ZGlmZiAtLWdpdCBhLy5naXRpZ25vcmUgYi8uZ2l0aWdub3JlCmluZGV4IDc2YzQxNGYuLmNiMDM0N2YgMTAwNjQ0Ci0tLSBhLy5naXRpZ25vcmUKKysrIGIvLmdpdGlnbm9yZQpAQCAtMSw0MCArMSw3NSBAQAotIwotIyAJVW50cmFja2VkIGRpcmVjdG9yaWVzCi0jCi1zcmMvQWRkcmVzc0Jvb2svYmluCi1zcmMvQWRkcmVzc0Jvb2svb2JqCi1zcmMvUHJvdG9jb2xCdWZmZXJzL2Jpbi8KLXNyYy9Qcm90b2NvbEJ1ZmZlcnMvb2JqLwotc3JjL1Byb3RvY29sQnVmZmVycy9vYmpDRgotc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L2Jpbi8KLXNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9vYmovCi1zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L2Jpbi8KLXNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3Qvb2JqLwotc3JjL1Byb3RvQmVuY2gvYmluLwotc3JjL1Byb3RvQmVuY2gvb2JqLwotc3JjL1Byb3RvRHVtcC9iaW4vCi1zcmMvUHJvdG9EdW1wL29iai8KLXNyYy9Qcm90b0dlbi9iaW4vCi1zcmMvUHJvdG9HZW4vb2JqLwotc3JjL1Byb3RvR2VuLlRlc3QvYmluLwotc3JjL1Byb3RvR2VuLlRlc3Qvb2JqLwotc3JjL1Byb3RvTXVuZ2UvYmluLwotc3JjL1Byb3RvTXVuZ2Uvb2JqLwotbW9uby9iaW4KLW1vbm8vdG1wCi1tb25vL3Byb3RvYwotYnVpbGRfb3V0cHV0Ci1idWlsZF90ZW1wCi1idWlsZC9tc2J1aWxkKi5sb2cKKyMgYXV0b2dlbi5zaC1nZW5lcmF0ZWQgZmlsZXMKK01ha2VmaWxlLmluCitzcmMvTWFrZWZpbGUuaW4KK2NvbmZpZy5ndWVzcworY29uZmlnLmguaW4KK2NvbmZpZy5zdWIKK2NvbmZpZ3VyZQorZGVwY29tcAoraW5zdGFsbC1zaAorbHRtYWluLnNoCittaXNzaW5nCiAKLSMKLSMgCVVudHJhY2tlZCBmaWxlcwotIwotKi51c2VyCi0qLnN1bwotX1JlU2hhcnBlci4qCi0qLnNsbi5jYWNoZQotbW9uby9UZXN0UmVzdWx0LnhtbAotbW9uby8ubGlicwotbW9uby8qLmV4ZQotbW9uby8qLmRsbAorYWNsb2NhbC5tNAorbTQvbGlidG9vbC5tNAorbTQvbHRvcHRpb25zLm00CittNC9sdHN1Z2FyLm00CittNC9sdHZlcnNpb24ubTQKK200L2x0fm9ic29sZXRlLm00CithdXRvbTR0ZS5jYWNoZQorCisjIGRvd25sb2FkZWQgZmlsZXMKK2d0ZXN0CisKKyMgaW4tdHJlZSBjb25maWd1cmUtZ2VuZXJhdGVkIGZpbGVzCitNYWtlZmlsZQorc3JjL01ha2VmaWxlCisvY29uZmlnLmgKK2NvbmZpZy5sb2cKK2NvbmZpZy5zdGF0dXMKKworbGlidG9vbAorcHJvdG9idWYtbGl0ZS5wYworcHJvdG9idWYucGMKKy5kZXBzCitzdGFtcC1oMQorCisjIGluLXRyZWUgYnVpbGQgcHJvZHVjdHMKKyoubworKi5sbworKi5sYQorc3JjLy5saWJzCisqLnNvCisKKy5kaXJzdGFtcAorCittYXAqdW5pdHRlc3QucGIuKgordW5pdHRlc3QqLnBiLioKK2NwcF90ZXN0Ki5wYi4qCisKKyoucHljCisqLmVnZy1pbmZvCisqX3BiMi5weQorcHl0aG9uLy5lZ2dzLworcHl0aG9uL2J1aWxkLworcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci8KKworc3JjL3Byb3RvYworc3JjL3VuaXR0ZXN0X3Byb3RvX21pZGRsZW1hbgorCisjIEdlbmVyYXRlZCB0ZXN0IHNjYWZmb2xkaW5nCitzcmMvcHJvdG9idWYqLXRlc3QKK3NyYy90ZXN0X3BsdWdpbgorc3JjL3Rlc3R6aXAuKgorc3JjL3pjZyp6aXAKK2FyLWxpYgorCit0ZXN0LWRyaXZlcgorY29tcGlsZQorCitzcmMvKiovKi5sb2cKK3NyYy8qKi8qLnRycworCisjIEphdmFCdWlsZCBvdXRwdXQuCitqYXZhL3RhcmdldAoramF2YW5hbm8vdGFyZ2V0CmRpZmYgLS1naXQgYS8udHJhdmlzLnltbCBiLy50cmF2aXMueW1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzMDEzYjgKLS0tIC9kZXYvbnVsbAorKysgYi8udHJhdmlzLnltbApAQCAtMCwwICsxLDQgQEAKK2xhbmd1YWdlOiBjcHAKK3NjcmlwdDogLi9hdXRvZ2VuLnNoICYmIC4vY29uZmlndXJlICYmIG1ha2UgZGlzdGNoZWNrCitub3RpZmljYXRpb25zOgorICBlbWFpbDogZmFsc2UKZGlmZiAtLWdpdCBhL0FuZHJvaWQubWsgYi9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4YmRkMDkKLS0tIC9kZXYvbnVsbAorKysgYi9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsNDg2IEBACisjIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIworIworCitMT0NBTF9QQVRIIDo9ICQoY2FsbCBteS1kaXIpCisKK0lHTk9SRURfV0FSTklOR1MgOj0gLVduby1zaWduLWNvbXBhcmUgLVduby11bnVzZWQtcGFyYW1ldGVyIC1Xbm8tc2lnbi1wcm9tbworCitDQ19MSVRFX1NSQ19GSUxFUyA6PSBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXAtdXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC1pbmwuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmNjICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmNjICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmggICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmNjICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5jYworCitKQVZBX0xJVEVfU1JDX0ZJTEVTIDo9IFwKKyAgICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbi5qYXZhIFwKKyAgICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlTGl0ZS5qYXZhIFwKKyAgICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24uamF2YSBcCisgICAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQ29kZWRPdXRwdXRTdHJlYW0uamF2YSBcCisgICAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQnl0ZVN0cmluZy5qYXZhIFwKKyAgICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZElucHV0U3RyZWFtLmphdmEgXAorICAgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0V4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5qYXZhIFwKKyAgICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2VMaXRlLmphdmEgXAorICAgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkU2V0LmphdmEgXAorICAgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0ludGVybmFsLmphdmEgXAorICAgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1dpcmVGb3JtYXQuamF2YSBcCisgICAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZUxpdGUuamF2YQorCitDT01QSUxFUl9TUkNfRklMRVMgOj0gIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0LmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfaGVhdnkuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21haW4uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvc3VicHJvY2Vzcy5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci96aXBfd3JpdGVyLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW1fZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpbGUuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2VfZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc3RyaW5nX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbWljcm8vamF2YW1pY3JvX2VudW0uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW1pY3JvL2phdmFtaWNyb19lbnVtX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFtaWNyby9qYXZhbWljcm9fZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW1pY3JvL2phdmFtaWNyb19maWxlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFtaWNyby9qYXZhbWljcm9fZ2VuZXJhdG9yLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFtaWNyby9qYXZhbWljcm9faGVscGVycy5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbWljcm8vamF2YW1pY3JvX21lc3NhZ2UuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW1pY3JvL2phdmFtaWNyb19tZXNzYWdlX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFtaWNyby9qYXZhbWljcm9fcHJpbWl0aXZlX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bV9maWVsZC5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uY2MgXAorICAgIHNyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnVjdHVyYWxseV92YWxpZC5jYyBcCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmNjIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuY2MKKworIyBKYXZhIG5hbm8gbGlicmFyeSAoZm9yIGRldmljZS1zaWRlIHVzZXJzKQorIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfTU9EVUxFIDo9IGxpYnByb3RvYnVmLWphdmEtbmFubworTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKK0xPQ0FMX1NES19WRVJTSU9OIDo9IDgKKworTE9DQUxfU1JDX0ZJTEVTIDo9ICQoY2FsbCBhbGwtamF2YS1maWxlcy11bmRlciwgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFubykKK0xPQ0FMX1NSQ19GSUxFUyArPSAkKGNhbGwgYWxsLWphdmEtZmlsZXMtdW5kZXIsIGphdmEvc3JjL2RldmljZS9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vKQorCitpbmNsdWRlICQoQlVJTERfU1RBVElDX0pBVkFfTElCUkFSWSkKKworIyBKYXZhIG5hbm8gbGlicmFyeSAoZm9yIGhvc3Qtc2lkZSB1c2VycykKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX01PRFVMRSA6PSBob3N0LWxpYnByb3RvYnVmLWphdmEtbmFubworTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKKworTE9DQUxfU1JDX0ZJTEVTIDo9ICQoY2FsbCBhbGwtamF2YS1maWxlcy11bmRlciwgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFubykKKworaW5jbHVkZSAkKEJVSUxEX0hPU1RfSkFWQV9MSUJSQVJZKQorCisjIEphdmEgbWljcm8gbGlicmFyeSAoZm9yIGRldmljZS1zaWRlIHVzZXJzKQorIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfTU9EVUxFIDo9IGxpYnByb3RvYnVmLWphdmEtbWljcm8KK0xPQ0FMX01PRFVMRV9UQUdTIDo9IG9wdGlvbmFsCitMT0NBTF9TREtfVkVSU0lPTiA6PSA4CisKK0xPQ0FMX1NSQ19GSUxFUyA6PSAkKGNhbGwgYWxsLWphdmEtZmlsZXMtdW5kZXIsIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21pY3JvKQorCitpbmNsdWRlICQoQlVJTERfU1RBVElDX0pBVkFfTElCUkFSWSkKKworIyBKYXZhIG1pY3JvIGxpYnJhcnkgKGZvciBob3N0LXNpZGUgdXNlcnMpCisjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9NT0RVTEUgOj0gaG9zdC1saWJwcm90b2J1Zi1qYXZhLW1pY3JvCitMT0NBTF9NT0RVTEVfVEFHUyA6PSBvcHRpb25hbAorCitMT0NBTF9TUkNfRklMRVMgOj0gJChjYWxsIGFsbC1qYXZhLWZpbGVzLXVuZGVyLCBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9taWNybykKKworaW5jbHVkZSAkKEJVSUxEX0hPU1RfSkFWQV9MSUJSQVJZKQorCisjIEphdmEgbGl0ZSBsaWJyYXJ5IChmb3IgZGV2aWNlLXNpZGUgdXNlcnMpCisjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9NT0RVTEUgOj0gbGlicHJvdG9idWYtamF2YS1saXRlCitMT0NBTF9NT0RVTEVfVEFHUyA6PSBvcHRpb25hbAorTE9DQUxfU0RLX1ZFUlNJT04gOj0gOAorCitMT0NBTF9TUkNfRklMRVMgOj0gJChKQVZBX0xJVEVfU1JDX0ZJTEVTKQorCitpbmNsdWRlICQoQlVJTERfU1RBVElDX0pBVkFfTElCUkFSWSkKKworIyBKYXZhIGxpdGUgbGlicmFyeSAoZm9yIGhvc3Qtc2lkZSB1c2VycykKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX01PRFVMRSA6PSBob3N0LWxpYnByb3RvYnVmLWphdmEtbGl0ZQorTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKKworTE9DQUxfU1JDX0ZJTEVTIDo9ICQoSkFWQV9MSVRFX1NSQ19GSUxFUykKKworaW5jbHVkZSAkKEJVSUxEX0hPU1RfSkFWQV9MSUJSQVJZKQorCisjIEMrKyBsaXRlIGxpYnJhcnkKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX01PRFVMRSA6PSBsaWJwcm90b2J1Zi1jcHAtbGl0ZQorTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKKworTE9DQUxfQ1BQX0VYVEVOU0lPTiA6PSAuY2MKKworTE9DQUxfU1JDX0ZJTEVTIDo9ICQoQ0NfTElURV9TUkNfRklMRVMpCisKK0xPQ0FMX0NfSU5DTFVERVMgOj0gXAorICAgICQoTE9DQUxfUEFUSCkvYW5kcm9pZCBcCisgICAgJChMT0NBTF9QQVRIKS9zcmMKKworIyBEZWZpbmUgdGhlIGhlYWRlciBmaWxlcyB0byBiZSBjb3BpZWQKKyNMT0NBTF9DT1BZX0hFQURFUlMgOj0gXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaCBcCisjICAgIHNyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmggXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oIFwKKyMgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmggXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmggXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaCBcCisjICAgIHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaAorIworI0xPQ0FMX0NPUFlfSEVBREVSU19UTyA6PSAkKExPQ0FMX01PRFVMRSkKKworTE9DQUxfQ0ZMQUdTIDo9IC1ER09PR0xFX1BST1RPQlVGX05PX1JUVEkgJChJR05PUkVEX1dBUk5JTkdTKQorCisjIFRoZXNlIGFyZSB0aGUgbWluaW11bSB2ZXJzaW9ucyBhbmQgZG9uJ3QgbmVlZCB0byBiZSB1cGRhdGUuCitpZmVxICgkKFRBUkdFVF9BUkNIKSxhcm0pCitMT0NBTF9TREtfVkVSU0lPTiA6PSA4CitlbHNlCisjIHg4Ni9taXBzIHN1cHBvcnQgb25seSBhdmFpbGFibGUgZnJvbSBBUEkgOS4KK0xPQ0FMX1NES19WRVJTSU9OIDo9IDkKK2VuZGlmCitMT0NBTF9OREtfU1RMX1ZBUklBTlQgOj0gc3RscG9ydF9zdGF0aWMKKworaW5jbHVkZSAkKEJVSUxEX1NUQVRJQ19MSUJSQVJZKQorCisjIEMrKyBsaXRlIGxpYnJhcnkgKGxpYmMrKyBmbGF2b3JlZCBmb3IgdGhlIHBsYXRmb3JtKQorIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfTU9EVUxFIDo9IGxpYnByb3RvYnVmLWNwcC1saXRlCitMT0NBTF9NT0RVTEVfVEFHUyA6PSBvcHRpb25hbAorCitMT0NBTF9DUFBfRVhURU5TSU9OIDo9IC5jYworCitMT0NBTF9TUkNfRklMRVMgOj0gJChDQ19MSVRFX1NSQ19GSUxFUykKKworTE9DQUxfQ19JTkNMVURFUyA6PSBcCisgICAgJChMT0NBTF9QQVRIKS9hbmRyb2lkIFwKKyAgICAkKExPQ0FMX1BBVEgpL3NyYworCitMT0NBTF9DRkxBR1MgOj0gLURHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSAkKElHTk9SRURfV0FSTklOR1MpCisKK2luY2x1ZGUgJChCVUlMRF9TSEFSRURfTElCUkFSWSkKKworIyBDKysgZnVsbCBsaWJyYXJ5CisjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK3Byb3RvYnVmX2NjX2Z1bGxfc3JjX2ZpbGVzIDo9IFwKKyAgICAkKENDX0xJVEVfU1JDX0ZJTEVTKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnVjdHVyYWxseV92YWxpZC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfaGVhdnkuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0LmNjICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmNjICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5jYworCisjIEMrKyBmdWxsIGxpYnJhcnkgLSBzdGxwb3J0IHZlcnNpb24KKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX01PRFVMRSA6PSBsaWJwcm90b2J1Zi1jcHAtZnVsbAorTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKK0xPQ0FMX0NQUF9FWFRFTlNJT04gOj0gLmNjCitMT0NBTF9TUkNfRklMRVMgOj0gJChwcm90b2J1Zl9jY19mdWxsX3NyY19maWxlcykKK0xPQ0FMX0NfSU5DTFVERVMgOj0gXAorICAgICQoTE9DQUxfUEFUSCkvYW5kcm9pZCBcCisgICAgZXh0ZXJuYWwvemxpYiBcCisgICAgJChMT0NBTF9QQVRIKS9zcmMKKworIyBEZWZpbmUgdGhlIGhlYWRlciBmaWxlcyB0byBiZSBjb3BpZWQKKyNMT0NBTF9DT1BZX0hFQURFUlMgOj0gXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaCBcCisjICAgIHNyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmggXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oIFwKKyMgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmggXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmggXAorIyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaCBcCisjICAgIHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaAorIworI0xPQ0FMX0NPUFlfSEVBREVSU19UTyA6PSAkKExPQ0FMX01PRFVMRSkKKworTE9DQUxfQ0ZMQUdTIDo9IC1ER09PR0xFX1BST1RPQlVGX05PX1JUVEkgJChJR05PUkVEX1dBUk5JTkdTKQorCisjIFRoZXNlIGFyZSB0aGUgbWluaW11bSB2ZXJzaW9ucyBhbmQgZG9uJ3QgbmVlZCB0byBiZSB1cGRhdGUuCitpZmVxICgkKFRBUkdFVF9BUkNIKSxhcm0pCitMT0NBTF9TREtfVkVSU0lPTiA6PSA4CitlbHNlCisjIHg4Ni9taXBzIHN1cHBvcnQgb25seSBhdmFpbGFibGUgZnJvbSBBUEkgOS4KK0xPQ0FMX1NES19WRVJTSU9OIDo9IDkKK2VuZGlmCitMT0NBTF9OREtfU1RMX1ZBUklBTlQgOj0gc3RscG9ydF9zdGF0aWMKKworaW5jbHVkZSAkKEJVSUxEX1NUQVRJQ19MSUJSQVJZKQorCisjIEMrKyBmdWxsIGxpYnJhcnkgLSBHbnVzdGwrcnR0aSB2ZXJzaW9uCisjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9NT0RVTEUgOj0gbGlicHJvdG9idWYtY3BwLWZ1bGwtZ251c3RsLXJ0dGkKK0xPQ0FMX01PRFVMRV9UQUdTIDo9IG9wdGlvbmFsCitMT0NBTF9DUFBfRVhURU5TSU9OIDo9IC5jYworTE9DQUxfU1JDX0ZJTEVTIDo9ICQocHJvdG9idWZfY2NfZnVsbF9zcmNfZmlsZXMpCitMT0NBTF9DX0lOQ0xVREVTIDo9IFwKKyAgICAkKExPQ0FMX1BBVEgpL2FuZHJvaWQgXAorICAgIGV4dGVybmFsL3psaWIgXAorICAgICQoTE9DQUxfUEFUSCkvc3JjCisKK0xPQ0FMX0NGTEFHUyA6PSAtZnJ0dGkgJChJR05PUkVEX1dBUk5JTkdTKQorTE9DQUxfU0RLX1ZFUlNJT04gOj0gMTQKK0xPQ0FMX05ES19TVExfVkFSSUFOVCA6PSBnbnVzdGxfc3RhdGljCisKK2luY2x1ZGUgJChCVUlMRF9TVEFUSUNfTElCUkFSWSkKKworIyBDKysgZnVsbCBsaWJyYXJ5IC0gbGliYysrIHZlcnNpb24gZm9yIHRoZSBwbGF0Zm9ybQorIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfTU9EVUxFIDo9IGxpYnByb3RvYnVmLWNwcC1mdWxsCitMT0NBTF9NT0RVTEVfVEFHUyA6PSBvcHRpb25hbAorTE9DQUxfQ1BQX0VYVEVOU0lPTiA6PSAuY2MKK0xPQ0FMX1NSQ19GSUxFUyA6PSAkKHByb3RvYnVmX2NjX2Z1bGxfc3JjX2ZpbGVzKQorTE9DQUxfQ19JTkNMVURFUyA6PSBcCisgICAgJChMT0NBTF9QQVRIKS9hbmRyb2lkIFwKKyAgICBleHRlcm5hbC96bGliIFwKKyAgICAkKExPQ0FMX1BBVEgpL3NyYworCitMT0NBTF9DRkxBR1MgOj0gLURHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSAkKElHTk9SRURfV0FSTklOR1MpCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IGxpYnoKKworaW5jbHVkZSAkKEJVSUxEX1NIQVJFRF9MSUJSQVJZKQorCisjIENsZWFuIHRlbXAgdmFycworcHJvdG9idWZfY2NfZnVsbF9zcmNfZmlsZXMgOj0KKworCisjIEFuZHJvaWQgUHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLCBhcHJvdG9jIChob3N0IGV4ZWN1dGFibGUpCisjIHVzZWQgYnkgdGhlIGJ1aWxkIHN5c3RlbXMgYXMgJChQUk9UT0MpIGRlZmluZWQgaW4KKyMgYnVpbGQvY29yZS9jb25maWcubWsKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX01PRFVMRSA6PSBhcHJvdG9jCitMT0NBTF9NT0RVTEVfQ0xBU1MgOj0gRVhFQ1VUQUJMRVMKK0xPQ0FMX01PRFVMRV9UQUdTIDo9IG9wdGlvbmFsCisKK0xPQ0FMX0NQUF9FWFRFTlNJT04gOj0gLmNjCitMT0NBTF9TUkNfRklMRVMgOj0gJChDT01QSUxFUl9TUkNfRklMRVMpCisKK0xPQ0FMX0NfSU5DTFVERVMgOj0gXAorICAgICQoTE9DQUxfUEFUSCkvYW5kcm9pZCBcCisgICAgZXh0ZXJuYWwvemxpYiBcCisgICAgJChMT0NBTF9QQVRIKS9zcmMKKworTE9DQUxfU1RBVElDX0xJQlJBUklFUyArPSBsaWJ6CisKK2lmbmVxICgkKEhPU1RfT1MpLHdpbmRvd3MpCitMT0NBTF9MRExJQlMgOj0gLWxwdGhyZWFkCitlbmRpZgorCitMT0NBTF9DRkxBR1MgOj0gJChJR05PUkVEX1dBUk5JTkdTKQorCitpbmNsdWRlICQoQlVJTERfSE9TVF9FWEVDVVRBQkxFKQorCisjIFRvIHRlc3QgamF2YSBwcm90byBwYXJhbXMgYnVpbGQgcnVsZXMuCisjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9NT0RVTEUgOj0gYXByb3RvYy10ZXN0LW5hbm8tcGFyYW1zCitMT0NBTF9NT0RVTEVfVEFHUyA6PSB0ZXN0cworTE9DQUxfU0RLX1ZFUlNJT04gOj0gY3VycmVudAorCitMT0NBTF9QUk9UT0NfT1BUSU1JWkVfVFlQRSA6PSBuYW5vCisKK0xPQ0FMX1NSQ19GSUxFUyA6PSBcCisgICAgICAgIHNyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X25hbm8ucHJvdG8gXAorICAgICAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3NpbXBsZV9uYW5vLnByb3RvIFwKKyAgICAgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9zdHJpbmd1dGY4X25hbm8ucHJvdG8gXAorICAgICAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3JlY3Vyc2l2ZV9uYW5vLnByb3RvCisKKworTE9DQUxfUFJPVE9DX0ZMQUdTIDo9IC0tcHJvdG9fcGF0aD0kKExPQ0FMX1BBVEgpL3NyYworCitMT0NBTF9QUk9UT19KQVZBX09VVFBVVF9QQVJBTVMgOj0gXAorICAgICAgICBqYXZhX3BhY2thZ2UgPSAkKExPQ0FMX1BBVEgpL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X25hbm8ucHJvdG98Y29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLCBcCisgICAgICAgIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gJChMT0NBTF9QQVRIKS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9uYW5vLnByb3RvfFVuaXR0ZXN0SW1wb3J0TmFubworCitpbmNsdWRlICQoQlVJTERfU1RBVElDX0pBVkFfTElCUkFSWSkKKworIyBUbyB0ZXN0IEFuZHJvaWQtc3BlY2lmaWMgbmFub3Byb3RvIGZlYXR1cmVzLgorIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworIyBQYXJjZWxhYmxlIG1lc3NhZ2VzCitMT0NBTF9NT0RVTEUgOj0gYW5kcm9pZC1uYW5vLXRlc3QtcGFyY2VsYWJsZQorTE9DQUxfTU9EVUxFX1RBR1MgOj0gdGVzdHMKK0xPQ0FMX1NES19WRVJTSU9OIDo9IGN1cnJlbnQKKworTE9DQUxfUFJPVE9DX09QVElNSVpFX1RZUEUgOj0gbmFubworCitMT0NBTF9TUkNfRklMRVMgOj0gc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9zaW1wbGVfbmFuby5wcm90bworCitMT0NBTF9QUk9UT0NfRkxBR1MgOj0gLS1wcm90b19wYXRoPSQoTE9DQUxfUEFUSCkvc3JjCisKK0xPQ0FMX1BST1RPX0pBVkFfT1VUUFVUX1BBUkFNUyA6PSBcCisgICAgICAgIHBhcmNlbGFibGVfbWVzc2FnZXMgPSB0cnVlCisKK2luY2x1ZGUgJChCVUlMRF9TVEFUSUNfSkFWQV9MSUJSQVJZKQorCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworIyBQYXJjZWxhYmxlIGFuZCBleHRlbmRhYmxlIG1lc3NhZ2VzCitMT0NBTF9NT0RVTEUgOj0gYW5kcm9pZC1uYW5vLXRlc3QtcGFyY2VsYWJsZS1leHRlbmRhYmxlCitMT0NBTF9NT0RVTEVfVEFHUyA6PSB0ZXN0cworTE9DQUxfU0RLX1ZFUlNJT04gOj0gY3VycmVudAorCitMT0NBTF9QUk9UT0NfT1BUSU1JWkVfVFlQRSA6PSBuYW5vCisKK0xPQ0FMX1NSQ19GSUxFUyA6PSBzcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2V4dGVuc2lvbl9uYW5vLnByb3RvCisKK0xPQ0FMX1BST1RPQ19GTEFHUyA6PSAtLXByb3RvX3BhdGg9JChMT0NBTF9QQVRIKS9zcmMKKworTE9DQUxfUFJPVE9fSkFWQV9PVVRQVVRfUEFSQU1TIDo9IFwKKyAgICAgICAgcGFyY2VsYWJsZV9tZXNzYWdlcyA9IHRydWUsIFwKKyAgICAgICAgc3RvcmVfdW5rbm93bl9maWVsZHMgPSB0cnVlCisKK2luY2x1ZGUgJChCVUlMRF9TVEFUSUNfSkFWQV9MSUJSQVJZKQorCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworIyBUZXN0IEFQSworTE9DQUxfUEFDS0FHRV9OQU1FIDo9IE5hbm9BbmRyb2lkVGVzdAorCitMT0NBTF9TREtfVkVSU0lPTiA6PSA4CisKK0xPQ0FMX01PRFVMRV9UQUdTIDo9IHRlc3RzCisKK0xPQ0FMX1NSQ19GSUxFUyA6PSAkKGNhbGwgYWxsLWphdmEtZmlsZXMtdW5kZXIsIGphdmEvc3JjL2RldmljZS90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vKQorCitMT0NBTF9NQU5JRkVTVF9GSUxFIDo9IGphdmEvc3JjL2RldmljZS90ZXN0L0FuZHJvaWRNYW5pZmVzdC54bWwKKworTE9DQUxfU1RBVElDX0pBVkFfTElCUkFSSUVTIDo9IGxpYnByb3RvYnVmLWphdmEtbmFubyBcCisgICAgICAgIGFuZHJvaWQtbmFuby10ZXN0LXBhcmNlbGFibGUgXAorICAgICAgICBhbmRyb2lkLW5hbm8tdGVzdC1wYXJjZWxhYmxlLWV4dGVuZGFibGUKKworTE9DQUxfREVYX1BSRU9QVCA6PSBmYWxzZQorCitpbmNsdWRlICQoQlVJTERfUEFDS0FHRSkKKworIyAyLjMuMCBwcmVidWlsdHMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LgoraW5jbHVkZSAkKExPQ0FMX1BBVEgpL3ByZWJ1aWx0cy9BbmRyb2lkLm1rCmRpZmYgLS1naXQgYS9DSEFOR0VTLnR4dCBiL0NIQU5HRVMudHh0CmluZGV4IDkwZTlkNzcuLmFjNDJhYTUgMTAwNjQ0Ci0tLSBhL0NIQU5HRVMudHh0CisrKyBiL0NIQU5HRVMudHh0CkBAIC0xLDE0NCArMSw3NzkgQEAKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLVdlbGNvbWUgdG8gdGhlIEMjIHBvcnQgb2YgR29vZ2xlIFByb3RvY29sIEJ1ZmZlcnMsIHdyaXR0ZW4gYnkgSm9uIFNrZWV0Ci0oc2tlZXRAcG9ib3guY29tKSBiYXNlZCBvbiB0aGUgd29yayBvZiBtYW55IHRhbGVudGVkIHBlb3BsZS4KKzIwMTUtMDItMjYgdmVyc2lvbiAzLjAuMC1hbHBoYS0yIChQeXRob24vUnVieS9KYXZhTmFubyk6CisgIEdlbmVyYWwKKyAgKiBJbnRyb2R1Y2VkIHRocmVlIG5ldyBsYW5ndWFnZSBpbXBsZW1lbnRhdGlvbnMgKFJ1YnksIEphdmFOYW5vLCBhbmQKKyAgICBQeXRob24pIHRvIHByb3RvMy4KKyAgKiBWYXJpb3VzIGJ1ZyBmaXhlcyBzaW5jZSAzLjAuMC1hbHBoYS0xCiAKLUZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgcG9ydCwgdmlzaXQgaXRzIGhvbWVwYWdlOgotaHR0cDovL3Byb3RvYnVmLWNzaGFycC1wb3J0Lmdvb2dsZWNvZGUuY29tCisgIFB5dGhvbjoKKyAgICBQeXRob24gaGFzIHJlY2VpdmVkIHNldmVyYWwgdXBkYXRlcywgbW9zdCBub3RhYmx5IHN1cHBvcnQgZm9yIHByb3RvMworICAgIHNlbWFudGljcyBpbiBhbnkgLnByb3RvIGZpbGUgdGhhdCBkZWNsYXJlcyBzeW50YXg9InByb3RvMyIuCisgICAgTWVzc2FnZXMgZGVjbGFyZWQgaW4gcHJvdG8zIGZpbGVzIG5vIGxvbmdlciByZXByZXNlbnQgZmllbGQgcHJlc2VuY2UKKyAgICBmb3Igc2NhbGFyIGZpZWxkcyAobnVtYmVyLCBlbnVtcywgYm9vbGVhbnMsIG9yIHN0cmluZ3MpLiAgWW91IGNhbgorICAgIG5vIGxvbmdlciBjYWxsIEhhc0ZpZWxkKCkgZm9yIHN1Y2ggZmllbGRzLCBhbmQgdGhleSBhcmUgc2VyaWFsaXplZAorICAgIGJhc2VkIG9uIHdoZXRoZXIgdGhleSBoYXZlIGEgbm9uLXplcm8vZW1wdHkvZmFsc2UgdmFsdWUuCiAKLUZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFByb3RvY29sIEJ1ZmZlcnMgaW4gZ2VuZXJhbCwgdmlzaXQgdGhlIHByb2plY3QgcGFnZSAKLWZvciB0aGUgQysrLCBKYXZhIGFuZCBQeXRob24gcHJvamVjdDoKLWh0dHA6Ly9wcm90b2J1Zi5nb29nbGVjb2RlLmNvbQotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMi40LjEuNTU1Ci09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICAgT25lIG90aGVyIG5vdGFibGUgY2hhbmdlIGlzIGluIHRoZSBDKystYWNjZWxlcmF0ZWQgaW1wbGVtZW50YXRpb24uCisgICAgRGVzY3JpcHRvciBvYmplY3RzICh3aGljaCBkZXNjcmliZSB0aGUgcHJvdG9idWYgc2NoZW1hIGFuZCBhbGxvdworICAgIHJlZmxlY3Rpb24gb3ZlciBpdCkgYXJlIG5vIGxvbmdlciBkdXBsaWNhdGVkIGJldHdlZW4gdGhlIFB5dGhvbgorICAgIGFuZCBDKysgbGF5ZXJzLiAgVGhlIFB5dGhvbiBkZXNjcmlwdG9ycyBhcmUgbm93IHNpbXBsZSB3cmFwcGVycworICAgIGFyb3VuZCB0aGUgQysrIGRlc2NyaXB0b3JzLiAgVGhpcyBjaGFuZ2Ugc2hvdWxkIHNpZ25pZmljYW50bHkKKyAgICByZWR1Y2UgdGhlIG1lbW9yeSB1c2FnZSBvZiBwcm9ncmFtcyB0aGF0IHVzZSBhIGxvdCBvZiBtZXNzYWdlCisgICAgdHlwZXMuCiAKLUNoYW5nZXM6Ci0tIFVwZ3JhZGUgc29sdXRpb24gZm9ybWF0IHRvIFZpc3VhbCBTdHVkaW8gMjAxMi4KLS0gQWRkIHRoZSBhYmlsaXR5IHRvIHByaW50IGEgYnVpbGRlciAobm90IGp1c3QgYSBtZXNzYWdlKQotLSBUZXh0R2VuZXJhdG9yIGludHJvZHVjZXMgYSBuZXcgb3ZlcmxvYWQgb2YgUHJpbnRUbwotLSBNdW5nZSBwcm90b2MncyBlcnJvciBmb3JtYXQgaW50byBhIFZTLUMjLWNvbXBhdGlibGUgb3V0cHV0IGZvcm1hdC4KLS0gV29yayB0byBtYWtlIFByb3RvR2VuIGNsb25lIHRoYXQgYWN0cyBhcyBhIHByb3RvYy5leGUgcGx1Z2luLgotLSBBZGRlZCB0aGUgQWxsb3dQYXJ0aWFsbHlUcnVzdGVkQ2FsbGVycyBhdHRyaWJ1dGUKLS0gT3B0aW1pemVkIGVudW0gcGFyc2luZy4KKyAgUnVieToKKyAgICBXZSBoYXZlIGFkZGVkIHByb3RvMyBzdXBwb3J0IGZvciBSdWJ5IHZpYSBhIG5hdGl2ZSBDIGV4dGVuc2lvbi4KIAotRml4ZXM6Ci0tIEZpeCBmb3IgYnVnIGluIGxpbWl0ZWQgaW5wdXQgc3RyZWFtJ3MgUG9zaXRpb24sIEludHJvZHVjZWQgUG9zaXRpb24gb24gCi0gIG91dHB1dCBzdHJlYW0KLS0gRml4IGZvciB3cml0aW5nIGEgY2hhcmFjdGVyIHRvIGEgSlNPTiBvdXRwdXQgb3ZlcmZsb3dzIGFsbG9jYXRlZCBidWZmZXIKLS0gT3B0aW1pemUgRnJvbUJhc2U2NFN0cmluZyB0byByZXR1cm4gRW1wdHkgd2hlbiBwcmVzZW50ZWQgd2l0aCBlbXB0eSBzdHJpbmcuCi0tIFVzZSBzdHJpbmcuQ29uY2F0IGluc3RlYWQgb2Ygb3BlcmF0b3IgdG8gYXZvaWQgcG90ZW50aWFsIGltcG9ydCBwcm9ibGVtcwotLSBJc3N1ZSA4MTogcXVvdGluZyBmb3IgTlVuaXQgcGFyYW1ldGVycy4KLS0gSXNzdWUgNTY6IE51R2V0IHBhY2thZ2UgaXMgbm9pc3kKLS0gSXNzdWUgNzA6IFBvcnRhYmxlIGxpYnJhcnkgcHJvamVjdCBoYXMgc29tZSBpbnZhbGlkIE51bml0LWJhc2VkIGNvZGUuCi0tIElzc3VlIDcxOiBDb2RlZElucHV0U3RyZWFtLlJlYWRCeXRlcyBnbyB0byBzbG93IHBhdGggdW5uZWNlc3NhcmlseQotLSBJc3N1ZSA4NDogd2FybmluZyBDUzAyMTk6IFRoZSB2YXJpYWJsZSBgc2l6ZScgaXMgYXNzaWduZWQgYnV0IG5ldmVyIHVzZWQKKyAgICBUaGUgUnVieSBleHRlbnNpb24gaXRzZWxmIGlzIGluY2x1ZGVkIGluIHRoZSBydWJ5LyBkaXJlY3RvcnksIGFuZCBkZXRhaWxzIG9uCisgICAgYnVpbGRpbmcgYW5kIGluc3RhbGxpbmcgdGhlIGV4dGVuc2lvbiBhcmUgaW4gcnVieS9SRUFETUUubWQuIFRoZSBleHRlbnNpb24KKyAgICB3aWxsIGFsc28gYmUgcHVibGlzaGVkIGFzIGEgUnVieSBnZW0uIENvZGUgZ2VuZXJhdG9yIHN1cHBvcnQgaXMgaW5jbHVkZWQgYXMKKyAgICBwYXJ0IG9mIGBwcm90b2NgIHdpdGggdGhlIGAtLXJ1Ynlfb3V0YCBmbGFnLgogCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci1SRUxFQVNFIE5PVEVTIC0gVmVyc2lvbiAyLjQuMS41MjEKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgICBUaGUgUnVieSBleHRlbnNpb24gaW1wbGVtZW50cyBhIHVzZXItZnJpZW5kbHkgRFNMIHRvIGRlZmluZSBtZXNzYWdlIHR5cGVzCisgICAgKGFsc28gZ2VuZXJhdGVkIGJ5IHRoZSBjb2RlIGdlbmVyYXRvciBmcm9tIGAucHJvdG9gIGZpbGVzKS4gIE9uY2UgYSBtZXNzYWdlCisgICAgdHlwZSBpcyBkZWZpbmVkLCB0aGUgdXNlciBtYXkgY3JlYXRlIGluc3RhbmNlcyBvZiB0aGUgbWVzc2FnZSB0aGF0IGJlaGF2ZSBpbgorICAgIHdheXMgaWRpb21hdGljIHRvIFJ1YnkuIEZvciBleGFtcGxlOgogCi1DaGFuZ2VzOgotLSBBZGQgZ2VuZXJhdGVkX2NvZGVfYXR0cmlidXRlcyBvcHRpb24sIGRlZmF1bHRlZCB0byBmYWxzZQotLSBBZGRlZCBzdXBwb3J0IGZvciBQb3J0YWJsZSBsaWJyYXJ5Ci0tIEFkZGVkICdVbnNhZmUnIHN0YXRpYyB0eXBlIGluIEJ5dGVTdHJpbmcgdG8gYWxsb3cgZGlyZWN0IGJ1ZmZlciBhY2Nlc3MKKyAgICAtIE1lc3NhZ2UgZmllbGRzIGFyZSBwcmVzZW50IGFzIG9yZGluYXJ5IFJ1YnkgcHJvcGVydGllcyAoZ2V0dGVyIG1ldGhvZAorICAgICAgYGZvb2AgYW5kIHNldHRlciBtZXRob2QgYGZvbz1gKS4KKyAgICAtIFJlcGVhdGVkIGZpZWxkIGVsZW1lbnRzIGFyZSBzdG9yZWQgaW4gYSBjb250YWluZXIgdGhhdCBhY3RzIGxpa2UgYSBuYXRpdmUKKyAgICAgIFJ1YnkgYXJyYXksIGFuZCBtYXAgZWxlbWVudHMgYXJlIHN0b3JlZCBpbiBhIGNvbnRhaW5lciB0aGF0IGFjdHMgbGlrZSBhCisgICAgICBuYXRpdmUgUnVieSBoYXNobWFwLgorICAgIC0gVGhlIHVzdWFsIHdlbGwta25vd24gbWV0aG9kcywgc3VjaCBhcyBgI3RvX3NgLCBgI2R1cGAsIGFuZCB0aGUgbGlrZSwgYXJlCisgICAgICBwcmVzZW50LgogCi1GaXhlczoKLS0gSXNzdWUgNTA6IFRoZSBYTUwgc2VyaWFsaXplciB3aWxsIGZhaWwgdG8gZGVzZXJpYWxpemUgYSBtZXNzYWdlIHdpdGggZW1wdHkgCi0gIGNoaWxkIG1lc3NhZ2UKLS0gSXNzdWUgNDU6IFVzZSBvZiAnaXRlbScgYXMgYSBmaWVsZCBuYW1lIGNhdXNlcyBBbWJpZ3VvdXNNYXRjaEV4Y2VwdGlvbgotLSBJc3N1ZSA0OTogR2VuZXJhdGVkIG5lc3RlZCBzdGF0aWMgVHlwZXMgY2xhc3Mgc2hvdWxkIGJlIHBhcnRpYWwKLS0gSXNzdWUgMzg6IERpc2FibGUgQ0xTQ29tcGxpYW50IHdhcm5pbmdzICgzMDIxKQotLSBJc3N1ZSA0MDogcHJvdG9fcGF0aCBkb2VzIG5vdCB3b3JrIGZvciBjb21tYW5kLWxpbmUgZmlsZSBuYW1lcwotLSBJc3N1ZSA1NDogc2hvdWxkIHJldGlyZSBhbGwgYnl0ZXMgaW4gYnVmZmVyIChidWZmZXJTaXplKQotLSBJc3N1ZSA0MzogRml4IHRvIGNvcnJlY3QgaWRlbnRpY2FsICd1bWJyZWxsYV9jbGFzc25hbWUnIG9wdGlvbnMgZnJvbSB0cnlpbmcgCi0gIHRvIHdyaXRlIHRvIHRoZSBzYW1lIGZpbGVuYW1lLgorICAgIFVubGlrZSBzZXZlcmFsIGV4aXN0aW5nIHRoaXJkLXBhcnR5IFJ1YnkgZXh0ZW5zaW9ucyBmb3IgcHJvdG9idWYsIHRoaXMKKyAgICBleHRlbnNpb24gaXMgYnVpbHQgb24gYSAic3Ryb25nbHktdHlwZWQiIHBoaWxvc29waHk6IG1lc3NhZ2UgZmllbGRzIGFuZAorICAgIGFycmF5L21hcCBjb250YWluZXJzIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBlYWdlcmx5IHdoZW4gdmFsdWVzIG9mIHRoZQorICAgIGluY29ycmVjdCB0eXBlIGFyZSBpbnNlcnRlZC4KIAotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMi40LjEuNDczCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICAgU2VlIHJ1YnkvUkVBRE1FLm1kIGZvciBkZXRhaWxzLgogCi1GZWF0dXJlczoKLS0gQWRkZWQgb3B0aW9uIHNlcnZpY2VfZ2VuZXJhdG9yX3R5cGUgdG8gY29udHJvbCBzZXJ2aWNlIGdlbmVyYXRpb24gd2l0aAotICBOT05FLCBHRU5FUklDLCBJTlRFUkZBQ0UsIG9yIElSUENESVNQQVRDSAotLSBBZGRlZCBpbnRlcmZhY2VzIElScGNEaXNwYXRjaCBhbmQgSVJwY1NlcnZlclN0dWIgdG8gcHJvdmlkZSBmb3IgYmxvY2tpbmcKLSAgc2VydmljZXMgYW5kIGltcGxlbWVudGF0aW9ucy4KLS0gQWRkZWQgUHJvdG9HZW4uZXhlIGNvbW1hbmQtbGluZSBhcmd1bWVudCAiLS1wcm90b2NfZGlyPSIgdG8gc3BlY2lmeSB0aGUgCi0gIGxvY2F0aW9uIG9mIHByb3RvYy5leGUuCi0tIEV4dHJhY3RlZCBpbnRlcmZhY2VzIGZvciBJQ29kZWRJbnB1dFN0cmVhbSBhbmQgSUNvZGVkT3V0cHV0U3RyZWFtIHRvIGFsbG93Ci0gIGN1c3RvbSBpbXBsZW1lbnRhdGlvbiBvZiB3cml0ZXJzIHdpdGggYm90aCBzcGVlZCBhbmQgc2l6ZSBvcHRpbWl6YXRpb25zLgotLSBBZGRpdGlvbiBvZiB0aGUgIkdvb2dsZS5Qcm90b0J1ZmZlcnMuU2VyaWFsaXphdGlvbiIgYXNzZW1ibHkgdG8gc3VwcG9ydAotICByZWFkaW5nIGFuZCB3cml0aW5nIG1lc3NhZ2VzIHRvL2Zyb20gWE1MLCBKU09OLCBJRGljdGlvbmFyeTwsPiBhbmQgb3RoZXJzLgotLSBTZXZlcmFsIHBlcmZvcm1hbmNlIHJlbGF0ZWQgZml4ZXMgYW5kIHR3ZWVrcwotLSBJc3N1ZSAzOglBZGQgb3B0aW9uIHRvIG1hcmsgZ2VuZXJhdGVkIGNvZGUgd2l0aCBhdHRyaWJ1dGUKLS0gSXNzdWUgMjA6CVN1cHBvcnQgZm9yIGRlY29yYXRpbmcgY2xhc3NlcyBbU2VyaWFsaXphYmxlXQotLSBJc3N1ZSAyMToJRGVjb3JhdGUgZmllbGRzIHdpdGggW2RlcHJlY2F0ZWQ9dHJ1ZV0gYXMgW1N5c3RlbS5PYnNvbGV0ZV0KLS0gSXNzdWUgMjI6CVJldXNhYmxlIEJ1aWxkZXIgY2xhc3NlcwotLSBJc3N1ZSAyNDoJU3VwcG9ydCBmb3IgdXNpbmcgSnNvbi9YbWwgZm9ybWF0cyB3aXRoIElDb2RlZElucHV0U3RyZWFtCi0tIElzc3VlIDI1OiBBZGRlZCBzdXBwb3J0IGZvciBOdUdldCBwYWNrYWdlcwotLSBJc3N1ZSAzMTogVXBncmFkZWQgcHJvdG9jLmV4ZSBhbmQgZGVzY3JpcHRvciB0byAyLjQuMQorICBKYXZhTmFubzoKKyAgICBKYXZhTmFubyBpcyBhIHNwZWNpYWwgY29kZSBnZW5lcmF0b3IgYW5kIHJ1bnRpbWUgbGlicmFyeSBkZXNpZ25lZCBlc3BlY2lhbGx5CisgICAgZm9yIHJlc291cmNlLXJlc3RyaWN0ZWQgc3lzdGVtcywgbGlrZSBBbmRyb2lkLiBJdCBpcyB2ZXJ5IHJlc291cmNlLWZyaWVuZGx5CisgICAgaW4gYm90aCB0aGUgYW1vdW50IG9mIGNvZGUgYW5kIHRoZSBydW50aW1lIG92ZXJoZWFkLiBIZXJlIGlzIGFuIGFuIG92ZXJ2aWV3CisgICAgb2YgSmF2YU5hbm8gZmVhdHVyZXMgY29tcGFyZWQgd2l0aCB0aGUgb2ZmaWNpYWwgSmF2YSBwcm90b2J1ZjoKIAotRml4ZXM6Ci0tIElzc3VlIDEzOglNZXNzYWdlIHdpdGggRmllbGQgc2FtZSBuYW1lIGFzIG1lc3NhZ2UgY2F1c2VzIHVuY29tcGlsYWJsZSAuY3MKLS0gSXNzdWUgMTY6CURvZXMgbm90IGludGVncmF0ZSB3ZWxsIHdpdGggb3RoZXIgdG9vbGluZwotLSBJc3N1ZSAxOToJU3VwcG9ydCBmb3IgbmVnYXRpdmUgZW51bSB2YWx1ZXMKLS0gSXNzdWUgMjY6CUFkZFJhbmdlIGluIEdlbmVyYXRlZEJ1aWxkZXIgaXRlcmF0ZXMgdHdpY2UuCi0tIElzc3VlIDI3OglSZW1vdmUgWE1MIGRvY3VtZW50YXRpb24gb3V0cHV0IGZyb20gdGVzdCBwcm9qZWN0cyB0byBjbGVhciAKLSAgd2FybmluZ3MvZXJyb3JzLgotLSBJc3N1ZSAyODogQ2lyY3VsYXIgbWVzc2FnZSBkZXBlbmRlbmNpZXMgcmVzdWx0IGluIG51bGwgZGVmYXVsdCB2YWx1ZXMgZm9yIAotICBNZXNzYWdlIGZpZWxkcy4KLS0gSXNzdWUgMjk6IE1lc3NhZ2UgY2xhc3NlcyBnZW5lcmF0ZWQgaGF2ZSBhIHB1YmxpYyBkZWZhdWx0IGNvbnN0cnVjdG9yLiAgWW91Ci0gIGNhbiBkaXNhYmxlIHByaXZhdGUgY3RvciBnZW5lcmF0aW9uIHdpdGggdGhlIG9wdGlvbiBnZW5lcmF0ZV9wcml2YXRlX2N0b3IuCi0tIElzc3VlIDM1OiBGaXhlZCBhIGJ1ZyBpbiBQcm90b0dlbiBoYW5kbGluZyBvZiBhcmd1bWVudHMgd2l0aCB0cmFpbGluZyBcCi0tIEJpZy1lbmRpYW4gc3VwcG9ydCBmb3IgZmxvYXQsIGFuZCBkb3VibGUgb24gU2lsdmVybGlnaHQKLS0gUGFja2VkIGFuZCBVbnBhY2tlZCBwYXJzaW5nIGFsbG93IGZvciBhbGwgcmVwZWF0ZWQsIGFzIHBlciB2ZXJzaW9uIDIuMwotLSBGaXggZm9yIGxlYXZpbmcgQnVpbGRlciBhIHB1YmxpYyBjdG9yIG9uIGludGVybmFsIGNsYXNzZXMgZm9yIHVzZSB3aXRoCi0gIGdlbmVyaWMgIndoZXJlIFQ6IG5ldygpIiBjb25zdHJhaW50cy4KKyAgICAtIE5vIGRlc2NyaXB0b3JzIG9yIG1lc3NhZ2UgYnVpbGRlcnMuCisgICAgLSBBbGwgbWVzc2FnZXMgYXJlIG11dGFibGU7IGZpZWxkcyBhcmUgcHVibGljIEphdmEgZmllbGRzLgorICAgIC0gRm9yIG9wdGlvbmFsIGZpZWxkcyBvbmx5LCBlbmNhcHN1bGF0aW9uIGJlaGluZCBzZXR0ZXIvZ2V0dGVyL2hhenplci8KKyAgICAgIGNsZWFyZXIgZnVuY3Rpb25zIGlzIG9wdC1pbiwgd2hpY2ggcHJvdmlkZSBwcm9wZXIgJ2hhcycgc3RhdGUgc3VwcG9ydC4KKyAgICAtIEZvciBwcm90bzIsIGlmIG5vdCBvcHRlZCBpbiwgaGFzIHN0YXRlIChmaWVsZCBwcmVzZW5jZSkgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgIFNlcmlhbGl6YXRpb24gb3V0cHV0cyBhbGwgZmllbGRzIG5vdCBlcXVhbCB0byB0aGVpciBkZWZhdWx0cy4KKyAgICAgIFRoZSBiZWhhdmlvciBpcyBjb25zaXN0ZW50IHdpdGggcHJvdG8zIHNlbWFudGljcy4KKyAgICAtIFJlcXVpcmVkIGZpZWxkcyAocHJvdG8yIG9ubHkpIGFyZSBhbHdheXMgc2VyaWFsaXplZC4KKyAgICAtIEVudW0gY29uc3RhbnRzIGFyZSBpbnRlZ2VyczsgcHJvdGVjdGlvbiBhZ2FpbnN0IGludmFsaWQgdmFsdWVzIG9ubHkKKyAgICAgIHdoZW4gcGFyc2luZyBmcm9tIHRoZSB3aXJlLgorICAgIC0gRW51bSBjb25zdGFudHMgY2FuIGJlIGdlbmVyYXRlZCBpbnRvIGNvbnRhaW5lciBpbnRlcmZhY2VzIGJlYXJpbmcKKyAgICAgIHRoZSBlbnVtJ3MgbmFtZSAoc28gdGhlIHJlZmVyZW5jaW5nIGNvZGUgaXMgaW4gSmF2YSBzdHlsZSkuCisgICAgLSBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8gY2FuIG9ubHkgdGFrZSBieXRlW10gKG5vdCBJbnB1dFN0cmVhbSkuCisgICAgLSBTaW1pbGFybHkgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBjYW4gb25seSB3cml0ZSB0byBieXRlW10uCisgICAgLSBSZXBlYXRlZCBmaWVsZHMgYXJlIGluIGFycmF5cywgbm90IEFycmF5TGlzdCBvciBWZWN0b3IuIE51bGwgYXJyYXkKKyAgICAgIGVsZW1lbnRzIGFyZSBhbGxvd2VkIGFuZCBzaWxlbnRseSBpZ25vcmVkLgorICAgIC0gRnVsbCBzdXBwb3J0IGZvciBzZXJpYWxpemluZy9kZXNlcmlhbGl6aW5nIHJlcGVhdGVkIHBhY2tlZCBmaWVsZHMuCisgICAgLSBTdXBwb3J0ICBleHRlbnNpb25zIChpbiBwcm90bzIpLgorICAgIC0gVW5zZXQgbWVzc2FnZXMvZ3JvdXBzIGFyZSBudWxsLCBub3QgYW4gaW1tdXRhYmxlIGVtcHR5IGRlZmF1bHQKKyAgICAgIGluc3RhbmNlLgorICAgIC0gdG9CeXRlQXJyYXkoLi4uKSBhbmQgbWVyZ2VGcm9tKC4uLikgYXJlIG5vdyBzdGF0aWMgZnVuY3Rpb25zIG9mCisgICAgICBNZXNzYWdlTmFuby4KKyAgICAtIFRoZSAnYnl0ZXMnIHR5cGUgdHJhbnNsYXRlcyB0byB0aGUgSmF2YSB0eXBlIGJ5dGVbXS4KIAotT3RoZXI6Ci0tIENoYW5nZWQgdGhlIGNvZGUgc2lnbmluZyBrZXkgdG8gYSBwcml2YXRlbHkgaGVsZCBrZXkKLS0gUmVmb3JtYXR0ZWQgYWxsIGNvZGUgYW5kIGxpbmUtZW5kaW5ncyB0byBDIyBkZWZhdWx0cwotLSBSZXdvcmtpbmcgb2YgcGVyZm9ybWFuY2UgYmVuY2htYXJrcyB0byBwcm9kdWNlIHJlbGlhYmxlIHJlc3VsdHMsIG9wdGlvbiAvdjIKLS0gSXNzdWUgMzQ6IFNpbHZlcmxpZ2h0IGFzc2VtYmxpZXMgYXJlIG5vdyB1bml0IHRlc3RlZAorICAgIFNlZSBqYXZhbmFuby9SRUFETUUudHh0IGZvciBkZXRhaWxzLgogCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci1SRUxFQVNFIE5PVEVTIC0gVmVyc2lvbiAyLjMuMC4yNzcKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKzIwMTQtMTItMDEgdmVyc2lvbiAzLjAuMC1hbHBoYS0xIChDKysvSmF2YSk6CiAKLUZlYXR1cmVzOgotLSBBZGRlZCBjbHNfY29tcGxpYW5jZSBvcHRpb24gdG8gZ2VuZXJhdGUgYXR0cmlidXRlcyBpbmRpY2F0aW5nIAotICBub24tQ0xTLWNvbXBsaWFuY2UuCi0tIEFkZGVkIGZpbGVfZXh0ZW5zaW9uIG9wdGlvbiB0byBjb250cm9sIHRoZSBnZW5lcmF0ZWQgb3V0cHV0IGZpbGUncyBleHRlbnNpb24uCi0tIEFkZGVkIHVtYnJlbGxhX25hbWVzcGFjZSBvcHRpb24gdG8gcGxhY2UgdGhlIHVtYnJlbGxhIGNsYXNzIGludG8gYSBuZXN0ZWQKLSAgbmFtZXNwYWNlIHRvIGFkZHJlc3MgaXNzdWVzIHdpdGggcHJvdG8gZmlsZXMgaGF2aW5nIHRoZSBzYW1lIG5hbWUgYXMgYSAKLSAgbWVzc2FnZSBpdCBjb250YWlucy4KLS0gQWRkZWQgb3V0cHV0X2RpcmVjdG9yeSBvcHRpb24gdG8gc2V0IHRoZSBvdXRwdXQgcGF0aCBmb3IgdGhlIHNvdXJjZSBmaWxlKHMpLgotLSBBZGRlZCBpZ25vcmVfZ29vZ2xlX3Byb3RvYnVmIG9wdGlvbiB0byBhdm9pZCBnZW5lcmF0aW5nIGNvZGUgZm9yIGluY2x1ZGVzIAotICBmcm9tIHRoZSBnb29nbGUucHJvdG9idWYgcGFja2FnZS4KLS0gQWRkZWQgdGhlIExJVEUgZnJhbWV3b3JrIChHb29nbGUuUHJvdG9CdWZmZXJzTGl0ZS5kbGwpIGFuZCB0aGUgYWJpbGl0eSB0bwotICBnZW5lcmF0ZSBjb2RlIHdpdGggIm9wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7Ii4KLS0gQWRkZWQgYWJpbGl0eSB0byBpbnZva2UgcHJvdG9jLmV4ZSBmcm9tIHdpdGhpbiBQcm90b0dlbi5leGUuCi0tIFVwZ3JhZGVkIHRvIHByb3RvYy5leGUgKDIuMykgY29tcGlsZXIuCisgIEdlbmVyYWwKKyAgKiBJbnRyb2R1Y2VkIFByb3RvY29sIEJ1ZmZlcnMgbGFuZ3VhZ2UgdmVyc2lvbiAzIChha2EgcHJvdG8zKS4KIAotRml4ZXM6Ci0tIElzc3VlIDk6CUNsYXNzIGNhbm5vdCBiZSBzdGF0aWMgYW5kIHNlYWxlZCBlcnJvcgotLSBJc3N1ZSAxMjoJZGVmYXVsdCB2YWx1ZSBmb3IgZW51bWVyYXRlIGZpZWxkcyBtdXN0IGJlIGZpbGxlZCBvdXQKKyAgICBXaGVuIHByb3RvYnVmIHdhcyBpbml0aWFsbHkgb3BlbnNvdXJjZWQgaXQgaW1wbGVtZW50ZWQgUHJvdG9jb2wgQnVmZmVycworICAgIGxhbmd1YWdlIHZlcnNpb24gMiAoYWthIHByb3RvMiksIHdoaWNoIGlzIHdoeSB0aGUgdmVyc2lvbiBudW1iZXIKKyAgICBzdGFydGVkIGZyb20gdjIuMC4wLiBGcm9tIHYzLjAuMCwgYSBuZXcgbGFuZ3VhZ2UgdmVyc2lvbiAocHJvdG8zKSBpcworICAgIGludHJvZHVjZWQgd2hpbGUgdGhlIG9sZCB2ZXJzaW9uIChwcm90bzIpIHdpbGwgY29udGludWUgdG8gYmUgc3VwcG9ydGVkLgogCi1PdGhlcjoKLS0gUmV3cml0ZSBvZiBidWlsZCB1c2luZyBNU0JidWlsZCBpbnN0ZWFkIG9mIE5BbnQKLS0gTW92ZWQgdG8gTlVuaXQgVmVyc2lvbiAyLjIuOC4wCi0tIENoYW5nZWQgdG8gdXNpbmcgc2VjdXJlIC5zbmsgZm9yIHJlbGVhc2VzCisgICAgVGhlIG1haW4gaW50ZW50IG9mIGludHJvZHVjaW5nIHByb3RvMyBpcyB0byBjbGVhbiB1cCBwcm90b2J1ZiBiZWZvcmUKKyAgICBwdXNoaW5nIHRoZSBsYW5ndWFnZSBhcyB0aGUgZm91bmRhdGlvbiBvZiBHb29nbGUncyBuZXcgQVBJIHBsYXRmb3JtLgorICAgIEluIHByb3RvMywgdGhlIGxhbmd1YWdlIGlzIHNpbXBsaWZpZWQsIGJvdGggZm9yIGVhc2Ugb2YgdXNlIGFuZCAgdG8KKyAgICBtYWtlIGl0IGF2YWlsYWJsZSBpbiBhIHdpZGVyIHJhbmdlIG9mIHByb2dyYW1taW5nIGxhbmd1YWdlcy4gQXQgdGhlCisgICAgc2FtZSB0aW1lIGEgZmV3IGZlYXR1cmVzIGFyZSBhZGRlZCB0byBiZXR0ZXIgc3VwcG9ydCBjb21tb24gaWRpb21zCisgICAgZm91bmQgaW4gQVBJcy4KIAotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMC45LjEKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgICBUaGUgZm9sbG93aW5nIGFyZSB0aGUgbWFpbiBuZXcgZmVhdHVyZXMgaW4gbGFuZ3VhZ2UgdmVyc2lvbiAzOgogCi1GaXhlczoKLS0gaXNzdWUgMTA6CUluY29ycmVjdCBlbmNvZGluZyBvZiBwYWNrZWQgZmllbGRzIHdoZW4gc2VyaWFsaXplZAorICAgICAgMS4gUmVtb3ZhbCBvZiBmaWVsZCBwcmVzZW5jZSBsb2dpYyBmb3IgcHJpbWl0aXZlIHZhbHVlIGZpZWxkcywgcmVtb3ZhbAorICAgICAgICAgb2YgcmVxdWlyZWQgZmllbGRzLCBhbmQgcmVtb3ZhbCBvZiBkZWZhdWx0IHZhbHVlcy4gVGhpcyBtYWtlcyBwcm90bzMKKyAgICAgICAgIHNpZ25pZmljYW50bHkgZWFzaWVyIHRvIGltcGxlbWVudCB3aXRoIG9wZW4gc3RydWN0IHJlcHJlc2VudGF0aW9ucywKKyAgICAgICAgIGFzIGluIGxhbmd1YWdlcyBsaWtlIEFuZHJvaWQgSmF2YSwgT2JqZWN0aXZlIEMsIG9yIEdvLgorICAgICAgMi4gUmVtb3ZhbCBvZiB1bmtub3duIGZpZWxkcy4KKyAgICAgIDMuIFJlbW92YWwgb2YgZXh0ZW5zaW9ucywgd2hpY2ggYXJlIGluc3RlYWQgcmVwbGFjZWQgYnkgYSBuZXcgc3RhbmRhcmQKKyAgICAgICAgIHR5cGUgY2FsbGVkIEFueS4KKyAgICAgIDQuIEZpeCBzZW1hbnRpY3MgZm9yIHVua25vd24gZW51bSB2YWx1ZXMuCisgICAgICA1LiBBZGRpdGlvbiBvZiBtYXBzLgorICAgICAgNi4gQWRkaXRpb24gb2YgYSBzbWFsbCBzZXQgb2Ygc3RhbmRhcmQgdHlwZXMgZm9yIHJlcHJlc2VudGF0aW9uIG9mIHRpbWUsCisgICAgICAgICBkeW5hbWljIGRhdGEsIGV0Yy4KKyAgICAgIDcuIEEgd2VsbC1kZWZpbmVkIGVuY29kaW5nIGluIEpTT04gYXMgYW4gYWx0ZXJuYXRpdmUgdG8gYmluYXJ5IHByb3RvCisgICAgICAgICBlbmNvZGluZy4KIAotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMC45LjAKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgICBUaGlzIHJlbGVhc2UgKHYzLjAuMC1hbHBoYS0xKSBpbmNsdWRlcyBwYXJ0aWFsIHByb3RvMyBzdXBwb3J0IGZvciBDKysgYW5kCisgICAgSmF2YS4gSXRlbXMgNiAod2VsbC1rbm93biB0eXBlcykgYW5kIDcgKEpTT04gZm9ybWF0KSBpbiB0aGUgYWJvdmUgZmVhdHVyZQorICAgIGxpc3QgYXJlIG5vdCBpbXBlbG1lbnRlZC4KIAotLSBJbml0aWFsIHJlbGVhc2UKKyAgICBBIG5ldyBub3Rpb24gInN5bnRheCIgaXMgaW50cm9kdWNlZCB0byBzcGVjaWZ5IHdoZXRoZXIgYSAucHJvdG8gZmlsZQorICAgIHVzZXMgcHJvdG8yIG9yIHByb3RvMzoKIAotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKKyAgICAgIC8vIGZvby5wcm90bworICAgICAgc3ludGF4ID0gInByb3RvMyI7CisgICAgICBtZXNzYWdlIEJhciB7Li4ufQorCisgICAgSWYgb21pdHRlZCwgdGhlIHByb3RvY29sIGNvbXBpbGVyIHdpbGwgZ2VuZXJhdGUgYSB3YXJuaW5nIGFuZCAicHJvdG8yIiB3aWxsCisgICAgYmUgdXNlZCBhcyB0aGUgZGVmYXVsdC4gVGhpcyB3YXJuaW5nIHdpbGwgYmUgdHVybmVkIGludG8gYW4gZXJyb3IgaW4gYQorICAgIGZ1dHVyZSByZWxlYXNlLgorCisgICAgV2UgcmVjb21tZW5kIHRoYXQgbmV3IFByb3RvY29sIEJ1ZmZlcnMgdXNlcnMgdXNlIHByb3RvMy4gSG93ZXZlciwgd2UgZG8gbm90CisgICAgZ2VuZXJhbGx5IHJlY29tbWVuZCB0aGF0IGV4aXN0aW5nIHVzZXJzIG1pZ3JhdGUgZnJvbSBwcm90bzIgZnJvbSBwcm90bzMgZHVlCisgICAgdG8gQVBJIGluY29tcGF0aWJpbGl0eSwgYW5kIHdlIHdpbGwgY29udGludWUgdG8gc3VwcG9ydCBwcm90bzIgZm9yIGEgbG9uZworICAgIHRpbWUuCisKKyAgKiBBZGRlZCBzdXBwb3J0IGZvciBtYXAgZmllbGRzIChpbXBsZW1lbnRlZCBpbiBDKysvSmF2YSBmb3IgYm90aCBwcm90bzIgYW5kCisgICAgcHJvdG8zKS4KKworICAgIE1hcCBmaWVsZHMgY2FuIGJlIGRlY2xhcmVkIHVzaW5nIHRoZSBmb2xsb3dpbmcgc3ludGF4OgorCisgICAgICBtZXNzYWdlIEZvbyB7CisgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFsdWVzID0gMTsKKyAgICAgIH0KKworICAgIERhdGEgb2YgYSBtYXAgZmllbGQgd2lsbCBiZSBzdG9yZWQgaW4gbWVtb3J5IGFzIGFuIHVub3JkZXJlZCBtYXAgYW5kIGl0CisgICAgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggZ2VuZXJhdGVkIGFjY2Vzc29ycy4KKworICBDKysKKyAgKiBBZGRlZCBhcmVuYSBhbGxvY2F0aW9uIHN1cHBvcnQgKGZvciBib3RoIHByb3RvMiBhbmQgcHJvdG8zKS4KKworICAgIFByb2ZpbGluZyBzaG93cyBtZW1vcnkgYWxsb2NhdGlvbiBhbmQgZGVhbGxvY2F0aW9uIGNvbnN0aXR1dGVzIGEgc2lnbmlmaWNhbnQKKyAgICBmcmFjdGlvbiBvZiBDUFUtdGltZSBzcGVudCBpbiBwcm90b2J1ZiBjb2RlIGFuZCBhcmVuYSBhbGxvY2F0aW9uIGlzIGEKKyAgICB0ZWNobmlxdWUgaW50cm9kdWNlZCB0byByZWR1Y2UgdGhpcyBjb3N0LiBXaXRoIGFyZW5hIGFsbG9jYXRpb24sIG5ldworICAgIG9iamVjdHMgd2lsbCBiZSBhbGxvY2F0ZWQgZnJvbSBhIGxhcmdlIHBpZWNlIG9mIHByZWFsbG9jYXRlZCBtZW1vcnkgYW5kCisgICAgZGVhbGxvY2F0aW9uIG9mIHRoZXNlIG9iamVjdHMgaXMgYWxtb3N0IGZyZWUuIEVhcmx5IGFkb3B0aW9uIHNob3dzIDIwJSB0bworICAgIDUwJSBpbXByb3ZlbWVudCBpbiBzb21lIEdvb2dsZSBiaW5hcmllcy4KKworICAgIFRvIGVuYWJsZSBhcmVuYSBzdXBwb3J0LCBhZGQgdGhlIGZvbGxvd2luZyBvcHRpb24gdG8geW91ciAucHJvdG8gZmlsZToKKworICAgICAgb3B0aW9uIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworCisgICAgUHJvdG9jb2wgY29tcGlsZXIgd2lsbCBnZW5lcmF0ZSBhZGRpdGlvbmFsIGNvZGUgdG8gbWFrZSB0aGUgZ2VuZXJhdGVkCisgICAgbWVzc2FnZSBjbGFzc2VzIHdvcmsgd2l0aCBhcmVuYXMuIFRoaXMgZG9lcyBub3QgY2hhbmdlIHRoZSBleGlzdGluZyBBUEkKKyAgICBvZiBwcm90b2J1ZiBtZXNzYWdlcyBhbmQgZG9lcyBub3QgYWZmZWN0IHdpcmUgZm9ybWF0LiBZb3VyIGV4aXN0aW5nIGNvZGUKKyAgICBzaG91bGQgY29udGludWUgdG8gd29yayBhZnRlciBhZGRpbmcgdGhpcyBvcHRpb24uIEluIHRoZSBmdXR1cmUgd2Ugd2lsbAorICAgIG1ha2UgdGhpcyBvcHRpb24gZW5hYmxlZCBieSBkZWZhdWx0LgorCisgICAgVG8gYWN0dWFsbHkgdGFrZSBhZHZhbnRhZ2Ugb2YgYXJlbmEgYWxsb2NhdGlvbiwgeW91IG5lZWQgdG8gdXNlIHRoZSBhcmVuYQorICAgIEFQSXMgd2hlbiBjcmVhdGluZyBtZXNzYWdlcy4gQSBxdWljayBleGFtcGxlIG9mIHVzaW5nIHRoZSBhcmVuYSBBUEk6CisKKyAgICAgIHsKKyAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmE7CisgICAgICAgIC8vIEFsbG9jYXRlIGEgcHJvdG9idWYgbWVzc2FnZSBpbiB0aGUgYXJlbmEuCisgICAgICAgIE15TWVzc2FnZSogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPE15TWVzc2FnZT4oJmFyZW5hKTsKKyAgICAgICAgLy8gQWxsIHN1Ym1lc3NhZ2VzIHdpbGwgYmUgYWxsb2NhdGVkIGluIHRoZSBzYW1lIGFyZW5hLgorICAgICAgICBpZiAoIW1lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhkYXRhKSkgeworICAgICAgICAgIC8vIERlYWwgd2l0aCBtYWxmb3JtZWQgaW5wdXQgZGF0YS4KKyAgICAgICAgfQorICAgICAgICAvLyBNdXN0IG5vdCBkZWxldGUgdGhlIG1lc3NhZ2UgaGVyZS4gSXQgd2lsbCBiZSBkZWxldGVkIGF1dG9tYXRpY2FsbHkKKyAgICAgICAgLy8gd2hlbiB0aGUgYXJlbmEgaXMgZGVzdHJveWVkLgorICAgICAgfQorCisgICAgQ3VycmVudGx5IGFyZW5hIGRvZXMgbm90IHdvcmsgd2l0aCBtYXAgZmllbGRzLiBFbmFibGluZyBhcmVuYSBpbiBhIC5wcm90bworICAgIGZpbGUgY29udGFpbmluZyBtYXAgZmllbGRzIHdpbGwgcmVzdWx0IGluIGNvbXBpbGUgZXJyb3JzIGluIHRoZSBnZW5lcmF0ZWQKKyAgICBjb2RlLiBUaGlzIHdpbGwgYmUgYWRkcmVzc2VkIGluIGEgZnV0dXJlIHJlbGVhc2UuCisKKzIwMTQtMTAtMjAgdmVyc2lvbiAyLjYuMToKKworICBDKysKKyAgKiBBZGRlZCBhdG9taWNvcHMgc3VwcG9ydCBmb3IgU29sYXJpcy4KKyAgKiBSZWxlYXNlZCBtZW1vcnkgYWxsb2NhdGVkIGJ5IEluaXRpYWxpemVEZWZhdWx0UmVwZWF0ZWRGaWVsZHMoKSBhbmQKKyAgICBHZXRFbXB0eVN0cmluZygpLiBTb21lIG1lbW9yeSBzYW5pdGl6ZXJzIHJlcG9ydGVkIHRoZW0gYXMgbWVtb3J5IGxlYWtzLgorCisgIEphdmEKKyAgKiBVcGRhdGVkIER5bmFtaWNNZXNzYWdlLnNldEZpZWxkKCkgdG8gaGFuZGxlIHJlcGVhdGVkIGVudW0gdmFsdWVzCisgICAgY29ycmVjdGx5LgorICAqIEZpeGVkIGEgYnVnIHRoYXQgY2F1c2VkIE51bGxQb2ludGVyRXhjZXB0aW9uIHRvIGJlIHRocm93biB3aGVuCisgICAgY29udmVydGluZyBtYW51YWxseSBjb25zdHJ1Y3RlZCBGaWxlRGVzY3JpcHRvclByb3RvIHRvCisgICAgRmlsZURlc2NyaXB0b3IuCisKKyAgUHl0aG9uCisgICogRml4ZWQgV2hpY2hPbmVvZigpIHRvIHdvcmsgd2l0aCBkZS1zZXJpYWxpemVkIHByb3RvYnVmIG1lc3NhZ2VzLgorICAqIEZpeGVkIGEgbWlzc2luZyBmaWxlIHByb2JsZW0gb2YgUHl0aG9uIEMrKyBpbXBsZW1lbnRhdGlvbi4KKworMjAxNC0wOC0xNSB2ZXJzaW9uIDIuNi4wOgorCisgIEdlbmVyYWwKKyAgKiBBZGRlZCBvbmVvZnModW5pb25zKSBmZWF0dXJlLiBGaWVsZHMgaW4gdGhlIHNhbWUgb25lb2Ygd2lsbCBzaGFyZQorICAgIG1lbW9yeSBhbmQgYXQgbW9zdCBvbmUgZmllbGQgY2FuIGJlIHNldCBhdCB0aGUgc2FtZSB0aW1lLiBVc2UgdGhlCisgICAgb25lb2Yga2V5d29yZCB0byBkZWZpbmUgYSBvbmVvZiBsaWtlOgorICAgICAgbWVzc2FnZSBTYW1wbGVNZXNzYWdlIHsKKyAgICAgICAgb25lb2YgdGVzdF9vbmVvZiB7CisgICAgICAgICAgc3RyaW5nIG5hbWUgPSA0OworICAgICAgICAgIFlvdXJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gOTsKKyAgICAgICAgfQorICAgICAgfQorICAqIEZpbGVzLCBzZXJ2aWNlcywgZW51bXMsIG1lc3NhZ2VzLCBtZXRob2RzIGFuZCBlbnVtIHZhbHVlcyBjYW4gYmUgbWFya2VkCisgICAgYXMgZGVwcmVjYXRlZCBub3cuCisgICogQWRkZWQgU3VwcG9ydCBmb3IgbGlzdCB2YWx1ZXMsIGluY2x1ZGluZyBsaXN0cyBvZiBtZXNhYWdlcywgd2hlbgorICAgIHBhcnNpbmcgdGV4dC1mb3JtYXR0ZWQgcHJvdG9zIGluIEMrKyBhbmQgSmF2YS4KKyAgICAgIEZvciBleGFtcGxlOiAgZm9vOiBbMSwgMiwgM10KKworICBDKysKKyAgKiBFbmhhbmNlZCBjdXN0b21pemF0aW9uIG9uIFRlc3RGb3JtYXQgcHJpbnRpbmcuCisgICogQWRkZWQgU3dhcEZpZWxkcygpIGluIHJlZmxlY3Rpb24gQVBJIHRvIHN3YXAgYSBzdWJzZXQgb2YgZmllbGRzLgorICAgIEFkZGVkIFNldEFsbG9jYXRlZE1lc3NhZ2UoKSBpbiByZWZsZWN0aW9uIEFQSS4KKyAgKiBSZXBlYXRlZCBwcmltaXRpdmUgZXh0ZW5zaW9ucyBhcmUgbm93IHBhY2thYmxlLiBUaGUKKyAgICBbcGFja2VkPXRydWVdIG9wdGlvbiBvbmx5IGFmZmVjdHMgc2VyaWFsaXplcnMuIFRoZXJlZm9yZSwgaXQgaXMKKyAgICBwb3NzaWJsZSB0byBzd2l0Y2ggYSByZXBlYXRlZCBleHRlbnNpb24gZmllbGQgdG8gcGFja2VkIGZvcm1hdAorICAgIHdpdGhvdXQgYnJlYWtpbmcgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCisgICogVmFyaW91cyBzcGVlZCBvcHRpbWl6YXRpb25zLgorCisgIEphdmEKKyAgKiB3cml0ZVRvKCkgbWV0aG9kIGluIEJ5dGVTdHJpbmcgY2FuIG5vdyB3cml0ZSBhIHN1YnN0cmluZyB0byBhbgorICAgIG91dHB1dCBzdHJlYW0uIEFkZGVkIGVuZFdpdGgoKSBtZXRob2QgZm9yIEJ5dGVTdHJpbmcuCisgICogQnl0ZVN0cmluZyBhbmQgQnl0ZUJ1ZmZlciBhcmUgbm93IHN1cHBvcnRlZCBpbiBDb2RlZElucHV0U3RyZWFtCisgICAgYW5kIENvZGVkT3V0cHV0U3RyZWFtLgorICAqIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoIGNhbiBub3cgYmUgdXNlZCB3aXRoIHRoZSBMSVRFX1JVTlRJTUUuCisKKyAgUHl0aG9uCisgICogQSBuZXcgQysrLWJhY2tlZCBleHRlbnNpb24gbW9kdWxlIChha2EgImNwcCBhcGkgdjIiKSB0aGF0IHJlcGxhY2VzIHRoZQorICAgIG9sZCAoImNwcCBhcGkgdjEiKSBvbmUuICBNdWNoIGZhc3RlciB0aGFuIHRoZSBwdXJlIFB5dGhvbiBjb2RlLiAgVGhpcyBvbmUKKyAgICByZXNvbHZlcyBtYW55IGJ1Z3MgYW5kIGlzIHJlY29tbWVuZGVkIGZvciBnZW5lcmFsIHVzZSBvdmVyIHRoZQorICAgIHB1cmUgUHl0aG9uIHdoZW4gcG9zc2libGUuCisgICogRGVzY3JpcHRvcnMgbm93IGhhdmUgZW51bV90eXBlc19ieV9uYW1lIGFuZCBleHRlbnNpb25fdHlwZXNfYnlfbmFtZSBkaWN0CisgICAgYXR0cmlidXRlcy4KKyAgKiBTdXBwb3J0IGZvciBQeXRob24gMy4KKworMjAxMy0wMi0yNyB2ZXJzaW9uIDIuNS4wOgorCisgIEdlbmVyYWwKKyAgKiBOZXcgbm90aW9uICJpbXBvcnQgcHVibGljIiB0aGF0IGFsbG93cyBhIHByb3RvIGZpbGUgdG8gZm9yd2FyZCB0aGUgY29udGVudAorICAgIGl0IGltcG9ydHMgdG8gaXRzIGltcG9ydGVycy4gRm9yIGV4YW1wbGUsCisgICAgICAvLyBmb28ucHJvdG8KKyAgICAgIGltcG9ydCBwdWJsaWMgImJhci5wcm90byI7CisgICAgICBpbXBvcnQgImJhei5wcm90byI7CisKKyAgICAgIC8vIHF1eC5wcm90bworICAgICAgaW1wb3J0ICJmb28ucHJvdG8iOworICAgICAgLy8gU3R1ZmYgZGVmaW5lZCBpbiBiYXIucHJvdG8gbWF5IGJlIHVzZWQgaW4gdGhpcyBmaWxlLCBidXQgc3R1ZmYgZnJvbQorICAgICAgLy8gYmF6LnByb3RvIG1heSBOT1QgYmUgdXNlZCB3aXRob3V0IGltcG9ydGluZyBpdCBleHBsaWNpdGx5LgorICAgIFRoaXMgaXMgdXNlZnVsIGZvciBtb3ZpbmcgcHJvdG8gZmlsZXMuIFRvIG1vdmUgYSBwcm90byBmaWxlLCBqdXN0IGxlYXZlCisgICAgYSBzaW5nbGUgImltcG9ydCBwdWJsaWMiIGluIHRoZSBvbGQgcHJvdG8gZmlsZS4KKyAgKiBOZXcgZW51bSBvcHRpb24gImFsbG93X2FsaWFzIiB0aGF0IHNwZWNpZmllcyB3aGV0aGVyIGRpZmZlcmVudCBzeW1ib2xzIGNhbgorICAgIGJlIGFzc2lnbmVkIHRoZSBzYW1lIG51bWVyaWMgdmFsdWUuIERlZmF1bHQgdmFsdWUgaXMgInRydWUiLiBTZXR0aW5nIGl0IHRvCisgICAgZmFsc2UgY2F1c2VzIHRoZSBjb21waWxlciB0byByZWplY3QgZW51bSBkZWZpbml0aW9ucyB3aGVyZSBtdWx0aXBsZSBzeW1ib2xzCisgICAgaGF2ZSB0aGUgc2FtZSBudW1lcmljIHZhbHVlLgorICAgIE5vdGU6IFdlIHBsYW4gdG8gZmxpcCB0aGUgZGVmYXVsdCB2YWx1ZSB0byAiZmFsc2UiIGluIGEgZnV0dXJlIHJlbGVhc2UuCisgICAgUHJvamVjdHMgdXNpbmcgZW51bSBhbGlhc2VzIHNob3VsZCBzZXQgdGhlIG9wdGlvbiB0byAidHJ1ZSIgaW4gdGhlaXIgLnByb3RvCisgICAgZmlsZXMuCisKKyAgQysrCisgICogTmV3IGdlbmVyYXRlZCBtZXRob2Qgc2V0X2FsbG9jYXRlZF9mb28oVHlwZSogZm9vKSBmb3IgbWVzc2FnZSBhbmQgc3RyaW5nCisgICAgZmllbGRzLiBUaGlzIG1ldGhvZCBhbGxvd3MgeW91IHRvIHNldCB0aGUgZmllbGQgdG8gYSBwcmUtYWxsb2NhdGVkIG9iamVjdAorICAgIGFuZCB0aGUgY29udGFpbmluZyBtZXNzYWdlIHRha2VzIHRoZSBvd25lcnNoaXAgb2YgdGhhdCBvYmplY3QuCisgICogQWRkZWQgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uKCkgYW5kIFJlbGVhc2VFeHRlbnNpb24oKSB0byBleHRlbnNpb25zIEFQSS4KKyAgKiBDdXN0b20gb3B0aW9ucyBhcmUgbm93IGZvcm1hdHRlZCBjb3JyZWN0bHkgd2hlbiBkZXNjcmlwdG9ycyBhcmUgcHJpbnRlZCBpbgorICAgIHRleHQgZm9ybWF0LgorICAqIFZhcmlvdXMgc3BlZWQgb3B0aW1pemF0aW9ucy4KKworICBKYXZhCisgICogQ29tbWVudHMgaW4gcHJvdG8gZmlsZXMgYXJlIG5vdyBjb2xsZWN0ZWQgYW5kIHB1dCBpbnRvIGdlbmVyYXRlZCBjb2RlIGFzCisgICAgY29tbWVudHMgZm9yIGNvcnJlc3BvbmRpbmcgY2xhc3NlcyBhbmQgZGF0YSBtZW1iZXJzLgorICAqIEFkZGVkIFBhcnNlciB0byBwYXJzZSBkaXJlY3RseSBpbnRvIG1lc3NhZ2VzIHdpdGhvdXQgYSBCdWlsZGVyLiBGb3IKKyAgICBleGFtcGxlLAorICAgICAgRm9vIGZvbyA9IEZvby5QQVJTRVIuUGFyc2VGcm9tKGlucHV0KTsKKyAgICBVc2luZyBQYXJzZXIgaXMgfjI1JSBmYXN0ZXIgdGhhbiB1c2luZyBCdWlsZGVyIHRvIHBhcnNlIG1lc3NhZ2VzLgorICAqIEFkZGVkIGdldHRlcnMvc2V0dGVycyB0byBhY2Nlc3MgdGhlIHVuZGVybHlpbmcgQnl0ZVN0cmluZyBvZiBhIHN0cmluZyBmaWVsZAorICAgIGRpcmVjdGx5LgorICAqIEJ5dGVTdHJpbmcgbm93IHN1cHBvcnRzIG1vcmUgb3BlcmF0aW9uczogc3Vic3RyaW5nKCksIHByZXBlbmQoKSwgYW5kCisgICAgYXBwZW5kKCkuIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiBCeXRlU3RyaW5nIHVzZXMgYSBiaW5hcnkgdHJlZSBzdHJ1Y3R1cmUKKyAgICB0byBzdXBwb3J0IHRoZXNlIG9wZXJhdGlvbnMgZWZmaWNpZW50bHkuCisgICogTmV3IG1ldGhvZCBmaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoKSB0aGF0IGxpc3RzIGFsbCBtaXNzaW5nIHJlcXVpcmVkCisgICAgZmllbGRzLgorICAqIFZhcmlvdXMgY29kZSBzaXplIGFuZCBzcGVlZCBvcHRpbWl6YXRpb25zLgorCisgIFB5dGhvbgorICAqIEFkZGVkIHN1cHBvcnQgZm9yIGR5bmFtaWMgbWVzc2FnZSBjcmVhdGlvbi4gRGVzY3JpcHRvckRhdGFiYXNlLAorICAgIERlc2NyaXB0b3JQb29sLCBhbmQgTWVzc2FnZUZhY3Rvcnkgd29yayBsaWtlIHRoZWlyIEMrKyBjb3V0ZXJwYXJ0cyB0bworICAgIHNpbXBsaWZ5IERlc2NyaXB0b3IgY29uc3RydWN0aW9uIGZyb20gKkRlc2NyaXB0b3JQcm90b3MsIGFuZCBNZXNzYWdlRmFjdG9yeQorICAgIHByb3ZpZGVzIGEgbWVzc2FnZSBpbnN0YW5jZSBmcm9tIGEgRGVzY3JpcHRvci4KKyAgKiBBZGRlZCBwaWNrbGUgc3VwcG9ydCBmb3IgcHJvdG9idWYgbWVzc2FnZXMuCisgICogVW5rbm93biBmaWVsZHMgYXJlIG5vdyBwcmVzZXJ2ZWQgYWZ0ZXIgcGFyc2luZy4KKyAgKiBGaXhlZCBidWcgd2hlcmUgY3VzdG9tIG9wdGlvbnMgd2VyZSBub3QgY29ycmVjdGx5IHBvcHVsYXRlZC4gQ3VzdG9tCisgICAgb3B0aW9ucyBjYW4gYmUgYWNjZXNzZWQgbm93LgorICAqIEFkZGVkIEVudW1UeXBlV3JhcHBlciB0aGF0IHByb3ZpZGVzIGJldHRlciBhY2Nlc3NpYmlsaXR5IHRvIGVudW0gdHlwZXMuCisgICogQWRkZWQgUGFyc2VNZXNzYWdlKGRlc2NyaXB0b3IsIGJ5dGVzKSB0byBnZW5lcmF0ZSBhIG5ldyBNZXNzYWdlIGluc3RhbmNlCisgICAgZnJvbSBhIGRlc2NyaXB0b3IgYW5kIGEgYnl0ZSBzdHJpbmcuCisKKzIwMTEtMDUtMDEgdmVyc2lvbiAyLjQuMToKKworICBDKysKKyAgKiBGaXhlZCB0aGUgZnJlbmRzaGlwIHByb2JsZW0gZm9yIG9sZCBjb21waWxlcnMgdG8gbWFrZSB0aGUgbGlicmFyeSBub3cgZ2NjIDMKKyAgICBjb21wYXRpYmxlIGFnYWluLgorICAqIEZpeGVkIHZjcHJvamVjdHMvZXh0cmFjdF9pbmNsdWRlcy5iYXQgdG8gZXh0cmFjdCBjb21waWxlci9wbHVnaW4uaC4KKworICBKYXZhCisgICogUmVtb3ZlZCB1c2FnZXMgb2YgSkRLIDEuNiBvbmx5IGZlYXR1cmVzIHRvIG1ha2UgdGhlIGxpYnJhcnkgbm93IEpESyAxLjUKKyAgICBjb21wYXRpYmxlIGFnYWluLgorICAqIEZpeGVkIGEgYnVnIGFib3V0IG5lZ2F0aXZlIGVudW0gdmFsdWVzLgorICAqIHNlcmlhbFZlcnNpb25VSUQgaXMgbm93IGRlZmluZWQgaW4gZ2VuZXJhdGVkIG1lc3NhZ2VzIGZvciBqYXZhIHNlcmlhbGl6aW5nLgorICAqIEZpeGVkIHByb3RvYyB0byB1c2UgamF2YS5sYW5nLk9iamVjdCwgd2hpY2ggbWFrZXMgIk9iamVjdCIgbm93IGEgdmFsaWQKKyAgICBtZXNzYWdlIG5hbWUgYWdhaW4uCisKKyAgUHl0aG9uCisgICogRXhwZXJpbWVudGFsIEMrKyBpbXBsZW1lbnRhdGlvbiBub3cgcmVxdWlyZXMgQysrIHByb3RvYnVmIGxpYnJhcnkgaW5zdGFsbGVkLgorICAgIFNlZSB0aGUgUkVBRE1FLnR4dCBpbiB0aGUgcHl0aG9uIGRpcmVjdG9yeSBmb3IgZGV0YWlscy4KKworMjAxMS0wMi0wMiB2ZXJzaW9uIDIuNC4wOgorCisgIEdlbmVyYWwKKyAgKiBUaGUgUlBDIChjY3xqYXZhfHB5KV9nZW5lcmljX3NlcnZpY2VzIGRlZmF1bHQgdmFsdWUgaXMgbm93IGZhbHNlIGluc3RlYWQgb2YKKyAgICB0cnVlLgorICAqIEN1c3RvbSBvcHRpb25zIGNhbiBoYXZlIGFnZ3JlZ2F0ZSB0eXBlcy4gRm9yIGV4YW1wbGUsCisgICAgICBtZXNzYWdlIE15T3B0aW9uIHsKKyAgICAgICAgb3B0aW9uYWwgc3RyaW5nIGNvbW1lbnQgPSAxOworICAgICAgICBvcHRpb25hbCBzdHJpbmcgYXV0aG9yID0gMjsKKyAgICAgIH0KKyAgICAgIGV4dGVuZCBnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsKKyAgICAgICAgb3B0aW9uYWwgTXlPcHRpb24gbXlvcHRpb24gPSAxMjM0NTsKKyAgICAgIH0KKyAgICBUaGlzIG9wdGlvbiBjYW4gbm93IGJlIHNldCBhcyBmb2xsb3dzOgorICAgICAgbWVzc2FnZSBTb21lVHlwZSB7CisgICAgICAgIG9wdGlvbmFsIGludDMyIGZpZWxkID0gMSBbKG15b3B0aW9uKSA9IHsgY29tbWVudDoneCcgYXV0aG9yOid5JyB9XTsKKyAgICAgIH0KKworICBDKysKKyAgKiBWYXJpb3VzIHNwZWVkIGFuZCBjb2RlIHNpemUgb3B0aW1pemF0aW9ucy4KKyAgKiBBZGRlZCBhIHJlbGVhc2VfZm9vKCkgbWV0aG9kIG9uIHN0cmluZyBhbmQgbWVzc2FnZSBmaWVsZHMuCisgICogRml4ZWQgZ3ppcF9vdXRwdXRfc3RyZWFtIHN1Yi1zdHJlYW0gaGFuZGxpbmcuCisKKyAgSmF2YQorICAqIEJ1aWxkZXJzIG5vdyBtYWludGFpbiBzdWItYnVpbGRlcnMgZm9yIHN1Yi1tZXNzYWdlcy4gVXNlIGdldEZvb0J1aWxkZXIoKSB0bworICAgIGdldCB0aGUgYnVpbGRlciBmb3IgdGhlIHN1Yi1tZXNzYWdlICJmb28iLiBUaGlzIGFsbG93cyB5b3UgdG8gcmVwZWF0ZWRseQorICAgIG1vZGlmeSBkZWVwbHktbmVzdGVkIHN1Yi1tZXNzYWdlcyB3aXRob3V0IHJlYnVpbGRpbmcgdGhlbS4KKyAgKiBCdWlsZGVyLmJ1aWxkKCkgbm8gbG9uZ2VyIGludmFsaWRhdGVzIHRoZSBCdWlsZGVyIGZvciBnZW5lcmF0ZWQgbWVzc2FnZXMKKyAgICAoWW91IG1heSBjb250aW51ZSB0byBtb2RpZnkgaXQgYW5kIHRoZW4gYnVpbGQgYW5vdGhlciBtZXNzYWdlKS4KKyAgKiBDb2RlIGdlbmVyYXRvciB3aWxsIGdlbmVyYXRlIGVmZmljaWVudCBlcXVhbHMoKSBhbmQgaGFzaENvZGUoKQorICAgIGltcGxlbWVudGF0aW9ucyBpZiBuZXcgb3B0aW9uIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoIGlzIGVuYWJsZWQuCisgICAgKE90aGVyd2lzZSwgcmVmbGVjdGlvbi1iYXNlZCBpbXBsZW1lbnRhdGlvbnMgYXJlIHVzZWQuKQorICAqIEdlbmVyYXRlZCBtZXNzYWdlcyBub3cgaW1wbGVtZW50IFNlcmlhbGl6YWJsZS4KKyAgKiBGaWVsZHMgd2l0aCBbZGVwcmVjYXRlZD10cnVlXSB3aWxsIGJlIG1hcmtlZCB3aXRoIEBEZXByZWNhdGVkIGluIEphdmEuCisgICogQWRkZWQgbGF6eSBjb252ZXJzaW9uIG9mIFVURi04IGVuY29kZWQgc3RyaW5ncyB0byBTdHJpbmcgb2JqZWN0cyB0byBpbXByb3ZlCisgICAgcGVyZm9ybWFuY2UuCisgICogVmFyaW91cyBvcHRpbWl6YXRpb25zLgorICAqIEVudW0gdmFsdWUgY2FuIGJlIGFjY2Vzc2VkIGRpcmVjdGx5LCBpbnN0ZWFkIG9mIGNhbGxpbmcgZ2V0TnVtYmVyKCkgb24gdGhlCisgICAgZW51bSBtZW1iZXIuCisgICogRm9yIGVhY2ggZW51bSB2YWx1ZSwgYW4gaW50ZWdlciBjb25zdGFudCBpcyBhbHNvIGdlbmVyYXRlZCB3aXRoIHRoZSBzdWZmaXgKKyAgICBfVkFMVUUuCisKKyAgUHl0aG9uCisgICogQWRkZWQgYW4gZXhwZXJpbWVudGFsICBDKysgaW1wbGVtZW50YXRpb24gZm9yIFB5dGhvbiBtZXNzYWdlcyB2aWEgYSBQeXRob24KKyAgICBleHRlbnNpb24uIEltcGxlbWVudGF0aW9uIHR5cGUgaXMgY29udHJvbGxlZCBieSBhbiBlbnZpcm9ubWVudCB2YXJpYWJsZQorICAgIFBST1RPQ09MX0JVRkZFUlNfUFlUSE9OX0lNUExFTUVOVEFUSU9OICh2YWxpZCB2YWx1ZXM6ICJjcHAiIGFuZCAicHl0aG9uIikKKyAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBjdXJyZW50bHkgInB5dGhvbiIgYnV0IHdpbGwgYmUgY2hhbmdlZCB0byAiY3BwIiBpbgorICAgIGZ1dHVyZSByZWxlYXNlLgorICAqIEltcHJvdmVkIHBlcmZvcm1hbmNlIG9uIG1lc3NhZ2UgaW5zdGFudGlhdGlvbiBzaWduaWZpY2FudGx5LgorICAgIE1vc3Qgb2YgdGhlIHdvcmsgb24gbWVzc2FnZSBpbnN0YW50aWF0aW9uIGlzIGRvbmUganVzdCBvbmNlIHBlciBtZXNzYWdlCisgICAgY2xhc3MsIGluc3RlYWQgb2Ygb25jZSBwZXIgbWVzc2FnZSBpbnN0YW5jZS4KKyAgKiBJbXByb3ZlZCBwZXJmb3JtYW5jZSBvbiB0ZXh0IG1lc3NhZ2UgcGFyc2luZy4KKyAgKiBBbGxvdyBhZGQoKSB0byBmb3J3YXJkIGtleXdvcmQgYXJndW1lbnRzIHRvIHRoZSBjb25jcmV0ZSBjbGFzcy4KKyAgICAgIEUuZy4gaW5zdGVhZCBvZgorICAgICAgICBpdGVtID0gcmVwZWF0ZWRfZmllbGQuYWRkKCkKKyAgICAgICAgaXRlbS5mb28gPSBiYXIKKyAgICAgICAgaXRlbS5iYXogPSBxdXV4CisgICAgICBZb3UgY2FuIGRvOgorICAgICAgICByZXBlYXRlZF9maWVsZC5hZGQoZm9vPWJhciwgYmF6PXF1dXgpCisgICogQWRkZWQgYSBzb3J0KCkgaW50ZXJmYWNlIHRvIHRoZSBCYXNlQ29udGFpbmVyLgorICAqIEFkZGVkIGFuIGV4dGVuZCgpIG1ldGhvZCB0byByZXBlYXRlZCBjb21wb3NpdGUgZmllbGRzLgorICAqIEFkZGVkIFVURjggZGVidWcgc3RyaW5nIHN1cHBvcnQuCisKKzIwMTAtMDEtMDggdmVyc2lvbiAyLjMuMDoKKworICBHZW5lcmFsCisgICogUGFyc2VycyBmb3IgcmVwZWF0ZWQgbnVtZXJpYyBmaWVsZHMgbm93IGFsd2F5cyBhY2NlcHQgYm90aCBwYWNrZWQgYW5kCisgICAgdW5wYWNrZWQgaW5wdXQuICBUaGUgW3BhY2tlZD10cnVlXSBvcHRpb24gb25seSBhZmZlY3RzIHNlcmlhbGl6ZXJzLgorICAgIFRoZXJlZm9yZSwgaXQgaXMgcG9zc2libGUgdG8gc3dpdGNoIGEgZmllbGQgdG8gcGFja2VkIGZvcm1hdCB3aXRob3V0CisgICAgYnJlYWtpbmcgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgLS0gYXMgbG9uZyBhcyBhbGwgcGFydGllcyBhcmUgdXNpbmcKKyAgICBwcm90b2J1ZiAyLjMuMCBvciBhYm92ZSwgYXQgbGVhc3QuCisgICogVGhlIGdlbmVyaWMgUlBDIHNlcnZpY2UgY29kZSBnZW5lcmF0ZWQgYnkgdGhlIEMrKywgSmF2YSwgYW5kIFB5dGhvbgorICAgIGdlbmVyYXRvcnMgY2FuIGJlIGRpc2FibGVkIHZpYSBmaWxlIG9wdGlvbnM6CisgICAgICBvcHRpb24gY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IGZhbHNlOworICAgICAgb3B0aW9uIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IGZhbHNlOworICAgICAgb3B0aW9uIHB5X2dlbmVyaWNfc2VydmljZXMgPSBmYWxzZTsKKyAgICBUaGlzIGFsbG93cyBwbHVnaW5zIHRvIGdlbmVyYXRlIGFsdGVybmF0aXZlIGNvZGUsIHBvc3NpYmx5IHNwZWNpZmljIHRvIHNvbWUKKyAgICBwYXJ0aWN1bGFyIFJQQyBpbXBsZW1lbnRhdGlvbi4KKworICBwcm90b2MKKyAgKiBOb3cgc3VwcG9ydHMgYSBwbHVnaW4gc3lzdGVtIGZvciBjb2RlIGdlbmVyYXRvcnMuICBQbHVnaW5zIGNhbiBnZW5lcmF0ZQorICAgIGNvZGUgZm9yIG5ldyBsYW5ndWFnZXMgb3IgaW5qZWN0IGFkZGl0aW9uYWwgY29kZSBpbnRvIHRoZSBvdXRwdXQgb2Ygb3RoZXIKKyAgICBjb2RlIGdlbmVyYXRvcnMuICBQbHVnaW5zIGFyZSBqdXN0IGJpbmFyaWVzIHdoaWNoIGFjY2VwdCBhIHByb3RvY29sIGJ1ZmZlcgorICAgIG9uIHN0ZGluIGFuZCB3cml0ZSBhIHByb3RvY29sIGJ1ZmZlciB0byBzdGRvdXQsIHNvIHRoZXkgbWF5IGJlIHdyaXR0ZW4gaW4KKyAgICBhbnkgbGFuZ3VhZ2UuICBTZWUgc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8uCisgICAgKipXQVJOSU5HKio6ICBQbHVnaW5zIGFyZSBleHBlcmltZW50YWwuICBUaGUgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gYQorICAgIGZ1dHVyZSB2ZXJzaW9uLgorICAqIElmIHRoZSBvdXRwdXQgbG9jYXRpb24gZW5kcyBpbiAuemlwIG9yIC5qYXIsIHByb3RvYyB3aWxsIHdyaXRlIGl0cyBvdXRwdXQKKyAgICB0byBhIHppcC9qYXIgYXJjaGl2ZSBpbnN0ZWFkIG9mIGEgZGlyZWN0b3J5LiAgRm9yIGV4YW1wbGU6CisgICAgICBwcm90b2MgLS1qYXZhX291dD1teXByb3RvX3NyY3MuamFyIC0tcHl0aG9uX291dD1teXByb3RvLnppcCBteXByb3RvLnByb3RvCisgICAgQ3VycmVudGx5IHRoZSBhcmNoaXZlIGNvbnRlbnRzIGFyZSBub3QgY29tcHJlc3NlZCwgdGhvdWdoIHRoaXMgY291bGQgY2hhbmdlCisgICAgaW4gdGhlIGZ1dHVyZS4KKyAgKiBpbmYsIC1pbmYsIGFuZCBuYW4gY2FuIG5vdyBiZSB1c2VkIGFzIGRlZmF1bHQgdmFsdWVzIGZvciBmbG9hdCBhbmQgZG91YmxlCisgICAgZmllbGRzLgorCisgIEMrKworICAqIFZhcmlvdXMgc3BlZWQgYW5kIGNvZGUgc2l6ZSBvcHRpbWl6YXRpb25zLgorICAqIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBpcyBub3cgZnVsbHkgdGhyZWFkLXNhZmUuCisgICogTWVzc2FnZTo6VXRmOERlYnVnU3RyaW5nKCkgbWV0aG9kIGlzIGxpa2UgRGVidWdTdHJpbmcoKSBidXQgYXZvaWRzIGVzY2FwaW5nCisgICAgVVRGLTggYnl0ZXMuCisgICogQ29tcGlsZWQtaW4gbWVzc2FnZSB0eXBlcyBjYW4gbm93IGNvbnRhaW4gZHluYW1pYyBleHRlbnNpb25zLCB0aHJvdWdoIHVzZQorICAgIG9mIENvZGVkSW5wdXRTdHJlYW06OlNldEV4dGVuc2lvblJlZ2lzdHJ5KCkuCisgICogTm93IGNvbXBpbGVzIHNoYXJlZCBsaWJyYXJpZXMgKERMTHMpIGJ5IGRlZmF1bHQgb24gQ3lnd2luIGFuZCBNaW5HVywgdG8KKyAgICBtYXRjaCBvdGhlciBwbGF0Zm9ybXMuICBVc2UgLS1kaXNhYmxlLXNoYXJlZCB0byBhdm9pZCB0aGlzLgorCisgIEphdmEKKyAgKiBwYXJzZURlbGltaXRlZEZyb20oKSBhbmQgbWVyZ2VEZWxpbWl0ZWRGcm9tKCkgbm93IGRldGVjdCBFT0YgYW5kIHJldHVybgorICAgIGZhbHNlL251bGwgaW5zdGVhZCBvZiB0aHJvd2luZyBhbiBleGNlcHRpb24uCisgICogRml4ZWQgc29tZSBpbml0aWFsaXphdGlvbiBvcmRlcmluZyBidWdzLgorICAqIEZpeGVzIGZvciBPcGVuSkRLIDcuCisKKyAgUHl0aG9uCisgICogMTAtMjUgdGltZXMgZmFzdGVyIHRoYW4gMi4yLjAsIHN0aWxsIHB1cmUtUHl0aG9uLgorICAqIENhbGxpbmcgYSBtdXRhdGluZyBtZXRob2Qgb24gYSBzdWItbWVzc2FnZSBhbHdheXMgaW5zdGFudGlhdGVzIHRoZSBtZXNzYWdlCisgICAgaW4gaXRzIHBhcmVudCBldmVuIGlmIHRoZSBtdXRhdGluZyBtZXRob2QgZG9lc24ndCBhY3R1YWxseSBtdXRhdGUgYW55dGhpbmcKKyAgICAoZS5nLiBwYXJzaW5nIGZyb20gYW4gZW1wdHkgc3RyaW5nKS4KKyAgKiBFeHBhbmRlZCBkZXNjcmlwdG9ycyBhIGJpdC4KKworMjAwOS0wOC0xMSB2ZXJzaW9uIDIuMi4wOgorCisgIEMrKworICAqIExpdGUgbW9kZTogIFRoZSAib3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FIiBvcHRpb24gY2F1c2VzIHRoZSBjb21waWxlcgorICAgIHRvIGdlbmVyYXRlIGNvZGUgd2hpY2ggb25seSBkZXBlbmRzIGxpYnByb3RvYnVmLWxpdGUsIHdoaWNoIGlzIG11Y2ggc21hbGxlcgorICAgIHRoYW4gbGlicHJvdG9idWYgYnV0IGxhY2tzIGRlc2NyaXB0b3JzLCByZWZsZWN0aW9uLCBhbmQgc29tZSBvdGhlciBmZWF0dXJlcy4KKyAgKiBGaXhlZCBidWcgd2hlcmUgTWVzc2FnZS5Td2FwKE1lc3NhZ2UpIHdhcyBvbmx5IGltcGxlbWVudGVkIGZvcgorICAgIG9wdGltaXplX2Zvcl9zcGVlZC4gIFN3YXAgbm93IHByb3Blcmx5IGltcGxlbWVudGVkIGluIGJvdGggbW9kZXMKKyAgICAoSXNzdWUgOTEpLgorICAqIEFkZGVkIFJlbW92ZUxhc3QgYW5kIFN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4MikgdG8gUmVmbGVjdGlvbgorICAgIGludGVyZmFjZSBmb3IgcmVwZWF0ZWQgZWxlbWVudHMuCisgICogQWRkZWQgU3dhcChNZXNzYWdlKSB0byBSZWZsZWN0aW9uIGludGVyZmFjZS4KKyAgKiBGbG9hdGluZy1wb2ludCBsaXRlcmFscyBpbiBnZW5lcmF0ZWQgY29kZSB0aGF0IGFyZSBpbnRlbmRlZCB0byBiZQorICAgIHNpbmdsZS1wcmVjaXNpb24gbm93IGV4cGxpY2l0bHkgaGF2ZSAnZicgc3VmZml4IHRvIGF2b2lkIHBlZGFudGljIHdhcm5pbmdzCisgICAgcHJvZHVjZWQgYnkgc29tZSBjb21waWxlcnMuCisgICogVGhlIFtkZXByZWNhdGVkPXRydWVdIG9wdGlvbiBub3cgY2F1c2VzIHRoZSBDKysgY29kZSBnZW5lcmF0b3IgdG8gZ2VuZXJhdGUKKyAgICBhIEdDQy1zdHlsZSBkZXByZWNhdGlvbiBhbm5vdGF0aW9uIChuby1vcCBvbiBvdGhlciBjb21waWxlcnMpLgorICAqIGdvb2dsZTo6cHJvdG9idWY6OkdldEVudW1EZXNjcmlwdG9yPFNvbWVHZW5lcmF0ZWRFbnVtVHlwZT4oKSByZXR1cm5zIHRoZQorICAgIEVudW1EZXNjcmlwdG9yIGZvciB0aGF0IHR5cGUgLS0gdXNlZnVsIGZvciB0ZW1wbGF0ZXMgd2hpY2ggY2Fubm90IGNhbGwKKyAgICBTb21lR2VuZXJhdGVkRW51bVR5cGVfZGVzY3JpcHRvcigpLgorICAqIFZhcmlvdXMgb3B0aW1pemF0aW9ucyBhbmQgb2JzY3VyZSBidWcgZml4ZXMuCisKKyAgSmF2YQorICAqIExpdGUgbW9kZTogIFRoZSAib3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FIiBvcHRpb24gY2F1c2VzIHRoZSBjb21waWxlcgorICAgIHRvIGdlbmVyYXRlIGNvZGUgd2hpY2ggb25seSBkZXBlbmRzIGxpYnByb3RvYnVmLWxpdGUsIHdoaWNoIGlzIG11Y2ggc21hbGxlcgorICAgIHRoYW4gbGlicHJvdG9idWYgYnV0IGxhY2tzIGRlc2NyaXB0b3JzLCByZWZsZWN0aW9uLCBhbmQgc29tZSBvdGhlciBmZWF0dXJlcy4KKyAgKiBMb3RzIG9mIHN0eWxlIGNsZWFudXBzLgorCisgIFB5dGhvbgorICAqIEZpeGVkIGVuZGlhbm5lc3MgYnVnIHdpdGggZmxvYXRzIGFuZCBkb3VibGVzLgorICAqIFRleHQgZm9ybWF0IHBhcnNpbmcgc3VwcG9ydC4KKyAgKiBGaXggYnVnIHdpdGggcGFyc2luZyBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzIGluIGVtYmVkZGVkIG1lc3NhZ2VzLgorICAqIEFiaWxpdHkgdG8gaW5pdGlhbGl6ZSBmaWVsZHMgYnkgcGFzc2luZyBrZXl3b3JkIGFyZ3MgdG8gY29uc3RydWN0b3IuCisgICogU3VwcG9ydCBpdGVyYXRvcnMgaW4gZXh0ZW5kIGFuZCBfX3NldHNsaWNlX18gZm9yIGNvbnRhaW5lcnMuCisKKzIwMDktMDUtMTMgdmVyc2lvbiAyLjEuMDoKKworICBHZW5lcmFsCisgICogUmVwZWF0ZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlcyAodHlwZXMgb3RoZXIgdGhhdCBzdHJpbmcsIGdyb3VwLCBhbmQKKyAgICBuZXN0ZWQgbWVzc2FnZXMpIG1heSBub3cgdXNlIHRoZSBvcHRpb24gW3BhY2tlZCA9IHRydWVdIHRvIGdldCBhIG1vcmUKKyAgICBlZmZpY2llbnQgZW5jb2RpbmcuICBJbiB0aGUgbmV3IGVuY29kaW5nLCB0aGUgZW50aXJlIGxpc3QgaXMgd3JpdHRlbgorICAgIGFzIGEgc2luZ2xlIGJ5dGUgYmxvYiB1c2luZyB0aGUgImxlbmd0aC1kZWxpbWl0ZWQiIHdpcmUgdHlwZS4gIFdpdGhpbgorICAgIHRoaXMgYmxvYiwgdGhlIGluZGl2aWR1YWwgdmFsdWVzIGFyZSBlbmNvZGVkIHRoZSBzYW1lIHdheSB0aGV5IHdvdWxkCisgICAgYmUgbm9ybWFsbHkgZXhjZXB0IHdpdGhvdXQgYSB0YWcgYmVmb3JlIGVhY2ggdmFsdWUgKHRodXMsIHRoZXkgYXJlCisgICAgdGlnaHRseSAicGFja2VkIikuCisgICogRm9yIGVhY2ggZmllbGQsIHRoZSBnZW5lcmF0ZWQgY29kZSBjb250YWlucyBhbiBpbnRlZ2VyIGNvbnN0YW50IGFzc2lnbmVkCisgICAgdG8gdGhlIGZpZWxkIG51bWJlci4gIEZvciBleGFtcGxlLCB0aGUgLnByb3RvIGZpbGU6CisgICAgICBtZXNzYWdlIEZvbyB7IG9wdGlvbmFsIGludCBiYXJfYmF6ID0gMTIzOyB9CisgICAgd291bGQgZ2VuZXJhdGUgdGhlIGZvbGxvd2luZyBjb25zdGFudHMsIGFsbCB3aXRoIHRoZSBpbnRlZ2VyIHZhbHVlIDEyMzoKKyAgICAgIEMrKzogICAgIEZvbzo6a0JhckJhekZpZWxkTnVtYmVyCisgICAgICBKYXZhOiAgICBGb28uQkFSX0JBWl9GSUVMRF9OVU1CRVIKKyAgICAgIFB5dGhvbjogIEZvby5CQVJfQkFaX0ZJRUxEX05VTUJFUgorICAgIENvbnN0YW50cyBhcmUgYWxzbyBnZW5lcmF0ZWQgZm9yIGV4dGVuc2lvbnMsIHdpdGggdGhlIHNhbWUgbmFtaW5nIHNjaGVtZS4KKyAgICBUaGVzZSBjb25zdGFudHMgbWF5IGJlIHVzZWQgYXMgc3dpdGNoIGNhc2VzLgorICAqIFVwZGF0ZWQgYnVuZGxlZCBHb29nbGUgVGVzdCB0byB2ZXJzaW9uIDEuMy4wLiAgR29vZ2xlIFRlc3QgaXMgbm93IGJ1bmRsZWQKKyAgICBpbiBpdHMgdmVyYmF0aW0gZm9ybSBhcyBhIG5lc3RlZCBhdXRvY29uZiBwYWNrYWdlLCBzbyB5b3UgY2FuIGRyb3AgaW4gYW55CisgICAgb3RoZXIgdmVyc2lvbiBvZiBHb29nbGUgVGVzdCBpZiBuZWVkZWQuCisgICogb3B0aW1pemVfZm9yID0gU1BFRUQgaXMgbm93IHRoZSBkZWZhdWx0LCBieSBwb3B1bGFyIGRlbWFuZC4gIFVzZQorICAgIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpZiBjb2RlIHNpemUgaXMgbW9yZSBpbXBvcnRhbnQgaW4geW91ciBhcHAuCisgICogSXQgaXMgbm93IGFuIGVycm9yIHRvIGRlZmluZSBhIGRlZmF1bHQgdmFsdWUgZm9yIGEgcmVwZWF0ZWQgZmllbGQuCisgICAgUHJldmlvdXNseSwgdGhpcyB3YXMgc2lsZW50bHkgaWdub3JlZCAoaXQgaGFkIG5vIGVmZmVjdCBvbiB0aGUgZ2VuZXJhdGVkCisgICAgY29kZSkuCisgICogRmllbGRzIGNhbiBub3cgYmUgbWFya2VkIGRlcHJlY2F0ZWQgbGlrZToKKyAgICAgIG9wdGlvbmFsIGludDMyIGZvbyA9IDEgW2RlcHJlY2F0ZWQgPSB0cnVlXTsKKyAgICBDdXJyZW50bHkgdGhpcyBkb2VzIG5vdCBoYXZlIGFueSBhY3R1YWwgZWZmZWN0LCBidXQgaW4gdGhlIGZ1dHVyZSB0aGUgY29kZQorICAgIGdlbmVyYXRvcnMgbWF5IGdlbmVyYXRlIGRlcHJlY2F0aW9uIGFubm90YXRpb25zIGluIGVhY2ggbGFuZ3VhZ2UuCisgICogQ3Jvc3MtY29tcGlsaW5nIHNob3VsZCBub3cgYmUgcG9zc2libGUgdXNpbmcgdGhlIC0td2l0aC1wcm90b2Mgb3B0aW9uIHRvCisgICAgY29uZmlndXJlLiAgU2VlIFJFQURNRS50eHQgZm9yIG1vcmUgaW5mby4KKworICBwcm90b2MKKyAgKiAtLWVycm9yX2Zvcm1hdD1tc3ZzIG9wdGlvbiBjYXVzZXMgZXJyb3JzIHRvIGJlIHByaW50ZWQgaW4gVmlzdWFsIFN0dWRpbworICAgIGZvcm1hdCwgd2hpY2ggc2hvdWxkIGFsbG93IHRoZW0gdG8gYmUgY2xpY2tlZCBvbiBpbiB0aGUgYnVpbGQgbG9nIHRvIGdvCisgICAgZGlyZWN0bHkgdG8gdGhlIGVycm9yIGxvY2F0aW9uLgorICAqIFRoZSB0eXBlIG5hbWUgcmVzb2x2ZXIgd2lsbCBubyBsb25nZXIgcmVzb2x2ZSB0eXBlIG5hbWVzIHRvIGZpZWxkcy4gIEZvcgorICAgIGV4YW1wbGUsIHRoaXMgbm93IHdvcmtzOgorICAgICAgbWVzc2FnZSBGb28ge30KKyAgICAgIG1lc3NhZ2UgQmFyIHsKKyAgICAgICAgb3B0aW9uYWwgaW50MzIgRm9vID0gMTsKKyAgICAgICAgb3B0aW9uYWwgRm9vIGJheiA9IDI7CisgICAgICB9CisgICAgUHJldmlvdXNseSwgdGhlIHR5cGUgb2YgImJheiIgd291bGQgcmVzb2x2ZSB0byAiQmFyLkZvbyIsIGFuZCB5b3UnZCBnZXQKKyAgICBhbiBlcnJvciBiZWNhdXNlIEJhci5Gb28gaXMgYSBmaWVsZCwgbm90IGEgdHlwZS4gIE5vdyB0aGUgdHlwZSBvZiAiYmF6IgorICAgIHJlc29sdmVzIHRvIHRoZSBtZXNzYWdlIHR5cGUgRm9vLiAgVGhpcyBjaGFuZ2UgaXMgdW5saWtlbHkgdG8gbWFrZSBhCisgICAgZGlmZmVyZW5jZSB0byBhbnlvbmUgd2hvIGZvbGxvd3MgdGhlIFByb3RvY29sIEJ1ZmZlcnMgc3R5bGUgZ3VpZGUuCisKKyAgQysrCisgICogU2V2ZXJhbCBvcHRpbWl6YXRpb25zLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvOgorICAgIC0gU2VyaWFsaXphdGlvbiwgZXNwZWNpYWxseSB0byBmbGF0IGFycmF5cywgaXMgMTAlLTUwJSBmYXN0ZXIsIHBvc3NpYmx5CisgICAgICBtb3JlIGZvciBzbWFsbCBvYmplY3RzLgorICAgIC0gU2V2ZXJhbCBkZXNjcmlwdG9yIG9wZXJhdGlvbnMgd2hpY2ggcHJldmlvdXNseSByZXF1aXJlZCBsb2NraW5nIG5vIGxvbmdlcgorICAgICAgZG8uCisgICAgLSBEZXNjcmlwdG9ycyBhcmUgbm93IGNvbnN0cnVjdGVkIGxhemlseSBvbiBmaXJzdCB1c2UsIHJhdGhlciB0aGFuIGF0CisgICAgICBwcm9jZXNzIHN0YXJ0dXAgdGltZS4gIFRoaXMgc2hvdWxkIHNhdmUgbWVtb3J5IGluIHByb2dyYW1zIHdoaWNoIGRvIG5vdAorICAgICAgdXNlIGRlc2NyaXB0b3JzIG9yIHJlZmxlY3Rpb24uCisgICAgLSBVbmtub3duRmllbGRTZXQgY29tcGxldGVseSByZWRlc2lnbmVkIHRvIGJlIG1vcmUgZWZmaWNpZW50IChlc3BlY2lhbGx5IGluCisgICAgICB0ZXJtcyBvZiBtZW1vcnkgdXNhZ2UpLgorICAgIC0gVmFyaW91cyBvcHRpbWl6YXRpb25zIHRvIHJlZHVjZSBjb2RlIHNpemUgKHRob3VnaCB0aGUgc2VyaWFsaXphdGlvbiBzcGVlZAorICAgICAgb3B0aW1pemF0aW9ucyBpbmNyZWFzZWQgY29kZSBzaXplKS4KKyAgKiBNZXNzYWdlIGludGVyZmFjZSBoYXMgbWV0aG9kIFBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgpIHdoaWNoIHBhcnNlcworICAgIGEgbGltaXRlZCBudW1iZXIgb2YgYnl0ZXMgZnJvbSBhbiBpbnB1dCBzdHJlYW0gcmF0aGVyIHRoYW4gcGFyc2luZyB1bnRpbAorICAgIEVPRi4KKyAgKiBHemlwSW5wdXRTdHJlYW0gYW5kIEd6aXBPdXRwdXRTdHJlYW0gc3VwcG9ydCByZWFkaW5nL3dyaXRpbmcgZ3ppcC0gb3IKKyAgICB6bGliLWNvbXByZXNzZWQgc3RyZWFtcyBpZiB6bGliIGlzIGF2YWlsYWJsZS4KKyAgICAoZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtLmgpCisgICogRGVzY3JpcHRvclBvb2w6OkZpbmRBbGxFeHRlbnNpb25zKCkgYW5kIGNvcnJlc3BvbmRpbmcKKyAgICBEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRBbGxFeHRlbnNpb25zKCkgY2FuIGJlIHVzZWQgdG8gZW51bWVyYXRlIGFsbAorICAgIGV4dGVuc2lvbnMgb2YgYSBnaXZlbiB0eXBlLgorICAqIEZvciBlYWNoIGVudW0gdHlwZSBGb28sIHByb3RvYyB3aWxsIGdlbmVyYXRlIGZ1bmN0aW9uczoKKyAgICAgIGNvbnN0IHN0cmluZyYgRm9vX05hbWUoRm9vIHZhbHVlKTsKKyAgICAgIGJvb2wgRm9vX1BhcnNlKGNvbnN0IHN0cmluZyYgbmFtZSwgRm9vKiByZXN1bHQpOworICAgIFRoZSBmb3JtZXIgcmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZW51bSBjb25zdGFudCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbgorICAgIHZhbHVlIHdoaWxlIHRoZSBsYXR0ZXIgZmluZHMgdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gYSBuYW1lLgorICAqIFJlcGVhdGVkRmllbGQgYW5kIFJlcGVhdGVkUHRyRmllbGQgbm93IGhhdmUgYmFjay1pbnNlcnRpb24gaXRlcmF0b3JzLgorICAqIFN0cmluZyBmaWVsZHMgbm93IGhhdmUgc2V0dGVycyB0aGF0IHRha2UgYSBjaGFyKiBhbmQgYSBzaXplLCBpbiBhZGRpdGlvbgorICAgIHRvIHRoZSBleGlzdGluZyBvbmVzIHRoYXQgdG9vayBjaGFyKiBvciBjb25zdCBzdHJpbmcmLgorICAqIERlc2NyaXB0b3JQb29sOjpBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBtYXkgYmUgdXNlZCB0byB0ZWxsCisgICAgRGVzY3JpcHRvclBvb2wgdG8gY3JlYXRlIHBsYWNlaG9sZGVyIGRlc2NyaXB0b3JzIGZvciB1bmtub3duIGVudGl0aWVzCisgICAgcmVmZXJlbmNlZCBpbiBhIEZpbGVEZXNjcmlwdG9yUHJvdG8uICBUaGlzIGNhbiBhbGxvdyB5b3UgdG8gcGFyc2UgYSAucHJvdG8KKyAgICBmaWxlIHdpdGhvdXQgaGF2aW5nIGFjY2VzcyB0byBvdGhlciAucHJvdG8gZmlsZXMgdGhhdCBpdCBpbXBvcnRzLCBmb3IKKyAgICBleGFtcGxlLgorICAqIFVwZGF0ZWQgZ3Rlc3QgdG8gbGF0ZXN0IHZlcnNpb24uICBUaGUgZ3Rlc3QgcGFja2FnZSBpcyBub3cgaW5jbHVkZWQgYXMgYQorICAgIG5lc3RlZCBhdXRvY29uZiBwYWNrYWdlLCBzbyBpdCBzaG91bGQgYmUgYWJsZSB0byBkcm9wIG5ldyB2ZXJzaW9ucyBpbnRvIHRoZQorICAgICJndGVzdCIgc3ViZGlyZWN0b3J5IHdpdGhvdXQgbW9kaWZpY2F0aW9uLgorCisgIEphdmEKKyAgKiBGaXhlZCBidWcgd2hlcmUgTWVzc2FnZS5tZXJnZUZyb20oTWVzc2FnZSkgZmFpbGVkIHRvIG1lcmdlIGV4dGVuc2lvbnMuCisgICogTWVzc2FnZSBpbnRlcmZhY2UgaGFzIG5ldyBtZXRob2QgdG9CdWlsZGVyKCkgd2hpY2ggaXMgZXF1aXZhbGVudCB0bworICAgIG5ld0J1aWxkZXJGb3JUeXBlKCkubWVyZ2VGcm9tKHRoaXMpLgorICAqIEFsbCBlbnVtcyBub3cgaW1wbGVtZW50IHRoZSBQcm90b2NvbE1lc3NhZ2VFbnVtIGludGVyZmFjZS4KKyAgKiBTZXR0aW5nIGEgZmllbGQgdG8gbnVsbCBub3cgdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uLgorICAqIEZpeGVkIHRlbmRlbmN5IGZvciBUZXh0Rm9ybWF0J3MgcGFyc2luZyB0byBvdmVyZmxvdyB0aGUgc3RhY2sgd2hlbgorICAgIHBhcnNpbmcgbGFyZ2Ugc3RyaW5nIHZhbHVlcy4gIFRoZSB1bmRlcmx5aW5nIHByb2JsZW0gaXMgd2l0aCBKYXZhJ3MKKyAgICByZWdleCBpbXBsZW1lbnRhdGlvbiAod2hpY2ggdW5mb3J0dW5hdGVseSB1c2VzIHJlY3Vyc2l2ZSBiYWNrdHJhY2tpbmcKKyAgICByYXRoZXIgdGhhbiBidWlsZGluZyBhbiBORkEpLiAgV29ya2VkIGFyb3VuZCBieSBtYWtpbmcgdXNlIG9mIHBvc3Nlc2l2ZQorICAgIHF1YW50aWZpZXJzLgorICAqIEdlbmVyYXRlZCBzZXJ2aWNlIGNsYXNzZXMgbm93IGFsc28gZ2VuZXJhdGUgcHVyZSBpbnRlcmZhY2VzLiAgRm9yIGEgc2VydmljZQorICAgIEZvbywgRm9vLkludGVyZmFjZSBpcyBhIHB1cmUgaW50ZXJmYWNlIGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBzZXJ2aWNlJ3MKKyAgICBkZWZpbmVkIG1ldGhvZHMuICBGb28ubmV3UmVmbGVjdGl2ZVNlcnZpY2UoKSBjYW4gYmUgY2FsbGVkIHRvIHdyYXAgYW4KKyAgICBpbnN0YW5jZSBvZiB0aGlzIGludGVyZmFjZSBpbiBhIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgZ2VuZXJpYworICAgIFJwY1NlcnZpY2UgaW50ZXJmYWNlLCB3aGljaCBwcm92aWRlcyByZWZsZWN0aW9uIHN1cHBvcnQgdGhhdCBpcyB1c3VhbGx5CisgICAgbmVlZGVkIGJ5IFJQQyBzZXJ2ZXIgaW1wbGVtZW50YXRpb25zLgorICAqIFJQQyBpbnRlcmZhY2VzIG5vdyBzdXBwb3J0IGJsb2NraW5nIG9wZXJhdGlvbiBpbiBhZGRpdGlvbiB0byBub24tYmxvY2tpbmcuCisgICAgVGhlIHByb3RvY29sIGNvbXBpbGVyIGdlbmVyYXRlcyBzZXBhcmF0ZSBibG9ja2luZyBhbmQgbm9uLWJsb2NraW5nIHN0dWJzCisgICAgd2hpY2ggb3BlcmF0ZSBhZ2FpbnN0IHNlcGFyYXRlIGJsb2NraW5nIGFuZCBub24tYmxvY2tpbmcgUlBDIGludGVyZmFjZXMuCisgICAgUlBDIGltcGxlbWVudGF0aW9ucyB3aWxsIGhhdmUgdG8gaW1wbGVtZW50IHRoZSBuZXcgaW50ZXJmYWNlcyBpbiBvcmRlciB0bworICAgIHN1cHBvcnQgYmxvY2tpbmcgbW9kZS4KKyAgKiBOZXcgSS9PIG1ldGhvZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKCksIG1lcmdlRGVsaW1pdGVkRnJvbSgpLCBhbmQKKyAgICB3cml0ZURlbGltaXRlZFRvKCkgcmVhZCBhbmQgd3JpdGUgImRlbGVtaXRlZCIgbWVzc2FnZXMgZnJvbS90byBhIHN0cmVhbSwKKyAgICBtZWFuaW5nIHRoYXQgdGhlIG1lc3NhZ2Ugc2l6ZSBwcmVjZWRlcyB0aGUgZGF0YS4gIFRoaXMgd2F5LCB5b3UgY2FuIHdyaXRlCisgICAgbXVsdGlwbGUgbWVzc2FnZXMgdG8gYSBzdHJlYW0gd2l0aG91dCBoYXZpbmcgdG8gd29ycnkgYWJvdXQgZGVsaW1pdGluZworICAgIHRoZW0geW91cnNlbGYuCisgICogVGhyb3cgYSBtb3JlIGRlc2NyaXB0aXZlIGV4Y2VwdGlvbiB3aGVuIGJ1aWxkKCkgaXMgZG91YmxlLWNhbGxlZC4KKyAgKiBBZGQgYSBtZXRob2QgdG8gcXVlcnkgd2hldGhlciBDb2RlZElucHV0U3RyZWFtIGlzIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0CisgICAgc3RyZWFtLgorICAqIEFkZCBhIG1ldGhvZCB0byByZXNldCBhIENvZGVkSW5wdXRTdHJlYW0ncyBzaXplIGNvdW50ZXI7IHVzZWZ1bCB3aGVuCisgICAgcmVhZGluZyBtYW55IG1lc3NhZ2VzIHdpdGggdGhlIHNhbWUgc3RyZWFtLgorICAqIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpIG5vdyBhY2NvdW50IGZvciB1bmtub3duIGZpZWxkcy4KKworICBQeXRob24KKyAgKiBBZGRlZCBzbGljaW5nIHN1cHBvcnQgZm9yIHJlcGVhdGVkIHNjYWxhciBmaWVsZHMuIEFkZGVkIHNsaWNlIHJldHJpZXZhbCBhbmQKKyAgICByZW1vdmFsIG9mIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZHMuCisgICogVXBkYXRlZCBSUEMgaW50ZXJmYWNlcyB0byBhbGxvdyBmb3IgYmxvY2tpbmcgb3BlcmF0aW9uLiAgQSBjbGllbnQgbWF5CisgICAgbm93IHBhc3MgTm9uZSBmb3IgYSBjYWxsYmFjayB3aGVuIG1ha2luZyBhbiBSUEMsIGluIHdoaWNoIGNhc2UgdGhlCisgICAgY2FsbCB3aWxsIGJsb2NrIHVudGlsIHRoZSByZXNwb25zZSBpcyByZWNlaXZlZCwgYW5kIHRoZSByZXNwb25zZQorICAgIG9iamVjdCB3aWxsIGJlIHJldHVybmVkIGRpcmVjdGx5IHRvIHRoZSBjYWxsZXIuICBUaGlzIGludGVyZmFjZSBjaGFuZ2UKKyAgICBjYW5ub3QgYmUgdXNlZCBpbiBwcmFjdGljZSB1bnRpbCBSUEMgaW1wbGVtZW50YXRpb25zIGFyZSB1cGRhdGVkIHRvCisgICAgaW1wbGVtZW50IGl0LgorICAqIENoYW5nZXMgdG8gaW5wdXRfc3RyZWFtLnB5IHNob3VsZCBtYWtlIHByb3RvYnVmIGNvbXBhdGlibGUgd2l0aCBhcHBlbmdpbmUuCisKKzIwMDgtMTEtMjUgdmVyc2lvbiAyLjAuMzoKKworICBwcm90b2MKKyAgKiBFbnVtIHZhbHVlcyBtYXkgbm93IGhhdmUgY3VzdG9tIG9wdGlvbnMsIHVzaW5nIHN5bnRheCBzaW1pbGFyIHRvIGZpZWxkCisgICAgb3B0aW9ucy4KKyAgKiBGaXhlZCBidWcgd2hlcmUgLnByb3RvIGZpbGVzIHdoaWNoIHVzZSBjdXN0b20gb3B0aW9ucyBidXQgZG9uJ3QgYWN0dWFsbHkKKyAgICBkZWZpbmUgdGhlbSAoaS5lLiB0aGV5IGltcG9ydCBhbm90aGVyIC5wcm90byBmaWxlIGRlZmluaW5nIHRoZSBvcHRpb25zKQorICAgIGhhZCB0byBleHBsaWNpdGx5IGltcG9ydCBkZXNjcmlwdG9yLnByb3RvLgorICAqIEFkamFjZW50IHN0cmluZyBsaXRlcmFscyBpbiAucHJvdG8gZmlsZXMgd2lsbCBub3cgYmUgY29uY2F0ZW5hdGVkLCBsaWtlIGluCisgICAgQy4KKyAgKiBJZiBhbiBpbnB1dCBmaWxlIGlzIGEgV2luZG93cyBhYnNvbHV0ZSBwYXRoIChlLmcuICJDOlxmb29cYmFyLnByb3RvIikgYW5kCisgICAgdGhlIGltcG9ydCBwYXRoIG9ubHkgY29udGFpbnMgIi4iIChvciBjb250YWlucyAiLiIgYnV0IGRvZXMgbm90IGNvbnRhaW4KKyAgICB0aGUgZmlsZSksIHByb3RvYyBpbmNvcnJlY3RseSB0aG91Z2h0IHRoYXQgdGhlIGZpbGUgd2FzIHVuZGVyICIuIiwgYmVjYXVzZQorICAgIGl0IHRob3VnaHQgdGhhdCB0aGUgcGF0aCB3YXMgcmVsYXRpdmUgKHNpbmNlIGl0IGRpZG4ndCBzdGFydCB3aXRoIGEgc2xhc2gpLgorICAgIFRoaXMgaGFzIGJlZW4gZml4ZWQuCisKKyAgQysrCisgICogR2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3NlcyBub3cgaGF2ZSBhIFN3YXAoKSBtZXRob2Qgd2hpY2ggZWZmaWNpZW50bHkgc3dhcHMKKyAgICB0aGUgY29udGVudHMgb2YgdHdvIG9iamVjdHMuCisgICogQWxsIG1lc3NhZ2UgY2xhc3NlcyBub3cgaGF2ZSBhIFNwYWNlVXNlZCgpIG1ldGhvZCB3aGljaCByZXR1cm5zIGFuIGVzdGltYXRlCisgICAgb2YgdGhlIG51bWJlciBvZiBieXRlcyBvZiBhbGxvY2F0ZWQgbWVtb3J5IGN1cnJlbnRseSBvd25lZCBieSB0aGUgb2JqZWN0LgorICAgIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCB3aGVuIHlvdSBhcmUgcmV1c2luZyBhIHNpbmdsZSBtZXNzYWdlIG9iamVjdAorICAgIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UgYnV0IHdhbnQgdG8gbWFrZSBzdXJlIGl0IGRvZXNuJ3QgYmxvYXQgdXAgdG9vIGxhcmdlLgorICAqIE5ldyBtZXRob2QgTWVzc2FnZTo6U2VyaWFsaXplQXNTdHJpbmcoKSByZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlCisgICAgc2VyaWFsaXplZCBkYXRhLiAgTWF5IGJlIG1vcmUgY29udmVuaWVudCB0aGFuIGNhbGxpbmcKKyAgICBTZXJpYWxpemVUb1N0cmluZyhzdHJpbmcqKS4KKyAgKiBJbiBkZWJ1ZyBtb2RlLCBsb2cgZXJyb3IgbWVzc2FnZXMgd2hlbiBzdHJpbmctdHlwZSBmaWVsZHMgYXJlIGZvdW5kIHRvCisgICAgY29udGFpbiBieXRlcyB0aGF0IGFyZSBub3QgdmFsaWQgVVRGLTguCisgICogRml4ZWQgYnVnIHdoZXJlIGEgbWVzc2FnZSB3aXRoIG11bHRpcGxlIGV4dGVuc2lvbiByYW5nZXMgY291bGRuJ3QgcGFyc2UKKyAgICBleHRlbnNpb25zLgorICAqIEZpeGVkIGJ1ZyB3aGVyZSBNZXJnZUZyb20oY29uc3QgTWVzc2FnZSYpIGRpZG4ndCBkbyBhbnl0aGluZyBpZiBpbnZva2VkIG9uCisgICAgYSBtZXNzYWdlIHRoYXQgY29udGFpbmVkIG5vIGZpZWxkcyAoYnV0IHBvc3NpYmx5IGNvbnRhaW5lZCBleHRlbnNpb25zKS4KKyAgKiBGaXhlZCBTaG9ydERlYnVnU3RyaW5nKCkgdG8gbm90IGJlIE8obl4yKS4gIER1cnIuCisgICogRml4ZWQgY3Jhc2ggaW4gVGV4dEZvcm1hdCBwYXJzaW5nIGlmIHRoZSBmaXJzdCB0b2tlbiBpbiB0aGUgaW5wdXQgY2F1c2VkIGEKKyAgICB0b2tlbml6YXRpb24gZXJyb3IuCisgICogRml4ZWQgb2JzY3VyZSBidWdzIGluIHplcm9fY29weV9zdHJlYW1faW1wbC5jYy4KKyAgKiBBZGRlZCBzdXBwb3J0IGZvciBIUCBDKysgb24gVHJ1NjQuCisgICogT25seSBidWlsZCB0ZXN0cyBvbiAibWFrZSBjaGVjayIsIG5vdCAibWFrZSIuCisgICogRml4ZWQgYWxpZ25tZW50IGlzc3VlIHRoYXQgY2F1c2VkIGNyYXNoZXMgd2hlbiB1c2luZyBEeW5hbWljTWVzc2FnZSBvbgorICAgIDY0LWJpdCBTcGFyYyBtYWNoaW5lcy4KKyAgKiBTaW1wbGlmeSB0ZW1wbGF0ZSB1c2FnZSB0byB3b3JrIHdpdGggTVNWQyAyMDAzLgorICAqIFdvcmsgYXJvdW5kIEdDQyA0LjMueCB4ODZfNjQgY29tcGlsZXIgYnVnIHRoYXQgY2F1c2VkIGNyYXNoZXMgb24gc3RhcnR1cC4KKyAgICAoVGhpcyBhZmZlY3RlZCBGZWRvcmEgOSBpbiBwYXJ0aWN1bGFyLikKKyAgKiBOb3cgd29ya3Mgb24gIlNvbGFyaXMgMTAgdXNpbmcgcmVjZW50IFN1biBTdHVkaW8iLgorCisgIEphdmEKKyAgKiBOZXcgb3ZlcmxvYWQgb2YgbWVyZ2VGcm9tKCkgd2hpY2ggcGFyc2VzIGEgc2xpY2Ugb2YgYSBieXRlIGFycmF5IGluc3RlYWQKKyAgICBvZiB0aGUgd2hvbGUgdGhpbmcuCisgICogTmV3IG1ldGhvZCBCeXRlU3RyaW5nLmFzUmVhZE9ubHlCeXRlQnVmZmVyKCkgZG9lcyB3aGF0IGl0IHNvdW5kcyBsaWtlLgorICAqIEltcHJvdmVkIHBlcmZvcm1hbmNlIG9mIGlzSW5pdGlhbGl6ZWQoKSB3aGVuIG9wdGltaXppbmcgZm9yIGNvZGUgc2l6ZS4KKworICBQeXRob24KKyAgKiBDb3JyZWN0ZWQgTGlzdEZpZWxkcygpIHNpZ25hdHVyZSBpbiBNZXNzYWdlIGJhc2UgY2xhc3MgdG8gbWF0Y2ggd2hhdAorICAgIHN1YmNsYXNzZXMgYWN0dWFsbHkgaW1wbGVtZW50LgorICAqIFNvbWUgbWlub3IgcmVmYWN0b3JpbmcuCisgICogRG9uJ3QgcGFzcyBzZWxmIGFzIGZpcnN0IGFyZ3VtZW50IHRvIHN1cGVyY2xhc3MgY29uc3RydWN0b3IgKG5vIGxvbmdlcgorICAgIGFsbG93ZWQgaW4gUHl0aG9uIDIuNikuCisKKzIwMDgtMDktMjkgdmVyc2lvbiAyLjAuMjoKKworICBHZW5lcmFsCisgICogTGljZW5zZSBjaGFuZ2VkIGZyb20gQXBhY2hlIDIuMCB0byBOZXcgQlNELgorICAqIEl0IGlzIG5vdyBwb3NzaWJsZSB0byBkZWZpbmUgY3VzdG9tICJvcHRpb25zIiwgd2hpY2ggYXJlIGJhc2ljYWxseQorICAgIGFubm90YXRpb25zIHdoaWNoIG1heSBiZSBwbGFjZWQgb24gZGVmaW5pdGlvbnMgaW4gYSAucHJvdG8gZmlsZS4KKyAgICBGb3IgZXhhbXBsZSwgeW91IG1pZ2h0IGRlZmluZSBhIGZpZWxkIG9wdGlvbiBjYWxsZWQgImZvbyIgbGlrZSBzbzoKKyAgICAgIGltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iCisgICAgICBleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyB7CisgICAgICAgIG9wdGlvbmFsIHN0cmluZyBmb28gPSAxMjM0NTsKKyAgICAgIH0KKyAgICBUaGVuIHlvdSBhbm5vdGF0ZSBhIGZpZWxkIHVzaW5nIHRoZSAiZm9vIiBvcHRpb246CisgICAgICBtZXNzYWdlIE15TWVzc2FnZSB7CisgICAgICAgIG9wdGlvbmFsIGludDMyIHNvbWVfZmllbGQgPSAxIFsoZm9vKSA9ICJiYXIiXQorICAgICAgfQorICAgIFRoZSB2YWx1ZSBvZiB0aGlzIG9wdGlvbiBpcyB0aGVuIHZpc2libGUgdmlhIHRoZSBtZXNzYWdlJ3MKKyAgICBEZXNjcmlwdG9yOgorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9CisgICAgICAgIE15TWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInNvbWVfZmllbGQiKTsKKyAgICAgIGFzc2VydChmaWVsZC0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihmb28pID09ICJiYXIiKTsKKyAgICBUaGlzIGZlYXR1cmUgaGFzIGJlZW4gaW1wbGVtZW50ZWQgYW5kIHRlc3RlZCBpbiBDKysgYW5kIEphdmEuCisgICAgT3RoZXIgbGFuZ3VhZ2VzIG1heSBvciBtYXkgbm90IG5lZWQgdG8gZG8gZXh0cmEgd29yayB0byBzdXBwb3J0CisgICAgY3VzdG9tIG9wdGlvbnMsIGRlcGVuZGluZyBvbiBob3cgdGhleSBjb25zdHJ1Y3QgZGVzY3JpcHRvcnMuCisKKyAgQysrCisgICogRml4ZWQgc29tZSBHQ0Mgd2FybmluZ3MgdGhhdCBvbmx5IG9jY3VyIHdoZW4gdXNpbmcgLXBlZGFudGljLgorICAqIEltcHJvdmVkIHN0YXRpYyBpbml0aWFsaXphdGlvbiBjb2RlLCBtYWtpbmcgb3JkZXJpbmcgbW9yZQorICAgIHByZWRpY3RhYmxlIGFtb25nIG90aGVyIHRoaW5ncy4KKyAgKiBUZXh0Rm9ybWF0IHdpbGwgbm8gbG9uZ2VyIGFjY2VwdCBtZXNzYWdlcyB3aGljaCBjb250YWluIG11bHRpcGxlCisgICAgaW5zdGFuY2VzIG9mIGEgc2luZ3VsYXIgZmllbGQuICBQcmV2aW91c2x5LCB0aGUgbGF0dGVyIGluc3RhbmNlCisgICAgd291bGQgb3ZlcndyaXRlIHRoZSBmb3JtZXIuCisgICogTm93IHdvcmtzIG9uIHN5c3RlbXMgdGhhdCBkb24ndCBoYXZlIGhhc2hfbWFwLgorCisgIEphdmEKKyAgKiBQcmludCBAT3ZlcnJpZGUgYW5ub3RhdGlvbiBpbiBnZW5lcmF0ZWQgY29kZSB3aGVyZSBhcHByb3ByaWF0ZS4KKworICBQeXRob24KKyAgKiBTdHJpbmdzIG5vdyB1c2UgdGhlICJ1bmljb2RlIiB0eXBlIHJhdGhlciB0aGFuIHRoZSAic3RyIiB0eXBlLgorICAgIFN0cmluZyBmaWVsZHMgbWF5IHN0aWxsIGJlIGFzc2lnbmVkIEFTQ0lJICJzdHIiIHZhbHVlczsgdGhleSB3aWxsCisgICAgYXV0b21hdGljYWxseSBiZSBjb252ZXJ0ZWQuCisgICogQWRkaW5nIGEgcHJvcGVydHkgdG8gYW4gb2JqZWN0IHJlcHJlc2VudGluZyBhIHJlcGVhdGVkIGZpZWxkIG5vdworICAgIHJhaXNlcyBhbiBleGNlcHRpb24uICBGb3IgZXhhbXBsZToKKyAgICAgICMgTm8gbG9uZ2VyIHdvcmtzIChhbmQgbmV2ZXIgc2hvdWxkIGhhdmUpLgorICAgICAgbWVzc2FnZS5zb21lX3JlcGVhdGVkX2ZpZWxkLmZvbyA9IDEKKworICBXaW5kb3dzCisgICogV2Ugbm93IGJ1aWxkIHN0YXRpYyBsaWJyYXJpZXMgcmF0aGVyIHRoYW4gRExMcyBieSBkZWZhdWx0IG9uIE1TVkMuCisgICAgU2VlIHZzcHJvamVjdHMvcmVhZG1lLnR4dCBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKworMjAwOC0wOC0xNSB2ZXJzaW9uIDIuMC4xOgorCisgIHByb3RvYworICAqIE5ldyBmbGFncyAtLWVuY29kZSBhbmQgLS1kZWNvZGUgY2FuIGJlIHVzZWQgdG8gY29udmVydCBiZXR3ZWVuIHByb3RvYnVmIHRleHQKKyAgICBmb3JtYXQgYW5kIGJpbmFyeSBmb3JtYXQgZnJvbSB0aGUgY29tbWFuZC1saW5lLgorICAqIE5ldyBmbGFnIC0tZGVzY3JpcHRvcl9zZXRfb3V0IGNhbiBiZSB1c2VkIHRvIHdyaXRlIEZpbGVEZXNjcmlwdG9yUHJvdG9zIGZvcgorICAgIGFsbCBwYXJzZWQgZmlsZXMgZGlyZWN0bHkgaW50byBhIHNpbmdsZSBvdXRwdXQgZmlsZS4gIFRoaXMgaXMgcGFydGljdWxhcmx5CisgICAgdXNlZnVsIGlmIHlvdSB3aXNoIHRvIHBhcnNlIC5wcm90byBmaWxlcyBmcm9tIHByb2dyYW1zIHdyaXR0ZW4gaW4gbGFuZ3VhZ2VzCisgICAgb3RoZXIgdGhhbiBDKys6IGp1c3QgcnVuIHByb3RvYyBhcyBhIGJhY2tncm91bmQgcHJvY2VzcyBhbmQgaGF2ZSBpdCBvdXRwdXQKKyAgICBhIEZpbGVEZXNjcmlwdG9yTGlzdCwgdGhlbiBwYXJzZSB0aGF0IG5hdGl2ZWx5LgorICAqIEltcHJvdmVkIGVycm9yIG1lc3NhZ2Ugd2hlbiBhbiBlbnVtIHZhbHVlJ3MgbmFtZSBjb25mbGljdHMgd2l0aCBhbm90aGVyCisgICAgc3ltYm9sIGRlZmluZWQgaW4gdGhlIGVudW0gdHlwZSdzIHNjb3BlLCBlLmcuIGlmIHR3byBlbnVtIHR5cGVzIGRlY2xhcmVkCisgICAgaW4gdGhlIHNhbWUgc2NvcGUgaGF2ZSB2YWx1ZXMgd2l0aCB0aGUgc2FtZSBuYW1lLiAgVGhpcyBpcyBkaXNhbGxvd2VkIGZvcgorICAgIGNvbXBhdGliaWxpdHkgd2l0aCBDKyssIGJ1dCB0aGlzIHdhc24ndCBjbGVhciBmcm9tIHRoZSBlcnJvci4KKyAgKiBGaXhlZCBhYnNvbHV0ZSBvdXRwdXQgcGF0aHMgb24gV2luZG93cy4KKyAgKiBBbGxvdyB0cmFpbGluZyBzbGFzaGVzIGluIC0tcHJvdG9fcGF0aCBtYXBwaW5ncy4KKworICBDKysKKyAgKiBSZWZsZWN0aW9uIG9iamVjdHMgYXJlIG5vdyBwZXItY2xhc3MgcmF0aGVyIHRoYW4gcGVyLWluc3RhbmNlLiAgVG8gbWFrZSB0aGlzCisgICAgcG9zc2libGUsIHRoZSBSZWZsZWN0aW9uIGludGVyZmFjZSBoYWQgdG8gYmUgY2hhbmdlZCBzdWNoIHRoYXQgYWxsIG1ldGhvZHMKKyAgICB0YWtlIHRoZSBNZXNzYWdlIGluc3RhbmNlIGFzIGEgcGFyYW1ldGVyLiAgVGhpcyBjaGFuZ2UgaW1wcm92ZXMgcGVyZm9ybWFuY2UKKyAgICBzaWduaWZpY2FudGx5IGluIG1lbW9yeS1iYW5kd2lkdGgtbGltaXRlZCB1c2UgY2FzZXMsIHNpbmNlIGl0IG1ha2VzIHRoZQorICAgIG1lc3NhZ2Ugb2JqZWN0cyBzbWFsbGVyLiAgTm90ZSB0aGF0IHNvdXJjZS1pbmNvbXBhdGlibGUgaW50ZXJmYWNlIGNoYW5nZXMKKyAgICBsaWtlIHRoaXMgd2lsbCBub3QgYmUgbWFkZSBhZ2FpbiBhZnRlciB0aGUgbGlicmFyeSBsZWF2ZXMgYmV0YS4KKyAgKiBIZXVyaXN0aWNhbGx5IGRldGVjdCBzdWItbWVzc2FnZXMgd2hlbiBwcmludGluZyB1bmtub3duIGZpZWxkcy4KKyAgKiBGaXggc3RhdGljIGluaXRpYWxpemF0aW9uIG9yZGVyaW5nIGJ1ZyB0aGF0IGNhdXNlZCBjcmFzaGVzIGF0IHN0YXJ0dXAgd2hlbgorICAgIGNvbXBpbGluZyBvbiBNYWMgd2l0aCBzdGF0aWMgbGlua2luZy4KKyAgKiBGaXhlZCBUb2tlbml6ZXJUZXN0IHdoZW4gY29tcGlsaW5nIHdpdGggLUROREVCVUcgb24gTGludXguCisgICogRml4ZWQgaW5jb3JyZWN0IGRlZmluaXRpb24gb2Yga2ludDMybWluLgorICAqIEZpeCBieXRlcyB0eXBlIHNldHRlciB0byB3b3JrIHdpdGggYnl0ZSBzZXF1ZW5jZXMgd2l0aCBlbWJlZGRlZCBOVUxMcy4KKyAgKiBPdGhlciBpcnJlbGV2YW50IHR3ZWFrcy4KKworICBKYXZhCisgICogRml4ZWQgVW5rbm93bkZpZWxkU2V0J3MgcGFyc2luZyBvZiB2YXJpbnRzIGxhcmdlciB0aGFuIDMyIGJpdHMuCisgICogRml4ZWQgVGV4dEZvcm1hdCdzIHBhcnNpbmcgb2YgImluZiIgYW5kICJuYW4iLgorICAqIEZpeGVkIFRleHRGb3JtYXQncyBwYXJzaW5nIG9mIGNvbW1lbnRzLgorICAqIEFkZGVkIGluZm8gdG8gSmF2YSBQT00gdGhhdCB3aWxsIGJlIHJlcXVpcmVkIHdoZW4gd2UgdXBsb2FkIHRoZQorICAgIHBhY2thZ2UgdG8gYSBNYXZlbiByZXBvLgorCisgIFB5dGhvbgorICAqIE1lcmdlRnJvbShtZXNzYWdlKSBhbmQgQ29weUZyb20obWVzc2FnZSkgYXJlIG5vdyBpbXBsZW1lbnRlZC4KKyAgKiBTZXJpYWxpemVUb1N0cmluZygpIHJhaXNlcyBhbiBleGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZAorICAgIGZpZWxkcy4KKyAgKiBDb2RlIG9yZ2FuaXphdGlvbiBpbXByb3ZlbWVudHMuCisgICogRml4ZWQgZG9jIGNvbW1lbnRzIGZvciBScGNDb250cm9sbGVyIGFuZCBScGNDaGFubmVsLCB3aGljaCBoYWQgc29tZWhvdyBiZWVuCisgICAgc3dhcHBlZC4KKyAgKiBGaXhlZCB0ZXh0X2Zvcm1hdF90ZXN0IG9uIFdpbmRvd3Mgd2hlcmUgZmxvYXRpbmctcG9pbnQgZXhwb25lbnRzIHNvbWV0aW1lcworICAgIGNvbnRhaW4gZXh0cmEgemVyb3MuCisgICogRml4IFB5dGhvbiBzZXJ2aWNlIENhbGxNZXRob2QoKSBpbXBsZW1lbnRhdGlvbi4KKworICBPdGhlcgorICAqIEltcHJvdmVkIHJlYWRtZXMuCisgICogVklNIHN5bnRheCBoaWdobGlnaHRpbmcgaW1wcm92ZW1lbnRzLgorCisyMDA4LTA3LTA3IHZlcnNpb24gMi4wLjA6CisKKyAgKiBGaXJzdCBwdWJsaWMgcmVsZWFzZS4KZGlmZiAtLWdpdCBhL0NPTlRSSUJVVE9SUy50eHQgYi9DT05UUklCVVRPUlMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4ZDk3ZmMKLS0tIC9kZXYvbnVsbAorKysgYi9DT05UUklCVVRPUlMudHh0CkBAIC0wLDAgKzEsMTAyIEBACitUaGlzIGZpbGUgY29udGFpbnMgYSBsaXN0IG9mIHBlb3BsZSB3aG8gaGF2ZSBtYWRlIGxhcmdlIGNvbnRyaWJ1dGlvbnMKK3RvIHRoZSBwdWJsaWMgdmVyc2lvbiBvZiBQcm90b2NvbCBCdWZmZXJzLgorCitPcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBhbmQgaW1wbGVtZW50YXRpb246CisgIFNhbmpheSBHaGVtYXdhdCA8c2FuamF5QGdvb2dsZS5jb20+CisgIEplZmYgRGVhbiA8amVmZkBnb29nbGUuY29tPgorICBEYW5pZWwgRHVsaXR6IDxkYW5pZWxAZ29vZ2xlLmNvbT4KKyAgQ3JhaWcgU2lsdmVyc3RlaW4KKyAgUGF1bCBIYWFociA8aGFhaHJAZ29vZ2xlLmNvbT4KKyAgQ29yZXkgQW5kZXJzb24gPGNvcmluQGdvb2dsZS5jb20+CisgIChhbmQgbWFueSBvdGhlcnMpCisKK1Byb3RvMiBDKysgYW5kIEphdmEgcHJpbWFyeSBhdXRob3I6CisgIEtlbnRvbiBWYXJkYSA8a2VudG9uQGdvb2dsZS5jb20+CisKK1Byb3RvMiBQeXRob24gcHJpbWFyeSBhdXRob3JzOgorICBXaWxsIFJvYmluc29uIDxyb2JpbnNvbkBnb29nbGUuY29tPgorICBQZXRhciBQZXRyb3YgPHBldGFyQGdvb2dsZS5jb20+CisKK0phdmEgTmFubyBwcmltYXJ5IGF1dGhvcnM6CisgIEJyaWFuIER1ZmYgPGJkdWZmQGdvb2dsZS5jb20+CisgIFRvbSBDaGFvIDxjaGFvdEBnb29nbGUuY29tPgorICBNYXggQ2FpIDxtYXh0cm95QGdvb2dsZS5jb20+CisgIFVsYXMgS2lyYXpjaSA8dWxhc0Bnb29nbGUuY29tPgorCitMYXJnZSBjb2RlIGNvbnRyaWJ1dGlvbnM6CisgIEphc29uIEhzdWVoIDxqYXNvbmhAZ29vZ2xlLmNvbT4KKyAgSm9zZXBoIFNjaG9yciA8anNjaG9yckBnb29nbGUuY29tPgorICBXZW5ibyBaaHUgPHdlbmJvekBnb29nbGUuY29tPgorCitMYXJnZSBxdWFudGl0eSBvZiBjb2RlIHJldmlld3M6CisgIFNjb3R0IEJydWNlIDxzYnJ1Y2VAZ29vZ2xlLmNvbT4KKyAgRnJhbmsgWWVsbGluCisgIE5lYWwgTm9yd2l0eiA8bm5vcndpdHpAZ29vZ2xlLmNvbT4KKyAgSmVmZnJleSBZYXNza2luIDxqeWFzc2tpbkBnb29nbGUuY29tPgorICBBbWJyb3NlIEZlaW5zdGVpbiA8YW1icm9zZUBnb29nbGUuY29tPgorCitEb2N1bWVudGF0aW9uOgorICBMaXNhIENhcmV5IDxsY2FyZXlAZ29vZ2xlLmNvbT4KKworTWF2ZW4gcGFja2FnaW5nOgorICBHcmVnb3J5IEtpY2sgPGdha0Bnb29nbGUuY29tPgorCitQYXRjaCBjb250cmlidXRvcnM6CisgIEtldmluIEtvIDxrZXZpbi5zLmtvQGdtYWlsLmNvbT4KKyAgICAqIFNtYWxsIHBhdGNoIHRvIGhhbmRsZSB0cmFpbGluZyBzbGFzaGVzIGluIC0tcHJvdG9fcGF0aCBmbGFnLgorICBKb2hhbiBFdXBocm9zaW5lIDxwcm9wcHlAYW1pbmNoZS5jb20+CisgICAgKiBTbWFsbCBwYXRjaCB0byBmaXggUHl0aG9uIENhbGxNZXRob2QoKS4KKyAgVWxyaWNoIEt1bml0eiA8a3VuZUBkZWluZS10YWxlci5kZT4KKyAgICAqIFNtYWxsIG9wdGltaXphdGlvbnMgdG8gUHl0aG9uIHNlcmlhbGl6YXRpb24uCisgIExlYW5kcm8gTHVjYXJlbGxhIDxsbHVjYXhAZ21haWwuY29tPgorICAgICogVkkgc3ludGF4IGhpZ2hsaWdodGluZyB0d2Vha3MuCisgICAgKiBGaXggY29tcGlsZXIgdG8gbm90IG1ha2Ugb3V0cHV0IGV4ZWN1dGFibGUuCisgIERpbGlwIEpvc2VwaCA8ZGlsaXAuYW50b255Lmpvc2VwaEBnbWFpbC5jb20+CisgICAgKiBIZXVyaXN0aWMgZGV0ZWN0aW9uIG9mIHN1Yi1tZXNzYWdlcyB3aGVuIHByaW50aW5nIHVua25vd24gZmllbGRzIGluCisgICAgICB0ZXh0IGZvcm1hdC4KKyAgQnJpYW4gQXRraW5zb24gPG5haXJiNzc0QGdtYWlsLmNvbT4KKyAgICAqIEFkZGVkIEBPdmVycmlkZSBhbm5vdGF0aW9uIHRvIGdlbmVyYXRlZCBKYXZhIGNvZGUgd2hlcmUgYXBwcm9wcmlhdGUuCisgIFZpbmNlbnQgQ2hvaW5pw6hyZSA8Q2hvaW5pZXJlLlZpbmNlbnRAaHlkcm8ucWMuY2E+CisgICAgKiBUcnU2NCBzdXBwb3J0LgorICBNb250eSBUYXlsb3IgPG1vbnR5LnRheWxvckBnbWFpbC5jb20+CisgICAgKiBTb2xhcmlzIDEwICsgU3VuIFN0dWRpbyBmaXhlcy4KKyAgQWxlayBTdG9ybSA8YWxlay5zdG9ybUBnbWFpbC5jb20+CisgICAgKiBTbGljaW5nIHN1cHBvcnQgZm9yIHJlcGVhdGVkIHNjYWxhciBmaWVsZHMgZm9yIHRoZSBQeXRob24gQVBJLgorICBPbGVnIFNtb2xza3kgPG9sZWcuc21vbHNreUBnbWFpbC5jb20+CisgICAgKiBNUyBWaXN1YWwgU3R1ZGlvIGVycm9yIGZvcm1hdCBvcHRpb24uCisgICAgKiBEZXRlY3QgdW5vcmRlcmVkX21hcCBpbiBzdGxfaGFzaC5tNC4KKyAgQnJpYW4gT2xzb24gPGJyaWFub2xzb25AZ29vZ2xlLmNvbT4KKyAgICAqIGd6aXAvemxpYiBJL08gc3VwcG9ydC4KKyAgTWljaGFlbCBQb29sZSA8bWRwb29sZUB0cm9pbHVzLm9yZz4KKyAgICAqIEZpeGVkIHdhcm5pbmdzIGFib3V0IGdlbmVyYXRlZCBjb25zdHJ1Y3RvcnMgbm90IGV4cGxpY2l0bHkgaW5pdGlhbGl6aW5nCisgICAgICBhbGwgZmllbGRzIChvbmx5IHByZXNlbnQgd2l0aCBjZXJ0YWluIGNvbXBpbGVyIHNldHRpbmdzKS4KKyAgICAqIEFkZGVkIGdlbmVyYXRpb24gb2YgZmllbGQgbnVtYmVyIGNvbnN0YW50cy4KKyAgV2luayBTYXZpbGxlIDx3aW5rQGdvb2dsZS5jb20+CisgICAgKiBGaXhlZCBpbml0aWFsaXphdGlvbiBvcmRlcmluZyBwcm9ibGVtIGluIGxvZ2dpbmcgY29kZS4KKyAgV2lsbCBQaWVyY2UgPHdpbGxwQG51Y2xlaS5jb20+CisgICAgKiBTbWFsbCBwYXRjaCBpbXByb3ZpbmcgcGVyZm9ybWFuY2Ugb2YgaW4gUHl0aG9uIHNlcmlhbGl6YXRpb24uCisgIEFsZXhhbmRyZSBWYXNzYWxvdHRpIDxhbGV4YW5kcmVAcGVhZHJvcC5jb20+CisgICAgKiBFbWFjcyBtb2RlIGZvciBQcm90b2NvbCBCdWZmZXJzIChlZGl0b3JzL3Byb3RvYnVmLW1vZGUuZWwpLgorICBTY290dCBTdGFmZm9yZCA8c2NvdHQuc3RhZmZvcmRAZ21haWwuY29tPgorICAgICogQWRkZWQgU3dhcCgpLCBTd2FwRWxlbWVudHMoKSwgYW5kIFJlbW92ZUxhc3QoKSB0byBSZWZsZWN0aW9uIGludGVyZmFjZS4KKyAgQWxleGFuZGVyIE1lbG5pa292IDxhbG1Ac2libWFpbC5ydT4KKyAgICAqIEhQVVggc3VwcG9ydC4KKyAgT2xpdmVyIEpvd2V0dCA8b2xpdmVyLmpvd2V0dEBnbWFpbC5jb20+CisgICAgKiBEZXRlY3Qgd2hldGhlciB6bGliIGlzIG5ldyBlbm91Z2ggaW4gY29uZmlndXJlIHNjcmlwdC4KKyAgICAqIEZpeGVzIGZvciBTb2xhcmlzIDEwIDMyLzY0LWJpdCBjb25mdXNpb24uCisgIEV2YW4gSm9uZXMgPGV2YW5qQG1pdC5lZHU+CisgICAgKiBPcHRpbWl6ZSBKYXZhIHNlcmlhbGl6YXRpb24gY29kZSB3aGVuIHdyaXRpbmcgYSBzbWFsbCBtZXNzYWdlIHRvIGEgc3RyZWFtLgorICAgICogT3B0aW1pemUgSmF2YSBzZXJpYWxpemF0aW9uIG9mIHN0cmluZ3Mgc28gdGhhdCBVVEYtOCBlbmNvZGluZyBoYXBwZW5zIG9ubHkKKyAgICAgIG9uY2UgcGVyIHN0cmluZyBwZXIgc2VyaWFsaXphdGlvbiBjYWxsLgorICAgICogQ2xlYW4gdXAgc29tZSBKYXZhIHdhcm5pbmdzLgorICAgICogRml4IGJ1ZyB3aXRoIHBlcm1hbmVudCBjYWxsYmFja3MgdGhhdCBkZWxldGUgdGhlbXNlbHZlcyB3aGVuIHJ1bi4KKyAgTWljaGFlbCBLdWNoYXJza2kgPG0ua3VjaGFyc2tpQGdtYWlsLmNvbT4KKyAgICAqIEFkZGVkIENvZGVkSW5wdXRTdHJlYW0uZ2V0VG90YWxCeXRlc1JlYWQoKS4KKyAgS2FjcGVyIEtvd2FsaWsgPHhhcnRoaXNpdXMua2tAZ21haWwuY29tPgorICAgICogRml4ZWQgbTQvYWN4X3B0aHJlYWQubTQgcHJvYmxlbSBmb3Igc29tZSBMaW51eCBkaXN0cmlidXRpb25zLgorICBXaWxsaWFtIE9yciA8d2lsbEB3b3JyYmFzZS5jb20+CisgICAgKiBGaXhlZCBkZXRlY3Rpb24gb2Ygc2NoZWRfeWllbGQgb24gU29sYXJpcy4KKyAgICAqIEFkZGVkIGF0b21pY29wcyBmb3IgU29sYXJpcworICBBbmRyZXcgUGFwcm9ja2kgPGFuZHJld0Bpc2hpYm9vLmNvbT4KKyAgICAqIEZpeGVkIG1pbm9yIElCTSB4bEMgY29tcGlsZXIgYnVpbGQgaXNzdWVzCisgICAgKiBBZGRlZCBhdG9taWNvcHMgZm9yIEFJWCAoUE9XRVIpCmRpZmYgLS1naXQgYS9JTlNUQUxMLnR4dCBiL0lOU1RBTEwudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlM2IwOTQKLS0tIC9kZXYvbnVsbAorKysgYi9JTlNUQUxMLnR4dApAQCAtMCwwICsxLDIzNyBAQAorVGhpcyBmaWxlIGNvbnRhaW5zIGRldGFpbGVkIGJ1dCBnZW5lcmljIGluZm9ybWF0aW9uIG9uIGJ1aWxkaW5nIGFuZAoraW5zdGFsbGluZyB0aGUgQysrIHBhcnQgb2YgdGhpcyBwcm9qZWN0LiAgRm9yIHNob3J0ZXIgaW5zdHJ1Y3Rpb25zLAorYXMgd2VsbCBhcyBpbnN0cnVjdGlvbnMgZm9yIGNvbXBpbGluZyBhbmQgaW5zdGFsbGluZyB0aGUgSmF2YSBvcgorUHl0aG9uIHBhcnRzLCBzZWUgUkVBRE1FLgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvcHlyaWdodCAxOTk0LCAxOTk1LCAxOTk2LCAxOTk5LCAyMDAwLCAyMDAxLCAyMDAyIEZyZWUgU29mdHdhcmUKK0ZvdW5kYXRpb24sIEluYy4KKworICAgVGhpcyBmaWxlIGlzIGZyZWUgZG9jdW1lbnRhdGlvbjsgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiBnaXZlcwordW5saW1pdGVkIHBlcm1pc3Npb24gdG8gY29weSwgZGlzdHJpYnV0ZSBhbmQgbW9kaWZ5IGl0LgorCisKK0Jhc2ljIEluc3RhbGxhdGlvbgorPT09PT09PT09PT09PT09PT09CisKKyAgIFRoZXNlIGFyZSBnZW5lcmljIGluc3RhbGxhdGlvbiBpbnN0cnVjdGlvbnMuCisKKyAgIFRoZSBgY29uZmlndXJlJyBzaGVsbCBzY3JpcHQgYXR0ZW1wdHMgdG8gZ3Vlc3MgY29ycmVjdCB2YWx1ZXMgZm9yCit2YXJpb3VzIHN5c3RlbS1kZXBlbmRlbnQgdmFyaWFibGVzIHVzZWQgZHVyaW5nIGNvbXBpbGF0aW9uLiAgSXQgdXNlcwordGhvc2UgdmFsdWVzIHRvIGNyZWF0ZSBhIGBNYWtlZmlsZScgaW4gZWFjaCBkaXJlY3Rvcnkgb2YgdGhlIHBhY2thZ2UuCitJdCBtYXkgYWxzbyBjcmVhdGUgb25lIG9yIG1vcmUgYC5oJyBmaWxlcyBjb250YWluaW5nIHN5c3RlbS1kZXBlbmRlbnQKK2RlZmluaXRpb25zLiAgRmluYWxseSwgaXQgY3JlYXRlcyBhIHNoZWxsIHNjcmlwdCBgY29uZmlnLnN0YXR1cycgdGhhdAoreW91IGNhbiBydW4gaW4gdGhlIGZ1dHVyZSB0byByZWNyZWF0ZSB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uLCBhbmQgYQorZmlsZSBgY29uZmlnLmxvZycgY29udGFpbmluZyBjb21waWxlciBvdXRwdXQgKHVzZWZ1bCBtYWlubHkgZm9yCitkZWJ1Z2dpbmcgYGNvbmZpZ3VyZScpLgorCisgICBJdCBjYW4gYWxzbyB1c2UgYW4gb3B0aW9uYWwgZmlsZSAodHlwaWNhbGx5IGNhbGxlZCBgY29uZmlnLmNhY2hlJworYW5kIGVuYWJsZWQgd2l0aCBgLS1jYWNoZS1maWxlPWNvbmZpZy5jYWNoZScgb3Igc2ltcGx5IGAtQycpIHRoYXQgc2F2ZXMKK3RoZSByZXN1bHRzIG9mIGl0cyB0ZXN0cyB0byBzcGVlZCB1cCByZWNvbmZpZ3VyaW5nLiAgKENhY2hpbmcgaXMKK2Rpc2FibGVkIGJ5IGRlZmF1bHQgdG8gcHJldmVudCBwcm9ibGVtcyB3aXRoIGFjY2lkZW50YWwgdXNlIG9mIHN0YWxlCitjYWNoZSBmaWxlcy4pCisKKyAgIElmIHlvdSBuZWVkIHRvIGRvIHVudXN1YWwgdGhpbmdzIHRvIGNvbXBpbGUgdGhlIHBhY2thZ2UsIHBsZWFzZSB0cnkKK3RvIGZpZ3VyZSBvdXQgaG93IGBjb25maWd1cmUnIGNvdWxkIGNoZWNrIHdoZXRoZXIgdG8gZG8gdGhlbSwgYW5kIG1haWwKK2RpZmZzIG9yIGluc3RydWN0aW9ucyB0byB0aGUgYWRkcmVzcyBnaXZlbiBpbiB0aGUgYFJFQURNRScgc28gdGhleSBjYW4KK2JlIGNvbnNpZGVyZWQgZm9yIHRoZSBuZXh0IHJlbGVhc2UuICBJZiB5b3UgYXJlIHVzaW5nIHRoZSBjYWNoZSwgYW5kIGF0Citzb21lIHBvaW50IGBjb25maWcuY2FjaGUnIGNvbnRhaW5zIHJlc3VsdHMgeW91IGRvbid0IHdhbnQgdG8ga2VlcCwgeW91CittYXkgcmVtb3ZlIG9yIGVkaXQgaXQuCisKKyAgIFRoZSBmaWxlIGBjb25maWd1cmUuYWMnIChvciBgY29uZmlndXJlLmluJykgaXMgdXNlZCB0byBjcmVhdGUKK2Bjb25maWd1cmUnIGJ5IGEgcHJvZ3JhbSBjYWxsZWQgYGF1dG9jb25mJy4gIFlvdSBvbmx5IG5lZWQKK2Bjb25maWd1cmUuYWMnIGlmIHlvdSB3YW50IHRvIGNoYW5nZSBpdCBvciByZWdlbmVyYXRlIGBjb25maWd1cmUnIHVzaW5nCithIG5ld2VyIHZlcnNpb24gb2YgYGF1dG9jb25mJy4KKworVGhlIHNpbXBsZXN0IHdheSB0byBjb21waWxlIHRoaXMgcGFja2FnZSBpczoKKworICAxLiBgY2QnIHRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgcGFja2FnZSdzIHNvdXJjZSBjb2RlIGFuZCB0eXBlCisgICAgIGAuL2NvbmZpZ3VyZScgdG8gY29uZmlndXJlIHRoZSBwYWNrYWdlIGZvciB5b3VyIHN5c3RlbS4gIElmIHlvdSdyZQorICAgICB1c2luZyBgY3NoJyBvbiBhbiBvbGQgdmVyc2lvbiBvZiBTeXN0ZW0gViwgeW91IG1pZ2h0IG5lZWQgdG8gdHlwZQorICAgICBgc2ggLi9jb25maWd1cmUnIGluc3RlYWQgdG8gcHJldmVudCBgY3NoJyBmcm9tIHRyeWluZyB0byBleGVjdXRlCisgICAgIGBjb25maWd1cmUnIGl0c2VsZi4KKworICAgICBSdW5uaW5nIGBjb25maWd1cmUnIHRha2VzIGF3aGlsZS4gIFdoaWxlIHJ1bm5pbmcsIGl0IHByaW50cyBzb21lCisgICAgIG1lc3NhZ2VzIHRlbGxpbmcgd2hpY2ggZmVhdHVyZXMgaXQgaXMgY2hlY2tpbmcgZm9yLgorCisgIDIuIFR5cGUgYG1ha2UnIHRvIGNvbXBpbGUgdGhlIHBhY2thZ2UuCisKKyAgMy4gT3B0aW9uYWxseSwgdHlwZSBgbWFrZSBjaGVjaycgdG8gcnVuIGFueSBzZWxmLXRlc3RzIHRoYXQgY29tZSB3aXRoCisgICAgIHRoZSBwYWNrYWdlLgorCisgIDQuIFR5cGUgYG1ha2UgaW5zdGFsbCcgdG8gaW5zdGFsbCB0aGUgcHJvZ3JhbXMgYW5kIGFueSBkYXRhIGZpbGVzIGFuZAorICAgICBkb2N1bWVudGF0aW9uLgorCisgIDUuIFlvdSBjYW4gcmVtb3ZlIHRoZSBwcm9ncmFtIGJpbmFyaWVzIGFuZCBvYmplY3QgZmlsZXMgZnJvbSB0aGUKKyAgICAgc291cmNlIGNvZGUgZGlyZWN0b3J5IGJ5IHR5cGluZyBgbWFrZSBjbGVhbicuICBUbyBhbHNvIHJlbW92ZSB0aGUKKyAgICAgZmlsZXMgdGhhdCBgY29uZmlndXJlJyBjcmVhdGVkIChzbyB5b3UgY2FuIGNvbXBpbGUgdGhlIHBhY2thZ2UgZm9yCisgICAgIGEgZGlmZmVyZW50IGtpbmQgb2YgY29tcHV0ZXIpLCB0eXBlIGBtYWtlIGRpc3RjbGVhbicuICBUaGVyZSBpcworICAgICBhbHNvIGEgYG1ha2UgbWFpbnRhaW5lci1jbGVhbicgdGFyZ2V0LCBidXQgdGhhdCBpcyBpbnRlbmRlZCBtYWlubHkKKyAgICAgZm9yIHRoZSBwYWNrYWdlJ3MgZGV2ZWxvcGVycy4gIElmIHlvdSB1c2UgaXQsIHlvdSBtYXkgaGF2ZSB0byBnZXQKKyAgICAgYWxsIHNvcnRzIG9mIG90aGVyIHByb2dyYW1zIGluIG9yZGVyIHRvIHJlZ2VuZXJhdGUgZmlsZXMgdGhhdCBjYW1lCisgICAgIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KKworQ29tcGlsZXJzIGFuZCBPcHRpb25zCis9PT09PT09PT09PT09PT09PT09PT0KKworICAgU29tZSBzeXN0ZW1zIHJlcXVpcmUgdW51c3VhbCBvcHRpb25zIGZvciBjb21waWxhdGlvbiBvciBsaW5raW5nIHRoYXQKK3RoZSBgY29uZmlndXJlJyBzY3JpcHQgZG9lcyBub3Qga25vdyBhYm91dC4gIFJ1biBgLi9jb25maWd1cmUgLS1oZWxwJworZm9yIGRldGFpbHMgb24gc29tZSBvZiB0aGUgcGVydGluZW50IGVudmlyb25tZW50IHZhcmlhYmxlcy4KKworICAgWW91IGNhbiBnaXZlIGBjb25maWd1cmUnIGluaXRpYWwgdmFsdWVzIGZvciBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMKK2J5IHNldHRpbmcgdmFyaWFibGVzIGluIHRoZSBjb21tYW5kIGxpbmUgb3IgaW4gdGhlIGVudmlyb25tZW50LiAgSGVyZQoraXMgYW4gZXhhbXBsZToKKworICAgICAuL2NvbmZpZ3VyZSBDQz1jODkgQ0ZMQUdTPS1PMiBMSUJTPS1scG9zaXgKKworICAgKk5vdGUgRGVmaW5pbmcgVmFyaWFibGVzOjosIGZvciBtb3JlIGRldGFpbHMuCisKK0NvbXBpbGluZyBGb3IgTXVsdGlwbGUgQXJjaGl0ZWN0dXJlcworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgIFlvdSBjYW4gY29tcGlsZSB0aGUgcGFja2FnZSBmb3IgbW9yZSB0aGFuIG9uZSBraW5kIG9mIGNvbXB1dGVyIGF0IHRoZQorc2FtZSB0aW1lLCBieSBwbGFjaW5nIHRoZSBvYmplY3QgZmlsZXMgZm9yIGVhY2ggYXJjaGl0ZWN0dXJlIGluIHRoZWlyCitvd24gZGlyZWN0b3J5LiAgVG8gZG8gdGhpcywgeW91IG11c3QgdXNlIGEgdmVyc2lvbiBvZiBgbWFrZScgdGhhdAorc3VwcG9ydHMgdGhlIGBWUEFUSCcgdmFyaWFibGUsIHN1Y2ggYXMgR05VIGBtYWtlJy4gIGBjZCcgdG8gdGhlCitkaXJlY3Rvcnkgd2hlcmUgeW91IHdhbnQgdGhlIG9iamVjdCBmaWxlcyBhbmQgZXhlY3V0YWJsZXMgdG8gZ28gYW5kIHJ1bgordGhlIGBjb25maWd1cmUnIHNjcmlwdC4gIGBjb25maWd1cmUnIGF1dG9tYXRpY2FsbHkgY2hlY2tzIGZvciB0aGUKK3NvdXJjZSBjb2RlIGluIHRoZSBkaXJlY3RvcnkgdGhhdCBgY29uZmlndXJlJyBpcyBpbiBhbmQgaW4gYC4uJy4KKworICAgSWYgeW91IGhhdmUgdG8gdXNlIGEgYG1ha2UnIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgYFZQQVRIJwordmFyaWFibGUsIHlvdSBoYXZlIHRvIGNvbXBpbGUgdGhlIHBhY2thZ2UgZm9yIG9uZSBhcmNoaXRlY3R1cmUgYXQgYQordGltZSBpbiB0aGUgc291cmNlIGNvZGUgZGlyZWN0b3J5LiAgQWZ0ZXIgeW91IGhhdmUgaW5zdGFsbGVkIHRoZQorcGFja2FnZSBmb3Igb25lIGFyY2hpdGVjdHVyZSwgdXNlIGBtYWtlIGRpc3RjbGVhbicgYmVmb3JlIHJlY29uZmlndXJpbmcKK2ZvciBhbm90aGVyIGFyY2hpdGVjdHVyZS4KKworSW5zdGFsbGF0aW9uIE5hbWVzCis9PT09PT09PT09PT09PT09PT0KKworICAgQnkgZGVmYXVsdCwgYG1ha2UgaW5zdGFsbCcgd2lsbCBpbnN0YWxsIHRoZSBwYWNrYWdlJ3MgZmlsZXMgaW4KK2AvdXNyL2xvY2FsL2JpbicsIGAvdXNyL2xvY2FsL21hbicsIGV0Yy4gIFlvdSBjYW4gc3BlY2lmeSBhbgoraW5zdGFsbGF0aW9uIHByZWZpeCBvdGhlciB0aGFuIGAvdXNyL2xvY2FsJyBieSBnaXZpbmcgYGNvbmZpZ3VyZScgdGhlCitvcHRpb24gYC0tcHJlZml4PVBBVEgnLgorCisgICBZb3UgY2FuIHNwZWNpZnkgc2VwYXJhdGUgaW5zdGFsbGF0aW9uIHByZWZpeGVzIGZvcgorYXJjaGl0ZWN0dXJlLXNwZWNpZmljIGZpbGVzIGFuZCBhcmNoaXRlY3R1cmUtaW5kZXBlbmRlbnQgZmlsZXMuICBJZiB5b3UKK2dpdmUgYGNvbmZpZ3VyZScgdGhlIG9wdGlvbiBgLS1leGVjLXByZWZpeD1QQVRIJywgdGhlIHBhY2thZ2Ugd2lsbCB1c2UKK1BBVEggYXMgdGhlIHByZWZpeCBmb3IgaW5zdGFsbGluZyBwcm9ncmFtcyBhbmQgbGlicmFyaWVzLgorRG9jdW1lbnRhdGlvbiBhbmQgb3RoZXIgZGF0YSBmaWxlcyB3aWxsIHN0aWxsIHVzZSB0aGUgcmVndWxhciBwcmVmaXguCisKKyAgIEluIGFkZGl0aW9uLCBpZiB5b3UgdXNlIGFuIHVudXN1YWwgZGlyZWN0b3J5IGxheW91dCB5b3UgY2FuIGdpdmUKK29wdGlvbnMgbGlrZSBgLS1iaW5kaXI9UEFUSCcgdG8gc3BlY2lmeSBkaWZmZXJlbnQgdmFsdWVzIGZvciBwYXJ0aWN1bGFyCitraW5kcyBvZiBmaWxlcy4gIFJ1biBgY29uZmlndXJlIC0taGVscCcgZm9yIGEgbGlzdCBvZiB0aGUgZGlyZWN0b3JpZXMKK3lvdSBjYW4gc2V0IGFuZCB3aGF0IGtpbmRzIG9mIGZpbGVzIGdvIGluIHRoZW0uCisKKyAgIElmIHRoZSBwYWNrYWdlIHN1cHBvcnRzIGl0LCB5b3UgY2FuIGNhdXNlIHByb2dyYW1zIHRvIGJlIGluc3RhbGxlZAord2l0aCBhbiBleHRyYSBwcmVmaXggb3Igc3VmZml4IG9uIHRoZWlyIG5hbWVzIGJ5IGdpdmluZyBgY29uZmlndXJlJyB0aGUKK29wdGlvbiBgLS1wcm9ncmFtLXByZWZpeD1QUkVGSVgnIG9yIGAtLXByb2dyYW0tc3VmZml4PVNVRkZJWCcuCisKK09wdGlvbmFsIEZlYXR1cmVzCis9PT09PT09PT09PT09PT09PQorCisgICBTb21lIHBhY2thZ2VzIHBheSBhdHRlbnRpb24gdG8gYC0tZW5hYmxlLUZFQVRVUkUnIG9wdGlvbnMgdG8KK2Bjb25maWd1cmUnLCB3aGVyZSBGRUFUVVJFIGluZGljYXRlcyBhbiBvcHRpb25hbCBwYXJ0IG9mIHRoZSBwYWNrYWdlLgorVGhleSBtYXkgYWxzbyBwYXkgYXR0ZW50aW9uIHRvIGAtLXdpdGgtUEFDS0FHRScgb3B0aW9ucywgd2hlcmUgUEFDS0FHRQoraXMgc29tZXRoaW5nIGxpa2UgYGdudS1hcycgb3IgYHgnIChmb3IgdGhlIFggV2luZG93IFN5c3RlbSkuICBUaGUKK2BSRUFETUUnIHNob3VsZCBtZW50aW9uIGFueSBgLS1lbmFibGUtJyBhbmQgYC0td2l0aC0nIG9wdGlvbnMgdGhhdCB0aGUKK3BhY2thZ2UgcmVjb2duaXplcy4KKworICAgRm9yIHBhY2thZ2VzIHRoYXQgdXNlIHRoZSBYIFdpbmRvdyBTeXN0ZW0sIGBjb25maWd1cmUnIGNhbiB1c3VhbGx5CitmaW5kIHRoZSBYIGluY2x1ZGUgYW5kIGxpYnJhcnkgZmlsZXMgYXV0b21hdGljYWxseSwgYnV0IGlmIGl0IGRvZXNuJ3QsCit5b3UgY2FuIHVzZSB0aGUgYGNvbmZpZ3VyZScgb3B0aW9ucyBgLS14LWluY2x1ZGVzPURJUicgYW5kCitgLS14LWxpYnJhcmllcz1ESVInIHRvIHNwZWNpZnkgdGhlaXIgbG9jYXRpb25zLgorCitTcGVjaWZ5aW5nIHRoZSBTeXN0ZW0gVHlwZQorPT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAgVGhlcmUgbWF5IGJlIHNvbWUgZmVhdHVyZXMgYGNvbmZpZ3VyZScgY2Fubm90IGZpZ3VyZSBvdXQKK2F1dG9tYXRpY2FsbHksIGJ1dCBuZWVkcyB0byBkZXRlcm1pbmUgYnkgdGhlIHR5cGUgb2YgbWFjaGluZSB0aGUgcGFja2FnZQord2lsbCBydW4gb24uICBVc3VhbGx5LCBhc3N1bWluZyB0aGUgcGFja2FnZSBpcyBidWlsdCB0byBiZSBydW4gb24gdGhlCitfc2FtZV8gYXJjaGl0ZWN0dXJlcywgYGNvbmZpZ3VyZScgY2FuIGZpZ3VyZSB0aGF0IG91dCwgYnV0IGlmIGl0IHByaW50cworYSBtZXNzYWdlIHNheWluZyBpdCBjYW5ub3QgZ3Vlc3MgdGhlIG1hY2hpbmUgdHlwZSwgZ2l2ZSBpdCB0aGUKK2AtLWJ1aWxkPVRZUEUnIG9wdGlvbi4gIFRZUEUgY2FuIGVpdGhlciBiZSBhIHNob3J0IG5hbWUgZm9yIHRoZSBzeXN0ZW0KK3R5cGUsIHN1Y2ggYXMgYHN1bjQnLCBvciBhIGNhbm9uaWNhbCBuYW1lIHdoaWNoIGhhcyB0aGUgZm9ybToKKworICAgICBDUFUtQ09NUEFOWS1TWVNURU0KKword2hlcmUgU1lTVEVNIGNhbiBoYXZlIG9uZSBvZiB0aGVzZSBmb3JtczoKKworICAgICBPUyBLRVJORUwtT1MKKworICAgU2VlIHRoZSBmaWxlIGBjb25maWcuc3ViJyBmb3IgdGhlIHBvc3NpYmxlIHZhbHVlcyBvZiBlYWNoIGZpZWxkLiAgSWYKK2Bjb25maWcuc3ViJyBpc24ndCBpbmNsdWRlZCBpbiB0aGlzIHBhY2thZ2UsIHRoZW4gdGhpcyBwYWNrYWdlIGRvZXNuJ3QKK25lZWQgdG8ga25vdyB0aGUgbWFjaGluZSB0eXBlLgorCisgICBJZiB5b3UgYXJlIF9idWlsZGluZ18gY29tcGlsZXIgdG9vbHMgZm9yIGNyb3NzLWNvbXBpbGluZywgeW91IHNob3VsZAordXNlIHRoZSBgLS10YXJnZXQ9VFlQRScgb3B0aW9uIHRvIHNlbGVjdCB0aGUgdHlwZSBvZiBzeXN0ZW0gdGhleSB3aWxsCitwcm9kdWNlIGNvZGUgZm9yLgorCisgICBJZiB5b3Ugd2FudCB0byBfdXNlXyBhIGNyb3NzIGNvbXBpbGVyLCB0aGF0IGdlbmVyYXRlcyBjb2RlIGZvciBhCitwbGF0Zm9ybSBkaWZmZXJlbnQgZnJvbSB0aGUgYnVpbGQgcGxhdGZvcm0sIHlvdSBzaG91bGQgc3BlY2lmeSB0aGUKKyJob3N0IiBwbGF0Zm9ybSAoaS5lLiwgdGhhdCBvbiB3aGljaCB0aGUgZ2VuZXJhdGVkIHByb2dyYW1zIHdpbGwKK2V2ZW50dWFsbHkgYmUgcnVuKSB3aXRoIGAtLWhvc3Q9VFlQRScuCisKK1NoYXJpbmcgRGVmYXVsdHMKKz09PT09PT09PT09PT09PT0KKworICAgSWYgeW91IHdhbnQgdG8gc2V0IGRlZmF1bHQgdmFsdWVzIGZvciBgY29uZmlndXJlJyBzY3JpcHRzIHRvIHNoYXJlLAoreW91IGNhbiBjcmVhdGUgYSBzaXRlIHNoZWxsIHNjcmlwdCBjYWxsZWQgYGNvbmZpZy5zaXRlJyB0aGF0IGdpdmVzCitkZWZhdWx0IHZhbHVlcyBmb3IgdmFyaWFibGVzIGxpa2UgYENDJywgYGNhY2hlX2ZpbGUnLCBhbmQgYHByZWZpeCcuCitgY29uZmlndXJlJyBsb29rcyBmb3IgYFBSRUZJWC9zaGFyZS9jb25maWcuc2l0ZScgaWYgaXQgZXhpc3RzLCB0aGVuCitgUFJFRklYL2V0Yy9jb25maWcuc2l0ZScgaWYgaXQgZXhpc3RzLiAgT3IsIHlvdSBjYW4gc2V0IHRoZQorYENPTkZJR19TSVRFJyBlbnZpcm9ubWVudCB2YXJpYWJsZSB0byB0aGUgbG9jYXRpb24gb2YgdGhlIHNpdGUgc2NyaXB0LgorQSB3YXJuaW5nOiBub3QgYWxsIGBjb25maWd1cmUnIHNjcmlwdHMgbG9vayBmb3IgYSBzaXRlIHNjcmlwdC4KKworRGVmaW5pbmcgVmFyaWFibGVzCis9PT09PT09PT09PT09PT09PT0KKworICAgVmFyaWFibGVzIG5vdCBkZWZpbmVkIGluIGEgc2l0ZSBzaGVsbCBzY3JpcHQgY2FuIGJlIHNldCBpbiB0aGUKK2Vudmlyb25tZW50IHBhc3NlZCB0byBgY29uZmlndXJlJy4gIEhvd2V2ZXIsIHNvbWUgcGFja2FnZXMgbWF5IHJ1bgorY29uZmlndXJlIGFnYWluIGR1cmluZyB0aGUgYnVpbGQsIGFuZCB0aGUgY3VzdG9taXplZCB2YWx1ZXMgb2YgdGhlc2UKK3ZhcmlhYmxlcyBtYXkgYmUgbG9zdC4gIEluIG9yZGVyIHRvIGF2b2lkIHRoaXMgcHJvYmxlbSwgeW91IHNob3VsZCBzZXQKK3RoZW0gaW4gdGhlIGBjb25maWd1cmUnIGNvbW1hbmQgbGluZSwgdXNpbmcgYFZBUj12YWx1ZScuICBGb3IgZXhhbXBsZToKKworICAgICAuL2NvbmZpZ3VyZSBDQz0vdXNyL2xvY2FsMi9iaW4vZ2NjCisKK3dpbGwgY2F1c2UgdGhlIHNwZWNpZmllZCBnY2MgdG8gYmUgdXNlZCBhcyB0aGUgQyBjb21waWxlciAodW5sZXNzIGl0IGlzCitvdmVycmlkZGVuIGluIHRoZSBzaXRlIHNoZWxsIHNjcmlwdCkuCisKK2Bjb25maWd1cmUnIEludm9jYXRpb24KKz09PT09PT09PT09PT09PT09PT09PT0KKworICAgYGNvbmZpZ3VyZScgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIG9wdGlvbnMgdG8gY29udHJvbCBob3cgaXQKK29wZXJhdGVzLgorCitgLS1oZWxwJworYC1oJworICAgICBQcmludCBhIHN1bW1hcnkgb2YgdGhlIG9wdGlvbnMgdG8gYGNvbmZpZ3VyZScsIGFuZCBleGl0LgorCitgLS12ZXJzaW9uJworYC1WJworICAgICBQcmludCB0aGUgdmVyc2lvbiBvZiBBdXRvY29uZiB1c2VkIHRvIGdlbmVyYXRlIHRoZSBgY29uZmlndXJlJworICAgICBzY3JpcHQsIGFuZCBleGl0LgorCitgLS1jYWNoZS1maWxlPUZJTEUnCisgICAgIEVuYWJsZSB0aGUgY2FjaGU6IHVzZSBhbmQgc2F2ZSB0aGUgcmVzdWx0cyBvZiB0aGUgdGVzdHMgaW4gRklMRSwKKyAgICAgdHJhZGl0aW9uYWxseSBgY29uZmlnLmNhY2hlJy4gIEZJTEUgZGVmYXVsdHMgdG8gYC9kZXYvbnVsbCcgdG8KKyAgICAgZGlzYWJsZSBjYWNoaW5nLgorCitgLS1jb25maWctY2FjaGUnCitgLUMnCisgICAgIEFsaWFzIGZvciBgLS1jYWNoZS1maWxlPWNvbmZpZy5jYWNoZScuCisKK2AtLXF1aWV0JworYC0tc2lsZW50JworYC1xJworICAgICBEbyBub3QgcHJpbnQgbWVzc2FnZXMgc2F5aW5nIHdoaWNoIGNoZWNrcyBhcmUgYmVpbmcgbWFkZS4gIFRvCisgICAgIHN1cHByZXNzIGFsbCBub3JtYWwgb3V0cHV0LCByZWRpcmVjdCBpdCB0byBgL2Rldi9udWxsJyAoYW55IGVycm9yCisgICAgIG1lc3NhZ2VzIHdpbGwgc3RpbGwgYmUgc2hvd24pLgorCitgLS1zcmNkaXI9RElSJworICAgICBMb29rIGZvciB0aGUgcGFja2FnZSdzIHNvdXJjZSBjb2RlIGluIGRpcmVjdG9yeSBESVIuICBVc3VhbGx5CisgICAgIGBjb25maWd1cmUnIGNhbiBkZXRlcm1pbmUgdGhhdCBkaXJlY3RvcnkgYXV0b21hdGljYWxseS4KKworYGNvbmZpZ3VyZScgYWxzbyBhY2NlcHRzIHNvbWUgb3RoZXIsIG5vdCB3aWRlbHkgdXNlZnVsLCBvcHRpb25zLiAgUnVuCitgY29uZmlndXJlIC0taGVscCcgZm9yIG1vcmUgZGV0YWlscy4KKwpkaWZmIC0tZ2l0IGEvTElDRU5TRSBiL0xJQ0VOU0UKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA4NmVmZAotLS0gL2Rldi9udWxsCisrKyBiL0xJQ0VOU0UKQEAgLTAsMCArMSw0NCBAQAorVGhpcyBsaWNlbnNlIGFwcGxpZXMgdG8gYWxsIHBhcnRzIG9mIFByb3RvY29sIEJ1ZmZlcnMgZXhjZXB0IHRoZSBmb2xsb3dpbmc6CisKKyAgLSBBdG9taWNvcHMgc3VwcG9ydCBmb3IgZ2VuZXJpYyBnY2MsIGxvY2F0ZWQgaW4KKyAgICBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaC4KKyAgICBUaGlzIGZpbGUgaXMgY29weXJpZ2h0ZWQgYnkgUmVkIEhhdCBJbmMuCisKKyAgLSBBdG9taWNvcHMgc3VwcG9ydCBmb3IgQUlYL1BPV0VSLCBsb2NhdGVkIGluCisgICAgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FpeC5oLgorICAgIFRoaXMgZmlsZSBpcyBjb3B5cmlnaHRlZCBieSBCbG9vbWJlcmcgRmluYW5jZSBMUC4KKworICAtIEFuZG9yaWQubWssIHdoaWNoIGlzIGNvcHlyaWdodGVkIGJ5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QuCisKK0NvcHlyaWdodCAyMDE0LCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Cittb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCittZXQ6CisKKyAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Citub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCitjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCitpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCitkaXN0cmlidXRpb24uCisgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCitjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQordGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKworVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKK0xJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKK09XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCitEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKK1RIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyhJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworQ29kZSBnZW5lcmF0ZWQgYnkgdGhlIFByb3RvY29sIEJ1ZmZlciBjb21waWxlciBpcyBvd25lZCBieSB0aGUgb3duZXIKK29mIHRoZSBpbnB1dCBmaWxlIHVzZWQgd2hlbiBnZW5lcmF0aW5nIGl0LiAgVGhpcyBjb2RlIGlzIG5vdAorc3RhbmRhbG9uZSBhbmQgcmVxdWlyZXMgYSBzdXBwb3J0IGxpYnJhcnkgdG8gYmUgbGlua2VkIHdpdGggaXQuICBUaGlzCitzdXBwb3J0IGxpYnJhcnkgaXMgaXRzZWxmIGNvdmVyZWQgYnkgdGhlIGFib3ZlIGxpY2Vuc2UuCmRpZmYgLS1naXQgYS9NYWtlZmlsZS5hbSBiL01ha2VmaWxlLmFtCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjMDM5MjMKLS0tIC9kZXYvbnVsbAorKysgYi9NYWtlZmlsZS5hbQpAQCAtMCwwICsxLDM1OSBAQAorIyMgUHJvY2VzcyB0aGlzIGZpbGUgd2l0aCBhdXRvbWFrZSB0byBwcm9kdWNlIE1ha2VmaWxlLmluCisKK0FDTE9DQUxfQU1GTEFHUyA9IC1JIG00CisKK0FVVE9NQUtFX09QVElPTlMgPSBmb3JlaWduCisKKyMgQnVpbGQgLiBiZWZvcmUgc3JjIHNvIHRoYXQgb3VyIGFsbC1sb2NhbCBhbmQgY2xlYW4tbG9jYWwgaG9va3Mga2lja3MgaW4gYXQKKyMgdGhlIHJpZ2h0IHRpbWUuCitTVUJESVJTID0gLiBzcmMKKworIyBBbHdheXMgaW5jbHVkZSBndGVzdCBpbiBkaXN0cmlidXRpb25zLgorRElTVF9TVUJESVJTID0gJChzdWJkaXJzKSBzcmMKKworIyBCdWlsZCBndGVzdCBiZWZvcmUgd2UgYnVpbGQgcHJvdG9idWYgdGVzdHMuICBXZSBkb24ndCBhZGQgZ3Rlc3QgdG8gU1VCRElSUworIyBiZWNhdXNlIHRoZW4gIm1ha2UgY2hlY2siIHdvdWxkIGFsc28gYnVpbGQgYW5kIHJ1biBhbGwgb2YgZ3Rlc3QncyBvd24gdGVzdHMsCisjIHdoaWNoIHRha2VzIGEgbG90IG9mIHRpbWUgYW5kIGlzIGdlbmVyYWxseSBub3QgdXNlZnVsIHRvIHVzLiAgQWxzbywgd2UgZG9uJ3QKKyMgd2FudCAibWFrZSBpbnN0YWxsIiB0byByZWN1cnNlIGludG8gZ3Rlc3Qgc2luY2Ugd2UgZG9uJ3Qgd2FudCB0byBvdmVyd3JpdGUKKyMgdGhlIGluc3RhbGxlZCB2ZXJzaW9uIG9mIGd0ZXN0IGlmIHRoZXJlIGlzIG9uZS4KK2NoZWNrLWxvY2FsOgorCUBlY2hvICJNYWtpbmcgbGliL2xpYmd0ZXN0LmEgbGliL2xpYmd0ZXN0X21haW4uYSBpbiBndGVzdCIKKwlAY2QgZ3Rlc3QgJiYgJChNQUtFKSAkKEFNX01BS0VGTEFHUykgbGliL2xpYmd0ZXN0LmxhIGxpYi9saWJndGVzdF9tYWluLmxhCisKKyMgV2Ugd291bGQgbGlrZSB0byBjbGVhbiBndGVzdCB3aGVuICJtYWtlIGNsZWFuIiBpcyBpbnZva2VkLiAgQnV0IHdlIGhhdmUgdG8KKyMgYmUgY2FyZWZ1bCBiZWNhdXNlIGNsZWFuLWxvY2FsIGlzIGFsc28gaW52b2tlZCBkdXJpbmcgIm1ha2UgZGlzdGNsZWFuIiwgYnV0CisjICJtYWtlIGRpc3RjbGVhbiIgYWxyZWFkeSByZWN1cnNlcyBpbnRvIGd0ZXN0IGJlY2F1c2UgaXQncyBsaXN0ZWQgYW1vbmcgdGhlCisjIERJU1RfU1VCRElSUy4gIGRpc3RjbGVhbiB3aWxsIGRlbGV0ZSBndGVzdC9NYWtlZmlsZSwgc28gaWYgd2UgdGhlbiB0cnkgdG8KKyMgY2QgdG8gdGhlIGRpcmVjdG9yeSBhZ2FpbiBhbmQgIm1ha2UgY2xlYW4iIGl0IHdpbGwgZmFpbC4gIFNvLCBjaGVjayB0aGF0IHRoZQorIyBNYWtlZmlsZSBleGlzdHMgYmVmb3JlIHJlY3Vyc2luZy4KK2NsZWFuLWxvY2FsOgorCUBpZiB0ZXN0IC1lIGd0ZXN0L01ha2VmaWxlOyB0aGVuIFwKKwkgIGVjaG8gIk1ha2luZyBjbGVhbiBpbiBndGVzdCI7IFwKKwkgIGNkIGd0ZXN0ICYmICQoTUFLRSkgJChBTV9NQUtFRkxBR1MpIGNsZWFuOyBcCisJZmkKKworcGtnY29uZmlnZGlyID0gJChsaWJkaXIpL3BrZ2NvbmZpZworcGtnY29uZmlnX0RBVEEgPSBwcm90b2J1Zi5wYyBwcm90b2J1Zi1saXRlLnBjCisKK2phdmFfRVhUUkFfRElTVD0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2UuamF2YSAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Fic3RyYWN0TWVzc2FnZUxpdGUuamF2YSAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RQYXJzZXIuamF2YSAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9CbG9ja2luZ1JwY0NoYW5uZWwuamF2YSAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Jsb2NraW5nU2VydmljZS5qYXZhICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQm91bmRlZEJ5dGVTdHJpbmcuamF2YSAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9CeXRlU3RyaW5nLmphdmEgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkSW5wdXRTdHJlYW0uamF2YSAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQ29kZWRPdXRwdXRTdHJlYW0uamF2YSAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EZXNjcmlwdG9ycy5qYXZhICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0R5bmFtaWNNZXNzYWdlLmphdmEgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uLmphdmEgICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9FeHRlbnNpb25MaXRlLmphdmEgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0V4dGVuc2lvblJlZ2lzdHJ5LmphdmEgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmphdmEgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9GaWVsZFNldC5qYXZhICAgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0dlbmVyYXRlZE1lc3NhZ2UuamF2YSAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZUxpdGUuamF2YSAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9JbnRlcm5hbC5qYXZhICAgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5qYXZhIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkLmphdmEgICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5RmllbGRMaXRlLmphdmEgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdBcnJheUxpc3QuamF2YSAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eVN0cmluZ0xpc3QuamF2YSAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MaXRlcmFsQnl0ZVN0cmluZy5qYXZhICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEVudHJ5LmphdmEgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRW50cnlMaXRlLmphdmEgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBGaWVsZC5qYXZhICAgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZpZWxkTGl0ZS5qYXZhICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWVzc2FnZS5qYXZhICAgICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlTGl0ZS5qYXZhICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VMaXRlT3JCdWlsZGVyLmphdmEgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWVzc2FnZU9yQnVpbGRlci5qYXZhICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlUmVmbGVjdGlvbi5qYXZhICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1BhcnNlci5qYXZhICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUHJvdG9jb2xNZXNzYWdlRW51bS5qYXZhICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Qcm90b2NvbFN0cmluZ0xpc3QuamF2YSAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JlcGVhdGVkRmllbGRCdWlsZGVyLmphdmEgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUm9wZUJ5dGVTdHJpbmcuamF2YSAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNDYWxsYmFjay5qYXZhICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JwY0NoYW5uZWwuamF2YSAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUnBjQ29udHJvbGxlci5qYXZhICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNVdGlsLmphdmEgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NlcnZpY2VFeGNlcHRpb24uamF2YSAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2VydmljZS5qYXZhICAgICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9TaW5nbGVGaWVsZEJ1aWxkZXIuamF2YSAgICAgICAgICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NtYWxsU29ydGVkTWFwLmphdmEgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGV4dEZvcm1hdC5qYXZhICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbi5qYXZhICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Vua25vd25GaWVsZFNldC5qYXZhICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0TGl0ZS5qYXZhICAgICAgICAgICAgXAorICBqYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbm1vZGlmaWFibGVMYXp5U3RyaW5nTGlzdC5qYXZhICAgICBcCisgIGphdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1V0ZjguamF2YSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdC5qYXZhICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2VUZXN0LmphdmEgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0JvdW5kZWRCeXRlU3RyaW5nVGVzdC5qYXZhICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQnl0ZVN0cmluZ1Rlc3QuamF2YSAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9DaGVja1V0ZjhUZXN0LmphdmEgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkSW5wdXRTdHJlYW1UZXN0LmphdmEgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQ29kZWRPdXRwdXRTdHJlYW1UZXN0LmphdmEgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EZXByZWNhdGVkRmllbGRUZXN0LmphdmEgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Rlc2NyaXB0b3JzVGVzdC5qYXZhICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRHluYW1pY01lc3NhZ2VUZXN0LmphdmEgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9GaWVsZFByZXNlbmNlVGVzdC5qYXZhICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0ZvcmNlRmllbGRCdWlsZGVyc1ByZVJ1bi5qYXZhICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZVRlc3QuamF2YSAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Jc1ZhbGlkVXRmOFRlc3QuamF2YSAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0lzVmFsaWRVdGY4VGVzdFV0aWwuamF2YSAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkTGl0ZVRlc3QuamF2YSAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5RmllbGRUZXN0LmphdmEgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlNZXNzYWdlTGl0ZVRlc3QuamF2YSAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eVN0cmluZ0FycmF5TGlzdFRlc3QuamF2YSAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5U3RyaW5nRW5kVG9FbmRUZXN0LmphdmEgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xpdGVFcXVhbHNBbmRIYXNoVGVzdC5qYXZhICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0LmphdmEgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MaXRlVGVzdC5qYXZhICAgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZvclByb3RvMkxpdGVUZXN0LmphdmEgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRm9yUHJvdG8yVGVzdC5qYXZhICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBUZXN0LmphdmEgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VUZXN0LmphdmEgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTmVzdGVkQnVpbGRlcnNUZXN0LmphdmEgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9QYXJzZXJUZXN0LmphdmEgICAgICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JlcGVhdGVkRmllbGRCdWlsZGVyVGVzdC5qYXZhICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUm9wZUJ5dGVTdHJpbmdTdWJzdHJpbmdUZXN0LmphdmEgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Sb3BlQnl0ZVN0cmluZ1Rlc3QuamF2YSAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NlcnZpY2VUZXN0LmphdmEgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2luZ2xlRmllbGRCdWlsZGVyVGVzdC5qYXZhICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9TbWFsbFNvcnRlZE1hcFRlc3QuamF2YSAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Rlc3RCYWRJZGVudGlmaWVycy5qYXZhICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGVzdFV0aWwuamF2YSAgICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9UZXh0Rm9ybWF0VGVzdC5qYXZhICAgICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Vua25vd25FbnVtVmFsdWVUZXN0LmphdmEgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0TGl0ZVRlc3QuamF2YSAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXRUZXN0LmphdmEgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1VubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0VGVzdC5qYXZhIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdFRlc3QuamF2YSAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9maWVsZF9wcmVzZW5jZV90ZXN0LnByb3RvICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2xhenlfZmllbGRzX2xpdGUucHJvdG8gICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbGl0ZV9lcXVhbHNfYW5kX2hhc2gucHJvdG8gICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QucHJvdG8gICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9mb3JfcHJvdG8yX3Rlc3QucHJvdG8gICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3QucHJvdG8gICAgICAgICAgICAgICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9idWlsZGVyc190ZXN0LnByb3RvICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2V4dGVuc2lvbl9saXRlLnByb3RvICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfZXh0ZW5zaW9uLnByb3RvICAgICAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25vbl9uZXN0ZWRfZXh0ZW5zaW9uX2xpdGUucHJvdG8gICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbm9uX25lc3RlZF9leHRlbnNpb24ucHJvdG8gICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3Rlc3QyLnByb3RvICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdDMucHJvdG8gICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvb3V0ZXJfY2xhc3NfbmFtZV90ZXN0LnByb3RvICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byAgICAgICAgICBcCisgIGphdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfY2hlY2tfdXRmOC5wcm90byAgICAgICAgICAgICAgIFwKKyAgamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jaGVja191dGY4X3NpemUucHJvdG8gICAgICAgICAgXAorICBqYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvICAgICAgICAgICBcCisgIGphdmEvcG9tLnhtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YS9SRUFETUUudHh0CisKK2phdmFuYW5vX0VYVFJBX0RJU1Q9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5qYXZhICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRmllbGREYXRhLmphdmEgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRmllbGRBcnJheS5qYXZhICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vV2lyZUZvcm1hdE5hbm8uamF2YSAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRXh0ZW5zaW9uLmphdmEgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vLmphdmEgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vVW5rbm93bkZpZWxkRGF0YS5qYXZhICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTWVzc2FnZU5hbm8uamF2YSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vSW50ZXJuYWxOYW5vLmphdmEgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi5qYXZhIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTWFwRmFjdG9yaWVzLmphdmEgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRXh0ZW5kYWJsZU1lc3NhZ2VOYW5vLmphdmEgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTWVzc2FnZU5hbm9QcmludGVyLmphdmEgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfYWNjZXNzb3JzX25hbm8ucHJvdG8gICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV9jbGFzc19uYW5vLnByb3RvICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVmZXJlbmNlX3R5cGVzX25hbm8ucHJvdG8gICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3JlcGVhdGVkX25hbm8ucHJvdG8gIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfaGFzX25hbm8ucHJvdG8gICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbmFuby5wcm90byAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbXVsdGlwbGVfbmFtZWNsYXNoX25hbm8ucHJvdG8gIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3Rfc2luZ2xlX25hbm8ucHJvdG8gICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTmFub1Rlc3QuamF2YSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3Rfc2ltcGxlX25hbm8ucHJvdG8gICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfaW1wb3J0X25hbm8ucHJvdG8gICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVwZWF0ZWRfbWVyZ2VfbmFuby5wcm90byAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX25hbm8ucHJvdG8gICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVwZWF0ZWRfcGFja2FibGVzX25hbm8ucHJvdG8gIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3Npbmd1bGFyX25hbm8ucHJvdG8gIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVjdXJzaXZlX25hbm8ucHJvdG8gICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3BhY2tlZF9uYW5vLnByb3RvICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV92YWxpZGl0eV9uYW5vLnByb3RvICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3Rfc3RyaW5ndXRmOF9uYW5vLnByb3RvICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbXVsdGlwbGVfbmFuby5wcm90byAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV9jbGFzc19tdWx0aXBsZV9uYW5vLnByb3RvIFwKKyAgamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vbWFwX3Rlc3QucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vUkVBRE1FLnR4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgamF2YW5hbm8vcG9tLnhtbAorCisKK3B5dGhvbl9FWFRSQV9ESVNUPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2FwaV9pbXBsZW1lbnRhdGlvbi5jYyAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvYXBpX2ltcGxlbWVudGF0aW9uLnB5ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9jb250YWluZXJzLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2NwcF9tZXNzYWdlLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVjb2Rlci5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX2RhdGFiYXNlX3Rlc3QucHkgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0LnB5ICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9wb29sX3Rlc3QxLnByb3RvICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX3Bvb2xfdGVzdDIucHJvdG8gICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcHl0aG9uX3Rlc3QucHkgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl90ZXN0LnB5ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9lbmNvZGVyLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2VudW1fdHlwZV93cmFwcGVyLnB5ICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0MS5wcm90byAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9mYWN0b3J5X3Rlc3QyLnByb3RvICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2dlbmVyYXRvcl90ZXN0LnB5ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9mYWN0b3J5X3B5dGhvbl90ZXN0LnB5ICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tZXNzYWdlX2ZhY3RvcnlfdGVzdC5weSAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfbGlzdGVuZXIucHkgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9weXRob25fdGVzdC5weSAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tZXNzYWdlX3Rlc3QucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21pc3NpbmdfZW51bV92YWx1ZXMucHJvdG8gICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbW9yZV9leHRlbnNpb25zLnByb3RvICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tb3JlX2V4dGVuc2lvbnNfZHluYW1pYy5wcm90byAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfbWVzc2FnZXMucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvX3BhcmFtZXRlcml6ZWQucHkgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9wcm90b19idWlsZGVyX3Rlc3QucHkgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3B5dGhvbl9tZXNzYWdlLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvcmVmbGVjdGlvbl90ZXN0LnB5ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9zZXJ2aWNlX3JlZmxlY3Rpb25fdGVzdC5weSAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3N5bWJvbF9kYXRhYmFzZV90ZXN0LnB5ICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG8gICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90ZXN0X3V0aWwucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3RleHRfZW5jb2RpbmdfdGVzdC5weSAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGV4dF9mb3JtYXRfdGVzdC5weSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90eXBlX2NoZWNrZXJzLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3Vua25vd25fZmllbGRzX3Rlc3QucHkgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvd2lyZV9mb3JtYXQucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC93aXJlX2Zvcm1hdF90ZXN0LnB5ICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL19faW5pdF9fLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvaW1wb3J0X3Rlc3RfcGFja2FnZS9fX2luaXRfXy5weSAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9pbXBvcnRfdGVzdF9wYWNrYWdlL2lubmVyLnByb3RvICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ltcG9ydF90ZXN0X3BhY2thZ2Uvb3V0ZXIucHJvdG8gICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvUkVBRE1FICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9jcHBfbWVzc2FnZS5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3IuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfcG9vbC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9jb250YWluZXJzLmggICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX2NvbnRhaW5lcnMuY2MgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2V4dGVuc2lvbl9kaWN0LmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvZXh0ZW5zaW9uX2RpY3QuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9tZXNzYWdlLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L21lc3NhZ2UuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvcHJvdG8yX2FwaV90ZXN0LnByb3RvICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9weXRob24ucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3B5dGhvbl9wcm90b2J1Zi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfY29tcG9zaXRlX2NvbnRhaW5lci5oICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyLmNjICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX3NjYWxhcl9jb250YWluZXIuaCAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lci5jYyAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9zY29wZWRfcHlvYmplY3RfcHRyLmggICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L19faW5pdF9fLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfcG9vbC5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2ZhY3RvcnkucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3Byb3RvX2J1aWxkZXIucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2VfcmVmbGVjdGlvbi5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvc3ltYm9sX2RhdGFiYXNlLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2VuY29kaW5nLnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LnB5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9nb29nbGUvcHJvdG9idWYvX19pbml0X18ucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL2dvb2dsZS9fX2luaXRfXy5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vZXpfc2V0dXAucHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9zZXR1cC5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcHl0aG9uL21veC5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBweXRob24vc3R1Ym91dC5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHB5dGhvbi9SRUFETUUudHh0CisKK3J1YnlfRVhUUkFfRElTVD0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L1JFQURNRS5tZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvUmFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvZGVmcy5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9lbmNvZGVfZGVjb2RlLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL2V4dGNvbmYucmIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvbWFwLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9tZXNzYWdlLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL3Byb3RvYnVmLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvcHJvdG9idWYuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9yZXBlYXRlZF9maWVsZC5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL3N0b3JhZ2UuYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvdXBiLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy91cGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvZ29vZ2xlLXByb3RvYnVmLmdlbXNwZWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcnVieS9saWIvZ29vZ2xlL3Byb3RvYnVmLnJiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L3Rlc3RzL2Jhc2ljLnJiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvdGVzdHMvc3RyZXNzLnJiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcnVieS90ZXN0cy9nZW5lcmF0ZWRfY29kZS5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBydWJ5L3Rlc3RzL2dlbmVyYXRlZF9jb2RlLnJiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJ1YnkvdGVzdHMvZ2VuZXJhdGVkX2NvZGVfdGVzdC5yYgorCithbGxfRVhUUkFfRElTVD0kKGphdmFfRVhUUkFfRElTVCkgJChqYXZhbmFub19FWFRSQV9ESVNUKSAkKHB5dGhvbl9FWFRSQV9ESVNUKSAkKHJ1YnlfRVhUUkFfRElTVCkKKworRVhUUkFfRElTVCA9ICQoQERJU1RfTEFOR0BfRVhUUkFfRElTVCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGF1dG9nZW4uc2ggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ2VuZXJhdGVfZGVzY3JpcHRvcl9wcm90by5zaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBSRUFETUUubWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIElOU1RBTEwudHh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgTElDRU5TRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBDT05UUklCVVRPUlMudHh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIENIQU5HRVMudHh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY29uZmlnLmguaW5jbHVkZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBlZGl0b3JzL1JFQURNRS50eHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGVkaXRvcnMvcHJvdG8udmltICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZWRpdG9ycy9wcm90b2J1Zi1tb2RlLmVsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2c3Byb2plY3RzL2NvbmZpZy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZzcHJvamVjdHMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BiY29uZmlnLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdnNwcm9qZWN0cy9leHRyYWN0X2luY2x1ZGVzLmJhdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2c3Byb2plY3RzL2xpYnByb3RvYnVmLnZjcHJvaiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZzcHJvamVjdHMvbGlicHJvdG9idWYtbGl0ZS52Y3Byb2ogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdnNwcm9qZWN0cy9saWJwcm90b2MudmNwcm9qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2c3Byb2plY3RzL3Byb3RvYnVmLnNsbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZzcHJvamVjdHMvcHJvdG9jLnZjcHJvaiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdnNwcm9qZWN0cy9yZWFkbWUudHh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2c3Byb2plY3RzL3Rlc3RfcGx1Z2luLnZjcHJvaiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZzcHJvamVjdHMvdGVzdHMudmNwcm9qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdnNwcm9qZWN0cy9saXRlLXRlc3QudmNwcm9qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2c3Byb2plY3RzL2NvbnZlcnQyMDA4dG8yMDA1LnNoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGV4YW1wbGVzL1JFQURNRS50eHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZXhhbXBsZXMvTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBleGFtcGxlcy9hZGRyZXNzYm9vay5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGV4YW1wbGVzL2FkZF9wZXJzb24uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZXhhbXBsZXMvbGlzdF9wZW9wbGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBleGFtcGxlcy9BZGRQZXJzb24uamF2YSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGV4YW1wbGVzL0xpc3RQZW9wbGUuamF2YSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZXhhbXBsZXMvYWRkX3BlcnNvbi5weSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBleGFtcGxlcy9saXN0X3Blb3BsZS5weQorCisjIERlbGV0ZXMgYWxsIHRoZSBmaWxlcyBnZW5lcmF0ZWQgYnkgYXV0b2dlbi5zaC4KK01BSU5UQUlORVJDTEVBTkZJTEVTID0gICBcCisgIGFjbG9jYWwubTQgICAgICAgICAgICAgXAorICBjb25maWcuZ3Vlc3MgICAgICAgICAgIFwKKyAgY29uZmlnLnN1YiAgICAgICAgICAgICBcCisgIGNvbmZpZ3VyZSAgICAgICAgICAgICAgXAorICBkZXBjb21wICAgICAgICAgICAgICAgIFwKKyAgaW5zdGFsbC1zaCAgICAgICAgICAgICBcCisgIGx0bWFpbi5zaCAgICAgICAgICAgICAgXAorICBNYWtlZmlsZS5pbiAgICAgICAgICAgIFwKKyAgbWlzc2luZyAgICAgICAgICAgICAgICBcCisgIG1raW5zdGFsbGRpcnMgICAgICAgICAgXAorICBjb25maWcuaC5pbiAgICAgICAgICAgIFwKKyAgc3RhbXAuaC5pbiAgICAgICAgICAgICBcCisgIG00L2x0c3VnYXIubTQgICAgICAgICAgXAorICBtNC9saWJ0b29sLm00ICAgICAgICAgIFwKKyAgbTQvbHR2ZXJzaW9uLm00ICAgICAgICBcCisgIG00L2x0fm9ic29sZXRlLm00ICAgICAgXAorICBtNC9sdG9wdGlvbnMubTQKZGlmZiAtLWdpdCBhL1JFQURNRS5tZCBiL1JFQURNRS5tZAppbmRleCA3ODQ0MDYyLi41ZWE2YWZmIDEwMDY0NAotLS0gYS9SRUFETUUubWQKKysrIGIvUkVBRE1FLm1kCkBAIC0xLDEyICsxLDE5MyBAQAotVGhpcyByZXBvIHdhcyBvcmlnaW5hbGx5IGV4cG9ydGVkIGZyb20gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLWNzaGFycC1wb3J0LAotYW5kIHJlcHJlc2VudHMgdGhlIGxhdGVzdCAibGVnYWN5IiB2ZXJzaW9uIG9mIHByb3RvYnVmLWNzaGFycC1wb3J0LgorUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0Cis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIAotVGhpcyBwcm9qZWN0IGhhcyBub3cgYmVlbiBmb2xkZWQgaW50byB0aGUgW21haW4gR29vZ2xlIFByb3RvY29sIEJ1ZmZlcnMgcHJvamVjdF0oaHR0cDovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmKSwKLWFuZCBpcyBiZWluZyByZXZhbXBlZCB0byBzdXBwb3J0IHByb3RvMy4gSXQgaXMgbm90IGV4cGVjdGVkIHRvIGJlIGZ1bGx5IGJhY2t3YXJkbHktY29tcGF0aWJsZSB3aXRoCi10aGUgY29kZSBpbiB0aGlzIHJlcG8gLSBpbiBwYXJ0aWN1bGFyLCBzb21lIG9mIHRoZSBDIy1zcGVjaWZpYyBvcHRpb25zIG1heSBub3QgYmUgc3VwcG9ydGVkIGluIHRoZSBuZXcKLWNvZGViYXNlLCBhbmQgc29tZSBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUgbWF5IGRpZmZlci4gQSBuZXcgbWFqb3IgdmVyc2lvbiBvZmZlcnMgYW4gb3Bwb3J0dW5pdHkgdG8gc3ByaW5nLWNsZWFuLAotYXMgaXQgd2VyZS4KK1shW0J1aWxkIFN0YXR1c10oaHR0cHM6Ly90cmF2aXMtY2kub3JnL2dvb2dsZS9wcm90b2J1Zi5zdmc/YnJhbmNoPW1hc3RlcildKGh0dHBzOi8vdHJhdmlzLWNpLm9yZy9nb29nbGUvcHJvdG9idWYpCiAKLVRoaXMgcmVwbyBleGlzdHMgYXMgYW4gYWNrbm93bGVkZ2VtZW50IHRoYXQgbm90IGV2ZXJ5b25lIHdpbGwgd2FudCB0byBpbW1lZGlhdGVseSB1c2UgdGhlIG5ld2VyIGNvZGViYXNlLAotYW5kIHRoYXQgdGhleSBtYXkgd2lzaCB0byBtYWtlIGNoYW5nZXMgdG8gdGhlIGxlZ2FjeSBjb2RlYmFzZS4gSSBkbyBub3QgZXhwZWN0IHRvIG1ha2UgYW55IGNoYW5nZXMgd2l0aGluIHRoaXMKLXJlcG8sIGJ1dCBpdCBjYW4gYmUgZm9ya2VkIGZvciBmdXJ0aGVyIGNoYW5nZXMuCitDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLgorCitodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworCitDKysgSW5zdGFsbGF0aW9uIC0gVW5peAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSWYgeW91IGdldCB0aGUgc291cmNlIGZyb20gZ2l0aHViLCB5b3UgbmVlZCB0byBnZW5lcmF0ZSB0aGUgY29uZmlndXJlIHNjcmlwdAorZmlyc3Q6CisKKyAgICAkIC4vYXV0b2dlbi5zaAorCitUaGlzIHdpbGwgZG93bmxvYWQgZ3Rlc3Qgc291cmNlICh3aGljaCBpcyB1c2VkIGZvciBDKysgUHJvdG9jb2wgQnVmZmVyCit1bml0LXRlc3RzKSB0byB0aGUgY3VycmVudCBkaXJlY3RvcnkgYW5kIHJ1biBhdXRvbWFrZSwgYXV0b2NvbmYsIGV0Yy4KK3RvIGdlbmVyYXRlIHRoZSBjb25maWd1cmUgc2NyaXB0IGFuZCB2YXJpb3VzIHRlbXBsYXRlIG1ha2VmaWxlcy4KKworWW91IGNhbiBza2lwIHRoaXMgc3RlcCBpZiB5b3UgYXJlIHVzaW5nIGEgcmVsZWFzZSBwYWNrYWdlICh3aGljaCBhbHJlYWR5Citjb250YWlucyBndGVzdCBhbmQgdGhlIGNvbmZpZ3VyZSBzY3JpcHQpLgorCitUbyBidWlsZCBhbmQgaW5zdGFsbCB0aGUgQysrIFByb3RvY29sIEJ1ZmZlciBydW50aW1lIGFuZCB0aGUgUHJvdG9jb2wKK0J1ZmZlciBjb21waWxlciAocHJvdG9jKSBleGVjdXRlIHRoZSBmb2xsb3dpbmc6CisKKyAgICAkIC4vY29uZmlndXJlCisgICAgJCBtYWtlCisgICAgJCBtYWtlIGNoZWNrCisgICAgJCBtYWtlIGluc3RhbGwKKworSWYgIm1ha2UgY2hlY2siIGZhaWxzLCB5b3UgY2FuIHN0aWxsIGluc3RhbGwsIGJ1dCBpdCBpcyBsaWtlbHkgdGhhdAorc29tZSBmZWF0dXJlcyBvZiB0aGlzIGxpYnJhcnkgd2lsbCBub3Qgd29yayBjb3JyZWN0bHkgb24geW91ciBzeXN0ZW0uCitQcm9jZWVkIGF0IHlvdXIgb3duIHJpc2suCisKKyJtYWtlIGluc3RhbGwiIG1heSByZXF1aXJlIHN1cGVydXNlciBwcml2aWxlZ2VzLgorCitGb3IgYWR2YW5jZWQgdXNhZ2UgaW5mb3JtYXRpb24gb24gY29uZmlndXJlIGFuZCBtYWtlLCBzZWUgSU5TVEFMTC50eHQuCisKKyoqSGludCBvbiBpbnN0YWxsIGxvY2F0aW9uKioKKworICBCeSBkZWZhdWx0LCB0aGUgcGFja2FnZSB3aWxsIGJlIGluc3RhbGxlZCB0byAvdXNyL2xvY2FsLiAgSG93ZXZlciwKKyAgb24gbWFueSBwbGF0Zm9ybXMsIC91c3IvbG9jYWwvbGliIGlzIG5vdCBwYXJ0IG9mIExEX0xJQlJBUllfUEFUSC4KKyAgWW91IGNhbiBhZGQgaXQsIGJ1dCBpdCBtYXkgYmUgZWFzaWVyIHRvIGp1c3QgaW5zdGFsbCB0byAvdXNyCisgIGluc3RlYWQuICBUbyBkbyB0aGlzLCBpbnZva2UgY29uZmlndXJlIGFzIGZvbGxvd3M6CisKKyAgICAuL2NvbmZpZ3VyZSAtLXByZWZpeD0vdXNyCisKKyAgSWYgeW91IGFscmVhZHkgYnVpbHQgdGhlIHBhY2thZ2Ugd2l0aCBhIGRpZmZlcmVudCBwcmVmaXgsIG1ha2Ugc3VyZQorICB0byBydW4gIm1ha2UgY2xlYW4iIGJlZm9yZSBidWlsZGluZyBhZ2Fpbi4KKworKipDb21waWxpbmcgZGVwZW5kZW50IHBhY2thZ2VzKioKKworICBUbyBjb21waWxlIGEgcGFja2FnZSB0aGF0IHVzZXMgUHJvdG9jb2wgQnVmZmVycywgeW91IG5lZWQgdG8gcGFzcworICB2YXJpb3VzIGZsYWdzIHRvIHlvdXIgY29tcGlsZXIgYW5kIGxpbmtlci4gIEFzIG9mIHZlcnNpb24gMi4yLjAsCisgIFByb3RvY29sIEJ1ZmZlcnMgaW50ZWdyYXRlcyB3aXRoIHBrZy1jb25maWcgdG8gbWFuYWdlIHRoaXMuICBJZiB5b3UKKyAgaGF2ZSBwa2ctY29uZmlnIGluc3RhbGxlZCwgdGhlbiB5b3UgY2FuIGludm9rZSBpdCB0byBnZXQgYSBsaXN0IG9mCisgIGZsYWdzIGxpa2Ugc286CisKKyAgICBwa2ctY29uZmlnIC0tY2ZsYWdzIHByb3RvYnVmICAgICAgICAgIyBwcmludCBjb21waWxlciBmbGFncworICAgIHBrZy1jb25maWcgLS1saWJzIHByb3RvYnVmICAgICAgICAgICAjIHByaW50IGxpbmtlciBmbGFncworICAgIHBrZy1jb25maWcgLS1jZmxhZ3MgLS1saWJzIHByb3RvYnVmICAjIHByaW50IGJvdGgKKworICBGb3IgZXhhbXBsZToKKworICAgIGMrKyBteV9wcm9ncmFtLmNjIG15X3Byb3RvLnBiLmNjIGBwa2ctY29uZmlnIC0tY2ZsYWdzIC0tbGlicyBwcm90b2J1ZmAKKworICBOb3RlIHRoYXQgcGFja2FnZXMgd3JpdHRlbiBwcmlvciB0byB0aGUgMi4yLjAgcmVsZWFzZSBvZiBQcm90b2NvbAorICBCdWZmZXJzIG1heSBub3QgeWV0IGludGVncmF0ZSB3aXRoIHBrZy1jb25maWcgdG8gZ2V0IGZsYWdzLCBhbmQgbWF5CisgIG5vdCBwYXNzIHRoZSBjb3JyZWN0IHNldCBvZiBmbGFncyB0byBjb3JyZWN0bHkgbGluayBhZ2FpbnN0CisgIGxpYnByb3RvYnVmLiAgSWYgdGhlIHBhY2thZ2UgaW4gcXVlc3Rpb24gdXNlcyBhdXRvY29uZiwgeW91IGNhbgorICBvZnRlbiBmaXggdGhlIHByb2JsZW0gYnkgaW52b2tpbmcgaXRzIGNvbmZpZ3VyZSBzY3JpcHQgbGlrZToKKworICAgIGNvbmZpZ3VyZSBDWFhGTEFHUz0iJChwa2ctY29uZmlnIC0tY2ZsYWdzIHByb3RvYnVmKSIgXAorICAgICAgICAgICAgICBMSUJTPSIkKHBrZy1jb25maWcgLS1saWJzIHByb3RvYnVmKSIKKworICBUaGlzIHdpbGwgZm9yY2UgaXQgdG8gdXNlIHRoZSBjb3JyZWN0IGZsYWdzLgorCisgIElmIHlvdSBhcmUgd3JpdGluZyBhbiBhdXRvY29uZi1iYXNlZCBwYWNrYWdlIHRoYXQgdXNlcyBQcm90b2NvbAorICBCdWZmZXJzLCB5b3Ugc2hvdWxkIHByb2JhYmx5IHVzZSB0aGUgUEtHX0NIRUNLX01PRFVMRVMgbWFjcm8gaW4geW91cgorICBjb25maWd1cmUgc2NyaXB0IGxpa2U6CisKKyAgICBQS0dfQ0hFQ0tfTU9EVUxFUyhbcHJvdG9idWZdLCBbcHJvdG9idWZdKQorCisgIFNlZSB0aGUgcGtnLWNvbmZpZyBtYW4gcGFnZSBmb3IgbW9yZSBpbmZvLgorCisgIElmIHlvdSBvbmx5IHdhbnQgcHJvdG9idWYtbGl0ZSwgc3Vic3RpdHV0ZSAicHJvdG9idWYtbGl0ZSIgaW4gcGxhY2UKKyAgb2YgInByb3RvYnVmIiBpbiB0aGVzZSBleGFtcGxlcy4KKworKipOb3RlIGZvciBNYWMgdXNlcnMqKgorCisgIEZvciBhIE1hYyBzeXN0ZW0sIFVuaXggdG9vbHMgYXJlIG5vdCBhdmFpbGFibGUgYnkgZGVmYXVsdC4gWW91IHdpbGwgZmlyc3QgbmVlZAorICB0byBpbnN0YWxsIFhjb2RlIGZyb20gdGhlIE1hYyBBcHBTdG9yZSBhbmQgdGhlbiBydW4gdGhlIGZvbGxvd2luZyBjb21tYW5kIGZyb20KKyAgYSB0ZXJtaW5hbDoKKworICAgICQgc3VkbyB4Y29kZS1zZWxlY3QgLS1pbnN0YWxsCisKKyAgVG8gaW5zdGFsbCBVbml4IHRvb2xzLCB5b3UgY2FuIGluc3RhbGwgInBvcnQiIGZvbGxvd2luZyB0aGUgaW5zdHJ1Y3Rpb25zIGF0CisgIGh0dHBzOi8vd3d3Lm1hY3BvcnRzLm9yZyAuIFRoaXMgd2lsbCByZXNpZGUgaW4gL29wdC9sb2NhbC9iaW4vcG9ydCBmb3IgbW9zdAorICBNYWMgaW5zdGFsbGF0aW9ucy4KKworICAgICQgc3VkbyAvb3B0L2xvY2FsL2Jpbi9wb3J0IGluc3RhbGwgYXV0b2NvbmYgYXV0b21ha2UgbGlidG9vbAorCisgIFRoZW4gZm9sbG93IHRoZSBVbml4IGluc3RydWN0aW9ucyBhYm92ZS4KKworKipOb3RlIGZvciBjcm9zcy1jb21waWxpbmcqKgorCisgIFRoZSBtYWtlZmlsZXMgbm9ybWFsbHkgaW52b2tlIHRoZSBwcm90b2MgZXhlY3V0YWJsZSB0aGF0IHRoZXkganVzdAorICBidWlsdCBpbiBvcmRlciB0byBidWlsZCB0ZXN0cy4gIFdoZW4gY3Jvc3MtY29tcGlsaW5nLCB0aGUgcHJvdG9jCisgIGV4ZWN1dGFibGUgbWF5IG5vdCBiZSBleGVjdXRhYmxlIG9uIHRoZSBob3N0IG1hY2hpbmUuICBJbiB0aGlzIGNhc2UsCisgIHlvdSBtdXN0IGJ1aWxkIGEgY29weSBvZiBwcm90b2MgZm9yIHRoZSBob3N0IG1hY2hpbmUgZmlyc3QsIHRoZW4gdXNlCisgIHRoZSAtLXdpdGgtcHJvdG9jIG9wdGlvbiB0byB0ZWxsIGNvbmZpZ3VyZSB0byB1c2UgaXQgaW5zdGVhZC4gIEZvcgorICBleGFtcGxlOgorCisgICAgLi9jb25maWd1cmUgLS13aXRoLXByb3RvYz1wcm90b2MKKworICBUaGlzIHdpbGwgdXNlIHRoZSBpbnN0YWxsZWQgcHJvdG9jIChmb3VuZCBpbiB5b3VyICRQQVRIKSBpbnN0ZWFkIG9mCisgIHRyeWluZyB0byBleGVjdXRlIHRoZSBvbmUgYnVpbHQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLiAgWW91IGNhbgorICBhbHNvIHVzZSBhbiBleGVjdXRhYmxlIHRoYXQgaGFzbid0IGJlZW4gaW5zdGFsbGVkLiAgRm9yIGV4YW1wbGUsIGlmCisgIHlvdSBidWlsdCB0aGUgcHJvdG9idWYgcGFja2FnZSBmb3IgeW91ciBob3N0IG1hY2hpbmUgaW4gLi4vaG9zdCwKKyAgeW91IG1pZ2h0IGRvOgorCisgICAgLi9jb25maWd1cmUgLS13aXRoLXByb3RvYz0uLi9ob3N0L3NyYy9wcm90b2MKKworICBFaXRoZXIgd2F5LCB5b3UgbXVzdCBtYWtlIHN1cmUgdGhhdCB0aGUgcHJvdG9jIGV4ZWN1dGFibGUgeW91IHVzZQorICBoYXMgdGhlIHNhbWUgdmVyc2lvbiBhcyB0aGUgcHJvdG9idWYgc291cmNlIGNvZGUgeW91IGFyZSB0cnlpbmcgdG8KKyAgdXNlIGl0IHdpdGguCisKKyoqTm90ZSBmb3IgU29sYXJpcyB1c2VycyoqCisKKyAgU29sYXJpcyAxMCB4ODYgaGFzIGEgYnVnIHRoYXQgd2lsbCBtYWtlIGxpbmtpbmcgZmFpbCwgY29tcGxhaW5pbmcKKyAgYWJvdXQgbGlic3RkYysrLmxhIGJlaW5nIGludmFsaWQuICBXZSBoYXZlIGluY2x1ZGVkIGEgd29yay1hcm91bmQKKyAgaW4gdGhpcyBwYWNrYWdlLiAgVG8gdXNlIHRoZSB3b3JrLWFyb3VuZCwgcnVuIGNvbmZpZ3VyZSBhcyBmb2xsb3dzOgorCisgICAgLi9jb25maWd1cmUgTERGTEFHUz0tTCRQV0Qvc3JjL3NvbGFyaXMKKworICBTZWUgc3JjL3NvbGFyaXMvbGlic3RkYysrLmxhIGZvciBtb3JlIGluZm8gb24gdGhpcyBidWcuCisKKyoqTm90ZSBmb3IgSFAgQysrIFRydTY0IHVzZXJzKioKKworICBUbyBjb21waWxlIGludm9rZSBjb25maWd1cmUgYXMgZm9sbG93czoKKworICAgIC4vY29uZmlndXJlIENYWEZMQUdTPSItTyAtc3RkIGFuc2kgLWllZWUgLURfX1VTRV9TVERfSU9TVFJFQU0iCisKKyAgQWxzbywgeW91IHdpbGwgbmVlZCB0byB1c2UgZ21ha2UgaW5zdGVhZCBvZiBtYWtlLgorCisqKk5vdGUgZm9yIEFJWCB1c2VycyoqCisKKyAgQ29tcGlsZSB1c2luZyB0aGUgSUJNIHhsQyBDKysgY29tcGlsZXIgYXMgZm9sbG93czoKKworICAgIC4vY29uZmlndXJlIENYWD14bEMKKworICBBbHNvLCB5b3Ugd2lsbCBuZWVkIHRvIHVzZSBHTlUgYG1ha2VgIChgZ21ha2VgKSBpbnN0ZWFkIG9mIEFJWCBgbWFrZWAuCisKK0MrKyBJbnN0YWxsYXRpb24gLSBXaW5kb3dzCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitJZiB5b3UgYXJlIHVzaW5nIE1pY3Jvc29mdCBWaXN1YWwgQysrLCBzZWUgdnNwcm9qZWN0cy9yZWFkbWUudHh0LgorCitJZiB5b3UgYXJlIHVzaW5nIEN5Z3dpbiBvciBNaW5HVywgZm9sbG93IHRoZSBVbml4IGluc3RhbGxhdGlvbgoraW5zdHJ1Y3Rpb25zLCBhYm92ZS4KKworQmluYXJ5IENvbXBhdGliaWxpdHkgV2FybmluZworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitEdWUgdG8gdGhlIG5hdHVyZSBvZiBDKyssIGl0IGlzIHVubGlrZWx5IHRoYXQgYW55IHR3byB2ZXJzaW9ucyBvZiB0aGUKK1Byb3RvY29sIEJ1ZmZlcnMgQysrIHJ1bnRpbWUgbGlicmFyaWVzIHdpbGwgaGF2ZSBjb21wYXRpYmxlIEFCSXMuCitUaGF0IGlzLCBpZiB5b3UgbGlua2VkIGFuIGV4ZWN1dGFibGUgYWdhaW5zdCBhbiBvbGRlciB2ZXJzaW9uIG9mCitsaWJwcm90b2J1ZiwgaXQgaXMgdW5saWtlbHkgdG8gd29yayB3aXRoIGEgbmV3ZXIgdmVyc2lvbiB3aXRob3V0CityZS1jb21waWxpbmcuICBUaGlzIHByb2JsZW0sIHdoZW4gaXQgb2NjdXJzLCB3aWxsIG5vcm1hbGx5IGJlIGRldGVjdGVkCitpbW1lZGlhdGVseSBvbiBzdGFydHVwIG9mIHlvdXIgYXBwLiAgU3RpbGwsIHlvdSBtYXkgd2FudCB0byBjb25zaWRlcgordXNpbmcgc3RhdGljIGxpbmthZ2UuICBZb3UgY2FuIGNvbmZpZ3VyZSB0aGlzIHBhY2thZ2UgdG8gaW5zdGFsbAorc3RhdGljIGxpYnJhcmllcyBvbmx5IHVzaW5nOgorCisgICAgLi9jb25maWd1cmUgLS1kaXNhYmxlLXNoYXJlZAorCitKYXZhIGFuZCBQeXRob24gSW5zdGFsbGF0aW9uCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBKYXZhIGFuZCBQeXRob24gcnVudGltZSBsaWJyYXJpZXMgZm9yIFByb3RvY29sIEJ1ZmZlcnMgYXJlIGxvY2F0ZWQKK2luIHRoZSBqYXZhIGFuZCBweXRob24gZGlyZWN0b3JpZXMuICBTZWUgdGhlIFJFQURNRSBmaWxlIGluIGVhY2gKK2RpcmVjdG9yeSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBob3cgdG8gY29tcGlsZSBhbmQgaW5zdGFsbCB0aGVtLgorTm90ZSB0aGF0IGJvdGggb2YgdGhlbSByZXF1aXJlIHlvdSB0byBmaXJzdCBpbnN0YWxsIHRoZSBQcm90b2NvbAorQnVmZmVyIGNvbXBpbGVyIChwcm90b2MpLCB3aGljaCBpcyBwYXJ0IG9mIHRoZSBDKysgcGFja2FnZS4KKworVXNhZ2UKKy0tLS0tCisKK1RoZSBjb21wbGV0ZSBkb2N1bWVudGF0aW9uIGZvciBQcm90b2NvbCBCdWZmZXJzIGlzIGF2YWlsYWJsZSB2aWEgdGhlCit3ZWIgYXQ6CisKKyAgICBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLwpkaWZmIC0tZ2l0IGEvYXV0b2dlbi5zaCBiL2F1dG9nZW4uc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDg5NjZjNgotLS0gL2Rldi9udWxsCisrKyBiL2F1dG9nZW4uc2gKQEAgLTAsMCArMSw0MyBAQAorIyEvYmluL3NoCisKKyMgUnVuIHRoaXMgc2NyaXB0IHRvIGdlbmVyYXRlIHRoZSBjb25maWd1cmUgc2NyaXB0IGFuZCBvdGhlciBmaWxlcyB0aGF0IHdpbGwKKyMgYmUgaW5jbHVkZWQgaW4gdGhlIGRpc3RyaWJ1dGlvbi4gIFRoZXNlIGZpbGVzIGFyZSBub3QgY2hlY2tlZCBpbiBiZWNhdXNlIHRoZXkKKyMgYXJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkLgorCitzZXQgLWUKKworIyBDaGVjayB0aGF0IHdlJ3JlIGJlaW5nIHJ1biBmcm9tIHRoZSByaWdodCBkaXJlY3RvcnkuCitpZiB0ZXN0ICEgLWYgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaDsgdGhlbgorICBjYXQgPiYyIDw8IF9fRU9GX18KK0NvdWxkIG5vdCBmaW5kIHNvdXJjZSBjb2RlLiAgTWFrZSBzdXJlIHlvdSBhcmUgcnVubmluZyB0aGlzIHNjcmlwdCBmcm9tIHRoZQorcm9vdCBvZiB0aGUgZGlzdHJpYnV0aW9uIHRyZWUuCitfX0VPRl9fCisgIGV4aXQgMQorZmkKKworIyBDaGVjayB0aGF0IGd0ZXN0IGlzIHByZXNlbnQuICBVc3VhbGx5IGl0IGlzIGFscmVhZHkgdGhlcmUgc2luY2UgdGhlCisjIGRpcmVjdG9yeSBpcyBzZXQgdXAgYXMgYW4gU1ZOIGV4dGVybmFsLgoraWYgdGVzdCAhIC1lIGd0ZXN0OyB0aGVuCisgIGVjaG8gIkdvb2dsZSBUZXN0IG5vdCBwcmVzZW50LiAgRmV0Y2hpbmcgZ3Rlc3QtMS43LjAgZnJvbSB0aGUgd2ViLi4uIgorICBjdXJsIC1PIGh0dHBzOi8vZ29vZ2xldGVzdC5nb29nbGVjb2RlLmNvbS9maWxlcy9ndGVzdC0xLjcuMC56aXAKKyAgdW56aXAgLXEgZ3Rlc3QtMS43LjAuemlwCisgIHJtIGd0ZXN0LTEuNy4wLnppcAorICBtdiBndGVzdC0xLjcuMCBndGVzdAorZmkKKworc2V0IC1leAorCisjIFRlbXBvcmFyeSBoYWNrOiAgTXVzdCBjaGFuZ2UgQyBydW50aW1lIGxpYnJhcnkgdG8gIm11bHRpLXRocmVhZGVkIERMTCIsCisjICAgb3RoZXJ3aXNlIGl0IHdpbGwgYmUgc2V0IHRvICJtdWx0aS10aHJlYWRlZCBzdGF0aWMiIHdoZW4gTVNWQyB1cGdyYWRlcworIyAgIHRoZSBwcm9qZWN0IGZpbGUgdG8gTVNWQyAyMDA1LzIwMDguICB2bGFkbCBvZiBHb29nbGUgVGVzdCBzYXlzIGd0ZXN0IHdpbGwKKyMgICBwcm9iYWJseSBjaGFuZ2UgdGhlaXIgZGVmYXVsdCB0byBtYXRjaCwgdGhlbiB0aGlzIHdpbGwgYmUgdW5uZWNlc3NhcnkuCisjICAgT25lIG9mIHRoZXNlIG1hcHBpbmdzIGNvbnZlcnRzIHRoZSBkZWJ1ZyBjb25maWd1cmF0aW9uIGFuZCB0aGUgb3RoZXIKKyMgICBjb252ZXJ0cyB0aGUgcmVsZWFzZSBjb25maWd1cmF0aW9uLiAgSSBkb24ndCBrbm93IHdoaWNoIGlzIHdoaWNoLgorc2VkIC1pIC1lICdzL1J1bnRpbWVMaWJyYXJ5PSI1Ii9SdW50aW1lTGlicmFyeT0iMyIvZzsKKyAgICAgICAgICAgcy9SdW50aW1lTGlicmFyeT0iNCIvUnVudGltZUxpYnJhcnk9IjIiL2c7JyBndGVzdC9tc3ZjLyoudmNwcm9qCisKKyMgVE9ETyhrZW50b24pOiAgUmVtb3ZlIHRoZSAiLG5vLW9ic29sZXRlIiBwYXJ0IGFuZCBmaXggdGhlIHJlc3VsdGluZyB3YXJuaW5ncy4KK2F1dG9yZWNvbmYgLWYgLWkgLVdhbGwsbm8tb2Jzb2xldGUKKworcm0gLXJmIGF1dG9tNHRlLmNhY2hlIGNvbmZpZy5oLmlufgorZXhpdCAwCmRpZmYgLS1naXQgYS9iZW5jaG1hcmtzL1Byb3RvQmVuY2guamF2YSBiL2JlbmNobWFya3MvUHJvdG9CZW5jaC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2ZDYyZmUKLS0tIC9kZXYvbnVsbAorKysgYi9iZW5jaG1hcmtzL1Byb3RvQmVuY2guamF2YQpAQCAtMCwwICsxLDIwMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOSBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2NvbGJ1ZmZlcnM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZTsKKworcHVibGljIGNsYXNzIFByb3RvQmVuY2ggeworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBNSU5fU0FNUExFX1RJTUVfTVMgPSAyICogMTAwMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBUQVJHRVRfVElNRV9NUyA9IDMwICogMTAwMDsKKworICBwcml2YXRlIFByb3RvQmVuY2goKSB7CisgICAgLy8gUHJldmVudCBpbnN0YW50aWF0aW9uCisgIH0KKyAgCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICBpZiAoYXJncy5sZW5ndGggPCAyIHx8IChhcmdzLmxlbmd0aCAlIDIpICE9IDApIHsKKyAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6IFByb3RvQmVuY2ggPGRlc2NyaXB0b3IgdHlwZSBuYW1lPiA8aW5wdXQgZGF0YT4iKTsKKyAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVGhlIGRlc2NyaXB0b3IgdHlwZSBuYW1lIGlzIHRoZSBmdWxseS1xdWFsaWZpZWQgbWVzc2FnZSBuYW1lLCIpOworICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJlLmcuIGNvbS5nb29nbGUucHJvdG9jb2xidWZmZXJzLmJlbmNobWFyay5NZXNzYWdlMSIpOworICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIoWW91IGNhbiBzcGVjaWZ5IG11bHRpcGxlIHBhaXJzIG9mIGRlc2NyaXB0b3IgdHlwZSBuYW1lIGFuZCBpbnB1dCBkYXRhLikiKTsKKyAgICAgIFN5c3RlbS5leGl0KDEpOworICAgIH0KKyAgICBib29sZWFuIHN1Y2Nlc3MgPSB0cnVlOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkgKz0gMikgeworICAgICAgc3VjY2VzcyAmPSBydW5UZXN0KGFyZ3NbaV0sIGFyZ3NbaSArIDFdKTsKKyAgICB9CisgICAgU3lzdGVtLmV4aXQoc3VjY2VzcyA/IDAgOiAxKTsKKyAgfQorCisgIC8qKgorICAgKiBSdW5zIGEgc2luZ2xlIHRlc3QuIEVycm9yIG1lc3NhZ2VzIGFyZSBkaXNwbGF5ZWQgdG8gc3RkZXJyLCBhbmQgdGhlIHJldHVybiB2YWx1ZQorICAgKiBpbmRpY2F0ZXMgZ2VuZXJhbCBzdWNjZXNzL2ZhaWx1cmUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuVGVzdChTdHJpbmcgdHlwZSwgU3RyaW5nIGZpbGUpIHsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkJlbmNobWFya2luZyAiICsgdHlwZSArICIgd2l0aCBmaWxlICIgKyBmaWxlKTsKKyAgICBmaW5hbCBNZXNzYWdlIGRlZmF1bHRNZXNzYWdlOworICAgIHRyeSB7CisgICAgICBDbGFzczw/PiBjbGF6eiA9IENsYXNzLmZvck5hbWUodHlwZSk7CisgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoImdldERlZmF1bHRJbnN0YW5jZSIpOworICAgICAgZGVmYXVsdE1lc3NhZ2UgPSAoTWVzc2FnZSkgbWV0aG9kLmludm9rZShudWxsKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2Ugd2FudCB0byBkbyB0aGUgc2FtZSB0aGluZyB3aXRoIGFsbCBleGNlcHRpb25zLiBOb3QgZ2VuZXJhbGx5IG5pY2UsCisgICAgICAvLyBidXQgdGhpcyBpcyBzbGlnaHRseSBkaWZmZXJlbnQuCisgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlVuYWJsZSB0byBnZXQgZGVmYXVsdCBtZXNzYWdlIGZvciAiICsgdHlwZSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIAorICAgIHRyeSB7CisgICAgICBmaW5hbCBieXRlW10gaW5wdXREYXRhID0gcmVhZEFsbEJ5dGVzKGZpbGUpOworICAgICAgZmluYWwgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXREYXRhKTsKKyAgICAgIGZpbmFsIEJ5dGVTdHJpbmcgaW5wdXRTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGlucHV0RGF0YSk7CisgICAgICBmaW5hbCBNZXNzYWdlIHNhbXBsZU1lc3NhZ2UgPSBkZWZhdWx0TWVzc2FnZS5uZXdCdWlsZGVyRm9yVHlwZSgpLm1lcmdlRnJvbShpbnB1dFN0cmluZykuYnVpbGQoKTsKKyAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZGV2TnVsbFRlbXAgPSBudWxsOworICAgICAgQ29kZWRPdXRwdXRTdHJlYW0gcmV1c2VEZXZOdWxsVGVtcCA9IG51bGw7CisgICAgICB0cnkgeworICAgICAgICBkZXZOdWxsVGVtcCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKCIvZGV2L251bGwiKTsKKyAgICAgICAgcmV1c2VEZXZOdWxsVGVtcCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKGRldk51bGxUZW1wKTsKKyAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGlnbm9yZTogdGhpcyBpcyBwcm9iYWJseSBXaW5kb3dzLCB3aGVyZSAvZGV2L251bGwgZG9lcyBub3QgZXhpc3QKKyAgICAgIH0KKyAgICAgIGZpbmFsIEZpbGVPdXRwdXRTdHJlYW0gZGV2TnVsbCA9IGRldk51bGxUZW1wOworICAgICAgZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gcmV1c2VEZXZOdWxsID0gcmV1c2VEZXZOdWxsVGVtcDsKKyAgICAgIGJlbmNobWFyaygiU2VyaWFsaXplIHRvIGJ5dGUgc3RyaW5nIiwgaW5wdXREYXRhLmxlbmd0aCwgbmV3IEFjdGlvbigpIHsKKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHsgc2FtcGxlTWVzc2FnZS50b0J5dGVTdHJpbmcoKTsgfQorICAgICAgfSk7ICAgICAgCisgICAgICBiZW5jaG1hcmsoIlNlcmlhbGl6ZSB0byBieXRlIGFycmF5IiwgaW5wdXREYXRhLmxlbmd0aCwgbmV3IEFjdGlvbigpIHsKKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHsgc2FtcGxlTWVzc2FnZS50b0J5dGVBcnJheSgpOyB9CisgICAgICB9KTsKKyAgICAgIGJlbmNobWFyaygiU2VyaWFsaXplIHRvIG1lbW9yeSBzdHJlYW0iLCBpbnB1dERhdGEubGVuZ3RoLCBuZXcgQWN0aW9uKCkgeworICAgICAgICBwdWJsaWMgdm9pZCBleGVjdXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsgCisgICAgICAgICAgc2FtcGxlTWVzc2FnZS53cml0ZVRvKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7IAorICAgICAgICB9CisgICAgICB9KTsKKyAgICAgIGlmIChkZXZOdWxsICE9IG51bGwpIHsKKyAgICAgICAgYmVuY2htYXJrKCJTZXJpYWxpemUgdG8gL2Rldi9udWxsIHdpdGggRmlsZU91dHB1dFN0cmVhbSIsIGlucHV0RGF0YS5sZW5ndGgsIG5ldyBBY3Rpb24oKSB7CisgICAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzYW1wbGVNZXNzYWdlLndyaXRlVG8oZGV2TnVsbCk7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgYmVuY2htYXJrKCJTZXJpYWxpemUgdG8gL2Rldi9udWxsIHJldXNpbmcgRmlsZU91dHB1dFN0cmVhbSIsIGlucHV0RGF0YS5sZW5ndGgsIG5ldyBBY3Rpb24oKSB7CisgICAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzYW1wbGVNZXNzYWdlLndyaXRlVG8ocmV1c2VEZXZOdWxsKTsKKyAgICAgICAgICAgIHJldXNlRGV2TnVsbC5mbHVzaCgpOyAgLy8gZm9yY2UgdGhlIHdyaXRlIHRvIHRoZSBPdXRwdXRTdHJlYW0KKyAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgfQorICAgICAgYmVuY2htYXJrKCJEZXNlcmlhbGl6ZSBmcm9tIGJ5dGUgc3RyaW5nIiwgaW5wdXREYXRhLmxlbmd0aCwgbmV3IEFjdGlvbigpIHsKKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IAorICAgICAgICAgIGRlZmF1bHRNZXNzYWdlLm5ld0J1aWxkZXJGb3JUeXBlKCkubWVyZ2VGcm9tKGlucHV0U3RyaW5nKS5idWlsZCgpOworICAgICAgICB9CisgICAgICB9KTsKKyAgICAgIGJlbmNobWFyaygiRGVzZXJpYWxpemUgZnJvbSBieXRlIGFycmF5IiwgaW5wdXREYXRhLmxlbmd0aCwgbmV3IEFjdGlvbigpIHsKKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IAorICAgICAgICAgIGRlZmF1bHRNZXNzYWdlLm5ld0J1aWxkZXJGb3JUeXBlKCkKKyAgICAgICAgICAgIC5tZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShpbnB1dERhdGEpKS5idWlsZCgpOworICAgICAgICB9CisgICAgICB9KTsKKyAgICAgIGJlbmNobWFyaygiRGVzZXJpYWxpemUgZnJvbSBtZW1vcnkgc3RyZWFtIiwgaW5wdXREYXRhLmxlbmd0aCwgbmV3IEFjdGlvbigpIHsKKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IAorICAgICAgICAgIGRlZmF1bHRNZXNzYWdlLm5ld0J1aWxkZXJGb3JUeXBlKCkKKyAgICAgICAgICAgIC5tZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShpbnB1dFN0cmVhbSkpLmJ1aWxkKCk7CisgICAgICAgICAgaW5wdXRTdHJlYW0ucmVzZXQoKTsKKyAgICAgICAgfQorICAgICAgfSk7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJEZXRhaWxlZCBleGNlcHRpb24gaW5mb3JtYXRpb246Iik7CisgICAgICBlLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgCisgIHByaXZhdGUgc3RhdGljIHZvaWQgYmVuY2htYXJrKFN0cmluZyBuYW1lLCBsb25nIGRhdGFTaXplLCBBY3Rpb24gYWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIE1ha2Ugc3VyZSBpdCdzIEpJVHRlZCAicmVhc29uYWJseSIgaGFyZCBiZWZvcmUgcnVubmluZyB0aGUgZmlyc3QgcHJvZ3Jlc3MgdGVzdAorICAgIGZvciAoaW50IGk9MDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICBhY3Rpb24uZXhlY3V0ZSgpOworICAgIH0KKyAgICAKKyAgICAvLyBSdW4gaXQgcHJvZ3Jlc3NpdmVseSBtb3JlIHRpbWVzIHVudGlsIHdlJ3ZlIGdvdCBhIHJlYXNvbmFibGUgc2FtcGxlCisgICAgaW50IGl0ZXJhdGlvbnMgPSAxOworICAgIGxvbmcgZWxhcHNlZCA9IHRpbWVBY3Rpb24oYWN0aW9uLCBpdGVyYXRpb25zKTsKKyAgICB3aGlsZSAoZWxhcHNlZCA8IE1JTl9TQU1QTEVfVElNRV9NUykgeworICAgICAgaXRlcmF0aW9ucyAqPSAyOworICAgICAgZWxhcHNlZCA9IHRpbWVBY3Rpb24oYWN0aW9uLCBpdGVyYXRpb25zKTsKKyAgICB9CisgICAgCisgICAgLy8gVXBzY2FsZSB0aGUgc2FtcGxlIHRvIHRoZSB0YXJnZXQgdGltZS4gRG8gdGhpcyBpbiBmbG9hdGluZyBwb2ludCBhcml0aG1ldGljCisgICAgLy8gdG8gYXZvaWQgb3ZlcmZsb3cgaXNzdWVzLgorICAgIGl0ZXJhdGlvbnMgPSAoaW50KSAoKFRBUkdFVF9USU1FX01TIC8gKGRvdWJsZSkgZWxhcHNlZCkgKiBpdGVyYXRpb25zKTsKKyAgICBlbGFwc2VkID0gdGltZUFjdGlvbihhY3Rpb24sIGl0ZXJhdGlvbnMpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbihuYW1lICsgIjogIiArIGl0ZXJhdGlvbnMgKyAiIGl0ZXJhdGlvbnMgaW4gIgorICAgICAgICAgKyAoZWxhcHNlZC8xMDAwZikgKyAiczsgIiAKKyAgICAgICAgICsgKGl0ZXJhdGlvbnMgKiBkYXRhU2l6ZSkgLyAoZWxhcHNlZCAqIDEwMjQgKiAxMDI0IC8gMTAwMGYpIAorICAgICAgICAgKyAiTUIvcyIpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBsb25nIHRpbWVBY3Rpb24oQWN0aW9uIGFjdGlvbiwgaW50IGl0ZXJhdGlvbnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU3lzdGVtLmdjKCk7ICAgIAorICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgeworICAgICAgYWN0aW9uLmV4ZWN1dGUoKTsKKyAgICB9CisgICAgbG9uZyBlbmQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICByZXR1cm4gZW5kIC0gc3RhcnQ7CisgIH0KKyAgCisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSByZWFkQWxsQnl0ZXMoU3RyaW5nIGZpbGVuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFJhbmRvbUFjY2Vzc0ZpbGUgZmlsZSA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKG5ldyBGaWxlKGZpbGVuYW1lKSwgInIiKTsKKyAgICBieXRlW10gY29udGVudCA9IG5ldyBieXRlWyhpbnQpIGZpbGUubGVuZ3RoKCldOworICAgIGZpbGUucmVhZEZ1bGx5KGNvbnRlbnQpOworICAgIHJldHVybiBjb250ZW50OworICB9CisKKyAgLyoqCisgICAqIEludGVyZmFjZSB1c2VkIHRvIGNhcHR1cmUgYSBzaW5nbGUgYWN0aW9uIHRvIGJlbmNobWFyay4KKyAgICovCisgIGludGVyZmFjZSBBY3Rpb24geworICAgIHZvaWQgZXhlY3V0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvZ29vZ2xlX21lc3NhZ2UxLmRhdCBiL2JlbmNobWFya3MvZ29vZ2xlX21lc3NhZ2UxLmRhdApzaW1pbGFyaXR5IGluZGV4IDEwMCUKY29weSBmcm9tIHNyYy9Qcm90b0JlbmNoL2dvb2dsZV9tZXNzYWdlMS5kYXQKY29weSB0byBiZW5jaG1hcmtzL2dvb2dsZV9tZXNzYWdlMS5kYXQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvZ29vZ2xlX21lc3NhZ2UyLmRhdCBiL2JlbmNobWFya3MvZ29vZ2xlX21lc3NhZ2UyLmRhdApzaW1pbGFyaXR5IGluZGV4IDEwMCUKY29weSBmcm9tIHNyYy9Qcm90b0JlbmNoL2dvb2dsZV9tZXNzYWdlMi5kYXQKY29weSB0byBiZW5jaG1hcmtzL2dvb2dsZV9tZXNzYWdlMi5kYXQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvYmVuY2htYXJrcy9nb29nbGVfc2l6ZS5wcm90byBiL2JlbmNobWFya3MvZ29vZ2xlX3NpemUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U2ZmJkYgotLS0gL2Rldi9udWxsCisrKyBiL2JlbmNobWFya3MvZ29vZ2xlX3NpemUucHJvdG8KQEAgLTAsMCArMSwxMzYgQEAKK3BhY2thZ2UgYmVuY2htYXJrczsKKworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIkdvb2dsZVNpemUiOworb3B0aW9uIG9wdGltaXplX2ZvciA9IENPREVfU0laRTsKKworbWVzc2FnZSBTaXplTWVzc2FnZTEgeworICByZXF1aXJlZCBzdHJpbmcgZmllbGQxID0gMTsKKyAgb3B0aW9uYWwgc3RyaW5nIGZpZWxkOSA9IDk7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDE4ID0gMTg7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ4MCA9IDgwIFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDgxID0gODEgW2RlZmF1bHQ9dHJ1ZV07CisgIHJlcXVpcmVkIGludDMyIGZpZWxkMiA9IDI7CisgIHJlcXVpcmVkIGludDMyIGZpZWxkMyA9IDM7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjgwID0gMjgwOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDYgPSA2IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDIyID0gMjI7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDQgPSA0OworICByZXBlYXRlZCBmaXhlZDY0IGZpZWxkNSA9IDU7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ1OSA9IDU5IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGZpZWxkNyA9IDc7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTYgPSAxNjsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxMzAgPSAxMzAgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQxMiA9IDEyIFtkZWZhdWx0PXRydWVdOworICBvcHRpb25hbCBib29sIGZpZWxkMTcgPSAxNyBbZGVmYXVsdD10cnVlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDEzID0gMTMgW2RlZmF1bHQ9dHJ1ZV07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQxNCA9IDE0IFtkZWZhdWx0PXRydWVdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDEwNCA9IDEwNCBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxMDAgPSAxMDAgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTAxID0gMTAxIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBzdHJpbmcgZmllbGQxMDIgPSAxMDI7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEwMyA9IDEwMzsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyOSA9IDI5IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBib29sIGZpZWxkMzAgPSAzMCBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkNjAgPSA2MCBbZGVmYXVsdD0tMV07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjcxID0gMjcxIFtkZWZhdWx0PS0xXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyNzIgPSAyNzIgW2RlZmF1bHQ9LTFdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDE1MCA9IDE1MDsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMyA9IDIzIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBib29sIGZpZWxkMjQgPSAyNCBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjUgPSAyNSBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgU2l6ZU1lc3NhZ2UxU3ViTWVzc2FnZSBmaWVsZDE1ID0gMTU7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ3OCA9IDc4OworICBvcHRpb25hbCBpbnQzMiBmaWVsZDY3ID0gNjcgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkNjggPSA2ODsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxMjggPSAxMjggW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEyOSA9IDEyOSBbZGVmYXVsdD0ieHh4eHh4eHh4eHh4eHh4eHh4eHh4Il07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTMxID0gMTMxIFtkZWZhdWx0PTBdOworfQorCittZXNzYWdlIFNpemVNZXNzYWdlMVN1Yk1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIgPSAyIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDMgPSAzIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBzdHJpbmcgZmllbGQxNSA9IDE1OworICBvcHRpb25hbCBib29sIGZpZWxkMTIgPSAxMiBbZGVmYXVsdD10cnVlXTsKKyAgb3B0aW9uYWwgaW50NjQgZmllbGQxMyA9IDEzOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDE0ID0gMTQ7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTYgPSAxNjsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxOSA9IDE5IFtkZWZhdWx0PTJdOworICBvcHRpb25hbCBib29sIGZpZWxkMjAgID0gMjAgW2RlZmF1bHQ9dHJ1ZV07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQyOCA9IDI4IFtkZWZhdWx0PXRydWVdOworICBvcHRpb25hbCBmaXhlZDY0IGZpZWxkMjEgPSAyMTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMiA9IDIyOworICBvcHRpb25hbCBib29sIGZpZWxkMjMgPSAyMyBbIGRlZmF1bHQ9ZmFsc2UgXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDIwNiA9IDIwNiBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGZpeGVkMzIgZmllbGQyMDMgPSAyMDM7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjA0ID0gMjA0OworICBvcHRpb25hbCBzdHJpbmcgZmllbGQyMDUgPSAyMDU7CisgIG9wdGlvbmFsIHVpbnQ2NCBmaWVsZDIwNyA9IDIwNzsKKyAgb3B0aW9uYWwgdWludDY0IGZpZWxkMzAwID0gMzAwOworfQorCittZXNzYWdlIFNpemVNZXNzYWdlMiB7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDMgPSAzOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDQgPSA0OworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDMwID0gMzA7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ3NSAgPSA3NSBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDYgPSA2OworICBvcHRpb25hbCBieXRlcyBmaWVsZDIgPSAyOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIxID0gMjEgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkNzEgPSA3MTsKKyAgb3B0aW9uYWwgZmxvYXQgZmllbGQyNSA9IDI1OworICBvcHRpb25hbCBpbnQzMiBmaWVsZDEwOSA9IDEwOSBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMTAgPSAyMTAgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjExID0gMjExIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIxMiA9IDIxMiBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMTMgPSAyMTMgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjE2ID0gMjE2IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIxNyA9IDIxNyBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMTggPSAyMTggW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjIwID0gMjIwIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIyMSA9IDIyMSBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgZmxvYXQgZmllbGQyMjIgPSAyMjIgW2RlZmF1bHQ9MC4wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQ2MyA9IDYzOworCisgIHJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsKKyAgICByZXF1aXJlZCBmbG9hdCBmaWVsZDExID0gMTE7CisgICAgb3B0aW9uYWwgZmxvYXQgZmllbGQyNiA9IDI2OworICAgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEyID0gMTI7CisgICAgb3B0aW9uYWwgc3RyaW5nIGZpZWxkMTMgPSAxMzsKKyAgICByZXBlYXRlZCBzdHJpbmcgZmllbGQxNCA9IDE0OworICAgIHJlcXVpcmVkIHVpbnQ2NCBmaWVsZDE1ID0gMTU7CisgICAgb3B0aW9uYWwgaW50MzIgZmllbGQ1ID0gNTsKKyAgICBvcHRpb25hbCBzdHJpbmcgZmllbGQyNyA9IDI3OworICAgIG9wdGlvbmFsIGludDMyIGZpZWxkMjggPSAyODsKKyAgICBvcHRpb25hbCBzdHJpbmcgZmllbGQyOSA9IDI5OworICAgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDE2ID0gMTY7CisgICAgcmVwZWF0ZWQgc3RyaW5nIGZpZWxkMjIgPSAyMjsKKyAgICByZXBlYXRlZCBpbnQzMiBmaWVsZDczID0gNzM7CisgICAgb3B0aW9uYWwgaW50MzIgZmllbGQyMCA9IDIwIFtkZWZhdWx0PTBdOworICAgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDI0ID0gMjQ7CisgICAgb3B0aW9uYWwgU2l6ZU1lc3NhZ2UyR3JvdXBlZE1lc3NhZ2UgZmllbGQzMSA9IDMxOworICB9CisgIHJlcGVhdGVkIHN0cmluZyBmaWVsZDEyOCA9IDEyODsKKyAgb3B0aW9uYWwgaW50NjQgZmllbGQxMzEgPSAxMzE7CisgIHJlcGVhdGVkIHN0cmluZyBmaWVsZDEyNyA9IDEyNzsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxMjkgPSAxMjk7CisgIHJlcGVhdGVkIGludDY0IGZpZWxkMTMwID0gMTMwOworICBvcHRpb25hbCBib29sIGZpZWxkMjA1ID0gMjA1IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDIwNiA9IDIwNiBbZGVmYXVsdD1mYWxzZV07Cit9CisKK21lc3NhZ2UgU2l6ZU1lc3NhZ2UyR3JvdXBlZE1lc3NhZ2UgeworICBvcHRpb25hbCBmbG9hdCBmaWVsZDEgPSAxOworICBvcHRpb25hbCBmbG9hdCBmaWVsZDIgPSAyOworICBvcHRpb25hbCBmbG9hdCBmaWVsZDMgPSAzIFtkZWZhdWx0PTAuMF07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ0ID0gNDsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDUgPSA1OworICBvcHRpb25hbCBib29sIGZpZWxkNiA9IDYgW2RlZmF1bHQ9dHJ1ZV07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ3ID0gNyBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGZsb2F0IGZpZWxkOCA9IDg7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ5ID0gOTsKKyAgb3B0aW9uYWwgZmxvYXQgZmllbGQxMCA9IDEwOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDExID0gMTE7Cit9CmRpZmYgLS1naXQgYS9iZW5jaG1hcmtzL2dvb2dsZV9zcGVlZC5wcm90byBiL2JlbmNobWFya3MvZ29vZ2xlX3NwZWVkLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2Y2QwMzIKLS0tIC9kZXYvbnVsbAorKysgYi9iZW5jaG1hcmtzL2dvb2dsZV9zcGVlZC5wcm90bwpAQCAtMCwwICsxLDEzNiBAQAorcGFja2FnZSBiZW5jaG1hcmtzOworCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiR29vZ2xlU3BlZWQiOworb3B0aW9uIG9wdGltaXplX2ZvciA9IFNQRUVEOworCittZXNzYWdlIFNwZWVkTWVzc2FnZTEgeworICByZXF1aXJlZCBzdHJpbmcgZmllbGQxID0gMTsKKyAgb3B0aW9uYWwgc3RyaW5nIGZpZWxkOSA9IDk7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDE4ID0gMTg7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ4MCA9IDgwIFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDgxID0gODEgW2RlZmF1bHQ9dHJ1ZV07CisgIHJlcXVpcmVkIGludDMyIGZpZWxkMiA9IDI7CisgIHJlcXVpcmVkIGludDMyIGZpZWxkMyA9IDM7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjgwID0gMjgwOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDYgPSA2IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDIyID0gMjI7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDQgPSA0OworICByZXBlYXRlZCBmaXhlZDY0IGZpZWxkNSA9IDU7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ1OSA9IDU5IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGZpZWxkNyA9IDc7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTYgPSAxNjsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxMzAgPSAxMzAgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQxMiA9IDEyIFtkZWZhdWx0PXRydWVdOworICBvcHRpb25hbCBib29sIGZpZWxkMTcgPSAxNyBbZGVmYXVsdD10cnVlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDEzID0gMTMgW2RlZmF1bHQ9dHJ1ZV07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQxNCA9IDE0IFtkZWZhdWx0PXRydWVdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDEwNCA9IDEwNCBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxMDAgPSAxMDAgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTAxID0gMTAxIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBzdHJpbmcgZmllbGQxMDIgPSAxMDI7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEwMyA9IDEwMzsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyOSA9IDI5IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBib29sIGZpZWxkMzAgPSAzMCBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkNjAgPSA2MCBbZGVmYXVsdD0tMV07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjcxID0gMjcxIFtkZWZhdWx0PS0xXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyNzIgPSAyNzIgW2RlZmF1bHQ9LTFdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDE1MCA9IDE1MDsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMyA9IDIzIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBib29sIGZpZWxkMjQgPSAyNCBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjUgPSAyNSBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgU3BlZWRNZXNzYWdlMVN1Yk1lc3NhZ2UgZmllbGQxNSA9IDE1OworICBvcHRpb25hbCBib29sIGZpZWxkNzggPSA3ODsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQ2NyA9IDY3IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDY4ID0gNjg7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTI4ID0gMTI4IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBzdHJpbmcgZmllbGQxMjkgPSAxMjkgW2RlZmF1bHQ9Inh4eHh4eHh4eHh4eHh4eHh4eHh4eCJdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDEzMSA9IDEzMSBbZGVmYXVsdD0wXTsKK30KKworbWVzc2FnZSBTcGVlZE1lc3NhZ2UxU3ViTWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMSA9IDEgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMiA9IDIgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMyA9IDMgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDE1ID0gMTU7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQxMiA9IDEyIFtkZWZhdWx0PXRydWVdOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDEzID0gMTM7CisgIG9wdGlvbmFsIGludDY0IGZpZWxkMTQgPSAxNDsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxNiA9IDE2OworICBvcHRpb25hbCBpbnQzMiBmaWVsZDE5ID0gMTkgW2RlZmF1bHQ9Ml07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQyMCAgPSAyMCBbZGVmYXVsdD10cnVlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDI4ID0gMjggW2RlZmF1bHQ9dHJ1ZV07CisgIG9wdGlvbmFsIGZpeGVkNjQgZmllbGQyMSA9IDIxOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIyID0gMjI7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQyMyA9IDIzIFsgZGVmYXVsdD1mYWxzZSBdOworICBvcHRpb25hbCBib29sIGZpZWxkMjA2ID0gMjA2IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgZml4ZWQzMiBmaWVsZDIwMyA9IDIwMzsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMDQgPSAyMDQ7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDIwNSA9IDIwNTsKKyAgb3B0aW9uYWwgdWludDY0IGZpZWxkMjA3ID0gMjA3OworICBvcHRpb25hbCB1aW50NjQgZmllbGQzMDAgPSAzMDA7Cit9CisKK21lc3NhZ2UgU3BlZWRNZXNzYWdlMiB7CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDMgPSAzOworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDQgPSA0OworICBvcHRpb25hbCBpbnQ2NCBmaWVsZDMwID0gMzA7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ3NSAgPSA3NSBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDYgPSA2OworICBvcHRpb25hbCBieXRlcyBmaWVsZDIgPSAyOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIxID0gMjEgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkNzEgPSA3MTsKKyAgb3B0aW9uYWwgZmxvYXQgZmllbGQyNSA9IDI1OworICBvcHRpb25hbCBpbnQzMiBmaWVsZDEwOSA9IDEwOSBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMTAgPSAyMTAgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjExID0gMjExIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIxMiA9IDIxMiBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMTMgPSAyMTMgW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjE2ID0gMjE2IFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIxNyA9IDIxNyBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQyMTggPSAyMTggW2RlZmF1bHQ9MF07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMjIwID0gMjIwIFtkZWZhdWx0PTBdOworICBvcHRpb25hbCBpbnQzMiBmaWVsZDIyMSA9IDIyMSBbZGVmYXVsdD0wXTsKKyAgb3B0aW9uYWwgZmxvYXQgZmllbGQyMjIgPSAyMjIgW2RlZmF1bHQ9MC4wXTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQ2MyA9IDYzOworCisgIHJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsKKyAgICByZXF1aXJlZCBmbG9hdCBmaWVsZDExID0gMTE7CisgICAgb3B0aW9uYWwgZmxvYXQgZmllbGQyNiA9IDI2OworICAgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEyID0gMTI7CisgICAgb3B0aW9uYWwgc3RyaW5nIGZpZWxkMTMgPSAxMzsKKyAgICByZXBlYXRlZCBzdHJpbmcgZmllbGQxNCA9IDE0OworICAgIHJlcXVpcmVkIHVpbnQ2NCBmaWVsZDE1ID0gMTU7CisgICAgb3B0aW9uYWwgaW50MzIgZmllbGQ1ID0gNTsKKyAgICBvcHRpb25hbCBzdHJpbmcgZmllbGQyNyA9IDI3OworICAgIG9wdGlvbmFsIGludDMyIGZpZWxkMjggPSAyODsKKyAgICBvcHRpb25hbCBzdHJpbmcgZmllbGQyOSA9IDI5OworICAgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDE2ID0gMTY7CisgICAgcmVwZWF0ZWQgc3RyaW5nIGZpZWxkMjIgPSAyMjsKKyAgICByZXBlYXRlZCBpbnQzMiBmaWVsZDczID0gNzM7CisgICAgb3B0aW9uYWwgaW50MzIgZmllbGQyMCA9IDIwIFtkZWZhdWx0PTBdOworICAgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDI0ID0gMjQ7CisgICAgb3B0aW9uYWwgU3BlZWRNZXNzYWdlMkdyb3VwZWRNZXNzYWdlIGZpZWxkMzEgPSAzMTsKKyAgfQorICByZXBlYXRlZCBzdHJpbmcgZmllbGQxMjggPSAxMjg7CisgIG9wdGlvbmFsIGludDY0IGZpZWxkMTMxID0gMTMxOworICByZXBlYXRlZCBzdHJpbmcgZmllbGQxMjcgPSAxMjc7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkMTI5ID0gMTI5OworICByZXBlYXRlZCBpbnQ2NCBmaWVsZDEzMCA9IDEzMDsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDIwNSA9IDIwNSBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGJvb2wgZmllbGQyMDYgPSAyMDYgW2RlZmF1bHQ9ZmFsc2VdOworfQorCittZXNzYWdlIFNwZWVkTWVzc2FnZTJHcm91cGVkTWVzc2FnZSB7CisgIG9wdGlvbmFsIGZsb2F0IGZpZWxkMSA9IDE7CisgIG9wdGlvbmFsIGZsb2F0IGZpZWxkMiA9IDI7CisgIG9wdGlvbmFsIGZsb2F0IGZpZWxkMyA9IDMgW2RlZmF1bHQ9MC4wXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDQgPSA0OworICBvcHRpb25hbCBib29sIGZpZWxkNSA9IDU7CisgIG9wdGlvbmFsIGJvb2wgZmllbGQ2ID0gNiBbZGVmYXVsdD10cnVlXTsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDcgPSA3IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgZmxvYXQgZmllbGQ4ID0gODsKKyAgb3B0aW9uYWwgYm9vbCBmaWVsZDkgPSA5OworICBvcHRpb25hbCBmbG9hdCBmaWVsZDEwID0gMTA7CisgIG9wdGlvbmFsIGludDY0IGZpZWxkMTEgPSAxMTsKK30KZGlmZiAtLWdpdCBhL2JlbmNobWFya3MvcmVhZG1lLnR4dCBiL2JlbmNobWFya3MvcmVhZG1lLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzgzNmQwCi0tLSAvZGV2L251bGwKKysrIGIvYmVuY2htYXJrcy9yZWFkbWUudHh0CkBAIC0wLDAgKzEsNTAgQEAKK0NvbnRlbnRzCistLS0tLS0tLQorCitUaGlzIGZvbGRlciBjb250YWlucyB0aHJlZSBraW5kcyBvZiBmaWxlOgorCistIENvZGUsIHN1Y2ggYXMgUHJvdG9CZW5jaC5qYXZhLCB0byBidWlsZCB0aGUgYmVuY2htYXJraW5nIGZyYW1ld29yay4KKy0gUHJvdG9jb2wgYnVmZmVyIGRlZmluaXRpb25zICgucHJvdG8gZmlsZXMpCistIFNhbXBsZSBkYXRhIGZpbGVzCisKK0lmIHdlIGVuZCB1cCB3aXRoIGEgbG90IG9mIGRpZmZlcmVudCBiZW5jaG1hcmtzIGl0IG1heSBiZSB3b3J0aAorc2VwYXJhdGluZyB0aGVzZSBvdXQgaW5mbyBkaWZmZXJlbnQgZGlyZWN0b3JpZXMsIGJ1dCB3aGlsZSB0aGVyZSBhcmUKK3NvIGZldyB0aGV5IG1pZ2h0IGFzIHdlbGwgYWxsIGJlIHRvZ2V0aGVyLgorCitSdW5uaW5nIGEgYmVuY2htYXJrIChKYXZhKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworMSkgQnVpbGQgcHJvdG9jIGFuZCB0aGUgSmF2YSBwcm90b2NvbCBidWZmZXIgbGlicmFyeS4gVGhlIGV4YW1wbGVzCisgICBiZWxvdyBhc3N1bWUgYSBqYXIgZmlsZSAocHJvdG9idWYuamFyKSBoYXMgYmVlbiBidWlsdCBhbmQgY29waWVkCisgICBpbnRvIHRoaXMgZGlyZWN0b3J5LgorCisyKSBCdWlsZCBQcm90b0JlbmNoOgorICAgJCBqYXZhYyAtZCB0bXAgLWNwIHByb3RvYnVmLmphciBQcm90b0JlbmNoLmphdmEKKyAgIAorMykgR2VuZXJhdGUgY29kZSBmb3IgdGhlIHJlbGV2YW50IGJlbmNobWFyayBwcm90b2NvbCBidWZmZXIsIGUuZy4KKyAgICQgcHJvdG9jIC0tamF2YV9vdXQ9dG1wIGdvb2dsZV9zaXplLnByb3RvIGdvb2dsZV9zcGVlZC5wcm90bworICAgCis0KSBCdWlsZCB0aGUgZ2VuZXJhdGVkIGNvZGUsIGUuZy4KKyAgICQgY2QgdG1wCisgICAkIGphdmFjIC1kIC4gLWNwIC4uL3Byb3RvYnVmLmphciBiZW5jaG1hcmtzLyouamF2YQorICAgICAgICAgICAKKzUpIFJ1biB0aGUgdGVzdC4gQXJndW1lbnRzIGFyZSBnaXZlbiBpbiBwYWlycyAtIHRoZSBmaXJzdCBhcmd1bWVudAorICAgaXMgdGhlIGRlc2NyaXB0b3IgdHlwZTsgdGhlIHNlY29uZCBpcyB0aGUgZmlsZW5hbWUuIEZvciBleGFtcGxlOgorICAgJCBqYXZhIC1jcCAuOy4uL3Byb3RvYnVmLmphciBjb20uZ29vZ2xlLnByb3RvY29sYnVmZmVycy5Qcm90b0JlbmNoCisgICAgICAgICAgYmVuY2htYXJrcy5Hb29nbGVTaXplJFNpemVNZXNzYWdlMSAuLi9nb29nbGVfbWVzc2FnZTEuZGF0CisgICAgICAgICAgYmVuY2htYXJrcy5Hb29nbGVTcGVlZCRTcGVlZE1lc3NhZ2UxIC4uL2dvb2dsZV9tZXNzYWdlMS5kYXQKKyAgICAgICAgICBiZW5jaG1hcmtzLkdvb2dsZVNpemUkU2l6ZU1lc3NhZ2UyIC4uL2dvb2dsZV9tZXNzYWdlMi5kYXQKKyAgICAgICAgICBiZW5jaG1hcmtzLkdvb2dsZVNwZWVkJFNwZWVkTWVzc2FnZTIgLi4vZ29vZ2xlX21lc3NhZ2UyLmRhdAorICAgICAgICAgIAorNikgV2FpdCEgRWFjaCB0ZXN0IHJ1bnMgZm9yIGFyb3VuZCAzMCBzZWNvbmRzLCBhbmQgdGhlcmUgYXJlIDYgdGVzdHMKKyAgIHBlciBjbGFzcy9kYXRhIGNvbWJpbmF0aW9uLiBUaGUgYWJvdmUgY29tbWFuZCB3b3VsZCB0aGVyZWZvcmUgdGFrZQorICAgYWJvdXQgMTIgbWludXRlcyB0byBydW4uCisKKyAgIAorQmVuY2htYXJrcyBhdmFpbGFibGUKKy0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0Zyb20gR29vZ2xlOgorZ29vZ2xlX3NpemUucHJvdG8gYW5kIGdvb2dsZV9zcGVlZC5wcm90bywgbWVzc2FnZXMKK2dvb2dsZV9tZXNzYWdlMS5kYXQgYW5kIGdvb2dsZV9tZXNzYWdlMi5kYXQuIFRoZSBwcm90byBmaWxlcyBhcmUKK2VxdWl2YWxlbnQsIGJ1dCBvcHRpbWl6ZWQgZGlmZmVyZW50bHkuCmRpZmYgLS1naXQgYS9jb25maWcuaC5pbmNsdWRlIGIvY29uZmlnLmguaW5jbHVkZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzU1N2ZiCi0tLSAvZGV2L251bGwKKysrIGIvY29uZmlnLmguaW5jbHVkZQpAQCAtMCwwICsxLDcgQEAKK0hBU0hfTUFQX0NMQVNTCitIQVNIX01BUF9ICitIQVNIX05BTUVTUEFDRQorSEFTSF9TRVRfQ0xBU1MKK0hBU0hfU0VUX0gKK0hBVkVfSEFTSF9NQVAKK0hBVkVfSEFTSF9TRVQKZGlmZiAtLWdpdCBhL2NvbmZpZ3VyZS5hYyBiL2NvbmZpZ3VyZS5hYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDM1MWE4Ci0tLSAvZGV2L251bGwKKysrIGIvY29uZmlndXJlLmFjCkBAIC0wLDAgKzEsMTY4IEBACisjIyBQcm9jZXNzIHRoaXMgZmlsZSB3aXRoIGF1dG9jb25mIHRvIHByb2R1Y2UgY29uZmlndXJlLgorIyMgSW4gZ2VuZXJhbCwgdGhlIHNhZmVzdCB3YXkgdG8gcHJvY2VlZCBpcyB0byBydW4gLi9hdXRvZ2VuLnNoCisKK0FDX1BSRVJFUSgyLjU5KQorCisjIE5vdGU6ICBJZiB5b3UgY2hhbmdlIHRoZSB2ZXJzaW9uLCB5b3UgbXVzdCBhbHNvIHVwZGF0ZSBpdCBpbjoKKyMgKiBqYXZhL3BvbS54bWwKKyMgKiBweXRob24vc2V0dXAucHkKKyMgKiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oCisjICogc3JjL01ha2VmaWxlLmFtIChVcGRhdGUgLXZlcnNpb24taW5mbyBmb3IgTERGTEFHUyBpZiBuZWVkZWQpCisjCisjIEluIHRoZSBTVk4gdHJ1bmssIHRoZSB2ZXJzaW9uIHNob3VsZCBhbHdheXMgYmUgdGhlIG5leHQgYW50aWNpcGF0ZWQgcmVsZWFzZQorIyB2ZXJzaW9uIHdpdGggdGhlICItcHJlIiBzdWZmaXguICAoV2UgdXNlZCB0byB1c2UgIi1TTkFQU0hPVCIgYnV0IHRoaXMgcHVzaGVkCisjIHRoZSBzaXplIG9mIG9uZSBmaWxlIG5hbWUgaW4gdGhlIGRpc3QgdGFyZmlsZSBvdmVyIHRoZSA5OS1jaGFyIGxpbWl0LikKK0FDX0lOSVQoW1Byb3RvY29sIEJ1ZmZlcnNdLFszLjAuMC1hbHBoYS0zLXByZV0sW3Byb3RvYnVmQGdvb2dsZWdyb3Vwcy5jb21dLFtwcm90b2J1Zl0pCisKK0FNX01BSU5UQUlORVJfTU9ERShbZW5hYmxlXSkKKworQUNfQ09ORklHX1NSQ0RJUihzcmMvZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuY2MpCitBQ19DT05GSUdfSEVBREVSUyhbY29uZmlnLmhdKQorQUNfQ09ORklHX01BQ1JPX0RJUihbbTRdKQorCitBQ19BUkdfVkFSKERJU1RfTEFORywgW2xhbmd1YWdlIHRvIGluY2x1ZGUgaW4gdGhlIGRpc3RyaWJ1dGlvbiBwYWNrYWdlIChpLmUuLCBtYWtlIGRpc3QpXSkKK2Nhc2UgIiRESVNUX0xBTkciIGluCisgICIiKSBESVNUX0xBTkc9YWxsIDs7CisgIGFsbCB8IGNwcCB8IGphdmEgfCBweXRob24gfCBqYXZhbmFubyB8IHJ1YnkpIDs7CisgICopIEFDX01TR19GQUlMVVJFKFt1bmtub3duIGxhbmd1YWdlOiAkRElTVF9MQU5HXSkgOzsKK2VzYWMKK0FDX1NVQlNUKERJU1RfTEFORykKKworIyBhdXRvY29uZidzIGRlZmF1bHQgQ1hYRkxBR1MgYXJlIHVzdWFsbHkgIi1nIC1PMiIuICBUaGVzZSBhcmVuJ3QgbmVjZXNzYXJpbHkKKyMgdGhlIGJlc3QgY2hvaWNlIGZvciBsaWJwcm90b2J1Zi4KK0FTX0lGKFt0ZXN0ICJ4JHthY19jdl9lbnZfQ0ZMQUdTX3NldH0iID0gIngiXSwKKyAgICAgIFtDRkxBR1M9IiJdKQorQVNfSUYoW3Rlc3QgIngke2FjX2N2X2Vudl9DWFhGTEFHU19zZXR9IiA9ICJ4Il0sCisgICAgICBbQ1hYRkxBR1M9IiJdKQorCitBQ19DQU5PTklDQUxfVEFSR0VUCisKK0FNX0lOSVRfQVVUT01BS0UoWzEuOSB0YXItdXN0YXIgc3ViZGlyLW9iamVjdHNdKQorCitBQ19BUkdfV0lUSChbemxpYl0sCisgIFtBU19IRUxQX1NUUklORyhbLS13aXRoLXpsaWJdLAorICAgIFtpbmNsdWRlIGNsYXNzZXMgZm9yIHN0cmVhbWluZyBjb21wcmVzc2VkIGRhdGEgaW4gYW5kIG91dCBAPDpAZGVmYXVsdD1jaGVja0A6PkBdKV0sCisgIFtdLFt3aXRoX3psaWI9Y2hlY2tdKQorCitBQ19BUkdfV0lUSChbcHJvdG9jXSwKKyAgW0FTX0hFTFBfU1RSSU5HKFstLXdpdGgtcHJvdG9jPUNPTU1BTkRdLAorICAgIFt1c2UgdGhlIGdpdmVuIHByb3RvYyBjb21tYW5kIGluc3RlYWQgb2YgYnVpbGRpbmcgYSBuZXcgb25lIHdoZW4gYnVpbGRpbmcgdGVzdHMgKHVzZWZ1bCBmb3IgY3Jvc3MtY29tcGlsaW5nKV0pXSwKKyAgW10sW3dpdGhfcHJvdG9jPW5vXSkKKworIyBDaGVja3MgZm9yIHByb2dyYW1zLgorQUNfUFJPR19DQworQUNfUFJPR19DWFgKK0FDX0xBTkcoW0MrK10pCitBQ1hfVVNFX1NZU1RFTV9FWFRFTlNJT05TCittNF9pZmRlZihbQU1fUFJPR19BUl0sIFtBTV9QUk9HX0FSXSkKK0FNX0NPTkRJVElPTkFMKEdDQywgdGVzdCAiJEdDQyIgPSB5ZXMpICAgIyBsZXQgdGhlIE1ha2VmaWxlIGtub3cgaWYgd2UncmUgZ2NjCisKKyMgdGVzdF91dGlsLmNjIHRha2VzIGZvcmV2ZXIgdG8gY29tcGlsZSB3aXRoIEdDQyBhbmQgb3B0aW1pemF0aW9uIHR1cm5lZCBvbi4KK0FDX01TR19DSEVDS0lORyhbQysrIGNvbXBpbGVyIGZsYWdzLi4uXSkKK0FTX0lGKFt0ZXN0ICJ4JHthY19jdl9lbnZfQ1hYRkxBR1Nfc2V0fSIgPSAieCJdLFsKKyAgQVNfSUYoW3Rlc3QgIiRHQ0MiID0gInllcyJdLFsKKyAgICBQUk9UT0JVRl9PUFRfRkxBRz0iLU8yIgorICAgIENYWEZMQUdTPSIke0NYWEZMQUdTfSAtZyIKKyAgXSkKKworICAjIFByb3RvY29sIEJ1ZmZlcnMgY29udGFpbnMgc2V2ZXJhbCBjaGVja3MgdGhhdCBhcmUgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5CisgICMgZm9yIGRlYnVnZ2luZyBhbmQgd2hpY2ggbWlnaHQgaHVydCBwZXJmb3JtYW5jZS4gIE1vc3QgdXNlcnMgYXJlIHByb2JhYmx5CisgICMgZW5kIHVzZXJzIHdobyBkb24ndCB3YW50IHRoZXNlIGNoZWNrcywgc28gYWRkIC1ETkRFQlVHIGJ5IGRlZmF1bHQuCisgIENYWEZMQUdTPSIkQ1hYRkxBR1MgLUROREVCVUciCisKKyAgQUNfTVNHX1JFU1VMVChbdXNlIGRlZmF1bHQ6ICRQUk9UT0JVRl9PUFRfRkxBRyAkQ1hYRkxBR1NdKQorXSxbCisgIEFDX01TR19SRVNVTFQoW3VzZSB1c2VyLXN1cHBsaWVkOiAkQ1hYRkxBR1NdKQorXSkKKworQUNfU1VCU1QoUFJPVE9CVUZfT1BUX0ZMQUcpCisKK0FDWF9DSEVDS19TVU5DQworCisjIEhhdmUgdG8gZG8gbGlidG9vbCBhZnRlciBTVU5DQywgb3RoZXIgd2lzZSBpdCAiaGVscGZ1bGx5IiBhZGRzIENydW4gQ3N0ZAorIyB0byB0aGUgbGluaworQUNfUFJPR19MSUJUT09MCisKKyMgQ2hlY2tzIGZvciBoZWFkZXIgZmlsZXMuCitBQ19IRUFERVJfU1REQworQUNfQ0hFQ0tfSEVBREVSUyhbZmNudGwuaCBpbnR0eXBlcy5oIGxpbWl0cy5oIHN0ZGxpYi5oIHVuaXN0ZC5oXSkKKworIyBDaGVja3MgZm9yIGxpYnJhcnkgZnVuY3Rpb25zLgorQUNfRlVOQ19NRU1DTVAKK0FDX0ZVTkNfU1RSVE9ECitBQ19DSEVDS19GVU5DUyhbZnRydW5jYXRlIG1lbXNldCBta2RpciBzdHJjaHIgc3RyZXJyb3Igc3RydG9sXSkKKworIyBDaGVjayBmb3IgemxpYi4KK0hBVkVfWkxJQj0wCitBU19JRihbdGVzdCAiJHdpdGhfemxpYiIgIT0gbm9dLCBbCisgIEFDX01TR19DSEVDS0lORyhbemxpYiB2ZXJzaW9uXSkKKworICAjIEZpcnN0IGNoZWNrIHRoZSB6bGliIGhlYWRlciB2ZXJzaW9uLgorICBBQ19DT01QSUxFX0lGRUxTRSgKKyAgICBbQUNfTEFOR19QUk9HUkFNKFtbCisgICAgICAgICNpbmNsdWRlIDx6bGliLmg+CisgICAgICAgICNpZiAhZGVmaW5lZChaTElCX1ZFUk5VTSkgfHwgKFpMSUJfVkVSTlVNIDwgMHgxMjA0KQorICAgICAgICAjIGVycm9yIHpsaWIgdmVyc2lvbiB0b28gb2xkCisgICAgICAgICNlbmRpZgorICAgICAgICBdXSwgW10pXSwgWworICAgIEFDX01TR19SRVNVTFQoW29rICgxLjIuMC40IG9yIGxhdGVyKV0pCisKKyAgICAjIEFsc28gbmVlZCB0byBhZGQgLWx6IHRvIHRoZSBsaW5rZXIgZmxhZ3MgYW5kIG1ha2Ugc3VyZSB0aGlzIHN1Y2NlZWRzLgorICAgIEFDX1NFQVJDSF9MSUJTKFt6bGliVmVyc2lvbl0sIFt6XSwgWworICAgICAgQUNfREVGSU5FKFtIQVZFX1pMSUJdLCBbMV0sIFtFbmFibGUgY2xhc3NlcyB1c2luZyB6bGliIGNvbXByZXNzaW9uLl0pCisgICAgICBIQVZFX1pMSUI9MQorICAgIF0sIFsKKyAgICAgIEFTX0lGKFt0ZXN0ICIkd2l0aF96bGliIiAhPSBjaGVja10sIFsKKyAgICAgICAgQUNfTVNHX0ZBSUxVUkUoWy0td2l0aC16bGliIHdhcyBnaXZlbiwgYnV0IG5vIHdvcmtpbmcgemxpYiBsaWJyYXJ5IHdhcyBmb3VuZF0pCisgICAgICBdKQorICAgIF0pCisgIF0sIFsKKyAgICBBU19JRihbdGVzdCAiJHdpdGhfemxpYiIgPSBjaGVja10sIFsKKyAgICAgIEFDX01TR19SRVNVTFQoW2hlYWRlcnMgbWlzc2luZyBvciB0b28gb2xkIChyZXF1aXJlcyAxLjIuMC40KV0pCisgICAgXSwgWworICAgICAgQUNfTVNHX0ZBSUxVUkUoWy0td2l0aC16bGliIHdhcyBnaXZlbiwgYnV0IHpsaWIgaGVhZGVycyB3ZXJlIG5vdCBwcmVzZW50IG9yIHdlcmUgdG9vIG9sZCAocmVxdWlyZXMgMS4yLjAuNCldKQorICAgIF0pCisgIF0pCitdKQorQU1fQ09ORElUSU9OQUwoW0hBVkVfWkxJQl0sIFt0ZXN0ICRIQVZFX1pMSUIgPSAxXSkKKworQVNfSUYoW3Rlc3QgIiR3aXRoX3Byb3RvYyIgIT0gIm5vIl0sIFsKKyAgUFJPVE9DPSR3aXRoX3Byb3RvYworICBBU19JRihbdGVzdCAiJHdpdGhfcHJvdG9jIiA9ICJ5ZXMiXSwgWworICAgICMgTm8gYXJndW1lbnQgZ2l2ZW4uICBVc2Ugc3lzdGVtIHByb3RvYy4KKyAgICBQUk9UT0M9cHJvdG9jCisgIF0pCisgIEFTX0lGKFtlY2hvICIkUFJPVE9DIiB8IGdyZXAgLXEgJ15APDpAXi9AOj5ALiovJ10sIFsKKyAgICAjIERvZXMgbm90IHN0YXJ0IHdpdGggYSBzbGFzaCwgYnV0IGNvbnRhaW5zIGEgc2xhc2guICBTbywgaXQncyBhIHJlbGF0aXZlCisgICAgIyBwYXRoIChhcyBvcHBvc2VkIHRvIGFuIGFic29sdXRlIHBhdGggb3IgYW4gZXhlY3V0YWJsZSBpbiAkUEFUSCkuCisgICAgIyBTaW5jZSBpdCB3aWxsIGFjdHVhbGx5IGJlIGV4ZWN1dGVkIGZyb20gdGhlIHNyYyBkaXJlY3RvcnksIHByZWZpeCB3aXRoCisgICAgIyB0aGUgY3VycmVudCBkaXJlY3RvcnkuICBXZSBhbHNvIGluc2VydCAkYWNfdG9wX2J1aWxkX3ByZWZpeCBpbiBjYXNlIHRoaXMKKyAgICAjIGlzIGEgbmVzdGVkIHBhY2thZ2UgYW5kIC0td2l0aC1wcm90b2Mgd2FzIGFjdHVhbGx5IGdpdmVuIG9uIHRoZSBvdXRlcgorICAgICMgcGFja2FnZSdzIGNvbmZpZ3VyZSBzY3JpcHQuCisgICAgUFJPVE9DPWBwd2RgLyR7YWNfdG9wX2J1aWxkX3ByZWZpeH0kUFJPVE9DCisgIF0pCisgIEFDX1NVQlNUKFtQUk9UT0NdKQorXSkKK0FNX0NPTkRJVElPTkFMKFtVU0VfRVhURVJOQUxfUFJPVE9DXSwgW3Rlc3QgIiR3aXRoX3Byb3RvYyIgIT0gIm5vIl0pCisKK0FDWF9QVEhSRUFECitBQ19DWFhfU1RMX0hBU0gKKworY2FzZSAiJHRhcmdldF9vcyIgaW4KKyAgbWluZ3cqIHwgY3lnd2luKiB8IHdpbiopCisgICAgOzsKKyAgKikKKyAgICAjIE5lZWQgdG8gbGluayBhZ2FpbnN0IHJ0IG9uIFNvbGFyaXMKKyAgICBBQ19TRUFSQ0hfTElCUyhbc2NoZWRfeWllbGRdLCBbcnRdLCBbXSwgW0FDX01TR19GQUlMVVJFKFtzY2hlZF95aWVsZCB3YXMgbm90IGZvdW5kIG9uIHlvdXIgc3lzdGVtXSldKQorICAgIDs7Citlc2FjCisKKyMgSEFDSzogIE1ha2UgZ3Rlc3QncyBjb25maWd1cmUgc2NyaXB0IHBpY2sgdXAgb3VyIGNvcHkgb2YgQ0ZMQUdTIGFuZCBDWFhGTEFHUywKKyMgICBzaW5jZSB0aGUgZmxhZ3MgYWRkZWQgYnkgQUNYX0NIRUNLX1NVTkNDIG11c3QgYmUgdXNlZCB3aGVuIGNvbXBpbGluZyBndGVzdAorIyAgIHRvby4KK2V4cG9ydCBDRkxBR1MKK2V4cG9ydCBDWFhGTEFHUworQUNfQ09ORklHX1NVQkRJUlMoW2d0ZXN0XSkKKworQUNfQ09ORklHX0ZJTEVTKFtNYWtlZmlsZSBzcmMvTWFrZWZpbGUgcHJvdG9idWYucGMgcHJvdG9idWYtbGl0ZS5wY10pCitBQ19PVVRQVVQKZGlmZiAtLWdpdCBhL2NzaGFycC8uZ2l0aWdub3JlIGIvY3NoYXJwLy5naXRpZ25vcmUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzZjNDE0ZgotLS0gL2Rldi9udWxsCisrKyBiL2NzaGFycC8uZ2l0aWdub3JlCkBAIC0wLDAgKzEsNDAgQEAKKyMKKyMgCVVudHJhY2tlZCBkaXJlY3RvcmllcworIworc3JjL0FkZHJlc3NCb29rL2Jpbgorc3JjL0FkZHJlc3NCb29rL29iagorc3JjL1Byb3RvY29sQnVmZmVycy9iaW4vCitzcmMvUHJvdG9jb2xCdWZmZXJzL29iai8KK3NyYy9Qcm90b2NvbEJ1ZmZlcnMvb2JqQ0YKK3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9iaW4vCitzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3Qvb2JqLworc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9iaW4vCitzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L29iai8KK3NyYy9Qcm90b0JlbmNoL2Jpbi8KK3NyYy9Qcm90b0JlbmNoL29iai8KK3NyYy9Qcm90b0R1bXAvYmluLworc3JjL1Byb3RvRHVtcC9vYmovCitzcmMvUHJvdG9HZW4vYmluLworc3JjL1Byb3RvR2VuL29iai8KK3NyYy9Qcm90b0dlbi5UZXN0L2Jpbi8KK3NyYy9Qcm90b0dlbi5UZXN0L29iai8KK3NyYy9Qcm90b011bmdlL2Jpbi8KK3NyYy9Qcm90b011bmdlL29iai8KK21vbm8vYmluCittb25vL3RtcAorbW9uby9wcm90b2MKK2J1aWxkX291dHB1dAorYnVpbGRfdGVtcAorYnVpbGQvbXNidWlsZCoubG9nCisKKyMKKyMgCVVudHJhY2tlZCBmaWxlcworIworKi51c2VyCisqLnN1bworX1JlU2hhcnBlci4qCisqLnNsbi5jYWNoZQorbW9uby9UZXN0UmVzdWx0LnhtbAorbW9uby8ubGlicworbW9uby8qLmV4ZQorbW9uby8qLmRsbApkaWZmIC0tZ2l0IGEvLmhnaWdub3JlIGIvY3NoYXJwLy5oZ2lnbm9yZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gLmhnaWdub3JlCnJlbmFtZSB0byBjc2hhcnAvLmhnaWdub3JlCmRpZmYgLS1naXQgYS9jc2hhcnAvQ0hBTkdFUy50eHQgYi9jc2hhcnAvQ0hBTkdFUy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBlOWQ3NwotLS0gL2Rldi9udWxsCisrKyBiL2NzaGFycC9DSEFOR0VTLnR4dApAQCAtMCwwICsxLDE0NCBAQAorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorV2VsY29tZSB0byB0aGUgQyMgcG9ydCBvZiBHb29nbGUgUHJvdG9jb2wgQnVmZmVycywgd3JpdHRlbiBieSBKb24gU2tlZXQKKyhza2VldEBwb2JveC5jb20pIGJhc2VkIG9uIHRoZSB3b3JrIG9mIG1hbnkgdGFsZW50ZWQgcGVvcGxlLgorCitGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIHBvcnQsIHZpc2l0IGl0cyBob21lcGFnZToKK2h0dHA6Ly9wcm90b2J1Zi1jc2hhcnAtcG9ydC5nb29nbGVjb2RlLmNvbQorCitGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBQcm90b2NvbCBCdWZmZXJzIGluIGdlbmVyYWwsIHZpc2l0IHRoZSBwcm9qZWN0IHBhZ2UgCitmb3IgdGhlIEMrKywgSmF2YSBhbmQgUHl0aG9uIHByb2plY3Q6CitodHRwOi8vcHJvdG9idWYuZ29vZ2xlY29kZS5jb20KKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK1JFTEVBU0UgTk9URVMgLSBWZXJzaW9uIDIuNC4xLjU1NQorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitDaGFuZ2VzOgorLSBVcGdyYWRlIHNvbHV0aW9uIGZvcm1hdCB0byBWaXN1YWwgU3R1ZGlvIDIwMTIuCistIEFkZCB0aGUgYWJpbGl0eSB0byBwcmludCBhIGJ1aWxkZXIgKG5vdCBqdXN0IGEgbWVzc2FnZSkKKy0gVGV4dEdlbmVyYXRvciBpbnRyb2R1Y2VzIGEgbmV3IG92ZXJsb2FkIG9mIFByaW50VG8KKy0gTXVuZ2UgcHJvdG9jJ3MgZXJyb3IgZm9ybWF0IGludG8gYSBWUy1DIy1jb21wYXRpYmxlIG91dHB1dCBmb3JtYXQuCistIFdvcmsgdG8gbWFrZSBQcm90b0dlbiBjbG9uZSB0aGF0IGFjdHMgYXMgYSBwcm90b2MuZXhlIHBsdWdpbi4KKy0gQWRkZWQgdGhlIEFsbG93UGFydGlhbGx5VHJ1c3RlZENhbGxlcnMgYXR0cmlidXRlCistIE9wdGltaXplZCBlbnVtIHBhcnNpbmcuCisKK0ZpeGVzOgorLSBGaXggZm9yIGJ1ZyBpbiBsaW1pdGVkIGlucHV0IHN0cmVhbSdzIFBvc2l0aW9uLCBJbnRyb2R1Y2VkIFBvc2l0aW9uIG9uIAorICBvdXRwdXQgc3RyZWFtCistIEZpeCBmb3Igd3JpdGluZyBhIGNoYXJhY3RlciB0byBhIEpTT04gb3V0cHV0IG92ZXJmbG93cyBhbGxvY2F0ZWQgYnVmZmVyCistIE9wdGltaXplIEZyb21CYXNlNjRTdHJpbmcgdG8gcmV0dXJuIEVtcHR5IHdoZW4gcHJlc2VudGVkIHdpdGggZW1wdHkgc3RyaW5nLgorLSBVc2Ugc3RyaW5nLkNvbmNhdCBpbnN0ZWFkIG9mIG9wZXJhdG9yIHRvIGF2b2lkIHBvdGVudGlhbCBpbXBvcnQgcHJvYmxlbXMKKy0gSXNzdWUgODE6IHF1b3RpbmcgZm9yIE5Vbml0IHBhcmFtZXRlcnMuCistIElzc3VlIDU2OiBOdUdldCBwYWNrYWdlIGlzIG5vaXN5CistIElzc3VlIDcwOiBQb3J0YWJsZSBsaWJyYXJ5IHByb2plY3QgaGFzIHNvbWUgaW52YWxpZCBOdW5pdC1iYXNlZCBjb2RlLgorLSBJc3N1ZSA3MTogQ29kZWRJbnB1dFN0cmVhbS5SZWFkQnl0ZXMgZ28gdG8gc2xvdyBwYXRoIHVubmVjZXNzYXJpbHkKKy0gSXNzdWUgODQ6IHdhcm5pbmcgQ1MwMjE5OiBUaGUgdmFyaWFibGUgYHNpemUnIGlzIGFzc2lnbmVkIGJ1dCBuZXZlciB1c2VkCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK1JFTEVBU0UgTk9URVMgLSBWZXJzaW9uIDIuNC4xLjUyMQorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitDaGFuZ2VzOgorLSBBZGQgZ2VuZXJhdGVkX2NvZGVfYXR0cmlidXRlcyBvcHRpb24sIGRlZmF1bHRlZCB0byBmYWxzZQorLSBBZGRlZCBzdXBwb3J0IGZvciBQb3J0YWJsZSBsaWJyYXJ5CistIEFkZGVkICdVbnNhZmUnIHN0YXRpYyB0eXBlIGluIEJ5dGVTdHJpbmcgdG8gYWxsb3cgZGlyZWN0IGJ1ZmZlciBhY2Nlc3MKKworRml4ZXM6CistIElzc3VlIDUwOiBUaGUgWE1MIHNlcmlhbGl6ZXIgd2lsbCBmYWlsIHRvIGRlc2VyaWFsaXplIGEgbWVzc2FnZSB3aXRoIGVtcHR5IAorICBjaGlsZCBtZXNzYWdlCistIElzc3VlIDQ1OiBVc2Ugb2YgJ2l0ZW0nIGFzIGEgZmllbGQgbmFtZSBjYXVzZXMgQW1iaWd1b3VzTWF0Y2hFeGNlcHRpb24KKy0gSXNzdWUgNDk6IEdlbmVyYXRlZCBuZXN0ZWQgc3RhdGljIFR5cGVzIGNsYXNzIHNob3VsZCBiZSBwYXJ0aWFsCistIElzc3VlIDM4OiBEaXNhYmxlIENMU0NvbXBsaWFudCB3YXJuaW5ncyAoMzAyMSkKKy0gSXNzdWUgNDA6IHByb3RvX3BhdGggZG9lcyBub3Qgd29yayBmb3IgY29tbWFuZC1saW5lIGZpbGUgbmFtZXMKKy0gSXNzdWUgNTQ6IHNob3VsZCByZXRpcmUgYWxsIGJ5dGVzIGluIGJ1ZmZlciAoYnVmZmVyU2l6ZSkKKy0gSXNzdWUgNDM6IEZpeCB0byBjb3JyZWN0IGlkZW50aWNhbCAndW1icmVsbGFfY2xhc3NuYW1lJyBvcHRpb25zIGZyb20gdHJ5aW5nIAorICB0byB3cml0ZSB0byB0aGUgc2FtZSBmaWxlbmFtZS4KKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMi40LjEuNDczCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ZlYXR1cmVzOgorLSBBZGRlZCBvcHRpb24gc2VydmljZV9nZW5lcmF0b3JfdHlwZSB0byBjb250cm9sIHNlcnZpY2UgZ2VuZXJhdGlvbiB3aXRoCisgIE5PTkUsIEdFTkVSSUMsIElOVEVSRkFDRSwgb3IgSVJQQ0RJU1BBVENICistIEFkZGVkIGludGVyZmFjZXMgSVJwY0Rpc3BhdGNoIGFuZCBJUnBjU2VydmVyU3R1YiB0byBwcm92aWRlIGZvciBibG9ja2luZworICBzZXJ2aWNlcyBhbmQgaW1wbGVtZW50YXRpb25zLgorLSBBZGRlZCBQcm90b0dlbi5leGUgY29tbWFuZC1saW5lIGFyZ3VtZW50ICItLXByb3RvY19kaXI9IiB0byBzcGVjaWZ5IHRoZSAKKyAgbG9jYXRpb24gb2YgcHJvdG9jLmV4ZS4KKy0gRXh0cmFjdGVkIGludGVyZmFjZXMgZm9yIElDb2RlZElucHV0U3RyZWFtIGFuZCBJQ29kZWRPdXRwdXRTdHJlYW0gdG8gYWxsb3cKKyAgY3VzdG9tIGltcGxlbWVudGF0aW9uIG9mIHdyaXRlcnMgd2l0aCBib3RoIHNwZWVkIGFuZCBzaXplIG9wdGltaXphdGlvbnMuCistIEFkZGl0aW9uIG9mIHRoZSAiR29vZ2xlLlByb3RvQnVmZmVycy5TZXJpYWxpemF0aW9uIiBhc3NlbWJseSB0byBzdXBwb3J0CisgIHJlYWRpbmcgYW5kIHdyaXRpbmcgbWVzc2FnZXMgdG8vZnJvbSBYTUwsIEpTT04sIElEaWN0aW9uYXJ5PCw+IGFuZCBvdGhlcnMuCistIFNldmVyYWwgcGVyZm9ybWFuY2UgcmVsYXRlZCBmaXhlcyBhbmQgdHdlZWtzCistIElzc3VlIDM6CUFkZCBvcHRpb24gdG8gbWFyayBnZW5lcmF0ZWQgY29kZSB3aXRoIGF0dHJpYnV0ZQorLSBJc3N1ZSAyMDoJU3VwcG9ydCBmb3IgZGVjb3JhdGluZyBjbGFzc2VzIFtTZXJpYWxpemFibGVdCistIElzc3VlIDIxOglEZWNvcmF0ZSBmaWVsZHMgd2l0aCBbZGVwcmVjYXRlZD10cnVlXSBhcyBbU3lzdGVtLk9ic29sZXRlXQorLSBJc3N1ZSAyMjoJUmV1c2FibGUgQnVpbGRlciBjbGFzc2VzCistIElzc3VlIDI0OglTdXBwb3J0IGZvciB1c2luZyBKc29uL1htbCBmb3JtYXRzIHdpdGggSUNvZGVkSW5wdXRTdHJlYW0KKy0gSXNzdWUgMjU6IEFkZGVkIHN1cHBvcnQgZm9yIE51R2V0IHBhY2thZ2VzCistIElzc3VlIDMxOiBVcGdyYWRlZCBwcm90b2MuZXhlIGFuZCBkZXNjcmlwdG9yIHRvIDIuNC4xCisKK0ZpeGVzOgorLSBJc3N1ZSAxMzoJTWVzc2FnZSB3aXRoIEZpZWxkIHNhbWUgbmFtZSBhcyBtZXNzYWdlIGNhdXNlcyB1bmNvbXBpbGFibGUgLmNzCistIElzc3VlIDE2OglEb2VzIG5vdCBpbnRlZ3JhdGUgd2VsbCB3aXRoIG90aGVyIHRvb2xpbmcKKy0gSXNzdWUgMTk6CVN1cHBvcnQgZm9yIG5lZ2F0aXZlIGVudW0gdmFsdWVzCistIElzc3VlIDI2OglBZGRSYW5nZSBpbiBHZW5lcmF0ZWRCdWlsZGVyIGl0ZXJhdGVzIHR3aWNlLgorLSBJc3N1ZSAyNzoJUmVtb3ZlIFhNTCBkb2N1bWVudGF0aW9uIG91dHB1dCBmcm9tIHRlc3QgcHJvamVjdHMgdG8gY2xlYXIgCisgIHdhcm5pbmdzL2Vycm9ycy4KKy0gSXNzdWUgMjg6IENpcmN1bGFyIG1lc3NhZ2UgZGVwZW5kZW5jaWVzIHJlc3VsdCBpbiBudWxsIGRlZmF1bHQgdmFsdWVzIGZvciAKKyAgTWVzc2FnZSBmaWVsZHMuCistIElzc3VlIDI5OiBNZXNzYWdlIGNsYXNzZXMgZ2VuZXJhdGVkIGhhdmUgYSBwdWJsaWMgZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIFlvdQorICBjYW4gZGlzYWJsZSBwcml2YXRlIGN0b3IgZ2VuZXJhdGlvbiB3aXRoIHRoZSBvcHRpb24gZ2VuZXJhdGVfcHJpdmF0ZV9jdG9yLgorLSBJc3N1ZSAzNTogRml4ZWQgYSBidWcgaW4gUHJvdG9HZW4gaGFuZGxpbmcgb2YgYXJndW1lbnRzIHdpdGggdHJhaWxpbmcgXAorLSBCaWctZW5kaWFuIHN1cHBvcnQgZm9yIGZsb2F0LCBhbmQgZG91YmxlIG9uIFNpbHZlcmxpZ2h0CistIFBhY2tlZCBhbmQgVW5wYWNrZWQgcGFyc2luZyBhbGxvdyBmb3IgYWxsIHJlcGVhdGVkLCBhcyBwZXIgdmVyc2lvbiAyLjMKKy0gRml4IGZvciBsZWF2aW5nIEJ1aWxkZXIgYSBwdWJsaWMgY3RvciBvbiBpbnRlcm5hbCBjbGFzc2VzIGZvciB1c2Ugd2l0aAorICBnZW5lcmljICJ3aGVyZSBUOiBuZXcoKSIgY29uc3RyYWludHMuCisKK090aGVyOgorLSBDaGFuZ2VkIHRoZSBjb2RlIHNpZ25pbmcga2V5IHRvIGEgcHJpdmF0ZWx5IGhlbGQga2V5CistIFJlZm9ybWF0dGVkIGFsbCBjb2RlIGFuZCBsaW5lLWVuZGluZ3MgdG8gQyMgZGVmYXVsdHMKKy0gUmV3b3JraW5nIG9mIHBlcmZvcm1hbmNlIGJlbmNobWFya3MgdG8gcHJvZHVjZSByZWxpYWJsZSByZXN1bHRzLCBvcHRpb24gL3YyCistIElzc3VlIDM0OiBTaWx2ZXJsaWdodCBhc3NlbWJsaWVzIGFyZSBub3cgdW5pdCB0ZXN0ZWQKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMi4zLjAuMjc3Cis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ZlYXR1cmVzOgorLSBBZGRlZCBjbHNfY29tcGxpYW5jZSBvcHRpb24gdG8gZ2VuZXJhdGUgYXR0cmlidXRlcyBpbmRpY2F0aW5nIAorICBub24tQ0xTLWNvbXBsaWFuY2UuCistIEFkZGVkIGZpbGVfZXh0ZW5zaW9uIG9wdGlvbiB0byBjb250cm9sIHRoZSBnZW5lcmF0ZWQgb3V0cHV0IGZpbGUncyBleHRlbnNpb24uCistIEFkZGVkIHVtYnJlbGxhX25hbWVzcGFjZSBvcHRpb24gdG8gcGxhY2UgdGhlIHVtYnJlbGxhIGNsYXNzIGludG8gYSBuZXN0ZWQKKyAgbmFtZXNwYWNlIHRvIGFkZHJlc3MgaXNzdWVzIHdpdGggcHJvdG8gZmlsZXMgaGF2aW5nIHRoZSBzYW1lIG5hbWUgYXMgYSAKKyAgbWVzc2FnZSBpdCBjb250YWlucy4KKy0gQWRkZWQgb3V0cHV0X2RpcmVjdG9yeSBvcHRpb24gdG8gc2V0IHRoZSBvdXRwdXQgcGF0aCBmb3IgdGhlIHNvdXJjZSBmaWxlKHMpLgorLSBBZGRlZCBpZ25vcmVfZ29vZ2xlX3Byb3RvYnVmIG9wdGlvbiB0byBhdm9pZCBnZW5lcmF0aW5nIGNvZGUgZm9yIGluY2x1ZGVzIAorICBmcm9tIHRoZSBnb29nbGUucHJvdG9idWYgcGFja2FnZS4KKy0gQWRkZWQgdGhlIExJVEUgZnJhbWV3b3JrIChHb29nbGUuUHJvdG9CdWZmZXJzTGl0ZS5kbGwpIGFuZCB0aGUgYWJpbGl0eSB0bworICBnZW5lcmF0ZSBjb2RlIHdpdGggIm9wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7Ii4KKy0gQWRkZWQgYWJpbGl0eSB0byBpbnZva2UgcHJvdG9jLmV4ZSBmcm9tIHdpdGhpbiBQcm90b0dlbi5leGUuCistIFVwZ3JhZGVkIHRvIHByb3RvYy5leGUgKDIuMykgY29tcGlsZXIuCisKK0ZpeGVzOgorLSBJc3N1ZSA5OglDbGFzcyBjYW5ub3QgYmUgc3RhdGljIGFuZCBzZWFsZWQgZXJyb3IKKy0gSXNzdWUgMTI6CWRlZmF1bHQgdmFsdWUgZm9yIGVudW1lcmF0ZSBmaWVsZHMgbXVzdCBiZSBmaWxsZWQgb3V0CisKK090aGVyOgorLSBSZXdyaXRlIG9mIGJ1aWxkIHVzaW5nIE1TQmJ1aWxkIGluc3RlYWQgb2YgTkFudAorLSBNb3ZlZCB0byBOVW5pdCBWZXJzaW9uIDIuMi44LjAKKy0gQ2hhbmdlZCB0byB1c2luZyBzZWN1cmUgLnNuayBmb3IgcmVsZWFzZXMKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMC45LjEKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworRml4ZXM6CistIGlzc3VlIDEwOglJbmNvcnJlY3QgZW5jb2Rpbmcgb2YgcGFja2VkIGZpZWxkcyB3aGVuIHNlcmlhbGl6ZWQKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorUkVMRUFTRSBOT1RFUyAtIFZlcnNpb24gMC45LjAKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLSBJbml0aWFsIHJlbGVhc2UKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2NzaGFycC9SRUFETUUubWQgYi9jc2hhcnAvUkVBRE1FLm1kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4NDQwNjIKLS0tIC9kZXYvbnVsbAorKysgYi9jc2hhcnAvUkVBRE1FLm1kCkBAIC0wLDAgKzEsMTIgQEAKK1RoaXMgcmVwbyB3YXMgb3JpZ2luYWxseSBleHBvcnRlZCBmcm9tIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi1jc2hhcnAtcG9ydCwKK2FuZCByZXByZXNlbnRzIHRoZSBsYXRlc3QgImxlZ2FjeSIgdmVyc2lvbiBvZiBwcm90b2J1Zi1jc2hhcnAtcG9ydC4KKworVGhpcyBwcm9qZWN0IGhhcyBub3cgYmVlbiBmb2xkZWQgaW50byB0aGUgW21haW4gR29vZ2xlIFByb3RvY29sIEJ1ZmZlcnMgcHJvamVjdF0oaHR0cDovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmKSwKK2FuZCBpcyBiZWluZyByZXZhbXBlZCB0byBzdXBwb3J0IHByb3RvMy4gSXQgaXMgbm90IGV4cGVjdGVkIHRvIGJlIGZ1bGx5IGJhY2t3YXJkbHktY29tcGF0aWJsZSB3aXRoCit0aGUgY29kZSBpbiB0aGlzIHJlcG8gLSBpbiBwYXJ0aWN1bGFyLCBzb21lIG9mIHRoZSBDIy1zcGVjaWZpYyBvcHRpb25zIG1heSBub3QgYmUgc3VwcG9ydGVkIGluIHRoZSBuZXcKK2NvZGViYXNlLCBhbmQgc29tZSBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUgbWF5IGRpZmZlci4gQSBuZXcgbWFqb3IgdmVyc2lvbiBvZmZlcnMgYW4gb3Bwb3J0dW5pdHkgdG8gc3ByaW5nLWNsZWFuLAorYXMgaXQgd2VyZS4KKworVGhpcyByZXBvIGV4aXN0cyBhcyBhbiBhY2tub3dsZWRnZW1lbnQgdGhhdCBub3QgZXZlcnlvbmUgd2lsbCB3YW50IHRvIGltbWVkaWF0ZWx5IHVzZSB0aGUgbmV3ZXIgY29kZWJhc2UsCithbmQgdGhhdCB0aGV5IG1heSB3aXNoIHRvIG1ha2UgY2hhbmdlcyB0byB0aGUgbGVnYWN5IGNvZGViYXNlLiBJIGRvIG5vdCBleHBlY3QgdG8gbWFrZSBhbnkgY2hhbmdlcyB3aXRoaW4gdGhpcworcmVwbywgYnV0IGl0IGNhbiBiZSBmb3JrZWQgZm9yIGZ1cnRoZXIgY2hhbmdlcy4KZGlmZiAtLWdpdCBhL2J1aWxkL0J1aWxkQWxsLmJhdCBiL2NzaGFycC9idWlsZC9CdWlsZEFsbC5iYXQKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGJ1aWxkL0J1aWxkQWxsLmJhdApyZW5hbWUgdG8gY3NoYXJwL2J1aWxkL0J1aWxkQWxsLmJhdApkaWZmIC0tZ2l0IGEvYnVpbGQvQ29tbW9uLnRhcmdldHMgYi9jc2hhcnAvYnVpbGQvQ29tbW9uLnRhcmdldHMKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGJ1aWxkL0NvbW1vbi50YXJnZXRzCnJlbmFtZSB0byBjc2hhcnAvYnVpbGQvQ29tbW9uLnRhcmdldHMKZGlmZiAtLWdpdCBhL2J1aWxkL0dvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMubnVzcGVjIGIvY3NoYXJwL2J1aWxkL0dvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMubnVzcGVjCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBidWlsZC9Hb29nbGUuUHJvdG9jb2xCdWZmZXJzLm51c3BlYwpyZW5hbWUgdG8gY3NoYXJwL2J1aWxkL0dvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMubnVzcGVjCmRpZmYgLS1naXQgYS9idWlsZC9Hb29nbGUuUHJvdG9jb2xCdWZmZXJzTGl0ZS5udXNwZWMgYi9jc2hhcnAvYnVpbGQvR29vZ2xlLlByb3RvY29sQnVmZmVyc0xpdGUubnVzcGVjCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBidWlsZC9Hb29nbGUuUHJvdG9jb2xCdWZmZXJzTGl0ZS5udXNwZWMKcmVuYW1lIHRvIGNzaGFycC9idWlsZC9Hb29nbGUuUHJvdG9jb2xCdWZmZXJzTGl0ZS5udXNwZWMKZGlmZiAtLWdpdCBhL2J1aWxkL1J1bkJlbmNobWFya3MuYmF0IGIvY3NoYXJwL2J1aWxkL1J1bkJlbmNobWFya3MuYmF0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBidWlsZC9SdW5CZW5jaG1hcmtzLmJhdApyZW5hbWUgdG8gY3NoYXJwL2J1aWxkL1J1bkJlbmNobWFya3MuYmF0CmRpZmYgLS1naXQgYS9idWlsZC9idWlsZC5iYXQgYi9jc2hhcnAvYnVpbGQvYnVpbGQuYmF0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBidWlsZC9idWlsZC5iYXQKcmVuYW1lIHRvIGNzaGFycC9idWlsZC9idWlsZC5iYXQKZGlmZiAtLWdpdCBhL2J1aWxkL2J1aWxkLmNzcHJvaiBiL2NzaGFycC9idWlsZC9idWlsZC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGJ1aWxkL2J1aWxkLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL2J1aWxkL2J1aWxkLmNzcHJvagpkaWZmIC0tZ2l0IGEvYnVpbGQvZ29vZ2xlY29kZV91cGxvYWQucHkgYi9jc2hhcnAvYnVpbGQvZ29vZ2xlY29kZV91cGxvYWQucHkKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGJ1aWxkL2dvb2dsZWNvZGVfdXBsb2FkLnB5CnJlbmFtZSB0byBjc2hhcnAvYnVpbGQvZ29vZ2xlY29kZV91cGxvYWQucHkKZGlmZiAtLWdpdCBhL2J1aWxkL251c3BlYy54c2QgYi9jc2hhcnAvYnVpbGQvbnVzcGVjLnhzZApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gYnVpbGQvbnVzcGVjLnhzZApyZW5hbWUgdG8gY3NoYXJwL2J1aWxkL251c3BlYy54c2QKZGlmZiAtLWdpdCBhL2J1aWxkL3B1Ymxpc2guY3Nwcm9qIGIvY3NoYXJwL2J1aWxkL3B1Ymxpc2guY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBidWlsZC9wdWJsaXNoLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL2J1aWxkL3B1Ymxpc2guY3Nwcm9qCmRpZmYgLS1naXQgYS9idWlsZC90YXJnZXQuY3Nwcm9qIGIvY3NoYXJwL2J1aWxkL3RhcmdldC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGJ1aWxkL3RhcmdldC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9idWlsZC90YXJnZXQuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL0NGMjAuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvQ0YyMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvQ0YyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL0NGMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL0NGMzUuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvQ0YzNS5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvQ0YzNS5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL0NGMzUuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL05FVDIwLmNzcHJvaiBiL2NzaGFycC9jc3Byb2pfdGVtcGxhdGVzL05FVDIwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gY3Nwcm9qX3RlbXBsYXRlcy9ORVQyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL05FVDIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvY3Nwcm9qX3RlbXBsYXRlcy9ORVQzNS5jc3Byb2ogYi9jc2hhcnAvY3Nwcm9qX3RlbXBsYXRlcy9ORVQzNS5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvTkVUMzUuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvY3Nwcm9qX3RlbXBsYXRlcy9ORVQzNS5jc3Byb2oKZGlmZiAtLWdpdCBhL2NzcHJval90ZW1wbGF0ZXMvTkVUNDAuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvTkVUNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBjc3Byb2pfdGVtcGxhdGVzL05FVDQwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvTkVUNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL1BMNDAuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvUEw0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvUEw0MC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL1BMNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL1NMMjAuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvU0wyMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvU0wyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL1NMMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL1NMMzAuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvU0wzMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvU0wzMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL1NMMzAuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL1NMNDAuY3Nwcm9qIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvU0w0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvU0w0MC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL1NMNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9jc3Byb2pfdGVtcGxhdGVzL1NMVGVzdC50YXJnZXRzIGIvY3NoYXJwL2NzcHJval90ZW1wbGF0ZXMvU0xUZXN0LnRhcmdldHMKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGNzcHJval90ZW1wbGF0ZXMvU0xUZXN0LnRhcmdldHMKcmVuYW1lIHRvIGNzaGFycC9jc3Byb2pfdGVtcGxhdGVzL1NMVGVzdC50YXJnZXRzCmRpZmYgLS1naXQgYS9rZXlzL0dvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMuc25rIGIvY3NoYXJwL2tleXMvR29vZ2xlLlByb3RvY29sQnVmZmVycy5zbmsKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGtleXMvR29vZ2xlLlByb3RvY29sQnVmZmVycy5zbmsKcmVuYW1lIHRvIGNzaGFycC9rZXlzL0dvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMuc25rCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2tleXMvZ2VuZXJhdGVfbmV3X2tleS5iYXQgYi9jc2hhcnAva2V5cy9nZW5lcmF0ZV9uZXdfa2V5LmJhdApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20ga2V5cy9nZW5lcmF0ZV9uZXdfa2V5LmJhdApyZW5hbWUgdG8gY3NoYXJwL2tleXMvZ2VuZXJhdGVfbmV3X2tleS5iYXQKZGlmZiAtLWdpdCBhL2xpYi83LVppcCA5LjIwLzctemlwLmNobSBiL2NzaGFycC9saWIvNy1aaXAgOS4yMC83LXppcC5jaG0Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi83LVppcCA5LjIwLzctemlwLmNobQpyZW5hbWUgdG8gY3NoYXJwL2xpYi83LVppcCA5LjIwLzctemlwLmNobQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvNy1aaXAgOS4yMC83emEuZXhlIGIvY3NoYXJwL2xpYi83LVppcCA5LjIwLzd6YS5leGUKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi83LVppcCA5LjIwLzd6YS5leGUKcmVuYW1lIHRvIGNzaGFycC9saWIvNy1aaXAgOS4yMC83emEuZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi83LVppcCA5LjIwL2xpY2Vuc2UudHh0IGIvY3NoYXJwL2xpYi83LVppcCA5LjIwL2xpY2Vuc2UudHh0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvNy1aaXAgOS4yMC9saWNlbnNlLnR4dApyZW5hbWUgdG8gY3NoYXJwL2xpYi83LVppcCA5LjIwL2xpY2Vuc2UudHh0CmRpZmYgLS1naXQgYS9saWIvNy1aaXAgOS4yMC9yZWFkbWUudHh0IGIvY3NoYXJwL2xpYi83LVppcCA5LjIwL3JlYWRtZS50eHQKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi83LVppcCA5LjIwL3JlYWRtZS50eHQKcmVuYW1lIHRvIGNzaGFycC9saWIvNy1aaXAgOS4yMC9yZWFkbWUudHh0CmRpZmYgLS1naXQgYS9saWIvQ3NQcm9qZWN0UHJvamVjdG9yL0NzUHJvamVjdFByb2plY3Rvci5leGUgYi9jc2hhcnAvbGliL0NzUHJvamVjdFByb2plY3Rvci9Dc1Byb2plY3RQcm9qZWN0b3IuZXhlCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvQ3NQcm9qZWN0UHJvamVjdG9yL0NzUHJvamVjdFByb2plY3Rvci5leGUKcmVuYW1lIHRvIGNzaGFycC9saWIvQ3NQcm9qZWN0UHJvamVjdG9yL0NzUHJvamVjdFByb2plY3Rvci5leGUKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nL0FwcmlsMjAxMC9FVUxBLnJ0ZiBiL2NzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL0VVTEEucnRmCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL0VVTEEucnRmCnJlbmFtZSB0byBjc2hhcnAvbGliL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nL0FwcmlsMjAxMC9FVUxBLnJ0ZgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLmRsbCBiL2NzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLmRsbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nL0FwcmlsMjAxMC9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy5kbGwKcmVuYW1lIHRvIGNzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLmV4dG1hcC54bWwgYi9jc2hhcnAvbGliL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nL0FwcmlsMjAxMC9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy5leHRtYXAueG1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLmV4dG1hcC54bWwKcmVuYW1lIHRvIGNzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLmV4dG1hcC54bWwKZGlmZiAtLWdpdCBhL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcucGRiIGIvY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcucGRiCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLnBkYgpyZW5hbWUgdG8gY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcucGRiCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcueG1sIGIvY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcueG1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nLnhtbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcueG1sCmRpZmYgLS1naXQgYS9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LmRsbCBiL2NzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LmRsbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nL0FwcmlsMjAxMC9NaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlF1YWxpdHlUb29scy5Vbml0VGVzdGluZy5TaWx2ZXJsaWdodC5kbGwKcmVuYW1lIHRvIGNzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LmV4dG1hcC54bWwgYi9jc2hhcnAvbGliL01pY3Jvc29mdC5TaWx2ZXJsaWdodC5UZXN0aW5nL0FwcmlsMjAxMC9NaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlF1YWxpdHlUb29scy5Vbml0VGVzdGluZy5TaWx2ZXJsaWdodC5leHRtYXAueG1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LmV4dG1hcC54bWwKcmVuYW1lIHRvIGNzaGFycC9saWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LmV4dG1hcC54bWwKZGlmZiAtLWdpdCBhL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5RdWFsaXR5VG9vbHMuVW5pdFRlc3RpbmcuU2lsdmVybGlnaHQucGRiIGIvY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5RdWFsaXR5VG9vbHMuVW5pdFRlc3RpbmcuU2lsdmVybGlnaHQucGRiCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LnBkYgpyZW5hbWUgdG8gY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5RdWFsaXR5VG9vbHMuVW5pdFRlc3RpbmcuU2lsdmVybGlnaHQucGRiCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5RdWFsaXR5VG9vbHMuVW5pdFRlc3RpbmcuU2lsdmVybGlnaHQueG1sIGIvY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5RdWFsaXR5VG9vbHMuVW5pdFRlc3RpbmcuU2lsdmVybGlnaHQueG1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcvQXByaWwyMDEwL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uUXVhbGl0eVRvb2xzLlVuaXRUZXN0aW5nLlNpbHZlcmxpZ2h0LnhtbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy9BcHJpbDIwMTAvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5RdWFsaXR5VG9vbHMuVW5pdFRlc3RpbmcuU2lsdmVybGlnaHQueG1sCmRpZmYgLS1naXQgYS9saWIvTlVuaXQtY29uZmlnL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uVGVzdFRvb2xzLmNzIGIvY3NoYXJwL2xpYi9OVW5pdC1jb25maWcvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5UZXN0VG9vbHMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC1jb25maWcvTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5UZXN0VG9vbHMuY3MKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQtY29uZmlnL01pY3Jvc29mdC5WaXN1YWxTdHVkaW8uVGVzdFRvb2xzLmNzCmRpZmYgLS1naXQgYS9saWIvTlVuaXQtY29uZmlnL251bml0LWNvbnNvbGUudjIuMC5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0LWNvbmZpZy9udW5pdC1jb25zb2xlLnYyLjAuY29uZmlnCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQtY29uZmlnL251bml0LWNvbnNvbGUudjIuMC5jb25maWcKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQtY29uZmlnL251bml0LWNvbnNvbGUudjIuMC5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC1jb25maWcvbnVuaXQtY29uc29sZS52My41LmNvbmZpZyBiL2NzaGFycC9saWIvTlVuaXQtY29uZmlnL251bml0LWNvbnNvbGUudjMuNS5jb25maWcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC1jb25maWcvbnVuaXQtY29uc29sZS52My41LmNvbmZpZwpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC1jb25maWcvbnVuaXQtY29uc29sZS52My41LmNvbmZpZwpkaWZmIC0tZ2l0IGEvbGliL05Vbml0LWNvbmZpZy9udW5pdC1jb25zb2xlLnY0LjAuY29uZmlnIGIvY3NoYXJwL2xpYi9OVW5pdC1jb25maWcvbnVuaXQtY29uc29sZS52NC4wLmNvbmZpZwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0LWNvbmZpZy9udW5pdC1jb25zb2xlLnY0LjAuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0LWNvbmZpZy9udW5pdC1jb25zb2xlLnY0LjAuY29uZmlnCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvTG9nby5pY28gYi9jc2hhcnAvbGliL05Vbml0L0xvZ28uaWNvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvTG9nby5pY28KcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvTG9nby5pY28KQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L05Vbml0Lm51cGtnIGIvY3NoYXJwL2xpYi9OVW5pdC9OVW5pdC5udXBrZwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L05Vbml0Lm51cGtnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L05Vbml0Lm51cGtnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC9OVW5pdEZpdFRlc3RzLmh0bWwgYi9jc2hhcnAvbGliL05Vbml0L05Vbml0Rml0VGVzdHMuaHRtbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L05Vbml0Rml0VGVzdHMuaHRtbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC9OVW5pdEZpdFRlc3RzLmh0bWwKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC9maXQtbGljZW5zZS50eHQgYi9jc2hhcnAvbGliL05Vbml0L2ZpdC1saWNlbnNlLnR4dApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L2ZpdC1saWNlbnNlLnR4dApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC9maXQtbGljZW5zZS50eHQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L2xpYi9udW5pdC5mcmFtZXdvcmsuZGxsIGIvY3NoYXJwL2xpYi9OVW5pdC9saWIvbnVuaXQuZnJhbWV3b3JrLmRsbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L2xpYi9udW5pdC5mcmFtZXdvcmsuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L2xpYi9udW5pdC5mcmFtZXdvcmsuZGxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC9saWIvbnVuaXQuZnJhbWV3b3JrLnhtbCBiL2NzaGFycC9saWIvTlVuaXQvbGliL251bml0LmZyYW1ld29yay54bWwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC9saWIvbnVuaXQuZnJhbWV3b3JrLnhtbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC9saWIvbnVuaXQuZnJhbWV3b3JrLnhtbApkaWZmIC0tZ2l0IGEvbGliL05Vbml0L2xpYi9udW5pdC5tb2Nrcy5kbGwgYi9jc2hhcnAvbGliL05Vbml0L2xpYi9udW5pdC5tb2Nrcy5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC9saWIvbnVuaXQubW9ja3MuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L2xpYi9udW5pdC5tb2Nrcy5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L2xpYi9wbnVuaXQuZnJhbWV3b3JrLmRsbCBiL2NzaGFycC9saWIvTlVuaXQvbGliL3BudW5pdC5mcmFtZXdvcmsuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvbGliL3BudW5pdC5mcmFtZXdvcmsuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L2xpYi9wbnVuaXQuZnJhbWV3b3JrLmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvbGljZW5zZS50eHQgYi9jc2hhcnAvbGliL05Vbml0L2xpY2Vuc2UudHh0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvbGljZW5zZS50eHQKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvbGljZW5zZS50eHQKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9OVW5pdFRlc3RzLlZpc3VhbFN0YXRlLnhtbCBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvTlVuaXRUZXN0cy5WaXN1YWxTdGF0ZS54bWwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9OVW5pdFRlc3RzLlZpc3VhbFN0YXRlLnhtbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9OVW5pdFRlc3RzLlZpc3VhbFN0YXRlLnhtbApkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL05Vbml0VGVzdHMuY29uZmlnIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9OVW5pdFRlc3RzLmNvbmZpZwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL05Vbml0VGVzdHMuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL05Vbml0VGVzdHMuY29uZmlnCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvTlVuaXRUZXN0cy5udW5pdCBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvTlVuaXRUZXN0cy5udW5pdApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL05Vbml0VGVzdHMubnVuaXQKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvTlVuaXRUZXN0cy5udW5pdApkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL1Rlc3RSZXN1bHQueG1sIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9UZXN0UmVzdWx0LnhtbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL1Rlc3RSZXN1bHQueG1sCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL1Rlc3RSZXN1bHQueG1sCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvYWdlbnQuY29uZiBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvYWdlbnQuY29uZgpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL2FnZW50LmNvbmYKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvYWdlbnQuY29uZgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2FnZW50LmxvZy5jb25mIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9hZ2VudC5sb2cuY29uZgpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL2FnZW50LmxvZy5jb25mCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2FnZW50LmxvZy5jb25mCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbGF1bmNoZXIubG9nLmNvbmYgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xhdW5jaGVyLmxvZy5jb25mCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGF1bmNoZXIubG9nLmNvbmYKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbGF1bmNoZXIubG9nLmNvbmYKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9saWIvRmFpbHVyZS5wbmcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9GYWlsdXJlLnBuZwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL2xpYi9GYWlsdXJlLnBuZwpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvRmFpbHVyZS5wbmcKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9JZ25vcmVkLnBuZyBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL0lnbm9yZWQucG5nCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL0lnbm9yZWQucG5nCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9JZ25vcmVkLnBuZwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbGliL0luY29uY2x1c2l2ZS5wbmcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9JbmNvbmNsdXNpdmUucG5nCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL0luY29uY2x1c2l2ZS5wbmcKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL0luY29uY2x1c2l2ZS5wbmcKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9Ta2lwcGVkLnBuZyBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL1NraXBwZWQucG5nCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL1NraXBwZWQucG5nCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9Ta2lwcGVkLnBuZwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbGliL1N1Y2Nlc3MucG5nIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvU3VjY2Vzcy5wbmcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9saWIvU3VjY2Vzcy5wbmcKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL1N1Y2Nlc3MucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9saWIvZml0LmRsbCBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL2ZpdC5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9saWIvZml0LmRsbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvZml0LmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbGliL2xvZzRuZXQuZGxsIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvbG9nNG5ldC5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9saWIvbG9nNG5ldC5kbGwKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL2xvZzRuZXQuZGxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9saWIvbnVuaXQtY29uc29sZS1ydW5uZXIuZGxsIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvbnVuaXQtY29uc29sZS1ydW5uZXIuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL251bml0LWNvbnNvbGUtcnVubmVyLmRsbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvbnVuaXQtY29uc29sZS1ydW5uZXIuZGxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9saWIvbnVuaXQtZ3VpLXJ1bm5lci5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC1ndWktcnVubmVyLmRsbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC1ndWktcnVubmVyLmRsbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9saWIvbnVuaXQtZ3VpLXJ1bm5lci5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC5jb3JlLmRsbCBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL251bml0LmNvcmUuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL251bml0LmNvcmUuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC5jb3JlLmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbGliL251bml0LmNvcmUuaW50ZXJmYWNlcy5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC5jb3JlLmludGVyZmFjZXMuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL251bml0LmNvcmUuaW50ZXJmYWNlcy5kbGwKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL251bml0LmNvcmUuaW50ZXJmYWNlcy5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC5maXh0dXJlcy5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC5maXh0dXJlcy5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9saWIvbnVuaXQuZml4dHVyZXMuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC5maXh0dXJlcy5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51aWV4Y2VwdGlvbi5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51aWV4Y2VwdGlvbi5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9saWIvbnVuaXQudWlleGNlcHRpb24uZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51aWV4Y2VwdGlvbi5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51aWtpdC5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51aWtpdC5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9saWIvbnVuaXQudWlraXQuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51aWtpdC5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51dGlsLmRsbCBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbGliL251bml0LnV0aWwuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbGliL251bml0LnV0aWwuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL2xpYi9udW5pdC51dGlsLmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbnVuaXQtYWdlbnQteDg2LmV4ZSBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQtYWdlbnQteDg2LmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LXg4Ni5leGUKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQtYWdlbnQteDg2LmV4ZQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbnVuaXQtYWdlbnQteDg2LmV4ZS5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LXg4Ni5leGUuY29uZmlnCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbnVuaXQtYWdlbnQteDg2LmV4ZS5jb25maWcKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQtYWdlbnQteDg2LmV4ZS5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9udW5pdC1hZ2VudC5leGUgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9udW5pdC1hZ2VudC5leGUKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LmV4ZS5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LmV4ZS5jb25maWcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9udW5pdC1hZ2VudC5leGUuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWFnZW50LmV4ZS5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9udW5pdC1jb25zb2xlLXg4Ni5leGUgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWNvbnNvbGUteDg2LmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL251bml0LWNvbnNvbGUteDg2LmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9udW5pdC1jb25zb2xlLXg4Ni5leGUKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL251bml0LWNvbnNvbGUteDg2LmV4ZS5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWNvbnNvbGUteDg2LmV4ZS5jb25maWcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9udW5pdC1jb25zb2xlLXg4Ni5leGUuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LWNvbnNvbGUteDg2LmV4ZS5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9udW5pdC1jb25zb2xlLmV4ZSBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQtY29uc29sZS5leGUKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9udW5pdC1jb25zb2xlLmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9udW5pdC1jb25zb2xlLmV4ZQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbnVuaXQteDg2LmV4ZSBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQteDg2LmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL251bml0LXg4Ni5leGUKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQteDg2LmV4ZQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvbnVuaXQteDg2LmV4ZS5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LXg4Ni5leGUuY29uZmlnCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbnVuaXQteDg2LmV4ZS5jb25maWcKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvbnVuaXQteDg2LmV4ZS5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9udW5pdC5leGUgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL251bml0LmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9udW5pdC5leGUKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL251bml0LmV4ZS5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LmV4ZS5jb25maWcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9udW5pdC5leGUuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL251bml0LmV4ZS5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9udW5pdC5mcmFtZXdvcmsuZGxsIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9udW5pdC5mcmFtZXdvcmsuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvbnVuaXQuZnJhbWV3b3JrLmRsbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9udW5pdC5mcmFtZXdvcmsuZGxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9wbnVuaXQtYWdlbnQuZXhlIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9wbnVuaXQtYWdlbnQuZXhlCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvcG51bml0LWFnZW50LmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9wbnVuaXQtYWdlbnQuZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9wbnVuaXQtYWdlbnQuZXhlLmNvbmZpZyBiL2NzaGFycC9saWIvTlVuaXQvdG9vbHMvcG51bml0LWFnZW50LmV4ZS5jb25maWcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9wbnVuaXQtYWdlbnQuZXhlLmNvbmZpZwpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9wbnVuaXQtYWdlbnQuZXhlLmNvbmZpZwpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL3BudW5pdC1sYXVuY2hlci5leGUgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL3BudW5pdC1sYXVuY2hlci5leGUKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9wbnVuaXQtbGF1bmNoZXIuZXhlCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL3BudW5pdC1sYXVuY2hlci5leGUKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL3BudW5pdC1sYXVuY2hlci5leGUuY29uZmlnIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9wbnVuaXQtbGF1bmNoZXIuZXhlLmNvbmZpZwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL3BudW5pdC1sYXVuY2hlci5leGUuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL3BudW5pdC1sYXVuY2hlci5leGUuY29uZmlnCmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvcG51bml0LmZyYW1ld29yay5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL3BudW5pdC5mcmFtZXdvcmsuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvcG51bml0LmZyYW1ld29yay5kbGwKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvcG51bml0LmZyYW1ld29yay5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL3BudW5pdC50ZXN0cy5kbGwgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL3BudW5pdC50ZXN0cy5kbGwKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy9wbnVuaXQudGVzdHMuZGxsCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL3BudW5pdC50ZXN0cy5kbGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbGliL05Vbml0L3Rvb2xzL3J1bkZpbGUuZXhlIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9ydW5GaWxlLmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL3J1bkZpbGUuZXhlCnJlbmFtZSB0byBjc2hhcnAvbGliL05Vbml0L3Rvb2xzL3J1bkZpbGUuZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9ydW5GaWxlLmV4ZS5jb25maWcgYi9jc2hhcnAvbGliL05Vbml0L3Rvb2xzL3J1bkZpbGUuZXhlLmNvbmZpZwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL05Vbml0L3Rvb2xzL3J1bkZpbGUuZXhlLmNvbmZpZwpyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9ydW5GaWxlLmV4ZS5jb25maWcKZGlmZiAtLWdpdCBhL2xpYi9OVW5pdC90b29scy9ydW5wbnVuaXQuYmF0IGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy9ydW5wbnVuaXQuYmF0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvTlVuaXQvdG9vbHMvcnVucG51bml0LmJhdApyZW5hbWUgdG8gY3NoYXJwL2xpYi9OVW5pdC90b29scy9ydW5wbnVuaXQuYmF0CmRpZmYgLS1naXQgYS9saWIvTlVuaXQvdG9vbHMvdGVzdC5jb25mIGIvY3NoYXJwL2xpYi9OVW5pdC90b29scy90ZXN0LmNvbmYKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OVW5pdC90b29scy90ZXN0LmNvbmYKcmVuYW1lIHRvIGNzaGFycC9saWIvTlVuaXQvdG9vbHMvdGVzdC5jb25mCmRpZmYgLS1naXQgYS9saWIvTnVHZXQuZXhlIGIvY3NoYXJwL2xpYi9OdUdldC5leGUKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9OdUdldC5leGUKcmVuYW1lIHRvIGNzaGFycC9saWIvTnVHZXQuZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGFtcFZlcnNpb24uTGljZW5zZS50eHQgYi9jc2hhcnAvbGliL1N0YW1wVmVyc2lvbi5MaWNlbnNlLnR4dApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL1N0YW1wVmVyc2lvbi5MaWNlbnNlLnR4dApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGFtcFZlcnNpb24uTGljZW5zZS50eHQKZGlmZiAtLWdpdCBhL2xpYi9TdGFtcFZlcnNpb24uZXhlIGIvY3NoYXJwL2xpYi9TdGFtcFZlcnNpb24uZXhlCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvU3RhbXBWZXJzaW9uLmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGFtcFZlcnNpb24uZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvU3RhdExpZ2h0Lm51cGtnIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvU3RhdExpZ2h0Lm51cGtnCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvU3RhdExpZ2h0L1N0YXRMaWdodC5udXBrZwpyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvU3RhdExpZ2h0Lm51cGtnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvSW9uaWMuWmlwLlJlZHVjZWQuZGxsIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvSW9uaWMuWmlwLlJlZHVjZWQuZGxsCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvU3RhdExpZ2h0L3Rvb2xzL0lvbmljLlppcC5SZWR1Y2VkLmRsbApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvSW9uaWMuWmlwLlJlZHVjZWQuZGxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcuTGljZW5zZS50eHQgYi9jc2hhcnAvbGliL1N0YXRMaWdodC90b29scy9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy5MaWNlbnNlLnR4dApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL1N0YXRMaWdodC90b29scy9NaWNyb3NvZnQuU2lsdmVybGlnaHQuVGVzdGluZy5MaWNlbnNlLnR4dApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvTWljcm9zb2Z0LlNpbHZlcmxpZ2h0LlRlc3RpbmcuTGljZW5zZS50eHQKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuQXByaWwyMDEwLnhhcCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLkFwcmlsMjAxMC54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuQXByaWwyMDEwLnhhcApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuQXByaWwyMDEwLnhhcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLkZlYjIwMTEueGFwIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuRmViMjAxMS54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuRmViMjAxMS54YXAKcmVuYW1lIHRvIGNzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLkZlYjIwMTEueGFwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuSnVseTIwMDkueGFwIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuSnVseTIwMDkueGFwCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLkp1bHkyMDA5LnhhcApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuSnVseTIwMDkueGFwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuSnVuZTIwMTEueGFwIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuSnVuZTIwMTEueGFwCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLkp1bmUyMDExLnhhcApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuSnVuZTIwMTEueGFwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTWFyY2gyMDEwLnhhcCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk1hcmNoMjAxMC54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTWFyY2gyMDEwLnhhcApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTWFyY2gyMDEwLnhhcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk1heTIwMTAueGFwIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTWF5MjAxMC54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTWF5MjAxMC54YXAKcmVuYW1lIHRvIGNzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk1heTIwMTAueGFwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTm92ZW1iZXIyMDA5LnhhcCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk5vdmVtYmVyMjAwOS54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTm92ZW1iZXIyMDA5LnhhcApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuTm92ZW1iZXIyMDA5LnhhcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk9jdG9iZXIyMDA5LnhhcCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk9jdG9iZXIyMDA5LnhhcApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL1N0YXRMaWdodC90b29scy9TdGF0TGlnaHQuQ2xpZW50LkZvci5PY3RvYmVyMjAwOS54YXAKcmVuYW1lIHRvIGNzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLk9jdG9iZXIyMDA5LnhhcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLlVuaXREcml2ZW5EZWNlbWJlcjIwMDkueGFwIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuVW5pdERyaXZlbkRlY2VtYmVyMjAwOS54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuVW5pdERyaXZlbkRlY2VtYmVyMjAwOS54YXAKcmVuYW1lIHRvIGNzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLlVuaXREcml2ZW5EZWNlbWJlcjIwMDkueGFwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuWFVuaXRDb250cmliQXByaWwyMDExLnhhcCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5DbGllbnQuRm9yLlhVbml0Q29udHJpYkFwcmlsMjAxMS54YXAKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIGxpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuWFVuaXRDb250cmliQXByaWwyMDExLnhhcApyZW5hbWUgdG8gY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LkNsaWVudC5Gb3IuWFVuaXRDb250cmliQXByaWwyMDExLnhhcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5Db3JlLmRsbCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5Db3JlLmRsbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL1N0YXRMaWdodC90b29scy9TdGF0TGlnaHQuQ29yZS5kbGwKcmVuYW1lIHRvIGNzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5Db3JlLmRsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5FVUxBLnR4dCBiL2NzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5FVUxBLnR4dApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL1N0YXRMaWdodC90b29scy9TdGF0TGlnaHQuRVVMQS50eHQKcmVuYW1lIHRvIGNzaGFycC9saWIvU3RhdExpZ2h0L3Rvb2xzL1N0YXRMaWdodC5FVUxBLnR4dApkaWZmIC0tZ2l0IGEvbGliL1N0YXRMaWdodC90b29scy9TdGF0TGlnaHQuZXhlIGIvY3NoYXJwL2xpYi9TdGF0TGlnaHQvdG9vbHMvU3RhdExpZ2h0LmV4ZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL1N0YXRMaWdodC90b29scy9TdGF0TGlnaHQuZXhlCnJlbmFtZSB0byBjc2hhcnAvbGliL1N0YXRMaWdodC90b29scy9TdGF0TGlnaHQuZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9wcm90b2MtbGljZW5zZS50eHQgYi9jc2hhcnAvbGliL3Byb3RvYy1saWNlbnNlLnR4dApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gbGliL3Byb3RvYy1saWNlbnNlLnR4dApyZW5hbWUgdG8gY3NoYXJwL2xpYi9wcm90b2MtbGljZW5zZS50eHQKZGlmZiAtLWdpdCBhL2xpYi9wcm90b2MuZXhlIGIvY3NoYXJwL2xpYi9wcm90b2MuZXhlCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWIvcHJvdG9jLmV4ZQpyZW5hbWUgdG8gY3NoYXJwL2xpYi9wcm90b2MuZXhlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpY2Vuc2UudHh0IGIvY3NoYXJwL2xpY2Vuc2UudHh0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBsaWNlbnNlLnR4dApyZW5hbWUgdG8gY3NoYXJwL2xpY2Vuc2UudHh0CmRpZmYgLS1naXQgYS9tb25vL2J1aWxkYWxsLnNoIGIvY3NoYXJwL21vbm8vYnVpbGRhbGwuc2gKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIG1vbm8vYnVpbGRhbGwuc2gKcmVuYW1lIHRvIGNzaGFycC9tb25vL2J1aWxkYWxsLnNoCmRpZmYgLS1naXQgYS9tb25vL2dlbmVyYXRlc291cmNlLnNoIGIvY3NoYXJwL21vbm8vZ2VuZXJhdGVzb3VyY2Uuc2gKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIG1vbm8vZ2VuZXJhdGVzb3VyY2Uuc2gKcmVuYW1lIHRvIGNzaGFycC9tb25vL2dlbmVyYXRlc291cmNlLnNoCmRpZmYgLS1naXQgYS9tb25vL3JlYWRtZS50eHQgYi9jc2hhcnAvbW9uby9yZWFkbWUudHh0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBtb25vL3JlYWRtZS50eHQKcmVuYW1lIHRvIGNzaGFycC9tb25vL3JlYWRtZS50eHQKZGlmZiAtLWdpdCBhL3Byb3Rvcy9iZW5jaG1hcmtzL2dvb2dsZV9zaXplLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9iZW5jaG1hcmtzL2dvb2dsZV9zaXplLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvYmVuY2htYXJrcy9nb29nbGVfc2l6ZS5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9iZW5jaG1hcmtzL2dvb2dsZV9zaXplLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvYmVuY2htYXJrcy9nb29nbGVfc3BlZWQucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2JlbmNobWFya3MvZ29vZ2xlX3NwZWVkLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvYmVuY2htYXJrcy9nb29nbGVfc3BlZWQucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvYmVuY2htYXJrcy9nb29nbGVfc3BlZWQucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhcy5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhc19mdWxsLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzX2Z1bGwucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzX2Z1bGwucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhc19mdWxsLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhc19saXRlLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzX2xpdGUucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzX2xpdGUucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhc19saXRlLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhc194bWx0ZXN0LnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzX3htbHRlc3QucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9leHRlc3QvdW5pdHRlc3RfZXh0cmFzX3htbHRlc3QucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2V4dHJhc194bWx0ZXN0LnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2dlbmVyaWNfc2VydmljZXMucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2V4dGVzdC91bml0dGVzdF9nZW5lcmljX3NlcnZpY2VzLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2dlbmVyaWNfc2VydmljZXMucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2dlbmVyaWNfc2VydmljZXMucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfaXNzdWVzLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfaXNzdWVzLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X2lzc3Vlcy5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfaXNzdWVzLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X3JwY19pbnRlcm9wLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9leHRlc3QvdW5pdHRlc3RfcnBjX2ludGVyb3AucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9leHRlc3QvdW5pdHRlc3RfcnBjX2ludGVyb3AucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X3JwY19pbnRlcm9wLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X3JwY19pbnRlcm9wX2xpdGUucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2V4dGVzdC91bml0dGVzdF9ycGNfaW50ZXJvcF9saXRlLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X3JwY19pbnRlcm9wX2xpdGUucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZXh0ZXN0L3VuaXR0ZXN0X3JwY19pbnRlcm9wX2xpdGUucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL2NzaGFycF9vcHRpb25zLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9nb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL2NzaGFycF9vcHRpb25zLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3NoYXJwX29wdGlvbnMucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jc2hhcnBfb3B0aW9ucy5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jc2hhcnBfb3B0aW9ucy5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3NoYXJwX29wdGlvbnMucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtcHR5LnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtcHR5LnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbm9ybW91c19kZXNjcmlwdG9yLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBwcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8gYi9jc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8KZGlmZiAtLWdpdCBhL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90byBiL2NzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90bwpyZW5hbWUgdG8gY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90bwpkaWZmIC0tZ2l0IGEvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvCnJlbmFtZSB0byBjc2hhcnAvcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wcm90byBiL2NzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wcm90bwpkaWZmIC0tZ2l0IGEvcHJvdG9zL2dvb2dsZS90ZXN0L2dvb2dsZV9zaXplLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvdGVzdC9nb29nbGVfc2l6ZS5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL2dvb2dsZS90ZXN0L2dvb2dsZV9zaXplLnByb3RvCnJlbmFtZSB0byBjc2hhcnAvcHJvdG9zL2dvb2dsZS90ZXN0L2dvb2dsZV9zaXplLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvZ29vZ2xlL3Rlc3QvZ29vZ2xlX3NwZWVkLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy9nb29nbGUvdGVzdC9nb29nbGVfc3BlZWQucHJvdG8Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHByb3Rvcy9nb29nbGUvdGVzdC9nb29nbGVfc3BlZWQucHJvdG8KcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvZ29vZ2xlL3Rlc3QvZ29vZ2xlX3NwZWVkLnByb3RvCmRpZmYgLS1naXQgYS9wcm90b3MvbnBwLmxhbmd1YWdlLnhtbCBiL2NzaGFycC9wcm90b3MvbnBwLmxhbmd1YWdlLnhtbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL25wcC5sYW5ndWFnZS54bWwKcmVuYW1lIHRvIGNzaGFycC9wcm90b3MvbnBwLmxhbmd1YWdlLnhtbApkaWZmIC0tZ2l0IGEvcHJvdG9zL3R1dG9yaWFsL2FkZHJlc3Nib29rLnByb3RvIGIvY3NoYXJwL3Byb3Rvcy90dXRvcmlhbC9hZGRyZXNzYm9vay5wcm90bwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gcHJvdG9zL3R1dG9yaWFsL2FkZHJlc3Nib29rLnByb3RvCnJlbmFtZSB0byBjc2hhcnAvcHJvdG9zL3R1dG9yaWFsL2FkZHJlc3Nib29rLnByb3RvCmRpZmYgLS1naXQgYS9zcmMvQWRkcmVzc0Jvb2svQWRkUGVyc29uLmNzIGIvY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9BZGRQZXJzb24uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9BZGRyZXNzQm9vay9BZGRQZXJzb24uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvQWRkcmVzc0Jvb2svQWRkUGVyc29uLmNzCmRpZmYgLS1naXQgYS9zcmMvQWRkcmVzc0Jvb2svQWRkcmVzc0Jvb2suY3Nwcm9qIGIvY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9BZGRyZXNzQm9vay5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9BZGRyZXNzQm9vay9BZGRyZXNzQm9vay5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvQWRkcmVzc0Jvb2svQWRkcmVzc0Jvb2suY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvQWRkcmVzc0Jvb2svQWRkcmVzc0Jvb2tQcm90b3MuY3MgYi9jc2hhcnAvc3JjL0FkZHJlc3NCb29rL0FkZHJlc3NCb29rUHJvdG9zLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvQWRkcmVzc0Jvb2svQWRkcmVzc0Jvb2tQcm90b3MuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvQWRkcmVzc0Jvb2svQWRkcmVzc0Jvb2tQcm90b3MuY3MKZGlmZiAtLWdpdCBhL3NyYy9BZGRyZXNzQm9vay9MaXN0UGVvcGxlLmNzIGIvY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9MaXN0UGVvcGxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvQWRkcmVzc0Jvb2svTGlzdFBlb3BsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9MaXN0UGVvcGxlLmNzCmRpZmYgLS1naXQgYS9zcmMvQWRkcmVzc0Jvb2svUHJvZ3JhbS5jcyBiL2NzaGFycC9zcmMvQWRkcmVzc0Jvb2svUHJvZ3JhbS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL0FkZHJlc3NCb29rL1Byb2dyYW0uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvQWRkcmVzc0Jvb2svUHJvZ3JhbS5jcwpkaWZmIC0tZ2l0IGEvc3JjL0FkZHJlc3NCb29rL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzIGIvY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL0FkZHJlc3NCb29rL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL0FkZHJlc3NCb29rL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCmRpZmYgLS1naXQgYS9zcmMvQWRkcmVzc0Jvb2svU2FtcGxlVXNhZ2UuY3MgYi9jc2hhcnAvc3JjL0FkZHJlc3NCb29rL1NhbXBsZVVzYWdlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvQWRkcmVzc0Jvb2svU2FtcGxlVXNhZ2UuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvQWRkcmVzc0Jvb2svU2FtcGxlVXNhZ2UuY3MKZGlmZiAtLWdpdCBhL3NyYy9BZGRyZXNzQm9vay9hcHAuY29uZmlnIGIvY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9hcHAuY29uZmlnCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvQWRkcmVzc0Jvb2svYXBwLmNvbmZpZwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9BZGRyZXNzQm9vay9hcHAuY29uZmlnCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9CZW5jaC9Qcm9ncmFtLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0JlbmNoL1Byb2dyYW0uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0JlbmNoL1Byb2dyYW0uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9CZW5jaC9Qcm9ncmFtLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9CZW5jaC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9CZW5jaC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvQmVuY2gvUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9CZW5jaC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvUHJvdG9CZW5jaC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvQmVuY2gvUHJvdG9CZW5jaC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0JlbmNoL1Byb3RvQmVuY2guY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvQmVuY2gvUHJvdG9CZW5jaC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0JlbmNoL1Rlc3RQcm90b3MvR29vZ2xlU2l6ZVByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL0dvb2dsZVNpemVQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0JlbmNoL1Rlc3RQcm90b3MvR29vZ2xlU2l6ZVByb3RvRmlsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0JlbmNoL1Rlc3RQcm90b3MvR29vZ2xlU2l6ZVByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvVGVzdFByb3Rvcy9Hb29nbGVTcGVlZFByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL0dvb2dsZVNwZWVkUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL0dvb2dsZVNwZWVkUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvQmVuY2gvVGVzdFByb3Rvcy9Hb29nbGVTcGVlZFByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvVGVzdFByb3Rvcy9Vbml0VGVzdEltcG9ydFByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0UHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvQmVuY2gvVGVzdFByb3Rvcy9Vbml0VGVzdEltcG9ydFByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvVGVzdFByb3Rvcy9Vbml0VGVzdFByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL1VuaXRUZXN0UHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9CZW5jaC9UZXN0UHJvdG9zL1VuaXRUZXN0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvQmVuY2gvVGVzdFByb3Rvcy9Vbml0VGVzdFByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvQmVuY2gvZ29vZ2xlX21lc3NhZ2UxLmRhdCBiL2NzaGFycC9zcmMvUHJvdG9CZW5jaC9nb29nbGVfbWVzc2FnZTEuZGF0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9CZW5jaC9nb29nbGVfbWVzc2FnZTEuZGF0CnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvQmVuY2gvZ29vZ2xlX21lc3NhZ2UxLmRhdApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9CZW5jaC9nb29nbGVfbWVzc2FnZTIuZGF0IGIvY3NoYXJwL3NyYy9Qcm90b0JlbmNoL2dvb2dsZV9tZXNzYWdlMi5kYXQKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0JlbmNoL2dvb2dsZV9tZXNzYWdlMi5kYXQKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9CZW5jaC9nb29nbGVfbWVzc2FnZTIuZGF0CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0R1bXAvUHJvZ3JhbS5jcyBiL2NzaGFycC9zcmMvUHJvdG9EdW1wL1Byb2dyYW0uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0R1bXAvUHJvZ3JhbS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0R1bXAvUHJvZ3JhbS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvRHVtcC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9EdW1wL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9EdW1wL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvRHVtcC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvRHVtcC9Qcm90b0R1bXAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b0R1bXAvUHJvdG9EdW1wLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvRHVtcC9Qcm90b0R1bXAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvRHVtcC9Qcm90b0R1bXAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4uVGVzdC9EZXBlbmRlbmN5UmVzb2x1dGlvblRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuLlRlc3QvRGVwZW5kZW5jeVJlc29sdXRpb25UZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4uVGVzdC9EZXBlbmRlbmN5UmVzb2x1dGlvblRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4uVGVzdC9EZXBlbmRlbmN5UmVzb2x1dGlvblRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi5UZXN0L1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi5UZXN0L1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4uVGVzdC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi5UZXN0L1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4uVGVzdC9Qcm90b0dlbi5UZXN0LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9HZW4uVGVzdC9Qcm90b0dlbi5UZXN0LmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuLlRlc3QvUHJvdG9HZW4uVGVzdC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4uVGVzdC9Qcm90b0dlbi5UZXN0LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuLlRlc3QvUHJvdG9jR2VuQ3NVbml0dGVzdHMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuLlRlc3QvUHJvdG9jR2VuQ3NVbml0dGVzdHMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi5UZXN0L1Byb3RvY0dlbkNzVW5pdHRlc3RzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuLlRlc3QvUHJvdG9jR2VuQ3NVbml0dGVzdHMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi5UZXN0L1RlbXBGaWxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi5UZXN0L1RlbXBGaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4uVGVzdC9UZW1wRmlsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi5UZXN0L1RlbXBGaWxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4uVGVzdC9UZXN0UHJlcHJvY2Vzc2luZy5jcyBiL2NzaGFycC9zcmMvUHJvdG9HZW4uVGVzdC9UZXN0UHJlcHJvY2Vzc2luZy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuLlRlc3QvVGVzdFByZXByb2Nlc3NpbmcuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4uVGVzdC9UZXN0UHJlcHJvY2Vzc2luZy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuLlRlc3QvcHJvdG9jLWdlbi1jcy5UZXN0LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9HZW4uVGVzdC9wcm90b2MtZ2VuLWNzLlRlc3QuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4uVGVzdC9wcm90b2MtZ2VuLWNzLlRlc3QuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuLlRlc3QvcHJvdG9jLWdlbi1jcy5UZXN0LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL0RlcGVuZGVuY3lSZXNvbHV0aW9uRXhjZXB0aW9uLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9EZXBlbmRlbmN5UmVzb2x1dGlvbkV4Y2VwdGlvbi5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL0RlcGVuZGVuY3lSZXNvbHV0aW9uRXhjZXB0aW9uLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL0RlcGVuZGVuY3lSZXNvbHV0aW9uRXhjZXB0aW9uLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vRGVzY3JpcHRvclV0aWwuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL0Rlc2NyaXB0b3JVdGlsLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vRGVzY3JpcHRvclV0aWwuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vRGVzY3JpcHRvclV0aWwuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9FbnVtRmllbGRHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL0VudW1GaWVsZEdlbmVyYXRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL0VudW1GaWVsZEdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9FbnVtRmllbGRHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9FbnVtR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9FbnVtR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vRW51bUdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9FbnVtR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vRXh0ZW5zaW9uR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9FeHRlbnNpb25HZW5lcmF0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9FeHRlbnNpb25HZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vRXh0ZW5zaW9uR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vRmllbGRHZW5lcmF0b3JCYXNlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9GaWVsZEdlbmVyYXRvckJhc2UuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9GaWVsZEdlbmVyYXRvckJhc2UuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vRmllbGRHZW5lcmF0b3JCYXNlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9HZW5lcmF0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9HZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vR2VuZXJhdG9yT3B0aW9ucy5jcyBiL2NzaGFycC9zcmMvUHJvdG9HZW4vR2VuZXJhdG9yT3B0aW9ucy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL0dlbmVyYXRvck9wdGlvbnMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vR2VuZXJhdG9yT3B0aW9ucy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL0hlbHBlcnMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL0hlbHBlcnMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9IZWxwZXJzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL0hlbHBlcnMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9JRmllbGRTb3VyY2VHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL0lGaWVsZFNvdXJjZUdlbmVyYXRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL0lGaWVsZFNvdXJjZUdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9JRmllbGRTb3VyY2VHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9JU291cmNlR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9JU291cmNlR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vSVNvdXJjZUdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9JU291cmNlR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vSW52YWxpZE9wdGlvbnNFeGNlcHRpb24uY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL0ludmFsaWRPcHRpb25zRXhjZXB0aW9uLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vSW52YWxpZE9wdGlvbnNFeGNlcHRpb24uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vSW52YWxpZE9wdGlvbnNFeGNlcHRpb24uY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9NZXNzYWdlRmllbGRHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL01lc3NhZ2VGaWVsZEdlbmVyYXRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL01lc3NhZ2VGaWVsZEdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9NZXNzYWdlRmllbGRHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9NZXNzYWdlR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9NZXNzYWdlR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vTWVzc2FnZUdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9NZXNzYWdlR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vUGx1Z2luUHJvdG9GaWxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9QbHVnaW5Qcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9QbHVnaW5Qcm90b0ZpbGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vUGx1Z2luUHJvdG9GaWxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9Qcm9ncmFtLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9Qcm9ncmFtLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vUHJvZ3JhbS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9Qcm9ncmFtLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vUHJvZ3JhbVByZXByb2Nlc3MuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL1Byb2dyYW1QcmVwcm9jZXNzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vUHJvZ3JhbVByZXByb2Nlc3MuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vUHJvZ3JhbVByZXByb2Nlc3MuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9HZW4vUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL1Byb3RvR2VuLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9HZW4vUHJvdG9HZW4uY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vUHJvdG9HZW4uY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL1Byb3RvR2VuLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL1Byb3RvY0dlbkNzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9Qcm90b2NHZW5Dcy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL1Byb3RvY0dlbkNzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL1Byb3RvY0dlbkNzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL1JlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9SZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9HZW4vUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9SZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9SZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9SZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9TZXJ2aWNlR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9TZXJ2aWNlR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vU2VydmljZUdlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9TZXJ2aWNlR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vU2VydmljZUludGVyZmFjZUdlbmVyYXRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9HZW4vU2VydmljZUludGVyZmFjZUdlbmVyYXRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL1NlcnZpY2VJbnRlcmZhY2VHZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vU2VydmljZUludGVyZmFjZUdlbmVyYXRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL1NvdXJjZUdlbmVyYXRvckJhc2UuY3MgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL1NvdXJjZUdlbmVyYXRvckJhc2UuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9Tb3VyY2VHZW5lcmF0b3JCYXNlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL1NvdXJjZUdlbmVyYXRvckJhc2UuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9Tb3VyY2VHZW5lcmF0b3JzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b0dlbi9Tb3VyY2VHZW5lcmF0b3JzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9HZW4vU291cmNlR2VuZXJhdG9ycy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9Tb3VyY2VHZW5lcmF0b3JzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9HZW4vVW1icmVsbGFDbGFzc0dlbmVyYXRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9HZW4vVW1icmVsbGFDbGFzc0dlbmVyYXRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvR2VuL1VtYnJlbGxhQ2xhc3NHZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9HZW4vVW1icmVsbGFDbGFzc0dlbmVyYXRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvR2VuL2FwcC5jb25maWcgYi9jc2hhcnAvc3JjL1Byb3RvR2VuL2FwcC5jb25maWcKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9hcHAuY29uZmlnCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvR2VuL2FwcC5jb25maWcKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b0dlbi9wcm90b2MtZ2VuLWNzLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9HZW4vcHJvdG9jLWdlbi1jcy5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b0dlbi9wcm90b2MtZ2VuLWNzLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b0dlbi9wcm90b2MtZ2VuLWNzLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvTXVuZ2UvUHJvZ3JhbS5jcyBiL2NzaGFycC9zcmMvUHJvdG9NdW5nZS9Qcm9ncmFtLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9NdW5nZS9Qcm9ncmFtLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvTXVuZ2UvUHJvZ3JhbS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvTXVuZ2UvUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MgYi9jc2hhcnAvc3JjL1Byb3RvTXVuZ2UvUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b011bmdlL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvTXVuZ2UvUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b011bmdlL1Byb3RvTXVuZ2UuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b011bmdlL1Byb3RvTXVuZ2UuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9NdW5nZS9Qcm90b011bmdlLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b011bmdlL1Byb3RvTXVuZ2UuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vQWJzdHJhY3RSZWFkZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0Fic3RyYWN0UmVhZGVyLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vQWJzdHJhY3RSZWFkZXIuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vQWJzdHJhY3RSZWFkZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFRleHRSZWFkZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0Fic3RyYWN0VGV4dFJlYWRlci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0Fic3RyYWN0VGV4dFJlYWRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFRleHRSZWFkZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFRleHRXcml0ZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0Fic3RyYWN0VGV4dFdyaXRlci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0Fic3RyYWN0VGV4dFdyaXRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFRleHRXcml0ZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFdyaXRlci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vQWJzdHJhY3RXcml0ZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFdyaXRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9BYnN0cmFjdFdyaXRlci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0RpY3Rpb25hcnlSZWFkZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0RpY3Rpb25hcnlSZWFkZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9EaWN0aW9uYXJ5UmVhZGVyLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0RpY3Rpb25hcnlSZWFkZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9EaWN0aW9uYXJ5V3JpdGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9EaWN0aW9uYXJ5V3JpdGVyLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vRGljdGlvbmFyeVdyaXRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9EaWN0aW9uYXJ5V3JpdGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vRXh0ZW5zaW9ucy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vRXh0ZW5zaW9ucy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0V4dGVuc2lvbnMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vRXh0ZW5zaW9ucy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0h0dHAvRm9ybVVybEVuY29kZWRSZWFkZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0h0dHAvRm9ybVVybEVuY29kZWRSZWFkZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9IdHRwL0Zvcm1VcmxFbmNvZGVkUmVhZGVyLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0h0dHAvRm9ybVVybEVuY29kZWRSZWFkZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9IdHRwL01lc3NhZ2VGb3JtYXRGYWN0b3J5LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9IdHRwL01lc3NhZ2VGb3JtYXRGYWN0b3J5LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSHR0cC9NZXNzYWdlRm9ybWF0RmFjdG9yeS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9IdHRwL01lc3NhZ2VGb3JtYXRGYWN0b3J5LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSHR0cC9NZXNzYWdlRm9ybWF0T3B0aW9ucy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSHR0cC9NZXNzYWdlRm9ybWF0T3B0aW9ucy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0h0dHAvTWVzc2FnZUZvcm1hdE9wdGlvbnMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSHR0cC9NZXNzYWdlRm9ybWF0T3B0aW9ucy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0pzb25Gb3JtYXRSZWFkZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0pzb25Gb3JtYXRSZWFkZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Kc29uRm9ybWF0UmVhZGVyLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0pzb25Gb3JtYXRSZWFkZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Kc29uRm9ybWF0V3JpdGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Kc29uRm9ybWF0V3JpdGVyLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSnNvbkZvcm1hdFdyaXRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Kc29uRm9ybWF0V3JpdGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSnNvblRleHRDdXJzb3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL0pzb25UZXh0Q3Vyc29yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSnNvblRleHRDdXJzb3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vSnNvblRleHRDdXJzb3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLkNGMjAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5DRjIwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLkNGMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLkNGMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uQ0YzNS5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLkNGMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uQ0YzNS5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uQ0YzNS5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5ORVQyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLk5FVDIwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLk5FVDIwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5ORVQyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5ORVQzNS5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLk5FVDM1LmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLk5FVDM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5ORVQzNS5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5ORVQ0MC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLk5FVDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLk5FVDQwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5ORVQ0MC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5QTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uUEw0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5QTDQwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5QTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLlNMMjAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5TTDIwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLlNMMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLlNMMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uU0wzMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLlNMMzAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uU0wzMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uU0wzMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5TTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uU0w0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5TTDQwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi5TTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24uY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5DRjIwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLkNGMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLkNGMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5DRjIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5DRjM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLkNGMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLkNGMzUuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5DRjM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5ORVQyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5ORVQyMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNlcmlhbGl6YXRpb24uTkVUMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5ORVQyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNlcmlhbGl6YXRpb24uTkVUMzUuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNlcmlhbGl6YXRpb24uTkVUMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLk5FVDM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNlcmlhbGl6YXRpb24uTkVUMzUuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLk5FVDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLk5FVDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5ORVQ0MC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLk5FVDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5QTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlBMNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlBMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5QTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5TTDIwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlNMMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlNMMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5TTDIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5TTDMwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlNMMzAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlNMMzAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5TTDMwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5TTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlNMNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUHJvdG9jb2xCdWZmZXJzTGl0ZS5TZXJpYWxpemF0aW9uLlNMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5TTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNlcmlhbGl6YXRpb24uY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1Byb3RvY29sQnVmZmVyc0xpdGUuU2VyaWFsaXphdGlvbi5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9SZWN1cnNpb25MaW1pdEV4Y2VlZGVkLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9SZWN1cnNpb25MaW1pdEV4Y2VlZGVkLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vUmVjdXJzaW9uTGltaXRFeGNlZWRlZC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9SZWN1cnNpb25MaW1pdEV4Y2VlZGVkLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sRm9ybWF0UmVhZGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9YbWxGb3JtYXRSZWFkZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9YbWxGb3JtYXRSZWFkZXIuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sRm9ybWF0UmVhZGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sRm9ybWF0V3JpdGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9YbWxGb3JtYXRXcml0ZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9YbWxGb3JtYXRXcml0ZXIuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sRm9ybWF0V3JpdGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sUmVhZGVyT3B0aW9ucy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sUmVhZGVyT3B0aW9ucy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1htbFJlYWRlck9wdGlvbnMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlNlcmlhbGl6YXRpb24vWG1sUmVhZGVyT3B0aW9ucy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1htbFdyaXRlck9wdGlvbnMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1htbFdyaXRlck9wdGlvbnMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuU2VyaWFsaXphdGlvbi9YbWxXcml0ZXJPcHRpb25zLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5TZXJpYWxpemF0aW9uL1htbFdyaXRlck9wdGlvbnMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9BYnN0cmFjdE1lc3NhZ2VUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9BYnN0cmFjdE1lc3NhZ2VUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQWJzdHJhY3RNZXNzYWdlVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9BYnN0cmFjdE1lc3NhZ2VUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQXBwLnhhbWwgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0FwcC54YW1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQXBwLnhhbWwKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQXBwLnhhbWwKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9BcHAueGFtbC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQXBwLnhhbWwuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9BcHAueGFtbC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9BcHAueGFtbC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0J5dGVTdHJpbmdUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9CeXRlU3RyaW5nVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0J5dGVTdHJpbmdUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0J5dGVTdHJpbmdUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ1NoYXJwT3B0aW9uc1Rlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NTaGFycE9wdGlvbnNUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ1NoYXJwT3B0aW9uc1Rlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ1NoYXJwT3B0aW9uc1Rlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db2RlZElucHV0U3RyZWFtVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29kZWRJbnB1dFN0cmVhbVRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db2RlZElucHV0U3RyZWFtVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db2RlZElucHV0U3RyZWFtVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvZGVkT3V0cHV0U3RyZWFtVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29kZWRPdXRwdXRTdHJlYW1UZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29kZWRPdXRwdXRTdHJlYW1UZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvZGVkT3V0cHV0U3RyZWFtVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbGxlY3Rpb25zL1BvcHNpY2xlTGlzdFRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbGxlY3Rpb25zL1BvcHNpY2xlTGlzdFRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db2xsZWN0aW9ucy9Qb3BzaWNsZUxpc3RUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbGxlY3Rpb25zL1BvcHNpY2xlTGlzdFRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0JpbmFyeUNvbXBhdGliaWxpdHlUZXN0cy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9CaW5hcnlDb21wYXRpYmlsaXR5VGVzdHMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0JpbmFyeUNvbXBhdGliaWxpdHlUZXN0cy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0JpbmFyeUNvbXBhdGliaWxpdHlUZXN0cy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvQ29tcGF0aWJpbGl0eVRlc3RzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0NvbXBhdGliaWxpdHlUZXN0cy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvQ29tcGF0aWJpbGl0eVRlc3RzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvQ29tcGF0aWJpbGl0eVRlc3RzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9EaWN0aW9uYXJ5Q29tcGF0aWJpbGl0eVRlc3RzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0RpY3Rpb25hcnlDb21wYXRpYmlsaXR5VGVzdHMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0RpY3Rpb25hcnlDb21wYXRpYmlsaXR5VGVzdHMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9EaWN0aW9uYXJ5Q29tcGF0aWJpbGl0eVRlc3RzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9Kc29uQ29tcGF0aWJpbGl0eVRlc3RzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0pzb25Db21wYXRpYmlsaXR5VGVzdHMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L0pzb25Db21wYXRpYmlsaXR5VGVzdHMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9Kc29uQ29tcGF0aWJpbGl0eVRlc3RzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9UZXN0UmVzb3VyY2VzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L1Rlc3RSZXNvdXJjZXMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L1Rlc3RSZXNvdXJjZXMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9UZXN0UmVzb3VyY2VzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9UZXh0Q29tcGF0aWJpbGl0eVRlc3RzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L1RleHRDb21wYXRpYmlsaXR5VGVzdHMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L1RleHRDb21wYXRpYmlsaXR5VGVzdHMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9UZXh0Q29tcGF0aWJpbGl0eVRlc3RzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9YbWxDb21wYXRpYmlsaXR5VGVzdHMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvWG1sQ29tcGF0aWJpbGl0eVRlc3RzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9YbWxDb21wYXRpYmlsaXR5VGVzdHMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9YbWxDb21wYXRpYmlsaXR5VGVzdHMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L2dvb2dsZV9tZXNzYWdlMS5kYXQgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvZ29vZ2xlX21lc3NhZ2UxLmRhdApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvZ29vZ2xlX21lc3NhZ2UxLmRhdApyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Db21wYXRpYmlsaXR5L2dvb2dsZV9tZXNzYWdlMS5kYXQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvZ29vZ2xlX21lc3NhZ2UyLmRhdCBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9nb29nbGVfbWVzc2FnZTIuZGF0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvQ29tcGF0aWJpbGl0eS9nb29nbGVfbWVzc2FnZTIuZGF0CnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0NvbXBhdGliaWxpdHkvZ29vZ2xlX21lc3NhZ2UyLmRhdApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvRGVwcmVjYXRlZE1lbWJlclRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0RlcHJlY2F0ZWRNZW1iZXJUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvRGVwcmVjYXRlZE1lbWJlclRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvRGVwcmVjYXRlZE1lbWJlclRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9EZXNjcmlwdG9ycy9NZXNzYWdlRGVzY3JpcHRvclRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0Rlc2NyaXB0b3JzL01lc3NhZ2VEZXNjcmlwdG9yVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0Rlc2NyaXB0b3JzL01lc3NhZ2VEZXNjcmlwdG9yVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9EZXNjcmlwdG9ycy9NZXNzYWdlRGVzY3JpcHRvclRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9EZXNjcmlwdG9yc1Rlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0Rlc2NyaXB0b3JzVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0Rlc2NyaXB0b3JzVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9EZXNjcmlwdG9yc1Rlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9EeW5hbWljTWVzc2FnZVRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0R5bmFtaWNNZXNzYWdlVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0R5bmFtaWNNZXNzYWdlVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9EeW5hbWljTWVzc2FnZVRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9FeHRlbmRhYmxlTWVzc2FnZVRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0V4dGVuZGFibGVNZXNzYWdlVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0V4dGVuZGFibGVNZXNzYWdlVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9FeHRlbmRhYmxlTWVzc2FnZVRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9HZW5lcmF0ZWRCdWlsZGVyVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvR2VuZXJhdGVkQnVpbGRlclRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9HZW5lcmF0ZWRCdWlsZGVyVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9HZW5lcmF0ZWRCdWlsZGVyVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0dlbmVyYXRlZE1lc3NhZ2VUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9HZW5lcmF0ZWRNZXNzYWdlVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0dlbmVyYXRlZE1lc3NhZ2VUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0dlbmVyYXRlZE1lc3NhZ2VUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvSXNzdWVzVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvSXNzdWVzVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L0lzc3Vlc1Rlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvSXNzdWVzVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L01lc3NhZ2VTdHJlYW1JdGVyYXRvclRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L01lc3NhZ2VTdHJlYW1JdGVyYXRvclRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlU3RyZWFtSXRlcmF0b3JUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L01lc3NhZ2VTdHJlYW1JdGVyYXRvclRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlU3RyZWFtV3JpdGVyVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvTWVzc2FnZVN0cmVhbVdyaXRlclRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlU3RyZWFtV3JpdGVyVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlU3RyZWFtV3JpdGVyVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L01lc3NhZ2VUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L01lc3NhZ2VUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L01lc3NhZ2VUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvTWVzc2FnZVV0aWxUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlVXRpbFRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9NZXNzYWdlVXRpbFRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvTWVzc2FnZVV0aWxUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvTmFtZUhlbHBlcnNUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9OYW1lSGVscGVyc1Rlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9OYW1lSGVscGVyc1Rlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvTmFtZUhlbHBlcnNUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvcGVydGllcy9BcHBNYW5pZmVzdC54bWwgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3BlcnRpZXMvQXBwTWFuaWZlc3QueG1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvcGVydGllcy9BcHBNYW5pZmVzdC54bWwKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvcGVydGllcy9BcHBNYW5pZmVzdC54bWwKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvcGVydGllcy9Bc3NlbWJseUluZm8uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3BlcnRpZXMvT3V0T2ZCcm93c2VyU2V0dGluZ3MueG1sIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm9wZXJ0aWVzL091dE9mQnJvd3NlclNldHRpbmdzLnhtbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3BlcnRpZXMvT3V0T2ZCcm93c2VyU2V0dGluZ3MueG1sCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3BlcnRpZXMvT3V0T2ZCcm93c2VyU2V0dGluZ3MueG1sCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuQ0YyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LkNGMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuQ0YyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuQ0YyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5DRjM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuQ0YzNS5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5DRjM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5DRjM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0Lk5FVDIwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuTkVUMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuTkVUMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0Lk5FVDIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0Lk5FVDM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuTkVUMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuTkVUMzUuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0Lk5FVDM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0Lk5FVDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuTkVUNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuTkVUNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0Lk5FVDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlBMNDAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5QTDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlBMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlBMNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuU0wyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlNMMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuU0wyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuU0wyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5TTDMwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuU0wzMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5TTDMwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5TTDMwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlNMNDAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5TTDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlNMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Byb3RvY29sQnVmZmVycy5UZXN0LlNMNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUHJvdG9jb2xCdWZmZXJzLlRlc3QuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUmVmbGVjdGlvblRlc3Rlci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUmVmbGVjdGlvblRlc3Rlci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1JlZmxlY3Rpb25UZXN0ZXIuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvUmVmbGVjdGlvblRlc3Rlci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1JldXNhYmxlQnVpbGRlclRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1JldXNhYmxlQnVpbGRlclRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9SZXVzYWJsZUJ1aWxkZXJUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1JldXNhYmxlQnVpbGRlclRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9TZXJpYWxpemFibGVBdHRyaWJ1dGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1NlcmlhbGl6YWJsZUF0dHJpYnV0ZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1NlcmlhbGl6YWJsZUF0dHJpYnV0ZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9TZXJpYWxpemFibGVBdHRyaWJ1dGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9TZXJpYWxpemFibGVUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9TZXJpYWxpemFibGVUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvU2VyaWFsaXphYmxlVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9TZXJpYWxpemFibGVUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvU2VydmljZVRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1NlcnZpY2VUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvU2VydmljZVRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvU2VydmljZVRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0Q29ybmVyQ2FzZXMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RDb3JuZXJDYXNlcy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RDb3JuZXJDYXNlcy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0Q29ybmVyQ2FzZXMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0TWltZU1lc3NhZ2VGb3JtYXRzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0TWltZU1lc3NhZ2VGb3JtYXRzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdE1pbWVNZXNzYWdlRm9ybWF0cy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0TWltZU1lc3NhZ2VGb3JtYXRzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdENTaGFycE9wdGlvbnNQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RDU2hhcnBPcHRpb25zUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdENTaGFycE9wdGlvbnNQcm90b0ZpbGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdENTaGFycE9wdGlvbnNQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0Q3VzdG9tT3B0aW9uc1Byb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEN1c3RvbU9wdGlvbnNQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0Q3VzdG9tT3B0aW9uc1Byb3RvRmlsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0Q3VzdG9tT3B0aW9uc1Byb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFbWJlZE9wdGltaXplRm9yUHJvdG9GaWxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RW1iZWRPcHRpbWl6ZUZvclByb3RvRmlsZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFbWJlZE9wdGltaXplRm9yUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFbWJlZE9wdGltaXplRm9yUHJvdG9GaWxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEVtcHR5UHJvdG9GaWxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RW1wdHlQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RW1wdHlQcm90b0ZpbGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEVtcHR5UHJvdG9GaWxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEV4dHJhc0lzc3Vlc1Byb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEV4dHJhc0lzc3Vlc1Byb3RvRmlsZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNJc3N1ZXNQcm90b0ZpbGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEV4dHJhc0lzc3Vlc1Byb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RXh0cmFzUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0R2VuZXJpY1NlcnZpY2VzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0R2VuZXJpY1NlcnZpY2VzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEdlbmVyaWNTZXJ2aWNlcy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0R2VuZXJpY1NlcnZpY2VzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEdvb2dsZVNpemVQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RHb29nbGVTaXplUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEdvb2dsZVNpemVQcm90b0ZpbGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEdvb2dsZVNpemVQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0R29vZ2xlU3BlZWRQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RHb29nbGVTcGVlZFByb3RvRmlsZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RHb29nbGVTcGVlZFByb3RvRmlsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0R29vZ2xlU3BlZWRQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0TGl0ZVByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEltcG9ydExpdGVQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0TGl0ZVByb3RvRmlsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0TGl0ZVByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RJbXBvcnRQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RJbXBvcnRQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RJbXBvcnRQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0TWVzc2FnZVNldFByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdE1lc3NhZ2VTZXRQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0TWVzc2FnZVNldFByb3RvRmlsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0TWVzc2FnZVNldFByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3ROb0dlbmVyaWNTZXJ2aWNlc1Byb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdE5vR2VuZXJpY1NlcnZpY2VzUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdE5vR2VuZXJpY1NlcnZpY2VzUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3ROb0dlbmVyaWNTZXJ2aWNlc1Byb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RPcHRpbWl6ZUZvclByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdE9wdGltaXplRm9yUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdE9wdGltaXplRm9yUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RPcHRpbWl6ZUZvclByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UnBjSW50ZXJvcC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdFJwY0ludGVyb3AuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UnBjSW50ZXJvcC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UnBjSW50ZXJvcC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RYbWxTZXJpYWxpemVyVGVzdFByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdFhtbFNlcmlhbGl6ZXJUZXN0UHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdFhtbFNlcmlhbGl6ZXJUZXN0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RYbWxTZXJpYWxpemVyVGVzdFByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RSZWFkZXJGb3JVcmxFbmNvZGVkLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UmVhZGVyRm9yVXJsRW5jb2RlZC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RSZWFkZXJGb3JVcmxFbmNvZGVkLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RSZWFkZXJGb3JVcmxFbmNvZGVkLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFJlc291cmNlcy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFJlc291cmNlcy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RSZXNvdXJjZXMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFJlc291cmNlcy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RScGNGb3JNaW1lVHlwZXMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RScGNGb3JNaW1lVHlwZXMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UnBjRm9yTWltZVR5cGVzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RScGNGb3JNaW1lVHlwZXMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UnBjR2VuZXJhdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UnBjR2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFJwY0dlbmVyYXRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0UnBjR2VuZXJhdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFV0aWwuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RVdGlsLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFV0aWwuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFV0aWwuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0V3JpdGVyRm9ybWF0SnNvbi5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGVzdFdyaXRlckZvcm1hdEpzb24uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0V3JpdGVyRm9ybWF0SnNvbi5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0V3JpdGVyRm9ybWF0SnNvbi5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RXcml0ZXJGb3JtYXRYbWwuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RXcml0ZXJGb3JtYXRYbWwuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXN0V3JpdGVyRm9ybWF0WG1sLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Rlc3RXcml0ZXJGb3JtYXRYbWwuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXh0Rm9ybWF0VGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvVGV4dEZvcm1hdFRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXh0Rm9ybWF0VGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9UZXh0Rm9ybWF0VGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Vua25vd25GaWVsZFNldFRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Vua25vd25GaWVsZFNldFRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9Vbmtub3duRmllbGRTZXRUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5UZXN0L1Vua25vd25GaWVsZFNldFRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9XaXJlRm9ybWF0VGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzLlRlc3QvV2lyZUZvcm1hdFRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9XaXJlRm9ybWF0VGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMuVGVzdC9XaXJlRm9ybWF0VGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy5zbG4gYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5zbG4Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMuc2xuCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy5zbG4KZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQWJzdHJhY3RCdWlsZGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQWJzdHJhY3RCdWlsZGVyLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0QnVpbGRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQWJzdHJhY3RCdWlsZGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0QnVpbGRlckxpdGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9BYnN0cmFjdEJ1aWxkZXJMaXRlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0QnVpbGRlckxpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0QnVpbGRlckxpdGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQWJzdHJhY3RNZXNzYWdlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQWJzdHJhY3RNZXNzYWdlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0TWVzc2FnZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQWJzdHJhY3RNZXNzYWdlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0TWVzc2FnZUxpdGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9BYnN0cmFjdE1lc3NhZ2VMaXRlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0TWVzc2FnZUxpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Fic3RyYWN0TWVzc2FnZUxpdGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQnl0ZUFycmF5LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQnl0ZUFycmF5LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0J5dGVBcnJheS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQnl0ZUFycmF5LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0J5dGVTdHJpbmcuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9CeXRlU3RyaW5nLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0J5dGVTdHJpbmcuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0J5dGVTdHJpbmcuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29kZWRJbnB1dFN0cmVhbS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0NvZGVkSW5wdXRTdHJlYW0uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29kZWRJbnB1dFN0cmVhbS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29kZWRJbnB1dFN0cmVhbS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Db2RlZE91dHB1dFN0cmVhbS5Db21wdXRlU2l6ZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0NvZGVkT3V0cHV0U3RyZWFtLkNvbXB1dGVTaXplLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0NvZGVkT3V0cHV0U3RyZWFtLkNvbXB1dGVTaXplLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2RlZE91dHB1dFN0cmVhbS5Db21wdXRlU2l6ZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Db2RlZE91dHB1dFN0cmVhbS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0NvZGVkT3V0cHV0U3RyZWFtLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0NvZGVkT3V0cHV0U3RyZWFtLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2RlZE91dHB1dFN0cmVhbS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9EaWN0aW9uYXJpZXMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9EaWN0aW9uYXJpZXMuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvRGljdGlvbmFyaWVzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9EaWN0aW9uYXJpZXMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvRW51bWVyYWJsZXMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9FbnVtZXJhYmxlcy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9FbnVtZXJhYmxlcy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvRW51bWVyYWJsZXMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvSVBvcHNpY2xlTGlzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0NvbGxlY3Rpb25zL0lQb3BzaWNsZUxpc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvSVBvcHNpY2xlTGlzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvSVBvcHNpY2xlTGlzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9MaXN0cy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0NvbGxlY3Rpb25zL0xpc3RzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0NvbGxlY3Rpb25zL0xpc3RzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9MaXN0cy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9Qb3BzaWNsZUxpc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9Qb3BzaWNsZUxpc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvUG9wc2ljbGVMaXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Db2xsZWN0aW9ucy9Qb3BzaWNsZUxpc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvUmVhZE9ubHlEaWN0aW9uYXJ5LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvUmVhZE9ubHlEaWN0aW9uYXJ5LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0NvbGxlY3Rpb25zL1JlYWRPbmx5RGljdGlvbmFyeS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvQ29sbGVjdGlvbnMvUmVhZE9ubHlEaWN0aW9uYXJ5LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0N1c3RvbVNlcmlhbGl6YXRpb24uY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9DdXN0b21TZXJpYWxpemF0aW9uLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0N1c3RvbVNlcmlhbGl6YXRpb24uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0N1c3RvbVNlcmlhbGl6YXRpb24uY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVsZWdhdGVzLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVsZWdhdGVzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0RlbGVnYXRlcy5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVsZWdhdGVzLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvQ1NoYXJwT3B0aW9ucy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvQ1NoYXJwT3B0aW9ucy5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9yUHJvdG9zL0NTaGFycE9wdGlvbnMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvQ1NoYXJwT3B0aW9ucy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9yUHJvdG9zL0Rlc2NyaXB0b3JQcm90b0ZpbGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9yUHJvdG9zL0Rlc2NyaXB0b3JQcm90b0ZpbGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvclByb3Rvcy9EZXNjcmlwdG9yUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9yUHJvdG9zL0Rlc2NyaXB0b3JQcm90b0ZpbGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvclByb3Rvcy9JRGVzY3JpcHRvclByb3RvLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvclByb3Rvcy9JRGVzY3JpcHRvclByb3RvLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvSURlc2NyaXB0b3JQcm90by5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvclByb3Rvcy9JRGVzY3JpcHRvclByb3RvLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvUGFydGlhbENsYXNzZXMuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9yUHJvdG9zL1BhcnRpYWxDbGFzc2VzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvUGFydGlhbENsYXNzZXMuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JQcm90b3MvUGFydGlhbENsYXNzZXMuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvckJhc2UuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yQmFzZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yQmFzZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvckJhc2UuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvclBvb2wuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yUG9vbC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yUG9vbC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvclBvb2wuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvclV0aWwuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yVXRpbC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yVXRpbC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvclV0aWwuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24uY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbi5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9EZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbi5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24uY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRW51bURlc2NyaXB0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9FbnVtRGVzY3JpcHRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9FbnVtRGVzY3JpcHRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRW51bURlc2NyaXB0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRW51bVZhbHVlRGVzY3JpcHRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0VudW1WYWx1ZURlc2NyaXB0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRW51bVZhbHVlRGVzY3JpcHRvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRW51bVZhbHVlRGVzY3JpcHRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9GaWVsZERlc2NyaXB0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9GaWVsZERlc2NyaXB0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRmllbGREZXNjcmlwdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9GaWVsZERlc2NyaXB0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRmllbGRNYXBwaW5nQXR0cmlidXRlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRmllbGRNYXBwaW5nQXR0cmlidXRlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0ZpZWxkTWFwcGluZ0F0dHJpYnV0ZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvRmllbGRNYXBwaW5nQXR0cmlidXRlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0ZpZWxkVHlwZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0ZpZWxkVHlwZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9GaWVsZFR5cGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0ZpZWxkVHlwZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9GaWxlRGVzY3JpcHRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0ZpbGVEZXNjcmlwdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0ZpbGVEZXNjcmlwdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9GaWxlRGVzY3JpcHRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9JRGVzY3JpcHRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0lEZXNjcmlwdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL0lEZXNjcmlwdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9JRGVzY3JpcHRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9JbmRleGVkRGVzY3JpcHRvckJhc2UuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9JbmRleGVkRGVzY3JpcHRvckJhc2UuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvSW5kZXhlZERlc2NyaXB0b3JCYXNlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9JbmRleGVkRGVzY3JpcHRvckJhc2UuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvTWFwcGVkVHlwZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL01hcHBlZFR5cGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvTWFwcGVkVHlwZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvTWFwcGVkVHlwZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9NZXNzYWdlRGVzY3JpcHRvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL01lc3NhZ2VEZXNjcmlwdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL01lc3NhZ2VEZXNjcmlwdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9NZXNzYWdlRGVzY3JpcHRvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9NZXRob2REZXNjcmlwdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvTWV0aG9kRGVzY3JpcHRvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9NZXRob2REZXNjcmlwdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9EZXNjcmlwdG9ycy9NZXRob2REZXNjcmlwdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL1BhY2thZ2VEZXNjcmlwdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvUGFja2FnZURlc2NyaXB0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvUGFja2FnZURlc2NyaXB0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL1BhY2thZ2VEZXNjcmlwdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL1NlcnZpY2VEZXNjcmlwdG9yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvU2VydmljZURlc2NyaXB0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRGVzY3JpcHRvcnMvU2VydmljZURlc2NyaXB0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0Rlc2NyaXB0b3JzL1NlcnZpY2VEZXNjcmlwdG9yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0R5bmFtaWNNZXNzYWdlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRHluYW1pY01lc3NhZ2UuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRHluYW1pY01lc3NhZ2UuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0R5bmFtaWNNZXNzYWdlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0VudW1MaXRlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRW51bUxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRW51bUxpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0VudW1MaXRlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVCdWlsZGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5kYWJsZUJ1aWxkZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5kYWJsZUJ1aWxkZXIuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVCdWlsZGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVCdWlsZGVyTGl0ZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVCdWlsZGVyTGl0ZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbmRhYmxlQnVpbGRlckxpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVCdWlsZGVyTGl0ZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbmRhYmxlTWVzc2FnZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVNZXNzYWdlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuZGFibGVNZXNzYWdlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbmRhYmxlTWVzc2FnZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbmRhYmxlTWVzc2FnZUxpdGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbmRhYmxlTWVzc2FnZUxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5kYWJsZU1lc3NhZ2VMaXRlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbmRhYmxlTWVzc2FnZUxpdGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5zaW9uSW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuc2lvbkluZm8uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5zaW9uSW5mby5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5zaW9uSW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbnNpb25SZWdpc3RyeS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuc2lvblJlZ2lzdHJ5LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0V4dGVuc2lvblJlZ2lzdHJ5LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbnNpb25SZWdpc3RyeS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbnNpb25SZWdpc3RyeUxpdGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbnNpb25SZWdpc3RyeUxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9FeHRlbnNpb25SZWdpc3RyeUxpdGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvRmllbGRBY2Nlc3NvclRhYmxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvRmllbGRBY2Nlc3NvclRhYmxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL0ZpZWxkQWNjZXNzb3JUYWJsZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvRmllbGRBY2Nlc3NvclRhYmxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL0lGaWVsZEFjY2Vzc29yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvSUZpZWxkQWNjZXNzb3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvSUZpZWxkQWNjZXNzb3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL0lGaWVsZEFjY2Vzc29yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlZmxlY3Rpb25VdGlsLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvUmVmbGVjdGlvblV0aWwuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvUmVmbGVjdGlvblV0aWwuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlZmxlY3Rpb25VdGlsLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkRW51bUFjY2Vzc29yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvUmVwZWF0ZWRFbnVtQWNjZXNzb3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvUmVwZWF0ZWRFbnVtQWNjZXNzb3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkRW51bUFjY2Vzc29yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkTWVzc2FnZUFjY2Vzc29yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvUmVwZWF0ZWRNZXNzYWdlQWNjZXNzb3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvUmVwZWF0ZWRNZXNzYWdlQWNjZXNzb3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkTWVzc2FnZUFjY2Vzc29yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkUHJpbWl0aXZlQWNjZXNzb3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9GaWVsZEFjY2Vzcy9SZXBlYXRlZFByaW1pdGl2ZUFjY2Vzc29yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkUHJpbWl0aXZlQWNjZXNzb3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1JlcGVhdGVkUHJpbWl0aXZlQWNjZXNzb3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvU2luZ2xlRW51bUFjY2Vzc29yLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvU2luZ2xlRW51bUFjY2Vzc29yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1NpbmdsZUVudW1BY2Nlc3Nvci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvRmllbGRBY2Nlc3MvU2luZ2xlRW51bUFjY2Vzc29yLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1NpbmdsZU1lc3NhZ2VBY2Nlc3Nvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1NpbmdsZU1lc3NhZ2VBY2Nlc3Nvci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9GaWVsZEFjY2Vzcy9TaW5nbGVNZXNzYWdlQWNjZXNzb3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1NpbmdsZU1lc3NhZ2VBY2Nlc3Nvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9GaWVsZEFjY2Vzcy9TaW5nbGVQcmltaXRpdmVBY2Nlc3Nvci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1NpbmdsZVByaW1pdGl2ZUFjY2Vzc29yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkQWNjZXNzL1NpbmdsZVByaW1pdGl2ZUFjY2Vzc29yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9GaWVsZEFjY2Vzcy9TaW5nbGVQcmltaXRpdmVBY2Nlc3Nvci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9GaWVsZFNldC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkU2V0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0ZpZWxkU2V0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9GaWVsZFNldC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9GcmFtZXdvcmtQb3J0YWJpbGl0eS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ZyYW1ld29ya1BvcnRhYmlsaXR5LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0ZyYW1ld29ya1BvcnRhYmlsaXR5LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9GcmFtZXdvcmtQb3J0YWJpbGl0eS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRCdWlsZGVyLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkQnVpbGRlci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRCdWlsZGVyLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRCdWlsZGVyLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZEJ1aWxkZXJMaXRlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkQnVpbGRlckxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkQnVpbGRlckxpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZEJ1aWxkZXJMaXRlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZEV4dGVuc2lvbkJhc2UuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRFeHRlbnNpb25CYXNlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZEV4dGVuc2lvbkJhc2UuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZEV4dGVuc2lvbkJhc2UuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkRXh0ZW5zaW9uTGl0ZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZEV4dGVuc2lvbkxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkRXh0ZW5zaW9uTGl0ZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkRXh0ZW5zaW9uTGl0ZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRNZXNzYWdlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkTWVzc2FnZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRNZXNzYWdlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRNZXNzYWdlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZE1lc3NhZ2VMaXRlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkTWVzc2FnZUxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkTWVzc2FnZUxpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZE1lc3NhZ2VMaXRlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZFJlcGVhdEV4dGVuc2lvbi5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZFJlcGVhdEV4dGVuc2lvbi5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRSZXBlYXRFeHRlbnNpb24uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0dlbmVyYXRlZFJlcGVhdEV4dGVuc2lvbi5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRTaW5nbGVFeHRlbnNpb24uY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRTaW5nbGVFeHRlbnNpb24uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvR2VuZXJhdGVkU2luZ2xlRXh0ZW5zaW9uLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9HZW5lcmF0ZWRTaW5nbGVFeHRlbnNpb24uY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSUJ1aWxkZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9JQnVpbGRlci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9JQnVpbGRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSUJ1aWxkZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSUJ1aWxkZXJMaXRlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSUJ1aWxkZXJMaXRlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0lCdWlsZGVyTGl0ZS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSUJ1aWxkZXJMaXRlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0lDb2RlZElucHV0U3RyZWFtLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSUNvZGVkSW5wdXRTdHJlYW0uY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvSUNvZGVkSW5wdXRTdHJlYW0uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0lDb2RlZElucHV0U3RyZWFtLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0lDb2RlZE91dHB1dFN0cmVhbS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0lDb2RlZE91dHB1dFN0cmVhbS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9JQ29kZWRPdXRwdXRTdHJlYW0uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0lDb2RlZE91dHB1dFN0cmVhbS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9JTWVzc2FnZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0lNZXNzYWdlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0lNZXNzYWdlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9JTWVzc2FnZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9JTWVzc2FnZUxpdGUuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9JTWVzc2FnZUxpdGUuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvSU1lc3NhZ2VMaXRlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9JTWVzc2FnZUxpdGUuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0NoYW5uZWwuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9JUnBjQ2hhbm5lbC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9JUnBjQ2hhbm5lbC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0NoYW5uZWwuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0NvbnRyb2xsZXIuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9JUnBjQ29udHJvbGxlci5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9JUnBjQ29udHJvbGxlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0NvbnRyb2xsZXIuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0Rpc3BhdGNoLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0Rpc3BhdGNoLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL0lScGNEaXNwYXRjaC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVJwY0Rpc3BhdGNoLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0lTZXJ2aWNlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvSVNlcnZpY2UuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvSVNlcnZpY2UuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0lTZXJ2aWNlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24uY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9NZXNzYWdlU3RyZWFtSXRlcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9NZXNzYWdlU3RyZWFtSXRlcmF0b3IuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvTWVzc2FnZVN0cmVhbUl0ZXJhdG9yLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9NZXNzYWdlU3RyZWFtSXRlcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvTWVzc2FnZVN0cmVhbVdyaXRlci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL01lc3NhZ2VTdHJlYW1Xcml0ZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvTWVzc2FnZVN0cmVhbVdyaXRlci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvTWVzc2FnZVN0cmVhbVdyaXRlci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9NZXNzYWdlVXRpbC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL01lc3NhZ2VVdGlsLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL01lc3NhZ2VVdGlsLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9NZXNzYWdlVXRpbC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9OYW1lSGVscGVycy5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL05hbWVIZWxwZXJzLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL05hbWVIZWxwZXJzLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9OYW1lSGVscGVycy5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm9wZXJ0aWVzL0Fzc2VtYmx5SW5mby5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuQ0YyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuQ0YyMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLkNGMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuQ0YyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLkNGMzUuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLkNGMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5DRjM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLkNGMzUuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5ORVQyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuTkVUMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5ORVQyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5ORVQyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLk5FVDM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5ORVQzNS5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLk5FVDM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLk5FVDM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuTkVUNDAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLk5FVDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuTkVUNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuTkVUNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5QTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5QTDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuUEw0MC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5QTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuU0wyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuU0wyMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLlNMMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuU0wyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLlNMMzAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLlNMMzAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5TTDMwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLlNMMzAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5TTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5TTDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuU0w0MC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVycy5TTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnMuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuQ0YyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLkNGMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuQ0YyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuQ0YyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5DRjM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuQ0YzNS5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5DRjM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5DRjM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLk5FVDIwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuTkVUMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuTkVUMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLk5FVDIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLk5FVDM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuTkVUMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuTkVUMzUuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLk5FVDM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLk5FVDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuTkVUNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuTkVUNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLk5FVDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlBMNDAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5QTDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlBMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlBMNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuU0wyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNMMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuU0wyMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuU0wyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5TTDMwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuU0wzMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5TTDMwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5TTDMwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNMNDAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5TTDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlNMNDAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Byb3RvY29sQnVmZmVyc0xpdGUuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1JwY1V0aWwuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9ScGNVdGlsLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1JwY1V0aWwuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1JwY1V0aWwuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvU29ydGVkTGlzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1NvcnRlZExpc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvU29ydGVkTGlzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvU29ydGVkTGlzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9UZXh0Rm9ybWF0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvVGV4dEZvcm1hdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVycy9UZXh0Rm9ybWF0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9UZXh0Rm9ybWF0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1RleHRHZW5lcmF0b3IuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9UZXh0R2VuZXJhdG9yLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1RleHRHZW5lcmF0b3IuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1RleHRHZW5lcmF0b3IuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvVGV4dFRva2VuaXplci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1RleHRUb2tlbml6ZXIuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvVGV4dFRva2VuaXplci5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvVGV4dFRva2VuaXplci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9UaHJvd0hlbHBlci5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1Rocm93SGVscGVyLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Rocm93SGVscGVyLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9UaHJvd0hlbHBlci5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbi5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbi5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVycy9Vbmtub3duRmllbGQuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Vbmtub3duRmllbGQuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnMvVW5rbm93bkZpZWxkLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9Vbmtub3duRmllbGQuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvVW5rbm93bkZpZWxkU2V0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvVW5rbm93bkZpZWxkU2V0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1Vua25vd25GaWVsZFNldC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnMvVW5rbm93bkZpZWxkU2V0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzL1dpcmVGb3JtYXQuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVycy9XaXJlRm9ybWF0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzL1dpcmVGb3JtYXQuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzL1dpcmVGb3JtYXQuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LkNGMjAuc2xuIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LkNGMjAuc2xuCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5DRjIwLnNsbgpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LkNGMjAuc2xuCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5DRjM1LnNsbiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5DRjM1LnNsbgpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuQ0YzNS5zbG4KcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5DRjM1LnNsbgpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuTkVUMjAuc2xuIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5Lk5FVDIwLnNsbgpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuTkVUMjAuc2xuCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuTkVUMjAuc2xuCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5ORVQzNS5zbG4gYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuTkVUMzUuc2xuCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5ORVQzNS5zbG4KcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5ORVQzNS5zbG4KZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5Lk5FVDQwLnNsbiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5ORVQ0MC5zbG4Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5Lk5FVDQwLnNsbgpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5Lk5FVDQwLnNsbgpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuUEw0MC5zbG4gYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuUEw0MC5zbG4Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LlBMNDAuc2xuCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuUEw0MC5zbG4KZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LlNMMjAuc2xuIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LlNMMjAuc2xuCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5TTDIwLnNsbgpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LlNMMjAuc2xuCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5TTDMwLnNsbiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5TTDMwLnNsbgpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuU0wzMC5zbG4KcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5TTDMwLnNsbgpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuU0w0MC5zbG4gYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuU0w0MC5zbG4Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LlNMNDAuc2xuCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpYnJhcnkuU0w0MC5zbG4KZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LnNsbiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGlicmFyeS5zbG4Kc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LnNsbgpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaWJyYXJ5LnNsbgpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BYnN0cmFjdEJ1aWxkZXJMaXRlVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0Fic3RyYWN0QnVpbGRlckxpdGVUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0Fic3RyYWN0QnVpbGRlckxpdGVUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BYnN0cmFjdEJ1aWxkZXJMaXRlVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BYnN0cmFjdE1lc3NhZ2VMaXRlVGVzdC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0Fic3RyYWN0TWVzc2FnZUxpdGVUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0Fic3RyYWN0TWVzc2FnZUxpdGVUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BYnN0cmFjdE1lc3NhZ2VMaXRlVGVzdC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BcHAueGFtbCBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0FwcC54YW1sCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0FwcC54YW1sCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BcHAueGFtbApkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BcHAueGFtbC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0FwcC54YW1sLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0FwcC54YW1sLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9BcHAueGFtbC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9FeHRlbmRhYmxlQnVpbGRlckxpdGVUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvRXh0ZW5kYWJsZUJ1aWxkZXJMaXRlVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9FeHRlbmRhYmxlQnVpbGRlckxpdGVUZXN0LmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9FeHRlbmRhYmxlQnVpbGRlckxpdGVUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0V4dGVuZGFibGVNZXNzYWdlTGl0ZVRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9FeHRlbmRhYmxlTWVzc2FnZUxpdGVUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0V4dGVuZGFibGVNZXNzYWdlTGl0ZVRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0V4dGVuZGFibGVNZXNzYWdlTGl0ZVRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvSW50ZXJvcExpdGVUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvSW50ZXJvcExpdGVUZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0ludGVyb3BMaXRlVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvSW50ZXJvcExpdGVUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0xpdGVUZXN0LmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvTGl0ZVRlc3QuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvTGl0ZVRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L0xpdGVUZXN0LmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L01pc3NpbmdGaWVsZEFuZEV4dGVuc2lvblRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9NaXNzaW5nRmllbGRBbmRFeHRlbnNpb25UZXN0LmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L01pc3NpbmdGaWVsZEFuZEV4dGVuc2lvblRlc3QuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L01pc3NpbmdGaWVsZEFuZEV4dGVuc2lvblRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvcGVydGllcy9BcHBNYW5pZmVzdC54bWwgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm9wZXJ0aWVzL0FwcE1hbmlmZXN0LnhtbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm9wZXJ0aWVzL0FwcE1hbmlmZXN0LnhtbApyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvcGVydGllcy9BcHBNYW5pZmVzdC54bWwKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvcGVydGllcy9PdXRPZkJyb3dzZXJTZXR0aW5ncy54bWwgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm9wZXJ0aWVzL091dE9mQnJvd3NlclNldHRpbmdzLnhtbApzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm9wZXJ0aWVzL091dE9mQnJvd3NlclNldHRpbmdzLnhtbApyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvcGVydGllcy9PdXRPZkJyb3dzZXJTZXR0aW5ncy54bWwKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LkNGMjAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LkNGMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5DRjIwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LkNGMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5DRjM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5DRjM1LmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuQ0YzNS5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5DRjM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuTkVUMjAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0Lk5FVDIwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuTkVUMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuTkVUMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5ORVQzNS5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuTkVUMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5ORVQzNS5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5ORVQzNS5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0Lk5FVDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5ORVQ0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0Lk5FVDQwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0Lk5FVDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuUEw0MC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuUEw0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LlBMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuUEw0MC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LlNMMjAuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LlNMMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5TTDIwLmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LlNMMjAuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5TTDMwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5TTDMwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuU0wzMC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5TTDMwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuU0w0MC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuU0w0MC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LlNMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QuU0w0MC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5DRjIwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LkNGMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LkNGMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5DRjIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5DRjM1LmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LkNGMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LkNGMzUuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5DRjM1LmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5ORVQyMC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5ORVQyMC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZU1peGVkLlRlc3QuTkVUMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5ORVQyMC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZU1peGVkLlRlc3QuTkVUMzUuY3Nwcm9qIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZU1peGVkLlRlc3QuTkVUMzUuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0Lk5FVDM1LmNzcHJvagpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZU1peGVkLlRlc3QuTkVUMzUuY3Nwcm9qCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0Lk5FVDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0Lk5FVDQwLmNzcHJvagpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5ORVQ0MC5jc3Byb2oKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0Lk5FVDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5QTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlBMNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlBMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5QTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5TTDIwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlNMMjAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlNMMjAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5TTDIwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5TTDMwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlNMMzAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlNMMzAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5TTDMwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5TTDQwLmNzcHJvaiBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlNMNDAuY3Nwcm9qCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Byb3RvY29sQnVmZmVyc0xpdGVNaXhlZC5UZXN0LlNMNDAuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5TTDQwLmNzcHJvagpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5jc3Byb2ogYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5jc3Byb2oKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvUHJvdG9jb2xCdWZmZXJzTGl0ZU1peGVkLlRlc3QuY3Nwcm9qCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9Qcm90b2NvbEJ1ZmZlcnNMaXRlTWl4ZWQuVGVzdC5jc3Byb2oKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvU2VyaWFsaXphYmxlTGl0ZVRlc3QuY3MgYi9jc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9TZXJpYWxpemFibGVMaXRlVGVzdC5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9TZXJpYWxpemFibGVMaXRlVGVzdC5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvU2VyaWFsaXphYmxlTGl0ZVRlc3QuY3MKZGlmZiAtLWdpdCBhL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvVGVzdExpdGVCeUFwaS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RMaXRlQnlBcGkuY3MKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvVGVzdExpdGVCeUFwaS5jcwpyZW5hbWUgdG8gY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvVGVzdExpdGVCeUFwaS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RXh0cmFzRnVsbFByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNGdWxsUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNGdWxsUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RXh0cmFzRnVsbFByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RXh0cmFzTGl0ZVByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNMaXRlUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RFeHRyYXNMaXRlUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0RXh0cmFzTGl0ZVByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0TGl0ZVByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RJbXBvcnRMaXRlUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RJbXBvcnRMaXRlUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0TGl0ZVByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0UHJvdG9GaWxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdEltcG9ydFByb3RvRmlsZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0SW1wb3J0UHJvdG9GaWxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RMaXRlSW1wb3J0Tm9uTGl0ZVByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RMaXRlSW1wb3J0Tm9uTGl0ZVByb3RvRmlsZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0TGl0ZUltcG9ydE5vbkxpdGVQcm90b0ZpbGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RMaXRlSW1wb3J0Tm9uTGl0ZVByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0TGl0ZVByb3RvRmlsZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RMaXRlUHJvdG9GaWxlLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RMaXRlUHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0TGl0ZVByb3RvRmlsZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UHJvdG9GaWxlLmNzIGIvY3NoYXJwL3NyYy9Qcm90b2NvbEJ1ZmZlcnNMaXRlLlRlc3QvVGVzdFByb3Rvcy9Vbml0VGVzdFByb3RvRmlsZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UHJvdG9GaWxlLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UHJvdG9GaWxlLmNzCmRpZmYgLS1naXQgYS9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RScGNJbnRlcm9wTGl0ZS5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RScGNJbnRlcm9wTGl0ZS5jcwpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0UHJvdG9zL1VuaXRUZXN0UnBjSW50ZXJvcExpdGUuY3MKcmVuYW1lIHRvIGNzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RQcm90b3MvVW5pdFRlc3RScGNJbnRlcm9wTGl0ZS5jcwpkaWZmIC0tZ2l0IGEvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0VXRpbC5jcyBiL2NzaGFycC9zcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RVdGlsLmNzCnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvUHJvdG9jb2xCdWZmZXJzTGl0ZS5UZXN0L1Rlc3RVdGlsLmNzCnJlbmFtZSB0byBjc2hhcnAvc3JjL1Byb3RvY29sQnVmZmVyc0xpdGUuVGVzdC9UZXN0VXRpbC5jcwpkaWZmIC0tZ2l0IGEvc3JjL1VzZVZTMjAwOC5iYXQgYi9jc2hhcnAvc3JjL1VzZVZTMjAwOC5iYXQKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHNyYy9Vc2VWUzIwMDguYmF0CnJlbmFtZSB0byBjc2hhcnAvc3JjL1VzZVZTMjAwOC5iYXQKZGlmZiAtLWdpdCBhL3NyYy9Vc2VWUzIwMTAuYmF0IGIvY3NoYXJwL3NyYy9Vc2VWUzIwMTAuYmF0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSBzcmMvVXNlVlMyMDEwLmJhdApyZW5hbWUgdG8gY3NoYXJwL3NyYy9Vc2VWUzIwMTAuYmF0CmRpZmYgLS1naXQgYS90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZSBiL2NzaGFycC90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZQpzaW1pbGFyaXR5IGluZGV4IDEwMCUKcmVuYW1lIGZyb20gdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2UKcmVuYW1lIHRvIGNzaGFycC90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlIGIvY3NoYXJwL3Rlc3RkYXRhL2dvbGRlbl9wYWNrZWRfZmllbGRzX21lc3NhZ2UKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHRlc3RkYXRhL2dvbGRlbl9wYWNrZWRfZmllbGRzX21lc3NhZ2UKcmVuYW1lIHRvIGNzaGFycC90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0IGIvY3NoYXJwL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0CnNpbWlsYXJpdHkgaW5kZXggMTAwJQpyZW5hbWUgZnJvbSB0ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhLnR4dApyZW5hbWUgdG8gY3NoYXJwL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0CmRpZmYgLS1naXQgYS90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0IGIvY3NoYXJwL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2V4dGVuc2lvbnNfZGF0YS50eHQKc2ltaWxhcml0eSBpbmRleCAxMDAlCnJlbmFtZSBmcm9tIHRlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2V4dGVuc2lvbnNfZGF0YS50eHQKcmVuYW1lIHRvIGNzaGFycC90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0CmRpZmYgLS1naXQgYS9lZGl0b3JzL1JFQURNRS50eHQgYi9lZGl0b3JzL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U5ZmM3OQotLS0gL2Rldi9udWxsCisrKyBiL2VkaXRvcnMvUkVBRE1FLnR4dApAQCAtMCwwICsxLDUgQEAKK1RoaXMgZGlyZWN0b3J5IGNvbnRhaW5zIHN5bnRheCBoaWdobGlnaHRpbmcgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMgZm9yIGVkaXRvcnMKK3RvIHByb3Blcmx5IGRpc3BsYXkgUHJvdG9jb2wgQnVmZmVyIGZpbGVzLgorCitTZWUgZWFjaCBmaWxlJ3MgaGVhZGVyIGNvbW1lbnQgZm9yIGRpcmVjdGlvbnMgb24gaG93IHRvIHVzZSBpdCB3aXRoIHRoZQorYXBwcm9wcmlhdGUgZWRpdG9yLgpkaWZmIC0tZ2l0IGEvZWRpdG9ycy9wcm90by52aW0gYi9lZGl0b3JzL3Byb3RvLnZpbQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzA4NWEyCi0tLSAvZGV2L251bGwKKysrIGIvZWRpdG9ycy9wcm90by52aW0KQEAgLTAsMCArMSwxMDUgQEAKKyIgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisiIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIgorIiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyIgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIiBtZXQ6CisiCisiICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisiIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyIgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisiIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyIgZGlzdHJpYnV0aW9uLgorIiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisiIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisiIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisiCisiIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyIgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyIgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisiIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisiIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisiIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyIgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyIgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiBUaGlzIGlzIHRoZSBWaW0gc3ludGF4IGZpbGUgZm9yIEdvb2dsZSBQcm90b2NvbCBCdWZmZXJzLgorIgorIiBVc2FnZToKKyIKKyIgMS4gY3AgcHJvdG8udmltIH4vLnZpbS9zeW50YXgvCisiIDIuIEFkZCB0aGUgZm9sbG93aW5nIHRvIH4vLnZpbXJjOgorIgorIiBhdWdyb3VwIGZpbGV0eXBlCisiICAgYXUhIEJ1ZlJlYWQsQnVmTmV3RmlsZSAqLnByb3RvIHNldGZpbGV0eXBlIHByb3RvCisiIGF1Z3JvdXAgZW5kCisiCisiIE9yIGp1c3QgY3JlYXRlIGEgbmV3IGZpbGUgY2FsbGVkIH4vLnZpbS9mdGRldGVjdC9wcm90by52aW0gd2l0aCB0aGUKKyIgcHJldmlvdXMgbGluZXMgb24gaXQuCisKK2lmIHZlcnNpb24gPCA2MDAKKyAgc3ludGF4IGNsZWFyCitlbHNlaWYgZXhpc3RzKCJiOmN1cnJlbnRfc3ludGF4IikKKyAgZmluaXNoCitlbmRpZgorCitzeW4gY2FzZSBtYXRjaAorCitzeW4ga2V5d29yZCBwYlRvZG8gICAgICAgY29udGFpbmVkIFRPRE8gRklYTUUgWFhYCitzeW4gY2x1c3RlciBwYkNvbW1lbnRHcnAgY29udGFpbnM9cGJUb2RvCisKK3N5biBrZXl3b3JkIHBiU3ludGF4ICAgICBzeW50YXggaW1wb3J0IG9wdGlvbgorc3luIGtleXdvcmQgcGJTdHJ1Y3R1cmUgIHBhY2thZ2UgbWVzc2FnZSBncm91cCBvbmVvZgorc3luIGtleXdvcmQgcGJSZXBlYXQgICAgIG9wdGlvbmFsIHJlcXVpcmVkIHJlcGVhdGVkCitzeW4ga2V5d29yZCBwYkRlZmF1bHQgICAgZGVmYXVsdAorc3luIGtleXdvcmQgcGJFeHRlbmQgICAgIGV4dGVuZCBleHRlbnNpb25zIHRvIG1heAorc3luIGtleXdvcmQgcGJSUEMgICAgICAgIHNlcnZpY2UgcnBjIHJldHVybnMKKworc3luIGtleXdvcmQgcGJUeXBlICAgICAgaW50MzIgaW50NjQgdWludDMyIHVpbnQ2NCBzaW50MzIgc2ludDY0CitzeW4ga2V5d29yZCBwYlR5cGUgICAgICBmaXhlZDMyIGZpeGVkNjQgc2ZpeGVkMzIgc2ZpeGVkNjQKK3N5biBrZXl3b3JkIHBiVHlwZSAgICAgIGZsb2F0IGRvdWJsZSBib29sIHN0cmluZyBieXRlcworc3luIGtleXdvcmQgcGJUeXBlZGVmICAgZW51bQorc3luIGtleXdvcmQgcGJCb29sICAgICAgdHJ1ZSBmYWxzZQorCitzeW4gbWF0Y2ggICBwYkludCAgICAgLy1cP1w8XGRcK1w+Lworc3luIG1hdGNoICAgcGJJbnQgICAgIC9cPDBbeFhdXHgrXD4vCitzeW4gbWF0Y2ggICBwYkZsb2F0ICAgL1w8LVw/XGQqXChcLlxkKlwpXD8vCitzeW4gcmVnaW9uICBwYkNvbW1lbnQgc3RhcnQ9IlwvXCoiIGVuZD0iXCpcLyIgY29udGFpbnM9QHBiQ29tbWVudEdycAorc3luIHJlZ2lvbiAgcGJDb21tZW50IHN0YXJ0PSIvLyIgc2tpcD0iXFwkIiBlbmQ9IiQiIGtlZXBlbmQgY29udGFpbnM9QHBiQ29tbWVudEdycAorc3luIHJlZ2lvbiAgcGJTdHJpbmcgIHN0YXJ0PS8iLyBza2lwPS9cXC4vIGVuZD0vIi8KK3N5biByZWdpb24gIHBiU3RyaW5nICBzdGFydD0vJy8gc2tpcD0vXFwuLyBlbmQ9LycvCisKK2lmIHZlcnNpb24gPj0gNTA4IHx8ICFleGlzdHMoImRpZF9wcm90b19zeW5faW5pdHMiKQorICBpZiB2ZXJzaW9uIDwgNTA4CisgICAgbGV0IGRpZF9wcm90b19zeW5faW5pdHMgPSAxCisgICAgY29tbWFuZCAtbmFyZ3M9KyBIaUxpbmsgaGkgbGluayA8YXJncz4KKyAgZWxzZQorICAgIGNvbW1hbmQgLW5hcmdzPSsgSGlMaW5rIGhpIGRlZiBsaW5rIDxhcmdzPgorICBlbmRpZgorCisgIEhpTGluayBwYlRvZG8gICAgICAgICBUb2RvCisKKyAgSGlMaW5rIHBiU3ludGF4ICAgICAgIEluY2x1ZGUKKyAgSGlMaW5rIHBiU3RydWN0dXJlICAgIFN0cnVjdHVyZQorICBIaUxpbmsgcGJSZXBlYXQgICAgICAgUmVwZWF0CisgIEhpTGluayBwYkRlZmF1bHQgICAgICBLZXl3b3JkCisgIEhpTGluayBwYkV4dGVuZCAgICAgICBLZXl3b3JkCisgIEhpTGluayBwYlJQQyAgICAgICAgICBLZXl3b3JkCisgIEhpTGluayBwYlR5cGUgICAgICAgICBUeXBlCisgIEhpTGluayBwYlR5cGVkZWYgICAgICBUeXBlZGVmCisgIEhpTGluayBwYkJvb2wgICAgICAgICBCb29sZWFuCisKKyAgSGlMaW5rIHBiSW50ICAgICAgICAgIE51bWJlcgorICBIaUxpbmsgcGJGbG9hdCAgICAgICAgRmxvYXQKKyAgSGlMaW5rIHBiQ29tbWVudCAgICAgIENvbW1lbnQKKyAgSGlMaW5rIHBiU3RyaW5nICAgICAgIFN0cmluZworCisgIGRlbGNvbW1hbmQgSGlMaW5rCitlbmRpZgorCitsZXQgYjpjdXJyZW50X3N5bnRheCA9ICJwcm90byIKZGlmZiAtLWdpdCBhL2VkaXRvcnMvcHJvdG9idWYtbW9kZS5lbCBiL2VkaXRvcnMvcHJvdG9idWYtbW9kZS5lbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOWFlY2M5Ci0tLSAvZGV2L251bGwKKysrIGIvZWRpdG9ycy9wcm90b2J1Zi1tb2RlLmVsCkBAIC0wLDAgKzEsMjIwIEBACis7OzsgcHJvdG9idWYtbW9kZS5lbCAtLS0gbWFqb3IgbW9kZSBmb3IgZWRpdGluZyBwcm90b2NvbCBidWZmZXJzLgorCis7OyBBdXRob3I6IEFsZXhhbmRyZSBWYXNzYWxvdHRpIDxhbGV4YW5kcmVAcGVhZHJvcC5jb20+Cis7OyBDcmVhdGVkOiAyMy1BcHItMjAwOQorOzsgVmVyc2lvbjogMC4zCis7OyBLZXl3b3JkczogZ29vZ2xlIHByb3RvYnVmIGxhbmd1YWdlcworCis7OyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKzs7IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKzs7IG1ldDoKKzs7Cis7OyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorOzsgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorOzsgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorOzsgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorOzsgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorOzsgZGlzdHJpYnV0aW9uLgorOzsgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworOzsgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKzs7IHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCis7OworOzsgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworOzsgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKzs7IExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorOzsgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKzs7IE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorOzsgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorOzsgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCis7OyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKzs7IFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKzs7IChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorOzsgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworOzs7IENvbW1lbnRhcnk6CisKKzs7IEluc3RhbGxhdGlvbjoKKzs7ICAgLSBQdXQgYHByb3RvYnVmLW1vZGUuZWwnIGluIHlvdXIgRW1hY3MgbG9hZC1wYXRoLgorOzsgICAtIEFkZCB0aGlzIGxpbmUgdG8geW91ciAuZW1hY3MgZmlsZToKKzs7ICAgICAgIChyZXF1aXJlICdwcm90b2J1Zi1tb2RlKQorOzsKKzs7IFlvdSBjYW4gY3VzdG9taXplIHRoaXMgbW9kZSBqdXN0IGxpa2UgYW55IG1vZGUgZGVyaXZlZCBmcm9tIENDIE1vZGUuICBJZgorOzsgeW91IHdhbnQgdG8gYWRkIGN1c3RvbWl6YXRpb25zIHNwZWNpZmljIHRvIHByb3RvYnVmLW1vZGUsIHlvdSBjYW4gdXNlIHRoZQorOzsgYHByb3RvYnVmLW1vZGUtaG9vaycuIEZvciBleGFtcGxlLCB0aGUgZm9sbG93aW5nIHdvdWxkIG1ha2UgcHJvdG9jb2wtbW9kZQorOzsgdXNlIDItc3BhY2UgaW5kZW50YXRpb246Cis7OworOzsgICAoZGVmY29uc3QgbXktcHJvdG9idWYtc3R5bGUKKzs7ICAgICAnKChjLWJhc2ljLW9mZnNldCAuIDIpCis7OyAgICAgICAoaW5kZW50LXRhYnMtbW9kZSAuIG5pbCkpKQorOzsKKzs7ICAgKGFkZC1ob29rICdwcm90b2J1Zi1tb2RlLWhvb2sKKzs7ICAgICAobGFtYmRhICgpIChjLWFkZC1zdHlsZSAibXktc3R5bGUiIG15LXByb3RvYnVmLXN0eWxlIHQpKSkKKzs7Cis7OyBSZWZlciB0byB0aGUgZG9jdW1lbnRhdGlvbiBvZiBDQyBNb2RlIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0Cis7OyBjdXN0b21pemF0aW9uIGRldGFpbHMgYW5kIGhvdyB0byB1c2UgdGhpcyBtb2RlLgorOzsKKzs7IFRPRE86Cis7OyAgIC0gTWFrZSBoaWdobGlnaHRpbmcgZm9yIGVudW0gdmFsdWVzIHdvcmsgcHJvcGVybHkuCis7OyAgIC0gRml4IHRoZSBwYXJzZXIgdG8gcmVjb2duaXplIGV4dGVuc2lvbnMgYXMgaWRlbnRpZmllcnMgYW5kIG5vdAorOzsgICAgIGFzIGNhc3RzLgorOzsgICAtIEltcHJvdmUgdGhlIHBhcnNpbmcgb2Ygb3B0aW9uIGFzc2lnbm1lbnQgbGlzdHMuIEZvciBleGFtcGxlOgorOzsgICAgICAgb3B0aW9uYWwgaW50MzIgZm9vID0gMSBbKG15X2ZpZWxkX29wdGlvbikgPSA0LjVdOworOzsgICAtIEFkZCBzdXBwb3J0IGZvciBmdWxseS1xdWFsaWZpZWQgaWRlbnRpZmllcnMgKGUuZy4sIHdpdGggYSBsZWFkaW5nICIuIikuCisKKzs7OyBDb2RlOgorCisocmVxdWlyZSAnY2MtbW9kZSkKKworKGV2YWwtd2hlbi1jb21waWxlCisgIChyZXF1aXJlICdjYy1sYW5ncykKKyAgKHJlcXVpcmUgJ2NjLWZvbnRzKSkKKworOzsgVGhpcyBtb2RlIGRvZXMgbm90IGluaGVyaXQgcHJvcGVydGllcyBmcm9tIG90aGVyIG1vZGVzLiBTbywgd2UgZG8gbm90IHVzZSAKKzs7IHRoZSB1c3VhbCBgYy1hZGQtbGFuZ3VhZ2UnIGZ1bmN0aW9uLgorKGV2YWwtYW5kLWNvbXBpbGUKKyAgKHB1dCAncHJvdG9idWYtbW9kZSAnYy1tb2RlLXByZWZpeCAicHJvdG9idWYtIikpCisKKzs7IFRoZSBmb2xsb3dpbmcgY29kZSB1c2VzIG9mIHRoZSBgYy1sYW5nLWRlZmNvbnN0JyBtYWNybyBkZWZpbmUgc3ludGFjdGljCis7OyBmZWF0dXJlcyBvZiBwcm90b2NvbCBidWZmZXIgbGFuZ3VhZ2UuICBSZWZlciB0byB0aGUgZG9jdW1lbnRhdGlvbiBpbiB0aGUKKzs7IGNjLWxhbmdzLmVsIGZpbGUgZm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWFuaW5nIG9mIHRoZSAta3dkcyB2YXJpYWJsZXMuCisKKyhjLWxhbmctZGVmY29uc3QgYy1wcmltaXRpdmUtdHlwZS1rd2RzCisgIHByb3RvYnVmICcoImRvdWJsZSIgImZsb2F0IiAiaW50MzIiICJpbnQ2NCIgInVpbnQzMiIgInVpbnQ2NCIgInNpbnQzMiIKKyAgICAgICAgICAgICAic2ludDY0IiAiZml4ZWQzMiIgImZpeGVkNjQiICJzZml4ZWQzMiIgInNmaXhlZDY0IiAiYm9vbCIKKyAgICAgICAgICAgICAic3RyaW5nIiAiYnl0ZXMiICJncm91cCIpKQorCisoYy1sYW5nLWRlZmNvbnN0IGMtbW9kaWZpZXIta3dkcworICBwcm90b2J1ZiAnKCJyZXF1aXJlZCIgIm9wdGlvbmFsIiAicmVwZWF0ZWQiKSkKKworKGMtbGFuZy1kZWZjb25zdCBjLWNsYXNzLWRlY2wta3dkcworICBwcm90b2J1ZiAnKCJtZXNzYWdlIiAiZW51bSIgInNlcnZpY2UiKSkKKworKGMtbGFuZy1kZWZjb25zdCBjLWNvbnN0YW50LWt3ZHMKKyAgcHJvdG9idWYgJygidHJ1ZSIgImZhbHNlIikpCisKKyhjLWxhbmctZGVmY29uc3QgYy1vdGhlci1kZWNsLWt3ZHMKKyAgcHJvdG9idWYgJygicGFja2FnZSIgImltcG9ydCIpKQorCisoYy1sYW5nLWRlZmNvbnN0IGMtb3RoZXIta3dkcworICBwcm90b2J1ZiAnKCJkZWZhdWx0IiAibWF4IikpCisKKyhjLWxhbmctZGVmY29uc3QgYy1pZGVudGlmaWVyLW9wcworICA7OyBIYW5kbGUgZXh0ZW5kZWQgaWRlbnRpZmllcnMgbGlrZSBnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMKKyAgcHJvdG9idWYgJygobGVmdC1hc3NvYyAiLiIpKSkKKworOzsgVGhlIGZvbGxvd2luZyBrZXl3b3JkcyBkbyBub3QgZml0IHdlbGwgaW4ga2V5d29yZCBjbGFzc2VzIGRlZmluZWQgYnkKKzs7IGNjLW1vZGUuICBTbywgd2UgYXBwcm94aW1hdGUgYXMgYmVzdCB3ZSBjYW4uCisKKyhjLWxhbmctZGVmY29uc3QgYy10eXBlLWxpc3Qta3dkcworICBwcm90b2J1ZiAnKCJleHRlbnNpb25zIiAidG8iKSkKKworKGMtbGFuZy1kZWZjb25zdCBjLXR5cGVsZXNzLWRlY2wta3dkcworICBwcm90b2J1ZiAnKCJleHRlbmQiICJycGMiICJvcHRpb24iICJyZXR1cm5zIikpCisKKworOzsgSGVyZSB3ZSByZW1vdmUgZGVmYXVsdCBzeW50YXggZm9yIGxvb3BzLCBpZi1zdGF0ZW1lbnRzIGFuZCBvdGhlciBDCis7OyBzeW50YWN0aWMgZmVhdHVyZXMgdGhhdCBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGxhbmd1YWdlLgorCisoYy1sYW5nLWRlZmNvbnN0IGMtYnJhY2UtbGlzdC1kZWNsLWt3ZHMKKyAgOzsgUmVtb3ZlIHN5bnRheCBmb3IgQy1zdHlsZSBlbnVtZXJhdGlvbnMuCisgIHByb3RvYnVmIG5pbCkKKworKGMtbGFuZy1kZWZjb25zdCBjLWJsb2NrLXN0bXQtMS1rd2RzCisgIDs7IFJlbW92ZSBzeW50YXggZm9yICJkbyIgYW5kICJlbHNlIiBrZXl3b3Jkcy4KKyAgcHJvdG9idWYgbmlsKQorCisoYy1sYW5nLWRlZmNvbnN0IGMtYmxvY2stc3RtdC0yLWt3ZHMKKyAgOzsgUmVtb3ZlIHN5bnRheCBmb3IgImZvciIsICJpZiIsICJzd2l0Y2giIGFuZCAid2hpbGUiIGtleXdvcmRzLgorICBwcm90b2J1ZiBuaWwpCisKKyhjLWxhbmctZGVmY29uc3QgYy1zaW1wbGUtc3RtdC1rd2RzCisgIDs7IFJlbW92ZSBzeW50YXggZm9yICJicmVhayIsICJjb250aW51ZSIsICJnb3RvIiBhbmQgInJldHVybiIga2V5d29yZHMuCisgIHByb3RvYnVmIG5pbCkKKworKGMtbGFuZy1kZWZjb25zdCBjLXBhcmVuLXN0bXQta3dkcworICA7OyBSZW1vdmUgc3BlY2lhbCBjYXNlIGZvciB0aGUgIig7OykiIGluIGZvci1sb29wcy4KKyAgcHJvdG9idWYgbmlsKQorCisoYy1sYW5nLWRlZmNvbnN0IGMtbGFiZWwta3dkcworICA7OyBSZW1vdmUgY2FzZSBsYWJlbCBzeW50YXggZm9yIHRoZSAiY2FzZSIgYW5kICJkZWZhdWx0IiBrZXl3b3Jkcy4KKyAgcHJvdG9idWYgbmlsKQorCisoYy1sYW5nLWRlZmNvbnN0IGMtYmVmb3JlLWxhYmVsLWt3ZHMKKyAgOzsgUmVtb3ZlIHNwZWNpYWwgY2FzZSBmb3IgdGhlIGxhYmVsIGluIGEgZ290byBzdGF0ZW1lbnQuCisgIHByb3RvYnVmIG5pbCkKKworKGMtbGFuZy1kZWZjb25zdCBjLWNwcC1tYXRjaGVycworICA7OyBEaXNhYmxlIGFsbCB0aGUgQyBwcmVwcm9jZXNzb3Igc3ludGF4LgorICBwcm90b2J1ZiBuaWwpCisKKyhjLWxhbmctZGVmY29uc3QgYy1kZWNsLXByZWZpeC1yZQorICA7OyBTYW1lIGFzIGZvciBDLCBleGNlcHQgaXQgZG9lcyBub3QgbWF0Y2ggIigiLiBUaGlzIGlzIG5lZWRlZCBmb3IgZGlzYWJsaW5nCisgIDs7IHRoZSBzeW50YXggZm9yIGNhc3RzLgorICBwcm90b2J1ZiAiXFwoW1x7XH07LF0rXFwpIikKKworCis7OyBBZGQgc3VwcG9ydCBmb3IgdmFyaWFibGUgbGV2ZWxzIG9mIHN5bnRheCBoaWdobGlnaHRpbmcuCisKKyhkZWZjb25zdCBwcm90b2J1Zi1mb250LWxvY2sta2V5d29yZHMtMSAoYy1sYW5nLWNvbnN0IGMtbWF0Y2hlcnMtMSBwcm90b2J1ZikKKyAgIk1pbmltYWwgaGlnaGxpZ2h0aW5nIGZvciBwcm90b2J1Zi1tb2RlLiIpCisKKyhkZWZjb25zdCBwcm90b2J1Zi1mb250LWxvY2sta2V5d29yZHMtMiAoYy1sYW5nLWNvbnN0IGMtbWF0Y2hlcnMtMiBwcm90b2J1ZikKKyAgIkZhc3Qgbm9ybWFsIGhpZ2hsaWdodGluZyBmb3IgcHJvdG9idWYtbW9kZS4iKQorCisoZGVmY29uc3QgcHJvdG9idWYtZm9udC1sb2NrLWtleXdvcmRzLTMgKGMtbGFuZy1jb25zdCBjLW1hdGNoZXJzLTMgcHJvdG9idWYpCisgICJBY2N1cmF0ZSBub3JtYWwgaGlnaGxpZ2h0aW5nIGZvciBwcm90b2J1Zi1tb2RlLiIpCisKKyhkZWZ2YXIgcHJvdG9idWYtZm9udC1sb2NrLWtleXdvcmRzIHByb3RvYnVmLWZvbnQtbG9jay1rZXl3b3Jkcy0zCisgICJEZWZhdWx0IGV4cHJlc3Npb25zIHRvIGhpZ2hsaWdodCBpbiBwcm90b2J1Zi1tb2RlLiIpCisKKzs7IE91ciBzeW50YXggdGFibGUgaXMgYXV0by1nZW5lcmF0ZWQgZnJvbSB0aGUga2V5d29yZCBjbGFzc2VzIHdlIGRlZmluZWQKKzs7IHByZXZpb3VzbHkgd2l0aCB0aGUgYGMtbGFuZy1jb25zdCcgbWFjcm8uCisoZGVmdmFyIHByb3RvYnVmLW1vZGUtc3ludGF4LXRhYmxlIG5pbAorICAiU3ludGF4IHRhYmxlIHVzZWQgaW4gcHJvdG9idWYtbW9kZSBidWZmZXJzLiIpCisob3IgcHJvdG9idWYtbW9kZS1zeW50YXgtdGFibGUKKyAgICAoc2V0cSBwcm90b2J1Zi1tb2RlLXN5bnRheC10YWJsZQorICAgICAgICAgIChmdW5jYWxsIChjLWxhbmctY29uc3QgYy1tYWtlLW1vZGUtc3ludGF4LXRhYmxlIHByb3RvYnVmKSkpKQorCisoZGVmdmFyIHByb3RvYnVmLW1vZGUtYWJicmV2LXRhYmxlIG5pbAorICAiQWJicmV2aWF0aW9uIHRhYmxlIHVzZWQgaW4gcHJvdG9idWYtbW9kZSBidWZmZXJzLiIpCisKKyhkZWZ2YXIgcHJvdG9idWYtbW9kZS1tYXAgbmlsCisgICJLZXltYXAgdXNlZCBpbiBwcm90b2J1Zi1tb2RlIGJ1ZmZlcnMuIikKKyhvciBwcm90b2J1Zi1tb2RlLW1hcAorICAgIChzZXRxIHByb3RvYnVmLW1vZGUtbWFwIChjLW1ha2UtaW5oZXJpdGVkLWtleW1hcCkpKQorCisoZWFzeS1tZW51LWRlZmluZSBwcm90b2J1Zi1tZW51IHByb3RvYnVmLW1vZGUtbWFwCisgICJQcm90b2NvbCBCdWZmZXJzIE1vZGUgQ29tbWFuZHMiCisgIChjb25zICJQcm90b2NvbCBCdWZmZXJzIiAoYy1sYW5nLWNvbnN0IGMtbW9kZS1tZW51IHByb3RvYnVmKSkpCisKKzs7OyMjI2F1dG9sb2FkIChhZGQtdG8tbGlzdCAnYXV0by1tb2RlLWFsaXN0ICcoIlxcLnByb3RvXFwnIiAuIHByb3RvYnVmLW1vZGUpKQorCis7OzsjIyNhdXRvbG9hZAorKGRlZnVuIHByb3RvYnVmLW1vZGUgKCkKKyAgIk1ham9yIG1vZGUgZm9yIGVkaXRpbmcgUHJvdG9jb2wgQnVmZmVycyBkZXNjcmlwdGlvbiBsYW5ndWFnZS4KKworVGhlIGhvb2sgYGMtbW9kZS1jb21tb24taG9vaycgaXMgcnVuIHdpdGggbm8gYXJndW1lbnQgYXQgbW9kZQoraW5pdGlhbGl6YXRpb24sIHRoZW4gYHByb3RvYnVmLW1vZGUtaG9vaycuCisKK0tleSBiaW5kaW5nczoKK1xce3Byb3RvYnVmLW1vZGUtbWFwfSIKKyAgKGludGVyYWN0aXZlKQorICAoa2lsbC1hbGwtbG9jYWwtdmFyaWFibGVzKQorICAoc2V0LXN5bnRheC10YWJsZSBwcm90b2J1Zi1tb2RlLXN5bnRheC10YWJsZSkKKyAgKHNldHEgbWFqb3ItbW9kZSAncHJvdG9idWYtbW9kZQorICAgICAgICBtb2RlLW5hbWUgIlByb3RvY29sLUJ1ZmZlcnMiCisgICAgICAgIGxvY2FsLWFiYnJldi10YWJsZSBwcm90b2J1Zi1tb2RlLWFiYnJldi10YWJsZQorICAgICAgICBhYmJyZXYtbW9kZSB0KQorICAodXNlLWxvY2FsLW1hcCBwcm90b2J1Zi1tb2RlLW1hcCkKKyAgKGMtaW5pdGlhbGl6ZS1jYy1tb2RlIHQpCisgIChpZiAoZmJvdW5kcCAnYy1tYWtlLWVtYWNzLXZhcmlhYmxlcy1sb2NhbCkKKyAgICAgIChjLW1ha2UtZW1hY3MtdmFyaWFibGVzLWxvY2FsKSkKKyAgKGMtaW5pdC1sYW5ndWFnZS12YXJzIHByb3RvYnVmLW1vZGUpCisgIChjLWNvbW1vbi1pbml0ICdwcm90b2J1Zi1tb2RlKQorICAoZWFzeS1tZW51LWFkZCBwcm90b2J1Zi1tZW51KQorICAoYy1ydW4tbW9kZS1ob29rcyAnYy1tb2RlLWNvbW1vbi1ob29rICdwcm90b2J1Zi1tb2RlLWhvb2spCisgIChjLXVwZGF0ZS1tb2RlbGluZSkpCisKKyhwcm92aWRlICdwcm90b2J1Zi1tb2RlKQorCis7OzsgcHJvdG9idWYtbW9kZS5lbCBlbmRzIGhlcmUKZGlmZiAtLWdpdCBhL2V4YW1wbGVzL0FkZFBlcnNvbi5qYXZhIGIvZXhhbXBsZXMvQWRkUGVyc29uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E1YWMyNwotLS0gL2Rldi9udWxsCisrKyBiL2V4YW1wbGVzL0FkZFBlcnNvbi5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKy8vIFNlZSBSRUFETUUudHh0IGZvciBpbmZvcm1hdGlvbiBhbmQgYnVpbGQgaW5zdHJ1Y3Rpb25zLgorCitpbXBvcnQgY29tLmV4YW1wbGUudHV0b3JpYWwuQWRkcmVzc0Jvb2tQcm90b3MuQWRkcmVzc0Jvb2s7CitpbXBvcnQgY29tLmV4YW1wbGUudHV0b3JpYWwuQWRkcmVzc0Jvb2tQcm90b3MuUGVyc29uOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworCitjbGFzcyBBZGRQZXJzb24geworICAvLyBUaGlzIGZ1bmN0aW9uIGZpbGxzIGluIGEgUGVyc29uIG1lc3NhZ2UgYmFzZWQgb24gdXNlciBpbnB1dC4KKyAgc3RhdGljIFBlcnNvbiBQcm9tcHRGb3JBZGRyZXNzKEJ1ZmZlcmVkUmVhZGVyIHN0ZGluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRTdHJlYW0gc3Rkb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFBlcnNvbi5CdWlsZGVyIHBlcnNvbiA9IFBlcnNvbi5uZXdCdWlsZGVyKCk7CisKKyAgICBzdGRvdXQucHJpbnQoIkVudGVyIHBlcnNvbiBJRDogIik7CisgICAgcGVyc29uLnNldElkKEludGVnZXIudmFsdWVPZihzdGRpbi5yZWFkTGluZSgpKSk7CisKKyAgICBzdGRvdXQucHJpbnQoIkVudGVyIG5hbWU6ICIpOworICAgIHBlcnNvbi5zZXROYW1lKHN0ZGluLnJlYWRMaW5lKCkpOworCisgICAgc3Rkb3V0LnByaW50KCJFbnRlciBlbWFpbCBhZGRyZXNzIChibGFuayBmb3Igbm9uZSk6ICIpOworICAgIFN0cmluZyBlbWFpbCA9IHN0ZGluLnJlYWRMaW5lKCk7CisgICAgaWYgKGVtYWlsLmxlbmd0aCgpID4gMCkgeworICAgICAgcGVyc29uLnNldEVtYWlsKGVtYWlsKTsKKyAgICB9CisKKyAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgc3Rkb3V0LnByaW50KCJFbnRlciBhIHBob25lIG51bWJlciAob3IgbGVhdmUgYmxhbmsgdG8gZmluaXNoKTogIik7CisgICAgICBTdHJpbmcgbnVtYmVyID0gc3RkaW4ucmVhZExpbmUoKTsKKyAgICAgIGlmIChudW1iZXIubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgUGVyc29uLlBob25lTnVtYmVyLkJ1aWxkZXIgcGhvbmVOdW1iZXIgPQorICAgICAgICBQZXJzb24uUGhvbmVOdW1iZXIubmV3QnVpbGRlcigpLnNldE51bWJlcihudW1iZXIpOworCisgICAgICBzdGRvdXQucHJpbnQoIklzIHRoaXMgYSBtb2JpbGUsIGhvbWUsIG9yIHdvcmsgcGhvbmU/ICIpOworICAgICAgU3RyaW5nIHR5cGUgPSBzdGRpbi5yZWFkTGluZSgpOworICAgICAgaWYgKHR5cGUuZXF1YWxzKCJtb2JpbGUiKSkgeworICAgICAgICBwaG9uZU51bWJlci5zZXRUeXBlKFBlcnNvbi5QaG9uZVR5cGUuTU9CSUxFKTsKKyAgICAgIH0gZWxzZSBpZiAodHlwZS5lcXVhbHMoImhvbWUiKSkgeworICAgICAgICBwaG9uZU51bWJlci5zZXRUeXBlKFBlcnNvbi5QaG9uZVR5cGUuSE9NRSk7CisgICAgICB9IGVsc2UgaWYgKHR5cGUuZXF1YWxzKCJ3b3JrIikpIHsKKyAgICAgICAgcGhvbmVOdW1iZXIuc2V0VHlwZShQZXJzb24uUGhvbmVUeXBlLldPUkspOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3Rkb3V0LnByaW50bG4oIlVua25vd24gcGhvbmUgdHlwZS4gIFVzaW5nIGRlZmF1bHQuIik7CisgICAgICB9CisKKyAgICAgIHBlcnNvbi5hZGRQaG9uZShwaG9uZU51bWJlcik7CisgICAgfQorCisgICAgcmV0dXJuIHBlcnNvbi5idWlsZCgpOworICB9CisKKyAgLy8gTWFpbiBmdW5jdGlvbjogIFJlYWRzIHRoZSBlbnRpcmUgYWRkcmVzcyBib29rIGZyb20gYSBmaWxlLAorICAvLyAgIGFkZHMgb25lIHBlcnNvbiBiYXNlZCBvbiB1c2VyIGlucHV0LCB0aGVuIHdyaXRlcyBpdCBiYWNrIG91dCB0byB0aGUgc2FtZQorICAvLyAgIGZpbGUuCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIGlmIChhcmdzLmxlbmd0aCAhPSAxKSB7CisgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlVzYWdlOiAgQWRkUGVyc29uIEFERFJFU1NfQk9PS19GSUxFIik7CisgICAgICBTeXN0ZW0uZXhpdCgtMSk7CisgICAgfQorCisgICAgQWRkcmVzc0Jvb2suQnVpbGRlciBhZGRyZXNzQm9vayA9IEFkZHJlc3NCb29rLm5ld0J1aWxkZXIoKTsKKworICAgIC8vIFJlYWQgdGhlIGV4aXN0aW5nIGFkZHJlc3MgYm9vay4KKyAgICB0cnkgeworICAgICAgRmlsZUlucHV0U3RyZWFtIGlucHV0ID0gbmV3IEZpbGVJbnB1dFN0cmVhbShhcmdzWzBdKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGFkZHJlc3NCb29rLm1lcmdlRnJvbShpbnB1dCk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICB0cnkgeyBpbnB1dC5jbG9zZSgpOyB9IGNhdGNoIChUaHJvd2FibGUgaWdub3JlKSB7fQorICAgICAgfQorICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYXJnc1swXSArICI6IEZpbGUgbm90IGZvdW5kLiAgQ3JlYXRpbmcgYSBuZXcgZmlsZS4iKTsKKyAgICB9CisKKyAgICAvLyBBZGQgYW4gYWRkcmVzcy4KKyAgICBhZGRyZXNzQm9vay5hZGRQZXJzb24oCisgICAgICBQcm9tcHRGb3JBZGRyZXNzKG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSksCisgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQpKTsKKworICAgIC8vIFdyaXRlIHRoZSBuZXcgYWRkcmVzcyBib29rIGJhY2sgdG8gZGlzay4KKyAgICBGaWxlT3V0cHV0U3RyZWFtIG91dHB1dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGFyZ3NbMF0pOworICAgIHRyeSB7CisgICAgICBhZGRyZXNzQm9vay5idWlsZCgpLndyaXRlVG8ob3V0cHV0KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgb3V0cHV0LmNsb3NlKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9leGFtcGxlcy9MaXN0UGVvcGxlLmphdmEgYi9leGFtcGxlcy9MaXN0UGVvcGxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjJmMTUzYQotLS0gL2Rldi9udWxsCisrKyBiL2V4YW1wbGVzL0xpc3RQZW9wbGUuamF2YQpAQCAtMCwwICsxLDUwIEBACisvLyBTZWUgUkVBRE1FLnR4dCBmb3IgaW5mb3JtYXRpb24gYW5kIGJ1aWxkIGluc3RydWN0aW9ucy4KKworaW1wb3J0IGNvbS5leGFtcGxlLnR1dG9yaWFsLkFkZHJlc3NCb29rUHJvdG9zLkFkZHJlc3NCb29rOworaW1wb3J0IGNvbS5leGFtcGxlLnR1dG9yaWFsLkFkZHJlc3NCb29rUHJvdG9zLlBlcnNvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CisKK2NsYXNzIExpc3RQZW9wbGUgeworICAvLyBJdGVyYXRlcyB0aG91Z2ggYWxsIHBlb3BsZSBpbiB0aGUgQWRkcmVzc0Jvb2sgYW5kIHByaW50cyBpbmZvIGFib3V0IHRoZW0uCisgIHN0YXRpYyB2b2lkIFByaW50KEFkZHJlc3NCb29rIGFkZHJlc3NCb29rKSB7CisgICAgZm9yIChQZXJzb24gcGVyc29uOiBhZGRyZXNzQm9vay5nZXRQZXJzb25MaXN0KCkpIHsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGVyc29uIElEOiAiICsgcGVyc29uLmdldElkKCkpOworICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIE5hbWU6ICIgKyBwZXJzb24uZ2V0TmFtZSgpKTsKKyAgICAgIGlmIChwZXJzb24uaGFzRW1haWwoKSkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgRS1tYWlsIGFkZHJlc3M6ICIgKyBwZXJzb24uZ2V0RW1haWwoKSk7CisgICAgICB9CisKKyAgICAgIGZvciAoUGVyc29uLlBob25lTnVtYmVyIHBob25lTnVtYmVyIDogcGVyc29uLmdldFBob25lTGlzdCgpKSB7CisgICAgICAgIHN3aXRjaCAocGhvbmVOdW1iZXIuZ2V0VHlwZSgpKSB7CisgICAgICAgICAgY2FzZSBNT0JJTEU6CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgIE1vYmlsZSBwaG9uZSAjOiAiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSE9NRToKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAgSG9tZSBwaG9uZSAjOiAiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgV09SSzoKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAgV29yayBwaG9uZSAjOiAiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihwaG9uZU51bWJlci5nZXROdW1iZXIoKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gTWFpbiBmdW5jdGlvbjogIFJlYWRzIHRoZSBlbnRpcmUgYWRkcmVzcyBib29rIGZyb20gYSBmaWxlIGFuZCBwcmludHMgYWxsCisgIC8vICAgdGhlIGluZm9ybWF0aW9uIGluc2lkZS4KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgaWYgKGFyZ3MubGVuZ3RoICE9IDEpIHsKKyAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6ICBMaXN0UGVvcGxlIEFERFJFU1NfQk9PS19GSUxFIik7CisgICAgICBTeXN0ZW0uZXhpdCgtMSk7CisgICAgfQorCisgICAgLy8gUmVhZCB0aGUgZXhpc3RpbmcgYWRkcmVzcyBib29rLgorICAgIEFkZHJlc3NCb29rIGFkZHJlc3NCb29rID0KKyAgICAgIEFkZHJlc3NCb29rLnBhcnNlRnJvbShuZXcgRmlsZUlucHV0U3RyZWFtKGFyZ3NbMF0pKTsKKworICAgIFByaW50KGFkZHJlc3NCb29rKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvZXhhbXBsZXMvTWFrZWZpbGUgYi9leGFtcGxlcy9NYWtlZmlsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZGM5MDgzCi0tLSAvZGV2L251bGwKKysrIGIvZXhhbXBsZXMvTWFrZWZpbGUKQEAgLTAsMCArMSw1OCBAQAorIyBTZWUgUkVBRE1FLnR4dC4KKworLlBIT05ZOiBhbGwgY3BwIGphdmEgcHl0aG9uIGNsZWFuCisKK2FsbDogY3BwIGphdmEgcHl0aG9uCisKK2NwcDogICAgYWRkX3BlcnNvbl9jcHAgICAgbGlzdF9wZW9wbGVfY3BwCitqYXZhOiAgIGFkZF9wZXJzb25famF2YSAgIGxpc3RfcGVvcGxlX2phdmEKK3B5dGhvbjogYWRkX3BlcnNvbl9weXRob24gbGlzdF9wZW9wbGVfcHl0aG9uCisKK2NsZWFuOgorCXJtIC1mIGFkZF9wZXJzb25fY3BwIGxpc3RfcGVvcGxlX2NwcCBhZGRfcGVyc29uX2phdmEgbGlzdF9wZW9wbGVfamF2YSBhZGRfcGVyc29uX3B5dGhvbiBsaXN0X3Blb3BsZV9weXRob24KKwlybSAtZiBqYXZhY19taWRkbGVtYW4gQWRkUGVyc29uKi5jbGFzcyBMaXN0UGVvcGxlKi5jbGFzcyBjb20vZXhhbXBsZS90dXRvcmlhbC8qLmNsYXNzCisJcm0gLWYgcHJvdG9jX21pZGRsZW1hbiBhZGRyZXNzYm9vay5wYi5jYyBhZGRyZXNzYm9vay5wYi5oIGFkZHJlc3Nib29rX3BiMi5weSBjb20vZXhhbXBsZS90dXRvcmlhbC9BZGRyZXNzQm9va1Byb3Rvcy5qYXZhCisJcm0gLWYgKi5weWMKKwlybWRpciBjb20vZXhhbXBsZS90dXRvcmlhbCAyPi9kZXYvbnVsbCB8fCB0cnVlCisJcm1kaXIgY29tL2V4YW1wbGUgMj4vZGV2L251bGwgfHwgdHJ1ZQorCXJtZGlyIGNvbSAyPi9kZXYvbnVsbCB8fCB0cnVlCisKK3Byb3RvY19taWRkbGVtYW46IGFkZHJlc3Nib29rLnByb3RvCisJcHJvdG9jIC0tY3BwX291dD0uIC0tamF2YV9vdXQ9LiAtLXB5dGhvbl9vdXQ9LiBhZGRyZXNzYm9vay5wcm90bworCUB0b3VjaCBwcm90b2NfbWlkZGxlbWFuCisKK2FkZF9wZXJzb25fY3BwOiBhZGRfcGVyc29uLmNjIHByb3RvY19taWRkbGVtYW4KKwlwa2ctY29uZmlnIC0tY2ZsYWdzIHByb3RvYnVmICAjIGZhaWxzIGlmIHByb3RvYnVmIGlzIG5vdCBpbnN0YWxsZWQKKwljKysgYWRkX3BlcnNvbi5jYyBhZGRyZXNzYm9vay5wYi5jYyAtbyBhZGRfcGVyc29uX2NwcCBgcGtnLWNvbmZpZyAtLWNmbGFncyAtLWxpYnMgcHJvdG9idWZgCisKK2xpc3RfcGVvcGxlX2NwcDogbGlzdF9wZW9wbGUuY2MgcHJvdG9jX21pZGRsZW1hbgorCXBrZy1jb25maWcgLS1jZmxhZ3MgcHJvdG9idWYgICMgZmFpbHMgaWYgcHJvdG9idWYgaXMgbm90IGluc3RhbGxlZAorCWMrKyBsaXN0X3Blb3BsZS5jYyBhZGRyZXNzYm9vay5wYi5jYyAtbyBsaXN0X3Blb3BsZV9jcHAgYHBrZy1jb25maWcgLS1jZmxhZ3MgLS1saWJzIHByb3RvYnVmYAorCitqYXZhY19taWRkbGVtYW46IEFkZFBlcnNvbi5qYXZhIExpc3RQZW9wbGUuamF2YSBwcm90b2NfbWlkZGxlbWFuCisJamF2YWMgQWRkUGVyc29uLmphdmEgTGlzdFBlb3BsZS5qYXZhIGNvbS9leGFtcGxlL3R1dG9yaWFsL0FkZHJlc3NCb29rUHJvdG9zLmphdmEKKwlAdG91Y2ggamF2YWNfbWlkZGxlbWFuCisKK2FkZF9wZXJzb25famF2YTogamF2YWNfbWlkZGxlbWFuCisJQGVjaG8gIldyaXRpbmcgc2hvcnRjdXQgc2NyaXB0IGFkZF9wZXJzb25famF2YS4uLiIKKwlAZWNobyAnIyEgL2Jpbi9zaCcgPiBhZGRfcGVyc29uX2phdmEKKwlAZWNobyAnamF2YSAtY2xhc3NwYXRoIC46JCRDTEFTU1BBVEggQWRkUGVyc29uICIkJEAiJyA+PiBhZGRfcGVyc29uX2phdmEKKwlAY2htb2QgK3ggYWRkX3BlcnNvbl9qYXZhCisKK2xpc3RfcGVvcGxlX2phdmE6IGphdmFjX21pZGRsZW1hbgorCUBlY2hvICJXcml0aW5nIHNob3J0Y3V0IHNjcmlwdCBsaXN0X3Blb3BsZV9qYXZhLi4uIgorCUBlY2hvICcjISAvYmluL3NoJyA+IGxpc3RfcGVvcGxlX2phdmEKKwlAZWNobyAnamF2YSAtY2xhc3NwYXRoIC46JCRDTEFTU1BBVEggTGlzdFBlb3BsZSAiJCRAIicgPj4gbGlzdF9wZW9wbGVfamF2YQorCUBjaG1vZCAreCBsaXN0X3Blb3BsZV9qYXZhCisKK2FkZF9wZXJzb25fcHl0aG9uOiBhZGRfcGVyc29uLnB5IHByb3RvY19taWRkbGVtYW4KKwlAZWNobyAiV3JpdGluZyBzaG9ydGN1dCBzY3JpcHQgYWRkX3BlcnNvbl9weXRob24uLi4iCisJQGVjaG8gJyMhIC9iaW4vc2gnID4gYWRkX3BlcnNvbl9weXRob24KKwlAZWNobyAnLi9hZGRfcGVyc29uLnB5ICIkJEAiJyA+PiBhZGRfcGVyc29uX3B5dGhvbgorCUBjaG1vZCAreCBhZGRfcGVyc29uX3B5dGhvbgorCitsaXN0X3Blb3BsZV9weXRob246IGxpc3RfcGVvcGxlLnB5IHByb3RvY19taWRkbGVtYW4KKwlAZWNobyAiV3JpdGluZyBzaG9ydGN1dCBzY3JpcHQgbGlzdF9wZW9wbGVfcHl0aG9uLi4uIgorCUBlY2hvICcjISAvYmluL3NoJyA+IGxpc3RfcGVvcGxlX3B5dGhvbgorCUBlY2hvICcuL2xpc3RfcGVvcGxlLnB5ICIkJEAiJyA+PiBsaXN0X3Blb3BsZV9weXRob24KKwlAY2htb2QgK3ggbGlzdF9wZW9wbGVfcHl0aG9uCmRpZmYgLS1naXQgYS9leGFtcGxlcy9SRUFETUUudHh0IGIvZXhhbXBsZXMvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNTUzMGE1Ci0tLSAvZGV2L251bGwKKysrIGIvZXhhbXBsZXMvUkVBRE1FLnR4dApAQCAtMCwwICsxLDI5IEBACitUaGlzIGRpcmVjdG9yeSBjb250YWlucyBleGFtcGxlIGNvZGUgdGhhdCB1c2VzIFByb3RvY29sIEJ1ZmZlcnMgdG8gbWFuYWdlIGFuCithZGRyZXNzIGJvb2suICBUd28gcHJvZ3JhbXMgYXJlIHByb3ZpZGVkLCBlYWNoIHdpdGggdGhyZWUgZGlmZmVyZW50CitpbXBsZW1lbnRhdGlvbnMsIG9uZSB3cml0dGVuIGluIGVhY2ggb2YgQysrLCBKYXZhLCBhbmQgUHl0aG9uLiAgVGhlIGFkZF9wZXJzb24KK2V4YW1wbGUgYWRkcyBhIG5ldyBwZXJzb24gdG8gYW4gYWRkcmVzcyBib29rLCBwcm9tcHRpbmcgdGhlIHVzZXIgdG8gaW5wdXQKK3RoZSBwZXJzb24ncyBpbmZvcm1hdGlvbi4gIFRoZSBsaXN0X3Blb3BsZSBleGFtcGxlIGxpc3RzIHBlb3BsZSBhbHJlYWR5IGluIHRoZQorYWRkcmVzcyBib29rLiAgVGhlIGV4YW1wbGVzIHVzZSB0aGUgZXhhY3Qgc2FtZSBmb3JtYXQgaW4gYWxsIHRocmVlIGxhbmd1YWdlcywKK3NvIHlvdSBjYW4sIGZvciBleGFtcGxlLCB1c2UgYWRkX3BlcnNvbl9qYXZhIHRvIGNyZWF0ZSBhbiBhZGRyZXNzIGJvb2sgYW5kIHRoZW4KK3VzZSBsaXN0X3Blb3BsZV9weXRob24gdG8gcmVhZCBpdC4KKworWW91IG11c3QgaW5zdGFsbCB0aGUgcHJvdG9idWYgcGFja2FnZSBiZWZvcmUgeW91IGNhbiBidWlsZCB0aGVzZS4KKworVG8gYnVpbGQgYWxsIHRoZSBleGFtcGxlcyAob24gYSB1bml4LWxpa2Ugc3lzdGVtKSwgc2ltcGx5IHJ1biAibWFrZSIuICBUaGlzCitjcmVhdGVzIHRoZSBmb2xsb3dpbmcgZXhlY3V0YWJsZSBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3Rvcnk6CisgIGFkZF9wZXJzb25fY3BwICAgICBsaXN0X3Blb3BsZV9jcHAKKyAgYWRkX3BlcnNvbl9qYXZhICAgIGxpc3RfcGVvcGxlX2phdmEKKyAgYWRkX3BlcnNvbl9weXRob24gIGxpc3RfcGVvcGxlX3B5dGhvbgorCitJZiB5b3Ugb25seSB3YW50IHRvIGNvbXBpbGUgZXhhbXBsZXMgaW4gb25lIGxhbmd1YWdlLCB1c2UgIm1ha2UgY3BwIiosCisibWFrZSBqYXZhIiwgb3IgIm1ha2UgcHl0aG9uIi4KKworQWxsIG9mIHRoZXNlIHByb2dyYW1zIHNpbXBseSB0YWtlIGFuIGFkZHJlc3MgYm9vayBmaWxlIGFzIHRoZWlyIHBhcmFtZXRlci4KK1RoZSBhZGRfcGVyc29uIHByb2dyYW1zIHdpbGwgY3JlYXRlIHRoZSBmaWxlIGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC4KKworVGhlc2UgZXhhbXBsZXMgYXJlIHBhcnQgb2YgdGhlIFByb3RvY29sIEJ1ZmZlcnMgdHV0b3JpYWwsIGxvY2F0ZWQgYXQ6CisgIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvZG9jcy90dXRvcmlhbHMKKworKiBOb3RlIHRoYXQgb24gc29tZSBwbGF0Zm9ybXMgeW91IG1heSBoYXZlIHRvIGVkaXQgdGhlIE1ha2VmaWxlIGFuZCByZW1vdmUKKyItbHB0aHJlYWQiIGZyb20gdGhlIGxpbmtlciBjb21tYW5kcyAocGVyaGFwcyByZXBsYWNpbmcgaXQgd2l0aCBzb21ldGhpbmcgZWxzZSkuCitXZSBkaWRuJ3QgZG8gdGhpcyBhdXRvbWF0aWNhbGx5IGJlY2F1c2Ugd2Ugd2FudGVkIHRvIGtlZXAgdGhlIGV4YW1wbGUgc2ltcGxlLgpkaWZmIC0tZ2l0IGEvZXhhbXBsZXMvYWRkX3BlcnNvbi5jYyBiL2V4YW1wbGVzL2FkZF9wZXJzb24uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjljYTQ0ZgotLS0gL2Rldi9udWxsCisrKyBiL2V4YW1wbGVzL2FkZF9wZXJzb24uY2MKQEAgLTAsMCArMSw5NSBAQAorLy8gU2VlIFJFQURNRS50eHQgZm9yIGluZm9ybWF0aW9uIGFuZCBidWlsZCBpbnN0cnVjdGlvbnMuCisKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxmc3RyZWFtPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlICJhZGRyZXNzYm9vay5wYi5oIgordXNpbmcgbmFtZXNwYWNlIHN0ZDsKKworLy8gVGhpcyBmdW5jdGlvbiBmaWxscyBpbiBhIFBlcnNvbiBtZXNzYWdlIGJhc2VkIG9uIHVzZXIgaW5wdXQuCit2b2lkIFByb21wdEZvckFkZHJlc3ModHV0b3JpYWw6OlBlcnNvbiogcGVyc29uKSB7CisgIGNvdXQgPDwgIkVudGVyIHBlcnNvbiBJRCBudW1iZXI6ICI7CisgIGludCBpZDsKKyAgY2luID4+IGlkOworICBwZXJzb24tPnNldF9pZChpZCk7CisgIGNpbi5pZ25vcmUoMjU2LCAnXG4nKTsKKworICBjb3V0IDw8ICJFbnRlciBuYW1lOiAiOworICBnZXRsaW5lKGNpbiwgKnBlcnNvbi0+bXV0YWJsZV9uYW1lKCkpOworCisgIGNvdXQgPDwgIkVudGVyIGVtYWlsIGFkZHJlc3MgKGJsYW5rIGZvciBub25lKTogIjsKKyAgc3RyaW5nIGVtYWlsOworICBnZXRsaW5lKGNpbiwgZW1haWwpOworICBpZiAoIWVtYWlsLmVtcHR5KCkpIHsKKyAgICBwZXJzb24tPnNldF9lbWFpbChlbWFpbCk7CisgIH0KKworICB3aGlsZSAodHJ1ZSkgeworICAgIGNvdXQgPDwgIkVudGVyIGEgcGhvbmUgbnVtYmVyIChvciBsZWF2ZSBibGFuayB0byBmaW5pc2gpOiAiOworICAgIHN0cmluZyBudW1iZXI7CisgICAgZ2V0bGluZShjaW4sIG51bWJlcik7CisgICAgaWYgKG51bWJlci5lbXB0eSgpKSB7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICB0dXRvcmlhbDo6UGVyc29uOjpQaG9uZU51bWJlciogcGhvbmVfbnVtYmVyID0gcGVyc29uLT5hZGRfcGhvbmUoKTsKKyAgICBwaG9uZV9udW1iZXItPnNldF9udW1iZXIobnVtYmVyKTsKKworICAgIGNvdXQgPDwgIklzIHRoaXMgYSBtb2JpbGUsIGhvbWUsIG9yIHdvcmsgcGhvbmU/ICI7CisgICAgc3RyaW5nIHR5cGU7CisgICAgZ2V0bGluZShjaW4sIHR5cGUpOworICAgIGlmICh0eXBlID09ICJtb2JpbGUiKSB7CisgICAgICBwaG9uZV9udW1iZXItPnNldF90eXBlKHR1dG9yaWFsOjpQZXJzb246Ok1PQklMRSk7CisgICAgfSBlbHNlIGlmICh0eXBlID09ICJob21lIikgeworICAgICAgcGhvbmVfbnVtYmVyLT5zZXRfdHlwZSh0dXRvcmlhbDo6UGVyc29uOjpIT01FKTsKKyAgICB9IGVsc2UgaWYgKHR5cGUgPT0gIndvcmsiKSB7CisgICAgICBwaG9uZV9udW1iZXItPnNldF90eXBlKHR1dG9yaWFsOjpQZXJzb246OldPUkspOworICAgIH0gZWxzZSB7CisgICAgICBjb3V0IDw8ICJVbmtub3duIHBob25lIHR5cGUuICBVc2luZyBkZWZhdWx0LiIgPDwgZW5kbDsKKyAgICB9CisgIH0KK30KKworLy8gTWFpbiBmdW5jdGlvbjogIFJlYWRzIHRoZSBlbnRpcmUgYWRkcmVzcyBib29rIGZyb20gYSBmaWxlLAorLy8gICBhZGRzIG9uZSBwZXJzb24gYmFzZWQgb24gdXNlciBpbnB1dCwgdGhlbiB3cml0ZXMgaXQgYmFjayBvdXQgdG8gdGhlIHNhbWUKKy8vICAgZmlsZS4KK2ludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2W10pIHsKKyAgLy8gVmVyaWZ5IHRoYXQgdGhlIHZlcnNpb24gb2YgdGhlIGxpYnJhcnkgdGhhdCB3ZSBsaW5rZWQgYWdhaW5zdCBpcworICAvLyBjb21wYXRpYmxlIHdpdGggdGhlIHZlcnNpb24gb2YgdGhlIGhlYWRlcnMgd2UgY29tcGlsZWQgYWdhaW5zdC4KKyAgR09PR0xFX1BST1RPQlVGX1ZFUklGWV9WRVJTSU9OOworCisgIGlmIChhcmdjICE9IDIpIHsKKyAgICBjZXJyIDw8ICJVc2FnZTogICIgPDwgYXJndlswXSA8PCAiIEFERFJFU1NfQk9PS19GSUxFIiA8PCBlbmRsOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIHR1dG9yaWFsOjpBZGRyZXNzQm9vayBhZGRyZXNzX2Jvb2s7CisKKyAgeworICAgIC8vIFJlYWQgdGhlIGV4aXN0aW5nIGFkZHJlc3MgYm9vay4KKyAgICBmc3RyZWFtIGlucHV0KGFyZ3ZbMV0sIGlvczo6aW4gfCBpb3M6OmJpbmFyeSk7CisgICAgaWYgKCFpbnB1dCkgeworICAgICAgY291dCA8PCBhcmd2WzFdIDw8ICI6IEZpbGUgbm90IGZvdW5kLiAgQ3JlYXRpbmcgYSBuZXcgZmlsZS4iIDw8IGVuZGw7CisgICAgfSBlbHNlIGlmICghYWRkcmVzc19ib29rLlBhcnNlRnJvbUlzdHJlYW0oJmlucHV0KSkgeworICAgICAgY2VyciA8PCAiRmFpbGVkIHRvIHBhcnNlIGFkZHJlc3MgYm9vay4iIDw8IGVuZGw7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICB9CisKKyAgLy8gQWRkIGFuIGFkZHJlc3MuCisgIFByb21wdEZvckFkZHJlc3MoYWRkcmVzc19ib29rLmFkZF9wZXJzb24oKSk7CisKKyAgeworICAgIC8vIFdyaXRlIHRoZSBuZXcgYWRkcmVzcyBib29rIGJhY2sgdG8gZGlzay4KKyAgICBmc3RyZWFtIG91dHB1dChhcmd2WzFdLCBpb3M6Om91dCB8IGlvczo6dHJ1bmMgfCBpb3M6OmJpbmFyeSk7CisgICAgaWYgKCFhZGRyZXNzX2Jvb2suU2VyaWFsaXplVG9Pc3RyZWFtKCZvdXRwdXQpKSB7CisgICAgICBjZXJyIDw8ICJGYWlsZWQgdG8gd3JpdGUgYWRkcmVzcyBib29rLiIgPDwgZW5kbDsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0KKworICAvLyBPcHRpb25hbDogIERlbGV0ZSBhbGwgZ2xvYmFsIG9iamVjdHMgYWxsb2NhdGVkIGJ5IGxpYnByb3RvYnVmLgorICBnb29nbGU6OnByb3RvYnVmOjpTaHV0ZG93blByb3RvYnVmTGlicmFyeSgpOworCisgIHJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEvZXhhbXBsZXMvYWRkX3BlcnNvbi5weSBiL2V4YW1wbGVzL2FkZF9wZXJzb24ucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNzhlNTY5NgotLS0gL2Rldi9udWxsCisrKyBiL2V4YW1wbGVzL2FkZF9wZXJzb24ucHkKQEAgLTAsMCArMSw1OCBAQAorIyEgL3Vzci9iaW4vcHl0aG9uCisKKyMgU2VlIFJFQURNRS50eHQgZm9yIGluZm9ybWF0aW9uIGFuZCBidWlsZCBpbnN0cnVjdGlvbnMuCisKK2ltcG9ydCBhZGRyZXNzYm9va19wYjIKK2ltcG9ydCBzeXMKKworIyBUaGlzIGZ1bmN0aW9uIGZpbGxzIGluIGEgUGVyc29uIG1lc3NhZ2UgYmFzZWQgb24gdXNlciBpbnB1dC4KK2RlZiBQcm9tcHRGb3JBZGRyZXNzKHBlcnNvbik6CisgIHBlcnNvbi5pZCA9IGludChyYXdfaW5wdXQoIkVudGVyIHBlcnNvbiBJRCBudW1iZXI6ICIpKQorICBwZXJzb24ubmFtZSA9IHJhd19pbnB1dCgiRW50ZXIgbmFtZTogIikKKworICBlbWFpbCA9IHJhd19pbnB1dCgiRW50ZXIgZW1haWwgYWRkcmVzcyAoYmxhbmsgZm9yIG5vbmUpOiAiKQorICBpZiBlbWFpbCAhPSAiIjoKKyAgICBwZXJzb24uZW1haWwgPSBlbWFpbAorCisgIHdoaWxlIFRydWU6CisgICAgbnVtYmVyID0gcmF3X2lucHV0KCJFbnRlciBhIHBob25lIG51bWJlciAob3IgbGVhdmUgYmxhbmsgdG8gZmluaXNoKTogIikKKyAgICBpZiBudW1iZXIgPT0gIiI6CisgICAgICBicmVhaworCisgICAgcGhvbmVfbnVtYmVyID0gcGVyc29uLnBob25lLmFkZCgpCisgICAgcGhvbmVfbnVtYmVyLm51bWJlciA9IG51bWJlcgorCisgICAgdHlwZSA9IHJhd19pbnB1dCgiSXMgdGhpcyBhIG1vYmlsZSwgaG9tZSwgb3Igd29yayBwaG9uZT8gIikKKyAgICBpZiB0eXBlID09ICJtb2JpbGUiOgorICAgICAgcGhvbmVfbnVtYmVyLnR5cGUgPSBhZGRyZXNzYm9va19wYjIuUGVyc29uLk1PQklMRQorICAgIGVsaWYgdHlwZSA9PSAiaG9tZSI6CisgICAgICBwaG9uZV9udW1iZXIudHlwZSA9IGFkZHJlc3Nib29rX3BiMi5QZXJzb24uSE9NRQorICAgIGVsaWYgdHlwZSA9PSAid29yayI6CisgICAgICBwaG9uZV9udW1iZXIudHlwZSA9IGFkZHJlc3Nib29rX3BiMi5QZXJzb24uV09SSworICAgIGVsc2U6CisgICAgICBwcmludCAiVW5rbm93biBwaG9uZSB0eXBlOyBsZWF2aW5nIGFzIGRlZmF1bHQgdmFsdWUuIgorCisjIE1haW4gcHJvY2VkdXJlOiAgUmVhZHMgdGhlIGVudGlyZSBhZGRyZXNzIGJvb2sgZnJvbSBhIGZpbGUsCisjICAgYWRkcyBvbmUgcGVyc29uIGJhc2VkIG9uIHVzZXIgaW5wdXQsIHRoZW4gd3JpdGVzIGl0IGJhY2sgb3V0IHRvIHRoZSBzYW1lCisjICAgZmlsZS4KK2lmIGxlbihzeXMuYXJndikgIT0gMjoKKyAgcHJpbnQgIlVzYWdlOiIsIHN5cy5hcmd2WzBdLCAiQUREUkVTU19CT09LX0ZJTEUiCisgIHN5cy5leGl0KC0xKQorCithZGRyZXNzX2Jvb2sgPSBhZGRyZXNzYm9va19wYjIuQWRkcmVzc0Jvb2soKQorCisjIFJlYWQgdGhlIGV4aXN0aW5nIGFkZHJlc3MgYm9vay4KK3RyeToKKyAgZiA9IG9wZW4oc3lzLmFyZ3ZbMV0sICJyYiIpCisgIGFkZHJlc3NfYm9vay5QYXJzZUZyb21TdHJpbmcoZi5yZWFkKCkpCisgIGYuY2xvc2UoKQorZXhjZXB0IElPRXJyb3I6CisgIHByaW50IHN5cy5hcmd2WzFdICsgIjogRmlsZSBub3QgZm91bmQuICBDcmVhdGluZyBhIG5ldyBmaWxlLiIKKworIyBBZGQgYW4gYWRkcmVzcy4KK1Byb21wdEZvckFkZHJlc3MoYWRkcmVzc19ib29rLnBlcnNvbi5hZGQoKSkKKworIyBXcml0ZSB0aGUgbmV3IGFkZHJlc3MgYm9vayBiYWNrIHRvIGRpc2suCitmID0gb3BlbihzeXMuYXJndlsxXSwgIndiIikKK2Yud3JpdGUoYWRkcmVzc19ib29rLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCitmLmNsb3NlKCkKZGlmZiAtLWdpdCBhL2V4YW1wbGVzL2FkZHJlc3Nib29rLnByb3RvIGIvZXhhbXBsZXMvYWRkcmVzc2Jvb2sucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE0ODI5ZQotLS0gL2Rldi9udWxsCisrKyBiL2V4YW1wbGVzL2FkZHJlc3Nib29rLnByb3RvCkBAIC0wLDAgKzEsMzAgQEAKKy8vIFNlZSBSRUFETUUudHh0IGZvciBpbmZvcm1hdGlvbiBhbmQgYnVpbGQgaW5zdHJ1Y3Rpb25zLgorCitwYWNrYWdlIHR1dG9yaWFsOworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5leGFtcGxlLnR1dG9yaWFsIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJBZGRyZXNzQm9va1Byb3RvcyI7CisKK21lc3NhZ2UgUGVyc29uIHsKKyAgcmVxdWlyZWQgc3RyaW5nIG5hbWUgPSAxOworICByZXF1aXJlZCBpbnQzMiBpZCA9IDI7ICAgICAgICAvLyBVbmlxdWUgSUQgbnVtYmVyIGZvciB0aGlzIHBlcnNvbi4KKyAgb3B0aW9uYWwgc3RyaW5nIGVtYWlsID0gMzsKKworICBlbnVtIFBob25lVHlwZSB7CisgICAgTU9CSUxFID0gMDsKKyAgICBIT01FID0gMTsKKyAgICBXT1JLID0gMjsKKyAgfQorCisgIG1lc3NhZ2UgUGhvbmVOdW1iZXIgeworICAgIHJlcXVpcmVkIHN0cmluZyBudW1iZXIgPSAxOworICAgIG9wdGlvbmFsIFBob25lVHlwZSB0eXBlID0gMiBbZGVmYXVsdCA9IEhPTUVdOworICB9CisKKyAgcmVwZWF0ZWQgUGhvbmVOdW1iZXIgcGhvbmUgPSA0OworfQorCisvLyBPdXIgYWRkcmVzcyBib29rIGZpbGUgaXMganVzdCBvbmUgb2YgdGhlc2UuCittZXNzYWdlIEFkZHJlc3NCb29rIHsKKyAgcmVwZWF0ZWQgUGVyc29uIHBlcnNvbiA9IDE7Cit9CmRpZmYgLS1naXQgYS9leGFtcGxlcy9saXN0X3Blb3BsZS5jYyBiL2V4YW1wbGVzL2xpc3RfcGVvcGxlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUzNjMxNTIKLS0tIC9kZXYvbnVsbAorKysgYi9leGFtcGxlcy9saXN0X3Blb3BsZS5jYwpAQCAtMCwwICsxLDY4IEBACisvLyBTZWUgUkVBRE1FLnR4dCBmb3IgaW5mb3JtYXRpb24gYW5kIGJ1aWxkIGluc3RydWN0aW9ucy4KKworI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPGZzdHJlYW0+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgImFkZHJlc3Nib29rLnBiLmgiCit1c2luZyBuYW1lc3BhY2Ugc3RkOworCisvLyBJdGVyYXRlcyB0aG91Z2ggYWxsIHBlb3BsZSBpbiB0aGUgQWRkcmVzc0Jvb2sgYW5kIHByaW50cyBpbmZvIGFib3V0IHRoZW0uCit2b2lkIExpc3RQZW9wbGUoY29uc3QgdHV0b3JpYWw6OkFkZHJlc3NCb29rJiBhZGRyZXNzX2Jvb2spIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyZXNzX2Jvb2sucGVyc29uX3NpemUoKTsgaSsrKSB7CisgICAgY29uc3QgdHV0b3JpYWw6OlBlcnNvbiYgcGVyc29uID0gYWRkcmVzc19ib29rLnBlcnNvbihpKTsKKworICAgIGNvdXQgPDwgIlBlcnNvbiBJRDogIiA8PCBwZXJzb24uaWQoKSA8PCBlbmRsOworICAgIGNvdXQgPDwgIiAgTmFtZTogIiA8PCBwZXJzb24ubmFtZSgpIDw8IGVuZGw7CisgICAgaWYgKHBlcnNvbi5oYXNfZW1haWwoKSkgeworICAgICAgY291dCA8PCAiICBFLW1haWwgYWRkcmVzczogIiA8PCBwZXJzb24uZW1haWwoKSA8PCBlbmRsOworICAgIH0KKworICAgIGZvciAoaW50IGogPSAwOyBqIDwgcGVyc29uLnBob25lX3NpemUoKTsgaisrKSB7CisgICAgICBjb25zdCB0dXRvcmlhbDo6UGVyc29uOjpQaG9uZU51bWJlciYgcGhvbmVfbnVtYmVyID0gcGVyc29uLnBob25lKGopOworCisgICAgICBzd2l0Y2ggKHBob25lX251bWJlci50eXBlKCkpIHsKKyAgICAgICAgY2FzZSB0dXRvcmlhbDo6UGVyc29uOjpNT0JJTEU6CisgICAgICAgICAgY291dCA8PCAiICBNb2JpbGUgcGhvbmUgIzogIjsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSB0dXRvcmlhbDo6UGVyc29uOjpIT01FOgorICAgICAgICAgIGNvdXQgPDwgIiAgSG9tZSBwaG9uZSAjOiAiOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIHR1dG9yaWFsOjpQZXJzb246OldPUks6CisgICAgICAgICAgY291dCA8PCAiICBXb3JrIHBob25lICM6ICI7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjb3V0IDw8IHBob25lX251bWJlci5udW1iZXIoKSA8PCBlbmRsOworICAgIH0KKyAgfQorfQorCisvLyBNYWluIGZ1bmN0aW9uOiAgUmVhZHMgdGhlIGVudGlyZSBhZGRyZXNzIGJvb2sgZnJvbSBhIGZpbGUgYW5kIHByaW50cyBhbGwKKy8vICAgdGhlIGluZm9ybWF0aW9uIGluc2lkZS4KK2ludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2W10pIHsKKyAgLy8gVmVyaWZ5IHRoYXQgdGhlIHZlcnNpb24gb2YgdGhlIGxpYnJhcnkgdGhhdCB3ZSBsaW5rZWQgYWdhaW5zdCBpcworICAvLyBjb21wYXRpYmxlIHdpdGggdGhlIHZlcnNpb24gb2YgdGhlIGhlYWRlcnMgd2UgY29tcGlsZWQgYWdhaW5zdC4KKyAgR09PR0xFX1BST1RPQlVGX1ZFUklGWV9WRVJTSU9OOworCisgIGlmIChhcmdjICE9IDIpIHsKKyAgICBjZXJyIDw8ICJVc2FnZTogICIgPDwgYXJndlswXSA8PCAiIEFERFJFU1NfQk9PS19GSUxFIiA8PCBlbmRsOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIHR1dG9yaWFsOjpBZGRyZXNzQm9vayBhZGRyZXNzX2Jvb2s7CisKKyAgeworICAgIC8vIFJlYWQgdGhlIGV4aXN0aW5nIGFkZHJlc3MgYm9vay4KKyAgICBmc3RyZWFtIGlucHV0KGFyZ3ZbMV0sIGlvczo6aW4gfCBpb3M6OmJpbmFyeSk7CisgICAgaWYgKCFhZGRyZXNzX2Jvb2suUGFyc2VGcm9tSXN0cmVhbSgmaW5wdXQpKSB7CisgICAgICBjZXJyIDw8ICJGYWlsZWQgdG8gcGFyc2UgYWRkcmVzcyBib29rLiIgPDwgZW5kbDsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0KKworICBMaXN0UGVvcGxlKGFkZHJlc3NfYm9vayk7CisKKyAgLy8gT3B0aW9uYWw6ICBEZWxldGUgYWxsIGdsb2JhbCBvYmplY3RzIGFsbG9jYXRlZCBieSBsaWJwcm90b2J1Zi4KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6U2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKTsKKworICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL2V4YW1wbGVzL2xpc3RfcGVvcGxlLnB5IGIvZXhhbXBsZXMvbGlzdF9wZW9wbGUucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZjlmMzZiOQotLS0gL2Rldi9udWxsCisrKyBiL2V4YW1wbGVzL2xpc3RfcGVvcGxlLnB5CkBAIC0wLDAgKzEsMzggQEAKKyMhIC91c3IvYmluL3B5dGhvbgorCisjIFNlZSBSRUFETUUudHh0IGZvciBpbmZvcm1hdGlvbiBhbmQgYnVpbGQgaW5zdHJ1Y3Rpb25zLgorCitpbXBvcnQgYWRkcmVzc2Jvb2tfcGIyCitpbXBvcnQgc3lzCisKKyMgSXRlcmF0ZXMgdGhvdWdoIGFsbCBwZW9wbGUgaW4gdGhlIEFkZHJlc3NCb29rIGFuZCBwcmludHMgaW5mbyBhYm91dCB0aGVtLgorZGVmIExpc3RQZW9wbGUoYWRkcmVzc19ib29rKToKKyAgZm9yIHBlcnNvbiBpbiBhZGRyZXNzX2Jvb2sucGVyc29uOgorICAgIHByaW50ICJQZXJzb24gSUQ6IiwgcGVyc29uLmlkCisgICAgcHJpbnQgIiAgTmFtZToiLCBwZXJzb24ubmFtZQorICAgIGlmIHBlcnNvbi5IYXNGaWVsZCgnZW1haWwnKToKKyAgICAgIHByaW50ICIgIEUtbWFpbCBhZGRyZXNzOiIsIHBlcnNvbi5lbWFpbAorCisgICAgZm9yIHBob25lX251bWJlciBpbiBwZXJzb24ucGhvbmU6CisgICAgICBpZiBwaG9uZV9udW1iZXIudHlwZSA9PSBhZGRyZXNzYm9va19wYjIuUGVyc29uLk1PQklMRToKKyAgICAgICAgcHJpbnQgIiAgTW9iaWxlIHBob25lICM6IiwKKyAgICAgIGVsaWYgcGhvbmVfbnVtYmVyLnR5cGUgPT0gYWRkcmVzc2Jvb2tfcGIyLlBlcnNvbi5IT01FOgorICAgICAgICBwcmludCAiICBIb21lIHBob25lICM6IiwKKyAgICAgIGVsaWYgcGhvbmVfbnVtYmVyLnR5cGUgPT0gYWRkcmVzc2Jvb2tfcGIyLlBlcnNvbi5XT1JLOgorICAgICAgICBwcmludCAiICBXb3JrIHBob25lICM6IiwKKyAgICAgIHByaW50IHBob25lX251bWJlci5udW1iZXIKKworIyBNYWluIHByb2NlZHVyZTogIFJlYWRzIHRoZSBlbnRpcmUgYWRkcmVzcyBib29rIGZyb20gYSBmaWxlIGFuZCBwcmludHMgYWxsCisjICAgdGhlIGluZm9ybWF0aW9uIGluc2lkZS4KK2lmIGxlbihzeXMuYXJndikgIT0gMjoKKyAgcHJpbnQgIlVzYWdlOiIsIHN5cy5hcmd2WzBdLCAiQUREUkVTU19CT09LX0ZJTEUiCisgIHN5cy5leGl0KC0xKQorCithZGRyZXNzX2Jvb2sgPSBhZGRyZXNzYm9va19wYjIuQWRkcmVzc0Jvb2soKQorCisjIFJlYWQgdGhlIGV4aXN0aW5nIGFkZHJlc3MgYm9vay4KK2YgPSBvcGVuKHN5cy5hcmd2WzFdLCAicmIiKQorYWRkcmVzc19ib29rLlBhcnNlRnJvbVN0cmluZyhmLnJlYWQoKSkKK2YuY2xvc2UoKQorCitMaXN0UGVvcGxlKGFkZHJlc3NfYm9vaykKZGlmZiAtLWdpdCBhL2dlbmVyYXRlX2Rlc2NyaXB0b3JfcHJvdG8uc2ggYi9nZW5lcmF0ZV9kZXNjcmlwdG9yX3Byb3RvLnNoCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmIyNWEzYzYKLS0tIC9kZXYvbnVsbAorKysgYi9nZW5lcmF0ZV9kZXNjcmlwdG9yX3Byb3RvLnNoCkBAIC0wLDAgKzEsNjUgQEAKKyMhL2Jpbi9zaAorCisjIFJ1biB0aGlzIHNjcmlwdCB0byByZWdlbmVyYXRlIGRlc2NyaXB0b3IucGIue2gsY2N9IGFmdGVyIHRoZSBwcm90b2NvbAorIyBjb21waWxlciBjaGFuZ2VzLiAgU2luY2UgdGhlc2UgZmlsZXMgYXJlIGNvbXBpbGVkIGludG8gdGhlIHByb3RvY29sIGNvbXBpbGVyCisjIGl0c2VsZiwgdGhleSBjYW5ub3QgYmUgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHkgYnkgYSBtYWtlIHJ1bGUuICAibWFrZSBjaGVjayIKKyMgd2lsbCBmYWlsIGlmIHRoZXNlIGZpbGVzIGRvIG5vdCBtYXRjaCB3aGF0IHRoZSBwcm90b2NvbCBjb21waWxlciB3b3VsZAorIyBnZW5lcmF0ZS4KKyMKKyMgSElOVDogIEZsYWdzIHBhc3NlZCB0byBnZW5lcmF0ZV9kZXNjcmlwdG9yX3Byb3RvLnNoIHdpbGwgYmUgcGFzc2VkIGRpcmVjdGx5CisjICAgdG8gbWFrZSB3aGVuIGJ1aWxkaW5nIHByb3RvYy4gIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3IgcGFzc2luZworIyAgIC1qNCB0byBydW4gNCBqb2JzIHNpbXVsdGFuZW91c2x5LgorCitpZiB0ZXN0ICEgLWUgc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaDsgdGhlbgorICBjYXQgPiYyIDw8IF9fRU9GX18KK0NvdWxkIG5vdCBmaW5kIHNvdXJjZSBjb2RlLiAgTWFrZSBzdXJlIHlvdSBhcmUgcnVubmluZyB0aGlzIHNjcmlwdCBmcm9tIHRoZQorcm9vdCBvZiB0aGUgZGlzdHJpYnV0aW9uIHRyZWUuCitfX0VPRl9fCisgIGV4aXQgMQorZmkKKworaWYgdGVzdCAhIC1lIHNyYy9NYWtlZmlsZTsgdGhlbgorICBjYXQgPiYyIDw8IF9fRU9GX18KK0NvdWxkIG5vdCBmaW5kIHNyYy9NYWtlZmlsZS4gIFlvdSBtdXN0IHJ1biAuL2NvbmZpZ3VyZSAoYW5kIHBlcmhhcHMKKy4vYXV0b2dlbi5zaCkgZmlyc3QuCitfX0VPRl9fCisgIGV4aXQgMQorZmkKKworY2Qgc3JjCitDT1JFX1BST1RPX0lTX0NPUlJFQ1Q9MAord2hpbGUgWyAkQ09SRV9QUk9UT19JU19DT1JSRUNUIC1uZSAxIF0KK2RvCisgIENPUkVfUFJPVE9fSVNfQ09SUkVDVD0xCisgIGNwIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmggZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaC50bXAKKyAgY3AgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuY2MgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuY2MudG1wCisgIGNwIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuaCBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmgudG1wCisgIGNwIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5jYy50bXAKKworICBtYWtlICRAIHByb3RvYyAmJgorICAgIC4vcHJvdG9jIC0tY3BwX291dD1kbGxleHBvcnRfZGVjbD1MSUJQUk9UT0JVRl9FWFBPUlQ6LiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byAmJiBcCisgICAgLi9wcm90b2MgLS1jcHBfb3V0PWRsbGV4cG9ydF9kZWNsPUxJQlBST1RPQ19FWFBPUlQ6LiBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCisKKyAgZGlmZiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgudG1wID4gL2Rldi9udWxsCisgIGlmIHRlc3QgJD8gLW5lIDA7IHRoZW4KKyAgICBDT1JFX1BST1RPX0lTX0NPUlJFQ1Q9MAorICBmaQorICBkaWZmIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjLnRtcCA+IC9kZXYvbnVsbAorICBpZiB0ZXN0ICQ/IC1uZSAwOyB0aGVuCisgICAgQ09SRV9QUk9UT19JU19DT1JSRUNUPTAKKyAgZmkKKyAgZGlmZiBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmggZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oLnRtcCA+IC9kZXYvbnVsbAorICBpZiB0ZXN0ICQ/IC1uZSAwOyB0aGVuCisgICAgQ09SRV9QUk9UT19JU19DT1JSRUNUPTAKKyAgZmkKKyAgZGlmZiBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmNjIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MudG1wID4gL2Rldi9udWxsCisgIGlmIHRlc3QgJD8gLW5lIDA7IHRoZW4KKyAgICBDT1JFX1BST1RPX0lTX0NPUlJFQ1Q9MAorICBmaQorCisgIHJtIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgudG1wCisgIHJtIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjLnRtcAorICBybSBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmgudG1wCisgIHJtIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MudG1wCitkb25lCitjZCAuLgpkaWZmIC0tZ2l0IGEvamF2YS9SRUFETUUudHh0IGIvamF2YS9SRUFETUUudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3ZTI2YTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL1JFQURNRS50eHQKQEAgLTAsMCArMSw5NiBAQAorUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CitDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLgorCitUaGlzIGRpcmVjdG9yeSBjb250YWlucyB0aGUgSmF2YSBQcm90b2NvbCBCdWZmZXJzIHJ1bnRpbWUgbGlicmFyeS4KKworSW5zdGFsbGF0aW9uIC0gV2l0aCBNYXZlbgorPT09PT09PT09PT09PT09PT09PT09PT09PQorCitUaGUgUHJvdG9jb2wgQnVmZmVycyBidWlsZCBpcyBtYW5hZ2VkIHVzaW5nIE1hdmVuLiAgSWYgeW91IHdvdWxkCityYXRoZXIgYnVpbGQgd2l0aG91dCBNYXZlbiwgc2VlIGJlbG93LgorCisxKSBJbnN0YWxsIEFwYWNoZSBNYXZlbiBpZiB5b3UgZG9uJ3QgaGF2ZSBpdDoKKworICAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy8KKworMikgQnVpbGQgdGhlIEMrKyBjb2RlLCBvciBvYnRhaW4gYSBiaW5hcnkgZGlzdHJpYnV0aW9uIG9mIHByb3RvYy4gIElmCisgICB5b3UgaW5zdGFsbCBhIGJpbmFyeSBkaXN0cmlidXRpb24sIG1ha2Ugc3VyZSB0aGF0IGl0IGlzIHRoZSBzYW1lCisgICB2ZXJzaW9uIGFzIHRoaXMgcGFja2FnZS4gIElmIGluIGRvdWJ0LCBydW46CisKKyAgICAgJCBwcm90b2MgLS12ZXJzaW9uCisKKyAgIFlvdSB3aWxsIG5lZWQgdG8gcGxhY2UgdGhlIHByb3RvYyBleGVjdXRhYmxlIGluIC4uL3NyYy4gIChJZiB5b3UKKyAgIGJ1aWx0IGl0IHlvdXJzZWxmLCBpdCBzaG91bGQgYWxyZWFkeSBiZSB0aGVyZS4pCisKKzMpIFJ1biB0aGUgdGVzdHM6CisKKyAgICAgJCBtdm4gdGVzdAorCisgICBJZiBzb21lIHRlc3RzIGZhaWwsIHRoaXMgbGlicmFyeSBtYXkgbm90IHdvcmsgY29ycmVjdGx5IG9uIHlvdXIKKyAgIHN5c3RlbS4gIENvbnRpbnVlIGF0IHlvdXIgb3duIHJpc2suCisKKzQpIEluc3RhbGwgdGhlIGxpYnJhcnkgaW50byB5b3VyIE1hdmVuIHJlcG9zaXRvcnk6CisKKyAgICAgJCBtdm4gaW5zdGFsbAorCis1KSBJZiB5b3UgZG8gbm90IHVzZSBNYXZlbiB0byBtYW5hZ2UgeW91ciBvd24gYnVpbGQsIHlvdSBjYW4gYnVpbGQgYQorICAgLmphciBmaWxlIHRvIHVzZToKKworICAgICAkIG12biBwYWNrYWdlCisKKyAgIFRoZSAuamFyIHdpbGwgYmUgcGxhY2VkIGluIHRoZSAidGFyZ2V0IiBkaXJlY3RvcnkuCisKK0luc3RhbGxhdGlvbiAtICdMaXRlJyBWZXJzaW9uIC0gV2l0aCBNYXZlbgorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0J1aWxkaW5nIHRoZSAnbGl0ZScgdmVyc2lvbiBvZiB0aGUgSmF2YSBQcm90b2NvbCBCdWZmZXJzIGxpYnJhcnkgaXMKK3RoZSBzYW1lIGFzIGJ1aWxkaW5nIHRoZSBmdWxsIHZlcnNpb24sIGV4Y2VwdCB0aGF0IGFsbCBjb21tYW5kcyBhcmUKK3J1biB1c2luZyB0aGUgJ2xpdGUnIHByb2ZpbGUuICAoc2VlCitodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9ndWlkZXMvaW50cm9kdWN0aW9uL2ludHJvZHVjdGlvbi10by1wcm9maWxlcy5odG1sKQorCitFLmcuIHRvIGluc3RhbGwgdGhlIGxpdGUgdmVyc2lvbiBvZiB0aGUgamFyLCB5b3Ugd291bGQgcnVuOgorCisgICQgbXZuIGluc3RhbGwgLVAgbGl0ZQorCitUaGUgcmVzdWx0aW5nIGFydGlmYWN0IGhhcyB0aGUgJ2xpdGUnIGNsYXNzaWZpZXIuICBUbyByZWZlcmVuY2UgaXQKK2ZvciBkZXBlbmRlbmN5IHJlc29sdXRpb24sIHlvdSB3b3VsZCBzcGVjaWZ5IGl0IGFzOgorCisgIDxkZXBlbmRlbmN5PgorICAgIDxncm91cElkPmNvbS5nb29nbGUucHJvdG9idWY8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+cHJvdG9idWYtamF2YTwvYXJ0aWZhY3RJZD4KKyAgICA8dmVyc2lvbj4ke3ZlcnNpb259PC92ZXJzaW9uPgorICAgIDxjbGFzc2lmaWVyPmxpdGU8L2NsYXNzaWZpZXI+CisgIDwvZGVwZW5kZW5jeT4KKworSW5zdGFsbGF0aW9uIC0gV2l0aG91dCBNYXZlbgorPT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJZiB5b3Ugd291bGQgcmF0aGVyIG5vdCBpbnN0YWxsIE1hdmVuIHRvIGJ1aWxkIHRoZSBsaWJyYXJ5LCB5b3UgbWF5Citmb2xsb3cgdGhlc2UgaW5zdHJ1Y3Rpb25zIGluc3RlYWQuICBOb3RlIHRoYXQgdGhlc2UgaW5zdHJ1Y3Rpb25zIHNraXAKK3J1bm5pbmcgdW5pdCB0ZXN0cy4KKworMSkgQnVpbGQgdGhlIEMrKyBjb2RlLCBvciBvYnRhaW4gYSBiaW5hcnkgZGlzdHJpYnV0aW9uIG9mIHByb3RvYy4gIElmCisgICB5b3UgaW5zdGFsbCBhIGJpbmFyeSBkaXN0cmlidXRpb24sIG1ha2Ugc3VyZSB0aGF0IGl0IGlzIHRoZSBzYW1lCisgICB2ZXJzaW9uIGFzIHRoaXMgcGFja2FnZS4gIElmIGluIGRvdWJ0LCBydW46CisKKyAgICAgJCBwcm90b2MgLS12ZXJzaW9uCisKKyAgIElmIHlvdSBidWlsdCB0aGUgQysrIGNvZGUgd2l0aG91dCBpbnN0YWxsaW5nLCB0aGUgY29tcGlsZXIgYmluYXJ5CisgICBzaG91bGQgYmUgbG9jYXRlZCBpbiAuLi9zcmMuCisKKzIpIEludm9rZSBwcm90b2MgdG8gYnVpbGQgRGVzY3JpcHRvclByb3Rvcy5qYXZhOgorCisgICAgICQgcHJvdG9jIC0tamF2YV9vdXQ9c3JjL21haW4vamF2YSAtSS4uL3NyYyBcCisgICAgICAgICAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KKworMykgQ29tcGlsZSB0aGUgY29kZSBpbiBzcmMvbWFpbi9qYXZhIHVzaW5nIHdoYXRldmVyIG1lYW5zIHlvdSBwcmVmZXIuCisKKzQpIEluc3RhbGwgdGhlIGNsYXNzZXMgd2hlcmV2ZXIgeW91IHByZWZlci4KKworVXNhZ2UKKz09PT09CisKK1RoZSBjb21wbGV0ZSBkb2N1bWVudGF0aW9uIGZvciBQcm90b2NvbCBCdWZmZXJzIGlzIGF2YWlsYWJsZSB2aWEgdGhlCit3ZWIgYXQ6CisKKyAgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KZGlmZiAtLWdpdCBhL2phdmEvcG9tLnhtbCBiL2phdmEvcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWI3YTcwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9wb20ueG1sCkBAIC0wLDAgKzEsMjg0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgorPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKyAgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKyAgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgPHBhcmVudD4KKyAgICA8Z3JvdXBJZD5jb20uZ29vZ2xlPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmdvb2dsZTwvYXJ0aWZhY3RJZD4KKyAgICA8dmVyc2lvbj4xPC92ZXJzaW9uPgorICA8L3BhcmVudD4KKyAgPGdyb3VwSWQ+Y29tLmdvb2dsZS5wcm90b2J1ZjwvZ3JvdXBJZD4KKyAgPGFydGlmYWN0SWQ+cHJvdG9idWYtamF2YTwvYXJ0aWZhY3RJZD4KKyAgPHZlcnNpb24+My4wLjAtYWxwaGEtMy1wcmU8L3ZlcnNpb24+CisgIDxwYWNrYWdpbmc+YnVuZGxlPC9wYWNrYWdpbmc+CisgIDxuYW1lPlByb3RvY29sIEJ1ZmZlciBKYXZhIEFQSTwvbmFtZT4KKyAgPGRlc2NyaXB0aW9uPgorICAgIFByb3RvY29sIEJ1ZmZlcnMgYXJlIGEgd2F5IG9mIGVuY29kaW5nIHN0cnVjdHVyZWQgZGF0YSBpbiBhbiBlZmZpY2llbnQgeWV0CisgICAgZXh0ZW5zaWJsZSBmb3JtYXQuCisgIDwvZGVzY3JpcHRpb24+CisgIDxpbmNlcHRpb25ZZWFyPjIwMDg8L2luY2VwdGlvblllYXI+CisgIDx1cmw+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy88L3VybD4KKyAgPGxpY2Vuc2VzPgorICAgIDxsaWNlbnNlPgorICAgICAgPG5hbWU+TmV3IEJTRCBsaWNlbnNlPC9uYW1lPgorICAgICAgPHVybD5odHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2JzZC1saWNlbnNlLnBocDwvdXJsPgorICAgICAgPGRpc3RyaWJ1dGlvbj5yZXBvPC9kaXN0cmlidXRpb24+CisgICAgPC9saWNlbnNlPgorICA8L2xpY2Vuc2VzPgorICA8c2NtPgorICAgIDx1cmw+aHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9wcm90b2J1ZjwvdXJsPgorICAgIDxjb25uZWN0aW9uPgorICAgICAgc2NtOmdpdDpodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmLmdpdAorICAgIDwvY29ubmVjdGlvbj4KKyAgPC9zY20+CisgIDxkZXBlbmRlbmNpZXM+CisgICAgPGRlcGVuZGVuY3k+CisgICAgICA8Z3JvdXBJZD5qdW5pdDwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPmp1bml0PC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+NC40PC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5lYXN5bW9jazwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPmVhc3ltb2NrPC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+Mi4yPC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5lYXN5bW9jazwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPmVhc3ltb2NrY2xhc3NleHRlbnNpb248L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4yLjIuMTwvdmVyc2lvbj4KKyAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKyAgICA8L2RlcGVuZGVuY3k+CisgIDwvZGVwZW5kZW5jaWVzPgorICA8YnVpbGQ+CisgICAgPHBsdWdpbnM+CisgICAgICA8cGx1Z2luPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgIDxzb3VyY2U+MS41PC9zb3VyY2U+CisgICAgICAgICAgPHRhcmdldD4xLjU8L3RhcmdldD4KKyAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgPC9wbHVnaW4+CisgICAgICA8cGx1Z2luPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1zdXJlZmlyZS1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgIDxpbmNsdWRlcz4KKyAgICAgICAgICAgIDxpbmNsdWRlPioqLypUZXN0LmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgPC9pbmNsdWRlcz4KKyAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgPC9wbHVnaW4+CisgICAgICA8cGx1Z2luPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1hbnRydW4tcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8ZXhlY3V0aW9ucz4KKyAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgPGlkPmdlbmVyYXRlLXNvdXJjZXM8L2lkPgorICAgICAgICAgICAgPHBoYXNlPmdlbmVyYXRlLXNvdXJjZXM8L3BoYXNlPgorICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgIDx0YXNrcz4KKyAgICAgICAgICAgICAgICA8bWtkaXIgZGlyPSJ0YXJnZXQvZ2VuZXJhdGVkLXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgPGV4ZWMgZXhlY3V0YWJsZT0iLi4vc3JjL3Byb3RvYyI+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLWphdmFfb3V0PXRhcmdldC9nZW5lcmF0ZWQtc291cmNlcyIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii0tcHJvdG9fcGF0aD0uLi9zcmMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSIuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgPC9leGVjPgorICAgICAgICAgICAgICA8L3Rhc2tzPgorICAgICAgICAgICAgICA8c291cmNlUm9vdD50YXJnZXQvZ2VuZXJhdGVkLXNvdXJjZXM8L3NvdXJjZVJvb3Q+CisgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICA8Z29hbHM+CisgICAgICAgICAgICAgIDxnb2FsPnJ1bjwvZ29hbD4KKyAgICAgICAgICAgIDwvZ29hbHM+CisgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgICAgPGV4ZWN1dGlvbj4KKyAgICAgICAgICAgIDxpZD5nZW5lcmF0ZS10ZXN0LXNvdXJjZXM8L2lkPgorICAgICAgICAgICAgPHBoYXNlPmdlbmVyYXRlLXRlc3Qtc291cmNlczwvcGhhc2U+CisgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgPHRhc2tzPgorICAgICAgICAgICAgICAgIDxta2RpciBkaXI9InRhcmdldC9nZW5lcmF0ZWQtdGVzdC1zb3VyY2VzIiAvPgorICAgICAgICAgICAgICAgIDxleGVjIGV4ZWN1dGFibGU9Ii4uL3NyYy9wcm90b2MiPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLS1qYXZhX291dD10YXJnZXQvZ2VuZXJhdGVkLXRlc3Qtc291cmNlcyIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii0tcHJvdG9fcGF0aD0uLi9zcmMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YSIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSIuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9sYXp5X2ZpZWxkc19saXRlLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2xpdGVfZXF1YWxzX2FuZF9oYXNoLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZworICAgICAgICAgICAgICAgICAgICB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL211bHRpcGxlX2ZpbGVzX3Rlc3QucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2J1aWxkZXJzX3Rlc3QucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2V4dGVuc2lvbi5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfZXh0ZW5zaW9uX2xpdGUucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbm9uX25lc3RlZF9leHRlbnNpb24ucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbm9uX25lc3RlZF9leHRlbnNpb25fbGl0ZS5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3Rlc3QucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvb3V0ZXJfY2xhc3NfbmFtZV90ZXN0Mi5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3Rlc3QzLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfY2hlY2tfdXRmOC5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZworICAgICAgICAgICAgICAgICAgICB2YWx1ZT0iLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnCisgICAgICAgICAgICAgICAgICAgIHZhbHVlPSIuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfbGl0ZS5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW5vcm1vdXNfZGVzY3JpcHRvci5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9maWVsZF9wcmVzZW5jZV90ZXN0LnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfZm9yX3Byb3RvMl90ZXN0LnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LnByb3RvIiAvPgorICAgICAgICAgICAgICAgIDwvZXhlYz4KKyAgICAgICAgICAgICAgPC90YXNrcz4KKyAgICAgICAgICAgICAgPHRlc3RTb3VyY2VSb290PnRhcmdldC9nZW5lcmF0ZWQtdGVzdC1zb3VyY2VzPC90ZXN0U291cmNlUm9vdD4KKyAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgIDxnb2Fscz4KKyAgICAgICAgICAgICAgPGdvYWw+cnVuPC9nb2FsPgorICAgICAgICAgICAgPC9nb2Fscz4KKyAgICAgICAgICA8L2V4ZWN1dGlvbj4KKyAgICAgICAgPC9leGVjdXRpb25zPgorICAgICAgPC9wbHVnaW4+CisgICAgICA8cGx1Z2luPgorICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1idW5kbGUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8ZXh0ZW5zaW9ucz50cnVlPC9leHRlbnNpb25zPgorICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8aW5zdHJ1Y3Rpb25zPgorICAgICAgICAgICAgPEJ1bmRsZS1Eb2NVUkw+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy88L0J1bmRsZS1Eb2NVUkw+CisgICAgICAgICAgICA8QnVuZGxlLVN5bWJvbGljTmFtZT5jb20uZ29vZ2xlLnByb3RvYnVmPC9CdW5kbGUtU3ltYm9saWNOYW1lPgorICAgICAgICAgICAgPEV4cG9ydC1QYWNrYWdlPmNvbS5nb29nbGUucHJvdG9idWY7dmVyc2lvbj0zLjAuMC1hbHBoYS0zLXByZTwvRXhwb3J0LVBhY2thZ2U+CisgICAgICAgICAgPC9pbnN0cnVjdGlvbnM+CisgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgIDwvcGx1Z2luPgorICAgIDwvcGx1Z2lucz4KKyAgPC9idWlsZD4KKyAgPHByb2ZpbGVzPgorICAgIDxwcm9maWxlPgorICAgICAgPGlkPnJlbGVhc2U8L2lkPgorICAgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKyAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc291cmNlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjIuMi4xPC92ZXJzaW9uPgorICAgICAgICAgICAgPGV4ZWN1dGlvbnM+CisgICAgICAgICAgICAgIDxleGVjdXRpb24+CisgICAgICAgICAgICAgICAgPGlkPmF0dGFjaC1zb3VyY2VzPC9pZD4KKyAgICAgICAgICAgICAgICA8Z29hbHM+CisgICAgICAgICAgICAgICAgICA8Z29hbD5qYXItbm8tZm9yazwvZ29hbD4KKyAgICAgICAgICAgICAgICA8L2dvYWxzPgorICAgICAgICAgICAgICA8L2V4ZWN1dGlvbj4KKyAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tamF2YWRvYy1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4yLjkuMTwvdmVyc2lvbj4KKyAgICAgICAgICAgIDxleGVjdXRpb25zPgorICAgICAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgIDxpZD5hdHRhY2gtamF2YWRvY3M8L2lkPgorICAgICAgICAgICAgICAgIDxnb2Fscz4KKyAgICAgICAgICAgICAgICAgIDxnb2FsPmphcjwvZ29hbD4KKyAgICAgICAgICAgICAgICA8L2dvYWxzPgorICAgICAgICAgICAgICA8L2V4ZWN1dGlvbj4KKyAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tZ3BnLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjEuNTwvdmVyc2lvbj4KKyAgICAgICAgICAgIDxleGVjdXRpb25zPgorICAgICAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgIDxpZD5zaWduLWFydGlmYWN0czwvaWQ+CisgICAgICAgICAgICAgICAgPHBoYXNlPnZlcmlmeTwvcGhhc2U+CisgICAgICAgICAgICAgICAgPGdvYWxzPgorICAgICAgICAgICAgICAgICAgPGdvYWw+c2lnbjwvZ29hbD4KKyAgICAgICAgICAgICAgICA8L2dvYWxzPgorICAgICAgICAgICAgICA8L2V4ZWN1dGlvbj4KKyAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLnNvbmF0eXBlLnBsdWdpbnM8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5uZXh1cy1zdGFnaW5nLW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgICAgICAgICAgPGV4dGVuc2lvbnM+dHJ1ZTwvZXh0ZW5zaW9ucz4KKyAgICAgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgICAgICAgPHNlcnZlcklkPnNvbmF0eXBlLW5leHVzLXN0YWdpbmc8L3NlcnZlcklkPgorICAgICAgICAgICAgICAgPG5leHVzVXJsPmh0dHBzOi8vb3NzLnNvbmF0eXBlLm9yZy88L25leHVzVXJsPgorICAgICAgICAgICAgICAgPGF1dG9SZWxlYXNlQWZ0ZXJDbG9zZT5mYWxzZTwvYXV0b1JlbGVhc2VBZnRlckNsb3NlPgorICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgICA8L2J1aWxkPgorICAgIDwvcHJvZmlsZT4KKyAgICA8cHJvZmlsZT4KKyAgICAgIDxpZD5saXRlPC9pZD4KKyAgICAgIDxidWlsZD4KKyAgICAgICAgPHBsdWdpbnM+CisgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgICAgICA8aW5jbHVkZXM+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovQWJzdHJhY3RNZXNzYWdlTGl0ZS5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL0Fic3RyYWN0UGFyc2VyLmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovQm91bmRlZEJ5dGVTdHJpbmcuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9CeXRlU3RyaW5nLmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovQ29kZWRJbnB1dFN0cmVhbS5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL0NvZGVkT3V0cHV0U3RyZWFtLmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovRXh0ZW5zaW9uTGl0ZS5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL0V4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL0ZpZWxkU2V0LmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovR2VuZXJhdGVkTWVzc2FnZUxpdGUuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9JbnRlcm5hbC5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL0xhenlGaWVsZExpdGUuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9MYXp5U3RyaW5nQXJyYXlMaXN0LmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovTGF6eVN0cmluZ0xpc3QuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9MaXRlcmFsQnl0ZVN0cmluZy5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL01hcEVudHJ5TGl0ZS5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL01hcEZpZWxkTGl0ZS5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL01lc3NhZ2VMaXRlLmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovTWVzc2FnZUxpdGVPckJ1aWxkZXIuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9QYXJzZXIuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9Qcm90b2NvbFN0cmluZ0xpc3QuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9Sb3BlQnl0ZVN0cmluZy5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL1NtYWxsU29ydGVkTWFwLmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24uamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9Vbmtub3duRmllbGRTZXRMaXRlLmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovVW5tb2RpZmlhYmxlTGF6eVN0cmluZ0xpc3QuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi9VdGY4LmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+KiovV2lyZUZvcm1hdC5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICA8L2luY2x1ZGVzPgorICAgICAgICAgICAgICA8dGVzdEluY2x1ZGVzPgorICAgICAgICAgICAgICAgIDx0ZXN0SW5jbHVkZT4qKi8qTGl0ZS5qYXZhPC90ZXN0SW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8dGVzdEluY2x1ZGU+KiovTGF6eU1lc3NhZ2VMaXRlVGVzdC5qYXZhPC90ZXN0SW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8dGVzdEluY2x1ZGU+KiovTGl0ZVRlc3QuamF2YTwvdGVzdEluY2x1ZGU+CisgICAgICAgICAgICAgICAgPHRlc3RJbmNsdWRlPioqL1Vua25vd25GaWVsZFNldExpdGVUZXN0LmphdmE8L3Rlc3RJbmNsdWRlPgorICAgICAgICAgICAgICA8L3Rlc3RJbmNsdWRlcz4KKyAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgIDxpbmNsdWRlcz4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi8qVGVzdC5qYXZhPC9pbmNsdWRlPgorICAgICAgICAgICAgICA8L2luY2x1ZGVzPgorICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICAgIDwvcGx1Z2luPgorICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1qYXItcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgIDxjbGFzc2lmaWVyPmxpdGU8L2NsYXNzaWZpZXI+CisgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICAgIDwvYnVpbGQ+CisgICAgPC9wcm9maWxlPgorICA8L3Byb2ZpbGVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RNZXNzYWdlLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzg5MTczCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RNZXNzYWdlLmphdmEKQEAgLTAsMCArMSw1MjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIEEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUge0BsaW5rIE1lc3NhZ2V9IGludGVyZmFjZSB3aGljaCBpbXBsZW1lbnRzCisgKiBhcyBtYW55IG1ldGhvZHMgb2YgdGhhdCBpbnRlcmZhY2UgYXMgcG9zc2libGUgaW4gdGVybXMgb2Ygb3RoZXIgbWV0aG9kcy4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RNZXNzYWdlIGV4dGVuZHMgQWJzdHJhY3RNZXNzYWdlTGl0ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBsZW1lbnRzIE1lc3NhZ2UgeworICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgeworICAgIHJldHVybiBNZXNzYWdlUmVmbGVjdGlvbi5pc0luaXRpYWxpemVkKHRoaXMpOworICB9CisKKworICBwdWJsaWMgTGlzdDxTdHJpbmc+IGZpbmRJbml0aWFsaXphdGlvbkVycm9ycygpIHsKKyAgICByZXR1cm4gTWVzc2FnZVJlZmxlY3Rpb24uZmluZE1pc3NpbmdGaWVsZHModGhpcyk7CisgIH0KKworICBwdWJsaWMgU3RyaW5nIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSB7CisgICAgcmV0dXJuIE1lc3NhZ2VSZWZsZWN0aW9uLmRlbGltaXRXaXRoQ29tbWFzKGZpbmRJbml0aWFsaXphdGlvbkVycm9ycygpKTsKKyAgfQorCisgIC8qKiBUT0RPKGppZWx1byk6IENsZWFyIGl0IHdoZW4gYWxsIHN1YmNsYXNzZXMgaGF2ZSBpbXBsZW1lbnRlZCB0aGlzIG1ldGhvZC4gKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mKE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiaGFzT25lb2YoKSBpcyBub3QgaW1wbGVtZW50ZWQuIik7CisgIH0KKworICAvKiogVE9ETyhqaWVsdW8pOiBDbGVhciBpdCB3aGVuIGFsbCBzdWJjbGFzc2VzIGhhdmUgaW1wbGVtZW50ZWQgdGhpcyBtZXRob2QuICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldE9uZW9mRmllbGREZXNjcmlwdG9yKE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgImdldE9uZW9mRmllbGREZXNjcmlwdG9yKCkgaXMgbm90IGltcGxlbWVudGVkLiIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgcmV0dXJuIFRleHRGb3JtYXQucHJpbnRUb1N0cmluZyh0aGlzKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE1lc3NhZ2VSZWZsZWN0aW9uLndyaXRlTWVzc2FnZVRvKHRoaXMsIGdldEFsbEZpZWxkcygpLCBvdXRwdXQsIGZhbHNlKTsKKyAgfQorCisgIHByb3RlY3RlZCBpbnQgbWVtb2l6ZWRTaXplID0gLTE7CisKKyAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKKyAgICBpZiAoc2l6ZSAhPSAtMSkgeworICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgbWVtb2l6ZWRTaXplID0gTWVzc2FnZVJlZmxlY3Rpb24uZ2V0U2VyaWFsaXplZFNpemUodGhpcywgZ2V0QWxsRmllbGRzKCkpOworICAgIHJldHVybiBtZW1vaXplZFNpemU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvdGhlcikgeworICAgIGlmIChvdGhlciA9PSB0aGlzKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBNZXNzYWdlKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBmaW5hbCBNZXNzYWdlIG90aGVyTWVzc2FnZSA9IChNZXNzYWdlKSBvdGhlcjsKKyAgICBpZiAoZ2V0RGVzY3JpcHRvckZvclR5cGUoKSAhPSBvdGhlck1lc3NhZ2UuZ2V0RGVzY3JpcHRvckZvclR5cGUoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gY29tcGFyZUZpZWxkcyhnZXRBbGxGaWVsZHMoKSwgb3RoZXJNZXNzYWdlLmdldEFsbEZpZWxkcygpKSAmJgorICAgICAgICBnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyTWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgaW50IGhhc2ggPSBtZW1vaXplZEhhc2hDb2RlOworICAgIGlmIChoYXNoID09IDApIHsKKyAgICAgIGhhc2ggPSA0MTsKKyAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3JGb3JUeXBlKCkuaGFzaENvZGUoKTsKKyAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEFsbEZpZWxkcygpKTsKKyAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOworICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CisgICAgfQorICAgIHJldHVybiBoYXNoOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIHRvQnl0ZVN0cmluZyhPYmplY3QgdmFsdWUpIHsKKyAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgIHJldHVybiBCeXRlU3RyaW5nLmNvcHlGcm9tKChieXRlW10pIHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIChCeXRlU3RyaW5nKSB2YWx1ZTsKKyAgICB9CisgIH0KKyAKKyAgLyoqCisgICAqIENvbXBhcmVzIHR3byBieXRlcyBmaWVsZHMuIFRoZSBwYXJhbWV0ZXJzIG11c3QgYmUgZWl0aGVyIGEgYnl0ZSBhcnJheSBvciBhCisgICAqIEJ5dGVTdHJpbmcgb2JqZWN0LiBUaGV5IGNhbiBiZSBvZiBkaWZmZXJlbnQgdHlwZSB0aG91Z2guCisgICAqLworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGNvbXBhcmVCeXRlcyhPYmplY3QgYSwgT2JqZWN0IGIpIHsKKyAgICBpZiAoYSBpbnN0YW5jZW9mIGJ5dGVbXSAmJiBiIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscygoYnl0ZVtdKWEsIChieXRlW10pYik7CisgICAgfQorICAgIHJldHVybiB0b0J5dGVTdHJpbmcoYSkuZXF1YWxzKHRvQnl0ZVN0cmluZyhiKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb252ZXJ0cyBhIGxpc3Qgb2YgTWFwRW50cnkgbWVzc2FnZXMgaW50byBhIE1hcCB1c2VkIGZvciBlcXVhbHMoKSBhbmQKKyAgICogaGFzaENvZGUoKS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMiLCAidW5jaGVja2VkIn0pCisgIHByaXZhdGUgc3RhdGljIE1hcCBjb252ZXJ0TWFwRW50cnlMaXN0VG9NYXAoTGlzdCBsaXN0KSB7CisgICAgaWYgKGxpc3QuaXNFbXB0eSgpKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKKyAgICB9CisgICAgTWFwIHJlc3VsdCA9IG5ldyBIYXNoTWFwKCk7CisgICAgSXRlcmF0b3IgaXRlcmF0b3IgPSBsaXN0Lml0ZXJhdG9yKCk7CisgICAgTWVzc2FnZSBlbnRyeSA9IChNZXNzYWdlKSBpdGVyYXRvci5uZXh0KCk7CisgICAgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZW50cnkuZ2V0RGVzY3JpcHRvckZvclR5cGUoKTsKKyAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3Iga2V5ID0gZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciB2YWx1ZSA9IGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHJlc3VsdC5wdXQoZW50cnkuZ2V0RmllbGQoa2V5KSwgZW50cnkuZ2V0RmllbGQodmFsdWUpKTsKKyAgICB3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CisgICAgICBlbnRyeSA9IChNZXNzYWdlKSBpdGVyYXRvci5uZXh0KCk7CisgICAgICByZXN1bHQucHV0KGVudHJ5LmdldEZpZWxkKGtleSksIGVudHJ5LmdldEZpZWxkKHZhbHVlKSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21wYXJlcyB0d28gbWFwIGZpZWxkcy4gVGhlIHBhcmFtZXRlcnMgbXVzdCBiZSBhIGxpc3Qgb2YgTWFwRW50cnkKKyAgICogbWVzc2FnZXMuCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIiwgInVuY2hlY2tlZCJ9KQorICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGNvbXBhcmVNYXBGaWVsZChPYmplY3QgYSwgT2JqZWN0IGIpIHsKKyAgICBNYXAgbWEgPSBjb252ZXJ0TWFwRW50cnlMaXN0VG9NYXAoKExpc3QpIGEpOworICAgIE1hcCBtYiA9IGNvbnZlcnRNYXBFbnRyeUxpc3RUb01hcCgoTGlzdCkgYik7CisgICAgcmV0dXJuIE1hcEZpZWxkTGl0ZS5lcXVhbHMobWEsIG1iKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbXBhcmVzIHR3byBzZXQgb2YgZmllbGRzLgorICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGltcGxlbWVudCB7QGxpbmsgQWJzdHJhY3RNZXNzYWdlI2VxdWFscyhPYmplY3QpfQorICAgKiBhbmQge0BsaW5rIEFic3RyYWN0TXV0YWJsZU1lc3NhZ2UjZXF1YWxzKE9iamVjdCl9LiBJdCB0YWtlcyBzcGVjaWFsIGNhcmUKKyAgICogb2YgYnl0ZXMgZmllbGRzIGJlY2F1c2UgaW1tdXRhYmxlIG1lc3NhZ2VzIGFuZCBtdXRhYmxlIG1lc3NhZ2VzIHVzZQorICAgKiBkaWZmZXJlbnQgSmF2YSB0eXBlIHRvIHJlcHJlbnNlbnQgYSBieXRlcyBmaWVsZCBhbmQgdGhpcyBtZXRob2Qgc2hvdWxkIGJlCisgICAqIGFibGUgdG8gY29tcGFyZSBpbW11dGFibGUgbWVzc2FnZXMsIG11dGFibGUgbWVzc2FnZXMgYW5kIGFsc28gYW4gaW1tdXRhYmxlCisgICAqIG1lc3NhZ2UgdG8gYSBtdXRhYmxlIG1lc3NhZ2UuCisgICAqLworICBzdGF0aWMgYm9vbGVhbiBjb21wYXJlRmllbGRzKE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gYSwKKyAgICAgIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gYikgeworICAgIGlmIChhLnNpemUoKSAhPSBiLnNpemUoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBmb3IgKEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yIDogYS5rZXlTZXQoKSkgeworICAgICAgaWYgKCFiLmNvbnRhaW5zS2V5KGRlc2NyaXB0b3IpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIE9iamVjdCB2YWx1ZTEgPSBhLmdldChkZXNjcmlwdG9yKTsKKyAgICAgIE9iamVjdCB2YWx1ZTIgPSBiLmdldChkZXNjcmlwdG9yKTsKKyAgICAgIGlmIChkZXNjcmlwdG9yLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5CWVRFUykgeworICAgICAgICBpZiAoZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICBMaXN0IGxpc3QxID0gKExpc3QpIHZhbHVlMTsKKyAgICAgICAgICBMaXN0IGxpc3QyID0gKExpc3QpIHZhbHVlMjsKKyAgICAgICAgICBpZiAobGlzdDEuc2l6ZSgpICE9IGxpc3QyLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3QxLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoIWNvbXBhcmVCeXRlcyhsaXN0MS5nZXQoaSksIGxpc3QyLmdldChpKSkpIHsKKyAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBDb21wYXJlcyBhIHNpbmd1bGFyIGJ5dGVzIGZpZWxkLgorICAgICAgICAgIGlmICghY29tcGFyZUJ5dGVzKHZhbHVlMSwgdmFsdWUyKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChkZXNjcmlwdG9yLmlzTWFwRmllbGQoKSkgeworICAgICAgICBpZiAoIWNvbXBhcmVNYXBGaWVsZCh2YWx1ZTEsIHZhbHVlMikpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIENvbXBhcmUgbm9uLWJ5dGVzIGZpZWxkcy4KKyAgICAgICAgaWYgKCF2YWx1ZTEuZXF1YWxzKHZhbHVlMikpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgCisgIC8qKgorICAgKiBDYWxjdWxhdGVzIHRoZSBoYXNoIGNvZGUgb2YgYSBtYXAgZmllbGQuIHtAY29kZSB2YWx1ZX0gbXVzdCBiZSBhIGxpc3Qgb2YKKyAgICogTWFwRW50cnkgbWVzc2FnZXMuCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHJpdmF0ZSBzdGF0aWMgaW50IGhhc2hNYXBGaWVsZChPYmplY3QgdmFsdWUpIHsKKyAgICByZXR1cm4gTWFwRmllbGRMaXRlLmNhbGN1bGF0ZUhhc2hDb2RlRm9yTWFwKGNvbnZlcnRNYXBFbnRyeUxpc3RUb01hcCgoTGlzdCkgdmFsdWUpKTsKKyAgfQorCisgIC8qKiBHZXQgYSBoYXNoIGNvZGUgZm9yIGdpdmVuIGZpZWxkcyBhbmQgdmFsdWVzLCB1c2luZyB0aGUgZ2l2ZW4gc2VlZC4gKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHByb3RlY3RlZCBzdGF0aWMgaW50IGhhc2hGaWVsZHMoaW50IGhhc2gsIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gbWFwKSB7CisgICAgZm9yIChNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGVudHJ5IDogbWFwLmVudHJ5U2V0KCkpIHsKKyAgICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGVudHJ5LmdldEtleSgpOworICAgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIGZpZWxkLmdldE51bWJlcigpOworICAgICAgaWYgKGZpZWxkLmlzTWFwRmllbGQoKSkgeworICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBoYXNoTWFwRmllbGQodmFsdWUpOworICAgICAgfSBlbHNlIGlmIChmaWVsZC5nZXRUeXBlKCkgIT0gRmllbGREZXNjcmlwdG9yLlR5cGUuRU5VTSl7CisgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHZhbHVlLmhhc2hDb2RlKCk7CisgICAgICB9IGVsc2UgaWYgKGZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICBMaXN0PD8gZXh0ZW5kcyBFbnVtTGl0ZT4gbGlzdCA9IChMaXN0PD8gZXh0ZW5kcyBFbnVtTGl0ZT4pIHZhbHVlOworICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBJbnRlcm5hbC5oYXNoRW51bUxpc3QobGlzdCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBJbnRlcm5hbC5oYXNoRW51bSgoRW51bUxpdGUpIHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGhhc2g7CisgIH0KKworICAvKioKKyAgICogUGFja2FnZSBwcml2YXRlIGhlbHBlciBtZXRob2QgZm9yIEFic3RyYWN0UGFyc2VyIHRvIGNyZWF0ZQorICAgKiBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiB3aXRoIG1pc3NpbmcgZmllbGQgaW5mb3JtYXRpb24uCisgICAqLworICBAT3ZlcnJpZGUKKyAgVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24oKSB7CisgICAgcmV0dXJuIEJ1aWxkZXIubmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24odGhpcyk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8qKgorICAgKiBBIHBhcnRpYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluayBNZXNzYWdlLkJ1aWxkZXJ9IGludGVyZmFjZSB3aGljaAorICAgKiBpbXBsZW1lbnRzIGFzIG1hbnkgbWV0aG9kcyBvZiB0aGF0IGludGVyZmFjZSBhcyBwb3NzaWJsZSBpbiB0ZXJtcyBvZgorICAgKiBvdGhlciBtZXRob2RzLgorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgQnVpbGRlcjxCdWlsZGVyVHlwZSBleHRlbmRzIEJ1aWxkZXI+CisgICAgICBleHRlbmRzIEFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlcjxCdWlsZGVyVHlwZT4KKyAgICAgIGltcGxlbWVudHMgTWVzc2FnZS5CdWlsZGVyIHsKKyAgICAvLyBUaGUgY29tcGlsZXIgcHJvZHVjZXMgYW4gZXJyb3IgaWYgdGhpcyBpcyBub3QgZGVjbGFyZWQgZXhwbGljaXRseS4KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlclR5cGUgY2xvbmUoKTsKKworICAgIC8qKiBUT0RPKGppZWx1byk6IENsZWFyIGl0IHdoZW4gYWxsIHN1YmNsYXNzZXMgaGF2ZSBpbXBsZW1lbnRlZCB0aGlzIG1ldGhvZC4gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZihPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiaGFzT25lb2YoKSBpcyBub3QgaW1wbGVtZW50ZWQuIik7CisgICAgfQorCisgICAgLyoqIFRPRE8oamllbHVvKTogQ2xlYXIgaXQgd2hlbiBhbGwgc3ViY2xhc3NlcyBoYXZlIGltcGxlbWVudGVkIHRoaXMgbWV0aG9kLiAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGaWVsZERlc2NyaXB0b3IgZ2V0T25lb2ZGaWVsZERlc2NyaXB0b3IoT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImdldE9uZW9mRmllbGREZXNjcmlwdG9yKCkgaXMgbm90IGltcGxlbWVudGVkLiIpOworICAgIH0KKworICAgIC8qKiBUT0RPKGppZWx1byk6IENsZWFyIGl0IHdoZW4gYWxsIHN1YmNsYXNzZXMgaGF2ZSBpbXBsZW1lbnRlZCB0aGlzIG1ldGhvZC4gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xlYXJPbmVvZihPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiY2xlYXJPbmVvZigpIGlzIG5vdCBpbXBsZW1lbnRlZC4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xlYXIoKSB7CisgICAgICBmb3IgKGZpbmFsIE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZW50cnkgOgorICAgICAgICAgICBnZXRBbGxGaWVsZHMoKS5lbnRyeVNldCgpKSB7CisgICAgICAgIGNsZWFyRmllbGQoZW50cnkuZ2V0S2V5KCkpOworICAgICAgfQorICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGZpbmRJbml0aWFsaXphdGlvbkVycm9ycygpIHsKKyAgICAgIHJldHVybiBNZXNzYWdlUmVmbGVjdGlvbi5maW5kTWlzc2luZ0ZpZWxkcyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSB7CisgICAgICByZXR1cm4gTWVzc2FnZVJlZmxlY3Rpb24uZGVsaW1pdFdpdGhDb21tYXMoZmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCkpOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBtZXJnZUZyb20oZmluYWwgTWVzc2FnZSBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvckZvclR5cGUoKSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJtZXJnZUZyb20oTWVzc2FnZSkgY2FuIG9ubHkgbWVyZ2UgbWVzc2FnZXMgb2YgdGhlIHNhbWUgdHlwZS4iKTsKKyAgICAgIH0KKworICAgICAgLy8gTm90ZTogIFdlIGRvbid0IGF0dGVtcHQgdG8gdmVyaWZ5IHRoYXQgb3RoZXIncyBmaWVsZHMgaGF2ZSB2YWxpZAorICAgICAgLy8gICB0eXBlcy4gIERvaW5nIHNvIHdvdWxkIGJlIGEgbG9zaW5nIGJhdHRsZS4gIFdlJ2QgaGF2ZSB0byB2ZXJpZnkKKyAgICAgIC8vICAgYWxsIHN1Yi1tZXNzYWdlcyBhcyB3ZWxsLCBhbmQgd2UnZCBoYXZlIHRvIG1ha2UgY29waWVzIG9mIGFsbCBvZgorICAgICAgLy8gICB0aGVtIHRvIGluc3VyZSB0aGF0IHRoZXkgZG9uJ3QgY2hhbmdlIGFmdGVyIHZlcmlmaWNhdGlvbiAoc2luY2UKKyAgICAgIC8vICAgdGhlIE1lc3NhZ2UgaW50ZXJmYWNlIGl0c2VsZiBjYW5ub3QgZW5mb3JjZSBpbW11dGFiaWxpdHkgb2YKKyAgICAgIC8vICAgaW1wbGVtZW50YXRpb25zKS4KKyAgICAgIC8vIFRPRE8oa2VudG9uKTogIFByb3ZpZGUgYSBmdW5jdGlvbiBzb21ld2hlcmUgY2FsbGVkIG1ha2VEZWVwQ29weSgpCisgICAgICAvLyAgIHdoaWNoIGFsbG93cyBwZW9wbGUgdG8gbWFrZSBzZWN1cmUgZGVlcCBjb3BpZXMgb2YgbWVzc2FnZXMuCisKKyAgICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBlbnRyeSA6CisgICAgICAgICAgIG90aGVyLmdldEFsbEZpZWxkcygpLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgIGlmIChmaWVsZC5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICBmb3IgKGZpbmFsIE9iamVjdCBlbGVtZW50IDogKExpc3QpZW50cnkuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgZWxlbWVudCk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGZpZWxkLmdldEphdmFUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgICBmaW5hbCBNZXNzYWdlIGV4aXN0aW5nVmFsdWUgPSAoTWVzc2FnZSlnZXRGaWVsZChmaWVsZCk7CisgICAgICAgICAgaWYgKGV4aXN0aW5nVmFsdWUgPT0gZXhpc3RpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkpIHsKKyAgICAgICAgICAgIHNldEZpZWxkKGZpZWxkLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0RmllbGQoZmllbGQsCisgICAgICAgICAgICAgIGV4aXN0aW5nVmFsdWUubmV3QnVpbGRlckZvclR5cGUoKQorICAgICAgICAgICAgICAgIC5tZXJnZUZyb20oZXhpc3RpbmdWYWx1ZSkKKyAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKChNZXNzYWdlKWVudHJ5LmdldFZhbHVlKCkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRGaWVsZChmaWVsZCwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgbWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CisKKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbShmaW5hbCBDb2RlZElucHV0U3RyZWFtIGlucHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBtZXJnZUZyb20oaW5wdXQsIEV4dGVuc2lvblJlZ2lzdHJ5LmdldEVtcHR5UmVnaXN0cnkoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbSgKKyAgICAgICAgZmluYWwgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgZmluYWwgVW5rbm93bkZpZWxkU2V0LkJ1aWxkZXIgdW5rbm93bkZpZWxkcyA9CisgICAgICAgIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKGdldFVua25vd25GaWVsZHMoKSk7CisgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICBmaW5hbCBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOworICAgICAgICBpZiAodGFnID09IDApIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIE1lc3NhZ2VSZWZsZWN0aW9uLkJ1aWxkZXJBZGFwdGVyIGJ1aWxkZXJBZGFwdGVyID0KKyAgICAgICAgICAgIG5ldyBNZXNzYWdlUmVmbGVjdGlvbi5CdWlsZGVyQWRhcHRlcih0aGlzKTsKKyAgICAgICAgaWYgKCFNZXNzYWdlUmVmbGVjdGlvbi5tZXJnZUZpZWxkRnJvbShpbnB1dCwgdW5rbm93bkZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkZXJBZGFwdGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZykpIHsKKyAgICAgICAgICAvLyBlbmQgZ3JvdXAgdGFnCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcy5idWlsZCgpKTsKKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlVW5rbm93bkZpZWxkcyhmaW5hbCBVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgc2V0VW5rbm93bkZpZWxkcygKKyAgICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoZ2V0VW5rbm93bkZpZWxkcygpKQorICAgICAgICAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHVua25vd25GaWVsZHMpCisgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZEJ1aWxkZXIoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImdldEZpZWxkQnVpbGRlcigpIGNhbGxlZCBvbiBhbiB1bnN1cHBvcnRlZCBtZXNzYWdlIHR5cGUuIik7CisgICAgfQorCisgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZEZpZWxkQnVpbGRlcihmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgIGludCBpbmRleCkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkQnVpbGRlcigpIGNhbGxlZCBvbiBhbiB1bnN1cHBvcnRlZCBtZXNzYWdlIHR5cGUuIik7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIHJldHVybiBUZXh0Rm9ybWF0LnByaW50VG9TdHJpbmcodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIHJlcG9ydGluZyBtaXNzaW5nIGZpZWxkcyBpbgorICAgICAqIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24KKyAgICAgICAgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24oTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICByZXR1cm4gbmV3IFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKAorICAgICAgICAgIE1lc3NhZ2VSZWZsZWN0aW9uLmZpbmRNaXNzaW5nRmllbGRzKG1lc3NhZ2UpKTsKKyAgICB9CisKKyAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgICAvLyBUaGUgZm9sbG93aW5nIGRlZmluaXRpb25zIHNlZW0gdG8gYmUgcmVxdWlyZWQgaW4gb3JkZXIgdG8gbWFrZSBqYXZhYworICAgIC8vIG5vdCBwcm9kdWNlIHdlaXJkIGVycm9ycyBsaWtlOgorICAgIC8vCisgICAgLy8gamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0R5bmFtaWNNZXNzYWdlLmphdmE6MjAzOiB0eXBlcworICAgIC8vICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2UuQnVpbGRlcjwKKyAgICAvLyAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EeW5hbWljTWVzc2FnZS5CdWlsZGVyPiBhbmQKKyAgICAvLyAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkJ1aWxkZXI8CisgICAgLy8gICAgIGNvbS5nb29nbGUucHJvdG9idWYuRHluYW1pY01lc3NhZ2UuQnVpbGRlcj4gYXJlIGluY29tcGF0aWJsZTsgYm90aAorICAgIC8vICAgZGVmaW5lIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpLCBidXQgd2l0aCB1bnJlbGF0ZWQKKyAgICAvLyAgIHJldHVybiB0eXBlcy4KKyAgICAvLworICAgIC8vIFN0cmFuZ2VseSwgdGhlc2UgbGluZXMgYXJlIG9ubHkgbmVlZGVkIGlmIGphdmFjIGlzIGludm9rZWQgc2VwYXJhdGVseQorICAgIC8vIG9uIEFic3RyYWN0TWVzc2FnZS5qYXZhIGFuZCBBYnN0cmFjdE1lc3NhZ2VMaXRlLmphdmEuICBJZiBqYXZhYyBpcworICAgIC8vIGludm9rZWQgb24gYm90aCBzaW11bHRhbmVvdXNseSwgaXQgd29ya3MuICAoT3IgbWF5YmUgdGhlIGltcG9ydGFudAorICAgIC8vIHBvaW50IGlzIHdoZXRoZXIgb3Igbm90IER5bmFtaWNNZXNzYWdlLmphdmEgaXMgY29tcGlsZWQgdG9nZXRoZXIgd2l0aAorICAgIC8vIEFic3RyYWN0TWVzc2FnZUxpdGUuamF2YSAtLSBub3Qgc3VyZS4pICBJIHN1c3BlY3QgdGhpcyBpcyBhIGNvbXBpbGVyCisgICAgLy8gYnVnLgorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbShmaW5hbCBCeXRlU3RyaW5nIGRhdGEpCisgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlRnJvbShkYXRhKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKAorICAgICAgICBmaW5hbCBCeXRlU3RyaW5nIGRhdGEsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gc3VwZXIubWVyZ2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKGZpbmFsIGJ5dGVbXSBkYXRhKQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBzdXBlci5tZXJnZUZyb20oZGF0YSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbSgKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pCisgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlRnJvbShkYXRhLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbSgKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gc3VwZXIubWVyZ2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKAorICAgICAgICBmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbiwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBzdXBlci5tZXJnZUZyb20oZGF0YSwgb2ZmLCBsZW4sIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKGZpbmFsIElucHV0U3RyZWFtIGlucHV0KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlRnJvbShpbnB1dCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbSgKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBzdXBlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtZXJnZURlbGltaXRlZEZyb20oZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gc3VwZXIubWVyZ2VEZWxpbWl0ZWRGcm9tKGlucHV0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtZXJnZURlbGltaXRlZEZyb20oCisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gc3VwZXIubWVyZ2VEZWxpbWl0ZWRGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2VMaXRlLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2VMaXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWFjNGZhNwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Fic3RyYWN0TWVzc2FnZUxpdGUuamF2YQpAQCAtMCwwICsxLDM1NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCisvKioKKyAqIEEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUge0BsaW5rIE1lc3NhZ2VMaXRlfSBpbnRlcmZhY2Ugd2hpY2gKKyAqIGltcGxlbWVudHMgYXMgbWFueSBtZXRob2RzIG9mIHRoYXQgaW50ZXJmYWNlIGFzIHBvc3NpYmxlIGluIHRlcm1zIG9mIG90aGVyCisgKiBtZXRob2RzLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE1lc3NhZ2VMaXRlIGltcGxlbWVudHMgTWVzc2FnZUxpdGUgeworICBwcm90ZWN0ZWQgaW50IG1lbW9pemVkSGFzaENvZGUgPSAwOworCisgIHB1YmxpYyBCeXRlU3RyaW5nIHRvQnl0ZVN0cmluZygpIHsKKyAgICB0cnkgeworICAgICAgZmluYWwgQnl0ZVN0cmluZy5Db2RlZEJ1aWxkZXIgb3V0ID0KKyAgICAgICAgQnl0ZVN0cmluZy5uZXdDb2RlZEJ1aWxkZXIoZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgICAgICB3cml0ZVRvKG91dC5nZXRDb2RlZE91dHB1dCgpKTsKKyAgICAgIHJldHVybiBvdXQuYnVpbGQoKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgIlNlcmlhbGl6aW5nIHRvIGEgQnl0ZVN0cmluZyB0aHJldyBhbiBJT0V4Y2VwdGlvbiAoc2hvdWxkICIgKworICAgICAgICAibmV2ZXIgaGFwcGVuKS4iLCBlKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIHRvQnl0ZUFycmF5KCkgeworICAgIHRyeSB7CisgICAgICBmaW5hbCBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbZ2V0U2VyaWFsaXplZFNpemUoKV07CisgICAgICBmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShyZXN1bHQpOworICAgICAgd3JpdGVUbyhvdXRwdXQpOworICAgICAgb3V0cHV0LmNoZWNrTm9TcGFjZUxlZnQoKTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICJTZXJpYWxpemluZyB0byBhIGJ5dGUgYXJyYXkgdGhyZXcgYW4gSU9FeGNlcHRpb24gIiArCisgICAgICAgICIoc2hvdWxkIG5ldmVyIGhhcHBlbikuIiwgZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGVUbyhmaW5hbCBPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIGludCBidWZmZXJTaXplID0KKyAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZVByZWZlcnJlZEJ1ZmZlclNpemUoZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgICAgZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRPdXRwdXQgPQorICAgICAgICBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShvdXRwdXQsIGJ1ZmZlclNpemUpOworICAgIHdyaXRlVG8oY29kZWRPdXRwdXQpOworICAgIGNvZGVkT3V0cHV0LmZsdXNoKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZURlbGltaXRlZFRvKGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IHNlcmlhbGl6ZWQgPSBnZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIGZpbmFsIGludCBidWZmZXJTaXplID0gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZVByZWZlcnJlZEJ1ZmZlclNpemUoCisgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoc2VyaWFsaXplZCkgKyBzZXJpYWxpemVkKTsKKyAgICBmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZE91dHB1dCA9CisgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKG91dHB1dCwgYnVmZmVyU2l6ZSk7CisgICAgY29kZWRPdXRwdXQud3JpdGVSYXdWYXJpbnQzMihzZXJpYWxpemVkKTsKKyAgICB3cml0ZVRvKGNvZGVkT3V0cHV0KTsKKyAgICBjb2RlZE91dHB1dC5mbHVzaCgpOworICB9CisKKworICAvKioKKyAgICogUGFja2FnZSBwcml2YXRlIGhlbHBlciBtZXRob2QgZm9yIEFic3RyYWN0UGFyc2VyIHRvIGNyZWF0ZQorICAgKiBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbi4KKyAgICovCisgIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKCkgeworICAgIHJldHVybiBuZXcgVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24odGhpcyk7CisgIH0KKworICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KEJ5dGVTdHJpbmcgYnl0ZVN0cmluZykKKyAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgIGlmICghYnl0ZVN0cmluZy5pc1ZhbGlkVXRmOCgpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCeXRlIHN0cmluZyBpcyBub3QgVVRGLTguIik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUge0BsaW5rIE1lc3NhZ2UuQnVpbGRlcn0gaW50ZXJmYWNlIHdoaWNoCisgICAqIGltcGxlbWVudHMgYXMgbWFueSBtZXRob2RzIG9mIHRoYXQgaW50ZXJmYWNlIGFzIHBvc3NpYmxlIGluIHRlcm1zIG9mCisgICAqIG90aGVyIG1ldGhvZHMuCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBCdWlsZGVyPEJ1aWxkZXJUeXBlIGV4dGVuZHMgQnVpbGRlcj4KKyAgICAgIGltcGxlbWVudHMgTWVzc2FnZUxpdGUuQnVpbGRlciB7CisgICAgLy8gVGhlIGNvbXBpbGVyIHByb2R1Y2VzIGFuIGVycm9yIGlmIHRoaXMgaXMgbm90IGRlY2xhcmVkIGV4cGxpY2l0bHkuCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXJUeXBlIGNsb25lKCk7CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIG1lcmdlRnJvbShpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKSk7CisgICAgfQorCisgICAgLy8gUmUtZGVmaW5lZCBoZXJlIGZvciByZXR1cm4gdHlwZSBjb3ZhcmlhbmNlLgorICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyVHlwZSBtZXJnZUZyb20oCisgICAgICAgIGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbShmaW5hbCBCeXRlU3RyaW5nIGRhdGEpCisgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgdHJ5IHsKKyAgICAgICAgZmluYWwgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IGRhdGEubmV3Q29kZWRJbnB1dCgpOworICAgICAgICBtZXJnZUZyb20oaW5wdXQpOworICAgICAgICBpbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBlOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAiUmVhZGluZyBmcm9tIGEgQnl0ZVN0cmluZyB0aHJldyBhbiBJT0V4Y2VwdGlvbiAoc2hvdWxkICIgKworICAgICAgICAgICJuZXZlciBoYXBwZW4pLiIsIGUpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBtZXJnZUZyb20oCisgICAgICAgIGZpbmFsIEJ5dGVTdHJpbmcgZGF0YSwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPSBkYXRhLm5ld0NvZGVkSW5wdXQoKTsKKyAgICAgICAgbWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgICAgIGlucHV0LmNoZWNrTGFzdFRhZ1dhcygwKTsKKyAgICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGU7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJSZWFkaW5nIGZyb20gYSBCeXRlU3RyaW5nIHRocmV3IGFuIElPRXhjZXB0aW9uIChzaG91bGQgIiArCisgICAgICAgICAgIm5ldmVyIGhhcHBlbikuIiwgZSk7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbShmaW5hbCBieXRlW10gZGF0YSkKKyAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gbWVyZ2VGcm9tKGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBpbnQgb2ZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgdHJ5IHsKKyAgICAgICAgZmluYWwgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9CisgICAgICAgICAgICBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGRhdGEsIG9mZiwgbGVuKTsKKyAgICAgICAgbWVyZ2VGcm9tKGlucHV0KTsKKyAgICAgICAgaW5wdXQuY2hlY2tMYXN0VGFnV2FzKDApOworICAgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSB0aGlzOworICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgZTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgIlJlYWRpbmcgZnJvbSBhIGJ5dGUgYXJyYXkgdGhyZXcgYW4gSU9FeGNlcHRpb24gKHNob3VsZCAiICsKKyAgICAgICAgICAibmV2ZXIgaGFwcGVuKS4iLCBlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKAorICAgICAgICBmaW5hbCBieXRlW10gZGF0YSwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBtZXJnZUZyb20oZGF0YSwgMCwgZGF0YS5sZW5ndGgsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKAorICAgICAgICBmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbiwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPQorICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhLCBvZmYsIGxlbik7CisgICAgICAgIG1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgICBpbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBlOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAiUmVhZGluZyBmcm9tIGEgYnl0ZSBhcnJheSB0aHJldyBhbiBJT0V4Y2VwdGlvbiAoc2hvdWxkICIgKworICAgICAgICAgICJuZXZlciBoYXBwZW4pLiIsIGUpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBtZXJnZUZyb20oZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBDb2RlZElucHV0U3RyZWFtIGNvZGVkSW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGlucHV0KTsKKyAgICAgIG1lcmdlRnJvbShjb2RlZElucHV0KTsKKyAgICAgIGNvZGVkSW5wdXQuY2hlY2tMYXN0VGFnV2FzKDApOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKAorICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgZmluYWwgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZElucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShpbnB1dCk7CisgICAgICBtZXJnZUZyb20oY29kZWRJbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgY29kZWRJbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIElucHV0U3RyZWFtIGltcGxlbWVudGF0aW9ucyB3aGljaCByZWFkcyBmcm9tIHNvbWUgb3RoZXIgSW5wdXRTdHJlYW0KKyAgICAgKiBidXQgaXMgbGltaXRlZCB0byBhIHBhcnRpY3VsYXIgbnVtYmVyIG9mIGJ5dGVzLiAgVXNlZCBieQorICAgICAqIG1lcmdlRGVsaW1pdGVkRnJvbSgpLiAgVGhpcyBpcyBpbnRlbnRpb25hbGx5IHBhY2thZ2UtcHJpdmF0ZSBzbyB0aGF0CisgICAgICogVW5rbm93bkZpZWxkU2V0IGNhbiBzaGFyZSBpdC4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgTGltaXRlZElucHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVySW5wdXRTdHJlYW0geworICAgICAgcHJpdmF0ZSBpbnQgbGltaXQ7CisKKyAgICAgIExpbWl0ZWRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbiwgaW50IGxpbWl0KSB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICAgICAgdGhpcy5saW1pdCA9IGxpbWl0OworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIE1hdGgubWluKHN1cGVyLmF2YWlsYWJsZSgpLCBsaW1pdCk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxpbWl0IDw9IDApIHsKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IHJlc3VsdCA9IHN1cGVyLnJlYWQoKTsKKyAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CisgICAgICAgICAgLS1saW1pdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobGltaXQgPD0gMCkgeworICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBsZW4gPSBNYXRoLm1pbihsZW4sIGxpbWl0KTsKKyAgICAgICAgZmluYWwgaW50IHJlc3VsdCA9IHN1cGVyLnJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICBpZiAocmVzdWx0ID49IDApIHsKKyAgICAgICAgICBsaW1pdCAtPSByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgbG9uZyBza2lwKGZpbmFsIGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgbG9uZyByZXN1bHQgPSBzdXBlci5za2lwKE1hdGgubWluKG4sIGxpbWl0KSk7CisgICAgICAgIGlmIChyZXN1bHQgPj0gMCkgeworICAgICAgICAgIGxpbWl0IC09IHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIG1lcmdlRGVsaW1pdGVkRnJvbSgKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGZpbmFsIGludCBmaXJzdEJ5dGUgPSBpbnB1dC5yZWFkKCk7CisgICAgICBpZiAoZmlyc3RCeXRlID09IC0xKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGZpbmFsIGludCBzaXplID0gQ29kZWRJbnB1dFN0cmVhbS5yZWFkUmF3VmFyaW50MzIoZmlyc3RCeXRlLCBpbnB1dCk7CisgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBsaW1pdGVkSW5wdXQgPSBuZXcgTGltaXRlZElucHV0U3RyZWFtKGlucHV0LCBzaXplKTsKKyAgICAgIG1lcmdlRnJvbShsaW1pdGVkSW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIG1lcmdlRGVsaW1pdGVkRnJvbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBtZXJnZURlbGltaXRlZEZyb20oaW5wdXQsCisgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIHJlcG9ydGluZyBtaXNzaW5nIGZpZWxkcyBpbgorICAgICAqIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24KKyAgICAgICAgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24oTWVzc2FnZUxpdGUgbWVzc2FnZSkgeworICAgICAgcmV0dXJuIG5ldyBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihtZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSB7QGNvZGUgdmFsdWVzfSB0byB0aGUge0Bjb2RlIGxpc3R9LiAgVGhpcyBpcyBhIGhlbHBlciBtZXRob2QKKyAgICAgKiB1c2VkIGJ5IGdlbmVyYXRlZCBjb2RlLiAgVXNlcnMgc2hvdWxkIGlnbm9yZSBpdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBlbGVtZW50cyBvZiB7QGNvZGUgdmFsdWVzfSBpcworICAgICAqIG51bGwuIFdoZW4gdGhhdCBoYXBwZW5zLCBzb21lIGVsZW1lbnRzIG9mIHtAY29kZSB2YWx1ZXN9IG1heSBoYXZlIGFscmVhZHkKKyAgICAgKiBiZWVuIGFkZGVkIHRvIHRoZSByZXN1bHQge0Bjb2RlIGxpc3R9LgorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgPFQ+IHZvaWQgYWRkQWxsKGZpbmFsIEl0ZXJhYmxlPFQ+IHZhbHVlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBDb2xsZWN0aW9uPD8gc3VwZXIgVD4gbGlzdCkgeworICAgICAgaWYgKHZhbHVlcyBpbnN0YW5jZW9mIExhenlTdHJpbmdMaXN0KSB7CisgICAgICAgIC8vIEZvciBTdHJpbmdPckJ5dGVTdHJpbmdMaXN0cywgY2hlY2sgdGhlIHVuZGVybHlpbmcgZWxlbWVudHMgdG8gYXZvaWQKKyAgICAgICAgLy8gZm9yY2luZyBjb252ZXJzaW9ucyBvZiBCeXRlU3RyaW5ncyB0byBTdHJpbmdzLgorICAgICAgICBjaGVja0Zvck51bGxWYWx1ZXMoKChMYXp5U3RyaW5nTGlzdCkgdmFsdWVzKS5nZXRVbmRlcmx5aW5nRWxlbWVudHMoKSk7CisgICAgICAgIGxpc3QuYWRkQWxsKChDb2xsZWN0aW9uPFQ+KSB2YWx1ZXMpOworICAgICAgfSBlbHNlIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBDb2xsZWN0aW9uKSB7CisgICAgICAgIGNoZWNrRm9yTnVsbFZhbHVlcyh2YWx1ZXMpOworICAgICAgICBsaXN0LmFkZEFsbCgoQ29sbGVjdGlvbjxUPikgdmFsdWVzKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZvciAoZmluYWwgVCB2YWx1ZSA6IHZhbHVlcykgeworICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICB9CisgICAgICAgICAgbGlzdC5hZGQodmFsdWUpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0Zvck51bGxWYWx1ZXMoZmluYWwgSXRlcmFibGU8Pz4gdmFsdWVzKSB7CisgICAgICBmb3IgKGZpbmFsIE9iamVjdCB2YWx1ZSA6IHZhbHVlcykgeworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdFBhcnNlci5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTRjNjMxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RQYXJzZXIuamF2YQpAQCAtMCwwICsxLDI1MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLkxpbWl0ZWRJbnB1dFN0cmVhbTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBBIHBhcnRpYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluayBQYXJzZXJ9IGludGVyZmFjZSB3aGljaCBpbXBsZW1lbnRzCisgKiBhcyBtYW55IG1ldGhvZHMgb2YgdGhhdCBpbnRlcmZhY2UgYXMgcG9zc2libGUgaW4gdGVybXMgb2Ygb3RoZXIgbWV0aG9kcy4KKyAqCisgKiBOb3RlOiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYWxsIHRoZSBjb252ZW5pZW5jZSBtZXRob2RzIGluIHRoZQorICoge0BsaW5rIFBhcnNlcn0gaW50ZXJmYWNlLiBTZWUge0BsaW5rIFBhcnNlcn0gZm9yIHJlbGF0ZWQgamF2YWRvY3MuCisgKiBTdWJjbGFzc2VzIG5lZWQgdG8gaW1wbGVtZW50CisgKiB7QGxpbmsgUGFyc2VyI3BhcnNlUGFydGlhbEZyb20oQ29kZWRJbnB1dFN0cmVhbSwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKX0KKyAqCisgKiBAYXV0aG9yIGxpdWppc2lAZ29vZ2xlLmNvbSAoUGhlcmwgTGl1KQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RQYXJzZXI8TWVzc2FnZVR5cGUgZXh0ZW5kcyBNZXNzYWdlTGl0ZT4KKyAgICBpbXBsZW1lbnRzIFBhcnNlcjxNZXNzYWdlVHlwZT4geworICAvKioKKyAgICogQ3JlYXRlcyBhbiBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBmb3IgTWVzc2FnZVR5cGUuCisgICAqLworICBwcml2YXRlIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uCisgICAgICBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihNZXNzYWdlVHlwZSBtZXNzYWdlKSB7CisgICAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBBYnN0cmFjdE1lc3NhZ2VMaXRlKSB7CisgICAgICByZXR1cm4gKChBYnN0cmFjdE1lc3NhZ2VMaXRlKSBtZXNzYWdlKS5uZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbigpOworICAgIH0KKyAgICByZXR1cm4gbmV3IFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKG1lc3NhZ2UpOworICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBtZXRob2QgdG8gY2hlY2sgaWYgbWVzc2FnZSBpcyBpbml0aWFsaXplZC4KKyAgICoKKyAgICogQHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gaWYgaXQgaXMgbm90IGluaXRpYWxpemVkLgorICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIHRvIGNoZWNrLgorICAgKi8KKyAgcHJpdmF0ZSBNZXNzYWdlVHlwZSBjaGVja01lc3NhZ2VJbml0aWFsaXplZChNZXNzYWdlVHlwZSBtZXNzYWdlKQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgaWYgKG1lc3NhZ2UgIT0gbnVsbCAmJiAhbWVzc2FnZS5pc0luaXRpYWxpemVkKCkpIHsKKyAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKG1lc3NhZ2UpCisgICAgICAgICAgLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkKKyAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UobWVzc2FnZSk7CisgICAgfQorICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIEVNUFRZX1JFR0lTVFJZCisgICAgICA9IEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5nZXRFbXB0eVJlZ2lzdHJ5KCk7CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIHJldHVybiBwYXJzZVBhcnRpYWxGcm9tKGlucHV0LCBFTVBUWV9SRUdJU1RSWSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNoZWNrTWVzc2FnZUluaXRpYWxpemVkKAorICAgICAgICBwYXJzZVBhcnRpYWxGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShDb2RlZElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlRnJvbShpbnB1dCwgRU1QVFlfUkVHSVNUUlkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oQnl0ZVN0cmluZyBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgTWVzc2FnZVR5cGUgbWVzc2FnZTsKKyAgICB0cnkgeworICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IGRhdGEubmV3Q29kZWRJbnB1dCgpOworICAgICAgbWVzc2FnZSA9IHBhcnNlUGFydGlhbEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgIHRyeSB7CisgICAgICAgIGlucHV0LmNoZWNrTGFzdFRhZ1dhcygwKTsKKyAgICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UobWVzc2FnZSk7CisgICAgICB9CisgICAgICByZXR1cm4gbWVzc2FnZTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShCeXRlU3RyaW5nIGRhdGEpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcGFyc2VQYXJ0aWFsRnJvbShkYXRhLCBFTVBUWV9SRUdJU1RSWSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VGcm9tKEJ5dGVTdHJpbmcgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY2hlY2tNZXNzYWdlSW5pdGlhbGl6ZWQocGFyc2VQYXJ0aWFsRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShCeXRlU3RyaW5nIGRhdGEpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcGFyc2VGcm9tKGRhdGEsIEVNUFRZX1JFR0lTVFJZKTsKKyAgfQorCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZVBhcnRpYWxGcm9tKGJ5dGVbXSBkYXRhLCBpbnQgb2ZmLCBpbnQgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZGF0YSwgb2ZmLCBsZW4pOworICAgICAgTWVzc2FnZVR5cGUgbWVzc2FnZSA9IHBhcnNlUGFydGlhbEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgIHRyeSB7CisgICAgICAgIGlucHV0LmNoZWNrTGFzdFRhZ1dhcygwKTsKKyAgICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UobWVzc2FnZSk7CisgICAgICB9CisgICAgICByZXR1cm4gbWVzc2FnZTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIHJldHVybiBwYXJzZVBhcnRpYWxGcm9tKGRhdGEsIG9mZiwgbGVuLCBFTVBUWV9SRUdJU1RSWSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShieXRlW10gZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlUGFydGlhbEZyb20oZGF0YSwgMCwgZGF0YS5sZW5ndGgsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgfQorCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZVBhcnRpYWxGcm9tKGJ5dGVbXSBkYXRhKQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlUGFydGlhbEZyb20oZGF0YSwgMCwgZGF0YS5sZW5ndGgsIEVNUFRZX1JFR0lTVFJZKTsKKyAgfQorCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNoZWNrTWVzc2FnZUluaXRpYWxpemVkKAorICAgICAgICBwYXJzZVBhcnRpYWxGcm9tKGRhdGEsIG9mZiwgbGVuLCBleHRlbnNpb25SZWdpc3RyeSkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIHJldHVybiBwYXJzZUZyb20oZGF0YSwgb2ZmLCBsZW4sIEVNUFRZX1JFR0lTVFJZKTsKKyAgfQorCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlRnJvbShkYXRhLCAwLCBkYXRhLmxlbmd0aCwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIHJldHVybiBwYXJzZUZyb20oZGF0YSwgRU1QVFlfUkVHSVNUUlkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRJbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoaW5wdXQpOworICAgIE1lc3NhZ2VUeXBlIG1lc3NhZ2UgPSBwYXJzZVBhcnRpYWxGcm9tKGNvZGVkSW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB0cnkgeworICAgICAgY29kZWRJbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UobWVzc2FnZSk7CisgICAgfQorICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcGFyc2VQYXJ0aWFsRnJvbShpbnB1dCwgRU1QVFlfUkVHSVNUUlkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY2hlY2tNZXNzYWdlSW5pdGlhbGl6ZWQoCisgICAgICAgIHBhcnNlUGFydGlhbEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VGcm9tKElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlRnJvbShpbnB1dCwgRU1QVFlfUkVHSVNUUlkpOworICB9CisKKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbERlbGltaXRlZEZyb20oCisgICAgICBJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIGludCBzaXplOworICAgIHRyeSB7CisgICAgICBpbnQgZmlyc3RCeXRlID0gaW5wdXQucmVhZCgpOworICAgICAgaWYgKGZpcnN0Qnl0ZSA9PSAtMSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIHNpemUgPSBDb2RlZElucHV0U3RyZWFtLnJlYWRSYXdWYXJpbnQzMihmaXJzdEJ5dGUsIGlucHV0KTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgICAgSW5wdXRTdHJlYW0gbGltaXRlZElucHV0ID0gbmV3IExpbWl0ZWRJbnB1dFN0cmVhbShpbnB1dCwgc2l6ZSk7CisgICAgcmV0dXJuIHBhcnNlUGFydGlhbEZyb20obGltaXRlZElucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRGVsaW1pdGVkRnJvbShJbnB1dFN0cmVhbSBpbnB1dCkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIHJldHVybiBwYXJzZVBhcnRpYWxEZWxpbWl0ZWRGcm9tKGlucHV0LCBFTVBUWV9SRUdJU1RSWSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAorICAgICAgSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY2hlY2tNZXNzYWdlSW5pdGlhbGl6ZWQoCisgICAgICAgIHBhcnNlUGFydGlhbERlbGltaXRlZEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KSk7CisgIH0KKworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VEZWxpbWl0ZWRGcm9tKElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlRGVsaW1pdGVkRnJvbShpbnB1dCwgRU1QVFlfUkVHSVNUUlkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9CbG9ja2luZ1JwY0NoYW5uZWwuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Jsb2NraW5nUnBjQ2hhbm5lbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ1MzVlZmIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9CbG9ja2luZ1JwY0NoYW5uZWwuamF2YQpAQCAtMCwwICsxLDUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCisvKioKKyAqIDxwPkFic3RyYWN0IGludGVyZmFjZSBmb3IgYSBibG9ja2luZyBSUEMgY2hhbm5lbC4gIHtAY29kZSBCbG9ja2luZ1JwY0NoYW5uZWx9CisgKiBpcyB0aGUgYmxvY2tpbmcgZXF1aXZhbGVudCB0byB7QGxpbmsgUnBjQ2hhbm5lbH0uCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqIEBhdXRob3IgY3Bvdmlya0Bnb29nbGUuY29tIENocmlzIFBvdmlyaworICovCitwdWJsaWMgaW50ZXJmYWNlIEJsb2NraW5nUnBjQ2hhbm5lbCB7CisgIC8qKgorICAgKiBDYWxsIHRoZSBnaXZlbiBtZXRob2Qgb2YgdGhlIHJlbW90ZSBzZXJ2aWNlIGFuZCBibG9ja3MgdW50aWwgaXQgcmV0dXJucy4KKyAgICoge0Bjb2RlIGNhbGxCbG9ja2luZ01ldGhvZCgpfSBpcyB0aGUgYmxvY2tpbmcgZXF1aXZhbGVudCB0bworICAgKiB7QGxpbmsgUnBjQ2hhbm5lbCNjYWxsTWV0aG9kfS4KKyAgICovCisgIE1lc3NhZ2UgY2FsbEJsb2NraW5nTWV0aG9kKAorICAgICAgRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QsCisgICAgICBScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCisgICAgICBNZXNzYWdlIHJlcXVlc3QsCisgICAgICBNZXNzYWdlIHJlc3BvbnNlUHJvdG90eXBlKSB0aHJvd3MgU2VydmljZUV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Jsb2NraW5nU2VydmljZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQmxvY2tpbmdTZXJ2aWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDAxZjBiOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Jsb2NraW5nU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogQmxvY2tpbmcgZXF1aXZhbGVudCB0byB7QGxpbmsgU2VydmljZX0uCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqIEBhdXRob3IgY3Bvdmlya0Bnb29nbGUuY29tIENocmlzIFBvdmlyaworICovCitwdWJsaWMgaW50ZXJmYWNlIEJsb2NraW5nU2VydmljZSB7CisgIC8qKgorICAgKiBFcXVpdmFsZW50IHRvIHtAbGluayBTZXJ2aWNlI2dldERlc2NyaXB0b3JGb3JUeXBlfS4KKyAgICovCisgIERlc2NyaXB0b3JzLlNlcnZpY2VEZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCk7CisKKyAgLyoqCisgICAqIEVxdWl2YWxlbnQgdG8ge0BsaW5rIFNlcnZpY2UjY2FsbE1ldGhvZH0sIGV4Y2VwdCB0aGF0CisgICAqIHtAY29kZSBjYWxsQmxvY2tpbmdNZXRob2QoKX0gcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBSUEMgb3IgdGhyb3dzIGEKKyAgICoge0BsaW5rIFNlcnZpY2VFeGNlcHRpb259IGlmIHRoZXJlIGlzIGEgZmFpbHVyZSwgcmF0aGVyIHRoYW4gcGFzc2luZyB0aGUKKyAgICogaW5mb3JtYXRpb24gdG8gYSBjYWxsYmFjay4KKyAgICovCisgIE1lc3NhZ2UgY2FsbEJsb2NraW5nTWV0aG9kKERlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgcmVxdWVzdCkgdGhyb3dzIFNlcnZpY2VFeGNlcHRpb247CisKKyAgLyoqCisgICAqIEVxdWl2YWxlbnQgdG8ge0BsaW5rIFNlcnZpY2UjZ2V0UmVxdWVzdFByb3RvdHlwZX0uCisgICAqLworICBNZXNzYWdlIGdldFJlcXVlc3RQcm90b3R5cGUoRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpOworCisgIC8qKgorICAgKiBFcXVpdmFsZW50IHRvIHtAbGluayBTZXJ2aWNlI2dldFJlc3BvbnNlUHJvdG90eXBlfS4KKyAgICovCisgIE1lc3NhZ2UgZ2V0UmVzcG9uc2VQcm90b3R5cGUoRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQm91bmRlZEJ5dGVTdHJpbmcuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0JvdW5kZWRCeXRlU3RyaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRjM2ZiMQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0JvdW5kZWRCeXRlU3RyaW5nLmphdmEKQEAgLTAsMCArMSwxODAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW52YWxpZE9iamVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgdXNlZCB0byByZXByZXNlbnQgdGhlIHN1YnN0cmluZyBvZiBhIHtAbGluayBCeXRlU3RyaW5nfSBvdmVyIGEKKyAqIHNpbmdsZSBieXRlIGFycmF5LiBJbiB0ZXJtcyBvZiB0aGUgcHVibGljIEFQSSBvZiB7QGxpbmsgQnl0ZVN0cmluZ30sIHlvdSBlbmQKKyAqIHVwIGhlcmUgYnkgY2FsbGluZyB7QGxpbmsgQnl0ZVN0cmluZyNjb3B5RnJvbShieXRlW10pfSBmb2xsb3dlZCBieSB7QGxpbmsKKyAqIEJ5dGVTdHJpbmcjc3Vic3RyaW5nKGludCwgaW50KX0uCisgKgorICogPHA+VGhpcyBjbGFzcyBjb250YWlucyBtb3N0IG9mIHRoZSBvdmVyaGVhZCBpbnZvbHZlZCBpbiBjcmVhdGluZyBhIHN1YnN0cmluZworICogZnJvbSBhIHtAbGluayBMaXRlcmFsQnl0ZVN0cmluZ30uICBUaGUgb3ZlcmhlYWQgaW52b2x2ZXMgc29tZSByYW5nZS1jaGVja2luZworICogYW5kIHR3byBleHRyYSBmaWVsZHMuCisgKgorICogQGF1dGhvciBjYXJsYW50b25AZ29vZ2xlLmNvbSAoQ2FybCBIYXZlcmwpCisgKi8KK2NsYXNzIEJvdW5kZWRCeXRlU3RyaW5nIGV4dGVuZHMgTGl0ZXJhbEJ5dGVTdHJpbmcgeworCisgIHByaXZhdGUgZmluYWwgaW50IGJ5dGVzT2Zmc2V0OworICBwcml2YXRlIGZpbmFsIGludCBieXRlc0xlbmd0aDsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIHtAY29kZSBCb3VuZGVkQnl0ZVN0cmluZ30gYmFja2VkIGJ5IHRoZSBzdWItcmFuZ2Ugb2YgZ2l2ZW4gYXJyYXksCisgICAqIHdpdGhvdXQgY29weWluZy4KKyAgICoKKyAgICogQHBhcmFtIGJ5dGVzICBhcnJheSB0byB3cmFwCisgICAqIEBwYXJhbSBvZmZzZXQgaW5kZXggdG8gZmlyc3QgYnl0ZSB0byB1c2UgaW4gYnl0ZXMKKyAgICogQHBhcmFtIGxlbmd0aCBudW1iZXIgb2YgYnl0ZXMgdG8gdXNlIGZyb20gYnl0ZXMKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIG9mZnNldCA8IDB9LCB7QGNvZGUgbGVuZ3RoIDwgMH0sCisgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIHtAY29kZSBvZmZzZXQgKyBsZW5ndGggPgorICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlcy5sZW5ndGh9LgorICAgKi8KKyAgQm91bmRlZEJ5dGVTdHJpbmcoYnl0ZVtdIGJ5dGVzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgc3VwZXIoYnl0ZXMpOworICAgIGlmIChvZmZzZXQgPCAwKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJPZmZzZXQgdG9vIHNtYWxsOiAiICsgb2Zmc2V0KTsKKyAgICB9CisgICAgaWYgKGxlbmd0aCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkxlbmd0aCB0b28gc21hbGw6ICIgKyBvZmZzZXQpOworICAgIH0KKyAgICBpZiAoKGxvbmcpIG9mZnNldCArIGxlbmd0aCA+IGJ5dGVzLmxlbmd0aCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiT2Zmc2V0K0xlbmd0aCB0b28gbGFyZ2U6ICIgKyBvZmZzZXQgKyAiKyIgKyBsZW5ndGgpOworICAgIH0KKworICAgIHRoaXMuYnl0ZXNPZmZzZXQgPSBvZmZzZXQ7CisgICAgdGhpcy5ieXRlc0xlbmd0aCA9IGxlbmd0aDsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleC4KKyAgICogVGhyb3dzIHtAbGluayBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb259CisgICAqIGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSByZWFzb25zIGFsdGhvdWdoIGl0IHdvdWxkIG1vcmUgcHJvcGVybHkgYmUKKyAgICoge0BsaW5rIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb259LgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgYnl0ZQorICAgKiBAcmV0dXJuIHRoZSB2YWx1ZQorICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7QGNvZGUgaW5kZXh9IGlzIDwgMCBvciA+PSBzaXplCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJ5dGUgYnl0ZUF0KGludCBpbmRleCkgeworICAgIC8vIFdlIG11c3QgY2hlY2sgdGhlIGluZGV4IG91cnNlbHZlcyBhcyB3ZSBjYW5ub3QgcmVseSBvbiBKYXZhIGFycmF5IGluZGV4CisgICAgLy8gY2hlY2tpbmcgZm9yIHN1YnN0cmluZ3MuCisgICAgaWYgKGluZGV4IDwgMCkgeworICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiSW5kZXggdG9vIHNtYWxsOiAiICsgaW5kZXgpOworICAgIH0KKyAgICBpZiAoaW5kZXggPj0gc2l6ZSgpKSB7CisgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKAorICAgICAgICAgICJJbmRleCB0b28gbGFyZ2U6ICIgKyBpbmRleCArICIsICIgKyBzaXplKCkpOworICAgIH0KKworICAgIHJldHVybiBieXRlc1tieXRlc09mZnNldCArIGluZGV4XTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgcmV0dXJuIGJ5dGVzTGVuZ3RoOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBpbnQgZ2V0T2Zmc2V0SW50b0J5dGVzKCkgeworICAgIHJldHVybiBieXRlc09mZnNldDsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIEJ5dGVTdHJpbmcgLT4gYnl0ZVtdCisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIGNvcHlUb0ludGVybmFsKGJ5dGVbXSB0YXJnZXQsIGludCBzb3VyY2VPZmZzZXQsIAorICAgICAgaW50IHRhcmdldE9mZnNldCwgaW50IG51bWJlclRvQ29weSkgeworICAgIFN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIGdldE9mZnNldEludG9CeXRlcygpICsgc291cmNlT2Zmc2V0LCB0YXJnZXQsCisgICAgICAgIHRhcmdldE9mZnNldCwgbnVtYmVyVG9Db3B5KTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIFNlcmlhbGl6YWJsZQorCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgIE9iamVjdCB3cml0ZVJlcGxhY2UoKSB7CisgICAgcmV0dXJuIG5ldyBMaXRlcmFsQnl0ZVN0cmluZyh0b0J5dGVBcnJheSgpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uKAorICAgICAgICAiQm91bmRlZEJ5dGVTdHJlYW0gaW5zdGFuY2VzIGFyZSBub3QgdG8gYmUgc2VyaWFsaXplZCBkaXJlY3RseSIpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gQnl0ZUl0ZXJhdG9yCisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBCeXRlSXRlcmF0b3IgaXRlcmF0b3IoKSB7CisgICAgcmV0dXJuIG5ldyBCb3VuZGVkQnl0ZUl0ZXJhdG9yKCk7CisgIH0KKworICBwcml2YXRlIGNsYXNzIEJvdW5kZWRCeXRlSXRlcmF0b3IgaW1wbGVtZW50cyBCeXRlSXRlcmF0b3IgeworCisgICAgcHJpdmF0ZSBpbnQgcG9zaXRpb247CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbGltaXQ7CisKKyAgICBwcml2YXRlIEJvdW5kZWRCeXRlSXRlcmF0b3IoKSB7CisgICAgICBwb3NpdGlvbiA9IGdldE9mZnNldEludG9CeXRlcygpOworICAgICAgbGltaXQgPSBwb3NpdGlvbiArIHNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgcmV0dXJuIChwb3NpdGlvbiA8IGxpbWl0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZSBuZXh0KCkgeworICAgICAgLy8gQm94aW5nIGNhbGxzIEJ5dGUudmFsdWVPZihieXRlKSwgd2hpY2ggZG9lcyBub3QgaW5zdGFudGlhdGUuCisgICAgICByZXR1cm4gbmV4dEJ5dGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZSBuZXh0Qnl0ZSgpIHsKKyAgICAgIGlmIChwb3NpdGlvbiA+PSBsaW1pdCkgeworICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgfQorICAgICAgcmV0dXJuIGJ5dGVzW3Bvc2l0aW9uKytdOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQnl0ZVN0cmluZy5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQnl0ZVN0cmluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliMGE1MjQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9CeXRlU3RyaW5nLmphdmEKQEAgLTAsMCArMSwxMDI2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCisvKioKKyAqIEltbXV0YWJsZSBzZXF1ZW5jZSBvZiBieXRlcy4gIFN1YnN0cmluZyBpcyBzdXBwb3J0ZWQgYnkgc2hhcmluZyB0aGUgcmVmZXJlbmNlCisgKiB0byB0aGUgaW1tdXRhYmxlIHVuZGVybHlpbmcgYnl0ZXMsIGFzIHdpdGgge0BsaW5rIFN0cmluZ30uICBDb25jYXRlbmF0aW9uIGlzCisgKiBsaWtld2lzZSBzdXBwb3J0ZWQgd2l0aG91dCBjb3B5aW5nIChsb25nIHN0cmluZ3MpIGJ5IGJ1aWxkaW5nIGEgdHJlZSBvZgorICogcGllY2VzIGluIHtAbGluayBSb3BlQnl0ZVN0cmluZ30uCisgKiA8cD4KKyAqIExpa2Uge0BsaW5rIFN0cmluZ30sIHRoZSBjb250ZW50cyBvZiBhIHtAbGluayBCeXRlU3RyaW5nfSBjYW4gbmV2ZXIgYmUKKyAqIG9ic2VydmVkIHRvIGNoYW5nZSwgbm90IGV2ZW4gaW4gdGhlIHByZXNlbmNlIG9mIGEgZGF0YSByYWNlIG9yIGluY29ycmVjdAorICogQVBJIHVzYWdlIGluIHRoZSBjbGllbnQgY29kZS4KKyAqCisgKiBAYXV0aG9yIGNyYXp5Ym9iQGdvb2dsZS5jb20gQm9iIExlZQorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqIEBhdXRob3IgY2FybGFudG9uQGdvb2dsZS5jb20gQ2FybCBIYXZlcmwKKyAqIEBhdXRob3IgbWFydGlucmJAZ29vZ2xlLmNvbSBNYXJ0aW4gQnVjaGhvbHoKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEJ5dGVTdHJpbmcgaW1wbGVtZW50cyBJdGVyYWJsZTxCeXRlPiwgU2VyaWFsaXphYmxlIHsKKworICAvKioKKyAgICogV2hlbiB0d28gc3RyaW5ncyB0byBiZSBjb25jYXRlbmF0ZWQgaGF2ZSBhIGNvbWJpbmVkIGxlbmd0aCBzaG9ydGVyIHRoYW4KKyAgICogdGhpcywgd2UganVzdCBjb3B5IHRoZWlyIGJ5dGVzIG9uIHtAbGluayAjY29uY2F0KEJ5dGVTdHJpbmcpfS4KKyAgICogVGhlIHRyYWRlLW9mZiBpcyBjb3B5IHNpemUgdmVyc3VzIHRoZSBvdmVyaGVhZCBvZiBjcmVhdGluZyB0cmVlIG5vZGVzCisgICAqIGluIHtAbGluayBSb3BlQnl0ZVN0cmluZ30uCisgICAqLworICBzdGF0aWMgZmluYWwgaW50IENPTkNBVEVOQVRFX0JZX0NPUFlfU0laRSA9IDEyODsKKworICAvKioKKyAgICogV2hlbiBjb3B5aW5nIGFuIElucHV0U3RyZWFtIGludG8gYSBCeXRlU3RyaW5nIHdpdGggLnJlYWRGcm9tKCksCisgICAqIHRoZSBjaHVua3MgaW4gdGhlIHVuZGVybHlpbmcgcm9wZSBzdGFydCBhdCAyNTYgYnl0ZXMsIGJ1dCBkb3VibGUKKyAgICogZWFjaCBpdGVyYXRpb24gdXAgdG8gODE5MiBieXRlcy4KKyAgICovCisgIHN0YXRpYyBmaW5hbCBpbnQgTUlOX1JFQURfRlJPTV9DSFVOS19TSVpFID0gMHgxMDA7ICAvLyAyNTZiCisgIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1JFQURfRlJPTV9DSFVOS19TSVpFID0gMHgyMDAwOyAgLy8gOGsKKworICAvLyBEZWZpbmVkIGJ5IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldAorICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBVVEZfOCA9ICJVVEYtOCI7CisKKyAgLyoqCisgICAqIEVtcHR5IHtAY29kZSBCeXRlU3RyaW5nfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgQnl0ZVN0cmluZyBFTVBUWSA9IG5ldyBMaXRlcmFsQnl0ZVN0cmluZyhuZXcgYnl0ZVswXSk7CisKKyAgLy8gVGhpcyBjb25zdHJ1Y3RvciBpcyBoZXJlIHRvIHByZXZlbnQgc3ViY2xhc3Npbmcgb3V0c2lkZSBvZiB0aGlzIHBhY2thZ2UsCisgIEJ5dGVTdHJpbmcoKSB7fQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleC4gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIHVzZWQgb25seSBmb3IKKyAgICogcmFuZG9tIGFjY2VzcyB0byBpbmRpdmlkdWFsIGJ5dGVzLiBUbyBhY2Nlc3MgYnl0ZXMgc2VxdWVudGlhbGx5LCB1c2UgdGhlCisgICAqIHtAbGluayBCeXRlSXRlcmF0b3J9IHJldHVybmVkIGJ5IHtAbGluayAjaXRlcmF0b3IoKX0sIGFuZCBjYWxsIHtAbGluaworICAgKiAjc3Vic3RyaW5nKGludCwgaW50KX0gZmlyc3QgaWYgbmVjZXNzYXJ5LgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgYnl0ZQorICAgKiBAcmV0dXJuIHRoZSB2YWx1ZQorICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7QGNvZGUgaW5kZXh9IGlzIDwgMCBvciA+PSBzaXplCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgYnl0ZSBieXRlQXQoaW50IGluZGV4KTsKKworICAvKioKKyAgICogUmV0dXJuIGEge0BsaW5rIEJ5dGVTdHJpbmcuQnl0ZUl0ZXJhdG9yfSBvdmVyIHRoZSBieXRlcyBpbiB0aGUgQnl0ZVN0cmluZy4KKyAgICogVG8gYXZvaWQgYXV0by1ib3hpbmcsIHlvdSBtYXkgZ2V0IHRoZSBpdGVyYXRvciBtYW51YWxseSBhbmQgY2FsbAorICAgKiB7QGxpbmsgQnl0ZUl0ZXJhdG9yI25leHRCeXRlKCl9LgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBpdGVyYXRvcgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IEJ5dGVJdGVyYXRvciBpdGVyYXRvcigpOworCisgIC8qKgorICAgKiBUaGlzIGludGVyZmFjZSBleHRlbmRzIHtAY29kZSBJdGVyYXRvcjxCeXRlPn0sIHNvIHRoYXQgd2UgY2FuIHJldHVybiBhbgorICAgKiB1bmJveGVkIHtAY29kZSBieXRlfS4KKyAgICovCisgIHB1YmxpYyBpbnRlcmZhY2UgQnl0ZUl0ZXJhdG9yIGV4dGVuZHMgSXRlcmF0b3I8Qnl0ZT4geworICAgIC8qKgorICAgICAqIEFuIGFsdGVybmF0aXZlIHRvIHtAbGluayBJdGVyYXRvciNuZXh0KCl9IHRoYXQgcmV0dXJucyBhbgorICAgICAqIHVuYm94ZWQgcHJpbWl0aXZlIHtAY29kZSBieXRlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQge0Bjb2RlIGJ5dGV9IGluIHRoZSBpdGVyYXRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWYgdGhlIGl0ZXJhdGlvbiBoYXMgbm8gbW9yZSBlbGVtZW50cworICAgICAqLworICAgIGJ5dGUgbmV4dEJ5dGUoKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYnl0ZXMuCisgICAqCisgICAqIEByZXR1cm4gc2l6ZSBpbiBieXRlcworICAgKi8KKyAgcHVibGljIGFic3RyYWN0IGludCBzaXplKCk7CisKKyAgLyoqCisgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBzaXplIGlzIHtAY29kZSAwfSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAqCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIHplcm8gYnl0ZXMgbG9uZworICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICByZXR1cm4gc2l6ZSgpID09IDA7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBCeXRlU3RyaW5nIC0+IHN1YnN0cmluZworCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIHN1YnN0cmluZyBmcm9tIHtAY29kZSBiZWdpbkluZGV4fSwgaW5jbHVzaXZlLCB0byB0aGUgZW5kIG9mIHRoZQorICAgKiBzdHJpbmcuCisgICAqCisgICAqIEBwYXJhbSBiZWdpbkluZGV4IHN0YXJ0IGF0IHRoaXMgaW5kZXgKKyAgICogQHJldHVybiBzdWJzdHJpbmcgc2hhcmluZyB1bmRlcmx5aW5nIGRhdGEKKyAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBiZWdpbkluZGV4IDwgMH0gb3IKKyAgICogICAgIHtAY29kZSBiZWdpbkluZGV4ID4gc2l6ZSgpfS4KKyAgICovCisgIHB1YmxpYyBCeXRlU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCkgeworICAgIHJldHVybiBzdWJzdHJpbmcoYmVnaW5JbmRleCwgc2l6ZSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIHN1YnN0cmluZyBmcm9tIHtAY29kZSBiZWdpbkluZGV4fSwgaW5jbHVzaXZlLCB0byB7QGNvZGUKKyAgICogZW5kSW5kZXh9LCBleGNsdXNpdmUuCisgICAqCisgICAqIEBwYXJhbSBiZWdpbkluZGV4IHN0YXJ0IGF0IHRoaXMgaW5kZXgKKyAgICogQHBhcmFtIGVuZEluZGV4ICAgdGhlIGxhc3QgY2hhcmFjdGVyIGlzIHRoZSBvbmUgYmVmb3JlIHRoaXMgaW5kZXgKKyAgICogQHJldHVybiBzdWJzdHJpbmcgc2hhcmluZyB1bmRlcmx5aW5nIGRhdGEKKyAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBiZWdpbkluZGV4IDwgMH0sCisgICAqICAgICB7QGNvZGUgZW5kSW5kZXggPiBzaXplKCl9LCBvciB7QGNvZGUgYmVnaW5JbmRleCA+IGVuZEluZGV4fS4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBCeXRlU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4KTsKKworICAvKioKKyAgICogVGVzdHMgaWYgdGhpcyBieXRlc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgorICAgKiBTaW1pbGFyIHRvIHtAbGluayBTdHJpbmcjc3RhcnRzV2l0aChTdHJpbmcpfQorICAgKgorICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXguCisgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGJ5dGUgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCisgICAqICAgICAgICAgYXJndW1lbnQgaXMgYSBwcmVmaXggb2YgdGhlIGJ5dGUgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKKyAgICogICAgICAgICB0aGlzIHN0cmluZzsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoQnl0ZVN0cmluZyBwcmVmaXgpIHsKKyAgICByZXR1cm4gc2l6ZSgpID49IHByZWZpeC5zaXplKCkgJiYKKyAgICAgICAgICAgc3Vic3RyaW5nKDAsIHByZWZpeC5zaXplKCkpLmVxdWFscyhwcmVmaXgpOworICB9CisKKyAgLyoqCisgICAqIFRlc3RzIGlmIHRoaXMgYnl0ZXN0cmluZyBlbmRzIHdpdGggdGhlIHNwZWNpZmllZCBzdWZmaXguCisgICAqIFNpbWlsYXIgdG8ge0BsaW5rIFN0cmluZyNlbmRzV2l0aChTdHJpbmcpfQorICAgKgorICAgKiBAcGFyYW0gc3VmZml4IHRoZSBzdWZmaXguCisgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGJ5dGUgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCisgICAqICAgICAgICAgYXJndW1lbnQgaXMgYSBzdWZmaXggb2YgdGhlIGJ5dGUgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKKyAgICogICAgICAgICB0aGlzIHN0cmluZzsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGVuZHNXaXRoKEJ5dGVTdHJpbmcgc3VmZml4KSB7CisgICAgcmV0dXJuIHNpemUoKSA+PSBzdWZmaXguc2l6ZSgpICYmCisgICAgICAgIHN1YnN0cmluZyhzaXplKCkgLSBzdWZmaXguc2l6ZSgpKS5lcXVhbHMoc3VmZml4KTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIGJ5dGVbXSAtPiBCeXRlU3RyaW5nCisKKyAgLyoqCisgICAqIENvcGllcyB0aGUgZ2l2ZW4gYnl0ZXMgaW50byBhIHtAY29kZSBCeXRlU3RyaW5nfS4KKyAgICoKKyAgICogQHBhcmFtIGJ5dGVzIHNvdXJjZSBhcnJheQorICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBpbiBzb3VyY2UgYXJyYXkKKyAgICogQHBhcmFtIHNpemUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNvcHkKKyAgICogQHJldHVybiBuZXcge0Bjb2RlIEJ5dGVTdHJpbmd9CisgICAqLworICBwdWJsaWMgc3RhdGljIEJ5dGVTdHJpbmcgY29weUZyb20oYnl0ZVtdIGJ5dGVzLCBpbnQgb2Zmc2V0LCBpbnQgc2l6ZSkgeworICAgIGJ5dGVbXSBjb3B5ID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgU3lzdGVtLmFycmF5Y29weShieXRlcywgb2Zmc2V0LCBjb3B5LCAwLCBzaXplKTsKKyAgICByZXR1cm4gbmV3IExpdGVyYWxCeXRlU3RyaW5nKGNvcHkpOworICB9CisKKyAgLyoqCisgICAqIENvcGllcyB0aGUgZ2l2ZW4gYnl0ZXMgaW50byBhIHtAY29kZSBCeXRlU3RyaW5nfS4KKyAgICoKKyAgICogQHBhcmFtIGJ5dGVzIHRvIGNvcHkKKyAgICogQHJldHVybiBuZXcge0Bjb2RlIEJ5dGVTdHJpbmd9CisgICAqLworICBwdWJsaWMgc3RhdGljIEJ5dGVTdHJpbmcgY29weUZyb20oYnl0ZVtdIGJ5dGVzKSB7CisgICAgcmV0dXJuIGNvcHlGcm9tKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpOworICB9CisKKyAgLyoqCisgICAqIENvcGllcyB0aGUgbmV4dCB7QGNvZGUgc2l6ZX0gYnl0ZXMgZnJvbSBhIHtAY29kZSBqYXZhLm5pby5CeXRlQnVmZmVyfSBpbnRvCisgICAqIGEge0Bjb2RlIEJ5dGVTdHJpbmd9LgorICAgKgorICAgKiBAcGFyYW0gYnl0ZXMgc291cmNlIGJ1ZmZlcgorICAgKiBAcGFyYW0gc2l6ZSBudW1iZXIgb2YgYnl0ZXMgdG8gY29weQorICAgKiBAcmV0dXJuIG5ldyB7QGNvZGUgQnl0ZVN0cmluZ30KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnl0ZVN0cmluZyBjb3B5RnJvbShCeXRlQnVmZmVyIGJ5dGVzLCBpbnQgc2l6ZSkgeworICAgIGJ5dGVbXSBjb3B5ID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgYnl0ZXMuZ2V0KGNvcHkpOworICAgIHJldHVybiBuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcoY29weSk7CisgIH0KKworICAvKioKKyAgICogQ29waWVzIHRoZSByZW1haW5pbmcgYnl0ZXMgZnJvbSBhIHtAY29kZSBqYXZhLm5pby5CeXRlQnVmZmVyfSBpbnRvCisgICAqIGEge0Bjb2RlIEJ5dGVTdHJpbmd9LgorICAgKgorICAgKiBAcGFyYW0gYnl0ZXMgc291cmNlQnVmZmVyCisgICAqIEByZXR1cm4gbmV3IHtAY29kZSBCeXRlU3RyaW5nfQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBCeXRlU3RyaW5nIGNvcHlGcm9tKEJ5dGVCdWZmZXIgYnl0ZXMpIHsKKyAgICByZXR1cm4gY29weUZyb20oYnl0ZXMsIGJ5dGVzLnJlbWFpbmluZygpKTsKKyAgfQorCisgIC8qKgorICAgKiBFbmNvZGVzIHtAY29kZSB0ZXh0fSBpbnRvIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgdXNpbmcgdGhlIG5hbWVkIGNoYXJzZXQKKyAgICogYW5kIHJldHVybnMgdGhlIHJlc3VsdCBhcyBhIHtAY29kZSBCeXRlU3RyaW5nfS4KKyAgICoKKyAgICogQHBhcmFtIHRleHQgc291cmNlIHN0cmluZworICAgKiBAcGFyYW0gY2hhcnNldE5hbWUgZW5jb2RpbmcgdG8gdXNlCisgICAqIEByZXR1cm4gbmV3IHtAY29kZSBCeXRlU3RyaW5nfQorICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gaWYgdGhlIGVuY29kaW5nIGlzbid0IGZvdW5kCisgICAqLworICBwdWJsaWMgc3RhdGljIEJ5dGVTdHJpbmcgY29weUZyb20oU3RyaW5nIHRleHQsIFN0cmluZyBjaGFyc2V0TmFtZSkKKyAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3IExpdGVyYWxCeXRlU3RyaW5nKHRleHQuZ2V0Qnl0ZXMoY2hhcnNldE5hbWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBFbmNvZGVzIHtAY29kZSB0ZXh0fSBpbnRvIGEgc2VxdWVuY2Ugb2YgVVRGLTggYnl0ZXMgYW5kIHJldHVybnMgdGhlCisgICAqIHJlc3VsdCBhcyBhIHtAY29kZSBCeXRlU3RyaW5nfS4KKyAgICoKKyAgICogQHBhcmFtIHRleHQgc291cmNlIHN0cmluZworICAgKiBAcmV0dXJuIG5ldyB7QGNvZGUgQnl0ZVN0cmluZ30KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnl0ZVN0cmluZyBjb3B5RnJvbVV0ZjgoU3RyaW5nIHRleHQpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsQnl0ZVN0cmluZyh0ZXh0LmdldEJ5dGVzKFVURl84KSk7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVVRGLTggbm90IHN1cHBvcnRlZD8iLCBlKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBJbnB1dFN0cmVhbSAtPiBCeXRlU3RyaW5nCisKKyAgLyoqCisgICAqIENvbXBsZXRlbHkgcmVhZHMgdGhlIGdpdmVuIHN0cmVhbSdzIGJ5dGVzIGludG8gYQorICAgKiB7QGNvZGUgQnl0ZVN0cmluZ30sIGJsb2NraW5nIGlmIG5lY2Vzc2FyeSB1bnRpbCBhbGwgYnl0ZXMgYXJlCisgICAqIHJlYWQgdGhyb3VnaCB0byB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uCisgICAqCisgICAqIDxiPlBlcmZvcm1hbmNlIG5vdGVzOjwvYj4gVGhlIHJldHVybmVkIHtAY29kZSBCeXRlU3RyaW5nfSBpcyBhbgorICAgKiBpbW11dGFibGUgdHJlZSBvZiBieXRlIGFycmF5cyAoImNodW5rcyIpIG9mIHRoZSBzdHJlYW0gZGF0YS4gIFRoZQorICAgKiBmaXJzdCBjaHVuayBpcyBzbWFsbCwgd2l0aCBzdWJzZXF1ZW50IGNodW5rcyBlYWNoIGJlaW5nIGRvdWJsZQorICAgKiB0aGUgc2l6ZSwgdXAgdG8gOEsuICBJZiB0aGUgY2FsbGVyIGtub3dzIHRoZSBwcmVjaXNlIGxlbmd0aCBvZgorICAgKiB0aGUgc3RyZWFtIGFuZCB3aXNoZXMgdG8gYXZvaWQgYWxsIHVubmVjZXNzYXJ5IGNvcGllcyBhbmQKKyAgICogYWxsb2NhdGlvbnMsIGNvbnNpZGVyIHVzaW5nIHRoZSB0d28tYXJndW1lbnQgdmVyc2lvbiBvZiB0aGlzCisgICAqIG1ldGhvZCwgYmVsb3cuCisgICAqCisgICAqIEBwYXJhbSBzdHJlYW1Ub0RyYWluIFRoZSBzb3VyY2Ugc3RyZWFtLCB3aGljaCBpcyByZWFkIGNvbXBsZXRlbHkKKyAgICogICAgIGJ1dCBub3QgY2xvc2VkLgorICAgKiBAcmV0dXJuIEEgbmV3IHtAY29kZSBCeXRlU3RyaW5nfSB3aGljaCBpcyBtYWRlIHVwIG9mIGNodW5rcyBvZgorICAgKiAgICAgdmFyaW91cyBzaXplcywgZGVwZW5kaW5nIG9uIHRoZSBiZWhhdmlvciBvZiB0aGUgdW5kZXJseWluZworICAgKiAgICAgc3RyZWFtLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElPRXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZSBpcyBhIHByb2JsZW0KKyAgICogICAgIHJlYWRpbmcgdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBCeXRlU3RyaW5nIHJlYWRGcm9tKElucHV0U3RyZWFtIHN0cmVhbVRvRHJhaW4pCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkRnJvbSgKKyAgICAgICAgc3RyZWFtVG9EcmFpbiwgTUlOX1JFQURfRlJPTV9DSFVOS19TSVpFLCBNQVhfUkVBRF9GUk9NX0NIVU5LX1NJWkUpOworICB9CisKKyAgLyoqCisgICAqIENvbXBsZXRlbHkgcmVhZHMgdGhlIGdpdmVuIHN0cmVhbSdzIGJ5dGVzIGludG8gYQorICAgKiB7QGNvZGUgQnl0ZVN0cmluZ30sIGJsb2NraW5nIGlmIG5lY2Vzc2FyeSB1bnRpbCBhbGwgYnl0ZXMgYXJlCisgICAqIHJlYWQgdGhyb3VnaCB0byB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uCisgICAqCisgICAqIDxiPlBlcmZvcm1hbmNlIG5vdGVzOjwvYj4gVGhlIHJldHVybmVkIHtAY29kZSBCeXRlU3RyaW5nfSBpcyBhbgorICAgKiBpbW11dGFibGUgdHJlZSBvZiBieXRlIGFycmF5cyAoImNodW5rcyIpIG9mIHRoZSBzdHJlYW0gZGF0YS4gIFRoZQorICAgKiBjaHVua1NpemUgcGFyYW1ldGVyIHNldHMgdGhlIHNpemUgb2YgdGhlc2UgYnl0ZSBhcnJheXMuIEluCisgICAqIHBhcnRpY3VsYXIsIGlmIHRoZSBjaHVua1NpemUgaXMgcHJlY2lzZWx5IHRoZSBzYW1lIGFzIHRoZSBsZW5ndGgKKyAgICogb2YgdGhlIHN0cmVhbSwgdW5uZWNlc3NhcnkgYWxsb2NhdGlvbnMgYW5kIGNvcGllcyB3aWxsIGJlCisgICAqIGF2b2lkZWQuIE90aGVyd2lzZSwgdGhlIGNodW5rcyB3aWxsIGJlIG9mIHRoZSBnaXZlbiBzaXplLCBleGNlcHQKKyAgICogZm9yIHRoZSBsYXN0IGNodW5rLCB3aGljaCB3aWxsIGJlIHJlc2l6ZWQgKHZpYSBhIHJlYWxsb2NhdGlvbiBhbmQKKyAgICogY29weSkgdG8gY29udGFpbiB0aGUgcmVtYWluZGVyIG9mIHRoZSBzdHJlYW0uCisgICAqCisgICAqIEBwYXJhbSBzdHJlYW1Ub0RyYWluIFRoZSBzb3VyY2Ugc3RyZWFtLCB3aGljaCBpcyByZWFkIGNvbXBsZXRlbHkKKyAgICogICAgIGJ1dCBub3QgY2xvc2VkLgorICAgKiBAcGFyYW0gY2h1bmtTaXplIFRoZSBzaXplIG9mIHRoZSBjaHVua3MgaW4gd2hpY2ggdG8gcmVhZCB0aGUKKyAgICogICAgIHN0cmVhbS4KKyAgICogQHJldHVybiBBIG5ldyB7QGNvZGUgQnl0ZVN0cmluZ30gd2hpY2ggaXMgbWFkZSB1cCBvZiBjaHVua3Mgb2YKKyAgICogICAgIHRoZSBnaXZlbiBzaXplLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElPRXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZSBpcyBhIHByb2JsZW0KKyAgICogICAgIHJlYWRpbmcgdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBCeXRlU3RyaW5nIHJlYWRGcm9tKElucHV0U3RyZWFtIHN0cmVhbVRvRHJhaW4sIGludCBjaHVua1NpemUpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkRnJvbShzdHJlYW1Ub0RyYWluLCBjaHVua1NpemUsIGNodW5rU2l6ZSk7CisgIH0KKworICAvLyBIZWxwZXIgbWV0aG9kIHRoYXQgdGFrZXMgdGhlIGNodW5rIHNpemUgcmFuZ2UgYXMgYSBwYXJhbWV0ZXIuCisgIHB1YmxpYyBzdGF0aWMgQnl0ZVN0cmluZyByZWFkRnJvbShJbnB1dFN0cmVhbSBzdHJlYW1Ub0RyYWluLCBpbnQgbWluQ2h1bmtTaXplLAorICAgICAgaW50IG1heENodW5rU2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDb2xsZWN0aW9uPEJ5dGVTdHJpbmc+IHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PEJ5dGVTdHJpbmc+KCk7CisKKyAgICAvLyBjb3B5IHRoZSBpbmJvdW5kIGJ5dGVzIGludG8gYSBsaXN0IG9mIGNodW5rczsgdGhlIGNodW5rIHNpemUKKyAgICAvLyBncm93cyBleHBvbmVudGlhbGx5IHRvIHN1cHBvcnQgYm90aCBzaG9ydCBhbmQgbG9uZyBzdHJlYW1zLgorICAgIGludCBjaHVua1NpemUgPSBtaW5DaHVua1NpemU7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIEJ5dGVTdHJpbmcgY2h1bmsgPSByZWFkQ2h1bmsoc3RyZWFtVG9EcmFpbiwgY2h1bmtTaXplKTsKKyAgICAgIGlmIChjaHVuayA9PSBudWxsKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgcmVzdWx0cy5hZGQoY2h1bmspOworICAgICAgY2h1bmtTaXplID0gTWF0aC5taW4oY2h1bmtTaXplICogMiwgbWF4Q2h1bmtTaXplKTsKKyAgICB9CisKKyAgICByZXR1cm4gQnl0ZVN0cmluZy5jb3B5RnJvbShyZXN1bHRzKTsKKyAgfQorCisgIC8qKgorICAgKiBCbG9ja3MgdW50aWwgYSBjaHVuayBvZiB0aGUgZ2l2ZW4gc2l6ZSBjYW4gYmUgbWFkZSBmcm9tIHRoZQorICAgKiBzdHJlYW0sIG9yIEVPRiBpcyByZWFjaGVkLiAgQ2FsbHMgcmVhZCgpIHJlcGVhdGVkbHkgaW4gY2FzZSB0aGUKKyAgICogZ2l2ZW4gc3RyZWFtIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgY29tcGxldGVseSBmaWxsIHRoZSBnaXZlbgorICAgKiBidWZmZXIgaW4gb25lIHJlYWQoKSBjYWxsLgorICAgKgorICAgKiBAcmV0dXJuIEEgY2h1bmsgb2YgdGhlIGRlc2lyZWQgc2l6ZSwgb3IgZWxzZSBhIGNodW5rIGFzIGxhcmdlIGFzCisgICAqIHdhcyBhdmFpbGFibGUgd2hlbiBlbmQgb2Ygc3RyZWFtIHdhcyByZWFjaGVkLiBSZXR1cm5zIG51bGwgaWYgdGhlCisgICAqIGdpdmVuIHN0cmVhbSBoYWQgbm8gbW9yZSBkYXRhIGluIGl0LgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgQnl0ZVN0cmluZyByZWFkQ2h1bmsoSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGludCBjaHVua1NpemUpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW2NodW5rU2l6ZV07CisgICAgICBpbnQgYnl0ZXNSZWFkID0gMDsKKyAgICAgIHdoaWxlIChieXRlc1JlYWQgPCBjaHVua1NpemUpIHsKKyAgICAgICAgZmluYWwgaW50IGNvdW50ID0gaW4ucmVhZChidWYsIGJ5dGVzUmVhZCwgY2h1bmtTaXplIC0gYnl0ZXNSZWFkKTsKKyAgICAgICAgaWYgKGNvdW50ID09IC0xKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZXNSZWFkICs9IGNvdW50OworICAgICAgfQorCisgICAgICBpZiAoYnl0ZXNSZWFkID09IDApIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQnl0ZVN0cmluZy5jb3B5RnJvbShidWYsIDAsIGJ5dGVzUmVhZCk7CisgICAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBNdWx0aXBsZSBCeXRlU3RyaW5ncyAtPiBPbmUgQnl0ZVN0cmluZworCisgIC8qKgorICAgKiBDb25jYXRlbmF0ZSB0aGUgZ2l2ZW4ge0Bjb2RlIEJ5dGVTdHJpbmd9IHRvIHRoaXMgb25lLiBTaG9ydCBjb25jYXRlbmF0aW9ucywKKyAgICogb2YgdG90YWwgc2l6ZSBzbWFsbGVyIHRoYW4ge0BsaW5rIEJ5dGVTdHJpbmcjQ09OQ0FURU5BVEVfQllfQ09QWV9TSVpFfSwgYXJlCisgICAqIHByb2R1Y2VkIGJ5IGNvcHlpbmcgdGhlIHVuZGVybHlpbmcgYnl0ZXMgKGFzIHBlciBSb3BlLmphdmEsIDxhCisgICAqIGhyZWY9Imh0dHA6Ly93d3cuY3MudWJjLmNhL2xvY2FsL3JlYWRpbmcvcHJvY2VlZGluZ3Mvc3BlOTEtOTUvc3BlL3ZvbDI1L2lzc3VlMTIvc3BlOTg2LnBkZiI+CisgICAqIEJBUDk1IDwvYT4uIEluIGdlbmVyYWwsIHRoZSBjb25jYXRlbmF0ZSBpbnZvbHZlcyBubyBjb3B5aW5nLgorICAgKgorICAgKiBAcGFyYW0gb3RoZXIgc3RyaW5nIHRvIGNvbmNhdGVuYXRlCisgICAqIEByZXR1cm4gYSBuZXcge0Bjb2RlIEJ5dGVTdHJpbmd9IGluc3RhbmNlCisgICAqLworICBwdWJsaWMgQnl0ZVN0cmluZyBjb25jYXQoQnl0ZVN0cmluZyBvdGhlcikgeworICAgIGludCB0aGlzU2l6ZSA9IHNpemUoKTsKKyAgICBpbnQgb3RoZXJTaXplID0gb3RoZXIuc2l6ZSgpOworICAgIGlmICgobG9uZykgdGhpc1NpemUgKyBvdGhlclNpemUgPj0gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJ5dGVTdHJpbmcgd291bGQgYmUgdG9vIGxvbmc6ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzU2l6ZSArICIrIiArIG90aGVyU2l6ZSk7CisgICAgfQorCisgICAgcmV0dXJuIFJvcGVCeXRlU3RyaW5nLmNvbmNhdGVuYXRlKHRoaXMsIG90aGVyKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25jYXRlbmF0ZXMgYWxsIGJ5dGUgc3RyaW5ncyBpbiB0aGUgaXRlcmFibGUgYW5kIHJldHVybnMgdGhlIHJlc3VsdC4KKyAgICogVGhpcyBpcyBkZXNpZ25lZCB0byBydW4gaW4gTyhsaXN0IHNpemUpLCBub3QgTyh0b3RhbCBieXRlcykuCisgICAqCisgICAqIDxwPlRoZSByZXR1cm5lZCB7QGNvZGUgQnl0ZVN0cmluZ30gaXMgbm90IG5lY2Vzc2FyaWx5IGEgdW5pcXVlIG9iamVjdC4KKyAgICogSWYgdGhlIGxpc3QgaXMgZW1wdHksIHRoZSByZXR1cm5lZCBvYmplY3QgaXMgdGhlIHNpbmdsZXRvbiBlbXB0eQorICAgKiB7QGNvZGUgQnl0ZVN0cmluZ30uICBJZiB0aGUgbGlzdCBoYXMgb25seSBvbmUgZWxlbWVudCwgdGhhdAorICAgKiB7QGNvZGUgQnl0ZVN0cmluZ30gd2lsbCBiZSByZXR1cm5lZCB3aXRob3V0IGNvcHlpbmcuCisgICAqCisgICAqIEBwYXJhbSBieXRlU3RyaW5ncyBzdHJpbmdzIHRvIGJlIGNvbmNhdGVuYXRlZAorICAgKiBAcmV0dXJuIG5ldyB7QGNvZGUgQnl0ZVN0cmluZ30KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnl0ZVN0cmluZyBjb3B5RnJvbShJdGVyYWJsZTxCeXRlU3RyaW5nPiBieXRlU3RyaW5ncykgeworICAgIENvbGxlY3Rpb248Qnl0ZVN0cmluZz4gY29sbGVjdGlvbjsKKyAgICBpZiAoIShieXRlU3RyaW5ncyBpbnN0YW5jZW9mIENvbGxlY3Rpb24pKSB7CisgICAgICBjb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdDxCeXRlU3RyaW5nPigpOworICAgICAgZm9yIChCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgOiBieXRlU3RyaW5ncykgeworICAgICAgICBjb2xsZWN0aW9uLmFkZChieXRlU3RyaW5nKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgY29sbGVjdGlvbiA9IChDb2xsZWN0aW9uPEJ5dGVTdHJpbmc+KSBieXRlU3RyaW5nczsKKyAgICB9CisgICAgQnl0ZVN0cmluZyByZXN1bHQ7CisgICAgaWYgKGNvbGxlY3Rpb24uaXNFbXB0eSgpKSB7CisgICAgICByZXN1bHQgPSBFTVBUWTsKKyAgICB9IGVsc2UgeworICAgICAgcmVzdWx0ID0gYmFsYW5jZWRDb25jYXQoY29sbGVjdGlvbi5pdGVyYXRvcigpLCBjb2xsZWN0aW9uLnNpemUoKSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvLyBJbnRlcm5hbCBmdW5jdGlvbiB1c2VkIGJ5IGNvcHlGcm9tKEl0ZXJhYmxlPEJ5dGVTdHJpbmc+KS4KKyAgLy8gQ3JlYXRlIGEgYmFsYW5jZWQgY29uY2F0ZW5hdGlvbiBvZiB0aGUgbmV4dCAibGVuZ3RoIiBlbGVtZW50cyBmcm9tIHRoZQorICAvLyBpdGVyYWJsZS4KKyAgcHJpdmF0ZSBzdGF0aWMgQnl0ZVN0cmluZyBiYWxhbmNlZENvbmNhdChJdGVyYXRvcjxCeXRlU3RyaW5nPiBpdGVyYXRvciwKKyAgICAgIGludCBsZW5ndGgpIHsKKyAgICBhc3NlcnQgbGVuZ3RoID49IDE7CisgICAgQnl0ZVN0cmluZyByZXN1bHQ7CisgICAgaWYgKGxlbmd0aCA9PSAxKSB7CisgICAgICByZXN1bHQgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGludCBoYWxmTGVuZ3RoID0gbGVuZ3RoID4+PiAxOworICAgICAgQnl0ZVN0cmluZyBsZWZ0ID0gYmFsYW5jZWRDb25jYXQoaXRlcmF0b3IsIGhhbGZMZW5ndGgpOworICAgICAgQnl0ZVN0cmluZyByaWdodCA9IGJhbGFuY2VkQ29uY2F0KGl0ZXJhdG9yLCBsZW5ndGggLSBoYWxmTGVuZ3RoKTsKKyAgICAgIHJlc3VsdCA9IGxlZnQuY29uY2F0KHJpZ2h0KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIEJ5dGVTdHJpbmcgLT4gYnl0ZVtdCisKKyAgLyoqCisgICAqIENvcGllcyBieXRlcyBpbnRvIGEgYnVmZmVyIGF0IHRoZSBnaXZlbiBvZmZzZXQuCisgICAqCisgICAqIEBwYXJhbSB0YXJnZXQgYnVmZmVyIHRvIGNvcHkgaW50bworICAgKiBAcGFyYW0gb2Zmc2V0IGluIHRoZSB0YXJnZXQgYnVmZmVyCisgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgb2Zmc2V0IGlzIG5lZ2F0aXZlIG9yIHRvbyBsYXJnZQorICAgKi8KKyAgcHVibGljIHZvaWQgY29weVRvKGJ5dGVbXSB0YXJnZXQsIGludCBvZmZzZXQpIHsKKyAgICBjb3B5VG8odGFyZ2V0LCAwLCBvZmZzZXQsIHNpemUoKSk7CisgIH0KKworICAvKioKKyAgICogQ29waWVzIGJ5dGVzIGludG8gYSBidWZmZXIuCisgICAqCisgICAqIEBwYXJhbSB0YXJnZXQgICAgICAgYnVmZmVyIHRvIGNvcHkgaW50bworICAgKiBAcGFyYW0gc291cmNlT2Zmc2V0IG9mZnNldCB3aXRoaW4gdGhlc2UgYnl0ZXMKKyAgICogQHBhcmFtIHRhcmdldE9mZnNldCBvZmZzZXQgd2l0aGluIHRoZSB0YXJnZXQgYnVmZmVyCisgICAqIEBwYXJhbSBudW1iZXJUb0NvcHkgbnVtYmVyIG9mIGJ5dGVzIHRvIGNvcHkKKyAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIGFuIG9mZnNldCBvciBzaXplIGlzIG5lZ2F0aXZlIG9yIHRvbworICAgKiAgICAgbGFyZ2UKKyAgICovCisgIHB1YmxpYyB2b2lkIGNvcHlUbyhieXRlW10gdGFyZ2V0LCBpbnQgc291cmNlT2Zmc2V0LCBpbnQgdGFyZ2V0T2Zmc2V0LAorICAgICAgaW50IG51bWJlclRvQ29weSkgeworICAgIGlmIChzb3VyY2VPZmZzZXQgPCAwKSB7CisgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiU291cmNlIG9mZnNldCA8IDA6ICIgKyBzb3VyY2VPZmZzZXQpOworICAgIH0KKyAgICBpZiAodGFyZ2V0T2Zmc2V0IDwgMCkgeworICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIlRhcmdldCBvZmZzZXQgPCAwOiAiICsgdGFyZ2V0T2Zmc2V0KTsKKyAgICB9CisgICAgaWYgKG51bWJlclRvQ29weSA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJMZW5ndGggPCAwOiAiICsgbnVtYmVyVG9Db3B5KTsKKyAgICB9CisgICAgaWYgKHNvdXJjZU9mZnNldCArIG51bWJlclRvQ29weSA+IHNpemUoKSkgeworICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oCisgICAgICAgICAgIlNvdXJjZSBlbmQgb2Zmc2V0IDwgMDogIiArIChzb3VyY2VPZmZzZXQgKyBudW1iZXJUb0NvcHkpKTsKKyAgICB9CisgICAgaWYgKHRhcmdldE9mZnNldCArIG51bWJlclRvQ29weSA+IHRhcmdldC5sZW5ndGgpIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKAorICAgICAgICAgICJUYXJnZXQgZW5kIG9mZnNldCA8IDA6ICIgKyAodGFyZ2V0T2Zmc2V0ICsgbnVtYmVyVG9Db3B5KSk7CisgICAgfQorICAgIGlmIChudW1iZXJUb0NvcHkgPiAwKSB7CisgICAgICBjb3B5VG9JbnRlcm5hbCh0YXJnZXQsIHNvdXJjZU9mZnNldCwgdGFyZ2V0T2Zmc2V0LCBudW1iZXJUb0NvcHkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBJbnRlcm5hbCAocGFja2FnZSBwcml2YXRlKSBpbXBsZW1lbnRhdGlvbiBvZgorICAgKiB7QGxpbmsgI2NvcHlUbyhieXRlW10saW50LGludCxpbnQpfS4KKyAgICogSXQgYXNzdW1lcyB0aGF0IGFsbCBlcnJvciBjaGVja2luZyBoYXMgYWxyZWFkeSBiZWVuIHBlcmZvcm1lZCBhbmQgdGhhdCAKKyAgICoge0Bjb2RlIG51bWJlclRvQ29weSA+IDB9LgorICAgKi8KKyAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgY29weVRvSW50ZXJuYWwoYnl0ZVtdIHRhcmdldCwgaW50IHNvdXJjZU9mZnNldCwKKyAgICAgIGludCB0YXJnZXRPZmZzZXQsIGludCBudW1iZXJUb0NvcHkpOworCisgIC8qKgorICAgKiBDb3BpZXMgYnl0ZXMgaW50byBhIEJ5dGVCdWZmZXIuCisgICAqCisgICAqIEBwYXJhbSB0YXJnZXQgQnl0ZUJ1ZmZlciB0byBjb3B5IGludG8uCisgICAqIEB0aHJvd3MgamF2YS5uaW8uUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gaWYgdGhlIHtAY29kZSB0YXJnZXR9IGlzIHJlYWQtb25seQorICAgKiBAdGhyb3dzIGphdmEubmlvLkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGlmIHRoZSB7QGNvZGUgdGFyZ2V0fSdzCisgICAqICAgICByZW1haW5pbmcoKSBzcGFjZSBpcyBub3QgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgdGhlIGRhdGEuCisgICAqLworICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjb3B5VG8oQnl0ZUJ1ZmZlciB0YXJnZXQpOworCisgIC8qKgorICAgKiBDb3BpZXMgYnl0ZXMgdG8gYSB7QGNvZGUgYnl0ZVtdfS4KKyAgICoKKyAgICogQHJldHVybiBjb3BpZWQgYnl0ZXMKKyAgICovCisgIHB1YmxpYyBieXRlW10gdG9CeXRlQXJyYXkoKSB7CisgICAgaW50IHNpemUgPSBzaXplKCk7CisgICAgaWYgKHNpemUgPT0gMCkgeworICAgICAgcmV0dXJuIEludGVybmFsLkVNUFRZX0JZVEVfQVJSQVk7CisgICAgfQorICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICBjb3B5VG9JbnRlcm5hbChyZXN1bHQsIDAsIDAsIHNpemUpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogV3JpdGVzIHRoZSBjb21wbGV0ZSBjb250ZW50cyBvZiB0aGlzIGJ5dGUgc3RyaW5nIHRvCisgICAqIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbSBhcmd1bWVudC4KKyAgICoKKyAgICogQHBhcmFtICBvdXQgIHRoZSBvdXRwdXQgc3RyZWFtIHRvIHdoaWNoIHRvIHdyaXRlIHRoZSBkYXRhLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogV3JpdGVzIGEgc3BlY2lmaWVkIHBhcnQgb2YgdGhpcyBieXRlIHN0cmluZyB0byBhbiBvdXRwdXQgc3RyZWFtLgorICAgKgorICAgKiBAcGFyYW0gIG91dCAgdGhlIG91dHB1dCBzdHJlYW0gdG8gd2hpY2ggdG8gd3JpdGUgdGhlIGRhdGEuCisgICAqIEBwYXJhbSAgc291cmNlT2Zmc2V0IG9mZnNldCB3aXRoaW4gdGhlc2UgYnl0ZXMKKyAgICogQHBhcmFtICBudW1iZXJUb1dyaXRlIG51bWJlciBvZiBieXRlcyB0byB3cml0ZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgYW4gb2Zmc2V0IG9yIHNpemUgaXMgbmVnYXRpdmUgb3IgdG9vCisgICAqICAgICBsYXJnZQorICAgKi8KKyAgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvdXQsIGludCBzb3VyY2VPZmZzZXQsIGludCBudW1iZXJUb1dyaXRlKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc291cmNlT2Zmc2V0IDwgMCkgeworICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIlNvdXJjZSBvZmZzZXQgPCAwOiAiICsgc291cmNlT2Zmc2V0KTsKKyAgICB9CisgICAgaWYgKG51bWJlclRvV3JpdGUgPCAwKSB7CisgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiTGVuZ3RoIDwgMDogIiArIG51bWJlclRvV3JpdGUpOworICAgIH0KKyAgICBpZiAoc291cmNlT2Zmc2V0ICsgbnVtYmVyVG9Xcml0ZSA+IHNpemUoKSkgeworICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oCisgICAgICAgICAgIlNvdXJjZSBlbmQgb2Zmc2V0IGV4Y2VlZGVkOiAiICsgKHNvdXJjZU9mZnNldCArIG51bWJlclRvV3JpdGUpKTsKKyAgICB9CisgICAgaWYgKG51bWJlclRvV3JpdGUgPiAwKSB7CisgICAgICB3cml0ZVRvSW50ZXJuYWwob3V0LCBzb3VyY2VPZmZzZXQsIG51bWJlclRvV3JpdGUpOworICAgIH0KKyAgICAKKyAgfQorCisgIC8qKgorICAgKiBJbnRlcm5hbCB2ZXJzaW9uIG9mIHtAbGluayAjd3JpdGVUbyhPdXRwdXRTdHJlYW0saW50LGludCl9IHRoYXQgYXNzdW1lcworICAgKiBhbGwgZXJyb3IgY2hlY2tpbmcgaGFzIGFscmVhZHkgYmVlbiBkb25lLgorICAgKi8KKyAgYWJzdHJhY3Qgdm9pZCB3cml0ZVRvSW50ZXJuYWwoT3V0cHV0U3RyZWFtIG91dCwgaW50IHNvdXJjZU9mZnNldCwKKyAgICAgIGludCBudW1iZXJUb1dyaXRlKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSByZWFkLW9ubHkge0Bjb2RlIGphdmEubmlvLkJ5dGVCdWZmZXJ9IHdob3NlIGNvbnRlbnQKKyAgICogaXMgZXF1YWwgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnl0ZSBzdHJpbmcuCisgICAqIFRoZSByZXN1bHQgdXNlcyB0aGUgc2FtZSBiYWNraW5nIGFycmF5IGFzIHRoZSBieXRlIHN0cmluZywgaWYgcG9zc2libGUuCisgICAqCisgICAqIEByZXR1cm4gd3JhcHBlZCBieXRlcworICAgKi8KKyAgcHVibGljIGFic3RyYWN0IEJ5dGVCdWZmZXIgYXNSZWFkT25seUJ5dGVCdWZmZXIoKTsKKworICAvKioKKyAgICogQ29uc3RydWN0cyBhIGxpc3Qgb2YgcmVhZC1vbmx5IHtAY29kZSBqYXZhLm5pby5CeXRlQnVmZmVyfSBvYmplY3RzCisgICAqIHN1Y2ggdGhhdCB0aGUgY29uY2F0ZW5hdGlvbiBvZiB0aGVpciBjb250ZW50cyBpcyBlcXVhbCB0byB0aGUgY29udGVudHMKKyAgICogb2YgdGhpcyBieXRlIHN0cmluZy4gIFRoZSByZXN1bHQgdXNlcyB0aGUgc2FtZSBiYWNraW5nIGFycmF5cyBhcyB0aGUKKyAgICogYnl0ZSBzdHJpbmcuCisgICAqIDxwPgorICAgKiBCeSByZXR1cm5pbmcgYSBsaXN0LCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2QgbWF5IGJlIGFibGUgdG8gYXZvaWQKKyAgICogY29weWluZyBldmVuIHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGJhY2tpbmcgYXJyYXlzLgorICAgKiAKKyAgICogQHJldHVybiBhIGxpc3Qgb2Ygd3JhcHBlZCBieXRlcworICAgKi8KKyAgcHVibGljIGFic3RyYWN0IExpc3Q8Qnl0ZUJ1ZmZlcj4gYXNSZWFkT25seUJ5dGVCdWZmZXJMaXN0KCk7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmluZ30gYnkgZGVjb2RpbmcgdGhlIGJ5dGVzIHVzaW5nIHRoZQorICAgKiBzcGVjaWZpZWQgY2hhcnNldC4KKyAgICoKKyAgICogQHBhcmFtIGNoYXJzZXROYW1lIGVuY29kZSB1c2luZyB0aGlzIGNoYXJzZXQKKyAgICogQHJldHVybiBuZXcgc3RyaW5nCisgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiBjaGFyc2V0IGlzbid0IHJlY29nbml6ZWQKKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdG9TdHJpbmcoU3RyaW5nIGNoYXJzZXROYW1lKQorICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gVVRGLTggZGVjb2RpbmcKKworICAvKioKKyAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU3RyaW5nfSBieSBkZWNvZGluZyB0aGUgYnl0ZXMgYXMgVVRGLTguCisgICAqCisgICAqIEByZXR1cm4gbmV3IHN0cmluZyB1c2luZyBVVEYtOCBlbmNvZGluZworICAgKi8KKyAgcHVibGljIFN0cmluZyB0b1N0cmluZ1V0ZjgoKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiB0b1N0cmluZyhVVEZfOCk7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVVRGLTggbm90IHN1cHBvcnRlZD8iLCBlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogVGVsbHMgd2hldGhlciB0aGlzIHtAY29kZSBCeXRlU3RyaW5nfSByZXByZXNlbnRzIGEgd2VsbC1mb3JtZWQgVVRGLTgKKyAgICogYnl0ZSBzZXF1ZW5jZSwgc3VjaCB0aGF0IHRoZSBvcmlnaW5hbCBieXRlcyBjYW4gYmUgY29udmVydGVkIHRvIGEKKyAgICogU3RyaW5nIG9iamVjdCBhbmQgdGhlbiByb3VuZCB0cmlwcGVkIGJhY2sgdG8gYnl0ZXMgd2l0aG91dCBsb3NzLgorICAgKgorICAgKiA8cD5Nb3JlIHByZWNpc2VseSwgcmV0dXJucyB7QGNvZGUgdHJ1ZX0gd2hlbmV2ZXI6IDxwcmU+IHtAY29kZQorICAgKiBBcnJheXMuZXF1YWxzKGJ5dGVTdHJpbmcudG9CeXRlQXJyYXkoKSwKKyAgICogICAgIG5ldyBTdHJpbmcoYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCAiVVRGLTgiKS5nZXRCeXRlcygiVVRGLTgiKSkKKyAgICogfTwvcHJlPgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCByZXR1cm5zIHtAY29kZSBmYWxzZX0gZm9yICJvdmVybG9uZyIgYnl0ZSBzZXF1ZW5jZXMsCisgICAqIGFzIHdlbGwgYXMgZm9yIDMtYnl0ZSBzZXF1ZW5jZXMgdGhhdCB3b3VsZCBtYXAgdG8gYSBzdXJyb2dhdGUKKyAgICogY2hhcmFjdGVyLCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIHJlc3RyaWN0ZWQgZGVmaW5pdGlvbiBvZiBVVEYtOAorICAgKiBpbnRyb2R1Y2VkIGluIFVuaWNvZGUgMy4xLiAgTm90ZSB0aGF0IHRoZSBVVEYtOCBkZWNvZGVyIGluY2x1ZGVkIGluCisgICAqIE9yYWNsZSdzIEpESyBoYXMgYmVlbiBtb2RpZmllZCB0byBhbHNvIHJlamVjdCAib3ZlcmxvbmciIGJ5dGUKKyAgICogc2VxdWVuY2VzLCBidXQgKGFzIG9mIDIwMTEpIHN0aWxsIGFjY2VwdHMgMy1ieXRlIHN1cnJvZ2F0ZQorICAgKiBjaGFyYWN0ZXIgYnl0ZSBzZXF1ZW5jZXMuCisgICAqCisgICAqIDxwPlNlZSB0aGUgVW5pY29kZSBTdGFuZGFyZCw8L2JyPgorICAgKiBUYWJsZSAzLTYuIDxlbT5VVEYtOCBCaXQgRGlzdHJpYnV0aW9uPC9lbT4sPC9icj4KKyAgICogVGFibGUgMy03LiA8ZW0+V2VsbCBGb3JtZWQgVVRGLTggQnl0ZSBTZXF1ZW5jZXM8L2VtPi4KKyAgICoKKyAgICogQHJldHVybiB3aGV0aGVyIHRoZSBieXRlcyBpbiB0aGlzIHtAY29kZSBCeXRlU3RyaW5nfSBhcmUgYQorICAgKiB3ZWxsLWZvcm1lZCBVVEYtOCBieXRlIHNlcXVlbmNlCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1ZhbGlkVXRmOCgpOworCisgIC8qKgorICAgKiBUZWxscyB3aGV0aGVyIHRoZSBnaXZlbiBieXRlIHNlcXVlbmNlIGlzIGEgd2VsbC1mb3JtZWQsIG1hbGZvcm1lZCwgb3IKKyAgICogaW5jb21wbGV0ZSBVVEYtOCBieXRlIHNlcXVlbmNlLiAgVGhpcyBtZXRob2QgYWNjZXB0cyBhbmQgcmV0dXJucyBhIHBhcnRpYWwKKyAgICogc3RhdGUgcmVzdWx0LCBhbGxvd2luZyB0aGUgYnl0ZXMgZm9yIGEgY29tcGxldGUgVVRGLTggYnl0ZSBzZXF1ZW5jZSB0byBiZQorICAgKiBjb21wb3NlZCBmcm9tIG11bHRpcGxlIHtAY29kZSBCeXRlU3RyaW5nfSBzZWdtZW50cy4KKyAgICoKKyAgICogQHBhcmFtIHN0YXRlIGVpdGhlciB7QGNvZGUgMH0gKGlmIHRoaXMgaXMgdGhlIGluaXRpYWwgZGVjb2Rpbmcgb3BlcmF0aW9uKQorICAgKiAgICAgb3IgdGhlIHZhbHVlIHJldHVybmVkIGZyb20gYSBjYWxsIHRvIGEgcGFydGlhbCBkZWNvZGluZyBtZXRob2QgZm9yIHRoZQorICAgKiAgICAgcHJldmlvdXMgYnl0ZXMKKyAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgb2YgdGhlIGZpcnN0IGJ5dGUgdG8gY2hlY2sKKyAgICogQHBhcmFtIGxlbmd0aCBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICoKKyAgICogQHJldHVybiB7QGNvZGUgLTF9IGlmIHRoZSBwYXJ0aWFsIGJ5dGUgc2VxdWVuY2UgaXMgZGVmaW5pdGVseSBtYWxmb3JtZWQsCisgICAqIHtAY29kZSAwfSBpZiBpdCBpcyB3ZWxsLWZvcm1lZCAobm8gYWRkaXRpb25hbCBpbnB1dCBuZWVkZWQpLCBvciwgaWYgdGhlCisgICAqIGJ5dGUgc2VxdWVuY2UgaXMgImluY29tcGxldGUiLCBpLmUuIGFwcGFyZW50bHkgdGVybWluYXRlZCBpbiB0aGUgbWlkZGxlIG9mCisgICAqIGEgY2hhcmFjdGVyLCBhbiBvcGFxdWUgaW50ZWdlciAic3RhdGUiIHZhbHVlIGNvbnRhaW5pbmcgZW5vdWdoIGluZm9ybWF0aW9uCisgICAqIHRvIGRlY29kZSB0aGUgY2hhcmFjdGVyIHdoZW4gcGFzc2VkIHRvIGEgc3Vic2VxdWVudCBpbnZvY2F0aW9uIG9mIGEKKyAgICogcGFydGlhbCBkZWNvZGluZyBtZXRob2QuCisgICAqLworICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IHBhcnRpYWxJc1ZhbGlkVXRmOChpbnQgc3RhdGUsIGludCBvZmZzZXQsIGludCBsZW5ndGgpOworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpCisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGVxdWFscyhPYmplY3Qgbyk7CisKKyAgLyoqCisgICAqIFJldHVybiBhIG5vbi16ZXJvIGhhc2hDb2RlIGRlcGVuZGluZyBvbmx5IG9uIHRoZSBzZXF1ZW5jZSBvZiBieXRlcworICAgKiBpbiB0aGlzIEJ5dGVTdHJpbmcuCisgICAqCisgICAqIEByZXR1cm4gaGFzaENvZGUgdmFsdWUgZm9yIHRoaXMgb2JqZWN0CisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGFic3RyYWN0IGludCBoYXNoQ29kZSgpOworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIElucHV0IHN0cmVhbQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gd2hpY2ggY2FuIGJlIHVzZWQgdG8gcmVhZCB0aGUgYnl0ZXMuCisgICAqIDxwPgorICAgKiBUaGUge0BsaW5rIElucHV0U3RyZWFtfSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBpcyBndWFyYW50ZWVkIHRvIGJlCisgICAqIGNvbXBsZXRlbHkgbm9uLWJsb2NraW5nLiAgVGhlIG1ldGhvZCB7QGxpbmsgSW5wdXRTdHJlYW0jYXZhaWxhYmxlKCl9CisgICAqIHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZW1haW5pbmcgaW4gdGhlIHN0cmVhbS4gVGhlIG1ldGhvZHMKKyAgICoge0BsaW5rIElucHV0U3RyZWFtI3JlYWQoYnl0ZVtdKX0sIHtAbGluayBJbnB1dFN0cmVhbSNyZWFkKGJ5dGVbXSxpbnQsaW50KX0KKyAgICogYW5kIHtAbGluayBJbnB1dFN0cmVhbSNza2lwKGxvbmcpfSB3aWxsIHJlYWQvc2tpcCBhcyBtYW55IGJ5dGVzIGFzIGFyZQorICAgKiBhdmFpbGFibGUuCisgICAqIDxwPgorICAgKiBUaGUgbWV0aG9kcyBpbiB0aGUgcmV0dXJuZWQge0BsaW5rIElucHV0U3RyZWFtfSBtaWdodCA8Yj5ub3Q8L2I+IGJlCisgICAqIHRocmVhZCBzYWZlLgorICAgKgorICAgKiBAcmV0dXJuIGFuIGlucHV0IHN0cmVhbSB0aGF0IHJldHVybnMgdGhlIGJ5dGVzIG9mIHRoaXMgYnl0ZSBzdHJpbmcuCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgSW5wdXRTdHJlYW0gbmV3SW5wdXQoKTsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIHtAbGluayBDb2RlZElucHV0U3RyZWFtfSB3aGljaCBjYW4gYmUgdXNlZCB0byByZWFkIHRoZSBieXRlcy4KKyAgICogVXNpbmcgdGhpcyBpcyBvZnRlbiBtb3JlIGVmZmljaWVudCB0aGFuIGNyZWF0aW5nIGEge0BsaW5rIENvZGVkSW5wdXRTdHJlYW19CisgICAqIHRoYXQgd3JhcHMgdGhlIHJlc3VsdCBvZiB7QGxpbmsgI25ld0lucHV0KCl9LgorICAgKgorICAgKiBAcmV0dXJuIHN0cmVhbSBiYXNlZCBvbiB3cmFwcGVkIGRhdGEKKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBDb2RlZElucHV0U3RyZWFtIG5ld0NvZGVkSW5wdXQoKTsKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBPdXRwdXQgc3RyZWFtCisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcge0BsaW5rIE91dHB1dH0gd2l0aCB0aGUgZ2l2ZW4gaW5pdGlhbCBjYXBhY2l0eS4gQ2FsbCB7QGxpbmsKKyAgICogT3V0cHV0I3RvQnl0ZVN0cmluZygpfSB0byBjcmVhdGUgdGhlIHtAY29kZSBCeXRlU3RyaW5nfSBpbnN0YW5jZS4KKyAgICogPHA+CisgICAqIEEge0BsaW5rIEJ5dGVTdHJpbmcuT3V0cHV0fSBvZmZlcnMgdGhlIHNhbWUgZnVuY3Rpb25hbGl0eSBhcyBhCisgICAqIHtAbGluayBCeXRlQXJyYXlPdXRwdXRTdHJlYW19LCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIGEge0BsaW5rIEJ5dGVTdHJpbmd9CisgICAqIHJhdGhlciB0aGFuIGEge0Bjb2RlIGJ5dGV9IGFycmF5LgorICAgKgorICAgKiBAcGFyYW0gaW5pdGlhbENhcGFjaXR5IGVzdGltYXRlIG9mIG51bWJlciBvZiBieXRlcyB0byBiZSB3cml0dGVuCisgICAqIEByZXR1cm4ge0Bjb2RlIE91dHB1dFN0cmVhbX0gZm9yIGJ1aWxkaW5nIGEge0Bjb2RlIEJ5dGVTdHJpbmd9CisgICAqLworICBwdWJsaWMgc3RhdGljIE91dHB1dCBuZXdPdXRwdXQoaW50IGluaXRpYWxDYXBhY2l0eSkgeworICAgIHJldHVybiBuZXcgT3V0cHV0KGluaXRpYWxDYXBhY2l0eSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIG5ldyB7QGxpbmsgT3V0cHV0fS4gQ2FsbCB7QGxpbmsgT3V0cHV0I3RvQnl0ZVN0cmluZygpfSB0byBjcmVhdGUKKyAgICogdGhlIHtAY29kZSBCeXRlU3RyaW5nfSBpbnN0YW5jZS4KKyAgICogPHA+CisgICAqIEEge0BsaW5rIEJ5dGVTdHJpbmcuT3V0cHV0fSBvZmZlcnMgdGhlIHNhbWUgZnVuY3Rpb25hbGl0eSBhcyBhCisgICAqIHtAbGluayBCeXRlQXJyYXlPdXRwdXRTdHJlYW19LCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIGEge0BsaW5rIEJ5dGVTdHJpbmd9CisgICAqIHJhdGhlciB0aGFuIGEge0Bjb2RlIGJ5dGUgYXJyYXl9LgorICAgKgorICAgKiBAcmV0dXJuIHtAY29kZSBPdXRwdXRTdHJlYW19IGZvciBidWlsZGluZyBhIHtAY29kZSBCeXRlU3RyaW5nfQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBPdXRwdXQgbmV3T3V0cHV0KCkgeworICAgIHJldHVybiBuZXcgT3V0cHV0KENPTkNBVEVOQVRFX0JZX0NPUFlfU0laRSk7CisgIH0KKworICAvKioKKyAgICogT3V0cHV0cyB0byBhIHtAY29kZSBCeXRlU3RyaW5nfSBpbnN0YW5jZS4gQ2FsbCB7QGxpbmsgI3RvQnl0ZVN0cmluZygpfSB0bworICAgKiBjcmVhdGUgdGhlIHtAY29kZSBCeXRlU3RyaW5nfSBpbnN0YW5jZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT3V0cHV0IGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBub3RlLgorICAgIC8vIFRoZSBwdWJsaWMgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIG11c3QgYmUgc3luY2hyb25pemVkLiAgQnl0ZVN0cmluZ3MKKyAgICAvLyBhcmUgZ3VhcmFudGVlZCB0byBiZSBpbW11dGFibGUuICBXaXRob3V0IHNvbWUgc29ydCBvZiBsb2NraW5nLCBpdCBjb3VsZAorICAgIC8vIGJlIHBvc3NpYmxlIGZvciBvbmUgdGhyZWFkIHRvIGNhbGwgdG9CeXRlU3JpbmcoKSwgd2hpbGUgYW5vdGhlciB0aHJlYWQKKyAgICAvLyBpcyBzdGlsbCBtb2RpZnlpbmcgdGhlIHVuZGVybHlpbmcgYnl0ZSBhcnJheS4KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBFTVBUWV9CWVRFX0FSUkFZID0gbmV3IGJ5dGVbMF07CisgICAgLy8gYXJndW1lbnQgcGFzc2VkIGJ5IHVzZXIsIGluZGljYXRpbmcgaW5pdGlhbCBjYXBhY2l0eS4KKyAgICBwcml2YXRlIGZpbmFsIGludCBpbml0aWFsQ2FwYWNpdHk7CisgICAgLy8gQnl0ZVN0cmluZ3MgdG8gYmUgY29uY2F0ZW5hdGVkIHRvIGNyZWF0ZSB0aGUgcmVzdWx0CisgICAgcHJpdmF0ZSBmaW5hbCBBcnJheUxpc3Q8Qnl0ZVN0cmluZz4gZmx1c2hlZEJ1ZmZlcnM7CisgICAgLy8gVG90YWwgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBCeXRlU3RyaW5ncyBvZiBmbHVzaGVkQnVmZmVycworICAgIHByaXZhdGUgaW50IGZsdXNoZWRCdWZmZXJzVG90YWxCeXRlczsKKyAgICAvLyBDdXJyZW50IGJ1ZmZlciB0byB3aGljaCB3ZSBhcmUgd3JpdGluZworICAgIHByaXZhdGUgYnl0ZVtdIGJ1ZmZlcjsKKyAgICAvLyBMb2NhdGlvbiBpbiBidWZmZXJbXSB0byB3aGljaCB3ZSB3cml0ZSB0aGUgbmV4dCBieXRlLgorICAgIHByaXZhdGUgaW50IGJ1ZmZlclBvczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQnl0ZVN0cmluZyBvdXRwdXQgc3RyZWFtIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGluaXRpYWwgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbENhcGFjaXR5ICB0aGUgaW5pdGlhbCBjYXBhY2l0eSBvZiB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBPdXRwdXQoaW50IGluaXRpYWxDYXBhY2l0eSkgeworICAgICAgaWYgKGluaXRpYWxDYXBhY2l0eSA8IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQnVmZmVyIHNpemUgPCAwIik7CisgICAgICB9CisgICAgICB0aGlzLmluaXRpYWxDYXBhY2l0eSA9IGluaXRpYWxDYXBhY2l0eTsKKyAgICAgIHRoaXMuZmx1c2hlZEJ1ZmZlcnMgPSBuZXcgQXJyYXlMaXN0PEJ5dGVTdHJpbmc+KCk7CisgICAgICB0aGlzLmJ1ZmZlciA9IG5ldyBieXRlW2luaXRpYWxDYXBhY2l0eV07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlKGludCBiKSB7CisgICAgICBpZiAoYnVmZmVyUG9zID09IGJ1ZmZlci5sZW5ndGgpIHsKKyAgICAgICAgZmx1c2hGdWxsQnVmZmVyKDEpOworICAgICAgfQorICAgICAgYnVmZmVyW2J1ZmZlclBvcysrXSA9IChieXRlKWI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSAgeworICAgICAgaWYgKGxlbmd0aCA8PSBidWZmZXIubGVuZ3RoIC0gYnVmZmVyUG9zKSB7CisgICAgICAgIC8vIFRoZSBieXRlcyBjYW4gZml0IGludG8gdGhlIGN1cnJlbnQgYnVmZmVyLgorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZnNldCwgYnVmZmVyLCBidWZmZXJQb3MsIGxlbmd0aCk7CisgICAgICAgIGJ1ZmZlclBvcyArPSBsZW5ndGg7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBVc2UgdXAgdGhlIGN1cnJlbnQgYnVmZmVyCisgICAgICAgIGludCBjb3B5U2l6ZSAgPSBidWZmZXIubGVuZ3RoIC0gYnVmZmVyUG9zOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZnNldCwgYnVmZmVyLCBidWZmZXJQb3MsIGNvcHlTaXplKTsKKyAgICAgICAgb2Zmc2V0ICs9IGNvcHlTaXplOworICAgICAgICBsZW5ndGggLT0gY29weVNpemU7CisgICAgICAgIC8vIEZsdXNoIHRoZSBidWZmZXIsIGFuZCBnZXQgYSBuZXcgYnVmZmVyIGF0IGxlYXN0IGJpZyBlbm91Z2ggdG8gY292ZXIKKyAgICAgICAgLy8gd2hhdCB3ZSBzdGlsbCBuZWVkIHRvIG91dHB1dAorICAgICAgICBmbHVzaEZ1bGxCdWZmZXIobGVuZ3RoKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiLCBvZmZzZXQsIGJ1ZmZlciwgMCAvKiBjb3VudCAqLywgbGVuZ3RoKTsKKyAgICAgICAgYnVmZmVyUG9zID0gbGVuZ3RoOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBieXRlIHN0cmluZy4gSXRzIHNpemUgaXMgdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGlzIG91dHB1dAorICAgICAqIHN0cmVhbSBhbmQgaXRzIG91dHB1dCBoYXMgYmVlbiBjb3BpZWQgdG8gaXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICB0aGUgY3VycmVudCBjb250ZW50cyBvZiB0aGlzIG91dHB1dCBzdHJlYW0sIGFzIGEgYnl0ZSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBCeXRlU3RyaW5nIHRvQnl0ZVN0cmluZygpIHsKKyAgICAgIGZsdXNoTGFzdEJ1ZmZlcigpOworICAgICAgcmV0dXJuIEJ5dGVTdHJpbmcuY29weUZyb20oZmx1c2hlZEJ1ZmZlcnMpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnQgamF2YS51dGlsLkFycmF5cy5jb3B5T2YoKSBmb3IgamRrIDEuNS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBjb3B5QXJyYXkoYnl0ZVtdIGJ1ZmZlciwgaW50IGxlbmd0aCkgeworICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgMCwgcmVzdWx0LCAwLCBNYXRoLm1pbihidWZmZXIubGVuZ3RoLCBsZW5ndGgpKTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBjb21wbGV0ZSBjb250ZW50cyBvZiB0aGlzIGJ5dGUgYXJyYXkgb3V0cHV0IHN0cmVhbSB0bworICAgICAqIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbSBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIG91dHB1dCBzdHJlYW0gdG8gd2hpY2ggdG8gd3JpdGUgdGhlIGRhdGEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBCeXRlU3RyaW5nW10gY2FjaGVkRmx1c2hCdWZmZXJzOworICAgICAgYnl0ZVtdIGNhY2hlZEJ1ZmZlcjsKKyAgICAgIGludCBjYWNoZWRCdWZmZXJQb3M7CisgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgLy8gQ29weSB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCBpbnRvIGxvY2FsIHZhcmlhYmxlcyBzbyBhcyB0byBob2xkCisgICAgICAgIC8vIHRoZSBsb2NrIGZvciBhcyBzaG9ydCBhIHRpbWUgYXMgcG9zc2libGUuCisgICAgICAgIGNhY2hlZEZsdXNoQnVmZmVycyA9CisgICAgICAgICAgICBmbHVzaGVkQnVmZmVycy50b0FycmF5KG5ldyBCeXRlU3RyaW5nW2ZsdXNoZWRCdWZmZXJzLnNpemUoKV0pOworICAgICAgICBjYWNoZWRCdWZmZXIgPSBidWZmZXI7CisgICAgICAgIGNhY2hlZEJ1ZmZlclBvcyA9IGJ1ZmZlclBvczsKKyAgICAgIH0KKyAgICAgIGZvciAoQnl0ZVN0cmluZyBieXRlU3RyaW5nIDogY2FjaGVkRmx1c2hCdWZmZXJzKSB7CisgICAgICAgIGJ5dGVTdHJpbmcud3JpdGVUbyhvdXQpOworICAgICAgfQorCisgICAgICBvdXQud3JpdGUoY29weUFycmF5KGNhY2hlZEJ1ZmZlciwgY2FjaGVkQnVmZmVyUG9zKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzaXplIG9mIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiAgdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHNpemUoKSB7CisgICAgICByZXR1cm4gZmx1c2hlZEJ1ZmZlcnNUb3RhbEJ5dGVzICsgYnVmZmVyUG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIHN0cmVhbSwgc28gdGhhdCBhbGwgY3VycmVudGx5IGFjY3VtdWxhdGVkIG91dHB1dCBpbiB0aGUKKyAgICAgKiBvdXRwdXQgc3RyZWFtIGlzIGRpc2NhcmRlZC4gVGhlIG91dHB1dCBzdHJlYW0gY2FuIGJlIHVzZWQgYWdhaW4sCisgICAgICogcmV1c2luZyB0aGUgYWxyZWFkeSBhbGxvY2F0ZWQgYnVmZmVyIHNwYWNlLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldCgpIHsKKyAgICAgIGZsdXNoZWRCdWZmZXJzLmNsZWFyKCk7CisgICAgICBmbHVzaGVkQnVmZmVyc1RvdGFsQnl0ZXMgPSAwOworICAgICAgYnVmZmVyUG9zID0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIjxCeXRlU3RyaW5nLk91dHB1dEAlcyBzaXplPSVkPiIsCisgICAgICAgICAgSW50ZWdlci50b0hleFN0cmluZyhTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh0aGlzKSksIHNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBieSB3cml0ZXJzLiAgVGhlIGN1cnJlbnQgYnVmZmVyIGlzIGZ1bGwsIGFuZCB0aGUKKyAgICAgKiB3cml0ZXIgbmVlZHMgYSBuZXcgYnVmZmVyIHdob3NlIHNpemUgaXMgYXQgbGVhc3QgdGhlIHNwZWNpZmllZCBtaW5pbXVtCisgICAgICogc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmx1c2hGdWxsQnVmZmVyKGludCBtaW5TaXplKSAgeworICAgICAgZmx1c2hlZEJ1ZmZlcnMuYWRkKG5ldyBMaXRlcmFsQnl0ZVN0cmluZyhidWZmZXIpKTsKKyAgICAgIGZsdXNoZWRCdWZmZXJzVG90YWxCeXRlcyArPSBidWZmZXIubGVuZ3RoOworICAgICAgLy8gV2Ugd2FudCB0byBpbmNyZWFzZSBvdXIgdG90YWwgY2FwYWNpdHkgYnkgNTAlLCBidXQgYXMgYSBtaW5pbXVtLAorICAgICAgLy8gdGhlIG5ldyBidWZmZXIgc2hvdWxkIGFsc28gYXQgbGVhc3QgYmUgPj0gbWluU2l6ZSBhbmQKKyAgICAgIC8vID49IGluaXRpYWwgQ2FwYWNpdHkuCisgICAgICBpbnQgbmV3U2l6ZSA9IE1hdGgubWF4KGluaXRpYWxDYXBhY2l0eSwKKyAgICAgICAgICBNYXRoLm1heChtaW5TaXplLCBmbHVzaGVkQnVmZmVyc1RvdGFsQnl0ZXMgPj4+IDEpKTsKKyAgICAgIGJ1ZmZlciA9IG5ldyBieXRlW25ld1NpemVdOworICAgICAgYnVmZmVyUG9zID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcm5hbCBmdW5jdGlvbiB1c2VkIGJ5IHtAbGluayAjdG9CeXRlU3RyaW5nKCl9LiBUaGUgY3VycmVudCBidWZmZXIgbWF5CisgICAgICogb3IgbWF5IG5vdCBiZSBmdWxsLCBidXQgaXQgbmVlZHMgdG8gYmUgZmx1c2hlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmx1c2hMYXN0QnVmZmVyKCkgIHsKKyAgICAgIGlmIChidWZmZXJQb3MgPCBidWZmZXIubGVuZ3RoKSB7CisgICAgICAgIGlmIChidWZmZXJQb3MgPiAwKSB7CisgICAgICAgICAgYnl0ZVtdIGJ1ZmZlckNvcHkgPSBjb3B5QXJyYXkoYnVmZmVyLCBidWZmZXJQb3MpOworICAgICAgICAgIGZsdXNoZWRCdWZmZXJzLmFkZChuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcoYnVmZmVyQ29weSkpOworICAgICAgICB9CisgICAgICAgIC8vIFdlIHJldXNlIHRoaXMgYnVmZmVyIGZvciBmdXJ0aGVyIHdyaXRlcy4KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIEJ1ZmZlciBpcyBjb21wbGV0ZWx5IGZ1bGwuICBIdXp6YWguCisgICAgICAgIGZsdXNoZWRCdWZmZXJzLmFkZChuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcoYnVmZmVyKSk7CisgICAgICAgIC8vIDk5JSBvZiB0aGUgdGltZSwgd2UncmUgbm90IGdvaW5nIHRvIHVzZSB0aGlzIE91dHB1dFN0cmVhbSBhZ2Fpbi4KKyAgICAgICAgLy8gV2Ugc2V0IGJ1ZmZlciB0byBhbiBlbXB0eSBieXRlIHN0cmVhbSBzbyB0aGF0IHdlJ3JlIGhhbmRsaW5nIHRoaXMKKyAgICAgICAgLy8gY2FzZSB3aXRob3V0IHdhc3Rpbmcgc3BhY2UuICBJbiB0aGUgcmFyZSBjYXNlIHRoYXQgbW9yZSB3cml0ZXMKKyAgICAgICAgLy8gKmRvKiBvY2N1ciwgdGhpcyBlbXB0eSBidWZmZXIgd2lsbCBiZSBmbHVzaGVkIGFuZCBhbiBhcHByb3ByaWF0ZWx5CisgICAgICAgIC8vIHNpemVkIG5ldyBidWZmZXIgd2lsbCBiZSBjcmVhdGVkLgorICAgICAgICBidWZmZXIgPSBFTVBUWV9CWVRFX0FSUkFZOworICAgICAgfQorICAgICAgZmx1c2hlZEJ1ZmZlcnNUb3RhbEJ5dGVzICs9IGJ1ZmZlclBvczsKKyAgICAgIGJ1ZmZlclBvcyA9IDA7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJ5dGVTdHJpbmd9IGJ1aWxkZXIsIHdoaWNoIGFsbG93cyB5b3UgdG8KKyAgICogZWZmaWNpZW50bHkgY29uc3RydWN0IGEge0Bjb2RlIEJ5dGVTdHJpbmd9IGJ5IHdyaXRpbmcgdG8gYSB7QGxpbmsKKyAgICogQ29kZWRPdXRwdXRTdHJlYW19LiBVc2luZyB0aGlzIGlzIG11Y2ggbW9yZSBlZmZpY2llbnQgdGhhbiBjYWxsaW5nIHtAY29kZQorICAgKiBuZXdPdXRwdXQoKX0gYW5kIHdyYXBwaW5nIHRoYXQgaW4gYSB7QGNvZGUgQ29kZWRPdXRwdXRTdHJlYW19LgorICAgKgorICAgKiA8cD5UaGlzIGlzIHBhY2thZ2UtcHJpdmF0ZSBiZWNhdXNlIGl0J3MgYSBzb21ld2hhdCBjb25mdXNpbmcgaW50ZXJmYWNlLgorICAgKiBVc2VycyBjYW4gY2FsbCB7QGxpbmsgTWVzc2FnZSN0b0J5dGVTdHJpbmcoKX0gaW5zdGVhZCBvZiBjYWxsaW5nIHRoaXMKKyAgICogZGlyZWN0bHkuCisgICAqCisgICAqIEBwYXJhbSBzaXplIFRoZSB0YXJnZXQgYnl0ZSBzaXplIG9mIHRoZSB7QGNvZGUgQnl0ZVN0cmluZ30uICBZb3UgbXVzdCB3cml0ZQorICAgKiAgICAgZXhhY3RseSB0aGlzIG1hbnkgYnl0ZXMgYmVmb3JlIGJ1aWxkaW5nIHRoZSByZXN1bHQuCisgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICovCisgIHN0YXRpYyBDb2RlZEJ1aWxkZXIgbmV3Q29kZWRCdWlsZGVyKGludCBzaXplKSB7CisgICAgcmV0dXJuIG5ldyBDb2RlZEJ1aWxkZXIoc2l6ZSk7CisgIH0KKworICAvKiogU2VlIHtAbGluayBCeXRlU3RyaW5nI25ld0NvZGVkQnVpbGRlcihpbnQpfS4gKi8KKyAgc3RhdGljIGZpbmFsIGNsYXNzIENvZGVkQnVpbGRlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmZmVyOworCisgICAgcHJpdmF0ZSBDb2RlZEJ1aWxkZXIoaW50IHNpemUpIHsKKyAgICAgIGJ1ZmZlciA9IG5ldyBieXRlW3NpemVdOworICAgICAgb3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UoYnVmZmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZVN0cmluZyBidWlsZCgpIHsKKyAgICAgIG91dHB1dC5jaGVja05vU3BhY2VMZWZ0KCk7CisKKyAgICAgIC8vIFdlIGNhbiBiZSBjb25maWRlbnQgdGhhdCB0aGUgQ29kZWRPdXRwdXRTdHJlYW0gd2lsbCBub3QgbW9kaWZ5IHRoZQorICAgICAgLy8gdW5kZXJseWluZyBieXRlcyBhbnltb3JlIGJlY2F1c2UgaXQgYWxyZWFkeSB3cm90ZSBhbGwgb2YgdGhlbS4gIFNvLAorICAgICAgLy8gbm8gbmVlZCB0byBtYWtlIGEgY29weS4KKyAgICAgIHJldHVybiBuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcoYnVmZmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29kZWRPdXRwdXRTdHJlYW0gZ2V0Q29kZWRPdXRwdXQoKSB7CisgICAgICByZXR1cm4gb3V0cHV0OworICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIE1ldGhvZHMge0BsaW5rIFJvcGVCeXRlU3RyaW5nfSBuZWVkcyBvbiBpbnN0YW5jZXMsIHdoaWNoIGFyZW4ndCBwYXJ0IG9mIHRoZQorICAvLyBwdWJsaWMgQVBJLgorCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIGRlcHRoIG9mIHRoZSB0cmVlIHJlcHJlc2VudGluZyB0aGlzIHtAY29kZSBCeXRlU3RyaW5nfSwgaWYgYW55LAorICAgKiB3aG9zZSByb290IGlzIHRoaXMgbm9kZS4gSWYgdGhpcyBpcyBhIGxlYWYgbm9kZSwgcmV0dXJuIDAuCisgICAqCisgICAqIEByZXR1cm4gdHJlZSBkZXB0aCBvciB6ZXJvCisgICAqLworICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGdldFRyZWVEZXB0aCgpOworCisgIC8qKgorICAgKiBSZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgQnl0ZVN0cmluZyBpcyBsaXRlcmFsIChhIGxlYWYgbm9kZSkgb3IgYQorICAgKiBmbGF0LWVub3VnaCB0cmVlIGluIHRoZSBzZW5zZSBvZiB7QGxpbmsgUm9wZUJ5dGVTdHJpbmd9LgorICAgKgorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRyZWUgaXMgZmxhdCBlbm91Z2gKKyAgICovCisgIHByb3RlY3RlZCBhYnN0cmFjdCBib29sZWFuIGlzQmFsYW5jZWQoKTsKKworICAvKioKKyAgICogUmV0dXJuIHRoZSBjYWNoZWQgaGFzaCBjb2RlIGlmIGF2YWlsYWJsZS4KKyAgICoKKyAgICogQHJldHVybiB2YWx1ZSBvZiBjYWNoZWQgaGFzaCBjb2RlIG9yIDAgaWYgbm90IGNvbXB1dGVkIHlldAorICAgKi8KKyAgcHJvdGVjdGVkIGFic3RyYWN0IGludCBwZWVrQ2FjaGVkSGFzaENvZGUoKTsKKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgaGFzaCBhY3Jvc3MgdGhlIHZhbHVlIGJ5dGVzIHN0YXJ0aW5nIHdpdGggdGhlIGdpdmVuIGhhc2gsIGFuZAorICAgKiByZXR1cm4gdGhlIHJlc3VsdC4gIFRoaXMgaXMgdXNlZCB0byBjb21wdXRlIHRoZSBoYXNoIGFjcm9zcyBzdHJpbmdzCisgICAqIHJlcHJlc2VudGVkIGFzIGEgc2V0IG9mIHBpZWNlcyBieSBhbGxvd2luZyB0aGUgaGFzaCBjb21wdXRhdGlvbiB0byBiZQorICAgKiBjb250aW51ZWQgZnJvbSBwaWVjZSB0byBwaWVjZS4KKyAgICoKKyAgICogQHBhcmFtIGggc3RhcnRpbmcgaGFzaCB2YWx1ZQorICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBpbnRvIHRoaXMgdmFsdWUgdG8gc3RhcnQgbG9va2luZyBhdCBkYXRhIHZhbHVlcworICAgKiBAcGFyYW0gbGVuZ3RoIG51bWJlciBvZiBkYXRhIHZhbHVlcyB0byBpbmNsdWRlIGluIHRoZSBoYXNoIGNvbXB1dGF0aW9uCisgICAqIEByZXR1cm4gZW5kaW5nIGhhc2ggdmFsdWUKKyAgICovCisgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgcGFydGlhbEhhc2goaW50IGgsIGludCBvZmZzZXQsIGludCBsZW5ndGgpOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCI8Qnl0ZVN0cmluZ0AlcyBzaXplPSVkPiIsCisgICAgICAgIEludGVnZXIudG9IZXhTdHJpbmcoU3lzdGVtLmlkZW50aXR5SGFzaENvZGUodGhpcykpLCBzaXplKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZElucHV0U3RyZWFtLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNhMDBiYQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEzMTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogUmVhZHMgYW5kIGRlY29kZXMgcHJvdG9jb2wgbWVzc2FnZSBmaWVsZHMuCisgKgorICogVGhpcyBjbGFzcyBjb250YWlucyB0d28ga2luZHMgb2YgbWV0aG9kczogIG1ldGhvZHMgdGhhdCByZWFkIHNwZWNpZmljCisgKiBwcm90b2NvbCBtZXNzYWdlIGNvbnN0cnVjdHMgYW5kIGZpZWxkIHR5cGVzIChlLmcuIHtAbGluayAjcmVhZFRhZygpfSBhbmQKKyAqIHtAbGluayAjcmVhZEludDMyKCl9KSBhbmQgbWV0aG9kcyB0aGF0IHJlYWQgbG93LWxldmVsIHZhbHVlcyAoZS5nLgorICoge0BsaW5rICNyZWFkUmF3VmFyaW50MzIoKX0gYW5kIHtAbGluayAjcmVhZFJhd0J5dGVzfSkuICBJZiB5b3UgYXJlIHJlYWRpbmcKKyAqIGVuY29kZWQgcHJvdG9jb2wgbWVzc2FnZXMsIHlvdSBzaG91bGQgdXNlIHRoZSBmb3JtZXIgbWV0aG9kcywgYnV0IGlmIHlvdSBhcmUKKyAqIHJlYWRpbmcgc29tZSBvdGhlciBmb3JtYXQgb2YgeW91ciBvd24gZGVzaWduLCB1c2UgdGhlIGxhdHRlci4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29kZWRJbnB1dFN0cmVhbSB7CisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcgQ29kZWRJbnB1dFN0cmVhbSB3cmFwcGluZyB0aGUgZ2l2ZW4gSW5wdXRTdHJlYW0uCisgICAqLworICBwdWJsaWMgc3RhdGljIENvZGVkSW5wdXRTdHJlYW0gbmV3SW5zdGFuY2UoZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQpIHsKKyAgICByZXR1cm4gbmV3IENvZGVkSW5wdXRTdHJlYW0oaW5wdXQpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyBDb2RlZElucHV0U3RyZWFtIHdyYXBwaW5nIHRoZSBnaXZlbiBieXRlIGFycmF5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBDb2RlZElucHV0U3RyZWFtIG5ld0luc3RhbmNlKGZpbmFsIGJ5dGVbXSBidWYpIHsKKyAgICByZXR1cm4gbmV3SW5zdGFuY2UoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcgQ29kZWRJbnB1dFN0cmVhbSB3cmFwcGluZyB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSBzbGljZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQ29kZWRJbnB1dFN0cmVhbSBuZXdJbnN0YW5jZShmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2ZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbikgeworICAgIENvZGVkSW5wdXRTdHJlYW0gcmVzdWx0ID0gbmV3IENvZGVkSW5wdXRTdHJlYW0oYnVmLCBvZmYsIGxlbik7CisgICAgdHJ5IHsKKyAgICAgIC8vIFNvbWUgdXNlcyBvZiBDb2RlZElucHV0U3RyZWFtIGNhbiBiZSBtb3JlIGVmZmljaWVudCBpZiB0aGV5IGtub3cKKyAgICAgIC8vIGV4YWN0bHkgaG93IG1hbnkgYnl0ZXMgYXJlIGF2YWlsYWJsZS4gIEJ5IHB1c2hpbmcgdGhlIGVuZCBwb2ludCBvZiB0aGUKKyAgICAgIC8vIGJ1ZmZlciBhcyBhIGxpbWl0LCB3ZSBhbGxvdyB0aGVtIHRvIGdldCB0aGlzIGluZm9ybWF0aW9uIHZpYQorICAgICAgLy8gZ2V0Qnl0ZXNVbnRpbExpbWl0KCkuICBQdXNoaW5nIGEgbGltaXQgdGhhdCB3ZSBrbm93IGlzIGF0IHRoZSBlbmQgb2YKKyAgICAgIC8vIHRoZSBzdHJlYW0gY2FuIG5ldmVyIGh1cnQsIHNpbmNlIHdlIGNhbiBuZXZlciBwYXN0IHRoYXQgcG9pbnQgYW55d2F5LgorICAgICAgcmVzdWx0LnB1c2hMaW1pdChsZW4pOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBleCkgeworICAgICAgLy8gVGhlIG9ubHkgcmVhc29uIHB1c2hMaW1pdCgpIG1pZ2h0IHRocm93IGFuIGV4Y2VwdGlvbiBoZXJlIGlzIGlmIGxlbgorICAgICAgLy8gaXMgbmVnYXRpdmUuIE5vcm1hbGx5IHB1c2hMaW1pdCgpJ3MgcGFyYW1ldGVyIGNvbWVzIGRpcmVjdGx5IG9mZiB0aGUKKyAgICAgIC8vIHdpcmUsIHNvIGl0J3MgaW1wb3J0YW50IHRvIGNhdGNoIGV4Y2VwdGlvbnMgaW4gY2FzZSBvZiBjb3JydXB0IG9yCisgICAgICAvLyBtYWxpY2lvdXMgZGF0YS4gSG93ZXZlciwgaW4gdGhpcyBjYXNlLCB3ZSBleHBlY3QgdGhhdCBsZW4gaXMgbm90IGEKKyAgICAgIC8vIHVzZXItc3VwcGxpZWQgdmFsdWUsIHNvIHdlIGNhbiBhc3N1bWUgdGhhdCBpdCBiZWluZyBuZWdhdGl2ZSBpbmRpY2F0ZXMKKyAgICAgIC8vIGEgcHJvZ3JhbW1pbmcgZXJyb3IuIFRoZXJlZm9yZSwgdGhyb3dpbmcgYW4gdW5jaGVja2VkIGV4Y2VwdGlvbiBpcworICAgICAgLy8gYXBwcm9wcmlhdGUuCisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGV4KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcgQ29kZWRJbnB1dFN0cmVhbSB3cmFwcGluZyB0aGUgZ2l2ZW4gQnl0ZUJ1ZmZlci4gVGhlIGRhdGEKKyAgICogc3RhcnRpbmcgZnJvbSB0aGUgQnl0ZUJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24gdG8gaXRzIGxpbWl0IHdpbGwgYmUgcmVhZC4KKyAgICogVGhlIHJldHVybmVkIENvZGVkSW5wdXRTdHJlYW0gbWF5IG9yIG1heSBub3Qgc2hhcmUgdGhlIHVuZGVybHlpbmcgZGF0YQorICAgKiBpbiB0aGUgQnl0ZUJ1ZmZlciwgdGhlcmVmb3JlIHRoZSBCeXRlQnVmZmVyIGNhbm5vdCBiZSBjaGFuZ2VkIHdoaWxlIHRoZQorICAgKiBDb2RlZElucHV0U3RyZWFtIGlzIGluIHVzZS4KKyAgICogTm90ZSB0aGF0IHRoZSBCeXRlQnVmZmVyJ3MgcG9zaXRpb24gd29uJ3QgYmUgY2hhbmdlZCBieSB0aGlzIGZ1bmN0aW9uLgorICAgKiBDb25jdXJyZW50IGNhbGxzIHdpdGggdGhlIHNhbWUgQnl0ZUJ1ZmZlciBvYmplY3QgYXJlIHNhZmUgaWYgbm8gb3RoZXIKKyAgICogdGhyZWFkIGlzIHRyeWluZyB0byBhbHRlciB0aGUgQnl0ZUJ1ZmZlcidzIHN0YXR1cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQ29kZWRJbnB1dFN0cmVhbSBuZXdJbnN0YW5jZShCeXRlQnVmZmVyIGJ1ZikgeworICAgIGlmIChidWYuaGFzQXJyYXkoKSkgeworICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKGJ1Zi5hcnJheSgpLCBidWYuYXJyYXlPZmZzZXQoKSArIGJ1Zi5wb3NpdGlvbigpLAorICAgICAgICAgIGJ1Zi5yZW1haW5pbmcoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEJ5dGVCdWZmZXIgdGVtcCA9IGJ1Zi5kdXBsaWNhdGUoKTsKKyAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVt0ZW1wLnJlbWFpbmluZygpXTsKKyAgICAgIHRlbXAuZ2V0KGJ1ZmZlcik7CisgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoYnVmZmVyKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IENvZGVkSW5wdXRTdHJlYW0gd3JhcHBpbmcgYSBMaXRlcmFsQnl0ZVN0cmluZy4KKyAgICovCisgIHN0YXRpYyBDb2RlZElucHV0U3RyZWFtIG5ld0luc3RhbmNlKExpdGVyYWxCeXRlU3RyaW5nIGJ5dGVTdHJpbmcpIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIHJlc3VsdCA9IG5ldyBDb2RlZElucHV0U3RyZWFtKGJ5dGVTdHJpbmcpOworICAgIHRyeSB7CisgICAgICAvLyBTb21lIHVzZXMgb2YgQ29kZWRJbnB1dFN0cmVhbSBjYW4gYmUgbW9yZSBlZmZpY2llbnQgaWYgdGhleSBrbm93CisgICAgICAvLyBleGFjdGx5IGhvdyBtYW55IGJ5dGVzIGFyZSBhdmFpbGFibGUuICBCeSBwdXNoaW5nIHRoZSBlbmQgcG9pbnQgb2YgdGhlCisgICAgICAvLyBidWZmZXIgYXMgYSBsaW1pdCwgd2UgYWxsb3cgdGhlbSB0byBnZXQgdGhpcyBpbmZvcm1hdGlvbiB2aWEKKyAgICAgIC8vIGdldEJ5dGVzVW50aWxMaW1pdCgpLiAgUHVzaGluZyBhIGxpbWl0IHRoYXQgd2Uga25vdyBpcyBhdCB0aGUgZW5kIG9mCisgICAgICAvLyB0aGUgc3RyZWFtIGNhbiBuZXZlciBodXJ0LCBzaW5jZSB3ZSBjYW4gbmV2ZXIgcGFzdCB0aGF0IHBvaW50IGFueXdheS4KKyAgICAgIHJlc3VsdC5wdXNoTGltaXQoYnl0ZVN0cmluZy5zaXplKCkpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBleCkgeworICAgICAgLy8gVGhlIG9ubHkgcmVhc29uIHB1c2hMaW1pdCgpIG1pZ2h0IHRocm93IGFuIGV4Y2VwdGlvbiBoZXJlIGlzIGlmIGxlbgorICAgICAgLy8gaXMgbmVnYXRpdmUuIE5vcm1hbGx5IHB1c2hMaW1pdCgpJ3MgcGFyYW1ldGVyIGNvbWVzIGRpcmVjdGx5IG9mZiB0aGUKKyAgICAgIC8vIHdpcmUsIHNvIGl0J3MgaW1wb3J0YW50IHRvIGNhdGNoIGV4Y2VwdGlvbnMgaW4gY2FzZSBvZiBjb3JydXB0IG9yCisgICAgICAvLyBtYWxpY2lvdXMgZGF0YS4gSG93ZXZlciwgaW4gdGhpcyBjYXNlLCB3ZSBleHBlY3QgdGhhdCBsZW4gaXMgbm90IGEKKyAgICAgIC8vIHVzZXItc3VwcGxpZWQgdmFsdWUsIHNvIHdlIGNhbiBhc3N1bWUgdGhhdCBpdCBiZWluZyBuZWdhdGl2ZSBpbmRpY2F0ZXMKKyAgICAgIC8vIGEgcHJvZ3JhbW1pbmcgZXJyb3IuIFRoZXJlZm9yZSwgdGhyb3dpbmcgYW4gdW5jaGVja2VkIGV4Y2VwdGlvbiBpcworICAgICAgLy8gYXBwcm9wcmlhdGUuCisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGV4KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIEF0dGVtcHQgdG8gcmVhZCBhIGZpZWxkIHRhZywgcmV0dXJuaW5nIHplcm8gaWYgd2UgaGF2ZSByZWFjaGVkIEVPRi4KKyAgICogUHJvdG9jb2wgbWVzc2FnZSBwYXJzZXJzIHVzZSB0aGlzIHRvIHJlYWQgdGFncywgc2luY2UgYSBwcm90b2NvbCBtZXNzYWdlCisgICAqIG1heSBsZWdhbGx5IGVuZCB3aGVyZXZlciBhIHRhZyBvY2N1cnMsIGFuZCB6ZXJvIGlzIG5vdCBhIHZhbGlkIHRhZyBudW1iZXIuCisgICAqLworICBwdWJsaWMgaW50IHJlYWRUYWcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChpc0F0RW5kKCkpIHsKKyAgICAgIGxhc3RUYWcgPSAwOworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgbGFzdFRhZyA9IHJlYWRSYXdWYXJpbnQzMigpOworICAgIGlmIChXaXJlRm9ybWF0LmdldFRhZ0ZpZWxkTnVtYmVyKGxhc3RUYWcpID09IDApIHsKKyAgICAgIC8vIElmIHdlIGFjdHVhbGx5IHJlYWQgemVybyAob3IgYW55IHRhZyBudW1iZXIgY29ycmVzcG9uZGluZyB0byBmaWVsZAorICAgICAgLy8gbnVtYmVyIHplcm8pLCB0aGF0J3Mgbm90IGEgdmFsaWQgdGFnLgorICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmludmFsaWRUYWcoKTsKKyAgICB9CisgICAgcmV0dXJuIGxhc3RUYWc7CisgIH0KKworICAvKioKKyAgICogVmVyaWZpZXMgdGhhdCB0aGUgbGFzdCBjYWxsIHRvIHJlYWRUYWcoKSByZXR1cm5lZCB0aGUgZ2l2ZW4gdGFnIHZhbHVlLgorICAgKiBUaGlzIGlzIHVzZWQgdG8gdmVyaWZ5IHRoYXQgYSBuZXN0ZWQgZ3JvdXAgZW5kZWQgd2l0aCB0aGUgY29ycmVjdAorICAgKiBlbmQgdGFnLgorICAgKgorICAgKiBAdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7QGNvZGUgdmFsdWV9IGRvZXMgbm90IG1hdGNoIHRoZQorICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0IHRhZy4KKyAgICovCisgIHB1YmxpYyB2b2lkIGNoZWNrTGFzdFRhZ1dhcyhmaW5hbCBpbnQgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICBpZiAobGFzdFRhZyAhPSB2YWx1ZSkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmludmFsaWRFbmRUYWcoKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgaW50IGdldExhc3RUYWcoKSB7CisgICAgcmV0dXJuIGxhc3RUYWc7CisgIH0KKworICAvKioKKyAgICogUmVhZHMgYW5kIGRpc2NhcmRzIGEgc2luZ2xlIGZpZWxkLCBnaXZlbiBpdHMgdGFnIHZhbHVlLgorICAgKgorICAgKiBAcmV0dXJuIHtAY29kZSBmYWxzZX0gaWYgdGhlIHRhZyBpcyBhbiBlbmRncm91cCB0YWcsIGluIHdoaWNoIGNhc2UKKyAgICogICAgICAgICBub3RoaW5nIGlzIHNraXBwZWQuICBPdGhlcndpc2UsIHJldHVybnMge0Bjb2RlIHRydWV9LgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gc2tpcEZpZWxkKGZpbmFsIGludCB0YWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3dpdGNoIChXaXJlRm9ybWF0LmdldFRhZ1dpcmVUeXBlKHRhZykpIHsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9WQVJJTlQ6CisgICAgICAgIHNraXBSYXdWYXJpbnQoKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQ2NDoKKyAgICAgICAgc2tpcFJhd0J5dGVzKDgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgICBza2lwUmF3Qnl0ZXMocmVhZFJhd1ZhcmludDMyKCkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9TVEFSVF9HUk9VUDoKKyAgICAgICAgc2tpcE1lc3NhZ2UoKTsKKyAgICAgICAgY2hlY2tMYXN0VGFnV2FzKAorICAgICAgICAgIFdpcmVGb3JtYXQubWFrZVRhZyhXaXJlRm9ybWF0LmdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0VORF9HUk9VUDoKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0ZJWEVEMzI6CisgICAgICAgIHNraXBSYXdCeXRlcyg0KTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24uaW52YWxpZFdpcmVUeXBlKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGEgc2luZ2xlIGZpZWxkIGFuZCB3cml0ZXMgaXQgdG8gb3V0cHV0IGluIHdpcmUgZm9ybWF0LAorICAgKiBnaXZlbiBpdHMgdGFnIHZhbHVlLgorICAgKgorICAgKiBAcmV0dXJuIHtAY29kZSBmYWxzZX0gaWYgdGhlIHRhZyBpcyBhbiBlbmRncm91cCB0YWcsIGluIHdoaWNoIGNhc2UKKyAgICogICAgICAgICBub3RoaW5nIGlzIHNraXBwZWQuICBPdGhlcndpc2UsIHJldHVybnMge0Bjb2RlIHRydWV9LgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gc2tpcEZpZWxkKGZpbmFsIGludCB0YWcsIGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3dpdGNoIChXaXJlRm9ybWF0LmdldFRhZ1dpcmVUeXBlKHRhZykpIHsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9WQVJJTlQ6IHsKKyAgICAgICAgbG9uZyB2YWx1ZSA9IHJlYWRJbnQ2NCgpOworICAgICAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0YWcpOworICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyh2YWx1ZSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0ZJWEVENjQ6IHsKKyAgICAgICAgbG9uZyB2YWx1ZSA9IHJlYWRSYXdMaXR0bGVFbmRpYW42NCgpOworICAgICAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0YWcpOworICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0Tm9UYWcodmFsdWUpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOiB7CisgICAgICAgIEJ5dGVTdHJpbmcgdmFsdWUgPSByZWFkQnl0ZXMoKTsKKyAgICAgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIodGFnKTsKKyAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXNOb1RhZyh2YWx1ZSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQOiB7CisgICAgICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKHRhZyk7CisgICAgICAgIHNraXBNZXNzYWdlKG91dHB1dCk7CisgICAgICAgIGludCBlbmR0YWcgPSBXaXJlRm9ybWF0Lm1ha2VUYWcoV2lyZUZvcm1hdC5nZXRUYWdGaWVsZE51bWJlcih0YWcpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKTsKKyAgICAgICAgY2hlY2tMYXN0VGFnV2FzKGVuZHRhZyk7CisgICAgICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKGVuZHRhZyk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0VORF9HUk9VUDogeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQzMjogeworICAgICAgICBpbnQgdmFsdWUgPSByZWFkUmF3TGl0dGxlRW5kaWFuMzIoKTsKKyAgICAgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIodGFnKTsKKyAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24uaW52YWxpZFdpcmVUeXBlKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGFuZCBkaXNjYXJkcyBhbiBlbnRpcmUgbWVzc2FnZS4gIFRoaXMgd2lsbCByZWFkIGVpdGhlciB1bnRpbCBFT0YKKyAgICogb3IgdW50aWwgYW4gZW5kZ3JvdXAgdGFnLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCisgICAqLworICBwdWJsaWMgdm9pZCBza2lwTWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGZpbmFsIGludCB0YWcgPSByZWFkVGFnKCk7CisgICAgICBpZiAodGFnID09IDAgfHwgIXNraXBGaWVsZCh0YWcpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmVhZHMgYW4gZW50aXJlIG1lc3NhZ2UgYW5kIHdyaXRlcyBpdCB0byBvdXRwdXQgaW4gd2lyZSBmb3JtYXQuCisgICAqIFRoaXMgd2lsbCByZWFkIGVpdGhlciB1bnRpbCBFT0Ygb3IgdW50aWwgYW4gZW5kZ3JvdXAgdGFnLAorICAgKiB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCisgICAqLworICBwdWJsaWMgdm9pZCBza2lwTWVzc2FnZShDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGZpbmFsIGludCB0YWcgPSByZWFkVGFnKCk7CisgICAgICBpZiAodGFnID09IDAgfHwgIXNraXBGaWVsZCh0YWcsIG91dHB1dCkpIHsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb2xsZWN0cyB0aGUgYnl0ZXMgc2tpcHBlZCBhbmQgcmV0dXJucyB0aGUgZGF0YSBpbiBhIEJ5dGVCdWZmZXIuCisgICAqLworICBwcml2YXRlIGNsYXNzIFNraXBwZWREYXRhU2luayBpbXBsZW1lbnRzIFJlZmlsbENhbGxiYWNrIHsKKyAgICBwcml2YXRlIGludCBsYXN0UG9zID0gYnVmZmVyUG9zOworICAgIHByaXZhdGUgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVBcnJheVN0cmVhbTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG9uUmVmaWxsKCkgeworICAgICAgaWYgKGJ5dGVBcnJheVN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgIGJ5dGVBcnJheVN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIH0KKyAgICAgIGJ5dGVBcnJheVN0cmVhbS53cml0ZShidWZmZXIsIGxhc3RQb3MsIGJ1ZmZlclBvcyAtIGxhc3RQb3MpOworICAgICAgbGFzdFBvcyA9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBza2lwcGVkIGRhdGEgaW4gYSBCeXRlQnVmZmVyLiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZQorICAgICAqIGNhbGxlZCBvbmNlLgorICAgICAqLworICAgIEJ5dGVCdWZmZXIgZ2V0U2tpcHBlZERhdGEoKSB7CisgICAgICBpZiAoYnl0ZUFycmF5U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIud3JhcChidWZmZXIsIGxhc3RQb3MsIGJ1ZmZlclBvcyAtIGxhc3RQb3MpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgYnl0ZUFycmF5U3RyZWFtLndyaXRlKGJ1ZmZlciwgbGFzdFBvcywgYnVmZmVyUG9zKTsKKyAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIud3JhcChieXRlQXJyYXlTdHJlYW0udG9CeXRlQXJyYXkoKSk7CisgICAgICB9CisgICAgfQorICB9CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKiBSZWFkIGEge0Bjb2RlIGRvdWJsZX0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgZG91YmxlIHJlYWREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShyZWFkUmF3TGl0dGxlRW5kaWFuNjQoKSk7CisgIH0KKworICAvKiogUmVhZCBhIHtAY29kZSBmbG9hdH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgZmxvYXQgcmVhZEZsb2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQocmVhZFJhd0xpdHRsZUVuZGlhbjMyKCkpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgdWludDY0fSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBsb25nIHJlYWRVSW50NjQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3VmFyaW50NjQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBpbnQ2NH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkSW50NjQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3VmFyaW50NjQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBpbnQzMn0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgaW50IHJlYWRJbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHJlYWRSYXdWYXJpbnQzMigpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgZml4ZWQ2NH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkRml4ZWQ2NCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHJlYWRSYXdMaXR0bGVFbmRpYW42NCgpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgZml4ZWQzMn0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgaW50IHJlYWRGaXhlZDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCk7CisgIH0KKworICAvKiogUmVhZCBhIHtAY29kZSBib29sfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBib29sZWFuIHJlYWRCb29sKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd1ZhcmludDY0KCkgIT0gMDsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkIGEge0Bjb2RlIHN0cmluZ30gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLgorICAgKiBJZiB0aGUgc3RyZWFtIGNvbnRhaW5zIG1hbGZvcm1lZCBVVEYtOCwKKyAgICogcmVwbGFjZSB0aGUgb2ZmZW5kaW5nIGJ5dGVzIHdpdGggdGhlIHN0YW5kYXJkIFVURi04IHJlcGxhY2VtZW50IGNoYXJhY3Rlci4KKyAgICovCisgIHB1YmxpYyBTdHJpbmcgcmVhZFN0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IHNpemUgPSByZWFkUmF3VmFyaW50MzIoKTsKKyAgICBpZiAoc2l6ZSA8PSAoYnVmZmVyU2l6ZSAtIGJ1ZmZlclBvcykgJiYgc2l6ZSA+IDApIHsKKyAgICAgIC8vIEZhc3QgcGF0aDogIFdlIGFscmVhZHkgaGF2ZSB0aGUgYnl0ZXMgaW4gYSBjb250aWd1b3VzIGJ1ZmZlciwgc28KKyAgICAgIC8vICAganVzdCBjb3B5IGRpcmVjdGx5IGZyb20gaXQuCisgICAgICBmaW5hbCBTdHJpbmcgcmVzdWx0ID0gbmV3IFN0cmluZyhidWZmZXIsIGJ1ZmZlclBvcywgc2l6ZSwgIlVURi04Iik7CisgICAgICBidWZmZXJQb3MgKz0gc2l6ZTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfSBlbHNlIGlmIChzaXplID09IDApIHsKKyAgICAgIHJldHVybiAiIjsKKyAgICB9IGVsc2UgeworICAgICAgLy8gU2xvdyBwYXRoOiAgQnVpbGQgYSBieXRlIGFycmF5IGZpcnN0IHRoZW4gY29weSBpdC4KKyAgICAgIHJldHVybiBuZXcgU3RyaW5nKHJlYWRSYXdCeXRlc1Nsb3dQYXRoKHNpemUpLCAiVVRGLTgiKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmVhZCBhIHtAY29kZSBzdHJpbmd9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4KKyAgICogSWYgdGhlIHN0cmVhbSBjb250YWlucyBtYWxmb3JtZWQgVVRGLTgsCisgICAqIHRocm93IGV4Y2VwdGlvbiB7QGxpbmsgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9ufS4KKyAgICovCisgIHB1YmxpYyBTdHJpbmcgcmVhZFN0cmluZ1JlcXVpcmVVdGY4KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgc2l6ZSA9IHJlYWRSYXdWYXJpbnQzMigpOworICAgIGZpbmFsIGJ5dGVbXSBieXRlczsKKyAgICBpbnQgcG9zID0gYnVmZmVyUG9zOworICAgIGlmIChzaXplIDw9IChidWZmZXJTaXplIC0gcG9zKSAmJiBzaXplID4gMCkgeworICAgICAgLy8gRmFzdCBwYXRoOiAgV2UgYWxyZWFkeSBoYXZlIHRoZSBieXRlcyBpbiBhIGNvbnRpZ3VvdXMgYnVmZmVyLCBzbworICAgICAgLy8gICBqdXN0IGNvcHkgZGlyZWN0bHkgZnJvbSBpdC4KKyAgICAgIGJ5dGVzID0gYnVmZmVyOworICAgICAgYnVmZmVyUG9zID0gcG9zICsgc2l6ZTsKKyAgICB9IGVsc2UgaWYgKHNpemUgPT0gMCkgeworICAgICAgcmV0dXJuICIiOworICAgIH0gZWxzZSB7CisgICAgICAvLyBTbG93IHBhdGg6ICBCdWlsZCBhIGJ5dGUgYXJyYXkgZmlyc3QgdGhlbiBjb3B5IGl0LgorICAgICAgYnl0ZXMgPSByZWFkUmF3Qnl0ZXNTbG93UGF0aChzaXplKTsKKyAgICAgIHBvcyA9IDA7CisgICAgfQorICAgIC8vIFRPRE8obWFydGlucmIpOiBXZSBjb3VsZCBzYXZlIGEgcGFzcyBieSB2YWxpZGF0aW5nIHdoaWxlIGRlY29kaW5nLgorICAgIGlmICghVXRmOC5pc1ZhbGlkVXRmOChieXRlcywgcG9zLCBwb3MgKyBzaXplKSkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmludmFsaWRVdGY4KCk7CisgICAgfQorICAgIHJldHVybiBuZXcgU3RyaW5nKGJ5dGVzLCBwb3MsIHNpemUsICJVVEYtOCIpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgZ3JvdXB9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgcmVhZEdyb3VwKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHJlY3Vyc2lvbkRlcHRoID49IHJlY3Vyc2lvbkxpbWl0KSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ucmVjdXJzaW9uTGltaXRFeGNlZWRlZCgpOworICAgIH0KKyAgICArK3JlY3Vyc2lvbkRlcHRoOworICAgIGJ1aWxkZXIubWVyZ2VGcm9tKHRoaXMsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICBjaGVja0xhc3RUYWdXYXMoCisgICAgICBXaXJlRm9ybWF0Lm1ha2VUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKSk7CisgICAgLS1yZWN1cnNpb25EZXB0aDsKKyAgfQorCisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgZ3JvdXB9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IFQgcmVhZEdyb3VwKAorICAgICAgZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgZmluYWwgUGFyc2VyPFQ+IHBhcnNlciwKKyAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHJlY3Vyc2lvbkRlcHRoID49IHJlY3Vyc2lvbkxpbWl0KSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ucmVjdXJzaW9uTGltaXRFeGNlZWRlZCgpOworICAgIH0KKyAgICArK3JlY3Vyc2lvbkRlcHRoOworICAgIFQgcmVzdWx0ID0gcGFyc2VyLnBhcnNlUGFydGlhbEZyb20odGhpcywgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgIGNoZWNrTGFzdFRhZ1dhcygKKyAgICAgIFdpcmVGb3JtYXQubWFrZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApKTsKKyAgICAtLXJlY3Vyc2lvbkRlcHRoOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogUmVhZHMgYSB7QGNvZGUgZ3JvdXB9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbSBhbmQgbWVyZ2VzIGl0IGludG8gdGhlCisgICAqIGdpdmVuIHtAbGluayBVbmtub3duRmllbGRTZXR9LgorICAgKgorICAgKiBAZGVwcmVjYXRlZCBVbmtub3duRmllbGRTZXQuQnVpbGRlciBub3cgaW1wbGVtZW50cyBNZXNzYWdlTGl0ZS5CdWlsZGVyLCBzbworICAgKiAgICAgICAgICAgICB5b3UgY2FuIGp1c3QgY2FsbCB7QGxpbmsgI3JlYWRHcm91cH0uCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgdm9pZCByZWFkVW5rbm93bkdyb3VwKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXIpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFdlIGtub3cgdGhhdCBVbmtub3duRmllbGRTZXQgd2lsbCBpZ25vcmUgYW55IEV4dGVuc2lvblJlZ2lzdHJ5IHNvIGl0CisgICAgLy8gaXMgc2FmZSB0byBwYXNzIG51bGwgaGVyZS4gIChXZSBjYW4ndCBjYWxsCisgICAgLy8gRXh0ZW5zaW9uUmVnaXN0cnkuZ2V0RW1wdHlSZWdpc3RyeSgpIGJlY2F1c2UgdGhhdCB3b3VsZCBtYWtlIHRoaXMKKyAgICAvLyBjbGFzcyBkZXBlbmQgb24gRXh0ZW5zaW9uUmVnaXN0cnksIHdoaWNoIGlzIG5vdCBwYXJ0IG9mIHRoZSBsaXRlCisgICAgLy8gbGlicmFyeS4pCisgICAgcmVhZEdyb3VwKGZpZWxkTnVtYmVyLCBidWlsZGVyLCBudWxsKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCByZWFkTWVzc2FnZShmaW5hbCBNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IGxlbmd0aCA9IHJlYWRSYXdWYXJpbnQzMigpOworICAgIGlmIChyZWN1cnNpb25EZXB0aCA+PSByZWN1cnNpb25MaW1pdCkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLnJlY3Vyc2lvbkxpbWl0RXhjZWVkZWQoKTsKKyAgICB9CisgICAgZmluYWwgaW50IG9sZExpbWl0ID0gcHVzaExpbWl0KGxlbmd0aCk7CisgICAgKytyZWN1cnNpb25EZXB0aDsKKyAgICBidWlsZGVyLm1lcmdlRnJvbSh0aGlzLCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgY2hlY2tMYXN0VGFnV2FzKDApOworICAgIC0tcmVjdXJzaW9uRGVwdGg7CisgICAgcG9wTGltaXQob2xkTGltaXQpOworICB9CisKKworICAvKiogUmVhZCBhbiBlbWJlZGRlZCBtZXNzYWdlIGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IFQgcmVhZE1lc3NhZ2UoCisgICAgICBmaW5hbCBQYXJzZXI8VD4gcGFyc2VyLAorICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgbGVuZ3RoID0gcmVhZFJhd1ZhcmludDMyKCk7CisgICAgaWYgKHJlY3Vyc2lvbkRlcHRoID49IHJlY3Vyc2lvbkxpbWl0KSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ucmVjdXJzaW9uTGltaXRFeGNlZWRlZCgpOworICAgIH0KKyAgICBmaW5hbCBpbnQgb2xkTGltaXQgPSBwdXNoTGltaXQobGVuZ3RoKTsKKyAgICArK3JlY3Vyc2lvbkRlcHRoOworICAgIFQgcmVzdWx0ID0gcGFyc2VyLnBhcnNlUGFydGlhbEZyb20odGhpcywgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgIGNoZWNrTGFzdFRhZ1dhcygwKTsKKyAgICAtLXJlY3Vyc2lvbkRlcHRoOworICAgIHBvcExpbWl0KG9sZExpbWl0KTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgYnl0ZXN9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIEJ5dGVTdHJpbmcgcmVhZEJ5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgc2l6ZSA9IHJlYWRSYXdWYXJpbnQzMigpOworICAgIGlmIChzaXplIDw9IChidWZmZXJTaXplIC0gYnVmZmVyUG9zKSAmJiBzaXplID4gMCkgeworICAgICAgLy8gRmFzdCBwYXRoOiAgV2UgYWxyZWFkeSBoYXZlIHRoZSBieXRlcyBpbiBhIGNvbnRpZ3VvdXMgYnVmZmVyLCBzbworICAgICAgLy8gICBqdXN0IGNvcHkgZGlyZWN0bHkgZnJvbSBpdC4KKyAgICAgIGZpbmFsIEJ5dGVTdHJpbmcgcmVzdWx0ID0gYnVmZmVySXNJbW11dGFibGUgJiYgZW5hYmxlQWxpYXNpbmcKKyAgICAgICAgICA/IG5ldyBCb3VuZGVkQnl0ZVN0cmluZyhidWZmZXIsIGJ1ZmZlclBvcywgc2l6ZSkKKyAgICAgICAgICA6IEJ5dGVTdHJpbmcuY29weUZyb20oYnVmZmVyLCBidWZmZXJQb3MsIHNpemUpOworICAgICAgYnVmZmVyUG9zICs9IHNpemU7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0gZWxzZSBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICByZXR1cm4gQnl0ZVN0cmluZy5FTVBUWTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gU2xvdyBwYXRoOiAgQnVpbGQgYSBieXRlIGFycmF5IGZpcnN0IHRoZW4gY29weSBpdC4KKyAgICAgIHJldHVybiBuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcocmVhZFJhd0J5dGVzU2xvd1BhdGgoc2l6ZSkpOworICAgIH0KKyAgfQorCisgIC8qKiBSZWFkIGEge0Bjb2RlIGJ5dGVzfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBieXRlW10gcmVhZEJ5dGVBcnJheSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IHNpemUgPSByZWFkUmF3VmFyaW50MzIoKTsKKyAgICBpZiAoc2l6ZSA8PSAoYnVmZmVyU2l6ZSAtIGJ1ZmZlclBvcykgJiYgc2l6ZSA+IDApIHsKKyAgICAgIC8vIEZhc3QgcGF0aDogV2UgYWxyZWFkeSBoYXZlIHRoZSBieXRlcyBpbiBhIGNvbnRpZ3VvdXMgYnVmZmVyLCBzbworICAgICAgLy8ganVzdCBjb3B5IGRpcmVjdGx5IGZyb20gaXQuCisgICAgICBmaW5hbCBieXRlW10gcmVzdWx0ID0KKyAgICAgICAgICBBcnJheXMuY29weU9mUmFuZ2UoYnVmZmVyLCBidWZmZXJQb3MsIGJ1ZmZlclBvcyArIHNpemUpOworICAgICAgYnVmZmVyUG9zICs9IHNpemU7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0gZWxzZSB7CisgICAgICAvLyBTbG93IHBhdGg6IEJ1aWxkIGEgYnl0ZSBhcnJheSBmaXJzdCB0aGVuIGNvcHkgaXQuCisgICAgICByZXR1cm4gcmVhZFJhd0J5dGVzU2xvd1BhdGgoc2l6ZSk7CisgICAgfQorICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgYnl0ZXN9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIEJ5dGVCdWZmZXIgcmVhZEJ5dGVCdWZmZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIGludCBzaXplID0gcmVhZFJhd1ZhcmludDMyKCk7CisgICAgaWYgKHNpemUgPD0gKGJ1ZmZlclNpemUgLSBidWZmZXJQb3MpICYmIHNpemUgPiAwKSB7CisgICAgICAvLyBGYXN0IHBhdGg6IFdlIGFscmVhZHkgaGF2ZSB0aGUgYnl0ZXMgaW4gYSBjb250aWd1b3VzIGJ1ZmZlci4KKyAgICAgIC8vIFdoZW4gYWxpYXNpbmcgaXMgZW5hYmxlZCwgd2UgY2FuIHJldHVybiBhIEJ5dGVCdWZmZXIgcG9pbnRpbmcgZGlyZWN0bHkKKyAgICAgIC8vIGludG8gdGhlIHVuZGVybHlpbmcgYnl0ZSBhcnJheSB3aXRob3V0IGNvcHkgaWYgdGhlIENvZGVkSW5wdXRTdHJlYW0gaXMKKyAgICAgIC8vIGNvbnN0cnVjdGVkIGZyb20gYSBieXRlIGFycmF5LiBJZiBhbGlhc2luZyBpcyBkaXNhYmxlZCBvciB0aGUgaW5wdXQgaXMKKyAgICAgIC8vIGZyb20gYW4gSW5wdXRTdHJlYW0gb3IgQnl0ZVN0cmluZywgd2UgaGF2ZSB0byBtYWtlIGEgY29weSBvZiB0aGUgYnl0ZXMuCisgICAgICBCeXRlQnVmZmVyIHJlc3VsdCA9IGlucHV0ID09IG51bGwgJiYgIWJ1ZmZlcklzSW1tdXRhYmxlICYmIGVuYWJsZUFsaWFzaW5nCisgICAgICAgICAgPyBCeXRlQnVmZmVyLndyYXAoYnVmZmVyLCBidWZmZXJQb3MsIHNpemUpLnNsaWNlKCkKKyAgICAgICAgICA6IEJ5dGVCdWZmZXIud3JhcChBcnJheXMuY29weU9mUmFuZ2UoCisgICAgICAgICAgICAgIGJ1ZmZlciwgYnVmZmVyUG9zLCBidWZmZXJQb3MgKyBzaXplKSk7CisgICAgICBidWZmZXJQb3MgKz0gc2l6ZTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfSBlbHNlIGlmIChzaXplID09IDApIHsKKyAgICAgIHJldHVybiBJbnRlcm5hbC5FTVBUWV9CWVRFX0JVRkZFUjsKKyAgICB9IGVsc2UgeworICAgICAgLy8gU2xvdyBwYXRoOiBCdWlsZCBhIGJ5dGUgYXJyYXkgZmlyc3QgdGhlbiBjb3B5IGl0LgorICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIud3JhcChyZWFkUmF3Qnl0ZXNTbG93UGF0aChzaXplKSk7CisgICAgfQorICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgdWludDMyfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBpbnQgcmVhZFVJbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHJlYWRSYXdWYXJpbnQzMigpOworICB9CisKKyAgLyoqCisgICAqIFJlYWQgYW4gZW51bSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICBDYWxsZXIgaXMgcmVzcG9uc2libGUKKyAgICogZm9yIGNvbnZlcnRpbmcgdGhlIG51bWVyaWMgdmFsdWUgdG8gYW4gYWN0dWFsIGVudW0uCisgICAqLworICBwdWJsaWMgaW50IHJlYWRFbnVtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd1ZhcmludDMyKCk7CisgIH0KKworICAvKiogUmVhZCBhbiB7QGNvZGUgc2ZpeGVkMzJ9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIGludCByZWFkU0ZpeGVkMzIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3TGl0dGxlRW5kaWFuMzIoKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBzZml4ZWQ2NH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkU0ZpeGVkNjQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3TGl0dGxlRW5kaWFuNjQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBzaW50MzJ9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIGludCByZWFkU0ludDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZGVjb2RlWmlnWmFnMzIocmVhZFJhd1ZhcmludDMyKCkpOworICB9CisKKyAgLyoqIFJlYWQgYW4ge0Bjb2RlIHNpbnQ2NH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkU0ludDY0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZGVjb2RlWmlnWmFnNjQocmVhZFJhd1ZhcmludDY0KCkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogUmVhZCBhIHJhdyBWYXJpbnQgZnJvbSB0aGUgc3RyZWFtLiAgSWYgbGFyZ2VyIHRoYW4gMzIgYml0cywgZGlzY2FyZCB0aGUKKyAgICogdXBwZXIgYml0cy4KKyAgICovCisgIHB1YmxpYyBpbnQgcmVhZFJhd1ZhcmludDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBTZWUgaW1wbGVtZW50YXRpb24gbm90ZXMgZm9yIHJlYWRSYXdWYXJpbnQ2NAorIGZhc3RwYXRoOiB7CisgICAgICBpbnQgcG9zID0gYnVmZmVyUG9zOworCisgICAgICBpZiAoYnVmZmVyU2l6ZSA9PSBwb3MpIHsKKyAgICAgICAgYnJlYWsgZmFzdHBhdGg7CisgICAgICB9CisKKyAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIgPSB0aGlzLmJ1ZmZlcjsKKyAgICAgIGludCB4OworICAgICAgaWYgKCh4ID0gYnVmZmVyW3BvcysrXSkgPj0gMCkgeworICAgICAgICBidWZmZXJQb3MgPSBwb3M7CisgICAgICAgIHJldHVybiB4OworICAgICAgfSBlbHNlIGlmIChidWZmZXJTaXplIC0gcG9zIDwgOSkgeworICAgICAgICBicmVhayBmYXN0cGF0aDsKKyAgICAgIH0gZWxzZSBpZiAoKHggXj0gKGJ1ZmZlcltwb3MrK10gPDwgNykpIDwgMCkgeworICAgICAgICB4IF49ICh+MCA8PCA3KTsKKyAgICAgIH0gZWxzZSBpZiAoKHggXj0gKGJ1ZmZlcltwb3MrK10gPDwgMTQpKSA+PSAwKSB7CisgICAgICAgIHggXj0gKH4wIDw8IDcpIF4gKH4wIDw8IDE0KTsKKyAgICAgIH0gZWxzZSBpZiAoKHggXj0gKGJ1ZmZlcltwb3MrK10gPDwgMjEpKSA8IDApIHsKKyAgICAgICAgeCBePSAofjAgPDwgNykgXiAofjAgPDwgMTQpIF4gKH4wIDw8IDIxKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGludCB5ID0gYnVmZmVyW3BvcysrXTsKKyAgICAgICAgeCBePSB5IDw8IDI4OworICAgICAgICB4IF49ICh+MCA8PCA3KSBeICh+MCA8PCAxNCkgXiAofjAgPDwgMjEpIF4gKH4wIDw8IDI4KTsKKyAgICAgICAgaWYgKHkgPCAwICYmCisgICAgICAgICAgICBidWZmZXJbcG9zKytdIDwgMCAmJgorICAgICAgICAgICAgYnVmZmVyW3BvcysrXSA8IDAgJiYKKyAgICAgICAgICAgIGJ1ZmZlcltwb3MrK10gPCAwICYmCisgICAgICAgICAgICBidWZmZXJbcG9zKytdIDwgMCAmJgorICAgICAgICAgICAgYnVmZmVyW3BvcysrXSA8IDApIHsKKyAgICAgICAgICBicmVhayBmYXN0cGF0aDsgIC8vIFdpbGwgdGhyb3cgbWFsZm9ybWVkVmFyaW50KCkKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnVmZmVyUG9zID0gcG9zOworICAgICAgcmV0dXJuIHg7CisgICAgfQorICAgIHJldHVybiAoaW50KSByZWFkUmF3VmFyaW50NjRTbG93UGF0aCgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNraXBSYXdWYXJpbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChidWZmZXJTaXplIC0gYnVmZmVyUG9zID49IDEwKSB7CisgICAgICBmaW5hbCBieXRlW10gYnVmZmVyID0gdGhpcy5idWZmZXI7CisgICAgICBpbnQgcG9zID0gYnVmZmVyUG9zOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgIGlmIChidWZmZXJbcG9zKytdID49IDApIHsKKyAgICAgICAgICBidWZmZXJQb3MgPSBwb3M7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHNraXBSYXdWYXJpbnRTbG93UGF0aCgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNraXBSYXdWYXJpbnRTbG93UGF0aCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICBpZiAocmVhZFJhd0J5dGUoKSA+PSAwKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9CisgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLm1hbGZvcm1lZFZhcmludCgpOworICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGEgdmFyaW50IGZyb20gdGhlIGlucHV0IG9uZSBieXRlIGF0IGEgdGltZSwgc28gdGhhdCBpdCBkb2VzIG5vdAorICAgKiByZWFkIGFueSBieXRlcyBhZnRlciB0aGUgZW5kIG9mIHRoZSB2YXJpbnQuICBJZiB5b3Ugc2ltcGx5IHdyYXBwZWQgdGhlCisgICAqIHN0cmVhbSBpbiBhIENvZGVkSW5wdXRTdHJlYW0gYW5kIHVzZWQge0BsaW5rICNyZWFkUmF3VmFyaW50MzIoSW5wdXRTdHJlYW0pfQorICAgKiB0aGVuIHlvdSB3b3VsZCBwcm9iYWJseSBlbmQgdXAgcmVhZGluZyBwYXN0IHRoZSBlbmQgb2YgdGhlIHZhcmludCBzaW5jZQorICAgKiBDb2RlZElucHV0U3RyZWFtIGJ1ZmZlcnMgaXRzIGlucHV0LgorICAgKi8KKyAgc3RhdGljIGludCByZWFkUmF3VmFyaW50MzIoZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IGZpcnN0Qnl0ZSA9IGlucHV0LnJlYWQoKTsKKyAgICBpZiAoZmlyc3RCeXRlID09IC0xKSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24udHJ1bmNhdGVkTWVzc2FnZSgpOworICAgIH0KKyAgICByZXR1cm4gcmVhZFJhd1ZhcmludDMyKGZpcnN0Qnl0ZSwgaW5wdXQpOworICB9CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNyZWFkUmF3VmFyaW50MzIoSW5wdXRTdHJlYW0pfSwgYnV0IGV4cGVjdHMgdGhhdCB0aGUgY2FsbGVyCisgICAqIGhhcyBhbHJlYWR5IHJlYWQgb25lIGJ5dGUuICBUaGlzIGFsbG93cyB0aGUgY2FsbGVyIHRvIGRldGVybWluZSBpZiBFT0YKKyAgICogaGFzIGJlZW4gcmVhY2hlZCBiZWZvcmUgYXR0ZW1wdGluZyB0byByZWFkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcmVhZFJhd1ZhcmludDMyKAorICAgICAgZmluYWwgaW50IGZpcnN0Qnl0ZSwgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKChmaXJzdEJ5dGUgJiAweDgwKSA9PSAwKSB7CisgICAgICByZXR1cm4gZmlyc3RCeXRlOworICAgIH0KKworICAgIGludCByZXN1bHQgPSBmaXJzdEJ5dGUgJiAweDdmOworICAgIGludCBvZmZzZXQgPSA3OworICAgIGZvciAoOyBvZmZzZXQgPCAzMjsgb2Zmc2V0ICs9IDcpIHsKKyAgICAgIGZpbmFsIGludCBiID0gaW5wdXQucmVhZCgpOworICAgICAgaWYgKGIgPT0gLTEpIHsKKyAgICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLnRydW5jYXRlZE1lc3NhZ2UoKTsKKyAgICAgIH0KKyAgICAgIHJlc3VsdCB8PSAoYiAmIDB4N2YpIDw8IG9mZnNldDsKKyAgICAgIGlmICgoYiAmIDB4ODApID09IDApIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gS2VlcCByZWFkaW5nIHVwIHRvIDY0IGJpdHMuCisgICAgZm9yICg7IG9mZnNldCA8IDY0OyBvZmZzZXQgKz0gNykgeworICAgICAgZmluYWwgaW50IGIgPSBpbnB1dC5yZWFkKCk7CisgICAgICBpZiAoYiA9PSAtMSkgeworICAgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24udHJ1bmNhdGVkTWVzc2FnZSgpOworICAgICAgfQorICAgICAgaWYgKChiICYgMHg4MCkgPT0gMCkgeworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgIH0KKyAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ubWFsZm9ybWVkVmFyaW50KCk7CisgIH0KKworICAvKiogUmVhZCBhIHJhdyBWYXJpbnQgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkUmF3VmFyaW50NjQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIEltcGxlbWVudGF0aW9uIG5vdGVzOgorICAgIC8vCisgICAgLy8gT3B0aW1pemVkIGZvciBvbmUtYnl0ZSB2YWx1ZXMsIGV4cGVjdGVkIHRvIGJlIGNvbW1vbi4KKyAgICAvLyBUaGUgcGFydGljdWxhciBjb2RlIGJlbG93IHdhcyBzZWxlY3RlZCBmcm9tIHZhcmlvdXMgY2FuZGlkYXRlcworICAgIC8vIGVtcGlyaWNhbGx5LCBieSB3aW5uaW5nIFZhcmludEJlbmNobWFyay4KKyAgICAvLworICAgIC8vIFNpZ24gZXh0ZW5zaW9uIG9mIChzaWduZWQpIEphdmEgYnl0ZXMgaXMgdXN1YWxseSBhIG51aXNhbmNlLCBidXQKKyAgICAvLyB3ZSBleHBsb2l0IGl0IGhlcmUgdG8gbW9yZSBlYXNpbHkgb2J0YWluIHRoZSBzaWduIG9mIGJ5dGVzIHJlYWQuCisgICAgLy8gSW5zdGVhZCBvZiBjbGVhbmluZyB1cCB0aGUgc2lnbiBleHRlbnNpb24gYml0cyBieSBtYXNraW5nIGVhZ2VybHksCisgICAgLy8gd2UgZGVsYXkgdW50aWwgd2UgZmluZCB0aGUgZmluYWwgKHBvc2l0aXZlKSBieXRlLCB3aGVuIHdlIGNsZWFyIGFsbAorICAgIC8vIGFjY3VtdWxhdGVkIGJpdHMgd2l0aCBvbmUgeG9yLiAgV2UgZGVwZW5kIG9uIGphdmFjIHRvIGNvbnN0YW50IGZvbGQuCisgZmFzdHBhdGg6IHsKKyAgICAgIGludCBwb3MgPSBidWZmZXJQb3M7CisKKyAgICAgIGlmIChidWZmZXJTaXplID09IHBvcykgeworICAgICAgICBicmVhayBmYXN0cGF0aDsKKyAgICAgIH0KKworICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IHRoaXMuYnVmZmVyOworICAgICAgbG9uZyB4OworICAgICAgaW50IHk7CisgICAgICBpZiAoKHkgPSBidWZmZXJbcG9zKytdKSA+PSAwKSB7CisgICAgICAgIGJ1ZmZlclBvcyA9IHBvczsKKyAgICAgICAgcmV0dXJuIHk7CisgICAgICB9IGVsc2UgaWYgKGJ1ZmZlclNpemUgLSBwb3MgPCA5KSB7CisgICAgICAgIGJyZWFrIGZhc3RwYXRoOworICAgICAgfSBlbHNlIGlmICgoeSBePSAoYnVmZmVyW3BvcysrXSA8PCA3KSkgPCAwKSB7CisgICAgICAgIHggPSB5IF4gKH4wIDw8IDcpOworICAgICAgfSBlbHNlIGlmICgoeSBePSAoYnVmZmVyW3BvcysrXSA8PCAxNCkpID49IDApIHsKKyAgICAgICAgeCA9IHkgXiAoKH4wIDw8IDcpIF4gKH4wIDw8IDE0KSk7CisgICAgICB9IGVsc2UgaWYgKCh5IF49IChidWZmZXJbcG9zKytdIDw8IDIxKSkgPCAwKSB7CisgICAgICAgIHggPSB5IF4gKCh+MCA8PCA3KSBeICh+MCA8PCAxNCkgXiAofjAgPDwgMjEpKTsKKyAgICAgIH0gZWxzZSBpZiAoKHggPSAoKGxvbmcpIHkpIF4gKChsb25nKSBidWZmZXJbcG9zKytdIDw8IDI4KSkgPj0gMEwpIHsKKyAgICAgICAgeCBePSAofjBMIDw8IDcpIF4gKH4wTCA8PCAxNCkgXiAofjBMIDw8IDIxKSBeICh+MEwgPDwgMjgpOworICAgICAgfSBlbHNlIGlmICgoeCBePSAoKGxvbmcpIGJ1ZmZlcltwb3MrK10gPDwgMzUpKSA8IDBMKSB7CisgICAgICAgIHggXj0gKH4wTCA8PCA3KSBeICh+MEwgPDwgMTQpIF4gKH4wTCA8PCAyMSkgXiAofjBMIDw8IDI4KSBeICh+MEwgPDwgMzUpOworICAgICAgfSBlbHNlIGlmICgoeCBePSAoKGxvbmcpIGJ1ZmZlcltwb3MrK10gPDwgNDIpKSA+PSAwTCkgeworICAgICAgICB4IF49ICh+MEwgPDwgNykgXiAofjBMIDw8IDE0KSBeICh+MEwgPDwgMjEpIF4gKH4wTCA8PCAyOCkgXiAofjBMIDw8IDM1KSBeICh+MEwgPDwgNDIpOworICAgICAgfSBlbHNlIGlmICgoeCBePSAoKGxvbmcpIGJ1ZmZlcltwb3MrK10gPDwgNDkpKSA8IDBMKSB7CisgICAgICAgIHggXj0gKH4wTCA8PCA3KSBeICh+MEwgPDwgMTQpIF4gKH4wTCA8PCAyMSkgXiAofjBMIDw8IDI4KSBeICh+MEwgPDwgMzUpIF4gKH4wTCA8PCA0MikKKyAgICAgICAgICAgIF4gKH4wTCA8PCA0OSk7CisgICAgICB9IGVsc2UgeworICAgICAgICB4IF49ICgobG9uZykgYnVmZmVyW3BvcysrXSA8PCA1Nik7CisgICAgICAgIHggXj0gKH4wTCA8PCA3KSBeICh+MEwgPDwgMTQpIF4gKH4wTCA8PCAyMSkgXiAofjBMIDw8IDI4KSBeICh+MEwgPDwgMzUpIF4gKH4wTCA8PCA0MikKKyAgICAgICAgICAgIF4gKH4wTCA8PCA0OSkgXiAofjBMIDw8IDU2KTsKKyAgICAgICAgaWYgKHggPCAwTCkgeworICAgICAgICAgIGlmIChidWZmZXJbcG9zKytdIDwgMEwpIHsKKyAgICAgICAgICAgIGJyZWFrIGZhc3RwYXRoOyAgLy8gV2lsbCB0aHJvdyBtYWxmb3JtZWRWYXJpbnQoKQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnVmZmVyUG9zID0gcG9zOworICAgICAgcmV0dXJuIHg7CisgICAgfQorICAgIHJldHVybiByZWFkUmF3VmFyaW50NjRTbG93UGF0aCgpOworICB9CisKKyAgLyoqIFZhcmlhbnQgb2YgcmVhZFJhd1ZhcmludDY0IGZvciB3aGVuIHVuY29tZm9ydGFibHkgY2xvc2UgdG8gdGhlIGxpbWl0LiAqLworICAvKiBWaXNpYmxlIGZvciB0ZXN0aW5nICovCisgIGxvbmcgcmVhZFJhd1ZhcmludDY0U2xvd1BhdGgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgcmVzdWx0ID0gMDsKKyAgICBmb3IgKGludCBzaGlmdCA9IDA7IHNoaWZ0IDwgNjQ7IHNoaWZ0ICs9IDcpIHsKKyAgICAgIGZpbmFsIGJ5dGUgYiA9IHJlYWRSYXdCeXRlKCk7CisgICAgICByZXN1bHQgfD0gKGxvbmcpIChiICYgMHg3RikgPDwgc2hpZnQ7CisgICAgICBpZiAoKGIgJiAweDgwKSA9PSAwKSB7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9CisgICAgfQorICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5tYWxmb3JtZWRWYXJpbnQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGEgMzItYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlciBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBpbnQgcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgcG9zID0gYnVmZmVyUG9zOworCisgICAgLy8gaGFuZC1pbmxpbmVkIGVuc3VyZUF2YWlsYWJsZSg0KTsKKyAgICBpZiAoYnVmZmVyU2l6ZSAtIHBvcyA8IDQpIHsKKyAgICAgIHJlZmlsbEJ1ZmZlcig0KTsKKyAgICAgIHBvcyA9IGJ1ZmZlclBvczsKKyAgICB9CisKKyAgICBmaW5hbCBieXRlW10gYnVmZmVyID0gdGhpcy5idWZmZXI7CisgICAgYnVmZmVyUG9zID0gcG9zICsgNDsKKyAgICByZXR1cm4gKCgoYnVmZmVyW3Bvc10gICAgICYgMHhmZikpICAgICAgIHwKKyAgICAgICAgICAgICgoYnVmZmVyW3BvcyArIDFdICYgMHhmZikgPDwgIDgpIHwKKyAgICAgICAgICAgICgoYnVmZmVyW3BvcyArIDJdICYgMHhmZikgPDwgMTYpIHwKKyAgICAgICAgICAgICgoYnVmZmVyW3BvcyArIDNdICYgMHhmZikgPDwgMjQpKTsKKyAgfQorCisgIC8qKiBSZWFkIGEgNjQtYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlciBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBsb25nIHJlYWRSYXdMaXR0bGVFbmRpYW42NCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IHBvcyA9IGJ1ZmZlclBvczsKKworICAgIC8vIGhhbmQtaW5saW5lZCBlbnN1cmVBdmFpbGFibGUoOCk7CisgICAgaWYgKGJ1ZmZlclNpemUgLSBwb3MgPCA4KSB7CisgICAgICByZWZpbGxCdWZmZXIoOCk7CisgICAgICBwb3MgPSBidWZmZXJQb3M7CisgICAgfQorCisgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IHRoaXMuYnVmZmVyOworICAgIGJ1ZmZlclBvcyA9IHBvcyArIDg7CisgICAgcmV0dXJuICgoKChsb25nKSBidWZmZXJbcG9zXSAgICAgJiAweGZmTCkpICAgICAgIHwKKyAgICAgICAgICAgICgoKGxvbmcpIGJ1ZmZlcltwb3MgKyAxXSAmIDB4ZmZMKSA8PCAgOCkgfAorICAgICAgICAgICAgKCgobG9uZykgYnVmZmVyW3BvcyArIDJdICYgMHhmZkwpIDw8IDE2KSB8CisgICAgICAgICAgICAoKChsb25nKSBidWZmZXJbcG9zICsgM10gJiAweGZmTCkgPDwgMjQpIHwKKyAgICAgICAgICAgICgoKGxvbmcpIGJ1ZmZlcltwb3MgKyA0XSAmIDB4ZmZMKSA8PCAzMikgfAorICAgICAgICAgICAgKCgobG9uZykgYnVmZmVyW3BvcyArIDVdICYgMHhmZkwpIDw8IDQwKSB8CisgICAgICAgICAgICAoKChsb25nKSBidWZmZXJbcG9zICsgNl0gJiAweGZmTCkgPDwgNDgpIHwKKyAgICAgICAgICAgICgoKGxvbmcpIGJ1ZmZlcltwb3MgKyA3XSAmIDB4ZmZMKSA8PCA1NikpOworICB9CisKKyAgLyoqCisgICAqIERlY29kZSBhIFppZ1phZy1lbmNvZGVkIDMyLWJpdCB2YWx1ZS4gIFppZ1phZyBlbmNvZGVzIHNpZ25lZCBpbnRlZ2VycworICAgKiBpbnRvIHZhbHVlcyB0aGF0IGNhbiBiZSBlZmZpY2llbnRseSBlbmNvZGVkIHdpdGggdmFyaW50LiAgKE90aGVyd2lzZSwKKyAgICogbmVnYXRpdmUgdmFsdWVzIG11c3QgYmUgc2lnbi1leHRlbmRlZCB0byA2NCBiaXRzIHRvIGJlIHZhcmludCBlbmNvZGVkLAorICAgKiB0aHVzIGFsd2F5cyB0YWtpbmcgMTAgYnl0ZXMgb24gdGhlIHdpcmUuKQorICAgKgorICAgKiBAcGFyYW0gbiBBbiB1bnNpZ25lZCAzMi1iaXQgaW50ZWdlciwgc3RvcmVkIGluIGEgc2lnbmVkIGludCBiZWNhdXNlCisgICAqICAgICAgICAgIEphdmEgaGFzIG5vIGV4cGxpY2l0IHVuc2lnbmVkIHN1cHBvcnQuCisgICAqIEByZXR1cm4gQSBzaWduZWQgMzItYml0IGludGVnZXIuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBkZWNvZGVaaWdaYWczMihmaW5hbCBpbnQgbikgeworICAgIHJldHVybiAobiA+Pj4gMSkgXiAtKG4gJiAxKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWNvZGUgYSBaaWdaYWctZW5jb2RlZCA2NC1iaXQgdmFsdWUuICBaaWdaYWcgZW5jb2RlcyBzaWduZWQgaW50ZWdlcnMKKyAgICogaW50byB2YWx1ZXMgdGhhdCBjYW4gYmUgZWZmaWNpZW50bHkgZW5jb2RlZCB3aXRoIHZhcmludC4gIChPdGhlcndpc2UsCisgICAqIG5lZ2F0aXZlIHZhbHVlcyBtdXN0IGJlIHNpZ24tZXh0ZW5kZWQgdG8gNjQgYml0cyB0byBiZSB2YXJpbnQgZW5jb2RlZCwKKyAgICogdGh1cyBhbHdheXMgdGFraW5nIDEwIGJ5dGVzIG9uIHRoZSB3aXJlLikKKyAgICoKKyAgICogQHBhcmFtIG4gQW4gdW5zaWduZWQgNjQtYml0IGludGVnZXIsIHN0b3JlZCBpbiBhIHNpZ25lZCBpbnQgYmVjYXVzZQorICAgKiAgICAgICAgICBKYXZhIGhhcyBubyBleHBsaWNpdCB1bnNpZ25lZCBzdXBwb3J0LgorICAgKiBAcmV0dXJuIEEgc2lnbmVkIDY0LWJpdCBpbnRlZ2VyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGRlY29kZVppZ1phZzY0KGZpbmFsIGxvbmcgbikgeworICAgIHJldHVybiAobiA+Pj4gMSkgXiAtKG4gJiAxKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmZmVyOworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYnVmZmVySXNJbW11dGFibGU7CisgIHByaXZhdGUgaW50IGJ1ZmZlclNpemU7CisgIHByaXZhdGUgaW50IGJ1ZmZlclNpemVBZnRlckxpbWl0OworICBwcml2YXRlIGludCBidWZmZXJQb3M7CisgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQ7CisgIHByaXZhdGUgaW50IGxhc3RUYWc7CisgIHByaXZhdGUgYm9vbGVhbiBlbmFibGVBbGlhc2luZyA9IGZhbHNlOworCisgIC8qKgorICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgYmVmb3JlIHRoZSBjdXJyZW50IGJ1ZmZlci4gIFRoZSB0b3RhbAorICAgKiBieXRlcyByZWFkIHVwIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGNhbiBiZSBjb21wdXRlZCBhcworICAgKiB7QGNvZGUgdG90YWxCeXRlc1JldGlyZWQgKyBidWZmZXJQb3N9LiAgVGhpcyB2YWx1ZSBtYXkgYmUgbmVnYXRpdmUgaWYKKyAgICogcmVhZGluZyBzdGFydGVkIGluIHRoZSBtaWRkbGUgb2YgdGhlIGN1cnJlbnQgYnVmZmVyIChlLmcuIGlmIHRoZQorICAgKiBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgYnl0ZSBhcnJheSBhbmQgYW4gb2Zmc2V0IHdhcyB1c2VkKS4KKyAgICovCisgIHByaXZhdGUgaW50IHRvdGFsQnl0ZXNSZXRpcmVkOworCisgIC8qKiBUaGUgYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgY3VycmVudCBtZXNzYWdlLiAqLworICBwcml2YXRlIGludCBjdXJyZW50TGltaXQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKworICAvKiogU2VlIHNldFJlY3Vyc2lvbkxpbWl0KCkgKi8KKyAgcHJpdmF0ZSBpbnQgcmVjdXJzaW9uRGVwdGg7CisgIHByaXZhdGUgaW50IHJlY3Vyc2lvbkxpbWl0ID0gREVGQVVMVF9SRUNVUlNJT05fTElNSVQ7CisKKyAgLyoqIFNlZSBzZXRTaXplTGltaXQoKSAqLworICBwcml2YXRlIGludCBzaXplTGltaXQgPSBERUZBVUxUX1NJWkVfTElNSVQ7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfUkVDVVJTSU9OX0xJTUlUID0gMTAwOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TSVpFX0xJTUlUID0gNjQgPDwgMjA7ICAvLyA2NE1CCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfU0laRSA9IDQwOTY7CisKKyAgcHJpdmF0ZSBDb2RlZElucHV0U3RyZWFtKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHsKKyAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjsKKyAgICBidWZmZXJTaXplID0gb2ZmICsgbGVuOworICAgIGJ1ZmZlclBvcyA9IG9mZjsKKyAgICB0b3RhbEJ5dGVzUmV0aXJlZCA9IC1vZmY7CisgICAgaW5wdXQgPSBudWxsOworICAgIGJ1ZmZlcklzSW1tdXRhYmxlID0gZmFsc2U7CisgIH0KKworICBwcml2YXRlIENvZGVkSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQpIHsKKyAgICBidWZmZXIgPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CisgICAgYnVmZmVyU2l6ZSA9IDA7CisgICAgYnVmZmVyUG9zID0gMDsKKyAgICB0b3RhbEJ5dGVzUmV0aXJlZCA9IDA7CisgICAgdGhpcy5pbnB1dCA9IGlucHV0OworICAgIGJ1ZmZlcklzSW1tdXRhYmxlID0gZmFsc2U7CisgIH0KKworICBwcml2YXRlIENvZGVkSW5wdXRTdHJlYW0oZmluYWwgTGl0ZXJhbEJ5dGVTdHJpbmcgYnl0ZVN0cmluZykgeworICAgIGJ1ZmZlciA9IGJ5dGVTdHJpbmcuYnl0ZXM7CisgICAgYnVmZmVyUG9zID0gYnl0ZVN0cmluZy5nZXRPZmZzZXRJbnRvQnl0ZXMoKTsKKyAgICBidWZmZXJTaXplID0gYnVmZmVyUG9zICsgYnl0ZVN0cmluZy5zaXplKCk7CisgICAgdG90YWxCeXRlc1JldGlyZWQgPSAtYnVmZmVyUG9zOworICAgIGlucHV0ID0gbnVsbDsKKyAgICBidWZmZXJJc0ltbXV0YWJsZSA9IHRydWU7CisgIH0KKworICBwdWJsaWMgdm9pZCBlbmFibGVBbGlhc2luZyhib29sZWFuIGVuYWJsZWQpIHsKKyAgICB0aGlzLmVuYWJsZUFsaWFzaW5nID0gZW5hYmxlZDsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIG1heGltdW0gbWVzc2FnZSByZWN1cnNpb24gZGVwdGguICBJbiBvcmRlciB0byBwcmV2ZW50IG1hbGljaW91cworICAgKiBtZXNzYWdlcyBmcm9tIGNhdXNpbmcgc3RhY2sgb3ZlcmZsb3dzLCB7QGNvZGUgQ29kZWRJbnB1dFN0cmVhbX0gbGltaXRzCisgICAqIGhvdyBkZWVwbHkgbWVzc2FnZXMgbWF5IGJlIG5lc3RlZC4gIFRoZSBkZWZhdWx0IGxpbWl0IGlzIDY0LgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBvbGQgbGltaXQuCisgICAqLworICBwdWJsaWMgaW50IHNldFJlY3Vyc2lvbkxpbWl0KGZpbmFsIGludCBsaW1pdCkgeworICAgIGlmIChsaW1pdCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJSZWN1cnNpb24gbGltaXQgY2Fubm90IGJlIG5lZ2F0aXZlOiAiICsgbGltaXQpOworICAgIH0KKyAgICBmaW5hbCBpbnQgb2xkTGltaXQgPSByZWN1cnNpb25MaW1pdDsKKyAgICByZWN1cnNpb25MaW1pdCA9IGxpbWl0OworICAgIHJldHVybiBvbGRMaW1pdDsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIG1heGltdW0gbWVzc2FnZSBzaXplLiAgSW4gb3JkZXIgdG8gcHJldmVudCBtYWxpY2lvdXMKKyAgICogbWVzc2FnZXMgZnJvbSBleGhhdXN0aW5nIG1lbW9yeSBvciBjYXVzaW5nIGludGVnZXIgb3ZlcmZsb3dzLAorICAgKiB7QGNvZGUgQ29kZWRJbnB1dFN0cmVhbX0gbGltaXRzIGhvdyBsYXJnZSBhIG1lc3NhZ2UgbWF5IGJlLgorICAgKiBUaGUgZGVmYXVsdCBsaW1pdCBpcyA2NE1CLiAgWW91IHNob3VsZCBzZXQgdGhpcyBsaW1pdCBhcyBzbWFsbAorICAgKiBhcyB5b3UgY2FuIHdpdGhvdXQgaGFybWluZyB5b3VyIGFwcCdzIGZ1bmN0aW9uYWxpdHkuICBOb3RlIHRoYXQKKyAgICogc2l6ZSBsaW1pdHMgb25seSBhcHBseSB3aGVuIHJlYWRpbmcgZnJvbSBhbiB7QGNvZGUgSW5wdXRTdHJlYW19LCBub3QKKyAgICogd2hlbiBjb25zdHJ1Y3RlZCBhcm91bmQgYSByYXcgYnl0ZSBhcnJheSAobm9yIHdpdGgKKyAgICoge0BsaW5rIEJ5dGVTdHJpbmcjbmV3Q29kZWRJbnB1dH0pLgorICAgKiA8cD4KKyAgICogSWYgeW91IHdhbnQgdG8gcmVhZCBzZXZlcmFsIG1lc3NhZ2VzIGZyb20gYSBzaW5nbGUgQ29kZWRJbnB1dFN0cmVhbSwgeW91CisgICAqIGNvdWxkIGNhbGwge0BsaW5rICNyZXNldFNpemVDb3VudGVyKCl9IGFmdGVyIGVhY2ggb25lIHRvIGF2b2lkIGhpdHRpbmcgdGhlCisgICAqIHNpemUgbGltaXQuCisgICAqCisgICAqIEByZXR1cm4gdGhlIG9sZCBsaW1pdC4KKyAgICovCisgIHB1YmxpYyBpbnQgc2V0U2l6ZUxpbWl0KGZpbmFsIGludCBsaW1pdCkgeworICAgIGlmIChsaW1pdCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJTaXplIGxpbWl0IGNhbm5vdCBiZSBuZWdhdGl2ZTogIiArIGxpbWl0KTsKKyAgICB9CisgICAgZmluYWwgaW50IG9sZExpbWl0ID0gc2l6ZUxpbWl0OworICAgIHNpemVMaW1pdCA9IGxpbWl0OworICAgIHJldHVybiBvbGRMaW1pdDsKKyAgfQorCisgIC8qKgorICAgKiBSZXNldHMgdGhlIGN1cnJlbnQgc2l6ZSBjb3VudGVyIHRvIHplcm8gKHNlZSB7QGxpbmsgI3NldFNpemVMaW1pdChpbnQpfSkuCisgICAqLworICBwdWJsaWMgdm9pZCByZXNldFNpemVDb3VudGVyKCkgeworICAgIHRvdGFsQnl0ZXNSZXRpcmVkID0gLWJ1ZmZlclBvczsKKyAgfQorCisgIC8qKgorICAgKiBTZXRzIHtAY29kZSBjdXJyZW50TGltaXR9IHRvIChjdXJyZW50IHBvc2l0aW9uKSArIHtAY29kZSBieXRlTGltaXR9LiAgVGhpcworICAgKiBpcyBjYWxsZWQgd2hlbiBkZXNjZW5kaW5nIGludG8gYSBsZW5ndGgtZGVsaW1pdGVkIGVtYmVkZGVkIG1lc3NhZ2UuCisgICAqCisgICAqIDxwPk5vdGUgdGhhdCB7QGNvZGUgcHVzaExpbWl0KCl9IGRvZXMgTk9UIGFmZmVjdCBob3cgbWFueSBieXRlcyB0aGUKKyAgICoge0Bjb2RlIENvZGVkSW5wdXRTdHJlYW19IHJlYWRzIGZyb20gYW4gdW5kZXJseWluZyB7QGNvZGUgSW5wdXRTdHJlYW19IHdoZW4KKyAgICogcmVmcmVzaGluZyBpdHMgYnVmZmVyLiAgSWYgeW91IG5lZWQgdG8gcHJldmVudCByZWFkaW5nIHBhc3QgYSBjZXJ0YWluCisgICAqIHBvaW50IGluIHRoZSB1bmRlcmx5aW5nIHtAY29kZSBJbnB1dFN0cmVhbX0gKGUuZy4gYmVjYXVzZSB5b3UgZXhwZWN0IGl0IHRvCisgICAqIGNvbnRhaW4gbW9yZSBkYXRhIGFmdGVyIHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2Ugd2hpY2ggeW91IG5lZWQgdG8gaGFuZGxlCisgICAqIGRpZmZlcmVudGx5KSB0aGVuIHlvdSBtdXN0IHBsYWNlIGEgd3JhcHBlciBhcm91bmQgeW91ciB7QGNvZGUgSW5wdXRTdHJlYW19CisgICAqIHdoaWNoIGxpbWl0cyB0aGUgYW1vdW50IG9mIGRhdGEgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIGl0LgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBvbGQgbGltaXQuCisgICAqLworICBwdWJsaWMgaW50IHB1c2hMaW1pdChpbnQgYnl0ZUxpbWl0KSB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICBpZiAoYnl0ZUxpbWl0IDwgMCkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLm5lZ2F0aXZlU2l6ZSgpOworICAgIH0KKyAgICBieXRlTGltaXQgKz0gdG90YWxCeXRlc1JldGlyZWQgKyBidWZmZXJQb3M7CisgICAgZmluYWwgaW50IG9sZExpbWl0ID0gY3VycmVudExpbWl0OworICAgIGlmIChieXRlTGltaXQgPiBvbGRMaW1pdCkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLnRydW5jYXRlZE1lc3NhZ2UoKTsKKyAgICB9CisgICAgY3VycmVudExpbWl0ID0gYnl0ZUxpbWl0OworCisgICAgcmVjb21wdXRlQnVmZmVyU2l6ZUFmdGVyTGltaXQoKTsKKworICAgIHJldHVybiBvbGRMaW1pdDsKKyAgfQorCisgIHByaXZhdGUgdm9pZCByZWNvbXB1dGVCdWZmZXJTaXplQWZ0ZXJMaW1pdCgpIHsKKyAgICBidWZmZXJTaXplICs9IGJ1ZmZlclNpemVBZnRlckxpbWl0OworICAgIGZpbmFsIGludCBidWZmZXJFbmQgPSB0b3RhbEJ5dGVzUmV0aXJlZCArIGJ1ZmZlclNpemU7CisgICAgaWYgKGJ1ZmZlckVuZCA+IGN1cnJlbnRMaW1pdCkgeworICAgICAgLy8gTGltaXQgaXMgaW4gY3VycmVudCBidWZmZXIuCisgICAgICBidWZmZXJTaXplQWZ0ZXJMaW1pdCA9IGJ1ZmZlckVuZCAtIGN1cnJlbnRMaW1pdDsKKyAgICAgIGJ1ZmZlclNpemUgLT0gYnVmZmVyU2l6ZUFmdGVyTGltaXQ7CisgICAgfSBlbHNlIHsKKyAgICAgIGJ1ZmZlclNpemVBZnRlckxpbWl0ID0gMDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRGlzY2FyZHMgdGhlIGN1cnJlbnQgbGltaXQsIHJldHVybmluZyB0byB0aGUgcHJldmlvdXMgbGltaXQuCisgICAqCisgICAqIEBwYXJhbSBvbGRMaW1pdCBUaGUgb2xkIGxpbWl0LCBhcyByZXR1cm5lZCBieSB7QGNvZGUgcHVzaExpbWl0fS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHBvcExpbWl0KGZpbmFsIGludCBvbGRMaW1pdCkgeworICAgIGN1cnJlbnRMaW1pdCA9IG9sZExpbWl0OworICAgIHJlY29tcHV0ZUJ1ZmZlclNpemVBZnRlckxpbWl0KCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHJlYWQgYmVmb3JlIHRoZSBjdXJyZW50IGxpbWl0LgorICAgKiBJZiBubyBsaW1pdCBpcyBzZXQsIHJldHVybnMgLTEuCisgICAqLworICBwdWJsaWMgaW50IGdldEJ5dGVzVW50aWxMaW1pdCgpIHsKKyAgICBpZiAoY3VycmVudExpbWl0ID09IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgZmluYWwgaW50IGN1cnJlbnRBYnNvbHV0ZVBvc2l0aW9uID0gdG90YWxCeXRlc1JldGlyZWQgKyBidWZmZXJQb3M7CisgICAgcmV0dXJuIGN1cnJlbnRMaW1pdCAtIGN1cnJlbnRBYnNvbHV0ZVBvc2l0aW9uOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3RyZWFtIGhhcyByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGlucHV0LiAgVGhpcyBpcyB0aGUKKyAgICogY2FzZSBpZiBlaXRoZXIgdGhlIGVuZCBvZiB0aGUgdW5kZXJseWluZyBpbnB1dCBzb3VyY2UgaGFzIGJlZW4gcmVhY2hlZCBvcgorICAgKiBpZiB0aGUgc3RyZWFtIGhhcyByZWFjaGVkIGEgbGltaXQgY3JlYXRlZCB1c2luZyB7QGxpbmsgI3B1c2hMaW1pdChpbnQpfS4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzQXRFbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBidWZmZXJQb3MgPT0gYnVmZmVyU2l6ZSAmJiAhdHJ5UmVmaWxsQnVmZmVyKDEpOworICB9CisKKyAgLyoqCisgICAqIFRoZSB0b3RhbCBieXRlcyByZWFkIHVwIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uLiBDYWxsaW5nCisgICAqIHtAbGluayAjcmVzZXRTaXplQ291bnRlcigpfSByZXNldHMgdGhpcyB2YWx1ZSB0byB6ZXJvLgorICAgKi8KKyAgcHVibGljIGludCBnZXRUb3RhbEJ5dGVzUmVhZCgpIHsKKyAgICAgIHJldHVybiB0b3RhbEJ5dGVzUmV0aXJlZCArIGJ1ZmZlclBvczsKKyAgfQorCisgIHByaXZhdGUgaW50ZXJmYWNlIFJlZmlsbENhbGxiYWNrIHsKKyAgICB2b2lkIG9uUmVmaWxsKCk7CisgIH0KKworICBwcml2YXRlIFJlZmlsbENhbGxiYWNrIHJlZmlsbENhbGxiYWNrID0gbnVsbDsKKworICAvKioKKyAgICogRW5zdXJlcyB0aGF0IGF0IGxlYXN0IHtAY29kZSBufSBieXRlcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBidWZmZXIsIHJlYWRpbmcKKyAgICogbW9yZSBieXRlcyBmcm9tIHRoZSBpbnB1dCBpZiBuZWNlc3NhcnkgdG8gbWFrZSBpdCBzby4gIENhbGxlciBtdXN0IGVuc3VyZQorICAgKiB0aGF0IHRoZSByZXF1ZXN0ZWQgc3BhY2UgaXMgbGVzcyB0aGFuIEJVRkZFUl9TSVpFLgorICAgKgorICAgKiBAdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBUaGUgZW5kIG9mIHRoZSBzdHJlYW0gb3IgdGhlIGN1cnJlbnQKKyAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgd2FzIHJlYWNoZWQuCisgICAqLworICBwcml2YXRlIHZvaWQgZW5zdXJlQXZhaWxhYmxlKGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChidWZmZXJTaXplIC0gYnVmZmVyUG9zIDwgbikgeworICAgICAgcmVmaWxsQnVmZmVyKG4pOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZWFkcyBtb3JlIGJ5dGVzIGZyb20gdGhlIGlucHV0LCBtYWtpbmcgYXQgbGVhc3Qge0Bjb2RlIG59IGJ5dGVzIGF2YWlsYWJsZQorICAgKiBpbiB0aGUgYnVmZmVyLiAgQ2FsbGVyIG11c3QgZW5zdXJlIHRoYXQgdGhlIHJlcXVlc3RlZCBzcGFjZSBpcyBub3QgeWV0CisgICAqIGF2YWlsYWJsZSwgYW5kIHRoYXQgdGhlIHJlcXVlc3RlZCBzcGFjZSBpcyBsZXNzIHRoYW4gQlVGRkVSX1NJWkUuCisgICAqCisgICAqIEB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIFRoZSBlbmQgb2YgdGhlIHN0cmVhbSBvciB0aGUgY3VycmVudAorICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCB3YXMgcmVhY2hlZC4KKyAgICovCisgIHByaXZhdGUgdm9pZCByZWZpbGxCdWZmZXIoaW50IG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCF0cnlSZWZpbGxCdWZmZXIobikpIHsKKyAgICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi50cnVuY2F0ZWRNZXNzYWdlKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFRyaWVzIHRvIHJlYWQgbW9yZSBieXRlcyBmcm9tIHRoZSBpbnB1dCwgbWFraW5nIGF0IGxlYXN0IHtAY29kZSBufSBieXRlcworICAgKiBhdmFpbGFibGUgaW4gdGhlIGJ1ZmZlci4gIENhbGxlciBtdXN0IGVuc3VyZSB0aGF0IHRoZSByZXF1ZXN0ZWQgc3BhY2UgaXMKKyAgICogbm90IHlldCBhdmFpbGFibGUsIGFuZCB0aGF0IHRoZSByZXF1ZXN0ZWQgc3BhY2UgaXMgbGVzcyB0aGFuIEJVRkZFUl9TSVpFLgorICAgKgorICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgYnl0ZXMgY291bGQgYmUgbWFkZSBhdmFpbGFibGU7IHtAY29kZSBmYWxzZX0KKyAgICogICAgICAgICBpZiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gb3IgdGhlIGN1cnJlbnQgbGltaXQgd2FzIHJlYWNoZWQuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gdHJ5UmVmaWxsQnVmZmVyKGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChidWZmZXJQb3MgKyBuIDw9IGJ1ZmZlclNpemUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgInJlZmlsbEJ1ZmZlcigpIGNhbGxlZCB3aGVuICIgKyBuICsKKyAgICAgICAgICAiIGJ5dGVzIHdlcmUgYWxyZWFkeSBhdmFpbGFibGUgaW4gYnVmZmVyIik7CisgICAgfQorCisgICAgaWYgKHRvdGFsQnl0ZXNSZXRpcmVkICsgYnVmZmVyUG9zICsgbiA+IGN1cnJlbnRMaW1pdCkgeworICAgICAgLy8gT29wcywgd2UgaGl0IGEgbGltaXQuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKHJlZmlsbENhbGxiYWNrICE9IG51bGwpIHsKKyAgICAgIHJlZmlsbENhbGxiYWNrLm9uUmVmaWxsKCk7CisgICAgfQorCisgICAgaWYgKGlucHV0ICE9IG51bGwpIHsKKyAgICAgIGludCBwb3MgPSBidWZmZXJQb3M7CisgICAgICBpZiAocG9zID4gMCkgeworICAgICAgICBpZiAoYnVmZmVyU2l6ZSA+IHBvcykgeworICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBwb3MsIGJ1ZmZlciwgMCwgYnVmZmVyU2l6ZSAtIHBvcyk7CisgICAgICAgIH0KKyAgICAgICAgdG90YWxCeXRlc1JldGlyZWQgKz0gcG9zOworICAgICAgICBidWZmZXJTaXplIC09IHBvczsKKyAgICAgICAgYnVmZmVyUG9zID0gMDsKKyAgICAgIH0KKworICAgICAgaW50IGJ5dGVzUmVhZCA9IGlucHV0LnJlYWQoYnVmZmVyLCBidWZmZXJTaXplLCBidWZmZXIubGVuZ3RoIC0gYnVmZmVyU2l6ZSk7CisgICAgICBpZiAoYnl0ZXNSZWFkID09IDAgfHwgYnl0ZXNSZWFkIDwgLTEgfHwgYnl0ZXNSZWFkID4gYnVmZmVyLmxlbmd0aCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgIklucHV0U3RyZWFtI3JlYWQoYnl0ZVtdKSByZXR1cm5lZCBpbnZhbGlkIHJlc3VsdDogIiArIGJ5dGVzUmVhZCArCisgICAgICAgICAgICAiXG5UaGUgSW5wdXRTdHJlYW0gaW1wbGVtZW50YXRpb24gaXMgYnVnZ3kuIik7CisgICAgICB9CisgICAgICBpZiAoYnl0ZXNSZWFkID4gMCkgeworICAgICAgICBidWZmZXJTaXplICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgLy8gSW50ZWdlci1vdmVyZmxvdy1jb25zY2lvdXMgY2hlY2sgYWdhaW5zdCBzaXplTGltaXQKKyAgICAgICAgaWYgKHRvdGFsQnl0ZXNSZXRpcmVkICsgbiAtIHNpemVMaW1pdCA+IDApIHsKKyAgICAgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24uc2l6ZUxpbWl0RXhjZWVkZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZWNvbXB1dGVCdWZmZXJTaXplQWZ0ZXJMaW1pdCgpOworICAgICAgICByZXR1cm4gKGJ1ZmZlclNpemUgPj0gbikgPyB0cnVlIDogdHJ5UmVmaWxsQnVmZmVyKG4pOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkIG9uZSBieXRlIGZyb20gdGhlIGlucHV0LgorICAgKgorICAgKiBAdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBUaGUgZW5kIG9mIHRoZSBzdHJlYW0gb3IgdGhlIGN1cnJlbnQKKyAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgd2FzIHJlYWNoZWQuCisgICAqLworICBwdWJsaWMgYnl0ZSByZWFkUmF3Qnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGJ1ZmZlclBvcyA9PSBidWZmZXJTaXplKSB7CisgICAgICByZWZpbGxCdWZmZXIoMSk7CisgICAgfQorICAgIHJldHVybiBidWZmZXJbYnVmZmVyUG9zKytdOworICB9CisKKyAgLyoqCisgICAqIFJlYWQgYSBmaXhlZCBzaXplIG9mIGJ5dGVzIGZyb20gdGhlIGlucHV0LgorICAgKgorICAgKiBAdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBUaGUgZW5kIG9mIHRoZSBzdHJlYW0gb3IgdGhlIGN1cnJlbnQKKyAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgd2FzIHJlYWNoZWQuCisgICAqLworICBwdWJsaWMgYnl0ZVtdIHJlYWRSYXdCeXRlcyhmaW5hbCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgcG9zID0gYnVmZmVyUG9zOworICAgIGlmIChzaXplIDw9IChidWZmZXJTaXplIC0gcG9zKSAmJiBzaXplID4gMCkgeworICAgICAgYnVmZmVyUG9zID0gcG9zICsgc2l6ZTsKKyAgICAgIHJldHVybiBBcnJheXMuY29weU9mUmFuZ2UoYnVmZmVyLCBwb3MsIHBvcyArIHNpemUpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gcmVhZFJhd0J5dGVzU2xvd1BhdGgoc2l6ZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEV4YWN0bHkgbGlrZSByZWFkUmF3Qnl0ZXMsIGJ1dCBjYWxsZXIgbXVzdCBoYXZlIGFscmVhZHkgY2hlY2tlZCB0aGUgZmFzdAorICAgKiBwYXRoOiAoc2l6ZSA8PSAoYnVmZmVyU2l6ZSAtIHBvcykgJiYgc2l6ZSA+IDApCisgICAqLworICBwcml2YXRlIGJ5dGVbXSByZWFkUmF3Qnl0ZXNTbG93UGF0aChmaW5hbCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc2l6ZSA8PSAwKSB7CisgICAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgIHJldHVybiBJbnRlcm5hbC5FTVBUWV9CWVRFX0FSUkFZOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLm5lZ2F0aXZlU2l6ZSgpOworICAgICAgfQorICAgIH0KKworICAgIGlmICh0b3RhbEJ5dGVzUmV0aXJlZCArIGJ1ZmZlclBvcyArIHNpemUgPiBjdXJyZW50TGltaXQpIHsKKyAgICAgIC8vIFJlYWQgdG8gdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGFueXdheS4KKyAgICAgIHNraXBSYXdCeXRlcyhjdXJyZW50TGltaXQgLSB0b3RhbEJ5dGVzUmV0aXJlZCAtIGJ1ZmZlclBvcyk7CisgICAgICAvLyBUaGVuIGZhaWwuCisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24udHJ1bmNhdGVkTWVzc2FnZSgpOworICAgIH0KKworICAgIGlmIChzaXplIDwgQlVGRkVSX1NJWkUpIHsKKyAgICAgIC8vIFJlYWRpbmcgbW9yZSBieXRlcyB0aGFuIGFyZSBpbiB0aGUgYnVmZmVyLCBidXQgbm90IGFuIGV4Y2Vzc2l2ZSBudW1iZXIKKyAgICAgIC8vIG9mIGJ5dGVzLiAgV2UgY2FuIHNhZmVseSBhbGxvY2F0ZSB0aGUgcmVzdWx0aW5nIGFycmF5IGFoZWFkIG9mIHRpbWUuCisKKyAgICAgIC8vIEZpcnN0IGNvcHkgd2hhdCB3ZSBoYXZlLgorICAgICAgZmluYWwgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICBpbnQgcG9zID0gYnVmZmVyU2l6ZSAtIGJ1ZmZlclBvczsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBidWZmZXJQb3MsIGJ5dGVzLCAwLCBwb3MpOworICAgICAgYnVmZmVyUG9zID0gYnVmZmVyU2l6ZTsKKworICAgICAgLy8gV2Ugd2FudCB0byByZWZpbGwgdGhlIGJ1ZmZlciBhbmQgdGhlbiBjb3B5IGZyb20gdGhlIGJ1ZmZlciBpbnRvIG91cgorICAgICAgLy8gYnl0ZSBhcnJheSByYXRoZXIgdGhhbiByZWFkaW5nIGRpcmVjdGx5IGludG8gb3VyIGJ5dGUgYXJyYXkgYmVjYXVzZQorICAgICAgLy8gdGhlIGlucHV0IG1heSBiZSB1bmJ1ZmZlcmVkLgorICAgICAgZW5zdXJlQXZhaWxhYmxlKHNpemUgLSBwb3MpOworICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIDAsIGJ5dGVzLCBwb3MsIHNpemUgLSBwb3MpOworICAgICAgYnVmZmVyUG9zID0gc2l6ZSAtIHBvczsKKworICAgICAgcmV0dXJuIGJ5dGVzOworICAgIH0gZWxzZSB7CisgICAgICAvLyBUaGUgc2l6ZSBpcyB2ZXJ5IGxhcmdlLiAgRm9yIHNlY3VyaXR5IHJlYXNvbnMsIHdlIGNhbid0IGFsbG9jYXRlIHRoZQorICAgICAgLy8gZW50aXJlIGJ5dGUgYXJyYXkgeWV0LiAgVGhlIHNpemUgY29tZXMgZGlyZWN0bHkgZnJvbSB0aGUgaW5wdXQsIHNvIGEKKyAgICAgIC8vIG1hbGljaW91c2x5LWNyYWZ0ZWQgbWVzc2FnZSBjb3VsZCBwcm92aWRlIGEgYm9ndXMgdmVyeSBsYXJnZSBzaXplIGluCisgICAgICAvLyBvcmRlciB0byB0cmljayB0aGUgYXBwIGludG8gYWxsb2NhdGluZyBhIGxvdCBvZiBtZW1vcnkuICBXZSBhdm9pZCB0aGlzCisgICAgICAvLyBieSBhbGxvY2F0aW5nIGFuZCByZWFkaW5nIG9ubHkgYSBzbWFsbCBjaHVuayBhdCBhIHRpbWUsIHNvIHRoYXQgdGhlCisgICAgICAvLyBtYWxpY2lvdXMgbWVzc2FnZSBtdXN0IGFjdHVhbGx5ICpiZSogZXh0cmVtZWx5IGxhcmdlIHRvIGNhdXNlCisgICAgICAvLyBwcm9ibGVtcy4gIE1lYW53aGlsZSwgd2UgbGltaXQgdGhlIGFsbG93ZWQgc2l6ZSBvZiBhIG1lc3NhZ2UgZWxzZXdoZXJlLgorCisgICAgICAvLyBSZW1lbWJlciB0aGUgYnVmZmVyIG1hcmtlcnMgc2luY2Ugd2UnbGwgaGF2ZSB0byBjb3B5IHRoZSBieXRlcyBvdXQgb2YKKyAgICAgIC8vIGl0IGxhdGVyLgorICAgICAgZmluYWwgaW50IG9yaWdpbmFsQnVmZmVyUG9zID0gYnVmZmVyUG9zOworICAgICAgZmluYWwgaW50IG9yaWdpbmFsQnVmZmVyU2l6ZSA9IGJ1ZmZlclNpemU7CisKKyAgICAgIC8vIE1hcmsgdGhlIGN1cnJlbnQgYnVmZmVyIGNvbnN1bWVkLgorICAgICAgdG90YWxCeXRlc1JldGlyZWQgKz0gYnVmZmVyU2l6ZTsKKyAgICAgIGJ1ZmZlclBvcyA9IDA7CisgICAgICBidWZmZXJTaXplID0gMDsKKworICAgICAgLy8gUmVhZCBhbGwgdGhlIHJlc3Qgb2YgdGhlIGJ5dGVzIHdlIG5lZWQuCisgICAgICBpbnQgc2l6ZUxlZnQgPSBzaXplIC0gKG9yaWdpbmFsQnVmZmVyU2l6ZSAtIG9yaWdpbmFsQnVmZmVyUG9zKTsKKyAgICAgIGZpbmFsIExpc3Q8Ynl0ZVtdPiBjaHVua3MgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oKTsKKworICAgICAgd2hpbGUgKHNpemVMZWZ0ID4gMCkgeworICAgICAgICBmaW5hbCBieXRlW10gY2h1bmsgPSBuZXcgYnl0ZVtNYXRoLm1pbihzaXplTGVmdCwgQlVGRkVSX1NJWkUpXTsKKyAgICAgICAgaW50IHBvcyA9IDA7CisgICAgICAgIHdoaWxlIChwb3MgPCBjaHVuay5sZW5ndGgpIHsKKyAgICAgICAgICBmaW5hbCBpbnQgbiA9IChpbnB1dCA9PSBudWxsKSA/IC0xIDoKKyAgICAgICAgICAgIGlucHV0LnJlYWQoY2h1bmssIHBvcywgY2h1bmsubGVuZ3RoIC0gcG9zKTsKKyAgICAgICAgICBpZiAobiA9PSAtMSkgeworICAgICAgICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLnRydW5jYXRlZE1lc3NhZ2UoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgdG90YWxCeXRlc1JldGlyZWQgKz0gbjsKKyAgICAgICAgICBwb3MgKz0gbjsKKyAgICAgICAgfQorICAgICAgICBzaXplTGVmdCAtPSBjaHVuay5sZW5ndGg7CisgICAgICAgIGNodW5rcy5hZGQoY2h1bmspOworICAgICAgfQorCisgICAgICAvLyBPSywgZ290IGV2ZXJ5dGhpbmcuICBOb3cgY29uY2F0ZW5hdGUgaXQgYWxsIGludG8gb25lIGJ1ZmZlci4KKyAgICAgIGZpbmFsIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW3NpemVdOworCisgICAgICAvLyBTdGFydCBieSBjb3B5aW5nIHRoZSBsZWZ0b3ZlciBieXRlcyBmcm9tIHRoaXMuYnVmZmVyLgorICAgICAgaW50IHBvcyA9IG9yaWdpbmFsQnVmZmVyU2l6ZSAtIG9yaWdpbmFsQnVmZmVyUG9zOworICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIG9yaWdpbmFsQnVmZmVyUG9zLCBieXRlcywgMCwgcG9zKTsKKworICAgICAgLy8gQW5kIG5vdyBhbGwgdGhlIGNodW5rcy4KKyAgICAgIGZvciAoZmluYWwgYnl0ZVtdIGNodW5rIDogY2h1bmtzKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2h1bmssIDAsIGJ5dGVzLCBwb3MsIGNodW5rLmxlbmd0aCk7CisgICAgICAgIHBvcyArPSBjaHVuay5sZW5ndGg7CisgICAgICB9CisKKyAgICAgIC8vIERvbmUuCisgICAgICByZXR1cm4gYnl0ZXM7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGFuZCBkaXNjYXJkcyB7QGNvZGUgc2l6ZX0gYnl0ZXMuCisgICAqCisgICAqIEB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIFRoZSBlbmQgb2YgdGhlIHN0cmVhbSBvciB0aGUgY3VycmVudAorICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCB3YXMgcmVhY2hlZC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNraXBSYXdCeXRlcyhmaW5hbCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc2l6ZSA8PSAoYnVmZmVyU2l6ZSAtIGJ1ZmZlclBvcykgJiYgc2l6ZSA+PSAwKSB7CisgICAgICAvLyBXZSBoYXZlIGFsbCB0aGUgYnl0ZXMgd2UgbmVlZCBhbHJlYWR5LgorICAgICAgYnVmZmVyUG9zICs9IHNpemU7CisgICAgfSBlbHNlIHsKKyAgICAgIHNraXBSYXdCeXRlc1Nsb3dQYXRoKHNpemUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBFeGFjdGx5IGxpa2Ugc2tpcFJhd0J5dGVzLCBidXQgY2FsbGVyIG11c3QgaGF2ZSBhbHJlYWR5IGNoZWNrZWQgdGhlIGZhc3QKKyAgICogcGF0aDogKHNpemUgPD0gKGJ1ZmZlclNpemUgLSBwb3MpICYmIHNpemUgPj0gMCkKKyAgICovCisgIHByaXZhdGUgdm9pZCBza2lwUmF3Qnl0ZXNTbG93UGF0aChmaW5hbCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc2l6ZSA8IDApIHsKKyAgICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5uZWdhdGl2ZVNpemUoKTsKKyAgICB9CisKKyAgICBpZiAodG90YWxCeXRlc1JldGlyZWQgKyBidWZmZXJQb3MgKyBzaXplID4gY3VycmVudExpbWl0KSB7CisgICAgICAvLyBSZWFkIHRvIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBhbnl3YXkuCisgICAgICBza2lwUmF3Qnl0ZXMoY3VycmVudExpbWl0IC0gdG90YWxCeXRlc1JldGlyZWQgLSBidWZmZXJQb3MpOworICAgICAgLy8gVGhlbiBmYWlsLgorICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLnRydW5jYXRlZE1lc3NhZ2UoKTsKKyAgICB9CisKKyAgICAvLyBTa2lwcGluZyBtb3JlIGJ5dGVzIHRoYW4gYXJlIGluIHRoZSBidWZmZXIuICBGaXJzdCBza2lwIHdoYXQgd2UgaGF2ZS4KKyAgICBpbnQgcG9zID0gYnVmZmVyU2l6ZSAtIGJ1ZmZlclBvczsKKyAgICBidWZmZXJQb3MgPSBidWZmZXJTaXplOworCisgICAgLy8gS2VlcCByZWZpbGxpbmcgdGhlIGJ1ZmZlciB1bnRpbCB3ZSBnZXQgdG8gdGhlIHBvaW50IHdlIHdhbnRlZCB0byBza2lwIHRvLgorICAgIC8vIFRoaXMgaGFzIHRoZSBzaWRlIGVmZmVjdCBvZiBlbnN1cmluZyB0aGUgbGltaXRzIGFyZSB1cGRhdGVkIGNvcnJlY3RseS4KKyAgICByZWZpbGxCdWZmZXIoMSk7CisgICAgd2hpbGUgKHNpemUgLSBwb3MgPiBidWZmZXJTaXplKSB7CisgICAgICBwb3MgKz0gYnVmZmVyU2l6ZTsKKyAgICAgIGJ1ZmZlclBvcyA9IGJ1ZmZlclNpemU7CisgICAgICByZWZpbGxCdWZmZXIoMSk7CisgICAgfQorCisgICAgYnVmZmVyUG9zID0gc2l6ZSAtIHBvczsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQ29kZWRPdXRwdXRTdHJlYW0uamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmFmZTAzNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMjk3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKKworLyoqCisgKiBFbmNvZGVzIGFuZCB3cml0ZXMgcHJvdG9jb2wgbWVzc2FnZSBmaWVsZHMuCisgKgorICogPHA+VGhpcyBjbGFzcyBjb250YWlucyB0d28ga2luZHMgb2YgbWV0aG9kczogIG1ldGhvZHMgdGhhdCB3cml0ZSBzcGVjaWZpYworICogcHJvdG9jb2wgbWVzc2FnZSBjb25zdHJ1Y3RzIGFuZCBmaWVsZCB0eXBlcyAoZS5nLiB7QGxpbmsgI3dyaXRlVGFnfSBhbmQKKyAqIHtAbGluayAjd3JpdGVJbnQzMn0pIGFuZCBtZXRob2RzIHRoYXQgd3JpdGUgbG93LWxldmVsIHZhbHVlcyAoZS5nLgorICoge0BsaW5rICN3cml0ZVJhd1ZhcmludDMyfSBhbmQge0BsaW5rICN3cml0ZVJhd0J5dGVzfSkuICBJZiB5b3UgYXJlCisgKiB3cml0aW5nIGVuY29kZWQgcHJvdG9jb2wgbWVzc2FnZXMsIHlvdSBzaG91bGQgdXNlIHRoZSBmb3JtZXIgbWV0aG9kcywgYnV0IGlmCisgKiB5b3UgYXJlIHdyaXRpbmcgc29tZSBvdGhlciBmb3JtYXQgb2YgeW91ciBvd24gZGVzaWduLCB1c2UgdGhlIGxhdHRlci4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIHRvdGFsbHkgdW5zeW5jaHJvbml6ZWQuCisgKgorICogQGF1dGhvciBrbmV0b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENvZGVkT3V0cHV0U3RyZWFtIHsKKyAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmZmVyOworICBwcml2YXRlIGZpbmFsIGludCBsaW1pdDsKKyAgcHJpdmF0ZSBpbnQgcG9zaXRpb247CisgIHByaXZhdGUgaW50IHRvdGFsQnl0ZXNXcml0dGVuID0gMDsKKworICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXQ7CisKKyAgLyoqCisgICAqIFRoZSBidWZmZXIgc2l6ZSB1c2VkIGluIHtAbGluayAjbmV3SW5zdGFuY2UoT3V0cHV0U3RyZWFtKX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JVRkZFUl9TSVpFID0gNDA5NjsKKworICAvKioKKyAgICogUmV0dXJucyB0aGUgYnVmZmVyIHNpemUgdG8gZWZmaWNpZW50bHkgd3JpdGUgZGF0YUxlbmd0aCBieXRlcyB0byB0aGlzCisgICAqIENvZGVkT3V0cHV0U3RyZWFtLiBVc2VkIGJ5IEFic3RyYWN0TWVzc2FnZUxpdGUuCisgICAqCisgICAqIEByZXR1cm4gdGhlIGJ1ZmZlciBzaXplIHRvIGVmZmljaWVudGx5IHdyaXRlIGRhdGFMZW5ndGggYnl0ZXMgdG8gdGhpcworICAgKiAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLgorICAgKi8KKyAgc3RhdGljIGludCBjb21wdXRlUHJlZmVycmVkQnVmZmVyU2l6ZShpbnQgZGF0YUxlbmd0aCkgeworICAgIGlmIChkYXRhTGVuZ3RoID4gREVGQVVMVF9CVUZGRVJfU0laRSkgcmV0dXJuIERFRkFVTFRfQlVGRkVSX1NJWkU7CisgICAgcmV0dXJuIGRhdGFMZW5ndGg7CisgIH0KKworICBwcml2YXRlIENvZGVkT3V0cHV0U3RyZWFtKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCkgeworICAgIG91dHB1dCA9IG51bGw7CisgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7CisgICAgcG9zaXRpb24gPSBvZmZzZXQ7CisgICAgbGltaXQgPSBvZmZzZXQgKyBsZW5ndGg7CisgIH0KKworICBwcml2YXRlIENvZGVkT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXQsIGZpbmFsIGJ5dGVbXSBidWZmZXIpIHsKKyAgICB0aGlzLm91dHB1dCA9IG91dHB1dDsKKyAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjsKKyAgICBwb3NpdGlvbiA9IDA7CisgICAgbGltaXQgPSBidWZmZXIubGVuZ3RoOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgQ29kZWRPdXRwdXRTdHJlYW19IHdyYXBwaW5nIHRoZSBnaXZlbgorICAgKiB7QGNvZGUgT3V0cHV0U3RyZWFtfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQ29kZWRPdXRwdXRTdHJlYW0gbmV3SW5zdGFuY2UoZmluYWwgT3V0cHV0U3RyZWFtIG91dHB1dCkgeworICAgIHJldHVybiBuZXdJbnN0YW5jZShvdXRwdXQsIERFRkFVTFRfQlVGRkVSX1NJWkUpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgQ29kZWRPdXRwdXRTdHJlYW19IHdyYXBwaW5nIHRoZSBnaXZlbgorICAgKiB7QGNvZGUgT3V0cHV0U3RyZWFtfSB3aXRoIGEgZ2l2ZW4gYnVmZmVyIHNpemUuCisgICAqLworICBwdWJsaWMgc3RhdGljIENvZGVkT3V0cHV0U3RyZWFtIG5ld0luc3RhbmNlKGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXQsCisgICAgICBmaW5hbCBpbnQgYnVmZmVyU2l6ZSkgeworICAgIHJldHVybiBuZXcgQ29kZWRPdXRwdXRTdHJlYW0ob3V0cHV0LCBuZXcgYnl0ZVtidWZmZXJTaXplXSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBDb2RlZE91dHB1dFN0cmVhbX0gdGhhdCB3cml0ZXMgZGlyZWN0bHkgdG8gdGhlIGdpdmVuCisgICAqIGJ5dGUgYXJyYXkuICBJZiBtb3JlIGJ5dGVzIGFyZSB3cml0dGVuIHRoYW4gZml0IGluIHRoZSBhcnJheSwKKyAgICoge0BsaW5rIE91dE9mU3BhY2VFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duLiAgV3JpdGluZyBkaXJlY3RseSB0byBhIGZsYXQKKyAgICogYXJyYXkgaXMgZmFzdGVyIHRoYW4gd3JpdGluZyB0byBhbiB7QGNvZGUgT3V0cHV0U3RyZWFtfS4gIFNlZSBhbHNvCisgICAqIHtAbGluayBCeXRlU3RyaW5nI25ld0NvZGVkQnVpbGRlcn0uCisgICAqLworICBwdWJsaWMgc3RhdGljIENvZGVkT3V0cHV0U3RyZWFtIG5ld0luc3RhbmNlKGZpbmFsIGJ5dGVbXSBmbGF0QXJyYXkpIHsKKyAgICByZXR1cm4gbmV3SW5zdGFuY2UoZmxhdEFycmF5LCAwLCBmbGF0QXJyYXkubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIENvZGVkT3V0cHV0U3RyZWFtfSB0aGF0IHdyaXRlcyBkaXJlY3RseSB0byB0aGUgZ2l2ZW4KKyAgICogYnl0ZSBhcnJheSBzbGljZS4gIElmIG1vcmUgYnl0ZXMgYXJlIHdyaXR0ZW4gdGhhbiBmaXQgaW4gdGhlIHNsaWNlLAorICAgKiB7QGxpbmsgT3V0T2ZTcGFjZUV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24uICBXcml0aW5nIGRpcmVjdGx5IHRvIGEgZmxhdAorICAgKiBhcnJheSBpcyBmYXN0ZXIgdGhhbiB3cml0aW5nIHRvIGFuIHtAY29kZSBPdXRwdXRTdHJlYW19LiAgU2VlIGFsc28KKyAgICoge0BsaW5rIEJ5dGVTdHJpbmcjbmV3Q29kZWRCdWlsZGVyfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQ29kZWRPdXRwdXRTdHJlYW0gbmV3SW5zdGFuY2UoZmluYWwgYnl0ZVtdIGZsYXRBcnJheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICByZXR1cm4gbmV3IENvZGVkT3V0cHV0U3RyZWFtKGZsYXRBcnJheSwgb2Zmc2V0LCBsZW5ndGgpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgQ29kZWRPdXRwdXRTdHJlYW19IHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBCeXRlQnVmZmVyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBDb2RlZE91dHB1dFN0cmVhbSBuZXdJbnN0YW5jZShCeXRlQnVmZmVyIGJ5dGVCdWZmZXIpIHsKKyAgICByZXR1cm4gbmV3SW5zdGFuY2UoYnl0ZUJ1ZmZlciwgREVGQVVMVF9CVUZGRVJfU0laRSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBDb2RlZE91dHB1dFN0cmVhbX0gdGhhdCB3cml0ZXMgdG8gdGhlIGdpdmVuIEJ5dGVCdWZmZXIuCisgICAqLworICBwdWJsaWMgc3RhdGljIENvZGVkT3V0cHV0U3RyZWFtIG5ld0luc3RhbmNlKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlciwKKyAgICAgIGludCBidWZmZXJTaXplKSB7CisgICAgcmV0dXJuIG5ld0luc3RhbmNlKG5ldyBCeXRlQnVmZmVyT3V0cHV0U3RyZWFtKGJ5dGVCdWZmZXIpLCBidWZmZXJTaXplKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQnl0ZUJ1ZmZlck91dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGJ5dGVCdWZmZXI7CisgICAgcHVibGljIEJ5dGVCdWZmZXJPdXRwdXRTdHJlYW0oQnl0ZUJ1ZmZlciBieXRlQnVmZmVyKSB7CisgICAgICB0aGlzLmJ5dGVCdWZmZXIgPSBieXRlQnVmZmVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYnl0ZUJ1ZmZlci5wdXQoKGJ5dGUpIGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYnl0ZUJ1ZmZlci5wdXQoZGF0YSwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGRvdWJsZX0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRG91YmxlKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgZG91YmxlIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0ZJWEVENjQpOworICAgIHdyaXRlRG91YmxlTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGZsb2F0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGbG9hdChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGZsb2F0IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQzMik7CisgICAgd3JpdGVGbG9hdE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSB1aW50NjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVVJbnQ2NChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGxvbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5UKTsKKyAgICB3cml0ZVVJbnQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgaW50NjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUludDY0KGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgbG9uZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX1ZBUklOVCk7CisgICAgd3JpdGVJbnQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgaW50MzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUludDMyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5UKTsKKyAgICB3cml0ZUludDMyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGZpeGVkNjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUZpeGVkNjQoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBsb25nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9GSVhFRDY0KTsKKyAgICB3cml0ZUZpeGVkNjROb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZml4ZWQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRml4ZWQzMihmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQzMik7CisgICAgd3JpdGVGaXhlZDMyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGJvb2x9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUJvb2woZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBib29sZWFuIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9WQVJJTlQpOworICAgIHdyaXRlQm9vbE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBzdHJpbmd9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVN0cmluZyhmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIFN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICB3cml0ZVN0cmluZ05vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBncm91cH0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlR3JvdXAoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBNZXNzYWdlTGl0ZSB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQKTsKKyAgICB3cml0ZUdyb3VwTm9UYWcodmFsdWUpOworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0VORF9HUk9VUCk7CisgIH0KKworCisgIC8qKgorICAgKiBXcml0ZSBhIGdyb3VwIHJlcHJlc2VudGVkIGJ5IGFuIHtAbGluayBVbmtub3duRmllbGRTZXR9LgorICAgKgorICAgKiBAZGVwcmVjYXRlZCBVbmtub3duRmllbGRTZXQgbm93IGltcGxlbWVudHMgTWVzc2FnZUxpdGUsIHNvIHlvdSBjYW4ganVzdAorICAgKiAgICAgICAgICAgICBjYWxsIHtAbGluayAjd3JpdGVHcm91cH0uCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgdm9pZCB3cml0ZVVua25vd25Hcm91cChmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VMaXRlIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlR3JvdXAoZmllbGROdW1iZXIsIHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiBlbWJlZGRlZCBtZXNzYWdlIGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZU1lc3NhZ2UoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBNZXNzYWdlTGl0ZSB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgd3JpdGVNZXNzYWdlTm9UYWcodmFsdWUpOworICB9CisKKworICAvKiogV3JpdGUgYSB7QGNvZGUgYnl0ZXN9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUJ5dGVzKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgIHdyaXRlQnl0ZXNOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgYnl0ZXN9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUJ5dGVBcnJheShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGJ5dGVbXSB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICB3cml0ZUJ5dGVBcnJheU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBieXRlc30gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlQnl0ZUFycmF5KGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgIHdyaXRlQnl0ZUFycmF5Tm9UYWcodmFsdWUsIG9mZnNldCwgbGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhIHtAY29kZSBieXRlc30gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uCisgICAqIFRoaXMgbWV0aG9kIHdpbGwgd3JpdGUgYWxsIGNvbnRlbnQgb2YgdGhlIEJ5dGVCdWZmZXIgcmVnYXJkbGVzcyBvZiB0aGUKKyAgICogY3VycmVudCBwb3NpdGlvbiBhbmQgbGltaXQgKGkuZS4sIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYmUgd3JpdHRlbiBpcworICAgKiB2YWx1ZS5jYXBhY2l0eSgpLCBub3QgdmFsdWUucmVtYWluaW5nKCkpLiBGdXJ0aGVybW9yZSwgdGhpcyBtZXRob2QgZG9lc24ndAorICAgKiBhbHRlciB0aGUgc3RhdGUgb2YgdGhlIHBhc3NlZC1pbiBCeXRlQnVmZmVyLiBJdHMgcG9zaXRpb24sIGxpbWl0LCBtYXJrLAorICAgKiBldGMuIHdpbGwgcmVtYWluIHVuY2hhbmdlZC4gSWYgeW91IG9ubHkgd2FudCB0byB3cml0ZSB0aGUgcmVtYWluaW5nIGJ5dGVzCisgICAqIG9mIGEgQnl0ZUJ1ZmZlciwgeW91IGNhbiBjYWxsCisgICAqIHtAY29kZSB3cml0ZUJ5dGVCdWZmZXIoZmllbGROdW1iZXIsIGJ5dGVCdWZmZXIuc2xpY2UoKSl9LgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVCeXRlQnVmZmVyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgQnl0ZUJ1ZmZlciB2YWx1ZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgd3JpdGVCeXRlQnVmZmVyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIHVpbnQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVUludDMyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX1ZBUklOVCk7CisgICAgd3JpdGVVSW50MzJOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYW4gZW51bSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gIENhbGxlciBpcyByZXNwb25zaWJsZQorICAgKiBmb3IgY29udmVydGluZyB0aGUgZW51bSB2YWx1ZSB0byBpdHMgbnVtZXJpYyB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRW51bShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5UKTsKKyAgICB3cml0ZUVudW1Ob1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIHNmaXhlZDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTRml4ZWQzMihmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0ZJWEVEMzIpOworICAgIHdyaXRlU0ZpeGVkMzJOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIHNmaXhlZDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTRml4ZWQ2NChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGxvbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9GSVhFRDY0KTsKKyAgICB3cml0ZVNGaXhlZDY0Tm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBzaW50MzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVNJbnQzMihmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9WQVJJTlQpOworICAgIHdyaXRlU0ludDMyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBzaW50NjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVNJbnQ2NChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGxvbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5UKTsKKyAgICB3cml0ZVNJbnQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBGb3IgaGlzdG9yaWNhbCByZWFzb25zLAorICAgKiB0aGUgd2lyZSBmb3JtYXQgZGlmZmVycyBmcm9tIG5vcm1hbCBmaWVsZHMuCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZU1lc3NhZ2VTZXRFeHRlbnNpb24oZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVzc2FnZUxpdGUgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfSVRFTSwgV2lyZUZvcm1hdC5XSVJFVFlQRV9TVEFSVF9HUk9VUCk7CisgICAgd3JpdGVVSW50MzIoV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9UWVBFX0lELCBmaWVsZE51bWJlcik7CisgICAgd3JpdGVNZXNzYWdlKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfTUVTU0FHRSwgdmFsdWUpOworICAgIHdyaXRlVGFnKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfSVRFTSwgV2lyZUZvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlIGFuIHVucGFyc2VkIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBGb3IKKyAgICogaGlzdG9yaWNhbCByZWFzb25zLCB0aGUgd2lyZSBmb3JtYXQgZGlmZmVycyBmcm9tIG5vcm1hbCBmaWVsZHMuCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd01lc3NhZ2VTZXRFeHRlbnNpb24oZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9JVEVNLCBXaXJlRm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQKTsKKyAgICB3cml0ZVVJbnQzMihXaXJlRm9ybWF0Lk1FU1NBR0VfU0VUX1RZUEVfSUQsIGZpZWxkTnVtYmVyKTsKKyAgICB3cml0ZUJ5dGVzKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfTUVTU0FHRSwgdmFsdWUpOworICAgIHdyaXRlVGFnKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfSVRFTSwgV2lyZUZvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZG91YmxlfSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZURvdWJsZU5vVGFnKGZpbmFsIGRvdWJsZSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0xpdHRsZUVuZGlhbjY0KERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKHZhbHVlKSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZmxvYXR9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRmxvYXROb1RhZyhmaW5hbCBmbG9hdCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0xpdHRsZUVuZGlhbjMyKEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKHZhbHVlKSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgdWludDY0fSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVVJbnQ2NE5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQ2NCh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIGludDY0fSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUludDY0Tm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd1ZhcmludDY0KHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgaW50MzJ9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlSW50MzJOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHZhbHVlID49IDApIHsKKyAgICAgIHdyaXRlUmF3VmFyaW50MzIodmFsdWUpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBNdXN0IHNpZ24tZXh0ZW5kLgorICAgICAgd3JpdGVSYXdWYXJpbnQ2NCh2YWx1ZSk7CisgICAgfQorICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGZpeGVkNjR9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRml4ZWQ2NE5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdMaXR0bGVFbmRpYW42NCh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZml4ZWQzMn0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGaXhlZDMyTm9UYWcoZmluYWwgaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3TGl0dGxlRW5kaWFuMzIodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGJvb2x9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlQm9vbE5vVGFnKGZpbmFsIGJvb2xlYW4gdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdCeXRlKHZhbHVlID8gMSA6IDApOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIHN0cmluZ30gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTdHJpbmdOb1RhZyhmaW5hbCBTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gVW5mb3J0dW5hdGVseSB0aGVyZSBkb2VzIG5vdCBhcHBlYXIgdG8gYmUgYW55IHdheSB0byB0ZWxsIEphdmEgdG8gZW5jb2RlCisgICAgLy8gVVRGLTggZGlyZWN0bHkgaW50byBvdXIgYnVmZmVyLCBzbyB3ZSBoYXZlIHRvIGxldCBpdCBjcmVhdGUgaXRzIG93biBieXRlCisgICAgLy8gYXJyYXkgYW5kIHRoZW4gY29weS4KKyAgICBmaW5hbCBieXRlW10gYnl0ZXMgPSB2YWx1ZS5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICB3cml0ZVJhd1ZhcmludDMyKGJ5dGVzLmxlbmd0aCk7CisgICAgd3JpdGVSYXdCeXRlcyhieXRlcyk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZ3JvdXB9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlR3JvdXBOb1RhZyhmaW5hbCBNZXNzYWdlTGl0ZSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB2YWx1ZS53cml0ZVRvKHRoaXMpOworICB9CisKKworICAvKioKKyAgICogV3JpdGUgYSBncm91cCByZXByZXNlbnRlZCBieSBhbiB7QGxpbmsgVW5rbm93bkZpZWxkU2V0fS4KKyAgICoKKyAgICogQGRlcHJlY2F0ZWQgVW5rbm93bkZpZWxkU2V0IG5vdyBpbXBsZW1lbnRzIE1lc3NhZ2VMaXRlLCBzbyB5b3UgY2FuIGp1c3QKKyAgICogICAgICAgICAgICAgY2FsbCB7QGxpbmsgI3dyaXRlR3JvdXBOb1RhZ30uCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgdm9pZCB3cml0ZVVua25vd25Hcm91cE5vVGFnKGZpbmFsIE1lc3NhZ2VMaXRlIHZhbHVlKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZUdyb3VwTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVNZXNzYWdlTm9UYWcoZmluYWwgTWVzc2FnZUxpdGUgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQzMih2YWx1ZS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgICB2YWx1ZS53cml0ZVRvKHRoaXMpOworICB9CisKKworICAvKiogV3JpdGUgYSB7QGNvZGUgYnl0ZXN9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlQnl0ZXNOb1RhZyhmaW5hbCBCeXRlU3RyaW5nIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3VmFyaW50MzIodmFsdWUuc2l6ZSgpKTsKKyAgICB3cml0ZVJhd0J5dGVzKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBieXRlc30gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVCeXRlQXJyYXlOb1RhZyhmaW5hbCBieXRlW10gdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQzMih2YWx1ZS5sZW5ndGgpOworICAgIHdyaXRlUmF3Qnl0ZXModmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGJ5dGVzfSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUJ5dGVBcnJheU5vVGFnKGZpbmFsIGJ5dGVbXSB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQzMihsZW5ndGgpOworICAgIHdyaXRlUmF3Qnl0ZXModmFsdWUsIG9mZnNldCwgbGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhIHtAY29kZSBieXRlc30gZmllbGQgdG8gdGhlIHN0cmVhbS4gIFRoaXMgbWV0aG9kIHdpbGwgd3JpdGUgYWxsCisgICAqIGNvbnRlbnQgb2YgdGhlIEJ5dGVCdWZmZXIgcmVnYXJkbGVzcyBvZiB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgbGltaXQKKyAgICogKGkuZS4sIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYmUgd3JpdHRlbiBpcyB2YWx1ZS5jYXBhY2l0eSgpLCBub3QKKyAgICogdmFsdWUucmVtYWluaW5nKCkpLiBGdXJ0aGVybW9yZSwgdGhpcyBtZXRob2QgZG9lc24ndCBhbHRlciB0aGUgc3RhdGUgb2YKKyAgICogdGhlIHBhc3NlZC1pbiBCeXRlQnVmZmVyLiBJdHMgcG9zaXRpb24sIGxpbWl0LCBtYXJrLCBldGMuIHdpbGwgcmVtYWluCisgICAqIHVuY2hhbmdlZC4gSWYgeW91IG9ubHkgd2FudCB0byB3cml0ZSB0aGUgcmVtYWluaW5nIGJ5dGVzIG9mIGEgQnl0ZUJ1ZmZlciwKKyAgICogeW91IGNhbiBjYWxsIHtAY29kZSB3cml0ZUJ5dGVCdWZmZXJOb1RhZyhieXRlQnVmZmVyLnNsaWNlKCkpfS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlQnl0ZUJ1ZmZlck5vVGFnKGZpbmFsIEJ5dGVCdWZmZXIgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQzMih2YWx1ZS5jYXBhY2l0eSgpKTsKKyAgICB3cml0ZVJhd0J5dGVzKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSB1aW50MzJ9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVUludDMyTm9UYWcoZmluYWwgaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3VmFyaW50MzIodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlIGFuIGVudW0gZmllbGQgdG8gdGhlIHN0cmVhbS4gIENhbGxlciBpcyByZXNwb25zaWJsZQorICAgKiBmb3IgY29udmVydGluZyB0aGUgZW51bSB2YWx1ZSB0byBpdHMgbnVtZXJpYyB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRW51bU5vVGFnKGZpbmFsIGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZUludDMyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBzZml4ZWQzMn0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTRml4ZWQzMk5vVGFnKGZpbmFsIGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0xpdHRsZUVuZGlhbjMyKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgc2ZpeGVkNjR9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlU0ZpeGVkNjROb1RhZyhmaW5hbCBsb25nIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3TGl0dGxlRW5kaWFuNjQodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBzaW50MzJ9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlU0ludDMyTm9UYWcoZmluYWwgaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3VmFyaW50MzIoZW5jb2RlWmlnWmFnMzIodmFsdWUpKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgc2ludDY0fSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVNJbnQ2NE5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQ2NChlbmNvZGVaaWdaYWc2NCh2YWx1ZSkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBkb3VibGV9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZURvdWJsZVNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBkb3VibGUgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZURvdWJsZVNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBmbG9hdH0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRmxvYXRTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgZmxvYXQgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUZsb2F0U2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIHVpbnQ2NH0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlVUludDY0U2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhbgorICAgKiB7QGNvZGUgaW50NjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUludDY0U2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUludDY0U2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBpbnQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlSW50MzJTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVJbnQzMlNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBmaXhlZDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVGaXhlZDY0U2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVGaXhlZDY0U2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGZpeGVkMzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUZpeGVkMzJTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlRml4ZWQzMlNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBib29sfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVCb29sU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVCb29sU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIHN0cmluZ30gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlU3RyaW5nU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGdyb3VwfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVHcm91cFNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VMaXRlIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSAqIDIgKyBjb21wdXRlR3JvdXBTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgZ3JvdXB9IGZpZWxkIHJlcHJlc2VudGVkIGJ5IGFuIHtAY29kZSBVbmtub3duRmllbGRTZXR9LCBpbmNsdWRpbmcKKyAgICogdGFnLgorICAgKgorICAgKiBAZGVwcmVjYXRlZCBVbmtub3duRmllbGRTZXQgbm93IGltcGxlbWVudHMgTWVzc2FnZUxpdGUsIHNvIHlvdSBjYW4ganVzdAorICAgKiAgICAgICAgICAgICBjYWxsIHtAbGluayAjY29tcHV0ZUdyb3VwU2l6ZX0uCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlVW5rbm93bkdyb3VwU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VMaXRlIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVHcm91cFNpemUoZmllbGROdW1iZXIsIHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlTWVzc2FnZVNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVzc2FnZUxpdGUgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZU1lc3NhZ2VTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgYnl0ZXN9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUJ5dGVzU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlQnl0ZXNTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgYnl0ZXN9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUJ5dGVBcnJheVNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUJ5dGVBcnJheVNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBieXRlc30gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlQnl0ZUJ1ZmZlclNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVCeXRlQnVmZmVyU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIGVtYmVkZGVkIG1lc3NhZ2UgaW4gbGF6eSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVMYXp5RmllbGRTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTGF6eUZpZWxkTGl0ZSB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlTGF6eUZpZWxkU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIHVpbnQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlVUludDMyU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlVUludDMyU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIGVudW0gZmllbGQsIGluY2x1ZGluZyB0YWcuICBDYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGNvbnZlcnRpbmcgdGhlCisgICAqIGVudW0gdmFsdWUgdG8gaXRzIG51bWVyaWMgdmFsdWUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRW51bVNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUVudW1TaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNmaXhlZDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTRml4ZWQzMlNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlU0ZpeGVkMzJTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNmaXhlZDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTRml4ZWQ2NFNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZVNGaXhlZDY0U2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBzaW50MzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVNJbnQzMlNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZVNJbnQzMlNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhbgorICAgKiB7QGNvZGUgc2ludDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTSW50NjRTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlU0ludDY0U2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICogTWVzc2FnZVNldCBleHRlbnNpb24gdG8gdGhlIHN0cmVhbS4gIEZvciBoaXN0b3JpY2FsIHJlYXNvbnMsCisgICAqIHRoZSB3aXJlIGZvcm1hdCBkaWZmZXJzIGZyb20gbm9ybWFsIGZpZWxkcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVNZXNzYWdlU2V0RXh0ZW5zaW9uU2l6ZSgKKyAgICAgIGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgTWVzc2FnZUxpdGUgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9JVEVNKSAqIDIgKworICAgICAgICAgICBjb21wdXRlVUludDMyU2l6ZShXaXJlRm9ybWF0Lk1FU1NBR0VfU0VUX1RZUEVfSUQsIGZpZWxkTnVtYmVyKSArCisgICAgICAgICAgIGNvbXB1dGVNZXNzYWdlU2l6ZShXaXJlRm9ybWF0Lk1FU1NBR0VfU0VUX01FU1NBR0UsIHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHVucGFyc2VkIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBGb3IKKyAgICogaGlzdG9yaWNhbCByZWFzb25zLCB0aGUgd2lyZSBmb3JtYXQgZGlmZmVycyBmcm9tIG5vcm1hbCBmaWVsZHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlUmF3TWVzc2FnZVNldEV4dGVuc2lvblNpemUoCisgICAgICBmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIEJ5dGVTdHJpbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9JVEVNKSAqIDIgKworICAgICAgICAgICBjb21wdXRlVUludDMyU2l6ZShXaXJlRm9ybWF0Lk1FU1NBR0VfU0VUX1RZUEVfSUQsIGZpZWxkTnVtYmVyKSArCisgICAgICAgICAgIGNvbXB1dGVCeXRlc1NpemUoV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9NRVNTQUdFLCB2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhbgorICAgKiBsYXppbHkgcGFyc2VkIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBGb3IKKyAgICogaGlzdG9yaWNhbCByZWFzb25zLCB0aGUgd2lyZSBmb3JtYXQgZGlmZmVycyBmcm9tIG5vcm1hbCBmaWVsZHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlTGF6eUZpZWxkTWVzc2FnZVNldEV4dGVuc2lvblNpemUoCisgICAgICBmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIExhenlGaWVsZExpdGUgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9JVEVNKSAqIDIgKworICAgICAgICAgICBjb21wdXRlVUludDMyU2l6ZShXaXJlRm9ybWF0Lk1FU1NBR0VfU0VUX1RZUEVfSUQsIGZpZWxkTnVtYmVyKSArCisgICAgICAgICAgIGNvbXB1dGVMYXp5RmllbGRTaXplKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfTUVTU0FHRSwgdmFsdWUpOworICB9CisgIAorICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGRvdWJsZX0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRG91YmxlU2l6ZU5vVGFnKGZpbmFsIGRvdWJsZSB2YWx1ZSkgeworICAgIHJldHVybiBMSVRUTEVfRU5ESUFOXzY0X1NJWkU7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBmbG9hdH0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRmxvYXRTaXplTm9UYWcoZmluYWwgZmxvYXQgdmFsdWUpIHsKKyAgICByZXR1cm4gTElUVExFX0VORElBTl8zMl9TSVpFOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgdWludDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVVSW50NjRTaXplTm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50NjRTaXplKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBpbnQ2NH0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlSW50NjRTaXplTm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50NjRTaXplKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBpbnQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlSW50MzJTaXplTm9UYWcoZmluYWwgaW50IHZhbHVlKSB7CisgICAgaWYgKHZhbHVlID49IDApIHsKKyAgICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTXVzdCBzaWduLWV4dGVuZC4KKyAgICAgIHJldHVybiAxMDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBmaXhlZDY0fSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVGaXhlZDY0U2l6ZU5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gTElUVExFX0VORElBTl82NF9TSVpFOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgZml4ZWQzMn0gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRml4ZWQzMlNpemVOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gTElUVExFX0VORElBTl8zMl9TSVpFOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgYm9vbH0gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlQm9vbFNpemVOb1RhZyhmaW5hbCBib29sZWFuIHZhbHVlKSB7CisgICAgcmV0dXJuIDE7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBzdHJpbmd9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhmaW5hbCBTdHJpbmcgdmFsdWUpIHsKKyAgICB0cnkgeworICAgICAgZmluYWwgYnl0ZVtdIGJ5dGVzID0gdmFsdWUuZ2V0Qnl0ZXMoIlVURi04Iik7CisgICAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShieXRlcy5sZW5ndGgpICsKKyAgICAgICAgICAgICBieXRlcy5sZW5ndGg7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVVRGLTggbm90IHN1cHBvcnRlZC4iLCBlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBncm91cH0gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlR3JvdXBTaXplTm9UYWcoZmluYWwgTWVzc2FnZUxpdGUgdmFsdWUpIHsKKyAgICByZXR1cm4gdmFsdWUuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGdyb3VwfSBmaWVsZCByZXByZXNlbnRlZCBieSBhbiB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fSwgaW5jbHVkaW5nCisgICAqIHRhZy4KKyAgICoKKyAgICogQGRlcHJlY2F0ZWQgVW5rbm93bkZpZWxkU2V0IG5vdyBpbXBsZW1lbnRzIE1lc3NhZ2VMaXRlLCBzbyB5b3UgY2FuIGp1c3QKKyAgICogICAgICAgICAgICAgY2FsbCB7QGxpbmsgI2NvbXB1dGVVbmtub3duR3JvdXBTaXplTm9UYWd9LgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVVua25vd25Hcm91cFNpemVOb1RhZyhmaW5hbCBNZXNzYWdlTGl0ZSB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlR3JvdXBTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4gZW1iZWRkZWQKKyAgICogbWVzc2FnZSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVNZXNzYWdlU2l6ZU5vVGFnKGZpbmFsIE1lc3NhZ2VMaXRlIHZhbHVlKSB7CisgICAgZmluYWwgaW50IHNpemUgPSB2YWx1ZS5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKHNpemUpICsgc2l6ZTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuIGVtYmVkZGVkCisgICAqIG1lc3NhZ2Ugc3RvcmVkIGluIGxhenkgZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlTGF6eUZpZWxkU2l6ZU5vVGFnKGZpbmFsIExhenlGaWVsZExpdGUgdmFsdWUpIHsKKyAgICBmaW5hbCBpbnQgc2l6ZSA9IHZhbHVlLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgcmV0dXJuIGNvbXB1dGVSYXdWYXJpbnQzMlNpemUoc2l6ZSkgKyBzaXplOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgYnl0ZXN9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUJ5dGVzU2l6ZU5vVGFnKGZpbmFsIEJ5dGVTdHJpbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZSh2YWx1ZS5zaXplKCkpICsKKyAgICAgICAgICAgdmFsdWUuc2l6ZSgpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgYnl0ZXN9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUJ5dGVBcnJheVNpemVOb1RhZyhmaW5hbCBieXRlW10gdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZSh2YWx1ZS5sZW5ndGgpICsgdmFsdWUubGVuZ3RoOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgYnl0ZXN9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUJ5dGVCdWZmZXJTaXplTm9UYWcoZmluYWwgQnl0ZUJ1ZmZlciB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKHZhbHVlLmNhcGFjaXR5KCkpICsgdmFsdWUuY2FwYWNpdHkoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIHVpbnQzMn0gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlVUludDMyU2l6ZU5vVGFnKGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuIGVudW0gZmllbGQuCisgICAqIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgY29udmVydGluZyB0aGUgZW51bSB2YWx1ZSB0byBpdHMgbnVtZXJpYyB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVFbnVtU2l6ZU5vVGFnKGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlSW50MzJTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNmaXhlZDMyfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTRml4ZWQzMlNpemVOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gTElUVExFX0VORElBTl8zMl9TSVpFOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNmaXhlZDY0fSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTRml4ZWQ2NFNpemVOb1RhZyhmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgcmV0dXJuIExJVFRMRV9FTkRJQU5fNjRfU0laRTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBzaW50MzJ9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShlbmNvZGVaaWdaYWczMih2YWx1ZSkpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNpbnQ2NH0gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlU0ludDY0U2l6ZU5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDY0U2l6ZShlbmNvZGVaaWdaYWc2NCh2YWx1ZSkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogSW50ZXJuYWwgaGVscGVyIHRoYXQgd3JpdGVzIHRoZSBjdXJyZW50IGJ1ZmZlciB0byB0aGUgb3V0cHV0LiBUaGUKKyAgICogYnVmZmVyIHBvc2l0aW9uIGlzIHJlc2V0IHRvIGl0cyBpbml0aWFsIHZhbHVlIHdoZW4gdGhpcyByZXR1cm5zLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHJlZnJlc2hCdWZmZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChvdXRwdXQgPT0gbnVsbCkgeworICAgICAgLy8gV2UncmUgd3JpdGluZyB0byBhIHNpbmdsZSBidWZmZXIuCisgICAgICB0aHJvdyBuZXcgT3V0T2ZTcGFjZUV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8vIFNpbmNlIHdlIGhhdmUgYW4gb3V0cHV0IHN0cmVhbSwgdGhpcyBpcyBvdXIgYnVmZmVyCisgICAgLy8gYW5kIGJ1ZmZlciBvZmZzZXQgPT0gMAorICAgIG91dHB1dC53cml0ZShidWZmZXIsIDAsIHBvc2l0aW9uKTsKKyAgICBwb3NpdGlvbiA9IDA7CisgIH0KKworICAvKioKKyAgICogRmx1c2hlcyB0aGUgc3RyZWFtIGFuZCBmb3JjZXMgYW55IGJ1ZmZlcmVkIGJ5dGVzIHRvIGJlIHdyaXR0ZW4uICBUaGlzCisgICAqIGRvZXMgbm90IGZsdXNoIHRoZSB1bmRlcmx5aW5nIE91dHB1dFN0cmVhbS4KKyAgICovCisgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAob3V0cHV0ICE9IG51bGwpIHsKKyAgICAgIHJlZnJlc2hCdWZmZXIoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogSWYgd3JpdGluZyB0byBhIGZsYXQgYXJyYXksIHJldHVybiB0aGUgc3BhY2UgbGVmdCBpbiB0aGUgYXJyYXkuCisgICAqIE90aGVyd2lzZSwgdGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgICAqLworICBwdWJsaWMgaW50IHNwYWNlTGVmdCgpIHsKKyAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgIHJldHVybiBsaW1pdCAtIHBvc2l0aW9uOworICAgIH0gZWxzZSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICJzcGFjZUxlZnQoKSBjYW4gb25seSBiZSBjYWxsZWQgb24gQ29kZWRPdXRwdXRTdHJlYW1zIHRoYXQgYXJlICIgKworICAgICAgICAid3JpdGluZyB0byBhIGZsYXQgYXJyYXkuIik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQge0BsaW5rICNzcGFjZUxlZnQoKX0gcmV0dXJucyB6ZXJvLiAgSXQncyBjb21tb24gdG8gY3JlYXRlCisgICAqIGEgYnl0ZSBhcnJheSB0aGF0IGlzIGV4YWN0bHkgYmlnIGVub3VnaCB0byBob2xkIGEgbWVzc2FnZSwgdGhlbiB3cml0ZSB0bworICAgKiBpdCB3aXRoIGEge0Bjb2RlIENvZGVkT3V0cHV0U3RyZWFtfS4gIENhbGxpbmcge0Bjb2RlIGNoZWNrTm9TcGFjZUxlZnQoKX0KKyAgICogYWZ0ZXIgd3JpdGluZyB2ZXJpZmllcyB0aGF0IHRoZSBtZXNzYWdlIHdhcyBhY3R1YWxseSBhcyBiaWcgYXMgZXhwZWN0ZWQsCisgICAqIHdoaWNoIGNhbiBoZWxwIGNhdGNoIGJ1Z3MuCisgICAqLworICBwdWJsaWMgdm9pZCBjaGVja05vU3BhY2VMZWZ0KCkgeworICAgIGlmIChzcGFjZUxlZnQoKSAhPSAwKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAiRGlkIG5vdCB3cml0ZSBhcyBtdWNoIGRhdGEgYXMgZXhwZWN0ZWQuIik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIElmIHlvdSBjcmVhdGUgYSBDb2RlZE91dHB1dFN0cmVhbSBhcm91bmQgYSBzaW1wbGUgZmxhdCBhcnJheSwgeW91IG11c3QKKyAgICogbm90IGF0dGVtcHQgdG8gd3JpdGUgbW9yZSBieXRlcyB0aGFuIHRoZSBhcnJheSBoYXMgc3BhY2UuICBPdGhlcndpc2UsCisgICAqIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBPdXRPZlNwYWNlRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02OTQ3NDg2ODg2OTk3ODg5NDk5TDsKKworICAgIE91dE9mU3BhY2VFeGNlcHRpb24oKSB7CisgICAgICBzdXBlcigiQ29kZWRPdXRwdXRTdHJlYW0gd2FzIHdyaXRpbmcgdG8gYSBmbGF0IGJ5dGUgYXJyYXkgYW5kIHJhbiAiICsKKyAgICAgICAgICAgICJvdXQgb2Ygc3BhY2UuIik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHN1Y2Nlc3NmdWxseSB3cml0dGVuIHRvIHRoaXMgc3RyZWFtLiAgVGhlCisgICAqIHJldHVybmVkIHZhbHVlIGlzIG5vdCBndWFyYW50ZWVkIHRvIGJlIGFjY3VyYXRlIGlmIGV4Y2VwdGlvbnMgaGF2ZSBiZWVuCisgICAqIGZvdW5kIGluIHRoZSBtaWRkbGUgb2Ygd3JpdGluZy4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0VG90YWxCeXRlc1dyaXR0ZW4oKSB7CisgICAgcmV0dXJuIHRvdGFsQnl0ZXNXcml0dGVuOworICB9CisKKyAgLyoqIFdyaXRlIGEgc2luZ2xlIGJ5dGUuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlUmF3Qnl0ZShmaW5hbCBieXRlIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgcmVmcmVzaEJ1ZmZlcigpOworICAgIH0KKworICAgIGJ1ZmZlcltwb3NpdGlvbisrXSA9IHZhbHVlOworICAgICsrdG90YWxCeXRlc1dyaXR0ZW47CisgIH0KKworICAvKiogV3JpdGUgYSBzaW5nbGUgYnl0ZSwgcmVwcmVzZW50ZWQgYnkgYW4gaW50ZWdlciB2YWx1ZS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVSYXdCeXRlKGZpbmFsIGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0J5dGUoKGJ5dGUpIHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIGJ5dGUgc3RyaW5nLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0J5dGVzKGZpbmFsIEJ5dGVTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdCeXRlcyh2YWx1ZSwgMCwgdmFsdWUuc2l6ZSgpKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiBhcnJheSBvZiBieXRlcy4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVSYXdCeXRlcyhmaW5hbCBieXRlW10gdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdCeXRlcyh2YWx1ZSwgMCwgdmFsdWUubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhIEJ5dGVCdWZmZXIuIFRoaXMgbWV0aG9kIHdpbGwgd3JpdGUgYWxsIGNvbnRlbnQgb2YgdGhlIEJ5dGVCdWZmZXIKKyAgICogcmVnYXJkbGVzcyBvZiB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgbGltaXQgKGkuZS4sIHRoZSBudW1iZXIgb2YgYnl0ZXMKKyAgICogdG8gYmUgd3JpdHRlbiBpcyB2YWx1ZS5jYXBhY2l0eSgpLCBub3QgdmFsdWUucmVtYWluaW5nKCkpLiBGdXJ0aGVybW9yZSwKKyAgICogdGhpcyBtZXRob2QgZG9lc24ndCBhbHRlciB0aGUgc3RhdGUgb2YgdGhlIHBhc3NlZC1pbiBCeXRlQnVmZmVyLiBJdHMKKyAgICogcG9zaXRpb24sIGxpbWl0LCBtYXJrLCBldGMuIHdpbGwgcmVtYWluIHVuY2hhbmdlZC4gSWYgeW91IG9ubHkgd2FudCB0bworICAgKiB3cml0ZSB0aGUgcmVtYWluaW5nIGJ5dGVzIG9mIGEgQnl0ZUJ1ZmZlciwgeW91IGNhbiBjYWxsCisgICAqIHtAY29kZSB3cml0ZVJhd0J5dGVzKGJ5dGVCdWZmZXIuc2xpY2UoKSl9LgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVSYXdCeXRlcyhmaW5hbCBCeXRlQnVmZmVyIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh2YWx1ZS5oYXNBcnJheSgpKSB7CisgICAgICB3cml0ZVJhd0J5dGVzKHZhbHVlLmFycmF5KCksIHZhbHVlLmFycmF5T2Zmc2V0KCksIHZhbHVlLmNhcGFjaXR5KCkpOworICAgIH0gZWxzZSB7CisgICAgICBCeXRlQnVmZmVyIGR1cGxpY2F0ZWQgPSB2YWx1ZS5kdXBsaWNhdGUoKTsKKyAgICAgIGR1cGxpY2F0ZWQuY2xlYXIoKTsKKyAgICAgIHdyaXRlUmF3Qnl0ZXNJbnRlcm5hbChkdXBsaWNhdGVkKTsKKyAgICB9CisgIH0KKworICAvKiogV3JpdGUgYSBCeXRlQnVmZmVyIHRoYXQgaXNuJ3QgYmFja2VkIGJ5IGFuIGFycmF5LiAqLworICBwcml2YXRlIHZvaWQgd3JpdGVSYXdCeXRlc0ludGVybmFsKGZpbmFsIEJ5dGVCdWZmZXIgdmFsdWUpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCBsZW5ndGggPSB2YWx1ZS5yZW1haW5pbmcoKTsKKyAgICBpZiAobGltaXQgLSBwb3NpdGlvbiA+PSBsZW5ndGgpIHsKKyAgICAgIC8vIFdlIGhhdmUgcm9vbSBpbiB0aGUgY3VycmVudCBidWZmZXIuCisgICAgICB2YWx1ZS5nZXQoYnVmZmVyLCBwb3NpdGlvbiwgbGVuZ3RoKTsKKyAgICAgIHBvc2l0aW9uICs9IGxlbmd0aDsKKyAgICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IGxlbmd0aDsKKyAgICB9IGVsc2UgeworICAgICAgLy8gV3JpdGUgZXh0ZW5kcyBwYXN0IGN1cnJlbnQgYnVmZmVyLiAgRmlsbCB0aGUgcmVzdCBvZiB0aGlzIGJ1ZmZlciBhbmQKKyAgICAgIC8vIGZsdXNoLgorICAgICAgZmluYWwgaW50IGJ5dGVzV3JpdHRlbiA9IGxpbWl0IC0gcG9zaXRpb247CisgICAgICB2YWx1ZS5nZXQoYnVmZmVyLCBwb3NpdGlvbiwgYnl0ZXNXcml0dGVuKTsKKyAgICAgIGxlbmd0aCAtPSBieXRlc1dyaXR0ZW47CisgICAgICBwb3NpdGlvbiA9IGxpbWl0OworICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gYnl0ZXNXcml0dGVuOworICAgICAgcmVmcmVzaEJ1ZmZlcigpOworCisgICAgICAvLyBOb3cgZGVhbCB3aXRoIHRoZSByZXN0LgorICAgICAgLy8gU2luY2Ugd2UgaGF2ZSBhbiBvdXRwdXQgc3RyZWFtLCB0aGlzIGlzIG91ciBidWZmZXIKKyAgICAgIC8vIGFuZCBidWZmZXIgb2Zmc2V0ID09IDAKKyAgICAgIHdoaWxlIChsZW5ndGggPiBsaW1pdCkgeworICAgICAgICAvLyBDb3B5IGRhdGEgaW50byB0aGUgYnVmZmVyIGJlZm9yZSB3cml0aW5nIGl0IHRvIE91dHB1dFN0cmVhbS4KKyAgICAgICAgLy8gVE9ETyh4aWFvZmVuZyk6IEludHJvZHVjZSBaZXJvQ29weU91dHB1dFN0cmVhbSB0byBhdm9pZCB0aGlzIGNvcHkuCisgICAgICAgIHZhbHVlLmdldChidWZmZXIsIDAsIGxpbWl0KTsKKyAgICAgICAgb3V0cHV0LndyaXRlKGJ1ZmZlciwgMCwgbGltaXQpOworICAgICAgICBsZW5ndGggLT0gbGltaXQ7CisgICAgICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IGxpbWl0OworICAgICAgfQorICAgICAgdmFsdWUuZ2V0KGJ1ZmZlciwgMCwgbGVuZ3RoKTsKKyAgICAgIHBvc2l0aW9uID0gbGVuZ3RoOworICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gbGVuZ3RoOworICAgIH0KKyAgfQorCisgIC8qKiBXcml0ZSBwYXJ0IG9mIGFuIGFycmF5IG9mIGJ5dGVzLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0J5dGVzKGZpbmFsIGJ5dGVbXSB2YWx1ZSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChsaW1pdCAtIHBvc2l0aW9uID49IGxlbmd0aCkgeworICAgICAgLy8gV2UgaGF2ZSByb29tIGluIHRoZSBjdXJyZW50IGJ1ZmZlci4KKyAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIG9mZnNldCwgYnVmZmVyLCBwb3NpdGlvbiwgbGVuZ3RoKTsKKyAgICAgIHBvc2l0aW9uICs9IGxlbmd0aDsKKyAgICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IGxlbmd0aDsKKyAgICB9IGVsc2UgeworICAgICAgLy8gV3JpdGUgZXh0ZW5kcyBwYXN0IGN1cnJlbnQgYnVmZmVyLiAgRmlsbCB0aGUgcmVzdCBvZiB0aGlzIGJ1ZmZlciBhbmQKKyAgICAgIC8vIGZsdXNoLgorICAgICAgZmluYWwgaW50IGJ5dGVzV3JpdHRlbiA9IGxpbWl0IC0gcG9zaXRpb247CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCBvZmZzZXQsIGJ1ZmZlciwgcG9zaXRpb24sIGJ5dGVzV3JpdHRlbik7CisgICAgICBvZmZzZXQgKz0gYnl0ZXNXcml0dGVuOworICAgICAgbGVuZ3RoIC09IGJ5dGVzV3JpdHRlbjsKKyAgICAgIHBvc2l0aW9uID0gbGltaXQ7CisgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBieXRlc1dyaXR0ZW47CisgICAgICByZWZyZXNoQnVmZmVyKCk7CisKKyAgICAgIC8vIE5vdyBkZWFsIHdpdGggdGhlIHJlc3QuCisgICAgICAvLyBTaW5jZSB3ZSBoYXZlIGFuIG91dHB1dCBzdHJlYW0sIHRoaXMgaXMgb3VyIGJ1ZmZlcgorICAgICAgLy8gYW5kIGJ1ZmZlciBvZmZzZXQgPT0gMAorICAgICAgaWYgKGxlbmd0aCA8PSBsaW1pdCkgeworICAgICAgICAvLyBGaXRzIGluIG5ldyBidWZmZXIuCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIG9mZnNldCwgYnVmZmVyLCAwLCBsZW5ndGgpOworICAgICAgICBwb3NpdGlvbiA9IGxlbmd0aDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFdyaXRlIGlzIHZlcnkgYmlnLiAgTGV0J3MgZG8gaXQgYWxsIGF0IG9uY2UuCisgICAgICAgIG91dHB1dC53cml0ZSh2YWx1ZSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgfQorICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gbGVuZ3RoOworICAgIH0KKyAgfQorCisgIC8qKiBXcml0ZSBwYXJ0IG9mIGEgYnl0ZSBzdHJpbmcuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlUmF3Qnl0ZXMoZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChsaW1pdCAtIHBvc2l0aW9uID49IGxlbmd0aCkgeworICAgICAgLy8gV2UgaGF2ZSByb29tIGluIHRoZSBjdXJyZW50IGJ1ZmZlci4KKyAgICAgIHZhbHVlLmNvcHlUbyhidWZmZXIsIG9mZnNldCwgcG9zaXRpb24sIGxlbmd0aCk7CisgICAgICBwb3NpdGlvbiArPSBsZW5ndGg7CisgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBsZW5ndGg7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFdyaXRlIGV4dGVuZHMgcGFzdCBjdXJyZW50IGJ1ZmZlci4gIEZpbGwgdGhlIHJlc3Qgb2YgdGhpcyBidWZmZXIgYW5kCisgICAgICAvLyBmbHVzaC4KKyAgICAgIGZpbmFsIGludCBieXRlc1dyaXR0ZW4gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgdmFsdWUuY29weVRvKGJ1ZmZlciwgb2Zmc2V0LCBwb3NpdGlvbiwgYnl0ZXNXcml0dGVuKTsKKyAgICAgIG9mZnNldCArPSBieXRlc1dyaXR0ZW47CisgICAgICBsZW5ndGggLT0gYnl0ZXNXcml0dGVuOworICAgICAgcG9zaXRpb24gPSBsaW1pdDsKKyAgICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IGJ5dGVzV3JpdHRlbjsKKyAgICAgIHJlZnJlc2hCdWZmZXIoKTsKKworICAgICAgLy8gTm93IGRlYWwgd2l0aCB0aGUgcmVzdC4KKyAgICAgIC8vIFNpbmNlIHdlIGhhdmUgYW4gb3V0cHV0IHN0cmVhbSwgdGhpcyBpcyBvdXIgYnVmZmVyCisgICAgICAvLyBhbmQgYnVmZmVyIG9mZnNldCA9PSAwCisgICAgICBpZiAobGVuZ3RoIDw9IGxpbWl0KSB7CisgICAgICAgIC8vIEZpdHMgaW4gbmV3IGJ1ZmZlci4KKyAgICAgICAgdmFsdWUuY29weVRvKGJ1ZmZlciwgb2Zmc2V0LCAwLCBsZW5ndGgpOworICAgICAgICBwb3NpdGlvbiA9IGxlbmd0aDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHZhbHVlLndyaXRlVG8ob3V0cHV0LCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICB9CisgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBsZW5ndGg7CisgICAgfQorICB9CisKKyAgLyoqIEVuY29kZSBhbmQgd3JpdGUgYSB0YWcuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVGFnKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHdpcmVUeXBlKQorICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3VmFyaW50MzIoV2lyZUZvcm1hdC5tYWtlVGFnKGZpZWxkTnVtYmVyLCB3aXJlVHlwZSkpOworICB9CisKKyAgLyoqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYSB0YWcuICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVUYWdTaXplKGZpbmFsIGludCBmaWVsZE51bWJlcikgeworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKFdpcmVGb3JtYXQubWFrZVRhZyhmaWVsZE51bWJlciwgMCkpOworICB9CisKKyAgLyoqCisgICAqIEVuY29kZSBhbmQgd3JpdGUgYSB2YXJpbnQuICB7QGNvZGUgdmFsdWV9IGlzIHRyZWF0ZWQgYXMKKyAgICogdW5zaWduZWQsIHNvIGl0IHdvbid0IGJlIHNpZ24tZXh0ZW5kZWQgaWYgbmVnYXRpdmUuCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd1ZhcmludDMyKGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgaWYgKCh2YWx1ZSAmIH4weDdGKSA9PSAwKSB7CisgICAgICAgIHdyaXRlUmF3Qnl0ZSh2YWx1ZSk7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHdyaXRlUmF3Qnl0ZSgodmFsdWUgJiAweDdGKSB8IDB4ODApOworICAgICAgICB2YWx1ZSA+Pj49IDc7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYSB2YXJpbnQuCisgICAqIHtAY29kZSB2YWx1ZX0gaXMgdHJlYXRlZCBhcyB1bnNpZ25lZCwgc28gaXQgd29uJ3QgYmUgc2lnbi1leHRlbmRlZCBpZgorICAgKiBuZWdhdGl2ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZmluYWwgaW50IHZhbHVlKSB7CisgICAgaWYgKCh2YWx1ZSAmICgweGZmZmZmZmZmIDw8ICA3KSkgPT0gMCkgcmV0dXJuIDE7CisgICAgaWYgKCh2YWx1ZSAmICgweGZmZmZmZmZmIDw8IDE0KSkgPT0gMCkgcmV0dXJuIDI7CisgICAgaWYgKCh2YWx1ZSAmICgweGZmZmZmZmZmIDw8IDIxKSkgPT0gMCkgcmV0dXJuIDM7CisgICAgaWYgKCh2YWx1ZSAmICgweGZmZmZmZmZmIDw8IDI4KSkgPT0gMCkgcmV0dXJuIDQ7CisgICAgcmV0dXJuIDU7CisgIH0KKworICAvKiogRW5jb2RlIGFuZCB3cml0ZSBhIHZhcmludC4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVSYXdWYXJpbnQ2NChsb25nIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpZiAoKHZhbHVlICYgfjB4N0ZMKSA9PSAwKSB7CisgICAgICAgIHdyaXRlUmF3Qnl0ZSgoaW50KXZhbHVlKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgd3JpdGVSYXdCeXRlKCgoaW50KXZhbHVlICYgMHg3RikgfCAweDgwKTsKKyAgICAgICAgdmFsdWUgPj4+PSA3OworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEgdmFyaW50LiAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlUmF3VmFyaW50NjRTaXplKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgIDcpKSA9PSAwKSByZXR1cm4gMTsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgMTQpKSA9PSAwKSByZXR1cm4gMjsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgMjEpKSA9PSAwKSByZXR1cm4gMzsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgMjgpKSA9PSAwKSByZXR1cm4gNDsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgMzUpKSA9PSAwKSByZXR1cm4gNTsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgNDIpKSA9PSAwKSByZXR1cm4gNjsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgNDkpKSA9PSAwKSByZXR1cm4gNzsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgNTYpKSA9PSAwKSByZXR1cm4gODsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmZmZmZmZmZmZkwgPDwgNjMpKSA9PSAwKSByZXR1cm4gOTsKKyAgICByZXR1cm4gMTA7CisgIH0KKworICAvKiogV3JpdGUgYSBsaXR0bGUtZW5kaWFuIDMyLWJpdCBpbnRlZ2VyLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0xpdHRsZUVuZGlhbjMyKGZpbmFsIGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0J5dGUoKHZhbHVlICAgICAgKSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgodmFsdWUgPj4gIDgpICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKCh2YWx1ZSA+PiAxNikgJiAweEZGKTsKKyAgICB3cml0ZVJhd0J5dGUoKHZhbHVlID4+IDI0KSAmIDB4RkYpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTElUVExFX0VORElBTl8zMl9TSVpFID0gNDsKKworICAvKiogV3JpdGUgYSBsaXR0bGUtZW5kaWFuIDY0LWJpdCBpbnRlZ2VyLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0xpdHRsZUVuZGlhbjY0KGZpbmFsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdCeXRlKChpbnQpKHZhbHVlICAgICAgKSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgoaW50KSh2YWx1ZSA+PiAgOCkgJiAweEZGKTsKKyAgICB3cml0ZVJhd0J5dGUoKGludCkodmFsdWUgPj4gMTYpICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKChpbnQpKHZhbHVlID4+IDI0KSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgoaW50KSh2YWx1ZSA+PiAzMikgJiAweEZGKTsKKyAgICB3cml0ZVJhd0J5dGUoKGludCkodmFsdWUgPj4gNDApICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKChpbnQpKHZhbHVlID4+IDQ4KSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgoaW50KSh2YWx1ZSA+PiA1NikgJiAweEZGKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExJVFRMRV9FTkRJQU5fNjRfU0laRSA9IDg7CisKKyAgLyoqCisgICAqIEVuY29kZSBhIFppZ1phZy1lbmNvZGVkIDMyLWJpdCB2YWx1ZS4gIFppZ1phZyBlbmNvZGVzIHNpZ25lZCBpbnRlZ2VycworICAgKiBpbnRvIHZhbHVlcyB0aGF0IGNhbiBiZSBlZmZpY2llbnRseSBlbmNvZGVkIHdpdGggdmFyaW50LiAgKE90aGVyd2lzZSwKKyAgICogbmVnYXRpdmUgdmFsdWVzIG11c3QgYmUgc2lnbi1leHRlbmRlZCB0byA2NCBiaXRzIHRvIGJlIHZhcmludCBlbmNvZGVkLAorICAgKiB0aHVzIGFsd2F5cyB0YWtpbmcgMTAgYnl0ZXMgb24gdGhlIHdpcmUuKQorICAgKgorICAgKiBAcGFyYW0gbiBBIHNpZ25lZCAzMi1iaXQgaW50ZWdlci4KKyAgICogQHJldHVybiBBbiB1bnNpZ25lZCAzMi1iaXQgaW50ZWdlciwgc3RvcmVkIGluIGEgc2lnbmVkIGludCBiZWNhdXNlCisgICAqICAgICAgICAgSmF2YSBoYXMgbm8gZXhwbGljaXQgdW5zaWduZWQgc3VwcG9ydC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGVuY29kZVppZ1phZzMyKGZpbmFsIGludCBuKSB7CisgICAgLy8gTm90ZTogIHRoZSByaWdodC1zaGlmdCBtdXN0IGJlIGFyaXRobWV0aWMKKyAgICByZXR1cm4gKG4gPDwgMSkgXiAobiA+PiAzMSk7CisgIH0KKworICAvKioKKyAgICogRW5jb2RlIGEgWmlnWmFnLWVuY29kZWQgNjQtYml0IHZhbHVlLiAgWmlnWmFnIGVuY29kZXMgc2lnbmVkIGludGVnZXJzCisgICAqIGludG8gdmFsdWVzIHRoYXQgY2FuIGJlIGVmZmljaWVudGx5IGVuY29kZWQgd2l0aCB2YXJpbnQuICAoT3RoZXJ3aXNlLAorICAgKiBuZWdhdGl2ZSB2YWx1ZXMgbXVzdCBiZSBzaWduLWV4dGVuZGVkIHRvIDY0IGJpdHMgdG8gYmUgdmFyaW50IGVuY29kZWQsCisgICAqIHRodXMgYWx3YXlzIHRha2luZyAxMCBieXRlcyBvbiB0aGUgd2lyZS4pCisgICAqCisgICAqIEBwYXJhbSBuIEEgc2lnbmVkIDY0LWJpdCBpbnRlZ2VyLgorICAgKiBAcmV0dXJuIEFuIHVuc2lnbmVkIDY0LWJpdCBpbnRlZ2VyLCBzdG9yZWQgaW4gYSBzaWduZWQgaW50IGJlY2F1c2UKKyAgICogICAgICAgICBKYXZhIGhhcyBubyBleHBsaWNpdCB1bnNpZ25lZCBzdXBwb3J0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGVuY29kZVppZ1phZzY0KGZpbmFsIGxvbmcgbikgeworICAgIC8vIE5vdGU6ICB0aGUgcmlnaHQtc2hpZnQgbXVzdCBiZSBhcml0aG1ldGljCisgICAgcmV0dXJuIChuIDw8IDEpIF4gKG4gPj4gNjMpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EZXNjcmlwdG9ycy5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRGVzY3JpcHRvcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDZmNDZjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRGVzY3JpcHRvcnMuamF2YQpAQCAtMCwwICsxLDIzNTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuKjsKKworaW1wb3J0IGphdmEubGFuZy5yZWYuV2Vha1JlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKKworLyoqCisgKiBDb250YWlucyBhIGNvbGxlY3Rpb24gb2YgY2xhc3NlcyB3aGljaCBkZXNjcmliZSBwcm90b2NvbCBtZXNzYWdlIHR5cGVzLgorICoKKyAqIEV2ZXJ5IG1lc3NhZ2UgdHlwZSBoYXMgYSB7QGxpbmsgRGVzY3JpcHRvcn0sIHdoaWNoIGxpc3RzIGFsbAorICogaXRzIGZpZWxkcyBhbmQgb3RoZXIgaW5mb3JtYXRpb24gYWJvdXQgYSB0eXBlLiAgWW91IGNhbiBnZXQgYSBtZXNzYWdlCisgKiB0eXBlJ3MgZGVzY3JpcHRvciBieSBjYWxsaW5nIHtAY29kZSBNZXNzYWdlVHlwZS5nZXREZXNjcmlwdG9yKCl9LCBvcgorICogKGdpdmVuIGEgbWVzc2FnZSBvYmplY3Qgb2YgdGhlIHR5cGUpIHtAY29kZSBtZXNzYWdlLmdldERlc2NyaXB0b3JGb3JUeXBlKCl9LgorICogRnVydGhlcm1vcmUsIGVhY2ggbWVzc2FnZSBpcyBhc3NvY2lhdGVkIHdpdGggYSB7QGxpbmsgRmlsZURlc2NyaXB0b3J9IGZvcgorICogYSByZWxldmFudCB7QGNvZGUgLnByb3RvfSBmaWxlLiBZb3UgY2FuIG9idGFpbiBpdCBieSBjYWxsaW5nCisgKiB7QGNvZGUgRGVzY3JpcHRvci5nZXRGaWxlKCl9LiBBIHtAbGluayBGaWxlRGVzY3JpcHRvcn0gY29udGFpbnMgZGVzY3JpcHRvcnMKKyAqIGZvciBhbGwgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhhdCBmaWxlLCBhbmQgZmlsZSBkZXNjcmlwdG9ycyBmb3IgYWxsIHRoZQorICogaW1wb3J0ZWQge0Bjb2RlIC5wcm90b30gZmlsZXMuCisgKgorICogRGVzY3JpcHRvcnMgYXJlIGJ1aWx0IGZyb20gRGVzY3JpcHRvclByb3RvcywgYXMgZGVmaW5lZCBpbgorICoge0Bjb2RlIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvfS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRGVzY3JpcHRvcnMgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2dnZXIgbG9nZ2VyID0KKyAgICAgIExvZ2dlci5nZXRMb2dnZXIoRGVzY3JpcHRvcnMuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgLyoqCisgICAqIERlc2NyaWJlcyBhIHtAY29kZSAucHJvdG99IGZpbGUsIGluY2x1ZGluZyBldmVyeXRoaW5nIGRlZmluZWQgd2l0aGluLgorICAgKiBUaGF0IGluY2x1ZGVzLCBpbiBwYXJ0aWN1bGFyLCBkZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBtZXNzYWdlcyBhbmQKKyAgICogZmlsZSBkZXNjcmlwdG9ycyBmb3IgYWxsIG90aGVyIGltcG9ydGVkIHtAY29kZSAucHJvdG99IGZpbGVzCisgICAqIChkZXBlbmRlbmNpZXMpLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWxlRGVzY3JpcHRvciBleHRlbmRzIEdlbmVyaWNEZXNjcmlwdG9yIHsKKyAgICAvKiogQ29udmVydCB0aGUgZGVzY3JpcHRvciB0byBpdHMgcHJvdG9jb2wgbWVzc2FnZSByZXByZXNlbnRhdGlvbi4gKi8KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3JQcm90byB0b1Byb3RvKCkgeyByZXR1cm4gcHJvdG87IH0KKworICAgIC8qKiBHZXQgdGhlIGZpbGUgbmFtZS4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBwcm90by5nZXROYW1lKCk7IH0KKworICAgIC8qKiBSZXR1cm5zIHRoaXMgb2JqZWN0LiAqLworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGaWxlKCkgeyByZXR1cm4gdGhpczsgfQorCisgICAgLyoqIFJldHVybnMgdGhlIHNhbWUgYXMgZ2V0TmFtZSgpLiAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnVsbE5hbWUoKSB7IHJldHVybiBwcm90by5nZXROYW1lKCk7IH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcHJvdG8gcGFja2FnZSBuYW1lLiAgVGhpcyBpcyB0aGUgcGFja2FnZSBuYW1lIGdpdmVuIGJ5IHRoZQorICAgICAqIHtAY29kZSBwYWNrYWdlfSBzdGF0ZW1lbnQgaW4gdGhlIHtAY29kZSAucHJvdG99IGZpbGUsIHdoaWNoIGRpZmZlcnMKKyAgICAgKiBmcm9tIHRoZSBKYXZhIHBhY2thZ2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQYWNrYWdlKCkgeyByZXR1cm4gcHJvdG8uZ2V0UGFja2FnZSgpOyB9CisKKyAgICAvKiogR2V0IHRoZSB7QGNvZGUgRmlsZU9wdGlvbnN9LCBkZWZpbmVkIGluIHtAY29kZSBkZXNjcmlwdG9yLnByb3RvfS4gKi8KKyAgICBwdWJsaWMgRmlsZU9wdGlvbnMgZ2V0T3B0aW9ucygpIHsgcmV0dXJuIHByb3RvLmdldE9wdGlvbnMoKTsgfQorCisgICAgLyoqIEdldCBhIGxpc3Qgb2YgdG9wLWxldmVsIG1lc3NhZ2UgdHlwZXMgZGVjbGFyZWQgaW4gdGhpcyBmaWxlLiAqLworICAgIHB1YmxpYyBMaXN0PERlc2NyaXB0b3I+IGdldE1lc3NhZ2VUeXBlcygpIHsKKyAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KEFycmF5cy5hc0xpc3QobWVzc2FnZVR5cGVzKSk7CisgICAgfQorCisgICAgLyoqIEdldCBhIGxpc3Qgb2YgdG9wLWxldmVsIGVudW0gdHlwZXMgZGVjbGFyZWQgaW4gdGhpcyBmaWxlLiAqLworICAgIHB1YmxpYyBMaXN0PEVudW1EZXNjcmlwdG9yPiBnZXRFbnVtVHlwZXMoKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChBcnJheXMuYXNMaXN0KGVudW1UeXBlcykpOworICAgIH0KKworICAgIC8qKiBHZXQgYSBsaXN0IG9mIHRvcC1sZXZlbCBzZXJ2aWNlcyBkZWNsYXJlZCBpbiB0aGlzIGZpbGUuICovCisgICAgcHVibGljIExpc3Q8U2VydmljZURlc2NyaXB0b3I+IGdldFNlcnZpY2VzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdChzZXJ2aWNlcykpOworICAgIH0KKworICAgIC8qKiBHZXQgYSBsaXN0IG9mIHRvcC1sZXZlbCBleHRlbnNpb25zIGRlY2xhcmVkIGluIHRoaXMgZmlsZS4gKi8KKyAgICBwdWJsaWMgTGlzdDxGaWVsZERlc2NyaXB0b3I+IGdldEV4dGVuc2lvbnMoKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChBcnJheXMuYXNMaXN0KGV4dGVuc2lvbnMpKTsKKyAgICB9CisKKyAgICAvKiogR2V0IGEgbGlzdCBvZiB0aGlzIGZpbGUncyBkZXBlbmRlbmNpZXMgKGltcG9ydHMpLiAqLworICAgIHB1YmxpYyBMaXN0PEZpbGVEZXNjcmlwdG9yPiBnZXREZXBlbmRlbmNpZXMoKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChBcnJheXMuYXNMaXN0KGRlcGVuZGVuY2llcykpOworICAgIH0KKworICAgIC8qKiBHZXQgYSBsaXN0IG9mIHRoaXMgZmlsZSdzIHB1YmxpYyBkZXBlbmRlbmNpZXMgKHB1YmxpYyBpbXBvcnRzKS4gKi8KKyAgICBwdWJsaWMgTGlzdDxGaWxlRGVzY3JpcHRvcj4gZ2V0UHVibGljRGVwZW5kZW5jaWVzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdChwdWJsaWNEZXBlbmRlbmNpZXMpKTsKKyAgICB9CisKKyAgICAvKiogVGhlIHN5bnRheCBvZiB0aGUgLnByb3RvIGZpbGUuICovCisgICAgcHVibGljIGVudW0gU3ludGF4IHsKKyAgICAgIFVOS05PV04oInVua25vd24iKSwKKyAgICAgIFBST1RPMigicHJvdG8yIiksCisgICAgICBQUk9UTzMoInByb3RvMyIpOworCisgICAgICBTeW50YXgoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgIH0KKyAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CisgICAgfQorCisgICAgLyoqIEdldCB0aGUgc3ludGF4IG9mIHRoZSAucHJvdG8gZmlsZS4gKi8KKyAgICBwdWJsaWMgU3ludGF4IGdldFN5bnRheCgpIHsKKyAgICAgIGlmIChTeW50YXguUFJPVE8zLm5hbWUuZXF1YWxzKHByb3RvLmdldFN5bnRheCgpKSkgeworICAgICAgICByZXR1cm4gU3ludGF4LlBST1RPMzsKKyAgICAgIH0KKyAgICAgIHJldHVybiBTeW50YXguUFJPVE8yOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYSBtZXNzYWdlIHR5cGUgaW4gdGhlIGZpbGUgYnkgbmFtZS4gIERvZXMgbm90IGZpbmQgbmVzdGVkIHR5cGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHVucXVhbGlmaWVkIHR5cGUgbmFtZSB0byBsb29rIGZvci4KKyAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIHR5cGUncyBkZXNjcmlwdG9yLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBEZXNjcmlwdG9yIGZpbmRNZXNzYWdlVHlwZUJ5TmFtZShTdHJpbmcgbmFtZSkgeworICAgICAgLy8gRG9uJ3QgYWxsb3cgbG9va2luZyB1cCBuZXN0ZWQgdHlwZXMuICBUaGlzIHdpbGwgbWFrZSBvcHRpbWl6YXRpb24KKyAgICAgIC8vIGVhc2llciBsYXRlci4KKyAgICAgIGlmIChuYW1lLmluZGV4T2YoJy4nKSAhPSAtMSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIGlmIChnZXRQYWNrYWdlKCkubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgIG5hbWUgPSBnZXRQYWNrYWdlKCkgKyAnLicgKyBuYW1lOworICAgICAgfQorICAgICAgZmluYWwgR2VuZXJpY0Rlc2NyaXB0b3IgcmVzdWx0ID0gcG9vbC5maW5kU3ltYm9sKG5hbWUpOworICAgICAgaWYgKHJlc3VsdCAhPSBudWxsICYmIHJlc3VsdCBpbnN0YW5jZW9mIERlc2NyaXB0b3IgJiYKKyAgICAgICAgICByZXN1bHQuZ2V0RmlsZSgpID09IHRoaXMpIHsKKyAgICAgICAgcmV0dXJuIChEZXNjcmlwdG9yKXJlc3VsdDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW4gZW51bSB0eXBlIGluIHRoZSBmaWxlIGJ5IG5hbWUuICBEb2VzIG5vdCBmaW5kIG5lc3RlZCB0eXBlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSB1bnF1YWxpZmllZCB0eXBlIG5hbWUgdG8gbG9vayBmb3IuCisgICAgICogQHJldHVybiBUaGUgZW51bSB0eXBlJ3MgZGVzY3JpcHRvciwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bURlc2NyaXB0b3IgZmluZEVudW1UeXBlQnlOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAvLyBEb24ndCBhbGxvdyBsb29raW5nIHVwIG5lc3RlZCB0eXBlcy4gIFRoaXMgd2lsbCBtYWtlIG9wdGltaXphdGlvbgorICAgICAgLy8gZWFzaWVyIGxhdGVyLgorICAgICAgaWYgKG5hbWUuaW5kZXhPZignLicpICE9IC0xKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgaWYgKGdldFBhY2thZ2UoKS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgbmFtZSA9IGdldFBhY2thZ2UoKSArICcuJyArIG5hbWU7CisgICAgICB9CisgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciByZXN1bHQgPSBwb29sLmZpbmRTeW1ib2wobmFtZSk7CisgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgcmVzdWx0IGluc3RhbmNlb2YgRW51bURlc2NyaXB0b3IgJiYKKyAgICAgICAgICByZXN1bHQuZ2V0RmlsZSgpID09IHRoaXMpIHsKKyAgICAgICAgcmV0dXJuIChFbnVtRGVzY3JpcHRvcilyZXN1bHQ7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGEgc2VydmljZSB0eXBlIGluIHRoZSBmaWxlIGJ5IG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgdHlwZSBuYW1lIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gVGhlIHNlcnZpY2UgdHlwZSdzIGRlc2NyaXB0b3IsIG9yIHtAY29kZSBudWxsfSBpZiBub3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIFNlcnZpY2VEZXNjcmlwdG9yIGZpbmRTZXJ2aWNlQnlOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAvLyBEb24ndCBhbGxvdyBsb29raW5nIHVwIG5lc3RlZCB0eXBlcy4gIFRoaXMgd2lsbCBtYWtlIG9wdGltaXphdGlvbgorICAgICAgLy8gZWFzaWVyIGxhdGVyLgorICAgICAgaWYgKG5hbWUuaW5kZXhPZignLicpICE9IC0xKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgaWYgKGdldFBhY2thZ2UoKS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgbmFtZSA9IGdldFBhY2thZ2UoKSArICcuJyArIG5hbWU7CisgICAgICB9CisgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciByZXN1bHQgPSBwb29sLmZpbmRTeW1ib2wobmFtZSk7CisgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgcmVzdWx0IGluc3RhbmNlb2YgU2VydmljZURlc2NyaXB0b3IgJiYKKyAgICAgICAgICByZXN1bHQuZ2V0RmlsZSgpID09IHRoaXMpIHsKKyAgICAgICAgcmV0dXJuIChTZXJ2aWNlRGVzY3JpcHRvcilyZXN1bHQ7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuIGV4dGVuc2lvbiBpbiB0aGUgZmlsZSBieSBuYW1lLiAgRG9lcyBub3QgZmluZCBleHRlbnNpb25zIG5lc3RlZAorICAgICAqIGluc2lkZSBtZXNzYWdlIHR5cGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHVucXVhbGlmaWVkIGV4dGVuc2lvbiBuYW1lIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gVGhlIGV4dGVuc2lvbidzIGRlc2NyaXB0b3IsIG9yIHtAY29kZSBudWxsfSBpZiBub3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIEZpZWxkRGVzY3JpcHRvciBmaW5kRXh0ZW5zaW9uQnlOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICBpZiAobmFtZS5pbmRleE9mKCcuJykgIT0gLTEpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICBpZiAoZ2V0UGFja2FnZSgpLmxlbmd0aCgpID4gMCkgeworICAgICAgICBuYW1lID0gZ2V0UGFja2FnZSgpICsgJy4nICsgbmFtZTsKKyAgICAgIH0KKyAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIHJlc3VsdCA9IHBvb2wuZmluZFN5bWJvbChuYW1lKTsKKyAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQgaW5zdGFuY2VvZiBGaWVsZERlc2NyaXB0b3IgJiYKKyAgICAgICAgICByZXN1bHQuZ2V0RmlsZSgpID09IHRoaXMpIHsKKyAgICAgICAgcmV0dXJuIChGaWVsZERlc2NyaXB0b3IpcmVzdWx0OworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEge0Bjb2RlIEZpbGVEZXNjcmlwdG9yfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm90byBUaGUgcHJvdG9jb2wgbWVzc2FnZSBmb3JtIG9mIHRoZSBGaWxlRGVzY3JpcHRvci4KKyAgICAgKiBAcGFyYW0gZGVwZW5kZW5jaWVzIHtAY29kZSBGaWxlRGVzY3JpcHRvcn1zIGNvcnJlc3BvbmRpbmcgdG8gYWxsIG9mCisgICAgICogICAgICAgICAgICAgICAgICAgICB0aGUgZmlsZSdzIGRlcGVuZGVuY2llcy4KKyAgICAgKiBAdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHtAY29kZSBwcm90b30gaXMgbm90IGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgZGVzY3JpcHRvci4gIFRoaXMgY2FuIG9jY3VyIGZvciBhIG51bWJlciBvZiByZWFzb25zLCBlLmcuCisgICAgICogICAgICAgICAgIGJlY2F1c2UgYSBmaWVsZCBoYXMgYW4gdW5kZWZpbmVkIHR5cGUgb3IgYmVjYXVzZSB0d28gbWVzc2FnZXMKKyAgICAgKiAgICAgICAgICAgd2VyZSBkZWZpbmVkIHdpdGggdGhlIHNhbWUgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZpbGVEZXNjcmlwdG9yIGJ1aWxkRnJvbShmaW5hbCBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGVEZXNjcmlwdG9yW10gZGVwZW5kZW5jaWVzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBidWlsZEZyb20ocHJvdG8sIGRlcGVuZGVuY2llcywgZmFsc2UpOworICAgIH0KKyAgICAKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIHtAY29kZSBGaWxlRGVzY3JpcHRvcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvdG8gVGhlIHByb3RvY29sIG1lc3NhZ2UgZm9ybSBvZiB0aGUgRmlsZURlc2NyaXB0b3IuCisgICAgICogQHBhcmFtIGRlcGVuZGVuY2llcyB7QGNvZGUgRmlsZURlc2NyaXB0b3J9cyBjb3JyZXNwb25kaW5nIHRvIGFsbCBvZgorICAgICAqICAgICAgICAgICAgICAgICAgICAgdGhlIGZpbGUncyBkZXBlbmRlbmNpZXMuCisgICAgICogQHBhcmFtIGFsbG93VW5rbm93bkRlcGVuZGVuY2llcyBJZiB0cnVlLCBub24tZXhpc3QgZGVwZW5kZW5uY2llcyB3aWxsIGJlCisgICAgICogICAgICAgICAgIGlnbm9yZWQgYW5kIHVuZGVmaW5lZCBtZXNzYWdlIHR5cGVzIHdpbGwgYmUgcmVwbGFjZWQgd2l0aCBhCisgICAgICogICAgICAgICAgIHBsYWNlaG9sZGVyIHR5cGUuCisgICAgICogQHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7QGNvZGUgcHJvdG99IGlzIG5vdCBhIHZhbGlkCisgICAgICogICAgICAgICAgIGRlc2NyaXB0b3IuICBUaGlzIGNhbiBvY2N1ciBmb3IgYSBudW1iZXIgb2YgcmVhc29ucywgZS5nLgorICAgICAqICAgICAgICAgICBiZWNhdXNlIGEgZmllbGQgaGFzIGFuIHVuZGVmaW5lZCB0eXBlIG9yIGJlY2F1c2UgdHdvIG1lc3NhZ2VzCisgICAgICogICAgICAgICAgIHdlcmUgZGVmaW5lZCB3aXRoIHRoZSBzYW1lIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgRmlsZURlc2NyaXB0b3IgYnVpbGRGcm9tKAorICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvLCBmaW5hbCBGaWxlRGVzY3JpcHRvcltdIGRlcGVuZGVuY2llcywKKyAgICAgICAgZmluYWwgYm9vbGVhbiBhbGxvd1Vua25vd25EZXBlbmRlbmNpZXMpCisgICAgICAgIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAvLyBCdWlsZGluZyBkZXNjcmlwdG9ycyBpbnZvbHZlcyB0d28gc3RlcHM6ICB0cmFuc2xhdGluZyBhbmQgbGlua2luZy4KKyAgICAgIC8vIEluIHRoZSB0cmFuc2xhdGlvbiBzdGVwIChpbXBsZW1lbnRlZCBieSBGaWxlRGVzY3JpcHRvcidzCisgICAgICAvLyBjb25zdHJ1Y3RvciksIHdlIGJ1aWxkIGFuIG9iamVjdCB0cmVlIG1pcnJvcmluZyB0aGUKKyAgICAgIC8vIEZpbGVEZXNjcmlwdG9yUHJvdG8ncyB0cmVlIGFuZCBwdXQgYWxsIG9mIHRoZSBkZXNjcmlwdG9ycyBpbnRvIHRoZQorICAgICAgLy8gRGVzY3JpcHRvclBvb2wncyBsb29rdXAgdGFibGVzLiAgSW4gdGhlIGxpbmtpbmcgc3RlcCwgd2UgbG9vayB1cCBhbGwKKyAgICAgIC8vIHR5cGUgcmVmZXJlbmNlcyBpbiB0aGUgRGVzY3JpcHRvclBvb2wsIHNvIHRoYXQsIGZvciBleGFtcGxlLCBhCisgICAgICAvLyBGaWVsZERlc2NyaXB0b3IgZm9yIGFuIGVtYmVkZGVkIG1lc3NhZ2UgY29udGFpbnMgYSBwb2ludGVyIGRpcmVjdGx5CisgICAgICAvLyB0byB0aGUgRGVzY3JpcHRvciBmb3IgdGhhdCBtZXNzYWdlJ3MgdHlwZS4gIFdlIGFsc28gZGV0ZWN0IHVuZGVmaW5lZAorICAgICAgLy8gdHlwZXMgaW4gdGhlIGxpbmtpbmcgc3RlcC4KKyAgICAgIGZpbmFsIERlc2NyaXB0b3JQb29sIHBvb2wgPSBuZXcgRGVzY3JpcHRvclBvb2woCisgICAgICAgICAgZGVwZW5kZW5jaWVzLCBhbGxvd1Vua25vd25EZXBlbmRlbmNpZXMpOworICAgICAgZmluYWwgRmlsZURlc2NyaXB0b3IgcmVzdWx0ID0gbmV3IEZpbGVEZXNjcmlwdG9yKAorICAgICAgICAgIHByb3RvLCBkZXBlbmRlbmNpZXMsIHBvb2wsIGFsbG93VW5rbm93bkRlcGVuZGVuY2llcyk7CisgICAgICByZXN1bHQuY3Jvc3NMaW5rKCk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHRvIGJlIGNhbGxlZCBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiAgSXQgaXMgZXF1aXZhbGVudAorICAgICAqIHRvIHtAY29kZSBidWlsZEZyb219IGV4Y2VwdCB0aGF0IHRoZSB7QGNvZGUgRmlsZURlc2NyaXB0b3JQcm90b30gaXMKKyAgICAgKiBlbmNvZGVkIGluIHByb3RvY29sIGJ1ZmZlciB3aXJlIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKAorICAgICAgICBmaW5hbCBTdHJpbmdbXSBkZXNjcmlwdG9yRGF0YVBhcnRzLAorICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvcltdIGRlcGVuZGVuY2llcywKKyAgICAgICAgZmluYWwgSW50ZXJuYWxEZXNjcmlwdG9yQXNzaWduZXIgZGVzY3JpcHRvckFzc2lnbmVyKSB7CisgICAgICAvLyBIYWNrOiAgV2UgY2FuJ3QgZW1iZWQgYSByYXcgYnl0ZSBhcnJheSBpbnNpZGUgZ2VuZXJhdGVkIEphdmEgY29kZQorICAgICAgLy8gICAoYXQgbGVhc3QsIG5vdCBlZmZpY2llbnRseSksIGJ1dCB3ZSBjYW4gZW1iZWQgU3RyaW5ncy4gIFNvLCB0aGUKKyAgICAgIC8vICAgcHJvdG9jb2wgY29tcGlsZXIgZW1iZWRzIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvIGFzIGEgZ2lhbnQKKyAgICAgIC8vICAgc3RyaW5nIGxpdGVyYWwgd2hpY2ggaXMgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gdG8gY29uc3RydWN0IHRoZQorICAgICAgLy8gICBmaWxlJ3MgRmlsZURlc2NyaXB0b3IuICBUaGUgc3RyaW5nIGxpdGVyYWwgY29udGFpbnMgb25seSA4LWJpdAorICAgICAgLy8gICBjaGFyYWN0ZXJzLCBlYWNoIG9uZSByZXByZXNlbnRpbmcgYSBieXRlIG9mIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvJ3MKKyAgICAgIC8vICAgc2VyaWFsaXplZCBmb3JtLiAgU28sIGlmIHdlIGNvbnZlcnQgaXQgdG8gYnl0ZXMgaW4gSVNPLTg4NTktMSwgd2UKKyAgICAgIC8vICAgc2hvdWxkIGdldCB0aGUgb3JpZ2luYWwgYnl0ZXMgdGhhdCB3ZSB3YW50LgorCisgICAgICAvLyBkZXNjcmlwdG9yRGF0YSBtYXkgY29udGFpbiBtdWx0aXBsZSBzdHJpbmdzIGluIG9yZGVyIHRvIGdldCBhcm91bmQgdGhlCisgICAgICAvLyBKYXZhIDY0ayBzdHJpbmcgbGl0ZXJhbCBsaW1pdC4KKyAgICAgIFN0cmluZ0J1aWxkZXIgZGVzY3JpcHRvckRhdGEgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgZm9yIChTdHJpbmcgcGFydCA6IGRlc2NyaXB0b3JEYXRhUGFydHMpIHsKKyAgICAgICAgZGVzY3JpcHRvckRhdGEuYXBwZW5kKHBhcnQpOworICAgICAgfQorCisgICAgICBmaW5hbCBieXRlW10gZGVzY3JpcHRvckJ5dGVzOworICAgICAgdHJ5IHsKKyAgICAgICAgZGVzY3JpcHRvckJ5dGVzID0gZGVzY3JpcHRvckRhdGEudG9TdHJpbmcoKS5nZXRCeXRlcygiSVNPLTg4NTktMSIpOworICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJTdGFuZGFyZCBlbmNvZGluZyBJU08tODg1OS0xIG5vdCBzdXBwb3J0ZWQgYnkgSlZNLiIsIGUpOworICAgICAgfQorCisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvOworICAgICAgdHJ5IHsKKyAgICAgICAgcHJvdG8gPSBGaWxlRGVzY3JpcHRvclByb3RvLnBhcnNlRnJvbShkZXNjcmlwdG9yQnl0ZXMpOworICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiRmFpbGVkIHRvIHBhcnNlIHByb3RvY29sIGJ1ZmZlciBkZXNjcmlwdG9yIGZvciBnZW5lcmF0ZWQgY29kZS4iLCBlKTsKKyAgICAgIH0KKworICAgICAgZmluYWwgRmlsZURlc2NyaXB0b3IgcmVzdWx0OworICAgICAgdHJ5IHsKKyAgICAgICAgLy8gV2hlbiBidWlsZGluZyBkZXNjcmlwdG9ycyBmb3IgZ2VuZXJhdGVkIGNvZGUsIHdlIGFsbG93IHVua25vd24KKyAgICAgICAgLy8gZGVwZW5kZW5jaWVzIGJ5IGRlZmF1bHQuCisgICAgICAgIHJlc3VsdCA9IGJ1aWxkRnJvbShwcm90bywgZGVwZW5kZW5jaWVzLCB0cnVlKTsKKyAgICAgIH0gY2F0Y2ggKERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiSW52YWxpZCBlbWJlZGRlZCBkZXNjcmlwdG9yIGZvciBcIiIgKyBwcm90by5nZXROYW1lKCkgKyAiXCIuIiwgZSk7CisgICAgICB9CisKKyAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0KKyAgICAgICAgICBkZXNjcmlwdG9yQXNzaWduZXIuYXNzaWduRGVzY3JpcHRvcnMocmVzdWx0KTsKKworICAgICAgaWYgKHJlZ2lzdHJ5ICE9IG51bGwpIHsKKyAgICAgICAgLy8gV2UgbXVzdCByZS1wYXJzZSB0aGUgcHJvdG8gdXNpbmcgdGhlIHJlZ2lzdHJ5LgorICAgICAgICB0cnkgeworICAgICAgICAgIHByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5wYXJzZUZyb20oZGVzY3JpcHRvckJ5dGVzLCByZWdpc3RyeSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICJGYWlsZWQgdG8gcGFyc2UgcHJvdG9jb2wgYnVmZmVyIGRlc2NyaXB0b3IgZm9yIGdlbmVyYXRlZCBjb2RlLiIsCisgICAgICAgICAgICBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlc3VsdC5zZXRQcm90byhwcm90byk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgdG8gYmUgY2FsbGVkIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuICBJdCB1c2VzIEphdmEKKyAgICAgKiByZWZsZWN0aW9uIHRvIGxvYWQgdGhlIGRlcGVuZGVuY2llcycgZGVzY3JpcHRvcnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbSgKKyAgICAgICAgZmluYWwgU3RyaW5nW10gZGVzY3JpcHRvckRhdGFQYXJ0cywKKyAgICAgICAgZmluYWwgQ2xhc3M8Pz4gZGVzY3JpcHRvck91dGVyQ2xhc3MsCisgICAgICAgIGZpbmFsIFN0cmluZ1tdIGRlcGVuZGVuY2llcywKKyAgICAgICAgZmluYWwgU3RyaW5nW10gZGVwZW5kZW5jeUZpbGVOYW1lcywKKyAgICAgICAgZmluYWwgSW50ZXJuYWxEZXNjcmlwdG9yQXNzaWduZXIgZGVzY3JpcHRvckFzc2lnbmVyKSB7CisgICAgICBMaXN0PEZpbGVEZXNjcmlwdG9yPiBkZXNjcmlwdG9ycyA9IG5ldyBBcnJheUxpc3Q8RmlsZURlc2NyaXB0b3I+KCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlcGVuZGVuY2llcy5sZW5ndGg7IGkrKykgeworICAgICAgICB0cnkgeworICAgICAgICAgIENsYXNzPD8+IGNsYXp6ID0KKyAgICAgICAgICAgICAgZGVzY3JpcHRvck91dGVyQ2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoZGVwZW5kZW5jaWVzW2ldKTsKKyAgICAgICAgICBkZXNjcmlwdG9ycy5hZGQoCisgICAgICAgICAgICAgIChGaWxlRGVzY3JpcHRvcikgY2xhenouZ2V0RmllbGQoImRlc2NyaXB0b3IiKS5nZXQobnVsbCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIFdlIGFsbG93IHVua25vd24gZGVwZW5kZW5jaWVzIGJ5IGRlZmF1bHQuIElmIGEgZGVwZW5kZW5jeSBjYW5ub3QKKyAgICAgICAgICAvLyBiZSBmb3VuZCB3ZSBvbmx5IGdlbmVyYXRlIGEgd2FybmluZy4KKyAgICAgICAgICBsb2dnZXIud2FybmluZygiRGVzY3JpcHRvcnMgZm9yIFwiIiArIGRlcGVuZGVuY3lGaWxlTmFtZXNbaV0gKworICAgICAgICAgICAgICAiXCIgY2FuIG5vdCBiZSBmb3VuZC4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgRmlsZURlc2NyaXB0b3JbXSBkZXNjcmlwdG9yQXJyYXkgPSBuZXcgRmlsZURlc2NyaXB0b3JbZGVzY3JpcHRvcnMuc2l6ZSgpXTsKKyAgICAgIGRlc2NyaXB0b3JzLnRvQXJyYXkoZGVzY3JpcHRvckFycmF5KTsKKyAgICAgIGludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbSgKKyAgICAgICAgICBkZXNjcmlwdG9yRGF0YVBhcnRzLCBkZXNjcmlwdG9yQXJyYXksIGRlc2NyaXB0b3JBc3NpZ25lcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgdG8gYmUgY2FsbGVkIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuICBJdCBpcyB1c2VkIHRvCisgICAgICogdXBkYXRlIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGVzY3JpcHRvciBieQorICAgICAqIHBhcnNpbmcgaXQgYWdhaW4gd2l0aCB0aGUgZ2l2ZW4gRXh0ZW5zaW9uUmVnaXN0cnkuIFRoaXMgaXMgbmVlZGVkIHRvCisgICAgICogcmVjb2duaXplIGN1c3RvbSBvcHRpb25zLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBpbnRlcm5hbFVwZGF0ZUZpbGVEZXNjcmlwdG9yKAorICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvciBkZXNjcmlwdG9yLAorICAgICAgICBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgeworICAgICAgQnl0ZVN0cmluZyBieXRlcyA9IGRlc2NyaXB0b3IucHJvdG8udG9CeXRlU3RyaW5nKCk7CisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvOworICAgICAgdHJ5IHsKKyAgICAgICAgcHJvdG8gPSBGaWxlRGVzY3JpcHRvclByb3RvLnBhcnNlRnJvbShieXRlcywgcmVnaXN0cnkpOworICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiRmFpbGVkIHRvIHBhcnNlIHByb3RvY29sIGJ1ZmZlciBkZXNjcmlwdG9yIGZvciBnZW5lcmF0ZWQgY29kZS4iLCBlKTsKKyAgICAgIH0KKyAgICAgIGRlc2NyaXB0b3Iuc2V0UHJvdG8ocHJvdG8pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgY2xhc3Mgc2hvdWxkIGJlIHVzZWQgYnkgZ2VuZXJhdGVkIGNvZGUgb25seS4gIFdoZW4gY2FsbGluZworICAgICAqIHtAbGluayBGaWxlRGVzY3JpcHRvciNpbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb219LCB0aGUgY2FsbGVyCisgICAgICogcHJvdmlkZXMgYSBjYWxsYmFjayBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UuICBUaGUgY2FsbGJhY2sgaXMgY2FsbGVkCisgICAgICogYWZ0ZXIgdGhlIEZpbGVEZXNjcmlwdG9yIGhhcyBiZWVuIGNvbnN0cnVjdGVkLCBpbiBvcmRlciB0byBhc3NpZ24gYWxsCisgICAgICogdGhlIGdsb2JhbCB2YXJpYWJsZXMgZGVmaW5lZCBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgd2hpY2ggcG9pbnQgYXQgcGFydHMKKyAgICAgKiBvZiB0aGUgRmlsZURlc2NyaXB0b3IuICBUaGUgY2FsbGJhY2sgcmV0dXJucyBhbiBFeHRlbnNpb25SZWdpc3RyeSB3aGljaAorICAgICAqIGNvbnRhaW5zIGFueSBleHRlbnNpb25zIHdoaWNoIG1pZ2h0IGJlIHVzZWQgaW4gdGhlIGRlc2NyaXB0b3IgLS0gdGhhdAorICAgICAqIGlzLCBleHRlbnNpb25zIG9mIHRoZSB2YXJpb3VzICJPcHRpb25zIiBtZXNzYWdlcyBkZWZpbmVkIGluCisgICAgICogZGVzY3JpcHRvci5wcm90by4gIFRoZSBjYWxsYmFjayBtYXkgYWxzbyByZXR1cm4gbnVsbCB0byBpbmRpY2F0ZSB0aGF0CisgICAgICogbm8gZXh0ZW5zaW9ucyBhcmUgdXNlZCBpbiB0aGUgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50ZXJmYWNlIEludGVybmFsRGVzY3JpcHRvckFzc2lnbmVyIHsKKyAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5IGFzc2lnbkRlc2NyaXB0b3JzKEZpbGVEZXNjcmlwdG9yIHJvb3QpOworICAgIH0KKworICAgIHByaXZhdGUgRmlsZURlc2NyaXB0b3JQcm90byBwcm90bzsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JbXSBtZXNzYWdlVHlwZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBFbnVtRGVzY3JpcHRvcltdIGVudW1UeXBlczsKKyAgICBwcml2YXRlIGZpbmFsIFNlcnZpY2VEZXNjcmlwdG9yW10gc2VydmljZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWVsZERlc2NyaXB0b3JbXSBleHRlbnNpb25zOworICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3JbXSBkZXBlbmRlbmNpZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvcltdIHB1YmxpY0RlcGVuZGVuY2llczsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JQb29sIHBvb2w7CisKKyAgICBwcml2YXRlIEZpbGVEZXNjcmlwdG9yKGZpbmFsIEZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvcltdIGRlcGVuZGVuY2llcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIERlc2NyaXB0b3JQb29sIHBvb2wsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93VW5rbm93bkRlcGVuZGVuY2llcykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMucG9vbCA9IHBvb2w7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisgICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IGRlcGVuZGVuY2llcy5jbG9uZSgpOworICAgICAgSGFzaE1hcDxTdHJpbmcsIEZpbGVEZXNjcmlwdG9yPiBuYW1lVG9GaWxlTWFwID0KKyAgICAgICAgICBuZXcgSGFzaE1hcDxTdHJpbmcsIEZpbGVEZXNjcmlwdG9yPigpOworICAgICAgZm9yIChGaWxlRGVzY3JpcHRvciBmaWxlIDogZGVwZW5kZW5jaWVzKSB7CisgICAgICAgIG5hbWVUb0ZpbGVNYXAucHV0KGZpbGUuZ2V0TmFtZSgpLCBmaWxlKTsKKyAgICAgIH0KKyAgICAgIExpc3Q8RmlsZURlc2NyaXB0b3I+IHB1YmxpY0RlcGVuZGVuY2llcyA9IG5ldyBBcnJheUxpc3Q8RmlsZURlc2NyaXB0b3I+KCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmdldFB1YmxpY0RlcGVuZGVuY3lDb3VudCgpOyBpKyspIHsKKyAgICAgICAgaW50IGluZGV4ID0gcHJvdG8uZ2V0UHVibGljRGVwZW5kZW5jeShpKTsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBwcm90by5nZXREZXBlbmRlbmN5Q291bnQoKSkgeworICAgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbih0aGlzLAorICAgICAgICAgICAgICAiSW52YWxpZCBwdWJsaWMgZGVwZW5kZW5jeSBpbmRleC4iKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgbmFtZSA9IHByb3RvLmdldERlcGVuZGVuY3koaW5kZXgpOworICAgICAgICBGaWxlRGVzY3JpcHRvciBmaWxlID0gbmFtZVRvRmlsZU1hcC5nZXQobmFtZSk7CisgICAgICAgIGlmIChmaWxlID09IG51bGwpIHsKKyAgICAgICAgICBpZiAoIWFsbG93VW5rbm93bkRlcGVuZGVuY2llcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAgICAgIkludmFsaWQgcHVibGljIGRlcGVuZGVuY3k6ICIgKyBuYW1lKTsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8gSWdub3JlIHVua25vd24gZGVwZW5kZW5jaWVzLgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHB1YmxpY0RlcGVuZGVuY2llcy5hZGQoZmlsZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHRoaXMucHVibGljRGVwZW5kZW5jaWVzID0gbmV3IEZpbGVEZXNjcmlwdG9yW3B1YmxpY0RlcGVuZGVuY2llcy5zaXplKCldOworICAgICAgcHVibGljRGVwZW5kZW5jaWVzLnRvQXJyYXkodGhpcy5wdWJsaWNEZXBlbmRlbmNpZXMpOworCisgICAgICBwb29sLmFkZFBhY2thZ2UoZ2V0UGFja2FnZSgpLCB0aGlzKTsKKworICAgICAgbWVzc2FnZVR5cGVzID0gbmV3IERlc2NyaXB0b3JbcHJvdG8uZ2V0TWVzc2FnZVR5cGVDb3VudCgpXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZ2V0TWVzc2FnZVR5cGVDb3VudCgpOyBpKyspIHsKKyAgICAgICAgbWVzc2FnZVR5cGVzW2ldID0KKyAgICAgICAgICBuZXcgRGVzY3JpcHRvcihwcm90by5nZXRNZXNzYWdlVHlwZShpKSwgdGhpcywgbnVsbCwgaSk7CisgICAgICB9CisKKyAgICAgIGVudW1UeXBlcyA9IG5ldyBFbnVtRGVzY3JpcHRvcltwcm90by5nZXRFbnVtVHlwZUNvdW50KCldOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by5nZXRFbnVtVHlwZUNvdW50KCk7IGkrKykgeworICAgICAgICBlbnVtVHlwZXNbaV0gPSBuZXcgRW51bURlc2NyaXB0b3IocHJvdG8uZ2V0RW51bVR5cGUoaSksIHRoaXMsIG51bGwsIGkpOworICAgICAgfQorCisgICAgICBzZXJ2aWNlcyA9IG5ldyBTZXJ2aWNlRGVzY3JpcHRvcltwcm90by5nZXRTZXJ2aWNlQ291bnQoKV07CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmdldFNlcnZpY2VDb3VudCgpOyBpKyspIHsKKyAgICAgICAgc2VydmljZXNbaV0gPSBuZXcgU2VydmljZURlc2NyaXB0b3IocHJvdG8uZ2V0U2VydmljZShpKSwgdGhpcywgaSk7CisgICAgICB9CisKKyAgICAgIGV4dGVuc2lvbnMgPSBuZXcgRmllbGREZXNjcmlwdG9yW3Byb3RvLmdldEV4dGVuc2lvbkNvdW50KCldOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by5nZXRFeHRlbnNpb25Db3VudCgpOyBpKyspIHsKKyAgICAgICAgZXh0ZW5zaW9uc1tpXSA9IG5ldyBGaWVsZERlc2NyaXB0b3IoCisgICAgICAgICAgcHJvdG8uZ2V0RXh0ZW5zaW9uKGkpLCB0aGlzLCBudWxsLCBpLCB0cnVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgcGxhY2Vob2xkZXIgRmlsZURlc2NyaXB0b3IgZm9yIGEgbWVzc2FnZSBEZXNjcmlwdG9yLiAKKyAgICAgKi8KKyAgICBGaWxlRGVzY3JpcHRvcihTdHJpbmcgcGFja2FnZU5hbWUsIERlc2NyaXB0b3IgbWVzc2FnZSkKKyAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMucG9vbCA9IG5ldyBEZXNjcmlwdG9yUG9vbChuZXcgRmlsZURlc2NyaXB0b3JbMF0sIHRydWUpOworICAgICAgdGhpcy5wcm90byA9IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgICAgLnNldE5hbWUobWVzc2FnZS5nZXRGdWxsTmFtZSgpICsgIi5wbGFjZWhvbGRlci5wcm90byIpCisgICAgICAgICAgLnNldFBhY2thZ2UocGFja2FnZU5hbWUpLmFkZE1lc3NhZ2VUeXBlKG1lc3NhZ2UudG9Qcm90bygpKS5idWlsZCgpOworICAgICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBuZXcgRmlsZURlc2NyaXB0b3JbMF07CisgICAgICB0aGlzLnB1YmxpY0RlcGVuZGVuY2llcyA9IG5ldyBGaWxlRGVzY3JpcHRvclswXTsKKworICAgICAgbWVzc2FnZVR5cGVzID0gbmV3IERlc2NyaXB0b3JbXSB7bWVzc2FnZX07CisgICAgICBlbnVtVHlwZXMgPSBuZXcgRW51bURlc2NyaXB0b3JbMF07CisgICAgICBzZXJ2aWNlcyA9IG5ldyBTZXJ2aWNlRGVzY3JpcHRvclswXTsKKyAgICAgIGV4dGVuc2lvbnMgPSBuZXcgRmllbGREZXNjcmlwdG9yWzBdOworCisgICAgICBwb29sLmFkZFBhY2thZ2UocGFja2FnZU5hbWUsIHRoaXMpOworICAgICAgcG9vbC5hZGRTeW1ib2wobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqIExvb2sgdXAgYW5kIGNyb3NzLWxpbmsgYWxsIGZpZWxkIHR5cGVzLCBldGMuICovCisgICAgcHJpdmF0ZSB2b2lkIGNyb3NzTGluaygpIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICBmb3IgKGZpbmFsIERlc2NyaXB0b3IgbWVzc2FnZVR5cGUgOiBtZXNzYWdlVHlwZXMpIHsKKyAgICAgICAgbWVzc2FnZVR5cGUuY3Jvc3NMaW5rKCk7CisgICAgICB9CisKKyAgICAgIGZvciAoZmluYWwgU2VydmljZURlc2NyaXB0b3Igc2VydmljZSA6IHNlcnZpY2VzKSB7CisgICAgICAgIHNlcnZpY2UuY3Jvc3NMaW5rKCk7CisgICAgICB9CisKKyAgICAgIGZvciAoZmluYWwgRmllbGREZXNjcmlwdG9yIGV4dGVuc2lvbiA6IGV4dGVuc2lvbnMpIHsKKyAgICAgICAgZXh0ZW5zaW9uLmNyb3NzTGluaygpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2Ugb3VyIHtAbGluayBGaWxlRGVzY3JpcHRvclByb3RvfSB3aXRoIHRoZSBnaXZlbiBvbmUsIHdoaWNoIGlzCisgICAgICogaWRlbnRpY2FsIGV4Y2VwdCB0aGF0IGl0IG1pZ2h0IGNvbnRhaW4gZXh0ZW5zaW9ucyB0aGF0IHdlcmVuJ3QgcHJlc2VudAorICAgICAqIGluIHRoZSBvcmlnaW5hbC4gIFRoaXMgbWV0aG9kIGlzIG5lZWRlZCBmb3IgYm9vdHN0cmFwcGluZyB3aGVuIGEgZmlsZQorICAgICAqIGRlZmluZXMgY3VzdG9tIG9wdGlvbnMuICBUaGUgb3B0aW9ucyBtYXkgYmUgZGVmaW5lZCBpbiB0aGUgZmlsZSBpdHNlbGYsCisgICAgICogc28gd2UgY2FuJ3QgYWN0dWFsbHkgcGFyc2UgdGhlbSB1bnRpbCB3ZSd2ZSBjb25zdHJ1Y3RlZCB0aGUgZGVzY3JpcHRvcnMsCisgICAgICogYnV0IHRvIGNvbnN0cnVjdCB0aGUgZGVzY3JpcHRvcnMgd2UgaGF2ZSB0byBoYXZlIHBhcnNlZCB0aGUgZGVzY3JpcHRvcgorICAgICAqIHByb3Rvcy4gIFNvLCB3ZSBoYXZlIHRvIHBhcnNlIHRoZSBkZXNjcmlwdG9yIHByb3RvcyBhIHNlY29uZCB0aW1lIGFmdGVyCisgICAgICogY29uc3RydWN0aW5nIHRoZSBkZXNjcmlwdG9ycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0UHJvdG8oZmluYWwgRmlsZURlc2NyaXB0b3JQcm90byBwcm90bykgeworICAgICAgdGhpcy5wcm90byA9IHByb3RvOworCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VUeXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICBtZXNzYWdlVHlwZXNbaV0uc2V0UHJvdG8ocHJvdG8uZ2V0TWVzc2FnZVR5cGUoaSkpOworICAgICAgfQorCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1UeXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICBlbnVtVHlwZXNbaV0uc2V0UHJvdG8ocHJvdG8uZ2V0RW51bVR5cGUoaSkpOworICAgICAgfQorCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2VzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIHNlcnZpY2VzW2ldLnNldFByb3RvKHByb3RvLmdldFNlcnZpY2UoaSkpOworICAgICAgfQorCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgZXh0ZW5zaW9uc1tpXS5zZXRQcm90byhwcm90by5nZXRFeHRlbnNpb24oaSkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBib29sZWFuIHN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZSgpIHsKKyAgICAgIHJldHVybiBnZXRTeW50YXgoKSA9PSBTeW50YXguUFJPVE8zOworICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqIERlc2NyaWJlcyBhIG1lc3NhZ2UgdHlwZS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBEZXNjcmlwdG9yIGV4dGVuZHMgR2VuZXJpY0Rlc2NyaXB0b3IgeworICAgIC8qKgorICAgICAqIEdldCB0aGUgaW5kZXggb2YgdGhpcyBkZXNjcmlwdG9yIHdpdGhpbiBpdHMgcGFyZW50LiAgSW4gb3RoZXIgd29yZHMsCisgICAgICogZ2l2ZW4gYSB7QGxpbmsgRmlsZURlc2NyaXB0b3J9IHtAY29kZSBmaWxlfSwgdGhlIGZvbGxvd2luZyBpcyB0cnVlOgorICAgICAqIDxwcmU+CisgICAgICogICBmb3IgYWxsIGkgaW4gWzAsIGZpbGUuZ2V0TWVzc2FnZVR5cGVDb3VudCgpKToKKyAgICAgKiAgICAgZmlsZS5nZXRNZXNzYWdlVHlwZShpKS5nZXRJbmRleCgpID09IGkKKyAgICAgKiA8L3ByZT4KKyAgICAgKiBTaW1pbGFybHksIGZvciBhIHtAbGluayBEZXNjcmlwdG9yfSB7QGNvZGUgbWVzc2FnZVR5cGV9OgorICAgICAqIDxwcmU+CisgICAgICogICBmb3IgYWxsIGkgaW4gWzAsIG1lc3NhZ2VUeXBlLmdldE5lc3RlZFR5cGVDb3VudCgpKToKKyAgICAgKiAgICAgbWVzc2FnZVR5cGUuZ2V0TmVzdGVkVHlwZShpKS5nZXRJbmRleCgpID09IGkKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeyByZXR1cm4gaW5kZXg7IH0KKworICAgIC8qKiBDb252ZXJ0IHRoZSBkZXNjcmlwdG9yIHRvIGl0cyBwcm90b2NvbCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiAqLworICAgIHB1YmxpYyBEZXNjcmlwdG9yUHJvdG8gdG9Qcm90bygpIHsgcmV0dXJuIHByb3RvOyB9CisKKyAgICAvKiogR2V0IHRoZSB0eXBlJ3MgdW5xdWFsaWZpZWQgbmFtZS4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBwcm90by5nZXROYW1lKCk7IH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdHlwZSdzIGZ1bGx5LXF1YWxpZmllZCBuYW1lLCB3aXRoaW4gdGhlIHByb3RvIGxhbmd1YWdlJ3MKKyAgICAgKiBuYW1lc3BhY2UuICBUaGlzIGRpZmZlcnMgZnJvbSB0aGUgSmF2YSBuYW1lLiAgRm9yIGV4YW1wbGUsIGdpdmVuIHRoaXMKKyAgICAgKiB7QGNvZGUgLnByb3RvfToKKyAgICAgKiA8cHJlPgorICAgICAqICAgcGFja2FnZSBmb28uYmFyOworICAgICAqICAgb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZXhhbXBsZS5wcm90b3MiCisgICAgICogICBtZXNzYWdlIEJheiB7fQorICAgICAqIDwvcHJlPgorICAgICAqIHtAY29kZSBCYXp9J3MgZnVsbCBuYW1lIGlzICJmb28uYmFyLkJheiIuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGdWxsTmFtZSgpIHsgcmV0dXJuIGZ1bGxOYW1lOyB9CisKKyAgICAvKiogR2V0IHRoZSB7QGxpbmsgRmlsZURlc2NyaXB0b3J9IGNvbnRhaW5pbmcgdGhpcyBkZXNjcmlwdG9yLiAqLworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGaWxlKCkgeyByZXR1cm4gZmlsZTsgfQorCisgICAgLyoqIElmIHRoaXMgaXMgYSBuZXN0ZWQgdHlwZSwgZ2V0IHRoZSBvdXRlciBkZXNjcmlwdG9yLCBvdGhlcndpc2UgbnVsbC4gKi8KKyAgICBwdWJsaWMgRGVzY3JpcHRvciBnZXRDb250YWluaW5nVHlwZSgpIHsgcmV0dXJuIGNvbnRhaW5pbmdUeXBlOyB9CisKKyAgICAvKiogR2V0IHRoZSB7QGNvZGUgTWVzc2FnZU9wdGlvbnN9LCBkZWZpbmVkIGluIHtAY29kZSBkZXNjcmlwdG9yLnByb3RvfS4gKi8KKyAgICBwdWJsaWMgTWVzc2FnZU9wdGlvbnMgZ2V0T3B0aW9ucygpIHsgcmV0dXJuIHByb3RvLmdldE9wdGlvbnMoKTsgfQorCisgICAgLyoqIEdldCBhIGxpc3Qgb2YgdGhpcyBtZXNzYWdlIHR5cGUncyBmaWVsZHMuICovCisgICAgcHVibGljIExpc3Q8RmllbGREZXNjcmlwdG9yPiBnZXRGaWVsZHMoKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChBcnJheXMuYXNMaXN0KGZpZWxkcykpOworICAgIH0KKworICAgIC8qKiBHZXQgYSBsaXN0IG9mIHRoaXMgbWVzc2FnZSB0eXBlJ3Mgb25lb2ZzLiAqLworICAgIHB1YmxpYyBMaXN0PE9uZW9mRGVzY3JpcHRvcj4gZ2V0T25lb2ZzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdChvbmVvZnMpKTsKKyAgICB9CisKKyAgICAvKiogR2V0IGEgbGlzdCBvZiB0aGlzIG1lc3NhZ2UgdHlwZSdzIGV4dGVuc2lvbnMuICovCisgICAgcHVibGljIExpc3Q8RmllbGREZXNjcmlwdG9yPiBnZXRFeHRlbnNpb25zKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdChleHRlbnNpb25zKSk7CisgICAgfQorCisgICAgLyoqIEdldCBhIGxpc3Qgb2YgbWVzc2FnZSB0eXBlcyBuZXN0ZWQgd2l0aGluIHRoaXMgb25lLiAqLworICAgIHB1YmxpYyBMaXN0PERlc2NyaXB0b3I+IGdldE5lc3RlZFR5cGVzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdChuZXN0ZWRUeXBlcykpOworICAgIH0KKworICAgIC8qKiBHZXQgYSBsaXN0IG9mIGVudW0gdHlwZXMgbmVzdGVkIHdpdGhpbiB0aGlzIG9uZS4gKi8KKyAgICBwdWJsaWMgTGlzdDxFbnVtRGVzY3JpcHRvcj4gZ2V0RW51bVR5cGVzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdChlbnVtVHlwZXMpKTsKKyAgICB9CisKKyAgICAvKiogRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gZmllbGQgbnVtYmVyIGlzIGFuIGV4dGVuc2lvbi4gKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVuc2lvbk51bWJlcihmaW5hbCBpbnQgbnVtYmVyKSB7CisgICAgICBmb3IgKGZpbmFsIERlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSByYW5nZSA6CisgICAgICAgICAgcHJvdG8uZ2V0RXh0ZW5zaW9uUmFuZ2VMaXN0KCkpIHsKKyAgICAgICAgaWYgKHJhbmdlLmdldFN0YXJ0KCkgPD0gbnVtYmVyICYmIG51bWJlciA8IHJhbmdlLmdldEVuZCgpKSB7CisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbWVzc2FnZSBjYW4gYmUgZXh0ZW5kZWQuICBUaGF0IGlzLCB3aGV0aGVyIGl0IGhhcworICAgICAqIGFueSAiZXh0ZW5zaW9ucyB4IHRvIHkiIHJhbmdlcyBkZWNsYXJlZCBvbiBpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVuZGFibGUoKSB7CisgICAgICByZXR1cm4gcHJvdG8uZ2V0RXh0ZW5zaW9uUmFuZ2VMaXN0KCkuc2l6ZSgpICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYSBmaWVsZCBieSBuYW1lLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSB1bnF1YWxpZmllZCBuYW1lIG9mIHRoZSBmaWVsZCAoZS5nLiAiZm9vIikuCisgICAgICogQHJldHVybiBUaGUgZmllbGQncyBkZXNjcmlwdG9yLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZERlc2NyaXB0b3IgZmluZEZpZWxkQnlOYW1lKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciByZXN1bHQgPQorICAgICAgICAgIGZpbGUucG9vbC5maW5kU3ltYm9sKGZ1bGxOYW1lICsgJy4nICsgbmFtZSk7CisgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgcmVzdWx0IGluc3RhbmNlb2YgRmllbGREZXNjcmlwdG9yKSB7CisgICAgICAgIHJldHVybiAoRmllbGREZXNjcmlwdG9yKXJlc3VsdDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIGEgZmllbGQgYnkgZmllbGQgbnVtYmVyLgorICAgICAqIEBwYXJhbSBudW1iZXIgVGhlIGZpZWxkIG51bWJlciB3aXRoaW4gdGhpcyBtZXNzYWdlIHR5cGUuCisgICAgICogQHJldHVybiBUaGUgZmllbGQncyBkZXNjcmlwdG9yLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZERlc2NyaXB0b3IgZmluZEZpZWxkQnlOdW1iZXIoZmluYWwgaW50IG51bWJlcikgeworICAgICAgcmV0dXJuIGZpbGUucG9vbC5maWVsZHNCeU51bWJlci5nZXQoCisgICAgICAgIG5ldyBEZXNjcmlwdG9yUG9vbC5EZXNjcmlwdG9ySW50UGFpcih0aGlzLCBudW1iZXIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyBhIG5lc3RlZCBtZXNzYWdlIHR5cGUgYnkgbmFtZS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgbmVzdGVkIHR5cGUgKGUuZy4gIkZvbyIpLgorICAgICAqIEByZXR1cm4gVGhlIHR5cGVzJ3MgZGVzY3JpcHRvciwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVzY3JpcHRvciBmaW5kTmVzdGVkVHlwZUJ5TmFtZShmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgZmluYWwgR2VuZXJpY0Rlc2NyaXB0b3IgcmVzdWx0ID0KKyAgICAgICAgICBmaWxlLnBvb2wuZmluZFN5bWJvbChmdWxsTmFtZSArICcuJyArIG5hbWUpOworICAgICAgaWYgKHJlc3VsdCAhPSBudWxsICYmIHJlc3VsdCBpbnN0YW5jZW9mIERlc2NyaXB0b3IpIHsKKyAgICAgICAgcmV0dXJuIChEZXNjcmlwdG9yKXJlc3VsdDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIGEgbmVzdGVkIGVudW0gdHlwZSBieSBuYW1lLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSB1bnF1YWxpZmllZCBuYW1lIG9mIHRoZSBuZXN0ZWQgdHlwZSAoZS5nLiAiRm9vIikuCisgICAgICogQHJldHVybiBUaGUgdHlwZXMncyBkZXNjcmlwdG9yLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBFbnVtRGVzY3JpcHRvciBmaW5kRW51bVR5cGVCeU5hbWUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIHJlc3VsdCA9CisgICAgICAgICAgZmlsZS5wb29sLmZpbmRTeW1ib2woZnVsbE5hbWUgKyAnLicgKyBuYW1lKTsKKyAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQgaW5zdGFuY2VvZiBFbnVtRGVzY3JpcHRvcikgeworICAgICAgICByZXR1cm4gKEVudW1EZXNjcmlwdG9yKXJlc3VsdDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgaW50IGluZGV4OworICAgIHByaXZhdGUgRGVzY3JpcHRvclByb3RvIHByb3RvOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZ1bGxOYW1lOworICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3IgZmlsZTsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3IgY29udGFpbmluZ1R5cGU7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9yW10gbmVzdGVkVHlwZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBFbnVtRGVzY3JpcHRvcltdIGVudW1UeXBlczsKKyAgICBwcml2YXRlIGZpbmFsIEZpZWxkRGVzY3JpcHRvcltdIGZpZWxkczsKKyAgICBwcml2YXRlIGZpbmFsIEZpZWxkRGVzY3JpcHRvcltdIGV4dGVuc2lvbnM7CisgICAgcHJpdmF0ZSBmaW5hbCBPbmVvZkRlc2NyaXB0b3JbXSBvbmVvZnM7CisKKyAgICAvLyBVc2VkIHRvIGNyZWF0ZSBhIHBsYWNlaG9sZGVyIHdoZW4gdGhlIHR5cGUgY2Fubm90IGJlIGZvdW5kLgorICAgIERlc2NyaXB0b3IoZmluYWwgU3RyaW5nIGZ1bGxuYW1lKSB0aHJvd3MgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24geworICAgICAgU3RyaW5nIG5hbWUgPSBmdWxsbmFtZTsKKyAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSA9ICIiOworICAgICAgaW50IHBvcyA9IGZ1bGxuYW1lLmxhc3RJbmRleE9mKCcuJyk7CisgICAgICBpZiAocG9zICE9IC0xKSB7CisgICAgICAgIG5hbWUgPSBmdWxsbmFtZS5zdWJzdHJpbmcocG9zICsgMSk7CisgICAgICAgIHBhY2thZ2VOYW1lID0gZnVsbG5hbWUuc3Vic3RyaW5nKDAsIHBvcyk7CisgICAgICB9CisgICAgICB0aGlzLmluZGV4ID0gMDsKKyAgICAgIHRoaXMucHJvdG8gPSBEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpLnNldE5hbWUobmFtZSkuYWRkRXh0ZW5zaW9uUmFuZ2UoCisgICAgICAgICAgRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLm5ld0J1aWxkZXIoKS5zZXRTdGFydCgxKQorICAgICAgICAgIC5zZXRFbmQoNTM2ODcwOTEyKS5idWlsZCgpKS5idWlsZCgpOworICAgICAgdGhpcy5mdWxsTmFtZSA9IGZ1bGxuYW1lOworICAgICAgdGhpcy5jb250YWluaW5nVHlwZSA9IG51bGw7CisKKyAgICAgIHRoaXMubmVzdGVkVHlwZXMgPSBuZXcgRGVzY3JpcHRvclswXTsKKyAgICAgIHRoaXMuZW51bVR5cGVzID0gbmV3IEVudW1EZXNjcmlwdG9yWzBdOworICAgICAgdGhpcy5maWVsZHMgPSBuZXcgRmllbGREZXNjcmlwdG9yWzBdOworICAgICAgdGhpcy5leHRlbnNpb25zID0gbmV3IEZpZWxkRGVzY3JpcHRvclswXTsKKyAgICAgIHRoaXMub25lb2ZzID0gbmV3IE9uZW9mRGVzY3JpcHRvclswXTsKKyAgICAgIAorICAgICAgLy8gQ3JlYXRlIGEgcGxhY2Vob2xkZXIgRmlsZURlc2NyaXB0b3IgdG8gaG9sZCB0aGlzIG1lc3NhZ2UuCisgICAgICB0aGlzLmZpbGUgPSBuZXcgRmlsZURlc2NyaXB0b3IocGFja2FnZU5hbWUsIHRoaXMpOworICAgIH0KKworICAgIHByaXZhdGUgRGVzY3JpcHRvcihmaW5hbCBEZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIERlc2NyaXB0b3IgcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpCisgICAgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKKyAgICAgIHRoaXMucHJvdG8gPSBwcm90bzsKKyAgICAgIGZ1bGxOYW1lID0gY29tcHV0ZUZ1bGxOYW1lKGZpbGUsIHBhcmVudCwgcHJvdG8uZ2V0TmFtZSgpKTsKKyAgICAgIHRoaXMuZmlsZSA9IGZpbGU7CisgICAgICBjb250YWluaW5nVHlwZSA9IHBhcmVudDsKKworICAgICAgb25lb2ZzID0gbmV3IE9uZW9mRGVzY3JpcHRvcltwcm90by5nZXRPbmVvZkRlY2xDb3VudCgpXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZ2V0T25lb2ZEZWNsQ291bnQoKTsgaSsrKSB7CisgICAgICAgIG9uZW9mc1tpXSA9IG5ldyBPbmVvZkRlc2NyaXB0b3IoCisgICAgICAgICAgcHJvdG8uZ2V0T25lb2ZEZWNsKGkpLCBmaWxlLCB0aGlzLCBpKTsKKyAgICAgIH0KKworICAgICAgbmVzdGVkVHlwZXMgPSBuZXcgRGVzY3JpcHRvcltwcm90by5nZXROZXN0ZWRUeXBlQ291bnQoKV07CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmdldE5lc3RlZFR5cGVDb3VudCgpOyBpKyspIHsKKyAgICAgICAgbmVzdGVkVHlwZXNbaV0gPSBuZXcgRGVzY3JpcHRvcigKKyAgICAgICAgICBwcm90by5nZXROZXN0ZWRUeXBlKGkpLCBmaWxlLCB0aGlzLCBpKTsKKyAgICAgIH0KKworICAgICAgZW51bVR5cGVzID0gbmV3IEVudW1EZXNjcmlwdG9yW3Byb3RvLmdldEVudW1UeXBlQ291bnQoKV07CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmdldEVudW1UeXBlQ291bnQoKTsgaSsrKSB7CisgICAgICAgIGVudW1UeXBlc1tpXSA9IG5ldyBFbnVtRGVzY3JpcHRvcigKKyAgICAgICAgICBwcm90by5nZXRFbnVtVHlwZShpKSwgZmlsZSwgdGhpcywgaSk7CisgICAgICB9CisKKyAgICAgIGZpZWxkcyA9IG5ldyBGaWVsZERlc2NyaXB0b3JbcHJvdG8uZ2V0RmllbGRDb3VudCgpXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZ2V0RmllbGRDb3VudCgpOyBpKyspIHsKKyAgICAgICAgZmllbGRzW2ldID0gbmV3IEZpZWxkRGVzY3JpcHRvcigKKyAgICAgICAgICBwcm90by5nZXRGaWVsZChpKSwgZmlsZSwgdGhpcywgaSwgZmFsc2UpOworICAgICAgfQorCisgICAgICBleHRlbnNpb25zID0gbmV3IEZpZWxkRGVzY3JpcHRvcltwcm90by5nZXRFeHRlbnNpb25Db3VudCgpXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZ2V0RXh0ZW5zaW9uQ291bnQoKTsgaSsrKSB7CisgICAgICAgIGV4dGVuc2lvbnNbaV0gPSBuZXcgRmllbGREZXNjcmlwdG9yKAorICAgICAgICAgIHByb3RvLmdldEV4dGVuc2lvbihpKSwgZmlsZSwgdGhpcywgaSwgdHJ1ZSk7CisgICAgICB9CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZ2V0T25lb2ZEZWNsQ291bnQoKTsgaSsrKSB7CisgICAgICAgIG9uZW9mc1tpXS5maWVsZHMgPSBuZXcgRmllbGREZXNjcmlwdG9yW29uZW9mc1tpXS5nZXRGaWVsZENvdW50KCldOworICAgICAgICBvbmVvZnNbaV0uZmllbGRDb3VudCA9IDA7CisgICAgICB9CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmdldEZpZWxkQ291bnQoKTsgaSsrKSB7CisgICAgICAgIE9uZW9mRGVzY3JpcHRvciBvbmVvZkRlc2NyaXB0b3IgPSBmaWVsZHNbaV0uZ2V0Q29udGFpbmluZ09uZW9mKCk7CisgICAgICAgIGlmIChvbmVvZkRlc2NyaXB0b3IgIT0gbnVsbCkgeworICAgICAgICAgIG9uZW9mRGVzY3JpcHRvci5maWVsZHNbb25lb2ZEZXNjcmlwdG9yLmZpZWxkQ291bnQrK10gPSBmaWVsZHNbaV07CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgZmlsZS5wb29sLmFkZFN5bWJvbCh0aGlzKTsKKyAgICB9CisKKyAgICAvKiogTG9vayB1cCBhbmQgY3Jvc3MtbGluayBhbGwgZmllbGQgdHlwZXMsIGV0Yy4gKi8KKyAgICBwcml2YXRlIHZvaWQgY3Jvc3NMaW5rKCkgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIGZvciAoZmluYWwgRGVzY3JpcHRvciBuZXN0ZWRUeXBlIDogbmVzdGVkVHlwZXMpIHsKKyAgICAgICAgbmVzdGVkVHlwZS5jcm9zc0xpbmsoKTsKKyAgICAgIH0KKworICAgICAgZm9yIChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQgOiBmaWVsZHMpIHsKKyAgICAgICAgZmllbGQuY3Jvc3NMaW5rKCk7CisgICAgICB9CisKKyAgICAgIGZvciAoZmluYWwgRmllbGREZXNjcmlwdG9yIGV4dGVuc2lvbiA6IGV4dGVuc2lvbnMpIHsKKyAgICAgICAgZXh0ZW5zaW9uLmNyb3NzTGluaygpOworICAgICAgfQorICAgIH0KKworICAgIC8qKiBTZWUge0BsaW5rIEZpbGVEZXNjcmlwdG9yI3NldFByb3RvfS4gKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0UHJvdG8oZmluYWwgRGVzY3JpcHRvclByb3RvIHByb3RvKSB7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmVzdGVkVHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgbmVzdGVkVHlwZXNbaV0uc2V0UHJvdG8ocHJvdG8uZ2V0TmVzdGVkVHlwZShpKSk7CisgICAgICB9CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bVR5cGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGVudW1UeXBlc1tpXS5zZXRQcm90byhwcm90by5nZXRFbnVtVHlwZShpKSk7CisgICAgICB9CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGZpZWxkc1tpXS5zZXRQcm90byhwcm90by5nZXRGaWVsZChpKSk7CisgICAgICB9CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9ucy5sZW5ndGg7IGkrKykgeworICAgICAgICBleHRlbnNpb25zW2ldLnNldFByb3RvKHByb3RvLmdldEV4dGVuc2lvbihpKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKiogRGVzY3JpYmVzIGEgZmllbGQgb2YgYSBtZXNzYWdlIHR5cGUuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGREZXNjcmlwdG9yCisgICAgICAgIGV4dGVuZHMgR2VuZXJpY0Rlc2NyaXB0b3IKKyAgICAgICAgaW1wbGVtZW50cyBDb21wYXJhYmxlPEZpZWxkRGVzY3JpcHRvcj4sCisgICAgICAgICAgICAgICAgIEZpZWxkU2V0LkZpZWxkRGVzY3JpcHRvckxpdGU8RmllbGREZXNjcmlwdG9yPiB7CisgICAgLyoqCisgICAgICogR2V0IHRoZSBpbmRleCBvZiB0aGlzIGRlc2NyaXB0b3Igd2l0aGluIGl0cyBwYXJlbnQuCisgICAgICogQHNlZSBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yI2dldEluZGV4KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeyByZXR1cm4gaW5kZXg7IH0KKworICAgIC8qKiBDb252ZXJ0IHRoZSBkZXNjcmlwdG9yIHRvIGl0cyBwcm90b2NvbCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiAqLworICAgIHB1YmxpYyBGaWVsZERlc2NyaXB0b3JQcm90byB0b1Byb3RvKCkgeyByZXR1cm4gcHJvdG87IH0KKworICAgIC8qKiBHZXQgdGhlIGZpZWxkJ3MgdW5xdWFsaWZpZWQgbmFtZS4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBwcm90by5nZXROYW1lKCk7IH0KKworICAgIC8qKiBHZXQgdGhlIGZpZWxkJ3MgbnVtYmVyLiAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgeyByZXR1cm4gcHJvdG8uZ2V0TnVtYmVyKCk7IH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZmllbGQncyBmdWxseS1xdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAc2VlIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IjZ2V0RnVsbE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnVsbE5hbWUoKSB7IHJldHVybiBmdWxsTmFtZTsgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBmaWVsZCdzIGphdmEgdHlwZS4gIFRoaXMgaXMganVzdCBmb3IgY29udmVuaWVuY2UuICBFdmVyeQorICAgICAqIHtAY29kZSBGaWVsZERlc2NyaXB0b3JQcm90by5UeXBlfSBtYXBzIHRvIGV4YWN0bHkgb25lIEphdmEgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmF2YVR5cGUgZ2V0SmF2YVR5cGUoKSB7IHJldHVybiB0eXBlLmdldEphdmFUeXBlKCk7IH0KKworICAgIC8qKiBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuICovCisgICAgcHVibGljIFdpcmVGb3JtYXQuSmF2YVR5cGUgZ2V0TGl0ZUphdmFUeXBlKCkgeworICAgICAgcmV0dXJuIGdldExpdGVUeXBlKCkuZ2V0SmF2YVR5cGUoKTsKKyAgICB9CisKKyAgICAvKiogR2V0IHRoZSB7QGNvZGUgRmlsZURlc2NyaXB0b3J9IGNvbnRhaW5pbmcgdGhpcyBkZXNjcmlwdG9yLiAqLworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGaWxlKCkgeyByZXR1cm4gZmlsZTsgfQorCisgICAgLyoqIEdldCB0aGUgZmllbGQncyBkZWNsYXJlZCB0eXBlLiAqLworICAgIHB1YmxpYyBUeXBlIGdldFR5cGUoKSB7IHJldHVybiB0eXBlOyB9CisKKyAgICAvKiogRm9yIGludGVybmFsIHVzZSBvbmx5LiAqLworICAgIHB1YmxpYyBXaXJlRm9ybWF0LkZpZWxkVHlwZSBnZXRMaXRlVHlwZSgpIHsKKyAgICAgIHJldHVybiB0YWJsZVt0eXBlLm9yZGluYWwoKV07CisgICAgfQorCisgICAgLyoqIEZvciBpbnRlcm5hbCB1c2Ugb25seS4gKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBuZWVkc1V0ZjhDaGVjaygpIHsKKyAgICAgIHJldHVybiAodHlwZSA9PSBUeXBlLlNUUklORykgJiYgKGdldEZpbGUoKS5nZXRPcHRpb25zKCkuZ2V0SmF2YVN0cmluZ0NoZWNrVXRmOCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc01hcEZpZWxkKCkgeworICAgICAgcmV0dXJuIGdldFR5cGUoKSA9PSBUeXBlLk1FU1NBR0UgJiYgaXNSZXBlYXRlZCgpCisgICAgICAgICAgJiYgZ2V0TWVzc2FnZVR5cGUoKS5nZXRPcHRpb25zKCkuZ2V0TWFwRW50cnkoKTsKKyAgICB9CisKKyAgICAvLyBJJ20gcHJldHR5IHN1cmUgdmFsdWVzKCkgY29uc3RydWN0cyBhIG5ldyBhcnJheSBldmVyeSB0aW1lLCBzaW5jZSB0aGVyZQorICAgIC8vIGlzIG5vdGhpbmcgc3RvcHBpbmcgdGhlIGNhbGxlciBmcm9tIG11dGF0aW5nIHRoZSBhcnJheS4gIFRoZXJlZm9yZSB3ZQorICAgIC8vIG1ha2UgYSBzdGF0aWMgY29weSBoZXJlLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFdpcmVGb3JtYXQuRmllbGRUeXBlW10gdGFibGUgPQorICAgICAgICBXaXJlRm9ybWF0LkZpZWxkVHlwZS52YWx1ZXMoKTsKKworICAgIC8qKiBJcyB0aGlzIGZpZWxkIGRlY2xhcmVkIHJlcXVpcmVkPyAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVxdWlyZWQoKSB7CisgICAgICByZXR1cm4gcHJvdG8uZ2V0TGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbC5MQUJFTF9SRVFVSVJFRDsKKyAgICB9CisKKyAgICAvKiogSXMgdGhpcyBmaWVsZCBkZWNsYXJlZCBvcHRpb25hbD8gKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc09wdGlvbmFsKCkgeworICAgICAgcmV0dXJuIHByb3RvLmdldExhYmVsKCkgPT0gRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwuTEFCRUxfT1BUSU9OQUw7CisgICAgfQorCisgICAgLyoqIElzIHRoaXMgZmllbGQgZGVjbGFyZWQgcmVwZWF0ZWQ/ICovCisgICAgcHVibGljIGJvb2xlYW4gaXNSZXBlYXRlZCgpIHsKKyAgICAgIHJldHVybiBwcm90by5nZXRMYWJlbCgpID09IEZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsLkxBQkVMX1JFUEVBVEVEOworICAgIH0KKworICAgIC8qKiBEb2VzIHRoaXMgZmllbGQgaGF2ZSB0aGUge0Bjb2RlIFtwYWNrZWQgPSB0cnVlXX0gb3B0aW9uPyAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUGFja2VkKCkgeworICAgICAgcmV0dXJuIGdldE9wdGlvbnMoKS5nZXRQYWNrZWQoKTsKKyAgICB9CisKKyAgICAvKiogQ2FuIHRoaXMgZmllbGQgYmUgcGFja2VkPyBpLmUuIGlzIGl0IGEgcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkPyAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUGFja2FibGUoKSB7CisgICAgICByZXR1cm4gaXNSZXBlYXRlZCgpICYmIGdldExpdGVUeXBlKCkuaXNQYWNrYWJsZSgpOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZpZWxkIGhhZCBhbiBleHBsaWNpdGx5LWRlZmluZWQgZGVmYXVsdCB2YWx1ZS4gKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0VmFsdWUoKSB7IHJldHVybiBwcm90by5oYXNEZWZhdWx0VmFsdWUoKTsgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmllbGQncyBkZWZhdWx0IHZhbHVlLiAgVmFsaWQgZm9yIGFsbCB0eXBlcyBleGNlcHQgZm9yCisgICAgICogbWVzc2FnZXMgYW5kIGdyb3Vwcy4gIEZvciBhbGwgb3RoZXIgdHlwZXMsIHRoZSBvYmplY3QgcmV0dXJuZWQgaXMgb2YKKyAgICAgKiB0aGUgc2FtZSBjbGFzcyB0aGF0IHdvdWxkIHJldHVybmVkIGJ5IE1lc3NhZ2UuZ2V0RmllbGQodGhpcykuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXREZWZhdWx0VmFsdWUoKSB7CisgICAgICBpZiAoZ2V0SmF2YVR5cGUoKSA9PSBKYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiRmllbGREZXNjcmlwdG9yLmdldERlZmF1bHRWYWx1ZSgpIGNhbGxlZCBvbiBhbiBlbWJlZGRlZCBtZXNzYWdlICIgKworICAgICAgICAgICJmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgfQorCisgICAgLyoqIEdldCB0aGUge0Bjb2RlIEZpZWxkT3B0aW9uc30sIGRlZmluZWQgaW4ge0Bjb2RlIGRlc2NyaXB0b3IucHJvdG99LiAqLworICAgIHB1YmxpYyBGaWVsZE9wdGlvbnMgZ2V0T3B0aW9ucygpIHsgcmV0dXJuIHByb3RvLmdldE9wdGlvbnMoKTsgfQorCisgICAgLyoqIElzIHRoaXMgZmllbGQgYW4gZXh0ZW5zaW9uPyAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRXh0ZW5zaW9uKCkgeyByZXR1cm4gcHJvdG8uaGFzRXh0ZW5kZWUoKTsgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBmaWVsZCdzIGNvbnRhaW5pbmcgdHlwZS4gRm9yIGV4dGVuc2lvbnMsIHRoaXMgaXMgdGhlIHR5cGUgYmVpbmcKKyAgICAgKiBleHRlbmRlZCwgbm90IHRoZSBsb2NhdGlvbiB3aGVyZSB0aGUgZXh0ZW5zaW9uIHdhcyBkZWZpbmVkLiAgU2VlCisgICAgICoge0BsaW5rICNnZXRFeHRlbnNpb25TY29wZSgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVzY3JpcHRvciBnZXRDb250YWluaW5nVHlwZSgpIHsgcmV0dXJuIGNvbnRhaW5pbmdUeXBlOyB9CisKKyAgICAvKiogR2V0IHRoZSBmaWVsZCdzIGNvbnRhaW5pbmcgb25lb2YuICovCisgICAgcHVibGljIE9uZW9mRGVzY3JpcHRvciBnZXRDb250YWluaW5nT25lb2YoKSB7IHJldHVybiBjb250YWluaW5nT25lb2Y7IH0KKworICAgIC8qKgorICAgICAqIEZvciBleHRlbnNpb25zIGRlZmluZWQgbmVzdGVkIHdpdGhpbiBtZXNzYWdlIHR5cGVzLCBnZXRzIHRoZSBvdXRlcgorICAgICAqIHR5cGUuICBOb3QgdmFsaWQgZm9yIG5vbi1leHRlbnNpb24gZmllbGRzLiAgRm9yIGV4YW1wbGUsIGNvbnNpZGVyCisgICAgICogdGhpcyB7QGNvZGUgLnByb3RvfSBmaWxlOgorICAgICAqIDxwcmU+CisgICAgICogICBtZXNzYWdlIEZvbyB7CisgICAgICogICAgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7CisgICAgICogICB9CisgICAgICogICBleHRlbmQgRm9vIHsKKyAgICAgKiAgICAgb3B0aW9uYWwgaW50MzIgYmF6ID0gMTIzNDsKKyAgICAgKiAgIH0KKyAgICAgKiAgIG1lc3NhZ2UgQmFyIHsKKyAgICAgKiAgICAgZXh0ZW5kIEZvbyB7CisgICAgICogICAgICAgb3B0aW9uYWwgaW50MzIgcXV4ID0gNDMyMTsKKyAgICAgKiAgICAgfQorICAgICAqICAgfQorICAgICAqIDwvcHJlPgorICAgICAqIEJvdGgge0Bjb2RlIGJhen0ncyBhbmQge0Bjb2RlIHF1eH0ncyBjb250YWluaW5nIHR5cGUgaXMge0Bjb2RlIEZvb30uCisgICAgICogSG93ZXZlciwge0Bjb2RlIGJhen0ncyBleHRlbnNpb24gc2NvcGUgaXMge0Bjb2RlIG51bGx9IHdoaWxlCisgICAgICoge0Bjb2RlIHF1eH0ncyBleHRlbnNpb24gc2NvcGUgaXMge0Bjb2RlIEJhcn0uCisgICAgICovCisgICAgcHVibGljIERlc2NyaXB0b3IgZ2V0RXh0ZW5zaW9uU2NvcGUoKSB7CisgICAgICBpZiAoIWlzRXh0ZW5zaW9uKCkpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJUaGlzIGZpZWxkIGlzIG5vdCBhbiBleHRlbnNpb24uIik7CisgICAgICB9CisgICAgICByZXR1cm4gZXh0ZW5zaW9uU2NvcGU7CisgICAgfQorCisgICAgLyoqIEZvciBlbWJlZGRlZCBtZXNzYWdlIGFuZCBncm91cCBmaWVsZHMsIGdldHMgdGhlIGZpZWxkJ3MgdHlwZS4gKi8KKyAgICBwdWJsaWMgRGVzY3JpcHRvciBnZXRNZXNzYWdlVHlwZSgpIHsKKyAgICAgIGlmIChnZXRKYXZhVHlwZSgpICE9IEphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJUaGlzIGZpZWxkIGlzIG5vdCBvZiBtZXNzYWdlIHR5cGUuIik7CisgICAgICB9CisgICAgICByZXR1cm4gbWVzc2FnZVR5cGU7CisgICAgfQorCisgICAgLyoqIEZvciBlbnVtIGZpZWxkcywgZ2V0cyB0aGUgZmllbGQncyB0eXBlLiAqLworICAgIHB1YmxpYyBFbnVtRGVzY3JpcHRvciBnZXRFbnVtVHlwZSgpIHsKKyAgICAgIGlmIChnZXRKYXZhVHlwZSgpICE9IEphdmFUeXBlLkVOVU0pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJUaGlzIGZpZWxkIGlzIG5vdCBvZiBlbnVtIHR5cGUuIik7CisgICAgICB9CisgICAgICByZXR1cm4gZW51bVR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZSB3aXRoIGFub3RoZXIge0Bjb2RlIEZpZWxkRGVzY3JpcHRvcn0uICBUaGlzIG9yZGVycyBmaWVsZHMgaW4KKyAgICAgKiAiY2Fub25pY2FsIiBvcmRlciwgd2hpY2ggc2ltcGx5IG1lYW5zIGFzY2VuZGluZyBvcmRlciBieSBmaWVsZCBudW1iZXIuCisgICAgICoge0Bjb2RlIG90aGVyfSBtdXN0IGJlIGEgZmllbGQgb2YgdGhlIHNhbWUgdHlwZSAtLSBpLmUuCisgICAgICoge0Bjb2RlIGdldENvbnRhaW5pbmdUeXBlKCl9IG11c3QgcmV0dXJuIHRoZSBzYW1lIHtAY29kZSBEZXNjcmlwdG9yfSBmb3IKKyAgICAgKiBib3RoIGZpZWxkcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbmVnYXRpdmUsIHplcm8sIG9yIHBvc2l0aXZlIGlmIHtAY29kZSB0aGlzfSBpcyBsZXNzIHRoYW4sCisgICAgICogICAgICAgICBlcXVhbCB0bywgb3IgZ3JlYXRlciB0aGFuIHtAY29kZSBvdGhlcn0sIHJlc3BlY3RpdmVseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhmaW5hbCBGaWVsZERlc2NyaXB0b3Igb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5jb250YWluaW5nVHlwZSAhPSBjb250YWluaW5nVHlwZSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJGaWVsZERlc2NyaXB0b3JzIGNhbiBvbmx5IGJlIGNvbXBhcmVkIHRvIG90aGVyIEZpZWxkRGVzY3JpcHRvcnMgIiArCisgICAgICAgICAgImZvciBmaWVsZHMgb2YgdGhlIHNhbWUgbWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgICAgcmV0dXJuIGdldE51bWJlcigpIC0gb3RoZXIuZ2V0TnVtYmVyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIHJldHVybiBnZXRGdWxsTmFtZSgpOworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgaW50IGluZGV4OworCisgICAgcHJpdmF0ZSBGaWVsZERlc2NyaXB0b3JQcm90byBwcm90bzsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmdWxsTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGZpbGU7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9yIGV4dGVuc2lvblNjb3BlOworCisgICAgLy8gUG9zc2libHkgaW5pdGlhbGl6ZWQgZHVyaW5nIGNyb3NzLWxpbmtpbmcuCisgICAgcHJpdmF0ZSBUeXBlIHR5cGU7CisgICAgcHJpdmF0ZSBEZXNjcmlwdG9yIGNvbnRhaW5pbmdUeXBlOworICAgIHByaXZhdGUgRGVzY3JpcHRvciBtZXNzYWdlVHlwZTsKKyAgICBwcml2YXRlIE9uZW9mRGVzY3JpcHRvciBjb250YWluaW5nT25lb2Y7CisgICAgcHJpdmF0ZSBFbnVtRGVzY3JpcHRvciBlbnVtVHlwZTsKKyAgICBwcml2YXRlIE9iamVjdCBkZWZhdWx0VmFsdWU7CisKKyAgICBwdWJsaWMgZW51bSBUeXBlIHsKKyAgICAgIERPVUJMRSAgKEphdmFUeXBlLkRPVUJMRSAgICAgKSwKKyAgICAgIEZMT0FUICAgKEphdmFUeXBlLkZMT0FUICAgICAgKSwKKyAgICAgIElOVDY0ICAgKEphdmFUeXBlLkxPTkcgICAgICAgKSwKKyAgICAgIFVJTlQ2NCAgKEphdmFUeXBlLkxPTkcgICAgICAgKSwKKyAgICAgIElOVDMyICAgKEphdmFUeXBlLklOVCAgICAgICAgKSwKKyAgICAgIEZJWEVENjQgKEphdmFUeXBlLkxPTkcgICAgICAgKSwKKyAgICAgIEZJWEVEMzIgKEphdmFUeXBlLklOVCAgICAgICAgKSwKKyAgICAgIEJPT0wgICAgKEphdmFUeXBlLkJPT0xFQU4gICAgKSwKKyAgICAgIFNUUklORyAgKEphdmFUeXBlLlNUUklORyAgICAgKSwKKyAgICAgIEdST1VQICAgKEphdmFUeXBlLk1FU1NBR0UgICAgKSwKKyAgICAgIE1FU1NBR0UgKEphdmFUeXBlLk1FU1NBR0UgICAgKSwKKyAgICAgIEJZVEVTICAgKEphdmFUeXBlLkJZVEVfU1RSSU5HKSwKKyAgICAgIFVJTlQzMiAgKEphdmFUeXBlLklOVCAgICAgICAgKSwKKyAgICAgIEVOVU0gICAgKEphdmFUeXBlLkVOVU0gICAgICAgKSwKKyAgICAgIFNGSVhFRDMyKEphdmFUeXBlLklOVCAgICAgICAgKSwKKyAgICAgIFNGSVhFRDY0KEphdmFUeXBlLkxPTkcgICAgICAgKSwKKyAgICAgIFNJTlQzMiAgKEphdmFUeXBlLklOVCAgICAgICAgKSwKKyAgICAgIFNJTlQ2NCAgKEphdmFUeXBlLkxPTkcgICAgICAgKTsKKworICAgICAgVHlwZShmaW5hbCBKYXZhVHlwZSBqYXZhVHlwZSkgeworICAgICAgICB0aGlzLmphdmFUeXBlID0gamF2YVR5cGU7CisgICAgICB9CisKKyAgICAgIHByaXZhdGUgSmF2YVR5cGUgamF2YVR5cGU7CisKKyAgICAgIHB1YmxpYyBGaWVsZERlc2NyaXB0b3JQcm90by5UeXBlIHRvUHJvdG8oKSB7CisgICAgICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90by5UeXBlLnZhbHVlT2Yob3JkaW5hbCgpICsgMSk7CisgICAgICB9CisgICAgICBwdWJsaWMgSmF2YVR5cGUgZ2V0SmF2YVR5cGUoKSB7IHJldHVybiBqYXZhVHlwZTsgfQorCisgICAgICBwdWJsaWMgc3RhdGljIFR5cGUgdmFsdWVPZihmaW5hbCBGaWVsZERlc2NyaXB0b3JQcm90by5UeXBlIHR5cGUpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlcygpW3R5cGUuZ2V0TnVtYmVyKCkgLSAxXTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgeworICAgICAgLy8gUmVmdXNlIHRvIGluaXQgaWYgc29tZW9uZSBhZGRlZCBhIG5ldyBkZWNsYXJlZCB0eXBlLgorICAgICAgaWYgKFR5cGUudmFsdWVzKCkubGVuZ3RoICE9IEZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUudmFsdWVzKCkubGVuZ3RoKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJkZXNjcmlwdG9yLnByb3RvIGhhcyBhIG5ldyBkZWNsYXJlZCB0eXBlIGJ1dCBEZXNyY2lwdG9ycy5qYXZhICIgKworICAgICAgICAgICJ3YXNuJ3QgdXBkYXRlZC4iKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZW51bSBKYXZhVHlwZSB7CisgICAgICBJTlQoMCksCisgICAgICBMT05HKDBMKSwKKyAgICAgIEZMT0FUKDBGKSwKKyAgICAgIERPVUJMRSgwRCksCisgICAgICBCT09MRUFOKGZhbHNlKSwKKyAgICAgIFNUUklORygiIiksCisgICAgICBCWVRFX1NUUklORyhCeXRlU3RyaW5nLkVNUFRZKSwKKyAgICAgIEVOVU0obnVsbCksCisgICAgICBNRVNTQUdFKG51bGwpOworCisgICAgICBKYXZhVHlwZShmaW5hbCBPYmplY3QgZGVmYXVsdERlZmF1bHQpIHsKKyAgICAgICAgdGhpcy5kZWZhdWx0RGVmYXVsdCA9IGRlZmF1bHREZWZhdWx0OworICAgICAgfQorCisgICAgICAvKioKKyAgICAgICAqIFRoZSBkZWZhdWx0IGRlZmF1bHQgdmFsdWUgZm9yIGZpZWxkcyBvZiB0aGlzIHR5cGUsIGlmIGl0J3MgYSBwcmltaXRpdmUKKyAgICAgICAqIHR5cGUuICBUaGlzIGlzIG1lYW50IGZvciB1c2UgaW5zaWRlIHRoaXMgZmlsZSBvbmx5LCBoZW5jZSBpcyBwcml2YXRlLgorICAgICAgICovCisgICAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBkZWZhdWx0RGVmYXVsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIEZpZWxkRGVzY3JpcHRvcihmaW5hbCBGaWVsZERlc2NyaXB0b3JQcm90byBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIERlc2NyaXB0b3IgcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzRXh0ZW5zaW9uKQorICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKKyAgICAgIHRoaXMucHJvdG8gPSBwcm90bzsKKyAgICAgIGZ1bGxOYW1lID0gY29tcHV0ZUZ1bGxOYW1lKGZpbGUsIHBhcmVudCwgcHJvdG8uZ2V0TmFtZSgpKTsKKyAgICAgIHRoaXMuZmlsZSA9IGZpbGU7CisKKyAgICAgIGlmIChwcm90by5oYXNUeXBlKCkpIHsKKyAgICAgICAgdHlwZSA9IFR5cGUudmFsdWVPZihwcm90by5nZXRUeXBlKCkpOworICAgICAgfQorCisgICAgICBpZiAoZ2V0TnVtYmVyKCkgPD0gMCkgeworICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAiRmllbGQgbnVtYmVycyBtdXN0IGJlIHBvc2l0aXZlIGludGVnZXJzLiIpOworICAgICAgfQorCisgICAgICBpZiAoaXNFeHRlbnNpb24pIHsKKyAgICAgICAgaWYgKCFwcm90by5oYXNFeHRlbmRlZSgpKSB7CisgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAiRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUgbm90IHNldCBmb3IgZXh0ZW5zaW9uIGZpZWxkLiIpOworICAgICAgICB9CisgICAgICAgIGNvbnRhaW5pbmdUeXBlID0gbnVsbDsgIC8vIFdpbGwgYmUgZmlsbGVkIGluIHdoZW4gY3Jvc3MtbGlua2luZworICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICBleHRlbnNpb25TY29wZSA9IHBhcmVudDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBleHRlbnNpb25TY29wZSA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBpZiAocHJvdG8uaGFzT25lb2ZJbmRleCgpKSB7CisgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAiRmllbGREZXNjcmlwdG9yUHJvdG8ub25lb2ZfaW5kZXggc2V0IGZvciBleHRlbnNpb24gZmllbGQuIik7CisgICAgICAgIH0KKyAgICAgICAgY29udGFpbmluZ09uZW9mID0gbnVsbDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChwcm90by5oYXNFeHRlbmRlZSgpKSB7CisgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAiRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUgc2V0IGZvciBub24tZXh0ZW5zaW9uIGZpZWxkLiIpOworICAgICAgICB9CisgICAgICAgIGNvbnRhaW5pbmdUeXBlID0gcGFyZW50OworCisgICAgICAgIGlmIChwcm90by5oYXNPbmVvZkluZGV4KCkpIHsKKyAgICAgICAgICBpZiAocHJvdG8uZ2V0T25lb2ZJbmRleCgpIDwgMCB8fAorICAgICAgICAgICAgICBwcm90by5nZXRPbmVvZkluZGV4KCkgPj0gcGFyZW50LnRvUHJvdG8oKS5nZXRPbmVvZkRlY2xDb3VudCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4IGlzIG91dCBvZiByYW5nZSBmb3IgdHlwZSAiCisgICAgICAgICAgICAgICsgcGFyZW50LmdldE5hbWUoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGNvbnRhaW5pbmdPbmVvZiA9IHBhcmVudC5nZXRPbmVvZnMoKS5nZXQocHJvdG8uZ2V0T25lb2ZJbmRleCgpKTsKKyAgICAgICAgICBjb250YWluaW5nT25lb2YuZmllbGRDb3VudCsrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGNvbnRhaW5pbmdPbmVvZiA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgZXh0ZW5zaW9uU2NvcGUgPSBudWxsOworICAgICAgfQorCisgICAgICBmaWxlLnBvb2wuYWRkU3ltYm9sKHRoaXMpOworICAgIH0KKworICAgIC8qKiBMb29rIHVwIGFuZCBjcm9zcy1saW5rIGFsbCBmaWVsZCB0eXBlcywgZXRjLiAqLworICAgIHByaXZhdGUgdm9pZCBjcm9zc0xpbmsoKSB0aHJvd3MgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24geworICAgICAgaWYgKHByb3RvLmhhc0V4dGVuZGVlKCkpIHsKKyAgICAgICAgZmluYWwgR2VuZXJpY0Rlc2NyaXB0b3IgZXh0ZW5kZWUgPQorICAgICAgICAgIGZpbGUucG9vbC5sb29rdXBTeW1ib2wocHJvdG8uZ2V0RXh0ZW5kZWUoKSwgdGhpcywKKyAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2wuU2VhcmNoRmlsdGVyLlRZUEVTX09OTFkpOworICAgICAgICBpZiAoIShleHRlbmRlZSBpbnN0YW5jZW9mIERlc2NyaXB0b3IpKSB7CisgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAgICdcIicgKyBwcm90by5nZXRFeHRlbmRlZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgICAgfQorICAgICAgICBjb250YWluaW5nVHlwZSA9IChEZXNjcmlwdG9yKWV4dGVuZGVlOworCisgICAgICAgIGlmICghZ2V0Q29udGFpbmluZ1R5cGUoKS5pc0V4dGVuc2lvbk51bWJlcihnZXROdW1iZXIoKSkpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICAgJ1wiJyArIGdldENvbnRhaW5pbmdUeXBlKCkuZ2V0RnVsbE5hbWUoKSArCisgICAgICAgICAgICAgICJcIiBkb2VzIG5vdCBkZWNsYXJlICIgKyBnZXROdW1iZXIoKSArCisgICAgICAgICAgICAgICIgYXMgYW4gZXh0ZW5zaW9uIG51bWJlci4iKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAocHJvdG8uaGFzVHlwZU5hbWUoKSkgeworICAgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciB0eXBlRGVzY3JpcHRvciA9CisgICAgICAgICAgZmlsZS5wb29sLmxvb2t1cFN5bWJvbChwcm90by5nZXRUeXBlTmFtZSgpLCB0aGlzLAorICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbC5TZWFyY2hGaWx0ZXIuVFlQRVNfT05MWSk7CisKKyAgICAgICAgaWYgKCFwcm90by5oYXNUeXBlKCkpIHsKKyAgICAgICAgICAvLyBDaG9vc2UgZmllbGQgdHlwZSBiYXNlZCBvbiBzeW1ib2wuCisgICAgICAgICAgaWYgKHR5cGVEZXNjcmlwdG9yIGluc3RhbmNlb2YgRGVzY3JpcHRvcikgeworICAgICAgICAgICAgdHlwZSA9IFR5cGUuTUVTU0FHRTsKKyAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVEZXNjcmlwdG9yIGluc3RhbmNlb2YgRW51bURlc2NyaXB0b3IpIHsKKyAgICAgICAgICAgIHR5cGUgPSBUeXBlLkVOVU07CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbih0aGlzLAorICAgICAgICAgICAgICAgICdcIicgKyBwcm90by5nZXRUeXBlTmFtZSgpICsgIlwiIGlzIG5vdCBhIHR5cGUuIik7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGdldEphdmFUeXBlKCkgPT0gSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICAgIGlmICghKHR5cGVEZXNjcmlwdG9yIGluc3RhbmNlb2YgRGVzY3JpcHRvcikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbih0aGlzLAorICAgICAgICAgICAgICAgICdcIicgKyBwcm90by5nZXRUeXBlTmFtZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgbWVzc2FnZVR5cGUgPSAoRGVzY3JpcHRvcil0eXBlRGVzY3JpcHRvcjsKKworICAgICAgICAgIGlmIChwcm90by5oYXNEZWZhdWx0VmFsdWUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAgICJNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChnZXRKYXZhVHlwZSgpID09IEphdmFUeXBlLkVOVU0pIHsKKyAgICAgICAgICBpZiAoISh0eXBlRGVzY3JpcHRvciBpbnN0YW5jZW9mIEVudW1EZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAgICAgJ1wiJyArIHByb3RvLmdldFR5cGVOYW1lKCkgKyAiXCIgaXMgbm90IGFuIGVudW0gdHlwZS4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgZW51bVR5cGUgPSAoRW51bURlc2NyaXB0b3IpdHlwZURlc2NyaXB0b3I7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAiRmllbGQgd2l0aCBwcmltaXRpdmUgdHlwZSBoYXMgdHlwZV9uYW1lLiIpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoZ2V0SmF2YVR5cGUoKSA9PSBKYXZhVHlwZS5NRVNTQUdFIHx8CisgICAgICAgICAgICBnZXRKYXZhVHlwZSgpID09IEphdmFUeXBlLkVOVU0pIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICJGaWVsZCB3aXRoIG1lc3NhZ2Ugb3IgZW51bSB0eXBlIG1pc3NpbmcgdHlwZV9uYW1lLiIpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIE9ubHkgcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkcyBtYXkgYmUgcGFja2VkLgorICAgICAgaWYgKHByb3RvLmdldE9wdGlvbnMoKS5nZXRQYWNrZWQoKSAmJiAhaXNQYWNrYWJsZSgpKSB7CisgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbih0aGlzLAorICAgICAgICAgICJbcGFja2VkID0gdHJ1ZV0gY2FuIG9ubHkgYmUgc3BlY2lmaWVkIGZvciByZXBlYXRlZCBwcmltaXRpdmUgIiArCisgICAgICAgICAgImZpZWxkcy4iKTsKKyAgICAgIH0KKworICAgICAgLy8gV2UgZG9uJ3QgYXR0ZW1wdCB0byBwYXJzZSB0aGUgZGVmYXVsdCB2YWx1ZSB1bnRpbCBoZXJlIGJlY2F1c2UgZm9yCisgICAgICAvLyBlbnVtcyB3ZSBuZWVkIHRoZSBlbnVtIHR5cGUncyBkZXNjcmlwdG9yLgorICAgICAgaWYgKHByb3RvLmhhc0RlZmF1bHRWYWx1ZSgpKSB7CisgICAgICAgIGlmIChpc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICJSZXBlYXRlZCBmaWVsZHMgY2Fubm90IGhhdmUgZGVmYXVsdCB2YWx1ZXMuIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgIHN3aXRjaCAoZ2V0VHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIElOVDMyOgorICAgICAgICAgICAgY2FzZSBTSU5UMzI6CisgICAgICAgICAgICBjYXNlIFNGSVhFRDMyOgorICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBUZXh0Rm9ybWF0LnBhcnNlSW50MzIocHJvdG8uZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVUlOVDMyOgorICAgICAgICAgICAgY2FzZSBGSVhFRDMyOgorICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBUZXh0Rm9ybWF0LnBhcnNlVUludDMyKHByb3RvLmdldERlZmF1bHRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIElOVDY0OgorICAgICAgICAgICAgY2FzZSBTSU5UNjQ6CisgICAgICAgICAgICBjYXNlIFNGSVhFRDY0OgorICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBUZXh0Rm9ybWF0LnBhcnNlSW50NjQocHJvdG8uZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVUlOVDY0OgorICAgICAgICAgICAgY2FzZSBGSVhFRDY0OgorICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBUZXh0Rm9ybWF0LnBhcnNlVUludDY0KHByb3RvLmdldERlZmF1bHRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEZMT0FUOgorICAgICAgICAgICAgICBpZiAocHJvdG8uZ2V0RGVmYXVsdFZhbHVlKCkuZXF1YWxzKCJpbmYiKSkgeworICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZOworICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvLmdldERlZmF1bHRWYWx1ZSgpLmVxdWFscygiLWluZiIpKSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFk7CisgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvdG8uZ2V0RGVmYXVsdFZhbHVlKCkuZXF1YWxzKCJuYW4iKSkgeworICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IEZsb2F0Lk5hTjsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBGbG9hdC52YWx1ZU9mKHByb3RvLmdldERlZmF1bHRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRE9VQkxFOgorICAgICAgICAgICAgICBpZiAocHJvdG8uZ2V0RGVmYXVsdFZhbHVlKCkuZXF1YWxzKCJpbmYiKSkgeworICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm90by5nZXREZWZhdWx0VmFsdWUoKS5lcXVhbHMoIi1pbmYiKSkgeworICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWTsKKyAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm90by5nZXREZWZhdWx0VmFsdWUoKS5lcXVhbHMoIm5hbiIpKSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gRG91YmxlLk5hTjsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBEb3VibGUudmFsdWVPZihwcm90by5nZXREZWZhdWx0VmFsdWUoKSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEJPT0w6CisgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IEJvb2xlYW4udmFsdWVPZihwcm90by5nZXREZWZhdWx0VmFsdWUoKSk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTVFJJTkc6CisgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IHByb3RvLmdldERlZmF1bHRWYWx1ZSgpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQllURVM6CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0KKyAgICAgICAgICAgICAgICAgIFRleHRGb3JtYXQudW5lc2NhcGVCeXRlcyhwcm90by5nZXREZWZhdWx0VmFsdWUoKSk7CisgICAgICAgICAgICAgIH0gY2F0Y2ggKFRleHRGb3JtYXQuSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICAgICAgICJDb3VsZG4ndCBwYXJzZSBkZWZhdWx0IHZhbHVlOiAiICsgZS5nZXRNZXNzYWdlKCksIGUpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBFTlVNOgorICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBlbnVtVHlwZS5maW5kVmFsdWVCeU5hbWUocHJvdG8uZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgICAgICAgICAgICBpZiAoZGVmYXVsdFZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICAgICAgICJVbmtub3duIGVudW0gZGVmYXVsdCB2YWx1ZTogXCIiICsKKyAgICAgICAgICAgICAgICAgIHByb3RvLmdldERlZmF1bHRWYWx1ZSgpICsgJ1wiJyk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgICAgICBjYXNlIEdST1VQOgorICAgICAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICAgICAiTWVzc2FnZSB0eXBlIGhhZCBkZWZhdWx0IHZhbHVlLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywgCisgICAgICAgICAgICAgICJDb3VsZCBub3QgcGFyc2UgZGVmYXVsdCB2YWx1ZTogXCIiICsgCisgICAgICAgICAgICAgIHByb3RvLmdldERlZmF1bHRWYWx1ZSgpICsgJ1wiJywgZSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIERldGVybWluZSB0aGUgZGVmYXVsdCBkZWZhdWx0IGZvciB0aGlzIGZpZWxkLgorICAgICAgICBpZiAoaXNSZXBlYXRlZCgpKSB7CisgICAgICAgICAgZGVmYXVsdFZhbHVlID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc3dpdGNoIChnZXRKYXZhVHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIEVOVU06CisgICAgICAgICAgICAgIC8vIFdlIGd1YXJhbnRlZSBlbHNld2hlcmUgdGhhdCBhbiBlbnVtIHR5cGUgYWx3YXlzIGhhcyBhdCBsZWFzdAorICAgICAgICAgICAgICAvLyBvbmUgcG9zc2libGUgdmFsdWUuCisgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGVudW1UeXBlLmdldFZhbHVlcygpLmdldCgwKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IG51bGw7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gZ2V0SmF2YVR5cGUoKS5kZWZhdWx0RGVmYXVsdDsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmICghaXNFeHRlbnNpb24oKSkgeworICAgICAgICBmaWxlLnBvb2wuYWRkRmllbGRCeU51bWJlcih0aGlzKTsKKyAgICAgIH0KKworICAgICAgaWYgKGNvbnRhaW5pbmdUeXBlICE9IG51bGwgJiYKKyAgICAgICAgICBjb250YWluaW5nVHlwZS5nZXRPcHRpb25zKCkuZ2V0TWVzc2FnZVNldFdpcmVGb3JtYXQoKSkgeworICAgICAgICBpZiAoaXNFeHRlbnNpb24oKSkgeworICAgICAgICAgIGlmICghaXNPcHRpb25hbCgpIHx8IGdldFR5cGUoKSAhPSBUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbih0aGlzLAorICAgICAgICAgICAgICAiRXh0ZW5zaW9ucyBvZiBNZXNzYWdlU2V0cyBtdXN0IGJlIG9wdGlvbmFsIG1lc3NhZ2VzLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24odGhpcywKKyAgICAgICAgICAgICJNZXNzYWdlU2V0cyBjYW5ub3QgaGF2ZSBmaWVsZHMsIG9ubHkgZXh0ZW5zaW9ucy4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8qKiBTZWUge0BsaW5rIEZpbGVEZXNjcmlwdG9yI3NldFByb3RvfS4gKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0UHJvdG8oZmluYWwgRmllbGREZXNjcmlwdG9yUHJvdG8gcHJvdG8pIHsKKyAgICAgIHRoaXMucHJvdG8gPSBwcm90bzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuICBUaGlzIGlzIHRvIHNhdGlzZnkgdGhlIEZpZWxkRGVzY3JpcHRvckxpdGUKKyAgICAgKiBpbnRlcmZhY2UuCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VMaXRlLkJ1aWxkZXIgaW50ZXJuYWxNZXJnZUZyb20oCisgICAgICAgIE1lc3NhZ2VMaXRlLkJ1aWxkZXIgdG8sIE1lc3NhZ2VMaXRlIGZyb20pIHsKKyAgICAgIC8vIEZpZWxkRGVzY3JpcHRvcnMgYXJlIG9ubHkgdXNlZCB3aXRoIG5vbi1saXRlIG1lc3NhZ2VzIHNvIHdlIGNhbiBqdXN0CisgICAgICAvLyBkb3duLWNhc3QgYW5kIGNhbGwgbWVyZ2VGcm9tIGRpcmVjdGx5LgorICAgICAgcmV0dXJuICgoTWVzc2FnZS5CdWlsZGVyKSB0bykubWVyZ2VGcm9tKChNZXNzYWdlKSBmcm9tKTsKKyAgICB9CisKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqIERlc2NyaWJlcyBhbiBlbnVtIHR5cGUuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRW51bURlc2NyaXB0b3IgZXh0ZW5kcyBHZW5lcmljRGVzY3JpcHRvcgorICAgICAgaW1wbGVtZW50cyBJbnRlcm5hbC5FbnVtTGl0ZU1hcDxFbnVtVmFsdWVEZXNjcmlwdG9yPiB7CisgICAgLyoqCisgICAgICogR2V0IHRoZSBpbmRleCBvZiB0aGlzIGRlc2NyaXB0b3Igd2l0aGluIGl0cyBwYXJlbnQuCisgICAgICogQHNlZSBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yI2dldEluZGV4KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeyByZXR1cm4gaW5kZXg7IH0KKworICAgIC8qKiBDb252ZXJ0IHRoZSBkZXNjcmlwdG9yIHRvIGl0cyBwcm90b2NvbCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiAqLworICAgIHB1YmxpYyBFbnVtRGVzY3JpcHRvclByb3RvIHRvUHJvdG8oKSB7IHJldHVybiBwcm90bzsgfQorCisgICAgLyoqIEdldCB0aGUgdHlwZSdzIHVucXVhbGlmaWVkIG5hbWUuICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeyByZXR1cm4gcHJvdG8uZ2V0TmFtZSgpOyB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHR5cGUncyBmdWxseS1xdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAc2VlIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IjZ2V0RnVsbE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnVsbE5hbWUoKSB7IHJldHVybiBmdWxsTmFtZTsgfQorCisgICAgLyoqIEdldCB0aGUge0BsaW5rIEZpbGVEZXNjcmlwdG9yfSBjb250YWluaW5nIHRoaXMgZGVzY3JpcHRvci4gKi8KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RmlsZSgpIHsgcmV0dXJuIGZpbGU7IH0KKworICAgIC8qKiBJZiB0aGlzIGlzIGEgbmVzdGVkIHR5cGUsIGdldCB0aGUgb3V0ZXIgZGVzY3JpcHRvciwgb3RoZXJ3aXNlIG51bGwuICovCisgICAgcHVibGljIERlc2NyaXB0b3IgZ2V0Q29udGFpbmluZ1R5cGUoKSB7IHJldHVybiBjb250YWluaW5nVHlwZTsgfQorCisgICAgLyoqIEdldCB0aGUge0Bjb2RlIEVudW1PcHRpb25zfSwgZGVmaW5lZCBpbiB7QGNvZGUgZGVzY3JpcHRvci5wcm90b30uICovCisgICAgcHVibGljIEVudW1PcHRpb25zIGdldE9wdGlvbnMoKSB7IHJldHVybiBwcm90by5nZXRPcHRpb25zKCk7IH0KKworICAgIC8qKiBHZXQgYSBsaXN0IG9mIGRlZmluZWQgdmFsdWVzIGZvciB0aGlzIGVudW0uICovCisgICAgcHVibGljIExpc3Q8RW51bVZhbHVlRGVzY3JpcHRvcj4gZ2V0VmFsdWVzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoQXJyYXlzLmFzTGlzdCh2YWx1ZXMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuIGVudW0gdmFsdWUgYnkgbmFtZS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgdmFsdWUgKGUuZy4gIkZPTyIpLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlJ3MgZGVzY3JpcHRvciwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bVZhbHVlRGVzY3JpcHRvciBmaW5kVmFsdWVCeU5hbWUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIHJlc3VsdCA9CisgICAgICAgICAgZmlsZS5wb29sLmZpbmRTeW1ib2woZnVsbE5hbWUgKyAnLicgKyBuYW1lKTsKKyAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQgaW5zdGFuY2VvZiBFbnVtVmFsdWVEZXNjcmlwdG9yKSB7CisgICAgICAgIHJldHVybiAoRW51bVZhbHVlRGVzY3JpcHRvcilyZXN1bHQ7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuIGVudW0gdmFsdWUgYnkgbnVtYmVyLiAgSWYgbXVsdGlwbGUgZW51bSB2YWx1ZXMgaGF2ZSB0aGUgc2FtZQorICAgICAqIG51bWJlciwgdGhpcyByZXR1cm5zIHRoZSBmaXJzdCBkZWZpbmVkIHZhbHVlIHdpdGggdGhhdCBudW1iZXIuCisgICAgICogQHBhcmFtIG51bWJlciBUaGUgdmFsdWUncyBudW1iZXIuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUncyBkZXNjcmlwdG9yLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBFbnVtVmFsdWVEZXNjcmlwdG9yIGZpbmRWYWx1ZUJ5TnVtYmVyKGZpbmFsIGludCBudW1iZXIpIHsKKyAgICAgIHJldHVybiBmaWxlLnBvb2wuZW51bVZhbHVlc0J5TnVtYmVyLmdldCgKKyAgICAgICAgbmV3IERlc2NyaXB0b3JQb29sLkRlc2NyaXB0b3JJbnRQYWlyKHRoaXMsIG51bWJlcikpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGVudW0gdmFsdWUgZm9yIGEgbnVtYmVyLiBJZiBubyBlbnVtIHZhbHVlIGhhcyB0aGlzIG51bWJlciwKKyAgICAgKiBjb25zdHJ1Y3QgYW4gRW51bVZhbHVlRGVzY3JpcHRvciBmb3IgaXQuCisgICAgICovCisgICAgcHVibGljIEVudW1WYWx1ZURlc2NyaXB0b3IgZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bihmaW5hbCBpbnQgbnVtYmVyKSB7CisgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yIHJlc3VsdCA9IGZpbmRWYWx1ZUJ5TnVtYmVyKG51bWJlcik7CisgICAgICBpZiAocmVzdWx0ICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKyAgICAgIC8vIFRoZSBudW1iZXIgcmVwcmVzZW50cyBhbiB1bmtub3duIGVudW0gdmFsdWUuCisgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgLy8gRGVzY3JpcHRvcnMgYXJlIGNvbXBhcmVkIGJ5IG9iamVjdCBpZGVudGl0eSBzbyBmb3IgdGhlIHNhbWUgbnVtYmVyCisgICAgICAgIC8vIHdlIG5lZWQgdG8gcmV0dXJuIHRoZSBzYW1lIEVudW1WYWx1ZURlc2NyaXB0b3Igb2JqZWN0LiBUaGlzIG1lYW5zCisgICAgICAgIC8vIHdlIGhhdmUgdG8gc3RvcmUgY3JlYXRlZCBFbnVtVmFsdWVEZXNjcmlwdG9ycy4gSG93ZXZlciwgYXMgdGhlcmUKKyAgICAgICAgLy8gYXJlIHBvdGVudGlhbGx5IDJHIHVua25vd24gZW51bSB2YWx1ZXMsIHN0b3JpbmcgYWxsIG9mIHRoZXNlCisgICAgICAgIC8vIG9iamVjdHMgcGVyc2lzdGVudGx5IHdpbGwgY29uc3VtZSBsb3RzIG9mIG1lbW9yeSBmb3IgbG9uZy1ydW5uaW5nCisgICAgICAgIC8vIHNlcnZpY2VzIGFuZCBpdCdzIGFsc28gdW5uZWNlc3NhcnkgYXMgbm90IG1hbnkgRW51bVZhbHVlRGVzY3JpcHRvcnMKKyAgICAgICAgLy8gd2lsbCBiZSB1c2VkIGF0IHRoZSBzYW1lIHRpbWUuCisgICAgICAgIC8vCisgICAgICAgIC8vIFRvIHNvbHZlIHRoZSBwcm9ibGVtIHdlIHRha2UgYWR2YW50YWdlIG9mIEphdmEncyB3ZWFrIHJlZmVyZW5jZXMgYW5kCisgICAgICAgIC8vIHJlbHkgb24gZ2MgdG8gcmVsZWFzZSB1bnVzZWQgZGVzY3JpcHRvcnMuCisgICAgICAgIC8vCisgICAgICAgIC8vIEhlcmUgaXMgaG93IGl0IHdvcmtzOgorICAgICAgICAvLyAgICogV2Ugc3RvcmUgdW5rbm93biBFbnVtVmFsdWVEZXNjcmlwdG9ycyBpbiBhIFdlYWtIYXNoTWFwIHdpdGggdGhlCisgICAgICAgIC8vICAgICB2YWx1ZSBiZWluZyBhIHdlYWsgcmVmZXJlbmNlIHRvIHRoZSBkZXNjcmlwdG9yLgorICAgICAgICAvLyAgICogVGhlIGRlc2NyaXB0b3IgaG9sZHMgYSBzdHJvbmcgcmVmZXJlbmNlIHRvIHRoZSBrZXkgc28gYXMgbG9uZworICAgICAgICAvLyAgICAgYXMgdGhlIEVudW1WYWx1ZURlc2NyaXB0b3IgaXMgaW4gdXNlLCB0aGUga2V5IHdpbGwgYmUgdGhlcmUKKyAgICAgICAgLy8gICAgIGFuZCB0aGUgY29ycmVzcG9uZGluZyBtYXAgZW50cnkgd2lsbCBiZSB0aGVyZS4gRm9sbG93aW5nLXVwCisgICAgICAgIC8vICAgICBxdWVyaWVzIHdpdGggdGhlIHNhbWUgbnVtYmVyIHdpbGwgcmV0dXJuIHRoZSBzYW1lIGRlc2NyaXB0b3IuCisgICAgICAgIC8vICAgKiBJZiB0aGUgdXNlciBubyBsb25nZXIgdXNlcyBhbiB1bmtub3duIEVudW1WYWx1ZURlc2NyaXB0b3IsCisgICAgICAgIC8vICAgICBpdCB3aWxsIGJlIGdjLWVkIHNpbmNlIHdlIG9ubHkgaG9sZCBhIHdlYWsgcmVmZXJlbmNlIHRvIGl0IGluCisgICAgICAgIC8vICAgICB0aGUgbWFwLiBUaGUga2V5IGluIHRoZSBjb3JyZXNwb25kaW5nIG1hcCBlbnRyeSB3aWxsIGFsc28gYmUKKyAgICAgICAgLy8gICAgIGdjLWVkIGFzIHRoZSBvbmx5IHN0cm9uZyByZWZlcmVuY2UgdG8gaXQgaXMgaW4gdGhlIGRlc2NyaXB0b3IKKyAgICAgICAgLy8gICAgIHdoaWNoIGlzIGp1c3QgZ2MtZWQuIFdpdGggdGhlIGtleSBiZWluZyBnb25lIFdlYWtIYXNoTWFwIHdpbGwKKyAgICAgICAgLy8gICAgIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBlbnRyeS4gVGhpcyB3YXkgdW5rbm93biBkZXNjcmlwdG9ycyB3aWxsCisgICAgICAgIC8vICAgICBiZSBmcmVlZCBhdXRvbWF0aWNhbGx5IGFuZCB3ZSBkb24ndCBuZWVkIHRvIGRvIGFueXRoaW5nIHRvCisgICAgICAgIC8vICAgICBjbGVhbi11cCB1bnVzZWQgbWFwIGVudHJpZXMuCisgICAgICAgIAorICAgICAgICAvLyBOb3RlOiBXZSBtdXN0IHVzZSAibmV3IEludGVnZXIobnVtYmVyKSIgaGVyZSBiZWNhdXNlIHdlIGRvbid0IHdhbnQKKyAgICAgICAgLy8gdGhlc2UgSW50ZWdlciBvYmplY3RzIHRvIGJlIGNhY2hlZC4KKyAgICAgICAgSW50ZWdlciBrZXkgPSBuZXcgSW50ZWdlcihudW1iZXIpOworICAgICAgICBXZWFrUmVmZXJlbmNlPEVudW1WYWx1ZURlc2NyaXB0b3I+IHJlZmVyZW5jZSA9IHVua25vd25WYWx1ZXMuZ2V0KGtleSk7CisgICAgICAgIGlmIChyZWZlcmVuY2UgIT0gbnVsbCkgeworICAgICAgICAgIHJlc3VsdCA9IHJlZmVyZW5jZS5nZXQoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICByZXN1bHQgPSBuZXcgRW51bVZhbHVlRGVzY3JpcHRvcihmaWxlLCB0aGlzLCBrZXkpOworICAgICAgICAgIHVua25vd25WYWx1ZXMucHV0KGtleSwgbmV3IFdlYWtSZWZlcmVuY2U8RW51bVZhbHVlRGVzY3JpcHRvcj4ocmVzdWx0KSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIAorICAgIC8vIFVzZWQgaW4gdGVzdHMgb25seS4KKyAgICBpbnQgZ2V0VW5rbm93bkVudW1WYWx1ZURlc2NyaXB0b3JDb3VudCgpIHsKKyAgICAgIHJldHVybiB1bmtub3duVmFsdWVzLnNpemUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBpbmRleDsKKyAgICBwcml2YXRlIEVudW1EZXNjcmlwdG9yUHJvdG8gcHJvdG87CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZnVsbE5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlOworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvciBjb250YWluaW5nVHlwZTsKKyAgICBwcml2YXRlIEVudW1WYWx1ZURlc2NyaXB0b3JbXSB2YWx1ZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBXZWFrSGFzaE1hcDxJbnRlZ2VyLCBXZWFrUmVmZXJlbmNlPEVudW1WYWx1ZURlc2NyaXB0b3I+PiB1bmtub3duVmFsdWVzID0KKyAgICAgICAgbmV3IFdlYWtIYXNoTWFwPEludGVnZXIsIFdlYWtSZWZlcmVuY2U8RW51bVZhbHVlRGVzY3JpcHRvcj4+KCk7CisKKyAgICBwcml2YXRlIEVudW1EZXNjcmlwdG9yKGZpbmFsIEVudW1EZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRGVzY3JpcHRvciBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisgICAgICBmdWxsTmFtZSA9IGNvbXB1dGVGdWxsTmFtZShmaWxlLCBwYXJlbnQsIHByb3RvLmdldE5hbWUoKSk7CisgICAgICB0aGlzLmZpbGUgPSBmaWxlOworICAgICAgY29udGFpbmluZ1R5cGUgPSBwYXJlbnQ7CisKKyAgICAgIGlmIChwcm90by5nZXRWYWx1ZUNvdW50KCkgPT0gMCkgeworICAgICAgICAvLyBXZSBjYW5ub3QgYWxsb3cgZW51bXMgd2l0aCBubyB2YWx1ZXMgYmVjYXVzZSB0aGlzIHdvdWxkIG1lYW4gdGhlcmUKKyAgICAgICAgLy8gd291bGQgYmUgbm8gdmFsaWQgZGVmYXVsdCB2YWx1ZSBmb3IgZmllbGRzIG9mIHRoaXMgdHlwZS4KKyAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgIkVudW1zIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgdmFsdWUuIik7CisgICAgICB9CisKKyAgICAgIHZhbHVlcyA9IG5ldyBFbnVtVmFsdWVEZXNjcmlwdG9yW3Byb3RvLmdldFZhbHVlQ291bnQoKV07CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmdldFZhbHVlQ291bnQoKTsgaSsrKSB7CisgICAgICAgIHZhbHVlc1tpXSA9IG5ldyBFbnVtVmFsdWVEZXNjcmlwdG9yKAorICAgICAgICAgIHByb3RvLmdldFZhbHVlKGkpLCBmaWxlLCB0aGlzLCBpKTsKKyAgICAgIH0KKworICAgICAgZmlsZS5wb29sLmFkZFN5bWJvbCh0aGlzKTsKKyAgICB9CisKKyAgICAvKiogU2VlIHtAbGluayBGaWxlRGVzY3JpcHRvciNzZXRQcm90b30uICovCisgICAgcHJpdmF0ZSB2b2lkIHNldFByb3RvKGZpbmFsIEVudW1EZXNjcmlwdG9yUHJvdG8gcHJvdG8pIHsKKyAgICAgIHRoaXMucHJvdG8gPSBwcm90bzsKKworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgdmFsdWVzW2ldLnNldFByb3RvKHByb3RvLmdldFZhbHVlKGkpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8qKgorICAgKiBEZXNjcmliZXMgb25lIHZhbHVlIHdpdGhpbiBhbiBlbnVtIHR5cGUuICBOb3RlIHRoYXQgbXVsdGlwbGUgZGVmaW5lZAorICAgKiB2YWx1ZXMgbWF5IGhhdmUgdGhlIHNhbWUgbnVtYmVyLiAgSW4gZ2VuZXJhdGVkIEphdmEgY29kZSwgYWxsIHZhbHVlcworICAgKiB3aXRoIHRoZSBzYW1lIG51bWJlciBhZnRlciB0aGUgZmlyc3QgYmVjb21lIGFsaWFzZXMgb2YgdGhlIGZpcnN0LgorICAgKiBIb3dldmVyLCB0aGV5IHN0aWxsIGhhdmUgaW5kZXBlbmRlbnQgRW51bVZhbHVlRGVzY3JpcHRvcnMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEVudW1WYWx1ZURlc2NyaXB0b3IgZXh0ZW5kcyBHZW5lcmljRGVzY3JpcHRvcgorICAgICAgaW1wbGVtZW50cyBJbnRlcm5hbC5FbnVtTGl0ZSB7CisgICAgLyoqCisgICAgICogR2V0IHRoZSBpbmRleCBvZiB0aGlzIGRlc2NyaXB0b3Igd2l0aGluIGl0cyBwYXJlbnQuCisgICAgICogQHNlZSBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yI2dldEluZGV4KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeyByZXR1cm4gaW5kZXg7IH0KKworICAgIC8qKiBDb252ZXJ0IHRoZSBkZXNjcmlwdG9yIHRvIGl0cyBwcm90b2NvbCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiAqLworICAgIHB1YmxpYyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdG9Qcm90bygpIHsgcmV0dXJuIHByb3RvOyB9CisKKyAgICAvKiogR2V0IHRoZSB2YWx1ZSdzIHVucXVhbGlmaWVkIG5hbWUuICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeyByZXR1cm4gcHJvdG8uZ2V0TmFtZSgpOyB9CisKKyAgICAvKiogR2V0IHRoZSB2YWx1ZSdzIG51bWJlci4gKi8KKyAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsgcmV0dXJuIHByb3RvLmdldE51bWJlcigpOyB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgcmV0dXJuIHByb3RvLmdldE5hbWUoKTsgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB2YWx1ZSdzIGZ1bGx5LXF1YWxpZmllZCBuYW1lLgorICAgICAqIEBzZWUgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciNnZXRGdWxsTmFtZSgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGdWxsTmFtZSgpIHsgcmV0dXJuIGZ1bGxOYW1lOyB9CisKKyAgICAvKiogR2V0IHRoZSB7QGxpbmsgRmlsZURlc2NyaXB0b3J9IGNvbnRhaW5pbmcgdGhpcyBkZXNjcmlwdG9yLiAqLworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGaWxlKCkgeyByZXR1cm4gZmlsZTsgfQorCisgICAgLyoqIEdldCB0aGUgdmFsdWUncyBlbnVtIHR5cGUuICovCisgICAgcHVibGljIEVudW1EZXNjcmlwdG9yIGdldFR5cGUoKSB7IHJldHVybiB0eXBlOyB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHtAY29kZSBFbnVtVmFsdWVPcHRpb25zfSwgZGVmaW5lZCBpbiB7QGNvZGUgZGVzY3JpcHRvci5wcm90b30uCisgICAgICovCisgICAgcHVibGljIEVudW1WYWx1ZU9wdGlvbnMgZ2V0T3B0aW9ucygpIHsgcmV0dXJuIHByb3RvLmdldE9wdGlvbnMoKTsgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgaW5kZXg7CisgICAgcHJpdmF0ZSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gcHJvdG87CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZnVsbE5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlOworICAgIHByaXZhdGUgZmluYWwgRW51bURlc2NyaXB0b3IgdHlwZTsKKworICAgIHByaXZhdGUgRW51bVZhbHVlRGVzY3JpcHRvcihmaW5hbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEVudW1EZXNjcmlwdG9yIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4KQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisgICAgICB0aGlzLmZpbGUgPSBmaWxlOworICAgICAgdHlwZSA9IHBhcmVudDsKKworICAgICAgZnVsbE5hbWUgPSBwYXJlbnQuZ2V0RnVsbE5hbWUoKSArICcuJyArIHByb3RvLmdldE5hbWUoKTsKKworICAgICAgZmlsZS5wb29sLmFkZFN5bWJvbCh0aGlzKTsKKyAgICAgIGZpbGUucG9vbC5hZGRFbnVtVmFsdWVCeU51bWJlcih0aGlzKTsKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSBJbnRlZ2VyIG51bWJlcjsKKyAgICAvLyBDcmVhdGUgYW4gdW5rbm93biBlbnVtIHZhbHVlLgorICAgIHByaXZhdGUgRW51bVZhbHVlRGVzY3JpcHRvcigKKyAgICAgICAgZmluYWwgRmlsZURlc2NyaXB0b3IgZmlsZSwKKyAgICAgICAgZmluYWwgRW51bURlc2NyaXB0b3IgcGFyZW50LAorICAgICAgICBmaW5hbCBJbnRlZ2VyIG51bWJlcikgeworICAgICAgU3RyaW5nIG5hbWUgPSAiVU5LTk9XTl9FTlVNX1ZBTFVFXyIgKyBwYXJlbnQuZ2V0TmFtZSgpICsgIl8iICsgbnVtYmVyOworICAgICAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHByb3RvID0gRW51bVZhbHVlRGVzY3JpcHRvclByb3RvCisgICAgICAgICAgLm5ld0J1aWxkZXIoKS5zZXROYW1lKG5hbWUpLnNldE51bWJlcihudW1iZXIpLmJ1aWxkKCk7CisgICAgICB0aGlzLmluZGV4ID0gLTE7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisgICAgICB0aGlzLmZpbGUgPSBmaWxlOworICAgICAgdGhpcy50eXBlID0gcGFyZW50OworICAgICAgdGhpcy5mdWxsTmFtZSA9IHBhcmVudC5nZXRGdWxsTmFtZSgpICsgJy4nICsgcHJvdG8uZ2V0TmFtZSgpOworICAgICAgdGhpcy5udW1iZXIgPSBudW1iZXI7CisgICAgICAKKyAgICAgIC8vIERvbid0IGFkZCB0aGlzIGRlc2NyaXB0b3IgaW50byBwb29sLgorICAgIH0KKworICAgIC8qKiBTZWUge0BsaW5rIEZpbGVEZXNjcmlwdG9yI3NldFByb3RvfS4gKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0UHJvdG8oZmluYWwgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHByb3RvKSB7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKiogRGVzY3JpYmVzIGEgc2VydmljZSB0eXBlLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFNlcnZpY2VEZXNjcmlwdG9yIGV4dGVuZHMgR2VuZXJpY0Rlc2NyaXB0b3IgeworICAgIC8qKgorICAgICAqIEdldCB0aGUgaW5kZXggb2YgdGhpcyBkZXNjcmlwdG9yIHdpdGhpbiBpdHMgcGFyZW50LgorICAgICAqICogQHNlZSBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yI2dldEluZGV4KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeyByZXR1cm4gaW5kZXg7IH0KKworICAgIC8qKiBDb252ZXJ0IHRoZSBkZXNjcmlwdG9yIHRvIGl0cyBwcm90b2NvbCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiAqLworICAgIHB1YmxpYyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvIHRvUHJvdG8oKSB7IHJldHVybiBwcm90bzsgfQorCisgICAgLyoqIEdldCB0aGUgdHlwZSdzIHVucXVhbGlmaWVkIG5hbWUuICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeyByZXR1cm4gcHJvdG8uZ2V0TmFtZSgpOyB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHR5cGUncyBmdWxseS1xdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAc2VlIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IjZ2V0RnVsbE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnVsbE5hbWUoKSB7IHJldHVybiBmdWxsTmFtZTsgfQorCisgICAgLyoqIEdldCB0aGUge0BsaW5rIEZpbGVEZXNjcmlwdG9yfSBjb250YWluaW5nIHRoaXMgZGVzY3JpcHRvci4gKi8KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RmlsZSgpIHsgcmV0dXJuIGZpbGU7IH0KKworICAgIC8qKiBHZXQgdGhlIHtAY29kZSBTZXJ2aWNlT3B0aW9uc30sIGRlZmluZWQgaW4ge0Bjb2RlIGRlc2NyaXB0b3IucHJvdG99LiAqLworICAgIHB1YmxpYyBTZXJ2aWNlT3B0aW9ucyBnZXRPcHRpb25zKCkgeyByZXR1cm4gcHJvdG8uZ2V0T3B0aW9ucygpOyB9CisKKyAgICAvKiogR2V0IGEgbGlzdCBvZiBtZXRob2RzIGZvciB0aGlzIHNlcnZpY2UuICovCisgICAgcHVibGljIExpc3Q8TWV0aG9kRGVzY3JpcHRvcj4gZ2V0TWV0aG9kcygpIHsKKyAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KEFycmF5cy5hc0xpc3QobWV0aG9kcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYSBtZXRob2QgYnkgbmFtZS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgbWV0aG9kIChlLmcuICJGb28iKS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtZXRob2QncyBkZXNjcmlwdG9yLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBNZXRob2REZXNjcmlwdG9yIGZpbmRNZXRob2RCeU5hbWUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIHJlc3VsdCA9CisgICAgICAgICAgZmlsZS5wb29sLmZpbmRTeW1ib2woZnVsbE5hbWUgKyAnLicgKyBuYW1lKTsKKyAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQgaW5zdGFuY2VvZiBNZXRob2REZXNjcmlwdG9yKSB7CisgICAgICAgIHJldHVybiAoTWV0aG9kRGVzY3JpcHRvcilyZXN1bHQ7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBpbmRleDsKKyAgICBwcml2YXRlIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gcHJvdG87CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZnVsbE5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlOworICAgIHByaXZhdGUgTWV0aG9kRGVzY3JpcHRvcltdIG1ldGhvZHM7CisKKyAgICBwcml2YXRlIFNlcnZpY2VEZXNjcmlwdG9yKGZpbmFsIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4KQorICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24geworICAgICAgdGhpcy5pbmRleCA9IGluZGV4OworICAgICAgdGhpcy5wcm90byA9IHByb3RvOworICAgICAgZnVsbE5hbWUgPSBjb21wdXRlRnVsbE5hbWUoZmlsZSwgbnVsbCwgcHJvdG8uZ2V0TmFtZSgpKTsKKyAgICAgIHRoaXMuZmlsZSA9IGZpbGU7CisKKyAgICAgIG1ldGhvZHMgPSBuZXcgTWV0aG9kRGVzY3JpcHRvcltwcm90by5nZXRNZXRob2RDb3VudCgpXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZ2V0TWV0aG9kQ291bnQoKTsgaSsrKSB7CisgICAgICAgIG1ldGhvZHNbaV0gPSBuZXcgTWV0aG9kRGVzY3JpcHRvcigKKyAgICAgICAgICBwcm90by5nZXRNZXRob2QoaSksIGZpbGUsIHRoaXMsIGkpOworICAgICAgfQorCisgICAgICBmaWxlLnBvb2wuYWRkU3ltYm9sKHRoaXMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjcm9zc0xpbmsoKSB0aHJvd3MgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24geworICAgICAgZm9yIChmaW5hbCBNZXRob2REZXNjcmlwdG9yIG1ldGhvZCA6IG1ldGhvZHMpIHsKKyAgICAgICAgbWV0aG9kLmNyb3NzTGluaygpOworICAgICAgfQorICAgIH0KKworICAgIC8qKiBTZWUge0BsaW5rIEZpbGVEZXNjcmlwdG9yI3NldFByb3RvfS4gKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0UHJvdG8oZmluYWwgU2VydmljZURlc2NyaXB0b3JQcm90byBwcm90bykgeworICAgICAgdGhpcy5wcm90byA9IHByb3RvOworCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgbWV0aG9kc1tpXS5zZXRQcm90byhwcm90by5nZXRNZXRob2QoaSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqCisgICAqIERlc2NyaWJlcyBvbmUgbWV0aG9kIHdpdGhpbiBhIHNlcnZpY2UgdHlwZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTWV0aG9kRGVzY3JpcHRvciBleHRlbmRzIEdlbmVyaWNEZXNjcmlwdG9yIHsKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGluZGV4IG9mIHRoaXMgZGVzY3JpcHRvciB3aXRoaW4gaXRzIHBhcmVudC4KKyAgICAgKiAqIEBzZWUgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciNnZXRJbmRleCgpCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsgcmV0dXJuIGluZGV4OyB9CisKKyAgICAvKiogQ29udmVydCB0aGUgZGVzY3JpcHRvciB0byBpdHMgcHJvdG9jb2wgbWVzc2FnZSByZXByZXNlbnRhdGlvbi4gKi8KKyAgICBwdWJsaWMgTWV0aG9kRGVzY3JpcHRvclByb3RvIHRvUHJvdG8oKSB7IHJldHVybiBwcm90bzsgfQorCisgICAgLyoqIEdldCB0aGUgbWV0aG9kJ3MgdW5xdWFsaWZpZWQgbmFtZS4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBwcm90by5nZXROYW1lKCk7IH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbWV0aG9kJ3MgZnVsbHktcXVhbGlmaWVkIG5hbWUuCisgICAgICogQHNlZSBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yI2dldEZ1bGxOYW1lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZ1bGxOYW1lKCkgeyByZXR1cm4gZnVsbE5hbWU7IH0KKworICAgIC8qKiBHZXQgdGhlIHtAbGluayBGaWxlRGVzY3JpcHRvcn0gY29udGFpbmluZyB0aGlzIGRlc2NyaXB0b3IuICovCisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZpbGUoKSB7IHJldHVybiBmaWxlOyB9CisKKyAgICAvKiogR2V0IHRoZSBtZXRob2QncyBzZXJ2aWNlIHR5cGUuICovCisgICAgcHVibGljIFNlcnZpY2VEZXNjcmlwdG9yIGdldFNlcnZpY2UoKSB7IHJldHVybiBzZXJ2aWNlOyB9CisKKyAgICAvKiogR2V0IHRoZSBtZXRob2QncyBpbnB1dCB0eXBlLiAqLworICAgIHB1YmxpYyBEZXNjcmlwdG9yIGdldElucHV0VHlwZSgpIHsgcmV0dXJuIGlucHV0VHlwZTsgfQorCisgICAgLyoqIEdldCB0aGUgbWV0aG9kJ3Mgb3V0cHV0IHR5cGUuICovCisgICAgcHVibGljIERlc2NyaXB0b3IgZ2V0T3V0cHV0VHlwZSgpIHsgcmV0dXJuIG91dHB1dFR5cGU7IH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUge0Bjb2RlIE1ldGhvZE9wdGlvbnN9LCBkZWZpbmVkIGluIHtAY29kZSBkZXNjcmlwdG9yLnByb3RvfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWV0aG9kT3B0aW9ucyBnZXRPcHRpb25zKCkgeyByZXR1cm4gcHJvdG8uZ2V0T3B0aW9ucygpOyB9CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBpbmRleDsKKyAgICBwcml2YXRlIE1ldGhvZERlc2NyaXB0b3JQcm90byBwcm90bzsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmdWxsTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGZpbGU7CisgICAgcHJpdmF0ZSBmaW5hbCBTZXJ2aWNlRGVzY3JpcHRvciBzZXJ2aWNlOworCisgICAgLy8gSW5pdGlhbGl6ZWQgZHVyaW5nIGNyb3NzLWxpbmtpbmcuCisgICAgcHJpdmF0ZSBEZXNjcmlwdG9yIGlucHV0VHlwZTsKKyAgICBwcml2YXRlIERlc2NyaXB0b3Igb3V0cHV0VHlwZTsKKworICAgIHByaXZhdGUgTWV0aG9kRGVzY3JpcHRvcihmaW5hbCBNZXRob2REZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFNlcnZpY2VEZXNjcmlwdG9yIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgICB0aGlzLnByb3RvID0gcHJvdG87CisgICAgICB0aGlzLmZpbGUgPSBmaWxlOworICAgICAgc2VydmljZSA9IHBhcmVudDsKKworICAgICAgZnVsbE5hbWUgPSBwYXJlbnQuZ2V0RnVsbE5hbWUoKSArICcuJyArIHByb3RvLmdldE5hbWUoKTsKKworICAgICAgZmlsZS5wb29sLmFkZFN5bWJvbCh0aGlzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3Jvc3NMaW5rKCkgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIGlucHV0ID0KKyAgICAgICAgZmlsZS5wb29sLmxvb2t1cFN5bWJvbChwcm90by5nZXRJbnB1dFR5cGUoKSwgdGhpcywKKyAgICAgICAgICAgIERlc2NyaXB0b3JQb29sLlNlYXJjaEZpbHRlci5UWVBFU19PTkxZKTsKKyAgICAgIGlmICghKGlucHV0IGluc3RhbmNlb2YgRGVzY3JpcHRvcikpIHsKKyAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAnXCInICsgcHJvdG8uZ2V0SW5wdXRUeXBlKCkgKyAiXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgICAgaW5wdXRUeXBlID0gKERlc2NyaXB0b3IpaW5wdXQ7CisKKyAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIG91dHB1dCA9CisgICAgICAgIGZpbGUucG9vbC5sb29rdXBTeW1ib2wocHJvdG8uZ2V0T3V0cHV0VHlwZSgpLCB0aGlzLAorICAgICAgICAgICAgRGVzY3JpcHRvclBvb2wuU2VhcmNoRmlsdGVyLlRZUEVTX09OTFkpOworICAgICAgaWYgKCEob3V0cHV0IGluc3RhbmNlb2YgRGVzY3JpcHRvcikpIHsKKyAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHRoaXMsCisgICAgICAgICAgICAnXCInICsgcHJvdG8uZ2V0T3V0cHV0VHlwZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgIH0KKyAgICAgIG91dHB1dFR5cGUgPSAoRGVzY3JpcHRvcilvdXRwdXQ7CisgICAgfQorCisgICAgLyoqIFNlZSB7QGxpbmsgRmlsZURlc2NyaXB0b3Ijc2V0UHJvdG99LiAqLworICAgIHByaXZhdGUgdm9pZCBzZXRQcm90byhmaW5hbCBNZXRob2REZXNjcmlwdG9yUHJvdG8gcHJvdG8pIHsKKyAgICAgIHRoaXMucHJvdG8gPSBwcm90bzsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjb21wdXRlRnVsbE5hbWUoZmluYWwgRmlsZURlc2NyaXB0b3IgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBEZXNjcmlwdG9yIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgeworICAgICAgcmV0dXJuIHBhcmVudC5nZXRGdWxsTmFtZSgpICsgJy4nICsgbmFtZTsKKyAgICB9IGVsc2UgaWYgKGZpbGUuZ2V0UGFja2FnZSgpLmxlbmd0aCgpID4gMCkgeworICAgICAgcmV0dXJuIGZpbGUuZ2V0UGFja2FnZSgpICsgJy4nICsgbmFtZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogQWxsIGRlc2NyaXB0b3JzIGltcGxlbWVudCB0aGlzIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGltcGxlbWVudCB0b29scyBsaWtlCisgICAqIHtAY29kZSBEZXNjcmlwdG9yUG9vbH0uPHA+CisgICAqCisgICAqIFRoaXMgY2xhc3MgaXMgcHVibGljIHNvIHRoYXQgdGhlIG1ldGhvZHMgaXQgZXhwb3NlcyBjYW4gYmUgY2FsbGVkIGZyb20KKyAgICogb3V0c2lkZSBvZiB0aGlzIHBhY2thZ2UuIEhvd2V2ZXIsIGl0IHNob3VsZCBvbmx5IGJlIHN1YmNsYXNzZWQgZnJvbQorICAgKiBuZXN0ZWQgY2xhc3NlcyBvZiBEZXNjcmlwdG9ycy4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgR2VuZXJpY0Rlc2NyaXB0b3IgeworICAgIHB1YmxpYyBhYnN0cmFjdCBNZXNzYWdlIHRvUHJvdG8oKTsKKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldE5hbWUoKTsKKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldEZ1bGxOYW1lKCk7CisgICAgcHVibGljIGFic3RyYWN0IEZpbGVEZXNjcmlwdG9yIGdldEZpbGUoKTsKKyAgfQorCisgIC8qKgorICAgKiBUaHJvd24gd2hlbiBidWlsZGluZyBkZXNjcmlwdG9ycyBmYWlscyBiZWNhdXNlIHRoZSBzb3VyY2UgRGVzY3JpcHRvclByb3RvcworICAgKiBhcmUgbm90IHZhbGlkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTc1MDIwNTc3NTQ5MDQ4MzE0OEw7CisKKyAgICAvKiogR2V0cyB0aGUgZnVsbCBuYW1lIG9mIHRoZSBkZXNjcmlwdG9yIHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb2JsZW1TeW1ib2xOYW1lKCkgeyByZXR1cm4gbmFtZTsgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJvdG9jb2wgbWVzc2FnZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW52YWxpZCBkZXNjcmlwdG9yLgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlIGdldFByb2JsZW1Qcm90bygpIHsgcmV0dXJuIHByb3RvOyB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB7IHJldHVybiBkZXNjcmlwdGlvbjsgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIE1lc3NhZ2UgcHJvdG87CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZGVzY3JpcHRpb247CisKKyAgICBwcml2YXRlIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKAorICAgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciBwcm9ibGVtRGVzY3JpcHRvciwKKyAgICAgICAgZmluYWwgU3RyaW5nIGRlc2NyaXB0aW9uKSB7CisgICAgICBzdXBlcihwcm9ibGVtRGVzY3JpcHRvci5nZXRGdWxsTmFtZSgpICsgIjogIiArIGRlc2NyaXB0aW9uKTsKKworICAgICAgLy8gTm90ZSB0aGF0IHByb2JsZW1EZXNjcmlwdG9yIG1heSBiZSBwYXJ0aWFsbHkgdW5pbml0aWFsaXplZCwgc28gd2UKKyAgICAgIC8vIGRvbid0IHdhbnQgdG8gZXhwb3NlIGl0IGRpcmVjdGx5IHRvIHRoZSB1c2VyLiAgU28sIHdlIG9ubHkgcHJvdmlkZQorICAgICAgLy8gdGhlIG5hbWUgYW5kIHRoZSBvcmlnaW5hbCBwcm90by4KKyAgICAgIG5hbWUgPSBwcm9ibGVtRGVzY3JpcHRvci5nZXRGdWxsTmFtZSgpOworICAgICAgcHJvdG8gPSBwcm9ibGVtRGVzY3JpcHRvci50b1Byb3RvKCk7CisgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CisgICAgfQorCisgICAgcHJpdmF0ZSBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgZmluYWwgR2VuZXJpY0Rlc2NyaXB0b3IgcHJvYmxlbURlc2NyaXB0b3IsCisgICAgICAgIGZpbmFsIFN0cmluZyBkZXNjcmlwdGlvbiwKKyAgICAgICAgZmluYWwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICB0aGlzKHByb2JsZW1EZXNjcmlwdG9yLCBkZXNjcmlwdGlvbik7CisgICAgICBpbml0Q2F1c2UoY2F1c2UpOworICAgIH0KKworICAgIHByaXZhdGUgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24oCisgICAgICAgIGZpbmFsIEZpbGVEZXNjcmlwdG9yIHByb2JsZW1EZXNjcmlwdG9yLAorICAgICAgICBmaW5hbCBTdHJpbmcgZGVzY3JpcHRpb24pIHsKKyAgICAgIHN1cGVyKHByb2JsZW1EZXNjcmlwdG9yLmdldE5hbWUoKSArICI6ICIgKyBkZXNjcmlwdGlvbik7CisKKyAgICAgIC8vIE5vdGUgdGhhdCBwcm9ibGVtRGVzY3JpcHRvciBtYXkgYmUgcGFydGlhbGx5IHVuaW5pdGlhbGl6ZWQsIHNvIHdlCisgICAgICAvLyBkb24ndCB3YW50IHRvIGV4cG9zZSBpdCBkaXJlY3RseSB0byB0aGUgdXNlci4gIFNvLCB3ZSBvbmx5IHByb3ZpZGUKKyAgICAgIC8vIHRoZSBuYW1lIGFuZCB0aGUgb3JpZ2luYWwgcHJvdG8uCisgICAgICBuYW1lID0gcHJvYmxlbURlc2NyaXB0b3IuZ2V0TmFtZSgpOworICAgICAgcHJvdG8gPSBwcm9ibGVtRGVzY3JpcHRvci50b1Byb3RvKCk7CisgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogQSBwcml2YXRlIGhlbHBlciBjbGFzcyB3aGljaCBjb250YWlucyBsb29rdXAgdGFibGVzIGNvbnRhaW5pbmcgYWxsIHRoZQorICAgKiBkZXNjcmlwdG9ycyBkZWZpbmVkIGluIGEgcGFydGljdWxhciBmaWxlLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRGVzY3JpcHRvclBvb2wgeworICAgIAorICAgIC8qKiBEZWZpbmVzIHdoYXQgc3ViY2xhc3Mgb2YgZGVzY3JpcHRvcnMgdG8gc2VhcmNoIGluIHRoZSBkZXNjcmlwdG9yIHBvb2wuIAorICAgICAqLworICAgIGVudW0gU2VhcmNoRmlsdGVyIHsKKyAgICAgIFRZUEVTX09OTFksIEFHR1JFR0FURVNfT05MWSwgQUxMX1NZTUJPTFMKKyAgICB9CisgICAgCisgICAgRGVzY3JpcHRvclBvb2woZmluYWwgRmlsZURlc2NyaXB0b3JbXSBkZXBlbmRlbmNpZXMsCisgICAgICAgIGJvb2xlYW4gYWxsb3dVbmtub3duRGVwZW5kZW5jaWVzKSB7CisgICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IG5ldyBIYXNoU2V0PEZpbGVEZXNjcmlwdG9yPigpOworICAgICAgdGhpcy5hbGxvd1Vua25vd25EZXBlbmRlbmNpZXMgPSBhbGxvd1Vua25vd25EZXBlbmRlbmNpZXM7CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLmFkZChkZXBlbmRlbmNpZXNbaV0pOworICAgICAgICBpbXBvcnRQdWJsaWNEZXBlbmRlbmNpZXMoZGVwZW5kZW5jaWVzW2ldKTsKKyAgICAgIH0KKworICAgICAgZm9yIChmaW5hbCBGaWxlRGVzY3JpcHRvciBkZXBlbmRlbmN5IDogdGhpcy5kZXBlbmRlbmNpZXMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBhZGRQYWNrYWdlKGRlcGVuZGVuY3kuZ2V0UGFja2FnZSgpLCBkZXBlbmRlbmN5KTsKKyAgICAgICAgfSBjYXRjaCAoRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIENhbid0IGhhcHBlbiwgYmVjYXVzZSBhZGRQYWNrYWdlKCkgb25seSBmYWlscyB3aGVuIHRoZSBuYW1lCisgICAgICAgICAgLy8gY29uZmxpY3RzIHdpdGggYSBub24tcGFja2FnZSwgYnV0IHdlIGhhdmUgbm90IHlldCBhZGRlZCBhbnkKKyAgICAgICAgICAvLyBub24tcGFja2FnZXMgYXQgdGhpcyBwb2ludC4KKyAgICAgICAgICBhc3NlcnQgZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogRmluZCBhbmQgcHV0IHB1YmxpYyBkZXBlbmRlbmNpZXMgb2YgdGhlIGZpbGUgaW50byBkZXBlbmRlbmNpZXMgc2V0LiovCisgICAgcHJpdmF0ZSB2b2lkIGltcG9ydFB1YmxpY0RlcGVuZGVuY2llcyhmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlKSB7CisgICAgICBmb3IgKEZpbGVEZXNjcmlwdG9yIGRlcGVuZGVuY3kgOiBmaWxlLmdldFB1YmxpY0RlcGVuZGVuY2llcygpKSB7CisgICAgICAgIGlmIChkZXBlbmRlbmNpZXMuYWRkKGRlcGVuZGVuY3kpKSB7CisgICAgICAgICAgaW1wb3J0UHVibGljRGVwZW5kZW5jaWVzKGRlcGVuZGVuY3kpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8RmlsZURlc2NyaXB0b3I+IGRlcGVuZGVuY2llczsKKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3dVbmtub3duRGVwZW5kZW5jaWVzOworCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBHZW5lcmljRGVzY3JpcHRvcj4gZGVzY3JpcHRvcnNCeU5hbWUgPQorICAgICAgbmV3IEhhc2hNYXA8U3RyaW5nLCBHZW5lcmljRGVzY3JpcHRvcj4oKTsKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxEZXNjcmlwdG9ySW50UGFpciwgRmllbGREZXNjcmlwdG9yPiBmaWVsZHNCeU51bWJlciA9CisgICAgICBuZXcgSGFzaE1hcDxEZXNjcmlwdG9ySW50UGFpciwgRmllbGREZXNjcmlwdG9yPigpOworICAgIHByaXZhdGUgZmluYWwgTWFwPERlc2NyaXB0b3JJbnRQYWlyLCBFbnVtVmFsdWVEZXNjcmlwdG9yPiBlbnVtVmFsdWVzQnlOdW1iZXIKKyAgICAgICAgPSBuZXcgSGFzaE1hcDxEZXNjcmlwdG9ySW50UGFpciwgRW51bVZhbHVlRGVzY3JpcHRvcj4oKTsKKworICAgIC8qKiBGaW5kIGEgZ2VuZXJpYyBkZXNjcmlwdG9yIGJ5IGZ1bGx5LXF1YWxpZmllZCBuYW1lLiAqLworICAgIEdlbmVyaWNEZXNjcmlwdG9yIGZpbmRTeW1ib2woZmluYWwgU3RyaW5nIGZ1bGxOYW1lKSB7CisgICAgICByZXR1cm4gZmluZFN5bWJvbChmdWxsTmFtZSwgU2VhcmNoRmlsdGVyLkFMTF9TWU1CT0xTKTsKKyAgICB9CisgICAgCisgICAgLyoqIEZpbmQgYSBkZXNjcmlwdG9yIGJ5IGZ1bGx5LXF1YWxpZmllZCBuYW1lIGFuZCBnaXZlbiBvcHRpb24gdG8gb25seSAKKyAgICAgKiBzZWFyY2ggdmFsaWQgZmllbGQgdHlwZSBkZXNjcmlwdG9ycy4gCisgICAgICovCisgICAgR2VuZXJpY0Rlc2NyaXB0b3IgZmluZFN5bWJvbChmaW5hbCBTdHJpbmcgZnVsbE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTZWFyY2hGaWx0ZXIgZmlsdGVyKSB7CisgICAgICBHZW5lcmljRGVzY3JpcHRvciByZXN1bHQgPSBkZXNjcmlwdG9yc0J5TmFtZS5nZXQoZnVsbE5hbWUpOworICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgIGlmICgoZmlsdGVyPT1TZWFyY2hGaWx0ZXIuQUxMX1NZTUJPTFMpIHx8CisgICAgICAgICAgICAoKGZpbHRlcj09U2VhcmNoRmlsdGVyLlRZUEVTX09OTFkpICYmIGlzVHlwZShyZXN1bHQpKSB8fAorICAgICAgICAgICAgKChmaWx0ZXI9PVNlYXJjaEZpbHRlci5BR0dSRUdBVEVTX09OTFkpICYmIGlzQWdncmVnYXRlKHJlc3VsdCkpKSB7CisgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBmb3IgKGZpbmFsIEZpbGVEZXNjcmlwdG9yIGRlcGVuZGVuY3kgOiBkZXBlbmRlbmNpZXMpIHsKKyAgICAgICAgcmVzdWx0ID0gZGVwZW5kZW5jeS5wb29sLmRlc2NyaXB0b3JzQnlOYW1lLmdldChmdWxsTmFtZSk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgIGlmICgoZmlsdGVyPT1TZWFyY2hGaWx0ZXIuQUxMX1NZTUJPTFMpIHx8CisgICAgICAgICAgICAgICgoZmlsdGVyPT1TZWFyY2hGaWx0ZXIuVFlQRVNfT05MWSkgJiYgaXNUeXBlKHJlc3VsdCkpIHx8CisgICAgICAgICAgICAgICgoZmlsdGVyPT1TZWFyY2hGaWx0ZXIuQUdHUkVHQVRFU19PTkxZKSAmJiBpc0FnZ3JlZ2F0ZShyZXN1bHQpKSkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqIENoZWNrcyBpZiB0aGUgZGVzY3JpcHRvciBpcyBhIHZhbGlkIHR5cGUgZm9yIGEgbWVzc2FnZSBmaWVsZC4gKi8KKyAgICBib29sZWFuIGlzVHlwZShHZW5lcmljRGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgICAgICByZXR1cm4gKGRlc2NyaXB0b3IgaW5zdGFuY2VvZiBEZXNjcmlwdG9yKSB8fCAKKyAgICAgICAgKGRlc2NyaXB0b3IgaW5zdGFuY2VvZiBFbnVtRGVzY3JpcHRvcik7CisgICAgfQorICAgIAorICAgIC8qKiBDaGVja3MgaWYgdGhlIGRlc2NyaXB0b3IgaXMgYSB2YWxpZCBuYW1lc3BhY2UgdHlwZS4gKi8KKyAgICBib29sZWFuIGlzQWdncmVnYXRlKEdlbmVyaWNEZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgICAgIHJldHVybiAoZGVzY3JpcHRvciBpbnN0YW5jZW9mIERlc2NyaXB0b3IpIHx8IAorICAgICAgICAoZGVzY3JpcHRvciBpbnN0YW5jZW9mIEVudW1EZXNjcmlwdG9yKSB8fCAKKyAgICAgICAgKGRlc2NyaXB0b3IgaW5zdGFuY2VvZiBQYWNrYWdlRGVzY3JpcHRvcikgfHwgCisgICAgICAgIChkZXNjcmlwdG9yIGluc3RhbmNlb2YgU2VydmljZURlc2NyaXB0b3IpOworICAgIH0KKyAgICAgICAKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGEgdHlwZSBkZXNjcmlwdG9yIGJ5IG5hbWUsIHJlbGF0aXZlIHRvIHNvbWUgb3RoZXIgZGVzY3JpcHRvci4KKyAgICAgKiBUaGUgbmFtZSBtYXkgYmUgZnVsbHktcXVhbGlmaWVkICh3aXRoIGEgbGVhZGluZyAnLicpLAorICAgICAqIHBhcnRpYWxseS1xdWFsaWZpZWQsIG9yIHVucXVhbGlmaWVkLiAgQysrLWxpa2UgbmFtZSBsb29rdXAgc2VtYW50aWNzCisgICAgICogYXJlIHVzZWQgdG8gc2VhcmNoIGZvciB0aGUgbWF0Y2hpbmcgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBHZW5lcmljRGVzY3JpcHRvciBsb29rdXBTeW1ib2woZmluYWwgU3RyaW5nIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIHJlbGF0aXZlVG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIERlc2NyaXB0b3JQb29sLlNlYXJjaEZpbHRlciBmaWx0ZXIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIC8vIFRPRE8oa2VudG9uKTogIFRoaXMgY291bGQgYmUgb3B0aW1pemVkIGluIGEgbnVtYmVyIG9mIHdheXMuCisKKyAgICAgIEdlbmVyaWNEZXNjcmlwdG9yIHJlc3VsdDsKKyAgICAgIFN0cmluZyBmdWxsbmFtZTsKKyAgICAgIGlmIChuYW1lLnN0YXJ0c1dpdGgoIi4iKSkgeworICAgICAgICAvLyBGdWxseS1xdWFsaWZpZWQgbmFtZS4KKyAgICAgICAgZnVsbG5hbWUgPSBuYW1lLnN1YnN0cmluZygxKTsKKyAgICAgICAgcmVzdWx0ID0gZmluZFN5bWJvbChmdWxsbmFtZSwgZmlsdGVyKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIElmICJuYW1lIiBpcyBhIGNvbXBvdW5kIGlkZW50aWZpZXIsIHdlIHdhbnQgdG8gc2VhcmNoIGZvciB0aGUKKyAgICAgICAgLy8gZmlyc3QgY29tcG9uZW50IG9mIGl0LCB0aGVuIHNlYXJjaCB3aXRoaW4gaXQgZm9yIHRoZSByZXN0LgorICAgICAgICAvLyBJZiBuYW1lIGlzIHNvbWV0aGluZyBsaWtlICJGb28uQmFyLmJheiIsIGFuZCBzeW1ib2xzIG5hbWVkICJGb28iIGFyZQorICAgICAgICAvLyBkZWZpbmVkIGluIG11bHRpcGxlIHBhcmVudCBzY29wZXMsIHdlIG9ubHkgd2FudCB0byBmaW5kICJCYXIuYmF6IiBpbgorICAgICAgICAvLyB0aGUgaW5uZXJtb3N0IG9uZS4gIEUuZy4sIHRoZSBmb2xsb3dpbmcgc2hvdWxkIHByb2R1Y2UgYW4gZXJyb3I6CisgICAgICAgIC8vICAgbWVzc2FnZSBCYXIgeyBtZXNzYWdlIEJheiB7fSB9CisgICAgICAgIC8vICAgbWVzc2FnZSBGb28geworICAgICAgICAvLyAgICAgbWVzc2FnZSBCYXIgeworICAgICAgICAvLyAgICAgfQorICAgICAgICAvLyAgICAgb3B0aW9uYWwgQmFyLkJheiBiYXogPSAxOworICAgICAgICAvLyAgIH0KKyAgICAgICAgLy8gU28sIHdlIGxvb2sgZm9yIGp1c3QgIkZvbyIgZmlyc3QsIHRoZW4gbG9vayBmb3IgIkJhci5iYXoiIHdpdGhpbiBpdAorICAgICAgICAvLyBpZiBmb3VuZC4KKyAgICAgICAgZmluYWwgaW50IGZpcnN0UGFydExlbmd0aCA9IG5hbWUuaW5kZXhPZignLicpOworICAgICAgICBmaW5hbCBTdHJpbmcgZmlyc3RQYXJ0OworICAgICAgICBpZiAoZmlyc3RQYXJ0TGVuZ3RoID09IC0xKSB7CisgICAgICAgICAgZmlyc3RQYXJ0ID0gbmFtZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBmaXJzdFBhcnQgPSBuYW1lLnN1YnN0cmluZygwLCBmaXJzdFBhcnRMZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gV2Ugd2lsbCBzZWFyY2ggZWFjaCBwYXJlbnQgc2NvcGUgb2YgInJlbGF0aXZlVG8iIGxvb2tpbmcgZm9yIHRoZQorICAgICAgICAvLyBzeW1ib2wuCisgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgc2NvcGVUb1RyeSA9CisgICAgICAgICAgICBuZXcgU3RyaW5nQnVpbGRlcihyZWxhdGl2ZVRvLmdldEZ1bGxOYW1lKCkpOworCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgLy8gQ2hvcCBvZmYgdGhlIGxhc3QgY29tcG9uZW50IG9mIHRoZSBzY29wZS4KKyAgICAgICAgICBmaW5hbCBpbnQgZG90cG9zID0gc2NvcGVUb1RyeS5sYXN0SW5kZXhPZigiLiIpOworICAgICAgICAgIGlmIChkb3Rwb3MgPT0gLTEpIHsKKyAgICAgICAgICAgIGZ1bGxuYW1lID0gbmFtZTsKKyAgICAgICAgICAgIHJlc3VsdCA9IGZpbmRTeW1ib2wobmFtZSwgZmlsdGVyKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzY29wZVRvVHJ5LnNldExlbmd0aChkb3Rwb3MgKyAxKTsKKworICAgICAgICAgICAgLy8gQXBwZW5kIGZpcnN0UGFydCBhbmQgdHJ5IHRvIGZpbmQKKyAgICAgICAgICAgIHNjb3BlVG9UcnkuYXBwZW5kKGZpcnN0UGFydCk7CisgICAgICAgICAgICByZXN1bHQgPSBmaW5kU3ltYm9sKHNjb3BlVG9UcnkudG9TdHJpbmcoKSwgCisgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2wuU2VhcmNoRmlsdGVyLkFHR1JFR0FURVNfT05MWSk7CisKKyAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICBpZiAoZmlyc3RQYXJ0TGVuZ3RoICE9IC0xKSB7CisgICAgICAgICAgICAgICAgLy8gV2Ugb25seSBmb3VuZCB0aGUgZmlyc3QgcGFydCBvZiB0aGUgc3ltYm9sLiAgTm93IGxvb2sgZm9yCisgICAgICAgICAgICAgICAgLy8gdGhlIHdob2xlIHRoaW5nLiAgSWYgdGhpcyBmYWlscywgd2UgKmRvbid0KiB3YW50IHRvIGtlZXAKKyAgICAgICAgICAgICAgICAvLyBzZWFyY2hpbmcgcGFyZW50IHNjb3Blcy4KKyAgICAgICAgICAgICAgICBzY29wZVRvVHJ5LnNldExlbmd0aChkb3Rwb3MgKyAxKTsKKyAgICAgICAgICAgICAgICBzY29wZVRvVHJ5LmFwcGVuZChuYW1lKTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBmaW5kU3ltYm9sKHNjb3BlVG9UcnkudG9TdHJpbmcoKSwgZmlsdGVyKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBmdWxsbmFtZSA9IHNjb3BlVG9UcnkudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIE5vdCBmb3VuZC4gIFJlbW92ZSB0aGUgbmFtZSBzbyB3ZSBjYW4gdHJ5IGFnYWluLgorICAgICAgICAgICAgc2NvcGVUb1RyeS5zZXRMZW5ndGgoZG90cG9zKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgIGlmIChhbGxvd1Vua25vd25EZXBlbmRlbmNpZXMgJiYgZmlsdGVyID09IFNlYXJjaEZpbHRlci5UWVBFU19PTkxZKSB7CisgICAgICAgICAgbG9nZ2VyLndhcm5pbmcoIlRoZSBkZXNjcmlwdG9yIGZvciBtZXNzYWdlIHR5cGUgXCIiICsgbmFtZSArCisgICAgICAgICAgICAgICJcIiBjYW4gbm90IGJlIGZvdW5kIGFuZCBhIHBsYWNlaG9sZGVyIGlzIGNyZWF0ZWQgZm9yIGl0Iik7CisgICAgICAgICAgLy8gV2UgY3JlYXRlIGEgZHVtbXkgbWVzc2FnZSBkZXNjcmlwdG9yIGhlcmUgcmVnYXJkbGVzcyBvZiB0aGUKKyAgICAgICAgICAvLyBleHBlY3RlZCB0eXBlLiBJZiB0aGUgdHlwZSBzaG91bGQgYmUgbWVzc2FnZSwgdGhpcyBkdW1teQorICAgICAgICAgIC8vIGRlc2NyaXB0b3Igd2lsbCB3b3JrIHdlbGwgYW5kIGlmIHRoZSB0eXBlIHNob3VsZCBiZSBlbnVtLCBhCisgICAgICAgICAgLy8gRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24gd2lsbCBiZSB0aHJvd24gbGF0dGVyLiBJbiBlaXRoZXIKKyAgICAgICAgICAvLyBjYXNlLCB0aGUgY29kZSB3b3JrcyBhcyBleHBlY3RlZDogd2UgYWxsb3cgdW5rbm93biBtZXNzYWdlIHR5cGVzCisgICAgICAgICAgLy8gYnV0IG5vdCB1bmtud29uIGVudW0gdHlwZXMuCisgICAgICAgICAgcmVzdWx0ID0gbmV3IERlc2NyaXB0b3IoZnVsbG5hbWUpOworICAgICAgICAgIC8vIEFkZCB0aGUgcGxhY2Vob2xkZXIgZmlsZSBhcyBhIGRlcGVuZGVuY3kgc28gd2UgY2FuIGZpbmQgdGhlCisgICAgICAgICAgLy8gcGxhY2Vob2xkZXIgc3ltYm9sIHdoZW4gcmVzb2x2aW5nIG90aGVyIHJlZmVyZW5jZXMuCisgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuYWRkKHJlc3VsdC5nZXRGaWxlKCkpOworICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGhyb3cgbmV3IERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uKHJlbGF0aXZlVG8sCisgICAgICAgICAgICAgICdcIicgKyBuYW1lICsgIlwiIGlzIG5vdCBkZWZpbmVkLiIpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBzeW1ib2wgdG8gdGhlIHN5bWJvbCB0YWJsZS4gIElmIGEgc3ltYm9sIHdpdGggdGhlIHNhbWUgbmFtZQorICAgICAqIGFscmVhZHkgZXhpc3RzLCB0aHJvd3MgYW4gZXJyb3IuCisgICAgICovCisgICAgdm9pZCBhZGRTeW1ib2woZmluYWwgR2VuZXJpY0Rlc2NyaXB0b3IgZGVzY3JpcHRvcikKKyAgICAgICAgICAgIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZVN5bWJvbE5hbWUoZGVzY3JpcHRvcik7CisKKyAgICAgIGZpbmFsIFN0cmluZyBmdWxsTmFtZSA9IGRlc2NyaXB0b3IuZ2V0RnVsbE5hbWUoKTsKKyAgICAgIGZpbmFsIGludCBkb3Rwb3MgPSBmdWxsTmFtZS5sYXN0SW5kZXhPZignLicpOworCisgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciBvbGQgPSBkZXNjcmlwdG9yc0J5TmFtZS5wdXQoZnVsbE5hbWUsIGRlc2NyaXB0b3IpOworICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgIGRlc2NyaXB0b3JzQnlOYW1lLnB1dChmdWxsTmFtZSwgb2xkKTsKKworICAgICAgICBpZiAoZGVzY3JpcHRvci5nZXRGaWxlKCkgPT0gb2xkLmdldEZpbGUoKSkgeworICAgICAgICAgIGlmIChkb3Rwb3MgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbihkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICdcIicgKyBmdWxsTmFtZSArICJcIiBpcyBhbHJlYWR5IGRlZmluZWQuIik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbihkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICdcIicgKyBmdWxsTmFtZS5zdWJzdHJpbmcoZG90cG9zICsgMSkgKworICAgICAgICAgICAgICAiXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluIFwiIiArCisgICAgICAgICAgICAgIGZ1bGxOYW1lLnN1YnN0cmluZygwLCBkb3Rwb3MpICsgIlwiLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24oZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgJ1wiJyArIGZ1bGxOYW1lICsgIlwiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiBmaWxlIFwiIiArCisgICAgICAgICAgICBvbGQuZ2V0RmlsZSgpLmdldE5hbWUoKSArICJcIi4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcHJlc2VudHMgYSBwYWNrYWdlIGluIHRoZSBzeW1ib2wgdGFibGUuICBXZSB1c2UgUGFja2FnZURlc2NyaXB0b3JzCisgICAgICoganVzdCBhcyBwbGFjZWhvbGRlcnMgc28gdGhhdCBzb21lb25lIGNhbm5vdCBkZWZpbmUsIHNheSwgYSBtZXNzYWdlIHR5cGUKKyAgICAgKiB0aGF0IGhhcyB0aGUgc2FtZSBuYW1lIGFzIGFuIGV4aXN0aW5nIHBhY2thZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUGFja2FnZURlc2NyaXB0b3IgZXh0ZW5kcyBHZW5lcmljRGVzY3JpcHRvciB7CisgICAgICBwdWJsaWMgTWVzc2FnZSB0b1Byb3RvKCkgICAgICAgIHsgcmV0dXJuIGZpbGUudG9Qcm90bygpOyB9CisgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSAgICAgICAgIHsgcmV0dXJuIG5hbWU7ICAgICAgICAgICB9CisgICAgICBwdWJsaWMgU3RyaW5nIGdldEZ1bGxOYW1lKCkgICAgIHsgcmV0dXJuIGZ1bGxOYW1lOyAgICAgICB9CisgICAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RmlsZSgpIHsgcmV0dXJuIGZpbGU7ICAgICAgICAgICB9CisKKyAgICAgIFBhY2thZ2VEZXNjcmlwdG9yKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBTdHJpbmcgZnVsbE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlKSB7CisgICAgICAgIHRoaXMuZmlsZSA9IGZpbGU7CisgICAgICAgIHRoaXMuZnVsbE5hbWUgPSBmdWxsTmFtZTsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKyAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZ1bGxOYW1lOworICAgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmaWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBwYWNrYWdlIHRvIHRoZSBzeW1ib2wgdGFibGVzLiAgSWYgYSBwYWNrYWdlIGJ5IHRoZSBzYW1lIG5hbWUKKyAgICAgKiBhbHJlYWR5IGV4aXN0cywgdGhhdCBpcyBmaW5lLCBidXQgaWYgc29tZSBvdGhlciBraW5kIG9mIHN5bWJvbCBleGlzdHMKKyAgICAgKiB1bmRlciB0aGUgc2FtZSBuYW1lLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLiAgSWYgdGhlIHBhY2thZ2UgaGFzCisgICAgICogbXVsdGlwbGUgY29tcG9uZW50cywgdGhpcyBhbHNvIGFkZHMgdGhlIHBhcmVudCBwYWNrYWdlKHMpLgorICAgICAqLworICAgIHZvaWQgYWRkUGFja2FnZShmaW5hbCBTdHJpbmcgZnVsbE5hbWUsIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGZpbGUpCisgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIGZpbmFsIGludCBkb3Rwb3MgPSBmdWxsTmFtZS5sYXN0SW5kZXhPZignLicpOworICAgICAgZmluYWwgU3RyaW5nIG5hbWU7CisgICAgICBpZiAoZG90cG9zID09IC0xKSB7CisgICAgICAgIG5hbWUgPSBmdWxsTmFtZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGFkZFBhY2thZ2UoZnVsbE5hbWUuc3Vic3RyaW5nKDAsIGRvdHBvcyksIGZpbGUpOworICAgICAgICBuYW1lID0gZnVsbE5hbWUuc3Vic3RyaW5nKGRvdHBvcyArIDEpOworICAgICAgfQorCisgICAgICBmaW5hbCBHZW5lcmljRGVzY3JpcHRvciBvbGQgPQorICAgICAgICBkZXNjcmlwdG9yc0J5TmFtZS5wdXQoZnVsbE5hbWUsCisgICAgICAgICAgbmV3IFBhY2thZ2VEZXNjcmlwdG9yKG5hbWUsIGZ1bGxOYW1lLCBmaWxlKSk7CisgICAgICBpZiAob2xkICE9IG51bGwpIHsKKyAgICAgICAgZGVzY3JpcHRvcnNCeU5hbWUucHV0KGZ1bGxOYW1lLCBvbGQpOworICAgICAgICBpZiAoIShvbGQgaW5zdGFuY2VvZiBQYWNrYWdlRGVzY3JpcHRvcikpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24oZmlsZSwKKyAgICAgICAgICAgICAgJ1wiJyArIG5hbWUgKyAiXCIgaXMgYWxyZWFkeSBkZWZpbmVkIChhcyBzb21ldGhpbmcgb3RoZXIgdGhhbiBhICIKKyAgICAgICAgICAgICAgKyAicGFja2FnZSkgaW4gZmlsZSBcIiIgKyBvbGQuZ2V0RmlsZSgpLmdldE5hbWUoKSArICJcIi4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8qKiBBIChHZW5lcmljRGVzY3JpcHRvciwgaW50KSBwYWlyLCB1c2VkIGFzIGEgbWFwIGtleS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBEZXNjcmlwdG9ySW50UGFpciB7CisgICAgICBwcml2YXRlIGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIGRlc2NyaXB0b3I7CisgICAgICBwcml2YXRlIGZpbmFsIGludCBudW1iZXI7CisKKyAgICAgIERlc2NyaXB0b3JJbnRQYWlyKGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIGRlc2NyaXB0b3IsIGZpbmFsIGludCBudW1iZXIpIHsKKyAgICAgICAgdGhpcy5kZXNjcmlwdG9yID0gZGVzY3JpcHRvcjsKKyAgICAgICAgdGhpcy5udW1iZXIgPSBudW1iZXI7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IuaGFzaENvZGUoKSAqICgoMSA8PCAxNikgLSAxKSArIG51bWJlcjsKKyAgICAgIH0KKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgRGVzY3JpcHRvckludFBhaXIpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZpbmFsIERlc2NyaXB0b3JJbnRQYWlyIG90aGVyID0gKERlc2NyaXB0b3JJbnRQYWlyKW9iajsKKyAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IgPT0gb3RoZXIuZGVzY3JpcHRvciAmJiBudW1iZXIgPT0gb3RoZXIubnVtYmVyOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBmaWVsZCB0byB0aGUgZmllbGRzQnlOdW1iZXIgdGFibGUuICBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIGEKKyAgICAgKiBmaWVsZCB3aXRoIHRoZSBzYW1lIGNvbnRhaW5pbmcgdHlwZSBhbmQgbnVtYmVyIGFscmVhZHkgZXhpc3RzLgorICAgICAqLworICAgIHZvaWQgYWRkRmllbGRCeU51bWJlcihmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpCisgICAgICAgICAgICAgICAgICAgdGhyb3dzIERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIGZpbmFsIERlc2NyaXB0b3JJbnRQYWlyIGtleSA9CisgICAgICAgIG5ldyBEZXNjcmlwdG9ySW50UGFpcihmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpLCBmaWVsZC5nZXROdW1iZXIoKSk7CisgICAgICBmaW5hbCBGaWVsZERlc2NyaXB0b3Igb2xkID0gZmllbGRzQnlOdW1iZXIucHV0KGtleSwgZmllbGQpOworICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgIGZpZWxkc0J5TnVtYmVyLnB1dChrZXksIG9sZCk7CisgICAgICAgIHRocm93IG5ldyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbihmaWVsZCwKKyAgICAgICAgICAiRmllbGQgbnVtYmVyICIgKyBmaWVsZC5nZXROdW1iZXIoKSArCisgICAgICAgICAgIiBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgaW4gXCIiICsKKyAgICAgICAgICBmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpLmdldEZ1bGxOYW1lKCkgKworICAgICAgICAgICJcIiBieSBmaWVsZCBcIiIgKyBvbGQuZ2V0TmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gZW51bSB2YWx1ZSB0byB0aGUgZW51bVZhbHVlc0J5TnVtYmVyIHRhYmxlLiAgSWYgYW4gZW51bSB2YWx1ZQorICAgICAqIHdpdGggdGhlIHNhbWUgdHlwZSBhbmQgbnVtYmVyIGFscmVhZHkgZXhpc3RzLCBkb2VzIG5vdGhpbmcuICAoVGhpcyBpcworICAgICAqIGFsbG93ZWQ7IHRoZSBmaXJzdCB2YWx1ZSBkZWZpbmUgd2l0aCB0aGUgbnVtYmVyIHRha2VzIHByZWNlZGVuY2UuKQorICAgICAqLworICAgIHZvaWQgYWRkRW51bVZhbHVlQnlOdW1iZXIoZmluYWwgRW51bVZhbHVlRGVzY3JpcHRvciB2YWx1ZSkgeworICAgICAgZmluYWwgRGVzY3JpcHRvckludFBhaXIga2V5ID0KKyAgICAgICAgbmV3IERlc2NyaXB0b3JJbnRQYWlyKHZhbHVlLmdldFR5cGUoKSwgdmFsdWUuZ2V0TnVtYmVyKCkpOworICAgICAgZmluYWwgRW51bVZhbHVlRGVzY3JpcHRvciBvbGQgPSBlbnVtVmFsdWVzQnlOdW1iZXIucHV0KGtleSwgdmFsdWUpOworICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgIGVudW1WYWx1ZXNCeU51bWJlci5wdXQoa2V5LCBvbGQpOworICAgICAgICAvLyBOb3QgYW4gZXJyb3I6ICBNdWx0aXBsZSBlbnVtIHZhbHVlcyBtYXkgaGF2ZSB0aGUgc2FtZSBudW1iZXIsIGJ1dAorICAgICAgICAvLyB3ZSBvbmx5IHdhbnQgdGhlIGZpcnN0IG9uZSBpbiB0aGUgbWFwLgorICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgdGhlIGRlc2NyaXB0b3IncyBuYW1lIGlzIHZhbGlkIChpLmUuIGl0IGNvbnRhaW5zIG9ubHkKKyAgICAgKiBsZXR0ZXJzLCBkaWdpdHMsIGFuZCB1bmRlcnNjb3JlcywgYW5kIGRvZXMgbm90IHN0YXJ0IHdpdGggYSBkaWdpdCkuCisgICAgICovCisgICAgc3RhdGljIHZvaWQgdmFsaWRhdGVTeW1ib2xOYW1lKGZpbmFsIEdlbmVyaWNEZXNjcmlwdG9yIGRlc2NyaXB0b3IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGRlc2NyaXB0b3IuZ2V0TmFtZSgpOworICAgICAgaWYgKG5hbWUubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24oZGVzY3JpcHRvciwgIk1pc3NpbmcgbmFtZS4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGJvb2xlYW4gdmFsaWQgPSB0cnVlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWUubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgIGZpbmFsIGNoYXIgYyA9IG5hbWUuY2hhckF0KGkpOworICAgICAgICAgIC8vIE5vbi1BU0NJSSBjaGFyYWN0ZXJzIGFyZSBub3QgdmFsaWQgaW4gcHJvdG9idWYgaWRlbnRpZmllcnMsIGV2ZW4KKyAgICAgICAgICAvLyBpZiB0aGV5IGFyZSBsZXR0ZXJzIG9yIGRpZ2l0cy4KKyAgICAgICAgICBpZiAoYyA+PSAxMjgpIHsKKyAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIC8vIEZpcnN0IGNoYXJhY3RlciBtdXN0IGJlIGxldHRlciBvciBfLiAgU3Vic2VxdWVudCBjaGFyYWN0ZXJzIG1heQorICAgICAgICAgIC8vIGJlIGxldHRlcnMsIG51bWJlcnMsIG9yIGRpZ2l0cy4KKyAgICAgICAgICBpZiAoQ2hhcmFjdGVyLmlzTGV0dGVyKGMpIHx8IGMgPT0gJ18nIHx8CisgICAgICAgICAgICAgIChDaGFyYWN0ZXIuaXNEaWdpdChjKSAmJiBpID4gMCkpIHsKKyAgICAgICAgICAgIC8vIFZhbGlkCisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICghdmFsaWQpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24oZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgJ1wiJyArIG5hbWUgKyAiXCIgaXMgbm90IGEgdmFsaWQgaWRlbnRpZmllci4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKiBEZXNjcmliZXMgYW4gb25lb2Ygb2YgYSBtZXNzYWdlIHR5cGUuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT25lb2ZEZXNjcmlwdG9yIHsKKyAgICAvKiogR2V0IHRoZSBpbmRleCBvZiB0aGlzIGRlc2NyaXB0b3Igd2l0aGluIGl0cyBwYXJlbnQuICovCisgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsgcmV0dXJuIGluZGV4OyB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBwcm90by5nZXROYW1lKCk7IH0KKworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGaWxlKCkgeyByZXR1cm4gZmlsZTsgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRGdWxsTmFtZSgpIHsgcmV0dXJuIGZ1bGxOYW1lOyB9CisKKyAgICBwdWJsaWMgRGVzY3JpcHRvciBnZXRDb250YWluaW5nVHlwZSgpIHsgcmV0dXJuIGNvbnRhaW5pbmdUeXBlOyB9CisKKyAgICBwdWJsaWMgaW50IGdldEZpZWxkQ291bnQoKSB7IHJldHVybiBmaWVsZENvdW50OyB9CisKKyAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldEZpZWxkKGludCBpbmRleCkgeworICAgICAgcmV0dXJuIGZpZWxkc1tpbmRleF07CisgICAgfQorCisgICAgcHJpdmF0ZSBPbmVvZkRlc2NyaXB0b3IoZmluYWwgT25lb2ZEZXNjcmlwdG9yUHJvdG8gcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRmlsZURlc2NyaXB0b3IgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBEZXNjcmlwdG9yIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpCisgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24geworICAgICAgdGhpcy5wcm90byA9IHByb3RvOworICAgICAgZnVsbE5hbWUgPSBjb21wdXRlRnVsbE5hbWUoZmlsZSwgcGFyZW50LCBwcm90by5nZXROYW1lKCkpOworICAgICAgdGhpcy5maWxlID0gZmlsZTsKKyAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKKworICAgICAgY29udGFpbmluZ1R5cGUgPSBwYXJlbnQ7CisgICAgICBmaWVsZENvdW50ID0gMDsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBpbmRleDsKKyAgICBwcml2YXRlIE9uZW9mRGVzY3JpcHRvclByb3RvIHByb3RvOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZ1bGxOYW1lOworICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3IgZmlsZTsKKworICAgIHByaXZhdGUgRGVzY3JpcHRvciBjb250YWluaW5nVHlwZTsKKyAgICBwcml2YXRlIGludCBmaWVsZENvdW50OworICAgIHByaXZhdGUgRmllbGREZXNjcmlwdG9yW10gZmllbGRzOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EeW5hbWljTWVzc2FnZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRHluYW1pY01lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWExYjY4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRHluYW1pY01lc3NhZ2UuamF2YQpAQCAtMCwwICsxLDY0NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3I7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIE1lc3NhZ2V9IHRoYXQgY2FuIHJlcHJlc2VudCBhcmJpdHJhcnkgdHlwZXMsCisgKiBnaXZlbiBhIHtAbGluayBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yfS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRHluYW1pY01lc3NhZ2UgZXh0ZW5kcyBBYnN0cmFjdE1lc3NhZ2UgeworICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3IgdHlwZTsKKyAgcHJpdmF0ZSBmaW5hbCBGaWVsZFNldDxGaWVsZERlc2NyaXB0b3I+IGZpZWxkczsKKyAgcHJpdmF0ZSBmaW5hbCBGaWVsZERlc2NyaXB0b3JbXSBvbmVvZkNhc2VzOworICBwcml2YXRlIGZpbmFsIFVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzOworICBwcml2YXRlIGludCBtZW1vaXplZFNpemUgPSAtMTsKKworICAvKioKKyAgICogQ29uc3RydWN0IGEge0Bjb2RlIER5bmFtaWNNZXNzYWdlfSB1c2luZyB0aGUgZ2l2ZW4ge0Bjb2RlIEZpZWxkU2V0fS4KKyAgICogb25lb2ZDYXNlcyBzdG9yZXMgdGhlIEZpZWxkRGVzY3JpcHRvciBmb3IgZWFjaCBvbmVvZiB0byBpbmRpY2F0ZQorICAgKiB3aGljaCBmaWVsZCBpcyBzZXQuIENhbGxlciBzaG91bGQgbWFrZSBzdXJlIHRoZSBhcnJheSBpcyBpbW11dGFibGUuCisgICAqCisgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgcGFja2FnZSBwcml2YXRlIGFuZCB3aWxsIGJlIHVzZWQgaW4KKyAgICoge0Bjb2RlIER5bmFtaWNNdXRhYmxlTWVzc2FnZX0gdG8gY29udmVydCBhIG11dGFibGUgbWVzc2FnZSB0byBhbiBpbW11dGFibGUKKyAgICogbWVzc2FnZS4KKyAgICovCisgIER5bmFtaWNNZXNzYWdlKERlc2NyaXB0b3IgdHlwZSwgRmllbGRTZXQ8RmllbGREZXNjcmlwdG9yPiBmaWVsZHMsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcltdIG9uZW9mQ2FzZXMsCisgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CisgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICB0aGlzLmZpZWxkcyA9IGZpZWxkczsKKyAgICB0aGlzLm9uZW9mQ2FzZXMgPSBvbmVvZkNhc2VzOworICAgIHRoaXMudW5rbm93bkZpZWxkcyA9IHVua25vd25GaWVsZHM7CisgIH0KKworICAvKioKKyAgICogR2V0IGEge0Bjb2RlIER5bmFtaWNNZXNzYWdlfSByZXByZXNlbnRpbmcgdGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhlCisgICAqIGdpdmVuIHR5cGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIER5bmFtaWNNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZShEZXNjcmlwdG9yIHR5cGUpIHsKKyAgICBpbnQgb25lb2ZEZWNsQ291bnQgPSB0eXBlLnRvUHJvdG8oKS5nZXRPbmVvZkRlY2xDb3VudCgpOworICAgIEZpZWxkRGVzY3JpcHRvcltdIG9uZW9mQ2FzZXMgPSBuZXcgRmllbGREZXNjcmlwdG9yW29uZW9mRGVjbENvdW50XTsKKyAgICByZXR1cm4gbmV3IER5bmFtaWNNZXNzYWdlKHR5cGUsIEZpZWxkU2V0LjxGaWVsZERlc2NyaXB0b3I+ZW1wdHlTZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZW9mQ2FzZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICB9CisKKworICAvKiogUGFyc2UgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiB0eXBlIGZyb20gdGhlIGdpdmVuIGlucHV0IHN0cmVhbS4gKi8KKyAgcHVibGljIHN0YXRpYyBEeW5hbWljTWVzc2FnZSBwYXJzZUZyb20oRGVzY3JpcHRvciB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBuZXdCdWlsZGVyKHR5cGUpLm1lcmdlRnJvbShpbnB1dCkuYnVpbGRQYXJzZWQoKTsKKyAgfQorCisgIC8qKiBQYXJzZSBhIG1lc3NhZ2Ugb2YgdGhlIGdpdmVuIHR5cGUgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtLiAqLworICBwdWJsaWMgc3RhdGljIER5bmFtaWNNZXNzYWdlIHBhcnNlRnJvbSgKKyAgICAgIERlc2NyaXB0b3IgdHlwZSwKKyAgICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIodHlwZSkubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSkuYnVpbGRQYXJzZWQoKTsKKyAgfQorCisgIC8qKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiB0eXBlIGFuZCByZXR1cm4gaXQuICovCisgIHB1YmxpYyBzdGF0aWMgRHluYW1pY01lc3NhZ2UgcGFyc2VGcm9tKERlc2NyaXB0b3IgdHlwZSwgQnl0ZVN0cmluZyBkYXRhKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3QnVpbGRlcih0eXBlKS5tZXJnZUZyb20oZGF0YSkuYnVpbGRQYXJzZWQoKTsKKyAgfQorCisgIC8qKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiB0eXBlIGFuZCByZXR1cm4gaXQuICovCisgIHB1YmxpYyBzdGF0aWMgRHluYW1pY01lc3NhZ2UgcGFyc2VGcm9tKERlc2NyaXB0b3IgdHlwZSwgQnl0ZVN0cmluZyBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIodHlwZSkubWVyZ2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KS5idWlsZFBhcnNlZCgpOworICB9CisKKyAgLyoqIFBhcnNlIHtAY29kZSBkYXRhfSBhcyBhIG1lc3NhZ2Ugb2YgdGhlIGdpdmVuIHR5cGUgYW5kIHJldHVybiBpdC4gKi8KKyAgcHVibGljIHN0YXRpYyBEeW5hbWljTWVzc2FnZSBwYXJzZUZyb20oRGVzY3JpcHRvciB0eXBlLCBieXRlW10gZGF0YSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIodHlwZSkubWVyZ2VGcm9tKGRhdGEpLmJ1aWxkUGFyc2VkKCk7CisgIH0KKworICAvKiogUGFyc2Uge0Bjb2RlIGRhdGF9IGFzIGEgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gdHlwZSBhbmQgcmV0dXJuIGl0LiAqLworICBwdWJsaWMgc3RhdGljIER5bmFtaWNNZXNzYWdlIHBhcnNlRnJvbShEZXNjcmlwdG9yIHR5cGUsIGJ5dGVbXSBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIodHlwZSkubWVyZ2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KS5idWlsZFBhcnNlZCgpOworICB9CisKKyAgLyoqIFBhcnNlIGEgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gdHlwZSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIHJldHVybiBpdC4gKi8KKyAgcHVibGljIHN0YXRpYyBEeW5hbWljTWVzc2FnZSBwYXJzZUZyb20oRGVzY3JpcHRvciB0eXBlLCBJbnB1dFN0cmVhbSBpbnB1dCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3QnVpbGRlcih0eXBlKS5tZXJnZUZyb20oaW5wdXQpLmJ1aWxkUGFyc2VkKCk7CisgIH0KKworICAvKiogUGFyc2UgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiB0eXBlIGZyb20ge0Bjb2RlIGlucHV0fSBhbmQgcmV0dXJuIGl0LiAqLworICBwdWJsaWMgc3RhdGljIER5bmFtaWNNZXNzYWdlIHBhcnNlRnJvbShEZXNjcmlwdG9yIHR5cGUsIElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3QnVpbGRlcih0eXBlKS5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KS5idWlsZFBhcnNlZCgpOworICB9CisKKyAgLyoqIENvbnN0cnVjdCBhIHtAbGluayBNZXNzYWdlLkJ1aWxkZXJ9IGZvciB0aGUgZ2l2ZW4gdHlwZS4gKi8KKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoRGVzY3JpcHRvciB0eXBlKSB7CisgICAgcmV0dXJuIG5ldyBCdWlsZGVyKHR5cGUpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIHtAbGluayBNZXNzYWdlLkJ1aWxkZXJ9IGZvciBhIG1lc3NhZ2Ugb2YgdGhlIHNhbWUgdHlwZSBhcworICAgKiB7QGNvZGUgcHJvdG90eXBlfSwgYW5kIGluaXRpYWxpemUgaXQgd2l0aCB7QGNvZGUgcHJvdG90eXBlfSdzIGNvbnRlbnRzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoTWVzc2FnZSBwcm90b3R5cGUpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXIocHJvdG90eXBlLmdldERlc2NyaXB0b3JGb3JUeXBlKCkpLm1lcmdlRnJvbShwcm90b3R5cGUpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSW1wbGVtZW50YXRpb24gb2YgTWVzc2FnZSBpbnRlcmZhY2UuCisKKyAgcHVibGljIERlc2NyaXB0b3IgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CisgICAgcmV0dXJuIHR5cGU7CisgIH0KKworICBwdWJsaWMgRHluYW1pY01lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gZ2V0RGVmYXVsdEluc3RhbmNlKHR5cGUpOworICB9CisKKyAgcHVibGljIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZ2V0QWxsRmllbGRzKCkgeworICAgIHJldHVybiBmaWVsZHMuZ2V0QWxsRmllbGRzKCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZihPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICB2ZXJpZnlPbmVvZkNvbnRhaW5pbmdUeXBlKG9uZW9mKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgZmllbGQgPSBvbmVvZkNhc2VzW29uZW9mLmdldEluZGV4KCldOworICAgIGlmIChmaWVsZCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgcHVibGljIEZpZWxkRGVzY3JpcHRvciBnZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICB2ZXJpZnlPbmVvZkNvbnRhaW5pbmdUeXBlKG9uZW9mKTsKKyAgICByZXR1cm4gb25lb2ZDYXNlc1tvbmVvZi5nZXRJbmRleCgpXTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICByZXR1cm4gZmllbGRzLmhhc0ZpZWxkKGZpZWxkKTsKKyAgfQorCisgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmllbGQpOworICAgIE9iamVjdCByZXN1bHQgPSBmaWVsZHMuZ2V0RmllbGQoZmllbGQpOworICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgaWYgKGZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICByZXN1bHQgPSBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKKyAgICAgIH0gZWxzZSBpZiAoZmllbGQuZ2V0SmF2YVR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICByZXN1bHQgPSBnZXREZWZhdWx0SW5zdGFuY2UoZmllbGQuZ2V0TWVzc2FnZVR5cGUoKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgPSBmaWVsZC5nZXREZWZhdWx0VmFsdWUoKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaWVsZENvdW50KEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICByZXR1cm4gZmllbGRzLmdldFJlcGVhdGVkRmllbGRDb3VudChmaWVsZCk7CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkRmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkLCBpbnQgaW5kZXgpIHsKKyAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgcmV0dXJuIGZpZWxkcy5nZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCk7CisgIH0KKworICBwdWJsaWMgVW5rbm93bkZpZWxkU2V0IGdldFVua25vd25GaWVsZHMoKSB7CisgICAgcmV0dXJuIHVua25vd25GaWVsZHM7CisgIH0KKworICBzdGF0aWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKERlc2NyaXB0b3IgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZFNldDxGaWVsZERlc2NyaXB0b3I+IGZpZWxkcykgeworICAgIC8vIENoZWNrIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudC4KKyAgICBmb3IgKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA6IHR5cGUuZ2V0RmllbGRzKCkpIHsKKyAgICAgIGlmIChmaWVsZC5pc1JlcXVpcmVkKCkpIHsKKyAgICAgICAgaWYgKCFmaWVsZHMuaGFzRmllbGQoZmllbGQpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gQ2hlY2sgdGhhdCBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgaW5pdGlhbGl6ZWQuCisgICAgcmV0dXJuIGZpZWxkcy5pc0luaXRpYWxpemVkKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICByZXR1cm4gaXNJbml0aWFsaXplZCh0eXBlLCBmaWVsZHMpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0eXBlLmdldE9wdGlvbnMoKS5nZXRNZXNzYWdlU2V0V2lyZUZvcm1hdCgpKSB7CisgICAgICBmaWVsZHMud3JpdGVNZXNzYWdlU2V0VG8ob3V0cHV0KTsKKyAgICAgIHVua25vd25GaWVsZHMud3JpdGVBc01lc3NhZ2VTZXRUbyhvdXRwdXQpOworICAgIH0gZWxzZSB7CisgICAgICBmaWVsZHMud3JpdGVUbyhvdXRwdXQpOworICAgICAgdW5rbm93bkZpZWxkcy53cml0ZVRvKG91dHB1dCk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CisgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CisgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOworCisgICAgaWYgKHR5cGUuZ2V0T3B0aW9ucygpLmdldE1lc3NhZ2VTZXRXaXJlRm9ybWF0KCkpIHsKKyAgICAgIHNpemUgPSBmaWVsZHMuZ2V0TWVzc2FnZVNldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgICBzaXplICs9IHVua25vd25GaWVsZHMuZ2V0U2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXQoKTsKKyAgICB9IGVsc2UgeworICAgICAgc2l6ZSA9IGZpZWxkcy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgICAgc2l6ZSArPSB1bmtub3duRmllbGRzLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgfQorCisgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcih0eXBlKTsKKyAgfQorCisgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3QnVpbGRlckZvclR5cGUoKS5tZXJnZUZyb20odGhpcyk7CisgIH0KKworICBwdWJsaWMgUGFyc2VyPER5bmFtaWNNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgeworICAgIHJldHVybiBuZXcgQWJzdHJhY3RQYXJzZXI8RHluYW1pY01lc3NhZ2U+KCkgeworICAgICAgcHVibGljIER5bmFtaWNNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCisgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIodHlwZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSkKKyAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgICAgfQorICAgIH07CisgIH0KKworICAvKiogVmVyaWZpZXMgdGhhdCB0aGUgZmllbGQgaXMgYSBmaWVsZCBvZiB0aGlzIG1lc3NhZ2UuICovCisgIHByaXZhdGUgdm9pZCB2ZXJpZnlDb250YWluaW5nVHlwZShGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICBpZiAoZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSB0eXBlKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAiRmllbGREZXNjcmlwdG9yIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICB9CisgIH0KKworICAvKiogVmVyaWZpZXMgdGhhdCB0aGUgb25lb2YgaXMgYW4gb25lb2Ygb2YgdGhpcyBtZXNzYWdlLiAqLworICBwcml2YXRlIHZvaWQgdmVyaWZ5T25lb2ZDb250YWluaW5nVHlwZShPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICBpZiAob25lb2YuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSB0eXBlKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAiT25lb2ZEZXNjcmlwdG9yIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8qKgorICAgKiBCdWlsZGVyIGZvciB7QGxpbmsgRHluYW1pY01lc3NhZ2V9cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzIEFic3RyYWN0TWVzc2FnZS5CdWlsZGVyPEJ1aWxkZXI+IHsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3IgdHlwZTsKKyAgICBwcml2YXRlIEZpZWxkU2V0PEZpZWxkRGVzY3JpcHRvcj4gZmllbGRzOworICAgIHByaXZhdGUgZmluYWwgRmllbGREZXNjcmlwdG9yW10gb25lb2ZDYXNlczsKKyAgICBwcml2YXRlIFVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzOworCisgICAgLyoqIENvbnN0cnVjdCBhIHtAY29kZSBCdWlsZGVyfSBmb3IgdGhlIGdpdmVuIHR5cGUuICovCisgICAgcHJpdmF0ZSBCdWlsZGVyKERlc2NyaXB0b3IgdHlwZSkgeworICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgIHRoaXMuZmllbGRzID0gRmllbGRTZXQubmV3RmllbGRTZXQoKTsKKyAgICAgIHRoaXMudW5rbm93bkZpZWxkcyA9IFVua25vd25GaWVsZFNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICAgIHRoaXMub25lb2ZDYXNlcyA9IG5ldyBGaWVsZERlc2NyaXB0b3JbdHlwZS50b1Byb3RvKCkuZ2V0T25lb2ZEZWNsQ291bnQoKV07CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gSW1wbGVtZW50YXRpb24gb2YgTWVzc2FnZS5CdWlsZGVyIGludGVyZmFjZS4KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgeworICAgICAgaWYgKGZpZWxkcy5pc0ltbXV0YWJsZSgpKSB7CisgICAgICAgIGZpZWxkcyA9IEZpZWxkU2V0Lm5ld0ZpZWxkU2V0KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBmaWVsZHMuY2xlYXIoKTsKKyAgICAgIH0KKyAgICAgIHVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oTWVzc2FnZSBvdGhlcikgeworICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgRHluYW1pY01lc3NhZ2UpIHsKKyAgICAgICAgLy8gVGhpcyBzaG91bGQgYmUgc29tZXdoYXQgZmFzdGVyIHRoYW4gY2FsbGluZyBzdXBlci5tZXJnZUZyb20oKS4KKyAgICAgICAgRHluYW1pY01lc3NhZ2Ugb3RoZXJEeW5hbWljTWVzc2FnZSA9IChEeW5hbWljTWVzc2FnZSkgb3RoZXI7CisgICAgICAgIGlmIChvdGhlckR5bmFtaWNNZXNzYWdlLnR5cGUgIT0gdHlwZSkgeworICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAibWVyZ2VGcm9tKE1lc3NhZ2UpIGNhbiBvbmx5IG1lcmdlIG1lc3NhZ2VzIG9mIHRoZSBzYW1lIHR5cGUuIik7CisgICAgICAgIH0KKyAgICAgICAgZW5zdXJlSXNNdXRhYmxlKCk7CisgICAgICAgIGZpZWxkcy5tZXJnZUZyb20ob3RoZXJEeW5hbWljTWVzc2FnZS5maWVsZHMpOworICAgICAgICBtZXJnZVVua25vd25GaWVsZHMob3RoZXJEeW5hbWljTWVzc2FnZS51bmtub3duRmllbGRzKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvbmVvZkNhc2VzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgaWYgKG9uZW9mQ2FzZXNbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgb25lb2ZDYXNlc1tpXSA9IG90aGVyRHluYW1pY01lc3NhZ2Uub25lb2ZDYXNlc1tpXTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKChvdGhlckR5bmFtaWNNZXNzYWdlLm9uZW9mQ2FzZXNbaV0gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAmJiAob25lb2ZDYXNlc1tpXSAhPSBvdGhlckR5bmFtaWNNZXNzYWdlLm9uZW9mQ2FzZXNbaV0pKSB7CisgICAgICAgICAgICAgIGZpZWxkcy5jbGVhckZpZWxkKG9uZW9mQ2FzZXNbaV0pOworICAgICAgICAgICAgICBvbmVvZkNhc2VzW2ldID0gb3RoZXJEeW5hbWljTWVzc2FnZS5vbmVvZkNhc2VzW2ldOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzdXBlci5tZXJnZUZyb20ob3RoZXIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBEeW5hbWljTWVzc2FnZSBidWlsZCgpIHsKKyAgICAgIGlmICghaXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKAorICAgICAgICAgIG5ldyBEeW5hbWljTWVzc2FnZSh0eXBlLCBmaWVsZHMsCisgICAgICAgICAgICAgIGphdmEudXRpbC5BcnJheXMuY29weU9mKG9uZW9mQ2FzZXMsIG9uZW9mQ2FzZXMubGVuZ3RoKSwgdW5rbm93bkZpZWxkcykpOworICAgICAgfQorICAgICAgcmV0dXJuIGJ1aWxkUGFydGlhbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBmb3IgRHluYW1pY01lc3NhZ2UucGFyc2VGcm9tKCkgbWV0aG9kcyB0byBjYWxsLiAgVGhyb3dzCisgICAgICoge0BsaW5rIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbn0gaW5zdGVhZCBvZgorICAgICAqIHtAbGluayBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHJpdmF0ZSBEeW5hbWljTWVzc2FnZSBidWlsZFBhcnNlZCgpIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgaWYgKCFpc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24oCisgICAgICAgICAgbmV3IER5bmFtaWNNZXNzYWdlKHR5cGUsIGZpZWxkcywKKyAgICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5jb3B5T2Yob25lb2ZDYXNlcywgb25lb2ZDYXNlcy5sZW5ndGgpLCB1bmtub3duRmllbGRzKSkKKyAgICAgICAgICAuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBidWlsZFBhcnRpYWwoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRHluYW1pY01lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgeworICAgICAgZmllbGRzLm1ha2VJbW11dGFibGUoKTsKKyAgICAgIER5bmFtaWNNZXNzYWdlIHJlc3VsdCA9CisgICAgICAgIG5ldyBEeW5hbWljTWVzc2FnZSh0eXBlLCBmaWVsZHMsCisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLmNvcHlPZihvbmVvZkNhc2VzLCBvbmVvZkNhc2VzLmxlbmd0aCksIHVua25vd25GaWVsZHMpOworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKKyAgICAgIEJ1aWxkZXIgcmVzdWx0ID0gbmV3IEJ1aWxkZXIodHlwZSk7CisgICAgICByZXN1bHQuZmllbGRzLm1lcmdlRnJvbShmaWVsZHMpOworICAgICAgcmVzdWx0Lm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkob25lb2ZDYXNlcywgMCwgcmVzdWx0Lm9uZW9mQ2FzZXMsIDAgLCBvbmVvZkNhc2VzLmxlbmd0aCk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CisgICAgICByZXR1cm4gRHluYW1pY01lc3NhZ2UuaXNJbml0aWFsaXplZCh0eXBlLCBmaWVsZHMpOworICAgIH0KKworICAgIHB1YmxpYyBEZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgcHVibGljIER5bmFtaWNNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CisgICAgICByZXR1cm4gZ2V0RGVmYXVsdEluc3RhbmNlKHR5cGUpOworICAgIH0KKworICAgIHB1YmxpYyBNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGdldEFsbEZpZWxkcygpIHsKKyAgICAgIHJldHVybiBmaWVsZHMuZ2V0QWxsRmllbGRzKCk7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvckZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmllbGQpOworCisgICAgICBpZiAoZmllbGQuZ2V0SmF2YVR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJuZXdCdWlsZGVyRm9yRmllbGQgaXMgb25seSB2YWxpZCBmb3IgZmllbGRzIHdpdGggbWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorCisgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIoZmllbGQuZ2V0TWVzc2FnZVR5cGUoKSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2YoT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CisgICAgICB2ZXJpZnlPbmVvZkNvbnRhaW5pbmdUeXBlKG9uZW9mKTsKKyAgICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IG9uZW9mQ2FzZXNbb25lb2YuZ2V0SW5kZXgoKV07CisgICAgICBpZiAoZmllbGQgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldE9uZW9mRmllbGREZXNjcmlwdG9yKE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgICAgdmVyaWZ5T25lb2ZDb250YWluaW5nVHlwZShvbmVvZik7CisgICAgICByZXR1cm4gb25lb2ZDYXNlc1tvbmVvZi5nZXRJbmRleCgpXTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgICAgdmVyaWZ5T25lb2ZDb250YWluaW5nVHlwZShvbmVvZik7CisgICAgICBGaWVsZERlc2NyaXB0b3IgZmllbGQgPSBvbmVvZkNhc2VzW29uZW9mLmdldEluZGV4KCldOworICAgICAgaWYgKGZpZWxkICE9IG51bGwpIHsKKyAgICAgICAgY2xlYXJGaWVsZChmaWVsZCk7CisgICAgICB9CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICAgIHJldHVybiBmaWVsZHMuaGFzRmllbGQoZmllbGQpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICBPYmplY3QgcmVzdWx0ID0gZmllbGRzLmdldEZpZWxkKGZpZWxkKTsKKyAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICBpZiAoZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgICAgcmVzdWx0ID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgIH0gZWxzZSBpZiAoZmllbGQuZ2V0SmF2YVR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICAgIHJlc3VsdCA9IGdldERlZmF1bHRJbnN0YW5jZShmaWVsZC5nZXRNZXNzYWdlVHlwZSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQgPSBmaWVsZC5nZXREZWZhdWx0VmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZChGaWVsZERlc2NyaXB0b3IgZmllbGQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmllbGQpOworICAgICAgZW5zdXJlSXNNdXRhYmxlKCk7CisgICAgICAvLyBUT0RPKHhpYW9mZW5nKTogVGhpcyBjaGVjayBzaG91bGQgcmVhbGx5IGJlIHB1dCBpbiBGaWVsZFNldC5zZXRGaWVsZCgpCisgICAgICAvLyB3aGVyZSBhbGwgb3RoZXIgc3VjaCBjaGVja3MgYXJlIGRvbmUuIEhvd2V2ZXIsIGN1cnJlbnRseQorICAgICAgLy8gRmllbGRTZXQuc2V0RmllbGQoKSBwZXJtaXRzIEludGVnZXIgdmFsdWUgZm9yIGVudW0gZmllbGRzIHByb2JhYmx5CisgICAgICAvLyBiZWNhdXNlIG9mIHNvbWUgaW50ZXJuYWwgZmVhdHVyZXMgd2Ugc3VwcG9ydC4gU2hvdWxkIGZpZ3VyZSBpdCBvdXQKKyAgICAgIC8vIGFuZCBtb3ZlIHRoaXMgY2hlY2sgdG8gYSBtb3JlIGFwcHJvcHJpYXRlIHBsYWNlLgorICAgICAgaWYgKGZpZWxkLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5FTlVNKSB7CisgICAgICAgIGVuc3VyZUVudW1WYWx1ZURlc2NyaXB0b3IoZmllbGQsIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIE9uZW9mRGVzY3JpcHRvciBvbmVvZkRlc2NyaXB0b3IgPSBmaWVsZC5nZXRDb250YWluaW5nT25lb2YoKTsKKyAgICAgIGlmIChvbmVvZkRlc2NyaXB0b3IgIT0gbnVsbCkgeworICAgICAgICBpbnQgaW5kZXggPSBvbmVvZkRlc2NyaXB0b3IuZ2V0SW5kZXgoKTsKKyAgICAgICAgRmllbGREZXNjcmlwdG9yIG9sZEZpZWxkID0gb25lb2ZDYXNlc1tpbmRleF07CisgICAgICAgIGlmICgob2xkRmllbGQgIT0gbnVsbCkgJiYgKG9sZEZpZWxkICE9IGZpZWxkKSkgeworICAgICAgICAgIGZpZWxkcy5jbGVhckZpZWxkKG9sZEZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICBvbmVvZkNhc2VzW2luZGV4XSA9IGZpZWxkOworICAgICAgfQorICAgICAgZmllbGRzLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmllbGQpOworICAgICAgZW5zdXJlSXNNdXRhYmxlKCk7CisgICAgICBPbmVvZkRlc2NyaXB0b3Igb25lb2ZEZXNjcmlwdG9yID0gZmllbGQuZ2V0Q29udGFpbmluZ09uZW9mKCk7CisgICAgICBpZiAob25lb2ZEZXNjcmlwdG9yICE9IG51bGwpIHsKKyAgICAgICAgaW50IGluZGV4ID0gb25lb2ZEZXNjcmlwdG9yLmdldEluZGV4KCk7CisgICAgICAgIGlmIChvbmVvZkNhc2VzW2luZGV4XSA9PSBmaWVsZCkgeworICAgICAgICAgIG9uZW9mQ2FzZXNbaW5kZXhdID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgZmllbGRzLmNsZWFyRmllbGQoZmllbGQpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICByZXR1cm4gZmllbGRzLmdldFJlcGVhdGVkRmllbGRDb3VudChmaWVsZCk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZEZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCwgaW50IGluZGV4KSB7CisgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICByZXR1cm4gZmllbGRzLmdldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4KTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICBlbnN1cmVJc011dGFibGUoKTsKKyAgICAgIGZpZWxkcy5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChGaWVsZERlc2NyaXB0b3IgZmllbGQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmllbGQpOworICAgICAgZW5zdXJlSXNNdXRhYmxlKCk7CisgICAgICBmaWVsZHMuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIFVua25vd25GaWVsZFNldCBnZXRVbmtub3duRmllbGRzKCkgeworICAgICAgcmV0dXJuIHVua25vd25GaWVsZHM7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcyhVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgaWYgKGdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RmlsZSgpLmdldFN5bnRheCgpCisgICAgICAgICAgPT0gRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuU3ludGF4LlBST1RPMykgeworICAgICAgICAvLyBQcm90bzMgZGlzY2FyZHMgdW5rbm93biBmaWVsZHMuCisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgdGhpcy51bmtub3duRmllbGRzID0gdW5rbm93bkZpZWxkczsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcyhVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgaWYgKGdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RmlsZSgpLmdldFN5bnRheCgpCisgICAgICAgICAgPT0gRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuU3ludGF4LlBST1RPMykgeworICAgICAgICAvLyBQcm90bzMgZGlzY2FyZHMgdW5rbm93biBmaWVsZHMuCisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgdGhpcy51bmtub3duRmllbGRzID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIodGhpcy51bmtub3duRmllbGRzKQorICAgICAgICAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHVua25vd25GaWVsZHMpCisgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIFZlcmlmaWVzIHRoYXQgdGhlIGZpZWxkIGlzIGEgZmllbGQgb2YgdGhpcyBtZXNzYWdlLiAqLworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlDb250YWluaW5nVHlwZShGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGlmIChmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpICE9IHR5cGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiRmllbGREZXNjcmlwdG9yIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogVmVyaWZpZXMgdGhhdCB0aGUgb25lb2YgaXMgYW4gb25lb2Ygb2YgdGhpcyBtZXNzYWdlLiAqLworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlPbmVvZkNvbnRhaW5pbmdUeXBlKE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgICAgaWYgKG9uZW9mLmdldENvbnRhaW5pbmdUeXBlKCkgIT0gdHlwZSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJPbmVvZkRlc2NyaXB0b3IgZG9lcyBub3QgbWF0Y2ggbWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgIH0KKworICAgIC8qKiBWZXJpZmllcyB0aGF0IHRoZSB2YWx1ZSBpcyBFbnVtVmFsdWVEZXNjcmlwdG9yIGFuZCBtYXRjaGVzIEVudW0gVHlwZS4gKi8KKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlU2luZ3VsYXJFbnVtVmFsdWVEZXNjcmlwdG9yKAorICAgICAgICBGaWVsZERlc2NyaXB0b3IgZmllbGQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICB9CisgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIEVudW1WYWx1ZURlc2NyaXB0b3IpKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgIkR5bmFtaWNNZXNzYWdlIHNob3VsZCB1c2UgRW51bVZhbHVlRGVzY3JpcHRvciB0byBzZXQgRW51bSBWYWx1ZS4iKTsKKyAgICAgIH0KKyAgICAgIC8vIFRPRE8oeGlhb2ZlbmcpOiBSZS1lbmFibGUgdGhpcyBjaGVjayBhZnRlciBPcmdzdG9yZSBpcyBmaXhlZCB0byBub3QKKyAgICAgIC8vIHNldCBpbmNvcnJlY3QgRW51bVZhbHVlRGVzY3JpcHRvcnMuCisgICAgICAvLyBFbnVtRGVzY3JpcHRvciBmaWVsZFR5cGUgPSBmaWVsZC5nZXRFbnVtVHlwZSgpOworICAgICAgLy8gRW51bURlc2NyaXB0b3IgZmllbGRWYWx1ZVR5cGUgPSAoKEVudW1WYWx1ZURlc2NyaXB0b3IpIHZhbHVlKS5nZXRUeXBlKCk7CisgICAgICAvLyBpZiAoZmllbGRUeXBlICE9IGZpZWxkVmFsdWVUeXBlKSB7CisgICAgICAvLyAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KAorICAgICAgLy8gICAgICAiRW51bURlc2NyaXB0b3IgJXMgb2YgZmllbGQgZG9lc24ndCBtYXRjaCBFbnVtRGVzY3JpcHRvciAlcyBvZiBmaWVsZCB2YWx1ZSIsCisgICAgICAvLyAgICAgIGZpZWxkVHlwZS5nZXRGdWxsTmFtZSgpLCBmaWVsZFZhbHVlVHlwZS5nZXRGdWxsTmFtZSgpKSk7CisgICAgICAvLyB9CisgICAgfQorCisgICAgLyoqIFZlcmlmaWVzIHRoZSB2YWx1ZSBmb3IgYW4gZW51bSBmaWVsZC4gKi8KKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlRW51bVZhbHVlRGVzY3JpcHRvcigKKyAgICAgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGlmIChmaWVsZC5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgZm9yIChPYmplY3QgaXRlbSA6IChMaXN0KSB2YWx1ZSkgeworICAgICAgICAgIGVuc3VyZVNpbmd1bGFyRW51bVZhbHVlRGVzY3JpcHRvcihmaWVsZCwgaXRlbSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgICBlbnN1cmVTaW5ndWxhckVudW1WYWx1ZURlc2NyaXB0b3IoZmllbGQsIHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlSXNNdXRhYmxlKCkgeworICAgICAgaWYgKGZpZWxkcy5pc0ltbXV0YWJsZSgpKSB7CisgICAgICAgIGZpZWxkcyA9IGZpZWxkcy5jbG9uZSgpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZEJ1aWxkZXIoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICAvLyBUT0RPKHhpYW5nbCk6IG5lZWQgaW1wbGVtZW50YXRpb24gZm9yIGR5bmFtaWMgbWVzc2FnZQorICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAiZ2V0RmllbGRCdWlsZGVyKCkgY2FsbGVkIG9uIGEgZHluYW1pYyBtZXNzYWdlIHR5cGUuIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkRmllbGRCdWlsZGVyKEZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgaW50IGluZGV4KSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkQnVpbGRlcigpIGNhbGxlZCBvbiBhIGR5bmFtaWMgbWVzc2FnZSB0eXBlLiIpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9FeHRlbnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OGQyOWYzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uLmphdmEKQEAgLTAsMCArMSw4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworLyoqCisgKiBJbnRlcmZhY2UgdGhhdCBnZW5lcmF0ZWQgZXh0ZW5zaW9ucyBpbXBsZW1lbnQuCisgKgorICogQGF1dGhvciBsaXVqaXNpQGdvb2dsZS5jb20gKEppc2kgTGl1KQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXh0ZW5zaW9uPENvbnRhaW5pbmdUeXBlIGV4dGVuZHMgTWVzc2FnZUxpdGUsIFR5cGU+CisgICAgZXh0ZW5kcyBFeHRlbnNpb25MaXRlPENvbnRhaW5pbmdUeXBlLCBUeXBlPiB7CisKKyAgLyoqIFJldHVybnMgdGhlIGRlc2NyaXB0b3Igb2YgdGhlIGV4dGVuc2lvbi4gKi8KKyAgcHVibGljIGFic3RyYWN0IERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yKCk7CisKKyAgLyoqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhpcyBleHRlbnNpb24gaXMgYSBMaXRlIEV4dGVuc2lvbi4gKi8KKyAgZmluYWwgYm9vbGVhbiBpc0xpdGUoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gQWxsIHRoZSBtZXRob2RzIGJlbG93IGFyZSBleHRlbnNpb24gaW1wbGVtZW50YXRpb24gZGV0YWlscy4KKworICAvKioKKyAgICogVGhlIEFQSSB0eXBlIHRoYXQgdGhlIGV4dGVuc2lvbiBpcyB1c2VkIGZvci4KKyAgICovCisgIHByb3RlY3RlZCBlbnVtIEV4dGVuc2lvblR5cGUgeworICAgIElNTVVUQUJMRSwKKyAgICBNVVRBQkxFLAorICAgIFBST1RPMSwKKyAgfQorCisgIHByb3RlY3RlZCBFeHRlbnNpb25UeXBlIGdldEV4dGVuc2lvblR5cGUoKSB7CisgICAgLy8gVE9ETyhsaXVqaXNpKTogbWFrZSB0aGlzIGFic3RyYWN0IGFmdGVyIHdlIGZpeCBwcm90bzEuCisgICAgcmV0dXJuIEV4dGVuc2lvblR5cGUuSU1NVVRBQkxFOworICB9CisKKyAgLyoqCisgICAqIFR5cGUgb2YgYSBtZXNzYWdlIGV4dGVuc2lvbi4KKyAgICovCisgIHB1YmxpYyBlbnVtIE1lc3NhZ2VUeXBlIHsKKyAgICBQUk9UTzEsCisgICAgUFJPVE8yLAorICB9CisgIAorICAvKioKKyAgICogSWYgdGhlIGV4dGVuc2lvbiBpcyBhIG1lc3NhZ2UgZXh0ZW5zaW9uIChpLmUuLCBnZXRMaXRlVHlwZSgpID09IE1FU1NBR0UpLAorICAgKiByZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBtZXNzYWdlLCBvdGhlcndpc2UgdW5kZWZpbmVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIGdldE1lc3NhZ2VUeXBlKCkgeworICAgIHJldHVybiBNZXNzYWdlVHlwZS5QUk9UTzI7CisgIH0KKworICBwcm90ZWN0ZWQgYWJzdHJhY3QgT2JqZWN0IGZyb21SZWZsZWN0aW9uVHlwZShPYmplY3QgdmFsdWUpOworICBwcm90ZWN0ZWQgYWJzdHJhY3QgT2JqZWN0IHNpbmd1bGFyRnJvbVJlZmxlY3Rpb25UeXBlKE9iamVjdCB2YWx1ZSk7CisgIHByb3RlY3RlZCBhYnN0cmFjdCBPYmplY3QgdG9SZWZsZWN0aW9uVHlwZShPYmplY3QgdmFsdWUpOworICBwcm90ZWN0ZWQgYWJzdHJhY3QgT2JqZWN0IHNpbmd1bGFyVG9SZWZsZWN0aW9uVHlwZShPYmplY3QgdmFsdWUpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uTGl0ZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uTGl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4ZjViZDIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9FeHRlbnNpb25MaXRlLmphdmEKQEAgLTAsMCArMSw2MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworLyoqCisgKiBMaXRlIGludGVyZmFjZSB0aGF0IGdlbmVyYXRlZCBleHRlbnNpb25zIGltcGxlbWVudC4KKyAqIDxwPgorICogTWV0aG9kcyBhcmUgZm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiBZb3UgY2FuIGhvbGQgYSByZWZlcmVuY2UgdG8KKyAqIGV4dGVuc2lvbnMgdXNpbmcgdGhpcyB0eXBlIG5hbWUuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBFeHRlbnNpb25MaXRlPENvbnRhaW5pbmdUeXBlIGV4dGVuZHMgTWVzc2FnZUxpdGUsIFR5cGU+IHsKKworICAvKiogUmV0dXJucyB0aGUgZmllbGQgbnVtYmVyIG9mIHRoZSBleHRlbnNpb24uICovCisgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TnVtYmVyKCk7CisKKyAgLyoqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGZpZWxkLiAqLworICBwdWJsaWMgYWJzdHJhY3QgV2lyZUZvcm1hdC5GaWVsZFR5cGUgZ2V0TGl0ZVR5cGUoKTsKKworICAvKiogUmV0dXJucyB3aGV0aGVyIGl0IGlzIGEgcmVwZWF0ZWQgZmllbGQuICovCisgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzUmVwZWF0ZWQoKTsKKworICAvKiogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgZXh0ZW5zaW9uIGZpZWxkLiAqLworICBwdWJsaWMgYWJzdHJhY3QgVHlwZSBnZXREZWZhdWx0VmFsdWUoKTsKKworICAvKioKKyAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBpbnN0YW5jZSBvZiB0aGUgZXh0ZW5zaW9uIGZpZWxkLCBpZiBpdCdzIGEgbWVzc2FnZQorICAgKiBleHRlbnNpb24uCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgTWVzc2FnZUxpdGUgZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpOworICAKKyAgLyoqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhpcyBleHRlbnNpb24gaXMgYSBMaXRlIEV4dGVuc2lvbi4gKi8KKyAgYm9vbGVhbiBpc0xpdGUoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0V4dGVuc2lvblJlZ2lzdHJ5LmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9FeHRlbnNpb25SZWdpc3RyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwNjczOTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9FeHRlbnNpb25SZWdpc3RyeS5qYXZhCkBAIC0wLDAgKzEsMzkyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBBIHRhYmxlIG9mIGtub3duIGV4dGVuc2lvbnMsIHNlYXJjaGFibGUgYnkgbmFtZSBvciBmaWVsZCBudW1iZXIuICBXaGVuCisgKiBwYXJzaW5nIGEgcHJvdG9jb2wgbWVzc2FnZSB0aGF0IG1pZ2h0IGhhdmUgZXh0ZW5zaW9ucywgeW91IG11c3QgcHJvdmlkZQorICogYW4ge0Bjb2RlIEV4dGVuc2lvblJlZ2lzdHJ5fSBpbiB3aGljaCB5b3UgaGF2ZSByZWdpc3RlcmVkIGFueSBleHRlbnNpb25zCisgKiB0aGF0IHlvdSB3YW50IHRvIGJlIGFibGUgdG8gcGFyc2UuICBPdGhlcndpc2UsIHRob3NlIGV4dGVuc2lvbnMgd2lsbCBqdXN0CisgKiBiZSB0cmVhdGVkIGxpa2UgdW5rbm93biBmaWVsZHMuCisgKgorICogPHA+Rm9yIGV4YW1wbGUsIGlmIHlvdSBoYWQgdGhlIHtAY29kZSAucHJvdG99IGZpbGU6CisgKgorICogPHByZT4KKyAqIG9wdGlvbiBqYXZhX2NsYXNzID0gIk15UHJvdG8iOworICoKKyAqIG1lc3NhZ2UgRm9vIHsKKyAqICAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKKyAqIH0KKyAqCisgKiBleHRlbmQgRm9vIHsKKyAqICAgb3B0aW9uYWwgaW50MzIgYmFyOworICogfQorICogPC9wcmU+CisgKgorICogVGhlbiB5b3UgbWlnaHQgd3JpdGUgY29kZSBsaWtlOgorICoKKyAqIDxwcmU+CisgKiBFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IEV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CisgKiByZWdpc3RyeS5hZGQoTXlQcm90by5iYXIpOworICogTXlQcm90by5Gb28gbWVzc2FnZSA9IE15UHJvdG8uRm9vLnBhcnNlRnJvbShpbnB1dCwgcmVnaXN0cnkpOworICogPC9wcmU+CisgKgorICogPHA+QmFja2dyb3VuZDoKKyAqCisgKiA8cD5Zb3UgbWlnaHQgd29uZGVyIHdoeSB0aGlzIGlzIG5lY2Vzc2FyeS4gIFR3byBhbHRlcm5hdGl2ZXMgbWlnaHQgY29tZSB0bworICogbWluZC4gIEZpcnN0LCB5b3UgbWlnaHQgaW1hZ2luZSBhIHN5c3RlbSB3aGVyZSBnZW5lcmF0ZWQgZXh0ZW5zaW9ucyBhcmUKKyAqIGF1dG9tYXRpY2FsbHkgcmVnaXN0ZXJlZCB3aGVuIHRoZWlyIGNvbnRhaW5pbmcgY2xhc3NlcyBhcmUgbG9hZGVkLiAgVGhpcworICogaXMgYSBwb3B1bGFyIHRlY2huaXF1ZSwgYnV0IGlzIGJhZCBkZXNpZ247IGFtb25nIG90aGVyIHRoaW5ncywgaXQgY3JlYXRlcyBhCisgKiBzaXR1YXRpb24gd2hlcmUgYmVoYXZpb3IgY2FuIGNoYW5nZSBkZXBlbmRpbmcgb24gd2hhdCBjbGFzc2VzIGhhcHBlbiB0byBiZQorICogbG9hZGVkLiAgSXQgYWxzbyBpbnRyb2R1Y2VzIGEgc2VjdXJpdHkgdnVsbmVyYWJpbGl0eSwgYmVjYXVzZSBhbgorICogdW5wcml2aWxlZ2VkIGNsYXNzIGNvdWxkIGNhdXNlIGl0cyBjb2RlIHRvIGJlIGNhbGxlZCB1bmV4cGVjdGVkbHkgZnJvbSBhCisgKiBwcml2aWxlZ2VkIGNsYXNzIGJ5IHJlZ2lzdGVyaW5nIGl0c2VsZiBhcyBhbiBleHRlbnNpb24gb2YgdGhlIHJpZ2h0IHR5cGUuCisgKgorICogPHA+QW5vdGhlciBvcHRpb24geW91IG1pZ2h0IGNvbnNpZGVyIGlzIGxhenkgcGFyc2luZzogZG8gbm90IHBhcnNlIGFuCisgKiBleHRlbnNpb24gdW50aWwgaXQgaXMgZmlyc3QgcmVxdWVzdGVkLCBhdCB3aGljaCBwb2ludCB0aGUgY2FsbGVyIG11c3QKKyAqIHByb3ZpZGUgYSB0eXBlIHRvIHVzZS4gIFRoaXMgaW50cm9kdWNlcyBhIGRpZmZlcmVudCBzZXQgb2YgcHJvYmxlbXMuICBGaXJzdCwKKyAqIGl0IHdvdWxkIHJlcXVpcmUgYSBtdXRleCBsb2NrIGFueSB0aW1lIGFuIGV4dGVuc2lvbiB3YXMgYWNjZXNzZWQsIHdoaWNoCisgKiB3b3VsZCBiZSBzbG93LiAgU2Vjb25kLCBjb3JydXB0IGRhdGEgd291bGQgbm90IGJlIGRldGVjdGVkIHVudGlsIGZpcnN0CisgKiBhY2Nlc3MsIGF0IHdoaWNoIHBvaW50IGl0IHdvdWxkIGJlIG11Y2ggaGFyZGVyIHRvIGRlYWwgd2l0aCBpdC4gIFRoaXJkLCBpdAorICogY291bGQgdmlvbGF0ZSB0aGUgZXhwZWN0YXRpb24gdGhhdCBtZXNzYWdlIG9iamVjdHMgYXJlIGltbXV0YWJsZSwgc2luY2UgdGhlCisgKiB0eXBlIHByb3ZpZGVkIGNvdWxkIGJlIGFueSBhcmJpdHJhcnkgbWVzc2FnZSBjbGFzcy4gIEFuIHVucHJpdmlsZWdlZCB1c2VyCisgKiBjb3VsZCB0YWtlIGFkdmFudGFnZSBvZiB0aGlzIHRvIGluamVjdCBhIG11dGFibGUgb2JqZWN0IGludG8gYSBtZXNzYWdlCisgKiBiZWxvbmdpbmcgdG8gcHJpdmlsZWdlZCBjb2RlIGFuZCBjcmVhdGUgbWlzY2hpZWYuCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGNsYXNzIEV4dGVuc2lvblJlZ2lzdHJ5IGV4dGVuZHMgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHsKKyAgLyoqIENvbnN0cnVjdCBhIG5ldywgZW1wdHkgaW5zdGFuY2UuICovCisgIHB1YmxpYyBzdGF0aWMgRXh0ZW5zaW9uUmVnaXN0cnkgbmV3SW5zdGFuY2UoKSB7CisgICAgcmV0dXJuIG5ldyBFeHRlbnNpb25SZWdpc3RyeSgpOworICB9CisKKyAgLyoqIEdldCB0aGUgdW5tb2RpZmlhYmxlIHNpbmdsZXRvbiBlbXB0eSBpbnN0YW5jZS4gKi8KKyAgcHVibGljIHN0YXRpYyBFeHRlbnNpb25SZWdpc3RyeSBnZXRFbXB0eVJlZ2lzdHJ5KCkgeworICAgIHJldHVybiBFTVBUWTsKKyAgfQorCisKKyAgLyoqIFJldHVybnMgYW4gdW5tb2RpZmlhYmxlIHZpZXcgb2YgdGhlIHJlZ2lzdHJ5LiAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIEV4dGVuc2lvblJlZ2lzdHJ5IGdldFVubW9kaWZpYWJsZSgpIHsKKyAgICByZXR1cm4gbmV3IEV4dGVuc2lvblJlZ2lzdHJ5KHRoaXMpOworICB9CisKKyAgLyoqIEEgKERlc2NyaXB0b3IsIE1lc3NhZ2UpIHBhaXIsIHJldHVybmVkIGJ5IGxvb2t1cCBtZXRob2RzLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEV4dGVuc2lvbkluZm8geworICAgIC8qKiBUaGUgZXh0ZW5zaW9uJ3MgZGVzY3JpcHRvci4gKi8KKyAgICBwdWJsaWMgZmluYWwgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3I7CisKKyAgICAvKioKKyAgICAgKiBBIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhlIGV4dGVuc2lvbidzIHR5cGUsIGlmIGl0IGhhcyBhIG1lc3NhZ2UgdHlwZS4KKyAgICAgKiBPdGhlcndpc2UsIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2U7CisKKyAgICBwcml2YXRlIEV4dGVuc2lvbkluZm8oZmluYWwgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgICAgIHRoaXMuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgICAgICBkZWZhdWx0SW5zdGFuY2UgPSBudWxsOworICAgIH0KKyAgICBwcml2YXRlIEV4dGVuc2lvbkluZm8oZmluYWwgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKSB7CisgICAgICB0aGlzLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yOworICAgICAgdGhpcy5kZWZhdWx0SW5zdGFuY2UgPSBkZWZhdWx0SW5zdGFuY2U7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIERlcHJlY2F0ZWQuIFVzZSB7QGxpbmsgI2ZpbmRJbW11dGFibGVFeHRlbnNpb25CeU5hbWUoU3RyaW5nKX0gaW5zdGVhZC4KKyAgICovCisgIHB1YmxpYyBFeHRlbnNpb25JbmZvIGZpbmRFeHRlbnNpb25CeU5hbWUoZmluYWwgU3RyaW5nIGZ1bGxOYW1lKSB7CisgICAgcmV0dXJuIGZpbmRJbW11dGFibGVFeHRlbnNpb25CeU5hbWUoZnVsbE5hbWUpOworICB9CisKKyAgLyoqCisgICAqIEZpbmQgYW4gZXh0ZW5zaW9uIGZvciBpbW11dGFibGUgQVBJcyBieSBmdWxseS1xdWFsaWZpZWQgZmllbGQgbmFtZSwKKyAgICogaW4gdGhlIHByb3RvIG5hbWVzcGFjZS4gaS5lLiB7QGNvZGUgcmVzdWx0LmRlc2NyaXB0b3IuZnVsbE5hbWUoKX0gd2lsbAorICAgKiBtYXRjaCB7QGNvZGUgZnVsbE5hbWV9IGlmIGEgbWF0Y2ggaXMgZm91bmQuCisgICAqCisgICAqIEByZXR1cm4gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGV4dGVuc2lvbiBpZiBmb3VuZCwgb3Ige0Bjb2RlIG51bGx9CisgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgKi8KKyAgcHVibGljIEV4dGVuc2lvbkluZm8gZmluZEltbXV0YWJsZUV4dGVuc2lvbkJ5TmFtZShmaW5hbCBTdHJpbmcgZnVsbE5hbWUpIHsKKyAgICByZXR1cm4gaW1tdXRhYmxlRXh0ZW5zaW9uc0J5TmFtZS5nZXQoZnVsbE5hbWUpOworICB9CisKKyAgLyoqCisgICAqIEZpbmQgYW4gZXh0ZW5zaW9uIGZvciBtdXRhYmxlIEFQSXMgYnkgZnVsbHktcXVhbGlmaWVkIGZpZWxkIG5hbWUsCisgICAqIGluIHRoZSBwcm90byBuYW1lc3BhY2UuIGkuZS4ge0Bjb2RlIHJlc3VsdC5kZXNjcmlwdG9yLmZ1bGxOYW1lKCl9IHdpbGwKKyAgICogbWF0Y2gge0Bjb2RlIGZ1bGxOYW1lfSBpZiBhIG1hdGNoIGlzIGZvdW5kLgorICAgKgorICAgKiBAcmV0dXJuIEluZm9ybWF0aW9uIGFib3V0IHRoZSBleHRlbnNpb24gaWYgZm91bmQsIG9yIHtAY29kZSBudWxsfQorICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICovCisgIHB1YmxpYyBFeHRlbnNpb25JbmZvIGZpbmRNdXRhYmxlRXh0ZW5zaW9uQnlOYW1lKGZpbmFsIFN0cmluZyBmdWxsTmFtZSkgeworICAgIHJldHVybiBtdXRhYmxlRXh0ZW5zaW9uc0J5TmFtZS5nZXQoZnVsbE5hbWUpOworICB9CisKKyAgLyoqCisgICAqIERlcHJlY2F0ZWQuIFVzZSB7QGxpbmsgI2ZpbmRJbW11dGFibGVFeHRlbnNpb25CeU51bWJlcigKKyAgICogRGVzY3JpcHRvcnMuRGVzY3JpcHRvciwgaW50KX0KKyAgICovCisgIHB1YmxpYyBFeHRlbnNpb25JbmZvIGZpbmRFeHRlbnNpb25CeU51bWJlcigKKyAgICAgIGZpbmFsIERlc2NyaXB0b3IgY29udGFpbmluZ1R5cGUsIGZpbmFsIGludCBmaWVsZE51bWJlcikgeworICAgIHJldHVybiBmaW5kSW1tdXRhYmxlRXh0ZW5zaW9uQnlOdW1iZXIoY29udGFpbmluZ1R5cGUsIGZpZWxkTnVtYmVyKTsKKyAgfQorCisgIC8qKgorICAgKiBGaW5kIGFuIGV4dGVuc2lvbiBieSBjb250YWluaW5nIHR5cGUgYW5kIGZpZWxkIG51bWJlciBmb3IgaW1tdXRhYmxlIEFQSXMuCisgICAqCisgICAqIEByZXR1cm4gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGV4dGVuc2lvbiBpZiBmb3VuZCwgb3Ige0Bjb2RlIG51bGx9CisgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgKi8KKyAgcHVibGljIEV4dGVuc2lvbkluZm8gZmluZEltbXV0YWJsZUV4dGVuc2lvbkJ5TnVtYmVyKAorICAgICAgZmluYWwgRGVzY3JpcHRvciBjb250YWluaW5nVHlwZSwgZmluYWwgaW50IGZpZWxkTnVtYmVyKSB7CisgICAgcmV0dXJuIGltbXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlci5nZXQoCisgICAgICBuZXcgRGVzY3JpcHRvckludFBhaXIoY29udGFpbmluZ1R5cGUsIGZpZWxkTnVtYmVyKSk7CisgIH0KKworICAvKioKKyAgICogRmluZCBhbiBleHRlbnNpb24gYnkgY29udGFpbmluZyB0eXBlIGFuZCBmaWVsZCBudW1iZXIgZm9yIG11dGFibGUgQVBJcy4KKyAgICoKKyAgICogQHJldHVybiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgZXh0ZW5zaW9uIGlmIGZvdW5kLCBvciB7QGNvZGUgbnVsbH0KKyAgICogICAgICAgICBvdGhlcndpc2UuCisgICAqLworICBwdWJsaWMgRXh0ZW5zaW9uSW5mbyBmaW5kTXV0YWJsZUV4dGVuc2lvbkJ5TnVtYmVyKAorICAgICAgZmluYWwgRGVzY3JpcHRvciBjb250YWluaW5nVHlwZSwgZmluYWwgaW50IGZpZWxkTnVtYmVyKSB7CisgICAgcmV0dXJuIG11dGFibGVFeHRlbnNpb25zQnlOdW1iZXIuZ2V0KAorICAgICAgICBuZXcgRGVzY3JpcHRvckludFBhaXIoY29udGFpbmluZ1R5cGUsIGZpZWxkTnVtYmVyKSk7CisgIH0KKworICAvKioKKyAgICogRmluZCBhbGwgZXh0ZW5zaW9ucyBmb3IgbXV0YWJsZSBBUElzIGJ5IGZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mCisgICAqIGV4dGVuZGVkIGNsYXNzLiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbW9yZSBjb21wdXRhdGlvbmFsbHkgZXhwZW5zaXZlCisgICAqIHRoYW4gZ2V0dGluZyBhIHNpbmdsZSBleHRlbnNpb24gYnkgbmFtZSBvciBudW1iZXIuCisgICAqCisgICAqIEByZXR1cm4gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGV4dGVuc2lvbnMgZm91bmQsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZQorICAgKiAgICAgYXJlIG5vbmUuCisgICAqLworICBwdWJsaWMgU2V0PEV4dGVuc2lvbkluZm8+IGdldEFsbE11dGFibGVFeHRlbnNpb25zQnlFeHRlbmRlZFR5cGUoZmluYWwgU3RyaW5nIGZ1bGxOYW1lKSB7CisgICAgSGFzaFNldDxFeHRlbnNpb25JbmZvPiBleHRlbnNpb25zID0gbmV3IEhhc2hTZXQ8RXh0ZW5zaW9uSW5mbz4oKTsKKyAgICBmb3IgKERlc2NyaXB0b3JJbnRQYWlyIHBhaXIgOiBtdXRhYmxlRXh0ZW5zaW9uc0J5TnVtYmVyLmtleVNldCgpKSB7CisgICAgICBpZiAocGFpci5kZXNjcmlwdG9yLmdldEZ1bGxOYW1lKCkuZXF1YWxzKGZ1bGxOYW1lKSkgeworICAgICAgICBleHRlbnNpb25zLmFkZChtdXRhYmxlRXh0ZW5zaW9uc0J5TnVtYmVyLmdldChwYWlyKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBleHRlbnNpb25zOworICB9CisKKyAgLyoqCisgICAqIEZpbmQgYWxsIGV4dGVuc2lvbnMgZm9yIGltbXV0YWJsZSBBUElzIGJ5IGZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mCisgICAqIGV4dGVuZGVkIGNsYXNzLiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbW9yZSBjb21wdXRhdGlvbmFsbHkgZXhwZW5zaXZlCisgICAqIHRoYW4gZ2V0dGluZyBhIHNpbmdsZSBleHRlbnNpb24gYnkgbmFtZSBvciBudW1iZXIuCisgICAqCisgICAqIEByZXR1cm4gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGV4dGVuc2lvbnMgZm91bmQsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZQorICAgKiAgICAgYXJlIG5vbmUuCisgICAqLworICBwdWJsaWMgU2V0PEV4dGVuc2lvbkluZm8+IGdldEFsbEltbXV0YWJsZUV4dGVuc2lvbnNCeUV4dGVuZGVkVHlwZShmaW5hbCBTdHJpbmcgZnVsbE5hbWUpIHsKKyAgICBIYXNoU2V0PEV4dGVuc2lvbkluZm8+IGV4dGVuc2lvbnMgPSBuZXcgSGFzaFNldDxFeHRlbnNpb25JbmZvPigpOworICAgIGZvciAoRGVzY3JpcHRvckludFBhaXIgcGFpciA6IGltbXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlci5rZXlTZXQoKSkgeworICAgICAgaWYgKHBhaXIuZGVzY3JpcHRvci5nZXRGdWxsTmFtZSgpLmVxdWFscyhmdWxsTmFtZSkpIHsKKyAgICAgICAgZXh0ZW5zaW9ucy5hZGQoaW1tdXRhYmxlRXh0ZW5zaW9uc0J5TnVtYmVyLmdldChwYWlyKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBleHRlbnNpb25zOworICB9CisKKyAgLyoqIEFkZCBhbiBleHRlbnNpb24gZnJvbSBhIGdlbmVyYXRlZCBmaWxlIHRvIHRoZSByZWdpc3RyeS4gKi8KKyAgcHVibGljIHZvaWQgYWRkKGZpbmFsIEV4dGVuc2lvbjw/LCA/PiBleHRlbnNpb24pIHsKKyAgICBpZiAoZXh0ZW5zaW9uLmdldEV4dGVuc2lvblR5cGUoKSAhPSBFeHRlbnNpb24uRXh0ZW5zaW9uVHlwZS5JTU1VVEFCTEUgJiYKKyAgICAgICAgZXh0ZW5zaW9uLmdldEV4dGVuc2lvblR5cGUoKSAhPSBFeHRlbnNpb24uRXh0ZW5zaW9uVHlwZS5NVVRBQkxFKSB7CisgICAgICAvLyBkbyBub3Qgc3VwcG9ydCBvdGhlciBleHRlbnNpb24gdHlwZXMuIGlnbm9yZQorICAgICAgcmV0dXJuOworICAgIH0KKyAgICBhZGQobmV3RXh0ZW5zaW9uSW5mbyhleHRlbnNpb24pLCBleHRlbnNpb24uZ2V0RXh0ZW5zaW9uVHlwZSgpKTsKKyAgfQorCisgIHN0YXRpYyBFeHRlbnNpb25JbmZvIG5ld0V4dGVuc2lvbkluZm8oZmluYWwgRXh0ZW5zaW9uPD8sID8+IGV4dGVuc2lvbikgeworICAgIGlmIChleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpLmdldEphdmFUeXBlKCkgPT0KKyAgICAgICAgRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgIGlmIChleHRlbnNpb24uZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICJSZWdpc3RlcmVkIG1lc3NhZ2UtdHlwZSBleHRlbnNpb24gaGFkIG51bGwgZGVmYXVsdCBpbnN0YW5jZTogIiArCisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKS5nZXRGdWxsTmFtZSgpKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBuZXcgRXh0ZW5zaW9uSW5mbyhleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpLAorICAgICAgICAgIChNZXNzYWdlKSBleHRlbnNpb24uZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIG5ldyBFeHRlbnNpb25JbmZvKGV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCksIG51bGwpOworICAgIH0KKyAgfQorCisgIC8qKiBBZGQgYSBub24tbWVzc2FnZS10eXBlIGV4dGVuc2lvbiB0byB0aGUgcmVnaXN0cnkgYnkgZGVzY3JpcHRvci4gKi8KKyAgcHVibGljIHZvaWQgYWRkKGZpbmFsIEZpZWxkRGVzY3JpcHRvciB0eXBlKSB7CisgICAgaWYgKHR5cGUuZ2V0SmF2YVR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgIkV4dGVuc2lvblJlZ2lzdHJ5LmFkZCgpIG11c3QgYmUgcHJvdmlkZWQgYSBkZWZhdWx0IGluc3RhbmNlIHdoZW4gIiArCisgICAgICAgICJhZGRpbmcgYW4gZW1iZWRkZWQgbWVzc2FnZSBleHRlbnNpb24uIik7CisgICAgfQorICAgIEV4dGVuc2lvbkluZm8gaW5mbyA9IG5ldyBFeHRlbnNpb25JbmZvKHR5cGUsIG51bGwpOworICAgIGFkZChpbmZvLCBFeHRlbnNpb24uRXh0ZW5zaW9uVHlwZS5JTU1VVEFCTEUpOworICAgIGFkZChpbmZvLCBFeHRlbnNpb24uRXh0ZW5zaW9uVHlwZS5NVVRBQkxFKTsKKyAgfQorCisgIC8qKiBBZGQgYSBtZXNzYWdlLXR5cGUgZXh0ZW5zaW9uIHRvIHRoZSByZWdpc3RyeSBieSBkZXNjcmlwdG9yLiAqLworICBwdWJsaWMgdm9pZCBhZGQoZmluYWwgRmllbGREZXNjcmlwdG9yIHR5cGUsIGZpbmFsIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKSB7CisgICAgaWYgKHR5cGUuZ2V0SmF2YVR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgIkV4dGVuc2lvblJlZ2lzdHJ5LmFkZCgpIHByb3ZpZGVkIGEgZGVmYXVsdCBpbnN0YW5jZSBmb3IgYSAiICsKKyAgICAgICAgIm5vbi1tZXNzYWdlIGV4dGVuc2lvbi4iKTsKKyAgICB9CisgICAgICBhZGQobmV3IEV4dGVuc2lvbkluZm8odHlwZSwgZGVmYXVsdEluc3RhbmNlKSwKKyAgICAgICAgICBFeHRlbnNpb24uRXh0ZW5zaW9uVHlwZS5JTU1VVEFCTEUpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gUHJpdmF0ZSBzdHVmZi4KKworICBwcml2YXRlIEV4dGVuc2lvblJlZ2lzdHJ5KCkgeworICAgIHRoaXMuaW1tdXRhYmxlRXh0ZW5zaW9uc0J5TmFtZSA9IG5ldyBIYXNoTWFwPFN0cmluZywgRXh0ZW5zaW9uSW5mbz4oKTsKKyAgICB0aGlzLm11dGFibGVFeHRlbnNpb25zQnlOYW1lID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBFeHRlbnNpb25JbmZvPigpOworICAgIHRoaXMuaW1tdXRhYmxlRXh0ZW5zaW9uc0J5TnVtYmVyID0KKyAgICAgICAgbmV3IEhhc2hNYXA8RGVzY3JpcHRvckludFBhaXIsIEV4dGVuc2lvbkluZm8+KCk7CisgICAgdGhpcy5tdXRhYmxlRXh0ZW5zaW9uc0J5TnVtYmVyID0KKyAgICAgICAgbmV3IEhhc2hNYXA8RGVzY3JpcHRvckludFBhaXIsIEV4dGVuc2lvbkluZm8+KCk7CisgIH0KKworICBwcml2YXRlIEV4dGVuc2lvblJlZ2lzdHJ5KEV4dGVuc2lvblJlZ2lzdHJ5IG90aGVyKSB7CisgICAgc3VwZXIob3RoZXIpOworICAgIHRoaXMuaW1tdXRhYmxlRXh0ZW5zaW9uc0J5TmFtZSA9CisgICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChvdGhlci5pbW11dGFibGVFeHRlbnNpb25zQnlOYW1lKTsKKyAgICB0aGlzLm11dGFibGVFeHRlbnNpb25zQnlOYW1lID0KKyAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG90aGVyLm11dGFibGVFeHRlbnNpb25zQnlOYW1lKTsKKyAgICB0aGlzLmltbXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlciA9CisgICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChvdGhlci5pbW11dGFibGVFeHRlbnNpb25zQnlOdW1iZXIpOworICAgIHRoaXMubXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlciA9CisgICAgICAgICAgICBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAob3RoZXIubXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlcik7CisgIH0KKworICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEV4dGVuc2lvbkluZm8+IGltbXV0YWJsZUV4dGVuc2lvbnNCeU5hbWU7CisgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgRXh0ZW5zaW9uSW5mbz4gbXV0YWJsZUV4dGVuc2lvbnNCeU5hbWU7CisgIHByaXZhdGUgZmluYWwgTWFwPERlc2NyaXB0b3JJbnRQYWlyLCBFeHRlbnNpb25JbmZvPiBpbW11dGFibGVFeHRlbnNpb25zQnlOdW1iZXI7CisgIHByaXZhdGUgZmluYWwgTWFwPERlc2NyaXB0b3JJbnRQYWlyLCBFeHRlbnNpb25JbmZvPiBtdXRhYmxlRXh0ZW5zaW9uc0J5TnVtYmVyOworCisgIEV4dGVuc2lvblJlZ2lzdHJ5KGJvb2xlYW4gZW1wdHkpIHsKKyAgICBzdXBlcihFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgICB0aGlzLmltbXV0YWJsZUV4dGVuc2lvbnNCeU5hbWUgPQorICAgICAgICBDb2xsZWN0aW9ucy48U3RyaW5nLCBFeHRlbnNpb25JbmZvPmVtcHR5TWFwKCk7CisgICAgdGhpcy5tdXRhYmxlRXh0ZW5zaW9uc0J5TmFtZSA9CisgICAgICAgIENvbGxlY3Rpb25zLjxTdHJpbmcsIEV4dGVuc2lvbkluZm8+ZW1wdHlNYXAoKTsKKyAgICB0aGlzLmltbXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlciA9CisgICAgICAgIENvbGxlY3Rpb25zLjxEZXNjcmlwdG9ySW50UGFpciwgRXh0ZW5zaW9uSW5mbz5lbXB0eU1hcCgpOworICAgIHRoaXMubXV0YWJsZUV4dGVuc2lvbnNCeU51bWJlciA9CisgICAgICAgICAgICBDb2xsZWN0aW9ucy48RGVzY3JpcHRvckludFBhaXIsIEV4dGVuc2lvbkluZm8+ZW1wdHlNYXAoKTsKKyAgfQorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeSBFTVBUWSA9IG5ldyBFeHRlbnNpb25SZWdpc3RyeSh0cnVlKTsKKworICBwcml2YXRlIHZvaWQgYWRkKAorICAgICAgZmluYWwgRXh0ZW5zaW9uSW5mbyBleHRlbnNpb24sCisgICAgICBmaW5hbCBFeHRlbnNpb24uRXh0ZW5zaW9uVHlwZSBleHRlbnNpb25UeXBlKSB7CisgICAgaWYgKCFleHRlbnNpb24uZGVzY3JpcHRvci5pc0V4dGVuc2lvbigpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJFeHRlbnNpb25SZWdpc3RyeS5hZGQoKSB3YXMgZ2l2ZW4gYSBGaWVsZERlc2NyaXB0b3IgZm9yIGEgcmVndWxhciAiICsKKyAgICAgICAgICAgICAgIihub24tZXh0ZW5zaW9uKSBmaWVsZC4iKTsKKyAgICB9CisKKyAgICBNYXA8U3RyaW5nLCBFeHRlbnNpb25JbmZvPiBleHRlbnNpb25zQnlOYW1lOworICAgIE1hcDxEZXNjcmlwdG9ySW50UGFpciwgRXh0ZW5zaW9uSW5mbz4gZXh0ZW5zaW9uc0J5TnVtYmVyOworICAgIHN3aXRjaCAoZXh0ZW5zaW9uVHlwZSkgeworICAgICAgY2FzZSBJTU1VVEFCTEU6CisgICAgICAgIGV4dGVuc2lvbnNCeU5hbWUgPSBpbW11dGFibGVFeHRlbnNpb25zQnlOYW1lOworICAgICAgICBleHRlbnNpb25zQnlOdW1iZXIgPSBpbW11dGFibGVFeHRlbnNpb25zQnlOdW1iZXI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBNVVRBQkxFOgorICAgICAgICBleHRlbnNpb25zQnlOYW1lID0gbXV0YWJsZUV4dGVuc2lvbnNCeU5hbWU7CisgICAgICAgIGV4dGVuc2lvbnNCeU51bWJlciA9IG11dGFibGVFeHRlbnNpb25zQnlOdW1iZXI7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgLy8gSWdub3JlIHRoZSB1bmtub3duIHN1cHBvcnRlZCB0eXBlLgorICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgZXh0ZW5zaW9uc0J5TmFtZS5wdXQoZXh0ZW5zaW9uLmRlc2NyaXB0b3IuZ2V0RnVsbE5hbWUoKSwgZXh0ZW5zaW9uKTsKKyAgICBleHRlbnNpb25zQnlOdW1iZXIucHV0KAorICAgICAgbmV3IERlc2NyaXB0b3JJbnRQYWlyKGV4dGVuc2lvbi5kZXNjcmlwdG9yLmdldENvbnRhaW5pbmdUeXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IuZ2V0TnVtYmVyKCkpLAorICAgICAgZXh0ZW5zaW9uKTsKKworICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGV4dGVuc2lvbi5kZXNjcmlwdG9yOworICAgIGlmIChmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpLmdldE9wdGlvbnMoKS5nZXRNZXNzYWdlU2V0V2lyZUZvcm1hdCgpICYmCisgICAgICAgIGZpZWxkLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFICYmCisgICAgICAgIGZpZWxkLmlzT3B0aW9uYWwoKSAmJgorICAgICAgICBmaWVsZC5nZXRFeHRlbnNpb25TY29wZSgpID09IGZpZWxkLmdldE1lc3NhZ2VUeXBlKCkpIHsKKyAgICAgIC8vIFRoaXMgaXMgYW4gZXh0ZW5zaW9uIG9mIGEgTWVzc2FnZVNldCB0eXBlIGRlZmluZWQgd2l0aGluIHRoZSBleHRlbnNpb24KKyAgICAgIC8vIHR5cGUncyBvd24gc2NvcGUuICBGb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHksIGFsbG93IGl0IHRvIGJlIGxvb2tlZAorICAgICAgLy8gdXAgYnkgdHlwZSBuYW1lLgorICAgICAgZXh0ZW5zaW9uc0J5TmFtZS5wdXQoZmllbGQuZ2V0TWVzc2FnZVR5cGUoKS5nZXRGdWxsTmFtZSgpLCBleHRlbnNpb24pOworICAgIH0KKyAgfQorCisgIC8qKiBBIChHZW5lcmljRGVzY3JpcHRvciwgaW50KSBwYWlyLCB1c2VkIGFzIGEgbWFwIGtleS4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRGVzY3JpcHRvckludFBhaXIgeworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvciBkZXNjcmlwdG9yOworICAgIHByaXZhdGUgZmluYWwgaW50IG51bWJlcjsKKworICAgIERlc2NyaXB0b3JJbnRQYWlyKGZpbmFsIERlc2NyaXB0b3IgZGVzY3JpcHRvciwgZmluYWwgaW50IG51bWJlcikgeworICAgICAgdGhpcy5kZXNjcmlwdG9yID0gZGVzY3JpcHRvcjsKKyAgICAgIHRoaXMubnVtYmVyID0gbnVtYmVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gZGVzY3JpcHRvci5oYXNoQ29kZSgpICogKCgxIDw8IDE2KSAtIDEpICsgbnVtYmVyOworICAgIH0KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG9iaikgeworICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgRGVzY3JpcHRvckludFBhaXIpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGZpbmFsIERlc2NyaXB0b3JJbnRQYWlyIG90aGVyID0gKERlc2NyaXB0b3JJbnRQYWlyKW9iajsKKyAgICAgIHJldHVybiBkZXNjcmlwdG9yID09IG90aGVyLmRlc2NyaXB0b3IgJiYgbnVtYmVyID09IG90aGVyLm51bWJlcjsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0V4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjVjZjczOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0V4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogRXF1aXZhbGVudCB0byB7QGxpbmsgRXh0ZW5zaW9uUmVnaXN0cnl9IGJ1dCBzdXBwb3J0cyBvbmx5ICJsaXRlIiB0eXBlcy4KKyAqIDxwPgorICogSWYgYWxsIG9mIHlvdXIgdHlwZXMgYXJlIGxpdGUgdHlwZXMsIHRoZW4geW91IG9ubHkgbmVlZCB0byB1c2UKKyAqIHtAY29kZSBFeHRlbnNpb25SZWdpc3RyeUxpdGV9LiAgU2ltaWxhcmx5LCBpZiBhbGwgeW91ciB0eXBlcyBhcmUgcmVndWxhcgorICogdHlwZXMsIHRoZW4geW91IG9ubHkgbmVlZCB7QGxpbmsgRXh0ZW5zaW9uUmVnaXN0cnl9LiAgVHlwaWNhbGx5IGl0IGRvZXMgbm90CisgKiBtYWtlIHNlbnNlIHRvIG1peCB0aGUgdHdvLCBzaW5jZSBpZiB5b3UgaGF2ZSBhbnkgcmVndWxhciB0eXBlcyBpbiB5b3VyCisgKiBwcm9ncmFtLCB5b3UgdGhlbiByZXF1aXJlIHRoZSBmdWxsIHJ1bnRpbWUgYW5kIGxvc2UgYWxsIHRoZSBiZW5lZml0cyBvZgorICogdGhlIGxpdGUgcnVudGltZSwgc28geW91IG1pZ2h0IGFzIHdlbGwgbWFrZSBhbGwgeW91ciB0eXBlcyBiZSByZWd1bGFyIHR5cGVzLgorICogSG93ZXZlciwgaW4gc29tZSBjYXNlcyAoZS5nLiB3aGVuIGRlcGVuZGluZyBvbiBtdWx0aXBsZSB0aGlyZC1wYXJ0eSBsaWJyYXJpZXMKKyAqIHdoZXJlIG9uZSB1c2VzIGxpdGUgdHlwZXMgYW5kIG9uZSB1c2VzIHJlZ3VsYXIpLCB5b3UgbWF5IGZpbmQgeW91cnNlbGYKKyAqIHdhbnRpbmcgdG8gbWl4IHRoZSB0d28uICBJbiB0aGlzIGNhc2UgdGhpbmdzIGdldCBtb3JlIGNvbXBsaWNhdGVkLgorICogPHA+CisgKiBUaGVyZSBhcmUgdGhyZWUgZmFjdG9ycyB0byBjb25zaWRlcjogIFdoZXRoZXIgdGhlIHR5cGUgYmVpbmcgZXh0ZW5kZWQgaXMKKyAqIGxpdGUsIHdoZXRoZXIgdGhlIGVtYmVkZGVkIHR5cGUgKGluIHRoZSBjYXNlIG9mIGEgbWVzc2FnZS10eXBlZCBleHRlbnNpb24pCisgKiBpcyBsaXRlLCBhbmQgd2hldGhlciB0aGUgZXh0ZW5zaW9uIGl0c2VsZiBpcyBsaXRlLiAgU2luY2UgYWxsIHRocmVlIGFyZQorICogZGVjbGFyZWQgaW4gZGlmZmVyZW50IGZpbGVzLCB0aGV5IGNvdWxkIGFsbCBiZSBkaWZmZXJlbnQuICBIZXJlIGFyZSBhbGwKKyAqIHRoZSBjb21iaW5hdGlvbnMgYW5kIHdoaWNoIHR5cGUgb2YgcmVnaXN0cnkgdG8gdXNlOgorICogPHByZT4KKyAqICAgRXh0ZW5kZWQgdHlwZSAgICAgSW5uZXIgdHlwZSAgICBFeHRlbnNpb24gICAgICAgICBVc2UgcmVnaXN0cnkKKyAqICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgbGl0ZSAgICAgICAgICAgICAgbGl0ZSAgICAgICAgICBsaXRlICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUKKyAqICAgbGl0ZSAgICAgICAgICAgICAgcmVndWxhciAgICAgICBsaXRlICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeQorICogICByZWd1bGFyICAgICAgICAgICByZWd1bGFyICAgICAgIHJlZ3VsYXIgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5CisgKiAgIGFsbCBvdGhlciBjb21iaW5hdGlvbnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90IHN1cHBvcnRlZAorICogPC9wcmU+CisgKiA8cD4KKyAqIE5vdGUgdGhhdCBqdXN0IGFzIHJlZ3VsYXIgdHlwZXMgYXJlIG5vdCBhbGxvd2VkIHRvIGNvbnRhaW4gbGl0ZS10eXBlIGZpZWxkcywKKyAqIHRoZXkgYXJlIGFsc28gbm90IGFsbG93ZWQgdG8gY29udGFpbiBsaXRlLXR5cGUgZXh0ZW5zaW9ucy4gIFRoaXMgaXMgYmVjYXVzZQorICogcmVndWxhciB0eXBlcyBtdXN0IGJlIGZ1bGx5IGFjY2Vzc2libGUgdmlhIHJlZmxlY3Rpb24sIHdoaWNoIGluIHR1cm4gbWVhbnMKKyAqIHRoYXQgYWxsIHRoZSBpbm5lciBtZXNzYWdlcyBtdXN0IGFsc28gc3VwcG9ydCByZWZsZWN0aW9uLiAgT24gdGhlIG90aGVyIGhhbmQsCisgKiBzaW5jZSByZWd1bGFyIHR5cGVzIGltcGxlbWVudCB0aGUgZW50aXJlIGxpdGUgaW50ZXJmYWNlLCB0aGVyZSBpcyBubyBwcm9ibGVtCisgKiB3aXRoIGVtYmVkZGluZyByZWd1bGFyIHR5cGVzIGluc2lkZSBsaXRlIHR5cGVzLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBjbGFzcyBFeHRlbnNpb25SZWdpc3RyeUxpdGUgeworCisgIC8vIFNldCB0cnVlIHRvIGVuYWJsZSBsYXp5IHBhcnNpbmcgZmVhdHVyZSBmb3IgTWVzc2FnZVNldC4KKyAgLy8KKyAgLy8gVE9ETyh4aWFuZ2wpOiBOb3cgd2UgdXNlIGEgZ2xvYmFsIGZsYWcgdG8gY29udHJvbCB3aGV0aGVyIGVuYWJsZSBsYXp5CisgIC8vIHBhcnNpbmcgZmVhdHVyZSBmb3IgTWVzc2FnZVNldCwgd2hpY2ggbWF5IGJlIHRvbyBjcnVkZSBmb3Igc29tZQorICAvLyBhcHBsaWNhdGlvbnMuIE5lZWQgdG8gc3VwcG9ydCB0aGlzIGZlYXR1cmUgb24gc21hbGxlciBncmFudWxhcml0eS4KKyAgcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBlYWdlcmx5UGFyc2VNZXNzYWdlU2V0cyA9IGZhbHNlOworCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VhZ2VybHlQYXJzZU1lc3NhZ2VTZXRzKCkgeworICAgIHJldHVybiBlYWdlcmx5UGFyc2VNZXNzYWdlU2V0czsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRFYWdlcmx5UGFyc2VNZXNzYWdlU2V0cyhib29sZWFuIGlzRWFnZXJseVBhcnNlKSB7CisgICAgZWFnZXJseVBhcnNlTWVzc2FnZVNldHMgPSBpc0VhZ2VybHlQYXJzZTsKKyAgfQorCisgIC8qKiBDb25zdHJ1Y3QgYSBuZXcsIGVtcHR5IGluc3RhbmNlLiAqLworICBwdWJsaWMgc3RhdGljIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBuZXdJbnN0YW5jZSgpIHsKKyAgICByZXR1cm4gbmV3IEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSgpOworICB9CisKKyAgLyoqIEdldCB0aGUgdW5tb2RpZmlhYmxlIHNpbmdsZXRvbiBlbXB0eSBpbnN0YW5jZS4gKi8KKyAgcHVibGljIHN0YXRpYyBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZ2V0RW1wdHlSZWdpc3RyeSgpIHsKKyAgICByZXR1cm4gRU1QVFk7CisgIH0KKworICAvKiogUmV0dXJucyBhbiB1bm1vZGlmaWFibGUgdmlldyBvZiB0aGUgcmVnaXN0cnkuICovCisgIHB1YmxpYyBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZ2V0VW5tb2RpZmlhYmxlKCkgeworICAgIHJldHVybiBuZXcgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKHRoaXMpOworICB9CisKKyAgLyoqCisgICAqIEZpbmQgYW4gZXh0ZW5zaW9uIGJ5IGNvbnRhaW5pbmcgdHlwZSBhbmQgZmllbGQgbnVtYmVyLgorICAgKgorICAgKiBAcmV0dXJuIEluZm9ybWF0aW9uIGFib3V0IHRoZSBleHRlbnNpb24gaWYgZm91bmQsIG9yIHtAY29kZSBudWxsfQorICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgPENvbnRhaW5pbmdUeXBlIGV4dGVuZHMgTWVzc2FnZUxpdGU+CisgICAgICBHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5HZW5lcmF0ZWRFeHRlbnNpb248Q29udGFpbmluZ1R5cGUsID8+CisgICAgICAgIGZpbmRMaXRlRXh0ZW5zaW9uQnlOdW1iZXIoCisgICAgICAgICAgZmluYWwgQ29udGFpbmluZ1R5cGUgY29udGFpbmluZ1R5cGVEZWZhdWx0SW5zdGFuY2UsCisgICAgICAgICAgZmluYWwgaW50IGZpZWxkTnVtYmVyKSB7CisgICAgcmV0dXJuIChHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5HZW5lcmF0ZWRFeHRlbnNpb248Q29udGFpbmluZ1R5cGUsID8+KQorICAgICAgZXh0ZW5zaW9uc0J5TnVtYmVyLmdldCgKKyAgICAgICAgbmV3IE9iamVjdEludFBhaXIoY29udGFpbmluZ1R5cGVEZWZhdWx0SW5zdGFuY2UsIGZpZWxkTnVtYmVyKSk7CisgIH0KKworICAvKiogQWRkIGFuIGV4dGVuc2lvbiBmcm9tIGEgbGl0ZSBnZW5lcmF0ZWQgZmlsZSB0byB0aGUgcmVnaXN0cnkuICovCisgIHB1YmxpYyBmaW5hbCB2b2lkIGFkZCgKKyAgICAgIGZpbmFsIEdlbmVyYXRlZE1lc3NhZ2VMaXRlLkdlbmVyYXRlZEV4dGVuc2lvbjw/LCA/PiBleHRlbnNpb24pIHsKKyAgICBleHRlbnNpb25zQnlOdW1iZXIucHV0KAorICAgICAgbmV3IE9iamVjdEludFBhaXIoZXh0ZW5zaW9uLmdldENvbnRhaW5pbmdUeXBlRGVmYXVsdEluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZ2V0TnVtYmVyKCkpLAorICAgICAgZXh0ZW5zaW9uKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIFByaXZhdGUgc3R1ZmYuCisKKyAgLy8gQ29uc3RydWN0b3JzIGFyZSBwYWNrYWdlLXByaXZhdGUgc28gdGhhdCBFeHRlbnNpb25SZWdpc3RyeSBjYW4gc3ViY2xhc3MKKyAgLy8gdGhpcy4KKworICBFeHRlbnNpb25SZWdpc3RyeUxpdGUoKSB7CisgICAgdGhpcy5leHRlbnNpb25zQnlOdW1iZXIgPQorICAgICAgICBuZXcgSGFzaE1hcDxPYmplY3RJbnRQYWlyLAorICAgICAgICAgICAgICAgICAgICBHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5HZW5lcmF0ZWRFeHRlbnNpb248PywgPz4+KCk7CisgIH0KKworICBFeHRlbnNpb25SZWdpc3RyeUxpdGUoRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIG90aGVyKSB7CisgICAgaWYgKG90aGVyID09IEVNUFRZKSB7CisgICAgICB0aGlzLmV4dGVuc2lvbnNCeU51bWJlciA9IENvbGxlY3Rpb25zLmVtcHR5TWFwKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHRoaXMuZXh0ZW5zaW9uc0J5TnVtYmVyID0KKyAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG90aGVyLmV4dGVuc2lvbnNCeU51bWJlcik7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBNYXA8T2JqZWN0SW50UGFpciwKKyAgICAgICAgICAgICAgICAgICAgR2VuZXJhdGVkTWVzc2FnZUxpdGUuR2VuZXJhdGVkRXh0ZW5zaW9uPD8sID8+PgorICAgICAgZXh0ZW5zaW9uc0J5TnVtYmVyOworCisgIHByaXZhdGUgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKGJvb2xlYW4gZW1wdHkpIHsKKyAgICB0aGlzLmV4dGVuc2lvbnNCeU51bWJlciA9IENvbGxlY3Rpb25zLmVtcHR5TWFwKCk7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIEVNUFRZID0KKyAgICBuZXcgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKHRydWUpOworCisgIC8qKiBBIChPYmplY3QsIGludCkgcGFpciwgdXNlZCBhcyBhIG1hcCBrZXkuICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE9iamVjdEludFBhaXIgeworICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IG9iamVjdDsKKyAgICBwcml2YXRlIGZpbmFsIGludCBudW1iZXI7CisKKyAgICBPYmplY3RJbnRQYWlyKGZpbmFsIE9iamVjdCBvYmplY3QsIGZpbmFsIGludCBudW1iZXIpIHsKKyAgICAgIHRoaXMub2JqZWN0ID0gb2JqZWN0OworICAgICAgdGhpcy5udW1iZXIgPSBudW1iZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZShvYmplY3QpICogKCgxIDw8IDE2KSAtIDEpICsgbnVtYmVyOworICAgIH0KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG9iaikgeworICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgT2JqZWN0SW50UGFpcikpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgZmluYWwgT2JqZWN0SW50UGFpciBvdGhlciA9IChPYmplY3RJbnRQYWlyKW9iajsKKyAgICAgIHJldHVybiBvYmplY3QgPT0gb3RoZXIub2JqZWN0ICYmIG51bWJlciA9PSBvdGhlci5udW1iZXI7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9GaWVsZFNldC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRmllbGRTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NzkyNGI2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRmllbGRTZXQuamF2YQpAQCAtMCwwICsxLDg4OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkLkxhenlJdGVyYXRvcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQSBjbGFzcyB3aGljaCByZXByZXNlbnRzIGFuIGFyYml0cmFyeSBzZXQgb2YgZmllbGRzIG9mIHNvbWUgbWVzc2FnZSB0eXBlLgorICogVGhpcyBpcyB1c2VkIHRvIGltcGxlbWVudCB7QGxpbmsgRHluYW1pY01lc3NhZ2V9LCBhbmQgYWxzbyB0byByZXByZXNlbnQKKyAqIGV4dGVuc2lvbnMgaW4ge0BsaW5rIEdlbmVyYXRlZE1lc3NhZ2V9LiAgVGhpcyBjbGFzcyBpcyBwYWNrYWdlLXByaXZhdGUsCisgKiBzaW5jZSBvdXRzaWRlIHVzZXJzIHNob3VsZCBwcm9iYWJseSBiZSB1c2luZyB7QGxpbmsgRHluYW1pY01lc3NhZ2V9LgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK2ZpbmFsIGNsYXNzIEZpZWxkU2V0PEZpZWxkRGVzY3JpcHRvclR5cGUgZXh0ZW5kcworICAgICAgRmllbGRTZXQuRmllbGREZXNjcmlwdG9yTGl0ZTxGaWVsZERlc2NyaXB0b3JUeXBlPj4geworICAvKioKKyAgICogSW50ZXJmYWNlIGZvciBhIEZpZWxkRGVzY3JpcHRvciBvciBsaXRlIGV4dGVuc2lvbiBkZXNjcmlwdG9yLiAgVGhpcworICAgKiBwcmV2ZW50cyBGaWVsZFNldCBmcm9tIGRlcGVuZGluZyBvbiB7QGxpbmsgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yfS4KKyAgICovCisgIHB1YmxpYyBpbnRlcmZhY2UgRmllbGREZXNjcmlwdG9yTGl0ZTxUIGV4dGVuZHMgRmllbGREZXNjcmlwdG9yTGl0ZTxUPj4KKyAgICAgIGV4dGVuZHMgQ29tcGFyYWJsZTxUPiB7CisgICAgaW50IGdldE51bWJlcigpOworICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIGdldExpdGVUeXBlKCk7CisgICAgV2lyZUZvcm1hdC5KYXZhVHlwZSBnZXRMaXRlSmF2YVR5cGUoKTsKKyAgICBib29sZWFuIGlzUmVwZWF0ZWQoKTsKKyAgICBib29sZWFuIGlzUGFja2VkKCk7CisgICAgSW50ZXJuYWwuRW51bUxpdGVNYXA8Pz4gZ2V0RW51bVR5cGUoKTsKKworICAgIC8vIElmIGdldExpdGVKYXZhVHlwZSgpID09IE1FU1NBR0UsIHRoaXMgbWVyZ2VzIGEgbWVzc2FnZSBvYmplY3Qgb2YgdGhlCisgICAgLy8gdHlwZSBpbnRvIGEgYnVpbGRlciBvZiB0aGUgdHlwZS4gIFJldHVybnMge0Bjb2RlIHRvfS4KKyAgICBNZXNzYWdlTGl0ZS5CdWlsZGVyIGludGVybmFsTWVyZ2VGcm9tKAorICAgICAgICBNZXNzYWdlTGl0ZS5CdWlsZGVyIHRvLCBNZXNzYWdlTGl0ZSBmcm9tKTsKKyAgfQorCisgIHByaXZhdGUgZmluYWwgU21hbGxTb3J0ZWRNYXA8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBmaWVsZHM7CisgIHByaXZhdGUgYm9vbGVhbiBpc0ltbXV0YWJsZTsKKyAgcHJpdmF0ZSBib29sZWFuIGhhc0xhenlGaWVsZCA9IGZhbHNlOworCisgIC8qKiBDb25zdHJ1Y3QgYSBuZXcgRmllbGRTZXQuICovCisgIHByaXZhdGUgRmllbGRTZXQoKSB7CisgICAgdGhpcy5maWVsZHMgPSBTbWFsbFNvcnRlZE1hcC5uZXdGaWVsZE1hcCgxNik7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0IGFuIGVtcHR5IEZpZWxkU2V0LiAgVGhpcyBpcyBvbmx5IHVzZWQgdG8gaW5pdGlhbGl6ZQorICAgKiBERUZBVUxUX0lOU1RBTkNFLgorICAgKi8KKyAgcHJpdmF0ZSBGaWVsZFNldChmaW5hbCBib29sZWFuIGR1bW15KSB7CisgICAgdGhpcy5maWVsZHMgPSBTbWFsbFNvcnRlZE1hcC5uZXdGaWVsZE1hcCgwKTsKKyAgICBtYWtlSW1tdXRhYmxlKCk7CisgIH0KKworICAvKiogQ29uc3RydWN0IGEgbmV3IEZpZWxkU2V0LiAqLworICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgRmllbGRTZXQuRmllbGREZXNjcmlwdG9yTGl0ZTxUPj4KKyAgICAgIEZpZWxkU2V0PFQ+IG5ld0ZpZWxkU2V0KCkgeworICAgIHJldHVybiBuZXcgRmllbGRTZXQ8VD4oKTsKKyAgfQorCisgIC8qKiBHZXQgYW4gaW1tdXRhYmxlIGVtcHR5IEZpZWxkU2V0LiAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIEZpZWxkU2V0LkZpZWxkRGVzY3JpcHRvckxpdGU8VD4+CisgICAgICBGaWVsZFNldDxUPiBlbXB0eVNldCgpIHsKKyAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKKyAgfQorICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZFNldCBERUZBVUxUX0lOU1RBTkNFID0gbmV3IEZpZWxkU2V0KHRydWUpOworCisgIC8qKiBNYWtlIHRoaXMgRmllbGRTZXQgaW1tdXRhYmxlIGZyb20gdGhpcyBwb2ludCBmb3J3YXJkLiAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHZvaWQgbWFrZUltbXV0YWJsZSgpIHsKKyAgICBpZiAoaXNJbW11dGFibGUpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgZmllbGRzLm1ha2VJbW11dGFibGUoKTsKKyAgICBpc0ltbXV0YWJsZSA9IHRydWU7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBGaWVsZFNldCBpcyBpbW11dGFibGUuIFRoaXMgaXMgdHJ1ZSBpZiBpdCBpcyB0aGUKKyAgICoge0BsaW5rICNlbXB0eVNldH0gb3IgaWYge0BsaW5rICNtYWtlSW1tdXRhYmxlfSB3ZXJlIGNhbGxlZC4KKyAgICoKKyAgICogQHJldHVybiB3aGV0aGVyIHRoZSBGaWVsZFNldCBpcyBpbW11dGFibGUuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0ltbXV0YWJsZSgpIHsKKyAgICByZXR1cm4gaXNJbW11dGFibGU7CisgIH0KKworICAvKioKKyAgICogQ2xvbmVzIHRoZSBGaWVsZFNldC4gVGhlIHJldHVybmVkIEZpZWxkU2V0IHdpbGwgYmUgbXV0YWJsZSBldmVuIGlmIHRoZQorICAgKiBvcmlnaW5hbCBGaWVsZFNldCB3YXMgaW1tdXRhYmxlLgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBuZXdseSBjbG9uZWQgRmllbGRTZXQKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgRmllbGRTZXQ8RmllbGREZXNjcmlwdG9yVHlwZT4gY2xvbmUoKSB7CisgICAgLy8gV2UgY2FuJ3QganVzdCBjYWxsIGZpZWxkcy5jbG9uZSBiZWNhdXNlIExpc3Qgb2JqZWN0cyBpbiB0aGUgbWFwCisgICAgLy8gc2hvdWxkIG5vdCBiZSBzaGFyZWQuCisgICAgRmllbGRTZXQ8RmllbGREZXNjcmlwdG9yVHlwZT4gY2xvbmUgPSBGaWVsZFNldC5uZXdGaWVsZFNldCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmdldE51bUFycmF5RW50cmllcygpOyBpKyspIHsKKyAgICAgIE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3JUeXBlLCBPYmplY3Q+IGVudHJ5ID0gZmllbGRzLmdldEFycmF5RW50cnlBdChpKTsKKyAgICAgIEZpZWxkRGVzY3JpcHRvclR5cGUgZGVzY3JpcHRvciA9IGVudHJ5LmdldEtleSgpOworICAgICAgY2xvbmUuc2V0RmllbGQoZGVzY3JpcHRvciwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgfQorICAgIGZvciAoTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnkgOgorICAgICAgICAgICAgIGZpZWxkcy5nZXRPdmVyZmxvd0VudHJpZXMoKSkgeworICAgICAgRmllbGREZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICBjbG9uZS5zZXRGaWVsZChkZXNjcmlwdG9yLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgY2xvbmUuaGFzTGF6eUZpZWxkID0gaGFzTGF6eUZpZWxkOworICAgIHJldHVybiBjbG9uZTsKKyAgfQorCisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKiogU2VlIHtAbGluayBNZXNzYWdlLkJ1aWxkZXIjY2xlYXIoKX0uICovCisgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgIGZpZWxkcy5jbGVhcigpOworICAgIGhhc0xhenlGaWVsZCA9IGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIHNpbXBsZSBtYXAgY29udGFpbmluZyBhbGwgdGhlIGZpZWxkcy4KKyAgICovCisgIHB1YmxpYyBNYXA8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBnZXRBbGxGaWVsZHMoKSB7CisgICAgaWYgKGhhc0xhenlGaWVsZCkgeworICAgICAgU21hbGxTb3J0ZWRNYXA8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiByZXN1bHQgPQorICAgICAgICAgIFNtYWxsU29ydGVkTWFwLm5ld0ZpZWxkTWFwKDE2KTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmdldE51bUFycmF5RW50cmllcygpOyBpKyspIHsKKyAgICAgICAgY2xvbmVGaWVsZEVudHJ5KHJlc3VsdCwgZmllbGRzLmdldEFycmF5RW50cnlBdChpKSk7CisgICAgICB9CisgICAgICBmb3IgKE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3JUeXBlLCBPYmplY3Q+IGVudHJ5IDoKKyAgICAgICAgICBmaWVsZHMuZ2V0T3ZlcmZsb3dFbnRyaWVzKCkpIHsKKyAgICAgICAgY2xvbmVGaWVsZEVudHJ5KHJlc3VsdCwgZW50cnkpOworICAgICAgfQorICAgICAgaWYgKGZpZWxkcy5pc0ltbXV0YWJsZSgpKSB7CisgICAgICAgIHJlc3VsdC5tYWtlSW1tdXRhYmxlKCk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICByZXR1cm4gZmllbGRzLmlzSW1tdXRhYmxlKCkgPyBmaWVsZHMgOiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoZmllbGRzKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBjbG9uZUZpZWxkRW50cnkoTWFwPEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gbWFwLAorICAgICAgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnkpIHsKKyAgICBGaWVsZERlc2NyaXB0b3JUeXBlIGtleSA9IGVudHJ5LmdldEtleSgpOworICAgIE9iamVjdCB2YWx1ZSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTGF6eUZpZWxkKSB7CisgICAgICBtYXAucHV0KGtleSwgKChMYXp5RmllbGQpIHZhbHVlKS5nZXRWYWx1ZSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgbWFwLnB1dChrZXksIHZhbHVlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogR2V0IGFuIGl0ZXJhdG9yIHRvIHRoZSBmaWVsZCBtYXAuIFRoaXMgaXRlcmF0b3Igc2hvdWxkIG5vdCBiZSBsZWFrZWQgb3V0CisgICAqIG9mIHRoZSBwcm90b2J1ZiBsaWJyYXJ5IGFzIGl0IGlzIG5vdCBwcm90ZWN0ZWQgZnJvbSBtdXRhdGlvbiB3aGVuIGZpZWxkcworICAgKiBpcyBub3QgaW1tdXRhYmxlLgorICAgKi8KKyAgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3JUeXBlLCBPYmplY3Q+PiBpdGVyYXRvcigpIHsKKyAgICBpZiAoaGFzTGF6eUZpZWxkKSB7CisgICAgICByZXR1cm4gbmV3IExhenlJdGVyYXRvcjxGaWVsZERlc2NyaXB0b3JUeXBlPigKKyAgICAgICAgICBmaWVsZHMuZW50cnlTZXQoKS5pdGVyYXRvcigpKTsKKyAgICB9CisgICAgcmV0dXJuIGZpZWxkcy5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgIH0KKworICAvKioKKyAgICogVXNlZnVsIGZvciBpbXBsZW1lbnRpbmcKKyAgICoge0BsaW5rIE1lc3NhZ2UjaGFzRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yKX0uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3JUeXBlIGRlc2NyaXB0b3IpIHsKKyAgICBpZiAoZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJoYXNGaWVsZCgpIGNhbiBvbmx5IGJlIGNhbGxlZCBvbiBub24tcmVwZWF0ZWQgZmllbGRzLiIpOworICAgIH0KKworICAgIHJldHVybiBmaWVsZHMuZ2V0KGRlc2NyaXB0b3IpICE9IG51bGw7CisgIH0KKworICAvKioKKyAgICogVXNlZnVsIGZvciBpbXBsZW1lbnRpbmcKKyAgICoge0BsaW5rIE1lc3NhZ2UjZ2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yKX0uICBUaGlzIG1ldGhvZAorICAgKiByZXR1cm5zIHtAY29kZSBudWxsfSBpZiB0aGUgZmllbGQgaXMgbm90IHNldDsgaW4gdGhpcyBjYXNlIGl0IGlzIHVwCisgICAqIHRvIHRoZSBjYWxsZXIgdG8gZmV0Y2ggdGhlIGZpZWxkJ3MgZGVmYXVsdCB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yKSB7CisgICAgT2JqZWN0IG8gPSBmaWVsZHMuZ2V0KGRlc2NyaXB0b3IpOworICAgIGlmIChvIGluc3RhbmNlb2YgTGF6eUZpZWxkKSB7CisgICAgICByZXR1cm4gKChMYXp5RmllbGQpIG8pLmdldFZhbHVlKCk7CisgICAgfQorICAgIHJldHVybiBvOworICB9CisKKyAgLyoqCisgICAqIFVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nCisgICAqIHtAbGluayBNZXNzYWdlLkJ1aWxkZXIjc2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLE9iamVjdCl9LgorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCAicmF3dHlwZXMifSkKKyAgcHVibGljIHZvaWQgc2V0RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpIHsKKyAgICBpZiAoZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgTGlzdCkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiV3Jvbmcgb2JqZWN0IHR5cGUgdXNlZCB3aXRoIHByb3RvY29sIG1lc3NhZ2UgcmVmbGVjdGlvbi4iKTsKKyAgICAgIH0KKworICAgICAgLy8gV3JhcCB0aGUgY29udGVudHMgaW4gYSBuZXcgbGlzdCBzbyB0aGF0IHRoZSBjYWxsZXIgY2Fubm90IGNoYW5nZQorICAgICAgLy8gdGhlIGxpc3QncyBjb250ZW50cyBhZnRlciBzZXR0aW5nIGl0LgorICAgICAgZmluYWwgTGlzdCBuZXdMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgbmV3TGlzdC5hZGRBbGwoKExpc3QpIHZhbHVlKTsKKyAgICAgIGZvciAoZmluYWwgT2JqZWN0IGVsZW1lbnQgOiBuZXdMaXN0KSB7CisgICAgICAgIHZlcmlmeVR5cGUoZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpLCBlbGVtZW50KTsKKyAgICAgIH0KKyAgICAgIHZhbHVlID0gbmV3TGlzdDsKKyAgICB9IGVsc2UgeworICAgICAgdmVyaWZ5VHlwZShkZXNjcmlwdG9yLmdldExpdGVUeXBlKCksIHZhbHVlKTsKKyAgICB9CisKKyAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMYXp5RmllbGQpIHsKKyAgICAgIGhhc0xhenlGaWVsZCA9IHRydWU7CisgICAgfQorICAgIGZpZWxkcy5wdXQoZGVzY3JpcHRvciwgdmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIFVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nCisgICAqIHtAbGluayBNZXNzYWdlLkJ1aWxkZXIjY2xlYXJGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IpfS4KKyAgICovCisgIHB1YmxpYyB2b2lkIGNsZWFyRmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yKSB7CisgICAgZmllbGRzLnJlbW92ZShkZXNjcmlwdG9yKTsKKyAgICBpZiAoZmllbGRzLmlzRW1wdHkoKSkgeworICAgICAgaGFzTGF6eUZpZWxkID0gZmFsc2U7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nCisgICAqIHtAbGluayBNZXNzYWdlI2dldFJlcGVhdGVkRmllbGRDb3VudChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IpfS4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpbmFsIEZpZWxkRGVzY3JpcHRvclR5cGUgZGVzY3JpcHRvcikgeworICAgIGlmICghZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkKCkgY2FuIG9ubHkgYmUgY2FsbGVkIG9uIHJlcGVhdGVkIGZpZWxkcy4iKTsKKyAgICB9CisKKyAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBnZXRGaWVsZChkZXNjcmlwdG9yKTsKKyAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAoKExpc3Q8Pz4pIHZhbHVlKS5zaXplKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nCisgICAqIHtAbGluayBNZXNzYWdlI2dldFJlcGVhdGVkRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLGludCl9LgorICAgKi8KKyAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZEZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvclR5cGUgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCkgeworICAgIGlmICghZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkKCkgY2FuIG9ubHkgYmUgY2FsbGVkIG9uIHJlcGVhdGVkIGZpZWxkcy4iKTsKKyAgICB9CisKKyAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBnZXRGaWVsZChkZXNjcmlwdG9yKTsKKworICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gKChMaXN0PD8+KSB2YWx1ZSkuZ2V0KGluZGV4KTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogVXNlZnVsIGZvciBpbXBsZW1lbnRpbmcKKyAgICoge0BsaW5rIE1lc3NhZ2UuQnVpbGRlciNzZXRSZXBlYXRlZEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcixpbnQsT2JqZWN0KX0uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHZvaWQgc2V0UmVwZWF0ZWRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3JUeXBlIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgIGlmICghZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkKCkgY2FuIG9ubHkgYmUgY2FsbGVkIG9uIHJlcGVhdGVkIGZpZWxkcy4iKTsKKyAgICB9CisKKyAgICBmaW5hbCBPYmplY3QgbGlzdCA9IGdldEZpZWxkKGRlc2NyaXB0b3IpOworICAgIGlmIChsaXN0ID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgdmVyaWZ5VHlwZShkZXNjcmlwdG9yLmdldExpdGVUeXBlKCksIHZhbHVlKTsKKyAgICAoKExpc3Q8T2JqZWN0PikgbGlzdCkuc2V0KGluZGV4LCB2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogVXNlZnVsIGZvciBpbXBsZW1lbnRpbmcKKyAgICoge0BsaW5rIE1lc3NhZ2UuQnVpbGRlciNhZGRSZXBlYXRlZEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcixPYmplY3QpfS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgdm9pZCBhZGRSZXBlYXRlZEZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvclR5cGUgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICBpZiAoIWRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAiYWRkUmVwZWF0ZWRGaWVsZCgpIGNhbiBvbmx5IGJlIGNhbGxlZCBvbiByZXBlYXRlZCBmaWVsZHMuIik7CisgICAgfQorCisgICAgdmVyaWZ5VHlwZShkZXNjcmlwdG9yLmdldExpdGVUeXBlKCksIHZhbHVlKTsKKworICAgIGZpbmFsIE9iamVjdCBleGlzdGluZ1ZhbHVlID0gZ2V0RmllbGQoZGVzY3JpcHRvcik7CisgICAgTGlzdDxPYmplY3Q+IGxpc3Q7CisgICAgaWYgKGV4aXN0aW5nVmFsdWUgPT0gbnVsbCkgeworICAgICAgbGlzdCA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpOworICAgICAgZmllbGRzLnB1dChkZXNjcmlwdG9yLCBsaXN0KTsKKyAgICB9IGVsc2UgeworICAgICAgbGlzdCA9IChMaXN0PE9iamVjdD4pIGV4aXN0aW5nVmFsdWU7CisgICAgfQorCisgICAgbGlzdC5hZGQodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQgdGhlIGdpdmVuIG9iamVjdCBpcyBvZiB0aGUgY29ycmVjdCB0eXBlIHRvIGJlIGEgdmFsaWQKKyAgICogdmFsdWUgZm9yIHRoZSBnaXZlbiBmaWVsZC4gIChGb3IgcmVwZWF0ZWQgZmllbGRzLCB0aGlzIGNoZWNrcyBpZiB0aGUKKyAgICogb2JqZWN0IGlzIHRoZSByaWdodCB0eXBlIHRvIGJlIG9uZSBlbGVtZW50IG9mIHRoZSBmaWVsZC4pCisgICAqCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFRoZSB2YWx1ZSBpcyBub3Qgb2YgdGhlIHJpZ2h0IHR5cGUuCisgICAqLworICBwcml2YXRlIHN0YXRpYyB2b2lkIHZlcmlmeVR5cGUoZmluYWwgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBib29sZWFuIGlzVmFsaWQgPSBmYWxzZTsKKyAgICBzd2l0Y2ggKHR5cGUuZ2V0SmF2YVR5cGUoKSkgeworICAgICAgY2FzZSBJTlQ6ICAgICAgICAgIGlzVmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIgICA7IGJyZWFrOworICAgICAgY2FzZSBMT05HOiAgICAgICAgIGlzVmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIExvbmcgICAgICA7IGJyZWFrOworICAgICAgY2FzZSBGTE9BVDogICAgICAgIGlzVmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIEZsb2F0ICAgICA7IGJyZWFrOworICAgICAgY2FzZSBET1VCTEU6ICAgICAgIGlzVmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIERvdWJsZSAgICA7IGJyZWFrOworICAgICAgY2FzZSBCT09MRUFOOiAgICAgIGlzVmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4gICA7IGJyZWFrOworICAgICAgY2FzZSBTVFJJTkc6ICAgICAgIGlzVmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZyAgICA7IGJyZWFrOworICAgICAgY2FzZSBCWVRFX1NUUklORzoKKyAgICAgICAgaXNWYWxpZCA9IHZhbHVlIGluc3RhbmNlb2YgQnl0ZVN0cmluZyB8fCB2YWx1ZSBpbnN0YW5jZW9mIGJ5dGVbXTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEVOVU06CisgICAgICAgIC8vIFRPRE8oa2VudG9uKTogIENhbGxlciBtdXN0IGRvIHR5cGUgY2hlY2tpbmcgaGVyZSwgSSBndWVzcy4KKyAgICAgICAgaXNWYWxpZCA9CisgICAgICAgICAgICAodmFsdWUgaW5zdGFuY2VvZiBJbnRlZ2VyIHx8IHZhbHVlIGluc3RhbmNlb2YgSW50ZXJuYWwuRW51bUxpdGUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTUVTU0FHRToKKyAgICAgICAgLy8gVE9ETyhrZW50b24pOiAgQ2FsbGVyIG11c3QgZG8gdHlwZSBjaGVja2luZyBoZXJlLCBJIGd1ZXNzLgorICAgICAgICBpc1ZhbGlkID0KKyAgICAgICAgICAgICh2YWx1ZSBpbnN0YW5jZW9mIE1lc3NhZ2VMaXRlKSB8fCAodmFsdWUgaW5zdGFuY2VvZiBMYXp5RmllbGQpOworICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICBpZiAoIWlzVmFsaWQpIHsKKyAgICAgIC8vIFRPRE8oa2VudG9uKTogIFdoZW4gY2hhaW5pbmcgY2FsbHMgdG8gc2V0RmllbGQoKSwgaXQgY2FuIGJlIGhhcmQgdG8KKyAgICAgIC8vICAgdGVsbCBmcm9tIHRoZSBzdGFjayB0cmFjZSB3aGljaCBleGFjdCBjYWxsIGZhaWxlZCwgc2luY2UgdGhlIHdob2xlCisgICAgICAvLyAgIGNoYWluIGlzIGNvbnNpZGVyZWQgb25lIGxpbmUgb2YgY29kZS4gIEl0IHdvdWxkIGJlIG5pY2UgdG8gcHJpbnQKKyAgICAgIC8vICAgbW9yZSBpbmZvcm1hdGlvbiBoZXJlLCBlLmcuIG5hbWluZyB0aGUgZmllbGQuICBXZSB1c2VkIHRvIGRvIHRoYXQuCisgICAgICAvLyAgIEJ1dCB3ZSBjYW4ndCBub3cgdGhhdCBGaWVsZFNldCBkb2Vzbid0IHVzZSBkZXNjcmlwdG9ycy4gIE1heWJlIHRoaXMKKyAgICAgIC8vICAgaXNuJ3QgYSBiaWcgZGVhbCwgdGhvdWdoLCBzaW5jZSBpdCB3b3VsZCBvbmx5IHJlYWxseSBhcHBseSB3aGVuIHVzaW5nCisgICAgICAvLyAgIHJlZmxlY3Rpb24gYW5kIGdlbmVyYWxseSBwZW9wbGUgZG9uJ3QgY2hhaW4gcmVmbGVjdGlvbiBzZXR0ZXJzLgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgIldyb25nIG9iamVjdCB0eXBlIHVzZWQgd2l0aCBwcm90b2NvbCBtZXNzYWdlIHJlZmxlY3Rpb24uIik7CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gUGFyc2luZyBhbmQgc2VyaWFsaXphdGlvbgorCisgIC8qKgorICAgKiBTZWUge0BsaW5rIE1lc3NhZ2UjaXNJbml0aWFsaXplZCgpfS4gIE5vdGU6ICBTaW5jZSB7QGNvZGUgRmllbGRTZXR9CisgICAqIGl0c2VsZiBkb2VzIG5vdCBoYXZlIGFueSB3YXkgb2Yga25vd2luZyBhYm91dCByZXF1aXJlZCBmaWVsZHMgdGhhdAorICAgKiBhcmVuJ3QgYWN0dWFsbHkgcHJlc2VudCBpbiB0aGUgc2V0LCBpdCBpcyB1cCB0byB0aGUgY2FsbGVyIHRvIGNoZWNrCisgICAqIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudC4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuZ2V0TnVtQXJyYXlFbnRyaWVzKCk7IGkrKykgeworICAgICAgaWYgKCFpc0luaXRpYWxpemVkKGZpZWxkcy5nZXRBcnJheUVudHJ5QXQoaSkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgZm9yIChmaW5hbCBNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSA6CisgICAgICAgICAgICAgZmllbGRzLmdldE92ZXJmbG93RW50cmllcygpKSB7CisgICAgICBpZiAoIWlzSW5pdGlhbGl6ZWQoZW50cnkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHJpdmF0ZSBib29sZWFuIGlzSW5pdGlhbGl6ZWQoCisgICAgICBmaW5hbCBNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSkgeworICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvclR5cGUgZGVzY3JpcHRvciA9IGVudHJ5LmdldEtleSgpOworICAgIGlmIChkZXNjcmlwdG9yLmdldExpdGVKYXZhVHlwZSgpID09IFdpcmVGb3JtYXQuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgaWYgKGRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIGZvciAoZmluYWwgTWVzc2FnZUxpdGUgZWxlbWVudDoKKyAgICAgICAgICAgICAgICAgKExpc3Q8TWVzc2FnZUxpdGU+KSBlbnRyeS5nZXRWYWx1ZSgpKSB7CisgICAgICAgICAgaWYgKCFlbGVtZW50LmlzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWVzc2FnZUxpdGUpIHsKKyAgICAgICAgICBpZiAoISgoTWVzc2FnZUxpdGUpIHZhbHVlKS5pc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBMYXp5RmllbGQpIHsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAiV3Jvbmcgb2JqZWN0IHR5cGUgdXNlZCB3aXRoIHByb3RvY29sIG1lc3NhZ2UgcmVmbGVjdGlvbi4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBHaXZlbiBhIGZpZWxkIHR5cGUsIHJldHVybiB0aGUgd2lyZSB0eXBlLgorICAgKgorICAgKiBAcmV0dXJucyBPbmUgb2YgdGhlIHtAY29kZSBXSVJFVFlQRV99IGNvbnN0YW50cyBkZWZpbmVkIGluCisgICAqICAgICAgICAgIHtAbGluayBXaXJlRm9ybWF0fS4KKyAgICovCisgIHN0YXRpYyBpbnQgZ2V0V2lyZUZvcm1hdEZvckZpZWxkVHlwZShmaW5hbCBXaXJlRm9ybWF0LkZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc1BhY2tlZCkgeworICAgIGlmIChpc1BhY2tlZCkgeworICAgICAgcmV0dXJuIFdpcmVGb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRDsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIHR5cGUuZ2V0V2lyZVR5cGUoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgTWVzc2FnZS5CdWlsZGVyI21lcmdlRnJvbShNZXNzYWdlKX0sIGJ1dCBtZXJnZXMgZnJvbSBhbm90aGVyIAorICAgKiB7QGxpbmsgRmllbGRTZXR9LgorICAgKi8KKyAgcHVibGljIHZvaWQgbWVyZ2VGcm9tKGZpbmFsIEZpZWxkU2V0PEZpZWxkRGVzY3JpcHRvclR5cGU+IG90aGVyKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdGhlci5maWVsZHMuZ2V0TnVtQXJyYXlFbnRyaWVzKCk7IGkrKykgeworICAgICAgbWVyZ2VGcm9tRmllbGQob3RoZXIuZmllbGRzLmdldEFycmF5RW50cnlBdChpKSk7CisgICAgfQorICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnkgOgorICAgICAgICAgICAgIG90aGVyLmZpZWxkcy5nZXRPdmVyZmxvd0VudHJpZXMoKSkgeworICAgICAgbWVyZ2VGcm9tRmllbGQoZW50cnkpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgT2JqZWN0IGNsb25lSWZNdXRhYmxlKE9iamVjdCB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgYnl0ZVtdIGJ5dGVzID0gKGJ5dGVbXSkgdmFsdWU7CisgICAgICBieXRlW10gY29weSA9IG5ldyBieXRlW2J5dGVzLmxlbmd0aF07CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ5dGVzLCAwLCBjb3B5LCAwLCBieXRlcy5sZW5ndGgpOworICAgICAgcmV0dXJuIGNvcHk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncyh7InVuY2hlY2tlZCIsICJyYXd0eXBlcyJ9KQorICBwcml2YXRlIHZvaWQgbWVyZ2VGcm9tRmllbGQoCisgICAgICBmaW5hbCBNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSkgeworICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvclR5cGUgZGVzY3JpcHRvciA9IGVudHJ5LmdldEtleSgpOworICAgIE9iamVjdCBvdGhlclZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICBpZiAob3RoZXJWYWx1ZSBpbnN0YW5jZW9mIExhenlGaWVsZCkgeworICAgICAgb3RoZXJWYWx1ZSA9ICgoTGF6eUZpZWxkKSBvdGhlclZhbHVlKS5nZXRWYWx1ZSgpOworICAgIH0KKworICAgIGlmIChkZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgT2JqZWN0IHZhbHVlID0gZ2V0RmllbGQoZGVzY3JpcHRvcik7CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB2YWx1ZSA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgIH0KKyAgICAgIGZvciAoT2JqZWN0IGVsZW1lbnQgOiAoTGlzdCkgb3RoZXJWYWx1ZSkgeworICAgICAgICAoKExpc3QpIHZhbHVlKS5hZGQoY2xvbmVJZk11dGFibGUoZWxlbWVudCkpOworICAgICAgfQorICAgICAgZmllbGRzLnB1dChkZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgfSBlbHNlIGlmIChkZXNjcmlwdG9yLmdldExpdGVKYXZhVHlwZSgpID09IFdpcmVGb3JtYXQuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgT2JqZWN0IHZhbHVlID0gZ2V0RmllbGQoZGVzY3JpcHRvcik7CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICBmaWVsZHMucHV0KGRlc2NyaXB0b3IsIGNsb25lSWZNdXRhYmxlKG90aGVyVmFsdWUpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE1lcmdlIHRoZSBtZXNzYWdlcy4KKyAgICAgICAgICB2YWx1ZSA9IGRlc2NyaXB0b3IuaW50ZXJuYWxNZXJnZUZyb20oCisgICAgICAgICAgICAgICAgKChNZXNzYWdlTGl0ZSkgdmFsdWUpLnRvQnVpbGRlcigpLCAoTWVzc2FnZUxpdGUpIG90aGVyVmFsdWUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAgICAgZmllbGRzLnB1dChkZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGZpZWxkcy5wdXQoZGVzY3JpcHRvciwgY2xvbmVJZk11dGFibGUob3RoZXJWYWx1ZSkpOworICAgIH0KKyAgfQorCisgIC8vIFRPRE8oa2VudG9uKTogIE1vdmUgc3RhdGljIHBhcnNpbmcgYW5kIHNlcmlhbGl6YXRpb24gbWV0aG9kcyBpbnRvIHNvbWUKKyAgLy8gICBvdGhlciBjbGFzcy4gIFByb2JhYmx5IFdpcmVGb3JtYXQuCisKKyAgLyoqCisgICAqIFJlYWQgYSBmaWVsZCBvZiBhbnkgcHJpbWl0aXZlIHR5cGUgZm9yIGltbXV0YWJsZSBtZXNzYWdlcyBmcm9tIGEKKyAgICogQ29kZWRJbnB1dFN0cmVhbS4gRW51bXMsIGdyb3VwcywgYW5kIGVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBub3QgaGFuZGxlZCBieQorICAgKiB0aGlzIG1ldGhvZC4KKyAgICoKKyAgICogQHBhcmFtIGlucHV0IFRoZSBzdHJlYW0gZnJvbSB3aGljaCB0byByZWFkLgorICAgKiBAcGFyYW0gdHlwZSBEZWNsYXJlZCB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgICogQHBhcmFtIGNoZWNrVXRmOCBXaGVuIHRydWUsIGNoZWNrIHRoYXQgdGhlIGlucHV0IGlzIHZhbGlkIHV0ZjguCisgICAqIEByZXR1cm4gQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZmllbGQncyB2YWx1ZSwgb2YgdGhlIGV4YWN0CisgICAqICAgICAgICAgdHlwZSB3aGljaCB3b3VsZCBiZSByZXR1cm5lZCBieQorICAgKiAgICAgICAgIHtAbGluayBNZXNzYWdlI2dldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcil9IGZvcgorICAgKiAgICAgICAgIHRoaXMgZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIE9iamVjdCByZWFkUHJpbWl0aXZlRmllbGQoCisgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgZmluYWwgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdHlwZSwKKyAgICAgIGJvb2xlYW4gY2hlY2tVdGY4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChjaGVja1V0ZjgpIHsKKyAgICAgIHJldHVybiBXaXJlRm9ybWF0LnJlYWRQcmltaXRpdmVGaWVsZChpbnB1dCwgdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0LlV0ZjhWYWxpZGF0aW9uLlNUUklDVCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBXaXJlRm9ybWF0LnJlYWRQcmltaXRpdmVGaWVsZChpbnB1dCwgdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0LlV0ZjhWYWxpZGF0aW9uLkxPT1NFKTsKKyAgICB9CisgIH0KKworCisgIC8qKiBTZWUge0BsaW5rIE1lc3NhZ2Ujd3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbSl9LiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVRvKGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKKyAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmdldE51bUFycmF5RW50cmllcygpOyBpKyspIHsKKyAgICAgIGZpbmFsIE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3JUeXBlLCBPYmplY3Q+IGVudHJ5ID0KKyAgICAgICAgICBmaWVsZHMuZ2V0QXJyYXlFbnRyeUF0KGkpOworICAgICAgd3JpdGVGaWVsZChlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKSwgb3V0cHV0KTsKKyAgICB9CisgICAgZm9yIChmaW5hbCBNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSA6CisgICAgICAgICBmaWVsZHMuZ2V0T3ZlcmZsb3dFbnRyaWVzKCkpIHsKKyAgICAgIHdyaXRlRmllbGQoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCksIG91dHB1dCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICN3cml0ZVRvfSBidXQgdXNlcyBNZXNzYWdlU2V0IHdpcmUgZm9ybWF0LgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVNZXNzYWdlU2V0VG8oZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmdldE51bUFycmF5RW50cmllcygpOyBpKyspIHsKKyAgICAgIHdyaXRlTWVzc2FnZVNldFRvKGZpZWxkcy5nZXRBcnJheUVudHJ5QXQoaSksIG91dHB1dCk7CisgICAgfQorICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnkgOgorICAgICAgICAgICAgIGZpZWxkcy5nZXRPdmVyZmxvd0VudHJpZXMoKSkgeworICAgICAgd3JpdGVNZXNzYWdlU2V0VG8oZW50cnksIG91dHB1dCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlTWVzc2FnZVNldFRvKAorICAgICAgZmluYWwgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnksCisgICAgICBmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgRmllbGREZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yID0gZW50cnkuZ2V0S2V5KCk7CisgICAgaWYgKGRlc2NyaXB0b3IuZ2V0TGl0ZUphdmFUeXBlKCkgPT0gV2lyZUZvcm1hdC5KYXZhVHlwZS5NRVNTQUdFICYmCisgICAgICAgICFkZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSAmJiAhZGVzY3JpcHRvci5pc1BhY2tlZCgpKSB7CisgICAgICBPYmplY3QgdmFsdWUgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTGF6eUZpZWxkKSB7CisgICAgICAgIHZhbHVlID0gKChMYXp5RmllbGQpIHZhbHVlKS5nZXRWYWx1ZSgpOworICAgICAgfQorICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZVNldEV4dGVuc2lvbihlbnRyeS5nZXRLZXkoKS5nZXROdW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1lc3NhZ2VMaXRlKSB2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHdyaXRlRmllbGQoZGVzY3JpcHRvciwgZW50cnkuZ2V0VmFsdWUoKSwgb3V0cHV0KTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYSBzaW5nbGUgdGFnLXZhbHVlIHBhaXIgdG8gdGhlIHN0cmVhbS4KKyAgICoKKyAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbS4KKyAgICogQHBhcmFtIHR5cGUgICBUaGUgZmllbGQncyB0eXBlLgorICAgKiBAcGFyYW0gbnVtYmVyIFRoZSBmaWVsZCdzIG51bWJlci4KKyAgICogQHBhcmFtIHZhbHVlICBPYmplY3QgcmVwcmVzZW50aW5nIHRoZSBmaWVsZCdzIHZhbHVlLiAgTXVzdCBiZSBvZiB0aGUgZXhhY3QKKyAgICogICAgICAgICAgICAgICB0eXBlIHdoaWNoIHdvdWxkIGJlIHJldHVybmVkIGJ5CisgICAqICAgICAgICAgICAgICAge0BsaW5rIE1lc3NhZ2UjZ2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yKX0gZm9yCisgICAqICAgICAgICAgICAgICAgdGhpcyBmaWVsZC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGVFbGVtZW50KGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgZ3JvdXBzLCB3aGljaCBuZWVkIGEgc3RhcnQgYW5kIGVuZCB0YWc7IG90aGVyIGZpZWxkcworICAgIC8vIGNhbiBqdXN0IHVzZSB3cml0ZVRhZygpIGFuZCB3cml0ZUZpZWxkTm9UYWcoKS4KKyAgICBpZiAodHlwZSA9PSBXaXJlRm9ybWF0LkZpZWxkVHlwZS5HUk9VUCkgeworICAgICAgICBvdXRwdXQud3JpdGVHcm91cChudW1iZXIsIChNZXNzYWdlTGl0ZSkgdmFsdWUpOworICAgIH0gZWxzZSB7CisgICAgICBvdXRwdXQud3JpdGVUYWcobnVtYmVyLCBnZXRXaXJlRm9ybWF0Rm9yRmllbGRUeXBlKHR5cGUsIGZhbHNlKSk7CisgICAgICB3cml0ZUVsZW1lbnROb1RhZyhvdXRwdXQsIHR5cGUsIHZhbHVlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYSBmaWVsZCBvZiBhcmJpdHJhcnkgdHlwZSwgd2l0aG91dCBpdHMgdGFnLCB0byB0aGUgc3RyZWFtLgorICAgKgorICAgKiBAcGFyYW0gb3V0cHV0IFRoZSBvdXRwdXQgc3RyZWFtLgorICAgKiBAcGFyYW0gdHlwZSBUaGUgZmllbGQncyB0eXBlLgorICAgKiBAcGFyYW0gdmFsdWUgIE9iamVjdCByZXByZXNlbnRpbmcgdGhlIGZpZWxkJ3MgdmFsdWUuICBNdXN0IGJlIG9mIHRoZSBleGFjdAorICAgKiAgICAgICAgICAgICAgIHR5cGUgd2hpY2ggd291bGQgYmUgcmV0dXJuZWQgYnkKKyAgICogICAgICAgICAgICAgICB7QGxpbmsgTWVzc2FnZSNnZXRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IpfSBmb3IKKyAgICogICAgICAgICAgICAgICB0aGlzIGZpZWxkLgorICAgKi8KKyAgc3RhdGljIHZvaWQgd3JpdGVFbGVtZW50Tm9UYWcoCisgICAgICBmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQsCisgICAgICBmaW5hbCBXaXJlRm9ybWF0LkZpZWxkVHlwZSB0eXBlLAorICAgICAgZmluYWwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgY2FzZSBET1VCTEUgIDogb3V0cHV0LndyaXRlRG91YmxlTm9UYWcgICgoRG91YmxlICAgICApIHZhbHVlKTsgYnJlYWs7CisgICAgICBjYXNlIEZMT0FUICAgOiBvdXRwdXQud3JpdGVGbG9hdE5vVGFnICAgKChGbG9hdCAgICAgICkgdmFsdWUpOyBicmVhazsKKyAgICAgIGNhc2UgSU5UNjQgICA6IG91dHB1dC53cml0ZUludDY0Tm9UYWcgICAoKExvbmcgICAgICAgKSB2YWx1ZSk7IGJyZWFrOworICAgICAgY2FzZSBVSU5UNjQgIDogb3V0cHV0LndyaXRlVUludDY0Tm9UYWcgICgoTG9uZyAgICAgICApIHZhbHVlKTsgYnJlYWs7CisgICAgICBjYXNlIElOVDMyICAgOiBvdXRwdXQud3JpdGVJbnQzMk5vVGFnICAgKChJbnRlZ2VyICAgICkgdmFsdWUpOyBicmVhazsKKyAgICAgIGNhc2UgRklYRUQ2NCA6IG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyAoKExvbmcgICAgICAgKSB2YWx1ZSk7IGJyZWFrOworICAgICAgY2FzZSBGSVhFRDMyIDogb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnICgoSW50ZWdlciAgICApIHZhbHVlKTsgYnJlYWs7CisgICAgICBjYXNlIEJPT0wgICAgOiBvdXRwdXQud3JpdGVCb29sTm9UYWcgICAgKChCb29sZWFuICAgICkgdmFsdWUpOyBicmVhazsKKyAgICAgIGNhc2UgR1JPVVAgICA6IG91dHB1dC53cml0ZUdyb3VwTm9UYWcgICAoKE1lc3NhZ2VMaXRlKSB2YWx1ZSk7IGJyZWFrOworICAgICAgY2FzZSBNRVNTQUdFIDogb3V0cHV0LndyaXRlTWVzc2FnZU5vVGFnICgoTWVzc2FnZUxpdGUpIHZhbHVlKTsgYnJlYWs7CisgICAgICBjYXNlIFNUUklORzoKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQnl0ZVN0cmluZykgeworICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGVzTm9UYWcoKEJ5dGVTdHJpbmcpIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBvdXRwdXQud3JpdGVTdHJpbmdOb1RhZygoU3RyaW5nKSB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEJZVEVTOgorICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCeXRlU3RyaW5nKSB7CisgICAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXNOb1RhZygoQnl0ZVN0cmluZykgdmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGVBcnJheU5vVGFnKChieXRlW10pIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVUlOVDMyICA6IG91dHB1dC53cml0ZVVJbnQzMk5vVGFnICAoKEludGVnZXIgICAgKSB2YWx1ZSk7IGJyZWFrOworICAgICAgY2FzZSBTRklYRUQzMjogb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZygoSW50ZWdlciAgICApIHZhbHVlKTsgYnJlYWs7CisgICAgICBjYXNlIFNGSVhFRDY0OiBvdXRwdXQud3JpdGVTRml4ZWQ2NE5vVGFnKChMb25nICAgICAgICkgdmFsdWUpOyBicmVhazsKKyAgICAgIGNhc2UgU0lOVDMyICA6IG91dHB1dC53cml0ZVNJbnQzMk5vVGFnICAoKEludGVnZXIgICAgKSB2YWx1ZSk7IGJyZWFrOworICAgICAgY2FzZSBTSU5UNjQgIDogb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcgICgoTG9uZyAgICAgICApIHZhbHVlKTsgYnJlYWs7CisKKyAgICAgIGNhc2UgRU5VTToKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgSW50ZXJuYWwuRW51bUxpdGUpIHsKKyAgICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcoKChJbnRlcm5hbC5FbnVtTGl0ZSkgdmFsdWUpLmdldE51bWJlcigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcoKChJbnRlZ2VyKSB2YWx1ZSkuaW50VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgLyoqIFdyaXRlIGEgc2luZ2xlIGZpZWxkLiAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGVGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3JMaXRlPD8+IGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGUgPSBkZXNjcmlwdG9yLmdldExpdGVUeXBlKCk7CisgICAgaW50IG51bWJlciA9IGRlc2NyaXB0b3IuZ2V0TnVtYmVyKCk7CisgICAgaWYgKGRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICBmaW5hbCBMaXN0PD8+IHZhbHVlTGlzdCA9IChMaXN0PD8+KXZhbHVlOworICAgICAgaWYgKGRlc2NyaXB0b3IuaXNQYWNrZWQoKSkgeworICAgICAgICBvdXRwdXQud3JpdGVUYWcobnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgICAgICAvLyBDb21wdXRlIHRoZSB0b3RhbCBkYXRhIHNpemUgc28gdGhlIGxlbmd0aCBjYW4gYmUgd3JpdHRlbi4KKyAgICAgICAgaW50IGRhdGFTaXplID0gMDsKKyAgICAgICAgZm9yIChmaW5hbCBPYmplY3QgZWxlbWVudCA6IHZhbHVlTGlzdCkgeworICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVFbGVtZW50U2l6ZU5vVGFnKHR5cGUsIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKGRhdGFTaXplKTsKKyAgICAgICAgLy8gV3JpdGUgdGhlIGRhdGEgaXRzZWxmLCB3aXRob3V0IGFueSB0YWdzLgorICAgICAgICBmb3IgKGZpbmFsIE9iamVjdCBlbGVtZW50IDogdmFsdWVMaXN0KSB7CisgICAgICAgICAgd3JpdGVFbGVtZW50Tm9UYWcob3V0cHV0LCB0eXBlLCBlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgZm9yIChmaW5hbCBPYmplY3QgZWxlbWVudCA6IHZhbHVlTGlzdCkgeworICAgICAgICAgIHdyaXRlRWxlbWVudChvdXRwdXQsIHR5cGUsIG51bWJlciwgZWxlbWVudCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTGF6eUZpZWxkKSB7CisgICAgICAgIHdyaXRlRWxlbWVudChvdXRwdXQsIHR5cGUsIG51bWJlciwgKChMYXp5RmllbGQpIHZhbHVlKS5nZXRWYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHdyaXRlRWxlbWVudChvdXRwdXQsIHR5cGUsIG51bWJlciwgdmFsdWUpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTZWUge0BsaW5rIE1lc3NhZ2UjZ2V0U2VyaWFsaXplZFNpemUoKX0uICBJdCdzIHVwIHRvIHRoZSBjYWxsZXIgdG8gY2FjaGUKKyAgICogdGhlIHJlc3VsdGluZyBzaXplIGlmIGRlc2lyZWQuCisgICAqLworICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgeworICAgIGludCBzaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5nZXROdW1BcnJheUVudHJpZXMoKTsgaSsrKSB7CisgICAgICBmaW5hbCBNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSA9CisgICAgICAgICAgZmllbGRzLmdldEFycmF5RW50cnlBdChpKTsKKyAgICAgIHNpemUgKz0gY29tcHV0ZUZpZWxkU2l6ZShlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgfQorICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnkgOgorICAgICAgICAgZmllbGRzLmdldE92ZXJmbG93RW50cmllcygpKSB7CisgICAgICBzaXplICs9IGNvbXB1dGVGaWVsZFNpemUoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIC8qKgorICAgKiBMaWtlIHtAbGluayAjZ2V0U2VyaWFsaXplZFNpemV9IGJ1dCB1c2VzIE1lc3NhZ2VTZXQgd2lyZSBmb3JtYXQuCisgICAqLworICBwdWJsaWMgaW50IGdldE1lc3NhZ2VTZXRTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICBpbnQgc2l6ZSA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuZ2V0TnVtQXJyYXlFbnRyaWVzKCk7IGkrKykgeworICAgICAgc2l6ZSArPSBnZXRNZXNzYWdlU2V0U2VyaWFsaXplZFNpemUoZmllbGRzLmdldEFycmF5RW50cnlBdChpKSk7CisgICAgfQorICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4gZW50cnkgOgorICAgICAgICAgICAgIGZpZWxkcy5nZXRPdmVyZmxvd0VudHJpZXMoKSkgeworICAgICAgc2l6ZSArPSBnZXRNZXNzYWdlU2V0U2VyaWFsaXplZFNpemUoZW50cnkpOworICAgIH0KKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIHByaXZhdGUgaW50IGdldE1lc3NhZ2VTZXRTZXJpYWxpemVkU2l6ZSgKKyAgICAgIGZpbmFsIE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3JUeXBlLCBPYmplY3Q+IGVudHJ5KSB7CisgICAgZmluYWwgRmllbGREZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yID0gZW50cnkuZ2V0S2V5KCk7CisgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICBpZiAoZGVzY3JpcHRvci5nZXRMaXRlSmF2YVR5cGUoKSA9PSBXaXJlRm9ybWF0LkphdmFUeXBlLk1FU1NBR0UKKyAgICAgICAgJiYgIWRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpICYmICFkZXNjcmlwdG9yLmlzUGFja2VkKCkpIHsKKyAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExhenlGaWVsZCkgeworICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZUxhenlGaWVsZE1lc3NhZ2VTZXRFeHRlbnNpb25TaXplKAorICAgICAgICAgICAgZW50cnkuZ2V0S2V5KCkuZ2V0TnVtYmVyKCksIChMYXp5RmllbGQpIHZhbHVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlTWVzc2FnZVNldEV4dGVuc2lvblNpemUoCisgICAgICAgICAgICBlbnRyeS5nZXRLZXkoKS5nZXROdW1iZXIoKSwgKE1lc3NhZ2VMaXRlKSB2YWx1ZSk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBjb21wdXRlRmllbGRTaXplKGRlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHNpbmdsZSB0YWcvdmFsdWUgcGFpciBvZiBhcmJpdHJhcnkgdHlwZS4KKyAgICoKKyAgICogQHBhcmFtIHR5cGUgICBUaGUgZmllbGQncyB0eXBlLgorICAgKiBAcGFyYW0gbnVtYmVyIFRoZSBmaWVsZCdzIG51bWJlci4KKyAgICogQHBhcmFtIHZhbHVlICBPYmplY3QgcmVwcmVzZW50aW5nIHRoZSBmaWVsZCdzIHZhbHVlLiAgTXVzdCBiZSBvZiB0aGUgZXhhY3QKKyAgICogICAgICAgICAgICAgICB0eXBlIHdoaWNoIHdvdWxkIGJlIHJldHVybmVkIGJ5CisgICAqICAgICAgICAgICAgICAge0BsaW5rIE1lc3NhZ2UjZ2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yKX0gZm9yCisgICAqICAgICAgICAgICAgICAgdGhpcyBmaWVsZC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGludCBjb21wdXRlRWxlbWVudFNpemUoCisgICAgICBmaW5hbCBXaXJlRm9ybWF0LkZpZWxkVHlwZSB0eXBlLAorICAgICAgZmluYWwgaW50IG51bWJlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgaW50IHRhZ1NpemUgPSBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlVGFnU2l6ZShudW1iZXIpOworICAgIGlmICh0eXBlID09IFdpcmVGb3JtYXQuRmllbGRUeXBlLkdST1VQKSB7CisgICAgICAvLyBPbmx5IGNvdW50IHRoZSBlbmQgZ3JvdXAgdGFnIGZvciBwcm90bzIgbWVzc2FnZXMgYXMgZm9yIHByb3RvMSB0aGUgZW5kCisgICAgICAvLyBncm91cCB0YWcgd2lsbCBiZSBjb3VudGVkIGFzIGEgcGFydCBvZiBnZXRTZXJpYWxpemVkU2l6ZSgpLgorICAgICAgICB0YWdTaXplICo9IDI7CisgICAgfQorICAgIHJldHVybiB0YWdTaXplICsgY29tcHV0ZUVsZW1lbnRTaXplTm9UYWcodHlwZSwgdmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiBwYXJ0aWN1bGFyIHZhbHVlIG9mIGFyYml0cmFyeSB0eXBlLCBleGNsdWRpbmcgdGFnLgorICAgKgorICAgKiBAcGFyYW0gdHlwZSAgIFRoZSBmaWVsZCdzIHR5cGUuCisgICAqIEBwYXJhbSB2YWx1ZSAgT2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZmllbGQncyB2YWx1ZS4gIE11c3QgYmUgb2YgdGhlIGV4YWN0CisgICAqICAgICAgICAgICAgICAgdHlwZSB3aGljaCB3b3VsZCBiZSByZXR1cm5lZCBieQorICAgKiAgICAgICAgICAgICAgIHtAbGluayBNZXNzYWdlI2dldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcil9IGZvcgorICAgKiAgICAgICAgICAgICAgIHRoaXMgZmllbGQuCisgICAqLworICBzdGF0aWMgaW50IGNvbXB1dGVFbGVtZW50U2l6ZU5vVGFnKAorICAgICAgZmluYWwgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdHlwZSwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICAvLyBOb3RlOiAgTWlub3IgdmlvbGF0aW9uIG9mIDgwLWNoYXIgbGltaXQgcnVsZSBoZXJlIGJlY2F1c2UgdGhpcyB3b3VsZAorICAgICAgLy8gICBhY3R1YWxseSBiZSBoYXJkZXIgdG8gcmVhZCBpZiB3ZSB3cmFwcGVkIHRoZSBsaW5lcy4KKyAgICAgIGNhc2UgRE9VQkxFICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlRG91YmxlU2l6ZU5vVGFnICAoKERvdWJsZSAgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgRkxPQVQgICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlRmxvYXRTaXplTm9UYWcgICAoKEZsb2F0ICAgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgSU5UNjQgICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlSW50NjRTaXplTm9UYWcgICAoKExvbmcgICAgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgVUlOVDY0ICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlVUludDY0U2l6ZU5vVGFnICAoKExvbmcgICAgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgSU5UMzIgICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlSW50MzJTaXplTm9UYWcgICAoKEludGVnZXIgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgRklYRUQ2NCA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlRml4ZWQ2NFNpemVOb1RhZyAoKExvbmcgICAgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgRklYRUQzMiA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlRml4ZWQzMlNpemVOb1RhZyAoKEludGVnZXIgICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgQk9PTCAgICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlQm9vbFNpemVOb1RhZyAgICAoKEJvb2xlYW4gICAgKXZhbHVlKTsKKyAgICAgIGNhc2UgR1JPVVAgICA6IHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlR3JvdXBTaXplTm9UYWcgICAoKE1lc3NhZ2VMaXRlKXZhbHVlKTsKKyAgICAgIGNhc2UgQllURVMgICA6CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEJ5dGVTdHJpbmcpIHsKKyAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZUJ5dGVzU2l6ZU5vVGFnKChCeXRlU3RyaW5nKSB2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVCeXRlQXJyYXlTaXplTm9UYWcoKGJ5dGVbXSkgdmFsdWUpOworICAgICAgICB9CisgICAgICBjYXNlIFNUUklORyAgOgorICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCeXRlU3RyaW5nKSB7CisgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVCeXRlc1NpemVOb1RhZygoQnl0ZVN0cmluZykgdmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlU3RyaW5nU2l6ZU5vVGFnKChTdHJpbmcpIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgY2FzZSBVSU5UMzIgIDogcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVVSW50MzJTaXplTm9UYWcgICgoSW50ZWdlciAgICApdmFsdWUpOworICAgICAgY2FzZSBTRklYRUQzMjogcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVTRml4ZWQzMlNpemVOb1RhZygoSW50ZWdlciAgICApdmFsdWUpOworICAgICAgY2FzZSBTRklYRUQ2NDogcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVTRml4ZWQ2NFNpemVOb1RhZygoTG9uZyAgICAgICApdmFsdWUpOworICAgICAgY2FzZSBTSU5UMzIgIDogcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVTSW50MzJTaXplTm9UYWcgICgoSW50ZWdlciAgICApdmFsdWUpOworICAgICAgY2FzZSBTSU5UNjQgIDogcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVTSW50NjRTaXplTm9UYWcgICgoTG9uZyAgICAgICApdmFsdWUpOworCisgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExhenlGaWVsZCkgeworICAgICAgICAgIHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlTGF6eUZpZWxkU2l6ZU5vVGFnKChMYXp5RmllbGQpIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZU1lc3NhZ2VTaXplTm9UYWcoKE1lc3NhZ2VMaXRlKSB2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgY2FzZSBFTlVNOgorICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBJbnRlcm5hbC5FbnVtTGl0ZSkgeworICAgICAgICAgIHJldHVybiBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlRW51bVNpemVOb1RhZygKKyAgICAgICAgICAgICAgKChJbnRlcm5hbC5FbnVtTGl0ZSkgdmFsdWUpLmdldE51bWJlcigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZUVudW1TaXplTm9UYWcoKEludGVnZXIpIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgIlRoZXJlIGlzIG5vIHdheSB0byBnZXQgaGVyZSwgYnV0IHRoZSBjb21waWxlciB0aGlua3Mgb3RoZXJ3aXNlLiIpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gZW5jb2RlIGEgcGFydGljdWxhciBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVGaWVsZFNpemUoZmluYWwgRmllbGREZXNjcmlwdG9yTGl0ZTw/PiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGUgPSBkZXNjcmlwdG9yLmdldExpdGVUeXBlKCk7CisgICAgaW50IG51bWJlciA9IGRlc2NyaXB0b3IuZ2V0TnVtYmVyKCk7CisgICAgaWYgKGRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICBpZiAoZGVzY3JpcHRvci5pc1BhY2tlZCgpKSB7CisgICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CisgICAgICAgIGZvciAoZmluYWwgT2JqZWN0IGVsZW1lbnQgOiAoTGlzdDw/Pil2YWx1ZSkgeworICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVFbGVtZW50U2l6ZU5vVGFnKHR5cGUsIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkYXRhU2l6ZSArCisgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlVGFnU2l6ZShudW1iZXIpICsKKyAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZGF0YVNpemUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaW50IHNpemUgPSAwOworICAgICAgICBmb3IgKGZpbmFsIE9iamVjdCBlbGVtZW50IDogKExpc3Q8Pz4pdmFsdWUpIHsKKyAgICAgICAgICBzaXplICs9IGNvbXB1dGVFbGVtZW50U2l6ZSh0eXBlLCBudW1iZXIsIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzaXplOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gY29tcHV0ZUVsZW1lbnRTaXplKHR5cGUsIG51bWJlciwgdmFsdWUpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0NTdkOTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9HZW5lcmF0ZWRNZXNzYWdlLmphdmEKQEAgLTAsMCArMSwyNjk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZS5FeHRlbmRhYmxlTWVzc2FnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLkdlbmVyYXRlZEV4dGVuc2lvbjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworLyoqCisgKiBBbGwgZ2VuZXJhdGVkIHByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcyBleHRlbmQgdGhpcyBjbGFzcy4gIFRoaXMgY2xhc3MKKyAqIGltcGxlbWVudHMgbW9zdCBvZiB0aGUgTWVzc2FnZSBhbmQgQnVpbGRlciBpbnRlcmZhY2VzIHVzaW5nIEphdmEgcmVmbGVjdGlvbi4KKyAqIFVzZXJzIGNhbiBpZ25vcmUgdGhpcyBjbGFzcyBhbmQgcHJldGVuZCB0aGF0IGdlbmVyYXRlZCBtZXNzYWdlcyBpbXBsZW1lbnQKKyAqIHRoZSBNZXNzYWdlIGludGVyZmFjZSBkaXJlY3RseS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgR2VuZXJhdGVkTWVzc2FnZSBleHRlbmRzIEFic3RyYWN0TWVzc2FnZQorICAgIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgLyoqCisgICAqIEZvciB0ZXN0aW5nLiBBbGxvd3MgYSB0ZXN0IHRvIGRpc2FibGUgdGhlIG9wdGltaXphdGlvbiB0aGF0IGF2b2lkcyB1c2luZworICAgKiBmaWVsZCBidWlsZGVycyBmb3IgbmVzdGVkIG1lc3NhZ2VzIHVudGlsIHRoZXkgYXJlIHJlcXVlc3RlZC4gQnkgZGlzYWJsaW5nCisgICAqIHRoaXMgb3B0aW1pemF0aW9uLCBleGlzdGluZyB0ZXN0cyBjYW4gYmUgcmV1c2VkIHRvIHRlc3QgdGhlIGZpZWxkIGJ1aWxkZXJzLgorICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPSBmYWxzZTsKKworICAvKiogRm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiAgKi8KKyAgcHJvdGVjdGVkIFVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzOworCisgIHByb3RlY3RlZCBHZW5lcmF0ZWRNZXNzYWdlKCkgeworICAgIHVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgIH0KKworICBwcm90ZWN0ZWQgR2VuZXJhdGVkTWVzc2FnZShCdWlsZGVyPD8+IGJ1aWxkZXIpIHsKKyAgICB1bmtub3duRmllbGRzID0gYnVpbGRlci5nZXRVbmtub3duRmllbGRzKCk7CisgIH0KKworICBwdWJsaWMgUGFyc2VyPD8gZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgIlRoaXMgaXMgc3VwcG9zZWQgdG8gYmUgb3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzLiIpOworICB9CisKKyAvKioKKyAgKiBGb3IgdGVzdGluZy4gQWxsb3dzIGEgdGVzdCB0byBkaXNhYmxlIHRoZSBvcHRpbWl6YXRpb24gdGhhdCBhdm9pZHMgdXNpbmcKKyAgKiBmaWVsZCBidWlsZGVycyBmb3IgbmVzdGVkIG1lc3NhZ2VzIHVudGlsIHRoZXkgYXJlIHJlcXVlc3RlZC4gQnkgZGlzYWJsaW5nCisgICogdGhpcyBvcHRpbWl6YXRpb24sIGV4aXN0aW5nIHRlc3RzIGNhbiBiZSByZXVzZWQgdG8gdGVzdCB0aGUgZmllbGQgYnVpbGRlcnMuCisgICogU2VlIHtAbGluayBSZXBlYXRlZEZpZWxkQnVpbGRlcn0gYW5kIHtAbGluayBTaW5nbGVGaWVsZEJ1aWxkZXJ9LgorICAqLworICBzdGF0aWMgdm9pZCBlbmFibGVBbHdheXNVc2VGaWVsZEJ1aWxkZXJzRm9yVGVzdGluZygpIHsKKyAgICBhbHdheXNVc2VGaWVsZEJ1aWxkZXJzID0gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIEZpZWxkQWNjZXNzb3JUYWJsZSBmb3IgdGhpcyB0eXBlLiAgV2UgY2FuJ3QgaGF2ZSB0aGUgbWVzc2FnZQorICAgKiBjbGFzcyBwYXNzIHRoaXMgaW4gdG8gdGhlIGNvbnN0cnVjdG9yIGJlY2F1c2Ugb2YgYm9vdHN0cmFwcGluZyB0cm91YmxlCisgICAqIHdpdGggRGVzY3JpcHRvclByb3Rvcy4KKyAgICovCisgIHByb3RlY3RlZCBhYnN0cmFjdCBGaWVsZEFjY2Vzc29yVGFibGUgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKTsKKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIERlc2NyaXB0b3IgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CisgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZGVzY3JpcHRvcjsKKyAgfQorCisgIC8qKgorICAgKiBJbnRlcm5hbCBoZWxwZXIgdG8gcmV0dXJuIGEgbW9kaWZpYWJsZSBtYXAgY29udGFpbmluZyBhbGwgdGhlIGZpZWxkcy4KKyAgICogVGhlIHJldHVybmVkIE1hcCBpcyBtb2RpZmlhbGJlIHNvIHRoYXQgdGhlIGNhbGxlciBjYW4gYWRkIGFkZGl0aW9uYWwKKyAgICogZXh0ZW5zaW9uIGZpZWxkcyB0byBpbXBsZW1lbnQge0BsaW5rICNnZXRBbGxGaWVsZHMoKX0uCisgICAqCisgICAqIEBwYXJhbSBnZXRCeXRlc0ZvclN0cmluZyB3aGV0aGVyIHRvIGdlbmVyYXRlIEJ5dGVTdHJpbmcgZm9yIHN0cmluZyBmaWVsZHMKKyAgICovCisgIHByaXZhdGUgTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBnZXRBbGxGaWVsZHNNdXRhYmxlKAorICAgICAgYm9vbGVhbiBnZXRCeXRlc0ZvclN0cmluZykgeworICAgIGZpbmFsIFRyZWVNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IHJlc3VsdCA9CisgICAgICBuZXcgVHJlZU1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4oKTsKKyAgICBmaW5hbCBEZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmRlc2NyaXB0b3I7CisgICAgZm9yIChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQgOiBkZXNjcmlwdG9yLmdldEZpZWxkcygpKSB7CisgICAgICBpZiAoZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIGZpbmFsIExpc3Q8Pz4gdmFsdWUgPSAoTGlzdDw/PikgZ2V0RmllbGQoZmllbGQpOworICAgICAgICBpZiAoIXZhbHVlLmlzRW1wdHkoKSkgeworICAgICAgICAgIHJlc3VsdC5wdXQoZmllbGQsIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGhhc0ZpZWxkKGZpZWxkKSkgeworICAgICAgICAgIGlmIChnZXRCeXRlc0ZvclN0cmluZworICAgICAgICAgICAgICAmJiBmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgIHJlc3VsdC5wdXQoZmllbGQsIGdldEZpZWxkUmF3KGZpZWxkKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdC5wdXQoZmllbGQsIGdldEZpZWxkKGZpZWxkKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICBmb3IgKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA6IGdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RmllbGRzKCkpIHsKKyAgICAgIC8vIENoZWNrIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudC4KKyAgICAgIGlmIChmaWVsZC5pc1JlcXVpcmVkKCkpIHsKKyAgICAgICAgaWYgKCFoYXNGaWVsZChmaWVsZCkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIC8vIENoZWNrIHRoYXQgZW1iZWRkZWQgbWVzc2FnZXMgYXJlIGluaXRpYWxpemVkLgorICAgICAgaWYgKGZpZWxkLmdldEphdmFUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgaWYgKGZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSBmaW5hbAorICAgICAgICAgIExpc3Q8TWVzc2FnZT4gbWVzc2FnZUxpc3QgPSAoTGlzdDxNZXNzYWdlPikgZ2V0RmllbGQoZmllbGQpOworICAgICAgICAgIGZvciAoZmluYWwgTWVzc2FnZSBlbGVtZW50IDogbWVzc2FnZUxpc3QpIHsKKyAgICAgICAgICAgIGlmICghZWxlbWVudC5pc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoaGFzRmllbGQoZmllbGQpICYmICEoKE1lc3NhZ2UpIGdldEZpZWxkKGZpZWxkKSkuaXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZ2V0QWxsRmllbGRzKCkgeworICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoCisgICAgICAgIGdldEFsbEZpZWxkc011dGFibGUoLyogZ2V0Qnl0ZXNGb3JTdHJpbmcgPSAqLyBmYWxzZSkpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIG9mIGFsbCB0aGUgZmllbGRzIGluIHRoaXMgbWVzc2FnZSB3aGljaCBhcmUgc2V0CisgICAqIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcy4gIEEgc2luZ3VsYXIgKCJyZXF1aXJlZCIgb3IgIm9wdGlvbmFsIikKKyAgICogZmllbGQgaXMgc2V0IGlmZiBoYXNGaWVsZCgpIHJldHVybnMgdHJ1ZSBmb3IgdGhhdCBmaWVsZC4gIEEgInJlcGVhdGVkIgorICAgKiBmaWVsZCBpcyBzZXQgaWZmIGdldFJlcGVhdGVkRmllbGRDb3VudCgpIGlzIGdyZWF0ZXIgdGhhbiB6ZXJvLiAgVGhlCisgICAqIHZhbHVlcyBhcmUgZXhhY3RseSB3aGF0IHdvdWxkIGJlIHJldHVybmVkIGJ5IGNhbGxpbmcKKyAgICoge0BsaW5rICNnZXRGaWVsZFJhdyhEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IpfSBmb3IgZWFjaCBmaWVsZC4gIFRoZSBtYXAKKyAgICogaXMgZ3VhcmFudGVlZCB0byBiZSBhIHNvcnRlZCBtYXAsIHNvIGl0ZXJhdGluZyBvdmVyIGl0IHdpbGwgcmV0dXJuIGZpZWxkcworICAgKiBpbiBvcmRlciBieSBmaWVsZCBudW1iZXIuCisgICAqLworICBNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGdldEFsbEZpZWxkc1JhdygpIHsKKyAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKAorICAgICAgICBnZXRBbGxGaWVsZHNNdXRhYmxlKC8qIGdldEJ5dGVzRm9yU3RyaW5nID0gKi8gdHJ1ZSkpOworICB9CisKKyAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mKGZpbmFsIE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldE9uZW9mKG9uZW9mKS5oYXModGhpcyk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIEZpZWxkRGVzY3JpcHRvciBnZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihmaW5hbCBPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKS5nZXRPbmVvZihvbmVvZikuZ2V0KHRoaXMpOworICB9CisKKyAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5oYXModGhpcyk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIE9iamVjdCBnZXRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKS5nZXRGaWVsZChmaWVsZCkuZ2V0KHRoaXMpOworICB9CisKKyAgLyoqCisgICAqIE9idGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCwgb3IgdGhlIGRlZmF1bHQgdmFsdWUgaWYgaXQgaXMKKyAgICogbm90IHNldC4gIEZvciBwcmltaXRpdmUgZmllbGRzLCB0aGUgYm94ZWQgcHJpbWl0aXZlIHZhbHVlIGlzIHJldHVybmVkLgorICAgKiBGb3IgZW51bSBmaWVsZHMsIHRoZSBFbnVtVmFsdWVEZXNjcmlwdG9yIGZvciB0aGUgdmFsdWUgaXMgcmV0dXJuZWQuIEZvcgorICAgKiBlbWJlZGRlZCBtZXNzYWdlIGZpZWxkcywgdGhlIHN1Yi1tZXNzYWdlIGlzIHJldHVybmVkLiAgRm9yIHJlcGVhdGVkCisgICAqIGZpZWxkcywgYSBqYXZhLnV0aWwuTGlzdCBpcyByZXR1cm5lZC4gRm9yIHByZXNlbnQgc3RyaW5nIGZpZWxkcywgYQorICAgKiBCeXRlU3RyaW5nIGlzIHJldHVybmVkIHJlcHJlc2VudGluZyB0aGUgYnl0ZXMgdGhhdCB0aGUgZmllbGQgY29udGFpbnMuCisgICAqLworICBPYmplY3QgZ2V0RmllbGRSYXcoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0RmllbGQoZmllbGQpLmdldFJhdyh0aGlzKTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmllbGRDb3VudChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKS5nZXRGaWVsZChmaWVsZCkKKyAgICAgIC5nZXRSZXBlYXRlZENvdW50KHRoaXMpOworICB9CisKKyAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQsIGZpbmFsIGludCBpbmRleCkgeworICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKQorICAgICAgLmdldFJlcGVhdGVkKHRoaXMsIGluZGV4KTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgVW5rbm93bkZpZWxkU2V0IGdldFVua25vd25GaWVsZHMoKSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAiVGhpcyBpcyBzdXBwb3NlZCB0byBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMuIik7CisgIH0KKworICAvKioKKyAgICogQ2FsbGVkIGJ5IHN1YmNsYXNzZXMgdG8gcGFyc2UgYW4gdW5rbm93biBmaWVsZC4KKyAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gdW5sZXNzIHRoZSB0YWcgaXMgYW4gZW5kLWdyb3VwIHRhZy4KKyAgICovCisgIHByb3RlY3RlZCBib29sZWFuIHBhcnNlVW5rbm93bkZpZWxkKAorICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgIFVua25vd25GaWVsZFNldC5CdWlsZGVyIHVua25vd25GaWVsZHMsCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICBpbnQgdGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB1bmtub3duRmllbGRzLm1lcmdlRmllbGRGcm9tKHRhZywgaW5wdXQpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE1lc3NhZ2VSZWZsZWN0aW9uLndyaXRlTWVzc2FnZVRvKHRoaXMsIGdldEFsbEZpZWxkc1JhdygpLCBvdXRwdXQsIGZhbHNlKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgeworICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOworICAgIGlmIChzaXplICE9IC0xKSB7CisgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICBtZW1vaXplZFNpemUgPSBNZXNzYWdlUmVmbGVjdGlvbi5nZXRTZXJpYWxpemVkU2l6ZSgKKyAgICAgICAgdGhpcywgZ2V0QWxsRmllbGRzUmF3KCkpOworICAgIHJldHVybiBtZW1vaXplZFNpemU7CisgIH0KKworCisKKyAgLyoqCisgICAqIFVzZWQgYnkgcGFyc2luZyBjb25zdHJ1Y3RvcnMgaW4gZ2VuZXJhdGVkIGNsYXNzZXMuCisgICAqLworICBwcm90ZWN0ZWQgdm9pZCBtYWtlRXh0ZW5zaW9uc0ltbXV0YWJsZSgpIHsKKyAgICAvLyBOb29wIGZvciBtZXNzYWdlcyB3aXRob3V0IGV4dGVuc2lvbnMuCisgIH0KKworICBwcm90ZWN0ZWQgYWJzdHJhY3QgTWVzc2FnZS5CdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKEJ1aWxkZXJQYXJlbnQgcGFyZW50KTsKKworICAvKioKKyAgICogSW50ZXJmYWNlIGZvciB0aGUgcGFyZW50IG9mIGEgQnVpbGRlciB0aGF0IGFsbG93cyB0aGUgYnVpbGRlciB0bworICAgKiBjb21tdW5pY2F0ZSBpbnZhbGlkYXRpb25zIGJhY2sgdG8gdGhlIHBhcmVudCBmb3IgdXNlIHdoZW4gdXNpbmcgbmVzdGVkCisgICAqIGJ1aWxkZXJzLgorICAgKi8KKyAgcHJvdGVjdGVkIGludGVyZmFjZSBCdWlsZGVyUGFyZW50IHsKKworICAgIC8qKgorICAgICAqIEEgYnVpbGRlciBiZWNvbWVzIGRpcnR5IHdoZW5ldmVyIGEgZmllbGQgaXMgbW9kaWZpZWQgLS0gaW5jbHVkaW5nIGZpZWxkcworICAgICAqIGluIG5lc3RlZCBidWlsZGVycyAtLSBhbmQgYmVjb21lcyBjbGVhbiB3aGVuIGJ1aWxkKCkgaXMgY2FsbGVkLiAgVGh1cywKKyAgICAgKiB3aGVuIGEgYnVpbGRlciBiZWNvbWVzIGRpcnR5LCBhbGwgaXRzIHBhcmVudHMgYmVjb21lIGRpcnR5IGFzIHdlbGwsIGFuZAorICAgICAqIHdoZW4gaXQgYmVjb21lcyBjbGVhbiwgYWxsIGl0cyBjaGlsZHJlbiBiZWNvbWUgY2xlYW4uICBUaGUgZGlydGluZXNzCisgICAgICogc3RhdGUgaXMgdXNlZCB0byBpbnZhbGlkYXRlIGNlcnRhaW4gY2FjaGVkIHZhbHVlcy4KKyAgICAgKiA8YnI+CisgICAgICogVG8gdGhpcyBlbmQsIGEgYnVpbGRlciBjYWxscyBtYXJrQXNEaXJ0eSgpIG9uIGl0cyBwYXJlbnQgd2hlbmV2ZXIgaXQKKyAgICAgKiB0cmFuc2l0aW9ucyBmcm9tIGNsZWFuIHRvIGRpcnR5LiAgVGhlIHBhcmVudCBtdXN0IHByb3BhZ2F0ZSB0aGlzIGNhbGwgdG8KKyAgICAgKiBpdHMgb3duIHBhcmVudCwgdW5sZXNzIGl0IHdhcyBhbHJlYWR5IGRpcnR5LCBpbiB3aGljaCBjYXNlIHRoZQorICAgICAqIGdyYW5kcGFyZW50IG11c3QgbmVjZXNzYXJpbHkgYWxyZWFkeSBiZSBkaXJ0eSBhcyB3ZWxsLiAgVGhlIHBhcmVudCBjYW4KKyAgICAgKiBvbmx5IHRyYW5zaXRpb24gYmFjayB0byAiY2xlYW4iIGFmdGVyIGNhbGxpbmcgYnVpbGQoKSBvbiBhbGwgY2hpbGRyZW4uCisgICAgICovCisgICAgdm9pZCBtYXJrRGlydHkoKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgPEJ1aWxkZXJUeXBlIGV4dGVuZHMgQnVpbGRlcj4KKyAgICAgIGV4dGVuZHMgQWJzdHJhY3RNZXNzYWdlLkJ1aWxkZXI8QnVpbGRlclR5cGU+IHsKKworICAgIHByaXZhdGUgQnVpbGRlclBhcmVudCBidWlsZGVyUGFyZW50OworCisgICAgcHJpdmF0ZSBCdWlsZGVyUGFyZW50SW1wbCBtZUFzUGFyZW50OworCisgICAgLy8gSW5kaWNhdGVzIHRoYXQgd2UndmUgYnVpbHQgYSBtZXNzYWdlIGFuZCBzbyB3ZSBhcmUgbm93IG9ibGlnYXRlZAorICAgIC8vIHRvIGRpc3BhdGNoIGRpcnR5IGludmFsaWRhdGlvbnMuIFNlZSBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXJMaXN0ZW5lci4KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDbGVhbjsKKworICAgIHByaXZhdGUgVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMgPQorICAgICAgICBVbmtub3duRmllbGRTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisKKyAgICBwcm90ZWN0ZWQgQnVpbGRlcigpIHsKKyAgICAgIHRoaXMobnVsbCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEJ1aWxkZXIoQnVpbGRlclBhcmVudCBidWlsZGVyUGFyZW50KSB7CisgICAgICB0aGlzLmJ1aWxkZXJQYXJlbnQgPSBidWlsZGVyUGFyZW50OworICAgIH0KKworICAgIHZvaWQgZGlzcG9zZSgpIHsKKyAgICAgIGJ1aWxkZXJQYXJlbnQgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxlZCBieSB0aGUgc3ViY2xhc3Mgd2hlbiBhIG1lc3NhZ2UgaXMgYnVpbHQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgb25CdWlsdCgpIHsKKyAgICAgIGlmIChidWlsZGVyUGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgbWFya0NsZWFuKCk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IHRoZSBzdWJjbGFzcyBvciBhIGJ1aWxkZXIgdG8gbm90aWZ5IHVzIHRoYXQgYSBtZXNzYWdlIHdhcworICAgICAqIGJ1aWx0IGFuZCBtYXkgYmUgY2FjaGVkIGFuZCB0aGVyZWZvcmUgaW52YWxpZGF0aW9ucyBhcmUgbmVlZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG1hcmtDbGVhbigpIHsKKyAgICAgIHRoaXMuaXNDbGVhbiA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB3aGV0aGVyIGludmFsaWRhdGlvbnMgYXJlIG5lZWRlZAorICAgICAqCisgICAgICogQHJldHVybiB3aGV0aGVyIGludmFsaWRhdGlvbnMgYXJlIG5lZWRlZAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlzQ2xlYW4oKSB7CisgICAgICByZXR1cm4gaXNDbGVhbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xvbmUoKSB7CisgICAgICBCdWlsZGVyVHlwZSBidWlsZGVyID0KKyAgICAgICAgICAoQnVpbGRlclR5cGUpIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgICAgYnVpbGRlci5tZXJnZUZyb20oYnVpbGRQYXJ0aWFsKCkpOworICAgICAgcmV0dXJuIGJ1aWxkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IHRoZSBpbml0aWFsaXphdGlvbiBhbmQgY2xlYXIgY29kZSBwYXRocyB0byBhbGxvdyBzdWJjbGFzc2VzIHRvCisgICAgICogcmVzZXQgYW55IG9mIHRoZWlyIGJ1aWx0aW4gZmllbGRzIGJhY2sgdG8gdGhlIGluaXRpYWwgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBjbGVhcigpIHsKKyAgICAgIHVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBGaWVsZEFjY2Vzc29yVGFibGUgZm9yIHRoaXMgdHlwZS4gIFdlIGNhbid0IGhhdmUgdGhlIG1lc3NhZ2UKKyAgICAgKiBjbGFzcyBwYXNzIHRoaXMgaW4gdG8gdGhlIGNvbnN0cnVjdG9yIGJlY2F1c2Ugb2YgYm9vdHN0cmFwcGluZyB0cm91YmxlCisgICAgICogd2l0aCBEZXNjcmlwdG9yUHJvdG9zLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBGaWVsZEFjY2Vzc29yVGFibGUgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKTsKKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBEZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZGVzY3JpcHRvcjsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBnZXRBbGxGaWVsZHMoKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGdldEFsbEZpZWxkc011dGFibGUoKSk7CisgICAgfQorCisgICAgLyoqIEludGVybmFsIGhlbHBlciB3aGljaCByZXR1cm5zIGEgbXV0YWJsZSBtYXAuICovCisgICAgcHJpdmF0ZSBNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGdldEFsbEZpZWxkc011dGFibGUoKSB7CisgICAgICBmaW5hbCBUcmVlTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiByZXN1bHQgPQorICAgICAgICBuZXcgVHJlZU1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4oKTsKKyAgICAgIGZpbmFsIERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZGVzY3JpcHRvcjsKKyAgICAgIGZvciAoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkIDogZGVzY3JpcHRvci5nZXRGaWVsZHMoKSkgeworICAgICAgICBpZiAoZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgICAgZmluYWwgTGlzdCB2YWx1ZSA9IChMaXN0KSBnZXRGaWVsZChmaWVsZCk7CisgICAgICAgICAgaWYgKCF2YWx1ZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5wdXQoZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKGhhc0ZpZWxkKGZpZWxkKSkgeworICAgICAgICAgICAgcmVzdWx0LnB1dChmaWVsZCwgZ2V0RmllbGQoZmllbGQpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBuZXdCdWlsZGVyRm9yRmllbGQoCisgICAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0RmllbGQoZmllbGQpLm5ld0J1aWxkZXIoKTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgTWVzc2FnZS5CdWlsZGVyIGdldEZpZWxkQnVpbGRlcihmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5nZXRCdWlsZGVyKHRoaXMpOworICAgIH0KKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICBpbnQgaW5kZXgpIHsKKyAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5nZXRSZXBlYXRlZEJ1aWxkZXIoCisgICAgICAgICAgdGhpcywgaW5kZXgpOworICAgIH0KKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mKGZpbmFsIE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0T25lb2Yob25lb2YpLmhhcyh0aGlzKTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldE9uZW9mRmllbGREZXNjcmlwdG9yKGZpbmFsIE9uZW9mRGVzY3JpcHRvciBvbmVvZikgeworICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0T25lb2Yob25lb2YpLmdldCh0aGlzKTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5oYXModGhpcyk7CisgICAgfQorCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIE9iamVjdCBvYmplY3QgPSBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5nZXQodGhpcyk7CisgICAgICBpZiAoZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIC8vIFRoZSB1bmRlcmx5aW5nIGxpc3Qgb2JqZWN0IGlzIHN0aWxsIG1vZGlmaWFibGUgYXQgdGhpcyBwb2ludC4KKyAgICAgICAgLy8gTWFrZSBzdXJlIG5vdCB0byBleHBvc2UgdGhlIG1vZGlmaWFibGUgbGlzdCB0byB0aGUgY2FsbGVyLgorICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgoTGlzdCkgb2JqZWN0KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBvYmplY3Q7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIHNldEZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5zZXQodGhpcywgdmFsdWUpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xlYXJGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0RmllbGQoZmllbGQpLmNsZWFyKHRoaXMpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xlYXJPbmVvZihmaW5hbCBPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0T25lb2Yob25lb2YpLmNsZWFyKHRoaXMpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmllbGRDb3VudChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKQorICAgICAgICAgIC5nZXRSZXBlYXRlZENvdW50KHRoaXMpOworICAgIH0KKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCkgeworICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0RmllbGQoZmllbGQpCisgICAgICAgICAgLmdldFJlcGVhdGVkKHRoaXMsIGluZGV4KTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgc2V0UmVwZWF0ZWRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4LCBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkuZ2V0RmllbGQoZmllbGQpCisgICAgICAgIC5zZXRSZXBlYXRlZCh0aGlzLCBpbmRleCwgdmFsdWUpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgYWRkUmVwZWF0ZWRGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpLmdldEZpZWxkKGZpZWxkKS5hZGRSZXBlYXRlZCh0aGlzLCB2YWx1ZSk7CisgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBzZXRVbmtub3duRmllbGRzKAorICAgICAgICBmaW5hbCBVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgdGhpcy51bmtub3duRmllbGRzID0gdW5rbm93bkZpZWxkczsKKyAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbWVyZ2VVbmtub3duRmllbGRzKAorICAgICAgICBmaW5hbCBVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgdGhpcy51bmtub3duRmllbGRzID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIodGhpcy51bmtub3duRmllbGRzKQorICAgICAgICAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHVua25vd25GaWVsZHMpCisgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgb25DaGFuZ2VkKCk7CisgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSB0aGlzOworICAgIH0KKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CisgICAgICBmb3IgKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA6IGdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RmllbGRzKCkpIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBhbGwgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50LgorICAgICAgICBpZiAoZmllbGQuaXNSZXF1aXJlZCgpKSB7CisgICAgICAgICAgaWYgKCFoYXNGaWVsZChmaWVsZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgaW5pdGlhbGl6ZWQuCisgICAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgaWYgKGZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIGZpbmFsCisgICAgICAgICAgICBMaXN0PE1lc3NhZ2U+IG1lc3NhZ2VMaXN0ID0gKExpc3Q8TWVzc2FnZT4pIGdldEZpZWxkKGZpZWxkKTsKKyAgICAgICAgICAgIGZvciAoZmluYWwgTWVzc2FnZSBlbGVtZW50IDogbWVzc2FnZUxpc3QpIHsKKyAgICAgICAgICAgICAgaWYgKCFlbGVtZW50LmlzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoaGFzRmllbGQoZmllbGQpICYmCisgICAgICAgICAgICAgICAgISgoTWVzc2FnZSkgZ2V0RmllbGQoZmllbGQpKS5pc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIGZpbmFsIFVua25vd25GaWVsZFNldCBnZXRVbmtub3duRmllbGRzKCkgeworICAgICAgcmV0dXJuIHVua25vd25GaWVsZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IHN1YmNsYXNzZXMgdG8gcGFyc2UgYW4gdW5rbm93biBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSB1bmxlc3MgdGhlIHRhZyBpcyBhbiBlbmQtZ3JvdXAgdGFnLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHBhcnNlVW5rbm93bkZpZWxkKAorICAgICAgICBmaW5hbCBDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICBmaW5hbCBVbmtub3duRmllbGRTZXQuQnVpbGRlciB1bmtub3duRmllbGRzLAorICAgICAgICBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICAgIGZpbmFsIGludCB0YWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gdW5rbm93bkZpZWxkcy5tZXJnZUZpZWxkRnJvbSh0YWcsIGlucHV0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQnVpbGRlclBhcmVudH0gZm9yIGdpdmluZyB0byBvdXIgY2hpbGRyZW4uIFRoaXMKKyAgICAgKiBzbWFsbCBpbm5lciBjbGFzcyBtYWtlcyBpdCBzbyB3ZSBkb24ndCBwdWJsaWNseSBleHBvc2UgdGhlIEJ1aWxkZXJQYXJlbnQKKyAgICAgKiBtZXRob2RzLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgQnVpbGRlclBhcmVudEltcGwgaW1wbGVtZW50cyBCdWlsZGVyUGFyZW50IHsKKworICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgdm9pZCBtYXJrRGlydHkoKSB7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAbGluayBCdWlsZGVyUGFyZW50fSBmb3IgZ2l2aW5nIHRvIG91ciBjaGlsZHJlbi4KKyAgICAgKiBAcmV0dXJuIFRoZSBidWlsZGVyIHBhcmVudCBmb3Igb3VyIGNoaWxkcmVuLgorICAgICAqLworICAgIHByb3RlY3RlZCBCdWlsZGVyUGFyZW50IGdldFBhcmVudEZvckNoaWxkcmVuKCkgeworICAgICAgaWYgKG1lQXNQYXJlbnQgPT0gbnVsbCkgeworICAgICAgICBtZUFzUGFyZW50ID0gbmV3IEJ1aWxkZXJQYXJlbnRJbXBsKCk7CisgICAgICB9CisgICAgICByZXR1cm4gbWVBc1BhcmVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgd2hlbiBhIHRoZSBidWlsZGVyIG9yIG9uZSBvZiBpdHMgbmVzdGVkIGNoaWxkcmVuIGhhcyBjaGFuZ2VkCisgICAgICogYW5kIGFueSBwYXJlbnQgc2hvdWxkIGJlIG5vdGlmaWVkIG9mIGl0cyBpbnZhbGlkYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgb25DaGFuZ2VkKCkgeworICAgICAgaWYgKGlzQ2xlYW4gJiYgYnVpbGRlclBhcmVudCAhPSBudWxsKSB7CisgICAgICAgIGJ1aWxkZXJQYXJlbnQubWFya0RpcnR5KCk7CisKKyAgICAgICAgLy8gRG9uJ3Qga2VlcCBkaXNwYXRjaGluZyBpbnZhbGlkYXRpb25zIHVudGlsIGJ1aWxkIGlzIGNhbGxlZCBhZ2Fpbi4KKyAgICAgICAgaXNDbGVhbiA9IGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1hcCBmaWVsZCB3aXRoIHRoZSBnaXZlbiBmaWVsZCBudW1iZXIuIFRoaXMgbWV0aG9kIHNob3VsZCBiZQorICAgICAqIG92ZXJyaWRkZW4gaW4gdGhlIGdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzIGlmIHRoZSBtZXNzYWdlIGNvbnRhaW5zIG1hcAorICAgICAqIGZpZWxkcy4KKyAgICAgKgorICAgICAqIFVubGlrZSBvdGhlciBmaWVsZCB0eXBlcywgcmVmbGVjdGlvbiBzdXBwb3J0IGZvciBtYXAgZmllbGRzIGNhbid0IGJlCisgICAgICogaW1wbGVtZW50ZWQgYmFzZWQgb24gZ2VuZXJhdGVkIHB1YmxpYyBBUEkgYmVjYXVzZSB3ZSBuZWVkIHRvIGFjY2VzcyBhCisgICAgICogbWFwIGZpZWxkIGFzIGEgbGlzdCBpbiByZWZsZWN0aW9uIEFQSSBidXQgdGhlIGdlbmVyYXRlZCBBUEkgb25seSBhbGxvd3MKKyAgICAgKiB1cyB0byBhY2Nlc3MgaXQgYXMgYSBtYXAuIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIHVuZGVybHlpbmcgbWFwIGZpZWxkCisgICAgICogZGlyZWN0bHkgYW5kIHRodXMgZW5hYmxlcyB1cyB0byBhY2Nlc3MgdGhlIG1hcCBmaWVsZCBhcyBhIGxpc3QuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQiLCAicmF3dHlwZXMifSkKKyAgICBwcm90ZWN0ZWQgTWFwRmllbGQgaW50ZXJuYWxHZXRNYXBGaWVsZChpbnQgZmllbGROdW1iZXIpIHsKKyAgICAgIC8vIE5vdGUgdGhhdCB3ZSBjYW4ndCB1c2UgZGVzY3JpcHRvciBuYW1lcyBoZXJlIGJlY2F1c2UgdGhpcyBtZXRob2Qgd2lsbAorICAgICAgLy8gYmUgY2FsbGVkIHdoZW4gZGVzY3JpcHRvciBpcyBiZWluZyBpbml0aWFsaXplZC4KKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJObyBtYXAgZmllbGRzIGZvdW5kIGluICIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqIExpa2Uge0BsaW5rIGludGVybmFsR2V0TWFwRmllbGR9IGJ1dCByZXR1cm4gYSBtdXRhYmxlIHZlcnNpb24uICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQiLCAicmF3dHlwZXMifSkKKyAgICBwcm90ZWN0ZWQgTWFwRmllbGQgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoaW50IGZpZWxkTnVtYmVyKSB7CisgICAgICAvLyBOb3RlIHRoYXQgd2UgY2FuJ3QgdXNlIGRlc2NyaXB0b3IgbmFtZXMgaGVyZSBiZWNhdXNlIHRoaXMgbWV0aG9kIHdpbGwKKyAgICAgIC8vIGJlIGNhbGxlZCB3aGVuIGRlc2NyaXB0b3IgaXMgYmVpbmcgaW5pdGlhbGl6ZWQuCisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAiTm8gbWFwIGZpZWxkcyBmb3VuZCBpbiAiICsgZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIEV4dGVuc2lvbnMtcmVsYXRlZCBzdHVmZgorCisgIHB1YmxpYyBpbnRlcmZhY2UgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8CisgICAgICBNZXNzYWdlVHlwZSBleHRlbmRzIEV4dGVuZGFibGVNZXNzYWdlPiBleHRlbmRzIE1lc3NhZ2VPckJ1aWxkZXIgeworICAgIC8vIFJlLWRlZmluZSBmb3IgcmV0dXJuIHR5cGUgY292YXJpYW5jZS4KKyAgICBNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKTsKKworICAgIC8qKiBDaGVjayBpZiBhIHNpbmd1bGFyIGV4dGVuc2lvbiBpcyBwcmVzZW50LiAqLworICAgIDxUeXBlPiBib29sZWFuIGhhc0V4dGVuc2lvbigKKyAgICAgICAgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uKTsKKworICAgIC8qKiBHZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICA8VHlwZT4gaW50IGdldEV4dGVuc2lvbkNvdW50KAorICAgICAgICBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24pOworCisgICAgLyoqIEdldCB0aGUgdmFsdWUgb2YgYW4gZXh0ZW5zaW9uLiAqLworICAgIDxUeXBlPiBUeXBlIGdldEV4dGVuc2lvbigKKyAgICAgICAgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uKTsKKworICAgIC8qKiBHZXQgb25lIGVsZW1lbnQgb2YgYSByZXBlYXRlZCBleHRlbnNpb24uICovCisgICAgPFR5cGU+IFR5cGUgZ2V0RXh0ZW5zaW9uKAorICAgICAgICBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24sCisgICAgICAgIGludCBpbmRleCk7CisgIH0KKworICAvKioKKyAgICogR2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3NlcyBmb3IgbWVzc2FnZSB0eXBlcyB0aGF0IGNvbnRhaW4gZXh0ZW5zaW9uIHJhbmdlcworICAgKiBzdWJjbGFzcyB0aGlzLgorICAgKgorICAgKiA8cD5UaGlzIGNsYXNzIGltcGxlbWVudHMgdHlwZS1zYWZlIGFjY2Vzc29ycyBmb3IgZXh0ZW5zaW9ucy4gIFRoZXkKKyAgICogaW1wbGVtZW50IGFsbCB0aGUgc2FtZSBvcGVyYXRpb25zIHRoYXQgeW91IGNhbiBkbyB3aXRoIG5vcm1hbCBmaWVsZHMgLS0KKyAgICogZS5nLiAiaGFzIiwgImdldCIsIGFuZCAiZ2V0Q291bnQiIC0tIGJ1dCBmb3IgZXh0ZW5zaW9ucy4gIFRoZSBleHRlbnNpb25zCisgICAqIGFyZSBpZGVudGlmaWVkIHVzaW5nIGluc3RhbmNlcyBvZiB0aGUgY2xhc3Mge0BsaW5rIEdlbmVyYXRlZEV4dGVuc2lvbn07CisgICAqIHRoZSBwcm90b2NvbCBjb21waWxlciBnZW5lcmF0ZXMgYSBzdGF0aWMgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmb3IgZXZlcnkKKyAgICogZXh0ZW5zaW9uIGluIGl0cyBpbnB1dC4gIFRocm91Z2ggdGhlIG1hZ2ljIG9mIGdlbmVyaWNzLCBhbGwgaXMgbWFkZQorICAgKiB0eXBlLXNhZmUuCisgICAqCisgICAqIDxwPkZvciBleGFtcGxlLCBpbWFnaW5lIHlvdSBoYXZlIHRoZSB7QGNvZGUgLnByb3RvfSBmaWxlOgorICAgKgorICAgKiA8cHJlPgorICAgKiBvcHRpb24gamF2YV9jbGFzcyA9ICJNeVByb3RvIjsKKyAgICoKKyAgICogbWVzc2FnZSBGb28geworICAgKiAgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7CisgICAqIH0KKyAgICoKKyAgICogZXh0ZW5kIEZvbyB7CisgICAqICAgb3B0aW9uYWwgaW50MzIgYmFyOworICAgKiB9CisgICAqIDwvcHJlPgorICAgKgorICAgKiA8cD5UaGVuIHlvdSBtaWdodCB3cml0ZSBjb2RlIGxpa2U6CisgICAqCisgICAqIDxwcmU+CisgICAqIE15UHJvdG8uRm9vIGZvbyA9IGdldEZvbygpOworICAgKiBpbnQgaSA9IGZvby5nZXRFeHRlbnNpb24oTXlQcm90by5iYXIpOworICAgKiA8L3ByZT4KKyAgICoKKyAgICogPHA+U2VlIGFsc28ge0BsaW5rIEV4dGVuZGFibGVCdWlsZGVyfS4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgRXh0ZW5kYWJsZU1lc3NhZ2U8CisgICAgICAgIE1lc3NhZ2VUeXBlIGV4dGVuZHMgRXh0ZW5kYWJsZU1lc3NhZ2U+CisgICAgICBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2UKKyAgICAgIGltcGxlbWVudHMgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8TWVzc2FnZVR5cGU+IHsKKworICAgIHByaXZhdGUgZmluYWwgRmllbGRTZXQ8RmllbGREZXNjcmlwdG9yPiBleHRlbnNpb25zOworCisgICAgcHJvdGVjdGVkIEV4dGVuZGFibGVNZXNzYWdlKCkgeworICAgICAgdGhpcy5leHRlbnNpb25zID0gRmllbGRTZXQubmV3RmllbGRTZXQoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgRXh0ZW5kYWJsZU1lc3NhZ2UoCisgICAgICAgIEV4dGVuZGFibGVCdWlsZGVyPE1lc3NhZ2VUeXBlLCA/PiBidWlsZGVyKSB7CisgICAgICBzdXBlcihidWlsZGVyKTsKKyAgICAgIHRoaXMuZXh0ZW5zaW9ucyA9IGJ1aWxkZXIuYnVpbGRFeHRlbnNpb25zKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKAorICAgICAgICBmaW5hbCBFeHRlbnNpb248TWVzc2FnZVR5cGUsID8+IGV4dGVuc2lvbikgeworICAgICAgaWYgKGV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCkuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPQorICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkpIHsKKyAgICAgICAgLy8gVGhpcyBjYW4gb25seSBoYXBwZW4gaWYgc29tZW9uZSB1c2VzIHVuY2hlY2tlZCBvcGVyYXRpb25zLgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJFeHRlbnNpb24gaXMgZm9yIHR5cGUgXCIiICsKKyAgICAgICAgICBleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpLmdldENvbnRhaW5pbmdUeXBlKCkuZ2V0RnVsbE5hbWUoKSArCisgICAgICAgICAgIlwiIHdoaWNoIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZSBcIiIgKworICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RnVsbE5hbWUoKSArICJcIi4iKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogQ2hlY2sgaWYgYSBzaW5ndWxhciBleHRlbnNpb24gaXMgcHJlc2VudC4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IGJvb2xlYW4gaGFzRXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb25MaXRlKSB7CisgICAgICBFeHRlbnNpb248TWVzc2FnZVR5cGUsIFR5cGU+IGV4dGVuc2lvbiA9IGNoZWNrTm90TGl0ZShleHRlbnNpb25MaXRlKTsKKworICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uKTsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmhhc0ZpZWxkKGV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCkpOworICAgIH0KKworICAgIC8qKiBHZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IGludCBnZXRFeHRlbnNpb25Db3VudCgKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uTGl0ZSkgeworICAgICAgRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24gPSBjaGVja05vdExpdGUoZXh0ZW5zaW9uTGl0ZSk7CisKKyAgICAgIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKGV4dGVuc2lvbik7CisgICAgICBmaW5hbCBGaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IGV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCk7CisgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZGVzY3JpcHRvcik7CisgICAgfQorCisgICAgLyoqIEdldCB0aGUgdmFsdWUgb2YgYW4gZXh0ZW5zaW9uLiAqLworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gVHlwZSBnZXRFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIFR5cGU+IGV4dGVuc2lvbkxpdGUpIHsKKyAgICAgIEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uID0gY2hlY2tOb3RMaXRlKGV4dGVuc2lvbkxpdGUpOworCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb24pOworICAgICAgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpOworICAgICAgZmluYWwgT2JqZWN0IHZhbHVlID0gZXh0ZW5zaW9ucy5nZXRGaWVsZChkZXNjcmlwdG9yKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIGlmIChkZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgIHJldHVybiAoVHlwZSkgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgIH0gZWxzZSBpZiAoZGVzY3JpcHRvci5nZXRKYXZhVHlwZSgpID09CisgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgICByZXR1cm4gKFR5cGUpIGV4dGVuc2lvbi5nZXRNZXNzYWdlRGVmYXVsdEluc3RhbmNlKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIChUeXBlKSBleHRlbnNpb24uZnJvbVJlZmxlY3Rpb25UeXBlKAorICAgICAgICAgICAgICBkZXNjcmlwdG9yLmdldERlZmF1bHRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIChUeXBlKSBleHRlbnNpb24uZnJvbVJlZmxlY3Rpb25UeXBlKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogR2V0IG9uZSBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgZXh0ZW5zaW9uLiAqLworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gVHlwZSBnZXRFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbkxpdGUsCisgICAgICAgIGZpbmFsIGludCBpbmRleCkgeworICAgICAgRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24gPSBjaGVja05vdExpdGUoZXh0ZW5zaW9uTGl0ZSk7CisKKyAgICAgIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKGV4dGVuc2lvbik7CisgICAgICBGaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IGV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCk7CisgICAgICByZXR1cm4gKFR5cGUpIGV4dGVuc2lvbi5zaW5ndWxhckZyb21SZWZsZWN0aW9uVHlwZSgKKyAgICAgICAgICBleHRlbnNpb25zLmdldFJlcGVhdGVkRmllbGQoZGVzY3JpcHRvciwgaW5kZXgpKTsKKyAgICB9CisKKyAgICAvKiogQ2FsbGVkIGJ5IHN1YmNsYXNzZXMgdG8gY2hlY2sgaWYgYWxsIGV4dGVuc2lvbnMgYXJlIGluaXRpYWxpemVkLiAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpIHsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmlzSW5pdGlhbGl6ZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgeworICAgICAgcmV0dXJuIHN1cGVyLmlzSW5pdGlhbGl6ZWQoKSAmJiBleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZVVua25vd25GaWVsZCgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgVW5rbm93bkZpZWxkU2V0LkJ1aWxkZXIgdW5rbm93bkZpZWxkcywKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICBpbnQgdGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIE1lc3NhZ2VSZWZsZWN0aW9uLm1lcmdlRmllbGRGcm9tKAorICAgICAgICAgIGlucHV0LCB1bmtub3duRmllbGRzLCBleHRlbnNpb25SZWdpc3RyeSwgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSwKKyAgICAgICAgICBuZXcgTWVzc2FnZVJlZmxlY3Rpb24uRXh0ZW5zaW9uQWRhcHRlcihleHRlbnNpb25zKSwgdGFnKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFVzZWQgYnkgcGFyc2luZyBjb25zdHJ1Y3RvcnMgaW4gZ2VuZXJhdGVkIGNsYXNzZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgbWFrZUV4dGVuc2lvbnNJbW11dGFibGUoKSB7CisgICAgICBleHRlbnNpb25zLm1ha2VJbW11dGFibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGJ5IHN1YmNsYXNzZXMgdG8gc2VyaWFsaXplIGV4dGVuc2lvbnMuICBFeHRlbnNpb24gcmFuZ2VzIG1heSBiZQorICAgICAqIGludGVybGVhdmVkIHdpdGggZmllbGQgbnVtYmVycywgYnV0IHdlIG11c3Qgd3JpdGUgdGhlbSBpbiBjYW5vbmljYWwKKyAgICAgKiAoc29ydGVkIGJ5IGZpZWxkIG51bWJlcikgb3JkZXIuICBFeHRlbnNpb25Xcml0ZXIgaGVscHMgdXMgd3JpdGUKKyAgICAgKiBpbmRpdmlkdWFsIHJhbmdlcyBvZiBleHRlbnNpb25zIGF0IG9uY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGNsYXNzIEV4dGVuc2lvbldyaXRlciB7CisgICAgICAvLyBJbWFnaW5lIGhvdyBtdWNoIHNpbXBsZXIgdGhpcyBjb2RlIHdvdWxkIGJlIGlmIEphdmEgaXRlcmF0b3JzIGhhZAorICAgICAgLy8gYSB3YXkgdG8gZ2V0IHRoZSBuZXh0IGVsZW1lbnQgd2l0aG91dCBhZHZhbmNpbmcgdGhlIGl0ZXJhdG9yLgorCisgICAgICBwcml2YXRlIGZpbmFsIEl0ZXJhdG9yPE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4+IGl0ZXIgPQorICAgICAgICBleHRlbnNpb25zLml0ZXJhdG9yKCk7CisgICAgICBwcml2YXRlIE1hcC5FbnRyeTxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gbmV4dDsKKyAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBtZXNzYWdlU2V0V2lyZUZvcm1hdDsKKworICAgICAgcHJpdmF0ZSBFeHRlbnNpb25Xcml0ZXIoZmluYWwgYm9vbGVhbiBtZXNzYWdlU2V0V2lyZUZvcm1hdCkgeworICAgICAgICBpZiAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICBuZXh0ID0gaXRlci5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5tZXNzYWdlU2V0V2lyZUZvcm1hdCA9IG1lc3NhZ2VTZXRXaXJlRm9ybWF0OworICAgICAgfQorCisgICAgICBwdWJsaWMgdm9pZCB3cml0ZVVudGlsKGZpbmFsIGludCBlbmQsIGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd2hpbGUgKG5leHQgIT0gbnVsbCAmJiBuZXh0LmdldEtleSgpLmdldE51bWJlcigpIDwgZW5kKSB7CisgICAgICAgICAgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBuZXh0LmdldEtleSgpOworICAgICAgICAgIGlmIChtZXNzYWdlU2V0V2lyZUZvcm1hdCAmJiBkZXNjcmlwdG9yLmdldExpdGVKYXZhVHlwZSgpID09CisgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0LkphdmFUeXBlLk1FU1NBR0UgJiYKKyAgICAgICAgICAgICAgIWRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgICAgICBpZiAobmV4dCBpbnN0YW5jZW9mIExhenlGaWVsZC5MYXp5RW50cnk8Pz4pIHsKKyAgICAgICAgICAgICAgb3V0cHV0LndyaXRlUmF3TWVzc2FnZVNldEV4dGVuc2lvbihkZXNjcmlwdG9yLmdldE51bWJlcigpLAorICAgICAgICAgICAgICAgICAgKChMYXp5RmllbGQuTGF6eUVudHJ5PD8+KSBuZXh0KS5nZXRGaWVsZCgpLnRvQnl0ZVN0cmluZygpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2VTZXRFeHRlbnNpb24oZGVzY3JpcHRvci5nZXROdW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWVzc2FnZSkgbmV4dC5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVE9ETyh4aWFuZ2wpOiBUYWtlbiBjYXJlIG9mIGZvbGxvd2luZyBjb2RlLCBpdCBtYXkgY2F1c2UKKyAgICAgICAgICAgIC8vIHByb2JsZW0gd2hlbiB3ZSB1c2UgTGF6eUZpZWxkIGZvciBub3JtYWwgZmllbGRzL2V4dGVuc2lvbnMuCisgICAgICAgICAgICAvLyBEdWUgdG8gdGhlIG9wdGlvbmFsIGZpZWxkIGNhbiBiZSBkdXBsaWNhdGVkIGF0IHRoZSBlbmQgb2YKKyAgICAgICAgICAgIC8vIHNlcmlhbGl6ZWQgYnl0ZXMsIHdoaWNoIHdpbGwgbWFrZSB0aGUgc2VyaWFsaXplZCBzaXplIGNoYW5nZQorICAgICAgICAgICAgLy8gYWZ0ZXIgbGF6eSBmaWVsZCBwYXJzZWQuIFNvIHdoZW4gd2UgdXNlIExhenlGaWVsZCBnbG9iYWxseSwKKyAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gY2hhbmdlIHRoZSBmb2xsb3dpbmcgd3JpdGUgbWV0aG9kIHRvIHdyaXRlIGNhY2hlZAorICAgICAgICAgICAgLy8gYnl0ZXMgZGlyZWN0bHkgcmF0aGVyIHRoYW4gd3JpdGUgdGhlIHBhcnNlZCBtZXNzYWdlLgorICAgICAgICAgICAgRmllbGRTZXQud3JpdGVGaWVsZChkZXNjcmlwdG9yLCBuZXh0LmdldFZhbHVlKCksIG91dHB1dCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChpdGVyLmhhc05leHQoKSkgeworICAgICAgICAgICAgbmV4dCA9IGl0ZXIubmV4dCgpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgRXh0ZW5zaW9uV3JpdGVyIG5ld0V4dGVuc2lvbldyaXRlcigpIHsKKyAgICAgIHJldHVybiBuZXcgRXh0ZW5zaW9uV3JpdGVyKGZhbHNlKTsKKyAgICB9CisgICAgcHJvdGVjdGVkIEV4dGVuc2lvbldyaXRlciBuZXdNZXNzYWdlU2V0RXh0ZW5zaW9uV3JpdGVyKCkgeworICAgICAgcmV0dXJuIG5ldyBFeHRlbnNpb25Xcml0ZXIodHJ1ZSk7CisgICAgfQorCisgICAgLyoqIENhbGxlZCBieSBzdWJjbGFzc2VzIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgZXh0ZW5zaW9ucy4gKi8KKyAgICBwcm90ZWN0ZWQgaW50IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgfQorICAgIHByb3RlY3RlZCBpbnQgZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplQXNNZXNzYWdlU2V0KCkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0TWVzc2FnZVNldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gUmVmbGVjdGlvbgorCisgICAgcHJvdGVjdGVkIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZ2V0RXh0ZW5zaW9uRmllbGRzKCkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0QWxsRmllbGRzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZ2V0QWxsRmllbGRzKCkgeworICAgICAgZmluYWwgTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiByZXN1bHQgPQorICAgICAgICAgIHN1cGVyLmdldEFsbEZpZWxkc011dGFibGUoLyogZ2V0Qnl0ZXNGb3JTdHJpbmcgPSAqLyBmYWxzZSk7CisgICAgICByZXN1bHQucHV0QWxsKGdldEV4dGVuc2lvbkZpZWxkcygpKTsKKyAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAocmVzdWx0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBnZXRBbGxGaWVsZHNSYXcoKSB7CisgICAgICBmaW5hbCBNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IHJlc3VsdCA9CisgICAgICAgICAgc3VwZXIuZ2V0QWxsRmllbGRzTXV0YWJsZSgvKiBnZXRCeXRlc0ZvclN0cmluZyA9ICovIGZhbHNlKTsKKyAgICAgIHJlc3VsdC5wdXRBbGwoZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChyZXN1bHQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgaWYgKGZpZWxkLmlzRXh0ZW5zaW9uKCkpIHsKKyAgICAgICAgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmllbGQpOworICAgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5oYXNGaWVsZChmaWVsZCk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gc3VwZXIuaGFzRmllbGQoZmllbGQpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuaXNFeHRlbnNpb24oKSkgeworICAgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGV4dGVuc2lvbnMuZ2V0RmllbGQoZmllbGQpOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgICAvLyBMYWNraW5nIGFuIEV4dGVuc2lvblJlZ2lzdHJ5LCB3ZSBoYXZlIG5vIHdheSB0byBkZXRlcm1pbmUgdGhlCisgICAgICAgICAgICAvLyBleHRlbnNpb24ncyByZWFsIHR5cGUsIHNvIHdlIHJldHVybiBhIER5bmFtaWNNZXNzYWdlLgorICAgICAgICAgICAgcmV0dXJuIER5bmFtaWNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZShmaWVsZC5nZXRNZXNzYWdlVHlwZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZpZWxkLmdldERlZmF1bHRWYWx1ZSgpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzdXBlci5nZXRGaWVsZChmaWVsZCk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuaXNFeHRlbnNpb24oKSkgeworICAgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLmdldFJlcGVhdGVkRmllbGRDb3VudChmaWVsZCk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpZWxkKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkRmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgIGlmIChmaWVsZC5pc0V4dGVuc2lvbigpKSB7CisgICAgICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmdldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5Q29udGFpbmluZ1R5cGUoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSBnZXREZXNjcmlwdG9yRm9yVHlwZSgpKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvciBkb2VzIG5vdCBtYXRjaCBtZXNzYWdlIHR5cGUuIik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEdlbmVyYXRlZCBtZXNzYWdlIGJ1aWxkZXJzIGZvciBtZXNzYWdlIHR5cGVzIHRoYXQgY29udGFpbiBleHRlbnNpb24gcmFuZ2VzCisgICAqIHN1YmNsYXNzIHRoaXMuCisgICAqCisgICAqIDxwPlRoaXMgY2xhc3MgaW1wbGVtZW50cyB0eXBlLXNhZmUgYWNjZXNzb3JzIGZvciBleHRlbnNpb25zLiAgVGhleQorICAgKiBpbXBsZW1lbnQgYWxsIHRoZSBzYW1lIG9wZXJhdGlvbnMgdGhhdCB5b3UgY2FuIGRvIHdpdGggbm9ybWFsIGZpZWxkcyAtLQorICAgKiBlLmcuICJnZXQiLCAic2V0IiwgYW5kICJhZGQiIC0tIGJ1dCBmb3IgZXh0ZW5zaW9ucy4gIFRoZSBleHRlbnNpb25zIGFyZQorICAgKiBpZGVudGlmaWVkIHVzaW5nIGluc3RhbmNlcyBvZiB0aGUgY2xhc3Mge0BsaW5rIEdlbmVyYXRlZEV4dGVuc2lvbn07IHRoZQorICAgKiBwcm90b2NvbCBjb21waWxlciBnZW5lcmF0ZXMgYSBzdGF0aWMgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmb3IgZXZlcnkKKyAgICogZXh0ZW5zaW9uIGluIGl0cyBpbnB1dC4gIFRocm91Z2ggdGhlIG1hZ2ljIG9mIGdlbmVyaWNzLCBhbGwgaXMgbWFkZQorICAgKiB0eXBlLXNhZmUuCisgICAqCisgICAqIDxwPkZvciBleGFtcGxlLCBpbWFnaW5lIHlvdSBoYXZlIHRoZSB7QGNvZGUgLnByb3RvfSBmaWxlOgorICAgKgorICAgKiA8cHJlPgorICAgKiBvcHRpb24gamF2YV9jbGFzcyA9ICJNeVByb3RvIjsKKyAgICoKKyAgICogbWVzc2FnZSBGb28geworICAgKiAgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7CisgICAqIH0KKyAgICoKKyAgICogZXh0ZW5kIEZvbyB7CisgICAqICAgb3B0aW9uYWwgaW50MzIgYmFyOworICAgKiB9CisgICAqIDwvcHJlPgorICAgKgorICAgKiA8cD5UaGVuIHlvdSBtaWdodCB3cml0ZSBjb2RlIGxpa2U6CisgICAqCisgICAqIDxwcmU+CisgICAqIE15UHJvdG8uRm9vIGZvbyA9CisgICAqICAgTXlQcm90by5Gb28ubmV3QnVpbGRlcigpCisgICAqICAgICAuc2V0RXh0ZW5zaW9uKE15UHJvdG8uYmFyLCAxMjMpCisgICAqICAgICAuYnVpbGQoKTsKKyAgICogPC9wcmU+CisgICAqCisgICAqIDxwPlNlZSBhbHNvIHtAbGluayBFeHRlbmRhYmxlTWVzc2FnZX0uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBFeHRlbmRhYmxlQnVpbGRlcjwKKyAgICAgICAgTWVzc2FnZVR5cGUgZXh0ZW5kcyBFeHRlbmRhYmxlTWVzc2FnZSwKKyAgICAgICAgQnVpbGRlclR5cGUgZXh0ZW5kcyBFeHRlbmRhYmxlQnVpbGRlcj4KKyAgICAgIGV4dGVuZHMgQnVpbGRlcjxCdWlsZGVyVHlwZT4KKyAgICAgIGltcGxlbWVudHMgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8TWVzc2FnZVR5cGU+IHsKKworICAgIHByaXZhdGUgRmllbGRTZXQ8RmllbGREZXNjcmlwdG9yPiBleHRlbnNpb25zID0gRmllbGRTZXQuZW1wdHlTZXQoKTsKKworICAgIHByb3RlY3RlZCBFeHRlbmRhYmxlQnVpbGRlcigpIHt9CisKKyAgICBwcm90ZWN0ZWQgRXh0ZW5kYWJsZUJ1aWxkZXIoCisgICAgICAgIEJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CisgICAgICBzdXBlcihwYXJlbnQpOworICAgIH0KKworICAgIC8vIEZvciBpbW11dGFibGUgbWVzc2FnZSBjb252ZXJzaW9uLgorICAgIHZvaWQgaW50ZXJuYWxTZXRFeHRlbnNpb25TZXQoRmllbGRTZXQ8RmllbGREZXNjcmlwdG9yPiBleHRlbnNpb25zKSB7CisgICAgICB0aGlzLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBjbGVhcigpIHsKKyAgICAgIGV4dGVuc2lvbnMgPSBGaWVsZFNldC5lbXB0eVNldCgpOworICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyKCk7CisgICAgfQorCisgICAgLy8gVGhpcyBpcyBpbXBsZW1lbnRlZCBoZXJlIG9ubHkgdG8gd29yayBhcm91bmQgYW4gYXBwYXJlbnQgYnVnIGluIHRoZQorICAgIC8vIEphdmEgY29tcGlsZXIgYW5kL29yIGJ1aWxkIHN5c3RlbS4gIFNlZSBidWcgIzE4OTg0NjMuICBUaGUgbWVyZSBwcmVzZW5jZQorICAgIC8vIG9mIHRoaXMgY2xvbmUoKSBpbXBsZW1lbnRhdGlvbiBtYWtlcyBpdCBnbyBhd2F5LgorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbnN1cmVFeHRlbnNpb25zSXNNdXRhYmxlKCkgeworICAgICAgaWYgKGV4dGVuc2lvbnMuaXNJbW11dGFibGUoKSkgeworICAgICAgICBleHRlbnNpb25zID0gZXh0ZW5zaW9ucy5jbG9uZSgpOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZSgKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCA/PiBleHRlbnNpb24pIHsKKyAgICAgIGlmIChleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpLmdldENvbnRhaW5pbmdUeXBlKCkgIT0KKyAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpKSB7CisgICAgICAgIC8vIFRoaXMgY2FuIG9ubHkgaGFwcGVuIGlmIHNvbWVvbmUgdXNlcyB1bmNoZWNrZWQgb3BlcmF0aW9ucy4KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiRXh0ZW5zaW9uIGlzIGZvciB0eXBlIFwiIiArCisgICAgICAgICAgZXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKS5nZXRDb250YWluaW5nVHlwZSgpLmdldEZ1bGxOYW1lKCkgKworICAgICAgICAgICJcIiB3aGljaCBkb2VzIG5vdCBtYXRjaCBtZXNzYWdlIHR5cGUgXCIiICsKKyAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpLmdldEZ1bGxOYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgfQorCisgICAgLyoqIENoZWNrIGlmIGEgc2luZ3VsYXIgZXh0ZW5zaW9uIGlzIHByZXNlbnQuICovCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIGZpbmFsIDxUeXBlPiBib29sZWFuIGhhc0V4dGVuc2lvbigKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uTGl0ZSkgeworICAgICAgRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb24gPSBjaGVja05vdExpdGUoZXh0ZW5zaW9uTGl0ZSk7CisKKyAgICAgIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKGV4dGVuc2lvbik7CisgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5oYXNGaWVsZChleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpKTsKKyAgICB9CisKKyAgICAvKiogR2V0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gYSByZXBlYXRlZCBleHRlbnNpb24uICovCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIGZpbmFsIDxUeXBlPiBpbnQgZ2V0RXh0ZW5zaW9uQ291bnQoCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbkxpdGUpIHsKKyAgICAgIEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uID0gY2hlY2tOb3RMaXRlKGV4dGVuc2lvbkxpdGUpOworCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb24pOworICAgICAgZmluYWwgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpOworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGRlc2NyaXB0b3IpOworICAgIH0KKworICAgIC8qKiBHZXQgdGhlIHZhbHVlIG9mIGFuIGV4dGVuc2lvbi4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IFR5cGUgZ2V0RXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb25MaXRlKSB7CisgICAgICBFeHRlbnNpb248TWVzc2FnZVR5cGUsIFR5cGU+IGV4dGVuc2lvbiA9IGNoZWNrTm90TGl0ZShleHRlbnNpb25MaXRlKTsKKworICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uKTsKKyAgICAgIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKTsKKyAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGV4dGVuc2lvbnMuZ2V0RmllbGQoZGVzY3JpcHRvcik7CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICBpZiAoZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICByZXR1cm4gKFR5cGUpIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworICAgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3IuZ2V0SmF2YVR5cGUoKSA9PQorICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgcmV0dXJuIChUeXBlKSBleHRlbnNpb24uZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiAoVHlwZSkgZXh0ZW5zaW9uLmZyb21SZWZsZWN0aW9uVHlwZSgKKyAgICAgICAgICAgICAgZGVzY3JpcHRvci5nZXREZWZhdWx0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAoVHlwZSkgZXh0ZW5zaW9uLmZyb21SZWZsZWN0aW9uVHlwZSh2YWx1ZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqIEdldCBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IFR5cGUgZ2V0RXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb25MaXRlLAorICAgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgIEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uID0gY2hlY2tOb3RMaXRlKGV4dGVuc2lvbkxpdGUpOworCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb24pOworICAgICAgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpOworICAgICAgcmV0dXJuIChUeXBlKSBleHRlbnNpb24uc2luZ3VsYXJGcm9tUmVmbGVjdGlvblR5cGUoCisgICAgICAgICAgZXh0ZW5zaW9ucy5nZXRSZXBlYXRlZEZpZWxkKGRlc2NyaXB0b3IsIGluZGV4KSk7CisgICAgfQorCisgICAgLyoqIFNldCB0aGUgdmFsdWUgb2YgYW4gZXh0ZW5zaW9uLiAqLworICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gQnVpbGRlclR5cGUgc2V0RXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb25MaXRlLAorICAgICAgICBmaW5hbCBUeXBlIHZhbHVlKSB7CisgICAgICBFeHRlbnNpb248TWVzc2FnZVR5cGUsIFR5cGU+IGV4dGVuc2lvbiA9IGNoZWNrTm90TGl0ZShleHRlbnNpb25MaXRlKTsKKworICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uKTsKKyAgICAgIGVuc3VyZUV4dGVuc2lvbnNJc011dGFibGUoKTsKKyAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKTsKKyAgICAgIGV4dGVuc2lvbnMuc2V0RmllbGQoZGVzY3JpcHRvciwgZXh0ZW5zaW9uLnRvUmVmbGVjdGlvblR5cGUodmFsdWUpKTsKKyAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0IHRoZSB2YWx1ZSBvZiBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IEJ1aWxkZXJUeXBlIHNldEV4dGVuc2lvbigKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uTGl0ZSwKKyAgICAgICAgZmluYWwgaW50IGluZGV4LCBmaW5hbCBUeXBlIHZhbHVlKSB7CisgICAgICBFeHRlbnNpb248TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbiA9IGNoZWNrTm90TGl0ZShleHRlbnNpb25MaXRlKTsKKworICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uKTsKKyAgICAgIGVuc3VyZUV4dGVuc2lvbnNJc011dGFibGUoKTsKKyAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKTsKKyAgICAgIGV4dGVuc2lvbnMuc2V0UmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgZGVzY3JpcHRvciwgaW5kZXgsCisgICAgICAgIGV4dGVuc2lvbi5zaW5ndWxhclRvUmVmbGVjdGlvblR5cGUodmFsdWUpKTsKKyAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvKiogQXBwZW5kIGEgdmFsdWUgdG8gYSByZXBlYXRlZCBleHRlbnNpb24uICovCisgICAgcHVibGljIGZpbmFsIDxUeXBlPiBCdWlsZGVyVHlwZSBhZGRFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbkxpdGUsCisgICAgICAgIGZpbmFsIFR5cGUgdmFsdWUpIHsKKyAgICAgIEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uID0gY2hlY2tOb3RMaXRlKGV4dGVuc2lvbkxpdGUpOworCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb24pOworICAgICAgZW5zdXJlRXh0ZW5zaW9uc0lzTXV0YWJsZSgpOworICAgICAgZmluYWwgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBleHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpOworICAgICAgZXh0ZW5zaW9ucy5hZGRSZXBlYXRlZEZpZWxkKAorICAgICAgICAgIGRlc2NyaXB0b3IsIGV4dGVuc2lvbi5zaW5ndWxhclRvUmVmbGVjdGlvblR5cGUodmFsdWUpKTsKKyAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvKiogQ2xlYXIgYW4gZXh0ZW5zaW9uLiAqLworICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gQnVpbGRlclR5cGUgY2xlYXJFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsID8+IGV4dGVuc2lvbkxpdGUpIHsKKyAgICAgIEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgPz4gZXh0ZW5zaW9uID0gY2hlY2tOb3RMaXRlKGV4dGVuc2lvbkxpdGUpOworCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb24pOworICAgICAgZW5zdXJlRXh0ZW5zaW9uc0lzTXV0YWJsZSgpOworICAgICAgZXh0ZW5zaW9ucy5jbGVhckZpZWxkKGV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCkpOworICAgICAgb25DaGFuZ2VkKCk7CisgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSB0aGlzOworICAgIH0KKworICAgIC8qKiBDYWxsZWQgYnkgc3ViY2xhc3NlcyB0byBjaGVjayBpZiBhbGwgZXh0ZW5zaW9ucyBhcmUgaW5pdGlhbGl6ZWQuICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuaXNJbml0aWFsaXplZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxlZCBieSB0aGUgYnVpbGQgY29kZSBwYXRoIHRvIGNyZWF0ZSBhIGNvcHkgb2YgdGhlIGV4dGVuc2lvbnMgZm9yCisgICAgICogYnVpbGRpbmcgdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBGaWVsZFNldDxGaWVsZERlc2NyaXB0b3I+IGJ1aWxkRXh0ZW5zaW9ucygpIHsKKyAgICAgIGV4dGVuc2lvbnMubWFrZUltbXV0YWJsZSgpOworICAgICAgcmV0dXJuIGV4dGVuc2lvbnM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICAgIHJldHVybiBzdXBlci5pc0luaXRpYWxpemVkKCkgJiYgZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IHN1YmNsYXNzZXMgdG8gcGFyc2UgYW4gdW5rbm93biBmaWVsZCBvciBhbiBleHRlbnNpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gdW5sZXNzIHRoZSB0YWcgaXMgYW4gZW5kLWdyb3VwIHRhZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZVVua25vd25GaWVsZCgKKyAgICAgICAgZmluYWwgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgZmluYWwgVW5rbm93bkZpZWxkU2V0LkJ1aWxkZXIgdW5rbm93bkZpZWxkcywKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICBmaW5hbCBpbnQgdGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIE1lc3NhZ2VSZWZsZWN0aW9uLm1lcmdlRmllbGRGcm9tKAorICAgICAgICAgIGlucHV0LCB1bmtub3duRmllbGRzLCBleHRlbnNpb25SZWdpc3RyeSwgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSwKKyAgICAgICAgICBuZXcgTWVzc2FnZVJlZmxlY3Rpb24uQnVpbGRlckFkYXB0ZXIodGhpcyksIHRhZyk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gUmVmbGVjdGlvbgorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZ2V0QWxsRmllbGRzKCkgeworICAgICAgZmluYWwgTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiByZXN1bHQgPSBzdXBlci5nZXRBbGxGaWVsZHNNdXRhYmxlKCk7CisgICAgICByZXN1bHQucHV0QWxsKGV4dGVuc2lvbnMuZ2V0QWxsRmllbGRzKCkpOworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChyZXN1bHQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuaXNFeHRlbnNpb24oKSkgeworICAgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGV4dGVuc2lvbnMuZ2V0RmllbGQoZmllbGQpOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgICAvLyBMYWNraW5nIGFuIEV4dGVuc2lvblJlZ2lzdHJ5LCB3ZSBoYXZlIG5vIHdheSB0byBkZXRlcm1pbmUgdGhlCisgICAgICAgICAgICAvLyBleHRlbnNpb24ncyByZWFsIHR5cGUsIHNvIHdlIHJldHVybiBhIER5bmFtaWNNZXNzYWdlLgorICAgICAgICAgICAgcmV0dXJuIER5bmFtaWNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZShmaWVsZC5nZXRNZXNzYWdlVHlwZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZpZWxkLmdldERlZmF1bHRWYWx1ZSgpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzdXBlci5nZXRGaWVsZChmaWVsZCk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuaXNFeHRlbnNpb24oKSkgeworICAgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLmdldFJlcGVhdGVkRmllbGRDb3VudChmaWVsZCk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpZWxkKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkRmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgIGlmIChmaWVsZC5pc0V4dGVuc2lvbigpKSB7CisgICAgICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmdldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGlmIChmaWVsZC5pc0V4dGVuc2lvbigpKSB7CisgICAgICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuaGFzRmllbGQoZmllbGQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmhhc0ZpZWxkKGZpZWxkKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgc2V0RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGlmIChmaWVsZC5pc0V4dGVuc2lvbigpKSB7CisgICAgICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICAgICAgZW5zdXJlRXh0ZW5zaW9uc0lzTXV0YWJsZSgpOworICAgICAgICBleHRlbnNpb25zLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSB0aGlzOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIGNsZWFyRmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuaXNFeHRlbnNpb24oKSkgeworICAgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICAgIGVuc3VyZUV4dGVuc2lvbnNJc011dGFibGUoKTsKKyAgICAgICAgZXh0ZW5zaW9ucy5jbGVhckZpZWxkKGZpZWxkKTsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIHNldFJlcGVhdGVkRmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBpZiAoZmllbGQuaXNFeHRlbnNpb24oKSkgeworICAgICAgICB2ZXJpZnlDb250YWluaW5nVHlwZShmaWVsZCk7CisgICAgICAgIGVuc3VyZUV4dGVuc2lvbnNJc011dGFibGUoKTsKKyAgICAgICAgZXh0ZW5zaW9ucy5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOworICAgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBhZGRSZXBlYXRlZEZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGlmIChmaWVsZC5pc0V4dGVuc2lvbigpKSB7CisgICAgICAgIHZlcmlmeUNvbnRhaW5pbmdUeXBlKGZpZWxkKTsKKyAgICAgICAgZW5zdXJlRXh0ZW5zaW9uc0lzTXV0YWJsZSgpOworICAgICAgICBleHRlbnNpb25zLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIG1lcmdlRXh0ZW5zaW9uRmllbGRzKGZpbmFsIEV4dGVuZGFibGVNZXNzYWdlIG90aGVyKSB7CisgICAgICBlbnN1cmVFeHRlbnNpb25zSXNNdXRhYmxlKCk7CisgICAgICBleHRlbnNpb25zLm1lcmdlRnJvbShvdGhlci5leHRlbnNpb25zKTsKKyAgICAgIG9uQ2hhbmdlZCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlDb250YWluaW5nVHlwZShmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGlmIChmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpICE9IGdldERlc2NyaXB0b3JGb3JUeXBlKCkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiRmllbGREZXNjcmlwdG9yIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBkZXNjcmlwdG9yIGZvciBhbiBleHRlbnNpb24uIFRoZSBpbXBsZW1lbnRhdGlvbiBkZXBlbmRzIG9uIHdoZXRoZXIKKyAgICogdGhlIGV4dGVuc2lvbiBpcyBzY29wZWQgaW4gdGhlIHRvcCBsZXZlbCBvZiBhIGZpbGUgb3Igc2NvcGVkIGluIGEgTWVzc2FnZS4KKyAgICovCisgIHN0YXRpYyBpbnRlcmZhY2UgRXh0ZW5zaW9uRGVzY3JpcHRvclJldHJpZXZlciB7CisgICAgRmllbGREZXNjcmlwdG9yIGdldERlc2NyaXB0b3IoKTsKKyAgfQorCisgIC8qKiBGb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuICovCisgIHB1YmxpYyBzdGF0aWMgPENvbnRhaW5pbmdUeXBlIGV4dGVuZHMgTWVzc2FnZSwgVHlwZT4KKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4KKyAgICAgIG5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oZmluYWwgTWVzc2FnZSBzY29wZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGRlc2NyaXB0b3JJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQ2xhc3Mgc2luZ3VsYXJUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlIGRlZmF1bHRJbnN0YW5jZSkgeworICAgIC8vIEZvciBleHRlbnNpb25zIHNjb3BlZCB3aXRoaW4gYSBNZXNzYWdlLCB3ZSB1c2UgdGhlIE1lc3NhZ2UgdG8gcmVzb2x2ZQorICAgIC8vIHRoZSBvdXRlciBjbGFzcydzIGRlc2NyaXB0b3IsIGZyb20gd2hpY2ggdGhlIGV4dGVuc2lvbiBkZXNjcmlwdG9yIGlzCisgICAgLy8gb2J0YWluZWQuCisgICAgcmV0dXJuIG5ldyBHZW5lcmF0ZWRFeHRlbnNpb248Q29udGFpbmluZ1R5cGUsIFR5cGU+KAorICAgICAgICBuZXcgQ2FjaGVkRGVzY3JpcHRvclJldHJpZXZlcigpIHsKKyAgICAgICAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICAgICAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGxvYWREZXNjcmlwdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIHNjb3BlLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RXh0ZW5zaW9ucygpCisgICAgICAgICAgICAgICAgLmdldChkZXNjcmlwdG9ySW5kZXgpOworICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgc2luZ3VsYXJUeXBlLAorICAgICAgICBkZWZhdWx0SW5zdGFuY2UsCisgICAgICAgIEV4dGVuc2lvbi5FeHRlbnNpb25UeXBlLklNTVVUQUJMRSk7CisgIH0KKworICAvKiogRm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiAqLworICBwdWJsaWMgc3RhdGljIDxDb250YWluaW5nVHlwZSBleHRlbmRzIE1lc3NhZ2UsIFR5cGU+CisgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4KKyAgICAgbmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbihmaW5hbCBDbGFzcyBzaW5ndWxhclR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2UpIHsKKyAgICAvLyBGb3IgZXh0ZW5zaW9ucyBzY29wZWQgd2l0aGluIGEgZmlsZSwgd2UgcmVseSBvbiB0aGUgb3V0ZXIgY2xhc3MncworICAgIC8vIHN0YXRpYyBpbml0aWFsaXplciB0byBjYWxsIGludGVybmFsSW5pdCgpIG9uIHRoZSBleHRlbnNpb24gd2hlbiB0aGUKKyAgICAvLyBkZXNjcmlwdG9yIGlzIGF2YWlsYWJsZS4KKyAgICByZXR1cm4gbmV3IEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4oCisgICAgICAgIG51bGwsICAvLyBFeHRlbnNpb25EZXNjcmlwdG9yUmV0cmlldmVyIGlzIGluaXRpYWxpemVkIGluIGludGVybmFsSW5pdCgpOworICAgICAgICBzaW5ndWxhclR5cGUsCisgICAgICAgIGRlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgRXh0ZW5zaW9uLkV4dGVuc2lvblR5cGUuSU1NVVRBQkxFKTsKKyAgfQorCisgIHByaXZhdGUgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIENhY2hlZERlc2NyaXB0b3JSZXRyaWV2ZXIKKyAgICAgIGltcGxlbWVudHMgRXh0ZW5zaW9uRGVzY3JpcHRvclJldHJpZXZlciB7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBGaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgRmllbGREZXNjcmlwdG9yIGxvYWREZXNjcmlwdG9yKCk7CisKKyAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldERlc2NyaXB0b3IoKSB7CisgICAgICBpZiAoZGVzY3JpcHRvciA9PSBudWxsKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgIGlmIChkZXNjcmlwdG9yID09IG51bGwpIHsKKyAgICAgICAgICAgIGRlc2NyaXB0b3IgPSBsb2FkRGVzY3JpcHRvcigpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFVzZWQgaW4gcHJvdG8xIGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAqCisgICAqIEFmdGVyIGVuYWJsaW5nIGJyaWRnZSwgd2UgY2FuIGRlZmluZSBwcm90bzIgZXh0ZW5zaW9ucyAodGhlIGV4dGVuZGVkIHR5cGUKKyAgICogaXMgYSBwcm90bzIgbXV0YWJsZSBtZXNzYWdlKSBpbiBhIHByb3RvMSAucHJvdG8gZmlsZS4gRm9yIHRoZXNlIGV4dGVuc2lvbnMKKyAgICogd2Ugc2hvdWxkIGdlbmVyYXRlIHByb3RvMiBHZW5lcmF0ZWRFeHRlbnNpb25zLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8Q29udGFpbmluZ1R5cGUgZXh0ZW5kcyBNZXNzYWdlLCBUeXBlPgorICAgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPENvbnRhaW5pbmdUeXBlLCBUeXBlPgorICAgICAgbmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICBmaW5hbCBNZXNzYWdlIHNjb3BlLCBmaW5hbCBTdHJpbmcgbmFtZSwKKyAgICAgICAgICBmaW5hbCBDbGFzcyBzaW5ndWxhclR5cGUsIGZpbmFsIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKSB7CisgICAgLy8gRm9yIGV4dGVuc2lvbnMgc2NvcGVkIHdpdGhpbiBhIE1lc3NhZ2UsIHdlIHVzZSB0aGUgTWVzc2FnZSB0byByZXNvbHZlCisgICAgLy8gdGhlIG91dGVyIGNsYXNzJ3MgZGVzY3JpcHRvciwgZnJvbSB3aGljaCB0aGUgZXh0ZW5zaW9uIGRlc2NyaXB0b3IgaXMKKyAgICAvLyBvYnRhaW5lZC4KKyAgICByZXR1cm4gbmV3IEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4oCisgICAgICAgIG5ldyBDYWNoZWREZXNjcmlwdG9yUmV0cmlldmVyKCkgeworICAgICAgICAgIHByb3RlY3RlZCBGaWVsZERlc2NyaXB0b3IgbG9hZERlc2NyaXB0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gc2NvcGUuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBzaW5ndWxhclR5cGUsCisgICAgICAgIGRlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgRXh0ZW5zaW9uLkV4dGVuc2lvblR5cGUuTVVUQUJMRSk7CisgIH0KKworICAvKioKKyAgICogVXNlZCBpbiBwcm90bzEgZ2VuZXJhdGVkIGNvZGUgb25seS4KKyAgICoKKyAgICogQWZ0ZXIgZW5hYmxpbmcgYnJpZGdlLCB3ZSBjYW4gZGVmaW5lIHByb3RvMiBleHRlbnNpb25zICh0aGUgZXh0ZW5kZWQgdHlwZQorICAgKiBpcyBhIHByb3RvMiBtdXRhYmxlIG1lc3NhZ2UpIGluIGEgcHJvdG8xIC5wcm90byBmaWxlLiBGb3IgdGhlc2UgZXh0ZW5zaW9ucworICAgKiB3ZSBzaG91bGQgZ2VuZXJhdGUgcHJvdG8yIEdlbmVyYXRlZEV4dGVuc2lvbnMuCisgICAqLworICBwdWJsaWMgc3RhdGljIDxDb250YWluaW5nVHlwZSBleHRlbmRzIE1lc3NhZ2UsIFR5cGU+CisgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4KKyAgICAgbmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKKyAgICAgICAgIGZpbmFsIENsYXNzIHNpbmd1bGFyVHlwZSwgZmluYWwgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2UsCisgICAgICAgICBmaW5hbCBTdHJpbmcgZGVzY3JpcHRvck91dGVyQ2xhc3MsIGZpbmFsIFN0cmluZyBleHRlbnNpb25OYW1lKSB7CisgICAgLy8gRm9yIGV4dGVuc2lvbnMgc2NvcGVkIHdpdGhpbiBhIGZpbGUsIHdlIGxvYWQgdGhlIGRlc2NyaXB0b3Igb3V0ZXIKKyAgICAvLyBjbGFzcyBhbmQgcmVseSBvbiBpdCB0byBnZXQgdGhlIEZpbGVEZXNjcmlwdG9yIHdoaWNoIHRoZW4gY2FuIGJlCisgICAgLy8gdXNlZCB0byBvYnRhaW4gdGhlIGV4dGVuc2lvbidzIEZpZWxkRGVzY3JpcHRvci4KKyAgICByZXR1cm4gbmV3IEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4oCisgICAgICAgIG5ldyBDYWNoZWREZXNjcmlwdG9yUmV0cmlldmVyKCkgeworICAgICAgICAgIHByb3RlY3RlZCBGaWVsZERlc2NyaXB0b3IgbG9hZERlc2NyaXB0b3IoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBDbGFzcyBjbGF6eiA9CisgICAgICAgICAgICAgICAgICBzaW5ndWxhclR5cGUuZ2V0Q2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoZGVzY3JpcHRvck91dGVyQ2xhc3MpOworICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvciBmaWxlID0KKyAgICAgICAgICAgICAgICAgIChGaWxlRGVzY3JpcHRvcikgY2xhenouZ2V0RmllbGQoImRlc2NyaXB0b3IiKS5nZXQobnVsbCk7CisgICAgICAgICAgICAgIHJldHVybiBmaWxlLmZpbmRFeHRlbnNpb25CeU5hbWUoZXh0ZW5zaW9uTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICJDYW5ub3QgbG9hZCBkZXNjcmlwdG9yczogIiArIGRlc2NyaXB0b3JPdXRlckNsYXNzICsKKyAgICAgICAgICAgICAgICAgICIgaXMgbm90IGEgdmFsaWQgZGVzY3JpcHRvciBjbGFzcyBuYW1lIiwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBzaW5ndWxhclR5cGUsCisgICAgICAgIGRlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgRXh0ZW5zaW9uLkV4dGVuc2lvblR5cGUuTVVUQUJMRSk7CisgIH0KKworICAvKioKKyAgICogVHlwZSB1c2VkIHRvIHJlcHJlc2VudCBnZW5lcmF0ZWQgZXh0ZW5zaW9ucy4gIFRoZSBwcm90b2NvbCBjb21waWxlcgorICAgKiBnZW5lcmF0ZXMgYSBzdGF0aWMgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZm9yIGVhY2ggZXh0ZW5zaW9uLgorICAgKgorICAgKiA8cD5Gb3IgZXhhbXBsZSwgaW1hZ2luZSB5b3UgaGF2ZSB0aGUge0Bjb2RlIC5wcm90b30gZmlsZToKKyAgICoKKyAgICogPHByZT4KKyAgICogb3B0aW9uIGphdmFfY2xhc3MgPSAiTXlQcm90byI7CisgICAqCisgICAqIG1lc3NhZ2UgRm9vIHsKKyAgICogICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworICAgKiB9CisgICAqCisgICAqIGV4dGVuZCBGb28geworICAgKiAgIG9wdGlvbmFsIGludDMyIGJhcjsKKyAgICogfQorICAgKiA8L3ByZT4KKyAgICoKKyAgICogPHA+VGhlbiwge0Bjb2RlIE15UHJvdG8uRm9vLmJhcn0gaGFzIHR5cGUKKyAgICoge0Bjb2RlIEdlbmVyYXRlZEV4dGVuc2lvbjxNeVByb3RvLkZvbywgSW50ZWdlcj59LgorICAgKgorICAgKiA8cD5JbiBnZW5lcmFsLCB1c2VycyBzaG91bGQgaWdub3JlIHRoZSBkZXRhaWxzIG9mIHRoaXMgdHlwZSwgYW5kIHNpbXBseSB1c2UKKyAgICogdGhlc2Ugc3RhdGljIHNpbmdsZXRvbnMgYXMgcGFyYW1ldGVycyB0byB0aGUgZXh0ZW5zaW9uIGFjY2Vzc29ycyBkZWZpbmVkCisgICAqIGluIHtAbGluayBFeHRlbmRhYmxlTWVzc2FnZX0gYW5kIHtAbGluayBFeHRlbmRhYmxlQnVpbGRlcn0uCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEdlbmVyYXRlZEV4dGVuc2lvbjwKKyAgICAgIENvbnRhaW5pbmdUeXBlIGV4dGVuZHMgTWVzc2FnZSwgVHlwZT4gZXh0ZW5kcworICAgICAgRXh0ZW5zaW9uPENvbnRhaW5pbmdUeXBlLCBUeXBlPiB7CisgICAgLy8gVE9ETyhrZW50b24pOiAgRmluZCB3YXlzIHRvIGF2b2lkIHVzaW5nIEphdmEgcmVmbGVjdGlvbiB3aXRoaW4gdGhpcworICAgIC8vICAgY2xhc3MuICBBbHNvIHRyeSB0byBhdm9pZCBzdXBwcmVzc2luZyB1bmNoZWNrZWQgd2FybmluZ3MuCisKKyAgICAvLyBXZSBjYW4ndCBhbHdheXMgaW5pdGlhbGl6ZSB0aGUgZGVzY3JpcHRvciBvZiBhIEdlbmVyYXRlZEV4dGVuc2lvbiB3aGVuCisgICAgLy8gd2UgZmlyc3QgY29uc3RydWN0IGl0IGR1ZSB0byBpbml0aWFsaXphdGlvbiBvcmRlciBkaWZmaWN1bHRpZXMgKG5hbWVseSwKKyAgICAvLyB0aGUgZGVzY3JpcHRvciBtYXkgbm90IGhhdmUgYmVlbiBjb25zdHJ1Y3RlZCB5ZXQsIHNpbmNlIGl0IGlzIG9mdGVuCisgICAgLy8gY29uc3RydWN0ZWQgYnkgdGhlIGluaXRpYWxpemVyIG9mIGEgc2VwYXJhdGUgbW9kdWxlKS4KKyAgICAvLworICAgIC8vIEluIHRoZSBjYXNlIG9mIG5lc3RlZCBleHRlbnNpb25zLCB3ZSBpbml0aWFsaXplIHRoZQorICAgIC8vIEV4dGVuc2lvbkRlc2NyaXB0b3JSZXRyaWV2ZXIgd2l0aCBhbiBpbnN0YW5jZSB0aGF0IHVzZXMgdGhlIHNjb3BpbmcKKyAgICAvLyBNZXNzYWdlJ3MgZGVmYXVsdCBpbnN0YW5jZSB0byByZXRyaWV2ZSB0aGUgZXh0ZW5zaW9uJ3MgZGVzY3JpcHRvci4KKyAgICAvLworICAgIC8vIEluIHRoZSBjYXNlIG9mIG5vbi1uZXN0ZWQgZXh0ZW5zaW9ucywgd2UgaW5pdGlhbGl6ZSB0aGUKKyAgICAvLyBFeHRlbnNpb25EZXNjcmlwdG9yUmV0cmlldmVyIHRvIG51bGwgYW5kIHJlbHkgb24gdGhlIG91dGVyIGNsYXNzJ3Mgc3RhdGljCisgICAgLy8gaW5pdGlhbGl6ZXIgdG8gY2FsbCBpbnRlcm5hbEluaXQoKSBhZnRlciB0aGUgZGVzY3JpcHRvciBoYXMgYmVlbiBwYXJzZWQuCisgICAgR2VuZXJhdGVkRXh0ZW5zaW9uKEV4dGVuc2lvbkRlc2NyaXB0b3JSZXRyaWV2ZXIgZGVzY3JpcHRvclJldHJpZXZlciwKKyAgICAgICAgQ2xhc3Mgc2luZ3VsYXJUeXBlLAorICAgICAgICBNZXNzYWdlIG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UsCisgICAgICAgIEV4dGVuc2lvblR5cGUgZXh0ZW5zaW9uVHlwZSkgeworICAgICAgaWYgKE1lc3NhZ2UuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShzaW5ndWxhclR5cGUpICYmCisgICAgICAgICAgIXNpbmd1bGFyVHlwZS5pc0luc3RhbmNlKG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UpKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAiQmFkIG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UgZm9yICIgKyBzaW5ndWxhclR5cGUuZ2V0TmFtZSgpKTsKKyAgICAgIH0KKyAgICAgIHRoaXMuZGVzY3JpcHRvclJldHJpZXZlciA9IGRlc2NyaXB0b3JSZXRyaWV2ZXI7CisgICAgICB0aGlzLnNpbmd1bGFyVHlwZSA9IHNpbmd1bGFyVHlwZTsKKyAgICAgIHRoaXMubWVzc2FnZURlZmF1bHRJbnN0YW5jZSA9IG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2U7CisKKyAgICAgIGlmIChQcm90b2NvbE1lc3NhZ2VFbnVtLmNsYXNzLmlzQXNzaWduYWJsZUZyb20oc2luZ3VsYXJUeXBlKSkgeworICAgICAgICB0aGlzLmVudW1WYWx1ZU9mID0gZ2V0TWV0aG9kT3JEaWUoc2luZ3VsYXJUeXBlLCAidmFsdWVPZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yLmNsYXNzKTsKKyAgICAgICAgdGhpcy5lbnVtR2V0VmFsdWVEZXNjcmlwdG9yID0KKyAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKHNpbmd1bGFyVHlwZSwgImdldFZhbHVlRGVzY3JpcHRvciIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhpcy5lbnVtVmFsdWVPZiA9IG51bGw7CisgICAgICAgIHRoaXMuZW51bUdldFZhbHVlRGVzY3JpcHRvciA9IG51bGw7CisgICAgICB9CisgICAgICB0aGlzLmV4dGVuc2lvblR5cGUgPSBleHRlbnNpb25UeXBlOworICAgIH0KKworICAgIC8qKiBGb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuICovCisgICAgcHVibGljIHZvaWQgaW50ZXJuYWxJbml0KGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgICAgICBpZiAoZGVzY3JpcHRvclJldHJpZXZlciAhPSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkFscmVhZHkgaW5pdGlhbGl6ZWQuIik7CisgICAgICB9CisgICAgICBkZXNjcmlwdG9yUmV0cmlldmVyID0gbmV3IEV4dGVuc2lvbkRlc2NyaXB0b3JSZXRyaWV2ZXIoKSB7CisgICAgICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICAgICAgcHVibGljIEZpZWxkRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7CisgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIHByaXZhdGUgRXh0ZW5zaW9uRGVzY3JpcHRvclJldHJpZXZlciBkZXNjcmlwdG9yUmV0cmlldmVyOworICAgIHByaXZhdGUgZmluYWwgQ2xhc3Mgc2luZ3VsYXJUeXBlOworICAgIHByaXZhdGUgZmluYWwgTWVzc2FnZSBtZXNzYWdlRGVmYXVsdEluc3RhbmNlOworICAgIHByaXZhdGUgZmluYWwgTWV0aG9kIGVudW1WYWx1ZU9mOworICAgIHByaXZhdGUgZmluYWwgTWV0aG9kIGVudW1HZXRWYWx1ZURlc2NyaXB0b3I7CisgICAgcHJpdmF0ZSBmaW5hbCBFeHRlbnNpb25UeXBlIGV4dGVuc2lvblR5cGU7CisKKyAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldERlc2NyaXB0b3IoKSB7CisgICAgICBpZiAoZGVzY3JpcHRvclJldHJpZXZlciA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAiZ2V0RGVzY3JpcHRvcigpIGNhbGxlZCBiZWZvcmUgaW50ZXJuYWxJbml0KCkiKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBkZXNjcmlwdG9yUmV0cmlldmVyLmdldERlc2NyaXB0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgZXh0ZW5zaW9uIGlzIGFuIGVtYmVkZGVkIG1lc3NhZ2Ugb3IgZ3JvdXAsIHJldHVybnMgdGhlIGRlZmF1bHQKKyAgICAgKiBpbnN0YW5jZSBvZiB0aGUgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZSBnZXRNZXNzYWdlRGVmYXVsdEluc3RhbmNlKCkgeworICAgICAgcmV0dXJuIG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2U7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEV4dGVuc2lvblR5cGUgZ2V0RXh0ZW5zaW9uVHlwZSgpIHsKKyAgICAgIHJldHVybiBleHRlbnNpb25UeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgZnJvbSB0aGUgdHlwZSB1c2VkIGJ5IHRoZSByZWZsZWN0aW9uIGFjY2Vzc29ycyB0byB0aGUgdHlwZSB1c2VkCisgICAgICogYnkgbmF0aXZlIGFjY2Vzc29ycy4gIEUuZy4sIGZvciBlbnVtcywgdGhlIHJlZmxlY3Rpb24gYWNjZXNzb3JzIHVzZQorICAgICAqIEVudW1WYWx1ZURlc2NyaXB0b3JzIGJ1dCB0aGUgbmF0aXZlIGFjY2Vzc29ycyB1c2UgdGhlIGdlbmVyYXRlZCBlbnVtCisgICAgICogdHlwZS4KKyAgICAgKi8KKyAgICAvLyBAT3ZlcnJpZGUKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGZyb21SZWZsZWN0aW9uVHlwZShmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZ2V0RGVzY3JpcHRvcigpOworICAgICAgaWYgKGRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIGlmIChkZXNjcmlwdG9yLmdldEphdmFUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UgfHwKKyAgICAgICAgICAgIGRlc2NyaXB0b3IuZ2V0SmF2YVR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuRU5VTSkgeworICAgICAgICAgIC8vIE11c3QgY29udmVydCB0aGUgd2hvbGUgbGlzdC4KKyAgICAgICAgICBmaW5hbCBMaXN0IHJlc3VsdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgICBmb3IgKGZpbmFsIE9iamVjdCBlbGVtZW50IDogKExpc3QpIHZhbHVlKSB7CisgICAgICAgICAgICByZXN1bHQuYWRkKHNpbmd1bGFyRnJvbVJlZmxlY3Rpb25UeXBlKGVsZW1lbnQpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzaW5ndWxhckZyb21SZWZsZWN0aW9uVHlwZSh2YWx1ZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlrZSB7QGxpbmsgI2Zyb21SZWZsZWN0aW9uVHlwZShPYmplY3QpfSwgYnV0IGlmIHRoZSB0eXBlIGlzIGEgcmVwZWF0ZWQKKyAgICAgKiB0eXBlLCB0aGlzIGNvbnZlcnRzIGEgc2luZ2xlIGVsZW1lbnQuCisgICAgICovCisgICAgLy8gQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdCBzaW5ndWxhckZyb21SZWZsZWN0aW9uVHlwZShmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZ2V0RGVzY3JpcHRvcigpOworICAgICAgc3dpdGNoIChkZXNjcmlwdG9yLmdldEphdmFUeXBlKCkpIHsKKyAgICAgICAgY2FzZSBNRVNTQUdFOgorICAgICAgICAgIGlmIChzaW5ndWxhclR5cGUuaXNJbnN0YW5jZSh2YWx1ZSkpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKQorICAgICAgICAgICAgICAgIC5tZXJnZUZyb20oKE1lc3NhZ2UpIHZhbHVlKS5idWlsZCgpOworICAgICAgICAgIH0KKyAgICAgICAgY2FzZSBFTlVNOgorICAgICAgICAgIHJldHVybiBpbnZva2VPckRpZShlbnVtVmFsdWVPZiwgbnVsbCwgKEVudW1WYWx1ZURlc2NyaXB0b3IpIHZhbHVlKTsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBmcm9tIHRoZSB0eXBlIHVzZWQgYnkgdGhlIG5hdGl2ZSBhY2Nlc3NvcnMgdG8gdGhlIHR5cGUgdXNlZAorICAgICAqIGJ5IHJlZmxlY3Rpb24gYWNjZXNzb3JzLiAgRS5nLiwgZm9yIGVudW1zLCB0aGUgcmVmbGVjdGlvbiBhY2Nlc3NvcnMgdXNlCisgICAgICogRW51bVZhbHVlRGVzY3JpcHRvcnMgYnV0IHRoZSBuYXRpdmUgYWNjZXNzb3JzIHVzZSB0aGUgZ2VuZXJhdGVkIGVudW0KKyAgICAgKiB0eXBlLgorICAgICAqLworICAgIC8vIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByb3RlY3RlZCBPYmplY3QgdG9SZWZsZWN0aW9uVHlwZShmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZ2V0RGVzY3JpcHRvcigpOworICAgICAgaWYgKGRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIGlmIChkZXNjcmlwdG9yLmdldEphdmFUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLkVOVU0pIHsKKyAgICAgICAgICAvLyBNdXN0IGNvbnZlcnQgdGhlIHdob2xlIGxpc3QuCisgICAgICAgICAgZmluYWwgTGlzdCByZXN1bHQgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgICAgZm9yIChmaW5hbCBPYmplY3QgZWxlbWVudCA6IChMaXN0KSB2YWx1ZSkgeworICAgICAgICAgICAgcmVzdWx0LmFkZChzaW5ndWxhclRvUmVmbGVjdGlvblR5cGUoZWxlbWVudCkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHNpbmd1bGFyVG9SZWZsZWN0aW9uVHlwZSh2YWx1ZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlrZSB7QGxpbmsgI3RvUmVmbGVjdGlvblR5cGUoT2JqZWN0KX0sIGJ1dCBpZiB0aGUgdHlwZSBpcyBhIHJlcGVhdGVkCisgICAgICogdHlwZSwgdGhpcyBjb252ZXJ0cyBhIHNpbmdsZSBlbGVtZW50LgorICAgICAqLworICAgIC8vIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3Qgc2luZ3VsYXJUb1JlZmxlY3Rpb25UeXBlKGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgICAgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBnZXREZXNjcmlwdG9yKCk7CisgICAgICBzd2l0Y2ggKGRlc2NyaXB0b3IuZ2V0SmF2YVR5cGUoKSkgeworICAgICAgICBjYXNlIEVOVU06CisgICAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGVudW1HZXRWYWx1ZURlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICB9CisgICAgfQorCisgICAgLy8gQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CisgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldE51bWJlcigpOworICAgIH0KKworICAgIC8vIEBPdmVycmlkZQorICAgIHB1YmxpYyBXaXJlRm9ybWF0LkZpZWxkVHlwZSBnZXRMaXRlVHlwZSgpIHsKKyAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0TGl0ZVR5cGUoKTsKKyAgICB9CisKKyAgICAvLyBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlcGVhdGVkKCkgeworICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5pc1JlcGVhdGVkKCk7CisgICAgfQorCisgICAgLy8gQE92ZXJyaWRlCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIFR5cGUgZ2V0RGVmYXVsdFZhbHVlKCkgeworICAgICAgaWYgKGlzUmVwZWF0ZWQoKSkgeworICAgICAgICByZXR1cm4gKFR5cGUpIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworICAgICAgfQorICAgICAgaWYgKGdldERlc2NyaXB0b3IoKS5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgIHJldHVybiAoVHlwZSkgbWVzc2FnZURlZmF1bHRJbnN0YW5jZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiAoVHlwZSkgc2luZ3VsYXJGcm9tUmVmbGVjdGlvblR5cGUoCisgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldERlZmF1bHRWYWx1ZSgpKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8qKiBDYWxscyBDbGFzcy5nZXRNZXRob2QgYW5kIHRocm93cyBhIFJ1bnRpbWVFeGNlcHRpb24gaWYgaXQgZmFpbHMuICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwcml2YXRlIHN0YXRpYyBNZXRob2QgZ2V0TWV0aG9kT3JEaWUoCisgICAgICBmaW5hbCBDbGFzcyBjbGF6eiwgZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIENsYXNzLi4uIHBhcmFtcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gY2xhenouZ2V0TWV0aG9kKG5hbWUsIHBhcmFtcyk7CisgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAiR2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3MgXCIiICsgY2xhenouZ2V0TmFtZSgpICsKKyAgICAgICAgIlwiIG1pc3NpbmcgbWV0aG9kIFwiIiArIG5hbWUgKyAiXCIuIiwgZSk7CisgICAgfQorICB9CisKKyAgLyoqIENhbGxzIGludm9rZSBhbmQgdGhyb3dzIGEgUnVudGltZUV4Y2VwdGlvbiBpZiBpdCBmYWlscy4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IGludm9rZU9yRGllKAorICAgICAgZmluYWwgTWV0aG9kIG1ldGhvZCwgZmluYWwgT2JqZWN0IG9iamVjdCwgZmluYWwgT2JqZWN0Li4uIHBhcmFtcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gbWV0aG9kLmludm9rZShvYmplY3QsIHBhcmFtcyk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgIkNvdWxkbid0IHVzZSBKYXZhIHJlZmxlY3Rpb24gdG8gaW1wbGVtZW50IHByb3RvY29sIG1lc3NhZ2UgIiArCisgICAgICAgICJyZWZsZWN0aW9uLiIsIGUpOworICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkgeworICAgICAgZmluYWwgVGhyb3dhYmxlIGNhdXNlID0gZS5nZXRDYXVzZSgpOworICAgICAgaWYgKGNhdXNlIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgY2F1c2U7CisgICAgICB9IGVsc2UgaWYgKGNhdXNlIGluc3RhbmNlb2YgRXJyb3IpIHsKKyAgICAgICAgdGhyb3cgKEVycm9yKSBjYXVzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB0aHJvd24gYnkgZ2VuZXJhdGVkIGFjY2Vzc29yIG1ldGhvZC4iLCBjYXVzZSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEdldHMgdGhlIG1hcCBmaWVsZCB3aXRoIHRoZSBnaXZlbiBmaWVsZCBudW1iZXIuIFRoaXMgbWV0aG9kIHNob3VsZCBiZQorICAgKiBvdmVycmlkZGVuIGluIHRoZSBnZW5lcmF0ZWQgbWVzc2FnZSBjbGFzcyBpZiB0aGUgbWVzc2FnZSBjb250YWlucyBtYXAKKyAgICogZmllbGRzLgorICAgKgorICAgKiBVbmxpa2Ugb3RoZXIgZmllbGQgdHlwZXMsIHJlZmxlY3Rpb24gc3VwcG9ydCBmb3IgbWFwIGZpZWxkcyBjYW4ndCBiZQorICAgKiBpbXBsZW1lbnRlZCBiYXNlZCBvbiBnZW5lcmF0ZWQgcHVibGljIEFQSSBiZWNhdXNlIHdlIG5lZWQgdG8gYWNjZXNzIGEKKyAgICogbWFwIGZpZWxkIGFzIGEgbGlzdCBpbiByZWZsZWN0aW9uIEFQSSBidXQgdGhlIGdlbmVyYXRlZCBBUEkgb25seSBhbGxvd3MKKyAgICogdXMgdG8gYWNjZXNzIGl0IGFzIGEgbWFwLiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSB1bmRlcmx5aW5nIG1hcCBmaWVsZAorICAgKiBkaXJlY3RseSBhbmQgdGh1cyBlbmFibGVzIHVzIHRvIGFjY2VzcyB0aGUgbWFwIGZpZWxkIGFzIGEgbGlzdC4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMiLCAidW51c2VkIn0pCisgIHByb3RlY3RlZCBNYXBGaWVsZCBpbnRlcm5hbEdldE1hcEZpZWxkKGludCBmaWVsZE51bWJlcikgeworICAgIC8vIE5vdGUgdGhhdCB3ZSBjYW4ndCB1c2UgZGVzY3JpcHRvciBuYW1lcyBoZXJlIGJlY2F1c2UgdGhpcyBtZXRob2Qgd2lsbAorICAgIC8vIGJlIGNhbGxlZCB3aGVuIGRlc2NyaXB0b3IgaXMgYmVpbmcgaW5pdGlhbGl6ZWQuCisgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICJObyBtYXAgZmllbGRzIGZvdW5kIGluICIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSk7CisgIH0KKworICAvKioKKyAgICogVXNlcnMgc2hvdWxkIGlnbm9yZSB0aGlzIGNsYXNzLiAgVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgaW1wbGVtZW50YXRpb24KKyAgICogd2l0aCBhY2Nlc3MgdG8gdGhlIGZpZWxkcyBvZiBhIG1lc3NhZ2Ugb2JqZWN0IHVzaW5nIEphdmEgcmVmbGVjdGlvbi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRBY2Nlc3NvclRhYmxlIHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIEZpZWxkQWNjZXNzb3JUYWJsZSBmb3IgYSBwYXJ0aWN1bGFyIG1lc3NhZ2UgY2xhc3MuICBPbmx5CisgICAgICogb25lIEZpZWxkQWNjZXNzb3JUYWJsZSBzaG91bGQgZXZlciBiZSBjb25zdHJ1Y3RlZCBwZXIgY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVzY3JpcHRvciAgICAgVGhlIHR5cGUncyBkZXNjcmlwdG9yLgorICAgICAqIEBwYXJhbSBjYW1lbENhc2VOYW1lcyBUaGUgY2FtZWxjYXNlIG5hbWVzIG9mIGFsbCBmaWVsZHMgaW4gdGhlIG1lc3NhZ2UuCisgICAgICogICAgICAgICAgICAgICAgICAgICAgIFRoZXNlIGFyZSB1c2VkIHRvIGRlcml2ZSB0aGUgYWNjZXNzb3IgbWV0aG9kIG5hbWVzLgorICAgICAqIEBwYXJhbSBtZXNzYWdlQ2xhc3MgICBUaGUgbWVzc2FnZSB0eXBlLgorICAgICAqIEBwYXJhbSBidWlsZGVyQ2xhc3MgICBUaGUgYnVpbGRlciB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZEFjY2Vzc29yVGFibGUoCisgICAgICAgIGZpbmFsIERlc2NyaXB0b3IgZGVzY3JpcHRvciwKKyAgICAgICAgZmluYWwgU3RyaW5nW10gY2FtZWxDYXNlTmFtZXMsCisgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlPiBtZXNzYWdlQ2xhc3MsCisgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MpIHsKKyAgICAgIHRoaXMoZGVzY3JpcHRvciwgY2FtZWxDYXNlTmFtZXMpOworICAgICAgZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZChtZXNzYWdlQ2xhc3MsIGJ1aWxkZXJDbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgRmllbGRBY2Nlc3NvclRhYmxlIGZvciBhIHBhcnRpY3VsYXIgbWVzc2FnZSBjbGFzcyB3aXRob3V0CisgICAgICogaW5pdGlhbGl6aW5nIEZpZWxkQWNjZXNzb3JzLgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZEFjY2Vzc29yVGFibGUoCisgICAgICAgIGZpbmFsIERlc2NyaXB0b3IgZGVzY3JpcHRvciwKKyAgICAgICAgZmluYWwgU3RyaW5nW10gY2FtZWxDYXNlTmFtZXMpIHsKKyAgICAgIHRoaXMuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgICAgICB0aGlzLmNhbWVsQ2FzZU5hbWVzID0gY2FtZWxDYXNlTmFtZXM7CisgICAgICBmaWVsZHMgPSBuZXcgRmllbGRBY2Nlc3NvcltkZXNjcmlwdG9yLmdldEZpZWxkcygpLnNpemUoKV07CisgICAgICBvbmVvZnMgPSBuZXcgT25lb2ZBY2Nlc3NvcltkZXNjcmlwdG9yLmdldE9uZW9mcygpLnNpemUoKV07CisgICAgICBpbml0aWFsaXplZCA9IGZhbHNlOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc01hcEZpZWxkRW5hYmxlZChGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGJvb2xlYW4gcmVzdWx0ID0gdHJ1ZTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGUgZmllbGQgYWNjZXNzb3JzIGFyZSBpbml0aWFsaXplZC4gVGhpcyBtZXRob2QgaXMgdGhyZWFkLXNhZmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZUNsYXNzICAgVGhlIG1lc3NhZ2UgdHlwZS4KKyAgICAgKiBAcGFyYW0gYnVpbGRlckNsYXNzICAgVGhlIGJ1aWxkZXIgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMKKyAgICAgKi8KKyAgICBwdWJsaWMgRmllbGRBY2Nlc3NvclRhYmxlIGVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlPiBtZXNzYWdlQ2xhc3MsCisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MpIHsKKyAgICAgIGlmIChpbml0aWFsaXplZCkgeyByZXR1cm4gdGhpczsgfQorICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgIGlmIChpbml0aWFsaXplZCkgeyByZXR1cm4gdGhpczsgfQorICAgICAgICBpbnQgZmllbGRzU2l6ZSA9IGZpZWxkcy5sZW5ndGg7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzU2l6ZTsgaSsrKSB7CisgICAgICAgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZGVzY3JpcHRvci5nZXRGaWVsZHMoKS5nZXQoaSk7CisgICAgICAgICAgU3RyaW5nIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUgPSBudWxsOworICAgICAgICAgIGlmIChmaWVsZC5nZXRDb250YWluaW5nT25lb2YoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBjb250YWluaW5nT25lb2ZDYW1lbENhc2VOYW1lID0KKyAgICAgICAgICAgICAgICBjYW1lbENhc2VOYW1lc1tmaWVsZHNTaXplICsgZmllbGQuZ2V0Q29udGFpbmluZ09uZW9mKCkuZ2V0SW5kZXgoKV07CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChmaWVsZC5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgICAgIGlmIChmaWVsZC5pc01hcEZpZWxkKCkgJiYgaXNNYXBGaWVsZEVuYWJsZWQoZmllbGQpKSB7CisgICAgICAgICAgICAgICAgZmllbGRzW2ldID0gbmV3IE1hcEZpZWxkQWNjZXNzb3IoCisgICAgICAgICAgICAgICAgICAgIGZpZWxkLCBjYW1lbENhc2VOYW1lc1tpXSwgbWVzc2FnZUNsYXNzLCBidWlsZGVyQ2xhc3MpOworICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZpZWxkc1tpXSA9IG5ldyBSZXBlYXRlZE1lc3NhZ2VGaWVsZEFjY2Vzc29yKAorICAgICAgICAgICAgICAgICAgICBmaWVsZCwgY2FtZWxDYXNlTmFtZXNbaV0sIG1lc3NhZ2VDbGFzcywgYnVpbGRlckNsYXNzKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5FTlVNKSB7CisgICAgICAgICAgICAgIGZpZWxkc1tpXSA9IG5ldyBSZXBlYXRlZEVudW1GaWVsZEFjY2Vzc29yKAorICAgICAgICAgICAgICAgICAgZmllbGQsIGNhbWVsQ2FzZU5hbWVzW2ldLCBtZXNzYWdlQ2xhc3MsIGJ1aWxkZXJDbGFzcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBmaWVsZHNbaV0gPSBuZXcgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKAorICAgICAgICAgICAgICAgICAgZmllbGQsIGNhbWVsQ2FzZU5hbWVzW2ldLCBtZXNzYWdlQ2xhc3MsIGJ1aWxkZXJDbGFzcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgICAgIGZpZWxkc1tpXSA9IG5ldyBTaW5ndWxhck1lc3NhZ2VGaWVsZEFjY2Vzc29yKAorICAgICAgICAgICAgICAgICAgZmllbGQsIGNhbWVsQ2FzZU5hbWVzW2ldLCBtZXNzYWdlQ2xhc3MsIGJ1aWxkZXJDbGFzcywKKyAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5FTlVNKSB7CisgICAgICAgICAgICAgIGZpZWxkc1tpXSA9IG5ldyBTaW5ndWxhckVudW1GaWVsZEFjY2Vzc29yKAorICAgICAgICAgICAgICAgICAgZmllbGQsIGNhbWVsQ2FzZU5hbWVzW2ldLCBtZXNzYWdlQ2xhc3MsIGJ1aWxkZXJDbGFzcywKKyAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgZmllbGRzW2ldID0gbmV3IFNpbmd1bGFyU3RyaW5nRmllbGRBY2Nlc3NvcigKKyAgICAgICAgICAgICAgICAgIGZpZWxkLCBjYW1lbENhc2VOYW1lc1tpXSwgbWVzc2FnZUNsYXNzLCBidWlsZGVyQ2xhc3MsCisgICAgICAgICAgICAgICAgICBjb250YWluaW5nT25lb2ZDYW1lbENhc2VOYW1lKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIGZpZWxkc1tpXSA9IG5ldyBTaW5ndWxhckZpZWxkQWNjZXNzb3IoCisgICAgICAgICAgICAgICAgICBmaWVsZCwgY2FtZWxDYXNlTmFtZXNbaV0sIG1lc3NhZ2VDbGFzcywgYnVpbGRlckNsYXNzLAorICAgICAgICAgICAgICAgICAgY29udGFpbmluZ09uZW9mQ2FtZWxDYXNlTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IG9uZW9mc1NpemUgPSBvbmVvZnMubGVuZ3RoOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9uZW9mc1NpemU7IGkrKykgeworICAgICAgICAgIG9uZW9mc1tpXSA9IG5ldyBPbmVvZkFjY2Vzc29yKAorICAgICAgICAgICAgICBkZXNjcmlwdG9yLCBjYW1lbENhc2VOYW1lc1tpICsgZmllbGRzU2l6ZV0sCisgICAgICAgICAgICAgIG1lc3NhZ2VDbGFzcywgYnVpbGRlckNsYXNzKTsKKyAgICAgICAgfQorICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7CisgICAgICAgIGNhbWVsQ2FzZU5hbWVzID0gbnVsbDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9yIGRlc2NyaXB0b3I7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWVsZEFjY2Vzc29yW10gZmllbGRzOworICAgIHByaXZhdGUgU3RyaW5nW10gY2FtZWxDYXNlTmFtZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBPbmVvZkFjY2Vzc29yW10gb25lb2ZzOworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBpbml0aWFsaXplZDsKKworICAgIC8qKiBHZXQgdGhlIEZpZWxkQWNjZXNzb3IgZm9yIGEgcGFydGljdWxhciBmaWVsZC4gKi8KKyAgICBwcml2YXRlIEZpZWxkQWNjZXNzb3IgZ2V0RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSBkZXNjcmlwdG9yKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvciBkb2VzIG5vdCBtYXRjaCBtZXNzYWdlIHR5cGUuIik7CisgICAgICB9IGVsc2UgaWYgKGZpZWxkLmlzRXh0ZW5zaW9uKCkpIHsKKyAgICAgICAgLy8gSWYgdGhpcyB0eXBlIGhhZCBleHRlbnNpb25zLCBpdCB3b3VsZCBzdWJjbGFzcyBFeHRlbmRhYmxlTWVzc2FnZSwKKyAgICAgICAgLy8gd2hpY2ggb3ZlcnJpZGVzIHRoZSByZWZsZWN0aW9uIGludGVyZmFjZSB0byBoYW5kbGUgZXh0ZW5zaW9ucy4KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiVGhpcyB0eXBlIGRvZXMgbm90IGhhdmUgZXh0ZW5zaW9ucy4iKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmaWVsZHNbZmllbGQuZ2V0SW5kZXgoKV07CisgICAgfQorCisgICAgLyoqIEdldCB0aGUgT25lb2ZBY2Nlc3NvciBmb3IgYSBwYXJ0aWN1bGFyIG9uZW9mLiAqLworICAgIHByaXZhdGUgT25lb2ZBY2Nlc3NvciBnZXRPbmVvZihmaW5hbCBPbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgIGlmIChvbmVvZi5nZXRDb250YWluaW5nVHlwZSgpICE9IGRlc2NyaXB0b3IpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiT25lb2ZEZXNjcmlwdG9yIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBvbmVvZnNbb25lb2YuZ2V0SW5kZXgoKV07CisgICAgfQorCisgICAgLyoqCisgICAgICogQWJzdHJhY3QgaW50ZXJmYWNlIHRoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIGEgc2luZ2xlIGZpZWxkLiAgVGhpcyBpcworICAgICAqIGltcGxlbWVudGVkIGRpZmZlcmVudGx5IGRlcGVuZGluZyBvbiB0aGUgZmllbGQgdHlwZSBhbmQgY2FyZGluYWxpdHkuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgRmllbGRBY2Nlc3NvciB7CisgICAgICBPYmplY3QgZ2V0KEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSk7CisgICAgICBPYmplY3QgZ2V0KEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKTsKKyAgICAgIE9iamVjdCBnZXRSYXcoR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKTsKKyAgICAgIE9iamVjdCBnZXRSYXcoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpOworICAgICAgdm9pZCBzZXQoQnVpbGRlciBidWlsZGVyLCBPYmplY3QgdmFsdWUpOworICAgICAgT2JqZWN0IGdldFJlcGVhdGVkKEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSwgaW50IGluZGV4KTsKKyAgICAgIE9iamVjdCBnZXRSZXBlYXRlZChHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlciwgaW50IGluZGV4KTsKKyAgICAgIE9iamVjdCBnZXRSZXBlYXRlZFJhdyhHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UsIGludCBpbmRleCk7CisgICAgICBPYmplY3QgZ2V0UmVwZWF0ZWRSYXcoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIsIGludCBpbmRleCk7CisgICAgICB2b2lkIHNldFJlcGVhdGVkKEJ1aWxkZXIgYnVpbGRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LCBPYmplY3QgdmFsdWUpOworICAgICAgdm9pZCBhZGRSZXBlYXRlZChCdWlsZGVyIGJ1aWxkZXIsIE9iamVjdCB2YWx1ZSk7CisgICAgICBib29sZWFuIGhhcyhHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpOworICAgICAgYm9vbGVhbiBoYXMoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpOworICAgICAgaW50IGdldFJlcGVhdGVkQ291bnQoR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKTsKKyAgICAgIGludCBnZXRSZXBlYXRlZENvdW50KEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKTsKKyAgICAgIHZvaWQgY2xlYXIoQnVpbGRlciBidWlsZGVyKTsKKyAgICAgIE1lc3NhZ2UuQnVpbGRlciBuZXdCdWlsZGVyKCk7CisgICAgICBNZXNzYWdlLkJ1aWxkZXIgZ2V0QnVpbGRlcihHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcik7CisgICAgICBNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRCdWlsZGVyKEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpOworICAgIH0KKworICAgIC8qKiBPbmVvZkFjY2Vzc29yIHByb3ZpZGVzIGFjY2VzcyB0byBhIHNpbmdsZSBvbmVvZi4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBPbmVvZkFjY2Vzc29yIHsKKyAgICAgIE9uZW9mQWNjZXNzb3IoCisgICAgICAgICAgZmluYWwgRGVzY3JpcHRvciBkZXNjcmlwdG9yLCBmaW5hbCBTdHJpbmcgY2FtZWxDYXNlTmFtZSwKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZT4gbWVzc2FnZUNsYXNzLAorICAgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MpIHsKKyAgICAgICAgdGhpcy5kZXNjcmlwdG9yID0gZGVzY3JpcHRvcjsKKyAgICAgICAgY2FzZU1ldGhvZCA9CisgICAgICAgICAgICBnZXRNZXRob2RPckRpZShtZXNzYWdlQ2xhc3MsICJnZXQiICsgY2FtZWxDYXNlTmFtZSArICJDYXNlIik7CisgICAgICAgIGNhc2VNZXRob2RCdWlsZGVyID0KKyAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIkNhc2UiKTsKKyAgICAgICAgY2xlYXJNZXRob2QgPSBnZXRNZXRob2RPckRpZShidWlsZGVyQ2xhc3MsICJjbGVhciIgKyBjYW1lbENhc2VOYW1lKTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9yIGRlc2NyaXB0b3I7CisgICAgICBwcml2YXRlIGZpbmFsIE1ldGhvZCBjYXNlTWV0aG9kOworICAgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgY2FzZU1ldGhvZEJ1aWxkZXI7CisgICAgICBwcml2YXRlIGZpbmFsIE1ldGhvZCBjbGVhck1ldGhvZDsKKworICAgICAgcHVibGljIGJvb2xlYW4gaGFzKGZpbmFsIEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSkgeworICAgICAgICBpZiAoKChJbnRlcm5hbC5FbnVtTGl0ZSkgaW52b2tlT3JEaWUoY2FzZU1ldGhvZCwgbWVzc2FnZSkpLmdldE51bWJlcigpID09IDApIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBib29sZWFuIGhhcyhHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICBpZiAoKChJbnRlcm5hbC5FbnVtTGl0ZSkgaW52b2tlT3JEaWUoY2FzZU1ldGhvZEJ1aWxkZXIsIGJ1aWxkZXIpKS5nZXROdW1iZXIoKSA9PSAwKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorCisgICAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldChmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpIHsKKyAgICAgICAgaW50IGZpZWxkTnVtYmVyID0gKChJbnRlcm5hbC5FbnVtTGl0ZSkgaW52b2tlT3JEaWUoY2FzZU1ldGhvZCwgbWVzc2FnZSkpLmdldE51bWJlcigpOworICAgICAgICBpZiAoZmllbGROdW1iZXIgPiAwKSB7CisgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOdW1iZXIoZmllbGROdW1iZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorCisgICAgICBwdWJsaWMgRmllbGREZXNjcmlwdG9yIGdldChHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICBpbnQgZmllbGROdW1iZXIgPSAoKEludGVybmFsLkVudW1MaXRlKSBpbnZva2VPckRpZShjYXNlTWV0aG9kQnVpbGRlciwgYnVpbGRlcikpLmdldE51bWJlcigpOworICAgICAgICBpZiAoZmllbGROdW1iZXIgPiAwKSB7CisgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOdW1iZXIoZmllbGROdW1iZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorCisgICAgICBwdWJsaWMgdm9pZCBjbGVhcihmaW5hbCBCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgaW52b2tlT3JEaWUoY2xlYXJNZXRob2QsIGJ1aWxkZXIpOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gc3VwcG9ydEZpZWxkUHJlc2VuY2UoRmlsZURlc2NyaXB0b3IgZmlsZSkgeworICAgICAgcmV0dXJuIGZpbGUuZ2V0U3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3IuU3ludGF4LlBST1RPMjsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFNpbmd1bGFyRmllbGRBY2Nlc3NvciBpbXBsZW1lbnRzIEZpZWxkQWNjZXNzb3IgeworICAgICAgU2luZ3VsYXJGaWVsZEFjY2Vzc29yKAorICAgICAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yLCBmaW5hbCBTdHJpbmcgY2FtZWxDYXNlTmFtZSwKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZT4gbWVzc2FnZUNsYXNzLAorICAgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MsCisgICAgICAgICAgZmluYWwgU3RyaW5nIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUpIHsKKyAgICAgICAgZmllbGQgPSBkZXNjcmlwdG9yOworICAgICAgICBpc09uZW9mRmllbGQgPSBkZXNjcmlwdG9yLmdldENvbnRhaW5pbmdPbmVvZigpICE9IG51bGw7CisgICAgICAgIGhhc0hhc01ldGhvZCA9IHN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3IuZ2V0RmlsZSgpKQorICAgICAgICAgICAgfHwgKCFpc09uZW9mRmllbGQgJiYgZGVzY3JpcHRvci5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKTsKKyAgICAgICAgZ2V0TWV0aG9kID0gZ2V0TWV0aG9kT3JEaWUobWVzc2FnZUNsYXNzLCAiZ2V0IiArIGNhbWVsQ2FzZU5hbWUpOworICAgICAgICBnZXRNZXRob2RCdWlsZGVyID0gZ2V0TWV0aG9kT3JEaWUoYnVpbGRlckNsYXNzLCAiZ2V0IiArIGNhbWVsQ2FzZU5hbWUpOworICAgICAgICB0eXBlID0gZ2V0TWV0aG9kLmdldFJldHVyblR5cGUoKTsKKyAgICAgICAgc2V0TWV0aG9kID0gZ2V0TWV0aG9kT3JEaWUoYnVpbGRlckNsYXNzLCAic2V0IiArIGNhbWVsQ2FzZU5hbWUsIHR5cGUpOworICAgICAgICBoYXNNZXRob2QgPQorICAgICAgICAgICAgaGFzSGFzTWV0aG9kID8gZ2V0TWV0aG9kT3JEaWUobWVzc2FnZUNsYXNzLCAiaGFzIiArIGNhbWVsQ2FzZU5hbWUpIDogbnVsbDsKKyAgICAgICAgaGFzTWV0aG9kQnVpbGRlciA9CisgICAgICAgICAgICBoYXNIYXNNZXRob2QgPyBnZXRNZXRob2RPckRpZShidWlsZGVyQ2xhc3MsICJoYXMiICsgY2FtZWxDYXNlTmFtZSkgOiBudWxsOworICAgICAgICBjbGVhck1ldGhvZCA9IGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImNsZWFyIiArIGNhbWVsQ2FzZU5hbWUpOworICAgICAgICBjYXNlTWV0aG9kID0gaXNPbmVvZkZpZWxkID8gZ2V0TWV0aG9kT3JEaWUoCisgICAgICAgICAgICBtZXNzYWdlQ2xhc3MsICJnZXQiICsgY29udGFpbmluZ09uZW9mQ2FtZWxDYXNlTmFtZSArICJDYXNlIikgOiBudWxsOworICAgICAgICBjYXNlTWV0aG9kQnVpbGRlciA9IGlzT25lb2ZGaWVsZCA/IGdldE1ldGhvZE9yRGllKAorICAgICAgICAgICAgYnVpbGRlckNsYXNzLCAiZ2V0IiArIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUgKyAiQ2FzZSIpIDogbnVsbDsKKyAgICAgIH0KKworICAgICAgLy8gTm90ZTogIFdlIHVzZSBKYXZhIHJlZmxlY3Rpb24gdG8gY2FsbCBwdWJsaWMgbWV0aG9kcyByYXRoZXIgdGhhbgorICAgICAgLy8gICBhY2Nlc3MgcHJpdmF0ZSBmaWVsZHMgZGlyZWN0bHkgYXMgdGhpcyBhdm9pZHMgcnVudGltZSBzZWN1cml0eQorICAgICAgLy8gICBjaGVja3MuCisgICAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8Pz4gdHlwZTsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2QgZ2V0TWV0aG9kOworICAgICAgcHJvdGVjdGVkIGZpbmFsIE1ldGhvZCBnZXRNZXRob2RCdWlsZGVyOworICAgICAgcHJvdGVjdGVkIGZpbmFsIE1ldGhvZCBzZXRNZXRob2Q7CisgICAgICBwcm90ZWN0ZWQgZmluYWwgTWV0aG9kIGhhc01ldGhvZDsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2QgaGFzTWV0aG9kQnVpbGRlcjsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2QgY2xlYXJNZXRob2Q7CisgICAgICBwcm90ZWN0ZWQgZmluYWwgTWV0aG9kIGNhc2VNZXRob2Q7CisgICAgICBwcm90ZWN0ZWQgZmluYWwgTWV0aG9kIGNhc2VNZXRob2RCdWlsZGVyOworICAgICAgcHJvdGVjdGVkIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZDsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGlzT25lb2ZGaWVsZDsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGhhc0hhc01ldGhvZDsKKworICAgICAgcHJpdmF0ZSBpbnQgZ2V0T25lb2ZGaWVsZE51bWJlcihmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpIHsKKyAgICAgICAgcmV0dXJuICgoSW50ZXJuYWwuRW51bUxpdGUpIGludm9rZU9yRGllKGNhc2VNZXRob2QsIG1lc3NhZ2UpKS5nZXROdW1iZXIoKTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBpbnQgZ2V0T25lb2ZGaWVsZE51bWJlcihmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICByZXR1cm4gKChJbnRlcm5hbC5FbnVtTGl0ZSkgaW52b2tlT3JEaWUoY2FzZU1ldGhvZEJ1aWxkZXIsIGJ1aWxkZXIpKS5nZXROdW1iZXIoKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIE9iamVjdCBnZXQoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShnZXRNZXRob2QsIG1lc3NhZ2UpOworICAgICAgfQorICAgICAgcHVibGljIE9iamVjdCBnZXQoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGdldE1ldGhvZEJ1aWxkZXIsIGJ1aWxkZXIpOworICAgICAgfQorICAgICAgcHVibGljIE9iamVjdCBnZXRSYXcoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBnZXQobWVzc2FnZSk7CisgICAgICB9CisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJhdyhHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICByZXR1cm4gZ2V0KGJ1aWxkZXIpOworICAgICAgfQorICAgICAgcHVibGljIHZvaWQgc2V0KGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGludm9rZU9yRGllKHNldE1ldGhvZCwgYnVpbGRlciwgdmFsdWUpOworICAgICAgfQorICAgICAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZChmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImdldFJlcGVhdGVkRmllbGQoKSBjYWxsZWQgb24gYSBzaW5ndWxhciBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRSYXcoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkUmF3KCkgY2FsbGVkIG9uIGEgc2luZ3VsYXIgZmllbGQuIik7CisgICAgICB9CisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkKEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkKCkgY2FsbGVkIG9uIGEgc2luZ3VsYXIgZmllbGQuIik7CisgICAgICB9CisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkUmF3KEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLAorICAgICAgICAgIGludCBpbmRleCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImdldFJlcGVhdGVkRmllbGRSYXcoKSBjYWxsZWQgb24gYSBzaW5ndWxhciBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyB2b2lkIHNldFJlcGVhdGVkKGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgaW50IGluZGV4LAorICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgInNldFJlcGVhdGVkRmllbGQoKSBjYWxsZWQgb24gYSBzaW5ndWxhciBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyB2b2lkIGFkZFJlcGVhdGVkKGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiYWRkUmVwZWF0ZWRGaWVsZCgpIGNhbGxlZCBvbiBhIHNpbmd1bGFyIGZpZWxkLiIpOworICAgICAgfQorICAgICAgcHVibGljIGJvb2xlYW4gaGFzKGZpbmFsIEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSkgeworICAgICAgICBpZiAoIWhhc0hhc01ldGhvZCkgeworICAgICAgICAgIGlmIChpc09uZW9mRmllbGQpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRPbmVvZkZpZWxkTnVtYmVyKG1lc3NhZ2UpID09IGZpZWxkLmdldE51bWJlcigpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gIWdldChtZXNzYWdlKS5lcXVhbHMoZmllbGQuZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoQm9vbGVhbikgaW52b2tlT3JEaWUoaGFzTWV0aG9kLCBtZXNzYWdlKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBib29sZWFuIGhhcyhHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICBpZiAoIWhhc0hhc01ldGhvZCkgeworICAgICAgICAgIGlmIChpc09uZW9mRmllbGQpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRPbmVvZkZpZWxkTnVtYmVyKGJ1aWxkZXIpID09IGZpZWxkLmdldE51bWJlcigpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gIWdldChidWlsZGVyKS5lcXVhbHMoZmllbGQuZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoQm9vbGVhbikgaW52b2tlT3JEaWUoaGFzTWV0aG9kQnVpbGRlciwgYnVpbGRlcik7CisgICAgICB9CisgICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ291bnQoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiZ2V0UmVwZWF0ZWRGaWVsZFNpemUoKSBjYWxsZWQgb24gYSBzaW5ndWxhciBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDb3VudChHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImdldFJlcGVhdGVkRmllbGRTaXplKCkgY2FsbGVkIG9uIGEgc2luZ3VsYXIgZmllbGQuIik7CisgICAgICB9CisgICAgICBwdWJsaWMgdm9pZCBjbGVhcihmaW5hbCBCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgaW52b2tlT3JEaWUoY2xlYXJNZXRob2QsIGJ1aWxkZXIpOworICAgICAgfQorICAgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBuZXdCdWlsZGVyKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgIm5ld0J1aWxkZXJGb3JGaWVsZCgpIGNhbGxlZCBvbiBhIG5vbi1NZXNzYWdlIHR5cGUuIik7CisgICAgICB9CisgICAgICBwdWJsaWMgTWVzc2FnZS5CdWlsZGVyIGdldEJ1aWxkZXIoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJnZXRGaWVsZEJ1aWxkZXIoKSBjYWxsZWQgb24gYSBub24tTWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZEJ1aWxkZXIoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIsCisgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoKSBjYWxsZWQgb24gYSBub24tTWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbXBsZW1lbnRzIEZpZWxkQWNjZXNzb3IgeworICAgICAgcHJvdGVjdGVkIGZpbmFsIENsYXNzIHR5cGU7CisgICAgICBwcm90ZWN0ZWQgZmluYWwgTWV0aG9kIGdldE1ldGhvZDsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2QgZ2V0TWV0aG9kQnVpbGRlcjsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2QgZ2V0UmVwZWF0ZWRNZXRob2Q7CisgICAgICBwcm90ZWN0ZWQgZmluYWwgTWV0aG9kIGdldFJlcGVhdGVkTWV0aG9kQnVpbGRlcjsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2Qgc2V0UmVwZWF0ZWRNZXRob2Q7CisgICAgICBwcm90ZWN0ZWQgZmluYWwgTWV0aG9kIGFkZFJlcGVhdGVkTWV0aG9kOworICAgICAgcHJvdGVjdGVkIGZpbmFsIE1ldGhvZCBnZXRDb3VudE1ldGhvZDsKKyAgICAgIHByb3RlY3RlZCBmaW5hbCBNZXRob2QgZ2V0Q291bnRNZXRob2RCdWlsZGVyOworICAgICAgcHJvdGVjdGVkIGZpbmFsIE1ldGhvZCBjbGVhck1ldGhvZDsKKworICAgICAgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKAorICAgICAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yLCBmaW5hbCBTdHJpbmcgY2FtZWxDYXNlTmFtZSwKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZT4gbWVzc2FnZUNsYXNzLAorICAgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MpIHsKKyAgICAgICAgZ2V0TWV0aG9kID0gZ2V0TWV0aG9kT3JEaWUobWVzc2FnZUNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0IiArIGNhbWVsQ2FzZU5hbWUgKyAiTGlzdCIpOworICAgICAgICBnZXRNZXRob2RCdWlsZGVyID0gZ2V0TWV0aG9kT3JEaWUoYnVpbGRlckNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0IiArIGNhbWVsQ2FzZU5hbWUgKyAiTGlzdCIpOworICAgICAgICBnZXRSZXBlYXRlZE1ldGhvZCA9CisgICAgICAgICAgICBnZXRNZXRob2RPckRpZShtZXNzYWdlQ2xhc3MsICJnZXQiICsgY2FtZWxDYXNlTmFtZSwgSW50ZWdlci5UWVBFKTsKKyAgICAgICAgZ2V0UmVwZWF0ZWRNZXRob2RCdWlsZGVyID0KKyAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lLCBJbnRlZ2VyLlRZUEUpOworICAgICAgICB0eXBlID0gZ2V0UmVwZWF0ZWRNZXRob2QuZ2V0UmV0dXJuVHlwZSgpOworICAgICAgICBzZXRSZXBlYXRlZE1ldGhvZCA9CisgICAgICAgICAgICBnZXRNZXRob2RPckRpZShidWlsZGVyQ2xhc3MsICJzZXQiICsgY2FtZWxDYXNlTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuVFlQRSwgdHlwZSk7CisgICAgICAgIGFkZFJlcGVhdGVkTWV0aG9kID0KKyAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImFkZCIgKyBjYW1lbENhc2VOYW1lLCB0eXBlKTsKKyAgICAgICAgZ2V0Q291bnRNZXRob2QgPQorICAgICAgICAgICAgZ2V0TWV0aG9kT3JEaWUobWVzc2FnZUNsYXNzLCAiZ2V0IiArIGNhbWVsQ2FzZU5hbWUgKyAiQ291bnQiKTsKKyAgICAgICAgZ2V0Q291bnRNZXRob2RCdWlsZGVyID0KKyAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIkNvdW50Iik7CisKKyAgICAgICAgY2xlYXJNZXRob2QgPSBnZXRNZXRob2RPckRpZShidWlsZGVyQ2xhc3MsICJjbGVhciIgKyBjYW1lbENhc2VOYW1lKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIE9iamVjdCBnZXQoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShnZXRNZXRob2QsIG1lc3NhZ2UpOworICAgICAgfQorICAgICAgcHVibGljIE9iamVjdCBnZXQoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGdldE1ldGhvZEJ1aWxkZXIsIGJ1aWxkZXIpOworICAgICAgfQorICAgICAgcHVibGljIE9iamVjdCBnZXRSYXcoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBnZXQobWVzc2FnZSk7CisgICAgICB9CisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJhdyhHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICByZXR1cm4gZ2V0KGJ1aWxkZXIpOworICAgICAgfQorICAgICAgcHVibGljIHZvaWQgc2V0KGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIC8vIEFkZCBhbGwgdGhlIGVsZW1lbnRzIGluZGl2aWR1YWxseS4gIFRoaXMgc2VydmVzIHR3byBwdXJwb3NlczoKKyAgICAgICAgLy8gMSkgVmVyaWZpZXMgdGhhdCBlYWNoIGVsZW1lbnQgaGFzIHRoZSBjb3JyZWN0IHR5cGUuCisgICAgICAgIC8vIDIpIEluc3VyZXMgdGhhdCB0aGUgY2FsbGVyIGNhbm5vdCBtb2RpZnkgdGhlIGxpc3QgbGF0ZXIgb24gYW5kCisgICAgICAgIC8vICAgIGhhdmUgdGhlIG1vZGlmaWNhdGlvbnMgYmUgcmVmbGVjdGVkIGluIHRoZSBtZXNzYWdlLgorICAgICAgICBjbGVhcihidWlsZGVyKTsKKyAgICAgICAgZm9yIChmaW5hbCBPYmplY3QgZWxlbWVudCA6IChMaXN0PD8+KSB2YWx1ZSkgeworICAgICAgICAgIGFkZFJlcGVhdGVkKGJ1aWxkZXIsIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICB9CisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkKGZpbmFsIEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShnZXRSZXBlYXRlZE1ldGhvZCwgbWVzc2FnZSwgaW5kZXgpOworICAgICAgfQorICAgICAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZChHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlciwgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShnZXRSZXBlYXRlZE1ldGhvZEJ1aWxkZXIsIGJ1aWxkZXIsIGluZGV4KTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRSYXcoR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkKG1lc3NhZ2UsIGluZGV4KTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRSYXcoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIsCisgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBnZXRSZXBlYXRlZChidWlsZGVyLCBpbmRleCk7CisgICAgICB9CisgICAgICBwdWJsaWMgdm9pZCBzZXRSZXBlYXRlZChmaW5hbCBCdWlsZGVyIGJ1aWxkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgsIGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpbnZva2VPckRpZShzZXRSZXBlYXRlZE1ldGhvZCwgYnVpbGRlciwgaW5kZXgsIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyB2b2lkIGFkZFJlcGVhdGVkKGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGludm9rZU9yRGllKGFkZFJlcGVhdGVkTWV0aG9kLCBidWlsZGVyLCB2YWx1ZSk7CisgICAgICB9CisgICAgICBwdWJsaWMgYm9vbGVhbiBoYXMoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiaGFzRmllbGQoKSBjYWxsZWQgb24gYSByZXBlYXRlZCBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBib29sZWFuIGhhcyhHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImhhc0ZpZWxkKCkgY2FsbGVkIG9uIGEgcmVwZWF0ZWQgZmllbGQuIik7CisgICAgICB9CisgICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ291bnQoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiAoSW50ZWdlcikgaW52b2tlT3JEaWUoZ2V0Q291bnRNZXRob2QsIG1lc3NhZ2UpOworICAgICAgfQorICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZENvdW50KEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKSB7CisgICAgICAgIHJldHVybiAoSW50ZWdlcikgaW52b2tlT3JEaWUoZ2V0Q291bnRNZXRob2RCdWlsZGVyLCBidWlsZGVyKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKGZpbmFsIEJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICBpbnZva2VPckRpZShjbGVhck1ldGhvZCwgYnVpbGRlcik7CisgICAgICB9CisgICAgICBwdWJsaWMgTWVzc2FnZS5CdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAibmV3QnVpbGRlckZvckZpZWxkKCkgY2FsbGVkIG9uIGEgbm9uLU1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBNZXNzYWdlLkJ1aWxkZXIgZ2V0QnVpbGRlcihHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgImdldEZpZWxkQnVpbGRlcigpIGNhbGxlZCBvbiBhIG5vbi1NZXNzYWdlIHR5cGUuIik7CisgICAgICB9CisgICAgICBwdWJsaWMgTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkQnVpbGRlcihHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlciwKKyAgICAgICAgICBpbnQgaW5kZXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJnZXRSZXBlYXRlZEZpZWxkQnVpbGRlcigpIGNhbGxlZCBvbiBhIG5vbi1NZXNzYWdlIHR5cGUuIik7CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTWFwRmllbGRBY2Nlc3NvciBpbXBsZW1lbnRzIEZpZWxkQWNjZXNzb3IgeworICAgICAgTWFwRmllbGRBY2Nlc3NvcigKKyAgICAgICAgICBmaW5hbCBGaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciwgZmluYWwgU3RyaW5nIGNhbWVsQ2FzZU5hbWUsCisgICAgICAgICAgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2U+IG1lc3NhZ2VDbGFzcywKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgQnVpbGRlcj4gYnVpbGRlckNsYXNzKSB7CisgICAgICAgIGZpZWxkID0gZGVzY3JpcHRvcjsKKyAgICAgICAgTWV0aG9kIGdldERlZmF1bHRJbnN0YW5jZU1ldGhvZCA9CisgICAgICAgICAgICBnZXRNZXRob2RPckRpZShtZXNzYWdlQ2xhc3MsICJnZXREZWZhdWx0SW5zdGFuY2UiKTsKKyAgICAgICAgTWFwRmllbGQgZGVmYXVsdE1hcEZpZWxkID0gZ2V0TWFwRmllbGQoCisgICAgICAgICAgICAoR2VuZXJhdGVkTWVzc2FnZSkgaW52b2tlT3JEaWUoZ2V0RGVmYXVsdEluc3RhbmNlTWV0aG9kLCBudWxsKSk7CisgICAgICAgIG1hcEVudHJ5TWVzc2FnZURlZmF1bHRJbnN0YW5jZSA9CisgICAgICAgICAgICBkZWZhdWx0TWFwRmllbGQuZ2V0TWFwRW50cnlNZXNzYWdlRGVmYXVsdEluc3RhbmNlKCk7CisgICAgICB9CisKKyAgICAgIHByaXZhdGUgZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkOworICAgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlIG1hcEVudHJ5TWVzc2FnZURlZmF1bHRJbnN0YW5jZTsKKworICAgICAgcHJpdmF0ZSBNYXBGaWVsZDw/LCA/PiBnZXRNYXBGaWVsZChHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpIHsKKyAgICAgICAgcmV0dXJuIChNYXBGaWVsZDw/LCA/PikgbWVzc2FnZS5pbnRlcm5hbEdldE1hcEZpZWxkKGZpZWxkLmdldE51bWJlcigpKTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBNYXBGaWVsZDw/LCA/PiBnZXRNYXBGaWVsZChHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICByZXR1cm4gKE1hcEZpZWxkPD8sID8+KSBidWlsZGVyLmludGVybmFsR2V0TWFwRmllbGQoZmllbGQuZ2V0TnVtYmVyKCkpOworICAgICAgfQorCisgICAgICBwcml2YXRlIE1hcEZpZWxkPD8sID8+IGdldE11dGFibGVNYXBGaWVsZCgKKyAgICAgICAgICBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICByZXR1cm4gKE1hcEZpZWxkPD8sID8+KSBidWlsZGVyLmludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKAorICAgICAgICAgICAgZmllbGQuZ2V0TnVtYmVyKCkpOworICAgICAgfQorCisgICAgICBwdWJsaWMgT2JqZWN0IGdldChHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpIHsKKyAgICAgICAgTGlzdCByZXN1bHQgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRDb3VudChtZXNzYWdlKTsgaSsrKSB7CisgICAgICAgICAgcmVzdWx0LmFkZChnZXRSZXBlYXRlZChtZXNzYWdlLCBpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVzdWx0KTsKKyAgICAgIH0KKworICAgICAgcHVibGljIE9iamVjdCBnZXQoQnVpbGRlciBidWlsZGVyKSB7CisgICAgICAgIExpc3QgcmVzdWx0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldFJlcGVhdGVkQ291bnQoYnVpbGRlcik7IGkrKykgeworICAgICAgICAgIHJlc3VsdC5hZGQoZ2V0UmVwZWF0ZWQoYnVpbGRlciwgaSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlc3VsdCk7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmF3KEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSkgeworICAgICAgICByZXR1cm4gZ2V0KG1lc3NhZ2UpOworICAgICAgfQorCisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJhdyhHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICByZXR1cm4gZ2V0KGJ1aWxkZXIpOworICAgICAgfQorCisgICAgICBwdWJsaWMgdm9pZCBzZXQoQnVpbGRlciBidWlsZGVyLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgY2xlYXIoYnVpbGRlcik7CisgICAgICAgIGZvciAoT2JqZWN0IGVudHJ5IDogKExpc3QpIHZhbHVlKSB7CisgICAgICAgICAgYWRkUmVwZWF0ZWQoYnVpbGRlciwgZW50cnkpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWQoR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIGdldE1hcEZpZWxkKG1lc3NhZ2UpLmdldExpc3QoKS5nZXQoaW5kZXgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkKEJ1aWxkZXIgYnVpbGRlciwgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBnZXRNYXBGaWVsZChidWlsZGVyKS5nZXRMaXN0KCkuZ2V0KGluZGV4KTsKKyAgICAgIH0KKworICAgICAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZFJhdyhHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UsIGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWQobWVzc2FnZSwgaW5kZXgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkUmF3KEJ1aWxkZXIgYnVpbGRlciwgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBnZXRSZXBlYXRlZChidWlsZGVyLCBpbmRleCk7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyB2b2lkIHNldFJlcGVhdGVkKEJ1aWxkZXIgYnVpbGRlciwgaW50IGluZGV4LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgZ2V0TXV0YWJsZU1hcEZpZWxkKGJ1aWxkZXIpLmdldE11dGFibGVMaXN0KCkuc2V0KGluZGV4LCAoTWVzc2FnZSkgdmFsdWUpOworICAgICAgfQorCisgICAgICBwdWJsaWMgdm9pZCBhZGRSZXBlYXRlZChCdWlsZGVyIGJ1aWxkZXIsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBnZXRNdXRhYmxlTWFwRmllbGQoYnVpbGRlcikuZ2V0TXV0YWJsZUxpc3QoKS5hZGQoKE1lc3NhZ2UpIHZhbHVlKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIGJvb2xlYW4gaGFzKEdlbmVyYXRlZE1lc3NhZ2UgbWVzc2FnZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiaGFzRmllbGQoKSBpcyBub3Qgc3VwcG9ydGVkIGZvciByZXBlYXRlZCBmaWVsZHMuIik7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBib29sZWFuIGhhcyhCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgImhhc0ZpZWxkKCkgaXMgbm90IHN1cHBvcnRlZCBmb3IgcmVwZWF0ZWQgZmllbGRzLiIpOworICAgICAgfQorCisgICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ291bnQoR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBnZXRNYXBGaWVsZChtZXNzYWdlKS5nZXRMaXN0KCkuc2l6ZSgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ291bnQoQnVpbGRlciBidWlsZGVyKSB7CisgICAgICAgIHJldHVybiBnZXRNYXBGaWVsZChidWlsZGVyKS5nZXRMaXN0KCkuc2l6ZSgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgdm9pZCBjbGVhcihCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgZ2V0TXV0YWJsZU1hcEZpZWxkKGJ1aWxkZXIpLmdldE11dGFibGVMaXN0KCkuY2xlYXIoKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZS5CdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgICAgIHJldHVybiBtYXBFbnRyeU1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZS5CdWlsZGVyIGdldEJ1aWxkZXIoQnVpbGRlciBidWlsZGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJOZXN0ZWQgYnVpbGRlciBub3Qgc3VwcG9ydGVkIGZvciBtYXAgZmllbGRzLiIpOworICAgICAgfQorCisgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRCdWlsZGVyKAorICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciwgaW50IGluZGV4KSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJOZXN0ZWQgYnVpbGRlciBub3Qgc3VwcG9ydGVkIGZvciBtYXAgZmllbGRzLiIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU2luZ3VsYXJFbnVtRmllbGRBY2Nlc3NvcgorICAgICAgICBleHRlbmRzIFNpbmd1bGFyRmllbGRBY2Nlc3NvciB7CisgICAgICBTaW5ndWxhckVudW1GaWVsZEFjY2Vzc29yKAorICAgICAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yLCBmaW5hbCBTdHJpbmcgY2FtZWxDYXNlTmFtZSwKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZT4gbWVzc2FnZUNsYXNzLAorICAgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MsCisgICAgICAgICAgZmluYWwgU3RyaW5nIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUpIHsKKyAgICAgICAgc3VwZXIoZGVzY3JpcHRvciwgY2FtZWxDYXNlTmFtZSwgbWVzc2FnZUNsYXNzLCBidWlsZGVyQ2xhc3MsIGNvbnRhaW5pbmdPbmVvZkNhbWVsQ2FzZU5hbWUpOworCisgICAgICAgIGVudW1EZXNjcmlwdG9yID0gZGVzY3JpcHRvci5nZXRFbnVtVHlwZSgpOworCisgICAgICAgIHZhbHVlT2ZNZXRob2QgPSBnZXRNZXRob2RPckRpZSh0eXBlLCAidmFsdWVPZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yLmNsYXNzKTsKKyAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yTWV0aG9kID0KKyAgICAgICAgICBnZXRNZXRob2RPckRpZSh0eXBlLCAiZ2V0VmFsdWVEZXNjcmlwdG9yIik7CisKKyAgICAgICAgc3VwcG9ydFVua25vd25FbnVtVmFsdWUgPSBkZXNjcmlwdG9yLmdldEZpbGUoKS5zdXBwb3J0c1Vua25vd25FbnVtVmFsdWUoKTsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgZ2V0VmFsdWVNZXRob2QgPQorICAgICAgICAgICAgICBnZXRNZXRob2RPckRpZShtZXNzYWdlQ2xhc3MsICJnZXQiICsgY2FtZWxDYXNlTmFtZSArICJWYWx1ZSIpOworICAgICAgICAgIGdldFZhbHVlTWV0aG9kQnVpbGRlciA9CisgICAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIlZhbHVlIik7CisgICAgICAgICAgc2V0VmFsdWVNZXRob2QgPQorICAgICAgICAgICAgICBnZXRNZXRob2RPckRpZShidWlsZGVyQ2xhc3MsICJzZXQiICsgY2FtZWxDYXNlTmFtZSArICJWYWx1ZSIsIGludC5jbGFzcyk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBFbnVtRGVzY3JpcHRvciBlbnVtRGVzY3JpcHRvcjsKKworICAgICAgcHJpdmF0ZSBNZXRob2QgdmFsdWVPZk1ldGhvZDsKKyAgICAgIHByaXZhdGUgTWV0aG9kIGdldFZhbHVlRGVzY3JpcHRvck1ldGhvZDsKKworICAgICAgcHJpdmF0ZSBib29sZWFuIHN1cHBvcnRVbmtub3duRW51bVZhbHVlOworICAgICAgcHJpdmF0ZSBNZXRob2QgZ2V0VmFsdWVNZXRob2Q7CisgICAgICBwcml2YXRlIE1ldGhvZCBnZXRWYWx1ZU1ldGhvZEJ1aWxkZXI7CisgICAgICBwcml2YXRlIE1ldGhvZCBzZXRWYWx1ZU1ldGhvZDsKKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgT2JqZWN0IGdldChmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpIHsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgaW50IHZhbHVlID0gKEludGVnZXIpIGludm9rZU9yRGllKGdldFZhbHVlTWV0aG9kLCBtZXNzYWdlKTsKKyAgICAgICAgICByZXR1cm4gZW51bURlc2NyaXB0b3IuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGdldFZhbHVlRGVzY3JpcHRvck1ldGhvZCwgc3VwZXIuZ2V0KG1lc3NhZ2UpKTsKKyAgICAgIH0KKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgT2JqZWN0IGdldChmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICBpZiAoc3VwcG9ydFVua25vd25FbnVtVmFsdWUpIHsKKyAgICAgICAgICBpbnQgdmFsdWUgPSAoSW50ZWdlcikgaW52b2tlT3JEaWUoZ2V0VmFsdWVNZXRob2RCdWlsZGVyLCBidWlsZGVyKTsKKyAgICAgICAgICByZXR1cm4gZW51bURlc2NyaXB0b3IuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGdldFZhbHVlRGVzY3JpcHRvck1ldGhvZCwgc3VwZXIuZ2V0KGJ1aWxkZXIpKTsKKyAgICAgIH0KKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgdm9pZCBzZXQoZmluYWwgQnVpbGRlciBidWlsZGVyLCBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgaW52b2tlT3JEaWUoc2V0VmFsdWVNZXRob2QsIGJ1aWxkZXIsCisgICAgICAgICAgICAgICgoRW51bVZhbHVlRGVzY3JpcHRvcikgdmFsdWUpLmdldE51bWJlcigpKTsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIuc2V0KGJ1aWxkZXIsIGludm9rZU9yRGllKHZhbHVlT2ZNZXRob2QsIG51bGwsIHZhbHVlKSk7CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUmVwZWF0ZWRFbnVtRmllbGRBY2Nlc3NvcgorICAgICAgICBleHRlbmRzIFJlcGVhdGVkRmllbGRBY2Nlc3NvciB7CisgICAgICBSZXBlYXRlZEVudW1GaWVsZEFjY2Vzc29yKAorICAgICAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yLCBmaW5hbCBTdHJpbmcgY2FtZWxDYXNlTmFtZSwKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZT4gbWVzc2FnZUNsYXNzLAorICAgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBCdWlsZGVyPiBidWlsZGVyQ2xhc3MpIHsKKyAgICAgICAgc3VwZXIoZGVzY3JpcHRvciwgY2FtZWxDYXNlTmFtZSwgbWVzc2FnZUNsYXNzLCBidWlsZGVyQ2xhc3MpOworCisgICAgICAgIGVudW1EZXNjcmlwdG9yID0gZGVzY3JpcHRvci5nZXRFbnVtVHlwZSgpOworCisgICAgICAgIHZhbHVlT2ZNZXRob2QgPSBnZXRNZXRob2RPckRpZSh0eXBlLCAidmFsdWVPZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yLmNsYXNzKTsKKyAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yTWV0aG9kID0KKyAgICAgICAgICBnZXRNZXRob2RPckRpZSh0eXBlLCAiZ2V0VmFsdWVEZXNjcmlwdG9yIik7CisKKyAgICAgICAgc3VwcG9ydFVua25vd25FbnVtVmFsdWUgPSBkZXNjcmlwdG9yLmdldEZpbGUoKS5zdXBwb3J0c1Vua25vd25FbnVtVmFsdWUoKTsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgZ2V0UmVwZWF0ZWRWYWx1ZU1ldGhvZCA9CisgICAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKG1lc3NhZ2VDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIlZhbHVlIiwgaW50LmNsYXNzKTsKKyAgICAgICAgICBnZXRSZXBlYXRlZFZhbHVlTWV0aG9kQnVpbGRlciA9CisgICAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIlZhbHVlIiwgaW50LmNsYXNzKTsKKyAgICAgICAgICBzZXRSZXBlYXRlZFZhbHVlTWV0aG9kID0KKyAgICAgICAgICAgICAgZ2V0TWV0aG9kT3JEaWUoYnVpbGRlckNsYXNzLCAic2V0IiArIGNhbWVsQ2FzZU5hbWUgKyAiVmFsdWUiLCBpbnQuY2xhc3MsIGludC5jbGFzcyk7CisgICAgICAgICAgYWRkUmVwZWF0ZWRWYWx1ZU1ldGhvZCA9CisgICAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImFkZCIgKyBjYW1lbENhc2VOYW1lICsgIlZhbHVlIiwgaW50LmNsYXNzKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcHJpdmF0ZSBFbnVtRGVzY3JpcHRvciBlbnVtRGVzY3JpcHRvcjsKKworICAgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgdmFsdWVPZk1ldGhvZDsKKyAgICAgIHByaXZhdGUgZmluYWwgTWV0aG9kIGdldFZhbHVlRGVzY3JpcHRvck1ldGhvZDsKKworICAgICAgcHJpdmF0ZSBib29sZWFuIHN1cHBvcnRVbmtub3duRW51bVZhbHVlOworICAgICAgcHJpdmF0ZSBNZXRob2QgZ2V0UmVwZWF0ZWRWYWx1ZU1ldGhvZDsKKyAgICAgIHByaXZhdGUgTWV0aG9kIGdldFJlcGVhdGVkVmFsdWVNZXRob2RCdWlsZGVyOworICAgICAgcHJpdmF0ZSBNZXRob2Qgc2V0UmVwZWF0ZWRWYWx1ZU1ldGhvZDsKKyAgICAgIHByaXZhdGUgTWV0aG9kIGFkZFJlcGVhdGVkVmFsdWVNZXRob2Q7CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICBwdWJsaWMgT2JqZWN0IGdldChmaW5hbCBHZW5lcmF0ZWRNZXNzYWdlIG1lc3NhZ2UpIHsKKyAgICAgICAgZmluYWwgTGlzdCBuZXdMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGdldFJlcGVhdGVkQ291bnQobWVzc2FnZSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgbmV3TGlzdC5hZGQoZ2V0UmVwZWF0ZWQobWVzc2FnZSwgaSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG5ld0xpc3QpOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgcHVibGljIE9iamVjdCBnZXQoZmluYWwgR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgZmluYWwgTGlzdCBuZXdMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGdldFJlcGVhdGVkQ291bnQoYnVpbGRlcik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgbmV3TGlzdC5hZGQoZ2V0UmVwZWF0ZWQoYnVpbGRlciwgaSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG5ld0xpc3QpOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWQoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgaW50IHZhbHVlID0gKEludGVnZXIpIGludm9rZU9yRGllKGdldFJlcGVhdGVkVmFsdWVNZXRob2QsIG1lc3NhZ2UsIGluZGV4KTsKKyAgICAgICAgICByZXR1cm4gZW51bURlc2NyaXB0b3IuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGdldFZhbHVlRGVzY3JpcHRvck1ldGhvZCwKKyAgICAgICAgICBzdXBlci5nZXRSZXBlYXRlZChtZXNzYWdlLCBpbmRleCkpOworICAgICAgfQorICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgT2JqZWN0IGdldFJlcGVhdGVkKGZpbmFsIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgaW50IHZhbHVlID0gKEludGVnZXIpIGludm9rZU9yRGllKGdldFJlcGVhdGVkVmFsdWVNZXRob2RCdWlsZGVyLCBidWlsZGVyLCBpbmRleCk7CisgICAgICAgICAgcmV0dXJuIGVudW1EZXNjcmlwdG9yLmZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24odmFsdWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShnZXRWYWx1ZURlc2NyaXB0b3JNZXRob2QsCisgICAgICAgICAgc3VwZXIuZ2V0UmVwZWF0ZWQoYnVpbGRlciwgaW5kZXgpKTsKKyAgICAgIH0KKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgc2V0UmVwZWF0ZWQoZmluYWwgQnVpbGRlciBidWlsZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4LCBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHN1cHBvcnRVbmtub3duRW51bVZhbHVlKSB7CisgICAgICAgICAgaW52b2tlT3JEaWUoc2V0UmVwZWF0ZWRWYWx1ZU1ldGhvZCwgYnVpbGRlciwgaW5kZXgsCisgICAgICAgICAgICAgICgoRW51bVZhbHVlRGVzY3JpcHRvcikgdmFsdWUpLmdldE51bWJlcigpKTsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIuc2V0UmVwZWF0ZWQoYnVpbGRlciwgaW5kZXgsIGludm9rZU9yRGllKHZhbHVlT2ZNZXRob2QsIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlKSk7CisgICAgICB9CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIGFkZFJlcGVhdGVkKGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmIChzdXBwb3J0VW5rbm93bkVudW1WYWx1ZSkgeworICAgICAgICAgIGludm9rZU9yRGllKGFkZFJlcGVhdGVkVmFsdWVNZXRob2QsIGJ1aWxkZXIsCisgICAgICAgICAgICAgICgoRW51bVZhbHVlRGVzY3JpcHRvcikgdmFsdWUpLmdldE51bWJlcigpKTsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIuYWRkUmVwZWF0ZWQoYnVpbGRlciwgaW52b2tlT3JEaWUodmFsdWVPZk1ldGhvZCwgbnVsbCwgdmFsdWUpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEZpZWxkIGFjY2Vzc29yIGZvciBzdHJpbmcgZmllbGRzLgorICAgICAqCisgICAgICogPHA+VGhpcyBjbGFzcyBtYWtlcyBnZXRGb29CeXRlcygpIGFuZCBzZXRGb29CeXRlcygpIGF2YWlsYWJsZSBmb3IKKyAgICAgKiByZWZsZWN0aW9uIEFQSSBzbyB0aGF0IHJlZmxlY3Rpb24gYmFzZWQgc2VyaWFsaXplL3BhcnNlIGZ1bmN0aW9ucyBjYW4KKyAgICAgKiBhY2Nlc3MgdGhlIHJhdyBieXRlcyBvZiB0aGUgZmllbGQgdG8gcHJlc2VydmUgbm9uLVVURjggYnl0ZXMgaW4gdGhlCisgICAgICogc3RyaW5nLgorICAgICAqCisgICAgICogPHA+VGhpcyBlbnN1cmVzIHRoZSBzZXJpYWxpemUvcGFyc2Ugcm91bmQtdHJpcCBzYWZldHksIHdoaWNoIGlzIGltcG9ydGFudAorICAgICAqIGZvciBzZXJ2ZXJzIHdoaWNoIGZvcndhcmQgbWVzc2FnZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU2luZ3VsYXJTdHJpbmdGaWVsZEFjY2Vzc29yCisgICAgICAgIGV4dGVuZHMgU2luZ3VsYXJGaWVsZEFjY2Vzc29yIHsKKyAgICAgIFNpbmd1bGFyU3RyaW5nRmllbGRBY2Nlc3NvcigKKyAgICAgICAgICBmaW5hbCBGaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciwgZmluYWwgU3RyaW5nIGNhbWVsQ2FzZU5hbWUsCisgICAgICAgICAgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2U+IG1lc3NhZ2VDbGFzcywKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgQnVpbGRlcj4gYnVpbGRlckNsYXNzLAorICAgICAgICAgIGZpbmFsIFN0cmluZyBjb250YWluaW5nT25lb2ZDYW1lbENhc2VOYW1lKSB7CisgICAgICAgIHN1cGVyKGRlc2NyaXB0b3IsIGNhbWVsQ2FzZU5hbWUsIG1lc3NhZ2VDbGFzcywgYnVpbGRlckNsYXNzLAorICAgICAgICAgICAgY29udGFpbmluZ09uZW9mQ2FtZWxDYXNlTmFtZSk7CisgICAgICAgIGdldEJ5dGVzTWV0aG9kID0gZ2V0TWV0aG9kT3JEaWUobWVzc2FnZUNsYXNzLAorICAgICAgICAgICAgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIkJ5dGVzIik7CisgICAgICAgIGdldEJ5dGVzTWV0aG9kQnVpbGRlciA9IGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywKKyAgICAgICAgICAgICJnZXQiICsgY2FtZWxDYXNlTmFtZSArICJCeXRlcyIpOworICAgICAgICBzZXRCeXRlc01ldGhvZEJ1aWxkZXIgPSBnZXRNZXRob2RPckRpZShidWlsZGVyQ2xhc3MsCisgICAgICAgICAgICAic2V0IiArIGNhbWVsQ2FzZU5hbWUgKyAiQnl0ZXMiLCBCeXRlU3RyaW5nLmNsYXNzKTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgZ2V0Qnl0ZXNNZXRob2Q7CisgICAgICBwcml2YXRlIGZpbmFsIE1ldGhvZCBnZXRCeXRlc01ldGhvZEJ1aWxkZXI7CisgICAgICBwcml2YXRlIGZpbmFsIE1ldGhvZCBzZXRCeXRlc01ldGhvZEJ1aWxkZXI7CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIE9iamVjdCBnZXRSYXcoZmluYWwgR2VuZXJhdGVkTWVzc2FnZSBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShnZXRCeXRlc01ldGhvZCwgbWVzc2FnZSk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIE9iamVjdCBnZXRSYXcoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgcmV0dXJuIGludm9rZU9yRGllKGdldEJ5dGVzTWV0aG9kQnVpbGRlciwgYnVpbGRlcik7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgc2V0KEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQnl0ZVN0cmluZykgeworICAgICAgICAgIGludm9rZU9yRGllKHNldEJ5dGVzTWV0aG9kQnVpbGRlciwgYnVpbGRlciwgdmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHN1cGVyLnNldChidWlsZGVyLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFNpbmd1bGFyTWVzc2FnZUZpZWxkQWNjZXNzb3IKKyAgICAgICAgZXh0ZW5kcyBTaW5ndWxhckZpZWxkQWNjZXNzb3IgeworICAgICAgU2luZ3VsYXJNZXNzYWdlRmllbGRBY2Nlc3NvcigKKyAgICAgICAgICBmaW5hbCBGaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciwgZmluYWwgU3RyaW5nIGNhbWVsQ2FzZU5hbWUsCisgICAgICAgICAgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2U+IG1lc3NhZ2VDbGFzcywKKyAgICAgICAgICBmaW5hbCBDbGFzczw/IGV4dGVuZHMgQnVpbGRlcj4gYnVpbGRlckNsYXNzLAorICAgICAgICAgIGZpbmFsIFN0cmluZyBjb250YWluaW5nT25lb2ZDYW1lbENhc2VOYW1lKSB7CisgICAgICAgIHN1cGVyKGRlc2NyaXB0b3IsIGNhbWVsQ2FzZU5hbWUsIG1lc3NhZ2VDbGFzcywgYnVpbGRlckNsYXNzLAorICAgICAgICAgICAgY29udGFpbmluZ09uZW9mQ2FtZWxDYXNlTmFtZSk7CisKKyAgICAgICAgbmV3QnVpbGRlck1ldGhvZCA9IGdldE1ldGhvZE9yRGllKHR5cGUsICJuZXdCdWlsZGVyIik7CisgICAgICAgIGdldEJ1aWxkZXJNZXRob2RCdWlsZGVyID0KKyAgICAgICAgICAgIGdldE1ldGhvZE9yRGllKGJ1aWxkZXJDbGFzcywgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIkJ1aWxkZXIiKTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgbmV3QnVpbGRlck1ldGhvZDsKKyAgICAgIHByaXZhdGUgZmluYWwgTWV0aG9kIGdldEJ1aWxkZXJNZXRob2RCdWlsZGVyOworCisgICAgICBwcml2YXRlIE9iamVjdCBjb2VyY2VUeXBlKGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAodHlwZS5pc0luc3RhbmNlKHZhbHVlKSkgeworICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBUaGUgdmFsdWUgaXMgbm90IHRoZSBleGFjdCByaWdodCBtZXNzYWdlIHR5cGUuICBIb3dldmVyLCBpZiBpdAorICAgICAgICAgIC8vIGlzIGFuIGFsdGVybmF0aXZlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzYW1lIHR5cGUgLS0gZS5nLiBhCisgICAgICAgICAgLy8gRHluYW1pY01lc3NhZ2UgLS0gd2Ugc2hvdWxkIGFjY2VwdCBpdC4gIEluIHRoaXMgY2FzZSB3ZSBjYW4gbWFrZQorICAgICAgICAgIC8vIGEgY29weSBvZiB0aGUgbWVzc2FnZS4KKyAgICAgICAgICByZXR1cm4gKChNZXNzYWdlLkJ1aWxkZXIpIGludm9rZU9yRGllKG5ld0J1aWxkZXJNZXRob2QsIG51bGwpKQorICAgICAgICAgICAgICAgICAgLm1lcmdlRnJvbSgoTWVzc2FnZSkgdmFsdWUpLmJ1aWxkUGFydGlhbCgpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgc2V0KGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHN1cGVyLnNldChidWlsZGVyLCBjb2VyY2VUeXBlKHZhbHVlKSk7CisgICAgICB9CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBNZXNzYWdlLkJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICAgICAgcmV0dXJuIChNZXNzYWdlLkJ1aWxkZXIpIGludm9rZU9yRGllKG5ld0J1aWxkZXJNZXRob2QsIG51bGwpOworICAgICAgfQorICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgTWVzc2FnZS5CdWlsZGVyIGdldEJ1aWxkZXIoR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgcmV0dXJuIChNZXNzYWdlLkJ1aWxkZXIpIGludm9rZU9yRGllKGdldEJ1aWxkZXJNZXRob2RCdWlsZGVyLCBidWlsZGVyKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXBlYXRlZE1lc3NhZ2VGaWVsZEFjY2Vzc29yCisgICAgICAgIGV4dGVuZHMgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHsKKyAgICAgIFJlcGVhdGVkTWVzc2FnZUZpZWxkQWNjZXNzb3IoCisgICAgICAgICAgZmluYWwgRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IsIGZpbmFsIFN0cmluZyBjYW1lbENhc2VOYW1lLAorICAgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlPiBtZXNzYWdlQ2xhc3MsCisgICAgICAgICAgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEJ1aWxkZXI+IGJ1aWxkZXJDbGFzcykgeworICAgICAgICBzdXBlcihkZXNjcmlwdG9yLCBjYW1lbENhc2VOYW1lLCBtZXNzYWdlQ2xhc3MsIGJ1aWxkZXJDbGFzcyk7CisKKyAgICAgICAgbmV3QnVpbGRlck1ldGhvZCA9IGdldE1ldGhvZE9yRGllKHR5cGUsICJuZXdCdWlsZGVyIik7CisgICAgICAgIGdldEJ1aWxkZXJNZXRob2RCdWlsZGVyID0gZ2V0TWV0aG9kT3JEaWUoYnVpbGRlckNsYXNzLAorICAgICAgICAgICAgImdldCIgKyBjYW1lbENhc2VOYW1lICsgIkJ1aWxkZXIiLCBJbnRlZ2VyLlRZUEUpOworICAgICAgfQorCisgICAgICBwcml2YXRlIGZpbmFsIE1ldGhvZCBuZXdCdWlsZGVyTWV0aG9kOworICAgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgZ2V0QnVpbGRlck1ldGhvZEJ1aWxkZXI7CisKKyAgICAgIHByaXZhdGUgT2JqZWN0IGNvZXJjZVR5cGUoZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICh0eXBlLmlzSW5zdGFuY2UodmFsdWUpKSB7CisgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFRoZSB2YWx1ZSBpcyBub3QgdGhlIGV4YWN0IHJpZ2h0IG1lc3NhZ2UgdHlwZS4gIEhvd2V2ZXIsIGlmIGl0CisgICAgICAgICAgLy8gaXMgYW4gYWx0ZXJuYXRpdmUgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNhbWUgdHlwZSAtLSBlLmcuIGEKKyAgICAgICAgICAvLyBEeW5hbWljTWVzc2FnZSAtLSB3ZSBzaG91bGQgYWNjZXB0IGl0LiAgSW4gdGhpcyBjYXNlIHdlIGNhbiBtYWtlCisgICAgICAgICAgLy8gYSBjb3B5IG9mIHRoZSBtZXNzYWdlLgorICAgICAgICAgIHJldHVybiAoKE1lc3NhZ2UuQnVpbGRlcikgaW52b2tlT3JEaWUobmV3QnVpbGRlck1ldGhvZCwgbnVsbCkpCisgICAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKChNZXNzYWdlKSB2YWx1ZSkuYnVpbGQoKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIHNldFJlcGVhdGVkKGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHN1cGVyLnNldFJlcGVhdGVkKGJ1aWxkZXIsIGluZGV4LCBjb2VyY2VUeXBlKHZhbHVlKSk7CisgICAgICB9CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIGFkZFJlcGVhdGVkKGZpbmFsIEJ1aWxkZXIgYnVpbGRlciwgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHN1cGVyLmFkZFJlcGVhdGVkKGJ1aWxkZXIsIGNvZXJjZVR5cGUodmFsdWUpKTsKKyAgICAgIH0KKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBuZXdCdWlsZGVyKCkgeworICAgICAgICByZXR1cm4gKE1lc3NhZ2UuQnVpbGRlcikgaW52b2tlT3JEaWUobmV3QnVpbGRlck1ldGhvZCwgbnVsbCk7CisgICAgICB9CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRCdWlsZGVyKAorICAgICAgICAgIGZpbmFsIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLCBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIChNZXNzYWdlLkJ1aWxkZXIpIGludm9rZU9yRGllKAorICAgICAgICAgICAgZ2V0QnVpbGRlck1ldGhvZEJ1aWxkZXIsIGJ1aWxkZXIsIGluZGV4KTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmVwbGFjZXMgdGhpcyBvYmplY3QgaW4gdGhlIG91dHB1dCBzdHJlYW0gd2l0aCBhIHNlcmlhbGl6ZWQgZm9ybS4KKyAgICogUGFydCBvZiBKYXZhJ3Mgc2VyaWFsaXphdGlvbiBtYWdpYy4gIEdlbmVyYXRlZCBzdWItY2xhc3NlcyBtdXN0IG92ZXJyaWRlCisgICAqIHRoaXMgbWV0aG9kIGJ5IGNhbGxpbmcge0Bjb2RlIHJldHVybiBzdXBlci53cml0ZVJlcGxhY2UoKTt9CisgICAqIEByZXR1cm4gYSBTZXJpYWxpemVkRm9ybSBvZiB0aGlzIG1lc3NhZ2UKKyAgICovCisgIHByb3RlY3RlZCBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5TZXJpYWxpemVkRm9ybSh0aGlzKTsKKyAgfQorCisgIC8qKgorICAgKiBDaGVja3MgdGhhdCB0aGUge0BsaW5rIEV4dGVuc2lvbn0gaXMgbm9uLUxpdGUgYW5kIHJldHVybnMgaXQgYXMgYQorICAgKiB7QGxpbmsgR2VuZXJhdGVkRXh0ZW5zaW9ufS4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIDxNZXNzYWdlVHlwZSBleHRlbmRzIEV4dGVuZGFibGVNZXNzYWdlPE1lc3NhZ2VUeXBlPiwgVD4KKyAgICBFeHRlbnNpb248TWVzc2FnZVR5cGUsIFQ+IGNoZWNrTm90TGl0ZSgKKyAgICAgICAgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVD4gZXh0ZW5zaW9uKSB7CisgICAgaWYgKGV4dGVuc2lvbi5pc0xpdGUoKSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRXhwZWN0ZWQgbm9uLWxpdGUgZXh0ZW5zaW9uLiIpOworICAgIH0KKworICAgIHJldHVybiAoRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBUPikgZXh0ZW5zaW9uOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9HZW5lcmF0ZWRNZXNzYWdlTGl0ZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZUxpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODM5YzlkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZUxpdGUuamF2YQpAQCAtMCwwICsxLDExMTYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50SGFzaE1hcDsKKworLyoqCisgKiBMaXRlIHZlcnNpb24gb2Yge0BsaW5rIEdlbmVyYXRlZE1lc3NhZ2V9LgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlTGl0ZTwKKyAgICBNZXNzYWdlVHlwZSBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2VMaXRlPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4sCisgICAgQnVpbGRlclR5cGUgZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5CdWlsZGVyPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4+IAorICAgICAgICBleHRlbmRzIEFic3RyYWN0TWVzc2FnZUxpdGUKKyAgICAgICAgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAKKyAgLyoqCisgICAqIEhvbGRzIGFsbCB0aGUge0BsaW5rIFByb3RvdHlwZUhvbGRlcn1zIGZvciBsb2FkZWQgY2xhc3Nlcy4KKyAgICovCisgIC8vIFRPRE8oZHdlaXMpOiBDb25zaWRlciBkaWZmZXJlbnQgY29uY3VycmVuY3kgdmFsdWVzLgorICAvLyBUT0RPKGR3ZWlzKTogVGhpcyB3aWxsIHByZXZlbnQgZ2FyYmFnZSBjb2xsZWN0aW9uIG9mIHRoZSBjbGFzcyBsb2FkZXIuCisgIC8vICAgICBJZGVhbGx5IHdlJ2QgdXNlIHNvbWV0aGluZyBsaWtlIENsYXNzVmFsdWUgYnV0IHRoYXQncyBKYXZhIDcgb25seS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPENsYXNzPD8+LCBQcm90b3R5cGVIb2xkZXI8PywgPz4+IFBST1RPVFlQRV9NQVAgPQorICAgICAgbmV3IENvbmN1cnJlbnRIYXNoTWFwPENsYXNzPD8+LCBQcm90b3R5cGVIb2xkZXI8PywgPz4+KCk7CisgIAorICAvLyBGb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgIHByb3RlY3RlZCBzdGF0aWMgPAorICAgICAgTWVzc2FnZVR5cGUgZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlTGl0ZTxNZXNzYWdlVHlwZSwgQnVpbGRlclR5cGU+LAorICAgICAgQnVpbGRlclR5cGUgZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5CdWlsZGVyPAorICAgICAgICAgIE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4+IHZvaWQgb25Mb2FkKENsYXNzPE1lc3NhZ2VUeXBlPiBjbGF6eiwKKyAgICAgICAgICAgICAgUHJvdG90eXBlSG9sZGVyPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4gcHJvdG9UeXBlSG9sZGVyKSB7CisgICAgUFJPVE9UWVBFX01BUC5wdXQoY2xhenosIHByb3RvVHlwZUhvbGRlcik7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAvKiogRm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiAgKi8KKyAgcHJvdGVjdGVkIFVua25vd25GaWVsZFNldExpdGUgdW5rbm93bkZpZWxkczsKKyAgCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBHdWFyYW50ZWVkIGJ5IHJ1bnRpbWUuCisgIHB1YmxpYyBmaW5hbCBQYXJzZXI8TWVzc2FnZVR5cGU+IGdldFBhcnNlckZvclR5cGUoKSB7CisgICAgcmV0dXJuIChQYXJzZXI8TWVzc2FnZVR5cGU+KSBQUk9UT1RZUEVfTUFQCisgICAgICAgIC5nZXQoZ2V0Q2xhc3MoKSkuZ2V0UGFyc2VyRm9yVHlwZSgpOworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIEd1YXJhbnRlZWQgYnkgcnVudGltZS4KKyAgcHVibGljIGZpbmFsIE1lc3NhZ2VUeXBlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CisgICAgcmV0dXJuIChNZXNzYWdlVHlwZSkgUFJPVE9UWVBFX01BUAorICAgICAgICAuZ2V0KGdldENsYXNzKCkpLmdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBHdWFyYW50ZWVkIGJ5IHJ1bnRpbWUuCisgIHB1YmxpYyBmaW5hbCBCdWlsZGVyVHlwZSBuZXdCdWlsZGVyRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSBQUk9UT1RZUEVfTUFQCisgICAgICAgIC5nZXQoZ2V0Q2xhc3MoKSkubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgfQorCisgIC8qKgorICAgKiBDYWxsZWQgYnkgc3ViY2xhc3NlcyB0byBwYXJzZSBhbiB1bmtub3duIGZpZWxkLiBGb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlCisgICAqIG9ubHkuCisgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IHVubGVzcyB0aGUgdGFnIGlzIGFuIGVuZC1ncm91cCB0YWcuCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gcGFyc2VVbmtub3duRmllbGQoCisgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgVW5rbm93bkZpZWxkU2V0TGl0ZS5CdWlsZGVyIHVua25vd25GaWVsZHMsCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICBpbnQgdGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB1bmtub3duRmllbGRzLm1lcmdlRmllbGRGcm9tKHRhZywgaW5wdXQpOworICB9CisKKyAgLy8gVGhlIGRlZmF1bHQgYmVoYXZpb3IuIElmIGEgbWVzc2FnZSBoYXMgcmVxdWlyZWQgZmllbGRzIGluIGl0cyBzdWJ0cmVlLCB0aGUKKyAgLy8gZ2VuZXJhdGVkIGNvZGUgd2lsbCBvdmVycmlkZS4KKyAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXI8CisgICAgICBNZXNzYWdlVHlwZSBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2VMaXRlPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4sCisgICAgICBCdWlsZGVyVHlwZSBleHRlbmRzIEJ1aWxkZXI8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPj4KKyAgICAgICAgICBleHRlbmRzIEFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlcjxCdWlsZGVyVHlwZT4geworCisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlVHlwZSBkZWZhdWx0SW5zdGFuY2U7CisKKyAgICAvKiogRm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiAqLworICAgIHByb3RlY3RlZCBVbmtub3duRmllbGRTZXRMaXRlIHVua25vd25GaWVsZHMgPQorICAgICAgICBVbmtub3duRmllbGRTZXRMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOworCisgICAgcHJvdGVjdGVkIEJ1aWxkZXIoTWVzc2FnZVR5cGUgZGVmYXVsdEluc3RhbmNlKSB7CisgICAgICB0aGlzLmRlZmF1bHRJbnN0YW5jZSA9IGRlZmF1bHRJbnN0YW5jZTsKKyAgICB9CisKKyAgICAvLyBUaGUgZGVmYXVsdCBiZWhhdmlvci4gSWYgYSBtZXNzYWdlIGhhcyByZXF1aXJlZCBmaWVsZHMgaW4gaXRzIHN1YnRyZWUsCisgICAgLy8gdGhlIGdlbmVyYXRlZCBjb2RlIHdpbGwgb3ZlcnJpZGUuCisgICAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBCdWlsZGVyVHlwZSBjbGVhcigpIHsKKyAgICAgIHVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXRMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xvbmUoKSB7CisgICAgICBCdWlsZGVyVHlwZSBidWlsZGVyID0KKyAgICAgICAgICAoQnVpbGRlclR5cGUpIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgICAgYnVpbGRlci5tZXJnZUZyb20oYnVpbGRQYXJ0aWFsKCkpOworICAgICAgcmV0dXJuIGJ1aWxkZXI7CisgICAgfQorCisgICAgLyoqIEFsbCBzdWJjbGFzc2VzIGltcGxlbWVudCB0aGlzLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBNZXNzYWdlVHlwZSBidWlsZFBhcnRpYWwoKTsKKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBmaW5hbCBNZXNzYWdlVHlwZSBidWlsZCgpIHsKKyAgICAgIE1lc3NhZ2VUeXBlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOworICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKiBBbGwgc3ViY2xhc3NlcyBpbXBsZW1lbnQgdGhpcy4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlclR5cGUgbWVyZ2VGcm9tKE1lc3NhZ2VUeXBlIG1lc3NhZ2UpOworICAgIAorICAgIHB1YmxpYyBNZXNzYWdlVHlwZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIGRlZmF1bHRJbnN0YW5jZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgYnkgc3ViY2xhc3NlcyB0byBwYXJzZSBhbiB1bmtub3duIGZpZWxkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IHVubGVzcyB0aGUgdGFnIGlzIGFuIGVuZC1ncm91cCB0YWcuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VVbmtub3duRmllbGQoCisgICAgICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIFVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciB1bmtub3duRmllbGRzLAorICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICAgIGludCB0YWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gdW5rbm93bkZpZWxkcy5tZXJnZUZpZWxkRnJvbSh0YWcsIGlucHV0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXJnZSBzb21lIHVua25vd24gZmllbGRzIGludG8gdGhlIHtAbGluayBVbmtub3duRmllbGRTZXRMaXRlfSBmb3IgdGhpcworICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiA8cD5Gb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIEJ1aWxkZXJUeXBlIG1lcmdlVW5rbm93bkZpZWxkcygKKyAgICAgICAgZmluYWwgVW5rbm93bkZpZWxkU2V0TGl0ZSB1bmtub3duRmllbGRzKSB7CisgICAgICB0aGlzLnVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXRMaXRlLmNvbmNhdCh0aGlzLnVua25vd25GaWVsZHMsIHVua25vd25GaWVsZHMpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisgICAgCisgICAgcHVibGljIEJ1aWxkZXJUeXBlIG1lcmdlRnJvbSgKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgTWVzc2FnZVR5cGUgcGFyc2VkTWVzc2FnZSA9IG51bGw7CisgICAgICB0cnkgeworICAgICAgICBwYXJzZWRNZXNzYWdlID0KKyAgICAgICAgICAgIChNZXNzYWdlVHlwZSkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpLmdldFBhcnNlckZvclR5cGUoKS5wYXJzZVBhcnRpYWxGcm9tKAorICAgICAgICAgICAgICAgIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHBhcnNlZE1lc3NhZ2UgPSAoTWVzc2FnZVR5cGUpIGUuZ2V0VW5maW5pc2hlZE1lc3NhZ2UoKTsKKyAgICAgICAgdGhyb3cgZTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIGlmIChwYXJzZWRNZXNzYWdlICE9IG51bGwpIHsKKyAgICAgICAgICBtZXJnZUZyb20ocGFyc2VkTWVzc2FnZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorICB9CisKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBFeHRlbnNpb25zLXJlbGF0ZWQgc3R1ZmYKKworICAvKioKKyAgICogTGl0ZSBlcXVpdmFsZW50IG9mIHtAbGluayBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXJ9LgorICAgKi8KKyAgcHVibGljIGludGVyZmFjZSBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjwKKyAgICAgIE1lc3NhZ2VUeXBlIGV4dGVuZHMgRXh0ZW5kYWJsZU1lc3NhZ2U8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPiwKKyAgICAgIEJ1aWxkZXJUeXBlIGV4dGVuZHMgRXh0ZW5kYWJsZUJ1aWxkZXI8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPj4KKyAgICAgICAgICBleHRlbmRzIE1lc3NhZ2VMaXRlT3JCdWlsZGVyIHsKKworICAgIC8qKiBDaGVjayBpZiBhIHNpbmd1bGFyIGV4dGVuc2lvbiBpcyBwcmVzZW50LiAqLworICAgIDxUeXBlPiBib29sZWFuIGhhc0V4dGVuc2lvbigKKyAgICAgICAgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uKTsKKworICAgIC8qKiBHZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICA8VHlwZT4gaW50IGdldEV4dGVuc2lvbkNvdW50KAorICAgICAgICBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24pOworCisgICAgLyoqIEdldCB0aGUgdmFsdWUgb2YgYW4gZXh0ZW5zaW9uLiAqLworICAgIDxUeXBlPiBUeXBlIGdldEV4dGVuc2lvbihFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb24pOworCisgICAgLyoqIEdldCBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICA8VHlwZT4gVHlwZSBnZXRFeHRlbnNpb24oCisgICAgICAgIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKKyAgICAgICAgaW50IGluZGV4KTsKKyAgfQorCisgIC8qKgorICAgKiBMaXRlIGVxdWl2YWxlbnQgb2Yge0BsaW5rIEdlbmVyYXRlZE1lc3NhZ2UuRXh0ZW5kYWJsZU1lc3NhZ2V9LgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBFeHRlbmRhYmxlTWVzc2FnZTwKKyAgICAgICAgTWVzc2FnZVR5cGUgZXh0ZW5kcyBFeHRlbmRhYmxlTWVzc2FnZTxNZXNzYWdlVHlwZSwgQnVpbGRlclR5cGU+LAorICAgICAgICBCdWlsZGVyVHlwZSBleHRlbmRzIEV4dGVuZGFibGVCdWlsZGVyPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4+CisgICAgICAgICAgICBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2VMaXRlPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4KKyAgICAgICAgICAgIGltcGxlbWVudHMgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPiB7CisKKyAgICAvKioKKyAgICAgKiBSZXByZXNlbnRzIHRoZSBzZXQgb2YgZXh0ZW5zaW9ucyBvbiB0aGlzIG1lc3NhZ2UuIEZvciB1c2UgYnkgZ2VuZXJhdGVkCisgICAgICogY29kZSBvbmx5LgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWVsZFNldDxFeHRlbnNpb25EZXNjcmlwdG9yPiBleHRlbnNpb25zID0gRmllbGRTZXQubmV3RmllbGRTZXQoKTsKKworICAgIC8vIC0xID0+IG5vdCBtZW1vaXplZCwgMCA9PiBmYWxzZSwgMSA9PiB0cnVlLgorICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKKworICAgIC8vIFRoZSBkZWZhdWx0IGJlaGF2aW9yLiBJZiBhIG1lc3NhZ2UgaGFzIHJlcXVpcmVkIGZpZWxkcyBpbiBpdHMgc3VidHJlZSwKKyAgICAvLyB0aGUgZ2VuZXJhdGVkIGNvZGUgd2lsbCBvdmVycmlkZS4KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgeworICAgICAgaWYgKG1lbW9pemVkSXNJbml0aWFsaXplZCA9PSAtMSkgeworICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAoYnl0ZSkgKGV4dGVuc2lvbnMuaXNJbml0aWFsaXplZCgpID8gMSA6IDApOworICAgICAgfQorCisgICAgICByZXR1cm4gbWVtb2l6ZWRJc0luaXRpYWxpemVkID09IDE7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKAorICAgICAgICBmaW5hbCBHZW5lcmF0ZWRFeHRlbnNpb248TWVzc2FnZVR5cGUsID8+IGV4dGVuc2lvbikgeworICAgICAgaWYgKGV4dGVuc2lvbi5nZXRDb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZSgpICE9CisgICAgICAgICAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpKSB7CisgICAgICAgIC8vIFRoaXMgY2FuIG9ubHkgaGFwcGVuIGlmIHNvbWVvbmUgdXNlcyB1bmNoZWNrZWQgb3BlcmF0aW9ucy4KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiVGhpcyBleHRlbnNpb24gaXMgZm9yIGEgZGlmZmVyZW50IG1lc3NhZ2UgdHlwZS4gIFBsZWFzZSBtYWtlICIgKworICAgICAgICAgICJzdXJlIHRoYXQgeW91IGFyZSBub3Qgc3VwcHJlc3NpbmcgYW55IGdlbmVyaWNzIHR5cGUgd2FybmluZ3MuIik7CisgICAgICB9CisgICAgfQorCisgICAgLyoqIENoZWNrIGlmIGEgc2luZ3VsYXIgZXh0ZW5zaW9uIGlzIHByZXNlbnQuICovCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIGZpbmFsIDxUeXBlPiBib29sZWFuIGhhc0V4dGVuc2lvbigKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uKSB7CisgICAgICBHZW5lcmF0ZWRFeHRlbnNpb248TWVzc2FnZVR5cGUsIFR5cGU+IGV4dGVuc2lvbkxpdGUgPQorICAgICAgICAgIGNoZWNrSXNMaXRlKGV4dGVuc2lvbik7CisgICAgICAKKyAgICAgIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKGV4dGVuc2lvbkxpdGUpOworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuaGFzRmllbGQoZXh0ZW5zaW9uTGl0ZS5kZXNjcmlwdG9yKTsKKyAgICB9CisKKyAgICAvKiogR2V0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gYSByZXBlYXRlZCBleHRlbnNpb24uICovCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIGZpbmFsIDxUeXBlPiBpbnQgZ2V0RXh0ZW5zaW9uQ291bnQoCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbikgeworICAgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb25MaXRlID0KKyAgICAgICAgICBjaGVja0lzTGl0ZShleHRlbnNpb24pOworICAgICAgCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb25MaXRlKTsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmdldFJlcGVhdGVkRmllbGRDb3VudChleHRlbnNpb25MaXRlLmRlc2NyaXB0b3IpOworICAgIH0KKworICAgIC8qKiBHZXQgdGhlIHZhbHVlIG9mIGFuIGV4dGVuc2lvbi4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IFR5cGUgZ2V0RXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb24pIHsKKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uTGl0ZSA9CisgICAgICAgICAgY2hlY2tJc0xpdGUoZXh0ZW5zaW9uKTsKKyAgICAgIAorICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uTGl0ZSk7CisgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBleHRlbnNpb25zLmdldEZpZWxkKGV4dGVuc2lvbkxpdGUuZGVzY3JpcHRvcik7CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gZXh0ZW5zaW9uTGl0ZS5kZWZhdWx0VmFsdWU7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gKFR5cGUpIGV4dGVuc2lvbkxpdGUuZnJvbUZpZWxkU2V0VHlwZSh2YWx1ZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqIEdldCBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IFR5cGUgZ2V0RXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24sCisgICAgICAgIGZpbmFsIGludCBpbmRleCkgeworICAgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb25MaXRlID0KKyAgICAgICAgICBjaGVja0lzTGl0ZShleHRlbnNpb24pOworCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb25MaXRlKTsKKyAgICAgIHJldHVybiAoVHlwZSkgZXh0ZW5zaW9uTGl0ZS5zaW5ndWxhckZyb21GaWVsZFNldFR5cGUoCisgICAgICAgICAgZXh0ZW5zaW9ucy5nZXRSZXBlYXRlZEZpZWxkKGV4dGVuc2lvbkxpdGUuZGVzY3JpcHRvciwgaW5kZXgpKTsKKyAgICB9CisKKyAgICAvKiogQ2FsbGVkIGJ5IHN1YmNsYXNzZXMgdG8gY2hlY2sgaWYgYWxsIGV4dGVuc2lvbnMgYXJlIGluaXRpYWxpemVkLiAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpIHsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmlzSW5pdGlhbGl6ZWQoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFVzZWQgYnkgcGFyc2luZyBjb25zdHJ1Y3RvcnMgaW4gZ2VuZXJhdGVkIGNsYXNzZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIG1ha2VFeHRlbnNpb25zSW1tdXRhYmxlKAorICAgICAgICBGaWVsZFNldDxFeHRlbnNpb25EZXNjcmlwdG9yPiBleHRlbnNpb25zKSB7CisgICAgICBleHRlbnNpb25zLm1ha2VJbW11dGFibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGJ5IHN1YmNsYXNzZXMgdG8gc2VyaWFsaXplIGV4dGVuc2lvbnMuICBFeHRlbnNpb24gcmFuZ2VzIG1heSBiZQorICAgICAqIGludGVybGVhdmVkIHdpdGggZmllbGQgbnVtYmVycywgYnV0IHdlIG11c3Qgd3JpdGUgdGhlbSBpbiBjYW5vbmljYWwKKyAgICAgKiAoc29ydGVkIGJ5IGZpZWxkIG51bWJlcikgb3JkZXIuICBFeHRlbnNpb25Xcml0ZXIgaGVscHMgdXMgd3JpdGUKKyAgICAgKiBpbmRpdmlkdWFsIHJhbmdlcyBvZiBleHRlbnNpb25zIGF0IG9uY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGNsYXNzIEV4dGVuc2lvbldyaXRlciB7CisgICAgICAvLyBJbWFnaW5lIGhvdyBtdWNoIHNpbXBsZXIgdGhpcyBjb2RlIHdvdWxkIGJlIGlmIEphdmEgaXRlcmF0b3JzIGhhZAorICAgICAgLy8gYSB3YXkgdG8gZ2V0IHRoZSBuZXh0IGVsZW1lbnQgd2l0aG91dCBhZHZhbmNpbmcgdGhlIGl0ZXJhdG9yLgorCisgICAgICBwcml2YXRlIGZpbmFsIEl0ZXJhdG9yPE1hcC5FbnRyeTxFeHRlbnNpb25EZXNjcmlwdG9yLCBPYmplY3Q+PiBpdGVyID0KKyAgICAgICAgICAgIGV4dGVuc2lvbnMuaXRlcmF0b3IoKTsKKyAgICAgIHByaXZhdGUgTWFwLkVudHJ5PEV4dGVuc2lvbkRlc2NyaXB0b3IsIE9iamVjdD4gbmV4dDsKKyAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBtZXNzYWdlU2V0V2lyZUZvcm1hdDsKKworICAgICAgcHJpdmF0ZSBFeHRlbnNpb25Xcml0ZXIoYm9vbGVhbiBtZXNzYWdlU2V0V2lyZUZvcm1hdCkgeworICAgICAgICBpZiAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICBuZXh0ID0gaXRlci5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5tZXNzYWdlU2V0V2lyZUZvcm1hdCA9IG1lc3NhZ2VTZXRXaXJlRm9ybWF0OworICAgICAgfQorCisgICAgICBwdWJsaWMgdm9pZCB3cml0ZVVudGlsKGZpbmFsIGludCBlbmQsIGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd2hpbGUgKG5leHQgIT0gbnVsbCAmJiBuZXh0LmdldEtleSgpLmdldE51bWJlcigpIDwgZW5kKSB7CisgICAgICAgICAgRXh0ZW5zaW9uRGVzY3JpcHRvciBleHRlbnNpb24gPSBuZXh0LmdldEtleSgpOworICAgICAgICAgIGlmIChtZXNzYWdlU2V0V2lyZUZvcm1hdCAmJiBleHRlbnNpb24uZ2V0TGl0ZUphdmFUeXBlKCkgPT0KKyAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXQuSmF2YVR5cGUuTUVTU0FHRSAmJgorICAgICAgICAgICAgICAhZXh0ZW5zaW9uLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZVNldEV4dGVuc2lvbihleHRlbnNpb24uZ2V0TnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNZXNzYWdlTGl0ZSkgbmV4dC5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgRmllbGRTZXQud3JpdGVGaWVsZChleHRlbnNpb24sIG5leHQuZ2V0VmFsdWUoKSwgb3V0cHV0KTsKKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBuZXh0ID0gaXRlci5uZXh0KCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG5leHQgPSBudWxsOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBFeHRlbnNpb25Xcml0ZXIgbmV3RXh0ZW5zaW9uV3JpdGVyKCkgeworICAgICAgcmV0dXJuIG5ldyBFeHRlbnNpb25Xcml0ZXIoZmFsc2UpOworICAgIH0KKyAgICBwcm90ZWN0ZWQgRXh0ZW5zaW9uV3JpdGVyIG5ld01lc3NhZ2VTZXRFeHRlbnNpb25Xcml0ZXIoKSB7CisgICAgICByZXR1cm4gbmV3IEV4dGVuc2lvbldyaXRlcih0cnVlKTsKKyAgICB9CisKKyAgICAvKiogQ2FsbGVkIGJ5IHN1YmNsYXNzZXMgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiBleHRlbnNpb25zLiAqLworICAgIHByb3RlY3RlZCBpbnQgZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICB9CisgICAgcHJvdGVjdGVkIGludCBleHRlbnNpb25zU2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXQoKSB7CisgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5nZXRNZXNzYWdlU2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTGl0ZSBlcXVpdmFsZW50IG9mIHtAbGluayBHZW5lcmF0ZWRNZXNzYWdlLkV4dGVuZGFibGVCdWlsZGVyfS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEV4dGVuZGFibGVCdWlsZGVyPAorICAgICAgICBNZXNzYWdlVHlwZSBleHRlbmRzIEV4dGVuZGFibGVNZXNzYWdlPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4sCisgICAgICAgIEJ1aWxkZXJUeXBlIGV4dGVuZHMgRXh0ZW5kYWJsZUJ1aWxkZXI8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPj4KKyAgICAgIGV4dGVuZHMgQnVpbGRlcjxNZXNzYWdlVHlwZSwgQnVpbGRlclR5cGU+CisgICAgICBpbXBsZW1lbnRzIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPE1lc3NhZ2VUeXBlLCBCdWlsZGVyVHlwZT4geworICAgIHByb3RlY3RlZCBFeHRlbmRhYmxlQnVpbGRlcihNZXNzYWdlVHlwZSBkZWZhdWx0SW5zdGFuY2UpIHsKKyAgICAgIHN1cGVyKGRlZmF1bHRJbnN0YW5jZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBGaWVsZFNldDxFeHRlbnNpb25EZXNjcmlwdG9yPiBleHRlbnNpb25zID0gRmllbGRTZXQuZW1wdHlTZXQoKTsKKyAgICBwcml2YXRlIGJvb2xlYW4gZXh0ZW5zaW9uc0lzTXV0YWJsZTsKKworICAgIC8vIFRoZSBkZWZhdWx0IGJlaGF2aW9yLiBJZiBhIG1lc3NhZ2UgaGFzIHJlcXVpcmVkIGZpZWxkcyBpbiBpdHMgc3VidHJlZSwKKyAgICAvLyB0aGUgZ2VuZXJhdGVkIGNvZGUgd2lsbCBvdmVycmlkZS4KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuaXNJbml0aWFsaXplZCgpOworICAgIH0KKworICAgIC8vIEZvciBpbW11dGFibGUgbWVzc2FnZSBjb252ZXJzaW9uLgorICAgIHZvaWQgaW50ZXJuYWxTZXRFeHRlbnNpb25TZXQoRmllbGRTZXQ8RXh0ZW5zaW9uRGVzY3JpcHRvcj4gZXh0ZW5zaW9ucykgeworICAgICAgdGhpcy5leHRlbnNpb25zID0gZXh0ZW5zaW9uczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xlYXIoKSB7CisgICAgICBleHRlbnNpb25zLmNsZWFyKCk7CisgICAgICBleHRlbnNpb25zSXNNdXRhYmxlID0gZmFsc2U7CisgICAgICByZXR1cm4gc3VwZXIuY2xlYXIoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlRXh0ZW5zaW9uc0lzTXV0YWJsZSgpIHsKKyAgICAgIGlmICghZXh0ZW5zaW9uc0lzTXV0YWJsZSkgeworICAgICAgICBleHRlbnNpb25zID0gZXh0ZW5zaW9ucy5jbG9uZSgpOworICAgICAgICBleHRlbnNpb25zSXNNdXRhYmxlID0gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgYnkgdGhlIGJ1aWxkIGNvZGUgcGF0aCB0byBjcmVhdGUgYSBjb3B5IG9mIHRoZSBleHRlbnNpb25zIGZvcgorICAgICAqIGJ1aWxkaW5nIHRoZSBtZXNzYWdlLgorICAgICAqIDxwPgorICAgICAqIEZvciB1c2UgYnkgZ2VuZXJhdGVkIGNvZGUgb25seS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgRmllbGRTZXQ8RXh0ZW5zaW9uRGVzY3JpcHRvcj4gYnVpbGRFeHRlbnNpb25zKCkgeworICAgICAgZXh0ZW5zaW9ucy5tYWtlSW1tdXRhYmxlKCk7CisgICAgICBleHRlbnNpb25zSXNNdXRhYmxlID0gZmFsc2U7CisgICAgICByZXR1cm4gZXh0ZW5zaW9uczsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoCisgICAgICAgIGZpbmFsIEdlbmVyYXRlZEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgPz4gZXh0ZW5zaW9uKSB7CisgICAgICBpZiAoZXh0ZW5zaW9uLmdldENvbnRhaW5pbmdUeXBlRGVmYXVsdEluc3RhbmNlKCkgIT0KKyAgICAgICAgICBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkpIHsKKyAgICAgICAgLy8gVGhpcyBjYW4gb25seSBoYXBwZW4gaWYgc29tZW9uZSB1c2VzIHVuY2hlY2tlZCBvcGVyYXRpb25zLgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJUaGlzIGV4dGVuc2lvbiBpcyBmb3IgYSBkaWZmZXJlbnQgbWVzc2FnZSB0eXBlLiAgUGxlYXNlIG1ha2UgIiArCisgICAgICAgICAgInN1cmUgdGhhdCB5b3UgYXJlIG5vdCBzdXBwcmVzc2luZyBhbnkgZ2VuZXJpY3MgdHlwZSB3YXJuaW5ncy4iKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogQ2hlY2sgaWYgYSBzaW5ndWxhciBleHRlbnNpb24gaXMgcHJlc2VudC4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IGJvb2xlYW4gaGFzRXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb24pIHsKKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uTGl0ZSA9CisgICAgICAgICAgY2hlY2tJc0xpdGUoZXh0ZW5zaW9uKTsKKyAgICAgIAorICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uTGl0ZSk7CisgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5oYXNGaWVsZChleHRlbnNpb25MaXRlLmRlc2NyaXB0b3IpOworICAgIH0KKworICAgIC8qKiBHZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IGludCBnZXRFeHRlbnNpb25Db3VudCgKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uKSB7CisgICAgICBHZW5lcmF0ZWRFeHRlbnNpb248TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbkxpdGUgPQorICAgICAgICAgIGNoZWNrSXNMaXRlKGV4dGVuc2lvbik7CisgICAgICAKKyAgICAgIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKGV4dGVuc2lvbkxpdGUpOworICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGV4dGVuc2lvbkxpdGUuZGVzY3JpcHRvcik7CisgICAgfQorCisgICAgLyoqIEdldCB0aGUgdmFsdWUgb2YgYW4gZXh0ZW5zaW9uLiAqLworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gVHlwZSBnZXRFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIFR5cGU+IGV4dGVuc2lvbikgeworICAgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb25MaXRlID0KKyAgICAgICAgICBjaGVja0lzTGl0ZShleHRlbnNpb24pOworICAgICAgCisgICAgICB2ZXJpZnlFeHRlbnNpb25Db250YWluaW5nVHlwZShleHRlbnNpb25MaXRlKTsKKyAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGV4dGVuc2lvbnMuZ2V0RmllbGQoZXh0ZW5zaW9uTGl0ZS5kZXNjcmlwdG9yKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBleHRlbnNpb25MaXRlLmRlZmF1bHRWYWx1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAoVHlwZSkgZXh0ZW5zaW9uTGl0ZS5mcm9tRmllbGRTZXRUeXBlKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogR2V0IG9uZSBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgZXh0ZW5zaW9uLiAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gVHlwZSBnZXRFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKKyAgICAgICAgZmluYWwgaW50IGluZGV4KSB7CisgICAgICBHZW5lcmF0ZWRFeHRlbnNpb248TWVzc2FnZVR5cGUsIExpc3Q8VHlwZT4+IGV4dGVuc2lvbkxpdGUgPQorICAgICAgICAgIGNoZWNrSXNMaXRlKGV4dGVuc2lvbik7CisgICAgICAKKyAgICAgIHZlcmlmeUV4dGVuc2lvbkNvbnRhaW5pbmdUeXBlKGV4dGVuc2lvbkxpdGUpOworICAgICAgcmV0dXJuIChUeXBlKSBleHRlbnNpb25MaXRlLnNpbmd1bGFyRnJvbUZpZWxkU2V0VHlwZSgKKyAgICAgICAgICBleHRlbnNpb25zLmdldFJlcGVhdGVkRmllbGQoZXh0ZW5zaW9uTGl0ZS5kZXNjcmlwdG9yLCBpbmRleCkpOworICAgIH0KKworICAgIC8vIFRoaXMgaXMgaW1wbGVtZW50ZWQgaGVyZSBvbmx5IHRvIHdvcmsgYXJvdW5kIGFuIGFwcGFyZW50IGJ1ZyBpbiB0aGUKKyAgICAvLyBKYXZhIGNvbXBpbGVyIGFuZC9vciBidWlsZCBzeXN0ZW0uICBTZWUgYnVnICMxODk4NDYzLiAgVGhlIG1lcmUgcHJlc2VuY2UKKyAgICAvLyBvZiB0aGlzIGR1bW15IGNsb25lKCkgaW1wbGVtZW50YXRpb24gbWFrZXMgaXQgZ28gYXdheS4KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgY2xvbmUoKSB7CisgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICB9CisgICAgCisgICAgLyoqIFNldCB0aGUgdmFsdWUgb2YgYW4gZXh0ZW5zaW9uLiAqLworICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gQnVpbGRlclR5cGUgc2V0RXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBUeXBlPiBleHRlbnNpb24sCisgICAgICAgIGZpbmFsIFR5cGUgdmFsdWUpIHsKKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgVHlwZT4gZXh0ZW5zaW9uTGl0ZSA9CisgICAgICAgICAgY2hlY2tJc0xpdGUoZXh0ZW5zaW9uKTsKKyAgICAgIAorICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uTGl0ZSk7CisgICAgICBlbnN1cmVFeHRlbnNpb25zSXNNdXRhYmxlKCk7CisgICAgICBleHRlbnNpb25zLnNldEZpZWxkKGV4dGVuc2lvbkxpdGUuZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uTGl0ZS50b0ZpZWxkU2V0VHlwZSh2YWx1ZSkpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0IHRoZSB2YWx1ZSBvZiBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4gKi8KKyAgICBwdWJsaWMgZmluYWwgPFR5cGU+IEJ1aWxkZXJUeXBlIHNldEV4dGVuc2lvbigKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAorICAgICAgICBmaW5hbCBpbnQgaW5kZXgsIGZpbmFsIFR5cGUgdmFsdWUpIHsKKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uTGl0ZSA9CisgICAgICAgICAgY2hlY2tJc0xpdGUoZXh0ZW5zaW9uKTsKKyAgICAgIAorICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uTGl0ZSk7CisgICAgICBlbnN1cmVFeHRlbnNpb25zSXNNdXRhYmxlKCk7CisgICAgICBleHRlbnNpb25zLnNldFJlcGVhdGVkRmllbGQoZXh0ZW5zaW9uTGl0ZS5kZXNjcmlwdG9yLCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25MaXRlLnNpbmd1bGFyVG9GaWVsZFNldFR5cGUodmFsdWUpKTsKKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorCisgICAgLyoqIEFwcGVuZCBhIHZhbHVlIHRvIGEgcmVwZWF0ZWQgZXh0ZW5zaW9uLiAqLworICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gQnVpbGRlclR5cGUgYWRkRXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBFeHRlbnNpb25MaXRlPE1lc3NhZ2VUeXBlLCBMaXN0PFR5cGU+PiBleHRlbnNpb24sCisgICAgICAgIGZpbmFsIFR5cGUgdmFsdWUpIHsKKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxNZXNzYWdlVHlwZSwgTGlzdDxUeXBlPj4gZXh0ZW5zaW9uTGl0ZSA9CisgICAgICAgICAgY2hlY2tJc0xpdGUoZXh0ZW5zaW9uKTsKKyAgICAgIAorICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uTGl0ZSk7CisgICAgICBlbnN1cmVFeHRlbnNpb25zSXNNdXRhYmxlKCk7CisgICAgICBleHRlbnNpb25zLmFkZFJlcGVhdGVkRmllbGQoZXh0ZW5zaW9uTGl0ZS5kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbkxpdGUuc2luZ3VsYXJUb0ZpZWxkU2V0VHlwZSh2YWx1ZSkpOworICAgICAgcmV0dXJuIChCdWlsZGVyVHlwZSkgdGhpczsKKyAgICB9CisKKyAgICAvKiogQ2xlYXIgYW4gZXh0ZW5zaW9uLiAqLworICAgIHB1YmxpYyBmaW5hbCA8VHlwZT4gQnVpbGRlclR5cGUgY2xlYXJFeHRlbnNpb24oCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkxpdGU8TWVzc2FnZVR5cGUsID8+IGV4dGVuc2lvbikgeworICAgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCA/PiBleHRlbnNpb25MaXRlID0gY2hlY2tJc0xpdGUoZXh0ZW5zaW9uKTsKKyAgICAgIAorICAgICAgdmVyaWZ5RXh0ZW5zaW9uQ29udGFpbmluZ1R5cGUoZXh0ZW5zaW9uTGl0ZSk7CisgICAgICBlbnN1cmVFeHRlbnNpb25zSXNNdXRhYmxlKCk7CisgICAgICBleHRlbnNpb25zLmNsZWFyRmllbGQoZXh0ZW5zaW9uTGl0ZS5kZXNjcmlwdG9yKTsKKyAgICAgIHJldHVybiAoQnVpbGRlclR5cGUpIHRoaXM7CisgICAgfQorCisgICAgLyoqIENhbGxlZCBieSBzdWJjbGFzc2VzIHRvIGNoZWNrIGlmIGFsbCBleHRlbnNpb25zIGFyZSBpbml0aWFsaXplZC4gKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSB7CisgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5pc0luaXRpYWxpemVkKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgbWVyZ2VFeHRlbnNpb25GaWVsZHMoZmluYWwgTWVzc2FnZVR5cGUgb3RoZXIpIHsKKyAgICAgIGVuc3VyZUV4dGVuc2lvbnNJc011dGFibGUoKTsKKyAgICAgIGV4dGVuc2lvbnMubWVyZ2VGcm9tKCgoRXh0ZW5kYWJsZU1lc3NhZ2UpIG90aGVyKS5leHRlbnNpb25zKTsKKyAgICB9CisgIH0KKworICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIFBhcnNlIGFuIHVua25vd24gZmllbGQgb3IgYW4gZXh0ZW5zaW9uLiBGb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IHVubGVzcyB0aGUgdGFnIGlzIGFuIGVuZC1ncm91cCB0YWcuCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIDxNZXNzYWdlVHlwZSBleHRlbmRzIE1lc3NhZ2VMaXRlPgorICAgICAgYm9vbGVhbiBwYXJzZVVua25vd25GaWVsZCgKKyAgICAgICAgICBGaWVsZFNldDxFeHRlbnNpb25EZXNjcmlwdG9yPiBleHRlbnNpb25zLAorICAgICAgICAgIE1lc3NhZ2VUeXBlIGRlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgIFVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciB1bmtub3duRmllbGRzLAorICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgICAgICBpbnQgdGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCB3aXJlVHlwZSA9IFdpcmVGb3JtYXQuZ2V0VGFnV2lyZVR5cGUodGFnKTsKKyAgICBpbnQgZmllbGROdW1iZXIgPSBXaXJlRm9ybWF0LmdldFRhZ0ZpZWxkTnVtYmVyKHRhZyk7CisKKyAgICBHZW5lcmF0ZWRFeHRlbnNpb248TWVzc2FnZVR5cGUsID8+IGV4dGVuc2lvbiA9CisgICAgICBleHRlbnNpb25SZWdpc3RyeS5maW5kTGl0ZUV4dGVuc2lvbkJ5TnVtYmVyKAorICAgICAgICAgIGRlZmF1bHRJbnN0YW5jZSwgZmllbGROdW1iZXIpOworCisgICAgYm9vbGVhbiB1bmtub3duID0gZmFsc2U7CisgICAgYm9vbGVhbiBwYWNrZWQgPSBmYWxzZTsKKyAgICBpZiAoZXh0ZW5zaW9uID09IG51bGwpIHsKKyAgICAgIHVua25vd24gPSB0cnVlOyAgLy8gVW5rbm93biBmaWVsZC4KKyAgICB9IGVsc2UgaWYgKHdpcmVUeXBlID09IEZpZWxkU2V0LmdldFdpcmVGb3JtYXRGb3JGaWVsZFR5cGUoCisgICAgICAgICAgICAgICAgIGV4dGVuc2lvbi5kZXNjcmlwdG9yLmdldExpdGVUeXBlKCksCisgICAgICAgICAgICAgICAgIGZhbHNlICAvKiBpc1BhY2tlZCAqLykpIHsKKyAgICAgIHBhY2tlZCA9IGZhbHNlOyAgLy8gTm9ybWFsLCB1bnBhY2tlZCB2YWx1ZS4KKyAgICB9IGVsc2UgaWYgKGV4dGVuc2lvbi5kZXNjcmlwdG9yLmlzUmVwZWF0ZWQgJiYKKyAgICAgICAgICAgICAgIGV4dGVuc2lvbi5kZXNjcmlwdG9yLnR5cGUuaXNQYWNrYWJsZSgpICYmCisgICAgICAgICAgICAgICB3aXJlVHlwZSA9PSBGaWVsZFNldC5nZXRXaXJlRm9ybWF0Rm9yRmllbGRUeXBlKAorICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpLAorICAgICAgICAgICAgICAgICB0cnVlICAvKiBpc1BhY2tlZCAqLykpIHsKKyAgICAgIHBhY2tlZCA9IHRydWU7ICAvLyBQYWNrZWQgdmFsdWUuCisgICAgfSBlbHNlIHsKKyAgICAgIHVua25vd24gPSB0cnVlOyAgLy8gV3Jvbmcgd2lyZSB0eXBlLgorICAgIH0KKworICAgIGlmICh1bmtub3duKSB7ICAvLyBVbmtub3duIGZpZWxkIG9yIHdyb25nIHdpcmUgdHlwZS4gIFNraXAuCisgICAgICByZXR1cm4gdW5rbm93bkZpZWxkcy5tZXJnZUZpZWxkRnJvbSh0YWcsIGlucHV0KTsKKyAgICB9CisKKyAgICBpZiAocGFja2VkKSB7CisgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CisgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKKyAgICAgIGlmIChleHRlbnNpb24uZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpID09IFdpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0pIHsKKyAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeworICAgICAgICAgIGludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7CisgICAgICAgICAgT2JqZWN0IHZhbHVlID0KKyAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IuZ2V0RW51bVR5cGUoKS5maW5kVmFsdWVCeU51bWJlcihyYXdWYWx1ZSk7CisgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIElmIHRoZSBudW1iZXIgaXNuJ3QgcmVjb2duaXplZCBhcyBhIHZhbGlkIHZhbHVlIGZvciB0aGlzCisgICAgICAgICAgICAvLyBlbnVtLCBkcm9wIGl0IChkb24ndCBldmVuIGFkZCBpdCB0byB1bmtub3duRmllbGRzKS4KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgICBleHRlbnNpb25zLmFkZFJlcGVhdGVkRmllbGQoZXh0ZW5zaW9uLmRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbi5zaW5ndWxhclRvRmllbGRTZXRUeXBlKHZhbHVlKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKKyAgICAgICAgICBPYmplY3QgdmFsdWUgPQorICAgICAgICAgICAgICBGaWVsZFNldC5yZWFkUHJpbWl0aXZlRmllbGQoaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypjaGVja1V0Zjg9Ki8gZmFsc2UpOworICAgICAgICAgIGV4dGVuc2lvbnMuYWRkUmVwZWF0ZWRGaWVsZChleHRlbnNpb24uZGVzY3JpcHRvciwgdmFsdWUpOworICAgICAgICB9CisgICAgICB9CisgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CisgICAgfSBlbHNlIHsKKyAgICAgIE9iamVjdCB2YWx1ZTsKKyAgICAgIHN3aXRjaCAoZXh0ZW5zaW9uLmRlc2NyaXB0b3IuZ2V0TGl0ZUphdmFUeXBlKCkpIHsKKyAgICAgICAgY2FzZSBNRVNTQUdFOiB7CisgICAgICAgICAgTWVzc2FnZUxpdGUuQnVpbGRlciBzdWJCdWlsZGVyID0gbnVsbDsKKyAgICAgICAgICBpZiAoIWV4dGVuc2lvbi5kZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgTWVzc2FnZUxpdGUgZXhpc3RpbmdWYWx1ZSA9CisgICAgICAgICAgICAgICAgKE1lc3NhZ2VMaXRlKSBleHRlbnNpb25zLmdldEZpZWxkKGV4dGVuc2lvbi5kZXNjcmlwdG9yKTsKKyAgICAgICAgICAgIGlmIChleGlzdGluZ1ZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgc3ViQnVpbGRlciA9IGV4aXN0aW5nVmFsdWUudG9CdWlsZGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChzdWJCdWlsZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHN1YkJ1aWxkZXIgPSBleHRlbnNpb24uZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpCisgICAgICAgICAgICAgICAgLm5ld0J1aWxkZXJGb3JUeXBlKCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChleHRlbnNpb24uZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpID09CisgICAgICAgICAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlLkdST1VQKSB7CisgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoZXh0ZW5zaW9uLmdldE51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YkJ1aWxkZXIsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2Uoc3ViQnVpbGRlciwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgICAgIH0KKyAgICAgICAgICB2YWx1ZSA9IHN1YkJ1aWxkZXIuYnVpbGQoKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBjYXNlIEVOVU06CisgICAgICAgICAgaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTsKKyAgICAgICAgICB2YWx1ZSA9IGV4dGVuc2lvbi5kZXNjcmlwdG9yLmdldEVudW1UeXBlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kVmFsdWVCeU51bWJlcihyYXdWYWx1ZSk7CisgICAgICAgICAgLy8gSWYgdGhlIG51bWJlciBpc24ndCByZWNvZ25pemVkIGFzIGEgdmFsaWQgdmFsdWUgZm9yIHRoaXMgZW51bSwKKyAgICAgICAgICAvLyB3cml0ZSBpdCB0byB1bmtub3duIGZpZWxkcyBvYmplY3QuCisgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHVua25vd25GaWVsZHMubWVyZ2VWYXJpbnRGaWVsZChmaWVsZE51bWJlciwgcmF3VmFsdWUpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHZhbHVlID0gRmllbGRTZXQucmVhZFByaW1pdGl2ZUZpZWxkKGlucHV0LAorICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpLAorICAgICAgICAgICAgICAvKmNoZWNrVXRmOD0qLyBmYWxzZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGlmIChleHRlbnNpb24uZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgZXh0ZW5zaW9ucy5hZGRSZXBlYXRlZEZpZWxkKGV4dGVuc2lvbi5kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLnNpbmd1bGFyVG9GaWVsZFNldFR5cGUodmFsdWUpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGV4dGVuc2lvbnMuc2V0RmllbGQoZXh0ZW5zaW9uLmRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLnNpbmd1bGFyVG9GaWVsZFNldFR5cGUodmFsdWUpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqIEZvciB1c2UgYnkgZ2VuZXJhdGVkIGNvZGUgb25seS4gKi8KKyAgcHVibGljIHN0YXRpYyA8Q29udGFpbmluZ1R5cGUgZXh0ZW5kcyBNZXNzYWdlTGl0ZSwgVHlwZT4KKyAgICAgIEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4KKyAgICAgICAgICBuZXdTaW5ndWxhckdlbmVyYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgICAgZmluYWwgQ29udGFpbmluZ1R5cGUgY29udGFpbmluZ1R5cGVEZWZhdWx0SW5zdGFuY2UsCisgICAgICAgICAgICAgIGZpbmFsIFR5cGUgZGVmYXVsdFZhbHVlLAorICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlTGl0ZSBtZXNzYWdlRGVmYXVsdEluc3RhbmNlLAorICAgICAgICAgICAgICBmaW5hbCBJbnRlcm5hbC5FbnVtTGl0ZU1hcDw/PiBlbnVtVHlwZU1hcCwKKyAgICAgICAgICAgICAgZmluYWwgaW50IG51bWJlciwKKyAgICAgICAgICAgICAgZmluYWwgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgZmluYWwgQ2xhc3Mgc2luZ3VsYXJUeXBlKSB7CisgICAgcmV0dXJuIG5ldyBHZW5lcmF0ZWRFeHRlbnNpb248Q29udGFpbmluZ1R5cGUsIFR5cGU+KAorICAgICAgICBjb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgZGVmYXVsdFZhbHVlLAorICAgICAgICBtZXNzYWdlRGVmYXVsdEluc3RhbmNlLAorICAgICAgICBuZXcgRXh0ZW5zaW9uRGVzY3JpcHRvcihlbnVtVHlwZU1hcCwgbnVtYmVyLCB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSAvKiBpc1JlcGVhdGVkICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSAvKiBpc1BhY2tlZCAqLyksCisgICAgICAgIHNpbmd1bGFyVHlwZSk7CisgIH0KKworICAvKiogRm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LiAqLworICBwdWJsaWMgc3RhdGljIDxDb250YWluaW5nVHlwZSBleHRlbmRzIE1lc3NhZ2VMaXRlLCBUeXBlPgorICAgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPENvbnRhaW5pbmdUeXBlLCBUeXBlPgorICAgICAgICAgIG5ld1JlcGVhdGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgICAgICBmaW5hbCBDb250YWluaW5nVHlwZSBjb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgICAgICAgZmluYWwgTWVzc2FnZUxpdGUgbWVzc2FnZURlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgICAgICAgZmluYWwgSW50ZXJuYWwuRW51bUxpdGVNYXA8Pz4gZW51bVR5cGVNYXAsCisgICAgICAgICAgICAgIGZpbmFsIGludCBudW1iZXIsCisgICAgICAgICAgICAgIGZpbmFsIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQYWNrZWQsCisgICAgICAgICAgICAgIGZpbmFsIENsYXNzIHNpbmd1bGFyVHlwZSkgeworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAgLy8gU3ViY2xhc3NlcyBlbnN1cmUgVHlwZSBpcyBhIExpc3QKKyAgICBUeXBlIGVtcHR5TGlzdCA9IChUeXBlKSBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKKyAgICByZXR1cm4gbmV3IEdlbmVyYXRlZEV4dGVuc2lvbjxDb250YWluaW5nVHlwZSwgVHlwZT4oCisgICAgICAgIGNvbnRhaW5pbmdUeXBlRGVmYXVsdEluc3RhbmNlLAorICAgICAgICBlbXB0eUxpc3QsCisgICAgICAgIG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UsCisgICAgICAgIG5ldyBFeHRlbnNpb25EZXNjcmlwdG9yKAorICAgICAgICAgICAgZW51bVR5cGVNYXAsIG51bWJlciwgdHlwZSwgdHJ1ZSAvKiBpc1JlcGVhdGVkICovLCBpc1BhY2tlZCksCisgICAgICAgIHNpbmd1bGFyVHlwZSk7CisgIH0KKworICBzdGF0aWMgZmluYWwgY2xhc3MgRXh0ZW5zaW9uRGVzY3JpcHRvcgorICAgICAgaW1wbGVtZW50cyBGaWVsZFNldC5GaWVsZERlc2NyaXB0b3JMaXRlPAorICAgICAgICBFeHRlbnNpb25EZXNjcmlwdG9yPiB7CisgICAgRXh0ZW5zaW9uRGVzY3JpcHRvcigKKyAgICAgICAgZmluYWwgSW50ZXJuYWwuRW51bUxpdGVNYXA8Pz4gZW51bVR5cGVNYXAsCisgICAgICAgIGZpbmFsIGludCBudW1iZXIsCisgICAgICAgIGZpbmFsIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGUsCisgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNSZXBlYXRlZCwKKyAgICAgICAgZmluYWwgYm9vbGVhbiBpc1BhY2tlZCkgeworICAgICAgdGhpcy5lbnVtVHlwZU1hcCA9IGVudW1UeXBlTWFwOworICAgICAgdGhpcy5udW1iZXIgPSBudW1iZXI7CisgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgdGhpcy5pc1JlcGVhdGVkID0gaXNSZXBlYXRlZDsKKyAgICAgIHRoaXMuaXNQYWNrZWQgPSBpc1BhY2tlZDsKKyAgICB9CisKKyAgICBmaW5hbCBJbnRlcm5hbC5FbnVtTGl0ZU1hcDw/PiBlbnVtVHlwZU1hcDsKKyAgICBmaW5hbCBpbnQgbnVtYmVyOworICAgIGZpbmFsIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGU7CisgICAgZmluYWwgYm9vbGVhbiBpc1JlcGVhdGVkOworICAgIGZpbmFsIGJvb2xlYW4gaXNQYWNrZWQ7CisKKyAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKKyAgICAgIHJldHVybiBudW1iZXI7CisgICAgfQorCisgICAgcHVibGljIFdpcmVGb3JtYXQuRmllbGRUeXBlIGdldExpdGVUeXBlKCkgeworICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgcHVibGljIFdpcmVGb3JtYXQuSmF2YVR5cGUgZ2V0TGl0ZUphdmFUeXBlKCkgeworICAgICAgcmV0dXJuIHR5cGUuZ2V0SmF2YVR5cGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlcGVhdGVkKCkgeworICAgICAgcmV0dXJuIGlzUmVwZWF0ZWQ7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNQYWNrZWQoKSB7CisgICAgICByZXR1cm4gaXNQYWNrZWQ7CisgICAgfQorCisgICAgcHVibGljIEludGVybmFsLkVudW1MaXRlTWFwPD8+IGdldEVudW1UeXBlKCkgeworICAgICAgcmV0dXJuIGVudW1UeXBlTWFwOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBNZXNzYWdlTGl0ZS5CdWlsZGVyIGludGVybmFsTWVyZ2VGcm9tKAorICAgICAgICBNZXNzYWdlTGl0ZS5CdWlsZGVyIHRvLCBNZXNzYWdlTGl0ZSBmcm9tKSB7CisgICAgICByZXR1cm4gKChCdWlsZGVyKSB0bykubWVyZ2VGcm9tKChHZW5lcmF0ZWRNZXNzYWdlTGl0ZSkgZnJvbSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhFeHRlbnNpb25EZXNjcmlwdG9yIG90aGVyKSB7CisgICAgICByZXR1cm4gbnVtYmVyIC0gb3RoZXIubnVtYmVyOworICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqIENhbGxzIENsYXNzLmdldE1ldGhvZCBhbmQgdGhyb3dzIGEgUnVudGltZUV4Y2VwdGlvbiBpZiBpdCBmYWlscy4gKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHN0YXRpYyBNZXRob2QgZ2V0TWV0aG9kT3JEaWUoQ2xhc3MgY2xhenosIFN0cmluZyBuYW1lLCBDbGFzcy4uLiBwYXJhbXMpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIGNsYXp6LmdldE1ldGhvZChuYW1lLCBwYXJhbXMpOworICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgIkdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzIFwiIiArIGNsYXp6LmdldE5hbWUoKSArCisgICAgICAgICJcIiBtaXNzaW5nIG1ldGhvZCBcIiIgKyBuYW1lICsgIlwiLiIsIGUpOworICAgIH0KKyAgfQorCisgIC8qKiBDYWxscyBpbnZva2UgYW5kIHRocm93cyBhIFJ1bnRpbWVFeGNlcHRpb24gaWYgaXQgZmFpbHMuICovCisgIHN0YXRpYyBPYmplY3QgaW52b2tlT3JEaWUoTWV0aG9kIG1ldGhvZCwgT2JqZWN0IG9iamVjdCwgT2JqZWN0Li4uIHBhcmFtcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gbWV0aG9kLmludm9rZShvYmplY3QsIHBhcmFtcyk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgIkNvdWxkbid0IHVzZSBKYXZhIHJlZmxlY3Rpb24gdG8gaW1wbGVtZW50IHByb3RvY29sIG1lc3NhZ2UgIiArCisgICAgICAgICJyZWZsZWN0aW9uLiIsIGUpOworICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkgeworICAgICAgZmluYWwgVGhyb3dhYmxlIGNhdXNlID0gZS5nZXRDYXVzZSgpOworICAgICAgaWYgKGNhdXNlIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgY2F1c2U7CisgICAgICB9IGVsc2UgaWYgKGNhdXNlIGluc3RhbmNlb2YgRXJyb3IpIHsKKyAgICAgICAgdGhyb3cgKEVycm9yKSBjYXVzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB0aHJvd24gYnkgZ2VuZXJhdGVkIGFjY2Vzc29yIG1ldGhvZC4iLCBjYXVzZSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIExpdGUgZXF1aXZhbGVudCB0byB7QGxpbmsgR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb259LgorICAgKgorICAgKiBVc2VycyBzaG91bGQgaWdub3JlIHRoZSBjb250ZW50cyBvZiB0aGlzIGNsYXNzIGFuZCBvbmx5IHVzZSBvYmplY3RzIG9mCisgICAqIHRoaXMgdHlwZSBhcyBwYXJhbWV0ZXJzIHRvIGV4dGVuc2lvbiBhY2Nlc3NvcnMgYW5kIEV4dGVuc2lvblJlZ2lzdHJ5LmFkZCgpLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBHZW5lcmF0ZWRFeHRlbnNpb248CisgICAgICBDb250YWluaW5nVHlwZSBleHRlbmRzIE1lc3NhZ2VMaXRlLCBUeXBlPgorICAgICAgICAgIGV4dGVuZHMgRXh0ZW5zaW9uTGl0ZTxDb250YWluaW5nVHlwZSwgVHlwZT4geworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGlzbnRhbmNlIHdpdGggdGhlIGdpdmVuIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBUaGUgbGFzdCBwYXJhbWV0ZXIge0Bjb2RlIHNpbmd1bGFyVHlwZX0gaXMgb25seSBuZWVkZWQgZm9yIGVudW0gdHlwZXMuCisgICAgICogV2Ugc3RvcmUgaW50ZWdlciB2YWx1ZXMgZm9yIGVudW0gdHlwZXMgaW4gYSB7QGxpbmsgRXh0ZW5kYWJsZU1lc3NhZ2V9CisgICAgICogYW5kIHVzZSBKYXZhIHJlZmxlY3Rpb24gdG8gY29udmVydCBhbiBpbnRlZ2VyIHZhbHVlIGJhY2sgaW50byBhIGNvbmNyZXRlCisgICAgICogZW51bSBvYmplY3QuCisgICAgICovCisgICAgR2VuZXJhdGVkRXh0ZW5zaW9uKAorICAgICAgICBmaW5hbCBDb250YWluaW5nVHlwZSBjb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZSwKKyAgICAgICAgZmluYWwgVHlwZSBkZWZhdWx0VmFsdWUsCisgICAgICAgIGZpbmFsIE1lc3NhZ2VMaXRlIG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvbkRlc2NyaXB0b3IgZGVzY3JpcHRvciwKKyAgICAgICAgQ2xhc3Mgc2luZ3VsYXJUeXBlKSB7CisgICAgICAvLyBEZWZlbnNpdmUgY2hlY2tzIHRvIHZlcmlmeSB0aGUgY29ycmVjdCBpbml0aWFsaXphdGlvbiBvcmRlciBvZgorICAgICAgLy8gR2VuZXJhdGVkRXh0ZW5zaW9ucyBhbmQgdGhlaXIgcmVsYXRlZCBHZW5lcmF0ZWRNZXNzYWdlcy4KKyAgICAgIGlmIChjb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZSA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAiTnVsbCBjb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZSIpOworICAgICAgfQorICAgICAgaWYgKGRlc2NyaXB0b3IuZ2V0TGl0ZVR5cGUoKSA9PSBXaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFICYmCisgICAgICAgICAgbWVzc2FnZURlZmF1bHRJbnN0YW5jZSA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAiTnVsbCBtZXNzYWdlRGVmYXVsdEluc3RhbmNlIik7CisgICAgICB9CisgICAgICB0aGlzLmNvbnRhaW5pbmdUeXBlRGVmYXVsdEluc3RhbmNlID0gY29udGFpbmluZ1R5cGVEZWZhdWx0SW5zdGFuY2U7CisgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTsKKyAgICAgIHRoaXMubWVzc2FnZURlZmF1bHRJbnN0YW5jZSA9IG1lc3NhZ2VEZWZhdWx0SW5zdGFuY2U7CisgICAgICB0aGlzLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yOworCisgICAgICAvLyBVc2UgSmF2YSByZWZsZWN0aW9uIHRvIGludm9rZSB0aGUgc3RhdGljIG1ldGhvZCB7QGNvZGUgdmFsdWVPZn0gb2YKKyAgICAgIC8vIGVudW0gdHlwZXMgaW4gb3JkZXIgdG8gY29udmVydCBpbnRlZ2VycyB0byBjb25jcmV0ZSBlbnVtIG9iamVjdHMuCisgICAgICB0aGlzLnNpbmd1bGFyVHlwZSA9IHNpbmd1bGFyVHlwZTsKKyAgICAgIGlmIChJbnRlcm5hbC5FbnVtTGl0ZS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKHNpbmd1bGFyVHlwZSkpIHsKKyAgICAgICAgdGhpcy5lbnVtVmFsdWVPZiA9IGdldE1ldGhvZE9yRGllKAorICAgICAgICAgICAgc2luZ3VsYXJUeXBlLCAidmFsdWVPZiIsIGludC5jbGFzcyk7CisgICAgICB9IGVsc2UgeworICAgICAgICB0aGlzLmVudW1WYWx1ZU9mID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBmaW5hbCBDb250YWluaW5nVHlwZSBjb250YWluaW5nVHlwZURlZmF1bHRJbnN0YW5jZTsKKyAgICBmaW5hbCBUeXBlIGRlZmF1bHRWYWx1ZTsKKyAgICBmaW5hbCBNZXNzYWdlTGl0ZSBtZXNzYWdlRGVmYXVsdEluc3RhbmNlOworICAgIGZpbmFsIEV4dGVuc2lvbkRlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBmaW5hbCBDbGFzcyBzaW5ndWxhclR5cGU7CisgICAgZmluYWwgTWV0aG9kIGVudW1WYWx1ZU9mOworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBpbnN0YW5jZSBvZiB0aGUgdHlwZSBiZWluZyBleHRlbmRlZCwgdXNlZCB0byBpZGVudGlmeSB0aGF0IHR5cGUuCisgICAgICovCisgICAgcHVibGljIENvbnRhaW5pbmdUeXBlIGdldENvbnRhaW5pbmdUeXBlRGVmYXVsdEluc3RhbmNlKCkgeworICAgICAgcmV0dXJuIGNvbnRhaW5pbmdUeXBlRGVmYXVsdEluc3RhbmNlOworICAgIH0KKworICAgIC8qKiBHZXQgdGhlIGZpZWxkIG51bWJlci4gKi8KKyAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKKyAgICAgIHJldHVybiBkZXNjcmlwdG9yLmdldE51bWJlcigpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogSWYgdGhlIGV4dGVuc2lvbiBpcyBhbiBlbWJlZGRlZCBtZXNzYWdlIG9yIGdyb3VwLCByZXR1cm5zIHRoZSBkZWZhdWx0CisgICAgICogaW5zdGFuY2Ugb2YgdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VMaXRlIGdldE1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgICByZXR1cm4gbWVzc2FnZURlZmF1bHRJbnN0YW5jZTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBPYmplY3QgZnJvbUZpZWxkU2V0VHlwZShmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGlmIChkZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICBpZiAoZGVzY3JpcHRvci5nZXRMaXRlSmF2YVR5cGUoKSA9PSBXaXJlRm9ybWF0LkphdmFUeXBlLkVOVU0pIHsKKyAgICAgICAgICBmaW5hbCBMaXN0IHJlc3VsdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgICBmb3IgKGZpbmFsIE9iamVjdCBlbGVtZW50IDogKExpc3QpIHZhbHVlKSB7CisgICAgICAgICAgICByZXN1bHQuYWRkKHNpbmd1bGFyRnJvbUZpZWxkU2V0VHlwZShlbGVtZW50KSk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gc2luZ3VsYXJGcm9tRmllbGRTZXRUeXBlKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBPYmplY3Qgc2luZ3VsYXJGcm9tRmllbGRTZXRUeXBlKGZpbmFsIE9iamVjdCB2YWx1ZSkgeworICAgICAgaWYgKGRlc2NyaXB0b3IuZ2V0TGl0ZUphdmFUeXBlKCkgPT0gV2lyZUZvcm1hdC5KYXZhVHlwZS5FTlVNKSB7CisgICAgICAgIHJldHVybiBpbnZva2VPckRpZShlbnVtVmFsdWVPZiwgbnVsbCwgKEludGVnZXIpIHZhbHVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBPYmplY3QgdG9GaWVsZFNldFR5cGUoZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBpZiAoZGVzY3JpcHRvci5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgaWYgKGRlc2NyaXB0b3IuZ2V0TGl0ZUphdmFUeXBlKCkgPT0gV2lyZUZvcm1hdC5KYXZhVHlwZS5FTlVNKSB7CisgICAgICAgICAgZmluYWwgTGlzdCByZXN1bHQgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgICAgZm9yIChmaW5hbCBPYmplY3QgZWxlbWVudCA6IChMaXN0KSB2YWx1ZSkgeworICAgICAgICAgICAgcmVzdWx0LmFkZChzaW5ndWxhclRvRmllbGRTZXRUeXBlKGVsZW1lbnQpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzaW5ndWxhclRvRmllbGRTZXRUeXBlKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBPYmplY3Qgc2luZ3VsYXJUb0ZpZWxkU2V0VHlwZShmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGlmIChkZXNjcmlwdG9yLmdldExpdGVKYXZhVHlwZSgpID09IFdpcmVGb3JtYXQuSmF2YVR5cGUuRU5VTSkgeworICAgICAgICByZXR1cm4gKChJbnRlcm5hbC5FbnVtTGl0ZSkgdmFsdWUpLmdldE51bWJlcigpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBGaWVsZFR5cGUgZ2V0TGl0ZVR5cGUoKSB7CisgICAgICByZXR1cm4gZGVzY3JpcHRvci5nZXRMaXRlVHlwZSgpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzUmVwZWF0ZWQoKSB7CisgICAgICByZXR1cm4gZGVzY3JpcHRvci5pc1JlcGVhdGVkOworICAgIH0KKworICAgIHB1YmxpYyBUeXBlIGdldERlZmF1bHRWYWx1ZSgpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEEgc2VyaWFsaXplZCAoc2VyaWFsaXphYmxlKSBmb3JtIG9mIHRoZSBnZW5lcmF0ZWQgbWVzc2FnZS4gIFN0b3JlcyB0aGUKKyAgICogbWVzc2FnZSBhcyBhIGNsYXNzIG5hbWUgYW5kIGEgYnl0ZSBhcnJheS4KKyAgICovCisgIHN0YXRpYyBmaW5hbCBjbGFzcyBTZXJpYWxpemVkRm9ybSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBtZXNzYWdlQ2xhc3NOYW1lOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGFzQnl0ZXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBzZXJpYWxpemVkIGZvcm0gYnkgY2FsbGluZyB7QGxpbmsgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZSN0b0J5dGVBcnJheX0uCisgICAgICogQHBhcmFtIHJlZ3VsYXJGb3JtIHRoZSBtZXNzYWdlIHRvIHNlcmlhbGl6ZQorICAgICAqLworICAgIFNlcmlhbGl6ZWRGb3JtKE1lc3NhZ2VMaXRlIHJlZ3VsYXJGb3JtKSB7CisgICAgICBtZXNzYWdlQ2xhc3NOYW1lID0gcmVndWxhckZvcm0uZ2V0Q2xhc3MoKS5nZXROYW1lKCk7CisgICAgICBhc0J5dGVzID0gcmVndWxhckZvcm0udG9CeXRlQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGVuIHJlYWQgZnJvbSBhbiBPYmplY3RJbnB1dFN0cmVhbSwgdGhpcyBtZXRob2QgY29udmVydHMgdGhpcyBvYmplY3QKKyAgICAgKiBiYWNrIHRvIHRoZSByZWd1bGFyIGZvcm0uICBQYXJ0IG9mIEphdmEncyBzZXJpYWxpemF0aW9uIG1hZ2ljLgorICAgICAqIEByZXR1cm4gYSBHZW5lcmF0ZWRNZXNzYWdlIG9mIHRoZSB0eXBlIHRoYXQgd2FzIHNlcmlhbGl6ZWQKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBDbGFzcyBtZXNzYWdlQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKG1lc3NhZ2VDbGFzc05hbWUpOworICAgICAgICBQYXJzZXI8Pz4gcGFyc2VyID0KKyAgICAgICAgICAgIChQYXJzZXI8Pz4pIG1lc3NhZ2VDbGFzcy5nZXRGaWVsZCgiUEFSU0VSIikuZ2V0KG51bGwpOworICAgICAgICByZXR1cm4gcGFyc2VyLnBhcnNlUGFydGlhbEZyb20oYXNCeXRlcyk7CisgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuYWJsZSB0byBmaW5kIHByb3RvIGJ1ZmZlciBjbGFzcyIsIGUpOworICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5hYmxlIHRvIGZpbmQgUEFSU0VSIiwgZSk7CisgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmFibGUgdG8gY2FsbCBQQVJTRVIiLCBlKTsKKyAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5hYmxlIHRvIGNhbGwgcGFyc2VGcm9tIG1ldGhvZCIsIGUpOworICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuYWJsZSB0byB1bmRlcnN0YW5kIHByb3RvIGJ1ZmZlciIsIGUpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZXBsYWNlcyB0aGlzIG9iamVjdCBpbiB0aGUgb3V0cHV0IHN0cmVhbSB3aXRoIGEgc2VyaWFsaXplZCBmb3JtLgorICAgKiBQYXJ0IG9mIEphdmEncyBzZXJpYWxpemF0aW9uIG1hZ2ljLiAgR2VuZXJhdGVkIHN1Yi1jbGFzc2VzIG11c3Qgb3ZlcnJpZGUKKyAgICogdGhpcyBtZXRob2QgYnkgY2FsbGluZyB7QGNvZGUgcmV0dXJuIHN1cGVyLndyaXRlUmVwbGFjZSgpO30KKyAgICogQHJldHVybiBhIFNlcmlhbGl6ZWRGb3JtIG9mIHRoaXMgbWVzc2FnZQorICAgKi8KKyAgcHJvdGVjdGVkIE9iamVjdCB3cml0ZVJlcGxhY2UoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3IFNlcmlhbGl6ZWRGb3JtKHRoaXMpOworICB9CisgIAorICAvKioKKyAgICogQ2hlY2tzIHRoYXQgdGhlIHtAbGluayBFeHRlbnNpb259IGlzIExpdGUgYW5kIHJldHVybnMgaXQgYXMgYQorICAgKiB7QGxpbmsgR2VuZXJhdGVkRXh0ZW5zaW9ufS4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIDwKKyAgICAgIE1lc3NhZ2VUeXBlIGV4dGVuZHMgRXh0ZW5kYWJsZU1lc3NhZ2U8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPiwKKyAgICAgIEJ1aWxkZXJUeXBlIGV4dGVuZHMgRXh0ZW5kYWJsZUJ1aWxkZXI8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPiwKKyAgICAgIFQ+CisgICAgR2VuZXJhdGVkRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBUPiBjaGVja0lzTGl0ZSgKKyAgICAgICAgRXh0ZW5zaW9uTGl0ZTxNZXNzYWdlVHlwZSwgVD4gZXh0ZW5zaW9uKSB7CisgICAgaWYgKCFleHRlbnNpb24uaXNMaXRlKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkV4cGVjdGVkIGEgbGl0ZSBleHRlbnNpb24uIik7CisgICAgfQorICAgIAorICAgIHJldHVybiAoR2VuZXJhdGVkRXh0ZW5zaW9uPE1lc3NhZ2VUeXBlLCBUPikgZXh0ZW5zaW9uOworICB9CisgIAorICAvKioKKyAgICogUmVwcmVzZW50cyB0aGUgc3RhdGUgbmVlZGVkIHRvIGltcGxlbWVudCAqRm9yVHlwZSBtZXRob2RzLiBHZW5lcmF0ZWQgY29kZQorICAgKiBtdXN0IHByb3ZpZGUgYSBzdGF0aWMgc2luZ2xldG9uIGluc3RhbmNlIGJ5IGFkZGluZyBpdCB3aXRoCisgICAqIHtAbGluayBHZW5lcmF0ZWRNZXNzYWdlTGl0ZSNvbkxvYWQoQ2xhc3MsIFByb3RvdHlwZUhvbGRlcil9IG9uIGNsYXNzIGxvYWQuCisgICAqIDx1bD4KKyAgICogPGxpPntAbGluayAjZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpfQorICAgKiA8bGk+e0BsaW5rICNnZXRQYXJzZXJGb3JUeXBlKCl9CisgICAqIDxsaT57QGxpbmsgI25ld0J1aWxkZXJGb3JUeXBlKCl9CisgICAqIDwvdWw+CisgICAqIFRoaXMgYWxsb3dzIHVzIHRvIHRyYWRlIHRocmVlIGdlbmVyYXRlZCBtZXRob2RzIGZvciBhIHN0YXRpYyBNYXAuCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGNsYXNzIFByb3RvdHlwZUhvbGRlcjwKKyAgICAgIE1lc3NhZ2VUeXBlIGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZUxpdGU8TWVzc2FnZVR5cGUsIEJ1aWxkZXJUeXBlPiwKKyAgICAgIEJ1aWxkZXJUeXBlIGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZUxpdGUuQnVpbGRlcjwKKyAgICAgICAgICBNZXNzYWdlVHlwZSwgQnVpbGRlclR5cGU+PiB7CisgICAgCisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlVHlwZSBkZWZhdWx0SW5zdGFuY2U7CisgICAgcHJpdmF0ZSBmaW5hbCBQYXJzZXI8TWVzc2FnZVR5cGU+IHBhcnNlcjsKKyAgICAKKyAgICBwdWJsaWMgUHJvdG90eXBlSG9sZGVyKAorICAgICAgICBNZXNzYWdlVHlwZSBkZWZhdWx0SW5zdGFuY2UsIFBhcnNlcjxNZXNzYWdlVHlwZT4gcGFyc2VyKSB7CisgICAgICB0aGlzLmRlZmF1bHRJbnN0YW5jZSA9IGRlZmF1bHRJbnN0YW5jZTsKKyAgICAgIHRoaXMucGFyc2VyID0gcGFyc2VyOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgTWVzc2FnZVR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0SW5zdGFuY2U7CisgICAgfQorCisgICAgcHVibGljIFBhcnNlcjxNZXNzYWdlVHlwZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKKyAgICAgIHJldHVybiBwYXJzZXI7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIEd1YXJhbnRlZWQgYnkgcnVudGltZS4KKyAgICBwdWJsaWMgQnVpbGRlclR5cGUgbmV3QnVpbGRlckZvclR5cGUoKSB7CisgICAgICByZXR1cm4gKEJ1aWxkZXJUeXBlKSBkZWZhdWx0SW5zdGFuY2UudG9CdWlsZGVyKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9JbnRlcm5hbC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvSW50ZXJuYWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTBkZTZkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvSW50ZXJuYWwuamF2YQpAQCAtMCwwICsxLDU2MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RNYXA7CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0U2V0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBUaGUgY2xhc3NlcyBjb250YWluZWQgd2l0aGluIGFyZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIFByb3RvY29sIEJ1ZmZlcgorICogbGlicmFyeSBhbmQgZ2VuZXJhdGVkIG1lc3NhZ2UgaW1wbGVtZW50YXRpb25zLiBUaGV5IGFyZSBwdWJsaWMgb25seSBiZWNhdXNlCisgKiB0aG9zZSBnZW5lcmF0ZWQgbWVzc2FnZXMgZG8gbm90IHJlc2lkZSBpbiB0aGUge0Bjb2RlIHByb3RvYnVmfSBwYWNrYWdlLgorICogT3RoZXJzIHNob3VsZCBub3QgdXNlIHRoaXMgY2xhc3MgZGlyZWN0bHkuCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorICovCitwdWJsaWMgY2xhc3MgSW50ZXJuYWwgeworICAvKioKKyAgICogSGVscGVyIGNhbGxlZCBieSBnZW5lcmF0ZWQgY29kZSB0byBjb25zdHJ1Y3QgZGVmYXVsdCB2YWx1ZXMgZm9yIHN0cmluZworICAgKiBmaWVsZHMuCisgICAqIDxwPgorICAgKiBUaGUgcHJvdG9jb2wgY29tcGlsZXIgZG9lcyBub3QgYWN0dWFsbHkgY29udGFpbiBhIFVURi04IGRlY29kZXIgLS0gaXQKKyAgICoganVzdCBwdXNoZXMgVVRGLTgtZW5jb2RlZCB0ZXh0IGFyb3VuZCB3aXRob3V0IHRvdWNoaW5nIGl0LiAgVGhlIG9uZSBwbGFjZQorICAgKiB3aGVyZSB0aGlzIHByZXNlbnRzIGEgcHJvYmxlbSBpcyB3aGVuIGdlbmVyYXRpbmcgSmF2YSBzdHJpbmcgbGl0ZXJhbHMuCisgICAqIFVuaWNvZGUgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIGxpdGVyYWwgd291bGQgbm9ybWFsbHkgbmVlZCB0byBiZSBlbmNvZGVkCisgICAqIHVzaW5nIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UsIHdoaWNoIHdvdWxkIHJlcXVpcmUgZGVjb2RpbmcgdGhlbS4KKyAgICogVG8gZ2V0IGFyb3VuZCB0aGlzLCBwcm90b2MgaW5zdGVhZCBlbWJlZHMgdGhlIFVURi04IGJ5dGVzIGludG8gdGhlCisgICAqIGdlbmVyYXRlZCBjb2RlIGFuZCBsZWF2ZXMgaXQgdG8gdGhlIHJ1bnRpbWUgbGlicmFyeSB0byBkZWNvZGUgdGhlbS4KKyAgICogPHA+CisgICAqIEl0IGdldHMgd29yc2UsIHRob3VnaC4gIElmIHByb3RvYyBqdXN0IGdlbmVyYXRlZCBhIGJ5dGUgYXJyYXksIGxpa2U6CisgICAqICAgbmV3IGJ5dGVbXSB7MHgxMiwgMHgzNCwgMHg1NiwgMHg3OH0KKyAgICogSmF2YSBhY3R1YWxseSBnZW5lcmF0ZXMgKmNvZGUqIHdoaWNoIGFsbG9jYXRlcyBhbiBhcnJheSBhbmQgdGhlbiBmaWxscworICAgKiBpbiBlYWNoIHZhbHVlLiAgVGhpcyBpcyBtdWNoIGxlc3MgZWZmaWNpZW50IHRoYW4ganVzdCBlbWJlZGRpbmcgdGhlIGJ5dGVzCisgICAqIGRpcmVjdGx5IGludG8gdGhlIGJ5dGVjb2RlLiAgVG8gZ2V0IGFyb3VuZCB0aGlzLCB3ZSBuZWVkIGFub3RoZXIKKyAgICogd29yay1hcm91bmQuICBTdHJpbmcgbGl0ZXJhbHMgYXJlIGVtYmVkZGVkIGRpcmVjdGx5LCBzbyBwcm90b2MgYWN0dWFsbHkKKyAgICogZ2VuZXJhdGVzIGEgc3RyaW5nIGxpdGVyYWwgY29ycmVzcG9uZGluZyB0byB0aGUgYnl0ZXMuICBUaGUgZWFzaWVzdCB3YXkKKyAgICogdG8gZG8gdGhpcyBpcyB0byB1c2UgdGhlIElTTy04ODU5LTEgY2hhcmFjdGVyIHNldCwgd2hpY2ggY29ycmVzcG9uZHMgdG8KKyAgICogdGhlIGZpcnN0IDI1NiBjaGFyYWN0ZXJzIG9mIHRoZSBVbmljb2RlIHJhbmdlLiAgUHJvdG9jIGNhbiB0aGVuIHVzZQorICAgKiBnb29kIG9sZCBDRXNjYXBlIHRvIGdlbmVyYXRlIHRoZSBzdHJpbmcuCisgICAqIDxwPgorICAgKiBTbyB3ZSBoYXZlIGEgc3RyaW5nIGxpdGVyYWwgd2hpY2ggcmVwcmVzZW50cyBhIHNldCBvZiBieXRlcyB3aGljaAorICAgKiByZXByZXNlbnRzIGFub3RoZXIgc3RyaW5nLiAgVGhpcyBmdW5jdGlvbiAtLSBzdHJpbmdEZWZhdWx0VmFsdWUgLS0KKyAgICogY29udmVydHMgZnJvbSB0aGUgZ2VuZXJhdGVkIHN0cmluZyB0byB0aGUgc3RyaW5nIHdlIGFjdHVhbGx5IHdhbnQuICBUaGUKKyAgICogZ2VuZXJhdGVkIGNvZGUgY2FsbHMgdGhpcyBhdXRvbWF0aWNhbGx5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3RyaW5nRGVmYXVsdFZhbHVlKFN0cmluZyBieXRlcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gbmV3IFN0cmluZyhieXRlcy5nZXRCeXRlcygiSVNPLTg4NTktMSIpLCAiVVRGLTgiKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBzaW5jZSBhbGwgSlZNcyBhcmUgcmVxdWlyZWQgdG8gaW1wbGVtZW50CisgICAgICAvLyBib3RoIG9mIHRoZSBhYm92ZSBjaGFyYWN0ZXIgc2V0cy4KKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgIkphdmEgVk0gZG9lcyBub3Qgc3VwcG9ydCBhIHN0YW5kYXJkIGNoYXJhY3RlciBzZXQuIiwgZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBjYWxsZWQgYnkgZ2VuZXJhdGVkIGNvZGUgdG8gY29uc3RydWN0IGRlZmF1bHQgdmFsdWVzIGZvciBieXRlcworICAgKiBmaWVsZHMuCisgICAqIDxwPgorICAgKiBUaGlzIGlzIGEgbG90IGxpa2Uge0BsaW5rICNzdHJpbmdEZWZhdWx0VmFsdWV9LCBidXQgZm9yIGJ5dGVzIGZpZWxkcy4KKyAgICogSW4gdGhpcyBjYXNlIHdlIG9ubHkgbmVlZCB0aGUgc2Vjb25kIG9mIHRoZSB0d28gaGFja3MgLS0gYWxsb3dpbmcgdXMgdG8KKyAgICogZW1iZWQgcmF3IGJ5dGVzIGFzIGEgc3RyaW5nIGxpdGVyYWwgd2l0aCBJU08tODg1OS0xIGVuY29kaW5nLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBCeXRlU3RyaW5nIGJ5dGVzRGVmYXVsdFZhbHVlKFN0cmluZyBieXRlcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gQnl0ZVN0cmluZy5jb3B5RnJvbShieXRlcy5nZXRCeXRlcygiSVNPLTg4NTktMSIpKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBzaW5jZSBhbGwgSlZNcyBhcmUgcmVxdWlyZWQgdG8gaW1wbGVtZW50CisgICAgICAvLyBJU08tODg1OS0xLgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAiSmF2YSBWTSBkb2VzIG5vdCBzdXBwb3J0IGEgc3RhbmRhcmQgY2hhcmFjdGVyIHNldC4iLCBlKTsKKyAgICB9CisgIH0KKyAgLyoqCisgICAqIEhlbHBlciBjYWxsZWQgYnkgZ2VuZXJhdGVkIGNvZGUgdG8gY29uc3RydWN0IGRlZmF1bHQgdmFsdWVzIGZvciBieXRlcworICAgKiBmaWVsZHMuCisgICAqIDxwPgorICAgKiBUaGlzIGlzIGxpa2Uge0BsaW5rICNieXRlc0RlZmF1bHRWYWx1ZX0sIGJ1dCByZXR1cm5zIGEgYnl0ZSBhcnJheS4gCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBieXRlQXJyYXlEZWZhdWx0VmFsdWUoU3RyaW5nIGJ5dGVzKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBieXRlcy5nZXRCeXRlcygiSVNPLTg4NTktMSIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuIHNpbmNlIGFsbCBKVk1zIGFyZSByZXF1aXJlZCB0byBpbXBsZW1lbnQKKyAgICAgIC8vIElTTy04ODU5LTEuCisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICJKYXZhIFZNIGRvZXMgbm90IHN1cHBvcnQgYSBzdGFuZGFyZCBjaGFyYWN0ZXIgc2V0LiIsIGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgY2FsbGVkIGJ5IGdlbmVyYXRlZCBjb2RlIHRvIGNvbnN0cnVjdCBkZWZhdWx0IHZhbHVlcyBmb3IgYnl0ZXMKKyAgICogZmllbGRzLgorICAgKiA8cD4KKyAgICogVGhpcyBpcyBsaWtlIHtAbGluayAjYnl0ZXNEZWZhdWx0VmFsdWV9LCBidXQgcmV0dXJucyBhIEJ5dGVCdWZmZXIuIAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBCeXRlQnVmZmVyIGJ5dGVCdWZmZXJEZWZhdWx0VmFsdWUoU3RyaW5nIGJ5dGVzKSB7CisgICAgcmV0dXJuIEJ5dGVCdWZmZXIud3JhcChieXRlQXJyYXlEZWZhdWx0VmFsdWUoYnl0ZXMpKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcgQnl0ZUJ1ZmZlciBhbmQgY29weSBhbGwgdGhlIGNvbnRlbnQgb2Yge0Bjb2RlIHNvdXJjZX0KKyAgICogQnl0ZUJ1ZmZlciB0byB0aGUgbmV3IEJ5dGVCdWZmZXIuIFRoZSBuZXcgQnl0ZUJ1ZmZlcidzIGxpbWl0IGFuZAorICAgKiBjYXBhY2l0eSB3aWxsIGJlIHNvdXJjZS5jYXBhY2l0eSgpLCBhbmQgaXRzIHBvc2l0aW9uIHdpbGwgYmUgMC4KKyAgICogTm90ZSB0aGF0IHRoZSBzdGF0ZSBvZiB7QGNvZGUgc291cmNlfSBCeXRlQnVmZmVyIHdvbid0IGJlIGNoYW5nZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIEJ5dGVCdWZmZXIgY29weUJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlciBzb3VyY2UpIHsKKyAgICAvLyBNYWtlIGEgZHVwbGljYXRlIG9mIHRoZSBzb3VyY2UgQnl0ZUJ1ZmZlciBhbmQgcmVhZCBkYXRhIGZyb20gdGhlCisgICAgLy8gZHVwbGljYXRlLiBUaGlzIGlzIHRvIGF2b2lkIGFmZmVjdGluZyB0aGUgc291cmNlIEJ5dGVCdWZmZXIncyBzdGF0ZS4KKyAgICBCeXRlQnVmZmVyIHRlbXAgPSBzb3VyY2UuZHVwbGljYXRlKCk7CisgICAgLy8gV2Ugd2FudCB0byBjb3B5IGFsbCB0aGUgZGF0YSBpbiB0aGUgc291cmNlIEJ5dGVCdWZmZXIsIG5vdCBqdXN0IHRoZQorICAgIC8vIHJlbWFpbmluZyBieXRlcy4KKyAgICB0ZW1wLmNsZWFyKCk7CisgICAgQnl0ZUJ1ZmZlciByZXN1bHQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKHRlbXAuY2FwYWNpdHkoKSk7CisgICAgcmVzdWx0LnB1dCh0ZW1wKTsKKyAgICByZXN1bHQuY2xlYXIoKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBjYWxsZWQgYnkgZ2VuZXJhdGVkIGNvZGUgdG8gZGV0ZXJtaW5lIGlmIGEgYnl0ZSBhcnJheSBpcyBhIHZhbGlkCisgICAqIFVURi04IGVuY29kZWQgc3RyaW5nIHN1Y2ggdGhhdCB0aGUgb3JpZ2luYWwgYnl0ZXMgY2FuIGJlIGNvbnZlcnRlZCB0bworICAgKiBhIFN0cmluZyBvYmplY3QgYW5kIHRoZW4gYmFjayB0byBhIGJ5dGUgYXJyYXkgcm91bmQgdHJpcHBpbmcgdGhlIGJ5dGVzCisgICAqIHdpdGhvdXQgbG9zcy4gIE1vcmUgcHJlY2lzZWx5LCByZXR1cm5zIHtAY29kZSB0cnVlfSB3aGVuZXZlcjoKKyAgICogPHByZT4gICB7QGNvZGUKKyAgICogQXJyYXlzLmVxdWFscyhieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksCisgICAqICAgICBuZXcgU3RyaW5nKGJ5dGVTdHJpbmcudG9CeXRlQXJyYXkoKSwgIlVURi04IikuZ2V0Qnl0ZXMoIlVURi04IikpCisgICAqIH08L3ByZT4KKyAgICoKKyAgICogPHA+VGhpcyBtZXRob2QgcmVqZWN0cyAib3ZlcmxvbmciIGJ5dGUgc2VxdWVuY2VzLCBhcyB3ZWxsIGFzCisgICAqIDMtYnl0ZSBzZXF1ZW5jZXMgdGhhdCB3b3VsZCBtYXAgdG8gYSBzdXJyb2dhdGUgY2hhcmFjdGVyLCBpbgorICAgKiBhY2NvcmRhbmNlIHdpdGggdGhlIHJlc3RyaWN0ZWQgZGVmaW5pdGlvbiBvZiBVVEYtOCBpbnRyb2R1Y2VkIGluCisgICAqIFVuaWNvZGUgMy4xLiAgTm90ZSB0aGF0IHRoZSBVVEYtOCBkZWNvZGVyIGluY2x1ZGVkIGluIE9yYWNsZSdzCisgICAqIEpESyBoYXMgYmVlbiBtb2RpZmllZCB0byBhbHNvIHJlamVjdCAib3ZlcmxvbmciIGJ5dGUgc2VxdWVuY2VzLAorICAgKiBidXQgY3VycmVudGx5ICgyMDExKSBzdGlsbCBhY2NlcHRzIDMtYnl0ZSBzdXJyb2dhdGUgY2hhcmFjdGVyCisgICAqIGJ5dGUgc2VxdWVuY2VzLgorICAgKgorICAgKiA8cD5TZWUgdGhlIFVuaWNvZGUgU3RhbmRhcmQsPC9icj4KKyAgICogVGFibGUgMy02LiA8ZW0+VVRGLTggQml0IERpc3RyaWJ1dGlvbjwvZW0+LDwvYnI+CisgICAqIFRhYmxlIDMtNy4gPGVtPldlbGwgRm9ybWVkIFVURi04IEJ5dGUgU2VxdWVuY2VzPC9lbT4uCisgICAqCisgICAqIDxwPkFzIG9mIDIwMTEtMDIsIHRoaXMgbWV0aG9kIHNpbXBseSByZXR1cm5zIHRoZSByZXN1bHQgb2Yge0BsaW5rCisgICAqIEJ5dGVTdHJpbmcjaXNWYWxpZFV0ZjgoKX0uICBDYWxsaW5nIHRoYXQgbWV0aG9kIGRpcmVjdGx5IGlzIHByZWZlcnJlZC4KKyAgICoKKyAgICogQHBhcmFtIGJ5dGVTdHJpbmcgdGhlIHN0cmluZyB0byBjaGVjaworICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIGJ5dGUgYXJyYXkgaXMgcm91bmQgdHJpcHBhYmxlCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFV0ZjgoQnl0ZVN0cmluZyBieXRlU3RyaW5nKSB7CisgICAgcmV0dXJuIGJ5dGVTdHJpbmcuaXNWYWxpZFV0ZjgoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNpc1ZhbGlkVXRmOChCeXRlU3RyaW5nKX0gYnV0IGZvciBieXRlIGFycmF5cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkVXRmOChieXRlW10gYnl0ZUFycmF5KSB7CisgICAgcmV0dXJuIFV0ZjguaXNWYWxpZFV0ZjgoYnl0ZUFycmF5KTsKKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgbWV0aG9kIHRvIGdldCB0aGUgVVRGLTggYnl0ZXMgb2YgYSBzdHJpbmcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSB0b0J5dGVBcnJheShTdHJpbmcgdmFsdWUpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIHZhbHVlLmdldEJ5dGVzKCJVVEYtOCIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVURi04IG5vdCBzdXBwb3J0ZWQ/IiwgZSk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogSGVscGVyIG1ldGhvZCB0byBjb252ZXJ0IGEgYnl0ZSBhcnJheSB0byBhIHN0cmluZyB1c2luZyBVVEYtOCBlbmNvZGluZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nVXRmOChieXRlW10gYnl0ZXMpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnl0ZXMsICJVVEYtOCIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVURi04IG5vdCBzdXBwb3J0ZWQ/IiwgZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEludGVyZmFjZSBmb3IgYW4gZW51bSB2YWx1ZSBvciB2YWx1ZSBkZXNjcmlwdG9yLCB0byBiZSB1c2VkIGluIEZpZWxkU2V0LgorICAgKiBUaGUgbGl0ZSBsaWJyYXJ5IHN0b3JlcyBlbnVtIHZhbHVlcyBkaXJlY3RseSBpbiBGaWVsZFNldHMgYnV0IHRoZSBmdWxsCisgICAqIGxpYnJhcnkgc3RvcmVzIEVudW1WYWx1ZURlc2NyaXB0b3JzIGluIG9yZGVyIHRvIGJldHRlciBzdXBwb3J0IHJlZmxlY3Rpb24uCisgICAqLworICBwdWJsaWMgaW50ZXJmYWNlIEVudW1MaXRlIHsKKyAgICBpbnQgZ2V0TnVtYmVyKCk7CisgIH0KKworICAvKioKKyAgICogSW50ZXJmYWNlIGZvciBhbiBvYmplY3Qgd2hpY2ggbWFwcyBpbnRlZ2VycyB0byB7QGxpbmsgRW51bUxpdGV9cy4KKyAgICoge0BsaW5rIERlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yfSBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGJ5IG1hcHBpbmcKKyAgICogbnVtYmVycyB0byB7QGxpbmsgRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcn1zLiAgQWRkaXRpb25hbGx5LAorICAgKiBldmVyeSBnZW5lcmF0ZWQgZW51bSB0eXBlIGhhcyBhIHN0YXRpYyBtZXRob2QgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHdoaWNoCisgICAqIHJldHVybnMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcyB0eXBlIHRoYXQgbWFwcyBudW1iZXJzIHRvIGVudW0gdmFsdWVzLgorICAgKi8KKyAgcHVibGljIGludGVyZmFjZSBFbnVtTGl0ZU1hcDxUIGV4dGVuZHMgRW51bUxpdGU+IHsKKyAgICBUIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpOworICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBtZXRob2QgZm9yIGltcGxlbWVudGluZyB7QGxpbmsgTWVzc2FnZSNoYXNoQ29kZSgpfSBmb3IgbG9uZ3MuCisgICAqIEBzZWUgTG9uZyNoYXNoQ29kZSgpCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBoYXNoTG9uZyhsb25nIG4pIHsKKyAgICByZXR1cm4gKGludCkgKG4gXiAobiA+Pj4gMzIpKTsKKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgbWV0aG9kIGZvciBpbXBsZW1lbnRpbmcge0BsaW5rIE1lc3NhZ2UjaGFzaENvZGUoKX0gZm9yCisgICAqIGJvb2xlYW5zLgorICAgKiBAc2VlIEJvb2xlYW4jaGFzaENvZGUoKQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgaGFzaEJvb2xlYW4oYm9vbGVhbiBiKSB7CisgICAgcmV0dXJuIGIgPyAxMjMxIDogMTIzNzsKKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgbWV0aG9kIGZvciBpbXBsZW1lbnRpbmcge0BsaW5rIE1lc3NhZ2UjaGFzaENvZGUoKX0gZm9yIGVudW1zLgorICAgKiA8cD4KKyAgICogVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSB7QGxpbmsgamF2YS5sYW5nLkVudW0jaGFzaENvZGUoKX0gaXMgZmluYWwsIGJ1dCB3ZQorICAgKiBuZWVkIHRvIHVzZSB0aGUgZmllbGQgbnVtYmVyIGFzIHRoZSBoYXNoIGNvZGUgdG8gZW5zdXJlIGNvbXBhdGliaWxpdHkKKyAgICogYmV0d2VlbiBzdGF0aWNhbGx5IGFuZCBkeW5hbWljYWxseSBnZW5lcmF0ZWQgZW51bSBvYmplY3RzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgaGFzaEVudW0oRW51bUxpdGUgZSkgeworICAgIHJldHVybiBlLmdldE51bWJlcigpOworICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBtZXRob2QgZm9yIGltcGxlbWVudGluZyB7QGxpbmsgTWVzc2FnZSNoYXNoQ29kZSgpfSBmb3IKKyAgICogZW51bSBsaXN0cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hFbnVtTGlzdChMaXN0PD8gZXh0ZW5kcyBFbnVtTGl0ZT4gbGlzdCkgeworICAgIGludCBoYXNoID0gMTsKKyAgICBmb3IgKEVudW1MaXRlIGUgOiBsaXN0KSB7CisgICAgICBoYXNoID0gMzEgKiBoYXNoICsgaGFzaEVudW0oZSk7CisgICAgfQorICAgIHJldHVybiBoYXNoOworICB9CisgIAorICAvKioKKyAgICogSGVscGVyIG1ldGhvZCBmb3IgaW1wbGVtZW50aW5nIHtAbGluayBNZXNzYWdlI2VxdWFscyhPYmplY3QpfSBmb3IgYnl0ZXMgZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKExpc3Q8Ynl0ZVtdPiBhLCBMaXN0PGJ5dGVbXT4gYikgeworICAgIGlmIChhLnNpemUoKSAhPSBiLnNpemUoKSkgcmV0dXJuIGZhbHNlOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5zaXplKCk7ICsraSkgeworICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKGEuZ2V0KGkpLCBiLmdldChpKSkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgbWV0aG9kIGZvciBpbXBsZW1lbnRpbmcge0BsaW5rIE1lc3NhZ2UjaGFzaENvZGUoKX0gZm9yIGJ5dGVzIGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoTGlzdDxieXRlW10+IGxpc3QpIHsKKyAgICBpbnQgaGFzaCA9IDE7CisgICAgZm9yIChieXRlW10gYnl0ZXMgOiBsaXN0KSB7CisgICAgICBoYXNoID0gMzEgKiBoYXNoICsgaGFzaENvZGUoYnl0ZXMpOworICAgIH0KKyAgICByZXR1cm4gaGFzaDsKKyAgfQorICAKKyAgLyoqCisgICAqIEhlbHBlciBtZXRob2QgZm9yIGltcGxlbWVudGluZyB7QGxpbmsgTWVzc2FnZSNoYXNoQ29kZSgpfSBmb3IgYnl0ZXMgZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZShieXRlW10gYnl0ZXMpIHsKKyAgICAvLyBUaGUgaGFzaCBjb2RlIGZvciBhIGJ5dGUgYXJyYXkgc2hvdWxkIGJlIHRoZSBzYW1lIGFzIHRoZSBoYXNoIGNvZGUgZm9yIGEKKyAgICAvLyBCeXRlU3RyaW5nIHdpdGggdGhlIHNhbWUgY29udGVudC4gVGhpcyBpcyB0byBlbnN1cmUgdGhhdCB0aGUgZ2VuZXJhdGVkCisgICAgLy8gaGFzaENvZGUoKSBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIHNhbWUgdmFsdWUgYXMgdGhlIHB1cmUgcmVmbGVjdGlvbgorICAgIC8vIGJhc2VkIGhhc2hDb2RlKCkgbWV0aG9kLgorICAgIHJldHVybiBMaXRlcmFsQnl0ZVN0cmluZy5oYXNoQ29kZShieXRlcyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBIZWxwZXIgbWV0aG9kIGZvciBpbXBsZW1lbnRpbmcge0BsaW5rIE1lc3NhZ2UjZXF1YWxzKE9iamVjdCl9IGZvciBieXRlcworICAgKiBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHNCeXRlQnVmZmVyKEJ5dGVCdWZmZXIgYSwgQnl0ZUJ1ZmZlciBiKSB7CisgICAgaWYgKGEuY2FwYWNpdHkoKSAhPSBiLmNhcGFjaXR5KCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgLy8gQnl0ZUJ1ZmZlci5lcXVhbHMoKSB3aWxsIG9ubHkgY29tcGFyZSB0aGUgcmVtYWluaW5nIGJ5dGVzLCBidXQgd2Ugd2FudCB0bworICAgIC8vIGNvbXBhcmUgYWxsIHRoZSBjb250ZW50LgorICAgIHJldHVybiBhLmR1cGxpY2F0ZSgpLmNsZWFyKCkuZXF1YWxzKGIuZHVwbGljYXRlKCkuY2xlYXIoKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBIZWxwZXIgbWV0aG9kIGZvciBpbXBsZW1lbnRpbmcge0BsaW5rIE1lc3NhZ2UjZXF1YWxzKE9iamVjdCl9IGZvciBieXRlcworICAgKiBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHNCeXRlQnVmZmVyKAorICAgICAgTGlzdDxCeXRlQnVmZmVyPiBhLCBMaXN0PEJ5dGVCdWZmZXI+IGIpIHsKKyAgICBpZiAoYS5zaXplKCkgIT0gYi5zaXplKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLnNpemUoKTsgKytpKSB7CisgICAgICBpZiAoIWVxdWFsc0J5dGVCdWZmZXIoYS5nZXQoaSksIGIuZ2V0KGkpKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBtZXRob2QgZm9yIGltcGxlbWVudGluZyB7QGxpbmsgTWVzc2FnZSNoYXNoQ29kZSgpfSBmb3IgYnl0ZXMKKyAgICogZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZUJ5dGVCdWZmZXIoTGlzdDxCeXRlQnVmZmVyPiBsaXN0KSB7CisgICAgaW50IGhhc2ggPSAxOworICAgIGZvciAoQnl0ZUJ1ZmZlciBieXRlcyA6IGxpc3QpIHsKKyAgICAgIGhhc2ggPSAzMSAqIGhhc2ggKyBoYXNoQ29kZUJ5dGVCdWZmZXIoYnl0ZXMpOworICAgIH0KKyAgICByZXR1cm4gaGFzaDsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQlVGRkVSX1NJWkUgPSA0MDk2OworICAKKyAgLyoqCisgICAqIEhlbHBlciBtZXRob2QgZm9yIGltcGxlbWVudGluZyB7QGxpbmsgTWVzc2FnZSNoYXNoQ29kZSgpfSBmb3IgYnl0ZXMKKyAgICogZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZUJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlciBieXRlcykgeworICAgIGlmIChieXRlcy5oYXNBcnJheSgpKSB7CisgICAgICAvLyBGYXN0IHBhdGguCisgICAgICBpbnQgaCA9IExpdGVyYWxCeXRlU3RyaW5nLmhhc2hDb2RlKGJ5dGVzLmNhcGFjaXR5KCksIGJ5dGVzLmFycmF5KCksCisgICAgICAgICAgYnl0ZXMuYXJyYXlPZmZzZXQoKSwgYnl0ZXMuY2FwYWNpdHkoKSk7CisgICAgICByZXR1cm4gaCA9PSAwID8gMSA6IGg7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFJlYWQgdGhlIGRhdGEgaW50byBhIHRlbXBvcmFyeSBieXRlIGFycmF5IGJlZm9yZSBjYWxjdWxhdGluZyB0aGUKKyAgICAgIC8vIGhhc2ggdmFsdWUuCisgICAgICBmaW5hbCBpbnQgYnVmZmVyU2l6ZSA9IGJ5dGVzLmNhcGFjaXR5KCkgPiBERUZBVUxUX0JVRkZFUl9TSVpFCisgICAgICAgICAgPyBERUZBVUxUX0JVRkZFUl9TSVpFIDogYnl0ZXMuY2FwYWNpdHkoKTsKKyAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJTaXplXTsKKyAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgZHVwbGljYXRlZCA9IGJ5dGVzLmR1cGxpY2F0ZSgpOworICAgICAgZHVwbGljYXRlZC5jbGVhcigpOworICAgICAgaW50IGggPSBieXRlcy5jYXBhY2l0eSgpOworICAgICAgd2hpbGUgKGR1cGxpY2F0ZWQucmVtYWluaW5nKCkgPiAwKSB7CisgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBkdXBsaWNhdGVkLnJlbWFpbmluZygpIDw9IGJ1ZmZlclNpemUgPworICAgICAgICAgICAgZHVwbGljYXRlZC5yZW1haW5pbmcoKSA6IGJ1ZmZlclNpemU7CisgICAgICAgIGR1cGxpY2F0ZWQuZ2V0KGJ1ZmZlciwgMCwgbGVuZ3RoKTsKKyAgICAgICAgaCA9IExpdGVyYWxCeXRlU3RyaW5nLmhhc2hDb2RlKGgsIGJ1ZmZlciwgMCwgbGVuZ3RoKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBoID09IDAgPyAxIDogaDsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBBbiBlbXB0eSBieXRlIGFycmF5IGNvbnN0YW50IHVzZWQgaW4gZ2VuZXJhdGVkIGNvZGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGVbXSBFTVBUWV9CWVRFX0FSUkFZID0gbmV3IGJ5dGVbMF07CisgIAorICAvKioKKyAgICogQW4gZW1wdHkgYnl0ZSBhcnJheSBjb25zdGFudCB1c2VkIGluIGdlbmVyYXRlZCBjb2RlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBCeXRlQnVmZmVyIEVNUFRZX0JZVEVfQlVGRkVSID0KKyAgICAgIEJ5dGVCdWZmZXIud3JhcChFTVBUWV9CWVRFX0FSUkFZKTsKKyAgCisgIC8qKiBBbiBlbXB0eSBjb2RlZCBpbnB1dCBzdHJlYW0gY29uc3RhbnQgdXNlZCBpbiBnZW5lcmF0ZWQgY29kZS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2RlZElucHV0U3RyZWFtIEVNUFRZX0NPREVEX0lOUFVUX1NUUkVBTSA9CisgICAgICBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKEVNUFRZX0JZVEVfQVJSQVkpOworCisKKyAgLyoqCisgICAqIFByb3ZpZGVzIGFuIGltbXV0YWJsZSB2aWV3IG9mIExpc3Q8VD4gYXJvdW5kIGEgTGlzdDxGPi4KKyAgICoKKyAgICogUHJvdG9idWYgaW50ZXJuYWwuIFVzZWQgaW4gcHJvdG9idWYgZ2VuZXJhdGVkIGNvZGUgb25seS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTGlzdEFkYXB0ZXI8RiwgVD4gZXh0ZW5kcyBBYnN0cmFjdExpc3Q8VD4geworICAgIC8qKgorICAgICAqIENvbnZlcnQgaW5kaXZpZHVhbCBlbGVtZW50cyBvZiB0aGUgTGlzdCBmcm9tIEYgdG8gVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50ZXJmYWNlIENvbnZlcnRlcjxGLCBUPiB7CisgICAgICBUIGNvbnZlcnQoRiBmcm9tKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8Rj4gZnJvbUxpc3Q7CisgICAgcHJpdmF0ZSBmaW5hbCBDb252ZXJ0ZXI8RiwgVD4gY29udmVydGVyOworCisgICAgcHVibGljIExpc3RBZGFwdGVyKExpc3Q8Rj4gZnJvbUxpc3QsIENvbnZlcnRlcjxGLCBUPiBjb252ZXJ0ZXIpIHsKKyAgICAgIHRoaXMuZnJvbUxpc3QgPSBmcm9tTGlzdDsKKyAgICAgIHRoaXMuY29udmVydGVyID0gY29udmVydGVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBUIGdldChpbnQgaW5kZXgpIHsKKyAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tTGlzdC5nZXQoaW5kZXgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICByZXR1cm4gZnJvbUxpc3Quc2l6ZSgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBXcmFwIGFyb3VuZCBhIE1hcDxLLCBSZWFsVmFsdWU+IGFuZCBwcm92aWRlIGEgTWFwPEssIFY+IGludGVyZmFjZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTWFwQWRhcHRlcjxLLCBWLCBSZWFsVmFsdWU+IGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4geworICAgIC8qKgorICAgICAqIEFuIGludGVyZmFjZSB1c2VkIHRvIGNvbnZlcnQgYmV0d2VlbiB0d28gdHlwZXMuCisgICAgICovCisgICAgcHVibGljIGludGVyZmFjZSBDb252ZXJ0ZXI8QSwgQj4geworICAgICAgQiBkb0ZvcndhcmQoQSBvYmplY3QpOworICAgICAgQSBkb0JhY2t3YXJkKEIgb2JqZWN0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgRW51bUxpdGU+IENvbnZlcnRlcjxJbnRlZ2VyLCBUPiBuZXdFbnVtQ29udmVydGVyKAorICAgICAgICBmaW5hbCBFbnVtTGl0ZU1hcDxUPiBlbnVtTWFwLCBmaW5hbCBUIHVucmVjb2duaXplZFZhbHVlKSB7CisgICAgICByZXR1cm4gbmV3IENvbnZlcnRlcjxJbnRlZ2VyLCBUPigpIHsKKyAgICAgICAgcHVibGljIFQgZG9Gb3J3YXJkKEludGVnZXIgdmFsdWUpIHsKKyAgICAgICAgICBUIHJlc3VsdCA9IGVudW1NYXAuZmluZFZhbHVlQnlOdW1iZXIodmFsdWUpOworICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHVucmVjb2duaXplZFZhbHVlIDogcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBJbnRlZ2VyIGRvQmFja3dhcmQoVCB2YWx1ZSkgeworICAgICAgICAgIHJldHVybiB2YWx1ZS5nZXROdW1iZXIoKTsKKyAgICAgICAgfQorICAgICAgfTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxLLCBSZWFsVmFsdWU+IHJlYWxNYXA7CisgICAgcHJpdmF0ZSBmaW5hbCBDb252ZXJ0ZXI8UmVhbFZhbHVlLCBWPiB2YWx1ZUNvbnZlcnRlcjsKKyAgICAKKyAgICBwdWJsaWMgTWFwQWRhcHRlcihNYXA8SywgUmVhbFZhbHVlPiByZWFsTWFwLAorICAgICAgICBDb252ZXJ0ZXI8UmVhbFZhbHVlLCBWPiB2YWx1ZUNvbnZlcnRlcikgeworICAgICAgdGhpcy5yZWFsTWFwID0gcmVhbE1hcDsKKyAgICAgIHRoaXMudmFsdWVDb252ZXJ0ZXIgPSB2YWx1ZUNvbnZlcnRlcjsKKyAgICB9CisgICAgCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgIFJlYWxWYWx1ZSByZXN1bHQgPSByZWFsTWFwLmdldChrZXkpOworICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgcmV0dXJuIHZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChyZXN1bHQpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgIFJlYWxWYWx1ZSBvbGRWYWx1ZSA9IHJlYWxNYXAucHV0KGtleSwgdmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOworICAgICAgaWYgKG9sZFZhbHVlID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICByZXR1cm4gdmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG9sZFZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2V0PGphdmEudXRpbC5NYXAuRW50cnk8SywgVj4+IGVudHJ5U2V0KCkgeworICAgICAgcmV0dXJuIG5ldyBTZXRBZGFwdGVyKHJlYWxNYXAuZW50cnlTZXQoKSk7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgY2xhc3MgU2V0QWRhcHRlciBleHRlbmRzIEFic3RyYWN0U2V0PE1hcC5FbnRyeTxLLCBWPj4geworICAgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8TWFwLkVudHJ5PEssIFJlYWxWYWx1ZT4+IHJlYWxTZXQ7CisgICAgICBwdWJsaWMgU2V0QWRhcHRlcihTZXQ8TWFwLkVudHJ5PEssIFJlYWxWYWx1ZT4+IHJlYWxTZXQpIHsKKyAgICAgICAgdGhpcy5yZWFsU2V0ID0gcmVhbFNldDsKKyAgICAgIH0KKyAgICAgIAorICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgSXRlcmF0b3I8amF2YS51dGlsLk1hcC5FbnRyeTxLLCBWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3JBZGFwdGVyKHJlYWxTZXQuaXRlcmF0b3IoKSk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gcmVhbFNldC5zaXplKCk7CisgICAgICB9IAorICAgIH0KKyAgICAKKyAgICBwcml2YXRlIGNsYXNzIEl0ZXJhdG9yQWRhcHRlciBpbXBsZW1lbnRzIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4geworICAgICAgcHJpdmF0ZSBmaW5hbCBJdGVyYXRvcjxNYXAuRW50cnk8SywgUmVhbFZhbHVlPj4gcmVhbEl0ZXJhdG9yOworICAgICAgCisgICAgICBwdWJsaWMgSXRlcmF0b3JBZGFwdGVyKAorICAgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBSZWFsVmFsdWU+PiByZWFsSXRlcmF0b3IpIHsKKyAgICAgICAgdGhpcy5yZWFsSXRlcmF0b3IgPSByZWFsSXRlcmF0b3I7CisgICAgICB9CisgICAgICAKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgcmV0dXJuIHJlYWxJdGVyYXRvci5oYXNOZXh0KCk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGphdmEudXRpbC5NYXAuRW50cnk8SywgVj4gbmV4dCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBFbnRyeUFkYXB0ZXIocmVhbEl0ZXJhdG9yLm5leHQoKSk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICByZWFsSXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHByaXZhdGUgY2xhc3MgRW50cnlBZGFwdGVyIGltcGxlbWVudHMgTWFwLkVudHJ5PEssIFY+IHsKKyAgICAgIHByaXZhdGUgZmluYWwgTWFwLkVudHJ5PEssIFJlYWxWYWx1ZT4gcmVhbEVudHJ5OworICAgICAgCisgICAgICBwdWJsaWMgRW50cnlBZGFwdGVyKE1hcC5FbnRyeTxLLCBSZWFsVmFsdWU+IHJlYWxFbnRyeSkgeworICAgICAgICB0aGlzLnJlYWxFbnRyeSA9IHJlYWxFbnRyeTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgSyBnZXRLZXkoKSB7CisgICAgICAgIHJldHVybiByZWFsRW50cnkuZ2V0S2V5KCk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIFYgZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQocmVhbEVudHJ5LmdldFZhbHVlKCkpOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBWIHNldFZhbHVlKFYgdmFsdWUpIHsKKyAgICAgICAgUmVhbFZhbHVlIG9sZFZhbHVlID0gcmVhbEVudHJ5LnNldFZhbHVlKAorICAgICAgICAgICAgdmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOworICAgICAgICBpZiAob2xkVmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiB2YWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQob2xkVmFsdWUpOworICAgICAgfQorICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjdmYTIzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxMjIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcHJvdG9jb2wgbWVzc2FnZSBiZWluZyBwYXJzZWQgaXMgaW52YWxpZCBpbiBzb21lIHdheSwKKyAqIGUuZy4gaXQgY29udGFpbnMgYSBtYWxmb3JtZWQgdmFyaW50IG9yIGEgbmVnYXRpdmUgYnl0ZSBsZW5ndGguCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGNsYXNzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE2MTYxNTE3NjMwNzI0NTA0NzZMOworICBwcml2YXRlIE1lc3NhZ2VMaXRlIHVuZmluaXNoZWRNZXNzYWdlID0gbnVsbDsKKworICBwdWJsaWMgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGZpbmFsIFN0cmluZyBkZXNjcmlwdGlvbikgeworICAgIHN1cGVyKGRlc2NyaXB0aW9uKTsKKyAgfQorCisgIC8qKgorICAgKiBBdHRhY2hlcyBhbiB1bmZpbmlzaGVkIG1lc3NhZ2UgdG8gdGhlIGV4Y2VwdGlvbiB0byBzdXBwb3J0IGJlc3QtZWZmb3J0CisgICAqIHBhcnNpbmcgaW4ge0Bjb2RlIFBhcnNlcn0gaW50ZXJmYWNlLgorICAgKgorICAgKiBAcmV0dXJuIHRoaXMKKyAgICovCisgIHB1YmxpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gc2V0VW5maW5pc2hlZE1lc3NhZ2UoCisgICAgICBNZXNzYWdlTGl0ZSB1bmZpbmlzaGVkTWVzc2FnZSkgeworICAgIHRoaXMudW5maW5pc2hlZE1lc3NhZ2UgPSB1bmZpbmlzaGVkTWVzc2FnZTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSB1bmZpbmlzaGVkIG1lc3NhZ2UgYXR0YWNoZWQgdG8gdGhlIGV4Y2VwdGlvbiwgb3IgbnVsbCBpZgorICAgKiBubyBtZXNzYWdlIGlzIGF0dGFjaGVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VMaXRlIGdldFVuZmluaXNoZWRNZXNzYWdlKCkgeworICAgIHJldHVybiB1bmZpbmlzaGVkTWVzc2FnZTsKKyAgfQorCisgIHN0YXRpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gdHJ1bmNhdGVkTWVzc2FnZSgpIHsKKyAgICByZXR1cm4gbmV3IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigKKyAgICAgICJXaGlsZSBwYXJzaW5nIGEgcHJvdG9jb2wgbWVzc2FnZSwgdGhlIGlucHV0IGVuZGVkIHVuZXhwZWN0ZWRseSAiICsKKyAgICAgICJpbiB0aGUgbWlkZGxlIG9mIGEgZmllbGQuICBUaGlzIGNvdWxkIG1lYW4gZWl0aGVyIHRoYW4gdGhlICIgKworICAgICAgImlucHV0IGhhcyBiZWVuIHRydW5jYXRlZCBvciB0aGF0IGFuIGVtYmVkZGVkIG1lc3NhZ2UgIiArCisgICAgICAibWlzcmVwb3J0ZWQgaXRzIG93biBsZW5ndGguIik7CisgIH0KKworICBzdGF0aWMgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIG5lZ2F0aXZlU2l6ZSgpIHsKKyAgICByZXR1cm4gbmV3IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigKKyAgICAgICJDb2RlZElucHV0U3RyZWFtIGVuY291bnRlcmVkIGFuIGVtYmVkZGVkIHN0cmluZyBvciBtZXNzYWdlICIgKworICAgICAgIndoaWNoIGNsYWltZWQgdG8gaGF2ZSBuZWdhdGl2ZSBzaXplLiIpOworICB9CisKKyAgc3RhdGljIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBtYWxmb3JtZWRWYXJpbnQoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oCisgICAgICAiQ29kZWRJbnB1dFN0cmVhbSBlbmNvdW50ZXJlZCBhIG1hbGZvcm1lZCB2YXJpbnQuIik7CisgIH0KKworICBzdGF0aWMgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGludmFsaWRUYWcoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oCisgICAgICAiUHJvdG9jb2wgbWVzc2FnZSBjb250YWluZWQgYW4gaW52YWxpZCB0YWcgKHplcm8pLiIpOworICB9CisKKyAgc3RhdGljIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBpbnZhbGlkRW5kVGFnKCkgeworICAgIHJldHVybiBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKAorICAgICAgIlByb3RvY29sIG1lc3NhZ2UgZW5kLWdyb3VwIHRhZyBkaWQgbm90IG1hdGNoIGV4cGVjdGVkIHRhZy4iKTsKKyAgfQorCisgIHN0YXRpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gaW52YWxpZFdpcmVUeXBlKCkgeworICAgIHJldHVybiBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKAorICAgICAgIlByb3RvY29sIG1lc3NhZ2UgdGFnIGhhZCBpbnZhbGlkIHdpcmUgdHlwZS4iKTsKKyAgfQorCisgIHN0YXRpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gcmVjdXJzaW9uTGltaXRFeGNlZWRlZCgpIHsKKyAgICByZXR1cm4gbmV3IEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigKKyAgICAgICJQcm90b2NvbCBtZXNzYWdlIGhhZCB0b28gbWFueSBsZXZlbHMgb2YgbmVzdGluZy4gIE1heSBiZSBtYWxpY2lvdXMuICAiICsKKyAgICAgICJVc2UgQ29kZWRJbnB1dFN0cmVhbS5zZXRSZWN1cnNpb25MaW1pdCgpIHRvIGluY3JlYXNlIHRoZSBkZXB0aCBsaW1pdC4iKTsKKyAgfQorCisgIHN0YXRpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gc2l6ZUxpbWl0RXhjZWVkZWQoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oCisgICAgICAiUHJvdG9jb2wgbWVzc2FnZSB3YXMgdG9vIGxhcmdlLiAgTWF5IGJlIG1hbGljaW91cy4gICIgKworICAgICAgIlVzZSBDb2RlZElucHV0U3RyZWFtLnNldFNpemVMaW1pdCgpIHRvIGluY3JlYXNlIHRoZSBzaXplIGxpbWl0LiIpOworICB9CisKKyAgc3RhdGljIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBwYXJzZUZhaWx1cmUoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oIkZhaWxlZCB0byBwYXJzZSB0aGUgbWVzc2FnZS4iKTsKKyAgfQorCisgIHN0YXRpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gaW52YWxpZFV0ZjgoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oIlByb3RvY29sIG1lc3NhZ2UgaGFkIGludmFsaWQgVVRGLTguIik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlGaWVsZC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2RhOGI5MAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlGaWVsZC5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXAuRW50cnk7CisKKy8qKgorICogTGF6eUZpZWxkIGVuY2Fwc3VsYXRlcyB0aGUgbG9naWMgb2YgbGF6aWx5IHBhcnNpbmcgbWVzc2FnZSBmaWVsZHMuIEl0IHN0b3JlcworICogdGhlIG1lc3NhZ2UgaW4gYSBCeXRlU3RyaW5nIGluaXRpYWxseSBhbmQgdGhlbiBwYXJzZSBpdCBvbi1kZW1hbmQuCisgKgorICogTW9zdCBvZiBrZXkgbWV0aG9kcyBhcmUgaW1wbGVtZW50ZWQgaW4ge0BsaW5rIExhenlGaWVsZExpdGV9IGJ1dCB0aGlzIGNsYXNzCisgKiBjYW4gY29udGFpbiBkZWZhdWx0IGluc3RhbmNlIG9mIHRoZSBtZXNzYWdlIHRvIHByb3ZpZGUge0Bjb2RlIGhhc2hDb2RlKCl9LAorICoge0Bjb2RlIGV1cWFscygpfSBhbmQge0Bjb2RlIHRvU3RyaW5nKCl9LgorICoKKyAqIEBhdXRob3IgeGlhbmdsQGdvb2dsZS5jb20gKFhpYW5nIExpKQorICovCitwdWJsaWMgY2xhc3MgTGF6eUZpZWxkIGV4dGVuZHMgTGF6eUZpZWxkTGl0ZSB7CisKKyAgLyoqCisgICAqIENhcnJ5IGEgbWVzc2FnZSdzIGRlZmF1bHQgaW5zdGFuY2Ugd2hpY2ggaXMgdXNlZCBieSB7QGNvZGUgaGFzaENvZGUoKX0sIHtAY29kZSBldXFhbHMoKX0gYW5kCisgICAqIHtAY29kZSB0b1N0cmluZygpfS4KKyAgICovCisgIHByaXZhdGUgZmluYWwgTWVzc2FnZUxpdGUgZGVmYXVsdEluc3RhbmNlOworCisgIHB1YmxpYyBMYXp5RmllbGQoTWVzc2FnZUxpdGUgZGVmYXVsdEluc3RhbmNlLAorICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LCBCeXRlU3RyaW5nIGJ5dGVzKSB7CisgICAgc3VwZXIoZXh0ZW5zaW9uUmVnaXN0cnksIGJ5dGVzKTsKKworICAgIHRoaXMuZGVmYXVsdEluc3RhbmNlID0gZGVmYXVsdEluc3RhbmNlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRGVmYXVsdEluc3RhbmNlKCkgeworICAgIHJldHVybiBzdXBlci5jb250YWluc0RlZmF1bHRJbnN0YW5jZSgpIHx8IHZhbHVlID09IGRlZmF1bHRJbnN0YW5jZTsKKyAgfQorCisgIHB1YmxpYyBNZXNzYWdlTGl0ZSBnZXRWYWx1ZSgpIHsKKyAgICByZXR1cm4gZ2V0VmFsdWUoZGVmYXVsdEluc3RhbmNlKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiBnZXRWYWx1ZSgpLmhhc2hDb2RlKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICByZXR1cm4gZ2V0VmFsdWUoKS5lcXVhbHMob2JqKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiBnZXRWYWx1ZSgpLnRvU3RyaW5nKCk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqCisgICAqIExhenlFbnRyeSBhbmQgTGF6eUl0ZXJhdG9yIGFyZSB1c2VkIHRvIGVuY2Fwc3VsYXRlIHRoZSBMYXp5RmllbGQsIHdoZW4KKyAgICogdXNlcnMgaXRlcmF0ZSBhbGwgZmllbGRzIGZyb20gRmllbGRTZXQuCisgICAqLworICBzdGF0aWMgY2xhc3MgTGF6eUVudHJ5PEs+IGltcGxlbWVudHMgRW50cnk8SywgT2JqZWN0PiB7CisgICAgcHJpdmF0ZSBFbnRyeTxLLCBMYXp5RmllbGQ+IGVudHJ5OworCisgICAgcHJpdmF0ZSBMYXp5RW50cnkoRW50cnk8SywgTGF6eUZpZWxkPiBlbnRyeSkgeworICAgICAgdGhpcy5lbnRyeSA9IGVudHJ5OworICAgIH0KKworICAgIC8vIEBPdmVycmlkZQorICAgIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICAgIHJldHVybiBlbnRyeS5nZXRLZXkoKTsKKyAgICB9CisKKyAgICAvLyBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldFZhbHVlKCkgeworICAgICAgTGF6eUZpZWxkIGZpZWxkID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgIGlmIChmaWVsZCA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgcmV0dXJuIGZpZWxkLmdldFZhbHVlKCk7CisgICAgfQorCisgICAgcHVibGljIExhenlGaWVsZCBnZXRGaWVsZCgpIHsKKyAgICAgIHJldHVybiBlbnRyeS5nZXRWYWx1ZSgpOworICAgIH0KKworICAgIC8vIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3Qgc2V0VmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIE1lc3NhZ2VMaXRlKSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIkxhenlGaWVsZCBub3cgb25seSB1c2VkIGZvciBNZXNzYWdlU2V0LCAiCisgICAgICAgICAgICArICJhbmQgdGhlIHZhbHVlIG9mIE1lc3NhZ2VTZXQgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBNZXNzYWdlTGl0ZSIpOworICAgICAgfQorICAgICAgcmV0dXJuIGVudHJ5LmdldFZhbHVlKCkuc2V0VmFsdWUoKE1lc3NhZ2VMaXRlKSB2YWx1ZSk7CisgICAgfQorICB9CisKKyAgc3RhdGljIGNsYXNzIExhenlJdGVyYXRvcjxLPiBpbXBsZW1lbnRzIEl0ZXJhdG9yPEVudHJ5PEssIE9iamVjdD4+IHsKKyAgICBwcml2YXRlIEl0ZXJhdG9yPEVudHJ5PEssIE9iamVjdD4+IGl0ZXJhdG9yOworCisgICAgcHVibGljIExhenlJdGVyYXRvcihJdGVyYXRvcjxFbnRyeTxLLCBPYmplY3Q+PiBpdGVyYXRvcikgeworICAgICAgdGhpcy5pdGVyYXRvciA9IGl0ZXJhdG9yOworICAgIH0KKworICAgIC8vIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICByZXR1cm4gaXRlcmF0b3IuaGFzTmV4dCgpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIC8vIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnRyeTxLLCBPYmplY3Q+IG5leHQoKSB7CisgICAgICBFbnRyeTxLLCA/PiBlbnRyeSA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgIGlmIChlbnRyeS5nZXRWYWx1ZSgpIGluc3RhbmNlb2YgTGF6eUZpZWxkKSB7CisgICAgICAgIHJldHVybiBuZXcgTGF6eUVudHJ5PEs+KChFbnRyeTxLLCBMYXp5RmllbGQ+KSBlbnRyeSk7CisgICAgICB9CisgICAgICByZXR1cm4gKEVudHJ5PEssIE9iamVjdD4pIGVudHJ5OworICAgIH0KKworICAgIC8vIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkTGl0ZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkTGl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlYTFmZTMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5RmllbGRMaXRlLmphdmEKQEAgLTAsMCArMSwzMzkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogTGF6eUZpZWxkTGl0ZSBlbmNhcHN1bGF0ZXMgdGhlIGxvZ2ljIG9mIGxhemlseSBwYXJzaW5nIG1lc3NhZ2UgZmllbGRzLiBJdCBzdG9yZXMKKyAqIHRoZSBtZXNzYWdlIGluIGEgQnl0ZVN0cmluZyBpbml0aWFsbHkgYW5kIHRoZW4gcGFyc2UgaXQgb24tZGVtYW5kLgorICoKKyAqIExhenlGaWVsZCBpcyB0aHJlYWQtY29tcGF0aWJsZSBlLmcuIGNvbmN1cnJlbnQgcmVhZCBhcmUgc2FmZSwgaG93ZXZlciwKKyAqIHN5bmNocm9uaXphdGlvbnMgYXJlIG5lZWRlZCB1bmRlciByZWFkL3dyaXRlIHNpdHVhdGlvbnMuCisgKgorICogVGhpcyBjbGFzcyBpcyBpbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwsIHNvIHlvdSBkb24ndCBuZWVkIHRvIHVzZSBpdCBkaXJlY3RseS4KKyAqCisgKiBAYXV0aG9yIHhpYW5nbEBnb29nbGUuY29tIChYaWFuZyBMaSkKKyAqLworcHVibGljIGNsYXNzIExhenlGaWVsZExpdGUgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeUxpdGUgRU1QVFlfUkVHSVNUUlkgPQorICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKTsKKworICAvKioKKyAgICogQSBkZWxheWVkLXBhcnNlZCB2ZXJzaW9uIG9mIHRoZSBieXRlcy4gV2hlbiB0aGlzIGlzIG5vbi1udWxsIHRoZW4ge0Bjb2RlIGV4dGVuc2lvblJlZ2lzdHJ5IH0gaXMKKyAgICogYWxzbyBub24tbnVsbCBhbmQge0Bjb2RlIHZhbHVlfSBhbmQge0Bjb2RlIG1lbW9pemVkQnl0ZXN9IGFyZSBudWxsLgorICAgKi8KKyAgcHJpdmF0ZSBCeXRlU3RyaW5nIGRlbGF5ZWRCeXRlczsKKworICAvKioKKyAgICogQW4ge0Bjb2RlIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZX0gZm9yIHBhcnNpbmcgYnl0ZXMuIEl0IGlzIG5vbi1udWxsIG9uIGEgYmVzdC1lZmZvcnQgYmFzaXMuIEl0CisgICAqIGlzIG9ubHkgZ3VhcmFudGVlZCB0byBiZSBub24tbnVsbCBpZiB0aGlzIG1lc3NhZ2Ugd2FzIGluaXRpYWxpemVkIHVzaW5nIGJ5dGVzIGFuZCBhbgorICAgKiB7QGNvZGUgRXh0ZW5zaW9uUmVnaXN0cnl9LiBJZiBpdCBkaXJlY3RseSBoYWQgYSB2YWx1ZSBzZXQgdGhlbiBpdCB3aWxsIGJlIG51bGwsIHVubGVzcyBpdCBoYXMKKyAgICogYmVlbiBtZXJnZWQgd2l0aCBhbm90aGVyIHtAY29kZSBMYXp5RmllbGRMaXRlfSB0aGF0IGhhZCBhbiB7QGNvZGUgRXh0ZW5zaW9uUmVnaXN0cnl9LgorICAgKi8KKyAgcHJpdmF0ZSBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnk7CisKKyAgLyoqCisgICAqIFRoZSBwYXJzZWQgdmFsdWUuIFdoZW4gdGhpcyBpcyBub24tbnVsbCB0aGVuIHtAY29kZSBkZWxheWVkQnl0ZXN9IHdpbGwgYmUgbnVsbC4KKyAgICovCisgIHByb3RlY3RlZCB2b2xhdGlsZSBNZXNzYWdlTGl0ZSB2YWx1ZTsKKworICAvKioKKyAgICogVGhlIG1lbW9pemVkIGJ5dGVzIGZvciB7QGNvZGUgdmFsdWV9LiBXaWxsIGJlIG51bGwgd2hlbiB7QGNvZGUgdmFsdWV9IGlzIG51bGwuCisgICAqLworICBwcml2YXRlIHZvbGF0aWxlIEJ5dGVTdHJpbmcgbWVtb2l6ZWRCeXRlczsKKworICAvKioKKyAgICogQ29uc3RydWN0cyBhIExhenlGaWVsZExpdGUgd2l0aCBieXRlcyB0aGF0IHdpbGwgYmUgcGFyc2VkIGxhemlseS4KKyAgICovCisgIHB1YmxpYyBMYXp5RmllbGRMaXRlKEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSwgQnl0ZVN0cmluZyBieXRlcykgeworICAgIGNoZWNrQXJndW1lbnRzKGV4dGVuc2lvblJlZ2lzdHJ5LCBieXRlcyk7CisgICAgdGhpcy5leHRlbnNpb25SZWdpc3RyeSA9IGV4dGVuc2lvblJlZ2lzdHJ5OworICAgIHRoaXMuZGVsYXllZEJ5dGVzID0gYnl0ZXM7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0cyBhIExhenlGaWVsZExpdGUgd2l0aCBubyBjb250ZW50cywgYW5kIG5vIGFiaWxpdHkgdG8gcGFyc2UgZXh0ZW5zaW9ucy4KKyAgICovCisgIHB1YmxpYyBMYXp5RmllbGRMaXRlKCkgeworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBMYXp5RmllbGRMaXRlIGluc3RhbmNlIHdpdGggYSB2YWx1ZS4gVGhlIExhenlGaWVsZExpdGUgbWF5IG5vdCBiZSBhYmxlIHRvIHBhcnNlCisgICAqIHRoZSBleHRlbnNpb25zIGluIHRoZSB2YWx1ZSBhcyBpdCBoYXMgbm8gRXh0ZW5zaW9uUmVnaXN0cnkuCisgICAqLworICBwdWJsaWMgc3RhdGljIExhenlGaWVsZExpdGUgZnJvbVZhbHVlKE1lc3NhZ2VMaXRlIHZhbHVlKSB7CisgICAgTGF6eUZpZWxkTGl0ZSBsZiA9IG5ldyBMYXp5RmllbGRMaXRlKCk7CisgICAgbGYuc2V0VmFsdWUodmFsdWUpOworICAgIHJldHVybiBsZjsKKyAgfQorCisgIC8qKgorICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyBMYXp5RmllbGRMaXRlIGluc3RhbmNlIHJlcHJlc2VudHMgdGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhpcyB0eXBlLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gY29udGFpbnNEZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgcmV0dXJuIG1lbW9pemVkQnl0ZXMgPT0gQnl0ZVN0cmluZy5FTVBUWQorICAgICAgICB8fCB2YWx1ZSA9PSBudWxsICYmIChkZWxheWVkQnl0ZXMgPT0gbnVsbCB8fCBkZWxheWVkQnl0ZXMgPT0gQnl0ZVN0cmluZy5FTVBUWSk7CisgIH0KKworICAvKioKKyAgICogQ2xlYXJzIHRoZSB2YWx1ZSBzdGF0ZSBvZiB0aGlzIGluc3RhbmNlLgorICAgKgorICAgKiA8cD5MYXp5RmllbGQgaXMgbm90IHRocmVhZC1zYWZlIGZvciB3cml0ZSBhY2Nlc3MuIFN5bmNocm9uaXphdGlvbnMgYXJlIG5lZWRlZAorICAgKiB1bmRlciByZWFkL3dyaXRlIHNpdHVhdGlvbnMuCisgICAqLworICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAvLyBEb24ndCBjbGVhciB0aGUgRXh0ZW5zaW9uUmVnaXN0cnkuIEl0IG1pZ2h0IHByb3ZlIHVzZWZ1bCBsYXRlciBvbiB3aGVuIG1lcmdpbmcgaW4gYW5vdGhlcgorICAgIC8vIHZhbHVlLCBidXQgdGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgaXQgd2lsbCBjb250YWluIGFsbCBleHRlbnNpb25zIHRoYXQgd2VyZSBkaXJlY3RseSBzZXQKKyAgICAvLyBvbiB0aGUgdmFsdWVzIHRoYXQgbmVlZCB0byBiZSBtZXJnZWQuCisgICAgZGVsYXllZEJ5dGVzID0gbnVsbDsKKyAgICB2YWx1ZSA9IG51bGw7CisgICAgbWVtb2l6ZWRCeXRlcyA9IG51bGw7CisgIH0KKworICAvKioKKyAgICogT3ZlcnJpZGVzIHRoZSBjb250ZW50cyBvZiB0aGlzIExhenlGaWVsZC4KKyAgICoKKyAgICogPHA+TGF6eUZpZWxkIGlzIG5vdCB0aHJlYWQtc2FmZSBmb3Igd3JpdGUgYWNjZXNzLiBTeW5jaHJvbml6YXRpb25zIGFyZSBuZWVkZWQKKyAgICogdW5kZXIgcmVhZC93cml0ZSBzaXR1YXRpb25zLgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0KExhenlGaWVsZExpdGUgb3RoZXIpIHsKKyAgICB0aGlzLmRlbGF5ZWRCeXRlcyA9IG90aGVyLmRlbGF5ZWRCeXRlczsKKyAgICB0aGlzLnZhbHVlID0gb3RoZXIudmFsdWU7CisgICAgdGhpcy5tZW1vaXplZEJ5dGVzID0gb3RoZXIubWVtb2l6ZWRCeXRlczsKKyAgICAvLyBJZiB0aGUgb3RoZXIgTGF6eUZpZWxkTGl0ZSB3YXMgY3JlYXRlZCBieSBkaXJlY3RseSBzZXR0aW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiBmaXJzdCBieQorICAgIC8vIHBhcnNpbmcsIHRoZW4gaXQgd2lsbCBub3QgaGF2ZSBhbiBleHRlbnNpb25SZWdpc3RyeS4gSW4gdGhpcyBjYXNlIHdlIGhvbGQgb24gdG8gdGhlIGV4aXN0aW5nCisgICAgLy8gZXh0ZW5zaW9uUmVnaXN0cnksIHdoaWNoIGhhcyBubyBndWFyYW50ZWVzIHRoYXQgaXQgaGFzIGFsbCB0aGUgZXh0ZW5zaW9ucyB0aGF0IHdpbGwgYmUKKyAgICAvLyBkaXJlY3RseSBzZXQgb24gdGhlIHZhbHVlLgorICAgIGlmIChvdGhlci5leHRlbnNpb25SZWdpc3RyeSAhPSBudWxsKSB7CisgICAgICB0aGlzLmV4dGVuc2lvblJlZ2lzdHJ5ID0gb3RoZXIuZXh0ZW5zaW9uUmVnaXN0cnk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgbWVzc2FnZSBpbnN0YW5jZS4gSXQgbWF5IGRvIHNvbWUgdGhyZWFkLXNhZmUgZGVsYXllZCBwYXJzaW5nIG9mIGJ5dGVzLgorICAgKgorICAgKiBAcGFyYW0gZGVmYXVsdEluc3RhbmNlIGl0cyBtZXNzYWdlJ3MgZGVmYXVsdCBpbnN0YW5jZS4gSXQncyBhbHNvIHVzZWQgdG8gZ2V0IHBhcnNlciBmb3IgdGhlCisgICAqIG1lc3NhZ2UgdHlwZS4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlTGl0ZSBnZXRWYWx1ZShNZXNzYWdlTGl0ZSBkZWZhdWx0SW5zdGFuY2UpIHsKKyAgICBlbnN1cmVJbml0aWFsaXplZChkZWZhdWx0SW5zdGFuY2UpOworICAgIHJldHVybiB2YWx1ZTsKKyAgfQorCisgIC8qKgorICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgaW5zdGFuY2UgYW5kIHJldHVybnMgdGhlIG9sZCB2YWx1ZSB3aXRob3V0IGRlbGF5IHBhcnNpbmcgYW55dGhpbmcuCisgICAqCisgICAqIDxwPkxhenlGaWVsZCBpcyBub3QgdGhyZWFkLXNhZmUgZm9yIHdyaXRlIGFjY2Vzcy4gU3luY2hyb25pemF0aW9ucyBhcmUgbmVlZGVkCisgICAqIHVuZGVyIHJlYWQvd3JpdGUgc2l0dWF0aW9ucy4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlTGl0ZSBzZXRWYWx1ZShNZXNzYWdlTGl0ZSB2YWx1ZSkgeworICAgIE1lc3NhZ2VMaXRlIG9yaWdpbmFsVmFsdWUgPSB0aGlzLnZhbHVlOworICAgIHRoaXMuZGVsYXllZEJ5dGVzID0gbnVsbDsKKyAgICB0aGlzLm1lbW9pemVkQnl0ZXMgPSBudWxsOworICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICByZXR1cm4gb3JpZ2luYWxWYWx1ZTsKKyAgfQorCisgIC8qKgorICAgKiBNZXJnZXMgYW5vdGhlciBpbnN0YW5jZSdzIGNvbnRlbnRzLiBJbiBzb21lIGNhc2VzIG1heSBkcm9wIHNvbWUgZXh0ZW5zaW9ucyBpZiBib3RoIGZpZWxkcworICAgKiBjb250YWluIGRhdGEuIElmIHRoZSBvdGhlciBmaWVsZCBoYXMgYW4ge0Bjb2RlIEV4dGVuc2lvblJlZ2lzdHJ5fSBidXQgdGhpcyBkb2VzIG5vdCwgdGhlbiB0aGlzCisgICAqIGZpZWxkIHdpbGwgY29weSBvdmVyIHRoYXQge0Bjb2RlIEV4dGVuc2lvblJlZ2lzdHJ5fS4KKyAgICoKKyAgICogPHA+TGF6eUZpZWxkIGlzIG5vdCB0aHJlYWQtc2FmZSBmb3Igd3JpdGUgYWNjZXNzLiBTeW5jaHJvbml6YXRpb25zIGFyZSBuZWVkZWQKKyAgICogdW5kZXIgcmVhZC93cml0ZSBzaXR1YXRpb25zLgorICAgKi8KKyAgcHVibGljIHZvaWQgbWVyZ2UoTGF6eUZpZWxkTGl0ZSBvdGhlcikgeworICAgIGlmIChvdGhlci5jb250YWluc0RlZmF1bHRJbnN0YW5jZSgpKSB7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKHRoaXMuY29udGFpbnNEZWZhdWx0SW5zdGFuY2UoKSkgeworICAgICAgc2V0KG90aGVyKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBJZiB0aGUgb3RoZXIgZmllbGQgaGFzIGFuIGV4dGVuc2lvbiByZWdpc3RyeSBidXQgdGhpcyBkb2VzIG5vdCwgY29weSBvdmVyIHRoZSBvdGhlciBleHRlbnNpb24KKyAgICAvLyByZWdpc3RyeS4KKyAgICBpZiAodGhpcy5leHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CisgICAgICB0aGlzLmV4dGVuc2lvblJlZ2lzdHJ5ID0gb3RoZXIuZXh0ZW5zaW9uUmVnaXN0cnk7CisgICAgfQorCisgICAgLy8gSW4gdGhlIGNhc2UgdGhhdCBib3RoIG9mIHRoZW0gYXJlIG5vdCBwYXJzZWQgd2Ugc2ltcGx5IGNvbmNhdGVuYXRlIHRoZSBieXRlcyB0byBzYXZlIHRpbWUuIEluCisgICAgLy8gdGhlIChwcm9iYWJseSByYXJlKSBjYXNlIHRoYXQgdGhleSBoYXZlIGRpZmZlcmVudCBleHRlbnNpb24gcmVnaXN0cmllcyB0aGVyZSBpcyBhIGNoYW5jZSB0aGF0CisgICAgLy8gc29tZSBvZiB0aGUgZXh0ZW5zaW9ucyBtYXkgYmUgZHJvcHBlZCwgYnV0IHRoZSB0cmFkZW9mZiBvZiBtYWtpbmcgdGhpcyBvcGVyYXRpb24gZmFzdCBzZWVtcworICAgIC8vIHRvIG91dHdheSB0aGUgYmVuZWZpdHMgb2YgY29tYmluaW5nIHRoZSBleHRlbnNpb24gcmVnaXN0cmllcywgd2hpY2ggaXMgbm90IG5vcm1hbGx5IGRvbmUgZm9yCisgICAgLy8gbGl0ZSBwcm90b3MgYW55d2F5cy4KKyAgICBpZiAodGhpcy5kZWxheWVkQnl0ZXMgIT0gbnVsbCAmJiBvdGhlci5kZWxheWVkQnl0ZXMgIT0gbnVsbCkgeworICAgICAgdGhpcy5kZWxheWVkQnl0ZXMgPSB0aGlzLmRlbGF5ZWRCeXRlcy5jb25jYXQob3RoZXIuZGVsYXllZEJ5dGVzKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBBdCBsZWFzdCBvbmUgaXMgcGFyc2VkIGFuZCBib3RoIGNvbnRhaW4gZGF0YS4gV2Ugd29uJ3QgZHJvcCBhbnkgZXh0ZW5zaW9ucyBoZXJlIGRpcmVjdGx5LCBidXQKKyAgICAvLyBpbiB0aGUgY2FzZSB0aGF0IHRoZSBleHRlbnNpb24gcmVnaXN0cmllcyBhcmUgbm90IHRoZSBzYW1lIHRoZW4gd2UgbWlnaHQgaW4gdGhlIGZ1dHVyZSBpZiB3ZQorICAgIC8vIG5lZWQgdG8gc2VyaWFsemUgYW5kIHBhcnNlIGEgbWVzc2FnZSBhZ2Fpbi4KKyAgICBpZiAodGhpcy52YWx1ZSA9PSBudWxsICYmIG90aGVyLnZhbHVlICE9IG51bGwpIHsKKyAgICAgIHNldFZhbHVlKG1lcmdlVmFsdWVBbmRCeXRlcyhvdGhlci52YWx1ZSwgdGhpcy5kZWxheWVkQnl0ZXMsIHRoaXMuZXh0ZW5zaW9uUmVnaXN0cnkpKTsKKyAgICAgIHJldHVybjsKKyAgICB9IGVsc2UgaWYgKHRoaXMudmFsdWUgIT0gbnVsbCAmJiBvdGhlci52YWx1ZSA9PSBudWxsKSB7CisgICAgICBzZXRWYWx1ZShtZXJnZVZhbHVlQW5kQnl0ZXModGhpcy52YWx1ZSwgb3RoZXIuZGVsYXllZEJ5dGVzLCBvdGhlci5leHRlbnNpb25SZWdpc3RyeSkpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgaGF2ZSB0d28gZnVsbHkgcGFyc2VkIG1lc3NhZ2VzLiBXZSBjYW4ndCBtZXJnZSBkaXJlY3RseSBmcm9tIG9uZSB0byB0aGUKKyAgICAvLyBvdGhlciBiZWNhdXNlIG9ubHkgZ2VuZXJhdGVkIGJ1aWxkZXIgY29kZSBjb250YWlucyBtZXRob2RzIHRvIG1lcmdlRnJvbSBhbm90aGVyIHBhcnNlZAorICAgIC8vIG1lc3NhZ2UuIFdlIGhhdmUgdG8gc2VyaWFsaXplIG9uZSBpbnN0YW5jZSBhbmQgdGhlbiBtZXJnZSB0aGUgYnl0ZXMgaW50byB0aGUgb3RoZXIuIFRoaXMgbWF5CisgICAgLy8gZHJvcCBleHRlbnNpb25zIGZyb20gb25lIG9mIHRoZSBtZXNzYWdlcyBpZiBvbmUgb2YgdGhlIHZhbHVlcyBoYWQgYW4gZXh0ZW5zaW9uIHNldCBvbiBpdAorICAgIC8vIGRpcmVjdGx5LgorICAgIC8vCisgICAgLy8gVG8gbWl0aWdhdGUgdGhpcyB3ZSBwcmVmZXIgc2VyaWFsaXppbmcgYSBtZXNzYWdlIHRoYXQgaGFzIGFuIGV4dGVuc2lvbiByZWdpc3RyeSwgYW5kCisgICAgLy8gdGhlcmVmb3JlIGEgY2hhbmNlIHRoYXQgYWxsIGV4dGVuc2lvbnMgc2V0IG9uIGl0IGFyZSBpbiB0aGF0IHJlZ2lzdHJ5LgorICAgIC8vCisgICAgLy8gTk9URTogVGhlIGNoZWNrIGZvciBvdGhlci5leHRlbnNpb25SZWdpc3RyeSBub3QgYmVpbmcgbnVsbCBtdXN0IGNvbWUgZmlyc3QgYmVjYXVzZSBhdCB0aGlzCisgICAgLy8gcG9pbnQgaW4gdGltZSBpZiBvdGhlci5leHRlbnNpb25SZWdpc3RyeSBpcyBub3QgbnVsbCB0aGVuIHRoaXMuZXh0ZW5zaW9uUmVnaXN0cnkgd2lsbCBub3QgYmUKKyAgICAvLyBudWxsIGVpdGhlci4KKyAgICBpZiAob3RoZXIuZXh0ZW5zaW9uUmVnaXN0cnkgIT0gbnVsbCkgeworICAgICAgc2V0VmFsdWUobWVyZ2VWYWx1ZUFuZEJ5dGVzKHRoaXMudmFsdWUsIG90aGVyLnRvQnl0ZVN0cmluZygpLCBvdGhlci5leHRlbnNpb25SZWdpc3RyeSkpOworICAgICAgcmV0dXJuOworICAgIH0gZWxzZSBpZiAodGhpcy5leHRlbnNpb25SZWdpc3RyeSAhPSBudWxsKSB7CisgICAgICBzZXRWYWx1ZShtZXJnZVZhbHVlQW5kQnl0ZXMob3RoZXIudmFsdWUsIHRoaXMudG9CeXRlU3RyaW5nKCksIHRoaXMuZXh0ZW5zaW9uUmVnaXN0cnkpKTsKKyAgICAgIHJldHVybjsKKyAgICB9IGVsc2UgeworICAgICAgLy8gQWxsIGV4dGVuc2lvbnMgZnJvbSB0aGUgb3RoZXIgbWVzc2FnZSB3aWxsIGJlIGRyb3BwZWQgYmVjYXVzZSB3ZSBoYXZlIG5vIHJlZ2lzdHJ5LgorICAgICAgc2V0VmFsdWUobWVyZ2VWYWx1ZUFuZEJ5dGVzKHRoaXMudmFsdWUsIG90aGVyLnRvQnl0ZVN0cmluZygpLCBFTVBUWV9SRUdJU1RSWSkpOworICAgICAgcmV0dXJuOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1lc3NhZ2VMaXRlIG1lcmdlVmFsdWVBbmRCeXRlcygKKyAgICAgIE1lc3NhZ2VMaXRlIHZhbHVlLCBCeXRlU3RyaW5nIG90aGVyQnl0ZXMsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gdmFsdWUudG9CdWlsZGVyKCkubWVyZ2VGcm9tKG90aGVyQnl0ZXMsIGV4dGVuc2lvblJlZ2lzdHJ5KS5idWlsZCgpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBOb3RoaW5nIGlzIGxvZ2dlZCBhbmQgbm8gZXhjZXB0aW9ucyBhcmUgdGhyb3duLiBDbGllbnRzIHdpbGwgYmUgdW5hd2FyZSB0aGF0IGEgcHJvdG8KKyAgICAgIC8vIHdhcyBpbnZhbGlkLgorICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTZXRzIHRoaXMgZmllbGQgd2l0aCBieXRlcyB0byBkZWxheS1wYXJzZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEJ5dGVTdHJpbmcoQnl0ZVN0cmluZyBieXRlcywgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KSB7CisgICAgY2hlY2tBcmd1bWVudHMoZXh0ZW5zaW9uUmVnaXN0cnksIGJ5dGVzKTsKKyAgICB0aGlzLmRlbGF5ZWRCeXRlcyA9IGJ5dGVzOworICAgIHRoaXMuZXh0ZW5zaW9uUmVnaXN0cnkgPSBleHRlbnNpb25SZWdpc3RyeTsKKyAgICB0aGlzLnZhbHVlID0gbnVsbDsKKyAgICB0aGlzLm1lbW9pemVkQnl0ZXMgPSBudWxsOworICB9CisKKyAgLyoqCisgICAqIER1ZSB0byB0aGUgb3B0aW9uYWwgZmllbGQgY2FuIGJlIGR1cGxpY2F0ZWQgYXQgdGhlIGVuZCBvZiBzZXJpYWxpemVkCisgICAqIGJ5dGVzLCB3aGljaCB3aWxsIG1ha2UgdGhlIHNlcmlhbGl6ZWQgc2l6ZSBjaGFuZ2VkIGFmdGVyIExhenlGaWVsZAorICAgKiBwYXJzZWQuIEJlIGNhcmVmdWwgd2hlbiB1c2luZyB0aGlzIG1ldGhvZC4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CisgICAgaWYgKGRlbGF5ZWRCeXRlcyAhPSBudWxsKSB7CisgICAgICByZXR1cm4gZGVsYXllZEJ5dGVzLnNpemUoKTsKKyAgICB9IGVsc2UgaWYgKG1lbW9pemVkQnl0ZXMgIT0gbnVsbCkgeworICAgICAgcmV0dXJuIG1lbW9pemVkQnl0ZXMuc2l6ZSgpOworICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgcmV0dXJuIHZhbHVlLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIGEgQnl0ZXNTdHJpbmcgZm9yIHRoaXMgZmllbGQgaW4gYSB0aHJlYWQtc2FmZSB3YXkuCisgICAqLworICBwdWJsaWMgQnl0ZVN0cmluZyB0b0J5dGVTdHJpbmcoKSB7CisgICAgaWYgKGRlbGF5ZWRCeXRlcyAhPSBudWxsKSB7CisgICAgICByZXR1cm4gZGVsYXllZEJ5dGVzOworICAgIH0KKyAgICBpZiAobWVtb2l6ZWRCeXRlcyAhPSBudWxsKSB7CisgICAgICByZXR1cm4gbWVtb2l6ZWRCeXRlczsKKyAgICB9CisgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICBpZiAobWVtb2l6ZWRCeXRlcyAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBtZW1vaXplZEJ5dGVzOworICAgICAgfQorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgbWVtb2l6ZWRCeXRlcyA9IEJ5dGVTdHJpbmcuRU1QVFk7CisgICAgICB9IGVsc2UgeworICAgICAgICBtZW1vaXplZEJ5dGVzID0gdmFsdWUudG9CeXRlU3RyaW5nKCk7CisgICAgICB9CisgICAgICByZXR1cm4gbWVtb2l6ZWRCeXRlczsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTWlnaHQgbGF6aWx5IHBhcnNlIHRoZSBieXRlcyB0aGF0IHdlcmUgcHJldmlvdXNseSBwYXNzZWQgaW4uIElzIHRocmVhZC1zYWZlLgorICAgKi8KKyAgcHJvdGVjdGVkIHZvaWQgZW5zdXJlSW5pdGlhbGl6ZWQoTWVzc2FnZUxpdGUgZGVmYXVsdEluc3RhbmNlKSB7CisgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBpZiAoZGVsYXllZEJ5dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAvLyBUaGUgZXh0ZW5zaW9uUmVnaXN0cnkgc2hvdWxkbid0IGJlIG51bGwgaGVyZSBzaW5jZSB3ZSBoYXZlIGRlbGF5ZWRCeXRlcy4KKyAgICAgICAgICBNZXNzYWdlTGl0ZSBwYXJzZWRWYWx1ZSA9IGRlZmF1bHRJbnN0YW5jZS5nZXRQYXJzZXJGb3JUeXBlKCkKKyAgICAgICAgICAgICAgLnBhcnNlRnJvbShkZWxheWVkQnl0ZXMsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgICAgICB0aGlzLnZhbHVlID0gcGFyc2VkVmFsdWU7CisgICAgICAgICAgdGhpcy5tZW1vaXplZEJ5dGVzID0gZGVsYXllZEJ5dGVzOworICAgICAgICAgIHRoaXMuZGVsYXllZEJ5dGVzID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aGlzLnZhbHVlID0gZGVmYXVsdEluc3RhbmNlOworICAgICAgICAgIHRoaXMubWVtb2l6ZWRCeXRlcyA9IEJ5dGVTdHJpbmcuRU1QVFk7CisgICAgICAgICAgdGhpcy5kZWxheWVkQnl0ZXMgPSBudWxsOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBOb3RoaW5nIGlzIGxvZ2dlZCBhbmQgbm8gZXhjZXB0aW9ucyBhcmUgdGhyb3duLiBDbGllbnRzIHdpbGwgYmUgdW5hd2FyZSB0aGF0IHRoaXMgcHJvdG8KKyAgICAgICAgLy8gd2FzIGludmFsaWQuCisgICAgICAgIHRoaXMudmFsdWUgPSBkZWZhdWx0SW5zdGFuY2U7CisgICAgICAgIHRoaXMubWVtb2l6ZWRCeXRlcyA9IEJ5dGVTdHJpbmcuRU1QVFk7CisgICAgICAgIHRoaXMuZGVsYXllZEJ5dGVzID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisgIH0KKworCisgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tBcmd1bWVudHMoRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LCBCeXRlU3RyaW5nIGJ5dGVzKSB7CisgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZm91bmQgbnVsbCBFeHRlbnNpb25SZWdpc3RyeSIpOworICAgIH0KKyAgICBpZiAoYnl0ZXMgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmb3VuZCBudWxsIEJ5dGVTdHJpbmciKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdBcnJheUxpc3QuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdBcnJheUxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDQwYTUxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eVN0cmluZ0FycmF5TGlzdC5qYXZhCkBAIC0wLDAgKzEsMzcxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5SYW5kb21BY2Nlc3M7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIExhenlTdHJpbmdMaXN0fSB0aGF0IHdyYXBzIGFuIEFycmF5TGlzdC4gRWFjaAorICogZWxlbWVudCBpcyBvbmUgb2YgU3RyaW5nLCBCeXRlU3RyaW5nLCBvciBieXRlW10uIEl0IGNhY2hlcyB0aGUgbGFzdCBvbmUKKyAqIHJlcXVlc3RlZCB3aGljaCBpcyBtb3N0IGxpa2VseSB0aGUgb25lIG5lZWRlZCBuZXh0LiBUaGlzIG1pbmltaXplcyBtZW1vcnkKKyAqIHVzYWdlIHdoaWxlIHNhdGlzZnlpbmcgdGhlIG1vc3QgY29tbW9uIHVzZSBjYXNlcy4KKyAqIDxwPgorICogPHN0cm9uZz5Ob3RlIHRoYXQgdGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBub3Qgc3luY2hyb25pemVkLjwvc3Ryb25nPgorICogSWYgbXVsdGlwbGUgdGhyZWFkcyBhY2Nlc3MgYW4gPHR0PkFycmF5TGlzdDwvdHQ+IGluc3RhbmNlIGNvbmN1cnJlbnRseSwKKyAqIGFuZCBhdCBsZWFzdCBvbmUgb2YgdGhlIHRocmVhZHMgbW9kaWZpZXMgdGhlIGxpc3Qgc3RydWN0dXJhbGx5LCBpdAorICogPGk+bXVzdDwvaT4gYmUgc3luY2hyb25pemVkIGV4dGVybmFsbHkuICAoQSBzdHJ1Y3R1cmFsIG1vZGlmaWNhdGlvbiBpcworICogYW55IG9wZXJhdGlvbiB0aGF0IGFkZHMgb3IgZGVsZXRlcyBvbmUgb3IgbW9yZSBlbGVtZW50cywgb3IgZXhwbGljaXRseQorICogcmVzaXplcyB0aGUgYmFja2luZyBhcnJheTsgbWVyZWx5IHNldHRpbmcgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQgaXMgbm90CisgKiBhIHN0cnVjdHVyYWwgbW9kaWZpY2F0aW9uLikgIFRoaXMgaXMgdHlwaWNhbGx5IGFjY29tcGxpc2hlZCBieQorICogc3luY2hyb25pemluZyBvbiBzb21lIG9iamVjdCB0aGF0IG5hdHVyYWxseSBlbmNhcHN1bGF0ZXMgdGhlIGxpc3QuCisgKiA8cD4KKyAqIElmIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBhY2Nlc3NlZCB2aWEgY29uY3VycmVudCByZWFkcywgdGhpcyBpcyB0aHJlYWQgc2FmZS4KKyAqIENvbnZlcnNpb25zIGFyZSBkb25lIGluIGEgdGhyZWFkIHNhZmUgbWFubmVyLiBJdCdzIHBvc3NpYmxlIHRoYXQgdGhlCisgKiBjb252ZXJzaW9uIG1heSBoYXBwZW4gbW9yZSB0aGFuIG9uY2UgaWYgdHdvIHRocmVhZHMgYXR0ZW1wdCB0byBhY2Nlc3MgdGhlCisgKiBzYW1lIGVsZW1lbnQgYW5kIHRoZSBtb2RpZmljYXRpb25zIHdlcmUgbm90IHZpc2libGUgdG8gZWFjaCBvdGhlciwgYnV0IHRoaXMKKyAqIHdpbGwgbm90IHJlc3VsdCBpbiBhbnkgY29ycnVwdGlvbiBvZiB0aGUgbGlzdCBvciBjaGFuZ2UgaW4gYmVoYXZpb3Igb3RoZXIKKyAqIHRoYW4gcGVyZm9ybWFuY2UuCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKi8KK3B1YmxpYyBjbGFzcyBMYXp5U3RyaW5nQXJyYXlMaXN0IGV4dGVuZHMgQWJzdHJhY3RMaXN0PFN0cmluZz4KKyAgICBpbXBsZW1lbnRzIExhenlTdHJpbmdMaXN0LCBSYW5kb21BY2Nlc3MgeworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgTGF6eVN0cmluZ0xpc3QgRU1QVFkgPQorICAgICAgbmV3IExhenlTdHJpbmdBcnJheUxpc3QoKS5nZXRVbm1vZGlmaWFibGVWaWV3KCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0PE9iamVjdD4gbGlzdDsKKworICBwdWJsaWMgTGF6eVN0cmluZ0FycmF5TGlzdCgpIHsKKyAgICBsaXN0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgIH0KKworICBwdWJsaWMgTGF6eVN0cmluZ0FycmF5TGlzdChpbnQgaW50aWFsQ2FwYWNpdHkpIHsKKyAgICBsaXN0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KGludGlhbENhcGFjaXR5KTsKKyAgfQorCisgIHB1YmxpYyBMYXp5U3RyaW5nQXJyYXlMaXN0KExhenlTdHJpbmdMaXN0IGZyb20pIHsKKyAgICBsaXN0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KGZyb20uc2l6ZSgpKTsKKyAgICBhZGRBbGwoZnJvbSk7CisgIH0KKworICBwdWJsaWMgTGF6eVN0cmluZ0FycmF5TGlzdChMaXN0PFN0cmluZz4gZnJvbSkgeworICAgIGxpc3QgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oZnJvbSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBnZXQoaW50IGluZGV4KSB7CisgICAgT2JqZWN0IG8gPSBsaXN0LmdldChpbmRleCk7CisgICAgaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgIHJldHVybiAoU3RyaW5nKSBvOworICAgIH0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIEJ5dGVTdHJpbmcpIHsKKyAgICAgIEJ5dGVTdHJpbmcgYnMgPSAoQnl0ZVN0cmluZykgbzsKKyAgICAgIFN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CisgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgeworICAgICAgICBsaXN0LnNldChpbmRleCwgcyk7CisgICAgICB9CisgICAgICByZXR1cm4gczsKKyAgICB9IGVsc2UgeworICAgICAgYnl0ZVtdIGJhID0gKGJ5dGVbXSkgbzsKKyAgICAgIFN0cmluZyBzID0gSW50ZXJuYWwudG9TdHJpbmdVdGY4KGJhKTsKKyAgICAgIGlmIChJbnRlcm5hbC5pc1ZhbGlkVXRmOChiYSkpIHsKKyAgICAgICAgbGlzdC5zZXQoaW5kZXgsIHMpOworICAgICAgfQorICAgICAgcmV0dXJuIHM7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gbGlzdC5zaXplKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBzZXQoaW50IGluZGV4LCBTdHJpbmcgcykgeworICAgIE9iamVjdCBvID0gbGlzdC5zZXQoaW5kZXgsIHMpOworICAgIHJldHVybiBhc1N0cmluZyhvKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBTdHJpbmcgZWxlbWVudCkgeworICAgIGxpc3QuYWRkKGluZGV4LCBlbGVtZW50KTsKKyAgICBtb2RDb3VudCsrOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBTdHJpbmc+IGMpIHsKKyAgICAvLyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBBYnN0cmFjdENvbGxlY3Rpb24uYWRkQWxsKENvbGxlY3Rpb24pCisgICAgLy8gZGVsZWdhdGVzIHRvIGFkZChPYmplY3QpLiBUaGlzIGltcGxlbWVudGF0aW9uIGluc3RlYWQgZGVsZWdhdGVzIHRvCisgICAgLy8gYWRkQWxsKGludCwgQ29sbGVjdGlvbiksIHdoaWNoIG1ha2VzIGEgc3BlY2lhbCBjYXNlIGZvciBDb2xsZWN0aW9ucworICAgIC8vIHdoaWNoIGFyZSBpbnN0YW5jZXMgb2YgTGF6eVN0cmluZ0xpc3QuCisgICAgcmV0dXJuIGFkZEFsbChzaXplKCksIGMpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGFkZEFsbChpbnQgaW5kZXgsIENvbGxlY3Rpb248PyBleHRlbmRzIFN0cmluZz4gYykgeworICAgIC8vIFdoZW4gY29weWluZyBmcm9tIGFub3RoZXIgTGF6eVN0cmluZ0xpc3QsIGRpcmVjdGx5IGNvcHkgdGhlIHVuZGVybHlpbmcKKyAgICAvLyBlbGVtZW50cyByYXRoZXIgdGhhbiBmb3JjaW5nIGVhY2ggZWxlbWVudCB0byBiZSBkZWNvZGVkIHRvIGEgU3RyaW5nLgorICAgIENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbiA9IGMgaW5zdGFuY2VvZiBMYXp5U3RyaW5nTGlzdAorICAgICAgICA/ICgoTGF6eVN0cmluZ0xpc3QpIGMpLmdldFVuZGVybHlpbmdFbGVtZW50cygpIDogYzsKKyAgICBib29sZWFuIHJldCA9IGxpc3QuYWRkQWxsKGluZGV4LCBjb2xsZWN0aW9uKTsKKyAgICBtb2RDb3VudCsrOworICAgIHJldHVybiByZXQ7CisgIH0KKworICAvLyBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gYWRkQWxsQnl0ZVN0cmluZyhDb2xsZWN0aW9uPD8gZXh0ZW5kcyBCeXRlU3RyaW5nPiB2YWx1ZXMpIHsKKyAgICBib29sZWFuIHJldCA9IGxpc3QuYWRkQWxsKHZhbHVlcyk7CisgICAgbW9kQ291bnQrKzsKKyAgICByZXR1cm4gcmV0OworICB9CisKKyAgLy8gQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGFkZEFsbEJ5dGVBcnJheShDb2xsZWN0aW9uPGJ5dGVbXT4gYykgeworICAgIGJvb2xlYW4gcmV0ID0gbGlzdC5hZGRBbGwoYyk7CisgICAgbW9kQ291bnQrKzsKKyAgICByZXR1cm4gcmV0OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgcmVtb3ZlKGludCBpbmRleCkgeworICAgIE9iamVjdCBvID0gbGlzdC5yZW1vdmUoaW5kZXgpOworICAgIG1vZENvdW50Kys7CisgICAgcmV0dXJuIGFzU3RyaW5nKG8pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgIGxpc3QuY2xlYXIoKTsKKyAgICBtb2RDb3VudCsrOworICB9CisKKyAgLy8gQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGFkZChCeXRlU3RyaW5nIGVsZW1lbnQpIHsKKyAgICBsaXN0LmFkZChlbGVtZW50KTsKKyAgICBtb2RDb3VudCsrOworICB9CisgIAorICAvLyBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgYWRkKGJ5dGVbXSBlbGVtZW50KSB7CisgICAgbGlzdC5hZGQoZWxlbWVudCk7CisgICAgbW9kQ291bnQrKzsKKyAgfQorCisgIC8vIEBPdmVycmlkZQorICBwdWJsaWMgQnl0ZVN0cmluZyBnZXRCeXRlU3RyaW5nKGludCBpbmRleCkgeworICAgIE9iamVjdCBvID0gbGlzdC5nZXQoaW5kZXgpOworICAgIEJ5dGVTdHJpbmcgYiA9IGFzQnl0ZVN0cmluZyhvKTsKKyAgICBpZiAoYiAhPSBvKSB7CisgICAgICBsaXN0LnNldChpbmRleCwgYik7CisgICAgfQorICAgIHJldHVybiBiOworICB9CisgIAorICAvLyBAT3ZlcnJpZGUKKyAgcHVibGljIGJ5dGVbXSBnZXRCeXRlQXJyYXkoaW50IGluZGV4KSB7CisgICAgT2JqZWN0IG8gPSBsaXN0LmdldChpbmRleCk7CisgICAgYnl0ZVtdIGIgPSBhc0J5dGVBcnJheShvKTsKKyAgICBpZiAoYiAhPSBvKSB7CisgICAgICBsaXN0LnNldChpbmRleCwgYik7CisgICAgfQorICAgIHJldHVybiBiOworICB9CisKKyAgLy8gQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldChpbnQgaW5kZXgsIEJ5dGVTdHJpbmcgcykgeworICAgIGxpc3Quc2V0KGluZGV4LCBzKTsKKyAgfQorCisgIC8vIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXQoaW50IGluZGV4LCBieXRlW10gcykgeworICAgIGxpc3Quc2V0KGluZGV4LCBzKTsKKyAgfQorCisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGFzU3RyaW5nKE9iamVjdCBvKSB7CisgICAgaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgIHJldHVybiAoU3RyaW5nKSBvOworICAgIH0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIEJ5dGVTdHJpbmcpIHsKKyAgICAgIHJldHVybiAoKEJ5dGVTdHJpbmcpIG8pLnRvU3RyaW5nVXRmOCgpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gSW50ZXJuYWwudG9TdHJpbmdVdGY4KChieXRlW10pIG8pOworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgQnl0ZVN0cmluZyBhc0J5dGVTdHJpbmcoT2JqZWN0IG8pIHsKKyAgICBpZiAobyBpbnN0YW5jZW9mIEJ5dGVTdHJpbmcpIHsKKyAgICAgIHJldHVybiAoQnl0ZVN0cmluZykgbzsKKyAgICB9IGVsc2UgaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgIHJldHVybiBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgoU3RyaW5nKSBvKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIEJ5dGVTdHJpbmcuY29weUZyb20oKGJ5dGVbXSkgbyk7CisgICAgfQorICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBieXRlW10gYXNCeXRlQXJyYXkoT2JqZWN0IG8pIHsKKyAgICBpZiAobyBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgcmV0dXJuIChieXRlW10pIG87CisgICAgfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICByZXR1cm4gSW50ZXJuYWwudG9CeXRlQXJyYXkoKFN0cmluZykgbyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAoKEJ5dGVTdHJpbmcpIG8pLnRvQnl0ZUFycmF5KCk7CisgICAgfQorICB9CisKKyAgLy8gQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0PD8+IGdldFVuZGVybHlpbmdFbGVtZW50cygpIHsKKyAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsaXN0KTsKKyAgfQorCisgIC8vIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBtZXJnZUZyb20oTGF6eVN0cmluZ0xpc3Qgb3RoZXIpIHsKKyAgICBmb3IgKE9iamVjdCBvIDogb3RoZXIuZ2V0VW5kZXJseWluZ0VsZW1lbnRzKCkpIHsKKyAgICAgIGlmIChvIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgIGJ5dGVbXSBiID0gKGJ5dGVbXSkgbzsKKyAgICAgICAgLy8gQnl0ZSBhcnJheSdzIGNvbnRlbnQgaXMgbXV0YWJsZSBzbyB0aGV5IHNob3VsZCBiZSBjb3BpZWQgcmF0aGVyIHRoYW4KKyAgICAgICAgLy8gc2hhcmVkIHdoZW4gbWVyZ2luZyBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIuCisgICAgICAgIGxpc3QuYWRkKEFycmF5cy5jb3B5T2YoYiwgYi5sZW5ndGgpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGxpc3QuYWRkKG8pOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJ5dGVBcnJheUxpc3RWaWV3IGV4dGVuZHMgQWJzdHJhY3RMaXN0PGJ5dGVbXT4KKyAgICAgIGltcGxlbWVudHMgUmFuZG9tQWNjZXNzIHsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8T2JqZWN0PiBsaXN0OworICAgIAorICAgIEJ5dGVBcnJheUxpc3RWaWV3KExpc3Q8T2JqZWN0PiBsaXN0KSB7CisgICAgICB0aGlzLmxpc3QgPSBsaXN0OworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldChpbnQgaW5kZXgpIHsKKyAgICAgIE9iamVjdCBvID0gbGlzdC5nZXQoaW5kZXgpOworICAgICAgYnl0ZVtdIGIgPSBhc0J5dGVBcnJheShvKTsKKyAgICAgIGlmIChiICE9IG8pIHsKKyAgICAgICAgbGlzdC5zZXQoaW5kZXgsIGIpOworICAgICAgfQorICAgICAgcmV0dXJuIGI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgcmV0dXJuIGxpc3Quc2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gc2V0KGludCBpbmRleCwgYnl0ZVtdIHMpIHsKKyAgICAgIE9iamVjdCBvID0gbGlzdC5zZXQoaW5kZXgsIHMpOworICAgICAgbW9kQ291bnQrKzsKKyAgICAgIHJldHVybiBhc0J5dGVBcnJheShvKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBieXRlW10gcykgeworICAgICAgbGlzdC5hZGQoaW5kZXgsIHMpOworICAgICAgbW9kQ291bnQrKzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIHJlbW92ZShpbnQgaW5kZXgpIHsKKyAgICAgIE9iamVjdCBvID0gbGlzdC5yZW1vdmUoaW5kZXgpOworICAgICAgbW9kQ291bnQrKzsKKyAgICAgIHJldHVybiBhc0J5dGVBcnJheShvKTsKKyAgICB9CisgIH0KKyAgCisgIC8vIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdDxieXRlW10+IGFzQnl0ZUFycmF5TGlzdCgpIHsKKyAgICByZXR1cm4gbmV3IEJ5dGVBcnJheUxpc3RWaWV3KGxpc3QpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQnl0ZVN0cmluZ0xpc3RWaWV3IGV4dGVuZHMgQWJzdHJhY3RMaXN0PEJ5dGVTdHJpbmc+CisgICAgICBpbXBsZW1lbnRzIFJhbmRvbUFjY2VzcyB7CisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PE9iamVjdD4gbGlzdDsKKworICAgIEJ5dGVTdHJpbmdMaXN0VmlldyhMaXN0PE9iamVjdD4gbGlzdCkgeworICAgICAgdGhpcy5saXN0ID0gbGlzdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZVN0cmluZyBnZXQoaW50IGluZGV4KSB7CisgICAgICBPYmplY3QgbyA9IGxpc3QuZ2V0KGluZGV4KTsKKyAgICAgIEJ5dGVTdHJpbmcgYiA9IGFzQnl0ZVN0cmluZyhvKTsKKyAgICAgIGlmIChiICE9IG8pIHsKKyAgICAgICAgbGlzdC5zZXQoaW5kZXgsIGIpOworICAgICAgfQorICAgICAgcmV0dXJuIGI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgcmV0dXJuIGxpc3Quc2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlU3RyaW5nIHNldChpbnQgaW5kZXgsIEJ5dGVTdHJpbmcgcykgeworICAgICAgT2JqZWN0IG8gPSBsaXN0LnNldChpbmRleCwgcyk7CisgICAgICBtb2RDb3VudCsrOworICAgICAgcmV0dXJuIGFzQnl0ZVN0cmluZyhvKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBCeXRlU3RyaW5nIHMpIHsKKyAgICAgIGxpc3QuYWRkKGluZGV4LCBzKTsKKyAgICAgIG1vZENvdW50Kys7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVTdHJpbmcgcmVtb3ZlKGludCBpbmRleCkgeworICAgICAgT2JqZWN0IG8gPSBsaXN0LnJlbW92ZShpbmRleCk7CisgICAgICBtb2RDb3VudCsrOworICAgICAgcmV0dXJuIGFzQnl0ZVN0cmluZyhvKTsKKyAgICB9CisgIH0KKworICAvLyBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3Q8Qnl0ZVN0cmluZz4gYXNCeXRlU3RyaW5nTGlzdCgpIHsKKyAgICByZXR1cm4gbmV3IEJ5dGVTdHJpbmdMaXN0VmlldyhsaXN0KTsKKyAgfQorCisgIC8vIEBPdmVycmlkZQorICBwdWJsaWMgTGF6eVN0cmluZ0xpc3QgZ2V0VW5tb2RpZmlhYmxlVmlldygpIHsKKyAgICByZXR1cm4gbmV3IFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0KHRoaXMpOworICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdMaXN0LmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5U3RyaW5nTGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzNTEyNmIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5U3RyaW5nTGlzdC5qYXZhCkBAIC0wLDAgKzEsMTYzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogQW4gaW50ZXJmYWNlIGV4dGVuZGluZyB7QGNvZGUgTGlzdDxTdHJpbmc+fSB0aGF0IGFsc28gcHJvdmlkZXMgYWNjZXNzIHRvIHRoZQorICogaXRlbXMgb2YgdGhlIGxpc3QgYXMgVVRGOC1lbmNvZGVkIEJ5dGVTdHJpbmcgb3IgYnl0ZVtdIG9iamVjdHMuIFRoaXMgaXMKKyAqIHVzZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBpbXBsZW1lbnRhdGlvbiB0byBzdXBwb3J0IGxhemlseSBjb252ZXJ0aW5nIGJ5dGVzCisgKiBwYXJzZWQgb3ZlciB0aGUgd2lyZSB0byBTdHJpbmcgb2JqZWN0cyB1bnRpbCBuZWVkZWQgYW5kIGFsc28gaW5jcmVhc2VzIHRoZQorICogZWZmaWNpZW5jeSBvZiBzZXJpYWxpemF0aW9uIGlmIHRoZSBTdHJpbmcgd2FzIG5ldmVyIHJlcXVlc3RlZCBhcyB0aGUKKyAqIEJ5dGVTdHJpbmcgb3IgYnl0ZVtdIGlzIGFscmVhZHkgY2FjaGVkLiBUaGUgQnl0ZVN0cmluZyBtZXRob2RzIGFyZSB1c2VkIGluCisgKiBpbW11dGFibGUgQVBJIG9ubHkgYW5kIGJ5dGVbXSBtZXRob2RzIHVzZWQgaW4gbXV0YWJsZSBBUEkgb25seSBmb3IgdGhleSB1c2UKKyAqIGRpZmZlcmVudCByZXByZXNlbnRhdGlvbnMgZm9yIHN0cmluZy9ieXRlcyBmaWVsZHMuCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTGF6eVN0cmluZ0xpc3QgZXh0ZW5kcyBQcm90b2NvbFN0cmluZ0xpc3QgeworCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyBsaXN0IGFzIGEgQnl0ZVN0cmluZy4KKyAgICoKKyAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybgorICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyBsaXN0CisgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlCisgICAqICAgICAgICAgKHtAY29kZSBpbmRleCA8IDAgfHwgaW5kZXggPj0gc2l6ZSgpfSkKKyAgICovCisgIEJ5dGVTdHJpbmcgZ2V0Qnl0ZVN0cmluZyhpbnQgaW5kZXgpOworICAKKyAgLyoqCisgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbiBpbiB0aGlzIGxpc3QgYXMgYnl0ZVtdLgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuCisgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbiBpbiB0aGlzIGxpc3QKKyAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UKKyAgICogICAgICAgICAoe0Bjb2RlIGluZGV4IDwgMCB8fCBpbmRleCA+PSBzaXplKCl9KQorICAgKi8KKyAgYnl0ZVtdIGdldEJ5dGVBcnJheShpbnQgaW5kZXgpOworCisgIC8qKgorICAgKiBBcHBlbmRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCB0byB0aGUgZW5kIG9mIHRoaXMgbGlzdCAob3B0aW9uYWwKKyAgICogb3BlcmF0aW9uKS4KKyAgICoKKyAgICogQHBhcmFtIGVsZW1lbnQgZWxlbWVudCB0byBiZSBhcHBlbmRlZCB0byB0aGlzIGxpc3QKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgPHR0PmFkZDwvdHQ+IG9wZXJhdGlvbgorICAgKiAgICAgICAgIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBsaXN0CisgICAqLworICB2b2lkIGFkZChCeXRlU3RyaW5nIGVsZW1lbnQpOworCisgIC8qKgorICAgKiBBcHBlbmRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCB0byB0aGUgZW5kIG9mIHRoaXMgbGlzdCAob3B0aW9uYWwKKyAgICogb3BlcmF0aW9uKS4KKyAgICoKKyAgICogQHBhcmFtIGVsZW1lbnQgZWxlbWVudCB0byBiZSBhcHBlbmRlZCB0byB0aGlzIGxpc3QKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgPHR0PmFkZDwvdHQ+IG9wZXJhdGlvbgorICAgKiAgICAgICAgIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBsaXN0CisgICAqLworICB2b2lkIGFkZChieXRlW10gZWxlbWVudCk7CisKKyAgLyoqCisgICAqIFJlcGxhY2VzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyBsaXN0IHdpdGggdGhlCisgICAqIHNwZWNpZmllZCBlbGVtZW50IChvcHRpb25hbCBvcGVyYXRpb24pLgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmVwbGFjZQorICAgKiBAcGFyYW0gZWxlbWVudCB0aGUgZWxlbWVudCB0byBiZSBzdG9yZWQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbgorICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSA8dHQ+c2V0PC90dD4gb3BlcmF0aW9uCisgICAqICAgICAgICAgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGxpc3QKKyAgICogICAgICAgICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UKKyAgICogICAgICAgICAoe0Bjb2RlIGluZGV4IDwgMCB8fCBpbmRleCA+PSBzaXplKCl9KQorICAgKi8KKyAgdm9pZCBzZXQoaW50IGluZGV4LCBCeXRlU3RyaW5nIGVsZW1lbnQpOworICAKKyAgLyoqCisgICAqIFJlcGxhY2VzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyBsaXN0IHdpdGggdGhlCisgICAqIHNwZWNpZmllZCBlbGVtZW50IChvcHRpb25hbCBvcGVyYXRpb24pLgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmVwbGFjZQorICAgKiBAcGFyYW0gZWxlbWVudCB0aGUgZWxlbWVudCB0byBiZSBzdG9yZWQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbgorICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSA8dHQ+c2V0PC90dD4gb3BlcmF0aW9uCisgICAqICAgICAgICAgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGxpc3QKKyAgICogICAgICAgICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UKKyAgICogICAgICAgICAoe0Bjb2RlIGluZGV4IDwgMCB8fCBpbmRleCA+PSBzaXplKCl9KQorICAgKi8KKyAgdm9pZCBzZXQoaW50IGluZGV4LCBieXRlW10gZWxlbWVudCk7CisKKyAgLyoqCisgICAqIEFwcGVuZHMgYWxsIGVsZW1lbnRzIGluIHRoZSBzcGVjaWZpZWQgQnl0ZVN0cmluZyBjb2xsZWN0aW9uIHRvIHRoZSBlbmQgb2YKKyAgICogdGhpcyBsaXN0LgorICAgKgorICAgKiBAcGFyYW0gYyBjb2xsZWN0aW9uIHdob3NlIGVsZW1lbnRzIGFyZSB0byBiZSBhZGRlZCB0byB0aGlzIGxpc3QKKyAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgbGlzdCBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsCisgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIDx0dD5hZGRBbGxCeXRlU3RyaW5nPC90dD4KKyAgICogICAgICAgICBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGxpc3QKKyAgICovCisgIGJvb2xlYW4gYWRkQWxsQnl0ZVN0cmluZyhDb2xsZWN0aW9uPD8gZXh0ZW5kcyBCeXRlU3RyaW5nPiBjKTsKKworICAvKioKKyAgICogQXBwZW5kcyBhbGwgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBieXRlW10gY29sbGVjdGlvbiB0byB0aGUgZW5kIG9mCisgICAqIHRoaXMgbGlzdC4KKyAgICoKKyAgICogQHBhcmFtIGMgY29sbGVjdGlvbiB3aG9zZSBlbGVtZW50cyBhcmUgdG8gYmUgYWRkZWQgdG8gdGhpcyBsaXN0CisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGxpc3QgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbAorICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSA8dHQ+YWRkQWxsQnl0ZUFycmF5PC90dD4KKyAgICogICAgICAgICBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGxpc3QKKyAgICovCisgIGJvb2xlYW4gYWRkQWxsQnl0ZUFycmF5KENvbGxlY3Rpb248Ynl0ZVtdPiBjKTsKKworICAvKioKKyAgICogUmV0dXJucyBhbiB1bm1vZGlmaWFibGUgTGlzdCBvZiB0aGUgdW5kZXJseWluZyBlbGVtZW50cywgZWFjaCBvZiB3aGljaCBpcworICAgKiBlaXRoZXIgYSB7QGNvZGUgU3RyaW5nfSBvciBpdHMgZXF1aXZhbGVudCBVVEYtOCBlbmNvZGVkIHtAY29kZSBCeXRlU3RyaW5nfQorICAgKiBvciBieXRlW10uIEl0IGlzIGFuIGVycm9yIGZvciB0aGUgY2FsbGVyIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQKKyAgICogTGlzdCwgYW5kIGF0dGVtcHRpbmcgdG8gZG8gc28gd2lsbCByZXN1bHQgaW4gYW4KKyAgICoge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICovCisgIExpc3Q8Pz4gZ2V0VW5kZXJseWluZ0VsZW1lbnRzKCk7CisKKyAgLyoqCisgICAqIE1lcmdlcyBhbGwgZWxlbWVudHMgZnJvbSBhbm90aGVyIExhenlTdHJpbmdMaXN0IGludG8gdGhpcyBvbmUuIFRoaXMgbWV0aG9kCisgICAqIGRpZmZlcnMgZnJvbSB7QGxpbmsgI2FkZEFsbChDb2xsZWN0aW9uKX0gb24gdGhhdCB1bmRlcmx5aW5nIGJ5dGUgYXJyYXlzIGFyZQorICAgKiBjb3BpZWQgaW5zdGVhZCBvZiByZWZlcmVuY2Ugc2hhcmVkLiBJbW11dGFibGUgQVBJIGRvZXNuJ3QgbmVlZCB0byB1c2UgdGhpcworICAgKiBtZXRob2QgYXMgYnl0ZVtdIGlzIG5vdCB1c2VkIHRoZXJlIGF0IGFsbC4KKyAgICovCisgIHZvaWQgbWVyZ2VGcm9tKExhenlTdHJpbmdMaXN0IG90aGVyKTsKKworICAvKioKKyAgICogUmV0dXJucyBhIG11dGFibGUgdmlldyBvZiB0aGlzIGxpc3QuIENoYW5nZXMgdG8gdGhlIHZpZXcgd2lsbCBiZSBtYWRlIGludG8KKyAgICogdGhlIG9yaWdpbmFsIGxpc3QuIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gbXV0YWJsZSBBUEkgb25seS4KKyAgICovCisgIExpc3Q8Ynl0ZVtdPiBhc0J5dGVBcnJheUxpc3QoKTsKKworICAvKiogUmV0dXJucyBhbiB1bm1vZGlmaWFibGUgdmlldyBvZiB0aGUgbGlzdC4gKi8KKyAgTGF6eVN0cmluZ0xpc3QgZ2V0VW5tb2RpZmlhYmxlVmlldygpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGl0ZXJhbEJ5dGVTdHJpbmcuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xpdGVyYWxCeXRlU3RyaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg5M2RkZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xpdGVyYWxCeXRlU3RyaW5nLmphdmEKQEAgLTAsMCArMSwzNzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIHtAbGluayBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmd9IGJhY2tlZCBieSBhCisgKiBzaW5nbGUgYXJyYXkgb2YgYnl0ZXMsIGNvbnRpZ3VvdXMgaW4gbWVtb3J5LiBJdCBzdXBwb3J0cyBzdWJzdHJpbmcgYnkKKyAqIHBvaW50aW5nIHRvIG9ubHkgYSBzdWItcmFuZ2Ugb2YgdGhlIHVuZGVybHlpbmcgYnl0ZSBhcnJheSwgbWVhbmluZyB0aGF0IGEKKyAqIHN1YnN0cmluZyB3aWxsIHJlZmVyZW5jZSB0aGUgZnVsbCBieXRlLWFycmF5IG9mIHRoZSBzdHJpbmcgaXQncyBtYWRlIGZyb20sCisgKiBleGFjdGx5IGFzIHdpdGgge0BsaW5rIFN0cmluZ30uCisgKgorICogQGF1dGhvciBjYXJsYW50b25AZ29vZ2xlLmNvbSAoQ2FybCBIYXZlcmwpCisgKi8KK2NsYXNzIExpdGVyYWxCeXRlU3RyaW5nIGV4dGVuZHMgQnl0ZVN0cmluZyB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgcHJvdGVjdGVkIGZpbmFsIGJ5dGVbXSBieXRlczsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIHtAY29kZSBMaXRlcmFsQnl0ZVN0cmluZ30gYmFja2VkIGJ5IHRoZSBnaXZlbiBhcnJheSwgd2l0aG91dAorICAgKiBjb3B5aW5nLgorICAgKgorICAgKiBAcGFyYW0gYnl0ZXMgYXJyYXkgdG8gd3JhcAorICAgKi8KKyAgTGl0ZXJhbEJ5dGVTdHJpbmcoYnl0ZVtdIGJ5dGVzKSB7CisgICAgdGhpcy5ieXRlcyA9IGJ5dGVzOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBieXRlIGJ5dGVBdChpbnQgaW5kZXgpIHsKKyAgICAvLyBVbmxpa2UgbW9zdCBtZXRob2RzIGluIHRoaXMgY2xhc3MsIHRoaXMgb25lIGlzIGEgZGlyZWN0IGltcGxlbWVudGF0aW9uCisgICAgLy8gaWdub3JpbmcgdGhlIHBvdGVudGlhbCBvZmZzZXQgYmVjYXVzZSB3ZSBuZWVkIHRvIGRvIHJhbmdlLWNoZWNraW5nIGluIHRoZQorICAgIC8vIHN1YnN0cmluZyBjYXNlIGFueXdheS4KKyAgICByZXR1cm4gYnl0ZXNbaW5kZXhdOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gYnl0ZXMubGVuZ3RoOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gQnl0ZVN0cmluZyAtPiBzdWJzdHJpbmcKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEJ5dGVTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpIHsKKyAgICBpZiAoYmVnaW5JbmRleCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKAorICAgICAgICAgICJCZWdpbm5pbmcgaW5kZXg6ICIgKyBiZWdpbkluZGV4ICsgIiA8IDAiKTsKKyAgICB9CisgICAgaWYgKGVuZEluZGV4ID4gc2l6ZSgpKSB7CisgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiRW5kIGluZGV4OiAiICsgZW5kSW5kZXggKyAiID4gIiArCisgICAgICAgICAgc2l6ZSgpKTsKKyAgICB9CisgICAgaW50IHN1YnN0cmluZ0xlbmd0aCA9IGVuZEluZGV4IC0gYmVnaW5JbmRleDsKKyAgICBpZiAoc3Vic3RyaW5nTGVuZ3RoIDwgMCkgeworICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oCisgICAgICAgICAgIkJlZ2lubmluZyBpbmRleCBsYXJnZXIgdGhhbiBlbmRpbmcgaW5kZXg6ICIgKyBiZWdpbkluZGV4ICsgIiwgIgorICAgICAgICAgICAgICArIGVuZEluZGV4KTsKKyAgICB9CisKKyAgICBCeXRlU3RyaW5nIHJlc3VsdDsKKyAgICBpZiAoc3Vic3RyaW5nTGVuZ3RoID09IDApIHsKKyAgICAgIHJlc3VsdCA9IEJ5dGVTdHJpbmcuRU1QVFk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdCA9IG5ldyBCb3VuZGVkQnl0ZVN0cmluZyhieXRlcywgZ2V0T2Zmc2V0SW50b0J5dGVzKCkgKyBiZWdpbkluZGV4LAorICAgICAgICAgIHN1YnN0cmluZ0xlbmd0aCk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBCeXRlU3RyaW5nIC0+IGJ5dGVbXQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBjb3B5VG9JbnRlcm5hbChieXRlW10gdGFyZ2V0LCBpbnQgc291cmNlT2Zmc2V0LCAKKyAgICAgIGludCB0YXJnZXRPZmZzZXQsIGludCBudW1iZXJUb0NvcHkpIHsKKyAgICAvLyBPcHRpbWl6ZWQgZm9ybSwgbm90IGZvciBzdWJjbGFzc2VzLCBzaW5jZSB3ZSBkb24ndCBjYWxsCisgICAgLy8gZ2V0T2Zmc2V0SW50b0J5dGVzKCkgb3IgY2hlY2sgdGhlICdudW1iZXJUb0NvcHknIHBhcmFtZXRlci4KKyAgICBTeXN0ZW0uYXJyYXljb3B5KGJ5dGVzLCBzb3VyY2VPZmZzZXQsIHRhcmdldCwgdGFyZ2V0T2Zmc2V0LCBudW1iZXJUb0NvcHkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNvcHlUbyhCeXRlQnVmZmVyIHRhcmdldCkgeworICAgIHRhcmdldC5wdXQoYnl0ZXMsIGdldE9mZnNldEludG9CeXRlcygpLCBzaXplKCkpOyAgLy8gQ29waWVzIGJ5dGVzCisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEJ5dGVCdWZmZXIgYXNSZWFkT25seUJ5dGVCdWZmZXIoKSB7CisgICAgQnl0ZUJ1ZmZlciBieXRlQnVmZmVyID0KKyAgICAgICAgQnl0ZUJ1ZmZlci53cmFwKGJ5dGVzLCBnZXRPZmZzZXRJbnRvQnl0ZXMoKSwgc2l6ZSgpKTsKKyAgICByZXR1cm4gYnl0ZUJ1ZmZlci5hc1JlYWRPbmx5QnVmZmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3Q8Qnl0ZUJ1ZmZlcj4gYXNSZWFkT25seUJ5dGVCdWZmZXJMaXN0KCkgeworICAgIC8vIFJldHVybiB0aGUgQnl0ZUJ1ZmZlciBnZW5lcmF0ZWQgYnkgYXNSZWFkT25seUJ5dGVCdWZmZXIoKSBhcyBhIHNpbmdsZXRvbgorICAgIExpc3Q8Qnl0ZUJ1ZmZlcj4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxCeXRlQnVmZmVyPigxKTsKKyAgICByZXN1bHQuYWRkKGFzUmVhZE9ubHlCeXRlQnVmZmVyKCkpOworICAgIHJldHVybiByZXN1bHQ7CisgfQorCisgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXRwdXRTdHJlYW0ud3JpdGUodG9CeXRlQXJyYXkoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgdm9pZCB3cml0ZVRvSW50ZXJuYWwoT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSwgaW50IHNvdXJjZU9mZnNldCwKKyAgICAgIGludCBudW1iZXJUb1dyaXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG91dHB1dFN0cmVhbS53cml0ZShieXRlcywgZ2V0T2Zmc2V0SW50b0J5dGVzKCkgKyBzb3VyY2VPZmZzZXQsCisgICAgICAgIG51bWJlclRvV3JpdGUpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoU3RyaW5nIGNoYXJzZXROYW1lKQorICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIC8vIE9wdGltaXplIGZvciBlbXB0eSBzdHJpbmdzLCBidXQgZW5zdXJlIHdlIGRvbid0IHNpbGVudGx5IGlnbm9yZSBpbnZhbGlkCisgICAgLy8gZW5jb2RpbmdzLgorICAgIHJldHVybiBzaXplKCkgPT0gMCAmJiBVVEZfOC5lcXVhbHMoY2hhcnNldE5hbWUpCisgICAgICAgID8gIiIKKyAgICAgICAgOiBuZXcgU3RyaW5nKGJ5dGVzLCBnZXRPZmZzZXRJbnRvQnl0ZXMoKSwgc2l6ZSgpLCBjaGFyc2V0TmFtZSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBVVEYtOCBkZWNvZGluZworCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkVXRmOCgpIHsKKyAgICBpbnQgb2Zmc2V0ID0gZ2V0T2Zmc2V0SW50b0J5dGVzKCk7CisgICAgcmV0dXJuIFV0ZjguaXNWYWxpZFV0ZjgoYnl0ZXMsIG9mZnNldCwgb2Zmc2V0ICsgc2l6ZSgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgaW50IHBhcnRpYWxJc1ZhbGlkVXRmOChpbnQgc3RhdGUsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICBpbnQgaW5kZXggPSBnZXRPZmZzZXRJbnRvQnl0ZXMoKSArIG9mZnNldDsKKyAgICByZXR1cm4gVXRmOC5wYXJ0aWFsSXNWYWxpZFV0Zjgoc3RhdGUsIGJ5dGVzLCBpbmRleCwgaW5kZXggKyBsZW5ndGgpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgIGlmIChvdGhlciA9PSB0aGlzKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBCeXRlU3RyaW5nKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmIChzaXplKCkgIT0gKChCeXRlU3RyaW5nKSBvdGhlcikuc2l6ZSgpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChzaXplKCkgPT0gMCkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgTGl0ZXJhbEJ5dGVTdHJpbmcpIHsKKyAgICAgIExpdGVyYWxCeXRlU3RyaW5nIG90aGVyQXNMaXRlcmFsID0gKExpdGVyYWxCeXRlU3RyaW5nKSBvdGhlcjsKKyAgICAgIC8vIElmIHdlIGtub3cgdGhlIGhhc2ggY29kZXMgYW5kIHRoZXkgYXJlIG5vdCBlcXVhbCwgd2Uga25vdyB0aGUgYnl0ZQorICAgICAgLy8gc3RyaW5ncyBhcmUgbm90IGVxdWFsLgorICAgICAgaWYgKGhhc2ggIT0gMCAKKyAgICAgICAgICAmJiBvdGhlckFzTGl0ZXJhbC5oYXNoICE9IDAgCisgICAgICAgICAgJiYgaGFzaCAhPSBvdGhlckFzTGl0ZXJhbC5oYXNoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgcmV0dXJuIGVxdWFsc1JhbmdlKChMaXRlcmFsQnl0ZVN0cmluZykgb3RoZXIsIDAsIHNpemUoKSk7CisgICAgfSBlbHNlIGlmIChvdGhlciBpbnN0YW5jZW9mIFJvcGVCeXRlU3RyaW5nKSB7CisgICAgICByZXR1cm4gb3RoZXIuZXF1YWxzKHRoaXMpOworICAgIH0gZWxzZSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJIYXMgYSBuZXcgdHlwZSBvZiBCeXRlU3RyaW5nIGJlZW4gY3JlYXRlZD8gRm91bmQgIgorICAgICAgICAgICAgICArIG90aGVyLmdldENsYXNzKCkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDaGVjayBlcXVhbGl0eSBvZiB0aGUgc3Vic3RyaW5nIG9mIGdpdmVuIGxlbmd0aCBvZiB0aGlzIG9iamVjdCBzdGFydGluZyBhdAorICAgKiB6ZXJvIHdpdGggYW5vdGhlciB7QGNvZGUgTGl0ZXJhbEJ5dGVTdHJpbmd9IHN1YnN0cmluZyBzdGFydGluZyBhdCBvZmZzZXQuCisgICAqCisgICAqIEBwYXJhbSBvdGhlciAgd2hhdCB0byBjb21wYXJlIGEgc3Vic3RyaW5nIGluCisgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IGludG8gb3RoZXIKKyAgICogQHBhcmFtIGxlbmd0aCBudW1iZXIgb2YgYnl0ZXMgdG8gY29tcGFyZQorICAgKiBAcmV0dXJuIHRydWUgZm9yIGVxdWFsaXR5IG9mIHN1YnN0cmluZ3MsIGVsc2UgZmFsc2UuCisgICAqLworICBib29sZWFuIGVxdWFsc1JhbmdlKExpdGVyYWxCeXRlU3RyaW5nIG90aGVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgaWYgKGxlbmd0aCA+IG90aGVyLnNpemUoKSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiTGVuZ3RoIHRvbyBsYXJnZTogIiArIGxlbmd0aCArIHNpemUoKSk7CisgICAgfQorICAgIGlmIChvZmZzZXQgKyBsZW5ndGggPiBvdGhlci5zaXplKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgIlJhbiBvZmYgZW5kIG9mIG90aGVyOiAiICsgb2Zmc2V0ICsgIiwgIiArIGxlbmd0aCArICIsICIgKworICAgICAgICAgICAgICBvdGhlci5zaXplKCkpOworICAgIH0KKworICAgIGJ5dGVbXSB0aGlzQnl0ZXMgPSBieXRlczsKKyAgICBieXRlW10gb3RoZXJCeXRlcyA9IG90aGVyLmJ5dGVzOworICAgIGludCB0aGlzTGltaXQgPSBnZXRPZmZzZXRJbnRvQnl0ZXMoKSArIGxlbmd0aDsKKyAgICBmb3IgKGludCB0aGlzSW5kZXggPSBnZXRPZmZzZXRJbnRvQnl0ZXMoKSwgb3RoZXJJbmRleCA9CisgICAgICAgIG90aGVyLmdldE9mZnNldEludG9CeXRlcygpICsgb2Zmc2V0OworICAgICAgICAodGhpc0luZGV4IDwgdGhpc0xpbWl0KTsgKyt0aGlzSW5kZXgsICsrb3RoZXJJbmRleCkgeworICAgICAgaWYgKHRoaXNCeXRlc1t0aGlzSW5kZXhdICE9IG90aGVyQnl0ZXNbb3RoZXJJbmRleF0pIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBDYWNoZWQgaGFzaCB2YWx1ZS4gIEludGVudGlvbmFsbHkgYWNjZXNzZWQgdmlhIGEgZGF0YSByYWNlLCB3aGljaAorICAgKiBpcyBzYWZlIGJlY2F1c2Ugb2YgdGhlIEphdmEgTWVtb3J5IE1vZGVsJ3MgIm5vIG91dC1vZi10aGluLWFpciB2YWx1ZXMiCisgICAqIGd1YXJhbnRlZXMgZm9yIGludHMuCisgICAqLworICBwcml2YXRlIGludCBoYXNoID0gMDsKKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgaGFzaENvZGUgdXNpbmcgdGhlIHRyYWRpdGlvbmFsIGFsZ29yaXRobSBmcm9tIHtAbGluaworICAgKiBCeXRlU3RyaW5nfS4KKyAgICoKKyAgICogQHJldHVybiBoYXNoQ29kZSB2YWx1ZQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgaW50IGggPSBoYXNoOworCisgICAgaWYgKGggPT0gMCkgeworICAgICAgaW50IHNpemUgPSBzaXplKCk7CisgICAgICBoID0gcGFydGlhbEhhc2goc2l6ZSwgMCwgc2l6ZSk7CisgICAgICBpZiAoaCA9PSAwKSB7CisgICAgICAgIGggPSAxOworICAgICAgfQorICAgICAgaGFzaCA9IGg7CisgICAgfQorICAgIHJldHVybiBoOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBpbnQgcGVla0NhY2hlZEhhc2hDb2RlKCkgeworICAgIHJldHVybiBoYXNoOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBpbnQgcGFydGlhbEhhc2goaW50IGgsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICByZXR1cm4gaGFzaENvZGUoaCwgYnl0ZXMsIGdldE9mZnNldEludG9CeXRlcygpICsgb2Zmc2V0LCBsZW5ndGgpOworICB9CisgIAorICBzdGF0aWMgaW50IGhhc2hDb2RlKGludCBoLCBieXRlW10gYnl0ZXMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgb2Zmc2V0ICsgbGVuZ3RoOyBpKyspIHsKKyAgICAgIGggPSBoICogMzEgKyBieXRlc1tpXTsKKyAgICB9CisgICAgcmV0dXJuIGg7CisgIH0KKyAgCisgIHN0YXRpYyBpbnQgaGFzaENvZGUoYnl0ZVtdIGJ5dGVzKSB7CisgICAgaW50IGggPSBoYXNoQ29kZShieXRlcy5sZW5ndGgsIGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpOworICAgIHJldHVybiBoID09IDAgPyAxIDogaDsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIElucHV0IHN0cmVhbQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgSW5wdXRTdHJlYW0gbmV3SW5wdXQoKSB7CisgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcywgZ2V0T2Zmc2V0SW50b0J5dGVzKCksCisgICAgICAgIHNpemUoKSk7ICAvLyBObyBjb3B5CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIENvZGVkSW5wdXRTdHJlYW0gbmV3Q29kZWRJbnB1dCgpIHsKKyAgICAvLyBXZSB0cnVzdCBDb2RlZElucHV0U3RyZWFtIG5vdCB0byBtb2RpZnkgdGhlIGJ5dGVzLCBvciB0byBnaXZlIGFueW9uZQorICAgIC8vIGVsc2UgYWNjZXNzIHRvIHRoZW0uCisgICAgcmV0dXJuIENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UodGhpcyk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBCeXRlSXRlcmF0b3IKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEJ5dGVJdGVyYXRvciBpdGVyYXRvcigpIHsKKyAgICByZXR1cm4gbmV3IExpdGVyYWxCeXRlSXRlcmF0b3IoKTsKKyAgfQorCisgIHByaXZhdGUgY2xhc3MgTGl0ZXJhbEJ5dGVJdGVyYXRvciBpbXBsZW1lbnRzIEJ5dGVJdGVyYXRvciB7CisgICAgcHJpdmF0ZSBpbnQgcG9zaXRpb247CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbGltaXQ7CisKKyAgICBwcml2YXRlIExpdGVyYWxCeXRlSXRlcmF0b3IoKSB7CisgICAgICBwb3NpdGlvbiA9IDA7CisgICAgICBsaW1pdCA9IHNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgcmV0dXJuIChwb3NpdGlvbiA8IGxpbWl0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZSBuZXh0KCkgeworICAgICAgLy8gQm94aW5nIGNhbGxzIEJ5dGUudmFsdWVPZihieXRlKSwgd2hpY2ggZG9lcyBub3QgaW5zdGFudGlhdGUuCisgICAgICByZXR1cm4gbmV4dEJ5dGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZSBuZXh0Qnl0ZSgpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybiBieXRlc1twb3NpdGlvbisrXTsKKyAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBJbnRlcm5hbCBtZXRob2RzCisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBpbnQgZ2V0VHJlZURlcHRoKCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBib29sZWFuIGlzQmFsYW5jZWQoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogT2Zmc2V0IGludG8ge0Bjb2RlIGJ5dGVzW119IHRvIHVzZSwgbm9uLXplcm8gZm9yIHN1YnN0cmluZ3MuCisgICAqCisgICAqIEByZXR1cm4gYWx3YXlzIDAgZm9yIHRoaXMgY2xhc3MKKyAgICovCisgIHByb3RlY3RlZCBpbnQgZ2V0T2Zmc2V0SW50b0J5dGVzKCkgeworICAgIHJldHVybiAwOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBFbnRyeS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRW50cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMTQxNGJiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRW50cnkuamF2YQpAQCAtMCwwICsxLDQzMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworCisvKioKKyAqIEltcGxlbWVudHMgTWFwRW50cnkgbWVzc2FnZXMuCisgKiAKKyAqIEluIHJlZmxlY3Rpb24gQVBJLCBtYXAgZmllbGRzIHdpbGwgYmUgdHJlYXRlZCBhcyByZXBlYXRlZCBtZXNzYWdlIGZpZWxkcyBhbmQKKyAqIGVhY2ggbWFwIGVudHJ5IGlzIGFjY2Vzc2VkIGFzIGEgbWVzc2FnZS4gVGhpcyBNYXBFbnRyeSBjbGFzcyBpcyB1c2VkIHRvCisgKiByZXByZXNlbnQgdGhlc2UgbWFwIGVudHJ5IG1lc3NhZ2VzIGluIHJlZmxlY3Rpb24gQVBJLgorICogCisgKiBQcm90b2J1ZiBpbnRlcm5hbC4gVXNlcnMgc2hvdWxkbid0IHVzZSB0aGlzIGNsYXNzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWFwRW50cnk8SywgVj4gZXh0ZW5kcyBBYnN0cmFjdE1lc3NhZ2UgeworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNZXRhZGF0YTxLLCBWPiB7CisgICAgcHVibGljIGZpbmFsIERlc2NyaXB0b3IgZGVzY3JpcHRvcjsgIAorICAgIHB1YmxpYyBmaW5hbCBNYXBFbnRyeTxLLCBWPiBkZWZhdWx0SW5zdGFuY2U7CisgICAgcHVibGljIGZpbmFsIEFic3RyYWN0UGFyc2VyPE1hcEVudHJ5PEssIFY+PiBwYXJzZXI7CisgICAgCisgICAgcHVibGljIE1ldGFkYXRhKAorICAgICAgICBmaW5hbCBEZXNjcmlwdG9yIGRlc2NyaXB0b3IsIGZpbmFsIE1hcEVudHJ5PEssIFY+IGRlZmF1bHRJbnN0YW5jZSkgeworICAgICAgdGhpcy5kZXNjcmlwdG9yID0gZGVzY3JpcHRvcjsKKyAgICAgIHRoaXMuZGVmYXVsdEluc3RhbmNlID0gZGVmYXVsdEluc3RhbmNlOworICAgICAgZmluYWwgTWV0YWRhdGE8SywgVj4gdGhpc01ldGFkYXRhID0gdGhpczsKKyAgICAgIHRoaXMucGFyc2VyID0gbmV3IEFic3RyYWN0UGFyc2VyPE1hcEVudHJ5PEssIFY+PigpIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBQYXJzZXI8TWFwRW50cnlMaXRlPEssIFY+PiBkYXRhUGFyc2VyID0KKyAgICAgICAgICAgIGRlZmF1bHRJbnN0YW5jZS5kYXRhLmdldFBhcnNlckZvclR5cGUoKTsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBNYXBFbnRyeTxLLCBWPiBwYXJzZVBhcnRpYWxGcm9tKAorICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgICAgTWFwRW50cnlMaXRlPEssIFY+IGRhdGEgPQorICAgICAgICAgICAgICBkYXRhUGFyc2VyLnBhcnNlUGFydGlhbEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgICAgICByZXR1cm4gbmV3IE1hcEVudHJ5PEssIFY+KHRoaXNNZXRhZGF0YSwgZGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICB9OworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSBmaW5hbCBNZXRhZGF0YTxLLCBWPiBtZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBNYXBFbnRyeUxpdGU8SywgVj4gZGF0YTsKKyAgCisgIC8qKiBDcmVhdGUgYSBkZWZhdWx0IE1hcEVudHJ5IGluc3RhbmNlLiAqLworICBwcml2YXRlIE1hcEVudHJ5KERlc2NyaXB0b3IgZGVzY3JpcHRvciwKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIGtleVR5cGUsIEsgZGVmYXVsdEtleSwKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHZhbHVlVHlwZSwgViBkZWZhdWx0VmFsdWUpIHsKKyAgICB0aGlzLmRhdGEgPSBNYXBFbnRyeUxpdGUubmV3RGVmYXVsdEluc3RhbmNlKAorICAgICAgICBrZXlUeXBlLCBkZWZhdWx0S2V5LCB2YWx1ZVR5cGUsIGRlZmF1bHRWYWx1ZSk7CisgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBNZXRhZGF0YTxLLCBWPihkZXNjcmlwdG9yLCB0aGlzKTsgCisgIH0KKyAgCisgIC8qKiBDcmVhdGUgYSBuZXcgTWFwRW50cnkgbWVzc2FnZS4gKi8KKyAgcHJpdmF0ZSBNYXBFbnRyeShNZXRhZGF0YTxLLCBWPiBtZXRhZGF0YSwgTWFwRW50cnlMaXRlPEssIFY+IGRhdGEpIHsKKyAgICB0aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7CisgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgfQorICAKKyAgLyoqCisgICAqIENyZWF0ZSBhIGRlZmF1bHQgTWFwRW50cnkgaW5zdGFuY2UuIEEgZGVmYXVsdCBNYXBFbnRyeSBpbnN0YW5jZSBzaG91bGQgYmUKKyAgICogY3JlYXRlZCBvbmx5IG9uY2UgZm9yIGVhY2ggbWFwIGVudHJ5IG1lc3NhZ2UgdHlwZS4gR2VuZXJhdGVkIGNvZGUgc2hvdWxkCisgICAqIHN0b3JlIHRoZSBjcmVhdGVkIGRlZmF1bHQgaW5zdGFuY2UgYW5kIHVzZSBpdCBsYXRlciB0byBjcmVhdGUgbmV3IE1hcEVudHJ5CisgICAqIG1lc3NhZ2VzIG9mIHRoZSBzYW1lIHR5cGUuIAorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8SywgVj4gTWFwRW50cnk8SywgVj4gbmV3RGVmYXVsdEluc3RhbmNlKAorICAgICAgRGVzY3JpcHRvciBkZXNjcmlwdG9yLAorICAgICAgV2lyZUZvcm1hdC5GaWVsZFR5cGUga2V5VHlwZSwgSyBkZWZhdWx0S2V5LAorICAgICAgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdmFsdWVUeXBlLCBWIGRlZmF1bHRWYWx1ZSkgeworICAgIHJldHVybiBuZXcgTWFwRW50cnk8SywgVj4oCisgICAgICAgIGRlc2NyaXB0b3IsIGtleVR5cGUsIGRlZmF1bHRLZXksIHZhbHVlVHlwZSwgZGVmYXVsdFZhbHVlKTsKKyAgfQorICAKKyAgcHVibGljIEsgZ2V0S2V5KCkgeworICAgIHJldHVybiBkYXRhLmdldEtleSgpOworICB9CisgIAorICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICByZXR1cm4gZGF0YS5nZXRWYWx1ZSgpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICByZXR1cm4gZGF0YS5nZXRTZXJpYWxpemVkU2l6ZSgpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgd3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGF0YS53cml0ZVRvKG91dHB1dCk7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgeworICAgIHJldHVybiBkYXRhLmlzSW5pdGlhbGl6ZWQoKTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBQYXJzZXI8TWFwRW50cnk8SywgVj4+IGdldFBhcnNlckZvclR5cGUoKSB7CisgICAgcmV0dXJuIG1ldGFkYXRhLnBhcnNlcjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgQnVpbGRlcjxLLCBWPiBuZXdCdWlsZGVyRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXI8SywgVj4obWV0YWRhdGEpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIEJ1aWxkZXI8SywgVj4gdG9CdWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcjxLLCBWPihtZXRhZGF0YSwgZGF0YSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE1hcEVudHJ5PEssIFY+IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CisgICAgcmV0dXJuIG1ldGFkYXRhLmRlZmF1bHRJbnN0YW5jZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gbWV0YWRhdGEuZGVzY3JpcHRvcjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTWFwPEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBnZXRBbGxGaWVsZHMoKSB7CisgICAgZmluYWwgVHJlZU1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gcmVzdWx0ID0KKyAgICAgICAgbmV3IFRyZWVNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+KCk7CisgICAgZm9yIChmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQgOiBtZXRhZGF0YS5kZXNjcmlwdG9yLmdldEZpZWxkcygpKSB7CisgICAgICBpZiAoaGFzRmllbGQoZmllbGQpKSB7CisgICAgICAgIHJlc3VsdC5wdXQoZmllbGQsIGdldEZpZWxkKGZpZWxkKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAocmVzdWx0KTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIGNoZWNrRmllbGREZXNjcmlwdG9yKEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgIGlmIChmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpICE9IG1ldGFkYXRhLmRlc2NyaXB0b3IpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJXcm9uZyBGaWVsZERlc2NyaXB0b3IgXCIiICsgZmllbGQuZ2V0RnVsbE5hbWUoKQorICAgICAgICAgICsgIlwiIHVzZWQgaW4gbWVzc2FnZSBcIiIgKyBtZXRhZGF0YS5kZXNjcmlwdG9yLmdldEZ1bGxOYW1lKCkpOyAKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgY2hlY2tGaWVsZERlc2NyaXB0b3IoZmllbGQpOzsKKyAgICAvLyBBIE1hcEVudHJ5IGFsd2F5cyBjb250YWlucyB0d28gZmllbGRzLgorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgY2hlY2tGaWVsZERlc2NyaXB0b3IoZmllbGQpOworICAgIE9iamVjdCByZXN1bHQgPSBmaWVsZC5nZXROdW1iZXIoKSA9PSAxID8gZ2V0S2V5KCkgOiBnZXRWYWx1ZSgpOworICAgIC8vIENvbnZlcnQgZW51bXMgdG8gRW51bVZhbHVlRGVzY3JpcHRvci4KKyAgICBpZiAoZmllbGQuZ2V0VHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5UeXBlLkVOVU0pIHsKKyAgICAgIHJlc3VsdCA9IGZpZWxkLmdldEVudW1UeXBlKCkuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bigKKyAgICAgICAgICAoamF2YS5sYW5nLkludGVnZXIpIHJlc3VsdCk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICJUaGVyZSBpcyBubyByZXBlYXRlZCBmaWVsZCBpbiBhIG1hcCBlbnRyeSBtZXNzYWdlLiIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRGaWVsZChGaWVsZERlc2NyaXB0b3IgZmllbGQsIGludCBpbmRleCkgeworICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAiVGhlcmUgaXMgbm8gcmVwZWF0ZWQgZmllbGQgaW4gYSBtYXAgZW50cnkgbWVzc2FnZS4iKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVW5rbm93bkZpZWxkU2V0IGdldFVua25vd25GaWVsZHMoKSB7CisgICAgcmV0dXJuIFVua25vd25GaWVsZFNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgfQorCisgIC8qKgorICAgKiBCdWlsZGVyIHRvIGNyZWF0ZSB7QGxpbmsgTWFwRW50cnl9IG1lc3NhZ2VzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBCdWlsZGVyPEssIFY+CisgICAgICBleHRlbmRzIEFic3RyYWN0TWVzc2FnZS5CdWlsZGVyPEJ1aWxkZXI8SywgVj4+IHsKKyAgICBwcml2YXRlIGZpbmFsIE1ldGFkYXRhPEssIFY+IG1ldGFkYXRhOworICAgIHByaXZhdGUgTWFwRW50cnlMaXRlPEssIFY+IGRhdGE7CisgICAgcHJpdmF0ZSBNYXBFbnRyeUxpdGUuQnVpbGRlcjxLLCBWPiBkYXRhQnVpbGRlcjsKKyAgICAKKyAgICBwcml2YXRlIEJ1aWxkZXIoTWV0YWRhdGE8SywgVj4gbWV0YWRhdGEpIHsKKyAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKKyAgICAgIHRoaXMuZGF0YSA9IG1ldGFkYXRhLmRlZmF1bHRJbnN0YW5jZS5kYXRhOworICAgICAgdGhpcy5kYXRhQnVpbGRlciA9IG51bGw7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgQnVpbGRlcihNZXRhZGF0YTxLLCBWPiBtZXRhZGF0YSwgTWFwRW50cnlMaXRlPEssIFY+IGRhdGEpIHsKKyAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKKyAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgICB0aGlzLmRhdGFCdWlsZGVyID0gbnVsbDsKKyAgICB9CisgICAgCisgICAgcHVibGljIEsgZ2V0S2V5KCkgeworICAgICAgcmV0dXJuIGRhdGFCdWlsZGVyID09IG51bGwgPyBkYXRhLmdldEtleSgpIDogZGF0YUJ1aWxkZXIuZ2V0S2V5KCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBWIGdldFZhbHVlKCkgeworICAgICAgcmV0dXJuIGRhdGFCdWlsZGVyID09IG51bGwgPyBkYXRhLmdldFZhbHVlKCkgOiBkYXRhQnVpbGRlci5nZXRWYWx1ZSgpOworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlTXV0YWJsZSgpIHsKKyAgICAgIGlmIChkYXRhQnVpbGRlciA9PSBudWxsKSB7CisgICAgICAgIGRhdGFCdWlsZGVyID0gZGF0YS50b0J1aWxkZXIoKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gc2V0S2V5KEsga2V5KSB7CisgICAgICBlbnN1cmVNdXRhYmxlKCk7CisgICAgICBkYXRhQnVpbGRlci5zZXRLZXkoa2V5KTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgQnVpbGRlcjxLLCBWPiBjbGVhcktleSgpIHsKKyAgICAgIGVuc3VyZU11dGFibGUoKTsKKyAgICAgIGRhdGFCdWlsZGVyLmNsZWFyS2V5KCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisgICAgCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gc2V0VmFsdWUoViB2YWx1ZSkgeworICAgICAgZW5zdXJlTXV0YWJsZSgpOworICAgICAgZGF0YUJ1aWxkZXIuc2V0VmFsdWUodmFsdWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IGNsZWFyVmFsdWUoKSB7CisgICAgICBlbnN1cmVNdXRhYmxlKCk7CisgICAgICBkYXRhQnVpbGRlci5jbGVhclZhbHVlKCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWFwRW50cnk8SywgVj4gYnVpbGQoKSB7CisgICAgICBNYXBFbnRyeTxLLCBWPiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKKyAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOworICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWFwRW50cnk8SywgVj4gYnVpbGRQYXJ0aWFsKCkgeworICAgICAgaWYgKGRhdGFCdWlsZGVyICE9IG51bGwpIHsKKyAgICAgICAgZGF0YSA9IGRhdGFCdWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgICAgICBkYXRhQnVpbGRlciA9IG51bGw7CisgICAgICB9CisgICAgICByZXR1cm4gbmV3IE1hcEVudHJ5PEssIFY+KG1ldGFkYXRhLCBkYXRhKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKKyAgICAgIHJldHVybiBtZXRhZGF0YS5kZXNjcmlwdG9yOworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tGaWVsZERlc2NyaXB0b3IoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBpZiAoZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSBtZXRhZGF0YS5kZXNjcmlwdG9yKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgIldyb25nIEZpZWxkRGVzY3JpcHRvciBcIiIgKyBmaWVsZC5nZXRGdWxsTmFtZSgpCisgICAgICAgICAgICArICJcIiB1c2VkIGluIG1lc3NhZ2UgXCIiICsgbWV0YWRhdGEuZGVzY3JpcHRvci5nZXRGdWxsTmFtZSgpKTsgCisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZS5CdWlsZGVyIG5ld0J1aWxkZXJGb3JGaWVsZCgKKyAgICAgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICBjaGVja0ZpZWxkRGVzY3JpcHRvcihmaWVsZCk7OworICAgICAgLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBmb3IgbWVzc2FnZSBmaWVsZHMgYW5kIGluIGEgTWFwRW50cnkKKyAgICAgIC8vIG1lc3NhZ2Ugb25seSB0aGUgdmFsdWUgZmllbGQgY2FuIHBvc3NpYmx5IGJlIGEgbWVzc2FnZSBmaWVsZC4KKyAgICAgIGlmIChmaWVsZC5nZXROdW1iZXIoKSAhPSAyCisgICAgICAgICAgfHwgZmllbGQuZ2V0SmF2YVR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICJcIiIgKyBmaWVsZC5nZXRGdWxsTmFtZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdmFsdWUgZmllbGQuIik7CisgICAgICB9CisgICAgICByZXR1cm4gKChNZXNzYWdlKSBkYXRhLmdldFZhbHVlKCkpLm5ld0J1aWxkZXJGb3JUeXBlKCk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gc2V0RmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGNoZWNrRmllbGREZXNjcmlwdG9yKGZpZWxkKTsKKyAgICAgIGlmIChmaWVsZC5nZXROdW1iZXIoKSA9PSAxKSB7CisgICAgICAgIHNldEtleSgoSykgdmFsdWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGZpZWxkLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5FTlVNKSB7CisgICAgICAgICAgdmFsdWUgPSAoKEVudW1WYWx1ZURlc2NyaXB0b3IpIHZhbHVlKS5nZXROdW1iZXIoKTsKKyAgICAgICAgfQorICAgICAgICBzZXRWYWx1ZSgoVikgdmFsdWUpOworICAgICAgfQorICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gY2xlYXJGaWVsZChGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGNoZWNrRmllbGREZXNjcmlwdG9yKGZpZWxkKTsKKyAgICAgIGlmIChmaWVsZC5nZXROdW1iZXIoKSA9PSAxKSB7CisgICAgICAgIGNsZWFyS2V5KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBjbGVhclZhbHVlKCk7CisgICAgICB9CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlcjxLLCBWPiBzZXRSZXBlYXRlZEZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCwgaW50IGluZGV4LAorICAgICAgICBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJUaGVyZSBpcyBubyByZXBlYXRlZCBmaWVsZCBpbiBhIG1hcCBlbnRyeSBtZXNzYWdlLiIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IGFkZFJlcGVhdGVkRmllbGQoRmllbGREZXNjcmlwdG9yIGZpZWxkLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJUaGVyZSBpcyBubyByZXBlYXRlZCBmaWVsZCBpbiBhIG1hcCBlbnRyeSBtZXNzYWdlLiIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IHNldFVua25vd25GaWVsZHMoVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKKyAgICAgIC8vIFVua25vd24gZmllbGRzIGFyZSBkaXNjYXJkZWQgZm9yIE1hcEVudHJ5IG1lc3NhZ2UuCisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWFwRW50cnk8SywgVj4gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKKyAgICAgIHJldHVybiBtZXRhZGF0YS5kZWZhdWx0SW5zdGFuY2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICAgIGlmIChkYXRhQnVpbGRlciAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBkYXRhQnVpbGRlci5pc0luaXRpYWxpemVkKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZGF0YS5pc0luaXRpYWxpemVkKCk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZ2V0QWxsRmllbGRzKCkgeworICAgICAgZmluYWwgVHJlZU1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gcmVzdWx0ID0KKyAgICAgICAgICBuZXcgVHJlZU1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4oKTsKKyAgICAgIGZvciAoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkIDogbWV0YWRhdGEuZGVzY3JpcHRvci5nZXRGaWVsZHMoKSkgeworICAgICAgICBpZiAoaGFzRmllbGQoZmllbGQpKSB7CisgICAgICAgICAgcmVzdWx0LnB1dChmaWVsZCwgZ2V0RmllbGQoZmllbGQpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChyZXN1bHQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgY2hlY2tGaWVsZERlc2NyaXB0b3IoZmllbGQpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZChGaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIGNoZWNrRmllbGREZXNjcmlwdG9yKGZpZWxkKTsKKyAgICAgIE9iamVjdCByZXN1bHQgPSBmaWVsZC5nZXROdW1iZXIoKSA9PSAxID8gZ2V0S2V5KCkgOiBnZXRWYWx1ZSgpOworICAgICAgLy8gQ29udmVydCBlbnVtcyB0byBFbnVtVmFsdWVEZXNjcmlwdG9yLgorICAgICAgaWYgKGZpZWxkLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5FTlVNKSB7CisgICAgICAgIHJlc3VsdCA9IGZpZWxkLmdldEVudW1UeXBlKCkuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bigKKyAgICAgICAgICAgIChqYXZhLmxhbmcuSW50ZWdlcikgcmVzdWx0KTsKKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAiVGhlcmUgaXMgbm8gcmVwZWF0ZWQgZmllbGQgaW4gYSBtYXAgZW50cnkgbWVzc2FnZS4iKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZEZpZWxkKEZpZWxkRGVzY3JpcHRvciBmaWVsZCwgaW50IGluZGV4KSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAiVGhlcmUgaXMgbm8gcmVwZWF0ZWQgZmllbGQgaW4gYSBtYXAgZW50cnkgbWVzc2FnZS4iKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFVua25vd25GaWVsZFNldCBnZXRVbmtub3duRmllbGRzKCkgeworICAgICAgcmV0dXJuIFVua25vd25GaWVsZFNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVpbGRlcjxLLCBWPiBjbG9uZSgpIHsKKyAgICAgIGlmIChkYXRhQnVpbGRlciA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBuZXcgQnVpbGRlcjxLLCBWPihtZXRhZGF0YSwgZGF0YSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXI8SywgVj4obWV0YWRhdGEsIGRhdGFCdWlsZGVyLmJ1aWxkKCkpOworICAgICAgfQorICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRW50cnlMaXRlLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBFbnRyeUxpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iY2ZmYTk0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRW50cnlMaXRlLmphdmEKQEAgLTAsMCArMSwzMzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIEltcGxlbWVudHMgdGhlIGxpdGUgdmVyc2lvbiBvZiBtYXAgZW50cnkgbWVzc2FnZXMuCisgKiAKKyAqIFRoaXMgY2xhc3Mgc2VydmVzIGFzIGFuIHV0aWxpdHkgY2xhc3MgdG8gaGVscCBkbyBzZXJpYWxpemF0aW9uL3BhcnNpbmcgb2YKKyAqIG1hcCBlbnRyaWVzLiBJdCdzIHVzZWQgaW4gZ2VuZXJhdGVkIGNvZGUgYW5kIGFsc28gaW4gdGhlIGZ1bGwgdmVyc2lvbgorICogTWFwRW50cnkgbWVzc2FnZS4KKyAqIAorICogUHJvdG9idWYgaW50ZXJuYWwuIFVzZXJzIHNob3VsZG4ndCB1c2UuCisgKi8KK3B1YmxpYyBjbGFzcyBNYXBFbnRyeUxpdGU8SywgVj4gZXh0ZW5kcyBBYnN0cmFjdE1lc3NhZ2VMaXRlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTWV0YWRhdGE8SywgVj4geworICAgIHB1YmxpYyBmaW5hbCBNYXBFbnRyeUxpdGU8SywgVj4gZGVmYXVsdEluc3RhbmNlOworICAgIHB1YmxpYyBmaW5hbCBXaXJlRm9ybWF0LkZpZWxkVHlwZSBrZXlUeXBlOworICAgIHB1YmxpYyBmaW5hbCBXaXJlRm9ybWF0LkZpZWxkVHlwZSB2YWx1ZVR5cGU7CisgICAgcHVibGljIGZpbmFsIFBhcnNlcjxNYXBFbnRyeUxpdGU8SywgVj4+IHBhcnNlcjsKKyAgICBwdWJsaWMgTWV0YWRhdGEoCisgICAgICAgIE1hcEVudHJ5TGl0ZTxLLCBWPiBkZWZhdWx0SW5zdGFuY2UsCisgICAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIGtleVR5cGUsCisgICAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHZhbHVlVHlwZSkgeworICAgICAgdGhpcy5kZWZhdWx0SW5zdGFuY2UgPSBkZWZhdWx0SW5zdGFuY2U7IAorICAgICAgdGhpcy5rZXlUeXBlID0ga2V5VHlwZTsKKyAgICAgIHRoaXMudmFsdWVUeXBlID0gdmFsdWVUeXBlOworICAgICAgZmluYWwgTWV0YWRhdGE8SywgVj4gZmluYWxUaGlzID0gdGhpczsKKyAgICAgIHRoaXMucGFyc2VyID0gbmV3IEFic3RyYWN0UGFyc2VyPE1hcEVudHJ5TGl0ZTxLLCBWPj4oKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgTWFwRW50cnlMaXRlPEssIFY+IHBhcnNlUGFydGlhbEZyb20oCisgICAgICAgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0LCBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgICByZXR1cm4gbmV3IE1hcEVudHJ5TGl0ZTxLLCBWPihmaW5hbFRoaXMsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgICAgIH0KKyAgICAgIH07CisgICAgfQorICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0ZJRUxEX05VTUJFUiA9IDE7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAyOworICAKKyAgcHJpdmF0ZSBmaW5hbCBNZXRhZGF0YTxLLCBWPiBtZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBLIGtleTsKKyAgcHJpdmF0ZSBmaW5hbCBWIHZhbHVlOworICAKKyAgLyoqIENyZWF0ZXMgYSBkZWZhdWx0IE1hcEVudHJ5TGl0ZSBtZXNzYWdlIGluc3RhbmNlLiAqLworICBwcml2YXRlIE1hcEVudHJ5TGl0ZSgKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIGtleVR5cGUsIEsgZGVmYXVsdEtleSwKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHZhbHVlVHlwZSwgViBkZWZhdWx0VmFsdWUpIHsKKyAgICB0aGlzLm1ldGFkYXRhID0gbmV3IE1ldGFkYXRhPEssIFY+KHRoaXMsIGtleVR5cGUsIHZhbHVlVHlwZSk7CisgICAgdGhpcy5rZXkgPSBkZWZhdWx0S2V5OworICAgIHRoaXMudmFsdWUgPSBkZWZhdWx0VmFsdWU7CisgIH0KKyAgCisgIC8qKiBDcmVhdGVzIGEgbmV3IE1hcEVudHJ5TGl0ZSBtZXNzYWdlLiAqLworICBwcml2YXRlIE1hcEVudHJ5TGl0ZShNZXRhZGF0YTxLLCBWPiBtZXRhZGF0YSwgSyBrZXksIFYgdmFsdWUpIHsKKyAgICB0aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7CisgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICB9CisgIAorICBwdWJsaWMgSyBnZXRLZXkoKSB7CisgICAgcmV0dXJuIGtleTsKKyAgfQorICAKKyAgcHVibGljIFYgZ2V0VmFsdWUoKSB7CisgICAgcmV0dXJuIHZhbHVlOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBkZWZhdWx0IE1hcEVudHJ5TGl0ZSBtZXNzYWdlIGluc3RhbmNlLgorICAgKiAKKyAgICogVGhpcyBtZXRob2QgaXMgdXNlZCBieSBnZW5lcmF0ZWQgY29kZSB0byBjcmVhdGUgdGhlIGRlZmF1bHQgaW5zdGFuY2UgZm9yCisgICAqIGEgbWFwIGVudHJ5IG1lc3NhZ2UuIFRoZSBjcmVhdGVkIGRlZmF1bHQgaW5zdGFuY2Ugc2hvdWxkIGJlIHVzZWQgdG8gY3JlYXRlCisgICAqIG5ldyBtYXAgZW50cnkgbWVzc2FnZXMgb2YgdGhlIHNhbWUgdHlwZS4gRm9yIGVhY2ggbWFwIGVudHJ5IG1lc3NhZ2UsIG9ubHkKKyAgICogb25lIGRlZmF1bHQgaW5zdGFuY2Ugc2hvdWxkIGJlIGNyZWF0ZWQuIAorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8SywgVj4gTWFwRW50cnlMaXRlPEssIFY+IG5ld0RlZmF1bHRJbnN0YW5jZSgKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIGtleVR5cGUsIEsgZGVmYXVsdEtleSwKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHZhbHVlVHlwZSwgViBkZWZhdWx0VmFsdWUpIHsKKyAgICByZXR1cm4gbmV3IE1hcEVudHJ5TGl0ZTxLLCBWPigKKyAgICAgICAga2V5VHlwZSwgZGVmYXVsdEtleSwgdmFsdWVUeXBlLCBkZWZhdWx0VmFsdWUpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgd3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVGaWVsZChLRVlfRklFTERfTlVNQkVSLCBtZXRhZGF0YS5rZXlUeXBlLCBrZXksIG91dHB1dCk7CisgICAgd3JpdGVGaWVsZChWQUxVRV9GSUVMRF9OVU1CRVIsIG1ldGFkYXRhLnZhbHVlVHlwZSwgdmFsdWUsIG91dHB1dCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgd3JpdGVGaWVsZCgKKyAgICAgIGludCBudW1iZXIsIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGUsIE9iamVjdCB2YWx1ZSwKKyAgICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXRwdXQud3JpdGVUYWcobnVtYmVyLCB0eXBlLmdldFdpcmVUeXBlKCkpOworICAgIEZpZWxkU2V0LndyaXRlRWxlbWVudE5vVGFnKG91dHB1dCwgdHlwZSwgdmFsdWUpOworICB9CisKKyAgcHJpdmF0ZSB2b2xhdGlsZSBpbnQgY2FjaGVkU2VyaWFsaXplZFNpemUgPSAtMTsKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CisgICAgaWYgKGNhY2hlZFNlcmlhbGl6ZWRTaXplICE9IC0xKSB7CisgICAgICByZXR1cm4gY2FjaGVkU2VyaWFsaXplZFNpemU7CisgICAgfQorICAgIGludCBzaXplID0gMDsKKyAgICBzaXplICs9IGdldEZpZWxkU2l6ZShLRVlfRklFTERfTlVNQkVSLCBtZXRhZGF0YS5rZXlUeXBlLCBrZXkpOworICAgIHNpemUgKz0gZ2V0RmllbGRTaXplKFZBTFVFX0ZJRUxEX05VTUJFUiwgbWV0YWRhdGEudmFsdWVUeXBlLCB2YWx1ZSk7CisgICAgY2FjaGVkU2VyaWFsaXplZFNpemUgPSBzaXplOworICAgIHJldHVybiBzaXplOworICB9CisKKyAgcHJpdmF0ZSBpbnQgZ2V0RmllbGRTaXplKAorICAgICAgaW50IG51bWJlciwgV2lyZUZvcm1hdC5GaWVsZFR5cGUgdHlwZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgcmV0dXJuIENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVUYWdTaXplKG51bWJlcikKKyAgICAgICAgKyBGaWVsZFNldC5jb21wdXRlRWxlbWVudFNpemVOb1RhZyh0eXBlLCB2YWx1ZSk7CisgIH0KKyAgCisgIC8qKiBQYXJzaW5nIGNvbnN0cnVjdG9yLiAqLworICBwcml2YXRlIE1hcEVudHJ5TGl0ZSgKKyAgICAgIE1ldGFkYXRhPEssIFY+IG1ldGFkYXRhLAorICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBLIGtleSA9IG1ldGFkYXRhLmRlZmF1bHRJbnN0YW5jZS5rZXk7CisgICAgICBWIHZhbHVlID0gbWV0YWRhdGEuZGVmYXVsdEluc3RhbmNlLnZhbHVlOworICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKKyAgICAgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRhZyA9PSBXaXJlRm9ybWF0Lm1ha2VUYWcoCisgICAgICAgICAgICAgICAgS0VZX0ZJRUxEX05VTUJFUiwgbWV0YWRhdGEua2V5VHlwZS5nZXRXaXJlVHlwZSgpKSkgeworICAgICAgICAgIGtleSA9IG1lcmdlRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgbWV0YWRhdGEua2V5VHlwZSwga2V5KTsKKyAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gV2lyZUZvcm1hdC5tYWtlVGFnKAorICAgICAgICAgICAgICAgICAgICAgICBWQUxVRV9GSUVMRF9OVU1CRVIsIG1ldGFkYXRhLnZhbHVlVHlwZS5nZXRXaXJlVHlwZSgpKSkgeworICAgICAgICAgIHZhbHVlID0gbWVyZ2VGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCBtZXRhZGF0YS52YWx1ZVR5cGUsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoIWlucHV0LnNraXBGaWVsZCh0YWcpKSB7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKKyAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKHRoaXMpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpCisgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKHRoaXMpOworICAgIH0KKyAgfQorICAKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHByaXZhdGUgPFQ+IFQgbWVyZ2VGaWVsZCgKKyAgICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgIFdpcmVGb3JtYXQuRmllbGRUeXBlIHR5cGUsIFQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgIE1lc3NhZ2VMaXRlLkJ1aWxkZXIgc3ViQnVpbGRlciA9ICgoTWVzc2FnZUxpdGUpIHZhbHVlKS50b0J1aWxkZXIoKTsKKyAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2Uoc3ViQnVpbGRlciwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgICByZXR1cm4gKFQpIHN1YkJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgICBjYXNlIEVOVU06CisgICAgICAgIHJldHVybiAoVCkgKGphdmEubGFuZy5JbnRlZ2VyKSBpbnB1dC5yZWFkRW51bSgpOworICAgICAgY2FzZSBHUk9VUDoKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkdyb3VwcyBhcmUgbm90IGFsbG93ZWQgaW4gbWFwcy4iKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiAoVCkgRmllbGRTZXQucmVhZFByaW1pdGl2ZUZpZWxkKGlucHV0LCB0eXBlLCB0cnVlKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFBhcnNlcjxNYXBFbnRyeUxpdGU8SywgVj4+IGdldFBhcnNlckZvclR5cGUoKSB7CisgICAgcmV0dXJuIG1ldGFkYXRhLnBhcnNlcjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgQnVpbGRlcjxLLCBWPiBuZXdCdWlsZGVyRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXI8SywgVj4obWV0YWRhdGEpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBCdWlsZGVyPEssIFY+IHRvQnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXI8SywgVj4obWV0YWRhdGEsIGtleSwgdmFsdWUpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBNYXBFbnRyeUxpdGU8SywgVj4gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gbWV0YWRhdGEuZGVmYXVsdEluc3RhbmNlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CisgICAgaWYgKG1ldGFkYXRhLnZhbHVlVHlwZS5nZXRKYXZhVHlwZSgpID09IFdpcmVGb3JtYXQuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgcmV0dXJuICgoTWVzc2FnZUxpdGUpIHZhbHVlKS5pc0luaXRpYWxpemVkKCk7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqCisgICAqIEJ1aWxkZXIgdXNlZCB0byBjcmVhdGUge0BsaW5rIE1hcEVudHJ5TGl0ZX0gbWVzc2FnZXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEJ1aWxkZXI8SywgVj4KKyAgICAgIGV4dGVuZHMgQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyPEJ1aWxkZXI8SywgVj4+IHsKKyAgICBwcml2YXRlIGZpbmFsIE1ldGFkYXRhPEssIFY+IG1ldGFkYXRhOworICAgIHByaXZhdGUgSyBrZXk7CisgICAgcHJpdmF0ZSBWIHZhbHVlOworICAgIAorICAgIHByaXZhdGUgQnVpbGRlcihNZXRhZGF0YTxLLCBWPiBtZXRhZGF0YSkgeworICAgICAgdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhOworICAgICAgdGhpcy5rZXkgPSBtZXRhZGF0YS5kZWZhdWx0SW5zdGFuY2Uua2V5OworICAgICAgdGhpcy52YWx1ZSA9IG1ldGFkYXRhLmRlZmF1bHRJbnN0YW5jZS52YWx1ZTsKKyAgICB9CisgICAgCisgICAgcHVibGljIEsgZ2V0S2V5KCkgeworICAgICAgcmV0dXJuIGtleTsKKyAgICB9CisgICAgCisgICAgcHVibGljIFYgZ2V0VmFsdWUoKSB7CisgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IHNldEtleShLIGtleSkgeworICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisgICAgCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gc2V0VmFsdWUoViB2YWx1ZSkgeworICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IGNsZWFyS2V5KCkgeworICAgICAgdGhpcy5rZXkgPSBtZXRhZGF0YS5kZWZhdWx0SW5zdGFuY2Uua2V5OworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IGNsZWFyVmFsdWUoKSB7CisgICAgICB0aGlzLnZhbHVlID0gbWV0YWRhdGEuZGVmYXVsdEluc3RhbmNlLnZhbHVlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gY2xlYXIoKSB7CisgICAgICB0aGlzLmtleSA9IG1ldGFkYXRhLmRlZmF1bHRJbnN0YW5jZS5rZXk7CisgICAgICB0aGlzLnZhbHVlID0gbWV0YWRhdGEuZGVmYXVsdEluc3RhbmNlLnZhbHVlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcEVudHJ5TGl0ZTxLLCBWPiBidWlsZCgpIHsKKyAgICAgIE1hcEVudHJ5TGl0ZTxLLCBWPiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKKyAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOworICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWFwRW50cnlMaXRlPEssIFY+IGJ1aWxkUGFydGlhbCgpIHsKKyAgICAgIHJldHVybiBuZXcgTWFwRW50cnlMaXRlPEssIFY+KG1ldGFkYXRhLCBrZXksIHZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKKyAgICAgIHJldHVybiBtZXRhZGF0YS5kZWZhdWx0SW5zdGFuY2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICAgIGlmIChtZXRhZGF0YS52YWx1ZVR5cGUuZ2V0SmF2YVR5cGUoKSA9PSBXaXJlRm9ybWF0LkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgcmV0dXJuICgoTWVzc2FnZUxpdGUpIHZhbHVlKS5pc0luaXRpYWxpemVkKCk7CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIEJ1aWxkZXIoTWV0YWRhdGE8SywgVj4gbWV0YWRhdGEsIEsga2V5LCBWIHZhbHVlKSB7CisgICAgICB0aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7CisgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1aWxkZXI8SywgVj4gY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IEJ1aWxkZXI8SywgVj4obWV0YWRhdGEsIGtleSwgdmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyPEssIFY+IG1lcmdlRnJvbSgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTWFwRW50cnlMaXRlPEssIFY+IGVudHJ5ID0KKyAgICAgICAgICBuZXcgTWFwRW50cnlMaXRlPEssIFY+KG1ldGFkYXRhLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgdGhpcy5rZXkgPSBlbnRyeS5rZXk7CisgICAgICB0aGlzLnZhbHVlID0gZW50cnkudmFsdWU7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZpZWxkLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBGaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyOTA2ZDMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBGaWVsZC5qYXZhCkBAIC0wLDAgKzEsMjU5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBJbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBtYXAgZmllbGRzIGluIGdlbmVyYXRlZCBtZXNzYWdlcy4KKyAqIAorICogVGhpcyBjbGFzcyBzdXBwb3J0cyBhY2Nlc3NpbmcgdGhlIG1hcCBmaWVsZCBhcyBhIHtAbGluayBNYXB9IHRvIGJlIHVzZWQgaW4KKyAqIGdlbmVyYXRlZCBBUEkgYW5kIGFsc28gc3VwcG9ydHMgYWNjZXNzaW5nIHRoZSBmaWVsZCBhcyBhIHtAbGluayBMaXN0fSB0byBiZQorICogdXNlZCBpbiByZWZsZWN0aW9uIEFQSS4gSXQga2VlcHMgdHJhY2sgb2Ygd2hlcmUgdGhlIGRhdGEgaXMgY3VycmVudGx5IHN0b3JlZAorICogYW5kIGRvIG5lY2Vzc2FyeSBjb252ZXJzaW9ucyBiZXR3ZWVuIG1hcCBhbmQgbGlzdC4gIAorICogCisgKiBUaGlzIGNsYXNzIGlzIGEgcHJvdG9idWYgaW1wbGVtZW50YXRpb24gZGV0YWlsLiBVc2VycyBzaG91bGRuJ3QgdXNlIHRoaXMKKyAqIGNsYXNzIGRpcmVjdGx5LgorICogCisgKiBUSFJFQUQtU0FGRVRZIE5PVEU6IFJlYWQtb25seSBhY2Nlc3MgaXMgdGhyZWFkLXNhZmUuIFVzZXJzIGNhbiBjYWxsIGdldE1hcCgpCisgKiBhbmQgZ2V0TGlzdCgpIGNvbmN1cnJlbnRseSBpbiBtdWx0aXBsZSB0aHJlYWRzLiBJZiB3cml0ZS1hY2Nlc3MgaXMgbmVlZGVkLAorICogYWxsIGFjY2VzcyBtdXN0IGJlIHN5bmNocm9uaXplZC4KKyAqLworcHVibGljIGNsYXNzIE1hcEZpZWxkPEssIFY+IHsKKyAgLyoqCisgICAqIEluZGljYXRlcyB3aGVyZSB0aGUgZGF0YSBvZiB0aGlzIG1hcCBmaWVsZCBpcyBjdXJyZW50bHkgc3RvcmVkLgorICAgKiAKKyAgICogTUFQOiBEYXRhIGlzIHN0b3JlZCBpbiBtYXBEYXRhLgorICAgKiBMSVNUOiBEYXRhIGlzIHN0b3JlZCBpbiBsaXN0RGF0YS4KKyAgICogQk9USDogbWFwRGF0YSBhbmQgbGlzdERhdGEgaGF2ZSB0aGUgc2FtZSBkYXRhLgorICAgKgorICAgKiBXaGVuIHRoZSBtYXAgZmllbGQgaXMgYWNjZXNzZWQgKHRocm91Z2ggZ2VuZXJhdGVkIEFQSSBvciByZWZsZWN0aW9uIEFQSSksCisgICAqIGl0IHdpbGwgc2hpZnQgYmV0d2VlbiB0aGVzZSAzIG1vZGVzOgorICAgKiAKKyAgICogICAgICAgICAgZ2V0TWFwKCkgICBnZXRMaXN0KCkgICBnZXRNdXRhYmxlTWFwKCkgICBnZXRNdXRhYmxlTGlzdCgpCisgICAqICAgTUFQICAgICAgTUFQICAgICAgICBCT1RIICAgICAgICAgIE1BUCAgICAgICAgICAgICAgIExJU1QKKyAgICogICBMSVNUICAgICBCT1RIICAgICAgIExJU1QgICAgICAgICAgTUFQICAgICAgICAgICAgICAgTElTVAorICAgKiAgIEJPVEggICAgIEJPVEggICAgICAgQk9USCAgICAgICAgICBNQVAgICAgICAgICAgICAgICBMSVNUCisgICAqICAgCisgICAqIEFzIHRoZSBtYXAgZmllbGQgY2hhbmdlcyBpdHMgbW9kZSwgdGhlIGxpc3QvbWFwIHJlZmVyZW5jZSByZXR1cm5lZCBpbiBhCisgICAqIHByZXZpb3VzIG1ldGhvZCBjYWxsIG1heSBiZSBpbnZhbGlkYXRlZC4gCisgICAqLworICBwcml2YXRlIGVudW0gU3RvcmFnZU1vZGUge01BUCwgTElTVCwgQk9USH0KKworICBwcml2YXRlIHZvbGF0aWxlIFN0b3JhZ2VNb2RlIG1vZGU7CisgIHByaXZhdGUgTWFwPEssIFY+IG1hcERhdGE7CisgIHByaXZhdGUgTGlzdDxNZXNzYWdlPiBsaXN0RGF0YTsKKyAgCisgIC8vIENvbnZlcnQgYmV0d2VlbiBhIG1hcCBlbnRyeSBNZXNzYWdlIGFuZCBhIGtleS12YWx1ZSBwYWlyLgorICBwcml2YXRlIHN0YXRpYyBpbnRlcmZhY2UgQ29udmVydGVyPEssIFY+IHsKKyAgICBNZXNzYWdlIGNvbnZlcnRLZXlBbmRWYWx1ZVRvTWVzc2FnZShLIGtleSwgViB2YWx1ZSk7CisgICAgdm9pZCBjb252ZXJ0TWVzc2FnZVRvS2V5QW5kVmFsdWUoTWVzc2FnZSBtZXNzYWdlLCBNYXA8SywgVj4gbWFwKTsKKyAgICAKKyAgICBNZXNzYWdlIGdldE1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UoKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSW1tdXRhYmxlTWVzc2FnZUNvbnZlcnRlcjxLLCBWPiBpbXBsZW1lbnRzIENvbnZlcnRlcjxLLCBWPiB7CisgICAgcHJpdmF0ZSBmaW5hbCBNYXBFbnRyeTxLLCBWPiBkZWZhdWx0RW50cnk7CisgICAgcHVibGljIEltbXV0YWJsZU1lc3NhZ2VDb252ZXJ0ZXIoTWFwRW50cnk8SywgVj4gZGVmYXVsdEVudHJ5KSB7CisgICAgICB0aGlzLmRlZmF1bHRFbnRyeSA9IGRlZmF1bHRFbnRyeTsKKyAgICB9CisgICAgCisgICAgcHVibGljIE1lc3NhZ2UgY29udmVydEtleUFuZFZhbHVlVG9NZXNzYWdlKEsga2V5LCBWIHZhbHVlKSB7CisgICAgICByZXR1cm4gZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkuc2V0S2V5KGtleSkuc2V0VmFsdWUodmFsdWUpLmJ1aWxkUGFydGlhbCgpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBjb252ZXJ0TWVzc2FnZVRvS2V5QW5kVmFsdWUoTWVzc2FnZSBtZXNzYWdlLCBNYXA8SywgVj4gbWFwKSB7CisgICAgICBNYXBFbnRyeTxLLCBWPiBlbnRyeSA9IChNYXBFbnRyeTxLLCBWPikgbWVzc2FnZTsKKyAgICAgIG1hcC5wdXQoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBNZXNzYWdlIGdldE1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgICByZXR1cm4gZGVmYXVsdEVudHJ5OworICAgIH0KKyAgfQorICAKKworICBwcml2YXRlIGZpbmFsIENvbnZlcnRlcjxLLCBWPiBjb252ZXJ0ZXI7CisgIAorICBwcml2YXRlIE1hcEZpZWxkKAorICAgICAgQ29udmVydGVyPEssIFY+IGNvbnZlcnRlciwKKyAgICAgIFN0b3JhZ2VNb2RlIG1vZGUsCisgICAgICBNYXA8SywgVj4gbWFwRGF0YSwKKyAgICAgIExpc3Q8TWVzc2FnZT4gbGlzdERhdGEpIHsKKyAgICB0aGlzLmNvbnZlcnRlciA9IGNvbnZlcnRlcjsKKyAgICB0aGlzLm1vZGUgPSBtb2RlOworICAgIHRoaXMubWFwRGF0YSA9IG1hcERhdGE7CisgICAgdGhpcy5saXN0RGF0YSA9IGxpc3REYXRhOworICB9CisgICAgCisgIHByaXZhdGUgTWFwRmllbGQoCisgICAgICBNYXBFbnRyeTxLLCBWPiBkZWZhdWx0RW50cnksCisgICAgICBTdG9yYWdlTW9kZSBtb2RlLAorICAgICAgTWFwPEssIFY+IG1hcERhdGEsCisgICAgICBMaXN0PE1lc3NhZ2U+IGxpc3REYXRhKSB7CisgICAgdGhpcyhuZXcgSW1tdXRhYmxlTWVzc2FnZUNvbnZlcnRlcjxLLCBWPihkZWZhdWx0RW50cnkpLCBtb2RlLCBtYXBEYXRhLCBsaXN0RGF0YSk7CisgIH0KKyAgCisgIAorICAvKiogUmV0dXJucyBhbiBpbW11dGFibGUgZW1wdHkgTWFwRmllbGQuICovCisgIHB1YmxpYyBzdGF0aWMgPEssIFY+IE1hcEZpZWxkPEssIFY+IGVtcHR5TWFwRmllbGQoCisgICAgICBNYXBFbnRyeTxLLCBWPiBkZWZhdWx0RW50cnkpIHsKKyAgICByZXR1cm4gbmV3IE1hcEZpZWxkPEssIFY+KAorICAgICAgICBkZWZhdWx0RW50cnksIFN0b3JhZ2VNb2RlLk1BUCwgQ29sbGVjdGlvbnMuPEssIFY+ZW1wdHlNYXAoKSwgbnVsbCk7CisgIH0KKyAgCisgIAorICAvKiogQ3JlYXRlcyBhIG5ldyBtdXRhYmxlIGVtcHR5IE1hcEZpZWxkLiAqLworICBwdWJsaWMgc3RhdGljIDxLLCBWPiBNYXBGaWVsZDxLLCBWPiBuZXdNYXBGaWVsZChNYXBFbnRyeTxLLCBWPiBkZWZhdWx0RW50cnkpIHsKKyAgICByZXR1cm4gbmV3IE1hcEZpZWxkPEssIFY+KAorICAgICAgICBkZWZhdWx0RW50cnksIFN0b3JhZ2VNb2RlLk1BUCwgbmV3IEhhc2hNYXA8SywgVj4oKSwgbnVsbCk7CisgIH0KKyAgCisgIAorICBwcml2YXRlIE1lc3NhZ2UgY29udmVydEtleUFuZFZhbHVlVG9NZXNzYWdlKEsga2V5LCBWIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0S2V5QW5kVmFsdWVUb01lc3NhZ2Uoa2V5LCB2YWx1ZSk7CisgIH0KKyAgCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwcml2YXRlIHZvaWQgY29udmVydE1lc3NhZ2VUb0tleUFuZFZhbHVlKE1lc3NhZ2UgbWVzc2FnZSwgTWFwPEssIFY+IG1hcCkgeworICAgIGNvbnZlcnRlci5jb252ZXJ0TWVzc2FnZVRvS2V5QW5kVmFsdWUobWVzc2FnZSwgbWFwKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdDxNZXNzYWdlPiBjb252ZXJ0TWFwVG9MaXN0KE1hcDxLLCBWPiBtYXBEYXRhKSB7CisgICAgTGlzdDxNZXNzYWdlPiBsaXN0RGF0YSA9IG5ldyBBcnJheUxpc3Q8TWVzc2FnZT4oKTsKKyAgICBmb3IgKE1hcC5FbnRyeTxLLCBWPiBlbnRyeSA6IG1hcERhdGEuZW50cnlTZXQoKSkgeworICAgICAgbGlzdERhdGEuYWRkKAorICAgICAgICAgIGNvbnZlcnRLZXlBbmRWYWx1ZVRvTWVzc2FnZSgKKyAgICAgICAgICAgICAgZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICB9CisgICAgcmV0dXJuIGxpc3REYXRhOworICB9CisKKyAgcHJpdmF0ZSBNYXA8SywgVj4gY29udmVydExpc3RUb01hcChMaXN0PE1lc3NhZ2U+IGxpc3REYXRhKSB7CisgICAgTWFwPEssIFY+IG1hcERhdGEgPSBuZXcgSGFzaE1hcDxLLCBWPigpOworICAgIGZvciAoTWVzc2FnZSBpdGVtIDogbGlzdERhdGEpIHsKKyAgICAgIGNvbnZlcnRNZXNzYWdlVG9LZXlBbmRWYWx1ZShpdGVtLCBtYXBEYXRhKTsKKyAgICB9CisgICAgcmV0dXJuIG1hcERhdGE7CisgIH0KKyAgCisgIC8qKiBSZXR1cm5zIHRoZSBjb250ZW50IG9mIHRoaXMgTWFwRmllbGQgYXMgYSByZWFkLW9ubHkgTWFwLiAqLworICBwdWJsaWMgTWFwPEssIFY+IGdldE1hcCgpIHsKKyAgICBpZiAobW9kZSA9PSBTdG9yYWdlTW9kZS5MSVNUKSB7CisgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgaWYgKG1vZGUgPT0gU3RvcmFnZU1vZGUuTElTVCkgeworICAgICAgICAgIG1hcERhdGEgPSBjb252ZXJ0TGlzdFRvTWFwKGxpc3REYXRhKTsKKyAgICAgICAgICBtb2RlID0gU3RvcmFnZU1vZGUuQk9USDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG1hcERhdGEpOworICB9CisgIAorICAvKiogR2V0cyBhIG11dGFibGUgTWFwIHZpZXcgb2YgdGhpcyBNYXBGaWVsZC4gKi8KKyAgcHVibGljIE1hcDxLLCBWPiBnZXRNdXRhYmxlTWFwKCkgeworICAgIGlmIChtb2RlICE9IFN0b3JhZ2VNb2RlLk1BUCkgeworICAgICAgaWYgKG1vZGUgPT0gU3RvcmFnZU1vZGUuTElTVCkgeworICAgICAgICBtYXBEYXRhID0gY29udmVydExpc3RUb01hcChsaXN0RGF0YSk7CisgICAgICB9CisgICAgICBsaXN0RGF0YSA9IG51bGw7CisgICAgICBtb2RlID0gU3RvcmFnZU1vZGUuTUFQOyAKKyAgICB9CisgICAgcmV0dXJuIG1hcERhdGE7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIG1lcmdlRnJvbShNYXBGaWVsZDxLLCBWPiBvdGhlcikgeworICAgIGdldE11dGFibGVNYXAoKS5wdXRBbGwoTWFwRmllbGRMaXRlLmNvcHkob3RoZXIuZ2V0TWFwKCkpKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgbWFwRGF0YSA9IG5ldyBIYXNoTWFwPEssIFY+KCk7CisgICAgbW9kZSA9IFN0b3JhZ2VNb2RlLk1BUDsKKyAgfQorICAKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIE1hcEZpZWxkKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBNYXBGaWVsZDxLLCBWPiBvdGhlciA9IChNYXBGaWVsZDxLLCBWPikgb2JqZWN0OworICAgIHJldHVybiBNYXBGaWVsZExpdGUuPEssIFY+ZXF1YWxzKGdldE1hcCgpLCBvdGhlci5nZXRNYXAoKSk7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiBNYXBGaWVsZExpdGUuPEssIFY+Y2FsY3VsYXRlSGFzaENvZGVGb3JNYXAoZ2V0TWFwKCkpOworICB9CisgIAorICAvKiogUmV0dXJucyBhIGRlZXAgY29weSBvZiB0aGlzIE1hcEZpZWxkLiAqLworICBwdWJsaWMgTWFwRmllbGQ8SywgVj4gY29weSgpIHsKKyAgICByZXR1cm4gbmV3IE1hcEZpZWxkPEssIFY+KAorICAgICAgICBjb252ZXJ0ZXIsIFN0b3JhZ2VNb2RlLk1BUCwgTWFwRmllbGRMaXRlLmNvcHkoZ2V0TWFwKCkpLCBudWxsKTsKKyAgfQorICAKKyAgLyoqIEdldHMgdGhlIGNvbnRlbnQgb2YgdGhpcyBNYXBGaWVsZCBhcyBhIHJlYWQtb25seSBMaXN0LiAqLworICBMaXN0PE1lc3NhZ2U+IGdldExpc3QoKSB7CisgICAgaWYgKG1vZGUgPT0gU3RvcmFnZU1vZGUuTUFQKSB7CisgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgaWYgKG1vZGUgPT0gU3RvcmFnZU1vZGUuTUFQKSB7CisgICAgICAgICAgbGlzdERhdGEgPSBjb252ZXJ0TWFwVG9MaXN0KG1hcERhdGEpOworICAgICAgICAgIG1vZGUgPSBTdG9yYWdlTW9kZS5CT1RIOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGxpc3REYXRhKTsKKyAgfQorICAKKyAgLyoqIEdldHMgYSBtdXRhYmxlIExpc3QgdmlldyBvZiB0aGlzIE1hcEZpZWxkLiAqLworICBMaXN0PE1lc3NhZ2U+IGdldE11dGFibGVMaXN0KCkgeworICAgIGlmIChtb2RlICE9IFN0b3JhZ2VNb2RlLkxJU1QpIHsKKyAgICAgIGlmIChtb2RlID09IFN0b3JhZ2VNb2RlLk1BUCkgeworICAgICAgICBsaXN0RGF0YSA9IGNvbnZlcnRNYXBUb0xpc3QobWFwRGF0YSk7CisgICAgICB9CisgICAgICBtYXBEYXRhID0gbnVsbDsKKyAgICAgIG1vZGUgPSBTdG9yYWdlTW9kZS5MSVNUOworICAgIH0KKyAgICByZXR1cm4gbGlzdERhdGE7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXRzIHRoZSBkZWZhdWx0IGluc3RhbmNlIG9mIHRoZSBtZXNzYWdlIHN0b3JlZCBpbiB0aGUgbGlzdCB2aWV3IG9mIHRoaXMKKyAgICogbWFwIGZpZWxkLgorICAgKi8KKyAgTWVzc2FnZSBnZXRNYXBFbnRyeU1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgcmV0dXJuIGNvbnZlcnRlci5nZXRNZXNzYWdlRGVmYXVsdEluc3RhbmNlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZpZWxkTGl0ZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRmllbGRMaXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Y5NGM2OQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZpZWxkTGl0ZS5qYXZhCkBAIC0wLDAgKzEsMTgyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBJbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBtYXAgZmllbGRzIGluIGdlbmVyYXRlZCBsaXRlLXJ1bnRpbWUgbWVzc2FnZXMuCisgKiAKKyAqIFRoaXMgY2xhc3MgaXMgYSBwcm90b2J1ZiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwuIFVzZXJzIHNob3VsZG4ndCB1c2UgdGhpcworICogY2xhc3MgZGlyZWN0bHkuCisgKi8KK3B1YmxpYyBjbGFzcyBNYXBGaWVsZExpdGU8SywgVj4geworICBwcml2YXRlIE1hcDxLLCBWPiBtYXBEYXRhOworICAKKyAgcHJpdmF0ZSBNYXBGaWVsZExpdGUoTWFwPEssIFY+IG1hcERhdGEpIHsKKyAgICB0aGlzLm1hcERhdGEgPSBtYXBEYXRhOworICB9CisgIAorICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIiwgInVuY2hlY2tlZCJ9KQorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXBGaWVsZExpdGUgRU1QVFlfTUFQX0ZJRUxEID0KKyAgICAgIG5ldyBNYXBGaWVsZExpdGUoQ29sbGVjdGlvbnMuZW1wdHlNYXAoKSk7CisgIAorICAvKiogUmV0dXJucyBhbiBzaW5nbGV0b24gaW1tdXRhYmxlIGVtcHR5IE1hcEZpZWxkTGl0ZSBpbnN0YW5jZS4gKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCAiY2FzdCJ9KQorICBwdWJsaWMgc3RhdGljIDxLLCBWPiBNYXBGaWVsZExpdGU8SywgVj4gZW1wdHlNYXBGaWVsZCgpIHsKKyAgICByZXR1cm4gKE1hcEZpZWxkTGl0ZTxLLCBWPikgRU1QVFlfTUFQX0ZJRUxEOworICB9CisgIAorICAvKiogQ3JlYXRlcyBhIG5ldyBNYXBGaWVsZExpdGUgaW5zdGFuY2UuICovCisgIHB1YmxpYyBzdGF0aWMgPEssIFY+IE1hcEZpZWxkTGl0ZTxLLCBWPiBuZXdNYXBGaWVsZCgpIHsKKyAgICByZXR1cm4gbmV3IE1hcEZpZWxkTGl0ZTxLLCBWPihuZXcgSGFzaE1hcDxLLCBWPigpKTsKKyAgfQorICAKKyAgLyoqIEdldHMgdGhlIGNvbnRlbnQgb2YgdGhpcyBNYXBGaWVsZCBhcyBhIHJlYWQtb25seSBNYXAuICovCisgIHB1YmxpYyBNYXA8SywgVj4gZ2V0TWFwKCkgeworICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobWFwRGF0YSk7CisgIH0KKyAgCisgIC8qKiBHZXRzIGEgbXV0YWJsZSBNYXAgdmlldyBvZiB0aGlzIE1hcEZpZWxkLiAqLworICBwdWJsaWMgTWFwPEssIFY+IGdldE11dGFibGVNYXAoKSB7CisgICAgcmV0dXJuIG1hcERhdGE7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIG1lcmdlRnJvbShNYXBGaWVsZExpdGU8SywgVj4gb3RoZXIpIHsKKyAgICBtYXBEYXRhLnB1dEFsbChjb3B5KG90aGVyLm1hcERhdGEpKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgbWFwRGF0YS5jbGVhcigpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYSwgT2JqZWN0IGIpIHsKKyAgICBpZiAoYSBpbnN0YW5jZW9mIGJ5dGVbXSAmJiBiIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscygoYnl0ZVtdKSBhLCAoYnl0ZVtdKSBiKTsKKyAgICB9CisgICAgcmV0dXJuIGEuZXF1YWxzKGIpOworICB9CisgIAorICAvKioKKyAgICogQ2hlY2tzIHdoZXRoZXIgdHdvIHtAbGluayBNYXB9cyBhcmUgZXF1YWwuIFdlIGRvbid0IHVzZSB0aGUgZGVmYXVsdCBlcXVhbHMKKyAgICogbWV0aG9kIG9mIHtAbGluayBNYXB9IGJlY2F1c2UgaXQgY29tcGFyZXMgYnkgaWRlbnRpdHkgbm90IGJ5IGNvbnRlbnQgZm9yCisgICAqIGJ5dGUgYXJyYXlzLgorICAgKi8KKyAgc3RhdGljIDxLLCBWPiBib29sZWFuIGVxdWFscyhNYXA8SywgVj4gYSwgTWFwPEssIFY+IGIpIHsKKyAgICBpZiAoYSA9PSBiKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKGEuc2l6ZSgpICE9IGIuc2l6ZSgpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGZvciAoTWFwLkVudHJ5PEssIFY+IGVudHJ5IDogYS5lbnRyeVNldCgpKSB7CisgICAgICBpZiAoIWIuY29udGFpbnNLZXkoZW50cnkuZ2V0S2V5KCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmICghZXF1YWxzKGVudHJ5LmdldFZhbHVlKCksIGIuZ2V0KGVudHJ5LmdldEtleSgpKSkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICAKKyAgLyoqCisgICAqIENoZWNrcyB3aGV0aGVyIHR3byBtYXAgZmllbGRzIGFyZSBlcXVhbC4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBNYXBGaWVsZExpdGUpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIE1hcEZpZWxkTGl0ZTxLLCBWPiBvdGhlciA9IChNYXBGaWVsZExpdGU8SywgVj4pIG9iamVjdDsKKyAgICByZXR1cm4gZXF1YWxzKG1hcERhdGEsIG90aGVyLm1hcERhdGEpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBpbnQgY2FsY3VsYXRlSGFzaENvZGVGb3JPYmplY3QoT2JqZWN0IGEpIHsKKyAgICBpZiAoYSBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgcmV0dXJuIExpdGVyYWxCeXRlU3RyaW5nLmhhc2hDb2RlKChieXRlW10pIGEpOworICAgIH0KKyAgICBpZiAoYSBpbnN0YW5jZW9mIEludGVybmFsLkVudW1MaXRlKSB7CisgICAgICByZXR1cm4gSW50ZXJuYWwuaGFzaEVudW0oKEludGVybmFsLkVudW1MaXRlKSBhKTsKKyAgICB9CisgICAgcmV0dXJuIGEuaGFzaENvZGUoKTsKKyAgfQorCisgIC8qKgorICAgKiBDYWxjdWxhdGVzIHRoZSBoYXNoIGNvZGUgZm9yIGEge0BsaW5rIE1hcH0uIFdlIGRvbid0IHVzZSB0aGUgZGVmYXVsdCBoYXNoCisgICAqIGNvZGUgbWV0aG9kIG9mIHtAbGluayBNYXB9IGJlY2F1c2UgZm9yIGJ5dGUgYXJyYXlzIGFuZCBwcm90b2J1ZiBlbnVtcyBpdAorICAgKiB1c2Uge0BsaW5rIE9iamVjdCNoYXNoQ29kZSgpfS4KKyAgICovCisgIHN0YXRpYyA8SywgVj4gaW50IGNhbGN1bGF0ZUhhc2hDb2RlRm9yTWFwKE1hcDxLLCBWPiBhKSB7CisgICAgaW50IHJlc3VsdCA9IDA7CisgICAgZm9yIChNYXAuRW50cnk8SywgVj4gZW50cnkgOiBhLmVudHJ5U2V0KCkpIHsKKyAgICAgIHJlc3VsdCArPSBjYWxjdWxhdGVIYXNoQ29kZUZvck9iamVjdChlbnRyeS5nZXRLZXkoKSkKKyAgICAgICAgICBeIGNhbGN1bGF0ZUhhc2hDb2RlRm9yT2JqZWN0KGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OyAgICAKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIGNhbGN1bGF0ZUhhc2hDb2RlRm9yTWFwKG1hcERhdGEpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBPYmplY3QgY29weShPYmplY3Qgb2JqZWN0KSB7CisgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgYnl0ZVtdIGRhdGEgPSAoYnl0ZVtdKSBvYmplY3Q7CisgICAgICByZXR1cm4gQXJyYXlzLmNvcHlPZihkYXRhLCBkYXRhLmxlbmd0aCk7CisgICAgfQorICAgIHJldHVybiBvYmplY3Q7CisgIH0KKyAgCisgIC8qKgorICAgKiBNYWtlcyBhIGRlZXAgY29weSBvZiBhIHtAbGluayBNYXB9LiBJbW11dGFibGUgb2JqZWN0cyBpbiB0aGUgbWFwIHdpbGwgYmUKKyAgICogc2hhcmVkIChlLmcuLCBpbnRlZ2Vycywgc3RyaW5ncywgaW1tdXRhYmxlIG1lc3NhZ2VzKSBhbmQgbXV0YWJsZSBvbmVzIHdpbGwKKyAgICogaGF2ZSBhIGNvcHkgKGUuZy4sIGJ5dGUgYXJyYXlzLCBtdXRhYmxlIG1lc3NhZ2VzKS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBzdGF0aWMgPEssIFY+IE1hcDxLLCBWPiBjb3B5KE1hcDxLLCBWPiBtYXApIHsKKyAgICBNYXA8SywgVj4gcmVzdWx0ID0gbmV3IEhhc2hNYXA8SywgVj4oKTsKKyAgICBmb3IgKE1hcC5FbnRyeTxLLCBWPiBlbnRyeSA6IG1hcC5lbnRyeVNldCgpKSB7CisgICAgICByZXN1bHQucHV0KGVudHJ5LmdldEtleSgpLCAoVikgY29weShlbnRyeS5nZXRWYWx1ZSgpKSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qKiBSZXR1cm5zIGEgZGVlcCBjb3B5IG9mIHRoaXMgbWFwIGZpZWxkLiAqLworICBwdWJsaWMgTWFwRmllbGRMaXRlPEssIFY+IGNvcHkoKSB7CisgICAgcmV0dXJuIG5ldyBNYXBGaWVsZExpdGU8SywgVj4oY29weShtYXBEYXRhKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2UuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYTAyNjVlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsMjYzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVE9ETyhrZW50b24pOiAgVXNlIGdlbmVyaWNzPyAgRS5nLiBCdWlsZGVyPEJ1aWxkZXJUeXBlIGV4dGVuZHMgQnVpbGRlcj4sIHRoZW4KKy8vICAgbWVyZ2VGcm9tKigpIGNvdWxkIHJldHVybiBCdWlsZGVyVHlwZSBmb3IgYmV0dGVyIHR5cGUtc2FmZXR5LgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBYnN0cmFjdCBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgUHJvdG9jb2wgTWVzc2FnZSBvYmplY3RzLgorICogPHA+CisgKiBTZWUgYWxzbyB7QGxpbmsgTWVzc2FnZUxpdGV9LCB3aGljaCBkZWZpbmVzIG1vc3Qgb2YgdGhlIG1ldGhvZHMgdGhhdCB0eXBpY2FsCisgKiB1c2VycyBjYXJlIGFib3V0LiAge0BsaW5rIE1lc3NhZ2V9IGFkZHMgdG8gaXQgbWV0aG9kcyB0aGF0IGFyZSBub3QgYXZhaWxhYmxlCisgKiBpbiB0aGUgImxpdGUiIHJ1bnRpbWUuICBUaGUgYmlnZ2VzdCBhZGRlZCBmZWF0dXJlcyBhcmUgaW50cm9zcGVjdGlvbiBhbmQKKyAqIHJlZmxlY3Rpb24gLS0gaS5lLiwgZ2V0dGluZyBkZXNjcmlwdG9ycyBmb3IgdGhlIG1lc3NhZ2UgdHlwZSBhbmQgYWNjZXNzaW5nCisgKiB0aGUgZmllbGQgdmFsdWVzIGR5bmFtaWNhbGx5LgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZSBleHRlbmRzIE1lc3NhZ2VMaXRlLCBNZXNzYWdlT3JCdWlsZGVyIHsKKworICAvLyAoRnJvbSBNZXNzYWdlTGl0ZSwgcmUtZGVjbGFyZWQgaGVyZSBvbmx5IGZvciByZXR1cm4gdHlwZSBjb3ZhcmlhbmNlLikKKyAgUGFyc2VyPD8gZXh0ZW5kcyBNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBDb21wYXJpc29uIGFuZCBoYXNoaW5nCisKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHdpdGggdGhpcyBtZXNzYWdlIGZvciBlcXVhbGl0eS4gIFJldHVybnMKKyAgICoge0Bjb2RlIHRydWV9IGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBtZXNzYWdlIG9mIHRoZSBzYW1lIHR5cGUgKGFzCisgICAqIGRlZmluZWQgYnkge0Bjb2RlIGdldERlc2NyaXB0b3JGb3JUeXBlKCl9KSBhbmQgaGFzIGlkZW50aWNhbCB2YWx1ZXMgZm9yCisgICAqIGFsbCBvZiBpdHMgZmllbGRzLiAgU3ViY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGlzOyBpbmhlcml0aW5nCisgICAqIHtAY29kZSBPYmplY3QuZXF1YWxzKCl9IGlzIGluY29ycmVjdC4KKyAgICoKKyAgICogQHBhcmFtIG90aGVyIG9iamVjdCB0byBiZSBjb21wYXJlZCBmb3IgZXF1YWxpdHkgd2l0aCB0aGlzIG1lc3NhZ2UKKyAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyBtZXNzYWdlCisgICAqLworICBAT3ZlcnJpZGUKKyAgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKTsKKworICAvKioKKyAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIG1lc3NhZ2UuICBUaGUgaGFzaCBjb2RlIG9mIGEgbWVzc2FnZQorICAgKiBzaG91bGQgbWl4IHRoZSBtZXNzYWdlJ3MgdHlwZSAob2JqZWN0IGlkZW50aXR5IG9mIHRoZSBkZXNjcmlwdG9yKSB3aXRoIGl0cworICAgKiBjb250ZW50cyAoa25vd24gYW5kIHVua25vd24gZmllbGQgdmFsdWVzKS4gIFN1YmNsYXNzZXMgbXVzdCBpbXBsZW1lbnQgdGhpczsKKyAgICogaW5oZXJpdGluZyB7QGNvZGUgT2JqZWN0Lmhhc2hDb2RlKCl9IGlzIGluY29ycmVjdC4KKyAgICoKKyAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIG1lc3NhZ2UKKyAgICogQHNlZSBNYXAjaGFzaENvZGUoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIGludCBoYXNoQ29kZSgpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIENvbnZlbmllbmNlIG1ldGhvZHMuCisKKyAgLyoqCisgICAqIENvbnZlcnRzIHRoZSBtZXNzYWdlIHRvIGEgc3RyaW5nIGluIHByb3RvY29sIGJ1ZmZlciB0ZXh0IGZvcm1hdC4gVGhpcyBpcworICAgKiBqdXN0IGEgdHJpdmlhbCB3cmFwcGVyIGFyb3VuZCB7QGxpbmsKKyAgICogVGV4dEZvcm1hdCNwcmludFRvU3RyaW5nKE1lc3NhZ2VPckJ1aWxkZXIpfS4KKyAgICovCisgIEBPdmVycmlkZQorICBTdHJpbmcgdG9TdHJpbmcoKTsKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBCdWlsZGVycworCisgIC8vIChGcm9tIE1lc3NhZ2VMaXRlLCByZS1kZWNsYXJlZCBoZXJlIG9ubHkgZm9yIHJldHVybiB0eXBlIGNvdmFyaWFuY2UuKQorICBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCk7CisgIEJ1aWxkZXIgdG9CdWlsZGVyKCk7CisKKyAgLyoqCisgICAqIEFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBQcm90b2NvbCBNZXNzYWdlIGJ1aWxkZXJzLgorICAgKi8KKyAgaW50ZXJmYWNlIEJ1aWxkZXIgZXh0ZW5kcyBNZXNzYWdlTGl0ZS5CdWlsZGVyLCBNZXNzYWdlT3JCdWlsZGVyIHsKKyAgICAvLyAoRnJvbSBNZXNzYWdlTGl0ZS5CdWlsZGVyLCByZS1kZWNsYXJlZCBoZXJlIG9ubHkgZm9yIHJldHVybiB0eXBlCisgICAgLy8gY292YXJpYW5jZS4pCisgICAgQnVpbGRlciBjbGVhcigpOworCisgICAgLyoqCisgICAgICogTWVyZ2Uge0Bjb2RlIG90aGVyfSBpbnRvIHRoZSBtZXNzYWdlIGJlaW5nIGJ1aWx0LiAge0Bjb2RlIG90aGVyfSBtdXN0CisgICAgICogaGF2ZSB0aGUgZXhhY3Qgc2FtZSB0eXBlIGFzIHtAY29kZSB0aGlzfSAoaS5lLgorICAgICAqIHtAY29kZSBnZXREZXNjcmlwdG9yRm9yVHlwZSgpID09IG90aGVyLmdldERlc2NyaXB0b3JGb3JUeXBlKCl9KS4KKyAgICAgKgorICAgICAqIE1lcmdpbmcgb2NjdXJzIGFzIGZvbGxvd3MuICBGb3IgZWFjaCBmaWVsZDo8YnI+CisgICAgICogKiBGb3Igc2luZ3VsYXIgcHJpbWl0aXZlIGZpZWxkcywgaWYgdGhlIGZpZWxkIGlzIHNldCBpbiB7QGNvZGUgb3RoZXJ9LAorICAgICAqICAgdGhlbiB7QGNvZGUgb3RoZXJ9J3MgdmFsdWUgb3ZlcndyaXRlcyB0aGUgdmFsdWUgaW4gdGhpcyBtZXNzYWdlLjxicj4KKyAgICAgKiAqIEZvciBzaW5ndWxhciBtZXNzYWdlIGZpZWxkcywgaWYgdGhlIGZpZWxkIGlzIHNldCBpbiB7QGNvZGUgb3RoZXJ9LAorICAgICAqICAgaXQgaXMgbWVyZ2VkIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgc3ViLW1lc3NhZ2Ugb2YgdGhpcyBtZXNzYWdlCisgICAgICogICB1c2luZyB0aGUgc2FtZSBtZXJnaW5nIHJ1bGVzLjxicj4KKyAgICAgKiAqIEZvciByZXBlYXRlZCBmaWVsZHMsIHRoZSBlbGVtZW50cyBpbiB7QGNvZGUgb3RoZXJ9IGFyZSBjb25jYXRlbmF0ZWQKKyAgICAgKiAgIHdpdGggdGhlIGVsZW1lbnRzIGluIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byB0aGUge0Bjb2RlIE1lc3NhZ2U6Ok1lcmdlRnJvbX0gbWV0aG9kIGluIEMrKy4KKyAgICAgKi8KKyAgICBCdWlsZGVyIG1lcmdlRnJvbShNZXNzYWdlIG90aGVyKTsKKworICAgIC8vIChGcm9tIE1lc3NhZ2VMaXRlLkJ1aWxkZXIsIHJlLWRlY2xhcmVkIGhlcmUgb25seSBmb3IgcmV0dXJuIHR5cGUKKyAgICAvLyBjb3ZhcmlhbmNlLikKKyAgICBNZXNzYWdlIGJ1aWxkKCk7CisgICAgTWVzc2FnZSBidWlsZFBhcnRpYWwoKTsKKyAgICBCdWlsZGVyIGNsb25lKCk7CisgICAgQnVpbGRlciBtZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIEJ1aWxkZXIgbWVyZ2VGcm9tKENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbWVzc2FnZSdzIHR5cGUncyBkZXNjcmlwdG9yLgorICAgICAqIFNlZSB7QGxpbmsgTWVzc2FnZSNnZXREZXNjcmlwdG9yRm9yVHlwZSgpfS4KKyAgICAgKi8KKyAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBCdWlsZGVyIGZvciBtZXNzYWdlcyBvZiB0aGUgYXBwcm9wcmlhdGUgdHlwZSBmb3IgdGhlIGdpdmVuCisgICAgICogZmllbGQuICBNZXNzYWdlcyBidWlsdCB3aXRoIHRoaXMgY2FuIHRoZW4gYmUgcGFzc2VkIHRvIHNldEZpZWxkKCksCisgICAgICogc2V0UmVwZWF0ZWRGaWVsZCgpLCBvciBhZGRSZXBlYXRlZEZpZWxkKCkuCisgICAgICovCisgICAgQnVpbGRlciBuZXdCdWlsZGVyRm9yRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKTsKKworICAgIC8qKgorICAgICAqIEdldCBhIG5lc3RlZCBidWlsZGVyIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gZmllbGQuCisgICAgICogPHA+CisgICAgICogTm9ybWFsbHksIHdlIGhvbGQgYSByZWZlcmVuY2UgdG8gdGhlIGltbXV0YWJsZSBtZXNzYWdlIG9iamVjdCBmb3IgdGhlCisgICAgICogbWVzc2FnZSB0eXBlIGZpZWxkLiBTb21lIGltcGxlbWVudGF0aW9ucyh0aGUgZ2VuZXJhdGVkIG1lc3NhZ2UgYnVpbGRlcnMpLAorICAgICAqIGhvd2V2ZXIsIGNhbiBhbHNvIGhvbGQgYSByZWZlcmVuY2UgdG8gdGhlIGJ1aWxkZXIgb2JqZWN0IChhIG5lc3RlZAorICAgICAqIGJ1aWxkZXIpIGZvciB0aGUgZmllbGQuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIGZpZWxkIGlzIGFscmVhZHkgYmFja2VkIHVwIGJ5IGEgbmVzdGVkIGJ1aWxkZXIsIHRoZSBuZXN0ZWQgYnVpbGRlcgorICAgICAqIHdpbGwgYmUgcmV0dXJuZWQuIE90aGVyd2lzZSwgYSBuZXcgZmllbGQgYnVpbGRlciB3aWxsIGJlIGNyZWF0ZWQgYW5kCisgICAgICogcmV0dXJuZWQuIFRoZSBvcmlnaW5hbCBtZXNzYWdlIGZpZWxkIChpZiBleGlzdCkgd2lsbCBiZSBtZXJnZWQgaW50byB0aGUKKyAgICAgKiBmaWVsZCBidWlsZGVyLCB3aGljaCB3aWxsIHRoZW4gYmUgbmVzdGVkIGludG8gaXRzIHBhcmVudCBidWlsZGVyLgorICAgICAqIDxwPgorICAgICAqIE5PVEU6IGltcGxlbWVudGF0aW9ucyB0aGF0IGRvIG5vdCBzdXBwb3J0IG5lc3RlZCBidWlsZGVycyB3aWxsIHRocm93CisgICAgICogPGNvZGU+VW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb248L2NvZGU+LgorICAgICAqLworICAgIEJ1aWxkZXIgZ2V0RmllbGRCdWlsZGVyKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBuZXN0ZWQgYnVpbGRlciBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIHJlcGVhdGVkIGZpZWxkIGluc3RhbmNlLgorICAgICAqIDxwPgorICAgICAqIE5vcm1hbGx5LCB3ZSBob2xkIGEgcmVmZXJlbmNlIHRvIHRoZSBpbW11dGFibGUgbWVzc2FnZSBvYmplY3QgZm9yIHRoZQorICAgICAqIG1lc3NhZ2UgdHlwZSBmaWVsZC4gU29tZSBpbXBsZW1lbnRhdGlvbnModGhlIGdlbmVyYXRlZCBtZXNzYWdlIGJ1aWxkZXJzKSwKKyAgICAgKiBob3dldmVyLCBjYW4gYWxzbyBob2xkIGEgcmVmZXJlbmNlIHRvIHRoZSBidWlsZGVyIG9iamVjdCAoYSBuZXN0ZWQKKyAgICAgKiBidWlsZGVyKSBmb3IgdGhlIGZpZWxkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBmaWVsZCBpcyBhbHJlYWR5IGJhY2tlZCB1cCBieSBhIG5lc3RlZCBidWlsZGVyLCB0aGUgbmVzdGVkIGJ1aWxkZXIKKyAgICAgKiB3aWxsIGJlIHJldHVybmVkLiBPdGhlcndpc2UsIGEgbmV3IGZpZWxkIGJ1aWxkZXIgd2lsbCBiZSBjcmVhdGVkIGFuZAorICAgICAqIHJldHVybmVkLiBUaGUgb3JpZ2luYWwgbWVzc2FnZSBmaWVsZCAoaWYgZXhpc3QpIHdpbGwgYmUgbWVyZ2VkIGludG8gdGhlCisgICAgICogZmllbGQgYnVpbGRlciwgd2hpY2ggd2lsbCB0aGVuIGJlIG5lc3RlZCBpbnRvIGl0cyBwYXJlbnQgYnVpbGRlci4KKyAgICAgKiA8cD4KKyAgICAgKiBOT1RFOiBpbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qgc3VwcG9ydCBuZXN0ZWQgYnVpbGRlcnMgd2lsbCB0aHJvdworICAgICAqIDxjb2RlPlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uPC9jb2RlPi4KKyAgICAgKi8KKyAgICBCdWlsZGVyIGdldFJlcGVhdGVkRmllbGRCdWlsZGVyKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgZmllbGQgdG8gdGhlIGdpdmVuIHZhbHVlLiAgVGhlIHZhbHVlIG11c3QgYmUgb2YgdGhlIGNvcnJlY3QgdHlwZQorICAgICAqIGZvciB0aGlzIGZpZWxkLCBpLmUuIHRoZSBzYW1lIHR5cGUgdGhhdAorICAgICAqIHtAbGluayBNZXNzYWdlI2dldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcil9IHdvdWxkIHJldHVybi4KKyAgICAgKi8KKyAgICBCdWlsZGVyIHNldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwgT2JqZWN0IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIENsZWFycyB0aGUgZmllbGQuICBUaGlzIGlzIGV4YWN0bHkgZXF1aXZhbGVudCB0byBjYWxsaW5nIHRoZSBnZW5lcmF0ZWQKKyAgICAgKiAiY2xlYXIiIGFjY2Vzc29yIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaWVsZC4KKyAgICAgKi8KKyAgICBCdWlsZGVyIGNsZWFyRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKTsKKworICAgIC8qKgorICAgICAqIENsZWFycyB0aGUgb25lb2YuICBUaGlzIGlzIGV4YWN0bHkgZXF1aXZhbGVudCB0byBjYWxsaW5nIHRoZSBnZW5lcmF0ZWQKKyAgICAgKiAiY2xlYXIiIGFjY2Vzc29yIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBvbmVvZi4KKyAgICAgKi8KKyAgICBCdWlsZGVyIGNsZWFyT25lb2YoRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKTsKKworICAgIC8qKgorICAgICAqIFNldHMgYW4gZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkIHRvIHRoZSBnaXZlbiB2YWx1ZS4gIFRoZSB2YWx1ZSBtdXN0CisgICAgICogYmUgb2YgdGhlIGNvcnJlY3QgdHlwZSBmb3IgdGhpcyBmaWVsZCwgaS5lLiB0aGUgc2FtZSB0eXBlIHRoYXQKKyAgICAgKiB7QGxpbmsgTWVzc2FnZSNnZXRSZXBlYXRlZEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcixpbnQpfSB3b3VsZAorICAgICAqIHJldHVybi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBUaGUgZmllbGQgaXMgbm90IGEgcmVwZWF0ZWQgZmllbGQsIG9yCisgICAgICogICAgICAgICAgIHtAY29kZSBmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpICE9IGdldERlc2NyaXB0b3JGb3JUeXBlKCl9LgorICAgICAqLworICAgIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgT2JqZWN0IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIExpa2Uge0Bjb2RlIHNldFJlcGVhdGVkRmllbGR9LCBidXQgYXBwZW5kcyB0aGUgdmFsdWUgYXMgYSBuZXcgZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBUaGUgZmllbGQgaXMgbm90IGEgcmVwZWF0ZWQgZmllbGQsIG9yCisgICAgICogICAgICAgICAgIHtAY29kZSBmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpICE9IGdldERlc2NyaXB0b3JGb3JUeXBlKCl9LgorICAgICAqLworICAgIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIE9iamVjdCB2YWx1ZSk7CisKKyAgICAvKiogU2V0IHRoZSB7QGxpbmsgVW5rbm93bkZpZWxkU2V0fSBmb3IgdGhpcyBtZXNzYWdlLiAqLworICAgIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcyhVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcyk7CisKKyAgICAvKioKKyAgICAgKiBNZXJnZSBzb21lIHVua25vd24gZmllbGRzIGludG8gdGhlIHtAbGluayBVbmtub3duRmllbGRTZXR9IGZvciB0aGlzCisgICAgICogbWVzc2FnZS4KKyAgICAgKi8KKyAgICBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcyhVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcyk7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyBDb252ZW5pZW5jZSBtZXRob2RzLgorCisgICAgLy8gKEZyb20gTWVzc2FnZUxpdGUuQnVpbGRlciwgcmUtZGVjbGFyZWQgaGVyZSBvbmx5IGZvciByZXR1cm4gdHlwZQorICAgIC8vIGNvdmFyaWFuY2UuKQorICAgIEJ1aWxkZXIgbWVyZ2VGcm9tKEJ5dGVTdHJpbmcgZGF0YSkgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKyAgICBCdWlsZGVyIG1lcmdlRnJvbShCeXRlU3RyaW5nIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisgICAgQnVpbGRlciBtZXJnZUZyb20oYnl0ZVtdIGRhdGEpIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisgICAgQnVpbGRlciBtZXJnZUZyb20oYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKyAgICBCdWlsZGVyIG1lcmdlRnJvbShieXRlW10gZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKyAgICBCdWlsZGVyIG1lcmdlRnJvbShieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKyAgICBCdWlsZGVyIG1lcmdlRnJvbShJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIEJ1aWxkZXIgbWVyZ2VGcm9tKElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgYm9vbGVhbiBtZXJnZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIGJvb2xlYW4gbWVyZ2VEZWxpbWl0ZWRGcm9tKElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VMaXRlLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlTGl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc5OGI3OTQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlTGl0ZS5qYXZhCkBAIC0wLDAgKzEsMzIwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVE9ETyhrZW50b24pOiAgVXNlIGdlbmVyaWNzPyAgRS5nLiBCdWlsZGVyPEJ1aWxkZXJUeXBlIGV4dGVuZHMgQnVpbGRlcj4sIHRoZW4KKy8vICAgbWVyZ2VGcm9tKigpIGNvdWxkIHJldHVybiBCdWlsZGVyVHlwZSBmb3IgYmV0dGVyIHR5cGUtc2FmZXR5LgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogQWJzdHJhY3QgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IFByb3RvY29sIE1lc3NhZ2Ugb2JqZWN0cy4KKyAqCisgKiA8cD5UaGlzIGludGVyZmFjZSBpcyBpbXBsZW1lbnRlZCBieSBhbGwgcHJvdG9jb2wgbWVzc2FnZSBvYmplY3RzLiAgTm9uLWxpdGUKKyAqIG1lc3NhZ2VzIGFkZGl0aW9uYWxseSBpbXBsZW1lbnQgdGhlIE1lc3NhZ2UgaW50ZXJmYWNlLCB3aGljaCBpcyBhIHN1YmNsYXNzCisgKiBvZiBNZXNzYWdlTGl0ZS4gIFVzZSBNZXNzYWdlTGl0ZSBpbnN0ZWFkIHdoZW4geW91IG9ubHkgbmVlZCB0aGUgc3Vic2V0IG9mCisgKiBmZWF0dXJlcyB3aGljaCBpdCBzdXBwb3J0cyAtLSBuYW1lbHksIG5vdGhpbmcgdGhhdCB1c2VzIGRlc2NyaXB0b3JzIG9yCisgKiByZWZsZWN0aW9uLiAgWW91IGNhbiBpbnN0cnVjdCB0aGUgcHJvdG9jb2wgY29tcGlsZXIgdG8gZ2VuZXJhdGUgY2xhc3NlcworICogd2hpY2ggaW1wbGVtZW50IG9ubHkgTWVzc2FnZUxpdGUsIG5vdCB0aGUgZnVsbCBNZXNzYWdlIGludGVyZmFjZSwgYnkgYWRkaW5nCisgKiB0aGUgZm9sbG93IGxpbmUgdG8gdGhlIC5wcm90byBmaWxlOgorICogPHByZT4KKyAqICAgb3B0aW9uIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRTsKKyAqIDwvcHJlPgorICoKKyAqIDxwPlRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBvbiByZXNvdXJjZS1jb25zdHJhaW5lZCBzeXN0ZW1zIHdoZXJlIHRoZQorICogZnVsbCBwcm90b2NvbCBidWZmZXJzIHJ1bnRpbWUgbGlicmFyeSBpcyB0b28gYmlnLgorICoKKyAqIDxwPk5vdGUgdGhhdCBvbiBub24tY29uc3RyYWluZWQgc3lzdGVtcyAoZS5nLiBzZXJ2ZXJzKSB3aGVuIHlvdSBuZWVkIHRvIGxpbmsKKyAqIGluIGxvdHMgb2YgcHJvdG9jb2wgZGVmaW5pdGlvbnMsIGEgYmV0dGVyIHdheSB0byByZWR1Y2UgdG90YWwgY29kZSBmb290cHJpbnQKKyAqIGlzIHRvIHVzZSB7QGNvZGUgb3B0aW1pemVfZm9yID0gQ09ERV9TSVpFfS4gIFRoaXMgd2lsbCBtYWtlIHRoZSBnZW5lcmF0ZWQKKyAqIGNvZGUgc21hbGxlciB3aGlsZSBzdGlsbCBzdXBwb3J0aW5nIGFsbCB0aGUgc2FtZSBmZWF0dXJlcyAoYXQgdGhlIGV4cGVuc2Ugb2YKKyAqIHNwZWVkKS4gIHtAY29kZSBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUV9IGlzIGJlc3Qgd2hlbiB5b3Ugb25seSBoYXZlIGEKKyAqIHNtYWxsIG51bWJlciBvZiBtZXNzYWdlIHR5cGVzIGxpbmtlZCBpbnRvIHlvdXIgYmluYXJ5LCBpbiB3aGljaCBjYXNlIHRoZQorICogc2l6ZSBvZiB0aGUgcHJvdG9jb2wgYnVmZmVycyBydW50aW1lIGl0c2VsZiBpcyB0aGUgYmlnZ2VzdCBwcm9ibGVtLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZUxpdGUgZXh0ZW5kcyBNZXNzYWdlTGl0ZU9yQnVpbGRlciB7CisKKworICAvKioKKyAgICogU2VyaWFsaXplcyB0aGUgbWVzc2FnZSBhbmQgd3JpdGVzIGl0IHRvIHtAY29kZSBvdXRwdXR9LiAgVGhpcyBkb2VzIG5vdAorICAgKiBmbHVzaCBvciBjbG9zZSB0aGUgc3RyZWFtLgorICAgKi8KKyAgdm9pZCB3cml0ZVRvKENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBHZXQgdGhlIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBlbmNvZGUgdGhpcyBtZXNzYWdlLiAgVGhlIHJlc3VsdAorICAgKiBpcyBvbmx5IGNvbXB1dGVkIG9uIHRoZSBmaXJzdCBjYWxsIGFuZCBtZW1vaXplZCBhZnRlciB0aGF0LgorICAgKi8KKyAgaW50IGdldFNlcmlhbGl6ZWRTaXplKCk7CisKKworICAvKioKKyAgICogR2V0cyB0aGUgcGFyc2VyIGZvciBhIG1lc3NhZ2Ugb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGlzIG1lc3NhZ2UuCisgICAqLworICBQYXJzZXI8PyBleHRlbmRzIE1lc3NhZ2VMaXRlPiBnZXRQYXJzZXJGb3JUeXBlKCk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gQ29udmVuaWVuY2UgbWV0aG9kcy4KKworICAvKioKKyAgICogU2VyaWFsaXplcyB0aGUgbWVzc2FnZSB0byBhIHtAY29kZSBCeXRlU3RyaW5nfSBhbmQgcmV0dXJucyBpdC4gVGhpcyBpcworICAgKiBqdXN0IGEgdHJpdmlhbCB3cmFwcGVyIGFyb3VuZAorICAgKiB7QGxpbmsgI3dyaXRlVG8oQ29kZWRPdXRwdXRTdHJlYW0pfS4KKyAgICovCisgIEJ5dGVTdHJpbmcgdG9CeXRlU3RyaW5nKCk7CisKKyAgLyoqCisgICAqIFNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgdG8gYSB7QGNvZGUgYnl0ZX0gYXJyYXkgYW5kIHJldHVybnMgaXQuICBUaGlzIGlzCisgICAqIGp1c3QgYSB0cml2aWFsIHdyYXBwZXIgYXJvdW5kCisgICAqIHtAbGluayAjd3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbSl9LgorICAgKi8KKyAgYnl0ZVtdIHRvQnl0ZUFycmF5KCk7CisKKyAgLyoqCisgICAqIFNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgYW5kIHdyaXRlcyBpdCB0byB7QGNvZGUgb3V0cHV0fS4gIFRoaXMgaXMganVzdCBhCisgICAqIHRyaXZpYWwgd3JhcHBlciBhcm91bmQge0BsaW5rICN3cml0ZVRvKENvZGVkT3V0cHV0U3RyZWFtKX0uICBUaGlzIGRvZXMKKyAgICogbm90IGZsdXNoIG9yIGNsb3NlIHRoZSBzdHJlYW0uCisgICAqIDxwPgorICAgKiBOT1RFOiAgUHJvdG9jb2wgQnVmZmVycyBhcmUgbm90IHNlbGYtZGVsaW1pdGluZy4gIFRoZXJlZm9yZSwgaWYgeW91IHdyaXRlCisgICAqIGFueSBtb3JlIGRhdGEgdG8gdGhlIHN0cmVhbSBhZnRlciB0aGUgbWVzc2FnZSwgeW91IG11c3Qgc29tZWhvdyBlbnN1cmUKKyAgICogdGhhdCB0aGUgcGFyc2VyIG9uIHRoZSByZWNlaXZpbmcgZW5kIGRvZXMgbm90IGludGVycHJldCB0aGlzIGFzIGJlaW5nCisgICAqIHBhcnQgb2YgdGhlIHByb3RvY29sIG1lc3NhZ2UuICBUaGlzIGNhbiBiZSBkb25lIGUuZy4gYnkgd3JpdGluZyB0aGUgc2l6ZQorICAgKiBvZiB0aGUgbWVzc2FnZSBiZWZvcmUgdGhlIGRhdGEsIHRoZW4gbWFraW5nIHN1cmUgdG8gbGltaXQgdGhlIGlucHV0IHRvCisgICAqIHRoYXQgc2l6ZSBvbiB0aGUgcmVjZWl2aW5nIGVuZCAoZS5nLiBieSB3cmFwcGluZyB0aGUgSW5wdXRTdHJlYW0gaW4gb25lCisgICAqIHdoaWNoIGxpbWl0cyB0aGUgaW5wdXQpLiAgQWx0ZXJuYXRpdmVseSwganVzdCB1c2UKKyAgICoge0BsaW5rICN3cml0ZURlbGltaXRlZFRvKE91dHB1dFN0cmVhbSl9LgorICAgKi8KKyAgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3dyaXRlVG8oT3V0cHV0U3RyZWFtKX0sIGJ1dCB3cml0ZXMgdGhlIHNpemUgb2YgdGhlIG1lc3NhZ2UKKyAgICogYXMgYSB2YXJpbnQgYmVmb3JlIHdyaXRpbmcgdGhlIGRhdGEuICBUaGlzIGFsbG93cyBtb3JlIGRhdGEgdG8gYmUgd3JpdHRlbgorICAgKiB0byB0aGUgc3RyZWFtIGFmdGVyIHRoZSBtZXNzYWdlIHdpdGhvdXQgdGhlIG5lZWQgdG8gZGVsaW1pdCB0aGUgbWVzc2FnZQorICAgKiBkYXRhIHlvdXJzZWxmLiAgVXNlIHtAbGluayBCdWlsZGVyI21lcmdlRGVsaW1pdGVkRnJvbShJbnB1dFN0cmVhbSl9IChvcgorICAgKiB0aGUgc3RhdGljIG1ldGhvZCB7QGNvZGUgWW91ck1lc3NhZ2VUeXBlLnBhcnNlRGVsaW1pdGVkRnJvbShJbnB1dFN0cmVhbSl9KQorICAgKiB0byBwYXJzZSBtZXNzYWdlcyB3cml0dGVuIGJ5IHRoaXMgbWV0aG9kLgorICAgKi8KKyAgdm9pZCB3cml0ZURlbGltaXRlZFRvKE91dHB1dFN0cmVhbSBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIEJ1aWxkZXJzCisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcgYnVpbGRlciBmb3IgYSBtZXNzYWdlIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhpcyBtZXNzYWdlLgorICAgKi8KKyAgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpOworCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIGEgYnVpbGRlciBpbml0aWFsaXplZCB3aXRoIHRoZSBjdXJyZW50IG1lc3NhZ2UuICBVc2UgdGhpcyB0bworICAgKiBkZXJpdmUgYSBuZXcgbWVzc2FnZSBmcm9tIHRoZSBjdXJyZW50IG9uZS4KKyAgICovCisgIEJ1aWxkZXIgdG9CdWlsZGVyKCk7CisKKyAgLyoqCisgICAqIEFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBQcm90b2NvbCBNZXNzYWdlIGJ1aWxkZXJzLgorICAgKi8KKyAgaW50ZXJmYWNlIEJ1aWxkZXIgZXh0ZW5kcyBNZXNzYWdlTGl0ZU9yQnVpbGRlciwgQ2xvbmVhYmxlIHsKKyAgICAvKiogUmVzZXRzIGFsbCBmaWVsZHMgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMuICovCisgICAgQnVpbGRlciBjbGVhcigpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyB0aGUgbWVzc2FnZSBiYXNlZCBvbiB0aGUgc3RhdGUgb2YgdGhlIEJ1aWxkZXIuIFN1YnNlcXVlbnQKKyAgICAgKiBjaGFuZ2VzIHRvIHRoZSBCdWlsZGVyIHdpbGwgbm90IGFmZmVjdCB0aGUgcmV0dXJuZWQgbWVzc2FnZS4KKyAgICAgKiBAdGhyb3dzIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIFRoZSBtZXNzYWdlIGlzIG1pc3Npbmcgb25lIG9yIG1vcmUKKyAgICAgKiAgICAgICAgIHJlcXVpcmVkIGZpZWxkcyAoaS5lLiB7QGxpbmsgI2lzSW5pdGlhbGl6ZWQoKX0gcmV0dXJucyBmYWxzZSkuCisgICAgICogICAgICAgICBVc2Uge0BsaW5rICNidWlsZFBhcnRpYWwoKX0gdG8gYnlwYXNzIHRoaXMgY2hlY2suCisgICAgICovCisgICAgTWVzc2FnZUxpdGUgYnVpbGQoKTsKKworICAgIC8qKgorICAgICAqIExpa2Uge0BsaW5rICNidWlsZCgpfSwgYnV0IGRvZXMgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZQorICAgICAqIGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLiAgSW5zdGVhZCwgYSBwYXJ0aWFsIG1lc3NhZ2UgaXMgcmV0dXJuZWQuCisgICAgICogU3Vic2VxdWVudCBjaGFuZ2VzIHRvIHRoZSBCdWlsZGVyIHdpbGwgbm90IGFmZmVjdCB0aGUgcmV0dXJuZWQgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBNZXNzYWdlTGl0ZSBidWlsZFBhcnRpYWwoKTsKKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGUgQnVpbGRlci4KKyAgICAgKiBAc2VlIE9iamVjdCNjbG9uZSgpCisgICAgICovCisgICAgQnVpbGRlciBjbG9uZSgpOworCisgICAgLyoqCisgICAgICogUGFyc2VzIGEgbWVzc2FnZSBvZiB0aGlzIHR5cGUgZnJvbSB0aGUgaW5wdXQgYW5kIG1lcmdlcyBpdCB3aXRoIHRoaXMKKyAgICAgKiBtZXNzYWdlLgorICAgICAqCisgICAgICogPHA+V2FybmluZzogIFRoaXMgZG9lcyBub3QgdmVyaWZ5IHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudCBpbgorICAgICAqIHRoZSBpbnB1dCBtZXNzYWdlLiAgSWYgeW91IGNhbGwge0BsaW5rICNidWlsZCgpfSB3aXRob3V0IHNldHRpbmcgYWxsCisgICAgICogcmVxdWlyZWQgZmllbGRzLCBpdCB3aWxsIHRocm93IGFuIHtAbGluayBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbn0sCisgICAgICogd2hpY2ggaXMgYSB7QGNvZGUgUnVudGltZUV4Y2VwdGlvbn0gYW5kIHRodXMgbWlnaHQgbm90IGJlIGNhdWdodC4gIFRoZXJlCisgICAgICogYXJlIGEgZmV3IGdvb2Qgd2F5cyB0byBkZWFsIHdpdGggdGhpczoKKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+Q2FsbCB7QGxpbmsgI2lzSW5pdGlhbGl6ZWQoKX0gdG8gdmVyaWZ5IHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcworICAgICAqICAgICAgIGFyZSBzZXQgYmVmb3JlIGJ1aWxkaW5nLgorICAgICAqICAgPGxpPlVzZSB7QGNvZGUgYnVpbGRQYXJ0aWFsKCl9IHRvIGJ1aWxkLCB3aGljaCBpZ25vcmVzIG1pc3NpbmcKKyAgICAgKiAgICAgICByZXF1aXJlZCBmaWVsZHMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPk5vdGU6ICBUaGUgY2FsbGVyIHNob3VsZCBjYWxsCisgICAgICoge0BsaW5rIENvZGVkSW5wdXRTdHJlYW0jY2hlY2tMYXN0VGFnV2FzKGludCl9IGFmdGVyIGNhbGxpbmcgdGhpcyB0bworICAgICAqIHZlcmlmeSB0aGF0IHRoZSBsYXN0IHRhZyBzZWVuIHdhcyB0aGUgYXBwcm9wcmlhdGUgZW5kLWdyb3VwIHRhZywKKyAgICAgKiBvciB6ZXJvIGZvciBFT0YuCisgICAgICovCisgICAgQnVpbGRlciBtZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogTGlrZSB7QGxpbmsgQnVpbGRlciNtZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbSl9LCBidXQgYWxzbworICAgICAqIHBhcnNlcyBleHRlbnNpb25zLiAgVGhlIGV4dGVuc2lvbnMgdGhhdCB5b3Ugd2FudCB0byBiZSBhYmxlIHRvIHBhcnNlCisgICAgICogbXVzdCBiZSByZWdpc3RlcmVkIGluIHtAY29kZSBleHRlbnNpb25SZWdpc3RyeX0uICBFeHRlbnNpb25zIG5vdCBpbgorICAgICAqIHRoZSByZWdpc3RyeSB3aWxsIGJlIHRyZWF0ZWQgYXMgdW5rbm93biBmaWVsZHMuCisgICAgICovCisgICAgQnVpbGRlciBtZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gQ29udmVuaWVuY2UgbWV0aG9kcy4KKworICAgIC8qKgorICAgICAqIFBhcnNlIHtAY29kZSBkYXRhfSBhcyBhIG1lc3NhZ2Ugb2YgdGhpcyB0eXBlIGFuZCBtZXJnZSBpdCB3aXRoIHRoZQorICAgICAqIG1lc3NhZ2UgYmVpbmcgYnVpbHQuICBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZAorICAgICAqIHtAbGluayAjbWVyZ2VGcm9tKENvZGVkSW5wdXRTdHJlYW0pfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcworICAgICAqLworICAgIEJ1aWxkZXIgbWVyZ2VGcm9tKEJ5dGVTdHJpbmcgZGF0YSkgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFBhcnNlIHtAY29kZSBkYXRhfSBhcyBhIG1lc3NhZ2Ugb2YgdGhpcyB0eXBlIGFuZCBtZXJnZSBpdCB3aXRoIHRoZQorICAgICAqIG1lc3NhZ2UgYmVpbmcgYnVpbHQuICBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZAorICAgICAqIHtAbGluayAjbWVyZ2VGcm9tKENvZGVkSW5wdXRTdHJlYW0sRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMKKyAgICAgKi8KKyAgICBCdWlsZGVyIG1lcmdlRnJvbShCeXRlU3RyaW5nIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHRoaXMgdHlwZSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LiAgVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQKKyAgICAgKiB7QGxpbmsgI21lcmdlRnJvbShDb2RlZElucHV0U3RyZWFtKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMKKyAgICAgKi8KKyAgICBCdWlsZGVyIG1lcmdlRnJvbShieXRlW10gZGF0YSkgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFBhcnNlIHtAY29kZSBkYXRhfSBhcyBhIG1lc3NhZ2Ugb2YgdGhpcyB0eXBlIGFuZCBtZXJnZSBpdCB3aXRoIHRoZQorICAgICAqIG1lc3NhZ2UgYmVpbmcgYnVpbHQuICBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZAorICAgICAqIHtAbGluayAjbWVyZ2VGcm9tKENvZGVkSW5wdXRTdHJlYW0pfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcworICAgICAqLworICAgIEJ1aWxkZXIgbWVyZ2VGcm9tKGJ5dGVbXSBkYXRhLCBpbnQgb2ZmLCBpbnQgbGVuKQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHRoaXMgdHlwZSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LiAgVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQKKyAgICAgKiB7QGxpbmsgI21lcmdlRnJvbShDb2RlZElucHV0U3RyZWFtLEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzCisgICAgICovCisgICAgQnVpbGRlciBtZXJnZUZyb20oYnl0ZVtdIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHRoaXMgdHlwZSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LiAgVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQKKyAgICAgKiB7QGxpbmsgI21lcmdlRnJvbShDb2RlZElucHV0U3RyZWFtLEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzCisgICAgICovCisgICAgQnVpbGRlciBtZXJnZUZyb20oYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIG1lc3NhZ2Ugb2YgdGhpcyB0eXBlIGZyb20ge0Bjb2RlIGlucHV0fSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LiAgVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQKKyAgICAgKiB7QGxpbmsgI21lcmdlRnJvbShDb2RlZElucHV0U3RyZWFtKX0uICBOb3RlIHRoYXQgdGhpcyBtZXRob2QgYWx3YXlzCisgICAgICogcmVhZHMgdGhlIDxpPmVudGlyZTwvaT4gaW5wdXQgKHVubGVzcyBpdCB0aHJvd3MgYW4gZXhjZXB0aW9uKS4gIElmIHlvdQorICAgICAqIHdhbnQgaXQgdG8gc3RvcCBlYXJsaWVyLCB5b3Ugd2lsbCBuZWVkIHRvIHdyYXAgeW91ciBpbnB1dCBpbiBzb21lCisgICAgICogd3JhcHBlciBzdHJlYW0gdGhhdCBsaW1pdHMgcmVhZGluZy4gIE9yLCB1c2UKKyAgICAgKiB7QGxpbmsgTWVzc2FnZUxpdGUjd3JpdGVEZWxpbWl0ZWRUbyhPdXRwdXRTdHJlYW0pfSB0byB3cml0ZSB5b3VyIG1lc3NhZ2UKKyAgICAgKiBhbmQge0BsaW5rICNtZXJnZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0pfSB0byByZWFkIGl0LgorICAgICAqIDxwPgorICAgICAqIERlc3BpdGUgdXN1YWxseSByZWFkaW5nIHRoZSBlbnRpcmUgaW5wdXQsIHRoaXMgZG9lcyBub3QgY2xvc2UgdGhlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcworICAgICAqLworICAgIEJ1aWxkZXIgbWVyZ2VGcm9tKElucHV0U3RyZWFtIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIG1lc3NhZ2Ugb2YgdGhpcyB0eXBlIGZyb20ge0Bjb2RlIGlucHV0fSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LiAgVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQKKyAgICAgKiB7QGxpbmsgI21lcmdlRnJvbShDb2RlZElucHV0U3RyZWFtLEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzCisgICAgICovCisgICAgQnVpbGRlciBtZXJnZUZyb20oSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIExpa2Uge0BsaW5rICNtZXJnZUZyb20oSW5wdXRTdHJlYW0pfSwgYnV0IGRvZXMgbm90IHJlYWQgdW50aWwgRU9GLgorICAgICAqIEluc3RlYWQsIHRoZSBzaXplIG9mIHRoZSBtZXNzYWdlIChlbmNvZGVkIGFzIGEgdmFyaW50KSBpcyByZWFkIGZpcnN0LAorICAgICAqIHRoZW4gdGhlIG1lc3NhZ2UgZGF0YS4gIFVzZQorICAgICAqIHtAbGluayBNZXNzYWdlTGl0ZSN3cml0ZURlbGltaXRlZFRvKE91dHB1dFN0cmVhbSl9IHRvIHdyaXRlIG1lc3NhZ2VzIGluCisgICAgICogdGhpcyBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRydWUgaWYgc3VjY2Vzc2Z1bCwgb3IgZmFsc2UgaWYgdGhlIHN0cmVhbSBpcyBhdCBFT0Ygd2hlbiB0aGUKKyAgICAgKiAgICAgICAgIG1ldGhvZCBzdGFydHMuICBBbnkgb3RoZXIgZXJyb3IgKGluY2x1ZGluZyByZWFjaGluZyBFT0YgZHVyaW5nCisgICAgICogICAgICAgICBwYXJzaW5nKSB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisgICAgICovCisgICAgYm9vbGVhbiBtZXJnZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogTGlrZSB7QGxpbmsgI21lcmdlRGVsaW1pdGVkRnJvbShJbnB1dFN0cmVhbSl9IGJ1dCBzdXBwb3J0aW5nIGV4dGVuc2lvbnMuCisgICAgICovCisgICAgYm9vbGVhbiBtZXJnZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWVzc2FnZUxpdGVPckJ1aWxkZXIuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VMaXRlT3JCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODE4Mzg2YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VMaXRlT3JCdWlsZGVyLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworLyoqCisgKiBCYXNlIGludGVyZmFjZSBmb3IgbWV0aG9kcyBjb21tb24gdG8ge0BsaW5rIE1lc3NhZ2VMaXRlfQorICogYW5kIHtAbGluayBNZXNzYWdlTGl0ZS5CdWlsZGVyfSB0byBwcm92aWRlIHR5cGUgZXF1aXZhbGVuY3kuCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZUxpdGVPckJ1aWxkZXIgeworICAvKioKKyAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSB0eXBlIHdpdGggbm8gZmllbGRzIHNldC4gQmVjYXVzZSBubyBmaWVsZHMgYXJlIHNldCwKKyAgICogYWxsIGdldHRlcnMgZm9yIHNpbmd1bGFyIGZpZWxkcyB3aWxsIHJldHVybiBkZWZhdWx0IHZhbHVlcyBhbmQgcmVwZWF0ZWQKKyAgICogZmllbGRzIHdpbGwgYXBwZWFyIGVtcHR5LgorICAgKiBUaGlzIG1heSBvciBtYXkgbm90IGJlIGEgc2luZ2xldG9uLiAgVGhpcyBkaWZmZXJzIGZyb20gdGhlCisgICAqIHtAY29kZSBnZXREZWZhdWx0SW5zdGFuY2UoKX0gbWV0aG9kIG9mIGdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMgaW4gdGhhdAorICAgKiB0aGlzIG1ldGhvZCBpcyBhbiBhYnN0cmFjdCBtZXRob2Qgb2YgdGhlIHtAY29kZSBNZXNzYWdlTGl0ZX0gaW50ZXJmYWNlCisgICAqIHdoZXJlYXMge0Bjb2RlIGdldERlZmF1bHRJbnN0YW5jZSgpfSBpcyBhIHN0YXRpYyBtZXRob2Qgb2YgYSBzcGVjaWZpYworICAgKiBjbGFzcy4gIFRoZXkgcmV0dXJuIHRoZSBzYW1lIHRoaW5nLgorICAgKi8KKyAgTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpOworCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgaWYgYWxsIHJlcXVpcmVkIGZpZWxkcyBpbiB0aGUgbWVzc2FnZSBhbmQgYWxsIGVtYmVkZGVkCisgICAqIG1lc3NhZ2VzIGFyZSBzZXQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICoKKyAgICogPHA+U2VlIGFsc286IHtAbGluayBNZXNzYWdlT3JCdWlsZGVyI2dldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKX0KKyAgICovCisgIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpOworCit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlT3JCdWlsZGVyLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlT3JCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjBmYzQ4NQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VPckJ1aWxkZXIuamF2YQpAQCAtMCwwICsxLDE0MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQmFzZSBpbnRlcmZhY2UgZm9yIG1ldGhvZHMgY29tbW9uIHRvIHtAbGluayBNZXNzYWdlfSBhbmQKKyAqIHtAbGluayBNZXNzYWdlLkJ1aWxkZXJ9IHRvIHByb3ZpZGUgdHlwZSBlcXVpdmFsZW5jeS4KKyAqCisgKiBAYXV0aG9yIGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKyAqLworcHVibGljIGludGVyZmFjZSBNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMgTWVzc2FnZUxpdGVPckJ1aWxkZXIgeworCisgIC8vIChGcm9tIE1lc3NhZ2VMaXRlLCByZS1kZWNsYXJlZCBoZXJlIG9ubHkgZm9yIHJldHVybiB0eXBlIGNvdmFyaWFuY2UuKQorICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCk7CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBsaXN0IG9mIGZpZWxkIHBhdGhzIChlLmcuICJmb28uYmFyLmJheiIpIG9mIHJlcXVpcmVkIGZpZWxkcworICAgKiB3aGljaCBhcmUgbm90IHNldCBpbiB0aGlzIG1lc3NhZ2UuICBZb3Ugc2hvdWxkIGNhbGwKKyAgICoge0BsaW5rIE1lc3NhZ2VMaXRlT3JCdWlsZGVyI2lzSW5pdGlhbGl6ZWQoKX0gZmlyc3QgdG8gY2hlY2sgaWYgdGhlcmUKKyAgICogYXJlIGFueSBtaXNzaW5nIGZpZWxkcywgYXMgdGhhdCBtZXRob2QgaXMgbGlrZWx5IHRvIGJlIG11Y2ggZmFzdGVyCisgICAqIHRoYW4gdGhpcyBvbmUgZXZlbiB3aGVuIHRoZSBtZXNzYWdlIGlzIGZ1bGx5LWluaXRpYWxpemVkLgorICAgKi8KKyAgTGlzdDxTdHJpbmc+IGZpbmRJbml0aWFsaXphdGlvbkVycm9ycygpOworCisgIC8qKgorICAgKiBSZXR1cm5zIGEgY29tbWEtZGVsaW1pdGVkIGxpc3Qgb2YgcmVxdWlyZWQgZmllbGRzIHdoaWNoIGFyZSBub3Qgc2V0CisgICAqIGluIHRoaXMgbWVzc2FnZSBvYmplY3QuICBZb3Ugc2hvdWxkIGNhbGwKKyAgICoge0BsaW5rIE1lc3NhZ2VMaXRlT3JCdWlsZGVyI2lzSW5pdGlhbGl6ZWQoKX0gZmlyc3QgdG8gY2hlY2sgaWYgdGhlcmUKKyAgICogYXJlIGFueSBtaXNzaW5nIGZpZWxkcywgYXMgdGhhdCBtZXRob2QgaXMgbGlrZWx5IHRvIGJlIG11Y2ggZmFzdGVyCisgICAqIHRoYW4gdGhpcyBvbmUgZXZlbiB3aGVuIHRoZSBtZXNzYWdlIGlzIGZ1bGx5LWluaXRpYWxpemVkLgorICAgKi8KKyAgU3RyaW5nIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKTsKKworICAvKioKKyAgICogR2V0IHRoZSBtZXNzYWdlJ3MgdHlwZSdzIGRlc2NyaXB0b3IuICBUaGlzIGRpZmZlcnMgZnJvbSB0aGUKKyAgICoge0Bjb2RlIGdldERlc2NyaXB0b3IoKX0gbWV0aG9kIG9mIGdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMgaW4gdGhhdAorICAgKiB0aGlzIG1ldGhvZCBpcyBhbiBhYnN0cmFjdCBtZXRob2Qgb2YgdGhlIHtAY29kZSBNZXNzYWdlfSBpbnRlcmZhY2UKKyAgICogd2hlcmVhcyB7QGNvZGUgZ2V0RGVzY3JpcHRvcigpfSBpcyBhIHN0YXRpYyBtZXRob2Qgb2YgYSBzcGVjaWZpYyBjbGFzcy4KKyAgICogVGhleSByZXR1cm4gdGhlIHNhbWUgdGhpbmcuCisgICAqLworICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCk7CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIG9mIGFsbCB0aGUgZmllbGRzIGluIHRoaXMgbWVzc2FnZSB3aGljaCBhcmUgc2V0CisgICAqIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcy4gIEEgc2luZ3VsYXIgKCJyZXF1aXJlZCIgb3IgIm9wdGlvbmFsIikKKyAgICogZmllbGQgaXMgc2V0IGlmZiBoYXNGaWVsZCgpIHJldHVybnMgdHJ1ZSBmb3IgdGhhdCBmaWVsZC4gIEEgInJlcGVhdGVkIgorICAgKiBmaWVsZCBpcyBzZXQgaWZmIGdldFJlcGVhdGVkRmllbGRDb3VudCgpIGlzIGdyZWF0ZXIgdGhhbiB6ZXJvLiAgVGhlCisgICAqIHZhbHVlcyBhcmUgZXhhY3RseSB3aGF0IHdvdWxkIGJlIHJldHVybmVkIGJ5IGNhbGxpbmcKKyAgICoge0BsaW5rICNnZXRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IpfSBmb3IgZWFjaCBmaWVsZC4gIFRoZSBtYXAKKyAgICogaXMgZ3VhcmFudGVlZCB0byBiZSBhIHNvcnRlZCBtYXAsIHNvIGl0ZXJhdGluZyBvdmVyIGl0IHdpbGwgcmV0dXJuIGZpZWxkcworICAgKiBpbiBvcmRlciBieSBmaWVsZCBudW1iZXIuCisgICAqIDxicj4KKyAgICogSWYgdGhpcyBpcyBmb3IgYSBidWlsZGVyLCB0aGUgcmV0dXJuZWQgbWFwIG1heSBvciBtYXkgbm90IHJlZmxlY3QgZnV0dXJlCisgICAqIGNoYW5nZXMgdG8gdGhlIGJ1aWxkZXIuICBFaXRoZXIgd2F5LCB0aGUgcmV0dXJuZWQgbWFwIGlzIGl0c2VsZgorICAgKiB1bm1vZGlmaWFibGUuCisgICAqLworICBNYXA8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGdldEFsbEZpZWxkcygpOworCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIG9uZW9mIGlzIHNldC4KKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYKKyAgICogICAgICAgICAgIHtAY29kZSBvbmVvZi5nZXRDb250YWluaW5nVHlwZSgpICE9IGdldERlc2NyaXB0b3JGb3JUeXBlKCl9LgorICAgKi8KKyAgYm9vbGVhbiBoYXNPbmVvZihEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpOworCisgIC8qKgorICAgKiBPYnRhaW5zIHRoZSBGaWVsZERlc2NyaXB0b3IgaWYgdGhlIGdpdmVuIG9uZW9mIGlzIHNldC4gUmV0dXJucyBudWxsCisgICAqIGlmIG5vIGZpZWxkIGlzIHNldC4KKyAgICovCisgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBnZXRPbmVvZkZpZWxkRGVzY3JpcHRvcigKKyAgICAgIERlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZik7CisKKyAgLyoqCisgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gZmllbGQgaXMgc2V0LiAgVGhpcyBpcyBleGFjdGx5IGVxdWl2YWxlbnQgdG8KKyAgICogY2FsbGluZyB0aGUgZ2VuZXJhdGVkICJoYXMiIGFjY2Vzc29yIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaWVsZC4KKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gVGhlIGZpZWxkIGlzIGEgcmVwZWF0ZWQgZmllbGQsIG9yCisgICAqICAgICAgICAgICB7QGNvZGUgZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSBnZXREZXNjcmlwdG9yRm9yVHlwZSgpfS4KKyAgICovCisgIGJvb2xlYW4gaGFzRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKTsKKworICAvKioKKyAgICogT2J0YWlucyB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkLCBvciB0aGUgZGVmYXVsdCB2YWx1ZSBpZiBpdCBpcworICAgKiBub3Qgc2V0LiAgRm9yIHByaW1pdGl2ZSBmaWVsZHMsIHRoZSBib3hlZCBwcmltaXRpdmUgdmFsdWUgaXMgcmV0dXJuZWQuCisgICAqIEZvciBlbnVtIGZpZWxkcywgdGhlIEVudW1WYWx1ZURlc2NyaXB0b3IgZm9yIHRoZSB2YWx1ZSBpcyByZXR1cm5lZC4gRm9yCisgICAqIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGRzLCB0aGUgc3ViLW1lc3NhZ2UgaXMgcmV0dXJuZWQuICBGb3IgcmVwZWF0ZWQKKyAgICogZmllbGRzLCBhIGphdmEudXRpbC5MaXN0IGlzIHJldHVybmVkLgorICAgKi8KKyAgT2JqZWN0IGdldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCk7CisKKyAgLyoqCisgICAqIEdldHMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkLiAgVGhpcyBpcyBleGFjdGx5CisgICAqIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB0aGUgZ2VuZXJhdGVkICJDb3VudCIgYWNjZXNzb3IgbWV0aG9kIGNvcnJlc3BvbmRpbmcKKyAgICogdG8gdGhlIGZpZWxkLgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBUaGUgZmllbGQgaXMgbm90IGEgcmVwZWF0ZWQgZmllbGQsIG9yCisgICAqICAgICAgICAgICB7QGNvZGUgZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSBnZXREZXNjcmlwdG9yRm9yVHlwZSgpfS4KKyAgICovCisgIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKTsKKworICAvKioKKyAgICogR2V0cyBhbiBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgZmllbGQuICBGb3IgcHJpbWl0aXZlIGZpZWxkcywgdGhlIGJveGVkCisgICAqIHByaW1pdGl2ZSB2YWx1ZSBpcyByZXR1cm5lZC4gIEZvciBlbnVtIGZpZWxkcywgdGhlIEVudW1WYWx1ZURlc2NyaXB0b3IKKyAgICogZm9yIHRoZSB2YWx1ZSBpcyByZXR1cm5lZC4gRm9yIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGRzLCB0aGUgc3ViLW1lc3NhZ2UKKyAgICogaXMgcmV0dXJuZWQuCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFRoZSBmaWVsZCBpcyBub3QgYSByZXBlYXRlZCBmaWVsZCwgb3IKKyAgICogICAgICAgICAgIHtAY29kZSBmaWVsZC5nZXRDb250YWluaW5nVHlwZSgpICE9IGdldERlc2NyaXB0b3JGb3JUeXBlKCl9LgorICAgKi8KKyAgT2JqZWN0IGdldFJlcGVhdGVkRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLCBpbnQgaW5kZXgpOworCisgIC8qKiBHZXQgdGhlIHtAbGluayBVbmtub3duRmllbGRTZXR9IGZvciB0aGlzIG1lc3NhZ2UuICovCisgIFVua25vd25GaWVsZFNldCBnZXRVbmtub3duRmllbGRzKCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlUmVmbGVjdGlvbi5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWVzc2FnZVJlZmxlY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZTRiZmQzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWVzc2FnZVJlZmxlY3Rpb24uamF2YQpAQCAtMCwwICsxLDk1MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKKy8qKgorICogUmVmbGVjdGlvbiB1dGlsaXR5IG1ldGhvZHMgc2hhcmVkIGJ5IGJvdGggbXV0YWJsZSBhbmQgaW1tdXRhYmxlIG1lc3NhZ2VzLgorICoKKyAqIEBhdXRob3IgbGl1amlzaUBnb29nbGUuY29tIChQaGVybCBMaXUpCisgKi8KK2NsYXNzIE1lc3NhZ2VSZWZsZWN0aW9uIHsKKworICBzdGF0aWMgdm9pZCB3cml0ZU1lc3NhZ2VUbygKKyAgICAgIE1lc3NhZ2UgbWVzc2FnZSwKKyAgICAgIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZmllbGRzLAorICAgICAgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0LAorICAgICAgYm9vbGVhbiBhbHdheXNXcml0ZVJlcXVpcmVkRmllbGRzKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBib29sZWFuIGlzTWVzc2FnZVNldCA9CisgICAgICAgIG1lc3NhZ2UuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5nZXRPcHRpb25zKCkuZ2V0TWVzc2FnZVNldFdpcmVGb3JtYXQoKTsKKyAgICBpZiAoYWx3YXlzV3JpdGVSZXF1aXJlZEZpZWxkcykgeworICAgICAgZmllbGRzID0gbmV3IFRyZWVNYXA8RmllbGREZXNjcmlwdG9yLCBPYmplY3Q+KGZpZWxkcyk7CisgICAgICBmb3IgKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA6CisgICAgICAgICAgbWVzc2FnZS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmdldEZpZWxkcygpKSB7CisgICAgICAgIGlmIChmaWVsZC5pc1JlcXVpcmVkKCkgJiYgIWZpZWxkcy5jb250YWluc0tleShmaWVsZCkpIHsKKyAgICAgICAgICBmaWVsZHMucHV0KGZpZWxkLCBtZXNzYWdlLmdldEZpZWxkKGZpZWxkKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgZm9yIChmaW5hbCBNYXAuRW50cnk8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGVudHJ5IDoKKyAgICAgICAgZmllbGRzLmVudHJ5U2V0KCkpIHsKKyAgICAgIGZpbmFsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGVudHJ5LmdldEtleSgpOworICAgICAgZmluYWwgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgIGlmIChpc01lc3NhZ2VTZXQgJiYgZmllbGQuaXNFeHRlbnNpb24oKSAmJgorICAgICAgICAgIGZpZWxkLmdldFR5cGUoKSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFICYmCisgICAgICAgICAgIWZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlU2V0RXh0ZW5zaW9uKGZpZWxkLmdldE51bWJlcigpLCAoTWVzc2FnZSkgdmFsdWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRmllbGRTZXQud3JpdGVGaWVsZChmaWVsZCwgdmFsdWUsIG91dHB1dCk7CisgICAgICB9CisgICAgfQorCisgICAgZmluYWwgVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMgPSBtZXNzYWdlLmdldFVua25vd25GaWVsZHMoKTsKKyAgICBpZiAoaXNNZXNzYWdlU2V0KSB7CisgICAgICB1bmtub3duRmllbGRzLndyaXRlQXNNZXNzYWdlU2V0VG8ob3V0cHV0KTsKKyAgICB9IGVsc2UgeworICAgICAgdW5rbm93bkZpZWxkcy53cml0ZVRvKG91dHB1dCk7CisgICAgfQorICB9CisKKyAgc3RhdGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgKKyAgICAgIE1lc3NhZ2UgbWVzc2FnZSwKKyAgICAgIE1hcDxGaWVsZERlc2NyaXB0b3IsIE9iamVjdD4gZmllbGRzKSB7CisgICAgaW50IHNpemUgPSAwOworICAgIGZpbmFsIGJvb2xlYW4gaXNNZXNzYWdlU2V0ID0KKyAgICAgICAgbWVzc2FnZS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmdldE9wdGlvbnMoKS5nZXRNZXNzYWdlU2V0V2lyZUZvcm1hdCgpOworCisgICAgZm9yIChmaW5hbCBNYXAuRW50cnk8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGVudHJ5IDoKKyAgICAgICAgZmllbGRzLmVudHJ5U2V0KCkpIHsKKyAgICAgIGZpbmFsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGVudHJ5LmdldEtleSgpOworICAgICAgZmluYWwgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgIGlmIChpc01lc3NhZ2VTZXQgJiYgZmllbGQuaXNFeHRlbnNpb24oKSAmJgorICAgICAgICAgIGZpZWxkLmdldFR5cGUoKSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFICYmCisgICAgICAgICAgIWZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICBzaXplICs9IENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVNZXNzYWdlU2V0RXh0ZW5zaW9uU2l6ZSgKKyAgICAgICAgICAgIGZpZWxkLmdldE51bWJlcigpLCAoTWVzc2FnZSkgdmFsdWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2l6ZSArPSBGaWVsZFNldC5jb21wdXRlRmllbGRTaXplKGZpZWxkLCB2YWx1ZSk7CisgICAgICB9CisgICAgfQorCisgICAgZmluYWwgVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMgPSBtZXNzYWdlLmdldFVua25vd25GaWVsZHMoKTsKKyAgICBpZiAoaXNNZXNzYWdlU2V0KSB7CisgICAgICBzaXplICs9IHVua25vd25GaWVsZHMuZ2V0U2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXQoKTsKKyAgICB9IGVsc2UgeworICAgICAgc2l6ZSArPSB1bmtub3duRmllbGRzLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgfQorICAgIHJldHVybiBzaXplOworICB9CisKKyAgc3RhdGljIFN0cmluZyBkZWxpbWl0V2l0aENvbW1hcyhMaXN0PFN0cmluZz4gcGFydHMpIHsKKyAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgZm9yIChTdHJpbmcgcGFydCA6IHBhcnRzKSB7CisgICAgICBpZiAocmVzdWx0Lmxlbmd0aCgpID4gMCkgeworICAgICAgICByZXN1bHQuYXBwZW5kKCIsICIpOworICAgICAgfQorICAgICAgcmVzdWx0LmFwcGVuZChwYXJ0KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHN0YXRpYyBib29sZWFuIGlzSW5pdGlhbGl6ZWQoTWVzc2FnZU9yQnVpbGRlciBtZXNzYWdlKSB7CisgICAgLy8gQ2hlY2sgdGhhdCBhbGwgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50LgorICAgIGZvciAoZmluYWwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkIDogbWVzc2FnZQorICAgICAgICAuZ2V0RGVzY3JpcHRvckZvclR5cGUoKQorICAgICAgICAuZ2V0RmllbGRzKCkpIHsKKyAgICAgIGlmIChmaWVsZC5pc1JlcXVpcmVkKCkpIHsKKyAgICAgICAgaWYgKCFtZXNzYWdlLmhhc0ZpZWxkKGZpZWxkKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8vIENoZWNrIHRoYXQgZW1iZWRkZWQgbWVzc2FnZXMgYXJlIGluaXRpYWxpemVkLgorICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBlbnRyeSA6CisgICAgICAgIG1lc3NhZ2UuZ2V0QWxsRmllbGRzKCkuZW50cnlTZXQoKSkgeworICAgICAgZmluYWwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICBpZiAoZmllbGQuZ2V0SmF2YVR5cGUoKSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICBpZiAoZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgICAgZm9yIChmaW5hbCBNZXNzYWdlIGVsZW1lbnQKKyAgICAgICAgICAgICAgOiAoTGlzdDxNZXNzYWdlPikgZW50cnkuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgaWYgKCFlbGVtZW50LmlzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmICghKChNZXNzYWdlKSBlbnRyeS5nZXRWYWx1ZSgpKS5pc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBzdWJNZXNzYWdlUHJlZml4KGZpbmFsIFN0cmluZyBwcmVmaXgsCisgICAgICBmaW5hbCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKHByZWZpeCk7CisgICAgaWYgKGZpZWxkLmlzRXh0ZW5zaW9uKCkpIHsKKyAgICAgIHJlc3VsdC5hcHBlbmQoJygnKQorICAgICAgICAgIC5hcHBlbmQoZmllbGQuZ2V0RnVsbE5hbWUoKSkKKyAgICAgICAgICAuYXBwZW5kKCcpJyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdC5hcHBlbmQoZmllbGQuZ2V0TmFtZSgpKTsKKyAgICB9CisgICAgaWYgKGluZGV4ICE9IC0xKSB7CisgICAgICByZXN1bHQuYXBwZW5kKCdbJykKKyAgICAgICAgICAuYXBwZW5kKGluZGV4KQorICAgICAgICAgIC5hcHBlbmQoJ10nKTsKKyAgICB9CisgICAgcmVzdWx0LmFwcGVuZCgnLicpOworICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgZmluZE1pc3NpbmdGaWVsZHMoZmluYWwgTWVzc2FnZU9yQnVpbGRlciBtZXNzYWdlLAorICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCwKKyAgICAgIGZpbmFsIExpc3Q8U3RyaW5nPiByZXN1bHRzKSB7CisgICAgZm9yIChmaW5hbCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQgOgorICAgICAgICBtZXNzYWdlLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZ2V0RmllbGRzKCkpIHsKKyAgICAgIGlmIChmaWVsZC5pc1JlcXVpcmVkKCkgJiYgIW1lc3NhZ2UuaGFzRmllbGQoZmllbGQpKSB7CisgICAgICAgIHJlc3VsdHMuYWRkKHByZWZpeCArIGZpZWxkLmdldE5hbWUoKSk7CisgICAgICB9CisgICAgfQorCisgICAgZm9yIChmaW5hbCBNYXAuRW50cnk8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGVudHJ5IDoKKyAgICAgICAgbWVzc2FnZS5nZXRBbGxGaWVsZHMoKS5lbnRyeVNldCgpKSB7CisgICAgICBmaW5hbCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQgPSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGVudHJ5LmdldFZhbHVlKCk7CisKKyAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgIGlmIChmaWVsZC5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgICAgZm9yIChmaW5hbCBPYmplY3QgZWxlbWVudCA6IChMaXN0KSB2YWx1ZSkgeworICAgICAgICAgICAgZmluZE1pc3NpbmdGaWVsZHMoKE1lc3NhZ2VPckJ1aWxkZXIpIGVsZW1lbnQsCisgICAgICAgICAgICAgICAgc3ViTWVzc2FnZVByZWZpeChwcmVmaXgsIGZpZWxkLCBpKyspLAorICAgICAgICAgICAgICAgIHJlc3VsdHMpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAobWVzc2FnZS5oYXNGaWVsZChmaWVsZCkpIHsKKyAgICAgICAgICAgIGZpbmRNaXNzaW5nRmllbGRzKChNZXNzYWdlT3JCdWlsZGVyKSB2YWx1ZSwKKyAgICAgICAgICAgICAgICBzdWJNZXNzYWdlUHJlZml4KHByZWZpeCwgZmllbGQsIC0xKSwKKyAgICAgICAgICAgICAgICByZXN1bHRzKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogUG9wdWxhdGVzIHtAY29kZSB0aGlzLm1pc3NpbmdGaWVsZHN9IHdpdGggdGhlIGZ1bGwgInBhdGgiIG9mIGVhY2ggbWlzc2luZworICAgKiByZXF1aXJlZCBmaWVsZCBpbiB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICovCisgIHN0YXRpYyBMaXN0PFN0cmluZz4gZmluZE1pc3NpbmdGaWVsZHMoCisgICAgICBmaW5hbCBNZXNzYWdlT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBmaW5hbCBMaXN0PFN0cmluZz4gcmVzdWx0cyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgIGZpbmRNaXNzaW5nRmllbGRzKG1lc3NhZ2UsICIiLCByZXN1bHRzKTsKKyAgICByZXR1cm4gcmVzdWx0czsKKyAgfQorCisgIHN0YXRpYyBpbnRlcmZhY2UgTWVyZ2VUYXJnZXQgeworICAgIGVudW0gQ29udGFpbmVyVHlwZSB7CisgICAgICBNRVNTQUdFLCBFWFRFTlNJT05fU0VUCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRvciBmb3IgdGhlIHRhcmdldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yRm9yVHlwZSgpOworCisgICAgcHVibGljIENvbnRhaW5lclR5cGUgZ2V0Q29udGFpbmVyVHlwZSgpOworCisgICAgcHVibGljIEV4dGVuc2lvblJlZ2lzdHJ5LkV4dGVuc2lvbkluZm8gZmluZEV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnksIFN0cmluZyBuYW1lKTsKKworICAgIHB1YmxpYyBFeHRlbnNpb25SZWdpc3RyeS5FeHRlbnNpb25JbmZvIGZpbmRFeHRlbnNpb25CeU51bWJlcigKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnksIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgY29udGFpbmluZ1R5cGUsCisgICAgICAgIGludCBmaWVsZE51bWJlcik7CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQsIG9yIHRoZSBkZWZhdWx0IHZhbHVlIGlmIGl0IGlzIG5vdAorICAgICAqIHNldC4gIEZvciBwcmltaXRpdmUgZmllbGRzLCB0aGUgYm94ZWQgcHJpbWl0aXZlIHZhbHVlIGlzIHJldHVybmVkLiBGb3IKKyAgICAgKiBlbnVtIGZpZWxkcywgdGhlIEVudW1WYWx1ZURlc2NyaXB0b3IgZm9yIHRoZSB2YWx1ZSBpcyByZXR1cm5lZC4gRm9yCisgICAgICogZW1iZWRkZWQgbWVzc2FnZSBmaWVsZHMsIHRoZSBzdWItbWVzc2FnZSBpcyByZXR1cm5lZC4gIEZvciByZXBlYXRlZAorICAgICAqIGZpZWxkcywgYSBqYXZhLnV0aWwuTGlzdCBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGZpZWxkIGlzIHNldC4gIFRoaXMgaXMgZXhhY3RseSBlcXVpdmFsZW50IHRvCisgICAgICogY2FsbGluZyB0aGUgZ2VuZXJhdGVkICJoYXMiIGFjY2Vzc29yIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFRoZSBmaWVsZCBpcyBhIHJlcGVhdGVkIGZpZWxkLCBvciB7QGNvZGUKKyAgICAgKiAgICAgZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSBnZXREZXNjcmlwdG9yRm9yVHlwZSgpfS4KKyAgICAgKi8KKyAgICBib29sZWFuIGhhc0ZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgZmllbGQgdG8gdGhlIGdpdmVuIHZhbHVlLiAgVGhlIHZhbHVlIG11c3QgYmUgb2YgdGhlIGNvcnJlY3QgdHlwZQorICAgICAqIGZvciB0aGlzIGZpZWxkLCBpLmUuIHRoZSBzYW1lIHR5cGUgdGhhdAorICAgICAqIHtAbGluayBNZXNzYWdlI2dldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcil9CisgICAgICogd291bGQgcmV0dXJuLgorICAgICAqLworICAgIE1lcmdlVGFyZ2V0IHNldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwgT2JqZWN0IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIENsZWFycyB0aGUgZmllbGQuICBUaGlzIGlzIGV4YWN0bHkgZXF1aXZhbGVudCB0byBjYWxsaW5nIHRoZSBnZW5lcmF0ZWQKKyAgICAgKiAiY2xlYXIiIGFjY2Vzc29yIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaWVsZC4KKyAgICAgKi8KKyAgICBNZXJnZVRhcmdldCBjbGVhckZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGFuIGVsZW1lbnQgb2YgYSByZXBlYXRlZCBmaWVsZCB0byB0aGUgZ2l2ZW4gdmFsdWUuICBUaGUgdmFsdWUgbXVzdAorICAgICAqIGJlIG9mIHRoZSBjb3JyZWN0IHR5cGUgZm9yIHRoaXMgZmllbGQsIGkuZS4gdGhlIHNhbWUgdHlwZSB0aGF0IHtAbGluaworICAgICAqIE1lc3NhZ2UjZ2V0UmVwZWF0ZWRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IsIGludCl9IHdvdWxkIHJldHVybi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFRoZSBmaWVsZCBpcyBub3QgYSByZXBlYXRlZCBmaWVsZCwgb3IKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7QGNvZGUgZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPQorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCl9LgorICAgICAqLworICAgIE1lcmdlVGFyZ2V0IHNldFJlcGVhdGVkRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICBpbnQgaW5kZXgsIE9iamVjdCB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBMaWtlIHtAY29kZSBzZXRSZXBlYXRlZEZpZWxkfSwgYnV0IGFwcGVuZHMgdGhlIHZhbHVlIGFzIGEgbmV3IGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBUaGUgZmllbGQgaXMgbm90IGEgcmVwZWF0ZWQgZmllbGQsIG9yCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge0Bjb2RlIGZpZWxkLmdldENvbnRhaW5pbmdUeXBlKCkgIT0KKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpfS4KKyAgICAgKi8KKyAgICBNZXJnZVRhcmdldCBhZGRSZXBlYXRlZEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgT2JqZWN0IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gb25lb2YgaXMgc2V0LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYKKyAgICAgKiAgICAgICAgICAge0Bjb2RlIG9uZW9mLmdldENvbnRhaW5pbmdUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvckZvclR5cGUoKX0uCisgICAgICovCisgICAgYm9vbGVhbiBoYXNPbmVvZihEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpOworCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBvbmVvZi4gIFRoaXMgaXMgZXhhY3RseSBlcXVpdmFsZW50IHRvIGNhbGxpbmcgdGhlIGdlbmVyYXRlZAorICAgICAqICJjbGVhciIgYWNjZXNzb3IgbWV0aG9kIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9uZW9mLgorICAgICAqLworICAgIE1lcmdlVGFyZ2V0IGNsZWFyT25lb2YoRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKTsKKworICAgIC8qKgorICAgICAqIE9idGFpbnMgdGhlIEZpZWxkRGVzY3JpcHRvciBpZiB0aGUgZ2l2ZW4gb25lb2YgaXMgc2V0LiBSZXR1cm5zIG51bGwKKyAgICAgKiBpZiBubyBmaWVsZCBpcyBzZXQuCisgICAgICovCisgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGdldE9uZW9mRmllbGREZXNjcmlwdG9yKERlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZik7CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgaW5wdXQgc3RyZWFtIGludG8gYSBzdWIgZmllbGQgZ3JvdXAgZGVmaW5lZCBiYXNlZCBvbiBlaXRoZXIKKyAgICAgKiBGaWVsZERlc2NyaXB0b3Igb3IgdGhlIGRlZmF1bHQgaW5zdGFuY2UuCisgICAgICovCisgICAgT2JqZWN0IHBhcnNlR3JvdXAoQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5LAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciwgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2UpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBpbnB1dCBzdHJlYW0gaW50byBhIHN1YiBmaWVsZCBtZXNzYWdlIGRlZmluZWQgYmFzZWQgb24gZWl0aGVyCisgICAgICogRmllbGREZXNjcmlwdG9yIG9yIHRoZSBkZWZhdWx0IGluc3RhbmNlLgorICAgICAqLworICAgIE9iamVjdCBwYXJzZU1lc3NhZ2UoQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5LAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciwgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2UpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFBhcnNlIGZyb20gYSBCeXRlU3RyaW5nIGludG8gYSBzdWIgZmllbGQgbWVzc2FnZSBkZWZpbmVkIGJhc2VkIG9uIGVpdGhlcgorICAgICAqIEZpZWxkRGVzY3JpcHRvciBvciB0aGUgZGVmYXVsdCBpbnN0YW5jZS4gIFRoZXJlIGlzbid0IGEgdmFyaW50IGluZGljYXRpbmcKKyAgICAgKiB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGlucHV0IEJ5dGVTdHJpbmcuCisgICAgICovCisgICAgT2JqZWN0IHBhcnNlTWVzc2FnZUZyb21CeXRlcygKKyAgICAgICAgQnl0ZVN0cmluZyBieXRlcywgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5LAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZGVzY3JpcHRvciwgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2UpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFVURjggdmFsaWRhdGlvbiBsZXZlbCBmb3IgdGhlIGZpZWxkLgorICAgICAqLworICAgIFdpcmVGb3JtYXQuVXRmOFZhbGlkYXRpb24gZ2V0VXRmOFZhbGlkYXRpb24oRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yCisgICAgICAgIGRlc2NyaXB0b3IpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBtZXJnZSB0YXJnZXQgZm9yIGEgc3ViLWZpZWxkLiBXaGVuIGRlZmF1bHRJbnN0YW5jZSBpcworICAgICAqIHByb3ZpZGVkLCBpdCBpbmRpY2F0ZXMgdGhlIGRlc2NyaXB0b3IgaXMgZm9yIGFuIGV4dGVuc2lvbiB0eXBlLCBhbmQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBmcm9tIHRoZSBkZWZhdWx0SW5zdGFuY2UKKyAgICAgKiBwcm90b3R5cGUgZGlyZWN0bHkuCisgICAgICovCisgICAgTWVyZ2VUYXJnZXQgbmV3TWVyZ2VUYXJnZXRGb3JGaWVsZCgKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IsCisgICAgICAgIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKTsKKworICAgIC8qKgorICAgICAqIEZpbmlzaGVzIHRoZSBtZXJnZSBhbmQgcmV0dXJucyB0aGUgdW5kZXJseWluZyBvYmplY3QuCisgICAgICovCisgICAgT2JqZWN0IGZpbmlzaCgpOworICB9CisKKyAgc3RhdGljIGNsYXNzIEJ1aWxkZXJBZGFwdGVyIGltcGxlbWVudHMgTWVyZ2VUYXJnZXQgeworCisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHB1YmxpYyBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0RGVzY3JpcHRvckZvclR5cGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlckFkYXB0ZXIoTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgIHRoaXMuYnVpbGRlciA9IGJ1aWxkZXI7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBidWlsZGVyLmdldEZpZWxkKGZpZWxkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBidWlsZGVyLmhhc0ZpZWxkKGZpZWxkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTWVyZ2VUYXJnZXQgc2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGJ1aWxkZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBNZXJnZVRhcmdldCBjbGVhckZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgYnVpbGRlci5jbGVhckZpZWxkKGZpZWxkKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBNZXJnZVRhcmdldCBzZXRSZXBlYXRlZEZpZWxkKAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIGludCBpbmRleCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBidWlsZGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTWVyZ2VUYXJnZXQgYWRkUmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2YoRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CisgICAgICByZXR1cm4gYnVpbGRlci5oYXNPbmVvZihvbmVvZik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1lcmdlVGFyZ2V0IGNsZWFyT25lb2YoRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CisgICAgICBidWlsZGVyLmNsZWFyT25lb2Yob25lb2YpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBnZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgIHJldHVybiBidWlsZGVyLmdldE9uZW9mRmllbGREZXNjcmlwdG9yKG9uZW9mKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29udGFpbmVyVHlwZSBnZXRDb250YWluZXJUeXBlKCkgeworICAgICAgcmV0dXJuIENvbnRhaW5lclR5cGUuTUVTU0FHRTsKKyAgICB9CisKKyAgICBwdWJsaWMgRXh0ZW5zaW9uUmVnaXN0cnkuRXh0ZW5zaW9uSW5mbyBmaW5kRXh0ZW5zaW9uQnlOYW1lKAorICAgICAgICBFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSwgU3RyaW5nIG5hbWUpIHsKKyAgICAgIHJldHVybiByZWdpc3RyeS5maW5kSW1tdXRhYmxlRXh0ZW5zaW9uQnlOYW1lKG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBFeHRlbnNpb25SZWdpc3RyeS5FeHRlbnNpb25JbmZvIGZpbmRFeHRlbnNpb25CeU51bWJlcigKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnksIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgY29udGFpbmluZ1R5cGUsCisgICAgICAgIGludCBmaWVsZE51bWJlcikgeworICAgICAgcmV0dXJuIHJlZ2lzdHJ5LmZpbmRJbW11dGFibGVFeHRlbnNpb25CeU51bWJlcihjb250YWluaW5nVHlwZSwKKyAgICAgICAgICBmaWVsZE51bWJlcik7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBwYXJzZUdyb3VwKENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLCBNZXNzYWdlIGRlZmF1bHRJbnN0YW5jZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIE1lc3NhZ2UuQnVpbGRlciBzdWJCdWlsZGVyOworICAgICAgLy8gV2hlbiBkZWZhdWx0IGluc3RhbmNlIGlzIG5vdCBudWxsLiBUaGUgZmllbGQgaXMgYW4gZXh0ZW5zaW9uIGZpZWxkLgorICAgICAgaWYgKGRlZmF1bHRJbnN0YW5jZSAhPSBudWxsKSB7CisgICAgICAgIHN1YkJ1aWxkZXIgPSBkZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHN1YkJ1aWxkZXIgPSBidWlsZGVyLm5ld0J1aWxkZXJGb3JGaWVsZChmaWVsZCk7CisgICAgICB9CisgICAgICBpZiAoIWZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICBNZXNzYWdlIG9yaWdpbmFsTWVzc2FnZSA9IChNZXNzYWdlKSBnZXRGaWVsZChmaWVsZCk7CisgICAgICAgIGlmIChvcmlnaW5hbE1lc3NhZ2UgIT0gbnVsbCkgeworICAgICAgICAgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKG9yaWdpbmFsTWVzc2FnZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlucHV0LnJlYWRHcm91cChmaWVsZC5nZXROdW1iZXIoKSwgc3ViQnVpbGRlciwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgcmV0dXJuIHN1YkJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBwYXJzZU1lc3NhZ2UoQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTWVzc2FnZS5CdWlsZGVyIHN1YkJ1aWxkZXI7CisgICAgICAvLyBXaGVuIGRlZmF1bHQgaW5zdGFuY2UgaXMgbm90IG51bGwuIFRoZSBmaWVsZCBpcyBhbiBleHRlbnNpb24gZmllbGQuCisgICAgICBpZiAoZGVmYXVsdEluc3RhbmNlICE9IG51bGwpIHsKKyAgICAgICAgc3ViQnVpbGRlciA9IGRlZmF1bHRJbnN0YW5jZS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3ViQnVpbGRlciA9IGJ1aWxkZXIubmV3QnVpbGRlckZvckZpZWxkKGZpZWxkKTsKKyAgICAgIH0KKyAgICAgIGlmICghZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIE1lc3NhZ2Ugb3JpZ2luYWxNZXNzYWdlID0gKE1lc3NhZ2UpIGdldEZpZWxkKGZpZWxkKTsKKyAgICAgICAgaWYgKG9yaWdpbmFsTWVzc2FnZSAhPSBudWxsKSB7CisgICAgICAgICAgc3ViQnVpbGRlci5tZXJnZUZyb20ob3JpZ2luYWxNZXNzYWdlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaW5wdXQucmVhZE1lc3NhZ2Uoc3ViQnVpbGRlciwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgcmV0dXJuIHN1YkJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBwYXJzZU1lc3NhZ2VGcm9tQnl0ZXMoQnl0ZVN0cmluZyBieXRlcywKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTWVzc2FnZS5CdWlsZGVyIHN1YkJ1aWxkZXI7CisgICAgICAvLyBXaGVuIGRlZmF1bHQgaW5zdGFuY2UgaXMgbm90IG51bGwuIFRoZSBmaWVsZCBpcyBhbiBleHRlbnNpb24gZmllbGQuCisgICAgICBpZiAoZGVmYXVsdEluc3RhbmNlICE9IG51bGwpIHsKKyAgICAgICAgc3ViQnVpbGRlciA9IGRlZmF1bHRJbnN0YW5jZS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3ViQnVpbGRlciA9IGJ1aWxkZXIubmV3QnVpbGRlckZvckZpZWxkKGZpZWxkKTsKKyAgICAgIH0KKyAgICAgIGlmICghZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIE1lc3NhZ2Ugb3JpZ2luYWxNZXNzYWdlID0gKE1lc3NhZ2UpIGdldEZpZWxkKGZpZWxkKTsKKyAgICAgICAgaWYgKG9yaWdpbmFsTWVzc2FnZSAhPSBudWxsKSB7CisgICAgICAgICAgc3ViQnVpbGRlci5tZXJnZUZyb20ob3JpZ2luYWxNZXNzYWdlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgc3ViQnVpbGRlci5tZXJnZUZyb20oYnl0ZXMsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICAgIHJldHVybiBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIH0KKworICAgIHB1YmxpYyBNZXJnZVRhcmdldCBuZXdNZXJnZVRhcmdldEZvckZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgTWVzc2FnZSBkZWZhdWx0SW5zdGFuY2UpIHsKKyAgICAgIGlmIChkZWZhdWx0SW5zdGFuY2UgIT0gbnVsbCkgeworICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXJBZGFwdGVyKAorICAgICAgICAgICAgZGVmYXVsdEluc3RhbmNlLm5ld0J1aWxkZXJGb3JUeXBlKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCdWlsZGVyQWRhcHRlcihidWlsZGVyLm5ld0J1aWxkZXJGb3JGaWVsZChmaWVsZCkpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBXaXJlRm9ybWF0LlV0ZjhWYWxpZGF0aW9uCisgICAgICAgIGdldFV0ZjhWYWxpZGF0aW9uKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgICAgICBpZiAoZGVzY3JpcHRvci5uZWVkc1V0ZjhDaGVjaygpKSB7CisgICAgICAgIHJldHVybiBXaXJlRm9ybWF0LlV0ZjhWYWxpZGF0aW9uLlNUUklDVDsKKyAgICAgIH0KKyAgICAgIC8vIFRPRE8obGl1amlzaSk6IHN1cHBvcnQgbGF6eSBzdHJpbmdzIGZvciByZXBlYXRlZCBmaWVsZHMuCisgICAgICBpZiAoIWRlc2NyaXB0b3IuaXNSZXBlYXRlZCgpCisgICAgICAgICAgJiYgYnVpbGRlciBpbnN0YW5jZW9mIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlcikgeworICAgICAgICByZXR1cm4gV2lyZUZvcm1hdC5VdGY4VmFsaWRhdGlvbi5MQVpZOworICAgICAgfQorICAgICAgcmV0dXJuIFdpcmVGb3JtYXQuVXRmOFZhbGlkYXRpb24uTE9PU0U7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBmaW5pc2goKSB7CisgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICB9CisgIH0KKworCisgIHN0YXRpYyBjbGFzcyBFeHRlbnNpb25BZGFwdGVyIGltcGxlbWVudHMgTWVyZ2VUYXJnZXQgeworCisgICAgcHJpdmF0ZSBmaW5hbCBGaWVsZFNldDxEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I+IGV4dGVuc2lvbnM7CisKKyAgICBFeHRlbnNpb25BZGFwdGVyKEZpZWxkU2V0PERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcj4gZXh0ZW5zaW9ucykgeworICAgICAgdGhpcy5leHRlbnNpb25zID0gZXh0ZW5zaW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiZ2V0RGVzY3JpcHRvckZvclR5cGUoKSBjYWxsZWQgb24gRmllbGRTZXQgb2JqZWN0Iik7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmdldEZpZWxkKGZpZWxkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgIHJldHVybiBleHRlbnNpb25zLmhhc0ZpZWxkKGZpZWxkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTWVyZ2VUYXJnZXQgc2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGV4dGVuc2lvbnMuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBNZXJnZVRhcmdldCBjbGVhckZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgZXh0ZW5zaW9ucy5jbGVhckZpZWxkKGZpZWxkKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBNZXJnZVRhcmdldCBzZXRSZXBlYXRlZEZpZWxkKAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIGludCBpbmRleCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBleHRlbnNpb25zLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTWVyZ2VUYXJnZXQgYWRkUmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIGV4dGVuc2lvbnMuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2YoRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1lcmdlVGFyZ2V0IGNsZWFyT25lb2YoRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CisgICAgICAvLyBOb3RoaW5nIHRvIGNsZWFyLgorICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBnZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBDb250YWluZXJUeXBlIGdldENvbnRhaW5lclR5cGUoKSB7CisgICAgICByZXR1cm4gQ29udGFpbmVyVHlwZS5FWFRFTlNJT05fU0VUOworICAgIH0KKworICAgIHB1YmxpYyBFeHRlbnNpb25SZWdpc3RyeS5FeHRlbnNpb25JbmZvIGZpbmRFeHRlbnNpb25CeU5hbWUoCisgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5LCBTdHJpbmcgbmFtZSkgeworICAgICAgcmV0dXJuIHJlZ2lzdHJ5LmZpbmRJbW11dGFibGVFeHRlbnNpb25CeU5hbWUobmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEV4dGVuc2lvblJlZ2lzdHJ5LkV4dGVuc2lvbkluZm8gZmluZEV4dGVuc2lvbkJ5TnVtYmVyKAorICAgICAgICBFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSwgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBjb250YWluaW5nVHlwZSwKKyAgICAgICAgaW50IGZpZWxkTnVtYmVyKSB7CisgICAgICByZXR1cm4gcmVnaXN0cnkuZmluZEltbXV0YWJsZUV4dGVuc2lvbkJ5TnVtYmVyKGNvbnRhaW5pbmdUeXBlLAorICAgICAgICAgIGZpZWxkTnVtYmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IHBhcnNlR3JvdXAoQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTWVzc2FnZS5CdWlsZGVyIHN1YkJ1aWxkZXIgPQorICAgICAgICAgIGRlZmF1bHRJbnN0YW5jZS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgICAgaWYgKCFmaWVsZC5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgTWVzc2FnZSBvcmlnaW5hbE1lc3NhZ2UgPSAoTWVzc2FnZSkgZ2V0RmllbGQoZmllbGQpOworICAgICAgICBpZiAob3JpZ2luYWxNZXNzYWdlICE9IG51bGwpIHsKKyAgICAgICAgICBzdWJCdWlsZGVyLm1lcmdlRnJvbShvcmlnaW5hbE1lc3NhZ2UpOworICAgICAgICB9CisgICAgICB9CisgICAgICBpbnB1dC5yZWFkR3JvdXAoZmllbGQuZ2V0TnVtYmVyKCksIHN1YkJ1aWxkZXIsIHJlZ2lzdHJ5KTsKKyAgICAgIHJldHVybiBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgcGFyc2VNZXNzYWdlKENvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICBNZXNzYWdlIGRlZmF1bHRJbnN0YW5jZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIE1lc3NhZ2UuQnVpbGRlciBzdWJCdWlsZGVyID0KKyAgICAgICAgICBkZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgICAgIGlmICghZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIE1lc3NhZ2Ugb3JpZ2luYWxNZXNzYWdlID0gKE1lc3NhZ2UpIGdldEZpZWxkKGZpZWxkKTsKKyAgICAgICAgaWYgKG9yaWdpbmFsTWVzc2FnZSAhPSBudWxsKSB7CisgICAgICAgICAgc3ViQnVpbGRlci5tZXJnZUZyb20ob3JpZ2luYWxNZXNzYWdlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaW5wdXQucmVhZE1lc3NhZ2Uoc3ViQnVpbGRlciwgcmVnaXN0cnkpOworICAgICAgcmV0dXJuIHN1YkJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBwYXJzZU1lc3NhZ2VGcm9tQnl0ZXMoQnl0ZVN0cmluZyBieXRlcywKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTWVzc2FnZS5CdWlsZGVyIHN1YkJ1aWxkZXIgPSAgZGVmYXVsdEluc3RhbmNlLm5ld0J1aWxkZXJGb3JUeXBlKCk7CisgICAgICBpZiAoIWZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICBNZXNzYWdlIG9yaWdpbmFsTWVzc2FnZSA9IChNZXNzYWdlKSBnZXRGaWVsZChmaWVsZCk7CisgICAgICAgIGlmIChvcmlnaW5hbE1lc3NhZ2UgIT0gbnVsbCkgeworICAgICAgICAgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKG9yaWdpbmFsTWVzc2FnZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKGJ5dGVzLCByZWdpc3RyeSk7CisgICAgICByZXR1cm4gc3ViQnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTWVyZ2VUYXJnZXQgbmV3TWVyZ2VUYXJnZXRGb3JGaWVsZCgKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IsIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgIm5ld01lcmdlVGFyZ2V0Rm9yRmllbGQoKSBjYWxsZWQgb24gRmllbGRTZXQgb2JqZWN0Iik7CisgICAgfQorCisgICAgcHVibGljIFdpcmVGb3JtYXQuVXRmOFZhbGlkYXRpb24KKyAgICAgICAgZ2V0VXRmOFZhbGlkYXRpb24oRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgICAgIGlmIChkZXNjcmlwdG9yLm5lZWRzVXRmOENoZWNrKCkpIHsKKyAgICAgICAgcmV0dXJuIFdpcmVGb3JtYXQuVXRmOFZhbGlkYXRpb24uU1RSSUNUOworICAgICAgfQorICAgICAgLy8gVE9ETyhsaXVqaXNpKTogc3VwcG9ydCBsYXp5IHN0cmluZ3MgZm9yIEV4dGVzbnNpb25TZXQuCisgICAgICByZXR1cm4gV2lyZUZvcm1hdC5VdGY4VmFsaWRhdGlvbi5MT09TRTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGZpbmlzaCgpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAiZmluaXNoKCkgY2FsbGVkIG9uIEZpZWxkU2V0IG9iamVjdCIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBQYXJzZXMgYSBzaW5nbGUgZmllbGQgaW50byBNZXJnZVRhcmdldC4gVGhlIHRhcmdldCBjYW4gYmUgTWVzc2FnZS5CdWlsZGVyLAorICAgKiBGaWVsZFNldCBvciBNdXRhYmxlTWVzc2FnZS4KKyAgICoKKyAgICogUGFja2FnZS1wcml2YXRlIGJlY2F1c2UgaXQgaXMgdXNlZCBieSBHZW5lcmF0ZWRNZXNzYWdlLkV4dGVuZGFibGVNZXNzYWdlLgorICAgKgorICAgKiBAcGFyYW0gdGFnIFRoZSB0YWcsIHdoaWNoIHNob3VsZCBoYXZlIGFscmVhZHkgYmVlbiByZWFkLgorICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSB1bmxlc3MgdGhlIHRhZyBpcyBhbiBlbmQtZ3JvdXAgdGFnLgorICAgKi8KKyAgc3RhdGljIGJvb2xlYW4gbWVyZ2VGaWVsZEZyb20oCisgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgVW5rbm93bkZpZWxkU2V0LkJ1aWxkZXIgdW5rbm93bkZpZWxkcywKKyAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgdHlwZSwKKyAgICAgIE1lcmdlVGFyZ2V0IHRhcmdldCwKKyAgICAgIGludCB0YWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHR5cGUuZ2V0T3B0aW9ucygpLmdldE1lc3NhZ2VTZXRXaXJlRm9ybWF0KCkgJiYKKyAgICAgICAgdGFnID09IFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfSVRFTV9UQUcpIHsKKyAgICAgIG1lcmdlTWVzc2FnZVNldEV4dGVuc2lvbkZyb21Db2RlZFN0cmVhbSgKKyAgICAgICAgICBpbnB1dCwgdW5rbm93bkZpZWxkcywgZXh0ZW5zaW9uUmVnaXN0cnksIHR5cGUsIHRhcmdldCk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBmaW5hbCBpbnQgd2lyZVR5cGUgPSBXaXJlRm9ybWF0LmdldFRhZ1dpcmVUeXBlKHRhZyk7CisgICAgZmluYWwgaW50IGZpZWxkTnVtYmVyID0gV2lyZUZvcm1hdC5nZXRUYWdGaWVsZE51bWJlcih0YWcpOworCisgICAgZmluYWwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkOworICAgIE1lc3NhZ2UgZGVmYXVsdEluc3RhbmNlID0gbnVsbDsKKworICAgIGlmICh0eXBlLmlzRXh0ZW5zaW9uTnVtYmVyKGZpZWxkTnVtYmVyKSkgeworICAgICAgLy8gZXh0ZW5zaW9uUmVnaXN0cnkgbWF5IGJlIGVpdGhlciBFeHRlbnNpb25SZWdpc3RyeSBvcgorICAgICAgLy8gRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLiAgU2luY2UgdGhlIHR5cGUgd2UgYXJlIHBhcnNpbmcgaXMgYSBmdWxsCisgICAgICAvLyBtZXNzYWdlLCBvbmx5IGEgZnVsbCBFeHRlbnNpb25SZWdpc3RyeSBjb3VsZCBwb3NzaWJseSBjb250YWluCisgICAgICAvLyBleHRlbnNpb25zIG9mIGl0LiAgT3RoZXJ3aXNlIHdlIHdpbGwgdHJlYXQgdGhlIHJlZ2lzdHJ5IGFzIGlmIGl0CisgICAgICAvLyB3ZXJlIGVtcHR5LgorICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5IGluc3RhbmNlb2YgRXh0ZW5zaW9uUmVnaXN0cnkpIHsKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnkuRXh0ZW5zaW9uSW5mbyBleHRlbnNpb24gPQorICAgICAgICAgICAgdGFyZ2V0LmZpbmRFeHRlbnNpb25CeU51bWJlcigoRXh0ZW5zaW9uUmVnaXN0cnkpIGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICAgICAgICAgIHR5cGUsIGZpZWxkTnVtYmVyKTsKKyAgICAgICAgaWYgKGV4dGVuc2lvbiA9PSBudWxsKSB7CisgICAgICAgICAgZmllbGQgPSBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGZpZWxkID0gZXh0ZW5zaW9uLmRlc2NyaXB0b3I7CisgICAgICAgICAgZGVmYXVsdEluc3RhbmNlID0gZXh0ZW5zaW9uLmRlZmF1bHRJbnN0YW5jZTsKKyAgICAgICAgICBpZiAoZGVmYXVsdEluc3RhbmNlID09IG51bGwgJiYKKyAgICAgICAgICAgICAgZmllbGQuZ2V0SmF2YVR5cGUoKQorICAgICAgICAgICAgICAgICAgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIk1lc3NhZ2UtdHlwZWQgZXh0ZW5zaW9uIGxhY2tlZCBkZWZhdWx0IGluc3RhbmNlOiAiICsKKyAgICAgICAgICAgICAgICAgICAgZmllbGQuZ2V0RnVsbE5hbWUoKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBmaWVsZCA9IG51bGw7CisgICAgICB9CisgICAgfSBlbHNlIGlmICh0YXJnZXQuZ2V0Q29udGFpbmVyVHlwZSgpID09IE1lcmdlVGFyZ2V0LkNvbnRhaW5lclR5cGUuTUVTU0FHRSkgeworICAgICAgZmllbGQgPSB0eXBlLmZpbmRGaWVsZEJ5TnVtYmVyKGZpZWxkTnVtYmVyKTsKKyAgICB9IGVsc2UgeworICAgICAgZmllbGQgPSBudWxsOworICAgIH0KKworICAgIGJvb2xlYW4gdW5rbm93biA9IGZhbHNlOworICAgIGJvb2xlYW4gcGFja2VkID0gZmFsc2U7CisgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgIHVua25vd24gPSB0cnVlOyAgLy8gVW5rbm93biBmaWVsZC4KKyAgICB9IGVsc2UgaWYgKHdpcmVUeXBlID09IEZpZWxkU2V0LmdldFdpcmVGb3JtYXRGb3JGaWVsZFR5cGUoCisgICAgICAgIGZpZWxkLmdldExpdGVUeXBlKCksCisgICAgICAgIGZhbHNlICAvKiBpc1BhY2tlZCAqLykpIHsKKyAgICAgIHBhY2tlZCA9IGZhbHNlOworICAgIH0gZWxzZSBpZiAoZmllbGQuaXNQYWNrYWJsZSgpICYmCisgICAgICAgIHdpcmVUeXBlID09IEZpZWxkU2V0LmdldFdpcmVGb3JtYXRGb3JGaWVsZFR5cGUoCisgICAgICAgICAgICBmaWVsZC5nZXRMaXRlVHlwZSgpLAorICAgICAgICAgICAgdHJ1ZSAgLyogaXNQYWNrZWQgKi8pKSB7CisgICAgICBwYWNrZWQgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICB1bmtub3duID0gdHJ1ZTsgIC8vIFVua25vd24gd2lyZSB0eXBlLgorICAgIH0KKworICAgIGlmICh1bmtub3duKSB7ICAvLyBVbmtub3duIGZpZWxkIG9yIHdyb25nIHdpcmUgdHlwZS4gIFNraXAuCisgICAgICByZXR1cm4gdW5rbm93bkZpZWxkcy5tZXJnZUZpZWxkRnJvbSh0YWcsIGlucHV0KTsKKyAgICB9CisKKyAgICBpZiAocGFja2VkKSB7CisgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CisgICAgICBmaW5hbCBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKKyAgICAgIGlmIChmaWVsZC5nZXRMaXRlVHlwZSgpID09IFdpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0pIHsKKyAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeworICAgICAgICAgIGZpbmFsIGludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7CisgICAgICAgICAgaWYgKGZpZWxkLmdldEZpbGUoKS5zdXBwb3J0c1Vua25vd25FbnVtVmFsdWUoKSkgeworICAgICAgICAgICAgdGFyZ2V0LmFkZFJlcGVhdGVkRmllbGQoZmllbGQsCisgICAgICAgICAgICAgICAgZmllbGQuZ2V0RW51bVR5cGUoKS5maW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKHJhd1ZhbHVlKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGZpZWxkLmdldEVudW1UeXBlKCkuZmluZFZhbHVlQnlOdW1iZXIocmF3VmFsdWUpOworICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgLy8gSWYgdGhlIG51bWJlciBpc24ndCByZWNvZ25pemVkIGFzIGEgdmFsaWQgdmFsdWUgZm9yIHRoaXMKKyAgICAgICAgICAgICAgLy8gZW51bSwgZHJvcCBpdCAoZG9uJ3QgZXZlbiBhZGQgaXQgdG8gdW5rbm93bkZpZWxkcykuCisgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGFyZ2V0LmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKKyAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBXaXJlRm9ybWF0LnJlYWRQcmltaXRpdmVGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIGZpZWxkLmdldExpdGVUeXBlKCksIHRhcmdldC5nZXRVdGY4VmFsaWRhdGlvbihmaWVsZCkpOworICAgICAgICAgIHRhcmdldC5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKKyAgICB9IGVsc2UgeworICAgICAgZmluYWwgT2JqZWN0IHZhbHVlOworICAgICAgc3dpdGNoIChmaWVsZC5nZXRUeXBlKCkpIHsKKyAgICAgICAgY2FzZSBHUk9VUDogeworICAgICAgICAgIHZhbHVlID0gdGFyZ2V0CisgICAgICAgICAgICAgIC5wYXJzZUdyb3VwKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgZmllbGQsIGRlZmF1bHRJbnN0YW5jZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgY2FzZSBNRVNTQUdFOiB7CisgICAgICAgICAgdmFsdWUgPSB0YXJnZXQKKyAgICAgICAgICAgICAgLnBhcnNlTWVzc2FnZShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIGZpZWxkLCBkZWZhdWx0SW5zdGFuY2UpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGNhc2UgRU5VTToKKyAgICAgICAgICBmaW5hbCBpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpOworICAgICAgICAgIGlmIChmaWVsZC5nZXRGaWxlKCkuc3VwcG9ydHNVbmtub3duRW51bVZhbHVlKCkpIHsKKyAgICAgICAgICAgIHZhbHVlID0gZmllbGQuZ2V0RW51bVR5cGUoKS5maW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKHJhd1ZhbHVlKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdmFsdWUgPSBmaWVsZC5nZXRFbnVtVHlwZSgpLmZpbmRWYWx1ZUJ5TnVtYmVyKHJhd1ZhbHVlKTsKKyAgICAgICAgICAgIC8vIElmIHRoZSBudW1iZXIgaXNuJ3QgcmVjb2duaXplZCBhcyBhIHZhbGlkIHZhbHVlIGZvciB0aGlzIGVudW0sCisgICAgICAgICAgICAvLyBkcm9wIGl0LgorICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgdW5rbm93bkZpZWxkcy5tZXJnZVZhcmludEZpZWxkKGZpZWxkTnVtYmVyLCByYXdWYWx1ZSk7CisgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICB2YWx1ZSA9IFdpcmVGb3JtYXQucmVhZFByaW1pdGl2ZUZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgZmllbGQuZ2V0TGl0ZVR5cGUoKSwgdGFyZ2V0LmdldFV0ZjhWYWxpZGF0aW9uKGZpZWxkKSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGlmIChmaWVsZC5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgdGFyZ2V0LmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRhcmdldC5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqCisgICAqIENhbGxlZCBieSB7QGNvZGUgI21lcmdlRmllbGRGcm9tKCl9IHRvIHBhcnNlIGEgTWVzc2FnZVNldCBleHRlbnNpb24gaW50bworICAgKiBNZXJnZVRhcmdldC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIHZvaWQgbWVyZ2VNZXNzYWdlU2V0RXh0ZW5zaW9uRnJvbUNvZGVkU3RyZWFtKAorICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgIFVua25vd25GaWVsZFNldC5CdWlsZGVyIHVua25vd25GaWVsZHMsCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIHR5cGUsCisgICAgICBNZXJnZVRhcmdldCB0YXJnZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAvLyBUaGUgd2lyZSBmb3JtYXQgZm9yIE1lc3NhZ2VTZXQgaXM6CisgICAgLy8gICBtZXNzYWdlIE1lc3NhZ2VTZXQgeworICAgIC8vICAgICByZXBlYXRlZCBncm91cCBJdGVtID0gMSB7CisgICAgLy8gICAgICAgcmVxdWlyZWQgaW50MzIgdHlwZUlkID0gMjsKKyAgICAvLyAgICAgICByZXF1aXJlZCBieXRlcyBtZXNzYWdlID0gMzsKKyAgICAvLyAgICAgfQorICAgIC8vICAgfQorICAgIC8vICJ0eXBlSWQiIGlzIHRoZSBleHRlbnNpb24ncyBmaWVsZCBudW1iZXIuICBUaGUgZXh0ZW5zaW9uIGNhbiBvbmx5IGJlCisgICAgLy8gYSBtZXNzYWdlIHR5cGUsIHdoZXJlICJtZXNzYWdlIiBjb250YWlucyB0aGUgZW5jb2RlZCBieXRlcyBvZiB0aGF0CisgICAgLy8gbWVzc2FnZS4KKyAgICAvLworICAgIC8vIEluIHByYWN0aWNlLCB3ZSB3aWxsIHByb2JhYmx5IG5ldmVyIHNlZSBhIE1lc3NhZ2VTZXQgaXRlbSBpbiB3aGljaAorICAgIC8vIHRoZSBtZXNzYWdlIGFwcGVhcnMgYmVmb3JlIHRoZSB0eXBlIElELCBvciB3aGVyZSBlaXRoZXIgZmllbGQgZG9lcyBub3QKKyAgICAvLyBhcHBlYXIgZXhhY3RseSBvbmNlLiAgSG93ZXZlciwgaW4gdGhlb3J5IHN1Y2ggY2FzZXMgYXJlIHZhbGlkLCBzbyB3ZQorICAgIC8vIHNob3VsZCBiZSBwcmVwYXJlZCB0byBhY2NlcHQgdGhlbS4KKworICAgIGludCB0eXBlSWQgPSAwOworICAgIEJ5dGVTdHJpbmcgcmF3Qnl0ZXMgPSBudWxsOyAvLyBJZiB3ZSBlbmNvdW50ZXIgIm1lc3NhZ2UiIGJlZm9yZSAidHlwZUlkIgorICAgIEV4dGVuc2lvblJlZ2lzdHJ5LkV4dGVuc2lvbkluZm8gZXh0ZW5zaW9uID0gbnVsbDsKKworICAgIC8vIFJlYWQgYnl0ZXMgZnJvbSBpbnB1dCwgaWYgd2UgZ2V0IGl0J3MgdHlwZSBmaXJzdCB0aGVuIHBhcnNlIGl0IGVhZ2VybHksCisgICAgLy8gb3RoZXJ3aXNlIHdlIHN0b3JlIHRoZSByYXcgYnl0ZXMgaW4gYSBsb2NhbCB2YXJpYWJsZS4KKyAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgZmluYWwgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKKyAgICAgIGlmICh0YWcgPT0gMCkgeworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgaWYgKHRhZyA9PSBXaXJlRm9ybWF0Lk1FU1NBR0VfU0VUX1RZUEVfSURfVEFHKSB7CisgICAgICAgIHR5cGVJZCA9IGlucHV0LnJlYWRVSW50MzIoKTsKKyAgICAgICAgaWYgKHR5cGVJZCAhPSAwKSB7CisgICAgICAgICAgLy8gZXh0ZW5zaW9uUmVnaXN0cnkgbWF5IGJlIGVpdGhlciBFeHRlbnNpb25SZWdpc3RyeSBvcgorICAgICAgICAgIC8vIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS4gU2luY2UgdGhlIHR5cGUgd2UgYXJlIHBhcnNpbmcgaXMgYSBmdWxsCisgICAgICAgICAgLy8gbWVzc2FnZSwgb25seSBhIGZ1bGwgRXh0ZW5zaW9uUmVnaXN0cnkgY291bGQgcG9zc2libHkgY29udGFpbgorICAgICAgICAgIC8vIGV4dGVuc2lvbnMgb2YgaXQuIE90aGVyd2lzZSB3ZSB3aWxsIHRyZWF0IHRoZSByZWdpc3RyeSBhcyBpZiBpdAorICAgICAgICAgIC8vIHdlcmUgZW1wdHkuCisgICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5IGluc3RhbmNlb2YgRXh0ZW5zaW9uUmVnaXN0cnkpIHsKKyAgICAgICAgICAgIGV4dGVuc2lvbiA9IHRhcmdldC5maW5kRXh0ZW5zaW9uQnlOdW1iZXIoCisgICAgICAgICAgICAgICAgKEV4dGVuc2lvblJlZ2lzdHJ5KSBleHRlbnNpb25SZWdpc3RyeSwgdHlwZSwgdHlwZUlkKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgfSBlbHNlIGlmICh0YWcgPT0gV2lyZUZvcm1hdC5NRVNTQUdFX1NFVF9NRVNTQUdFX1RBRykgeworICAgICAgICBpZiAodHlwZUlkICE9IDApIHsKKyAgICAgICAgICBpZiAoZXh0ZW5zaW9uICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmlzRWFnZXJseVBhcnNlTWVzc2FnZVNldHMoKSkgeworICAgICAgICAgICAgLy8gV2UgYWxyZWFkeSBrbm93IHRoZSB0eXBlLCBzbyB3ZSBjYW4gcGFyc2UgZGlyZWN0bHkgZnJvbSB0aGUKKyAgICAgICAgICAgIC8vIGlucHV0IHdpdGggbm8gY29weWluZy4gIEhvb3JheSEKKyAgICAgICAgICAgIGVhZ2VybHlNZXJnZU1lc3NhZ2VTZXRFeHRlbnNpb24oCisgICAgICAgICAgICAgICAgaW5wdXQsIGV4dGVuc2lvbiwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhcmdldCk7CisgICAgICAgICAgICByYXdCeXRlcyA9IG51bGw7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gV2UgaGF2ZW4ndCBzZWVuIGEgdHlwZSBJRCB5ZXQgb3Igd2Ugd2FudCBwYXJzZSBtZXNzYWdlIGxhemlseS4KKyAgICAgICAgcmF3Qnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKKworICAgICAgfSBlbHNlIHsgLy8gVW5rbm93biB0YWcuIFNraXAgaXQuCisgICAgICAgIGlmICghaW5wdXQuc2tpcEZpZWxkKHRhZykpIHsKKyAgICAgICAgICBicmVhazsgLy8gRW5kIG9mIGdyb3VwCisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgaW5wdXQuY2hlY2tMYXN0VGFnV2FzKFdpcmVGb3JtYXQuTUVTU0FHRV9TRVRfSVRFTV9FTkRfVEFHKTsKKworICAgIC8vIFByb2Nlc3MgdGhlIHJhdyBieXRlcy4KKyAgICBpZiAocmF3Qnl0ZXMgIT0gbnVsbCAmJiB0eXBlSWQgIT0gMCkgeyAvLyBaZXJvIGlzIG5vdCBhIHZhbGlkIHR5cGUgSUQuCisgICAgICBpZiAoZXh0ZW5zaW9uICE9IG51bGwpIHsgLy8gV2Uga25vd24gdGhlIHR5cGUKKyAgICAgICAgbWVyZ2VNZXNzYWdlU2V0RXh0ZW5zaW9uRnJvbUJ5dGVzKAorICAgICAgICAgICAgcmF3Qnl0ZXMsIGV4dGVuc2lvbiwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhcmdldCk7CisgICAgICB9IGVsc2UgeyAvLyBXZSBkb24ndCBrbm93IGhvdyB0byBwYXJzZSB0aGlzLiBJZ25vcmUgaXQuCisgICAgICAgIGlmIChyYXdCeXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgdW5rbm93bkZpZWxkcy5tZXJnZUZpZWxkKHR5cGVJZCwgVW5rbm93bkZpZWxkU2V0LkZpZWxkLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAuYWRkTGVuZ3RoRGVsaW1pdGVkKHJhd0J5dGVzKS5idWlsZCgpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgbWVyZ2VNZXNzYWdlU2V0RXh0ZW5zaW9uRnJvbUJ5dGVzKAorICAgICAgQnl0ZVN0cmluZyByYXdCeXRlcywKKyAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5LkV4dGVuc2lvbkluZm8gZXh0ZW5zaW9uLAorICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgTWVyZ2VUYXJnZXQgdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZXh0ZW5zaW9uLmRlc2NyaXB0b3I7CisgICAgYm9vbGVhbiBoYXNPcmlnaW5hbFZhbHVlID0gdGFyZ2V0Lmhhc0ZpZWxkKGZpZWxkKTsKKworICAgIGlmIChoYXNPcmlnaW5hbFZhbHVlIHx8IEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5pc0VhZ2VybHlQYXJzZU1lc3NhZ2VTZXRzKCkpIHsKKyAgICAgIC8vIElmIHRoZSBmaWVsZCBhbHJlYWR5IGV4aXN0cywgd2UganVzdCBwYXJzZSB0aGUgZmllbGQuCisgICAgICBPYmplY3QgdmFsdWUgPSB0YXJnZXQucGFyc2VNZXNzYWdlRnJvbUJ5dGVzKAorICAgICAgICAgIHJhd0J5dGVzLCBleHRlbnNpb25SZWdpc3RyeSxmaWVsZCwgZXh0ZW5zaW9uLmRlZmF1bHRJbnN0YW5jZSk7CisgICAgICB0YXJnZXQuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVXNlIExhenlGaWVsZCB0byBsb2FkIE1lc3NhZ2VTZXQgbGF6aWx5LgorICAgICAgTGF6eUZpZWxkIGxhenlGaWVsZCA9IG5ldyBMYXp5RmllbGQoCisgICAgICAgICAgZXh0ZW5zaW9uLmRlZmF1bHRJbnN0YW5jZSwgZXh0ZW5zaW9uUmVnaXN0cnksIHJhd0J5dGVzKTsKKyAgICAgIHRhcmdldC5zZXRGaWVsZChmaWVsZCwgbGF6eUZpZWxkKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGVhZ2VybHlNZXJnZU1lc3NhZ2VTZXRFeHRlbnNpb24oCisgICAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgRXh0ZW5zaW9uUmVnaXN0cnkuRXh0ZW5zaW9uSW5mbyBleHRlbnNpb24sCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICBNZXJnZVRhcmdldCB0YXJnZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZXh0ZW5zaW9uLmRlc2NyaXB0b3I7CisgICAgT2JqZWN0IHZhbHVlID0gdGFyZ2V0LnBhcnNlTWVzc2FnZShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlZmF1bHRJbnN0YW5jZSk7CisgICAgdGFyZ2V0LnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1BhcnNlci5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUGFyc2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI3YzAyYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1BhcnNlci5qYXZhCkBAIC0wLDAgKzEsMjYxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIHBhcnNpbmcgUHJvdG9jb2wgTWVzc2FnZXMuCisgKgorICogVGhlIGltcGxlbWVudGF0aW9uIHNob3VsZCBiZSBzdGF0ZWxlc3MgYW5kIHRocmVhZC1zYWZlLgorICoKKyAqIEBhdXRob3IgbGl1amlzaUBnb29nbGUuY29tIChQaGVybCBMaXUpCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUGFyc2VyPE1lc3NhZ2VUeXBlPiB7CisgIC8qKgorICAgKiBQYXJzZXMgYSBtZXNzYWdlIG9mIHtAY29kZSBNZXNzYWdlVHlwZX0gZnJvbSB0aGUgaW5wdXQuCisgICAqCisgICAqIDxwPk5vdGU6ICBUaGUgY2FsbGVyIHNob3VsZCBjYWxsCisgICAqIHtAbGluayBDb2RlZElucHV0U3RyZWFtI2NoZWNrTGFzdFRhZ1dhcyhpbnQpfSBhZnRlciBjYWxsaW5nIHRoaXMgdG8KKyAgICogdmVyaWZ5IHRoYXQgdGhlIGxhc3QgdGFnIHNlZW4gd2FzIHRoZSBhcHByb3ByaWF0ZSBlbmQtZ3JvdXAgdGFnLAorICAgKiBvciB6ZXJvIGZvciBFT0YuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBMaWtlIHtAbGluayAjcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0pfSwgYnV0IGFsc28gcGFyc2VzIGV4dGVuc2lvbnMuCisgICAqIFRoZSBleHRlbnNpb25zIHRoYXQgeW91IHdhbnQgdG8gYmUgYWJsZSB0byBwYXJzZSBtdXN0IGJlIHJlZ2lzdGVyZWQgaW4KKyAgICoge0Bjb2RlIGV4dGVuc2lvblJlZ2lzdHJ5fS4gRXh0ZW5zaW9ucyBub3QgaW4gdGhlIHJlZ2lzdHJ5IHdpbGwgYmUgdHJlYXRlZAorICAgKiBhcyB1bmtub3duIGZpZWxkcy4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBMaWtlIHtAbGluayAjcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0pfSwgYnV0IGRvZXMgbm90IHRocm93IGFuCisgICAqIGV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4gSW5zdGVhZCwgYSBwYXJ0aWFsCisgICAqIG1lc3NhZ2UgaXMgcmV0dXJuZWQuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShDb2RlZElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3BhcnNlRnJvbShDb2RlZElucHV0U3RyZWFtIGlucHV0LCBFeHRlbnNpb25SZWdpc3RyeUxpdGUpfSwKKyAgICogYnV0IGRvZXMgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgICogSW5zdGVhZCwgYSBwYXJ0aWFsIG1lc3NhZ2UgaXMgcmV0dXJuZWQuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShDb2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBDb252ZW5pZW5jZSBtZXRob2RzLgorCisgIC8qKgorICAgKiBQYXJzZXMge0Bjb2RlIGRhdGF9IGFzIGEgbWVzc2FnZSBvZiB7QGNvZGUgTWVzc2FnZVR5cGV9LgorICAgKiBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCB7QGxpbmsgI3BhcnNlRnJvbShDb2RlZElucHV0U3RyZWFtKX0uCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VGcm9tKEJ5dGVTdHJpbmcgZGF0YSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIFBhcnNlcyB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHtAY29kZSBNZXNzYWdlVHlwZX0uCisgICAqIFRoaXMgaXMganVzdCBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kCisgICAqIHtAbGluayAjcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0sIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSl9LgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShCeXRlU3RyaW5nIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3BhcnNlRnJvbShCeXRlU3RyaW5nKX0sIGJ1dCBkb2VzIG5vdCB0aHJvdyBhbgorICAgKiBleGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuIEluc3RlYWQsIGEgcGFydGlhbAorICAgKiBtZXNzYWdlIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oQnl0ZVN0cmluZyBkYXRhKQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3BhcnNlRnJvbShCeXRlU3RyaW5nLCBFeHRlbnNpb25SZWdpc3RyeUxpdGUpfSwKKyAgICogYnV0IGRvZXMgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgICogSW5zdGVhZCwgYSBwYXJ0aWFsIG1lc3NhZ2UgaXMgcmV0dXJuZWQuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShCeXRlU3RyaW5nIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIFBhcnNlcyB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHtAY29kZSBNZXNzYWdlVHlwZX0uCisgICAqIFRoaXMgaXMganVzdCBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kIHtAbGluayAjcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0pfS4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4pCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBQYXJzZXMge0Bjb2RlIGRhdGF9IGFzIGEgbWVzc2FnZSBvZiB7QGNvZGUgTWVzc2FnZVR5cGV9LgorICAgKiBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZAorICAgKiB7QGxpbmsgI3BhcnNlRnJvbShDb2RlZElucHV0U3RyZWFtLCBFeHRlbnNpb25SZWdpc3RyeUxpdGUpfS4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogUGFyc2VzIHtAY29kZSBkYXRhfSBhcyBhIG1lc3NhZ2Ugb2Yge0Bjb2RlIE1lc3NhZ2VUeXBlfS4KKyAgICogVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQge0BsaW5rICNwYXJzZUZyb20oQ29kZWRJbnB1dFN0cmVhbSl9LgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIFBhcnNlcyB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHtAY29kZSBNZXNzYWdlVHlwZX0uCisgICAqIFRoaXMgaXMganVzdCBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kCisgICAqIHtAbGluayAjcGFyc2VGcm9tKENvZGVkSW5wdXRTdHJlYW0sIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSl9LgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlRnJvbShieXRlW10gZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBMaWtlIHtAbGluayAjcGFyc2VGcm9tKGJ5dGVbXSwgaW50LCBpbnQpfSwgYnV0IGRvZXMgbm90IHRocm93IGFuCisgICAqIGV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4gSW5zdGVhZCwgYSBwYXJ0aWFsCisgICAqIG1lc3NhZ2UgaXMgcmV0dXJuZWQuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbShieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNwYXJzZUZyb20oQnl0ZVN0cmluZywgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKX0sCisgICAqIGJ1dCBkb2VzIG5vdCB0aHJvdyBhbiBleGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgICAqIEluc3RlYWQsIGEgcGFydGlhbCBtZXNzYWdlIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNwYXJzZUZyb20oYnl0ZVtdKX0sIGJ1dCBkb2VzIG5vdCB0aHJvdyBhbgorICAgKiBleGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuIEluc3RlYWQsIGEgcGFydGlhbAorICAgKiBtZXNzYWdlIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oYnl0ZVtdIGRhdGEpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBMaWtlIHtAbGluayAjcGFyc2VGcm9tKGJ5dGVbXSwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKX0sCisgICAqIGJ1dCBkb2VzIG5vdCB0aHJvdyBhbiBleGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgICAqIEluc3RlYWQsIGEgcGFydGlhbCBtZXNzYWdlIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oYnl0ZVtdIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIFBhcnNlIGEgbWVzc2FnZSBvZiB7QGNvZGUgTWVzc2FnZVR5cGV9IGZyb20ge0Bjb2RlIGlucHV0fS4KKyAgICogVGhpcyBpcyBqdXN0IGEgc21hbGwgd3JhcHBlciBhcm91bmQge0BsaW5rICNwYXJzZUZyb20oQ29kZWRJbnB1dFN0cmVhbSl9LgorICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgYWx3YXlzIHJlYWRzIHRoZSA8aT5lbnRpcmU8L2k+IGlucHV0ICh1bmxlc3MgaXQKKyAgICogdGhyb3dzIGFuIGV4Y2VwdGlvbikuICBJZiB5b3Ugd2FudCBpdCB0byBzdG9wIGVhcmxpZXIsIHlvdSB3aWxsIG5lZWQgdG8KKyAgICogd3JhcCB5b3VyIGlucHV0IGluIHNvbWUgd3JhcHBlciBzdHJlYW0gdGhhdCBsaW1pdHMgcmVhZGluZy4gIE9yLCB1c2UKKyAgICoge0BsaW5rIE1lc3NhZ2VMaXRlI3dyaXRlRGVsaW1pdGVkVG8oamF2YS5pby5PdXRwdXRTdHJlYW0pfSB0byB3cml0ZSB5b3VyCisgICAqIG1lc3NhZ2UgYW5kIHtAbGluayAjcGFyc2VEZWxpbWl0ZWRGcm9tKElucHV0U3RyZWFtKX0gdG8gcmVhZCBpdC4KKyAgICogPHA+CisgICAqIERlc3BpdGUgdXN1YWxseSByZWFkaW5nIHRoZSBlbnRpcmUgaW5wdXQsIHRoaXMgZG9lcyBub3QgY2xvc2UgdGhlIHN0cmVhbS4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBQYXJzZXMgYSBtZXNzYWdlIG9mIHtAY29kZSBNZXNzYWdlVHlwZX0gZnJvbSB7QGNvZGUgaW5wdXR9LgorICAgKiBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZAorICAgKiB7QGxpbmsgI3BhcnNlRnJvbShDb2RlZElucHV0U3RyZWFtLCBFeHRlbnNpb25SZWdpc3RyeUxpdGUpfS4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZUZyb20oSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3BhcnNlRnJvbShJbnB1dFN0cmVhbSl9LCBidXQgZG9lcyBub3QgdGhyb3cgYW4KKyAgICogZXhjZXB0aW9uIGlmIHRoZSBtZXNzYWdlIGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLiBJbnN0ZWFkLCBhIHBhcnRpYWwKKyAgICogbWVzc2FnZSBpcyByZXR1cm5lZC4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZVBhcnRpYWxGcm9tKElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3BhcnNlRnJvbShJbnB1dFN0cmVhbSwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKX0sCisgICAqIGJ1dCBkb2VzIG5vdCB0aHJvdyBhbiBleGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgICAqIEluc3RlYWQsIGEgcGFydGlhbCBtZXNzYWdlIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIE1lc3NhZ2VUeXBlIHBhcnNlUGFydGlhbEZyb20oSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNwYXJzZUZyb20oSW5wdXRTdHJlYW0pfSwgYnV0IGRvZXMgbm90IHJlYWQgdXRpbCBFT0YuCisgICAqIEluc3RlYWQsIHRoZSBzaXplIG9mIG1lc3NhZ2UgKGVuY29kZWQgYXMgYSB2YXJpbnQpIGlzIHJlYWQgZmlyc3QsCisgICAqIHRoZW4gdGhlIG1lc3NhZ2UgZGF0YS4gVXNlCisgICAqIHtAbGluayBNZXNzYWdlTGl0ZSN3cml0ZURlbGltaXRlZFRvKGphdmEuaW8uT3V0cHV0U3RyZWFtKX0gdG8gd3JpdGUKKyAgICogbWVzc2FnZXMgaW4gdGhpcyBmb3JtYXQuCisgICAqCisgICAqIEByZXR1cm4gUGFyc2VkIG1lc3NhZ2UgaWYgc3VjY2Vzc2Z1bCwgb3IgbnVsbCBpZiB0aGUgc3RyZWFtIGlzIGF0IEVPRiB3aGVuCisgICAqICAgICAgICAgdGhlIG1ldGhvZCBzdGFydHMuIEFueSBvdGhlciBlcnJvciAoaW5jbHVkaW5nIHJlYWNoaW5nIEVPRiBkdXJpbmcKKyAgICogICAgICAgICBwYXJzaW5nKSB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VEZWxpbWl0ZWRGcm9tKElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI3BhcnNlRGVsaW1pdGVkRnJvbShJbnB1dFN0cmVhbSl9IGJ1dCBzdXBwb3J0aW5nIGV4dGVuc2lvbnMuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VEZWxpbWl0ZWRGcm9tKElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNwYXJzZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0pfSwgYnV0IGRvZXMgbm90IHRocm93IGFuCisgICAqIGV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4gSW5zdGVhZCwgYSBwYXJ0aWFsCisgICAqIG1lc3NhZ2UgaXMgcmV0dXJuZWQuCisgICAqLworICBwdWJsaWMgTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRGVsaW1pdGVkRnJvbShJbnB1dFN0cmVhbSBpbnB1dCkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNwYXJzZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0sIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSl9LAorICAgKiBidXQgZG9lcyBub3QgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSBtZXNzYWdlIGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICAgKiBJbnN0ZWFkLCBhIHBhcnRpYWwgbWVzc2FnZSBpcyByZXR1cm5lZC4KKyAgICovCisgIHB1YmxpYyBNZXNzYWdlVHlwZSBwYXJzZVBhcnRpYWxEZWxpbWl0ZWRGcm9tKAorICAgICAgSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUHJvdG9jb2xNZXNzYWdlRW51bS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUHJvdG9jb2xNZXNzYWdlRW51bS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjOGRmOTgKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Qcm90b2NvbE1lc3NhZ2VFbnVtLmphdmEKQEAgLTAsMCArMSw1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yOworCisvKioKKyAqIEludGVyZmFjZSBvZiB1c2VmdWwgbWV0aG9kcyBhZGRlZCB0byBhbGwgZW51bXMgZ2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbAorICogY29tcGlsZXIuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUHJvdG9jb2xNZXNzYWdlRW51bSBleHRlbmRzIEludGVybmFsLkVudW1MaXRlIHsKKworICAvKioKKyAgICogUmV0dXJuIHRoZSB2YWx1ZSdzIG51bWVyaWMgdmFsdWUgYXMgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgICAqLworICBpbnQgZ2V0TnVtYmVyKCk7CisKKyAgLyoqCisgICAqIFJldHVybiB0aGUgdmFsdWUncyBkZXNjcmlwdG9yLCB3aGljaCBjb250YWlucyBpbmZvcm1hdGlvbiBzdWNoIGFzCisgICAqIHZhbHVlIG5hbWUsIG51bWJlciwgYW5kIHR5cGUuCisgICAqLworICBFbnVtVmFsdWVEZXNjcmlwdG9yIGdldFZhbHVlRGVzY3JpcHRvcigpOworCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIGVudW0gdHlwZSdzIGRlc2NyaXB0b3IsIHdoaWNoIGNvbnRhaW5zIGluZm9ybWF0aW9uCisgICAqIGFib3V0IGVhY2ggZGVmaW5lZCB2YWx1ZSwgZXRjLgorICAgKi8KKyAgRW51bURlc2NyaXB0b3IgZ2V0RGVzY3JpcHRvckZvclR5cGUoKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Byb3RvY29sU3RyaW5nTGlzdC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUHJvdG9jb2xTdHJpbmdMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDU1M2I0MQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Byb3RvY29sU3RyaW5nTGlzdC5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZXh0ZW5kaW5nIHtAY29kZSBMaXN0PFN0cmluZz59IHVzZWQgZm9yIHJlcGVhdGVkIHN0cmluZyBmaWVsZHMKKyAqIHRvIHByb3ZpZGUgb3B0aW9uYWwgYWNjZXNzIHRvIHRoZSBkYXRhIGFzIGEgbGlzdCBvZiBCeXRlU3RyaW5ncy4gVGhlCisgKiB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIHN0b3JlcyB2YWx1ZXMgYXMgZWl0aGVyIEJ5dGVTdHJpbmdzIG9yIFN0cmluZ3MKKyAqIChzZWUge0BsaW5rIExhenlTdHJpbmdBcnJheUxpc3R9KSBkZXBlbmRpbmcgb24gaG93IHRoZSB2YWx1ZSB3YXMgaW5pdGlhbGl6ZWQKKyAqIG9yIGxhc3QgcmVhZCwgYW5kIGl0IGlzIG9mdGVuIG1vcmUgZWZmaWNpZW50IHRvIGRlYWwgd2l0aCBsaXN0cyBvZgorICogQnl0ZVN0cmluZ3Mgd2hlbiBoYW5kbGluZyBwcm90b3MgdGhhdCBoYXZlIGJlZW4gZGVzZXJpYWxpemVkIGZyb20gYnl0ZXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUHJvdG9jb2xTdHJpbmdMaXN0IGV4dGVuZHMgTGlzdDxTdHJpbmc+IHsKKworICAvKiogUmV0dXJucyBhIHZpZXcgb2YgdGhlIGRhdGEgYXMgYSBsaXN0IG9mIEJ5dGVTdHJpbmdzLiAqLworICBMaXN0PEJ5dGVTdHJpbmc+IGFzQnl0ZVN0cmluZ0xpc3QoKTsKKworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUmVwZWF0ZWRGaWVsZEJ1aWxkZXIuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JlcGVhdGVkRmllbGRCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmU3MzdiMQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JlcGVhdGVkRmllbGRCdWlsZGVyLmphdmEKQEAgLTAsMCArMSw3MDIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIHtAY29kZSBSZXBlYXRlZEZpZWxkQnVpbGRlcn0gaW1wbGVtZW50cyBhIHN0cnVjdHVyZSB0aGF0IGEgcHJvdG9jb2wKKyAqIG1lc3NhZ2UgdXNlcyB0byBob2xkIGEgcmVwZWF0ZWQgZmllbGQgb2Ygb3RoZXIgcHJvdG9jb2wgbWVzc2FnZXMuIEl0IHN1cHBvcnRzCisgKiB0aGUgY2xhc3NpY2FsIHVzZSBjYXNlIG9mIGFkZGluZyBpbW11dGFibGUge0BsaW5rIE1lc3NhZ2V9J3MgdG8gdGhlCisgKiByZXBlYXRlZCBmaWVsZCBhbmQgaXMgaGlnaGx5IG9wdGltaXplZCBhcm91bmQgdGhpcyAobm8gZXh0cmEgbWVtb3J5CisgKiBhbGxvY2F0aW9ucyBhbmQgc2hhcmluZyBvZiBpbW11dGFibGUgYXJyYXlzKS4KKyAqIDxicj4KKyAqIEl0IGFsc28gc3VwcG9ydHMgdGhlIGFkZGl0aW9uYWwgdXNlIGNhc2Ugb2YgYWRkaW5nIGEge0BsaW5rIE1lc3NhZ2UuQnVpbGRlcn0KKyAqIHRvIHRoZSByZXBlYXRlZCBmaWVsZCBhbmQgZGVmZXJyaW5nIGNvbnZlcnNpb24gb2YgdGhhdCB7QGNvZGUgQnVpbGRlcn0KKyAqIHRvIGFuIGltbXV0YWJsZSB7QGNvZGUgTWVzc2FnZX0uIEluIHRoaXMgd2F5LCBpdCdzIHBvc3NpYmxlIHRvIG1haW50YWluCisgKiBhIHRyZWUgb2Yge0Bjb2RlIEJ1aWxkZXJ9J3MgdGhhdCBhY3RzIGFzIGEgZnVsbHkgcmVhZC93cml0ZSBkYXRhCisgKiBzdHJ1Y3R1cmUuCisgKiA8YnI+CisgKiBMb2dpY2FsbHksIG9uZSBjYW4gdGhpbmsgb2YgYSB0cmVlIG9mIGJ1aWxkZXJzIGFzIGNvbnZlcnRpbmcgdGhlIGVudGlyZSB0cmVlCisgKiB0byBtZXNzYWdlcyB3aGVuIGJ1aWxkIGlzIGNhbGxlZCBvbiB0aGUgcm9vdCBvciB3aGVuIGFueSBtZXRob2QgaXMgY2FsbGVkCisgKiB0aGF0IGRlc2lyZXMgYSBNZXNzYWdlIGluc3RlYWQgb2YgYSBCdWlsZGVyLiBJbiB0ZXJtcyBvZiB0aGUgaW1wbGVtZW50YXRpb24sCisgKiB0aGUge0Bjb2RlIFNpbmdsZUZpZWxkQnVpbGRlcn0gYW5kIHtAY29kZSBSZXBlYXRlZEZpZWxkQnVpbGRlcn0KKyAqIGNsYXNzZXMgY2FjaGUgbWVzc2FnZXMgdGhhdCB3ZXJlIGNyZWF0ZWQgc28gdGhhdCBtZXNzYWdlcyBvbmx5IG5lZWQgdG8gYmUKKyAqIGNyZWF0ZWQgd2hlbiBzb21lIGNoYW5nZSBvY2N1cnJlZCBpbiBpdHMgYnVpbGRlciBvciBhIGJ1aWxkZXIgZm9yIG9uZSBvZiBpdHMKKyAqIGRlc2NlbmRhbnRzLgorICoKKyAqIEBwYXJhbSA8TVR5cGU+IHRoZSB0eXBlIG9mIG1lc3NhZ2UgZm9yIHRoZSBmaWVsZAorICogQHBhcmFtIDxCVHlwZT4gdGhlIHR5cGUgb2YgYnVpbGRlciBmb3IgdGhlIGZpZWxkCisgKiBAcGFyYW0gPElUeXBlPiB0aGUgY29tbW9uIGludGVyZmFjZSBmb3IgdGhlIG1lc3NhZ2UgYW5kIHRoZSBidWlsZGVyCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKi8KK3B1YmxpYyBjbGFzcyBSZXBlYXRlZEZpZWxkQnVpbGRlcgorICAgIDxNVHlwZSBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2UsCisgICAgIEJUeXBlIGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyLAorICAgICBJVHlwZSBleHRlbmRzIE1lc3NhZ2VPckJ1aWxkZXI+CisgICAgaW1wbGVtZW50cyBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXJQYXJlbnQgeworCisgIC8vIFBhcmVudCB0byBzZW5kIGNoYW5nZXMgdG8uCisgIHByaXZhdGUgR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyUGFyZW50IHBhcmVudDsKKworICAvLyBMaXN0IG9mIG1lc3NhZ2VzLiBOZXZlciBudWxsLiBJdCBtYXkgYmUgaW1tdXRhYmxlLCBpbiB3aGljaCBjYXNlCisgIC8vIGlzTWVzc2FnZXNMaXN0SW1tdXRhYmxlIHdpbGwgYmUgdHJ1ZS4gU2VlIG5vdGUgYmVsb3cuCisgIHByaXZhdGUgTGlzdDxNVHlwZT4gbWVzc2FnZXM7CisKKyAgLy8gV2hldGhlciBtZXNzYWdlcyBpcyBhbiBtdXRhYmxlIGFycmF5IHRoYXQgY2FuIGJlIG1vZGlmaWVkLgorICBwcml2YXRlIGJvb2xlYW4gaXNNZXNzYWdlc0xpc3RNdXRhYmxlOworCisgIC8vIExpc3Qgb2YgYnVpbGRlcnMuIE1heSBiZSBudWxsLCBpbiB3aGljaCBjYXNlLCBubyBuZXN0ZWQgYnVpbGRlcnMgd2VyZQorICAvLyBjcmVhdGVkLiBJZiBub3QgbnVsbCwgZW50cmllcyByZXByZXNlbnQgdGhlIGJ1aWxkZXIgZm9yIHRoYXQgaW5kZXguCisgIHByaXZhdGUgTGlzdDxTaW5nbGVGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4+IGJ1aWxkZXJzOworCisgIC8vIEhlcmUgYXJlIHRoZSBpbnZhcmlhbnRzIGZvciBtZXNzYWdlcyBhbmQgYnVpbGRlcnM6CisgIC8vIDEuIG1lc3NhZ2VzIGlzIG5ldmVyIG51bGwgYW5kIGl0cyBjb3VudCBjb3JyZXNwb25kcyB0byB0aGUgbnVtYmVyIG9mIGl0ZW1zCisgIC8vICAgIGluIHRoZSByZXBlYXRlZCBmaWVsZC4KKyAgLy8gMi4gSWYgYnVpbGRlcnMgaXMgbm9uLW51bGwsIG1lc3NhZ2VzIGFuZCBidWlsZGVycyBNVVNUIGFsd2F5cworICAvLyAgICBjb250YWluIHRoZSBzYW1lIG51bWJlciBvZiBpdGVtcy4KKyAgLy8gMy4gRW50cmllcyBpbiBlaXRoZXIgYXJyYXkgY2FuIGJlIG51bGwsIGJ1dCBmb3IgYW55IGluZGV4LCB0aGVyZSBNVVNUIGJlCisgIC8vICAgIGVpdGhlciBhIE1lc3NhZ2UgaW4gbWVzc2FnZXMgb3IgYSBidWlsZGVyIGluIGJ1aWxkZXJzLgorICAvLyA0LiBJZiB0aGUgYnVpbGRlciBhdCBhbiBpbmRleCBpcyBub24tbnVsbCwgdGhlIGJ1aWxkZXIgaXMKKyAgLy8gICAgYXV0aG9yaXRhdGl2ZS4gVGhpcyBpcyB0aGUgY2FzZSB3aGVyZSBhIEJ1aWxkZXIgd2FzIHNldCBvbiB0aGUgaW5kZXguCisgIC8vICAgIEFueSBtZXNzYWdlIGluIHRoZSBtZXNzYWdlcyBhcnJheSBNVVNUIGJlIGlnbm9yZWQuCisgIC8vIHQuIElmIHRoZSBidWlsZGVyIGF0IGFuIGluZGV4IGlzIG51bGwsIHRoZSBtZXNzYWdlIGluIHRoZSBtZXNzYWdlcworICAvLyAgICBsaXN0IGlzIGF1dGhvcml0YXRpdmUuIFRoaXMgaXMgdGhlIGNhc2Ugd2hlcmUgYSBNZXNzYWdlIChub3QgYSBCdWlsZGVyKQorICAvLyAgICB3YXMgc2V0IGRpcmVjdGx5IGZvciBhbiBpbmRleC4KKworICAvLyBJbmRpY2F0ZXMgdGhhdCB3ZSd2ZSBidWlsdCBhIG1lc3NhZ2UgYW5kIHNvIHdlIGFyZSBub3cgb2JsaWdhdGVkCisgIC8vIHRvIGRpc3BhdGNoIGRpcnR5IGludmFsaWRhdGlvbnMuIFNlZSBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXJMaXN0ZW5lci4KKyAgcHJpdmF0ZSBib29sZWFuIGlzQ2xlYW47CisKKyAgLy8gQSB2aWV3IG9mIHRoaXMgYnVpbGRlciB0aGF0IGV4cG9zZXMgYSBMaXN0IGludGVyZmFjZSBvZiBtZXNzYWdlcy4gVGhpcyBpcworICAvLyBpbml0aWFsaXplZCBvbiBkZW1hbmQuIFRoaXMgaXMgZnVsbHkgYmFja2VkIGJ5IHRoaXMgb2JqZWN0IGFuZCBhbGwgY2hhbmdlcworICAvLyBhcmUgcmVmbGVjdGVkIGluIGl0LiBBY2Nlc3MgdG8gYW55IGl0ZW0gY29udmVydHMgaXQgdG8gYSBtZXNzYWdlIGlmIGl0CisgIC8vIHdhcyBhIGJ1aWxkZXIuCisgIHByaXZhdGUgTWVzc2FnZUV4dGVybmFsTGlzdDxNVHlwZSwgQlR5cGUsIElUeXBlPiBleHRlcm5hbE1lc3NhZ2VMaXN0OworCisgIC8vIEEgdmlldyBvZiB0aGlzIGJ1aWxkZXIgdGhhdCBleHBvc2VzIGEgTGlzdCBpbnRlcmZhY2Ugb2YgYnVpbGRlcnMuIFRoaXMgaXMKKyAgLy8gaW5pdGlhbGl6ZWQgb24gZGVtYW5kLiBUaGlzIGlzIGZ1bGx5IGJhY2tlZCBieSB0aGlzIG9iamVjdCBhbmQgYWxsIGNoYW5nZXMKKyAgLy8gYXJlIHJlZmxlY3RlZCBpbiBpdC4gQWNjZXNzIHRvIGFueSBpdGVtIGNvbnZlcnRzIGl0IHRvIGEgYnVpbGRlciBpZiBpdAorICAvLyB3YXMgYSBtZXNzYWdlLgorICBwcml2YXRlIEJ1aWxkZXJFeHRlcm5hbExpc3Q8TVR5cGUsIEJUeXBlLCBJVHlwZT4gZXh0ZXJuYWxCdWlsZGVyTGlzdDsKKworICAvLyBBIHZpZXcgb2YgdGhpcyBidWlsZGVyIHRoYXQgZXhwb3NlcyBhIExpc3QgaW50ZXJmYWNlIG9mIHRoZSBpbnRlcmZhY2UKKyAgLy8gaW1wbGVtZW50ZWQgYnkgbWVzc2FnZXMgYW5kIGJ1aWxkZXJzLiBUaGlzIGlzIGluaXRpYWxpemVkIG9uIGRlbWFuZC4gVGhpcworICAvLyBpcyBmdWxseSBiYWNrZWQgYnkgdGhpcyBvYmplY3QgYW5kIGFsbCBjaGFuZ2VzIGFyZSByZWZsZWN0ZWQgaW4gaXQuCisgIC8vIEFjY2VzcyB0byBhbnkgaXRlbSByZXR1cm5zIGVpdGhlciBhIGJ1aWxkZXIgb3IgbWVzc2FnZSBkZXBlbmRpbmcgb24KKyAgLy8gd2hhdCBpcyBtb3N0IGVmZmljaWVudC4KKyAgcHJpdmF0ZSBNZXNzYWdlT3JCdWlsZGVyRXh0ZXJuYWxMaXN0PE1UeXBlLCBCVHlwZSwgSVR5cGU+CisgICAgICBleHRlcm5hbE1lc3NhZ2VPckJ1aWxkZXJMaXN0OworCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGJ1aWxkZXIgd2l0aCBhbiBlbXB0eSBsaXN0IG9mIG1lc3NhZ2VzLgorICAgKgorICAgKiBAcGFyYW0gbWVzc2FnZXMgdGhlIGN1cnJlbnQgbGlzdCBvZiBtZXNzYWdlcworICAgKiBAcGFyYW0gaXNNZXNzYWdlc0xpc3RNdXRhYmxlIFdoZXRoZXIgdGhlIG1lc3NhZ2VzIGxpc3QgaXMgbXV0YWJsZQorICAgKiBAcGFyYW0gcGFyZW50IGEgbGlzdGVuZXIgdG8gbm90aWZ5IG9mIGNoYW5nZXMKKyAgICogQHBhcmFtIGlzQ2xlYW4gd2hldGhlciB0aGUgYnVpbGRlciBpcyBpbml0aWFsbHkgbWFya2VkIGNsZWFuCisgICAqLworICBwdWJsaWMgUmVwZWF0ZWRGaWVsZEJ1aWxkZXIoCisgICAgICBMaXN0PE1UeXBlPiBtZXNzYWdlcywKKyAgICAgIGJvb2xlYW4gaXNNZXNzYWdlc0xpc3RNdXRhYmxlLAorICAgICAgR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyUGFyZW50IHBhcmVudCwKKyAgICAgIGJvb2xlYW4gaXNDbGVhbikgeworICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlczsKKyAgICB0aGlzLmlzTWVzc2FnZXNMaXN0TXV0YWJsZSA9IGlzTWVzc2FnZXNMaXN0TXV0YWJsZTsKKyAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKKyAgICB0aGlzLmlzQ2xlYW4gPSBpc0NsZWFuOworICB9CisKKyAgcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKKyAgICAvLyBOdWxsIG91dCBwYXJlbnQgc28gd2Ugc3RvcCBzZW5kaW5nIGl0IGludmFsaWRhdGlvbnMuCisgICAgcGFyZW50ID0gbnVsbDsKKyAgfQorCisgIC8qKgorICAgKiBFbnN1cmVzIHRoYXQgdGhlIGxpc3Qgb2YgbWVzc2FnZXMgaXMgbXV0YWJsZSBzbyBpdCBjYW4gYmUgdXBkYXRlZC4gSWYgaXQncworICAgKiBpbW11dGFibGUsIGEgY29weSBpcyBtYWRlLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGVuc3VyZU11dGFibGVNZXNzYWdlTGlzdCgpIHsKKyAgICBpZiAoIWlzTWVzc2FnZXNMaXN0TXV0YWJsZSkgeworICAgICAgbWVzc2FnZXMgPSBuZXcgQXJyYXlMaXN0PE1UeXBlPihtZXNzYWdlcyk7CisgICAgICBpc01lc3NhZ2VzTGlzdE11dGFibGUgPSB0cnVlOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBFbnN1cmVzIHRoYXQgdGhlIGxpc3Qgb2YgYnVpbGRlcnMgaXMgbm90IG51bGwuIElmIGl0J3MgbnVsbCwgdGhlIGxpc3QgaXMKKyAgICogY3JlYXRlZCBhbmQgaW5pdGlhbGl6ZWQgdG8gYmUgdGhlIHNhbWUgc2l6ZSBhcyB0aGUgbWVzc2FnZXMgbGlzdCB3aXRoCisgICAqIG51bGwgZW50cmllcy4KKyAgICovCisgIHByaXZhdGUgdm9pZCBlbnN1cmVCdWlsZGVycygpIHsKKyAgICBpZiAodGhpcy5idWlsZGVycyA9PSBudWxsKSB7CisgICAgICB0aGlzLmJ1aWxkZXJzID0KKyAgICAgICAgICBuZXcgQXJyYXlMaXN0PFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPj4oCisgICAgICAgICAgICAgIG1lc3NhZ2VzLnNpemUoKSk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VzLnNpemUoKTsgaSsrKSB7CisgICAgICAgIGJ1aWxkZXJzLmFkZChudWxsKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgY291bnQgb2YgaXRlbXMgaW4gdGhlIGxpc3QuCisgICAqCisgICAqIEByZXR1cm4gdGhlIGNvdW50IG9mIGl0ZW1zIGluIHRoZSBsaXN0LgorICAgKi8KKyAgcHVibGljIGludCBnZXRDb3VudCgpIHsKKyAgICByZXR1cm4gbWVzc2FnZXMuc2l6ZSgpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgd2hldGhlciB0aGUgbGlzdCBpcyBlbXB0eS4KKyAgICoKKyAgICogQHJldHVybiB3aGV0aGVyIHRoZSBsaXN0IGlzIGVtcHR5CisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgIHJldHVybiBtZXNzYWdlcy5pc0VtcHR5KCk7CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSBtZXNzYWdlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIElmIHRoZSBtZXNzYWdlIGlzIGN1cnJlbnRseSBzdG9yZWQKKyAgICogYXMgYSB7QGNvZGUgQnVpbGRlcn0sIGl0IGlzIGNvbnZlcnRlZCB0byBhIHtAY29kZSBNZXNzYWdlfSBieQorICAgKiBjYWxsaW5nIHtAbGluayBNZXNzYWdlLkJ1aWxkZXIjYnVpbGRQYXJ0aWFsfSBvbiBpdC4KKyAgICoKKyAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZSB0byBnZXQKKyAgICogQHJldHVybiB0aGUgbWVzc2FnZSBmb3IgdGhlIHNwZWNpZmllZCBpbmRleAorICAgKi8KKyAgcHVibGljIE1UeXBlIGdldE1lc3NhZ2UoaW50IGluZGV4KSB7CisgICAgcmV0dXJuIGdldE1lc3NhZ2UoaW5kZXgsIGZhbHNlKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIG1lc3NhZ2UgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gSWYgdGhlIG1lc3NhZ2UgaXMgY3VycmVudGx5IHN0b3JlZAorICAgKiBhcyBhIHtAY29kZSBCdWlsZGVyfSwgaXQgaXMgY29udmVydGVkIHRvIGEge0Bjb2RlIE1lc3NhZ2V9IGJ5CisgICAqIGNhbGxpbmcge0BsaW5rIE1lc3NhZ2UuQnVpbGRlciNidWlsZFBhcnRpYWx9IG9uIGl0LgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBtZXNzYWdlIHRvIGdldAorICAgKiBAcGFyYW0gZm9yQnVpbGQgdGhpcyBpcyBiZWluZyBjYWxsZWQgZm9yIGJ1aWxkIHNvIHdlIHdhbnQgdG8gbWFrZSBzdXJlCisgICAqICAgICB3ZSBTaW5nbGVGaWVsZEJ1aWxkZXIuYnVpbGQgdG8gc2VuZCBkaXJ0eSBpbnZhbGlkYXRpb25zCisgICAqIEByZXR1cm4gdGhlIG1lc3NhZ2UgZm9yIHRoZSBzcGVjaWZpZWQgaW5kZXgKKyAgICovCisgIHByaXZhdGUgTVR5cGUgZ2V0TWVzc2FnZShpbnQgaW5kZXgsIGJvb2xlYW4gZm9yQnVpbGQpIHsKKyAgICBpZiAodGhpcy5idWlsZGVycyA9PSBudWxsKSB7CisgICAgICAvLyBXZSBkb24ndCBoYXZlIGFueSBidWlsZGVycyAtLSByZXR1cm4gdGhlIGN1cnJlbnQgTWVzc2FnZS4KKyAgICAgIC8vIFRoaXMgaXMgdGhlIGNhc2Ugd2hlcmUgbm8gYnVpbGRlciB3YXMgY3JlYXRlZCwgc28gd2UgTVVTVCBoYXZlIGEKKyAgICAgIC8vIE1lc3NhZ2UuCisgICAgICByZXR1cm4gbWVzc2FnZXMuZ2V0KGluZGV4KTsKKyAgICB9CisKKyAgICBTaW5nbGVGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gYnVpbGRlciA9IGJ1aWxkZXJzLmdldChpbmRleCk7CisgICAgaWYgKGJ1aWxkZXIgPT0gbnVsbCkgeworICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSBhIGJ1aWxkZXIgLS0gcmV0dXJuIHRoZSBjdXJyZW50IG1lc3NhZ2UuCisgICAgICAvLyBUaGlzIGlzIHRoZSBjYXNlIHdoZXJlIG5vIGJ1aWxkZXIgd2FzIGNyZWF0ZWQgZm9yIHRoZSBlbnRyeSBhdCBpbmRleCwKKyAgICAgIC8vIHNvIHdlIE1VU1QgaGF2ZSBhIG1lc3NhZ2UuCisgICAgICByZXR1cm4gbWVzc2FnZXMuZ2V0KGluZGV4KTsKKworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZm9yQnVpbGQgPyBidWlsZGVyLmJ1aWxkKCkgOiBidWlsZGVyLmdldE1lc3NhZ2UoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogR2V0cyBhIGJ1aWxkZXIgZm9yIHRoZSBzcGVjaWZpZWQgaW5kZXguIElmIG5vIGJ1aWxkZXIgaGFzIGJlZW4gY3JlYXRlZCBmb3IKKyAgICogdGhhdCBpbmRleCwgYSBidWlsZGVyIGlzIGNyZWF0ZWQgb24gZGVtYW5kIGJ5IGNhbGxpbmcKKyAgICoge0BsaW5rIE1lc3NhZ2UjdG9CdWlsZGVyfS4KKyAgICoKKyAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZSB0byBnZXQKKyAgICogQHJldHVybiBUaGUgYnVpbGRlciBmb3IgdGhhdCBpbmRleAorICAgKi8KKyAgcHVibGljIEJUeXBlIGdldEJ1aWxkZXIoaW50IGluZGV4KSB7CisgICAgZW5zdXJlQnVpbGRlcnMoKTsKKyAgICBTaW5nbGVGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gYnVpbGRlciA9IGJ1aWxkZXJzLmdldChpbmRleCk7CisgICAgaWYgKGJ1aWxkZXIgPT0gbnVsbCkgeworICAgICAgTVR5cGUgbWVzc2FnZSA9IG1lc3NhZ2VzLmdldChpbmRleCk7CisgICAgICBidWlsZGVyID0gbmV3IFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPigKKyAgICAgICAgICBtZXNzYWdlLCB0aGlzLCBpc0NsZWFuKTsKKyAgICAgIGJ1aWxkZXJzLnNldChpbmRleCwgYnVpbGRlcik7CisgICAgfQorICAgIHJldHVybiBidWlsZGVyLmdldEJ1aWxkZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBiYXNlIGNsYXNzIGludGVyZmFjZSBmb3IgdGhlIHNwZWNpZmllZCBpbmRleC4gVGhpcyBtYXkgZWl0aGVyIGJlCisgICAqIGEgYnVpbGRlciBvciBhIG1lc3NhZ2UuIEl0IHdpbGwgcmV0dXJuIHdoYXRldmVyIGlzIG1vcmUgZWZmaWNpZW50LgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBtZXNzYWdlIHRvIGdldAorICAgKiBAcmV0dXJuIHRoZSBtZXNzYWdlIG9yIGJ1aWxkZXIgZm9yIHRoZSBpbmRleCBhcyB0aGUgYmFzZSBjbGFzcyBpbnRlcmZhY2UKKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgSVR5cGUgZ2V0TWVzc2FnZU9yQnVpbGRlcihpbnQgaW5kZXgpIHsKKyAgICBpZiAodGhpcy5idWlsZGVycyA9PSBudWxsKSB7CisgICAgICAvLyBXZSBkb24ndCBoYXZlIGFueSBidWlsZGVycyAtLSByZXR1cm4gdGhlIGN1cnJlbnQgTWVzc2FnZS4KKyAgICAgIC8vIFRoaXMgaXMgdGhlIGNhc2Ugd2hlcmUgbm8gYnVpbGRlciB3YXMgY3JlYXRlZCwgc28gd2UgTVVTVCBoYXZlIGEKKyAgICAgIC8vIE1lc3NhZ2UuCisgICAgICByZXR1cm4gKElUeXBlKSBtZXNzYWdlcy5nZXQoaW5kZXgpOworICAgIH0KKworICAgIFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBidWlsZGVyID0gYnVpbGRlcnMuZ2V0KGluZGV4KTsKKyAgICBpZiAoYnVpbGRlciA9PSBudWxsKSB7CisgICAgICAvLyBXZSBkb24ndCBoYXZlIGEgYnVpbGRlciAtLSByZXR1cm4gdGhlIGN1cnJlbnQgbWVzc2FnZS4KKyAgICAgIC8vIFRoaXMgaXMgdGhlIGNhc2Ugd2hlcmUgbm8gYnVpbGRlciB3YXMgY3JlYXRlZCBmb3IgdGhlIGVudHJ5IGF0IGluZGV4LAorICAgICAgLy8gc28gd2UgTVVTVCBoYXZlIGEgbWVzc2FnZS4KKyAgICAgIHJldHVybiAoSVR5cGUpIG1lc3NhZ2VzLmdldChpbmRleCk7CisKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0TWVzc2FnZU9yQnVpbGRlcigpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTZXRzIGEgIG1lc3NhZ2UgYXQgdGhlIHNwZWNpZmllZCBpbmRleCByZXBsYWNpbmcgdGhlIGV4aXN0aW5nIGl0ZW0gYXQKKyAgICogdGhhdCBpbmRleC4KKyAgICoKKyAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCB0byBzZXQuCisgICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBtZXNzYWdlIHRvIHNldAorICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAqLworICBwdWJsaWMgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gc2V0TWVzc2FnZSgKKyAgICAgIGludCBpbmRleCwgTVR5cGUgbWVzc2FnZSkgeworICAgIGlmIChtZXNzYWdlID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgIH0KKyAgICBlbnN1cmVNdXRhYmxlTWVzc2FnZUxpc3QoKTsKKyAgICBtZXNzYWdlcy5zZXQoaW5kZXgsIG1lc3NhZ2UpOworICAgIGlmIChidWlsZGVycyAhPSBudWxsKSB7CisgICAgICBTaW5nbGVGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gZW50cnkgPQorICAgICAgICAgIGJ1aWxkZXJzLnNldChpbmRleCwgbnVsbCk7CisgICAgICBpZiAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICBlbnRyeS5kaXNwb3NlKCk7CisgICAgICB9CisgICAgfQorICAgIG9uQ2hhbmdlZCgpOworICAgIGluY3JlbWVudE1vZENvdW50cygpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqCisgICAqIEFwcGVuZHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IHRvIHRoZSBlbmQgb2YgdGhpcyBsaXN0LgorICAgKgorICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSB0byBhZGQKKyAgICogQHJldHVybiB0aGUgYnVpbGRlcgorICAgKi8KKyAgcHVibGljIFJlcGVhdGVkRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+IGFkZE1lc3NhZ2UoCisgICAgICBNVHlwZSBtZXNzYWdlKSB7CisgICAgaWYgKG1lc3NhZ2UgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgfQorICAgIGVuc3VyZU11dGFibGVNZXNzYWdlTGlzdCgpOworICAgIG1lc3NhZ2VzLmFkZChtZXNzYWdlKTsKKyAgICBpZiAoYnVpbGRlcnMgIT0gbnVsbCkgeworICAgICAgYnVpbGRlcnMuYWRkKG51bGwpOworICAgIH0KKyAgICBvbkNoYW5nZWQoKTsKKyAgICBpbmNyZW1lbnRNb2RDb3VudHMoKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIGluIHRoaXMgbGlzdC4KKyAgICogU2hpZnRzIHRoZSBlbGVtZW50IGN1cnJlbnRseSBhdCB0aGF0IHBvc2l0aW9uIChpZiBhbnkpIGFuZCBhbnkgc3Vic2VxdWVudAorICAgKiBlbGVtZW50cyB0byB0aGUgcmlnaHQgKGFkZHMgb25lIHRvIHRoZWlyIGluZGljZXMpLgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydCB0aGUgbWVzc2FnZQorICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSB0byBhZGQKKyAgICogQHJldHVybiB0aGUgYnVpbGRlcgorICAgKi8KKyAgcHVibGljIFJlcGVhdGVkRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+IGFkZE1lc3NhZ2UoCisgICAgICBpbnQgaW5kZXgsIE1UeXBlIG1lc3NhZ2UpIHsKKyAgICBpZiAobWVzc2FnZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICB9CisgICAgZW5zdXJlTXV0YWJsZU1lc3NhZ2VMaXN0KCk7CisgICAgbWVzc2FnZXMuYWRkKGluZGV4LCBtZXNzYWdlKTsKKyAgICBpZiAoYnVpbGRlcnMgIT0gbnVsbCkgeworICAgICAgYnVpbGRlcnMuYWRkKGluZGV4LCBudWxsKTsKKyAgICB9CisgICAgb25DaGFuZ2VkKCk7CisgICAgaW5jcmVtZW50TW9kQ291bnRzKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogQXBwZW5kcyBhbGwgb2YgdGhlIG1lc3NhZ2VzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiB0byB0aGUgZW5kIG9mCisgICAqIHRoaXMgbGlzdCwgaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcmUgcmV0dXJuZWQgYnkgdGhlIHNwZWNpZmllZAorICAgKiBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAqCisgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIG1lc3NhZ2VzIHRvIGFkZAorICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAqLworICBwdWJsaWMgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gYWRkQWxsTWVzc2FnZXMoCisgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgTVR5cGU+IHZhbHVlcykgeworICAgIGZvciAoZmluYWwgTVR5cGUgdmFsdWUgOiB2YWx1ZXMpIHsKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgfQorICAgIH0KKworICAgIC8vIElmIHdlIGNhbiBpbnNwZWN0IHRoZSBzaXplLCB3ZSBjYW4gbW9yZSBlZmZpY2llbnRseSBhZGQgbWVzc2FnZXMuCisgICAgaW50IHNpemUgPSAtMTsKKyAgICBpZiAodmFsdWVzIGluc3RhbmNlb2YgQ29sbGVjdGlvbikgeworICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIGZpbmFsCisgICAgICBDb2xsZWN0aW9uPE1UeXBlPiBjb2xsZWN0aW9uID0gKENvbGxlY3Rpb248TVR5cGU+KSB2YWx1ZXM7CisgICAgICBpZiAoY29sbGVjdGlvbi5zaXplKCkgPT0gMCkgeworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIHNpemUgPSBjb2xsZWN0aW9uLnNpemUoKTsKKyAgICB9CisgICAgZW5zdXJlTXV0YWJsZU1lc3NhZ2VMaXN0KCk7CisKKyAgICBpZiAoc2l6ZSA+PSAwICYmIG1lc3NhZ2VzIGluc3RhbmNlb2YgQXJyYXlMaXN0KSB7CisgICAgICAoKEFycmF5TGlzdDxNVHlwZT4pIG1lc3NhZ2VzKQorICAgICAgICAgIC5lbnN1cmVDYXBhY2l0eShtZXNzYWdlcy5zaXplKCkgKyBzaXplKTsKKyAgICB9CisKKyAgICBmb3IgKE1UeXBlIHZhbHVlIDogdmFsdWVzKSB7CisgICAgICBhZGRNZXNzYWdlKHZhbHVlKTsKKyAgICB9CisKKyAgICBvbkNoYW5nZWQoKTsKKyAgICBpbmNyZW1lbnRNb2RDb3VudHMoKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBBcHBlbmRzIGEgbmV3IGJ1aWxkZXIgdG8gdGhlIGVuZCBvZiB0aGlzIGxpc3QgYW5kIHJldHVybnMgdGhlIGJ1aWxkZXIuCisgICAqCisgICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBtZXNzYWdlIHRvIGFkZCB3aGljaCBpcyB0aGUgYmFzaXMgb2YgdGhlIGJ1aWxkZXIKKyAgICogQHJldHVybiB0aGUgbmV3IGJ1aWxkZXIKKyAgICovCisgIHB1YmxpYyBCVHlwZSBhZGRCdWlsZGVyKE1UeXBlIG1lc3NhZ2UpIHsKKyAgICBlbnN1cmVNdXRhYmxlTWVzc2FnZUxpc3QoKTsKKyAgICBlbnN1cmVCdWlsZGVycygpOworICAgIFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBidWlsZGVyID0KKyAgICAgICAgbmV3IFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPigKKyAgICAgICAgICAgIG1lc3NhZ2UsIHRoaXMsIGlzQ2xlYW4pOworICAgIG1lc3NhZ2VzLmFkZChudWxsKTsKKyAgICBidWlsZGVycy5hZGQoYnVpbGRlcik7CisgICAgb25DaGFuZ2VkKCk7CisgICAgaW5jcmVtZW50TW9kQ291bnRzKCk7CisgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0QnVpbGRlcigpOworICB9CisKKyAgLyoqCisgICAqIEluc2VydHMgYSBuZXcgYnVpbGRlciBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIGluIHRoaXMgbGlzdC4KKyAgICogU2hpZnRzIHRoZSBlbGVtZW50IGN1cnJlbnRseSBhdCB0aGF0IHBvc2l0aW9uIChpZiBhbnkpIGFuZCBhbnkgc3Vic2VxdWVudAorICAgKiBlbGVtZW50cyB0byB0aGUgcmlnaHQgKGFkZHMgb25lIHRvIHRoZWlyIGluZGljZXMpLgorICAgKgorICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydCB0aGUgYnVpbGRlcgorICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSB0byBhZGQgd2hpY2ggaXMgdGhlIGJhc2lzIG9mIHRoZSBidWlsZGVyCisgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICovCisgIHB1YmxpYyBCVHlwZSBhZGRCdWlsZGVyKGludCBpbmRleCwgTVR5cGUgbWVzc2FnZSkgeworICAgIGVuc3VyZU11dGFibGVNZXNzYWdlTGlzdCgpOworICAgIGVuc3VyZUJ1aWxkZXJzKCk7CisgICAgU2luZ2xlRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+IGJ1aWxkZXIgPQorICAgICAgICBuZXcgU2luZ2xlRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+KAorICAgICAgICAgICAgbWVzc2FnZSwgdGhpcywgaXNDbGVhbik7CisgICAgbWVzc2FnZXMuYWRkKGluZGV4LCBudWxsKTsKKyAgICBidWlsZGVycy5hZGQoaW5kZXgsIGJ1aWxkZXIpOworICAgIG9uQ2hhbmdlZCgpOworICAgIGluY3JlbWVudE1vZENvdW50cygpOworICAgIHJldHVybiBidWlsZGVyLmdldEJ1aWxkZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZW1vdmVzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyBsaXN0LiBTaGlmdHMgYW55CisgICAqIHN1YnNlcXVlbnQgZWxlbWVudHMgdG8gdGhlIGxlZnQgKHN1YnRyYWN0cyBvbmUgZnJvbSB0aGVpciBpbmRpY2VzKS4KKyAgICogUmV0dXJucyB0aGUgZWxlbWVudCB0aGF0IHdhcyByZW1vdmVkIGZyb20gdGhlIGxpc3QuCisgICAqCisgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggYXQgd2hpY2ggdG8gcmVtb3ZlIHRoZSBtZXNzYWdlCisgICAqLworICBwdWJsaWMgdm9pZCByZW1vdmUoaW50IGluZGV4KSB7CisgICAgZW5zdXJlTXV0YWJsZU1lc3NhZ2VMaXN0KCk7CisgICAgbWVzc2FnZXMucmVtb3ZlKGluZGV4KTsKKyAgICBpZiAoYnVpbGRlcnMgIT0gbnVsbCkgeworICAgICAgU2luZ2xlRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+IGVudHJ5ID0KKyAgICAgICAgICBidWlsZGVycy5yZW1vdmUoaW5kZXgpOworICAgICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgZW50cnkuZGlzcG9zZSgpOworICAgICAgfQorICAgIH0KKyAgICBvbkNoYW5nZWQoKTsKKyAgICBpbmNyZW1lbnRNb2RDb3VudHMoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZW1vdmVzIGFsbCBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIGxpc3QuCisgICAqIFRoZSBsaXN0IHdpbGwgYmUgZW1wdHkgYWZ0ZXIgdGhpcyBjYWxsIHJldHVybnMuCisgICAqLworICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICBtZXNzYWdlcyA9IENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworICAgIGlzTWVzc2FnZXNMaXN0TXV0YWJsZSA9IGZhbHNlOworICAgIGlmIChidWlsZGVycyAhPSBudWxsKSB7CisgICAgICBmb3IgKFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBlbnRyeSA6CisgICAgICAgICAgYnVpbGRlcnMpIHsKKyAgICAgICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICBlbnRyeS5kaXNwb3NlKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGJ1aWxkZXJzID0gbnVsbDsKKyAgICB9CisgICAgb25DaGFuZ2VkKCk7CisgICAgaW5jcmVtZW50TW9kQ291bnRzKCk7CisgIH0KKworICAvKioKKyAgICogQnVpbGRzIHRoZSBsaXN0IG9mIG1lc3NhZ2VzIGZyb20gdGhlIGJ1aWxkZXIgYW5kIHJldHVybnMgdGhlbS4KKyAgICoKKyAgICogQHJldHVybiBhbiBpbW11dGFibGUgbGlzdCBvZiBtZXNzYWdlcworICAgKi8KKyAgcHVibGljIExpc3Q8TVR5cGU+IGJ1aWxkKCkgeworICAgIC8vIE5vdyB0aGF0IGJ1aWxkIGhhcyBiZWVuIGNhbGxlZCwgd2UgYXJlIHJlcXVpcmVkIHRvIGRpc3BhdGNoCisgICAgLy8gaW52YWxpZGF0aW9ucy4KKyAgICBpc0NsZWFuID0gdHJ1ZTsKKworICAgIGlmICghaXNNZXNzYWdlc0xpc3RNdXRhYmxlICYmIGJ1aWxkZXJzID09IG51bGwpIHsKKyAgICAgIC8vIFdlIHN0aWxsIGhhdmUgYW4gaW1tdXRhYmxlIGxpc3QgYW5kIHdlIG5ldmVyIGNyZWF0ZWQgYSBidWlsZGVyLgorICAgICAgcmV0dXJuIG1lc3NhZ2VzOworICAgIH0KKworICAgIGJvb2xlYW4gYWxsTWVzc2FnZXNJblN5bmMgPSB0cnVlOworICAgIGlmICghaXNNZXNzYWdlc0xpc3RNdXRhYmxlKSB7CisgICAgICAvLyBXZSBzdGlsbCBoYXZlIGFuIGltbXV0YWJsZSBsaXN0LiBMZXQncyBzZWUgaWYgYW55IG9mIHRoZW0gYXJlIG91dAorICAgICAgLy8gb2Ygc3luYyB3aXRoIHRoZWlyIGJ1aWxkZXJzLgorICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlcy5zaXplKCk7IGkrKykgeworICAgICAgICBNZXNzYWdlIG1lc3NhZ2UgPSBtZXNzYWdlcy5nZXQoaSk7CisgICAgICAgIFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBidWlsZGVyID0gYnVpbGRlcnMuZ2V0KGkpOworICAgICAgICBpZiAoYnVpbGRlciAhPSBudWxsKSB7CisgICAgICAgICAgaWYgKGJ1aWxkZXIuYnVpbGQoKSAhPSBtZXNzYWdlKSB7CisgICAgICAgICAgICBhbGxNZXNzYWdlc0luU3luYyA9IGZhbHNlOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoYWxsTWVzc2FnZXNJblN5bmMpIHsKKyAgICAgICAgLy8gSW1tdXRhYmxlIGxpc3QgaXMgc3RpbGwgaW4gc3luYy4KKyAgICAgICAgcmV0dXJuIG1lc3NhZ2VzOworICAgICAgfQorICAgIH0KKworICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIG1lc3NhZ2VzIGlzIHVwIHRvIGRhdGUKKyAgICBlbnN1cmVNdXRhYmxlTWVzc2FnZUxpc3QoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VzLnNpemUoKTsgaSsrKSB7CisgICAgICBtZXNzYWdlcy5zZXQoaSwgZ2V0TWVzc2FnZShpLCB0cnVlKSk7CisgICAgfQorCisgICAgLy8gV2UncmUgZ29pbmcgdG8gcmV0dXJuIG91ciBsaXN0IGFzIGltbXV0YWJsZSBzbyB3ZSBtYXJrIHRoYXQgd2UgY2FuCisgICAgLy8gbm8gbG9uZ2VyIHVwZGF0ZSBpdC4KKyAgICBtZXNzYWdlcyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobWVzc2FnZXMpOworICAgIGlzTWVzc2FnZXNMaXN0TXV0YWJsZSA9IGZhbHNlOworICAgIHJldHVybiBtZXNzYWdlczsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIGEgdmlldyBvZiB0aGUgYnVpbGRlciBhcyBhIGxpc3Qgb2YgbWVzc2FnZXMuIFRoZSByZXR1cm5lZCBsaXN0IGlzIGxpdmUKKyAgICogYW5kIHdpbGwgcmVmbGVjdCBhbnkgY2hhbmdlcyB0byB0aGUgdW5kZXJseWluZyBidWlsZGVyLgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBtZXNzYWdlcyBpbiB0aGUgbGlzdAorICAgKi8KKyAgcHVibGljIExpc3Q8TVR5cGU+IGdldE1lc3NhZ2VMaXN0KCkgeworICAgIGlmIChleHRlcm5hbE1lc3NhZ2VMaXN0ID09IG51bGwpIHsKKyAgICAgIGV4dGVybmFsTWVzc2FnZUxpc3QgPQorICAgICAgICAgIG5ldyBNZXNzYWdlRXh0ZXJuYWxMaXN0PE1UeXBlLCBCVHlwZSwgSVR5cGU+KHRoaXMpOworICAgIH0KKyAgICByZXR1cm4gZXh0ZXJuYWxNZXNzYWdlTGlzdDsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIGEgdmlldyBvZiB0aGUgYnVpbGRlciBhcyBhIGxpc3Qgb2YgYnVpbGRlcnMuIFRoaXMgcmV0dXJuZWQgbGlzdCBpcworICAgKiBsaXZlIGFuZCB3aWxsIHJlZmxlY3QgYW55IGNoYW5nZXMgdG8gdGhlIHVuZGVybHlpbmcgYnVpbGRlci4KKyAgICoKKyAgICogQHJldHVybiB0aGUgYnVpbGRlcnMgaW4gdGhlIGxpc3QKKyAgICovCisgIHB1YmxpYyBMaXN0PEJUeXBlPiBnZXRCdWlsZGVyTGlzdCgpIHsKKyAgICBpZiAoZXh0ZXJuYWxCdWlsZGVyTGlzdCA9PSBudWxsKSB7CisgICAgICBleHRlcm5hbEJ1aWxkZXJMaXN0ID0KKyAgICAgICAgICBuZXcgQnVpbGRlckV4dGVybmFsTGlzdDxNVHlwZSwgQlR5cGUsIElUeXBlPih0aGlzKTsKKyAgICB9CisgICAgcmV0dXJuIGV4dGVybmFsQnVpbGRlckxpc3Q7CisgIH0KKworICAvKioKKyAgICogR2V0cyBhIHZpZXcgb2YgdGhlIGJ1aWxkZXIgYXMgYSBsaXN0IG9mIE1lc3NhZ2VPckJ1aWxkZXJzLiBUaGlzIHJldHVybmVkCisgICAqIGxpc3QgaXMgbGl2ZSBhbmQgd2lsbCByZWZsZWN0IGFueSBjaGFuZ2VzIHRvIHRoZSB1bmRlcmx5aW5nIGJ1aWxkZXIuCisgICAqCisgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXJzIGluIHRoZSBsaXN0CisgICAqLworICBwdWJsaWMgTGlzdDxJVHlwZT4gZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CisgICAgaWYgKGV4dGVybmFsTWVzc2FnZU9yQnVpbGRlckxpc3QgPT0gbnVsbCkgeworICAgICAgZXh0ZXJuYWxNZXNzYWdlT3JCdWlsZGVyTGlzdCA9CisgICAgICAgICAgbmV3IE1lc3NhZ2VPckJ1aWxkZXJFeHRlcm5hbExpc3Q8TVR5cGUsIEJUeXBlLCBJVHlwZT4odGhpcyk7CisgICAgfQorICAgIHJldHVybiBleHRlcm5hbE1lc3NhZ2VPckJ1aWxkZXJMaXN0OworICB9CisKKyAgLyoqCisgICAqIENhbGxlZCB3aGVuIGEgdGhlIGJ1aWxkZXIgb3Igb25lIG9mIGl0cyBuZXN0ZWQgY2hpbGRyZW4gaGFzIGNoYW5nZWQKKyAgICogYW5kIGFueSBwYXJlbnQgc2hvdWxkIGJlIG5vdGlmaWVkIG9mIGl0cyBpbnZhbGlkYXRpb24uCisgICAqLworICBwcml2YXRlIHZvaWQgb25DaGFuZ2VkKCkgeworICAgIGlmIChpc0NsZWFuICYmIHBhcmVudCAhPSBudWxsKSB7CisgICAgICBwYXJlbnQubWFya0RpcnR5KCk7CisKKyAgICAgIC8vIERvbid0IGtlZXAgZGlzcGF0Y2hpbmcgaW52YWxpZGF0aW9ucyB1bnRpbCBidWlsZCBpcyBjYWxsZWQgYWdhaW4uCisgICAgICBpc0NsZWFuID0gZmFsc2U7CisgICAgfQorICB9CisKKyAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgIHB1YmxpYyB2b2lkIG1hcmtEaXJ0eSgpIHsKKyAgICBvbkNoYW5nZWQoKTsKKyAgfQorCisgIC8qKgorICAgKiBJbmNyZW1lbnRzIHRoZSBtb2QgY291bnRzIHNvIHRoYXQgYW4gQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBjYW4KKyAgICogYmUgdGhyb3duIGlmIGNhbGxpbmcgY29kZSB0cmllcyB0byBtb2RpZnkgdGhlIGJ1aWxkZXIgd2hpbGUgaXRzIGl0ZXJhdGluZworICAgKiB0aGUgbGlzdC4KKyAgICovCisgIHByaXZhdGUgdm9pZCBpbmNyZW1lbnRNb2RDb3VudHMoKSB7CisgICAgaWYgKGV4dGVybmFsTWVzc2FnZUxpc3QgIT0gbnVsbCkgeworICAgICAgZXh0ZXJuYWxNZXNzYWdlTGlzdC5pbmNyZW1lbnRNb2RDb3VudCgpOworICAgIH0KKyAgICBpZiAoZXh0ZXJuYWxCdWlsZGVyTGlzdCAhPSBudWxsKSB7CisgICAgICBleHRlcm5hbEJ1aWxkZXJMaXN0LmluY3JlbWVudE1vZENvdW50KCk7CisgICAgfQorICAgIGlmIChleHRlcm5hbE1lc3NhZ2VPckJ1aWxkZXJMaXN0ICE9IG51bGwpIHsKKyAgICAgIGV4dGVybmFsTWVzc2FnZU9yQnVpbGRlckxpc3QuaW5jcmVtZW50TW9kQ291bnQoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUHJvdmlkZXMgYSBsaXZlIHZpZXcgb2YgdGhlIGJ1aWxkZXIgYXMgYSBsaXN0IG9mIG1lc3NhZ2VzLgorICAgKgorICAgKiBAcGFyYW0gPE1UeXBlPiB0aGUgdHlwZSBvZiBtZXNzYWdlIGZvciB0aGUgZmllbGQKKyAgICogQHBhcmFtIDxCVHlwZT4gdGhlIHR5cGUgb2YgYnVpbGRlciBmb3IgdGhlIGZpZWxkCisgICAqIEBwYXJhbSA8SVR5cGU+IHRoZSBjb21tb24gaW50ZXJmYWNlIGZvciB0aGUgbWVzc2FnZSBhbmQgdGhlIGJ1aWxkZXIKKyAgICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIE1lc3NhZ2VFeHRlcm5hbExpc3Q8CisgICAgICBNVHlwZSBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2UsCisgICAgICBCVHlwZSBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciwKKyAgICAgIElUeXBlIGV4dGVuZHMgTWVzc2FnZU9yQnVpbGRlcj4KKyAgICAgIGV4dGVuZHMgQWJzdHJhY3RMaXN0PE1UeXBlPiBpbXBsZW1lbnRzIExpc3Q8TVR5cGU+IHsKKworICAgIFJlcGVhdGVkRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+IGJ1aWxkZXI7CisKKyAgICBNZXNzYWdlRXh0ZXJuYWxMaXN0KAorICAgICAgICBSZXBlYXRlZEZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBidWlsZGVyKSB7CisgICAgICB0aGlzLmJ1aWxkZXIgPSBidWlsZGVyOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLmJ1aWxkZXIuZ2V0Q291bnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTVR5cGUgZ2V0KGludCBpbmRleCkgeworICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0TWVzc2FnZShpbmRleCk7CisgICAgfQorCisgICAgdm9pZCBpbmNyZW1lbnRNb2RDb3VudCgpIHsKKyAgICAgIG1vZENvdW50Kys7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFByb3ZpZGVzIGEgbGl2ZSB2aWV3IG9mIHRoZSBidWlsZGVyIGFzIGEgbGlzdCBvZiBidWlsZGVycy4KKyAgICoKKyAgICogQHBhcmFtIDxNVHlwZT4gdGhlIHR5cGUgb2YgbWVzc2FnZSBmb3IgdGhlIGZpZWxkCisgICAqIEBwYXJhbSA8QlR5cGU+IHRoZSB0eXBlIG9mIGJ1aWxkZXIgZm9yIHRoZSBmaWVsZAorICAgKiBAcGFyYW0gPElUeXBlPiB0aGUgY29tbW9uIGludGVyZmFjZSBmb3IgdGhlIG1lc3NhZ2UgYW5kIHRoZSBidWlsZGVyCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBCdWlsZGVyRXh0ZXJuYWxMaXN0PAorICAgICAgTVR5cGUgZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlLAorICAgICAgQlR5cGUgZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIsCisgICAgICBJVHlwZSBleHRlbmRzIE1lc3NhZ2VPckJ1aWxkZXI+CisgICAgICBleHRlbmRzIEFic3RyYWN0TGlzdDxCVHlwZT4gaW1wbGVtZW50cyBMaXN0PEJUeXBlPiB7CisKKyAgICBSZXBlYXRlZEZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBidWlsZGVyOworCisgICAgQnVpbGRlckV4dGVybmFsTGlzdCgKKyAgICAgICAgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gYnVpbGRlcikgeworICAgICAgdGhpcy5idWlsZGVyID0gYnVpbGRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICByZXR1cm4gdGhpcy5idWlsZGVyLmdldENvdW50KCk7CisgICAgfQorCisgICAgcHVibGljIEJUeXBlIGdldChpbnQgaW5kZXgpIHsKKyAgICAgIHJldHVybiBidWlsZGVyLmdldEJ1aWxkZXIoaW5kZXgpOworICAgIH0KKworICAgIHZvaWQgaW5jcmVtZW50TW9kQ291bnQoKSB7CisgICAgICBtb2RDb3VudCsrOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBQcm92aWRlcyBhIGxpdmUgdmlldyBvZiB0aGUgYnVpbGRlciBhcyBhIGxpc3Qgb2YgYnVpbGRlcnMuCisgICAqCisgICAqIEBwYXJhbSA8TVR5cGU+IHRoZSB0eXBlIG9mIG1lc3NhZ2UgZm9yIHRoZSBmaWVsZAorICAgKiBAcGFyYW0gPEJUeXBlPiB0aGUgdHlwZSBvZiBidWlsZGVyIGZvciB0aGUgZmllbGQKKyAgICogQHBhcmFtIDxJVHlwZT4gdGhlIGNvbW1vbiBpbnRlcmZhY2UgZm9yIHRoZSBtZXNzYWdlIGFuZCB0aGUgYnVpbGRlcgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTWVzc2FnZU9yQnVpbGRlckV4dGVybmFsTGlzdDwKKyAgICAgIE1UeXBlIGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZSwKKyAgICAgIEJUeXBlIGV4dGVuZHMgR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyLAorICAgICAgSVR5cGUgZXh0ZW5kcyBNZXNzYWdlT3JCdWlsZGVyPgorICAgICAgZXh0ZW5kcyBBYnN0cmFjdExpc3Q8SVR5cGU+IGltcGxlbWVudHMgTGlzdDxJVHlwZT4geworCisgICAgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gYnVpbGRlcjsKKworICAgIE1lc3NhZ2VPckJ1aWxkZXJFeHRlcm5hbExpc3QoCisgICAgICAgIFJlcGVhdGVkRmllbGRCdWlsZGVyPE1UeXBlLCBCVHlwZSwgSVR5cGU+IGJ1aWxkZXIpIHsKKyAgICAgIHRoaXMuYnVpbGRlciA9IGJ1aWxkZXI7CisgICAgfQorCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgcmV0dXJuIHRoaXMuYnVpbGRlci5nZXRDb3VudCgpOworICAgIH0KKworICAgIHB1YmxpYyBJVHlwZSBnZXQoaW50IGluZGV4KSB7CisgICAgICByZXR1cm4gYnVpbGRlci5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKKyAgICB9CisKKyAgICB2b2lkIGluY3JlbWVudE1vZENvdW50KCkgeworICAgICAgbW9kQ291bnQrKzsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JvcGVCeXRlU3RyaW5nLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Sb3BlQnl0ZVN0cmluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2OGJjY2UKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Sb3BlQnl0ZVN0cmluZy5qYXZhCkBAIC0wLDAgKzEsOTc3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW52YWxpZE9iamVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU3RhY2s7CisKKy8qKgorICogQ2xhc3MgdG8gcmVwcmVzZW50IHtAY29kZSBCeXRlU3RyaW5nc30gZm9ybWVkIGJ5IGNvbmNhdGVuYXRpb24gb2Ygb3RoZXIKKyAqIEJ5dGVTdHJpbmdzLCB3aXRob3V0IGNvcHlpbmcgdGhlIGRhdGEgaW4gdGhlIHBpZWNlcy4gVGhlIGNvbmNhdGVuYXRpb24gaXMKKyAqIHJlcHJlc2VudGVkIGFzIGEgdHJlZSB3aG9zZSBsZWFmIG5vZGVzIGFyZSBlYWNoIGEge0BsaW5rIExpdGVyYWxCeXRlU3RyaW5nfS4KKyAqCisgKiA8cD5Nb3N0IG9mIHRoZSBvcGVyYXRpb24gaGVyZSBpcyBpbnNwaXJlZCBieSB0aGUgbm93LWZhbW91cyBwYXBlciA8YQorICogaHJlZj0iaHR0cDovL3d3dy5jcy51YmMuY2EvbG9jYWwvcmVhZGluZy9wcm9jZWVkaW5ncy9zcGU5MS05NS9zcGUvdm9sMjUvaXNzdWUxMi9zcGU5ODYucGRmIj4KKyAqIEJBUDk1IDwvYT4gUm9wZXM6IGFuIEFsdGVybmF0aXZlIHRvIFN0cmluZ3MgaGFucy1qLiBib2VobSwgcnVzcyBhdGtpbnNvbiBhbmQKKyAqIG1pY2hhZWwgcGxhc3MKKyAqCisgKiA8cD5UaGUgYWxnb3JpdGhtcyBkZXNjcmliZWQgaW4gdGhlIHBhcGVyIGhhdmUgYmVlbiBpbXBsZW1lbnRlZCBmb3IgY2hhcmFjdGVyCisgKiBzdHJpbmdzIGluIHtAbGluayBjb20uZ29vZ2xlLmNvbW1vbi5zdHJpbmcuUm9wZX0gYW5kIGluIHRoZSBjKysgY2xhc3Mge0Bjb2RlCisgKiBjb3JkLmNjfS4KKyAqCisgKiA8cD5GdW5kYW1lbnRhbGx5IHRoZSBSb3BlIGFsZ29yaXRobSByZXByZXNlbnRzIHRoZSBjb2xsZWN0aW9uIG9mIHBpZWNlcyBhcyBhCisgKiBiaW5hcnkgdHJlZS4gQkFQOTUgdXNlcyBhIEZpYm9uYWNjaSBib3VuZCByZWxhdGluZyBkZXB0aCB0byBhIG1pbmltdW0KKyAqIHNlcXVlbmNlIGxlbmd0aCwgc2VxdWVuY2VzIHRoYXQgYXJlIHRvbyBzaG9ydCByZWxhdGl2ZSB0byB0aGVpciBkZXB0aCBjYXVzZSBhCisgKiB0cmVlIHJlYmFsYW5jZS4gIE1vcmUgcHJlY2lzZWx5LCBhIHRyZWUgb2YgZGVwdGggZCBpcyAiYmFsYW5jZWQiIGluIHRoZQorICogdGVybWlub2xvZ3kgb2YgQkFQOTUgaWYgaXRzIGxlbmd0aCBpcyBhdCBsZWFzdCBGKGQrMiksIHdoZXJlIEYobikgaXMgdGhlCisgKiBuLXRoZSBGaWJvbmFjY2kgbnVtYmVyLiBUaHVzIGZvciBkZXB0aHMgMCwgMSwgMiwgMywgNCwgNSwuLi4gd2UgaGF2ZSBtaW5pbXVtCisgKiBsZW5ndGhzIDEsIDIsIDMsIDUsIDgsIDEzLC4uLgorICoKKyAqIEBhdXRob3IgY2FybGFudG9uQGdvb2dsZS5jb20gKENhcmwgSGF2ZXJsKQorICovCitjbGFzcyBSb3BlQnl0ZVN0cmluZyBleHRlbmRzIEJ5dGVTdHJpbmcgeworCisgIC8qKgorICAgKiBCQVA5NS4gTGV0IEZuIGJlIHRoZSBudGggRmlib25hY2NpIG51bWJlci4gQSB7QGxpbmsgUm9wZUJ5dGVTdHJpbmd9IG9mCisgICAqIGRlcHRoIG4gaXMgImJhbGFuY2VkIiwgaS5lIGZsYXQgZW5vdWdoLCBpZiBpdHMgbGVuZ3RoIGlzIGF0IGxlYXN0IEZuKzIsCisgICAqIGUuZy4gYSAiYmFsYW5jZWQiIHtAbGluayBSb3BlQnl0ZVN0cmluZ30gb2YgZGVwdGggMSBtdXN0IGhhdmUgbGVuZ3RoIGF0CisgICAqIGxlYXN0IDIsIG9mIGRlcHRoIDQgbXVzdCBoYXZlIGxlbmd0aCA+PSA4LCBldGMuCisgICAqCisgICAqIDxwPlRoZXJlJ3Mgbm90aGluZyBzcGVjaWFsIGFib3V0IHVzaW5nIHRoZSBGaWJvbmFjY2kgbnVtYmVycyBmb3IgdGhpcywgYnV0CisgICAqIHRoZXkgYXJlIGEgcmVhc29uYWJsZSBzZXF1ZW5jZSBmb3IgZW5jYXBzdWxhdGluZyB0aGUgaWRlYSB0aGF0IHdlIGFyZSBPSworICAgKiB3aXRoIGxvbmdlciBzdHJpbmdzIGJlaW5nIGVuY29kZWQgaW4gZGVlcGVyIGJpbmFyeSB0cmVlcy4KKyAgICoKKyAgICogPHA+Rm9yIDMyLWJpdCBpbnRlZ2VycywgdGhpcyBhcnJheSBoYXMgbGVuZ3RoIDQ2LgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gbWluTGVuZ3RoQnlEZXB0aDsKKworICBzdGF0aWMgeworICAgIC8vIER5bmFtaWNhbGx5IGdlbmVyYXRlIHRoZSBsaXN0IG9mIEZpYm9uYWNjaSBudW1iZXJzIHRoZSBmaXJzdCB0aW1lIHRoaXMKKyAgICAvLyBjbGFzcyBpcyBhY2Nlc3NlZC4KKyAgICBMaXN0PEludGVnZXI+IG51bWJlcnMgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisKKyAgICAvLyB3ZSBza2lwIHRoZSBmaXJzdCBGaWJvbmFjY2kgbnVtYmVyICgxKS4gIFNvIGluc3RlYWQgb2Y6IDEgMSAyIDMgNSA4IC4uLgorICAgIC8vIHdlIGhhdmU6IDEgMiAzIDUgOCAuLi4KKyAgICBpbnQgZjEgPSAxOworICAgIGludCBmMiA9IDE7CisKKyAgICAvLyBnZXQgYWxsIHRoZSB2YWx1ZXMgdW50aWwgd2Ugcm9sbCBvdmVyLgorICAgIHdoaWxlIChmMiA+IDApIHsKKyAgICAgIG51bWJlcnMuYWRkKGYyKTsKKyAgICAgIGludCB0ZW1wID0gZjEgKyBmMjsKKyAgICAgIGYxID0gZjI7CisgICAgICBmMiA9IHRlbXA7CisgICAgfQorCisgICAgLy8gd2UgaW5jbHVkZSB0aGlzIGhlcmUgc28gdGhhdCB3ZSBjYW4gaW5kZXggdGhpcyBhcnJheSB0byBbeCArIDFdIGluIHRoZQorICAgIC8vIGxvb3BzIGJlbG93LgorICAgIG51bWJlcnMuYWRkKEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICBtaW5MZW5ndGhCeURlcHRoID0gbmV3IGludFtudW1iZXJzLnNpemUoKV07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtaW5MZW5ndGhCeURlcHRoLmxlbmd0aDsgaSsrKSB7CisgICAgICAvLyB1bmJveCBhbGwgdGhlIHZhbHVlcworICAgICAgbWluTGVuZ3RoQnlEZXB0aFtpXSA9IG51bWJlcnMuZ2V0KGkpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgZmluYWwgaW50IHRvdGFsTGVuZ3RoOworICBwcml2YXRlIGZpbmFsIEJ5dGVTdHJpbmcgbGVmdDsKKyAgcHJpdmF0ZSBmaW5hbCBCeXRlU3RyaW5nIHJpZ2h0OworICBwcml2YXRlIGZpbmFsIGludCBsZWZ0TGVuZ3RoOworICBwcml2YXRlIGZpbmFsIGludCB0cmVlRGVwdGg7CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyBSb3BlQnl0ZVN0cmluZywgd2hpY2ggY2FuIGJlIHRob3VnaHQgb2YgYXMgYSBuZXcgdHJlZSBub2RlLCBieQorICAgKiByZWNvcmRpbmcgcmVmZXJlbmNlcyB0byB0aGUgdHdvIGdpdmVuIHN0cmluZ3MuCisgICAqCisgICAqIEBwYXJhbSBsZWZ0ICBzdHJpbmcgb24gdGhlIGxlZnQgb2YgdGhpcyBub2RlLCBzaG91bGQgaGF2ZSB7QGNvZGUgc2l6ZSgpID4KKyAgICogICAgICAgICAgICAgIDB9CisgICAqIEBwYXJhbSByaWdodCBzdHJpbmcgb24gdGhlIHJpZ2h0IG9mIHRoaXMgbm9kZSwgc2hvdWxkIGhhdmUge0Bjb2RlIHNpemUoKSA+CisgICAqICAgICAgICAgICAgICAwfQorICAgKi8KKyAgcHJpdmF0ZSBSb3BlQnl0ZVN0cmluZyhCeXRlU3RyaW5nIGxlZnQsIEJ5dGVTdHJpbmcgcmlnaHQpIHsKKyAgICB0aGlzLmxlZnQgPSBsZWZ0OworICAgIHRoaXMucmlnaHQgPSByaWdodDsKKyAgICBsZWZ0TGVuZ3RoID0gbGVmdC5zaXplKCk7CisgICAgdG90YWxMZW5ndGggPSBsZWZ0TGVuZ3RoICsgcmlnaHQuc2l6ZSgpOworICAgIHRyZWVEZXB0aCA9IE1hdGgubWF4KGxlZnQuZ2V0VHJlZURlcHRoKCksIHJpZ2h0LmdldFRyZWVEZXB0aCgpKSArIDE7CisgIH0KKworICAvKioKKyAgICogQ29uY2F0ZW5hdGUgdGhlIGdpdmVuIHN0cmluZ3Mgd2hpbGUgcGVyZm9ybWluZyB2YXJpb3VzIG9wdGltaXphdGlvbnMgdG8KKyAgICogc2xvdyB0aGUgZ3Jvd3RoIHJhdGUgb2YgdHJlZSBkZXB0aCBhbmQgdHJlZSBub2RlIGNvdW50LiBUaGUgcmVzdWx0IGlzCisgICAqIGVpdGhlciBhIHtAbGluayBMaXRlcmFsQnl0ZVN0cmluZ30gb3IgYSB7QGxpbmsgUm9wZUJ5dGVTdHJpbmd9CisgICAqIGRlcGVuZGluZyBvbiB3aGljaCBvcHRpbWl6YXRpb25zLCBpZiBhbnksIHdlcmUgYXBwbGllZC4KKyAgICoKKyAgICogPHA+U21hbGwgcGllY2VzIG9mIGxlbmd0aCBsZXNzIHRoYW4ge0BsaW5rCisgICAqIEJ5dGVTdHJpbmcjQ09OQ0FURU5BVEVfQllfQ09QWV9TSVpFfSBtYXkgYmUgY29waWVkIGJ5IHZhbHVlIGhlcmUsIGFzIGluCisgICAqIEJBUDk1LiAgTGFyZ2UgcGllY2VzIGFyZSByZWZlcmVuY2VkIHdpdGhvdXQgY29weS4KKyAgICoKKyAgICogQHBhcmFtIGxlZnQgIHN0cmluZyBvbiB0aGUgbGVmdAorICAgKiBAcGFyYW0gcmlnaHQgc3RyaW5nIG9uIHRoZSByaWdodAorICAgKiBAcmV0dXJuIGNvbmNhdGVuYXRpb24gcmVwcmVzZW50aW5nIHRoZSBzYW1lIHNlcXVlbmNlIGFzIHRoZSBnaXZlbiBzdHJpbmdzCisgICAqLworICBzdGF0aWMgQnl0ZVN0cmluZyBjb25jYXRlbmF0ZShCeXRlU3RyaW5nIGxlZnQsIEJ5dGVTdHJpbmcgcmlnaHQpIHsKKyAgICBCeXRlU3RyaW5nIHJlc3VsdDsKKyAgICBSb3BlQnl0ZVN0cmluZyBsZWZ0Um9wZSA9CisgICAgICAgIChsZWZ0IGluc3RhbmNlb2YgUm9wZUJ5dGVTdHJpbmcpID8gKFJvcGVCeXRlU3RyaW5nKSBsZWZ0IDogbnVsbDsKKyAgICBpZiAocmlnaHQuc2l6ZSgpID09IDApIHsKKyAgICAgIHJlc3VsdCA9IGxlZnQ7CisgICAgfSBlbHNlIGlmIChsZWZ0LnNpemUoKSA9PSAwKSB7CisgICAgICByZXN1bHQgPSByaWdodDsKKyAgICB9IGVsc2UgeworICAgICAgaW50IG5ld0xlbmd0aCA9IGxlZnQuc2l6ZSgpICsgcmlnaHQuc2l6ZSgpOworICAgICAgaWYgKG5ld0xlbmd0aCA8IEJ5dGVTdHJpbmcuQ09OQ0FURU5BVEVfQllfQ09QWV9TSVpFKSB7CisgICAgICAgIC8vIE9wdGltaXphdGlvbiBmcm9tIEJBUDk1OiBGb3Igc2hvcnQgKGxlYXZlcyBpbiBwYXBlciwgYnV0IGp1c3Qgc2hvcnQKKyAgICAgICAgLy8gaGVyZSkgdG90YWwgbGVuZ3RoLCBkbyBhIGNvcHkgb2YgZGF0YSB0byBhIG5ldyBsZWFmLgorICAgICAgICByZXN1bHQgPSBjb25jYXRlbmF0ZUJ5dGVzKGxlZnQsIHJpZ2h0KTsKKyAgICAgIH0gZWxzZSBpZiAobGVmdFJvcGUgIT0gbnVsbAorICAgICAgICAgICYmIGxlZnRSb3BlLnJpZ2h0LnNpemUoKSArIHJpZ2h0LnNpemUoKSA8IENPTkNBVEVOQVRFX0JZX0NPUFlfU0laRSkgeworICAgICAgICAvLyBPcHRpbWl6YXRpb24gZnJvbSBCQVA5NTogQXMgYW4gb3B0aW1pemF0aW9uIG9mIHRoZSBjYXNlIHdoZXJlIHRoZQorICAgICAgICAvLyBCeXRlU3RyaW5nIGlzIGNvbnN0cnVjdGVkIGJ5IHJlcGVhdGVkIGNvbmNhdGVuYXRlLCByZWNvZ25pemUgdGhlIGNhc2UKKyAgICAgICAgLy8gd2hlcmUgYSBzaG9ydCBzdHJpbmcgaXMgY29uY2F0ZW5hdGVkIHRvIGEgbGVmdC1oYW5kIG5vZGUgd2hvc2UKKyAgICAgICAgLy8gcmlnaHQtaGFuZCBicmFuY2ggaXMgc2hvcnQuICBJbiB0aGUgcGFwZXIgdGhpcyBhcHBsaWVzIHRvIGxlYXZlcywgYnV0CisgICAgICAgIC8vIHdlIGp1c3QgbG9vayBhdCB0aGUgbGVuZ3RoIGhlcmUuIFRoaXMgaGFzIHRoZSBhZHZhbnRhZ2Ugb2Ygc2hlZGRpbmcKKyAgICAgICAgLy8gcmVmZXJlbmNlcyB0byB1bm5lZWRlZCBkYXRhIHdoZW4gc3Vic3RyaW5ncyBoYXZlIGJlZW4gdGFrZW4uCisgICAgICAgIC8vCisgICAgICAgIC8vIFdoZW4gd2UgcmVjb2duaXplIHRoaXMgY2FzZSwgd2UgZG8gYSBjb3B5IG9mIHRoZSBkYXRhIGFuZCBjcmVhdGUgYQorICAgICAgICAvLyBuZXcgcGFyZW50IG5vZGUgc28gdGhhdCB0aGUgZGVwdGggb2YgdGhlIHJlc3VsdCBpcyB0aGUgc2FtZSBhcyB0aGUKKyAgICAgICAgLy8gZ2l2ZW4gbGVmdCB0cmVlLgorICAgICAgICBCeXRlU3RyaW5nIG5ld1JpZ2h0ID0gY29uY2F0ZW5hdGVCeXRlcyhsZWZ0Um9wZS5yaWdodCwgcmlnaHQpOworICAgICAgICByZXN1bHQgPSBuZXcgUm9wZUJ5dGVTdHJpbmcobGVmdFJvcGUubGVmdCwgbmV3UmlnaHQpOworICAgICAgfSBlbHNlIGlmIChsZWZ0Um9wZSAhPSBudWxsCisgICAgICAgICAgJiYgbGVmdFJvcGUubGVmdC5nZXRUcmVlRGVwdGgoKSA+IGxlZnRSb3BlLnJpZ2h0LmdldFRyZWVEZXB0aCgpCisgICAgICAgICAgJiYgbGVmdFJvcGUuZ2V0VHJlZURlcHRoKCkgPiByaWdodC5nZXRUcmVlRGVwdGgoKSkgeworICAgICAgICAvLyBUeXBpY2FsbHkgZm9yIGNvbmNhdGVuYXRlLWJ1aWx0IHN0cmluZ3MgdGhlIGxlZnQtc2lkZSBpcyBkZWVwZXIgdGhhbgorICAgICAgICAvLyB0aGUgcmlnaHQuICBUaGlzIGlzIG91ciBmaW5hbCBhdHRlbXB0IHRvIGNvbmNhdGVuYXRlIHdpdGhvdXQKKyAgICAgICAgLy8gaW5jcmVhc2luZyB0aGUgdHJlZSBkZXB0aC4gIFdlJ2xsIHJlZG8gdGhlIHRoZSBub2RlIG9uIHRoZSBSSFMuICBUaGlzCisgICAgICAgIC8vIGlzIHlldCBhbm90aGVyIG9wdGltaXphdGlvbiBmb3IgYnVpbGRpbmcgdGhlIHN0cmluZyBieSByZXBlYXRlZGx5CisgICAgICAgIC8vIGNvbmNhdGVuYXRpbmcgb24gdGhlIHJpZ2h0LgorICAgICAgICBCeXRlU3RyaW5nIG5ld1JpZ2h0ID0gbmV3IFJvcGVCeXRlU3RyaW5nKGxlZnRSb3BlLnJpZ2h0LCByaWdodCk7CisgICAgICAgIHJlc3VsdCA9IG5ldyBSb3BlQnl0ZVN0cmluZyhsZWZ0Um9wZS5sZWZ0LCBuZXdSaWdodCk7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBGaW5lLCB3ZSdsbCBhZGQgYSBub2RlIGFuZCBpbmNyZWFzZSB0aGUgdHJlZSBkZXB0aC0tdW5sZXNzIHdlCisgICAgICAgIC8vIHJlYmFsYW5jZSA7XikKKyAgICAgICAgaW50IG5ld0RlcHRoID0gTWF0aC5tYXgobGVmdC5nZXRUcmVlRGVwdGgoKSwgcmlnaHQuZ2V0VHJlZURlcHRoKCkpICsgMTsKKyAgICAgICAgaWYgKG5ld0xlbmd0aCA+PSBtaW5MZW5ndGhCeURlcHRoW25ld0RlcHRoXSkgeworICAgICAgICAgIC8vIFRoZSB0cmVlIGlzIHNoYWxsb3cgZW5vdWdoLCBzbyBkb24ndCByZWJhbGFuY2UKKyAgICAgICAgICByZXN1bHQgPSBuZXcgUm9wZUJ5dGVTdHJpbmcobGVmdCwgcmlnaHQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdCA9IG5ldyBCYWxhbmNlcigpLmJhbGFuY2UobGVmdCwgcmlnaHQpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQ29uY2F0ZW5hdGVzIHR3byBzdHJpbmdzIGJ5IGNvcHlpbmcgZGF0YSB2YWx1ZXMuIFRoaXMgaXMgY2FsbGVkIGluIGEgZmV3CisgICAqIGNhc2VzIGluIG9yZGVyIHRvIHJlZHVjZSB0aGUgZ3Jvd3RoIG9mIHRoZSBudW1iZXIgb2YgdHJlZSBub2Rlcy4KKyAgICoKKyAgICogQHBhcmFtIGxlZnQgIHN0cmluZyBvbiB0aGUgbGVmdAorICAgKiBAcGFyYW0gcmlnaHQgc3RyaW5nIG9uIHRoZSByaWdodAorICAgKiBAcmV0dXJuIHN0cmluZyBmb3JtZWQgYnkgY29weWluZyBkYXRhIGJ5dGVzCisgICAqLworICBwcml2YXRlIHN0YXRpYyBMaXRlcmFsQnl0ZVN0cmluZyBjb25jYXRlbmF0ZUJ5dGVzKEJ5dGVTdHJpbmcgbGVmdCwKKyAgICAgIEJ5dGVTdHJpbmcgcmlnaHQpIHsKKyAgICBpbnQgbGVmdFNpemUgPSBsZWZ0LnNpemUoKTsKKyAgICBpbnQgcmlnaHRTaXplID0gcmlnaHQuc2l6ZSgpOworICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW2xlZnRTaXplICsgcmlnaHRTaXplXTsKKyAgICBsZWZ0LmNvcHlUbyhieXRlcywgMCwgMCwgbGVmdFNpemUpOworICAgIHJpZ2h0LmNvcHlUbyhieXRlcywgMCwgbGVmdFNpemUsIHJpZ2h0U2l6ZSk7CisgICAgcmV0dXJuIG5ldyBMaXRlcmFsQnl0ZVN0cmluZyhieXRlcyk7ICAvLyBDb25zdHJ1Y3RvciB3cmFwcyBieXRlcworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyBSb3BlQnl0ZVN0cmluZyBmb3IgdGVzdGluZyBvbmx5IHdoaWxlIGJ5cGFzc2luZyBhbGwgdGhlCisgICAqIGRlZmVuc2VzIG9mIHtAbGluayAjY29uY2F0ZW5hdGUoQnl0ZVN0cmluZywgQnl0ZVN0cmluZyl9LiBUaGlzIGFsbG93cworICAgKiB0ZXN0aW5nIHRyZWVzIG9mIHNwZWNpZmljIHN0cnVjdHVyZS4gV2UgYXJlIGFsc28gYWJsZSB0byBpbnNlcnQgZW1wdHkKKyAgICogbGVhdmVzLCB0aG91Z2ggdGhlc2UgYXJlIGRpcy1hbGxvd2VkLCBzbyB0aGF0IHdlIGNhbiBtYWtlIHN1cmUgdGhlCisgICAqIGltcGxlbWVudGF0aW9uIGNhbiB3aXRoc3RhbmQgdGhlaXIgcHJlc2VuY2UuCisgICAqCisgICAqIEBwYXJhbSBsZWZ0ICBzdHJpbmcgb24gdGhlIGxlZnQgb2YgdGhpcyBub2RlCisgICAqIEBwYXJhbSByaWdodCBzdHJpbmcgb24gdGhlIHJpZ2h0IG9mIHRoaXMgbm9kZQorICAgKiBAcmV0dXJuIGFuIHVuc2FmZSBpbnN0YW5jZSBmb3IgdGVzdGluZyBvbmx5CisgICAqLworICBzdGF0aWMgUm9wZUJ5dGVTdHJpbmcgbmV3SW5zdGFuY2VGb3JUZXN0KEJ5dGVTdHJpbmcgbGVmdCwgQnl0ZVN0cmluZyByaWdodCkgeworICAgIHJldHVybiBuZXcgUm9wZUJ5dGVTdHJpbmcobGVmdCwgcmlnaHQpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgdGhlIGJ5dGUgYXQgdGhlIGdpdmVuIGluZGV4LgorICAgKiBUaHJvd3Mge0BsaW5rIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbn0gZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5CisgICAqIHJlYXNvbnMgYWx0aG91Z2ggaXQgd291bGQgbW9yZSBwcm9wZXJseSBiZSB7QGxpbmsKKyAgICogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbn0uCisgICAqCisgICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiBieXRlCisgICAqIEByZXR1cm4gdGhlIHZhbHVlCisgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHtAY29kZSBpbmRleH0gaXMgPCAwIG9yID49IHNpemUKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgYnl0ZSBieXRlQXQoaW50IGluZGV4KSB7CisgICAgaWYgKGluZGV4IDwgMCkgeworICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiSW5kZXggPCAwOiAiICsgaW5kZXgpOworICAgIH0KKyAgICBpZiAoaW5kZXggPiB0b3RhbExlbmd0aCkgeworICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigKKyAgICAgICAgICAiSW5kZXggPiBsZW5ndGg6ICIgKyBpbmRleCArICIsICIgKyB0b3RhbExlbmd0aCk7CisgICAgfQorCisgICAgYnl0ZSByZXN1bHQ7CisgICAgLy8gRmluZCB0aGUgcmVsZXZhbnQgcGllY2UgYnkgcmVjdXJzaXZlIGRlc2NlbnQKKyAgICBpZiAoaW5kZXggPCBsZWZ0TGVuZ3RoKSB7CisgICAgICByZXN1bHQgPSBsZWZ0LmJ5dGVBdChpbmRleCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdCA9IHJpZ2h0LmJ5dGVBdChpbmRleCAtIGxlZnRMZW5ndGgpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gdG90YWxMZW5ndGg7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBQaWVjZXMKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIGludCBnZXRUcmVlRGVwdGgoKSB7CisgICAgcmV0dXJuIHRyZWVEZXB0aDsKKyAgfQorCisgIC8qKgorICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB0cmVlIGlzIGJhbGFuY2VkIGFjY29yZGluZyB0byBCQVA5NSwgd2hpY2ggbWVhbnMgdGhlIHRyZWUKKyAgICogaXMgZmxhdC1lbm91Z2ggd2l0aCByZXNwZWN0IHRvIHRoZSBib3VuZHMuIE5vdGUgdGhhdCB0aGlzIGRlZmluaXRpb24gb2YKKyAgICogYmFsYW5jZWQgaXMgb25lIHdoZXJlIHN1Yi10cmVlcyBvZiBiYWxhbmNlZCB0cmVlcyBhcmUgbm90IG5lY2Vzc2FyaWx5CisgICAqIGJhbGFuY2VkLgorICAgKgorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRyZWUgaXMgYmFsYW5jZWQKKyAgICovCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0JhbGFuY2VkKCkgeworICAgIHJldHVybiB0b3RhbExlbmd0aCA+PSBtaW5MZW5ndGhCeURlcHRoW3RyZWVEZXB0aF07CisgIH0KKworICAvKioKKyAgICogVGFrZXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBvbmUuIFRoaXMgaW52b2x2ZXMgcmVjdXJzaXZlIGRlc2NlbnQgYWxvbmcgdGhlCisgICAqIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzIG9mIHRoZSBzdWJzdHJpbmcsIGFuZCByZWZlcmVuY2luZyBhbnkgd2hvbGx5IGNvbnRhaW5lZAorICAgKiBzZWdtZW50cyBpbiBiZXR3ZWVuLiBBbnkgbGVhZiBub2RlcyBlbnRpcmVseSB1bmludm9sdmVkIGluIHRoZSBzdWJzdHJpbmcKKyAgICogd2lsbCBub3QgYmUgcmVmZXJlbmNlZCBieSB0aGUgc3Vic3RyaW5nLgorICAgKgorICAgKiA8cD5TdWJzdHJpbmdzIG9mIHtAY29kZSBsZW5ndGggPCAyfSBzaG91bGQgcmVzdWx0IGluIGF0IG1vc3QgYSBzaW5nbGUKKyAgICogcmVjdXJzaXZlIGNhbGwgY2hhaW4sIHRlcm1pbmF0aW5nIGF0IGEgbGVhZiBub2RlLiBUaHVzIHRoZSByZXN1bHQgd2lsbCBiZSBhCisgICAqIHtAbGluayBMaXRlcmFsQnl0ZVN0cmluZ30uIHtAbGluayAjUm9wZUJ5dGVTdHJpbmcoQnl0ZVN0cmluZywKKyAgICogQnl0ZVN0cmluZyl9LgorICAgKgorICAgKiBAcGFyYW0gYmVnaW5JbmRleCBzdGFydCBhdCB0aGlzIGluZGV4CisgICAqIEBwYXJhbSBlbmRJbmRleCAgIHRoZSBsYXN0IGNoYXJhY3RlciBpcyB0aGUgb25lIGJlZm9yZSB0aGlzIGluZGV4CisgICAqIEByZXR1cm4gc3Vic3RyaW5nIGxlYWYgbm9kZSBvciB0cmVlCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIEJ5dGVTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpIHsKKyAgICBpZiAoYmVnaW5JbmRleCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKAorICAgICAgICAgICJCZWdpbm5pbmcgaW5kZXg6ICIgKyBiZWdpbkluZGV4ICsgIiA8IDAiKTsKKyAgICB9CisgICAgaWYgKGVuZEluZGV4ID4gdG90YWxMZW5ndGgpIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKAorICAgICAgICAgICJFbmQgaW5kZXg6ICIgKyBlbmRJbmRleCArICIgPiAiICsgdG90YWxMZW5ndGgpOworICAgIH0KKyAgICBpbnQgc3Vic3RyaW5nTGVuZ3RoID0gZW5kSW5kZXggLSBiZWdpbkluZGV4OworICAgIGlmIChzdWJzdHJpbmdMZW5ndGggPCAwKSB7CisgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigKKyAgICAgICAgICAiQmVnaW5uaW5nIGluZGV4IGxhcmdlciB0aGFuIGVuZGluZyBpbmRleDogIiArIGJlZ2luSW5kZXggKyAiLCAiCisgICAgICAgICAgICAgICsgZW5kSW5kZXgpOworICAgIH0KKworICAgIEJ5dGVTdHJpbmcgcmVzdWx0OworICAgIGlmIChzdWJzdHJpbmdMZW5ndGggPT0gMCkgeworICAgICAgLy8gRW1wdHkgc3Vic3RyaW5nCisgICAgICByZXN1bHQgPSBCeXRlU3RyaW5nLkVNUFRZOworICAgIH0gZWxzZSBpZiAoc3Vic3RyaW5nTGVuZ3RoID09IHRvdGFsTGVuZ3RoKSB7CisgICAgICAvLyBUaGUgd2hvbGUgc3RyaW5nCisgICAgICByZXN1bHQgPSB0aGlzOworICAgIH0gZWxzZSB7CisgICAgICAvLyBQcm9wZXIgc3Vic3RyaW5nCisgICAgICBpZiAoZW5kSW5kZXggPD0gbGVmdExlbmd0aCkgeworICAgICAgICAvLyBTdWJzdHJpbmcgb24gdGhlIGxlZnQKKyAgICAgICAgcmVzdWx0ID0gbGVmdC5zdWJzdHJpbmcoYmVnaW5JbmRleCwgZW5kSW5kZXgpOworICAgICAgfSBlbHNlIGlmIChiZWdpbkluZGV4ID49IGxlZnRMZW5ndGgpIHsKKyAgICAgICAgLy8gU3Vic3RyaW5nIG9uIHRoZSByaWdodAorICAgICAgICByZXN1bHQgPSByaWdodAorICAgICAgICAgICAgLnN1YnN0cmluZyhiZWdpbkluZGV4IC0gbGVmdExlbmd0aCwgZW5kSW5kZXggLSBsZWZ0TGVuZ3RoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFNwbGl0IHN1YnN0cmluZworICAgICAgICBCeXRlU3RyaW5nIGxlZnRTdWIgPSBsZWZ0LnN1YnN0cmluZyhiZWdpbkluZGV4KTsKKyAgICAgICAgQnl0ZVN0cmluZyByaWdodFN1YiA9IHJpZ2h0LnN1YnN0cmluZygwLCBlbmRJbmRleCAtIGxlZnRMZW5ndGgpOworICAgICAgICAvLyBJbnRlbnRpb25hbGx5IG5vdCByZWJhbGFuY2luZywgc2luY2UgaW4gbWFueSBjYXNlcyB0aGVzZSB0d28KKyAgICAgICAgLy8gc3Vic3RyaW5ncyB3aWxsIGFscmVhZHkgYmUgbGVzcyBkZWVwIHRoYW4gdGhlIHRvcC1sZXZlbAorICAgICAgICAvLyBSb3BlQnl0ZVN0cmluZyB3ZSdyZSB0YWtpbmcgYSBzdWJzdHJpbmcgb2YuCisgICAgICAgIHJlc3VsdCA9IG5ldyBSb3BlQnl0ZVN0cmluZyhsZWZ0U3ViLCByaWdodFN1Yik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBCeXRlU3RyaW5nIC0+IGJ5dGVbXQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBjb3B5VG9JbnRlcm5hbChieXRlW10gdGFyZ2V0LCBpbnQgc291cmNlT2Zmc2V0LAorICAgICAgaW50IHRhcmdldE9mZnNldCwgaW50IG51bWJlclRvQ29weSkgeworICAgaWYgKHNvdXJjZU9mZnNldCArIG51bWJlclRvQ29weSA8PSBsZWZ0TGVuZ3RoKSB7CisgICAgICBsZWZ0LmNvcHlUb0ludGVybmFsKHRhcmdldCwgc291cmNlT2Zmc2V0LCB0YXJnZXRPZmZzZXQsIG51bWJlclRvQ29weSk7CisgICAgfSBlbHNlIGlmIChzb3VyY2VPZmZzZXQgPj0gbGVmdExlbmd0aCkgeworICAgICAgcmlnaHQuY29weVRvSW50ZXJuYWwodGFyZ2V0LCBzb3VyY2VPZmZzZXQgLSBsZWZ0TGVuZ3RoLCB0YXJnZXRPZmZzZXQsCisgICAgICAgICAgbnVtYmVyVG9Db3B5KTsKKyAgICB9IGVsc2UgeworICAgICAgaW50IGxlZnRMZW5ndGggPSB0aGlzLmxlZnRMZW5ndGggLSBzb3VyY2VPZmZzZXQ7CisgICAgICBsZWZ0LmNvcHlUb0ludGVybmFsKHRhcmdldCwgc291cmNlT2Zmc2V0LCB0YXJnZXRPZmZzZXQsIGxlZnRMZW5ndGgpOworICAgICAgcmlnaHQuY29weVRvSW50ZXJuYWwodGFyZ2V0LCAwLCB0YXJnZXRPZmZzZXQgKyBsZWZ0TGVuZ3RoLAorICAgICAgICAgIG51bWJlclRvQ29weSAtIGxlZnRMZW5ndGgpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjb3B5VG8oQnl0ZUJ1ZmZlciB0YXJnZXQpIHsKKyAgICBsZWZ0LmNvcHlUbyh0YXJnZXQpOworICAgIHJpZ2h0LmNvcHlUbyh0YXJnZXQpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBCeXRlQnVmZmVyIGFzUmVhZE9ubHlCeXRlQnVmZmVyKCkgeworICAgIEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlciA9IEJ5dGVCdWZmZXIud3JhcCh0b0J5dGVBcnJheSgpKTsKKyAgICByZXR1cm4gYnl0ZUJ1ZmZlci5hc1JlYWRPbmx5QnVmZmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3Q8Qnl0ZUJ1ZmZlcj4gYXNSZWFkT25seUJ5dGVCdWZmZXJMaXN0KCkgeworICAgIC8vIFdhbGsgdGhyb3VnaCB0aGUgbGlzdCBvZiBMaXRlcmFsQnl0ZVN0cmluZydzIHRoYXQgbWFrZSB1cCB0aGlzCisgICAgLy8gcm9wZSwgYW5kIGFkZCBlYWNoIG9uZSBhcyBhIHJlYWQtb25seSBCeXRlQnVmZmVyLgorICAgIExpc3Q8Qnl0ZUJ1ZmZlcj4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxCeXRlQnVmZmVyPigpOworICAgIFBpZWNlSXRlcmF0b3IgcGllY2VzID0gbmV3IFBpZWNlSXRlcmF0b3IodGhpcyk7CisgICAgd2hpbGUgKHBpZWNlcy5oYXNOZXh0KCkpIHsKKyAgICAgIExpdGVyYWxCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBwaWVjZXMubmV4dCgpOworICAgICAgcmVzdWx0LmFkZChieXRlU3RyaW5nLmFzUmVhZE9ubHlCeXRlQnVmZmVyKCkpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsZWZ0LndyaXRlVG8ob3V0cHV0U3RyZWFtKTsKKyAgICByaWdodC53cml0ZVRvKG91dHB1dFN0cmVhbSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgdm9pZCB3cml0ZVRvSW50ZXJuYWwoT3V0cHV0U3RyZWFtIG91dCwgaW50IHNvdXJjZU9mZnNldCwKKyAgICAgIGludCBudW1iZXJUb1dyaXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChzb3VyY2VPZmZzZXQgKyBudW1iZXJUb1dyaXRlIDw9IGxlZnRMZW5ndGgpIHsKKyAgICAgIGxlZnQud3JpdGVUb0ludGVybmFsKG91dCwgc291cmNlT2Zmc2V0LCBudW1iZXJUb1dyaXRlKTsKKyAgICB9IGVsc2UgaWYgKHNvdXJjZU9mZnNldCA+PSBsZWZ0TGVuZ3RoKSB7CisgICAgICByaWdodC53cml0ZVRvSW50ZXJuYWwob3V0LCBzb3VyY2VPZmZzZXQgLSBsZWZ0TGVuZ3RoLCBudW1iZXJUb1dyaXRlKTsKKyAgICB9IGVsc2UgeworICAgICAgaW50IG51bWJlclRvV3JpdGVJbkxlZnQgPSBsZWZ0TGVuZ3RoIC0gc291cmNlT2Zmc2V0OworICAgICAgbGVmdC53cml0ZVRvSW50ZXJuYWwob3V0LCBzb3VyY2VPZmZzZXQsIG51bWJlclRvV3JpdGVJbkxlZnQpOworICAgICAgcmlnaHQud3JpdGVUb0ludGVybmFsKG91dCwgMCwgbnVtYmVyVG9Xcml0ZSAtIG51bWJlclRvV3JpdGVJbkxlZnQpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKFN0cmluZyBjaGFyc2V0TmFtZSkKKyAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAvLyBPcHRpbWl6ZSBmb3IgZW1wdHkgc3RyaW5ncywgYnV0IGVuc3VyZSB3ZSBkb24ndCBzaWxlbnRseSBpZ25vcmUgaW52YWxpZAorICAgIC8vIGVuY29kaW5ncy4KKyAgICByZXR1cm4gc2l6ZSgpID09IDAgJiYgVVRGXzguZXF1YWxzKGNoYXJzZXROYW1lKQorICAgICAgICA/ICIiCisgICAgICAgIDogbmV3IFN0cmluZyh0b0J5dGVBcnJheSgpLCBjaGFyc2V0TmFtZSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBVVEYtOCBkZWNvZGluZworCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkVXRmOCgpIHsKKyAgICBpbnQgbGVmdFBhcnRpYWwgPSBsZWZ0LnBhcnRpYWxJc1ZhbGlkVXRmOChVdGY4LkNPTVBMRVRFLCAwLCBsZWZ0TGVuZ3RoKTsKKyAgICBpbnQgc3RhdGUgPSByaWdodC5wYXJ0aWFsSXNWYWxpZFV0ZjgobGVmdFBhcnRpYWwsIDAsIHJpZ2h0LnNpemUoKSk7CisgICAgcmV0dXJuIHN0YXRlID09IFV0ZjguQ09NUExFVEU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIGludCBwYXJ0aWFsSXNWYWxpZFV0ZjgoaW50IHN0YXRlLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgaW50IHRvSW5kZXggPSBvZmZzZXQgKyBsZW5ndGg7CisgICAgaWYgKHRvSW5kZXggPD0gbGVmdExlbmd0aCkgeworICAgICAgcmV0dXJuIGxlZnQucGFydGlhbElzVmFsaWRVdGY4KHN0YXRlLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfSBlbHNlIGlmIChvZmZzZXQgPj0gbGVmdExlbmd0aCkgeworICAgICAgcmV0dXJuIHJpZ2h0LnBhcnRpYWxJc1ZhbGlkVXRmOChzdGF0ZSwgb2Zmc2V0IC0gbGVmdExlbmd0aCwgbGVuZ3RoKTsKKyAgICB9IGVsc2UgeworICAgICAgaW50IGxlZnRMZW5ndGggPSB0aGlzLmxlZnRMZW5ndGggLSBvZmZzZXQ7CisgICAgICBpbnQgbGVmdFBhcnRpYWwgPSBsZWZ0LnBhcnRpYWxJc1ZhbGlkVXRmOChzdGF0ZSwgb2Zmc2V0LCBsZWZ0TGVuZ3RoKTsKKyAgICAgIHJldHVybiByaWdodC5wYXJ0aWFsSXNWYWxpZFV0ZjgobGVmdFBhcnRpYWwsIDAsIGxlbmd0aCAtIGxlZnRMZW5ndGgpOworICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpCisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICBpZiAob3RoZXIgPT0gdGhpcykgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgQnl0ZVN0cmluZykpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBCeXRlU3RyaW5nIG90aGVyQnl0ZVN0cmluZyA9IChCeXRlU3RyaW5nKSBvdGhlcjsKKyAgICBpZiAodG90YWxMZW5ndGggIT0gb3RoZXJCeXRlU3RyaW5nLnNpemUoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodG90YWxMZW5ndGggPT0gMCkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLy8gWW91IGRvbid0IHJlYWxseSB3YW50IHRvIGJlIGNhbGxpbmcgZXF1YWxzIG9uIGxvbmcgc3RyaW5ncywgYnV0IHNpbmNlCisgICAgLy8gd2UgY2FjaGUgdGhlIGhhc2hDb2RlLCB3ZSBlZmZlY3RpdmVseSBjYWNoZSBpbmVxdWFsaXR5LiBXZSB1c2UgdGhlIGNhY2hlZAorICAgIC8vIGhhc2hDb2RlIGlmIGl0J3MgYWxyZWFkeSBjb21wdXRlZC4gIEl0J3MgYXJndWFibGUgd2Ugc2hvdWxkIGNvbXB1dGUgdGhlCisgICAgLy8gaGFzaENvZGUgaGVyZSwgYW5kIGlmIHdlJ3JlIGdvaW5nIHRvIGJlIHRlc3RpbmcgYSBidW5jaCBvZiBieXRlU3RyaW5ncywKKyAgICAvLyBpdCBtaWdodCBldmVuIG1ha2Ugc2Vuc2UuCisgICAgaWYgKGhhc2ggIT0gMCkgeworICAgICAgaW50IGNhY2hlZE90aGVySGFzaCA9IG90aGVyQnl0ZVN0cmluZy5wZWVrQ2FjaGVkSGFzaENvZGUoKTsKKyAgICAgIGlmIChjYWNoZWRPdGhlckhhc2ggIT0gMCAmJiBoYXNoICE9IGNhY2hlZE90aGVySGFzaCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIGVxdWFsc0ZyYWdtZW50cyhvdGhlckJ5dGVTdHJpbmcpOworICB9CisKKyAgLyoqCisgICAqIERldGVybWluZXMgaWYgdGhpcyBzdHJpbmcgaXMgZXF1YWwgdG8gYW5vdGhlciBvZiB0aGUgc2FtZSBsZW5ndGggYnkKKyAgICogaXRlcmF0aW5nIG92ZXIgdGhlIGxlYWYgbm9kZXMuIE9uIGVhY2ggc3RlcCBvZiB0aGUgaXRlcmF0aW9uLCB0aGUKKyAgICogb3ZlcmxhcHBpbmcgc2VnbWVudHMgb2YgdGhlIGxlYXZlcyBhcmUgY29tcGFyZWQuCisgICAqCisgICAqIEBwYXJhbSBvdGhlciBzdHJpbmcgb2YgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoaXMgb25lCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdmFsdWVzIG9mIHRoaXMgc3RyaW5nIGVxdWFscyB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuCisgICAqICAgICAgICAgb25lCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gZXF1YWxzRnJhZ21lbnRzKEJ5dGVTdHJpbmcgb3RoZXIpIHsKKyAgICBpbnQgdGhpc09mZnNldCA9IDA7CisgICAgSXRlcmF0b3I8TGl0ZXJhbEJ5dGVTdHJpbmc+IHRoaXNJdGVyID0gbmV3IFBpZWNlSXRlcmF0b3IodGhpcyk7CisgICAgTGl0ZXJhbEJ5dGVTdHJpbmcgdGhpc1N0cmluZyA9IHRoaXNJdGVyLm5leHQoKTsKKworICAgIGludCB0aGF0T2Zmc2V0ID0gMDsKKyAgICBJdGVyYXRvcjxMaXRlcmFsQnl0ZVN0cmluZz4gdGhhdEl0ZXIgPSBuZXcgUGllY2VJdGVyYXRvcihvdGhlcik7CisgICAgTGl0ZXJhbEJ5dGVTdHJpbmcgdGhhdFN0cmluZyA9IHRoYXRJdGVyLm5leHQoKTsKKworICAgIGludCBwb3MgPSAwOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpbnQgdGhpc1JlbWFpbmluZyA9IHRoaXNTdHJpbmcuc2l6ZSgpIC0gdGhpc09mZnNldDsKKyAgICAgIGludCB0aGF0UmVtYWluaW5nID0gdGhhdFN0cmluZy5zaXplKCkgLSB0aGF0T2Zmc2V0OworICAgICAgaW50IGJ5dGVzVG9Db21wYXJlID0gTWF0aC5taW4odGhpc1JlbWFpbmluZywgdGhhdFJlbWFpbmluZyk7CisKKyAgICAgIC8vIEF0IGxlYXN0IG9uZSBvZiB0aGUgb2Zmc2V0cyB3aWxsIGJlIHplcm8KKyAgICAgIGJvb2xlYW4gc3RpbGxFcXVhbCA9ICh0aGlzT2Zmc2V0ID09IDApCisgICAgICAgICAgPyB0aGlzU3RyaW5nLmVxdWFsc1JhbmdlKHRoYXRTdHJpbmcsIHRoYXRPZmZzZXQsIGJ5dGVzVG9Db21wYXJlKQorICAgICAgICAgIDogdGhhdFN0cmluZy5lcXVhbHNSYW5nZSh0aGlzU3RyaW5nLCB0aGlzT2Zmc2V0LCBieXRlc1RvQ29tcGFyZSk7CisgICAgICBpZiAoIXN0aWxsRXF1YWwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBwb3MgKz0gYnl0ZXNUb0NvbXBhcmU7CisgICAgICBpZiAocG9zID49IHRvdGFsTGVuZ3RoKSB7CisgICAgICAgIGlmIChwb3MgPT0gdG90YWxMZW5ndGgpIHsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICB9CisgICAgICAvLyBXZSBhbHdheXMgZ2V0IHRvIHRoZSBlbmQgb2YgYXQgbGVhc3Qgb25lIG9mIHRoZSBwaWVjZXMKKyAgICAgIGlmIChieXRlc1RvQ29tcGFyZSA9PSB0aGlzUmVtYWluaW5nKSB7IC8vIElmIHJlYWNoZWQgZW5kIG9mIHRoaXMKKyAgICAgICAgdGhpc09mZnNldCA9IDA7CisgICAgICAgIHRoaXNTdHJpbmcgPSB0aGlzSXRlci5uZXh0KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICB0aGlzT2Zmc2V0ICs9IGJ5dGVzVG9Db21wYXJlOworICAgICAgfQorICAgICAgaWYgKGJ5dGVzVG9Db21wYXJlID09IHRoYXRSZW1haW5pbmcpIHsgLy8gSWYgcmVhY2hlZCBlbmQgb2YgdGhhdAorICAgICAgICB0aGF0T2Zmc2V0ID0gMDsKKyAgICAgICAgdGhhdFN0cmluZyA9IHRoYXRJdGVyLm5leHQoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRoYXRPZmZzZXQgKz0gYnl0ZXNUb0NvbXBhcmU7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENhY2hlZCBoYXNoIHZhbHVlLiAgSW50ZW50aW9uYWxseSBhY2Nlc3NlZCB2aWEgYSBkYXRhIHJhY2UsIHdoaWNoIGlzIHNhZmUKKyAgICogYmVjYXVzZSBvZiB0aGUgSmF2YSBNZW1vcnkgTW9kZWwncyAibm8gb3V0LW9mLXRoaW4tYWlyIHZhbHVlcyIgZ3VhcmFudGVlcworICAgKiBmb3IgaW50cy4KKyAgICovCisgIHByaXZhdGUgaW50IGhhc2ggPSAwOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIGludCBoID0gaGFzaDsKKworICAgIGlmIChoID09IDApIHsKKyAgICAgIGggPSB0b3RhbExlbmd0aDsKKyAgICAgIGggPSBwYXJ0aWFsSGFzaChoLCAwLCB0b3RhbExlbmd0aCk7CisgICAgICBpZiAoaCA9PSAwKSB7CisgICAgICAgIGggPSAxOworICAgICAgfQorICAgICAgaGFzaCA9IGg7CisgICAgfQorICAgIHJldHVybiBoOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBpbnQgcGVla0NhY2hlZEhhc2hDb2RlKCkgeworICAgIHJldHVybiBoYXNoOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBpbnQgcGFydGlhbEhhc2goaW50IGgsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICBpbnQgdG9JbmRleCA9IG9mZnNldCArIGxlbmd0aDsKKyAgICBpZiAodG9JbmRleCA8PSBsZWZ0TGVuZ3RoKSB7CisgICAgICByZXR1cm4gbGVmdC5wYXJ0aWFsSGFzaChoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfSBlbHNlIGlmIChvZmZzZXQgPj0gbGVmdExlbmd0aCkgeworICAgICAgcmV0dXJuIHJpZ2h0LnBhcnRpYWxIYXNoKGgsIG9mZnNldCAtIGxlZnRMZW5ndGgsIGxlbmd0aCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGludCBsZWZ0TGVuZ3RoID0gdGhpcy5sZWZ0TGVuZ3RoIC0gb2Zmc2V0OworICAgICAgaW50IGxlZnRQYXJ0aWFsID0gbGVmdC5wYXJ0aWFsSGFzaChoLCBvZmZzZXQsIGxlZnRMZW5ndGgpOworICAgICAgcmV0dXJuIHJpZ2h0LnBhcnRpYWxIYXNoKGxlZnRQYXJ0aWFsLCAwLCBsZW5ndGggLSBsZWZ0TGVuZ3RoKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBJbnB1dCBzdHJlYW0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIENvZGVkSW5wdXRTdHJlYW0gbmV3Q29kZWRJbnB1dCgpIHsKKyAgICByZXR1cm4gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShuZXcgUm9wZUlucHV0U3RyZWFtKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBJbnB1dFN0cmVhbSBuZXdJbnB1dCgpIHsKKyAgICByZXR1cm4gbmV3IFJvcGVJbnB1dFN0cmVhbSgpOworICB9CisKKyAgLyoqCisgICAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgYmFsYW5jaW5nIGFsZ29yaXRobSBvZiBCQVA5NS4gSW4gdGhlIHBhcGVyIHRoZQorICAgKiBhdXRob3JzIHVzZSBhbiBhcnJheSB0byBrZWVwIHRyYWNrIG9mIHBpZWNlcywgd2hpbGUgaGVyZSB3ZSB1c2UgYSBzdGFjay4KKyAgICogVGhlIHRyZWUgaXMgYmFsYW5jZWQgYnkgdHJhdmVyc2luZyBzdWJ0cmVlcyBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLCBhbmQgdGhlCisgICAqIHN0YWNrIGFsd2F5cyBjb250YWlucyB0aGUgcGFydCBvZiB0aGUgc3RyaW5nIHdlJ3ZlIHRyYXZlcnNlZCBzbyBmYXIuCisgICAqCisgICAqIDxwPk9uZSBzdXJwcmlzaW5nIGFzcGVjdCBvZiB0aGUgYWxnb3JpdGhtIGlzIHRoZSByZXN1bHQgb2YgYmFsYW5jaW5nIGlzIG5vdAorICAgKiBuZWNlc3NhcmlseSBiYWxhbmNlZCwgdGhvdWdoIGl0IGlzIG5lYXJseSBiYWxhbmNlZC4gIEZvciBkZXRhaWxzLCBzZWUKKyAgICogQkFQOTUuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBCYWxhbmNlciB7CisgICAgLy8gU3RhY2sgY29udGFpbmluZyB0aGUgcGFydCBvZiB0aGUgc3RyaW5nLCBzdGFydGluZyBmcm9tIHRoZSBsZWZ0LCB0aGF0CisgICAgLy8gd2UndmUgYWxyZWFkeSB0cmF2ZXJzZWQuICBUaGUgZmluYWwgc3RyaW5nIHNob3VsZCBiZSB0aGUgZXF1aXZhbGVudCBvZgorICAgIC8vIGNvbmNhdGVuYXRpbmcgdGhlIHN0cmluZ3Mgb24gdGhlIHN0YWNrIGZyb20gYm90dG9tIHRvIHRvcC4KKyAgICBwcml2YXRlIGZpbmFsIFN0YWNrPEJ5dGVTdHJpbmc+IHByZWZpeGVzU3RhY2sgPSBuZXcgU3RhY2s8Qnl0ZVN0cmluZz4oKTsKKworICAgIHByaXZhdGUgQnl0ZVN0cmluZyBiYWxhbmNlKEJ5dGVTdHJpbmcgbGVmdCwgQnl0ZVN0cmluZyByaWdodCkgeworICAgICAgZG9CYWxhbmNlKGxlZnQpOworICAgICAgZG9CYWxhbmNlKHJpZ2h0KTsKKworICAgICAgLy8gU3dlZXAgc3RhY2sgdG8gZ2F0aGVyIHRoZSByZXN1bHQKKyAgICAgIEJ5dGVTdHJpbmcgcGFydGlhbFN0cmluZyA9IHByZWZpeGVzU3RhY2sucG9wKCk7CisgICAgICB3aGlsZSAoIXByZWZpeGVzU3RhY2suaXNFbXB0eSgpKSB7CisgICAgICAgIEJ5dGVTdHJpbmcgbmV3TGVmdCA9IHByZWZpeGVzU3RhY2sucG9wKCk7CisgICAgICAgIHBhcnRpYWxTdHJpbmcgPSBuZXcgUm9wZUJ5dGVTdHJpbmcobmV3TGVmdCwgcGFydGlhbFN0cmluZyk7CisgICAgICB9CisgICAgICAvLyBXZSBzaG91bGQgZW5kIHVwIHdpdGggYSBSb3BlQnl0ZVN0cmluZyBzaW5jZSBhdCBhIG1pbmltdW0gd2Ugd2lsbAorICAgICAgLy8gY3JlYXRlIG9uZSBmcm9tIGNvbmNhdGVuYXRpbmcgbGVmdCBhbmQgcmlnaHQKKyAgICAgIHJldHVybiBwYXJ0aWFsU3RyaW5nOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkb0JhbGFuY2UoQnl0ZVN0cmluZyByb290KSB7CisgICAgICAvLyBCQVA5NTogSW5zZXJ0IGJhbGFuY2VkIHN1YnRyZWVzIHdob2xlLiBUaGlzIG1lYW5zIHRoZSByZXN1bHQgbWlnaHQgbm90CisgICAgICAvLyBiZSBiYWxhbmNlZCwgbGVhZGluZyB0byByZXBlYXRlZCByZWJhbGFuY2luZ3Mgb24gY29uY2F0ZW5hdGUuIEhvd2V2ZXIsCisgICAgICAvLyB0aGVzZSByZWJhbGFuY2luZ3MgYXJlIHNoYWxsb3cgZHVlIHRvIGlnbm9yaW5nIGJhbGFuY2VkIHN1YnRyZWVzLCBhbmQKKyAgICAgIC8vIHJlbGF0aXZlbHkgZmV3IGNhbGxzIHRvIGluc2VydCgpIHJlc3VsdC4KKyAgICAgIGlmIChyb290LmlzQmFsYW5jZWQoKSkgeworICAgICAgICBpbnNlcnQocm9vdCk7CisgICAgICB9IGVsc2UgaWYgKHJvb3QgaW5zdGFuY2VvZiBSb3BlQnl0ZVN0cmluZykgeworICAgICAgICBSb3BlQnl0ZVN0cmluZyByYnMgPSAoUm9wZUJ5dGVTdHJpbmcpIHJvb3Q7CisgICAgICAgIGRvQmFsYW5jZShyYnMubGVmdCk7CisgICAgICAgIGRvQmFsYW5jZShyYnMucmlnaHQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICJIYXMgYSBuZXcgdHlwZSBvZiBCeXRlU3RyaW5nIGJlZW4gY3JlYXRlZD8gRm91bmQgIiArCisgICAgICAgICAgICAgICAgcm9vdC5nZXRDbGFzcygpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXNoIGEgc3RyaW5nIG9uIHRoZSBiYWxhbmNlIHN0YWNrIChCQVA5NSkuICBCQVA5NSB1c2VzIGFuIGFycmF5IGFuZAorICAgICAqIGNhbGxzIHRoZSBlbGVtZW50cyBpbiB0aGUgYXJyYXkgJ2JpbnMnLiAgV2UgaW5zdGVhZCB1c2UgYSBzdGFjaywgc28gdGhlCisgICAgICogJ2JpbnMnIG9mIGxlbmd0aHMgYXJlIHJlcHJlc2VudGVkIGJ5IGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGVsZW1lbnRzIG9mCisgICAgICogbWluTGVuZ3RoQnlEZXB0aC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsZW5ndGggYmluIGZvciBvdXIgc3RyaW5nLCBhbmQgYWxsIHNob3J0ZXIgbGVuZ3RoIGJpbnMsIGFyZQorICAgICAqIGVtcHR5LCB3ZSBqdXN0IHB1c2ggaXQgb24gdGhlIHN0YWNrLiAgT3RoZXJ3aXNlLCB3ZSBuZWVkIHRvIHN0YXJ0CisgICAgICogY29uY2F0ZW5hdGluZywgcHV0dGluZyB0aGUgZ2l2ZW4gc3RyaW5nIGluIHRoZSAibWlkZGxlIiBhbmQgY29udGludWluZworICAgICAqIHVudGlsIHdlIGxhbmQgaW4gYW4gZW1wdHkgbGVuZ3RoIGJpbiB0aGF0IG1hdGNoZXMgdGhlIGxlbmd0aCBvZiBvdXIKKyAgICAgKiBjb25jYXRlbmF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGJ5dGVTdHJpbmcgc3RyaW5nIHRvIHBsYWNlIG9uIHRoZSBiYWxhbmNlIHN0YWNrCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGluc2VydChCeXRlU3RyaW5nIGJ5dGVTdHJpbmcpIHsKKyAgICAgIGludCBkZXB0aEJpbiA9IGdldERlcHRoQmluRm9yTGVuZ3RoKGJ5dGVTdHJpbmcuc2l6ZSgpKTsKKyAgICAgIGludCBiaW5FbmQgPSBtaW5MZW5ndGhCeURlcHRoW2RlcHRoQmluICsgMV07CisKKyAgICAgIC8vIEJBUDk1OiBDb25jYXRlbmF0ZSBhbGwgdHJlZXMgb2NjdXB5aW5nIGJpbnMgcmVwcmVzZW50aW5nIHRoZSBsZW5ndGggb2YKKyAgICAgIC8vIG91ciBuZXcgcGllY2Ugb3Igb2Ygc2hvcnRlciBwaWVjZXMsIHRvIHRoZSBleHRlbnQgdGhhdCBpcyBwb3NzaWJsZS4KKyAgICAgIC8vIFRoZSBnb2FsIGlzIHRvIGNsZWFyIHRoZSBiaW4gd2hpY2ggb3VyIHBpZWNlIGJlbG9uZ3MgaW4sIGJ1dCB0aGF0IG1heQorICAgICAgLy8gbm90IGJlIGVudGlyZWx5IHBvc3NpYmxlIGlmIHRoZXJlIGFyZW4ndCBlbm91Z2ggbG9uZ2VyIGJpbnMgb2NjdXBpZWQuCisgICAgICBpZiAocHJlZml4ZXNTdGFjay5pc0VtcHR5KCkgfHwgcHJlZml4ZXNTdGFjay5wZWVrKCkuc2l6ZSgpID49IGJpbkVuZCkgeworICAgICAgICBwcmVmaXhlc1N0YWNrLnB1c2goYnl0ZVN0cmluZyk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpbnQgYmluU3RhcnQgPSBtaW5MZW5ndGhCeURlcHRoW2RlcHRoQmluXTsKKworICAgICAgICAvLyBDb25jYXRlbmF0ZSB0aGUgc3VidHJlZXMgb2Ygc2hvcnRlciBsZW5ndGgKKyAgICAgICAgQnl0ZVN0cmluZyBuZXdUcmVlID0gcHJlZml4ZXNTdGFjay5wb3AoKTsKKyAgICAgICAgd2hpbGUgKCFwcmVmaXhlc1N0YWNrLmlzRW1wdHkoKQorICAgICAgICAgICAgJiYgcHJlZml4ZXNTdGFjay5wZWVrKCkuc2l6ZSgpIDwgYmluU3RhcnQpIHsKKyAgICAgICAgICBCeXRlU3RyaW5nIGxlZnQgPSBwcmVmaXhlc1N0YWNrLnBvcCgpOworICAgICAgICAgIG5ld1RyZWUgPSBuZXcgUm9wZUJ5dGVTdHJpbmcobGVmdCwgbmV3VHJlZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBDb25jYXRlbmF0ZSB0aGUgZ2l2ZW4gc3RyaW5nCisgICAgICAgIG5ld1RyZWUgPSBuZXcgUm9wZUJ5dGVTdHJpbmcobmV3VHJlZSwgYnl0ZVN0cmluZyk7CisKKyAgICAgICAgLy8gQ29udGludWUgY29uY2F0ZW5hdGluZyB1bnRpbCB3ZSBsYW5kIGluIGFuIGVtcHR5IGJpbgorICAgICAgICB3aGlsZSAoIXByZWZpeGVzU3RhY2suaXNFbXB0eSgpKSB7CisgICAgICAgICAgZGVwdGhCaW4gPSBnZXREZXB0aEJpbkZvckxlbmd0aChuZXdUcmVlLnNpemUoKSk7CisgICAgICAgICAgYmluRW5kID0gbWluTGVuZ3RoQnlEZXB0aFtkZXB0aEJpbiArIDFdOworICAgICAgICAgIGlmIChwcmVmaXhlc1N0YWNrLnBlZWsoKS5zaXplKCkgPCBiaW5FbmQpIHsKKyAgICAgICAgICAgIEJ5dGVTdHJpbmcgbGVmdCA9IHByZWZpeGVzU3RhY2sucG9wKCk7CisgICAgICAgICAgICBuZXdUcmVlID0gbmV3IFJvcGVCeXRlU3RyaW5nKGxlZnQsIG5ld1RyZWUpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHJlZml4ZXNTdGFjay5wdXNoKG5ld1RyZWUpOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldERlcHRoQmluRm9yTGVuZ3RoKGludCBsZW5ndGgpIHsKKyAgICAgIGludCBkZXB0aCA9IEFycmF5cy5iaW5hcnlTZWFyY2gobWluTGVuZ3RoQnlEZXB0aCwgbGVuZ3RoKTsKKyAgICAgIGlmIChkZXB0aCA8IDApIHsKKyAgICAgICAgLy8gSXQgd2Fzbid0IGFuIGV4YWN0IG1hdGNoLCBzbyBjb252ZXJ0IHRvIHRoZSBpbmRleCBvZiB0aGUgY29udGFpbmluZworICAgICAgICAvLyBmcmFnbWVudCwgd2hpY2ggaXMgb25lIGxlc3MgZXZlbiB0aGFuIHRoZSBpbnNlcnRpb24gcG9pbnQuCisgICAgICAgIGludCBpbnNlcnRpb25Qb2ludCA9IC0oZGVwdGggKyAxKTsKKyAgICAgICAgZGVwdGggPSBpbnNlcnRpb25Qb2ludCAtIDE7CisgICAgICB9CisKKyAgICAgIHJldHVybiBkZXB0aDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogVGhpcyBjbGFzcyBpcyBhIGNvbnRpbnVhYmxlIHRyZWUgdHJhdmVyc2FsLCB3aGljaCBrZWVwcyB0aGUgc3RhdGUKKyAgICogaW5mb3JtYXRpb24gd2hpY2ggd291bGQgZXhpc3Qgb24gdGhlIHN0YWNrIGluIGEgcmVjdXJzaXZlIHRyYXZlcnNhbCBpbnN0ZWFkCisgICAqIG9uIGEgc3RhY2sgb2YgIkJyZWFkIENydW1icyIuIFRoZSBtYXhpbXVtIGRlcHRoIG9mIHRoZSBzdGFjayBpbiB0aGlzCisgICAqIGl0ZXJhdG9yIGlzIHRoZSBzYW1lIGFzIHRoZSBkZXB0aCBvZiB0aGUgdHJlZSBiZWluZyB0cmF2ZXJzZWQuCisgICAqCisgICAqIDxwPlRoaXMgaXRlcmF0b3IgaXMgdXNlZCB0byBpbXBsZW1lbnQKKyAgICoge0BsaW5rIFJvcGVCeXRlU3RyaW5nI2VxdWFsc0ZyYWdtZW50cyhCeXRlU3RyaW5nKX0uCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQaWVjZUl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8TGl0ZXJhbEJ5dGVTdHJpbmc+IHsKKworICAgIHByaXZhdGUgZmluYWwgU3RhY2s8Um9wZUJ5dGVTdHJpbmc+IGJyZWFkQ3J1bWJzID0KKyAgICAgICAgbmV3IFN0YWNrPFJvcGVCeXRlU3RyaW5nPigpOworICAgIHByaXZhdGUgTGl0ZXJhbEJ5dGVTdHJpbmcgbmV4dDsKKworICAgIHByaXZhdGUgUGllY2VJdGVyYXRvcihCeXRlU3RyaW5nIHJvb3QpIHsKKyAgICAgIG5leHQgPSBnZXRMZWFmQnlMZWZ0KHJvb3QpOworICAgIH0KKworICAgIHByaXZhdGUgTGl0ZXJhbEJ5dGVTdHJpbmcgZ2V0TGVhZkJ5TGVmdChCeXRlU3RyaW5nIHJvb3QpIHsKKyAgICAgIEJ5dGVTdHJpbmcgcG9zID0gcm9vdDsKKyAgICAgIHdoaWxlIChwb3MgaW5zdGFuY2VvZiBSb3BlQnl0ZVN0cmluZykgeworICAgICAgICBSb3BlQnl0ZVN0cmluZyByYnMgPSAoUm9wZUJ5dGVTdHJpbmcpIHBvczsKKyAgICAgICAgYnJlYWRDcnVtYnMucHVzaChyYnMpOworICAgICAgICBwb3MgPSByYnMubGVmdDsKKyAgICAgIH0KKyAgICAgIHJldHVybiAoTGl0ZXJhbEJ5dGVTdHJpbmcpIHBvczsKKyAgICB9CisKKyAgICBwcml2YXRlIExpdGVyYWxCeXRlU3RyaW5nIGdldE5leHROb25FbXB0eUxlYWYoKSB7CisgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAvLyBBbG1vc3QgYWx3YXlzLCB3ZSBnbyB0aHJvdWdoIHRoaXMgbG9vcCBleGFjdGx5IG9uY2UuICBIb3dldmVyLCBpZgorICAgICAgICAvLyB3ZSBkaXNjb3ZlciBhbiBlbXB0eSBzdHJpbmcgaW4gdGhlIHJvcGUsIHdlIHRvc3MgaXQgYW5kIHRyeSBhZ2Fpbi4KKyAgICAgICAgaWYgKGJyZWFkQ3J1bWJzLmlzRW1wdHkoKSkgeworICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIExpdGVyYWxCeXRlU3RyaW5nIHJlc3VsdCA9IGdldExlYWZCeUxlZnQoYnJlYWRDcnVtYnMucG9wKCkucmlnaHQpOworICAgICAgICAgIGlmICghcmVzdWx0LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGl0ZW0gYW5kIGFkdmFuY2VzIG9uZSB7QGNvZGUgTGl0ZXJhbEJ5dGVTdHJpbmd9LgorICAgICAqCisgICAgICogQHJldHVybiBuZXh0IG5vbi1lbXB0eSBMaXRlcmFsQnl0ZVN0cmluZyBvciB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgTGl0ZXJhbEJ5dGVTdHJpbmcgbmV4dCgpIHsKKyAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgIH0KKyAgICAgIExpdGVyYWxCeXRlU3RyaW5nIHJlc3VsdCA9IG5leHQ7CisgICAgICBuZXh0ID0gZ2V0TmV4dE5vbkVtcHR5TGVhZigpOworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBTZXJpYWxpemFibGUKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgeworICAgIHJldHVybiBuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcodG9CeXRlQXJyYXkoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvdyBuZXcgSW52YWxpZE9iamVjdEV4Y2VwdGlvbigKKyAgICAgICAgIlJvcGVCeXRlU3RyZWFtIGluc3RhbmNlcyBhcmUgbm90IHRvIGJlIHNlcmlhbGl6ZWQgZGlyZWN0bHkiKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIEJ5dGVJdGVyYXRvcgorCisgIEBPdmVycmlkZQorICBwdWJsaWMgQnl0ZUl0ZXJhdG9yIGl0ZXJhdG9yKCkgeworICAgIHJldHVybiBuZXcgUm9wZUJ5dGVJdGVyYXRvcigpOworICB9CisKKyAgcHJpdmF0ZSBjbGFzcyBSb3BlQnl0ZUl0ZXJhdG9yIGltcGxlbWVudHMgQnl0ZVN0cmluZy5CeXRlSXRlcmF0b3IgeworCisgICAgcHJpdmF0ZSBmaW5hbCBQaWVjZUl0ZXJhdG9yIHBpZWNlczsKKyAgICBwcml2YXRlIEJ5dGVJdGVyYXRvciBieXRlczsKKyAgICBpbnQgYnl0ZXNSZW1haW5pbmc7CisKKyAgICBwcml2YXRlIFJvcGVCeXRlSXRlcmF0b3IoKSB7CisgICAgICBwaWVjZXMgPSBuZXcgUGllY2VJdGVyYXRvcihSb3BlQnl0ZVN0cmluZy50aGlzKTsKKyAgICAgIGJ5dGVzID0gcGllY2VzLm5leHQoKS5pdGVyYXRvcigpOworICAgICAgYnl0ZXNSZW1haW5pbmcgPSBzaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgIHJldHVybiAoYnl0ZXNSZW1haW5pbmcgPiAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZSBuZXh0KCkgeworICAgICAgcmV0dXJuIG5leHRCeXRlKCk7IC8vIERvZXMgbm90IGluc3RhbnRpYXRlIGEgQnl0ZQorICAgIH0KKworICAgIHB1YmxpYyBieXRlIG5leHRCeXRlKCkgeworICAgICAgaWYgKCFieXRlcy5oYXNOZXh0KCkpIHsKKyAgICAgICAgYnl0ZXMgPSBwaWVjZXMubmV4dCgpLml0ZXJhdG9yKCk7CisgICAgICB9CisgICAgICAtLWJ5dGVzUmVtYWluaW5nOworICAgICAgcmV0dXJuIGJ5dGVzLm5leHRCeXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFRoaXMgY2xhc3MgaXMgdGhlIHtAbGluayBSb3BlQnl0ZVN0cmluZ30gZXF1aXZhbGVudCBmb3IKKyAgICoge0BsaW5rIEJ5dGVBcnJheUlucHV0U3RyZWFtfS4KKyAgICovCisgIHByaXZhdGUgY2xhc3MgUm9wZUlucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIC8vIEl0ZXJhdGVzIHRocm91Z2ggdGhlIHBpZWNlcyBvZiB0aGUgcm9wZQorICAgIHByaXZhdGUgUGllY2VJdGVyYXRvciBwaWVjZUl0ZXJhdG9yOworICAgIC8vIFRoZSBjdXJyZW50IHBpZWNlCisgICAgcHJpdmF0ZSBMaXRlcmFsQnl0ZVN0cmluZyBjdXJyZW50UGllY2U7CisgICAgLy8gVGhlIHNpemUgb2YgdGhlIGN1cnJlbnQgcGllY2UKKyAgICBwcml2YXRlIGludCBjdXJyZW50UGllY2VTaXplOworICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgbmV4dCBieXRlIHRvIHJlYWQgaW4gdGhlIGN1cnJlbnQgcGllY2UKKyAgICBwcml2YXRlIGludCBjdXJyZW50UGllY2VJbmRleDsKKyAgICAvLyBUaGUgb2Zmc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgY3VycmVudCBwaWVjZSBpbiB0aGUgcm9wZSBieXRlIHN0cmluZworICAgIHByaXZhdGUgaW50IGN1cnJlbnRQaWVjZU9mZnNldEluUm9wZTsKKyAgICAvLyBPZmZzZXQgaW4gdGhlIGJ1ZmZlciBhdCB3aGljaCB1c2VyIGNhbGxlZCBtYXJrKCk7CisgICAgcHJpdmF0ZSBpbnQgbWFyazsKKworICAgIHB1YmxpYyBSb3BlSW5wdXRTdHJlYW0oKSB7CisgICAgICBpbml0aWFsaXplKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGUgYltdLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSAgeworICAgICAgaWYgKGIgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgMCB8fCBsZW5ndGggPCAwIHx8IGxlbmd0aCA+IGIubGVuZ3RoIC0gb2Zmc2V0KSB7CisgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVhZFNraXBJbnRlcm5hbChiLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGxlbmd0aCkgeworICAgICAgaWYgKGxlbmd0aCA8IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgIH0gZWxzZSBpZiAobGVuZ3RoID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgbGVuZ3RoID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICB9CisgICAgICByZXR1cm4gcmVhZFNraXBJbnRlcm5hbChudWxsLCAwLCAoaW50KSBsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIHJlYWQgYW5kIHNraXAuICBJZiBiICE9IG51bGwsIHRoZW4gcmVhZCB0aGUKKyAgICAgKiBuZXh0IHtAY29kZSBsZW5ndGh9IGJ5dGVzIGludG8gdGhlIGJ1ZmZlciB7QGNvZGUgYn0gYXQKKyAgICAgKiBvZmZzZXQge0Bjb2RlIG9mZnNldH0uICBJZiBiID09IG51bGwsIHRoZW4gc2tpcCB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RoKQorICAgICAqIGJ5dGVzLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCBhbGwgZXJyb3IgY2hlY2tpbmcgaGFzIGFscmVhZHkgaGFwcGVuZWQuCisgICAgICogPHA+CisgICAgICogUmV0dXJucyB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkIG9yIHNraXBwZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgcmVhZFNraXBJbnRlcm5hbChieXRlIGJbXSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgIHsKKyAgICAgIGludCBieXRlc1JlbWFpbmluZyA9IGxlbmd0aDsKKyAgICAgIHdoaWxlIChieXRlc1JlbWFpbmluZyA+IDApIHsKKyAgICAgICAgYWR2YW5jZUlmQ3VycmVudFBpZWNlRnVsbHlSZWFkKCk7CisgICAgICAgIGlmIChjdXJyZW50UGllY2UgPT0gbnVsbCkgeworICAgICAgICAgIGlmIChieXRlc1JlbWFpbmluZyA9PSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAvLyBXZSBkaWRuJ3QgbWFuYWdlIHRvIHJlYWQgYW55dGhpbmcKKyAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBDb3B5IHRoZSBieXRlcyBmcm9tIHRoaXMgcGllY2UuCisgICAgICAgICAgaW50IGN1cnJlbnRQaWVjZVJlbWFpbmluZyA9IGN1cnJlbnRQaWVjZVNpemUgLSBjdXJyZW50UGllY2VJbmRleDsKKyAgICAgICAgICBpbnQgY291bnQgPSBNYXRoLm1pbihjdXJyZW50UGllY2VSZW1haW5pbmcsIGJ5dGVzUmVtYWluaW5nKTsKKyAgICAgICAgICBpZiAoYiAhPSBudWxsKSB7CisgICAgICAgICAgICBjdXJyZW50UGllY2UuY29weVRvKGIsIGN1cnJlbnRQaWVjZUluZGV4LCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgICAgIG9mZnNldCArPSBjb3VudDsKKyAgICAgICAgICB9CisgICAgICAgICAgY3VycmVudFBpZWNlSW5kZXggKz0gY291bnQ7CisgICAgICAgICAgYnl0ZXNSZW1haW5pbmcgLT0gY291bnQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgICAvLyBSZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyByZWFkLgorICAgICAgcmV0dXJuIGxlbmd0aCAtIGJ5dGVzUmVtYWluaW5nOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBhZHZhbmNlSWZDdXJyZW50UGllY2VGdWxseVJlYWQoKTsKKyAgICAgIGlmIChjdXJyZW50UGllY2UgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gY3VycmVudFBpZWNlLmJ5dGVBdChjdXJyZW50UGllY2VJbmRleCsrKSAmIDB4RkY7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaW50IGJ5dGVzUmVhZCA9IGN1cnJlbnRQaWVjZU9mZnNldEluUm9wZSArIGN1cnJlbnRQaWVjZUluZGV4OworICAgICAgcmV0dXJuIFJvcGVCeXRlU3RyaW5nLnRoaXMuc2l6ZSgpIC0gYnl0ZXNSZWFkOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkQWhlYWRMaW1pdCkgeworICAgICAgLy8gU2V0IHRoZSBtYXJrIHRvIG91ciBwb3NpdGlvbiBpbiB0aGUgYnl0ZSBzdHJpbmcKKyAgICAgIG1hcmsgPSBjdXJyZW50UGllY2VPZmZzZXRJblJvcGUgKyBjdXJyZW50UGllY2VJbmRleDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoKSB7CisgICAgICAvLyBKdXN0IHJlaW5pdGlhbGl6ZSBhbmQgc2tpcCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcy4KKyAgICAgIGluaXRpYWxpemUoKTsKKyAgICAgIHJlYWRTa2lwSW50ZXJuYWwobnVsbCwgMCwgbWFyayk7CisgICAgfQorCisgICAgLyoqIENvbW1vbiBpbml0aWFsaXphdGlvbiBjb2RlIHVzZWQgYnkgYm90aCB0aGUgY29uc3RydWN0b3IgYW5kIHJlc2V0KCkgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZSgpIHsKKyAgICAgIHBpZWNlSXRlcmF0b3IgPSBuZXcgUGllY2VJdGVyYXRvcihSb3BlQnl0ZVN0cmluZy50aGlzKTsKKyAgICAgIGN1cnJlbnRQaWVjZSA9IHBpZWNlSXRlcmF0b3IubmV4dCgpOworICAgICAgY3VycmVudFBpZWNlU2l6ZSA9IGN1cnJlbnRQaWVjZS5zaXplKCk7CisgICAgICBjdXJyZW50UGllY2VJbmRleCA9IDA7CisgICAgICBjdXJyZW50UGllY2VPZmZzZXRJblJvcGUgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIHRvIHRoZSBuZXh0IHBpZWNlIGlmIHdlIGhhdmUgcmVhZCBhbGwgdGhlIGRhdGEgaW4gdGhlIGN1cnJlbnQKKyAgICAgKiBwaWVjZS4gIFNldHMgY3VycmVudFBpZWNlIHRvIG51bGwgaWYgd2UgaGF2ZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlCisgICAgICogaW5wdXQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFkdmFuY2VJZkN1cnJlbnRQaWVjZUZ1bGx5UmVhZCgpIHsKKyAgICAgIGlmIChjdXJyZW50UGllY2UgIT0gbnVsbCAmJiBjdXJyZW50UGllY2VJbmRleCA9PSBjdXJyZW50UGllY2VTaXplKSB7CisgICAgICAgIC8vIEdlbmVyYWxseSwgd2UgY2FuIG9ubHkgZ28gdGhyb3VnaCB0aGlzIGxvb3AgYXQgbW9zdCBvbmNlLCBzaW5jZQorICAgICAgICAvLyBlbXB0eSBzdHJpbmdzIGNhbid0IGVuZCB1cCBpbiBhIHJvcGUuICBCdXQgYmV0dGVyIHRvIHRlc3QuCisgICAgICAgIGN1cnJlbnRQaWVjZU9mZnNldEluUm9wZSArPSBjdXJyZW50UGllY2VTaXplOworICAgICAgICBjdXJyZW50UGllY2VJbmRleCA9IDA7CisgICAgICAgIGlmIChwaWVjZUl0ZXJhdG9yLmhhc05leHQoKSkgeworICAgICAgICAgIGN1cnJlbnRQaWVjZSA9IHBpZWNlSXRlcmF0b3IubmV4dCgpOworICAgICAgICAgIGN1cnJlbnRQaWVjZVNpemUgPSBjdXJyZW50UGllY2Uuc2l6ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGN1cnJlbnRQaWVjZSA9IG51bGw7CisgICAgICAgICAgY3VycmVudFBpZWNlU2l6ZSA9IDA7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JwY0NhbGxiYWNrLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNDYWxsYmFjay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwNzUyOTYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNDYWxsYmFjay5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogSW50ZXJmYWNlIGZvciBhbiBSUEMgY2FsbGJhY2ssIG5vcm1hbGx5IGNhbGxlZCB3aGVuIGFuIFJQQyBjb21wbGV0ZXMuCisgKiB7QGNvZGUgUGFyYW1ldGVyVHlwZX0gaXMgbm9ybWFsbHkgdGhlIG1ldGhvZCdzIHJlc3BvbnNlIG1lc3NhZ2UgdHlwZS4KKyAqCisgKiA8cD5TdGFydGluZyB3aXRoIHZlcnNpb24gMi4zLjAsIFJQQyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCB0cnkgdG8gYnVpbGQKKyAqIG9uIHRoaXMsIGJ1dCBzaG91bGQgaW5zdGVhZCBwcm92aWRlIGNvZGUgZ2VuZXJhdG9yIHBsdWdpbnMgd2hpY2ggZ2VuZXJhdGUKKyAqIGNvZGUgc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIgUlBDIGltcGxlbWVudGF0aW9uLiAgVGhpcyB3YXkgdGhlIGdlbmVyYXRlZAorICogY29kZSBjYW4gYmUgbW9yZSBhcHByb3ByaWF0ZSBmb3IgdGhlIGltcGxlbWVudGF0aW9uIGluIHVzZSBhbmQgY2FuIGF2b2lkCisgKiB1bm5lY2Vzc2FyeSBsYXllcnMgb2YgaW5kaXJlY3Rpb24uCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGludGVyZmFjZSBScGNDYWxsYmFjazxQYXJhbWV0ZXJUeXBlPiB7CisgIHZvaWQgcnVuKFBhcmFtZXRlclR5cGUgcGFyYW1ldGVyKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JwY0NoYW5uZWwuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JwY0NoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjcyZjRhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUnBjQ2hhbm5lbC5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogPHA+QWJzdHJhY3QgaW50ZXJmYWNlIGZvciBhbiBSUEMgY2hhbm5lbC4gIEFuIHtAY29kZSBScGNDaGFubmVsfSByZXByZXNlbnRzIGEKKyAqIGNvbW11bmljYXRpb24gbGluZSB0byBhIHtAbGluayBTZXJ2aWNlfSB3aGljaCBjYW4gYmUgdXNlZCB0byBjYWxsIHRoYXQKKyAqIHtAbGluayBTZXJ2aWNlfSdzIG1ldGhvZHMuICBUaGUge0BsaW5rIFNlcnZpY2V9IG1heSBiZSBydW5uaW5nIG9uIGFub3RoZXIKKyAqIG1hY2hpbmUuICBOb3JtYWxseSwgeW91IHNob3VsZCBub3QgY2FsbCBhbiB7QGNvZGUgUnBjQ2hhbm5lbH0gZGlyZWN0bHksIGJ1dAorICogaW5zdGVhZCBjb25zdHJ1Y3QgYSBzdHViIHtAbGluayBTZXJ2aWNlfSB3cmFwcGluZyBpdC4gIEV4YW1wbGU6CisgKgorICogPHByZT4KKyAqICAgUnBjQ2hhbm5lbCBjaGFubmVsID0gcnBjSW1wbC5uZXdDaGFubmVsKCJyZW1vdGVob3N0LmV4YW1wbGUuY29tOjEyMzQiKTsKKyAqICAgUnBjQ29udHJvbGxlciBjb250cm9sbGVyID0gcnBjSW1wbC5uZXdDb250cm9sbGVyKCk7CisgKiAgIE15U2VydmljZSBzZXJ2aWNlID0gTXlTZXJ2aWNlLm5ld1N0dWIoY2hhbm5lbCk7CisgKiAgIHNlcnZpY2UubXlNZXRob2QoY29udHJvbGxlciwgcmVxdWVzdCwgY2FsbGJhY2spOworICogPC9wcmU+CisgKgorICogPHA+U3RhcnRpbmcgd2l0aCB2ZXJzaW9uIDIuMy4wLCBSUEMgaW1wbGVtZW50YXRpb25zIHNob3VsZCBub3QgdHJ5IHRvIGJ1aWxkCisgKiBvbiB0aGlzLCBidXQgc2hvdWxkIGluc3RlYWQgcHJvdmlkZSBjb2RlIGdlbmVyYXRvciBwbHVnaW5zIHdoaWNoIGdlbmVyYXRlCisgKiBjb2RlIHNwZWNpZmljIHRvIHRoZSBwYXJ0aWN1bGFyIFJQQyBpbXBsZW1lbnRhdGlvbi4gIFRoaXMgd2F5IHRoZSBnZW5lcmF0ZWQKKyAqIGNvZGUgY2FuIGJlIG1vcmUgYXBwcm9wcmlhdGUgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiBpbiB1c2UgYW5kIGNhbiBhdm9pZAorICogdW5uZWNlc3NhcnkgbGF5ZXJzIG9mIGluZGlyZWN0aW9uLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUnBjQ2hhbm5lbCB7CisgIC8qKgorICAgKiBDYWxsIHRoZSBnaXZlbiBtZXRob2Qgb2YgdGhlIHJlbW90ZSBzZXJ2aWNlLiAgVGhpcyBtZXRob2QgaXMgc2ltaWxhciB0bworICAgKiB7QGNvZGUgU2VydmljZS5jYWxsTWV0aG9kKCl9IHdpdGggb25lIGltcG9ydGFudCBkaWZmZXJlbmNlOiAgdGhlIGNhbGxlcgorICAgKiBkZWNpZGVzIHRoZSB0eXBlcyBvZiB0aGUge0Bjb2RlIE1lc3NhZ2V9IG9iamVjdHMsIG5vdCB0aGUgY2FsbGVlLiAgVGhlCisgICAqIHJlcXVlc3QgbWF5IGJlIG9mIGFueSB0eXBlIGFzIGxvbmcgYXMKKyAgICoge0Bjb2RlIHJlcXVlc3QuZ2V0RGVzY3JpcHRvcigpID09IG1ldGhvZC5nZXRJbnB1dFR5cGUoKX0uCisgICAqIFRoZSByZXNwb25zZSBwYXNzZWQgdG8gdGhlIGNhbGxiYWNrIHdpbGwgYmUgb2YgdGhlIHNhbWUgdHlwZSBhcworICAgKiB7QGNvZGUgcmVzcG9uc2VQcm90b3R5cGV9ICh3aGljaCBtdXN0IGhhdmUKKyAgICoge0Bjb2RlIGdldERlc2NyaXB0b3IoKSA9PSBtZXRob2QuZ2V0T3V0cHV0VHlwZSgpfSkuCisgICAqLworICB2b2lkIGNhbGxNZXRob2QoRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QsCisgICAgICAgICAgICAgICAgICBScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICBNZXNzYWdlIHJlcXVlc3QsCisgICAgICAgICAgICAgICAgICBNZXNzYWdlIHJlc3BvbnNlUHJvdG90eXBlLAorICAgICAgICAgICAgICAgICAgUnBjQ2FsbGJhY2s8TWVzc2FnZT4gZG9uZSk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNDb250cm9sbGVyLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNDb250cm9sbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTkyZGQ3YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JwY0NvbnRyb2xsZXIuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworLyoqCisgKiA8cD5BbiB7QGNvZGUgUnBjQ29udHJvbGxlcn0gbWVkaWF0ZXMgYSBzaW5nbGUgbWV0aG9kIGNhbGwuICBUaGUgcHJpbWFyeQorICogcHVycG9zZSBvZiB0aGUgY29udHJvbGxlciBpcyB0byBwcm92aWRlIGEgd2F5IHRvIG1hbmlwdWxhdGUgc2V0dGluZ3MKKyAqIHNwZWNpZmljIHRvIHRoZSBSUEMgaW1wbGVtZW50YXRpb24gYW5kIHRvIGZpbmQgb3V0IGFib3V0IFJQQy1sZXZlbCBlcnJvcnMuCisgKgorICogPHA+U3RhcnRpbmcgd2l0aCB2ZXJzaW9uIDIuMy4wLCBSUEMgaW1wbGVtZW50YXRpb25zIHNob3VsZCBub3QgdHJ5IHRvIGJ1aWxkCisgKiBvbiB0aGlzLCBidXQgc2hvdWxkIGluc3RlYWQgcHJvdmlkZSBjb2RlIGdlbmVyYXRvciBwbHVnaW5zIHdoaWNoIGdlbmVyYXRlCisgKiBjb2RlIHNwZWNpZmljIHRvIHRoZSBwYXJ0aWN1bGFyIFJQQyBpbXBsZW1lbnRhdGlvbi4gIFRoaXMgd2F5IHRoZSBnZW5lcmF0ZWQKKyAqIGNvZGUgY2FuIGJlIG1vcmUgYXBwcm9wcmlhdGUgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiBpbiB1c2UgYW5kIGNhbiBhdm9pZAorICogdW5uZWNlc3NhcnkgbGF5ZXJzIG9mIGluZGlyZWN0aW9uLgorICoKKyAqIDxwPlRoZSBtZXRob2RzIHByb3ZpZGVkIGJ5IHRoZSB7QGNvZGUgUnBjQ29udHJvbGxlcn0gaW50ZXJmYWNlIGFyZSBpbnRlbmRlZAorICogdG8gYmUgYSAibGVhc3QgY29tbW9uIGRlbm9taW5hdG9yIiBzZXQgb2YgZmVhdHVyZXMgd2hpY2ggd2UgZXhwZWN0IGFsbAorICogaW1wbGVtZW50YXRpb25zIHRvIHN1cHBvcnQuICBTcGVjaWZpYyBpbXBsZW1lbnRhdGlvbnMgbWF5IHByb3ZpZGUgbW9yZQorICogYWR2YW5jZWQgZmVhdHVyZXMgKGUuZy4gZGVhZGxpbmUgcHJvcGFnYXRpb24pLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUnBjQ29udHJvbGxlciB7CisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGNhbGxzIG1heSBiZSBtYWRlIGZyb20gdGhlIGNsaWVudCBzaWRlIG9ubHkuICBUaGVpciByZXN1bHRzCisgIC8vIGFyZSB1bmRlZmluZWQgb24gdGhlIHNlcnZlciBzaWRlIChtYXkgdGhyb3cgUnVudGltZUV4Y2VwdGlvbnMpLgorCisgIC8qKgorICAgKiBSZXNldHMgdGhlIFJwY0NvbnRyb2xsZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUgc28gdGhhdCBpdCBtYXkgYmUgcmV1c2VkIGluCisgICAqIGEgbmV3IGNhbGwuICBUaGlzIGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgY2xpZW50IHNpZGUgb25seS4gIEl0IG11c3Qgbm90CisgICAqIGJlIGNhbGxlZCB3aGlsZSBhbiBSUEMgaXMgaW4gcHJvZ3Jlc3MuCisgICAqLworICB2b2lkIHJlc2V0KCk7CisKKyAgLyoqCisgICAqIEFmdGVyIGEgY2FsbCBoYXMgZmluaXNoZWQsIHJldHVybnMgdHJ1ZSBpZiB0aGUgY2FsbCBmYWlsZWQuICBUaGUgcG9zc2libGUKKyAgICogcmVhc29ucyBmb3IgZmFpbHVyZSBkZXBlbmQgb24gdGhlIFJQQyBpbXBsZW1lbnRhdGlvbi4gIHtAY29kZSBmYWlsZWQoKX0KKyAgICogbW9zdCBvbmx5IGJlIGNhbGxlZCBvbiB0aGUgY2xpZW50IHNpZGUsIGFuZCBtdXN0IG5vdCBiZSBjYWxsZWQgYmVmb3JlIGEKKyAgICogY2FsbCBoYXMgZmluaXNoZWQuCisgICAqLworICBib29sZWFuIGZhaWxlZCgpOworCisgIC8qKgorICAgKiBJZiB7QGNvZGUgZmFpbGVkKCl9IGlzIHtAY29kZSB0cnVlfSwgcmV0dXJucyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uCisgICAqIG9mIHRoZSBlcnJvci4KKyAgICovCisgIFN0cmluZyBlcnJvclRleHQoKTsKKworICAvKioKKyAgICogQWR2aXNlcyB0aGUgUlBDIHN5c3RlbSB0aGF0IHRoZSBjYWxsZXIgZGVzaXJlcyB0aGF0IHRoZSBSUEMgY2FsbCBiZQorICAgKiBjYW5jZWxlZC4gIFRoZSBSUEMgc3lzdGVtIG1heSBjYW5jZWwgaXQgaW1tZWRpYXRlbHksIG1heSB3YWl0IGF3aGlsZSBhbmQKKyAgICogdGhlbiBjYW5jZWwgaXQsIG9yIG1heSBub3QgZXZlbiBjYW5jZWwgdGhlIGNhbGwgYXQgYWxsLiAgSWYgdGhlIGNhbGwgaXMKKyAgICogY2FuY2VsZWQsIHRoZSAiZG9uZSIgY2FsbGJhY2sgd2lsbCBzdGlsbCBiZSBjYWxsZWQgYW5kIHRoZSBScGNDb250cm9sbGVyCisgICAqIHdpbGwgaW5kaWNhdGUgdGhhdCB0aGUgY2FsbCBmYWlsZWQgYXQgdGhhdCB0aW1lLgorICAgKi8KKyAgdm9pZCBzdGFydENhbmNlbCgpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGNhbGxzIG1heSBiZSBtYWRlIGZyb20gdGhlIHNlcnZlciBzaWRlIG9ubHkuICBUaGVpciByZXN1bHRzCisgIC8vIGFyZSB1bmRlZmluZWQgb24gdGhlIGNsaWVudCBzaWRlIChtYXkgdGhyb3cgUnVudGltZUV4Y2VwdGlvbnMpLgorCisgIC8qKgorICAgKiBDYXVzZXMge0Bjb2RlIGZhaWxlZCgpfSB0byByZXR1cm4gdHJ1ZSBvbiB0aGUgY2xpZW50IHNpZGUuICB7QGNvZGUgcmVhc29ufQorICAgKiB3aWxsIGJlIGluY29ycG9yYXRlZCBpbnRvIHRoZSBtZXNzYWdlIHJldHVybmVkIGJ5IHtAY29kZSBlcnJvclRleHQoKX0uCisgICAqIElmIHlvdSBmaW5kIHlvdSBuZWVkIHRvIHJldHVybiBtYWNoaW5lLXJlYWRhYmxlIGluZm9ybWF0aW9uIGFib3V0CisgICAqIGZhaWx1cmVzLCB5b3Ugc2hvdWxkIGluY29ycG9yYXRlIGl0IGludG8geW91ciByZXNwb25zZSBwcm90b2NvbCBidWZmZXIKKyAgICogYW5kIHNob3VsZCBOT1QgY2FsbCB7QGNvZGUgc2V0RmFpbGVkKCl9LgorICAgKi8KKyAgdm9pZCBzZXRGYWlsZWQoU3RyaW5nIHJlYXNvbik7CisKKyAgLyoqCisgICAqIElmIHtAY29kZSB0cnVlfSwgaW5kaWNhdGVzIHRoYXQgdGhlIGNsaWVudCBjYW5jZWxlZCB0aGUgUlBDLCBzbyB0aGUgc2VydmVyCisgICAqIG1heSBhcyB3ZWxsIGdpdmUgdXAgb24gcmVwbHlpbmcgdG8gaXQuICBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBvbiB0aGUKKyAgICogc2VydmVyIHNpZGUgb25seS4gIFRoZSBzZXJ2ZXIgc2hvdWxkIHN0aWxsIGNhbGwgdGhlIGZpbmFsICJkb25lIiBjYWxsYmFjay4KKyAgICovCisgIGJvb2xlYW4gaXNDYW5jZWxlZCgpOworCisgIC8qKgorICAgKiBBc2tzIHRoYXQgdGhlIGdpdmVuIGNhbGxiYWNrIGJlIGNhbGxlZCB3aGVuIHRoZSBSUEMgaXMgY2FuY2VsZWQuICBUaGUKKyAgICogcGFyYW1ldGVyIHBhc3NlZCB0byB0aGUgY2FsbGJhY2sgd2lsbCBhbHdheXMgYmUge0Bjb2RlIG51bGx9LiAgVGhlCisgICAqIGNhbGxiYWNrIHdpbGwgYWx3YXlzIGJlIGNhbGxlZCBleGFjdGx5IG9uY2UuICBJZiB0aGUgUlBDIGNvbXBsZXRlcyB3aXRob3V0CisgICAqIGJlaW5nIGNhbmNlbGVkLCB0aGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgY29tcGxldGlvbi4gIElmIHRoZSBSUEMKKyAgICogaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZCB3aGVuIE5vdGlmeU9uQ2FuY2VsKCkgaXMgY2FsbGVkLCB0aGUgY2FsbGJhY2sKKyAgICogd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkuCisgICAqCisgICAqIDxwPntAY29kZSBub3RpZnlPbkNhbmNlbCgpfSBtdXN0IGJlIGNhbGxlZCBubyBtb3JlIHRoYW4gb25jZSBwZXIgcmVxdWVzdC4KKyAgICogSXQgbXVzdCBiZSBjYWxsZWQgb24gdGhlIHNlcnZlciBzaWRlIG9ubHkuCisgICAqLworICB2b2lkIG5vdGlmeU9uQ2FuY2VsKFJwY0NhbGxiYWNrPE9iamVjdD4gY2FsbGJhY2spOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUnBjVXRpbC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUnBjVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NGI4ZDEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ScGNVdGlsLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogR3JhYi1iYWcgb2YgdXRpbGl0eSBmdW5jdGlvbnMgdXNlZnVsIHdoZW4gZGVhbGluZyB3aXRoIFJQQ3MuCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFJwY1V0aWwgeworICBwcml2YXRlIFJwY1V0aWwoKSB7fQorCisgIC8qKgorICAgKiBUYWtlIGFuIHtAY29kZSBScGNDYWxsYmFjazxNZXNzYWdlPn0gYW5kIGNvbnZlcnQgaXQgdG8gYW4KKyAgICoge0Bjb2RlIFJwY0NhbGxiYWNrfSBhY2NlcHRpbmcgYSBzcGVjaWZpYyBtZXNzYWdlIHR5cGUuICBUaGlzIGlzIGFsd2F5cworICAgKiB0eXBlLXNhZmUgKHBhcmFtZXRlciB0eXBlIGNvbnRyYXZhcmlhbmNlKS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgc3RhdGljIDxUeXBlIGV4dGVuZHMgTWVzc2FnZT4gUnBjQ2FsbGJhY2s8VHlwZT4KKyAgc3BlY2lhbGl6ZUNhbGxiYWNrKGZpbmFsIFJwY0NhbGxiYWNrPE1lc3NhZ2U+IG9yaWdpbmFsQ2FsbGJhY2spIHsKKyAgICByZXR1cm4gKFJwY0NhbGxiYWNrPFR5cGU+KW9yaWdpbmFsQ2FsbGJhY2s7CisgICAgLy8gVGhlIGFib3ZlIGNhc3Qgd29ya3MsIGJ1dCBvbmx5IGR1ZSB0byB0ZWNobmljYWwgZGV0YWlscyBvZiB0aGUgSmF2YQorICAgIC8vIGltcGxlbWVudGF0aW9uLiAgQSBtb3JlIHRoZW9yZXRpY2FsbHkgY29ycmVjdCAtLSBidXQgbGVzcyBlZmZpY2llbnQgLS0KKyAgICAvLyBpbXBsZW1lbnRhdGlvbiB3b3VsZCBiZSBhcyBmb2xsb3dzOgorICAgIC8vICAgcmV0dXJuIG5ldyBScGNDYWxsYmFjazxUeXBlPigpIHsKKyAgICAvLyAgICAgcHVibGljIHZvaWQgcnVuKFR5cGUgcGFyYW1ldGVyKSB7CisgICAgLy8gICAgICAgb3JpZ2luYWxDYWxsYmFjay5ydW4ocGFyYW1ldGVyKTsKKyAgICAvLyAgICAgfQorICAgIC8vICAgfTsKKyAgfQorCisgIC8qKgorICAgKiBUYWtlIGFuIHtAY29kZSBScGNDYWxsYmFja30gYWNjZXB0aW5nIGEgc3BlY2lmaWMgbWVzc2FnZSB0eXBlIGFuZCBjb252ZXJ0CisgICAqIGl0IHRvIGFuIHtAY29kZSBScGNDYWxsYmFjazxNZXNzYWdlPn0uICBUaGUgZ2VuZXJhbGl6ZWQgY2FsbGJhY2sgd2lsbAorICAgKiBhY2NlcHQgYW55IG1lc3NhZ2Ugb2JqZWN0IHdoaWNoIGhhcyB0aGUgc2FtZSBkZXNjcmlwdG9yLCBhbmQgd2lsbCBjb252ZXJ0CisgICAqIGl0IHRvIHRoZSBjb3JyZWN0IGNsYXNzIGJlZm9yZSBjYWxsaW5nIHRoZSBvcmlnaW5hbCBjYWxsYmFjay4gIEhvd2V2ZXIsCisgICAqIGlmIHRoZSBnZW5lcmFsaXplZCBjYWxsYmFjayBpcyBnaXZlbiBhIG1lc3NhZ2Ugd2l0aCBhIGRpZmZlcmVudCBkZXNjcmlwdG9yLAorICAgKiBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCisgICAqLworICBwdWJsaWMgc3RhdGljIDxUeXBlIGV4dGVuZHMgTWVzc2FnZT4KKyAgUnBjQ2FsbGJhY2s8TWVzc2FnZT4gZ2VuZXJhbGl6ZUNhbGxiYWNrKAorICAgICAgZmluYWwgUnBjQ2FsbGJhY2s8VHlwZT4gb3JpZ2luYWxDYWxsYmFjaywKKyAgICAgIGZpbmFsIENsYXNzPFR5cGU+IG9yaWdpbmFsQ2xhc3MsCisgICAgICBmaW5hbCBUeXBlIGRlZmF1bHRJbnN0YW5jZSkgeworICAgIHJldHVybiBuZXcgUnBjQ2FsbGJhY2s8TWVzc2FnZT4oKSB7CisgICAgICBwdWJsaWMgdm9pZCBydW4oZmluYWwgTWVzc2FnZSBwYXJhbWV0ZXIpIHsKKyAgICAgICAgVHlwZSB0eXBlZFBhcmFtZXRlcjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICB0eXBlZFBhcmFtZXRlciA9IG9yaWdpbmFsQ2xhc3MuY2FzdChwYXJhbWV0ZXIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgIHR5cGVkUGFyYW1ldGVyID0gY29weUFzVHlwZShkZWZhdWx0SW5zdGFuY2UsIHBhcmFtZXRlcik7CisgICAgICAgIH0KKyAgICAgICAgb3JpZ2luYWxDYWxsYmFjay5ydW4odHlwZWRQYXJhbWV0ZXIpOworICAgICAgfQorICAgIH07CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIG5ldyBtZXNzYWdlIG9mIHR5cGUgIlR5cGUiIHdoaWNoIGlzIGEgY29weSBvZiAic291cmNlIi4gICJzb3VyY2UiCisgICAqIG11c3QgaGF2ZSB0aGUgc2FtZSBkZXNjcmlwdG9yIGJ1dCBtYXkgYmUgYSBkaWZmZXJlbnQgY2xhc3MgKGUuZy4KKyAgICogRHluYW1pY01lc3NhZ2UpLgorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHByaXZhdGUgc3RhdGljIDxUeXBlIGV4dGVuZHMgTWVzc2FnZT4gVHlwZSBjb3B5QXNUeXBlKAorICAgICAgZmluYWwgVHlwZSB0eXBlRGVmYXVsdEluc3RhbmNlLCBmaW5hbCBNZXNzYWdlIHNvdXJjZSkgeworICAgIHJldHVybiAoVHlwZSkgdHlwZURlZmF1bHRJbnN0YW5jZQorICAgICAgICAubmV3QnVpbGRlckZvclR5cGUoKS5tZXJnZUZyb20oc291cmNlKS5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBjYWxsYmFjayB3aGljaCBjYW4gb25seSBiZSBjYWxsZWQgb25jZS4gIFRoaXMgbWF5IGJlIHVzZWZ1bCBmb3IKKyAgICogc2VjdXJpdHksIHdoZW4gcGFzc2luZyBhIGNhbGxiYWNrIHRvIHVudHJ1c3RlZCBjb2RlOiAgbW9zdCBjYWxsYmFja3MgZG8KKyAgICogbm90IGV4cGVjdCB0byBiZSBjYWxsZWQgbW9yZSB0aGFuIG9uY2UsIHNvIGRvaW5nIHNvIG1heSBleHBvc2UgYnVncyBpZiBpdAorICAgKiBpcyBub3QgcHJldmVudGVkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8UGFyYW1ldGVyVHlwZT4KKyAgICBScGNDYWxsYmFjazxQYXJhbWV0ZXJUeXBlPiBuZXdPbmVUaW1lQ2FsbGJhY2soCisgICAgICBmaW5hbCBScGNDYWxsYmFjazxQYXJhbWV0ZXJUeXBlPiBvcmlnaW5hbENhbGxiYWNrKSB7CisgICAgcmV0dXJuIG5ldyBScGNDYWxsYmFjazxQYXJhbWV0ZXJUeXBlPigpIHsKKyAgICAgIHByaXZhdGUgYm9vbGVhbiBhbHJlYWR5Q2FsbGVkID0gZmFsc2U7CisKKyAgICAgIHB1YmxpYyB2b2lkIHJ1bihmaW5hbCBQYXJhbWV0ZXJUeXBlIHBhcmFtZXRlcikgeworICAgICAgICBzeW5jaHJvbml6ZWQodGhpcykgeworICAgICAgICAgIGlmIChhbHJlYWR5Q2FsbGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQWxyZWFkeUNhbGxlZEV4Y2VwdGlvbigpOworICAgICAgICAgIH0KKyAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIG9yaWdpbmFsQ2FsbGJhY2sucnVuKHBhcmFtZXRlcik7CisgICAgICB9CisgICAgfTsKKyAgfQorCisgIC8qKgorICAgKiBFeGNlcHRpb24gdGhyb3duIHdoZW4gYSBvbmUtdGltZSBjYWxsYmFjayBpcyBjYWxsZWQgbW9yZSB0aGFuIG9uY2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEFscmVhZHlDYWxsZWRFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NDY5NzQxMjc5NTA3ODQ4MjY2TDsKKworICAgIHB1YmxpYyBBbHJlYWR5Q2FsbGVkRXhjZXB0aW9uKCkgeworICAgICAgc3VwZXIoIlRoaXMgUnBjQ2FsbGJhY2sgd2FzIGFscmVhZHkgY2FsbGVkIGFuZCBjYW5ub3QgYmUgY2FsbGVkICIgKworICAgICAgICAgICAgIm11bHRpcGxlIHRpbWVzLiIpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2VydmljZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2VydmljZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhN2IwMzMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9TZXJ2aWNlLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogQWJzdHJhY3QgYmFzZSBpbnRlcmZhY2UgZm9yIHByb3RvY29sLWJ1ZmZlci1iYXNlZCBSUEMgc2VydmljZXMuICBTZXJ2aWNlcworICogdGhlbXNlbHZlcyBhcmUgYWJzdHJhY3QgY2xhc3NlcyAoaW1wbGVtZW50ZWQgZWl0aGVyIGJ5IHNlcnZlcnMgb3IgYXMKKyAqIHN0dWJzKSwgYnV0IHRoZXkgc3ViY2xhc3MgdGhpcyBiYXNlIGludGVyZmFjZS4gIFRoZSBtZXRob2RzIG9mIHRoaXMKKyAqIGludGVyZmFjZSBjYW4gYmUgdXNlZCB0byBjYWxsIHRoZSBtZXRob2RzIG9mIHRoZSBzZXJ2aWNlIHdpdGhvdXQga25vd2luZworICogaXRzIGV4YWN0IHR5cGUgYXQgY29tcGlsZSB0aW1lIChhbmFsb2dvdXMgdG8gdGhlIE1lc3NhZ2UgaW50ZXJmYWNlKS4KKyAqCisgKiA8cD5TdGFydGluZyB3aXRoIHZlcnNpb24gMi4zLjAsIFJQQyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCB0cnkgdG8gYnVpbGQKKyAqIG9uIHRoaXMsIGJ1dCBzaG91bGQgaW5zdGVhZCBwcm92aWRlIGNvZGUgZ2VuZXJhdG9yIHBsdWdpbnMgd2hpY2ggZ2VuZXJhdGUKKyAqIGNvZGUgc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIgUlBDIGltcGxlbWVudGF0aW9uLiAgVGhpcyB3YXkgdGhlIGdlbmVyYXRlZAorICogY29kZSBjYW4gYmUgbW9yZSBhcHByb3ByaWF0ZSBmb3IgdGhlIGltcGxlbWVudGF0aW9uIGluIHVzZSBhbmQgY2FuIGF2b2lkCisgKiB1bm5lY2Vzc2FyeSBsYXllcnMgb2YgaW5kaXJlY3Rpb24uCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGludGVyZmFjZSBTZXJ2aWNlIHsKKyAgLyoqCisgICAqIEdldCB0aGUge0Bjb2RlIFNlcnZpY2VEZXNjcmlwdG9yfSBkZXNjcmliaW5nIHRoaXMgc2VydmljZSBhbmQgaXRzIG1ldGhvZHMuCisgICAqLworICBEZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yRm9yVHlwZSgpOworCisgIC8qKgorICAgKiA8cD5DYWxsIGEgbWV0aG9kIG9mIHRoZSBzZXJ2aWNlIHNwZWNpZmllZCBieSBNZXRob2REZXNjcmlwdG9yLiAgVGhpcyBpcworICAgKiBub3JtYWxseSBpbXBsZW1lbnRlZCBhcyBhIHNpbXBsZSB7QGNvZGUgc3dpdGNoKCl9IHRoYXQgY2FsbHMgdGhlIHN0YW5kYXJkCisgICAqIGRlZmluaXRpb25zIG9mIHRoZSBzZXJ2aWNlJ3MgbWV0aG9kcy4KKyAgICoKKyAgICogPHA+UHJlY29uZGl0aW9uczoKKyAgICogPHVsPgorICAgKiAgIDxsaT57QGNvZGUgbWV0aG9kLmdldFNlcnZpY2UoKSA9PSBnZXREZXNjcmlwdG9yRm9yVHlwZSgpfQorICAgKiAgIDxsaT57QGNvZGUgcmVxdWVzdH0gaXMgb2YgdGhlIGV4YWN0IHNhbWUgY2xhc3MgYXMgdGhlIG9iamVjdCByZXR1cm5lZCBieQorICAgKiAgICAgICB7QGNvZGUgZ2V0UmVxdWVzdFByb3RvdHlwZShtZXRob2QpfS4KKyAgICogICA8bGk+e0Bjb2RlIGNvbnRyb2xsZXJ9IGlzIG9mIHRoZSBjb3JyZWN0IHR5cGUgZm9yIHRoZSBSUEMgaW1wbGVtZW50YXRpb24KKyAgICogICAgICAgYmVpbmcgdXNlZCBieSB0aGlzIFNlcnZpY2UuICBGb3Igc3R1YnMsIHRoZSAiY29ycmVjdCB0eXBlIiBkZXBlbmRzCisgICAqICAgICAgIG9uIHRoZSBScGNDaGFubmVsIHdoaWNoIHRoZSBzdHViIGlzIHVzaW5nLiAgU2VydmVyLXNpZGUgU2VydmljZQorICAgKiAgICAgICBpbXBsZW1lbnRhdGlvbnMgYXJlIGV4cGVjdGVkIHRvIGFjY2VwdCB3aGF0ZXZlciB0eXBlIG9mCisgICAqICAgICAgIHtAY29kZSBScGNDb250cm9sbGVyfSB0aGUgc2VydmVyLXNpZGUgUlBDIGltcGxlbWVudGF0aW9uIHVzZXMuCisgICAqIDwvdWw+CisgICAqCisgICAqIDxwPlBvc3Rjb25kaXRpb25zOgorICAgKiA8dWw+CisgICAqICAgPGxpPntAY29kZSBkb25lfSB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBtZXRob2QgaXMgY29tcGxldGUuICBUaGlzIG1heSBiZQorICAgKiAgICAgICBiZWZvcmUge0Bjb2RlIGNhbGxNZXRob2QoKX0gcmV0dXJucyBvciBpdCBtYXkgYmUgYXQgc29tZSBwb2ludCBpbgorICAgKiAgICAgICB0aGUgZnV0dXJlLgorICAgKiAgIDxsaT5UaGUgcGFyYW1ldGVyIHRvIHtAY29kZSBkb25lfSBpcyB0aGUgcmVzcG9uc2UuICBJdCBtdXN0IGJlIG9mIHRoZQorICAgKiAgICAgICBleGFjdCBzYW1lIHR5cGUgYXMgd291bGQgYmUgcmV0dXJuZWQgYnkKKyAgICogICAgICAge0Bjb2RlIGdldFJlc3BvbnNlUHJvdG90eXBlKG1ldGhvZCl9LgorICAgKiAgIDxsaT5JZiB0aGUgUlBDIGZhaWxlZCwgdGhlIHBhcmFtZXRlciB0byB7QGNvZGUgZG9uZX0gd2lsbCBiZQorICAgKiAgICAgICB7QGNvZGUgbnVsbH0uICBGdXJ0aGVyIGRldGFpbHMgYWJvdXQgdGhlIGZhaWx1cmUgY2FuIGJlIGZvdW5kIGJ5CisgICAqICAgICAgIHF1ZXJ5aW5nIHtAY29kZSBjb250cm9sbGVyfS4KKyAgICogPC91bD4KKyAgICovCisgIHZvaWQgY2FsbE1ldGhvZChEZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgIFJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKKyAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgcmVxdWVzdCwKKyAgICAgICAgICAgICAgICAgIFJwY0NhbGxiYWNrPE1lc3NhZ2U+IGRvbmUpOworCisgIC8qKgorICAgKiA8cD57QGNvZGUgY2FsbE1ldGhvZCgpfSByZXF1aXJlcyB0aGF0IHRoZSByZXF1ZXN0IHBhc3NlZCBpbiBpcyBvZiBhCisgICAqIHBhcnRpY3VsYXIgc3ViY2xhc3Mgb2Yge0Bjb2RlIE1lc3NhZ2V9LiAge0Bjb2RlIGdldFJlcXVlc3RQcm90b3R5cGUoKX0KKyAgICogZ2V0cyB0aGUgZGVmYXVsdCBpbnN0YW5jZXMgb2YgdGhpcyB0eXBlIGZvciBhIGdpdmVuIG1ldGhvZC4gIFlvdSBjYW4gdGhlbgorICAgKiBjYWxsIHtAY29kZSBNZXNzYWdlLm5ld0J1aWxkZXJGb3JUeXBlKCl9IG9uIHRoaXMgaW5zdGFuY2UgdG8KKyAgICogY29uc3RydWN0IGEgYnVpbGRlciB0byBidWlsZCBhbiBvYmplY3Qgd2hpY2ggeW91IGNhbiB0aGVuIHBhc3MgdG8KKyAgICoge0Bjb2RlIGNhbGxNZXRob2QoKX0uCisgICAqCisgICAqIDxwPkV4YW1wbGU6CisgICAqIDxwcmU+CisgICAqICAgTWV0aG9kRGVzY3JpcHRvciBtZXRob2QgPQorICAgKiAgICAgc2VydmljZS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRNZXRob2RCeU5hbWUoIkZvbyIpOworICAgKiAgIE1lc3NhZ2UgcmVxdWVzdCA9CisgICAqICAgICBzdHViLmdldFJlcXVlc3RQcm90b3R5cGUobWV0aG9kKS5uZXdCdWlsZGVyRm9yVHlwZSgpCisgICAqICAgICAgICAgLm1lcmdlRnJvbShpbnB1dCkuYnVpbGQoKTsKKyAgICogICBzZXJ2aWNlLmNhbGxNZXRob2QobWV0aG9kLCByZXF1ZXN0LCBjYWxsYmFjayk7CisgICAqIDwvcHJlPgorICAgKi8KKyAgTWVzc2FnZSBnZXRSZXF1ZXN0UHJvdG90eXBlKERlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKTsKKworICAvKioKKyAgICogTGlrZSB7QGNvZGUgZ2V0UmVxdWVzdFByb3RvdHlwZSgpfSwgYnV0IGdldHMgYSBwcm90b3R5cGUgb2YgdGhlIHJlc3BvbnNlCisgICAqIG1lc3NhZ2UuICB7QGNvZGUgZ2V0UmVzcG9uc2VQcm90b3R5cGUoKX0gaXMgZ2VuZXJhbGx5IG5vdCBuZWVkZWQgYmVjYXVzZQorICAgKiB0aGUge0Bjb2RlIFNlcnZpY2V9IGltcGxlbWVudGF0aW9uIGNvbnN0cnVjdHMgdGhlIHJlc3BvbnNlIG1lc3NhZ2UgaXRzZWxmLAorICAgKiBidXQgaXQgbWF5IGJlIHVzZWZ1bCBpbiBzb21lIGNhc2VzIHRvIGtub3cgYWhlYWQgb2YgdGltZSB3aGF0IHR5cGUgb2YKKyAgICogb2JqZWN0IHdpbGwgYmUgcmV0dXJuZWQuCisgICAqLworICBNZXNzYWdlIGdldFJlc3BvbnNlUHJvdG90eXBlKERlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NlcnZpY2VFeGNlcHRpb24uamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NlcnZpY2VFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGQ1NzA3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2VydmljZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogVGhyb3duIGJ5IGJsb2NraW5nIFJQQyBtZXRob2RzIHdoZW4gYSBmYWlsdXJlIG9jY3Vycy4KKyAqCisgKiBAYXV0aG9yIGNwb3ZpcmtAZ29vZ2xlLmNvbSAoQ2hyaXMgUG92aXJrKQorICovCitwdWJsaWMgY2xhc3MgU2VydmljZUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xMjE5MjYyMzM1NzI5ODkxOTIwTDsKKworICBwdWJsaWMgU2VydmljZUV4Y2VwdGlvbihmaW5hbCBTdHJpbmcgbWVzc2FnZSkgeworICAgIHN1cGVyKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIFNlcnZpY2VFeGNlcHRpb24oZmluYWwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgc3VwZXIoY2F1c2UpOworICB9CisKKyAgcHVibGljIFNlcnZpY2VFeGNlcHRpb24oZmluYWwgU3RyaW5nIG1lc3NhZ2UsIGZpbmFsIFRocm93YWJsZSBjYXVzZSkgeworICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2luZ2xlRmllbGRCdWlsZGVyLmphdmEgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9TaW5nbGVGaWVsZEJ1aWxkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYmE2NWUzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2luZ2xlRmllbGRCdWlsZGVyLmphdmEKQEAgLTAsMCArMSwyNDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICoge0Bjb2RlIFNpbmdsZUZpZWxkQnVpbGRlcn0gaW1wbGVtZW50cyBhIHN0cnVjdHVyZSB0aGF0IGEgcHJvdG9jb2wKKyAqIG1lc3NhZ2UgdXNlcyB0byBob2xkIGEgc2luZ2xlIGZpZWxkIG9mIGFub3RoZXIgcHJvdG9jb2wgbWVzc2FnZS4gSXQgc3VwcG9ydHMKKyAqIHRoZSBjbGFzc2ljYWwgdXNlIGNhc2Ugb2Ygc2V0dGluZyBhbiBpbW11dGFibGUge0BsaW5rIE1lc3NhZ2V9IGFzIHRoZSB2YWx1ZQorICogb2YgdGhlIGZpZWxkIGFuZCBpcyBoaWdobHkgb3B0aW1pemVkIGFyb3VuZCB0aGlzLgorICogPGJyPgorICogSXQgYWxzbyBzdXBwb3J0cyB0aGUgYWRkaXRpb25hbCB1c2UgY2FzZSBvZiBzZXR0aW5nIGEge0BsaW5rIE1lc3NhZ2UuQnVpbGRlcn0KKyAqIGFzIHRoZSBmaWVsZCBhbmQgZGVmZXJyaW5nIGNvbnZlcnNpb24gb2YgdGhhdCB7QGNvZGUgQnVpbGRlcn0KKyAqIHRvIGFuIGltbXV0YWJsZSB7QGNvZGUgTWVzc2FnZX0uIEluIHRoaXMgd2F5LCBpdCdzIHBvc3NpYmxlIHRvIG1haW50YWluCisgKiBhIHRyZWUgb2Yge0Bjb2RlIEJ1aWxkZXJ9J3MgdGhhdCBhY3RzIGFzIGEgZnVsbHkgcmVhZC93cml0ZSBkYXRhCisgKiBzdHJ1Y3R1cmUuCisgKiA8YnI+CisgKiBMb2dpY2FsbHksIG9uZSBjYW4gdGhpbmsgb2YgYSB0cmVlIG9mIGJ1aWxkZXJzIGFzIGNvbnZlcnRpbmcgdGhlIGVudGlyZSB0cmVlCisgKiB0byBtZXNzYWdlcyB3aGVuIGJ1aWxkIGlzIGNhbGxlZCBvbiB0aGUgcm9vdCBvciB3aGVuIGFueSBtZXRob2QgaXMgY2FsbGVkCisgKiB0aGF0IGRlc2lyZXMgYSBNZXNzYWdlIGluc3RlYWQgb2YgYSBCdWlsZGVyLiBJbiB0ZXJtcyBvZiB0aGUgaW1wbGVtZW50YXRpb24sCisgKiB0aGUge0Bjb2RlIFNpbmdsZUZpZWxkQnVpbGRlcn0gYW5kIHtAY29kZSBSZXBlYXRlZEZpZWxkQnVpbGRlcn0KKyAqIGNsYXNzZXMgY2FjaGUgbWVzc2FnZXMgdGhhdCB3ZXJlIGNyZWF0ZWQgc28gdGhhdCBtZXNzYWdlcyBvbmx5IG5lZWQgdG8gYmUKKyAqIGNyZWF0ZWQgd2hlbiBzb21lIGNoYW5nZSBvY2N1cnJlZCBpbiBpdHMgYnVpbGRlciBvciBhIGJ1aWxkZXIgZm9yIG9uZSBvZiBpdHMKKyAqIGRlc2NlbmRhbnRzLgorICoKKyAqIEBwYXJhbSA8TVR5cGU+IHRoZSB0eXBlIG9mIG1lc3NhZ2UgZm9yIHRoZSBmaWVsZAorICogQHBhcmFtIDxCVHlwZT4gdGhlIHR5cGUgb2YgYnVpbGRlciBmb3IgdGhlIGZpZWxkCisgKiBAcGFyYW0gPElUeXBlPiB0aGUgY29tbW9uIGludGVyZmFjZSBmb3IgdGhlIG1lc3NhZ2UgYW5kIHRoZSBidWlsZGVyCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKi8KK3B1YmxpYyBjbGFzcyBTaW5nbGVGaWVsZEJ1aWxkZXIKKyAgICA8TVR5cGUgZXh0ZW5kcyBHZW5lcmF0ZWRNZXNzYWdlLAorICAgICBCVHlwZSBleHRlbmRzIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlciwKKyAgICAgSVR5cGUgZXh0ZW5kcyBNZXNzYWdlT3JCdWlsZGVyPgorICAgIGltcGxlbWVudHMgR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyUGFyZW50IHsKKworICAvLyBQYXJlbnQgdG8gc2VuZCBjaGFuZ2VzIHRvLgorICBwcml2YXRlIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudCBwYXJlbnQ7CisKKyAgLy8gSW52YXJpYW50OiBvbmUgb2YgYnVpbGRlciBvciBtZXNzYWdlIGZpZWxkcyBtdXN0IGJlIG5vbi1udWxsLgorCisgIC8vIElmIHNldCwgdGhpcyBpcyB0aGUgY2FzZSB3aGVyZSB3ZSBhcmUgYmFja2VkIGJ5IGEgYnVpbGRlci4gSW4gdGhpcyBjYXNlLAorICAvLyBtZXNzYWdlIGZpZWxkIHJlcHJlc2VudHMgYSBjYWNoZWQgbWVzc2FnZSBmb3IgdGhlIGJ1aWxkZXIgKG9yIG51bGwgaWYKKyAgLy8gdGhlcmUgaXMgbm8gY2FjaGVkIG1lc3NhZ2UpLgorICBwcml2YXRlIEJUeXBlIGJ1aWxkZXI7CisKKyAgLy8gSWYgYnVpbGRlciBpcyBub24tbnVsbCwgdGhpcyByZXByZXNlbnRzIGEgY2FjaGVkIG1lc3NhZ2UgZnJvbSB0aGUgYnVpbGRlci4KKyAgLy8gSWYgYnVpbGRlciBpcyBudWxsLCB0aGlzIGlzIHRoZSBhdXRob3JpdGF0aXZlIG1lc3NhZ2UgZm9yIHRoZSBmaWVsZC4KKyAgcHJpdmF0ZSBNVHlwZSBtZXNzYWdlOworCisgIC8vIEluZGljYXRlcyB0aGF0IHdlJ3ZlIGJ1aWx0IGEgbWVzc2FnZSBhbmQgc28gd2UgYXJlIG5vdyBvYmxpZ2F0ZWQKKyAgLy8gdG8gZGlzcGF0Y2ggZGlydHkgaW52YWxpZGF0aW9ucy4gU2VlIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlckxpc3RlbmVyLgorICBwcml2YXRlIGJvb2xlYW4gaXNDbGVhbjsKKworICBwdWJsaWMgU2luZ2xlRmllbGRCdWlsZGVyKAorICAgICAgTVR5cGUgbWVzc2FnZSwKKyAgICAgIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudCBwYXJlbnQsCisgICAgICBib29sZWFuIGlzQ2xlYW4pIHsKKyAgICBpZiAobWVzc2FnZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICB9CisgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKKyAgICB0aGlzLmlzQ2xlYW4gPSBpc0NsZWFuOworICB9CisKKyAgcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKKyAgICAvLyBOdWxsIG91dCBwYXJlbnQgc28gd2Ugc3RvcCBzZW5kaW5nIGl0IGludmFsaWRhdGlvbnMuCisgICAgcGFyZW50ID0gbnVsbDsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIG1lc3NhZ2UgZm9yIHRoZSBmaWVsZC4gSWYgdGhlIG1lc3NhZ2UgaXMgY3VycmVudGx5IHN0b3JlZAorICAgKiBhcyBhIHtAY29kZSBCdWlsZGVyfSwgaXQgaXMgY29udmVydGVkIHRvIGEge0Bjb2RlIE1lc3NhZ2V9IGJ5CisgICAqIGNhbGxpbmcge0BsaW5rIE1lc3NhZ2UuQnVpbGRlciNidWlsZFBhcnRpYWx9IG9uIGl0LiBJZiBubyBtZXNzYWdlIGhhcworICAgKiBiZWVuIHNldCwgcmV0dXJucyB0aGUgZGVmYXVsdCBpbnN0YW5jZSBvZiB0aGUgbWVzc2FnZS4KKyAgICoKKyAgICogQHJldHVybiB0aGUgbWVzc2FnZSBmb3IgdGhlIGZpZWxkCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIE1UeXBlIGdldE1lc3NhZ2UoKSB7CisgICAgaWYgKG1lc3NhZ2UgPT0gbnVsbCkgeworICAgICAgLy8gSWYgbWVzc2FnZSBpcyBudWxsLCB0aGUgaW52YXJpYW50IGlzIHRoYXQgd2UgbXVzdCBiZSBoYXZlIGEgYnVpbGRlci4KKyAgICAgIG1lc3NhZ2UgPSAoTVR5cGUpIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgfQorICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgLyoqCisgICAqIEJ1aWxkcyB0aGUgbWVzc2FnZSBhbmQgcmV0dXJucyBpdC4KKyAgICoKKyAgICogQHJldHVybiB0aGUgbWVzc2FnZQorICAgKi8KKyAgcHVibGljIE1UeXBlIGJ1aWxkKCkgeworICAgIC8vIE5vdyB0aGF0IGJ1aWxkIGhhcyBiZWVuIGNhbGxlZCwgd2UgYXJlIHJlcXVpcmVkIHRvIGRpc3BhdGNoCisgICAgLy8gaW52YWxpZGF0aW9ucy4KKyAgICBpc0NsZWFuID0gdHJ1ZTsKKyAgICByZXR1cm4gZ2V0TWVzc2FnZSgpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgYSBidWlsZGVyIGZvciB0aGUgZmllbGQuIElmIG5vIGJ1aWxkZXIgaGFzIGJlZW4gY3JlYXRlZCB5ZXQsIGEKKyAgICogYnVpbGRlciBpcyBjcmVhdGVkIG9uIGRlbWFuZCBieSBjYWxsaW5nIHtAbGluayBNZXNzYWdlI3RvQnVpbGRlcn0uCisgICAqCisgICAqIEByZXR1cm4gVGhlIGJ1aWxkZXIgZm9yIHRoZSBmaWVsZAorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHB1YmxpYyBCVHlwZSBnZXRCdWlsZGVyKCkgeworICAgIGlmIChidWlsZGVyID09IG51bGwpIHsKKyAgICAgIC8vIGJ1aWxkZXIubWVyZ2VGcm9tKCkgb24gYSBmcmVzaCBidWlsZGVyCisgICAgICAvLyBkb2VzIG5vdCBjcmVhdGUgYW55IHN1Yi1vYmplY3RzIHdpdGggaW5kZXBlbmRlbnQgY2xlYW4vZGlydHkgc3RhdGVzLAorICAgICAgLy8gdGhlcmVmb3JlIHNldHRpbmcgdGhlIGJ1aWxkZXIgaXRzZWxmIHRvIGNsZWFuIHdpdGhvdXQgYWN0dWFsbHkgY2FsbGluZworICAgICAgLy8gYnVpbGQoKSBjYW5ub3QgYnJlYWsgYW55IGludmFyaWFudHMuCisgICAgICBidWlsZGVyID0gKEJUeXBlKSBtZXNzYWdlLm5ld0J1aWxkZXJGb3JUeXBlKHRoaXMpOworICAgICAgYnVpbGRlci5tZXJnZUZyb20obWVzc2FnZSk7IC8vIG5vLW9wIGlmIG1lc3NhZ2UgaXMgdGhlIGRlZmF1bHQgbWVzc2FnZQorICAgICAgYnVpbGRlci5tYXJrQ2xlYW4oKTsKKyAgICB9CisgICAgcmV0dXJuIGJ1aWxkZXI7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgYmFzZSBjbGFzcyBpbnRlcmZhY2UgZm9yIHRoZSBmaWVsZC4gVGhpcyBtYXkgZWl0aGVyIGJlIGEgYnVpbGRlcgorICAgKiBvciBhIG1lc3NhZ2UuIEl0IHdpbGwgcmV0dXJuIHdoYXRldmVyIGlzIG1vcmUgZWZmaWNpZW50LgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBtZXNzYWdlIG9yIGJ1aWxkZXIgZm9yIHRoZSBmaWVsZCBhcyB0aGUgYmFzZSBjbGFzcyBpbnRlcmZhY2UKKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgSVR5cGUgZ2V0TWVzc2FnZU9yQnVpbGRlcigpIHsKKyAgICBpZiAoYnVpbGRlciAhPSBudWxsKSB7CisgICAgICByZXR1cm4gIChJVHlwZSkgYnVpbGRlcjsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIChJVHlwZSkgbWVzc2FnZTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogU2V0cyBhICBtZXNzYWdlIGZvciB0aGUgZmllbGQgcmVwbGFjaW5nIGFueSBleGlzdGluZyB2YWx1ZS4KKyAgICoKKyAgICogQHBhcmFtIG1lc3NhZ2UgdGhlIG1lc3NhZ2UgdG8gc2V0CisgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICovCisgIHB1YmxpYyBTaW5nbGVGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gc2V0TWVzc2FnZSgKKyAgICAgIE1UeXBlIG1lc3NhZ2UpIHsKKyAgICBpZiAobWVzc2FnZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICB9CisgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgICBpZiAoYnVpbGRlciAhPSBudWxsKSB7CisgICAgICBidWlsZGVyLmRpc3Bvc2UoKTsKKyAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgIH0KKyAgICBvbkNoYW5nZWQoKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBNZXJnZXMgdGhlIGZpZWxkIGZyb20gYW5vdGhlciBmaWVsZC4KKyAgICoKKyAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBtZXJnZSBmcm9tCisgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICovCisgIHB1YmxpYyBTaW5nbGVGaWVsZEJ1aWxkZXI8TVR5cGUsIEJUeXBlLCBJVHlwZT4gbWVyZ2VGcm9tKAorICAgICAgTVR5cGUgdmFsdWUpIHsKKyAgICBpZiAoYnVpbGRlciA9PSBudWxsICYmIG1lc3NhZ2UgPT0gbWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkpIHsKKyAgICAgIG1lc3NhZ2UgPSB2YWx1ZTsKKyAgICB9IGVsc2UgeworICAgICAgZ2V0QnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CisgICAgfQorICAgIG9uQ2hhbmdlZCgpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqCisgICAqIENsZWFycyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkLgorICAgKgorICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIFNpbmdsZUZpZWxkQnVpbGRlcjxNVHlwZSwgQlR5cGUsIElUeXBlPiBjbGVhcigpIHsKKyAgICBtZXNzYWdlID0gKE1UeXBlKSAobWVzc2FnZSAhPSBudWxsID8KKyAgICAgICAgbWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgOgorICAgICAgICBidWlsZGVyLmdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSk7CisgICAgaWYgKGJ1aWxkZXIgIT0gbnVsbCkgeworICAgICAgYnVpbGRlci5kaXNwb3NlKCk7CisgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICB9CisgICAgb25DaGFuZ2VkKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogQ2FsbGVkIHdoZW4gYSB0aGUgYnVpbGRlciBvciBvbmUgb2YgaXRzIG5lc3RlZCBjaGlsZHJlbiBoYXMgY2hhbmdlZAorICAgKiBhbmQgYW55IHBhcmVudCBzaG91bGQgYmUgbm90aWZpZWQgb2YgaXRzIGludmFsaWRhdGlvbi4KKyAgICovCisgIHByaXZhdGUgdm9pZCBvbkNoYW5nZWQoKSB7CisgICAgLy8gSWYgYnVpbGRlciBpcyBudWxsLCB0aGlzIGlzIHRoZSBjYXNlIHdoZXJlIG9uQ2hhbmdlZCBpcyBiZWluZyBjYWxsZWQKKyAgICAvLyBmcm9tIHNldE1lc3NhZ2Ugb3IgY2xlYXIuCisgICAgaWYgKGJ1aWxkZXIgIT0gbnVsbCkgeworICAgICAgbWVzc2FnZSA9IG51bGw7CisgICAgfQorICAgIGlmIChpc0NsZWFuICYmIHBhcmVudCAhPSBudWxsKSB7CisgICAgICBwYXJlbnQubWFya0RpcnR5KCk7CisKKyAgICAgIC8vIERvbid0IGtlZXAgZGlzcGF0Y2hpbmcgaW52YWxpZGF0aW9ucyB1bnRpbCBidWlsZCBpcyBjYWxsZWQgYWdhaW4uCisgICAgICBpc0NsZWFuID0gZmFsc2U7CisgICAgfQorICB9CisKKyAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgIHB1YmxpYyB2b2lkIG1hcmtEaXJ0eSgpIHsKKyAgICBvbkNoYW5nZWQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU21hbGxTb3J0ZWRNYXAuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NtYWxsU29ydGVkTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDY3NGQyZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NtYWxsU29ydGVkTWFwLmphdmEKQEAgLTAsMCArMSw2MTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RNYXA7CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0U2V0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKKworLyoqCisgKiBBIGN1c3RvbSBtYXAgaW1wbGVtZW50YXRpb24gZnJvbSBGaWVsZERlc2NyaXB0b3IgdG8gT2JqZWN0IG9wdGltaXplZCB0bworICogbWluaW1pemUgdGhlIG51bWJlciBvZiBtZW1vcnkgYWxsb2NhdGlvbnMgZm9yIGluc3RhbmNlcyB3aXRoIGEgc21hbGwgbnVtYmVyCisgKiBvZiBtYXBwaW5ncy4gVGhlIGltcGxlbWVudGF0aW9uIHN0b3JlcyB0aGUgZmlyc3Qge0Bjb2RlIGt9IG1hcHBpbmdzIGluIGFuCisgKiBhcnJheSBmb3IgYSBjb25maWd1cmFibGUgdmFsdWUgb2Yge0Bjb2RlIGt9LCBhbGxvd2luZyBkaXJlY3QgYWNjZXNzIHRvIHRoZQorICogY29ycmVzcG9uZGluZyB7QGNvZGUgRW50cnl9cyB3aXRob3V0IHRoZSBuZWVkIHRvIGNyZWF0ZSBhbiBJdGVyYXRvci4gVGhlCisgKiByZW1haW5pbmcgZW50cmllcyBhcmUgc3RvcmVkIGluIGFuIG92ZXJmbG93IG1hcC4gSXRlcmF0aW9uIG92ZXIgdGhlIGVudHJpZXMKKyAqIGluIHRoZSBtYXAgc2hvdWxkIGJlIGRvbmUgYXMgZm9sbG93czoKKyAqCisgKiA8cHJlPiAgIHtAY29kZQorICogZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZE1hcC5nZXROdW1BcnJheUVudHJpZXMoKTsgaSsrKSB7CisgKiAgIHByb2Nlc3MoZmllbGRNYXAuZ2V0QXJyYXlFbnRyeUF0KGkpKTsKKyAqIH0KKyAqIGZvciAoTWFwLkVudHJ5PEssIFY+IGVudHJ5IDogZmllbGRNYXAuZ2V0T3ZlcmZsb3dFbnRyaWVzKCkpIHsKKyAqICAgcHJvY2VzcyhlbnRyeSk7CisgKiB9CisgKiB9PC9wcmU+CisgKgorICogVGhlIHJlc3VsdGluZyBpdGVyYXRpb24gaXMgaW4gb3JkZXIgb2YgYXNjZW5kaW5nIGZpZWxkIHRhZyBudW1iZXIuIFRoZQorICogb2JqZWN0IHJldHVybmVkIGJ5IHtAbGluayAjZW50cnlTZXQoKX0gYWRoZXJlcyB0byB0aGUgc2FtZSBjb250cmFjdCBidXQgaXMKKyAqIGxlc3MgZWZmaWNpZW50IGFzIGl0IG5lY2Vzc2FyaWx5IGludm9sdmVzIGNyZWF0aW5nIGFuIG9iamVjdCBmb3IgaXRlcmF0aW9uLgorICogPHA+CisgKiBUaGUgdHJhZGVvZmYgZm9yIHRoaXMgbWVtb3J5IGVmZmljaWVuY3kgaXMgdGhhdCB0aGUgd29yc3QgY2FzZSBydW5uaW5nIHRpbWUKKyAqIG9mIHRoZSB7QGNvZGUgcHV0KCl9IG9wZXJhdGlvbiBpcyB7QGNvZGUgTyhrICsgbGcgbil9LCB3aGljaCBoYXBwZW5zIHdoZW4KKyAqIGVudHJpZXMgYXJlIGFkZGVkIGluIGRlc2NlbmRpbmcgb3JkZXIuIHtAY29kZSBrfSBzaG91bGQgYmUgY2hvc2VuIHN1Y2ggdGhhdAorICogaXQgY292ZXJzIGVub3VnaCBjb21tb24gY2FzZXMgd2l0aG91dCBhZHZlcnNlbHkgYWZmZWN0aW5nIGxhcmdlciBtYXBzLiBJbgorICogcHJhY3RpY2UsIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvIGRvZXMgbm90IGhhcHBlbiBmb3IgZXh0ZW5zaW9ucyBiZWNhdXNlCisgKiBleHRlbnNpb24gZmllbGRzIGFyZSBzZXJpYWxpemVkIGFuZCBkZXNlcmlhbGl6ZWQgaW4gb3JkZXIgb2YgYXNjZW5kaW5nIHRhZworICogbnVtYmVyLCBidXQgdGhlIHdvcnN0IGNhc2Ugc2NlbmFyaW8gY2FuIGhhcHBlbiBmb3IgRHluYW1pY01lc3NhZ2VzLgorICogPHA+CisgKiBUaGUgcnVubmluZyB0aW1lIGZvciBhbGwgb3RoZXIgb3BlcmF0aW9ucyBpcyBzaW1pbGFyIHRvIHRoYXQgb2YKKyAqIHtAY29kZSBUcmVlTWFwfS4KKyAqIDxwPgorICogSW5zdGFuY2VzIGFyZSBub3QgdGhyZWFkLXNhZmUgdW50aWwge0BsaW5rICNtYWtlSW1tdXRhYmxlKCl9IGlzIGNhbGxlZCwKKyAqIGFmdGVyIHdoaWNoIGFueSBtb2RpZnlpbmcgb3BlcmF0aW9uIHdpbGwgcmVzdWx0IGluIGFuCisgKiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICoKKyAqIEBhdXRob3IgZGFyaWNrQGdvb2dsZS5jb20gRGFyaWNrIFRvbmcKKyAqLworLy8gVGhpcyBjbGFzcyBpcyBmaW5hbCBmb3IgYWxsIGludGVudHMgYW5kIHB1cnBvc2VzIGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIGlzCisvLyBwcml2YXRlLiBIb3dldmVyLCB0aGUgRmllbGREZXNjcmlwdG9yLXNwZWNpZmljIGxvZ2ljIGlzIGVuY2Fwc3VsYXRlZCBpbgorLy8gYSBzdWJjbGFzcyB0byBhaWQgdGVzdGFiaWxpdHkgb2YgdGhlIGNvcmUgbG9naWMuCitjbGFzcyBTbWFsbFNvcnRlZE1hcDxLIGV4dGVuZHMgQ29tcGFyYWJsZTxLPiwgVj4gZXh0ZW5kcyBBYnN0cmFjdE1hcDxLLCBWPiB7CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2UgZm9yIG1hcHBpbmcgRmllbGREZXNjcmlwdG9ycyB0byB0aGVpciB2YWx1ZXMuCisgICAqIFRoZSB7QGxpbmsgI21ha2VJbW11dGFibGUoKX0gaW1wbGVtZW50YXRpb24gd2lsbCBjb252ZXJ0IHRoZSBMaXN0IHZhbHVlcworICAgKiBvZiBhbnkgcmVwZWF0ZWQgZmllbGRzIHRvIHVubW9kaWZpYWJsZSBsaXN0cy4KKyAgICoKKyAgICogQHBhcmFtIGFycmF5U2l6ZSBUaGUgc2l6ZSBvZiB0aGUgZW50cnkgYXJyYXkgY29udGFpbmluZyB0aGUKKyAgICogICAgICAgIGxleGljb2dyYXBoaWNhbGx5IHNtYWxsZXN0IG1hcHBpbmdzLgorICAgKi8KKyAgc3RhdGljIDxGaWVsZERlc2NyaXB0b3JUeXBlIGV4dGVuZHMKKyAgICAgIEZpZWxkU2V0LkZpZWxkRGVzY3JpcHRvckxpdGU8RmllbGREZXNjcmlwdG9yVHlwZT4+CisgICAgICBTbWFsbFNvcnRlZE1hcDxGaWVsZERlc2NyaXB0b3JUeXBlLCBPYmplY3Q+IG5ld0ZpZWxkTWFwKGludCBhcnJheVNpemUpIHsKKyAgICByZXR1cm4gbmV3IFNtYWxsU29ydGVkTWFwPEZpZWxkRGVzY3JpcHRvclR5cGUsIE9iamVjdD4oYXJyYXlTaXplKSB7CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgcHVibGljIHZvaWQgbWFrZUltbXV0YWJsZSgpIHsKKyAgICAgICAgaWYgKCFpc0ltbXV0YWJsZSgpKSB7CisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXROdW1BcnJheUVudHJpZXMoKTsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSA9CisgICAgICAgICAgICAgICAgZ2V0QXJyYXlFbnRyeUF0KGkpOworICAgICAgICAgICAgaWYgKGVudHJ5LmdldEtleSgpLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgICBmaW5hbCBMaXN0IHZhbHVlID0gKExpc3QpIGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICAgIGVudHJ5LnNldFZhbHVlKENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QodmFsdWUpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZm9yIChNYXAuRW50cnk8RmllbGREZXNjcmlwdG9yVHlwZSwgT2JqZWN0PiBlbnRyeSA6CisgICAgICAgICAgICAgICAgICAgZ2V0T3ZlcmZsb3dFbnRyaWVzKCkpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5nZXRLZXkoKS5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICAgICAgZmluYWwgTGlzdCB2YWx1ZSA9IChMaXN0KSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICBlbnRyeS5zZXRWYWx1ZShDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHZhbHVlKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHN1cGVyLm1ha2VJbW11dGFibGUoKTsKKyAgICAgIH0KKyAgICB9OworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2UgZm9yIHRlc3RpbmcuCisgICAqCisgICAqIEBwYXJhbSBhcnJheVNpemUgVGhlIHNpemUgb2YgdGhlIGVudHJ5IGFycmF5IGNvbnRhaW5pbmcgdGhlCisgICAqICAgICAgICBsZXhpY29ncmFwaGljYWxseSBzbWFsbGVzdCBtYXBwaW5ncy4KKyAgICovCisgIHN0YXRpYyA8SyBleHRlbmRzIENvbXBhcmFibGU8Sz4sIFY+IFNtYWxsU29ydGVkTWFwPEssIFY+IG5ld0luc3RhbmNlRm9yVGVzdCgKKyAgICAgIGludCBhcnJheVNpemUpIHsKKyAgICByZXR1cm4gbmV3IFNtYWxsU29ydGVkTWFwPEssIFY+KGFycmF5U2l6ZSk7CisgIH0KKworICBwcml2YXRlIGZpbmFsIGludCBtYXhBcnJheVNpemU7CisgIC8vIFRoZSAiZW50cnkgYXJyYXkiIGlzIGFjdHVhbGx5IGEgTGlzdCBiZWNhdXNlIGdlbmVyaWMgYXJyYXlzIGFyZSBub3QKKyAgLy8gYWxsb3dlZC4gQXJyYXlMaXN0IGFsc28gbmljZWx5IGhhbmRsZXMgdGhlIGVudHJ5IHNoaWZ0aW5nIG9uIGluc2VydHMgYW5kCisgIC8vIHJlbW92ZXMuCisgIHByaXZhdGUgTGlzdDxFbnRyeT4gZW50cnlMaXN0OworICBwcml2YXRlIE1hcDxLLCBWPiBvdmVyZmxvd0VudHJpZXM7CisgIHByaXZhdGUgYm9vbGVhbiBpc0ltbXV0YWJsZTsKKyAgLy8gVGhlIEVudHJ5U2V0IGlzIGEgc3RhdGVsZXNzIHZpZXcgb2YgdGhlIE1hcC4gSXQncyBpbml0aWFsaXplZCB0aGUgZmlyc3QKKyAgLy8gdGltZSBpdCBpcyByZXF1ZXN0ZWQgYW5kIHJldXNlZCBoZW5jZWZvcnRoLgorICBwcml2YXRlIHZvbGF0aWxlIEVudHJ5U2V0IGxhenlFbnRyeVNldDsKKworICAvKioKKyAgICogQGNvZGUgYXJyYXlTaXplIFNpemUgb2YgdGhlIGFycmF5IGluIHdoaWNoIHRoZSBsZXhpY29ncmFwaGljYWxseSBzbWFsbGVzdAorICAgKiAgICAgICBtYXBwaW5ncyBhcmUgc3RvcmVkLiAoaS5lLiB0aGUge0Bjb2RlIGt9IHJlZmVycmVkIHRvIGluIHRoZSBjbGFzcworICAgKiAgICAgICBkb2N1bWVudGF0aW9uKS4KKyAgICovCisgIHByaXZhdGUgU21hbGxTb3J0ZWRNYXAoaW50IGFycmF5U2l6ZSkgeworICAgIHRoaXMubWF4QXJyYXlTaXplID0gYXJyYXlTaXplOworICAgIHRoaXMuZW50cnlMaXN0ID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgdGhpcy5vdmVyZmxvd0VudHJpZXMgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOworICB9CisKKyAgLyoqIE1ha2UgdGhpcyBtYXAgaW1tdXRhYmxlIGZyb20gdGhpcyBwb2ludCBmb3J3YXJkLiAqLworICBwdWJsaWMgdm9pZCBtYWtlSW1tdXRhYmxlKCkgeworICAgIGlmICghaXNJbW11dGFibGUpIHsKKyAgICAgIC8vIE5vdGU6IFRoZXJlJ3Mgbm8gbmVlZCB0byB3cmFwIHRoZSBlbnRyeUxpc3QgaW4gYW4gdW5tb2RpZmlhYmxlTGlzdAorICAgICAgLy8gYmVjYXVzZSBub25lIG9mIHRoZSBsaXN0J3MgYWNjZXNzb3JzIGFyZSBleHBvc2VkLiBUaGUgaXRlcmF0b3IoKSBvZgorICAgICAgLy8gb3ZlcmZsb3dFbnRyaWVzLCBvbiB0aGUgb3RoZXIgaGFuZCwgaXMgZXhwb3NlZCBzbyBpdCBtdXN0IGJlIG1hZGUKKyAgICAgIC8vIHVubW9kaWZpYWJsZS4KKyAgICAgIG92ZXJmbG93RW50cmllcyA9IG92ZXJmbG93RW50cmllcy5pc0VtcHR5KCkgPworICAgICAgICAgIENvbGxlY3Rpb25zLjxLLCBWPmVtcHR5TWFwKCkgOgorICAgICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChvdmVyZmxvd0VudHJpZXMpOworICAgICAgaXNJbW11dGFibGUgPSB0cnVlOworICAgIH0KKyAgfQorCisgIC8qKiBAcmV0dXJuIFdoZXRoZXIge0BsaW5rICNtYWtlSW1tdXRhYmxlKCl9IGhhcyBiZWVuIGNhbGxlZC4gKi8KKyAgcHVibGljIGJvb2xlYW4gaXNJbW11dGFibGUoKSB7CisgICAgcmV0dXJuIGlzSW1tdXRhYmxlOworICB9CisKKyAgLyoqIEByZXR1cm4gVGhlIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSBlbnRyeSBhcnJheS4gKi8KKyAgcHVibGljIGludCBnZXROdW1BcnJheUVudHJpZXMoKSB7CisgICAgcmV0dXJuIGVudHJ5TGlzdC5zaXplKCk7CisgIH0KKworICAvKiogQHJldHVybiBUaGUgYXJyYXkgZW50cnkgYXQgdGhlIGdpdmVuIHtAY29kZSBpbmRleH0uICovCisgIHB1YmxpYyBNYXAuRW50cnk8SywgVj4gZ2V0QXJyYXlFbnRyeUF0KGludCBpbmRleCkgeworICAgIHJldHVybiBlbnRyeUxpc3QuZ2V0KGluZGV4KTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIFRoZXJlIG51bWJlciBvZiBvdmVyZmxvdyBlbnRyaWVzLiAqLworICBwdWJsaWMgaW50IGdldE51bU92ZXJmbG93RW50cmllcygpIHsKKyAgICByZXR1cm4gb3ZlcmZsb3dFbnRyaWVzLnNpemUoKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIEFuIGl0ZXJhYmxlIG92ZXIgdGhlIG92ZXJmbG93IGVudHJpZXMuICovCisgIHB1YmxpYyBJdGVyYWJsZTxNYXAuRW50cnk8SywgVj4+IGdldE92ZXJmbG93RW50cmllcygpIHsKKyAgICByZXR1cm4gb3ZlcmZsb3dFbnRyaWVzLmlzRW1wdHkoKSA/CisgICAgICAgIEVtcHR5U2V0LjxNYXAuRW50cnk8SywgVj4+aXRlcmFibGUoKSA6CisgICAgICAgIG92ZXJmbG93RW50cmllcy5lbnRyeVNldCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gZW50cnlMaXN0LnNpemUoKSArIG92ZXJmbG93RW50cmllcy5zaXplKCk7CisgIH0KKworICAvKioKKyAgICogVGhlIGltcGxlbWVudGF0aW9uIHRocm93cyBhIHtAY29kZSBDbGFzc0Nhc3RFeGNlcHRpb259IGlmIG8gaXMgbm90IGFuCisgICAqIG9iamVjdCBvZiB0eXBlIHtAY29kZSBLfS4KKyAgICoKKyAgICoge0Bpbmhlcml0RG9jfQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBvKSB7CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgZmluYWwgSyBrZXkgPSAoSykgbzsKKyAgICByZXR1cm4gYmluYXJ5U2VhcmNoSW5BcnJheShrZXkpID49IDAgfHwgb3ZlcmZsb3dFbnRyaWVzLmNvbnRhaW5zS2V5KGtleSk7CisgIH0KKworICAvKioKKyAgICogVGhlIGltcGxlbWVudGF0aW9uIHRocm93cyBhIHtAY29kZSBDbGFzc0Nhc3RFeGNlcHRpb259IGlmIG8gaXMgbm90IGFuCisgICAqIG9iamVjdCBvZiB0eXBlIHtAY29kZSBLfS4KKyAgICoKKyAgICoge0Bpbmhlcml0RG9jfQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBWIGdldChPYmplY3QgbykgeworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIGZpbmFsIEsga2V5ID0gKEspIG87CisgICAgZmluYWwgaW50IGluZGV4ID0gYmluYXJ5U2VhcmNoSW5BcnJheShrZXkpOworICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICByZXR1cm4gZW50cnlMaXN0LmdldChpbmRleCkuZ2V0VmFsdWUoKTsKKyAgICB9CisgICAgcmV0dXJuIG92ZXJmbG93RW50cmllcy5nZXQoa2V5KTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICBjaGVja011dGFibGUoKTsKKyAgICBmaW5hbCBpbnQgaW5kZXggPSBiaW5hcnlTZWFyY2hJbkFycmF5KGtleSk7CisgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgIC8vIFJlcGxhY2UgZXhpc3RpbmcgYXJyYXkgZW50cnkuCisgICAgICByZXR1cm4gZW50cnlMaXN0LmdldChpbmRleCkuc2V0VmFsdWUodmFsdWUpOworICAgIH0KKyAgICBlbnN1cmVFbnRyeUFycmF5TXV0YWJsZSgpOworICAgIGZpbmFsIGludCBpbnNlcnRpb25Qb2ludCA9IC0oaW5kZXggKyAxKTsKKyAgICBpZiAoaW5zZXJ0aW9uUG9pbnQgPj0gbWF4QXJyYXlTaXplKSB7CisgICAgICAvLyBQdXQgZGlyZWN0bHkgaW4gb3ZlcmZsb3cuCisgICAgICByZXR1cm4gZ2V0T3ZlcmZsb3dFbnRyaWVzTXV0YWJsZSgpLnB1dChrZXksIHZhbHVlKTsKKyAgICB9CisgICAgLy8gSW5zZXJ0IG5ldyBFbnRyeSBpbiBhcnJheS4KKyAgICBpZiAoZW50cnlMaXN0LnNpemUoKSA9PSBtYXhBcnJheVNpemUpIHsKKyAgICAgIC8vIFNoaWZ0IHRoZSBsYXN0IGFycmF5IGVudHJ5IGludG8gb3ZlcmZsb3cuCisgICAgICBmaW5hbCBFbnRyeSBsYXN0RW50cnlJbkFycmF5ID0gZW50cnlMaXN0LnJlbW92ZShtYXhBcnJheVNpemUgLSAxKTsKKyAgICAgIGdldE92ZXJmbG93RW50cmllc011dGFibGUoKS5wdXQobGFzdEVudHJ5SW5BcnJheS5nZXRLZXkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEVudHJ5SW5BcnJheS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgZW50cnlMaXN0LmFkZChpbnNlcnRpb25Qb2ludCwgbmV3IEVudHJ5KGtleSwgdmFsdWUpKTsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICBjaGVja011dGFibGUoKTsKKyAgICBpZiAoIWVudHJ5TGlzdC5pc0VtcHR5KCkpIHsKKyAgICAgIGVudHJ5TGlzdC5jbGVhcigpOworICAgIH0KKyAgICBpZiAoIW92ZXJmbG93RW50cmllcy5pc0VtcHR5KCkpIHsKKyAgICAgIG92ZXJmbG93RW50cmllcy5jbGVhcigpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUaGUgaW1wbGVtZW50YXRpb24gdGhyb3dzIGEge0Bjb2RlIENsYXNzQ2FzdEV4Y2VwdGlvbn0gaWYgbyBpcyBub3QgYW4KKyAgICogb2JqZWN0IG9mIHR5cGUge0Bjb2RlIEt9LgorICAgKgorICAgKiB7QGluaGVyaXREb2N9CisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgY2hlY2tNdXRhYmxlKCk7CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgZmluYWwgSyBrZXkgPSAoSykgbzsKKyAgICBmaW5hbCBpbnQgaW5kZXggPSBiaW5hcnlTZWFyY2hJbkFycmF5KGtleSk7CisgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgIHJldHVybiByZW1vdmVBcnJheUVudHJ5QXQoaW5kZXgpOworICAgIH0KKyAgICAvLyBvdmVyZmxvd0VudHJpZXMgbWlnaHQgYmUgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKCksIHNvIG9ubHkKKyAgICAvLyBjYWxsIHJlbW92ZSgpIGlmIGl0IGlzIG5vbi1lbXB0eS4KKyAgICBpZiAob3ZlcmZsb3dFbnRyaWVzLmlzRW1wdHkoKSkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBvdmVyZmxvd0VudHJpZXMucmVtb3ZlKGtleSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBWIHJlbW92ZUFycmF5RW50cnlBdChpbnQgaW5kZXgpIHsKKyAgICBjaGVja011dGFibGUoKTsKKyAgICBmaW5hbCBWIHJlbW92ZWQgPSBlbnRyeUxpc3QucmVtb3ZlKGluZGV4KS5nZXRWYWx1ZSgpOworICAgIGlmICghb3ZlcmZsb3dFbnRyaWVzLmlzRW1wdHkoKSkgeworICAgICAgLy8gU2hpZnQgdGhlIGZpcnN0IGVudHJ5IGluIHRoZSBvdmVyZmxvdyB0byBiZSB0aGUgbGFzdCBlbnRyeSBpbiB0aGUKKyAgICAgIC8vIGFycmF5LgorICAgICAgZmluYWwgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBpdGVyYXRvciA9CisgICAgICAgICAgZ2V0T3ZlcmZsb3dFbnRyaWVzTXV0YWJsZSgpLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgIGVudHJ5TGlzdC5hZGQobmV3IEVudHJ5KGl0ZXJhdG9yLm5leHQoKSkpOworICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgfQorICAgIHJldHVybiByZW1vdmVkOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0byBmaW5kIGluIHRoZSBlbnRyeSBhcnJheS4KKyAgICogQHJldHVybiBUaGUgcmV0dXJuZWQgaW50ZWdlciBwb3NpdGlvbiBmb2xsb3dzIHRoZSBzYW1lIHNlbWFudGljcyBhcyB0aGUKKyAgICogICAgIHZhbHVlIHJldHVybmVkIGJ5IHtAbGluayBqYXZhLnV0aWwuQXJyYXlzI2JpbmFyeVNlYXJjaCgpfS4KKyAgICovCisgIHByaXZhdGUgaW50IGJpbmFyeVNlYXJjaEluQXJyYXkoSyBrZXkpIHsKKyAgICBpbnQgbGVmdCA9IDA7CisgICAgaW50IHJpZ2h0ID0gZW50cnlMaXN0LnNpemUoKSAtIDE7CisKKyAgICAvLyBPcHRpbWl6YXRpb246IEZvciB0aGUgY29tbW9uIGNhc2UgaW4gd2hpY2ggZW50cmllcyBhcmUgYWRkZWQgaW4KKyAgICAvLyBhc2NlbmRpbmcgdGFnIG9yZGVyLCBjaGVjayB0aGUgbGFyZ2VzdCBlbGVtZW50IGluIHRoZSBhcnJheSBiZWZvcmUKKyAgICAvLyBkb2luZyBhIGZ1bGwgYmluYXJ5IHNlYXJjaC4KKyAgICBpZiAocmlnaHQgPj0gMCkgeworICAgICAgaW50IGNtcCA9IGtleS5jb21wYXJlVG8oZW50cnlMaXN0LmdldChyaWdodCkuZ2V0S2V5KCkpOworICAgICAgaWYgKGNtcCA+IDApIHsKKyAgICAgICAgcmV0dXJuIC0ocmlnaHQgKyAyKTsgIC8vIEluc2VydCBwb2ludCBpcyBhZnRlciAicmlnaHQiLgorICAgICAgfSBlbHNlIGlmIChjbXAgPT0gMCkgeworICAgICAgICByZXR1cm4gcmlnaHQ7CisgICAgICB9CisgICAgfQorCisgICAgd2hpbGUgKGxlZnQgPD0gcmlnaHQpIHsKKyAgICAgIGludCBtaWQgPSAobGVmdCArIHJpZ2h0KSAvIDI7CisgICAgICBpbnQgY21wID0ga2V5LmNvbXBhcmVUbyhlbnRyeUxpc3QuZ2V0KG1pZCkuZ2V0S2V5KCkpOworICAgICAgaWYgKGNtcCA8IDApIHsKKyAgICAgICAgcmlnaHQgPSBtaWQgLSAxOworICAgICAgfSBlbHNlIGlmIChjbXAgPiAwKSB7CisgICAgICAgIGxlZnQgPSBtaWQgKyAxOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIG1pZDsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIC0obGVmdCArIDEpOworICB9CisKKyAgLyoqCisgICAqIFNpbWlsYXIgdG8gdGhlIEFic3RyYWN0TWFwIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBrZXlTZXQoKX0gYW5kCisgICAqIHtAY29kZSB2YWx1ZXMoKX0sIHRoZSBlbnRyeSBzZXQgaXMgY3JlYXRlZCB0aGUgZmlyc3QgdGltZSB0aGlzIG1ldGhvZCBpcworICAgKiBjYWxsZWQsIGFuZCByZXR1cm5lZCBpbiByZXNwb25zZSB0byBhbGwgc3Vic2VxdWVudCBjYWxscy4KKyAgICoKKyAgICoge0Bpbmhlcml0RG9jfQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICBpZiAobGF6eUVudHJ5U2V0ID09IG51bGwpIHsKKyAgICAgIGxhenlFbnRyeVNldCA9IG5ldyBFbnRyeVNldCgpOworICAgIH0KKyAgICByZXR1cm4gbGF6eUVudHJ5U2V0OworICB9CisKKyAgLyoqCisgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYge0BsaW5rICNtYWtlSW1tdXRhYmxlKCl9IGhhcworICAgKiAgICAgICAgIGhhcyBiZWVuIGNhbGxlZC4KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja011dGFibGUoKSB7CisgICAgaWYgKGlzSW1tdXRhYmxlKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBhIHtAbGluayBTb3J0ZWRNYXB9IHRvIHdoaWNoIG92ZXJmbG93IGVudHJpZXMgbWFwcGluZ3MgY2FuIGJlCisgICAqICAgICAgICAgYWRkZWQgb3IgcmVtb3ZlZC4KKyAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB7QGxpbmsgI21ha2VJbW11dGFibGUoKX0gaGFzIGJlZW4KKyAgICogICAgICAgICBjYWxsZWQuCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHJpdmF0ZSBTb3J0ZWRNYXA8SywgVj4gZ2V0T3ZlcmZsb3dFbnRyaWVzTXV0YWJsZSgpIHsKKyAgICBjaGVja011dGFibGUoKTsKKyAgICBpZiAob3ZlcmZsb3dFbnRyaWVzLmlzRW1wdHkoKSAmJiAhKG92ZXJmbG93RW50cmllcyBpbnN0YW5jZW9mIFRyZWVNYXApKSB7CisgICAgICBvdmVyZmxvd0VudHJpZXMgPSBuZXcgVHJlZU1hcDxLLCBWPigpOworICAgIH0KKyAgICByZXR1cm4gKFNvcnRlZE1hcDxLLCBWPikgb3ZlcmZsb3dFbnRyaWVzOworICB9CisKKyAgLyoqCisgICAqIExhemlseSBjcmVhdGVzIHRoZSBlbnRyeSBsaXN0LiBBbnkgY29kZSB0aGF0IGFkZHMgdG8gdGhlIGxpc3QgbXVzdCBmaXJzdAorICAgKiBjYWxsIHRoaXMgbWV0aG9kLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGVuc3VyZUVudHJ5QXJyYXlNdXRhYmxlKCkgeworICAgIGNoZWNrTXV0YWJsZSgpOworICAgIGlmIChlbnRyeUxpc3QuaXNFbXB0eSgpICYmICEoZW50cnlMaXN0IGluc3RhbmNlb2YgQXJyYXlMaXN0KSkgeworICAgICAgZW50cnlMaXN0ID0gbmV3IEFycmF5TGlzdDxFbnRyeT4obWF4QXJyYXlTaXplKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRW50cnkgaW1wbGVtZW50YXRpb24gdGhhdCBpbXBsZW1lbnRzIENvbXBhcmFibGUgaW4gb3JkZXIgdG8gc3VwcG9ydAorICAgKiBiaW5hcnkgc2VhcmNoIHdpdGhpbiB0aGUgZW50cnkgYXJyYXkuIEFsc28gY2hlY2tzIG11dGFiaWxpdHkgaW4KKyAgICoge0BsaW5rICNzZXRWYWx1ZSgpfS4KKyAgICovCisgIHByaXZhdGUgY2xhc3MgRW50cnkgaW1wbGVtZW50cyBNYXAuRW50cnk8SywgVj4sIENvbXBhcmFibGU8RW50cnk+IHsKKworICAgIHByaXZhdGUgZmluYWwgSyBrZXk7CisgICAgcHJpdmF0ZSBWIHZhbHVlOworCisgICAgRW50cnkoTWFwLkVudHJ5PEssIFY+IGNvcHkpIHsKKyAgICAgIHRoaXMoY29weS5nZXRLZXkoKSwgY29weS5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBFbnRyeShLIGtleSwgViB2YWx1ZSkgeworICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIEsgZ2V0S2V5KCkgeworICAgICAgcmV0dXJuIGtleTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhFbnRyeSBvdGhlcikgeworICAgICAgcmV0dXJuIGdldEtleSgpLmNvbXBhcmVUbyhvdGhlci5nZXRLZXkoKSk7CisgICAgfQorCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIFYgc2V0VmFsdWUoViBuZXdWYWx1ZSkgeworICAgICAgY2hlY2tNdXRhYmxlKCk7CisgICAgICBmaW5hbCBWIG9sZFZhbHVlID0gdGhpcy52YWx1ZTsKKyAgICAgIHRoaXMudmFsdWUgPSBuZXdWYWx1ZTsKKyAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgIGlmIChvID09IHRoaXMpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAoIShvIGluc3RhbmNlb2YgTWFwLkVudHJ5KSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgIE1hcC5FbnRyeTw/LCA/PiBvdGhlciA9IChNYXAuRW50cnk8PywgPz4pIG87CisgICAgICByZXR1cm4gZXF1YWxzKGtleSwgb3RoZXIuZ2V0S2V5KCkpICYmIGVxdWFscyh2YWx1ZSwgb3RoZXIuZ2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAoa2V5ID09IG51bGwgPyAwIDoga2V5Lmhhc2hDb2RlKCkpIF4KKyAgICAgICAgICAodmFsdWUgPT0gbnVsbCA/IDAgOiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgcmV0dXJuIGtleSArICI9IiArIHZhbHVlOworICAgIH0KKworICAgIC8qKiBlcXVhbHMoKSB0aGF0IGhhbmRsZXMgbnVsbCB2YWx1ZXMuICovCisgICAgcHJpdmF0ZSBib29sZWFuIGVxdWFscyhPYmplY3QgbzEsIE9iamVjdCBvMikgeworICAgICAgcmV0dXJuIG8xID09IG51bGwgPyBvMiA9PSBudWxsIDogbzEuZXF1YWxzKG8yKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogU3RhdGVsZXNzIHZpZXcgb2YgdGhlIGVudHJpZXMgaW4gdGhlIGZpZWxkIG1hcC4KKyAgICovCisgIHByaXZhdGUgY2xhc3MgRW50cnlTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldDxNYXAuRW50cnk8SywgVj4+IHsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxNYXAuRW50cnk8SywgVj4+IGl0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuIG5ldyBFbnRyeUl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgcmV0dXJuIFNtYWxsU29ydGVkTWFwLnRoaXMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyBhIHtAbGluayBDbGFzc0Nhc3RFeGNlcHRpb259IGlmIG8gaXMgbm90IG9mIHRoZSBleHBlY3RlZCB0eXBlLgorICAgICAqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgIGZpbmFsIE1hcC5FbnRyeTxLLCBWPiBlbnRyeSA9IChNYXAuRW50cnk8SywgVj4pIG87CisgICAgICBmaW5hbCBWIGV4aXN0aW5nID0gZ2V0KGVudHJ5LmdldEtleSgpKTsKKyAgICAgIGZpbmFsIFYgdmFsdWUgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgcmV0dXJuIGV4aXN0aW5nID09IHZhbHVlIHx8CisgICAgICAgICAgKGV4aXN0aW5nICE9IG51bGwgJiYgZXhpc3RpbmcuZXF1YWxzKHZhbHVlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkKE1hcC5FbnRyeTxLLCBWPiBlbnRyeSkgeworICAgICAgaWYgKCFjb250YWlucyhlbnRyeSkpIHsKKyAgICAgICAgcHV0KGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhyb3dzIGEge0BsaW5rIENsYXNzQ2FzdEV4Y2VwdGlvbn0gaWYgbyBpcyBub3Qgb2YgdGhlIGV4cGVjdGVkIHR5cGUuCisgICAgICoKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgIGZpbmFsIE1hcC5FbnRyeTxLLCBWPiBlbnRyeSA9IChNYXAuRW50cnk8SywgVj4pIG87CisgICAgICBpZiAoY29udGFpbnMoZW50cnkpKSB7CisgICAgICAgIFNtYWxsU29ydGVkTWFwLnRoaXMucmVtb3ZlKGVudHJ5LmdldEtleSgpKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICBTbWFsbFNvcnRlZE1hcC50aGlzLmNsZWFyKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEl0ZXJhdG9yIGltcGxlbWVudGF0aW9uIHRoYXQgc3dpdGNoZXMgZnJvbSB0aGUgZW50cnkgYXJyYXkgdG8gdGhlIG92ZXJmbG93CisgICAqIGVudHJpZXMgYXBwcm9wcmlhdGVseS4KKyAgICovCisgIHByaXZhdGUgY2xhc3MgRW50cnlJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4geworCisgICAgcHJpdmF0ZSBpbnQgcG9zID0gLTE7CisgICAgcHJpdmF0ZSBib29sZWFuIG5leHRDYWxsZWRCZWZvcmVSZW1vdmU7CisgICAgcHJpdmF0ZSBJdGVyYXRvcjxNYXAuRW50cnk8SywgVj4+IGxhenlPdmVyZmxvd0l0ZXJhdG9yOworCisgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgIHJldHVybiAocG9zICsgMSkgPCBlbnRyeUxpc3Quc2l6ZSgpIHx8CisgICAgICAgICAgZ2V0T3ZlcmZsb3dJdGVyYXRvcigpLmhhc05leHQoKTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICBwdWJsaWMgTWFwLkVudHJ5PEssIFY+IG5leHQoKSB7CisgICAgICBuZXh0Q2FsbGVkQmVmb3JlUmVtb3ZlID0gdHJ1ZTsKKyAgICAgIC8vIEFsd2F5cyBpbmNyZW1lbnQgcG9zIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIHRoZSBsYXN0IHJldHVybmVkIHZhbHVlCisgICAgICAvLyB3YXMgZnJvbSB0aGUgYXJyYXkgb3IgZnJvbSBvdmVyZmxvdy4KKyAgICAgIGlmICgrK3BvcyA8IGVudHJ5TGlzdC5zaXplKCkpIHsKKyAgICAgICAgcmV0dXJuIGVudHJ5TGlzdC5nZXQocG9zKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBnZXRPdmVyZmxvd0l0ZXJhdG9yKCkubmV4dCgpOworICAgIH0KKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgIGlmICghbmV4dENhbGxlZEJlZm9yZVJlbW92ZSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJyZW1vdmUoKSB3YXMgY2FsbGVkIGJlZm9yZSBuZXh0KCkiKTsKKyAgICAgIH0KKyAgICAgIG5leHRDYWxsZWRCZWZvcmVSZW1vdmUgPSBmYWxzZTsKKyAgICAgIGNoZWNrTXV0YWJsZSgpOworCisgICAgICBpZiAocG9zIDwgZW50cnlMaXN0LnNpemUoKSkgeworICAgICAgICByZW1vdmVBcnJheUVudHJ5QXQocG9zLS0pOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZ2V0T3ZlcmZsb3dJdGVyYXRvcigpLnJlbW92ZSgpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEl0IGlzIGltcG9ydGFudCB0byBjcmVhdGUgdGhlIG92ZXJmbG93IGl0ZXJhdG9yIG9ubHkgYWZ0ZXIgdGhlIGFycmF5CisgICAgICogZW50cmllcyBoYXZlIGJlZW4gaXRlcmF0ZWQgb3ZlciBiZWNhdXNlIHRoZSBvdmVyZmxvdyBlbnRyeSBzZXQgY2hhbmdlcworICAgICAqIHdoZW4gdGhlIGNsaWVudCBjYWxscyByZW1vdmUoKSBvbiB0aGUgYXJyYXkgZW50cmllcywgd2hpY2ggaW52YWxpZGF0ZXMKKyAgICAgKiBhbnkgZXhpc3RpbmcgaXRlcmF0b3JzLgorICAgICAqLworICAgIHByaXZhdGUgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBnZXRPdmVyZmxvd0l0ZXJhdG9yKCkgeworICAgICAgaWYgKGxhenlPdmVyZmxvd0l0ZXJhdG9yID09IG51bGwpIHsKKyAgICAgICAgbGF6eU92ZXJmbG93SXRlcmF0b3IgPSBvdmVyZmxvd0VudHJpZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgfQorICAgICAgcmV0dXJuIGxhenlPdmVyZmxvd0l0ZXJhdG9yOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgY2xhc3MgdGhhdCBob2xkcyBpbW11dGFibGUgaW5zdGFuY2VzIG9mIGFuIEl0ZXJhYmxlL0l0ZXJhdG9yIHRoYXQKKyAgICogd2UgcmV0dXJuIHdoZW4gdGhlIG92ZXJmbG93IGVudHJpZXMgaXMgZW1wdHkuIFRoaXMgZWxpbWluYXRlcyB0aGUgY3JlYXRpb24KKyAgICogb2YgYW4gSXRlcmF0b3Igb2JqZWN0IHdoZW4gdGhlcmUgaXMgbm90aGluZyB0byBpdGVyYXRlIG92ZXIuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbXB0eVNldCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJdGVyYXRvcjxPYmplY3Q+IElURVJBVE9SID0gbmV3IEl0ZXJhdG9yPE9iamVjdD4oKSB7CisgICAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgeworICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgfQorICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJdGVyYWJsZTxPYmplY3Q+IElURVJBQkxFID0gbmV3IEl0ZXJhYmxlPE9iamVjdD4oKSB7CisgICAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICAgIHB1YmxpYyBJdGVyYXRvcjxPYmplY3Q+IGl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gSVRFUkFUT1I7CisgICAgICB9CisgICAgfTsKKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHN0YXRpYyA8VD4gSXRlcmFibGU8VD4gaXRlcmFibGUoKSB7CisgICAgICByZXR1cm4gKEl0ZXJhYmxlPFQ+KSBJVEVSQUJMRTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1RleHRGb3JtYXQuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1RleHRGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDJiNDYwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGV4dEZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsMTk5OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CisKKy8qKgorICogUHJvdmlkZSB0ZXh0IHBhcnNpbmcgYW5kIGZvcm1hdHRpbmcgc3VwcG9ydCBmb3IgcHJvdG8yIGluc3RhbmNlcy4KKyAqIFRoZSBpbXBsZW1lbnRhdGlvbiBsYXJnZWx5IGZvbGxvd3MgZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmNjLgorICoKKyAqIEBhdXRob3Igd2VuYm96QGdvb2dsZS5jb20gV2VuYm8gWmh1CisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGV4dEZvcm1hdCB7CisgIHByaXZhdGUgVGV4dEZvcm1hdCgpIHt9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nZ2VyIGxvZ2dlciA9CisgICAgICBMb2dnZXIuZ2V0TG9nZ2VyKFRleHRGb3JtYXQuY2xhc3MuZ2V0TmFtZSgpKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcmludGVyIERFRkFVTFRfUFJJTlRFUiA9IG5ldyBQcmludGVyKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByaW50ZXIgU0lOR0xFX0xJTkVfUFJJTlRFUiA9CisgICAgICAobmV3IFByaW50ZXIoKSkuc2V0U2luZ2xlTGluZU1vZGUodHJ1ZSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByaW50ZXIgVU5JQ09ERV9QUklOVEVSID0KKyAgICAgIChuZXcgUHJpbnRlcigpKS5zZXRFc2NhcGVOb25Bc2NpaShmYWxzZSk7CisKKyAgLyoqCisgICAqIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBQcm90b2NvbCBNZXNzYWdlIHN1cHBsaWVkIGludG8KKyAgICogdGhlIHBhcmFtZXRlciBvdXRwdXQuIChUaGlzIHJlcHJlc2VudGF0aW9uIGlzIHRoZSBuZXcgdmVyc2lvbiBvZiB0aGUKKyAgICogY2xhc3NpYyAiUHJvdG9jb2xQcmludGVyIiBvdXRwdXQgZnJvbSB0aGUgb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVyIHN5c3RlbSkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludCgKKyAgICAgIGZpbmFsIE1lc3NhZ2VPckJ1aWxkZXIgbWVzc2FnZSwgZmluYWwgQXBwZW5kYWJsZSBvdXRwdXQpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIERFRkFVTFRfUFJJTlRFUi5wcmludChtZXNzYWdlLCBuZXcgVGV4dEdlbmVyYXRvcihvdXRwdXQpKTsKKyAgfQorCisgIC8qKiBPdXRwdXRzIGEgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgZmllbGRzfSB0byB7QGNvZGUgb3V0cHV0fS4gKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50KGZpbmFsIFVua25vd25GaWVsZFNldCBmaWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBBcHBlbmRhYmxlIG91dHB1dCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgREVGQVVMVF9QUklOVEVSLnByaW50VW5rbm93bkZpZWxkcyhmaWVsZHMsIG5ldyBUZXh0R2VuZXJhdG9yKG91dHB1dCkpOworICB9CisKKyAgLyoqCisgICAqIFNhbWUgYXMge0Bjb2RlIHByaW50KCl9LCBleGNlcHQgdGhhdCBub24tQVNDSUkgY2hhcmFjdGVycyBhcmUgbm90CisgICAqIGVzY2FwZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRVbmljb2RlKAorICAgICAgZmluYWwgTWVzc2FnZU9yQnVpbGRlciBtZXNzYWdlLCBmaW5hbCBBcHBlbmRhYmxlIG91dHB1dCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVU5JQ09ERV9QUklOVEVSLnByaW50KG1lc3NhZ2UsIG5ldyBUZXh0R2VuZXJhdG9yKG91dHB1dCkpOworICB9CisKKyAgLyoqCisgICAqIFNhbWUgYXMge0Bjb2RlIHByaW50KCl9LCBleGNlcHQgdGhhdCBub24tQVNDSUkgY2hhcmFjdGVycyBhcmUgbm90CisgICAqIGVzY2FwZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRVbmljb2RlKGZpbmFsIFVua25vd25GaWVsZFNldCBmaWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQXBwZW5kYWJsZSBvdXRwdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBVTklDT0RFX1BSSU5URVIucHJpbnRVbmtub3duRmllbGRzKGZpZWxkcywgbmV3IFRleHRHZW5lcmF0b3Iob3V0cHV0KSk7CisgIH0KKworICAvKioKKyAgICogR2VuZXJhdGVzIGEgaHVtYW4gcmVhZGFibGUgZm9ybSBvZiB0aGlzIG1lc3NhZ2UsIHVzZWZ1bCBmb3IgZGVidWdnaW5nIGFuZAorICAgKiBvdGhlciBwdXJwb3Nlcywgd2l0aCBubyBuZXdsaW5lIGNoYXJhY3RlcnMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBzaG9ydERlYnVnU3RyaW5nKGZpbmFsIE1lc3NhZ2VPckJ1aWxkZXIgbWVzc2FnZSkgeworICAgIHRyeSB7CisgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgIFNJTkdMRV9MSU5FX1BSSU5URVIucHJpbnQobWVzc2FnZSwgbmV3IFRleHRHZW5lcmF0b3Ioc2IpKTsKKyAgICAgIC8vIFNpbmdsZSBsaW5lIG1vZGUgY3VycmVudGx5IG1pZ2h0IGhhdmUgYW4gZXh0cmEgc3BhY2UgYXQgdGhlIGVuZC4KKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpLnRyaW0oKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBHZW5lcmF0ZXMgYSBodW1hbiByZWFkYWJsZSBmb3JtIG9mIHRoZSB1bmtub3duIGZpZWxkcywgdXNlZnVsIGZvciBkZWJ1Z2dpbmcKKyAgICogYW5kIG90aGVyIHB1cnBvc2VzLCB3aXRoIG5vIG5ld2xpbmUgY2hhcmFjdGVycy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNob3J0RGVidWdTdHJpbmcoZmluYWwgVW5rbm93bkZpZWxkU2V0IGZpZWxkcykgeworICAgIHRyeSB7CisgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgIFNJTkdMRV9MSU5FX1BSSU5URVIucHJpbnRVbmtub3duRmllbGRzKGZpZWxkcywgbmV3IFRleHRHZW5lcmF0b3Ioc2IpKTsKKyAgICAgIC8vIFNpbmdsZSBsaW5lIG1vZGUgY3VycmVudGx5IG1pZ2h0IGhhdmUgYW4gZXh0cmEgc3BhY2UgYXQgdGhlIGVuZC4KKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpLnRyaW0oKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBMaWtlIHtAY29kZSBwcmludCgpfSwgYnV0IHdyaXRlcyBkaXJlY3RseSB0byBhIHtAY29kZSBTdHJpbmd9IGFuZAorICAgKiByZXR1cm5zIGl0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgcHJpbnRUb1N0cmluZyhmaW5hbCBNZXNzYWdlT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICB0cnkgeworICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciB0ZXh0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgIHByaW50KG1lc3NhZ2UsIHRleHQpOworICAgICAgcmV0dXJuIHRleHQudG9TdHJpbmcoKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBMaWtlIHtAY29kZSBwcmludCgpfSwgYnV0IHdyaXRlcyBkaXJlY3RseSB0byBhIHtAY29kZSBTdHJpbmd9IGFuZAorICAgKiByZXR1cm5zIGl0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgcHJpbnRUb1N0cmluZyhmaW5hbCBVbmtub3duRmllbGRTZXQgZmllbGRzKSB7CisgICAgdHJ5IHsKKyAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgdGV4dCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICBwcmludChmaWVsZHMsIHRleHQpOworICAgICAgcmV0dXJuIHRleHQudG9TdHJpbmcoKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTYW1lIGFzIHtAY29kZSBwcmludFRvU3RyaW5nKCl9LCBleGNlcHQgdGhhdCBub24tQVNDSUkgY2hhcmFjdGVycworICAgKiBpbiBzdHJpbmcgdHlwZSBmaWVsZHMgYXJlIG5vdCBlc2NhcGVkIGluIGJhY2tzbGFzaCtvY3RhbHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBwcmludFRvVW5pY29kZVN0cmluZyhmaW5hbCBNZXNzYWdlT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICB0cnkgeworICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciB0ZXh0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgIFVOSUNPREVfUFJJTlRFUi5wcmludChtZXNzYWdlLCBuZXcgVGV4dEdlbmVyYXRvcih0ZXh0KSk7CisgICAgICByZXR1cm4gdGV4dC50b1N0cmluZygpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFNhbWUgYXMge0Bjb2RlIHByaW50VG9TdHJpbmcoKX0sIGV4Y2VwdCB0aGF0IG5vbi1BU0NJSSBjaGFyYWN0ZXJzCisgICAqIGluIHN0cmluZyB0eXBlIGZpZWxkcyBhcmUgbm90IGVzY2FwZWQgaW4gYmFja3NsYXNoK29jdGFscy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHByaW50VG9Vbmljb2RlU3RyaW5nKGZpbmFsIFVua25vd25GaWVsZFNldCBmaWVsZHMpIHsKKyAgICB0cnkgeworICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciB0ZXh0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgIFVOSUNPREVfUFJJTlRFUi5wcmludFVua25vd25GaWVsZHMoZmllbGRzLCBuZXcgVGV4dEdlbmVyYXRvcih0ZXh0KSk7CisgICAgICByZXR1cm4gdGV4dC50b1N0cmluZygpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEFwcGVuZGFibGUgb3V0cHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIERFRkFVTFRfUFJJTlRFUi5wcmludEZpZWxkKGZpZWxkLCB2YWx1ZSwgbmV3IFRleHRHZW5lcmF0b3Iob3V0cHV0KSk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIFN0cmluZyBwcmludEZpZWxkVG9TdHJpbmcoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlKSB7CisgICAgdHJ5IHsKKyAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgdGV4dCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICBwcmludEZpZWxkKGZpZWxkLCB2YWx1ZSwgdGV4dCk7CisgICAgICByZXR1cm4gdGV4dC50b1N0cmluZygpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiBnaXZlbiBmaWVsZCB2YWx1ZS4KKyAgICoKKyAgICogQHBhcmFtIGZpZWxkIHRoZSBkZXNjcmlwdG9yIG9mIHRoZSBmaWVsZAorICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZAorICAgKiBAcGFyYW0gb3V0cHV0IHRoZSBvdXRwdXQgdG8gd2hpY2ggdG8gYXBwZW5kIHRoZSBmb3JtYXR0ZWQgdmFsdWUKKyAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHZhbHVlIGlzIG5vdCBhcHByb3ByaWF0ZSBmb3IgdGhlCisgICAqICAgICBnaXZlbiBmaWVsZCBkZXNjcmlwdG9yCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlcmUgaXMgYW4gZXhjZXB0aW9uIHdyaXRpbmcgdG8gdGhlIG91dHB1dAorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50RmllbGRWYWx1ZShmaW5hbCBGaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEFwcGVuZGFibGUgb3V0cHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgREVGQVVMVF9QUklOVEVSLnByaW50RmllbGRWYWx1ZShmaWVsZCwgdmFsdWUsIG5ldyBUZXh0R2VuZXJhdG9yKG91dHB1dCkpOworICB9CisKKyAgLyoqCisgICAqIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiBhbiB1bmtub3duIGZpZWxkLgorICAgKgorICAgKiBAcGFyYW0gdGFnIHRoZSBmaWVsZCdzIHRhZyBudW1iZXIKKyAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQKKyAgICogQHBhcmFtIG91dHB1dCB0aGUgb3V0cHV0IHRvIHdoaWNoIHRvIGFwcGVuZCB0aGUgZm9ybWF0dGVkIHZhbHVlCisgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSBpcyBub3QgYXBwcm9wcmlhdGUgZm9yIHRoZQorICAgKiAgICAgZ2l2ZW4gZmllbGQgZGVzY3JpcHRvcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGFuIGV4Y2VwdGlvbiB3cml0aW5nIHRvIHRoZSBvdXRwdXQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludFVua25vd25GaWVsZFZhbHVlKGZpbmFsIGludCB0YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQXBwZW5kYWJsZSBvdXRwdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcHJpbnRVbmtub3duRmllbGRWYWx1ZSh0YWcsIHZhbHVlLCBuZXcgVGV4dEdlbmVyYXRvcihvdXRwdXQpKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJpbnRVbmtub3duRmllbGRWYWx1ZShmaW5hbCBpbnQgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVGV4dEdlbmVyYXRvciBnZW5lcmF0b3IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN3aXRjaCAoV2lyZUZvcm1hdC5nZXRUYWdXaXJlVHlwZSh0YWcpKSB7CisgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5UOgorICAgICAgICBnZW5lcmF0b3IucHJpbnQodW5zaWduZWRUb1N0cmluZygoTG9uZykgdmFsdWUpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQzMjoKKyAgICAgICAgZ2VuZXJhdG9yLnByaW50KAorICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgoTG9jYWxlKSBudWxsLCAiMHglMDh4IiwgKEludGVnZXIpIHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0ZJWEVENjQ6CisgICAgICAgIGdlbmVyYXRvci5wcmludChTdHJpbmcuZm9ybWF0KChMb2NhbGUpIG51bGwsICIweCUwMTZ4IiwgKExvbmcpIHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQ6CisgICAgICAgIGdlbmVyYXRvci5wcmludCgiXCIiKTsKKyAgICAgICAgZ2VuZXJhdG9yLnByaW50KGVzY2FwZUJ5dGVzKChCeXRlU3RyaW5nKSB2YWx1ZSkpOworICAgICAgICBnZW5lcmF0b3IucHJpbnQoIlwiIik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQOgorICAgICAgICBERUZBVUxUX1BSSU5URVIucHJpbnRVbmtub3duRmllbGRzKChVbmtub3duRmllbGRTZXQpIHZhbHVlLCBnZW5lcmF0b3IpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJhZCB0YWc6ICIgKyB0YWcpOworICAgIH0KKyAgfQorCisgIC8qKiBIZWxwZXIgY2xhc3MgZm9yIGNvbnZlcnRpbmcgcHJvdG9idWZzIHRvIHRleHQuICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFByaW50ZXIgeworICAgIC8qKiBXaGV0aGVyIHRvIG9taXQgbmV3bGluZXMgZnJvbSB0aGUgb3V0cHV0LiAqLworICAgIGJvb2xlYW4gc2luZ2xlTGluZU1vZGUgPSBmYWxzZTsKKworICAgIC8qKiBXaGV0aGVyIHRvIGVzY2FwZSBub24gQVNDSUkgY2hhcmFjdGVycyB3aXRoIGJhY2tzbGFzaCBhbmQgb2N0YWwuICovCisgICAgYm9vbGVhbiBlc2NhcGVOb25Bc2NpaSA9IHRydWU7CisKKyAgICBwcml2YXRlIFByaW50ZXIoKSB7fQorCisgICAgLyoqIFNldHRlciBvZiBzaW5nbGVMaW5lTW9kZSAqLworICAgIHByaXZhdGUgUHJpbnRlciBzZXRTaW5nbGVMaW5lTW9kZShib29sZWFuIHNpbmdsZUxpbmVNb2RlKSB7CisgICAgICB0aGlzLnNpbmdsZUxpbmVNb2RlID0gc2luZ2xlTGluZU1vZGU7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0dGVyIG9mIGVzY2FwZU5vbkFzY2lpICovCisgICAgcHJpdmF0ZSBQcmludGVyIHNldEVzY2FwZU5vbkFzY2lpKGJvb2xlYW4gZXNjYXBlTm9uQXNjaWkpIHsKKyAgICAgIHRoaXMuZXNjYXBlTm9uQXNjaWkgPSBlc2NhcGVOb25Bc2NpaTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcmludCgKKyAgICAgICAgZmluYWwgTWVzc2FnZU9yQnVpbGRlciBtZXNzYWdlLCBmaW5hbCBUZXh0R2VuZXJhdG9yIGdlbmVyYXRvcikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGZvciAoTWFwLkVudHJ5PEZpZWxkRGVzY3JpcHRvciwgT2JqZWN0PiBmaWVsZAorICAgICAgICAgIDogbWVzc2FnZS5nZXRBbGxGaWVsZHMoKS5lbnRyeVNldCgpKSB7CisgICAgICAgIHByaW50RmllbGQoZmllbGQuZ2V0S2V5KCksIGZpZWxkLmdldFZhbHVlKCksIGdlbmVyYXRvcik7CisgICAgICB9CisgICAgICBwcmludFVua25vd25GaWVsZHMobWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCksIGdlbmVyYXRvcik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHByaW50RmllbGQoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLCBmaW5hbCBPYmplY3QgdmFsdWUsCisgICAgICAgIGZpbmFsIFRleHRHZW5lcmF0b3IgZ2VuZXJhdG9yKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGZpZWxkLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAvLyBSZXBlYXRlZCBmaWVsZC4gIFByaW50IGVhY2ggZWxlbWVudC4KKyAgICAgICAgZm9yIChPYmplY3QgZWxlbWVudCA6IChMaXN0PD8+KSB2YWx1ZSkgeworICAgICAgICAgIHByaW50U2luZ2xlRmllbGQoZmllbGQsIGVsZW1lbnQsIGdlbmVyYXRvcik7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50U2luZ2xlRmllbGQoZmllbGQsIHZhbHVlLCBnZW5lcmF0b3IpOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcmludFNpbmdsZUZpZWxkKGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVGV4dEdlbmVyYXRvciBnZW5lcmF0b3IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChmaWVsZC5pc0V4dGVuc2lvbigpKSB7CisgICAgICAgIGdlbmVyYXRvci5wcmludCgiWyIpOworICAgICAgICAvLyBXZSBzcGVjaWFsLWNhc2UgTWVzc2FnZVNldCBlbGVtZW50cyBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIHByb3RvMS4KKyAgICAgICAgaWYgKGZpZWxkLmdldENvbnRhaW5pbmdUeXBlKCkuZ2V0T3B0aW9ucygpLmdldE1lc3NhZ2VTZXRXaXJlRm9ybWF0KCkKKyAgICAgICAgICAgICYmIChmaWVsZC5nZXRUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLlR5cGUuTUVTU0FHRSkKKyAgICAgICAgICAgICYmIChmaWVsZC5pc09wdGlvbmFsKCkpCisgICAgICAgICAgICAvLyBvYmplY3QgZXF1YWxpdHkKKyAgICAgICAgICAgICYmIChmaWVsZC5nZXRFeHRlbnNpb25TY29wZSgpID09IGZpZWxkLmdldE1lc3NhZ2VUeXBlKCkpKSB7CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KGZpZWxkLmdldE1lc3NhZ2VUeXBlKCkuZ2V0RnVsbE5hbWUoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KGZpZWxkLmdldEZ1bGxOYW1lKCkpOworICAgICAgICB9CisgICAgICAgIGdlbmVyYXRvci5wcmludCgiXSIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGZpZWxkLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5HUk9VUCkgeworICAgICAgICAgIC8vIEdyb3VwcyBtdXN0IGJlIHNlcmlhbGl6ZWQgd2l0aCB0aGVpciBvcmlnaW5hbCBjYXBpdGFsaXphdGlvbi4KKyAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoZmllbGQuZ2V0TWVzc2FnZVR5cGUoKS5nZXROYW1lKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5wcmludChmaWVsZC5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgIGlmIChzaW5nbGVMaW5lTW9kZSkgeworICAgICAgICAgIGdlbmVyYXRvci5wcmludCgiIHsgIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCIge1xuIik7CisgICAgICAgICAgZ2VuZXJhdG9yLmluZGVudCgpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBnZW5lcmF0b3IucHJpbnQoIjogIik7CisgICAgICB9CisKKyAgICAgIHByaW50RmllbGRWYWx1ZShmaWVsZCwgdmFsdWUsIGdlbmVyYXRvcik7CisKKyAgICAgIGlmIChmaWVsZC5nZXRKYXZhVHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFKSB7CisgICAgICAgIGlmIChzaW5nbGVMaW5lTW9kZSkgeworICAgICAgICAgIGdlbmVyYXRvci5wcmludCgifSAiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnZW5lcmF0b3Iub3V0ZGVudCgpOworICAgICAgICAgIGdlbmVyYXRvci5wcmludCgifVxuIik7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChzaW5nbGVMaW5lTW9kZSkgeworICAgICAgICAgIGdlbmVyYXRvci5wcmludCgiICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5wcmludCgiXG4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcmludEZpZWxkVmFsdWUoZmluYWwgRmllbGREZXNjcmlwdG9yIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVGV4dEdlbmVyYXRvciBnZW5lcmF0b3IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgc3dpdGNoIChmaWVsZC5nZXRUeXBlKCkpIHsKKyAgICAgICAgY2FzZSBJTlQzMjoKKyAgICAgICAgY2FzZSBTSU5UMzI6CisgICAgICAgIGNhc2UgU0ZJWEVEMzI6CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCgoSW50ZWdlcikgdmFsdWUpLnRvU3RyaW5nKCkpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgSU5UNjQ6CisgICAgICAgIGNhc2UgU0lOVDY0OgorICAgICAgICBjYXNlIFNGSVhFRDY0OgorICAgICAgICAgIGdlbmVyYXRvci5wcmludCgoKExvbmcpIHZhbHVlKS50b1N0cmluZygpKTsKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEJPT0w6CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCgoQm9vbGVhbikgdmFsdWUpLnRvU3RyaW5nKCkpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRkxPQVQ6CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCgoRmxvYXQpIHZhbHVlKS50b1N0cmluZygpKTsKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIERPVUJMRToKKyAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoKChEb3VibGUpIHZhbHVlKS50b1N0cmluZygpKTsKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIFVJTlQzMjoKKyAgICAgICAgY2FzZSBGSVhFRDMyOgorICAgICAgICAgIGdlbmVyYXRvci5wcmludCh1bnNpZ25lZFRvU3RyaW5nKChJbnRlZ2VyKSB2YWx1ZSkpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgVUlOVDY0OgorICAgICAgICBjYXNlIEZJWEVENjQ6CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KHVuc2lnbmVkVG9TdHJpbmcoKExvbmcpIHZhbHVlKSk7CisgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBTVFJJTkc6CisgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCJcIiIpOworICAgICAgICAgIGdlbmVyYXRvci5wcmludChlc2NhcGVOb25Bc2NpaQorICAgICAgICAgICAgICA/IGVzY2FwZVRleHQoKFN0cmluZykgdmFsdWUpCisgICAgICAgICAgICAgIDogZXNjYXBlRG91YmxlUXVvdGVzQW5kQmFja3NsYXNoZXMoKFN0cmluZykgdmFsdWUpCisgICAgICAgICAgICAgICAgICAucmVwbGFjZSgiXG4iLCAiXFxuIikpOworICAgICAgICAgIGdlbmVyYXRvci5wcmludCgiXCIiKTsKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEJZVEVTOgorICAgICAgICAgIGdlbmVyYXRvci5wcmludCgiXCIiKTsKKyAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCeXRlU3RyaW5nKSB7CisgICAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoZXNjYXBlQnl0ZXMoKEJ5dGVTdHJpbmcpIHZhbHVlKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdlbmVyYXRvci5wcmludChlc2NhcGVCeXRlcygoYnl0ZVtdKSB2YWx1ZSkpOworICAgICAgICAgIH0KKyAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoIlwiIik7CisgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBFTlVNOgorICAgICAgICAgIGdlbmVyYXRvci5wcmludCgoKEVudW1WYWx1ZURlc2NyaXB0b3IpIHZhbHVlKS5nZXROYW1lKCkpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgTUVTU0FHRToKKyAgICAgICAgY2FzZSBHUk9VUDoKKyAgICAgICAgICBwcmludCgoTWVzc2FnZSkgdmFsdWUsIGdlbmVyYXRvcik7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHByaW50VW5rbm93bkZpZWxkcyhmaW5hbCBVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFRleHRHZW5lcmF0b3IgZ2VuZXJhdG9yKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGZvciAoTWFwLkVudHJ5PEludGVnZXIsIFVua25vd25GaWVsZFNldC5GaWVsZD4gZW50cnkgOgorICAgICAgICAgICAgICAgdW5rbm93bkZpZWxkcy5hc01hcCgpLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgZmluYWwgaW50IG51bWJlciA9IGVudHJ5LmdldEtleSgpOworICAgICAgICBmaW5hbCBVbmtub3duRmllbGRTZXQuRmllbGQgZmllbGQgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICBwcmludFVua25vd25GaWVsZChudW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5ULAorICAgICAgICAgICAgZmllbGQuZ2V0VmFyaW50TGlzdCgpLCBnZW5lcmF0b3IpOworICAgICAgICBwcmludFVua25vd25GaWVsZChudW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQzMiwKKyAgICAgICAgICAgIGZpZWxkLmdldEZpeGVkMzJMaXN0KCksIGdlbmVyYXRvcik7CisgICAgICAgIHByaW50VW5rbm93bkZpZWxkKG51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9GSVhFRDY0LAorICAgICAgICAgICAgZmllbGQuZ2V0Rml4ZWQ2NExpc3QoKSwgZ2VuZXJhdG9yKTsKKyAgICAgICAgcHJpbnRVbmtub3duRmllbGQobnVtYmVyLCBXaXJlRm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsCisgICAgICAgICAgICBmaWVsZC5nZXRMZW5ndGhEZWxpbWl0ZWRMaXN0KCksIGdlbmVyYXRvcik7CisgICAgICAgIGZvciAoZmluYWwgVW5rbm93bkZpZWxkU2V0IHZhbHVlIDogZmllbGQuZ2V0R3JvdXBMaXN0KCkpIHsKKyAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoZW50cnkuZ2V0S2V5KCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgaWYgKHNpbmdsZUxpbmVNb2RlKSB7CisgICAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoIiB7ICIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnZW5lcmF0b3IucHJpbnQoIiB7XG4iKTsKKyAgICAgICAgICAgIGdlbmVyYXRvci5pbmRlbnQoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcHJpbnRVbmtub3duRmllbGRzKHZhbHVlLCBnZW5lcmF0b3IpOworICAgICAgICAgIGlmIChzaW5nbGVMaW5lTW9kZSkgeworICAgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCJ9ICIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnZW5lcmF0b3Iub3V0ZGVudCgpOworICAgICAgICAgICAgZ2VuZXJhdG9yLnByaW50KCJ9XG4iKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcHJpbnRVbmtub3duRmllbGQoZmluYWwgaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHdpcmVUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PD8+IHZhbHVlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVGV4dEdlbmVyYXRvciBnZW5lcmF0b3IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmb3IgKGZpbmFsIE9iamVjdCB2YWx1ZSA6IHZhbHVlcykgeworICAgICAgICBnZW5lcmF0b3IucHJpbnQoU3RyaW5nLnZhbHVlT2YobnVtYmVyKSk7CisgICAgICAgIGdlbmVyYXRvci5wcmludCgiOiAiKTsKKyAgICAgICAgcHJpbnRVbmtub3duRmllbGRWYWx1ZSh3aXJlVHlwZSwgdmFsdWUsIGdlbmVyYXRvcik7CisgICAgICAgIGdlbmVyYXRvci5wcmludChzaW5nbGVMaW5lTW9kZSA/ICIgIiA6ICJcbiIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKiBDb252ZXJ0IGFuIHVuc2lnbmVkIDMyLWJpdCBpbnRlZ2VyIHRvIGEgc3RyaW5nLiAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyB1bnNpZ25lZFRvU3RyaW5nKGZpbmFsIGludCB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSA+PSAwKSB7CisgICAgICByZXR1cm4gSW50ZWdlci50b1N0cmluZyh2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBMb25nLnRvU3RyaW5nKHZhbHVlICYgMHgwMDAwMDAwMEZGRkZGRkZGTCk7CisgICAgfQorICB9CisKKyAgLyoqIENvbnZlcnQgYW4gdW5zaWduZWQgNjQtYml0IGludGVnZXIgdG8gYSBzdHJpbmcuICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHVuc2lnbmVkVG9TdHJpbmcoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSA+PSAwKSB7CisgICAgICByZXR1cm4gTG9uZy50b1N0cmluZyh2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFB1bGwgb2ZmIHRoZSBtb3N0LXNpZ25pZmljYW50IGJpdCBzbyB0aGF0IEJpZ0ludGVnZXIgZG9lc24ndCB0aGluaworICAgICAgLy8gdGhlIG51bWJlciBpcyBuZWdhdGl2ZSwgdGhlbiBzZXQgaXQgYWdhaW4gdXNpbmcgc2V0Qml0KCkuCisgICAgICByZXR1cm4gQmlnSW50ZWdlci52YWx1ZU9mKHZhbHVlICYgMHg3RkZGRkZGRkZGRkZGRkZGTCkKKyAgICAgICAgICAgICAgICAgICAgICAgLnNldEJpdCg2MykudG9TdHJpbmcoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQW4gaW5uZXIgY2xhc3MgZm9yIHdyaXRpbmcgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFRleHRHZW5lcmF0b3IgeworICAgIHByaXZhdGUgZmluYWwgQXBwZW5kYWJsZSBvdXRwdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdCdWlsZGVyIGluZGVudCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgcHJpdmF0ZSBib29sZWFuIGF0U3RhcnRPZkxpbmUgPSB0cnVlOworCisgICAgcHJpdmF0ZSBUZXh0R2VuZXJhdG9yKGZpbmFsIEFwcGVuZGFibGUgb3V0cHV0KSB7CisgICAgICB0aGlzLm91dHB1dCA9IG91dHB1dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRlbnQgdGV4dCBieSB0d28gc3BhY2VzLiAgQWZ0ZXIgY2FsbGluZyBJbmRlbnQoKSwgdHdvIHNwYWNlcyB3aWxsIGJlCisgICAgICogaW5zZXJ0ZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIGxpbmUgb2YgdGV4dC4gIEluZGVudCgpIG1heSBiZSBjYWxsZWQKKyAgICAgKiBtdWx0aXBsZSB0aW1lcyB0byBwcm9kdWNlIGRlZXBlciBpbmRlbnRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGluZGVudCgpIHsKKyAgICAgIGluZGVudC5hcHBlbmQoIiAgIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVkdWNlcyB0aGUgY3VycmVudCBpbmRlbnQgbGV2ZWwgYnkgdHdvIHNwYWNlcywgb3IgY3Jhc2hlcyBpZiB0aGUgaW5kZW50CisgICAgICogbGV2ZWwgaXMgemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBvdXRkZW50KCkgeworICAgICAgZmluYWwgaW50IGxlbmd0aCA9IGluZGVudC5sZW5ndGgoKTsKKyAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIiBPdXRkZW50KCkgd2l0aG91dCBtYXRjaGluZyBJbmRlbnQoKS4iKTsKKyAgICAgIH0KKyAgICAgIGluZGVudC5kZWxldGUobGVuZ3RoIC0gMiwgbGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludCB0ZXh0IHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGZpbmFsIENoYXJTZXF1ZW5jZSB0ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgZmluYWwgaW50IHNpemUgPSB0ZXh0Lmxlbmd0aCgpOworICAgICAgaW50IHBvcyA9IDA7CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgIGlmICh0ZXh0LmNoYXJBdChpKSA9PSAnXG4nKSB7CisgICAgICAgICAgd3JpdGUodGV4dC5zdWJTZXF1ZW5jZShwb3MsIGkgKyAxKSk7CisgICAgICAgICAgcG9zID0gaSArIDE7CisgICAgICAgICAgYXRTdGFydE9mTGluZSA9IHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHdyaXRlKHRleHQuc3ViU2VxdWVuY2UocG9zLCBzaXplKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlKGZpbmFsIENoYXJTZXF1ZW5jZSBkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGRhdGEubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBpZiAoYXRTdGFydE9mTGluZSkgeworICAgICAgICBhdFN0YXJ0T2ZMaW5lID0gZmFsc2U7CisgICAgICAgIG91dHB1dC5hcHBlbmQoaW5kZW50KTsKKyAgICAgIH0KKyAgICAgIG91dHB1dC5hcHBlbmQoZGF0YSk7CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gUGFyc2luZworCisgIC8qKgorICAgKiBSZXByZXNlbnRzIGEgc3RyZWFtIG9mIHRva2VucyBwYXJzZWQgZnJvbSBhIHtAY29kZSBTdHJpbmd9LgorICAgKgorICAgKiA8cD5UaGUgSmF2YSBzdGFuZGFyZCBsaWJyYXJ5IHByb3ZpZGVzIG1hbnkgY2xhc3NlcyB0aGF0IHlvdSBtaWdodCB0aGluaworICAgKiB3b3VsZCBiZSB1c2VmdWwgZm9yIGltcGxlbWVudGluZyB0aGlzLCBidXQgYXJlbid0LiAgRm9yIGV4YW1wbGU6CisgICAqCisgICAqIDx1bD4KKyAgICogPGxpPntAY29kZSBqYXZhLmlvLlN0cmVhbVRva2VuaXplcn06ICBUaGlzIGFsbW9zdCBkb2VzIHdoYXQgd2Ugd2FudCAtLSBvciwKKyAgICogICBhdCBsZWFzdCwgc29tZXRoaW5nIHRoYXQgd291bGQgZ2V0IHVzIGNsb3NlIHRvIHdoYXQgd2Ugd2FudCAtLSBleGNlcHQKKyAgICogICBmb3Igb25lIGZhdGFsIGZsYXc6ICBJdCBhdXRvbWF0aWNhbGx5IHVuLWVzY2FwZXMgc3RyaW5ncyB1c2luZyBKYXZhCisgICAqICAgZXNjYXBlIHNlcXVlbmNlcywgd2hpY2ggZG8gbm90IGluY2x1ZGUgYWxsIHRoZSBlc2NhcGUgc2VxdWVuY2VzIHdlCisgICAqICAgbmVlZCB0byBzdXBwb3J0IChlLmcuICdceCcpLgorICAgKiA8bGk+e0Bjb2RlIGphdmEudXRpbC5TY2FubmVyfTogIFRoaXMgc2VlbXMgbGlrZSBhIGdyZWF0IHdheSBhdCBsZWFzdCB0bworICAgKiAgIHBhcnNlIHJlZ3VsYXIgZXhwcmVzc2lvbnMgb3V0IG9mIGEgc3RyZWFtIChzbyB3ZSB3b3VsZG4ndCBoYXZlIHRvIGxvYWQKKyAgICogICB0aGUgZW50aXJlIGlucHV0IGludG8gYSBzaW5nbGUgc3RyaW5nIGJlZm9yZSBwYXJzaW5nKS4gIFNhZGx5LAorICAgKiAgIHtAY29kZSBTY2FubmVyfSByZXF1aXJlcyB0aGF0IHRva2VucyBiZSBkZWxpbWl0ZWQgd2l0aCBzb21lIGRlbGltaXRlci4KKyAgICogICBUaHVzLCBhbHRob3VnaCB0aGUgdGV4dCAiZm9vOiIgc2hvdWxkIHBhcnNlIHRvIHR3byB0b2tlbnMgKCJmb28iIGFuZAorICAgKiAgICI6IiksIHtAY29kZSBTY2FubmVyfSB3b3VsZCByZWNvZ25pemUgaXQgb25seSBhcyBhIHNpbmdsZSB0b2tlbi4KKyAgICogICBGdXJ0aGVybW9yZSwge0Bjb2RlIFNjYW5uZXJ9IHByb3ZpZGVzIG5vIHdheSB0byBpbnNwZWN0IHRoZSBjb250ZW50cworICAgKiAgIG9mIGRlbGltaXRlcnMsIG1ha2luZyBpdCBpbXBvc3NpYmxlIHRvIGtlZXAgdHJhY2sgb2YgbGluZSBhbmQgY29sdW1uCisgICAqICAgbnVtYmVycy4KKyAgICogPC91bD4KKyAgICoKKyAgICogPHA+THVja2lseSwgSmF2YSdzIHJlZ3VsYXIgZXhwcmVzc2lvbiBzdXBwb3J0IGRvZXMgbWFuYWdlIHRvIGJlIHVzZWZ1bCB0bworICAgKiB1cy4gIChCYXJlbHk6ICBXZSBuZWVkIHtAY29kZSBNYXRjaGVyLnVzZVBhdHRlcm4oKX0sIHdoaWNoIGlzIG5ldyBpbgorICAgKiBKYXZhIDEuNS4pICBTbywgd2UgY2FuIHVzZSB0aGF0LCBhdCBsZWFzdC4gIFVuZm9ydHVuYXRlbHksIHRoaXMgaW1wbGllcworICAgKiB0aGF0IHdlIG5lZWQgdG8gaGF2ZSB0aGUgZW50aXJlIGlucHV0IGluIG9uZSBjb250aWd1b3VzIHN0cmluZy4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFRva2VuaXplciB7CisgICAgcHJpdmF0ZSBmaW5hbCBDaGFyU2VxdWVuY2UgdGV4dDsKKyAgICBwcml2YXRlIGZpbmFsIE1hdGNoZXIgbWF0Y2hlcjsKKyAgICBwcml2YXRlIFN0cmluZyBjdXJyZW50VG9rZW47CisKKyAgICAvLyBUaGUgY2hhcmFjdGVyIGluZGV4IHdpdGhpbiB0aGlzLnRleHQgYXQgd2hpY2ggdGhlIGN1cnJlbnQgdG9rZW4gYmVnaW5zLgorICAgIHByaXZhdGUgaW50IHBvcyA9IDA7CisKKyAgICAvLyBUaGUgbGluZSBhbmQgY29sdW1uIG51bWJlcnMgb2YgdGhlIGN1cnJlbnQgdG9rZW4uCisgICAgcHJpdmF0ZSBpbnQgbGluZSA9IDA7CisgICAgcHJpdmF0ZSBpbnQgY29sdW1uID0gMDsKKworICAgIC8vIFRoZSBsaW5lIGFuZCBjb2x1bW4gbnVtYmVycyBvZiB0aGUgcHJldmlvdXMgdG9rZW4gKGFsbG93cyB0aHJvd2luZworICAgIC8vIGVycm9ycyAqYWZ0ZXIqIGNvbnN1bWluZykuCisgICAgcHJpdmF0ZSBpbnQgcHJldmlvdXNMaW5lID0gMDsKKyAgICBwcml2YXRlIGludCBwcmV2aW91c0NvbHVtbiA9IDA7CisKKyAgICAvLyBXZSB1c2UgcG9zc2Vzc2l2ZSBxdWFudGlmaWVycyAoKisgYW5kICsrKSBiZWNhdXNlIG90aGVyd2lzZSB0aGUgSmF2YQorICAgIC8vIHJlZ2V4IG1hdGNoZXIgaGFzIHN0YWNrIG92ZXJmbG93cyBvbiBsYXJnZSBpbnB1dHMuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBXSElURVNQQUNFID0KKyAgICAgIFBhdHRlcm4uY29tcGlsZSgiKFxcc3woIy4qJCkpKysiLCBQYXR0ZXJuLk1VTFRJTElORSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBUT0tFTiA9IFBhdHRlcm4uY29tcGlsZSgKKyAgICAgICJbYS16QS1aX11bMC05YS16QS1aXystXSorfCIgKyAgICAgICAgICAgICAgICAvLyBhbiBpZGVudGlmaWVyCisgICAgICAiWy5dP1swLTkrLV1bMC05YS16QS1aXy4rLV0qK3wiICsgICAgICAgICAgICAgLy8gYSBudW1iZXIKKyAgICAgICJcIihbXlwiXG5cXFxcXXxcXFxcLikqKyhcInxcXFxcPyQpfCIgKyAgICAgICAvLyBhIGRvdWJsZS1xdW90ZWQgc3RyaW5nCisgICAgICAiXCcoW15cJ1xuXFxcXF18XFxcXC4pKisoXCd8XFxcXD8kKSIsICAgICAgICAgLy8gYSBzaW5nbGUtcXVvdGVkIHN0cmluZworICAgICAgUGF0dGVybi5NVUxUSUxJTkUpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBET1VCTEVfSU5GSU5JVFkgPSBQYXR0ZXJuLmNvbXBpbGUoCisgICAgICAiLT9pbmYoaW5pdHkpPyIsCisgICAgICBQYXR0ZXJuLkNBU0VfSU5TRU5TSVRJVkUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gRkxPQVRfSU5GSU5JVFkgPSBQYXR0ZXJuLmNvbXBpbGUoCisgICAgICAiLT9pbmYoaW5pdHkpP2Y/IiwKKyAgICAgIFBhdHRlcm4uQ0FTRV9JTlNFTlNJVElWRSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBGTE9BVF9OQU4gPSBQYXR0ZXJuLmNvbXBpbGUoCisgICAgICAibmFuZj8iLAorICAgICAgUGF0dGVybi5DQVNFX0lOU0VOU0lUSVZFKTsKKworICAgIC8qKiBDb25zdHJ1Y3QgYSB0b2tlbml6ZXIgdGhhdCBwYXJzZXMgdG9rZW5zIGZyb20gdGhlIGdpdmVuIHRleHQuICovCisgICAgcHJpdmF0ZSBUb2tlbml6ZXIoZmluYWwgQ2hhclNlcXVlbmNlIHRleHQpIHsKKyAgICAgIHRoaXMudGV4dCA9IHRleHQ7CisgICAgICB0aGlzLm1hdGNoZXIgPSBXSElURVNQQUNFLm1hdGNoZXIodGV4dCk7CisgICAgICBza2lwV2hpdGVzcGFjZSgpOworICAgICAgbmV4dFRva2VuKCk7CisgICAgfQorCisgICAgLyoqIEFyZSB3ZSBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dD8gKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhdEVuZCgpIHsKKyAgICAgIHJldHVybiBjdXJyZW50VG9rZW4ubGVuZ3RoKCkgPT0gMDsKKyAgICB9CisKKyAgICAvKiogQWR2YW5jZSB0byB0aGUgbmV4dCB0b2tlbi4gKi8KKyAgICBwdWJsaWMgdm9pZCBuZXh0VG9rZW4oKSB7CisgICAgICBwcmV2aW91c0xpbmUgPSBsaW5lOworICAgICAgcHJldmlvdXNDb2x1bW4gPSBjb2x1bW47CisKKyAgICAgIC8vIEFkdmFuY2UgdGhlIGxpbmUgY291bnRlciB0byB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICAgIHdoaWxlIChwb3MgPCBtYXRjaGVyLnJlZ2lvblN0YXJ0KCkpIHsKKyAgICAgICAgaWYgKHRleHQuY2hhckF0KHBvcykgPT0gJ1xuJykgeworICAgICAgICAgICsrbGluZTsKKyAgICAgICAgICBjb2x1bW4gPSAwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICsrY29sdW1uOworICAgICAgICB9CisgICAgICAgICsrcG9zOworICAgICAgfQorCisgICAgICAvLyBNYXRjaCB0aGUgbmV4dCB0b2tlbi4KKyAgICAgIGlmIChtYXRjaGVyLnJlZ2lvblN0YXJ0KCkgPT0gbWF0Y2hlci5yZWdpb25FbmQoKSkgeworICAgICAgICAvLyBFT0YKKyAgICAgICAgY3VycmVudFRva2VuID0gIiI7CisgICAgICB9IGVsc2UgeworICAgICAgICBtYXRjaGVyLnVzZVBhdHRlcm4oVE9LRU4pOworICAgICAgICBpZiAobWF0Y2hlci5sb29raW5nQXQoKSkgeworICAgICAgICAgIGN1cnJlbnRUb2tlbiA9IG1hdGNoZXIuZ3JvdXAoKTsKKyAgICAgICAgICBtYXRjaGVyLnJlZ2lvbihtYXRjaGVyLmVuZCgpLCBtYXRjaGVyLnJlZ2lvbkVuZCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBUYWtlIG9uZSBjaGFyYWN0ZXIuCisgICAgICAgICAgY3VycmVudFRva2VuID0gU3RyaW5nLnZhbHVlT2YodGV4dC5jaGFyQXQocG9zKSk7CisgICAgICAgICAgbWF0Y2hlci5yZWdpb24ocG9zICsgMSwgbWF0Y2hlci5yZWdpb25FbmQoKSk7CisgICAgICAgIH0KKworICAgICAgICBza2lwV2hpdGVzcGFjZSgpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXAgb3ZlciBhbnkgd2hpdGVzcGFjZSBzbyB0aGF0IHRoZSBtYXRjaGVyIHJlZ2lvbiBzdGFydHMgYXQgdGhlIG5leHQKKyAgICAgKiB0b2tlbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2tpcFdoaXRlc3BhY2UoKSB7CisgICAgICBtYXRjaGVyLnVzZVBhdHRlcm4oV0hJVEVTUEFDRSk7CisgICAgICBpZiAobWF0Y2hlci5sb29raW5nQXQoKSkgeworICAgICAgICBtYXRjaGVyLnJlZ2lvbihtYXRjaGVyLmVuZCgpLCBtYXRjaGVyLnJlZ2lvbkVuZCgpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbmV4dCB0b2tlbiBleGFjdGx5IG1hdGNoZXMge0Bjb2RlIHRva2VufSwgY29uc3VtZSBpdCBhbmQgcmV0dXJuCisgICAgICoge0Bjb2RlIHRydWV9LiAgT3RoZXJ3aXNlLCByZXR1cm4ge0Bjb2RlIGZhbHNlfSB3aXRob3V0IGRvaW5nIGFueXRoaW5nLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRyeUNvbnN1bWUoZmluYWwgU3RyaW5nIHRva2VuKSB7CisgICAgICBpZiAoY3VycmVudFRva2VuLmVxdWFscyh0b2tlbikpIHsKKyAgICAgICAgbmV4dFRva2VuKCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGV4YWN0bHkgbWF0Y2hlcyB7QGNvZGUgdG9rZW59LCBjb25zdW1lIGl0LiAgT3RoZXJ3aXNlLAorICAgICAqIHRocm93IGEge0BsaW5rIFBhcnNlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25zdW1lKGZpbmFsIFN0cmluZyB0b2tlbikgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIGlmICghdHJ5Q29uc3VtZSh0b2tlbikpIHsKKyAgICAgICAgdGhyb3cgcGFyc2VFeGNlcHRpb24oIkV4cGVjdGVkIFwiIiArIHRva2VuICsgIlwiLiIpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHRva2VuIGlzIGFuIGludGVnZXIsIGJ1dCBkb2VzCisgICAgICogbm90IGNvbnN1bWUgaXQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbG9va2luZ0F0SW50ZWdlcigpIHsKKyAgICAgIGlmIChjdXJyZW50VG9rZW4ubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGZpbmFsIGNoYXIgYyA9IGN1cnJlbnRUb2tlbi5jaGFyQXQoMCk7CisgICAgICByZXR1cm4gKCcwJyA8PSBjICYmIGMgPD0gJzknKQorICAgICAgICAgIHx8IGMgPT0gJy0nIHx8IGMgPT0gJysnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBjdXJyZW50IHRva2VuJ3MgdGV4dCBpcyBlcXVhbCB0byB0aGF0CisgICAgICogc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGxvb2tpbmdBdChTdHJpbmcgdGV4dCkgeworICAgICAgcmV0dXJuIGN1cnJlbnRUb2tlbi5lcXVhbHModGV4dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5leHQgdG9rZW4gaXMgYW4gaWRlbnRpZmllciwgY29uc3VtZSBpdCBhbmQgcmV0dXJuIGl0cyB2YWx1ZS4KKyAgICAgKiBPdGhlcndpc2UsIHRocm93IGEge0BsaW5rIFBhcnNlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGNvbnN1bWVJZGVudGlmaWVyKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3VycmVudFRva2VuLmxlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgZmluYWwgY2hhciBjID0gY3VycmVudFRva2VuLmNoYXJBdChpKTsKKyAgICAgICAgaWYgKCgnYScgPD0gYyAmJiBjIDw9ICd6JykKKyAgICAgICAgICAgIHx8ICgnQScgPD0gYyAmJiBjIDw9ICdaJykKKyAgICAgICAgICAgIHx8ICgnMCcgPD0gYyAmJiBjIDw9ICc5JykKKyAgICAgICAgICAgIHx8IChjID09ICdfJykgfHwgKGMgPT0gJy4nKSkgeworICAgICAgICAgIC8vIE9LCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGhyb3cgcGFyc2VFeGNlcHRpb24oCisgICAgICAgICAgICAgICJFeHBlY3RlZCBpZGVudGlmaWVyLiBGb3VuZCAnIiArIGN1cnJlbnRUb2tlbiArICInIik7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgZmluYWwgU3RyaW5nIHJlc3VsdCA9IGN1cnJlbnRUb2tlbjsKKyAgICAgIG5leHRUb2tlbigpOworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbmV4dCB0b2tlbiBpcyBhbiBpZGVudGlmaWVyLCBjb25zdW1lIGl0IGFuZCByZXR1cm4ge0Bjb2RlIHRydWV9LgorICAgICAqIE90aGVyd2lzZSwgcmV0dXJuIHtAY29kZSBmYWxzZX0gd2l0aG91dCBkb2luZyBhbnl0aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB0cnlDb25zdW1lSWRlbnRpZmllcigpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGNvbnN1bWVJZGVudGlmaWVyKCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5leHQgdG9rZW4gaXMgYSAzMi1iaXQgc2lnbmVkIGludGVnZXIsIGNvbnN1bWUgaXQgYW5kIHJldHVybiBpdHMKKyAgICAgKiB2YWx1ZS4gIE90aGVyd2lzZSwgdGhyb3cgYSB7QGxpbmsgUGFyc2VFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29uc3VtZUludDMyKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIGludCByZXN1bHQgPSBwYXJzZUludDMyKGN1cnJlbnRUb2tlbik7CisgICAgICAgIG5leHRUb2tlbigpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgaW50ZWdlclBhcnNlRXhjZXB0aW9uKGUpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGlzIGEgMzItYml0IHVuc2lnbmVkIGludGVnZXIsIGNvbnN1bWUgaXQgYW5kIHJldHVybiBpdHMKKyAgICAgKiB2YWx1ZS4gIE90aGVyd2lzZSwgdGhyb3cgYSB7QGxpbmsgUGFyc2VFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29uc3VtZVVJbnQzMigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBmaW5hbCBpbnQgcmVzdWx0ID0gcGFyc2VVSW50MzIoY3VycmVudFRva2VuKTsKKyAgICAgICAgbmV4dFRva2VuKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBpbnRlZ2VyUGFyc2VFeGNlcHRpb24oZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5leHQgdG9rZW4gaXMgYSA2NC1iaXQgc2lnbmVkIGludGVnZXIsIGNvbnN1bWUgaXQgYW5kIHJldHVybiBpdHMKKyAgICAgKiB2YWx1ZS4gIE90aGVyd2lzZSwgdGhyb3cgYSB7QGxpbmsgUGFyc2VFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGNvbnN1bWVJbnQ2NCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBmaW5hbCBsb25nIHJlc3VsdCA9IHBhcnNlSW50NjQoY3VycmVudFRva2VuKTsKKyAgICAgICAgbmV4dFRva2VuKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBpbnRlZ2VyUGFyc2VFeGNlcHRpb24oZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5leHQgdG9rZW4gaXMgYSA2NC1iaXQgc2lnbmVkIGludGVnZXIsIGNvbnN1bWUgaXQgYW5kIHJldHVybgorICAgICAqIHtAY29kZSB0cnVlfS4gIE90aGVyd2lzZSwgcmV0dXJuIHtAY29kZSBmYWxzZX0gd2l0aG91dCBkb2luZyBhbnl0aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB0cnlDb25zdW1lSW50NjQoKSB7CisgICAgICB0cnkgeworICAgICAgICBjb25zdW1lSW50NjQoKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbmV4dCB0b2tlbiBpcyBhIDY0LWJpdCB1bnNpZ25lZCBpbnRlZ2VyLCBjb25zdW1lIGl0IGFuZCByZXR1cm4gaXRzCisgICAgICogdmFsdWUuICBPdGhlcndpc2UsIHRocm93IGEge0BsaW5rIFBhcnNlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBjb25zdW1lVUludDY0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIGxvbmcgcmVzdWx0ID0gcGFyc2VVSW50NjQoY3VycmVudFRva2VuKTsKKyAgICAgICAgbmV4dFRva2VuKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBpbnRlZ2VyUGFyc2VFeGNlcHRpb24oZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5leHQgdG9rZW4gaXMgYSA2NC1iaXQgdW5zaWduZWQgaW50ZWdlciwgY29uc3VtZSBpdCBhbmQgcmV0dXJuCisgICAgICoge0Bjb2RlIHRydWV9LiAgT3RoZXJ3aXNlLCByZXR1cm4ge0Bjb2RlIGZhbHNlfSB3aXRob3V0IGRvaW5nIGFueXRoaW5nLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRyeUNvbnN1bWVVSW50NjQoKSB7CisgICAgICB0cnkgeworICAgICAgICBjb25zdW1lVUludDY0KCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5leHQgdG9rZW4gaXMgYSBkb3VibGUsIGNvbnN1bWUgaXQgYW5kIHJldHVybiBpdHMgdmFsdWUuCisgICAgICogT3RoZXJ3aXNlLCB0aHJvdyBhIHtAbGluayBQYXJzZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBjb25zdW1lRG91YmxlKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIC8vIFdlIG5lZWQgdG8gcGFyc2UgaW5maW5pdHkgYW5kIG5hbiBzZXBhcmF0ZWx5IGJlY2F1c2UKKyAgICAgIC8vIERvdWJsZS5wYXJzZURvdWJsZSgpIGRvZXMgbm90IGFjY2VwdCAiaW5mIiwgImluZmluaXR5Iiwgb3IgIm5hbiIuCisgICAgICBpZiAoRE9VQkxFX0lORklOSVRZLm1hdGNoZXIoY3VycmVudFRva2VuKS5tYXRjaGVzKCkpIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBuZWdhdGl2ZSA9IGN1cnJlbnRUb2tlbi5zdGFydHNXaXRoKCItIik7CisgICAgICAgIG5leHRUb2tlbigpOworICAgICAgICByZXR1cm4gbmVnYXRpdmUgPyBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkgOiBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFk7CisgICAgICB9CisgICAgICBpZiAoY3VycmVudFRva2VuLmVxdWFsc0lnbm9yZUNhc2UoIm5hbiIpKSB7CisgICAgICAgIG5leHRUb2tlbigpOworICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIGRvdWJsZSByZXN1bHQgPSBEb3VibGUucGFyc2VEb3VibGUoY3VycmVudFRva2VuKTsKKyAgICAgICAgbmV4dFRva2VuKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBmbG9hdFBhcnNlRXhjZXB0aW9uKGUpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGlzIGEgZG91YmxlLCBjb25zdW1lIGl0IGFuZCByZXR1cm4ge0Bjb2RlIHRydWV9LgorICAgICAqIE90aGVyd2lzZSwgcmV0dXJuIHtAY29kZSBmYWxzZX0gd2l0aG91dCBkb2luZyBhbnl0aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB0cnlDb25zdW1lRG91YmxlKCkgeworICAgICAgdHJ5IHsKKyAgICAgICAgY29uc3VtZURvdWJsZSgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGlzIGEgZmxvYXQsIGNvbnN1bWUgaXQgYW5kIHJldHVybiBpdHMgdmFsdWUuCisgICAgICogT3RoZXJ3aXNlLCB0aHJvdyBhIHtAbGluayBQYXJzZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGNvbnN1bWVGbG9hdCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAvLyBXZSBuZWVkIHRvIHBhcnNlIGluZmluaXR5IGFuZCBuYW4gc2VwYXJhdGVseSBiZWNhdXNlCisgICAgICAvLyBGbG9hdC5wYXJzZUZsb2F0KCkgZG9lcyBub3QgYWNjZXB0ICJpbmYiLCAiaW5maW5pdHkiLCBvciAibmFuIi4KKyAgICAgIGlmIChGTE9BVF9JTkZJTklUWS5tYXRjaGVyKGN1cnJlbnRUb2tlbikubWF0Y2hlcygpKSB7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gbmVnYXRpdmUgPSBjdXJyZW50VG9rZW4uc3RhcnRzV2l0aCgiLSIpOworICAgICAgICBuZXh0VG9rZW4oKTsKKyAgICAgICAgcmV0dXJuIG5lZ2F0aXZlID8gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkgOiBGbG9hdC5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgIH0KKyAgICAgIGlmIChGTE9BVF9OQU4ubWF0Y2hlcihjdXJyZW50VG9rZW4pLm1hdGNoZXMoKSkgeworICAgICAgICBuZXh0VG9rZW4oKTsKKyAgICAgICAgcmV0dXJuIEZsb2F0Lk5hTjsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIGZsb2F0IHJlc3VsdCA9IEZsb2F0LnBhcnNlRmxvYXQoY3VycmVudFRva2VuKTsKKyAgICAgICAgbmV4dFRva2VuKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBmbG9hdFBhcnNlRXhjZXB0aW9uKGUpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGlzIGEgZmxvYXQsIGNvbnN1bWUgaXQgYW5kIHJldHVybiB7QGNvZGUgdHJ1ZX0uCisgICAgICogT3RoZXJ3aXNlLCByZXR1cm4ge0Bjb2RlIGZhbHNlfSB3aXRob3V0IGRvaW5nIGFueXRoaW5nLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRyeUNvbnN1bWVGbG9hdCgpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGNvbnN1bWVGbG9hdCgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGlzIGEgYm9vbGVhbiwgY29uc3VtZSBpdCBhbmQgcmV0dXJuIGl0cyB2YWx1ZS4KKyAgICAgKiBPdGhlcndpc2UsIHRocm93IGEge0BsaW5rIFBhcnNlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb25zdW1lQm9vbGVhbigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBpZiAoY3VycmVudFRva2VuLmVxdWFscygidHJ1ZSIpCisgICAgICAgICAgfHwgY3VycmVudFRva2VuLmVxdWFscygidCIpCisgICAgICAgICAgfHwgY3VycmVudFRva2VuLmVxdWFscygiMSIpKSB7CisgICAgICAgIG5leHRUb2tlbigpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gZWxzZSBpZiAoY3VycmVudFRva2VuLmVxdWFscygiZmFsc2UiKQorICAgICAgICAgIHx8IGN1cnJlbnRUb2tlbi5lcXVhbHMoImYiKQorICAgICAgICAgIHx8IGN1cnJlbnRUb2tlbi5lcXVhbHMoIjAiKSkgeworICAgICAgICBuZXh0VG9rZW4oKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgcGFyc2VFeGNlcHRpb24oIkV4cGVjdGVkIFwidHJ1ZVwiIG9yIFwiZmFsc2VcIi4iKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbmV4dCB0b2tlbiBpcyBhIHN0cmluZywgY29uc3VtZSBpdCBhbmQgcmV0dXJuIGl0cyAodW5lc2NhcGVkKQorICAgICAqIHZhbHVlLiAgT3RoZXJ3aXNlLCB0aHJvdyBhIHtAbGluayBQYXJzZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBjb25zdW1lU3RyaW5nKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBjb25zdW1lQnl0ZVN0cmluZygpLnRvU3RyaW5nVXRmOCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBuZXh0IHRva2VuIGlzIGEgc3RyaW5nLCBjb25zdW1lIGl0IGFuZCByZXR1cm4gdHJ1ZS4gIE90aGVyd2lzZSwKKyAgICAgKiByZXR1cm4gZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdHJ5Q29uc3VtZVN0cmluZygpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGNvbnN1bWVTdHJpbmcoKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbmV4dCB0b2tlbiBpcyBhIHN0cmluZywgY29uc3VtZSBpdCwgdW5lc2NhcGUgaXQgYXMgYQorICAgICAqIHtAbGluayBCeXRlU3RyaW5nfSwgYW5kIHJldHVybiBpdC4gIE90aGVyd2lzZSwgdGhyb3cgYQorICAgICAqIHtAbGluayBQYXJzZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEJ5dGVTdHJpbmcgY29uc3VtZUJ5dGVTdHJpbmcoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgTGlzdDxCeXRlU3RyaW5nPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxCeXRlU3RyaW5nPigpOworICAgICAgY29uc3VtZUJ5dGVTdHJpbmcobGlzdCk7CisgICAgICB3aGlsZSAoY3VycmVudFRva2VuLnN0YXJ0c1dpdGgoIiciKSB8fCBjdXJyZW50VG9rZW4uc3RhcnRzV2l0aCgiXCIiKSkgeworICAgICAgICBjb25zdW1lQnl0ZVN0cmluZyhsaXN0KTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBCeXRlU3RyaW5nLmNvcHlGcm9tKGxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExpa2Uge0BsaW5rICNjb25zdW1lQnl0ZVN0cmluZygpfSBidXQgYWRkcyBlYWNoIHRva2VuIG9mIHRoZSBzdHJpbmcgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gbGlzdC4gIFN0cmluZyBsaXRlcmFscyAod2hldGhlciBieXRlcyBvciB0ZXh0KSBtYXkgY29tZSBpbgorICAgICAqIG11bHRpcGxlIGFkamFjZW50IHRva2VucyB3aGljaCBhcmUgYXV0b21hdGljYWxseSBjb25jYXRlbmF0ZWQsIGxpa2UgaW4KKyAgICAgKiBDIG9yIFB5dGhvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29uc3VtZUJ5dGVTdHJpbmcoTGlzdDxCeXRlU3RyaW5nPiBsaXN0KQorICAgICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgZmluYWwgY2hhciBxdW90ZSA9IGN1cnJlbnRUb2tlbi5sZW5ndGgoKSA+IDAKKyAgICAgICAgICA/IGN1cnJlbnRUb2tlbi5jaGFyQXQoMCkKKyAgICAgICAgICA6ICdcMCc7CisgICAgICBpZiAocXVvdGUgIT0gJ1wiJyAmJiBxdW90ZSAhPSAnXCcnKSB7CisgICAgICAgIHRocm93IHBhcnNlRXhjZXB0aW9uKCJFeHBlY3RlZCBzdHJpbmcuIik7CisgICAgICB9CisKKyAgICAgIGlmIChjdXJyZW50VG9rZW4ubGVuZ3RoKCkgPCAyCisgICAgICAgICAgfHwgY3VycmVudFRva2VuLmNoYXJBdChjdXJyZW50VG9rZW4ubGVuZ3RoKCkgLSAxKSAhPSBxdW90ZSkgeworICAgICAgICB0aHJvdyBwYXJzZUV4Y2VwdGlvbigiU3RyaW5nIG1pc3NpbmcgZW5kaW5nIHF1b3RlLiIpOworICAgICAgfQorCisgICAgICB0cnkgeworICAgICAgICBmaW5hbCBTdHJpbmcgZXNjYXBlZCA9CisgICAgICAgICAgICBjdXJyZW50VG9rZW4uc3Vic3RyaW5nKDEsIGN1cnJlbnRUb2tlbi5sZW5ndGgoKSAtIDEpOworICAgICAgICBmaW5hbCBCeXRlU3RyaW5nIHJlc3VsdCA9IHVuZXNjYXBlQnl0ZXMoZXNjYXBlZCk7CisgICAgICAgIG5leHRUb2tlbigpOworICAgICAgICBsaXN0LmFkZChyZXN1bHQpOworICAgICAgfSBjYXRjaCAoSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgcGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgUGFyc2VFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgbGluZSBhbmQgY29sdW1uCisgICAgICogbnVtYmVycyBpbiB0aGUgZGVzY3JpcHRpb24sIHN1aXRhYmxlIGZvciB0aHJvd2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyc2VFeGNlcHRpb24gcGFyc2VFeGNlcHRpb24oZmluYWwgU3RyaW5nIGRlc2NyaXB0aW9uKSB7CisgICAgICAvLyBOb3RlOiAgUGVvcGxlIGdlbmVyYWxseSBwcmVmZXIgb25lLWJhc2VkIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzLgorICAgICAgcmV0dXJuIG5ldyBQYXJzZUV4Y2VwdGlvbigKKyAgICAgICAgbGluZSArIDEsIGNvbHVtbiArIDEsIGRlc2NyaXB0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIFBhcnNlRXhjZXB0aW9ufSB3aXRoIHRoZSBsaW5lIGFuZCBjb2x1bW4gbnVtYmVycyBvZgorICAgICAqIHRoZSBwcmV2aW91cyB0b2tlbiBpbiB0aGUgZGVzY3JpcHRpb24sIHN1aXRhYmxlIGZvciB0aHJvd2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyc2VFeGNlcHRpb24gcGFyc2VFeGNlcHRpb25QcmV2aW91c1Rva2VuKAorICAgICAgICBmaW5hbCBTdHJpbmcgZGVzY3JpcHRpb24pIHsKKyAgICAgIC8vIE5vdGU6ICBQZW9wbGUgZ2VuZXJhbGx5IHByZWZlciBvbmUtYmFzZWQgbGluZSBhbmQgY29sdW1uIG51bWJlcnMuCisgICAgICByZXR1cm4gbmV3IFBhcnNlRXhjZXB0aW9uKAorICAgICAgICBwcmV2aW91c0xpbmUgKyAxLCBwcmV2aW91c0NvbHVtbiArIDEsIGRlc2NyaXB0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIGFwcHJvcHJpYXRlIHtAbGluayBQYXJzZUV4Y2VwdGlvbn0gZm9yIHRoZSBnaXZlbgorICAgICAqIHtAY29kZSBOdW1iZXJGb3JtYXRFeGNlcHRpb259IHdoZW4gdHJ5aW5nIHRvIHBhcnNlIGFuIGludGVnZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBQYXJzZUV4Y2VwdGlvbiBpbnRlZ2VyUGFyc2VFeGNlcHRpb24oCisgICAgICAgIGZpbmFsIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICByZXR1cm4gcGFyc2VFeGNlcHRpb24oIkNvdWxkbid0IHBhcnNlIGludGVnZXI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBhcHByb3ByaWF0ZSB7QGxpbmsgUGFyc2VFeGNlcHRpb259IGZvciB0aGUgZ2l2ZW4KKyAgICAgKiB7QGNvZGUgTnVtYmVyRm9ybWF0RXhjZXB0aW9ufSB3aGVuIHRyeWluZyB0byBwYXJzZSBhIGZsb2F0IG9yIGRvdWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFBhcnNlRXhjZXB0aW9uIGZsb2F0UGFyc2VFeGNlcHRpb24oZmluYWwgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBwYXJzZUV4Y2VwdGlvbigiQ291bGRuJ3QgcGFyc2UgbnVtYmVyOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisgIC8qKiBUaHJvd24gd2hlbiBwYXJzaW5nIGFuIGludmFsaWQgdGV4dCBmb3JtYXQgbWVzc2FnZS4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBQYXJzZUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMTk2MTg4MDYwMjI1MTA3NzAyTDsKKworICAgIHByaXZhdGUgZmluYWwgaW50IGxpbmU7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgY29sdW1uOworCisgICAgLyoqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSwgd2l0aCAtMSBhcyB0aGUgbGluZSBhbmQgY29sdW1uIG51bWJlcnMuICovCisgICAgcHVibGljIFBhcnNlRXhjZXB0aW9uKGZpbmFsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgICB0aGlzKC0xLCAtMSwgbWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGluZSB0aGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIHBhcnNlIGVycm9yIG9jY3VycmVkLAorICAgICAqIHVzaW5nIDEtb2Zmc2V0LgorICAgICAqIEBwYXJhbSBjb2x1bW4gdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIHBhcnNlciBlcnJvciBvY2N1cnJlZCwKKyAgICAgKiB1c2luZyAxLW9mZnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyc2VFeGNlcHRpb24oZmluYWwgaW50IGxpbmUsIGZpbmFsIGludCBjb2x1bW4sCisgICAgICAgIGZpbmFsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgICBzdXBlcihJbnRlZ2VyLnRvU3RyaW5nKGxpbmUpICsgIjoiICsgY29sdW1uICsgIjogIiArIG1lc3NhZ2UpOworICAgICAgdGhpcy5saW5lID0gbGluZTsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbGluZSB3aGVyZSB0aGUgcGFyc2UgZXhjZXB0aW9uIG9jY3VycmVkLCBvciAtMSB3aGVuCisgICAgICogbm9uZSBpcyBwcm92aWRlZC4gVGhlIHZhbHVlIGlzIHNwZWNpZmllZCBhcyAxLW9mZnNldCwgc28gdGhlIGZpcnN0CisgICAgICogbGluZSBpcyBsaW5lIDEuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMaW5lKCkgeworICAgICAgcmV0dXJuIGxpbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb2x1bW4gd2hlcmUgdGhlIHBhcnNlIGV4Y2VwdGlvbiBvY2N1cnJlZCwgb3IgLTEgd2hlbgorICAgICAqIG5vbmUgaXMgcHJvdmlkZWQuIFRoZSB2YWx1ZSBpcyBzcGVjaWZpZWQgYXMgMS1vZmZzZXQsIHNvIHRoZSBmaXJzdAorICAgICAqIGxpbmUgaXMgbGluZSAxLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uKCkgeworICAgICAgcmV0dXJuIGNvbHVtbjsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXJzZXIgUEFSU0VSID0gUGFyc2VyLm5ld0J1aWxkZXIoKS5idWlsZCgpOworCisgIC8qKgorICAgKiBSZXR1cm4gYSB7QGxpbmsgUGFyc2VyfSBpbnN0YW5jZSB3aGljaCBjYW4gcGFyc2UgdGV4dC1mb3JtYXQKKyAgICogbWVzc2FnZXMuIFRoZSByZXR1cm5lZCBpbnN0YW5jZSBpcyB0aHJlYWQtc2FmZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUGFyc2VyIGdldFBhcnNlcigpIHsKKyAgICByZXR1cm4gUEFSU0VSOworICB9CisKKyAgLyoqCisgICAqIFBhcnNlIGEgdGV4dC1mb3JtYXQgbWVzc2FnZSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIHRoZSBjb250ZW50cworICAgKiBpbnRvIHtAY29kZSBidWlsZGVyfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtZXJnZShmaW5hbCBSZWFkYWJsZSBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQQVJTRVIubWVyZ2UoaW5wdXQsIGJ1aWxkZXIpOworICB9CisKKyAgLyoqCisgICAqIFBhcnNlIGEgdGV4dC1mb3JtYXQgbWVzc2FnZSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIHRoZSBjb250ZW50cworICAgKiBpbnRvIHtAY29kZSBidWlsZGVyfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtZXJnZShmaW5hbCBDaGFyU2VxdWVuY2UgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgUEFSU0VSLm1lcmdlKGlucHV0LCBidWlsZGVyKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZSBhIHRleHQtZm9ybWF0IG1lc3NhZ2UgZnJvbSB7QGNvZGUgaW5wdXR9IGFuZCBtZXJnZSB0aGUgY29udGVudHMKKyAgICogaW50byB7QGNvZGUgYnVpbGRlcn0uICBFeHRlbnNpb25zIHdpbGwgYmUgcmVjb2duaXplZCBpZiB0aGV5IGFyZQorICAgKiByZWdpc3RlcmVkIGluIHtAY29kZSBleHRlbnNpb25SZWdpc3RyeX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWVyZ2UoZmluYWwgUmVhZGFibGUgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQQVJTRVIubWVyZ2UoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCBidWlsZGVyKTsKKyAgfQorCisKKyAgLyoqCisgICAqIFBhcnNlIGEgdGV4dC1mb3JtYXQgbWVzc2FnZSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIHRoZSBjb250ZW50cworICAgKiBpbnRvIHtAY29kZSBidWlsZGVyfS4gIEV4dGVuc2lvbnMgd2lsbCBiZSByZWNvZ25pemVkIGlmIHRoZXkgYXJlCisgICAqIHJlZ2lzdGVyZWQgaW4ge0Bjb2RlIGV4dGVuc2lvblJlZ2lzdHJ5fS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtZXJnZShmaW5hbCBDaGFyU2VxdWVuY2UgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICBQQVJTRVIubWVyZ2UoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCBidWlsZGVyKTsKKyAgfQorCisKKyAgLyoqCisgICAqIFBhcnNlciBmb3IgdGV4dC1mb3JtYXQgcHJvdG8yIGluc3RhbmNlcy4gVGhpcyBjbGFzcyBpcyB0aHJlYWQtc2FmZS4KKyAgICogVGhlIGltcGxlbWVudGF0aW9uIGxhcmdlbHkgZm9sbG93cyBnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuY2MuCisgICAqCisgICAqIDxwPlVzZSB7QGxpbmsgVGV4dEZvcm1hdCNnZXRQYXJzZXIoKX0gdG8gb2J0YWluIHRoZSBkZWZhdWx0IHBhcnNlciwgb3IKKyAgICoge0BsaW5rIEJ1aWxkZXJ9IHRvIGNvbnRyb2wgdGhlIHBhcnNlciBiZWhhdmlvci4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUGFyc2VyIHsKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIGlmIHJlcGVhdGVkIHZhbHVlcyBmb3Igbm9uLXJlcGVhdGVkIGZpZWxkcyBhbmQKKyAgICAgKiBvbmVvZnMgYXJlIHBlcm1pdHRlZC4gRm9yIGV4YW1wbGUsIGdpdmVuIHJlcXVpcmVkL29wdGlvbmFsIGZpZWxkICJmb28iCisgICAgICogYW5kIGEgb25lb2YgY29udGFpbmluZyAiYmF6IiBhbmQgInF1eCI6CisgICAgICogPGxpPgorICAgICAqIDx1bD4iZm9vOiAxIGZvbzogMiIKKyAgICAgKiA8dWw+ImJhejogMSBxdXg6IDIiCisgICAgICogPHVsPm1lcmdpbmcgImZvbzogMiIgaW50byBhIHByb3RvIGluIHdoaWNoIGZvbyBpcyBhbHJlYWR5IHNldCwgb3IKKyAgICAgKiA8dWw+bWVyZ2luZyAicXV4OiAyIiBpbnRvIGEgcHJvdG8gaW4gd2hpY2ggYmF6IGlzIGFscmVhZHkgc2V0LgorICAgICAqIDwvbGk+CisgICAgICovCisgICAgcHVibGljIGVudW0gU2luZ3VsYXJPdmVyd3JpdGVQb2xpY3kgeworICAgICAgLyoqIFRoZSBsYXN0IHZhbHVlIGlzIHJldGFpbmVkLiAqLworICAgICAgQUxMT1dfU0lOR1VMQVJfT1ZFUldSSVRFUywKKyAgICAgIC8qKiBBbiBlcnJvciBpcyBpc3N1ZWQuICovCisgICAgICBGT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBhbGxvd1Vua25vd25GaWVsZHM7CisgICAgcHJpdmF0ZSBmaW5hbCBTaW5ndWxhck92ZXJ3cml0ZVBvbGljeSBzaW5ndWxhck92ZXJ3cml0ZVBvbGljeTsKKworICAgIHByaXZhdGUgUGFyc2VyKGJvb2xlYW4gYWxsb3dVbmtub3duRmllbGRzLAorICAgICAgICBTaW5ndWxhck92ZXJ3cml0ZVBvbGljeSBzaW5ndWxhck92ZXJ3cml0ZVBvbGljeSkgeworICAgICAgdGhpcy5hbGxvd1Vua25vd25GaWVsZHMgPSBhbGxvd1Vua25vd25GaWVsZHM7CisgICAgICB0aGlzLnNpbmd1bGFyT3ZlcndyaXRlUG9saWN5ID0gc2luZ3VsYXJPdmVyd3JpdGVQb2xpY3k7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgQnVpbGRlcn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWlsZGVyIHRoYXQgY2FuIGJlIHVzZWQgdG8gb2J0YWluIG5ldyBpbnN0YW5jZXMgb2Yge0BsaW5rIFBhcnNlcn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICAgIHByaXZhdGUgYm9vbGVhbiBhbGxvd1Vua25vd25GaWVsZHMgPSBmYWxzZTsKKyAgICAgIHByaXZhdGUgU2luZ3VsYXJPdmVyd3JpdGVQb2xpY3kgc2luZ3VsYXJPdmVyd3JpdGVQb2xpY3kgPQorICAgICAgICAgIFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5LkFMTE9XX1NJTkdVTEFSX09WRVJXUklURVM7CisKKworICAgICAgLyoqCisgICAgICAgKiBTZXRzIHBhcnNlciBiZWhhdmlvciB3aGVuIGEgbm9uLXJlcGVhdGVkIGZpZWxkIGFwcGVhcnMgbW9yZSB0aGFuIG9uY2UuCisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5KFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5IHApIHsKKyAgICAgICAgdGhpcy5zaW5ndWxhck92ZXJ3cml0ZVBvbGljeSA9IHA7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorCisgICAgICBwdWJsaWMgUGFyc2VyIGJ1aWxkKCkgeworICAgICAgICByZXR1cm4gbmV3IFBhcnNlcihhbGxvd1Vua25vd25GaWVsZHMsIHNpbmd1bGFyT3ZlcndyaXRlUG9saWN5KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHRleHQtZm9ybWF0IG1lc3NhZ2UgZnJvbSB7QGNvZGUgaW5wdXR9IGFuZCBtZXJnZSB0aGUgY29udGVudHMKKyAgICAgKiBpbnRvIHtAY29kZSBidWlsZGVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtZXJnZShmaW5hbCBSZWFkYWJsZSBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikKKyAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgbWVyZ2UoaW5wdXQsIEV4dGVuc2lvblJlZ2lzdHJ5LmdldEVtcHR5UmVnaXN0cnkoKSwgYnVpbGRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYSB0ZXh0LWZvcm1hdCBtZXNzYWdlIGZyb20ge0Bjb2RlIGlucHV0fSBhbmQgbWVyZ2UgdGhlIGNvbnRlbnRzCisgICAgICogaW50byB7QGNvZGUgYnVpbGRlcn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgbWVyZ2UoZmluYWwgQ2hhclNlcXVlbmNlIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBtZXJnZShpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnkuZ2V0RW1wdHlSZWdpc3RyeSgpLCBidWlsZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHRleHQtZm9ybWF0IG1lc3NhZ2UgZnJvbSB7QGNvZGUgaW5wdXR9IGFuZCBtZXJnZSB0aGUgY29udGVudHMKKyAgICAgKiBpbnRvIHtAY29kZSBidWlsZGVyfS4gIEV4dGVuc2lvbnMgd2lsbCBiZSByZWNvZ25pemVkIGlmIHRoZXkgYXJlCisgICAgICogcmVnaXN0ZXJlZCBpbiB7QGNvZGUgZXh0ZW5zaW9uUmVnaXN0cnl9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1lcmdlKGZpbmFsIFJlYWRhYmxlIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5IGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyKQorICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAvLyBSZWFkIHRoZSBlbnRpcmUgaW5wdXQgdG8gYSBTdHJpbmcgdGhlbiBwYXJzZSB0aGF0LgorCisgICAgICAvLyBJZiBTdHJlYW1Ub2tlbml6ZXIgd2VyZSBub3QgcXVpdGUgc28gY3JpcHBsZWQsIG9yIGlmIHRoZXJlIHdlcmUgYSBraW5kCisgICAgICAvLyBvZiBSZWFkZXIgdGhhdCBjb3VsZCByZWFkIGluIGNodW5rcyB0aGF0IG1hdGNoIHNvbWUgcGFydGljdWxhciByZWdleCwKKyAgICAgIC8vIG9yIGlmIHdlIHdhbnRlZCB0byB3cml0ZSBhIGN1c3RvbSBSZWFkZXIgdG8gdG9rZW5pemUgb3VyIHN0cmVhbSwgdGhlbgorICAgICAgLy8gd2Ugd291bGQgbm90IGhhdmUgdG8gcmVhZCB0byBvbmUgYmlnIFN0cmluZy4gIEFsYXMsIG5vbmUgb2YgdGhlc2UgaXMKKyAgICAgIC8vIHRoZSBjYXNlLiAgT2ggd2VsbC4KKworICAgICAgbWVyZ2UodG9TdHJpbmdCdWlsZGVyKGlucHV0KSwgZXh0ZW5zaW9uUmVnaXN0cnksIGJ1aWxkZXIpOworICAgIH0KKworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRkZFUl9TSVpFID0gNDA5NjsKKworICAgIC8vIFRPRE8oY2hyaXNuKTogU2VlIGlmIHdvcmtpbmcgYXJvdW5kIGphdmEuaW8uUmVhZGVyI3JlYWQoQ2hhckJ1ZmZlcikKKyAgICAvLyBvdmVyaGVhZCBpcyB3b3J0aHdoaWxlCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nQnVpbGRlciB0b1N0cmluZ0J1aWxkZXIoZmluYWwgUmVhZGFibGUgaW5wdXQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHRleHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgZmluYWwgQ2hhckJ1ZmZlciBidWZmZXIgPSBDaGFyQnVmZmVyLmFsbG9jYXRlKEJVRkZFUl9TSVpFKTsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIGZpbmFsIGludCBuID0gaW5wdXQucmVhZChidWZmZXIpOworICAgICAgICBpZiAobiA9PSAtMSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGJ1ZmZlci5mbGlwKCk7CisgICAgICAgIHRleHQuYXBwZW5kKGJ1ZmZlciwgMCwgbik7CisgICAgICB9CisgICAgICByZXR1cm4gdGV4dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHRleHQtZm9ybWF0IG1lc3NhZ2UgZnJvbSB7QGNvZGUgaW5wdXR9IGFuZCBtZXJnZSB0aGUgY29udGVudHMKKyAgICAgKiBpbnRvIHtAY29kZSBidWlsZGVyfS4gIEV4dGVuc2lvbnMgd2lsbCBiZSByZWNvZ25pemVkIGlmIHRoZXkgYXJlCisgICAgICogcmVnaXN0ZXJlZCBpbiB7QGNvZGUgZXh0ZW5zaW9uUmVnaXN0cnl9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1lcmdlKGZpbmFsIENoYXJTZXF1ZW5jZSBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSwKKyAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikKKyAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgZmluYWwgVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBUb2tlbml6ZXIoaW5wdXQpOworICAgICAgTWVzc2FnZVJlZmxlY3Rpb24uQnVpbGRlckFkYXB0ZXIgdGFyZ2V0ID0KKyAgICAgICAgICBuZXcgTWVzc2FnZVJlZmxlY3Rpb24uQnVpbGRlckFkYXB0ZXIoYnVpbGRlcik7CisKKyAgICAgIHdoaWxlICghdG9rZW5pemVyLmF0RW5kKCkpIHsKKyAgICAgICAgbWVyZ2VGaWVsZCh0b2tlbml6ZXIsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YXJnZXQpOworICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogUGFyc2UgYSBzaW5nbGUgZmllbGQgZnJvbSB7QGNvZGUgdG9rZW5pemVyfSBhbmQgbWVyZ2UgaXQgaW50bworICAgICAqIHtAY29kZSBidWlsZGVyfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbWVyZ2VGaWVsZChmaW5hbCBUb2tlbml6ZXIgdG9rZW5pemVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5IGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VSZWZsZWN0aW9uLk1lcmdlVGFyZ2V0IHRhcmdldCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gbnVsbDsKKyAgICAgIGZpbmFsIERlc2NyaXB0b3IgdHlwZSA9IHRhcmdldC5nZXREZXNjcmlwdG9yRm9yVHlwZSgpOworICAgICAgRXh0ZW5zaW9uUmVnaXN0cnkuRXh0ZW5zaW9uSW5mbyBleHRlbnNpb24gPSBudWxsOworCisgICAgICBpZiAodG9rZW5pemVyLnRyeUNvbnN1bWUoIlsiKSkgeworICAgICAgICAvLyBBbiBleHRlbnNpb24uCisgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgbmFtZSA9CisgICAgICAgICAgICBuZXcgU3RyaW5nQnVpbGRlcih0b2tlbml6ZXIuY29uc3VtZUlkZW50aWZpZXIoKSk7CisgICAgICAgIHdoaWxlICh0b2tlbml6ZXIudHJ5Q29uc3VtZSgiLiIpKSB7CisgICAgICAgICAgbmFtZS5hcHBlbmQoJy4nKTsKKyAgICAgICAgICBuYW1lLmFwcGVuZCh0b2tlbml6ZXIuY29uc3VtZUlkZW50aWZpZXIoKSk7CisgICAgICAgIH0KKworICAgICAgICBleHRlbnNpb24gPSB0YXJnZXQuZmluZEV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5LCBuYW1lLnRvU3RyaW5nKCkpOworCisgICAgICAgIGlmIChleHRlbnNpb24gPT0gbnVsbCkgeworICAgICAgICAgIGlmICghYWxsb3dVbmtub3duRmllbGRzKSB7CisgICAgICAgICAgICB0aHJvdyB0b2tlbml6ZXIucGFyc2VFeGNlcHRpb25QcmV2aW91c1Rva2VuKAorICAgICAgICAgICAgICAiRXh0ZW5zaW9uIFwiIiArIG5hbWUgKyAiXCIgbm90IGZvdW5kIGluIHRoZSBFeHRlbnNpb25SZWdpc3RyeS4iKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbG9nZ2VyLndhcm5pbmcoCisgICAgICAgICAgICAgICJFeHRlbnNpb24gXCIiICsgbmFtZSArICJcIiBub3QgZm91bmQgaW4gdGhlIEV4dGVuc2lvblJlZ2lzdHJ5LiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoZXh0ZW5zaW9uLmRlc2NyaXB0b3IuZ2V0Q29udGFpbmluZ1R5cGUoKSAhPSB0eXBlKSB7CisgICAgICAgICAgICB0aHJvdyB0b2tlbml6ZXIucGFyc2VFeGNlcHRpb25QcmV2aW91c1Rva2VuKAorICAgICAgICAgICAgICAiRXh0ZW5zaW9uIFwiIiArIG5hbWUgKyAiXCIgZG9lcyBub3QgZXh0ZW5kIG1lc3NhZ2UgdHlwZSBcIiIKKyAgICAgICAgICAgICAgKyB0eXBlLmdldEZ1bGxOYW1lKCkgKyAiXCIuIik7CisgICAgICAgICAgfQorICAgICAgICAgIGZpZWxkID0gZXh0ZW5zaW9uLmRlc2NyaXB0b3I7CisgICAgICAgIH0KKworICAgICAgICB0b2tlbml6ZXIuY29uc3VtZSgiXSIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSB0b2tlbml6ZXIuY29uc3VtZUlkZW50aWZpZXIoKTsKKyAgICAgICAgZmllbGQgPSB0eXBlLmZpbmRGaWVsZEJ5TmFtZShuYW1lKTsKKworICAgICAgICAvLyBHcm91cCBuYW1lcyBhcmUgZXhwZWN0ZWQgdG8gYmUgY2FwaXRhbGl6ZWQgYXMgdGhleSBhcHBlYXIgaW4gdGhlCisgICAgICAgIC8vIC5wcm90byBmaWxlLCB3aGljaCBhY3R1YWxseSBtYXRjaGVzIHRoZWlyIHR5cGUgbmFtZXMsIG5vdCB0aGVpciBmaWVsZAorICAgICAgICAvLyBuYW1lcy4KKyAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgICAgICAvLyBFeHBsaWNpdGx5IHNwZWNpZnkgVVMgbG9jYWxlIHNvIHRoYXQgdGhpcyBjb2RlIGRvZXMgbm90IGJyZWFrIHdoZW4KKyAgICAgICAgICAvLyBleGVjdXRpbmcgaW4gVHVya2V5LgorICAgICAgICAgIGZpbmFsIFN0cmluZyBsb3dlck5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5VUyk7CisgICAgICAgICAgZmllbGQgPSB0eXBlLmZpbmRGaWVsZEJ5TmFtZShsb3dlck5hbWUpOworICAgICAgICAgIC8vIElmIHRoZSBjYXNlLWluc2Vuc2l0aXZlIG1hdGNoIHdvcmtlZCBidXQgdGhlIGZpZWxkIGlzIE5PVCBhIGdyb3VwLAorICAgICAgICAgIGlmIChmaWVsZCAhPSBudWxsICYmIGZpZWxkLmdldFR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3IuVHlwZS5HUk9VUCkgeworICAgICAgICAgICAgZmllbGQgPSBudWxsOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBBZ2Fpbiwgc3BlY2lhbC1jYXNlIGdyb3VwIG5hbWVzIGFzIGRlc2NyaWJlZCBhYm92ZS4KKyAgICAgICAgaWYgKGZpZWxkICE9IG51bGwgJiYgZmllbGQuZ2V0VHlwZSgpID09IEZpZWxkRGVzY3JpcHRvci5UeXBlLkdST1VQCisgICAgICAgICAgICAmJiAhZmllbGQuZ2V0TWVzc2FnZVR5cGUoKS5nZXROYW1lKCkuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgZmllbGQgPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgICAgICBpZiAoIWFsbG93VW5rbm93bkZpZWxkcykgeworICAgICAgICAgICAgdGhyb3cgdG9rZW5pemVyLnBhcnNlRXhjZXB0aW9uUHJldmlvdXNUb2tlbigKKyAgICAgICAgICAgICAgIk1lc3NhZ2UgdHlwZSBcIiIgKyB0eXBlLmdldEZ1bGxOYW1lKCkKKyAgICAgICAgICAgICAgKyAiXCIgaGFzIG5vIGZpZWxkIG5hbWVkIFwiIiArIG5hbWUgKyAiXCIuIik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxvZ2dlci53YXJuaW5nKAorICAgICAgICAgICAgICAiTWVzc2FnZSB0eXBlIFwiIiArIHR5cGUuZ2V0RnVsbE5hbWUoKQorICAgICAgICAgICAgICArICJcIiBoYXMgbm8gZmllbGQgbmFtZWQgXCIiICsgbmFtZSArICJcIi4iKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgLy8gU2tpcHMgdW5rbm93biBmaWVsZHMuCisgICAgICBpZiAoZmllbGQgPT0gbnVsbCkgeworICAgICAgICAvLyBUcnkgdG8gZ3Vlc3MgdGhlIHR5cGUgb2YgdGhpcyBmaWVsZC4KKyAgICAgICAgLy8gSWYgdGhpcyBmaWVsZCBpcyBub3QgYSBtZXNzYWdlLCB0aGVyZSBzaG91bGQgYmUgYSAiOiIgYmV0d2VlbiB0aGUKKyAgICAgICAgLy8gZmllbGQgbmFtZSBhbmQgdGhlIGZpZWxkIHZhbHVlIGFuZCBhbHNvIHRoZSBmaWVsZCB2YWx1ZSBzaG91bGQgbm90CisgICAgICAgIC8vIHN0YXJ0IHdpdGggInsiIG9yICI8IiB3aGljaCBpbmRpY2F0ZXMgdGhlIGJlZ2lubmluZyBvZiBhIG1lc3NhZ2UgYm9keS4KKyAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gIjoiIG9yIHRoZXJlIGlzIGEgInsiIG9yICI8IiBhZnRlciAiOiIsIHRoaXMgZmllbGQgaGFzCisgICAgICAgIC8vIHRvIGJlIGEgbWVzc2FnZSBvciB0aGUgaW5wdXQgaXMgaWxsLWZvcm1lZC4KKyAgICAgICAgaWYgKHRva2VuaXplci50cnlDb25zdW1lKCI6IikKKyAgICAgICAgICAgICYmICF0b2tlbml6ZXIubG9va2luZ0F0KCJ7IikKKyAgICAgICAgICAgICYmICF0b2tlbml6ZXIubG9va2luZ0F0KCI8IikpIHsKKyAgICAgICAgICBza2lwRmllbGRWYWx1ZSh0b2tlbml6ZXIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNraXBGaWVsZE1lc3NhZ2UodG9rZW5pemVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm47CisgICAgICB9CisKKyAgICAgIC8vIEhhbmRsZSBwb3RlbnRpYWwgJzonLgorICAgICAgaWYgKGZpZWxkLmdldEphdmFUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgdG9rZW5pemVyLnRyeUNvbnN1bWUoIjoiKTsgIC8vIG9wdGlvbmFsCisgICAgICB9IGVsc2UgeworICAgICAgICB0b2tlbml6ZXIuY29uc3VtZSgiOiIpOyAgLy8gcmVxdWlyZWQKKyAgICAgIH0KKyAgICAgIC8vIFN1cHBvcnQgc3BlY2lmeWluZyByZXBlYXRlZCBmaWVsZCB2YWx1ZXMgYXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdC4KKyAgICAgIC8vIEV4LiJmb286IFsxLCAyLCAzXSIKKyAgICAgIGlmIChmaWVsZC5pc1JlcGVhdGVkKCkgJiYgdG9rZW5pemVyLnRyeUNvbnN1bWUoIlsiKSkgeworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgIGNvbnN1bWVGaWVsZFZhbHVlKHRva2VuaXplciwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhcmdldCwgZmllbGQsIGV4dGVuc2lvbik7CisgICAgICAgICAgaWYgKHRva2VuaXplci50cnlDb25zdW1lKCJdIikpIHsKKyAgICAgICAgICAgIC8vIEVuZCBvZiBsaXN0LgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIHRva2VuaXplci5jb25zdW1lKCIsIik7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbnN1bWVGaWVsZFZhbHVlKHRva2VuaXplciwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhcmdldCwgZmllbGQsIGV4dGVuc2lvbik7CisgICAgICB9CisKKyAgICAgIC8vIEZvciBoaXN0b3JpY2FsIHJlYXNvbnMsIGZpZWxkcyBtYXkgb3B0aW9uYWxseSBiZSBzZXBhcmF0ZWQgYnkgY29tbWFzIG9yCisgICAgICAvLyBzZW1pY29sb25zLgorICAgICAgaWYgKCF0b2tlbml6ZXIudHJ5Q29uc3VtZSgiOyIpKSB7CisgICAgICAgIHRva2VuaXplci50cnlDb25zdW1lKCIsIik7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYSBzaW5nbGUgZmllbGQgdmFsdWUgZnJvbSB7QGNvZGUgdG9rZW5pemVyfSBhbmQgbWVyZ2UgaXQgaW50bworICAgICAqIHtAY29kZSBidWlsZGVyfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29uc3VtZUZpZWxkVmFsdWUoCisgICAgICAgIGZpbmFsIFRva2VuaXplciB0b2tlbml6ZXIsCisgICAgICAgIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5IGV4dGVuc2lvblJlZ2lzdHJ5LAorICAgICAgICBmaW5hbCBNZXNzYWdlUmVmbGVjdGlvbi5NZXJnZVRhcmdldCB0YXJnZXQsCisgICAgICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBmaWVsZCwKKyAgICAgICAgZmluYWwgRXh0ZW5zaW9uUmVnaXN0cnkuRXh0ZW5zaW9uSW5mbyBleHRlbnNpb24pCisgICAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBPYmplY3QgdmFsdWUgPSBudWxsOworCisgICAgICBpZiAoZmllbGQuZ2V0SmF2YVR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUuTUVTU0FHRSkgeworICAgICAgICBmaW5hbCBTdHJpbmcgZW5kVG9rZW47CisgICAgICAgIGlmICh0b2tlbml6ZXIudHJ5Q29uc3VtZSgiPCIpKSB7CisgICAgICAgICAgZW5kVG9rZW4gPSAiPiI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdG9rZW5pemVyLmNvbnN1bWUoInsiKTsKKyAgICAgICAgICBlbmRUb2tlbiA9ICJ9IjsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIE1lc3NhZ2VSZWZsZWN0aW9uLk1lcmdlVGFyZ2V0IHN1YkZpZWxkOworICAgICAgICBzdWJGaWVsZCA9IHRhcmdldC5uZXdNZXJnZVRhcmdldEZvckZpZWxkKGZpZWxkLAorICAgICAgICAgICAgKGV4dGVuc2lvbiA9PSBudWxsKSA/IG51bGwgOiBleHRlbnNpb24uZGVmYXVsdEluc3RhbmNlKTsKKworICAgICAgICB3aGlsZSAoIXRva2VuaXplci50cnlDb25zdW1lKGVuZFRva2VuKSkgeworICAgICAgICAgIGlmICh0b2tlbml6ZXIuYXRFbmQoKSkgeworICAgICAgICAgICAgdGhyb3cgdG9rZW5pemVyLnBhcnNlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAiRXhwZWN0ZWQgXCIiICsgZW5kVG9rZW4gKyAiXCIuIik7CisgICAgICAgICAgfQorICAgICAgICAgIG1lcmdlRmllbGQodG9rZW5pemVyLCBleHRlbnNpb25SZWdpc3RyeSwgc3ViRmllbGQpOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBzdWJGaWVsZC5maW5pc2goKTsKKworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3dpdGNoIChmaWVsZC5nZXRUeXBlKCkpIHsKKyAgICAgICAgICBjYXNlIElOVDMyOgorICAgICAgICAgIGNhc2UgU0lOVDMyOgorICAgICAgICAgIGNhc2UgU0ZJWEVEMzI6CisgICAgICAgICAgICB2YWx1ZSA9IHRva2VuaXplci5jb25zdW1lSW50MzIoKTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgY2FzZSBJTlQ2NDoKKyAgICAgICAgICBjYXNlIFNJTlQ2NDoKKyAgICAgICAgICBjYXNlIFNGSVhFRDY0OgorICAgICAgICAgICAgdmFsdWUgPSB0b2tlbml6ZXIuY29uc3VtZUludDY0KCk7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgIGNhc2UgVUlOVDMyOgorICAgICAgICAgIGNhc2UgRklYRUQzMjoKKyAgICAgICAgICAgIHZhbHVlID0gdG9rZW5pemVyLmNvbnN1bWVVSW50MzIoKTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgY2FzZSBVSU5UNjQ6CisgICAgICAgICAgY2FzZSBGSVhFRDY0OgorICAgICAgICAgICAgdmFsdWUgPSB0b2tlbml6ZXIuY29uc3VtZVVJbnQ2NCgpOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICBjYXNlIEZMT0FUOgorICAgICAgICAgICAgdmFsdWUgPSB0b2tlbml6ZXIuY29uc3VtZUZsb2F0KCk7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgIGNhc2UgRE9VQkxFOgorICAgICAgICAgICAgdmFsdWUgPSB0b2tlbml6ZXIuY29uc3VtZURvdWJsZSgpOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICBjYXNlIEJPT0w6CisgICAgICAgICAgICB2YWx1ZSA9IHRva2VuaXplci5jb25zdW1lQm9vbGVhbigpOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICBjYXNlIFNUUklORzoKKyAgICAgICAgICAgIHZhbHVlID0gdG9rZW5pemVyLmNvbnN1bWVTdHJpbmcoKTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgY2FzZSBCWVRFUzoKKyAgICAgICAgICAgIHZhbHVlID0gdG9rZW5pemVyLmNvbnN1bWVCeXRlU3RyaW5nKCk7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgIGNhc2UgRU5VTToKKyAgICAgICAgICAgIGZpbmFsIEVudW1EZXNjcmlwdG9yIGVudW1UeXBlID0gZmllbGQuZ2V0RW51bVR5cGUoKTsKKworICAgICAgICAgICAgaWYgKHRva2VuaXplci5sb29raW5nQXRJbnRlZ2VyKCkpIHsKKyAgICAgICAgICAgICAgZmluYWwgaW50IG51bWJlciA9IHRva2VuaXplci5jb25zdW1lSW50MzIoKTsKKyAgICAgICAgICAgICAgdmFsdWUgPSBlbnVtVHlwZS5maW5kVmFsdWVCeU51bWJlcihudW1iZXIpOworICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IHRva2VuaXplci5wYXJzZUV4Y2VwdGlvblByZXZpb3VzVG9rZW4oCisgICAgICAgICAgICAgICAgICAiRW51bSB0eXBlIFwiIiArIGVudW1UeXBlLmdldEZ1bGxOYW1lKCkKKyAgICAgICAgICAgICAgICAgICsgIlwiIGhhcyBubyB2YWx1ZSB3aXRoIG51bWJlciAiICsgbnVtYmVyICsgJy4nKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGlkID0gdG9rZW5pemVyLmNvbnN1bWVJZGVudGlmaWVyKCk7CisgICAgICAgICAgICAgIHZhbHVlID0gZW51bVR5cGUuZmluZFZhbHVlQnlOYW1lKGlkKTsKKyAgICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyB0b2tlbml6ZXIucGFyc2VFeGNlcHRpb25QcmV2aW91c1Rva2VuKAorICAgICAgICAgICAgICAgICAgIkVudW0gdHlwZSBcIiIgKyBlbnVtVHlwZS5nZXRGdWxsTmFtZSgpCisgICAgICAgICAgICAgICAgICArICJcIiBoYXMgbm8gdmFsdWUgbmFtZWQgXCIiICsgaWQgKyAiXCIuIik7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgICAgY2FzZSBHUk9VUDoKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDYW4ndCBnZXQgaGVyZS4iKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAoZmllbGQuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgIHRhcmdldC5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgICB9IGVsc2UgaWYgKChzaW5ndWxhck92ZXJ3cml0ZVBvbGljeQorICAgICAgICAgICAgICA9PSBTaW5ndWxhck92ZXJ3cml0ZVBvbGljeS5GT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUykKKyAgICAgICAgICAmJiB0YXJnZXQuaGFzRmllbGQoZmllbGQpKSB7CisgICAgICAgIHRocm93IHRva2VuaXplci5wYXJzZUV4Y2VwdGlvblByZXZpb3VzVG9rZW4oIk5vbi1yZXBlYXRlZCBmaWVsZCBcIiIKKyAgICAgICAgICAgICsgZmllbGQuZ2V0RnVsbE5hbWUoKSArICJcIiBjYW5ub3QgYmUgb3ZlcndyaXR0ZW4uIik7CisgICAgICB9IGVsc2UgaWYgKChzaW5ndWxhck92ZXJ3cml0ZVBvbGljeQorICAgICAgICAgICAgICA9PSBTaW5ndWxhck92ZXJ3cml0ZVBvbGljeS5GT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUykKKyAgICAgICAgICAmJiBmaWVsZC5nZXRDb250YWluaW5nT25lb2YoKSAhPSBudWxsCisgICAgICAgICAgJiYgdGFyZ2V0Lmhhc09uZW9mKGZpZWxkLmdldENvbnRhaW5pbmdPbmVvZigpKSkgeworICAgICAgICBEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YgPSBmaWVsZC5nZXRDb250YWluaW5nT25lb2YoKTsKKyAgICAgICAgdGhyb3cgdG9rZW5pemVyLnBhcnNlRXhjZXB0aW9uUHJldmlvdXNUb2tlbigiRmllbGQgXCIiCisgICAgICAgICAgICArIGZpZWxkLmdldEZ1bGxOYW1lKCkgKyAiXCIgaXMgc3BlY2lmaWVkIGFsb25nIHdpdGggZmllbGQgXCIiCisgICAgICAgICAgICArIHRhcmdldC5nZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihvbmVvZikuZ2V0RnVsbE5hbWUoKQorICAgICAgICAgICAgKyAiXCIsIGFub3RoZXIgbWVtYmVyIG9mIG9uZW9mIFwiIiArIG9uZW9mLmdldE5hbWUoKSArICJcIi4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRhcmdldC5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIHRoZSBuZXh0IGZpZWxkIGluY2x1ZGluZyB0aGUgZmllbGQncyBuYW1lIGFuZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2tpcEZpZWxkKFRva2VuaXplciB0b2tlbml6ZXIpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBpZiAodG9rZW5pemVyLnRyeUNvbnN1bWUoIlsiKSkgeworICAgICAgICAvLyBFeHRlbnNpb24gbmFtZS4KKyAgICAgICAgZG8geworICAgICAgICAgIHRva2VuaXplci5jb25zdW1lSWRlbnRpZmllcigpOworICAgICAgICB9IHdoaWxlICh0b2tlbml6ZXIudHJ5Q29uc3VtZSgiLiIpKTsKKyAgICAgICAgdG9rZW5pemVyLmNvbnN1bWUoIl0iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRva2VuaXplci5jb25zdW1lSWRlbnRpZmllcigpOworICAgICAgfQorCisgICAgICAvLyBUcnkgdG8gZ3Vlc3MgdGhlIHR5cGUgb2YgdGhpcyBmaWVsZC4KKyAgICAgIC8vIElmIHRoaXMgZmllbGQgaXMgbm90IGEgbWVzc2FnZSwgdGhlcmUgc2hvdWxkIGJlIGEgIjoiIGJldHdlZW4gdGhlCisgICAgICAvLyBmaWVsZCBuYW1lIGFuZCB0aGUgZmllbGQgdmFsdWUgYW5kIGFsc28gdGhlIGZpZWxkIHZhbHVlIHNob3VsZCBub3QKKyAgICAgIC8vIHN0YXJ0IHdpdGggInsiIG9yICI8IiB3aGljaCBpbmRpY2F0ZXMgdGhlIGJlZ2lubmluZyBvZiBhIG1lc3NhZ2UgYm9keS4KKyAgICAgIC8vIElmIHRoZXJlIGlzIG5vICI6IiBvciB0aGVyZSBpcyBhICJ7IiBvciAiPCIgYWZ0ZXIgIjoiLCB0aGlzIGZpZWxkIGhhcworICAgICAgLy8gdG8gYmUgYSBtZXNzYWdlIG9yIHRoZSBpbnB1dCBpcyBpbGwtZm9ybWVkLgorICAgICAgaWYgKHRva2VuaXplci50cnlDb25zdW1lKCI6IikKKyAgICAgICAgICAmJiAhdG9rZW5pemVyLmxvb2tpbmdBdCgiPCIpCisgICAgICAgICAgJiYgIXRva2VuaXplci5sb29raW5nQXQoInsiKSkgeworICAgICAgICBza2lwRmllbGRWYWx1ZSh0b2tlbml6ZXIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2tpcEZpZWxkTWVzc2FnZSh0b2tlbml6ZXIpOworICAgICAgfQorICAgICAgLy8gRm9yIGhpc3RvcmljYWwgcmVhc29ucywgZmllbGRzIG1heSBvcHRpb25hbGx5IGJlIHNlcGFyYXRlZCBieSBjb21tYXMgb3IKKyAgICAgIC8vIHNlbWljb2xvbnMuCisgICAgICBpZiAoIXRva2VuaXplci50cnlDb25zdW1lKCI7IikpIHsKKyAgICAgICAgdG9rZW5pemVyLnRyeUNvbnN1bWUoIiwiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB0aGUgd2hvbGUgYm9keSBvZiBhIG1lc3NhZ2UgaW5jbHVkaW5nIHRoZSBiZWdpbm5pbmcgZGVsaW1pdGVyIGFuZAorICAgICAqIHRoZSBlbmRpbmcgZGVsaW1pdGVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBza2lwRmllbGRNZXNzYWdlKFRva2VuaXplciB0b2tlbml6ZXIpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBTdHJpbmcgZGVsaW1pdGVyOworICAgICAgaWYgKHRva2VuaXplci50cnlDb25zdW1lKCI8IikpIHsKKyAgICAgICAgZGVsaW1pdGVyID0gIj4iOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdG9rZW5pemVyLmNvbnN1bWUoInsiKTsKKyAgICAgICAgZGVsaW1pdGVyID0gIn0iOworICAgICAgfQorICAgICAgd2hpbGUgKCF0b2tlbml6ZXIubG9va2luZ0F0KCI+IikgJiYgIXRva2VuaXplci5sb29raW5nQXQoIn0iKSkgeworICAgICAgICBza2lwRmllbGQodG9rZW5pemVyKTsKKyAgICAgIH0KKyAgICAgIHRva2VuaXplci5jb25zdW1lKGRlbGltaXRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgYSBmaWVsZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2tpcEZpZWxkVmFsdWUoVG9rZW5pemVyIHRva2VuaXplcikgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgIGlmICh0b2tlbml6ZXIudHJ5Q29uc3VtZVN0cmluZygpKSB7CisgICAgICAgIHdoaWxlICh0b2tlbml6ZXIudHJ5Q29uc3VtZVN0cmluZygpKSB7fQorICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBpZiAoIXRva2VuaXplci50cnlDb25zdW1lSWRlbnRpZmllcigpICAgLy8gaW5jbHVkZXMgZW51bSAmIGJvb2xlYW4KKyAgICAgICAgICAmJiAhdG9rZW5pemVyLnRyeUNvbnN1bWVJbnQ2NCgpICAgICAvLyBpbmNsdWRlcyBpbnQzMgorICAgICAgICAgICYmICF0b2tlbml6ZXIudHJ5Q29uc3VtZVVJbnQ2NCgpICAgIC8vIGluY2x1ZGVzIHVpbnQzMgorICAgICAgICAgICYmICF0b2tlbml6ZXIudHJ5Q29uc3VtZURvdWJsZSgpCisgICAgICAgICAgJiYgIXRva2VuaXplci50cnlDb25zdW1lRmxvYXQoKSkgeworICAgICAgICB0aHJvdyB0b2tlbml6ZXIucGFyc2VFeGNlcHRpb24oCisgICAgICAgICAgICAiSW52YWxpZCBmaWVsZCB2YWx1ZTogIiArIHRva2VuaXplci5jdXJyZW50VG9rZW4pOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIFV0aWxpdHkgZnVuY3Rpb25zCisgIC8vCisgIC8vIFNvbWUgb2YgdGhlc2UgbWV0aG9kcyBhcmUgcGFja2FnZS1wcml2YXRlIGJlY2F1c2UgRGVzY3JpcHRvcnMuamF2YSB1c2VzCisgIC8vIHRoZW0uCisKKyAgcHJpdmF0ZSBpbnRlcmZhY2UgQnl0ZVNlcXVlbmNlIHsKKyAgICBpbnQgc2l6ZSgpOworICAgIGJ5dGUgYnl0ZUF0KGludCBvZmZzZXQpOworICB9CisKKyAgLyoqCisgICAqIEVzY2FwZXMgYnl0ZXMgaW4gdGhlIGZvcm1hdCB1c2VkIGluIHByb3RvY29sIGJ1ZmZlciB0ZXh0IGZvcm1hdCwgd2hpY2gKKyAgICogaXMgdGhlIHNhbWUgYXMgdGhlIGZvcm1hdCB1c2VkIGZvciBDIHN0cmluZyBsaXRlcmFscy4gIEFsbCBieXRlcworICAgKiB0aGF0IGFyZSBub3QgcHJpbnRhYmxlIDctYml0IEFTQ0lJIGNoYXJhY3RlcnMgYXJlIGVzY2FwZWQsIGFzIHdlbGwgYXMKKyAgICogYmFja3NsYXNoLCBzaW5nbGUtcXVvdGUsIGFuZCBkb3VibGUtcXVvdGUgY2hhcmFjdGVycy4gIENoYXJhY3RlcnMgZm9yCisgICAqIHdoaWNoIG5vIGRlZmluZWQgc2hvcnQtaGFuZCBlc2NhcGUgc2VxdWVuY2UgaXMgZGVmaW5lZCB3aWxsIGJlIGVzY2FwZWQKKyAgICogdXNpbmcgMy1kaWdpdCBvY3RhbCBzZXF1ZW5jZXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBlc2NhcGVCeXRlcyhmaW5hbCBCeXRlU2VxdWVuY2UgaW5wdXQpIHsKKyAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihpbnB1dC5zaXplKCkpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGZpbmFsIGJ5dGUgYiA9IGlucHV0LmJ5dGVBdChpKTsKKyAgICAgIHN3aXRjaCAoYikgeworICAgICAgICAvLyBKYXZhIGRvZXMgbm90IHJlY29nbml6ZSBcYSBvciBcdiwgYXBwYXJlbnRseS4KKyAgICAgICAgY2FzZSAweDA3OiBidWlsZGVyLmFwcGVuZCgiXFxhIik7IGJyZWFrOworICAgICAgICBjYXNlICdcYic6IGJ1aWxkZXIuYXBwZW5kKCJcXGIiKTsgYnJlYWs7CisgICAgICAgIGNhc2UgJ1xmJzogYnVpbGRlci5hcHBlbmQoIlxcZiIpOyBicmVhazsKKyAgICAgICAgY2FzZSAnXG4nOiBidWlsZGVyLmFwcGVuZCgiXFxuIik7IGJyZWFrOworICAgICAgICBjYXNlICdccic6IGJ1aWxkZXIuYXBwZW5kKCJcXHIiKTsgYnJlYWs7CisgICAgICAgIGNhc2UgJ1x0JzogYnVpbGRlci5hcHBlbmQoIlxcdCIpOyBicmVhazsKKyAgICAgICAgY2FzZSAweDBiOiBidWlsZGVyLmFwcGVuZCgiXFx2Iik7IGJyZWFrOworICAgICAgICBjYXNlICdcXCc6IGJ1aWxkZXIuYXBwZW5kKCJcXFxcIik7IGJyZWFrOworICAgICAgICBjYXNlICdcJyc6IGJ1aWxkZXIuYXBwZW5kKCJcXFwnIik7IGJyZWFrOworICAgICAgICBjYXNlICciJyA6IGJ1aWxkZXIuYXBwZW5kKCJcXFwiIik7IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIC8vIE9ubHkgQVNDSUkgY2hhcmFjdGVycyBiZXR3ZWVuIDB4MjAgKHNwYWNlKSBhbmQgMHg3ZSAodGlsZGUpIGFyZQorICAgICAgICAgIC8vIHByaW50YWJsZS4gIE90aGVyIGJ5dGUgdmFsdWVzIG11c3QgYmUgZXNjYXBlZC4KKyAgICAgICAgICBpZiAoYiA+PSAweDIwICYmIGIgPD0gMHg3ZSkgeworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIGIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgnXFwnKTsKKyAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSAoJzAnICsgKChiID4+PiA2KSAmIDMpKSk7CisgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgKCcwJyArICgoYiA+Pj4gMykgJiA3KSkpOworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpICgnMCcgKyAoYiAmIDcpKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICB9CisKKyAgLyoqCisgICAqIEVzY2FwZXMgYnl0ZXMgaW4gdGhlIGZvcm1hdCB1c2VkIGluIHByb3RvY29sIGJ1ZmZlciB0ZXh0IGZvcm1hdCwgd2hpY2gKKyAgICogaXMgdGhlIHNhbWUgYXMgdGhlIGZvcm1hdCB1c2VkIGZvciBDIHN0cmluZyBsaXRlcmFscy4gIEFsbCBieXRlcworICAgKiB0aGF0IGFyZSBub3QgcHJpbnRhYmxlIDctYml0IEFTQ0lJIGNoYXJhY3RlcnMgYXJlIGVzY2FwZWQsIGFzIHdlbGwgYXMKKyAgICogYmFja3NsYXNoLCBzaW5nbGUtcXVvdGUsIGFuZCBkb3VibGUtcXVvdGUgY2hhcmFjdGVycy4gIENoYXJhY3RlcnMgZm9yCisgICAqIHdoaWNoIG5vIGRlZmluZWQgc2hvcnQtaGFuZCBlc2NhcGUgc2VxdWVuY2UgaXMgZGVmaW5lZCB3aWxsIGJlIGVzY2FwZWQKKyAgICogdXNpbmcgMy1kaWdpdCBvY3RhbCBzZXF1ZW5jZXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBlc2NhcGVCeXRlcyhmaW5hbCBCeXRlU3RyaW5nIGlucHV0KSB7CisgICAgcmV0dXJuIGVzY2FwZUJ5dGVzKG5ldyBCeXRlU2VxdWVuY2UoKSB7CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0LnNpemUoKTsKKyAgICAgIH0KKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGJ5dGUgYnl0ZUF0KGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0LmJ5dGVBdChvZmZzZXQpOworICAgICAgfQorICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIExpa2Uge0BsaW5rICNlc2NhcGVCeXRlcyhCeXRlU3RyaW5nKX0sIGJ1dCB1c2VkIGZvciBieXRlIGFycmF5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZXNjYXBlQnl0ZXMoZmluYWwgYnl0ZVtdIGlucHV0KSB7CisgICAgcmV0dXJuIGVzY2FwZUJ5dGVzKG5ldyBCeXRlU2VxdWVuY2UoKSB7CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0Lmxlbmd0aDsKKyAgICAgIH0KKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGJ5dGUgYnl0ZUF0KGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0W29mZnNldF07CisgICAgICB9CisgICAgfSk7CisgIH0KKworICAvKioKKyAgICogVW4tZXNjYXBlIGEgYnl0ZSBzZXF1ZW5jZSBhcyBlc2NhcGVkIHVzaW5nCisgICAqIHtAbGluayAjZXNjYXBlQnl0ZXMoQnl0ZVN0cmluZyl9LiAgVHdvLWRpZ2l0IGhleCBlc2NhcGVzIChzdGFydGluZyB3aXRoCisgICAqICJceCIpIGFyZSBhbHNvIHJlY29nbml6ZWQuCisgICAqLworICBzdGF0aWMgQnl0ZVN0cmluZyB1bmVzY2FwZUJ5dGVzKGZpbmFsIENoYXJTZXF1ZW5jZSBjaGFyU3RyaW5nKQorICAgICAgdGhyb3dzIEludmFsaWRFc2NhcGVTZXF1ZW5jZUV4Y2VwdGlvbiB7CisgICAgLy8gRmlyc3QgY29udmVydCB0aGUgSmF2YSBjaGFyYWN0ZXIgc2VxdWVuY2UgdG8gVVRGLTggYnl0ZXMuCisgICAgQnl0ZVN0cmluZyBpbnB1dCA9IEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KGNoYXJTdHJpbmcudG9TdHJpbmcoKSk7CisgICAgLy8gVGhlbiB1bmVzY2FwZSBjZXJ0YWluIGJ5dGUgc2VxdWVuY2VzIGludHJvZHVjZWQgYnkgQVNDSUkgJ1xcJy4gIFRoZSB2YWxpZAorICAgIC8vIGVzY2FwZXMgY2FuIGFsbCBiZSBleHByZXNzZWQgd2l0aCBBU0NJSSBjaGFyYWN0ZXJzLCBzbyBpdCBpcyBzYWZlIHRvCisgICAgLy8gb3BlcmF0ZSBvbiBieXRlcyBoZXJlLgorICAgIC8vCisgICAgLy8gVW5lc2NhcGluZyB0aGUgaW5wdXQgYnl0ZSBhcnJheSB3aWxsIHJlc3VsdCBpbiBhIGJ5dGUgc2VxdWVuY2UgdGhhdCdzIG5vCisgICAgLy8gbG9uZ2VyIHRoYW4gdGhlIGlucHV0LiAgVGhhdCdzIGJlY2F1c2UgZWFjaCBlc2NhcGUgc2VxdWVuY2UgaXMgYmV0d2VlbgorICAgIC8vIHR3byBhbmQgZm91ciBieXRlcyBsb25nIGFuZCBzdGFuZHMgZm9yIGEgc2luZ2xlIGJ5dGUuCisgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2lucHV0LnNpemUoKV07CisgICAgaW50IHBvcyA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgICAgYnl0ZSBjID0gaW5wdXQuYnl0ZUF0KGkpOworICAgICAgaWYgKGMgPT0gJ1xcJykgeworICAgICAgICBpZiAoaSArIDEgPCBpbnB1dC5zaXplKCkpIHsKKyAgICAgICAgICArK2k7CisgICAgICAgICAgYyA9IGlucHV0LmJ5dGVBdChpKTsKKyAgICAgICAgICBpZiAoaXNPY3RhbChjKSkgeworICAgICAgICAgICAgLy8gT2N0YWwgZXNjYXBlLgorICAgICAgICAgICAgaW50IGNvZGUgPSBkaWdpdFZhbHVlKGMpOworICAgICAgICAgICAgaWYgKGkgKyAxIDwgaW5wdXQuc2l6ZSgpICYmIGlzT2N0YWwoaW5wdXQuYnl0ZUF0KGkgKyAxKSkpIHsKKyAgICAgICAgICAgICAgKytpOworICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDggKyBkaWdpdFZhbHVlKGlucHV0LmJ5dGVBdChpKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaSArIDEgPCBpbnB1dC5zaXplKCkgJiYgaXNPY3RhbChpbnB1dC5ieXRlQXQoaSArIDEpKSkgeworICAgICAgICAgICAgICArK2k7CisgICAgICAgICAgICAgIGNvZGUgPSBjb2RlICogOCArIGRpZ2l0VmFsdWUoaW5wdXQuYnl0ZUF0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRPRE86IENoZWNrIHRoYXQgMCA8PSBjb2RlICYmIGNvZGUgPD0gMHhGRi4KKyAgICAgICAgICAgIHJlc3VsdFtwb3MrK10gPSAoYnl0ZSkgY29kZTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc3dpdGNoIChjKSB7CisgICAgICAgICAgICAgIGNhc2UgJ2EnIDogcmVzdWx0W3BvcysrXSA9IDB4MDc7IGJyZWFrOworICAgICAgICAgICAgICBjYXNlICdiJyA6IHJlc3VsdFtwb3MrK10gPSAnXGInOyBicmVhazsKKyAgICAgICAgICAgICAgY2FzZSAnZicgOiByZXN1bHRbcG9zKytdID0gJ1xmJzsgYnJlYWs7CisgICAgICAgICAgICAgIGNhc2UgJ24nIDogcmVzdWx0W3BvcysrXSA9ICdcbic7IGJyZWFrOworICAgICAgICAgICAgICBjYXNlICdyJyA6IHJlc3VsdFtwb3MrK10gPSAnXHInOyBicmVhazsKKyAgICAgICAgICAgICAgY2FzZSAndCcgOiByZXN1bHRbcG9zKytdID0gJ1x0JzsgYnJlYWs7CisgICAgICAgICAgICAgIGNhc2UgJ3YnIDogcmVzdWx0W3BvcysrXSA9IDB4MGI7IGJyZWFrOworICAgICAgICAgICAgICBjYXNlICdcXCc6IHJlc3VsdFtwb3MrK10gPSAnXFwnOyBicmVhazsKKyAgICAgICAgICAgICAgY2FzZSAnXCcnOiByZXN1bHRbcG9zKytdID0gJ1wnJzsgYnJlYWs7CisgICAgICAgICAgICAgIGNhc2UgJyInIDogcmVzdWx0W3BvcysrXSA9ICdcIic7IGJyZWFrOworCisgICAgICAgICAgICAgIGNhc2UgJ3gnOgorICAgICAgICAgICAgICAgIC8vIGhleCBlc2NhcGUKKyAgICAgICAgICAgICAgICBpbnQgY29kZSA9IDA7CisgICAgICAgICAgICAgICAgaWYgKGkgKyAxIDwgaW5wdXQuc2l6ZSgpICYmIGlzSGV4KGlucHV0LmJ5dGVBdChpICsgMSkpKSB7CisgICAgICAgICAgICAgICAgICArK2k7CisgICAgICAgICAgICAgICAgICBjb2RlID0gZGlnaXRWYWx1ZShpbnB1dC5ieXRlQXQoaSkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZTogJ1xceCcgd2l0aCBubyBkaWdpdHMiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGkgKyAxIDwgaW5wdXQuc2l6ZSgpICYmIGlzSGV4KGlucHV0LmJ5dGVBdChpICsgMSkpKSB7CisgICAgICAgICAgICAgICAgICArK2k7CisgICAgICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDE2ICsgZGlnaXRWYWx1ZShpbnB1dC5ieXRlQXQoaSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXN1bHRbcG9zKytdID0gKGJ5dGUpIGNvZGU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBlc2NhcGUgc2VxdWVuY2U6ICdcXCIgKyAoY2hhcikgYyArICdcJycpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAiSW52YWxpZCBlc2NhcGUgc2VxdWVuY2U6ICdcXCcgYXQgZW5kIG9mIHN0cmluZy4iKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0W3BvcysrXSA9IGM7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIEJ5dGVTdHJpbmcuY29weUZyb20ocmVzdWx0LCAwLCBwb3MpOworICB9CisKKyAgLyoqCisgICAqIFRocm93biBieSB7QGxpbmsgVGV4dEZvcm1hdCN1bmVzY2FwZUJ5dGVzfSBhbmQKKyAgICoge0BsaW5rIFRleHRGb3JtYXQjdW5lc2NhcGVUZXh0fSB3aGVuIGFuIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlIGlzIHNlZW4uCisgICAqLworICBzdGF0aWMgY2xhc3MgSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MTY0MDMzNjUwMTQyNTkzMzA0TDsKKworICAgIEludmFsaWRFc2NhcGVTZXF1ZW5jZUV4Y2VwdGlvbihmaW5hbCBTdHJpbmcgZGVzY3JpcHRpb24pIHsKKyAgICAgIHN1cGVyKGRlc2NyaXB0aW9uKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTGlrZSB7QGxpbmsgI2VzY2FwZUJ5dGVzKEJ5dGVTdHJpbmcpfSwgYnV0IGVzY2FwZXMgYSB0ZXh0IHN0cmluZy4KKyAgICogTm9uLUFTQ0lJIGNoYXJhY3RlcnMgYXJlIGZpcnN0IGVuY29kZWQgYXMgVVRGLTgsIHRoZW4gZWFjaCBieXRlIGlzIGVzY2FwZWQKKyAgICogaW5kaXZpZHVhbGx5IGFzIGEgMy1kaWdpdCBvY3RhbCBlc2NhcGUuICBZZXMsIGl0J3Mgd2VpcmQuCisgICAqLworICBzdGF0aWMgU3RyaW5nIGVzY2FwZVRleHQoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgcmV0dXJuIGVzY2FwZUJ5dGVzKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KGlucHV0KSk7CisgIH0KKworICAvKioKKyAgICogRXNjYXBlIGRvdWJsZSBxdW90ZXMgYW5kIGJhY2tzbGFzaGVzIGluIGEgU3RyaW5nIGZvciB1bmljb2RlIG91dHB1dCBvZiBhIG1lc3NhZ2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBlc2NhcGVEb3VibGVRdW90ZXNBbmRCYWNrc2xhc2hlcyhmaW5hbCBTdHJpbmcgaW5wdXQpIHsKKyAgICByZXR1cm4gaW5wdXQucmVwbGFjZSgiXFwiLCAiXFxcXCIpLnJlcGxhY2UoIlwiIiwgIlxcXCIiKTsKKyAgfQorCisgIC8qKgorICAgKiBVbi1lc2NhcGUgYSB0ZXh0IHN0cmluZyBhcyBlc2NhcGVkIHVzaW5nIHtAbGluayAjZXNjYXBlVGV4dChTdHJpbmcpfS4KKyAgICogVHdvLWRpZ2l0IGhleCBlc2NhcGVzIChzdGFydGluZyB3aXRoICJceCIpIGFyZSBhbHNvIHJlY29nbml6ZWQuCisgICAqLworICBzdGF0aWMgU3RyaW5nIHVuZXNjYXBlVGV4dChmaW5hbCBTdHJpbmcgaW5wdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkRXNjYXBlU2VxdWVuY2VFeGNlcHRpb24geworICAgIHJldHVybiB1bmVzY2FwZUJ5dGVzKGlucHV0KS50b1N0cmluZ1V0ZjgoKTsKKyAgfQorCisgIC8qKiBJcyB0aGlzIGFuIG9jdGFsIGRpZ2l0PyAqLworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzT2N0YWwoZmluYWwgYnl0ZSBjKSB7CisgICAgcmV0dXJuICcwJyA8PSBjICYmIGMgPD0gJzcnOworICB9CisKKyAgLyoqIElzIHRoaXMgYSBoZXggZGlnaXQ/ICovCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNIZXgoZmluYWwgYnl0ZSBjKSB7CisgICAgcmV0dXJuICgnMCcgPD0gYyAmJiBjIDw9ICc5JykKKyAgICAgICAgfHwgKCdhJyA8PSBjICYmIGMgPD0gJ2YnKQorICAgICAgICB8fCAoJ0EnIDw9IGMgJiYgYyA8PSAnRicpOworICB9CisKKyAgLyoqCisgICAqIEludGVycHJldCBhIGNoYXJhY3RlciBhcyBhIGRpZ2l0IChpbiBhbnkgYmFzZSB1cCB0byAzNikgYW5kIHJldHVybiB0aGUKKyAgICogbnVtZXJpYyB2YWx1ZS4gIFRoaXMgaXMgbGlrZSB7QGNvZGUgQ2hhcmFjdGVyLmRpZ2l0KCl9IGJ1dCB3ZSBkb24ndCBhY2NlcHQKKyAgICogbm9uLUFTQ0lJIGRpZ2l0cy4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGludCBkaWdpdFZhbHVlKGZpbmFsIGJ5dGUgYykgeworICAgIGlmICgnMCcgPD0gYyAmJiBjIDw9ICc5JykgeworICAgICAgcmV0dXJuIGMgLSAnMCc7CisgICAgfSBlbHNlIGlmICgnYScgPD0gYyAmJiBjIDw9ICd6JykgeworICAgICAgcmV0dXJuIGMgLSAnYScgKyAxMDsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGMgLSAnQScgKyAxMDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUGFyc2UgYSAzMi1iaXQgc2lnbmVkIGludGVnZXIgZnJvbSB0aGUgdGV4dC4gIFVubGlrZSB0aGUgSmF2YSBzdGFuZGFyZAorICAgKiB7QGNvZGUgSW50ZWdlci5wYXJzZUludCgpfSwgdGhpcyBmdW5jdGlvbiByZWNvZ25pemVzIHRoZSBwcmVmaXhlcyAiMHgiCisgICAqIGFuZCAiMCIgdG8gc2lnbmlmeSBoZXhhZGVjaW1hbCBhbmQgb2N0YWwgbnVtYmVycywgcmVzcGVjdGl2ZWx5LgorICAgKi8KKyAgc3RhdGljIGludCBwYXJzZUludDMyKGZpbmFsIFN0cmluZyB0ZXh0KSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICByZXR1cm4gKGludCkgcGFyc2VJbnRlZ2VyKHRleHQsIHRydWUsIGZhbHNlKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZSBhIDMyLWJpdCB1bnNpZ25lZCBpbnRlZ2VyIGZyb20gdGhlIHRleHQuICBVbmxpa2UgdGhlIEphdmEgc3RhbmRhcmQKKyAgICoge0Bjb2RlIEludGVnZXIucGFyc2VJbnQoKX0sIHRoaXMgZnVuY3Rpb24gcmVjb2duaXplcyB0aGUgcHJlZml4ZXMgIjB4IgorICAgKiBhbmQgIjAiIHRvIHNpZ25pZnkgaGV4YWRlY2ltYWwgYW5kIG9jdGFsIG51bWJlcnMsIHJlc3BlY3RpdmVseS4gIFRoZQorICAgKiByZXN1bHQgaXMgY29lcmNlZCB0byBhIChzaWduZWQpIHtAY29kZSBpbnR9IHdoZW4gcmV0dXJuZWQgc2luY2UgSmF2YSBoYXMKKyAgICogbm8gdW5zaWduZWQgaW50ZWdlciB0eXBlLgorICAgKi8KKyAgc3RhdGljIGludCBwYXJzZVVJbnQzMihmaW5hbCBTdHJpbmcgdGV4dCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIChpbnQpIHBhcnNlSW50ZWdlcih0ZXh0LCBmYWxzZSwgZmFsc2UpOworICB9CisKKyAgLyoqCisgICAqIFBhcnNlIGEgNjQtYml0IHNpZ25lZCBpbnRlZ2VyIGZyb20gdGhlIHRleHQuICBVbmxpa2UgdGhlIEphdmEgc3RhbmRhcmQKKyAgICoge0Bjb2RlIEludGVnZXIucGFyc2VJbnQoKX0sIHRoaXMgZnVuY3Rpb24gcmVjb2duaXplcyB0aGUgcHJlZml4ZXMgIjB4IgorICAgKiBhbmQgIjAiIHRvIHNpZ25pZnkgaGV4YWRlY2ltYWwgYW5kIG9jdGFsIG51bWJlcnMsIHJlc3BlY3RpdmVseS4KKyAgICovCisgIHN0YXRpYyBsb25nIHBhcnNlSW50NjQoZmluYWwgU3RyaW5nIHRleHQpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgIHJldHVybiBwYXJzZUludGVnZXIodGV4dCwgdHJ1ZSwgdHJ1ZSk7CisgIH0KKworICAvKioKKyAgICogUGFyc2UgYSA2NC1iaXQgdW5zaWduZWQgaW50ZWdlciBmcm9tIHRoZSB0ZXh0LiAgVW5saWtlIHRoZSBKYXZhIHN0YW5kYXJkCisgICAqIHtAY29kZSBJbnRlZ2VyLnBhcnNlSW50KCl9LCB0aGlzIGZ1bmN0aW9uIHJlY29nbml6ZXMgdGhlIHByZWZpeGVzICIweCIKKyAgICogYW5kICIwIiB0byBzaWduaWZ5IGhleGFkZWNpbWFsIGFuZCBvY3RhbCBudW1iZXJzLCByZXNwZWN0aXZlbHkuICBUaGUKKyAgICogcmVzdWx0IGlzIGNvZXJjZWQgdG8gYSAoc2lnbmVkKSB7QGNvZGUgbG9uZ30gd2hlbiByZXR1cm5lZCBzaW5jZSBKYXZhIGhhcworICAgKiBubyB1bnNpZ25lZCBsb25nIHR5cGUuCisgICAqLworICBzdGF0aWMgbG9uZyBwYXJzZVVJbnQ2NChmaW5hbCBTdHJpbmcgdGV4dCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHBhcnNlSW50ZWdlcih0ZXh0LCBmYWxzZSwgdHJ1ZSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBsb25nIHBhcnNlSW50ZWdlcihmaW5hbCBTdHJpbmcgdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1NpZ25lZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc0xvbmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgIGludCBwb3MgPSAwOworCisgICAgYm9vbGVhbiBuZWdhdGl2ZSA9IGZhbHNlOworICAgIGlmICh0ZXh0LnN0YXJ0c1dpdGgoIi0iLCBwb3MpKSB7CisgICAgICBpZiAoIWlzU2lnbmVkKSB7CisgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIk51bWJlciBtdXN0IGJlIHBvc2l0aXZlOiAiICsgdGV4dCk7CisgICAgICB9CisgICAgICArK3BvczsKKyAgICAgIG5lZ2F0aXZlID0gdHJ1ZTsKKyAgICB9CisKKyAgICBpbnQgcmFkaXggPSAxMDsKKyAgICBpZiAodGV4dC5zdGFydHNXaXRoKCIweCIsIHBvcykpIHsKKyAgICAgIHBvcyArPSAyOworICAgICAgcmFkaXggPSAxNjsKKyAgICB9IGVsc2UgaWYgKHRleHQuc3RhcnRzV2l0aCgiMCIsIHBvcykpIHsKKyAgICAgIHJhZGl4ID0gODsKKyAgICB9CisKKyAgICBmaW5hbCBTdHJpbmcgbnVtYmVyVGV4dCA9IHRleHQuc3Vic3RyaW5nKHBvcyk7CisKKyAgICBsb25nIHJlc3VsdCA9IDA7CisgICAgaWYgKG51bWJlclRleHQubGVuZ3RoKCkgPCAxNikgeworICAgICAgLy8gQ2FuIHNhZmVseSBhc3N1bWUgbm8gb3ZlcmZsb3cuCisgICAgICByZXN1bHQgPSBMb25nLnBhcnNlTG9uZyhudW1iZXJUZXh0LCByYWRpeCk7CisgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgcmVzdWx0ID0gLXJlc3VsdDsKKyAgICAgIH0KKworICAgICAgLy8gQ2hlY2sgYm91bmRzLgorICAgICAgLy8gTm8gbmVlZCB0byBjaGVjayBmb3IgNjQtYml0IG51bWJlcnMgc2luY2UgdGhleSdkIGhhdmUgdG8gYmUgMTYgY2hhcnMKKyAgICAgIC8vIG9yIGxvbmdlciB0byBvdmVyZmxvdy4KKyAgICAgIGlmICghaXNMb25nKSB7CisgICAgICAgIGlmIChpc1NpZ25lZCkgeworICAgICAgICAgIGlmIChyZXN1bHQgPiBJbnRlZ2VyLk1BWF9WQUxVRSB8fCByZXN1bHQgPCBJbnRlZ2VyLk1JTl9WQUxVRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIk51bWJlciBvdXQgb2YgcmFuZ2UgZm9yIDMyLWJpdCBzaWduZWQgaW50ZWdlcjogIiArIHRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAocmVzdWx0ID49ICgxTCA8PCAzMikgfHwgcmVzdWx0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIk51bWJlciBvdXQgb2YgcmFuZ2UgZm9yIDMyLWJpdCB1bnNpZ25lZCBpbnRlZ2VyOiAiICsgdGV4dCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIEJpZ0ludGVnZXIgYmlnVmFsdWUgPSBuZXcgQmlnSW50ZWdlcihudW1iZXJUZXh0LCByYWRpeCk7CisgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgYmlnVmFsdWUgPSBiaWdWYWx1ZS5uZWdhdGUoKTsKKyAgICAgIH0KKworICAgICAgLy8gQ2hlY2sgYm91bmRzLgorICAgICAgaWYgKCFpc0xvbmcpIHsKKyAgICAgICAgaWYgKGlzU2lnbmVkKSB7CisgICAgICAgICAgaWYgKGJpZ1ZhbHVlLmJpdExlbmd0aCgpID4gMzEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oCisgICAgICAgICAgICAgICJOdW1iZXIgb3V0IG9mIHJhbmdlIGZvciAzMi1iaXQgc2lnbmVkIGludGVnZXI6ICIgKyB0ZXh0KTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKGJpZ1ZhbHVlLmJpdExlbmd0aCgpID4gMzIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oCisgICAgICAgICAgICAgICJOdW1iZXIgb3V0IG9mIHJhbmdlIGZvciAzMi1iaXQgdW5zaWduZWQgaW50ZWdlcjogIiArIHRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGlzU2lnbmVkKSB7CisgICAgICAgICAgaWYgKGJpZ1ZhbHVlLmJpdExlbmd0aCgpID4gNjMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oCisgICAgICAgICAgICAgICJOdW1iZXIgb3V0IG9mIHJhbmdlIGZvciA2NC1iaXQgc2lnbmVkIGludGVnZXI6ICIgKyB0ZXh0KTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKGJpZ1ZhbHVlLmJpdExlbmd0aCgpID4gNjQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oCisgICAgICAgICAgICAgICJOdW1iZXIgb3V0IG9mIHJhbmdlIGZvciA2NC1iaXQgdW5zaWduZWQgaW50ZWdlcjogIiArIHRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorCisgICAgICByZXN1bHQgPSBiaWdWYWx1ZS5sb25nVmFsdWUoKTsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbi5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzE0YzA2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gYnVpbGQgYSBwcm90b2NvbCBtZXNzYWdlIHRoYXQgaXMgbWlzc2luZyByZXF1aXJlZAorICogZmllbGRzLiAgVGhpcyBpcyBhIHtAY29kZSBSdW50aW1lRXhjZXB0aW9ufSBiZWNhdXNlIGl0IG5vcm1hbGx5IHJlcHJlc2VudHMKKyAqIGEgcHJvZ3JhbW1pbmcgZXJyb3I6ICBpdCBoYXBwZW5zIHdoZW4gc29tZSBjb2RlIHdoaWNoIGNvbnN0cnVjdHMgYSBtZXNzYWdlCisgKiBmYWlscyB0byBzZXQgYWxsIHRoZSBmaWVsZHMuICB7QGNvZGUgcGFyc2VGcm9tKCl9IG1ldGhvZHMgPGI+ZG8gbm90PC9iPgorICogdGhyb3cgdGhpczsgdGhleSB0aHJvdyBhbiB7QGxpbmsgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9ufSBpZgorICogcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nLCBiZWNhdXNlIGl0IGlzIG5vdCBhIHByb2dyYW1taW5nIGVycm9yIHRvCisgKiByZWNlaXZlIGFuIGluY29tcGxldGUgbWVzc2FnZS4gIEluIG90aGVyIHdvcmRzLAorICoge0Bjb2RlIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9ufSBzaG91bGQgbmV2ZXIgYmUgdGhyb3duIGJ5IGNvcnJlY3QKKyAqIGNvZGUsIGJ1dCB7QGNvZGUgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9ufSBtaWdodCBiZS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgY2xhc3MgVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc0NjY5Mjk5NTMzNzQ4ODM1MDdMOworCisgIHB1YmxpYyBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihmaW5hbCBNZXNzYWdlTGl0ZSBtZXNzYWdlKSB7CisgICAgc3VwZXIoIk1lc3NhZ2Ugd2FzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLiAgKExpdGUgcnVudGltZSBjb3VsZCBub3QgIiArCisgICAgICAgICAgImRldGVybWluZSB3aGljaCBmaWVsZHMgd2VyZSBtaXNzaW5nKS4iKTsKKyAgICBtaXNzaW5nRmllbGRzID0gbnVsbDsKKyAgfQorCisgIHB1YmxpYyBVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihmaW5hbCBMaXN0PFN0cmluZz4gbWlzc2luZ0ZpZWxkcykgeworICAgIHN1cGVyKGJ1aWxkRGVzY3JpcHRpb24obWlzc2luZ0ZpZWxkcykpOworICAgIHRoaXMubWlzc2luZ0ZpZWxkcyA9IG1pc3NpbmdGaWVsZHM7CisgIH0KKworICBwcml2YXRlIGZpbmFsIExpc3Q8U3RyaW5nPiBtaXNzaW5nRmllbGRzOworCisgIC8qKgorICAgKiBHZXQgYSBsaXN0IG9mIGh1bWFuLXJlYWRhYmxlIG5hbWVzIG9mIHJlcXVpcmVkIGZpZWxkcyBtaXNzaW5nIGZyb20gdGhpcworICAgKiBtZXNzYWdlLiAgRWFjaCBuYW1lIGlzIGEgZnVsbCBwYXRoIHRvIGEgZmllbGQsIGUuZy4gImZvby5iYXJbNV0uYmF6Ii4KKyAgICogUmV0dXJucyBudWxsIGlmIHRoZSBsaXRlIHJ1bnRpbWUgd2FzIHVzZWQsIHNpbmNlIGl0IGxhY2tzIHRoZSBhYmlsaXR5IHRvCisgICAqIGZpbmQgbWlzc2luZyBmaWVsZHMuCisgICAqLworICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldE1pc3NpbmdGaWVsZHMoKSB7CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobWlzc2luZ0ZpZWxkcyk7CisgIH0KKworICAvKioKKyAgICogQ29udmVydHMgdGhpcyBleGNlcHRpb24gdG8gYW4ge0BsaW5rIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbn0uCisgICAqIFdoZW4gYSBwYXJzZWQgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcywgdGhpcyBzaG91bGQgYmUgdGhyb3duCisgICAqIGluc3RlYWQgb2Yge0Bjb2RlIFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9ufS4KKyAgICovCisgIHB1YmxpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZ2V0TWVzc2FnZSgpKTsKKyAgfQorCisgIC8qKiBDb25zdHJ1Y3QgdGhlIGRlc2NyaXB0aW9uIHN0cmluZyBmb3IgdGhpcyBleGNlcHRpb24uICovCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBidWlsZERlc2NyaXB0aW9uKGZpbmFsIExpc3Q8U3RyaW5nPiBtaXNzaW5nRmllbGRzKSB7CisgICAgZmluYWwgU3RyaW5nQnVpbGRlciBkZXNjcmlwdGlvbiA9CisgICAgICBuZXcgU3RyaW5nQnVpbGRlcigiTWVzc2FnZSBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogIik7CisgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisgICAgZm9yIChmaW5hbCBTdHJpbmcgZmllbGQgOiBtaXNzaW5nRmllbGRzKSB7CisgICAgICBpZiAoZmlyc3QpIHsKKyAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGRlc2NyaXB0aW9uLmFwcGVuZCgiLCAiKTsKKyAgICAgIH0KKyAgICAgIGRlc2NyaXB0aW9uLmFwcGVuZChmaWVsZCk7CisgICAgfQorICAgIHJldHVybiBkZXNjcmlwdGlvbi50b1N0cmluZygpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXQuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Vua25vd25GaWVsZFNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjZDIyNTAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXQuamF2YQpAQCAtMCwwICsxLDEwMTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5MaW1pdGVkSW5wdXRTdHJlYW07CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworCisvKioKKyAqIHtAY29kZSBVbmtub3duRmllbGRTZXR9IGlzIHVzZWQgdG8ga2VlcCB0cmFjayBvZiBmaWVsZHMgd2hpY2ggd2VyZSBzZWVuIHdoZW4KKyAqIHBhcnNpbmcgYSBwcm90b2NvbCBtZXNzYWdlIGJ1dCB3aG9zZSBmaWVsZCBudW1iZXJzIG9yIHR5cGVzIGFyZSB1bnJlY29nbml6ZWQuCisgKiBUaGlzIG1vc3QgZnJlcXVlbnRseSBvY2N1cnMgd2hlbiBuZXcgZmllbGRzIGFyZSBhZGRlZCB0byBhIG1lc3NhZ2UgdHlwZQorICogYW5kIHRoZW4gbWVzc2FnZXMgY29udGFpbmluZyB0aG9zZSBmaWVsZHMgYXJlIHJlYWQgYnkgb2xkIHNvZnR3YXJlIHRoYXQgd2FzCisgKiBjb21waWxlZCBiZWZvcmUgdGhlIG5ldyB0eXBlcyB3ZXJlIGFkZGVkLgorICoKKyAqIDxwPkV2ZXJ5IHtAbGluayBNZXNzYWdlfSBjb250YWlucyBhbiB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fSAoYW5kIGV2ZXJ5CisgKiB7QGxpbmsgTWVzc2FnZS5CdWlsZGVyfSBjb250YWlucyBhbiB7QGxpbmsgQnVpbGRlcn0pLgorICoKKyAqIDxwPk1vc3QgdXNlcnMgd2lsbCBuZXZlciBuZWVkIHRvIHVzZSB0aGlzIGNsYXNzLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVbmtub3duRmllbGRTZXQgaW1wbGVtZW50cyBNZXNzYWdlTGl0ZSB7CisgIHByaXZhdGUgVW5rbm93bkZpZWxkU2V0KCkge30KKworICAvKiogQ3JlYXRlIGEgbmV3IHtAbGluayBCdWlsZGVyfS4gKi8KKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIEJ1aWxkZXIuY3JlYXRlKCk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IHtAbGluayBCdWlsZGVyfSBhbmQgaW5pdGlhbGl6ZSBpdCB0byBiZSBhIGNvcHkKKyAgICogb2Yge0Bjb2RlIGNvcHlGcm9tfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGZpbmFsIFVua25vd25GaWVsZFNldCBjb3B5RnJvbSkgeworICAgIHJldHVybiBuZXdCdWlsZGVyKCkubWVyZ2VGcm9tKGNvcHlGcm9tKTsKKyAgfQorCisgIC8qKiBHZXQgYW4gZW1wdHkge0Bjb2RlIFVua25vd25GaWVsZFNldH0uICovCisgIHB1YmxpYyBzdGF0aWMgVW5rbm93bkZpZWxkU2V0IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKKyAgICByZXR1cm4gZGVmYXVsdEluc3RhbmNlOworICB9CisgIHB1YmxpYyBVbmtub3duRmllbGRTZXQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKKyAgICByZXR1cm4gZGVmYXVsdEluc3RhbmNlOworICB9CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVua25vd25GaWVsZFNldCBkZWZhdWx0SW5zdGFuY2UgPQorICAgIG5ldyBVbmtub3duRmllbGRTZXQoQ29sbGVjdGlvbnMuPEludGVnZXIsIEZpZWxkPmVtcHR5TWFwKCkpOworCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgYW4ge0Bjb2RlIFVua25vd25GaWVsZFNldH0gYXJvdW5kIHRoZSBnaXZlbiBtYXAuICBUaGUgbWFwIGlzCisgICAqIGV4cGVjdGVkIHRvIGJlIGltbXV0YWJsZS4KKyAgICovCisgIHByaXZhdGUgVW5rbm93bkZpZWxkU2V0KGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZD4gZmllbGRzKSB7CisgICAgdGhpcy5maWVsZHMgPSBmaWVsZHM7CisgIH0KKyAgcHJpdmF0ZSBNYXA8SW50ZWdlciwgRmllbGQ+IGZpZWxkczsKKworCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG90aGVyKSB7CisgICAgaWYgKHRoaXMgPT0gb3RoZXIpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICByZXR1cm4gKG90aGVyIGluc3RhbmNlb2YgVW5rbm93bkZpZWxkU2V0KSAmJgorICAgICAgICAgICBmaWVsZHMuZXF1YWxzKCgoVW5rbm93bkZpZWxkU2V0KSBvdGhlcikuZmllbGRzKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiBmaWVsZHMuaGFzaENvZGUoKTsKKyAgfQorCisgIC8qKiBHZXQgYSBtYXAgb2YgZmllbGRzIGluIHRoZSBzZXQgYnkgbnVtYmVyLiAqLworICBwdWJsaWMgTWFwPEludGVnZXIsIEZpZWxkPiBhc01hcCgpIHsKKyAgICByZXR1cm4gZmllbGRzOworICB9CisKKyAgLyoqIENoZWNrIGlmIHRoZSBnaXZlbiBmaWVsZCBudW1iZXIgaXMgcHJlc2VudCBpbiB0aGUgc2V0LiAqLworICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChmaW5hbCBpbnQgbnVtYmVyKSB7CisgICAgcmV0dXJuIGZpZWxkcy5jb250YWluc0tleShudW1iZXIpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIGZpZWxkIGJ5IG51bWJlci4gIFJldHVybnMgYW4gZW1wdHkgZmllbGQgaWYgbm90IHByZXNlbnQuICBOZXZlcgorICAgKiByZXR1cm5zIHtAY29kZSBudWxsfS4KKyAgICovCisgIHB1YmxpYyBGaWVsZCBnZXRGaWVsZChmaW5hbCBpbnQgbnVtYmVyKSB7CisgICAgZmluYWwgRmllbGQgcmVzdWx0ID0gZmllbGRzLmdldChudW1iZXIpOworICAgIHJldHVybiAocmVzdWx0ID09IG51bGwpID8gRmllbGQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXN1bHQ7CisgIH0KKworICAvKiogU2VyaWFsaXplcyB0aGUgc2V0IGFuZCB3cml0ZXMgaXQgdG8ge0Bjb2RlIG91dHB1dH0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEludGVnZXIsIEZpZWxkPiBlbnRyeSA6IGZpZWxkcy5lbnRyeVNldCgpKSB7CisgICAgICBlbnRyeS5nZXRWYWx1ZSgpLndyaXRlVG8oZW50cnkuZ2V0S2V5KCksIG91dHB1dCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbnZlcnRzIHRoZSBzZXQgdG8gYSBzdHJpbmcgaW4gcHJvdG9jb2wgYnVmZmVyIHRleHQgZm9ybWF0LiBUaGlzIGlzCisgICAqIGp1c3QgYSB0cml2aWFsIHdyYXBwZXIgYXJvdW5kCisgICAqIHtAbGluayBUZXh0Rm9ybWF0I3ByaW50VG9TdHJpbmcoVW5rbm93bkZpZWxkU2V0KX0uCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gVGV4dEZvcm1hdC5wcmludFRvU3RyaW5nKHRoaXMpOworICB9CisKKyAgLyoqCisgICAqIFNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgdG8gYSB7QGNvZGUgQnl0ZVN0cmluZ30gYW5kIHJldHVybnMgaXQuIFRoaXMgaXMKKyAgICoganVzdCBhIHRyaXZpYWwgd3JhcHBlciBhcm91bmQge0BsaW5rICN3cml0ZVRvKENvZGVkT3V0cHV0U3RyZWFtKX0uCisgICAqLworICBwdWJsaWMgQnl0ZVN0cmluZyB0b0J5dGVTdHJpbmcoKSB7CisgICAgdHJ5IHsKKyAgICAgIGZpbmFsIEJ5dGVTdHJpbmcuQ29kZWRCdWlsZGVyIG91dCA9CisgICAgICAgIEJ5dGVTdHJpbmcubmV3Q29kZWRCdWlsZGVyKGdldFNlcmlhbGl6ZWRTaXplKCkpOworICAgICAgd3JpdGVUbyhvdXQuZ2V0Q29kZWRPdXRwdXQoKSk7CisgICAgICByZXR1cm4gb3V0LmJ1aWxkKCk7CisgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICJTZXJpYWxpemluZyB0byBhIEJ5dGVTdHJpbmcgdGhyZXcgYW4gSU9FeGNlcHRpb24gKHNob3VsZCAiICsKKyAgICAgICAgIm5ldmVyIGhhcHBlbikuIiwgZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgdG8gYSB7QGNvZGUgYnl0ZX0gYXJyYXkgYW5kIHJldHVybnMgaXQuICBUaGlzIGlzCisgICAqIGp1c3QgYSB0cml2aWFsIHdyYXBwZXIgYXJvdW5kIHtAbGluayAjd3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbSl9LgorICAgKi8KKyAgcHVibGljIGJ5dGVbXSB0b0J5dGVBcnJheSgpIHsKKyAgICB0cnkgeworICAgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2dldFNlcmlhbGl6ZWRTaXplKCldOworICAgICAgZmluYWwgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UocmVzdWx0KTsKKyAgICAgIHdyaXRlVG8ob3V0cHV0KTsKKyAgICAgIG91dHB1dC5jaGVja05vU3BhY2VMZWZ0KCk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAiU2VyaWFsaXppbmcgdG8gYSBieXRlIGFycmF5IHRocmV3IGFuIElPRXhjZXB0aW9uICIgKworICAgICAgICAiKHNob3VsZCBuZXZlciBoYXBwZW4pLiIsIGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTZXJpYWxpemVzIHRoZSBtZXNzYWdlIGFuZCB3cml0ZXMgaXQgdG8ge0Bjb2RlIG91dHB1dH0uICBUaGlzIGlzIGp1c3QgYQorICAgKiB0cml2aWFsIHdyYXBwZXIgYXJvdW5kIHtAbGluayAjd3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbSl9LgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVUbyhmaW5hbCBPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkT3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2Uob3V0cHV0KTsKKyAgICB3cml0ZVRvKGNvZGVkT3V0cHV0KTsKKyAgICBjb2RlZE91dHB1dC5mbHVzaCgpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGVEZWxpbWl0ZWRUbyhPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkT3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2Uob3V0cHV0KTsKKyAgICBjb2RlZE91dHB1dC53cml0ZVJhd1ZhcmludDMyKGdldFNlcmlhbGl6ZWRTaXplKCkpOworICAgIHdyaXRlVG8oY29kZWRPdXRwdXQpOworICAgIGNvZGVkT3V0cHV0LmZsdXNoKCk7CisgIH0KKworICAvKiogR2V0IHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gZW5jb2RlIHRoaXMgc2V0LiAqLworICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgeworICAgIGludCByZXN1bHQgPSAwOworICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEludGVnZXIsIEZpZWxkPiBlbnRyeSA6IGZpZWxkcy5lbnRyeVNldCgpKSB7CisgICAgICByZXN1bHQgKz0gZW50cnkuZ2V0VmFsdWUoKS5nZXRTZXJpYWxpemVkU2l6ZShlbnRyeS5nZXRLZXkoKSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogU2VyaWFsaXplcyB0aGUgc2V0IGFuZCB3cml0ZXMgaXQgdG8ge0Bjb2RlIG91dHB1dH0gdXNpbmcKKyAgICoge0Bjb2RlIE1lc3NhZ2VTZXR9IHdpcmUgZm9ybWF0LgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVBc01lc3NhZ2VTZXRUbyhmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEludGVnZXIsIEZpZWxkPiBlbnRyeSA6IGZpZWxkcy5lbnRyeVNldCgpKSB7CisgICAgICBlbnRyeS5nZXRWYWx1ZSgpLndyaXRlQXNNZXNzYWdlU2V0RXh0ZW5zaW9uVG8oCisgICAgICAgIGVudHJ5LmdldEtleSgpLCBvdXRwdXQpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBlbmNvZGUgdGhpcyBzZXQgdXNpbmcKKyAgICoge0Bjb2RlIE1lc3NhZ2VTZXR9IHdpcmUgZm9ybWF0LgorICAgKi8KKyAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZUFzTWVzc2FnZVNldCgpIHsKKyAgICBpbnQgcmVzdWx0ID0gMDsKKyAgICBmb3IgKGZpbmFsIE1hcC5FbnRyeTxJbnRlZ2VyLCBGaWVsZD4gZW50cnkgOiBmaWVsZHMuZW50cnlTZXQoKSkgeworICAgICAgcmVzdWx0ICs9IGVudHJ5LmdldFZhbHVlKCkuZ2V0U2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXRFeHRlbnNpb24oCisgICAgICAgIGVudHJ5LmdldEtleSgpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CisgICAgLy8gVW5rbm93bkZpZWxkU2V0cyBkbyBub3QgaGF2ZSByZXF1aXJlZCBmaWVsZHMsIHNvIHRoZXkgYXJlIGFsd2F5cworICAgIC8vIGluaXRpYWxpemVkLgorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqIFBhcnNlIGFuIHtAY29kZSBVbmtub3duRmllbGRTZXR9IGZyb20gdGhlIGdpdmVuIGlucHV0IHN0cmVhbS4gKi8KKyAgcHVibGljIHN0YXRpYyBVbmtub3duRmllbGRTZXQgcGFyc2VGcm9tKGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBuZXdCdWlsZGVyKCkubWVyZ2VGcm9tKGlucHV0KS5idWlsZCgpOworICB9CisKKyAgLyoqIFBhcnNlIHtAY29kZSBkYXRhfSBhcyBhbiB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fSBhbmQgcmV0dXJuIGl0LiAqLworICBwdWJsaWMgc3RhdGljIFVua25vd25GaWVsZFNldCBwYXJzZUZyb20oZmluYWwgQnl0ZVN0cmluZyBkYXRhKQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIoKS5tZXJnZUZyb20oZGF0YSkuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYW4ge0Bjb2RlIFVua25vd25GaWVsZFNldH0gYW5kIHJldHVybiBpdC4gKi8KKyAgcHVibGljIHN0YXRpYyBVbmtub3duRmllbGRTZXQgcGFyc2VGcm9tKGZpbmFsIGJ5dGVbXSBkYXRhKQorICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIoKS5tZXJnZUZyb20oZGF0YSkuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBQYXJzZSBhbiB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIHJldHVybiBpdC4gKi8KKyAgcHVibGljIHN0YXRpYyBVbmtub3duRmllbGRTZXQgcGFyc2VGcm9tKGZpbmFsIElucHV0U3RyZWFtIGlucHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3QnVpbGRlcigpLm1lcmdlRnJvbShpbnB1dCkuYnVpbGQoKTsKKyAgfQorCisgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeworICAgIHJldHVybiBuZXdCdWlsZGVyKCk7CisgIH0KKworICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ld0J1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CisgIH0KKworICAvKioKKyAgICogQnVpbGRlciBmb3Ige0BsaW5rIFVua25vd25GaWVsZFNldH1zLgorICAgKgorICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBjbGFzcyBtYWludGFpbnMge0BsaW5rIEZpZWxkLkJ1aWxkZXJ9cyBmb3IgYWxsIGZpZWxkcworICAgKiBpbiB0aGUgc2V0LiAgVGh1cywgYWRkaW5nIG9uZSBlbGVtZW50IHRvIGFuIGV4aXN0aW5nIHtAbGluayBGaWVsZH0gZG9lcyBub3QKKyAgICogcmVxdWlyZSBtYWtpbmcgYSBjb3B5LiAgVGhpcyBpcyBpbXBvcnRhbnQgZm9yIGVmZmljaWVudCBwYXJzaW5nIG9mCisgICAqIHVua25vd24gcmVwZWF0ZWQgZmllbGRzLiAgSG93ZXZlciwgaXQgaW1wbGllcyB0aGF0IHtAbGluayBGaWVsZH1zIGNhbm5vdAorICAgKiBiZSBjb25zdHJ1Y3RlZCBpbmRlcGVuZGVudGx5LCBub3IgY2FuIHR3byB7QGxpbmsgVW5rbm93bkZpZWxkU2V0fXMgc2hhcmUKKyAgICogdGhlIHNhbWUge0Bjb2RlIEZpZWxkfSBvYmplY3QuCisgICAqCisgICAqIDxwPlVzZSB7QGxpbmsgVW5rbm93bkZpZWxkU2V0I25ld0J1aWxkZXIoKX0gdG8gY29uc3RydWN0IGEge0Bjb2RlIEJ1aWxkZXJ9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGltcGxlbWVudHMgTWVzc2FnZUxpdGUuQnVpbGRlciB7CisgICAgLy8gVGhpcyBjb25zdHJ1Y3RvciBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkIGRpcmVjdGx5IChleGNlcHQgZnJvbSAnY3JlYXRlJykuCisgICAgcHJpdmF0ZSBCdWlsZGVyKCkge30KKworICAgIHByaXZhdGUgTWFwPEludGVnZXIsIEZpZWxkPiBmaWVsZHM7CisKKyAgICAvLyBPcHRpbWl6YXRpb246ICBXZSBrZWVwIGFyb3VuZCBhIGJ1aWxkZXIgZm9yIHRoZSBsYXN0IGZpZWxkIHRoYXQgd2FzCisgICAgLy8gICBtb2RpZmllZCBzbyB0aGF0IHdlIGNhbiBlZmZpY2llbnRseSBhZGQgdG8gaXQgbXVsdGlwbGUgdGltZXMgaW4gYQorICAgIC8vICAgcm93IChpbXBvcnRhbnQgd2hlbiBwYXJzaW5nIGFuIHVua25vd24gcmVwZWF0ZWQgZmllbGQpLgorICAgIHByaXZhdGUgaW50IGxhc3RGaWVsZE51bWJlcjsKKyAgICBwcml2YXRlIEZpZWxkLkJ1aWxkZXIgbGFzdEZpZWxkOworCisgICAgcHJpdmF0ZSBzdGF0aWMgQnVpbGRlciBjcmVhdGUoKSB7CisgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcigpOworICAgICAgYnVpbGRlci5yZWluaXRpYWxpemUoKTsKKyAgICAgIHJldHVybiBidWlsZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIGZpZWxkIGJ1aWxkZXIgZm9yIHRoZSBnaXZlbiBmaWVsZCBudW1iZXIgd2hpY2ggaW5jbHVkZXMgYW55CisgICAgICogdmFsdWVzIHRoYXQgYWxyZWFkeSBleGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEZpZWxkLkJ1aWxkZXIgZ2V0RmllbGRCdWlsZGVyKGZpbmFsIGludCBudW1iZXIpIHsKKyAgICAgIGlmIChsYXN0RmllbGQgIT0gbnVsbCkgeworICAgICAgICBpZiAobnVtYmVyID09IGxhc3RGaWVsZE51bWJlcikgeworICAgICAgICAgIHJldHVybiBsYXN0RmllbGQ7CisgICAgICAgIH0KKyAgICAgICAgLy8gTm90ZTogIGFkZEZpZWxkKCkgd2lsbCByZXNldCBsYXN0RmllbGQgYW5kIGxhc3RGaWVsZE51bWJlci4KKyAgICAgICAgYWRkRmllbGQobGFzdEZpZWxkTnVtYmVyLCBsYXN0RmllbGQuYnVpbGQoKSk7CisgICAgICB9CisgICAgICBpZiAobnVtYmVyID09IDApIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9IGVsc2UgeworICAgICAgICBmaW5hbCBGaWVsZCBleGlzdGluZyA9IGZpZWxkcy5nZXQobnVtYmVyKTsKKyAgICAgICAgbGFzdEZpZWxkTnVtYmVyID0gbnVtYmVyOworICAgICAgICBsYXN0RmllbGQgPSBGaWVsZC5uZXdCdWlsZGVyKCk7CisgICAgICAgIGlmIChleGlzdGluZyAhPSBudWxsKSB7CisgICAgICAgICAgbGFzdEZpZWxkLm1lcmdlRnJvbShleGlzdGluZyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxhc3RGaWVsZDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWlsZCB0aGUge0BsaW5rIFVua25vd25GaWVsZFNldH0gYW5kIHJldHVybiBpdC4KKyAgICAgKgorICAgICAqIDxwPk9uY2Uge0Bjb2RlIGJ1aWxkKCl9IGhhcyBiZWVuIGNhbGxlZCwgdGhlIHtAY29kZSBCdWlsZGVyfSB3aWxsIG5vCisgICAgICogbG9uZ2VyIGJlIHVzYWJsZS4gIENhbGxpbmcgYW55IG1ldGhvZCBhZnRlciB7QGNvZGUgYnVpbGQoKX0gd2lsbCByZXN1bHQKKyAgICAgKiBpbiB1bmRlZmluZWQgYmVoYXZpb3IgYW5kIGNhbiBjYXVzZSBhIHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbn0gdG8gYmUKKyAgICAgKiB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIFVua25vd25GaWVsZFNldCBidWlsZCgpIHsKKyAgICAgIGdldEZpZWxkQnVpbGRlcigwKTsgIC8vIEZvcmNlIGxhc3RGaWVsZCB0byBiZSBidWlsdC4KKyAgICAgIGZpbmFsIFVua25vd25GaWVsZFNldCByZXN1bHQ7CisgICAgICBpZiAoZmllbGRzLmlzRW1wdHkoKSkgeworICAgICAgICByZXN1bHQgPSBnZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdCA9IG5ldyBVbmtub3duRmllbGRTZXQoQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGZpZWxkcykpOworICAgICAgfQorICAgICAgZmllbGRzID0gbnVsbDsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIFVua25vd25GaWVsZFNldCBidWlsZFBhcnRpYWwoKSB7CisgICAgICAvLyBObyByZXF1aXJlZCBmaWVsZHMsIHNvIHRoaXMgaXMgdGhlIHNhbWUgYXMgYnVpbGQoKS4KKyAgICAgIHJldHVybiBidWlsZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgeworICAgICAgZ2V0RmllbGRCdWlsZGVyKDApOyAgLy8gRm9yY2UgbGFzdEZpZWxkIHRvIGJlIGJ1aWx0LgorICAgICAgcmV0dXJuIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkubWVyZ2VGcm9tKAorICAgICAgICAgIG5ldyBVbmtub3duRmllbGRTZXQoZmllbGRzKSk7CisgICAgfQorCisgICAgcHVibGljIFVua25vd25GaWVsZFNldCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIFVua25vd25GaWVsZFNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVpbml0aWFsaXplKCkgeworICAgICAgZmllbGRzID0gQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKKyAgICAgIGxhc3RGaWVsZE51bWJlciA9IDA7CisgICAgICBsYXN0RmllbGQgPSBudWxsOworICAgIH0KKworICAgIC8qKiBSZXNldCB0aGUgYnVpbGRlciB0byBhbiBlbXB0eSBzZXQuICovCisgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CisgICAgICByZWluaXRpYWxpemUoKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKyAgICAKKyAgICAvKiogQ2xlYXIgZmllbGRzIGZyb20gdGhlIHNldCB3aXRoIGEgZ2l2ZW4gZmllbGQgbnVtYmVyLiAqLworICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoZmluYWwgaW50IG51bWJlcikgeworICAgICAgaWYgKG51bWJlciA9PSAwKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlplcm8gaXMgbm90IGEgdmFsaWQgZmllbGQgbnVtYmVyLiIpOworICAgICAgfQorICAgICAgaWYgKGxhc3RGaWVsZCAhPSBudWxsICYmIGxhc3RGaWVsZE51bWJlciA9PSBudW1iZXIpIHsKKyAgICAgICAgLy8gRGlzY2FyZCB0aGlzLgorICAgICAgICBsYXN0RmllbGQgPSBudWxsOworICAgICAgICBsYXN0RmllbGROdW1iZXIgPSAwOworICAgICAgfQorICAgICAgaWYgKGZpZWxkcy5jb250YWluc0tleShudW1iZXIpKSB7CisgICAgICAgIGZpZWxkcy5yZW1vdmUobnVtYmVyKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlIHRoZSBmaWVsZHMgZnJvbSB7QGNvZGUgb3RoZXJ9IGludG8gdGhpcyBzZXQuICBJZiBhIGZpZWxkIG51bWJlcgorICAgICAqIGV4aXN0cyBpbiBib3RoIHNldHMsIHtAY29kZSBvdGhlcn0ncyB2YWx1ZXMgZm9yIHRoYXQgZmllbGQgd2lsbCBiZQorICAgICAqIGFwcGVuZGVkIHRvIHRoZSB2YWx1ZXMgaW4gdGhpcyBzZXQuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGZpbmFsIFVua25vd25GaWVsZFNldCBvdGhlcikgeworICAgICAgaWYgKG90aGVyICE9IGdldERlZmF1bHRJbnN0YW5jZSgpKSB7CisgICAgICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PEludGVnZXIsIEZpZWxkPiBlbnRyeSA6IG90aGVyLmZpZWxkcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgbWVyZ2VGaWVsZChlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIGZpZWxkIHRvIHRoZSB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fS4gIElmIGEgZmllbGQgd2l0aCB0aGUgc2FtZQorICAgICAqIG51bWJlciBhbHJlYWR5IGV4aXN0cywgdGhlIHR3byBhcmUgbWVyZ2VkLgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGQoZmluYWwgaW50IG51bWJlciwgZmluYWwgRmllbGQgZmllbGQpIHsKKyAgICAgIGlmIChudW1iZXIgPT0gMCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJaZXJvIGlzIG5vdCBhIHZhbGlkIGZpZWxkIG51bWJlci4iKTsKKyAgICAgIH0KKyAgICAgIGlmIChoYXNGaWVsZChudW1iZXIpKSB7CisgICAgICAgIGdldEZpZWxkQnVpbGRlcihudW1iZXIpLm1lcmdlRnJvbShmaWVsZCk7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBPcHRpbWl6YXRpb246ICBXZSBjb3VsZCBjYWxsIGdldEZpZWxkQnVpbGRlcihudW1iZXIpLm1lcmdlRnJvbShmaWVsZCkKKyAgICAgICAgLy8gaW4gdGhpcyBjYXNlLCBidXQgdGhhdCB3b3VsZCBjcmVhdGUgYSBjb3B5IG9mIHRoZSBGaWVsZCBvYmplY3QuCisgICAgICAgIC8vIFdlJ2QgcmF0aGVyIHJldXNlIHRoZSBvbmUgcGFzc2VkIHRvIHVzLCBzbyBjYWxsIGFkZEZpZWxkKCkgaW5zdGVhZC4KKyAgICAgICAgYWRkRmllbGQobnVtYmVyLCBmaWVsZCk7CisgICAgICB9CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIG1lcmdpbmcgYSBuZXcgZmllbGQgY29udGFpbmluZyBhIHNpbmdsZSB2YXJpbnQKKyAgICAgKiB2YWx1ZS4gIFRoaXMgaXMgdXNlZCBpbiBwYXJ0aWN1bGFyIHdoZW4gYW4gdW5rbm93biBlbnVtIHZhbHVlIGlzCisgICAgICogZW5jb3VudGVyZWQuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VWYXJpbnRGaWVsZChmaW5hbCBpbnQgbnVtYmVyLCBmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICAgIGlmIChudW1iZXIgPT0gMCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJaZXJvIGlzIG5vdCBhIHZhbGlkIGZpZWxkIG51bWJlci4iKTsKKyAgICAgIH0KKyAgICAgIGdldEZpZWxkQnVpbGRlcihudW1iZXIpLmFkZFZhcmludCh2YWx1ZSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgbWVyZ2luZyBhIGxlbmd0aC1kZWxpbWl0ZWQgZmllbGQuCisgICAgICoKKyAgICAgKiA8cD5Gb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VMZW5ndGhEZWxpbWl0ZWRGaWVsZCgKKyAgICAgICAgZmluYWwgaW50IG51bWJlciwgZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSkgeyAgCisgICAgICBpZiAobnVtYmVyID09IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiWmVybyBpcyBub3QgYSB2YWxpZCBmaWVsZCBudW1iZXIuIik7CisgICAgICB9CisgICAgICBnZXRGaWVsZEJ1aWxkZXIobnVtYmVyKS5hZGRMZW5ndGhEZWxpbWl0ZWQodmFsdWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIENoZWNrIGlmIHRoZSBnaXZlbiBmaWVsZCBudW1iZXIgaXMgcHJlc2VudCBpbiB0aGUgc2V0LiAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkKGZpbmFsIGludCBudW1iZXIpIHsKKyAgICAgIGlmIChudW1iZXIgPT0gMCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJaZXJvIGlzIG5vdCBhIHZhbGlkIGZpZWxkIG51bWJlci4iKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBudW1iZXIgPT0gbGFzdEZpZWxkTnVtYmVyIHx8IGZpZWxkcy5jb250YWluc0tleShudW1iZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIGZpZWxkIHRvIHRoZSB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fS4gIElmIGEgZmllbGQgd2l0aCB0aGUgc2FtZQorICAgICAqIG51bWJlciBhbHJlYWR5IGV4aXN0cywgaXQgaXMgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZChmaW5hbCBpbnQgbnVtYmVyLCBmaW5hbCBGaWVsZCBmaWVsZCkgeworICAgICAgaWYgKG51bWJlciA9PSAwKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlplcm8gaXMgbm90IGEgdmFsaWQgZmllbGQgbnVtYmVyLiIpOworICAgICAgfQorICAgICAgaWYgKGxhc3RGaWVsZCAhPSBudWxsICYmIGxhc3RGaWVsZE51bWJlciA9PSBudW1iZXIpIHsKKyAgICAgICAgLy8gRGlzY2FyZCB0aGlzLgorICAgICAgICBsYXN0RmllbGQgPSBudWxsOworICAgICAgICBsYXN0RmllbGROdW1iZXIgPSAwOworICAgICAgfQorICAgICAgaWYgKGZpZWxkcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgZmllbGRzID0gbmV3IFRyZWVNYXA8SW50ZWdlcixGaWVsZD4oKTsKKyAgICAgIH0KKyAgICAgIGZpZWxkcy5wdXQobnVtYmVyLCBmaWVsZCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHByZXNlbnQge0Bjb2RlIEZpZWxkfXMgYXMgYW4gaW1tdXRhYmxlIHtAY29kZSBNYXB9LiAgSWYgbW9yZQorICAgICAqIGZpZWxkcyBhcmUgYWRkZWQsIHRoZSBjaGFuZ2VzIG1heSBvciBtYXkgbm90IGJlIHJlZmxlY3RlZCBpbiB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPEludGVnZXIsIEZpZWxkPiBhc01hcCgpIHsKKyAgICAgIGdldEZpZWxkQnVpbGRlcigwKTsgIC8vIEZvcmNlIGxhc3RGaWVsZCB0byBiZSBidWlsdC4KKyAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoZmllbGRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhbiBlbnRpcmUgbWVzc2FnZSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIGl0cyBmaWVsZHMgaW50bworICAgICAqIHRoaXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShmaW5hbCBDb2RlZElucHV0U3RyZWFtIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgZmluYWwgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8ICFtZXJnZUZpZWxkRnJvbSh0YWcsIGlucHV0KSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHNpbmdsZSBmaWVsZCBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIGl0IGludG8gdGhpcyBzZXQuCisgICAgICogQHBhcmFtIHRhZyBUaGUgZmllbGQncyB0YWcgbnVtYmVyLCB3aGljaCB3YXMgYWxyZWFkeSBwYXJzZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgZmFsc2V9IGlmIHRoZSB0YWcgaXMgYW4gZW5kIGdyb3VwIHRhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtZXJnZUZpZWxkRnJvbShmaW5hbCBpbnQgdGFnLCBmaW5hbCBDb2RlZElucHV0U3RyZWFtIGlucHV0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBpbnQgbnVtYmVyID0gV2lyZUZvcm1hdC5nZXRUYWdGaWVsZE51bWJlcih0YWcpOworICAgICAgc3dpdGNoIChXaXJlRm9ybWF0LmdldFRhZ1dpcmVUeXBlKHRhZykpIHsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX1ZBUklOVDoKKyAgICAgICAgICBnZXRGaWVsZEJ1aWxkZXIobnVtYmVyKS5hZGRWYXJpbnQoaW5wdXQucmVhZEludDY0KCkpOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfRklYRUQ2NDoKKyAgICAgICAgICBnZXRGaWVsZEJ1aWxkZXIobnVtYmVyKS5hZGRGaXhlZDY0KGlucHV0LnJlYWRGaXhlZDY0KCkpOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgICAgICBnZXRGaWVsZEJ1aWxkZXIobnVtYmVyKS5hZGRMZW5ndGhEZWxpbWl0ZWQoaW5wdXQucmVhZEJ5dGVzKCkpOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfU1RBUlRfR1JPVVA6CisgICAgICAgICAgZmluYWwgQnVpbGRlciBzdWJCdWlsZGVyID0gbmV3QnVpbGRlcigpOworICAgICAgICAgIGlucHV0LnJlYWRHcm91cChudW1iZXIsIHN1YkJ1aWxkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5LmdldEVtcHR5UmVnaXN0cnkoKSk7CisgICAgICAgICAgZ2V0RmllbGRCdWlsZGVyKG51bWJlcikuYWRkR3JvdXAoc3ViQnVpbGRlci5idWlsZCgpKTsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0VORF9HUk9VUDoKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9GSVhFRDMyOgorICAgICAgICAgIGdldEZpZWxkQnVpbGRlcihudW1iZXIpLmFkZEZpeGVkMzIoaW5wdXQucmVhZEZpeGVkMzIoKSk7CisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmludmFsaWRXaXJlVHlwZSgpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHtAY29kZSBkYXRhfSBhcyBhbiB7QGNvZGUgVW5rbm93bkZpZWxkU2V0fSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBzZXQgYmVpbmcgYnVpbHQuICBUaGlzIGlzIGp1c3QgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZAorICAgICAqIHtAbGluayAjbWVyZ2VGcm9tKENvZGVkSW5wdXRTdHJlYW0pfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oZmluYWwgQnl0ZVN0cmluZyBkYXRhKQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPSBkYXRhLm5ld0NvZGVkSW5wdXQoKTsKKyAgICAgICAgbWVyZ2VGcm9tKGlucHV0KTsKKyAgICAgICAgaW5wdXQuY2hlY2tMYXN0VGFnV2FzKDApOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0gY2F0Y2ggKGZpbmFsIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGU7CisgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJSZWFkaW5nIGZyb20gYSBCeXRlU3RyaW5nIHRocmV3IGFuIElPRXhjZXB0aW9uIChzaG91bGQgIiArCisgICAgICAgICAgIm5ldmVyIGhhcHBlbikuIiwgZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2Uge0Bjb2RlIGRhdGF9IGFzIGFuIHtAY29kZSBVbmtub3duRmllbGRTZXR9IGFuZCBtZXJnZSBpdCB3aXRoIHRoZQorICAgICAqIHNldCBiZWluZyBidWlsdC4gIFRoaXMgaXMganVzdCBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kCisgICAgICoge0BsaW5rICNtZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbSl9LgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShmaW5hbCBieXRlW10gZGF0YSkKKyAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBmaW5hbCBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKTsKKyAgICAgICAgbWVyZ2VGcm9tKGlucHV0KTsKKyAgICAgICAgaW5wdXQuY2hlY2tMYXN0VGFnV2FzKDApOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0gY2F0Y2ggKGZpbmFsIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGU7CisgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJSZWFkaW5nIGZyb20gYSBieXRlIGFycmF5IHRocmV3IGFuIElPRXhjZXB0aW9uIChzaG91bGQgIiArCisgICAgICAgICAgIm5ldmVyIGhhcHBlbikuIiwgZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYW4ge0Bjb2RlIFVua25vd25GaWVsZFNldH0gZnJvbSB7QGNvZGUgaW5wdXR9IGFuZCBtZXJnZSBpdCB3aXRoIHRoZQorICAgICAqIHNldCBiZWluZyBidWlsdC4gIFRoaXMgaXMganVzdCBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kCisgICAgICoge0BsaW5rICNtZXJnZUZyb20oQ29kZWRJbnB1dFN0cmVhbSl9LgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gY29kZWRJbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoaW5wdXQpOworICAgICAgbWVyZ2VGcm9tKGNvZGVkSW5wdXQpOworICAgICAgY29kZWRJbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBtZXJnZURlbGltaXRlZEZyb20oSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBpbnQgZmlyc3RCeXRlID0gaW5wdXQucmVhZCgpOworICAgICAgaWYgKGZpcnN0Qnl0ZSA9PSAtMSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBmaW5hbCBpbnQgc2l6ZSA9IENvZGVkSW5wdXRTdHJlYW0ucmVhZFJhd1ZhcmludDMyKGZpcnN0Qnl0ZSwgaW5wdXQpOworICAgICAgZmluYWwgSW5wdXRTdHJlYW0gbGltaXRlZElucHV0ID0gbmV3IExpbWl0ZWRJbnB1dFN0cmVhbShpbnB1dCwgc2l6ZSk7CisgICAgICBtZXJnZUZyb20obGltaXRlZElucHV0KTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIG1lcmdlRGVsaW1pdGVkRnJvbSgKKyAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXQsCisgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIFVua25vd25GaWVsZFNldCBoYXMgbm8gZXh0ZW5zaW9ucy4KKyAgICAgIHJldHVybiBtZXJnZURlbGltaXRlZEZyb20oaW5wdXQpOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gVW5rbm93bkZpZWxkU2V0IGhhcyBubyBleHRlbnNpb25zLgorICAgICAgcmV0dXJuIG1lcmdlRnJvbShpbnB1dCk7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAorICAgICAgICBCeXRlU3RyaW5nIGRhdGEsCisgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAvLyBVbmtub3duRmllbGRTZXQgaGFzIG5vIGV4dGVuc2lvbnMuCisgICAgICByZXR1cm4gbWVyZ2VGcm9tKGRhdGEpOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgICAgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBmaW5hbCBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0KKyAgICAgICAgICAgIENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZGF0YSwgb2ZmLCBsZW4pOworICAgICAgICBtZXJnZUZyb20oaW5wdXQpOworICAgICAgICBpbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgZTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgIlJlYWRpbmcgZnJvbSBhIGJ5dGUgYXJyYXkgdGhyZXcgYW4gSU9FeGNlcHRpb24gKHNob3VsZCAiICsKKyAgICAgICAgICAibmV2ZXIgaGFwcGVuKS4iLCBlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCisgICAgICAgIGJ5dGVbXSBkYXRhLAorICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgLy8gVW5rbm93bkZpZWxkU2V0IGhhcyBubyBleHRlbnNpb25zLgorICAgICAgcmV0dXJuIG1lcmdlRnJvbShkYXRhKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCisgICAgICAgIGJ5dGVbXSBkYXRhLCBpbnQgb2ZmLCBpbnQgbGVuLAorICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgLy8gVW5rbm93bkZpZWxkU2V0IGhhcyBubyBleHRlbnNpb25zLgorICAgICAgcmV0dXJuIG1lcmdlRnJvbShkYXRhLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAorICAgICAgICBJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gVW5rbm93bkZpZWxkU2V0IGhhcyBubyBleHRlbnNpb25zLgorICAgICAgcmV0dXJuIG1lcmdlRnJvbShpbnB1dCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKKyAgICAgIC8vIFVua25vd25GaWVsZFNldHMgZG8gbm90IGhhdmUgcmVxdWlyZWQgZmllbGRzLCBzbyB0aGV5IGFyZSBhbHdheXMKKyAgICAgIC8vIGluaXRpYWxpemVkLgorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlcHJlc2VudHMgYSBzaW5nbGUgZmllbGQgaW4gYW4ge0Bjb2RlIFVua25vd25GaWVsZFNldH0uCisgICAqCisgICAqIDxwPkEge0Bjb2RlIEZpZWxkfSBjb25zaXN0cyBvZiBmaXZlIGxpc3RzIG9mIHZhbHVlcy4gIFRoZSBsaXN0cyBjb3JyZXNwb25kCisgICAqIHRvIHRoZSBmaXZlICJ3aXJlIHR5cGVzIiB1c2VkIGluIHRoZSBwcm90b2NvbCBidWZmZXIgYmluYXJ5IGZvcm1hdC4KKyAgICogVGhlIHdpcmUgdHlwZSBvZiBlYWNoIGZpZWxkIGNhbiBiZSBkZXRlcm1pbmVkIGZyb20gdGhlIGVuY29kZWQgZm9ybSBhbG9uZSwKKyAgICogd2l0aG91dCBrbm93aW5nIHRoZSBmaWVsZCdzIGRlY2xhcmVkIHR5cGUuICBTbywgd2UgYXJlIGFibGUgdG8gcGFyc2UKKyAgICogdW5rbm93biB2YWx1ZXMgYXQgbGVhc3QgdGhpcyBmYXIgYW5kIHNlcGFyYXRlIHRoZW0uICBOb3JtYWxseSwgb25seSBvbmUKKyAgICogb2YgdGhlIGZpdmUgbGlzdHMgd2lsbCBjb250YWluIGFueSB2YWx1ZXMsIHNpbmNlIGl0IGlzIGltcG9zc2libGUgdG8KKyAgICogZGVmaW5lIGEgdmFsaWQgbWVzc2FnZSB0eXBlIHRoYXQgZGVjbGFyZXMgdHdvIGRpZmZlcmVudCB0eXBlcyBmb3IgdGhlCisgICAqIHNhbWUgZmllbGQgbnVtYmVyLiAgSG93ZXZlciwgdGhlIGNvZGUgaXMgZGVzaWduZWQgdG8gYWxsb3cgZm9yIHRoZSBjYXNlCisgICAqIHdoZXJlIHRoZSBzYW1lIHVua25vd24gZmllbGQgbnVtYmVyIGlzIGVuY291bnRlcmVkIHVzaW5nIG11bHRpcGxlIGRpZmZlcmVudAorICAgKiB3aXJlIHR5cGVzLgorICAgKgorICAgKiA8cD57QGNvZGUgRmllbGR9IGlzIGFuIGltbXV0YWJsZSBjbGFzcy4gIFRvIGNvbnN0cnVjdCBvbmUsIHlvdSBtdXN0IHVzZSBhCisgICAqIHtAbGluayBCdWlsZGVyfS4KKyAgICoKKyAgICogQHNlZSBVbmtub3duRmllbGRTZXQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGQgeworICAgIHByaXZhdGUgRmllbGQoKSB7fQorCisgICAgLyoqIENvbnN0cnVjdCBhIG5ldyB7QGxpbmsgQnVpbGRlcn0uICovCisgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgICByZXR1cm4gQnVpbGRlci5jcmVhdGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0BsaW5rIEJ1aWxkZXJ9IGFuZCBpbml0aWFsaXplIGl0IHRvIGEgY29weSBvZgorICAgICAqIHtAY29kZSBjb3B5RnJvbX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoZmluYWwgRmllbGQgY29weUZyb20pIHsKKyAgICAgIHJldHVybiBuZXdCdWlsZGVyKCkubWVyZ2VGcm9tKGNvcHlGcm9tKTsKKyAgICB9CisKKyAgICAvKiogR2V0IGFuIGVtcHR5IHtAY29kZSBGaWVsZH0uICovCisgICAgcHVibGljIHN0YXRpYyBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgICByZXR1cm4gZmllbGREZWZhdWx0SW5zdGFuY2U7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkIGZpZWxkRGVmYXVsdEluc3RhbmNlID0gbmV3QnVpbGRlcigpLmJ1aWxkKCk7CisKKyAgICAvKiogR2V0IHRoZSBsaXN0IG9mIHZhcmludCB2YWx1ZXMgZm9yIHRoaXMgZmllbGQuICovCisgICAgcHVibGljIExpc3Q8TG9uZz4gZ2V0VmFyaW50TGlzdCgpICAgICAgICAgICAgICAgeyByZXR1cm4gdmFyaW50OyAgICAgICAgICB9CisKKyAgICAvKiogR2V0IHRoZSBsaXN0IG9mIGZpeGVkMzIgdmFsdWVzIGZvciB0aGlzIGZpZWxkLiAqLworICAgIHB1YmxpYyBMaXN0PEludGVnZXI+IGdldEZpeGVkMzJMaXN0KCkgICAgICAgICAgIHsgcmV0dXJuIGZpeGVkMzI7ICAgICAgICAgfQorCisgICAgLyoqIEdldCB0aGUgbGlzdCBvZiBmaXhlZDY0IHZhbHVlcyBmb3IgdGhpcyBmaWVsZC4gKi8KKyAgICBwdWJsaWMgTGlzdDxMb25nPiBnZXRGaXhlZDY0TGlzdCgpICAgICAgICAgICAgICB7IHJldHVybiBmaXhlZDY0OyAgICAgICAgIH0KKworICAgIC8qKiBHZXQgdGhlIGxpc3Qgb2YgbGVuZ3RoLWRlbGltaXRlZCB2YWx1ZXMgZm9yIHRoaXMgZmllbGQuICovCisgICAgcHVibGljIExpc3Q8Qnl0ZVN0cmluZz4gZ2V0TGVuZ3RoRGVsaW1pdGVkTGlzdCgpIHsgcmV0dXJuIGxlbmd0aERlbGltaXRlZDsgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsaXN0IG9mIGVtYmVkZGVkIGdyb3VwIHZhbHVlcyBmb3IgdGhpcyBmaWVsZC4gIFRoZXNlIGFyZQorICAgICAqIHJlcHJlc2VudGVkIHVzaW5nIHtAbGluayBVbmtub3duRmllbGRTZXR9cyByYXRoZXIgdGhhbiB7QGxpbmsgTWVzc2FnZX1zCisgICAgICogc2luY2UgdGhlIGdyb3VwJ3MgdHlwZSBpcyBwcmVzdW1hYmx5IHVua25vd24uCisgICAgICovCisgICAgcHVibGljIExpc3Q8VW5rbm93bkZpZWxkU2V0PiBnZXRHcm91cExpc3QoKSAgICAgIHsgcmV0dXJuIGdyb3VwOyAgICAgICAgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvdGhlcikgeworICAgICAgaWYgKHRoaXMgPT0gb3RoZXIpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIEZpZWxkKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhnZXRJZGVudGl0eUFycmF5KCksCisgICAgICAgICAgKChGaWVsZCkgb3RoZXIpLmdldElkZW50aXR5QXJyYXkoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiBBcnJheXMuaGFzaENvZGUoZ2V0SWRlbnRpdHlBcnJheSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBvYmplY3RzIHRvIGJlIHVzZWQgdG8gdW5pcXVlbHkgaWRlbnRpZnkgdGhpcworICAgICAqIHtAbGluayBGaWVsZH0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3RbXSBnZXRJZGVudGl0eUFycmF5KCkgeworICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXSB7CisgICAgICAgICAgdmFyaW50LAorICAgICAgICAgIGZpeGVkMzIsCisgICAgICAgICAgZml4ZWQ2NCwKKyAgICAgICAgICBsZW5ndGhEZWxpbWl0ZWQsCisgICAgICAgICAgZ3JvdXB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlcmlhbGl6ZXMgdGhlIGZpZWxkLCBpbmNsdWRpbmcgZmllbGQgbnVtYmVyLCBhbmQgd3JpdGVzIGl0IHRvCisgICAgICoge0Bjb2RlIG91dHB1dH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmb3IgKGZpbmFsIGxvbmcgdmFsdWUgOiB2YXJpbnQpIHsKKyAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KGZpZWxkTnVtYmVyLCB2YWx1ZSk7CisgICAgICB9CisgICAgICBmb3IgKGZpbmFsIGludCB2YWx1ZSA6IGZpeGVkMzIpIHsKKyAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMihmaWVsZE51bWJlciwgdmFsdWUpOworICAgICAgfQorICAgICAgZm9yIChmaW5hbCBsb25nIHZhbHVlIDogZml4ZWQ2NCkgeworICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KGZpZWxkTnVtYmVyLCB2YWx1ZSk7CisgICAgICB9CisgICAgICBmb3IgKGZpbmFsIEJ5dGVTdHJpbmcgdmFsdWUgOiBsZW5ndGhEZWxpbWl0ZWQpIHsKKyAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoZmllbGROdW1iZXIsIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGZvciAoZmluYWwgVW5rbm93bkZpZWxkU2V0IHZhbHVlIDogZ3JvdXApIHsKKyAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoZmllbGROdW1iZXIsIHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBlbmNvZGUgdGhpcyBmaWVsZCwgaW5jbHVkaW5nIGZpZWxkCisgICAgICogbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyKSB7CisgICAgICBpbnQgcmVzdWx0ID0gMDsKKyAgICAgIGZvciAoZmluYWwgbG9uZyB2YWx1ZSA6IHZhcmludCkgeworICAgICAgICByZXN1bHQgKz0gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZVVJbnQ2NFNpemUoZmllbGROdW1iZXIsIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGZvciAoZmluYWwgaW50IHZhbHVlIDogZml4ZWQzMikgeworICAgICAgICByZXN1bHQgKz0gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZUZpeGVkMzJTaXplKGZpZWxkTnVtYmVyLCB2YWx1ZSk7CisgICAgICB9CisgICAgICBmb3IgKGZpbmFsIGxvbmcgdmFsdWUgOiBmaXhlZDY0KSB7CisgICAgICAgIHJlc3VsdCArPSBDb2RlZE91dHB1dFN0cmVhbS5jb21wdXRlRml4ZWQ2NFNpemUoZmllbGROdW1iZXIsIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGZvciAoZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSA6IGxlbmd0aERlbGltaXRlZCkgeworICAgICAgICByZXN1bHQgKz0gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZUJ5dGVzU2l6ZShmaWVsZE51bWJlciwgdmFsdWUpOworICAgICAgfQorICAgICAgZm9yIChmaW5hbCBVbmtub3duRmllbGRTZXQgdmFsdWUgOiBncm91cCkgeworICAgICAgICByZXN1bHQgKz0gQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZUdyb3VwU2l6ZShmaWVsZE51bWJlciwgdmFsdWUpOworICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemVzIHRoZSBmaWVsZCwgaW5jbHVkaW5nIGZpZWxkIG51bWJlciwgYW5kIHdyaXRlcyBpdCB0bworICAgICAqIHtAY29kZSBvdXRwdXR9LCB1c2luZyB7QGNvZGUgTWVzc2FnZVNldH0gd2lyZSBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVBc01lc3NhZ2VTZXRFeHRlbnNpb25UbygKKyAgICAgICAgZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICBmaW5hbCBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmb3IgKGZpbmFsIEJ5dGVTdHJpbmcgdmFsdWUgOiBsZW5ndGhEZWxpbWl0ZWQpIHsKKyAgICAgICAgb3V0cHV0LndyaXRlUmF3TWVzc2FnZVNldEV4dGVuc2lvbihmaWVsZE51bWJlciwgdmFsdWUpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIGVuY29kZSB0aGlzIGZpZWxkLCBpbmNsdWRpbmcgZmllbGQKKyAgICAgKiBudW1iZXIsIHVzaW5nIHtAY29kZSBNZXNzYWdlU2V0fSB3aXJlIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplQXNNZXNzYWdlU2V0RXh0ZW5zaW9uKGZpbmFsIGludCBmaWVsZE51bWJlcikgeworICAgICAgaW50IHJlc3VsdCA9IDA7CisgICAgICBmb3IgKGZpbmFsIEJ5dGVTdHJpbmcgdmFsdWUgOiBsZW5ndGhEZWxpbWl0ZWQpIHsKKyAgICAgICAgcmVzdWx0ICs9IENvZGVkT3V0cHV0U3RyZWFtLmNvbXB1dGVSYXdNZXNzYWdlU2V0RXh0ZW5zaW9uU2l6ZSgKKyAgICAgICAgICBmaWVsZE51bWJlciwgdmFsdWUpOworICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIExpc3Q8TG9uZz4gdmFyaW50OworICAgIHByaXZhdGUgTGlzdDxJbnRlZ2VyPiBmaXhlZDMyOworICAgIHByaXZhdGUgTGlzdDxMb25nPiBmaXhlZDY0OworICAgIHByaXZhdGUgTGlzdDxCeXRlU3RyaW5nPiBsZW5ndGhEZWxpbWl0ZWQ7CisgICAgcHJpdmF0ZSBMaXN0PFVua25vd25GaWVsZFNldD4gZ3JvdXA7CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIGJ1aWxkIGEge0BsaW5rIEZpZWxkfSB3aXRoaW4gYW4ge0BsaW5rIFVua25vd25GaWVsZFNldH0uCisgICAgICoKKyAgICAgKiA8cD5Vc2Uge0BsaW5rIEZpZWxkI25ld0J1aWxkZXIoKX0gdG8gY29uc3RydWN0IGEge0Bjb2RlIEJ1aWxkZXJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciB7CisgICAgICAvLyBUaGlzIGNvbnN0cnVjdG9yIHNob3VsZCBuZXZlciBiZSBjYWxsZWQgZGlyZWN0bHkgKGV4Y2VwdCBmcm9tICdjcmVhdGUnKS4KKyAgICAgIHByaXZhdGUgQnVpbGRlcigpIHt9CisKKyAgICAgIHByaXZhdGUgc3RhdGljIEJ1aWxkZXIgY3JlYXRlKCkgeworICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcigpOworICAgICAgICBidWlsZGVyLnJlc3VsdCA9IG5ldyBGaWVsZCgpOworICAgICAgICByZXR1cm4gYnVpbGRlcjsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBGaWVsZCByZXN1bHQ7CisKKyAgICAgIC8qKgorICAgICAgICogQnVpbGQgdGhlIGZpZWxkLiAgQWZ0ZXIge0Bjb2RlIGJ1aWxkKCl9IGhhcyBiZWVuIGNhbGxlZCwgdGhlCisgICAgICAgKiB7QGNvZGUgQnVpbGRlcn0gaXMgbm8gbG9uZ2VyIHVzYWJsZS4gIENhbGxpbmcgYW55IG90aGVyIG1ldGhvZCB3aWxsCisgICAgICAgKiByZXN1bHQgaW4gdW5kZWZpbmVkIGJlaGF2aW9yIGFuZCBjYW4gY2F1c2UgYQorICAgICAgICoge0Bjb2RlIE51bGxQb2ludGVyRXhjZXB0aW9ufSB0byBiZSB0aHJvd24uCisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBGaWVsZCBidWlsZCgpIHsKKyAgICAgICAgaWYgKHJlc3VsdC52YXJpbnQgPT0gbnVsbCkgeworICAgICAgICAgIHJlc3VsdC52YXJpbnQgPSBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQudmFyaW50ID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXN1bHQudmFyaW50KTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVzdWx0LmZpeGVkMzIgPT0gbnVsbCkgeworICAgICAgICAgIHJlc3VsdC5maXhlZDMyID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVzdWx0LmZpeGVkMzIgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlc3VsdC5maXhlZDMyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVzdWx0LmZpeGVkNjQgPT0gbnVsbCkgeworICAgICAgICAgIHJlc3VsdC5maXhlZDY0ID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVzdWx0LmZpeGVkNjQgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlc3VsdC5maXhlZDY0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aERlbGltaXRlZCA9PSBudWxsKSB7CisgICAgICAgICAgcmVzdWx0Lmxlbmd0aERlbGltaXRlZCA9IENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdC5sZW5ndGhEZWxpbWl0ZWQgPQorICAgICAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXN1bHQubGVuZ3RoRGVsaW1pdGVkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVzdWx0Lmdyb3VwID09IG51bGwpIHsKKyAgICAgICAgICByZXN1bHQuZ3JvdXAgPSBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQuZ3JvdXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlc3VsdC5ncm91cCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBGaWVsZCByZXR1cm5NZSA9IHJlc3VsdDsKKyAgICAgICAgcmVzdWx0ID0gbnVsbDsKKyAgICAgICAgcmV0dXJuIHJldHVybk1lOworICAgICAgfQorCisgICAgICAvKiogRGlzY2FyZCB0aGUgZmllbGQncyBjb250ZW50cy4gKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgeworICAgICAgICByZXN1bHQgPSBuZXcgRmllbGQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIC8qKgorICAgICAgICogTWVyZ2UgdGhlIHZhbHVlcyBpbiB7QGNvZGUgb3RoZXJ9IGludG8gdGhpcyBmaWVsZC4gIEZvciBlYWNoIGxpc3QKKyAgICAgICAqIG9mIHZhbHVlcywge0Bjb2RlIG90aGVyfSdzIHZhbHVlcyBhcmUgYXBwZW5kIHRvIHRoZSBvbmVzIGluIHRoaXMKKyAgICAgICAqIGZpZWxkLgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oZmluYWwgRmllbGQgb3RoZXIpIHsKKyAgICAgICAgaWYgKCFvdGhlci52YXJpbnQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgaWYgKHJlc3VsdC52YXJpbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LnZhcmludCA9IG5ldyBBcnJheUxpc3Q8TG9uZz4oKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmVzdWx0LnZhcmludC5hZGRBbGwob3RoZXIudmFyaW50KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIW90aGVyLmZpeGVkMzIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgaWYgKHJlc3VsdC5maXhlZDMyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5maXhlZDMyID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXN1bHQuZml4ZWQzMi5hZGRBbGwob3RoZXIuZml4ZWQzMik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFvdGhlci5maXhlZDY0LmlzRW1wdHkoKSkgeworICAgICAgICAgIGlmIChyZXN1bHQuZml4ZWQ2NCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuZml4ZWQ2NCA9IG5ldyBBcnJheUxpc3Q8TG9uZz4oKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmVzdWx0LmZpeGVkNjQuYWRkQWxsKG90aGVyLmZpeGVkNjQpOworICAgICAgICB9CisgICAgICAgIGlmICghb3RoZXIubGVuZ3RoRGVsaW1pdGVkLmlzRW1wdHkoKSkgeworICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoRGVsaW1pdGVkID09IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5sZW5ndGhEZWxpbWl0ZWQgPSBuZXcgQXJyYXlMaXN0PEJ5dGVTdHJpbmc+KCk7CisgICAgICAgICAgfQorICAgICAgICAgIHJlc3VsdC5sZW5ndGhEZWxpbWl0ZWQuYWRkQWxsKG90aGVyLmxlbmd0aERlbGltaXRlZCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFvdGhlci5ncm91cC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICBpZiAocmVzdWx0Lmdyb3VwID09IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5ncm91cCA9IG5ldyBBcnJheUxpc3Q8VW5rbm93bkZpZWxkU2V0PigpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXN1bHQuZ3JvdXAuYWRkQWxsKG90aGVyLmdyb3VwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgLyoqIEFkZCBhIHZhcmludCB2YWx1ZS4gKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFZhcmludChmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgICAgIGlmIChyZXN1bHQudmFyaW50ID09IG51bGwpIHsKKyAgICAgICAgICByZXN1bHQudmFyaW50ID0gbmV3IEFycmF5TGlzdDxMb25nPigpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC52YXJpbnQuYWRkKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIC8qKiBBZGQgYSBmaXhlZDMyIHZhbHVlLiAqLworICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRml4ZWQzMihmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICAgICAgaWYgKHJlc3VsdC5maXhlZDMyID09IG51bGwpIHsKKyAgICAgICAgICByZXN1bHQuZml4ZWQzMiA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuZml4ZWQzMi5hZGQodmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgLyoqIEFkZCBhIGZpeGVkNjQgdmFsdWUuICovCisgICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaXhlZDY0KGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKHJlc3VsdC5maXhlZDY0ID09IG51bGwpIHsKKyAgICAgICAgICByZXN1bHQuZml4ZWQ2NCA9IG5ldyBBcnJheUxpc3Q8TG9uZz4oKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuZml4ZWQ2NC5hZGQodmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgLyoqIEFkZCBhIGxlbmd0aC1kZWxpbWl0ZWQgdmFsdWUuICovCisgICAgICBwdWJsaWMgQnVpbGRlciBhZGRMZW5ndGhEZWxpbWl0ZWQoZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSkgeworICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aERlbGltaXRlZCA9PSBudWxsKSB7CisgICAgICAgICAgcmVzdWx0Lmxlbmd0aERlbGltaXRlZCA9IG5ldyBBcnJheUxpc3Q8Qnl0ZVN0cmluZz4oKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQubGVuZ3RoRGVsaW1pdGVkLmFkZCh2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorCisgICAgICAvKiogQWRkIGFuIGVtYmVkZGVkIGdyb3VwLiAqLworICAgICAgcHVibGljIEJ1aWxkZXIgYWRkR3JvdXAoZmluYWwgVW5rbm93bkZpZWxkU2V0IHZhbHVlKSB7CisgICAgICAgIGlmIChyZXN1bHQuZ3JvdXAgPT0gbnVsbCkgeworICAgICAgICAgIHJlc3VsdC5ncm91cCA9IG5ldyBBcnJheUxpc3Q8VW5rbm93bkZpZWxkU2V0PigpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC5ncm91cC5hZGQodmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogUGFyc2VyIHRvIGltcGxlbWVudCBNZXNzYWdlTGl0ZSBpbnRlcmZhY2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFBhcnNlciBleHRlbmRzIEFic3RyYWN0UGFyc2VyPFVua25vd25GaWVsZFNldD4geworICAgIHB1YmxpYyBVbmtub3duRmllbGRTZXQgcGFyc2VQYXJ0aWFsRnJvbSgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0KTsKKyAgICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpCisgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CisgICAgICB9CisgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXJzZXIgUEFSU0VSID0gbmV3IFBhcnNlcigpOworICBwdWJsaWMgZmluYWwgUGFyc2VyIGdldFBhcnNlckZvclR5cGUoKSB7CisgICAgcmV0dXJuIFBBUlNFUjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0TGl0ZS5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0TGl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlYTg0MDIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXRMaXRlLmphdmEKQEAgLTAsMCArMSwyOTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIHtAY29kZSBVbmtub3duRmllbGRTZXRMaXRlfSBpcyB1c2VkIHRvIGtlZXAgdHJhY2sgb2YgZmllbGRzIHdoaWNoIHdlcmUgc2VlbgorICogd2hlbiBwYXJzaW5nIGEgcHJvdG9jb2wgbWVzc2FnZSBidXQgd2hvc2UgZmllbGQgbnVtYmVycyBvciB0eXBlcyBhcmUKKyAqIHVucmVjb2duaXplZC4gVGhpcyBtb3N0IGZyZXF1ZW50bHkgb2NjdXJzIHdoZW4gbmV3IGZpZWxkcyBhcmUgYWRkZWQgdG8gYQorICogbWVzc2FnZSB0eXBlIGFuZCB0aGVuIG1lc3NhZ2VzIGNvbnRhaW5pbmcgdGhvc2UgZmllbGRzIGFyZSByZWFkIGJ5IG9sZAorICogc29mdHdhcmUgdGhhdCB3YXMgY29tcGlsZWQgYmVmb3JlIHRoZSBuZXcgdHlwZXMgd2VyZSBhZGRlZC4KKyAqCisgKiA8cD5Gb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgKgorICogQGF1dGhvciBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFVua25vd25GaWVsZFNldExpdGUgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVua25vd25GaWVsZFNldExpdGUgREVGQVVMVF9JTlNUQU5DRSA9CisgICAgICBuZXcgVW5rbm93bkZpZWxkU2V0TGl0ZShCeXRlU3RyaW5nLkVNUFRZKTsKKworICAvKioKKyAgICogR2V0IGFuIGVtcHR5IHtAY29kZSBVbmtub3duRmllbGRTZXRMaXRlfS4KKyAgICoKKyAgICogPHA+Rm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBVbmtub3duRmllbGRTZXRMaXRlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKKyAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcge0BsaW5rIEJ1aWxkZXJ9LgorICAgKgorICAgKiA8cD5Gb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAqLworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIGFuIHtAY29kZSBVbmtub3duRmllbGRTZXRMaXRlfSB0aGF0IGlzIHRoZSBjb21wb3NpdGUgb2Yge0Bjb2RlIGZpcnN0fSBhbmQKKyAgICoge0Bjb2RlIHNlY29uZH0uCisgICAqLworICBzdGF0aWMgVW5rbm93bkZpZWxkU2V0TGl0ZSBjb25jYXQoVW5rbm93bkZpZWxkU2V0TGl0ZSBmaXJzdCwgVW5rbm93bkZpZWxkU2V0TGl0ZSBzZWNvbmQpIHsKKyAgICByZXR1cm4gbmV3IFVua25vd25GaWVsZFNldExpdGUoZmlyc3QuYnl0ZVN0cmluZy5jb25jYXQoc2Vjb25kLmJ5dGVTdHJpbmcpKTsKKyAgfQorCisgIC8qKgorICAgKiBUaGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHVua25vd24gZmllbGRzLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBCeXRlU3RyaW5nIGJ5dGVTdHJpbmc7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgdGhlIHtAY29kZSBVbmtub3duRmllbGRTZXRMaXRlfSBhcyBhIHRoaW4gd3JhcHBlciBhcm91bmQge0BsaW5rIEJ5dGVTdHJpbmd9LgorICAgKi8KKyAgcHJpdmF0ZSBVbmtub3duRmllbGRTZXRMaXRlKEJ5dGVTdHJpbmcgYnl0ZVN0cmluZykgeworICAgIHRoaXMuYnl0ZVN0cmluZyA9IGJ5dGVTdHJpbmc7CisgIH0KKworICAvKioKKyAgICogU2VyaWFsaXplcyB0aGUgc2V0IGFuZCB3cml0ZXMgaXQgdG8ge0Bjb2RlIG91dHB1dH0uCisgICAqCisgICAqIDxwPkZvciB1c2UgYnkgZ2VuZXJhdGVkIGNvZGUgb25seS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVG8oQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG91dHB1dC53cml0ZVJhd0J5dGVzKGJ5dGVTdHJpbmcpOworICB9CisKKworICAvKioKKyAgICogR2V0IHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gZW5jb2RlIHRoaXMgc2V0LgorICAgKgorICAgKiA8cD5Gb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAqLworICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgeworICAgIHJldHVybiBieXRlU3RyaW5nLnNpemUoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgIGlmICh0aGlzID09IG9iaikgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFVua25vd25GaWVsZFNldExpdGUpIHsKKyAgICAgIHJldHVybiBieXRlU3RyaW5nLmVxdWFscygoKFVua25vd25GaWVsZFNldExpdGUpIG9iaikuYnl0ZVN0cmluZyk7CisgICAgfQorCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIGJ5dGVTdHJpbmcuaGFzaENvZGUoKTsKKyAgfQorCisgIC8qKgorICAgKiBCdWlsZGVyIGZvciB7QGxpbmsgVW5rbm93bkZpZWxkU2V0TGl0ZX1zLgorICAgKgorICAgKiA8cD5Vc2Uge0BsaW5rIFVua25vd25GaWVsZFNldCNuZXdCdWlsZGVyKCl9IHRvIGNvbnN0cnVjdCBhIHtAY29kZSBCdWlsZGVyfS4KKyAgICoKKyAgICogPHA+Rm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIHsKKworICAgIHByaXZhdGUgQnl0ZVN0cmluZy5PdXRwdXQgYnl0ZVN0cmluZ091dHB1dDsKKyAgICBwcml2YXRlIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dDsKKyAgICBwcml2YXRlIGJvb2xlYW4gYnVpbHQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEJ1aWxkZXJ9LiBMYXppbHkgaW5pdGlhbGl6ZWQgYnkKKyAgICAgKiB7QGxpbmsgI2Vuc3VyZUluaXRpYWxpemVkQnV0Tm90QnVpbHQoKX0uCisgICAgICovCisgICAgcHJpdmF0ZSBCdWlsZGVyKCkge30KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgaW50ZXJuYWwgc3RhdGUgaXMgaW5pdGlhbGl6ZWQgZm9yIHVzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlSW5pdGlhbGl6ZWRCdXROb3RCdWlsdCgpIHsKKyAgICAgIGlmIChidWlsdCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJEbyBub3QgcmV1c2UgVW5rbm93bkZpZWxkU2V0TGl0ZSBCdWlsZGVycy4iKTsKKyAgICAgIH0KKworICAgICAgaWYgKG91dHB1dCA9PSBudWxsICYmIGJ5dGVTdHJpbmdPdXRwdXQgPT0gbnVsbCkgeworICAgICAgICAgIGJ5dGVTdHJpbmdPdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dCgxMDAgLyogaW5pdGlhbENhcGFjaXR5ICovKTsKKyAgICAgICAgICBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShieXRlU3RyaW5nT3V0cHV0KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHNpbmdsZSBmaWVsZCBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIGl0IGludG8gdGhpcyBzZXQuCisgICAgICoKKyAgICAgKiA8cD5Gb3IgdXNlIGJ5IGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFnIFRoZSBmaWVsZCdzIHRhZyBudW1iZXIsIHdoaWNoIHdhcyBhbHJlYWR5IHBhcnNlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSBmYWxzZX0gaWYgdGhlIHRhZyBpcyBhbiBlbmQgZ3JvdXAgdGFnLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1lcmdlRmllbGRGcm9tKGZpbmFsIGludCB0YWcsIGZpbmFsIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGVuc3VyZUluaXRpYWxpemVkQnV0Tm90QnVpbHQoKTsKKworICAgICAgZmluYWwgaW50IGZpZWxkTnVtYmVyID0gV2lyZUZvcm1hdC5nZXRUYWdGaWVsZE51bWJlcih0YWcpOworICAgICAgc3dpdGNoIChXaXJlRm9ybWF0LmdldFRhZ1dpcmVUeXBlKHRhZykpIHsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX1ZBUklOVDoKKyAgICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoZmllbGROdW1iZXIsIGlucHV0LnJlYWRJbnQ2NCgpKTsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0ZJWEVEMzI6CisgICAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMihmaWVsZE51bWJlciwgaW5wdXQucmVhZEZpeGVkMzIoKSk7CisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdC5XSVJFVFlQRV9GSVhFRDY0OgorICAgICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoZmllbGROdW1iZXIsIGlucHV0LnJlYWRGaXhlZDY0KCkpOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgICAgICBvdXRwdXQud3JpdGVCeXRlcyhmaWVsZE51bWJlciwgaW5wdXQucmVhZEJ5dGVzKCkpOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFdpcmVGb3JtYXQuV0lSRVRZUEVfU1RBUlRfR1JPVVA6CisgICAgICAgICAgZmluYWwgQnVpbGRlciBzdWJCdWlsZGVyID0gbmV3QnVpbGRlcigpOworICAgICAgICAgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0KTsKKyAgICAgICAgICBpbnB1dC5jaGVja0xhc3RUYWdXYXMoCisgICAgICAgICAgICAgIFdpcmVGb3JtYXQubWFrZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApKTsKKworICAgICAgICAgIG91dHB1dC53cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdC5XSVJFVFlQRV9TVEFSVF9HUk9VUCk7CisgICAgICAgICAgc3ViQnVpbGRlci5idWlsZCgpLndyaXRlVG8ob3V0cHV0KTsKKyAgICAgICAgICBvdXRwdXQud3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKTsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0LldJUkVUWVBFX0VORF9HUk9VUDoKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmludmFsaWRXaXJlVHlwZSgpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgbWVyZ2luZyBhIG5ldyBmaWVsZCBjb250YWluaW5nIGEgc2luZ2xlIHZhcmludAorICAgICAqIHZhbHVlLiBUaGlzIGlzIHVzZWQgaW4gcGFydGljdWxhciB3aGVuIGFuIHVua25vd24gZW51bSB2YWx1ZSBpcworICAgICAqIGVuY291bnRlcmVkLgorICAgICAqCisgICAgICogPHA+Rm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlVmFyaW50RmllbGQoaW50IGZpZWxkTnVtYmVyLCBpbnQgdmFsdWUpIHsKKyAgICAgIGlmIChmaWVsZE51bWJlciA9PSAwKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlplcm8gaXMgbm90IGEgdmFsaWQgZmllbGQgbnVtYmVyLiIpOworICAgICAgfQorICAgICAgZW5zdXJlSW5pdGlhbGl6ZWRCdXROb3RCdWlsdCgpOworICAgICAgdHJ5IHsKKyAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KGZpZWxkTnVtYmVyLCB2YWx1ZSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFNob3VsZCBuZXZlciBoYXBwZW4uCisgICAgICB9CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIG1lcmdpbmcgYSBsZW5ndGgtZGVsaW1pdGVkIGZpZWxkLgorICAgICAqCisgICAgICogPHA+Rm9yIHVzZSBieSBnZW5lcmF0ZWQgY29kZSBvbmx5LgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTGVuZ3RoRGVsaW1pdGVkRmllbGQoCisgICAgICAgIGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgQnl0ZVN0cmluZyB2YWx1ZSkgeyAgCisgICAgICBpZiAoZmllbGROdW1iZXIgPT0gMCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJaZXJvIGlzIG5vdCBhIHZhbGlkIGZpZWxkIG51bWJlci4iKTsKKyAgICAgIH0KKyAgICAgIGVuc3VyZUluaXRpYWxpemVkQnV0Tm90QnVpbHQoKTsKKyAgICAgIHRyeSB7CisgICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKGZpZWxkTnVtYmVyLCB2YWx1ZSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFNob3VsZCBuZXZlciBoYXBwZW4uCisgICAgICB9CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWlsZCB0aGUge0BsaW5rIFVua25vd25GaWVsZFNldExpdGV9IGFuZCByZXR1cm4gaXQuCisgICAgICoKKyAgICAgKiA8cD5PbmNlIHtAY29kZSBidWlsZCgpfSBoYXMgYmVlbiBjYWxsZWQsIHRoZSB7QGNvZGUgQnVpbGRlcn0gd2lsbCBubworICAgICAqIGxvbmdlciBiZSB1c2FibGUuICBDYWxsaW5nIGFueSBtZXRob2QgYWZ0ZXIge0Bjb2RlIGJ1aWxkKCl9IHdpbGwgcmVzdWx0CisgICAgICogaW4gdW5kZWZpbmVkIGJlaGF2aW9yIGFuZCBjYW4gY2F1c2UgYSB7QGNvZGUgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufSB0byBiZQorICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIDxwPkZvciB1c2UgYnkgZ2VuZXJhdGVkIGNvZGUgb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5rbm93bkZpZWxkU2V0TGl0ZSBidWlsZCgpIHsKKyAgICAgIGlmIChidWlsdCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJEbyBub3QgcmV1c2UgVW5rbm93bkZpZWxkU2V0TGl0ZSBCdWlsZGVycy4iKTsKKyAgICAgIH0KKworICAgICAgYnVpbHQgPSB0cnVlOworCisgICAgICBmaW5hbCBVbmtub3duRmllbGRTZXRMaXRlIHJlc3VsdDsKKyAgICAgIC8vIElmIHdlIHdlcmUgbmV2ZXIgaW5pdGlhbGl6ZWQsIG5vIGRhdGEgd2FzIHdyaXR0ZW4uCisgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgcmVzdWx0ID0gZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICB0cnkgeworICAgICAgICAgIG91dHB1dC5mbHVzaCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgLy8gU2hvdWxkIG5ldmVyIGhhcHBlbi4KKyAgICAgICAgfQorICAgICAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBieXRlU3RyaW5nT3V0cHV0LnRvQnl0ZVN0cmluZygpOworICAgICAgICBpZiAoYnl0ZVN0cmluZy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICByZXN1bHQgPSBnZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQgPSBuZXcgVW5rbm93bkZpZWxkU2V0TGl0ZShieXRlU3RyaW5nKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBBbGxvdyBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLgorICAgICAgb3V0cHV0ID0gbnVsbDsKKyAgICAgIGJ5dGVTdHJpbmdPdXRwdXQgPSBudWxsOworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhbiBlbnRpcmUgbWVzc2FnZSBmcm9tIHtAY29kZSBpbnB1dH0gYW5kIG1lcmdlIGl0cyBmaWVsZHMgaW50bworICAgICAqIHRoaXMgc2V0LgorICAgICAqLworICAgIHByaXZhdGUgQnVpbGRlciBtZXJnZUZyb20oZmluYWwgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIEVuc3VyZXMgaW5pdGlhbGl6YXRpb24gaW4gbWVyZ2VGaWVsZEZyb20uCisgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICBmaW5hbCBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOworICAgICAgICBpZiAodGFnID09IDAgfHwgIW1lcmdlRmllbGRGcm9tKHRhZywgaW5wdXQpKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5tb2RpZmlhYmxlTGF6eVN0cmluZ0xpc3QuamF2YSBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1VubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWNjMDA1ZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1VubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0LmphdmEKQEAgLTAsMCArMSwyMDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tQWNjZXNzOworCisvKioKKyAqIEFuIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBMYXp5U3RyaW5nTGlzdH0gdGhhdCB3cmFwcyBhbm90aGVyCisgKiB7QGxpbmsgTGF6eVN0cmluZ0xpc3R9IHN1Y2ggdGhhdCBpdCBjYW5ub3QgYmUgbW9kaWZpZWQgdmlhIHRoZSB3cmFwcGVyLgorICoKKyAqIEBhdXRob3Igam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorICovCitwdWJsaWMgY2xhc3MgVW5tb2RpZmlhYmxlTGF6eVN0cmluZ0xpc3QgZXh0ZW5kcyBBYnN0cmFjdExpc3Q8U3RyaW5nPgorICAgIGltcGxlbWVudHMgTGF6eVN0cmluZ0xpc3QsIFJhbmRvbUFjY2VzcyB7CisKKyAgcHJpdmF0ZSBmaW5hbCBMYXp5U3RyaW5nTGlzdCBsaXN0OworCisgIHB1YmxpYyBVbm1vZGlmaWFibGVMYXp5U3RyaW5nTGlzdChMYXp5U3RyaW5nTGlzdCBsaXN0KSB7CisgICAgdGhpcy5saXN0ID0gbGlzdDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIGdldChpbnQgaW5kZXgpIHsKKyAgICByZXR1cm4gbGlzdC5nZXQoaW5kZXgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gbGlzdC5zaXplKCk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIEJ5dGVTdHJpbmcgZ2V0Qnl0ZVN0cmluZyhpbnQgaW5kZXgpIHsKKyAgICByZXR1cm4gbGlzdC5nZXRCeXRlU3RyaW5nKGluZGV4KTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgdm9pZCBhZGQoQnl0ZVN0cmluZyBlbGVtZW50KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIHZvaWQgc2V0KGludCBpbmRleCwgQnl0ZVN0cmluZyBlbGVtZW50KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIGJvb2xlYW4gYWRkQWxsQnl0ZVN0cmluZyhDb2xsZWN0aW9uPD8gZXh0ZW5kcyBCeXRlU3RyaW5nPiBlbGVtZW50KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIGJ5dGVbXSBnZXRCeXRlQXJyYXkoaW50IGluZGV4KSB7CisgICAgcmV0dXJuIGxpc3QuZ2V0Qnl0ZUFycmF5KGluZGV4KTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgdm9pZCBhZGQoYnl0ZVtdIGVsZW1lbnQpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgfQorICAKKyAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgIHB1YmxpYyB2b2lkIHNldChpbnQgaW5kZXgsIGJ5dGVbXSBlbGVtZW50KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIGJvb2xlYW4gYWRkQWxsQnl0ZUFycmF5KENvbGxlY3Rpb248Ynl0ZVtdPiBlbGVtZW50KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RJdGVyYXRvcjxTdHJpbmc+IGxpc3RJdGVyYXRvcihmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICByZXR1cm4gbmV3IExpc3RJdGVyYXRvcjxTdHJpbmc+KCkgeworICAgICAgTGlzdEl0ZXJhdG9yPFN0cmluZz4gaXRlciA9IGxpc3QubGlzdEl0ZXJhdG9yKGluZGV4KTsKKworICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICByZXR1cm4gaXRlci5oYXNOZXh0KCk7CisgICAgICB9CisKKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIFN0cmluZyBuZXh0KCkgeworICAgICAgICByZXR1cm4gaXRlci5uZXh0KCk7CisgICAgICB9CisKKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJldmlvdXMoKSB7CisgICAgICAgIHJldHVybiBpdGVyLmhhc1ByZXZpb3VzKCk7CisgICAgICB9CisKKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIFN0cmluZyBwcmV2aW91cygpIHsKKyAgICAgICAgcmV0dXJuIGl0ZXIucHJldmlvdXMoKTsKKyAgICAgIH0KKworICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGl0ZXIubmV4dEluZGV4KCk7CisgICAgICB9CisKKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIGludCBwcmV2aW91c0luZGV4KCkgeworICAgICAgICByZXR1cm4gaXRlci5wcmV2aW91c0luZGV4KCk7CisgICAgICB9CisKKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgIH0KKworICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgdm9pZCBzZXQoU3RyaW5nIG8pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICB9CisKKyAgICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgICAgcHVibGljIHZvaWQgYWRkKFN0cmluZyBvKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgfQorICAgIH07CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEl0ZXJhdG9yPFN0cmluZz4gaXRlcmF0b3IoKSB7CisgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxTdHJpbmc+KCkgeworICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdGVyID0gbGlzdC5pdGVyYXRvcigpOworCisgICAgICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgIHJldHVybiBpdGVyLmhhc05leHQoKTsKKyAgICAgIH0KKworICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgU3RyaW5nIG5leHQoKSB7CisgICAgICAgIHJldHVybiBpdGVyLm5leHQoKTsKKyAgICAgIH0KKworICAgICAgLy9AT3ZlcnJpZGUgKEphdmEgMS42IG92ZXJyaWRlIHNlbWFudGljcywgYnV0IHdlIG11c3Qgc3VwcG9ydCAxLjUpCisgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgfQorICAgIH07CisgIH0KKworICAvL0BPdmVycmlkZSAoSmF2YSAxLjYgb3ZlcnJpZGUgc2VtYW50aWNzLCBidXQgd2UgbXVzdCBzdXBwb3J0IDEuNSkKKyAgcHVibGljIExpc3Q8Pz4gZ2V0VW5kZXJseWluZ0VsZW1lbnRzKCkgeworICAgIC8vIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhbHJlYWR5IHVubW9kaWZpYWJsZS4KKyAgICByZXR1cm4gbGlzdC5nZXRVbmRlcmx5aW5nRWxlbWVudHMoKTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgdm9pZCBtZXJnZUZyb20oTGF6eVN0cmluZ0xpc3Qgb3RoZXIpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgTGlzdDxieXRlW10+IGFzQnl0ZUFycmF5TGlzdCgpIHsKKyAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsaXN0LmFzQnl0ZUFycmF5TGlzdCgpKTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgTGlzdDxCeXRlU3RyaW5nPiBhc0J5dGVTdHJpbmdMaXN0KCkgeworICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGxpc3QuYXNCeXRlU3RyaW5nTGlzdCgpKTsKKyAgfQorCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgTGF6eVN0cmluZ0xpc3QgZ2V0VW5tb2RpZmlhYmxlVmlldygpIHsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVXRmOC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVXRmOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkMGVmNTMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9VdGY4LmphdmEKQEAgLTAsMCArMSwzNDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKKy8qKgorICogQSBzZXQgb2YgbG93LWxldmVsLCBoaWdoLXBlcmZvcm1hbmNlIHN0YXRpYyB1dGlsaXR5IG1ldGhvZHMgcmVsYXRlZAorICogdG8gdGhlIFVURi04IGNoYXJhY3RlciBlbmNvZGluZy4gIFRoaXMgY2xhc3MgaGFzIG5vIGRlcGVuZGVuY2llcworICogb3V0c2lkZSBvZiB0aGUgY29yZSBKREsgbGlicmFyaWVzLgorICoKKyAqIDxwPlRoZXJlIGFyZSBzZXZlcmFsIHZhcmlhbnRzIG9mIFVURi04LiAgVGhlIG9uZSBpbXBsZW1lbnRlZCBieQorICogdGhpcyBjbGFzcyBpcyB0aGUgcmVzdHJpY3RlZCBkZWZpbml0aW9uIG9mIFVURi04IGludHJvZHVjZWQgaW4KKyAqIFVuaWNvZGUgMy4xLCB3aGljaCBtYW5kYXRlcyB0aGUgcmVqZWN0aW9uIG9mICJvdmVybG9uZyIgYnl0ZQorICogc2VxdWVuY2VzIGFzIHdlbGwgYXMgcmVqZWN0aW9uIG9mIDMtYnl0ZSBzdXJyb2dhdGUgY29kZXBvaW50IGJ5dGUKKyAqIHNlcXVlbmNlcy4gIE5vdGUgdGhhdCB0aGUgVVRGLTggZGVjb2RlciBpbmNsdWRlZCBpbiBPcmFjbGUncyBKREsKKyAqIGhhcyBiZWVuIG1vZGlmaWVkIHRvIGFsc28gcmVqZWN0ICJvdmVybG9uZyIgYnl0ZSBzZXF1ZW5jZXMsIGJ1dCAoYXMKKyAqIG9mIDIwMTEpIHN0aWxsIGFjY2VwdHMgMy1ieXRlIHN1cnJvZ2F0ZSBjb2RlcG9pbnQgYnl0ZSBzZXF1ZW5jZXMuCisgKgorICogPHA+VGhlIGJ5dGUgc2VxdWVuY2VzIGNvbnNpZGVyZWQgdmFsaWQgYnkgdGhpcyBjbGFzcyBhcmUgZXhhY3RseQorICogdGhvc2UgdGhhdCBjYW4gYmUgcm91bmR0cmlwIGNvbnZlcnRlZCB0byBTdHJpbmdzIGFuZCBiYWNrIHRvIGJ5dGVzCisgKiB1c2luZyB0aGUgVVRGLTggY2hhcnNldCwgd2l0aG91dCBsb3NzOiA8cHJlPiB7QGNvZGUKKyAqIEFycmF5cy5lcXVhbHMoYnl0ZXMsIG5ldyBTdHJpbmcoYnl0ZXMsICJVVEYtOCIpLmdldEJ5dGVzKCJVVEYtOCIpKQorICogfTwvcHJlPgorICoKKyAqIDxwPlNlZSB0aGUgVW5pY29kZSBTdGFuZGFyZCw8L2JyPgorICogVGFibGUgMy02LiA8ZW0+VVRGLTggQml0IERpc3RyaWJ1dGlvbjwvZW0+LDwvYnI+CisgKiBUYWJsZSAzLTcuIDxlbT5XZWxsIEZvcm1lZCBVVEYtOCBCeXRlIFNlcXVlbmNlczwvZW0+LgorICoKKyAqIDxwPlRoaXMgY2xhc3Mgc3VwcG9ydHMgZGVjb2Rpbmcgb2YgcGFydGlhbCBieXRlIHNlcXVlbmNlcywgc28gdGhhdCB0aGUKKyAqIGJ5dGVzIGluIGEgY29tcGxldGUgVVRGLTggYnl0ZSBzZXF1ZW5jZXMgY2FuIGJlIHN0b3JlZCBpbiBtdWx0aXBsZQorICogc2VnbWVudHMuICBNZXRob2RzIHR5cGljYWxseSByZXR1cm4ge0BsaW5rICNNQUxGT1JNRUR9IGlmIHRoZSBwYXJ0aWFsCisgKiBieXRlIHNlcXVlbmNlIGlzIGRlZmluaXRlbHkgbm90IHdlbGwtZm9ybWVkLCB7QGxpbmsgI0NPTVBMRVRFfSBpZiBpdCBpcworICogd2VsbC1mb3JtZWQgaW4gdGhlIGFic2VuY2Ugb2YgYWRkaXRpb25hbCBpbnB1dCwgb3IgaWYgdGhlIGJ5dGUgc2VxdWVuY2UKKyAqIGFwcGFyZW50bHkgdGVybWluYXRlZCBpbiB0aGUgbWlkZGxlIG9mIGEgY2hhcmFjdGVyLCBhbiBvcGFxdWUgaW50ZWdlcgorICogInN0YXRlIiB2YWx1ZSBjb250YWluaW5nIGVub3VnaCBpbmZvcm1hdGlvbiB0byBkZWNvZGUgdGhlIGNoYXJhY3RlciB3aGVuCisgKiBwYXNzZWQgdG8gYSBzdWJzZXF1ZW50IGludm9jYXRpb24gb2YgYSBwYXJ0aWFsIGRlY29kaW5nIG1ldGhvZC4KKyAqCisgKiBAYXV0aG9yIG1hcnRpbnJiQGdvb2dsZS5jb20gKE1hcnRpbiBCdWNoaG9seikKKyAqLworZmluYWwgY2xhc3MgVXRmOCB7CisgIHByaXZhdGUgVXRmOCgpIHt9CisKKyAgLyoqCisgICAqIFN0YXRlIHZhbHVlIGluZGljYXRpbmcgdGhhdCB0aGUgYnl0ZSBzZXF1ZW5jZSBpcyB3ZWxsLWZvcm1lZCBhbmQKKyAgICogY29tcGxldGUgKG5vIGZ1cnRoZXIgYnl0ZXMgYXJlIG5lZWRlZCB0byBjb21wbGV0ZSBhIGNoYXJhY3RlcikuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QTEVURSA9IDA7CisKKyAgLyoqCisgICAqIFN0YXRlIHZhbHVlIGluZGljYXRpbmcgdGhhdCB0aGUgYnl0ZSBzZXF1ZW5jZSBpcyBkZWZpbml0ZWx5IG5vdAorICAgKiB3ZWxsLWZvcm1lZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BTEZPUk1FRCA9IC0xOworCisgIC8vIE90aGVyIHN0YXRlIHZhbHVlcyBpbmNsdWRlIHRoZSBwYXJ0aWFsIGJ5dGVzIG9mIHRoZSBpbmNvbXBsZXRlCisgIC8vIGNoYXJhY3RlciB0byBiZSBkZWNvZGVkIGluIHRoZSBzaW1wbGVzdCB3YXk6IHdlIHBhY2sgdGhlIGJ5dGVzCisgIC8vIGludG8gdGhlIHN0YXRlIGludCBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyLiAgRm9yIGV4YW1wbGU6CisgIC8vCisgIC8vIGludCBzdGF0ZSA9IGJ5dGUxIF4gKGJ5dGUyIDw8IDgpIF4gKGJ5dGUzIDw8IDE2KTsKKyAgLy8KKyAgLy8gU3VjaCBhIHN0YXRlIGlzIHVucGFja2VkIHRodXMgKG5vdGUgdGhlIH4gb3BlcmF0aW9uIGZvciBieXRlMiB0bworICAvLyB1bmRvIGJ5dGUxJ3Mgc2lnbi1leHRlbnNpb24gYml0cyk6CisgIC8vCisgIC8vIGludCBieXRlMSA9IChieXRlKSBzdGF0ZTsKKyAgLy8gaW50IGJ5dGUyID0gKGJ5dGUpIH4oc3RhdGUgPj4gOCk7CisgIC8vIGludCBieXRlMyA9IChieXRlKSAoc3RhdGUgPj4gMTYpOworICAvLworICAvLyBXZSBjYW5ub3Qgc3RvcmUgYSB6ZXJvIGJ5dGUgaW4gdGhlIHN0YXRlIGJlY2F1c2UgaXQgd291bGQgYmUKKyAgLy8gaW5kaXN0aW5ndWlzaGFibGUgZnJvbSB0aGUgYWJzZW5jZSBvZiBhIGJ5dGUuICBCdXQgd2UgZG9uJ3QgbmVlZAorICAvLyB0bywgYmVjYXVzZSBwYXJ0aWFsIGJ5dGVzIG11c3QgYWx3YXlzIGJlIG5lZ2F0aXZlLiAgV2hlbiBidWlsZGluZworICAvLyBhIHN0YXRlLCB3ZSBlbnN1cmUgdGhhdCBieXRlMSBpcyBuZWdhdGl2ZSBhbmQgc3Vic2VxdWVudCBieXRlcworICAvLyBhcmUgdmFsaWQgdHJhaWxpbmcgYnl0ZXMuCisKKyAgLyoqCisgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBnaXZlbiBieXRlIGFycmF5IGlzIGEgd2VsbC1mb3JtZWQKKyAgICogVVRGLTggYnl0ZSBzZXF1ZW5jZS4KKyAgICoKKyAgICogPHA+VGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCwgZXF1aXZhbGVudCB0byBhIGNhbGwgdG8ge0Bjb2RlCisgICAqIGlzVmFsaWRVdGY4KGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkVXRmOChieXRlW10gYnl0ZXMpIHsKKyAgICByZXR1cm4gaXNWYWxpZFV0ZjgoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGdpdmVuIGJ5dGUgYXJyYXkgc2xpY2UgaXMgYQorICAgKiB3ZWxsLWZvcm1lZCBVVEYtOCBieXRlIHNlcXVlbmNlLiAgVGhlIHJhbmdlIG9mIGJ5dGVzIHRvIGJlCisgICAqIGNoZWNrZWQgZXh0ZW5kcyBmcm9tIGluZGV4IHtAY29kZSBpbmRleH0sIGluY2x1c2l2ZSwgdG8ge0Bjb2RlCisgICAqIGxpbWl0fSwgZXhjbHVzaXZlLgorICAgKgorICAgKiA8cD5UaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kLCBlcXVpdmFsZW50IHRvIHtAY29kZQorICAgKiBwYXJ0aWFsSXNWYWxpZFV0ZjgoYnl0ZXMsIGluZGV4LCBsaW1pdCkgPT0gVXRmOC5DT01QTEVURX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFV0ZjgoYnl0ZVtdIGJ5dGVzLCBpbnQgaW5kZXgsIGludCBsaW1pdCkgeworICAgIHJldHVybiBwYXJ0aWFsSXNWYWxpZFV0ZjgoYnl0ZXMsIGluZGV4LCBsaW1pdCkgPT0gQ09NUExFVEU7CisgIH0KKworICAvKioKKyAgICogVGVsbHMgd2hldGhlciB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSBzbGljZSBpcyBhIHdlbGwtZm9ybWVkLAorICAgKiBtYWxmb3JtZWQsIG9yIGluY29tcGxldGUgVVRGLTggYnl0ZSBzZXF1ZW5jZS4gIFRoZSByYW5nZSBvZiBieXRlcworICAgKiB0byBiZSBjaGVja2VkIGV4dGVuZHMgZnJvbSBpbmRleCB7QGNvZGUgaW5kZXh9LCBpbmNsdXNpdmUsIHRvCisgICAqIHtAY29kZSBsaW1pdH0sIGV4Y2x1c2l2ZS4KKyAgICoKKyAgICogQHBhcmFtIHN0YXRlIGVpdGhlciB7QGxpbmsgVXRmOCNDT01QTEVURX0gKGlmIHRoaXMgaXMgdGhlIGluaXRpYWwgZGVjb2RpbmcKKyAgICogb3BlcmF0aW9uKSBvciB0aGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBhIGNhbGwgdG8gYSBwYXJ0aWFsIGRlY29kaW5nIG1ldGhvZAorICAgKiBmb3IgdGhlIHByZXZpb3VzIGJ5dGVzCisgICAqCisgICAqIEByZXR1cm4ge0BsaW5rICNNQUxGT1JNRUR9IGlmIHRoZSBwYXJ0aWFsIGJ5dGUgc2VxdWVuY2UgaXMKKyAgICogZGVmaW5pdGVseSBub3Qgd2VsbC1mb3JtZWQsIHtAbGluayAjQ09NUExFVEV9IGlmIGl0IGlzIHdlbGwtZm9ybWVkCisgICAqIChubyBhZGRpdGlvbmFsIGlucHV0IG5lZWRlZCksIG9yIGlmIHRoZSBieXRlIHNlcXVlbmNlIGlzCisgICAqICJpbmNvbXBsZXRlIiwgaS5lLiBhcHBhcmVudGx5IHRlcm1pbmF0ZWQgaW4gdGhlIG1pZGRsZSBvZiBhIGNoYXJhY3RlciwKKyAgICogYW4gb3BhcXVlIGludGVnZXIgInN0YXRlIiB2YWx1ZSBjb250YWluaW5nIGVub3VnaCBpbmZvcm1hdGlvbiB0bworICAgKiBkZWNvZGUgdGhlIGNoYXJhY3RlciB3aGVuIHBhc3NlZCB0byBhIHN1YnNlcXVlbnQgaW52b2NhdGlvbiBvZiBhCisgICAqIHBhcnRpYWwgZGVjb2RpbmcgbWV0aG9kLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcGFydGlhbElzVmFsaWRVdGY4KAorICAgICAgaW50IHN0YXRlLCBieXRlW10gYnl0ZXMsIGludCBpbmRleCwgaW50IGxpbWl0KSB7CisgICAgaWYgKHN0YXRlICE9IENPTVBMRVRFKSB7CisgICAgICAvLyBUaGUgcHJldmlvdXMgZGVjb2Rpbmcgb3BlcmF0aW9uIHdhcyBpbmNvbXBsZXRlIChvciBtYWxmb3JtZWQpLgorICAgICAgLy8gV2UgbG9vayBmb3IgYSB3ZWxsLWZvcm1lZCBzZXF1ZW5jZSBjb25zaXN0aW5nIG9mIGJ5dGVzIGZyb20KKyAgICAgIC8vIHRoZSBwcmV2aW91cyBkZWNvZGluZyBvcGVyYXRpb24gKHN0b3JlZCBpbiBzdGF0ZSkgdG9nZXRoZXIKKyAgICAgIC8vIHdpdGggYnl0ZXMgZnJvbSB0aGUgYXJyYXkgc2xpY2UuCisgICAgICAvLworICAgICAgLy8gV2UgZXhwZWN0IHN1Y2ggInN0cmFkZGxlciBjaGFyYWN0ZXJzIiB0byBiZSByYXJlLgorCisgICAgICBpZiAoaW5kZXggPj0gbGltaXQpIHsgIC8vIE5vIGJ5dGVzPyBObyBwcm9ncmVzcy4KKyAgICAgICAgcmV0dXJuIHN0YXRlOworICAgICAgfQorICAgICAgaW50IGJ5dGUxID0gKGJ5dGUpIHN0YXRlOworICAgICAgLy8gYnl0ZTEgaXMgbmV2ZXIgQVNDSUkuCisgICAgICBpZiAoYnl0ZTEgPCAoYnl0ZSkgMHhFMCkgeworICAgICAgICAvLyB0d28tYnl0ZSBmb3JtCisKKyAgICAgICAgLy8gU2ltdWx0YW5lb3VzbHkgY2hlY2tzIGZvciBpbGxlZ2FsIHRyYWlsaW5nLWJ5dGUgaW4KKyAgICAgICAgLy8gbGVhZGluZyBwb3NpdGlvbiBhbmQgb3ZlcmxvbmcgMi1ieXRlIGZvcm0uCisgICAgICAgIGlmIChieXRlMSA8IChieXRlKSAweEMyIHx8CisgICAgICAgICAgICAvLyBieXRlMiB0cmFpbGluZy1ieXRlIHRlc3QKKyAgICAgICAgICAgIGJ5dGVzW2luZGV4KytdID4gKGJ5dGUpIDB4QkYpIHsKKyAgICAgICAgICByZXR1cm4gTUFMRk9STUVEOworICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKGJ5dGUxIDwgKGJ5dGUpIDB4RjApIHsKKyAgICAgICAgLy8gdGhyZWUtYnl0ZSBmb3JtCisKKyAgICAgICAgLy8gR2V0IGJ5dGUyIGZyb20gc2F2ZWQgc3RhdGUgb3IgYXJyYXkKKyAgICAgICAgaW50IGJ5dGUyID0gKGJ5dGUpIH4oc3RhdGUgPj4gOCk7CisgICAgICAgIGlmIChieXRlMiA9PSAwKSB7CisgICAgICAgICAgYnl0ZTIgPSBieXRlc1tpbmRleCsrXTsKKyAgICAgICAgICBpZiAoaW5kZXggPj0gbGltaXQpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmNvbXBsZXRlU3RhdGVGb3IoYnl0ZTEsIGJ5dGUyKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGUyID4gKGJ5dGUpIDB4QkYgfHwKKyAgICAgICAgICAgIC8vIG92ZXJsb25nPyA1IG1vc3Qgc2lnbmlmaWNhbnQgYml0cyBtdXN0IG5vdCBhbGwgYmUgemVybworICAgICAgICAgICAgKGJ5dGUxID09IChieXRlKSAweEUwICYmIGJ5dGUyIDwgKGJ5dGUpIDB4QTApIHx8CisgICAgICAgICAgICAvLyBpbGxlZ2FsIHN1cnJvZ2F0ZSBjb2RlcG9pbnQ/CisgICAgICAgICAgICAoYnl0ZTEgPT0gKGJ5dGUpIDB4RUQgJiYgYnl0ZTIgPj0gKGJ5dGUpIDB4QTApIHx8CisgICAgICAgICAgICAvLyBieXRlMyB0cmFpbGluZy1ieXRlIHRlc3QKKyAgICAgICAgICAgIGJ5dGVzW2luZGV4KytdID4gKGJ5dGUpIDB4QkYpIHsKKyAgICAgICAgICByZXR1cm4gTUFMRk9STUVEOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBmb3VyLWJ5dGUgZm9ybQorCisgICAgICAgIC8vIEdldCBieXRlMiBhbmQgYnl0ZTMgZnJvbSBzYXZlZCBzdGF0ZSBvciBhcnJheQorICAgICAgICBpbnQgYnl0ZTIgPSAoYnl0ZSkgfihzdGF0ZSA+PiA4KTsKKyAgICAgICAgaW50IGJ5dGUzID0gMDsKKyAgICAgICAgaWYgKGJ5dGUyID09IDApIHsKKyAgICAgICAgICBieXRlMiA9IGJ5dGVzW2luZGV4KytdOworICAgICAgICAgIGlmIChpbmRleCA+PSBsaW1pdCkgeworICAgICAgICAgICAgcmV0dXJuIGluY29tcGxldGVTdGF0ZUZvcihieXRlMSwgYnl0ZTIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBieXRlMyA9IChieXRlKSAoc3RhdGUgPj4gMTYpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlMyA9PSAwKSB7CisgICAgICAgICAgYnl0ZTMgPSBieXRlc1tpbmRleCsrXTsKKyAgICAgICAgICBpZiAoaW5kZXggPj0gbGltaXQpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmNvbXBsZXRlU3RhdGVGb3IoYnl0ZTEsIGJ5dGUyLCBieXRlMyk7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgd2Ugd2VyZSBjYWxsZWQgd2l0aCBzdGF0ZSA9PSBNQUxGT1JNRUQsIHRoZW4gYnl0ZTEgaXMgMHhGRiwKKyAgICAgICAgLy8gd2hpY2ggbmV2ZXIgb2NjdXJzIGluIHdlbGwtZm9ybWVkIFVURi04LCBhbmQgc28gd2Ugd2lsbCByZXR1cm4KKyAgICAgICAgLy8gTUFMRk9STUVEIGFnYWluIGJlbG93LgorCisgICAgICAgIGlmIChieXRlMiA+IChieXRlKSAweEJGIHx8CisgICAgICAgICAgICAvLyBDaGVjayB0aGF0IDEgPD0gcGxhbmUgPD0gMTYuICBUcmlja3kgb3B0aW1pemVkIGZvcm0gb2Y6CisgICAgICAgICAgICAvLyBpZiAoYnl0ZTEgPiAoYnl0ZSkgMHhGNCB8fAorICAgICAgICAgICAgLy8gICAgIGJ5dGUxID09IChieXRlKSAweEYwICYmIGJ5dGUyIDwgKGJ5dGUpIDB4OTAgfHwKKyAgICAgICAgICAgIC8vICAgICBieXRlMSA9PSAoYnl0ZSkgMHhGNCAmJiBieXRlMiA+IChieXRlKSAweDhGKQorICAgICAgICAgICAgKCgoYnl0ZTEgPDwgMjgpICsgKGJ5dGUyIC0gKGJ5dGUpIDB4OTApKSA+PiAzMCkgIT0gMCB8fAorICAgICAgICAgICAgLy8gYnl0ZTMgdHJhaWxpbmctYnl0ZSB0ZXN0CisgICAgICAgICAgICBieXRlMyA+IChieXRlKSAweEJGIHx8CisgICAgICAgICAgICAvLyBieXRlNCB0cmFpbGluZy1ieXRlIHRlc3QKKyAgICAgICAgICAgICBieXRlc1tpbmRleCsrXSA+IChieXRlKSAweEJGKSB7CisgICAgICAgICAgcmV0dXJuIE1BTEZPUk1FRDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBwYXJ0aWFsSXNWYWxpZFV0ZjgoYnl0ZXMsIGluZGV4LCBsaW1pdCk7CisgIH0KKworICAvKioKKyAgICogVGVsbHMgd2hldGhlciB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSBzbGljZSBpcyBhIHdlbGwtZm9ybWVkLAorICAgKiBtYWxmb3JtZWQsIG9yIGluY29tcGxldGUgVVRGLTggYnl0ZSBzZXF1ZW5jZS4gIFRoZSByYW5nZSBvZiBieXRlcworICAgKiB0byBiZSBjaGVja2VkIGV4dGVuZHMgZnJvbSBpbmRleCB7QGNvZGUgaW5kZXh9LCBpbmNsdXNpdmUsIHRvCisgICAqIHtAY29kZSBsaW1pdH0sIGV4Y2x1c2l2ZS4KKyAgICoKKyAgICogPHA+VGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCwgZXF1aXZhbGVudCB0byBhIGNhbGwgdG8ge0Bjb2RlCisgICAqIHBhcnRpYWxJc1ZhbGlkVXRmOChVdGY4LkNPTVBMRVRFLCBieXRlcywgaW5kZXgsIGxpbWl0KX0uCisgICAqCisgICAqIEByZXR1cm4ge0BsaW5rICNNQUxGT1JNRUR9IGlmIHRoZSBwYXJ0aWFsIGJ5dGUgc2VxdWVuY2UgaXMKKyAgICogZGVmaW5pdGVseSBub3Qgd2VsbC1mb3JtZWQsIHtAbGluayAjQ09NUExFVEV9IGlmIGl0IGlzIHdlbGwtZm9ybWVkCisgICAqIChubyBhZGRpdGlvbmFsIGlucHV0IG5lZWRlZCksIG9yIGlmIHRoZSBieXRlIHNlcXVlbmNlIGlzCisgICAqICJpbmNvbXBsZXRlIiwgaS5lLiBhcHBhcmVudGx5IHRlcm1pbmF0ZWQgaW4gdGhlIG1pZGRsZSBvZiBhIGNoYXJhY3RlciwKKyAgICogYW4gb3BhcXVlIGludGVnZXIgInN0YXRlIiB2YWx1ZSBjb250YWluaW5nIGVub3VnaCBpbmZvcm1hdGlvbiB0bworICAgKiBkZWNvZGUgdGhlIGNoYXJhY3RlciB3aGVuIHBhc3NlZCB0byBhIHN1YnNlcXVlbnQgaW52b2NhdGlvbiBvZiBhCisgICAqIHBhcnRpYWwgZGVjb2RpbmcgbWV0aG9kLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcGFydGlhbElzVmFsaWRVdGY4KAorICAgICAgYnl0ZVtdIGJ5dGVzLCBpbnQgaW5kZXgsIGludCBsaW1pdCkgeworICAgIC8vIE9wdGltaXplIGZvciAxMDAlIEFTQ0lJLgorICAgIC8vIEhvdHNwb3QgbG92ZXMgc21hbGwgc2ltcGxlIHRvcC1sZXZlbCBsb29wcyBsaWtlIHRoaXMuCisgICAgd2hpbGUgKGluZGV4IDwgbGltaXQgJiYgYnl0ZXNbaW5kZXhdID49IDApIHsKKyAgICAgIGluZGV4Kys7CisgICAgfQorCisgICAgcmV0dXJuIChpbmRleCA+PSBsaW1pdCkgPyBDT01QTEVURSA6CisgICAgICAgIHBhcnRpYWxJc1ZhbGlkVXRmOE5vbkFzY2lpKGJ5dGVzLCBpbmRleCwgbGltaXQpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgaW50IHBhcnRpYWxJc1ZhbGlkVXRmOE5vbkFzY2lpKAorICAgICAgYnl0ZVtdIGJ5dGVzLCBpbnQgaW5kZXgsIGludCBsaW1pdCkgeworICAgIGZvciAoOzspIHsKKyAgICAgIGludCBieXRlMSwgYnl0ZTI7CisKKyAgICAgIC8vIE9wdGltaXplIGZvciBpbnRlcmlvciBydW5zIG9mIEFTQ0lJIGJ5dGVzLgorICAgICAgZG8geworICAgICAgICBpZiAoaW5kZXggPj0gbGltaXQpIHsKKyAgICAgICAgICByZXR1cm4gQ09NUExFVEU7CisgICAgICAgIH0KKyAgICAgIH0gd2hpbGUgKChieXRlMSA9IGJ5dGVzW2luZGV4KytdKSA+PSAwKTsKKworICAgICAgaWYgKGJ5dGUxIDwgKGJ5dGUpIDB4RTApIHsKKyAgICAgICAgLy8gdHdvLWJ5dGUgZm9ybQorCisgICAgICAgIGlmIChpbmRleCA+PSBsaW1pdCkgeworICAgICAgICAgIHJldHVybiBieXRlMTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNpbXVsdGFuZW91c2x5IGNoZWNrcyBmb3IgaWxsZWdhbCB0cmFpbGluZy1ieXRlIGluCisgICAgICAgIC8vIGxlYWRpbmcgcG9zaXRpb24gYW5kIG92ZXJsb25nIDItYnl0ZSBmb3JtLgorICAgICAgICBpZiAoYnl0ZTEgPCAoYnl0ZSkgMHhDMiB8fAorICAgICAgICAgICAgYnl0ZXNbaW5kZXgrK10gPiAoYnl0ZSkgMHhCRikgeworICAgICAgICAgIHJldHVybiBNQUxGT1JNRUQ7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAoYnl0ZTEgPCAoYnl0ZSkgMHhGMCkgeworICAgICAgICAvLyB0aHJlZS1ieXRlIGZvcm0KKworICAgICAgICBpZiAoaW5kZXggPj0gbGltaXQgLSAxKSB7IC8vIGluY29tcGxldGUgc2VxdWVuY2UKKyAgICAgICAgICByZXR1cm4gaW5jb21wbGV0ZVN0YXRlRm9yKGJ5dGVzLCBpbmRleCwgbGltaXQpOworICAgICAgICB9CisgICAgICAgIGlmICgoYnl0ZTIgPSBieXRlc1tpbmRleCsrXSkgPiAoYnl0ZSkgMHhCRiB8fAorICAgICAgICAgICAgLy8gb3Zlcmxvbmc/IDUgbW9zdCBzaWduaWZpY2FudCBiaXRzIG11c3Qgbm90IGFsbCBiZSB6ZXJvCisgICAgICAgICAgICAoYnl0ZTEgPT0gKGJ5dGUpIDB4RTAgJiYgYnl0ZTIgPCAoYnl0ZSkgMHhBMCkgfHwKKyAgICAgICAgICAgIC8vIGNoZWNrIGZvciBpbGxlZ2FsIHN1cnJvZ2F0ZSBjb2RlcG9pbnRzCisgICAgICAgICAgICAoYnl0ZTEgPT0gKGJ5dGUpIDB4RUQgJiYgYnl0ZTIgPj0gKGJ5dGUpIDB4QTApIHx8CisgICAgICAgICAgICAvLyBieXRlMyB0cmFpbGluZy1ieXRlIHRlc3QKKyAgICAgICAgICAgIGJ5dGVzW2luZGV4KytdID4gKGJ5dGUpIDB4QkYpIHsKKyAgICAgICAgICByZXR1cm4gTUFMRk9STUVEOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBmb3VyLWJ5dGUgZm9ybQorCisgICAgICAgIGlmIChpbmRleCA+PSBsaW1pdCAtIDIpIHsgIC8vIGluY29tcGxldGUgc2VxdWVuY2UKKyAgICAgICAgICByZXR1cm4gaW5jb21wbGV0ZVN0YXRlRm9yKGJ5dGVzLCBpbmRleCwgbGltaXQpOworICAgICAgICB9CisgICAgICAgIGlmICgoYnl0ZTIgPSBieXRlc1tpbmRleCsrXSkgPiAoYnl0ZSkgMHhCRiB8fAorICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCAxIDw9IHBsYW5lIDw9IDE2LiAgVHJpY2t5IG9wdGltaXplZCBmb3JtIG9mOgorICAgICAgICAgICAgLy8gaWYgKGJ5dGUxID4gKGJ5dGUpIDB4RjQgfHwKKyAgICAgICAgICAgIC8vICAgICBieXRlMSA9PSAoYnl0ZSkgMHhGMCAmJiBieXRlMiA8IChieXRlKSAweDkwIHx8CisgICAgICAgICAgICAvLyAgICAgYnl0ZTEgPT0gKGJ5dGUpIDB4RjQgJiYgYnl0ZTIgPiAoYnl0ZSkgMHg4RikKKyAgICAgICAgICAgICgoKGJ5dGUxIDw8IDI4KSArIChieXRlMiAtIChieXRlKSAweDkwKSkgPj4gMzApICE9IDAgfHwKKyAgICAgICAgICAgIC8vIGJ5dGUzIHRyYWlsaW5nLWJ5dGUgdGVzdAorICAgICAgICAgICAgYnl0ZXNbaW5kZXgrK10gPiAoYnl0ZSkgMHhCRiB8fAorICAgICAgICAgICAgLy8gYnl0ZTQgdHJhaWxpbmctYnl0ZSB0ZXN0CisgICAgICAgICAgICBieXRlc1tpbmRleCsrXSA+IChieXRlKSAweEJGKSB7CisgICAgICAgICAgcmV0dXJuIE1BTEZPUk1FRDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGludCBpbmNvbXBsZXRlU3RhdGVGb3IoaW50IGJ5dGUxKSB7CisgICAgcmV0dXJuIChieXRlMSA+IChieXRlKSAweEY0KSA/CisgICAgICAgIE1BTEZPUk1FRCA6IGJ5dGUxOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgaW50IGluY29tcGxldGVTdGF0ZUZvcihpbnQgYnl0ZTEsIGludCBieXRlMikgeworICAgIHJldHVybiAoYnl0ZTEgPiAoYnl0ZSkgMHhGNCB8fAorICAgICAgICAgICAgYnl0ZTIgPiAoYnl0ZSkgMHhCRikgPworICAgICAgICBNQUxGT1JNRUQgOiBieXRlMSBeIChieXRlMiA8PCA4KTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGludCBpbmNvbXBsZXRlU3RhdGVGb3IoaW50IGJ5dGUxLCBpbnQgYnl0ZTIsIGludCBieXRlMykgeworICAgIHJldHVybiAoYnl0ZTEgPiAoYnl0ZSkgMHhGNCB8fAorICAgICAgICAgICAgYnl0ZTIgPiAoYnl0ZSkgMHhCRiB8fAorICAgICAgICAgICAgYnl0ZTMgPiAoYnl0ZSkgMHhCRikgPworICAgICAgICBNQUxGT1JNRUQgOiBieXRlMSBeIChieXRlMiA8PCA4KSBeIChieXRlMyA8PCAxNik7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBpbnQgaW5jb21wbGV0ZVN0YXRlRm9yKGJ5dGVbXSBieXRlcywgaW50IGluZGV4LCBpbnQgbGltaXQpIHsKKyAgICBpbnQgYnl0ZTEgPSBieXRlc1tpbmRleCAtIDFdOworICAgIHN3aXRjaCAobGltaXQgLSBpbmRleCkgeworICAgICAgY2FzZSAwOiByZXR1cm4gaW5jb21wbGV0ZVN0YXRlRm9yKGJ5dGUxKTsKKyAgICAgIGNhc2UgMTogcmV0dXJuIGluY29tcGxldGVTdGF0ZUZvcihieXRlMSwgYnl0ZXNbaW5kZXhdKTsKKyAgICAgIGNhc2UgMjogcmV0dXJuIGluY29tcGxldGVTdGF0ZUZvcihieXRlMSwgYnl0ZXNbaW5kZXhdLCBieXRlc1tpbmRleCArIDFdKTsKKyAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdC5qYXZhIGIvamF2YS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhODNiNjYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9XaXJlRm9ybWF0LmphdmEKQEAgLTAsMCArMSwyNDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBQcm90b2NvbCBCdWZmZXIgbGlicmFyeSBhbmQgZ2VuZXJhdGVkCisgKiBtZXNzYWdlIGltcGxlbWVudGF0aW9ucy4gIEl0IGlzIHB1YmxpYyBvbmx5IGJlY2F1c2UgdGhvc2UgZ2VuZXJhdGVkIG1lc3NhZ2VzCisgKiBkbyBub3QgcmVzaWRlIGluIHRoZSB7QGNvZGUgcHJvdG9idWZ9IHBhY2thZ2UuICBPdGhlcnMgc2hvdWxkIG5vdCB1c2UgdGhpcworICogY2xhc3MgZGlyZWN0bHkuCisgKgorICogVGhpcyBjbGFzcyBjb250YWlucyBjb25zdGFudHMgYW5kIGhlbHBlciBmdW5jdGlvbnMgdXNlZnVsIGZvciBkZWFsaW5nIHdpdGgKKyAqIHRoZSBQcm90b2NvbCBCdWZmZXIgd2lyZSBmb3JtYXQuCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFdpcmVGb3JtYXQgeworICAvLyBEbyBub3QgYWxsb3cgaW5zdGFudGlhdGlvbi4KKyAgcHJpdmF0ZSBXaXJlRm9ybWF0KCkge30KKworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSVJFVFlQRV9WQVJJTlQgICAgICAgICAgID0gMDsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfRklYRUQ2NCAgICAgICAgICA9IDE7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQgPSAyOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSVJFVFlQRV9TVEFSVF9HUk9VUCAgICAgID0gMzsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfRU5EX0dST1VQICAgICAgICA9IDQ7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdJUkVUWVBFX0ZJWEVEMzIgICAgICAgICAgPSA1OworCisgIHN0YXRpYyBmaW5hbCBpbnQgVEFHX1RZUEVfQklUUyA9IDM7CisgIHN0YXRpYyBmaW5hbCBpbnQgVEFHX1RZUEVfTUFTSyA9ICgxIDw8IFRBR19UWVBFX0JJVFMpIC0gMTsKKworICAvKiogR2l2ZW4gYSB0YWcgdmFsdWUsIGRldGVybWluZXMgdGhlIHdpcmUgdHlwZSAodGhlIGxvd2VyIDMgYml0cykuICovCisgIHN0YXRpYyBpbnQgZ2V0VGFnV2lyZVR5cGUoZmluYWwgaW50IHRhZykgeworICAgIHJldHVybiB0YWcgJiBUQUdfVFlQRV9NQVNLOworICB9CisKKyAgLyoqIEdpdmVuIGEgdGFnIHZhbHVlLCBkZXRlcm1pbmVzIHRoZSBmaWVsZCBudW1iZXIgKHRoZSB1cHBlciAyOSBiaXRzKS4gKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgZ2V0VGFnRmllbGROdW1iZXIoZmluYWwgaW50IHRhZykgeworICAgIHJldHVybiB0YWcgPj4+IFRBR19UWVBFX0JJVFM7CisgIH0KKworICAvKiogTWFrZXMgYSB0YWcgdmFsdWUgZ2l2ZW4gYSBmaWVsZCBudW1iZXIgYW5kIHdpcmUgdHlwZS4gKi8KKyAgc3RhdGljIGludCBtYWtlVGFnKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHdpcmVUeXBlKSB7CisgICAgcmV0dXJuIChmaWVsZE51bWJlciA8PCBUQUdfVFlQRV9CSVRTKSB8IHdpcmVUeXBlOworICB9CisKKyAgLyoqCisgICAqIExpdGUgZXF1aXZhbGVudCB0byB7QGxpbmsgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLkphdmFUeXBlfS4gIFRoaXMgaXMKKyAgICogb25seSBoZXJlIHRvIHN1cHBvcnQgdGhlIGxpdGUgcnVudGltZSBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGJ5IHVzZXJzLgorICAgKi8KKyAgcHVibGljIGVudW0gSmF2YVR5cGUgeworICAgIElOVCgwKSwKKyAgICBMT05HKDBMKSwKKyAgICBGTE9BVCgwRiksCisgICAgRE9VQkxFKDBEKSwKKyAgICBCT09MRUFOKGZhbHNlKSwKKyAgICBTVFJJTkcoIiIpLAorICAgIEJZVEVfU1RSSU5HKEJ5dGVTdHJpbmcuRU1QVFkpLAorICAgIEVOVU0obnVsbCksCisgICAgTUVTU0FHRShudWxsKTsKKworICAgIEphdmFUeXBlKGZpbmFsIE9iamVjdCBkZWZhdWx0RGVmYXVsdCkgeworICAgICAgdGhpcy5kZWZhdWx0RGVmYXVsdCA9IGRlZmF1bHREZWZhdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGRlZmF1bHQgdmFsdWUgZm9yIGZpZWxkcyBvZiB0aGlzIHR5cGUsIGlmIGl0J3MgYSBwcmltaXRpdmUKKyAgICAgKiB0eXBlLgorICAgICAqLworICAgIE9iamVjdCBnZXREZWZhdWx0RGVmYXVsdCgpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0RGVmYXVsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBkZWZhdWx0RGVmYXVsdDsKKyAgfQorCisgIC8qKgorICAgKiBMaXRlIGVxdWl2YWxlbnQgdG8ge0BsaW5rIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlfS4gIFRoaXMgaXMKKyAgICogb25seSBoZXJlIHRvIHN1cHBvcnQgdGhlIGxpdGUgcnVudGltZSBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGJ5IHVzZXJzLgorICAgKi8KKyAgcHVibGljIGVudW0gRmllbGRUeXBlIHsKKyAgICBET1VCTEUgIChKYXZhVHlwZS5ET1VCTEUgICAgICwgV0lSRVRZUEVfRklYRUQ2NCAgICAgICAgICksCisgICAgRkxPQVQgICAoSmF2YVR5cGUuRkxPQVQgICAgICAsIFdJUkVUWVBFX0ZJWEVEMzIgICAgICAgICApLAorICAgIElOVDY0ICAgKEphdmFUeXBlLkxPTkcgICAgICAgLCBXSVJFVFlQRV9WQVJJTlQgICAgICAgICAgKSwKKyAgICBVSU5UNjQgIChKYXZhVHlwZS5MT05HICAgICAgICwgV0lSRVRZUEVfVkFSSU5UICAgICAgICAgICksCisgICAgSU5UMzIgICAoSmF2YVR5cGUuSU5UICAgICAgICAsIFdJUkVUWVBFX1ZBUklOVCAgICAgICAgICApLAorICAgIEZJWEVENjQgKEphdmFUeXBlLkxPTkcgICAgICAgLCBXSVJFVFlQRV9GSVhFRDY0ICAgICAgICAgKSwKKyAgICBGSVhFRDMyIChKYXZhVHlwZS5JTlQgICAgICAgICwgV0lSRVRZUEVfRklYRUQzMiAgICAgICAgICksCisgICAgQk9PTCAgICAoSmF2YVR5cGUuQk9PTEVBTiAgICAsIFdJUkVUWVBFX1ZBUklOVCAgICAgICAgICApLAorICAgIFNUUklORyAgKEphdmFUeXBlLlNUUklORyAgICAgLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhY2thYmxlKCkgeyByZXR1cm4gZmFsc2U7IH0KKyAgICB9LAorICAgIEdST1VQICAgKEphdmFUeXBlLk1FU1NBR0UgICAgLCBXSVJFVFlQRV9TVEFSVF9HUk9VUCAgICAgKSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhY2thYmxlKCkgeyByZXR1cm4gZmFsc2U7IH0KKyAgICB9LAorICAgIE1FU1NBR0UgKEphdmFUeXBlLk1FU1NBR0UgICAgLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhY2thYmxlKCkgeyByZXR1cm4gZmFsc2U7IH0KKyAgICB9LAorICAgIEJZVEVTICAgKEphdmFUeXBlLkJZVEVfU1RSSU5HLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhY2thYmxlKCkgeyByZXR1cm4gZmFsc2U7IH0KKyAgICB9LAorICAgIFVJTlQzMiAgKEphdmFUeXBlLklOVCAgICAgICAgLCBXSVJFVFlQRV9WQVJJTlQgICAgICAgICAgKSwKKyAgICBFTlVNICAgIChKYXZhVHlwZS5FTlVNICAgICAgICwgV0lSRVRZUEVfVkFSSU5UICAgICAgICAgICksCisgICAgU0ZJWEVEMzIoSmF2YVR5cGUuSU5UICAgICAgICAsIFdJUkVUWVBFX0ZJWEVEMzIgICAgICAgICApLAorICAgIFNGSVhFRDY0KEphdmFUeXBlLkxPTkcgICAgICAgLCBXSVJFVFlQRV9GSVhFRDY0ICAgICAgICAgKSwKKyAgICBTSU5UMzIgIChKYXZhVHlwZS5JTlQgICAgICAgICwgV0lSRVRZUEVfVkFSSU5UICAgICAgICAgICksCisgICAgU0lOVDY0ICAoSmF2YVR5cGUuTE9ORyAgICAgICAsIFdJUkVUWVBFX1ZBUklOVCAgICAgICAgICApOworCisgICAgRmllbGRUeXBlKGZpbmFsIEphdmFUeXBlIGphdmFUeXBlLCBmaW5hbCBpbnQgd2lyZVR5cGUpIHsKKyAgICAgIHRoaXMuamF2YVR5cGUgPSBqYXZhVHlwZTsKKyAgICAgIHRoaXMud2lyZVR5cGUgPSB3aXJlVHlwZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIEphdmFUeXBlIGphdmFUeXBlOworICAgIHByaXZhdGUgZmluYWwgaW50IHdpcmVUeXBlOworCisgICAgcHVibGljIEphdmFUeXBlIGdldEphdmFUeXBlKCkgeyByZXR1cm4gamF2YVR5cGU7IH0KKyAgICBwdWJsaWMgaW50IGdldFdpcmVUeXBlKCkgeyByZXR1cm4gd2lyZVR5cGU7IH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzUGFja2FibGUoKSB7IHJldHVybiB0cnVlOyB9CisgIH0KKworICAvLyBGaWVsZCBudW1iZXJzIGZvciBmaWVsZHMgaW4gTWVzc2FnZVNldCB3aXJlIGZvcm1hdC4KKyAgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9JVEVNICAgID0gMTsKKyAgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9UWVBFX0lEID0gMjsKKyAgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9NRVNTQUdFID0gMzsKKworICAvLyBUYWcgbnVtYmVycy4KKyAgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9JVEVNX1RBRyA9CisgICAgbWFrZVRhZyhNRVNTQUdFX1NFVF9JVEVNLCBXSVJFVFlQRV9TVEFSVF9HUk9VUCk7CisgIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TRVRfSVRFTV9FTkRfVEFHID0KKyAgICBtYWtlVGFnKE1FU1NBR0VfU0VUX0lURU0sIFdJUkVUWVBFX0VORF9HUk9VUCk7CisgIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TRVRfVFlQRV9JRF9UQUcgPQorICAgIG1ha2VUYWcoTUVTU0FHRV9TRVRfVFlQRV9JRCwgV0lSRVRZUEVfVkFSSU5UKTsKKyAgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9NRVNTQUdFX1RBRyA9CisgICAgbWFrZVRhZyhNRVNTQUdFX1NFVF9NRVNTQUdFLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKworICAvKioKKyAgICogVmFsaWRhdGlvbiBsZXZlbCBmb3IgaGFuZGxpbmcgaW5jb21pbmcgc3RyaW5nIGZpZWxkIGRhdGEgd2hpY2ggcG90ZW50aWFsbHkKKyAgICogY29udGFpbiBub24tVVRGOCBieXRlcy4KKyAgICovCisgIGVudW0gVXRmOFZhbGlkYXRpb24geworICAgIC8qKiBFYWdlcmx5IHBhcnNlcyB0byBTdHJpbmc7IHNpbGVudGx5IGFjY2VwdHMgaW52YWxpZCBVVEY4IGJ5dGVzLiAqLworICAgIExPT1NFIHsKKyAgICAgIE9iamVjdCByZWFkU3RyaW5nKENvZGVkSW5wdXRTdHJlYW0gaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbnB1dC5yZWFkU3RyaW5nKCk7CisgICAgICB9CisgICAgfSwKKyAgICAvKiogRWFnZXJseSBwYXJzZXMgdG8gU3RyaW5nOyB0aHJvd3MgYW4gSU9FeGNlcHRpb24gb24gaW52YWxpZCBieXRlcy4gKi8KKyAgICBTVFJJQ1QgeworICAgICAgT2JqZWN0IHJlYWRTdHJpbmcoQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOworICAgICAgfQorICAgIH0sCisgICAgLyoqIEtlZXAgZGF0YSBhcyBCeXRlU3RyaW5nOyB2YWxpZGF0aW9uL2NvbnZlcnNpb24gdG8gU3RyaW5nIGlzIGxhenkuICovCisgICAgTEFaWSB7CisgICAgICBPYmplY3QgcmVhZFN0cmluZyhDb2RlZElucHV0U3RyZWFtIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gaW5wdXQucmVhZEJ5dGVzKCk7CisgICAgICB9CisgICAgfTsKKworICAgIC8qKiBSZWFkIGEgc3RyaW5nIGZpZWxkIGZyb20gdGhlIGlucHV0IHdpdGggdGhlIHByb3BlciBVVEY4IHZhbGlkYXRpb24uICovCisgICAgYWJzdHJhY3QgT2JqZWN0IHJlYWRTdHJpbmcoQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uOworICB9CisKKyAgLyoqCisgICAqIFJlYWQgYSBmaWVsZCBvZiBhbnkgcHJpbWl0aXZlIHR5cGUgZm9yIGltbXV0YWJsZSBtZXNzYWdlcyBmcm9tIGEKKyAgICogQ29kZWRJbnB1dFN0cmVhbS4gRW51bXMsIGdyb3VwcywgYW5kIGVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBub3QgaGFuZGxlZCBieQorICAgKiB0aGlzIG1ldGhvZC4KKyAgICoKKyAgICogQHBhcmFtIGlucHV0IFRoZSBzdHJlYW0gZnJvbSB3aGljaCB0byByZWFkLgorICAgKiBAcGFyYW0gdHlwZSBEZWNsYXJlZCB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgICogQHBhcmFtIHV0ZjhWYWxpZGF0aW9uIERpZmZlcmVudCBzdHJpbmcgVVRGOCB2YWxpZGF0aW9uIGxldmVsIGZvciBoYW5kbGluZworICAgKiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGZpZWxkcy4KKyAgICogQHJldHVybiBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBmaWVsZCdzIHZhbHVlLCBvZiB0aGUgZXhhY3QKKyAgICogICAgICAgICB0eXBlIHdoaWNoIHdvdWxkIGJlIHJldHVybmVkIGJ5CisgICAqICAgICAgICAge0BsaW5rIE1lc3NhZ2UjZ2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yKX0gZm9yCisgICAqICAgICAgICAgdGhpcyBmaWVsZC4KKyAgICovCisgIHN0YXRpYyBPYmplY3QgcmVhZFByaW1pdGl2ZUZpZWxkKAorICAgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgIEZpZWxkVHlwZSB0eXBlLAorICAgICAgVXRmOFZhbGlkYXRpb24gdXRmOFZhbGlkYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIERPVUJMRSAgOiByZXR1cm4gaW5wdXQucmVhZERvdWJsZSAgKCk7CisgICAgICBjYXNlIEZMT0FUICAgOiByZXR1cm4gaW5wdXQucmVhZEZsb2F0ICAgKCk7CisgICAgICBjYXNlIElOVDY0ICAgOiByZXR1cm4gaW5wdXQucmVhZEludDY0ICAgKCk7CisgICAgICBjYXNlIFVJTlQ2NCAgOiByZXR1cm4gaW5wdXQucmVhZFVJbnQ2NCAgKCk7CisgICAgICBjYXNlIElOVDMyICAgOiByZXR1cm4gaW5wdXQucmVhZEludDMyICAgKCk7CisgICAgICBjYXNlIEZJWEVENjQgOiByZXR1cm4gaW5wdXQucmVhZEZpeGVkNjQgKCk7CisgICAgICBjYXNlIEZJWEVEMzIgOiByZXR1cm4gaW5wdXQucmVhZEZpeGVkMzIgKCk7CisgICAgICBjYXNlIEJPT0wgICAgOiByZXR1cm4gaW5wdXQucmVhZEJvb2wgICAgKCk7CisgICAgICBjYXNlIEJZVEVTICAgOiByZXR1cm4gaW5wdXQucmVhZEJ5dGVzICAgKCk7CisgICAgICBjYXNlIFVJTlQzMiAgOiByZXR1cm4gaW5wdXQucmVhZFVJbnQzMiAgKCk7CisgICAgICBjYXNlIFNGSVhFRDMyOiByZXR1cm4gaW5wdXQucmVhZFNGaXhlZDMyKCk7CisgICAgICBjYXNlIFNGSVhFRDY0OiByZXR1cm4gaW5wdXQucmVhZFNGaXhlZDY0KCk7CisgICAgICBjYXNlIFNJTlQzMiAgOiByZXR1cm4gaW5wdXQucmVhZFNJbnQzMiAgKCk7CisgICAgICBjYXNlIFNJTlQ2NCAgOiByZXR1cm4gaW5wdXQucmVhZFNJbnQ2NCAgKCk7CisKKyAgICAgIGNhc2UgU1RSSU5HICA6IHJldHVybiB1dGY4VmFsaWRhdGlvbi5yZWFkU3RyaW5nKGlucHV0KTsKKyAgICAgIGNhc2UgR1JPVVA6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgInJlYWRQcmltaXRpdmVGaWVsZCgpIGNhbm5vdCBoYW5kbGUgbmVzdGVkIGdyb3Vwcy4iKTsKKyAgICAgIGNhc2UgTUVTU0FHRToKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAicmVhZFByaW1pdGl2ZUZpZWxkKCkgY2Fubm90IGhhbmRsZSBlbWJlZGRlZCBtZXNzYWdlcy4iKTsKKyAgICAgIGNhc2UgRU5VTToKKyAgICAgICAgLy8gV2UgZG9uJ3QgaGFuZGxlIGVudW1zIGJlY2F1c2Ugd2UgZG9uJ3Qga25vdyB3aGF0IHRvIGRvIGlmIHRoZQorICAgICAgICAvLyB2YWx1ZSBpcyBub3QgcmVjb2duaXplZC4KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAicmVhZFByaW1pdGl2ZUZpZWxkKCkgY2Fubm90IGhhbmRsZSBlbnVtcy4iKTsKKyAgICB9CisKKyAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICJUaGVyZSBpcyBubyB3YXkgdG8gZ2V0IGhlcmUsIGJ1dCB0aGUgY29tcGlsZXIgdGhpbmtzIG90aGVyd2lzZS4iKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RNZXNzYWdlVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQWJzdHJhY3RNZXNzYWdlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5NjRlZjUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9BYnN0cmFjdE1lc3NhZ2VUZXN0LmphdmEKQEAgLTAsMCArMSw1MjcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG87CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBVbml0IHRlc3QgZm9yIHtAbGluayBBYnN0cmFjdE1lc3NhZ2V9LgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBjbGFzcyBBYnN0cmFjdE1lc3NhZ2VUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAvKioKKyAgICogRXh0ZW5kcyBBYnN0cmFjdE1lc3NhZ2UgYW5kIHdyYXBzIHNvbWUgb3RoZXIgbWVzc2FnZSBvYmplY3QuICBUaGUgbWV0aG9kcworICAgKiBvZiB0aGUgTWVzc2FnZSBpbnRlcmZhY2Ugd2hpY2ggYXJlbid0IGV4cGxpY2l0bHkgaW1wbGVtZW50ZWQgYnkKKyAgICogQWJzdHJhY3RNZXNzYWdlIGFyZSBmb3J3YXJkZWQgdG8gdGhlIHdyYXBwZWQgb2JqZWN0LiAgVGhpcyBhbGxvd3MgdXMgdG8KKyAgICogdGVzdCB0aGF0IEFic3RyYWN0TWVzc2FnZSdzIGltcGxlbWVudGF0aW9ucyB3b3JrIGV2ZW4gaWYgdGhlIHdyYXBwZWQKKyAgICogb2JqZWN0IGRvZXMgbm90IHVzZSB0aGVtLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQWJzdHJhY3RNZXNzYWdlV3JhcHBlciBleHRlbmRzIEFic3RyYWN0TWVzc2FnZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlIHdyYXBwZWRNZXNzYWdlOworCisgICAgcHVibGljIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIoTWVzc2FnZSB3cmFwcGVkTWVzc2FnZSkgeworICAgICAgdGhpcy53cmFwcGVkTWVzc2FnZSA9IHdyYXBwZWRNZXNzYWdlOworICAgIH0KKworICAgIHB1YmxpYyBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRNZXNzYWdlLmdldERlc2NyaXB0b3JGb3JUeXBlKCk7CisgICAgfQorICAgIHB1YmxpYyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CisgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIoCisgICAgICAgIHdyYXBwZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSk7CisgICAgfQorICAgIHB1YmxpYyBNYXA8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGdldEFsbEZpZWxkcygpIHsKKyAgICAgIHJldHVybiB3cmFwcGVkTWVzc2FnZS5nZXRBbGxGaWVsZHMoKTsKKyAgICB9CisgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICByZXR1cm4gd3JhcHBlZE1lc3NhZ2UuaGFzRmllbGQoZmllbGQpOworICAgIH0KKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRNZXNzYWdlLmdldEZpZWxkKGZpZWxkKTsKKyAgICB9CisgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICByZXR1cm4gd3JhcHBlZE1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpZWxkKTsKKyAgICB9CisgICAgcHVibGljIE9iamVjdCBnZXRSZXBlYXRlZEZpZWxkKAorICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIGludCBpbmRleCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRNZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4KTsKKyAgICB9CisgICAgcHVibGljIFVua25vd25GaWVsZFNldCBnZXRVbmtub3duRmllbGRzKCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRNZXNzYWdlLmdldFVua25vd25GaWVsZHMoKTsKKyAgICB9CisgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7CisgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIod3JhcHBlZE1lc3NhZ2UubmV3QnVpbGRlckZvclR5cGUoKSk7CisgICAgfQorICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKKyAgICAgIHJldHVybiBuZXcgQnVpbGRlcih3cmFwcGVkTWVzc2FnZS50b0J1aWxkZXIoKSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcyBBYnN0cmFjdE1lc3NhZ2UuQnVpbGRlcjxCdWlsZGVyPiB7CisgICAgICBwcml2YXRlIGZpbmFsIE1lc3NhZ2UuQnVpbGRlciB3cmFwcGVkQnVpbGRlcjsKKworICAgICAgcHVibGljIEJ1aWxkZXIoTWVzc2FnZS5CdWlsZGVyIHdyYXBwZWRCdWlsZGVyKSB7CisgICAgICAgIHRoaXMud3JhcHBlZEJ1aWxkZXIgPSB3cmFwcGVkQnVpbGRlcjsKKyAgICAgIH0KKworICAgICAgcHVibGljIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIgYnVpbGQoKSB7CisgICAgICAgIHJldHVybiBuZXcgQWJzdHJhY3RNZXNzYWdlV3JhcHBlcih3cmFwcGVkQnVpbGRlci5idWlsZCgpKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyIGJ1aWxkUGFydGlhbCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyKHdyYXBwZWRCdWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgeworICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIod3JhcHBlZEJ1aWxkZXIuY2xvbmUoKSk7CisgICAgICB9CisgICAgICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgeworICAgICAgICByZXR1cm4gY2xvbmUoKS5idWlsZFBhcnRpYWwoKS5pc0luaXRpYWxpemVkKCk7CisgICAgICB9CisgICAgICBwdWJsaWMgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWRCdWlsZGVyLmdldERlc2NyaXB0b3JGb3JUeXBlKCk7CisgICAgICB9CisgICAgICBwdWJsaWMgQWJzdHJhY3RNZXNzYWdlV3JhcHBlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgeworICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIoCisgICAgICAgICAgd3JhcHBlZEJ1aWxkZXIuZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBNYXA8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBPYmplY3Q+IGdldEFsbEZpZWxkcygpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWRCdWlsZGVyLmdldEFsbEZpZWxkcygpOworICAgICAgfQorICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvckZpZWxkKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIod3JhcHBlZEJ1aWxkZXIubmV3QnVpbGRlckZvckZpZWxkKGZpZWxkKSk7CisgICAgICB9CisgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWRCdWlsZGVyLmhhc0ZpZWxkKGZpZWxkKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkQnVpbGRlci5nZXRGaWVsZChmaWVsZCk7CisgICAgICB9CisgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkQnVpbGRlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICAgIHdyYXBwZWRCdWlsZGVyLmNsZWFyRmllbGQoZmllbGQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaWVsZENvdW50KERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZEJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpZWxkKTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZEJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgpOworICAgICAgfQorICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHdyYXBwZWRCdWlsZGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkQnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgcHVibGljIFVua25vd25GaWVsZFNldCBnZXRVbmtub3duRmllbGRzKCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZEJ1aWxkZXIuZ2V0VW5rbm93bkZpZWxkcygpOworICAgICAgfQorICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcyhVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgICB3cmFwcGVkQnVpbGRlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIE1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZEJ1aWxkZXIoRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkQnVpbGRlci5nZXRGaWVsZEJ1aWxkZXIoZmllbGQpOworICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgUGFyc2VyPD8gZXh0ZW5kcyBNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRNZXNzYWdlLmdldFBhcnNlckZvclR5cGUoKTsKKyAgICB9CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvblRlc3RlciA9CisgICAgbmV3IFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIoVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKSwgbnVsbCk7CisKKyAgVGVzdFV0aWwuUmVmbGVjdGlvblRlc3RlciBleHRlbnNpb25zUmVmbGVjdGlvblRlc3RlciA9CisgICAgbmV3IFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVzY3JpcHRvcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCkpOworCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhcigpIHRocm93cyBFeGNlcHRpb24geworICAgIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIgbWVzc2FnZSA9CisgICAgICBuZXcgQWJzdHJhY3RNZXNzYWdlV3JhcHBlci5CdWlsZGVyKAorICAgICAgICAgIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKFRlc3RVdGlsLmdldEFsbFNldCgpKSkKKyAgICAgICAgLmNsZWFyKCkuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRDbGVhcigoVGVzdEFsbFR5cGVzKSBtZXNzYWdlLndyYXBwZWRNZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlciBtZXNzYWdlID0KKyAgICAgIG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyLkJ1aWxkZXIoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKSkKKyAgICAgICAgLm1lcmdlRnJvbShUZXN0VXRpbC5nZXRBbGxTZXQoKSkuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQoKFRlc3RBbGxUeXBlcykgbWVzc2FnZS53cmFwcGVkTWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXplZFNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIE1lc3NhZ2UgYWJzdHJhY3RNZXNzYWdlID0gbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIoVGVzdFV0aWwuZ2V0QWxsU2V0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0U2VyaWFsaXplZFNpemUoKSwKKyAgICAgICAgICAgICAgICAgYWJzdHJhY3RNZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNZXNzYWdlIGFic3RyYWN0TWVzc2FnZSA9IG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyKFRlc3RVdGlsLmdldEFsbFNldCgpKTsKKworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldCgKKyAgICAgIFRlc3RBbGxUeXBlcy5wYXJzZUZyb20oYWJzdHJhY3RNZXNzYWdlLnRvQnl0ZVN0cmluZygpKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwuZ2V0QWxsU2V0KCkudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICAgICAgIGFic3RyYWN0TWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlciBidWlsZGVyID0KKyAgICAgIG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyLkJ1aWxkZXIoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKSk7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlciBtZXNzYWdlID0KKyAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKFRlc3RVdGlsLmdldEFsbFNldCgpLnRvQnl0ZVN0cmluZygpKS5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldCgoVGVzdEFsbFR5cGVzKSBtZXNzYWdlLndyYXBwZWRNZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nVW5pbml0aWFsaXplZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RSZXF1aXJlZEZvcmVpZ24uQnVpbGRlciBidWlsZGVyID0gVGVzdFJlcXVpcmVkRm9yZWlnbi5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5nZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkuc2V0RHVtbXkyKDEwKTsKKyAgICBCeXRlU3RyaW5nIGJ5dGVzID0gYnVpbGRlci5idWlsZFBhcnRpYWwoKS50b0J5dGVTdHJpbmcoKTsKKyAgICBNZXNzYWdlLkJ1aWxkZXIgYWJzdHJhY3RNZXNzYWdlQnVpbGRlciA9CisgICAgICAgIG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyLkJ1aWxkZXIoVGVzdFJlcXVpcmVkRm9yZWlnbi5uZXdCdWlsZGVyKCkpOworICAgIC8vIG1lcmdlRnJvbSgpIHNob3VsZCBub3QgdGhyb3cgaW5pdGlhbGl6YXRpb24gZXJyb3IuCisgICAgYWJzdHJhY3RNZXNzYWdlQnVpbGRlci5tZXJnZUZyb20oYnl0ZXMpLmJ1aWxkUGFydGlhbCgpOworICAgIHRyeSB7CisgICAgICBhYnN0cmFjdE1lc3NhZ2VCdWlsZGVyLm1lcmdlRnJvbShieXRlcykuYnVpbGQoKTsKKyAgICAgIGZhaWwoKTsKKyAgICB9IGNhdGNoIChVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBleCkgeworICAgICAgLy8gcGFzcworICAgIH0KKworICAgIC8vIHRlc3QgRHluYW1pY01lc3NhZ2UgZGlyZWN0bHkuCisgICAgTWVzc2FnZS5CdWlsZGVyIGR5bmFtaWNNZXNzYWdlQnVpbGRlciA9IER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIoCisgICAgICAgIFRlc3RSZXF1aXJlZEZvcmVpZ24uZ2V0RGVzY3JpcHRvcigpKTsKKyAgICAvLyBtZXJnZUZyb20oKSBzaG91bGQgbm90IHRocm93IGluaXRpYWxpemF0aW9uIGVycm9yLgorICAgIGR5bmFtaWNNZXNzYWdlQnVpbGRlci5tZXJnZUZyb20oYnl0ZXMpLmJ1aWxkUGFydGlhbCgpOworICAgIHRyeSB7CisgICAgICBkeW5hbWljTWVzc2FnZUJ1aWxkZXIubWVyZ2VGcm9tKGJ5dGVzKS5idWlsZCgpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGV4KSB7CisgICAgICAvLyBwYXNzCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhY2tlZFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNZXNzYWdlIGFic3RyYWN0TWVzc2FnZSA9CisgICAgICAgIG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyKFRlc3RVdGlsLmdldFBhY2tlZFNldCgpKTsKKworICAgIFRlc3RVdGlsLmFzc2VydFBhY2tlZEZpZWxkc1NldCgKKyAgICAgIFRlc3RQYWNrZWRUeXBlcy5wYXJzZUZyb20oYWJzdHJhY3RNZXNzYWdlLnRvQnl0ZVN0cmluZygpKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwuZ2V0UGFja2VkU2V0KCkudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICAgICAgIGFic3RyYWN0TWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFja2VkUGFyc2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlciBidWlsZGVyID0KKyAgICAgIG5ldyBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyLkJ1aWxkZXIoVGVzdFBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKSk7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlciBtZXNzYWdlID0KKyAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKFRlc3RVdGlsLmdldFBhY2tlZFNldCgpLnRvQnl0ZVN0cmluZygpKS5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydFBhY2tlZEZpZWxkc1NldCgoVGVzdFBhY2tlZFR5cGVzKSBtZXNzYWdlLndyYXBwZWRNZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RVbnBhY2tlZFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNZXNzYWdlIGFic3RyYWN0TWVzc2FnZSA9CisgICAgICBuZXcgQWJzdHJhY3RNZXNzYWdlV3JhcHBlcihUZXN0VXRpbC5nZXRVbnBhY2tlZFNldCgpKTsKKworICAgIFRlc3RVdGlsLmFzc2VydFVucGFja2VkRmllbGRzU2V0KAorICAgICAgVGVzdFVucGFja2VkVHlwZXMucGFyc2VGcm9tKGFic3RyYWN0TWVzc2FnZS50b0J5dGVTdHJpbmcoKSkpOworCisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLmdldFVucGFja2VkU2V0KCkudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICAgICAgIGFic3RyYWN0TWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VQYWNrZWRUb1VucGFja2VkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlci5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlcihUZXN0VW5wYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkpOworICAgIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIgbWVzc2FnZSA9CisgICAgICBidWlsZGVyLm1lcmdlRnJvbShUZXN0VXRpbC5nZXRQYWNrZWRTZXQoKS50b0J5dGVTdHJpbmcoKSkuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRVbnBhY2tlZEZpZWxkc1NldCgKKyAgICAgIChUZXN0VW5wYWNrZWRUeXBlcykgbWVzc2FnZS53cmFwcGVkTWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VVbnBhY2tlZFRvUGFja2VkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlci5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlcihUZXN0UGFja2VkVHlwZXMubmV3QnVpbGRlcigpKTsKKyAgICBBYnN0cmFjdE1lc3NhZ2VXcmFwcGVyIG1lc3NhZ2UgPQorICAgICAgYnVpbGRlci5tZXJnZUZyb20oVGVzdFV0aWwuZ2V0VW5wYWNrZWRTZXQoKS50b0J5dGVTdHJpbmcoKSkuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRQYWNrZWRGaWVsZHNTZXQoKFRlc3RQYWNrZWRUeXBlcykgbWVzc2FnZS53cmFwcGVkTWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5wYWNrZWRQYXJzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlci5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlcihUZXN0VW5wYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkpOworICAgIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIgbWVzc2FnZSA9CisgICAgICBidWlsZGVyLm1lcmdlRnJvbShUZXN0VXRpbC5nZXRVbnBhY2tlZFNldCgpLnRvQnl0ZVN0cmluZygpKS5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydFVucGFja2VkRmllbGRzU2V0KAorICAgICAgKFRlc3RVbnBhY2tlZFR5cGVzKSBtZXNzYWdlLndyYXBwZWRNZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RPcHRpbWl6ZWRGb3JTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV2UncmUgbW9zdGx5IG9ubHkgY2hlY2tpbmcgdGhhdCB0aGlzIGNsYXNzIHdhcyBjb21waWxlZCBzdWNjZXNzZnVsbHkuCisgICAgVGVzdE9wdGltaXplZEZvclNpemUgbWVzc2FnZSA9CisgICAgICBUZXN0T3B0aW1pemVkRm9yU2l6ZS5uZXdCdWlsZGVyKCkuc2V0SSgxKS5idWlsZCgpOworICAgIG1lc3NhZ2UgPSBUZXN0T3B0aW1pemVkRm9yU2l6ZS5wYXJzZUZyb20obWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUZXN0cyBmb3IgaXNJbml0aWFsaXplZCgpLgorCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RSZXF1aXJlZCBURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQgPQorICAgIFRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGVzdFJlcXVpcmVkIFRFU1RfUkVRVUlSRURfSU5JVElBTElaRUQgPQorICAgIFRlc3RSZXF1aXJlZC5uZXdCdWlsZGVyKCkuc2V0QSgxKS5zZXRCKDIpLnNldEMoMykuYnVpbGQoKTsKKworICBwdWJsaWMgdm9pZCB0ZXN0SXNJbml0aWFsaXplZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0UmVxdWlyZWQubmV3QnVpbGRlcigpOworICAgIEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlciBhYnN0cmFjdEJ1aWxkZXIgPQorICAgICAgbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlcihidWlsZGVyKTsKKworICAgIGFzc2VydEZhbHNlKGFic3RyYWN0QnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydEVxdWFscygiYSwgYiwgYyIsIGFic3RyYWN0QnVpbGRlci5nZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nKCkpOworICAgIGJ1aWxkZXIuc2V0QSgxKTsKKyAgICBhc3NlcnRGYWxzZShhYnN0cmFjdEJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoImIsIGMiLCBhYnN0cmFjdEJ1aWxkZXIuZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKKyAgICBidWlsZGVyLnNldEIoMSk7CisgICAgYXNzZXJ0RmFsc2UoYWJzdHJhY3RCdWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJjIiwgYWJzdHJhY3RCdWlsZGVyLmdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSk7CisgICAgYnVpbGRlci5zZXRDKDEpOworICAgIGFzc2VydFRydWUoYWJzdHJhY3RCdWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCIiLCBhYnN0cmFjdEJ1aWxkZXIuZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RGb3JlaWduSXNJbml0aWFsaXplZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RSZXF1aXJlZEZvcmVpZ24uQnVpbGRlciBidWlsZGVyID0gVGVzdFJlcXVpcmVkRm9yZWlnbi5uZXdCdWlsZGVyKCk7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlci5CdWlsZGVyIGFic3RyYWN0QnVpbGRlciA9CisgICAgICBuZXcgQWJzdHJhY3RNZXNzYWdlV3JhcHBlci5CdWlsZGVyKGJ1aWxkZXIpOworCisgICAgYXNzZXJ0VHJ1ZShhYnN0cmFjdEJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoIiIsIGFic3RyYWN0QnVpbGRlci5nZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nKCkpOworCisgICAgYnVpbGRlci5zZXRPcHRpb25hbE1lc3NhZ2UoVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRGYWxzZShhYnN0cmFjdEJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICJvcHRpb25hbF9tZXNzYWdlLmEsIG9wdGlvbmFsX21lc3NhZ2UuYiwgb3B0aW9uYWxfbWVzc2FnZS5jIiwKKyAgICAgICAgYWJzdHJhY3RCdWlsZGVyLmdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSk7CisKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTWVzc2FnZShURVNUX1JFUVVJUkVEX0lOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRUcnVlKGFic3RyYWN0QnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydEVxdWFscygiIiwgYWJzdHJhY3RCdWlsZGVyLmdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSk7CisKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkTWVzc2FnZShURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQpOworICAgIGFzc2VydEZhbHNlKGFic3RyYWN0QnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMF0uYSwgcmVwZWF0ZWRfbWVzc2FnZVswXS5iLCByZXBlYXRlZF9tZXNzYWdlWzBdLmMiLAorICAgICAgICBhYnN0cmFjdEJ1aWxkZXIuZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKKworICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWRNZXNzYWdlKDAsIFRFU1RfUkVRVUlSRURfSU5JVElBTElaRUQpOworICAgIGFzc2VydFRydWUoYWJzdHJhY3RCdWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCIiLCBhYnN0cmFjdEJ1aWxkZXIuZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRlc3RzIGZvciBtZXJnZUZyb20KKworICBzdGF0aWMgZmluYWwgVGVzdEFsbFR5cGVzIE1FUkdFX1NPVVJDRSA9CisgICAgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQorICAgICAgLnNldE9wdGlvbmFsSW50MzIoMSkKKyAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiZm9vIikKKyAgICAgIC5zZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKEZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgLmFkZFJlcGVhdGVkU3RyaW5nKCJiYXIiKQorICAgICAgLmJ1aWxkKCk7CisKKyAgc3RhdGljIGZpbmFsIFRlc3RBbGxUeXBlcyBNRVJHRV9ERVNUID0KKyAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAuc2V0T3B0aW9uYWxJbnQ2NCgyKQorICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJiYXoiKQorICAgICAgLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMykuYnVpbGQoKSkKKyAgICAgIC5hZGRSZXBlYXRlZFN0cmluZygicXV4IikKKyAgICAgIC5idWlsZCgpOworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVSR0VfUkVTVUxUX1RFWFQgPQorICAgICAgIm9wdGlvbmFsX2ludDMyOiAxXG4iICsKKyAgICAgICJvcHRpb25hbF9pbnQ2NDogMlxuIiArCisgICAgICAib3B0aW9uYWxfc3RyaW5nOiBcImZvb1wiXG4iICsKKyAgICAgICJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2Uge1xuIiArCisgICAgICAiICBjOiAzXG4iICsKKyAgICAgICJ9XG4iICsKKyAgICAgICJyZXBlYXRlZF9zdHJpbmc6IFwicXV4XCJcbiIgKworICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJiYXJcIlxuIjsKKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQWJzdHJhY3RNZXNzYWdlV3JhcHBlciByZXN1bHQgPQorICAgICAgbmV3IEFic3RyYWN0TWVzc2FnZVdyYXBwZXIuQnVpbGRlcigKKyAgICAgICAgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoTUVSR0VfREVTVCkpCisgICAgICAubWVyZ2VGcm9tKE1FUkdFX1NPVVJDRSkuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscyhNRVJHRV9SRVNVTFRfVEVYVCwgcmVzdWx0LnRvU3RyaW5nKCkpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGVzdHMgZm9yIGVxdWFscyBhbmQgaGFzaENvZGUKKworICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzQW5kSGFzaENvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMgYSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIFRlc3RBbGxUeXBlcyBiID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5idWlsZCgpOworICAgIFRlc3RBbGxUeXBlcyBjID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoYikuYWRkUmVwZWF0ZWRTdHJpbmcoIngiKS5idWlsZCgpOworICAgIFRlc3RBbGxUeXBlcyBkID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoYykuYWRkUmVwZWF0ZWRTdHJpbmcoInkiKS5idWlsZCgpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIGUgPSBUZXN0VXRpbC5nZXRBbGxFeHRlbnNpb25zU2V0KCk7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgZiA9IFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoZSkKKyAgICAgICAgLmFkZEV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb24sIDk5OSkuYnVpbGQoKTsKKworICAgIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KGEpOworICAgIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KGIpOworICAgIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KGMpOworICAgIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KGQpOworICAgIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KGUpOworICAgIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KGYpOworCisgICAgY2hlY2tOb3RFcXVhbChhLCBiKTsKKyAgICBjaGVja05vdEVxdWFsKGEsIGMpOworICAgIGNoZWNrTm90RXF1YWwoYSwgZCk7CisgICAgY2hlY2tOb3RFcXVhbChhLCBlKTsKKyAgICBjaGVja05vdEVxdWFsKGEsIGYpOworCisgICAgY2hlY2tOb3RFcXVhbChiLCBjKTsKKyAgICBjaGVja05vdEVxdWFsKGIsIGQpOworICAgIGNoZWNrTm90RXF1YWwoYiwgZSk7CisgICAgY2hlY2tOb3RFcXVhbChiLCBmKTsKKworICAgIGNoZWNrTm90RXF1YWwoYywgZCk7CisgICAgY2hlY2tOb3RFcXVhbChjLCBlKTsKKyAgICBjaGVja05vdEVxdWFsKGMsIGYpOworCisgICAgY2hlY2tOb3RFcXVhbChkLCBlKTsKKyAgICBjaGVja05vdEVxdWFsKGQsIGYpOworCisgICAgY2hlY2tOb3RFcXVhbChlLCBmKTsKKworICAgIC8vIERlc2VyaWFsaXppbmcgaW50byB0aGUgVGVzdEVtcHR5TWVzc2FnZSBzdWNoIHRoYXQgZXZlcnkgZmllbGQKKyAgICAvLyBpcyBhbiB7QGxpbmsgVW5rbm93bkZpZWxkU2V0LkZpZWxkfS4KKyAgICBVbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UgZVVua25vd25GaWVsZHMgPQorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UucGFyc2VGcm9tKGUudG9CeXRlQXJyYXkoKSk7CisgICAgVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIGZVbmtub3duRmllbGRzID0KKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlLnBhcnNlRnJvbShmLnRvQnl0ZUFycmF5KCkpOworICAgIGNoZWNrTm90RXF1YWwoZVVua25vd25GaWVsZHMsIGZVbmtub3duRmllbGRzKTsKKyAgICBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChlVW5rbm93bkZpZWxkcyk7CisgICAgY2hlY2tFcXVhbHNJc0NvbnNpc3RlbnQoZlVua25vd25GaWVsZHMpOworCisgICAgLy8gU3Vic2VxdWVudCByZWNvbnN0aXR1dGlvbnMgc2hvdWxkIGJlIGlkZW50aWNhbAorICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSBlVW5rbm93bkZpZWxkczIgPQorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UucGFyc2VGcm9tKGUudG9CeXRlQXJyYXkoKSk7CisgICAgY2hlY2tFcXVhbHNJc0NvbnNpc3RlbnQoZVVua25vd25GaWVsZHMsIGVVbmtub3duRmllbGRzMik7CisgIH0KKworCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgdGhlIGdpdmVuIHByb3RvIGhhcyBzeW1tZXRyaWMgZXF1YWxzIGFuZCBoYXNoQ29kZSBtZXRob2RzLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGNoZWNrRXF1YWxzSXNDb25zaXN0ZW50KE1lc3NhZ2UgbWVzc2FnZSkgeworICAgIC8vIE9iamVjdCBzaG91bGQgYmUgZXF1YWwgdG8gaXRzZWxmLgorICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBtZXNzYWdlKTsKKworICAgIC8vIE9iamVjdCBzaG91bGQgYmUgZXF1YWwgdG8gYSBkeW5hbWljIGNvcHkgb2YgaXRzZWxmLgorICAgIER5bmFtaWNNZXNzYWdlIGR5bmFtaWMgPSBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKG1lc3NhZ2UpLmJ1aWxkKCk7CisgICAgY2hlY2tFcXVhbHNJc0NvbnNpc3RlbnQobWVzc2FnZSwgZHluYW1pYyk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBwcm90b3MgYXJlIGVxdWFsIGFuZCBoYXZlIHRoZSBzYW1lIGhhc2ggY29kZS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChNZXNzYWdlIG1lc3NhZ2UxLCBNZXNzYWdlIG1lc3NhZ2UyKSB7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UxLCBtZXNzYWdlMik7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UyLCBtZXNzYWdlMSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UyLmhhc2hDb2RlKCksIG1lc3NhZ2UxLmhhc2hDb2RlKCkpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gcHJvdG9zIGFyZSBub3QgZXF1YWwgYW5kIGhhdmUgZGlmZmVyZW50IGhhc2ggY29kZXMuCisgICAqCisgICAqIEB3YXJuaW5nIEl0J3MgdmFsaWQgZm9yIG5vbi1lcXVhbCBvYmplY3RzIHRvIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2RlLCBzbworICAgKiAgIHRoaXMgdGVzdCBpcyBzdHJpY3RlciB0aGFuIGl0IG5lZWRzIHRvIGJlLiBIb3dldmVyLCB0aGlzIHNob3VsZCBoYXBwZW4KKyAgICogICByZWxhdGl2ZWx5IHJhcmVseS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja05vdEVxdWFsKE1lc3NhZ2UgbTEsIE1lc3NhZ2UgbTIpIHsKKyAgICBTdHJpbmcgZXF1YWxzRXJyb3IgPSBTdHJpbmcuZm9ybWF0KCIlcyBzaG91bGQgbm90IGJlIGVxdWFsIHRvICVzIiwgbTEsIG0yKTsKKyAgICBhc3NlcnRGYWxzZShlcXVhbHNFcnJvciwgbTEuZXF1YWxzKG0yKSk7CisgICAgYXNzZXJ0RmFsc2UoZXF1YWxzRXJyb3IsIG0yLmVxdWFscyhtMSkpOworCisgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgIFN0cmluZy5mb3JtYXQoIiVzIHNob3VsZCBoYXZlIGEgZGlmZmVyZW50IGhhc2ggY29kZSBmcm9tICVzIiwgbTEsIG0yKSwKKyAgICAgICAgbTEuaGFzaENvZGUoKSA9PSBtMi5oYXNoQ29kZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDaGVja0J5dGVTdHJpbmdJc1V0ZjhPblV0ZjgoKSB7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoInNvbWUgdGV4dCIpOworICAgIEFic3RyYWN0TWVzc2FnZUxpdGUuY2hlY2tCeXRlU3RyaW5nSXNVdGY4KGJ5dGVTdHJpbmcpOworICAgIC8vIE5vIGV4Y2VwdGlvbiB0aHJvd24uCisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tCeXRlU3RyaW5nSXNVdGY4T25Ob25VdGY4KCkgeworICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9CisgICAgICAgIEJ5dGVTdHJpbmcuY29weUZyb20obmV3IGJ5dGVbXXsoYnl0ZSkgMHg4MH0pOyAvLyBBIGxvbmUgY29udGludWF0aW9uIGJ5dGUuCisgICAgdHJ5IHsKKyAgICAgIEFic3RyYWN0TWVzc2FnZUxpdGUuY2hlY2tCeXRlU3RyaW5nSXNVdGY4KGJ5dGVTdHJpbmcpOworICAgICAgZmFpbCgiRXhwZWN0ZWQgQWJzdHJhY3RNZXNzYWdlTGl0ZS5jaGVja0J5dGVTdHJpbmdJc1V0ZjggdG8gdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4Y2VwdGlvbikgeworICAgICAgYXNzZXJ0RXF1YWxzKCJCeXRlIHN0cmluZyBpcyBub3QgVVRGLTguIiwgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0JvdW5kZWRCeXRlU3RyaW5nVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQm91bmRlZEJ5dGVTdHJpbmdUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmM5NTk2YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0JvdW5kZWRCeXRlU3RyaW5nVGVzdC5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHRlc3RzIHtAbGluayBCb3VuZGVkQnl0ZVN0cmluZ30sIHdoaWNoIGV4dGVuZHMge0BsaW5rIExpdGVyYWxCeXRlU3RyaW5nfSwKKyAqIGJ5IGluaGVyaXRpbmcgdGhlIHRlc3RzIGZyb20ge0BsaW5rIExpdGVyYWxCeXRlU3RyaW5nVGVzdH0uICBUaGUgb25seSBtZXRob2Qgd2hpY2gKKyAqIGlzIHN0cmFuZ2UgZW5vdWdoIHRoYXQgaXQgbmVlZHMgdG8gYmUgb3ZlcnJpZGRlbiBoZXJlIGlzIHtAbGluayAjdGVzdFRvU3RyaW5nKCl9LgorICoKKyAqIEBhdXRob3IgY2FybGFudG9uQGdvb2dsZS5jb20gKENhcmwgSGF2ZXJsKQorICovCitwdWJsaWMgY2xhc3MgQm91bmRlZEJ5dGVTdHJpbmdUZXN0IGV4dGVuZHMgTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0IHsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjbGFzc1VuZGVyVGVzdCA9ICJCb3VuZGVkQnl0ZVN0cmluZyI7CisgICAgYnl0ZVtdIHNvdXJjZUJ5dGVzID0gQnl0ZVN0cmluZ1Rlc3QuZ2V0VGVzdEJ5dGVzKDIzNDEsIDExMzM3NzY2TCk7CisgICAgaW50IGZyb20gPSAxMDA7CisgICAgaW50IHRvID0gc291cmNlQnl0ZXMubGVuZ3RoIC0gMTAwOworICAgIHN0cmluZ1VuZGVyVGVzdCA9IEJ5dGVTdHJpbmcuY29weUZyb20oc291cmNlQnl0ZXMpLnN1YnN0cmluZyhmcm9tLCB0byk7CisgICAgcmVmZXJlbmNlQnl0ZXMgPSBuZXcgYnl0ZVt0byAtIGZyb21dOworICAgIFN5c3RlbS5hcnJheWNvcHkoc291cmNlQnl0ZXMsIGZyb20sIHJlZmVyZW5jZUJ5dGVzLCAwLCB0byAtIGZyb20pOworICAgIGV4cGVjdGVkSGFzaENvZGUgPSA3Mjc1NzU4ODc7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIkkgbG92ZSB1bmljb2RlIFx1MTIzNFx1NTY3OCBjaGFyYWN0ZXJzIjsKKyAgICBMaXRlcmFsQnl0ZVN0cmluZyB1bmljb2RlID0gbmV3IExpdGVyYWxCeXRlU3RyaW5nKHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICBCeXRlU3RyaW5nIGNob3BwZWQgPSB1bmljb2RlLnN1YnN0cmluZygyLCB1bmljb2RlLnNpemUoKSAtIDYpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIuc3Vic3RyaW5nKCkgbXVzdCBoYXZlIHRoZSBleHBlY3RlZCB0eXBlIiwKKyAgICAgICAgY2xhc3NVbmRlclRlc3QsIGdldEFjdHVhbENsYXNzTmFtZShjaG9wcGVkKSk7CisKKyAgICBTdHJpbmcgcm91bmRUcmlwU3RyaW5nID0gY2hvcHBlZC50b1N0cmluZyhVVEZfOCk7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIiB1bmljb2RlIGJ5dGVzIG11c3QgbWF0Y2giLAorICAgICAgICB0ZXN0U3RyaW5nLnN1YnN0cmluZygyLCB0ZXN0U3RyaW5nLmxlbmd0aCgpIC0gNiksIHJvdW5kVHJpcFN0cmluZyk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SmF2YVNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCk7CisgICAgb29zLndyaXRlT2JqZWN0KHN0cmluZ1VuZGVyVGVzdCk7CisgICAgb29zLmNsb3NlKCk7CisgICAgYnl0ZVtdIHBpY2tsZWQgPSBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShwaWNrbGVkKTsKKyAgICBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oaW4pOworICAgIE9iamVjdCBvID0gb2lzLnJlYWRPYmplY3QoKTsKKyAgICBhc3NlcnRUcnVlKCJEaWRuJ3QgZ2V0IGEgQnl0ZVN0cmluZyBiYWNrIiwgbyBpbnN0YW5jZW9mIEJ5dGVTdHJpbmcpOworICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGdldCBhbiBlcXVhbCBCeXRlU3RyaW5nIGJhY2siLCBzdHJpbmdVbmRlclRlc3QsIG8pOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9CeXRlU3RyaW5nVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQnl0ZVN0cmluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNWRlMTdjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQnl0ZVN0cmluZ1Rlc3QuamF2YQpAQCAtMCwwICsxLDc1OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5PdXRwdXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKKy8qKgorICogVGVzdCBtZXRob2RzIHdpdGggaW1wbGVtZW50YXRpb25zIGluIHtAbGluayBCeXRlU3RyaW5nfSwgcGx1cyBkbyBzb21lIHRvcC1sZXZlbCAiaW50ZWdyYXRpb24iCisgKiB0ZXN0cy4KKyAqCisgKiBAYXV0aG9yIGNhcmxhbnRvbkBnb29nbGUuY29tIChDYXJsIEhhdmVybCkKKyAqLworcHVibGljIGNsYXNzIEJ5dGVTdHJpbmdUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBVVEZfMTYgPSAiVVRGLTE2IjsKKworICBzdGF0aWMgYnl0ZVtdIGdldFRlc3RCeXRlcyhpbnQgc2l6ZSwgbG9uZyBzZWVkKSB7CisgICAgUmFuZG9tIHJhbmRvbSA9IG5ldyBSYW5kb20oc2VlZCk7CisgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3NpemVdOworICAgIHJhbmRvbS5uZXh0Qnl0ZXMocmVzdWx0KTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgcHJpdmF0ZSBieXRlW10gZ2V0VGVzdEJ5dGVzKGludCBzaXplKSB7CisgICAgcmV0dXJuIGdldFRlc3RCeXRlcyhzaXplLCA0NDU1NjZMKTsKKyAgfQorCisgIHByaXZhdGUgYnl0ZVtdIGdldFRlc3RCeXRlcygpIHsKKyAgICByZXR1cm4gZ2V0VGVzdEJ5dGVzKDEwMDApOworICB9CisKKyAgLy8gQ29tcGFyZSB0aGUgZW50aXJlIGxlZnQgYXJyYXkgd2l0aCBhIHN1YnNldCBvZiB0aGUgcmlnaHQgYXJyYXkuCisgIHByaXZhdGUgYm9vbGVhbiBpc0FycmF5UmFuZ2UoYnl0ZVtdIGxlZnQsIGJ5dGVbXSByaWdodCwgaW50IHJpZ2h0T2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgYm9vbGVhbiBzdGlsbEVxdWFsID0gKGxlZnQubGVuZ3RoID09IGxlbmd0aCk7CisgICAgZm9yIChpbnQgaSA9IDA7IChzdGlsbEVxdWFsICYmIGkgPCBsZW5ndGgpOyArK2kpIHsKKyAgICAgIHN0aWxsRXF1YWwgPSAobGVmdFtpXSA9PSByaWdodFtyaWdodE9mZnNldCArIGldKTsKKyAgICB9CisgICAgcmV0dXJuIHN0aWxsRXF1YWw7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgb25seSBpZiB0aGUgZ2l2ZW4gdHdvIGFycmF5cyBoYXZlIGlkZW50aWNhbCBjb250ZW50cy4KKyAgcHJpdmF0ZSBib29sZWFuIGlzQXJyYXkoYnl0ZVtdIGxlZnQsIGJ5dGVbXSByaWdodCkgeworICAgIHJldHVybiBsZWZ0Lmxlbmd0aCA9PSByaWdodC5sZW5ndGggJiYgaXNBcnJheVJhbmdlKGxlZnQsIHJpZ2h0LCAwLCBsZWZ0Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U3Vic3RyaW5nX0JlZ2luSW5kZXgoKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gZ2V0VGVzdEJ5dGVzKCk7CisgICAgQnl0ZVN0cmluZyBzdWJzdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzKS5zdWJzdHJpbmcoNTAwKTsKKyAgICBhc3NlcnRUcnVlKCJzdWJzdHJpbmcgbXVzdCBjb250YWluIHRoZSB0YWlsIG9mIHRoZSBzdHJpbmciLAorICAgICAgICBpc0FycmF5UmFuZ2Uoc3Vic3RyaW5nLnRvQnl0ZUFycmF5KCksIGJ5dGVzLCA1MDAsIGJ5dGVzLmxlbmd0aCAtIDUwMCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENvcHlGcm9tX0J5dGVzT2Zmc2V0U2l6ZSgpIHsKKyAgICBieXRlW10gYnl0ZXMgPSBnZXRUZXN0Qnl0ZXMoKTsKKyAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzLCA1MDAsIDIwMCk7CisgICAgYXNzZXJ0VHJ1ZSgiY29weUZyb20gc3ViLXJhbmdlIG11c3QgY29udGFpbiB0aGUgZXhwZWN0ZWQgYnl0ZXMiLAorICAgICAgICBpc0FycmF5UmFuZ2UoYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCBieXRlcywgNTAwLCAyMDApKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5RnJvbV9CeXRlcygpIHsKKyAgICBieXRlW10gYnl0ZXMgPSBnZXRUZXN0Qnl0ZXMoKTsKKyAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzKTsKKyAgICBhc3NlcnRUcnVlKCJjb3B5RnJvbSBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgaXNBcnJheShieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksIGJ5dGVzKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29weUZyb21fQnl0ZUJ1ZmZlclNpemUoKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gZ2V0VGVzdEJ5dGVzKCk7CisgICAgQnl0ZUJ1ZmZlciBieXRlQnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShieXRlcy5sZW5ndGgpOworICAgIGJ5dGVCdWZmZXIucHV0KGJ5dGVzKTsKKyAgICBieXRlQnVmZmVyLnBvc2l0aW9uKDUwMCk7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbShieXRlQnVmZmVyLCAyMDApOworICAgIGFzc2VydFRydWUoImNvcHlGcm9tIGJ5dGVCdWZmZXIgc3ViLXJhbmdlIG11c3QgY29udGFpbiB0aGUgZXhwZWN0ZWQgYnl0ZXMiLAorICAgICAgICBpc0FycmF5UmFuZ2UoYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCBieXRlcywgNTAwLCAyMDApKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5RnJvbV9CeXRlQnVmZmVyKCkgeworICAgIGJ5dGVbXSBieXRlcyA9IGdldFRlc3RCeXRlcygpOworICAgIEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoYnl0ZXMubGVuZ3RoKTsKKyAgICBieXRlQnVmZmVyLnB1dChieXRlcyk7CisgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbig1MDApOworICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9IEJ5dGVTdHJpbmcuY29weUZyb20oYnl0ZUJ1ZmZlcik7CisgICAgYXNzZXJ0VHJ1ZSgiY29weUZyb20gYnl0ZUJ1ZmZlciBzdWItcmFuZ2UgbXVzdCBjb250YWluIHRoZSBleHBlY3RlZCBieXRlcyIsCisgICAgICAgIGlzQXJyYXlSYW5nZShieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksIGJ5dGVzLCA1MDAsIGJ5dGVzLmxlbmd0aCAtIDUwMCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENvcHlGcm9tX1N0cmluZ0VuY29kaW5nKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIkkgbG92ZSB1bmljb2RlIFx1MTIzNFx1NTY3OCBjaGFyYWN0ZXJzIjsKKyAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKHRlc3RTdHJpbmcsIFVURl8xNik7CisgICAgYnl0ZVtdIHRlc3RCeXRlcyA9IHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoVVRGXzE2KTsKKyAgICBhc3NlcnRUcnVlKCJjb3B5RnJvbSBzdHJpbmcgbXVzdCByZXNwZWN0IHRoZSBjaGFyc2V0IiwKKyAgICAgICAgaXNBcnJheVJhbmdlKGJ5dGVTdHJpbmcudG9CeXRlQXJyYXkoKSwgdGVzdEJ5dGVzLCAwLCB0ZXN0Qnl0ZXMubGVuZ3RoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29weUZyb21fVXRmOCgpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJJIGxvdmUgdW5pY29kZSBcdTEyMzRcdTU2NzggY2hhcmFjdGVycyI7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgodGVzdFN0cmluZyk7CisgICAgYnl0ZVtdIHRlc3RCeXRlcyA9IHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoIlVURi04Iik7CisgICAgYXNzZXJ0VHJ1ZSgiY29weUZyb21VdGY4IHN0cmluZyBtdXN0IHJlc3BlY3QgdGhlIGNoYXJzZXQiLAorICAgICAgICBpc0FycmF5UmFuZ2UoYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCB0ZXN0Qnl0ZXMsIDAsIHRlc3RCeXRlcy5sZW5ndGgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5RnJvbV9JdGVyYWJsZSgpIHsKKyAgICBieXRlW10gdGVzdEJ5dGVzID0gZ2V0VGVzdEJ5dGVzKDc3Nzc3LCAxMTMzNDRMKTsKKyAgICBmaW5hbCBMaXN0PEJ5dGVTdHJpbmc+IHBpZWNlcyA9IG1ha2VDb25jcmV0ZVBpZWNlcyh0ZXN0Qnl0ZXMpOworICAgIC8vIENhbGwgY29weUZyb20oKSBvbiBhIENvbGxlY3Rpb24KKyAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKHBpZWNlcyk7CisgICAgYXNzZXJ0VHJ1ZSgiY29weUZyb20gYSBMaXN0IG11c3QgY29udGFpbiB0aGUgZXhwZWN0ZWQgYnl0ZXMiLAorICAgICAgICBpc0FycmF5UmFuZ2UoYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCB0ZXN0Qnl0ZXMsIDAsIHRlc3RCeXRlcy5sZW5ndGgpKTsKKyAgICAvLyBDYWxsIGNvcHlGcm9tIG9uIGFuIGl0ZXJhdGlvbiB0aGF0J3Mgbm90IGEgY29sbGVjdGlvbgorICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZ0FsdCA9IEJ5dGVTdHJpbmcuY29weUZyb20obmV3IEl0ZXJhYmxlPEJ5dGVTdHJpbmc+KCkgeworICAgICAgcHVibGljIEl0ZXJhdG9yPEJ5dGVTdHJpbmc+IGl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gcGllY2VzLml0ZXJhdG9yKCk7CisgICAgICB9CisgICAgfSk7CisgICAgYXNzZXJ0RXF1YWxzKCJjb3B5RnJvbSBmcm9tIGFuIEl0ZXJhdGlvbiBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgYnl0ZVN0cmluZywgYnl0ZVN0cmluZ0FsdCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29weVRvX1RhcmdldE9mZnNldCgpIHsKKyAgICBieXRlW10gYnl0ZXMgPSBnZXRUZXN0Qnl0ZXMoKTsKKyAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzKTsKKyAgICBieXRlW10gdGFyZ2V0ID0gbmV3IGJ5dGVbYnl0ZXMubGVuZ3RoICsgMTAwMF07CisgICAgYnl0ZVN0cmluZy5jb3B5VG8odGFyZ2V0LCA0MDApOworICAgIGFzc2VydFRydWUoImNvcHlGcm9tIGJ5dGVCdWZmZXIgc3ViLXJhbmdlIG11c3QgY29udGFpbiB0aGUgZXhwZWN0ZWQgYnl0ZXMiLAorICAgICAgICBpc0FycmF5UmFuZ2UoYnl0ZXMsIHRhcmdldCwgNDAwLCBieXRlcy5sZW5ndGgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkRnJvbV9lbXB0eVN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0KKyAgICAgICAgQnl0ZVN0cmluZy5yZWFkRnJvbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pKTsKKyAgICBhc3NlcnRTYW1lKCJyZWFkaW5nIGFuIGVtcHR5IHN0cmVhbSBtdXN0IHJlc3VsdCBpbiB0aGUgRU1QVFkgY29uc3RhbnQgIgorICAgICAgICArICJieXRlIHN0cmluZyIsIEJ5dGVTdHJpbmcuRU1QVFksIGJ5dGVTdHJpbmcpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlYWRGcm9tX3NtYWxsU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMoMTApKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkRnJvbV9tdXRhdGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGNhcHR1cmVkQXJyYXkgPSBudWxsOworICAgIEV2aWxJbnB1dFN0cmVhbSBlaXMgPSBuZXcgRXZpbElucHV0U3RyZWFtKCk7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gQnl0ZVN0cmluZy5yZWFkRnJvbShlaXMpOworCisgICAgY2FwdHVyZWRBcnJheSA9IGVpcy5jYXB0dXJlZEFycmF5OworICAgIGJ5dGVbXSBvcmlnaW5hbFZhbHVlID0gYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpOworICAgIGZvciAoaW50IHggPSAwOyB4IDwgY2FwdHVyZWRBcnJheS5sZW5ndGg7ICsreCkgeworICAgICAgY2FwdHVyZWRBcnJheVt4XSA9IChieXRlKSAwOworICAgIH0KKworICAgIGJ5dGVbXSBuZXdWYWx1ZSA9IGJ5dGVTdHJpbmcudG9CeXRlQXJyYXkoKTsKKyAgICBhc3NlcnRUcnVlKCJjb3B5RnJvbSBieXRlQnVmZmVyIG11c3Qgbm90IGdyYW50IGFjY2VzcyB0byB1bmRlcmx5aW5nIGFycmF5IiwKKyAgICAgICAgQXJyYXlzLmVxdWFscyhvcmlnaW5hbFZhbHVlLCBuZXdWYWx1ZSkpOworICB9CisKKyAgLy8gVGVzdHMgc2l6ZXMgdGhhdCBhcmUgbmVhciB0aGUgcm9wZSBjb3B5LW91dCB0aHJlc2hvbGQuCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkRnJvbV9tZWRpdW1TdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhCeXRlU3RyaW5nLkNPTkNBVEVOQVRFX0JZX0NPUFlfU0laRSAtIDEpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMoQnl0ZVN0cmluZy5DT05DQVRFTkFURV9CWV9DT1BZX1NJWkUpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMoQnl0ZVN0cmluZy5DT05DQVRFTkFURV9CWV9DT1BZX1NJWkUgKyAxKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKDIwMCkpOworICB9CisKKyAgLy8gVGVzdHMgc2l6ZXMgdGhhdCBhcmUgb3ZlciBtdWx0aS1zZWdtZW50IHJvcGUgdGhyZXNob2xkLgorICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEZyb21fbGFyZ2VTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcygweDEwMCkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcygweDEwMSkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcygweDExMCkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcygweDEwMDApKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMoMHgxMDAxKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKDB4MTAxMCkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcygweDEwMDAwKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKDB4MTAwMDEpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMoMHgxMDAxMCkpOworICB9CisKKyAgLy8gVGVzdHMgc2l6ZXMgdGhhdCBhcmUgbmVhciB0aGUgcmVhZCBidWZmZXIgc2l6ZS4KKyAgcHVibGljIHZvaWQgdGVzdFJlYWRGcm9tX2J5dGVCb3VuZGFyaWVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgbWluID0gQnl0ZVN0cmluZy5NSU5fUkVBRF9GUk9NX0NIVU5LX1NJWkU7CisgICAgZmluYWwgaW50IG1heCA9IEJ5dGVTdHJpbmcuTUFYX1JFQURfRlJPTV9DSFVOS19TSVpFOworCisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKG1pbiAtIDEpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMobWluKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKG1pbiArIDEpKTsKKworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhtaW4gKiAyIC0gMSkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhtaW4gKiAyKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKG1pbiAqIDIgKyAxKSk7CisKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMobWluICogNCAtIDEpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMobWluICogNCkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhtaW4gKiA0ICsgMSkpOworCisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKG1pbiAqIDggLSAxKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKG1pbiAqIDgpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMobWluICogOCArIDEpKTsKKworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhtYXggLSAxKSk7CisgICAgYXNzZXJ0UmVhZEZyb20oZ2V0VGVzdEJ5dGVzKG1heCkpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhtYXggKyAxKSk7CisKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMobWF4ICogMiAtIDEpKTsKKyAgICBhc3NlcnRSZWFkRnJvbShnZXRUZXN0Qnl0ZXMobWF4ICogMikpOworICAgIGFzc2VydFJlYWRGcm9tKGdldFRlc3RCeXRlcyhtYXggKiAyICsgMSkpOworICB9CisKKyAgLy8gVGVzdHMgdGhhdCBJT0V4Y2VwdGlvbnMgcHJvcGFnYXRlIHRocm91Z2ggQnl0ZVN0cmluZy5yZWFkRnJvbSgpLgorICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEZyb21fSU9FeGNlcHRpb25zKCkgeworICAgIHRyeSB7CisgICAgICBCeXRlU3RyaW5nLnJlYWRGcm9tKG5ldyBGYWlsU3RyZWFtKCkpOworICAgICAgZmFpbCgicmVhZEZyb20gbXVzdCB0aHJvdyB0aGUgdW5kZXJseWluZyBJT0V4Y2VwdGlvbiIpOworCisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgYXNzZXJ0RXF1YWxzKCJyZWFkRnJvbSBtdXN0IHRocm93IHRoZSBleHBlY3RlZCBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICJzeW50aGV0aWMgZmFpbHVyZSIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICAvLyBUZXN0cyB0aGF0IEJ5dGVTdHJpbmcucmVhZEZyb20gd29ya3Mgd2l0aCBzdHJlYW1zIHRoYXQgZG9uJ3QKKyAgLy8gYWx3YXlzIGZpbGwgdGhlaXIgYnVmZmVycy4KKyAgcHVibGljIHZvaWQgdGVzdFJlYWRGcm9tX3JlbHVjdGFudFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBnZXRUZXN0Qnl0ZXMoMHgxMDAwKTsKKworICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9IEJ5dGVTdHJpbmcucmVhZEZyb20obmV3IFJlbHVjdGFudFN0cmVhbShkYXRhKSk7CisgICAgYXNzZXJ0VHJ1ZSgicmVhZEZyb20gYnl0ZSBzdHJlYW0gbXVzdCBjb250YWluIHRoZSBleHBlY3RlZCBieXRlcyIsCisgICAgICAgIGlzQXJyYXkoYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCBkYXRhKSk7CisKKyAgICAvLyBTYW1lIHRlc3QgYXMgYWJvdmUsIGJ1dCB3aXRoIHNvbWUgc3BlY2lmaWMgY2h1bmsgc2l6ZXMuCisgICAgYXNzZXJ0UmVhZEZyb21SZWx1Y3RhbnRTdHJlYW0oZGF0YSwgMTAwKTsKKyAgICBhc3NlcnRSZWFkRnJvbVJlbHVjdGFudFN0cmVhbShkYXRhLCAyNDgpOworICAgIGFzc2VydFJlYWRGcm9tUmVsdWN0YW50U3RyZWFtKGRhdGEsIDI0OSk7CisgICAgYXNzZXJ0UmVhZEZyb21SZWx1Y3RhbnRTdHJlYW0oZGF0YSwgMjUwKTsKKyAgICBhc3NlcnRSZWFkRnJvbVJlbHVjdGFudFN0cmVhbShkYXRhLCAyNTEpOworICAgIGFzc2VydFJlYWRGcm9tUmVsdWN0YW50U3RyZWFtKGRhdGEsIDB4MTAwMCk7CisgICAgYXNzZXJ0UmVhZEZyb21SZWx1Y3RhbnRTdHJlYW0oZGF0YSwgMHgxMDAxKTsKKyAgfQorCisgIC8vIEZhaWxzIHVubGVzcyBCeXRlU3RyaW5nLnJlYWRGcm9tIHJlYWRzIHRoZSBieXRlcyBjb3JyZWN0bHkgZnJvbSBhCisgIC8vIHJlbHVjdGFudCBzdHJlYW0gd2l0aCB0aGUgZ2l2ZW4gY2h1bmtTaXplIHBhcmFtZXRlci4KKyAgcHJpdmF0ZSB2b2lkIGFzc2VydFJlYWRGcm9tUmVsdWN0YW50U3RyZWFtKGJ5dGVbXSBieXRlcywgaW50IGNodW5rU2l6ZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZyBiID0gQnl0ZVN0cmluZy5yZWFkRnJvbShuZXcgUmVsdWN0YW50U3RyZWFtKGJ5dGVzKSwgY2h1bmtTaXplKTsKKyAgICBhc3NlcnRUcnVlKCJyZWFkRnJvbSBieXRlIHN0cmVhbSBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgaXNBcnJheShiLnRvQnl0ZUFycmF5KCksIGJ5dGVzKSk7CisgIH0KKworICAvLyBUZXN0cyB0aGF0IEJ5dGVTdHJpbmcucmVhZEZyb20gd29ya3Mgd2l0aCBzdHJlYW1zIHRoYXQgaW1wbGVtZW50CisgIC8vIGF2YWlsYWJsZSgpLgorICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEZyb21fYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBieXRlW10gZGF0YSA9IGdldFRlc3RCeXRlcygweDEwMDEpOworCisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gQnl0ZVN0cmluZy5yZWFkRnJvbShuZXcgQXZhaWxhYmxlU3RyZWFtKGRhdGEpKTsKKyAgICBhc3NlcnRUcnVlKCJyZWFkRnJvbSBieXRlIHN0cmVhbSBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgaXNBcnJheShieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksIGRhdGEpKTsKKyAgfQorCisgIC8vIEZhaWxzIHVubGVzcyBCeXRlU3RyaW5nLnJlYWRGcm9tIHJlYWRzIHRoZSBieXRlcyBjb3JyZWN0bHkuCisgIHByaXZhdGUgdm9pZCBhc3NlcnRSZWFkRnJvbShieXRlW10gYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0KKyAgICAgICAgQnl0ZVN0cmluZy5yZWFkRnJvbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMpKTsKKyAgICBhc3NlcnRUcnVlKCJyZWFkRnJvbSBieXRlIHN0cmVhbSBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgaXNBcnJheShieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksIGJ5dGVzKSk7CisgIH0KKworICAvLyBBIHN0cmVhbSB0aGF0IGZhaWxzIHdoZW4gcmVhZC4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmFpbFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic3ludGhldGljIGZhaWx1cmUiKTsKKyAgICB9CisgIH0KKworICAvLyBBIHN0cmVhbSB0aGF0IHNpbXVsYXRlcyBibG9ja2luZyBieSBvbmx5IHByb2R1Y2luZyAyNTAgY2hhcmFjdGVycworICAvLyBwZXIgY2FsbCB0byByZWFkKGJ5dGVbXSkuCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFJlbHVjdGFudFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKyAgICBwcm90ZWN0ZWQgZmluYWwgYnl0ZVtdIGRhdGE7CisgICAgcHJvdGVjdGVkIGludCBwb3MgPSAwOworCisgICAgcHVibGljIFJlbHVjdGFudFN0cmVhbShieXRlW10gZGF0YSkgeworICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKCkgeworICAgICAgaWYgKHBvcyA9PSBkYXRhLmxlbmd0aCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZGF0YVtwb3MrK107CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmKSB7CisgICAgICByZXR1cm4gcmVhZChidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IHNpemUpIHsKKyAgICAgIGlmIChwb3MgPT0gZGF0YS5sZW5ndGgpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgaW50IGNvdW50ID0gTWF0aC5taW4oTWF0aC5taW4oc2l6ZSwgZGF0YS5sZW5ndGggLSBwb3MpLCAyNTApOworICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBwb3MsIGJ1Ziwgb2Zmc2V0LCBjb3VudCk7CisgICAgICBwb3MgKz0gY291bnQ7CisgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorICB9CisKKyAgLy8gU2FtZSBhcyBhYm92ZSwgYnV0IGFsc28gaW1wbGVtZW50cyBhdmFpbGFibGUoKS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQXZhaWxhYmxlU3RyZWFtIGV4dGVuZHMgUmVsdWN0YW50U3RyZWFtIHsKKyAgICBwdWJsaWMgQXZhaWxhYmxlU3RyZWFtKGJ5dGVbXSBkYXRhKSB7CisgICAgICBzdXBlcihkYXRhKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBhdmFpbGFibGUoKSB7CisgICAgICByZXR1cm4gTWF0aC5taW4oMjUwLCBkYXRhLmxlbmd0aCAtIHBvcyk7CisgICAgfQorICB9CisKKyAgLy8gQSBzdHJlYW0gd2hpY2ggZXhwb3NlcyB0aGUgYnl0ZSBhcnJheSBwYXNzZWQgaW50byByZWFkKGJ5dGVbXSwgaW50LCBpbnQpLgorICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFdmlsSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisgICAgcHVibGljIGJ5dGVbXSBjYXB0dXJlZEFycmF5ID0gbnVsbDsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICBpZiAoY2FwdHVyZWRBcnJheSAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNhcHR1cmVkQXJyYXkgPSBidWY7CisgICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgbGVuOyArK3gpIHsKKyAgICAgICAgICBidWZbeF0gPSAoYnl0ZSkgeDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGVuOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHsKKyAgICAgIC8vIFB1cnBvc2VmdWxseSBkbyBub3RoaW5nLgorICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgfQorICAKKyAgLy8gQSBzdHJlYW0gd2hpY2ggZXhwb3NlcyB0aGUgYnl0ZSBhcnJheSBwYXNzZWQgaW50byB3cml0ZShieXRlW10sIGludCwgaW50KS4KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRXZpbE91dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisgICAgcHVibGljIGJ5dGVbXSBjYXB0dXJlZEFycmF5ID0gbnVsbDsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgIGlmIChjYXB0dXJlZEFycmF5ID09IG51bGwpIHsKKyAgICAgICAgY2FwdHVyZWRBcnJheSA9IGJ1ZjsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgaWdub3JlZCkgeworICAgICAgLy8gUHVycG9zZWZ1bGx5IGRvIG5vdGhpbmcuCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nVXRmOCgpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJJIGxvdmUgdW5pY29kZSBcdTEyMzRcdTU2NzggY2hhcmFjdGVycyI7CisgICAgYnl0ZVtdIHRlc3RCeXRlcyA9IHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoIlVURi04Iik7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbSh0ZXN0Qnl0ZXMpOworICAgIGFzc2VydEVxdWFscygiY29weVRvU3RyaW5nVXRmOCBtdXN0IHJlc3BlY3QgdGhlIGNoYXJzZXQiLAorICAgICAgICB0ZXN0U3RyaW5nLCBieXRlU3RyaW5nLnRvU3RyaW5nVXRmOCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXdPdXRwdXRfSW5pdGlhbENhcGFjaXR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBieXRlW10gYnl0ZXMgPSBnZXRUZXN0Qnl0ZXMoKTsKKyAgICBCeXRlU3RyaW5nLk91dHB1dCBvdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dChieXRlcy5sZW5ndGggKyAxMDApOworICAgIG91dHB1dC53cml0ZShieXRlcyk7CisgICAgQnl0ZVN0cmluZyBieXRlU3RyaW5nID0gb3V0cHV0LnRvQnl0ZVN0cmluZygpOworICAgIGFzc2VydFRydWUoCisgICAgICAgICJTdHJpbmcgYnVpbHQgZnJvbSBuZXdPdXRwdXQoaW50KSBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgaXNBcnJheVJhbmdlKGJ5dGVzLCBieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksIDAsIGJ5dGVzLmxlbmd0aCkpOworICB9CisKKyAgLy8gVGVzdCBuZXdPdXRwdXQoKSB1c2luZyBhIHZhcmlldHkgb2YgYnVmZmVyIHNpemVzIGFuZCBhIHZhcmlldHkgb2YgKGZpeGVkKQorICAvLyB3cml0ZSBzaXplcworICBwdWJsaWMgdm9pZCB0ZXN0TmV3T3V0cHV0X0FycmF5V3JpdGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGVbXSBieXRlcyA9IGdldFRlc3RCeXRlcygpOworICAgIGludCBsZW5ndGggPSBieXRlcy5sZW5ndGg7CisgICAgaW50W10gYnVmZmVyU2l6ZXMgPSB7MTI4LCAyNTYsIGxlbmd0aCAvIDIsIGxlbmd0aCAtIDEsIGxlbmd0aCwgbGVuZ3RoICsgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAyICogbGVuZ3RoLCAzICogbGVuZ3RofTsKKyAgICBpbnRbXSB3cml0ZVNpemVzID0gezEsIDQsIDUsIDcsIDIzLCBieXRlcy5sZW5ndGh9OworCisgICAgZm9yIChpbnQgYnVmZmVyU2l6ZSA6IGJ1ZmZlclNpemVzKSB7CisgICAgICBmb3IgKGludCB3cml0ZVNpemUgOiB3cml0ZVNpemVzKSB7CisgICAgICAgIC8vIFRlc3Qgd3JpdGluZyB0aGUgZW50aXJlIG91dHB1dCB3cml0ZVNpemUgYnl0ZXMgYXQgYSB0aW1lLgorICAgICAgICBCeXRlU3RyaW5nLk91dHB1dCBvdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dChidWZmZXJTaXplKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gd3JpdGVTaXplKSB7CisgICAgICAgICAgb3V0cHV0LndyaXRlKGJ5dGVzLCBpLCBNYXRoLm1pbih3cml0ZVNpemUsIGxlbmd0aCAtIGkpKTsKKyAgICAgICAgfQorICAgICAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBvdXRwdXQudG9CeXRlU3RyaW5nKCk7CisgICAgICAgIGFzc2VydFRydWUoIlN0cmluZyBidWlsdCBmcm9tIG5ld091dHB1dCgpIG11c3QgY29udGFpbiB0aGUgZXhwZWN0ZWQgYnl0ZXMiLAorICAgICAgICAgICAgaXNBcnJheVJhbmdlKGJ5dGVzLCBieXRlU3RyaW5nLnRvQnl0ZUFycmF5KCksIDAsIGJ5dGVzLmxlbmd0aCkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFRlc3QgbmV3T3V0cHV0KCkgdXNpbmcgYSB2YXJpZXR5IG9mIGJ1ZmZlciBzaXplcywgYnV0IHdyaXRpbmcgYWxsIHRoZQorICAvLyBjaGFyYWN0ZXJzIHVzaW5nIHdyaXRlKGJ5dGUpOworICBwdWJsaWMgdm9pZCB0ZXN0TmV3T3V0cHV0X1dyaXRlQ2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGJ5dGVzID0gZ2V0VGVzdEJ5dGVzKCk7CisgICAgaW50IGxlbmd0aCA9IGJ5dGVzLmxlbmd0aDsKKyAgICBpbnRbXSBidWZmZXJTaXplcyA9IHswLCAxLCAxMjgsIDI1NiwgbGVuZ3RoIC8gMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggLSAxLCBsZW5ndGgsIGxlbmd0aCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgMiAqIGxlbmd0aCwgMyAqIGxlbmd0aH07CisgICAgZm9yIChpbnQgYnVmZmVyU2l6ZSA6IGJ1ZmZlclNpemVzKSB7CisgICAgICBCeXRlU3RyaW5nLk91dHB1dCBvdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dChidWZmZXJTaXplKTsKKyAgICAgIGZvciAoYnl0ZSBieXRlVmFsdWUgOiBieXRlcykgeworICAgICAgICBvdXRwdXQud3JpdGUoYnl0ZVZhbHVlKTsKKyAgICAgIH0KKyAgICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9IG91dHB1dC50b0J5dGVTdHJpbmcoKTsKKyAgICAgIGFzc2VydFRydWUoIlN0cmluZyBidWlsdCBmcm9tIG5ld091dHB1dCgpIG11c3QgY29udGFpbiB0aGUgZXhwZWN0ZWQgYnl0ZXMiLAorICAgICAgICAgIGlzQXJyYXlSYW5nZShieXRlcywgYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCAwLCBieXRlcy5sZW5ndGgpKTsKKyAgICB9CisgIH0KKworICAvLyBUZXN0IG5ld091dHB1dCgpIGluIHdoaWNoIHdlIHdyaXRlIHRoZSBieXRlcyB1c2luZyBhIHZhcmlldHkgb2YgbWV0aG9kcworICAvLyBhbmQgc2l6ZXMsIGFuZCBpbiB3aGljaCB3ZSByZXBlYXRlZGx5IGNhbGwgdG9CeXRlU3RyaW5nKCkgaW4gdGhlIG1pZGRsZS4KKyAgcHVibGljIHZvaWQgdGVzdE5ld091dHB1dF9NaXhlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUmFuZG9tIHJuZyA9IG5ldyBSYW5kb20oMSk7CisgICAgYnl0ZVtdIGJ5dGVzID0gZ2V0VGVzdEJ5dGVzKCk7CisgICAgaW50IGxlbmd0aCA9IGJ5dGVzLmxlbmd0aDsKKyAgICBpbnRbXSBidWZmZXJTaXplcyA9IHswLCAxLCAxMjgsIDI1NiwgbGVuZ3RoIC8gMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggLSAxLCBsZW5ndGgsIGxlbmd0aCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgMiAqIGxlbmd0aCwgMyAqIGxlbmd0aH07CisKKyAgICBmb3IgKGludCBidWZmZXJTaXplIDogYnVmZmVyU2l6ZXMpIHsKKyAgICAgIC8vIFRlc3Qgd3JpdGluZyB0aGUgZW50aXJlIG91dHB1dCB1c2luZyBhIG1peHR1cmUgb2Ygd3JpdGUgc2l6ZXMgYW5kCisgICAgICAvLyBtZXRob2RzOworICAgICAgQnl0ZVN0cmluZy5PdXRwdXQgb3V0cHV0ID0gQnl0ZVN0cmluZy5uZXdPdXRwdXQoYnVmZmVyU2l6ZSk7CisgICAgICBpbnQgcG9zaXRpb24gPSAwOworICAgICAgd2hpbGUgKHBvc2l0aW9uIDwgYnl0ZXMubGVuZ3RoKSB7CisgICAgICAgIGlmIChybmcubmV4dEJvb2xlYW4oKSkgeworICAgICAgICAgIGludCBjb3VudCA9IDEgKyBybmcubmV4dEludChieXRlcy5sZW5ndGggLSBwb3NpdGlvbik7CisgICAgICAgICAgb3V0cHV0LndyaXRlKGJ5dGVzLCBwb3NpdGlvbiwgY291bnQpOworICAgICAgICAgIHBvc2l0aW9uICs9IGNvdW50OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIG91dHB1dC53cml0ZShieXRlc1twb3NpdGlvbl0pOworICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaXplKCkgcmV0dXJucyB0aGUgcmlnaHQgdmFsdWUiLCBwb3NpdGlvbiwgb3V0cHV0LnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIm5ld091dHB1dCgpIHN1YnN0cmluZyBtdXN0IGhhdmUgY29ycmVjdCBieXRlcyIsCisgICAgICAgICAgICBpc0FycmF5UmFuZ2Uob3V0cHV0LnRvQnl0ZVN0cmluZygpLnRvQnl0ZUFycmF5KCksCisgICAgICAgICAgICAgICAgYnl0ZXMsIDAsIHBvc2l0aW9uKSk7CisgICAgICB9CisgICAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBvdXRwdXQudG9CeXRlU3RyaW5nKCk7CisgICAgICBhc3NlcnRUcnVlKCJTdHJpbmcgYnVpbHQgZnJvbSBuZXdPdXRwdXQoKSBtdXN0IGNvbnRhaW4gdGhlIGV4cGVjdGVkIGJ5dGVzIiwKKyAgICAgICAgICBpc0FycmF5UmFuZ2UoYnl0ZXMsIGJ5dGVTdHJpbmcudG9CeXRlQXJyYXkoKSwgMCwgYnl0ZXMubGVuZ3RoKSk7CisgICAgfQorICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0TmV3T3V0cHV0RW1wdHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIE1ha2Ugc3VyZSBuZXdPdXRwdXQoKSBjb3JyZWN0bHkgYnVpbGRzIGVtcHR5IGJ5dGUgc3RyaW5ncworICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9IEJ5dGVTdHJpbmcubmV3T3V0cHV0KCkudG9CeXRlU3RyaW5nKCk7CisgICAgYXNzZXJ0RXF1YWxzKEJ5dGVTdHJpbmcuRU1QVFksIGJ5dGVTdHJpbmcpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0TmV3T3V0cHV0X011dGF0aW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBPdXRwdXQgb3MgPSBCeXRlU3RyaW5nLm5ld091dHB1dCg1KTsKKyAgICBvcy53cml0ZShuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fSk7CisgICAgRXZpbE91dHB1dFN0cmVhbSBlb3MgPSBuZXcgRXZpbE91dHB1dFN0cmVhbSgpOworICAgIG9zLndyaXRlVG8oZW9zKTsKKyAgICBieXRlW10gY2FwdHVyZWRBcnJheSA9IGVvcy5jYXB0dXJlZEFycmF5OworICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9IG9zLnRvQnl0ZVN0cmluZygpOworICAgIGJ5dGVbXSBvbGRWYWx1ZSA9IGJ5dGVTdHJpbmcudG9CeXRlQXJyYXkoKTsKKyAgICBBcnJheXMuZmlsbChjYXB0dXJlZEFycmF5LCAoYnl0ZSkgMCk7CisgICAgYnl0ZVtdIG5ld1ZhbHVlID0gYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpOworICAgIGFzc2VydFRydWUoIk91dHB1dCBtdXN0IG5vdCBwcm92aWRlIGFjY2VzcyB0byB0aGUgdW5kZXJseWluZyBieXRlIGFycmF5IiwKKyAgICAgICAgQXJyYXlzLmVxdWFscyhvbGRWYWx1ZSwgbmV3VmFsdWUpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXdDb2RlZEJ1aWxkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGVbXSBieXRlcyA9IGdldFRlc3RCeXRlcygpOworICAgIEJ5dGVTdHJpbmcuQ29kZWRCdWlsZGVyIGJ1aWxkZXIgPSBCeXRlU3RyaW5nLm5ld0NvZGVkQnVpbGRlcihieXRlcy5sZW5ndGgpOworICAgIGJ1aWxkZXIuZ2V0Q29kZWRPdXRwdXQoKS53cml0ZVJhd0J5dGVzKGJ5dGVzKTsKKyAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0VHJ1ZSgiU3RyaW5nIGJ1aWx0IGZyb20gbmV3Q29kZWRCdWlsZGVyKCkgbXVzdCBjb250YWluIHRoZSBleHBlY3RlZCBieXRlcyIsCisgICAgICAgIGlzQXJyYXlSYW5nZShieXRlcywgYnl0ZVN0cmluZy50b0J5dGVBcnJheSgpLCAwLCBieXRlcy5sZW5ndGgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTdWJzdHJpbmdQYXJpdHkoKSB7CisgICAgYnl0ZVtdIGJpZ0J5dGVzID0gZ2V0VGVzdEJ5dGVzKDIwNDggKiAxMDI0LCAxMTMzNDRMKTsKKyAgICBpbnQgc3RhcnQgPSA1MTIgKiAxMDI0IC0gMzMzMzsKKyAgICBpbnQgZW5kICAgPSA1MTIgKiAxMDI0ICsgNzc3NzsKKyAgICBCeXRlU3RyaW5nIGNvbmNyZXRlU3Vic3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbShiaWdCeXRlcykuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpOworICAgIGJvb2xlYW4gb2sgPSB0cnVlOworICAgIGZvciAoaW50IGkgPSBzdGFydDsgb2sgJiYgaSA8IGVuZDsgKytpKSB7CisgICAgICBvayA9IChiaWdCeXRlc1tpXSA9PSBjb25jcmV0ZVN1YnN0cmluZy5ieXRlQXQoaSAtIHN0YXJ0KSk7CisgICAgfQorICAgIGFzc2VydFRydWUoIkNvbmNyZXRlIHN1YnN0cmluZyBkaWRuJ3QgY2FwdHVyZSB0aGUgcmlnaHQgYnl0ZXMiLCBvayk7CisKKyAgICBCeXRlU3RyaW5nIGxpdGVyYWxTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJpZ0J5dGVzLCBzdGFydCwgZW5kIC0gc3RhcnQpOworICAgIGFzc2VydFRydWUoIlN1YnN0cmluZyBtdXN0IGJlIGVxdWFsIHRvIGxpdGVyYWwgc3RyaW5nIiwKKyAgICAgICAgY29uY3JldGVTdWJzdHJpbmcuZXF1YWxzKGxpdGVyYWxTdHJpbmcpKTsKKyAgICBhc3NlcnRFcXVhbHMoIlN1YnN0cmluZyBtdXN0IGhhdmUgc2FtZSBoYXNoY29kZSBhcyBsaXRlcmFsIHN0cmluZyIsCisgICAgICAgIGxpdGVyYWxTdHJpbmcuaGFzaENvZGUoKSwgY29uY3JldGVTdWJzdHJpbmcuaGFzaENvZGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29tcG9zaXRlU3Vic3RyaW5nKCkgeworICAgIGJ5dGVbXSByZWZlcmVuY2VCeXRlcyA9IGdldFRlc3RCeXRlcyg3Nzc0OCwgMTEzMzQ0TCk7CisKKyAgICBMaXN0PEJ5dGVTdHJpbmc+IHBpZWNlcyA9IG1ha2VDb25jcmV0ZVBpZWNlcyhyZWZlcmVuY2VCeXRlcyk7CisgICAgQnl0ZVN0cmluZyBsaXN0U3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbShwaWVjZXMpOworCisgICAgaW50IGZyb20gPSAxMDAwOworICAgIGludCB0byA9IDQwMDAwOworICAgIEJ5dGVTdHJpbmcgY29tcG9zaXRlU3Vic3RyaW5nID0gbGlzdFN0cmluZy5zdWJzdHJpbmcoZnJvbSwgdG8pOworICAgIGJ5dGVbXSBzdWJzdHJpbmdCeXRlcyA9IGNvbXBvc2l0ZVN1YnN0cmluZy50b0J5dGVBcnJheSgpOworICAgIGJvb2xlYW4gc3RpbGxFcXVhbCA9IHRydWU7CisgICAgZm9yIChpbnQgaSA9IDA7IHN0aWxsRXF1YWwgJiYgaSA8IHRvIC0gZnJvbTsgKytpKSB7CisgICAgICBzdGlsbEVxdWFsID0gcmVmZXJlbmNlQnl0ZXNbZnJvbSArIGldID09IHN1YnN0cmluZ0J5dGVzW2ldOworICAgIH0KKyAgICBhc3NlcnRUcnVlKCJTdWJzdHJpbmcgbXVzdCByZXR1cm4gY29ycmVjdCBieXRlcyIsIHN0aWxsRXF1YWwpOworCisgICAgc3RpbGxFcXVhbCA9IHRydWU7CisgICAgZm9yIChpbnQgaSA9IDA7IHN0aWxsRXF1YWwgJiYgaSA8IHRvIC0gZnJvbTsgKytpKSB7CisgICAgICBzdGlsbEVxdWFsID0gcmVmZXJlbmNlQnl0ZXNbZnJvbSArIGldID09IGNvbXBvc2l0ZVN1YnN0cmluZy5ieXRlQXQoaSk7CisgICAgfQorICAgIGFzc2VydFRydWUoIlN1YnN0cmluZyBtdXN0IHN1cHBvcnQgYnl0ZUF0KCkgY29ycmVjdGx5Iiwgc3RpbGxFcXVhbCk7CisKKyAgICBCeXRlU3RyaW5nIGxpdGVyYWxTdWJzdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKHJlZmVyZW5jZUJ5dGVzLCBmcm9tLCB0byAtIGZyb20pOworICAgIGFzc2VydFRydWUoIkNvbXBvc2l0ZSBzdWJzdHJpbmcgbXVzdCBlcXVhbCBhIGxpdGVyYWwgc3Vic3RyaW5nIG92ZXIgdGhlIHNhbWUgYnl0ZXMiLAorICAgICAgICBjb21wb3NpdGVTdWJzdHJpbmcuZXF1YWxzKGxpdGVyYWxTdWJzdHJpbmcpKTsKKyAgICBhc3NlcnRUcnVlKCJMaXRlcmFsIHN1YnN0cmluZyBtdXN0IGVxdWFsIGEgY29tcG9zaXRlIHN1YnN0cmluZyBvdmVyIHRoZSBzYW1lIGJ5dGVzIiwKKyAgICAgICAgbGl0ZXJhbFN1YnN0cmluZy5lcXVhbHMoY29tcG9zaXRlU3Vic3RyaW5nKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoIldlIG11c3QgZ2V0IHRoZSBzYW1lIGhhc2hjb2RlcyBmb3IgY29tcG9zaXRlIGFuZCBsaXRlcmFsIHN1YnN0cmluZ3MiLAorICAgICAgICBsaXRlcmFsU3Vic3RyaW5nLmhhc2hDb2RlKCksIGNvbXBvc2l0ZVN1YnN0cmluZy5oYXNoQ29kZSgpKTsKKworICAgIGFzc2VydEZhbHNlKCJXZSBjYW4ndCBiZSBlcXVhbCB0byBhIHByb3BlciBzdWJzdHJpbmciLAorICAgICAgICBjb21wb3NpdGVTdWJzdHJpbmcuZXF1YWxzKGxpdGVyYWxTdWJzdHJpbmcuc3Vic3RyaW5nKDAsIGxpdGVyYWxTdWJzdHJpbmcuc2l6ZSgpIC0gMSkpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5RnJvbUxpc3QoKSB7CisgICAgYnl0ZVtdIHJlZmVyZW5jZUJ5dGVzID0gZ2V0VGVzdEJ5dGVzKDc3NzQ4LCAxMTMzNDRMKTsKKyAgICBCeXRlU3RyaW5nIGxpdGVyYWxTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKHJlZmVyZW5jZUJ5dGVzKTsKKworICAgIExpc3Q8Qnl0ZVN0cmluZz4gcGllY2VzID0gbWFrZUNvbmNyZXRlUGllY2VzKHJlZmVyZW5jZUJ5dGVzKTsKKyAgICBCeXRlU3RyaW5nIGxpc3RTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKHBpZWNlcyk7CisKKyAgICBhc3NlcnRUcnVlKCJDb21wb3NpdGUgc3RyaW5nIG11c3QgYmUgZXF1YWwgdG8gbGl0ZXJhbCBzdHJpbmciLAorICAgICAgICBsaXN0U3RyaW5nLmVxdWFscyhsaXRlcmFsU3RyaW5nKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJDb21wb3NpdGUgc3RyaW5nIG11c3QgaGF2ZSBzYW1lIGhhc2hjb2RlIGFzIGxpdGVyYWwgc3RyaW5nIiwKKyAgICAgICAgbGl0ZXJhbFN0cmluZy5oYXNoQ29kZSgpLCBsaXN0U3RyaW5nLmhhc2hDb2RlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENvbmNhdCgpIHsKKyAgICBieXRlW10gcmVmZXJlbmNlQnl0ZXMgPSBnZXRUZXN0Qnl0ZXMoNzc3NDgsIDExMzM0NEwpOworICAgIEJ5dGVTdHJpbmcgbGl0ZXJhbFN0cmluZyA9IEJ5dGVTdHJpbmcuY29weUZyb20ocmVmZXJlbmNlQnl0ZXMpOworCisgICAgTGlzdDxCeXRlU3RyaW5nPiBwaWVjZXMgPSBtYWtlQ29uY3JldGVQaWVjZXMocmVmZXJlbmNlQnl0ZXMpOworCisgICAgSXRlcmF0b3I8Qnl0ZVN0cmluZz4gaXRlciA9IHBpZWNlcy5pdGVyYXRvcigpOworICAgIEJ5dGVTdHJpbmcgY29uY2F0ZW5hdGVkU3RyaW5nID0gaXRlci5uZXh0KCk7CisgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICBjb25jYXRlbmF0ZWRTdHJpbmcgPSBjb25jYXRlbmF0ZWRTdHJpbmcuY29uY2F0KGl0ZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBhc3NlcnRUcnVlKCJDb25jYXRlbmF0ZWQgc3RyaW5nIG11c3QgYmUgZXF1YWwgdG8gbGl0ZXJhbCBzdHJpbmciLAorICAgICAgICBjb25jYXRlbmF0ZWRTdHJpbmcuZXF1YWxzKGxpdGVyYWxTdHJpbmcpKTsKKyAgICBhc3NlcnRFcXVhbHMoIkNvbmNhdGVuYXRlZCBzdHJpbmcgbXVzdCBoYXZlIHNhbWUgaGFzaGNvZGUgYXMgbGl0ZXJhbCBzdHJpbmciLAorICAgICAgICBsaXRlcmFsU3RyaW5nLmhhc2hDb2RlKCksIGNvbmNhdGVuYXRlZFN0cmluZy5oYXNoQ29kZSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0IHRoZSBSb3BlIGltcGxlbWVudGF0aW9uIGNhbiBkZWFsIHdpdGggRW1wdHkgbm9kZXMsIGV2ZW4gdGhvdWdoIHdlCisgICAqIGd1YXJkIGFnYWluc3QgdGhlbS4gU2VlIGFsc28ge0BsaW5rIExpdGVyYWxCeXRlU3RyaW5nVGVzdCN0ZXN0Q29uY2F0X2VtcHR5KCl9LgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdENvbmNhdF9lbXB0eSgpIHsKKyAgICBieXRlW10gcmVmZXJlbmNlQnl0ZXMgPSBnZXRUZXN0Qnl0ZXMoNzc0OCwgMTEzMzQ0TCk7CisgICAgQnl0ZVN0cmluZyBsaXRlcmFsU3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbShyZWZlcmVuY2VCeXRlcyk7CisKKyAgICBCeXRlU3RyaW5nIGR1byA9IFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdChsaXRlcmFsU3RyaW5nLCBsaXRlcmFsU3RyaW5nKTsKKyAgICBCeXRlU3RyaW5nIHRlbXAgPSBSb3BlQnl0ZVN0cmluZy5uZXdJbnN0YW5jZUZvclRlc3QoCisgICAgICAgIFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdChsaXRlcmFsU3RyaW5nLCBCeXRlU3RyaW5nLkVNUFRZKSwKKyAgICAgICAgUm9wZUJ5dGVTdHJpbmcubmV3SW5zdGFuY2VGb3JUZXN0KEJ5dGVTdHJpbmcuRU1QVFksIGxpdGVyYWxTdHJpbmcpKTsKKyAgICBCeXRlU3RyaW5nIHF1aW50ZXQgPSBSb3BlQnl0ZVN0cmluZy5uZXdJbnN0YW5jZUZvclRlc3QodGVtcCwgQnl0ZVN0cmluZy5FTVBUWSk7CisKKyAgICBhc3NlcnRUcnVlKCJTdHJpbmcgd2l0aCBjb25jYXRlbmF0ZWQgbnVsbHMgbXVzdCBlcXVhbCBzaW1wbGUgY29uY2F0ZW5hdGUiLAorICAgICAgICBkdW8uZXF1YWxzKHF1aW50ZXQpKTsKKyAgICBhc3NlcnRFcXVhbHMoIlN0cmluZyB3aXRoIGNvbmNhdGVuYXRlZCBudWxscyBoYXZlIHNhbWUgaGFzaGNvZGUgYXMgc2ltcGxlIGNvbmNhdGVuYXRlIiwKKyAgICAgICAgZHVvLmhhc2hDb2RlKCksIHF1aW50ZXQuaGFzaENvZGUoKSk7CisKKyAgICBCeXRlU3RyaW5nLkJ5dGVJdGVyYXRvciBkdW9JdGVyID0gZHVvLml0ZXJhdG9yKCk7CisgICAgQnl0ZVN0cmluZy5CeXRlSXRlcmF0b3IgcXVpbnRldEl0ZXIgPSBxdWludGV0Lml0ZXJhdG9yKCk7CisgICAgYm9vbGVhbiBzdGlsbEVxdWFsID0gdHJ1ZTsKKyAgICB3aGlsZSAoc3RpbGxFcXVhbCAmJiBxdWludGV0SXRlci5oYXNOZXh0KCkpIHsKKyAgICAgIHN0aWxsRXF1YWwgPSAoZHVvSXRlci5uZXh0Qnl0ZSgpID09IHF1aW50ZXRJdGVyLm5leHRCeXRlKCkpOworICAgIH0KKyAgICBhc3NlcnRUcnVlKCJXZSBtdXN0IGdldCB0aGUgc2FtZSBjaGFyYWN0ZXJzIGJ5IGl0ZXJhdGluZyIsIHN0aWxsRXF1YWwpOworICAgIGFzc2VydEZhbHNlKCJJdGVyYXRvciBtdXN0IGJlIGV4aGF1c3RlZCIsIGR1b0l0ZXIuaGFzTmV4dCgpKTsKKyAgICB0cnkgeworICAgICAgZHVvSXRlci5uZXh0Qnl0ZSgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFRoaXMgaXMgc3VjY2VzcworICAgIH0KKyAgICB0cnkgeworICAgICAgcXVpbnRldEl0ZXIubmV4dEJ5dGUoKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBUaGlzIGlzIHN1Y2Nlc3MKKyAgICB9CisKKyAgICAvLyBUZXN0IHRoYXQgZXZlbiBpZiB3ZSBmb3JjZSBlbXB0eSBzdHJpbmdzIGluIGFzIHJvcGUgbGVhdmVzIGluIHRoaXMKKyAgICAvLyBjb25maWd1cmF0aW9uLCB3ZSBhbHdheXMgZ2V0IGEgKHBvc3NpYmx5IEJvdW5kZWQpIExpdGVyYWxCeXRlU3RyaW5nCisgICAgLy8gZm9yIGEgbGVuZ3RoIDEgc3Vic3RyaW5nLgorICAgIC8vCisgICAgLy8gSXQgaXMgcG9zc2libGUsIHVzaW5nIHRoZSB0ZXN0aW5nIGZhY3RvcnkgbWV0aG9kIHRvIGNyZWF0ZSBkZWVwbHkgbmVzdGVkCisgICAgLy8gdHJlZXMgb2YgZW1wdHkgbGVhdmVzLCB0byBtYWtlIGEgc3RyaW5nIHRoYXQgd2lsbCBmYWlsIHRoaXMgdGVzdC4KKyAgICBmb3IgKGludCBpID0gMTsgaSA8IGR1by5zaXplKCk7ICsraSkgeworICAgICAgYXNzZXJ0VHJ1ZSgiU3Vic3RyaW5ncyBvZiBzaXplKCkgPCAyIG11c3Qgbm90IGJlIFJvcGVCeXRlU3RyaW5ncyIsCisgICAgICAgICAgZHVvLnN1YnN0cmluZyhpIC0gMSwgaSkgaW5zdGFuY2VvZiBMaXRlcmFsQnl0ZVN0cmluZyk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAxOyBpIDwgcXVpbnRldC5zaXplKCk7ICsraSkgeworICAgICAgYXNzZXJ0VHJ1ZSgiU3Vic3RyaW5ncyBvZiBzaXplKCkgPCAyIG11c3Qgbm90IGJlIFJvcGVCeXRlU3RyaW5ncyIsCisgICAgICAgICAgcXVpbnRldC5zdWJzdHJpbmcoaSAtIDEsIGkpIGluc3RhbmNlb2YgTGl0ZXJhbEJ5dGVTdHJpbmcpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydHNXaXRoKCkgeworICAgIGJ5dGVbXSBieXRlcyA9IGdldFRlc3RCeXRlcygxMDAwLCAxMjM0TCk7CisgICAgQnl0ZVN0cmluZyBzdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzKTsKKyAgICBCeXRlU3RyaW5nIHByZWZpeCA9IEJ5dGVTdHJpbmcuY29weUZyb20oYnl0ZXMsIDAsIDUwMCk7CisgICAgQnl0ZVN0cmluZyBzdWZmaXggPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzLCA0MDAsIDYwMCk7CisgICAgYXNzZXJ0VHJ1ZShzdHJpbmcuc3RhcnRzV2l0aChCeXRlU3RyaW5nLkVNUFRZKSk7CisgICAgYXNzZXJ0VHJ1ZShzdHJpbmcuc3RhcnRzV2l0aChzdHJpbmcpKTsKKyAgICBhc3NlcnRUcnVlKHN0cmluZy5zdGFydHNXaXRoKHByZWZpeCkpOworICAgIGFzc2VydEZhbHNlKHN0cmluZy5zdGFydHNXaXRoKHN1ZmZpeCkpOworICAgIGFzc2VydEZhbHNlKHByZWZpeC5zdGFydHNXaXRoKHN1ZmZpeCkpOworICAgIGFzc2VydEZhbHNlKHN1ZmZpeC5zdGFydHNXaXRoKHByZWZpeCkpOworICAgIGFzc2VydEZhbHNlKEJ5dGVTdHJpbmcuRU1QVFkuc3RhcnRzV2l0aChwcmVmaXgpKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVTdHJpbmcuRU1QVFkuc3RhcnRzV2l0aChCeXRlU3RyaW5nLkVNUFRZKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RW5kc1dpdGgoKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gZ2V0VGVzdEJ5dGVzKDEwMDAsIDEyMzRMKTsKKyAgICBCeXRlU3RyaW5nIHN0cmluZyA9IEJ5dGVTdHJpbmcuY29weUZyb20oYnl0ZXMpOworICAgIEJ5dGVTdHJpbmcgcHJlZml4ID0gQnl0ZVN0cmluZy5jb3B5RnJvbShieXRlcywgMCwgNTAwKTsKKyAgICBCeXRlU3RyaW5nIHN1ZmZpeCA9IEJ5dGVTdHJpbmcuY29weUZyb20oYnl0ZXMsIDQwMCwgNjAwKTsKKyAgICBhc3NlcnRUcnVlKHN0cmluZy5lbmRzV2l0aChCeXRlU3RyaW5nLkVNUFRZKSk7CisgICAgYXNzZXJ0VHJ1ZShzdHJpbmcuZW5kc1dpdGgoc3RyaW5nKSk7CisgICAgYXNzZXJ0VHJ1ZShzdHJpbmcuZW5kc1dpdGgoc3VmZml4KSk7CisgICAgYXNzZXJ0RmFsc2Uoc3RyaW5nLmVuZHNXaXRoKHByZWZpeCkpOworICAgIGFzc2VydEZhbHNlKHN1ZmZpeC5lbmRzV2l0aChwcmVmaXgpKTsKKyAgICBhc3NlcnRGYWxzZShwcmVmaXguZW5kc1dpdGgoc3VmZml4KSk7CisgICAgYXNzZXJ0RmFsc2UoQnl0ZVN0cmluZy5FTVBUWS5lbmRzV2l0aChzdWZmaXgpKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVTdHJpbmcuRU1QVFkuZW5kc1dpdGgoQnl0ZVN0cmluZy5FTVBUWSkpOworICB9CisKKyAgc3RhdGljIExpc3Q8Qnl0ZVN0cmluZz4gbWFrZUNvbmNyZXRlUGllY2VzKGJ5dGVbXSByZWZlcmVuY2VCeXRlcykgeworICAgIExpc3Q8Qnl0ZVN0cmluZz4gcGllY2VzID0gbmV3IEFycmF5TGlzdDxCeXRlU3RyaW5nPigpOworICAgIC8vIFN0YXJ0aW5nIGxlbmd0aCBzaG91bGQgYmUgc21hbGwgZW5vdWdoIHRoYXQgd2UnbGwgZG8gc29tZSBjb25jYXRlbmF0aW5nIGJ5CisgICAgLy8gY29weWluZyBpZiB3ZSBqdXN0IGNvbmNhdGVuYXRlIGFsbCB0aGVzZSBwaWVjZXMgdG9nZXRoZXIuCisgICAgZm9yIChpbnQgc3RhcnQgPSAwLCBsZW5ndGggPSAxNjsgc3RhcnQgPCByZWZlcmVuY2VCeXRlcy5sZW5ndGg7IHN0YXJ0ICs9IGxlbmd0aCkgeworICAgICAgbGVuZ3RoID0gKGxlbmd0aCA8PCAxKSAtIDE7CisgICAgICBpZiAoc3RhcnQgKyBsZW5ndGggPiByZWZlcmVuY2VCeXRlcy5sZW5ndGgpIHsKKyAgICAgICAgbGVuZ3RoID0gcmVmZXJlbmNlQnl0ZXMubGVuZ3RoIC0gc3RhcnQ7CisgICAgICB9CisgICAgICBwaWVjZXMuYWRkKEJ5dGVTdHJpbmcuY29weUZyb20ocmVmZXJlbmNlQnl0ZXMsIHN0YXJ0LCBsZW5ndGgpKTsKKyAgICB9CisgICAgcmV0dXJuIHBpZWNlczsKKyAgfQorICAKKyAgcHJpdmF0ZSBieXRlW10gc3Vic3RyaW5nVXNpbmdXcml0ZVRvKAorICAgICAgQnl0ZVN0cmluZyBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgZGF0YS53cml0ZVRvKG91dHB1dCwgb2Zmc2V0LCBsZW5ndGgpOworICAgIHJldHVybiBvdXRwdXQudG9CeXRlQXJyYXkoKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFdyaXRlVG9PdXRwdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDaG9vc2UgYSBzaXplIGxhcmdlIGVub3VnaCBzbyB3aGVuIHR3byBCeXRlU3RyaW5ncyBhcmUgY29uY2F0ZW5hdGVkIHRoZXkKKyAgICAvLyB3b24ndCBiZSBtZXJnZWQgaW50byBvbmUgYnl0ZSBhcnJheSBkdWUgdG8gc29tZSBvcHRpbWl6YXRpb25zLgorICAgIGZpbmFsIGludCBkYXRhU2l6ZSA9IEJ5dGVTdHJpbmcuQ09OQ0FURU5BVEVfQllfQ09QWV9TSVpFICsgMTsKKyAgICBieXRlW10gZGF0YTEgPSBuZXcgYnl0ZVtkYXRhU2l6ZV07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhMS5sZW5ndGg7IGkrKykgeworICAgICAgZGF0YTFbaV0gPSAoYnl0ZSkgMTsKKyAgICB9CisgICAgZGF0YTFbMV0gPSAoYnl0ZSkgMTE7CisgICAgLy8gVGVzdCBMaXRlcmFsQnl0ZVN0cmluZy53cml0ZVRvKE91dHB1dFN0cmVhbSxpbnQsaW50KQorICAgIExpdGVyYWxCeXRlU3RyaW5nIGxlZnQgPSBuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcoZGF0YTEpOworICAgIGJ5dGVbXSByZXN1bHQgPSBzdWJzdHJpbmdVc2luZ1dyaXRlVG8obGVmdCwgMSwgMSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMTEsIHJlc3VsdFswXSk7CisgICAgCisgICAgYnl0ZVtdIGRhdGEyID0gbmV3IGJ5dGVbZGF0YVNpemVdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YTEubGVuZ3RoOyBpKyspIHsKKyAgICAgIGRhdGEyW2ldID0gKGJ5dGUpIDI7CisgICAgfQorICAgIExpdGVyYWxCeXRlU3RyaW5nIHJpZ2h0ID0gbmV3IExpdGVyYWxCeXRlU3RyaW5nKGRhdGEyKTsKKyAgICAvLyBDb25jYXRlbmF0ZSB0d28gQnl0ZVN0cmluZ3MgdG8gY3JlYXRlIGEgUm9wZUJ5dGVTdHJpbmcuCisgICAgQnl0ZVN0cmluZyByb290ID0gbGVmdC5jb25jYXQocmlnaHQpOworICAgIC8vIE1ha2Ugc3VyZSB3ZSBhcmUgYWN0dWFsbHkgdGVzdGluZyBhIFJvcGVCeXRlU3RyaW5nIHdpdGggYSBzaW1wbGUgdHJlZQorICAgIC8vIHN0cnVjdHVyZS4KKyAgICBhc3NlcnRFcXVhbHMoMSwgcm9vdC5nZXRUcmVlRGVwdGgoKSk7CisgICAgLy8gV3JpdGUgcGFydHMgb2YgdGhlIGxlZnQgbm9kZS4KKyAgICByZXN1bHQgPSBzdWJzdHJpbmdVc2luZ1dyaXRlVG8ocm9vdCwgMCwgZGF0YVNpemUpOworICAgIGFzc2VydEVxdWFscyhkYXRhU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAxLCByZXN1bHRbMF0pOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMSwgcmVzdWx0W2RhdGFTaXplIC0gMV0pOworICAgIC8vIFdyaXRlIHBhcnRzIG9mIHRoZSByaWdodCBub2RlLgorICAgIHJlc3VsdCA9IHN1YnN0cmluZ1VzaW5nV3JpdGVUbyhyb290LCBkYXRhU2l6ZSwgZGF0YVNpemUpOworICAgIGFzc2VydEVxdWFscyhkYXRhU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAyLCByZXN1bHRbMF0pOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMiwgcmVzdWx0W2RhdGFTaXplIC0gMV0pOworICAgIC8vIFdyaXRlIGEgc2VnbWVudCBvZiBieXRlcyB0aGF0IHJ1bnMgYWNyb3NzIGJvdGggbm9kZXMuCisgICAgcmVzdWx0ID0gc3Vic3RyaW5nVXNpbmdXcml0ZVRvKHJvb3QsIGRhdGFTaXplIC8gMiwgZGF0YVNpemUpOworICAgIGFzc2VydEVxdWFscyhkYXRhU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAxLCByZXN1bHRbMF0pOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMSwgcmVzdWx0W2RhdGFTaXplIC0gZGF0YVNpemUgLyAyIC0gMV0pOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMiwgcmVzdWx0W2RhdGFTaXplIC0gZGF0YVNpemUgLyAyXSk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAyLCByZXN1bHRbZGF0YVNpemUgLSAxXSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NoZWNrVXRmOFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NoZWNrVXRmOFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NDcwZTljCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvQ2hlY2tVdGY4VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlcjsKK2ltcG9ydCBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlcjsKK2ltcG9ydCBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZTsKK2ltcG9ydCBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3QgdGhhdCBwcm90b3MgZ2VuZXJhdGVkIHdpdGggZmlsZSBvcHRpb24gamF2YV9zdHJpbmdfY2hlY2tfdXRmOCBkbyBpbgorICogZmFjdCBwZXJmb3JtIGFwcHJvcHJpYXRlIFVURi04IGNoZWNrcy4KKyAqCisgKiBAYXV0aG9yIGpiYXVtQGdvb2dsZS5jb20gKEphY29iIEJ1dGNoZXIpCisgKi8KK3B1YmxpYyBjbGFzcyBDaGVja1V0ZjhUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBVVEY4X0JZVEVfU1RSSU5HX1RFWFQgPSAic29tZSB0ZXh0IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQnl0ZVN0cmluZyBVVEY4X0JZVEVfU1RSSU5HID0KKyAgICAgIEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KFVURjhfQllURV9TVFJJTkdfVEVYVCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJ5dGVTdHJpbmcgTk9OX1VURjhfQllURV9TVFJJTkcgPQorICAgICAgQnl0ZVN0cmluZy5jb3B5RnJvbShuZXcgYnl0ZVtdeyhieXRlKSAweDgwfSk7IC8vIEEgbG9uZSBjb250aW51YXRpb24gYnl0ZS4KKworICBwdWJsaWMgdm9pZCB0ZXN0QnVpbGRSZXF1aXJlZFN0cmluZ1dpdGhHb29kVXRmOCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEVxdWFscyhVVEY4X0JZVEVfU1RSSU5HX1RFWFQsCisgICAgICAgICAgICAgICAgIFN0cmluZ1dyYXBwZXIubmV3QnVpbGRlcigpLnNldFJlcUJ5dGVzKFVURjhfQllURV9TVFJJTkcpLmdldFJlcSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVJlcXVpcmVkU3RyaW5nV2l0aEdvb2RVdGY4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZyBzZXJpYWxpemVkID0KKyAgICAgICAgQnl0ZXNXcmFwcGVyLm5ld0J1aWxkZXIoKS5zZXRSZXEoVVRGOF9CWVRFX1NUUklORykuYnVpbGQoKS50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRFcXVhbHMoVVRGOF9CWVRFX1NUUklOR19URVhULAorICAgICAgICAgICAgICAgICBTdHJpbmdXcmFwcGVyLlBBUlNFUi5wYXJzZUZyb20oc2VyaWFsaXplZCkuZ2V0UmVxKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJ1aWxkUmVxdWlyZWRTdHJpbmdXaXRoQmFkVXRmOCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBTdHJpbmdXcmFwcGVyLm5ld0J1aWxkZXIoKS5zZXRSZXFCeXRlcyhOT05fVVRGOF9CWVRFX1NUUklORyk7CisgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIG5vbiBVVEYtOCBieXRlIHN0cmluZy4iKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIkJ5dGUgc3RyaW5nIGlzIG5vdCBVVEYtOC4iLCBleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QnVpbGRPcHRpb25hbFN0cmluZ1dpdGhCYWRVdGY4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIFN0cmluZ1dyYXBwZXIubmV3QnVpbGRlcigpLnNldE9wdEJ5dGVzKE5PTl9VVEY4X0JZVEVfU1RSSU5HKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3Igbm9uIFVURi04IGJ5dGUgc3RyaW5nLiIpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICAgIGFzc2VydEVxdWFscygiQnl0ZSBzdHJpbmcgaXMgbm90IFVURi04LiIsIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RCdWlsZFJlcGVhdGVkU3RyaW5nV2l0aEJhZFV0ZjgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgU3RyaW5nV3JhcHBlci5uZXdCdWlsZGVyKCkuYWRkUmVwQnl0ZXMoTk9OX1VURjhfQllURV9TVFJJTkcpOworICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBub24gVVRGLTggYnl0ZSBzdHJpbmcuIik7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4Y2VwdGlvbikgeworICAgICAgYXNzZXJ0RXF1YWxzKCJCeXRlIHN0cmluZyBpcyBub3QgVVRGLTguIiwgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlUmVxdWlyZWRTdHJpbmdXaXRoQmFkVXRmOCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcgc2VyaWFsaXplZCA9CisgICAgICAgIEJ5dGVzV3JhcHBlci5uZXdCdWlsZGVyKCkuc2V0UmVxKE5PTl9VVEY4X0JZVEVfU1RSSU5HKS5idWlsZCgpLnRvQnl0ZVN0cmluZygpOworICAgIHRyeSB7CisgICAgICBTdHJpbmdXcmFwcGVyLlBBUlNFUi5wYXJzZUZyb20oc2VyaWFsaXplZCk7CisgICAgICBmYWlsKCJFeHBlY3RlZCBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZm9yIG5vbiBVVEYtOCBieXRlIHN0cmluZy4iKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIlByb3RvY29sIG1lc3NhZ2UgaGFkIGludmFsaWQgVVRGLTguIiwgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJ1aWxkUmVxdWlyZWRTdHJpbmdXaXRoQmFkVXRmOFNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgU3RyaW5nV3JhcHBlclNpemUubmV3QnVpbGRlcigpLnNldFJlcUJ5dGVzKE5PTl9VVEY4X0JZVEVfU1RSSU5HKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3Igbm9uIFVURi04IGJ5dGUgc3RyaW5nLiIpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICAgIGFzc2VydEVxdWFscygiQnl0ZSBzdHJpbmcgaXMgbm90IFVURi04LiIsIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RCdWlsZE9wdGlvbmFsU3RyaW5nV2l0aEJhZFV0ZjhTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIFN0cmluZ1dyYXBwZXJTaXplLm5ld0J1aWxkZXIoKS5zZXRPcHRCeXRlcyhOT05fVVRGOF9CWVRFX1NUUklORyk7CisgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIG5vbiBVVEYtOCBieXRlIHN0cmluZy4iKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIkJ5dGUgc3RyaW5nIGlzIG5vdCBVVEYtOC4iLCBleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QnVpbGRSZXBlYXRlZFN0cmluZ1dpdGhCYWRVdGY4U2l6ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBTdHJpbmdXcmFwcGVyU2l6ZS5uZXdCdWlsZGVyKCkuYWRkUmVwQnl0ZXMoTk9OX1VURjhfQllURV9TVFJJTkcpOworICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBub24gVVRGLTggYnl0ZSBzdHJpbmcuIik7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4Y2VwdGlvbikgeworICAgICAgYXNzZXJ0RXF1YWxzKCJCeXRlIHN0cmluZyBpcyBub3QgVVRGLTguIiwgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlUmVxdWlyZWRTdHJpbmdXaXRoQmFkVXRmOFNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlU3RyaW5nIHNlcmlhbGl6ZWQgPQorICAgICAgICBCeXRlc1dyYXBwZXJTaXplLm5ld0J1aWxkZXIoKS5zZXRSZXEoTk9OX1VURjhfQllURV9TVFJJTkcpLmJ1aWxkKCkudG9CeXRlU3RyaW5nKCk7CisgICAgdHJ5IHsKKyAgICAgIFN0cmluZ1dyYXBwZXJTaXplLlBBUlNFUi5wYXJzZUZyb20oc2VyaWFsaXplZCk7CisgICAgICBmYWlsKCJFeHBlY3RlZCBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZm9yIG5vbiBVVEYtOCBieXRlIHN0cmluZy4iKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIlByb3RvY29sIG1lc3NhZ2UgaGFkIGludmFsaWQgVVRGLTguIiwgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZElucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4ZDgxNDIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzY5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIFVuaXQgdGVzdCBmb3Ige0BsaW5rIENvZGVkSW5wdXRTdHJlYW19LgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBjbGFzcyBDb2RlZElucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgLyoqCisgICAqIEhlbHBlciB0byBjb25zdHJ1Y3QgYSBieXRlIGFycmF5IGZyb20gYSBidW5jaCBvZiBieXRlcy4gIFRoZSBpbnB1dHMgYXJlCisgICAqIGFjdHVhbGx5IGludHMgc28gdGhhdCBJIGNhbiB1c2UgaGV4IG5vdGF0aW9uIGFuZCBub3QgZ2V0IHN0dXBpZCBlcnJvcnMKKyAgICogYWJvdXQgcHJlY2lzaW9uLgorICAgKi8KKyAgcHJpdmF0ZSBieXRlW10gYnl0ZXMoaW50Li4uIGJ5dGVzQXNJbnRzKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXNBc0ludHMubGVuZ3RoXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzQXNJbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBieXRlc1tpXSA9IChieXRlKSBieXRlc0FzSW50c1tpXTsKKyAgICB9CisgICAgcmV0dXJuIGJ5dGVzOworICB9CisKKyAgLyoqCisgICAqIEFuIElucHV0U3RyZWFtIHdoaWNoIGxpbWl0cyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGl0IHJlYWRzIGF0IGEgdGltZS4KKyAgICogV2UgdXNlIHRoaXMgdG8gbWFrZSBzdXJlIHRoYXQgQ29kZWRJbnB1dFN0cmVhbSBkb2Vzbid0IHNjcmV3IHVwIHdoZW4KKyAgICogcmVhZGluZyBpbiBzbWFsbCBibG9ja3MuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTbWFsbEJsb2NrSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgYmxvY2tTaXplOworCisgICAgcHVibGljIFNtYWxsQmxvY2tJbnB1dFN0cmVhbShieXRlW10gZGF0YSwgaW50IGJsb2NrU2l6ZSkgeworICAgICAgdGhpcyhuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSksIGJsb2NrU2l6ZSk7CisgICAgfQorCisgICAgcHVibGljIFNtYWxsQmxvY2tJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbiwgaW50IGJsb2NrU2l6ZSkgeworICAgICAgc3VwZXIoaW4pOworICAgICAgdGhpcy5ibG9ja1NpemUgPSBibG9ja1NpemU7CisgICAgfQorCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIHN1cGVyLnJlYWQoYiwgMCwgTWF0aC5taW4oYi5sZW5ndGgsIGJsb2NrU2l6ZSkpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBzdXBlci5yZWFkKGIsIG9mZiwgTWF0aC5taW4obGVuLCBibG9ja1NpemUpKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0RGF0YUNvbnN1bWVkKGJ5dGVbXSBkYXRhLCBDb2RlZElucHV0U3RyZWFtIGlucHV0KQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRFcXVhbHMoZGF0YS5sZW5ndGgsIGlucHV0LmdldFRvdGFsQnl0ZXNSZWFkKCkpOworICAgIGFzc2VydFRydWUoaW5wdXQuaXNBdEVuZCgpKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZXMgdGhlIGdpdmVuIGJ5dGVzIHVzaW5nIHJlYWRSYXdWYXJpbnQzMigpIGFuZCByZWFkUmF3VmFyaW50NjQoKSBhbmQKKyAgICogY2hlY2tzIHRoYXQgdGhlIHJlc3VsdCBtYXRjaGVzIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBhc3NlcnRSZWFkVmFyaW50KGJ5dGVbXSBkYXRhLCBsb25nIHZhbHVlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKTsKKyAgICBhc3NlcnRFcXVhbHMoKGludCkgdmFsdWUsIGlucHV0LnJlYWRSYXdWYXJpbnQzMigpKTsKKyAgICBhc3NlcnREYXRhQ29uc3VtZWQoZGF0YSwgaW5wdXQpOworCisgICAgaW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGRhdGEpOworICAgIGFzc2VydEVxdWFscyh2YWx1ZSwgaW5wdXQucmVhZFJhd1ZhcmludDY0KCkpOworICAgIGFzc2VydERhdGFDb25zdW1lZChkYXRhLCBpbnB1dCk7CisKKyAgICBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBpbnB1dC5yZWFkUmF3VmFyaW50NjRTbG93UGF0aCgpKTsKKyAgICBhc3NlcnREYXRhQ29uc3VtZWQoZGF0YSwgaW5wdXQpOworCisgICAgaW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGRhdGEpOworICAgIGFzc2VydFRydWUoaW5wdXQuc2tpcEZpZWxkKFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5UKSk7CisgICAgYXNzZXJ0RGF0YUNvbnN1bWVkKGRhdGEsIGlucHV0KTsKKworICAgIC8vIFRyeSBkaWZmZXJlbnQgYmxvY2sgc2l6ZXMuCisgICAgZm9yIChpbnQgYmxvY2tTaXplID0gMTsgYmxvY2tTaXplIDw9IDE2OyBibG9ja1NpemUgKj0gMikgeworICAgICAgaW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKAorICAgICAgICBuZXcgU21hbGxCbG9ja0lucHV0U3RyZWFtKGRhdGEsIGJsb2NrU2l6ZSkpOworICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIHZhbHVlLCBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKSk7CisgICAgICBhc3NlcnREYXRhQ29uc3VtZWQoZGF0YSwgaW5wdXQpOworCisgICAgICBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoCisgICAgICAgIG5ldyBTbWFsbEJsb2NrSW5wdXRTdHJlYW0oZGF0YSwgYmxvY2tTaXplKSk7CisgICAgICBhc3NlcnRFcXVhbHModmFsdWUsIGlucHV0LnJlYWRSYXdWYXJpbnQ2NCgpKTsKKyAgICAgIGFzc2VydERhdGFDb25zdW1lZChkYXRhLCBpbnB1dCk7CisKKyAgICAgIGlucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZSgKKyAgICAgICAgbmV3IFNtYWxsQmxvY2tJbnB1dFN0cmVhbShkYXRhLCBibG9ja1NpemUpKTsKKyAgICAgIGFzc2VydEVxdWFscyh2YWx1ZSwgaW5wdXQucmVhZFJhd1ZhcmludDY0U2xvd1BhdGgoKSk7CisgICAgICBhc3NlcnREYXRhQ29uc3VtZWQoZGF0YSwgaW5wdXQpOworCisgICAgICBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoCisgICAgICAgIG5ldyBTbWFsbEJsb2NrSW5wdXRTdHJlYW0oZGF0YSwgYmxvY2tTaXplKSk7CisgICAgICBhc3NlcnRUcnVlKGlucHV0LnNraXBGaWVsZChXaXJlRm9ybWF0LldJUkVUWVBFX1ZBUklOVCkpOworICAgICAgYXNzZXJ0RGF0YUNvbnN1bWVkKGRhdGEsIGlucHV0KTsKKyAgICB9CisKKyAgICAvLyBUcnkgcmVhZGluZyBkaXJlY3QgZnJvbSBhbiBJbnB1dFN0cmVhbS4gIFdlIHdhbnQgdG8gdmVyaWZ5IHRoYXQgaXQKKyAgICAvLyBkb2Vzbid0IHJlYWQgcGFzdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCwgc28gd2UgY29weSB0byBhIG5ldywgYmlnZ2VyCisgICAgLy8gYXJyYXkgZmlyc3QuCisgICAgYnl0ZVtdIGxvbmdlckRhdGEgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aCArIDFdOworICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgMCwgbG9uZ2VyRGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICAgIElucHV0U3RyZWFtIHJhd0lucHV0ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGxvbmdlckRhdGEpOworICAgIGFzc2VydEVxdWFscygoaW50KSB2YWx1ZSwgQ29kZWRJbnB1dFN0cmVhbS5yZWFkUmF3VmFyaW50MzIocmF3SW5wdXQpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcmF3SW5wdXQuYXZhaWxhYmxlKCkpOworICB9CisKKyAgLyoqCisgICAqIFBhcnNlcyB0aGUgZ2l2ZW4gYnl0ZXMgdXNpbmcgcmVhZFJhd1ZhcmludDMyKCkgYW5kIHJlYWRSYXdWYXJpbnQ2NCgpIGFuZAorICAgKiBleHBlY3RzIHRoZW0gdG8gZmFpbCB3aXRoIGFuIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB3aG9zZQorICAgKiBkZXNjcmlwdGlvbiBtYXRjaGVzIHRoZSBnaXZlbiBvbmUuCisgICAqLworICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVhZFZhcmludEZhaWx1cmUoCisgICAgICBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQsIGJ5dGVbXSBkYXRhKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZGF0YSk7CisgICAgdHJ5IHsKKyAgICAgIGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLmdldE1lc3NhZ2UoKSwgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKworICAgIGlucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKTsKKyAgICB0cnkgeworICAgICAgaW5wdXQucmVhZFJhd1ZhcmludDY0KCk7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorCisgICAgaW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGRhdGEpOworICAgIHRyeSB7CisgICAgICBpbnB1dC5yZWFkUmF3VmFyaW50NjRTbG93UGF0aCgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLmdldE1lc3NhZ2UoKSwgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKworICAgIC8vIE1ha2Ugc3VyZSB3ZSBnZXQgdGhlIHNhbWUgZXJyb3Igd2hlbiByZWFkaW5nIGRpcmVjdCBmcm9tIGFuIElucHV0U3RyZWFtLgorICAgIHRyeSB7CisgICAgICBDb2RlZElucHV0U3RyZWFtLnJlYWRSYXdWYXJpbnQzMihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLmdldE1lc3NhZ2UoKSwgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisgIC8qKiBUZXN0cyByZWFkUmF3VmFyaW50MzIoKSBhbmQgcmVhZFJhd1ZhcmludDY0KCkuICovCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkVmFyaW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0UmVhZFZhcmludChieXRlcygweDAwKSwgMCk7CisgICAgYXNzZXJ0UmVhZFZhcmludChieXRlcygweDAxKSwgMSk7CisgICAgYXNzZXJ0UmVhZFZhcmludChieXRlcygweDdmKSwgMTI3KTsKKyAgICAvLyAxNDg4MgorICAgIGFzc2VydFJlYWRWYXJpbnQoYnl0ZXMoMHhhMiwgMHg3NCksICgweDIyIDw8IDApIHwgKDB4NzQgPDwgNykpOworICAgIC8vIDI5NjE0ODg4MzAKKyAgICBhc3NlcnRSZWFkVmFyaW50KGJ5dGVzKDB4YmUsIDB4ZjcsIDB4OTIsIDB4ODQsIDB4MGIpLAorICAgICAgKDB4M2UgPDwgMCkgfCAoMHg3NyA8PCA3KSB8ICgweDEyIDw8IDE0KSB8ICgweDA0IDw8IDIxKSB8CisgICAgICAoMHgwYkwgPDwgMjgpKTsKKworICAgIC8vIDY0LWJpdAorICAgIC8vIDcyNTY0NTYxMjYKKyAgICBhc3NlcnRSZWFkVmFyaW50KGJ5dGVzKDB4YmUsIDB4ZjcsIDB4OTIsIDB4ODQsIDB4MWIpLAorICAgICAgKDB4M2UgPDwgMCkgfCAoMHg3NyA8PCA3KSB8ICgweDEyIDw8IDE0KSB8ICgweDA0IDw8IDIxKSB8CisgICAgICAoMHgxYkwgPDwgMjgpKTsKKyAgICAvLyA0MTI1NjIwMjU4MDcxODMzNgorICAgIGFzc2VydFJlYWRWYXJpbnQoCisgICAgICBieXRlcygweDgwLCAweGU2LCAweGViLCAweDljLCAweGMzLCAweGM5LCAweGE0LCAweDQ5KSwKKyAgICAgICgweDAwIDw8IDApIHwgKDB4NjYgPDwgNykgfCAoMHg2YiA8PCAxNCkgfCAoMHgxYyA8PCAyMSkgfAorICAgICAgKDB4NDNMIDw8IDI4KSB8ICgweDQ5TCA8PCAzNSkgfCAoMHgyNEwgPDwgNDIpIHwgKDB4NDlMIDw8IDQ5KSk7CisgICAgLy8gMTE5NjQzNzgzMzA5Nzg3MzUxMzEKKyAgICBhc3NlcnRSZWFkVmFyaW50KAorICAgICAgYnl0ZXMoMHg5YiwgMHhhOCwgMHhmOSwgMHhjMiwgMHhiYiwgMHhkNiwgMHg4MCwgMHg4NSwgMHhhNiwgMHgwMSksCisgICAgICAoMHgxYiA8PCAwKSB8ICgweDI4IDw8IDcpIHwgKDB4NzkgPDwgMTQpIHwgKDB4NDIgPDwgMjEpIHwKKyAgICAgICgweDNiTCA8PCAyOCkgfCAoMHg1NkwgPDwgMzUpIHwgKDB4MDBMIDw8IDQyKSB8CisgICAgICAoMHgwNUwgPDwgNDkpIHwgKDB4MjZMIDw8IDU2KSB8ICgweDAxTCA8PCA2MykpOworCisgICAgLy8gRmFpbHVyZXMKKyAgICBhc3NlcnRSZWFkVmFyaW50RmFpbHVyZSgKKyAgICAgIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5tYWxmb3JtZWRWYXJpbnQoKSwKKyAgICAgIGJ5dGVzKDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsCisgICAgICAgICAgICAweDAwKSk7CisgICAgYXNzZXJ0UmVhZFZhcmludEZhaWx1cmUoCisgICAgICBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24udHJ1bmNhdGVkTWVzc2FnZSgpLAorICAgICAgYnl0ZXMoMHg4MCkpOworICB9CisKKyAgLyoqCisgICAqIFBhcnNlcyB0aGUgZ2l2ZW4gYnl0ZXMgdXNpbmcgcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCkgYW5kIGNoZWNrcworICAgKiB0aGF0IHRoZSByZXN1bHQgbWF0Y2hlcyB0aGUgZ2l2ZW4gdmFsdWUuCisgICAqLworICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVhZExpdHRsZUVuZGlhbjMyKGJ5dGVbXSBkYXRhLCBpbnQgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBpbnB1dC5yZWFkUmF3TGl0dGxlRW5kaWFuMzIoKSk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworCisgICAgLy8gVHJ5IGRpZmZlcmVudCBibG9jayBzaXplcy4KKyAgICBmb3IgKGludCBibG9ja1NpemUgPSAxOyBibG9ja1NpemUgPD0gMTY7IGJsb2NrU2l6ZSAqPSAyKSB7CisgICAgICBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoCisgICAgICAgIG5ldyBTbWFsbEJsb2NrSW5wdXRTdHJlYW0oZGF0YSwgYmxvY2tTaXplKSk7CisgICAgICBhc3NlcnRFcXVhbHModmFsdWUsIGlucHV0LnJlYWRSYXdMaXR0bGVFbmRpYW4zMigpKTsKKyAgICAgIGFzc2VydFRydWUoaW5wdXQuaXNBdEVuZCgpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUGFyc2VzIHRoZSBnaXZlbiBieXRlcyB1c2luZyByZWFkUmF3TGl0dGxlRW5kaWFuNjQoKSBhbmQgY2hlY2tzCisgICAqIHRoYXQgdGhlIHJlc3VsdCBtYXRjaGVzIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBhc3NlcnRSZWFkTGl0dGxlRW5kaWFuNjQoYnl0ZVtdIGRhdGEsIGxvbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBpbnB1dC5yZWFkUmF3TGl0dGxlRW5kaWFuNjQoKSk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworCisgICAgLy8gVHJ5IGRpZmZlcmVudCBibG9jayBzaXplcy4KKyAgICBmb3IgKGludCBibG9ja1NpemUgPSAxOyBibG9ja1NpemUgPD0gMTY7IGJsb2NrU2l6ZSAqPSAyKSB7CisgICAgICBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoCisgICAgICAgIG5ldyBTbWFsbEJsb2NrSW5wdXRTdHJlYW0oZGF0YSwgYmxvY2tTaXplKSk7CisgICAgICBhc3NlcnRFcXVhbHModmFsdWUsIGlucHV0LnJlYWRSYXdMaXR0bGVFbmRpYW42NCgpKTsKKyAgICAgIGFzc2VydFRydWUoaW5wdXQuaXNBdEVuZCgpKTsKKyAgICB9CisgIH0KKworICAvKiogVGVzdHMgcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCkgYW5kIHJlYWRSYXdMaXR0bGVFbmRpYW42NCgpLiAqLworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZExpdHRsZUVuZGlhbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFJlYWRMaXR0bGVFbmRpYW4zMihieXRlcygweDc4LCAweDU2LCAweDM0LCAweDEyKSwgMHgxMjM0NTY3OCk7CisgICAgYXNzZXJ0UmVhZExpdHRsZUVuZGlhbjMyKGJ5dGVzKDB4ZjAsIDB4ZGUsIDB4YmMsIDB4OWEpLCAweDlhYmNkZWYwKTsKKworICAgIGFzc2VydFJlYWRMaXR0bGVFbmRpYW42NCgKKyAgICAgIGJ5dGVzKDB4ZjAsIDB4ZGUsIDB4YmMsIDB4OWEsIDB4NzgsIDB4NTYsIDB4MzQsIDB4MTIpLAorICAgICAgMHgxMjM0NTY3ODlhYmNkZWYwTCk7CisgICAgYXNzZXJ0UmVhZExpdHRsZUVuZGlhbjY0KAorICAgICAgYnl0ZXMoMHg3OCwgMHg1NiwgMHgzNCwgMHgxMiwgMHhmMCwgMHhkZSwgMHhiYywgMHg5YSksCisgICAgICAweDlhYmNkZWYwMTIzNDU2NzhMKTsKKyAgfQorCisgIC8qKiBUZXN0IGRlY29kZVppZ1phZzMyKCkgYW5kIGRlY29kZVppZ1phZzY0KCkuICovCisgIHB1YmxpYyB2b2lkIHRlc3REZWNvZGVaaWdaYWcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRFcXVhbHMoIDAsIENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnMzIoMCkpOworICAgIGFzc2VydEVxdWFscygtMSwgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWczMigxKSk7CisgICAgYXNzZXJ0RXF1YWxzKCAxLCBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzMyKDIpKTsKKyAgICBhc3NlcnRFcXVhbHMoLTIsIENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnMzIoMykpOworICAgIGFzc2VydEVxdWFscygweDNGRkZGRkZGLCBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzMyKDB4N0ZGRkZGRkUpKTsKKyAgICBhc3NlcnRFcXVhbHMoMHhDMDAwMDAwMCwgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWczMigweDdGRkZGRkZGKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4N0ZGRkZGRkYsIENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnMzIoMHhGRkZGRkZGRSkpOworICAgIGFzc2VydEVxdWFscygweDgwMDAwMDAwLCBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzMyKDB4RkZGRkZGRkYpKTsKKworICAgIGFzc2VydEVxdWFscyggMCwgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWc2NCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0xLCBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoIDEsIENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnNjQoMikpOworICAgIGFzc2VydEVxdWFscygtMiwgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWc2NCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4MDAwMDAwMDAzRkZGRkZGRkwsCisgICAgICAgICAgICAgICAgIENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnNjQoMHgwMDAwMDAwMDdGRkZGRkZFTCkpOworICAgIGFzc2VydEVxdWFscygweEZGRkZGRkZGQzAwMDAwMDBMLAorICAgICAgICAgICAgICAgICBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KDB4MDAwMDAwMDA3RkZGRkZGRkwpKTsKKyAgICBhc3NlcnRFcXVhbHMoMHgwMDAwMDAwMDdGRkZGRkZGTCwKKyAgICAgICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWc2NCgweDAwMDAwMDAwRkZGRkZGRkVMKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4RkZGRkZGRkY4MDAwMDAwMEwsCisgICAgICAgICAgICAgICAgIENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnNjQoMHgwMDAwMDAwMEZGRkZGRkZGTCkpOworICAgIGFzc2VydEVxdWFscygweDdGRkZGRkZGRkZGRkZGRkZMLAorICAgICAgICAgICAgICAgICBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KDB4RkZGRkZGRkZGRkZGRkZGRUwpKTsKKyAgICBhc3NlcnRFcXVhbHMoMHg4MDAwMDAwMDAwMDAwMDAwTCwKKyAgICAgICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWc2NCgweEZGRkZGRkZGRkZGRkZGRkZMKSk7CisgIH0KKworICAvKiogVGVzdHMgcmVhZGluZyBhbmQgcGFyc2luZyBhIHdob2xlIG1lc3NhZ2Ugd2l0aCBldmVyeSBmaWVsZCB0eXBlLiAqLworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZFdob2xlTWVzc2FnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsU2V0KCk7CisKKyAgICBieXRlW10gcmF3Qnl0ZXMgPSBtZXNzYWdlLnRvQnl0ZUFycmF5KCk7CisgICAgYXNzZXJ0RXF1YWxzKHJhd0J5dGVzLmxlbmd0aCwgbWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlMiA9IFRlc3RBbGxUeXBlcy5wYXJzZUZyb20ocmF3Qnl0ZXMpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisKKyAgICAvLyBUcnkgZGlmZmVyZW50IGJsb2NrIHNpemVzLgorICAgIGZvciAoaW50IGJsb2NrU2l6ZSA9IDE7IGJsb2NrU2l6ZSA8IDI1NjsgYmxvY2tTaXplICo9IDIpIHsKKyAgICAgIG1lc3NhZ2UyID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbSgKKyAgICAgICAgbmV3IFNtYWxsQmxvY2tJbnB1dFN0cmVhbShyYXdCeXRlcywgYmxvY2tTaXplKSk7CisgICAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworICAgIH0KKyAgfQorCisgIC8qKiBUZXN0cyBza2lwRmllbGQoKS4gKi8KKyAgcHVibGljIHZvaWQgdGVzdFNraXBXaG9sZU1lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIGJ5dGVbXSByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlQXJyYXkoKTsKKworICAgIC8vIENyZWF0ZSB0d28gcGFyYWxsZWwgaW5wdXRzLiAgUGFyc2Ugb25lIGFzIHVua25vd24gZmllbGRzIHdoaWxlIHVzaW5nCisgICAgLy8gc2tpcEZpZWxkKCkgdG8gc2tpcCBlYWNoIGZpZWxkIG9uIHRoZSBvdGhlci4gIEV4cGVjdCB0aGUgc2FtZSB0YWdzLgorICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQxID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShyYXdCeXRlcyk7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dDIgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKHJhd0J5dGVzKTsKKyAgICBVbmtub3duRmllbGRTZXQuQnVpbGRlciB1bmtub3duRmllbGRzID0gVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKTsKKworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpbnQgdGFnID0gaW5wdXQxLnJlYWRUYWcoKTsKKyAgICAgIGFzc2VydEVxdWFscyh0YWcsIGlucHV0Mi5yZWFkVGFnKCkpOworICAgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgdW5rbm93bkZpZWxkcy5tZXJnZUZpZWxkRnJvbSh0YWcsIGlucHV0MSk7CisgICAgICBpbnB1dDIuc2tpcEZpZWxkKHRhZyk7CisgICAgfQorICB9CisKKworICAvKioKKyAgICogVGVzdCB0aGF0IGEgYnVnIGluIHNraXBSYXdCeXRlcygpIGhhcyBiZWVuIGZpeGVkOiAgaWYgdGhlIHNraXAgc2tpcHMKKyAgICogZXhhY3RseSB1cCB0byBhIGxpbWl0LCB0aGlzIHNob3VsZCBub3QgYnJlYWsgdGhpbmdzLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNraXBSYXdCeXRlc0J1ZygpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGVbXSByYXdCeXRlcyA9IG5ldyBieXRlW10geyAxLCAyIH07CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UocmF3Qnl0ZXMpOworCisgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KDEpOworICAgIGlucHV0LnNraXBSYXdCeXRlcygxKTsKKyAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGlucHV0LnJlYWRSYXdCeXRlKCkpOworICB9CisKKyAgLyoqCisgICAqIFRlc3QgdGhhdCBhIGJ1ZyBpbiBza2lwUmF3Qnl0ZXMoKSBoYXMgYmVlbiBmaXhlZDogIGlmIHRoZSBza2lwIHNraXBzCisgICAqIHBhc3QgdGhlIGVuZCBvZiBhIGJ1ZmZlciB3aXRoIGEgbGltaXQgdGhhdCBoYXMgYmVlbiBzZXQgcGFzdCB0aGUgZW5kIG9mCisgICAqIHRoYXQgYnVmZmVyLCB0aGlzIHNob3VsZCBub3QgYnJlYWsgdGhpbmdzLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNraXBSYXdCeXRlc1Bhc3RFbmRPZkJ1ZmZlcldpdGhMaW1pdCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGVbXSByYXdCeXRlcyA9IG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCA1IH07CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoCisgICAgICAgIG5ldyBTbWFsbEJsb2NrSW5wdXRTdHJlYW0ocmF3Qnl0ZXMsIDMpKTsKKworICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdCg0KTsKKyAgICAvLyBJbiBvcmRlciB0byBleHBvc2UgdGhlIGJ1ZyB3ZSBuZWVkIHRvIHJlYWQgYXQgbGVhc3Qgb25lIGJ5dGUgdG8gcHJpbWUgdGhlCisgICAgLy8gYnVmZmVyIGluc2lkZSB0aGUgQ29kZWRJbnB1dFN0cmVhbS4KKyAgICBhc3NlcnRFcXVhbHMoMSwgaW5wdXQucmVhZFJhd0J5dGUoKSk7CisgICAgLy8gU2tpcCB0byB0aGUgZW5kIG9mIHRoZSBsaW1pdC4KKyAgICBpbnB1dC5za2lwUmF3Qnl0ZXMoMyk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKKyAgICBhc3NlcnRFcXVhbHMoNSwgaW5wdXQucmVhZFJhd0J5dGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEh1Z2VCbG9iKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSAxTUIgYmxvYi4KKyAgICBieXRlW10gYmxvYiA9IG5ldyBieXRlWzEgPDwgMjBdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmxvYi5sZW5ndGg7IGkrKykgeworICAgICAgYmxvYltpXSA9IChieXRlKSBpOworICAgIH0KKworICAgIC8vIE1ha2UgYSBtZXNzYWdlIGNvbnRhaW5pbmcgaXQuCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGVzdFV0aWwuc2V0QWxsRmllbGRzKGJ1aWxkZXIpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxCeXRlcyhCeXRlU3RyaW5nLmNvcHlGcm9tKGJsb2IpKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKworICAgIC8vIFNlcmlhbGl6ZSBhbmQgcGFyc2UgaXQuICBNYWtlIHN1cmUgdG8gcGFyc2UgZnJvbSBhbiBJbnB1dFN0cmVhbSwgbm90CisgICAgLy8gZGlyZWN0bHkgZnJvbSBhIEJ5dGVTdHJpbmcsIHNvIHRoYXQgQ29kZWRJbnB1dFN0cmVhbSB1c2VzIGJ1ZmZlcmVkCisgICAgLy8gcmVhZGluZy4KKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZTIgPQorICAgICAgVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShtZXNzYWdlLnRvQnl0ZVN0cmluZygpLm5ld0lucHV0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0T3B0aW9uYWxCeXRlcygpLCBtZXNzYWdlMi5nZXRPcHRpb25hbEJ5dGVzKCkpOworCisgICAgLy8gTWFrZSBzdXJlIGFsbCB0aGUgb3RoZXIgZmllbGRzIHdlcmUgcGFyc2VkIGNvcnJlY3RseS4KKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZTMgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcihtZXNzYWdlMikKKyAgICAgIC5zZXRPcHRpb25hbEJ5dGVzKFRlc3RVdGlsLmdldEFsbFNldCgpLmdldE9wdGlvbmFsQnl0ZXMoKSkKKyAgICAgIC5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldChtZXNzYWdlMyk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZE1hbGljaW91c2x5TGFyZ2VCbG9iKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZy5PdXRwdXQgcmF3T3V0cHV0ID0gQnl0ZVN0cmluZy5uZXdPdXRwdXQoKTsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShyYXdPdXRwdXQpOworCisgICAgaW50IHRhZyA9IFdpcmVGb3JtYXQubWFrZVRhZygxLCBXaXJlRm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKHRhZyk7CisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoMHg3RkZGRkZGRik7CisgICAgb3V0cHV0LndyaXRlUmF3Qnl0ZXMobmV3IGJ5dGVbMzJdKTsgIC8vIFBhZCB3aXRoIGEgZmV3IHJhbmRvbSBieXRlcy4KKyAgICBvdXRwdXQuZmx1c2goKTsKKworICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPSByYXdPdXRwdXQudG9CeXRlU3RyaW5nKCkubmV3Q29kZWRJbnB1dCgpOworICAgIGFzc2VydEVxdWFscyh0YWcsIGlucHV0LnJlYWRUYWcoKSk7CisKKyAgICB0cnkgeworICAgICAgaW5wdXQucmVhZEJ5dGVzKCk7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uISIpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzdWNjZXNzLgorICAgIH0KKyAgfQorCisgIHByaXZhdGUgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgbWFrZVJlY3Vyc2l2ZU1lc3NhZ2UoaW50IGRlcHRoKSB7CisgICAgaWYgKGRlcHRoID09IDApIHsKKyAgICAgIHJldHVybiBUZXN0UmVjdXJzaXZlTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0SSg1KS5idWlsZCgpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRBKG1ha2VSZWN1cnNpdmVNZXNzYWdlKGRlcHRoIC0gMSkpLmJ1aWxkKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydE1lc3NhZ2VEZXB0aChUZXN0UmVjdXJzaXZlTWVzc2FnZSBtZXNzYWdlLCBpbnQgZGVwdGgpIHsKKyAgICBpZiAoZGVwdGggPT0gMCkgeworICAgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNBKCkpOworICAgICAgYXNzZXJ0RXF1YWxzKDUsIG1lc3NhZ2UuZ2V0SSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0EoKSk7CisgICAgICBhc3NlcnRNZXNzYWdlRGVwdGgobWVzc2FnZS5nZXRBKCksIGRlcHRoIC0gMSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1hbGljaW91c1JlY3Vyc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcgZGF0YTEwMCA9IG1ha2VSZWN1cnNpdmVNZXNzYWdlKDEwMCkudG9CeXRlU3RyaW5nKCk7CisgICAgQnl0ZVN0cmluZyBkYXRhMTAxID0gbWFrZVJlY3Vyc2l2ZU1lc3NhZ2UoMTAxKS50b0J5dGVTdHJpbmcoKTsKKworICAgIGFzc2VydE1lc3NhZ2VEZXB0aChUZXN0UmVjdXJzaXZlTWVzc2FnZS5wYXJzZUZyb20oZGF0YTEwMCksIDEwMCk7CisKKyAgICB0cnkgeworICAgICAgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UucGFyc2VGcm9tKGRhdGExMDEpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbiEiKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2Vzcy4KKyAgICB9CisKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gZGF0YTEwMC5uZXdDb2RlZElucHV0KCk7CisgICAgaW5wdXQuc2V0UmVjdXJzaW9uTGltaXQoOCk7CisgICAgdHJ5IHsKKyAgICAgIFRlc3RSZWN1cnNpdmVNZXNzYWdlLnBhcnNlRnJvbShpbnB1dCk7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uISIpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzdWNjZXNzLgorICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBjaGVja1NpemVMaW1pdEV4Y2VlZGVkKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLnNpemVMaW1pdEV4Y2VlZGVkKCkuZ2V0TWVzc2FnZSgpLAorICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTaXplTGltaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZSgKKyAgICAgICAgbmV3IFNtYWxsQmxvY2tJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgIFRlc3RVdGlsLmdldEFsbFNldCgpLnRvQnl0ZVN0cmluZygpLm5ld0lucHV0KCksIDE2KSk7CisgICAgaW5wdXQuc2V0U2l6ZUxpbWl0KDE2KTsKKworICAgIHRyeSB7CisgICAgICBUZXN0QWxsVHlwZXMucGFyc2VGcm9tKGlucHV0KTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24hIik7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICBjaGVja1NpemVMaW1pdEV4Y2VlZGVkKGV4cGVjdGVkKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVzZXRTaXplQ291bnRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKAorICAgICAgICBuZXcgU21hbGxCbG9ja0lucHV0U3RyZWFtKG5ldyBieXRlWzI1Nl0sIDgpKTsKKyAgICBpbnB1dC5zZXRTaXplTGltaXQoMTYpOworICAgIGlucHV0LnJlYWRSYXdCeXRlcygxNik7CisgICAgYXNzZXJ0RXF1YWxzKDE2LCBpbnB1dC5nZXRUb3RhbEJ5dGVzUmVhZCgpKTsKKworICAgIHRyeSB7CisgICAgICBpbnB1dC5yZWFkUmF3Qnl0ZSgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbiEiKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgIGNoZWNrU2l6ZUxpbWl0RXhjZWVkZWQoZXhwZWN0ZWQpOworICAgIH0KKworICAgIGlucHV0LnJlc2V0U2l6ZUNvdW50ZXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgaW5wdXQuZ2V0VG90YWxCeXRlc1JlYWQoKSk7CisgICAgaW5wdXQucmVhZFJhd0J5dGUoKTsgIC8vIE5vIGV4Y2VwdGlvbiB0aHJvd24uCisgICAgaW5wdXQucmVzZXRTaXplQ291bnRlcigpOworICAgIGFzc2VydEVxdWFscygwLCBpbnB1dC5nZXRUb3RhbEJ5dGVzUmVhZCgpKTsKKyAgICBpbnB1dC5yZWFkUmF3Qnl0ZXMoMTYpOworICAgIGFzc2VydEVxdWFscygxNiwgaW5wdXQuZ2V0VG90YWxCeXRlc1JlYWQoKSk7CisgICAgaW5wdXQucmVzZXRTaXplQ291bnRlcigpOworCisgICAgdHJ5IHsKKyAgICAgIGlucHV0LnJlYWRSYXdCeXRlcygxNyk7ICAvLyBIaXRzIGxpbWl0IGFnYWluLgorICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbiEiKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgIGNoZWNrU2l6ZUxpbWl0RXhjZWVkZWQoZXhwZWN0ZWQpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTaXplTGltaXRNdWx0aXBsZU1lc3NhZ2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbMjU2XTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICBieXRlc1tpXSA9IChieXRlKSBpOworICAgIH0KKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZSgKKyAgICAgICAgbmV3IFNtYWxsQmxvY2tJbnB1dFN0cmVhbShieXRlcywgNykpOworICAgIGlucHV0LnNldFNpemVMaW1pdCgxNik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTYgLyAxNjsgaSsrKSB7CisgICAgICBieXRlW10gbWVzc2FnZSA9IGlucHV0LnJlYWRSYXdCeXRlcygxNik7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG1lc3NhZ2UubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGkgKiAxNiArIGosIG1lc3NhZ2Vbal0gJiAweGZmKTsKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygxNiwgaW5wdXQuZ2V0VG90YWxCeXRlc1JlYWQoKSk7CisgICAgICBpbnB1dC5yZXNldFNpemVDb3VudGVyKCk7CisgICAgICBhc3NlcnRFcXVhbHMoMCwgaW5wdXQuZ2V0VG90YWxCeXRlc1JlYWQoKSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFRlc3RzIHRoYXQgaWYgd2UgcmVhZFN0cmluZyBpbnZhbGlkIFVURi04IGJ5dGVzLCBubyBleGNlcHRpb24KKyAgICogaXMgdGhyb3duLiAgSW5zdGVhZCwgdGhlIGludmFsaWQgYnl0ZXMgYXJlIHJlcGxhY2VkIHdpdGggdGhlIFVuaWNvZGUKKyAgICogInJlcGxhY2VtZW50IGNoYXJhY3RlciIgVStGRkZELgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFJlYWRTdHJpbmdJbnZhbGlkVXRmOCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcuT3V0cHV0IHJhd091dHB1dCA9IEJ5dGVTdHJpbmcubmV3T3V0cHV0KCk7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UocmF3T3V0cHV0KTsKKworICAgIGludCB0YWcgPSBXaXJlRm9ybWF0Lm1ha2VUYWcoMSwgV2lyZUZvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0YWcpOworICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKDEpOworICAgIG91dHB1dC53cml0ZVJhd0J5dGVzKG5ldyBieXRlW10geyAoYnl0ZSkgMHg4MCB9KTsKKyAgICBvdXRwdXQuZmx1c2goKTsKKworICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPSByYXdPdXRwdXQudG9CeXRlU3RyaW5nKCkubmV3Q29kZWRJbnB1dCgpOworICAgIGFzc2VydEVxdWFscyh0YWcsIGlucHV0LnJlYWRUYWcoKSk7CisgICAgU3RyaW5nIHRleHQgPSBpbnB1dC5yZWFkU3RyaW5nKCk7CisgICAgYXNzZXJ0RXF1YWxzKDB4ZmZmZCwgdGV4dC5jaGFyQXQoMCkpOworICB9CisKKyAgLyoqCisgICAqIFRlc3RzIHRoYXQgaWYgd2UgcmVhZFN0cmluZ1JlcXVpcmVVdGY4IGludmFsaWQgVVRGLTggYnl0ZXMsIGFuCisgICAqIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZFN0cmluZ1JlcXVpcmVVdGY4SW52YWxpZFV0ZjgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlU3RyaW5nLk91dHB1dCByYXdPdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dCgpOworICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKHJhd091dHB1dCk7CisKKyAgICBpbnQgdGFnID0gV2lyZUZvcm1hdC5tYWtlVGFnKDEsIFdpcmVGb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIodGFnKTsKKyAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigxKTsKKyAgICBvdXRwdXQud3JpdGVSYXdCeXRlcyhuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4ODAgfSk7CisgICAgb3V0cHV0LmZsdXNoKCk7CisKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gcmF3T3V0cHV0LnRvQnl0ZVN0cmluZygpLm5ld0NvZGVkSW5wdXQoKTsKKyAgICBhc3NlcnRFcXVhbHModGFnLCBpbnB1dC5yZWFkVGFnKCkpOworICAgIHRyeSB7CisgICAgICBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIGludmFsaWQgVVRGLTggZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICAgIGFzc2VydEVxdWFscygiUHJvdG9jb2wgbWVzc2FnZSBoYWQgaW52YWxpZCBVVEYtOC4iLCBleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEZyb21TbGljZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGVbXSBieXRlcyA9IGJ5dGVzKDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDkpOworICAgIENvZGVkSW5wdXRTdHJlYW0gaW4gPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGJ5dGVzLCAzLCA1KTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgaW4uZ2V0VG90YWxCeXRlc1JlYWQoKSk7CisgICAgZm9yIChpbnQgaSA9IDM7IGkgPCA4OyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyhpLCBpbi5yZWFkUmF3Qnl0ZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhpIC0gMiwgaW4uZ2V0VG90YWxCeXRlc1JlYWQoKSk7CisgICAgfQorICAgIC8vIGVvZgorICAgIGFzc2VydEVxdWFscygwLCBpbi5yZWFkVGFnKCkpOworICAgIGFzc2VydEVxdWFscyg1LCBpbi5nZXRUb3RhbEJ5dGVzUmVhZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkVGFnKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQW55IHRhZyBudW1iZXIgd2hpY2ggY29ycmVzcG9uZHMgdG8gZmllbGQgbnVtYmVyIHplcm8gaXMgaW52YWxpZCBhbmQKKyAgICAvLyBzaG91bGQgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICB0cnkgeworICAgICAgICBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGJ5dGVzKGkpKS5yZWFkVGFnKCk7CisgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICBhc3NlcnRFcXVhbHMoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uLmludmFsaWRUYWcoKS5nZXRNZXNzYWdlKCksCisgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlYWRCeXRlQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlU3RyaW5nLk91dHB1dCByYXdPdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dCgpOworICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKHJhd091dHB1dCk7CisgICAgLy8gWmVyby1zaXplZCBieXRlcyBmaWVsZC4KKyAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigwKTsKKyAgICAvLyBPbmUgb25lLWJ5dGUgYnl0ZXMgZmllbGQKKyAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigxKTsKKyAgICBvdXRwdXQud3JpdGVSYXdCeXRlcyhuZXcgYnl0ZVtdIHsgKGJ5dGUpIDIzIH0pOworICAgIC8vIEFub3RoZXIgb25lLWJ5dGUgYnl0ZXMgZmllbGQKKyAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigxKTsKKyAgICBvdXRwdXQud3JpdGVSYXdCeXRlcyhuZXcgYnl0ZVtdIHsgKGJ5dGUpIDQ1IH0pOworICAgIC8vIEEgYnl0ZXMgZmllbGQgbGFyZ2UgZW5vdWdoIHRoYXQgd29uJ3QgZml0IGludG8gdGhlIDRLIGJ1ZmZlci4KKyAgICBmaW5hbCBpbnQgYnl0ZXNMZW5ndGggPSAxNiAqIDEwMjQ7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXNMZW5ndGhdOworICAgIGJ5dGVzWzBdID0gKGJ5dGUpIDY3OworICAgIGJ5dGVzW2J5dGVzTGVuZ3RoIC0gMV0gPSAoYnl0ZSkgODk7CisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoYnl0ZXNMZW5ndGgpOworICAgIG91dHB1dC53cml0ZVJhd0J5dGVzKGJ5dGVzKTsKKworICAgIG91dHB1dC5mbHVzaCgpOworICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSByYXdPdXRwdXQudG9CeXRlU3RyaW5nKCkubmV3Q29kZWRJbnB1dCgpOworCisgICAgYnl0ZVtdIHJlc3VsdCA9IGlucHV0U3RyZWFtLnJlYWRCeXRlQXJyYXkoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgcmVzdWx0Lmxlbmd0aCk7CisgICAgcmVzdWx0ID0gaW5wdXRTdHJlYW0ucmVhZEJ5dGVBcnJheSgpOworICAgIGFzc2VydEVxdWFscygxLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDIzLCByZXN1bHRbMF0pOworICAgIHJlc3VsdCA9IGlucHV0U3RyZWFtLnJlYWRCeXRlQXJyYXkoKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSA0NSwgcmVzdWx0WzBdKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUFycmF5KCk7CisgICAgYXNzZXJ0RXF1YWxzKGJ5dGVzTGVuZ3RoLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDY3LCByZXN1bHRbMF0pOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgODksIHJlc3VsdFtieXRlc0xlbmd0aCAtIDFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkQnl0ZUJ1ZmZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcuT3V0cHV0IHJhd091dHB1dCA9IEJ5dGVTdHJpbmcubmV3T3V0cHV0KCk7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UocmF3T3V0cHV0KTsKKyAgICAvLyBaZXJvLXNpemVkIGJ5dGVzIGZpZWxkLgorICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKDApOworICAgIC8vIE9uZSBvbmUtYnl0ZSBieXRlcyBmaWVsZAorICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKDEpOworICAgIG91dHB1dC53cml0ZVJhd0J5dGVzKG5ldyBieXRlW117KGJ5dGUpIDIzfSk7CisgICAgLy8gQW5vdGhlciBvbmUtYnl0ZSBieXRlcyBmaWVsZAorICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKDEpOworICAgIG91dHB1dC53cml0ZVJhd0J5dGVzKG5ldyBieXRlW117KGJ5dGUpIDQ1fSk7CisgICAgLy8gQSBieXRlcyBmaWVsZCBsYXJnZSBlbm91Z2ggdGhhdCB3b24ndCBmaXQgaW50byB0aGUgNEsgYnVmZmVyLgorICAgIGZpbmFsIGludCBieXRlc0xlbmd0aCA9IDE2ICogMTAyNDsKKyAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtieXRlc0xlbmd0aF07CisgICAgYnl0ZXNbMF0gPSAoYnl0ZSkgNjc7CisgICAgYnl0ZXNbYnl0ZXNMZW5ndGggLSAxXSA9IChieXRlKSA4OTsKKyAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMihieXRlc0xlbmd0aCk7CisgICAgb3V0cHV0LndyaXRlUmF3Qnl0ZXMoYnl0ZXMpOworCisgICAgb3V0cHV0LmZsdXNoKCk7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9IHJhd091dHB1dC50b0J5dGVTdHJpbmcoKS5uZXdDb2RlZElucHV0KCk7CisKKyAgICBCeXRlQnVmZmVyIHJlc3VsdCA9IGlucHV0U3RyZWFtLnJlYWRCeXRlQnVmZmVyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIHJlc3VsdC5jYXBhY2l0eSgpKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUJ1ZmZlcigpOworICAgIGFzc2VydEVxdWFscygxLCByZXN1bHQuY2FwYWNpdHkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAyMywgcmVzdWx0LmdldCgpKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUJ1ZmZlcigpOworICAgIGFzc2VydEVxdWFscygxLCByZXN1bHQuY2FwYWNpdHkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSA0NSwgcmVzdWx0LmdldCgpKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUJ1ZmZlcigpOworICAgIGFzc2VydEVxdWFscyhieXRlc0xlbmd0aCwgcmVzdWx0LmNhcGFjaXR5KCkpOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgNjcsIHJlc3VsdC5nZXQoKSk7CisgICAgcmVzdWx0LnBvc2l0aW9uKGJ5dGVzTGVuZ3RoIC0gMSk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSA4OSwgcmVzdWx0LmdldCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkQnl0ZUJ1ZmZlckFsaWFzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVBcnJheVN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShieXRlQXJyYXlTdHJlYW0pOworICAgIC8vIFplcm8tc2l6ZWQgYnl0ZXMgZmllbGQuCisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoMCk7CisgICAgLy8gT25lIG9uZS1ieXRlIGJ5dGVzIGZpZWxkCisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoMSk7CisgICAgb3V0cHV0LndyaXRlUmF3Qnl0ZXMobmV3IGJ5dGVbXXsoYnl0ZSkgMjN9KTsKKyAgICAvLyBBbm90aGVyIG9uZS1ieXRlIGJ5dGVzIGZpZWxkCisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoMSk7CisgICAgb3V0cHV0LndyaXRlUmF3Qnl0ZXMobmV3IGJ5dGVbXXsoYnl0ZSkgNDV9KTsKKyAgICAvLyBBIGJ5dGVzIGZpZWxkIGxhcmdlIGVub3VnaCB0aGF0IHdvbid0IGZpdCBpbnRvIHRoZSA0SyBidWZmZXIuCisgICAgZmluYWwgaW50IGJ5dGVzTGVuZ3RoID0gMTYgKiAxMDI0OworICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW2J5dGVzTGVuZ3RoXTsKKyAgICBieXRlc1swXSA9IChieXRlKSA2NzsKKyAgICBieXRlc1tieXRlc0xlbmd0aCAtIDFdID0gKGJ5dGUpIDg5OworICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKGJ5dGVzTGVuZ3RoKTsKKyAgICBvdXRwdXQud3JpdGVSYXdCeXRlcyhieXRlcyk7CisgICAgb3V0cHV0LmZsdXNoKCk7CisgICAgYnl0ZVtdIGRhdGEgPSBieXRlQXJyYXlTdHJlYW0udG9CeXRlQXJyYXkoKTsKKworICAgIC8vIFdpdGhvdXQgYWxpYXNpbmcKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKTsKKyAgICBCeXRlQnVmZmVyIHJlc3VsdCA9IGlucHV0U3RyZWFtLnJlYWRCeXRlQnVmZmVyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIHJlc3VsdC5jYXBhY2l0eSgpKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUJ1ZmZlcigpOworICAgIGFzc2VydFRydWUocmVzdWx0LmFycmF5KCkgIT0gZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHJlc3VsdC5jYXBhY2l0eSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDIzLCByZXN1bHQuZ2V0KCkpOworICAgIHJlc3VsdCA9IGlucHV0U3RyZWFtLnJlYWRCeXRlQnVmZmVyKCk7CisgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuYXJyYXkoKSAhPSBkYXRhKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcmVzdWx0LmNhcGFjaXR5KCkpOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgNDUsIHJlc3VsdC5nZXQoKSk7CisgICAgcmVzdWx0ID0gaW5wdXRTdHJlYW0ucmVhZEJ5dGVCdWZmZXIoKTsKKyAgICBhc3NlcnRUcnVlKHJlc3VsdC5hcnJheSgpICE9IGRhdGEpOworICAgIGFzc2VydEVxdWFscyhieXRlc0xlbmd0aCwgcmVzdWx0LmNhcGFjaXR5KCkpOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgNjcsIHJlc3VsdC5nZXQoKSk7CisgICAgcmVzdWx0LnBvc2l0aW9uKGJ5dGVzTGVuZ3RoIC0gMSk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSA4OSwgcmVzdWx0LmdldCgpKTsKKworICAgIC8vIEVuYWJsZSBhbGlhc2luZworICAgIGlucHV0U3RyZWFtID0gQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKTsKKyAgICBpbnB1dFN0cmVhbS5lbmFibGVBbGlhc2luZyh0cnVlKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUJ1ZmZlcigpOworICAgIGFzc2VydEVxdWFscygwLCByZXN1bHQuY2FwYWNpdHkoKSk7CisgICAgcmVzdWx0ID0gaW5wdXRTdHJlYW0ucmVhZEJ5dGVCdWZmZXIoKTsKKyAgICBhc3NlcnRUcnVlKHJlc3VsdC5hcnJheSgpID09IGRhdGEpOworICAgIGFzc2VydEVxdWFscygxLCByZXN1bHQuY2FwYWNpdHkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAyMywgcmVzdWx0LmdldCgpKTsKKyAgICByZXN1bHQgPSBpbnB1dFN0cmVhbS5yZWFkQnl0ZUJ1ZmZlcigpOworICAgIGFzc2VydFRydWUocmVzdWx0LmFycmF5KCkgPT0gZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHJlc3VsdC5jYXBhY2l0eSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDQ1LCByZXN1bHQuZ2V0KCkpOworICAgIHJlc3VsdCA9IGlucHV0U3RyZWFtLnJlYWRCeXRlQnVmZmVyKCk7CisgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuYXJyYXkoKSA9PSBkYXRhKTsKKyAgICBhc3NlcnRFcXVhbHMoYnl0ZXNMZW5ndGgsIHJlc3VsdC5jYXBhY2l0eSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDY3LCByZXN1bHQuZ2V0KCkpOworICAgIHJlc3VsdC5wb3NpdGlvbihieXRlc0xlbmd0aCAtIDEpOworICAgIGFzc2VydEVxdWFscygoYnl0ZSkgODksIHJlc3VsdC5nZXQoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGF0aWJsZVR5cGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbG9uZyBkYXRhID0gMHgxMDAwMDAwMDBMOworICAgIEludDY0TWVzc2FnZSBtZXNzYWdlID0gSW50NjRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXREYXRhKGRhdGEpLmJ1aWxkKCk7CisgICAgQnl0ZVN0cmluZyBzZXJpYWxpemVkID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKworICAgIC8vIFRlc3QgaW50NjQobG9uZykgaXMgY29tcGF0aWJsZSB3aXRoIGJvb2woYm9vbGVhbikKKyAgICBCb29sTWVzc2FnZSBtc2cyID0gQm9vbE1lc3NhZ2UucGFyc2VGcm9tKHNlcmlhbGl6ZWQpOworICAgIGFzc2VydFRydWUobXNnMi5nZXREYXRhKCkpOworCisgICAgLy8gVGVzdCBpbnQ2NChsb25nKSBpcyBjb21wYXRpYmxlIHdpdGggaW50MzIoaW50KQorICAgIEludDMyTWVzc2FnZSBtc2czID0gSW50MzJNZXNzYWdlLnBhcnNlRnJvbShzZXJpYWxpemVkKTsKKyAgICBhc3NlcnRFcXVhbHMoKGludCkgZGF0YSwgbXNnMy5nZXREYXRhKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZE91dHB1dFN0cmVhbVRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0NvZGVkT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3ODVjYzkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Db2RlZE91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDQwMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2U7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0U3BhcnNlRW51bTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBVbml0IHRlc3QgZm9yIHtAbGluayBDb2RlZE91dHB1dFN0cmVhbX0uCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGNsYXNzIENvZGVkT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgLyoqCisgICAqIEhlbHBlciB0byBjb25zdHJ1Y3QgYSBieXRlIGFycmF5IGZyb20gYSBidW5jaCBvZiBieXRlcy4gIFRoZSBpbnB1dHMgYXJlCisgICAqIGFjdHVhbGx5IGludHMgc28gdGhhdCBJIGNhbiB1c2UgaGV4IG5vdGF0aW9uIGFuZCBub3QgZ2V0IHN0dXBpZCBlcnJvcnMKKyAgICogYWJvdXQgcHJlY2lzaW9uLgorICAgKi8KKyAgcHJpdmF0ZSBieXRlW10gYnl0ZXMoaW50Li4uIGJ5dGVzQXNJbnRzKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXNBc0ludHMubGVuZ3RoXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzQXNJbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBieXRlc1tpXSA9IChieXRlKSBieXRlc0FzSW50c1tpXTsKKyAgICB9CisgICAgcmV0dXJuIGJ5dGVzOworICB9CisKKyAgLyoqIEFycmF5cy5hc0xpc3QoKSBkb2VzIG5vdCB3b3JrIHdpdGggYXJyYXlzIG9mIHByaW1pdGl2ZXMuICA6KCAqLworICBwcml2YXRlIExpc3Q8Qnl0ZT4gdG9MaXN0KGJ5dGVbXSBieXRlcykgeworICAgIExpc3Q8Qnl0ZT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxCeXRlPigpOworICAgIGZvciAoYnl0ZSBiIDogYnl0ZXMpIHsKKyAgICAgIHJlc3VsdC5hZGQoYik7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0RXF1YWxCeXRlcyhieXRlW10gYSwgYnl0ZVtdIGIpIHsKKyAgICBhc3NlcnRFcXVhbHModG9MaXN0KGEpLCB0b0xpc3QoYikpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gdmFsdWUgdXNpbmcgd3JpdGVSYXdWYXJpbnQzMigpIGFuZCB3cml0ZVJhd1ZhcmludDY0KCkgYW5kCisgICAqIGNoZWNrcyB0aGF0IHRoZSByZXN1bHQgbWF0Y2hlcyB0aGUgZ2l2ZW4gYnl0ZXMuCisgICAqLworICBwcml2YXRlIHZvaWQgYXNzZXJ0V3JpdGVWYXJpbnQoYnl0ZVtdIGRhdGEsIGxvbmcgdmFsdWUpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE9ubHkgZG8gMzItYml0IHdyaXRlIGlmIHRoZSB2YWx1ZSBmaXRzIGluIDMyIGJpdHMuCisgICAgaWYgKCh2YWx1ZSA+Pj4gMzIpID09IDApIHsKKyAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSByYXdPdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShyYXdPdXRwdXQpOworICAgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoKGludCkgdmFsdWUpOworICAgICAgb3V0cHV0LmZsdXNoKCk7CisgICAgICBhc3NlcnRFcXVhbEJ5dGVzKGRhdGEsIHJhd091dHB1dC50b0J5dGVBcnJheSgpKTsKKworICAgICAgLy8gQWxzbyB0cnkgY29tcHV0aW5nIHNpemUuCisgICAgICBhc3NlcnRFcXVhbHMoZGF0YS5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZVJhd1ZhcmludDMyU2l6ZSgoaW50KSB2YWx1ZSkpOworICAgIH0KKworICAgIHsKKyAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSByYXdPdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShyYXdPdXRwdXQpOworICAgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50NjQodmFsdWUpOworICAgICAgb3V0cHV0LmZsdXNoKCk7CisgICAgICBhc3NlcnRFcXVhbEJ5dGVzKGRhdGEsIHJhd091dHB1dC50b0J5dGVBcnJheSgpKTsKKworICAgICAgLy8gQWxzbyB0cnkgY29tcHV0aW5nIHNpemUuCisgICAgICBhc3NlcnRFcXVhbHMoZGF0YS5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uY29tcHV0ZVJhd1ZhcmludDY0U2l6ZSh2YWx1ZSkpOworICAgIH0KKworICAgIC8vIFRyeSBkaWZmZXJlbnQgYmxvY2sgc2l6ZXMuCisgICAgZm9yIChpbnQgYmxvY2tTaXplID0gMTsgYmxvY2tTaXplIDw9IDE2OyBibG9ja1NpemUgKj0gMikgeworICAgICAgLy8gT25seSBkbyAzMi1iaXQgd3JpdGUgaWYgdGhlIHZhbHVlIGZpdHMgaW4gMzIgYml0cy4KKyAgICAgIGlmICgodmFsdWUgPj4+IDMyKSA9PSAwKSB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSByYXdPdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCA9CisgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UocmF3T3V0cHV0LCBibG9ja1NpemUpOworICAgICAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigoaW50KSB2YWx1ZSk7CisgICAgICAgIG91dHB1dC5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbEJ5dGVzKGRhdGEsIHJhd091dHB1dC50b0J5dGVBcnJheSgpKTsKKyAgICAgIH0KKworICAgICAgeworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gcmF3T3V0cHV0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPQorICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKHJhd091dHB1dCwgYmxvY2tTaXplKTsKKyAgICAgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50NjQodmFsdWUpOworICAgICAgICBvdXRwdXQuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxCeXRlcyhkYXRhLCByYXdPdXRwdXQudG9CeXRlQXJyYXkoKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIFRlc3RzIHdyaXRlUmF3VmFyaW50MzIoKSBhbmQgd3JpdGVSYXdWYXJpbnQ2NCgpLiAqLworICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVWYXJpbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRXcml0ZVZhcmludChieXRlcygweDAwKSwgMCk7CisgICAgYXNzZXJ0V3JpdGVWYXJpbnQoYnl0ZXMoMHgwMSksIDEpOworICAgIGFzc2VydFdyaXRlVmFyaW50KGJ5dGVzKDB4N2YpLCAxMjcpOworICAgIC8vIDE0ODgyCisgICAgYXNzZXJ0V3JpdGVWYXJpbnQoYnl0ZXMoMHhhMiwgMHg3NCksICgweDIyIDw8IDApIHwgKDB4NzQgPDwgNykpOworICAgIC8vIDI5NjE0ODg4MzAKKyAgICBhc3NlcnRXcml0ZVZhcmludChieXRlcygweGJlLCAweGY3LCAweDkyLCAweDg0LCAweDBiKSwKKyAgICAgICgweDNlIDw8IDApIHwgKDB4NzcgPDwgNykgfCAoMHgxMiA8PCAxNCkgfCAoMHgwNCA8PCAyMSkgfAorICAgICAgKDB4MGJMIDw8IDI4KSk7CisKKyAgICAvLyA2NC1iaXQKKyAgICAvLyA3MjU2NDU2MTI2CisgICAgYXNzZXJ0V3JpdGVWYXJpbnQoYnl0ZXMoMHhiZSwgMHhmNywgMHg5MiwgMHg4NCwgMHgxYiksCisgICAgICAoMHgzZSA8PCAwKSB8ICgweDc3IDw8IDcpIHwgKDB4MTIgPDwgMTQpIHwgKDB4MDQgPDwgMjEpIHwKKyAgICAgICgweDFiTCA8PCAyOCkpOworICAgIC8vIDQxMjU2MjAyNTgwNzE4MzM2CisgICAgYXNzZXJ0V3JpdGVWYXJpbnQoCisgICAgICBieXRlcygweDgwLCAweGU2LCAweGViLCAweDljLCAweGMzLCAweGM5LCAweGE0LCAweDQ5KSwKKyAgICAgICgweDAwIDw8IDApIHwgKDB4NjYgPDwgNykgfCAoMHg2YiA8PCAxNCkgfCAoMHgxYyA8PCAyMSkgfAorICAgICAgKDB4NDNMIDw8IDI4KSB8ICgweDQ5TCA8PCAzNSkgfCAoMHgyNEwgPDwgNDIpIHwgKDB4NDlMIDw8IDQ5KSk7CisgICAgLy8gMTE5NjQzNzgzMzA5Nzg3MzUxMzEKKyAgICBhc3NlcnRXcml0ZVZhcmludCgKKyAgICAgIGJ5dGVzKDB4OWIsIDB4YTgsIDB4ZjksIDB4YzIsIDB4YmIsIDB4ZDYsIDB4ODAsIDB4ODUsIDB4YTYsIDB4MDEpLAorICAgICAgKDB4MWIgPDwgMCkgfCAoMHgyOCA8PCA3KSB8ICgweDc5IDw8IDE0KSB8ICgweDQyIDw8IDIxKSB8CisgICAgICAoMHgzYkwgPDwgMjgpIHwgKDB4NTZMIDw8IDM1KSB8ICgweDAwTCA8PCA0MikgfAorICAgICAgKDB4MDVMIDw8IDQ5KSB8ICgweDI2TCA8PCA1NikgfCAoMHgwMUwgPDwgNjMpKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZXMgdGhlIGdpdmVuIGJ5dGVzIHVzaW5nIHdyaXRlUmF3TGl0dGxlRW5kaWFuMzIoKSBhbmQgY2hlY2tzCisgICAqIHRoYXQgdGhlIHJlc3VsdCBtYXRjaGVzIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBhc3NlcnRXcml0ZUxpdHRsZUVuZGlhbjMyKGJ5dGVbXSBkYXRhLCBpbnQgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSByYXdPdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UocmF3T3V0cHV0KTsKKyAgICBvdXRwdXQud3JpdGVSYXdMaXR0bGVFbmRpYW4zMih2YWx1ZSk7CisgICAgb3V0cHV0LmZsdXNoKCk7CisgICAgYXNzZXJ0RXF1YWxCeXRlcyhkYXRhLCByYXdPdXRwdXQudG9CeXRlQXJyYXkoKSk7CisKKyAgICAvLyBUcnkgZGlmZmVyZW50IGJsb2NrIHNpemVzLgorICAgIGZvciAoaW50IGJsb2NrU2l6ZSA9IDE7IGJsb2NrU2l6ZSA8PSAxNjsgYmxvY2tTaXplICo9IDIpIHsKKyAgICAgIHJhd091dHB1dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIG91dHB1dCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKHJhd091dHB1dCwgYmxvY2tTaXplKTsKKyAgICAgIG91dHB1dC53cml0ZVJhd0xpdHRsZUVuZGlhbjMyKHZhbHVlKTsKKyAgICAgIG91dHB1dC5mbHVzaCgpOworICAgICAgYXNzZXJ0RXF1YWxCeXRlcyhkYXRhLCByYXdPdXRwdXQudG9CeXRlQXJyYXkoKSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFBhcnNlcyB0aGUgZ2l2ZW4gYnl0ZXMgdXNpbmcgd3JpdGVSYXdMaXR0bGVFbmRpYW42NCgpIGFuZCBjaGVja3MKKyAgICogdGhhdCB0aGUgcmVzdWx0IG1hdGNoZXMgdGhlIGdpdmVuIHZhbHVlLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGFzc2VydFdyaXRlTGl0dGxlRW5kaWFuNjQoYnl0ZVtdIGRhdGEsIGxvbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSByYXdPdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2UocmF3T3V0cHV0KTsKKyAgICBvdXRwdXQud3JpdGVSYXdMaXR0bGVFbmRpYW42NCh2YWx1ZSk7CisgICAgb3V0cHV0LmZsdXNoKCk7CisgICAgYXNzZXJ0RXF1YWxCeXRlcyhkYXRhLCByYXdPdXRwdXQudG9CeXRlQXJyYXkoKSk7CisKKyAgICAvLyBUcnkgZGlmZmVyZW50IGJsb2NrIHNpemVzLgorICAgIGZvciAoaW50IGJsb2NrU2l6ZSA9IDE7IGJsb2NrU2l6ZSA8PSAxNjsgYmxvY2tTaXplICo9IDIpIHsKKyAgICAgIHJhd091dHB1dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIG91dHB1dCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKHJhd091dHB1dCwgYmxvY2tTaXplKTsKKyAgICAgIG91dHB1dC53cml0ZVJhd0xpdHRsZUVuZGlhbjY0KHZhbHVlKTsKKyAgICAgIG91dHB1dC5mbHVzaCgpOworICAgICAgYXNzZXJ0RXF1YWxCeXRlcyhkYXRhLCByYXdPdXRwdXQudG9CeXRlQXJyYXkoKSk7CisgICAgfQorICB9CisKKyAgLyoqIFRlc3RzIHdyaXRlUmF3TGl0dGxlRW5kaWFuMzIoKSBhbmQgd3JpdGVSYXdMaXR0bGVFbmRpYW42NCgpLiAqLworICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVMaXR0bGVFbmRpYW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRXcml0ZUxpdHRsZUVuZGlhbjMyKGJ5dGVzKDB4NzgsIDB4NTYsIDB4MzQsIDB4MTIpLCAweDEyMzQ1Njc4KTsKKyAgICBhc3NlcnRXcml0ZUxpdHRsZUVuZGlhbjMyKGJ5dGVzKDB4ZjAsIDB4ZGUsIDB4YmMsIDB4OWEpLCAweDlhYmNkZWYwKTsKKworICAgIGFzc2VydFdyaXRlTGl0dGxlRW5kaWFuNjQoCisgICAgICBieXRlcygweGYwLCAweGRlLCAweGJjLCAweDlhLCAweDc4LCAweDU2LCAweDM0LCAweDEyKSwKKyAgICAgIDB4MTIzNDU2Nzg5YWJjZGVmMEwpOworICAgIGFzc2VydFdyaXRlTGl0dGxlRW5kaWFuNjQoCisgICAgICBieXRlcygweDc4LCAweDU2LCAweDM0LCAweDEyLCAweGYwLCAweGRlLCAweGJjLCAweDlhKSwKKyAgICAgIDB4OWFiY2RlZjAxMjM0NTY3OEwpOworICB9CisKKyAgLyoqIFRlc3QgZW5jb2RlWmlnWmFnMzIoKSBhbmQgZW5jb2RlWmlnWmFnNjQoKS4gKi8KKyAgcHVibGljIHZvaWQgdGVzdEVuY29kZVppZ1phZygpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEVxdWFscygwLCBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMiggMCkpOworICAgIGFzc2VydEVxdWFscygxLCBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMigtMSkpOworICAgIGFzc2VydEVxdWFscygyLCBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMiggMSkpOworICAgIGFzc2VydEVxdWFscygzLCBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMigtMikpOworICAgIGFzc2VydEVxdWFscygweDdGRkZGRkZFLCBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMigweDNGRkZGRkZGKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4N0ZGRkZGRkYsIENvZGVkT3V0cHV0U3RyZWFtLmVuY29kZVppZ1phZzMyKDB4QzAwMDAwMDApKTsKKyAgICBhc3NlcnRFcXVhbHMoMHhGRkZGRkZGRSwgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnMzIoMHg3RkZGRkZGRikpOworICAgIGFzc2VydEVxdWFscygweEZGRkZGRkZGLCBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMigweDgwMDAwMDAwKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMCwgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoIDApKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoLTEpKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoIDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoLTIpKTsKKyAgICBhc3NlcnRFcXVhbHMoMHgwMDAwMDAwMDdGRkZGRkZFTCwKKyAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoMHgwMDAwMDAwMDNGRkZGRkZGTCkpOworICAgIGFzc2VydEVxdWFscygweDAwMDAwMDAwN0ZGRkZGRkZMLAorICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWc2NCgweEZGRkZGRkZGQzAwMDAwMDBMKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4MDAwMDAwMDBGRkZGRkZGRUwsCisgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmVuY29kZVppZ1phZzY0KDB4MDAwMDAwMDA3RkZGRkZGRkwpKTsKKyAgICBhc3NlcnRFcXVhbHMoMHgwMDAwMDAwMEZGRkZGRkZGTCwKKyAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoMHhGRkZGRkZGRjgwMDAwMDAwTCkpOworICAgIGFzc2VydEVxdWFscygweEZGRkZGRkZGRkZGRkZGRkVMLAorICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWc2NCgweDdGRkZGRkZGRkZGRkZGRkZMKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4RkZGRkZGRkZGRkZGRkZGRkwsCisgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmVuY29kZVppZ1phZzY0KDB4ODAwMDAwMDAwMDAwMDAwMEwpKTsKKworICAgIC8vIFNvbWUgZWFzaWVyLXRvLXZlcmlmeSByb3VuZC10cmlwIHRlc3RzLiAgVGhlIGlucHV0cyAob3RoZXIgdGhhbiAwLCAxLCAtMSkKKyAgICAvLyB3ZXJlIGNob3NlbiBzZW1pLXJhbmRvbWx5IHZpYSBrZXlib2FyZCBiYXNoaW5nLgorICAgIGFzc2VydEVxdWFscygwLAorICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnMzIoQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWczMigwKSkpOworICAgIGFzc2VydEVxdWFscygxLAorICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnMzIoQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWczMigxKSkpOworICAgIGFzc2VydEVxdWFscygtMSwKKyAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmVuY29kZVppZ1phZzMyKENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnMzIoLTEpKSk7CisgICAgYXNzZXJ0RXF1YWxzKDE0OTI3LAorICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnMzIoQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWczMigxNDkyNykpKTsKKyAgICBhc3NlcnRFcXVhbHMoLTM2MTIsCisgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWczMihDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzMyKC0zNjEyKSkpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsCisgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWc2NChDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KDApKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsCisgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWc2NChDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KDEpKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0xLAorICAgICAgQ29kZWRPdXRwdXRTdHJlYW0uZW5jb2RlWmlnWmFnNjQoQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWc2NCgtMSkpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTQ5MjcsCisgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWc2NChDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KDE0OTI3KSkpOworICAgIGFzc2VydEVxdWFscygtMzYxMiwKKyAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmVuY29kZVppZ1phZzY0KENvZGVkSW5wdXRTdHJlYW0uZGVjb2RlWmlnWmFnNjQoLTM2MTIpKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoODU2OTEyMzA0ODAxNDE2TCwKKyAgICAgIENvZGVkT3V0cHV0U3RyZWFtLmVuY29kZVppZ1phZzY0KAorICAgICAgICBDb2RlZElucHV0U3RyZWFtLmRlY29kZVppZ1phZzY0KAorICAgICAgICAgIDg1NjkxMjMwNDgwMTQxNkwpKSk7CisgICAgYXNzZXJ0RXF1YWxzKC03NTEyMzkwNTQzOTU3MTI1NkwsCisgICAgICBDb2RlZE91dHB1dFN0cmVhbS5lbmNvZGVaaWdaYWc2NCgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5kZWNvZGVaaWdaYWc2NCgKKyAgICAgICAgICAtNzUxMjM5MDU0Mzk1NzEyNTZMKSkpOworICB9CisKKyAgLyoqIFRlc3RzIHdyaXRpbmcgYSB3aG9sZSBtZXNzYWdlIHdpdGggZXZlcnkgZmllbGQgdHlwZS4gKi8KKyAgcHVibGljIHZvaWQgdGVzdFdyaXRlV2hvbGVNZXNzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRBbGxTZXQoKTsKKworICAgIGJ5dGVbXSByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlQXJyYXkoKTsKKyAgICBhc3NlcnRFcXVhbEJ5dGVzKFRlc3RVdGlsLmdldEdvbGRlbk1lc3NhZ2UoKS50b0J5dGVBcnJheSgpLCByYXdCeXRlcyk7CisKKyAgICAvLyBUcnkgZGlmZmVyZW50IGJsb2NrIHNpemVzLgorICAgIGZvciAoaW50IGJsb2NrU2l6ZSA9IDE7IGJsb2NrU2l6ZSA8IDI1NjsgYmxvY2tTaXplICo9IDIpIHsKKyAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSByYXdPdXRwdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPQorICAgICAgICBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShyYXdPdXRwdXQsIGJsb2NrU2l6ZSk7CisgICAgICBtZXNzYWdlLndyaXRlVG8ob3V0cHV0KTsKKyAgICAgIG91dHB1dC5mbHVzaCgpOworICAgICAgYXNzZXJ0RXF1YWxCeXRlcyhyYXdCeXRlcywgcmF3T3V0cHV0LnRvQnl0ZUFycmF5KCkpOworICAgIH0KKyAgfQorCisgIC8qKiBUZXN0cyB3cml0aW5nIGEgd2hvbGUgbWVzc2FnZSB3aXRoIGV2ZXJ5IHBhY2tlZCBmaWVsZCB0eXBlLiBFbnN1cmVzIHRoZQorICAgKiB3aXJlIGZvcm1hdCBvZiBwYWNrZWQgZmllbGRzIGlzIGNvbXBhdGlibGUgd2l0aCBDKysuICovCisgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZVdob2xlUGFja2VkRmllbGRzTWVzc2FnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0UGFja2VkU2V0KCk7CisKKyAgICBieXRlW10gcmF3Qnl0ZXMgPSBtZXNzYWdlLnRvQnl0ZUFycmF5KCk7CisgICAgYXNzZXJ0RXF1YWxCeXRlcyhUZXN0VXRpbC5nZXRHb2xkZW5QYWNrZWRGaWVsZHNNZXNzYWdlKCkudG9CeXRlQXJyYXkoKSwKKyAgICAgICAgICAgICAgICAgICAgIHJhd0J5dGVzKTsKKyAgfQorCisgIC8qKiBUZXN0IHdyaXRpbmcgYSBtZXNzYWdlIGNvbnRhaW5pbmcgYSBuZWdhdGl2ZSBlbnVtIHZhbHVlLiBUaGlzIHVzZWQgdG8KKyAgICogZmFpbCBiZWNhdXNlIHRoZSBzaXplIHdhcyBub3QgcHJvcGVybHkgY29tcHV0ZWQgYXMgYSBzaWduLWV4dGVuZGVkIHZhcmludC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZU1lc3NhZ2VXaXRoTmVnYXRpdmVFbnVtVmFsdWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTcGFyc2VFbnVtTWVzc2FnZSBtZXNzYWdlID0gU3BhcnNlRW51bU1lc3NhZ2UubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRTcGFyc2VFbnVtKFRlc3RTcGFyc2VFbnVtLlNQQVJTRV9FKSAuYnVpbGQoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0U3BhcnNlRW51bSgpLmdldE51bWJlcigpIDwgMCk7CisgICAgYnl0ZVtdIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVBcnJheSgpOworICAgIFNwYXJzZUVudW1NZXNzYWdlIG1lc3NhZ2UyID0gU3BhcnNlRW51bU1lc3NhZ2UucGFyc2VGcm9tKHJhd0J5dGVzKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFNwYXJzZUVudW0uU1BBUlNFX0UsIG1lc3NhZ2UyLmdldFNwYXJzZUVudW0oKSk7CisgIH0KKworICAvKiogVGVzdCBnZXRUb3RhbEJ5dGVzV3JpdHRlbigpICovCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRUb3RhbEJ5dGVzV3JpdHRlbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGZpbmFsIGludCBCVUZGRVJfU0laRSA9IDQgKiAxMDI0OworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKEJVRkZFUl9TSVpFKTsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZFN0cmVhbSA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKG91dHB1dFN0cmVhbSk7CisgICAgYnl0ZVtdIHZhbHVlID0gImFiY2RlIi5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMjQ7ICsraSkgeworICAgICAgY29kZWRTdHJlYW0ud3JpdGVSYXdCeXRlcyh2YWx1ZSwgMCwgdmFsdWUubGVuZ3RoKTsKKyAgICB9CisgICAgLy8gTWFrZSBzdXJlIHdlIGhhdmUgd3JpdHRlbiBtb3JlIGJ5dGVzIHRoYW4gdGhlIGJ1ZmZlciBjb3VsZCBob2xkLiBUaGlzIGlzCisgICAgLy8gdG8gbWFrZSB0aGUgdGVzdCBjb21wbGV0ZS4KKyAgICBhc3NlcnRUcnVlKGNvZGVkU3RyZWFtLmdldFRvdGFsQnl0ZXNXcml0dGVuKCkgPiBCVUZGRVJfU0laRSk7CisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLmxlbmd0aCAqIDEwMjQsIGNvZGVkU3RyZWFtLmdldFRvdGFsQnl0ZXNXcml0dGVuKCkpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVUb0J5dGVCdWZmZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgYnVmZmVyU2l6ZSA9IDE2ICogMTAyNDsKKyAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoYnVmZmVyU2l6ZSk7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRTdHJlYW0gPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShidWZmZXIpOworICAgIC8vIFdyaXRlIHJhdyBieXRlcyBpbnRvIHRoZSBCeXRlQnVmZmVyLgorICAgIGZpbmFsIGludCBsZW5ndGgxID0gNTAwMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDE7IGkrKykgeworICAgICAgY29kZWRTdHJlYW0ud3JpdGVSYXdCeXRlKChieXRlKSAxKTsKKyAgICB9CisgICAgZmluYWwgaW50IGxlbmd0aDIgPSA4ICogMTAyNDsKKyAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW2xlbmd0aDJdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoMjsgaSsrKSB7CisgICAgICBkYXRhW2ldID0gKGJ5dGUpIDI7CisgICAgfQorICAgIGNvZGVkU3RyZWFtLndyaXRlUmF3Qnl0ZXMoZGF0YSk7CisgICAgZmluYWwgaW50IGxlbmd0aDMgPSBidWZmZXJTaXplIC0gbGVuZ3RoMSAtIGxlbmd0aDI7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGgzOyBpKyspIHsKKyAgICAgIGNvZGVkU3RyZWFtLndyaXRlUmF3Qnl0ZSgoYnl0ZSkgMyk7CisgICAgfQorICAgIGNvZGVkU3RyZWFtLmZsdXNoKCk7CisgICAgCisgICAgLy8gQ2hlY2sgdGhhdCBkYXRhIGlzIGNvcnJlY3RseSB3cml0dGVuIHRvIHRoZSBCeXRlQnVmZmVyLgorICAgIGFzc2VydEVxdWFscygwLCBidWZmZXIucmVtYWluaW5nKCkpOworICAgIGJ1ZmZlci5mbGlwKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGgxOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMSwgYnVmZmVyLmdldCgpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGgyOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMiwgYnVmZmVyLmdldCgpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGgzOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMywgYnVmZmVyLmdldCgpKTsKKyAgICB9CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUJ5dGVCdWZmZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBieXRlW10gdmFsdWUgPSAiYWJjZGUiLmdldEJ5dGVzKCJVVEYtOCIpOworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRTdHJlYW0gPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShvdXRwdXRTdHJlYW0pOworICAgIEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlciA9IEJ5dGVCdWZmZXIud3JhcCh2YWx1ZSwgMCwgMSk7CisgICAgLy8gVGhpcyB3aWxsIGFjdHVhbGx5IHdyaXRlIDUgYnl0ZXMgaW50byB0aGUgQ29kZWRPdXRwdXRTdHJlYW0gYXMgdGhlCisgICAgLy8gQnl0ZUJ1ZmZlcidzIGNhcGFjaXR5KCkgaXMgNS4KKyAgICBjb2RlZFN0cmVhbS53cml0ZVJhd0J5dGVzKGJ5dGVCdWZmZXIpOworICAgIC8vIFRoZSBhYm92ZSBjYWxsIHNob3VsZG4ndCBhZmZlY3QgdGhlIEJ5dGVCdWZmZXIncyBzdGF0ZS4KKyAgICBhc3NlcnRFcXVhbHMoMCwgYnl0ZUJ1ZmZlci5wb3NpdGlvbigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnl0ZUJ1ZmZlci5saW1pdCgpKTsKKyAgICAKKyAgICAvLyBUaGUgY29ycmVjdCB3YXkgdG8gd3JpdGUgcGFydCBvZiBhbiBhcnJheSB1c2luZyBCeXRlQnVmZmVyLgorICAgIGNvZGVkU3RyZWFtLndyaXRlUmF3Qnl0ZXMoQnl0ZUJ1ZmZlci53cmFwKHZhbHVlLCAyLCAxKS5zbGljZSgpKTsKKyAgICAKKyAgICBjb2RlZFN0cmVhbS5mbHVzaCgpOworICAgIGJ5dGVbXSByZXN1bHQgPSBvdXRwdXRTdHJlYW0udG9CeXRlQXJyYXkoKTsKKyAgICBhc3NlcnRFcXVhbHMoNiwgcmVzdWx0Lmxlbmd0aCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1OyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyh2YWx1ZVtpXSwgcmVzdWx0W2ldKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlWzJdLCByZXN1bHRbNV0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFdyaXRlQnl0ZUFycmF5V2l0aE9mZnNldHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBieXRlW10gZnVsbEFycmF5ID0gYnl0ZXMoMHgxMSwgMHgyMiwgMHgzMywgMHg0NCwgMHg1NSwgMHg2NiwgMHg3NywgMHg4OCk7CisgICAgYnl0ZVtdIGRlc3RpbmF0aW9uID0gbmV3IGJ5dGVbNF07CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRTdHJlYW0gPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShkZXN0aW5hdGlvbik7CisgICAgY29kZWRTdHJlYW0ud3JpdGVCeXRlQXJyYXlOb1RhZyhmdWxsQXJyYXksIDIsIDIpOworICAgIGFzc2VydEVxdWFsQnl0ZXMoYnl0ZXMoMHgwMiwgMHgzMywgMHg0NCwgMHgwMCksIGRlc3RpbmF0aW9uKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgY29kZWRTdHJlYW0uZ2V0VG90YWxCeXRlc1dyaXR0ZW4oKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0RlcHJlY2F0ZWRGaWVsZFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0RlcHJlY2F0ZWRGaWVsZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNzkwNWY3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRGVwcmVjYXRlZEZpZWxkVGVzdC5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQW5ub3RhdGVkRWxlbWVudDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CisvKioKKyAqIFRlc3QgZmllbGQgZGVwcmVjYXRpb24KKyAqIAorICogQGF1dGhvciBiaXJkb0Bnb29nbGUuY29tIChSb2JlcnRvIFNjYXJhbXV6emkpCisgKi8KK3B1YmxpYyBjbGFzcyBEZXByZWNhdGVkRmllbGRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICBwcml2YXRlIFN0cmluZ1tdIGRlcHJlY2F0ZWRHZXR0ZXJOYW1lcyA9IHsKKyAgICAgICJoYXNEZXByZWNhdGVkSW50MzIiLAorICAgICAgImdldERlcHJlY2F0ZWRJbnQzMiJ9OworICAKKyAgcHJpdmF0ZSBTdHJpbmdbXSBkZXByZWNhdGVkQnVpbGRlckdldHRlck5hbWVzID0geworICAgICAgImhhc0RlcHJlY2F0ZWRJbnQzMiIsCisgICAgICAiZ2V0RGVwcmVjYXRlZEludDMyIiwKKyAgICAgICJjbGVhckRlcHJlY2F0ZWRJbnQzMiJ9OworICAKKyAgcHJpdmF0ZSBTdHJpbmdbXSBkZXByZWNhdGVkQnVpbGRlclNldHRlck5hbWVzID0geworICAgICAgInNldERlcHJlY2F0ZWRJbnQzMiJ9OyAKKyAgCisgIHB1YmxpYyB2b2lkIHRlc3REZXByZWNhdGVkRmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDbGFzczw/PiBkZXByZWNhdGVkRmllbGRzID0gVGVzdERlcHJlY2F0ZWRGaWVsZHMuY2xhc3M7CisgICAgQ2xhc3M8Pz4gZGVwcmVjYXRlZEZpZWxkc0J1aWxkZXIgPSBUZXN0RGVwcmVjYXRlZEZpZWxkcy5CdWlsZGVyLmNsYXNzOworICAgIGZvciAoU3RyaW5nIG5hbWUgOiBkZXByZWNhdGVkR2V0dGVyTmFtZXMpIHsKKyAgICAgIE1ldGhvZCBtZXRob2QgPSBkZXByZWNhdGVkRmllbGRzLmdldE1ldGhvZChuYW1lKTsKKyAgICAgIGFzc2VydFRydWUoIk1ldGhvZCAiICsgbmFtZSArICIgc2hvdWxkIGJlIGRlcHJlY2F0ZWQiLAorICAgICAgICAgIGlzRGVwcmVjYXRlZChtZXRob2QpKTsKKyAgICB9CisgICAgZm9yIChTdHJpbmcgbmFtZSA6IGRlcHJlY2F0ZWRCdWlsZGVyR2V0dGVyTmFtZXMpIHsKKyAgICAgIE1ldGhvZCBtZXRob2QgPSBkZXByZWNhdGVkRmllbGRzQnVpbGRlci5nZXRNZXRob2QobmFtZSk7CisgICAgICBhc3NlcnRUcnVlKCJNZXRob2QgIiArIG5hbWUgKyAiIHNob3VsZCBiZSBkZXByZWNhdGVkIiwKKyAgICAgICAgICBpc0RlcHJlY2F0ZWQobWV0aG9kKSk7CisgICAgfQorICAgIGZvciAoU3RyaW5nIG5hbWUgOiBkZXByZWNhdGVkQnVpbGRlclNldHRlck5hbWVzKSB7CisgICAgICBNZXRob2QgbWV0aG9kID0gZGVwcmVjYXRlZEZpZWxkc0J1aWxkZXIuZ2V0TWV0aG9kKG5hbWUsIGludC5jbGFzcyk7CisgICAgICBhc3NlcnRUcnVlKCJNZXRob2QgIiArIG5hbWUgKyAiIHNob3VsZCBiZSBkZXByZWNhdGVkIiwKKyAgICAgICAgICBpc0RlcHJlY2F0ZWQobWV0aG9kKSk7CisgICAgfQorICB9CisgIAorICBwcml2YXRlIGJvb2xlYW4gaXNEZXByZWNhdGVkKEFubm90YXRlZEVsZW1lbnQgYW5ub3RhdGVkKSB7CisgICAgcmV0dXJuIGFubm90YXRlZC5pc0Fubm90YXRpb25QcmVzZW50KERlcHJlY2F0ZWQuY2xhc3MpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EZXNjcmlwdG9yc1Rlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0Rlc2NyaXB0b3JzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1ODMyYTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EZXNjcmlwdG9yc1Rlc3QuamF2YQpAQCAtMCwwICsxLDc0MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5EZXNjcmlwdG9yUHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkVudW1EZXNjcmlwdG9yUHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmllbGREZXNjcmlwdG9yUHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVEZXNjcmlwdG9yUHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLlNlcnZpY2VEZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvcjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydDsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW07CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFNlcnZpY2U7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnM7CisKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFVuaXQgdGVzdCBmb3Ige0BsaW5rIERlc2NyaXB0b3JzfS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgY2xhc3MgRGVzY3JpcHRvcnNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgYnVnIHdoZXJlIHJlZmVyZW5jaW5nIGEgRmllbGREZXNjcmlwdG9yLlR5cGUgdmFsdWUKKyAgLy8gYmVmb3JlIGEgRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSB2YWx1ZSB3b3VsZCB5aWVsZCBhCisgIC8vIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvci4KKyAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdCBTVEFUSUNfSU5JVF9URVNUID0gRmllbGREZXNjcmlwdG9yLlR5cGUuQk9PTDsKKworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGRUeXBlRW51bU1hcHBpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRFcXVhbHMoRmllbGREZXNjcmlwdG9yLlR5cGUudmFsdWVzKCkubGVuZ3RoLAorICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90by5UeXBlLnZhbHVlcygpLmxlbmd0aCk7CisgICAgZm9yIChGaWVsZERlc2NyaXB0b3IuVHlwZSB0eXBlIDogRmllbGREZXNjcmlwdG9yLlR5cGUudmFsdWVzKCkpIHsKKyAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgcHJvdG9UeXBlID0gdHlwZS50b1Byb3RvKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIlRZUEVfIiArIHR5cGUubmFtZSgpLCBwcm90b1R5cGUubmFtZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyh0eXBlLCBGaWVsZERlc2NyaXB0b3IuVHlwZS52YWx1ZU9mKHByb3RvVHlwZSkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RGaWxlRGVzY3JpcHRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGVEZXNjcmlwdG9yIGZpbGUgPSBVbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKTsKKworICAgIGFzc2VydEVxdWFscygiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvIiwgZmlsZS5nZXROYW1lKCkpOworICAgIGFzc2VydEVxdWFscygicHJvdG9idWZfdW5pdHRlc3QiLCBmaWxlLmdldFBhY2thZ2UoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoIlVuaXR0ZXN0UHJvdG8iLCBmaWxlLmdldE9wdGlvbnMoKS5nZXRKYXZhT3V0ZXJDbGFzc25hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iLAorICAgICAgICAgICAgICAgICBmaWxlLnRvUHJvdG8oKS5nZXROYW1lKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoVW5pdHRlc3RJbXBvcnQuZ2V0RGVzY3JpcHRvcigpKSwKKyAgICAgICAgICAgICAgICAgZmlsZS5nZXREZXBlbmRlbmNpZXMoKSk7CisKKyAgICBEZXNjcmlwdG9yIG1lc3NhZ2VUeXBlID0gVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZVR5cGUsIGZpbGUuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZVR5cGUsIGZpbGUuZmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJUZXN0QWxsVHlwZXMiKSk7CisgICAgYXNzZXJ0TnVsbChmaWxlLmZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiTm9TdWNoVHlwZSIpKTsKKyAgICBhc3NlcnROdWxsKGZpbGUuZmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMiKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLmdldE1lc3NhZ2VUeXBlcygpLnNpemUoKTsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMoaSwgZmlsZS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoaSkuZ2V0SW5kZXgoKSk7CisgICAgfQorCisgICAgRW51bURlc2NyaXB0b3IgZW51bVR5cGUgPSBGb3JlaWduRW51bS5nZXREZXNjcmlwdG9yKCk7CisgICAgYXNzZXJ0RXF1YWxzKGVudW1UeXBlLCBmaWxlLmdldEVudW1UeXBlcygpLmdldCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKGVudW1UeXBlLCBmaWxlLmZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9yZWlnbkVudW0iKSk7CisgICAgYXNzZXJ0TnVsbChmaWxlLmZpbmRFbnVtVHlwZUJ5TmFtZSgiTm9TdWNoVHlwZSIpKTsKKyAgICBhc3NlcnROdWxsKGZpbGUuZmluZEVudW1UeXBlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSIpKTsKKyAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChJbXBvcnRFbnVtLmdldERlc2NyaXB0b3IoKSksCisgICAgICAgICAgICAgICAgIFVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLmdldEVudW1UeXBlcygpLnNpemUoKTsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMoaSwgZmlsZS5nZXRFbnVtVHlwZXMoKS5nZXQoaSkuZ2V0SW5kZXgoKSk7CisgICAgfQorCisgICAgU2VydmljZURlc2NyaXB0b3Igc2VydmljZSA9IFRlc3RTZXJ2aWNlLmdldERlc2NyaXB0b3IoKTsKKyAgICBhc3NlcnRFcXVhbHMoc2VydmljZSwgZmlsZS5nZXRTZXJ2aWNlcygpLmdldCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKHNlcnZpY2UsIGZpbGUuZmluZFNlcnZpY2VCeU5hbWUoIlRlc3RTZXJ2aWNlIikpOworICAgIGFzc2VydE51bGwoZmlsZS5maW5kU2VydmljZUJ5TmFtZSgiTm9TdWNoVHlwZSIpKTsKKyAgICBhc3NlcnROdWxsKGZpbGUuZmluZFNlcnZpY2VCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTZXJ2aWNlIikpOworICAgIGFzc2VydEVxdWFscyhDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKSwKKyAgICAgICAgICAgICAgICAgVW5pdHRlc3RJbXBvcnQuZ2V0RGVzY3JpcHRvcigpLmdldFNlcnZpY2VzKCkpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS5nZXRTZXJ2aWNlcygpLnNpemUoKTsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMoaSwgZmlsZS5nZXRTZXJ2aWNlcygpLmdldChpKS5nZXRJbmRleCgpKTsKKyAgICB9CisKKyAgICBGaWVsZERlc2NyaXB0b3IgZXh0ZW5zaW9uID0KKyAgICAgIFVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbnQzMkV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4dGVuc2lvbiwgZmlsZS5nZXRFeHRlbnNpb25zKCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMoZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICBmaWxlLmZpbmRFeHRlbnNpb25CeU5hbWUoIm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiIpKTsKKyAgICBhc3NlcnROdWxsKGZpbGUuZmluZEV4dGVuc2lvbkJ5TmFtZSgibm9fc3VjaF9leHQiKSk7CisgICAgYXNzZXJ0TnVsbChmaWxlLmZpbmRFeHRlbnNpb25CeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uIikpOworICAgIGFzc2VydEVxdWFscyhDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKSwKKyAgICAgICAgICAgICAgICAgVW5pdHRlc3RJbXBvcnQuZ2V0RGVzY3JpcHRvcigpLmdldEV4dGVuc2lvbnMoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLmdldEV4dGVuc2lvbnMoKS5zaXplKCk7IGkrKykgeworICAgICAgYXNzZXJ0RXF1YWxzKGksIGZpbGUuZ2V0RXh0ZW5zaW9ucygpLmdldChpKS5nZXRJbmRleCgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RGVzY3JpcHRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIERlc2NyaXB0b3IgbWVzc2FnZVR5cGUgPSBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpOworICAgIERlc2NyaXB0b3IgbmVzdGVkVHlwZSA9IFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlc2NyaXB0b3IoKTsKKworICAgIGFzc2VydEVxdWFscygiVGVzdEFsbFR5cGVzIiwgbWVzc2FnZVR5cGUuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyIsIG1lc3NhZ2VUeXBlLmdldEZ1bGxOYW1lKCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKSwgbWVzc2FnZVR5cGUuZ2V0RmlsZSgpKTsKKyAgICBhc3NlcnROdWxsKG1lc3NhZ2VUeXBlLmdldENvbnRhaW5pbmdUeXBlKCkpOworICAgIGFzc2VydEVxdWFscyhEZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICBtZXNzYWdlVHlwZS5nZXRPcHRpb25zKCkpOworICAgIGFzc2VydEVxdWFscygiVGVzdEFsbFR5cGVzIiwgbWVzc2FnZVR5cGUudG9Qcm90bygpLmdldE5hbWUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoIk5lc3RlZE1lc3NhZ2UiLCBuZXN0ZWRUeXBlLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSIsCisgICAgICAgICAgICAgICAgIG5lc3RlZFR5cGUuZ2V0RnVsbE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLCBuZXN0ZWRUeXBlLmdldEZpbGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2VUeXBlLCBuZXN0ZWRUeXBlLmdldENvbnRhaW5pbmdUeXBlKCkpOworCisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gbWVzc2FnZVR5cGUuZ2V0RmllbGRzKCkuZ2V0KDApOworICAgIGFzc2VydEVxdWFscygib3B0aW9uYWxfaW50MzIiLCBmaWVsZC5nZXROYW1lKCkpOworICAgIGFzc2VydEVxdWFscyhmaWVsZCwgbWVzc2FnZVR5cGUuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpKTsKKyAgICBhc3NlcnROdWxsKG1lc3NhZ2VUeXBlLmZpbmRGaWVsZEJ5TmFtZSgibm9fc3VjaF9maWVsZCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoZmllbGQsIG1lc3NhZ2VUeXBlLmZpbmRGaWVsZEJ5TnVtYmVyKDEpKTsKKyAgICBhc3NlcnROdWxsKG1lc3NhZ2VUeXBlLmZpbmRGaWVsZEJ5TnVtYmVyKDU3MTI4MykpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZVR5cGUuZ2V0RmllbGRzKCkuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyhpLCBtZXNzYWdlVHlwZS5nZXRGaWVsZHMoKS5nZXQoaSkuZ2V0SW5kZXgoKSk7CisgICAgfQorCisgICAgYXNzZXJ0RXF1YWxzKG5lc3RlZFR5cGUsIG1lc3NhZ2VUeXBlLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMobmVzdGVkVHlwZSwgbWVzc2FnZVR5cGUuZmluZE5lc3RlZFR5cGVCeU5hbWUoIk5lc3RlZE1lc3NhZ2UiKSk7CisgICAgYXNzZXJ0TnVsbChtZXNzYWdlVHlwZS5maW5kTmVzdGVkVHlwZUJ5TmFtZSgiTm9TdWNoVHlwZSIpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VUeXBlLmdldE5lc3RlZFR5cGVzKCkuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyhpLCBtZXNzYWdlVHlwZS5nZXROZXN0ZWRUeXBlcygpLmdldChpKS5nZXRJbmRleCgpKTsKKyAgICB9CisKKyAgICBFbnVtRGVzY3JpcHRvciBlbnVtVHlwZSA9IFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmdldERlc2NyaXB0b3IoKTsKKyAgICBhc3NlcnRFcXVhbHMoZW51bVR5cGUsIG1lc3NhZ2VUeXBlLmdldEVudW1UeXBlcygpLmdldCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKGVudW1UeXBlLCBtZXNzYWdlVHlwZS5maW5kRW51bVR5cGVCeU5hbWUoIk5lc3RlZEVudW0iKSk7CisgICAgYXNzZXJ0TnVsbChtZXNzYWdlVHlwZS5maW5kRW51bVR5cGVCeU5hbWUoIk5vU3VjaFR5cGUiKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlVHlwZS5nZXRFbnVtVHlwZXMoKS5zaXplKCk7IGkrKykgeworICAgICAgYXNzZXJ0RXF1YWxzKGksIG1lc3NhZ2VUeXBlLmdldEVudW1UeXBlcygpLmdldChpKS5nZXRJbmRleCgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGREZXNjcmlwdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGVzY3JpcHRvciBtZXNzYWdlVHlwZSA9IFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgRmllbGREZXNjcmlwdG9yIHByaW1pdGl2ZUZpZWxkID0KKyAgICAgIG1lc3NhZ2VUeXBlLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50MzIiKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgZW51bUZpZWxkID0KKyAgICAgIG1lc3NhZ2VUeXBlLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX2VudW0iKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgbWVzc2FnZUZpZWxkID0KKyAgICAgIG1lc3NhZ2VUeXBlLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIik7CisgICAgRmllbGREZXNjcmlwdG9yIGNvcmRGaWVsZCA9CisgICAgICBtZXNzYWdlVHlwZS5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2NvcmQiKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgZXh0ZW5zaW9uID0KKyAgICAgIFVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbnQzMkV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCk7CisgICAgRmllbGREZXNjcmlwdG9yIG5lc3RlZEV4dGVuc2lvbiA9IFRlc3RSZXF1aXJlZC5zaW5nbGUuZ2V0RGVzY3JpcHRvcigpOworCisgICAgYXNzZXJ0RXF1YWxzKCJvcHRpb25hbF9pbnQzMiIsIHByaW1pdGl2ZUZpZWxkLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMub3B0aW9uYWxfaW50MzIiLAorICAgICAgICAgICAgICAgICBwcmltaXRpdmVGaWVsZC5nZXRGdWxsTmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcHJpbWl0aXZlRmllbGQuZ2V0TnVtYmVyKCkpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlVHlwZSwgcHJpbWl0aXZlRmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLCBwcmltaXRpdmVGaWVsZC5nZXRGaWxlKCkpOworICAgIGFzc2VydEVxdWFscyhGaWVsZERlc2NyaXB0b3IuVHlwZS5JTlQzMiwgcHJpbWl0aXZlRmllbGQuZ2V0VHlwZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLklOVCwgcHJpbWl0aXZlRmllbGQuZ2V0SmF2YVR5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKERlc2NyaXB0b3JQcm90b3MuRmllbGRPcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICBwcmltaXRpdmVGaWVsZC5nZXRPcHRpb25zKCkpOworICAgIGFzc2VydEZhbHNlKHByaW1pdGl2ZUZpZWxkLmlzRXh0ZW5zaW9uKCkpOworICAgIGFzc2VydEVxdWFscygib3B0aW9uYWxfaW50MzIiLCBwcmltaXRpdmVGaWVsZC50b1Byb3RvKCkuZ2V0TmFtZSgpKTsKKworICAgIGFzc2VydEVxdWFscygib3B0aW9uYWxfbmVzdGVkX2VudW0iLCBlbnVtRmllbGQuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRmllbGREZXNjcmlwdG9yLlR5cGUuRU5VTSwgZW51bUZpZWxkLmdldFR5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5FTlVNLCBlbnVtRmllbGQuZ2V0SmF2YVR5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgZW51bUZpZWxkLmdldEVudW1UeXBlKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiLCBtZXNzYWdlRmllbGQuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRmllbGREZXNjcmlwdG9yLlR5cGUuTUVTU0FHRSwgbWVzc2FnZUZpZWxkLmdldFR5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5NRVNTQUdFLCBtZXNzYWdlRmllbGQuZ2V0SmF2YVR5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZvcmVpZ25NZXNzYWdlLmdldERlc2NyaXB0b3IoKSwgbWVzc2FnZUZpZWxkLmdldE1lc3NhZ2VUeXBlKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKCJvcHRpb25hbF9jb3JkIiwgY29yZEZpZWxkLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZpZWxkRGVzY3JpcHRvci5UeXBlLlNUUklORywgY29yZEZpZWxkLmdldFR5cGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZS5TVFJJTkcsIGNvcmRGaWVsZC5nZXRKYXZhVHlwZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRGVzY3JpcHRvclByb3Rvcy5GaWVsZE9wdGlvbnMuQ1R5cGUuQ09SRCwKKyAgICAgICAgICAgICAgICAgY29yZEZpZWxkLmdldE9wdGlvbnMoKS5nZXRDdHlwZSgpKTsKKworICAgIGFzc2VydEVxdWFscygib3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uIiwgZXh0ZW5zaW9uLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJwcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbnQzMl9leHRlbnNpb24iLAorICAgICAgICAgICAgICAgICBleHRlbnNpb24uZ2V0RnVsbE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGV4dGVuc2lvbi5nZXROdW1iZXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxFeHRlbnNpb25zLmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmdldENvbnRhaW5pbmdUeXBlKCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKSwgZXh0ZW5zaW9uLmdldEZpbGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZpZWxkRGVzY3JpcHRvci5UeXBlLklOVDMyLCBleHRlbnNpb24uZ2V0VHlwZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRmllbGREZXNjcmlwdG9yLkphdmFUeXBlLklOVCwgZXh0ZW5zaW9uLmdldEphdmFUeXBlKCkpOworICAgIGFzc2VydEVxdWFscyhEZXNjcmlwdG9yUHJvdG9zLkZpZWxkT3B0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmdldE9wdGlvbnMoKSk7CisgICAgYXNzZXJ0VHJ1ZShleHRlbnNpb24uaXNFeHRlbnNpb24oKSk7CisgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGV4dGVuc2lvbi5nZXRFeHRlbnNpb25TY29wZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoIm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiIsIGV4dGVuc2lvbi50b1Byb3RvKCkuZ2V0TmFtZSgpKTsKKworICAgIGFzc2VydEVxdWFscygic2luZ2xlIiwgbmVzdGVkRXh0ZW5zaW9uLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQuc2luZ2xlIiwKKyAgICAgICAgICAgICAgICAgbmVzdGVkRXh0ZW5zaW9uLmdldEZ1bGxOYW1lKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0UmVxdWlyZWQuZ2V0RGVzY3JpcHRvcigpLAorICAgICAgICAgICAgICAgICBuZXN0ZWRFeHRlbnNpb24uZ2V0RXh0ZW5zaW9uU2NvcGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGREZXNjcmlwdG9yTGFiZWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWVsZERlc2NyaXB0b3IgcmVxdWlyZWRGaWVsZCA9CisgICAgICBUZXN0UmVxdWlyZWQuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgiYSIpOworICAgIEZpZWxkRGVzY3JpcHRvciBvcHRpb25hbEZpZWxkID0KKyAgICAgIFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpOworICAgIEZpZWxkRGVzY3JpcHRvciByZXBlYXRlZEZpZWxkID0KKyAgICAgIFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpOworCisgICAgYXNzZXJ0VHJ1ZShyZXF1aXJlZEZpZWxkLmlzUmVxdWlyZWQoKSk7CisgICAgYXNzZXJ0RmFsc2UocmVxdWlyZWRGaWVsZC5pc1JlcGVhdGVkKCkpOworICAgIGFzc2VydEZhbHNlKG9wdGlvbmFsRmllbGQuaXNSZXF1aXJlZCgpKTsKKyAgICBhc3NlcnRGYWxzZShvcHRpb25hbEZpZWxkLmlzUmVwZWF0ZWQoKSk7CisgICAgYXNzZXJ0RmFsc2UocmVwZWF0ZWRGaWVsZC5pc1JlcXVpcmVkKCkpOworICAgIGFzc2VydFRydWUocmVwZWF0ZWRGaWVsZC5pc1JlcGVhdGVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEZpZWxkRGVzY3JpcHRvckRlZmF1bHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEZXNjcmlwdG9yIGQgPSBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpOworICAgIGFzc2VydEZhbHNlKGQuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpLmhhc0RlZmF1bHRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgZC5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ludDMyIikuZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgIGFzc2VydFRydWUoZC5maW5kRmllbGRCeU5hbWUoImRlZmF1bHRfaW50MzIiKS5oYXNEZWZhdWx0VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQxLCBkLmZpbmRGaWVsZEJ5TmFtZSgiZGVmYXVsdF9pbnQzMiIpLmdldERlZmF1bHRWYWx1ZSgpKTsKKworICAgIGQgPSBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMuZ2V0RGVzY3JpcHRvcigpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgIEJ5dGVTdHJpbmcuY29weUZyb20oCisgICAgICAgICJcMFwwMDFcMDA3XGJcZlxuXHJcdFwwMTNcXFwnXCJcdTAwZmUiLmdldEJ5dGVzKCJJU08tODg1OS0xIikpLAorICAgICAgZC5maW5kRmllbGRCeU5hbWUoImVzY2FwZWRfYnl0ZXMiKS5nZXREZWZhdWx0VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0xLCBkLmZpbmRGaWVsZEJ5TmFtZSgibGFyZ2VfdWludDMyIikuZ2V0RGVmYXVsdFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygtMUwsIGQuZmluZEZpZWxkQnlOYW1lKCJsYXJnZV91aW50NjQiKS5nZXREZWZhdWx0VmFsdWUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RW51bURlc2NyaXB0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFbnVtRGVzY3JpcHRvciBlbnVtVHlwZSA9IEZvcmVpZ25FbnVtLmdldERlc2NyaXB0b3IoKTsKKyAgICBFbnVtRGVzY3JpcHRvciBuZXN0ZWRUeXBlID0gVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZ2V0RGVzY3JpcHRvcigpOworCisgICAgYXNzZXJ0RXF1YWxzKCJGb3JlaWduRW51bSIsIGVudW1UeXBlLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSIsIGVudW1UeXBlLmdldEZ1bGxOYW1lKCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKSwgZW51bVR5cGUuZ2V0RmlsZSgpKTsKKyAgICBhc3NlcnROdWxsKGVudW1UeXBlLmdldENvbnRhaW5pbmdUeXBlKCkpOworICAgIGFzc2VydEVxdWFscyhEZXNjcmlwdG9yUHJvdG9zLkVudW1PcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICBlbnVtVHlwZS5nZXRPcHRpb25zKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKCJOZXN0ZWRFbnVtIiwgbmVzdGVkVHlwZS5nZXROYW1lKCkpOworICAgIGFzc2VydEVxdWFscygicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0iLAorICAgICAgICAgICAgICAgICBuZXN0ZWRUeXBlLmdldEZ1bGxOYW1lKCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKSwgbmVzdGVkVHlwZS5nZXRGaWxlKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLCBuZXN0ZWRUeXBlLmdldENvbnRhaW5pbmdUeXBlKCkpOworCisgICAgRW51bVZhbHVlRGVzY3JpcHRvciB2YWx1ZSA9IEZvcmVpZ25FbnVtLkZPUkVJR05fRk9PLmdldFZhbHVlRGVzY3JpcHRvcigpOworICAgIGFzc2VydEVxdWFscyh2YWx1ZSwgZW51bVR5cGUuZ2V0VmFsdWVzKCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMoIkZPUkVJR05fRk9PIiwgdmFsdWUuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoIkZPUkVJR05fRk9PIiwgdmFsdWUudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIHZhbHVlLmdldE51bWJlcigpKTsKKyAgICBhc3NlcnRFcXVhbHModmFsdWUsIGVudW1UeXBlLmZpbmRWYWx1ZUJ5TmFtZSgiRk9SRUlHTl9GT08iKSk7CisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBlbnVtVHlwZS5maW5kVmFsdWVCeU51bWJlcig0KSk7CisgICAgYXNzZXJ0TnVsbChlbnVtVHlwZS5maW5kVmFsdWVCeU5hbWUoIk5PX1NVQ0hfVkFMVUUiKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtVHlwZS5nZXRWYWx1ZXMoKS5zaXplKCk7IGkrKykgeworICAgICAgYXNzZXJ0RXF1YWxzKGksIGVudW1UeXBlLmdldFZhbHVlcygpLmdldChpKS5nZXRJbmRleCgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2VydmljZURlc2NyaXB0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTZXJ2aWNlRGVzY3JpcHRvciBzZXJ2aWNlID0gVGVzdFNlcnZpY2UuZ2V0RGVzY3JpcHRvcigpOworCisgICAgYXNzZXJ0RXF1YWxzKCJUZXN0U2VydmljZSIsIHNlcnZpY2UuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTZXJ2aWNlIiwgc2VydmljZS5nZXRGdWxsTmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCksIHNlcnZpY2UuZ2V0RmlsZSgpKTsKKworCisgICAgTWV0aG9kRGVzY3JpcHRvciBmb29NZXRob2QgPSBzZXJ2aWNlLmdldE1ldGhvZHMoKS5nZXQoMCk7CisgICAgYXNzZXJ0RXF1YWxzKCJGb28iLCBmb29NZXRob2QuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0LmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgZm9vTWV0aG9kLmdldElucHV0VHlwZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZS5nZXREZXNjcmlwdG9yKCksCisgICAgICAgICAgICAgICAgIGZvb01ldGhvZC5nZXRPdXRwdXRUeXBlKCkpOworICAgIGFzc2VydEVxdWFscyhmb29NZXRob2QsIHNlcnZpY2UuZmluZE1ldGhvZEJ5TmFtZSgiRm9vIikpOworCisgICAgTWV0aG9kRGVzY3JpcHRvciBiYXJNZXRob2QgPSBzZXJ2aWNlLmdldE1ldGhvZHMoKS5nZXQoMSk7CisgICAgYXNzZXJ0RXF1YWxzKCJCYXIiLCBiYXJNZXRob2QuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0LmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgYmFyTWV0aG9kLmdldElucHV0VHlwZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZS5nZXREZXNjcmlwdG9yKCksCisgICAgICAgICAgICAgICAgIGJhck1ldGhvZC5nZXRPdXRwdXRUeXBlKCkpOworICAgIGFzc2VydEVxdWFscyhiYXJNZXRob2QsIHNlcnZpY2UuZmluZE1ldGhvZEJ5TmFtZSgiQmFyIikpOworCisgICAgYXNzZXJ0TnVsbChzZXJ2aWNlLmZpbmRNZXRob2RCeU5hbWUoIk5vU3VjaE1ldGhvZCIpKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VydmljZS5nZXRNZXRob2RzKCkuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyhpLCBzZXJ2aWNlLmdldE1ldGhvZHMoKS5nZXQoaSkuZ2V0SW5kZXgoKSk7CisgICAgfQorICB9CisKKworICBwdWJsaWMgdm9pZCB0ZXN0Q3VzdG9tT3B0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEdldCB0aGUgZGVzY3JpcHRvciBpbmRpcmVjdGx5IGZyb20gYSBkZXBlbmRlbnQgcHJvdG8gY2xhc3MuIFRoaXMgaXMgdG8KKyAgICAvLyBlbnN1cmUgdGhhdCB3aGVuIGEgcHJvdG8gY2xhc3MgaXMgbG9hZGVkLCBjdXN0b20gb3B0aW9ucyBkZWZpbmVkIGluIGl0cworICAgIC8vIGRlcGVuZGVuY2llcyBhcmUgYWxzbyBwcm9wZXJseSBpbml0aWFsaXplZC4KKyAgICBEZXNjcmlwdG9yIGRlc2NyaXB0b3IgPQorICAgICAgICBUZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyLmdldERlc2NyaXB0b3IoKQorICAgICAgICAuZmluZEZpZWxkQnlOYW1lKCJmaWVsZCIpLmdldE1lc3NhZ2VUeXBlKCk7CisKKyAgICBhc3NlcnRUcnVlKAorICAgICAgZGVzY3JpcHRvci5nZXRPcHRpb25zKCkuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5tZXNzYWdlT3B0MSkpOworICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnZhbHVlT2YoLTU2KSwKKyAgICAgIGRlc2NyaXB0b3IuZ2V0T3B0aW9ucygpLmdldEV4dGVuc2lvbihVbml0dGVzdEN1c3RvbU9wdGlvbnMubWVzc2FnZU9wdDEpKTsKKworICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJmaWVsZDEiKTsKKyAgICBhc3NlcnROb3ROdWxsKGZpZWxkKTsKKworICAgIGFzc2VydFRydWUoCisgICAgICBmaWVsZC5nZXRPcHRpb25zKCkuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5maWVsZE9wdDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoTG9uZy52YWx1ZU9mKDg3NjU0MzIxMDlMKSwKKyAgICAgIGZpZWxkLmdldE9wdGlvbnMoKS5nZXRFeHRlbnNpb24oVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpZWxkT3B0MSkpOworCisgICAgRW51bURlc2NyaXB0b3IgZW51bVR5cGUgPQorICAgICAgVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuQW5FbnVtLmdldERlc2NyaXB0b3IoKTsKKworICAgIGFzc2VydFRydWUoCisgICAgICBlbnVtVHlwZS5nZXRPcHRpb25zKCkuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtT3B0MSkpOworICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnZhbHVlT2YoLTc4OSksCisgICAgICBlbnVtVHlwZS5nZXRPcHRpb25zKCkuZ2V0RXh0ZW5zaW9uKFVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtT3B0MSkpOworCisgICAgU2VydmljZURlc2NyaXB0b3Igc2VydmljZSA9CisgICAgICBVbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucy5nZXREZXNjcmlwdG9yKCk7CisKKyAgICBhc3NlcnRUcnVlKAorICAgICAgc2VydmljZS5nZXRPcHRpb25zKCkuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5zZXJ2aWNlT3B0MSkpOworICAgIGFzc2VydEVxdWFscyhMb25nLnZhbHVlT2YoLTk4NzY1NDMyMTBMKSwKKyAgICAgIHNlcnZpY2UuZ2V0T3B0aW9ucygpLmdldEV4dGVuc2lvbihVbml0dGVzdEN1c3RvbU9wdGlvbnMuc2VydmljZU9wdDEpKTsKKworICAgIE1ldGhvZERlc2NyaXB0b3IgbWV0aG9kID0gc2VydmljZS5maW5kTWV0aG9kQnlOYW1lKCJGb28iKTsKKyAgICBhc3NlcnROb3ROdWxsKG1ldGhvZCk7CisKKyAgICBhc3NlcnRUcnVlKAorICAgICAgbWV0aG9kLmdldE9wdGlvbnMoKS5oYXNFeHRlbnNpb24oVW5pdHRlc3RDdXN0b21PcHRpb25zLm1ldGhvZE9wdDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RDdXN0b21PcHRpb25zLk1ldGhvZE9wdDEuTUVUSE9ET1BUMV9WQUwyLAorICAgICAgbWV0aG9kLmdldE9wdGlvbnMoKS5nZXRFeHRlbnNpb24oVW5pdHRlc3RDdXN0b21PcHRpb25zLm1ldGhvZE9wdDEpKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0IHRoYXQgdGhlIEZpZWxkRGVzY3JpcHRvci5UeXBlIGVudW0gaXMgdGhlIHNhbWUgYXMgdGhlCisgICAqIFdpcmVGb3JtYXQuRmllbGRUeXBlIGVudW0uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGRUeXBlVGFibGVzTWF0Y2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWVsZERlc2NyaXB0b3IuVHlwZVtdIHZhbHVlczEgPSBGaWVsZERlc2NyaXB0b3IuVHlwZS52YWx1ZXMoKTsKKyAgICBXaXJlRm9ybWF0LkZpZWxkVHlwZVtdIHZhbHVlczIgPSBXaXJlRm9ybWF0LkZpZWxkVHlwZS52YWx1ZXMoKTsKKworICAgIGFzc2VydEVxdWFscyh2YWx1ZXMxLmxlbmd0aCwgdmFsdWVzMi5sZW5ndGgpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMxLmxlbmd0aDsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHModmFsdWVzMVtpXS50b1N0cmluZygpLCB2YWx1ZXMyW2ldLnRvU3RyaW5nKCkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUZXN0IHRoYXQgdGhlIEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZSBlbnVtIGlzIHRoZSBzYW1lIGFzIHRoZQorICAgKiBXaXJlRm9ybWF0LkphdmFUeXBlIGVudW0uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SmF2YVR5cGVUYWJsZXNNYXRjaCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpZWxkRGVzY3JpcHRvci5KYXZhVHlwZVtdIHZhbHVlczEgPSBGaWVsZERlc2NyaXB0b3IuSmF2YVR5cGUudmFsdWVzKCk7CisgICAgV2lyZUZvcm1hdC5KYXZhVHlwZVtdIHZhbHVlczIgPSBXaXJlRm9ybWF0LkphdmFUeXBlLnZhbHVlcygpOworCisgICAgYXNzZXJ0RXF1YWxzKHZhbHVlczEubGVuZ3RoLCB2YWx1ZXMyLmxlbmd0aCk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlczEubGVuZ3RoOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyh2YWx1ZXMxW2ldLnRvU3RyaW5nKCksIHZhbHVlczJbaV0udG9TdHJpbmcoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVub3Jtb3VzRGVzY3JpcHRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRoZSBkZXNjcmlwdG9yIGZvciB0aGlzIGZpbGUgaXMgbGFyZ2VyIHRoYW4gNjRrLCB5ZXQgaXQgZGlkIG5vdCBjYXVzZQorICAgIC8vIGEgY29tcGlsZXIgZXJyb3IgZHVlIHRvIGFuIG92ZXItbG9uZyBzdHJpbmcgbGl0ZXJhbC4KKyAgICBhc3NlcnRUcnVlKAorICAgICAgICBVbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5nZXREZXNjcmlwdG9yKCkKKyAgICAgICAgICAudG9Qcm90bygpLmdldFNlcmlhbGl6ZWRTaXplKCkgPiA2NTUzNik7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCB0aGUgRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24gd29ya3MgYXMgaW50ZW5kZWQuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0RGVzY3JpcHRvclZhbGlkYXRvckV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZURlc2NyaXB0b3JQcm90byA9IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAuc2V0TmFtZSgiZm9vLnByb3RvIikKKyAgICAgIC5hZGRNZXNzYWdlVHlwZShEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAuc2V0TmFtZSgiRm9vIikKKyAgICAgICAgLmFkZEZpZWxkKEZpZWxkRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgIC5zZXRMYWJlbChGaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbC5MQUJFTF9PUFRJT05BTCkKKyAgICAgICAgICAuc2V0VHlwZShGaWVsZERlc2NyaXB0b3JQcm90by5UeXBlLlRZUEVfSU5UMzIpCisgICAgICAgICAgLnNldE5hbWUoImZvbyIpCisgICAgICAgICAgLnNldE51bWJlcigxKQorICAgICAgICAgIC5zZXREZWZhdWx0VmFsdWUoImludmFsaWQiKQorICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKSkKKyAgICAgIC5idWlsZCgpOworICAgIHRyeSB7CisgICAgICBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci5idWlsZEZyb20oZmlsZURlc2NyaXB0b3JQcm90bywKKyAgICAgICAgICBuZXcgRmlsZURlc2NyaXB0b3JbMF0pOworICAgICAgZmFpbCgiRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICB9IGNhdGNoIChEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZDsgY2hlY2sgdGhhdCB0aGUgZXJyb3IgbWVzc2FnZSBjb250YWlucyBzb21lIHVzZWZ1bCBoaW50cworICAgICAgYXNzZXJ0VHJ1ZShlLmdldE1lc3NhZ2UoKS5pbmRleE9mKCJmb28iKSAhPSAtMSk7CisgICAgICBhc3NlcnRUcnVlKGUuZ2V0TWVzc2FnZSgpLmluZGV4T2YoIkZvbyIpICE9IC0xKTsKKyAgICAgIGFzc2VydFRydWUoZS5nZXRNZXNzYWdlKCkuaW5kZXhPZigiaW52YWxpZCIpICE9IC0xKTsKKyAgICAgIGFzc2VydFRydWUoZS5nZXRDYXVzZSgpIGluc3RhbmNlb2YgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKTsKKyAgICAgIGFzc2VydFRydWUoZS5nZXRDYXVzZSgpLmdldE1lc3NhZ2UoKS5pbmRleE9mKCJpbnZhbGlkIikgIT0gLTEpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyB0aGUgdHJhbnNsYXRlL2Nyb3NzbGluayBmb3IgYW4gZXhhbXBsZSB3aGVyZSBhIG1lc3NhZ2UgZmllbGQncyBuYW1lCisgICAqIGFuZCB0eXBlIG5hbWUgYXJlIHRoZSBzYW1lLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdERlc2NyaXB0b3JDb21wbGV4Q3Jvc3NsaW5rKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlRGVzY3JpcHRvclByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgIC5zZXROYW1lKCJmb28ucHJvdG8iKQorICAgICAgLmFkZE1lc3NhZ2VUeXBlKERlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoIkZvbyIpCisgICAgICAgIC5hZGRGaWVsZChGaWVsZERlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0TGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwuTEFCRUxfT1BUSU9OQUwpCisgICAgICAgICAgLnNldFR5cGUoRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZS5UWVBFX0lOVDMyKQorICAgICAgICAgIC5zZXROYW1lKCJmb28iKQorICAgICAgICAgIC5zZXROdW1iZXIoMSkKKyAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCkpCisgICAgICAuYWRkTWVzc2FnZVR5cGUoRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TmFtZSgiQmFyIikKKyAgICAgICAgLmFkZEZpZWxkKEZpZWxkRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgIC5zZXRMYWJlbChGaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbC5MQUJFTF9PUFRJT05BTCkKKyAgICAgICAgICAuc2V0VHlwZU5hbWUoIkZvbyIpCisgICAgICAgICAgLnNldE5hbWUoIkZvbyIpCisgICAgICAgICAgLnNldE51bWJlcigxKQorICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKSkKKyAgICAgIC5idWlsZCgpOworICAgIC8vIHRyYW5zbGF0ZSBhbmQgY3Jvc3NsaW5rCisgICAgRmlsZURlc2NyaXB0b3IgZmlsZSA9CisgICAgICBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci5idWlsZEZyb20oZmlsZURlc2NyaXB0b3JQcm90bywgCisgICAgICAgICAgbmV3IEZpbGVEZXNjcmlwdG9yWzBdKTsKKyAgICAvLyB2ZXJpZnkgcmVzdWx0aW5nIGRlc2NyaXB0b3JzCisgICAgYXNzZXJ0Tm90TnVsbChmaWxlKTsKKyAgICBMaXN0PERlc2NyaXB0b3I+IG1zZ2xpc3QgPSBmaWxlLmdldE1lc3NhZ2VUeXBlcygpOworICAgIGFzc2VydE5vdE51bGwobXNnbGlzdCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dsaXN0LnNpemUoKSA9PSAyKTsKKyAgICBib29sZWFuIGJhckZvdW5kID0gZmFsc2U7CisgICAgZm9yIChEZXNjcmlwdG9yIGRlc2MgOiBtc2dsaXN0KSB7CisgICAgICBpZiAoZGVzYy5nZXROYW1lKCkuZXF1YWxzKCJCYXIiKSkgeworICAgICAgICBiYXJGb3VuZCA9IHRydWU7CisgICAgICAgIGFzc2VydE5vdE51bGwoZGVzYy5nZXRGaWVsZHMoKSk7CisgICAgICAgIExpc3Q8RmllbGREZXNjcmlwdG9yPiBmaWVsZGxpc3QgPSBkZXNjLmdldEZpZWxkcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKGZpZWxkbGlzdCk7CisgICAgICAgIGFzc2VydFRydWUoZmllbGRsaXN0LnNpemUoKSA9PSAxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmaWVsZGxpc3QuZ2V0KDApLmdldFR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmaWVsZGxpc3QuZ2V0KDApLmdldE1lc3NhZ2VUeXBlKCkuZ2V0TmFtZSgpLmVxdWFscygiRm9vIikpOworICAgICAgfQorICAgIH0KKyAgICBhc3NlcnRUcnVlKGJhckZvdW5kKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdERlcGVuZGVuY3lPcmRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vUHJvdG8gPSBGaWxlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TmFtZSgiZm9vLnByb3RvIikuYnVpbGQoKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhclByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImJhci5wcm90byIpCisgICAgICAgIC5hZGREZXBlbmRlbmN5KCJmb28ucHJvdG8iKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhelByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImJhei5wcm90byIpCisgICAgICAgIC5hZGREZXBlbmRlbmN5KCJmb28ucHJvdG8iKQorICAgICAgICAuYWRkRGVwZW5kZW5jeSgiYmFyLnByb3RvIikKKyAgICAgICAgLmFkZFB1YmxpY0RlcGVuZGVuY3koMCkKKyAgICAgICAgLmFkZFB1YmxpY0RlcGVuZGVuY3koMSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgRmlsZURlc2NyaXB0b3IgZm9vRmlsZSA9IERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLmJ1aWxkRnJvbShmb29Qcm90bywKKyAgICAgICAgbmV3IEZpbGVEZXNjcmlwdG9yWzBdKTsKKyAgICBGaWxlRGVzY3JpcHRvciBiYXJGaWxlID0gRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKGJhclByb3RvLAorICAgICAgICBuZXcgRmlsZURlc2NyaXB0b3JbXSB7Zm9vRmlsZX0pOworICAgIAorICAgIC8vIEl0ZW1zIGluIHRoZSBGaWxlRGVzY3JpcHRvciBhcnJheSBjYW4gYmUgaW4gYW55IG9yZGVyLiAKKyAgICBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci5idWlsZEZyb20oYmF6UHJvdG8sCisgICAgICAgIG5ldyBGaWxlRGVzY3JpcHRvcltdIHtmb29GaWxlLCBiYXJGaWxlfSk7CisgICAgRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKGJhelByb3RvLAorICAgICAgICBuZXcgRmlsZURlc2NyaXB0b3JbXSB7YmFyRmlsZSwgZm9vRmlsZX0pOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZFB1YmxpY0RlcGVuZGVuY3koKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZvb1Byb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImZvby5wcm90byIpLmJ1aWxkKCk7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBiYXJQcm90byA9IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROYW1lKCJib28ucHJvdG8iKQorICAgICAgICAuYWRkRGVwZW5kZW5jeSgiZm9vLnByb3RvIikKKyAgICAgICAgLmFkZFB1YmxpY0RlcGVuZGVuY3koMSkgIC8vIEVycm9yLCBzaG91bGQgYmUgMC4KKyAgICAgICAgLmJ1aWxkKCk7CisgICAgRmlsZURlc2NyaXB0b3IgZm9vRmlsZSA9IERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLmJ1aWxkRnJvbShmb29Qcm90bywKKyAgICAgICAgbmV3IEZpbGVEZXNjcmlwdG9yWzBdKTsKKyAgICB0cnkgeworICAgICAgRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKGJhclByb3RvLAorICAgICAgICAgIG5ldyBGaWxlRGVzY3JpcHRvcltdIHtmb29GaWxlfSk7CisgICAgICBmYWlsKCJEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgIH0gY2F0Y2ggKERlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgZS5nZXRNZXNzYWdlKCkuaW5kZXhPZigiSW52YWxpZCBwdWJsaWMgZGVwZW5kZW5jeSBpbmRleC4iKSAhPSAtMSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEhpZGRlbkRlcGVuZGVuY3koKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhclByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImJhci5wcm90byIpCisgICAgICAgIC5hZGRNZXNzYWdlVHlwZShEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpLnNldE5hbWUoIkJhciIpKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZvcndhcmRQcm90byA9IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROYW1lKCJmb3J3YXJkLnByb3RvIikKKyAgICAgICAgLmFkZERlcGVuZGVuY3koImJhci5wcm90byIpCisgICAgICAgIC5idWlsZCgpOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vUHJvdG8gPSBGaWxlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TmFtZSgiZm9vLnByb3RvIikKKyAgICAgICAgLmFkZERlcGVuZGVuY3koImZvcndhcmQucHJvdG8iKQorICAgICAgICAuYWRkTWVzc2FnZVR5cGUoRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoIkZvbyIpCisgICAgICAgICAgICAuYWRkRmllbGQoRmllbGREZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldExhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsLkxBQkVMX09QVElPTkFMKQorICAgICAgICAgICAgICAgIC5zZXRUeXBlTmFtZSgiQmFyIikKKyAgICAgICAgICAgICAgICAuc2V0TmFtZSgiYmFyIikKKyAgICAgICAgICAgICAgICAuc2V0TnVtYmVyKDEpKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgRmlsZURlc2NyaXB0b3IgYmFyRmlsZSA9IERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLmJ1aWxkRnJvbSgKKyAgICAgICAgYmFyUHJvdG8sIG5ldyBGaWxlRGVzY3JpcHRvclswXSk7CisgICAgRmlsZURlc2NyaXB0b3IgZm9yd2FyZEZpbGUgPSBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci5idWlsZEZyb20oCisgICAgICAgIGZvcndhcmRQcm90bywgbmV3IEZpbGVEZXNjcmlwdG9yW10ge2JhckZpbGV9KTsKKworICAgIHRyeSB7CisgICAgICBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci5idWlsZEZyb20oCisgICAgICAgICAgZm9vUHJvdG8sIG5ldyBGaWxlRGVzY3JpcHRvcltdIHtmb3J3YXJkRmlsZX0pOworICAgICAgZmFpbCgiRGVzY3JpcHRvclZhbGlkYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICB9IGNhdGNoIChEZXNjcmlwdG9yVmFsaWRhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRUcnVlKGUuZ2V0TWVzc2FnZSgpLmluZGV4T2YoIkJhciIpICE9IC0xKTsKKyAgICAgIGFzc2VydFRydWUoZS5nZXRNZXNzYWdlKCkuaW5kZXhPZigiaXMgbm90IGRlZmluZWQiKSAhPSAtMSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFB1YmxpY0RlcGVuZGVuY3koKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhclByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImJhci5wcm90byIpCisgICAgICAgIC5hZGRNZXNzYWdlVHlwZShEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpLnNldE5hbWUoIkJhciIpKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZvcndhcmRQcm90byA9IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROYW1lKCJmb3J3YXJkLnByb3RvIikKKyAgICAgICAgLmFkZERlcGVuZGVuY3koImJhci5wcm90byIpCisgICAgICAgIC5hZGRQdWJsaWNEZXBlbmRlbmN5KDApCisgICAgICAgIC5idWlsZCgpOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vUHJvdG8gPSBGaWxlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TmFtZSgiZm9vLnByb3RvIikKKyAgICAgICAgLmFkZERlcGVuZGVuY3koImZvcndhcmQucHJvdG8iKQorICAgICAgICAuYWRkTWVzc2FnZVR5cGUoRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoIkZvbyIpCisgICAgICAgICAgICAuYWRkRmllbGQoRmllbGREZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldExhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsLkxBQkVMX09QVElPTkFMKQorICAgICAgICAgICAgICAgIC5zZXRUeXBlTmFtZSgiQmFyIikKKyAgICAgICAgICAgICAgICAuc2V0TmFtZSgiYmFyIikKKyAgICAgICAgICAgICAgICAuc2V0TnVtYmVyKDEpKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgRmlsZURlc2NyaXB0b3IgYmFyRmlsZSA9IERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLmJ1aWxkRnJvbSgKKyAgICAgICAgYmFyUHJvdG8sIG5ldyBGaWxlRGVzY3JpcHRvclswXSk7CisgICAgRmlsZURlc2NyaXB0b3IgZm9yd2FyZEZpbGUgPSBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci5idWlsZEZyb20oCisgICAgICAgIGZvcndhcmRQcm90bywgbmV3IEZpbGVEZXNjcmlwdG9yW117YmFyRmlsZX0pOworICAgIERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLmJ1aWxkRnJvbSgKKyAgICAgICAgZm9vUHJvdG8sIG5ldyBGaWxlRGVzY3JpcHRvcltdIHtmb3J3YXJkRmlsZX0pOworICB9CisgIAorICAvKioKKyAgICogVGVzdHMgdGhlIHRyYW5zbGF0ZS9jcm9zc2xpbmsgZm9yIGFuIGV4YW1wbGUgd2l0aCBhIG1vcmUgY29tcGxleCBuYW1lc3BhY2UKKyAgICogcmVmZXJlbmNpbmcuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGxleE5hbWVzcGFjZVB1YmxpY0RlcGVuZGVuY3koKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZvb1Byb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImJhci5wcm90byIpCisgICAgICAgIC5zZXRQYWNrYWdlKCJhLmIuYy5kLmJhci5zaGFyZWQiKQorICAgICAgICAuYWRkRW51bVR5cGUoRW51bURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXROYW1lKCJNeUVudW0iKQorICAgICAgICAgICAgLmFkZFZhbHVlKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0TmFtZSgiQkxBSCIpCisgICAgICAgICAgICAgICAgLnNldE51bWJlcigxKSkpCisgICAgICAgIC5idWlsZCgpOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyUHJvdG8gPSBGaWxlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TmFtZSgiZm9vLnByb3RvIikKKyAgICAgICAgLmFkZERlcGVuZGVuY3koImJhci5wcm90byIpCisgICAgICAgIC5zZXRQYWNrYWdlKCJhLmIuYy5kLmZvby5zaGFyZWQiKQorICAgICAgICAuYWRkTWVzc2FnZVR5cGUoRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoIk15TWVzc2FnZSIpCisgICAgICAgICAgICAuYWRkRmllbGQoRmllbGREZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldExhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsLkxBQkVMX1JFUEVBVEVEKQorICAgICAgICAgICAgICAgIC5zZXRUeXBlTmFtZSgiYmFyLnNoYXJlZC5NeUVudW0iKQorICAgICAgICAgICAgICAgIC5zZXROYW1lKCJNeUZpZWxkIikKKyAgICAgICAgICAgICAgICAuc2V0TnVtYmVyKDEpKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgLy8gdHJhbnNsYXRlIGFuZCBjcm9zc2xpbmsKKyAgICBGaWxlRGVzY3JpcHRvciBmb29GaWxlID0gRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKAorICAgICAgICBmb29Qcm90bywgbmV3IEZpbGVEZXNjcmlwdG9yWzBdKTsKKyAgICBGaWxlRGVzY3JpcHRvciBiYXJGaWxlID0gRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKAorICAgICAgICBiYXJQcm90bywgbmV3IEZpbGVEZXNjcmlwdG9yW117Zm9vRmlsZX0pOworICAgIC8vIHZlcmlmeSByZXN1bHRpbmcgZGVzY3JpcHRvcnMKKyAgICBhc3NlcnROb3ROdWxsKGJhckZpbGUpOworICAgIExpc3Q8RGVzY3JpcHRvcj4gbXNnbGlzdCA9IGJhckZpbGUuZ2V0TWVzc2FnZVR5cGVzKCk7CisgICAgYXNzZXJ0Tm90TnVsbChtc2dsaXN0KTsKKyAgICBhc3NlcnRUcnVlKG1zZ2xpc3Quc2l6ZSgpID09IDEpOworICAgIERlc2NyaXB0b3IgZGVzYyA9IG1zZ2xpc3QuZ2V0KDApOworICAgIGlmIChkZXNjLmdldE5hbWUoKS5lcXVhbHMoIk15TWVzc2FnZSIpKSB7CisgICAgICBhc3NlcnROb3ROdWxsKGRlc2MuZ2V0RmllbGRzKCkpOworICAgICAgTGlzdDxGaWVsZERlc2NyaXB0b3I+IGZpZWxkbGlzdCA9IGRlc2MuZ2V0RmllbGRzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKGZpZWxkbGlzdCk7CisgICAgICBhc3NlcnRUcnVlKGZpZWxkbGlzdC5zaXplKCkgPT0gMSk7CisgICAgICBGaWVsZERlc2NyaXB0b3IgZmllbGQgPSBmaWVsZGxpc3QuZ2V0KDApOworICAgICAgYXNzZXJ0VHJ1ZShmaWVsZC5nZXRUeXBlKCkgPT0gRmllbGREZXNjcmlwdG9yLlR5cGUuRU5VTSk7CisgICAgICBhc3NlcnRUcnVlKGZpZWxkLmdldEVudW1UeXBlKCkuZ2V0TmFtZSgpLmVxdWFscygiTXlFbnVtIikpOworICAgICAgYXNzZXJ0VHJ1ZShmaWVsZC5nZXRFbnVtVHlwZSgpLmdldEZpbGUoKS5nZXROYW1lKCkuZXF1YWxzKCJiYXIucHJvdG8iKSk7CisgICAgICBhc3NlcnRUcnVlKGZpZWxkLmdldEVudW1UeXBlKCkuZ2V0RmlsZSgpLmdldFBhY2thZ2UoKS5lcXVhbHMoCisgICAgICAgICAgImEuYi5jLmQuYmFyLnNoYXJlZCIpKTsKKyAgICB9ICAgCisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZEZXNjcmlwdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGVzY3JpcHRvciBtZXNzYWdlVHlwZSA9IFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0KKyAgICAgICAgbWVzc2FnZVR5cGUuZmluZEZpZWxkQnlOYW1lKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpOworICAgIE9uZW9mRGVzY3JpcHRvciBvbmVvZkRlc2NyaXB0b3IgPSBmaWVsZC5nZXRDb250YWluaW5nT25lb2YoKTsKKyAgICBhc3NlcnROb3ROdWxsKG9uZW9mRGVzY3JpcHRvcik7CisgICAgYXNzZXJ0U2FtZShvbmVvZkRlc2NyaXB0b3IsIG1lc3NhZ2VUeXBlLmdldE9uZW9mcygpLmdldCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJvbmVvZl9maWVsZCIsIG9uZW9mRGVzY3JpcHRvci5nZXROYW1lKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDQsIG9uZW9mRGVzY3JpcHRvci5nZXRGaWVsZENvdW50KCkpOworICAgIGFzc2VydFNhbWUob25lb2ZEZXNjcmlwdG9yLmdldEZpZWxkKDEpLCBmaWVsZCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZURlc2NyaXB0b3JFeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0RmFsc2UoVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKS5pc0V4dGVuZGFibGUoKSk7CisgICAgYXNzZXJ0VHJ1ZShUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZXNjcmlwdG9yKCkuaXNFeHRlbmRhYmxlKCkpOworICAgIGFzc2VydFRydWUoVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzLmdldERlc2NyaXB0b3IoKS5pc0V4dGVuZGFibGUoKSk7CisKKyAgICBhc3NlcnRGYWxzZShUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmlzRXh0ZW5zaW9uTnVtYmVyKDMpKTsKKyAgICBhc3NlcnRUcnVlKFRlc3RBbGxFeHRlbnNpb25zLmdldERlc2NyaXB0b3IoKS5pc0V4dGVuc2lvbk51bWJlcigzKSk7CisgICAgYXNzZXJ0VHJ1ZShUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMuZ2V0RGVzY3JpcHRvcigpLmlzRXh0ZW5zaW9uTnVtYmVyKDQyKSk7CisgICAgYXNzZXJ0RmFsc2UoVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzLmdldERlc2NyaXB0b3IoKS5pc0V4dGVuc2lvbk51bWJlcig0MykpOworICAgIGFzc2VydEZhbHNlKFRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5nZXREZXNjcmlwdG9yKCkuaXNFeHRlbnNpb25OdW1iZXIoNDE0MikpOworICAgIGFzc2VydFRydWUoVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzLmdldERlc2NyaXB0b3IoKS5pc0V4dGVuc2lvbk51bWJlcig0MTQzKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgYXNzZXJ0RXF1YWxzKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMub3B0aW9uYWxfdWludDY0IiwKKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TnVtYmVyKAorICAgICAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUikudG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFja2VkRW51bUZpZWxkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlRGVzY3JpcHRvclByb3RvID0gRmlsZURlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoImZvby5wcm90byIpCisgICAgICAgIC5hZGRFbnVtVHlwZShFbnVtRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgIC5zZXROYW1lKCJFbnVtIikKKyAgICAgICAgICAuYWRkVmFsdWUoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoIkZPTyIpCisgICAgICAgICAgICAuc2V0TnVtYmVyKDEpCisgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmFkZE1lc3NhZ2VUeXBlKERlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0TmFtZSgiTWVzc2FnZSIpCisgICAgICAgICAgLmFkZEZpZWxkKEZpZWxkRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoImZvbyIpCisgICAgICAgICAgICAuc2V0VHlwZU5hbWUoIkVudW0iKQorICAgICAgICAgICAgLnNldE51bWJlcigxKQorICAgICAgICAgICAgLnNldExhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsLkxBQkVMX1JFUEVBVEVEKQorICAgICAgICAgICAgLnNldE9wdGlvbnMoRGVzY3JpcHRvclByb3Rvcy5GaWVsZE9wdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgIC5zZXRQYWNrZWQodHJ1ZSkKKyAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKAorICAgICAgICBmaWxlRGVzY3JpcHRvclByb3RvLCBuZXcgRmlsZURlc2NyaXB0b3JbMF0pOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EeW5hbWljTWVzc2FnZVRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0R5bmFtaWNNZXNzYWdlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1MTQ0ZTcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9EeW5hbWljTWVzc2FnZVRlc3QuamF2YQpAQCAtMCwwICsxLDMyNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3I7CisKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFVuaXQgdGVzdCBmb3Ige0BsaW5rIER5bmFtaWNNZXNzYWdlfS4gIFNlZSBhbHNvIHtAbGluayBNZXNzYWdlVGVzdH0sIHdoaWNoCisgKiB0ZXN0cyBzb21lIHtAbGluayBEeW5hbWljTWVzc2FnZX0gZnVuY3Rpb25hbGl0eS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgY2xhc3MgRHluYW1pY01lc3NhZ2VUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICBUZXN0VXRpbC5SZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25UZXN0ZXIgPQorICAgIG5ldyBUZXN0VXRpbC5SZWZsZWN0aW9uVGVzdGVyKFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCksIG51bGwpOworCisgIFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIgZXh0ZW5zaW9uc1JlZmxlY3Rpb25UZXN0ZXIgPQorICAgIG5ldyBUZXN0VXRpbC5SZWZsZWN0aW9uVGVzdGVyKFRlc3RBbGxFeHRlbnNpb25zLmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpKTsKKyAgVGVzdFV0aWwuUmVmbGVjdGlvblRlc3RlciBwYWNrZWRSZWZsZWN0aW9uVGVzdGVyID0KKyAgICBuZXcgVGVzdFV0aWwuUmVmbGVjdGlvblRlc3RlcihUZXN0UGFja2VkVHlwZXMuZ2V0RGVzY3JpcHRvcigpLCBudWxsKTsKKworICBwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY01lc3NhZ2VBY2Nlc3NvcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlciA9CisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIuc2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihidWlsZGVyKTsKKyAgICBNZXNzYWdlIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNldHRlcnNBZnRlckJ1aWxkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICBNZXNzYWdlIGZpcnN0TWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAvLyBkb3VibGUgYnVpbGQoKQorICAgIGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAvLyBjbGVhcigpIGFmdGVyIGJ1aWxkKCkKKyAgICBidWlsZGVyLmNsZWFyKCk7CisgICAgLy8gc2V0dGVycyBhZnRlciBidWlsZCgpCisgICAgcmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIE1lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24obWVzc2FnZSk7CisgICAgLy8gcmVwZWF0ZWQgc2V0dGVycyBhZnRlciBidWlsZCgpCisgICAgcmVmbGVjdGlvblRlc3Rlci5tb2RpZnlSZXBlYXRlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydFJlcGVhdGVkRmllbGRzTW9kaWZpZWRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworICAgIC8vIGZpcnN0TWVzc2FnZSBzaG91bGRuJ3QgaGF2ZSBiZWVuIG1vZGlmaWVkLgorICAgIHJlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0Q2xlYXJWaWFSZWZsZWN0aW9uKGZpcnN0TWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5rbm93bkZpZWxkcygpIHRocm93cyBFeGNlcHRpb24geworICAgIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0RW1wdHlNZXNzYWdlLmdldERlc2NyaXB0b3IoKSk7CisgICAgYnVpbGRlci5zZXRVbmtub3duRmllbGRzKFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgLmFkZEZpZWxkKDEsIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkuYWRkVmFyaW50KDEpLmJ1aWxkKCkpCisgICAgICAgIC5hZGRGaWVsZCgyLCBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpLmFkZEZpeGVkMzIoMSkuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCkpOworICAgIE1lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkuYXNNYXAoKS5zaXplKCkpOworICAgIC8vIGNsb25lKCkgd2l0aCB1bmtub3duIGZpZWxkcworICAgIE1lc3NhZ2UuQnVpbGRlciBuZXdCdWlsZGVyID0gYnVpbGRlci5jbG9uZSgpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdCdWlsZGVyLmdldFVua25vd25GaWVsZHMoKS5hc01hcCgpLnNpemUoKSk7CisgICAgLy8gY2xlYXIoKSB3aXRoIHVua25vd24gZmllbGRzCisgICAgbmV3QnVpbGRlci5jbGVhcigpOworICAgIGFzc2VydFRydWUobmV3QnVpbGRlci5nZXRVbmtub3duRmllbGRzKCkuYXNNYXAoKS5pc0VtcHR5KCkpOworICAgIC8vIHNlcmlhbGl6ZS9wYXJzZSB3aXRoIHVua25vd24gZmllbGRzCisgICAgbmV3QnVpbGRlci5tZXJnZUZyb20obWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld0J1aWxkZXIuZ2V0VW5rbm93bkZpZWxkcygpLmFzTWFwKCkuc2l6ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljTWVzc2FnZVNldHRlcnNSZWplY3ROdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydFJlZmxlY3Rpb25TZXR0ZXJzUmVqZWN0TnVsbChidWlsZGVyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljTWVzc2FnZUV4dGVuc2lvbkFjY2Vzc29ycygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gZXh0ZW5zaXZlbHkgdGVzdCBEeW5hbWljTWVzc2FnZSdzIGhhbmRsaW5nIG9mCisgICAgLy8gZXh0ZW5zaW9ucyBiZWNhdXNlLCBmcmFua2x5LCBpdCBkb2Vzbid0IGRvIGFueXRoaW5nIHNwZWNpYWwgd2l0aCB0aGVtLgorICAgIC8vIEl0IHRyZWF0cyB0aGVtIGp1c3QgbGlrZSBhbnkgb3RoZXIgZmllbGRzLgorICAgIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgIER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICBleHRlbnNpb25zUmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIE1lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBleHRlbnNpb25zUmVmbGVjdGlvblRlc3Rlci5hc3NlcnRBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uU2V0dGVyc1JlamVjdE51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlciA9CisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RBbGxFeHRlbnNpb25zLmdldERlc2NyaXB0b3IoKSk7CisgICAgZXh0ZW5zaW9uc1JlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0UmVmbGVjdGlvblNldHRlcnNSZWplY3ROdWxsKGJ1aWxkZXIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlUmVwZWF0ZWRTZXR0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLnNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgcmVmbGVjdGlvblRlc3Rlci5tb2RpZnlSZXBlYXRlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgTWVzc2FnZSBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZFZpYVJlZmxlY3Rpb24obWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY01lc3NhZ2VSZXBlYXRlZFNldHRlcnNSZWplY3ROdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydFJlZmxlY3Rpb25SZXBlYXRlZFNldHRlcnNSZWplY3ROdWxsKGJ1aWxkZXIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlRGVmYXVsdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydENsZWFyVmlhUmVmbGVjdGlvbigKKyAgICAgIER5bmFtaWNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZShUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKSk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRDbGVhclZpYVJlZmxlY3Rpb24oCisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkpLmJ1aWxkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlU2VyaWFsaXplZFNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworCisgICAgTWVzc2FnZS5CdWlsZGVyIGR5bmFtaWNCdWlsZGVyID0KKyAgICAgIER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIoVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKSk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGR5bmFtaWNCdWlsZGVyKTsKKyAgICBNZXNzYWdlIGR5bmFtaWNNZXNzYWdlID0gZHluYW1pY0J1aWxkZXIuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksCisgICAgICAgICAgICAgICAgIGR5bmFtaWNNZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlU2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgIER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIoVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKSk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIE1lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKworICAgIEJ5dGVTdHJpbmcgcmF3Qnl0ZXMgPSBtZXNzYWdlLnRvQnl0ZVN0cmluZygpOworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlMiA9IFRlc3RBbGxUeXBlcy5wYXJzZUZyb20ocmF3Qnl0ZXMpOworCisgICAgVGVzdFV0aWwuYXNzZXJ0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAgIC8vIEluIGZhY3QsIHRoZSBzZXJpYWxpemVkIGZvcm1zIHNob3VsZCBiZSBleGFjdGx5IHRoZSBzYW1lLCBieXRlLWZvci1ieXRlLgorICAgIGFzc2VydEVxdWFscyhUZXN0VXRpbC5nZXRBbGxTZXQoKS50b0J5dGVTdHJpbmcoKSwgcmF3Qnl0ZXMpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlUGFyc2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RVdGlsLnNldEFsbEZpZWxkcyhidWlsZGVyKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKworICAgIEJ5dGVTdHJpbmcgcmF3Qnl0ZXMgPSBtZXNzYWdlLnRvQnl0ZVN0cmluZygpOworCisgICAgTWVzc2FnZSBtZXNzYWdlMiA9CisgICAgICBEeW5hbWljTWVzc2FnZS5wYXJzZUZyb20oVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKSwgcmF3Qnl0ZXMpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbihtZXNzYWdlMik7CisKKyAgICAvLyBUZXN0IFBhcnNlciBpbnRlcmZhY2UuCisgICAgTWVzc2FnZSBtZXNzYWdlMyA9IG1lc3NhZ2UyLmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20ocmF3Qnl0ZXMpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbihtZXNzYWdlMyk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY01lc3NhZ2VFeHRlbnNpb25QYXJzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKS50b0J5dGVTdHJpbmcoKTsKKyAgICBNZXNzYWdlIG1lc3NhZ2UgPSBEeW5hbWljTWVzc2FnZS5wYXJzZUZyb20oCisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zLmdldERlc2NyaXB0b3IoKSwgcmF3Qnl0ZXMsCisgICAgICAgIFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCkpOworICAgIGV4dGVuc2lvbnNSZWZsZWN0aW9uVGVzdGVyLmFzc2VydEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24obWVzc2FnZSk7CisKKyAgICAvLyBUZXN0IFBhcnNlciBpbnRlcmZhY2UuCisgICAgTWVzc2FnZSBtZXNzYWdlMiA9IG1lc3NhZ2UuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbSgKKyAgICAgICAgcmF3Qnl0ZXMsIFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCkpOworICAgIGV4dGVuc2lvbnNSZWZsZWN0aW9uVGVzdGVyLmFzc2VydEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24obWVzc2FnZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXNzYWdlUGFja2VkU2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0UGFja2VkVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICBwYWNrZWRSZWZsZWN0aW9uVGVzdGVyLnNldFBhY2tlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgTWVzc2FnZSBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisgICAgVGVzdFBhY2tlZFR5cGVzIG1lc3NhZ2UyID0gVGVzdFBhY2tlZFR5cGVzLnBhcnNlRnJvbShyYXdCeXRlcyk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRQYWNrZWRGaWVsZHNTZXQobWVzc2FnZTIpOworCisgICAgLy8gSW4gZmFjdCwgdGhlIHNlcmlhbGl6ZWQgZm9ybXMgc2hvdWxkIGJlIGV4YWN0bHkgdGhlIHNhbWUsIGJ5dGUtZm9yLWJ5dGUuCisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLmdldFBhY2tlZFNldCgpLnRvQnl0ZVN0cmluZygpLCByYXdCeXRlcyk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY01lc3NhZ2VQYWNrZWRQYXJzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RQYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGVzdFV0aWwuc2V0UGFja2VkRmllbGRzKGJ1aWxkZXIpOworICAgIFRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisKKyAgICBNZXNzYWdlIG1lc3NhZ2UyID0KKyAgICAgIER5bmFtaWNNZXNzYWdlLnBhcnNlRnJvbShUZXN0UGFja2VkVHlwZXMuZ2V0RGVzY3JpcHRvcigpLCByYXdCeXRlcyk7CisgICAgcGFja2VkUmVmbGVjdGlvblRlc3Rlci5hc3NlcnRQYWNrZWRGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UyKTsKKworICAgIC8vIFRlc3QgUGFyc2VyIGludGVyZmFjZS4KKyAgICBNZXNzYWdlIG1lc3NhZ2UzID0gbWVzc2FnZTIuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShyYXdCeXRlcyk7CisgICAgcGFja2VkUmVmbGVjdGlvblRlc3Rlci5hc3NlcnRQYWNrZWRGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UzKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljTWVzc2FnZUNvcHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRBbGxGaWVsZHMoYnVpbGRlcik7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisKKyAgICBEeW5hbWljTWVzc2FnZSBjb3B5ID0gRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihtZXNzYWdlKS5idWlsZCgpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbihjb3B5KTsKKworICAgIC8vIFRlc3Qgb25lb2YgYmVoYXZpb3IKKyAgICBGaWVsZERlc2NyaXB0b3IgYnl0ZXNGaWVsZCA9CisgICAgICAgIFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJvbmVvZl9ieXRlcyIpOworICAgIEZpZWxkRGVzY3JpcHRvciB1aW50MzJGaWVsZCA9CisgICAgICAgIFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJvbmVvZl91aW50MzIiKTsKKyAgICBhc3NlcnRUcnVlKGNvcHkuaGFzRmllbGQoYnl0ZXNGaWVsZCkpOworICAgIGFzc2VydEZhbHNlKGNvcHkuaGFzRmllbGQodWludDMyRmllbGQpKTsKKyAgICBEeW5hbWljTWVzc2FnZSBjb3B5MiA9CisgICAgICAgIER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIobWVzc2FnZSkuc2V0RmllbGQodWludDMyRmllbGQsIDEyMykuYnVpbGQoKTsKKyAgICBhc3NlcnRGYWxzZShjb3B5Mi5oYXNGaWVsZChieXRlc0ZpZWxkKSk7CisgICAgYXNzZXJ0VHJ1ZShjb3B5Mi5oYXNGaWVsZCh1aW50MzJGaWVsZCkpOworICAgIGFzc2VydEVxdWFscygxMjMsIGNvcHkyLmdldEZpZWxkKHVpbnQzMkZpZWxkKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VG9CdWlsZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRHluYW1pY01lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLnNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgaW50IHVua25vd25GaWVsZE51bSA9IDk7CisgICAgbG9uZyB1bmtub3duRmllbGRWYWwgPSA5MDsKKyAgICBidWlsZGVyLnNldFVua25vd25GaWVsZHMoVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkRmllbGQodW5rbm93bkZpZWxkTnVtLAorICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5hZGRWYXJpbnQodW5rbm93bkZpZWxkVmFsKS5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKSk7CisgICAgRHluYW1pY01lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKworICAgIER5bmFtaWNNZXNzYWdlIGRlcml2ZWQgPSBtZXNzYWdlLnRvQnVpbGRlcigpLmJ1aWxkKCk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKGRlcml2ZWQpOworICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KHVua25vd25GaWVsZFZhbCksCisgICAgICAgIGRlcml2ZWQuZ2V0VW5rbm93bkZpZWxkcygpLmdldEZpZWxkKHVua25vd25GaWVsZE51bSkuZ2V0VmFyaW50TGlzdCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljT25lb2ZNZXNzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRHluYW1pY01lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICBPbmVvZkRlc2NyaXB0b3Igb25lb2YgPSBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmdldE9uZW9mcygpLmdldCgwKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmhhc09uZW9mKG9uZW9mKSk7CisgICAgYXNzZXJ0U2FtZShudWxsLCBidWlsZGVyLmdldE9uZW9mRmllbGREZXNjcmlwdG9yKG9uZW9mKSk7CisKKyAgICByZWZsZWN0aW9uVGVzdGVyLnNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmhhc09uZW9mKG9uZW9mKSk7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gb25lb2YuZ2V0RmllbGQoMyk7CisgICAgYXNzZXJ0U2FtZShmaWVsZCwgYnVpbGRlci5nZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihvbmVvZikpOworCisgICAgRHluYW1pY01lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09uZW9mKG9uZW9mKSk7CisKKyAgICBEeW5hbWljTWVzc2FnZS5CdWlsZGVyIG1lcmdlZEJ1aWxkZXIgPQorICAgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkpOworICAgIEZpZWxkRGVzY3JpcHRvciBtZXJnZWRGaWVsZCA9IG9uZW9mLmdldEZpZWxkKDApOworICAgIG1lcmdlZEJ1aWxkZXIuc2V0RmllbGQobWVyZ2VkRmllbGQsIDEyMyk7CisgICAgYXNzZXJ0VHJ1ZShtZXJnZWRCdWlsZGVyLmhhc0ZpZWxkKG1lcmdlZEZpZWxkKSk7CisgICAgbWVyZ2VkQnVpbGRlci5tZXJnZUZyb20obWVzc2FnZSk7CisgICAgYXNzZXJ0VHJ1ZShtZXJnZWRCdWlsZGVyLmhhc0ZpZWxkKGZpZWxkKSk7CisgICAgYXNzZXJ0RmFsc2UobWVyZ2VkQnVpbGRlci5oYXNGaWVsZChtZXJnZWRGaWVsZCkpOworCisgICAgYnVpbGRlci5jbGVhck9uZW9mKG9uZW9mKTsKKyAgICBhc3NlcnRTYW1lKG51bGwsIGJ1aWxkZXIuZ2V0T25lb2ZGaWVsZERlc2NyaXB0b3Iob25lb2YpKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydFNhbWUobnVsbCwgbWVzc2FnZS5nZXRPbmVvZkZpZWxkRGVzY3JpcHRvcihvbmVvZikpOworICB9CisKKyAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBhIGJ1ZyB0aGF0IG1ha2VzIHNldEZpZWxkKCkgbm90IHdvcmsgZm9yIHJlcGVhdGVkCisgIC8vIGVudW0gZmllbGRzLgorICBwdWJsaWMgdm9pZCB0ZXN0U2V0dGVyc0ZvclJlcGVhdGVkRW51bUZpZWxkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRHluYW1pY01lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgcmVwZWF0ZWRFbnVtRmllbGQgPQorICAgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAgICJyZXBlYXRlZF9uZXN0ZWRfZW51bSIpOworICAgIEVudW1EZXNjcmlwdG9yIGVudW1EZXNjcmlwdG9yID0gVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZ2V0RGVzY3JpcHRvcigpOworICAgIGJ1aWxkZXIuc2V0RmllbGQocmVwZWF0ZWRFbnVtRmllbGQsIGVudW1EZXNjcmlwdG9yLmdldFZhbHVlcygpKTsKKyAgICBEeW5hbWljTWVzc2FnZSBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgZW51bURlc2NyaXB0b3IuZ2V0VmFsdWVzKCksIG1lc3NhZ2UuZ2V0RmllbGQocmVwZWF0ZWRFbnVtRmllbGQpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRmllbGRQcmVzZW5jZVRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkUHJlc2VuY2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNmMmIwMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkUHJlc2VuY2VUZXN0LmphdmEKQEAgLTAsMCArMSwzNjMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIHByb3RvcyB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBmaWVsZCBwcmVzZW5jZSB0ZXN0IGZvciBvcHRpb25hbAorICogbm9uLW1lc3NhZ2UgZmllbGRzLgorICovCitwdWJsaWMgY2xhc3MgRmllbGRQcmVzZW5jZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaGFzTWV0aG9kKENsYXNzIGNsYXp6LCBTdHJpbmcgbmFtZSkgeworICAgIHRyeSB7CisgICAgICBpZiAoY2xhenouZ2V0TWV0aG9kKG5hbWUsIG5ldyBDbGFzc1tde30pICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzSGFzTWV0aG9kUmVtb3ZlZCgKKyAgICAgIENsYXNzIGNsYXNzV2l0aEZpZWxkUHJlc2VuY2UsCisgICAgICBDbGFzcyBjbGFzc1dpdGhvdXRGaWVsZFByZXNlbmNlLAorICAgICAgU3RyaW5nIGNhbWVsTmFtZSkgeworICAgIHJldHVybiBoYXNNZXRob2QoY2xhc3NXaXRoRmllbGRQcmVzZW5jZSwgImdldCIgKyBjYW1lbE5hbWUpCisgICAgICAgICYmIGhhc01ldGhvZChjbGFzc1dpdGhGaWVsZFByZXNlbmNlLCAiaGFzIiArIGNhbWVsTmFtZSkKKyAgICAgICAgJiYgaGFzTWV0aG9kKGNsYXNzV2l0aG91dEZpZWxkUHJlc2VuY2UsICJnZXQiICsgY2FtZWxOYW1lKQorICAgICAgICAmJiAhaGFzTWV0aG9kKGNsYXNzV2l0aG91dEZpZWxkUHJlc2VuY2UsICJoYXMiICsgY2FtZWxOYW1lKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RIYXNNZXRob2QoKSB7CisgICAgLy8gT3B0aW9uYWwgbm9uLW1lc3NhZ2UgZmllbGRzIGRvbid0IGhhdmUgYSBoYXNGb28oKSBtZXRob2QgZ2VuZXJhdGVkLgorICAgIGFzc2VydFRydWUoaXNIYXNNZXRob2RSZW1vdmVkKAorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgVGVzdEFsbFR5cGVzLmNsYXNzLAorICAgICAgICAiT3B0aW9uYWxJbnQzMiIpKTsKKyAgICBhc3NlcnRUcnVlKGlzSGFzTWV0aG9kUmVtb3ZlZCgKKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgIk9wdGlvbmFsU3RyaW5nIikpOworICAgIGFzc2VydFRydWUoaXNIYXNNZXRob2RSZW1vdmVkKAorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgVGVzdEFsbFR5cGVzLmNsYXNzLAorICAgICAgICAiT3B0aW9uYWxCeXRlcyIpKTsKKyAgICBhc3NlcnRUcnVlKGlzSGFzTWV0aG9kUmVtb3ZlZCgKKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgIk9wdGlvbmFsTmVzdGVkRW51bSIpKTsKKworICAgIGFzc2VydFRydWUoaXNIYXNNZXRob2RSZW1vdmVkKAorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzLAorICAgICAgICBUZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcywKKyAgICAgICAgIk9wdGlvbmFsSW50MzIiKSk7CisgICAgYXNzZXJ0VHJ1ZShpc0hhc01ldGhvZFJlbW92ZWQoCisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzLAorICAgICAgICAiT3B0aW9uYWxTdHJpbmciKSk7CisgICAgYXNzZXJ0VHJ1ZShpc0hhc01ldGhvZFJlbW92ZWQoCisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzLAorICAgICAgICAiT3B0aW9uYWxCeXRlcyIpKTsKKyAgICBhc3NlcnRUcnVlKGlzSGFzTWV0aG9kUmVtb3ZlZCgKKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcywKKyAgICAgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgICJPcHRpb25hbE5lc3RlZEVudW0iKSk7CisKKyAgICAvLyBtZXNzYWdlIGZpZWxkcyBzdGlsbCBoYXZlIHRoZSBoYXNGb28oKSBtZXRob2QgZ2VuZXJhdGVkLgorICAgIGFzc2VydEZhbHNlKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuYnVpbGQoKS5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CisgICAgYXNzZXJ0RmFsc2UoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CisKKyAgICAvLyBvbmVvZiBmaWVsZHMgZG9uJ3QgaGF2ZSBoYXNGb28oKSBtZXRob2RzIChldmVuIGZvciBtZXNzYWdlIHR5cGVzKS4KKyAgICBhc3NlcnRUcnVlKGlzSGFzTWV0aG9kUmVtb3ZlZCgKKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgIk9uZW9mVWludDMyIikpOworICAgIGFzc2VydFRydWUoaXNIYXNNZXRob2RSZW1vdmVkKAorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgVGVzdEFsbFR5cGVzLmNsYXNzLAorICAgICAgICAiT25lb2ZTdHJpbmciKSk7CisgICAgYXNzZXJ0VHJ1ZShpc0hhc01ldGhvZFJlbW92ZWQoCisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmNsYXNzLAorICAgICAgICBUZXN0QWxsVHlwZXMuY2xhc3MsCisgICAgICAgICJPbmVvZkJ5dGVzIikpOworICAgIGFzc2VydFRydWUoaXNIYXNNZXRob2RSZW1vdmVkKAorICAgICAgICBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywKKyAgICAgICAgVGVzdEFsbFR5cGVzLmNsYXNzLAorICAgICAgICAiT25lb2ZOZXN0ZWRNZXNzYWdlIikpOworCisgICAgYXNzZXJ0VHJ1ZShpc0hhc01ldGhvZFJlbW92ZWQoCisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzLAorICAgICAgICAiT25lb2ZVaW50MzIiKSk7CisgICAgYXNzZXJ0VHJ1ZShpc0hhc01ldGhvZFJlbW92ZWQoCisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzLAorICAgICAgICAiT25lb2ZTdHJpbmciKSk7CisgICAgYXNzZXJ0VHJ1ZShpc0hhc01ldGhvZFJlbW92ZWQoCisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzLAorICAgICAgICAiT25lb2ZCeXRlcyIpKTsKKyAgICBhc3NlcnRUcnVlKGlzSGFzTWV0aG9kUmVtb3ZlZCgKKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcywKKyAgICAgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MsCisgICAgICAgICJPbmVvZk5lc3RlZE1lc3NhZ2UiKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGRQcmVzZW5jZSgpIHsKKyAgICAvLyBPcHRpb25hbCBub24tbWVzc2FnZSBmaWVsZHMgc2V0IHRvIHRoZWlyIGRlZmF1bHQgdmFsdWUgYXJlIHRyZWF0ZWQgdGhlCisgICAgLy8gc2FtZSB3YXkgYXMgbm90IHNldC4KKworICAgIC8vIFNlcmlhbGl6YXRpb24gd2lsbCBpZ25vcmUgc3VjaCBmaWVsZHMuCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5zZXRPcHRpb25hbEludDMyKDApOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxTdHJpbmcoIiIpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxCeXRlcyhCeXRlU3RyaW5nLkVNUFRZKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkRW51bShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08pOworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCkpOworCisgICAgLy8gbWVyZ2VGcm9tKCkgd2lsbCBpZ25vcmUgc3VjaCBmaWVsZHMuCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgYS5zZXRPcHRpb25hbEludDMyKDEpOworICAgIGEuc2V0T3B0aW9uYWxTdHJpbmcoIngiKTsKKyAgICBhLnNldE9wdGlvbmFsQnl0ZXMoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoInkiKSk7CisgICAgYS5zZXRPcHRpb25hbE5lc3RlZEVudW0oVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFSKTsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBiID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBiLnNldE9wdGlvbmFsSW50MzIoMCk7CisgICAgYi5zZXRPcHRpb25hbFN0cmluZygiIik7CisgICAgYi5zZXRPcHRpb25hbEJ5dGVzKEJ5dGVTdHJpbmcuRU1QVFkpOworICAgIGIuc2V0T3B0aW9uYWxOZXN0ZWRFbnVtKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTyk7CisgICAgYS5tZXJnZUZyb20oYi5idWlsZCgpKTsKKyAgICBtZXNzYWdlID0gYS5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygxLCBtZXNzYWdlLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgbWVzc2FnZS5nZXRPcHRpb25hbFN0cmluZygpKTsKKyAgICBhc3NlcnRFcXVhbHMoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoInkiKSwgbWVzc2FnZS5nZXRPcHRpb25hbEJ5dGVzKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworCisgICAgLy8gZXF1YWxzKCkvaGFzaENvZGUoKSBzaG91bGQgcHJvZHVjZSB0aGUgc2FtZSByZXN1bHRzLgorICAgIFRlc3RBbGxUeXBlcyBlbXB0eSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydFRydWUoZW1wdHkuZXF1YWxzKG1lc3NhZ2UpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuZXF1YWxzKGVtcHR5KSk7CisgICAgYXNzZXJ0RXF1YWxzKGVtcHR5Lmhhc2hDb2RlKCksIG1lc3NhZ2UuaGFzaENvZGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGRQcmVzZW5jZUJ5UmVmbGVjdGlvbigpIHsKKyAgICBEZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpOworICAgIEZpZWxkRGVzY3JpcHRvciBvcHRpb25hbEludDMyRmllbGQgPSBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50MzIiKTsKKyAgICBGaWVsZERlc2NyaXB0b3Igb3B0aW9uYWxTdHJpbmdGaWVsZCA9IGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9zdHJpbmciKTsKKyAgICBGaWVsZERlc2NyaXB0b3Igb3B0aW9uYWxCeXRlc0ZpZWxkID0gZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2J5dGVzIik7CisgICAgRmllbGREZXNjcmlwdG9yIG9wdGlvbmFsTmVzdGVkRW51bUZpZWxkID0gZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9lbnVtIik7CisKKyAgICAvLyBGaWVsZCBub3QgcHJlc2VudC4KKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKG9wdGlvbmFsSW50MzJGaWVsZCkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQob3B0aW9uYWxTdHJpbmdGaWVsZCkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQob3B0aW9uYWxCeXRlc0ZpZWxkKSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChvcHRpb25hbE5lc3RlZEVudW1GaWVsZCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEFsbEZpZWxkcygpLnNpemUoKSk7CisKKyAgICAvLyBGaWVsZCBzZXQgdG8gZGVmYXVsdCB2YWx1ZSBpcyBzZWVuIGFzIG5vdCBwcmVzZW50LgorICAgIG1lc3NhZ2UgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRPcHRpb25hbEludDMyKDApCisgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiIikKKyAgICAgICAgLnNldE9wdGlvbmFsQnl0ZXMoQnl0ZVN0cmluZy5FTVBUWSkKKyAgICAgICAgLnNldE9wdGlvbmFsTmVzdGVkRW51bShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08pCisgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQob3B0aW9uYWxJbnQzMkZpZWxkKSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChvcHRpb25hbFN0cmluZ0ZpZWxkKSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChvcHRpb25hbEJ5dGVzRmllbGQpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKG9wdGlvbmFsTmVzdGVkRW51bUZpZWxkKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0QWxsRmllbGRzKCkuc2l6ZSgpKTsKKworICAgIC8vIEZpZWxkIHNldCB0byBub24tZGVmYXVsdCB2YWx1ZSBpcyBzZWVuIGFzIHByZXNlbnQuCisgICAgbWVzc2FnZSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMSkKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJ4IikKKyAgICAgICAgLnNldE9wdGlvbmFsQnl0ZXMoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoInkiKSkKKyAgICAgICAgLnNldE9wdGlvbmFsTmVzdGVkRW51bShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIpCisgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChvcHRpb25hbEludDMyRmllbGQpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQob3B0aW9uYWxTdHJpbmdGaWVsZCkpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChvcHRpb25hbEJ5dGVzRmllbGQpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQob3B0aW9uYWxOZXN0ZWRFbnVtRmllbGQpKTsKKyAgICBhc3NlcnRFcXVhbHMoNCwgbWVzc2FnZS5nZXRBbGxGaWVsZHMoKS5zaXplKCkpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZUZpZWxkKCkgeworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuYnVpbGQoKS5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CisgICAgCisgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBuZXN0ZWRCdWlsZGVyID0KKyAgICAgICAgYnVpbGRlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuYnVpbGQoKS5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CisgICAgCisgICAgbmVzdGVkQnVpbGRlci5zZXRWYWx1ZSgxKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnVpbGRlci5idWlsZCgpLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmdldFZhbHVlKCkpOworICAgIAorICAgIGJ1aWxkZXIuY2xlYXJPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmJ1aWxkKCkuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOworICAgIAorICAgIC8vIFVubGlrZSBub24tbWVzc2FnZSBmaWVsZHMsIGlmIHdlIHNldCBhIG1lc3NhZ2UgZmllbGQgdG8gaXRzIGRlZmF1bHQgdmFsdWUgKGkuZS4sCisgICAgLy8gZGVmYXVsdCBpbnN0YW5jZSksIHRoZSBmaWVsZCBzaG91bGQgYmUgc2VlbiBhcyBwcmVzZW50LgorICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5idWlsZCgpLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemVBbmRQYXJzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxJbnQzMigxMjM0KTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsU3RyaW5nKCJoZWxsbyIpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICAvLyBTZXQgYW4gb25lb2YgZmllbGQgdG8gaXRzIGRlZmF1bHQgdmFsdWUgYW5kIGV4cGVjdCBpdCB0byBiZSBzZXJpYWxpemVkIChpLmUuLAorICAgIC8vIGFuIG9uZW9mIGZpZWxkIHNldCB0byB0aGUgZGVmYXVsdCB2YWx1ZSBzaG91bGQgYmUgdHJlYXRlZCBhcyBwcmVzZW50KS4KKyAgICBidWlsZGVyLnNldE9uZW9mSW50MzIoMCk7CisgICAgQnl0ZVN0cmluZyBkYXRhID0gYnVpbGRlci5idWlsZCgpLnRvQnl0ZVN0cmluZygpOworCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBUZXN0QWxsVHlwZXMucGFyc2VGcm9tKGRhdGEpOworICAgIGFzc2VydEVxdWFscygxMjM0LCBtZXNzYWdlLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgICAgLy8gRmllbGRzIG5vdCBzZXQgd2lsbCBoYXZlIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgIGFzc2VydEVxdWFscyhCeXRlU3RyaW5nLkVNUFRZLCBtZXNzYWdlLmdldE9wdGlvbmFsQnl0ZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTywgbWVzc2FnZS5nZXRPcHRpb25hbE5lc3RlZEVudW0oKSk7CisgICAgLy8gVGhlIG1lc3NhZ2UgZmllbGQgaXMgc2V0IGRlc3BpdGUgdGhhdCBpdCdzIHNldCB3aXRoIGEgZGVmYXVsdCBpbnN0YW5jZS4KKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmdldFZhbHVlKCkpOworICAgIC8vIFRoZSBvbmVvZiBmaWVsZCBzZXQgdG8gaXRzIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBwcmVzZW50LgorICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgVGVzdEFsbFR5cGVzLk9uZW9mRmllbGRDYXNlLk9ORU9GX0lOVDMyLCBtZXNzYWdlLmdldE9uZW9mRmllbGRDYXNlKCkpOworICB9CisKKyAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBiLzE2MTczMzk3CisgIC8vIE1ha2Ugc3VyZSB3ZSBoYXZlbid0IHNjcmV3ZWQgdXAgdGhlIGNvZGUgZ2VuZXJhdGlvbiBmb3IgcmVwZWF0ZWQgZmllbGRzLgorICBwdWJsaWMgdm9pZCB0ZXN0UmVwZWF0ZWRGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsSW50MzIoMTIzNCk7CisgICAgYnVpbGRlci5zZXRPcHRpb25hbFN0cmluZygiaGVsbG8iKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZShUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEludDMyKDQzMjEpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRTdHJpbmcoIndvcmxkIik7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICAgIEJ5dGVTdHJpbmcgZGF0YSA9IGJ1aWxkZXIuYnVpbGQoKS50b0J5dGVTdHJpbmcoKTsKKworICAgIFRlc3RPcHRpb25hbEZpZWxkc09ubHkgb3B0aW9uYWxPbmx5TWVzc2FnZSA9IFRlc3RPcHRpb25hbEZpZWxkc09ubHkucGFyc2VGcm9tKGRhdGEpOworICAgIGFzc2VydEVxdWFscygxMjM0LCBvcHRpb25hbE9ubHlNZXNzYWdlLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIG9wdGlvbmFsT25seU1lc3NhZ2UuZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgICAgYXNzZXJ0VHJ1ZShvcHRpb25hbE9ubHlNZXNzYWdlLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgb3B0aW9uYWxPbmx5TWVzc2FnZS5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKS5nZXRWYWx1ZSgpKTsKKworICAgIFRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcmVwZWF0ZWRPbmx5TWVzc2FnZSA9IFRlc3RSZXBlYXRlZEZpZWxkc09ubHkucGFyc2VGcm9tKGRhdGEpOworICAgIGFzc2VydEVxdWFscygxLCByZXBlYXRlZE9ubHlNZXNzYWdlLmdldFJlcGVhdGVkSW50MzJDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDMyMSwgcmVwZWF0ZWRPbmx5TWVzc2FnZS5nZXRSZXBlYXRlZEludDMyKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcmVwZWF0ZWRPbmx5TWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkpOworICAgIGFzc2VydEVxdWFscygid29ybGQiLCByZXBlYXRlZE9ubHlNZXNzYWdlLmdldFJlcGVhdGVkU3RyaW5nKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcmVwZWF0ZWRPbmx5TWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgcmVwZWF0ZWRPbmx5TWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoMCkuZ2V0VmFsdWUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SXNJbml0aWFsaXplZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworCisgICAgLy8gVGVzdCBvcHRpb25hbCBwcm90bzIgbWVzc2FnZSBmaWVsZHMuCisgICAgVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBwcm90bzJCdWlsZGVyID0KKyAgICAgICAgYnVpbGRlci5nZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyKCk7CisgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkuaXNJbml0aWFsaXplZCgpKTsKKworICAgIHByb3RvMkJ1aWxkZXIuc2V0QSgxKS5zZXRCKDIpLnNldEMoMyk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICAvLyBUZXN0IG9uZW9mIHByb3RvMiBtZXNzYWdlIGZpZWxkcy4KKyAgICBwcm90bzJCdWlsZGVyID0gYnVpbGRlci5nZXRPbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyKCk7CisgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkuaXNJbml0aWFsaXplZCgpKTsKKworICAgIHByb3RvMkJ1aWxkZXIuc2V0QSgxKS5zZXRCKDIpLnNldEMoMyk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICAvLyBUZXN0IHJlcGVhdGVkIHByb3RvMiBtZXNzYWdlIGZpZWxkcy4KKyAgICBwcm90bzJCdWlsZGVyID0gYnVpbGRlci5hZGRSZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyKCk7CisgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkuaXNJbml0aWFsaXplZCgpKTsKKworICAgIHByb3RvMkJ1aWxkZXIuc2V0QSgxKS5zZXRCKDIpLnNldEMoMyk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpLmlzSW5pdGlhbGl6ZWQoKSk7CisgIH0KKworICAKKyAgLy8gVGVzdCB0aGF0IHVua25vd24gZmllbGRzIGFyZSBkcm9wcGVkLgorICBwdWJsaWMgdm9pZCB0ZXN0VW5rbm93bkZpZWxkcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxJbnQzMigxMjM0KTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkSW50MzIoNTY3OCk7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgQnl0ZVN0cmluZyBkYXRhID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICAKKyAgICBUZXN0T3B0aW9uYWxGaWVsZHNPbmx5IG9wdGlvbmFsT25seU1lc3NhZ2UgPQorICAgICAgICBUZXN0T3B0aW9uYWxGaWVsZHNPbmx5LnBhcnNlRnJvbShkYXRhKTsKKyAgICAvLyBVbmtub3duRmllbGRTZXQgc2hvdWxkIGJlIGVtcHR5LgorICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgMCwgb3B0aW9uYWxPbmx5TWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkudG9CeXRlU3RyaW5nKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzNCwgb3B0aW9uYWxPbmx5TWVzc2FnZS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIG1lc3NhZ2UgPSBUZXN0QWxsVHlwZXMucGFyc2VGcm9tKG9wdGlvbmFsT25seU1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydEVxdWFscygxMjM0LCBtZXNzYWdlLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgLy8gVGhlIHJlcGVhdGVkIGZpZWxkIGlzIGRpc2NhcmRlZCBiZWNhdXNlIGl0J3MgdW5rbm93biB0byB0aGUgb3B0aW9uYWwtb25seQorICAgIC8vIG1lc3NhZ2UuCisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkpOworICAgIAorICAgIER5bmFtaWNNZXNzYWdlIGR5bmFtaWNPcHRpb25hbE9ubHlNZXNzYWdlID0KKyAgICAgICAgRHluYW1pY01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKAorICAgICAgICAgICAgVGVzdE9wdGlvbmFsRmllbGRzT25seS5nZXREZXNjcmlwdG9yKCkpCisgICAgICAgIC5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGRhdGEpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgMCwgZHluYW1pY09wdGlvbmFsT25seU1lc3NhZ2UuZ2V0VW5rbm93bkZpZWxkcygpLnRvQnl0ZVN0cmluZygpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKG9wdGlvbmFsT25seU1lc3NhZ2UudG9CeXRlU3RyaW5nKCksCisgICAgICAgIGR5bmFtaWNPcHRpb25hbE9ubHlNZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRm9yY2VGaWVsZEJ1aWxkZXJzUHJlUnVuLmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Gb3JjZUZpZWxkQnVpbGRlcnNQcmVSdW4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTJiYTM3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvRm9yY2VGaWVsZEJ1aWxkZXJzUHJlUnVuLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworLyoqCisgKiBBIHByZXJ1biBmb3IgYSB0ZXN0IHN1aXRlIHRoYXQgYWxsb3dzIHJ1bm5pbmcgdGhlIGZ1bGwgcHJvdG9jb2wgYnVmZmVyCisgKiB0ZXN0cyBpbiBhIG1vZGUgdGhhdCBkaXNhYmxlcyB0aGUgb3B0aW1pemF0aW9uIGZvciBub3QgdXNpbmcKKyAqIHtAbGluayBSZXBlYXRlZEZpZWxkQnVpbGRlcn0gYW5kIHtAbGluayBTaW5nbGVGaWVsZEJ1aWxkZXJ9IHVudGlsIHRoZXkgYXJlCisgKiByZXF1ZXN0ZWQuIFRoaXMgYWxsb3dzIHVzIHRvIHJ1biBhbGwgdGhlIHRlc3RzIHRocm91Z2ggYm90aCBjb2RlIHBhdGhzCisgKiBhbmQgZW5zdXJlcyB0aGF0IGJvdGggY29kZSBwYXRocyBwcm9kdWNlIGlkZW50aWNhbCByZXN1bHRzLgorICoKKyAqIEBhdXRob3Igam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorICovCitwdWJsaWMgY2xhc3MgRm9yY2VGaWVsZEJ1aWxkZXJzUHJlUnVuIGltcGxlbWVudHMgUnVubmFibGUgeworCisgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgR2VuZXJhdGVkTWVzc2FnZS5lbmFibGVBbHdheXNVc2VGaWVsZEJ1aWxkZXJzRm9yVGVzdGluZygpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9HZW5lcmF0ZWRNZXNzYWdlVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmQ4ZDFhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZVRlc3QuamF2YQpAQCAtMCwwICsxLDE2NjIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuVGVzdEFsbEV4dGVuc2lvbnNMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydDsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXI7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk11bHRpcGxlRmlsZXNUZXN0UHJvdG87CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZDsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb247CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3M7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuU2VydmljZVdpdGhOb091dGVyOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemU7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW07CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjI7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogVW5pdCB0ZXN0IGZvciBnZW5lcmF0ZWQgbWVzc2FnZXMgYW5kIGdlbmVyYXRlZCBjb2RlLiAgU2VlIGFsc28KKyAqIHtAbGluayBNZXNzYWdlVGVzdH0sIHdoaWNoIHRlc3RzIHNvbWUgZ2VuZXJhdGVkIG1lc3NhZ2UgZnVuY3Rpb25hbGl0eS4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgY2xhc3MgR2VuZXJhdGVkTWVzc2FnZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvblRlc3RlciA9CisgICAgbmV3IFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIoVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKSwgbnVsbCk7CisKKyAgcHVibGljIHZvaWQgdGVzdERlZmF1bHRJbnN0YW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFNhbWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSk7CisgICAgYXNzZXJ0U2FtZShUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCisgICAgICAgICAgICAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLmdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZU9yQnVpbGRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RVdGlsLnNldEFsbEZpZWxkcyhidWlsZGVyKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VXNpbmdCdWlsZGVyTXVsdGlwbGVUaW1lcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIC8vIHByaW1pdGl2ZSBmaWVsZCBzY2FsYXIgYW5kIHJlcGVhdGVkCisgICAgYnVpbGRlci5zZXRPcHRpb25hbFNmaXhlZDY0KDEwMCk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEludDMyKDEwMCk7CisgICAgLy8gZW51bSBmaWVsZCBzY2FsYXIgYW5kIHJlcGVhdGVkCisgICAgYnVpbGRlci5zZXRPcHRpb25hbEltcG9ydEVudW0oVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bS5JTVBPUlRfQkFSKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkSW1wb3J0RW51bShVbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9CQVIpOworICAgIC8vIHByb3RvIGZpZWxkIHNjYWxhciBhbmQgcmVwZWF0ZWQKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMSkpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZShGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygxKSk7CisKKyAgICBUZXN0QWxsVHlwZXMgdmFsdWUxID0gYnVpbGRlci5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKDEwMCwgdmFsdWUxLmdldE9wdGlvbmFsU2ZpeGVkNjQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEwMCwgdmFsdWUxLmdldFJlcGVhdGVkSW50MzIoMCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9CQVIsCisgICAgICAgIHZhbHVlMS5nZXRPcHRpb25hbEltcG9ydEVudW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uSU1QT1JUX0JBUiwKKyAgICAgICAgdmFsdWUxLmdldFJlcGVhdGVkSW1wb3J0RW51bSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHZhbHVlMS5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgdmFsdWUxLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoMCkuZ2V0QygpKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGJ1aWxkZXIgZGlkbid0IHVwZGF0ZSBwcmV2aW91c2x5IGNyZWF0ZWQgdmFsdWVzCisgICAgYnVpbGRlci5zZXRPcHRpb25hbFNmaXhlZDY0KDIwMCk7CisgICAgYnVpbGRlci5zZXRSZXBlYXRlZEludDMyKDAsIDIwMCk7CisgICAgYnVpbGRlci5zZXRPcHRpb25hbEltcG9ydEVudW0oVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bS5JTVBPUlRfRk9PKTsKKyAgICBidWlsZGVyLnNldFJlcGVhdGVkSW1wb3J0RW51bSgwLCBVbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9GT08pOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZShGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygyKSk7CisgICAgYnVpbGRlci5zZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKDAsIEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRDKDIpKTsKKworICAgIFRlc3RBbGxUeXBlcyB2YWx1ZTIgPSBidWlsZGVyLmJ1aWxkKCk7CisKKyAgICAvLyBNYWtlIHN1cmUgdmFsdWUxIGRpZG4ndCBjaGFuZ2UuCisgICAgYXNzZXJ0RXF1YWxzKDEwMCwgdmFsdWUxLmdldE9wdGlvbmFsU2ZpeGVkNjQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEwMCwgdmFsdWUxLmdldFJlcGVhdGVkSW50MzIoMCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9CQVIsCisgICAgICAgIHZhbHVlMS5nZXRPcHRpb25hbEltcG9ydEVudW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uSU1QT1JUX0JBUiwKKyAgICAgICAgdmFsdWUxLmdldFJlcGVhdGVkSW1wb3J0RW51bSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHZhbHVlMS5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgdmFsdWUxLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoMCkuZ2V0QygpKTsKKworICAgIC8vIE1ha2Ugc3VyZSB2YWx1ZTIgaXMgY29ycmVjdAorICAgIGFzc2VydEVxdWFscygyMDAsIHZhbHVlMi5nZXRPcHRpb25hbFNmaXhlZDY0KCkpOworICAgIGFzc2VydEVxdWFscygyMDAsIHZhbHVlMi5nZXRSZXBlYXRlZEludDMyKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bS5JTVBPUlRfRk9PLAorICAgICAgICB2YWx1ZTIuZ2V0T3B0aW9uYWxJbXBvcnRFbnVtKCkpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9GT08sCisgICAgICAgIHZhbHVlMi5nZXRSZXBlYXRlZEltcG9ydEVudW0oMCkpOworICAgIGFzc2VydEVxdWFscygyLCB2YWx1ZTIuZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIHZhbHVlMi5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKDApLmdldEMoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UHJvdG9zU2hhcmVSZXBlYXRlZEFycmF5c0lmRGlkbnRDaGFuZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkSW50MzIoMTAwKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworCisgICAgVGVzdEFsbFR5cGVzIHZhbHVlMSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0QWxsVHlwZXMgdmFsdWUyID0gdmFsdWUxLnRvQnVpbGRlcigpLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRTYW1lKHZhbHVlMS5nZXRSZXBlYXRlZEludDMyTGlzdCgpLCB2YWx1ZTIuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSk7CisgICAgYXNzZXJ0U2FtZSh2YWx1ZTEuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSwKKyAgICAgICAgdmFsdWUyLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcGVhdGVkQXJyYXlzQXJlSW1tdXRhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEludDMyKDEwMCk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEltcG9ydEVudW0oVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bS5JTVBPUlRfQkFSKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKGJ1aWxkZXIuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUoYnVpbGRlci5nZXRSZXBlYXRlZEltcG9ydEVudW1MaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUoYnVpbGRlci5nZXRSZXBlYXRlZEZsb2F0TGlzdCgpKTsKKworCisgICAgVGVzdEFsbFR5cGVzIHZhbHVlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkSW50MzJMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkSW1wb3J0RW51bUxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VkTWVzc2FnZXNBcmVJbW11dGFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMgdmFsdWUgPSBUZXN0QWxsVHlwZXMuUEFSU0VSLnBhcnNlRnJvbSgKKyAgICAgICAgVGVzdFV0aWwuZ2V0QWxsU2V0KCkudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkSW50MzJMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkSW50NjRMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkVWludDMyTGlzdCgpKTsKKyAgICBhc3NlcnRJc1VubW9kaWZpYWJsZSh2YWx1ZS5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkU2ludDY0TGlzdCgpKTsKKyAgICBhc3NlcnRJc1VubW9kaWZpYWJsZSh2YWx1ZS5nZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkQm9vbExpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkQnl0ZXNMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkR3JvdXBMaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSk7CisgICAgYXNzZXJ0SXNVbm1vZGlmaWFibGUodmFsdWUuZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpKTsKKyAgICBhc3NlcnRJc1VubW9kaWZpYWJsZSh2YWx1ZS5nZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKHZhbHVlLmdldFJlcGVhdGVkSW1wb3J0RW51bUxpc3QoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0SXNVbm1vZGlmaWFibGUoTGlzdDw/PiBsaXN0KSB7CisgICAgaWYgKGxpc3QgPT0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkpIHsKKyAgICAgIC8vIE9LQVkgLS0gTmVlZCB0byBjaGVjayB0aGlzIGIvYyBFbXB0eUxpc3QgYWxsb3dzIHlvdSB0byBjYWxsIGNsZWFyLgorICAgIH0gZWxzZSB7CisgICAgICB0cnkgeworICAgICAgICBsaXN0LmNsZWFyKCk7CisgICAgICAgIGZhaWwoIkxpc3Qgd2Fzbid0IGltbXV0YWJsZSIpOworICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAvLyBnb29kCisgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNldHRlcnNSZWplY3ROdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxTdHJpbmcobnVsbCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICAgIHRyeSB7CisgICAgICBidWlsZGVyLnNldE9wdGlvbmFsQnl0ZXMobnVsbCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICAgIHRyeSB7CisgICAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgoVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG51bGwpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgICB0cnkgeworICAgICAgYnVpbGRlci5zZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoCisgICAgICAgICAgKFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIpIG51bGwpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgICB0cnkgeworICAgICAgYnVpbGRlci5zZXRPcHRpb25hbE5lc3RlZEVudW0obnVsbCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICAgIHRyeSB7CisgICAgICBidWlsZGVyLmFkZFJlcGVhdGVkU3RyaW5nKG51bGwpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgICB0cnkgeworICAgICAgYnVpbGRlci5hZGRSZXBlYXRlZEJ5dGVzKG51bGwpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgICB0cnkgeworICAgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoKFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBudWxsKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAorICAgICAgICAgIChUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyKSBudWxsKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRFbnVtKG51bGwpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZXBlYXRlZFNldHRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRBbGxGaWVsZHMoYnVpbGRlcik7CisgICAgVGVzdFV0aWwubW9kaWZ5UmVwZWF0ZWRGaWVsZHMoYnVpbGRlcik7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgVGVzdFV0aWwuYXNzZXJ0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZChtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZXBlYXRlZFNldHRlcnNSZWplY3ROdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkU3RyaW5nKCJvbmUiKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkU3RyaW5nKCJ0d28iKTsKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5zZXRSZXBlYXRlZFN0cmluZygxLCBudWxsKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkQnl0ZXMoVGVzdFV0aWwudG9CeXRlcygib25lIikpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRCeXRlcyhUZXN0VXRpbC50b0J5dGVzKCJ0d28iKSk7CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWRCeXRlcygxLCBudWxsKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKKyAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYigyMTgpLmJ1aWxkKCkpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAorICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDQ1NikuYnVpbGQoKSk7CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKDEsIChUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgbnVsbCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICAgIHRyeSB7CisgICAgICBidWlsZGVyLnNldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKKyAgICAgICAgICAxLCAoVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlcikgbnVsbCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorCisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZEVudW0oVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkTmVzdGVkRW51bShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIpOworICAgIHRyeSB7CisgICAgICBidWlsZGVyLnNldFJlcGVhdGVkTmVzdGVkRW51bSgxLCBudWxsKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVwZWF0ZWRBcHBlbmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKworICAgIGJ1aWxkZXIuYWRkQWxsUmVwZWF0ZWRJbnQzMihBcnJheXMuYXNMaXN0KDEsIDIsIDMsIDQpKTsKKyAgICBidWlsZGVyLmFkZEFsbFJlcGVhdGVkRm9yZWlnbkVudW0oQXJyYXlzLmFzTGlzdChGb3JlaWduRW51bS5GT1JFSUdOX0JBWikpOworCisgICAgRm9yZWlnbk1lc3NhZ2UgZm9yZWlnbk1lc3NhZ2UgPQorICAgICAgICBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygxMikuYnVpbGQoKTsKKyAgICBidWlsZGVyLmFkZEFsbFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoQXJyYXlzLmFzTGlzdChmb3JlaWduTWVzc2FnZSkpOworCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSwgQXJyYXlzLmFzTGlzdCgxLCAyLCAzLCA0KSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKSwKKyAgICAgICAgQXJyYXlzLmFzTGlzdChGb3JlaWduRW51bS5GT1JFSUdOX0JBWikpOworICAgIGFzc2VydEVxdWFscygxLCBtZXNzYWdlLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgwKS5nZXRDKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcGVhdGVkQXBwZW5kUmVqZWN0c051bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKworICAgIEZvcmVpZ25NZXNzYWdlIGZvcmVpZ25NZXNzYWdlID0KKyAgICAgICAgRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMTIpLmJ1aWxkKCk7CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuYWRkQWxsUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKKyAgICAgICAgICBBcnJheXMuYXNMaXN0KGZvcmVpZ25NZXNzYWdlLCAoRm9yZWlnbk1lc3NhZ2UpIG51bGwpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5hZGRBbGxSZXBlYXRlZEZvcmVpZ25FbnVtKAorICAgICAgICAgIEFycmF5cy5hc0xpc3QoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVosIG51bGwpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5hZGRBbGxSZXBlYXRlZFN0cmluZyhBcnJheXMuYXNMaXN0KCJvbmUiLCBudWxsKSk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuYWRkQWxsUmVwZWF0ZWRCeXRlcyhBcnJheXMuYXNMaXN0KFRlc3RVdGlsLnRvQnl0ZXMoIm9uZSIpLCBudWxsKSk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0UmVwZWF0ZWRBcHBlbmRJdGVyYXRlT25seU9uY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBJdGVyYWJsZSB0aGF0IGNhbiBvbmx5IGJlIGl0ZXJhdGVkIG9uY2UuCisgICAgSXRlcmFibGU8U3RyaW5nPiBzdHJpbmdJdGVyYWJsZSA9IG5ldyBJdGVyYWJsZTxTdHJpbmc+KCkgeworICAgICAgcHJpdmF0ZSBib29sZWFuIGNhbGxlZCA9IGZhbHNlOworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgSXRlcmF0b3I8U3RyaW5nPiBpdGVyYXRvcigpIHsKKyAgICAgICAgaWYgKGNhbGxlZCkgeworICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBjYWxsZWQgPSB0cnVlOworICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdCgib25lIiwgInR3byIsICJ0aHJlZSIpLml0ZXJhdG9yKCk7CisgICAgICB9CisgICAgfTsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmFkZEFsbFJlcGVhdGVkU3RyaW5nKHN0cmluZ0l0ZXJhYmxlKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgYnVpbGRlci5nZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkpOworICAgIGFzc2VydEVxdWFscygib25lIiwgYnVpbGRlci5nZXRSZXBlYXRlZFN0cmluZygwKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJ0d28iLCBidWlsZGVyLmdldFJlcGVhdGVkU3RyaW5nKDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoInRocmVlIiwgYnVpbGRlci5nZXRSZXBlYXRlZFN0cmluZygyKSk7CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5hZGRBbGxSZXBlYXRlZFN0cmluZyhzdHJpbmdJdGVyYWJsZSk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUZyb21PdGhlclJlamVjdHNOdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgICAgYnVpbGRlci5tZXJnZUZyb20oKFRlc3RBbGxUeXBlcykgbnVsbCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNldHRpbmdGb3JlaWduTWVzc2FnZVVzaW5nQnVpbGRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQorICAgICAgICAvLyBQYXNzIGJ1aWxkZXIgZm9yIGZvcmVpZ24gbWVzc2FnZSBpbnN0YW5jZS4KKyAgICAgICAgLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMTIzKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgVGVzdEFsbFR5cGVzIGV4cGVjdGVkTWVzc2FnZSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLy8gQ3JlYXRlIGV4cGVjdGVkIHZlcnNpb24gcGFzc2luZyBmb3JlaWduIG1lc3NhZ2UgaW5zdGFuY2UgZXhwbGljaXRseS4KKyAgICAgICAgLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoCisgICAgICAgICAgICBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygxMjMpLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworICAgIC8vIFRPRE8obmdkKTogVXBncmFkZSB0byB1c2luZyByZWFsICNlcXVhbHMgbWV0aG9kIG9uY2UgaW1wbGVtZW50ZWQKKyAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRNZXNzYWdlLnRvU3RyaW5nKCksIG1lc3NhZ2UudG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2V0dGluZ1JlcGVhdGVkRm9yZWlnbk1lc3NhZ2VVc2luZ0J1aWxkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLy8gUGFzcyBidWlsZGVyIGZvciBmb3JlaWduIG1lc3NhZ2UgaW5zdGFuY2UuCisgICAgICAgIC5hZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRDKDQ1NikpCisgICAgICAgIC5idWlsZCgpOworICAgIFRlc3RBbGxUeXBlcyBleHBlY3RlZE1lc3NhZ2UgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgIC8vIENyZWF0ZSBleHBlY3RlZCB2ZXJzaW9uIHBhc3NpbmcgZm9yZWlnbiBtZXNzYWdlIGluc3RhbmNlIGV4cGxpY2l0bHkuCisgICAgICAgIC5hZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAorICAgICAgICAgICAgRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoNDU2KS5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRNZXNzYWdlLnRvU3RyaW5nKCksIG1lc3NhZ2UudG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0VXRpbC5hc3NlcnRDbGVhcihUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICAgIFRlc3RVdGlsLmFzc2VydENsZWFyKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuYnVpbGQoKSk7CisKKyAgICBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgbWVzc2FnZSA9CisgICAgICAgIFRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICBhc3NlcnRFcXVhbHMoIlx1MTIzNCIsIG1lc3NhZ2UuZ2V0VXRmOFN0cmluZygpKTsKKyAgICBhc3NlcnRFcXVhbHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBtZXNzYWdlLmdldEluZkRvdWJsZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBtZXNzYWdlLmdldE5lZ0luZkRvdWJsZSgpKTsKKyAgICBhc3NlcnRUcnVlKERvdWJsZS5pc05hTihtZXNzYWdlLmdldE5hbkRvdWJsZSgpKSk7CisgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LlBPU0lUSVZFX0lORklOSVRZLCBtZXNzYWdlLmdldEluZkZsb2F0KCkpOworICAgIGFzc2VydEVxdWFscyhGbG9hdC5ORUdBVElWRV9JTkZJTklUWSwgbWVzc2FnZS5nZXROZWdJbmZGbG9hdCgpKTsKKyAgICBhc3NlcnRUcnVlKEZsb2F0LmlzTmFOKG1lc3NhZ2UuZ2V0TmFuRmxvYXQoKSkpOworICAgIGFzc2VydEVxdWFscygiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIiwgbWVzc2FnZS5nZXRDcHBUcmlncmFwaCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RVdGlsLmFzc2VydENsZWFyKGJ1aWxkZXIpOworICAgIFRlc3RVdGlsLnNldEFsbEZpZWxkcyhidWlsZGVyKTsKKyAgICBidWlsZGVyLmNsZWFyKCk7CisgICAgVGVzdFV0aWwuYXNzZXJ0Q2xlYXIoYnVpbGRlcik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVmbGVjdGlvbkdldHRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRBbGxGaWVsZHMoYnVpbGRlcik7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlZmxlY3Rpb25TZXR0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldChidWlsZGVyKTsKKworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldChtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWZsZWN0aW9uU2V0dGVyc1JlamVjdE51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydFJlZmxlY3Rpb25TZXR0ZXJzUmVqZWN0TnVsbChidWlsZGVyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWZsZWN0aW9uUmVwZWF0ZWRTZXR0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIubW9kaWZ5UmVwZWF0ZWRGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIFRlc3RVdGlsLmFzc2VydFJlcGVhdGVkRmllbGRzTW9kaWZpZWQoYnVpbGRlcik7CisKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRSZXBlYXRlZEZpZWxkc01vZGlmaWVkKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlZmxlY3Rpb25SZXBlYXRlZFNldHRlcnNSZWplY3ROdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRSZWZsZWN0aW9uUmVwZWF0ZWRTZXR0ZXJzUmVqZWN0TnVsbChidWlsZGVyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWZsZWN0aW9uRGVmYXVsdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICByZWZsZWN0aW9uVGVzdGVyLmFzc2VydENsZWFyVmlhUmVmbGVjdGlvbigKKyAgICAgIFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgcmVmbGVjdGlvblRlc3Rlci5hc3NlcnRDbGVhclZpYVJlZmxlY3Rpb24oCisgICAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLmJ1aWxkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlZmxlY3Rpb25HZXRPbmVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIHJlZmxlY3Rpb25UZXN0ZXIuc2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihidWlsZGVyKTsKKyAgICBEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YgPQorICAgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmdldE9uZW9mcygpLmdldCgwKTsKKyAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQgPQorICAgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgib25lb2ZfYnl0ZXMiKTsKKyAgICBhc3NlcnRTYW1lKGZpZWxkLCBidWlsZGVyLmdldE9uZW9mRmllbGREZXNjcmlwdG9yKG9uZW9mKSk7CisKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRTYW1lKGZpZWxkLCBtZXNzYWdlLmdldE9uZW9mRmllbGREZXNjcmlwdG9yKG9uZW9mKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVmbGVjdGlvbkNsZWFyT25lb2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICByZWZsZWN0aW9uVGVzdGVyLnNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisgICAgRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mID0KKyAgICAgICAgVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKS5nZXRPbmVvZnMoKS5nZXQoMCk7CisgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkID0KKyAgICAgICAgVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKS5maW5kRmllbGRCeU5hbWUoIm9uZW9mX2J5dGVzIik7CisKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaGFzT25lb2Yob25lb2YpKTsKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaGFzRmllbGQoZmllbGQpKTsKKyAgICBidWlsZGVyLmNsZWFyT25lb2Yob25lb2YpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaGFzT25lb2Yob25lb2YpKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmhhc0ZpZWxkKGZpZWxkKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RW51bUludGVyZmFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRydWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlZmF1bHROZXN0ZWRFbnVtKCkKKyAgICAgICAgaW5zdGFuY2VvZiBQcm90b2NvbE1lc3NhZ2VFbnVtKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFbnVtTWFwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSW50ZXJuYWwuRW51bUxpdGVNYXA8Rm9yZWlnbkVudW0+IG1hcCA9IEZvcmVpZ25FbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKTsKKworICAgIGZvciAoRm9yZWlnbkVudW0gdmFsdWUgOiBGb3JlaWduRW51bS52YWx1ZXMoKSkgeworICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBtYXAuZmluZFZhbHVlQnlOdW1iZXIodmFsdWUuZ2V0TnVtYmVyKCkpKTsKKyAgICB9CisKKyAgICBhc3NlcnRUcnVlKG1hcC5maW5kVmFsdWVCeU51bWJlcigxMjM0NSkgPT0gbnVsbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VQYWNrZWRUb1VucGFja2VkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFVucGFja2VkVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RVbnBhY2tlZFR5cGVzIG1lc3NhZ2UgPQorICAgICAgYnVpbGRlci5tZXJnZUZyb20oVGVzdFV0aWwuZ2V0UGFja2VkU2V0KCkudG9CeXRlU3RyaW5nKCkpLmJ1aWxkKCk7CisgICAgVGVzdFV0aWwuYXNzZXJ0VW5wYWNrZWRGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VVbnBhY2tlZFRvUGFja2VkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RQYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGVzdFBhY2tlZFR5cGVzIG1lc3NhZ2UgPQorICAgICAgYnVpbGRlci5tZXJnZUZyb20oVGVzdFV0aWwuZ2V0VW5wYWNrZWRTZXQoKS50b0J5dGVTdHJpbmcoKSkuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRQYWNrZWRGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBFeHRlbnNpb25zLgorCisgIFRlc3RVdGlsLlJlZmxlY3Rpb25UZXN0ZXIgZXh0ZW5zaW9uc1JlZmxlY3Rpb25UZXN0ZXIgPQorICAgIG5ldyBUZXN0VXRpbC5SZWZsZWN0aW9uVGVzdGVyKFRlc3RBbGxFeHRlbnNpb25zLmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpKTsKKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uTWVzc2FnZU9yQnVpbGRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRBbGxFeHRlbnNpb25zKGJ1aWxkZXIpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgVGVzdFV0aWwuYXNzZXJ0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFeHRlbnNpb25SZXBlYXRlZFNldHRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCk7CisgICAgVGVzdFV0aWwuc2V0QWxsRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5tb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnMoYnVpbGRlcik7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZChtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFeHRlbnNpb25EZWZhdWx0cygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RVdGlsLmFzc2VydEV4dGVuc2lvbnNDbGVhcihUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgVGVzdFV0aWwuYXNzZXJ0RXh0ZW5zaW9uc0NsZWFyKFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKS5idWlsZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFeHRlbnNpb25SZWZsZWN0aW9uR2V0dGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRBbGxFeHRlbnNpb25zKGJ1aWxkZXIpOworICAgIGV4dGVuc2lvbnNSZWZsZWN0aW9uVGVzdGVyLmFzc2VydEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oYnVpbGRlcik7CisKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGV4dGVuc2lvbnNSZWZsZWN0aW9uVGVzdGVyLmFzc2VydEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24obWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uUmVmbGVjdGlvblNldHRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCk7CisgICAgZXh0ZW5zaW9uc1JlZmxlY3Rpb25UZXN0ZXIuc2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxFeHRlbnNpb25zU2V0KGJ1aWxkZXIpOworCisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEV4dGVuc2lvblJlZmxlY3Rpb25TZXR0ZXJzUmVqZWN0TnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKTsKKyAgICBleHRlbnNpb25zUmVmbGVjdGlvblRlc3Rlci5hc3NlcnRSZWZsZWN0aW9uU2V0dGVyc1JlamVjdE51bGwoYnVpbGRlcik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uUmVmbGVjdGlvblJlcGVhdGVkU2V0dGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKTsKKyAgICBleHRlbnNpb25zUmVmbGVjdGlvblRlc3Rlci5zZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKGJ1aWxkZXIpOworICAgIGV4dGVuc2lvbnNSZWZsZWN0aW9uVGVzdGVyLm1vZGlmeVJlcGVhdGVkRmllbGRzVmlhUmVmbGVjdGlvbihidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZChidWlsZGVyKTsKKworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgVGVzdFV0aWwuYXNzZXJ0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uUmVmbGVjdGlvblJlcGVhdGVkU2V0dGVyc1JlamVjdE51bGwoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpOworICAgIGV4dGVuc2lvbnNSZWZsZWN0aW9uVGVzdGVyLmFzc2VydFJlZmxlY3Rpb25SZXBlYXRlZFNldHRlcnNSZWplY3ROdWxsKAorICAgICAgICBidWlsZGVyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFeHRlbnNpb25SZWZsZWN0aW9uRGVmYXVsdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBleHRlbnNpb25zUmVmbGVjdGlvblRlc3Rlci5hc3NlcnRDbGVhclZpYVJlZmxlY3Rpb24oCisgICAgICBUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgZXh0ZW5zaW9uc1JlZmxlY3Rpb25UZXN0ZXIuYXNzZXJ0Q2xlYXJWaWFSZWZsZWN0aW9uKAorICAgICAgVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpLmJ1aWxkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENsZWFyRXh0ZW5zaW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gY2xlYXJFeHRlbnNpb24oKSBpcyBub3QgYWN0dWFsbHkgdXNlZCBpbiBUZXN0VXRpbCwgc28gdHJ5IGl0IG1hbnVhbGx5LgorICAgIGFzc2VydEZhbHNlKAorICAgICAgVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRFeHRlbnNpb24oVW5pdHRlc3RQcm90by5vcHRpb25hbEludDMyRXh0ZW5zaW9uLCAxKQorICAgICAgICAuY2xlYXJFeHRlbnNpb24oVW5pdHRlc3RQcm90by5vcHRpb25hbEludDMyRXh0ZW5zaW9uKQorICAgICAgICAuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbnQzMkV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFscygwLAorICAgICAgVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpCisgICAgICAgIC5hZGRFeHRlbnNpb24oVW5pdHRlc3RQcm90by5yZXBlYXRlZEludDMyRXh0ZW5zaW9uLCAxKQorICAgICAgICAuY2xlYXJFeHRlbnNpb24oVW5pdHRlc3RQcm90by5yZXBlYXRlZEludDMyRXh0ZW5zaW9uKQorICAgICAgICAuZ2V0RXh0ZW5zaW9uQ291bnQoVW5pdHRlc3RQcm90by5yZXBlYXRlZEludDMyRXh0ZW5zaW9uKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uQ29weSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zIG9yaWdpbmFsID0gVGVzdFV0aWwuZ2V0QWxsRXh0ZW5zaW9uc1NldCgpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIGNvcHkgPSBUZXN0QWxsRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKG9yaWdpbmFsKS5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEV4dGVuc2lvbnNTZXQoY29weSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uTWVyZ2VGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgb3JpZ2luYWwgPQorICAgICAgVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRFeHRlbnNpb24oVW5pdHRlc3RQcm90by5vcHRpb25hbEludDMyRXh0ZW5zaW9uLCAxKS5idWlsZCgpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lcmdlZCA9CisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20ob3JpZ2luYWwpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VHJ1ZShtZXJnZWQuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbnQzMkV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgMSwgKGludCkgbWVyZ2VkLmdldEV4dGVuc2lvbihVbml0dGVzdFByb3RvLm9wdGlvbmFsSW50MzJFeHRlbnNpb24pKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIExpdGUgRXh0ZW5zaW9ucy4KKworICAvLyBXZSB0ZXN0IGxpdGUgZXh0ZW5zaW9ucyBkaXJlY3RseSBiZWNhdXNlIHRoZXkgaGF2ZSBhIHNlcGFyYXRlCisgIC8vIGltcGxlbWVudGF0aW9uIGZyb20gZnVsbCBleHRlbnNpb25zLiAgSW4gY29udHJhc3QsIHdlIGRvIG5vdCB0ZXN0CisgIC8vIGxpdGUgZmllbGRzIGRpcmVjdGx5IHNpbmNlIHRoZXkgYXJlIGltcGxlbWVudGVkIGV4YWN0bHkgdGhlIHNhbWUgYXMKKyAgLy8gcmVndWxhciBmaWVsZHMuCisKKyAgcHVibGljIHZvaWQgdGVzdExpdGVFeHRlbnNpb25NZXNzYWdlT3JCdWlsZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zTGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgVGVzdFV0aWwuc2V0QWxsRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxFeHRlbnNpb25zU2V0KGJ1aWxkZXIpOworCisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgVGVzdFV0aWwuYXNzZXJ0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RMaXRlRXh0ZW5zaW9uUmVwZWF0ZWRTZXR0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zTGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgVGVzdFV0aWwuc2V0QWxsRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5tb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnMoYnVpbGRlcik7CisgICAgVGVzdFV0aWwuYXNzZXJ0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQoYnVpbGRlcik7CisKKyAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZChtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RMaXRlRXh0ZW5zaW9uRGVmYXVsdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0VXRpbC5hc3NlcnRFeHRlbnNpb25zQ2xlYXIoVGVzdEFsbEV4dGVuc2lvbnNMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRFeHRlbnNpb25zQ2xlYXIoVGVzdEFsbEV4dGVuc2lvbnNMaXRlLm5ld0J1aWxkZXIoKS5idWlsZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhckxpdGVFeHRlbnNpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBjbGVhckV4dGVuc2lvbigpIGlzIG5vdCBhY3R1YWxseSB1c2VkIGluIFRlc3RVdGlsLCBzbyB0cnkgaXQgbWFudWFsbHkuCisgICAgYXNzZXJ0RmFsc2UoCisgICAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlLCAxKQorICAgICAgICAuY2xlYXJFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlKQorICAgICAgICAuaGFzRXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5vcHRpb25hbEludDMyRXh0ZW5zaW9uTGl0ZSkpOworICAgIGFzc2VydEVxdWFscygwLAorICAgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkRXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSwgMSkKKyAgICAgICAgLmNsZWFyRXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSkKKyAgICAgICAgLmdldEV4dGVuc2lvbkNvdW50KFVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdExpdGVFeHRlbnNpb25Db3B5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIG9yaWdpbmFsID0gVGVzdFV0aWwuZ2V0QWxsTGl0ZUV4dGVuc2lvbnNTZXQoKTsKKyAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUgY29weSA9CisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZS5uZXdCdWlsZGVyKG9yaWdpbmFsKS5idWlsZCgpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEV4dGVuc2lvbnNTZXQoY29weSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TGl0ZUV4dGVuc2lvbk1lcmdlRnJvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZSBvcmlnaW5hbCA9CisgICAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlLCAxKS5idWlsZCgpOworICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZSBtZXJnZWQgPQorICAgICAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUubmV3QnVpbGRlcigpLm1lcmdlRnJvbShvcmlnaW5hbCkuYnVpbGQoKTsKKyAgICBhc3NlcnRUcnVlKG1lcmdlZC5oYXNFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAxLCAoaW50KSBtZXJnZWQuZ2V0RXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5vcHRpb25hbEludDMyRXh0ZW5zaW9uTGl0ZSkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gbXVsdGlwbGVfZmlsZXNfdGVzdAorCisgIC8vIFRlc3QgdGhhdCBjdXN0b20gb3B0aW9ucyBvZiBhbiBmaWxlIGxldmVsIGVudW0gYXJlIHByb3Blcmx5IGluaXRpYWxpemVkLgorICAvLyBUaGlzIHRlc3QgbmVlZHMgdG8gYmUgcHV0IGJlZm9yZSBhbnkgb3RoZXIgYWNjZXNzIHRvIE11bHRpcGxlRmlsZXNUZXN0UHJvdG8KKyAgLy8gb3IgbWVzc2FnZXMgZGVmaW5lZCBpbiBtdWx0aXBsZV9maWxlc190ZXN0LnByb3RvIGJlY2F1c2UgdGhlIGNsYXNzIGxvYWRpbmcKKyAgLy8gb3JkZXIgYWZmZWN0cyBpbml0aWFsaXphdGlvbiBwcm9jZXNzIG9mIGN1c3RvbSBvcHRpb25zLgorICBwdWJsaWMgdm9pZCB0ZXN0RW51bVZhbHVlT3B0aW9uc0luTXVsdGlwbGVGaWxlc01vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRFcXVhbHMoMTIzNDUsIEVudW1XaXRoTm9PdXRlci5GT08uZ2V0VmFsdWVEZXNjcmlwdG9yKCkuZ2V0T3B0aW9ucygpCisgICAgICAgIC5nZXRFeHRlbnNpb24oTXVsdGlwbGVGaWxlc1Rlc3RQcm90by5lbnVtVmFsdWVPcHRpb24pLmludFZhbHVlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlRmlsZXNPcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXZSBtb3N0bHkganVzdCB3YW50IHRvIGNoZWNrIHRoYXQgdGhpbmdzIGNvbXBpbGUuCisgICAgTWVzc2FnZVdpdGhOb091dGVyIG1lc3NhZ2UgPQorICAgICAgTWVzc2FnZVdpdGhOb091dGVyLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TmVzdGVkKE1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRJKDEpKQorICAgICAgICAuYWRkRm9yZWlnbihUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLnNldE9wdGlvbmFsSW50MzIoMSkpCisgICAgICAgIC5zZXROZXN0ZWRFbnVtKE1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtLkJBWikKKyAgICAgICAgLnNldEZvcmVpZ25FbnVtKEVudW1XaXRoTm9PdXRlci5CQVIpCisgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBNZXNzYWdlV2l0aE5vT3V0ZXIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpKTsKKworICAgIGFzc2VydEVxdWFscyhNdWx0aXBsZUZpbGVzVGVzdFByb3RvLmdldERlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgTWVzc2FnZVdpdGhOb091dGVyLmdldERlc2NyaXB0b3IoKS5nZXRGaWxlKCkpOworCisgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkID0KKyAgICAgIE1lc3NhZ2VXaXRoTm9PdXRlci5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJmb3JlaWduX2VudW0iKTsKKyAgICBhc3NlcnRFcXVhbHMoRW51bVdpdGhOb091dGVyLkJBUi5nZXRWYWx1ZURlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRGaWVsZChmaWVsZCkpOworCisgICAgYXNzZXJ0RXF1YWxzKE11bHRpcGxlRmlsZXNUZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLAorICAgICAgICAgICAgICAgICBTZXJ2aWNlV2l0aE5vT3V0ZXIuZ2V0RGVzY3JpcHRvcigpLmdldEZpbGUoKSk7CisKKyAgICBhc3NlcnRGYWxzZSgKKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLmhhc0V4dGVuc2lvbigKKyAgICAgICAgTXVsdGlwbGVGaWxlc1Rlc3RQcm90by5leHRlbnNpb25XaXRoT3V0ZXIpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RPcHRpb25hbEZpZWxkV2l0aFJlcXVpcmVkU3ViZmllbGRzT3B0aW1pemVkRm9yU2l6ZSgpCisgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBtZXNzYWdlID0KKyAgICAgICAgVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaXNJbml0aWFsaXplZCgpKTsKKworICAgIG1lc3NhZ2UgPSBUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKS5zZXRPKAorICAgICAgICBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKS5idWlsZFBhcnRpYWwoKQorICAgICAgICApLmJ1aWxkUGFydGlhbCgpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaXNJbml0aWFsaXplZCgpKTsKKworICAgIG1lc3NhZ2UgPSBUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKS5zZXRPKAorICAgICAgICBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKS5zZXRYKDUpLmJ1aWxkUGFydGlhbCgpCisgICAgICAgICkuYnVpbGRQYXJ0aWFsKCk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmlzSW5pdGlhbGl6ZWQoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5pbml0aWFsaXplZEV4dGVuc2lvbkluT3B0aW1pemVkRm9yU2l6ZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T3B0aW1pemVkRm9yU2l6ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5zZXRFeHRlbnNpb24oVGVzdE9wdGltaXplZEZvclNpemUudGVzdEV4dGVuc2lvbjIsCisgICAgICAgIFRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUubmV3QnVpbGRlcigpLmJ1aWxkUGFydGlhbCgpKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKS5pc0luaXRpYWxpemVkKCkpOworCisgICAgYnVpbGRlciA9IFRlc3RPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLnNldEV4dGVuc2lvbihUZXN0T3B0aW1pemVkRm9yU2l6ZS50ZXN0RXh0ZW5zaW9uMiwKKyAgICAgICAgVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5uZXdCdWlsZGVyKCkuc2V0WCgxMCkuYnVpbGRQYXJ0aWFsKCkpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5idWlsZFBhcnRpYWwoKS5pc0luaXRpYWxpemVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFRvQnVpbGRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RVdGlsLnNldEFsbEZpZWxkcyhidWlsZGVyKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgICAgVGVzdFV0aWwuYXNzZXJ0QWxsRmllbGRzU2V0KG1lc3NhZ2UudG9CdWlsZGVyKCkuYnVpbGQoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RmllbGRDb25zdGFudFZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CQl9GSUVMRF9OVU1CRVIsIDEpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuT1BUSU9OQUxfSU5UMzJfRklFTERfTlVNQkVSLCAxKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk9QVElPTkFMR1JPVVBfRklFTERfTlVNQkVSLCAxNik7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5PUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIsIDE4KTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiwgMjEpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSLCAzMSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5SRVBFQVRFREdST1VQX0ZJRUxEX05VTUJFUiwgNDYpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSLCA0OCk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5SRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIsIDUxKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFeHRlbnNpb25Db25zdGFudFZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5TSU5HTEVfRklFTERfTlVNQkVSLCAxMDAwKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuTVVMVElfRklFTERfTlVNQkVSLCAxMDAxKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5PUFRJT05BTF9JTlQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSLCAxKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5PUFRJT05BTEdST1VQX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDE2KTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICBVbml0dGVzdFByb3RvLk9QVElPTkFMX05FU1RFRF9NRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDE4KTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RQcm90by5PUFRJT05BTF9ORVNURURfRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSLCAyMSk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0UHJvdG8uUkVQRUFURURfSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiwgMzEpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLlJFUEVBVEVER1JPVVBfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiwgNDYpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgIFVuaXR0ZXN0UHJvdG8uUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiwgNDgpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdFByb3RvLlJFUEVBVEVEX05FU1RFRF9FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDUxKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWN1cnNpdmVNZXNzYWdlRGVmYXVsdEluc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBtZXNzYWdlID0KKyAgICAgICAgVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UgIT0gbnVsbCk7CisgICAgYXNzZXJ0Tm90TnVsbChtZXNzYWdlLmdldEEoKSk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldEEoKSA9PSBtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRBbGxGaWVsZHMoYnVpbGRlcik7CisgICAgVGVzdEFsbFR5cGVzIGV4cGVjdGVkID0gYnVpbGRlci5idWlsZCgpOworICAgIE9iamVjdE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJhb3MpOworICAgIHRyeSB7CisgICAgICBvdXQud3JpdGVPYmplY3QoZXhwZWN0ZWQpOworICAgIH0gZmluYWxseSB7CisgICAgICBvdXQuY2xvc2UoKTsKKyAgICB9CisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW9zLnRvQnl0ZUFycmF5KCkpOworICAgIE9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGJhaXMpOworICAgIFRlc3RBbGxUeXBlcyBhY3R1YWwgPSAoVGVzdEFsbFR5cGVzKSBpbi5yZWFkT2JqZWN0KCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZVBhcnRpYWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0QWxsVHlwZXMgZXhwZWN0ZWQgPSBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIE9iamVjdE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJhb3MpOworICAgIHRyeSB7CisgICAgICBvdXQud3JpdGVPYmplY3QoZXhwZWN0ZWQpOworICAgIH0gZmluYWxseSB7CisgICAgICBvdXQuY2xvc2UoKTsKKyAgICB9CisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW9zLnRvQnl0ZUFycmF5KCkpOworICAgIE9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGJhaXMpOworICAgIFRlc3RBbGxUeXBlcyBhY3R1YWwgPSAoVGVzdEFsbFR5cGVzKSBpbi5yZWFkT2JqZWN0KCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVudW1WYWx1ZXMoKSB7CisgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUi5nZXROdW1iZXIoKSwKKyAgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUl9WQUxVRSk7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVouZ2V0TnVtYmVyKCksCisgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBWl9WQUxVRSk7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08uZ2V0TnVtYmVyKCksCisgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPT19WQUxVRSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Tm9uTmVzdGVkRXh0ZW5zaW9uSW5pdGlhbGl6YXRpb24oKSB7CisgICAgYXNzZXJ0VHJ1ZShOb25OZXN0ZWRFeHRlbnNpb24ubm9uTmVzdGVkRXh0ZW5zaW9uCisgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpIGluc3RhbmNlb2YgTXlOb25OZXN0ZWRFeHRlbnNpb24pOworICAgIGFzc2VydEVxdWFscygibm9uTmVzdGVkRXh0ZW5zaW9uIiwKKyAgICAgICAgICAgICAgICAgTm9uTmVzdGVkRXh0ZW5zaW9uLm5vbk5lc3RlZEV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCkuZ2V0TmFtZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXN0ZWRFeHRlbnNpb25Jbml0aWFsaXphdGlvbigpIHsKKyAgICBhc3NlcnRUcnVlKE15TmVzdGVkRXh0ZW5zaW9uLnJlY3Vyc2l2ZUV4dGVuc2lvbi5nZXRNZXNzYWdlRGVmYXVsdEluc3RhbmNlKCkKKyAgICAgICAgICAgICAgIGluc3RhbmNlb2YgTWVzc2FnZVRvQmVFeHRlbmRlZCk7CisgICAgYXNzZXJ0RXF1YWxzKCJyZWN1cnNpdmVFeHRlbnNpb24iLAorICAgICAgICAgICAgICAgICBNeU5lc3RlZEV4dGVuc2lvbi5yZWN1cnNpdmVFeHRlbnNpb24uZ2V0RGVzY3JpcHRvcigpLmdldE5hbWUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZUluaXRpYWxpemF0aW9uKCkgeworICAgIGFzc2VydFRydWUoTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5ub25OZXN0ZWRFeHRlbnNpb25MaXRlCisgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZURlZmF1bHRJbnN0YW5jZSgpIGluc3RhbmNlb2YgTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXN0ZWRFeHRlbnNpb25MaXRlSW5pdGlhbGl6YXRpb24oKSB7CisgICAgYXNzZXJ0VHJ1ZShNeU5lc3RlZEV4dGVuc2lvbkxpdGUucmVjdXJzaXZlRXh0ZW5zaW9uTGl0ZQorICAgICAgICAgICAgICAgLmdldE1lc3NhZ2VEZWZhdWx0SW5zdGFuY2UoKSBpbnN0YW5jZW9mIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkYXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR2VuZXJhdGVkTWVzc2FnZS5lbmFibGVBbHdheXNVc2VGaWVsZEJ1aWxkZXJzRm9yVGVzdGluZygpOworICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG5lc3RlZE1lc3NhZ2UxID0KKyAgICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTWVzc2FnZTIgPQorICAgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKworICAgIC8vIFNldCBhbGwgdGhyZWUgZmxhdm9ycyAoZW51bSwgcHJpbWl0aXZlLCBtZXNzYWdlIGFuZCBzaW5ndWxhci9yZXBlYXRlZCkKKyAgICAvLyBhbmQgdmVyaWZ5IG5vIGludmFsaWRhdGlvbnMgZmlyZWQKKyAgICBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCBtb2NrUGFyZW50ID0gbmV3IFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50KCk7CisKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gKFRlc3RBbGxUeXBlcy5CdWlsZGVyKQorICAgICAgICAoKEdlbmVyYXRlZE1lc3NhZ2UpIFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkuCisgICAgICAgICAgICBuZXdCdWlsZGVyRm9yVHlwZShtb2NrUGFyZW50KTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsSW50MzIoMSk7CisgICAgYnVpbGRlci5zZXRPcHRpb25hbE5lc3RlZEVudW0oVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFSKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZShuZXN0ZWRNZXNzYWdlMSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEludDMyKDEpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRFbnVtKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUik7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UobmVzdGVkTWVzc2FnZTEpOworICAgIGFzc2VydEVxdWFscygwLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworCisgICAgLy8gTm93IHRlbGwgaXQgd2Ugd2FudCBjaGFuZ2VzIGFuZCBtYWtlIHN1cmUgaXQncyBvbmx5IGZpcmVkIG9uY2UKKyAgICAvLyBBbmQgZG8gdGhpcyBmb3IgZWFjaCBmbGF2b3IKKworICAgIC8vIHByaW1pdGl2ZSBzaW5nbGUKKyAgICBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxJbnQzMigyKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsSW50MzIoMyk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisKKyAgICAvLyBlbnVtIHNpbmdsZQorICAgIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgYnVpbGRlci5zZXRPcHRpb25hbE5lc3RlZEVudW0oVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFaKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkRW51bShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIpOworICAgIGFzc2VydEVxdWFscygyLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworCisgICAgLy8gbWVzc2FnZSBzaW5nbGUKKyAgICBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG5lc3RlZE1lc3NhZ2UyKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZShuZXN0ZWRNZXNzYWdlMSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisKKyAgICAvLyBwcmltaXRpdmUgcmVwZWF0ZWQKKyAgICBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRJbnQzMigyKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkSW50MzIoMyk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisKKyAgICAvLyBlbnVtIHJlcGVhdGVkCisgICAgYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkTmVzdGVkRW51bShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVopOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRFbnVtKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBWik7CisgICAgYXNzZXJ0RXF1YWxzKDUsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisKKyAgICAvLyBtZXNzYWdlIHJlcGVhdGVkCisgICAgYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZShuZXN0ZWRNZXNzYWdlMik7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UobmVzdGVkTWVzc2FnZTEpOworICAgIGFzc2VydEVxdWFscyg2LCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworCisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZGF0aW9uc19FeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFV0aWwuTW9ja0J1aWxkZXJQYXJlbnQgbW9ja1BhcmVudCA9IG5ldyBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCgpOworCisgICAgVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciBidWlsZGVyID0gKFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIpCisgICAgICAgICgoR2VuZXJhdGVkTWVzc2FnZSkgVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpLgorICAgICAgICAgICAgbmV3QnVpbGRlckZvclR5cGUobW9ja1BhcmVudCk7CisKKyAgICBidWlsZGVyLmFkZEV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb24sIDEpOworICAgIGJ1aWxkZXIuc2V0RXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbnQzMkV4dGVuc2lvbiwgMCwgMik7CisgICAgYnVpbGRlci5jbGVhckV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb24pOworICAgIGFzc2VydEVxdWFscygwLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworCisgICAgLy8gTm93IHRlbGwgaXQgd2Ugd2FudCBjaGFuZ2VzIGFuZCBtYWtlIHN1cmUgaXQncyBvbmx5IGZpcmVkIG9uY2UKKyAgICBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIGJ1aWxkZXIuYWRkRXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbnQzMkV4dGVuc2lvbiwgMik7CisgICAgYnVpbGRlci5hZGRFeHRlbnNpb24oVW5pdHRlc3RQcm90by5yZXBlYXRlZEludDMyRXh0ZW5zaW9uLCAzKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKworICAgIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgYnVpbGRlci5zZXRFeHRlbnNpb24oVW5pdHRlc3RQcm90by5yZXBlYXRlZEludDMyRXh0ZW5zaW9uLCAwLCA0KTsKKyAgICBidWlsZGVyLnNldEV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb24sIDEsIDUpOworICAgIGFzc2VydEVxdWFscygyLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworCisgICAgYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICBidWlsZGVyLmNsZWFyRXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbnQzMkV4dGVuc2lvbik7CisgICAgYnVpbGRlci5jbGVhckV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb24pOworICAgIGFzc2VydEVxdWFscygzLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJhc2VNZXNzYWdlT3JCdWlsZGVyKCkgeworICAgIC8vIE1vc3RseSBqdXN0IG1ha2VzIHN1cmUgdGhlIGJhc2UgaW50ZXJmYWNlIGV4aXN0cyBhbmQgaGFzIHNvbWUgbWV0aG9kcy4KKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGJ1aWxkZXJBc0ludGVyZmFjZSA9IChUZXN0QWxsVHlwZXNPckJ1aWxkZXIpIGJ1aWxkZXI7CisgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyIG1lc3NhZ2VBc0ludGVyZmFjZSA9IChUZXN0QWxsVHlwZXNPckJ1aWxkZXIpIG1lc3NhZ2U7CisKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIG1lc3NhZ2VBc0ludGVyZmFjZS5nZXREZWZhdWx0Qm9vbCgpLAorICAgICAgICBtZXNzYWdlQXNJbnRlcmZhY2UuZ2V0RGVmYXVsdEJvb2woKSk7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICBtZXNzYWdlQXNJbnRlcmZhY2UuZ2V0T3B0aW9uYWxEb3VibGUoKSwKKyAgICAgICAgbWVzc2FnZUFzSW50ZXJmYWNlLmdldE9wdGlvbmFsRG91YmxlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lc3NhZ2VPckJ1aWxkZXJHZXR0ZXJzKCkgeworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworCisgICAgLy8gc2luZ2xlIGZpZWxkcworICAgIGFzc2VydFNhbWUoRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCksCisgICAgICAgIGJ1aWxkZXIuZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigpKTsKKyAgICBGb3JlaWduTWVzc2FnZS5CdWlsZGVyIHN1YkJ1aWxkZXIgPQorICAgICAgICBidWlsZGVyLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKCk7CisgICAgYXNzZXJ0U2FtZShzdWJCdWlsZGVyLCBidWlsZGVyLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoKSk7CisKKyAgICAvLyByZXBlYXRlZCBmaWVsZHMKKyAgICBGb3JlaWduTWVzc2FnZSBtMCA9IEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5idWlsZFBhcnRpYWwoKTsKKyAgICBGb3JlaWduTWVzc2FnZSBtMSA9IEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5idWlsZFBhcnRpYWwoKTsKKyAgICBGb3JlaWduTWVzc2FnZSBtMiA9IEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5idWlsZFBhcnRpYWwoKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UobTApOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZShtMSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKG0yKTsKKyAgICBhc3NlcnRTYW1lKG0wLCBidWlsZGVyLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoMCkpOworICAgIGFzc2VydFNhbWUobTEsIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigxKSk7CisgICAgYXNzZXJ0U2FtZShtMiwgYnVpbGRlci5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKDIpKTsKKyAgICBGb3JlaWduTWVzc2FnZS5CdWlsZGVyIGIwID0gYnVpbGRlci5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcigwKTsKKyAgICBGb3JlaWduTWVzc2FnZS5CdWlsZGVyIGIxID0gYnVpbGRlci5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcigxKTsKKyAgICBhc3NlcnRTYW1lKGIwLCBidWlsZGVyLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoMCkpOworICAgIGFzc2VydFNhbWUoYjEsIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigxKSk7CisgICAgYXNzZXJ0U2FtZShtMiwgYnVpbGRlci5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKDIpKTsKKworICAgIExpc3Q8PyBleHRlbmRzIEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBtZXNzYWdlT3JCdWlsZGVyTGlzdCA9CisgICAgICAgIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKKyAgICBhc3NlcnRTYW1lKGIwLCBtZXNzYWdlT3JCdWlsZGVyTGlzdC5nZXQoMCkpOworICAgIGFzc2VydFNhbWUoYjEsIG1lc3NhZ2VPckJ1aWxkZXJMaXN0LmdldCgxKSk7CisgICAgYXNzZXJ0U2FtZShtMiwgbWVzc2FnZU9yQnVpbGRlckxpc3QuZ2V0KDIpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRGaWVsZEJ1aWxkZXIoKSB7CisgICAgRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKTsKKworICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgZm9yZWlnbkZpZWxkRGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgaW1wb3J0RmllbGREZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIik7CisKKyAgICAvLyBNdXRhdGUgdGhlIG1lc3NhZ2Ugd2l0aCBuZXcgZmllbGQgYnVpbGRlcgorICAgIC8vIE11dGF0ZSBuZXN0ZWQgbWVzc2FnZQorICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIxID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBNZXNzYWdlLkJ1aWxkZXIgZmllbGRCdWlsZGVyMSA9IGJ1aWxkZXIxLm5ld0J1aWxkZXJGb3JGaWVsZChmaWVsZERlc2NyaXB0b3IpCisgICAgICAgIC5tZXJnZUZyb20oKE1lc3NhZ2UpIGJ1aWxkZXIxLmdldEZpZWxkKGZpZWxkRGVzY3JpcHRvcikpOworICAgIEZpZWxkRGVzY3JpcHRvciBzdWJGaWVsZERlc2NyaXB0b3IxID0KKyAgICAgICAgZmllbGRCdWlsZGVyMS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgiYmIiKTsKKyAgICBmaWVsZEJ1aWxkZXIxLnNldEZpZWxkKHN1YkZpZWxkRGVzY3JpcHRvcjEsIDEpOworICAgIGJ1aWxkZXIxLnNldEZpZWxkKGZpZWxkRGVzY3JpcHRvciwgZmllbGRCdWlsZGVyMS5idWlsZCgpKTsKKworICAgIC8vIE11dGF0ZSBmb3JlaWduIG1lc3NhZ2UKKyAgICBNZXNzYWdlLkJ1aWxkZXIgZm9yZWlnbkZpZWxkQnVpbGRlcjEgPSBidWlsZGVyMS5uZXdCdWlsZGVyRm9yRmllbGQoCisgICAgICAgIGZvcmVpZ25GaWVsZERlc2NyaXB0b3IpCisgICAgICAgIC5tZXJnZUZyb20oKE1lc3NhZ2UpIGJ1aWxkZXIxLmdldEZpZWxkKGZvcmVpZ25GaWVsZERlc2NyaXB0b3IpKTsKKyAgICBGaWVsZERlc2NyaXB0b3Igc3ViRm9yZWlnbkZpZWxkRGVzY3JpcHRvcjEgPQorICAgICAgICBmb3JlaWduRmllbGRCdWlsZGVyMS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgiYyIpOworICAgIGZvcmVpZ25GaWVsZEJ1aWxkZXIxLnNldEZpZWxkKHN1YkZvcmVpZ25GaWVsZERlc2NyaXB0b3IxLCAyKTsKKyAgICBidWlsZGVyMS5zZXRGaWVsZChmb3JlaWduRmllbGREZXNjcmlwdG9yLCBmb3JlaWduRmllbGRCdWlsZGVyMS5idWlsZCgpKTsKKworICAgIC8vIE11dGF0ZSBpbXBvcnQgbWVzc2FnZQorICAgIE1lc3NhZ2UuQnVpbGRlciBpbXBvcnRGaWVsZEJ1aWxkZXIxID0gYnVpbGRlcjEubmV3QnVpbGRlckZvckZpZWxkKAorICAgICAgICBpbXBvcnRGaWVsZERlc2NyaXB0b3IpCisgICAgICAgIC5tZXJnZUZyb20oKE1lc3NhZ2UpIGJ1aWxkZXIxLmdldEZpZWxkKGltcG9ydEZpZWxkRGVzY3JpcHRvcikpOworICAgIEZpZWxkRGVzY3JpcHRvciBzdWJJbXBvcnRGaWVsZERlc2NyaXB0b3IxID0KKyAgICAgICAgaW1wb3J0RmllbGRCdWlsZGVyMS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgiZCIpOworICAgIGltcG9ydEZpZWxkQnVpbGRlcjEuc2V0RmllbGQoc3ViSW1wb3J0RmllbGREZXNjcmlwdG9yMSwgMyk7CisgICAgYnVpbGRlcjEuc2V0RmllbGQoaW1wb3J0RmllbGREZXNjcmlwdG9yLCBpbXBvcnRGaWVsZEJ1aWxkZXIxLmJ1aWxkKCkpOworCisgICAgTWVzc2FnZSBuZXdNZXNzYWdlMSA9IGJ1aWxkZXIxLmJ1aWxkKCk7CisKKyAgICAvLyBNdXRhdGUgdGhlIG1lc3NhZ2Ugd2l0aCBleGlzdGluZyBmaWVsZCBidWlsZGVyCisgICAgLy8gTXV0YXRlIG5lc3RlZCBtZXNzYWdlCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlcjIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIE1lc3NhZ2UuQnVpbGRlciBmaWVsZEJ1aWxkZXIyID0gYnVpbGRlcjIuZ2V0RmllbGRCdWlsZGVyKGZpZWxkRGVzY3JpcHRvcik7CisgICAgRmllbGREZXNjcmlwdG9yIHN1YkZpZWxkRGVzY3JpcHRvcjIgPQorICAgICAgICBmaWVsZEJ1aWxkZXIyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKCJiYiIpOworICAgIGZpZWxkQnVpbGRlcjIuc2V0RmllbGQoc3ViRmllbGREZXNjcmlwdG9yMiwgMSk7CisgICAgYnVpbGRlcjIuc2V0RmllbGQoZmllbGREZXNjcmlwdG9yLCBmaWVsZEJ1aWxkZXIyLmJ1aWxkKCkpOworCisgICAgLy8gTXV0YXRlIGZvcmVpZ24gbWVzc2FnZQorICAgIE1lc3NhZ2UuQnVpbGRlciBmb3JlaWduRmllbGRCdWlsZGVyMiA9IGJ1aWxkZXIyLm5ld0J1aWxkZXJGb3JGaWVsZCgKKyAgICAgICAgZm9yZWlnbkZpZWxkRGVzY3JpcHRvcikKKyAgICAgICAgLm1lcmdlRnJvbSgoTWVzc2FnZSkgYnVpbGRlcjIuZ2V0RmllbGQoZm9yZWlnbkZpZWxkRGVzY3JpcHRvcikpOworICAgIEZpZWxkRGVzY3JpcHRvciBzdWJGb3JlaWduRmllbGREZXNjcmlwdG9yMiA9CisgICAgICAgIGZvcmVpZ25GaWVsZEJ1aWxkZXIyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKCJjIik7CisgICAgZm9yZWlnbkZpZWxkQnVpbGRlcjIuc2V0RmllbGQoc3ViRm9yZWlnbkZpZWxkRGVzY3JpcHRvcjIsIDIpOworICAgIGJ1aWxkZXIyLnNldEZpZWxkKGZvcmVpZ25GaWVsZERlc2NyaXB0b3IsIGZvcmVpZ25GaWVsZEJ1aWxkZXIyLmJ1aWxkKCkpOworCisgICAgLy8gTXV0YXRlIGltcG9ydCBtZXNzYWdlCisgICAgTWVzc2FnZS5CdWlsZGVyIGltcG9ydEZpZWxkQnVpbGRlcjIgPSBidWlsZGVyMi5uZXdCdWlsZGVyRm9yRmllbGQoCisgICAgICAgIGltcG9ydEZpZWxkRGVzY3JpcHRvcikKKyAgICAgICAgLm1lcmdlRnJvbSgoTWVzc2FnZSkgYnVpbGRlcjIuZ2V0RmllbGQoaW1wb3J0RmllbGREZXNjcmlwdG9yKSk7CisgICAgRmllbGREZXNjcmlwdG9yIHN1YkltcG9ydEZpZWxkRGVzY3JpcHRvcjIgPQorICAgICAgICBpbXBvcnRGaWVsZEJ1aWxkZXIyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKCJkIik7CisgICAgaW1wb3J0RmllbGRCdWlsZGVyMi5zZXRGaWVsZChzdWJJbXBvcnRGaWVsZERlc2NyaXB0b3IyLCAzKTsKKyAgICBidWlsZGVyMi5zZXRGaWVsZChpbXBvcnRGaWVsZERlc2NyaXB0b3IsIGltcG9ydEZpZWxkQnVpbGRlcjIuYnVpbGQoKSk7CisKKyAgICBNZXNzYWdlIG5ld01lc3NhZ2UyID0gYnVpbGRlcjIuYnVpbGQoKTsKKworICAgIC8vIFRoZXNlIHR3byBtZXNzYWdlcyBzaG91bGQgYmUgZXF1YWwuCisgICAgYXNzZXJ0RXF1YWxzKG5ld01lc3NhZ2UxLCBuZXdNZXNzYWdlMik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0RmllbGRCdWlsZGVyV2l0aEluaXRpYWxpemVkVmFsdWUoKSB7CisgICAgRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisKKyAgICAvLyBCZWZvcmUgc2V0dGluZyBmaWVsZCwgYnVpbGRlciBpcyBpbml0aWFsaXplZCBieSBkZWZhdWx0IHZhbHVlLiAKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBOZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZmllbGRCdWlsZGVyID0KKyAgICAgICAgKE5lc3RlZE1lc3NhZ2UuQnVpbGRlcikgYnVpbGRlci5nZXRGaWVsZEJ1aWxkZXIoZmllbGREZXNjcmlwdG9yKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgZmllbGRCdWlsZGVyLmdldEJiKCkpOworCisgICAgLy8gU2V0dGluZyBmaWVsZCB2YWx1ZSB3aXRoIG5ldyBmaWVsZCBidWlsZGVyIGluc3RhbmNlLgorICAgIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIE5lc3RlZE1lc3NhZ2UuQnVpbGRlciBuZXdGaWVsZEJ1aWxkZXIgPQorICAgICAgICBidWlsZGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKTsKKyAgICBuZXdGaWVsZEJ1aWxkZXIuc2V0QmIoMik7CisgICAgLy8gVGhlbiBnZXQgdGhlIGZpZWxkIGJ1aWxkZXIgaW5zdGFuY2UgYnkgZ2V0RmllbGRCdWlsZGVyKCkuCisgICAgZmllbGRCdWlsZGVyID0KKyAgICAgICAgKE5lc3RlZE1lc3NhZ2UuQnVpbGRlcikgYnVpbGRlci5nZXRGaWVsZEJ1aWxkZXIoZmllbGREZXNjcmlwdG9yKTsKKyAgICAvLyBJdCBzaG91bGQgY29udGFpbiBuZXcgdmFsdWUuCisgICAgYXNzZXJ0RXF1YWxzKDIsIGZpZWxkQnVpbGRlci5nZXRCYigpKTsKKyAgICAvLyBUaGVzZSB0d28gYnVpbGRlciBzaG91bGQgYmUgZXF1YWwuCisgICAgYXNzZXJ0U2FtZShmaWVsZEJ1aWxkZXIsIG5ld0ZpZWxkQnVpbGRlcik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0RmllbGRCdWlsZGVyTm90U3VwcG9ydGVkRXhjZXB0aW9uKCkgeworICAgIERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0RmllbGRCdWlsZGVyKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0RmllbGRCdWlsZGVyKAorICAgICAgICAgIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfZW51bSIpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0RmllbGRCdWlsZGVyKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0RmllbGRCdWlsZGVyKAorICAgICAgICAgIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0RmllbGRCdWlsZGVyKAorICAgICAgICAgIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgIH0KKworICAvLyBUZXN0IHRoYXQgd2hlbiB0aGUgZGVmYXVsdCBvdXRlciBjbGFzcyBuYW1lIGNvbmZsaWN0cyB3aXRoIGFub3RoZXIgdHlwZQorICAvLyBkZWZpbmVkIGluIHRoZSBwcm90byB0aGUgY29tcGlsZXIgd2lsbCBhcHBlbmQgYSBzdWZmaXggdG8gYXZvaWQgdGhlCisgIC8vIGNvbmZsaWN0LgorICBwdWJsaWMgdm9pZCB0ZXN0Q29uZmxpY3RpbmdPdXRlckNsYXNzTmFtZSgpIHsKKyAgICAvLyBXZSBqdXN0IG5lZWQgdG8gbWFrZSBzdXJlIHdlIGNhbiByZWZlciB0byB0aGUgb3V0ZXIgY2xhc3Mgd2l0aCB0aGUKKyAgICAvLyBleHBlY3RlZCBuYW1lLiBUaGVyZSBpcyBub3RoaW5nIGVsc2UgdG8gdGVzdC4KKyAgICBPdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCBtZXNzYWdlID0KKyAgICAgICAgT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldERlc2NyaXB0b3JGb3JUeXBlKCkgPT0KKyAgICAgICAgT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QuZ2V0RGVzY3JpcHRvcigpKTsKKworICAgIE91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIKKyAgICAgICAgbWVzc2FnZTIgPSBPdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZQorICAgICAgICAgICAgLk91dGVyQ2xhc3NOYW1lVGVzdDIubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UyLmdldFNlcmlhbGl6ZWRTaXplKCkpOworCisgICAgT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MworICAgICAgICBlbnVtVmFsdWUgPSBPdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZQorICAgICAgICAgICAgLk91dGVyQ2xhc3NOYW1lVGVzdDMuRFVNTVlfVkFMVUU7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGVudW1WYWx1ZS5nZXROdW1iZXIoKSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBvbmVvZiBnZW5lcmF0ZWQgY29kZSB0ZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RPbmVvZkVudW1DYXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE9uZW9mMiBtZXNzYWdlID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZvb0ludCgxMjMpLnNldEZvb1N0cmluZygiZm9vIikuc2V0Rm9vQ29yZCgiYmFyIikuYnVpbGQoKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENsZWFyT25lb2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpLnNldEZvb0ludCgxMjMpOworICAgIGFzc2VydEVxdWFscyhUZXN0T25lb2YyLkZvb0Nhc2UuRk9PX0lOVCwgYnVpbGRlci5nZXRGb29DYXNlKCkpOworICAgIGJ1aWxkZXIuY2xlYXJGb28oKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE9uZW9mMi5Gb29DYXNlLkZPT19OT1RfU0VULCBidWlsZGVyLmdldEZvb0Nhc2UoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2V0T25lb2ZDbGVhcnNPdGhlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9CisgICAgICAgIGJ1aWxkZXIuc2V0Rm9vSW50KDEyMykuc2V0Rm9vU3RyaW5nKCJmb28iKS5idWlsZFBhcnRpYWwoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vU3RyaW5nKCkpOworICAgIFRlc3RVdGlsLmFzc2VydEF0TW9zdE9uZUZpZWxkU2V0T25lb2YobWVzc2FnZSk7CisKKyAgICBtZXNzYWdlID0gYnVpbGRlci5zZXRGb29Db3JkKCJiYXIiKS5idWlsZFBhcnRpYWwoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vQ29yZCgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworCisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vU3RyaW5nUGllY2UoImJheiIpLmJ1aWxkUGFydGlhbCgpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNGb29TdHJpbmdQaWVjZSgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworCisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vQnl0ZXMoVGVzdFV0aWwudG9CeXRlcygicXV4IikpLmJ1aWxkUGFydGlhbCgpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNGb29CeXRlcygpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworCisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vRW51bShUZXN0T25lb2YyLk5lc3RlZEVudW0uRk9PKS5idWlsZFBhcnRpYWwoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vRW51bSgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworCisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vTWVzc2FnZSgKKyAgICAgICAgVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRRdXhJbnQoMjM0KS5idWlsZCgpKS5idWlsZFBhcnRpYWwoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworCisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vSW50KDEyMykuYnVpbGRQYXJ0aWFsKCk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb0ludCgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBdE1vc3RPbmVGaWVsZFNldE9uZW9mKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE9uZW9mVHlwZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBQcmltaXRpdmUKKyAgICB7CisgICAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgICAgYXNzZXJ0RXF1YWxzKGJ1aWxkZXIuZ2V0Rm9vSW50KCksIDApOworICAgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5oYXNGb29JbnQoKSk7CisgICAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuc2V0Rm9vSW50KDEyMykuaGFzRm9vSW50KCkpOworICAgICAgYXNzZXJ0RXF1YWxzKGJ1aWxkZXIuZ2V0Rm9vSW50KCksIDEyMyk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb0ludCgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb0ludCgpLCAxMjMpOworCisgICAgICBhc3NlcnRGYWxzZShidWlsZGVyLmNsZWFyRm9vSW50KCkuaGFzRm9vSW50KCkpOworICAgICAgVGVzdE9uZW9mMiBtZXNzYWdlMiA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UyLmhhc0Zvb0ludCgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29JbnQoKSwgMCk7CisgICAgfQorCisgICAgLy8gRW51bQorICAgIHsKKyAgICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBhc3NlcnRFcXVhbHMoYnVpbGRlci5nZXRGb29FbnVtKCksIFRlc3RPbmVvZjIuTmVzdGVkRW51bS5GT08pOworICAgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLnNldEZvb0VudW0oVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLkJBUikuaGFzRm9vRW51bSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhidWlsZGVyLmdldEZvb0VudW0oKSwgVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLkJBUik7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb0VudW0oKSk7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRGb29FbnVtKCksIFRlc3RPbmVvZjIuTmVzdGVkRW51bS5CQVIpOworCisgICAgICBhc3NlcnRGYWxzZShidWlsZGVyLmNsZWFyRm9vRW51bSgpLmhhc0Zvb0VudW0oKSk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UyID0gYnVpbGRlci5idWlsZCgpOworICAgICAgYXNzZXJ0RmFsc2UobWVzc2FnZTIuaGFzRm9vRW51bSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29FbnVtKCksIFRlc3RPbmVvZjIuTmVzdGVkRW51bS5GT08pOworICAgIH0KKworICAgIC8vIFN0cmluZworICAgIHsKKyAgICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBhc3NlcnRFcXVhbHMoYnVpbGRlci5nZXRGb29TdHJpbmcoKSwgIiIpOworICAgICAgYnVpbGRlci5zZXRGb29TdHJpbmcoImZvbyIpOworICAgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmhhc0Zvb1N0cmluZygpKTsKKyAgICAgIGFzc2VydEVxdWFscyhidWlsZGVyLmdldEZvb1N0cmluZygpLCAiZm9vIik7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb1N0cmluZygpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb1N0cmluZygpLCAiZm9vIik7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRGb29TdHJpbmdCeXRlcygpLCBUZXN0VXRpbC50b0J5dGVzKCJmb28iKSk7CisKKyAgICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuY2xlYXJGb29TdHJpbmcoKS5oYXNGb29TdHJpbmcoKSk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UyID0gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UyLmhhc0Zvb1N0cmluZygpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29TdHJpbmcoKSwgIiIpOworICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UyLmdldEZvb1N0cmluZ0J5dGVzKCksIFRlc3RVdGlsLnRvQnl0ZXMoIiIpKTsKKworICAgICAgLy8gR2V0IG1ldGhvZCBzaG91bGQgbm90IGNoYW5nZSB0aGUgb25lb2YgdmFsdWUuCisgICAgICBidWlsZGVyLnNldEZvb0ludCgxMjMpOworICAgICAgYXNzZXJ0RXF1YWxzKGJ1aWxkZXIuZ2V0Rm9vU3RyaW5nKCksICIiKTsKKyAgICAgIGFzc2VydEVxdWFscyhidWlsZGVyLmdldEZvb1N0cmluZ0J5dGVzKCksIFRlc3RVdGlsLnRvQnl0ZXMoIiIpKTsKKyAgICAgIGFzc2VydEVxdWFscygxMjMsIGJ1aWxkZXIuZ2V0Rm9vSW50KCkpOworCisgICAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0Rm9vU3RyaW5nKCksICIiKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb1N0cmluZ0J5dGVzKCksIFRlc3RVdGlsLnRvQnl0ZXMoIiIpKTsKKyAgICAgIGFzc2VydEVxdWFscygxMjMsIG1lc3NhZ2UuZ2V0Rm9vSW50KCkpOworICAgIH0KKworICAgIC8vIENvcmQKKyAgICB7CisgICAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgICAgYXNzZXJ0RXF1YWxzKGJ1aWxkZXIuZ2V0Rm9vQ29yZCgpLCAiIik7CisgICAgICBidWlsZGVyLnNldEZvb0NvcmQoImZvbyIpOworICAgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmhhc0Zvb0NvcmQoKSk7CisgICAgICBhc3NlcnRFcXVhbHMoYnVpbGRlci5nZXRGb29Db3JkKCksICJmb28iKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vQ29yZCgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb0NvcmQoKSwgImZvbyIpOworICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0Rm9vQ29yZEJ5dGVzKCksIFRlc3RVdGlsLnRvQnl0ZXMoImZvbyIpKTsKKworICAgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5jbGVhckZvb0NvcmQoKS5oYXNGb29Db3JkKCkpOworICAgICAgVGVzdE9uZW9mMiBtZXNzYWdlMiA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UyLmhhc0Zvb0NvcmQoKSk7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZTIuZ2V0Rm9vQ29yZCgpLCAiIik7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZTIuZ2V0Rm9vQ29yZEJ5dGVzKCksIFRlc3RVdGlsLnRvQnl0ZXMoIiIpKTsKKyAgICB9CisKKyAgICAvLyBTdHJpbmdQaWVjZQorICAgIHsKKyAgICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBhc3NlcnRFcXVhbHMoYnVpbGRlci5nZXRGb29TdHJpbmdQaWVjZSgpLCAiIik7CisgICAgICBidWlsZGVyLnNldEZvb1N0cmluZ1BpZWNlKCJmb28iKTsKKyAgICAgIGFzc2VydFRydWUoYnVpbGRlci5oYXNGb29TdHJpbmdQaWVjZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhidWlsZGVyLmdldEZvb1N0cmluZ1BpZWNlKCksICJmb28iKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vU3RyaW5nUGllY2UoKSk7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRGb29TdHJpbmdQaWVjZSgpLCAiZm9vIik7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRGb29TdHJpbmdQaWVjZUJ5dGVzKCksIFRlc3RVdGlsLnRvQnl0ZXMoImZvbyIpKTsKKworICAgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5jbGVhckZvb1N0cmluZ1BpZWNlKCkuaGFzRm9vU3RyaW5nUGllY2UoKSk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UyID0gYnVpbGRlci5idWlsZCgpOworICAgICAgYXNzZXJ0RmFsc2UobWVzc2FnZTIuaGFzRm9vU3RyaW5nUGllY2UoKSk7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZTIuZ2V0Rm9vU3RyaW5nUGllY2UoKSwgIiIpOworICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UyLmdldEZvb1N0cmluZ1BpZWNlQnl0ZXMoKSwgVGVzdFV0aWwudG9CeXRlcygiIikpOworICAgIH0KKworICAgIC8vIE1lc3NhZ2UKKyAgICB7CisgICAgICAvLyBzZXQKKyAgICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBhc3NlcnRFcXVhbHMoYnVpbGRlci5nZXRGb29NZXNzYWdlKCkuZ2V0UXV4SW50KCksIDApOworICAgICAgYnVpbGRlci5zZXRGb29NZXNzYWdlKAorICAgICAgICAgIFRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0UXV4SW50KDIzNCkuYnVpbGQoKSk7CisgICAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhidWlsZGVyLmdldEZvb01lc3NhZ2UoKS5nZXRRdXhJbnQoKSwgMjM0KTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb01lc3NhZ2UoKS5nZXRRdXhJbnQoKSwgMjM0KTsKKworICAgICAgLy8gY2xlYXIKKyAgICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuY2xlYXJGb29NZXNzYWdlKCkuaGFzRm9vU3RyaW5nKCkpOworICAgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb01lc3NhZ2UoKS5nZXRRdXhJbnQoKSwgMCk7CisKKyAgICAgIC8vIG5lc3RlZCBidWlsZGVyCisgICAgICBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBhc3NlcnRTYW1lKGJ1aWxkZXIuZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpLAorICAgICAgICAgIFRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgICBhc3NlcnRGYWxzZShidWlsZGVyLmhhc0Zvb01lc3NhZ2UoKSk7CisgICAgICBidWlsZGVyLmdldEZvb01lc3NhZ2VCdWlsZGVyKCkuc2V0UXV4SW50KDEyMyk7CisgICAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhidWlsZGVyLmdldEZvb01lc3NhZ2UoKS5nZXRRdXhJbnQoKSwgMTIzKTsKKyAgICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldEZvb01lc3NhZ2UoKS5nZXRRdXhJbnQoKSwgMTIzKTsKKyAgICB9CisKKyAgICAvLyBMYXp5TWVzc2FnZSBpcyB0ZXN0ZWQgaW4gTGF6eU1lc3NhZ2VMaXRlVGVzdC5qYXZhCisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZNZXJnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFByaW1pdGl2ZSBUeXBlCisgICAgeworICAgICAgVGVzdE9uZW9mMi5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vSW50KDEyMykuYnVpbGQoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZTIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20obWVzc2FnZSkuYnVpbGQoKTsKKyAgICAgIGFzc2VydFRydWUobWVzc2FnZTIuaGFzRm9vSW50KCkpOworICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UyLmdldEZvb0ludCgpLCAxMjMpOworICAgIH0KKworICAgIC8vIFN0cmluZworICAgIHsKKyAgICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBidWlsZGVyLnNldEZvb1N0cmluZygiZm9vIikuYnVpbGQoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZTIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20obWVzc2FnZSkuYnVpbGQoKTsKKyAgICAgIGFzc2VydFRydWUobWVzc2FnZTIuaGFzRm9vU3RyaW5nKCkpOworICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UyLmdldEZvb1N0cmluZygpLCAiZm9vIik7CisgICAgfQorCisgICAgLy8gRW51bQorICAgIHsKKyAgICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBidWlsZGVyLnNldEZvb0VudW0oVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLkJBUikuYnVpbGQoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZTIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20obWVzc2FnZSkuYnVpbGQoKTsKKyAgICAgIGFzc2VydFRydWUobWVzc2FnZTIuaGFzRm9vRW51bSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29FbnVtKCksIFRlc3RPbmVvZjIuTmVzdGVkRW51bS5CQVIpOworICAgIH0KKworICAgIC8vIE1lc3NhZ2UKKyAgICB7CisgICAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgICAgVGVzdE9uZW9mMiBtZXNzYWdlID0gYnVpbGRlci5zZXRGb29NZXNzYWdlKAorICAgICAgICAgIFRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0UXV4SW50KDIzNCkuYnVpbGQoKSkuYnVpbGQoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZTIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20obWVzc2FnZSkuYnVpbGQoKTsKKyAgICAgIGFzc2VydFRydWUobWVzc2FnZTIuaGFzRm9vTWVzc2FnZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29NZXNzYWdlKCkuZ2V0UXV4SW50KCksIDIzNCk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE9uZW9mU2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFByaW1pdGl2ZSBUeXBlCisgICAgeworICAgICAgVGVzdE9uZW9mMi5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vSW50KDEyMykuYnVpbGQoKTsKKyAgICAgIEJ5dGVTdHJpbmcgc2VyaWFsaXplZCA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UyID0gVGVzdE9uZW9mMi5wYXJzZUZyb20oc2VyaWFsaXplZCk7CisgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UyLmhhc0Zvb0ludCgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29JbnQoKSwgMTIzKTsKKyAgICB9CisKKyAgICAvLyBTdHJpbmcKKyAgICB7CisgICAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgICAgVGVzdE9uZW9mMiBtZXNzYWdlID0gYnVpbGRlci5zZXRGb29TdHJpbmcoImZvbyIpLmJ1aWxkKCk7CisgICAgICBCeXRlU3RyaW5nIHNlcmlhbGl6ZWQgPSBtZXNzYWdlLnRvQnl0ZVN0cmluZygpOworICAgICAgVGVzdE9uZW9mMiBtZXNzYWdlMiA9IFRlc3RPbmVvZjIucGFyc2VGcm9tKHNlcmlhbGl6ZWQpOworICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlMi5oYXNGb29TdHJpbmcoKSk7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZTIuZ2V0Rm9vU3RyaW5nKCksICJmb28iKTsKKyAgICB9CisKKyAgICAvLyBFbnVtCisgICAgeworICAgICAgVGVzdE9uZW9mMi5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuc2V0Rm9vRW51bShUZXN0T25lb2YyLk5lc3RlZEVudW0uQkFSKS5idWlsZCgpOworICAgICAgQnl0ZVN0cmluZyBzZXJpYWxpemVkID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICAgIFRlc3RPbmVvZjIgbWVzc2FnZTIgPSBUZXN0T25lb2YyLnBhcnNlRnJvbShzZXJpYWxpemVkKTsKKyAgICAgIGFzc2VydFRydWUobWVzc2FnZTIuaGFzRm9vRW51bSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlMi5nZXRGb29FbnVtKCksIFRlc3RPbmVvZjIuTmVzdGVkRW51bS5CQVIpOworICAgIH0KKworICAgIC8vIE1lc3NhZ2UKKyAgICB7CisgICAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgICAgVGVzdE9uZW9mMiBtZXNzYWdlID0gYnVpbGRlci5zZXRGb29NZXNzYWdlKAorICAgICAgICAgIFRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0UXV4SW50KDIzNCkuYnVpbGQoKSkuYnVpbGQoKTsKKyAgICAgIEJ5dGVTdHJpbmcgc2VyaWFsaXplZCA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisgICAgICBUZXN0T25lb2YyIG1lc3NhZ2UyID0gVGVzdE9uZW9mMi5wYXJzZUZyb20oc2VyaWFsaXplZCk7CisgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UyLmhhc0Zvb01lc3NhZ2UoKSk7CisgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZTIuZ2V0Rm9vTWVzc2FnZSgpLmdldFF1eEludCgpLCAyMzQpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RPbmVvZk5lc3RlZEJ1aWxkZXJPbkNoYW5nZVByb3BhZ2F0aW9uKCkgeworICAgIE5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIHBhcmVudEJ1aWxkZXIgPSBOZXN0ZWRUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBwYXJlbnRCdWlsZGVyLmdldFBheWxvYWRCdWlsZGVyKCk7CisgICAgYnVpbGRlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyKCk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmhhc09uZW9mTmVzdGVkTWVzc2FnZSgpKTsKKyAgICBhc3NlcnRUcnVlKHBhcmVudEJ1aWxkZXIuaGFzUGF5bG9hZCgpKTsKKyAgICBOZXN0ZWRUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IHBhcmVudEJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzUGF5bG9hZCgpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0UGF5bG9hZCgpLmhhc09uZW9mTmVzdGVkTWVzc2FnZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRSZXBlYXRlZEZpZWxkQnVpbGRlcigpIHsKKyAgICBEZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpOworCisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpOworICAgIEZpZWxkRGVzY3JpcHRvciBmb3JlaWduRmllbGREZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpOworICAgIEZpZWxkRGVzY3JpcHRvciBpbXBvcnRGaWVsZERlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKTsKKworICAgIC8vIE11dGF0ZSB0aGUgbWVzc2FnZSB3aXRoIG5ldyBmaWVsZCBidWlsZGVyCisgICAgLy8gTXV0YXRlIG5lc3RlZCBtZXNzYWdlCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlcjEgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIE1lc3NhZ2UuQnVpbGRlciBmaWVsZEJ1aWxkZXIxID0gYnVpbGRlcjEubmV3QnVpbGRlckZvckZpZWxkKAorICAgICAgICBmaWVsZERlc2NyaXB0b3IpOworICAgIEZpZWxkRGVzY3JpcHRvciBzdWJGaWVsZERlc2NyaXB0b3IxID0KKyAgICAgICAgZmllbGRCdWlsZGVyMS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgiYmIiKTsKKyAgICBmaWVsZEJ1aWxkZXIxLnNldEZpZWxkKHN1YkZpZWxkRGVzY3JpcHRvcjEsIDEpOworICAgIGJ1aWxkZXIxLmFkZFJlcGVhdGVkRmllbGQoZmllbGREZXNjcmlwdG9yLCBmaWVsZEJ1aWxkZXIxLmJ1aWxkKCkpOworCisgICAgLy8gTXV0YXRlIGZvcmVpZ24gbWVzc2FnZQorICAgIE1lc3NhZ2UuQnVpbGRlciBmb3JlaWduRmllbGRCdWlsZGVyMSA9IGJ1aWxkZXIxLm5ld0J1aWxkZXJGb3JGaWVsZCgKKyAgICAgICAgZm9yZWlnbkZpZWxkRGVzY3JpcHRvcik7CisgICAgRmllbGREZXNjcmlwdG9yIHN1YkZvcmVpZ25GaWVsZERlc2NyaXB0b3IxID0KKyAgICAgICAgZm9yZWlnbkZpZWxkQnVpbGRlcjEuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUoImMiKTsKKyAgICBmb3JlaWduRmllbGRCdWlsZGVyMS5zZXRGaWVsZChzdWJGb3JlaWduRmllbGREZXNjcmlwdG9yMSwgMik7CisgICAgYnVpbGRlcjEuYWRkUmVwZWF0ZWRGaWVsZChmb3JlaWduRmllbGREZXNjcmlwdG9yLAorICAgICAgICBmb3JlaWduRmllbGRCdWlsZGVyMS5idWlsZCgpKTsKKworICAgIC8vIE11dGF0ZSBpbXBvcnQgbWVzc2FnZQorICAgIE1lc3NhZ2UuQnVpbGRlciBpbXBvcnRGaWVsZEJ1aWxkZXIxID0gYnVpbGRlcjEubmV3QnVpbGRlckZvckZpZWxkKAorICAgICAgICBpbXBvcnRGaWVsZERlc2NyaXB0b3IpOworICAgIEZpZWxkRGVzY3JpcHRvciBzdWJJbXBvcnRGaWVsZERlc2NyaXB0b3IxID0KKyAgICAgICAgaW1wb3J0RmllbGRCdWlsZGVyMS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgiZCIpOworICAgIGltcG9ydEZpZWxkQnVpbGRlcjEuc2V0RmllbGQoc3ViSW1wb3J0RmllbGREZXNjcmlwdG9yMSwgMyk7CisgICAgYnVpbGRlcjEuYWRkUmVwZWF0ZWRGaWVsZChpbXBvcnRGaWVsZERlc2NyaXB0b3IsCisgICAgICAgIGltcG9ydEZpZWxkQnVpbGRlcjEuYnVpbGQoKSk7CisKKyAgICBNZXNzYWdlIG5ld01lc3NhZ2UxID0gYnVpbGRlcjEuYnVpbGQoKTsKKworICAgIC8vIE11dGF0ZSB0aGUgbWVzc2FnZSB3aXRoIGV4aXN0aW5nIGZpZWxkIGJ1aWxkZXIKKyAgICAvLyBNdXRhdGUgbmVzdGVkIG1lc3NhZ2UKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyMiA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlcjIuYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigpOworICAgIE1lc3NhZ2UuQnVpbGRlciBmaWVsZEJ1aWxkZXIyID0gYnVpbGRlcjIuZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoCisgICAgICAgIGZpZWxkRGVzY3JpcHRvciwgMCk7CisgICAgRmllbGREZXNjcmlwdG9yIHN1YkZpZWxkRGVzY3JpcHRvcjIgPQorICAgICAgICBmaWVsZEJ1aWxkZXIyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKCJiYiIpOworICAgIGZpZWxkQnVpbGRlcjIuc2V0RmllbGQoc3ViRmllbGREZXNjcmlwdG9yMiwgMSk7CisKKyAgICAvLyBNdXRhdGUgZm9yZWlnbiBtZXNzYWdlCisgICAgTWVzc2FnZS5CdWlsZGVyIGZvcmVpZ25GaWVsZEJ1aWxkZXIyID0gYnVpbGRlcjIubmV3QnVpbGRlckZvckZpZWxkKAorICAgICAgICBmb3JlaWduRmllbGREZXNjcmlwdG9yKTsKKyAgICBGaWVsZERlc2NyaXB0b3Igc3ViRm9yZWlnbkZpZWxkRGVzY3JpcHRvcjIgPQorICAgICAgICBmb3JlaWduRmllbGRCdWlsZGVyMi5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgiYyIpOworICAgIGZvcmVpZ25GaWVsZEJ1aWxkZXIyLnNldEZpZWxkKHN1YkZvcmVpZ25GaWVsZERlc2NyaXB0b3IyLCAyKTsKKyAgICBidWlsZGVyMi5hZGRSZXBlYXRlZEZpZWxkKGZvcmVpZ25GaWVsZERlc2NyaXB0b3IsCisgICAgICAgIGZvcmVpZ25GaWVsZEJ1aWxkZXIyLmJ1aWxkKCkpOworCisgICAgLy8gTXV0YXRlIGltcG9ydCBtZXNzYWdlCisgICAgTWVzc2FnZS5CdWlsZGVyIGltcG9ydEZpZWxkQnVpbGRlcjIgPSBidWlsZGVyMi5uZXdCdWlsZGVyRm9yRmllbGQoCisgICAgICAgIGltcG9ydEZpZWxkRGVzY3JpcHRvcik7CisgICAgRmllbGREZXNjcmlwdG9yIHN1YkltcG9ydEZpZWxkRGVzY3JpcHRvcjIgPQorICAgICAgICBpbXBvcnRGaWVsZEJ1aWxkZXIyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKCJkIik7CisgICAgaW1wb3J0RmllbGRCdWlsZGVyMi5zZXRGaWVsZChzdWJJbXBvcnRGaWVsZERlc2NyaXB0b3IyLCAzKTsKKyAgICBidWlsZGVyMi5hZGRSZXBlYXRlZEZpZWxkKGltcG9ydEZpZWxkRGVzY3JpcHRvciwKKyAgICAgICAgaW1wb3J0RmllbGRCdWlsZGVyMi5idWlsZCgpKTsKKworICAgIE1lc3NhZ2UgbmV3TWVzc2FnZTIgPSBidWlsZGVyMi5idWlsZCgpOworCisgICAgLy8gVGhlc2UgdHdvIG1lc3NhZ2VzIHNob3VsZCBiZSBlcXVhbC4KKyAgICBhc3NlcnRFcXVhbHMobmV3TWVzc2FnZTEsIG5ld01lc3NhZ2UyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRSZXBlYXRlZEZpZWxkQnVpbGRlcldpdGhJbml0aWFsaXplZFZhbHVlKCkgeworICAgIERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpOworCisgICAgLy8gQmVmb3JlIHNldHRpbmcgZmllbGQsIGJ1aWxkZXIgaXMgaW5pdGlhbGl6ZWQgYnkgZGVmYXVsdCB2YWx1ZS4gCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCk7CisgICAgTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGZpZWxkQnVpbGRlciA9CisgICAgICAgIChOZXN0ZWRNZXNzYWdlLkJ1aWxkZXIpIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoZmllbGREZXNjcmlwdG9yLCAwKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgZmllbGRCdWlsZGVyLmdldEJiKCkpOworCisgICAgLy8gU2V0dGluZyBmaWVsZCB2YWx1ZSB3aXRoIG5ldyBmaWVsZCBidWlsZGVyIGluc3RhbmNlLgorICAgIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIE5lc3RlZE1lc3NhZ2UuQnVpbGRlciBuZXdGaWVsZEJ1aWxkZXIgPQorICAgICAgICBidWlsZGVyLmFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKTsKKyAgICBuZXdGaWVsZEJ1aWxkZXIuc2V0QmIoMik7CisgICAgLy8gVGhlbiBnZXQgdGhlIGZpZWxkIGJ1aWxkZXIgaW5zdGFuY2UgYnkgZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoKS4KKyAgICBmaWVsZEJ1aWxkZXIgPQorICAgICAgICAoTmVzdGVkTWVzc2FnZS5CdWlsZGVyKSBidWlsZGVyLmdldFJlcGVhdGVkRmllbGRCdWlsZGVyKGZpZWxkRGVzY3JpcHRvciwgMCk7CisgICAgLy8gSXQgc2hvdWxkIGNvbnRhaW4gbmV3IHZhbHVlLgorICAgIGFzc2VydEVxdWFscygyLCBmaWVsZEJ1aWxkZXIuZ2V0QmIoKSk7CisgICAgLy8gVGhlc2UgdHdvIGJ1aWxkZXIgc2hvdWxkIGJlIGVxdWFsLgorICAgIGFzc2VydFNhbWUoZmllbGRCdWlsZGVyLCBuZXdGaWVsZEJ1aWxkZXIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldFJlcGVhdGVkRmllbGRCdWlsZGVyTm90U3VwcG9ydGVkRXhjZXB0aW9uKCkgeworICAgIERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ludDMyIiksIDApOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgICB0cnkgeworICAgICAgYnVpbGRlci5nZXRSZXBlYXRlZEZpZWxkQnVpbGRlcigKKyAgICAgICAgICBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX2VudW0iKSwgMCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICAgIHRyeSB7CisgICAgICBidWlsZGVyLmdldFJlcGVhdGVkRmllbGRCdWlsZGVyKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpLCAwKTsKKyAgICAgIGZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZEJ1aWxkZXIoCisgICAgICAgICAgZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiksIDApOworICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgIH0KKyAgICB0cnkgeworICAgICAgYnVpbGRlci5nZXRSZXBlYXRlZEZpZWxkQnVpbGRlcigKKyAgICAgICAgICBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSwgMCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Jc1ZhbGlkVXRmOFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0lzVmFsaWRVdGY4VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5YjY0NTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Jc1ZhbGlkVXRmOFRlc3QuamF2YQpAQCAtMCwwICsxLDE4MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuSXNWYWxpZFV0ZjhUZXN0VXRpbC5TaGFyZDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyBjYXNlcyBmb3Ige0BsaW5rIEJ5dGVTdHJpbmcjaXNWYWxpZFV0ZjgoKX0uIFRoaXMgaW5jbHVkZXMgdGhyZWUKKyAqIGJydXRlIGZvcmNlIHRlc3RzIHRoYXQgYWN0dWFsbHkgdGVzdCBldmVyeSBwZXJtdXRhdGlvbiBvZiBvbmUgYnl0ZSwgdHdvIGJ5dGUsCisgKiBhbmQgdGhyZWUgYnl0ZSBzZXF1ZW5jZXMgdG8gZW5zdXJlIHRoYXQgdGhlIG1ldGhvZCBwcm9kdWNlcyB0aGUgcmlnaHQgcmVzdWx0CisgKiBmb3IgZXZlcnkgcG9zc2libGUgYnl0ZSBlbmNvZGluZyB3aGVyZSAicmlnaHQiIG1lYW5zIGl0J3MgY29uc2lzdGVudCB3aXRoCisgKiBqYXZhJ3MgVVRGLTggc3RyaW5nIGVuY29kaW5nL2RlY29kaW5nIHN1Y2ggdGhhdCB0aGUgbWV0aG9kIHJldHVybnMgdHJ1ZSBmb3IKKyAqIGFueSBzZXF1ZW5jZSB0aGF0IHdpbGwgcm91bmQgdHJpcCB3aGVuIGNvbnZlcnRlZCB0byBhIFN0cmluZyBhbmQgdGhlbiBiYWNrIHRvCisgKiBieXRlcyBhbmQgd2lsbCByZXR1cm4gZmFsc2UgZm9yIGFueSBzZXF1ZW5jZSB0aGF0IHdpbGwgbm90IHJvdW5kIHRyaXAuCisgKiBTZWUgYWxzbyB7QGxpbmsgSXNWYWxpZFV0ZjhGb3VyQnl0ZVRlc3R9LiBJdCBhbHNvIGluY2x1ZGVzIHNvbWUKKyAqIG90aGVyIG1vcmUgdGFyZ2V0ZWQgdGVzdHMuCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKiBAYXV0aG9yIG1hcnRpbnJiQGdvb2dsZS5jb20gKE1hcnRpbiBCdWNoaG9seikKKyAqLworcHVibGljIGNsYXNzIElzVmFsaWRVdGY4VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAvKioKKyAgICogVGVzdHMgdGhhdCByb3VuZCB0cmlwcGluZyBvZiBhbGwgdHdvIGJ5dGUgcGVybXV0YXRpb25zIHdvcmsuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SXNWYWxpZFV0ZjhfMUJ5dGUoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgSXNWYWxpZFV0ZjhUZXN0VXRpbC50ZXN0Qnl0ZXMoMSwKKyAgICAgICAgSXNWYWxpZFV0ZjhUZXN0VXRpbC5FWFBFQ1RFRF9PTkVfQllURV9ST1VORFRSSVBQQUJMRV9DT1VOVCk7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCByb3VuZCB0cmlwcGluZyBvZiBhbGwgdHdvIGJ5dGUgcGVybXV0YXRpb25zIHdvcmsuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SXNWYWxpZFV0ZjhfMkJ5dGVzKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIElzVmFsaWRVdGY4VGVzdFV0aWwudGVzdEJ5dGVzKDIsCisgICAgICAgIElzVmFsaWRVdGY4VGVzdFV0aWwuRVhQRUNURURfVFdPX0JZVEVfUk9VTkRUUklQUEFCTEVfQ09VTlQpOworICB9CisKKyAgLyoqCisgICAqIFRlc3RzIHRoYXQgcm91bmQgdHJpcHBpbmcgb2YgYWxsIHRocmVlIGJ5dGUgcGVybXV0YXRpb25zIHdvcmsuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SXNWYWxpZFV0ZjhfM0J5dGVzKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIElzVmFsaWRVdGY4VGVzdFV0aWwudGVzdEJ5dGVzKDMsCisgICAgICAgIElzVmFsaWRVdGY4VGVzdFV0aWwuRVhQRUNURURfVEhSRUVfQllURV9ST1VORFRSSVBQQUJMRV9DT1VOVCk7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCByb3VuZCB0cmlwcGluZyBvZiBhIHNhbXBsZSBvZiBmb3VyIGJ5dGUgcGVybXV0YXRpb25zIHdvcmsuCisgICAqIEFsbCBwZXJtdXRhdGlvbnMgYXJlIHByb2hpYml0aXZlbHkgZXhwZW5zaXZlIHRvIHRlc3QgZm9yIGF1dG9tYXRlZCBydW5zOworICAgKiB7QGxpbmsgSXNWYWxpZFV0ZjhGb3VyQnl0ZVRlc3R9IGlzIHVzZWQgZm9yIGZ1bGwgY292ZXJhZ2UuIFRoaXMgbWV0aG9kCisgICAqIHRlc3RzIHNwZWNpZmljIGZvdXItYnl0ZSBjYXNlcy4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RJc1ZhbGlkVXRmOF80Qnl0ZXNTYW1wbGVzKCkKKyAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAvLyBWYWxpZCA0IGJ5dGUuCisgICAgYXNzZXJ0VmFsaWRVdGY4KDB4RjAsIDB4QTQsIDB4QUQsIDB4QTIpOworCisgICAgLy8gQmFkIHRyYWlsaW5nIGJ5dGVzCisgICAgYXNzZXJ0SW52YWxpZFV0ZjgoMHhGMCwgMHhBNCwgMHhBRCwgMHg3Rik7CisgICAgYXNzZXJ0SW52YWxpZFV0ZjgoMHhGMCwgMHhBNCwgMHhBRCwgMHhDMCk7CisKKyAgICAvLyBTcGVjaWFsIGNhc2VzIGZvciBieXRlMgorICAgIGFzc2VydEludmFsaWRVdGY4KDB4RjAsIDB4OEYsIDB4QUQsIDB4QTIpOworICAgIGFzc2VydEludmFsaWRVdGY4KDB4RjQsIDB4OTAsIDB4QUQsIDB4QTIpOworICB9CisKKyAgLyoqCisgICAqIFRlc3RzIHNvbWUgaGFyZC1jb2RlZCB0ZXN0IGNhc2VzLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNvbWVTZXF1ZW5jZXMoKSB7CisgICAgLy8gRW1wdHkKKyAgICBhc3NlcnRUcnVlKGFzQnl0ZXMoIiIpLmlzVmFsaWRVdGY4KCkpOworCisgICAgLy8gT25lLWJ5dGUgY2hhcmFjdGVycywgaW5jbHVkaW5nIGNvbnRyb2wgY2hhcmFjdGVycworICAgIGFzc2VydFRydWUoYXNCeXRlcygiXHUwMDAwYWJjXHUwMDdmIikuaXNWYWxpZFV0ZjgoKSk7CisKKyAgICAvLyBUd28tYnl0ZSBjaGFyYWN0ZXJzCisgICAgYXNzZXJ0VHJ1ZShhc0J5dGVzKCJcdTAwYTJcdTAwYTIiKS5pc1ZhbGlkVXRmOCgpKTsKKworICAgIC8vIFRocmVlLWJ5dGUgY2hhcmFjdGVycworICAgIGFzc2VydFRydWUoYXNCeXRlcygiXHUwMjBhY1x1MDIwYWMiKS5pc1ZhbGlkVXRmOCgpKTsKKworICAgIC8vIEZvdXItYnl0ZSBjaGFyYWN0ZXJzCisgICAgYXNzZXJ0VHJ1ZShhc0J5dGVzKCJcdTAyNEI2Mlx1MDI0QjYyIikuaXNWYWxpZFV0ZjgoKSk7CisKKyAgICAvLyBNaXhlZCBzdHJpbmcKKyAgICBhc3NlcnRUcnVlKAorICAgICAgICBhc0J5dGVzKCJhXHUwMjBhY1x1MDBhMmJcXHUwMjRCNjJ1MDIwYWNjXHUwMGEyZGVcdTAyNEI2MiIpCisgICAgICAgIC5pc1ZhbGlkVXRmOCgpKTsKKworICAgIC8vIE5vdCBhIHZhbGlkIHN0cmluZworICAgIGFzc2VydEludmFsaWRVdGY4KC0xLCAwLCAtMSwgMCk7CisgIH0KKworICBwcml2YXRlIGJ5dGVbXSB0b0J5dGVBcnJheShpbnQuLi4gYnl0ZXMpIHsKKyAgICBieXRlW10gcmVhbEJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXMubGVuZ3RoXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICByZWFsQnl0ZXNbaV0gPSAoYnl0ZSkgYnl0ZXNbaV07CisgICAgfQorICAgIHJldHVybiByZWFsQnl0ZXM7CisgIH0KKworICBwcml2YXRlIEJ5dGVTdHJpbmcgdG9CeXRlU3RyaW5nKGludC4uLiBieXRlcykgeworICAgIHJldHVybiBCeXRlU3RyaW5nLmNvcHlGcm9tKHRvQnl0ZUFycmF5KGJ5dGVzKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0VmFsaWRVdGY4KGludFtdIGJ5dGVzLCBib29sZWFuIG5vdCkgeworICAgIGJ5dGVbXSByZWFsQnl0ZXMgPSB0b0J5dGVBcnJheShieXRlcyk7CisgICAgYXNzZXJ0VHJ1ZShub3QgXiBVdGY4LmlzVmFsaWRVdGY4KHJlYWxCeXRlcykpOworICAgIGFzc2VydFRydWUobm90IF4gVXRmOC5pc1ZhbGlkVXRmOChyZWFsQnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCkpOworICAgIEJ5dGVTdHJpbmcgbGl0ID0gQnl0ZVN0cmluZy5jb3B5RnJvbShyZWFsQnl0ZXMpOworICAgIEJ5dGVTdHJpbmcgc3ViID0gbGl0LnN1YnN0cmluZygwLCBieXRlcy5sZW5ndGgpOworICAgIGFzc2VydFRydWUobm90IF4gbGl0LmlzVmFsaWRVdGY4KCkpOworICAgIGFzc2VydFRydWUobm90IF4gc3ViLmlzVmFsaWRVdGY4KCkpOworICAgIEJ5dGVTdHJpbmdbXSByb3BlcyA9IHsKKyAgICAgIFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdChCeXRlU3RyaW5nLkVNUFRZLCBsaXQpLAorICAgICAgUm9wZUJ5dGVTdHJpbmcubmV3SW5zdGFuY2VGb3JUZXN0KEJ5dGVTdHJpbmcuRU1QVFksIHN1YiksCisgICAgICBSb3BlQnl0ZVN0cmluZy5uZXdJbnN0YW5jZUZvclRlc3QobGl0LCBCeXRlU3RyaW5nLkVNUFRZKSwKKyAgICAgIFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdChzdWIsIEJ5dGVTdHJpbmcuRU1QVFkpLAorICAgICAgUm9wZUJ5dGVTdHJpbmcubmV3SW5zdGFuY2VGb3JUZXN0KHN1YiwgbGl0KQorICAgIH07CisgICAgZm9yIChCeXRlU3RyaW5nIHJvcGUgOiByb3BlcykgeworICAgICAgYXNzZXJ0VHJ1ZShub3QgXiByb3BlLmlzVmFsaWRVdGY4KCkpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRWYWxpZFV0ZjgoaW50Li4uIGJ5dGVzKSB7CisgICAgYXNzZXJ0VmFsaWRVdGY4KGJ5dGVzLCBmYWxzZSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0SW52YWxpZFV0ZjgoaW50Li4uIGJ5dGVzKSB7CisgICAgYXNzZXJ0VmFsaWRVdGY4KGJ5dGVzLCB0cnVlKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIEJ5dGVTdHJpbmcgYXNCeXRlcyhTdHJpbmcgcykgeworICAgIHJldHVybiBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChzKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTaGFyZHNIYXZlRXhwZWN0ZWRSb3VuZFRyaXBwYWJsZXMoKSB7CisgICAgLy8gQSBzYW5pdHkgY2hlY2suCisgICAgaW50IGFjdHVhbCA9IDA7CisgICAgZm9yIChTaGFyZCBzaGFyZCA6IElzVmFsaWRVdGY4VGVzdFV0aWwuRk9VUl9CWVRFX1NIQVJEUykgeworICAgICAgYWN0dWFsICs9IHNoYXJkLmV4cGVjdGVkOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoSXNWYWxpZFV0ZjhUZXN0VXRpbC5FWFBFQ1RFRF9GT1VSX0JZVEVfUk9VTkRUUklQUEFCTEVfQ09VTlQsCisgICAgICAgIGFjdHVhbCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0lzVmFsaWRVdGY4VGVzdFV0aWwuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0lzVmFsaWRVdGY4VGVzdFV0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDE1OTVlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvSXNWYWxpZFV0ZjhUZXN0VXRpbC5qYXZhCkBAIC0wLDAgKzEsNDIxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgc3RhdGljIGp1bml0LmZyYW1ld29yay5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RGVjb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RpbmdFcnJvckFjdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ29kZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworCisvKioKKyAqIFNoYXJlZCB0ZXN0aW5nIGNvZGUgZm9yIHtAbGluayBJc1ZhbGlkVXRmOFRlc3R9IGFuZAorICoge0BsaW5rIElzVmFsaWRVdGY4Rm91ckJ5dGVUZXN0fS4KKyAqCisgKiBAYXV0aG9yIGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKyAqIEBhdXRob3IgbWFydGlucmJAZ29vZ2xlLmNvbSAoTWFydGluIEJ1Y2hob2x6KQorICovCitjbGFzcyBJc1ZhbGlkVXRmOFRlc3RVdGlsIHsKKyAgcHJpdmF0ZSBzdGF0aWMgTG9nZ2VyIGxvZ2dlciA9IExvZ2dlci5nZXRMb2dnZXIoCisgICAgICBJc1ZhbGlkVXRmOFRlc3RVdGlsLmNsYXNzLmdldE5hbWUoKSk7CisKKyAgLy8gMTI4IC0gW2NoYXJzIDB4MDAwMCB0byAweDAwN2ZdCisgIHN0YXRpYyBsb25nIE9ORV9CWVRFX1JPVU5EVFJJUFBBQkxFX0NIQVJBQ1RFUlMgPSAweDAwN2YgLSAweDAwMDAgKyAxOworCisgIC8vIDEyOAorICBzdGF0aWMgbG9uZyBFWFBFQ1RFRF9PTkVfQllURV9ST1VORFRSSVBQQUJMRV9DT1VOVCA9CisgICAgICBPTkVfQllURV9ST1VORFRSSVBQQUJMRV9DSEFSQUNURVJTOworCisgIC8vIDE5MjAgW2NoYXJzIDB4MDA4MCB0byAweDA3RkZdCisgIHN0YXRpYyBsb25nIFRXT19CWVRFX1JPVU5EVFJJUFBBQkxFX0NIQVJBQ1RFUlMgPSAweDA3RkYgLSAweDAwODAgKyAxOworCisgIC8vIDE4LDMwNAorICBzdGF0aWMgbG9uZyBFWFBFQ1RFRF9UV09fQllURV9ST1VORFRSSVBQQUJMRV9DT1VOVCA9CisgICAgICAvLyBCb3RoIGJ5dGVzIGFyZSBvbmUgYnl0ZSBjaGFyYWN0ZXJzCisgICAgICAobG9uZykgTWF0aC5wb3coRVhQRUNURURfT05FX0JZVEVfUk9VTkRUUklQUEFCTEVfQ09VTlQsIDIpICsKKyAgICAgIC8vIFRoZSBwb3NzaWJsZSBudW1iZXIgb2YgdHdvIGJ5dGUgY2hhcmFjdGVycworICAgICAgVFdPX0JZVEVfUk9VTkRUUklQUEFCTEVfQ0hBUkFDVEVSUzsKKworICAvLyAyMDQ4CisgIHN0YXRpYyBsb25nIFRIUkVFX0JZVEVfU1VSUk9HQVRFUyA9IDIgKiAxMDI0OworCisgIC8vIDYxLDQ0MCBbY2hhcnMgMHgwODAwIHRvIDB4RkZGRiwgbWludXMgc3Vycm9nYXRlc10KKyAgc3RhdGljIGxvbmcgVEhSRUVfQllURV9ST1VORFRSSVBQQUJMRV9DSEFSQUNURVJTID0KKyAgICAgIDB4RkZGRiAtIDB4MDgwMCArIDEgLSBUSFJFRV9CWVRFX1NVUlJPR0FURVM7CisKKyAgLy8gMiw2NTAsMTEyCisgIHN0YXRpYyBsb25nIEVYUEVDVEVEX1RIUkVFX0JZVEVfUk9VTkRUUklQUEFCTEVfQ09VTlQgPQorICAgICAgLy8gQWxsIG9uZSBieXRlIGNoYXJhY3RlcnMKKyAgICAgIChsb25nKSBNYXRoLnBvdyhFWFBFQ1RFRF9PTkVfQllURV9ST1VORFRSSVBQQUJMRV9DT1VOVCwgMykgKworICAgICAgLy8gT25lIHR3byBieXRlIGNoYXJhY3RlciBhbmQgYSBvbmUgYnl0ZSBjaGFyYWN0ZXIKKyAgICAgIDIgKiBUV09fQllURV9ST1VORFRSSVBQQUJMRV9DSEFSQUNURVJTICoKKyAgICAgICAgICBPTkVfQllURV9ST1VORFRSSVBQQUJMRV9DSEFSQUNURVJTICsKKyAgICAgICAvLyBUaHJlZSBieXRlIGNoYXJhY3RlcnMKKyAgICAgIFRIUkVFX0JZVEVfUk9VTkRUUklQUEFCTEVfQ0hBUkFDVEVSUzsKKworICAvLyAxLDA0OCw1NzYgW2NoYXJzIDB4MTAwMDBMIHRvIDB4MTBGRkZGXQorICBzdGF0aWMgbG9uZyBGT1VSX0JZVEVfUk9VTkRUUklQUEFCTEVfQ0hBUkFDVEVSUyA9IDB4MTBGRkZGIC0gMHgxMDAwMEwgKyAxOworCisgIC8vIDI4OSw1NzEsODM5CisgIHN0YXRpYyBsb25nIEVYUEVDVEVEX0ZPVVJfQllURV9ST1VORFRSSVBQQUJMRV9DT1VOVCA9CisgICAgICAvLyBBbGwgb25lIGJ5dGUgY2hhcmFjdGVycworICAgICAgKGxvbmcpIE1hdGgucG93KEVYUEVDVEVEX09ORV9CWVRFX1JPVU5EVFJJUFBBQkxFX0NPVU5ULCA0KSArCisgICAgICAvLyBPbmUgYW5kIHRocmVlIGJ5dGUgY2hhcmFjdGVycworICAgICAgMiAqIFRIUkVFX0JZVEVfUk9VTkRUUklQUEFCTEVfQ0hBUkFDVEVSUyAqCisgICAgICAgICAgT05FX0JZVEVfUk9VTkRUUklQUEFCTEVfQ0hBUkFDVEVSUyArCisgICAgICAvLyBUd28gdHdvIGJ5dGUgY2hhcmFjdGVycworICAgICAgVFdPX0JZVEVfUk9VTkRUUklQUEFCTEVfQ0hBUkFDVEVSUyAqIFRXT19CWVRFX1JPVU5EVFJJUFBBQkxFX0NIQVJBQ1RFUlMgKworICAgICAgLy8gUGVybXV0YXRpb25zIG9mIG9uZSBhbmQgdHdvIGJ5dGUgY2hhcmFjdGVycworICAgICAgMyAqIFRXT19CWVRFX1JPVU5EVFJJUFBBQkxFX0NIQVJBQ1RFUlMgKgorICAgICAgICAgIE9ORV9CWVRFX1JPVU5EVFJJUFBBQkxFX0NIQVJBQ1RFUlMgKgorICAgICAgICAgIE9ORV9CWVRFX1JPVU5EVFJJUFBBQkxFX0NIQVJBQ1RFUlMgKworICAgICAgLy8gRm91ciBieXRlIGNoYXJhY3RlcnMKKyAgICAgIEZPVVJfQllURV9ST1VORFRSSVBQQUJMRV9DSEFSQUNURVJTOworCisgIHN0YXRpYyBjbGFzcyBTaGFyZCB7CisgICAgZmluYWwgbG9uZyBpbmRleDsKKyAgICBmaW5hbCBsb25nIHN0YXJ0OworICAgIGZpbmFsIGxvbmcgbGltOworICAgIGZpbmFsIGxvbmcgZXhwZWN0ZWQ7CisKKworICAgIHB1YmxpYyBTaGFyZChsb25nIGluZGV4LCBsb25nIHN0YXJ0LCBsb25nIGxpbSwgbG9uZyBleHBlY3RlZCkgeworICAgICAgYXNzZXJ0VHJ1ZShzdGFydCA8IGxpbSk7CisgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CisgICAgICB0aGlzLmxpbSA9IGxpbTsKKyAgICAgIHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZDsKKyAgICB9CisgIH0KKworICBzdGF0aWMgZmluYWwgbG9uZ1tdIEZPVVJfQllURV9TSEFSRFNfRVhQRUNURURfUk9VTlRSSVBQQUJMRVMgPQorICAgICAgZ2VuZXJhdGVGb3VyQnl0ZVNoYXJkc0V4cGVjdGVkUnVubmFibGVzKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgbG9uZ1tdIGdlbmVyYXRlRm91ckJ5dGVTaGFyZHNFeHBlY3RlZFJ1bm5hYmxlcygpIHsKKyAgICBsb25nW10gZXhwZWN0ZWQgPSBuZXcgbG9uZ1sxMjhdOworCisgICAgLy8gMC02MyBhcmUgYWxsIDUzMDAyMjQKKyAgICBmb3IgKGludCBpID0gMDsgaSA8PSA2MzsgaSsrKSB7CisgICAgICBleHBlY3RlZFtpXSA9IDUzMDAyMjQ7CisgICAgfQorCisgICAgLy8gOTctMTExIGFyZSBhbGwgMjM0MjkxMgorICAgIGZvciAoaW50IGkgPSA5NzsgaSA8PSAxMTE7IGkrKykgeworICAgICBleHBlY3RlZFtpXSA9IDIzNDI5MTI7CisgICAgfQorCisgICAgLy8gMTEzLTExNyBhcmUgYWxsIDEwNDg1NzYKKyAgICBmb3IgKGludCBpID0gMTEzOyBpIDw9IDExNzsgaSsrKSB7CisgICAgICBleHBlY3RlZFtpXSA9IDEwNDg1NzY7CisgICAgfQorCisgICAgLy8gT25lIG9mZnMKKyAgICBleHBlY3RlZFsxMTJdID0gNzg2NDMyOworICAgIGV4cGVjdGVkWzExOF0gPSA3ODY0MzI7CisgICAgZXhwZWN0ZWRbMTE5XSA9IDEwNDg1NzY7CisgICAgZXhwZWN0ZWRbMTIwXSA9IDQ1ODc1MjsKKyAgICBleHBlY3RlZFsxMjFdID0gNTI0Mjg4OworICAgIGV4cGVjdGVkWzEyMl0gPSA2NTUzNjsKKworICAgIC8vIEFueXRoaW5nIG5vdCBhc3NpZ25lZCB3YXMgdGhlIGRlZmF1bHQgMC4KKyAgICByZXR1cm4gZXhwZWN0ZWQ7CisgIH0KKworICBzdGF0aWMgZmluYWwgTGlzdDxTaGFyZD4gRk9VUl9CWVRFX1NIQVJEUyA9IGdlbmVyYXRlRm91ckJ5dGVTaGFyZHMoCisgICAgICAxMjgsIEZPVVJfQllURV9TSEFSRFNfRVhQRUNURURfUk9VTlRSSVBQQUJMRVMpOworCisKKyAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxTaGFyZD4gZ2VuZXJhdGVGb3VyQnl0ZVNoYXJkcygKKyAgICAgIGludCBudW1TaGFyZHMsIGxvbmdbXSBleHBlY3RlZCkgeworICAgIGFzc2VydEVxdWFscyhudW1TaGFyZHMsIGV4cGVjdGVkLmxlbmd0aCk7CisgICAgTGlzdDxTaGFyZD4gc2hhcmRzID0gbmV3IEFycmF5TGlzdDxTaGFyZD4obnVtU2hhcmRzKTsKKyAgICBsb25nIExJTSA9IDFMIDw8IDMyOworICAgIGxvbmcgaW5jcmVtZW50ID0gTElNIC8gbnVtU2hhcmRzOworICAgIGFzc2VydFRydWUoTElNICUgbnVtU2hhcmRzID09IDApOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtU2hhcmRzOyBpKyspIHsKKyAgICAgIHNoYXJkcy5hZGQobmV3IFNoYXJkKGksCisgICAgICAgICAgaW5jcmVtZW50ICogaSwKKyAgICAgICAgICBpbmNyZW1lbnQgKiAoaSArIDEpLAorICAgICAgICAgIGV4cGVjdGVkW2ldKSk7CisgICAgfQorICAgIHJldHVybiBzaGFyZHM7CisgIH0KKworICAvKioKKyAgICogSGVscGVyIHRvIHJ1biB0aGUgbG9vcCB0byB0ZXN0IGFsbCB0aGUgcGVybXV0YXRpb25zIGZvciB0aGUgbnVtYmVyIG9mIGJ5dGVzCisgICAqIHNwZWNpZmllZC4KKyAgICoKKyAgICogQHBhcmFtIG51bUJ5dGVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIGV4cGVjdGVkQ291bnQgdGhlIGV4cGVjdGVkIG51bWJlciBvZiByb3VuZHRyaXBwYWJsZSBwZXJtdXRhdGlvbnMKKyAgICovCisgIHN0YXRpYyB2b2lkIHRlc3RCeXRlcyhpbnQgbnVtQnl0ZXMsIGxvbmcgZXhwZWN0ZWRDb3VudCkKKyAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICB0ZXN0Qnl0ZXMobnVtQnl0ZXMsIGV4cGVjdGVkQ291bnQsIDAsIC0xKTsKKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgdG8gcnVuIHRoZSBsb29wIHRvIHRlc3QgYWxsIHRoZSBwZXJtdXRhdGlvbnMgZm9yIHRoZSBudW1iZXIgb2YgYnl0ZXMKKyAgICogc3BlY2lmaWVkLiBUaGlzIG92ZXJsb2FkIGlzIHVzZWZ1bCBmb3IgZGVidWdnaW5nIHRvIGdldCB0aGUgbG9vcCB0byBzdGFydAorICAgKiBhdCBhIGNlcnRhaW4gY2hhcmFjdGVyLgorICAgKgorICAgKiBAcGFyYW0gbnVtQnl0ZXMgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYnl0ZSBhcnJheQorICAgKiBAcGFyYW0gZXhwZWN0ZWRDb3VudCB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIHJvdW5kdHJpcHBhYmxlIHBlcm11dGF0aW9ucworICAgKiBAcGFyYW0gc3RhcnQgdGhlIHN0YXJ0aW5nIGJ5dGVzIGVuY29kZWQgYXMgYSBsb25nIGFzIGJpZy1lbmRpYW4KKyAgICogQHBhcmFtIGxpbSB0aGUgbGltaXQgb2YgYnl0ZXMgdG8gcHJvY2VzcyBlbmNvZGVkIGFzIGEgbG9uZyBhcyBiaWctZW5kaWFuLAorICAgKiAgICAgb3IgLTEgdG8gbWVhbiB0aGUgbWF4IGxpbWl0IGZvciBudW1CeXRlcworICAgKi8KKyAgc3RhdGljIHZvaWQgdGVzdEJ5dGVzKGludCBudW1CeXRlcywgbG9uZyBleHBlY3RlZENvdW50LCBsb25nIHN0YXJ0LCBsb25nIGxpbSkKKyAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgpOworICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW251bUJ5dGVzXTsKKworICAgIGlmIChsaW0gPT0gLTEpIHsKKyAgICAgIGxpbSA9IDFMIDw8IChudW1CeXRlcyAqIDgpOworICAgIH0KKyAgICBsb25nIGNvdW50ID0gMDsKKyAgICBsb25nIGNvdW50Um91bmRUcmlwcGVkID0gMDsKKyAgICBmb3IgKGxvbmcgYnl0ZUNoYXIgPSBzdGFydDsgYnl0ZUNoYXIgPCBsaW07IGJ5dGVDaGFyKyspIHsKKyAgICAgIGxvbmcgdG1wQnl0ZUNoYXIgPSBieXRlQ2hhcjsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQnl0ZXM7IGkrKykgeworICAgICAgICBieXRlc1tieXRlcy5sZW5ndGggLSBpIC0gMV0gPSAoYnl0ZSkgdG1wQnl0ZUNoYXI7CisgICAgICAgIHRtcEJ5dGVDaGFyID0gdG1wQnl0ZUNoYXIgPj4gODsKKyAgICAgIH0KKyAgICAgIEJ5dGVTdHJpbmcgYnMgPSBCeXRlU3RyaW5nLmNvcHlGcm9tKGJ5dGVzKTsKKyAgICAgIGJvb2xlYW4gaXNSb3VuZFRyaXBwYWJsZSA9IGJzLmlzVmFsaWRVdGY4KCk7CisgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoYnl0ZXMsICJVVEYtOCIpOworICAgICAgYnl0ZVtdIGJ5dGVzUmVlbmNvZGVkID0gcy5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgIGJvb2xlYW4gYnl0ZXNFcXVhbCA9IEFycmF5cy5lcXVhbHMoYnl0ZXMsIGJ5dGVzUmVlbmNvZGVkKTsKKworICAgICAgaWYgKGJ5dGVzRXF1YWwgIT0gaXNSb3VuZFRyaXBwYWJsZSkgeworICAgICAgICBvdXRwdXRGYWlsdXJlKGJ5dGVDaGFyLCBieXRlcywgYnl0ZXNSZWVuY29kZWQpOworICAgICAgfQorCisgICAgICAvLyBDaGVjayBhZ3JlZW1lbnQgd2l0aCBzdGF0aWMgVXRmOCBtZXRob2RzLgorICAgICAgYXNzZXJ0RXF1YWxzKGlzUm91bmRUcmlwcGFibGUsIFV0ZjguaXNWYWxpZFV0ZjgoYnl0ZXMpKTsKKyAgICAgIGFzc2VydEVxdWFscyhpc1JvdW5kVHJpcHBhYmxlLCBVdGY4LmlzVmFsaWRVdGY4KGJ5dGVzLCAwLCBudW1CeXRlcykpOworCisgICAgICAvLyBUZXN0IHBhcnRpYWwgc2VxdWVuY2VzLgorICAgICAgLy8gUGFydGl0aW9uIG51bUJ5dGVzIGludG8gdGhyZWUgc2VnbWVudHMgKG5vdCBuZWNlc3NhcmlseSBub24tZW1wdHkpLgorICAgICAgaW50IGkgPSBybmQubmV4dEludChudW1CeXRlcyk7CisgICAgICBpbnQgaiA9IHJuZC5uZXh0SW50KG51bUJ5dGVzKTsKKyAgICAgIGlmIChqIDwgaSkgeworICAgICAgICBpbnQgdG1wID0gaTsgaSA9IGo7IGogPSB0bXA7CisgICAgICB9CisgICAgICBpbnQgc3RhdGUxID0gVXRmOC5wYXJ0aWFsSXNWYWxpZFV0ZjgoVXRmOC5DT01QTEVURSwgYnl0ZXMsIDAsIGkpOworICAgICAgaW50IHN0YXRlMiA9IFV0ZjgucGFydGlhbElzVmFsaWRVdGY4KHN0YXRlMSwgYnl0ZXMsIGksIGopOworICAgICAgaW50IHN0YXRlMyA9IFV0ZjgucGFydGlhbElzVmFsaWRVdGY4KHN0YXRlMiwgYnl0ZXMsIGosIG51bUJ5dGVzKTsKKyAgICAgIGlmIChpc1JvdW5kVHJpcHBhYmxlICE9IChzdGF0ZTMgPT0gVXRmOC5DT01QTEVURSkpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGYoInN0YXRlPSUwNHggJTA0eCAlMDR4IGk9JWQgaj0lZCVuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUxLCBzdGF0ZTIsIHN0YXRlMywgaSwgaik7CisgICAgICAgIG91dHB1dEZhaWx1cmUoYnl0ZUNoYXIsIGJ5dGVzLCBieXRlc1JlZW5jb2RlZCk7CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoaXNSb3VuZFRyaXBwYWJsZSwgKHN0YXRlMyA9PSBVdGY4LkNPTVBMRVRFKSk7CisKKyAgICAgIC8vIFRlc3Qgcm9wZXMgYnVpbHQgb3V0IG9mIHNtYWxsIHBhcnRpYWwgc2VxdWVuY2VzCisgICAgICBCeXRlU3RyaW5nIHJvcGUgPSBSb3BlQnl0ZVN0cmluZy5uZXdJbnN0YW5jZUZvclRlc3QoCisgICAgICAgICAgYnMuc3Vic3RyaW5nKDAsIGkpLAorICAgICAgICAgIFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdCgKKyAgICAgICAgICAgICAgYnMuc3Vic3RyaW5nKGksIGopLAorICAgICAgICAgICAgICBicy5zdWJzdHJpbmcoaiwgbnVtQnl0ZXMpKSk7CisgICAgICBhc3NlcnRTYW1lKFJvcGVCeXRlU3RyaW5nLmNsYXNzLCByb3BlLmdldENsYXNzKCkpOworCisgICAgICBCeXRlU3RyaW5nW10gYnl0ZVN0cmluZ3MgPSB7IGJzLCBicy5zdWJzdHJpbmcoMCwgbnVtQnl0ZXMpLCByb3BlIH07CisgICAgICBmb3IgKEJ5dGVTdHJpbmcgeCA6IGJ5dGVTdHJpbmdzKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhpc1JvdW5kVHJpcHBhYmxlLAorICAgICAgICAgICAgICAgICAgICAgeC5pc1ZhbGlkVXRmOCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN0YXRlMywKKyAgICAgICAgICAgICAgICAgICAgIHgucGFydGlhbElzVmFsaWRVdGY4KFV0ZjguQ09NUExFVEUsIDAsIG51bUJ5dGVzKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN0YXRlMSwKKyAgICAgICAgICAgICAgICAgICAgIHgucGFydGlhbElzVmFsaWRVdGY4KFV0ZjguQ09NUExFVEUsIDAsIGkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN0YXRlMSwKKyAgICAgICAgICAgICAgICAgICAgIHguc3Vic3RyaW5nKDAsIGkpLnBhcnRpYWxJc1ZhbGlkVXRmOChVdGY4LkNPTVBMRVRFLCAwLCBpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdGF0ZTIsCisgICAgICAgICAgICAgICAgICAgICB4LnBhcnRpYWxJc1ZhbGlkVXRmOChzdGF0ZTEsIGksIGogLSBpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdGF0ZTIsCisgICAgICAgICAgICAgICAgICAgICB4LnN1YnN0cmluZyhpLCBqKS5wYXJ0aWFsSXNWYWxpZFV0Zjgoc3RhdGUxLCAwLCBqIC0gaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RhdGUzLAorICAgICAgICAgICAgICAgICAgICAgeC5wYXJ0aWFsSXNWYWxpZFV0Zjgoc3RhdGUyLCBqLCBudW1CeXRlcyAtIGopKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN0YXRlMywKKyAgICAgICAgICAgICAgICAgICAgIHguc3Vic3RyaW5nKGosIG51bUJ5dGVzKQorICAgICAgICAgICAgICAgICAgICAgLnBhcnRpYWxJc1ZhbGlkVXRmOChzdGF0ZTIsIDAsIG51bUJ5dGVzIC0gaikpOworICAgICAgfQorCisgICAgICAvLyBCeXRlU3RyaW5nIHJlZHVwbGljYXRpb24gc2hvdWxkIG5vdCBhZmZlY3QgaXRzIFVURi04IHZhbGlkaXR5LgorICAgICAgQnl0ZVN0cmluZyByb3BlQURvcGUgPQorICAgICAgICAgIFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdChicywgYnMuc3Vic3RyaW5nKDAsIG51bUJ5dGVzKSk7CisgICAgICBhc3NlcnRFcXVhbHMoaXNSb3VuZFRyaXBwYWJsZSwgcm9wZUFEb3BlLmlzVmFsaWRVdGY4KCkpOworCisgICAgICBpZiAoaXNSb3VuZFRyaXBwYWJsZSkgeworICAgICAgICBjb3VudFJvdW5kVHJpcHBlZCsrOworICAgICAgfQorICAgICAgY291bnQrKzsKKyAgICAgIGlmIChieXRlQ2hhciAhPSAwICYmIGJ5dGVDaGFyICUgMTAwMDAwMEwgPT0gMCkgeworICAgICAgICBsb2dnZXIuaW5mbygiUHJvY2Vzc2VkICIgKyAoYnl0ZUNoYXIgLyAxMDAwMDAwTCkgKworICAgICAgICAgICAgIiBtaWxsaW9uIGNoYXJhY3RlcnMiKTsKKyAgICAgIH0KKyAgICB9CisgICAgbG9nZ2VyLmluZm8oIlJvdW5kIHRyaXBwZWQgIiArIGNvdW50Um91bmRUcmlwcGVkICsgIiBvZiAiICsgY291bnQpOworICAgIGFzc2VydEVxdWFscyhleHBlY3RlZENvdW50LCBjb3VudFJvdW5kVHJpcHBlZCk7CisgIH0KKworICAvKioKKyAgICogVmFyaWF0aW9uIG9mIHtAbGluayAjdGVzdEJ5dGVzfSB0aGF0IGRvZXMgbGVzcyBhbGxvY2F0aW9uIHVzaW5nIHRoZQorICAgKiBsb3ctbGV2ZWwgZW5jb2RlcnMvZGVjb2RlcnMgZGlyZWN0bHkuIENoZWNrZWQgaW4gYmVjYXVzZSBpdCdzIHVzZWZ1bCBmb3IKKyAgICogZGVidWdnaW5nIHdoZW4gdHJ5aW5nIHRvIHByb2Nlc3MgYnl0ZXMgZmFzdGVyLCBidXQgc2luY2UgaXQgZG9lc24ndCB1c2UgdGhlCisgICAqIGFjdHVhbCBTdHJpbmcgY2xhc3MsIGl0J3MgcG9zc2libGUgZm9yIGluY29tcGF0aWJpbGl0aWVzIHRvIGRldmVsb3AKKyAgICogKGFsdGhvdWdoIHVubGlrZWx5KS4KKyAgICoKKyAgICogQHBhcmFtIG51bUJ5dGVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIGV4cGVjdGVkQ291bnQgdGhlIGV4cGVjdGVkIG51bWJlciBvZiByb3VuZHRyaXBwYWJsZSBwZXJtdXRhdGlvbnMKKyAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydGluZyBieXRlcyBlbmNvZGVkIGFzIGEgbG9uZyBhcyBiaWctZW5kaWFuCisgICAqIEBwYXJhbSBsaW0gdGhlIGxpbWl0IG9mIGJ5dGVzIHRvIHByb2Nlc3MgZW5jb2RlZCBhcyBhIGxvbmcgYXMgYmlnLWVuZGlhbiwKKyAgICogICAgIG9yIC0xIHRvIG1lYW4gdGhlIG1heCBsaW1pdCBmb3IgbnVtQnl0ZXMKKyAgICovCisgIHZvaWQgdGVzdEJ5dGVzVXNpbmdCeXRlQnVmZmVycygKKyAgICAgIGludCBudW1CeXRlcywgbG9uZyBleHBlY3RlZENvdW50LCBsb25nIHN0YXJ0LCBsb25nIGxpbSkKKyAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpLm5ld0RlY29kZXIoKQorICAgICAgICAub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKQorICAgICAgICAub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpOworICAgIENoYXJzZXRFbmNvZGVyIGVuY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoIlVURi04IikubmV3RW5jb2RlcigpCisgICAgICAgIC5vbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpCisgICAgICAgIC5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbbnVtQnl0ZXNdOworICAgIGludCBtYXhDaGFycyA9IChpbnQpIChkZWNvZGVyLm1heENoYXJzUGVyQnl0ZSgpICogbnVtQnl0ZXMpICsgMTsKKyAgICBjaGFyW10gY2hhcnNEZWNvZGVkID0KKyAgICAgICAgbmV3IGNoYXJbKGludCkgKGRlY29kZXIubWF4Q2hhcnNQZXJCeXRlKCkgKiBudW1CeXRlcykgKyAxXTsKKyAgICBpbnQgbWF4Qnl0ZXMgPSAoaW50KSAoZW5jb2Rlci5tYXhCeXRlc1BlckNoYXIoKSAqIG1heENoYXJzKSArIDE7CisgICAgYnl0ZVtdIGJ5dGVzUmVlbmNvZGVkID0gbmV3IGJ5dGVbbWF4Qnl0ZXNdOworCisgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIud3JhcChieXRlcyk7CisgICAgQ2hhckJ1ZmZlciBjYiA9IENoYXJCdWZmZXIud3JhcChjaGFyc0RlY29kZWQpOworICAgIEJ5dGVCdWZmZXIgYmJSZWVuY29kZWQgPSBCeXRlQnVmZmVyLndyYXAoYnl0ZXNSZWVuY29kZWQpOworICAgIGlmIChsaW0gPT0gLTEpIHsKKyAgICAgIGxpbSA9IDFMIDw8IChudW1CeXRlcyAqIDgpOworICAgIH0KKyAgICBsb25nIGNvdW50ID0gMDsKKyAgICBsb25nIGNvdW50Um91bmRUcmlwcGVkID0gMDsKKyAgICBmb3IgKGxvbmcgYnl0ZUNoYXIgPSBzdGFydDsgYnl0ZUNoYXIgPCBsaW07IGJ5dGVDaGFyKyspIHsKKyAgICAgIGJiLnJld2luZCgpOworICAgICAgYmIubGltaXQoYnl0ZXMubGVuZ3RoKTsKKyAgICAgIGNiLnJld2luZCgpOworICAgICAgY2IubGltaXQoY2hhcnNEZWNvZGVkLmxlbmd0aCk7CisgICAgICBiYlJlZW5jb2RlZC5yZXdpbmQoKTsKKyAgICAgIGJiUmVlbmNvZGVkLmxpbWl0KGJ5dGVzUmVlbmNvZGVkLmxlbmd0aCk7CisgICAgICBlbmNvZGVyLnJlc2V0KCk7CisgICAgICBkZWNvZGVyLnJlc2V0KCk7CisgICAgICBsb25nIHRtcEJ5dGVDaGFyID0gYnl0ZUNoYXI7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGJ5dGVzW2J5dGVzLmxlbmd0aCAtIGkgLSAxXSA9IChieXRlKSB0bXBCeXRlQ2hhcjsKKyAgICAgICAgdG1wQnl0ZUNoYXIgPSB0bXBCeXRlQ2hhciA+PiA4OworICAgICAgfQorICAgICAgYm9vbGVhbiBpc1JvdW5kVHJpcHBhYmxlID0gQnl0ZVN0cmluZy5jb3B5RnJvbShieXRlcykuaXNWYWxpZFV0ZjgoKTsKKyAgICAgIENvZGVyUmVzdWx0IHJlc3VsdCA9IGRlY29kZXIuZGVjb2RlKGJiLCBjYiwgdHJ1ZSk7CisgICAgICBhc3NlcnRGYWxzZShyZXN1bHQuaXNFcnJvcigpKTsKKyAgICAgIHJlc3VsdCA9IGRlY29kZXIuZmx1c2goY2IpOworICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0LmlzRXJyb3IoKSk7CisKKyAgICAgIGludCBjaGFyTGVuID0gY2IucG9zaXRpb24oKTsKKyAgICAgIGNiLnJld2luZCgpOworICAgICAgY2IubGltaXQoY2hhckxlbik7CisgICAgICByZXN1bHQgPSBlbmNvZGVyLmVuY29kZShjYiwgYmJSZWVuY29kZWQsIHRydWUpOworICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0LmlzRXJyb3IoKSk7CisgICAgICByZXN1bHQgPSBlbmNvZGVyLmZsdXNoKGJiUmVlbmNvZGVkKTsKKyAgICAgIGFzc2VydEZhbHNlKHJlc3VsdC5pc0Vycm9yKCkpOworCisgICAgICBib29sZWFuIGJ5dGVzRXF1YWwgPSB0cnVlOworICAgICAgaW50IGJ5dGVzTGVuID0gYmJSZWVuY29kZWQucG9zaXRpb24oKTsKKyAgICAgIGlmIChieXRlc0xlbiAhPSBudW1CeXRlcykgeworICAgICAgICBieXRlc0VxdWFsID0gZmFsc2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJ5dGVzOyBpKyspIHsKKyAgICAgICAgICBpZiAoYnl0ZXNbaV0gIT0gYnl0ZXNSZWVuY29kZWRbaV0pIHsKKyAgICAgICAgICAgIGJ5dGVzRXF1YWwgPSBmYWxzZTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKGJ5dGVzRXF1YWwgIT0gaXNSb3VuZFRyaXBwYWJsZSkgeworICAgICAgICBvdXRwdXRGYWlsdXJlKGJ5dGVDaGFyLCBieXRlcywgYnl0ZXNSZWVuY29kZWQsIGJ5dGVzTGVuKTsKKyAgICAgIH0KKworICAgICAgY291bnQrKzsKKyAgICAgIGlmIChpc1JvdW5kVHJpcHBhYmxlKSB7CisgICAgICAgIGNvdW50Um91bmRUcmlwcGVkKys7CisgICAgICB9CisgICAgICBpZiAoYnl0ZUNoYXIgIT0gMCAmJiBieXRlQ2hhciAlIDEwMDAwMDAgPT0gMCkgeworICAgICAgICBsb2dnZXIuaW5mbygiUHJvY2Vzc2VkICIgKyAoYnl0ZUNoYXIgLyAxMDAwMDAwKSArCisgICAgICAgICAgICAiIG1pbGxpb24gY2hhcmFjdGVycyIpOworICAgICAgfQorICAgIH0KKyAgICBsb2dnZXIuaW5mbygiUm91bmQgdHJpcHBlZCAiICsgY291bnRSb3VuZFRyaXBwZWQgKyAiIG9mICIgKyBjb3VudCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkQ291bnQsIGNvdW50Um91bmRUcmlwcGVkKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgb3V0cHV0RmFpbHVyZShsb25nIGJ5dGVDaGFyLCBieXRlW10gYnl0ZXMsIGJ5dGVbXSBhZnRlcikgeworICAgIG91dHB1dEZhaWx1cmUoYnl0ZUNoYXIsIGJ5dGVzLCBhZnRlciwgYWZ0ZXIubGVuZ3RoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgb3V0cHV0RmFpbHVyZShsb25nIGJ5dGVDaGFyLCBieXRlW10gYnl0ZXMsIGJ5dGVbXSBhZnRlciwKKyAgICAgIGludCBsZW4pIHsKKyAgICBmYWlsKCJGYWlsdXJlOiAoIiArIExvbmcudG9IZXhTdHJpbmcoYnl0ZUNoYXIpICsgIikgIiArCisgICAgICAgIHRvSGV4U3RyaW5nKGJ5dGVzKSArICIgPT4gIiArIHRvSGV4U3RyaW5nKGFmdGVyLCBsZW4pKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b0hleFN0cmluZyhieXRlW10gYikgeworICAgIHJldHVybiB0b0hleFN0cmluZyhiLCBiLmxlbmd0aCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdG9IZXhTdHJpbmcoYnl0ZVtdIGIsIGludCBsZW4pIHsKKyAgICBTdHJpbmdCdWlsZGVyIHMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIHMuYXBwZW5kKCJcIiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgIGlmIChpID4gMCkgeworICAgICAgICBzLmFwcGVuZCgiICIpOworICAgICAgfQorICAgICAgcy5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJTAyeCIsIGJbaV0gJiAweEZGKSk7CisgICAgfQorICAgIHMuYXBwZW5kKCJcIiIpOworICAgIHJldHVybiBzLnRvU3RyaW5nKCk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkTGl0ZVRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlGaWVsZExpdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjExYjU2OQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlGaWVsZExpdGVUZXN0LmphdmEKQEAgLTAsMCArMSwyNzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEludDMyRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsSW50NjRFeHRlbnNpb247CisKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVW5pdCB0ZXN0IGZvciB7QGxpbmsgTGF6eUZpZWxkTGl0ZX0uCisgKgorICogQGF1dGhvciB4aWFuZ2xAZ29vZ2xlLmNvbSAoWGlhbmcgTGkpCisgKi8KK3B1YmxpYyBjbGFzcyBMYXp5RmllbGRMaXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWUoKSB7CisgICAgTWVzc2FnZUxpdGUgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIExhenlGaWVsZExpdGUgbGF6eUZpZWxkID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKG1lc3NhZ2UpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBsYXp5RmllbGQuZ2V0VmFsdWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgICAgY2hhbmdlVmFsdWUobGF6eUZpZWxkKTsKKyAgICBhc3NlcnROb3RFcXVhbChtZXNzYWdlLCBsYXp5RmllbGQuZ2V0VmFsdWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWVFeCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRBbGxFeHRlbnNpb25zU2V0KCk7CisgICAgTGF6eUZpZWxkTGl0ZSBsYXp5RmllbGQgPSBjcmVhdGVMYXp5RmllbGRMaXRlRnJvbU1lc3NhZ2UobWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIGxhenlGaWVsZC5nZXRWYWx1ZShUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOworICAgIGNoYW5nZVZhbHVlKGxhenlGaWVsZCk7CisgICAgYXNzZXJ0Tm90RXF1YWwobWVzc2FnZSwgbGF6eUZpZWxkLmdldFZhbHVlKFRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2V0VmFsdWUoKSB7CisgICAgTWVzc2FnZUxpdGUgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIExhenlGaWVsZExpdGUgbGF6eUZpZWxkID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKG1lc3NhZ2UpOworICAgIGNoYW5nZVZhbHVlKGxhenlGaWVsZCk7CisgICAgYXNzZXJ0Tm90RXF1YWwobWVzc2FnZSwgbGF6eUZpZWxkLmdldFZhbHVlKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOworICAgIG1lc3NhZ2UgPSBsYXp5RmllbGQuZ2V0VmFsdWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICBjaGFuZ2VWYWx1ZShsYXp5RmllbGQpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBsYXp5RmllbGQuZ2V0VmFsdWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2V0VmFsdWVFeCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRBbGxFeHRlbnNpb25zU2V0KCk7CisgICAgTGF6eUZpZWxkTGl0ZSBsYXp5RmllbGQgPSBjcmVhdGVMYXp5RmllbGRMaXRlRnJvbU1lc3NhZ2UobWVzc2FnZSk7CisgICAgY2hhbmdlVmFsdWUobGF6eUZpZWxkKTsKKyAgICBhc3NlcnROb3RFcXVhbChtZXNzYWdlLCBsYXp5RmllbGQuZ2V0VmFsdWUoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKyAgICBNZXNzYWdlTGl0ZSB2YWx1ZSA9IGxhenlGaWVsZC5nZXRWYWx1ZShUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgY2hhbmdlVmFsdWUobGF6eUZpZWxkKTsKKyAgICBhc3NlcnRFcXVhbHModmFsdWUsIGxhenlGaWVsZC5nZXRWYWx1ZShUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldFNlcmlhbGl6ZWRTaXplKCkgeworICAgIE1lc3NhZ2VMaXRlIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRBbGxTZXQoKTsKKyAgICBMYXp5RmllbGRMaXRlIGxhenlGaWVsZCA9IGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpLCBsYXp5RmllbGQuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgICAgY2hhbmdlVmFsdWUobGF6eUZpZWxkKTsKKyAgICBhc3NlcnROb3RFcXVhbChtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIGxhenlGaWVsZC5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRTZXJpYWxpemVkU2l6ZUV4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBMYXp5RmllbGRMaXRlIGxhenlGaWVsZCA9IGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpLCBsYXp5RmllbGQuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgICAgY2hhbmdlVmFsdWUobGF6eUZpZWxkKTsKKyAgICBhc3NlcnROb3RFcXVhbChtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIGxhenlGaWVsZC5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRCeXRlU3RyaW5nKCkgeworICAgIE1lc3NhZ2VMaXRlIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRBbGxTZXQoKTsKKyAgICBMYXp5RmllbGRMaXRlIGxhenlGaWVsZCA9IGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS50b0J5dGVTdHJpbmcoKSwgbGF6eUZpZWxkLnRvQnl0ZVN0cmluZygpKTsKKyAgICBjaGFuZ2VWYWx1ZShsYXp5RmllbGQpOworICAgIGFzc2VydE5vdEVxdWFsKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCksIGxhenlGaWVsZC50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZVN0cmluZ0V4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBMYXp5RmllbGRMaXRlIGxhenlGaWVsZCA9IGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS50b0J5dGVTdHJpbmcoKSwgbGF6eUZpZWxkLnRvQnl0ZVN0cmluZygpKTsKKyAgICBjaGFuZ2VWYWx1ZShsYXp5RmllbGQpOworICAgIGFzc2VydE5vdEVxdWFsKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCksIGxhenlGaWVsZC50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VFeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBMYXp5RmllbGRMaXRlIG9yaWdpbmFsID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKG1lc3NhZ2UpOworICAgIExhenlGaWVsZExpdGUgbWVyZ2VkID0gbmV3IExhenlGaWVsZExpdGUoKTsKKyAgICBtZXJnZWQubWVyZ2Uob3JpZ2luYWwpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIHZhbHVlID0gKFRlc3RBbGxFeHRlbnNpb25zKSBtZXJnZWQuZ2V0VmFsdWUoCisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgdmFsdWUpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVtcHR5TGF6eUZpZWxkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTGF6eUZpZWxkTGl0ZSBmaWVsZCA9IG5ldyBMYXp5RmllbGRMaXRlKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGZpZWxkLmdldFNlcmlhbGl6ZWRTaXplKCkpOworICAgIGFzc2VydEVxdWFscyhCeXRlU3RyaW5nLkVNUFRZLCBmaWVsZC50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZFByb3RvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2lsZW50bHkgZmFpbHMgYW5kIHVzZXMgdGhlIGRlZmF1bHQgaW5zdGFuY2UuCisgICAgTGF6eUZpZWxkTGl0ZSBmaWVsZCA9IG5ldyBMYXp5RmllbGRMaXRlKAorICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiaW52YWxpZCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgZmllbGQuZ2V0VmFsdWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGZpZWxkLmdldFNlcmlhbGl6ZWRTaXplKCkpOworICAgIGFzc2VydEVxdWFscyhCeXRlU3RyaW5nLkVNUFRZLCBmaWVsZC50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VCZWZvcmVQYXJzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UxID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDEpLmJ1aWxkKCk7CisgICAgTGF6eUZpZWxkTGl0ZSBmaWVsZDEgPSBjcmVhdGVMYXp5RmllbGRMaXRlRnJvbU1lc3NhZ2UobWVzc2FnZTEpOworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlMiA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQ2NCgyKS5idWlsZCgpOworICAgIExhenlGaWVsZExpdGUgZmllbGQyID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKG1lc3NhZ2UyKTsKKworICAgIGZpZWxkMS5tZXJnZShmaWVsZDIpOworICAgIFRlc3RBbGxUeXBlcyBleHBlY3RlZCA9CisgICAgICAgIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigxKS5zZXRPcHRpb25hbEludDY0KDIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmaWVsZDEuZ2V0VmFsdWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VPbmVOb3RQYXJzZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0IGEgZmV3IGRpZmZlcmVudCBwYXRocyB0aGF0IGludm9sdmUgb25lIG1lc3NhZ2UgdGhhdCB3YXMgbm90IHBhcnNlZC4KKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZTEgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLnNldE9wdGlvbmFsSW50MzIoMSkuYnVpbGQoKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZTIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLnNldE9wdGlvbmFsSW50NjQoMikuYnVpbGQoKTsKKyAgICBUZXN0QWxsVHlwZXMgZXhwZWN0ZWQgPQorICAgICAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLnNldE9wdGlvbmFsSW50MzIoMSkuc2V0T3B0aW9uYWxJbnQ2NCgyKS5idWlsZCgpOworCisgICAgTGF6eUZpZWxkTGl0ZSBmaWVsZDEgPSBMYXp5RmllbGRMaXRlLmZyb21WYWx1ZShtZXNzYWdlMSk7CisgICAgZmllbGQxLmdldFZhbHVlKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7ICAvLyBGb3JjZSBwYXJzaW5nLgorICAgIExhenlGaWVsZExpdGUgZmllbGQyID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKG1lc3NhZ2UyKTsKKyAgICBmaWVsZDEubWVyZ2UoZmllbGQyKTsKKyAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGZpZWxkMS5nZXRWYWx1ZShUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKworICAgIC8vIE5vdyByZXZlcnNlIHdoaWNoIG9uZSBpcyBwYXJzZWQgZmlyc3QuCisgICAgZmllbGQxID0gTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUobWVzc2FnZTEpOworICAgIGZpZWxkMiA9IGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShtZXNzYWdlMik7CisgICAgZmllbGQyLmdldFZhbHVlKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7ICAvLyBGb3JjZSBwYXJzaW5nLgorICAgIGZpZWxkMS5tZXJnZShmaWVsZDIpOworICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZmllbGQxLmdldFZhbHVlKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlSW52YWxpZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3QgYSBmZXcgZGlmZmVyZW50IHBhdGhzIHRoYXQgaW52b2x2ZSBvbmUgbWVzc2FnZSB0aGF0IHdhcyBub3QgcGFyc2VkLgorICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDEpLmJ1aWxkKCk7CisgICAgTGF6eUZpZWxkTGl0ZSB2YWxpZCA9IExhenlGaWVsZExpdGUuZnJvbVZhbHVlKG1lc3NhZ2UpOworICAgIExhenlGaWVsZExpdGUgaW52YWxpZCA9IG5ldyBMYXp5RmllbGRMaXRlKAorICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiaW52YWxpZCIpKTsKKyAgICBpbnZhbGlkLm1lcmdlKHZhbGlkKTsKKworICAgIC8vIFdlIHN3YWxsb3cgdGhlIGV4Y2VwdGlvbiBhbmQganVzdCB1c2UgdGhlIHNldCBmaWVsZC4KKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgaW52YWxpZC5nZXRWYWx1ZShUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUtlZXBzRXh0ZW5zaW9uc1doZW5Qb3NzaWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEluIHRoaXMgdGVzdCB3ZSBhdHRlbXB0IHRvIG9ubHkgdXNlIHRoZSBlbXB0eSByZWdpc3RyeSwgd2hpY2ggd2lsbCBzdHJpcCBvdXQgYWxsIGV4dGVuc2lvbnMKKyAgICAvLyB3aGVuIHNlcmlhbGl6aW5nIGFuZCB0aGVuIHBhcnNpbmcuIFdlIHZlcmlmeSB0aGF0IGVhY2ggY29kZSBwYXRoIHdpbGwgYXR0ZW1wdCB0byBub3QKKyAgICAvLyBzZXJpYWxpemUgYW5kIHBhcnNlIGEgbWVzc2FnZSB0aGF0IHdhcyBzZXQgZGlyZWN0bHkgd2l0aG91dCBnb2luZyB0aHJvdWdoIHRoZQorICAgIC8vIGV4dGVuc2lvblJlZ2lzdHJ5LgorICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyA9CisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKS5zZXRFeHRlbnNpb24ob3B0aW9uYWxJbnQzMkV4dGVuc2lvbiwgNDIpLmJ1aWxkKCk7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgZW1wdHlNZXNzYWdlID0gVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisKKyAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZW1wdHlSZWdpc3RyeSA9IEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5nZXRFbXB0eVJlZ2lzdHJ5KCk7CisKKyAgICBMYXp5RmllbGRMaXRlIGZpZWxkID0gTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUobWVzc2FnZVdpdGhFeHRlbnNpb25zKTsKKyAgICBmaWVsZC5tZXJnZShjcmVhdGVMYXp5RmllbGRMaXRlRnJvbU1lc3NhZ2UoZW1wdHlSZWdpc3RyeSwgZW1wdHlNZXNzYWdlKSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywgZmllbGQuZ2V0VmFsdWUoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKworICAgIC8vIE5vdyByZXZlcnNlIHRoZSBvcmRlciBvZiB0aGUgbWVyZ2luZy4KKyAgICBmaWVsZCA9IGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShlbXB0eVJlZ2lzdHJ5LCBlbXB0eU1lc3NhZ2UpOworICAgIGZpZWxkLm1lcmdlKExhenlGaWVsZExpdGUuZnJvbVZhbHVlKG1lc3NhZ2VXaXRoRXh0ZW5zaW9ucykpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlV2l0aEV4dGVuc2lvbnMsIGZpZWxkLmdldFZhbHVlKFRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisKKyAgICAvLyBOb3cgdHJ5IHBhcnNpbmcgdGhlIGVtcHR5IGZpZWxkIGZpcnN0LgorICAgIGZpZWxkID0gTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUobWVzc2FnZVdpdGhFeHRlbnNpb25zKTsKKyAgICBMYXp5RmllbGRMaXRlIG90aGVyID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKGVtcHR5UmVnaXN0cnksIGVtcHR5TWVzc2FnZSk7CisgICAgb3RoZXIuZ2V0VmFsdWUoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOyAgLy8gRm9yY2UgcGFyc2luZy4KKyAgICBmaWVsZC5tZXJnZShvdGhlcik7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywgZmllbGQuZ2V0VmFsdWUoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKworICAgIC8vIEFuZCBhZ2FpbiByZXZlcnNlLgorICAgIGZpZWxkID0gY3JlYXRlTGF6eUZpZWxkTGl0ZUZyb21NZXNzYWdlKGVtcHR5UmVnaXN0cnksIGVtcHR5TWVzc2FnZSk7CisgICAgZmllbGQuZ2V0VmFsdWUoVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOyAgLy8gRm9yY2UgcGFyc2luZy4KKyAgICBvdGhlciA9IExhenlGaWVsZExpdGUuZnJvbVZhbHVlKG1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyk7CisgICAgZmllbGQubWVyZ2Uob3RoZXIpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlV2l0aEV4dGVuc2lvbnMsIGZpZWxkLmdldFZhbHVlKFRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VNaWdodExvc2VFeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGVzdCB0aGF0IHdlIGRvbid0IGtub3cgYWJvdXQgdGhlIGV4dGVuc2lvbnMgd2hlbiBwYXJzaW5nLgorICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UxID0KKyAgICAgICAgVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpLnNldEV4dGVuc2lvbihvcHRpb25hbEludDMyRXh0ZW5zaW9uLCAxKS5idWlsZCgpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyID0KKyAgICAgICAgVGVzdEFsbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpLnNldEV4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uLCAyTCkuYnVpbGQoKTsKKworICAgIExhenlGaWVsZExpdGUgZmllbGQgPSBMYXp5RmllbGRMaXRlLmZyb21WYWx1ZShtZXNzYWdlMSk7CisgICAgZmllbGQubWVyZ2UoTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUobWVzc2FnZTIpKTsKKworICAgIC8vIFdlIGxvc2UgdGhlIGV4dGVuc2lvbnMgZnJvbSBtZXNzYWdlIDIgYmVjYXVzZSB3ZSBoYXZlIHRvIHNlcmlhbGl6ZSBpdCBhbmQgdGhlbiBwYXJzZSBpdAorICAgIC8vIGFnYWluLCB1c2luZyB0aGUgZW1wdHkgcmVnaXN0cnkgdGhpcyB0aW1lLgorICAgIFRlc3RBbGxFeHRlbnNpb25zIHZhbHVlID0KKyAgICAgICAgKFRlc3RBbGxFeHRlbnNpb25zKSBmaWVsZC5nZXRWYWx1ZShUZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgYXNzZXJ0VHJ1ZSh2YWx1ZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbnQzMkV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnZhbHVlT2YoMSksIHZhbHVlLmdldEV4dGVuc2lvbihvcHRpb25hbEludDMyRXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RmFsc2UodmFsdWUuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsSW50NjRFeHRlbnNpb24pKTsKKworICAgIC8vIFRoZSBmaWVsZCBpcyBzdGlsbCB0aGVyZSwgaXQgaXMganVzdCB1bmtub3duLgorICAgIGFzc2VydFRydWUodmFsdWUuZ2V0VW5rbm93bkZpZWxkcygpCisgICAgICAgIC5oYXNGaWVsZChvcHRpb25hbEludDY0RXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKS5nZXROdW1iZXIoKSkpOworICB9CisKKworICAvLyBIZWxwIG1ldGhvZHMuCisKKyAgcHJpdmF0ZSBMYXp5RmllbGRMaXRlIGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShNZXNzYWdlTGl0ZSBtZXNzYWdlKSB7CisgICAgcmV0dXJuIGNyZWF0ZUxhenlGaWVsZExpdGVGcm9tTWVzc2FnZShUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBtZXNzYWdlKTsKKyAgfQorCisgIHByaXZhdGUgTGF6eUZpZWxkTGl0ZSBjcmVhdGVMYXp5RmllbGRMaXRlRnJvbU1lc3NhZ2UoCisgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnksIE1lc3NhZ2VMaXRlIG1lc3NhZ2UpIHsKKyAgICBCeXRlU3RyaW5nIGJ5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICByZXR1cm4gbmV3IExhenlGaWVsZExpdGUoZXh0ZW5zaW9uUmVnaXN0cnksIGJ5dGVzKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBjaGFuZ2VWYWx1ZShMYXp5RmllbGRMaXRlIGxhenlGaWVsZCkgeworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0VXRpbC5nZXRBbGxTZXQoKS50b0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkQm9vbCh0cnVlKTsKKyAgICBNZXNzYWdlTGl0ZSBuZXdNZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGxhenlGaWVsZC5zZXRWYWx1ZShuZXdNZXNzYWdlKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnROb3RFcXVhbChPYmplY3QgdW5leHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgeworICAgIGFzc2VydEZhbHNlKHVuZXhwZWN0ZWQgPT0gYWN0dWFsCisgICAgICAgIHx8ICh1bmV4cGVjdGVkICE9IG51bGwgJiYgdW5leHBlY3RlZC5lcXVhbHMoYWN0dWFsKSkpOworICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlGaWVsZFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlGaWVsZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjkwMDA2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eUZpZWxkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFVuaXQgdGVzdCBmb3Ige0BsaW5rIExhenlGaWVsZH0uCisgKgorICogQGF1dGhvciB4aWFuZ2xAZ29vZ2xlLmNvbSAoWGlhbmcgTGkpCisgKi8KK3B1YmxpYyBjbGFzcyBMYXp5RmllbGRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7CisgICAgTWVzc2FnZUxpdGUgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIExhenlGaWVsZCBsYXp5RmllbGQgPQorICAgICAgICBjcmVhdGVMYXp5RmllbGRGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5oYXNoQ29kZSgpLCBsYXp5RmllbGQuaGFzaENvZGUoKSk7CisgICAgbGF6eUZpZWxkLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuaGFzaENvZGUoKSwgbGF6eUZpZWxkLmhhc2hDb2RlKCkpOworICAgIGNoYW5nZVZhbHVlKGxhenlGaWVsZCk7CisgICAgLy8gbWFrZSBzdXJlIHR3byBtZXNzYWdlcyBoYXZlIGRpZmZlcmVudCBoYXNoIGNvZGUKKyAgICBhc3NlcnROb3RFcXVhbChtZXNzYWdlLmhhc2hDb2RlKCksIGxhenlGaWVsZC5oYXNoQ29kZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RIYXNoQ29kZUV4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBMYXp5RmllbGQgbGF6eUZpZWxkID0gY3JlYXRlTGF6eUZpZWxkRnJvbU1lc3NhZ2UobWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuaGFzaENvZGUoKSwgbGF6eUZpZWxkLmhhc2hDb2RlKCkpOworICAgIGxhenlGaWVsZC5nZXRWYWx1ZSgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmhhc2hDb2RlKCksIGxhenlGaWVsZC5oYXNoQ29kZSgpKTsKKyAgICBjaGFuZ2VWYWx1ZShsYXp5RmllbGQpOworICAgIC8vIG1ha2Ugc3VyZSB0d28gbWVzc2FnZXMgaGF2ZSBkaWZmZXJlbnQgaGFzaCBjb2RlCisgICAgYXNzZXJ0Tm90RXF1YWwobWVzc2FnZS5oYXNoQ29kZSgpLCBsYXp5RmllbGQuaGFzaENvZGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWUoKSB7CisgICAgTWVzc2FnZUxpdGUgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbFNldCgpOworICAgIExhenlGaWVsZCBsYXp5RmllbGQgPSBjcmVhdGVMYXp5RmllbGRGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbGF6eUZpZWxkLmdldFZhbHVlKCkpOworICAgIGNoYW5nZVZhbHVlKGxhenlGaWVsZCk7CisgICAgYXNzZXJ0Tm90RXF1YWwobWVzc2FnZSwgbGF6eUZpZWxkLmdldFZhbHVlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldFZhbHVlRXgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsRXh0ZW5zaW9uc1NldCgpOworICAgIExhenlGaWVsZCBsYXp5RmllbGQgPSBjcmVhdGVMYXp5RmllbGRGcm9tTWVzc2FnZShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbGF6eUZpZWxkLmdldFZhbHVlKCkpOworICAgIGNoYW5nZVZhbHVlKGxhenlGaWVsZCk7CisgICAgYXNzZXJ0Tm90RXF1YWwobWVzc2FnZSwgbGF6eUZpZWxkLmdldFZhbHVlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVxdWFsc09iamVjdCgpIHsKKyAgICBNZXNzYWdlTGl0ZSBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsU2V0KCk7CisgICAgTGF6eUZpZWxkIGxhenlGaWVsZCA9IGNyZWF0ZUxhenlGaWVsZEZyb21NZXNzYWdlKG1lc3NhZ2UpOworICAgIGFzc2VydFRydWUobGF6eUZpZWxkLmVxdWFscyhtZXNzYWdlKSk7CisgICAgY2hhbmdlVmFsdWUobGF6eUZpZWxkKTsKKyAgICBhc3NlcnRGYWxzZShsYXp5RmllbGQuZXF1YWxzKG1lc3NhZ2UpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmVxdWFscyhsYXp5RmllbGQuZ2V0VmFsdWUoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVxdWFsc09iamVjdEV4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBMYXp5RmllbGQgbGF6eUZpZWxkID0gY3JlYXRlTGF6eUZpZWxkRnJvbU1lc3NhZ2UobWVzc2FnZSk7CisgICAgYXNzZXJ0VHJ1ZShsYXp5RmllbGQuZXF1YWxzKG1lc3NhZ2UpKTsKKyAgICBjaGFuZ2VWYWx1ZShsYXp5RmllbGQpOworICAgIGFzc2VydEZhbHNlKGxhenlGaWVsZC5lcXVhbHMobWVzc2FnZSkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuZXF1YWxzKGxhenlGaWVsZC5nZXRWYWx1ZSgpKSk7CisgIH0KKworICAvLyBIZWxwIG1ldGhvZHMuCisKKyAgcHJpdmF0ZSBMYXp5RmllbGQgY3JlYXRlTGF6eUZpZWxkRnJvbU1lc3NhZ2UoTWVzc2FnZUxpdGUgbWVzc2FnZSkgeworICAgIEJ5dGVTdHJpbmcgYnl0ZXMgPSBtZXNzYWdlLnRvQnl0ZVN0cmluZygpOworICAgIHJldHVybiBuZXcgTGF6eUZpZWxkKG1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpLAorICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBieXRlcyk7CisgIH0KKworICBwcml2YXRlIHZvaWQgY2hhbmdlVmFsdWUoTGF6eUZpZWxkIGxhenlGaWVsZCkgeworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0VXRpbC5nZXRBbGxTZXQoKS50b0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkQm9vbCh0cnVlKTsKKyAgICBNZXNzYWdlTGl0ZSBuZXdNZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGxhenlGaWVsZC5zZXRWYWx1ZShuZXdNZXNzYWdlKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnROb3RFcXVhbChPYmplY3QgdW5leHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgeworICAgIGFzc2VydEZhbHNlKHVuZXhwZWN0ZWQgPT0gYWN0dWFsCisgICAgICAgIHx8ICh1bmV4cGVjdGVkICE9IG51bGwgJiYgdW5leHBlY3RlZC5lcXVhbHMoYWN0dWFsKSkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5TWVzc2FnZUxpdGVUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5TWVzc2FnZUxpdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWZlMGZmZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlNZXNzYWdlTGl0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDMwNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb247CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGU7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworLyoqCisgKiBVbml0IHRlc3QgZm9yIG1lc3NhZ2VzIHdpdGggbGF6eSBmaWVsZHMuCisgKgorICogQGF1dGhvciBuaXdhc2FraUBnb29nbGUuY29tIChOYW9raSBJd2FzYWtpKQorICovCitwdWJsaWMgY2xhc3MgTGF6eU1lc3NhZ2VMaXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICBwcml2YXRlIFBhcnNlcjxMYXp5SW5uZXJNZXNzYWdlTGl0ZT4gb3JpZ2luYWxMYXp5SW5uZXJNZXNzYWdlTGl0ZVBhcnNlcjsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIudGVhckRvd24oKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXRWYWx1ZXMoKSB7CisgICAgTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkID0gTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROdW0oMykKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSBMYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE51bSgyKQorICAgICAgICAuc2V0TmVzdGVkKG5lc3RlZCkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgTGF6eU1lc3NhZ2VMaXRlIG91dGVyID0gTGF6eU1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TnVtKDEpCisgICAgICAgIC5zZXRJbm5lcihpbm5lcikKKyAgICAgICAgLnNldE9uZW9mTnVtKDEyMykKKyAgICAgICAgLnNldE9uZW9mSW5uZXIoaW5uZXIpCisgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKDEsIG91dGVyLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIxLCBvdXRlci5nZXROdW1XaXRoRGVmYXVsdCgpKTsKKworICAgIGFzc2VydEVxdWFscygyLCBvdXRlci5nZXRJbm5lcigpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIsIG91dGVyLmdldElubmVyKCkuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgb3V0ZXIuZ2V0SW5uZXIoKS5nZXROZXN0ZWQoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIG91dGVyLmdldElubmVyKCkuZ2V0TmVzdGVkKCkuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisKKyAgICBhc3NlcnRGYWxzZShvdXRlci5oYXNPbmVvZk51bSgpKTsKKyAgICBhc3NlcnRUcnVlKG91dGVyLmhhc09uZW9mSW5uZXIoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMiwgb3V0ZXIuZ2V0T25lb2ZJbm5lcigpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIsIG91dGVyLmdldE9uZW9mSW5uZXIoKS5nZXROdW1XaXRoRGVmYXVsdCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgb3V0ZXIuZ2V0T25lb2ZJbm5lcigpLmdldE5lc3RlZCgpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNCwgb3V0ZXIuZ2V0T25lb2ZJbm5lcigpLmdldE5lc3RlZCgpLmdldE51bVdpdGhEZWZhdWx0KCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNldFJlcGVhdGVkVmFsdWVzKCkgeworICAgIExhenlNZXNzYWdlTGl0ZSBvdXRlciA9IExhenlNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE51bSgxKQorICAgICAgICAuYWRkUmVwZWF0ZWRJbm5lcihMYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkuc2V0TnVtKDExOSkpCisgICAgICAgIC5hZGRSZXBlYXRlZElubmVyKExhenlJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKS5zZXROdW0oMTIyKSkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRFcXVhbHMoMSwgb3V0ZXIuZ2V0TnVtKCkpOworICAgIGFzc2VydEVxdWFscygyLCBvdXRlci5nZXRSZXBlYXRlZElubmVyQ291bnQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExOSwgb3V0ZXIuZ2V0UmVwZWF0ZWRJbm5lcigwKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMiwgb3V0ZXIuZ2V0UmVwZWF0ZWRJbm5lcigxKS5nZXROdW0oKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QWRkQWxsKCkgeworICAgIEFycmF5TGlzdDxMYXp5SW5uZXJNZXNzYWdlTGl0ZT4gaW5uZXJzID0gbmV3IEFycmF5TGlzdDxMYXp5SW5uZXJNZXNzYWdlTGl0ZT4oKTsKKyAgICBpbnQgY291bnQgPSA0OworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSBMYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0TnVtKGkpCisgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICBpbm5lcnMuYWRkKGlubmVyKTsKKyAgICB9CisKKyAgICBMYXp5TWVzc2FnZUxpdGUgb3V0ZXIgPSBMYXp5TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5hZGRBbGxSZXBlYXRlZElubmVyKGlubmVycykKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKGNvdW50LCBvdXRlci5nZXRSZXBlYXRlZElubmVyQ291bnQoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMoaSwgb3V0ZXIuZ2V0UmVwZWF0ZWRJbm5lcihpKS5nZXROdW0oKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldERlZmF1bHRWYWx1ZXMoKSB7CisgICAgTGF6eU1lc3NhZ2VMaXRlIG91dGVyID0gTGF6eU1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscygwLCBvdXRlci5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQyMSwgb3V0ZXIuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMCwgb3V0ZXIuZ2V0SW5uZXIoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQyLCBvdXRlci5nZXRJbm5lcigpLmdldE51bVdpdGhEZWZhdWx0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyLmdldElubmVyKCkuZ2V0TmVzdGVkKCkuZ2V0TnVtKCkpOworICAgIGFzc2VydEVxdWFscyg0LCBvdXRlci5nZXRJbm5lcigpLmdldE5lc3RlZCgpLmdldE51bVdpdGhEZWZhdWx0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyLmdldE9uZW9mTnVtKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyLmdldE9uZW9mSW5uZXIoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQyLCBvdXRlci5nZXRPbmVvZklubmVyKCkuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyLmdldE9uZW9mSW5uZXIoKS5nZXROZXN0ZWQoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIG91dGVyLmdldE9uZW9mSW5uZXIoKS5nZXROZXN0ZWQoKS5nZXROdW1XaXRoRGVmYXVsdCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhclZhbHVlcygpIHsKKyAgICBMYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lciA9IExhenlJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TnVtKDExNSkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMYXp5TWVzc2FnZUxpdGUuQnVpbGRlciBvdXRlckJ1aWxkZXIgPSBMYXp5TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyQnVpbGRlci5idWlsZCgpLmdldE51bSgpKTsKKworCisgICAgLy8gU2V0L0NsZWFyIG51bQorICAgIG91dGVyQnVpbGRlci5zZXROdW0oMTAwKTsKKworICAgIGFzc2VydEVxdWFscygxMDAsIG91dGVyQnVpbGRlci5idWlsZCgpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIxLCBvdXRlckJ1aWxkZXIuYnVpbGQoKS5nZXROdW1XaXRoRGVmYXVsdCgpKTsKKyAgICBhc3NlcnRGYWxzZShvdXRlckJ1aWxkZXIuYnVpbGQoKS5oYXNJbm5lcigpKTsKKworICAgIG91dGVyQnVpbGRlci5jbGVhck51bSgpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyQnVpbGRlci5idWlsZCgpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIxLCBvdXRlckJ1aWxkZXIuYnVpbGQoKS5nZXROdW1XaXRoRGVmYXVsdCgpKTsKKyAgICBhc3NlcnRGYWxzZShvdXRlckJ1aWxkZXIuYnVpbGQoKS5oYXNJbm5lcigpKTsKKworCisgICAgLy8gU2V0L0NsZWFyIGFsbAorICAgIG91dGVyQnVpbGRlci5zZXROdW0oMTAwKQorICAgICAgICAuc2V0SW5uZXIoaW5uZXIpCisgICAgICAgIC5hZGRSZXBlYXRlZElubmVyKExhenlJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKS5zZXROdW0oMTE5KSkKKyAgICAgICAgLmFkZFJlcGVhdGVkSW5uZXIoTGF6eUlubmVyTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpLnNldE51bSgxMjIpKQorICAgICAgICAuc2V0T25lb2ZJbm5lcihMYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkuc2V0TnVtKDEyMykpOworCisgICAgTGF6eU1lc3NhZ2VMaXRlIG91dGVyID0gb3V0ZXJCdWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEwMCwgb3V0ZXIuZ2V0TnVtKCkpOworICAgIGFzc2VydEVxdWFscyg0MjEsIG91dGVyLmdldE51bVdpdGhEZWZhdWx0KCkpOworICAgIGFzc2VydFRydWUob3V0ZXIuaGFzSW5uZXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExNSwgb3V0ZXIuZ2V0SW5uZXIoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG91dGVyLmdldFJlcGVhdGVkSW5uZXJDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTE5LCBvdXRlci5nZXRSZXBlYXRlZElubmVyKDApLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIyLCBvdXRlci5nZXRSZXBlYXRlZElubmVyKDEpLmdldE51bSgpKTsKKyAgICBhc3NlcnRUcnVlKG91dGVyLmhhc09uZW9mSW5uZXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgb3V0ZXIuZ2V0T25lb2ZJbm5lcigpLmdldE51bSgpKTsKKworICAgIG91dGVyQnVpbGRlci5jbGVhcigpOworCisgICAgb3V0ZXIgPSBvdXRlckJ1aWxkZXIuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscygwLCBvdXRlci5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQyMSwgb3V0ZXIuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisgICAgYXNzZXJ0RmFsc2Uob3V0ZXIuaGFzSW5uZXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG91dGVyLmdldFJlcGVhdGVkSW5uZXJDb3VudCgpKTsKKyAgICBhc3NlcnRGYWxzZShvdXRlci5oYXNPbmVvZklubmVyKCkpOworICAgIGFzc2VydEVxdWFscygwLCBvdXRlci5nZXRPbmVvZklubmVyKCkuZ2V0TnVtKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlVmFsdWVzKCkgeworICAgIExhenlNZXNzYWdlTGl0ZSBvdXRlckJhc2UgPSBMYXp5TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROdW1XaXRoRGVmYXVsdCgxMjIpCisgICAgICAgIC5idWlsZCgpOworCisgICAgTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXJNZXJnaW5nID0gTGF6eUlubmVyTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROdW0oMTE1KQorICAgICAgICAuYnVpbGQoKTsKKyAgICBMYXp5TWVzc2FnZUxpdGUgb3V0ZXJNZXJnaW5nID0gTGF6eU1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TnVtKDExOSkKKyAgICAgICAgLnNldElubmVyKGlubmVyTWVyZ2luZykKKyAgICAgICAgLnNldE9uZW9mSW5uZXIoaW5uZXJNZXJnaW5nKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIExhenlNZXNzYWdlTGl0ZSBtZXJnZWQgPSBMYXp5TWVzc2FnZUxpdGUKKyAgICAgICAgLm5ld0J1aWxkZXIob3V0ZXJCYXNlKQorICAgICAgICAubWVyZ2VGcm9tKG91dGVyTWVyZ2luZykKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDExOSwgbWVyZ2VkLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIyLCBtZXJnZWQuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExNSwgbWVyZ2VkLmdldElubmVyKCkuZ2V0TnVtKCkpOworICAgIGFzc2VydEVxdWFscyg0MiwgbWVyZ2VkLmdldElubmVyKCkuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExNSwgbWVyZ2VkLmdldE9uZW9mSW5uZXIoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQyLCBtZXJnZWQuZ2V0T25lb2ZJbm5lcigpLmdldE51bVdpdGhEZWZhdWx0KCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlRGVmYXVsdFZhbHVlcygpIHsKKyAgICBMYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lckJhc2UgPSBMYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE51bSgxMTUpCisgICAgICAgIC5idWlsZCgpOworICAgIExhenlNZXNzYWdlTGl0ZSBvdXRlckJhc2UgPSBMYXp5TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROdW0oMTE5KQorICAgICAgICAuc2V0TnVtV2l0aERlZmF1bHQoMTIyKQorICAgICAgICAuc2V0SW5uZXIoaW5uZXJCYXNlKQorICAgICAgICAuc2V0T25lb2ZJbm5lcihpbm5lckJhc2UpCisgICAgICAgIC5idWlsZCgpOworCisgICAgTGF6eU1lc3NhZ2VMaXRlIG91dGVyTWVyZ2luZyA9IExhenlNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMYXp5TWVzc2FnZUxpdGUgbWVyZ2VkID0gTGF6eU1lc3NhZ2VMaXRlCisgICAgICAgIC5uZXdCdWlsZGVyKG91dGVyQmFzZSkKKyAgICAgICAgLm1lcmdlRnJvbShvdXRlck1lcmdpbmcpCisgICAgICAgIC5idWlsZCgpOworICAgIC8vIE1lcmdpbmcgZGVmYXVsdC1pbnN0YW5jZSBzaG91bGRuJ3Qgb3ZlcndyaXRlIHZhbHVlcyBpbiB0aGUgYmFzZSBtZXNzYWdlLgorICAgIGFzc2VydEVxdWFscygxMTksIG1lcmdlZC5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMiwgbWVyZ2VkLmdldE51bVdpdGhEZWZhdWx0KCkpOworICAgIGFzc2VydEVxdWFscygxMTUsIG1lcmdlZC5nZXRJbm5lcigpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIsIG1lcmdlZC5nZXRJbm5lcigpLmdldE51bVdpdGhEZWZhdWx0KCkpOworICAgIGFzc2VydEVxdWFscygxMTUsIG1lcmdlZC5nZXRPbmVvZklubmVyKCkuZ2V0TnVtKCkpOworICAgIGFzc2VydEVxdWFscyg0MiwgbWVyZ2VkLmdldE9uZW9mSW5uZXIoKS5nZXROdW1XaXRoRGVmYXVsdCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemUoKSB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICBMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWQgPSBMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE51bSgzKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBMYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lciA9IExhenlJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TnVtKDIpCisgICAgICAgIC5zZXROZXN0ZWQobmVzdGVkKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBMYXp5TWVzc2FnZUxpdGUgb3V0ZXIgPSBMYXp5TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXROdW0oMSkKKyAgICAgICAgLnNldElubmVyKGlubmVyKQorICAgICAgICAuc2V0T25lb2ZJbm5lcihpbm5lcikKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBCeXRlU3RyaW5nIGJ5dGVzID0gb3V0ZXIudG9CeXRlU3RyaW5nKCk7CisgICAgYXNzZXJ0RXF1YWxzKGJ5dGVzLnNpemUoKSwgb3V0ZXIuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisKKyAgICBMYXp5TWVzc2FnZUxpdGUgZGVzZXJpYWxpemVkID0gTGF6eU1lc3NhZ2VMaXRlLnBhcnNlRnJvbShieXRlcyk7CisKKyAgICBhc3NlcnRFcXVhbHMoMSwgZGVzZXJpYWxpemVkLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIxLCAgZGVzZXJpYWxpemVkLmdldE51bVdpdGhEZWZhdWx0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDIsICBkZXNlcmlhbGl6ZWQuZ2V0SW5uZXIoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQyLCAgZGVzZXJpYWxpemVkLmdldElubmVyKCkuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgIGRlc2VyaWFsaXplZC5nZXRJbm5lcigpLmdldE5lc3RlZCgpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNCwgIGRlc2VyaWFsaXplZC5nZXRJbm5lcigpLmdldE5lc3RlZCgpLmdldE51bVdpdGhEZWZhdWx0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDIsICBkZXNlcmlhbGl6ZWQuZ2V0T25lb2ZJbm5lcigpLmdldE51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDIsICBkZXNlcmlhbGl6ZWQuZ2V0T25lb2ZJbm5lcigpLmdldE51bVdpdGhEZWZhdWx0KCkpOworICAgIGFzc2VydEVxdWFscygzLCAgZGVzZXJpYWxpemVkLmdldE9uZW9mSW5uZXIoKS5nZXROZXN0ZWQoKS5nZXROdW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsICBkZXNlcmlhbGl6ZWQuZ2V0T25lb2ZJbm5lcigpLmdldE5lc3RlZCgpLmdldE51bVdpdGhEZWZhdWx0KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKGJ5dGVzLCBkZXNlcmlhbGl6ZWQudG9CeXRlU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBMYXp5SW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyIGlubmVyQnVpbGRlciA9IExhenlJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKTsKKyAgICBpbm5lckJ1aWxkZXIuc2V0RXh0ZW5zaW9uKAorICAgICAgICBMYXp5RXh0ZW5zaW9uLmV4dGVuc2lvbiwgTGF6eUV4dGVuc2lvbi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE5hbWUoIm5hbWUiKS5idWlsZCgpKTsKKyAgICBhc3NlcnRUcnVlKGlubmVyQnVpbGRlci5oYXNFeHRlbnNpb24oTGF6eUV4dGVuc2lvbi5leHRlbnNpb24pKTsKKyAgICBhc3NlcnRFcXVhbHMoIm5hbWUiLCBpbm5lckJ1aWxkZXIuZ2V0RXh0ZW5zaW9uKExhenlFeHRlbnNpb24uZXh0ZW5zaW9uKS5nZXROYW1lKCkpOworCisgICAgTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXJNZXNzYWdlID0gaW5uZXJCdWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0VHJ1ZShpbm5lck1lc3NhZ2UuaGFzRXh0ZW5zaW9uKExhenlFeHRlbnNpb24uZXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgaW5uZXJNZXNzYWdlLmdldEV4dGVuc2lvbihMYXp5RXh0ZW5zaW9uLmV4dGVuc2lvbikuZ2V0TmFtZSgpKTsKKworICAgIExhenlNZXNzYWdlTGl0ZSBsaXRlID0gTGF6eU1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0SW5uZXIoaW5uZXJNZXNzYWdlKS5idWlsZCgpOworICAgIGFzc2VydFRydWUobGl0ZS5nZXRJbm5lcigpLmhhc0V4dGVuc2lvbihMYXp5RXh0ZW5zaW9uLmV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFscygibmFtZSIsIGxpdGUuZ2V0SW5uZXIoKS5nZXRFeHRlbnNpb24oTGF6eUV4dGVuc2lvbi5leHRlbnNpb24pLmdldE5hbWUoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdBcnJheUxpc3RUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5U3RyaW5nQXJyYXlMaXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzMDEyYjkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MYXp5U3RyaW5nQXJyYXlMaXN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBUZXN0cyBmb3Ige0BsaW5rIExhenlTdHJpbmdBcnJheUxpc3R9LgorICoKKyAqIEBhdXRob3Igam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorICovCitwdWJsaWMgY2xhc3MgTGF6eVN0cmluZ0FycmF5TGlzdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFNUUklOR19BID0gIkEiOworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgU1RSSU5HX0IgPSAiQiI7CisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBTVFJJTkdfQyA9ICJDIjsKKworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIEJZVEVfU1RSSU5HX0EgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiQSIpOworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIEJZVEVfU1RSSU5HX0IgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiQiIpOworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIEJZVEVfU1RSSU5HX0MgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiQyIpOworCisgIHB1YmxpYyB2b2lkIHRlc3RKdXN0U3RyaW5ncygpIHsKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QgPSBuZXcgTGF6eVN0cmluZ0FycmF5TGlzdCgpOworICAgIGxpc3QuYWRkKFNUUklOR19BKTsKKyAgICBsaXN0LmFkZChTVFJJTkdfQik7CisgICAgbGlzdC5hZGQoU1RSSU5HX0MpOworCisgICAgYXNzZXJ0RXF1YWxzKDMsIGxpc3Quc2l6ZSgpKTsKKyAgICBhc3NlcnRTYW1lKFNUUklOR19BLCBsaXN0LmdldCgwKSk7CisgICAgYXNzZXJ0U2FtZShTVFJJTkdfQiwgbGlzdC5nZXQoMSkpOworICAgIGFzc2VydFNhbWUoU1RSSU5HX0MsIGxpc3QuZ2V0KDIpKTsKKworICAgIGxpc3Quc2V0KDEsIFNUUklOR19DKTsKKyAgICBhc3NlcnRTYW1lKFNUUklOR19DLCBsaXN0LmdldCgxKSk7CisKKyAgICBsaXN0LnJlbW92ZSgxKTsKKyAgICBhc3NlcnRTYW1lKFNUUklOR19BLCBsaXN0LmdldCgwKSk7CisgICAgYXNzZXJ0U2FtZShTVFJJTkdfQywgbGlzdC5nZXQoMSkpOworCisgICAgTGlzdDxCeXRlU3RyaW5nPiBieXRlU3RyaW5nTGlzdCA9IGxpc3QuYXNCeXRlU3RyaW5nTGlzdCgpOworICAgIGFzc2VydEVxdWFscyhCWVRFX1NUUklOR19BLCBieXRlU3RyaW5nTGlzdC5nZXQoMCkpOworICAgIGFzc2VydEVxdWFscyhCWVRFX1NUUklOR19DLCBieXRlU3RyaW5nTGlzdC5nZXQoMSkpOworCisgICAgLy8gVW5kZXJseWluZyBsaXN0IHNob3VsZCBiZSB0cmFuc2Zvcm1lZC4KKyAgICBhc3NlcnRTYW1lKGJ5dGVTdHJpbmdMaXN0LmdldCgwKSwgbGlzdC5nZXRCeXRlU3RyaW5nKDApKTsKKyAgICBhc3NlcnRTYW1lKGJ5dGVTdHJpbmdMaXN0LmdldCgxKSwgbGlzdC5nZXRCeXRlU3RyaW5nKDEpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RKdXN0Qnl0ZVN0cmluZygpIHsKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QgPSBuZXcgTGF6eVN0cmluZ0FycmF5TGlzdCgpOworICAgIGxpc3QuYWRkKEJZVEVfU1RSSU5HX0EpOworICAgIGxpc3QuYWRkKEJZVEVfU1RSSU5HX0IpOworICAgIGxpc3QuYWRkKEJZVEVfU1RSSU5HX0MpOworCisgICAgYXNzZXJ0RXF1YWxzKDMsIGxpc3Quc2l6ZSgpKTsKKyAgICBhc3NlcnRTYW1lKEJZVEVfU1RSSU5HX0EsIGxpc3QuZ2V0Qnl0ZVN0cmluZygwKSk7CisgICAgYXNzZXJ0U2FtZShCWVRFX1NUUklOR19CLCBsaXN0LmdldEJ5dGVTdHJpbmcoMSkpOworICAgIGFzc2VydFNhbWUoQllURV9TVFJJTkdfQywgbGlzdC5nZXRCeXRlU3RyaW5nKDIpKTsKKworICAgIGxpc3QucmVtb3ZlKDEpOworICAgIGFzc2VydFNhbWUoQllURV9TVFJJTkdfQSwgbGlzdC5nZXRCeXRlU3RyaW5nKDApKTsKKyAgICBhc3NlcnRTYW1lKEJZVEVfU1RSSU5HX0MsIGxpc3QuZ2V0Qnl0ZVN0cmluZygxKSk7CisKKyAgICBMaXN0PEJ5dGVTdHJpbmc+IGJ5dGVTdHJpbmdMaXN0ID0gbGlzdC5hc0J5dGVTdHJpbmdMaXN0KCk7CisgICAgYXNzZXJ0U2FtZShCWVRFX1NUUklOR19BLCBieXRlU3RyaW5nTGlzdC5nZXQoMCkpOworICAgIGFzc2VydFNhbWUoQllURV9TVFJJTkdfQywgYnl0ZVN0cmluZ0xpc3QuZ2V0KDEpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb252ZXJzaW9uQmFja0FuZEZvcnRoKCkgeworICAgIExhenlTdHJpbmdBcnJheUxpc3QgbGlzdCA9IG5ldyBMYXp5U3RyaW5nQXJyYXlMaXN0KCk7CisgICAgbGlzdC5hZGQoU1RSSU5HX0EpOworICAgIGxpc3QuYWRkKEJZVEVfU1RSSU5HX0IpOworICAgIGxpc3QuYWRkKEJZVEVfU1RSSU5HX0MpOworCisgICAgLy8gU3RyaW5nIGEgc2hvdWxkIGJlIHRoZSBzYW1lIGJlY2F1c2UgaXQgd2FzIG9yaWdpbmFsbHkgYSBzdHJpbmcKKyAgICBhc3NlcnRTYW1lKFNUUklOR19BLCBsaXN0LmdldCgwKSk7CisKKyAgICAvLyBTdHJpbmcgYiBhbmQgYyBzaG91bGQgYmUgZGlmZmVyZW50IGJlY2F1c2UgdGhlIHN0cmluZyBoYXMgdG8gYmUgY29tcHV0ZWQKKyAgICAvLyBmcm9tIHRoZSBCeXRlU3RyaW5nCisgICAgU3RyaW5nIGJQcmltZSA9IGxpc3QuZ2V0KDEpOworICAgIGFzc2VydE5vdFNhbWUoU1RSSU5HX0IsIGJQcmltZSk7CisgICAgYXNzZXJ0RXF1YWxzKFNUUklOR19CLCBiUHJpbWUpOworICAgIFN0cmluZyBjUHJpbWUgPSBsaXN0LmdldCgyKTsKKyAgICBhc3NlcnROb3RTYW1lKFNUUklOR19DLCBjUHJpbWUpOworICAgIGFzc2VydEVxdWFscyhTVFJJTkdfQywgY1ByaW1lKTsKKworICAgIC8vIFN0cmluZyBjIGFuZCBjIHNob3VsZCBzdGF5IHRoZSBzYW1lIG9uY2UgY2FjaGVkLgorICAgIGFzc2VydFNhbWUoYlByaW1lLCBsaXN0LmdldCgxKSk7CisgICAgYXNzZXJ0U2FtZShjUHJpbWUsIGxpc3QuZ2V0KDIpKTsKKworICAgIC8vIEJ5dGVTdHJpbmcgbmVlZHMgdG8gYmUgY29tcHV0ZWQgZnJvbSBzdHJpbmcgZm9yIGJvdGggYSBhbmQgYgorICAgIEJ5dGVTdHJpbmcgYVByaW1lQnl0ZVN0cmluZyA9IGxpc3QuZ2V0Qnl0ZVN0cmluZygwKTsKKyAgICBhc3NlcnRFcXVhbHMoQllURV9TVFJJTkdfQSwgYVByaW1lQnl0ZVN0cmluZyk7CisgICAgQnl0ZVN0cmluZyBiUHJpbWVCeXRlU3RyaW5nID0gbGlzdC5nZXRCeXRlU3RyaW5nKDEpOworICAgIGFzc2VydE5vdFNhbWUoQllURV9TVFJJTkdfQiwgYlByaW1lQnl0ZVN0cmluZyk7CisgICAgYXNzZXJ0RXF1YWxzKEJZVEVfU1RSSU5HX0IsIGxpc3QuZ2V0Qnl0ZVN0cmluZygxKSk7CisKKyAgICAvLyBPbmNlIGNhY2hlZCwgQnl0ZVN0cmluZyBzaG91bGQgc3RheSBjYWNoZWQuCisgICAgYXNzZXJ0U2FtZShhUHJpbWVCeXRlU3RyaW5nLCBsaXN0LmdldEJ5dGVTdHJpbmcoMCkpOworICAgIGFzc2VydFNhbWUoYlByaW1lQnl0ZVN0cmluZywgbGlzdC5nZXRCeXRlU3RyaW5nKDEpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5Q29uc3RydWN0b3JDb3BpZXNCeVJlZmVyZW5jZSgpIHsKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QxID0gbmV3IExhenlTdHJpbmdBcnJheUxpc3QoKTsKKyAgICBsaXN0MS5hZGQoU1RSSU5HX0EpOworICAgIGxpc3QxLmFkZChCWVRFX1NUUklOR19CKTsKKyAgICBsaXN0MS5hZGQoQllURV9TVFJJTkdfQyk7CisKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QyID0gbmV3IExhenlTdHJpbmdBcnJheUxpc3QobGlzdDEpOworICAgIGFzc2VydEVxdWFscygzLCBsaXN0Mi5zaXplKCkpOworICAgIGFzc2VydFNhbWUoU1RSSU5HX0EsIGxpc3QyLmdldCgwKSk7CisgICAgYXNzZXJ0U2FtZShCWVRFX1NUUklOR19CLCBsaXN0Mi5nZXRCeXRlU3RyaW5nKDEpKTsKKyAgICBhc3NlcnRTYW1lKEJZVEVfU1RSSU5HX0MsIGxpc3QyLmdldEJ5dGVTdHJpbmcoMikpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdExpc3RDb3B5Q29uc3RydWN0b3IoKSB7CisgICAgTGlzdDxTdHJpbmc+IGxpc3QxID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgbGlzdDEuYWRkKFNUUklOR19BKTsKKyAgICBsaXN0MS5hZGQoU1RSSU5HX0IpOworICAgIGxpc3QxLmFkZChTVFJJTkdfQyk7CisKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QyID0gbmV3IExhenlTdHJpbmdBcnJheUxpc3QobGlzdDEpOworICAgIGFzc2VydEVxdWFscygzLCBsaXN0Mi5zaXplKCkpOworICAgIGFzc2VydFNhbWUoU1RSSU5HX0EsIGxpc3QyLmdldCgwKSk7CisgICAgYXNzZXJ0U2FtZShTVFJJTkdfQiwgbGlzdDIuZ2V0KDEpKTsKKyAgICBhc3NlcnRTYW1lKFNUUklOR19DLCBsaXN0Mi5nZXQoMikpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEFkZEFsbENvcGllc0J5UmVmZXJlbmNlSWZQb3NzaWJsZSgpIHsKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QxID0gbmV3IExhenlTdHJpbmdBcnJheUxpc3QoKTsKKyAgICBsaXN0MS5hZGQoU1RSSU5HX0EpOworICAgIGxpc3QxLmFkZChCWVRFX1NUUklOR19CKTsKKyAgICBsaXN0MS5hZGQoQllURV9TVFJJTkdfQyk7CisKKyAgICBMYXp5U3RyaW5nQXJyYXlMaXN0IGxpc3QyID0gbmV3IExhenlTdHJpbmdBcnJheUxpc3QoKTsKKyAgICBsaXN0Mi5hZGRBbGwobGlzdDEpOworCisgICAgYXNzZXJ0RXF1YWxzKDMsIGxpc3QyLnNpemUoKSk7CisgICAgYXNzZXJ0U2FtZShTVFJJTkdfQSwgbGlzdDIuZ2V0KDApKTsKKyAgICBhc3NlcnRTYW1lKEJZVEVfU1RSSU5HX0IsIGxpc3QyLmdldEJ5dGVTdHJpbmcoMSkpOworICAgIGFzc2VydFNhbWUoQllURV9TVFJJTkdfQywgbGlzdDIuZ2V0Qnl0ZVN0cmluZygyKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdFbmRUb0VuZFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xhenlTdHJpbmdFbmRUb0VuZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2QxODAwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGF6eVN0cmluZ0VuZFRvRW5kVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCisKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyB0byBtYWtlIHN1cmUgdGhlIGxhenkgY29udmVyc2lvbiBvZiBVVEY4LWVuY29kZWQgYnl0ZSBhcnJheXMgdG8KKyAqIHN0cmluZ3Mgd29ya3MgY29ycmVjdGx5LgorICoKKyAqIEBhdXRob3Igam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorICovCitwdWJsaWMgY2xhc3MgTGF6eVN0cmluZ0VuZFRvRW5kVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIFRFU1RfQUxMX1RZUEVTX1NFUklBTElaRURfV0lUSF9JTExFR0FMX1VURjggPQorICAgICAgQnl0ZVN0cmluZy5jb3B5RnJvbShuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAxMTQsIDQsIC0xLCAwLCAtMSwgMCwgLTMwLCAyLCA0LCAtMSwKKyAgICAgICAgICAwLCAtMSwgMCwgLTMwLCAyLCA0LCAtMSwgMCwgLTEsIDAsIH0pOworCisgIHByaXZhdGUgQnl0ZVN0cmluZyBlbmNvZGVkVGVzdEFsbFR5cGVzOworCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisgICAgdGhpcy5lbmNvZGVkVGVzdEFsbFR5cGVzID0gVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiZm9vIikKKyAgICAgICAgLmFkZFJlcGVhdGVkU3RyaW5nKCJiYXIiKQorICAgICAgICAuYWRkUmVwZWF0ZWRTdHJpbmcoImJheiIpCisgICAgICAgIC5idWlsZCgpCisgICAgICAgIC50b0J5dGVTdHJpbmcoKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyB0aGF0IGFuIGludmFsaWQgVVRGOCBzdHJpbmcgd2lsbCByb3VuZHRyaXAgdGhyb3VnaCBhIHBhcnNlCisgICAqIGFuZCBzZXJpYWxpemF0aW9uLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlQW5kU2VyaWFsaXplKCkgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdFYyID0gVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMucGFyc2VGcm9tKAorICAgICAgICBURVNUX0FMTF9UWVBFU19TRVJJQUxJWkVEX1dJVEhfSUxMRUdBTF9VVEY4KTsKKyAgICBCeXRlU3RyaW5nIGJ5dGVzID0gdFYyLnRvQnl0ZVN0cmluZygpOworICAgIGFzc2VydEVxdWFscyhURVNUX0FMTF9UWVBFU19TRVJJQUxJWkVEX1dJVEhfSUxMRUdBTF9VVEY4LCBieXRlcyk7CisKKyAgICB0VjIuZ2V0T3B0aW9uYWxTdHJpbmcoKTsKKyAgICBieXRlcyA9IHRWMi50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRFcXVhbHMoVEVTVF9BTExfVFlQRVNfU0VSSUFMSVpFRF9XSVRIX0lMTEVHQUxfVVRGOCwgYnl0ZXMpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlQW5kV3JpdGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHRWMiA9IFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLnBhcnNlRnJvbSgKKyAgICAgICAgVEVTVF9BTExfVFlQRVNfU0VSSUFMSVpFRF9XSVRIX0lMTEVHQUxfVVRGOCk7CisgICAgYnl0ZVtdIHNpbmsgPSBuZXcgYnl0ZVtURVNUX0FMTF9UWVBFU19TRVJJQUxJWkVEX1dJVEhfSUxMRUdBTF9VVEY4LnNpemUoKV07CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2Uoc2luayk7CisgICAgdFYyLndyaXRlVG8ob3V0cHV0U3RyZWFtKTsKKyAgICBvdXRwdXRTdHJlYW0uZmx1c2goKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIFRFU1RfQUxMX1RZUEVTX1NFUklBTElaRURfV0lUSF9JTExFR0FMX1VURjgsCisgICAgICAgIEJ5dGVTdHJpbmcuY29weUZyb20oc2luaykpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENhY2hpbmcoKSB7CisgICAgU3RyaW5nIGEgPSAiYSI7CisgICAgU3RyaW5nIGIgPSAiYiI7CisgICAgU3RyaW5nIGMgPSAiYyI7CisgICAgVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcHJvdG8gPSBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKGEpCisgICAgICAgIC5hZGRSZXBlYXRlZFN0cmluZyhiKQorICAgICAgICAuYWRkUmVwZWF0ZWRTdHJpbmcoYykKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBTdHJpbmcgc2hvdWxkIGJlIHRoZSBvbmUgd2UgcGFzc2VkIGl0LgorICAgIGFzc2VydFNhbWUoYSwgcHJvdG8uZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgICAgYXNzZXJ0U2FtZShiLCBwcm90by5nZXRSZXBlYXRlZFN0cmluZygwKSk7CisgICAgYXNzZXJ0U2FtZShjLCBwcm90by5nZXRSZXBlYXRlZFN0cmluZygxKSk7CisKKworICAgIC8vIFRoZXJlJ3Mgbm8gd2F5IHRvIGRpcmVjdGx5IG9ic2VydmUgdGhhdCB0aGUgQnl0ZVN0cmluZyBpcyBjYWNoZWQKKyAgICAvLyBjb3JyZWN0bHkgb24gc2VyaWFsaXphdGlvbiwgYnV0IHdlIGNhbiBvYnNlcnZlIHRoYXQgaXQgaGFkIHRvIHJlY29tcHV0ZQorICAgIC8vIHRoZSBzdHJpbmcgYWZ0ZXIgc2VyaWFsaXphdGlvbi4KKyAgICBwcm90by50b0J5dGVTdHJpbmcoKTsKKyAgICBTdHJpbmcgYVByaW1lID0gcHJvdG8uZ2V0T3B0aW9uYWxTdHJpbmcoKTsKKyAgICBhc3NlcnROb3RTYW1lKGEsIGFQcmltZSk7CisgICAgYXNzZXJ0RXF1YWxzKGEsIGFQcmltZSk7CisgICAgU3RyaW5nIGJQcmltZSA9IHByb3RvLmdldFJlcGVhdGVkU3RyaW5nKDApOworICAgIGFzc2VydE5vdFNhbWUoYiwgYlByaW1lKTsKKyAgICBhc3NlcnRFcXVhbHMoYiwgYlByaW1lKTsKKyAgICBTdHJpbmcgY1ByaW1lID0gcHJvdG8uZ2V0UmVwZWF0ZWRTdHJpbmcoMSk7CisgICAgYXNzZXJ0Tm90U2FtZShjLCBjUHJpbWUpOworICAgIGFzc2VydEVxdWFscyhjLCBjUHJpbWUpOworCisgICAgLy8gQW5kIG5vdyB0aGUgc3RyaW5nIHNob3VsZCBzdGF5IGNhY2hlZC4KKyAgICBhc3NlcnRTYW1lKGFQcmltZSwgcHJvdG8uZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgICAgYXNzZXJ0U2FtZShiUHJpbWUsIHByb3RvLmdldFJlcGVhdGVkU3RyaW5nKDApKTsKKyAgICBhc3NlcnRTYW1lKGNQcmltZSwgcHJvdG8uZ2V0UmVwZWF0ZWRTdHJpbmcoMSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5vU3RyaW5nQ2FjaGluZ0lmT25seUJ5dGVzQWNjZXNzZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwcm90byA9CisgICAgICAgIFVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShlbmNvZGVkVGVzdEFsbFR5cGVzKTsKKyAgICBCeXRlU3RyaW5nIG9wdGlvbmFsID0gcHJvdG8uZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpOworICAgIGFzc2VydFNhbWUob3B0aW9uYWwsIHByb3RvLmdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKSk7CisgICAgYXNzZXJ0U2FtZShvcHRpb25hbCwgcHJvdG8udG9CdWlsZGVyKCkuZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpKTsKKworICAgIEJ5dGVTdHJpbmcgcmVwZWF0ZWQwID0gcHJvdG8uZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcygwKTsKKyAgICBCeXRlU3RyaW5nIHJlcGVhdGVkMSA9IHByb3RvLmdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoMSk7CisgICAgYXNzZXJ0U2FtZShyZXBlYXRlZDAsIHByb3RvLmdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoMCkpOworICAgIGFzc2VydFNhbWUocmVwZWF0ZWQxLCBwcm90by5nZXRSZXBlYXRlZFN0cmluZ0J5dGVzKDEpKTsKKyAgICBhc3NlcnRTYW1lKHJlcGVhdGVkMCwgcHJvdG8udG9CdWlsZGVyKCkuZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcygwKSk7CisgICAgYXNzZXJ0U2FtZShyZXBlYXRlZDEsIHByb3RvLnRvQnVpbGRlcigpLmdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoMSkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MaXRlRXF1YWxzQW5kSGFzaFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xpdGVFcXVhbHNBbmRIYXNoVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNTkxN2MKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MaXRlRXF1YWxzQW5kSGFzaFRlc3QuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb287CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdCBnZW5lcmF0ZSBlcXVhbCBhbmQgaGFzaCBtZXRob2RzIGZvciB0aGUgbGl0ZSBydW50aW1lLgorICoKKyAqIEBhdXRob3IgcGJvZ2xlQGdvb2dsZS5jb20gUGhpbCBCb2dsZQorICovCitwdWJsaWMgY2xhc3MgTGl0ZUVxdWFsc0FuZEhhc2hUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTaW5jZSB0aGUgZ2VuZXJhdGVkIGVxdWFscyBhbmQgaGFzaENvZGUgbWV0aG9kcyBmb3IgbGl0ZSBtZXNzYWdlcyBhcmUgYQorICAgIC8vIG1vc3RseSBjb21wbGV0ZSBzdWJzZXQgb2YgdGhvc2UgZm9yIHJlZ3VsYXIgbWVzc2FnZXMsIHdlIGNhbiBtb3N0bHkgYXNzdW1lCisgICAgLy8gdGhhdCB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMgYXJlIGFscmVhZHkgdGhvcm91Z2hseSB0ZXN0ZWQgYnkgdGhlIHJlZ3VsYXIgdGVzdHMuCisKKyAgICAvLyBUaGlzIHRlc3QgbW9zdGx5IGp1c3QgdmVyaWZpZXMgaXMgdGhhdCBhIHByb3RvIHdpdGgKKyAgICAvLyBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUgYW5kIGphdmFfZ2VuZXJhdGVzX2VxdWFsc19hbmRfaGFzaF9jb21waWxlcworICAgIC8vIGNvcnJlY3RseSB3aGVuIGxpbmtlZCBvbmx5IGFnYWluc3QgdGhlIGxpdGUgbGlicmFyeS4KKworICAgIC8vIFdlIGRvIGhvd2V2ZXIgZG8gc29tZSBiYXNpYyB0ZXN0aW5nIHRvIG1ha2Ugc3VyZSB0aGF0IGVxdWFscyBpcyBhY3R1YWxseQorICAgIC8vIG92ZXJyaWRlbiB0byB0ZXN0IGZvciB2YWx1ZSBlcXVhbGl0eSByYXRoZXIgdGhhbiBzaW1wbGUgb2JqZWN0IGVxdWFsaXR5LgorCisgICAgLy8gQ2hlY2sgdGhhdCB0d28gaWRlbnRpY2FsIG9ianMgYXJlIGVxdWFsLgorICAgIEZvbyBmb28xYSA9IEZvby5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldFZhbHVlKDEpCisgICAgICAgIC5hZGRCYXIoQmFyLm5ld0J1aWxkZXIoKS5zZXROYW1lKCJmb28xIikpCisgICAgICAgIC5idWlsZCgpOworICAgIEZvbyBmb28xYiA9IEZvby5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldFZhbHVlKDEpCisgICAgICAgIC5hZGRCYXIoQmFyLm5ld0J1aWxkZXIoKS5zZXROYW1lKCJmb28xIikpCisgICAgICAgIC5idWlsZCgpOworICAgIEZvbyBmb28yID0gRm9vLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0VmFsdWUoMSkKKyAgICAgICAgLmFkZEJhcihCYXIubmV3QnVpbGRlcigpLnNldE5hbWUoImZvbzIiKSkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDaGVjayB0aGF0IGVxdWFscyBpcyBkb2luZyB2YWx1ZSByYXRoZXIgdGhhbiBvYmplY3QgZXF1YWxpdHkuCisgICAgYXNzZXJ0RXF1YWxzKGZvbzFhLCBmb28xYik7CisgICAgYXNzZXJ0RXF1YWxzKGZvbzFhLmhhc2hDb2RlKCksIGZvbzFiLmhhc2hDb2RlKCkpOworCisgICAgLy8gQ2hlY2sgdGhhdCBhIGRpZmZlZW50IG9iamVjdCBpcyBub3QgZXF1YWwuCisgICAgYXNzZXJ0RmFsc2UoZm9vMWEuZXF1YWxzKGZvbzIpKTsKKworICAgIC8vIENoZWNrIHRoYXQgdHdvIG9iamVjdHMgd2hpY2ggaGF2ZSBkaWZmZXJlbnQgdHlwZXMgYnV0IHRoZSBzYW1lIGZpZWxkIHZhbHVlcyBhcmUgbm90CisgICAgLy8gY29uc2lkZXJlZCB0byBiZSBlcXVhbC4KKyAgICBCYXIgYmFyID0gQmFyLm5ld0J1aWxkZXIoKS5zZXROYW1lKCJiYXIiKS5idWlsZCgpOworICAgIEJhclByaW1lIGJhclByaW1lID0gQmFyUHJpbWUubmV3QnVpbGRlcigpLnNldE5hbWUoImJhciIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0RmFsc2UoYmFyLmVxdWFscyhiYXJQcmltZSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVxdWFsc0FuZEhhc2hDb2RlV2l0aFVua25vd25GaWVsZHMoKSB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICBGb28gZm9vV2l0aE9ubHlWYWx1ZSA9IEZvby5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldFZhbHVlKDEpCisgICAgICAgIC5idWlsZCgpOworCisgICAgRm9vIGZvb1dpdGhWYWx1ZUFuZEV4dGVuc2lvbiA9IGZvb1dpdGhPbmx5VmFsdWUudG9CdWlsZGVyKCkKKyAgICAgICAgLnNldFZhbHVlKDEpCisgICAgICAgIC5zZXRFeHRlbnNpb24oQmFyLmZvb0V4dCwgQmFyLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoIm5hbWUiKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgRm9vIGZvb1dpdGhWYWx1ZUFuZFVua25vd25GaWVsZHMgPSBGb28ucGFyc2VGcm9tKGZvb1dpdGhWYWx1ZUFuZEV4dGVuc2lvbi50b0J5dGVBcnJheSgpKTsKKworICAgIGFzc2VydEVxdWFsc0FuZEhhc2hDb2RlQXJlRmFsc2UoZm9vV2l0aE9ubHlWYWx1ZSwgZm9vV2l0aFZhbHVlQW5kVW5rbm93bkZpZWxkcyk7CisgICAgYXNzZXJ0RXF1YWxzQW5kSGFzaENvZGVBcmVGYWxzZShmb29XaXRoVmFsdWVBbmRFeHRlbnNpb24sIGZvb1dpdGhWYWx1ZUFuZFVua25vd25GaWVsZHMpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydEVxdWFsc0FuZEhhc2hDb2RlQXJlRmFsc2UoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKKyAgICBhc3NlcnRGYWxzZShvMS5lcXVhbHMobzIpKTsKKyAgICBhc3NlcnRGYWxzZShvMS5oYXNoQ29kZSgpID09IG8yLmhhc2hDb2RlKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9MaXRlVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGl0ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDgwMzdmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGl0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDE2MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLlRlc3RBbGxUeXBlc0xpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuVGVzdEFsbEV4dGVuc2lvbnNMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLlRlc3ROZXN0ZWRFeHRlbnNpb25MaXRlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworCisvKioKKyAqIFRlc3QgbGl0ZSBydW50aW1lLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBjbGFzcyBMaXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0IHRoYXQgbmVzdGVkIGV4dGVuc2lvbnMgYXJlIGluaXRpYWxpemVkIGNvcnJlY3RseSBldmVuIGlmIHRoZSBvdXRlcgorICAgIC8vIGNsYXNzIGhhcyBub3QgYmVlbiBhY2Nlc3NlZCBkaXJlY3RseS4gIFRoaXMgd2FzIG9uY2UgYSBidWcgd2l0aCBsaXRlCisgICAgLy8gbWVzc2FnZXMuCisgICAgLy8KKyAgICAvLyBXZSBwdXQgdGhpcyBpbiBzZXRVcCgpIHJhdGhlciB0aGFuIGluIGl0cyBvd24gdGVzdCBtZXRob2QgYmVjYXVzZSB3ZQorICAgIC8vIG5lZWQgdG8gbWFrZSBzdXJlIGl0IHJ1bnMgYmVmb3JlIGFueSBhY3R1YWwgdGVzdHMuCisgICAgYXNzZXJ0VHJ1ZShUZXN0TmVzdGVkRXh0ZW5zaW9uTGl0ZS5uZXN0ZWRFeHRlbnNpb24gIT0gbnVsbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TGl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNpbmNlIGxpdGUgbWVzc2FnZXMgYXJlIGEgc3Vic2V0IG9mIHJlZ3VsYXIgbWVzc2FnZXMsIHdlIGNhbiBtb3N0bHkKKyAgICAvLyBhc3N1bWUgdGhhdCB0aGUgZnVuY3Rpb25hbGl0eSBvZiBsaXRlIG1lc3NhZ2VzIGlzIGFscmVhZHkgdGhvcm91Z2hseQorICAgIC8vIHRlc3RlZCBieSB0aGUgcmVndWxhciB0ZXN0cy4gIEFsbCB0aGlzIHRlc3QgcmVhbGx5IHZlcmlmaWVzIGlzIHRoYXQKKyAgICAvLyBhIHByb3RvIHdpdGggb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FIGNvbXBpbGVzIGNvcnJlY3RseSB3aGVuCisgICAgLy8gbGlua2VkIG9ubHkgYWdhaW5zdCB0aGUgbGl0ZSBsaWJyYXJ5LiAgVGhhdCBpcyBhbGwgdGVzdGVkIGF0IGNvbXBpbGUKKyAgICAvLyB0aW1lLCBsZWF2aW5nIG5vdCBtdWNoIHRvIGRvIGluIHRoaXMgbWV0aG9kLiAgTGV0J3MganVzdCBkbyBzb21lIHJhbmRvbQorICAgIC8vIHN0dWZmIHRvIG1ha2Ugc3VyZSB0aGUgbGl0ZSBtZXNzYWdlIGlzIGFjdHVhbGx5IGhlcmUgYW5kIHVzYWJsZS4KKworICAgIFRlc3RBbGxUeXBlc0xpdGUgbWVzc2FnZSA9CisgICAgICBUZXN0QWxsVHlwZXNMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgIC5zZXRPcHRpb25hbEludDMyKDEyMykKKyAgICAgICAgICAgICAgICAgICAgICAuYWRkUmVwZWF0ZWRTdHJpbmcoImhlbGxvIikKKyAgICAgICAgICAgICAgICAgICAgICAuc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDcpKQorICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgQnl0ZVN0cmluZyBkYXRhID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKworICAgIFRlc3RBbGxUeXBlc0xpdGUgbWVzc2FnZTIgPSBUZXN0QWxsVHlwZXNMaXRlLnBhcnNlRnJvbShkYXRhKTsKKworICAgIGFzc2VydEVxdWFscygxMjMsIG1lc3NhZ2UyLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1lc3NhZ2UyLmdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIG1lc3NhZ2UyLmdldFJlcGVhdGVkU3RyaW5nKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoNywgbWVzc2FnZTIuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuZ2V0QmIoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TGl0ZUV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBVbmxpa2Ugb3RoZXIgZmVhdHVyZXMgb2YgdGhlIGxpdGUgbGlicmFyeSwgZXh0ZW5zaW9ucyBhcmUKKyAgICAvLyAgIGltcGxlbWVudGVkIGNvbXBsZXRlbHkgZGlmZmVyZW50bHkgZnJvbSB0aGUgcmVndWxhciBsaWJyYXJ5LiAgV2UKKyAgICAvLyAgIHNob3VsZCBwcm9iYWJseSB0ZXN0IHRoZW0gbW9yZSB0aG9yb3VnaGx5LgorCisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UgPQorICAgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5vcHRpb25hbEludDMyRXh0ZW5zaW9uTGl0ZSwgMTIzKQorICAgICAgICAuYWRkRXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5yZXBlYXRlZFN0cmluZ0V4dGVuc2lvbkxpdGUsICJoZWxsbyIpCisgICAgICAgIC5zZXRFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbkxpdGUsCisgICAgICAgICAgICBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uQkFaKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKFVuaXR0ZXN0TGl0ZS5vcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb25MaXRlLAorICAgICAgICAgICAgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYig3KS5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFRlc3QgY29weWluZyBhIG1lc3NhZ2UsIHNpbmNlIGNvcGluZyBleHRlbnNpb25zIGFjdHVhbGx5IGRvZXMgdXNlIGEKKyAgICAvLyBkaWZmZXJlbnQgY29kZSBwYXRoIGJldHdlZW4gbGl0ZSBhbmQgcmVndWxhciBsaWJyYXJpZXMsIGFuZCBhcyBvZiB0aGlzCisgICAgLy8gd3JpdGluZywgcGFyc2luZyBoYXNuJ3QgYmVlbiBpbXBsZW1lbnRlZCB5ZXQuCisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UyID0gbWVzc2FnZS50b0J1aWxkZXIoKS5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKDEyMywgKGludCkgbWVzc2FnZTIuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBVbml0dGVzdExpdGUub3B0aW9uYWxJbnQzMkV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbWVzc2FnZTIuZ2V0RXh0ZW5zaW9uQ291bnQoCisgICAgICAgIFVuaXR0ZXN0TGl0ZS5yZXBlYXRlZFN0cmluZ0V4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbWVzc2FnZTIuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBVbml0dGVzdExpdGUucmVwZWF0ZWRTdHJpbmdFeHRlbnNpb25MaXRlKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygiaGVsbG8iLCBtZXNzYWdlMi5nZXRFeHRlbnNpb24oCisgICAgICAgIFVuaXR0ZXN0TGl0ZS5yZXBlYXRlZFN0cmluZ0V4dGVuc2lvbkxpdGUsIDApKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRFbnVtLkJBWiwgbWVzc2FnZTIuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBVbml0dGVzdExpdGUub3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSkpOworICAgIGFzc2VydEVxdWFscyg3LCBtZXNzYWdlMi5nZXRFeHRlbnNpb24oCisgICAgICAgIFVuaXR0ZXN0TGl0ZS5vcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb25MaXRlKS5nZXRCYigpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBUZXN0QWxsVHlwZXNMaXRlIGV4cGVjdGVkID0KKyAgICAgIFRlc3RBbGxUeXBlc0xpdGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMTIzKQorICAgICAgICAgICAgICAgICAgICAgIC5hZGRSZXBlYXRlZFN0cmluZygiaGVsbG8iKQorICAgICAgICAgICAgICAgICAgICAgIC5zZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoNykpCisgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgdHJ5IHsKKyAgICAgIG91dC53cml0ZU9iamVjdChleHBlY3RlZCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIG91dC5jbG9zZSgpOworICAgIH0KKyAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSk7CisgICAgT2JqZWN0SW5wdXRTdHJlYW0gaW4gPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oYmFpcyk7CisgICAgVGVzdEFsbFR5cGVzTGl0ZSBhY3R1YWwgPSAoVGVzdEFsbFR5cGVzTGl0ZSkgaW4ucmVhZE9iamVjdCgpOworICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5nZXRPcHRpb25hbEludDMyKCksIGFjdHVhbC5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5nZXRSZXBlYXRlZFN0cmluZ0NvdW50KCksCisgICAgICAgIGFjdHVhbC5nZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkpOworICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5nZXRSZXBlYXRlZFN0cmluZygwKSwKKyAgICAgICAgYWN0dWFsLmdldFJlcGVhdGVkU3RyaW5nKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuZ2V0QmIoKSwKKyAgICAgICAgYWN0dWFsLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmdldEJiKCkpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgVGVzdEFsbFR5cGVzTGl0ZS5CdWlsZGVyIGV4cGVjdGVkID0gVGVzdEFsbFR5cGVzTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMTIzKTsKKyAgIGFzc2VydEVxdWFscygKKyAgICAgICBleHBlY3RlZC5nZXRPcHRpb25hbEludDMyKCksIGV4cGVjdGVkLmNsb25lKCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgIAorICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLkJ1aWxkZXIgZXhwZWN0ZWQyID0gVGVzdEFsbEV4dGVuc2lvbnNMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgIC5zZXRFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlLCAxMjMpOworICAgYXNzZXJ0RXF1YWxzKAorICAgICAgIGV4cGVjdGVkMi5nZXRFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlKSwKKyAgICAgICBleHBlY3RlZDIuY2xvbmUoKS5nZXRFeHRlbnNpb24oVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xpdGVyYWxCeXRlU3RyaW5nVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ2ODMyZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL0xpdGVyYWxCeXRlU3RyaW5nVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCisvKioKKyAqIFRlc3Qge0BsaW5rIExpdGVyYWxCeXRlU3RyaW5nfSBieSBzZXR0aW5nIHVwIGEgcmVmZXJlbmNlIHN0cmluZyBpbiB7QGxpbmsgI3NldFVwKCl9LgorICogVGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byBiZSBleHRlbmRlZCBmb3IgdGVzdGluZyBleHRlbnNpb25zIG9mIHtAbGluayBMaXRlcmFsQnl0ZVN0cmluZ30KKyAqIHN1Y2ggYXMge0BsaW5rIEJvdW5kZWRCeXRlU3RyaW5nfSwgc2VlIHtAbGluayBCb3VuZGVkQnl0ZVN0cmluZ1Rlc3R9LgorICoKKyAqIEBhdXRob3IgY2FybGFudG9uQGdvb2dsZS5jb20gKENhcmwgSGF2ZXJsKQorICovCitwdWJsaWMgY2xhc3MgTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBVVEZfOCA9ICJVVEYtOCI7CisKKyAgcHJvdGVjdGVkIFN0cmluZyBjbGFzc1VuZGVyVGVzdDsKKyAgcHJvdGVjdGVkIGJ5dGVbXSByZWZlcmVuY2VCeXRlczsKKyAgcHJvdGVjdGVkIEJ5dGVTdHJpbmcgc3RyaW5nVW5kZXJUZXN0OworICBwcm90ZWN0ZWQgaW50IGV4cGVjdGVkSGFzaENvZGU7CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgY2xhc3NVbmRlclRlc3QgPSAiTGl0ZXJhbEJ5dGVTdHJpbmciOworICAgIHJlZmVyZW5jZUJ5dGVzID0gQnl0ZVN0cmluZ1Rlc3QuZ2V0VGVzdEJ5dGVzKDEyMzQsIDExMzM3NzY2TCk7CisgICAgc3RyaW5nVW5kZXJUZXN0ID0gQnl0ZVN0cmluZy5jb3B5RnJvbShyZWZlcmVuY2VCeXRlcyk7CisgICAgZXhwZWN0ZWRIYXNoQ29kZSA9IDMzMTE2MTg1MjsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFeHBlY3RlZFR5cGUoKSB7CisgICAgU3RyaW5nIGFjdHVhbENsYXNzTmFtZSA9IGdldEFjdHVhbENsYXNzTmFtZShzdHJpbmdVbmRlclRlc3QpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgc2hvdWxkIG1hdGNoIHR5cGUgZXhhY3RseSIsIGNsYXNzVW5kZXJUZXN0LCBhY3R1YWxDbGFzc05hbWUpOworICB9CisKKyAgcHJvdGVjdGVkIFN0cmluZyBnZXRBY3R1YWxDbGFzc05hbWUoT2JqZWN0IG9iamVjdCkgeworICAgIFN0cmluZyBhY3R1YWxDbGFzc05hbWUgPSBvYmplY3QuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7CisgICAgYWN0dWFsQ2xhc3NOYW1lID0gYWN0dWFsQ2xhc3NOYW1lLnN1YnN0cmluZyhhY3R1YWxDbGFzc05hbWUubGFzdEluZGV4T2YoJy4nKSArIDEpOworICAgIHJldHVybiBhY3R1YWxDbGFzc05hbWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZUF0KCkgeworICAgIGJvb2xlYW4gc3RpbGxFcXVhbCA9IHRydWU7CisgICAgZm9yIChpbnQgaSA9IDA7IHN0aWxsRXF1YWwgJiYgaSA8IHJlZmVyZW5jZUJ5dGVzLmxlbmd0aDsgKytpKSB7CisgICAgICBzdGlsbEVxdWFsID0gKHJlZmVyZW5jZUJ5dGVzW2ldID09IHN0cmluZ1VuZGVyVGVzdC5ieXRlQXQoaSkpOworICAgIH0KKyAgICBhc3NlcnRUcnVlKGNsYXNzVW5kZXJUZXN0ICsgIiBtdXN0IGNhcHR1cmUgdGhlIHJpZ2h0IGJ5dGVzIiwgc3RpbGxFcXVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZUl0ZXJhdG9yKCkgeworICAgIGJvb2xlYW4gc3RpbGxFcXVhbCA9IHRydWU7CisgICAgQnl0ZVN0cmluZy5CeXRlSXRlcmF0b3IgaXRlciA9IHN0cmluZ1VuZGVyVGVzdC5pdGVyYXRvcigpOworICAgIGZvciAoaW50IGkgPSAwOyBzdGlsbEVxdWFsICYmIGkgPCByZWZlcmVuY2VCeXRlcy5sZW5ndGg7ICsraSkgeworICAgICAgc3RpbGxFcXVhbCA9IChpdGVyLmhhc05leHQoKSAmJiByZWZlcmVuY2VCeXRlc1tpXSA9PSBpdGVyLm5leHRCeXRlKCkpOworICAgIH0KKyAgICBhc3NlcnRUcnVlKGNsYXNzVW5kZXJUZXN0ICsgIiBtdXN0IGNhcHR1cmUgdGhlIHJpZ2h0IGJ5dGVzIiwgc3RpbGxFcXVhbCk7CisgICAgYXNzZXJ0RmFsc2UoY2xhc3NVbmRlclRlc3QgKyAiIG11c3QgaGF2ZSBleGhhdXN0ZWQgdGhlIGl0ZXJ0b3IiLCBpdGVyLmhhc05leHQoKSk7CisKKyAgICB0cnkgeworICAgICAgaXRlci5uZXh0Qnl0ZSgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFRoaXMgaXMgc3VjY2VzcworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RCeXRlSXRlcmFibGUoKSB7CisgICAgYm9vbGVhbiBzdGlsbEVxdWFsID0gdHJ1ZTsKKyAgICBpbnQgaiA9IDA7CisgICAgZm9yIChieXRlIHF1YW50dW0gOiBzdHJpbmdVbmRlclRlc3QpIHsKKyAgICAgIHN0aWxsRXF1YWwgPSAocmVmZXJlbmNlQnl0ZXNbal0gPT0gcXVhbnR1bSk7CisgICAgICArK2o7CisgICAgfQorICAgIGFzc2VydFRydWUoY2xhc3NVbmRlclRlc3QgKyAiIG11c3QgY2FwdHVyZSB0aGUgcmlnaHQgYnl0ZXMgYXMgQnl0ZXMiLCBzdGlsbEVxdWFsKTsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIGl0ZXJhYmxlIGNoYXJhY3RlciBjb3VudCIsIHJlZmVyZW5jZUJ5dGVzLmxlbmd0aCwgaik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2l6ZSgpIHsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIG11c3QgaGF2ZSB0aGUgZXhwZWN0ZWQgc2l6ZSIsIHJlZmVyZW5jZUJ5dGVzLmxlbmd0aCwKKyAgICAgICAgc3RyaW5nVW5kZXJUZXN0LnNpemUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHJlZURlcHRoKCkgeworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgbXVzdCBoYXZlIGRlcHRoIDAiLCAwLCBzdHJpbmdVbmRlclRlc3QuZ2V0VHJlZURlcHRoKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdElzQmFsYW5jZWQoKSB7CisgICAgYXNzZXJ0VHJ1ZShjbGFzc1VuZGVyVGVzdCArICIgaXMgdGVjaG5pY2FsbHkgYmFsYW5jZWQiLCBzdHJpbmdVbmRlclRlc3QuaXNCYWxhbmNlZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5VG9fQnl0ZUFycmF5T2Zmc2V0TGVuZ3RoKCkgeworICAgIGludCBkZXN0aW5hdGlvbk9mZnNldCA9IDUwOworICAgIGludCBsZW5ndGggPSAxMDA7CisgICAgYnl0ZVtdIGRlc3RpbmF0aW9uID0gbmV3IGJ5dGVbZGVzdGluYXRpb25PZmZzZXQgKyBsZW5ndGhdOworICAgIGludCBzb3VyY2VPZmZzZXQgPSAyMTM7CisgICAgc3RyaW5nVW5kZXJUZXN0LmNvcHlUbyhkZXN0aW5hdGlvbiwgc291cmNlT2Zmc2V0LCBkZXN0aW5hdGlvbk9mZnNldCwgbGVuZ3RoKTsKKyAgICBib29sZWFuIHN0aWxsRXF1YWwgPSB0cnVlOworICAgIGZvciAoaW50IGkgPSAwOyBzdGlsbEVxdWFsICYmIGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgc3RpbGxFcXVhbCA9IHJlZmVyZW5jZUJ5dGVzW2kgKyBzb3VyY2VPZmZzZXRdID09IGRlc3RpbmF0aW9uW2kgKyBkZXN0aW5hdGlvbk9mZnNldF07CisgICAgfQorICAgIGFzc2VydFRydWUoY2xhc3NVbmRlclRlc3QgKyAiLmNvcHlUbyg0IGFyZykgbXVzdCBnaXZlIHRoZSBleHBlY3RlZCBieXRlcyIsIHN0aWxsRXF1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENvcHlUb19CeXRlQXJyYXlPZmZzZXRMZW5ndGhFcnJvcnMoKSB7CisgICAgaW50IGRlc3RpbmF0aW9uT2Zmc2V0ID0gNTA7CisgICAgaW50IGxlbmd0aCA9IDEwMDsKKyAgICBieXRlW10gZGVzdGluYXRpb24gPSBuZXcgYnl0ZVtkZXN0aW5hdGlvbk9mZnNldCArIGxlbmd0aF07CisKKyAgICB0cnkgeworICAgICAgLy8gQ29weSBvbmUgdG9vIG1hbnkgYnl0ZXMKKyAgICAgIHN0cmluZ1VuZGVyVGVzdC5jb3B5VG8oZGVzdGluYXRpb24sIHN0cmluZ1VuZGVyVGVzdC5zaXplKCkgKyAxIC0gbGVuZ3RoLAorICAgICAgICAgIGRlc3RpbmF0aW9uT2Zmc2V0LCBsZW5ndGgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbiB3aGVuIGNvcHlpbmcgdG9vIG1hbnkgYnl0ZXMgb2YgYSAiCisgICAgICAgICAgKyBjbGFzc1VuZGVyVGVzdCk7CisgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgLy8gVGhpcyBpcyBzdWNjZXNzCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIC8vIENvcHkgd2l0aCBpbGxlZ2FsIG5lZ2F0aXZlIHNvdXJjZU9mZnNldAorICAgICAgc3RyaW5nVW5kZXJUZXN0LmNvcHlUbyhkZXN0aW5hdGlvbiwgLTEsIGRlc3RpbmF0aW9uT2Zmc2V0LCBsZW5ndGgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbiB3aGVuIGdpdmVuIGEgbmVnYXRpdmUgc291cmNlT2Zmc2V0IGluICIKKyAgICAgICAgICArIGNsYXNzVW5kZXJUZXN0KTsKKyAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAvLyBUaGlzIGlzIHN1Y2Nlc3MKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgLy8gQ29weSB3aXRoIGlsbGVnYWwgbmVnYXRpdmUgZGVzdGluYXRpb25PZmZzZXQKKyAgICAgIHN0cmluZ1VuZGVyVGVzdC5jb3B5VG8oZGVzdGluYXRpb24sIDAsIC0xLCBsZW5ndGgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbiB3aGVuIGdpdmVuIGEgbmVnYXRpdmUgZGVzdGluYXRpb25PZmZzZXQgaW4gIgorICAgICAgICAgICsgY2xhc3NVbmRlclRlc3QpOworICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgIC8vIFRoaXMgaXMgc3VjY2VzcworICAgIH0KKworICAgIHRyeSB7CisgICAgICAvLyBDb3B5IHdpdGggaWxsZWdhbCBuZWdhdGl2ZSBzaXplCisgICAgICBzdHJpbmdVbmRlclRlc3QuY29weVRvKGRlc3RpbmF0aW9uLCAwLCAwLCAtMSk7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uIHdoZW4gZ2l2ZW4gYSBuZWdhdGl2ZSBzaXplIGluICIKKyAgICAgICAgICArIGNsYXNzVW5kZXJUZXN0KTsKKyAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAvLyBUaGlzIGlzIHN1Y2Nlc3MKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgLy8gQ29weSB3aXRoIGlsbGVnYWwgdG9vLWxhcmdlIHNvdXJjZU9mZnNldAorICAgICAgc3RyaW5nVW5kZXJUZXN0LmNvcHlUbyhkZXN0aW5hdGlvbiwgMiAqIHN0cmluZ1VuZGVyVGVzdC5zaXplKCksIDAsIGxlbmd0aCk7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uIHdoZW4gdGhlIGRlc3RpbmF0aW9uT2Zmc2V0IGlzIHRvbyBsYXJnZSBpbiAiCisgICAgICAgICAgKyBjbGFzc1VuZGVyVGVzdCk7CisgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgLy8gVGhpcyBpcyBzdWNjZXNzCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIC8vIENvcHkgd2l0aCBpbGxlZ2FsIHRvby1sYXJnZSBkZXN0aW5hdGlvbk9mZnNldAorICAgICAgc3RyaW5nVW5kZXJUZXN0LmNvcHlUbyhkZXN0aW5hdGlvbiwgMCwgMiAqIGRlc3RpbmF0aW9uLmxlbmd0aCwgbGVuZ3RoKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24gd2hlbiB0aGUgZGVzdGluYXRpb25PZmZzZXQgaXMgdG9vIGxhcmdlIGluICIKKyAgICAgICAgICArIGNsYXNzVW5kZXJUZXN0KTsKKyAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAvLyBUaGlzIGlzIHN1Y2Nlc3MKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29weVRvX0J5dGVCdWZmZXIoKSB7CisgICAgQnl0ZUJ1ZmZlciBteUJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUocmVmZXJlbmNlQnl0ZXMubGVuZ3RoKTsKKyAgICBzdHJpbmdVbmRlclRlc3QuY29weVRvKG15QnVmZmVyKTsKKyAgICBhc3NlcnRUcnVlKGNsYXNzVW5kZXJUZXN0ICsgIi5jb3B5VG8oQnl0ZUJ1ZmZlcikgbXVzdCBnaXZlIGJhY2sgdGhlIHNhbWUgYnl0ZXMiLAorICAgICAgICBBcnJheXMuZXF1YWxzKHJlZmVyZW5jZUJ5dGVzLCBteUJ1ZmZlci5hcnJheSgpKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QXNSZWFkT25seUJ5dGVCdWZmZXIoKSB7CisgICAgQnl0ZUJ1ZmZlciBieXRlQnVmZmVyID0gc3RyaW5nVW5kZXJUZXN0LmFzUmVhZE9ubHlCeXRlQnVmZmVyKCk7CisgICAgYnl0ZVtdIHJvdW5kVHJpcEJ5dGVzID0gbmV3IGJ5dGVbcmVmZXJlbmNlQnl0ZXMubGVuZ3RoXTsKKyAgICBhc3NlcnRUcnVlKGJ5dGVCdWZmZXIucmVtYWluaW5nKCkgPT0gcmVmZXJlbmNlQnl0ZXMubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKGJ5dGVCdWZmZXIuaXNSZWFkT25seSgpKTsKKyAgICBieXRlQnVmZmVyLmdldChyb3VuZFRyaXBCeXRlcyk7CisgICAgYXNzZXJ0VHJ1ZShjbGFzc1VuZGVyVGVzdCArICIuYXNSZWFkT25seUJ5dGVCdWZmZXIoKSBtdXN0IGdpdmUgYmFjayB0aGUgc2FtZSBieXRlcyIsCisgICAgICAgIEFycmF5cy5lcXVhbHMocmVmZXJlbmNlQnl0ZXMsIHJvdW5kVHJpcEJ5dGVzKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QXNSZWFkT25seUJ5dGVCdWZmZXJMaXN0KCkgeworICAgIExpc3Q8Qnl0ZUJ1ZmZlcj4gYnl0ZUJ1ZmZlcnMgPSBzdHJpbmdVbmRlclRlc3QuYXNSZWFkT25seUJ5dGVCdWZmZXJMaXN0KCk7CisgICAgaW50IGJ5dGVzU2VlbiA9IDA7CisgICAgYnl0ZVtdIHJvdW5kVHJpcEJ5dGVzID0gbmV3IGJ5dGVbcmVmZXJlbmNlQnl0ZXMubGVuZ3RoXTsKKyAgICBmb3IgKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlciA6IGJ5dGVCdWZmZXJzKSB7CisgICAgICBpbnQgdGhpc0xlbmd0aCA9IGJ5dGVCdWZmZXIucmVtYWluaW5nKCk7CisgICAgICBhc3NlcnRUcnVlKGJ5dGVCdWZmZXIuaXNSZWFkT25seSgpKTsKKyAgICAgIGFzc2VydFRydWUoYnl0ZXNTZWVuICsgdGhpc0xlbmd0aCA8PSByZWZlcmVuY2VCeXRlcy5sZW5ndGgpOworICAgICAgYnl0ZUJ1ZmZlci5nZXQocm91bmRUcmlwQnl0ZXMsIGJ5dGVzU2VlbiwgdGhpc0xlbmd0aCk7CisgICAgICBieXRlc1NlZW4gKz0gdGhpc0xlbmd0aDsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZShieXRlc1NlZW4gPT0gcmVmZXJlbmNlQnl0ZXMubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKGNsYXNzVW5kZXJUZXN0ICsgIi5hc1JlYWRPbmx5Qnl0ZUJ1ZmZlclRlc3QoKSBtdXN0IGdpdmUgYmFjayB0aGUgc2FtZSBieXRlcyIsCisgICAgICAgIEFycmF5cy5lcXVhbHMocmVmZXJlbmNlQnl0ZXMsIHJvdW5kVHJpcEJ5dGVzKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VG9CeXRlQXJyYXkoKSB7CisgICAgYnl0ZVtdIHJvdW5kVHJpcEJ5dGVzID0gc3RyaW5nVW5kZXJUZXN0LnRvQnl0ZUFycmF5KCk7CisgICAgYXNzZXJ0VHJ1ZShjbGFzc1VuZGVyVGVzdCArICIudG9CeXRlQXJyYXkoKSBtdXN0IGdpdmUgYmFjayB0aGUgc2FtZSBieXRlcyIsCisgICAgICAgIEFycmF5cy5lcXVhbHMocmVmZXJlbmNlQnl0ZXMsIHJvdW5kVHJpcEJ5dGVzKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVUbygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBzdHJpbmdVbmRlclRlc3Qud3JpdGVUbyhib3MpOworICAgIGJ5dGVbXSByb3VuZFRyaXBCeXRlcyA9IGJvcy50b0J5dGVBcnJheSgpOworICAgIGFzc2VydFRydWUoY2xhc3NVbmRlclRlc3QgKyAiLndyaXRlVG8oKSBtdXN0IGdpdmUgYmFjayB0aGUgc2FtZSBieXRlcyIsCisgICAgICAgIEFycmF5cy5lcXVhbHMocmVmZXJlbmNlQnl0ZXMsIHJvdW5kVHJpcEJ5dGVzKSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZVRvX211dGF0aW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBPdXRwdXRTdHJlYW0gb3MgPSBuZXcgT3V0cHV0U3RyZWFtKCkgeworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICBmb3IgKGludCB4ID0gMDsgeCA8IGxlbjsgKyt4KSB7CisgICAgICAgICAgYltvZmYgKyB4XSA9IChieXRlKSAwOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHsKKyAgICAgICAgLy8gUHVycG9zZWZ1bGx5IGxlZnQgYmxhbmsuCisgICAgICB9CisgICAgfTsKKworICAgIHN0cmluZ1VuZGVyVGVzdC53cml0ZVRvKG9zKTsKKyAgICBieXRlW10gbmV3Qnl0ZXMgPSBzdHJpbmdVbmRlclRlc3QudG9CeXRlQXJyYXkoKTsKKyAgICBhc3NlcnRUcnVlKGNsYXNzVW5kZXJUZXN0ICsgIi53cml0ZVRvKCkgbXVzdCBub3QgZ3JhbnQgYWNjZXNzIHRvIHVuZGVybHlpbmcgYXJyYXkiLAorICAgICAgICBBcnJheXMuZXF1YWxzKHJlZmVyZW5jZUJ5dGVzLCBuZXdCeXRlcykpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5ld091dHB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBCeXRlU3RyaW5nLk91dHB1dCBvdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dCgpOworICAgIHN0cmluZ1VuZGVyVGVzdC53cml0ZVRvKG91dHB1dCk7CisgICAgYXNzZXJ0RXF1YWxzKCJPdXRwdXQgU2l6ZSByZXR1cm5zIGNvcnJlY3QgcmVzdWx0IiwKKyAgICAgICAgb3V0cHV0LnNpemUoKSwgc3RyaW5nVW5kZXJUZXN0LnNpemUoKSk7CisgICAgb3V0cHV0LndyaXRlVG8oYm9zKTsKKyAgICBhc3NlcnRUcnVlKCJPdXRwdXQud3JpdGVUbygpIG11c3QgZ2l2ZSBiYWNrIHRoZSBzYW1lIGJ5dGVzIiwKKyAgICAgICAgQXJyYXlzLmVxdWFscyhyZWZlcmVuY2VCeXRlcywgYm9zLnRvQnl0ZUFycmF5KCkpKTsKKworICAgIC8vIHdyaXRlIHRoZSBvdXRwdXQgc3RyZWFtIHRvIGl0c2VsZiEgVGhpcyBzaG91bGQgY2F1c2UgaXQgdG8gZG91YmxlCisgICAgb3V0cHV0LndyaXRlVG8ob3V0cHV0KTsKKyAgICBhc3NlcnRFcXVhbHMoIldyaXRpbmcgYW4gb3V0cHV0IHN0cmVhbSB0byBpdHNlbGYgaXMgc3VjY2Vzc2Z1bCIsCisgICAgICAgIHN0cmluZ1VuZGVyVGVzdC5jb25jYXQoc3RyaW5nVW5kZXJUZXN0KSwgb3V0cHV0LnRvQnl0ZVN0cmluZygpKTsKKworICAgIG91dHB1dC5yZXNldCgpOworICAgIGFzc2VydEVxdWFscygiT3V0cHV0LnJlc2V0KCkgcmVzZXRzIHRoZSBvdXRwdXQiLCAwLCBvdXRwdXQuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoIk91dHB1dC5yZXNldCgpIHJlc2V0cyB0aGUgb3V0cHV0IiwKKyAgICAgICAgQnl0ZVN0cmluZy5FTVBUWSwgb3V0cHV0LnRvQnl0ZVN0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZygpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJJIGxvdmUgdW5pY29kZSBcdTEyMzRcdTU2NzggY2hhcmFjdGVycyI7CisgICAgTGl0ZXJhbEJ5dGVTdHJpbmcgdW5pY29kZSA9IG5ldyBMaXRlcmFsQnl0ZVN0cmluZyh0ZXN0U3RyaW5nLmdldEJ5dGVzKFVURl84KSk7CisgICAgU3RyaW5nIHJvdW5kVHJpcFN0cmluZyA9IHVuaWNvZGUudG9TdHJpbmcoVVRGXzgpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgdW5pY29kZSBtdXN0IG1hdGNoIiwgdGVzdFN0cmluZywgcm91bmRUcmlwU3RyaW5nKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZ19yZXR1cm5zQ2Fub25pY2FsRW1wdHlTdHJpbmcoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbnsKKyAgICBhc3NlcnRTYW1lKGNsYXNzVW5kZXJUZXN0ICsgIiBtdXN0IGJlIHRoZSBzYW1lIHN0cmluZyByZWZlcmVuY2VzIiwKKyAgICAgICAgQnl0ZVN0cmluZy5FTVBUWS50b1N0cmluZyhVVEZfOCksIG5ldyBMaXRlcmFsQnl0ZVN0cmluZyhuZXcgYnl0ZVtde30pLnRvU3RyaW5nKFVURl84KSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmdfcmFpc2VzRXhjZXB0aW9uKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb257CisgICAgdHJ5IHsKKyAgICAgIEJ5dGVTdHJpbmcuRU1QVFkudG9TdHJpbmcoImludmFsaWQiKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgLy8gVGhpcyBpcyBzdWNjZXNzCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIG5ldyBMaXRlcmFsQnl0ZVN0cmluZyhyZWZlcmVuY2VCeXRlcykudG9TdHJpbmcoImludmFsaWQiKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgLy8gVGhpcyBpcyBzdWNjZXNzCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVxdWFscygpIHsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIG11c3Qgbm90IGVxdWFsIG51bGwiLCBmYWxzZSwgc3RyaW5nVW5kZXJUZXN0LmVxdWFscyhudWxsKSk7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIiBtdXN0IGVxdWFsIHNlbGYiLCBzdHJpbmdVbmRlclRlc3QsIHN0cmluZ1VuZGVyVGVzdCk7CisgICAgYXNzZXJ0RmFsc2UoY2xhc3NVbmRlclRlc3QgKyAiIG11c3Qgbm90IGVxdWFsIHRoZSBlbXB0eSBzdHJpbmciLAorICAgICAgICBzdHJpbmdVbmRlclRlc3QuZXF1YWxzKEJ5dGVTdHJpbmcuRU1QVFkpKTsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIGVtcHR5IHN0cmluZ3MgbXVzdCBiZSBlcXVhbCIsCisgICAgICAgIG5ldyBMaXRlcmFsQnl0ZVN0cmluZyhuZXcgYnl0ZVtde30pLCBzdHJpbmdVbmRlclRlc3Quc3Vic3RyaW5nKDU1LCA1NSkpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgbXVzdCBlcXVhbCBhbm90aGVyIHN0cmluZyB3aXRoIHRoZSBzYW1lIHZhbHVlIiwKKyAgICAgICAgc3RyaW5nVW5kZXJUZXN0LCBuZXcgTGl0ZXJhbEJ5dGVTdHJpbmcocmVmZXJlbmNlQnl0ZXMpKTsKKworICAgIGJ5dGVbXSBtdW5nZWRCeXRlcyA9IG5ldyBieXRlW3JlZmVyZW5jZUJ5dGVzLmxlbmd0aF07CisgICAgU3lzdGVtLmFycmF5Y29weShyZWZlcmVuY2VCeXRlcywgMCwgbXVuZ2VkQnl0ZXMsIDAsIHJlZmVyZW5jZUJ5dGVzLmxlbmd0aCk7CisgICAgbXVuZ2VkQnl0ZXNbbXVuZ2VkQnl0ZXMubGVuZ3RoIC0gNV0gPSAoYnl0ZSkgKG11bmdlZEJ5dGVzW211bmdlZEJ5dGVzLmxlbmd0aCAtIDVdIF4gMHhGRik7CisgICAgYXNzZXJ0RmFsc2UoY2xhc3NVbmRlclRlc3QgKyAiIG11c3Qgbm90IGVxdWFsIGV2ZXJ5IHN0cmluZyB3aXRoIHRoZSBzYW1lIGxlbmd0aCIsCisgICAgICAgIHN0cmluZ1VuZGVyVGVzdC5lcXVhbHMobmV3IExpdGVyYWxCeXRlU3RyaW5nKG11bmdlZEJ5dGVzKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2RlKCkgeworICAgIGludCBoYXNoID0gc3RyaW5nVW5kZXJUZXN0Lmhhc2hDb2RlKCk7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIiBtdXN0IGhhdmUgZXhwZWN0ZWQgaGFzaENvZGUiLCBleHBlY3RlZEhhc2hDb2RlLCBoYXNoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQZWVrQ2FjaGVkSGFzaENvZGUoKSB7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIi5wZWVrQ2FjaGVkSGFzaENvZGUoKSBzaG91bGQgcmV0dXJuIHplcm8gYXQgZmlyc3QiLCAwLAorICAgICAgICBzdHJpbmdVbmRlclRlc3QucGVla0NhY2hlZEhhc2hDb2RlKCkpOworICAgIHN0cmluZ1VuZGVyVGVzdC5oYXNoQ29kZSgpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIucGVla0NhY2hlZEhhc2hDb2RlIHNob3VsZCByZXR1cm4gemVybyBhdCBmaXJzdCIsCisgICAgICAgIGV4cGVjdGVkSGFzaENvZGUsIHN0cmluZ1VuZGVyVGVzdC5wZWVrQ2FjaGVkSGFzaENvZGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFydGlhbEhhc2goKSB7CisgICAgLy8gcGFydGlhbEhhc2goKSBpcyBtb3JlIHN0cmVudW91c2x5IHRlc3RlZCBlbHNld2hlcmUgYnkgdGVzdGluZyBoYXNoZXMgb2Ygc3Vic3RyaW5ncy4KKyAgICAvLyBUaGlzIHRlc3Qgd291bGQgZmFpbCBpZiB0aGUgZXhwZWN0ZWQgaGFzaCB3ZXJlIDEuICBJdCdzIG5vdC4KKyAgICBpbnQgaGFzaCA9IHN0cmluZ1VuZGVyVGVzdC5wYXJ0aWFsSGFzaChzdHJpbmdVbmRlclRlc3Quc2l6ZSgpLCAwLCBzdHJpbmdVbmRlclRlc3Quc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiLnBhcnRpYWxIYXNoKCkgbXVzdCB5aWVsZCBleHBlY3RlZCBoYXNoQ29kZSIsCisgICAgICAgIGV4cGVjdGVkSGFzaENvZGUsIGhhc2gpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5ld0lucHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnB1dFN0cmVhbSBpbnB1dCA9IHN0cmluZ1VuZGVyVGVzdC5uZXdJbnB1dCgpOworICAgIGFzc2VydEVxdWFscygiSW5wdXRTdHJlYW0uYXZhaWxhYmxlKCkgcmV0dXJucyBjb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgc3RyaW5nVW5kZXJUZXN0LnNpemUoKSwgaW5wdXQuYXZhaWxhYmxlKCkpOworICAgIGJvb2xlYW4gc3RpbGxFcXVhbCA9IHRydWU7CisgICAgZm9yIChieXRlIHJlZmVyZW5jZUJ5dGUgOiByZWZlcmVuY2VCeXRlcykgeworICAgICAgaW50IGV4cGVjdGVkSW50ID0gKHJlZmVyZW5jZUJ5dGUgJiAweEZGKTsKKyAgICAgIHN0aWxsRXF1YWwgPSAoZXhwZWN0ZWRJbnQgPT0gaW5wdXQucmVhZCgpKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKCJJbnB1dFN0cmVhbS5hdmFpbGFibGUoKSByZXR1cm5zIGNvcnJlY3QgdmFsdWUiLAorICAgICAgICAwLCBpbnB1dC5hdmFpbGFibGUoKSk7CisgICAgYXNzZXJ0VHJ1ZShjbGFzc1VuZGVyVGVzdCArICIgbXVzdCBnaXZlIHRoZSBzYW1lIGJ5dGVzIGZyb20gdGhlIElucHV0U3RyZWFtIiwgc3RpbGxFcXVhbCk7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIiBJbnB1dFN0cmVhbSBtdXN0IG5vdyBiZSBleGhhdXN0ZWQiLCAtMSwgaW5wdXQucmVhZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXdJbnB1dF9za2lwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnB1dFN0cmVhbSBpbnB1dCA9IHN0cmluZ1VuZGVyVGVzdC5uZXdJbnB1dCgpOworICAgIGludCBzdHJpbmdTaXplID0gc3RyaW5nVW5kZXJUZXN0LnNpemUoKTsKKyAgICBpbnQgbmVhckVuZEluZGV4ID0gc3RyaW5nU2l6ZSAqIDIgLyAzOworICAgIGxvbmcgc2tpcHBlZDEgPSBpbnB1dC5za2lwKG5lYXJFbmRJbmRleCk7CisgICAgYXNzZXJ0RXF1YWxzKCJJbnB1dFN0cmVhbS5za2lwKCkiLCBza2lwcGVkMSwgbmVhckVuZEluZGV4KTsKKyAgICBhc3NlcnRFcXVhbHMoIklucHV0U3RyZWFtLmF2YWlsYWJsZSgpIiwKKyAgICAgICAgc3RyaW5nU2l6ZSAtIHNraXBwZWQxLCBpbnB1dC5hdmFpbGFibGUoKSk7CisgICAgYXNzZXJ0VHJ1ZSgiSW5wdXRTdHJlYW0ubWFyaygpIGlzIGF2YWlsYWJsZSIsIGlucHV0Lm1hcmtTdXBwb3J0ZWQoKSk7CisgICAgaW5wdXQubWFyaygwKTsKKyAgICBhc3NlcnRFcXVhbHMoIklucHV0U3RyZWFtLnNraXAoKSwgcmVhZCgpIiwKKyAgICAgICAgc3RyaW5nVW5kZXJUZXN0LmJ5dGVBdChuZWFyRW5kSW5kZXgpICYgMHhGRiwgaW5wdXQucmVhZCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoIklucHV0U3RyZWFtLmF2YWlsYWJsZSgpIiwKKyAgICAgICAgICAgICAgICAgc3RyaW5nU2l6ZSAtIHNraXBwZWQxIC0gMSwgaW5wdXQuYXZhaWxhYmxlKCkpOworICAgIGxvbmcgc2tpcHBlZDIgPSBpbnB1dC5za2lwKHN0cmluZ1NpemUpOworICAgIGFzc2VydEVxdWFscygiSW5wdXRTdHJlYW0uc2tpcCgpIGluY29tcGxldGUiLAorICAgICAgICBza2lwcGVkMiwgc3RyaW5nU2l6ZSAtIHNraXBwZWQxIC0gMSk7CisgICAgYXNzZXJ0RXF1YWxzKCJJbnB1dFN0cmVhbS5za2lwKCksIG5vIG1vcmUgaW5wdXQiLCAwLCBpbnB1dC5hdmFpbGFibGUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJJbnB1dFN0cmVhbS5za2lwKCksIG5vIG1vcmUgaW5wdXQiLCAtMSwgaW5wdXQucmVhZCgpKTsKKyAgICBpbnB1dC5yZXNldCgpOworICAgIGFzc2VydEVxdWFscygiSW5wdXRTdHJlYW0ucmVzZXQoKSBzdWNjZWRlZCIsCisgICAgICAgICAgICAgICAgIHN0cmluZ1NpemUgLSBza2lwcGVkMSwgaW5wdXQuYXZhaWxhYmxlKCkpOworICAgIGFzc2VydEVxdWFscygiSW5wdXRTdHJlYW0ucmVzZXQoKSwgcmVhZCgpIiwKKyAgICAgICAgc3RyaW5nVW5kZXJUZXN0LmJ5dGVBdChuZWFyRW5kSW5kZXgpICYgMHhGRiwgaW5wdXQucmVhZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXdDb2RlZElucHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNpcyA9IHN0cmluZ1VuZGVyVGVzdC5uZXdDb2RlZElucHV0KCk7CisgICAgYnl0ZVtdIHJvdW5kVHJpcEJ5dGVzID0gY2lzLnJlYWRSYXdCeXRlcyhyZWZlcmVuY2VCeXRlcy5sZW5ndGgpOworICAgIGFzc2VydFRydWUoY2xhc3NVbmRlclRlc3QgKyAiIG11c3QgZ2l2ZSB0aGUgc2FtZSBieXRlcyBiYWNrIGZyb20gdGhlIENvZGVkSW5wdXRTdHJlYW0iLAorICAgICAgICBBcnJheXMuZXF1YWxzKHJlZmVyZW5jZUJ5dGVzLCByb3VuZFRyaXBCeXRlcykpOworICAgIGFzc2VydFRydWUoY2xhc3NVbmRlclRlc3QgKyAiIENvZGVkSW5wdXRTdHJlYW0gbXVzdCBub3cgYmUgZXhoYXVzdGVkIiwgY2lzLmlzQXRFbmQoKSk7CisgIH0KKworICAvKioKKyAgICogTWFrZSBzdXJlIHdlIGtlZXAgdGhpbmdzIHNpbXBsZSB3aGVuIGNvbmNhdGVuYXRpbmcgd2l0aCBlbXB0eS4gU2VlIGFsc28KKyAgICoge0BsaW5rIEJ5dGVTdHJpbmdUZXN0I3Rlc3RDb25jYXRfZW1wdHkoKX0uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Q29uY2F0X2VtcHR5KCkgeworICAgIGFzc2VydFNhbWUoY2xhc3NVbmRlclRlc3QgKyAiIGNvbmNhdGVuYXRlZCB3aXRoIGVtcHR5IG11c3QgZ2l2ZSAiICsgY2xhc3NVbmRlclRlc3QsCisgICAgICAgIHN0cmluZ1VuZGVyVGVzdC5jb25jYXQoQnl0ZVN0cmluZy5FTVBUWSksIHN0cmluZ1VuZGVyVGVzdCk7CisgICAgYXNzZXJ0U2FtZSgiZW1wdHkgY29uY2F0ZW5hdGVkIHdpdGggIiArIGNsYXNzVW5kZXJUZXN0ICsgIiBtdXN0IGdpdmUgIiArIGNsYXNzVW5kZXJUZXN0LAorICAgICAgICBCeXRlU3RyaW5nLkVNUFRZLmNvbmNhdChzdHJpbmdVbmRlclRlc3QpLCBzdHJpbmdVbmRlclRlc3QpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEphdmFTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShvdXQpOworICAgIG9vcy53cml0ZU9iamVjdChzdHJpbmdVbmRlclRlc3QpOworICAgIG9vcy5jbG9zZSgpOworICAgIGJ5dGVbXSBwaWNrbGVkID0gb3V0LnRvQnl0ZUFycmF5KCk7CisgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocGlja2xlZCk7CisgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGluKTsKKyAgICBPYmplY3QgbyA9IG9pcy5yZWFkT2JqZWN0KCk7CisgICAgYXNzZXJ0VHJ1ZSgiRGlkbid0IGdldCBhIEJ5dGVTdHJpbmcgYmFjayIsIG8gaW5zdGFuY2VvZiBCeXRlU3RyaW5nKTsKKyAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCBnZXQgYW4gZXF1YWwgQnl0ZVN0cmluZyBiYWNrIiwgc3RyaW5nVW5kZXJUZXN0LCBvKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRm9yUHJvdG8yTGl0ZVRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZvclByb3RvMkxpdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjJkYmViNwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZvclByb3RvMkxpdGVUZXN0LmphdmEKQEAgLTAsMCArMSwyNzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwOworaW1wb3J0IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlOworaW1wb3J0IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIG1hcCBmaWVsZHMuCisgKi8KK3B1YmxpYyBjbGFzcyBNYXBGb3JQcm90bzJMaXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgcHJpdmF0ZSB2b2lkIHNldE1hcFZhbHVlcyhUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlcikgeworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDExKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgyLCAyMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMywgMzMpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkucHV0KDEsICIxMSIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLnB1dCgyLCAiMjIiKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoMywgIjMzIik7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMSwgVGVzdFV0aWwudG9CeXRlcygiMTEiKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMiwgVGVzdFV0aWwudG9CeXRlcygiMjIiKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMywgVGVzdFV0aWwudG9CeXRlcygiMzMiKSk7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLnB1dCgxLCBUZXN0TWFwLkVudW1WYWx1ZS5GT08pOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoMiwgVGVzdE1hcC5FbnVtVmFsdWUuQkFSKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkucHV0KDMsIFRlc3RNYXAuRW51bVZhbHVlLkJBWik7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMSwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgxMSkuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMiwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgyMikuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMywgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgzMykuYnVpbGQoKSk7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkucHV0KCIxIiwgMTEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnB1dCgiMiIsIDIyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5wdXQoIjMiLCAzMyk7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0TWFwVmFsdWVzU2V0KFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTEsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMSkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIyLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgzKS5pbnRWYWx1ZSgpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCIxMSIsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoIjIyIiwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXQoMikpOworICAgIGFzc2VydEVxdWFscygiMzMiLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldCgzKSk7CisgICAgCisgICAgYXNzZXJ0RXF1YWxzKDMsIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0VXRpbC50b0J5dGVzKCIxMSIpLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiMjIiKSwgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldCgyKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjMzIiksIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXQoMykpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5GT08sIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkJBUiwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDIpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuQkFaLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoMykpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMSwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDEpLmdldFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygyMiwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDIpLmdldFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDMpLmdldFZhbHVlKCkpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldCgiMSIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygyMiwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXQoIjIiKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0KCIzIikuaW50VmFsdWUoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgdXBkYXRlTWFwVmFsdWVzKFRlc3RNYXAuQnVpbGRlciBidWlsZGVyKSB7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMTExKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnJlbW92ZSgyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCg0LCA0NCk7CisKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoMSwgIjExMSIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLnJlbW92ZSgyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoNCwgIjQ0Iik7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMSwgVGVzdFV0aWwudG9CeXRlcygiMTExIikpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkucmVtb3ZlKDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkucHV0KDQsIFRlc3RVdGlsLnRvQnl0ZXMoIjQ0IikpOworICAgIAorICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoMSwgVGVzdE1hcC5FbnVtVmFsdWUuQkFSKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkucmVtb3ZlKDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoNCwgVGVzdE1hcC5FbnVtVmFsdWUuUVVYKTsKKyAgICAKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkucHV0KAorICAgICAgICAxLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDExMSkuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnJlbW92ZSgyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkucHV0KAorICAgICAgICA0LCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDQ0KS5idWlsZCgpKTsKKyAgICAKKyAgICBidWlsZGVyLmdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5wdXQoIjEiLCAxMTEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnJlbW92ZSgiMiIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnB1dCgiNCIsIDQ0KTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBWYWx1ZXNVcGRhdGVkKFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTExLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDEpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgzKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoNCkuaW50VmFsdWUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygiMTExIiwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscygiMzMiLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKCI0NCIsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0KDQpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjExMSIpLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiMzMiKSwgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjQ0IiksIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXQoNCkpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5CQVIsIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkJBWiwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDMpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuUVVYLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoNCkpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMTEsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCgxKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCgzKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCg0KS5nZXRWYWx1ZSgpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMTEsIG1lc3NhZ2UuZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0KCIxIikuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMzLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldCgiMyIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg0NCwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXQoIjQiKS5pbnRWYWx1ZSgpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBWYWx1ZXNDbGVhcmVkKFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5zaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldHRlcnNBbmRTZXR0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0TWFwVmFsdWVzQ2xlYXJlZChtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNTZXQobWVzc2FnZSk7CisgICAgCisgICAgYnVpbGRlciA9IG1lc3NhZ2UudG9CdWlsZGVyKCk7CisgICAgdXBkYXRlTWFwVmFsdWVzKGJ1aWxkZXIpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0TWFwVmFsdWVzVXBkYXRlZChtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmNsZWFyKCk7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNDbGVhcmVkKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZUFuZFBhcnNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkuc2l6ZSgpKTsKKyAgICBtZXNzYWdlID0gVGVzdE1hcC5QQVJTRVIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydE1hcFZhbHVlc1NldChtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICB1cGRhdGVNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpLCBtZXNzYWdlLnRvQnl0ZVN0cmluZygpLnNpemUoKSk7CisgICAgbWVzc2FnZSA9IFRlc3RNYXAuUEFSU0VSLnBhcnNlRnJvbShtZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNVcGRhdGVkKG1lc3NhZ2UpOworICAgIAorICAgIGJ1aWxkZXIgPSBtZXNzYWdlLnRvQnVpbGRlcigpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkuc2l6ZSgpKTsKKyAgICBtZXNzYWdlID0gVGVzdE1hcC5QQVJTRVIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydE1hcFZhbHVlc0NsZWFyZWQobWVzc2FnZSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUZyb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIHNldE1hcFZhbHVlcyhidWlsZGVyKTsKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgCisgICAgVGVzdE1hcC5CdWlsZGVyIG90aGVyID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgb3RoZXIubWVyZ2VGcm9tKG1lc3NhZ2UpOworICAgIGFzc2VydE1hcFZhbHVlc1NldChvdGhlci5idWlsZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNBbmRIYXNoQ29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3QgdGhhdCBnZW5lcmF0ZWQgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkgd2lsbCBkaXNyZWdhcmQgdGhlIG9yZGVyCisgICAgLy8gb2YgbWFwIGVudHJpZXMgd2hlbiBjb21wYXJpbmcvaGFzaGluZyBtYXAgZmllbGRzLgorICAgIAorICAgIC8vIFdlIGNhbid0IGNvbnRyb2wgdGhlIG9yZGVyIG9mIGVsZW1lbnRzIGluIGEgSGFzaE1hcC4gVGhlIGJlc3Qgd2UgY2FuIGRvCisgICAgLy8gaGVyZSBpcyB0byBhZGQgZWxlbWVudHMgaW4gZGlmZmVyZW50IG9yZGVyLgorICAgIFRlc3RNYXAuQnVpbGRlciBiMSA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGIxLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgxLCAyKTsKKyAgICBiMS5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMywgNCk7CisgICAgYjEuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDUsIDYpOworICAgIFRlc3RNYXAgbTEgPSBiMS5idWlsZCgpOworICAgIAorICAgIFRlc3RNYXAuQnVpbGRlciBiMiA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGIyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCg1LCA2KTsKKyAgICBiMi5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMik7CisgICAgYjIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDMsIDQpOworICAgIFRlc3RNYXAgbTIgPSBiMi5idWlsZCgpOworICAgIAorICAgIGFzc2VydEVxdWFscyhtMSwgbTIpOworICAgIGFzc2VydEVxdWFscyhtMS5oYXNoQ29kZSgpLCBtMi5oYXNoQ29kZSgpKTsKKyAgICAKKyAgICAvLyBNYWtlIHN1cmUgd2UgZGlkIGNvbXBhcmUgbWFwIGZpZWxkcy4KKyAgICBiMi5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMCk7CisgICAgbTIgPSBiMi5idWlsZCgpOworICAgIGFzc2VydEZhbHNlKG0xLmVxdWFscyhtMikpOworICAgIC8vIERvbid0IGNoZWNrIG0xLmhhc2hDb2RlKCkgIT0gbTIuaGFzaENvZGUoKSBiZWNhdXNlIGl0J3Mgbm90IGd1YXJhbnRlZWQKKyAgICAvLyB0byBiZSBkaWZmZXJlbnQuCisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5rbm93bkVudW1WYWx1ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0VW5rbm93bkVudW1WYWx1ZS5CdWlsZGVyIGJ1aWxkZXIgPQorICAgICAgICBUZXN0VW5rbm93bkVudW1WYWx1ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMiwgNTQzMjEpOworICAgIEJ5dGVTdHJpbmcgZGF0YSA9IGJ1aWxkZXIuYnVpbGQoKS50b0J5dGVTdHJpbmcoKTsKKworICAgIFRlc3RNYXAgbWVzc2FnZSA9IFRlc3RNYXAucGFyc2VGcm9tKGRhdGEpOworICAgIC8vIEVudHJpZXMgd2l0aCB1bmtub3duIGVudW0gdmFsdWVzIHdpbGwgYmUgc3RvcmVkIGludG8gVW5rbm93bkZpZWxkU2V0IHNvCisgICAgLy8gdGhlcmUgaXMgb25seSBvbmUgZW50cnkgaW4gdGhlIG1hcC4KKyAgICBhc3NlcnRFcXVhbHMoMSwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuQkFSLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoMSkpOworICAgIC8vIFNlcmlhbGl6aW5nIGFuZCBwYXJzaW5nIHNob3VsZCBwcmVzZXJ2ZSB0aGUgdW5rbm93biBlbnRyeS4KKyAgICBkYXRhID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICBUZXN0VW5rbm93bkVudW1WYWx1ZSBtZXNzYWdlV2l0aFVua25vd25FbnVtcyA9CisgICAgICAgIFRlc3RVbmtub3duRW51bVZhbHVlLnBhcnNlRnJvbShkYXRhKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbWVzc2FnZVdpdGhVbmtub3duRW51bXMuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxLCBtZXNzYWdlV2l0aFVua25vd25FbnVtcy5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgxKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNTQzMjEsIG1lc3NhZ2VXaXRoVW5rbm93bkVudW1zLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDIpLmludFZhbHVlKCkpOworICB9CisgIAorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRm9yUHJvdG8yVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwRm9yUHJvdG8yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4Y2JhMWIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NYXBGb3JQcm90bzJUZXN0LmphdmEKQEAgLTAsMCArMSw1MTYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcjsKK2ltcG9ydCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcDsKK2ltcG9ydCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU7CitpbXBvcnQgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkczsKK2ltcG9ydCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcDsKK2ltcG9ydCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWU7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogVW5pdCB0ZXN0cyBmb3IgbWFwIGZpZWxkcyBpbiBwcm90bzIgcHJvdG9zLgorICovCitwdWJsaWMgY2xhc3MgTWFwRm9yUHJvdG8yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgcHJpdmF0ZSB2b2lkIHNldE1hcFZhbHVlcyhUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlcikgeworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDExKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgyLCAyMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMywgMzMpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkucHV0KDEsICIxMSIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLnB1dCgyLCAiMjIiKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoMywgIjMzIik7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMSwgVGVzdFV0aWwudG9CeXRlcygiMTEiKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMiwgVGVzdFV0aWwudG9CeXRlcygiMjIiKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMywgVGVzdFV0aWwudG9CeXRlcygiMzMiKSk7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLnB1dCgxLCBUZXN0TWFwLkVudW1WYWx1ZS5GT08pOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoMiwgVGVzdE1hcC5FbnVtVmFsdWUuQkFSKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkucHV0KDMsIFRlc3RNYXAuRW51bVZhbHVlLkJBWik7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMSwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgxMSkuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMiwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgyMikuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMywgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgzMykuYnVpbGQoKSk7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkucHV0KCIxIiwgMTEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnB1dCgiMiIsIDIyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5wdXQoIjMiLCAzMyk7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0TWFwVmFsdWVzU2V0KFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTEsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMSkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIyLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgzKS5pbnRWYWx1ZSgpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCIxMSIsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoIjIyIiwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXQoMikpOworICAgIGFzc2VydEVxdWFscygiMzMiLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldCgzKSk7CisgICAgCisgICAgYXNzZXJ0RXF1YWxzKDMsIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0VXRpbC50b0J5dGVzKCIxMSIpLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiMjIiKSwgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldCgyKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjMzIiksIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXQoMykpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5GT08sIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkJBUiwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDIpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuQkFaLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoMykpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMSwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDEpLmdldFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygyMiwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDIpLmdldFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDMpLmdldFZhbHVlKCkpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldCgiMSIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygyMiwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXQoIjIiKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0KCIzIikuaW50VmFsdWUoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgdXBkYXRlTWFwVmFsdWVzKFRlc3RNYXAuQnVpbGRlciBidWlsZGVyKSB7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMTExKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnJlbW92ZSgyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCg0LCA0NCk7CisKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoMSwgIjExMSIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLnJlbW92ZSgyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoNCwgIjQ0Iik7CisgICAgCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMSwgVGVzdFV0aWwudG9CeXRlcygiMTExIikpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkucmVtb3ZlKDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkucHV0KDQsIFRlc3RVdGlsLnRvQnl0ZXMoIjQ0IikpOworICAgIAorICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoMSwgVGVzdE1hcC5FbnVtVmFsdWUuQkFSKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkucmVtb3ZlKDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoNCwgVGVzdE1hcC5FbnVtVmFsdWUuUVVYKTsKKyAgICAKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkucHV0KAorICAgICAgICAxLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDExMSkuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnJlbW92ZSgyKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkucHV0KAorICAgICAgICA0LCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDQ0KS5idWlsZCgpKTsKKyAgICAKKyAgICBidWlsZGVyLmdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5wdXQoIjEiLCAxMTEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnJlbW92ZSgiMiIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnB1dCgiNCIsIDQ0KTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBWYWx1ZXNVcGRhdGVkKFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTExLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDEpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgzKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoNCkuaW50VmFsdWUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygiMTExIiwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscygiMzMiLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKCI0NCIsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0KDQpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjExMSIpLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0KDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiMzMiKSwgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjQ0IiksIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXQoNCkpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5CQVIsIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkJBWiwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDMpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuUVVYLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoNCkpOworICAgIAorICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMTEsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCgxKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCgzKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCg0KS5nZXRWYWx1ZSgpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMTEsIG1lc3NhZ2UuZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0KCIxIikuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMzLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldCgiMyIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg0NCwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXQoIjQiKS5pbnRWYWx1ZSgpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBWYWx1ZXNDbGVhcmVkKFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5zaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldHRlcnNBbmRTZXR0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0TWFwVmFsdWVzQ2xlYXJlZChtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNTZXQobWVzc2FnZSk7CisgICAgCisgICAgYnVpbGRlciA9IG1lc3NhZ2UudG9CdWlsZGVyKCk7CisgICAgdXBkYXRlTWFwVmFsdWVzKGJ1aWxkZXIpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0TWFwVmFsdWVzVXBkYXRlZChtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmNsZWFyKCk7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNDbGVhcmVkKG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZUFuZFBhcnNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkuc2l6ZSgpKTsKKyAgICBtZXNzYWdlID0gVGVzdE1hcC5QQVJTRVIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydE1hcFZhbHVlc1NldChtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICB1cGRhdGVNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpLCBtZXNzYWdlLnRvQnl0ZVN0cmluZygpLnNpemUoKSk7CisgICAgbWVzc2FnZSA9IFRlc3RNYXAuUEFSU0VSLnBhcnNlRnJvbShtZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNVcGRhdGVkKG1lc3NhZ2UpOworICAgIAorICAgIGJ1aWxkZXIgPSBtZXNzYWdlLnRvQnVpbGRlcigpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkuc2l6ZSgpKTsKKyAgICBtZXNzYWdlID0gVGVzdE1hcC5QQVJTRVIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydE1hcFZhbHVlc0NsZWFyZWQobWVzc2FnZSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUZyb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIHNldE1hcFZhbHVlcyhidWlsZGVyKTsKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgCisgICAgVGVzdE1hcC5CdWlsZGVyIG90aGVyID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgb3RoZXIubWVyZ2VGcm9tKG1lc3NhZ2UpOworICAgIGFzc2VydE1hcFZhbHVlc1NldChvdGhlci5idWlsZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNBbmRIYXNoQ29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3QgdGhhdCBnZW5lcmF0ZWQgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkgd2lsbCBkaXNyZWdhcmQgdGhlIG9yZGVyCisgICAgLy8gb2YgbWFwIGVudHJpZXMgd2hlbiBjb21wYXJpbmcvaGFzaGluZyBtYXAgZmllbGRzLgorICAgIAorICAgIC8vIFdlIGNhbid0IGNvbnRyb2wgdGhlIG9yZGVyIG9mIGVsZW1lbnRzIGluIGEgSGFzaE1hcC4gVGhlIGJlc3Qgd2UgY2FuIGRvCisgICAgLy8gaGVyZSBpcyB0byBhZGQgZWxlbWVudHMgaW4gZGlmZmVyZW50IG9yZGVyLgorICAgIFRlc3RNYXAuQnVpbGRlciBiMSA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGIxLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgxLCAyKTsKKyAgICBiMS5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMywgNCk7CisgICAgYjEuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDUsIDYpOworICAgIFRlc3RNYXAgbTEgPSBiMS5idWlsZCgpOworICAgIAorICAgIFRlc3RNYXAuQnVpbGRlciBiMiA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGIyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCg1LCA2KTsKKyAgICBiMi5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMik7CisgICAgYjIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDMsIDQpOworICAgIFRlc3RNYXAgbTIgPSBiMi5idWlsZCgpOworICAgIAorICAgIGFzc2VydEVxdWFscyhtMSwgbTIpOworICAgIGFzc2VydEVxdWFscyhtMS5oYXNoQ29kZSgpLCBtMi5oYXNoQ29kZSgpKTsKKyAgICAKKyAgICAvLyBNYWtlIHN1cmUgd2UgZGlkIGNvbXBhcmUgbWFwIGZpZWxkcy4KKyAgICBiMi5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMCk7CisgICAgbTIgPSBiMi5idWlsZCgpOworICAgIGFzc2VydEZhbHNlKG0xLmVxdWFscyhtMikpOworICAgIC8vIERvbid0IGNoZWNrIG0xLmhhc2hDb2RlKCkgIT0gbTIuaGFzaENvZGUoKSBiZWNhdXNlIGl0J3Mgbm90IGd1YXJhbnRlZWQKKyAgICAvLyB0byBiZSBkaWZmZXJlbnQuCisgIH0KKyAgCisgIAorICAvLyBUaGUgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gdGVzdCByZWZsZWN0aW9uIEFQSS4KKyAgCisgIHByaXZhdGUgc3RhdGljIEZpZWxkRGVzY3JpcHRvciBmKFN0cmluZyBuYW1lKSB7CisgICAgcmV0dXJuIFRlc3RNYXAuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZShuYW1lKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoTWVzc2FnZSBtYXBFbnRyeSwgU3RyaW5nIG5hbWUpIHsKKyAgICBGaWVsZERlc2NyaXB0b3IgZmllbGQgPSBtYXBFbnRyeS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZShuYW1lKTsKKyAgICByZXR1cm4gbWFwRW50cnkuZ2V0RmllbGQoZmllbGQpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBNZXNzYWdlLkJ1aWxkZXIgc2V0RmllbGRWYWx1ZSgKKyAgICAgIE1lc3NhZ2UuQnVpbGRlciBtYXBFbnRyeSwgU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgeworICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IG1hcEVudHJ5LmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKG5hbWUpOworICAgIG1hcEVudHJ5LnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CisgICAgcmV0dXJuIG1hcEVudHJ5OworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEhhc01hcFZhbHVlcyhNZXNzYWdlIG1lc3NhZ2UsIFN0cmluZyBuYW1lLCBNYXA8PywgPz4gdmFsdWVzKSB7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZihuYW1lKTsKKyAgICBmb3IgKE9iamVjdCBlbnRyeSA6IChMaXN0PD8+KSBtZXNzYWdlLmdldEZpZWxkKGZpZWxkKSkgeworICAgICAgTWVzc2FnZSBtYXBFbnRyeSA9IChNZXNzYWdlKSBlbnRyeTsKKyAgICAgIE9iamVjdCBrZXkgPSBnZXRGaWVsZFZhbHVlKG1hcEVudHJ5LCAia2V5Iik7CisgICAgICBPYmplY3QgdmFsdWUgPSBnZXRGaWVsZFZhbHVlKG1hcEVudHJ5LCAidmFsdWUiKTsKKyAgICAgIGFzc2VydFRydWUodmFsdWVzLmNvbnRhaW5zS2V5KGtleSkpOworICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCB2YWx1ZXMuZ2V0KGtleSkpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHModmFsdWVzLnNpemUoKSwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZmllbGQpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpZWxkKTsgaSsrKSB7CisgICAgICBNZXNzYWdlIG1hcEVudHJ5ID0gKE1lc3NhZ2UpIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaSk7CisgICAgICBPYmplY3Qga2V5ID0gZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgImtleSIpOworICAgICAgT2JqZWN0IHZhbHVlID0gZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgInZhbHVlIik7CisgICAgICBhc3NlcnRUcnVlKHZhbHVlcy5jb250YWluc0tleShrZXkpKTsKKyAgICAgIGFzc2VydEVxdWFscyh2YWx1ZSwgdmFsdWVzLmdldChrZXkpKTsKKyAgICB9CisgIH0KKyAgCisgIHByaXZhdGUgc3RhdGljIDxLZXlUeXBlLCBWYWx1ZVR5cGU+CisgIE1lc3NhZ2UgbmV3TWFwRW50cnkoTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIsIFN0cmluZyBuYW1lLCBLZXlUeXBlIGtleSwgVmFsdWVUeXBlIHZhbHVlKSB7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gYnVpbGRlci5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZShuYW1lKTsKKyAgICBNZXNzYWdlLkJ1aWxkZXIgZW50cnlCdWlsZGVyID0gYnVpbGRlci5uZXdCdWlsZGVyRm9yRmllbGQoZmllbGQpOworICAgIEZpZWxkRGVzY3JpcHRvciBrZXlGaWVsZCA9IGVudHJ5QnVpbGRlci5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgRmllbGREZXNjcmlwdG9yIHZhbHVlRmllbGQgPSBlbnRyeUJ1aWxkZXIuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgZW50cnlCdWlsZGVyLnNldEZpZWxkKGtleUZpZWxkLCBrZXkpOworICAgIGVudHJ5QnVpbGRlci5zZXRGaWVsZCh2YWx1ZUZpZWxkLCB2YWx1ZSk7CisgICAgcmV0dXJuIGVudHJ5QnVpbGRlci5idWlsZCgpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyB2b2lkIHNldE1hcFZhbHVlcyhNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlciwgU3RyaW5nIG5hbWUsIE1hcDw/LCA/PiB2YWx1ZXMpIHsKKyAgICBMaXN0PE1lc3NhZ2U+IGVudHJ5TGlzdCA9IG5ldyBBcnJheUxpc3Q8TWVzc2FnZT4oKTsKKyAgICBmb3IgKE1hcC5FbnRyeTw/LCA/PiBlbnRyeSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CisgICAgICBlbnRyeUxpc3QuYWRkKG5ld01hcEVudHJ5KGJ1aWxkZXIsIG5hbWUsIGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpKSk7CisgICAgfQorICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGJ1aWxkZXIuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgYnVpbGRlci5zZXRGaWVsZChmaWVsZCwgZW50cnlMaXN0KTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgPEtleVR5cGUsIFZhbHVlVHlwZT4KKyAgTWFwPEtleVR5cGUsIFZhbHVlVHlwZT4gbWFwRm9yVmFsdWVzKAorICAgICAgS2V5VHlwZSBrZXkxLCBWYWx1ZVR5cGUgdmFsdWUxLCBLZXlUeXBlIGtleTIsIFZhbHVlVHlwZSB2YWx1ZTIpIHsKKyAgICBNYXA8S2V5VHlwZSwgVmFsdWVUeXBlPiBtYXAgPSBuZXcgSGFzaE1hcDxLZXlUeXBlLCBWYWx1ZVR5cGU+KCk7CisgICAgbWFwLnB1dChrZXkxLCB2YWx1ZTEpOworICAgIG1hcC5wdXQoa2V5MiwgdmFsdWUyKTsKKyAgICByZXR1cm4gbWFwOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlZmxlY3Rpb25BcGkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBJbiByZWZsZWN0aW9uIEFQSSwgbWFwIGZpZWxkcyBhcmUganVzdCByZXBlYXRlZCBtZXNzYWdlIGZpZWxkcy4KKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDMsIDQpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5wdXQoCisgICAgICAgIDExLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDIyKS5idWlsZCgpKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkucHV0KAorICAgICAgICAzMywgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSg0NCkuYnVpbGQoKSk7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgLy8gVGVzdCBnZXRGaWVsZCgpLCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoKSwgZ2V0UmVwZWF0ZWRGaWVsZCgpLgorICAgIGFzc2VydEhhc01hcFZhbHVlcyhtZXNzYWdlLCAiaW50MzJfdG9faW50MzJfZmllbGQiLAorICAgICAgICBtYXBGb3JWYWx1ZXMoMSwgMiwgMywgNCkpOworICAgIGFzc2VydEhhc01hcFZhbHVlcyhtZXNzYWdlLCAiaW50MzJfdG9fbWVzc2FnZV9maWVsZCIsCisgICAgICAgIG1hcEZvclZhbHVlcygKKyAgICAgICAgICAgIDExLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDIyKS5idWlsZCgpLAorICAgICAgICAgICAgMzMsIE1lc3NhZ2VWYWx1ZS5uZXdCdWlsZGVyKCkuc2V0VmFsdWUoNDQpLmJ1aWxkKCkpKTsKKyAgICAKKyAgICAvLyBUZXN0IGNsZWFyRmllbGQoKQorICAgIGJ1aWxkZXIuY2xlYXJGaWVsZChmKCJpbnQzMl90b19pbnQzMl9maWVsZCIpKTsKKyAgICBidWlsZGVyLmNsZWFyRmllbGQoZigiaW50MzJfdG9fbWVzc2FnZV9maWVsZCIpKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuc2l6ZSgpKTsKKyAgICAKKyAgICAvLyBUZXN0IHNldEZpZWxkKCkKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlciwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwKKyAgICAgICAgbWFwRm9yVmFsdWVzKDExLCAyMiwgMzMsIDQ0KSk7CisgICAgc2V0TWFwVmFsdWVzKGJ1aWxkZXIsICJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIiwKKyAgICAgICAgbWFwRm9yVmFsdWVzKAorICAgICAgICAgICAgMTExLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDIyMikuYnVpbGQoKSwKKyAgICAgICAgICAgIDMzMywgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSg0NDQpLmJ1aWxkKCkpKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygyMiwgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgxMSkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ0LCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDMzKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMjIyLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoMTExKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQ0LCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoMzMzKS5nZXRWYWx1ZSgpKTsKKyAgICAKKyAgICAvLyBUZXN0IGFkZFJlcGVhdGVkRmllbGQKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRmllbGQoZigiaW50MzJfdG9faW50MzJfZmllbGQiKSwKKyAgICAgICAgbmV3TWFwRW50cnkoYnVpbGRlciwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgNTUsIDY2KSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoImludDMyX3RvX21lc3NhZ2VfZmllbGQiKSwKKyAgICAgICAgbmV3TWFwRW50cnkoYnVpbGRlciwgImludDMyX3RvX21lc3NhZ2VfZmllbGQiLCA1NTUsCisgICAgICAgICAgICBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDY2NikuYnVpbGQoKSkpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDY2LCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDU1KS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNjY2LCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoNTU1KS5nZXRWYWx1ZSgpKTsKKworICAgIC8vIFRlc3QgYWRkUmVwZWF0ZWRGaWVsZCAob3ZlcnJpZGluZyBleGlzdGluZyB2YWx1ZXMpCisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoImludDMyX3RvX2ludDMyX2ZpZWxkIiksCisgICAgICAgIG5ld01hcEVudHJ5KGJ1aWxkZXIsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDU1LCA1NSkpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmKCJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIiksCisgICAgICAgIG5ld01hcEVudHJ5KGJ1aWxkZXIsICJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIiwgNTU1LAorICAgICAgICAgICAgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSg1NTUpLmJ1aWxkKCkpKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyg1NSwgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCg1NSkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU1NSwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDU1NSkuZ2V0VmFsdWUoKSk7CisgICAgCisgICAgLy8gVGVzdCBzZXRSZXBlYXRlZEZpZWxkCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWlsZGVyLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJpbnQzMl90b19pbnQzMl9maWVsZCIpKTsgaSsrKSB7CisgICAgICBNZXNzYWdlIG1hcEVudHJ5ID0gKE1lc3NhZ2UpIGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZChmKCJpbnQzMl90b19pbnQzMl9maWVsZCIpLCBpKTsKKyAgICAgIGludCBvbGRLZXkgPSAoKEludGVnZXIpIGdldEZpZWxkVmFsdWUobWFwRW50cnksICJrZXkiKSkuaW50VmFsdWUoKTsKKyAgICAgIGludCBvbGRWYWx1ZSA9ICgoSW50ZWdlcikgZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgInZhbHVlIikpLmludFZhbHVlKCk7CisgICAgICAvLyBTd2FwIGtleSB3aXRoIHZhbHVlIGZvciBlYWNoIGVudHJ5LgorICAgICAgTWVzc2FnZS5CdWlsZGVyIG1hcEVudHJ5QnVpbGRlciA9IG1hcEVudHJ5LnRvQnVpbGRlcigpOworICAgICAgc2V0RmllbGRWYWx1ZShtYXBFbnRyeUJ1aWxkZXIsICJrZXkiLCBvbGRWYWx1ZSk7CisgICAgICBzZXRGaWVsZFZhbHVlKG1hcEVudHJ5QnVpbGRlciwgInZhbHVlIiwgb2xkS2V5KTsKKyAgICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWRGaWVsZChmKCJpbnQzMl90b19pbnQzMl9maWVsZCIpLCBpLCBtYXBFbnRyeUJ1aWxkZXIuYnVpbGQoKSk7CisgICAgfQorICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDExLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDIyKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoNDQpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg1NSwgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCg1NSkuaW50VmFsdWUoKSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RUZXh0Rm9ybWF0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIAorICAgIFN0cmluZyB0ZXh0RGF0YSA9IFRleHRGb3JtYXQucHJpbnRUb1N0cmluZyhtZXNzYWdlKTsKKyAgICAKKyAgICBidWlsZGVyID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZSh0ZXh0RGF0YSwgYnVpbGRlcik7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAKKyAgICBhc3NlcnRNYXBWYWx1ZXNTZXQobWVzc2FnZSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljTWVzc2FnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RNYXAuQnVpbGRlciBidWlsZGVyID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgc2V0TWFwVmFsdWVzKGJ1aWxkZXIpOworICAgIFRlc3RNYXAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAKKyAgICBNZXNzYWdlIGR5bmFtaWNEZWZhdWx0SW5zdGFuY2UgPQorICAgICAgICBEeW5hbWljTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoVGVzdE1hcC5nZXREZXNjcmlwdG9yKCkpOworICAgIE1lc3NhZ2UgZHluYW1pY01lc3NhZ2UgPSBkeW5hbWljRGVmYXVsdEluc3RhbmNlCisgICAgICAgIC5uZXdCdWlsZGVyRm9yVHlwZSgpLm1lcmdlRnJvbShtZXNzYWdlLnRvQnl0ZVN0cmluZygpKS5idWlsZCgpOworICAgIAorICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBkeW5hbWljTWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuaGFzaENvZGUoKSwgZHluYW1pY01lc3NhZ2UuaGFzaENvZGUoKSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RSZWZsZWN0aW9uRXF1YWxzQW5kSGFzaENvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0IHRoYXQgZ2VuZXJhdGVkIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpIHdpbGwgZGlzcmVnYXJkIHRoZSBvcmRlcgorICAgIC8vIG9mIG1hcCBlbnRyaWVzIHdoZW4gY29tcGFyaW5nL2hhc2hpbmcgbWFwIGZpZWxkcy4KKworICAgIC8vIFdlIHVzZSBEeW5hbWljTWVzc2FnZSB0byB0ZXN0IHJlZmxlY3Rpb24gYmFzZWQgZXF1YWxzKCkvaGFzaENvZGUoKS4KKyAgICBNZXNzYWdlIGR5bmFtaWNEZWZhdWx0SW5zdGFuY2UgPQorICAgICAgICBEeW5hbWljTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoVGVzdE1hcC5nZXREZXNjcmlwdG9yKCkpOworICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGYoImludDMyX3RvX2ludDMyX2ZpZWxkIik7CisgICAgCisgICAgTWVzc2FnZS5CdWlsZGVyIGIxID0gZHluYW1pY0RlZmF1bHRJbnN0YW5jZS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgIGIxLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIG5ld01hcEVudHJ5KGIxLCAiaW50MzJfdG9faW50MzJfZmllbGQiLCAxLCAyKSk7CisgICAgYjEuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgbmV3TWFwRW50cnkoYjEsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDMsIDQpKTsKKyAgICBiMS5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCBuZXdNYXBFbnRyeShiMSwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgNSwgNikpOworICAgIE1lc3NhZ2UgbTEgPSBiMS5idWlsZCgpOworICAgIAorICAgIE1lc3NhZ2UuQnVpbGRlciBiMiA9IGR5bmFtaWNEZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgICBiMi5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCBuZXdNYXBFbnRyeShiMiwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgNSwgNikpOworICAgIGIyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIG5ld01hcEVudHJ5KGIyLCAiaW50MzJfdG9faW50MzJfZmllbGQiLCAxLCAyKSk7CisgICAgYjIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgbmV3TWFwRW50cnkoYjIsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDMsIDQpKTsKKyAgICBNZXNzYWdlIG0yID0gYjIuYnVpbGQoKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMobTEsIG0yKTsKKyAgICBhc3NlcnRFcXVhbHMobTEuaGFzaENvZGUoKSwgbTIuaGFzaENvZGUoKSk7CisgICAgCisgICAgLy8gTWFrZSBzdXJlIHdlIGRpZCBjb21wYXJlIG1hcCBmaWVsZHMuCisgICAgYjIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgMCwgbmV3TWFwRW50cnkoYjEsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDAsIDApKTsKKyAgICBtMiA9IGIyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RmFsc2UobTEuZXF1YWxzKG0yKSk7CisgICAgLy8gRG9uJ3QgY2hlY2sgbTEuaGFzaENvZGUoKSAhPSBtMi5oYXNoQ29kZSgpIGJlY2F1c2UgaXQncyBub3QgZ3VhcmFudGVlZAorICAgIC8vIHRvIGJlIGRpZmZlcmVudC4KKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFVua25vd25FbnVtVmFsdWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFVua25vd25FbnVtVmFsdWUuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgVGVzdFVua25vd25FbnVtVmFsdWUubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDIsIDU0MzIxKTsKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBidWlsZGVyLmJ1aWxkKCkudG9CeXRlU3RyaW5nKCk7CisKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBUZXN0TWFwLnBhcnNlRnJvbShkYXRhKTsKKyAgICAvLyBFbnRyaWVzIHdpdGggdW5rbm93biBlbnVtIHZhbHVlcyB3aWxsIGJlIHN0b3JlZCBpbnRvIFVua25vd25GaWVsZFNldCBzbworICAgIC8vIHRoZXJlIGlzIG9ubHkgb25lIGVudHJ5IGluIHRoZSBtYXAuCisgICAgYXNzZXJ0RXF1YWxzKDEsIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkJBUiwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDEpKTsKKyAgICAvLyBVbmtub3duRmllbGRTZXQgc2hvdWxkIG5vdCBiZSBlbXB0eS4KKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmdldFVua25vd25GaWVsZHMoKS5hc01hcCgpLmlzRW1wdHkoKSk7CisgICAgLy8gU2VyaWFsaXppbmcgYW5kIHBhcnNpbmcgc2hvdWxkIHByZXNlcnZlIHRoZSB1bmtub3duIGVudHJ5LgorICAgIGRhdGEgPSBtZXNzYWdlLnRvQnl0ZVN0cmluZygpOworICAgIFRlc3RVbmtub3duRW51bVZhbHVlIG1lc3NhZ2VXaXRoVW5rbm93bkVudW1zID0KKyAgICAgICAgVGVzdFVua25vd25FbnVtVmFsdWUucGFyc2VGcm9tKGRhdGEpOworICAgIGFzc2VydEVxdWFscygyLCBtZXNzYWdlV2l0aFVua25vd25FbnVtcy5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1lc3NhZ2VXaXRoVW5rbm93bkVudW1zLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDEpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg1NDMyMSwgbWVzc2FnZVdpdGhVbmtub3duRW51bXMuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMikuaW50VmFsdWUoKSk7CisgIH0KKworCisgIHB1YmxpYyB2b2lkIHRlc3RSZXF1aXJlZE1lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLnB1dCgwLAorICAgICAgICBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLm5ld0J1aWxkZXIoKS5idWlsZFBhcnRpYWwoKSk7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICBidWlsZGVyLmdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5wdXQoMCwKKyAgICAgICAgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5uZXdCdWlsZGVyKCkuc2V0VmFsdWUoMSkuYnVpbGQoKSk7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaXNJbml0aWFsaXplZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWN1cnNpdmVNYXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0UmVjdXJzaXZlTWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RSZWN1cnNpdmVNYXAubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkucHV0KAorICAgICAgICAxLCBUZXN0UmVjdXJzaXZlTWFwLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgyKS5idWlsZCgpKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLnB1dCgKKyAgICAgICAgMywgVGVzdFJlY3Vyc2l2ZU1hcC5uZXdCdWlsZGVyKCkuc2V0VmFsdWUoNCkuYnVpbGQoKSk7CisgICAgQnl0ZVN0cmluZyBkYXRhID0gYnVpbGRlci5idWlsZCgpLnRvQnl0ZVN0cmluZygpOworCisgICAgVGVzdFJlY3Vyc2l2ZU1hcCBtZXNzYWdlID0gVGVzdFJlY3Vyc2l2ZU1hcC5wYXJzZUZyb20oZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXQoMSkuZ2V0VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIG1lc3NhZ2UuZ2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXQoMykuZ2V0VmFsdWUoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01hcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOGU2N2I3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTWFwVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjE0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yOworaW1wb3J0IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwOworaW1wb3J0IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZTsKK2ltcG9ydCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBVbml0IHRlc3RzIGZvciBtYXAgZmllbGRzLgorICovCitwdWJsaWMgY2xhc3MgTWFwVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgcHJpdmF0ZSB2b2lkIHNldE1hcFZhbHVlcyhUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlcikgeworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDExKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgyLCAyMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMywgMzMpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkucHV0KDEsICIxMSIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLnB1dCgyLCAiMjIiKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5wdXQoMywgIjMzIik7CisKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLnB1dCgxLCBUZXN0VXRpbC50b0J5dGVzKCIxMSIpKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLnB1dCgyLCBUZXN0VXRpbC50b0J5dGVzKCIyMiIpKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLnB1dCgzLCBUZXN0VXRpbC50b0J5dGVzKCIzMyIpKTsKKworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5wdXQoMSwgVGVzdE1hcC5FbnVtVmFsdWUuRk9PKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkucHV0KDIsIFRlc3RNYXAuRW51bVZhbHVlLkJBUik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLnB1dCgzLCBUZXN0TWFwLkVudW1WYWx1ZS5CQVopOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMSwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgxMSkuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMiwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgyMikuYnVpbGQoKSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMywgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgzMykuYnVpbGQoKSk7CisKKyAgICBidWlsZGVyLmdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5wdXQoIjEiLCAxMSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkucHV0KCIyIiwgMjIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnB1dCgiMyIsIDMzKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBWYWx1ZXNTZXQoVGVzdE1hcCBtZXNzYWdlKSB7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMSwgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgxKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMjIsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMikuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMzLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDMpLmludFZhbHVlKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDMsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoIjExIiwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscygiMjIiLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldCgyKSk7CisgICAgYXNzZXJ0RXF1YWxzKCIzMyIsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0KDMpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiMTEiKSwgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldCgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RVdGlsLnRvQnl0ZXMoIjIyIiksIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXQoMikpOworICAgIGFzc2VydEVxdWFscyhUZXN0VXRpbC50b0J5dGVzKCIzMyIpLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0KDMpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5GT08sIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkJBUiwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDIpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuQkFaLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoMykpOworCisgICAgYXNzZXJ0RXF1YWxzKDMsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoMSkuZ2V0VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIyLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoMikuZ2V0VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMzLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoMykuZ2V0VmFsdWUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMSwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXQoIjEiKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMjIsIG1lc3NhZ2UuZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0KCIyIikuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMzLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldCgiMyIpLmludFZhbHVlKCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHVwZGF0ZU1hcFZhbHVlcyhUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlcikgeworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDExMSk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5yZW1vdmUoMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoNCwgNDQpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkucHV0KDEsICIxMTEiKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5yZW1vdmUoMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkucHV0KDQsICI0NCIpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5wdXQoMSwgVGVzdFV0aWwudG9CeXRlcygiMTExIikpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkucmVtb3ZlKDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkucHV0KDQsIFRlc3RVdGlsLnRvQnl0ZXMoIjQ0IikpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLnB1dCgxLCBUZXN0TWFwLkVudW1WYWx1ZS5CQVIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5yZW1vdmUoMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLnB1dCg0LCBUZXN0TWFwLkVudW1WYWx1ZS5RVVgpOworCisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgMSwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgxMTEpLmJ1aWxkKCkpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5yZW1vdmUoMik7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLnB1dCgKKyAgICAgICAgNCwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSg0NCkuYnVpbGQoKSk7CisKKyAgICBidWlsZGVyLmdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5wdXQoIjEiLCAxMTEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnJlbW92ZSgiMiIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLnB1dCgiNCIsIDQ0KTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBWYWx1ZXNVcGRhdGVkKFRlc3RNYXAgbWVzc2FnZSkgeworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTExLCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDEpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgzKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoNCkuaW50VmFsdWUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygiMTExIiwgbWVzc2FnZS5nZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscygiMzMiLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKCI0NCIsIG1lc3NhZ2UuZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0KDQpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiMTExIiksIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscyhUZXN0VXRpbC50b0J5dGVzKCIzMyIpLCBtZXNzYWdlLmdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0KDMpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdFV0aWwudG9CeXRlcygiNDQiKSwgbWVzc2FnZS5nZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldCg0KSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuQkFSLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5CQVosIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLlFVWCwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDQpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxMTEsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCgxKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCgzKS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDQsIG1lc3NhZ2UuZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldCg0KS5nZXRWYWx1ZSgpKTsKKworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDExMSwgbWVzc2FnZS5nZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXQoIjEiKS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzMsIG1lc3NhZ2UuZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0KCIzIikuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ0LCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldCgiNCIpLmludFZhbHVlKCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydE1hcFZhbHVlc0NsZWFyZWQoVGVzdE1hcCBtZXNzYWdlKSB7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9TdHJpbmdGaWVsZCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0SW50MzJUb0J5dGVzRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFN0cmluZ1RvSW50MzJGaWVsZCgpLnNpemUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0dGVyc0FuZFNldHRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIFRlc3RNYXAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRNYXBWYWx1ZXNDbGVhcmVkKG1lc3NhZ2UpOworCisgICAgYnVpbGRlciA9IG1lc3NhZ2UudG9CdWlsZGVyKCk7CisgICAgc2V0TWFwVmFsdWVzKGJ1aWxkZXIpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0TWFwVmFsdWVzU2V0KG1lc3NhZ2UpOworCisgICAgYnVpbGRlciA9IG1lc3NhZ2UudG9CdWlsZGVyKCk7CisgICAgdXBkYXRlTWFwVmFsdWVzKGJ1aWxkZXIpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0TWFwVmFsdWVzVXBkYXRlZChtZXNzYWdlKTsKKworICAgIGJ1aWxkZXIgPSBtZXNzYWdlLnRvQnVpbGRlcigpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydE1hcFZhbHVlc0NsZWFyZWQobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXplQW5kUGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIHNldE1hcFZhbHVlcyhidWlsZGVyKTsKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0U2VyaWFsaXplZFNpemUoKSwgbWVzc2FnZS50b0J5dGVTdHJpbmcoKS5zaXplKCkpOworICAgIG1lc3NhZ2UgPSBUZXN0TWFwLlBBUlNFUi5wYXJzZUZyb20obWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgICAgYXNzZXJ0TWFwVmFsdWVzU2V0KG1lc3NhZ2UpOworCisgICAgYnVpbGRlciA9IG1lc3NhZ2UudG9CdWlsZGVyKCk7CisgICAgdXBkYXRlTWFwVmFsdWVzKGJ1aWxkZXIpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0U2VyaWFsaXplZFNpemUoKSwgbWVzc2FnZS50b0J5dGVTdHJpbmcoKS5zaXplKCkpOworICAgIG1lc3NhZ2UgPSBUZXN0TWFwLlBBUlNFUi5wYXJzZUZyb20obWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgICAgYXNzZXJ0TWFwVmFsdWVzVXBkYXRlZChtZXNzYWdlKTsKKworICAgIGJ1aWxkZXIgPSBtZXNzYWdlLnRvQnVpbGRlcigpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCksIG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkuc2l6ZSgpKTsKKyAgICBtZXNzYWdlID0gVGVzdE1hcC5QQVJTRVIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydE1hcFZhbHVlc0NsZWFyZWQobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgVGVzdE1hcC5CdWlsZGVyIG90aGVyID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgb3RoZXIubWVyZ2VGcm9tKG1lc3NhZ2UpOworICAgIGFzc2VydE1hcFZhbHVlc1NldChvdGhlci5idWlsZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNBbmRIYXNoQ29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3QgdGhhdCBnZW5lcmF0ZWQgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkgd2lsbCBkaXNyZWdhcmQgdGhlIG9yZGVyCisgICAgLy8gb2YgbWFwIGVudHJpZXMgd2hlbiBjb21wYXJpbmcvaGFzaGluZyBtYXAgZmllbGRzLgorCisgICAgLy8gV2UgY2FuJ3QgY29udHJvbCB0aGUgb3JkZXIgb2YgZWxlbWVudHMgaW4gYSBIYXNoTWFwLiBUaGUgYmVzdCB3ZSBjYW4gZG8KKyAgICAvLyBoZXJlIGlzIHRvIGFkZCBlbGVtZW50cyBpbiBkaWZmZXJlbnQgb3JkZXIuCisgICAgVGVzdE1hcC5CdWlsZGVyIGIxID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgYjEuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDIpOworICAgIGIxLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgzLCA0KTsKKyAgICBiMS5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoNSwgNik7CisgICAgVGVzdE1hcCBtMSA9IGIxLmJ1aWxkKCk7CisKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYjIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBiMi5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoNSwgNik7CisgICAgYjIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDIpOworICAgIGIyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgzLCA0KTsKKyAgICBUZXN0TWFwIG0yID0gYjIuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscyhtMSwgbTIpOworICAgIGFzc2VydEVxdWFscyhtMS5oYXNoQ29kZSgpLCBtMi5oYXNoQ29kZSgpKTsKKworICAgIC8vIE1ha2Ugc3VyZSB3ZSBkaWQgY29tcGFyZSBtYXAgZmllbGRzLgorICAgIGIyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgxLCAwKTsKKyAgICBtMiA9IGIyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RmFsc2UobTEuZXF1YWxzKG0yKSk7CisgICAgLy8gRG9uJ3QgY2hlY2sgbTEuaGFzaENvZGUoKSAhPSBtMi5oYXNoQ29kZSgpIGJlY2F1c2UgaXQncyBub3QgZ3VhcmFudGVlZAorICAgIC8vIHRvIGJlIGRpZmZlcmVudC4KKworICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgYi8xODU0OTE5MDogaWYgYSBtYXAgaXMgYSBzdWJzZXQgb2YgdGhlIG90aGVyIG1hcCwKKyAgICAvLyBlcXVhbHMoKSBzaG91bGQgcmV0dXJuIGZhbHNlLgorICAgIGIyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnJlbW92ZSgxKTsKKyAgICBtMiA9IGIyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RmFsc2UobTEuZXF1YWxzKG0yKSk7CisgICAgYXNzZXJ0RmFsc2UobTIuZXF1YWxzKG0xKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmVzdGVkQnVpbGRlck9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbigpIHsKKyAgICBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLkJ1aWxkZXIgcGFyZW50ID0KKyAgICAgICAgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5uZXdCdWlsZGVyKCk7CisgICAgcGFyZW50LmdldE9wdGlvbmFsTWVzc2FnZUJ1aWxkZXIoKS5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgMik7CisgICAgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBtZXNzYWdlID0gcGFyZW50LmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxNZXNzYWdlKCkuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMSkuaW50VmFsdWUoKSk7CisKKyAgICAvLyBNYWtlIGEgY2hhbmdlIHVzaW5nIG5lc3RlZCBidWlsZGVyLgorICAgIHBhcmVudC5nZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDMpOworCisgICAgLy8gU2hvdWxkIGJlIGFibGUgdG8gb2JzZXJ2ZSB0aGUgY2hhbmdlLgorICAgIG1lc3NhZ2UgPSBwYXJlbnQuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5nZXRPcHRpb25hbE1lc3NhZ2UoKS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgxKS5pbnRWYWx1ZSgpKTsKKworICAgIC8vIE1ha2UgYW5vdGhlciBjaGFuZ2UgdXNpbmcgbWVyZ2VGcm9tKCkKKyAgICBUZXN0TWFwLkJ1aWxkZXIgb3RoZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBvdGhlci5nZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5wdXQoMSwgNCk7CisgICAgcGFyZW50LmdldE9wdGlvbmFsTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20ob3RoZXIuYnVpbGQoKSk7CisKKyAgICAvLyBTaG91bGQgYmUgYWJsZSB0byBvYnNlcnZlIHRoZSBjaGFuZ2UuCisgICAgbWVzc2FnZSA9IHBhcmVudC5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyg0LCBtZXNzYWdlLmdldE9wdGlvbmFsTWVzc2FnZSgpLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDEpLmludFZhbHVlKCkpOworCisgICAgLy8gTWFrZSB5ZXQgYW5vdGhlciBjaGFuZ2UgYnkgY2xlYXJpbmcgdGhlIG5lc3RlZCBidWlsZGVyLgorICAgIHBhcmVudC5nZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkuY2xlYXIoKTsKKworICAgIC8vIFNob3VsZCBiZSBhYmxlIHRvIG9ic2VydmUgdGhlIGNoYW5nZS4KKyAgICBtZXNzYWdlID0gcGFyZW50LmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxNZXNzYWdlKCkuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5zaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5lc3RlZEJ1aWxkZXJPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25SZWZsZWN0aW9uKCkgeworICAgIEZpZWxkRGVzY3JpcHRvciBpbnRNYXBGaWVsZCA9IGYoImludDMyX3RvX2ludDMyX2ZpZWxkIik7CisgICAgLy8gQ3JlYXRlIGFuIG91dGVyIG1lc3NhZ2UgYnVpbGRlciB3aXRoIG5lc3RlZCBidWlsZGVyLgorICAgIFRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24uQnVpbGRlciBwYXJlbnRCdWlsZGVyID0KKyAgICAgICAgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5uZXdCdWlsZGVyKCk7CisgICAgVGVzdE1hcC5CdWlsZGVyIHRlc3RNYXBCdWlsZGVyID0gcGFyZW50QnVpbGRlci5nZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCk7CisKKyAgICAvLyBDcmVhdGUgYSBtYXAgZW50cnkgbWVzc2FnZS4KKyAgICBUZXN0TWFwLkJ1aWxkZXIgZW50cnlCdWlsZGVyID0gVGVzdE1hcC5uZXdCdWlsZGVyKCk7CisgICAgZW50cnlCdWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgxLCAxKTsKKworICAgIC8vIFB1dCB0aGUgZW50cnkgaW50byB0aGUgbmVzdGVkIGJ1aWxkZXIuCisgICAgdGVzdE1hcEJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgaW50TWFwRmllbGQsIGVudHJ5QnVpbGRlci5nZXRSZXBlYXRlZEZpZWxkKGludE1hcEZpZWxkLCAwKSk7CisKKyAgICAvLyBTaG91bGQgYmUgYWJsZSB0byBvYnNlcnZlIHRoZSBjaGFuZ2UuCisgICAgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBtZXNzYWdlID0gcGFyZW50QnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygxLCBtZXNzYWdlLmdldE9wdGlvbmFsTWVzc2FnZSgpLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKworICAgIC8vIENoYW5nZSB0aGUgZW50cnkgdmFsdWUuCisgICAgZW50cnlCdWlsZGVyLmdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLnB1dCgxLCA0KTsKKyAgICB0ZXN0TWFwQnVpbGRlciA9IHBhcmVudEJ1aWxkZXIuZ2V0T3B0aW9uYWxNZXNzYWdlQnVpbGRlcigpOworICAgIHRlc3RNYXBCdWlsZGVyLnNldFJlcGVhdGVkRmllbGQoCisgICAgICAgIGludE1hcEZpZWxkLCAwLCBlbnRyeUJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZChpbnRNYXBGaWVsZCwgMCkpOworCisgICAgLy8gU2hvdWxkIGJlIGFibGUgdG8gb2JzZXJ2ZSB0aGUgY2hhbmdlLgorICAgIG1lc3NhZ2UgPSBwYXJlbnRCdWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDQsCisgICAgICAgIG1lc3NhZ2UuZ2V0T3B0aW9uYWxNZXNzYWdlKCkuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMSkuaW50VmFsdWUoKSk7CisKKyAgICAvLyBDbGVhciB0aGUgbmVzdGVkIGJ1aWxkZXIuCisgICAgdGVzdE1hcEJ1aWxkZXIgPSBwYXJlbnRCdWlsZGVyLmdldE9wdGlvbmFsTWVzc2FnZUJ1aWxkZXIoKTsKKyAgICB0ZXN0TWFwQnVpbGRlci5jbGVhckZpZWxkKGludE1hcEZpZWxkKTsKKworICAgIC8vIFNob3VsZCBiZSBhYmxlIHRvIG9ic2VydmUgdGhlIGNoYW5nZS4KKyAgICBtZXNzYWdlID0gcGFyZW50QnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldE9wdGlvbmFsTWVzc2FnZSgpLmdldEludDMyVG9JbnQzMkZpZWxkKCkuc2l6ZSgpKTsKKyAgfQorCisgIC8vIFRoZSBmb2xsb3dpbmcgbWV0aG9kcyBhcmUgdXNlZCB0byB0ZXN0IHJlZmxlY3Rpb24gQVBJLgorCisgIHByaXZhdGUgc3RhdGljIEZpZWxkRGVzY3JpcHRvciBmKFN0cmluZyBuYW1lKSB7CisgICAgcmV0dXJuIFRlc3RNYXAuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZShuYW1lKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKE1lc3NhZ2UgbWFwRW50cnksIFN0cmluZyBuYW1lKSB7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gbWFwRW50cnkuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgcmV0dXJuIG1hcEVudHJ5LmdldEZpZWxkKGZpZWxkKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1lc3NhZ2UuQnVpbGRlciBzZXRGaWVsZFZhbHVlKAorICAgICAgTWVzc2FnZS5CdWlsZGVyIG1hcEVudHJ5LCBTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gbWFwRW50cnkuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgbWFwRW50cnkuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKKyAgICByZXR1cm4gbWFwRW50cnk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEhhc01hcFZhbHVlcyhNZXNzYWdlIG1lc3NhZ2UsIFN0cmluZyBuYW1lLCBNYXA8PywgPz4gdmFsdWVzKSB7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZihuYW1lKTsKKyAgICBmb3IgKE9iamVjdCBlbnRyeSA6IChMaXN0PD8+KSBtZXNzYWdlLmdldEZpZWxkKGZpZWxkKSkgeworICAgICAgTWVzc2FnZSBtYXBFbnRyeSA9IChNZXNzYWdlKSBlbnRyeTsKKyAgICAgIE9iamVjdCBrZXkgPSBnZXRGaWVsZFZhbHVlKG1hcEVudHJ5LCAia2V5Iik7CisgICAgICBPYmplY3QgdmFsdWUgPSBnZXRGaWVsZFZhbHVlKG1hcEVudHJ5LCAidmFsdWUiKTsKKyAgICAgIGFzc2VydFRydWUodmFsdWVzLmNvbnRhaW5zS2V5KGtleSkpOworICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCB2YWx1ZXMuZ2V0KGtleSkpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHModmFsdWVzLnNpemUoKSwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZmllbGQpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGZpZWxkKTsgaSsrKSB7CisgICAgICBNZXNzYWdlIG1hcEVudHJ5ID0gKE1lc3NhZ2UpIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaSk7CisgICAgICBPYmplY3Qga2V5ID0gZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgImtleSIpOworICAgICAgT2JqZWN0IHZhbHVlID0gZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgInZhbHVlIik7CisgICAgICBhc3NlcnRUcnVlKHZhbHVlcy5jb250YWluc0tleShrZXkpKTsKKyAgICAgIGFzc2VydEVxdWFscyh2YWx1ZSwgdmFsdWVzLmdldChrZXkpKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyA8S2V5VHlwZSwgVmFsdWVUeXBlPgorICBNZXNzYWdlIG5ld01hcEVudHJ5KE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLCBTdHJpbmcgbmFtZSwgS2V5VHlwZSBrZXksIFZhbHVlVHlwZSB2YWx1ZSkgeworICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGJ1aWxkZXIuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgTWVzc2FnZS5CdWlsZGVyIGVudHJ5QnVpbGRlciA9IGJ1aWxkZXIubmV3QnVpbGRlckZvckZpZWxkKGZpZWxkKTsKKyAgICBGaWVsZERlc2NyaXB0b3Iga2V5RmllbGQgPSBlbnRyeUJ1aWxkZXIuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5maW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIEZpZWxkRGVzY3JpcHRvciB2YWx1ZUZpZWxkID0gZW50cnlCdWlsZGVyLmdldERlc2NyaXB0b3JGb3JUeXBlKCkuZmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIGVudHJ5QnVpbGRlci5zZXRGaWVsZChrZXlGaWVsZCwga2V5KTsKKyAgICBlbnRyeUJ1aWxkZXIuc2V0RmllbGQodmFsdWVGaWVsZCwgdmFsdWUpOworICAgIHJldHVybiBlbnRyeUJ1aWxkZXIuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0TWFwVmFsdWVzKE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyLCBTdHJpbmcgbmFtZSwgTWFwPD8sID8+IHZhbHVlcykgeworICAgIExpc3Q8TWVzc2FnZT4gZW50cnlMaXN0ID0gbmV3IEFycmF5TGlzdDxNZXNzYWdlPigpOworICAgIGZvciAoTWFwLkVudHJ5PD8sID8+IGVudHJ5IDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKKyAgICAgIGVudHJ5TGlzdC5hZGQobmV3TWFwRW50cnkoYnVpbGRlciwgbmFtZSwgZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICB9CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gYnVpbGRlci5nZXREZXNjcmlwdG9yRm9yVHlwZSgpLmZpbmRGaWVsZEJ5TmFtZShuYW1lKTsKKyAgICBidWlsZGVyLnNldEZpZWxkKGZpZWxkLCBlbnRyeUxpc3QpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgPEtleVR5cGUsIFZhbHVlVHlwZT4KKyAgTWFwPEtleVR5cGUsIFZhbHVlVHlwZT4gbWFwRm9yVmFsdWVzKAorICAgICAgS2V5VHlwZSBrZXkxLCBWYWx1ZVR5cGUgdmFsdWUxLCBLZXlUeXBlIGtleTIsIFZhbHVlVHlwZSB2YWx1ZTIpIHsKKyAgICBNYXA8S2V5VHlwZSwgVmFsdWVUeXBlPiBtYXAgPSBuZXcgSGFzaE1hcDxLZXlUeXBlLCBWYWx1ZVR5cGU+KCk7CisgICAgbWFwLnB1dChrZXkxLCB2YWx1ZTEpOworICAgIG1hcC5wdXQoa2V5MiwgdmFsdWUyKTsKKyAgICByZXR1cm4gbWFwOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlZmxlY3Rpb25BcGkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBJbiByZWZsZWN0aW9uIEFQSSwgbWFwIGZpZWxkcyBhcmUganVzdCByZXBlYXRlZCBtZXNzYWdlIGZpZWxkcy4KKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDEsIDIpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkucHV0KDMsIDQpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5wdXQoCisgICAgICAgIDExLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDIyKS5idWlsZCgpKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkucHV0KAorICAgICAgICAzMywgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSg0NCkuYnVpbGQoKSk7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgLy8gVGVzdCBnZXRGaWVsZCgpLCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoKSwgZ2V0UmVwZWF0ZWRGaWVsZCgpLgorICAgIGFzc2VydEhhc01hcFZhbHVlcyhtZXNzYWdlLCAiaW50MzJfdG9faW50MzJfZmllbGQiLAorICAgICAgICBtYXBGb3JWYWx1ZXMoMSwgMiwgMywgNCkpOworICAgIGFzc2VydEhhc01hcFZhbHVlcyhtZXNzYWdlLCAiaW50MzJfdG9fbWVzc2FnZV9maWVsZCIsCisgICAgICAgIG1hcEZvclZhbHVlcygKKyAgICAgICAgICAgIDExLCBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDIyKS5idWlsZCgpLAorICAgICAgICAgICAgMzMsIE1lc3NhZ2VWYWx1ZS5uZXdCdWlsZGVyKCkuc2V0VmFsdWUoNDQpLmJ1aWxkKCkpKTsKKworICAgIC8vIFRlc3QgY2xlYXJGaWVsZCgpCisgICAgYnVpbGRlci5jbGVhckZpZWxkKGYoImludDMyX3RvX2ludDMyX2ZpZWxkIikpOworICAgIGJ1aWxkZXIuY2xlYXJGaWVsZChmKCJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIikpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5zaXplKCkpOworCisgICAgLy8gVGVzdCBzZXRGaWVsZCgpCisgICAgc2V0TWFwVmFsdWVzKGJ1aWxkZXIsICJpbnQzMl90b19pbnQzMl9maWVsZCIsCisgICAgICAgIG1hcEZvclZhbHVlcygxMSwgMjIsIDMzLCA0NCkpOworICAgIHNldE1hcFZhbHVlcyhidWlsZGVyLCAiaW50MzJfdG9fbWVzc2FnZV9maWVsZCIsCisgICAgICAgIG1hcEZvclZhbHVlcygKKyAgICAgICAgICAgIDExMSwgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgyMjIpLmJ1aWxkKCksCisgICAgICAgICAgICAzMzMsIE1lc3NhZ2VWYWx1ZS5uZXdCdWlsZGVyKCkuc2V0VmFsdWUoNDQ0KS5idWlsZCgpKSk7CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMjIsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMTEpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg0NCwgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCgzMykuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIyMiwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDExMSkuZ2V0VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ0NCwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDMzMykuZ2V0VmFsdWUoKSk7CisKKyAgICAvLyBUZXN0IGFkZFJlcGVhdGVkRmllbGQKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRmllbGQoZigiaW50MzJfdG9faW50MzJfZmllbGQiKSwKKyAgICAgICAgbmV3TWFwRW50cnkoYnVpbGRlciwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgNTUsIDY2KSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoImludDMyX3RvX21lc3NhZ2VfZmllbGQiKSwKKyAgICAgICAgbmV3TWFwRW50cnkoYnVpbGRlciwgImludDMyX3RvX21lc3NhZ2VfZmllbGQiLCA1NTUsCisgICAgICAgICAgICBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpLnNldFZhbHVlKDY2NikuYnVpbGQoKSkpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDY2LCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDU1KS5pbnRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNjY2LCBtZXNzYWdlLmdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXQoNTU1KS5nZXRWYWx1ZSgpKTsKKworICAgIC8vIFRlc3QgYWRkUmVwZWF0ZWRGaWVsZCAob3ZlcnJpZGluZyBleGlzdGluZyB2YWx1ZXMpCisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoImludDMyX3RvX2ludDMyX2ZpZWxkIiksCisgICAgICAgIG5ld01hcEVudHJ5KGJ1aWxkZXIsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDU1LCA1NSkpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmKCJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIiksCisgICAgICAgIG5ld01hcEVudHJ5KGJ1aWxkZXIsICJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIiwgNTU1LAorICAgICAgICAgICAgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSg1NTUpLmJ1aWxkKCkpKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyg1NSwgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCg1NSkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU1NSwgbWVzc2FnZS5nZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0KDU1NSkuZ2V0VmFsdWUoKSk7CisKKyAgICAvLyBUZXN0IHNldFJlcGVhdGVkRmllbGQKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoImludDMyX3RvX2ludDMyX2ZpZWxkIikpOyBpKyspIHsKKyAgICAgIE1lc3NhZ2UgbWFwRW50cnkgPSAoTWVzc2FnZSkgYnVpbGRlci5nZXRSZXBlYXRlZEZpZWxkKGYoImludDMyX3RvX2ludDMyX2ZpZWxkIiksIGkpOworICAgICAgaW50IG9sZEtleSA9ICgoSW50ZWdlcikgZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgImtleSIpKS5pbnRWYWx1ZSgpOworICAgICAgaW50IG9sZFZhbHVlID0gKChJbnRlZ2VyKSBnZXRGaWVsZFZhbHVlKG1hcEVudHJ5LCAidmFsdWUiKSkuaW50VmFsdWUoKTsKKyAgICAgIC8vIFN3YXAga2V5IHdpdGggdmFsdWUgZm9yIGVhY2ggZW50cnkuCisgICAgICBNZXNzYWdlLkJ1aWxkZXIgbWFwRW50cnlCdWlsZGVyID0gbWFwRW50cnkudG9CdWlsZGVyKCk7CisgICAgICBzZXRGaWVsZFZhbHVlKG1hcEVudHJ5QnVpbGRlciwgImtleSIsIG9sZFZhbHVlKTsKKyAgICAgIHNldEZpZWxkVmFsdWUobWFwRW50cnlCdWlsZGVyLCAidmFsdWUiLCBvbGRLZXkpOworICAgICAgYnVpbGRlci5zZXRSZXBlYXRlZEZpZWxkKGYoImludDMyX3RvX2ludDMyX2ZpZWxkIiksIGksIG1hcEVudHJ5QnVpbGRlci5idWlsZCgpKTsKKyAgICB9CisgICAgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTEsIG1lc3NhZ2UuZ2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXQoMjIpLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscygzMywgbWVzc2FnZS5nZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldCg0NCkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU1LCBtZXNzYWdlLmdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0KDU1KS5pbnRWYWx1ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RUZXh0Rm9ybWF0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBzZXRNYXBWYWx1ZXMoYnVpbGRlcik7CisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgU3RyaW5nIHRleHREYXRhID0gVGV4dEZvcm1hdC5wcmludFRvU3RyaW5nKG1lc3NhZ2UpOworCisgICAgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIFRleHRGb3JtYXQubWVyZ2UodGV4dERhdGEsIGJ1aWxkZXIpOworICAgIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRNYXBWYWx1ZXNTZXQobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY01lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIHNldE1hcFZhbHVlcyhidWlsZGVyKTsKKyAgICBUZXN0TWFwIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisKKyAgICBNZXNzYWdlIGR5bmFtaWNEZWZhdWx0SW5zdGFuY2UgPQorICAgICAgICBEeW5hbWljTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoVGVzdE1hcC5nZXREZXNjcmlwdG9yKCkpOworICAgIE1lc3NhZ2UgZHluYW1pY01lc3NhZ2UgPSBkeW5hbWljRGVmYXVsdEluc3RhbmNlCisgICAgICAgIC5uZXdCdWlsZGVyRm9yVHlwZSgpLm1lcmdlRnJvbShtZXNzYWdlLnRvQnl0ZVN0cmluZygpKS5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIGR5bmFtaWNNZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5oYXNoQ29kZSgpLCBkeW5hbWljTWVzc2FnZS5oYXNoQ29kZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZWZsZWN0aW9uRXF1YWxzQW5kSGFzaENvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0IHRoYXQgZ2VuZXJhdGVkIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpIHdpbGwgZGlzcmVnYXJkIHRoZSBvcmRlcgorICAgIC8vIG9mIG1hcCBlbnRyaWVzIHdoZW4gY29tcGFyaW5nL2hhc2hpbmcgbWFwIGZpZWxkcy4KKworICAgIC8vIFdlIHVzZSBEeW5hbWljTWVzc2FnZSB0byB0ZXN0IHJlZmxlY3Rpb24gYmFzZWQgZXF1YWxzKCkvaGFzaENvZGUoKS4KKyAgICBNZXNzYWdlIGR5bmFtaWNEZWZhdWx0SW5zdGFuY2UgPQorICAgICAgICBEeW5hbWljTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoVGVzdE1hcC5nZXREZXNjcmlwdG9yKCkpOworICAgIEZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGYoImludDMyX3RvX2ludDMyX2ZpZWxkIik7CisKKyAgICBNZXNzYWdlLkJ1aWxkZXIgYjEgPSBkeW5hbWljRGVmYXVsdEluc3RhbmNlLm5ld0J1aWxkZXJGb3JUeXBlKCk7CisgICAgYjEuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgbmV3TWFwRW50cnkoYjEsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDEsIDIpKTsKKyAgICBiMS5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCBuZXdNYXBFbnRyeShiMSwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgMywgNCkpOworICAgIGIxLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIG5ld01hcEVudHJ5KGIxLCAiaW50MzJfdG9faW50MzJfZmllbGQiLCA1LCA2KSk7CisgICAgTWVzc2FnZSBtMSA9IGIxLmJ1aWxkKCk7CisKKyAgICBNZXNzYWdlLkJ1aWxkZXIgYjIgPSBkeW5hbWljRGVmYXVsdEluc3RhbmNlLm5ld0J1aWxkZXJGb3JUeXBlKCk7CisgICAgYjIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgbmV3TWFwRW50cnkoYjIsICJpbnQzMl90b19pbnQzMl9maWVsZCIsIDUsIDYpKTsKKyAgICBiMi5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCBuZXdNYXBFbnRyeShiMiwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgMSwgMikpOworICAgIGIyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIG5ld01hcEVudHJ5KGIyLCAiaW50MzJfdG9faW50MzJfZmllbGQiLCAzLCA0KSk7CisgICAgTWVzc2FnZSBtMiA9IGIyLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRFcXVhbHMobTEsIG0yKTsKKyAgICBhc3NlcnRFcXVhbHMobTEuaGFzaENvZGUoKSwgbTIuaGFzaENvZGUoKSk7CisKKyAgICAvLyBNYWtlIHN1cmUgd2UgZGlkIGNvbXBhcmUgbWFwIGZpZWxkcy4KKyAgICBiMi5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCAwLCBuZXdNYXBFbnRyeShiMSwgImludDMyX3RvX2ludDMyX2ZpZWxkIiwgMCwgMCkpOworICAgIG0yID0gYjIuYnVpbGQoKTsKKyAgICBhc3NlcnRGYWxzZShtMS5lcXVhbHMobTIpKTsKKyAgICAvLyBEb24ndCBjaGVjayBtMS5oYXNoQ29kZSgpICE9IG0yLmhhc2hDb2RlKCkgYmVjYXVzZSBpdCdzIG5vdCBndWFyYW50ZWVkCisgICAgLy8gdG8gYmUgZGlmZmVyZW50LgorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFVua25vd25FbnVtVmFsdWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcC5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkVmFsdWUoKS5wdXQoMCwgMCk7CisgICAgYnVpbGRlci5nZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZFZhbHVlKCkucHV0KDEsIDEpOworICAgIGJ1aWxkZXIuZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGRWYWx1ZSgpLnB1dCgyLCAxMDAwKTsgIC8vIHVua25vd24gdmFsdWUuCisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKFRlc3RNYXAuRW51bVZhbHVlLkZPTywKKyAgICAgICAgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE1hcC5FbnVtVmFsdWUuQkFSLAorICAgICAgICBtZXNzYWdlLmdldEludDMyVG9FbnVtRmllbGQoKS5nZXQoMSkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TWFwLkVudW1WYWx1ZS5VTlJFQ09HTklaRUQsCisgICAgICAgIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZCgpLmdldCgyKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEwMDAsIG1lc3NhZ2UuZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlKCkuZ2V0KDIpLmludFZhbHVlKCkpOworCisgICAgLy8gVW5rbm93biBlbnVtIHZhbHVlcyBzaG91bGQgYmUgcHJlc2VydmVkIGFmdGVyOgorICAgIC8vICAgMS4gU2VyaWFsaXphdGlvbiBhbmQgcGFyc2luZy4KKyAgICAvLyAgIDIuIHRvQnVpbGQoKS4KKyAgICAvLyAgIDMuIG1lcmdlRnJvbSgpLgorICAgIG1lc3NhZ2UgPSBUZXN0TWFwLnBhcnNlRnJvbShtZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTAwMCwgbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkVmFsdWUoKS5nZXQoMikuaW50VmFsdWUoKSk7CisgICAgYnVpbGRlciA9IG1lc3NhZ2UudG9CdWlsZGVyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEwMDAsIGJ1aWxkZXIuZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlKCkuZ2V0KDIpLmludFZhbHVlKCkpOworICAgIGJ1aWxkZXIgPSBUZXN0TWFwLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20obWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKDEwMDAsIGJ1aWxkZXIuZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlKCkuZ2V0KDIpLmludFZhbHVlKCkpOworCisgICAgLy8gaGFzaENvZGUoKS9lcXVhbHMoKSBzaG91bGQgdGFrZSB1bmtub3duIGVudW0gdmFsdWVzIGludG8gYWNjb3VudC4KKyAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkVmFsdWUoKS5wdXQoMiwgMTAwMSk7CisgICAgVGVzdE1hcCBtZXNzYWdlMiA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc2hDb2RlKCkgPT0gbWVzc2FnZTIuaGFzaENvZGUoKSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5lcXVhbHMobWVzc2FnZTIpKTsKKyAgICAvLyBVbmtub3duIHZhbHVlcyB3aWxsIGJlIGNvbnZlcnRlZCB0byBVTlJFQ09HTklaRUQgc28gdGhlIHJlc3VsdGVkIGVudW0gbWFwCisgICAgLy8gc2hvdWxkIGJlIHRoZSBzYW1lLgorICAgIGFzc2VydFRydWUobWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkKCkuZXF1YWxzKG1lc3NhZ2UyLmdldEludDMyVG9FbnVtRmllbGQoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFVua25vd25FbnVtVmFsdWVzSW5SZWZsZWN0aW9uQXBpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gVGVzdE1hcC5nZXREZXNjcmlwdG9yKCk7CisgICAgRW51bURlc2NyaXB0b3IgZW51bURlc2NyaXB0b3IgPSBUZXN0TWFwLkVudW1WYWx1ZS5nZXREZXNjcmlwdG9yKCk7CisgICAgRmllbGREZXNjcmlwdG9yIGZpZWxkID0gZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoImludDMyX3RvX2VudW1fZmllbGQiKTsKKworICAgIE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBkYXRhID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICBkYXRhLnB1dCgwLCAwKTsKKyAgICBkYXRhLnB1dCgxLCAxKTsKKyAgICBkYXRhLnB1dCgyLCAxMDAwKTsgIC8vIHVua25vd24gdmFsdWUuCisKKyAgICBUZXN0TWFwLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNYXAubmV3QnVpbGRlcigpOworICAgIGZvciAoTWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+IGVudHJ5IDogZGF0YS5lbnRyeVNldCgpKSB7CisgICAgICBidWlsZGVyLmdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkVmFsdWUoKS5wdXQoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKworICAgIC8vIFRyeSB0byByZWFkIHVua25vd24gZW51bSB2YWx1ZXMgdXNpbmcgcmVmbGVjdGlvbiBBUEkuCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWlsZGVyLmdldFJlcGVhdGVkRmllbGRDb3VudChmaWVsZCk7IGkrKykgeworICAgICAgTWVzc2FnZSBtYXBFbnRyeSA9IChNZXNzYWdlKSBidWlsZGVyLmdldFJlcGVhdGVkRmllbGQoZmllbGQsIGkpOworICAgICAgaW50IGtleSA9ICgoSW50ZWdlcikgZ2V0RmllbGRWYWx1ZShtYXBFbnRyeSwgImtleSIpKS5pbnRWYWx1ZSgpOworICAgICAgaW50IHZhbHVlID0gKChFbnVtVmFsdWVEZXNjcmlwdG9yKSBnZXRGaWVsZFZhbHVlKG1hcEVudHJ5LCAidmFsdWUiKSkuZ2V0TnVtYmVyKCk7CisgICAgICBhc3NlcnRFcXVhbHMoZGF0YS5nZXQoa2V5KS5pbnRWYWx1ZSgpLCB2YWx1ZSk7CisgICAgICBNZXNzYWdlLkJ1aWxkZXIgbWFwRW50cnlCdWlsZGVyID0gbWFwRW50cnkudG9CdWlsZGVyKCk7CisgICAgICAvLyBJbmNyZWFzZSB0aGUgdmFsdWUgYnkgMS4KKyAgICAgIHNldEZpZWxkVmFsdWUobWFwRW50cnlCdWlsZGVyLCAidmFsdWUiLAorICAgICAgICAgIGVudW1EZXNjcmlwdG9yLmZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24odmFsdWUgKyAxKSk7CisgICAgICBidWlsZGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGksIG1hcEVudHJ5QnVpbGRlci5idWlsZCgpKTsKKyAgICB9CisKKyAgICAvLyBWZXJpZnkgdGhhdCBlbnVtIHZhbHVlcyBoYXZlIGJlZW4gc3VjY2Vzc2Z1bGx5IHVwZGF0ZWQuCisgICAgVGVzdE1hcCBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIGZvciAoTWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+IGVudHJ5IDogbWVzc2FnZS5nZXRJbnQzMlRvRW51bUZpZWxkVmFsdWUoKS5lbnRyeVNldCgpKSB7CisgICAgICBhc3NlcnRFcXVhbHMoZGF0YS5nZXQoZW50cnkuZ2V0S2V5KCkpICsgMSwgZW50cnkuZ2V0VmFsdWUoKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL01lc3NhZ2VUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiY2QzYTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9NZXNzYWdlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZDsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ247CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIE1pc2MuIHVuaXQgdGVzdHMgZm9yIG1lc3NhZ2Ugb3BlcmF0aW9ucyB0aGF0IGFwcGx5IHRvIGJvdGggZ2VuZXJhdGVkCisgKiBhbmQgZHluYW1pYyBtZXNzYWdlcy4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgY2xhc3MgTWVzc2FnZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIE1lc3NhZ2UtbWVyZ2luZyB0ZXN0cy4KKworICBzdGF0aWMgZmluYWwgVGVzdEFsbFR5cGVzIE1FUkdFX1NPVVJDRSA9CisgICAgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQorICAgICAgLnNldE9wdGlvbmFsSW50MzIoMSkKKyAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiZm9vIikKKyAgICAgIC5zZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKEZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgLmFkZFJlcGVhdGVkU3RyaW5nKCJiYXIiKQorICAgICAgLmJ1aWxkKCk7CisKKyAgc3RhdGljIGZpbmFsIFRlc3RBbGxUeXBlcyBNRVJHRV9ERVNUID0KKyAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAuc2V0T3B0aW9uYWxJbnQ2NCgyKQorICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJiYXoiKQorICAgICAgLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMykuYnVpbGQoKSkKKyAgICAgIC5hZGRSZXBlYXRlZFN0cmluZygicXV4IikKKyAgICAgIC5idWlsZCgpOworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVSR0VfUkVTVUxUX1RFWFQgPQorICAgICAgIm9wdGlvbmFsX2ludDMyOiAxXG4iICsKKyAgICAgICJvcHRpb25hbF9pbnQ2NDogMlxuIiArCisgICAgICAib3B0aW9uYWxfc3RyaW5nOiBcImZvb1wiXG4iICsKKyAgICAgICJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2Uge1xuIiArCisgICAgICAiICBjOiAzXG4iICsKKyAgICAgICJ9XG4iICsKKyAgICAgICJyZXBlYXRlZF9zdHJpbmc6IFwicXV4XCJcbiIgKworICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJiYXJcIlxuIjsKKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzIHJlc3VsdCA9CisgICAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcihNRVJHRV9ERVNUKQorICAgICAgICAubWVyZ2VGcm9tKE1FUkdFX1NPVVJDRSkuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscyhNRVJHRV9SRVNVTFRfVEVYVCwgcmVzdWx0LnRvU3RyaW5nKCkpOworICB9CisKKyAgLyoqCisgICAqIFRlc3QgbWVyZ2luZyBhIER5bmFtaWNNZXNzYWdlIGludG8gYSBHZW5lcmF0ZWRNZXNzYWdlLiAgQXMgbG9uZyBhcyB0aGV5CisgICAqIGhhdmUgdGhlIHNhbWUgZGVzY3JpcHRvciwgdGhpcyBzaG91bGQgd29yaywgYnV0IGl0IGlzIGFuIGVudGlyZWx5IGRpZmZlcmVudAorICAgKiBjb2RlIHBhdGguCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VGcm9tRHluYW1pYygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcyByZXN1bHQgPQorICAgICAgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoTUVSR0VfREVTVCkKKyAgICAgICAgLm1lcmdlRnJvbShEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKE1FUkdFX1NPVVJDRSkuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRFcXVhbHMoTUVSR0VfUkVTVUxUX1RFWFQsIHJlc3VsdC50b1N0cmluZygpKTsKKyAgfQorCisgIC8qKiBUZXN0IG1lcmdpbmcgdHdvIER5bmFtaWNNZXNzYWdlcy4gKi8KKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNNZXJnZUZyb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEeW5hbWljTWVzc2FnZSByZXN1bHQgPQorICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihNRVJHRV9ERVNUKQorICAgICAgICAubWVyZ2VGcm9tKER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIoTUVSR0VfU09VUkNFKS5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscyhNRVJHRV9SRVNVTFRfVEVYVCwgcmVzdWx0LnRvU3RyaW5nKCkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gUmVxdWlyZWQtZmllbGQtcmVsYXRlZCB0ZXN0cy4KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUZXN0UmVxdWlyZWQgVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEID0KKyAgICBUZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RSZXF1aXJlZCBURVNUX1JFUVVJUkVEX0lOSVRJQUxJWkVEID0KKyAgICBUZXN0UmVxdWlyZWQubmV3QnVpbGRlcigpLnNldEEoMSkuc2V0QigyKS5zZXRDKDMpLmJ1aWxkKCk7CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcXVpcmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RSZXF1aXJlZC5uZXdCdWlsZGVyKCk7CisKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisgICAgYnVpbGRlci5zZXRBKDEpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBidWlsZGVyLnNldEIoMSk7CisgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICAgIGJ1aWxkZXIuc2V0QygxKTsKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZXF1aXJlZEZvcmVpZ24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0UmVxdWlyZWRGb3JlaWduLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RSZXF1aXJlZEZvcmVpZ24ubmV3QnVpbGRlcigpOworCisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTWVzc2FnZShURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxNZXNzYWdlKFRFU1RfUkVRVUlSRURfSU5JVElBTElaRUQpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworCisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE1lc3NhZ2UoVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICBidWlsZGVyLnNldFJlcGVhdGVkTWVzc2FnZSgwLCBURVNUX1JFUVVJUkVEX0lOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZXF1aXJlZEV4dGVuc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKTsKKworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworCisgICAgYnVpbGRlci5zZXRFeHRlbnNpb24oVGVzdFJlcXVpcmVkLnNpbmdsZSwgVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICBidWlsZGVyLnNldEV4dGVuc2lvbihUZXN0UmVxdWlyZWQuc2luZ2xlLCBURVNUX1JFUVVJUkVEX0lOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRUcnVlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKworICAgIGJ1aWxkZXIuYWRkRXh0ZW5zaW9uKFRlc3RSZXF1aXJlZC5tdWx0aSwgVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKTsKKyAgICBhc3NlcnRGYWxzZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICBidWlsZGVyLnNldEV4dGVuc2lvbihUZXN0UmVxdWlyZWQubXVsdGksIDAsIFRFU1RfUkVRVUlSRURfSU5JVElBTElaRUQpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcXVpcmVkRHluYW1pYygpIHRocm93cyBFeGNlcHRpb24geworICAgIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZGVzY3JpcHRvciA9IFRlc3RSZXF1aXJlZC5nZXREZXNjcmlwdG9yKCk7CisgICAgRHluYW1pY01lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0gRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihkZXNjcmlwdG9yKTsKKworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBidWlsZGVyLnNldEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJhIiksIDEpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBidWlsZGVyLnNldEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJiIiksIDEpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKyAgICBidWlsZGVyLnNldEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJjIiksIDEpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcXVpcmVkRHluYW1pY0ZvcmVpZ24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0UmVxdWlyZWRGb3JlaWduLmdldERlc2NyaXB0b3IoKTsKKyAgICBEeW5hbWljTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIgPSBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKGRlc2NyaXB0b3IpOworCisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmlzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICBidWlsZGVyLnNldEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9tZXNzYWdlIiksCisgICAgICAgICAgICAgICAgICAgICBURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQpOworICAgIGFzc2VydEZhbHNlKGJ1aWxkZXIuaXNJbml0aWFsaXplZCgpKTsKKworICAgIGJ1aWxkZXIuc2V0RmllbGQoZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX21lc3NhZ2UiKSwKKyAgICAgICAgICAgICAgICAgICAgIFRFU1RfUkVRVUlSRURfSU5JVElBTElaRUQpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworCisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9tZXNzYWdlIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRFU1RfUkVRVUlSRURfVU5JTklUSUFMSVpFRCk7CisgICAgYXNzZXJ0RmFsc2UoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworCisgICAgYnVpbGRlci5zZXRSZXBlYXRlZEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9tZXNzYWdlIiksIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRFU1RfUkVRVUlSRURfSU5JVElBTElaRUQpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5pc0luaXRpYWxpemVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFVuaW5pdGlhbGl6ZWRFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgVGVzdFJlcXVpcmVkLm5ld0J1aWxkZXIoKS5idWlsZCgpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIk1lc3NhZ2UgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6IGEsIGIsIGMiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJ1aWxkUGFydGlhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdlJ3JlIG1vc3RseSB0ZXN0aW5nIHRoYXQgbm8gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICBUZXN0UmVxdWlyZWQgbWVzc2FnZSA9IFRlc3RSZXF1aXJlZC5uZXdCdWlsZGVyKCkuYnVpbGRQYXJ0aWFsKCk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5pc0luaXRpYWxpemVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5lc3RlZFVuaW5pdGlhbGl6ZWRFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgVGVzdFJlcXVpcmVkRm9yZWlnbi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsTWVzc2FnZShURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQpCisgICAgICAgIC5hZGRSZXBlYXRlZE1lc3NhZ2UoVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKQorICAgICAgICAuYWRkUmVwZWF0ZWRNZXNzYWdlKFRFU1RfUkVRVUlSRURfVU5JTklUSUFMSVpFRCkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKFVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKKyAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgIk1lc3NhZ2UgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICIgKworICAgICAgICAib3B0aW9uYWxfbWVzc2FnZS5hLCAiICsKKyAgICAgICAgIm9wdGlvbmFsX21lc3NhZ2UuYiwgIiArCisgICAgICAgICJvcHRpb25hbF9tZXNzYWdlLmMsICIgKworICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVswXS5hLCAiICsKKyAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMF0uYiwgIiArCisgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzBdLmMsICIgKworICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVsxXS5hLCAiICsKKyAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMV0uYiwgIiArCisgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzFdLmMiLAorICAgICAgICBlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJ1aWxkTmVzdGVkUGFydGlhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdlJ3JlIG1vc3RseSB0ZXN0aW5nIHRoYXQgbm8gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICBUZXN0UmVxdWlyZWRGb3JlaWduIG1lc3NhZ2UgPQorICAgICAgVGVzdFJlcXVpcmVkRm9yZWlnbi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsTWVzc2FnZShURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQpCisgICAgICAgIC5hZGRSZXBlYXRlZE1lc3NhZ2UoVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKQorICAgICAgICAuYWRkUmVwZWF0ZWRNZXNzYWdlKFRFU1RfUkVRVUlSRURfVU5JTklUSUFMSVpFRCkKKyAgICAgICAgLmJ1aWxkUGFydGlhbCgpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaXNJbml0aWFsaXplZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVVuaXRpdGlhbGl6ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgVGVzdFJlcXVpcmVkLnBhcnNlRnJvbShCeXRlU3RyaW5nLkVNUFRZKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIGFzc2VydEVxdWFscygiTWVzc2FnZSBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogYSwgYiwgYyIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VOZXN0ZWRVbml0aXRpYWxpemVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnl0ZVN0cmluZyBkYXRhID0KKyAgICAgIFRlc3RSZXF1aXJlZEZvcmVpZ24ubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRPcHRpb25hbE1lc3NhZ2UoVEVTVF9SRVFVSVJFRF9VTklOSVRJQUxJWkVEKQorICAgICAgICAuYWRkUmVwZWF0ZWRNZXNzYWdlKFRFU1RfUkVRVUlSRURfVU5JTklUSUFMSVpFRCkKKyAgICAgICAgLmFkZFJlcGVhdGVkTWVzc2FnZShURVNUX1JFUVVJUkVEX1VOSU5JVElBTElaRUQpCisgICAgICAgIC5idWlsZFBhcnRpYWwoKS50b0J5dGVTdHJpbmcoKTsKKworICAgIHRyeSB7CisgICAgICBUZXN0UmVxdWlyZWRGb3JlaWduLnBhcnNlRnJvbShkYXRhKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgIk1lc3NhZ2UgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICIgKworICAgICAgICAib3B0aW9uYWxfbWVzc2FnZS5hLCAiICsKKyAgICAgICAgIm9wdGlvbmFsX21lc3NhZ2UuYiwgIiArCisgICAgICAgICJvcHRpb25hbF9tZXNzYWdlLmMsICIgKworICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVswXS5hLCAiICsKKyAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMF0uYiwgIiArCisgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzBdLmMsICIgKworICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVsxXS5hLCAiICsKKyAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMV0uYiwgIiArCisgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzFdLmMiLAorICAgICAgICBlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNVbmluaXRpYWxpemVkRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIER5bmFtaWNNZXNzYWdlLm5ld0J1aWxkZXIoVGVzdFJlcXVpcmVkLmdldERlc2NyaXB0b3IoKSkuYnVpbGQoKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgeworICAgICAgYXNzZXJ0RXF1YWxzKCJNZXNzYWdlIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzOiBhLCBiLCBjIiwgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljQnVpbGRQYXJ0aWFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV2UncmUgbW9zdGx5IHRlc3RpbmcgdGhhdCBubyBleGNlcHRpb24gaXMgdGhyb3duLgorICAgIER5bmFtaWNNZXNzYWdlIG1lc3NhZ2UgPQorICAgICAgRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihUZXN0UmVxdWlyZWQuZ2V0RGVzY3JpcHRvcigpKQorICAgICAgICAuYnVpbGRQYXJ0aWFsKCk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5pc0luaXRpYWxpemVkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdER5bmFtaWNQYXJzZVVuaXRpdGlhbGl6ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gVGVzdFJlcXVpcmVkLmdldERlc2NyaXB0b3IoKTsKKyAgICAgIER5bmFtaWNNZXNzYWdlLnBhcnNlRnJvbShkZXNjcmlwdG9yLCBCeXRlU3RyaW5nLkVNUFRZKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIGFzc2VydEVxdWFscygiTWVzc2FnZSBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogYSwgYiwgYyIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKiBUZXN0IHJlYWRpbmcgdW5zZXQgcmVwZWF0ZWQgbWVzc2FnZSBmcm9tIER5bmFtaWNNZXNzYWdlLiAqLworICBwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY1JlcGVhdGVkTWVzc2FnZU51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0UmVxdWlyZWQuZ2V0RGVzY3JpcHRvcigpOworICAgIER5bmFtaWNNZXNzYWdlIHJlc3VsdCA9CisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkpCisgICAgICAgIC5tZXJnZUZyb20oRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihNRVJHRV9TT1VSQ0UpLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuZ2V0RmllbGQocmVzdWx0LmdldERlc2NyaXB0b3JGb3JUeXBlKCkKKyAgICAgICAgLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpIGluc3RhbmNlb2YgTGlzdDw/Pik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5nZXRSZXBlYXRlZEZpZWxkQ291bnQocmVzdWx0LmdldERlc2NyaXB0b3JGb3JUeXBlKCkKKyAgICAgICAgLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpLCAwKTsKKyAgfQorICAKKyAgLyoqIFRlc3QgcmVhZGluZyByZXBlYXRlZCBtZXNzYWdlIGZyb20gRHluYW1pY01lc3NhZ2UuICovCisgIHB1YmxpYyB2b2lkIHRlc3REeW5hbWljUmVwZWF0ZWRNZXNzYWdlTm90TnVsbCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgVGVzdEFsbFR5cGVzIFJFUEVBVEVEX05FU1RFRCA9CisgICAgICBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRPcHRpb25hbEludDMyKDEpCisgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiZm9vIikKKyAgICAgICAgLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgIC5hZGRSZXBlYXRlZFN0cmluZygiYmFyIikKKyAgICAgICAgLmFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgIC5hZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKEZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0UmVxdWlyZWQuZ2V0RGVzY3JpcHRvcigpOworICAgIER5bmFtaWNNZXNzYWdlIHJlc3VsdCA9CisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkpCisgICAgICAgIC5tZXJnZUZyb20oRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcihSRVBFQVRFRF9ORVNURUQpLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuZ2V0RmllbGQocmVzdWx0LmdldERlc2NyaXB0b3JGb3JUeXBlKCkKKyAgICAgICAgLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpIGluc3RhbmNlb2YgTGlzdDw/Pik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5nZXRSZXBlYXRlZEZpZWxkQ291bnQocmVzdWx0LmdldERlc2NyaXB0b3JGb3JUeXBlKCkKKyAgICAgICAgLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpLCAyKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTmVzdGVkQnVpbGRlcnNUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9OZXN0ZWRCdWlsZGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzY1MzEyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvTmVzdGVkQnVpbGRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSwxODUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworLyoqCisgKiBUZXN0IGNhc2VzIHRoYXQgZXhlcmNpc2UgZW5kLXRvLWVuZCB1c2UgY2FzZXMgaW52b2x2aW5nCisgKiB7QGxpbmsgU2luZ2xlRmllbGRCdWlsZGVyfSBhbmQge0BsaW5rIFJlcGVhdGVkRmllbGRCdWlsZGVyfS4KKyAqCisgKiBAYXV0aG9yIGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKyAqLworcHVibGljIGNsYXNzIE5lc3RlZEJ1aWxkZXJzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZXNBbmRCdWlsZGVycygpIHsKKyAgICBWZWhpY2xlLkJ1aWxkZXIgdmVoaWNsZUJ1aWxkZXIgPSBWZWhpY2xlLm5ld0J1aWxkZXIoKTsKKyAgICB2ZWhpY2xlQnVpbGRlci5hZGRXaGVlbEJ1aWxkZXIoKQorICAgICAgICAuc2V0UmFkaXVzKDQpCisgICAgICAgIC5zZXRXaWR0aCgxKTsKKyAgICB2ZWhpY2xlQnVpbGRlci5hZGRXaGVlbEJ1aWxkZXIoKQorICAgICAgICAuc2V0UmFkaXVzKDQpCisgICAgICAgIC5zZXRXaWR0aCgyKTsKKyAgICB2ZWhpY2xlQnVpbGRlci5hZGRXaGVlbEJ1aWxkZXIoKQorICAgICAgICAuc2V0UmFkaXVzKDQpCisgICAgICAgIC5zZXRXaWR0aCgzKTsKKyAgICB2ZWhpY2xlQnVpbGRlci5hZGRXaGVlbEJ1aWxkZXIoKQorICAgICAgICAuc2V0UmFkaXVzKDQpCisgICAgICAgIC5zZXRXaWR0aCg0KTsKKyAgICB2ZWhpY2xlQnVpbGRlci5nZXRFbmdpbmVCdWlsZGVyKCkKKyAgICAgICAgLnNldExpdGVycygxMCk7CisKKyAgICBWZWhpY2xlIHZlaGljbGUgPSB2ZWhpY2xlQnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyg0LCB2ZWhpY2xlLmdldFdoZWVsQ291bnQoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgIFdoZWVsIHdoZWVsID0gdmVoaWNsZS5nZXRXaGVlbChpKTsKKyAgICAgIGFzc2VydEVxdWFscyg0LCB3aGVlbC5nZXRSYWRpdXMoKSk7CisgICAgICBhc3NlcnRFcXVhbHMoaSArIDEsIHdoZWVsLmdldFdpZHRoKCkpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMTAsIHZlaGljbGUuZ2V0RW5naW5lKCkuZ2V0TGl0ZXJzKCkpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgIHZlaGljbGVCdWlsZGVyLmdldFdoZWVsQnVpbGRlcihpKQorICAgICAgICAgIC5zZXRSYWRpdXMoNSkKKyAgICAgICAgICAuc2V0V2lkdGgoaSArIDEwKTsKKyAgICB9CisgICAgdmVoaWNsZUJ1aWxkZXIuZ2V0RW5naW5lQnVpbGRlcigpLnNldExpdGVycygyMCk7CisKKyAgICB2ZWhpY2xlID0gdmVoaWNsZUJ1aWxkZXIuYnVpbGQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykgeworICAgICAgV2hlZWwgd2hlZWwgPSB2ZWhpY2xlLmdldFdoZWVsKGkpOworICAgICAgYXNzZXJ0RXF1YWxzKDUsIHdoZWVsLmdldFJhZGl1cygpKTsKKyAgICAgIGFzc2VydEVxdWFscyhpICsgMTAsIHdoZWVsLmdldFdpZHRoKCkpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMjAsIHZlaGljbGUuZ2V0RW5naW5lKCkuZ2V0TGl0ZXJzKCkpOworICAgIGFzc2VydFRydWUodmVoaWNsZS5oYXNFbmdpbmUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZXNBcmVDYWNoZWQoKSB7CisgICAgVmVoaWNsZS5CdWlsZGVyIHZlaGljbGVCdWlsZGVyID0gVmVoaWNsZS5uZXdCdWlsZGVyKCk7CisgICAgdmVoaWNsZUJ1aWxkZXIuYWRkV2hlZWxCdWlsZGVyKCkKKyAgICAgICAgLnNldFJhZGl1cygxKQorICAgICAgICAuc2V0V2lkdGgoMik7CisgICAgdmVoaWNsZUJ1aWxkZXIuYWRkV2hlZWxCdWlsZGVyKCkKKyAgICAgICAgLnNldFJhZGl1cygzKQorICAgICAgICAuc2V0V2lkdGgoNCk7CisgICAgdmVoaWNsZUJ1aWxkZXIuYWRkV2hlZWxCdWlsZGVyKCkKKyAgICAgICAgLnNldFJhZGl1cyg1KQorICAgICAgICAuc2V0V2lkdGgoNik7CisgICAgdmVoaWNsZUJ1aWxkZXIuYWRkV2hlZWxCdWlsZGVyKCkKKyAgICAgICAgLnNldFJhZGl1cyg3KQorICAgICAgICAuc2V0V2lkdGgoOCk7CisKKyAgICAvLyBNYWtlIHN1cmUgbWVzc2FnZXMgYXJlIGNhY2hlZC4KKyAgICBMaXN0PFdoZWVsPiB3aGVlbHMgPSBuZXcgQXJyYXlMaXN0PFdoZWVsPih2ZWhpY2xlQnVpbGRlci5nZXRXaGVlbExpc3QoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB3aGVlbHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGFzc2VydFNhbWUod2hlZWxzLmdldChpKSwgdmVoaWNsZUJ1aWxkZXIuZ2V0V2hlZWwoaSkpOworICAgIH0KKworICAgIC8vIE5vdyBnZXQgYnVpbGRlcnMgYW5kIGNoZWNrIHRoZXkgZGlkbid0IGNoYW5nZS4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHdoZWVscy5zaXplKCk7IGkrKykgeworICAgICAgdmVoaWNsZUJ1aWxkZXIuZ2V0V2hlZWwoaSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgd2hlZWxzLnNpemUoKTsgaSsrKSB7CisgICAgICBhc3NlcnRTYW1lKHdoZWVscy5nZXQoaSksIHZlaGljbGVCdWlsZGVyLmdldFdoZWVsKGkpKTsKKyAgICB9CisKKyAgICAvLyBDaGFuZ2UganVzdCBvbmUKKyAgICB2ZWhpY2xlQnVpbGRlci5nZXRXaGVlbEJ1aWxkZXIoMykKKyAgICAgICAgLnNldFJhZGl1cygyMCkuc2V0V2lkdGgoMjApOworCisgICAgLy8gTm93IGdldCB3aGVlbHMgYW5kIGNoZWNrIHRoYXQgb25seSB0aGF0IG9uZSBjaGFuZ2VkCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB3aGVlbHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGlmIChpIDwgMykgeworICAgICAgICBhc3NlcnRTYW1lKHdoZWVscy5nZXQoaSksIHZlaGljbGVCdWlsZGVyLmdldFdoZWVsKGkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGFzc2VydE5vdFNhbWUod2hlZWxzLmdldChpKSwgdmVoaWNsZUJ1aWxkZXIuZ2V0V2hlZWwoaSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVfV2l0aE5lc3RlZEJ1aWxkZXJzKCkgeworICAgIFZlaGljbGUuQnVpbGRlciB2ZWhpY2xlQnVpbGRlciA9IFZlaGljbGUubmV3QnVpbGRlcigpOworICAgIHZlaGljbGVCdWlsZGVyLmFkZFdoZWVsQnVpbGRlcigpCisgICAgICAgIC5zZXRSYWRpdXMoMSkKKyAgICAgICAgLnNldFdpZHRoKDEpOworICAgIHZlaGljbGVCdWlsZGVyLmFkZFdoZWVsQnVpbGRlcigpCisgICAgICAgIC5zZXRSYWRpdXMoMikKKyAgICAgICAgLnNldFdpZHRoKDIpOworICAgIHZlaGljbGVCdWlsZGVyLnJlbW92ZVdoZWVsKDApOworCisgICAgYXNzZXJ0RXF1YWxzKDEsIHZlaGljbGVCdWlsZGVyLmdldFdoZWVsQ291bnQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIHZlaGljbGVCdWlsZGVyLmdldFdoZWVsKDApLmdldFJhZGl1cygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVfV2l0aE5lc3RlZE1lc3NhZ2VzKCkgeworICAgIFZlaGljbGUuQnVpbGRlciB2ZWhpY2xlQnVpbGRlciA9IFZlaGljbGUubmV3QnVpbGRlcigpOworICAgIHZlaGljbGVCdWlsZGVyLmFkZFdoZWVsKFdoZWVsLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0UmFkaXVzKDEpCisgICAgICAgIC5zZXRXaWR0aCgxKSk7CisgICAgdmVoaWNsZUJ1aWxkZXIuYWRkV2hlZWwoV2hlZWwubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRSYWRpdXMoMikKKyAgICAgICAgLnNldFdpZHRoKDIpKTsKKyAgICB2ZWhpY2xlQnVpbGRlci5yZW1vdmVXaGVlbCgwKTsKKworICAgIGFzc2VydEVxdWFscygxLCB2ZWhpY2xlQnVpbGRlci5nZXRXaGVlbENvdW50KCkpOworICAgIGFzc2VydEVxdWFscygyLCB2ZWhpY2xlQnVpbGRlci5nZXRXaGVlbCgwKS5nZXRSYWRpdXMoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2UoKSB7CisgICAgVmVoaWNsZSB2ZWhpY2xlMSA9IFZlaGljbGUubmV3QnVpbGRlcigpCisgICAgICAgIC5hZGRXaGVlbChXaGVlbC5uZXdCdWlsZGVyKCkuc2V0UmFkaXVzKDEpLmJ1aWxkKCkpCisgICAgICAgIC5hZGRXaGVlbChXaGVlbC5uZXdCdWlsZGVyKCkuc2V0UmFkaXVzKDIpLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgVmVoaWNsZSB2ZWhpY2xlMiA9IFZlaGljbGUubmV3QnVpbGRlcigpCisgICAgICAgIC5tZXJnZUZyb20odmVoaWNsZTEpCisgICAgICAgIC5idWlsZCgpOworICAgIC8vIExpc3Qgc2hvdWxkIGJlIHRoZSBzYW1lIC0tIG5vIGFsbG9jYXRpb24KKyAgICBhc3NlcnRTYW1lKHZlaGljbGUxLmdldFdoZWVsTGlzdCgpLCB2ZWhpY2xlMi5nZXRXaGVlbExpc3QoKSk7CisKKyAgICBWZWhpY2xlIHZlaGljbGUzID0gdmVoaWNsZTEudG9CdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBhc3NlcnRTYW1lKHZlaGljbGUxLmdldFdoZWVsTGlzdCgpLCB2ZWhpY2xlMy5nZXRXaGVlbExpc3QoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0dGluZ0J1aWxkZXJNYXJrc0ZpZWxkQXNIYXZpbmcoKSB7CisgICAgVmVoaWNsZS5CdWlsZGVyIHZlaGljbGVCdWlsZGVyID0gVmVoaWNsZS5uZXdCdWlsZGVyKCk7CisgICAgdmVoaWNsZUJ1aWxkZXIuZ2V0RW5naW5lQnVpbGRlcigpOworICAgIFZlaGljbGUgdmVoaWNsZSA9IHZlaGljbGVCdWlsZGVyLmJ1aWxkUGFydGlhbCgpOworICAgIGFzc2VydFRydWUodmVoaWNsZS5oYXNFbmdpbmUoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1BhcnNlclRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1BhcnNlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTFkOGNiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUGFyc2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzgxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuVGVzdEFsbFR5cGVzTGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5UZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuVGVzdFBhcnNpbmdNZXJnZUxpdGU7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemU7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2U7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIFVuaXQgdGVzdCBmb3Ige0BsaW5rIFBhcnNlcn0uCisgKgorICogQGF1dGhvciBsaXVqaXNpQGdvb2dsZS5jb20gKFBoZXJsIExpdSkKKyAqLworcHVibGljIGNsYXNzIFBhcnNlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZWRNZXNzYWdlUGFyc2VyU2luZ2xldG9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLlBBUlNFUiwKKyAgICAgICAgICAgICAgICAgICBUZXN0VXRpbC5nZXRBbGxTZXQoKS5nZXRQYXJzZXJGb3JUeXBlKCkpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRSb3VuZFRyaXBFcXVhbHMoTWVzc2FnZUxpdGUgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBieXRlW10gZGF0YSA9IG1lc3NhZ2UudG9CeXRlQXJyYXkoKTsKKyAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gMjA7CisgICAgZmluYWwgaW50IGxlbmd0aCA9IGRhdGEubGVuZ3RoOworICAgIGZpbmFsIGludCBwYWRkaW5nID0gMzA7CisgICAgUGFyc2VyPD8gZXh0ZW5kcyBNZXNzYWdlTGl0ZT4gcGFyc2VyID0gbWVzc2FnZS5nZXRQYXJzZXJGb3JUeXBlKCk7CisgICAgYXNzZXJ0TWVzc2FnZUVxdWFscyhtZXNzYWdlLCBwYXJzZXIucGFyc2VGcm9tKGRhdGEsIHJlZ2lzdHJ5KSk7CisgICAgYXNzZXJ0TWVzc2FnZUVxdWFscyhtZXNzYWdlLCBwYXJzZXIucGFyc2VGcm9tKAorICAgICAgICBnZW5lcmF0ZVBhZGRpbmdBcnJheShkYXRhLCBvZmZzZXQsIHBhZGRpbmcpLAorICAgICAgICBvZmZzZXQsIGxlbmd0aCwgcmVnaXN0cnkpKTsKKyAgICBhc3NlcnRNZXNzYWdlRXF1YWxzKG1lc3NhZ2UsIHBhcnNlci5wYXJzZUZyb20oCisgICAgICAgIG1lc3NhZ2UudG9CeXRlU3RyaW5nKCksIHJlZ2lzdHJ5KSk7CisgICAgYXNzZXJ0TWVzc2FnZUVxdWFscyhtZXNzYWdlLCBwYXJzZXIucGFyc2VGcm9tKAorICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSksIHJlZ2lzdHJ5KSk7CisgICAgYXNzZXJ0TWVzc2FnZUVxdWFscyhtZXNzYWdlLCBwYXJzZXIucGFyc2VGcm9tKAorICAgICAgICBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGRhdGEpLCByZWdpc3RyeSkpOworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHByaXZhdGUgdm9pZCBhc3NlcnRSb3VuZFRyaXBFcXVhbHMoTWVzc2FnZUxpdGUgbWVzc2FnZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBtZXNzYWdlLnRvQnl0ZUFycmF5KCk7CisgICAgZmluYWwgaW50IG9mZnNldCA9IDIwOworICAgIGZpbmFsIGludCBsZW5ndGggPSBkYXRhLmxlbmd0aDsKKyAgICBmaW5hbCBpbnQgcGFkZGluZyA9IDMwOworCisgICAgUGFyc2VyPE1lc3NhZ2VMaXRlPiBwYXJzZXIgPQorICAgICAgICAoUGFyc2VyPE1lc3NhZ2VMaXRlPikgbWVzc2FnZS5nZXRQYXJzZXJGb3JUeXBlKCk7CisgICAgYXNzZXJ0TWVzc2FnZUVxdWFscyhtZXNzYWdlLCBwYXJzZXIucGFyc2VGcm9tKGRhdGEpKTsKKyAgICBhc3NlcnRNZXNzYWdlRXF1YWxzKG1lc3NhZ2UsIHBhcnNlci5wYXJzZUZyb20oCisgICAgICAgIGdlbmVyYXRlUGFkZGluZ0FycmF5KGRhdGEsIG9mZnNldCwgcGFkZGluZyksCisgICAgICAgIG9mZnNldCwgbGVuZ3RoKSk7CisgICAgYXNzZXJ0TWVzc2FnZUVxdWFscyhtZXNzYWdlLCBwYXJzZXIucGFyc2VGcm9tKG1lc3NhZ2UudG9CeXRlU3RyaW5nKCkpKTsKKyAgICBhc3NlcnRNZXNzYWdlRXF1YWxzKG1lc3NhZ2UsIHBhcnNlci5wYXJzZUZyb20oCisgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSkpOworICAgIGFzc2VydE1lc3NhZ2VFcXVhbHMobWVzc2FnZSwgcGFyc2VyLnBhcnNlRnJvbSgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKSkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydE1lc3NhZ2VFcXVhbHMoCisgICAgICBNZXNzYWdlTGl0ZSBleHBlY3RlZCwgTWVzc2FnZUxpdGUgYWN0dWFsKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgaWYgKGV4cGVjdGVkIGluc3RhbmNlb2YgTWVzc2FnZSkgeworICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0gZWxzZSB7CisgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQudG9CeXRlU3RyaW5nKCksIGFjdHVhbC50b0J5dGVTdHJpbmcoKSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBieXRlW10gZ2VuZXJhdGVQYWRkaW5nQXJyYXkoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBwYWRkaW5nKSB7CisgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW29mZnNldCArIGRhdGEubGVuZ3RoICsgcGFkZGluZ107CisgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCByZXN1bHQsIG9mZnNldCwgZGF0YS5sZW5ndGgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Tm9ybWFsTWVzc2FnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFJvdW5kVHJpcEVxdWFscyhUZXN0VXRpbC5nZXRBbGxTZXQoKSk7CisgIH0KKworCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVBhcnRpYWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRQYXJzZVBhcnRpYWwoVGVzdFJlcXVpcmVkLlBBUlNFUiwKKyAgICAgICAgVGVzdFJlcXVpcmVkLm5ld0J1aWxkZXIoKS5zZXRBKDEpLmJ1aWxkUGFydGlhbCgpKTsKKyAgfQorCisgIHByaXZhdGUgPFQgZXh0ZW5kcyBNZXNzYWdlTGl0ZT4gdm9pZCBhc3NlcnRQYXJzZVBhcnRpYWwoCisgICAgICBQYXJzZXI8VD4gcGFyc2VyLCBUIHBhcnRpYWxNZXNzYWdlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBTdHJpbmcgZXJyb3JTdHJpbmcgPQorICAgICAgICAiU2hvdWxkIHRocm93IGV4Y2VwdGlvbnMgd2hlbiB0aGUgcGFyc2VkIG1lc3NhZ2UgaXNuJ3QgaW5pdGlhbGl6ZWQuIjsKKworICAgIC8vIHBhcnNlUGFydGlhbEZyb20gc2hvdWxkIHBhc3MuCisgICAgYnl0ZVtdIGRhdGEgPSBwYXJ0aWFsTWVzc2FnZS50b0J5dGVBcnJheSgpOworICAgIGFzc2VydEVxdWFscyhwYXJ0aWFsTWVzc2FnZSwgcGFyc2VyLnBhcnNlUGFydGlhbEZyb20oZGF0YSkpOworICAgIGFzc2VydEVxdWFscyhwYXJ0aWFsTWVzc2FnZSwgcGFyc2VyLnBhcnNlUGFydGlhbEZyb20oCisgICAgICAgIHBhcnRpYWxNZXNzYWdlLnRvQnl0ZVN0cmluZygpKSk7CisgICAgYXNzZXJ0RXF1YWxzKHBhcnRpYWxNZXNzYWdlLCBwYXJzZXIucGFyc2VQYXJ0aWFsRnJvbSgKKyAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKSk7CisgICAgYXNzZXJ0RXF1YWxzKHBhcnRpYWxNZXNzYWdlLCBwYXJzZXIucGFyc2VQYXJ0aWFsRnJvbSgKKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShkYXRhKSkpOworCisgICAgLy8gcGFyc2VGcm9tKEJ5dGVBcnJheSkKKyAgICB0cnkgeworICAgICAgcGFyc2VyLnBhcnNlRnJvbShwYXJ0aWFsTWVzc2FnZS50b0J5dGVBcnJheSgpKTsKKyAgICAgIGZhaWwoZXJyb3JTdHJpbmcpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBwYXNzLgorICAgIH0KKworICAgIC8vIHBhcnNlRnJvbShCeXRlU3RyaW5nKQorICAgIHRyeSB7CisgICAgICBwYXJzZXIucGFyc2VGcm9tKHBhcnRpYWxNZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgICAgIGZhaWwoZXJyb3JTdHJpbmcpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBwYXNzLgorICAgIH0KKworICAgIC8vIHBhcnNlRnJvbShJbnB1dFN0cmVhbSkKKyAgICB0cnkgeworICAgICAgcGFyc2VyLnBhcnNlRnJvbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocGFydGlhbE1lc3NhZ2UudG9CeXRlQXJyYXkoKSkpOworICAgICAgZmFpbChlcnJvclN0cmluZyk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgLy8gcGFzcy4KKyAgICB9CisKKyAgICAvLyBwYXJzZUZyb20oQ29kZWRJbnB1dFN0cmVhbSkKKyAgICB0cnkgeworICAgICAgcGFyc2VyLnBhcnNlRnJvbShDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKAorICAgICAgICAgIHBhcnRpYWxNZXNzYWdlLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgIGZhaWwoZXJyb3JTdHJpbmcpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIHBhc3MuCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlRXh0ZW5zaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFJvdW5kVHJpcEVxdWFscyhUZXN0VXRpbC5nZXRBbGxFeHRlbnNpb25zU2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCkpOworICAgIGFzc2VydFJvdW5kVHJpcEVxdWFscyhUZXN0VXRpbC5nZXRBbGxMaXRlRXh0ZW5zaW9uc1NldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeUxpdGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VQYWNrZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRSb3VuZFRyaXBFcXVhbHMoVGVzdFV0aWwuZ2V0UGFja2VkU2V0KCkpOworICAgIGFzc2VydFJvdW5kVHJpcEVxdWFscyhUZXN0VXRpbC5nZXRQYWNrZWRFeHRlbnNpb25zU2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCkpOworICAgIGFzc2VydFJvdW5kVHJpcEVxdWFscyhUZXN0VXRpbC5nZXRMaXRlUGFja2VkRXh0ZW5zaW9uc1NldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeUxpdGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VEZWxpbWl0ZWRUbygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIG5vcm1hbCBNZXNzYWdlLgorICAgIFRlc3RBbGxUeXBlcyBub3JtYWxNZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsU2V0KCk7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dHB1dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBub3JtYWxNZXNzYWdlLndyaXRlRGVsaW1pdGVkVG8ob3V0cHV0KTsKKworICAgIC8vIFdyaXRlIE1lc3NhZ2VMaXRlIHdpdGggcGFja2VkIGV4dGVuc2lvbiBmaWVsZHMuCisgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlIHBhY2tlZE1lc3NhZ2UgPQorICAgICAgICBUZXN0VXRpbC5nZXRMaXRlUGFja2VkRXh0ZW5zaW9uc1NldCgpOworICAgIHBhY2tlZE1lc3NhZ2Uud3JpdGVEZWxpbWl0ZWRUbyhvdXRwdXQpOworCisgICAgSW5wdXRTdHJlYW0gaW5wdXQgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ob3V0cHV0LnRvQnl0ZUFycmF5KCkpOworICAgIGFzc2VydE1lc3NhZ2VFcXVhbHMoCisgICAgICAgIG5vcm1hbE1lc3NhZ2UsCisgICAgICAgIG5vcm1hbE1lc3NhZ2UuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRGVsaW1pdGVkRnJvbShpbnB1dCkpOworICAgIGFzc2VydE1lc3NhZ2VFcXVhbHMoCisgICAgICAgIHBhY2tlZE1lc3NhZ2UsCisgICAgICAgIHBhY2tlZE1lc3NhZ2UuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRGVsaW1pdGVkRnJvbSgKKyAgICAgICAgICAgIGlucHV0LCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeUxpdGUoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlVW5rbm93bkZpZWxkcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEFsbCBmaWVsZHMgd2lsbCBiZSB0cmVhdGVkIGFzIHVua25vd24gZmllbGRzIGluIGVtcHR5TWVzc2FnZS4KKyAgICBUZXN0RW1wdHlNZXNzYWdlIGVtcHR5TWVzc2FnZSA9IFRlc3RFbXB0eU1lc3NhZ2UuUEFSU0VSLnBhcnNlRnJvbSgKKyAgICAgICAgVGVzdFV0aWwuZ2V0QWxsU2V0KCkudG9CeXRlU3RyaW5nKCkpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgVGVzdFV0aWwuZ2V0QWxsU2V0KCkudG9CeXRlU3RyaW5nKCksCisgICAgICAgIGVtcHR5TWVzc2FnZS50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworCisgIHB1YmxpYyB2b2lkIHRlc3RPcHRpbWl6ZUZvclNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T3B0aW1pemVkRm9yU2l6ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5zZXRJKDEyKS5zZXRNc2coRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMzQpLmJ1aWxkKCkpOworICAgIGJ1aWxkZXIuc2V0RXh0ZW5zaW9uKFRlc3RPcHRpbWl6ZWRGb3JTaXplLnRlc3RFeHRlbnNpb24sIDU2KTsKKyAgICBidWlsZGVyLnNldEV4dGVuc2lvbihUZXN0T3B0aW1pemVkRm9yU2l6ZS50ZXN0RXh0ZW5zaW9uMiwKKyAgICAgICAgVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5uZXdCdWlsZGVyKCkuc2V0WCg3OCkuYnVpbGQoKSk7CisKKyAgICBUZXN0T3B0aW1pemVkRm9yU2l6ZSBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gRXh0ZW5zaW9uUmVnaXN0cnkubmV3SW5zdGFuY2UoKTsKKyAgICBVbml0dGVzdE9wdGltaXplRm9yLnJlZ2lzdGVyQWxsRXh0ZW5zaW9ucyhyZWdpc3RyeSk7CisKKyAgICBhc3NlcnRSb3VuZFRyaXBFcXVhbHMobWVzc2FnZSwgcmVnaXN0cnkpOworICB9CisKKyAgLyoqIEhlbHBlciBtZXRob2QgZm9yIHtAbGluayAjdGVzdFBhcnNpbmdNZXJnZSgpfS4qLworICBwcml2YXRlIHZvaWQgYXNzZXJ0TWVzc2FnZU1lcmdlZChUZXN0QWxsVHlwZXMgYWxsVHlwZXMpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRFcXVhbHMoMywgYWxsVHlwZXMuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgYWxsVHlwZXMuZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgYWxsVHlwZXMuZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgIH0KKworICAvKiogSGVscGVyIG1ldGhvZCBmb3Ige0BsaW5rICN0ZXN0UGFyc2luZ01lcmdlTGl0ZSgpfS4qLworICBwcml2YXRlIHZvaWQgYXNzZXJ0TWVzc2FnZU1lcmdlZChUZXN0QWxsVHlwZXNMaXRlIGFsbFR5cGVzKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0RXF1YWxzKDMsIGFsbFR5cGVzLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGFsbFR5cGVzLmdldE9wdGlvbmFsSW50NjQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIGFsbFR5cGVzLmdldE9wdGlvbmFsU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdNZXJnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEJ1aWxkIG1lc3NhZ2VzLgorICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRlc3RBbGxUeXBlcyBtc2cxID0gYnVpbGRlci5zZXRPcHRpb25hbEludDMyKDEpLmJ1aWxkKCk7CisgICAgYnVpbGRlci5jbGVhcigpOworICAgIFRlc3RBbGxUeXBlcyBtc2cyID0gYnVpbGRlci5zZXRPcHRpb25hbEludDY0KDIpLmJ1aWxkKCk7CisgICAgYnVpbGRlci5jbGVhcigpOworICAgIFRlc3RBbGxUeXBlcyBtc2czID0gYnVpbGRlci5zZXRPcHRpb25hbEludDMyKDMpCisgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiaGVsbG8iKS5idWlsZCgpOworCisgICAgLy8gQnVpbGQgZ3JvdXBzLgorICAgIFRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIG9wdGlvbmFsRzEgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2cxKS5idWlsZCgpOworICAgIFRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIG9wdGlvbmFsRzIgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2cyKS5idWlsZCgpOworICAgIFRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIG9wdGlvbmFsRzMgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2czKS5idWlsZCgpOworICAgIFRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHJlcGVhdGVkRzEgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2cxKS5idWlsZCgpOworICAgIFRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHJlcGVhdGVkRzIgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2cyKS5idWlsZCgpOworICAgIFRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHJlcGVhdGVkRzMgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2czKS5idWlsZCgpOworCisgICAgLy8gQXNzaWduIGFuZCBzZXJpYWxpemUgUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuCisgICAgQnl0ZVN0cmluZyBkYXRhID0gVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5uZXdCdWlsZGVyKCkKKyAgICAgICAgLmFkZEZpZWxkMShtc2cxKS5hZGRGaWVsZDEobXNnMikuYWRkRmllbGQxKG1zZzMpCisgICAgICAgIC5hZGRGaWVsZDIobXNnMSkuYWRkRmllbGQyKG1zZzIpLmFkZEZpZWxkMihtc2czKQorICAgICAgICAuYWRkRmllbGQzKG1zZzEpLmFkZEZpZWxkMyhtc2cyKS5hZGRGaWVsZDMobXNnMykKKyAgICAgICAgLmFkZEdyb3VwMShvcHRpb25hbEcxKS5hZGRHcm91cDEob3B0aW9uYWxHMikuYWRkR3JvdXAxKG9wdGlvbmFsRzMpCisgICAgICAgIC5hZGRHcm91cDIocmVwZWF0ZWRHMSkuYWRkR3JvdXAyKHJlcGVhdGVkRzIpLmFkZEdyb3VwMihyZXBlYXRlZEczKQorICAgICAgICAuYWRkRXh0MShtc2cxKS5hZGRFeHQxKG1zZzIpLmFkZEV4dDEobXNnMykKKyAgICAgICAgLmFkZEV4dDIobXNnMSkuYWRkRXh0Mihtc2cyKS5hZGRFeHQyKG1zZzMpCisgICAgICAgIC5idWlsZCgpLnRvQnl0ZVN0cmluZygpOworCisgICAgLy8gUGFyc2UgVGVzdFBhcnNpbmdNZXJnZS4KKyAgICBFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IEV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CisgICAgVW5pdHRlc3RQcm90by5yZWdpc3RlckFsbEV4dGVuc2lvbnMocmVnaXN0cnkpOworICAgIFRlc3RQYXJzaW5nTWVyZ2UgcGFyc2luZ01lcmdlID0KKyAgICAgICAgVGVzdFBhcnNpbmdNZXJnZS5QQVJTRVIucGFyc2VGcm9tKGRhdGEsIHJlZ2lzdHJ5KTsKKworICAgIC8vIFJlcXVpcmVkIGFuZCBvcHRpb25hbCBmaWVsZHMgc2hvdWxkIGJlIG1lcmdlZC4KKyAgICBhc3NlcnRNZXNzYWdlTWVyZ2VkKHBhcnNpbmdNZXJnZS5nZXRSZXF1aXJlZEFsbFR5cGVzKCkpOworICAgIGFzc2VydE1lc3NhZ2VNZXJnZWQocGFyc2luZ01lcmdlLmdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CisgICAgYXNzZXJ0TWVzc2FnZU1lcmdlZCgKKyAgICAgICAgcGFyc2luZ01lcmdlLmdldE9wdGlvbmFsR3JvdXAoKS5nZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSk7CisgICAgYXNzZXJ0TWVzc2FnZU1lcmdlZChwYXJzaW5nTWVyZ2UuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBUZXN0UGFyc2luZ01lcmdlLm9wdGlvbmFsRXh0KSk7CisKKyAgICAvLyBSZXBlYXRlZCBmaWVsZHMgc2hvdWxkIG5vdCBiZSBtZXJnZWQuCisgICAgYXNzZXJ0RXF1YWxzKDMsIHBhcnNpbmdNZXJnZS5nZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIHBhcnNpbmdNZXJnZS5nZXRSZXBlYXRlZEdyb3VwQ291bnQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIHBhcnNpbmdNZXJnZS5nZXRFeHRlbnNpb25Db3VudCgKKyAgICAgICAgVGVzdFBhcnNpbmdNZXJnZS5yZXBlYXRlZEV4dCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdNZXJnZUxpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBCdWlsZCBtZXNzYWdlcy4KKyAgICBUZXN0QWxsVHlwZXNMaXRlLkJ1aWxkZXIgYnVpbGRlciA9CisgICAgICAgIFRlc3RBbGxUeXBlc0xpdGUubmV3QnVpbGRlcigpOworICAgIFRlc3RBbGxUeXBlc0xpdGUgbXNnMSA9IGJ1aWxkZXIuc2V0T3B0aW9uYWxJbnQzMigxKS5idWlsZCgpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBUZXN0QWxsVHlwZXNMaXRlIG1zZzIgPSBidWlsZGVyLnNldE9wdGlvbmFsSW50NjQoMikuYnVpbGQoKTsKKyAgICBidWlsZGVyLmNsZWFyKCk7CisgICAgVGVzdEFsbFR5cGVzTGl0ZSBtc2czID0gYnVpbGRlci5zZXRPcHRpb25hbEludDMyKDMpCisgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiaGVsbG8iKS5idWlsZCgpOworCisgICAgLy8gQnVpbGQgZ3JvdXBzLgorICAgIFRlc3RQYXJzaW5nTWVyZ2VMaXRlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBvcHRpb25hbEcxID0KKyAgICAgICAgVGVzdFBhcnNpbmdNZXJnZUxpdGUuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0RmllbGQxKG1zZzEpLmJ1aWxkKCk7CisgICAgVGVzdFBhcnNpbmdNZXJnZUxpdGUuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIG9wdGlvbmFsRzIgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRGaWVsZDEobXNnMikuYnVpbGQoKTsKKyAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgb3B0aW9uYWxHMyA9CisgICAgICAgIFRlc3RQYXJzaW5nTWVyZ2VMaXRlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2czKS5idWlsZCgpOworICAgIFRlc3RQYXJzaW5nTWVyZ2VMaXRlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiByZXBlYXRlZEcxID0KKyAgICAgICAgVGVzdFBhcnNpbmdNZXJnZUxpdGUuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0RmllbGQxKG1zZzEpLmJ1aWxkKCk7CisgICAgVGVzdFBhcnNpbmdNZXJnZUxpdGUuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHJlcGVhdGVkRzIgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRGaWVsZDEobXNnMikuYnVpbGQoKTsKKyAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgcmVwZWF0ZWRHMyA9CisgICAgICAgIFRlc3RQYXJzaW5nTWVyZ2VMaXRlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpZWxkMShtc2czKS5idWlsZCgpOworCisgICAgLy8gQXNzaWduIGFuZCBzZXJpYWxpemUgUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuCisgICAgQnl0ZVN0cmluZyBkYXRhID0gVGVzdFBhcnNpbmdNZXJnZUxpdGUuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IubmV3QnVpbGRlcigpCisgICAgICAgIC5hZGRGaWVsZDEobXNnMSkuYWRkRmllbGQxKG1zZzIpLmFkZEZpZWxkMShtc2czKQorICAgICAgICAuYWRkRmllbGQyKG1zZzEpLmFkZEZpZWxkMihtc2cyKS5hZGRGaWVsZDIobXNnMykKKyAgICAgICAgLmFkZEZpZWxkMyhtc2cxKS5hZGRGaWVsZDMobXNnMikuYWRkRmllbGQzKG1zZzMpCisgICAgICAgIC5hZGRHcm91cDEob3B0aW9uYWxHMSkuYWRkR3JvdXAxKG9wdGlvbmFsRzIpLmFkZEdyb3VwMShvcHRpb25hbEczKQorICAgICAgICAuYWRkR3JvdXAyKHJlcGVhdGVkRzEpLmFkZEdyb3VwMihyZXBlYXRlZEcyKS5hZGRHcm91cDIocmVwZWF0ZWRHMykKKyAgICAgICAgLmFkZEV4dDEobXNnMSkuYWRkRXh0MShtc2cyKS5hZGRFeHQxKG1zZzMpCisgICAgICAgIC5hZGRFeHQyKG1zZzEpLmFkZEV4dDIobXNnMikuYWRkRXh0Mihtc2czKQorICAgICAgICAuYnVpbGQoKS50b0J5dGVTdHJpbmcoKTsKKworICAgIC8vIFBhcnNlIFRlc3RQYXJzaW5nTWVyZ2VMaXRlLgorICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gRXh0ZW5zaW9uUmVnaXN0cnkubmV3SW5zdGFuY2UoKTsKKyAgICBVbml0dGVzdExpdGUucmVnaXN0ZXJBbGxFeHRlbnNpb25zKHJlZ2lzdHJ5KTsKKyAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZSBwYXJzaW5nTWVyZ2UgPQorICAgICAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZS5QQVJTRVIucGFyc2VGcm9tKGRhdGEsIHJlZ2lzdHJ5KTsKKworICAgIC8vIFJlcXVpcmVkIGFuZCBvcHRpb25hbCBmaWVsZHMgc2hvdWxkIGJlIG1lcmdlZC4KKyAgICBhc3NlcnRNZXNzYWdlTWVyZ2VkKHBhcnNpbmdNZXJnZS5nZXRSZXF1aXJlZEFsbFR5cGVzKCkpOworICAgIGFzc2VydE1lc3NhZ2VNZXJnZWQocGFyc2luZ01lcmdlLmdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CisgICAgYXNzZXJ0TWVzc2FnZU1lcmdlZCgKKyAgICAgICAgcGFyc2luZ01lcmdlLmdldE9wdGlvbmFsR3JvdXAoKS5nZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSk7CisgICAgYXNzZXJ0TWVzc2FnZU1lcmdlZChwYXJzaW5nTWVyZ2UuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBUZXN0UGFyc2luZ01lcmdlTGl0ZS5vcHRpb25hbEV4dCkpOworCisgICAgLy8gUmVwZWF0ZWQgZmllbGRzIHNob3VsZCBub3QgYmUgbWVyZ2VkLgorICAgIGFzc2VydEVxdWFscygzLCBwYXJzaW5nTWVyZ2UuZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkpOworICAgIGFzc2VydEVxdWFscygzLCBwYXJzaW5nTWVyZ2UuZ2V0UmVwZWF0ZWRHcm91cENvdW50KCkpOworICAgIGFzc2VydEVxdWFscygzLCBwYXJzaW5nTWVyZ2UuZ2V0RXh0ZW5zaW9uQ291bnQoCisgICAgICAgIFRlc3RQYXJzaW5nTWVyZ2VMaXRlLnJlcGVhdGVkRXh0KSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JlcGVhdGVkRmllbGRCdWlsZGVyVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUmVwZWF0ZWRGaWVsZEJ1aWxkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDlkNTIzMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JlcGVhdGVkRmllbGRCdWlsZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogVGVzdHMgZm9yIHtAbGluayBSZXBlYXRlZEZpZWxkQnVpbGRlcn0uIFRoaXMgdGVzdHMgYmFzaWMgZnVuY3Rpb25hbGl0eS4KKyAqIE1vcmUgZXh0ZW5zaXZlIHRlc3RpbmcgaXMgcHJvdmlkZWQgdmlhIG90aGVyIHRlc3RzIHRoYXQgZXhlcmNpc2UgdGhlCisgKiBidWlsZGVyLgorICoKKyAqIEBhdXRob3Igam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorICovCitwdWJsaWMgY2xhc3MgUmVwZWF0ZWRGaWVsZEJ1aWxkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgIHB1YmxpYyB2b2lkIHRlc3RCYXNpY1VzZSgpIHsKKyAgICBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCBtb2NrUGFyZW50ID0gbmV3IFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50KCk7CisgICAgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8VGVzdEFsbFR5cGVzLCBUZXN0QWxsVHlwZXMuQnVpbGRlciwKKyAgICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBidWlsZGVyID0gbmV3UmVwZWF0ZWRGaWVsZEJ1aWxkZXIobW9ja1BhcmVudCk7CisgICAgYnVpbGRlci5hZGRNZXNzYWdlKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigwKS5idWlsZCgpKTsKKyAgICBidWlsZGVyLmFkZE1lc3NhZ2UoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDEpLmJ1aWxkKCkpOworICAgIGFzc2VydEVxdWFscygwLCBidWlsZGVyLmdldE1lc3NhZ2UoMCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnVpbGRlci5nZXRNZXNzYWdlKDEpLmdldE9wdGlvbmFsSW50MzIoKSk7CisKKyAgICBMaXN0PFRlc3RBbGxUeXBlcz4gbGlzdCA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbGlzdC5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBsaXN0LmdldCgwKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygxLCBsaXN0LmdldCgxKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKGxpc3QpOworCisgICAgLy8gTWFrZSBzdXJlIGl0IGRvZXNuJ3QgY2hhbmdlLgorICAgIExpc3Q8VGVzdEFsbFR5cGVzPiBsaXN0MiA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRTYW1lKGxpc3QsIGxpc3QyKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHb2luZ0JhY2tBbmRGb3J0aCgpIHsKKyAgICBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCBtb2NrUGFyZW50ID0gbmV3IFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50KCk7CisgICAgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8VGVzdEFsbFR5cGVzLCBUZXN0QWxsVHlwZXMuQnVpbGRlciwKKyAgICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBidWlsZGVyID0gbmV3UmVwZWF0ZWRGaWVsZEJ1aWxkZXIobW9ja1BhcmVudCk7CisgICAgYnVpbGRlci5hZGRNZXNzYWdlKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigwKS5idWlsZCgpKTsKKyAgICBidWlsZGVyLmFkZE1lc3NhZ2UoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDEpLmJ1aWxkKCkpOworICAgIGFzc2VydEVxdWFscygwLCBidWlsZGVyLmdldE1lc3NhZ2UoMCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnVpbGRlci5nZXRNZXNzYWdlKDEpLmdldE9wdGlvbmFsSW50MzIoKSk7CisKKyAgICAvLyBDb252ZXJ0IHRvIGxpc3QKKyAgICBMaXN0PFRlc3RBbGxUeXBlcz4gbGlzdCA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbGlzdC5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBsaXN0LmdldCgwKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygxLCBsaXN0LmdldCgxKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKGxpc3QpOworCisgICAgLy8gVXBkYXRlIDB0aCBpdGVtCisgICAgYXNzZXJ0RXF1YWxzKDAsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisgICAgYnVpbGRlci5nZXRCdWlsZGVyKDApLnNldE9wdGlvbmFsU3RyaW5nKCJmb28iKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKyAgICBsaXN0ID0gYnVpbGRlci5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygyLCBsaXN0LnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGxpc3QuZ2V0KDApLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIGxpc3QuZ2V0KDApLmdldE9wdGlvbmFsU3RyaW5nKCkpOworICAgIGFzc2VydEVxdWFscygxLCBsaXN0LmdldCgxKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydElzVW5tb2RpZmlhYmxlKGxpc3QpOworICAgIGFzc2VydEVxdWFscygxLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFZhcmlvdXNNZXRob2RzKCkgeworICAgIFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50IG1vY2tQYXJlbnQgPSBuZXcgVGVzdFV0aWwuTW9ja0J1aWxkZXJQYXJlbnQoKTsKKyAgICBSZXBlYXRlZEZpZWxkQnVpbGRlcjxUZXN0QWxsVHlwZXMsIFRlc3RBbGxUeXBlcy5CdWlsZGVyLAorICAgICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGJ1aWxkZXIgPSBuZXdSZXBlYXRlZEZpZWxkQnVpbGRlcihtb2NrUGFyZW50KTsKKyAgICBidWlsZGVyLmFkZE1lc3NhZ2UoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDEpLmJ1aWxkKCkpOworICAgIGJ1aWxkZXIuYWRkTWVzc2FnZShUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLnNldE9wdGlvbmFsSW50MzIoMikuYnVpbGQoKSk7CisgICAgYnVpbGRlci5hZGRCdWlsZGVyKDAsIFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMCk7CisgICAgYnVpbGRlci5hZGRCdWlsZGVyKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkuc2V0T3B0aW9uYWxJbnQzMigzKTsKKworICAgIGFzc2VydEVxdWFscygwLCBidWlsZGVyLmdldE1lc3NhZ2UoMCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnVpbGRlci5nZXRNZXNzYWdlKDEpLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGJ1aWxkZXIuZ2V0TWVzc2FnZSgyKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygzLCBidWlsZGVyLmdldE1lc3NhZ2UoMykuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKworICAgIGFzc2VydEVxdWFscygwLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworICAgIExpc3Q8VGVzdEFsbFR5cGVzPiBtZXNzYWdlcyA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoNCwgbWVzc2FnZXMuc2l6ZSgpKTsKKyAgICBhc3NlcnRTYW1lKG1lc3NhZ2VzLCBidWlsZGVyLmJ1aWxkKCkpOyAvLyBleHBlY3Qgc2FtZSBsaXN0CisKKyAgICAvLyBSZW1vdmUgYSBtZXNzYWdlLgorICAgIGJ1aWxkZXIucmVtb3ZlKDIpOworICAgIGFzc2VydEVxdWFscygxLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworICAgIGFzc2VydEVxdWFscygzLCBidWlsZGVyLmdldENvdW50KCkpOworICAgIGFzc2VydEVxdWFscygwLCBidWlsZGVyLmdldE1lc3NhZ2UoMCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnVpbGRlci5nZXRNZXNzYWdlKDEpLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIGJ1aWxkZXIuZ2V0TWVzc2FnZSgyKS5nZXRPcHRpb25hbEludDMyKCkpOworCisgICAgLy8gUmVtb3ZlIGEgYnVpbGRlci4KKyAgICBidWlsZGVyLnJlbW92ZSgwKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgYnVpbGRlci5nZXRDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgYnVpbGRlci5nZXRNZXNzYWdlKDApLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIGJ1aWxkZXIuZ2V0TWVzc2FnZSgxKS5nZXRPcHRpb25hbEludDMyKCkpOworCisgICAgLy8gVGVzdCBjbGVhci4KKyAgICBidWlsZGVyLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGJ1aWxkZXIuZ2V0Q291bnQoKSk7CisgICAgYXNzZXJ0VHJ1ZShidWlsZGVyLmlzRW1wdHkoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TGlzdHMoKSB7CisgICAgVGVzdFV0aWwuTW9ja0J1aWxkZXJQYXJlbnQgbW9ja1BhcmVudCA9IG5ldyBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCgpOworICAgIFJlcGVhdGVkRmllbGRCdWlsZGVyPFRlc3RBbGxUeXBlcywgVGVzdEFsbFR5cGVzLkJ1aWxkZXIsCisgICAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gYnVpbGRlciA9IG5ld1JlcGVhdGVkRmllbGRCdWlsZGVyKG1vY2tQYXJlbnQpOworICAgIGJ1aWxkZXIuYWRkTWVzc2FnZShUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLnNldE9wdGlvbmFsSW50MzIoMSkuYnVpbGQoKSk7CisgICAgYnVpbGRlci5hZGRNZXNzYWdlKDAsCisgICAgICAgIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigwKS5idWlsZCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgYnVpbGRlci5nZXRNZXNzYWdlKDApLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGJ1aWxkZXIuZ2V0TWVzc2FnZSgxKS5nZXRPcHRpb25hbEludDMyKCkpOworCisgICAgLy8gVXNlIGxpc3Qgb2YgYnVpbGRlcnMuCisgICAgTGlzdDxUZXN0QWxsVHlwZXMuQnVpbGRlcj4gYnVpbGRlcnMgPSBidWlsZGVyLmdldEJ1aWxkZXJMaXN0KCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGJ1aWxkZXJzLmdldCgwKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygxLCBidWlsZGVycy5nZXQoMSkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBidWlsZGVycy5nZXQoMCkuc2V0T3B0aW9uYWxJbnQzMigxMCk7CisgICAgYnVpbGRlcnMuZ2V0KDEpLnNldE9wdGlvbmFsSW50MzIoMTEpOworCisgICAgLy8gVXNlIGxpc3Qgb2YgcHJvdG9zCisgICAgTGlzdDxUZXN0QWxsVHlwZXM+IHByb3RvcyA9IGJ1aWxkZXIuZ2V0TWVzc2FnZUxpc3QoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTAsIHByb3Rvcy5nZXQoMCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTEsIHByb3Rvcy5nZXQoMSkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKworICAgIC8vIEFkZCBhbiBpdGVtIHRvIHRoZSBidWlsZGVycyBhbmQgdmVyaWZ5IGl0J3MgdXBkYXRlZCBpbiBib3RoCisgICAgYnVpbGRlci5hZGRNZXNzYWdlKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigxMikuYnVpbGQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIGJ1aWxkZXJzLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIHByb3Rvcy5zaXplKCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydElzVW5tb2RpZmlhYmxlKExpc3Q8Pz4gbGlzdCkgeworICAgIGlmIChsaXN0ID09IENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpKSB7CisgICAgICAvLyBPS0FZIC0tIE5lZWQgdG8gY2hlY2sgdGhpcyBiL2MgRW1wdHlMaXN0IGFsbG93cyB5b3UgdG8gY2FsbCBjbGVhci4KKyAgICB9IGVsc2UgeworICAgICAgdHJ5IHsKKyAgICAgICAgbGlzdC5jbGVhcigpOworICAgICAgICBmYWlsKCJMaXN0IHdhc24ndCBpbW11dGFibGUiKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gZ29vZAorICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8VGVzdEFsbFR5cGVzLCBUZXN0QWxsVHlwZXMuQnVpbGRlciwKKyAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlcj4KKyAgICAgIG5ld1JlcGVhdGVkRmllbGRCdWlsZGVyKEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKKyAgICByZXR1cm4gbmV3IFJlcGVhdGVkRmllbGRCdWlsZGVyPFRlc3RBbGxUeXBlcywgVGVzdEFsbFR5cGVzLkJ1aWxkZXIsCisgICAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlcj4oQ29sbGVjdGlvbnMuPFRlc3RBbGxUeXBlcz5lbXB0eUxpc3QoKSwgZmFsc2UsCisgICAgICAgIHBhcmVudCwgZmFsc2UpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Sb3BlQnl0ZVN0cmluZ1N1YnN0cmluZ1Rlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1JvcGVCeXRlU3RyaW5nU3Vic3RyaW5nVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxMmY4ZDYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Sb3BlQnl0ZVN0cmluZ1N1YnN0cmluZ1Rlc3QuamF2YQpAQCAtMCwwICsxLDk3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHRlc3RzIHtAbGluayBSb3BlQnl0ZVN0cmluZyNzdWJzdHJpbmcoaW50LCBpbnQpfSBieSBpbmhlcml0aW5nIHRoZSB0ZXN0cyBmcm9tCisgKiB7QGxpbmsgTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0fS4gIE9ubHkgYSBjb3VwbGUgb2YgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbi4gIAorICoKKyAqIEBhdXRob3IgY2FybGFudG9uQGdvb2dsZS5jb20gKENhcmwgSGF2ZXJsKQorICovCitwdWJsaWMgY2xhc3MgUm9wZUJ5dGVTdHJpbmdTdWJzdHJpbmdUZXN0IGV4dGVuZHMgTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0IHsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjbGFzc1VuZGVyVGVzdCA9ICJSb3BlQnl0ZVN0cmluZyI7CisgICAgYnl0ZVtdIHNvdXJjZUJ5dGVzID0gQnl0ZVN0cmluZ1Rlc3QuZ2V0VGVzdEJ5dGVzKDIyMzQxLCAyMjMzNzc2NkwpOworICAgIEl0ZXJhdG9yPEJ5dGVTdHJpbmc+IGl0ZXIgPSBCeXRlU3RyaW5nVGVzdC5tYWtlQ29uY3JldGVQaWVjZXMoc291cmNlQnl0ZXMpLml0ZXJhdG9yKCk7CisgICAgQnl0ZVN0cmluZyBzb3VyY2VTdHJpbmcgPSBpdGVyLm5leHQoKTsKKyAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgIHNvdXJjZVN0cmluZyA9IHNvdXJjZVN0cmluZy5jb25jYXQoaXRlci5uZXh0KCkpOworICAgIH0KKworICAgIGludCBmcm9tID0gMTEzMDsKKyAgICBpbnQgdG8gPSBzb3VyY2VCeXRlcy5sZW5ndGggLSA1NTU1OworICAgIHN0cmluZ1VuZGVyVGVzdCA9IHNvdXJjZVN0cmluZy5zdWJzdHJpbmcoZnJvbSwgdG8pOworICAgIHJlZmVyZW5jZUJ5dGVzID0gbmV3IGJ5dGVbdG8gLSBmcm9tXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KHNvdXJjZUJ5dGVzLCBmcm9tLCByZWZlcmVuY2VCeXRlcywgMCwgdG8gLSBmcm9tKTsKKyAgICBleHBlY3RlZEhhc2hDb2RlID0gLTEyNTkyNjA2ODA7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVzdEdldFRyZWVEZXB0aCgpIHsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIG11c3QgaGF2ZSB0aGUgZXhwZWN0ZWQgdHJlZSBkZXB0aCIsCisgICAgICAgIDMsIHN0cmluZ1VuZGVyVGVzdC5nZXRUcmVlRGVwdGgoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIFN0cmluZyBzb3VyY2VTdHJpbmcgPSAiSSBsb3ZlIHVuaWNvZGUgXHUxMjM0XHU1Njc4IGNoYXJhY3RlcnMiOworICAgIEJ5dGVTdHJpbmcgc291cmNlQnl0ZVN0cmluZyA9IEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KHNvdXJjZVN0cmluZyk7CisgICAgaW50IGNvcGllcyA9IDI1MDsKKworICAgIC8vIEJ5IGJ1aWxkaW5nIHRoZSBSb3BlQnl0ZVN0cmluZyBieSBjb25jYXRlbmF0aW5nLCB0aGlzIGlzIGFjdHVhbGx5IGEgZmFpcmx5IHN0cmVudW91cyB0ZXN0LgorICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKGNvcGllcyAqIHNvdXJjZVN0cmluZy5sZW5ndGgoKSk7CisgICAgQnl0ZVN0cmluZyB1bmljb2RlID0gQnl0ZVN0cmluZy5FTVBUWTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvcGllczsgKytpKSB7CisgICAgICBidWlsZGVyLmFwcGVuZChzb3VyY2VTdHJpbmcpOworICAgICAgdW5pY29kZSA9IFJvcGVCeXRlU3RyaW5nLmNvbmNhdGVuYXRlKHVuaWNvZGUsIHNvdXJjZUJ5dGVTdHJpbmcpOworICAgIH0KKyAgICBTdHJpbmcgdGVzdFN0cmluZyA9IGJ1aWxkZXIudG9TdHJpbmcoKTsKKworICAgIC8vIERvIHRoZSBzdWJzdHJpbmcgcGFydAorICAgIHRlc3RTdHJpbmcgPSB0ZXN0U3RyaW5nLnN1YnN0cmluZygyLCB0ZXN0U3RyaW5nLmxlbmd0aCgpIC0gNik7CisgICAgdW5pY29kZSA9IHVuaWNvZGUuc3Vic3RyaW5nKDIsIHVuaWNvZGUuc2l6ZSgpIC0gNik7CisKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIGZyb20gc3RyaW5nIG11c3QgaGF2ZSB0aGUgZXhwZWN0ZWQgdHlwZSIsCisgICAgICAgIGNsYXNzVW5kZXJUZXN0LCBnZXRBY3R1YWxDbGFzc05hbWUodW5pY29kZSkpOworICAgIFN0cmluZyByb3VuZFRyaXBTdHJpbmcgPSB1bmljb2RlLnRvU3RyaW5nKFVURl84KTsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIHVuaWNvZGUgYnl0ZXMgbXVzdCBtYXRjaCIsCisgICAgICAgIHRlc3RTdHJpbmcsIHJvdW5kVHJpcFN0cmluZyk7CisgICAgQnl0ZVN0cmluZyBmbGF0U3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgodGVzdFN0cmluZyk7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIiBzdHJpbmcgbXVzdCBlcXVhbCB0aGUgZmxhdCBzdHJpbmciLCBmbGF0U3RyaW5nLCB1bmljb2RlKTsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIHN0cmluZyBtdXN0IG11c3QgaGF2ZSBzYW1lIGhhc2hDb2RlIGFzIHRoZSBmbGF0IHN0cmluZyIsCisgICAgICAgIGZsYXRTdHJpbmcuaGFzaENvZGUoKSwgdW5pY29kZS5oYXNoQ29kZSgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUm9wZUJ5dGVTdHJpbmdUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Sb3BlQnl0ZVN0cmluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjIzNDRkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvUm9wZUJ5dGVTdHJpbmdUZXN0LmphdmEKQEAgLTAsMCArMSwxNjEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CisKKy8qKgorICogVGhpcyBjbGFzcyB0ZXN0cyB7QGxpbmsgUm9wZUJ5dGVTdHJpbmd9IGJ5IGluaGVyaXRpbmcgdGhlIHRlc3RzIGZyb20KKyAqIHtAbGluayBMaXRlcmFsQnl0ZVN0cmluZ1Rlc3R9LiAgT25seSBhIGNvdXBsZSBvZiBtZXRob2RzIGFyZSBvdmVycmlkZGVuLgorICogCisgKiA8cD5BIGZ1bGwgdGVzdCBvZiB0aGUgcmVzdWx0IG9mIHtAbGluayBSb3BlQnl0ZVN0cmluZyNzdWJzdHJpbmcoaW50LCBpbnQpfSBpcyBmb3VuZCBpbiB0aGUKKyAqIHNlcGFyYXRlIGNsYXNzIHtAbGluayBSb3BlQnl0ZVN0cmluZ1N1YnN0cmluZ1Rlc3R9LgorICoKKyAqIEBhdXRob3IgY2FybGFudG9uQGdvb2dsZS5jb20gKENhcmwgSGF2ZXJsKQorICovCitwdWJsaWMgY2xhc3MgUm9wZUJ5dGVTdHJpbmdUZXN0IGV4dGVuZHMgTGl0ZXJhbEJ5dGVTdHJpbmdUZXN0IHsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjbGFzc1VuZGVyVGVzdCA9ICJSb3BlQnl0ZVN0cmluZyI7CisgICAgcmVmZXJlbmNlQnl0ZXMgPSBCeXRlU3RyaW5nVGVzdC5nZXRUZXN0Qnl0ZXMoMjIzNDEsIDIyMzM3NzY2TCk7CisgICAgSXRlcmF0b3I8Qnl0ZVN0cmluZz4gaXRlciA9IEJ5dGVTdHJpbmdUZXN0Lm1ha2VDb25jcmV0ZVBpZWNlcyhyZWZlcmVuY2VCeXRlcykuaXRlcmF0b3IoKTsKKyAgICBzdHJpbmdVbmRlclRlc3QgPSBpdGVyLm5leHQoKTsKKyAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgIHN0cmluZ1VuZGVyVGVzdCA9IHN0cmluZ1VuZGVyVGVzdC5jb25jYXQoaXRlci5uZXh0KCkpOworICAgIH0KKyAgICBleHBlY3RlZEhhc2hDb2RlID0gLTEyMTQxOTcyMzg7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVzdEdldFRyZWVEZXB0aCgpIHsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIG11c3QgaGF2ZSB0aGUgZXhwZWN0ZWQgdHJlZSBkZXB0aCIsCisgICAgICAgIDQsIHN0cmluZ1VuZGVyVGVzdC5nZXRUcmVlRGVwdGgoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QmFsYW5jZSgpIHsKKyAgICBpbnQgbnVtYmVyT2ZQaWVjZXMgPSAxMDAwMDsKKyAgICBpbnQgcGllY2VTaXplID0gNjQ7CisgICAgYnl0ZVtdIHRlc3RCeXRlcyA9IEJ5dGVTdHJpbmdUZXN0LmdldFRlc3RCeXRlcyhudW1iZXJPZlBpZWNlcyAqIHBpZWNlU2l6ZSwgMTEzMzc3TCk7CisKKyAgICAvLyBCdWlsZCB1cCBhIGJpZyBCeXRlU3RyaW5nIGZyb20gc21hbGxlciBwaWVjZXMgdG8gZm9yY2UgYSByZWJhbGFuY2UKKyAgICBCeXRlU3RyaW5nIGNvbmNhdGVuYXRlZCA9IEJ5dGVTdHJpbmcuRU1QVFk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1iZXJPZlBpZWNlczsgKytpKSB7CisgICAgICBjb25jYXRlbmF0ZWQgPSBjb25jYXRlbmF0ZWQuY29uY2F0KEJ5dGVTdHJpbmcuY29weUZyb20odGVzdEJ5dGVzLCBpICogcGllY2VTaXplLCBwaWVjZVNpemUpKTsKKyAgICB9CisKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIGZyb20gc3RyaW5nIG11c3QgaGF2ZSB0aGUgZXhwZWN0ZWQgdHlwZSIsCisgICAgICAgIGNsYXNzVW5kZXJUZXN0LCBnZXRBY3R1YWxDbGFzc05hbWUoY29uY2F0ZW5hdGVkKSk7CisgICAgYXNzZXJ0VHJ1ZShjbGFzc1VuZGVyVGVzdCArICIgdW5kZXJseWluZyBieXRlcyBtdXN0IG1hdGNoIGFmdGVyIGJhbGFuY2luZyIsCisgICAgICAgIEFycmF5cy5lcXVhbHModGVzdEJ5dGVzLCBjb25jYXRlbmF0ZWQudG9CeXRlQXJyYXkoKSkpOworICAgIEJ5dGVTdHJpbmcgdGVzdFN0cmluZyA9IEJ5dGVTdHJpbmcuY29weUZyb20odGVzdEJ5dGVzKTsKKyAgICBhc3NlcnRUcnVlKGNsYXNzVW5kZXJUZXN0ICsgIiBiYWxhbmNlZCBzdHJpbmcgbXVzdCBlcXVhbCBmbGF0IHN0cmluZyIsCisgICAgICAgIGNvbmNhdGVuYXRlZC5lcXVhbHModGVzdFN0cmluZykpOworICAgIGFzc2VydFRydWUoY2xhc3NVbmRlclRlc3QgKyAiIGZsYXQgc3RyaW5nIG11c3QgZXF1YWwgYmFsYW5jZWQgc3RyaW5nIiwKKyAgICAgICAgdGVzdFN0cmluZy5lcXVhbHMoY29uY2F0ZW5hdGVkKSk7CisgICAgYXNzZXJ0RXF1YWxzKGNsYXNzVW5kZXJUZXN0ICsgIiBiYWxhbmNlZCBzdHJpbmcgbXVzdCBoYXZlIHNhbWUgaGFzaCBjb2RlIGFzIGZsYXQgc3RyaW5nIiwKKyAgICAgICAgdGVzdFN0cmluZy5oYXNoQ29kZSgpLCBjb25jYXRlbmF0ZWQuaGFzaENvZGUoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIFN0cmluZyBzb3VyY2VTdHJpbmcgPSAiSSBsb3ZlIHVuaWNvZGUgXHUxMjM0XHU1Njc4IGNoYXJhY3RlcnMiOworICAgIEJ5dGVTdHJpbmcgc291cmNlQnl0ZVN0cmluZyA9IEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KHNvdXJjZVN0cmluZyk7CisgICAgaW50IGNvcGllcyA9IDI1MDsKKworICAgIC8vIEJ5IGJ1aWxkaW5nIHRoZSBSb3BlQnl0ZVN0cmluZyBieSBjb25jYXRlbmF0aW5nLCB0aGlzIGlzIGFjdHVhbGx5IGEgZmFpcmx5IHN0cmVudW91cyB0ZXN0LgorICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKGNvcGllcyAqIHNvdXJjZVN0cmluZy5sZW5ndGgoKSk7CisgICAgQnl0ZVN0cmluZyB1bmljb2RlID0gQnl0ZVN0cmluZy5FTVBUWTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvcGllczsgKytpKSB7CisgICAgICBidWlsZGVyLmFwcGVuZChzb3VyY2VTdHJpbmcpOworICAgICAgdW5pY29kZSA9IFJvcGVCeXRlU3RyaW5nLmNvbmNhdGVuYXRlKHVuaWNvZGUsIHNvdXJjZUJ5dGVTdHJpbmcpOworICAgIH0KKyAgICBTdHJpbmcgdGVzdFN0cmluZyA9IGJ1aWxkZXIudG9TdHJpbmcoKTsKKworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgZnJvbSBzdHJpbmcgbXVzdCBoYXZlIHRoZSBleHBlY3RlZCB0eXBlIiwKKyAgICAgICAgY2xhc3NVbmRlclRlc3QsIGdldEFjdHVhbENsYXNzTmFtZSh1bmljb2RlKSk7CisgICAgU3RyaW5nIHJvdW5kVHJpcFN0cmluZyA9IHVuaWNvZGUudG9TdHJpbmcoVVRGXzgpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgdW5pY29kZSBieXRlcyBtdXN0IG1hdGNoIiwKKyAgICAgICAgdGVzdFN0cmluZywgcm91bmRUcmlwU3RyaW5nKTsKKyAgICBCeXRlU3RyaW5nIGZsYXRTdHJpbmcgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCh0ZXN0U3RyaW5nKTsKKyAgICBhc3NlcnRFcXVhbHMoY2xhc3NVbmRlclRlc3QgKyAiIHN0cmluZyBtdXN0IGVxdWFsIHRoZSBmbGF0IHN0cmluZyIsIGZsYXRTdHJpbmcsIHVuaWNvZGUpOworICAgIGFzc2VydEVxdWFscyhjbGFzc1VuZGVyVGVzdCArICIgc3RyaW5nIG11c3QgbXVzdCBoYXZlIHNhbWUgaGFzaENvZGUgYXMgdGhlIGZsYXQgc3RyaW5nIiwKKyAgICAgICAgZmxhdFN0cmluZy5oYXNoQ29kZSgpLCB1bmljb2RlLmhhc2hDb2RlKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZ19yZXR1cm5zQ2Fub25pY2FsRW1wdHlTdHJpbmcoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgUm9wZUJ5dGVTdHJpbmcgcm9wZUJ5dGVTdHJpbmcgPQorICAgICAgICBSb3BlQnl0ZVN0cmluZy5uZXdJbnN0YW5jZUZvclRlc3QoQnl0ZVN0cmluZy5FTVBUWSwgQnl0ZVN0cmluZy5FTVBUWSk7CisgICAgYXNzZXJ0U2FtZShjbGFzc1VuZGVyVGVzdCArICIgbXVzdCBiZSB0aGUgc2FtZSBzdHJpbmcgcmVmZXJlbmNlcyIsCisgICAgICAgIEJ5dGVTdHJpbmcuRU1QVFkudG9TdHJpbmcoVVRGXzgpLCByb3BlQnl0ZVN0cmluZy50b1N0cmluZyhVVEZfOCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nX3JhaXNlc0V4Y2VwdGlvbigpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9ueworICAgIHRyeSB7CisgICAgICBCeXRlU3RyaW5nIGJ5dGVTdHJpbmcgPQorICAgICAgICAgIFJvcGVCeXRlU3RyaW5nLm5ld0luc3RhbmNlRm9yVGVzdChCeXRlU3RyaW5nLkVNUFRZLCBCeXRlU3RyaW5nLkVNUFRZKTsKKyAgICAgIGJ5dGVTdHJpbmcudG9TdHJpbmcoImludmFsaWQiKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgLy8gVGhpcyBpcyBzdWNjZXNzCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZyA9IFJvcGVCeXRlU3RyaW5nLmNvbmNhdGVuYXRlKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJmb28iKSwKKyAgICAgICAgICBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiYmFyIikpOworICAgICAgYnl0ZVN0cmluZy50b1N0cmluZygiaW52YWxpZCIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAvLyBUaGlzIGlzIHN1Y2Nlc3MKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SmF2YVNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCk7CisgICAgb29zLndyaXRlT2JqZWN0KHN0cmluZ1VuZGVyVGVzdCk7CisgICAgb29zLmNsb3NlKCk7CisgICAgYnl0ZVtdIHBpY2tsZWQgPSBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShwaWNrbGVkKTsKKyAgICBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oaW4pOworICAgIE9iamVjdCBvID0gb2lzLnJlYWRPYmplY3QoKTsKKyAgICBhc3NlcnRUcnVlKCJEaWRuJ3QgZ2V0IGEgQnl0ZVN0cmluZyBiYWNrIiwgbyBpbnN0YW5jZW9mIEJ5dGVTdHJpbmcpOworICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGdldCBhbiBlcXVhbCBCeXRlU3RyaW5nIGJhY2siLCBzdHJpbmdVbmRlclRlc3QsIG8pOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9TZXJ2aWNlVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2VydmljZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjk4MGQ2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2VydmljZVRlc3QuamF2YQpAQCAtMCwwICsxLDMyMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yOworaW1wb3J0IGdvb2dsZS5wcm90b2J1Zi5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXI7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuU2VydmljZVdpdGhOb091dGVyOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFNlcnZpY2U7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0OworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2U7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0OworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2U7CisKK2ltcG9ydCBvcmcuZWFzeW1vY2suY2xhc3NleHRlbnNpb24uRWFzeU1vY2s7CitpbXBvcnQgb3JnLmVhc3ltb2NrLmNsYXNzZXh0ZW5zaW9uLklNb2Nrc0NvbnRyb2w7CitpbXBvcnQgb3JnLmVhc3ltb2NrLklBcmd1bWVudE1hdGNoZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIHNlcnZpY2VzIGFuZCBzdHVicy4KKyAqCisgKiBAYXV0aG9yIGtlbnRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgY2xhc3MgU2VydmljZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgSU1vY2tzQ29udHJvbCBjb250cm9sOworICBwcml2YXRlIFJwY0NvbnRyb2xsZXIgbW9ja0NvbnRyb2xsZXI7CisKKyAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIGZvb0Rlc2NyaXB0b3IgPQorICAgIFRlc3RTZXJ2aWNlLmdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDApOworICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgYmFyRGVzY3JpcHRvciA9CisgICAgVGVzdFNlcnZpY2UuZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoMSk7CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICBjb250cm9sID0gRWFzeU1vY2suY3JlYXRlU3RyaWN0Q29udHJvbCgpOworICAgIG1vY2tDb250cm9sbGVyID0gY29udHJvbC5jcmVhdGVNb2NrKFJwY0NvbnRyb2xsZXIuY2xhc3MpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKiogVGVzdHMgU2VydmljZS5jYWxsTWV0aG9kKCkuICovCisgIHB1YmxpYyB2b2lkIHRlc3RDYWxsTWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRm9vUmVxdWVzdCBmb29SZXF1ZXN0ID0gRm9vUmVxdWVzdC5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBCYXJSZXF1ZXN0IGJhclJlcXVlc3QgPSBCYXJSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5idWlsZCgpOworICAgIE1vY2tDYWxsYmFjazxNZXNzYWdlPiBmb29DYWxsYmFjayA9IG5ldyBNb2NrQ2FsbGJhY2s8TWVzc2FnZT4oKTsKKyAgICBNb2NrQ2FsbGJhY2s8TWVzc2FnZT4gYmFyQ2FsbGJhY2sgPSBuZXcgTW9ja0NhbGxiYWNrPE1lc3NhZ2U+KCk7CisgICAgVGVzdFNlcnZpY2UgbW9ja1NlcnZpY2UgPSBjb250cm9sLmNyZWF0ZU1vY2soVGVzdFNlcnZpY2UuY2xhc3MpOworCisgICAgbW9ja1NlcnZpY2UuZm9vKEVhc3lNb2NrLnNhbWUobW9ja0NvbnRyb2xsZXIpLCBFYXN5TW9jay5zYW1lKGZvb1JlcXVlc3QpLAorICAgICAgICAgICAgICAgICAgICB0aGlzLjxGb29SZXNwb25zZT53cmFwc0NhbGxiYWNrKGZvb0NhbGxiYWNrKSk7CisgICAgbW9ja1NlcnZpY2UuYmFyKEVhc3lNb2NrLnNhbWUobW9ja0NvbnRyb2xsZXIpLCBFYXN5TW9jay5zYW1lKGJhclJlcXVlc3QpLAorICAgICAgICAgICAgICAgICAgICB0aGlzLjxCYXJSZXNwb25zZT53cmFwc0NhbGxiYWNrKGJhckNhbGxiYWNrKSk7CisgICAgY29udHJvbC5yZXBsYXkoKTsKKworICAgIG1vY2tTZXJ2aWNlLmNhbGxNZXRob2QoZm9vRGVzY3JpcHRvciwgbW9ja0NvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmb29SZXF1ZXN0LCBmb29DYWxsYmFjayk7CisgICAgbW9ja1NlcnZpY2UuY2FsbE1ldGhvZChiYXJEZXNjcmlwdG9yLCBtb2NrQ29udHJvbGxlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhclJlcXVlc3QsIGJhckNhbGxiYWNrKTsKKyAgICBjb250cm9sLnZlcmlmeSgpOworICB9CisKKyAgLyoqIFRlc3RzIFNlcnZpY2UuZ2V0e1JlcXVlc3QsUmVzcG9uc2V9UHJvdG90eXBlKCkuICovCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcm90b3R5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0U2VydmljZSBtb2NrU2VydmljZSA9IGNvbnRyb2wuY3JlYXRlTW9jayhUZXN0U2VydmljZS5jbGFzcyk7CisKKyAgICBhc3NlcnRTYW1lKG1vY2tTZXJ2aWNlLmdldFJlcXVlc3RQcm90b3R5cGUoZm9vRGVzY3JpcHRvciksCisgICAgICAgICAgICAgICBGb29SZXF1ZXN0LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICBhc3NlcnRTYW1lKG1vY2tTZXJ2aWNlLmdldFJlc3BvbnNlUHJvdG90eXBlKGZvb0Rlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgRm9vUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICAgIGFzc2VydFNhbWUobW9ja1NlcnZpY2UuZ2V0UmVxdWVzdFByb3RvdHlwZShiYXJEZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgIEJhclJlcXVlc3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICAgIGFzc2VydFNhbWUobW9ja1NlcnZpY2UuZ2V0UmVzcG9uc2VQcm90b3R5cGUoYmFyRGVzY3JpcHRvciksCisgICAgICAgICAgICAgICBCYXJSZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgIH0KKworICAvKiogVGVzdHMgZ2VuZXJhdGVkIHN0dWJzLiAqLworICBwdWJsaWMgdm9pZCB0ZXN0U3R1YigpIHRocm93cyBFeGNlcHRpb24geworICAgIEZvb1JlcXVlc3QgZm9vUmVxdWVzdCA9IEZvb1JlcXVlc3QubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisgICAgQmFyUmVxdWVzdCBiYXJSZXF1ZXN0ID0gQmFyUmVxdWVzdC5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBNb2NrQ2FsbGJhY2s8Rm9vUmVzcG9uc2U+IGZvb0NhbGxiYWNrID0gbmV3IE1vY2tDYWxsYmFjazxGb29SZXNwb25zZT4oKTsKKyAgICBNb2NrQ2FsbGJhY2s8QmFyUmVzcG9uc2U+IGJhckNhbGxiYWNrID0gbmV3IE1vY2tDYWxsYmFjazxCYXJSZXNwb25zZT4oKTsKKyAgICBScGNDaGFubmVsIG1vY2tDaGFubmVsID0gY29udHJvbC5jcmVhdGVNb2NrKFJwY0NoYW5uZWwuY2xhc3MpOworICAgIFRlc3RTZXJ2aWNlIHN0dWIgPSBUZXN0U2VydmljZS5uZXdTdHViKG1vY2tDaGFubmVsKTsKKworICAgIG1vY2tDaGFubmVsLmNhbGxNZXRob2QoCisgICAgICBFYXN5TW9jay5zYW1lKGZvb0Rlc2NyaXB0b3IpLAorICAgICAgRWFzeU1vY2suc2FtZShtb2NrQ29udHJvbGxlciksCisgICAgICBFYXN5TW9jay5zYW1lKGZvb1JlcXVlc3QpLAorICAgICAgRWFzeU1vY2suc2FtZShGb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSksCisgICAgICB0aGlzLjxNZXNzYWdlPndyYXBzQ2FsbGJhY2soZm9vQ2FsbGJhY2spKTsKKyAgICBtb2NrQ2hhbm5lbC5jYWxsTWV0aG9kKAorICAgICAgRWFzeU1vY2suc2FtZShiYXJEZXNjcmlwdG9yKSwKKyAgICAgIEVhc3lNb2NrLnNhbWUobW9ja0NvbnRyb2xsZXIpLAorICAgICAgRWFzeU1vY2suc2FtZShiYXJSZXF1ZXN0KSwKKyAgICAgIEVhc3lNb2NrLnNhbWUoQmFyUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpLAorICAgICAgdGhpcy48TWVzc2FnZT53cmFwc0NhbGxiYWNrKGJhckNhbGxiYWNrKSk7CisgICAgY29udHJvbC5yZXBsYXkoKTsKKworICAgIHN0dWIuZm9vKG1vY2tDb250cm9sbGVyLCBmb29SZXF1ZXN0LCBmb29DYWxsYmFjayk7CisgICAgc3R1Yi5iYXIobW9ja0NvbnRyb2xsZXIsIGJhclJlcXVlc3QsIGJhckNhbGxiYWNrKTsKKyAgICBjb250cm9sLnZlcmlmeSgpOworICB9CisKKyAgLyoqIFRlc3RzIGdlbmVyYXRlZCBibG9ja2luZyBzdHVicy4gKi8KKyAgcHVibGljIHZvaWQgdGVzdEJsb2NraW5nU3R1YigpIHRocm93cyBFeGNlcHRpb24geworICAgIEZvb1JlcXVlc3QgZm9vUmVxdWVzdCA9IEZvb1JlcXVlc3QubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisgICAgQmFyUmVxdWVzdCBiYXJSZXF1ZXN0ID0gQmFyUmVxdWVzdC5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBCbG9ja2luZ1JwY0NoYW5uZWwgbW9ja0NoYW5uZWwgPQorICAgICAgICBjb250cm9sLmNyZWF0ZU1vY2soQmxvY2tpbmdScGNDaGFubmVsLmNsYXNzKTsKKyAgICBUZXN0U2VydmljZS5CbG9ja2luZ0ludGVyZmFjZSBzdHViID0KKyAgICAgICAgVGVzdFNlcnZpY2UubmV3QmxvY2tpbmdTdHViKG1vY2tDaGFubmVsKTsKKworICAgIEZvb1Jlc3BvbnNlIGZvb1Jlc3BvbnNlID0gRm9vUmVzcG9uc2UubmV3QnVpbGRlcigpLmJ1aWxkKCk7CisgICAgQmFyUmVzcG9uc2UgYmFyUmVzcG9uc2UgPSBCYXJSZXNwb25zZS5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKworICAgIEVhc3lNb2NrLmV4cGVjdChtb2NrQ2hhbm5lbC5jYWxsQmxvY2tpbmdNZXRob2QoCisgICAgICBFYXN5TW9jay5zYW1lKGZvb0Rlc2NyaXB0b3IpLAorICAgICAgRWFzeU1vY2suc2FtZShtb2NrQ29udHJvbGxlciksCisgICAgICBFYXN5TW9jay5zYW1lKGZvb1JlcXVlc3QpLAorICAgICAgRWFzeU1vY2suc2FtZShGb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpKS5hbmRSZXR1cm4oZm9vUmVzcG9uc2UpOworICAgIEVhc3lNb2NrLmV4cGVjdChtb2NrQ2hhbm5lbC5jYWxsQmxvY2tpbmdNZXRob2QoCisgICAgICBFYXN5TW9jay5zYW1lKGJhckRlc2NyaXB0b3IpLAorICAgICAgRWFzeU1vY2suc2FtZShtb2NrQ29udHJvbGxlciksCisgICAgICBFYXN5TW9jay5zYW1lKGJhclJlcXVlc3QpLAorICAgICAgRWFzeU1vY2suc2FtZShCYXJSZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpKS5hbmRSZXR1cm4oYmFyUmVzcG9uc2UpOworICAgIGNvbnRyb2wucmVwbGF5KCk7CisKKyAgICBhc3NlcnRTYW1lKGZvb1Jlc3BvbnNlLCBzdHViLmZvbyhtb2NrQ29udHJvbGxlciwgZm9vUmVxdWVzdCkpOworICAgIGFzc2VydFNhbWUoYmFyUmVzcG9uc2UsIHN0dWIuYmFyKG1vY2tDb250cm9sbGVyLCBiYXJSZXF1ZXN0KSk7CisgICAgY29udHJvbC52ZXJpZnkoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROZXdSZWZsZWN0aXZlU2VydmljZSgpIHsKKyAgICBTZXJ2aWNlV2l0aE5vT3V0ZXIuSW50ZXJmYWNlIGltcGwgPQorICAgICAgICBjb250cm9sLmNyZWF0ZU1vY2soU2VydmljZVdpdGhOb091dGVyLkludGVyZmFjZS5jbGFzcyk7CisgICAgUnBjQ29udHJvbGxlciBjb250cm9sbGVyID0gY29udHJvbC5jcmVhdGVNb2NrKFJwY0NvbnRyb2xsZXIuY2xhc3MpOworICAgIFNlcnZpY2Ugc2VydmljZSA9IFNlcnZpY2VXaXRoTm9PdXRlci5uZXdSZWZsZWN0aXZlU2VydmljZShpbXBsKTsKKworICAgIE1ldGhvZERlc2NyaXB0b3IgZm9vTWV0aG9kID0KKyAgICAgICAgU2VydmljZVdpdGhOb091dGVyLmdldERlc2NyaXB0b3IoKS5maW5kTWV0aG9kQnlOYW1lKCJGb28iKTsKKyAgICBNZXNzYWdlV2l0aE5vT3V0ZXIgcmVxdWVzdCA9IE1lc3NhZ2VXaXRoTm9PdXRlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICBScGNDYWxsYmFjazxNZXNzYWdlPiBjYWxsYmFjayA9IG5ldyBScGNDYWxsYmFjazxNZXNzYWdlPigpIHsKKyAgICAgIHB1YmxpYyB2b2lkIHJ1bihNZXNzYWdlIHBhcmFtZXRlcikgeworICAgICAgICAvLyBObyByZWFzb24gdGhpcyBzaG91bGQgYmUgcnVuLgorICAgICAgICBmYWlsKCk7CisgICAgICB9CisgICAgfTsKKyAgICBScGNDYWxsYmFjazxUZXN0QWxsVHlwZXM+IHNwZWNpYWxpemVkQ2FsbGJhY2sgPQorICAgICAgICBScGNVdGlsLnNwZWNpYWxpemVDYWxsYmFjayhjYWxsYmFjayk7CisKKyAgICBpbXBsLmZvbyhFYXN5TW9jay5zYW1lKGNvbnRyb2xsZXIpLCBFYXN5TW9jay5zYW1lKHJlcXVlc3QpLAorICAgICAgICBFYXN5TW9jay5zYW1lKHNwZWNpYWxpemVkQ2FsbGJhY2spKTsKKyAgICBFYXN5TW9jay5leHBlY3RMYXN0Q2FsbCgpOworCisgICAgY29udHJvbC5yZXBsYXkoKTsKKworICAgIHNlcnZpY2UuY2FsbE1ldGhvZChmb29NZXRob2QsIGNvbnRyb2xsZXIsIHJlcXVlc3QsIGNhbGxiYWNrKTsKKworICAgIGNvbnRyb2wudmVyaWZ5KCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmV3UmVmbGVjdGl2ZUJsb2NraW5nU2VydmljZSgpIHRocm93cyBTZXJ2aWNlRXhjZXB0aW9uIHsKKyAgICBTZXJ2aWNlV2l0aE5vT3V0ZXIuQmxvY2tpbmdJbnRlcmZhY2UgaW1wbCA9CisgICAgICAgIGNvbnRyb2wuY3JlYXRlTW9jayhTZXJ2aWNlV2l0aE5vT3V0ZXIuQmxvY2tpbmdJbnRlcmZhY2UuY2xhc3MpOworICAgIFJwY0NvbnRyb2xsZXIgY29udHJvbGxlciA9IGNvbnRyb2wuY3JlYXRlTW9jayhScGNDb250cm9sbGVyLmNsYXNzKTsKKyAgICBCbG9ja2luZ1NlcnZpY2Ugc2VydmljZSA9CisgICAgICAgIFNlcnZpY2VXaXRoTm9PdXRlci5uZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlKGltcGwpOworCisgICAgTWV0aG9kRGVzY3JpcHRvciBmb29NZXRob2QgPQorICAgICAgICBTZXJ2aWNlV2l0aE5vT3V0ZXIuZ2V0RGVzY3JpcHRvcigpLmZpbmRNZXRob2RCeU5hbWUoIkZvbyIpOworICAgIE1lc3NhZ2VXaXRoTm9PdXRlciByZXF1ZXN0ID0gTWVzc2FnZVdpdGhOb091dGVyLmdldERlZmF1bHRJbnN0YW5jZSgpOworCisgICAgVGVzdEFsbFR5cGVzIGV4cGVjdGVkUmVzcG9uc2UgPSBUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgICAgRWFzeU1vY2suZXhwZWN0KGltcGwuZm9vKEVhc3lNb2NrLnNhbWUoY29udHJvbGxlciksIEVhc3lNb2NrLnNhbWUocmVxdWVzdCkpKQorICAgICAgICAuYW5kUmV0dXJuKGV4cGVjdGVkUmVzcG9uc2UpOworCisgICAgY29udHJvbC5yZXBsYXkoKTsKKworICAgIE1lc3NhZ2UgcmVzcG9uc2UgPQorICAgICAgICBzZXJ2aWNlLmNhbGxCbG9ja2luZ01ldGhvZChmb29NZXRob2QsIGNvbnRyb2xsZXIsIHJlcXVlc3QpOworICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFJlc3BvbnNlLCByZXNwb25zZSk7CisKKyAgICBjb250cm9sLnZlcmlmeSgpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5vR2VuZXJpY1NlcnZpY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTm9uLXNlcnZpY2VzIHNob3VsZCBiZSB1c2FibGUuCisgICAgVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBtZXNzYWdlID0KKyAgICAgIFVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRBKDEyMykKKyAgICAgICAgLnNldEV4dGVuc2lvbihVbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLnRlc3RFeHRlbnNpb24sIDQ1NikKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbWVzc2FnZS5nZXRBKCkpOworICAgIGFzc2VydEVxdWFscygxLCBVbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RFbnVtLkZPTy5nZXROdW1iZXIoKSk7CisKKyAgICAvLyBCdWlsZCBhIGxpc3Qgb2YgdGhlIGNsYXNzIG5hbWVzIG5lc3RlZCBpbiBVbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLgorICAgIFN0cmluZyBvdXRlck5hbWUgPSAiZ29vZ2xlLnByb3RvYnVmLm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC4iICsKKyAgICAgICAgICAgICAgICAgICAgICAgIlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMiOworICAgIENsYXNzPD8+IG91dGVyQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKG91dGVyTmFtZSk7CisKKyAgICBTZXQ8U3RyaW5nPiBpbm5lckNsYXNzTmFtZXMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgZm9yIChDbGFzczw/PiBpbm5lckNsYXNzIDogb3V0ZXJDbGFzcy5nZXRDbGFzc2VzKCkpIHsKKyAgICAgIFN0cmluZyBmdWxsTmFtZSA9IGlubmVyQ2xhc3MuZ2V0TmFtZSgpOworICAgICAgLy8gRmlndXJlIG91dCB0aGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgaW5uZXIgY2xhc3MuCisgICAgICAvLyBOb3RlOiAgU3VycHJpc2luZ2x5LCB0aGUgZnVsbCBuYW1lIG9mIGFuIGlubmVyIGNsYXNzIHdpbGwgYmUgc2VwYXJhdGVkCisgICAgICAvLyAgIGZyb20gdGhlIG91dGVyIGNsYXNzIG5hbWUgYnkgYSAnJCcgcmF0aGVyIHRoYW4gYSAnLicuICBUaGlzIGlzIG5vdAorICAgICAgLy8gICBtZW50aW9uZWQgaW4gdGhlIGRvY3VtZW50YXRpb24gZm9yIGphdmEubGFuZy5DbGFzcy4gIEkgZG9uJ3Qgd2FudCB0bworICAgICAgLy8gICBtYWtlIGFzc3VtcHRpb25zLCBzbyBJJ20ganVzdCBnb2luZyB0byBhY2NlcHQgYW55IGNoYXJhY3RlciBhcyB0aGUKKyAgICAgIC8vICAgc2VwYXJhdG9yLgorICAgICAgYXNzZXJ0VHJ1ZShmdWxsTmFtZS5zdGFydHNXaXRoKG91dGVyTmFtZSkpOworCisgICAgICBpZiAoIVNlcnZpY2UuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShpbm5lckNsYXNzKSAmJgorICAgICAgICAgICFNZXNzYWdlLmNsYXNzLmlzQXNzaWduYWJsZUZyb20oaW5uZXJDbGFzcykgJiYKKyAgICAgICAgICAhUHJvdG9jb2xNZXNzYWdlRW51bS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGlubmVyQ2xhc3MpKSB7CisgICAgICAgIC8vIElnbm9yZSBhbnkgY2xhc3NlcyBub3QgZ2VuZXJhdGVkIGJ5IHRoZSBiYXNlIGNvZGUgZ2VuZXJhdG9yLgorICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKworICAgICAgaW5uZXJDbGFzc05hbWVzLmFkZChmdWxsTmFtZS5zdWJzdHJpbmcob3V0ZXJOYW1lLmxlbmd0aCgpICsgMSkpOworICAgIH0KKworICAgIC8vIE5vIHNlcnZpY2UgY2xhc3Mgc2hvdWxkIGhhdmUgYmVlbiBnZW5lcmF0ZWQuCisgICAgYXNzZXJ0VHJ1ZShpbm5lckNsYXNzTmFtZXMuY29udGFpbnMoIlRlc3RNZXNzYWdlIikpOworICAgIGFzc2VydFRydWUoaW5uZXJDbGFzc05hbWVzLmNvbnRhaW5zKCJUZXN0RW51bSIpKTsKKyAgICBhc3NlcnRGYWxzZShpbm5lckNsYXNzTmFtZXMuY29udGFpbnMoIlRlc3RTZXJ2aWNlIikpOworCisgICAgLy8gQnV0IGRlc2NyaXB0b3JzIGFyZSB0aGVyZS4KKyAgICBGaWxlRGVzY3JpcHRvciBmaWxlID0gVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGZpbGUuZ2V0U2VydmljZXMoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygiVGVzdFNlcnZpY2UiLCBmaWxlLmdldFNlcnZpY2VzKCkuZ2V0KDApLmdldE5hbWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGZpbGUuZ2V0U2VydmljZXMoKS5nZXQoMCkuZ2V0TWV0aG9kcygpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJGb28iLAorICAgICAgICBmaWxlLmdldFNlcnZpY2VzKCkuZ2V0KDApLmdldE1ldGhvZHMoKS5nZXQoMCkuZ2V0TmFtZSgpKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqCisgICAqIHdyYXBzQ2FsbGJhY2soKSBpcyBhbiBFYXN5TW9jayBhcmd1bWVudCBwcmVkaWNhdGUuICB3cmFwc0NhbGxiYWNrKGMpCisgICAqIG1hdGNoZXMgYSBjYWxsYmFjayBpZiBjYWxsaW5nIHRoYXQgY2FsbGJhY2sgY2F1c2VzIGMgdG8gYmUgY2FsbGVkLgorICAgKiBJbiBvdGhlciB3b3JkcywgYyB3cmFwcyB0aGUgZ2l2ZW4gY2FsbGJhY2suCisgICAqLworICBwcml2YXRlIDxUeXBlIGV4dGVuZHMgTWVzc2FnZT4gUnBjQ2FsbGJhY2s8VHlwZT4gd3JhcHNDYWxsYmFjaygKKyAgICAgIE1vY2tDYWxsYmFjazw/PiBjYWxsYmFjaykgeworICAgIEVhc3lNb2NrLnJlcG9ydE1hdGNoZXIobmV3IFdyYXBzQ2FsbGJhY2soY2FsbGJhY2spKTsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIC8qKiBUaGUgcGFyYW1ldGVyIHRvIHdyYXBzQ2FsbGJhY2soKSBtdXN0IGJlIGEgTW9ja0NhbGxiYWNrLiAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrQ2FsbGJhY2s8VHlwZSBleHRlbmRzIE1lc3NhZ2U+CisgICAgICBpbXBsZW1lbnRzIFJwY0NhbGxiYWNrPFR5cGU+IHsKKyAgICBwcml2YXRlIGJvb2xlYW4gY2FsbGVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NhbGxlZCgpIHsgcmV0dXJuIGNhbGxlZDsgfQorCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7IGNhbGxlZCA9IGZhbHNlOyB9CisgICAgcHVibGljIHZvaWQgcnVuKFR5cGUgbWVzc2FnZSkgeyBjYWxsZWQgPSB0cnVlOyB9CisgIH0KKworICAvKiogSW1wbGVtZW50YXRpb24gb2YgdGhlIHdyYXBzQ2FsbGJhY2soKSBhcmd1bWVudCBtYXRjaGVyLiAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBXcmFwc0NhbGxiYWNrIGltcGxlbWVudHMgSUFyZ3VtZW50TWF0Y2hlciB7CisgICAgcHJpdmF0ZSBNb2NrQ2FsbGJhY2s8Pz4gY2FsbGJhY2s7CisKKyAgICBwdWJsaWMgV3JhcHNDYWxsYmFjayhNb2NrQ2FsbGJhY2s8Pz4gY2FsbGJhY2spIHsKKyAgICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjazsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKE9iamVjdCBhY3R1YWwpIHsKKyAgICAgIGlmICghKGFjdHVhbCBpbnN0YW5jZW9mIFJwY0NhbGxiYWNrKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBScGNDYWxsYmFjayBhY3R1YWxDYWxsYmFjayA9IChScGNDYWxsYmFjaylhY3R1YWw7CisKKyAgICAgIGNhbGxiYWNrLnJlc2V0KCk7CisgICAgICBhY3R1YWxDYWxsYmFjay5ydW4obnVsbCk7CisgICAgICByZXR1cm4gY2FsbGJhY2suaXNDYWxsZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhcHBlbmRUbyhTdHJpbmdCdWZmZXIgYnVmZmVyKSB7CisgICAgICBidWZmZXIuYXBwZW5kKCJ3cmFwc0NhbGxiYWNrKG1vY2tDYWxsYmFjaykiKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NpbmdsZUZpZWxkQnVpbGRlclRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1NpbmdsZUZpZWxkQnVpbGRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OGI4MDAwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU2luZ2xlRmllbGRCdWlsZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIHtAbGluayBTaW5nbGVGaWVsZEJ1aWxkZXJ9LiBUaGlzIHRlc3RzIGJhc2ljIGZ1bmN0aW9uYWxpdHkuCisgKiBNb3JlIGV4dGVuc2l2ZSB0ZXN0aW5nIGlzIHByb3ZpZGVkIHZpYSBvdGhlciB0ZXN0cyB0aGF0IGV4ZXJjaXNlIHRoZQorICogYnVpbGRlci4KKyAqCisgKiBAYXV0aG9yIGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKyAqLworcHVibGljIGNsYXNzIFNpbmdsZUZpZWxkQnVpbGRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgcHVibGljIHZvaWQgdGVzdEJhc2ljVXNlQW5kSW52YWxpZGF0aW9ucygpIHsKKyAgICBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCBtb2NrUGFyZW50ID0gbmV3IFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50KCk7CisgICAgU2luZ2xlRmllbGRCdWlsZGVyPFRlc3RBbGxUeXBlcywgVGVzdEFsbFR5cGVzLkJ1aWxkZXIsCisgICAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gYnVpbGRlciA9CisgICAgICAgIG5ldyBTaW5nbGVGaWVsZEJ1aWxkZXI8VGVzdEFsbFR5cGVzLCBUZXN0QWxsVHlwZXMuQnVpbGRlciwKKyAgICAgICAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCisgICAgICAgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCisgICAgICAgICAgICBtb2NrUGFyZW50LAorICAgICAgICAgICAgZmFsc2UpOworICAgIGFzc2VydFNhbWUoVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpLCBidWlsZGVyLmdldE1lc3NhZ2UoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwKKyAgICAgICAgYnVpbGRlci5nZXRCdWlsZGVyKCkuYnVpbGRQYXJ0aWFsKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworCisgICAgYnVpbGRlci5nZXRCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigxMCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1vY2tQYXJlbnQuZ2V0SW52YWxpZGF0aW9uQ291bnQoKSk7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEwLCBtZXNzYWdlLmdldE9wdGlvbmFsSW50MzIoKSk7CisKKyAgICAvLyBUZXN0IHRoYXQgd2UgcmVjZWl2ZSBpbnZhbGlkYXRpb25zIG5vdyB0aGF0IGJ1aWxkIGhhcyBiZWVuIGNhbGxlZC4KKyAgICBhc3NlcnRFcXVhbHMoMCwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKyAgICBidWlsZGVyLmdldEJ1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDIwKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKworICAgIC8vIFRlc3QgdGhhdCB3ZSBkb24ndCBrZWVwIGdldHRpbmcgaW52YWxpZGF0aW9ucyBvbiBldmVyeSBjaGFuZ2UKKyAgICBidWlsZGVyLmdldEJ1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDMwKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbW9ja1BhcmVudC5nZXRJbnZhbGlkYXRpb25Db3VudCgpKTsKKworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNldE1lc3NhZ2UoKSB7CisgICAgVGVzdFV0aWwuTW9ja0J1aWxkZXJQYXJlbnQgbW9ja1BhcmVudCA9IG5ldyBUZXN0VXRpbC5Nb2NrQnVpbGRlclBhcmVudCgpOworICAgIFNpbmdsZUZpZWxkQnVpbGRlcjxUZXN0QWxsVHlwZXMsIFRlc3RBbGxUeXBlcy5CdWlsZGVyLAorICAgICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGJ1aWxkZXIgPQorICAgICAgICBuZXcgU2luZ2xlRmllbGRCdWlsZGVyPFRlc3RBbGxUeXBlcywgVGVzdEFsbFR5cGVzLkJ1aWxkZXIsCisgICAgICAgICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAorICAgICAgICAgICAgVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpLAorICAgICAgICAgICAgbW9ja1BhcmVudCwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBidWlsZGVyLnNldE1lc3NhZ2UoVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDApLmJ1aWxkKCkpOworICAgIGFzc2VydEVxdWFscygwLCBidWlsZGVyLmdldE1lc3NhZ2UoKS5nZXRPcHRpb25hbEludDMyKCkpOworCisgICAgLy8gVXBkYXRlIG1lc3NhZ2UgdXNpbmcgdGhlIGJ1aWxkZXIKKyAgICBidWlsZGVyLmdldEJ1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDEpOworICAgIGFzc2VydEVxdWFscygwLCBtb2NrUGFyZW50LmdldEludmFsaWRhdGlvbkNvdW50KCkpOworICAgIGFzc2VydEVxdWFscygxLCBidWlsZGVyLmdldEJ1aWxkZXIoKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygxLCBidWlsZGVyLmdldE1lc3NhZ2UoKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBidWlsZGVyLmdldEJ1aWxkZXIoKS5zZXRPcHRpb25hbEludDMyKDIpOworICAgIGFzc2VydEVxdWFscygyLCBidWlsZGVyLmdldEJ1aWxkZXIoKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygyLCBidWlsZGVyLmdldE1lc3NhZ2UoKS5nZXRPcHRpb25hbEludDMyKCkpOworCisgICAgLy8gTWFrZSBzdXJlIG1lc3NhZ2Ugc3RheXMgY2FjaGVkCisgICAgYXNzZXJ0U2FtZShidWlsZGVyLmdldE1lc3NhZ2UoKSwgYnVpbGRlci5nZXRNZXNzYWdlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENsZWFyKCkgeworICAgIFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50IG1vY2tQYXJlbnQgPSBuZXcgVGVzdFV0aWwuTW9ja0J1aWxkZXJQYXJlbnQoKTsKKyAgICBTaW5nbGVGaWVsZEJ1aWxkZXI8VGVzdEFsbFR5cGVzLCBUZXN0QWxsVHlwZXMuQnVpbGRlciwKKyAgICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBidWlsZGVyID0KKyAgICAgICAgbmV3IFNpbmdsZUZpZWxkQnVpbGRlcjxUZXN0QWxsVHlwZXMsIFRlc3RBbGxUeXBlcy5CdWlsZGVyLAorICAgICAgICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKKyAgICAgICAgICAgIFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgIG1vY2tQYXJlbnQsCisgICAgICAgICAgICBmYWxzZSk7CisgICAgYnVpbGRlci5zZXRNZXNzYWdlKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigwKS5idWlsZCgpKTsKKyAgICBhc3NlcnROb3RTYW1lKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgYnVpbGRlci5nZXRNZXNzYWdlKCkpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBhc3NlcnRTYW1lKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgYnVpbGRlci5nZXRNZXNzYWdlKCkpOworCisgICAgYnVpbGRlci5nZXRCdWlsZGVyKCkuc2V0T3B0aW9uYWxJbnQzMigxKTsKKyAgICBhc3NlcnROb3RTYW1lKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgYnVpbGRlci5nZXRNZXNzYWdlKCkpOworICAgIGJ1aWxkZXIuY2xlYXIoKTsKKyAgICBhc3NlcnRTYW1lKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgYnVpbGRlci5nZXRNZXNzYWdlKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlKCkgeworICAgIFRlc3RVdGlsLk1vY2tCdWlsZGVyUGFyZW50IG1vY2tQYXJlbnQgPSBuZXcgVGVzdFV0aWwuTW9ja0J1aWxkZXJQYXJlbnQoKTsKKyAgICBTaW5nbGVGaWVsZEJ1aWxkZXI8VGVzdEFsbFR5cGVzLCBUZXN0QWxsVHlwZXMuQnVpbGRlciwKKyAgICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBidWlsZGVyID0KKyAgICAgICAgbmV3IFNpbmdsZUZpZWxkQnVpbGRlcjxUZXN0QWxsVHlwZXMsIFRlc3RBbGxUeXBlcy5CdWlsZGVyLAorICAgICAgICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKKyAgICAgICAgICAgIFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgIG1vY2tQYXJlbnQsCisgICAgICAgICAgICBmYWxzZSk7CisKKyAgICAvLyBNZXJnZSBpbnRvIGRlZmF1bHQgZmllbGQuCisgICAgYnVpbGRlci5tZXJnZUZyb20oVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKKyAgICBhc3NlcnRTYW1lKFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgYnVpbGRlci5nZXRNZXNzYWdlKCkpOworCisgICAgLy8gTWVyZ2UgaW50byBub24tZGVmYXVsdCBmaWVsZCBvbiBleGlzdGluZyBidWlsZGVyLgorICAgIGJ1aWxkZXIuZ2V0QnVpbGRlcigpLnNldE9wdGlvbmFsSW50MzIoMik7CisgICAgYnVpbGRlci5tZXJnZUZyb20oVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0T3B0aW9uYWxEb3VibGUoNC4wKQorICAgICAgICAuYnVpbGRQYXJ0aWFsKCkpOworICAgIGFzc2VydEVxdWFscygyLCBidWlsZGVyLmdldE1lc3NhZ2UoKS5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscyg0LjAsIGJ1aWxkZXIuZ2V0TWVzc2FnZSgpLmdldE9wdGlvbmFsRG91YmxlKCkpOworCisgICAgLy8gTWVyZ2UgaW50byBub24tZGVmYXVsdCBmaWVsZCBvbiBleGlzdGluZyBtZXNzYWdlCisgICAgYnVpbGRlci5zZXRNZXNzYWdlKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMTApCisgICAgICAgIC5idWlsZFBhcnRpYWwoKSk7CisgICAgYnVpbGRlci5tZXJnZUZyb20oVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0T3B0aW9uYWxEb3VibGUoNS4wKQorICAgICAgICAuYnVpbGRQYXJ0aWFsKCkpOworICAgIGFzc2VydEVxdWFscygxMCwgYnVpbGRlci5nZXRNZXNzYWdlKCkuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoNS4wLCBidWlsZGVyLmdldE1lc3NhZ2UoKS5nZXRPcHRpb25hbERvdWJsZSgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU21hbGxTb3J0ZWRNYXBUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9TbWFsbFNvcnRlZE1hcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjYwODZkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvU21hbGxTb3J0ZWRNYXBUZXN0LmphdmEKQEAgLTAsMCArMSw0MjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKKworLyoqCisgKiBAYXV0aG9yIGRhcmlja0Bnb29nbGUuY29tIERhcmljayBUb25nCisgKi8KK3B1YmxpYyBjbGFzcyBTbWFsbFNvcnRlZE1hcFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIC8vIGphdmEudXRpbC5BYnN0cmFjdE1hcC5TaW1wbGVFbnRyeSBpcyBwcml2YXRlIGluIEpESyAxLjUuIFdlIHJlLWltcGxlbWVudCBpdAorICAvLyBoZXJlIGZvciBKREsgMS41IHVzZXJzLgorICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTaW1wbGVFbnRyeTxLLCBWPiBpbXBsZW1lbnRzIE1hcC5FbnRyeTxLLCBWPiB7CisgICAgcHJpdmF0ZSBmaW5hbCBLIGtleTsKKyAgICBwcml2YXRlIFYgdmFsdWU7CisKKyAgICBTaW1wbGVFbnRyeShLIGtleSwgViB2YWx1ZSkgeworICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIEsgZ2V0S2V5KCkgeworICAgICAgcmV0dXJuIGtleTsKKyAgICB9CisKKyAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgViBzZXRWYWx1ZShWIHZhbHVlKSB7CisgICAgICBWIG9sZFZhbHVlID0gdGhpcy52YWx1ZTsKKyAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGVxKE9iamVjdCBvMSwgT2JqZWN0IG8yKSB7CisgICAgICByZXR1cm4gbzEgPT0gbnVsbCA/IG8yID09IG51bGwgOiBvMS5lcXVhbHMobzIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIE1hcC5FbnRyeSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIE1hcC5FbnRyeSBlID0gKE1hcC5FbnRyeSkgbzsKKyAgICAgIHJldHVybiBlcShrZXksIGUuZ2V0S2V5KCkpICYmIGVxKHZhbHVlLCBlLmdldFZhbHVlKCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gKChrZXkgPT0gbnVsbCkgPyAwIDoga2V5Lmhhc2hDb2RlKCkpIF4KKyAgICAgICAgICAoKHZhbHVlID09IG51bGwpID8gMCA6IHZhbHVlLmhhc2hDb2RlKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQdXRBbmRHZXRBcnJheUVudHJpZXNPbmx5KCkgeworICAgIHJ1blB1dEFuZEdldFRlc3QoMyk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UHV0QW5kR2V0T3ZlcmZsb3dFbnRyaWVzKCkgeworICAgIHJ1blB1dEFuZEdldFRlc3QoNik7CisgIH0KKworICBwcml2YXRlIHZvaWQgcnVuUHV0QW5kR2V0VGVzdChpbnQgbnVtRWxlbWVudHMpIHsKKyAgICAvLyBUZXN0IHdpdGggZXZlbiBhbmQgb2RkIGFycmF5U2l6ZQorICAgIFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+IG1hcDEgPQorICAgICAgICBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgU21hbGxTb3J0ZWRNYXA8SW50ZWdlciwgSW50ZWdlcj4gbWFwMiA9CisgICAgICAgIFNtYWxsU29ydGVkTWFwLm5ld0luc3RhbmNlRm9yVGVzdCg0KTsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAzID0KKyAgICAgICAgU21hbGxTb3J0ZWRNYXAubmV3SW5zdGFuY2VGb3JUZXN0KDMpOworICAgIFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+IG1hcDQgPQorICAgICAgICBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoNCk7CisKKyAgICAvLyBUZXN0IHdpdGggcHV0cyBpbiBhc2NlbmRpbmcgb3JkZXIuCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1FbGVtZW50czsgaSsrKSB7CisgICAgICBhc3NlcnROdWxsKG1hcDEucHV0KGksIGkgKyAxKSk7CisgICAgICBhc3NlcnROdWxsKG1hcDIucHV0KGksIGkgKyAxKSk7CisgICAgfQorICAgIC8vIFRlc3Qgd2l0aCBwdXRzIGluIGRlc2NlbmRpbmcgb3JkZXIuCisgICAgZm9yIChpbnQgaSA9IG51bUVsZW1lbnRzIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgIGFzc2VydE51bGwobWFwMy5wdXQoaSwgaSArIDEpKTsKKyAgICAgIGFzc2VydE51bGwobWFwNC5wdXQoaSwgaSArIDEpKTsKKyAgICB9CisKKyAgICBhc3NlcnRFcXVhbHMoTWF0aC5taW4oMywgbnVtRWxlbWVudHMpLCBtYXAxLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoTWF0aC5taW4oNCwgbnVtRWxlbWVudHMpLCBtYXAyLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoTWF0aC5taW4oMywgbnVtRWxlbWVudHMpLCBtYXAzLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoTWF0aC5taW4oNCwgbnVtRWxlbWVudHMpLCBtYXA0LmdldE51bUFycmF5RW50cmllcygpKTsKKworICAgIExpc3Q8U21hbGxTb3J0ZWRNYXA8SW50ZWdlciwgSW50ZWdlcj4+IGFsbE1hcHMgPQorICAgICAgICBuZXcgQXJyYXlMaXN0PFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+PigpOworICAgIGFsbE1hcHMuYWRkKG1hcDEpOworICAgIGFsbE1hcHMuYWRkKG1hcDIpOworICAgIGFsbE1hcHMuYWRkKG1hcDMpOworICAgIGFsbE1hcHMuYWRkKG1hcDQpOworCisgICAgZm9yIChTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgOiBhbGxNYXBzKSB7CisgICAgICBhc3NlcnRFcXVhbHMobnVtRWxlbWVudHMsIG1hcC5zaXplKCkpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1FbGVtZW50czsgaSsrKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcihpICsgMSksIG1hcC5nZXQoaSkpOworICAgICAgfQorICAgIH0KKworICAgIGFzc2VydEVxdWFscyhtYXAxLCBtYXAyKTsKKyAgICBhc3NlcnRFcXVhbHMobWFwMiwgbWFwMyk7CisgICAgYXNzZXJ0RXF1YWxzKG1hcDMsIG1hcDQpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcGxhY2luZ1B1dCgpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgICAgYXNzZXJ0TnVsbChtYXAucmVtb3ZlKGkgKyAxKSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IEludGVnZXIoaSArIDEpLCBtYXAucHV0KGksIGkgKyAyKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlbW92ZSgpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgICAgYXNzZXJ0TnVsbChtYXAucmVtb3ZlKGkgKyAxKSk7CisgICAgfQorCisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1BcnJheUVudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1PdmVyZmxvd0VudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDYsICBtYXAuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMobWFrZVNvcnRlZEtleVNldCgwLCAxLCAyLCAzLCA0LCA1KSwgbWFwLmtleVNldCgpKTsKKworICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcigyKSwgbWFwLnJlbW92ZSgxKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1BcnJheUVudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1hcC5nZXROdW1PdmVyZmxvd0VudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDUsICBtYXAuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMobWFrZVNvcnRlZEtleVNldCgwLCAyLCAzLCA0LCA1KSwgbWFwLmtleVNldCgpKTsKKworICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcig1KSwgbWFwLnJlbW92ZSg0KSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1BcnJheUVudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1hcC5nZXROdW1PdmVyZmxvd0VudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsICBtYXAuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMobWFrZVNvcnRlZEtleVNldCgwLCAyLCAzLCA1KSwgbWFwLmtleVNldCgpKTsKKworICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcig0KSwgbWFwLnJlbW92ZSgzKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1BcnJheUVudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5nZXROdW1PdmVyZmxvd0VudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhtYWtlU29ydGVkS2V5U2V0KDAsIDIsIDUpLCBtYXAua2V5U2V0KCkpOworCisgICAgYXNzZXJ0TnVsbChtYXAucmVtb3ZlKDMpKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbWFwLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLmdldE51bU92ZXJmbG93RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbWFwLnNpemUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMobmV3IEludGVnZXIoMSksIG1hcC5yZW1vdmUoMCkpOworICAgIGFzc2VydEVxdWFscygyLCBtYXAuZ2V0TnVtQXJyYXlFbnRyaWVzKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtYXAuZ2V0TnVtT3ZlcmZsb3dFbnRyaWVzKCkpOworICAgIGFzc2VydEVxdWFscygyLCBtYXAuc2l6ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhcigpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgIH0KKyAgICBtYXAuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLmdldE51bU92ZXJmbG93RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLnNpemUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXJyYXlFbnRyeUFuZE92ZXJmbG93RW50cmllcygpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMywgbWFwLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgTWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+IGVudHJ5ID0gbWFwLmdldEFycmF5RW50cnlBdChpKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcihpKSwgZW50cnkuZ2V0S2V5KCkpOworICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBJbnRlZ2VyKGkgKyAxKSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgfQorICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxJbnRlZ2VyLCBJbnRlZ2VyPj4gaXQgPQorICAgICAgICBtYXAuZ2V0T3ZlcmZsb3dFbnRyaWVzKCkuaXRlcmF0b3IoKTsKKyAgICBmb3IgKGludCBpID0gMzsgaSA8IDY7IGkrKykgeworICAgICAgYXNzZXJ0VHJ1ZShpdC5oYXNOZXh0KCkpOworICAgICAgTWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+IGVudHJ5ID0gaXQubmV4dCgpOworICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBJbnRlZ2VyKGkpLCBlbnRyeS5nZXRLZXkoKSk7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IEludGVnZXIoaSArIDEpLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgYXNzZXJ0RmFsc2UoaXQuaGFzTmV4dCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RFbnRyeVNldENvbnRhaW5zKCkgeworICAgIFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+IG1hcCA9IFNtYWxsU29ydGVkTWFwLm5ld0luc3RhbmNlRm9yVGVzdCgzKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDY7IGkrKykgeworICAgICAgYXNzZXJ0TnVsbChtYXAucHV0KGksIGkgKyAxKSk7CisgICAgfQorICAgIFNldDxNYXAuRW50cnk8SW50ZWdlciwgSW50ZWdlcj4+IGVudHJ5U2V0ID0gbWFwLmVudHJ5U2V0KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgZW50cnlTZXQuY29udGFpbnMobmV3IFNpbXBsZUVudHJ5PEludGVnZXIsIEludGVnZXI+KGksIGkgKyAxKSkpOworICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgZW50cnlTZXQuY29udGFpbnMobmV3IFNpbXBsZUVudHJ5PEludGVnZXIsIEludGVnZXI+KGksIGkpKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVudHJ5U2V0QWRkKCkgeworICAgIFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+IG1hcCA9IFNtYWxsU29ydGVkTWFwLm5ld0luc3RhbmNlRm9yVGVzdCgzKTsKKyAgICBTZXQ8TWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+PiBlbnRyeVNldCA9IG1hcC5lbnRyeVNldCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICBNYXAuRW50cnk8SW50ZWdlciwgSW50ZWdlcj4gZW50cnkgPQorICAgICAgICAgIG5ldyBTaW1wbGVFbnRyeTxJbnRlZ2VyLCBJbnRlZ2VyPihpLCBpICsgMSk7CisgICAgICBhc3NlcnRUcnVlKGVudHJ5U2V0LmFkZChlbnRyeSkpOworICAgICAgYXNzZXJ0RmFsc2UoZW50cnlTZXQuYWRkKGVudHJ5KSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IEludGVnZXIoaSArIDEpLCBtYXAuZ2V0KGkpKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1BcnJheUVudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1hcC5nZXROdW1PdmVyZmxvd0VudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDYsIG1hcC5zaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVudHJ5U2V0UmVtb3ZlKCkgeworICAgIFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+IG1hcCA9IFNtYWxsU29ydGVkTWFwLm5ld0luc3RhbmNlRm9yVGVzdCgzKTsKKyAgICBTZXQ8TWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+PiBlbnRyeVNldCA9IG1hcC5lbnRyeVNldCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICBhc3NlcnROdWxsKG1hcC5wdXQoaSwgaSArIDEpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIE1hcC5FbnRyeTxJbnRlZ2VyLCBJbnRlZ2VyPiBlbnRyeSA9CisgICAgICAgICAgbmV3IFNpbXBsZUVudHJ5PEludGVnZXIsIEludGVnZXI+KGksIGkgKyAxKTsKKyAgICAgIGFzc2VydFRydWUoZW50cnlTZXQucmVtb3ZlKGVudHJ5KSk7CisgICAgICBhc3NlcnRGYWxzZShlbnRyeVNldC5yZW1vdmUoZW50cnkpKTsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZShtYXAuaXNFbXB0eSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLmdldE51bUFycmF5RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLmdldE51bU92ZXJmbG93RW50cmllcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLnNpemUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RW50cnlTZXRDbGVhcigpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgIH0KKyAgICBtYXAuZW50cnlTZXQoKS5jbGVhcigpOworICAgIGFzc2VydFRydWUobWFwLmlzRW1wdHkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5nZXROdW1BcnJheUVudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5nZXROdW1PdmVyZmxvd0VudHJpZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5zaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVudHJ5U2V0SXRlcmF0b3JOZXh0KCkgeworICAgIFNtYWxsU29ydGVkTWFwPEludGVnZXIsIEludGVnZXI+IG1hcCA9IFNtYWxsU29ydGVkTWFwLm5ld0luc3RhbmNlRm9yVGVzdCgzKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDY7IGkrKykgeworICAgICAgYXNzZXJ0TnVsbChtYXAucHV0KGksIGkgKyAxKSk7CisgICAgfQorICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxJbnRlZ2VyLCBJbnRlZ2VyPj4gaXQgPSBtYXAuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICBhc3NlcnRUcnVlKGl0Lmhhc05leHQoKSk7CisgICAgICBNYXAuRW50cnk8SW50ZWdlciwgSW50ZWdlcj4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IEludGVnZXIoaSksIGVudHJ5LmdldEtleSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcihpICsgMSksIGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKyAgICBhc3NlcnRGYWxzZShpdC5oYXNOZXh0KCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVudHJ5U2V0SXRlcmF0b3JSZW1vdmUoKSB7CisgICAgU21hbGxTb3J0ZWRNYXA8SW50ZWdlciwgSW50ZWdlcj4gbWFwID0gU21hbGxTb3J0ZWRNYXAubmV3SW5zdGFuY2VGb3JUZXN0KDMpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICBhc3NlcnROdWxsKG1hcC5wdXQoaSwgaSArIDEpKTsKKyAgICB9CisgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+PiBpdCA9IG1hcC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydFRydWUobWFwLmNvbnRhaW5zS2V5KGkpKTsKKyAgICAgIGl0Lm5leHQoKTsKKyAgICAgIGl0LnJlbW92ZSgpOworICAgICAgYXNzZXJ0RmFsc2UobWFwLmNvbnRhaW5zS2V5KGkpKTsKKyAgICAgIGFzc2VydEVxdWFscyg2IC0gaSAtIDEsIG1hcC5zaXplKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNYXBFbnRyeU1vZGlmaWNhdGlvbigpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgIH0KKyAgICBJdGVyYXRvcjxNYXAuRW50cnk8SW50ZWdlciwgSW50ZWdlcj4+IGl0ID0gbWFwLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDY7IGkrKykgeworICAgICAgTWFwLkVudHJ5PEludGVnZXIsIEludGVnZXI+IGVudHJ5ID0gaXQubmV4dCgpOworICAgICAgZW50cnkuc2V0VmFsdWUoaSArIDIzKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcihpICsgMjMpLCBtYXAuZ2V0KGkpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWFrZUltbXV0YWJsZSgpIHsKKyAgICBTbWFsbFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBTbWFsbFNvcnRlZE1hcC5uZXdJbnN0YW5jZUZvclRlc3QoMyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKKyAgICAgIGFzc2VydE51bGwobWFwLnB1dChpLCBpICsgMSkpOworICAgIH0KKyAgICBtYXAubWFrZUltbXV0YWJsZSgpOworICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcigxKSwgbWFwLmdldCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKDYsIG1hcC5zaXplKCkpOworCisgICAgdHJ5IHsKKyAgICAgIG1hcC5wdXQoMjMsIDIzKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICB9CisKKyAgICBNYXA8SW50ZWdlciwgSW50ZWdlcj4gb3RoZXIgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgIG90aGVyLnB1dCgyMywgMjMpOworICAgIHRyeSB7CisgICAgICBtYXAucHV0QWxsKG90aGVyKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgbWFwLnJlbW92ZSgwKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgbWFwLmNsZWFyKCk7CisgICAgICBmYWlsKCJFeHBlY3RlZCBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgfQorCisgICAgU2V0PE1hcC5FbnRyeTxJbnRlZ2VyLCBJbnRlZ2VyPj4gZW50cnlTZXQgPSBtYXAuZW50cnlTZXQoKTsKKyAgICB0cnkgeworICAgICAgZW50cnlTZXQuY2xlYXIoKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICB9CisKKyAgICBJdGVyYXRvcjxNYXAuRW50cnk8SW50ZWdlciwgSW50ZWdlcj4+IGl0ID0gZW50cnlTZXQuaXRlcmF0b3IoKTsKKyAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICBNYXAuRW50cnk8SW50ZWdlciwgSW50ZWdlcj4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICB0cnkgeworICAgICAgICBlbnRyeS5zZXRWYWx1ZSgwKTsKKyAgICAgICAgZmFpbCgiRXhwZWN0ZWQgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24iKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgZmFpbCgiRXhwZWN0ZWQgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24iKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICB9CisgICAgfQorCisgICAgU2V0PEludGVnZXI+IGtleVNldCA9IG1hcC5rZXlTZXQoKTsKKyAgICB0cnkgeworICAgICAga2V5U2V0LmNsZWFyKCk7CisgICAgICBmYWlsKCJFeHBlY3RlZCBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgfQorCisgICAgSXRlcmF0b3I8SW50ZWdlcj4ga2V5cyA9IGtleVNldC5pdGVyYXRvcigpOworICAgIHdoaWxlIChrZXlzLmhhc05leHQoKSkgeworICAgICAgSW50ZWdlciBrZXkgPSBrZXlzLm5leHQoKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGtleVNldC5yZW1vdmUoa2V5KTsKKyAgICAgICAgZmFpbCgiRXhwZWN0ZWQgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24iKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBrZXlzLnJlbW92ZSgpOworICAgICAgICBmYWlsKCJFeHBlY3RlZCBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcml2YXRlIFNldDxJbnRlZ2VyPiBtYWtlU29ydGVkS2V5U2V0KEludGVnZXIuLi4ga2V5cykgeworICAgIHJldHVybiBuZXcgVHJlZVNldDxJbnRlZ2VyPihBcnJheXMuPEludGVnZXI+YXNMaXN0KGtleXMpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGVzdEJhZElkZW50aWZpZXJzLmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9UZXN0QmFkSWRlbnRpZmllcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzYwZmUwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGVzdEJhZElkZW50aWZpZXJzLmphdmEKQEAgLTAsMCArMSw5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyB0aGF0IHByb3RvMiBhcGkgZ2VuZXJhdGlvbiBkb2Vzbid0IGNhdXNlIGNvbXBpbGUgZXJyb3JzIHdoZW4KKyAqIGNvbXBpbGluZyBwcm90b2NvbCBidWZmZXJzIHRoYXQgaGF2ZSBuYW1lcyB0aGF0IHdvdWxkIG90aGVyd2lzZSBjb25mbGljdAorICogaWYgbm90IGZ1bGx5IHF1YWxpZmllZCAobGlrZSBARGVwcmVjYXRlZCBhbmQgQE92ZXJyaWRlKS4KKyAqCisgKiBAYXV0aG9yIGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKyAqLworcHVibGljIGNsYXNzIFRlc3RCYWRJZGVudGlmaWVycyBleHRlbmRzIFRlc3RDYXNlIHsKKworICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGlsYXRpb24oKSB7CisgICAgLy8gSWYgdGhpcyBjb21waWxlcywgaXQgbWVhbnMgdGhlIGdlbmVyYXRpb24gd2FzIGNvcnJlY3QuCisgICAgVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5uZXdCdWlsZGVyKCk7CisgICAgVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUubmV3QnVpbGRlcigpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldERlc2NyaXB0b3IoKSB7CisgICAgRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IgZmlsZURlc2NyaXB0b3IgPQorICAgICAgICBUZXN0QmFkSWRlbnRpZmllcnNQcm90by5nZXREZXNjcmlwdG9yKCk7CisgICAgU3RyaW5nIGRlc2NyaXB0b3JGaWVsZCA9IFRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IKKyAgICAgICAgLmdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlc2NyaXB0b3IoKTsKKyAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIHByb3RvRGVzY3JpcHRvciA9IFRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IKKyAgICAgICAgLmdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlc2NyaXB0b3JGb3JUeXBlKCk7CisgICAgU3RyaW5nIG5lc3RlZERlc2NyaXB0b3JGaWVsZCA9IFRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IKKyAgICAgICAgLk5lc3RlZERlc2NyaXB0b3IuZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGVzY3JpcHRvcigpOworICAgIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgbmVzdGVkUHJvdG9EZXNjcmlwdG9yID0gVGVzdEJhZElkZW50aWZpZXJzUHJvdG8KKyAgICAgICAgLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5nZXREZWZhdWx0SW5zdGFuY2UoKQorICAgICAgICAuZ2V0RGVzY3JpcHRvckZvclR5cGUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIG1lc3NhZ2UgPQorICAgICAgICBUZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLmdldERlZmF1bHRJbnN0YW5jZSgpOworICAgIC8vIE1ha2Ugc3VyZSBnZW5lcmF0ZWQgYWNjZXNzb3JzIGFyZSBwcm9wZXJseSBuYW1lZC4KKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMkZpZWxkMUNvdW50KCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEVudW1GaWVsZDJDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRTdHJpbmdGaWVsZDNDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRCeXRlc0ZpZWxkNENvdW50KCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldE1lc3NhZ2VGaWVsZDVDb3VudCgpKTsKKworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEludDMyRmllbGRDb3VudDExKCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEVudW1GaWVsZENvdW50MTIoKS5nZXROdW1iZXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCIiLCBtZXNzYWdlLmdldFN0cmluZ0ZpZWxkQ291bnQxMygpKTsKKyAgICBhc3NlcnRFcXVhbHMoQnl0ZVN0cmluZy5FTVBUWSwgbWVzc2FnZS5nZXRCeXRlc0ZpZWxkQ291bnQxNCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRNZXNzYWdlRmllbGRDb3VudDE1KCkuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMkZpZWxkMjFDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFbnVtRmllbGQyMkNvdW50KCkpOworICAgIGFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFN0cmluZ0ZpZWxkMjNDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRCeXRlc0ZpZWxkMjRDb3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRNZXNzYWdlRmllbGQyNUNvdW50KCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0SW50MzJGaWVsZDFMaXN0KCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRJbnQzMkZpZWxkTGlzdDMxKCkpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0SW50NjRGaWVsZENvdW50KCkpOworICAgIGFzc2VydEVxdWFscygwTCwgbWVzc2FnZS5nZXRFeHRlbnNpb24oCisgICAgICAgIFRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuaW50NjRGaWVsZENvdW50KS5sb25nVmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDBMLCBtZXNzYWdlLmdldEV4dGVuc2lvbigKKyAgICAgICAgVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5pbnQ2NEZpZWxkTGlzdCkubG9uZ1ZhbHVlKCkpOworCisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Rlc3RVdGlsLmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9UZXN0VXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzNWExMTcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9UZXN0VXRpbC5qYXZhCkBAIC0wLDAgKzEsNDEyNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGU7CisKKy8vIFRoZSBzdGF0aWMgaW1wb3J0cyBhcmUgdG8gYXZvaWQgMTAwKyBjaGFyIGxpbmVzLiAgVGhlIGZvbGxvd2luZyBpcyByb3VnaGx5IGVxdWl2YWxlbnQgdG8KKy8vIGltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by4qOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRJbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0SW50NjRFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdFVpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0VWludDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRTaW50MzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdFNmaXhlZDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRGbG9hdEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0RG91YmxlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRCb29sRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRTdHJpbmdFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdENvcmRFeHRlbnNpb247CisKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vbmVvZlVpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vbmVvZk5lc3RlZE1lc3NhZ2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub25lb2ZTdHJpbmdFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub25lb2ZCeXRlc0V4dGVuc2lvbjsKKworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsSW50MzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbFVpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbFVpbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbFNpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbFNpbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEZpeGVkMzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxGaXhlZDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsU2ZpeGVkMzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxTZml4ZWQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEZsb2F0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsRG91YmxlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsQm9vbEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbFN0cmluZ0V4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEJ5dGVzRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsR3JvdXBFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxDb3JkRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsRm9yZWlnbkVudW1FeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxGb3JlaWduTWVzc2FnZUV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsTGF6eU1lc3NhZ2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxTdHJpbmdQaWVjZUV4dGVuc2lvbjsKKworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFVpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFNpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEZpeGVkMzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEZsb2F0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkQm9vbEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFN0cmluZ0V4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkR3JvdXBFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkU3RyaW5nUGllY2VFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRDb3JkRXh0ZW5zaW9uOworCitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb247CisKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRJbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRJbnQ2NEV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRVaW50MzJFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkVWludDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZFNpbnQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRTaW50NjRFeHRlbnNpb247CitpbXBvcnQgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkRml4ZWQzMkV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRGaXhlZDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZFNmaXhlZDY0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZEZsb2F0RXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZERvdWJsZUV4dGVuc2lvbjsKK2ltcG9ydCBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRCb29sRXh0ZW5zaW9uOworaW1wb3J0IHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZEVudW1FeHRlbnNpb247CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdEludDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdEludDY0RXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdFVpbnQzMkV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLmRlZmF1bHRVaW50NjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0U2ludDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLmRlZmF1bHRGaXhlZDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdEZpeGVkNjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0U2ZpeGVkNjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0RmxvYXRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0RG91YmxlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdEJvb2xFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0U3RyaW5nRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5kZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLmRlZmF1bHRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLmRlZmF1bHRDb3JkRXh0ZW5zaW9uTGl0ZTsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vbmVvZlVpbnQzMkV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9uZW9mTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9uZW9mU3RyaW5nRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub25lb2ZCeXRlc0V4dGVuc2lvbkxpdGU7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxJbnQzMkV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsSW50NjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vcHRpb25hbFVpbnQzMkV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsVWludDY0RXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxTaW50MzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vcHRpb25hbFNpbnQ2NEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsRml4ZWQ2NEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsU2ZpeGVkMzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vcHRpb25hbFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxGbG9hdEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsRG91YmxlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxCb29sRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxTdHJpbmdFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vcHRpb25hbEJ5dGVzRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxHcm91cEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsRm9yZWlnbkVudW1FeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUub3B0aW9uYWxMYXp5TWVzc2FnZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLm9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5vcHRpb25hbENvcmRFeHRlbnNpb25MaXRlOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkSW50MzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEludDY0RXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRVaW50MzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRTaW50NjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEZpeGVkMzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEZpeGVkNjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkRmxvYXRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZERvdWJsZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkQm9vbEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRCeXRlc0V4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkR3JvdXBFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRMYXp5TWVzc2FnZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZEltcG9ydEVudW1FeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5yZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucmVwZWF0ZWRDb3JkRXh0ZW5zaW9uTGl0ZTsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9saXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbl9saXRlOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnBhY2tlZEludDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucGFja2VkSW50NjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRVaW50MzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRVaW50NjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRTaW50MzJFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRTaW50NjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRGaXhlZDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucGFja2VkRml4ZWQ2NEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUucGFja2VkU2ZpeGVkNjRFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRGbG9hdEV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnBhY2tlZERvdWJsZUV4dGVuc2lvbkxpdGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLnBhY2tlZEJvb2xFeHRlbnNpb25MaXRlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5wYWNrZWRFbnVtRXh0ZW5zaW9uTGl0ZTsKKworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjI7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9uczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZTsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLlRlc3RBbGxUeXBlc0xpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuVGVzdEFsbEV4dGVuc2lvbnNMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLlRlc3RBbGxFeHRlbnNpb25zTGl0ZU9yQnVpbGRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5UZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdExpdGUuRm9yZWlnbk1lc3NhZ2VMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLkZvcmVpZ25FbnVtTGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0SW1wb3J0TGl0ZS5JbXBvcnRFbnVtTGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0SW1wb3J0TGl0ZS5JbXBvcnRNZXNzYWdlTGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0SW1wb3J0UHVibGljTGl0ZS5QdWJsaWNJbXBvcnRNZXNzYWdlTGl0ZTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CisKKy8qKgorICogQ29udGFpbnMgbWV0aG9kcyBmb3Igc2V0dGluZyBhbGwgZmllbGRzIG9mIHtAY29kZSBUZXN0QWxsVHlwZXN9IHRvCisgKiBzb21lIHZhbHVlcyBhcyB3ZWxsIGFzIGNoZWNraW5nIHRoYXQgYWxsIHRoZSBmaWVsZHMgYXJlIHNldCB0byB0aG9zZSB2YWx1ZXMuCisgKiBUaGVzZSBhcmUgdXNlZnVsIGZvciB0ZXN0aW5nIHZhcmlvdXMgcHJvdG9jb2wgbWVzc2FnZSBmZWF0dXJlcywgZS5nLgorICogc2V0IGFsbCBmaWVsZHMgb2YgYSBtZXNzYWdlLCBzZXJpYWxpemUgaXQsIHBhcnNlIGl0LCBhbmQgY2hlY2sgdGhhdCBhbGwKKyAqIGZpZWxkcyBhcmUgc2V0LgorICoKKyAqIDxwPlRoaXMgY29kZSBpcyBub3QgdG8gYmUgdXNlZCBvdXRzaWRlIG9mIHtAY29kZSBjb20uZ29vZ2xlLnByb3RvYnVmfSBhbmQKKyAqIHN1YnBhY2thZ2VzLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUZXN0VXRpbCB7CisgIHByaXZhdGUgVGVzdFV0aWwoKSB7fQorCisgIC8qKiBIZWxwZXIgdG8gY29udmVydCBhIFN0cmluZyB0byBCeXRlU3RyaW5nLiAqLworICBzdGF0aWMgQnl0ZVN0cmluZyB0b0J5dGVzKFN0cmluZyBzdHIpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIEJ5dGVTdHJpbmcuY29weUZyb20oc3RyLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICB9IGNhdGNoKGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVVRGLTggbm90IHN1cHBvcnRlZC4iLCBlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogR2V0IGEge0Bjb2RlIFRlc3RBbGxUeXBlc30gd2l0aCBhbGwgZmllbGRzIHNldCBhcyB0aGV5IHdvdWxkIGJlIGJ5CisgICAqIHtAbGluayAjc2V0QWxsRmllbGRzKFRlc3RBbGxUeXBlcy5CdWlsZGVyKX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIFRlc3RBbGxUeXBlcyBnZXRBbGxTZXQoKSB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgc2V0QWxsRmllbGRzKGJ1aWxkZXIpOworICAgIHJldHVybiBidWlsZGVyLmJ1aWxkKCk7CisgIH0KKworICAvKioKKyAgICogR2V0IGEge0Bjb2RlIFRlc3RBbGxUeXBlcy5CdWlsZGVyfSB3aXRoIGFsbCBmaWVsZHMgc2V0IGFzIHRoZXkgd291bGQgYmUgYnkKKyAgICoge0BsaW5rICNzZXRBbGxGaWVsZHMoVGVzdEFsbFR5cGVzLkJ1aWxkZXIpfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0QWxsU2V0QnVpbGRlcigpIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBzZXRBbGxGaWVsZHMoYnVpbGRlcik7CisgICAgcmV0dXJuIGJ1aWxkZXI7CisgIH0KKworICAvKioKKyAgICogR2V0IGEge0Bjb2RlIFRlc3RBbGxFeHRlbnNpb25zfSB3aXRoIGFsbCBmaWVsZHMgc2V0IGFzIHRoZXkgd291bGQgYmUgYnkKKyAgICoge0BsaW5rICNzZXRBbGxFeHRlbnNpb25zKFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIpfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgVGVzdEFsbEV4dGVuc2lvbnMgZ2V0QWxsRXh0ZW5zaW9uc1NldCgpIHsKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCk7CisgICAgc2V0QWxsRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICByZXR1cm4gYnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUgZ2V0QWxsTGl0ZUV4dGVuc2lvbnNTZXQoKSB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxFeHRlbnNpb25zTGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgc2V0QWxsRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICByZXR1cm4gYnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBUZXN0UGFja2VkVHlwZXMgZ2V0UGFja2VkU2V0KCkgeworICAgIFRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0UGFja2VkVHlwZXMubmV3QnVpbGRlcigpOworICAgIHNldFBhY2tlZEZpZWxkcyhidWlsZGVyKTsKKyAgICByZXR1cm4gYnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBUZXN0VW5wYWNrZWRUeXBlcyBnZXRVbnBhY2tlZFNldCgpIHsKKyAgICBUZXN0VW5wYWNrZWRUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0VW5wYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgc2V0VW5wYWNrZWRGaWVsZHMoYnVpbGRlcik7CisgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGQoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgVGVzdFBhY2tlZEV4dGVuc2lvbnMgZ2V0UGFja2VkRXh0ZW5zaW9uc1NldCgpIHsKKyAgICBUZXN0UGFja2VkRXh0ZW5zaW9ucy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0UGFja2VkRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCk7CisgICAgc2V0UGFja2VkRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICByZXR1cm4gYnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUgZ2V0TGl0ZVBhY2tlZEV4dGVuc2lvbnNTZXQoKSB7CisgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlLkJ1aWxkZXIgYnVpbGRlciA9CisgICAgICAgIFRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgc2V0UGFja2VkRXh0ZW5zaW9ucyhidWlsZGVyKTsKKyAgICByZXR1cm4gYnVpbGRlci5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIFNldCBldmVyeSBmaWVsZCBvZiB7QGNvZGUgbWVzc2FnZX0gdG8gdGhlIHZhbHVlcyBleHBlY3RlZCBieQorICAgKiB7QGNvZGUgYXNzZXJ0QWxsRmllbGRzU2V0KCl9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHNldEFsbEZpZWxkcyhUZXN0QWxsVHlwZXMuQnVpbGRlciBtZXNzYWdlKSB7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEludDMyICAgKDEwMSk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEludDY0ICAgKDEwMik7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbFVpbnQzMiAgKDEwMyk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbFVpbnQ2NCAgKDEwNCk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbFNpbnQzMiAgKDEwNSk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbFNpbnQ2NCAgKDEwNik7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEZpeGVkMzIgKDEwNyk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEZpeGVkNjQgKDEwOCk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbFNmaXhlZDMyKDEwOSk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbFNmaXhlZDY0KDExMCk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEZsb2F0ICAgKDExMSk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbERvdWJsZSAgKDExMik7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEJvb2wgICAgKHRydWUpOworICAgIG1lc3NhZ2Uuc2V0T3B0aW9uYWxTdHJpbmcgICgiMTE1Iik7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEJ5dGVzICAgKHRvQnl0ZXMoIjExNiIpKTsKKworICAgIG1lc3NhZ2Uuc2V0T3B0aW9uYWxHcm91cCgKKyAgICAgIFRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLm5ld0J1aWxkZXIoKS5zZXRBKDExNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMTE4KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoCisgICAgICBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygxMTkpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKAorICAgICAgSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RCgxMjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKAorICAgICAgUHVibGljSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RSgxMjYpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgKKyAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYigxMjcpLmJ1aWxkKCkpOworCisgICAgbWVzc2FnZS5zZXRPcHRpb25hbE5lc3RlZEVudW0gKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBWik7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbEZvcmVpZ25FbnVtKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFaKTsKKyAgICBtZXNzYWdlLnNldE9wdGlvbmFsSW1wb3J0RW51bSAoSW1wb3J0RW51bS5JTVBPUlRfQkFaKTsKKworICAgIG1lc3NhZ2Uuc2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgiMTI0Iik7CisgICAgbWVzc2FnZS5zZXRPcHRpb25hbENvcmQoIjEyNSIpOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRJbnQzMiAgICgyMDEpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRJbnQ2NCAgICgyMDIpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRVaW50MzIgICgyMDMpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRVaW50NjQgICgyMDQpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRTaW50MzIgICgyMDUpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRTaW50NjQgICgyMDYpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaXhlZDMyICgyMDcpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaXhlZDY0ICgyMDgpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRTZml4ZWQzMigyMDkpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRTZml4ZWQ2NCgyMTApOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGbG9hdCAgICgyMTEpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWREb3VibGUgICgyMTIpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRCb29sICAgICh0cnVlKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkU3RyaW5nICAoIjIxNSIpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRCeXRlcyAgICh0b0J5dGVzKCIyMTYiKSk7CisKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkR3JvdXAoCisgICAgICBUZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5uZXdCdWlsZGVyKCkuc2V0QSgyMTcpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAorICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDIxOCkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAorICAgICAgRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMjE5KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKKyAgICAgIEltcG9ydE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEQoMjIwKS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkTGF6eU1lc3NhZ2UoCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMjI3KS5idWlsZCgpKTsKKworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWROZXN0ZWRFbnVtIChUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGb3JlaWduRW51bShGb3JlaWduRW51bS5GT1JFSUdOX0JBUik7CisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEltcG9ydEVudW0gKEltcG9ydEVudW0uSU1QT1JUX0JBUik7CisKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkU3RyaW5nUGllY2UoIjIyNCIpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRDb3JkKCIyMjUiKTsKKworICAgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkSW50MzIgICAoMzAxKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkSW50NjQgICAoMzAyKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkVWludDMyICAoMzAzKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkVWludDY0ICAoMzA0KTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkU2ludDMyICAoMzA1KTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkU2ludDY0ICAoMzA2KTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRml4ZWQzMiAoMzA3KTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRml4ZWQ2NCAoMzA4KTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkU2ZpeGVkMzIoMzA5KTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkU2ZpeGVkNjQoMzEwKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmxvYXQgICAoMzExKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRG91YmxlICAoMzEyKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkQm9vbCAgICAoZmFsc2UpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRTdHJpbmcgICgiMzE1Iik7CisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEJ5dGVzICAgKHRvQnl0ZXMoIjMxNiIpKTsKKworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRHcm91cCgKKyAgICAgIFRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLm5ld0J1aWxkZXIoKS5zZXRBKDMxNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMzE4KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCisgICAgICBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygzMTkpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAorICAgICAgSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RCgzMjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKKyAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYigzMjcpLmJ1aWxkKCkpOworCisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZE5lc3RlZEVudW0gKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBWik7CisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZvcmVpZ25FbnVtKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFaKTsKKyAgICBtZXNzYWdlLmFkZFJlcGVhdGVkSW1wb3J0RW51bSAoSW1wb3J0RW51bS5JTVBPUlRfQkFaKTsKKworICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRTdHJpbmdQaWVjZSgiMzI0Iik7CisgICAgbWVzc2FnZS5hZGRSZXBlYXRlZENvcmQoIjMyNSIpOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIG1lc3NhZ2Uuc2V0RGVmYXVsdEludDMyICAgKDQwMSk7CisgICAgbWVzc2FnZS5zZXREZWZhdWx0SW50NjQgICAoNDAyKTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHRVaW50MzIgICg0MDMpOworICAgIG1lc3NhZ2Uuc2V0RGVmYXVsdFVpbnQ2NCAgKDQwNCk7CisgICAgbWVzc2FnZS5zZXREZWZhdWx0U2ludDMyICAoNDA1KTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHRTaW50NjQgICg0MDYpOworICAgIG1lc3NhZ2Uuc2V0RGVmYXVsdEZpeGVkMzIgKDQwNyk7CisgICAgbWVzc2FnZS5zZXREZWZhdWx0Rml4ZWQ2NCAoNDA4KTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHRTZml4ZWQzMig0MDkpOworICAgIG1lc3NhZ2Uuc2V0RGVmYXVsdFNmaXhlZDY0KDQxMCk7CisgICAgbWVzc2FnZS5zZXREZWZhdWx0RmxvYXQgICAoNDExKTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHREb3VibGUgICg0MTIpOworICAgIG1lc3NhZ2Uuc2V0RGVmYXVsdEJvb2wgICAgKGZhbHNlKTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHRTdHJpbmcgICgiNDE1Iik7CisgICAgbWVzc2FnZS5zZXREZWZhdWx0Qnl0ZXMgICAodG9CeXRlcygiNDE2IikpOworCisgICAgbWVzc2FnZS5zZXREZWZhdWx0TmVzdGVkRW51bSAoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PKTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHRGb3JlaWduRW51bShGb3JlaWduRW51bS5GT1JFSUdOX0ZPTyk7CisgICAgbWVzc2FnZS5zZXREZWZhdWx0SW1wb3J0RW51bSAoSW1wb3J0RW51bS5JTVBPUlRfRk9PKTsKKworICAgIG1lc3NhZ2Uuc2V0RGVmYXVsdFN0cmluZ1BpZWNlKCI0MjQiKTsKKyAgICBtZXNzYWdlLnNldERlZmF1bHRDb3JkKCI0MjUiKTsKKworICAgIG1lc3NhZ2Uuc2V0T25lb2ZVaW50MzIoNjAxKTsKKyAgICBtZXNzYWdlLnNldE9uZW9mTmVzdGVkTWVzc2FnZSgKKyAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYig2MDIpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0T25lb2ZTdHJpbmcoIjYwMyIpOworICAgIG1lc3NhZ2Uuc2V0T25lb2ZCeXRlcyh0b0J5dGVzKCI2MDQiKSk7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIE1vZGlmeSB0aGUgcmVwZWF0ZWQgZmllbGRzIG9mIHtAY29kZSBtZXNzYWdlfSB0byBjb250YWluIHRoZSB2YWx1ZXMKKyAgICogZXhwZWN0ZWQgYnkge0Bjb2RlIGFzc2VydFJlcGVhdGVkRmllbGRzTW9kaWZpZWQoKX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbW9kaWZ5UmVwZWF0ZWRGaWVsZHMoVGVzdEFsbFR5cGVzLkJ1aWxkZXIgbWVzc2FnZSkgeworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRJbnQzMiAgICgxLCA1MDEpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRJbnQ2NCAgICgxLCA1MDIpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRVaW50MzIgICgxLCA1MDMpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRVaW50NjQgICgxLCA1MDQpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRTaW50MzIgICgxLCA1MDUpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRTaW50NjQgICgxLCA1MDYpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaXhlZDMyICgxLCA1MDcpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaXhlZDY0ICgxLCA1MDgpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRTZml4ZWQzMigxLCA1MDkpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRTZml4ZWQ2NCgxLCA1MTApOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGbG9hdCAgICgxLCA1MTEpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWREb3VibGUgICgxLCA1MTIpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRCb29sICAgICgxLCB0cnVlKTsKKyAgICBtZXNzYWdlLnNldFJlcGVhdGVkU3RyaW5nICAoMSwgIjUxNSIpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRCeXRlcyAgICgxLCB0b0J5dGVzKCI1MTYiKSk7CisKKyAgICBtZXNzYWdlLnNldFJlcGVhdGVkR3JvdXAoMSwKKyAgICAgIFRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLm5ld0J1aWxkZXIoKS5zZXRBKDUxNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoMSwKKyAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYig1MTgpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgxLAorICAgICAgRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoNTE5KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgxLAorICAgICAgSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RCg1MjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRMYXp5TWVzc2FnZSgxLAorICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDUyNykuYnVpbGQoKSk7CisKKyAgICBtZXNzYWdlLnNldFJlcGVhdGVkTmVzdGVkRW51bSAoMSwgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PKTsKKyAgICBtZXNzYWdlLnNldFJlcGVhdGVkRm9yZWlnbkVudW0oMSwgRm9yZWlnbkVudW0uRk9SRUlHTl9GT08pOworICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRJbXBvcnRFbnVtICgxLCBJbXBvcnRFbnVtLklNUE9SVF9GT08pOworCisgICAgbWVzc2FnZS5zZXRSZXBlYXRlZFN0cmluZ1BpZWNlKDEsICI1MjQiKTsKKyAgICBtZXNzYWdlLnNldFJlcGVhdGVkQ29yZCgxLCAiNTI1Iik7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBmaWVsZHMgb2YKKyAgICoge0Bjb2RlIG1lc3NhZ2V9IGFyZSBzZXQgdG8gdGhlIHZhbHVlcyBhc3NpZ25lZCBieSB7QGNvZGUgc2V0QWxsRmllbGRzfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRBbGxGaWVsZHNTZXQoVGVzdEFsbFR5cGVzT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsSW50MzIgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbEludDY0ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxVaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsVWludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbFNpbnQzMiAgKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxTaW50NjQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsRml4ZWQzMiAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbEZpeGVkNjQgKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxTZml4ZWQzMigpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsU2ZpeGVkNjQoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbEZsb2F0ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxEb3VibGUgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsQm9vbCAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbFN0cmluZyAgKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxCeXRlcyAgICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxHcm91cCAgICAgICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0T3B0aW9uYWxHcm91cCAgICAgICAgICgpLmhhc0EoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UgKCkuaGFzQmIoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuaGFzQygpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSAoKS5oYXNEKCkpOworCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbE5lc3RlZEVudW0gKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT3B0aW9uYWxGb3JlaWduRW51bSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsSW1wb3J0RW51bSAoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc09wdGlvbmFsU3RyaW5nUGllY2UoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNPcHRpb25hbENvcmQoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwMSAgLCBtZXNzYWdlLmdldE9wdGlvbmFsSW50MzIgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMDIgICwgbWVzc2FnZS5nZXRPcHRpb25hbEludDY0ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTAzICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxVaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwNCAgLCBtZXNzYWdlLmdldE9wdGlvbmFsVWludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMDUgICwgbWVzc2FnZS5nZXRPcHRpb25hbFNpbnQzMiAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTA2ICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxTaW50NjQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwNyAgLCBtZXNzYWdlLmdldE9wdGlvbmFsRml4ZWQzMiAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMDggICwgbWVzc2FnZS5nZXRPcHRpb25hbEZpeGVkNjQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTA5ICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxTZml4ZWQzMigpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDExMCAgLCBtZXNzYWdlLmdldE9wdGlvbmFsU2ZpeGVkNjQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMTEgICwgbWVzc2FnZS5nZXRPcHRpb25hbEZsb2F0ICAgKCksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMTIgICwgbWVzc2FnZS5nZXRPcHRpb25hbERvdWJsZSAgKCksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0cnVlICwgbWVzc2FnZS5nZXRPcHRpb25hbEJvb2wgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjExNSIsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxTdHJpbmcgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRvQnl0ZXMoIjExNiIpLCBtZXNzYWdlLmdldE9wdGlvbmFsQnl0ZXMoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDExNywgbWVzc2FnZS5nZXRPcHRpb25hbEdyb3VwICAgICAgICAgICAgICAoKS5nZXRBKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTE4LCBtZXNzYWdlLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSAgICAgICgpLmdldEJiKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTE5LCBtZXNzYWdlLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgICAgICgpLmdldEMoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMjAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlICAgICAgKCkuZ2V0RCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEyNiwgbWVzc2FnZS5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKS5nZXRFKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTI3LCBtZXNzYWdlLmdldE9wdGlvbmFsTGF6eU1lc3NhZ2UgICAgICAgICgpLmdldEJiKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVosIG1lc3NhZ2UuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVosIG1lc3NhZ2UuZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEltcG9ydEVudW0uSU1QT1JUX0JBWiwgbWVzc2FnZS5nZXRPcHRpb25hbEltcG9ydEVudW0oKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIxMjQiLCBtZXNzYWdlLmdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMTI1IiwgbWVzc2FnZS5nZXRPcHRpb25hbENvcmQoKSk7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkSW50MzJDb3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQ2NENvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZFVpbnQzMkNvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkVWludDY0Q291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZFNpbnQ2NENvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRml4ZWQzMkNvdW50ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGbG9hdENvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZERvdWJsZUNvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkQm9vbENvdW50ICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEJ5dGVzQ291bnQgICAoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRHcm91cENvdW50ICAgICAgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50ICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEltcG9ydEVudW1Db3VudCAgICAoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZENvcmRDb3VudCgpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjAxICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQzMiAgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDIgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEludDY0ICAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwMyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkVWludDMyICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA0ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRVaW50NjQgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDUgICwgbWVzc2FnZS5nZXRSZXBlYXRlZFNpbnQzMiAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwNiAgLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ludDY0ICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA3ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaXhlZDMyICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDggICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpeGVkNjQgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwOSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ZpeGVkMzIoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjEwICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTZml4ZWQ2NCgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTEgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZsb2F0ICAgKDApLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjEyICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWREb3VibGUgICgwKSwgMC4wKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRydWUgLCBtZXNzYWdlLmdldFJlcGVhdGVkQm9vbCAgICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjIxNSIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTdHJpbmcgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0b0J5dGVzKCIyMTYiKSwgbWVzc2FnZS5nZXRSZXBlYXRlZEJ5dGVzKDApKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjE3LCBtZXNzYWdlLmdldFJlcGVhdGVkR3JvdXAgICAgICAgICAoMCkuZ2V0QSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxOCwgbWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UgKDApLmdldEJiKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjE5LCBtZXNzYWdlLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoMCkuZ2V0QygpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIyMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UgKDApLmdldEQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMjcsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZSAgICgwKS5nZXRCYigpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFSLCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bSAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduRW51bSgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhJbXBvcnRFbnVtLklNUE9SVF9CQVIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbXBvcnRFbnVtKDApKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjIyNCIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZSgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMjI1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZENvcmQoMCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMDEgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEludDMyICAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMwMiAgLCBtZXNzYWdlLmdldFJlcGVhdGVkSW50NjQgICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzAzICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRVaW50MzIgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMDQgICwgbWVzc2FnZS5nZXRSZXBlYXRlZFVpbnQ2NCAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMwNSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ludDMyICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzA2ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTaW50NjQgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMDcgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpeGVkMzIgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMwOCAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRml4ZWQ2NCAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzA5ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTZml4ZWQzMigxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMTAgICwgbWVzc2FnZS5nZXRSZXBlYXRlZFNmaXhlZDY0KDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMxMSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmxvYXQgICAoMSksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMTIgICwgbWVzc2FnZS5nZXRSZXBlYXRlZERvdWJsZSAgKDEpLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZmFsc2UsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRCb29sICAgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMzE1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZyAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRvQnl0ZXMoIjMxNiIpLCBtZXNzYWdlLmdldFJlcGVhdGVkQnl0ZXMoMSkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMTcsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRHcm91cCAgICAgICAgICgxKS5nZXRBKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzE4LCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSAoMSkuZ2V0QmIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMTksIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgxKS5nZXRDKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzIwLCBtZXNzYWdlLmdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSAoMSkuZ2V0RCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMyNywgbWVzc2FnZS5nZXRSZXBlYXRlZExhenlNZXNzYWdlICAgKDEpLmdldEJiKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVosIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhGb3JlaWduRW51bS5GT1JFSUdOX0JBWiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZvcmVpZ25FbnVtKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEltcG9ydEVudW0uSU1QT1JUX0JBWiwgbWVzc2FnZS5nZXRSZXBlYXRlZEltcG9ydEVudW0oMSkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMzI0IiwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ1BpZWNlKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIzMjUiLCBtZXNzYWdlLmdldFJlcGVhdGVkQ29yZCgxKSk7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0SW50MzIgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0SW50NjQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0VWludDMyICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0VWludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0U2ludDMyICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0U2ludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0Rml4ZWQzMiAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0Rml4ZWQ2NCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0U2ZpeGVkMzIoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0U2ZpeGVkNjQoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0RmxvYXQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0RG91YmxlICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0Qm9vbCAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0U3RyaW5nICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNEZWZhdWx0Qnl0ZXMgICAoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0RlZmF1bHROZXN0ZWRFbnVtICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0RlZmF1bHRGb3JlaWduRW51bSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0RlZmF1bHRJbXBvcnRFbnVtICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRGVmYXVsdFN0cmluZ1BpZWNlKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRGVmYXVsdENvcmQoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwMSAgLCBtZXNzYWdlLmdldERlZmF1bHRJbnQzMiAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwMiAgLCBtZXNzYWdlLmdldERlZmF1bHRJbnQ2NCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwMyAgLCBtZXNzYWdlLmdldERlZmF1bHRVaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwNCAgLCBtZXNzYWdlLmdldERlZmF1bHRVaW50NjQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwNSAgLCBtZXNzYWdlLmdldERlZmF1bHRTaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwNiAgLCBtZXNzYWdlLmdldERlZmF1bHRTaW50NjQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwNyAgLCBtZXNzYWdlLmdldERlZmF1bHRGaXhlZDMyICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwOCAgLCBtZXNzYWdlLmdldERlZmF1bHRGaXhlZDY0ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwOSAgLCBtZXNzYWdlLmdldERlZmF1bHRTZml4ZWQzMigpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQxMCAgLCBtZXNzYWdlLmdldERlZmF1bHRTZml4ZWQ2NCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQxMSAgLCBtZXNzYWdlLmdldERlZmF1bHRGbG9hdCAgICgpLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNDEyICAsIG1lc3NhZ2UuZ2V0RGVmYXVsdERvdWJsZSAgKCksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhmYWxzZSwgbWVzc2FnZS5nZXREZWZhdWx0Qm9vbCAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNDE1IiwgbWVzc2FnZS5nZXREZWZhdWx0U3RyaW5nICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0b0J5dGVzKCI0MTYiKSwgbWVzc2FnZS5nZXREZWZhdWx0Qnl0ZXMoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTywgbWVzc2FnZS5nZXREZWZhdWx0TmVzdGVkRW51bSAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhGb3JlaWduRW51bS5GT1JFSUdOX0ZPTywgbWVzc2FnZS5nZXREZWZhdWx0Rm9yZWlnbkVudW0oKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhJbXBvcnRFbnVtLklNUE9SVF9GT08sIG1lc3NhZ2UuZ2V0RGVmYXVsdEltcG9ydEVudW0oKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCI0MjQiLCBtZXNzYWdlLmdldERlZmF1bHRTdHJpbmdQaWVjZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCI0MjUiLCBtZXNzYWdlLmdldERlZmF1bHRDb3JkKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT25lb2ZVaW50MzIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09uZW9mU3RyaW5nKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzT25lb2ZCeXRlcygpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHModG9CeXRlcygiNjA0IiksIG1lc3NhZ2UuZ2V0T25lb2ZCeXRlcygpKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBmaWVsZHMgb2YKKyAgICoge0Bjb2RlIG1lc3NhZ2V9IGFyZSBjbGVhcmVkLCBhbmQgdGhhdCBnZXR0aW5nIHRoZSBmaWVsZHMgcmV0dXJucyB0aGVpcgorICAgKiBkZWZhdWx0IHZhbHVlcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRDbGVhcihUZXN0QWxsVHlwZXNPckJ1aWxkZXIgbWVzc2FnZSkgeworICAgIC8vIGhhc0JsYWgoKSBzaG91bGQgaW5pdGlhbGx5IGJlIGZhbHNlIGZvciBhbGwgb3B0aW9uYWwgZmllbGRzLgorICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsSW50MzIgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxJbnQ2NCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbFVpbnQzMiAgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsVWludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxTaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbFNpbnQ2NCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsRml4ZWQzMiAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxGaXhlZDY0ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbFNmaXhlZDMyKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsU2ZpeGVkNjQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxGbG9hdCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbERvdWJsZSAgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsQm9vbCAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxTdHJpbmcgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbEJ5dGVzICAgKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxHcm91cCAgICAgICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09wdGlvbmFsTmVzdGVkRW51bSAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxGb3JlaWduRW51bSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbEltcG9ydEVudW0gKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzT3B0aW9uYWxTdHJpbmdQaWVjZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPcHRpb25hbENvcmQoKSk7CisKKyAgICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHplcm8gb3Igc29tZXRoaW5nIGxpa2UgaXQuCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwICAgICwgbWVzc2FnZS5nZXRPcHRpb25hbEludDMyICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCAgICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxJbnQ2NCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAgICAgLCBtZXNzYWdlLmdldE9wdGlvbmFsVWludDMyICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwICAgICwgbWVzc2FnZS5nZXRPcHRpb25hbFVpbnQ2NCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCAgICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxTaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAgICAgLCBtZXNzYWdlLmdldE9wdGlvbmFsU2ludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwICAgICwgbWVzc2FnZS5nZXRPcHRpb25hbEZpeGVkMzIgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCAgICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxGaXhlZDY0ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAgICAgLCBtZXNzYWdlLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwICAgICwgbWVzc2FnZS5nZXRPcHRpb25hbFNmaXhlZDY0KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCAgICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxGbG9hdCAgICgpLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCAgICAsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxEb3VibGUgICgpLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZmFsc2UsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxCb29sICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIiICAgLCBtZXNzYWdlLmdldE9wdGlvbmFsU3RyaW5nICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhCeXRlU3RyaW5nLkVNUFRZLCBtZXNzYWdlLmdldE9wdGlvbmFsQnl0ZXMoKSk7CisKKyAgICAvLyBFbWJlZGRlZCBtZXNzYWdlcyBzaG91bGQgYWxzbyBiZSBjbGVhci4KKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5nZXRPcHRpb25hbEdyb3VwICAgICAgICAgICAgICAoKS5oYXNBKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSAgICAgICgpLmhhc0JiKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgICAgICgpLmhhc0MoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlICAgICAgKCkuaGFzRCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKS5oYXNFKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldE9wdGlvbmFsTGF6eU1lc3NhZ2UgICAgICAgICgpLmhhc0JiKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldE9wdGlvbmFsR3JvdXAgICAgICAgICAgICAgICgpLmdldEEoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSAgICAgICgpLmdldEJiKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlICAgICAoKS5nZXRDKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UgICAgICAoKS5nZXREKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKS5nZXRFKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRPcHRpb25hbExhenlNZXNzYWdlICAgICAgICAoKS5nZXRCYigpKTsKKworICAgIC8vIEVudW1zIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlIGVudW0uCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08sIG1lc3NhZ2UuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEZvcmVpZ25FbnVtLkZPUkVJR05fRk9PLCBtZXNzYWdlLmdldE9wdGlvbmFsRm9yZWlnbkVudW0oKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhJbXBvcnRFbnVtLklNUE9SVF9GT08sIG1lc3NhZ2UuZ2V0T3B0aW9uYWxJbXBvcnRFbnVtKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiIiwgbWVzc2FnZS5nZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIiIsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxDb3JkKCkpOworCisgICAgLy8gUmVwZWF0ZWQgZmllbGRzIGFyZSBlbXB0eS4KKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQzMkNvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEludDY0Q291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkVWludDMyQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZFNpbnQzMkNvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ludDY0Q291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpeGVkNjRDb3VudCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZsb2F0Q291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRG91YmxlQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRCb29sQ291bnQgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ0NvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkQnl0ZXNDb3VudCAgICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEdyb3VwQ291bnQgICAgICAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkSW1wb3J0RW51bUNvdW50ICAgICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ1BpZWNlQ291bnQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkQ29yZENvdW50KCkpOworCisgICAgLy8gaGFzQmxhaCgpIHNob3VsZCBhbHNvIGJlIGZhbHNlIGZvciBhbGwgZGVmYXVsdCBmaWVsZHMuCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRGVmYXVsdEludDMyICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRJbnQ2NCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0VWludDMyICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRGVmYXVsdFVpbnQ2NCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRTaW50MzIgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0U2ludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRGVmYXVsdEZpeGVkMzIgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRGaXhlZDY0ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0U2ZpeGVkMzIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRGVmYXVsdFNmaXhlZDY0KCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRGbG9hdCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0RG91YmxlICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRGVmYXVsdEJvb2wgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRTdHJpbmcgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0Qnl0ZXMgICAoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0TmVzdGVkRW51bSAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRGVmYXVsdEZvcmVpZ25FbnVtKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRJbXBvcnRFbnVtICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0RlZmF1bHRTdHJpbmdQaWVjZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNEZWZhdWx0Q29yZCgpKTsKKworICAgIC8vIEZpZWxkcyB3aXRoIGRlZmF1bHRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMgKGR1aCkuCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggNDEgICAgLCBtZXNzYWdlLmdldERlZmF1bHRJbnQzMiAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCA0MiAgICAsIG1lc3NhZ2UuZ2V0RGVmYXVsdEludDY0ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQzICAgICwgbWVzc2FnZS5nZXREZWZhdWx0VWludDMyICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggNDQgICAgLCBtZXNzYWdlLmdldERlZmF1bHRVaW50NjQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC00NSAgICAsIG1lc3NhZ2UuZ2V0RGVmYXVsdFNpbnQzMiAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ2ICAgICwgbWVzc2FnZS5nZXREZWZhdWx0U2ludDY0ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggNDcgICAgLCBtZXNzYWdlLmdldERlZmF1bHRGaXhlZDMyICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCA0OCAgICAsIG1lc3NhZ2UuZ2V0RGVmYXVsdEZpeGVkNjQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ5ICAgICwgbWVzc2FnZS5nZXREZWZhdWx0U2ZpeGVkMzIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtNTAgICAgLCBtZXNzYWdlLmdldERlZmF1bHRTZml4ZWQ2NCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCA1MS41ICAsIG1lc3NhZ2UuZ2V0RGVmYXVsdEZsb2F0ICAgKCksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggNTJlMyAgLCBtZXNzYWdlLmdldERlZmF1bHREb3VibGUgICgpLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHModHJ1ZSAgICwgbWVzc2FnZS5nZXREZWZhdWx0Qm9vbCAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiaGVsbG8iLCBtZXNzYWdlLmdldERlZmF1bHRTdHJpbmcgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRvQnl0ZXMoIndvcmxkIiksIG1lc3NhZ2UuZ2V0RGVmYXVsdEJ5dGVzKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsIG1lc3NhZ2UuZ2V0RGVmYXVsdE5lc3RlZEVudW0gKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVIsIG1lc3NhZ2UuZ2V0RGVmYXVsdEZvcmVpZ25FbnVtKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoSW1wb3J0RW51bS5JTVBPUlRfQkFSLCBtZXNzYWdlLmdldERlZmF1bHRJbXBvcnRFbnVtKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiYWJjIiwgbWVzc2FnZS5nZXREZWZhdWx0U3RyaW5nUGllY2UoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMTIzIiwgbWVzc2FnZS5nZXREZWZhdWx0Q29yZCgpKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09uZW9mVWludDMyKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc09uZW9mTmVzdGVkTWVzc2FnZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPbmVvZlN0cmluZygpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNPbmVvZkJ5dGVzKCkpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKgorICAgKiBBc3NlcnQgKHVzaW5nIHtAY29kZSBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0fX0gdGhhdCBhbGwgZmllbGRzIG9mCisgICAqIHtAY29kZSBtZXNzYWdlfSBhcmUgc2V0IHRvIHRoZSB2YWx1ZXMgYXNzaWduZWQgYnkge0Bjb2RlIHNldEFsbEZpZWxkc30KKyAgICogZm9sbG93ZWQgYnkge0Bjb2RlIG1vZGlmeVJlcGVhdGVkRmllbGRzfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRSZXBlYXRlZEZpZWxkc01vZGlmaWVkKAorICAgICAgVGVzdEFsbFR5cGVzT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAvLyBNb2RpZnlSZXBlYXRlZEZpZWxkcyBvbmx5IHNldHMgdGhlIHNlY29uZCByZXBlYXRlZCBlbGVtZW50IG9mIGVhY2gKKyAgICAvLyBmaWVsZC4gIEluIGFkZGl0aW9uIHRvIHZlcmlmeWluZyB0aGlzLCB3ZSBhbHNvIHZlcmlmeSB0aGF0IHRoZSBmaXJzdAorICAgIC8vIGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KiBtb2RpZmllZC4KKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQzMkNvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEludDY0Q291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkVWludDMyQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZFNpbnQzMkNvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ludDY0Q291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpeGVkNjRDb3VudCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZsb2F0Q291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRG91YmxlQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRCb29sQ291bnQgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ0NvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkQnl0ZXNDb3VudCAgICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEdyb3VwQ291bnQgICAgICAgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkSW1wb3J0RW51bUNvdW50ICAgICgpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ1BpZWNlQ291bnQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkQ29yZENvdW50KCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDEgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEludDMyICAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwMkwgLCBtZXNzYWdlLmdldFJlcGVhdGVkSW50NjQgICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjAzICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRVaW50MzIgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDRMICwgbWVzc2FnZS5nZXRSZXBlYXRlZFVpbnQ2NCAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwNSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ludDMyICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA2TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTaW50NjQgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDcgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpeGVkMzIgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwOEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRml4ZWQ2NCAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA5ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTZml4ZWQzMigwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTBMICwgbWVzc2FnZS5nZXRSZXBlYXRlZFNmaXhlZDY0KDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxMUYgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmxvYXQgICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjEyRCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWREb3VibGUgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0cnVlICwgbWVzc2FnZS5nZXRSZXBlYXRlZEJvb2wgICAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIyMTUiLCBtZXNzYWdlLmdldFJlcGVhdGVkU3RyaW5nICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHModG9CeXRlcygiMjE2IiksIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRCeXRlcygwKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxNywgbWVzc2FnZS5nZXRSZXBlYXRlZEdyb3VwICAgICAgICAgKDApLmdldEEoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTgsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlICgwKS5nZXRCYigpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxOSwgbWVzc2FnZS5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKDApLmdldEMoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMjAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlICgwKS5nZXREKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjI3LCBtZXNzYWdlLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2UgICAoMCkuZ2V0QmIoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUiwgbWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZEVudW0gKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFSLCBtZXNzYWdlLmdldFJlcGVhdGVkRm9yZWlnbkVudW0oMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoSW1wb3J0RW51bS5JTVBPUlRfQkFSLCBtZXNzYWdlLmdldFJlcGVhdGVkSW1wb3J0RW51bSgwKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIyMjQiLCBtZXNzYWdlLmdldFJlcGVhdGVkU3RyaW5nUGllY2UoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjIyNSIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRDb3JkKDApKTsKKworICAgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTAxICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRJbnQzMiAgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MDJMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEludDY0ICAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUwMyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkVWludDMyICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTA0TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRVaW50NjQgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MDUgICwgbWVzc2FnZS5nZXRSZXBlYXRlZFNpbnQzMiAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUwNkwgLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ludDY0ICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTA3ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaXhlZDMyICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MDhMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpeGVkNjQgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUwOSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkU2ZpeGVkMzIoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTEwTCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRTZml4ZWQ2NCgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MTFGICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZsb2F0ICAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUxMkQgLCBtZXNzYWdlLmdldFJlcGVhdGVkRG91YmxlICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHModHJ1ZSAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRCb29sICAgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNTE1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZyAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRvQnl0ZXMoIjUxNiIpLCBtZXNzYWdlLmdldFJlcGVhdGVkQnl0ZXMoMSkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MTcsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRHcm91cCAgICAgICAgICgxKS5nZXRBKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTE4LCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSAoMSkuZ2V0QmIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MTksIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgxKS5nZXRDKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTIwLCBtZXNzYWdlLmdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSAoMSkuZ2V0RCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUyNywgbWVzc2FnZS5nZXRSZXBlYXRlZExhenlNZXNzYWdlICAgKDEpLmdldEJiKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08sIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhGb3JlaWduRW51bS5GT1JFSUdOX0ZPTywgbWVzc2FnZS5nZXRSZXBlYXRlZEZvcmVpZ25FbnVtKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEltcG9ydEVudW0uSU1QT1JUX0ZPTywgbWVzc2FnZS5nZXRSZXBlYXRlZEltcG9ydEVudW0oMSkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNTI0IiwgbWVzc2FnZS5nZXRSZXBlYXRlZFN0cmluZ1BpZWNlKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCI1MjUiLCBtZXNzYWdlLmdldFJlcGVhdGVkQ29yZCgxKSk7CisgIH0KKworICAvKioKKyAgICogU2V0IGV2ZXJ5IGZpZWxkIG9mIHtAY29kZSBtZXNzYWdlfSB0byBhIHVuaXF1ZSB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQYWNrZWRGaWVsZHMoVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIgbWVzc2FnZSkgeworICAgIG1lc3NhZ2UuYWRkUGFja2VkSW50MzIgICAoNjAxKTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZEludDY0ICAgKDYwMik7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRVaW50MzIgICg2MDMpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkVWludDY0ICAoNjA0KTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZFNpbnQzMiAgKDYwNSk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRTaW50NjQgICg2MDYpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkRml4ZWQzMiAoNjA3KTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZEZpeGVkNjQgKDYwOCk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRTZml4ZWQzMig2MDkpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkU2ZpeGVkNjQoNjEwKTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZEZsb2F0ICAgKDYxMSk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWREb3VibGUgICg2MTIpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkQm9vbCAgICAodHJ1ZSk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRFbnVtICAgIChGb3JlaWduRW51bS5GT1JFSUdOX0JBUik7CisgICAgLy8gQWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICAgIG1lc3NhZ2UuYWRkUGFja2VkSW50MzIgICAoNzAxKTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZEludDY0ICAgKDcwMik7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRVaW50MzIgICg3MDMpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkVWludDY0ICAoNzA0KTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZFNpbnQzMiAgKDcwNSk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRTaW50NjQgICg3MDYpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkRml4ZWQzMiAoNzA3KTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZEZpeGVkNjQgKDcwOCk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWRTZml4ZWQzMig3MDkpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkU2ZpeGVkNjQoNzEwKTsKKyAgICBtZXNzYWdlLmFkZFBhY2tlZEZsb2F0ICAgKDcxMSk7CisgICAgbWVzc2FnZS5hZGRQYWNrZWREb3VibGUgICg3MTIpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkQm9vbCAgICAoZmFsc2UpOworICAgIG1lc3NhZ2UuYWRkUGFja2VkRW51bSAgICAoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVopOworICB9CisKKyAgLyoqCisgICAqIFNldCBldmVyeSBmaWVsZCBvZiB7QGNvZGUgbWVzc2FnZX0gdG8gYSB1bmlxdWUgdmFsdWUuIE11c3QgY29ycmVzcG9uZCB3aXRoCisgICAqIHRoZSB2YWx1ZXMgYXBwbGllZCBieSB7QGNvZGUgc2V0UGFja2VkRmllbGRzfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRVbnBhY2tlZEZpZWxkcyhUZXN0VW5wYWNrZWRUeXBlcy5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkSW50MzIgICAoNjAxKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkSW50NjQgICAoNjAyKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkVWludDMyICAoNjAzKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkVWludDY0ICAoNjA0KTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkU2ludDMyICAoNjA1KTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkU2ludDY0ICAoNjA2KTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkRml4ZWQzMiAoNjA3KTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkRml4ZWQ2NCAoNjA4KTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkU2ZpeGVkMzIoNjA5KTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkU2ZpeGVkNjQoNjEwKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkRmxvYXQgICAoNjExKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkRG91YmxlICAoNjEyKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkQm9vbCAgICAodHJ1ZSk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEVudW0gICAgKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFSKTsKKyAgICAvLyBBZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQuCisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEludDMyICAgKDcwMSk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEludDY0ICAgKDcwMik7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZFVpbnQzMiAgKDcwMyk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZFVpbnQ2NCAgKDcwNCk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZFNpbnQzMiAgKDcwNSk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZFNpbnQ2NCAgKDcwNik7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEZpeGVkMzIgKDcwNyk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEZpeGVkNjQgKDcwOCk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZFNmaXhlZDMyKDcwOSk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZFNmaXhlZDY0KDcxMCk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEZsb2F0ICAgKDcxMSk7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZERvdWJsZSAgKDcxMik7CisgICAgbWVzc2FnZS5hZGRVbnBhY2tlZEJvb2wgICAgKGZhbHNlKTsKKyAgICBtZXNzYWdlLmFkZFVucGFja2VkRW51bSAgICAoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVopOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBmaWVsZHMgb2YKKyAgICoge0Bjb2RlIG1lc3NhZ2V9IGFyZSBzZXQgdG8gdGhlIHZhbHVlcyBhc3NpZ25lZCBieSB7QGNvZGUgc2V0UGFja2VkRmllbGRzfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRQYWNrZWRGaWVsZHNTZXQoVGVzdFBhY2tlZFR5cGVzIG1lc3NhZ2UpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkSW50MzJDb3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkSW50NjRDb3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkVWludDMyQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkVWludDY0Q291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkU2ludDMyQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkU2ludDY0Q291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkRml4ZWQzMkNvdW50ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkRml4ZWQ2NENvdW50ICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkU2ZpeGVkNjRDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkRmxvYXRDb3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkRG91YmxlQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkQm9vbENvdW50ICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UGFja2VkRW51bUNvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjAxICAsIG1lc3NhZ2UuZ2V0UGFja2VkSW50MzIgICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjAyICAsIG1lc3NhZ2UuZ2V0UGFja2VkSW50NjQgICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjAzICAsIG1lc3NhZ2UuZ2V0UGFja2VkVWludDMyICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA0ICAsIG1lc3NhZ2UuZ2V0UGFja2VkVWludDY0ICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA1ICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ludDMyICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA2ICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ludDY0ICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA3ICAsIG1lc3NhZ2UuZ2V0UGFja2VkRml4ZWQzMiAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA4ICAsIG1lc3NhZ2UuZ2V0UGFja2VkRml4ZWQ2NCAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA5ICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ZpeGVkMzIoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjEwICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ZpeGVkNjQoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjExICAsIG1lc3NhZ2UuZ2V0UGFja2VkRmxvYXQgICAoMCksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MTIgICwgbWVzc2FnZS5nZXRQYWNrZWREb3VibGUgICgwKSwgMC4wKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRydWUgLCBtZXNzYWdlLmdldFBhY2tlZEJvb2wgICAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFSLCBtZXNzYWdlLmdldFBhY2tlZEVudW0oMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzAxICAsIG1lc3NhZ2UuZ2V0UGFja2VkSW50MzIgICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzAyICAsIG1lc3NhZ2UuZ2V0UGFja2VkSW50NjQgICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzAzICAsIG1lc3NhZ2UuZ2V0UGFja2VkVWludDMyICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA0ICAsIG1lc3NhZ2UuZ2V0UGFja2VkVWludDY0ICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA1ICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ludDMyICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA2ICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ludDY0ICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA3ICAsIG1lc3NhZ2UuZ2V0UGFja2VkRml4ZWQzMiAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA4ICAsIG1lc3NhZ2UuZ2V0UGFja2VkRml4ZWQ2NCAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA5ICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ZpeGVkMzIoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzEwICAsIG1lc3NhZ2UuZ2V0UGFja2VkU2ZpeGVkNjQoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzExICAsIG1lc3NhZ2UuZ2V0UGFja2VkRmxvYXQgICAoMSksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MTIgICwgbWVzc2FnZS5nZXRQYWNrZWREb3VibGUgICgxKSwgMC4wKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZhbHNlLCBtZXNzYWdlLmdldFBhY2tlZEJvb2wgICAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFaLCBtZXNzYWdlLmdldFBhY2tlZEVudW0oMSkpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBmaWVsZHMgb2YKKyAgICoge0Bjb2RlIG1lc3NhZ2V9IGFyZSBzZXQgdG8gdGhlIHZhbHVlcyBhc3NpZ25lZCBieSB7QGNvZGUgc2V0VW5wYWNrZWRGaWVsZHN9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFVucGFja2VkRmllbGRzU2V0KFRlc3RVbnBhY2tlZFR5cGVzIG1lc3NhZ2UpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRJbnQzMkNvdW50ICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRVbnBhY2tlZEludDY0Q291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFVucGFja2VkVWludDMyQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRVaW50NjRDb3VudCAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRVbnBhY2tlZFNpbnQzMkNvdW50ICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFVucGFja2VkU2ludDY0Q291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRGaXhlZDMyQ291bnQgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRVbnBhY2tlZEZpeGVkNjRDb3VudCAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFVucGFja2VkU2ZpeGVkMzJDb3VudCgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRTZml4ZWQ2NENvdW50KCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRVbnBhY2tlZEZsb2F0Q291bnQgICAoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFVucGFja2VkRG91YmxlQ291bnQgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRCb29sQ291bnQgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRVbnBhY2tlZEVudW1Db3VudCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYwMSAgLCBtZXNzYWdlLmdldFVucGFja2VkSW50MzIgICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjAyICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRJbnQ2NCAgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDMgICwgbWVzc2FnZS5nZXRVbnBhY2tlZFVpbnQzMiAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYwNCAgLCBtZXNzYWdlLmdldFVucGFja2VkVWludDY0ICAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA1ICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRTaW50MzIgICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDYgICwgbWVzc2FnZS5nZXRVbnBhY2tlZFNpbnQ2NCAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYwNyAgLCBtZXNzYWdlLmdldFVucGFja2VkRml4ZWQzMiAoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA4ICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRGaXhlZDY0ICgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDkgICwgbWVzc2FnZS5nZXRVbnBhY2tlZFNmaXhlZDMyKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYxMCAgLCBtZXNzYWdlLmdldFVucGFja2VkU2ZpeGVkNjQoMCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjExICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRGbG9hdCAgICgwKSwgMC4wKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYxMiAgLCBtZXNzYWdlLmdldFVucGFja2VkRG91YmxlICAoMCksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0cnVlICwgbWVzc2FnZS5nZXRVbnBhY2tlZEJvb2wgICAgKDApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFSLCBtZXNzYWdlLmdldFVucGFja2VkRW51bSgwKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MDEgICwgbWVzc2FnZS5nZXRVbnBhY2tlZEludDMyICAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcwMiAgLCBtZXNzYWdlLmdldFVucGFja2VkSW50NjQgICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzAzICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRVaW50MzIgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MDQgICwgbWVzc2FnZS5nZXRVbnBhY2tlZFVpbnQ2NCAgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcwNSAgLCBtZXNzYWdlLmdldFVucGFja2VkU2ludDMyICAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA2ICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRTaW50NjQgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MDcgICwgbWVzc2FnZS5nZXRVbnBhY2tlZEZpeGVkMzIgKDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcwOCAgLCBtZXNzYWdlLmdldFVucGFja2VkRml4ZWQ2NCAoMSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA5ICAsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRTZml4ZWQzMigxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MTAgICwgbWVzc2FnZS5nZXRVbnBhY2tlZFNmaXhlZDY0KDEpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcxMSAgLCBtZXNzYWdlLmdldFVucGFja2VkRmxvYXQgICAoMSksIDAuMCk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MTIgICwgbWVzc2FnZS5nZXRVbnBhY2tlZERvdWJsZSAgKDEpLCAwLjApOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZmFsc2UsIG1lc3NhZ2UuZ2V0VW5wYWNrZWRCb29sICAgICgxKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhGb3JlaWduRW51bS5GT1JFSUdOX0JBWiwgbWVzc2FnZS5nZXRVbnBhY2tlZEVudW0oMSkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBMaWtlIGFib3ZlLCBidXQgZm9yIGV4dGVuc2lvbnMKKworICAvLyBKYXZhIGdldHMgY29uZnVzZWQgd2l0aCB0aGluZ3MgbGlrZSBhc3NlcnRFcXVhbHMoaW50LCBJbnRlZ2VyKTogIGl0IGNhbid0CisgIC8vIGRlY2lkZSB3aGV0aGVyIHRvIGNhbGwgYXNzZXJ0RXF1YWxzKGludCwgaW50KSBvciBhc3NlcnRFcXVhbHMoT2JqZWN0LAorICAvLyBPYmplY3QpLiAgU28gd2UgZGVmaW5lIHRoZXNlIG1ldGhvZHMgdG8gaGVscCBpdC4KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoaW50IGEsIGludCBiKSB7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhhLCBiKTsKKyAgfQorICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsc0V4YWN0VHlwZShsb25nIGEsIGxvbmcgYikgeworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoYSwgYik7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoZmxvYXQgYSwgZmxvYXQgYikgeworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoYSwgYiwgMC4wKTsKKyAgfQorICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsc0V4YWN0VHlwZShkb3VibGUgYSwgZG91YmxlIGIpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGEsIGIsIDAuMCk7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoYm9vbGVhbiBhLCBib29sZWFuIGIpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGEsIGIpOworICB9CisgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFN0cmluZyBhLCBTdHJpbmcgYikgeworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoYSwgYik7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoQnl0ZVN0cmluZyBhLCBCeXRlU3RyaW5nIGIpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGEsIGIpOworICB9CisgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGIpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGEsIGIpOworICB9CisgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtIGEsIEZvcmVpZ25FbnVtIGIpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGEsIGIpOworICB9CisgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW0gYSwgSW1wb3J0RW51bSBiKSB7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhhLCBiKTsKKyAgfQorICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0gYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRFbnVtIGIpIHsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGEsIGIpOworICB9CisgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtTGl0ZSBhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JlaWduRW51bUxpdGUgYikgeworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoYSwgYik7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoSW1wb3J0RW51bUxpdGUgYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1wb3J0RW51bUxpdGUgYikgeworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoYSwgYik7CisgIH0KKworICAvKioKKyAgICogR2V0IGFuIHVubW9kaWZpYWJsZSB7QGxpbmsgRXh0ZW5zaW9uUmVnaXN0cnl9IGNvbnRhaW5pbmcgYWxsIHRoZQorICAgKiBleHRlbnNpb25zIG9mIHtAY29kZSBUZXN0QWxsRXh0ZW5zaW9uc30uCisgICAqLworICBwdWJsaWMgc3RhdGljIEV4dGVuc2lvblJlZ2lzdHJ5IGdldEV4dGVuc2lvblJlZ2lzdHJ5KCkgeworICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gRXh0ZW5zaW9uUmVnaXN0cnkubmV3SW5zdGFuY2UoKTsKKyAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMocmVnaXN0cnkpOworICAgIHJldHVybiByZWdpc3RyeS5nZXRVbm1vZGlmaWFibGUoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGdldEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSgpIHsKKyAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkgPSBFeHRlbnNpb25SZWdpc3RyeUxpdGUubmV3SW5zdGFuY2UoKTsKKyAgICByZWdpc3RlckFsbEV4dGVuc2lvbnNMaXRlKHJlZ2lzdHJ5KTsKKyAgICByZXR1cm4gcmVnaXN0cnkuZ2V0VW5tb2RpZmlhYmxlKCk7CisgIH0KKworICAvKioKKyAgICogUmVnaXN0ZXIgYWxsIG9mIHtAY29kZSBUZXN0QWxsRXh0ZW5zaW9uc30ncyBleHRlbnNpb25zIHdpdGggdGhlCisgICAqIGdpdmVuIHtAbGluayBFeHRlbnNpb25SZWdpc3RyeX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CisgICAgVW5pdHRlc3RQcm90by5yZWdpc3RlckFsbEV4dGVuc2lvbnMocmVnaXN0cnkpOworICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9uc0xpdGUocmVnaXN0cnkpOworICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9uc0xpdGUoRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CisgICAgVW5pdHRlc3RMaXRlLnJlZ2lzdGVyQWxsRXh0ZW5zaW9ucyhyZWdpc3RyeSk7CisgIH0KKworICAvKioKKyAgICogU2V0IGV2ZXJ5IGZpZWxkIG9mIHtAY29kZSBtZXNzYWdlfSB0byB0aGUgdmFsdWVzIGV4cGVjdGVkIGJ5CisgICAqIHtAY29kZSBhc3NlcnRBbGxFeHRlbnNpb25zU2V0KCl9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHNldEFsbEV4dGVuc2lvbnMoVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciBtZXNzYWdlKSB7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxJbnQzMkV4dGVuc2lvbiAgICwgMTAxKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uICAgLCAxMDJMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbFVpbnQzMkV4dGVuc2lvbiAgLCAxMDMpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsVWludDY0RXh0ZW5zaW9uICAsIDEwNEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uICAsIDEwNSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxTaW50NjRFeHRlbnNpb24gICwgMTA2TCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxGaXhlZDMyRXh0ZW5zaW9uICwgMTA3KTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkNjRFeHRlbnNpb24gLCAxMDhMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbFNmaXhlZDMyRXh0ZW5zaW9uLCAxMDkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkNjRFeHRlbnNpb24sIDExMEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsRmxvYXRFeHRlbnNpb24gICAsIDExMUYpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsRG91YmxlRXh0ZW5zaW9uICAsIDExMkQpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsQm9vbEV4dGVuc2lvbiAgICAsIHRydWUpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nRXh0ZW5zaW9uICAsICIxMTUiKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEJ5dGVzRXh0ZW5zaW9uICAgLCB0b0J5dGVzKCIxMTYiKSk7CisKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEdyb3VwRXh0ZW5zaW9uLAorICAgICAgT3B0aW9uYWxHcm91cF9leHRlbnNpb24ubmV3QnVpbGRlcigpLnNldEEoMTE3KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb24sCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMTE4KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uLAorICAgICAgRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEMoMTE5KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb24sCisgICAgICBJbXBvcnRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXREKDEyMCkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uLAorICAgICAgUHVibGljSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RSgxMjYpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsTGF6eU1lc3NhZ2VFeHRlbnNpb24sCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMTI3KS5idWlsZCgpKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbiwgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFaKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uLCBGb3JlaWduRW51bS5GT1JFSUdOX0JBWik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uLCBJbXBvcnRFbnVtLklNUE9SVF9CQVopOworCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxTdHJpbmdQaWVjZUV4dGVuc2lvbiwgIjEyNCIpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsQ29yZEV4dGVuc2lvbiwgIjEyNSIpOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb24gICAsIDIwMSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbiAgICwgMjAyTCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb24gICwgMjAzKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgLCAyMDRMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbiAgLCAyMDUpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uICAsIDIwNkwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbiAsIDIwNyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uICwgMjA4TCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbiwgMjA5KTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uLCAyMTBMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uICAgLCAyMTFGKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZERvdWJsZUV4dGVuc2lvbiAgLCAyMTJEKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgLCB0cnVlKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbiAgLCAiMjE1Iik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbiAgICwgdG9CeXRlcygiMjE2IikpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRHcm91cEV4dGVuc2lvbiwKKyAgICAgIFJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uLm5ld0J1aWxkZXIoKS5zZXRBKDIxNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uLAorICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDIxOCkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbiwKKyAgICAgIEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRDKDIxOSkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uLAorICAgICAgSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RCgyMjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb24sCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMjI3KS5idWlsZCgpKTsKKworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbiwgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFSKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uLCBGb3JlaWduRW51bS5GT1JFSUdOX0JBUik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uLCBJbXBvcnRFbnVtLklNUE9SVF9CQVIpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbiwgIjIyNCIpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkQ29yZEV4dGVuc2lvbiwgIjIyNSIpOworCisgICAgLy8gQWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb24gICAsIDMwMSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbiAgICwgMzAyTCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb24gICwgMzAzKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgLCAzMDRMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbiAgLCAzMDUpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uICAsIDMwNkwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbiAsIDMwNyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uICwgMzA4TCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbiwgMzA5KTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uLCAzMTBMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uICAgLCAzMTFGKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZERvdWJsZUV4dGVuc2lvbiAgLCAzMTJEKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgLCBmYWxzZSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb24gICwgIjMxNSIpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkQnl0ZXNFeHRlbnNpb24gICAsIHRvQnl0ZXMoIjMxNiIpKTsKKworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkR3JvdXBFeHRlbnNpb24sCisgICAgICBSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5uZXdCdWlsZGVyKCkuc2V0QSgzMTcpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiwKKyAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYigzMTgpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24sCisgICAgICBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QygzMTkpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiwKKyAgICAgIEltcG9ydE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEQoMzIwKS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uLAorICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDMyNykuYnVpbGQoKSk7CisKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb24sIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBWik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbiwgRm9yZWlnbkVudW0uRk9SRUlHTl9CQVopOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbiwgSW1wb3J0RW51bS5JTVBPUlRfQkFaKTsKKworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkU3RyaW5nUGllY2VFeHRlbnNpb24sICIzMjQiKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZENvcmRFeHRlbnNpb24sICIzMjUiKTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0SW50MzJFeHRlbnNpb24gICAsIDQwMSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEludDY0RXh0ZW5zaW9uICAgLCA0MDJMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0VWludDMyRXh0ZW5zaW9uICAsIDQwMyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdFVpbnQ2NEV4dGVuc2lvbiAgLCA0MDRMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uICAsIDQwNSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbiAgLCA0MDZMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbiAsIDQwNyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEZpeGVkNjRFeHRlbnNpb24gLCA0MDhMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb24sIDQwOSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdFNmaXhlZDY0RXh0ZW5zaW9uLCA0MTBMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb24gICAsIDQxMUYpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHREb3VibGVFeHRlbnNpb24gICwgNDEyRCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEJvb2xFeHRlbnNpb24gICAgLCBmYWxzZSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdFN0cmluZ0V4dGVuc2lvbiAgLCAiNDE1Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uICAgLCB0b0J5dGVzKCI0MTYiKSk7CisKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0TmVzdGVkRW51bUV4dGVuc2lvbiwgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb24sIEZvcmVpZ25FbnVtLkZPUkVJR05fRk9PKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbiwgSW1wb3J0RW51bS5JTVBPUlRfRk9PKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRTdHJpbmdQaWVjZUV4dGVuc2lvbiwgIjQyNCIpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRDb3JkRXh0ZW5zaW9uLCAiNDI1Iik7CisKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvbmVvZlVpbnQzMkV4dGVuc2lvbiwgNjAxKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvbmVvZk5lc3RlZE1lc3NhZ2VFeHRlbnNpb24sCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoNjAyKS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvbmVvZlN0cmluZ0V4dGVuc2lvbiwgIjYwMyIpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9uZW9mQnl0ZXNFeHRlbnNpb24sIHRvQnl0ZXMoIjYwNCIpKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvKioKKyAgICogTW9kaWZ5IHRoZSByZXBlYXRlZCBleHRlbnNpb25zIG9mIHtAY29kZSBtZXNzYWdlfSB0byBjb250YWluIHRoZSB2YWx1ZXMKKyAgICogZXhwZWN0ZWQgYnkge0Bjb2RlIGFzc2VydFJlcGVhdGVkRXh0ZW5zaW9uc01vZGlmaWVkKCl9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1vZGlmeVJlcGVhdGVkRXh0ZW5zaW9ucygKKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgbWVzc2FnZSkgeworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb24gICAsIDEsIDUwMSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbiAgICwgMSwgNTAyTCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb24gICwgMSwgNTAzKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgLCAxLCA1MDRMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbiAgLCAxLCA1MDUpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uICAsIDEsIDUwNkwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbiAsIDEsIDUwNyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uICwgMSwgNTA4TCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbiwgMSwgNTA5KTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uLCAxLCA1MTBMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uICAgLCAxLCA1MTFGKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZERvdWJsZUV4dGVuc2lvbiAgLCAxLCA1MTJEKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgLCAxLCB0cnVlKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbiAgLCAxLCAiNTE1Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbiAgICwgMSwgdG9CeXRlcygiNTE2IikpOworCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRHcm91cEV4dGVuc2lvbiwgMSwKKyAgICAgIFJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uLm5ld0J1aWxkZXIoKS5zZXRBKDUxNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uLCAxLAorICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDUxOCkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbiwgMSwKKyAgICAgIEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRDKDUxOSkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uLCAxLAorICAgICAgSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0RCg1MjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb24sIDEsCisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoNTI3KS5idWlsZCgpKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbiAsIDEsIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbiwgMSwgRm9yZWlnbkVudW0uRk9SRUlHTl9GT08pOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbiAsIDEsIEltcG9ydEVudW0uSU1QT1JUX0ZPTyk7CisKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uLCAxLCAiNTI0Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uLCAxLCAiNTI1Iik7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBleHRlbnNpb25zIG9mCisgICAqIHtAY29kZSBtZXNzYWdlfSBhcmUgc2V0IHRvIHRoZSB2YWx1ZXMgYXNzaWduZWQgYnkge0Bjb2RlIHNldEFsbEV4dGVuc2lvbnN9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEFsbEV4dGVuc2lvbnNTZXQoCisgICAgICBUZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlciBtZXNzYWdlKSB7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsSW50NjRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFVpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxVaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFNpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFNmaXhlZDMyRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbERvdWJsZUV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxCb29sRXh0ZW5zaW9uICAgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEJ5dGVzRXh0ZW5zaW9uICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEdyb3VwRXh0ZW5zaW9uICAgICAgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb24gKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEdyb3VwRXh0ZW5zaW9uICAgICAgICAgKS5oYXNBKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiApLmhhc0JiKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24pLmhhc0MoKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uICkuaGFzRCgpKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uICkpOworCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxTdHJpbmdQaWVjZUV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQ29yZEV4dGVuc2lvbikpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEludDMyRXh0ZW5zaW9uICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwMyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFVpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFVpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFNpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwNkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFNpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkMzJFeHRlbnNpb24gKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkNjRFeHRlbnNpb24gKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwOSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFNmaXhlZDMyRXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDExMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFNmaXhlZDY0RXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDExMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZsb2F0RXh0ZW5zaW9uICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDExMkQgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbERvdWJsZUV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRydWUgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEJvb2xFeHRlbnNpb24gICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIxMTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFN0cmluZ0V4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRvQnl0ZXMoIjExNiIpLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEJ5dGVzRXh0ZW5zaW9uKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTE3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEdyb3VwRXh0ZW5zaW9uICAgICAgICAgICAgICApLmdldEEoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDExOCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICAgICAgKS5nZXRCYigpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTE5LCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uICAgICApLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEyMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uICAgICAgKS5nZXREKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMjYsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUV4dGVuc2lvbikuZ2V0RSgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTI3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uICAgICAgICApLmdldEJiKCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBWiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bS5GT1JFSUdOX0JBWiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbkVudW1FeHRlbnNpb24pKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoSW1wb3J0RW51bS5JTVBPUlRfQkFaLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjEyNCIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb24pKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjEyNSIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsQ29yZEV4dGVuc2lvbikpOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEludDMyRXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW50NjRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRVaW50MzJFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRTaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24gKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWREb3VibGVFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbiAgICkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkR3JvdXBFeHRlbnNpb24gICAgICAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRMYXp5TWVzc2FnZUV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb24gICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uICAgICkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU3RyaW5nUGllY2VFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjAxICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb24gICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjAyTCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW50NjRFeHRlbnNpb24gICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA0TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA1ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA3ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbiAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA4TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbiAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb24sIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjEwTCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkNjRFeHRlbnNpb24sIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjExRiAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRmxvYXRFeHRlbnNpb24gICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodHJ1ZSAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQm9vbEV4dGVuc2lvbiAgICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjIxNSIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygiMjE2IiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQnl0ZXNFeHRlbnNpb24sIDApKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkR3JvdXBFeHRlbnNpb24gICAgICAgICAsIDApLmdldEEoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxOCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICwgMCkuZ2V0QmIoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxOSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbiwgMCkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjIwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydE1lc3NhZ2VFeHRlbnNpb24gLCAwKS5nZXREKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMjcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb24gICAsIDApLmdldEJiKCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbiwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bS5GT1JFSUdOX0JBUiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb24sIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoSW1wb3J0RW51bS5JTVBPUlRfQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uLCAwKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjIyNCIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU3RyaW5nUGllY2VFeHRlbnNpb24sIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjIyNSIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQ29yZEV4dGVuc2lvbiwgMCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDMyRXh0ZW5zaW9uICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDY0RXh0ZW5zaW9uICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwMyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQzMkV4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwNkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24gLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb24gLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwOSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDMyRXh0ZW5zaW9uLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMxMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMxMkQgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZERvdWJsZUV4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKGZhbHNlLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIzMTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRvQnl0ZXMoIjMxNiIpLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uLCAxKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzE3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEdyb3VwRXh0ZW5zaW9uICAgICAgICAgLCAxKS5nZXRBKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMTgsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiAsIDEpLmdldEJiKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMTksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24sIDEpLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMyMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uICwgMSkuZ2V0RCgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzI3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uICAgLCAxKS5nZXRCYigpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVosCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb24sIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVosCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW0uSU1QT1JUX0JBWiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbiwgMSkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIzMjQiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIzMjUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZENvcmRFeHRlbnNpb24sIDEpKTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0SW50MzJFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0VWludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0VWludDY0RXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ludDY0RXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ZpeGVkNjRFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0RG91YmxlRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Qm9vbEV4dGVuc2lvbiAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Qnl0ZXNFeHRlbnNpb24gICApKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRJbXBvcnRFbnVtRXh0ZW5zaW9uICkpOworCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFN0cmluZ1BpZWNlRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdENvcmRFeHRlbnNpb24pKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg0MDEgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEludDMyRXh0ZW5zaW9uICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb24gICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNDAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRVaW50MzJFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg0MDRMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFVpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNDA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTaW50NjRFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg0MDcgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEZpeGVkMzJFeHRlbnNpb24gKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNDA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQzMkV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg0MTBMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFNmaXhlZDY0RXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNDEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHREb3VibGVFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShmYWxzZSwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEJvb2xFeHRlbnNpb24gICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCI0MTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygiNDE2IiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRCeXRlc0V4dGVuc2lvbikpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTywKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bS5GT1JFSUdOX0ZPTywKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShJbXBvcnRFbnVtLklNUE9SVF9GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbikpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCI0MjQiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb24pKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjQyNSIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRDb3JkRXh0ZW5zaW9uKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvbmVvZkJ5dGVzRXh0ZW5zaW9uKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygiNjA0IiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9uZW9mQnl0ZXNFeHRlbnNpb24pKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvKioKKyAgICogQXNzZXJ0ICh1c2luZyB7QGNvZGUganVuaXQuZnJhbWV3b3JrLkFzc2VydH19IHRoYXQgYWxsIGV4dGVuc2lvbnMgb2YKKyAgICoge0Bjb2RlIG1lc3NhZ2V9IGFyZSBjbGVhcmVkLCBhbmQgdGhhdCBnZXR0aW5nIHRoZSBleHRlbnNpb25zIHJldHVybnMgdGhlaXIKKyAgICogZGVmYXVsdCB2YWx1ZXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0RXh0ZW5zaW9uc0NsZWFyKFRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAvLyBoYXNCbGFoKCkgc2hvdWxkIGluaXRpYWxseSBiZSBmYWxzZSBmb3IgYWxsIG9wdGlvbmFsIGZpZWxkcy4KKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsVWludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxVaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFNpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ludDY0RXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEZpeGVkNjRFeHRlbnNpb24gKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkMzJFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEZsb2F0RXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRG91YmxlRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxCb29sRXh0ZW5zaW9uICAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFN0cmluZ0V4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQnl0ZXNFeHRlbnNpb24gICApKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEdyb3VwRXh0ZW5zaW9uICAgICAgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxGb3JlaWduTWVzc2FnZUV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb24gKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsSW1wb3J0RW51bUV4dGVuc2lvbiApKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFN0cmluZ1BpZWNlRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQ29yZEV4dGVuc2lvbikpOworCisgICAgLy8gT3B0aW9uYWwgZmllbGRzIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB6ZXJvIG9yIHNvbWV0aGluZyBsaWtlIGl0LgorICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxJbnQ2NEV4dGVuc2lvbiAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxVaW50MzJFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxVaW50NjRFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTaW50MzJFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTaW50NjRFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxGaXhlZDY0RXh0ZW5zaW9uICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQzMkV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwRiAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxGbG9hdEV4dGVuc2lvbiAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwRCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxEb3VibGVFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShmYWxzZSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxCb29sRXh0ZW5zaW9uICAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiIiAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTdHJpbmdFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShCeXRlU3RyaW5nLkVNUFRZLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEJ5dGVzRXh0ZW5zaW9uKSk7CisKKyAgICAvLyBFbWJlZGRlZCBtZXNzYWdlcyBzaG91bGQgYWxzbyBiZSBjbGVhci4KKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxHcm91cEV4dGVuc2lvbiAgICAgICAgICkuaGFzQSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICkuaGFzQmIoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24pLmhhc0MoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiApLmhhc0QoKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxHcm91cEV4dGVuc2lvbiAgICAgICAgICkuZ2V0QSgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICkuZ2V0QmIoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24pLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiApLmdldEQoKSk7CisKKyAgICAvLyBFbnVtcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBlbnVtLgorICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbE5lc3RlZEVudW1FeHRlbnNpb24gKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtLkZPUkVJR05fRk9PLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxGb3JlaWduRW51bUV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShJbXBvcnRFbnVtLklNUE9SVF9GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb24pKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiIiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTdHJpbmdQaWVjZUV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiIiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxDb3JkRXh0ZW5zaW9uKSk7CisKKyAgICAvLyBSZXBlYXRlZCBmaWVsZHMgYXJlIGVtcHR5LgorICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEludDMyRXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW50NjRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRVaW50MzJFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRTaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24gKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWREb3VibGVFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbiAgICkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkR3JvdXBFeHRlbnNpb24gICAgICAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRMYXp5TWVzc2FnZUV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb24gICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uICAgICkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU3RyaW5nUGllY2VFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uKSk7CisKKyAgICAvLyBSZXBlYXRlZCBmaWVsZHMgYXJlIGVtcHR5IHZpYSBnZXRFeHRlbnNpb24oKS5zaXplKCkuCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDMyRXh0ZW5zaW9uICAgKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbiAgICkuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uICApLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50MzJFeHRlbnNpb24gICkuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uICApLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24gKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uICkuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb24pLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGbG9hdEV4dGVuc2lvbiAgICkuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uICApLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb24gICkuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQnl0ZXNFeHRlbnNpb24gICApLnNpemUoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkR3JvdXBFeHRlbnNpb24gICAgICAgICApLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZE1lc3NhZ2VFeHRlbnNpb24gKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbikuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiApLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uICAgKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uICAgICkuc2l6ZSgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb24gICApLnNpemUoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydEVudW1FeHRlbnNpb24gICAgKS5zaXplKCkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uKS5zaXplKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uKS5zaXplKCkpOworCisgICAgLy8gaGFzQmxhaCgpIHNob3VsZCBhbHNvIGJlIGZhbHNlIGZvciBhbGwgZGVmYXVsdCBmaWVsZHMuCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFVpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRVaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFNmaXhlZDMyRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdERvdWJsZUV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRCb29sRXh0ZW5zaW9uICAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb24gKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbiApKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdENvcmRFeHRlbnNpb24pKTsKKworICAgIC8vIEZpZWxkcyB3aXRoIGRlZmF1bHRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMgKGR1aCkuCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA0MSAgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSggNDJMICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb24gICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDQzICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFVpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA0NEwgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRVaW50NjRFeHRlbnNpb24gICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgtNDUgICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDQ2TCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA0NyAgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSggNDhMICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbiApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDQ5ICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFNmaXhlZDMyRXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKC01MEwgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSggNTEuNUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb24gICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDUyZTNEICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdERvdWJsZUV4dGVuc2lvbiAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRydWUgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRCb29sRXh0ZW5zaW9uICAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiaGVsbG8iLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygid29ybGQiKSwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb24gKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEZvcmVpZ25FbnVtRXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW0uSU1QT1JUX0JBUiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRJbXBvcnRFbnVtRXh0ZW5zaW9uKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoImFiYyIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTdHJpbmdQaWVjZUV4dGVuc2lvbikpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiMTIzIiwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdENvcmRFeHRlbnNpb24pKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvbmVvZlVpbnQzMkV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvbmVvZk5lc3RlZE1lc3NhZ2VFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob25lb2ZTdHJpbmdFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob25lb2ZCeXRlc0V4dGVuc2lvbikpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKgorICAgKiBBc3NlcnQgKHVzaW5nIHtAY29kZSBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0fX0gdGhhdCBhbGwgZXh0ZW5zaW9ucyBvZgorICAgKiB7QGNvZGUgbWVzc2FnZX0gYXJlIHNldCB0byB0aGUgdmFsdWVzIGFzc2lnbmVkIGJ5IHtAY29kZSBzZXRBbGxFeHRlbnNpb25zfQorICAgKiBmb2xsb3dlZCBieSB7QGNvZGUgbW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAvLyBNb2RpZnlSZXBlYXRlZEZpZWxkcyBvbmx5IHNldHMgdGhlIHNlY29uZCByZXBlYXRlZCBlbGVtZW50IG9mIGVhY2gKKyAgICAvLyBmaWVsZC4gIEluIGFkZGl0aW9uIHRvIHZlcmlmeWluZyB0aGlzLCB3ZSBhbHNvIHZlcmlmeSB0aGF0IHRoZSBmaXJzdAorICAgIC8vIGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KiBtb2RpZmllZC4KKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEludDY0RXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRVaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb24gKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb24pKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRCb29sRXh0ZW5zaW9uICAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbiAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkQnl0ZXNFeHRlbnNpb24gICApKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEdyb3VwRXh0ZW5zaW9uICAgICAgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEltcG9ydE1lc3NhZ2VFeHRlbnNpb24gKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb24gICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uICAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbiAgICApKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkQ29yZEV4dGVuc2lvbikpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDMyRXh0ZW5zaW9uICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDY0RXh0ZW5zaW9uICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwMyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQzMkV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwNkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24gLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb24gLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwOSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDMyRXh0ZW5zaW9uLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxMkQgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZERvdWJsZUV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRydWUgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb24gICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRvQnl0ZXMoIjIxNiIpLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uLCAwKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjE3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEdyb3VwRXh0ZW5zaW9uICAgICAgICAgLCAwKS5nZXRBKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTgsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiAsIDApLmdldEJiKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24sIDApLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIyMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uICwgMCkuZ2V0RCgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjI3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uICAgLCAwKS5nZXRCYigpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb24sIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVIsCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW0uSU1QT1JUX0JBUiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbiwgMCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMjQiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMjUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZENvcmRFeHRlbnNpb24sIDApKTsKKworICAgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDEgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbnQzMkV4dGVuc2lvbiAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDJMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbiAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDMgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDRMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50NjRFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDUgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50MzJFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDZMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50NjRFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDcgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDMyRXh0ZW5zaW9uICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDhMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDkgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbiwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MTBMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbiwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MTFGICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGbG9hdEV4dGVuc2lvbiAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MTJEICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWREb3VibGVFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSh0cnVlICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRCb29sRXh0ZW5zaW9uICAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiNTE1IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSh0b0J5dGVzKCI1MTYiKSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbiwgMSkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUxNywgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRHcm91cEV4dGVuc2lvbiAgICAgICAgICwgMSkuZ2V0QSgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTE4LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZE1lc3NhZ2VFeHRlbnNpb24gLCAxKS5nZXRCYigpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTE5LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uLCAxKS5nZXRDKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MjAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbiAsIDEpLmdldEQoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUyNywgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRMYXp5TWVzc2FnZUV4dGVuc2lvbiAgICwgMSkuZ2V0QmIoKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtLkZPUkVJR05fRk9PLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbiwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShJbXBvcnRFbnVtLklNUE9SVF9GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydEVudW1FeHRlbnNpb24sIDEpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiNTI0IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbiwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiNTI1IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uLCAxKSk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0UGFja2VkRXh0ZW5zaW9ucyhUZXN0UGFja2VkRXh0ZW5zaW9ucy5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRJbnQzMkV4dGVuc2lvbiAgICwgNjAxKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRJbnQ2NEV4dGVuc2lvbiAgICwgNjAyTCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkVWludDMyRXh0ZW5zaW9uICAsIDYwMyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkVWludDY0RXh0ZW5zaW9uICAsIDYwNEwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZFNpbnQzMkV4dGVuc2lvbiAgLCA2MDUpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZFNpbnQ2NEV4dGVuc2lvbiAgLCA2MDZMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGaXhlZDMyRXh0ZW5zaW9uICwgNjA3KTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGaXhlZDY0RXh0ZW5zaW9uICwgNjA4TCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkU2ZpeGVkMzJFeHRlbnNpb24sIDYwOSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkU2ZpeGVkNjRFeHRlbnNpb24sIDYxMEwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZEZsb2F0RXh0ZW5zaW9uICAgLCA2MTFGKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWREb3VibGVFeHRlbnNpb24gICwgNjEyRCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkQm9vbEV4dGVuc2lvbiAgICAsIHRydWUpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZEVudW1FeHRlbnNpb24sIEZvcmVpZ25FbnVtLkZPUkVJR05fQkFSKTsKKyAgICAvLyBBZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQuCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkSW50MzJFeHRlbnNpb24gICAsIDcwMSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkSW50NjRFeHRlbnNpb24gICAsIDcwMkwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZFVpbnQzMkV4dGVuc2lvbiAgLCA3MDMpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZFVpbnQ2NEV4dGVuc2lvbiAgLCA3MDRMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRTaW50MzJFeHRlbnNpb24gICwgNzA1KTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRTaW50NjRFeHRlbnNpb24gICwgNzA2TCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRml4ZWQzMkV4dGVuc2lvbiAsIDcwNyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRml4ZWQ2NEV4dGVuc2lvbiAsIDcwOEwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uLCA3MDkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZFNmaXhlZDY0RXh0ZW5zaW9uLCA3MTBMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGbG9hdEV4dGVuc2lvbiAgICwgNzExRik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRG91YmxlRXh0ZW5zaW9uICAsIDcxMkQpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZEJvb2xFeHRlbnNpb24gICAgLCBmYWxzZSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRW51bUV4dGVuc2lvbiwgRm9yZWlnbkVudW0uRk9SRUlHTl9CQVopOworICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFBhY2tlZEV4dGVuc2lvbnNTZXQoVGVzdFBhY2tlZEV4dGVuc2lvbnMgbWVzc2FnZSkgeworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRJbnQzMkV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRJbnQ2NEV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRVaW50MzJFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRVaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRTaW50MzJFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRTaW50NjRFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRGaXhlZDMyRXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRGaXhlZDY0RXh0ZW5zaW9uICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRTZml4ZWQzMkV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRTZml4ZWQ2NEV4dGVuc2lvbikpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRGbG9hdEV4dGVuc2lvbiAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWREb3VibGVFeHRlbnNpb24gICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRCb29sRXh0ZW5zaW9uICAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRFbnVtRXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRJbnQzMkV4dGVuc2lvbiAgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MDJMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkSW50NjRFeHRlbnNpb24gICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFVpbnQzMkV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRVaW50NjRFeHRlbnNpb24gICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MDUgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkU2ludDMyRXh0ZW5zaW9uICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNpbnQ2NEV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRGaXhlZDMyRXh0ZW5zaW9uICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MDhMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkRml4ZWQ2NEV4dGVuc2lvbiAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYxMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRTZml4ZWQ2NEV4dGVuc2lvbiwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MTFGICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkRmxvYXRFeHRlbnNpb24gICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZERvdWJsZUV4dGVuc2lvbiAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRydWUgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRCb29sRXh0ZW5zaW9uICAgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bS5GT1JFSUdOX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkRW51bUV4dGVuc2lvbiwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MDEgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkSW50MzJFeHRlbnNpb24gICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzAyTCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZEludDY0RXh0ZW5zaW9uICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcwMyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRVaW50MzJFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MDRMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkVWludDY0RXh0ZW5zaW9uICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzA1ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNpbnQzMkV4dGVuc2lvbiAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcwNkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRTaW50NjRFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MDcgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkRml4ZWQzMkV4dGVuc2lvbiAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzA4TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZEZpeGVkNjRFeHRlbnNpb24gLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcwOSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRTZml4ZWQzMkV4dGVuc2lvbiwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MTBMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkU2ZpeGVkNjRFeHRlbnNpb24sIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzExRiAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZEZsb2F0RXh0ZW5zaW9uICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcxMkQgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWREb3VibGVFeHRlbnNpb24gICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShmYWxzZSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkQm9vbEV4dGVuc2lvbiAgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoRm9yZWlnbkVudW0uRk9SRUlHTl9CQVosCisgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZEVudW1FeHRlbnNpb24sIDEpKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gTGl0ZSBleHRlbnNpb25zCisKKyAgLyoqCisgICAqIFNldCBldmVyeSBmaWVsZCBvZiB7QGNvZGUgbWVzc2FnZX0gdG8gdGhlIHZhbHVlcyBleHBlY3RlZCBieQorICAgKiB7QGNvZGUgYXNzZXJ0QWxsRXh0ZW5zaW9uc1NldCgpfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRBbGxFeHRlbnNpb25zKFRlc3RBbGxFeHRlbnNpb25zTGl0ZS5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEludDMyRXh0ZW5zaW9uTGl0ZSAgICwgMTAxKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uTGl0ZSAgICwgMTAyTCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxVaW50MzJFeHRlbnNpb25MaXRlICAsIDEwMyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxVaW50NjRFeHRlbnNpb25MaXRlICAsIDEwNEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uTGl0ZSAgLCAxMDUpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU2ludDY0RXh0ZW5zaW9uTGl0ZSAgLCAxMDZMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkMzJFeHRlbnNpb25MaXRlICwgMTA3KTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkNjRFeHRlbnNpb25MaXRlICwgMTA4TCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQzMkV4dGVuc2lvbkxpdGUsIDEwOSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQ2NEV4dGVuc2lvbkxpdGUsIDExMEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsRmxvYXRFeHRlbnNpb25MaXRlICAgLCAxMTFGKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbERvdWJsZUV4dGVuc2lvbkxpdGUgICwgMTEyRCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxCb29sRXh0ZW5zaW9uTGl0ZSAgICAsIHRydWUpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nRXh0ZW5zaW9uTGl0ZSAgLCAiMTE1Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxCeXRlc0V4dGVuc2lvbkxpdGUgICAsIHRvQnl0ZXMoIjExNiIpKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsR3JvdXBFeHRlbnNpb25MaXRlLAorICAgICAgT3B0aW9uYWxHcm91cF9leHRlbnNpb25fbGl0ZS5uZXdCdWlsZGVyKCkuc2V0QSgxMTcpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUsCisgICAgICBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDExOCkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxGb3JlaWduTWVzc2FnZUV4dGVuc2lvbkxpdGUsCisgICAgICBGb3JlaWduTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpLnNldEMoMTE5KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlLAorICAgICAgSW1wb3J0TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpLnNldEQoMTIwKS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlLAorICAgICAgUHVibGljSW1wb3J0TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpLnNldEUoMTI2KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSwKKyAgICAgIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMTI3KS5idWlsZCgpKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbkxpdGUsIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkRW51bS5CQVopOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbkVudW1FeHRlbnNpb25MaXRlLCBGb3JlaWduRW51bUxpdGUuRk9SRUlHTl9MSVRFX0JBWik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSwgSW1wb3J0RW51bUxpdGUuSU1QT1JUX0xJVEVfQkFaKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb25MaXRlLCAiMTI0Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob3B0aW9uYWxDb3JkRXh0ZW5zaW9uTGl0ZSwgIjEyNSIpOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb25MaXRlICAgLCAyMDEpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW50NjRFeHRlbnNpb25MaXRlICAgLCAyMDJMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFVpbnQzMkV4dGVuc2lvbkxpdGUgICwgMjAzKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbkxpdGUgICwgMjA0TCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDIwNSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTaW50NjRFeHRlbnNpb25MaXRlICAsIDIwNkwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbkxpdGUgLCAyMDcpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbkxpdGUgLCAyMDhMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZSwgMjA5KTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZSwgMjEwTCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDIxMUYpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uTGl0ZSAgLCAyMTJEKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb25MaXRlICAgICwgdHJ1ZSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb25MaXRlICAsICIyMTUiKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uTGl0ZSAgICwgdG9CeXRlcygiMjE2IikpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRHcm91cEV4dGVuc2lvbkxpdGUsCisgICAgICBSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbl9saXRlLm5ld0J1aWxkZXIoKS5zZXRBKDIxNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSwKKyAgICAgIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMjE4KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZSwKKyAgICAgIEZvcmVpZ25NZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkuc2V0QygyMTkpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbkxpdGUsCisgICAgICBJbXBvcnRNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkuc2V0RCgyMjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb25MaXRlLAorICAgICAgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYigyMjcpLmJ1aWxkKCkpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRFbnVtLkJBUik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUsIEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFSKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydEVudW1FeHRlbnNpb25MaXRlLCBJbXBvcnRFbnVtTGl0ZS5JTVBPUlRfTElURV9CQVIpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUsICIyMjQiKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZENvcmRFeHRlbnNpb25MaXRlLCAiMjI1Iik7CisKKyAgICAvLyBBZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQuCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRJbnQzMkV4dGVuc2lvbkxpdGUgICAsIDMwMSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbkxpdGUgICAsIDMwMkwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uTGl0ZSAgLCAzMDMpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCAzMDRMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbkxpdGUgICwgMzA1KTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbkxpdGUgICwgMzA2TCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDMyRXh0ZW5zaW9uTGl0ZSAsIDMwNyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uTGl0ZSAsIDMwOEwpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb25MaXRlLCAzMDkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCAzMTBMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICwgMzExRik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWREb3VibGVFeHRlbnNpb25MaXRlICAsIDMxMkQpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCBmYWxzZSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb25MaXRlICAsICIzMTUiKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uTGl0ZSAgICwgdG9CeXRlcygiMzE2IikpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRHcm91cEV4dGVuc2lvbkxpdGUsCisgICAgICBSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbl9saXRlLm5ld0J1aWxkZXIoKS5zZXRBKDMxNykuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSwKKyAgICAgIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoMzE4KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZSwKKyAgICAgIEZvcmVpZ25NZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkuc2V0QygzMTkpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbkxpdGUsCisgICAgICBJbXBvcnRNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkuc2V0RCgzMjApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb25MaXRlLAorICAgICAgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKS5zZXRCYigzMjcpLmJ1aWxkKCkpOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRFbnVtLkJBWik7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUsIEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFaKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydEVudW1FeHRlbnNpb25MaXRlLCBJbXBvcnRFbnVtTGl0ZS5JTVBPUlRfTElURV9CQVopOworCisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUsICIzMjQiKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihyZXBlYXRlZENvcmRFeHRlbnNpb25MaXRlLCAiMzI1Iik7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEludDMyRXh0ZW5zaW9uTGl0ZSAgICwgNDAxKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb25MaXRlICAgLCA0MDJMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0VWludDMyRXh0ZW5zaW9uTGl0ZSAgLCA0MDMpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRVaW50NjRFeHRlbnNpb25MaXRlICAsIDQwNEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRTaW50MzJFeHRlbnNpb25MaXRlICAsIDQwNSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbkxpdGUgICwgNDA2TCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEZpeGVkMzJFeHRlbnNpb25MaXRlICwgNDA3KTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbkxpdGUgLCA0MDhMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb25MaXRlLCA0MDkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQ2NEV4dGVuc2lvbkxpdGUsIDQxMEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDQxMUYpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHREb3VibGVFeHRlbnNpb25MaXRlICAsIDQxMkQpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRCb29sRXh0ZW5zaW9uTGl0ZSAgICAsIGZhbHNlKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uTGl0ZSAgLCAiNDE1Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uTGl0ZSAgICwgdG9CeXRlcygiNDE2IikpOworCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb25MaXRlLCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uRk9PKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihkZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb25MaXRlLCBGb3JlaWduRW51bUxpdGUuRk9SRUlHTl9MSVRFX0ZPTyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdEltcG9ydEVudW1FeHRlbnNpb25MaXRlLCBJbXBvcnRFbnVtTGl0ZS5JTVBPUlRfTElURV9GT08pOworCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oZGVmYXVsdFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZSwgIjQyNCIpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKGRlZmF1bHRDb3JkRXh0ZW5zaW9uTGl0ZSwgIjQyNSIpOworCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob25lb2ZVaW50MzJFeHRlbnNpb25MaXRlLCA2MDEpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKG9uZW9mTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUsCisgICAgICBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDYwMikuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob25lb2ZTdHJpbmdFeHRlbnNpb25MaXRlLCAiNjAzIik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ob25lb2ZCeXRlc0V4dGVuc2lvbkxpdGUsIHRvQnl0ZXMoIjYwNCIpKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvKioKKyAgICogTW9kaWZ5IHRoZSByZXBlYXRlZCBleHRlbnNpb25zIG9mIHtAY29kZSBtZXNzYWdlfSB0byBjb250YWluIHRoZSB2YWx1ZXMKKyAgICogZXhwZWN0ZWQgYnkge0Bjb2RlIGFzc2VydFJlcGVhdGVkRXh0ZW5zaW9uc01vZGlmaWVkKCl9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1vZGlmeVJlcGVhdGVkRXh0ZW5zaW9ucygKKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZS5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSAgICwgMSwgNTAxKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEludDY0RXh0ZW5zaW9uTGl0ZSAgICwgMSwgNTAyTCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb25MaXRlICAsIDEsIDUwMyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50NjRFeHRlbnNpb25MaXRlICAsIDEsIDUwNEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uTGl0ZSAgLCAxLCA1MDUpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgLCAxLCA1MDZMKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb25MaXRlICwgMSwgNTA3KTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb25MaXRlICwgMSwgNTA4TCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbkxpdGUsIDEsIDUwOSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbkxpdGUsIDEsIDUxMEwpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkRmxvYXRFeHRlbnNpb25MaXRlICAgLCAxLCA1MTFGKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZERvdWJsZUV4dGVuc2lvbkxpdGUgICwgMSwgNTEyRCk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRCb29sRXh0ZW5zaW9uTGl0ZSAgICAsIDEsIHRydWUpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uTGl0ZSAgLCAxLCAiNTE1Iik7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbkxpdGUgICAsIDEsIHRvQnl0ZXMoIjUxNiIpKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkR3JvdXBFeHRlbnNpb25MaXRlLCAxLAorICAgICAgUmVwZWF0ZWRHcm91cF9leHRlbnNpb25fbGl0ZS5uZXdCdWlsZGVyKCkuc2V0QSg1MTcpLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUsIDEsCisgICAgICBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDUxOCkuYnVpbGQoKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbkxpdGUsIDEsCisgICAgICBGb3JlaWduTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpLnNldEMoNTE5KS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlLCAxLAorICAgICAgSW1wb3J0TWVzc2FnZUxpdGUubmV3QnVpbGRlcigpLnNldEQoNTIwKS5idWlsZCgpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSwgMSwKKyAgICAgIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoNTI3KS5idWlsZCgpKTsKKworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbkxpdGUgLCAxLCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uRk9PKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uTGl0ZSwgMSwgRm9yZWlnbkVudW1MaXRlLkZPUkVJR05fTElURV9GT08pOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbkxpdGUgLCAxLCBJbXBvcnRFbnVtTGl0ZS5JTVBPUlRfTElURV9GT08pOworCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUsIDEsICI1MjQiKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihyZXBlYXRlZENvcmRFeHRlbnNpb25MaXRlLCAxLCAiNTI1Iik7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBleHRlbnNpb25zIG9mCisgICAqIHtAY29kZSBtZXNzYWdlfSBhcmUgc2V0IHRvIHRoZSB2YWx1ZXMgYXNzaWduZWQgYnkge0Bjb2RlIHNldEFsbEV4dGVuc2lvbnN9LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEFsbEV4dGVuc2lvbnNTZXQoCisgICAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGVPckJ1aWxkZXIgbWVzc2FnZSkgeworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbnQ2NEV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFVpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsVWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxTaW50MzJFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFNpbnQ2NEV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxGaXhlZDY0RXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxGbG9hdEV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbERvdWJsZUV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxTdHJpbmdFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEJ5dGVzRXh0ZW5zaW9uTGl0ZSAgICkpOworCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxHcm91cEV4dGVuc2lvbkxpdGUgICAgICAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsR3JvdXBFeHRlbnNpb25MaXRlICAgICAgICAgKS5oYXNBKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUgKS5oYXNCYigpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZSkuaGFzQygpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlICkuaGFzRCgpKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb25MaXRlICkpOworCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbENvcmRFeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTAxICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMDMgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxVaW50MzJFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTA0TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsVWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFNpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMDZMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTaW50NjRFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTA3ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDEwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkNjRFeHRlbnNpb25MaXRlICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMDkgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQzMkV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTEwTCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDExMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMTJEICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxEb3VibGVFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodHJ1ZSAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsQm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIxMTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFN0cmluZ0V4dGVuc2lvbkxpdGUgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSh0b0J5dGVzKCIxMTYiKSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxCeXRlc0V4dGVuc2lvbkxpdGUpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMTcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsR3JvdXBFeHRlbnNpb25MaXRlICAgICAgICAgKS5nZXRBKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgxMTgsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUgKS5nZXRCYigpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTE5LCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZSkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTIwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlICkuZ2V0RCgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTI2LCBtZXNzYWdlLmdldEV4dGVuc2lvbigKKyAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSkuZ2V0RSgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMTI3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSkuZ2V0QmIoKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRFbnVtLkJBWiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoRm9yZWlnbkVudW1MaXRlLkZPUkVJR05fTElURV9CQVosCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uTGl0ZSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShJbXBvcnRFbnVtTGl0ZS5JTVBPUlRfTElURV9CQVosCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjEyNCIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIxMjUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbENvcmRFeHRlbnNpb25MaXRlKSk7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW50NjRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRmxvYXRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkQm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkQnl0ZXNFeHRlbnNpb25MaXRlICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRHcm91cEV4dGVuc2lvbkxpdGUgICAgICAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRMYXp5TWVzc2FnZUV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSAgICApKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZENvcmRFeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjAxICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb25MaXRlICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDY0RXh0ZW5zaW9uTGl0ZSAgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMDMgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA0TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMDZMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50NjRFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA3ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbkxpdGUgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb25MaXRlICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMDkgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbkxpdGUsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjEwTCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTJEICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWREb3VibGVFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodHJ1ZSAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSh0b0J5dGVzKCIyMTYiKSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbkxpdGUsIDApKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkR3JvdXBFeHRlbnNpb25MaXRlICAgICAgICAgLDApLmdldEEoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxOCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAsMCkuZ2V0QmIoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxOSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbkxpdGUsMCkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjIwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlICwwKS5nZXREKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMjcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb25MaXRlICAgLDApLmdldEJiKCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkRW51bS5CQVIsCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb25MaXRlLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoSW1wb3J0RW51bUxpdGUuSU1QT1JUX0xJVEVfQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSwgMCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMjQiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZSwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiMjI1IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uTGl0ZSwgMCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMDJMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbkxpdGUgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbkxpdGUgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMDUgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb25MaXRlICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMDhMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uTGl0ZSAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb25MaXRlLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMxMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZSwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMTFGICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKGZhbHNlLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb25MaXRlICAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiMzE1IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb25MaXRlICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygiMzE2IiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQnl0ZXNFeHRlbnNpb25MaXRlLCAxKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzE3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEdyb3VwRXh0ZW5zaW9uTGl0ZSAgICAgICAgICwxKS5nZXRBKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMTgsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUgLDEpLmdldEJiKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgzMTksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb25MaXRlLDEpLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDMyMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAsMSkuZ2V0RCgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMzI3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAgICwxKS5nZXRCYigpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uQkFaLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bUxpdGUuRk9SRUlHTl9MSVRFX0JBWiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb25MaXRlLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW1MaXRlLklNUE9SVF9MSVRFX0JBWiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbkxpdGUsIDEpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiMzI0IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjMyNSIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQ29yZEV4dGVuc2lvbkxpdGUsIDEpKTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0SW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEludDY0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRVaW50MzJFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0VWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFNpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRTaW50NjRFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEZpeGVkNjRFeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQzMkV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHREb3VibGVFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Qm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFN0cmluZ0V4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRCeXRlc0V4dGVuc2lvbkxpdGUgICApKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEltcG9ydEVudW1FeHRlbnNpb25MaXRlICkpOworCisgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRDb3JkRXh0ZW5zaW9uTGl0ZSkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0SW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwMyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0VWludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0VWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwNkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbkxpdGUgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQwOSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQxMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDQxMkQgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0RG91YmxlRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKGZhbHNlLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Qm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCI0MTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRvQnl0ZXMoIjQxNiIpLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Qnl0ZXNFeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRFbnVtLkZPTywKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoRm9yZWlnbkVudW1MaXRlLkZPUkVJR05fTElURV9GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW1MaXRlLklNUE9SVF9MSVRFX0ZPTywKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCI0MjQiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCI0MjUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Q29yZEV4dGVuc2lvbkxpdGUpKTsKKworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9uZW9mQnl0ZXNFeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygiNjA0IiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9uZW9mQnl0ZXNFeHRlbnNpb25MaXRlKSk7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBleHRlbnNpb25zIG9mCisgICAqIHtAY29kZSBtZXNzYWdlfSBhcmUgY2xlYXJlZCwgYW5kIHRoYXQgZ2V0dGluZyB0aGUgZXh0ZW5zaW9ucyByZXR1cm5zIHRoZWlyCisgICAqIGRlZmF1bHQgdmFsdWVzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEV4dGVuc2lvbnNDbGVhcigKKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZU9yQnVpbGRlciBtZXNzYWdlKSB7CisgICAgLy8gaGFzQmxhaCgpIHNob3VsZCBpbml0aWFsbHkgYmUgZmFsc2UgZm9yIGFsbCBvcHRpb25hbCBmaWVsZHMuCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsSW50NjRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsVWludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsVWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRml4ZWQ2NEV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkMzJFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRmxvYXRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRG91YmxlRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQnl0ZXNFeHRlbnNpb25MaXRlICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxHcm91cEV4dGVuc2lvbkxpdGUgICAgICAgICAgICAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb25MaXRlICAgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb25MaXRlICAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAgICAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsTGF6eU1lc3NhZ2VFeHRlbnNpb25MaXRlICAgICAgICApKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbE5lc3RlZEVudW1FeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb25MaXRlICkpOworCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9wdGlvbmFsQ29yZEV4dGVuc2lvbkxpdGUpKTsKKworICAgIC8vIE9wdGlvbmFsIGZpZWxkcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gemVybyBvciBzb21ldGhpbmcgbGlrZSBpdC4KKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMCAgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsSW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDBMICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEludDY0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxVaW50MzJFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMEwgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsVWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDAgICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFNpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTaW50NjRFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMCAgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDBMICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZpeGVkNjRFeHRlbnNpb25MaXRlICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxTZml4ZWQzMkV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMEwgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsU2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDBGICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwRCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxEb3VibGVFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoZmFsc2UsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsQm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIiICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFN0cmluZ0V4dGVuc2lvbkxpdGUgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShCeXRlU3RyaW5nLkVNUFRZLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEJ5dGVzRXh0ZW5zaW9uTGl0ZSkpOworCisgICAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsR3JvdXBFeHRlbnNpb25MaXRlICAgICAgICAgICAgICApLmhhc0EoKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUgICAgICApLmhhc0JiKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZSAgICAgKS5oYXNDKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlICAgICAgKS5oYXNEKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlKS5oYXNFKCkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAgICAgICAgKS5oYXNCYigpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEdyb3VwRXh0ZW5zaW9uTGl0ZSAgICAgICAgICkuZ2V0QSgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApLmdldEJiKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25NZXNzYWdlRXh0ZW5zaW9uTGl0ZSkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApLmdldEQoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlKS5nZXRFKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAgICkuZ2V0QmIoKSk7CisKKyAgICAvLyBFbnVtcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBlbnVtLgorICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uRk9PLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ob3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoRm9yZWlnbkVudW1MaXRlLkZPUkVJR05fTElURV9GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uTGl0ZSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShJbXBvcnRFbnVtTGl0ZS5JTVBPUlRfTElURV9GT08sCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIiIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb25MaXRlKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihvcHRpb25hbENvcmRFeHRlbnNpb25MaXRlKSk7CisKKyAgICAvLyBSZXBlYXRlZCBmaWVsZHMgYXJlIGVtcHR5LgorICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEludDY0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFVpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZERvdWJsZUV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEJvb2xFeHRlbnNpb25MaXRlICAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uTGl0ZSAgICkpOworCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkR3JvdXBFeHRlbnNpb25MaXRlICAgICAgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW1wb3J0TWVzc2FnZUV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbkxpdGUgICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uTGl0ZSkpOworCisgICAgLy8gaGFzQmxhaCgpIHNob3VsZCBhbHNvIGJlIGZhbHNlIGZvciBhbGwgZGVmYXVsdCBmaWVsZHMuCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRJbnQzMkV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEludDY0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0VWludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRVaW50NjRFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFNpbnQzMkV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRGaXhlZDMyRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEZpeGVkNjRFeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQ2NEV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0RG91YmxlRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRCb29sRXh0ZW5zaW9uTGl0ZSAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdFN0cmluZ0V4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Qnl0ZXNFeHRlbnNpb25MaXRlICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSApKTsKKworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihkZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKGRlZmF1bHRDb3JkRXh0ZW5zaW9uTGl0ZSkpOworCisgICAgLy8gRmllbGRzIHdpdGggZGVmYXVsdHMgaGF2ZSB0aGVpciBkZWZhdWx0IHZhbHVlcyAoZHVoKS4KKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDQxICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEludDMyRXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSggNDJMICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0SW50NjRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA0MyAgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRVaW50MzJFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDQ0TCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFVpbnQ2NEV4dGVuc2lvbkxpdGUgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgtNDUgICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U2ludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA0NkwgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTaW50NjRFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIDQ3ICAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEZpeGVkMzJFeHRlbnNpb25MaXRlICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSggNDhMICAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbkxpdGUgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA0OSAgICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTZml4ZWQzMkV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoLTUwTCAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSggNTEuNUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0RmxvYXRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCA1MmUzRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHREb3VibGVFeHRlbnNpb25MaXRlICApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodHJ1ZSAgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEJvb2xFeHRlbnNpb25MaXRlICAgICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiaGVsbG8iLCBtZXNzYWdlLmdldEV4dGVuc2lvbihkZWZhdWx0U3RyaW5nRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRvQnl0ZXMoIndvcmxkIiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRCeXRlc0V4dGVuc2lvbkxpdGUpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb25MaXRlICkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bUxpdGUuRk9SRUlHTl9MSVRFX0JBUiwKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoSW1wb3J0RW51bUxpdGUuSU1QT1JUX0xJVEVfQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24oZGVmYXVsdEltcG9ydEVudW1FeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoImFiYyIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjEyMyIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKGRlZmF1bHRDb3JkRXh0ZW5zaW9uTGl0ZSkpOworCisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9uZW9mVWludDMyRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvbmVvZk5lc3RlZE1lc3NhZ2VFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKG9uZW9mU3RyaW5nRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihvbmVvZkJ5dGVzRXh0ZW5zaW9uTGl0ZSkpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKgorICAgKiBBc3NlcnQgKHVzaW5nIHtAY29kZSBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0fX0gdGhhdCBhbGwgZXh0ZW5zaW9ucyBvZgorICAgKiB7QGNvZGUgbWVzc2FnZX0gYXJlIHNldCB0byB0aGUgdmFsdWVzIGFzc2lnbmVkIGJ5IHtAY29kZSBzZXRBbGxFeHRlbnNpb25zfQorICAgKiBmb2xsb3dlZCBieSB7QGNvZGUgbW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZU9yQnVpbGRlciBtZXNzYWdlKSB7CisgICAgLy8gTW9kaWZ5UmVwZWF0ZWRGaWVsZHMgb25seSBzZXRzIHRoZSBzZWNvbmQgcmVwZWF0ZWQgZWxlbWVudCBvZiBlYWNoCisgICAgLy8gZmllbGQuICBJbiBhZGRpdGlvbiB0byB2ZXJpZnlpbmcgdGhpcywgd2UgYWxzbyB2ZXJpZnkgdGhhdCB0aGUgZmlyc3QKKyAgICAvLyBlbGVtZW50IGFuZCBzaXplIHdlcmUgKm5vdCogbW9kaWZpZWQuCisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW50MzJFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkSW50NjRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbkxpdGUgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU2ZpeGVkNjRFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRmxvYXRFeHRlbnNpb25MaXRlICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkQm9vbEV4dGVuc2lvbkxpdGUgICAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkU3RyaW5nRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHJlcGVhdGVkQnl0ZXNFeHRlbnNpb25MaXRlICAgKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRHcm91cEV4dGVuc2lvbkxpdGUgICAgICAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbkxpdGUpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRMYXp5TWVzc2FnZUV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSAgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSAgICApKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChyZXBlYXRlZENvcmRFeHRlbnNpb25MaXRlKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjAxICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW50MzJFeHRlbnNpb25MaXRlICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDY0RXh0ZW5zaW9uTGl0ZSAgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMDMgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRVaW50MzJFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA0TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNpbnQzMkV4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMDZMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50NjRFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjA3ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRml4ZWQzMkV4dGVuc2lvbkxpdGUgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkNjRFeHRlbnNpb25MaXRlICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMDkgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTZml4ZWQzMkV4dGVuc2lvbkxpdGUsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjEwTCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZsb2F0RXh0ZW5zaW9uTGl0ZSAgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTJEICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWREb3VibGVFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodHJ1ZSAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMTUiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ0V4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSh0b0J5dGVzKCIyMTYiKSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRCeXRlc0V4dGVuc2lvbkxpdGUsIDApKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMTcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkR3JvdXBFeHRlbnNpb25MaXRlICAgICAgICAgLDApLmdldEEoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxOCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAsMCkuZ2V0QmIoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDIxOSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbkxpdGUsMCkuZ2V0QygpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoMjIwLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEltcG9ydE1lc3NhZ2VFeHRlbnNpb25MaXRlICwwKS5nZXREKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgyMjcsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb25MaXRlICAgLDApLmdldEJiKCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkRW51bS5CQVIsCisgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb25MaXRlLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGb3JlaWduRW51bUV4dGVuc2lvbkxpdGUsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoSW1wb3J0RW51bUxpdGUuSU1QT1JUX0xJVEVfQkFSLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRFbnVtRXh0ZW5zaW9uTGl0ZSwgMCkpOworCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKCIyMjQiLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uTGl0ZSwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiMjI1IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRDb3JkRXh0ZW5zaW9uTGl0ZSwgMCkpOworCisgICAgLy8gQWN0dWFsbHkgdmVyaWZ5IHRoZSBzZWNvbmQgKG1vZGlmaWVkKSBlbGVtZW50cyBub3cuCisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUwMSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEludDMyRXh0ZW5zaW9uTGl0ZSAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDJMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbkxpdGUgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUwNEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbkxpdGUgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDUgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUwNyAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEZpeGVkMzJFeHRlbnNpb25MaXRlICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MDhMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uTGl0ZSAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb25MaXRlLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUxMEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZSwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MTFGICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKHRydWUgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEJvb2xFeHRlbnNpb25MaXRlICAgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiNTE1IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdFeHRlbnNpb25MaXRlICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUodG9CeXRlcygiNTE2IiksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQnl0ZXNFeHRlbnNpb25MaXRlLCAxKSk7CisKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTE3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZEdyb3VwRXh0ZW5zaW9uTGl0ZSAgICAgICAgICwxKS5nZXRBKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MTgsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkxpdGUgLDEpLmdldEJiKCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg1MTksIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb25MaXRlLDEpLmdldEMoKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDUyMCwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAsMSkuZ2V0RCgpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNTI3LCBtZXNzYWdlLmdldEV4dGVuc2lvbihyZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uTGl0ZSAgICwxKS5nZXRCYigpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0uRk9PLAorICAgICAgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShGb3JlaWduRW51bUxpdGUuRk9SRUlHTl9MSVRFX0ZPTywKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkRm9yZWlnbkVudW1FeHRlbnNpb25MaXRlLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEltcG9ydEVudW1MaXRlLklNUE9SVF9MSVRFX0ZPTywKKyAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbkxpdGUsIDEpKTsKKworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSgiNTI0IiwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocmVwZWF0ZWRTdHJpbmdQaWVjZUV4dGVuc2lvbkxpdGUsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoIjUyNSIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHJlcGVhdGVkQ29yZEV4dGVuc2lvbkxpdGUsIDEpKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQYWNrZWRFeHRlbnNpb25zKFRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZS5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRJbnQzMkV4dGVuc2lvbkxpdGUgICAsIDYwMSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkSW50NjRFeHRlbnNpb25MaXRlICAgLCA2MDJMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRVaW50MzJFeHRlbnNpb25MaXRlICAsIDYwMyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCA2MDRMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDYwNSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgLCA2MDZMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGaXhlZDMyRXh0ZW5zaW9uTGl0ZSAsIDYwNyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRml4ZWQ2NEV4dGVuc2lvbkxpdGUgLCA2MDhMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRTZml4ZWQzMkV4dGVuc2lvbkxpdGUsIDYwOSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCA2MTBMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDYxMUYpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZERvdWJsZUV4dGVuc2lvbkxpdGUgICwgNjEyRCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCB0cnVlKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgRm9yZWlnbkVudW1MaXRlLkZPUkVJR05fTElURV9CQVIpOworICAgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRJbnQzMkV4dGVuc2lvbkxpdGUgICAsIDcwMSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkSW50NjRFeHRlbnNpb25MaXRlICAgLCA3MDJMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRVaW50MzJFeHRlbnNpb25MaXRlICAsIDcwMyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCA3MDRMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDcwNSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgLCA3MDZMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGaXhlZDMyRXh0ZW5zaW9uTGl0ZSAsIDcwNyk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRml4ZWQ2NEV4dGVuc2lvbkxpdGUgLCA3MDhMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRTZml4ZWQzMkV4dGVuc2lvbkxpdGUsIDcwOSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCA3MTBMKTsKKyAgICBtZXNzYWdlLmFkZEV4dGVuc2lvbihwYWNrZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDcxMUYpOworICAgIG1lc3NhZ2UuYWRkRXh0ZW5zaW9uKHBhY2tlZERvdWJsZUV4dGVuc2lvbkxpdGUgICwgNzEyRCk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCBmYWxzZSk7CisgICAgbWVzc2FnZS5hZGRFeHRlbnNpb24ocGFja2VkRW51bUV4dGVuc2lvbkxpdGUsIEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFaKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRQYWNrZWRFeHRlbnNpb25zU2V0KFRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSBtZXNzYWdlKSB7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHBhY2tlZEludDMyRXh0ZW5zaW9uTGl0ZSAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRJbnQ2NEV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocGFja2VkVWludDMyRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHBhY2tlZFVpbnQ2NEV4dGVuc2lvbkxpdGUgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRTaW50MzJFeHRlbnNpb25MaXRlICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocGFja2VkU2ludDY0RXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHBhY2tlZEZpeGVkMzJFeHRlbnNpb25MaXRlICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRGaXhlZDY0RXh0ZW5zaW9uTGl0ZSApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocGFja2VkU2ZpeGVkMzJFeHRlbnNpb25MaXRlKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHBhY2tlZFNmaXhlZDY0RXh0ZW5zaW9uTGl0ZSkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRGbG9hdEV4dGVuc2lvbkxpdGUgICApKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uQ291bnQocGFja2VkRG91YmxlRXh0ZW5zaW9uTGl0ZSAgKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldEV4dGVuc2lvbkNvdW50KHBhY2tlZEJvb2xFeHRlbnNpb25MaXRlICAgICkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRFeHRlbnNpb25Db3VudChwYWNrZWRFbnVtRXh0ZW5zaW9uTGl0ZSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MDEgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkSW50MzJFeHRlbnNpb25MaXRlICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRJbnQ2NEV4dGVuc2lvbkxpdGUgICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFVpbnQzMkV4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MDRMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNpbnQ2NEV4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MDcgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkRml4ZWQzMkV4dGVuc2lvbkxpdGUgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRGaXhlZDY0RXh0ZW5zaW9uTGl0ZSAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZSwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg2MTBMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDYxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDApKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNjEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZERvdWJsZUV4dGVuc2lvbkxpdGUgICwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSh0cnVlICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCAwKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFSLAorICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgMCkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MDEgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkSW50MzJFeHRlbnNpb25MaXRlICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcwMkwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRJbnQ2NEV4dGVuc2lvbkxpdGUgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzAzICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFVpbnQzMkV4dGVuc2lvbkxpdGUgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MDRMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkVWludDY0RXh0ZW5zaW9uTGl0ZSAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcwNSAgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRTaW50MzJFeHRlbnNpb25MaXRlICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzA2TCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNpbnQ2NEV4dGVuc2lvbkxpdGUgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MDcgICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkRml4ZWQzMkV4dGVuc2lvbkxpdGUgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcwOEwgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRGaXhlZDY0RXh0ZW5zaW9uTGl0ZSAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzA5ICAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uTGl0ZSwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZSg3MTBMICwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkU2ZpeGVkNjRFeHRlbnNpb25MaXRlLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKDcxMUYgLCBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRGbG9hdEV4dGVuc2lvbkxpdGUgICAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHNFeGFjdFR5cGUoNzEyRCAsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKHBhY2tlZERvdWJsZUV4dGVuc2lvbkxpdGUgICwgMSkpOworICAgIGFzc2VydEVxdWFsc0V4YWN0VHlwZShmYWxzZSwgbWVzc2FnZS5nZXRFeHRlbnNpb24ocGFja2VkQm9vbEV4dGVuc2lvbkxpdGUgICAgLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzRXhhY3RUeXBlKEZvcmVpZ25FbnVtTGl0ZS5GT1JFSUdOX0xJVEVfQkFaLAorICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihwYWNrZWRFbnVtRXh0ZW5zaW9uTGl0ZSwgMSkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBvbmVvZgorICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0T25lb2YoVGVzdE9uZW9mMi5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICBtZXNzYWdlLnNldEZvb0xhenlNZXNzYWdlKAorICAgICAgICBUZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldFF1eEludCgxMDApLmJ1aWxkKCkpOworICAgIG1lc3NhZ2Uuc2V0QmFyU3RyaW5nKCIxMDEiKTsKKyAgICBtZXNzYWdlLnNldEJhekludCgxMDIpOworICAgIG1lc3NhZ2Uuc2V0QmF6U3RyaW5nKCIxMDMiKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRPbmVvZlNldChUZXN0T25lb2YyIG1lc3NhZ2UpIHsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb0xhenlNZXNzYWdlICAgICAgICAgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuZ2V0Rm9vTGF6eU1lc3NhZ2UoKS5oYXNRdXhJbnQoKSk7CisKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0JhclN0cmluZygpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0JhekludCAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0JhelN0cmluZygpKTsKKworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTAwICAsIG1lc3NhZ2UuZ2V0Rm9vTGF6eU1lc3NhZ2UoKS5nZXRRdXhJbnQoKSk7CisgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMTAxIiwgbWVzc2FnZS5nZXRCYXJTdHJpbmcgICAgICAgICAgICAgICAgICgpKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwMiAgLCBtZXNzYWdlLmdldEJhekludCAgICAgICAgICAgICAgICAgICAgKCkpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjEwMyIsIG1lc3NhZ2UuZ2V0QmF6U3RyaW5nICAgICAgICAgICAgICAgICAoKSk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0QXRNb3N0T25lRmllbGRTZXRPbmVvZihUZXN0T25lb2YyIG1lc3NhZ2UpIHsKKyAgICBpbnQgY291bnQgPSAwOworICAgIGlmIChtZXNzYWdlLmhhc0Zvb0ludCgpKSB7ICsrY291bnQ7IH0KKyAgICBpZiAobWVzc2FnZS5oYXNGb29TdHJpbmcoKSkgeyArK2NvdW50OyB9CisgICAgaWYgKG1lc3NhZ2UuaGFzRm9vQ29yZCgpKSB7ICsrY291bnQ7IH0KKyAgICBpZiAobWVzc2FnZS5oYXNGb29TdHJpbmdQaWVjZSgpKSB7ICsrY291bnQ7IH0KKyAgICBpZiAobWVzc2FnZS5oYXNGb29CeXRlcygpKSB7ICsrY291bnQ7IH0KKyAgICBpZiAobWVzc2FnZS5oYXNGb29FbnVtKCkpIHsgKytjb3VudDsgfQorICAgIGlmIChtZXNzYWdlLmhhc0Zvb01lc3NhZ2UoKSkgeyArK2NvdW50OyB9CisgICAgaWYgKG1lc3NhZ2UuaGFzRm9vR3JvdXAoKSkgeyArK2NvdW50OyB9CisgICAgaWYgKG1lc3NhZ2UuaGFzRm9vTGF6eU1lc3NhZ2UoKSkgeyArK2NvdW50OyB9CisgICAgQXNzZXJ0LmFzc2VydFRydWUoY291bnQgPD0gMSk7CisKKyAgICBjb3VudCA9IDA7CisgICAgaWYgKG1lc3NhZ2UuaGFzQmFySW50KCkpIHsgKytjb3VudDsgfQorICAgIGlmIChtZXNzYWdlLmhhc0JhclN0cmluZygpKSB7ICsrY291bnQ7IH0KKyAgICBpZiAobWVzc2FnZS5oYXNCYXJDb3JkKCkpIHsgKytjb3VudDsgfQorICAgIGlmIChtZXNzYWdlLmhhc0JhclN0cmluZ1BpZWNlKCkpIHsgKytjb3VudDsgfQorICAgIGlmIChtZXNzYWdlLmhhc0JhckJ5dGVzKCkpIHsgKytjb3VudDsgfQorICAgIGlmIChtZXNzYWdlLmhhc0JhckVudW0oKSkgeyArK2NvdW50OyB9CisgICAgQXNzZXJ0LmFzc2VydFRydWUoY291bnQgPD0gMSk7CisKKyAgICBzd2l0Y2ggKG1lc3NhZ2UuZ2V0Rm9vQ2FzZSgpKSB7CisgICAgICBjYXNlIEZPT19JTlQ6CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vSW50KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRk9PX1NUUklORzoKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGb29TdHJpbmcoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGT09fQ09SRDoKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGb29Db3JkKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRk9PX0JZVEVTOgorICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb0J5dGVzKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRk9PX0VOVU06CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vRW51bSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZPT19NRVNTQUdFOgorICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb01lc3NhZ2UoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGT09HUk9VUDoKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGb29Hcm91cCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZPT19MQVpZX01FU1NBR0U6CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRm9vTGF6eU1lc3NhZ2UoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGT09fTk9UX1NFVDoKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogUGVyZm9ybXMgdGhlIHNhbWUgdGhpbmdzIHRoYXQgdGhlIG1ldGhvZHMgb2Yge0Bjb2RlIFRlc3RVdGlsfSBkbywgYnV0CisgICAqIHZpYSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UuICBUaGlzIGlzIGl0cyBvd24gY2xhc3MgYmVjYXVzZSBpdCBuZWVkcworICAgKiB0byBrbm93IHdoYXQgZGVzY3JpcHRvciB0byB1c2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlZmxlY3Rpb25UZXN0ZXIgeworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBiYXNlRGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIGZpbmFsIEV4dGVuc2lvblJlZ2lzdHJ5IGV4dGVuc2lvblJlZ2lzdHJ5OworCisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvciBmaWxlOworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IgaW1wb3J0RmlsZTsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yIHB1YmxpY0ltcG9ydEZpbGU7CisKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkRlc2NyaXB0b3Igb3B0aW9uYWxHcm91cDsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgcmVwZWF0ZWRHcm91cDsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgbmVzdGVkTWVzc2FnZTsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZm9yZWlnbk1lc3NhZ2U7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGltcG9ydE1lc3NhZ2U7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIHB1YmxpY0ltcG9ydE1lc3NhZ2U7CisKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBncm91cEE7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgcmVwZWF0ZWRHcm91cEE7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgbmVzdGVkQjsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmb3JlaWduQzsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBpbXBvcnREOworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGltcG9ydEU7CisKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yIG5lc3RlZEVudW07CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvciBmb3JlaWduRW51bTsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yIGltcG9ydEVudW07CisKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgbmVzdGVkRm9vOworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBuZXN0ZWRCYXI7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIG5lc3RlZEJhejsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZm9yZWlnbkZvbzsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZm9yZWlnbkJhcjsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZm9yZWlnbkJhejsKKyAgICBwcml2YXRlIGZpbmFsIERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgaW1wb3J0Rm9vOworICAgIHByaXZhdGUgZmluYWwgRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBpbXBvcnRCYXI7CisgICAgcHJpdmF0ZSBmaW5hbCBEZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGltcG9ydEJhejsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIHtAY29kZSBSZWZsZWN0aW9uVGVzdGVyfSB0aGF0IHdpbGwgZXhwZWN0IG1lc3NhZ2VzIHVzaW5nCisgICAgICogdGhlIGdpdmVuIGRlc2NyaXB0b3IuCisgICAgICoKKyAgICAgKiBOb3JtYWxseSB7QGNvZGUgYmFzZURlc2NyaXB0b3J9IHNob3VsZCBiZSBhIGRlc2NyaXB0b3IgZm9yIHRoZSB0eXBlCisgICAgICoge0Bjb2RlIFRlc3RBbGxUeXBlc30sIGRlZmluZWQgaW4KKyAgICAgKiB7QGNvZGUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvfS4gIEhvd2V2ZXIsIGlmCisgICAgICoge0Bjb2RlIGV4dGVuc2lvblJlZ2lzdHJ5fSBpcyBub24tbnVsbCwgdGhlbiB7QGNvZGUgYmFzZURlc2NyaXB0b3J9IHNob3VsZAorICAgICAqIGJlIGZvciB7QGNvZGUgVGVzdEFsbEV4dGVuc2lvbnN9IGluc3RlYWQsIGFuZCBpbnN0ZWFkIG9mIHJlYWRpbmcgYW5kCisgICAgICogd3JpdGluZyBub3JtYWwgZmllbGRzLCB0aGUgdGVzdGVyIHdpbGwgcmVhZCBhbmQgd3JpdGUgZXh0ZW5zaW9ucy4KKyAgICAgKiBBbGwgb2Yge0Bjb2RlIFRlc3RBbGxFeHRlbnNpb25zfScgZXh0ZW5zaW9ucyBtdXN0IGJlIHJlZ2lzdGVyZWQgaW4gdGhlCisgICAgICogcmVnaXN0cnkuCisgICAgICovCisgICAgcHVibGljIFJlZmxlY3Rpb25UZXN0ZXIoRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBiYXNlRGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSkgeworICAgICAgdGhpcy5iYXNlRGVzY3JpcHRvciA9IGJhc2VEZXNjcmlwdG9yOworICAgICAgdGhpcy5leHRlbnNpb25SZWdpc3RyeSA9IGV4dGVuc2lvblJlZ2lzdHJ5OworCisgICAgICB0aGlzLmZpbGUgPSBiYXNlRGVzY3JpcHRvci5nZXRGaWxlKCk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEsIGZpbGUuZ2V0RGVwZW5kZW5jaWVzKCkuc2l6ZSgpKTsKKyAgICAgIHRoaXMuaW1wb3J0RmlsZSA9IGZpbGUuZ2V0RGVwZW5kZW5jaWVzKCkuZ2V0KDApOworICAgICAgdGhpcy5wdWJsaWNJbXBvcnRGaWxlID0gaW1wb3J0RmlsZS5nZXREZXBlbmRlbmNpZXMoKS5nZXQoMCk7CisKKyAgICAgIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgdGVzdEFsbFR5cGVzOworICAgICAgaWYgKGJhc2VEZXNjcmlwdG9yLmdldE5hbWUoKSA9PSAiVGVzdEFsbFR5cGVzIikgeworICAgICAgICB0ZXN0QWxsVHlwZXMgPSBiYXNlRGVzY3JpcHRvcjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRlc3RBbGxUeXBlcyA9IGZpbGUuZmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJUZXN0QWxsVHlwZXMiKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwodGVzdEFsbFR5cGVzKTsKKyAgICAgIH0KKworICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKKyAgICAgICAgLy8gVXNlIHRlc3RBbGxUeXBlcywgcmF0aGVyIHRoYW4gYmFzZURlc2NyaXB0b3IsIHRvIGFsbG93CisgICAgICAgIC8vIGluaXRpYWxpemF0aW9uIHVzaW5nIFRlc3RQYWNrZWRUeXBlcyBkZXNjcmlwdG9ycy4gVGhlc2Ugb2JqZWN0cworICAgICAgICAvLyB3b24ndCBiZSB1c2VkIGJ5IHRoZSBtZXRob2RzIGZvciBwYWNrZWQgZmllbGRzLgorICAgICAgICB0aGlzLm9wdGlvbmFsR3JvdXAgPQorICAgICAgICAgIHRlc3RBbGxUeXBlcy5maW5kTmVzdGVkVHlwZUJ5TmFtZSgiT3B0aW9uYWxHcm91cCIpOworICAgICAgICB0aGlzLnJlcGVhdGVkR3JvdXAgPQorICAgICAgICAgIHRlc3RBbGxUeXBlcy5maW5kTmVzdGVkVHlwZUJ5TmFtZSgiUmVwZWF0ZWRHcm91cCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhpcy5vcHRpb25hbEdyb3VwID0KKyAgICAgICAgICBmaWxlLmZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiT3B0aW9uYWxHcm91cF9leHRlbnNpb24iKTsKKyAgICAgICAgdGhpcy5yZXBlYXRlZEdyb3VwID0KKyAgICAgICAgICBmaWxlLmZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiUmVwZWF0ZWRHcm91cF9leHRlbnNpb24iKTsKKyAgICAgIH0KKyAgICAgIHRoaXMubmVzdGVkTWVzc2FnZSA9IHRlc3RBbGxUeXBlcy5maW5kTmVzdGVkVHlwZUJ5TmFtZSgiTmVzdGVkTWVzc2FnZSIpOworICAgICAgdGhpcy5mb3JlaWduTWVzc2FnZSA9IGZpbGUuZmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJGb3JlaWduTWVzc2FnZSIpOworICAgICAgdGhpcy5pbXBvcnRNZXNzYWdlID0gaW1wb3J0RmlsZS5maW5kTWVzc2FnZVR5cGVCeU5hbWUoIkltcG9ydE1lc3NhZ2UiKTsKKyAgICAgIHRoaXMucHVibGljSW1wb3J0TWVzc2FnZSA9IHB1YmxpY0ltcG9ydEZpbGUuZmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAgICJQdWJsaWNJbXBvcnRNZXNzYWdlIik7CisKKyAgICAgIHRoaXMubmVzdGVkRW51bSA9IHRlc3RBbGxUeXBlcy5maW5kRW51bVR5cGVCeU5hbWUoIk5lc3RlZEVudW0iKTsKKyAgICAgIHRoaXMuZm9yZWlnbkVudW0gPSBmaWxlLmZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9yZWlnbkVudW0iKTsKKyAgICAgIHRoaXMuaW1wb3J0RW51bSA9IGltcG9ydEZpbGUuZmluZEVudW1UeXBlQnlOYW1lKCJJbXBvcnRFbnVtIik7CisKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKG9wdGlvbmFsR3JvdXAgKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKHJlcGVhdGVkR3JvdXAgKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKG5lc3RlZE1lc3NhZ2UgKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKGZvcmVpZ25NZXNzYWdlKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKGltcG9ydE1lc3NhZ2UgKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKG5lc3RlZEVudW0gICAgKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKGZvcmVpZ25FbnVtICAgKTsKKyAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKGltcG9ydEVudW0gICAgKTsKKworICAgICAgdGhpcy5uZXN0ZWRCICA9IG5lc3RlZE1lc3NhZ2UgLmZpbmRGaWVsZEJ5TmFtZSgiYmIiKTsKKyAgICAgIHRoaXMuZm9yZWlnbkMgPSBmb3JlaWduTWVzc2FnZS5maW5kRmllbGRCeU5hbWUoImMiKTsKKyAgICAgIHRoaXMuaW1wb3J0RCAgPSBpbXBvcnRNZXNzYWdlIC5maW5kRmllbGRCeU5hbWUoImQiKTsKKyAgICAgIHRoaXMuaW1wb3J0RSAgPSBwdWJsaWNJbXBvcnRNZXNzYWdlLmZpbmRGaWVsZEJ5TmFtZSgiZSIpOworICAgICAgdGhpcy5uZXN0ZWRGb28gPSBuZXN0ZWRFbnVtLmZpbmRWYWx1ZUJ5TmFtZSgiRk9PIik7CisgICAgICB0aGlzLm5lc3RlZEJhciA9IG5lc3RlZEVudW0uZmluZFZhbHVlQnlOYW1lKCJCQVIiKTsKKyAgICAgIHRoaXMubmVzdGVkQmF6ID0gbmVzdGVkRW51bS5maW5kVmFsdWVCeU5hbWUoIkJBWiIpOworICAgICAgdGhpcy5mb3JlaWduRm9vID0gZm9yZWlnbkVudW0uZmluZFZhbHVlQnlOYW1lKCJGT1JFSUdOX0ZPTyIpOworICAgICAgdGhpcy5mb3JlaWduQmFyID0gZm9yZWlnbkVudW0uZmluZFZhbHVlQnlOYW1lKCJGT1JFSUdOX0JBUiIpOworICAgICAgdGhpcy5mb3JlaWduQmF6ID0gZm9yZWlnbkVudW0uZmluZFZhbHVlQnlOYW1lKCJGT1JFSUdOX0JBWiIpOworICAgICAgdGhpcy5pbXBvcnRGb28gPSBpbXBvcnRFbnVtLmZpbmRWYWx1ZUJ5TmFtZSgiSU1QT1JUX0ZPTyIpOworICAgICAgdGhpcy5pbXBvcnRCYXIgPSBpbXBvcnRFbnVtLmZpbmRWYWx1ZUJ5TmFtZSgiSU1QT1JUX0JBUiIpOworICAgICAgdGhpcy5pbXBvcnRCYXogPSBpbXBvcnRFbnVtLmZpbmRWYWx1ZUJ5TmFtZSgiSU1QT1JUX0JBWiIpOworCisgICAgICB0aGlzLmdyb3VwQSA9IG9wdGlvbmFsR3JvdXAuZmluZEZpZWxkQnlOYW1lKCJhIik7CisgICAgICB0aGlzLnJlcGVhdGVkR3JvdXBBID0gcmVwZWF0ZWRHcm91cC5maW5kRmllbGRCeU5hbWUoImEiKTsKKworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZ3JvdXBBICAgICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwocmVwZWF0ZWRHcm91cEEpOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmVzdGVkQiAgICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZm9yZWlnbkMgICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoaW1wb3J0RCAgICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoaW1wb3J0RSAgICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmVzdGVkRm9vICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmVzdGVkQmFyICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmVzdGVkQmF6ICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZm9yZWlnbkZvbyAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZm9yZWlnbkJhciAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZm9yZWlnbkJheiAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoaW1wb3J0Rm9vICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoaW1wb3J0QmFyICAgICApOworICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoaW1wb3J0QmF6ICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNob3J0aGFuZCB0byBnZXQgYSBGaWVsZERlc2NyaXB0b3IgZm9yIGEgZmllbGQgb2YgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmKFN0cmluZyBuYW1lKSB7CisgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgcmVzdWx0OworICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKKyAgICAgICAgcmVzdWx0ID0gYmFzZURlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKG5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0ID0gZmlsZS5maW5kRXh0ZW5zaW9uQnlOYW1lKG5hbWUgKyAiX2V4dGVuc2lvbiIpOworICAgICAgfQorICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwocmVzdWx0KTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMge0Bjb2RlIHBhcmVudC5uZXdCdWlsZGVyRm9yRmllbGQoKX0gb3IgdXNlcyB0aGUKKyAgICAgKiB7QGNvZGUgRXh0ZW5zaW9uUmVnaXN0cnl9IHRvIGZpbmQgYW4gYXBwcm9wcmlhdGUgYnVpbGRlciwgZGVwZW5kaW5nCisgICAgICogb24gd2hhdCB0eXBlIGlzIGJlaW5nIHRlc3RlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1lc3NhZ2UuQnVpbGRlciBuZXdCdWlsZGVyRm9yRmllbGQoCisgICAgICAgIE1lc3NhZ2UuQnVpbGRlciBwYXJlbnQsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgeworICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIHBhcmVudC5uZXdCdWlsZGVyRm9yRmllbGQoZmllbGQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnkuRXh0ZW5zaW9uSW5mbyBleHRlbnNpb24gPQorICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5LmZpbmRJbW11dGFibGVFeHRlbnNpb25CeU51bWJlcigKKyAgICAgICAgICAgICAgZmllbGQuZ2V0Q29udGFpbmluZ1R5cGUoKSwgZmllbGQuZ2V0TnVtYmVyKCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChleHRlbnNpb24pOworICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChleHRlbnNpb24uZGVmYXVsdEluc3RhbmNlKTsKKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbi5kZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBTZXQgZXZlcnkgZmllbGQgb2Yge0Bjb2RlIG1lc3NhZ2V9IHRvIHRoZSB2YWx1ZXMgZXhwZWN0ZWQgYnkKKyAgICAgKiB7QGNvZGUgYXNzZXJ0QWxsRmllbGRzU2V0KCl9LCB1c2luZyB0aGUge0BsaW5rIE1lc3NhZ2UuQnVpbGRlcn0KKyAgICAgKiByZWZsZWN0aW9uIGludGVyZmFjZS4KKyAgICAgKi8KKyAgICB2b2lkIHNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZS5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfaW50MzIiICAgKSwgMTAxICk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX2ludDY0IiAgICksIDEwMkwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJvcHRpb25hbF91aW50MzIiICApLCAxMDMgKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfdWludDY0IiAgKSwgMTA0TCk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX3NpbnQzMiIgICksIDEwNSApOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJvcHRpb25hbF9zaW50NjQiICApLCAxMDZMKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfZml4ZWQzMiIgKSwgMTA3ICk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX2ZpeGVkNjQiICksIDEwOEwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJvcHRpb25hbF9zZml4ZWQzMiIpLCAxMDkgKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfc2ZpeGVkNjQiKSwgMTEwTCk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX2Zsb2F0IiAgICksIDExMUYpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJvcHRpb25hbF9kb3VibGUiICApLCAxMTJEKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfYm9vbCIgICAgKSwgdHJ1ZSk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX3N0cmluZyIgICksICIxMTUiKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfYnl0ZXMiICAgKSwgdG9CeXRlcygiMTE2IikpOworCisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsZ3JvdXAiKSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoIm9wdGlvbmFsZ3JvdXAiKSkKKyAgICAgICAgICAgICAgIC5zZXRGaWVsZChncm91cEEsIDExNykuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiksCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKG5lc3RlZEIsIDExOCkuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpLAorICAgICAgICBuZXdCdWlsZGVyRm9yRmllbGQobWVzc2FnZSwgZigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQoZm9yZWlnbkMsIDExOSkuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIiksCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKGltcG9ydEQsIDEyMCkuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpLAorICAgICAgICBuZXdCdWlsZGVyRm9yRmllbGQobWVzc2FnZSwgZigib3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQoaW1wb3J0RSwgMTI2KS5idWlsZCgpKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfbGF6eV9tZXNzYWdlIiksCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJvcHRpb25hbF9sYXp5X21lc3NhZ2UiKSkKKyAgICAgICAgICAgICAgIC5zZXRGaWVsZChuZXN0ZWRCLCAxMjcpLmJ1aWxkKCkpOworCisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApLCAgbmVzdGVkQmF6KTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfZm9yZWlnbl9lbnVtIiksIGZvcmVpZ25CYXopOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJvcHRpb25hbF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydEJheik7CisKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIiApLCAiMTI0Iik7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9wdGlvbmFsX2NvcmQiICksICIxMjUiKTsKKworICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDMyIiAgICksIDIwMSApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDY0IiAgICksIDIwMkwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3VpbnQzMiIgICksIDIwMyApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDIwNEwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NpbnQzMiIgICksIDIwNSApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NpbnQ2NCIgICksIDIwNkwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDIwNyApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDIwOEwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NmaXhlZDMyIiksIDIwOSApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDIxMEwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDIxMUYpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2RvdWJsZSIgICksIDIxMkQpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Jvb2wiICAgICksIHRydWUpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3N0cmluZyIgICksICIyMTUiKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9ieXRlcyIgICApLCB0b0J5dGVzKCIyMTYiKSk7CisKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZGdyb3VwIiksCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJyZXBlYXRlZGdyb3VwIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQocmVwZWF0ZWRHcm91cEEsIDIxNykuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQobmVzdGVkQiwgMjE4KS5idWlsZCgpKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKGZvcmVpZ25DLCAyMTkpLmJ1aWxkKCkpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiksCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKGltcG9ydEQsIDIyMCkuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbGF6eV9tZXNzYWdlIiksCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSkKKyAgICAgICAgICAgICAgIC5zZXRGaWVsZChuZXN0ZWRCLCAyMjcpLmJ1aWxkKCkpOworCisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX2VudW0iICksICBuZXN0ZWRCYXIpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIpLCBmb3JlaWduQmFyKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydEJhcik7CisKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiICksICIyMjQiKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9jb3JkIiApLCAiMjI1Iik7CisKKyAgICAgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbnQzMiIgICApLCAzMDEgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAzMDJMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF91aW50MzIiICApLCAzMDMgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF91aW50NjQiICApLCAzMDRMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zaW50MzIiICApLCAzMDUgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zaW50NjQiICApLCAzMDZMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9maXhlZDMyIiApLCAzMDcgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9maXhlZDY0IiApLCAzMDhMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zZml4ZWQzMiIpLCAzMDkgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zZml4ZWQ2NCIpLCAzMTBMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mbG9hdCIgICApLCAzMTFGKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9kb3VibGUiICApLCAzMTJEKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9ib29sIiAgICApLCBmYWxzZSk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc3RyaW5nIiAgKSwgIjMxNSIpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2J5dGVzIiAgICksIHRvQnl0ZXMoIjMxNiIpKTsKKworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkZ3JvdXAiKSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkZ3JvdXAiKSkKKyAgICAgICAgICAgICAgIC5zZXRGaWVsZChyZXBlYXRlZEdyb3VwQSwgMzE3KS5idWlsZCgpKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpLAorICAgICAgICBuZXdCdWlsZGVyRm9yRmllbGQobWVzc2FnZSwgZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSkKKyAgICAgICAgICAgICAgIC5zZXRGaWVsZChuZXN0ZWRCLCAzMTgpLmJ1aWxkKCkpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpLAorICAgICAgICBuZXdCdWlsZGVyRm9yRmllbGQobWVzc2FnZSwgZigicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQoZm9yZWlnbkMsIDMxOSkuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQoaW1wb3J0RCwgMzIwKS5idWlsZCgpKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkX2xhenlfbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKG5lc3RlZEIsIDMyNykuYnVpbGQoKSk7CisKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwgIG5lc3RlZEJheik7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiksIGZvcmVpZ25CYXopOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ltcG9ydF9lbnVtIiApLCAgaW1wb3J0QmF6KTsKKworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIgKSwgIjMyNCIpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2NvcmQiICksICIzMjUiKTsKKworICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2ludDMyIiAgICksIDQwMSApOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2ludDY0IiAgICksIDQwMkwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X3VpbnQzMiIgICksIDQwMyApOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X3VpbnQ2NCIgICksIDQwNEwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X3NpbnQzMiIgICksIDQwNSApOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X3NpbnQ2NCIgICksIDQwNkwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2ZpeGVkMzIiICksIDQwNyApOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2ZpeGVkNjQiICksIDQwOEwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X3NmaXhlZDMyIiksIDQwOSApOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X3NmaXhlZDY0IiksIDQxMEwpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2Zsb2F0IiAgICksIDQxMUYpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2RvdWJsZSIgICksIDQxMkQpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2Jvb2wiICAgICksIGZhbHNlKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigiZGVmYXVsdF9zdHJpbmciICApLCAiNDE1Iik7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoImRlZmF1bHRfYnl0ZXMiICAgKSwgdG9CeXRlcygiNDE2IikpOworCisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoImRlZmF1bHRfbmVzdGVkX2VudW0iICksICBuZXN0ZWRGb28pOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpLCBmb3JlaWduRm9vKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigiZGVmYXVsdF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydEZvbyk7CisKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigiZGVmYXVsdF9zdHJpbmdfcGllY2UiICksICI0MjQiKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigiZGVmYXVsdF9jb3JkIiApLCAiNDI1Iik7CisKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib25lb2ZfdWludDMyIiApLCA2MDEpOworICAgICAgbWVzc2FnZS5zZXRGaWVsZChmKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpLAorICAgICAgICBuZXdCdWlsZGVyRm9yRmllbGQobWVzc2FnZSwgZigib25lb2ZfbmVzdGVkX21lc3NhZ2UiKSkKKyAgICAgICAgICAuc2V0RmllbGQobmVzdGVkQiwgNjAyKS5idWlsZCgpKTsKKyAgICAgIG1lc3NhZ2Uuc2V0RmllbGQoZigib25lb2Zfc3RyaW5nIiApLCAiNjAzIik7CisgICAgICBtZXNzYWdlLnNldEZpZWxkKGYoIm9uZW9mX2J5dGVzIiApLCB0b0J5dGVzKCI2MDQiKSk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogTW9kaWZ5IHRoZSByZXBlYXRlZCBmaWVsZHMgb2Yge0Bjb2RlIG1lc3NhZ2V9IHRvIGNvbnRhaW4gdGhlIHZhbHVlcworICAgICAqIGV4cGVjdGVkIGJ5IHtAY29kZSBhc3NlcnRSZXBlYXRlZEZpZWxkc01vZGlmaWVkKCl9LCB1c2luZyB0aGUKKyAgICAgKiB7QGxpbmsgTWVzc2FnZS5CdWlsZGVyfSByZWZsZWN0aW9uIGludGVyZmFjZS4KKyAgICAgKi8KKyAgICB2b2lkIG1vZGlmeVJlcGVhdGVkRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlLkJ1aWxkZXIgbWVzc2FnZSkgeworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDMyIiAgICksIDEsIDUwMSApOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDY0IiAgICksIDEsIDUwMkwpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3VpbnQzMiIgICksIDEsIDUwMyApOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDEsIDUwNEwpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NpbnQzMiIgICksIDEsIDUwNSApOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NpbnQ2NCIgICksIDEsIDUwNkwpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDEsIDUwNyApOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDEsIDUwOEwpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NmaXhlZDMyIiksIDEsIDUwOSApOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDEsIDUxMEwpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDEsIDUxMUYpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2RvdWJsZSIgICksIDEsIDUxMkQpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Jvb2wiICAgICksIDEsIHRydWUpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3N0cmluZyIgICksIDEsICI1MTUiKTsKKyAgICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9ieXRlcyIgICApLCAxLCB0b0J5dGVzKCI1MTYiKSk7CisKKyAgICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZGdyb3VwIiksIDEsCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJyZXBlYXRlZGdyb3VwIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQocmVwZWF0ZWRHcm91cEEsIDUxNykuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLnNldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIikpCisgICAgICAgICAgICAgICAuc2V0RmllbGQobmVzdGVkQiwgNTE4KS5idWlsZCgpKTsKKyAgICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMSwKKyAgICAgICAgbmV3QnVpbGRlckZvckZpZWxkKG1lc3NhZ2UsIGYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKGZvcmVpZ25DLCA1MTkpLmJ1aWxkKCkpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiksIDEsCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSIpKQorICAgICAgICAgICAgICAgLnNldEZpZWxkKGltcG9ydEQsIDUyMCkuYnVpbGQoKSk7CisgICAgICBtZXNzYWdlLnNldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbGF6eV9tZXNzYWdlIiksIDEsCisgICAgICAgIG5ld0J1aWxkZXJGb3JGaWVsZChtZXNzYWdlLCBmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSkKKyAgICAgICAgICAgICAgIC5zZXRGaWVsZChuZXN0ZWRCLCA1MjcpLmJ1aWxkKCkpOworCisgICAgICBtZXNzYWdlLnNldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX2VudW0iICksIDEsICBuZXN0ZWRGb28pOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIpLCAxLCBmb3JlaWduRm9vKTsKKyAgICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgMSwgIGltcG9ydEZvbyk7CisKKyAgICAgIG1lc3NhZ2Uuc2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMSwgIjUyNCIpOworICAgICAgbWVzc2FnZS5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2NvcmQiKSwgMSwgIjUyNSIpOworICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEFzc2VydCAodXNpbmcge0Bjb2RlIGp1bml0LmZyYW1ld29yay5Bc3NlcnR9fSB0aGF0IGFsbCBmaWVsZHMgb2YKKyAgICAgKiB7QGNvZGUgbWVzc2FnZX0gYXJlIHNldCB0byB0aGUgdmFsdWVzIGFzc2lnbmVkIGJ5IHtAY29kZSBzZXRBbGxGaWVsZHN9LAorICAgICAqIHVzaW5nIHRoZSB7QGxpbmsgTWVzc2FnZX0gcmVmbGVjdGlvbiBpbnRlcmZhY2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXNzZXJ0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbihNZXNzYWdlT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9pbnQ2NCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX3VpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zaW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX3NpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9maXhlZDY0IiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX3NmaXhlZDMyIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9mbG9hdCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX2RvdWJsZSIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zdHJpbmciICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX2J5dGVzIiAgICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbGdyb3VwIiAgICAgICAgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIgKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZSgKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxncm91cCIpKSkuaGFzRmllbGQoZ3JvdXBBKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZSgKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmhhc0ZpZWxkKG5lc3RlZEIpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmhhc0ZpZWxkKGZvcmVpZ25DKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZSgKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmhhc0ZpZWxkKGltcG9ydEQpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfZW51bSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9pbXBvcnRfZW51bSIgKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX2NvcmQiKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwMSAgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ludDMyIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTAyTCAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfaW50NjQiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMDMgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF91aW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwNEwgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX3VpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTA1ICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfc2ludDMyIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMDZMICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9zaW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwNyAgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ZpeGVkMzIiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTA4TCAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfZml4ZWQ2NCIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMDkgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9zZml4ZWQzMiIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDExMEwgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX3NmaXhlZDY0IikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTExRiAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfZmxvYXQiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMTJEICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9kb3VibGUiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRydWUgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2Jvb2wiICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjExNSIsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfc3RyaW5nIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0b0J5dGVzKCIxMTYiKSwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9ieXRlcyIpKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTE3LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbGdyb3VwIikpKS5nZXRGaWVsZChncm91cEEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTE4LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMTksCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQoZm9yZWlnbkMpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMTIwLAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQoaW1wb3J0RCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMjYsCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQoaW1wb3J0RSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMjcsCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBuZXN0ZWRCYXosIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfbmVzdGVkX2VudW0iICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZm9yZWlnbkJheiwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggaW1wb3J0QmF6LCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ltcG9ydF9lbnVtIiApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjEyNCIsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjEyNSIsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfY29yZCIpKSk7CisKKyAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfaW50MzIiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9pbnQ2NCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3VpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfdWludDY0IiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zaW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3NpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZml4ZWQzMiIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9maXhlZDY0IiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3NmaXhlZDMyIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfc2ZpeGVkNjQiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9mbG9hdCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2RvdWJsZSIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfYm9vbCIgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zdHJpbmciICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2J5dGVzIiAgICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZGdyb3VwIiAgICAgICAgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfbmVzdGVkX2VudW0iICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfaW1wb3J0X2VudW0iICAgICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9jb3JkIikpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDEgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDMyIiAgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjAyTCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwMyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfdWludDMyIiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDRMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA1ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zaW50MzIiICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwNkwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc2ludDY0IiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDcgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA4TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9maXhlZDY0IiApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwOSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc2ZpeGVkMzIiKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTBMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjExRiAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mbG9hdCIgICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxMkQgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZG91YmxlIiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0cnVlICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Jvb2wiICAgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjIxNSIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmciICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRvQnl0ZXMoIjIxNiIpLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfYnl0ZXMiKSwgMCkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxNywKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZGdyb3VwIiksIDApKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChyZXBlYXRlZEdyb3VwQSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTgsCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKG5lc3RlZEIpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjE5LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpLCAwKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQoZm9yZWlnbkMpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjIwLAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiksIDApKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChpbXBvcnREKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIyNywKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKG5lc3RlZEIpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggbmVzdGVkQmFyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX2VudW0iICksMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhmb3JlaWduQmFyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiksMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggaW1wb3J0QmFyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW1wb3J0X2VudW0iICksMCkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIyMjQiLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjIyNSIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9jb3JkIiksIDApKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMDEgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDMyIiAgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzAyTCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMwMyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfdWludDMyIiAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMDRMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzA1ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zaW50MzIiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMwNkwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc2ludDY0IiAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMDcgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzA4TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9maXhlZDY0IiApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMwOSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc2ZpeGVkMzIiKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMTBMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzExRiAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mbG9hdCIgICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMxMkQgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZG91YmxlIiAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhmYWxzZSwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Jvb2wiICAgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjMxNSIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmciICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRvQnl0ZXMoIjMxNiIpLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfYnl0ZXMiKSwgMSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMxNywKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZGdyb3VwIiksIDEpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChyZXBlYXRlZEdyb3VwQSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygzMTgsCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKG5lc3RlZEIpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzE5LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpLCAxKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQoZm9yZWlnbkMpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMzIwLAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiksIDEpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChpbXBvcnREKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDMyNywKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKG5lc3RlZEIpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggbmVzdGVkQmF6LCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX2VudW0iICksMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhmb3JlaWduQmF6LCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiksMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggaW1wb3J0QmF6LCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW1wb3J0X2VudW0iICksMSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCIzMjQiLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjMyNSIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9jb3JkIiksIDEpKTsKKworICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ludDMyIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9pbnQ2NCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfdWludDMyIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X3VpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9zaW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfc2ludDY0IiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ZpeGVkMzIiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9maXhlZDY0IiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfc2ZpeGVkMzIiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X3NmaXhlZDY0IikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9mbG9hdCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfZG91YmxlIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2Jvb2wiICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9zdHJpbmciICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfYnl0ZXMiICAgKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9mb3JlaWduX2VudW0iKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2NvcmQiKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwMSAgLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfaW50MzIiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg0MDJMICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNDAzICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF91aW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwNEwgLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfdWludDY0IiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg0MDUgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNDA2TCAsIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9zaW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQwNyAgLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfZml4ZWQzMiIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg0MDhMICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNDA5ICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9zZml4ZWQzMiIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDQxMEwgLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfc2ZpeGVkNjQiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg0MTFGICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNDEyRCAsIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9kb3VibGUiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZhbHNlLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfYm9vbCIgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNDE1IiwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHModG9CeXRlcygiNDE2IiksIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9ieXRlcyIpKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIG5lc3RlZEZvbywgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X25lc3RlZF9lbnVtIiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZvcmVpZ25Gb28sIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9mb3JlaWduX2VudW0iKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggaW1wb3J0Rm9vLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfaW1wb3J0X2VudW0iICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNDI0IiwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3N0cmluZ19waWVjZSIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCI0MjUiLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfY29yZCIpKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib25lb2ZfYnl0ZXMiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0b0J5dGVzKCI2MDQiKSwgbWVzc2FnZS5nZXRGaWVsZChmKCJvbmVvZl9ieXRlcyIpKSk7CisKKyAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CisgICAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9uZW9mX3VpbnQzMiIpKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9uZW9mX25lc3RlZF9tZXNzYWdlIikpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigib25lb2Zfc3RyaW5nIikpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib25lb2ZfdWludDMyIikpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUobWVzc2FnZS5oYXNGaWVsZChmKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRmllbGQoZigib25lb2Zfc3RyaW5nIikpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDEsIG1lc3NhZ2UuZ2V0RmllbGQoZigib25lb2ZfdWludDMyIikpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDIsCisgICAgICAgICAgICAoKE1lc3NhZ2VPckJ1aWxkZXIpIG1lc3NhZ2UuZ2V0RmllbGQoZigib25lb2ZfbmVzdGVkX21lc3NhZ2UiKSkpCisgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCI2MDMiLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9uZW9mX3N0cmluZyIpKSk7CisgICAgICB9CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogQXNzZXJ0ICh1c2luZyB7QGNvZGUganVuaXQuZnJhbWV3b3JrLkFzc2VydH19IHRoYXQgYWxsIGZpZWxkcyBvZgorICAgICAqIHtAY29kZSBtZXNzYWdlfSBhcmUgY2xlYXJlZCwgYW5kIHRoYXQgZ2V0dGluZyB0aGUgZmllbGRzIHJldHVybnMgdGhlaXIKKyAgICAgKiBkZWZhdWx0IHZhbHVlcywgdXNpbmcgdGhlIHtAbGluayBNZXNzYWdlfSByZWZsZWN0aW9uIGludGVyZmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRDbGVhclZpYVJlZmxlY3Rpb24oTWVzc2FnZU9yQnVpbGRlciBtZXNzYWdlKSB7CisgICAgICAvLyBoYXNfYmxhaCgpIHNob3VsZCBpbml0aWFsbHkgYmUgZmFsc2UgZm9yIGFsbCBvcHRpb25hbCBmaWVsZHMuCisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9pbnQzMiIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9pbnQ2NCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF91aW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF91aW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zaW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zaW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9maXhlZDMyIiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9maXhlZDY0IiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zZml4ZWQzMiIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zZml4ZWQ2NCIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9mbG9hdCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9kb3VibGUiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9ib29sIiAgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9zdHJpbmciICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9ieXRlcyIgICApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsZ3JvdXAiICAgICAgICAgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIiApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfaW1wb3J0X2VudW0iICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9wdGlvbmFsX2NvcmQiKSkpOworCisgICAgICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHplcm8gb3Igc29tZXRoaW5nIGxpa2UgaXQuCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAgICAgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ludDMyIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMEwgICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfaW50NjQiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF91aW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDBMICAgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX3VpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCAgICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfc2ludDMyIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwTCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9zaW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAgICAgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ZpeGVkMzIiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMEwgICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfZml4ZWQ2NCIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9zZml4ZWQzMiIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDBMICAgLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX3NmaXhlZDY0IikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMEYgICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfZmxvYXQiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwRCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9kb3VibGUiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZhbHNlLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2Jvb2wiICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIiIgICAsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfc3RyaW5nIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhCeXRlU3RyaW5nLkVNUFRZLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2J5dGVzIikpKTsKKworICAgICAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UoCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsZ3JvdXAiKSkpLmhhc0ZpZWxkKGdyb3VwQSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuaGFzRmllbGQobmVzdGVkQikpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmhhc0ZpZWxkKGZvcmVpZ25DKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UoCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIikpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5oYXNGaWVsZChpbXBvcnREKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UoCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuaGFzRmllbGQoaW1wb3J0RSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9sYXp5X21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmhhc0ZpZWxkKG5lc3RlZEIpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbGdyb3VwIikpKS5nZXRGaWVsZChncm91cEEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKG5lc3RlZEIpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChmb3JlaWduQykpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQoaW1wb3J0RCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKGltcG9ydEUpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfbGF6eV9tZXNzYWdlIikpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChuZXN0ZWRCKSk7CisKKyAgICAgIC8vIEVudW1zIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlIGVudW0uCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBuZXN0ZWRGb28sIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfbmVzdGVkX2VudW0iICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZm9yZWlnbkZvbywgbWVzc2FnZS5nZXRGaWVsZChmKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggaW1wb3J0Rm9vLCBtZXNzYWdlLmdldEZpZWxkKGYoIm9wdGlvbmFsX2ltcG9ydF9lbnVtIiApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIiIsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIiIsIG1lc3NhZ2UuZ2V0RmllbGQoZigib3B0aW9uYWxfY29yZCIpKSk7CisKKyAgICAgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2ludDMyIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfaW50NjQiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF91aW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3VpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfc2ludDMyIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zaW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2ZpeGVkMzIiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZml4ZWQ2NCIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zZml4ZWQzMiIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3NmaXhlZDY0IikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZmxvYXQiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9kb3VibGUiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2Jvb2wiICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfc3RyaW5nIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9ieXRlcyIgICApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRncm91cCIgICAgICAgICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfbGF6eV9tZXNzYWdlIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfbmVzdGVkX2VudW0iICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfaW1wb3J0X2VudW0iICAgICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygwLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9jb3JkIikpKTsKKworICAgICAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9pbnQzMiIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfdWludDMyIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF91aW50NjQiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfc2ludDY0IiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9maXhlZDMyIiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfc2ZpeGVkMzIiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9zZml4ZWQ2NCIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfZG91YmxlIiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigiZGVmYXVsdF9ib29sIiAgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfYnl0ZXMiICAgKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X25lc3RlZF9lbnVtIiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJkZWZhdWx0X2NvcmQiICkpKTsKKworICAgICAgLy8gRmllbGRzIHdpdGggZGVmYXVsdHMgaGF2ZSB0aGVpciBkZWZhdWx0IHZhbHVlcyAoZHVoKS4KKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQxICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ludDMyIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQyTCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQzICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3VpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ0TCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3VpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTQ1ICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ2TCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3NpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ3ICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ZpeGVkMzIiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ4TCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDQ5ICAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3NmaXhlZDMyIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTUwTCAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3NmaXhlZDY0IikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDUxLjVGICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIDUyZTNEICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2RvdWJsZSIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHModHJ1ZSAgICwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2Jvb2wiICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoImhlbGxvIiwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHModG9CeXRlcygid29ybGQiKSwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2J5dGVzIikpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyggbmVzdGVkQmFyLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZm9yZWlnbkJhciwgbWVzc2FnZS5nZXRGaWVsZChmKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBpbXBvcnRCYXIsIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9pbXBvcnRfZW51bSIgKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJhYmMiLCBtZXNzYWdlLmdldEZpZWxkKGYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjEyMyIsIG1lc3NhZ2UuZ2V0RmllbGQoZigiZGVmYXVsdF9jb3JkIikpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRmllbGQoZigib25lb2ZfdWludDMyIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9uZW9mX25lc3RlZF9tZXNzYWdlIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShtZXNzYWdlLmhhc0ZpZWxkKGYoIm9uZW9mX3N0cmluZyIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGaWVsZChmKCJvbmVvZl9ieXRlcyIpKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRGaWVsZChmKCJvbmVvZl91aW50MzIiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiIiwgbWVzc2FnZS5nZXRGaWVsZChmKCJvbmVvZl9zdHJpbmciKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0b0J5dGVzKCIiKSwgbWVzc2FnZS5nZXRGaWVsZChmKCJvbmVvZl9ieXRlcyIpKSk7CisgICAgfQorCisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHB1YmxpYyB2b2lkIGFzc2VydFJlcGVhdGVkRmllbGRzTW9kaWZpZWRWaWFSZWZsZWN0aW9uKAorICAgICAgICBNZXNzYWdlT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAgIC8vIE1vZGlmeVJlcGVhdGVkRmllbGRzIG9ubHkgc2V0cyB0aGUgc2Vjb25kIHJlcGVhdGVkIGVsZW1lbnQgb2YgZWFjaAorICAgICAgLy8gZmllbGQuICBJbiBhZGRpdGlvbiB0byB2ZXJpZnlpbmcgdGhpcywgd2UgYWxzbyB2ZXJpZnkgdGhhdCB0aGUgZmlyc3QKKyAgICAgIC8vIGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KiBtb2RpZmllZC4KKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfaW50MzIiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9pbnQ2NCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3VpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfdWludDY0IiAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zaW50MzIiICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3NpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfZml4ZWQzMiIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9maXhlZDY0IiApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3NmaXhlZDMyIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfc2ZpeGVkNjQiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9mbG9hdCIgICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2RvdWJsZSIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicmVwZWF0ZWRfYm9vbCIgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9zdHJpbmciICApKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2J5dGVzIiAgICkpKTsKKworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZGdyb3VwIiAgICAgICAgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSIgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGRDb3VudChmKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgICAgKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZENvdW50KGYoInJlcGVhdGVkX2NvcmQiKSkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwMSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW50MzIiICAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDJMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDY0IiAgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjAzICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF91aW50MzIiICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwNEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfdWludDY0IiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDUgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NpbnQzMiIgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA2TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zaW50NjQiICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIwNyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZml4ZWQzMiIgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMDhMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjA5ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zZml4ZWQzMiIpLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxMEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc2ZpeGVkNjQiKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTFGICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjEyRCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9kb3VibGUiICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRydWUgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfYm9vbCIgICAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMjE1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3N0cmluZyIgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHModG9CeXRlcygiMjE2IiksIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9ieXRlcyIpLCAwKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjE3LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkZ3JvdXAiKSwgMCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKHJlcGVhdGVkR3JvdXBBKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDIxOCwKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpLCAwKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMTksCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIiksIDApKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChmb3JlaWduQykpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyMjAsCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKGltcG9ydEQpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMjI3LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2xhenlfbWVzc2FnZSIpLCAwKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBuZXN0ZWRCYXIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZvcmVpZ25CYXIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iKSwwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBpbXBvcnRCYXIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwwKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjIyNCIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiMjI1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2NvcmQiKSwgMCkpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUwMSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW50MzIiICAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MDJMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ludDY0IiAgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTAzICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF91aW50MzIiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUwNEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfdWludDY0IiAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MDUgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3NpbnQzMiIgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTA2TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zaW50NjQiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUwNyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZml4ZWQzMiIgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MDhMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTA5ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zZml4ZWQzMiIpLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUxMEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc2ZpeGVkNjQiKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MTFGICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTEyRCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9kb3VibGUiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHRydWUgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfYm9vbCIgICAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNTE1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3N0cmluZyIgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHModG9CeXRlcygiNTE2IiksIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9ieXRlcyIpLCAxKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTE3LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkZ3JvdXAiKSwgMSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKHJlcGVhdGVkR3JvdXBBKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDUxOCwKKyAgICAgICAgKChNZXNzYWdlKW1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpLCAxKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MTksCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIiksIDEpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChmb3JlaWduQykpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1MjAsCisgICAgICAgICgoTWVzc2FnZSltZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKGltcG9ydEQpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNTI3LAorICAgICAgICAoKE1lc3NhZ2UpbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2xhenlfbWVzc2FnZSIpLCAxKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQobmVzdGVkQikpOworCisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBuZXN0ZWRGb28sIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZvcmVpZ25Gb28sIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iKSwxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCBpbXBvcnRGb28sIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwxKSk7CisKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIjUyNCIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiNTI1IiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2NvcmQiKSwgMSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFBhY2tlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZS5CdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfaW50MzIiICAgKSwgNjAxICk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ludDY0IiAgICksIDYwMkwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF91aW50MzIiICApLCA2MDMgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfdWludDY0IiAgKSwgNjA0TCk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX3NpbnQzMiIgICksIDYwNSApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zaW50NjQiICApLCA2MDZMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfZml4ZWQzMiIgKSwgNjA3ICk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ZpeGVkNjQiICksIDYwOEwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zZml4ZWQzMiIpLCA2MDkgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfc2ZpeGVkNjQiKSwgNjEwTCk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2Zsb2F0IiAgICksIDYxMUYpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9kb3VibGUiICApLCA2MTJEKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfYm9vbCIgICAgKSwgdHJ1ZSk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2VudW0iICksICBmb3JlaWduQmFyKTsKKyAgICAgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfaW50MzIiICAgKSwgNzAxICk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ludDY0IiAgICksIDcwMkwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF91aW50MzIiICApLCA3MDMgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfdWludDY0IiAgKSwgNzA0TCk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX3NpbnQzMiIgICksIDcwNSApOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zaW50NjQiICApLCA3MDZMKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfZml4ZWQzMiIgKSwgNzA3ICk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ZpeGVkNjQiICksIDcwOEwpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zZml4ZWQzMiIpLCA3MDkgKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfc2ZpeGVkNjQiKSwgNzEwTCk7CisgICAgICBtZXNzYWdlLmFkZFJlcGVhdGVkRmllbGQoZigicGFja2VkX2Zsb2F0IiAgICksIDcxMUYpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9kb3VibGUiICApLCA3MTJEKTsKKyAgICAgIG1lc3NhZ2UuYWRkUmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfYm9vbCIgICAgKSwgZmFsc2UpOworICAgICAgbWVzc2FnZS5hZGRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9lbnVtIiApLCAgZm9yZWlnbkJheik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXNzZXJ0UGFja2VkRmllbGRzU2V0VmlhUmVmbGVjdGlvbihNZXNzYWdlT3JCdWlsZGVyIG1lc3NhZ2UpIHsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2ludDMyIiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2ludDY0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX3VpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX3VpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX3NpbnQzMiIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX3NpbnQ2NCIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2ZpeGVkMzIiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2ZpeGVkNjQiICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX3NmaXhlZDMyIikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX3NmaXhlZDY0IikpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2Zsb2F0IiAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2RvdWJsZSIgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2Jvb2wiICAgICkpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZigicGFja2VkX2VudW0iICAgKSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDEgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9pbnQzMiIgICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYwMkwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ludDY0IiAgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjAzICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfdWludDMyIiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDRMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF91aW50NjQiICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYwNSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX3NpbnQzMiIgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA2TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfc2ludDY0IiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MDcgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9maXhlZDMyIiApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYwOEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ZpeGVkNjQiICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjA5ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfc2ZpeGVkMzIiKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg2MTBMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zZml4ZWQ2NCIpLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDYxMUYgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX2Zsb2F0IiAgICksIDApKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNjEyRCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfZG91YmxlIiAgKSwgMCkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyh0cnVlICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9ib29sIiAgICApLCAwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZvcmVpZ25CYXIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfZW51bSIgKSwwKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcwMSAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ludDMyIiAgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzAyTCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfaW50NjQiICAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MDMgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF91aW50MzIiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcwNEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX3VpbnQ2NCIgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA1ICAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfc2ludDMyIiAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MDZMICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zaW50NjQiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcwNyAgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX2ZpeGVkMzIiICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzA4TCAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfZml4ZWQ2NCIgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MDkgICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9zZml4ZWQzMiIpLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDcxMEwgLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX3NmaXhlZDY0IiksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoNzExRiAsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChmKCJwYWNrZWRfZmxvYXQiICAgKSwgMSkpOworICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg3MTJEICwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9kb3VibGUiICApLCAxKSk7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZhbHNlLCBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQoZigicGFja2VkX2Jvb2wiICAgICksIDEpKTsKKyAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZm9yZWlnbkJheiwgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKGYoInBhY2tlZF9lbnVtIiApLDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGF0IHRoZSByZWZsZWN0aW9uIHNldHRlcnMgZm9yIHRoZSBnaXZlbi5CdWlsZGVyIG9iamVjdCB0aHJvdyBhCisgICAgICogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhleSBhcmUgcGFzc2VkIGEgbnVsbCB2YWx1ZS4gIFVzZXMgQXNzZXJ0IHRvIHRocm93IGFuCisgICAgICogYXBwcm9wcmlhdGUgYXNzZXJ0aW9uIGZhaWx1cmUsIGlmIHRoZSBjb25kaXRpb24gaXMgbm90IHZlcmlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFzc2VydFJlZmxlY3Rpb25TZXR0ZXJzUmVqZWN0TnVsbChNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikKKyAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBidWlsZGVyLnNldEZpZWxkKGYoIm9wdGlvbmFsX3N0cmluZyIpLCBudWxsKTsKKyAgICAgICAgQXNzZXJ0LmZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBidWlsZGVyLnNldEZpZWxkKGYoIm9wdGlvbmFsX2J5dGVzIiksIG51bGwpOworICAgICAgICBBc3NlcnQuZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGJ1aWxkZXIuc2V0RmllbGQoZigib3B0aW9uYWxfbmVzdGVkX2VudW0iKSwgbnVsbCk7CisgICAgICAgIEFzc2VydC5mYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgYnVpbGRlci5zZXRGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpLAorICAgICAgICAgICAgICAgICAgICAgICAgIChUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgbnVsbCk7CisgICAgICAgIEFzc2VydC5mYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgYnVpbGRlci5zZXRGaWVsZChmKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpLAorICAgICAgICAgICAgICAgICAgICAgICAgIChUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyKSBudWxsKTsKKyAgICAgICAgQXNzZXJ0LmZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgICB9CisKKyAgICAgIHRyeSB7CisgICAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9zdHJpbmciKSwgbnVsbCk7CisgICAgICAgIEFzc2VydC5mYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2J5dGVzIiksIG51bGwpOworICAgICAgICBBc3NlcnQuZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIpLCBudWxsKTsKKyAgICAgICAgQXNzZXJ0LmZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBidWlsZGVyLmFkZFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgbnVsbCk7CisgICAgICAgIEFzc2VydC5mYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgdGhlIHJlZmxlY3Rpb24gcmVwZWF0ZWQgc2V0dGVycyBmb3IgdGhlIGdpdmVuIEJ1aWxkZXIgb2JqZWN0IHRocm93IGEKKyAgICAgKiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGV5IGFyZSBwYXNzZWQgYSBudWxsIHZhbHVlLiAgVXNlcyBBc3NlcnQgdG8gdGhyb3cgYW4gYXBwcm9wcmlhdGUKKyAgICAgKiBhc3NlcnRpb24gZmFpbHVyZSwgaWYgdGhlIGNvbmRpdGlvbiBpcyBub3QgdmVyaWZpZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXNzZXJ0UmVmbGVjdGlvblJlcGVhdGVkU2V0dGVyc1JlamVjdE51bGwoTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXIpCisgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX3N0cmluZyIpLCAib25lIik7CisgICAgICB0cnkgeworICAgICAgICBidWlsZGVyLnNldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfc3RyaW5nIiksIDAsIG51bGwpOworICAgICAgICBBc3NlcnQuZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgIH0KKworICAgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX2J5dGVzIiksIHRvQnl0ZXMoIm9uZSIpKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9ieXRlcyIpLCAwLCBudWxsKTsKKyAgICAgICAgQXNzZXJ0LmZhaWwoIkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBXZSBleHBlY3QgdGhpcyBleGNlcHRpb24uCisgICAgICB9CisKKyAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIpLCBuZXN0ZWRCYXopOworICAgICAgdHJ5IHsKKyAgICAgICAgYnVpbGRlci5zZXRSZXBlYXRlZEZpZWxkKGYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiksIDAsIG51bGwpOworICAgICAgICBBc3NlcnQuZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgIH0KKworICAgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKAorICAgICAgICAgIGYoInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIiksCisgICAgICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDIxOCkuYnVpbGQoKSk7CisgICAgICB0cnkgeworICAgICAgICBidWlsZGVyLnNldFJlcGVhdGVkRmllbGQoZigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMCwgbnVsbCk7CisgICAgICAgIEFzc2VydC5mYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gV2UgZXhwZWN0IHRoaXMgZXhjZXB0aW9uLgorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gZmlsZVBhdGggVGhlIHBhdGggcmVsYXRpdmUgdG8KKyAgICoge0BsaW5rICNnZXRUZXN0RGF0YURpcn0uCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkVGV4dEZyb21GaWxlKFN0cmluZyBmaWxlUGF0aCkgeworICAgIHJldHVybiByZWFkQnl0ZXNGcm9tRmlsZShmaWxlUGF0aCkudG9TdHJpbmdVdGY4KCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBGaWxlIGdldFRlc3REYXRhRGlyKCkgeworICAgIC8vIFNlYXJjaCBlYWNoIHBhcmVudCBkaXJlY3RvcnkgbG9va2luZyBmb3IgInNyYy9nb29nbGUvcHJvdG9idWYiLgorICAgIEZpbGUgYW5jZXN0b3IgPSBuZXcgRmlsZSgiLiIpOworICAgIHRyeSB7CisgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLmdldENhbm9uaWNhbEZpbGUoKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgIkNvdWxkbid0IGdldCBjYW5vbmljYWwgbmFtZSBvZiB3b3JraW5nIGRpcmVjdG9yeS4iLCBlKTsKKyAgICB9CisgICAgd2hpbGUgKGFuY2VzdG9yICE9IG51bGwgJiYgYW5jZXN0b3IuZXhpc3RzKCkpIHsKKyAgICAgIGlmIChuZXcgRmlsZShhbmNlc3RvciwgInNyYy9nb29nbGUvcHJvdG9idWYiKS5leGlzdHMoKSkgeworICAgICAgICByZXR1cm4gbmV3IEZpbGUoYW5jZXN0b3IsICJzcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhIik7CisgICAgICB9CisgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLmdldFBhcmVudEZpbGUoKTsKKyAgICB9CisKKyAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICJDb3VsZCBub3QgZmluZCBnb2xkZW4gZmlsZXMuICBUaGlzIHRlc3QgbXVzdCBiZSBydW4gZnJvbSB3aXRoaW4gdGhlICIgKworICAgICAgInByb3RvYnVmIHNvdXJjZSBwYWNrYWdlIHNvIHRoYXQgaXQgY2FuIHJlYWQgdGVzdCBkYXRhIGZpbGVzIGZyb20gdGhlICIgKworICAgICAgIkMrKyBzb3VyY2UgdHJlZS4iKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gZmlsZW5hbWUgVGhlIHBhdGggcmVsYXRpdmUgdG8KKyAgICoge0BsaW5rICNnZXRUZXN0RGF0YURpcn0uCisgICAqLworICBwdWJsaWMgc3RhdGljIEJ5dGVTdHJpbmcgcmVhZEJ5dGVzRnJvbUZpbGUoU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgRmlsZSBmdWxsUGF0aCA9IG5ldyBGaWxlKGdldFRlc3REYXRhRGlyKCksIGZpbGVuYW1lKTsKKyAgICB0cnkgeworICAgICAgUmFuZG9tQWNjZXNzRmlsZSBmaWxlID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZnVsbFBhdGgsICJyIik7CisgICAgICBieXRlW10gY29udGVudCA9IG5ldyBieXRlWyhpbnQpIGZpbGUubGVuZ3RoKCldOworICAgICAgZmlsZS5yZWFkRnVsbHkoY29udGVudCk7CisgICAgICByZXR1cm4gQnl0ZVN0cmluZy5jb3B5RnJvbShjb250ZW50KTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBUaHJvdyBhIFJ1bnRpbWVFeGNlcHRpb24gaGVyZSBzbyB0aGF0IHdlIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24gZnJvbQorICAgICAgLy8gc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJDb3VsZG4ndCByZWFkIGZpbGU6ICIgKyBmdWxsUGF0aC5nZXRQYXRoKCksIGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIGJ5dGVzIG9mIHRoZSAiZ29sZGVuIG1lc3NhZ2UiLiAgVGhpcyBpcyBhIHNlcmlhbGl6ZWQgVGVzdEFsbFR5cGVzCisgICAqIHdpdGggYWxsIGZpZWxkcyBzZXQgYXMgdGhleSB3b3VsZCBiZSBieQorICAgKiB7QGxpbmsgI3NldEFsbEZpZWxkcyhUZXN0QWxsVHlwZXMuQnVpbGRlcil9LCBidXQgaXQgaXMgbG9hZGVkIGZyb20gYSBmaWxlCisgICAqIG9uIGRpc2sgcmF0aGVyIHRoYW4gZ2VuZXJhdGVkIGR5bmFtaWNhbGx5LiAgVGhlIGZpbGUgaXMgYWN0dWFsbHkgZ2VuZXJhdGVkCisgICAqIGJ5IEMrKyBjb2RlLCBzbyB0ZXN0aW5nIGFnYWluc3QgaXQgdmVyaWZpZXMgY29tcGF0aWJpbGl0eSB3aXRoIEMrKy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnl0ZVN0cmluZyBnZXRHb2xkZW5NZXNzYWdlKCkgeworICAgIGlmIChnb2xkZW5NZXNzYWdlID09IG51bGwpIHsKKyAgICAgIGdvbGRlbk1lc3NhZ2UgPSByZWFkQnl0ZXNGcm9tRmlsZSgiZ29sZGVuX21lc3NhZ2Vfb25lb2ZfaW1wbGVtZW50ZWQiKTsKKyAgICB9CisgICAgcmV0dXJuIGdvbGRlbk1lc3NhZ2U7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgQnl0ZVN0cmluZyBnb2xkZW5NZXNzYWdlID0gbnVsbDsKKworICAvKioKKyAgICogR2V0IHRoZSBieXRlcyBvZiB0aGUgImdvbGRlbiBwYWNrZWQgZmllbGRzIG1lc3NhZ2UiLiAgVGhpcyBpcyBhIHNlcmlhbGl6ZWQKKyAgICogVGVzdFBhY2tlZFR5cGVzIHdpdGggYWxsIGZpZWxkcyBzZXQgYXMgdGhleSB3b3VsZCBiZSBieQorICAgKiB7QGxpbmsgI3NldFBhY2tlZEZpZWxkcyhUZXN0UGFja2VkVHlwZXMuQnVpbGRlcil9LCBidXQgaXQgaXMgbG9hZGVkIGZyb20gYQorICAgKiBmaWxlIG9uIGRpc2sgcmF0aGVyIHRoYW4gZ2VuZXJhdGVkIGR5bmFtaWNhbGx5LiAgVGhlIGZpbGUgaXMgYWN0dWFsbHkKKyAgICogZ2VuZXJhdGVkIGJ5IEMrKyBjb2RlLCBzbyB0ZXN0aW5nIGFnYWluc3QgaXQgdmVyaWZpZXMgY29tcGF0aWJpbGl0eSB3aXRoCisgICAqIEMrKy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnl0ZVN0cmluZyBnZXRHb2xkZW5QYWNrZWRGaWVsZHNNZXNzYWdlKCkgeworICAgIGlmIChnb2xkZW5QYWNrZWRGaWVsZHNNZXNzYWdlID09IG51bGwpIHsKKyAgICAgIGdvbGRlblBhY2tlZEZpZWxkc01lc3NhZ2UgPQorICAgICAgICAgIHJlYWRCeXRlc0Zyb21GaWxlKCJnb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlIik7CisgICAgfQorICAgIHJldHVybiBnb2xkZW5QYWNrZWRGaWVsZHNNZXNzYWdlOworICB9CisgIHByaXZhdGUgc3RhdGljIEJ5dGVTdHJpbmcgZ29sZGVuUGFja2VkRmllbGRzTWVzc2FnZSA9IG51bGw7CisKKyAgLyoqCisgICAqIE1vY2sgaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIEdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudH0gZm9yIHRlc3RpbmcuCisgICAqCisgICAqIEBhdXRob3Igam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrQnVpbGRlclBhcmVudAorICAgICAgaW1wbGVtZW50cyBHZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXJQYXJlbnQgeworCisgICAgcHJpdmF0ZSBpbnQgaW52YWxpZGF0aW9uczsKKworICAgIC8vQE92ZXJyaWRlIChKYXZhIDEuNiBvdmVycmlkZSBzZW1hbnRpY3MsIGJ1dCB3ZSBtdXN0IHN1cHBvcnQgMS41KQorICAgIHB1YmxpYyB2b2lkIG1hcmtEaXJ0eSgpIHsKKyAgICAgIGludmFsaWRhdGlvbnMrKzsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEludmFsaWRhdGlvbkNvdW50KCkgeworICAgICAgcmV0dXJuIGludmFsaWRhdGlvbnM7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9UZXh0Rm9ybWF0VGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGV4dEZvcm1hdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYmEwNmNhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVGV4dEZvcm1hdFRlc3QuamF2YQpAQCAtMCwwICsxLDEwMDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlRleHRGb3JtYXQuUGFyc2VyLlNpbmd1bGFyT3ZlcndyaXRlUG9saWN5OworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldDsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmc7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKKworLyoqCisgKiBUZXN0IGNhc2UgZm9yIHtAbGluayBUZXh0Rm9ybWF0fS4KKyAqCisgKiBUT0RPKHdlbmJveik6IEV4dGVuc2lvblRlc3QgYW5kIHJlc3Qgb2YgdGV4dF9mb3JtYXRfdW5pdHRlc3QuY2MuCisgKgorICogQGF1dGhvciB3ZW5ib3pAZ29vZ2xlLmNvbSAoV2VuYm8gWmh1KQorICovCitwdWJsaWMgY2xhc3MgVGV4dEZvcm1hdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgLy8gQSBiYXNpYyBzdHJpbmcgd2l0aCBkaWZmZXJlbnQgZXNjYXBhYmxlIGNoYXJhY3RlcnMgZm9yIHRlc3RpbmcuCisgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBrRXNjYXBlVGVzdFN0cmluZyA9CisgICAgICAiXCJBIHN0cmluZyB3aXRoICcgY2hhcmFjdGVycyBcbiBhbmQgXHIgbmV3bGluZXMgYW5kIFx0IHRhYnMgYW5kIFwwMDEgIgorICAgICAgICAgICsgInNsYXNoZXMgXFwiOworCisgIC8vIEEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFib3ZlIHN0cmluZyB3aXRoIGFsbCB0aGUgY2hhcmFjdGVycyBlc2NhcGVkLgorICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcga0VzY2FwZVRlc3RTdHJpbmdFc2NhcGVkID0KKyAgICAgICJcXFwiQSBzdHJpbmcgd2l0aCBcXCcgY2hhcmFjdGVycyBcXG4gYW5kIFxcciBuZXdsaW5lcyAiCisgICAgICAgICAgKyAiYW5kIFxcdCB0YWJzIGFuZCBcXDAwMSBzbGFzaGVzIFxcXFwiOworCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBhbGxGaWVsZHNTZXRUZXh0ID0gVGVzdFV0aWwucmVhZFRleHRGcm9tRmlsZSgKKyAgICAidGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9vbmVvZl9pbXBsZW1lbnRlZC50eHQiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGFsbEV4dGVuc2lvbnNTZXRUZXh0ID0gVGVzdFV0aWwucmVhZFRleHRGcm9tRmlsZSgKKyAgICAidGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhLnR4dCIpOworCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBleG90aWNUZXh0ID0KKyAgICAicmVwZWF0ZWRfaW50MzI6IC0xXG4iICsKKyAgICAicmVwZWF0ZWRfaW50MzI6IC0yMTQ3NDgzNjQ4XG4iICsKKyAgICAicmVwZWF0ZWRfaW50NjQ6IC0xLFxuIiArCisgICAgInJlcGVhdGVkX2ludDY0OiAtOTIyMzM3MjAzNjg1NDc3NTgwOFxuIiArCisgICAgInJlcGVhdGVkX3VpbnQzMjogNDI5NDk2NzI5NVxuIiArCisgICAgInJlcGVhdGVkX3VpbnQzMjogMjE0NzQ4MzY0OFxuIiArCisgICAgInJlcGVhdGVkX3VpbnQ2NDogMTg0NDY3NDQwNzM3MDk1NTE2MTVcbiIgKworICAgICJyZXBlYXRlZF91aW50NjQ6IDkyMjMzNzIwMzY4NTQ3NzU4MDhcbiIgKworICAgICJyZXBlYXRlZF9kb3VibGU6IDEyMy4wXG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxMjMuNVxuIiArCisgICAgInJlcGVhdGVkX2RvdWJsZTogMC4xMjVcbiIgKworICAgICJyZXBlYXRlZF9kb3VibGU6IC4xMjVcbiIgKworICAgICJyZXBlYXRlZF9kb3VibGU6IC0uMTI1XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzRTE3XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzRSsxN1xuIiArCisgICAgInJlcGVhdGVkX2RvdWJsZTogLTEuMjNlLTE3XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAuMjNlKzE3XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAtLjIzRTE3XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNUUyMlxuIiArCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzVFLTE4XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxMjMuNDU2Nzg5XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBJbmZpbml0eVxuIiArCisgICAgInJlcGVhdGVkX2RvdWJsZTogLUluZmluaXR5XG4iICsKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBOYU5cbiIgKworICAgICJyZXBlYXRlZF9zdHJpbmc6IFwiXFwwMDBcXDAwMVxcYVxcYlxcZlxcblxcclxcdFxcdlxcXFxcXCdcXFwiIiArCisgICAgICAiXFwzNDFcXDIxMFxcMjY0XCJcbiIgKworICAgICJyZXBlYXRlZF9ieXRlczogXCJcXDAwMFxcMDAxXFxhXFxiXFxmXFxuXFxyXFx0XFx2XFxcXFxcJ1xcXCJcXDM3NlwiXG4iOworCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjYW5vbmljYWxFeG90aWNUZXh0ID0KKyAgICAgIGV4b3RpY1RleHQucmVwbGFjZSgiOiAuIiwgIjogMC4iKS5yZXBsYWNlKCI6IC0uIiwgIjogLTAuIikgICAvLyBzaG9ydC1mb3JtIGRvdWJsZQorICAgICAgLnJlcGxhY2UoIjIzZSIsICIyM0UiKS5yZXBsYWNlKCJFKyIsICJFIikucmVwbGFjZSgiMC4yM0UxNyIsICIyLjNFMTYiKS5yZXBsYWNlKCIsIiwgIiIpOworCisgIHByaXZhdGUgU3RyaW5nIG1lc3NhZ2VTZXRUZXh0ID0KKyAgICAiW3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMV0ge1xuIiArCisgICAgIiAgaTogMTIzXG4iICsKKyAgICAifVxuIiArCisgICAgIltwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjJdIHtcbiIgKworICAgICIgIHN0cjogXCJmb29cIlxuIiArCisgICAgIn1cbiI7CisKKyAgcHJpdmF0ZSBTdHJpbmcgbWVzc2FnZVNldFRleHRXaXRoUmVwZWF0ZWRFeHRlbnNpb24gPQorICAgICAgIltwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjFdIHtcbiIgKworICAgICAgIiAgaTogMTIzXG4iICsKKyAgICAgICJ9XG4iICsKKyAgICAgICJbcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xXSB7XG4iICsKKyAgICAgICIgIGk6IDQ1NlxuIiArCisgICAgICAifVxuIjsKKworCisgIHByaXZhdGUgZmluYWwgVGV4dEZvcm1hdC5QYXJzZXIgcGFyc2VyV2l0aE92ZXJ3cml0ZUZvcmJpZGRlbiA9CisgICAgICBUZXh0Rm9ybWF0LlBhcnNlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0U2luZ3VsYXJPdmVyd3JpdGVQb2xpY3koCisgICAgICAgICAgICAgIFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5LkZPUkJJRF9TSU5HVUxBUl9PVkVSV1JJVEVTKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHByaXZhdGUgZmluYWwgVGV4dEZvcm1hdC5QYXJzZXIgZGVmYXVsdFBhcnNlciA9CisgICAgICBUZXh0Rm9ybWF0LlBhcnNlci5uZXdCdWlsZGVyKCkuYnVpbGQoKTsKKworICAvKiogUHJpbnQgVGVzdEFsbFR5cGVzIGFuZCBjb21wYXJlIHdpdGggZ29sZGVuIGZpbGUuICovCisgIHB1YmxpYyB2b2lkIHRlc3RQcmludE1lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgamF2YVRleHQgPSBUZXh0Rm9ybWF0LnByaW50VG9TdHJpbmcoVGVzdFV0aWwuZ2V0QWxsU2V0KCkpOworCisgICAgLy8gSmF2YSBsaWtlcyB0byBhZGQgYSB0cmFpbGluZyAiLjAiIHRvIGZsb2F0cyBhbmQgZG91Ymxlcy4gIEMgcHJpbnRmCisgICAgLy8gKHdpdGggJWcgZm9ybWF0KSBkb2VzIG5vdC4gIE91ciBnb2xkZW4gZmlsZXMgYXJlIHVzZWQgZm9yIGJvdGgKKyAgICAvLyBDKysgYW5kIEphdmEgVGV4dEZvcm1hdCBjbGFzc2VzLCBzbyB3ZSBuZWVkIHRvIGNvbmZvcm0uCisgICAgamF2YVRleHQgPSBqYXZhVGV4dC5yZXBsYWNlKCIuMFxuIiwgIlxuIik7CisKKyAgICBhc3NlcnRFcXVhbHMoYWxsRmllbGRzU2V0VGV4dCwgamF2YVRleHQpOworICB9CisKKyAgLyoqIFByaW50IFRlc3RBbGxUeXBlcyBhcyBCdWlsZGVyIGFuZCBjb21wYXJlIHdpdGggZ29sZGVuIGZpbGUuICovCisgIHB1YmxpYyB2b2lkIHRlc3RQcmludE1lc3NhZ2VCdWlsZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3RyaW5nIGphdmFUZXh0ID0gVGV4dEZvcm1hdC5wcmludFRvU3RyaW5nKFRlc3RVdGlsLmdldEFsbFNldEJ1aWxkZXIoKSk7CisKKyAgICAvLyBKYXZhIGxpa2VzIHRvIGFkZCBhIHRyYWlsaW5nICIuMCIgdG8gZmxvYXRzIGFuZCBkb3VibGVzLiAgQyBwcmludGYKKyAgICAvLyAod2l0aCAlZyBmb3JtYXQpIGRvZXMgbm90LiAgT3VyIGdvbGRlbiBmaWxlcyBhcmUgdXNlZCBmb3IgYm90aAorICAgIC8vIEMrKyBhbmQgSmF2YSBUZXh0Rm9ybWF0IGNsYXNzZXMsIHNvIHdlIG5lZWQgdG8gY29uZm9ybS4KKyAgICBqYXZhVGV4dCA9IGphdmFUZXh0LnJlcGxhY2UoIi4wXG4iLCAiXG4iKTsKKworICAgIGFzc2VydEVxdWFscyhhbGxGaWVsZHNTZXRUZXh0LCBqYXZhVGV4dCk7CisgIH0KKworICAvKiogUHJpbnQgVGVzdEFsbEV4dGVuc2lvbnMgYW5kIGNvbXBhcmUgd2l0aCBnb2xkZW4gZmlsZS4gKi8KKyAgcHVibGljIHZvaWQgdGVzdFByaW50RXh0ZW5zaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBqYXZhVGV4dCA9IFRleHRGb3JtYXQucHJpbnRUb1N0cmluZyhUZXN0VXRpbC5nZXRBbGxFeHRlbnNpb25zU2V0KCkpOworCisgICAgLy8gSmF2YSBsaWtlcyB0byBhZGQgYSB0cmFpbGluZyAiLjAiIHRvIGZsb2F0cyBhbmQgZG91Ymxlcy4gIEMgcHJpbnRmCisgICAgLy8gKHdpdGggJWcgZm9ybWF0KSBkb2VzIG5vdC4gIE91ciBnb2xkZW4gZmlsZXMgYXJlIHVzZWQgZm9yIGJvdGgKKyAgICAvLyBDKysgYW5kIEphdmEgVGV4dEZvcm1hdCBjbGFzc2VzLCBzbyB3ZSBuZWVkIHRvIGNvbmZvcm0uCisgICAgamF2YVRleHQgPSBqYXZhVGV4dC5yZXBsYWNlKCIuMFxuIiwgIlxuIik7CisKKyAgICBhc3NlcnRFcXVhbHMoYWxsRXh0ZW5zaW9uc1NldFRleHQsIGphdmFUZXh0KTsKKyAgfQorCisgIC8vIENyZWF0ZXMgYW4gZXhhbXBsZSB1bmtub3duIGZpZWxkIHNldC4KKyAgcHJpdmF0ZSBVbmtub3duRmllbGRTZXQgbWFrZVVua25vd25GaWVsZFNldCgpIHsKKyAgICByZXR1cm4gVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkRmllbGQoNSwKKyAgICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoMSkKKyAgICAgICAgICAgIC5hZGRGaXhlZDMyKDIpCisgICAgICAgICAgICAuYWRkRml4ZWQ2NCgzKQorICAgICAgICAgICAgLmFkZExlbmd0aERlbGltaXRlZChCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiNCIpKQorICAgICAgICAgICAgLmFkZEdyb3VwKAorICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWRkRmllbGQoMTAsCisgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLmFkZFZhcmludCg1KQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYWRkRmllbGQoOCwKKyAgICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoMSkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoMikKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoMykKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYWRkRmllbGQoMTUsCisgICAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVmFyaW50KDB4QUJDREVGMTIzNDU2Nzg5MEwpCisgICAgICAgICAgICAuYWRkRml4ZWQzMigweEFCQ0QxMjM0KQorICAgICAgICAgICAgLmFkZEZpeGVkNjQoMHhBQkNERUYxMjM0NTY3ODkwTCkKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQcmludFVua25vd25GaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0IHByaW50aW5nIG9mIHVua25vd24gZmllbGRzIGluIGEgbWVzc2FnZS4KKworICAgIFRlc3RFbXB0eU1lc3NhZ2UgbWVzc2FnZSA9CisgICAgICBUZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0VW5rbm93bkZpZWxkcyhtYWtlVW5rbm93bkZpZWxkU2V0KCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgIjU6IDFcbiIgKworICAgICAgIjU6IDB4MDAwMDAwMDJcbiIgKworICAgICAgIjU6IDB4MDAwMDAwMDAwMDAwMDAwM1xuIiArCisgICAgICAiNTogXCI0XCJcbiIgKworICAgICAgIjUge1xuIiArCisgICAgICAiICAxMDogNVxuIiArCisgICAgICAifVxuIiArCisgICAgICAiODogMVxuIiArCisgICAgICAiODogMlxuIiArCisgICAgICAiODogM1xuIiArCisgICAgICAiMTU6IDEyMzc5ODEzODEyMTc3ODkzNTIwXG4iICsKKyAgICAgICIxNTogMHhhYmNkMTIzNFxuIiArCisgICAgICAiMTU6IDB4YWJjZGVmMTIzNDU2Nzg5MFxuIiwKKyAgICAgIFRleHRGb3JtYXQucHJpbnRUb1N0cmluZyhtZXNzYWdlKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UHJpbnRGaWVsZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBkYXRhRmllbGQgPQorICAgICAgT25lU3RyaW5nLmdldERlc2NyaXB0b3IoKS5maW5kRmllbGRCeU5hbWUoImRhdGEiKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAiZGF0YTogXCJ0ZXN0IGRhdGFcIlxuIiwKKyAgICAgIFRleHRGb3JtYXQucHJpbnRGaWVsZFRvU3RyaW5nKGRhdGFGaWVsZCwgInRlc3QgZGF0YSIpKTsKKworICAgIGZpbmFsIEZpZWxkRGVzY3JpcHRvciBvcHRpb25hbEZpZWxkID0KKyAgICAgIFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpLnNldEJiKDQyKS5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHtcbiAgYmI6IDQyXG59XG4iLAorICAgICAgVGV4dEZvcm1hdC5wcmludEZpZWxkVG9TdHJpbmcob3B0aW9uYWxGaWVsZCwgdmFsdWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgdG8gY29uc3RydWN0IGEgQnl0ZVN0cmluZyBmcm9tIGEgU3RyaW5nIGNvbnRhaW5pbmcgb25seSA4LWJpdAorICAgKiBjaGFyYWN0ZXJzLiAgVGhlIGNoYXJhY3RlcnMgYXJlIGNvbnZlcnRlZCBkaXJlY3RseSB0byBieXRlcywgKm5vdCoKKyAgICogZW5jb2RlZCB1c2luZyBVVEYtOC4KKyAgICovCisgIHByaXZhdGUgQnl0ZVN0cmluZyBieXRlcyhTdHJpbmcgc3RyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gQnl0ZVN0cmluZy5jb3B5RnJvbShzdHIuZ2V0Qnl0ZXMoIklTTy04ODU5LTEiKSk7CisgIH0KKworICAvKioKKyAgICogSGVscGVyIHRvIGNvbnN0cnVjdCBhIEJ5dGVTdHJpbmcgZnJvbSBhIGJ1bmNoIG9mIGJ5dGVzLiAgVGhlIGlucHV0cyBhcmUKKyAgICogYWN0dWFsbHkgaW50cyBzbyB0aGF0IEkgY2FuIHVzZSBoZXggbm90YXRpb24gYW5kIG5vdCBnZXQgc3R1cGlkIGVycm9ycworICAgKiBhYm91dCBwcmVjaXNpb24uCisgICAqLworICBwcml2YXRlIEJ5dGVTdHJpbmcgYnl0ZXMoaW50Li4uIGJ5dGVzQXNJbnRzKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXNBc0ludHMubGVuZ3RoXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzQXNJbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBieXRlc1tpXSA9IChieXRlKSBieXRlc0FzSW50c1tpXTsKKyAgICB9CisgICAgcmV0dXJuIEJ5dGVTdHJpbmcuY29weUZyb20oYnl0ZXMpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFByaW50RXhvdGljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWVzc2FnZSBtZXNzYWdlID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQorICAgICAgLy8gU2lnbmVkIHZzLiB1bnNpZ25lZCBudW1iZXJzLgorICAgICAgLmFkZFJlcGVhdGVkSW50MzIgKC0xKQorICAgICAgLmFkZFJlcGVhdGVkVWludDMyKC0xKQorICAgICAgLmFkZFJlcGVhdGVkSW50NjQgKC0xKQorICAgICAgLmFkZFJlcGVhdGVkVWludDY0KC0xKQorCisgICAgICAuYWRkUmVwZWF0ZWRJbnQzMiAoMSAgPDwgMzEpCisgICAgICAuYWRkUmVwZWF0ZWRVaW50MzIoMSAgPDwgMzEpCisgICAgICAuYWRkUmVwZWF0ZWRJbnQ2NCAoMUwgPDwgNjMpCisgICAgICAuYWRkUmVwZWF0ZWRVaW50NjQoMUwgPDwgNjMpCisKKyAgICAgIC8vIEZsb2F0cyBvZiB2YXJpb3VzIHByZWNpc2lvbnMgYW5kIGV4cG9uZW50cy4KKyAgICAgIC5hZGRSZXBlYXRlZERvdWJsZSgxMjMpCisgICAgICAuYWRkUmVwZWF0ZWREb3VibGUoMTIzLjUpCisgICAgICAuYWRkUmVwZWF0ZWREb3VibGUoMC4xMjUpCisgICAgICAuYWRkUmVwZWF0ZWREb3VibGUoLjEyNSkKKyAgICAgIC5hZGRSZXBlYXRlZERvdWJsZSgtLjEyNSkKKyAgICAgIC5hZGRSZXBlYXRlZERvdWJsZSgxMjNlMTUpCisgICAgICAuYWRkUmVwZWF0ZWREb3VibGUoMTIzZTE1KQorICAgICAgLmFkZFJlcGVhdGVkRG91YmxlKC0xLjIzZS0xNykKKyAgICAgIC5hZGRSZXBlYXRlZERvdWJsZSguMjNlMTcpCisgICAgICAuYWRkUmVwZWF0ZWREb3VibGUoLTIzZTE1KQorICAgICAgLmFkZFJlcGVhdGVkRG91YmxlKDEyMy41ZTIwKQorICAgICAgLmFkZFJlcGVhdGVkRG91YmxlKDEyMy41ZS0yMCkKKyAgICAgIC5hZGRSZXBlYXRlZERvdWJsZSgxMjMuNDU2Nzg5KQorICAgICAgLmFkZFJlcGVhdGVkRG91YmxlKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkKKyAgICAgIC5hZGRSZXBlYXRlZERvdWJsZShEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpCisgICAgICAuYWRkUmVwZWF0ZWREb3VibGUoRG91YmxlLk5hTikKKworICAgICAgLy8gU3RyaW5ncyBhbmQgYnl0ZXMgdGhhdCBuZWVkaW5nIGVzY2FwaW5nLgorICAgICAgLmFkZFJlcGVhdGVkU3RyaW5nKCJcMFwwMDFcMDA3XGJcZlxuXHJcdFwwMTNcXFwnXCJcdTEyMzQiKQorICAgICAgLmFkZFJlcGVhdGVkQnl0ZXMoYnl0ZXMoIlwwXDAwMVwwMDdcYlxmXG5cclx0XDAxM1xcXCdcIlx1MDBmZSIpKQorICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRFcXVhbHMoY2Fub25pY2FsRXhvdGljVGV4dCwgbWVzc2FnZS50b1N0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQcmludE1lc3NhZ2VTZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWVzc2FnZVNldCBtZXNzYWdlU2V0ID0KKyAgICAgIFRlc3RNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKAorICAgICAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uLAorICAgICAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5uZXdCdWlsZGVyKCkuc2V0SSgxMjMpLmJ1aWxkKCkpCisgICAgICAgIC5zZXRFeHRlbnNpb24oCisgICAgICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLm1lc3NhZ2VTZXRFeHRlbnNpb24sCisgICAgICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLm5ld0J1aWxkZXIoKS5zZXRTdHIoImZvbyIpLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2VTZXRUZXh0LCBtZXNzYWdlU2V0LnRvU3RyaW5nKCkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKGFsbEZpZWxkc1NldFRleHQsIGJ1aWxkZXIpOworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldChidWlsZGVyLmJ1aWxkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlUmVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZShuZXcgU3RyaW5nUmVhZGVyKGFsbEZpZWxkc1NldFRleHQpLCBidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQoYnVpbGRlci5idWlsZCgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZShhbGxFeHRlbnNpb25zU2V0VGV4dCwKKyAgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCksCisgICAgICAgICAgICAgICAgICAgICBidWlsZGVyKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxFeHRlbnNpb25zU2V0KGJ1aWxkZXIuYnVpbGQoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VDb21wYXRpYmlsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3RyaW5nIG9yaWdpbmFsID0gInJlcGVhdGVkX2Zsb2F0OiBpbmZcbiIgKworICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9mbG9hdDogLWluZlxuIiArCisgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkX2Zsb2F0OiBuYW5cbiIgKworICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9mbG9hdDogaW5mZlxuIiArCisgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkX2Zsb2F0OiAtaW5mZlxuIiArCisgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkX2Zsb2F0OiBuYW5mXG4iICsKKyAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMGZcbiIgKworICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9mbG9hdDogaW5maW5pdHlmXG4iICsKKyAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZmxvYXQ6IC1JbmZpbml0eWZcbiIgKworICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9kb3VibGU6IGluZmluaXR5XG4iICsKKyAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZG91YmxlOiAtaW5maW5pdHlcbiIgKworICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9kb3VibGU6IG5hblxuIjsKKyAgICBTdHJpbmcgY2Fub25pY2FsID0gICJyZXBlYXRlZF9mbG9hdDogSW5maW5pdHlcbiIgKworICAgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkX2Zsb2F0OiAtSW5maW5pdHlcbiIgKworICAgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkX2Zsb2F0OiBOYU5cbiIgKworICAgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkX2Zsb2F0OiBJbmZpbml0eVxuIiArCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZmxvYXQ6IC1JbmZpbml0eVxuIiArCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZmxvYXQ6IE5hTlxuIiArCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMFxuIiArCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZmxvYXQ6IEluZmluaXR5XG4iICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9mbG9hdDogLUluZmluaXR5XG4iICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9kb3VibGU6IEluZmluaXR5XG4iICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9kb3VibGU6IC1JbmZpbml0eVxuIiArCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWRfZG91YmxlOiBOYU5cbiI7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZShvcmlnaW5hbCwgYnVpbGRlcik7CisgICAgYXNzZXJ0RXF1YWxzKGNhbm9uaWNhbCwgYnVpbGRlci5idWlsZCgpLnRvU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlRXhvdGljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZShleG90aWNUZXh0LCBidWlsZGVyKTsKKworICAgIC8vIFRvbyBsYXp5IHRvIGNoZWNrIHRoaW5ncyBpbmRpdmlkdWFsbHkuICBEb24ndCB0cnkgdG8gZGVidWcgdGhpcworICAgIC8vIGlmIHRlc3RQcmludEV4b3RpYygpIGlzIGZhaWxpbmcuCisgICAgYXNzZXJ0RXF1YWxzKGNhbm9uaWNhbEV4b3RpY1RleHQsIGJ1aWxkZXIuYnVpbGQoKS50b1N0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU1lc3NhZ2VTZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSA9IEV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CisgICAgZXh0ZW5zaW9uUmVnaXN0cnkuYWRkKFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uKTsKKyAgICBleHRlbnNpb25SZWdpc3RyeS5hZGQoVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLm1lc3NhZ2VTZXRFeHRlbnNpb24pOworCisgICAgVGVzdE1lc3NhZ2VTZXQuQnVpbGRlciBidWlsZGVyID0gVGVzdE1lc3NhZ2VTZXQubmV3QnVpbGRlcigpOworICAgIFRleHRGb3JtYXQubWVyZ2UobWVzc2FnZVNldFRleHQsIGV4dGVuc2lvblJlZ2lzdHJ5LCBidWlsZGVyKTsKKyAgICBUZXN0TWVzc2FnZVNldCBtZXNzYWdlU2V0ID0gYnVpbGRlci5idWlsZCgpOworCisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlU2V0Lmhhc0V4dGVuc2lvbigKKyAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbWVzc2FnZVNldC5nZXRFeHRlbnNpb24oCisgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubWVzc2FnZVNldEV4dGVuc2lvbikuZ2V0SSgpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2VTZXQuaGFzRXh0ZW5zaW9uKAorICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLm1lc3NhZ2VTZXRFeHRlbnNpb24pKTsKKyAgICBhc3NlcnRFcXVhbHMoImZvbyIsIG1lc3NhZ2VTZXQuZ2V0RXh0ZW5zaW9uKAorICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLm1lc3NhZ2VTZXRFeHRlbnNpb24pLmdldFN0cigpKTsKKworICAgIGJ1aWxkZXIgPSBUZXN0TWVzc2FnZVNldC5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZShtZXNzYWdlU2V0VGV4dFdpdGhSZXBlYXRlZEV4dGVuc2lvbiwgZXh0ZW5zaW9uUmVnaXN0cnksCisgICAgICAgIGJ1aWxkZXIpOworICAgIG1lc3NhZ2VTZXQgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbWVzc2FnZVNldC5nZXRFeHRlbnNpb24oCisgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubWVzc2FnZVNldEV4dGVuc2lvbikuZ2V0SSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU1lc3NhZ2VTZXRXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRXh0ZW5zaW9uUmVnaXN0cnkgZXh0ZW5zaW9uUmVnaXN0cnkgPSBFeHRlbnNpb25SZWdpc3RyeS5uZXdJbnN0YW5jZSgpOworICAgIGV4dGVuc2lvblJlZ2lzdHJ5LmFkZChUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubWVzc2FnZVNldEV4dGVuc2lvbik7CisgICAgZXh0ZW5zaW9uUmVnaXN0cnkuYWRkKFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMi5tZXNzYWdlU2V0RXh0ZW5zaW9uKTsKKworICAgIFRlc3RNZXNzYWdlU2V0LkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKTsKKyAgICBwYXJzZXJXaXRoT3ZlcndyaXRlRm9yYmlkZGVuLm1lcmdlKAorICAgICAgICBtZXNzYWdlU2V0VGV4dCwgZXh0ZW5zaW9uUmVnaXN0cnksIGJ1aWxkZXIpOworICAgIFRlc3RNZXNzYWdlU2V0IG1lc3NhZ2VTZXQgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbWVzc2FnZVNldC5nZXRFeHRlbnNpb24oCisgICAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uKS5nZXRJKCkpOworICAgIGFzc2VydEVxdWFscygiZm9vIiwgbWVzc2FnZVNldC5nZXRFeHRlbnNpb24oCisgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIubWVzc2FnZVNldEV4dGVuc2lvbikuZ2V0U3RyKCkpOworCisgICAgYnVpbGRlciA9IFRlc3RNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKTsKKyAgICB0cnkgeworICAgICAgcGFyc2VyV2l0aE92ZXJ3cml0ZUZvcmJpZGRlbi5tZXJnZSgKKyAgICAgICAgICBtZXNzYWdlU2V0VGV4dFdpdGhSZXBlYXRlZEV4dGVuc2lvbiwgZXh0ZW5zaW9uUmVnaXN0cnksIGJ1aWxkZXIpOworICAgICAgZmFpbCgiZXhwZWN0ZWQgcGFyc2UgZXhjZXB0aW9uIik7CisgICAgfSBjYXRjaCAoVGV4dEZvcm1hdC5QYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIjY6MTogTm9uLXJlcGVhdGVkIGZpZWxkICIKKyAgICAgICAgICArICJcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlX3NldF9leHRlbnNpb25cIiIKKyAgICAgICAgICArICIgY2Fubm90IGJlIG92ZXJ3cml0dGVuLiIsCisgICAgICAgICAgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU51bWVyaWNFbnVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZSgib3B0aW9uYWxfbmVzdGVkX2VudW06IDIiLCBidWlsZGVyKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFSLCBidWlsZGVyLmdldE9wdGlvbmFsTmVzdGVkRW51bSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUFuZ2xlQnJhY2tldHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKCJPcHRpb25hbEdyb3VwOiA8IGE6IDEgPiIsIGJ1aWxkZXIpOworICAgIGFzc2VydFRydWUoYnVpbGRlci5oYXNPcHRpb25hbEdyb3VwKCkpOworICAgIGFzc2VydEVxdWFscygxLCBidWlsZGVyLmdldE9wdGlvbmFsR3JvdXAoKS5nZXRBKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlQ29tbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRleHRGb3JtYXQubWVyZ2UoCisgICAgICAiIyB0aGlzIGlzIGEgY29tbWVudFxuIiArCisgICAgICAib3B0aW9uYWxfaW50MzI6IDEgICMgYW5vdGhlciBjb21tZW50XG4iICsKKyAgICAgICJvcHRpb25hbF9pbnQ2NDogMlxuIiArCisgICAgICAiIyBFT0YgY29tbWVudCIsIGJ1aWxkZXIpOworICAgIGFzc2VydEVxdWFscygxLCBidWlsZGVyLmdldE9wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGJ1aWxkZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRQYXJzZUVycm9yKFN0cmluZyBlcnJvciwgU3RyaW5nIHRleHQpIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC5tZXJnZSh0ZXh0LCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBidWlsZGVyKTsKKyAgICAgIGZhaWwoIkV4cGVjdGVkIHBhcnNlIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChUZXh0Rm9ybWF0LlBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgIGFzc2VydEVxdWFscyhlcnJvciwgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKyAgfQorCisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydFBhcnNlRXJyb3JXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKFN0cmluZyBlcnJvciwKKyAgICAgIFN0cmluZyB0ZXh0KSB7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgdHJ5IHsKKyAgICAgIHBhcnNlcldpdGhPdmVyd3JpdGVGb3JiaWRkZW4ubWVyZ2UoCisgICAgICAgICAgdGV4dCwgVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSwgYnVpbGRlcik7CisgICAgICBmYWlsKCJFeHBlY3RlZCBwYXJzZSBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoVGV4dEZvcm1hdC5QYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRFcXVhbHMoZXJyb3IsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIFRlc3RBbGxUeXBlcyBhc3NlcnRQYXJzZVN1Y2Nlc3NXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKAorICAgICAgU3RyaW5nIHRleHQpIHRocm93cyBUZXh0Rm9ybWF0LlBhcnNlRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBwYXJzZXJXaXRoT3ZlcndyaXRlRm9yYmlkZGVuLm1lcmdlKAorICAgICAgICB0ZXh0LCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBidWlsZGVyKTsKKyAgICByZXR1cm4gYnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlRXJyb3JzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0UGFyc2VFcnJvcigKKyAgICAgICIxOjE2OiBFeHBlY3RlZCBcIjpcIi4iLAorICAgICAgIm9wdGlvbmFsX2ludDMyIDEyMyIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToyMzogRXhwZWN0ZWQgaWRlbnRpZmllci4gRm91bmQgJz8nIiwKKyAgICAgICJvcHRpb25hbF9uZXN0ZWRfZW51bTogPyIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToxODogQ291bGRuJ3QgcGFyc2UgaW50ZWdlcjogTnVtYmVyIG11c3QgYmUgcG9zaXRpdmU6IC0xIiwKKyAgICAgICJvcHRpb25hbF91aW50MzI6IC0xIik7CisgICAgYXNzZXJ0UGFyc2VFcnJvcigKKyAgICAgICIxOjE3OiBDb3VsZG4ndCBwYXJzZSBpbnRlZ2VyOiBOdW1iZXIgb3V0IG9mIHJhbmdlIGZvciAzMi1iaXQgc2lnbmVkICIgKworICAgICAgICAiaW50ZWdlcjogODIzMDE0ODEyOTA4NDkwMTIzODUyMzAxNTciLAorICAgICAgIm9wdGlvbmFsX2ludDMyOiA4MjMwMTQ4MTI5MDg0OTAxMjM4NTIzMDE1NyIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToxNjogRXhwZWN0ZWQgXCJ0cnVlXCIgb3IgXCJmYWxzZVwiLiIsCisgICAgICAib3B0aW9uYWxfYm9vbDogbWF5YmUiKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MTY6IEV4cGVjdGVkIFwidHJ1ZVwiIG9yIFwiZmFsc2VcIi4iLAorICAgICAgIm9wdGlvbmFsX2Jvb2w6IDIiKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MTg6IEV4cGVjdGVkIHN0cmluZy4iLAorICAgICAgIm9wdGlvbmFsX3N0cmluZzogMTIzIik7CisgICAgYXNzZXJ0UGFyc2VFcnJvcigKKyAgICAgICIxOjE4OiBTdHJpbmcgbWlzc2luZyBlbmRpbmcgcXVvdGUuIiwKKyAgICAgICJvcHRpb25hbF9zdHJpbmc6IFwidWVvYXVhb2UiKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MTg6IFN0cmluZyBtaXNzaW5nIGVuZGluZyBxdW90ZS4iLAorICAgICAgIm9wdGlvbmFsX3N0cmluZzogXCJ1ZW9hdWFvZVxuIiArCisgICAgICAib3B0aW9uYWxfaW50MzI6IDEyMyIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToxODogSW52YWxpZCBlc2NhcGUgc2VxdWVuY2U6ICdcXHonIiwKKyAgICAgICJvcHRpb25hbF9zdHJpbmc6IFwiXFx6XCIiKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MTg6IFN0cmluZyBtaXNzaW5nIGVuZGluZyBxdW90ZS4iLAorICAgICAgIm9wdGlvbmFsX3N0cmluZzogXCJ1ZW9hdWFvZVxuIiArCisgICAgICAib3B0aW9uYWxfaW50MzI6IDEyMyIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToyOiBFeHRlbnNpb24gXCJub3N1Y2hleHRcIiBub3QgZm91bmQgaW4gdGhlIEV4dGVuc2lvblJlZ2lzdHJ5LiIsCisgICAgICAiW25vc3VjaGV4dF06IDEyMyIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToyMDogRXh0ZW5zaW9uIFwicHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXCIgZG9lcyAiICsKKyAgICAgICAgIm5vdCBleHRlbmQgbWVzc2FnZSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIuIiwKKyAgICAgICJbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXTogMTIzIik7CisgICAgYXNzZXJ0UGFyc2VFcnJvcigKKyAgICAgICIxOjE6IE1lc3NhZ2UgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiIGhhcyBubyBmaWVsZCAiICsKKyAgICAgICAgIm5hbWVkIFwibm9zdWNoZmllbGRcIi4iLAorICAgICAgIm5vc3VjaGZpZWxkOiAxMjMiKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MjE6IEV4cGVjdGVkIFwiPlwiLiIsCisgICAgICAiT3B0aW9uYWxHcm91cCA8IGE6IDEiKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MjM6IEVudW0gdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtXCIgaGFzIG5vICIgKworICAgICAgICAidmFsdWUgbmFtZWQgXCJOT19TVUNIX1ZBTFVFXCIuIiwKKyAgICAgICJvcHRpb25hbF9uZXN0ZWRfZW51bTogTk9fU1VDSF9WQUxVRSIpOworICAgIGFzc2VydFBhcnNlRXJyb3IoCisgICAgICAiMToyMzogRW51bSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW1cIiBoYXMgbm8gIiArCisgICAgICAgICJ2YWx1ZSB3aXRoIG51bWJlciAxMjMuIiwKKyAgICAgICJvcHRpb25hbF9uZXN0ZWRfZW51bTogMTIzIik7CisKKyAgICAvLyBEZWxpbWl0ZXJzIG11c3QgbWF0Y2guCisgICAgYXNzZXJ0UGFyc2VFcnJvcigKKyAgICAgICIxOjIyOiBFeHBlY3RlZCBpZGVudGlmaWVyLiBGb3VuZCAnfSciLAorICAgICAgIk9wdGlvbmFsR3JvdXAgPCBhOiAxIH0iKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yKAorICAgICAgIjE6MjI6IEV4cGVjdGVkIGlkZW50aWZpZXIuIEZvdW5kICc+JyIsCisgICAgICAiT3B0aW9uYWxHcm91cCB7IGE6IDEgPiIpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gRXNjYXBlIHNlcXVlbmNlcy4KKyAgICBhc3NlcnRFcXVhbHMoIlxcMDAwXFwwMDFcXGFcXGJcXGZcXG5cXHJcXHRcXHZcXFxcXFwnXFxcIlxcMTc3IiwKKyAgICAgIFRleHRGb3JtYXQuZXNjYXBlQnl0ZXMoYnl0ZXMoIlwwXDAwMVwwMDdcYlxmXG5cclx0XDAxM1xcXCdcIlwxNzciKSkpOworICAgIGFzc2VydEVxdWFscygiXFwwMDBcXDAwMVxcYVxcYlxcZlxcblxcclxcdFxcdlxcXFxcXCdcXFwiXFwxNzciLAorICAgICAgVGV4dEZvcm1hdC5lc2NhcGVUZXh0KCJcMFwwMDFcMDA3XGJcZlxuXHJcdFwwMTNcXFwnXCJcMTc3IikpOworICAgIGFzc2VydEVxdWFscyhieXRlcygiXDBcMDAxXDAwN1xiXGZcblxyXHRcMDEzXFxcJ1wiIiksCisgICAgICBUZXh0Rm9ybWF0LnVuZXNjYXBlQnl0ZXMoIlxcMDAwXFwwMDFcXGFcXGJcXGZcXG5cXHJcXHRcXHZcXFxcXFwnXFxcIiIpKTsKKyAgICBhc3NlcnRFcXVhbHMoIlwwXDAwMVwwMDdcYlxmXG5cclx0XDAxM1xcXCdcIiIsCisgICAgICBUZXh0Rm9ybWF0LnVuZXNjYXBlVGV4dCgiXFwwMDBcXDAwMVxcYVxcYlxcZlxcblxcclxcdFxcdlxcXFxcXCdcXFwiIikpOworICAgIGFzc2VydEVxdWFscyhrRXNjYXBlVGVzdFN0cmluZ0VzY2FwZWQsCisgICAgICBUZXh0Rm9ybWF0LmVzY2FwZVRleHQoa0VzY2FwZVRlc3RTdHJpbmcpKTsKKyAgICBhc3NlcnRFcXVhbHMoa0VzY2FwZVRlc3RTdHJpbmcsCisgICAgICBUZXh0Rm9ybWF0LnVuZXNjYXBlVGV4dChrRXNjYXBlVGVzdFN0cmluZ0VzY2FwZWQpKTsKKworICAgIC8vIFVuaWNvZGUgaGFuZGxpbmcuCisgICAgYXNzZXJ0RXF1YWxzKCJcXDM0MVxcMjEwXFwyNjQiLCBUZXh0Rm9ybWF0LmVzY2FwZVRleHQoIlx1MTIzNCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoIlxcMzQxXFwyMTBcXDI2NCIsCisgICAgICAgICAgICAgICAgIFRleHRGb3JtYXQuZXNjYXBlQnl0ZXMoYnl0ZXMoMHhlMSwgMHg4OCwgMHhiNCkpKTsKKyAgICBhc3NlcnRFcXVhbHMoIlx1MTIzNCIsIFRleHRGb3JtYXQudW5lc2NhcGVUZXh0KCJcXDM0MVxcMjEwXFwyNjQiKSk7CisgICAgYXNzZXJ0RXF1YWxzKGJ5dGVzKDB4ZTEsIDB4ODgsIDB4YjQpLAorICAgICAgICAgICAgICAgICBUZXh0Rm9ybWF0LnVuZXNjYXBlQnl0ZXMoIlxcMzQxXFwyMTBcXDI2NCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoIlx1MTIzNCIsIFRleHRGb3JtYXQudW5lc2NhcGVUZXh0KCJcXHhlMVxceDg4XFx4YjQiKSk7CisgICAgYXNzZXJ0RXF1YWxzKGJ5dGVzKDB4ZTEsIDB4ODgsIDB4YjQpLAorICAgICAgICAgICAgICAgICBUZXh0Rm9ybWF0LnVuZXNjYXBlQnl0ZXMoIlxceGUxXFx4ODhcXHhiNCIpKTsKKworICAgIC8vIEhhbmRsaW5nIG9mIHN0cmluZ3Mgd2l0aCB1bmVzY2FwZWQgVW5pY29kZSBjaGFyYWN0ZXJzID4gMjU1LgorICAgIGZpbmFsIFN0cmluZyB6aCA9ICJcdTk5OTlcdTZlMmZcdTRlMGFcdTZkNzdcdWQ4NGZcdWRmODBcdThjNTBcdTkyODBcdTg4NGMiOworICAgIEJ5dGVTdHJpbmcgemhCeXRlU3RyaW5nID0gQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoemgpOworICAgIGFzc2VydEVxdWFscyh6aEJ5dGVTdHJpbmcsIFRleHRGb3JtYXQudW5lc2NhcGVCeXRlcyh6aCkpOworCisgICAgLy8gRXJyb3JzLgorICAgIHRyeSB7CisgICAgICBUZXh0Rm9ybWF0LnVuZXNjYXBlVGV4dCgiXFx4Iik7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKFRleHRGb3JtYXQuSW52YWxpZEVzY2FwZVNlcXVlbmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIHN1Y2Nlc3MKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC51bmVzY2FwZVRleHQoIlxceiIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChUZXh0Rm9ybWF0LkludmFsaWRFc2NhcGVTZXF1ZW5jZUV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzdWNjZXNzCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIFRleHRGb3JtYXQudW5lc2NhcGVUZXh0KCJcXCIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChUZXh0Rm9ybWF0LkludmFsaWRFc2NhcGVTZXF1ZW5jZUV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzdWNjZXNzCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlSW50ZWdlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEVxdWFscyggICAgICAgICAgMCwgVGV4dEZvcm1hdC5wYXJzZUludDMyKCAgICAgICAgICAiMCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoICAgICAgICAgIDEsIFRleHRGb3JtYXQucGFyc2VJbnQzMiggICAgICAgICAgIjEiKSk7CisgICAgYXNzZXJ0RXF1YWxzKCAgICAgICAgIC0xLCBUZXh0Rm9ybWF0LnBhcnNlSW50MzIoICAgICAgICAgIi0xIikpOworICAgIGFzc2VydEVxdWFscyggICAgICAxMjM0NSwgVGV4dEZvcm1hdC5wYXJzZUludDMyKCAgICAgICIxMjM0NSIpKTsKKyAgICBhc3NlcnRFcXVhbHMoICAgICAtMTIzNDUsIFRleHRGb3JtYXQucGFyc2VJbnQzMiggICAgICItMTIzNDUiKSk7CisgICAgYXNzZXJ0RXF1YWxzKCAyMTQ3NDgzNjQ3LCBUZXh0Rm9ybWF0LnBhcnNlSW50MzIoICIyMTQ3NDgzNjQ3IikpOworICAgIGFzc2VydEVxdWFscygtMjE0NzQ4MzY0OCwgVGV4dEZvcm1hdC5wYXJzZUludDMyKCItMjE0NzQ4MzY0OCIpKTsKKworICAgIGFzc2VydEVxdWFscyggICAgICAgICAgICAgICAgMCwgVGV4dEZvcm1hdC5wYXJzZVVJbnQzMiggICAgICAgICAiMCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoICAgICAgICAgICAgICAgIDEsIFRleHRGb3JtYXQucGFyc2VVSW50MzIoICAgICAgICAgIjEiKSk7CisgICAgYXNzZXJ0RXF1YWxzKCAgICAgICAgICAgIDEyMzQ1LCBUZXh0Rm9ybWF0LnBhcnNlVUludDMyKCAgICAgIjEyMzQ1IikpOworICAgIGFzc2VydEVxdWFscyggICAgICAgMjE0NzQ4MzY0NywgVGV4dEZvcm1hdC5wYXJzZVVJbnQzMigiMjE0NzQ4MzY0NyIpKTsKKyAgICBhc3NlcnRFcXVhbHMoKGludCkgMjE0NzQ4MzY0OEwsIFRleHRGb3JtYXQucGFyc2VVSW50MzIoIjIxNDc0ODM2NDgiKSk7CisgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDQyOTQ5NjcyOTVMLCBUZXh0Rm9ybWF0LnBhcnNlVUludDMyKCI0Mjk0OTY3Mjk1IikpOworCisgICAgYXNzZXJ0RXF1YWxzKCAgICAgICAgICAwTCwgVGV4dEZvcm1hdC5wYXJzZUludDY0KCAgICAgICAgICAiMCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoICAgICAgICAgIDFMLCBUZXh0Rm9ybWF0LnBhcnNlSW50NjQoICAgICAgICAgICIxIikpOworICAgIGFzc2VydEVxdWFscyggICAgICAgICAtMUwsIFRleHRGb3JtYXQucGFyc2VJbnQ2NCggICAgICAgICAiLTEiKSk7CisgICAgYXNzZXJ0RXF1YWxzKCAgICAgIDEyMzQ1TCwgVGV4dEZvcm1hdC5wYXJzZUludDY0KCAgICAgICIxMjM0NSIpKTsKKyAgICBhc3NlcnRFcXVhbHMoICAgICAtMTIzNDVMLCBUZXh0Rm9ybWF0LnBhcnNlSW50NjQoICAgICAiLTEyMzQ1IikpOworICAgIGFzc2VydEVxdWFscyggMjE0NzQ4MzY0N0wsIFRleHRGb3JtYXQucGFyc2VJbnQ2NCggIjIxNDc0ODM2NDciKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0yMTQ3NDgzNjQ4TCwgVGV4dEZvcm1hdC5wYXJzZUludDY0KCItMjE0NzQ4MzY0OCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoIDQyOTQ5NjcyOTVMLCBUZXh0Rm9ybWF0LnBhcnNlSW50NjQoICI0Mjk0OTY3Mjk1IikpOworICAgIGFzc2VydEVxdWFscyggNDI5NDk2NzI5NkwsIFRleHRGb3JtYXQucGFyc2VJbnQ2NCggIjQyOTQ5NjcyOTYiKSk7CisgICAgYXNzZXJ0RXF1YWxzKDkyMjMzNzIwMzY4NTQ3NzU4MDdMLAorICAgICAgICAgICAgICAgICBUZXh0Rm9ybWF0LnBhcnNlSW50NjQoIjkyMjMzNzIwMzY4NTQ3NzU4MDciKSk7CisgICAgYXNzZXJ0RXF1YWxzKC05MjIzMzcyMDM2ODU0Nzc1ODA4TCwKKyAgICAgICAgICAgICAgICAgVGV4dEZvcm1hdC5wYXJzZUludDY0KCItOTIyMzM3MjAzNjg1NDc3NTgwOCIpKTsKKworICAgIGFzc2VydEVxdWFscyggICAgICAgICAgMEwsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoICAgICAgICAgICIwIikpOworICAgIGFzc2VydEVxdWFscyggICAgICAgICAgMUwsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoICAgICAgICAgICIxIikpOworICAgIGFzc2VydEVxdWFscyggICAgICAxMjM0NUwsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoICAgICAgIjEyMzQ1IikpOworICAgIGFzc2VydEVxdWFscyggMjE0NzQ4MzY0N0wsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoICIyMTQ3NDgzNjQ3IikpOworICAgIGFzc2VydEVxdWFscyggNDI5NDk2NzI5NUwsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoICI0Mjk0OTY3Mjk1IikpOworICAgIGFzc2VydEVxdWFscyggNDI5NDk2NzI5NkwsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoICI0Mjk0OTY3Mjk2IikpOworICAgIGFzc2VydEVxdWFscyg5MjIzMzcyMDM2ODU0Nzc1ODA3TCwKKyAgICAgICAgICAgICAgICAgVGV4dEZvcm1hdC5wYXJzZVVJbnQ2NCgiOTIyMzM3MjAzNjg1NDc3NTgwNyIpKTsKKyAgICBhc3NlcnRFcXVhbHMoLTkyMjMzNzIwMzY4NTQ3NzU4MDhMLAorICAgICAgICAgICAgICAgICBUZXh0Rm9ybWF0LnBhcnNlVUludDY0KCI5MjIzMzcyMDM2ODU0Nzc1ODA4IikpOworICAgIGFzc2VydEVxdWFscygtMUwsIFRleHRGb3JtYXQucGFyc2VVSW50NjQoIjE4NDQ2NzQ0MDczNzA5NTUxNjE1IikpOworCisgICAgLy8gSGV4CisgICAgYXNzZXJ0RXF1YWxzKDB4MTIzNGFiY2QsIFRleHRGb3JtYXQucGFyc2VJbnQzMigiMHgxMjM0YWJjZCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoLTB4MTIzNGFiY2QsIFRleHRGb3JtYXQucGFyc2VJbnQzMigiLTB4MTIzNGFiY2QiKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0xLCBUZXh0Rm9ybWF0LnBhcnNlVUludDY0KCIweGZmZmZmZmZmZmZmZmZmZmYiKSk7CisgICAgYXNzZXJ0RXF1YWxzKDB4N2ZmZmZmZmZmZmZmZmZmZkwsCisgICAgICAgICAgICAgICAgIFRleHRGb3JtYXQucGFyc2VJbnQ2NCgiMHg3ZmZmZmZmZmZmZmZmZmZmIikpOworCisgICAgLy8gT2N0YWwKKyAgICBhc3NlcnRFcXVhbHMoMDEyMzQ1NjcsIFRleHRGb3JtYXQucGFyc2VJbnQzMigiMDEyMzQ1NjciKSk7CisKKyAgICAvLyBPdXQtb2YtcmFuZ2UKKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC5wYXJzZUludDMyKCIyMTQ3NDgzNjQ4Iik7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzdWNjZXNzCisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIFRleHRGb3JtYXQucGFyc2VJbnQzMigiLTIxNDc0ODM2NDkiKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIHN1Y2Nlc3MKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC5wYXJzZVVJbnQzMigiNDI5NDk2NzI5NiIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2VzcworICAgIH0KKworICAgIHRyeSB7CisgICAgICBUZXh0Rm9ybWF0LnBhcnNlVUludDMyKCItMSIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2VzcworICAgIH0KKworICAgIHRyeSB7CisgICAgICBUZXh0Rm9ybWF0LnBhcnNlSW50NjQoIjkyMjMzNzIwMzY4NTQ3NzU4MDgiKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIHN1Y2Nlc3MKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC5wYXJzZUludDY0KCItOTIyMzM3MjAzNjg1NDc3NTgwOSIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2VzcworICAgIH0KKworICAgIHRyeSB7CisgICAgICBUZXh0Rm9ybWF0LnBhcnNlVUludDY0KCIxODQ0Njc0NDA3MzcwOTU1MTYxNiIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2VzcworICAgIH0KKworICAgIHRyeSB7CisgICAgICBUZXh0Rm9ybWF0LnBhcnNlVUludDY0KCItMSIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2VzcworICAgIH0KKworICAgIC8vIE5vdCBhIG51bWJlci4KKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC5wYXJzZUludDMyKCJhYmNkIik7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzdWNjZXNzCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmluYWwgU3RyaW5nIHpoID0gIlx1OTk5OVx1NmUyZlx1NGUwYVx1NmQ3N1x1ZDg0Zlx1ZGY4MFx1OGM1MFx1OTI4MFx1ODg0YyI7CisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgVGV4dEZvcm1hdC5tZXJnZSgib3B0aW9uYWxfc3RyaW5nOiBcIiIgKyB6aCArICJcIiIsIGJ1aWxkZXIpOworICAgIGFzc2VydEVxdWFscyh6aCwgYnVpbGRlci5nZXRPcHRpb25hbFN0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUxvbmdTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgbG9uZ1RleHQgPQorICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIgKworICAgICAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCI7CisKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKCJvcHRpb25hbF9zdHJpbmc6IFwiIiArIGxvbmdUZXh0ICsgIlwiIiwgYnVpbGRlcik7CisgICAgYXNzZXJ0RXF1YWxzKGxvbmdUZXh0LCBidWlsZGVyLmdldE9wdGlvbmFsU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlQm9vbGVhbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBnb29kVGV4dCA9CisgICAgICAgICJyZXBlYXRlZF9ib29sOiB0ICByZXBlYXRlZF9ib29sIDogMFxuIiArCisgICAgICAgICJyZXBlYXRlZF9ib29sIDpmIHJlcGVhdGVkX2Jvb2w6MSI7CisgICAgU3RyaW5nIGdvb2RUZXh0Q2Fub25pY2FsID0KKyAgICAgICAgInJlcGVhdGVkX2Jvb2w6IHRydWVcbiIgKworICAgICAgICAicmVwZWF0ZWRfYm9vbDogZmFsc2VcbiIgKworICAgICAgICAicmVwZWF0ZWRfYm9vbDogZmFsc2VcbiIgKworICAgICAgICAicmVwZWF0ZWRfYm9vbDogdHJ1ZVxuIjsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKGdvb2RUZXh0LCBidWlsZGVyKTsKKyAgICBhc3NlcnRFcXVhbHMoZ29vZFRleHRDYW5vbmljYWwsIGJ1aWxkZXIuYnVpbGQoKS50b1N0cmluZygpKTsKKworICAgIHRyeSB7CisgICAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBiYWRCdWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICAgIFRleHRGb3JtYXQubWVyZ2UoIm9wdGlvbmFsX2Jvb2w6MiIsIGJhZEJ1aWxkZXIpOworICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGFuIGV4Y2VwdGlvbi4iKTsKKyAgICB9IGNhdGNoIChUZXh0Rm9ybWF0LlBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIHN1Y2Nlc3MKKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJhZEJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgICAgVGV4dEZvcm1hdC5tZXJnZSgib3B0aW9uYWxfYm9vbDogZm9vIiwgYmFkQnVpbGRlcik7CisgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYW4gZXhjZXB0aW9uLiIpOworICAgIH0gY2F0Y2ggKFRleHRGb3JtYXQuUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgLy8gc3VjY2VzcworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUFkamFjZW50U3RyaW5nTGl0ZXJhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKCJvcHRpb25hbF9zdHJpbmc6IFwiZm9vXCIgJ2NvcmdlJyBcImdyYXVsdFwiIiwgYnVpbGRlcik7CisgICAgYXNzZXJ0RXF1YWxzKCJmb29jb3JnZWdyYXVsdCIsIGJ1aWxkZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UHJpbnRGaWVsZFZhbHVlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0UHJpbnRGaWVsZFZhbHVlKCJcIkhlbGxvXCIiLCAiSGVsbG8iLCAicmVwZWF0ZWRfc3RyaW5nIik7CisgICAgYXNzZXJ0UHJpbnRGaWVsZFZhbHVlKCIxMjMuMCIsICAxMjNmLCAicmVwZWF0ZWRfZmxvYXQiKTsKKyAgICBhc3NlcnRQcmludEZpZWxkVmFsdWUoIjEyMy4wIiwgIDEyM2QsICJyZXBlYXRlZF9kb3VibGUiKTsKKyAgICBhc3NlcnRQcmludEZpZWxkVmFsdWUoIjEyMyIsICAxMjMsICJyZXBlYXRlZF9pbnQzMiIpOworICAgIGFzc2VydFByaW50RmllbGRWYWx1ZSgiMTIzIiwgIDEyM0wsICJyZXBlYXRlZF9pbnQ2NCIpOworICAgIGFzc2VydFByaW50RmllbGRWYWx1ZSgidHJ1ZSIsICB0cnVlLCAicmVwZWF0ZWRfYm9vbCIpOworICAgIGFzc2VydFByaW50RmllbGRWYWx1ZSgiNDI5NDk2NzI5NSIsIDB4RkZGRkZGRkYsICJyZXBlYXRlZF91aW50MzIiKTsKKyAgICBhc3NlcnRQcmludEZpZWxkVmFsdWUoIjE4NDQ2NzQ0MDczNzA5NTUxNjE1IiwgIDB4RkZGRkZGRkZGRkZGRkZGRkwsCisgICAgICAgICJyZXBlYXRlZF91aW50NjQiKTsKKyAgICBhc3NlcnRQcmludEZpZWxkVmFsdWUoIlwiXFwwMDFcXDAwMlxcMDAzXCIiLAorICAgICAgICBCeXRlU3RyaW5nLmNvcHlGcm9tKG5ldyBieXRlW10gezEsIDIsIDN9KSwgInJlcGVhdGVkX2J5dGVzIik7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0UHJpbnRGaWVsZFZhbHVlKFN0cmluZyBleHBlY3QsIE9iamVjdCB2YWx1ZSwKKyAgICAgIFN0cmluZyBmaWVsZE5hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIFRleHRGb3JtYXQucHJpbnRGaWVsZFZhbHVlKAorICAgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZShmaWVsZE5hbWUpLAorICAgICAgICB2YWx1ZSwgc2IpOworICAgIGFzc2VydEVxdWFscyhleHBlY3QsIHNiLnRvU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNob3J0RGVidWdTdHJpbmcoKSB7CisgICAgYXNzZXJ0RXF1YWxzKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiA0MiB9IHJlcGVhdGVkX2ludDMyOiAxIgorICAgICAgICArICIgcmVwZWF0ZWRfdWludDMyOiAyIiwKKyAgICAgICAgVGV4dEZvcm1hdC5zaG9ydERlYnVnU3RyaW5nKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRSZXBlYXRlZEludDMyKDEpCisgICAgICAgICAgICAuYWRkUmVwZWF0ZWRVaW50MzIoMikKKyAgICAgICAgICAgIC5zZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkuc2V0QmIoNDIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNob3J0RGVidWdTdHJpbmdfdW5rbm93bigpIHsKKyAgICBhc3NlcnRFcXVhbHMoIjU6IDEgNTogMHgwMDAwMDAwMiA1OiAweDAwMDAwMDAwMDAwMDAwMDMgNTogXCI0XCIgNSB7IDEwOiA1IH0iCisgICAgICAgICsgIiA4OiAxIDg6IDIgODogMyAxNTogMTIzNzk4MTM4MTIxNzc4OTM1MjAgMTU6IDB4YWJjZDEyMzQgMTU6IgorICAgICAgICArICIgMHhhYmNkZWYxMjM0NTY3ODkwIiwKKyAgICAgICAgVGV4dEZvcm1hdC5zaG9ydERlYnVnU3RyaW5nKG1ha2VVbmtub3duRmllbGRTZXQoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFByaW50VG9Vbmljb2RlU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAib3B0aW9uYWxfc3RyaW5nOiBcImFiY1x1MzA0MmVmZ1wiXG4iICsKKyAgICAgICAgIm9wdGlvbmFsX2J5dGVzOiBcIlxcMzQzXFwyMDFcXDIwMlwiXG4iICsKKyAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJcdTMwOTNYWVpcIlxuIiwKKyAgICAgICAgVGV4dEZvcm1hdC5wcmludFRvVW5pY29kZVN0cmluZyhUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3B0aW9uYWxTdHJpbmcoImFiY1x1MzA0MmVmZyIpCisgICAgICAgICAgICAuc2V0T3B0aW9uYWxCeXRlcyhieXRlcygweGUzLCAweDgxLCAweDgyKSkKKyAgICAgICAgICAgIC5hZGRSZXBlYXRlZFN0cmluZygiXHUzMDkzWFlaIikKKyAgICAgICAgICAgIC5idWlsZCgpKSk7CisKKyAgICAvLyBEb3VibGUgcXVvdGVzIGFuZCBiYWNrc2xhc2hlcyBzaG91bGQgYmUgZXNjYXBlZAorICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgIm9wdGlvbmFsX3N0cmluZzogXCJhXFxcXGJjXFxcImVmXFxcImdcIlxuIiwKKyAgICAgICAgVGV4dEZvcm1hdC5wcmludFRvVW5pY29kZVN0cmluZyhUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3B0aW9uYWxTdHJpbmcoImFcXGJjXCJlZlwiZyIpCisgICAgICAgICAgICAuYnVpbGQoKSkpOworCisgICAgLy8gVGVzdCBlc2NhcGluZyByb3VuZHRyaXAKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJhXFxiY1xcXCJlZlwiZyIpCisgICAgICAgIC5idWlsZCgpOworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIFRleHRGb3JtYXQubWVyZ2UoVGV4dEZvcm1hdC5wcmludFRvVW5pY29kZVN0cmluZyhtZXNzYWdlKSwgYnVpbGRlcik7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UuZ2V0T3B0aW9uYWxTdHJpbmcoKSwgYnVpbGRlci5nZXRPcHRpb25hbFN0cmluZygpKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFByaW50VG9Vbmljb2RlU3RyaW5nV2l0aE5ld2xpbmVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTm8gbmV3bGluZXMgYXQgc3RhcnQgYW5kIGVuZAorICAgIGFzc2VydEVxdWFscygib3B0aW9uYWxfc3RyaW5nOiBcInRlc3QgbmV3bGluZXNcXG5cXG5pblxcbnN0cmluZ1wiXG4iLAorICAgICAgICBUZXh0Rm9ybWF0LnByaW50VG9Vbmljb2RlU3RyaW5nKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygidGVzdCBuZXdsaW5lc1xuXG5pblxuc3RyaW5nIikKKyAgICAgICAgICAgIC5idWlsZCgpKSk7CisKKyAgICAvLyBOZXdsaW5lcyBhdCBzdGFydCBhbmQgZW5kCisgICAgYXNzZXJ0RXF1YWxzKCJvcHRpb25hbF9zdHJpbmc6IFwiXFxudGVzdFxcbm5ld2xpbmVzXFxuXFxuaW5cXG5zdHJpbmdcXG5cIlxuIiwKKyAgICAgICAgVGV4dEZvcm1hdC5wcmludFRvVW5pY29kZVN0cmluZyhUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3B0aW9uYWxTdHJpbmcoIlxudGVzdFxubmV3bGluZXNcblxuaW5cbnN0cmluZ1xuIikKKyAgICAgICAgICAgIC5idWlsZCgpKSk7CisKKyAgICAvLyBTdHJpbmdzIHdpdGggMCwgMSBhbmQgMiBuZXdsaW5lcy4KKyAgICBhc3NlcnRFcXVhbHMoIm9wdGlvbmFsX3N0cmluZzogXCJcIlxuIiwKKyAgICAgICAgVGV4dEZvcm1hdC5wcmludFRvVW5pY29kZVN0cmluZyhUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3B0aW9uYWxTdHJpbmcoIiIpCisgICAgICAgICAgICAuYnVpbGQoKSkpOworICAgIGFzc2VydEVxdWFscygib3B0aW9uYWxfc3RyaW5nOiBcIlxcblwiXG4iLAorICAgICAgICBUZXh0Rm9ybWF0LnByaW50VG9Vbmljb2RlU3RyaW5nKFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiXG4iKQorICAgICAgICAgICAgLmJ1aWxkKCkpKTsKKyAgICBhc3NlcnRFcXVhbHMoIm9wdGlvbmFsX3N0cmluZzogXCJcXG5cXG5cIlxuIiwKKyAgICAgICAgVGV4dEZvcm1hdC5wcmludFRvVW5pY29kZVN0cmluZyhUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3B0aW9uYWxTdHJpbmcoIlxuXG4iKQorICAgICAgICAgICAgLmJ1aWxkKCkpKTsKKworICAgIC8vIFRlc3QgZXNjYXBpbmcgcm91bmR0cmlwCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRPcHRpb25hbFN0cmluZygiXG50ZXN0XG5uZXdsaW5lc1xuXG5pblxuc3RyaW5nXG4iKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKFRleHRGb3JtYXQucHJpbnRUb1VuaWNvZGVTdHJpbmcobWVzc2FnZSksIGJ1aWxkZXIpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmdldE9wdGlvbmFsU3RyaW5nKCksIGJ1aWxkZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UHJpbnRUb1VuaWNvZGVTdHJpbmdfdW5rbm93bigpIHsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICIxOiBcIlxcMzQzXFwyMDFcXDIwMlwiXG4iLAorICAgICAgICBUZXh0Rm9ybWF0LnByaW50VG9Vbmljb2RlU3RyaW5nKFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaWVsZCgxLAorICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWRkTGVuZ3RoRGVsaW1pdGVkKGJ5dGVzKDB4ZTMsIDB4ODEsIDB4ODIpKS5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCkpKTsKKyAgfQorCisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlTm9uUmVwZWF0ZWRGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRQYXJzZVN1Y2Nlc3NXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKAorICAgICAgICAicmVwZWF0ZWRfaW50MzI6IDFcbiIgKworICAgICAgICAicmVwZWF0ZWRfaW50MzI6IDJcbiIpOworICAgIGFzc2VydFBhcnNlU3VjY2Vzc1dpdGhPdmVyd3JpdGVGb3JiaWRkZW4oCisgICAgICAgICJSZXBlYXRlZEdyb3VwIHsgYTogMSB9XG4iICsKKyAgICAgICAgIlJlcGVhdGVkR3JvdXAgeyBhOiAyIH1cbiIpOworICAgIGFzc2VydFBhcnNlU3VjY2Vzc1dpdGhPdmVyd3JpdGVGb3JiaWRkZW4oCisgICAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiAxIH1cbiIgKworICAgICAgICAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgeyBiYjogMiB9XG4iKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yV2l0aE92ZXJ3cml0ZUZvcmJpZGRlbigKKyAgICAgICAgIjM6MTc6IE5vbi1yZXBlYXRlZCBmaWVsZCAiICsKKyAgICAgICAgIlwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLm9wdGlvbmFsX2ludDMyXCIgIiArCisgICAgICAgICJjYW5ub3QgYmUgb3ZlcndyaXR0ZW4uIiwKKyAgICAgICAgIm9wdGlvbmFsX2ludDMyOiAxXG4iICsKKyAgICAgICAgIm9wdGlvbmFsX2Jvb2w6IHRydWVcbiIgKworICAgICAgICAib3B0aW9uYWxfaW50MzI6IDFcbiIpOworICAgIGFzc2VydFBhcnNlRXJyb3JXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKAorICAgICAgICAiMjoxNzogTm9uLXJlcGVhdGVkIGZpZWxkICIgKworICAgICAgICAiXCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMub3B0aW9uYWxncm91cFwiICIgKworICAgICAgICAiY2Fubm90IGJlIG92ZXJ3cml0dGVuLiIsCisgICAgICAgICJPcHRpb25hbEdyb3VwIHsgYTogMSB9XG4iICsKKyAgICAgICAgIk9wdGlvbmFsR3JvdXAgeyB9XG4iKTsKKyAgICBhc3NlcnRQYXJzZUVycm9yV2l0aE92ZXJ3cml0ZUZvcmJpZGRlbigKKyAgICAgICAgIjI6MzM6IE5vbi1yZXBlYXRlZCBmaWVsZCAiICsKKyAgICAgICAgIlwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlXCIgIiArCisgICAgICAgICJjYW5ub3QgYmUgb3ZlcndyaXR0ZW4uIiwKKyAgICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsgfVxuIiArCisgICAgICAgICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiAzIH1cbiIpOworICAgIGFzc2VydFBhcnNlRXJyb3JXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKAorICAgICAgICAiMjoxNjogTm9uLXJlcGVhdGVkIGZpZWxkICIgKworICAgICAgICAiXCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuZGVmYXVsdF9pbnQzMlwiICIgKworICAgICAgICAiY2Fubm90IGJlIG92ZXJ3cml0dGVuLiIsCisgICAgICAgICJkZWZhdWx0X2ludDMyOiA0MVxuIiArICAvLyB0aGUgZGVmYXVsdCB2YWx1ZQorICAgICAgICAiZGVmYXVsdF9pbnQzMjogNDFcbiIpOworICAgIGFzc2VydFBhcnNlRXJyb3JXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKAorICAgICAgICAiMjoxNzogTm9uLXJlcGVhdGVkIGZpZWxkICIgKworICAgICAgICAiXCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuZGVmYXVsdF9zdHJpbmdcIiAiICsKKyAgICAgICAgImNhbm5vdCBiZSBvdmVyd3JpdHRlbi4iLAorICAgICAgICAiZGVmYXVsdF9zdHJpbmc6IFwienhjdlwiXG4iICsKKyAgICAgICAgImRlZmF1bHRfc3RyaW5nOiBcImFzZGZcIlxuIik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VTaG9ydFJlcGVhdGVkRm9ybU9mUmVwZWF0ZWRGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRQYXJzZVN1Y2Nlc3NXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKCJyZXBlYXRlZF9mb3JlaWduX2VudW06IFtGT1JFSUdOX0ZPTywgRk9SRUlHTl9CQVJdIik7CisgICAgYXNzZXJ0UGFyc2VTdWNjZXNzV2l0aE92ZXJ3cml0ZUZvcmJpZGRlbigicmVwZWF0ZWRfaW50MzI6IFsgMSwgMiBdXG4iKTsKKyAgICBhc3NlcnRQYXJzZVN1Y2Nlc3NXaXRoT3ZlcndyaXRlRm9yYmlkZGVuKCJSZXBlYXRlZEdyb3VwIFt7IGE6IDEgfSx7IGE6IDIgfV1cbiIpOworICAgIGFzc2VydFBhcnNlU3VjY2Vzc1dpdGhPdmVyd3JpdGVGb3JiaWRkZW4oInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIFt7IGJiOiAxIH0sIHsgYmI6IDIgfV1cbiIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlU2hvcnRSZXBlYXRlZEZvcm1PZk5vblJlcGVhdGVkRmllbGRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0UGFyc2VFcnJvcldpdGhPdmVyd3JpdGVGb3JiaWRkZW4oCisgICAgICAgICIxOjE3OiBDb3VsZG4ndCBwYXJzZSBpbnRlZ2VyOiBGb3IgaW5wdXQgc3RyaW5nOiBcIltcIiIsCisgICAgICAgICJvcHRpb25hbF9pbnQzMjogWzFdXG4iKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIHRlc3Qgb25lb2YKKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZUZXh0Rm9ybWF0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE9uZW9mMi5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKTsKKyAgICBUZXN0VXRpbC5zZXRPbmVvZihidWlsZGVyKTsKKyAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgVGVzdE9uZW9mMi5CdWlsZGVyIGRlc3QgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKTsKKyAgICBUZXh0Rm9ybWF0Lm1lcmdlKFRleHRGb3JtYXQucHJpbnRUb1VuaWNvZGVTdHJpbmcobWVzc2FnZSksIGRlc3QpOworICAgIFRlc3RVdGlsLmFzc2VydE9uZW9mU2V0KGRlc3QuYnVpbGQoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZPdmVyd3JpdGVGb3JiaWRkZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgaW5wdXQgPSAiZm9vX3N0cmluZzogXCJzdHJpbmd2YWx1ZVwiIGZvb19pbnQ6IDEyMyI7CisgICAgVGVzdE9uZW9mMi5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0T25lb2YyLm5ld0J1aWxkZXIoKTsKKyAgICB0cnkgeworICAgICAgcGFyc2VyV2l0aE92ZXJ3cml0ZUZvcmJpZGRlbi5tZXJnZSgKKyAgICAgICAgICBpbnB1dCwgVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSwgYnVpbGRlcik7CisgICAgICBmYWlsKCJFeHBlY3RlZCBwYXJzZSBleGNlcHRpb24uIik7CisgICAgfSBjYXRjaCAoVGV4dEZvcm1hdC5QYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICBhc3NlcnRFcXVhbHMoIjE6MzY6IEZpZWxkIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5mb29faW50XCIiCisgICAgICAgICAgICAgICAgICAgKyAiIGlzIHNwZWNpZmllZCBhbG9uZyB3aXRoIGZpZWxkIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5mb29fc3RyaW5nXCIsIgorICAgICAgICAgICAgICAgICAgICsgIiBhbm90aGVyIG1lbWJlciBvZiBvbmVvZiBcImZvb1wiLiIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZPdmVyd3JpdGVBbGxvd2VkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3RyaW5nIGlucHV0ID0gImZvb19zdHJpbmc6IFwic3RyaW5ndmFsdWVcIiBmb29faW50OiAxMjMiOworICAgIFRlc3RPbmVvZjIuQnVpbGRlciBidWlsZGVyID0gVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCk7CisgICAgZGVmYXVsdFBhcnNlci5tZXJnZShpbnB1dCwgVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSwgYnVpbGRlcik7CisgICAgLy8gT25seSB0aGUgbGFzdCB2YWx1ZSBzdGlja3MuCisgICAgVGVzdE9uZW9mMiBvbmVvZiA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRGYWxzZShvbmVvZi5oYXNGb29TdHJpbmcoKSk7CisgICAgYXNzZXJ0VHJ1ZShvbmVvZi5oYXNGb29JbnQoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Vua25vd25FbnVtVmFsdWVUZXN0LmphdmEgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRW51bVZhbHVlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmNDU5NzYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRW51bVZhbHVlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXh0Rm9ybWF0LlBhcnNlRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIHByb3RvcyB0aGF0IGtlZXAgdW5rbm93biBlbnVtIHZhbHVlcyByYXRoZXIgdGhhbiBkaXNjYXJkCisgKiB0aGVtIGFzIHVua25vd24gZmllbGRzLgorICovCitwdWJsaWMgY2xhc3MgVW5rbm93bkVudW1WYWx1ZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHB1YmxpYyB2b2lkIHRlc3RVbmtub3duRW51bVZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoNDMyMSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSg1NDMyKTsKKyAgICBidWlsZGVyLmFkZFBhY2tlZE5lc3RlZEVudW1WYWx1ZSg2NTQzKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDMyMSwgbWVzc2FnZS5nZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNTQzMiwgbWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU0MzIsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkuZ2V0KDApLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg2NTQzLCBtZXNzYWdlLmdldFBhY2tlZE5lc3RlZEVudW1WYWx1ZSgwKSk7CisgICAgLy8gUmV0dXJucyBVTlJFQ09HTklaRUQgaWYgYW4gZW51bSB0eXBlIGlzIHJlcXVlc3RlZC4KKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBtZXNzYWdlLmdldE9wdGlvbmFsTmVzdGVkRW51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCwgbWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBtZXNzYWdlLmdldFBhY2tlZE5lc3RlZEVudW0oMCkpOworICAgIAorICAgIC8vIFRlc3Qgc2VyaWFsaXphdGlvbiBhbmQgcGFyc2luZy4KKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBtZXNzYWdlLnRvQnl0ZVN0cmluZygpOworICAgIG1lc3NhZ2UgPSBUZXN0QWxsVHlwZXMucGFyc2VGcm9tKGRhdGEpOworICAgIGFzc2VydEVxdWFscyg0MzIxLCBtZXNzYWdlLmdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg1NDMyLCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoNTQzMiwgbWVzc2FnZS5nZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKS5nZXQoMCkuaW50VmFsdWUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDY1NDMsIG1lc3NhZ2UuZ2V0UGFja2VkTmVzdGVkRW51bVZhbHVlKDApKTsKKyAgICAvLyBSZXR1cm5zIFVOUkVDT0dOSVpFRCBpZiBhbiBlbnVtIHR5cGUgaXMgcmVxdWVzdGVkLgorICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQsIG1lc3NhZ2UuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQsIG1lc3NhZ2UuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKS5nZXQoMCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQsIG1lc3NhZ2UuZ2V0UGFja2VkTmVzdGVkRW51bSgwKSk7CisgICAgCisgICAgLy8gVGVzdCB0b0J1aWxkZXIoKS4KKyAgICBidWlsZGVyID0gbWVzc2FnZS50b0J1aWxkZXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDMyMSwgYnVpbGRlci5nZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNTQzMiwgYnVpbGRlci5nZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU0MzIsIGJ1aWxkZXIuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkuZ2V0KDApLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg2NTQzLCBidWlsZGVyLmdldFBhY2tlZE5lc3RlZEVudW1WYWx1ZSgwKSk7ICAgIAorICAgIC8vIFJldHVybnMgVU5SRUNPR05JWkVEIGlmIGFuIGVudW0gdHlwZSBpcyByZXF1ZXN0ZWQuCisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCwgYnVpbGRlci5nZXRPcHRpb25hbE5lc3RlZEVudW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCwgYnVpbGRlci5nZXRSZXBlYXRlZE5lc3RlZEVudW0oMCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQsIGJ1aWxkZXIuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpLmdldCgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCwgYnVpbGRlci5nZXRQYWNrZWROZXN0ZWRFbnVtKDApKTsKKyAgICAKKyAgICAvLyBUZXN0IG1lcmdlRnJvbSgpLgorICAgIGJ1aWxkZXIgPSBUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpLm1lcmdlRnJvbShtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMoNDMyMSwgYnVpbGRlci5nZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoNTQzMiwgYnVpbGRlci5nZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU0MzIsIGJ1aWxkZXIuZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkuZ2V0KDApLmludFZhbHVlKCkpOworICAgIGFzc2VydEVxdWFscyg2NTQzLCBidWlsZGVyLmdldFBhY2tlZE5lc3RlZEVudW1WYWx1ZSgwKSk7CisgICAgLy8gUmV0dXJucyBVTlJFQ09HTklaRUQgaWYgYW4gZW51bSB0eXBlIGlzIHJlcXVlc3RlZC4KKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBidWlsZGVyLmdldE9wdGlvbmFsTmVzdGVkRW51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBidWlsZGVyLmdldFJlcGVhdGVkTmVzdGVkRW51bSgwKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCwgYnVpbGRlci5nZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuZ2V0KDApKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVELCBidWlsZGVyLmdldFBhY2tlZE5lc3RlZEVudW0oMCkpOworICAgIAorICAgIC8vIFRlc3QgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkKKyAgICBUZXN0QWxsVHlwZXMgc2FtZU1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIHNhbWVNZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZS5oYXNoQ29kZSgpLCBzYW1lTWVzc2FnZS5oYXNoQ29kZSgpKTsKKworICAgIC8vIEdldHRpbmcgdGhlIG51bWVyaWMgdmFsdWUgb2YgVU5SRUNPR05JWkVEIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uLgorICAgIHRyeSB7CisgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQuZ2V0TnVtYmVyKCk7CisgICAgICBmYWlsKCJFeGNlcHRpb24gaXMgZXhwZWN0ZWQuIik7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLgorICAgIH0KKworICAgIC8vIFNldHRpbmcgYW4gZW51bSBmaWVsZCB0byBhbiBVTlJFQ09HTklaRUQgdmFsdWUgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24uCisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuc2V0T3B0aW9uYWxOZXN0ZWRFbnVtKGJ1aWxkZXIuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIGlzIGV4cGVjdGVkLiIpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZC4KKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRFbnVtKGJ1aWxkZXIuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworICAgICAgZmFpbCgiRXhjZXB0aW9uIGlzIGV4cGVjdGVkLiIpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZC4KKyAgICB9CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RVbmtub3duRW51bVZhbHVlSW5SZWZsZWN0aW9uQXBpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKTsKKyAgICBGaWVsZERlc2NyaXB0b3Igb3B0aW9uYWxOZXN0ZWRFbnVtRmllbGQgPSBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX2VudW0iKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgcmVwZWF0ZWROZXN0ZWRFbnVtRmllbGQgPSBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX2VudW0iKTsKKyAgICBGaWVsZERlc2NyaXB0b3IgcGFja2VkTmVzdGVkRW51bUZpZWxkID0gZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoInBhY2tlZF9uZXN0ZWRfZW51bSIpOworICAgIEVudW1EZXNjcmlwdG9yIGVudW1UeXBlID0gVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZ2V0RGVzY3JpcHRvcigpOworCisgICAgVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5zZXRGaWVsZChvcHRpb25hbE5lc3RlZEVudW1GaWVsZCwKKyAgICAgICAgZW51bVR5cGUuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93big0MzIxKSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKHJlcGVhdGVkTmVzdGVkRW51bUZpZWxkLAorICAgICAgICBlbnVtVHlwZS5maW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKDU0MzIpKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRmllbGQocGFja2VkTmVzdGVkRW51bUZpZWxkLAorICAgICAgICBlbnVtVHlwZS5maW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKDY1NDMpKTsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICAKKyAgICAvLyBHZXR0ZXJzIHdpbGwgcmV0dXJuIHVua25vd24gZW51bSB2YWx1ZXMgYXMgRW51bVZhbHVlRGVzY3JpcHRvci4KKyAgICBFbnVtVmFsdWVEZXNjcmlwdG9yIHVua25vd240MzIxID0KKyAgICAgICAgKEVudW1WYWx1ZURlc2NyaXB0b3IpIG1lc3NhZ2UuZ2V0RmllbGQob3B0aW9uYWxOZXN0ZWRFbnVtRmllbGQpOworICAgIEVudW1WYWx1ZURlc2NyaXB0b3IgdW5rbm93bjU0MzIgPQorICAgICAgICAoRW51bVZhbHVlRGVzY3JpcHRvcikgbWVzc2FnZS5nZXRSZXBlYXRlZEZpZWxkKHJlcGVhdGVkTmVzdGVkRW51bUZpZWxkLCAwKTsKKyAgICBFbnVtVmFsdWVEZXNjcmlwdG9yIHVua25vd242NTQzID0KKyAgICAgICAgKEVudW1WYWx1ZURlc2NyaXB0b3IpIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChwYWNrZWROZXN0ZWRFbnVtRmllbGQsIDApOworICAgIGFzc2VydEVxdWFscyg0MzIxLCB1bmtub3duNDMyMS5nZXROdW1iZXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDU0MzIsIHVua25vd241NDMyLmdldE51bWJlcigpKTsKKyAgICBhc3NlcnRFcXVhbHMoNjU0MywgdW5rbm93bjY1NDMuZ2V0TnVtYmVyKCkpOworICAgIAorICAgIC8vIFVua25vd24gRW51bVZhbHVlRGVzY3JpcHRvciB3aWxsIG1hcCB0byBVTlJFQ09HTklaRUQuCisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS52YWx1ZU9mKHVua25vd240MzIxKSwKKyAgICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLnZhbHVlT2YodW5rbm93bjU0MzIpLAorICAgICAgICBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0udmFsdWVPZih1bmtub3duNjU0MyksCisgICAgICAgIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCk7CisgICAgCisgICAgLy8gU2V0dGVycyBhbHNvIGFjY2VwdCB1bmtub3duIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgICAgYnVpbGRlci5zZXRGaWVsZChvcHRpb25hbE5lc3RlZEVudW1GaWVsZCwgdW5rbm93bjY1NDMpOworICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWRGaWVsZChyZXBlYXRlZE5lc3RlZEVudW1GaWVsZCwgMCwgdW5rbm93bjQzMjEpOworICAgIGJ1aWxkZXIuc2V0UmVwZWF0ZWRGaWVsZChwYWNrZWROZXN0ZWRFbnVtRmllbGQsIDAsIHVua25vd241NDMyKTsKKyAgICBtZXNzYWdlID0gYnVpbGRlci5idWlsZCgpOworICAgIC8vIExpa2Ugb3RoZXIgZGVzY3JpcHRvcnMsIHVua25vd24gRW51bVZhbHVlRGVzY3JpcHRvciBjYW4gYmUgY29tcGFyZWQgYnkKKyAgICAvLyBvYmplY3QgaWRlbnRpdHkuCisgICAgYXNzZXJ0VHJ1ZSh1bmtub3duNjU0MyA9PSBtZXNzYWdlLmdldEZpZWxkKG9wdGlvbmFsTmVzdGVkRW51bUZpZWxkKSk7CisgICAgYXNzZXJ0VHJ1ZSh1bmtub3duNDMyMSA9PSBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQocmVwZWF0ZWROZXN0ZWRFbnVtRmllbGQsIDApKTsKKyAgICBhc3NlcnRUcnVlKHVua25vd241NDMyID09IG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChwYWNrZWROZXN0ZWRFbnVtRmllbGQsIDApKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFVua25vd25FbnVtVmFsdWVXaXRoRHluYW1pY01lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpOworICAgIEZpZWxkRGVzY3JpcHRvciBvcHRpb25hbE5lc3RlZEVudW1GaWVsZCA9IGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfZW51bSIpOworICAgIEZpZWxkRGVzY3JpcHRvciByZXBlYXRlZE5lc3RlZEVudW1GaWVsZCA9IGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIpOworICAgIEZpZWxkRGVzY3JpcHRvciBwYWNrZWROZXN0ZWRFbnVtRmllbGQgPSBkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgicGFja2VkX25lc3RlZF9lbnVtIik7CisgICAgRW51bURlc2NyaXB0b3IgZW51bVR5cGUgPSBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5nZXREZXNjcmlwdG9yKCk7CisgICAgCisgICAgTWVzc2FnZSBkeW5hbWljTWVzc2FnZURlZmF1bHRJbnN0YW5jZSA9IER5bmFtaWNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZShkZXNjcmlwdG9yKTsKKworICAgIE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyID0gZHluYW1pY01lc3NhZ2VEZWZhdWx0SW5zdGFuY2UubmV3QnVpbGRlckZvclR5cGUoKTsKKyAgICBidWlsZGVyLnNldEZpZWxkKG9wdGlvbmFsTmVzdGVkRW51bUZpZWxkLAorICAgICAgICBlbnVtVHlwZS5maW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKDQzMjEpKTsKKyAgICBidWlsZGVyLmFkZFJlcGVhdGVkRmllbGQocmVwZWF0ZWROZXN0ZWRFbnVtRmllbGQsCisgICAgICAgIGVudW1UeXBlLmZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oNTQzMikpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChwYWNrZWROZXN0ZWRFbnVtRmllbGQsCisgICAgICAgIGVudW1UeXBlLmZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oNjU0MykpOworICAgIE1lc3NhZ2UgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDMyMSwKKyAgICAgICAgKChFbnVtVmFsdWVEZXNjcmlwdG9yKSBtZXNzYWdlLmdldEZpZWxkKG9wdGlvbmFsTmVzdGVkRW51bUZpZWxkKSkuZ2V0TnVtYmVyKCkpOworICAgIGFzc2VydEVxdWFscyg1NDMyLAorICAgICAgICAoKEVudW1WYWx1ZURlc2NyaXB0b3IpIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChyZXBlYXRlZE5lc3RlZEVudW1GaWVsZCwgMCkpLmdldE51bWJlcigpKTsKKyAgICBhc3NlcnRFcXVhbHMoNjU0MywKKyAgICAgICAgKChFbnVtVmFsdWVEZXNjcmlwdG9yKSBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQocGFja2VkTmVzdGVkRW51bUZpZWxkLCAwKSkuZ2V0TnVtYmVyKCkpOworICAgIAorICAgIC8vIFRlc3QgcmVmbGVjdGlvbiBiYXNlZCBzZXJpYWxpemF0aW9uL3BhcnNpbmcgaW1wbGVtZW50YXRpb24uCisgICAgQnl0ZVN0cmluZyBkYXRhID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICBtZXNzYWdlID0gZHluYW1pY01lc3NhZ2VEZWZhdWx0SW5zdGFuY2UKKyAgICAgICAgLm5ld0J1aWxkZXJGb3JUeXBlKCkKKyAgICAgICAgLm1lcmdlRnJvbShkYXRhKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDMyMSwKKyAgICAgICAgKChFbnVtVmFsdWVEZXNjcmlwdG9yKSBtZXNzYWdlLmdldEZpZWxkKG9wdGlvbmFsTmVzdGVkRW51bUZpZWxkKSkuZ2V0TnVtYmVyKCkpOworICAgIGFzc2VydEVxdWFscyg1NDMyLAorICAgICAgICAoKEVudW1WYWx1ZURlc2NyaXB0b3IpIG1lc3NhZ2UuZ2V0UmVwZWF0ZWRGaWVsZChyZXBlYXRlZE5lc3RlZEVudW1GaWVsZCwgMCkpLmdldE51bWJlcigpKTsKKyAgICBhc3NlcnRFcXVhbHMoNjU0MywKKyAgICAgICAgKChFbnVtVmFsdWVEZXNjcmlwdG9yKSBtZXNzYWdlLmdldFJlcGVhdGVkRmllbGQocGFja2VkTmVzdGVkRW51bUZpZWxkLCAwKSkuZ2V0TnVtYmVyKCkpOworICAgIAorICAgIC8vIFRlc3QgcmVmbGVjdGlvbiBiYXNlZCBlcXVhbHMoKS9oYXNoQ29kZSgpLgorICAgIGJ1aWxkZXIgPSBkeW5hbWljTWVzc2FnZURlZmF1bHRJbnN0YW5jZS5uZXdCdWlsZGVyRm9yVHlwZSgpOworICAgIGJ1aWxkZXIuc2V0RmllbGQob3B0aW9uYWxOZXN0ZWRFbnVtRmllbGQsCisgICAgICAgIGVudW1UeXBlLmZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oNDMyMSkpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChyZXBlYXRlZE5lc3RlZEVudW1GaWVsZCwKKyAgICAgICAgZW51bVR5cGUuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93big1NDMyKSk7CisgICAgYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKHBhY2tlZE5lc3RlZEVudW1GaWVsZCwKKyAgICAgICAgZW51bVR5cGUuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93big2NTQzKSk7CisgICAgTWVzc2FnZSBzYW1lTWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgc2FtZU1lc3NhZ2UpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmhhc2hDb2RlKCksIHNhbWVNZXNzYWdlLmhhc2hDb2RlKCkpOworICAgIGJ1aWxkZXIuc2V0RmllbGQob3B0aW9uYWxOZXN0ZWRFbnVtRmllbGQsCisgICAgICAgIGVudW1UeXBlLmZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oMCkpOworICAgIE1lc3NhZ2UgZGlmZmVyZW50TWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmVxdWFscyhkaWZmZXJlbnRNZXNzYWdlKSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RVbmtub3duRW51bVZhbHVlc0luVGV4dEZvcm1hdCgpIHsKKyAgICBUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyID0gVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLnNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKDQzMjEpOworICAgIGJ1aWxkZXIuYWRkUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoNTQzMik7CisgICAgYnVpbGRlci5hZGRQYWNrZWROZXN0ZWRFbnVtVmFsdWUoNjU0Myk7CisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgCisgICAgLy8gV2UgY2FuIHByaW50IGEgbWVzc2FnZSB3aXRoIHVua25vd24gZW51bSB2YWx1ZXMuCisgICAgU3RyaW5nIHRleHREYXRhID0gVGV4dEZvcm1hdC5wcmludFRvU3RyaW5nKG1lc3NhZ2UpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgIm9wdGlvbmFsX25lc3RlZF9lbnVtOiBVTktOT1dOX0VOVU1fVkFMVUVfTmVzdGVkRW51bV80MzIxXG4iCisgICAgICAgICsgInJlcGVhdGVkX25lc3RlZF9lbnVtOiBVTktOT1dOX0VOVU1fVkFMVUVfTmVzdGVkRW51bV81NDMyXG4iCisgICAgICAgICsgInBhY2tlZF9uZXN0ZWRfZW51bTogVU5LTk9XTl9FTlVNX1ZBTFVFX05lc3RlZEVudW1fNjU0M1xuIiwgdGV4dERhdGEpOworICAgIAorICAgIC8vIFBhcnNpbmcgdW5rbm93biBlbnVtIHZhbHVlcyB3aWxsIGZhaWwganVzdCBsaWtlIHBhcnNpbmcgb3RoZXIga2luZHMgb2YKKyAgICAvLyB1bmtub3duIGZpZWxkcy4KKyAgICB0cnkgeworICAgICAgVGV4dEZvcm1hdC5tZXJnZSh0ZXh0RGF0YSwgYnVpbGRlcik7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgLy8gZXhwZWN0ZWQuCisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXRMaXRlVGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0TGl0ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZWMzZGExCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0TGl0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDMxNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKKworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb287CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRlc3RzIGZvciB7QGxpbmsgVW5rbm93bkZpZWxkU2V0TGl0ZX0uCisgKgorICogQGF1dGhvciBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKyAqLworcHVibGljIGNsYXNzIFVua25vd25GaWVsZFNldExpdGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgIHB1YmxpYyB2b2lkIHRlc3ROb0RhdGFJc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgICBhc3NlcnRTYW1lKAorICAgICAgICBVbmtub3duRmllbGRTZXRMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpLAorICAgICAgICBVbmtub3duRmllbGRTZXRMaXRlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmJ1aWxkKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdERlZmF1bHRJbnN0YW5jZSgpIHsKKyAgICBVbmtub3duRmllbGRTZXRMaXRlIHVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXRMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOworCisgICAgYXNzZXJ0RXF1YWxzKDAsIHVua25vd25GaWVsZHMuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEJ5dGVTdHJpbmcuRU1QVFksIHRvQnl0ZVN0cmluZyh1bmtub3duRmllbGRzKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VGaWVsZEZyb20oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZvbyBmb28gPSBGb28ubmV3QnVpbGRlcigpCisgICAgICAuc2V0VmFsdWUoMikKKyAgICAgIC5idWlsZCgpOworCisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9IENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UoZm9vLnRvQnl0ZUFycmF5KCkpOworCisgICAgVW5rbm93bkZpZWxkU2V0TGl0ZS5CdWlsZGVyIGJ1aWxkZXIgPSBVbmtub3duRmllbGRTZXRMaXRlLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLm1lcmdlRmllbGRGcm9tKGlucHV0LnJlYWRUYWcoKSwgaW5wdXQpOworCisgICAgYXNzZXJ0RXF1YWxzKGZvby50b0J5dGVTdHJpbmcoKSwgdG9CeXRlU3RyaW5nKGJ1aWxkZXIuYnVpbGQoKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZWRTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGb28gZm9vID0gRm9vLm5ld0J1aWxkZXIoKQorICAgICAgLnNldFZhbHVlKDIpCisgICAgICAuYnVpbGQoKTsKKworICAgIENvZGVkSW5wdXRTdHJlYW0gaW5wdXQgPSBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKGZvby50b0J5dGVBcnJheSgpKTsKKworICAgIFVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciBidWlsZGVyID0gVW5rbm93bkZpZWxkU2V0TGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5tZXJnZUZpZWxkRnJvbShpbnB1dC5yZWFkVGFnKCksIGlucHV0KTsKKworICAgIGFzc2VydEVxdWFscyhmb28udG9CeXRlU3RyaW5nKCkuc2l6ZSgpLCBidWlsZGVyLmJ1aWxkKCkuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VWYXJpbnRGaWVsZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVW5rbm93bkZpZWxkU2V0TGl0ZS5CdWlsZGVyIGJ1aWxkZXIgPSBVbmtub3duRmllbGRTZXRMaXRlLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLm1lcmdlVmFyaW50RmllbGQoMTAsIDIpOworCisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9CisgICAgICAgIENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UodG9CeXRlU3RyaW5nKGJ1aWxkZXIuYnVpbGQoKSkudG9CeXRlQXJyYXkoKSk7CisKKyAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOworICAgIGFzc2VydEVxdWFscygxMCwgV2lyZUZvcm1hdC5nZXRUYWdGaWVsZE51bWJlcih0YWcpKTsKKyAgICBhc3NlcnRFcXVhbHMoV2lyZUZvcm1hdC5XSVJFVFlQRV9WQVJJTlQsIFdpcmVGb3JtYXQuZ2V0VGFnV2lyZVR5cGUodGFnKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGlucHV0LnJlYWRVSW50NjQoKSk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlVmFyaW50RmllbGRfbmVnYXRpdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciBidWlsZGVyID0gVW5rbm93bkZpZWxkU2V0TGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5tZXJnZVZhcmludEZpZWxkKDEwLCAtNik7CisKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0KKyAgICAgICAgQ29kZWRJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZSh0b0J5dGVTdHJpbmcoYnVpbGRlci5idWlsZCgpKS50b0J5dGVBcnJheSgpKTsKKworICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEwLCBXaXJlRm9ybWF0LmdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpOworICAgIGFzc2VydEVxdWFscyhXaXJlRm9ybWF0LldJUkVUWVBFX1ZBUklOVCwgV2lyZUZvcm1hdC5nZXRUYWdXaXJlVHlwZSh0YWcpKTsKKyAgICBhc3NlcnRFcXVhbHMoLTYsIGlucHV0LnJlYWRVSW50NjQoKSk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVxdWFsc0FuZEhhc2hDb2RlKCkgeworICAgIFVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciBidWlsZGVyMSA9IFVua25vd25GaWVsZFNldExpdGUubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIxLm1lcmdlVmFyaW50RmllbGQoMTAsIDIpOworICAgIFVua25vd25GaWVsZFNldExpdGUgdW5rbm93bkZpZWxkczEgPSBidWlsZGVyMS5idWlsZCgpOworCisgICAgVW5rbm93bkZpZWxkU2V0TGl0ZS5CdWlsZGVyIGJ1aWxkZXIyID0gVW5rbm93bkZpZWxkU2V0TGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlcjIubWVyZ2VWYXJpbnRGaWVsZCgxMCwgMik7CisgICAgVW5rbm93bkZpZWxkU2V0TGl0ZSB1bmtub3duRmllbGRzMiA9IGJ1aWxkZXIyLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRFcXVhbHModW5rbm93bkZpZWxkczEsIHVua25vd25GaWVsZHMyKTsKKyAgICBhc3NlcnRFcXVhbHModW5rbm93bkZpZWxkczEuaGFzaENvZGUoKSwgdW5rbm93bkZpZWxkczIuaGFzaENvZGUoKSk7CisgICAgYXNzZXJ0RmFsc2UodW5rbm93bkZpZWxkczEuZXF1YWxzKFVua25vd25GaWVsZFNldExpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKyAgICBhc3NlcnRGYWxzZSh1bmtub3duRmllbGRzMS5oYXNoQ29kZSgpID09IFVua25vd25GaWVsZFNldExpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkuaGFzaENvZGUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29uY2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBVbmtub3duRmllbGRTZXRMaXRlLkJ1aWxkZXIgYnVpbGRlciA9IFVua25vd25GaWVsZFNldExpdGUubmV3QnVpbGRlcigpOworICAgIGJ1aWxkZXIubWVyZ2VWYXJpbnRGaWVsZCgxMCwgMik7CisgICAgVW5rbm93bkZpZWxkU2V0TGl0ZSB1bmtub3duRmllbGRzID0gYnVpbGRlci5idWlsZCgpOworCisgICAgdW5rbm93bkZpZWxkcyA9IFVua25vd25GaWVsZFNldExpdGUuY29uY2F0KHVua25vd25GaWVsZHMsIHVua25vd25GaWVsZHMpOworCisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCA9CisgICAgICAgIENvZGVkSW5wdXRTdHJlYW0ubmV3SW5zdGFuY2UodG9CeXRlU3RyaW5nKHVua25vd25GaWVsZHMpLnRvQnl0ZUFycmF5KCkpOworCisgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTAsIFdpcmVGb3JtYXQuZ2V0VGFnRmllbGROdW1iZXIodGFnKSk7CisgICAgYXNzZXJ0RXF1YWxzKFdpcmVGb3JtYXQuV0lSRVRZUEVfVkFSSU5ULCBXaXJlRm9ybWF0LmdldFRhZ1dpcmVUeXBlKHRhZykpOworICAgIGFzc2VydEVxdWFscygyLCBpbnB1dC5yZWFkVUludDY0KCkpOworICAgIGFzc2VydEZhbHNlKGlucHV0LmlzQXRFbmQoKSk7CisgICAgaW5wdXQucmVhZFRhZygpOworICAgIGFzc2VydEVxdWFscygxMCwgV2lyZUZvcm1hdC5nZXRUYWdGaWVsZE51bWJlcih0YWcpKTsKKyAgICBhc3NlcnRFcXVhbHMoV2lyZUZvcm1hdC5XSVJFVFlQRV9WQVJJTlQsIFdpcmVGb3JtYXQuZ2V0VGFnV2lyZVR5cGUodGFnKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGlucHV0LnJlYWRVSW50NjQoKSk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENvbmNhdF9lbXB0eSgpIHsKKyAgICBVbmtub3duRmllbGRTZXRMaXRlIHVua25vd25GaWVsZHMgPSBVbmtub3duRmllbGRTZXRMaXRlLmNvbmNhdCgKKyAgICAgICAgVW5rbm93bkZpZWxkU2V0TGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSwgVW5rbm93bkZpZWxkU2V0TGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMCwgdW5rbm93bkZpZWxkcy5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoQnl0ZVN0cmluZy5FTVBUWSwgdG9CeXRlU3RyaW5nKHVua25vd25GaWVsZHMpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RCdWlsZGVyUmV1c2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciBidWlsZGVyID0gVW5rbm93bkZpZWxkU2V0TGl0ZS5uZXdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5tZXJnZVZhcmludEZpZWxkKDEwLCAyKTsKKyAgICBidWlsZGVyLmJ1aWxkKCk7CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5idWlsZCgpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZC4KKyAgICB9CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5tZXJnZUZpZWxkRnJvbSgwLCBDb2RlZElucHV0U3RyZWFtLm5ld0luc3RhbmNlKG5ldyBieXRlWzBdKSk7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLgorICAgIH0KKworICAgIHRyeSB7CisgICAgICBidWlsZGVyLm1lcmdlVmFyaW50RmllbGQoNSwgMSk7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLgorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RCdWlsZGVyUmV1c2VfZW1wdHkoKSB7CisgICAgVW5rbm93bkZpZWxkU2V0TGl0ZS5CdWlsZGVyIGJ1aWxkZXIgPSBVbmtub3duRmllbGRTZXRMaXRlLm5ld0J1aWxkZXIoKTsKKyAgICBidWlsZGVyLmJ1aWxkKCk7CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlci5idWlsZCgpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZC4KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Um91bmRUcmlwcygpIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIEZvbyBmb28gPSBGb28ubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRWYWx1ZSgxKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKEJhci5mb29FeHQsIEJhci5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXROYW1lKCJuYW1lIikKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKExpdGVFcXVhbHNBbmRIYXNoLnZhcmludCwgMjIpCisgICAgICAgIC5zZXRFeHRlbnNpb24oTGl0ZUVxdWFsc0FuZEhhc2guZml4ZWQzMiwgNDQpCisgICAgICAgIC5zZXRFeHRlbnNpb24oTGl0ZUVxdWFsc0FuZEhhc2guZml4ZWQ2NCwgNjZMKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKExpdGVFcXVhbHNBbmRIYXNoLm15R3JvdXAsIExpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBWYWx1ZSgidmFsdWUiKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgRm9vIGNvcHkgPSBGb28ucGFyc2VGcm9tKGZvby50b0J5dGVBcnJheSgpKTsKKworICAgIGFzc2VydEVxdWFscyhmb28uZ2V0U2VyaWFsaXplZFNpemUoKSwgY29weS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgICBhc3NlcnRGYWxzZShmb28uZXF1YWxzKGNvcHkpKTsKKworICAgIEZvbyBzZWNvbmRDb3B5ID0gRm9vLnBhcnNlRnJvbShmb28udG9CeXRlQXJyYXkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKGNvcHksIHNlY29uZENvcHkpOworCisgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5ID0gRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLm5ld0luc3RhbmNlKCk7CisgICAgTGl0ZUVxdWFsc0FuZEhhc2gucmVnaXN0ZXJBbGxFeHRlbnNpb25zKGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICBGb28gY29weU9mQ29weSA9IEZvby5wYXJzZUZyb20oY29weS50b0J5dGVBcnJheSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CisKKyAgICBhc3NlcnRFcXVhbHMoZm9vLCBjb3B5T2ZDb3B5KTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNYWxmb3JtZWRCeXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBGb28ucGFyc2VGcm9tKCJ0aGlzIGlzIGEgbWFsZm9ybWVkIHByb3RvY29sIGJ1ZmZlciIuZ2V0Qnl0ZXMoIlVURi04IikpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZC4KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWlzc2luZ1N0YXJ0R3JvdXBUYWcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcuT3V0cHV0IGJ5dGVTdHJpbmdPdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dCgpOworICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKGJ5dGVTdHJpbmdPdXRwdXQpOworICAgIG91dHB1dC53cml0ZUdyb3VwTm9UYWcoRm9vLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgxMSkuYnVpbGQoKSk7CisgICAgb3V0cHV0LndyaXRlVGFnKDEwMCwgV2lyZUZvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApOworICAgIG91dHB1dC5mbHVzaCgpOworCisgICAgdHJ5IHsKKyAgICAgIEZvby5wYXJzZUZyb20oYnl0ZVN0cmluZ091dHB1dC50b0J5dGVTdHJpbmcoKSk7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLgorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nRW5kR3JvdXBUYWcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcuT3V0cHV0IGJ5dGVTdHJpbmdPdXRwdXQgPSBCeXRlU3RyaW5nLm5ld091dHB1dCgpOworICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCA9IENvZGVkT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlKGJ5dGVTdHJpbmdPdXRwdXQpOworICAgIG91dHB1dC53cml0ZVRhZygxMDAsIFdpcmVGb3JtYXQuV0lSRVRZUEVfU1RBUlRfR1JPVVApOworICAgIG91dHB1dC53cml0ZUdyb3VwTm9UYWcoRm9vLm5ld0J1aWxkZXIoKS5zZXRWYWx1ZSgxMSkuYnVpbGQoKSk7CisgICAgb3V0cHV0LmZsdXNoKCk7CisKKyAgICB0cnkgeworICAgICAgRm9vLnBhcnNlRnJvbShieXRlU3RyaW5nT3V0cHV0LnRvQnl0ZVN0cmluZygpKTsKKyAgICAgIGZhaWwoKTsKKyAgICB9IGNhdGNoIChJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgLy8gRXhwZWN0ZWQuCisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1pc21hdGNoaW5nR3JvdXBUYWdzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCeXRlU3RyaW5nLk91dHB1dCBieXRlU3RyaW5nT3V0cHV0ID0gQnl0ZVN0cmluZy5uZXdPdXRwdXQoKTsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShieXRlU3RyaW5nT3V0cHV0KTsKKyAgICBvdXRwdXQud3JpdGVUYWcoMTAwLCBXaXJlRm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQKTsKKyAgICBvdXRwdXQud3JpdGVHcm91cE5vVGFnKEZvby5uZXdCdWlsZGVyKCkuc2V0VmFsdWUoMTEpLmJ1aWxkKCkpOworICAgIG91dHB1dC53cml0ZVRhZygxMDEsIFdpcmVGb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKTsKKyAgICBvdXRwdXQuZmx1c2goKTsKKworICAgIHRyeSB7CisgICAgICBGb28ucGFyc2VGcm9tKGJ5dGVTdHJpbmdPdXRwdXQudG9CeXRlU3RyaW5nKCkpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZC4KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VHJ1bmNhdGVkSW5wdXQoKSB7CisgICAgRm9vIGZvbyA9IEZvby5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldFZhbHVlKDEpCisgICAgICAgIC5zZXRFeHRlbnNpb24oQmFyLmZvb0V4dCwgQmFyLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE5hbWUoIm5hbWUiKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5zZXRFeHRlbnNpb24oTGl0ZUVxdWFsc0FuZEhhc2gudmFyaW50LCAyMikKKyAgICAgICAgLnNldEV4dGVuc2lvbihMaXRlRXF1YWxzQW5kSGFzaC5teUdyb3VwLCBMaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwVmFsdWUoInZhbHVlIikKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIHRyeSB7CisgICAgICBGb28ucGFyc2VGcm9tKGZvby50b0J5dGVTdHJpbmcoKS5zdWJzdHJpbmcoMCwgZm9vLnRvQnl0ZVN0cmluZygpLnNpemUoKSAtIDEwKSk7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLgorICAgIH0KKyAgfQorCisgIHByaXZhdGUgQnl0ZVN0cmluZyB0b0J5dGVTdHJpbmcoVW5rbm93bkZpZWxkU2V0TGl0ZSB1bmtub3duRmllbGRzKSB7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVBcnJheU91dHB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQgPSBDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShieXRlQXJyYXlPdXRwdXRTdHJlYW0pOworICAgIHRyeSB7CisgICAgICB1bmtub3duRmllbGRzLndyaXRlVG8ob3V0cHV0KTsKKyAgICAgIG91dHB1dC5mbHVzaCgpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgIH0KKyAgICByZXR1cm4gQnl0ZVN0cmluZy5jb3B5RnJvbShieXRlQXJyYXlPdXRwdXRTdHJlYW0udG9CeXRlQXJyYXkoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Vua25vd25GaWVsZFNldFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1Vua25vd25GaWVsZFNldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2E1ZWUyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5rbm93bkZpZWxkU2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnM7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogVGVzdHMgcmVsYXRlZCB0byB1bmtub3duIGZpZWxkIGhhbmRsaW5nLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKyAqLworcHVibGljIGNsYXNzIFVua25vd25GaWVsZFNldFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZGVzY3JpcHRvciA9IFRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCk7CisgICAgYWxsRmllbGRzID0gVGVzdFV0aWwuZ2V0QWxsU2V0KCk7CisgICAgYWxsRmllbGRzRGF0YSA9IGFsbEZpZWxkcy50b0J5dGVTdHJpbmcoKTsKKyAgICBlbXB0eU1lc3NhZ2UgPSBUZXN0RW1wdHlNZXNzYWdlLnBhcnNlRnJvbShhbGxGaWVsZHNEYXRhKTsKKyAgICB1bmtub3duRmllbGRzID0gZW1wdHlNZXNzYWdlLmdldFVua25vd25GaWVsZHMoKTsKKyAgfQorCisgIFVua25vd25GaWVsZFNldC5GaWVsZCBnZXRGaWVsZChTdHJpbmcgbmFtZSkgeworICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCA9IGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKG5hbWUpOworICAgIGFzc2VydE5vdE51bGwoZmllbGQpOworICAgIHJldHVybiB1bmtub3duRmllbGRzLmdldEZpZWxkKGZpZWxkLmdldE51bWJlcigpKTsKKyAgfQorCisgIC8vIENvbnN0cnVjdHMgYSBwcm90b2NvbCBidWZmZXIgd2hpY2ggY29udGFpbnMgZmllbGRzIHdpdGggYWxsIHRoZSBzYW1lCisgIC8vIG51bWJlcnMgYXMgYWxsRmllbGRzRGF0YSBleGNlcHQgdGhhdCBlYWNoIGZpZWxkIGlzIHNvbWUgb3RoZXIgd2lyZQorICAvLyB0eXBlLgorICBCeXRlU3RyaW5nIGdldEJpemFycm9EYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVW5rbm93bkZpZWxkU2V0LkJ1aWxkZXIgYml6YXJyb0ZpZWxkcyA9IFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCk7CisKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgdmFyaW50RmllbGQgPQorICAgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkLm5ld0J1aWxkZXIoKS5hZGRWYXJpbnQoMSkuYnVpbGQoKTsKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZml4ZWQzMkZpZWxkID0KKyAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkuYWRkRml4ZWQzMigxKS5idWlsZCgpOworCisgICAgZm9yIChNYXAuRW50cnk8SW50ZWdlciwgVW5rbm93bkZpZWxkU2V0LkZpZWxkPiBlbnRyeSA6CisgICAgICAgICB1bmtub3duRmllbGRzLmFzTWFwKCkuZW50cnlTZXQoKSkgeworICAgICAgaWYgKGVudHJ5LmdldFZhbHVlKCkuZ2V0VmFyaW50TGlzdCgpLmlzRW1wdHkoKSkgeworICAgICAgICAvLyBPcmlnaW5hbCBmaWVsZCBpcyBub3QgYSB2YXJpbnQsIHNvIHVzZSBhIHZhcmludC4KKyAgICAgICAgYml6YXJyb0ZpZWxkcy5hZGRGaWVsZChlbnRyeS5nZXRLZXkoKSwgdmFyaW50RmllbGQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gT3JpZ2luYWwgZmllbGQgKmlzKiBhIHZhcmludCwgc28gdXNlIHNvbWV0aGluZyBlbHNlLgorICAgICAgICBiaXphcnJvRmllbGRzLmFkZEZpZWxkKGVudHJ5LmdldEtleSgpLCBmaXhlZDMyRmllbGQpOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBiaXphcnJvRmllbGRzLmJ1aWxkKCkudG9CeXRlU3RyaW5nKCk7CisgIH0KKworICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGRlc2NyaXB0b3I7CisgIFRlc3RBbGxUeXBlcyBhbGxGaWVsZHM7CisgIEJ5dGVTdHJpbmcgYWxsRmllbGRzRGF0YTsKKworICAvLyBBbiBlbXB0eSBtZXNzYWdlIHRoYXQgaGFzIGJlZW4gcGFyc2VkIGZyb20gYWxsRmllbGRzRGF0YS4gIFNvLCBpdCBoYXMKKyAgLy8gdW5rbm93biBmaWVsZHMgb2YgZXZlcnkgdHlwZS4KKyAgVGVzdEVtcHR5TWVzc2FnZSBlbXB0eU1lc3NhZ2U7CisgIFVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzOworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgcHVibGljIHZvaWQgdGVzdFZhcmludCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVua25vd25GaWVsZFNldC5GaWVsZCBmaWVsZCA9IGdldEZpZWxkKCJvcHRpb25hbF9pbnQzMiIpOworICAgIGFzc2VydEVxdWFscygxLCBmaWVsZC5nZXRWYXJpbnRMaXN0KCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoYWxsRmllbGRzLmdldE9wdGlvbmFsSW50MzIoKSwKKyAgICAgICAgICAgICAgICAgKGxvbmcpIGZpZWxkLmdldFZhcmludExpc3QoKS5nZXQoMCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEZpeGVkMzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZmllbGQgPSBnZXRGaWVsZCgib3B0aW9uYWxfZml4ZWQzMiIpOworICAgIGFzc2VydEVxdWFscygxLCBmaWVsZC5nZXRGaXhlZDMyTGlzdCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsbEZpZWxkcy5nZXRPcHRpb25hbEZpeGVkMzIoKSwKKyAgICAgICAgICAgICAgICAgKGludCkgZmllbGQuZ2V0Rml4ZWQzMkxpc3QoKS5nZXQoMCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEZpeGVkNjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZmllbGQgPSBnZXRGaWVsZCgib3B0aW9uYWxfZml4ZWQ2NCIpOworICAgIGFzc2VydEVxdWFscygxLCBmaWVsZC5nZXRGaXhlZDY0TGlzdCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsbEZpZWxkcy5nZXRPcHRpb25hbEZpeGVkNjQoKSwKKyAgICAgICAgICAgICAgICAgKGxvbmcpIGZpZWxkLmdldEZpeGVkNjRMaXN0KCkuZ2V0KDApKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RMZW5ndGhEZWxpbWl0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZmllbGQgPSBnZXRGaWVsZCgib3B0aW9uYWxfYnl0ZXMiKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgZmllbGQuZ2V0TGVuZ3RoRGVsaW1pdGVkTGlzdCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsbEZpZWxkcy5nZXRPcHRpb25hbEJ5dGVzKCksCisgICAgICAgICAgICAgICAgIGZpZWxkLmdldExlbmd0aERlbGltaXRlZExpc3QoKS5nZXQoMCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIG5lc3RlZEZpZWxkRGVzY3JpcHRvciA9CisgICAgICBUZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5nZXREZXNjcmlwdG9yKCkuZmluZEZpZWxkQnlOYW1lKCJhIik7CisgICAgYXNzZXJ0Tm90TnVsbChuZXN0ZWRGaWVsZERlc2NyaXB0b3IpOworCisgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkIGZpZWxkID0gZ2V0RmllbGQoIm9wdGlvbmFsZ3JvdXAiKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgZmllbGQuZ2V0R3JvdXBMaXN0KCkuc2l6ZSgpKTsKKworICAgIFVua25vd25GaWVsZFNldCBncm91cCA9IGZpZWxkLmdldEdyb3VwTGlzdCgpLmdldCgwKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgZ3JvdXAuYXNNYXAoKS5zaXplKCkpOworICAgIGFzc2VydFRydWUoZ3JvdXAuaGFzRmllbGQobmVzdGVkRmllbGREZXNjcmlwdG9yLmdldE51bWJlcigpKSk7CisKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgbmVzdGVkRmllbGQgPQorICAgICAgZ3JvdXAuZ2V0RmllbGQobmVzdGVkRmllbGREZXNjcmlwdG9yLmdldE51bWJlcigpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmVzdGVkRmllbGQuZ2V0VmFyaW50TGlzdCgpLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsbEZpZWxkcy5nZXRPcHRpb25hbEdyb3VwKCkuZ2V0QSgpLAorICAgICAgICAgICAgICAgICAobG9uZykgbmVzdGVkRmllbGQuZ2V0VmFyaW50TGlzdCgpLmdldCgwKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQ2hlY2sgdGhhdCBzZXJpYWxpemluZyB0aGUgVW5rbm93bkZpZWxkU2V0IHByb2R1Y2VzIHRoZSBvcmlnaW5hbCBkYXRhCisgICAgLy8gYWdhaW4uCisgICAgQnl0ZVN0cmluZyBkYXRhID0gZW1wdHlNZXNzYWdlLnRvQnl0ZVN0cmluZygpOworICAgIGFzc2VydEVxdWFscyhhbGxGaWVsZHNEYXRhLCBkYXRhKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDb3B5RnJvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RFbXB0eU1lc3NhZ2UgbWVzc2FnZSA9CisgICAgICBUZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKS5tZXJnZUZyb20oZW1wdHlNZXNzYWdlKS5idWlsZCgpOworCisgICAgYXNzZXJ0RXF1YWxzKGVtcHR5TWVzc2FnZS50b1N0cmluZygpLCBtZXNzYWdlLnRvU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlRnJvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RFbXB0eU1lc3NhZ2Ugc291cmNlID0KKyAgICAgIFRlc3RFbXB0eU1lc3NhZ2UubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRVbmtub3duRmllbGRzKAorICAgICAgICAgIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaWVsZCgyLAorICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFkZFZhcmludCgyKS5idWlsZCgpKQorICAgICAgICAgICAgLmFkZEZpZWxkKDMsCisgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWRkVmFyaW50KDQpLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgVGVzdEVtcHR5TWVzc2FnZSBkZXN0aW5hdGlvbiA9CisgICAgICBUZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0VW5rbm93bkZpZWxkcygKKyAgICAgICAgICBVbmtub3duRmllbGRTZXQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkRmllbGQoMSwKKyAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5hZGRWYXJpbnQoMSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5hZGRGaWVsZCgzLAorICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFkZFZhcmludCgzKS5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5tZXJnZUZyb20oc291cmNlKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydEVxdWFscygKKyAgICAgICIxOiAxXG4iICsKKyAgICAgICIyOiAyXG4iICsKKyAgICAgICIzOiAzXG4iICsKKyAgICAgICIzOiA0XG4iLAorICAgICAgZGVzdGluYXRpb24udG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVbmtub3duRmllbGRTZXQgZmllbGRzID0KKyAgICAgIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkubWVyZ2VGcm9tKHVua25vd25GaWVsZHMpLmNsZWFyKCkuYnVpbGQoKTsKKyAgICBhc3NlcnRUcnVlKGZpZWxkcy5hc01hcCgpLmlzRW1wdHkoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXJNZXNzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlID0KKyAgICAgIFRlc3RFbXB0eU1lc3NhZ2UubmV3QnVpbGRlcigpLm1lcmdlRnJvbShlbXB0eU1lc3NhZ2UpLmNsZWFyKCkuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdENsZWFyRmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBpbnQgZmllbGROdW1iZXIgPSB1bmtub3duRmllbGRzLmFzTWFwKCkua2V5U2V0KCkuaXRlcmF0b3IoKS5uZXh0KCk7CisgICAgVW5rbm93bkZpZWxkU2V0IGZpZWxkcyA9CisgICAgICAgIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkubWVyZ2VGcm9tKHVua25vd25GaWVsZHMpLmNsZWFyRmllbGQoZmllbGROdW1iZXIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0RmFsc2UoZmllbGRzLmhhc0ZpZWxkKGZpZWxkTnVtYmVyKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VLbm93bkFuZFVua25vd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0IG1peGluZyBrbm93biBhbmQgdW5rbm93biBmaWVsZHMgd2hlbiBwYXJzaW5nLgorCisgICAgVW5rbm93bkZpZWxkU2V0IGZpZWxkcyA9CisgICAgICBVbmtub3duRmllbGRTZXQubmV3QnVpbGRlcih1bmtub3duRmllbGRzKQorICAgICAgICAuYWRkRmllbGQoMTIzNDU2LAorICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkuYWRkVmFyaW50KDY1NDMyMSkuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBmaWVsZHMudG9CeXRlU3RyaW5nKCk7CisgICAgVGVzdEFsbFR5cGVzIGRlc3RpbmF0aW9uID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShkYXRhKTsKKworICAgIFRlc3RVdGlsLmFzc2VydEFsbEZpZWxkc1NldChkZXN0aW5hdGlvbik7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGRlc3RpbmF0aW9uLmdldFVua25vd25GaWVsZHMoKS5hc01hcCgpLnNpemUoKSk7CisKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZmllbGQgPQorICAgICAgZGVzdGluYXRpb24uZ2V0VW5rbm93bkZpZWxkcygpLmdldEZpZWxkKDEyMzQ1Nik7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGZpZWxkLmdldFZhcmludExpc3QoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyg2NTQzMjEsIChsb25nKSBmaWVsZC5nZXRWYXJpbnRMaXN0KCkuZ2V0KDApKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RXcm9uZ1R5cGVUcmVhdGVkQXNVbmtub3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGVzdCB0aGF0IGZpZWxkcyBvZiB0aGUgd3Jvbmcgd2lyZSB0eXBlIGFyZSB0cmVhdGVkIGxpa2UgdW5rbm93biBmaWVsZHMKKyAgICAvLyB3aGVuIHBhcnNpbmcuCisKKyAgICBCeXRlU3RyaW5nIGJpemFycm9EYXRhID0gZ2V0Qml6YXJyb0RhdGEoKTsKKyAgICBUZXN0QWxsVHlwZXMgYWxsVHlwZXNNZXNzYWdlID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShiaXphcnJvRGF0YSk7CisgICAgVGVzdEVtcHR5TWVzc2FnZSBlbXB0eU1lc3NhZ2UgPSBUZXN0RW1wdHlNZXNzYWdlLnBhcnNlRnJvbShiaXphcnJvRGF0YSk7CisKKyAgICAvLyBBbGwgZmllbGRzIHNob3VsZCBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQgYXMgdW5rbm93biwgc28gdGhlIGRlYnVnIHN0cmluZ3MKKyAgICAvLyBzaG91bGQgYmUgdGhlIHNhbWUuCisgICAgYXNzZXJ0RXF1YWxzKGVtcHR5TWVzc2FnZS50b1N0cmluZygpLCBhbGxUeXBlc01lc3NhZ2UudG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5rbm93bkV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNYWtlIHN1cmUgZmllbGRzIGFyZSBwcm9wZXJseSBwYXJzZWQgdG8gdGhlIFVua25vd25GaWVsZFNldCBldmVuIHdoZW4KKyAgICAvLyB0aGV5IGFyZSBkZWNsYXJlZCBhcyBleHRlbnNpb24gbnVtYmVycy4KKworICAgIFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBtZXNzYWdlID0KKyAgICAgIFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucy5wYXJzZUZyb20oYWxsRmllbGRzRGF0YSk7CisKKyAgICBhc3NlcnRFcXVhbHModW5rbm93bkZpZWxkcy5hc01hcCgpLnNpemUoKSwKKyAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkuYXNNYXAoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscyhhbGxGaWVsZHNEYXRhLCBtZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RXcm9uZ0V4dGVuc2lvblR5cGVUcmVhdGVkQXNVbmtub3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGVzdCB0aGF0IGZpZWxkcyBvZiB0aGUgd3Jvbmcgd2lyZSB0eXBlIGFyZSB0cmVhdGVkIGxpa2UgdW5rbm93biBmaWVsZHMKKyAgICAvLyB3aGVuIHBhcnNpbmcgZXh0ZW5zaW9ucy4KKworICAgIEJ5dGVTdHJpbmcgYml6YXJyb0RhdGEgPSBnZXRCaXphcnJvRGF0YSgpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIGFsbEV4dGVuc2lvbnNNZXNzYWdlID0KKyAgICAgIFRlc3RBbGxFeHRlbnNpb25zLnBhcnNlRnJvbShiaXphcnJvRGF0YSk7CisgICAgVGVzdEVtcHR5TWVzc2FnZSBlbXB0eU1lc3NhZ2UgPSBUZXN0RW1wdHlNZXNzYWdlLnBhcnNlRnJvbShiaXphcnJvRGF0YSk7CisKKyAgICAvLyBBbGwgZmllbGRzIHNob3VsZCBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQgYXMgdW5rbm93biwgc28gdGhlIGRlYnVnIHN0cmluZ3MKKyAgICAvLyBzaG91bGQgYmUgdGhlIHNhbWUuCisgICAgYXNzZXJ0RXF1YWxzKGVtcHR5TWVzc2FnZS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgICBhbGxFeHRlbnNpb25zTWVzc2FnZS50b1N0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVVua25vd25FbnVtVmFsdWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3Igc2luZ3VsYXJGaWVsZCA9CisgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX2VudW0iKTsKKyAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgcmVwZWF0ZWRGaWVsZCA9CisgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX2VudW0iKTsKKyAgICBhc3NlcnROb3ROdWxsKHNpbmd1bGFyRmllbGQpOworICAgIGFzc2VydE5vdE51bGwocmVwZWF0ZWRGaWVsZCk7CisKKyAgICBCeXRlU3RyaW5nIGRhdGEgPQorICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkRmllbGQoc2luZ3VsYXJGaWVsZC5nZXROdW1iZXIoKSwKKyAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVmFyaW50KFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUi5nZXROdW1iZXIoKSkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoNSkgICAvLyBub3QgdmFsaWQKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYWRkRmllbGQocmVwZWF0ZWRGaWVsZC5nZXROdW1iZXIoKSwKKyAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVmFyaW50KFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTy5nZXROdW1iZXIoKSkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoNCkgICAvLyBub3QgdmFsaWQKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFaLmdldE51bWJlcigpKQorICAgICAgICAgICAgLmFkZFZhcmludCg2KSAgIC8vIG5vdCB2YWxpZAorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpCisgICAgICAgIC50b0J5dGVTdHJpbmcoKTsKKworICAgIHsKKyAgICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShkYXRhKTsKKyAgICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsCisgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRPcHRpb25hbE5lc3RlZEVudW0oKSk7CisgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIEFycmF5cy5hc0xpc3QoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PLCBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVopLAorICAgICAgICBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSk7CisgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCg1TCksCisgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKHNpbmd1bGFyRmllbGQuZ2V0TnVtYmVyKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYXJpbnRMaXN0KCkpOworICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoNEwsIDZMKSwKKyAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdldFVua25vd25GaWVsZHMoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQocmVwZWF0ZWRGaWVsZC5nZXROdW1iZXIoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZhcmludExpc3QoKSk7CisgICAgfQorCisgICAgeworICAgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9CisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zLnBhcnNlRnJvbShkYXRhLCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsCisgICAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uKSk7CisgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIEFycmF5cy5hc0xpc3QoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PLCBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVopLAorICAgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbikpOworICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoNUwpLAorICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ2V0VW5rbm93bkZpZWxkcygpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChzaW5ndWxhckZpZWxkLmdldE51bWJlcigpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0VmFyaW50TGlzdCgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KDRMLCA2TCksCisgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKHJlcGVhdGVkRmllbGQuZ2V0TnVtYmVyKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYXJpbnRMaXN0KCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RMYXJnZVZhcmludCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEJ5dGVTdHJpbmcgZGF0YSA9CisgICAgICBVbmtub3duRmllbGRTZXQubmV3QnVpbGRlcigpCisgICAgICAgIC5hZGRGaWVsZCgxLAorICAgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoMHg3RkZGRkZGRkZGRkZGRkZGTCkKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKQorICAgICAgICAudG9CeXRlU3RyaW5nKCk7CisgICAgVW5rbm93bkZpZWxkU2V0IHBhcnNlZCA9IFVua25vd25GaWVsZFNldC5wYXJzZUZyb20oZGF0YSk7CisgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkIGZpZWxkID0gcGFyc2VkLmdldEZpZWxkKDEpOworICAgIGFzc2VydEVxdWFscygxLCBmaWVsZC5nZXRWYXJpbnRMaXN0KCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMHg3RkZGRkZGRkZGRkZGRkZGTCwgKGxvbmcpZmllbGQuZ2V0VmFyaW50TGlzdCgpLmdldCgwKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzQW5kSGFzaENvZGUoKSB7CisgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkIGZpeGVkMzJGaWVsZCA9CisgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaXhlZDMyKDEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZml4ZWQ2NEZpZWxkID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpeGVkNjQoMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVua25vd25GaWVsZFNldC5GaWVsZCB2YXJJbnRGaWVsZCA9CisgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVua25vd25GaWVsZFNldC5GaWVsZCBsZW5ndGhEZWxpbWl0ZWRGaWVsZCA9CisgICAgICAgIFVua25vd25GaWVsZFNldC5GaWVsZC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRMZW5ndGhEZWxpbWl0ZWQoQnl0ZVN0cmluZy5FTVBUWSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVua25vd25GaWVsZFNldC5GaWVsZCBncm91cEZpZWxkID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0LkZpZWxkLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEdyb3VwKHVua25vd25GaWVsZHMpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIFVua25vd25GaWVsZFNldCBhID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpZWxkKDEsIGZpeGVkMzJGaWVsZCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVua25vd25GaWVsZFNldCBiID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpZWxkKDEsIGZpeGVkNjRGaWVsZCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVua25vd25GaWVsZFNldCBjID0KKyAgICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpZWxkKDEsIHZhckludEZpZWxkKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgVW5rbm93bkZpZWxkU2V0IGQgPQorICAgICAgICBVbmtub3duRmllbGRTZXQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkRmllbGQoMSwgbGVuZ3RoRGVsaW1pdGVkRmllbGQpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBVbmtub3duRmllbGRTZXQgZSA9CisgICAgICAgIFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaWVsZCgxLCBncm91cEZpZWxkKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChhKTsKKyAgICBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChiKTsKKyAgICBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChjKTsKKyAgICBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChkKTsKKyAgICBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChlKTsKKworICAgIGNoZWNrTm90RXF1YWwoYSwgYik7CisgICAgY2hlY2tOb3RFcXVhbChhLCBjKTsKKyAgICBjaGVja05vdEVxdWFsKGEsIGQpOworICAgIGNoZWNrTm90RXF1YWwoYSwgZSk7CisgICAgY2hlY2tOb3RFcXVhbChiLCBjKTsKKyAgICBjaGVja05vdEVxdWFsKGIsIGQpOworICAgIGNoZWNrTm90RXF1YWwoYiwgZSk7CisgICAgY2hlY2tOb3RFcXVhbChjLCBkKTsKKyAgICBjaGVja05vdEVxdWFsKGMsIGUpOworICAgIGNoZWNrTm90RXF1YWwoZCwgZSk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBmaWVsZCBzZXRzIGFyZSBub3QgZXF1YWwgYW5kIGhhdmUgZGlmZmVyZW50CisgICAqIGhhc2ggY29kZXMuCisgICAqCisgICAqIEB3YXJuaW5nIEl0J3MgdmFsaWQgZm9yIG5vbi1lcXVhbCBvYmplY3RzIHRvIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2RlLCBzbworICAgKiAgIHRoaXMgdGVzdCBpcyBzdHJpY3RlciB0aGFuIGl0IG5lZWRzIHRvIGJlLiBIb3dldmVyLCB0aGlzIHNob3VsZCBoYXBwZW4KKyAgICogICByZWxhdGl2ZWx5IHJhcmVseS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja05vdEVxdWFsKFVua25vd25GaWVsZFNldCBzMSwgVW5rbm93bkZpZWxkU2V0IHMyKSB7CisgICAgU3RyaW5nIGVxdWFsc0Vycm9yID0gU3RyaW5nLmZvcm1hdCgiJXMgc2hvdWxkIG5vdCBiZSBlcXVhbCB0byAlcyIsIHMxLCBzMik7CisgICAgYXNzZXJ0RmFsc2UoZXF1YWxzRXJyb3IsIHMxLmVxdWFscyhzMikpOworICAgIGFzc2VydEZhbHNlKGVxdWFsc0Vycm9yLCBzMi5lcXVhbHMoczEpKTsKKworICAgIGFzc2VydEZhbHNlKAorICAgICAgICBTdHJpbmcuZm9ybWF0KCIlcyBzaG91bGQgaGF2ZSBhIGRpZmZlcmVudCBoYXNoIGNvZGUgZnJvbSAlcyIsIHMxLCBzMiksCisgICAgICAgIHMxLmhhc2hDb2RlKCkgPT0gczIuaGFzaENvZGUoKSk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBmaWVsZCBzZXRzIGFyZSBlcXVhbCBhbmQgaGF2ZSBpZGVudGljYWwgaGFzaCBjb2Rlcy4KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja0VxdWFsc0lzQ29uc2lzdGVudChVbmtub3duRmllbGRTZXQgc2V0KSB7CisgICAgLy8gT2JqZWN0IHNob3VsZCBiZSBlcXVhbCB0byBpdHNlbGYuCisgICAgYXNzZXJ0RXF1YWxzKHNldCwgc2V0KTsKKworICAgIC8vIE9iamVjdCBzaG91bGQgYmUgZXF1YWwgdG8gYSBjb3B5IG9mIGl0c2VsZi4KKyAgICBVbmtub3duRmllbGRTZXQgY29weSA9IFVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKHNldCkuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoc2V0LCBjb3B5KTsKKyAgICBhc3NlcnRFcXVhbHMoY29weSwgc2V0KTsKKyAgICBhc3NlcnRFcXVhbHMoc2V0Lmhhc2hDb2RlKCksIGNvcHkuaGFzaENvZGUoKSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemVMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5TWVzc2FnZUxpdGUgPQorICAgICAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUucGFyc2VGcm9tKGFsbEZpZWxkc0RhdGEpOworICAgIGFzc2VydEVxdWFscyhhbGxGaWVsZHNEYXRhLnNpemUoKSwgZW1wdHlNZXNzYWdlTGl0ZS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBlbXB0eU1lc3NhZ2VMaXRlLnRvQnl0ZVN0cmluZygpOworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShkYXRhKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsbEZpZWxkc0RhdGEsIGRhdGEpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEFsbEV4dGVuc2lvbnNMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbEV4dGVuc2lvbnMgYWxsRXh0ZW5zaW9ucyA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBCeXRlU3RyaW5nIGFsbEV4dGVuc2lvbnNEYXRhID0gYWxsRXh0ZW5zaW9ucy50b0J5dGVTdHJpbmcoKTsKKyAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlNZXNzYWdlTGl0ZSA9CisgICAgICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZS5QQVJTRVIucGFyc2VGcm9tKGFsbEV4dGVuc2lvbnNEYXRhKTsKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBlbXB0eU1lc3NhZ2VMaXRlLnRvQnl0ZVN0cmluZygpOworICAgIFRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UgPQorICAgICAgICBUZXN0QWxsRXh0ZW5zaW9ucy5wYXJzZUZyb20oZGF0YSwgVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSk7CisgICAgVGVzdFV0aWwuYXNzZXJ0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMoYWxsRXh0ZW5zaW9uc0RhdGEsIGRhdGEpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEFsbFBhY2tlZEZpZWxkc0xpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0UGFja2VkVHlwZXMgYWxsUGFja2VkRmllbGRzID0gVGVzdFV0aWwuZ2V0UGFja2VkU2V0KCk7CisgICAgQnl0ZVN0cmluZyBhbGxQYWNrZWREYXRhID0gYWxsUGFja2VkRmllbGRzLnRvQnl0ZVN0cmluZygpOworICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eU1lc3NhZ2VMaXRlID0KKyAgICAgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlLnBhcnNlRnJvbShhbGxQYWNrZWREYXRhKTsKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBlbXB0eU1lc3NhZ2VMaXRlLnRvQnl0ZVN0cmluZygpOworICAgIFRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlID0KKyAgICAgICAgVGVzdFBhY2tlZFR5cGVzLnBhcnNlRnJvbShkYXRhLCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRQYWNrZWRGaWVsZHNTZXQobWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsbFBhY2tlZERhdGEsIGRhdGEpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEFsbFBhY2tlZEV4dGVuc2lvbnNMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnMgYWxsUGFja2VkRXh0ZW5zaW9ucyA9IFRlc3RVdGlsLmdldFBhY2tlZEV4dGVuc2lvbnNTZXQoKTsKKyAgICBCeXRlU3RyaW5nIGFsbFBhY2tlZEV4dGVuc2lvbnNEYXRhID0gYWxsUGFja2VkRXh0ZW5zaW9ucy50b0J5dGVTdHJpbmcoKTsKKyAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlNZXNzYWdlTGl0ZSA9CisgICAgICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZS5wYXJzZUZyb20oYWxsUGFja2VkRXh0ZW5zaW9uc0RhdGEpOworICAgIEJ5dGVTdHJpbmcgZGF0YSA9IGVtcHR5TWVzc2FnZUxpdGUudG9CeXRlU3RyaW5nKCk7CisgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnMgbWVzc2FnZSA9CisgICAgICAgIFRlc3RQYWNrZWRFeHRlbnNpb25zLnBhcnNlRnJvbShkYXRhLCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpKTsKKyAgICBUZXN0VXRpbC5hc3NlcnRQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworICAgIGFzc2VydEVxdWFscyhhbGxQYWNrZWRFeHRlbnNpb25zRGF0YSwgZGF0YSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0Q29weUZyb21MaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5TWVzc2FnZUxpdGUgPQorICAgICAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUucGFyc2VGcm9tKGFsbEZpZWxkc0RhdGEpOworICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eU1lc3NhZ2VMaXRlMiA9CisgICAgICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLm1lcmdlRnJvbShlbXB0eU1lc3NhZ2VMaXRlKS5idWlsZCgpOworICAgIGFzc2VydEVxdWFscyhlbXB0eU1lc3NhZ2VMaXRlLnRvQnl0ZVN0cmluZygpLCBlbXB0eU1lc3NhZ2VMaXRlMi50b0J5dGVTdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VGcm9tTGl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlMSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMSkKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJmb28iKQorICAgICAgICAuYWRkUmVwZWF0ZWRTdHJpbmcoImJhciIpCisgICAgICAgIC5zZXRPcHRpb25hbE5lc3RlZEVudW0oVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFaKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlMiA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50NjQoMikKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJiYXoiKQorICAgICAgICAuYWRkUmVwZWF0ZWRTdHJpbmcoInF1eCIpCisgICAgICAgIC5zZXRPcHRpb25hbEZvcmVpZ25FbnVtKEZvcmVpZ25FbnVtLkZPUkVJR05fQkFaKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIEJ5dGVTdHJpbmcgZGF0YTEgPSBtZXNzYWdlMS50b0J5dGVTdHJpbmcoKTsKKyAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlNZXNzYWdlTGl0ZTEgPQorICAgICAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUucGFyc2VGcm9tKGRhdGExKTsKKyAgICBCeXRlU3RyaW5nIGRhdGEyID0gbWVzc2FnZTIudG9CeXRlU3RyaW5nKCk7CisgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5TWVzc2FnZUxpdGUyID0KKyAgICAgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlLnBhcnNlRnJvbShkYXRhMik7CisKKyAgICBtZXNzYWdlMSA9IFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKG1lc3NhZ2UxKS5tZXJnZUZyb20obWVzc2FnZTIpLmJ1aWxkKCk7CisgICAgZW1wdHlNZXNzYWdlTGl0ZTEgPSBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUubmV3QnVpbGRlcihlbXB0eU1lc3NhZ2VMaXRlMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5tZXJnZUZyb20oZW1wdHlNZXNzYWdlTGl0ZTIpLmJ1aWxkKCk7CisKKyAgICBkYXRhMSA9IGVtcHR5TWVzc2FnZUxpdGUxLnRvQnl0ZVN0cmluZygpOworICAgIG1lc3NhZ2UyID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShkYXRhMSk7CisKKyAgICBhc3NlcnRFcXVhbHMobWVzc2FnZTEsIG1lc3NhZ2UyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RXcm9uZ1R5cGVUcmVhdGVkQXNVbmtub3duTGl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3QgdGhhdCBmaWVsZHMgb2YgdGhlIHdyb25nIHdpcmUgdHlwZSBhcmUgdHJlYXRlZCBsaWtlIHVua25vd24gZmllbGRzCisgICAgLy8gd2hlbiBwYXJzaW5nLgorCisgICAgQnl0ZVN0cmluZyBiaXphcnJvRGF0YSA9IGdldEJpemFycm9EYXRhKCk7CisgICAgVGVzdEFsbFR5cGVzIGFsbFR5cGVzTWVzc2FnZSA9IFRlc3RBbGxUeXBlcy5wYXJzZUZyb20oYml6YXJyb0RhdGEpOworICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eU1lc3NhZ2VMaXRlID0KKyAgICAgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlLnBhcnNlRnJvbShiaXphcnJvRGF0YSk7CisgICAgQnl0ZVN0cmluZyBkYXRhID0gZW1wdHlNZXNzYWdlTGl0ZS50b0J5dGVTdHJpbmcoKTsKKyAgICBUZXN0QWxsVHlwZXMgYWxsVHlwZXNNZXNzYWdlMiA9IFRlc3RBbGxUeXBlcy5wYXJzZUZyb20oZGF0YSk7CisKKyAgICBhc3NlcnRFcXVhbHMoYWxsVHlwZXNNZXNzYWdlLnRvU3RyaW5nKCksIGFsbFR5cGVzTWVzc2FnZTIudG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5rbm93bkV4dGVuc2lvbnNMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTWFrZSBzdXJlIGZpZWxkcyBhcmUgcHJvcGVybHkgcGFyc2VkIHRvIHRoZSBVbmtub3duRmllbGRTZXQgZXZlbiB3aGVuCisgICAgLy8gdGhleSBhcmUgZGVjbGFyZWQgYXMgZXh0ZW5zaW9uIG51bWJlcnMuCisKKyAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zTGl0ZSBtZXNzYWdlID0KKyAgICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNMaXRlLnBhcnNlRnJvbShhbGxGaWVsZHNEYXRhKTsKKworICAgIGFzc2VydEVxdWFscyhhbGxGaWVsZHNEYXRhLCBtZXNzYWdlLnRvQnl0ZVN0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RXcm9uZ0V4dGVuc2lvblR5cGVUcmVhdGVkQXNVbmtub3duTGl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3QgdGhhdCBmaWVsZHMgb2YgdGhlIHdyb25nIHdpcmUgdHlwZSBhcmUgdHJlYXRlZCBsaWtlIHVua25vd24gZmllbGRzCisgICAgLy8gd2hlbiBwYXJzaW5nIGV4dGVuc2lvbnMuCisKKyAgICBCeXRlU3RyaW5nIGJpemFycm9EYXRhID0gZ2V0Qml6YXJyb0RhdGEoKTsKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucyBhbGxFeHRlbnNpb25zTWVzc2FnZSA9CisgICAgICBUZXN0QWxsRXh0ZW5zaW9ucy5wYXJzZUZyb20oYml6YXJyb0RhdGEpOworICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eU1lc3NhZ2VMaXRlID0KKyAgICAgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlLnBhcnNlRnJvbShiaXphcnJvRGF0YSk7CisKKyAgICAvLyBBbGwgZmllbGRzIHNob3VsZCBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQgYXMgdW5rbm93biwgc28gdGhlIGJ5dGUgc3RyaW5ncworICAgIC8vIHNob3VsZCBiZSB0aGUgc2FtZS4KKyAgICBhc3NlcnRFcXVhbHMoZW1wdHlNZXNzYWdlTGl0ZS50b0J5dGVTdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgYWxsRXh0ZW5zaW9uc01lc3NhZ2UudG9CeXRlU3RyaW5nKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlVW5rbm93bkVudW1WYWx1ZUxpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3Igc2luZ3VsYXJGaWVsZCA9CisgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX2VudW0iKTsKKyAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgcmVwZWF0ZWRGaWVsZCA9CisgICAgICBUZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX2VudW0iKTsKKyAgICBhc3NlcnROb3ROdWxsKHNpbmd1bGFyRmllbGQpOworICAgIGFzc2VydE5vdE51bGwocmVwZWF0ZWRGaWVsZCk7CisKKyAgICBCeXRlU3RyaW5nIGRhdGEgPQorICAgICAgVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkRmllbGQoc2luZ3VsYXJGaWVsZC5nZXROdW1iZXIoKSwKKyAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVmFyaW50KFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkJBUi5nZXROdW1iZXIoKSkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoNSkgICAvLyBub3QgdmFsaWQKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYWRkRmllbGQocmVwZWF0ZWRGaWVsZC5nZXROdW1iZXIoKSwKKyAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVmFyaW50KFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTy5nZXROdW1iZXIoKSkKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoNCkgICAvLyBub3QgdmFsaWQKKyAgICAgICAgICAgIC5hZGRWYXJpbnQoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uQkFaLmdldE51bWJlcigpKQorICAgICAgICAgICAgLmFkZFZhcmludCg2KSAgIC8vIG5vdCB2YWxpZAorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpCisgICAgICAgIC50b0J5dGVTdHJpbmcoKTsKKworICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eU1lc3NhZ2VMaXRlID0KKyAgICAgICAgVW5pdHRlc3RMaXRlLlRlc3RFbXB0eU1lc3NhZ2VMaXRlLnBhcnNlRnJvbShkYXRhKTsKKyAgICBkYXRhID0gZW1wdHlNZXNzYWdlTGl0ZS50b0J5dGVTdHJpbmcoKTsKKworICAgIHsKKyAgICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShkYXRhKTsKKyAgICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsCisgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRPcHRpb25hbE5lc3RlZEVudW0oKSk7CisgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIEFycmF5cy5hc0xpc3QoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PLCBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVopLAorICAgICAgICBtZXNzYWdlLmdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSk7CisgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCg1TCksCisgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKHNpbmd1bGFyRmllbGQuZ2V0TnVtYmVyKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYXJpbnRMaXN0KCkpOworICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoNEwsIDZMKSwKKyAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdldFVua25vd25GaWVsZHMoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmllbGQocmVwZWF0ZWRGaWVsZC5nZXROdW1iZXIoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZhcmludExpc3QoKSk7CisgICAgfQorCisgICAgeworICAgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9CisgICAgICAgIFRlc3RBbGxFeHRlbnNpb25zLnBhcnNlRnJvbShkYXRhLCBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIsCisgICAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uKSk7CisgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIEFycmF5cy5hc0xpc3QoVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PLCBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVopLAorICAgICAgICBtZXNzYWdlLmdldEV4dGVuc2lvbihVbml0dGVzdFByb3RvLnJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbikpOworICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoNUwpLAorICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ2V0VW5rbm93bkZpZWxkcygpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZChzaW5ndWxhckZpZWxkLmdldE51bWJlcigpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0VmFyaW50TGlzdCgpKTsKKyAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KDRMLCA2TCksCisgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5nZXRVbmtub3duRmllbGRzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpZWxkKHJlcGVhdGVkRmllbGQuZ2V0TnVtYmVyKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYXJpbnRMaXN0KCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhckxpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlNZXNzYWdlTGl0ZTEgPQorICAgICAgICBVbml0dGVzdExpdGUuVGVzdEVtcHR5TWVzc2FnZUxpdGUucGFyc2VGcm9tKGFsbEZpZWxkc0RhdGEpOworICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eU1lc3NhZ2VMaXRlMiA9CisgICAgICAgIFVuaXR0ZXN0TGl0ZS5UZXN0RW1wdHlNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLm1lcmdlRnJvbShlbXB0eU1lc3NhZ2VMaXRlMSkuY2xlYXIoKS5idWlsZCgpOworICAgIGFzc2VydEVxdWFscygwLCBlbXB0eU1lc3NhZ2VMaXRlMi5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBlbXB0eU1lc3NhZ2VMaXRlMi50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgZGF0YS5zaXplKCkpOworICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1VubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0VGVzdC5qYXZhIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvVW5tb2RpZmlhYmxlTGF6eVN0cmluZ0xpc3RUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFjNzVmYwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1VubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjI3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0SXRlcmF0b3I7CisKKy8qKgorICogVGVzdHMgZm9yIHtAbGluayBVbm1vZGlmaWFibGVMYXp5U3RyaW5nTGlzdH0uCisgKgorICogQGF1dGhvciBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisgKi8KK3B1YmxpYyBjbGFzcyBVbm1vZGlmaWFibGVMYXp5U3RyaW5nTGlzdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFNUUklOR19BID0gIkEiOworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgU1RSSU5HX0IgPSAiQiI7CisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBTVFJJTkdfQyA9ICJDIjsKKworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIEJZVEVfU1RSSU5HX0EgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiQSIpOworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIEJZVEVfU1RSSU5HX0IgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiQiIpOworICBwcml2YXRlIHN0YXRpYyBCeXRlU3RyaW5nIEJZVEVfU1RSSU5HX0MgPSBCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiQyIpOworCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkT25seU1ldGhvZHMoKSB7CisgICAgTGF6eVN0cmluZ0FycmF5TGlzdCByYXdMaXN0ID0gY3JlYXRlU2FtcGxlTGlzdCgpOworICAgIFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0IGxpc3QgPSBuZXcgVW5tb2RpZmlhYmxlTGF6eVN0cmluZ0xpc3QocmF3TGlzdCk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIGxpc3Quc2l6ZSgpKTsKKyAgICBhc3NlcnRTYW1lKFNUUklOR19BLCBsaXN0LmdldCgwKSk7CisgICAgYXNzZXJ0U2FtZShTVFJJTkdfQiwgbGlzdC5nZXQoMSkpOworICAgIGFzc2VydFNhbWUoU1RSSU5HX0MsIGxpc3QuZ2V0KDIpKTsKKyAgICBhc3NlcnRFcXVhbHMoQllURV9TVFJJTkdfQSwgbGlzdC5nZXRCeXRlU3RyaW5nKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoQllURV9TVFJJTkdfQiwgbGlzdC5nZXRCeXRlU3RyaW5nKDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoQllURV9TVFJJTkdfQywgbGlzdC5nZXRCeXRlU3RyaW5nKDIpKTsKKworICAgIExpc3Q8Qnl0ZVN0cmluZz4gYnl0ZVN0cmluZ0xpc3QgPSBsaXN0LmFzQnl0ZVN0cmluZ0xpc3QoKTsKKyAgICBhc3NlcnRTYW1lKGxpc3QuZ2V0Qnl0ZVN0cmluZygwKSwgYnl0ZVN0cmluZ0xpc3QuZ2V0KDApKTsKKyAgICBhc3NlcnRTYW1lKGxpc3QuZ2V0Qnl0ZVN0cmluZygxKSwgYnl0ZVN0cmluZ0xpc3QuZ2V0KDEpKTsKKyAgICBhc3NlcnRTYW1lKGxpc3QuZ2V0Qnl0ZVN0cmluZygyKSwgYnl0ZVN0cmluZ0xpc3QuZ2V0KDIpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNb2RpZnlNZXRob2RzKCkgeworICAgIExhenlTdHJpbmdBcnJheUxpc3QgcmF3TGlzdCA9IGNyZWF0ZVNhbXBsZUxpc3QoKTsKKyAgICBVbm1vZGlmaWFibGVMYXp5U3RyaW5nTGlzdCBsaXN0ID0gbmV3IFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0KHJhd0xpc3QpOworCisgICAgdHJ5IHsKKyAgICAgIGxpc3QucmVtb3ZlKDApOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGV4cGVjdGVkCisgICAgfQorICAgIGFzc2VydEVxdWFscygzLCBsaXN0LnNpemUoKSk7CisKKyAgICB0cnkgeworICAgICAgbGlzdC5hZGQoU1RSSU5HX0IpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGV4cGVjdGVkCisgICAgfQorICAgIGFzc2VydEVxdWFscygzLCBsaXN0LnNpemUoKSk7CisKKyAgICB0cnkgeworICAgICAgbGlzdC5zZXQoMSwgU1RSSU5HX0IpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGV4cGVjdGVkCisgICAgfQorICAgIGFzc2VydEVxdWFscygzLCBsaXN0LnNpemUoKSk7CisKKyAgICBMaXN0PEJ5dGVTdHJpbmc+IGJ5dGVTdHJpbmdMaXN0ID0gbGlzdC5hc0J5dGVTdHJpbmdMaXN0KCk7CisgICAgdHJ5IHsKKyAgICAgIGJ5dGVTdHJpbmdMaXN0LnJlbW92ZSgwKTsKKyAgICAgIGZhaWwoKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBleHBlY3RlZAorICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMywgbGlzdC5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygzLCBieXRlU3RyaW5nTGlzdC5zaXplKCkpOworCisgICAgdHJ5IHsKKyAgICAgIGJ5dGVTdHJpbmdMaXN0LmFkZChCWVRFX1NUUklOR19CKTsKKyAgICAgIGZhaWwoKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBleHBlY3RlZAorICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMywgbGlzdC5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygzLCBieXRlU3RyaW5nTGlzdC5zaXplKCkpOworCisgICAgdHJ5IHsKKyAgICAgIGJ5dGVTdHJpbmdMaXN0LnNldCgxLCBCWVRFX1NUUklOR19CKTsKKyAgICAgIGZhaWwoKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBleHBlY3RlZAorICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMywgbGlzdC5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygzLCBieXRlU3RyaW5nTGlzdC5zaXplKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEl0ZXJhdG9yKCkgeworICAgIExhenlTdHJpbmdBcnJheUxpc3QgcmF3TGlzdCA9IGNyZWF0ZVNhbXBsZUxpc3QoKTsKKyAgICBVbm1vZGlmaWFibGVMYXp5U3RyaW5nTGlzdCBsaXN0ID0gbmV3IFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0KHJhd0xpc3QpOworCisgICAgSXRlcmF0b3I8U3RyaW5nPiBpdGVyID0gbGlzdC5pdGVyYXRvcigpOworICAgIGludCBjb3VudCA9IDA7CisgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICBpdGVyLm5leHQoKTsKKyAgICAgIGNvdW50Kys7CisgICAgICB0cnkgeworICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICBmYWlsKCk7CisgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICB9CisgICAgfQorICAgIGFzc2VydEVxdWFscygzLCBjb3VudCk7CisKKyAgICBMaXN0PEJ5dGVTdHJpbmc+IGJ5dGVTdHJpbmdMaXN0ID0gbGlzdC5hc0J5dGVTdHJpbmdMaXN0KCk7CisgICAgSXRlcmF0b3I8Qnl0ZVN0cmluZz4gYnl0ZUl0ZXIgPSBieXRlU3RyaW5nTGlzdC5pdGVyYXRvcigpOworICAgIGNvdW50ID0gMDsKKyAgICB3aGlsZSAoYnl0ZUl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICBieXRlSXRlci5uZXh0KCk7CisgICAgICBjb3VudCsrOworICAgICAgdHJ5IHsKKyAgICAgICAgYnl0ZUl0ZXIucmVtb3ZlKCk7CisgICAgICAgIGZhaWwoKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgIH0KKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKDMsIGNvdW50KTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RMaXN0SXRlcmF0b3IoKSB7CisgICAgTGF6eVN0cmluZ0FycmF5TGlzdCByYXdMaXN0ID0gY3JlYXRlU2FtcGxlTGlzdCgpOworICAgIFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0IGxpc3QgPSBuZXcgVW5tb2RpZmlhYmxlTGF6eVN0cmluZ0xpc3QocmF3TGlzdCk7CisKKyAgICBMaXN0SXRlcmF0b3I8U3RyaW5nPiBpdGVyID0gbGlzdC5saXN0SXRlcmF0b3IoKTsKKyAgICBpbnQgY291bnQgPSAwOworICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgeworICAgICAgaXRlci5uZXh0KCk7CisgICAgICBjb3VudCsrOworICAgICAgdHJ5IHsKKyAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgZmFpbCgpOworICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAvLyBleHBlY3RlZAorICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgaXRlci5zZXQoImJhciIpOworICAgICAgICBmYWlsKCk7CisgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBpdGVyLmFkZCgiYmFyIik7CisgICAgICAgIGZhaWwoKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgIH0KKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKDMsIGNvdW50KTsKKworICAgIExpc3Q8Qnl0ZVN0cmluZz4gYnl0ZVN0cmluZ0xpc3QgPSBsaXN0LmFzQnl0ZVN0cmluZ0xpc3QoKTsKKyAgICBMaXN0SXRlcmF0b3I8Qnl0ZVN0cmluZz4gYnl0ZUl0ZXIgPSBieXRlU3RyaW5nTGlzdC5saXN0SXRlcmF0b3IoKTsKKyAgICBjb3VudCA9IDA7CisgICAgd2hpbGUgKGJ5dGVJdGVyLmhhc05leHQoKSkgeworICAgICAgYnl0ZUl0ZXIubmV4dCgpOworICAgICAgY291bnQrKzsKKyAgICAgIHRyeSB7CisgICAgICAgIGJ5dGVJdGVyLnJlbW92ZSgpOworICAgICAgICBmYWlsKCk7CisgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBieXRlSXRlci5zZXQoQllURV9TVFJJTkdfQSk7CisgICAgICAgIGZhaWwoKTsKKyAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGJ5dGVJdGVyLmFkZChCWVRFX1NUUklOR19BKTsKKyAgICAgICAgZmFpbCgpOworICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAvLyBleHBlY3RlZAorICAgICAgfQorICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoMywgY291bnQpOworICB9CisKKyAgcHJpdmF0ZSBMYXp5U3RyaW5nQXJyYXlMaXN0IGNyZWF0ZVNhbXBsZUxpc3QoKSB7CisgICAgTGF6eVN0cmluZ0FycmF5TGlzdCByYXdMaXN0ID0gbmV3IExhenlTdHJpbmdBcnJheUxpc3QoKTsKKyAgICByYXdMaXN0LmFkZChTVFJJTkdfQSk7CisgICAgcmF3TGlzdC5hZGQoU1RSSU5HX0IpOworICAgIHJhd0xpc3QuYWRkKFNUUklOR19DKTsKKyAgICByZXR1cm4gcmF3TGlzdDsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdFRlc3QuamF2YSBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1dpcmVGb3JtYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg1ODUyNAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL1dpcmVGb3JtYXRUZXN0LmphdmEKQEAgLTAsMCArMSw2MDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzOworaW1wb3J0IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMjsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGU7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9uczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlczsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXQ7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQ7CitpbXBvcnQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTsKK2ltcG9ydCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RMaXRlLlRlc3RBbGxFeHRlbnNpb25zTGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0TGl0ZS5UZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGU7CisKKy8qKgorICogVGVzdHMgcmVsYXRlZCB0byBwYXJzaW5nIGFuZCBzZXJpYWxpemF0aW9uLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKyAqLworcHVibGljIGNsYXNzIFdpcmVGb3JtYXRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsU2V0KCk7CisKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRFcXVhbHMocmF3Qnl0ZXMuc2l6ZSgpLCBtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCkpOworCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UyID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShyYXdCeXRlcyk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25QYWNrZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0UGFja2VkVHlwZXMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldFBhY2tlZFNldCgpOworCisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisgICAgYXNzZXJ0RXF1YWxzKHJhd0J5dGVzLnNpemUoKSwgbWVzc2FnZS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKworICAgIFRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlMiA9IFRlc3RQYWNrZWRUeXBlcy5wYXJzZUZyb20ocmF3Qnl0ZXMpOworCisgICAgVGVzdFV0aWwuYXNzZXJ0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemVFeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGVzdEFsbFR5cGVzIGFuZCBUZXN0QWxsRXh0ZW5zaW9ucyBzaG91bGQgaGF2ZSBjb21wYXRpYmxlIHdpcmUgZm9ybWF0cywKKyAgICAvLyBzbyBpZiB3ZSBzZXJpYWxpemUgYSBUZXN0QWxsRXh0ZW5zaW9ucyB0aGVuIHBhcnNlIGl0IGFzIFRlc3RBbGxUeXBlcworICAgIC8vIGl0IHNob3VsZCB3b3JrLgorCisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRFcXVhbHMocmF3Qnl0ZXMuc2l6ZSgpLCBtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCkpOworCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UyID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShyYXdCeXRlcyk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZVBhY2tlZEV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUZXN0UGFja2VkVHlwZXMgYW5kIFRlc3RQYWNrZWRFeHRlbnNpb25zIHNob3VsZCBoYXZlIGNvbXBhdGlibGUgd2lyZQorICAgIC8vIGZvcm1hdHM7IGNoZWNrIHRoYXQgdGhleSBzZXJpYWxpemUgdG8gdGhlIHNhbWUgc3RyaW5nLgorICAgIFRlc3RQYWNrZWRFeHRlbnNpb25zIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRQYWNrZWRFeHRlbnNpb25zU2V0KCk7CisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisKKyAgICBUZXN0UGFja2VkVHlwZXMgbWVzc2FnZTIgPSBUZXN0VXRpbC5nZXRQYWNrZWRTZXQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzMiA9IG1lc3NhZ2UyLnRvQnl0ZVN0cmluZygpOworCisgICAgYXNzZXJ0RXF1YWxzKHJhd0J5dGVzLCByYXdCeXRlczIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25QYWNrZWRXaXRob3V0R2V0U2VyaWFsaXplZFNpemUoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgZGlyZWN0bHkgdG8gYW4gT3V0cHV0U3RyZWFtLCB3aXRob3V0IGludm9raW5nIGdldFNlcmlhbGl6ZWRTaXplKCkKKyAgICAvLyBUaGlzIHVzZWQgdG8gYmUgYSBidWcgd2hlcmUgdGhlIHNpemUgb2YgYSBwYWNrZWQgZmllbGQgd2FzIGluY29ycmVjdCwKKyAgICAvLyBzaW5jZSBnZXRTZXJpYWxpemVkU2l6ZSgpIHdhcyBuZXZlciBpbnZva2VkLgorICAgIFRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0UGFja2VkU2V0KCk7CisKKyAgICAvLyBEaXJlY3RseSBjb25zdHJ1Y3QgYSBDb2RlZE91dHB1dFN0cmVhbSBhcm91bmQgdGhlIGFjdHVhbCBPdXRwdXRTdHJlYW0sCisgICAgLy8gaW4gY2FzZSB3cml0ZVRvKE91dHB1dFN0cmVhbSBvdXRwdXQpIGludm9rZXMgZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkT3V0cHV0ID0gQ29kZWRPdXRwdXRTdHJlYW0ubmV3SW5zdGFuY2Uob3V0cHV0U3RyZWFtKTsKKworICAgIG1lc3NhZ2Uud3JpdGVUbyhjb2RlZE91dHB1dCk7CisKKyAgICBjb2RlZE91dHB1dC5mbHVzaCgpOworCisgICAgVGVzdFBhY2tlZFR5cGVzIG1lc3NhZ2UyID0gVGVzdFBhY2tlZFR5cGVzLnBhcnNlRnJvbSgKKyAgICAgICAgb3V0cHV0U3RyZWFtLnRvQnl0ZUFycmF5KCkpOworCisgICAgVGVzdFV0aWwuYXNzZXJ0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemVFeHRlbnNpb25zTGl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3RBbGxUeXBlcyBhbmQgVGVzdEFsbEV4dGVuc2lvbnMgc2hvdWxkIGhhdmUgY29tcGF0aWJsZSB3aXJlIGZvcm1hdHMsCisgICAgLy8gc28gaWYgd2Ugc2VyaWFsaXplIGEgVGVzdEFsbEV4dGVuc2lvbnMgdGhlbiBwYXJzZSBpdCBhcyBUZXN0QWxsVHlwZXMKKyAgICAvLyBpdCBzaG91bGQgd29yay4KKworICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZSBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsTGl0ZUV4dGVuc2lvbnNTZXQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRFcXVhbHMocmF3Qnl0ZXMuc2l6ZSgpLCBtZXNzYWdlLmdldFNlcmlhbGl6ZWRTaXplKCkpOworCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UyID0gVGVzdEFsbFR5cGVzLnBhcnNlRnJvbShyYXdCeXRlcyk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZVBhY2tlZEV4dGVuc2lvbnNMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGVzdFBhY2tlZFR5cGVzIGFuZCBUZXN0UGFja2VkRXh0ZW5zaW9ucyBzaG91bGQgaGF2ZSBjb21wYXRpYmxlIHdpcmUKKyAgICAvLyBmb3JtYXRzOyBjaGVjayB0aGF0IHRoZXkgc2VyaWFsaXplIHRvIHRoZSBzYW1lIHN0cmluZy4KKyAgICBUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUgbWVzc2FnZSA9IFRlc3RVdGlsLmdldExpdGVQYWNrZWRFeHRlbnNpb25zU2V0KCk7CisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisKKyAgICBUZXN0UGFja2VkVHlwZXMgbWVzc2FnZTIgPSBUZXN0VXRpbC5nZXRQYWNrZWRTZXQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzMiA9IG1lc3NhZ2UyLnRvQnl0ZVN0cmluZygpOworCisgICAgYXNzZXJ0RXF1YWxzKHJhd0J5dGVzLCByYXdCeXRlczIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlRXh0ZW5zaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3RBbGxUeXBlcyBhbmQgVGVzdEFsbEV4dGVuc2lvbnMgc2hvdWxkIGhhdmUgY29tcGF0aWJsZSB3aXJlIGZvcm1hdHMsCisgICAgLy8gc28gaWYgd2Ugc2VyaWFsaXplIGEgVGVzdEFsbFR5cGVzIHRoZW4gcGFyc2UgaXQgYXMgVGVzdEFsbEV4dGVuc2lvbnMKKyAgICAvLyBpdCBzaG91bGQgd29yay4KKworICAgIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gVGVzdFV0aWwuZ2V0QWxsU2V0KCk7CisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisKKyAgICBFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFRlc3RVdGlsLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CisKKyAgICBUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMiA9CisgICAgICBUZXN0QWxsRXh0ZW5zaW9ucy5wYXJzZUZyb20ocmF3Qnl0ZXMsIHJlZ2lzdHJ5KTsKKworICAgIFRlc3RVdGlsLmFzc2VydEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlUGFja2VkRXh0ZW5zaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEVuc3VyZSB0aGF0IHBhY2tlZCBleHRlbnNpb25zIGNhbiBiZSBwcm9wZXJseSBwYXJzZWQuCisgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnMgbWVzc2FnZSA9IFRlc3RVdGlsLmdldFBhY2tlZEV4dGVuc2lvbnNTZXQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKworICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKKworICAgIFRlc3RQYWNrZWRFeHRlbnNpb25zIG1lc3NhZ2UyID0KKyAgICAgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnMucGFyc2VGcm9tKHJhd0J5dGVzLCByZWdpc3RyeSk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUV4dGVuc2lvbnNMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGVzdEFsbFR5cGVzIGFuZCBUZXN0QWxsRXh0ZW5zaW9ucyBzaG91bGQgaGF2ZSBjb21wYXRpYmxlIHdpcmUgZm9ybWF0cywKKyAgICAvLyBzbyBpZiB3ZSBzZXJpYWxpemUgYSBUZXN0QWxsVHlwZXMgdGhlbiBwYXJzZSBpdCBhcyBUZXN0QWxsRXh0ZW5zaW9ucworICAgIC8vIGl0IHNob3VsZCB3b3JrLgorCisgICAgVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSBUZXN0VXRpbC5nZXRBbGxTZXQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKworICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeV9saXRlID0gVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnlMaXRlKCk7CisKKyAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUgbWVzc2FnZTIgPQorICAgICAgVGVzdEFsbEV4dGVuc2lvbnNMaXRlLnBhcnNlRnJvbShyYXdCeXRlcywgcmVnaXN0cnlfbGl0ZSk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKKworICAgIC8vIFRyeSBhZ2FpbiB1c2luZyBhIGZ1bGwgZXh0ZW5zaW9uIHJlZ2lzdHJ5LgorICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gVGVzdFV0aWwuZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKKworICAgIFRlc3RBbGxFeHRlbnNpb25zTGl0ZSBtZXNzYWdlMyA9CisgICAgICBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUucGFyc2VGcm9tKHJhd0J5dGVzLCByZWdpc3RyeSk7CisKKyAgICBUZXN0VXRpbC5hc3NlcnRBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UzKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVBhY2tlZEV4dGVuc2lvbnNMaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gRW5zdXJlIHRoYXQgcGFja2VkIGV4dGVuc2lvbnMgY2FuIGJlIHByb3Blcmx5IHBhcnNlZC4KKyAgICBUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUgbWVzc2FnZSA9IFRlc3RVdGlsLmdldExpdGVQYWNrZWRFeHRlbnNpb25zU2V0KCk7CisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IG1lc3NhZ2UudG9CeXRlU3RyaW5nKCk7CisKKyAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkgPSBUZXN0VXRpbC5nZXRFeHRlbnNpb25SZWdpc3RyeUxpdGUoKTsKKworICAgIFRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSBtZXNzYWdlMiA9CisgICAgICAgIFRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZS5wYXJzZUZyb20ocmF3Qnl0ZXMsIHJlZ2lzdHJ5KTsKKworICAgIFRlc3RVdGlsLmFzc2VydFBhY2tlZEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydE5vdFNhbWUoVGVzdFV0aWwuZ2V0QWxsU2V0KCkuZ2V0U2VyaWFsaXplZFNpemUoKSwKKyAgICAgICAgICAgICAgICAgIFRlc3RVdGlsLmdldEFsbEV4dGVuc2lvbnNTZXQoKS5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemVEZWxpbWl0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIFRlc3RVdGlsLmdldEFsbFNldCgpLndyaXRlRGVsaW1pdGVkVG8ob3V0cHV0KTsKKyAgICBvdXRwdXQud3JpdGUoMTIpOworICAgIFRlc3RVdGlsLmdldFBhY2tlZFNldCgpLndyaXRlRGVsaW1pdGVkVG8ob3V0cHV0KTsKKyAgICBvdXRwdXQud3JpdGUoMzQpOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW5wdXQgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ob3V0cHV0LnRvQnl0ZUFycmF5KCkpOworCisgICAgVGVzdFV0aWwuYXNzZXJ0QWxsRmllbGRzU2V0KFRlc3RBbGxUeXBlcy5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQpKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIsIGlucHV0LnJlYWQoKSk7CisgICAgVGVzdFV0aWwuYXNzZXJ0UGFja2VkRmllbGRzU2V0KFRlc3RQYWNrZWRUeXBlcy5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQpKTsKKyAgICBhc3NlcnRFcXVhbHMoMzQsIGlucHV0LnJlYWQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbnB1dC5yZWFkKCkpOworCisgICAgLy8gV2UncmUgYXQgRU9GLCBzbyBwYXJzaW5nIGFnYWluIHNob3VsZCByZXR1cm4gbnVsbC4KKyAgICBhc3NlcnRUcnVlKFRlc3RBbGxUeXBlcy5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQpID09IG51bGwpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydEZpZWxkc0luT3JkZXIoQnl0ZVN0cmluZyBkYXRhKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0ID0gZGF0YS5uZXdDb2RlZElucHV0KCk7CisgICAgaW50IHByZXZpb3VzVGFnID0gMDsKKworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOworICAgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBhc3NlcnRUcnVlKHRhZyA+IHByZXZpb3VzVGFnKTsKKyAgICAgIHByZXZpb3VzVGFnID0gdGFnOworICAgICAgaW5wdXQuc2tpcEZpZWxkKHRhZyk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEludGVybGVhdmVkRmllbGRzQW5kRXh0ZW5zaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRlc3RzIHRoYXQgZmllbGRzIGFyZSB3cml0dGVuIGluIG9yZGVyIGV2ZW4gd2hlbiBleHRlbnNpb24gcmFuZ2VzCisgICAgLy8gYXJlIGludGVybGVhdmVkIHdpdGggZmllbGQgbnVtYmVycy4KKyAgICBCeXRlU3RyaW5nIGRhdGEgPQorICAgICAgVGVzdEZpZWxkT3JkZXJpbmdzLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0TXlJbnQoMSkKKyAgICAgICAgLnNldE15U3RyaW5nKCJmb28iKQorICAgICAgICAuc2V0TXlGbG9hdCgxLjBGKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ubXlFeHRlbnNpb25JbnQsIDIzKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKFVuaXR0ZXN0UHJvdG8ubXlFeHRlbnNpb25TdHJpbmcsICJiYXIiKQorICAgICAgICAuYnVpbGQoKS50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRGaWVsZHNJbk9yZGVyKGRhdGEpOworCisgICAgRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gVGVzdEZpZWxkT3JkZXJpbmdzLmdldERlc2NyaXB0b3IoKTsKKyAgICBCeXRlU3RyaW5nIGR5bmFtaWNfZGF0YSA9CisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RGaWVsZE9yZGVyaW5ncy5nZXREZXNjcmlwdG9yKCkpCisgICAgICAgIC5zZXRGaWVsZChkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgibXlfaW50IiksIDFMKQorICAgICAgICAuc2V0RmllbGQoZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm15X3N0cmluZyIpLCAiZm9vIikKKyAgICAgICAgLnNldEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJteV9mbG9hdCIpLCAxLjBGKQorICAgICAgICAuc2V0RmllbGQoVW5pdHRlc3RQcm90by5teUV4dGVuc2lvbkludC5nZXREZXNjcmlwdG9yKCksIDIzKQorICAgICAgICAuc2V0RmllbGQoVW5pdHRlc3RQcm90by5teUV4dGVuc2lvblN0cmluZy5nZXREZXNjcmlwdG9yKCksICJiYXIiKQorICAgICAgICAuYnVpbGQoKS50b0J5dGVTdHJpbmcoKTsKKyAgICBhc3NlcnRGaWVsZHNJbk9yZGVyKGR5bmFtaWNfZGF0YSk7CisgIH0KKworICBwcml2YXRlIEV4dGVuc2lvblJlZ2lzdHJ5IGdldFRlc3RGaWVsZE9yZGVyaW5nc1JlZ2lzdHJ5KCkgeworICAgIEV4dGVuc2lvblJlZ2lzdHJ5IHJlc3VsdCA9IEV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CisgICAgcmVzdWx0LmFkZChVbml0dGVzdFByb3RvLm15RXh0ZW5zaW9uSW50KTsKKyAgICByZXN1bHQuYWRkKFVuaXR0ZXN0UHJvdG8ubXlFeHRlbnNpb25TdHJpbmcpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VNdWx0aXBsZUV4dGVuc2lvblJhbmdlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gcGFyc2UgYSBtZXNzYWdlIHRoYXQgY29udGFpbnMgbXVsdGlwbGUgZXh0ZW5zaW9ucworICAgIC8vIHJhbmdlcy4KKyAgICBUZXN0RmllbGRPcmRlcmluZ3Mgc291cmNlID0KKyAgICAgIFRlc3RGaWVsZE9yZGVyaW5ncy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE15SW50KDEpCisgICAgICAgIC5zZXRNeVN0cmluZygiZm9vIikKKyAgICAgICAgLnNldE15RmxvYXQoMS4wRikKKyAgICAgICAgLnNldEV4dGVuc2lvbihVbml0dGVzdFByb3RvLm15RXh0ZW5zaW9uSW50LCAyMykKKyAgICAgICAgLnNldEV4dGVuc2lvbihVbml0dGVzdFByb3RvLm15RXh0ZW5zaW9uU3RyaW5nLCAiYmFyIikKKyAgICAgICAgLmJ1aWxkKCk7CisgICAgVGVzdEZpZWxkT3JkZXJpbmdzIGRlc3QgPQorICAgICAgVGVzdEZpZWxkT3JkZXJpbmdzLnBhcnNlRnJvbShzb3VyY2UudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFRlc3RGaWVsZE9yZGVyaW5nc1JlZ2lzdHJ5KCkpOworICAgIGFzc2VydEVxdWFscyhzb3VyY2UsIGRlc3QpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFBhcnNlTXVsdGlwbGVFeHRlbnNpb25SYW5nZXNEeW5hbWljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2FtZSBhcyBhYm92ZSBleGNlcHQgd2l0aCBEeW5hbWljTWVzc2FnZS4KKyAgICBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGRlc2NyaXB0b3IgPSBUZXN0RmllbGRPcmRlcmluZ3MuZ2V0RGVzY3JpcHRvcigpOworICAgIER5bmFtaWNNZXNzYWdlIHNvdXJjZSA9CisgICAgICBEeW5hbWljTWVzc2FnZS5uZXdCdWlsZGVyKFRlc3RGaWVsZE9yZGVyaW5ncy5nZXREZXNjcmlwdG9yKCkpCisgICAgICAgIC5zZXRGaWVsZChkZXNjcmlwdG9yLmZpbmRGaWVsZEJ5TmFtZSgibXlfaW50IiksIDFMKQorICAgICAgICAuc2V0RmllbGQoZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoIm15X3N0cmluZyIpLCAiZm9vIikKKyAgICAgICAgLnNldEZpZWxkKGRlc2NyaXB0b3IuZmluZEZpZWxkQnlOYW1lKCJteV9mbG9hdCIpLCAxLjBGKQorICAgICAgICAuc2V0RmllbGQoVW5pdHRlc3RQcm90by5teUV4dGVuc2lvbkludC5nZXREZXNjcmlwdG9yKCksIDIzKQorICAgICAgICAuc2V0RmllbGQoVW5pdHRlc3RQcm90by5teUV4dGVuc2lvblN0cmluZy5nZXREZXNjcmlwdG9yKCksICJiYXIiKQorICAgICAgICAuYnVpbGQoKTsKKyAgICBEeW5hbWljTWVzc2FnZSBkZXN0ID0KKyAgICAgIER5bmFtaWNNZXNzYWdlLnBhcnNlRnJvbShkZXNjcmlwdG9yLCBzb3VyY2UudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VGVzdEZpZWxkT3JkZXJpbmdzUmVnaXN0cnkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKHNvdXJjZSwgZGVzdCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9UWVBFX0lEID0gMTU1MDA1NTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRZUEVfSURfMSA9CisgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLmdldERlc2NyaXB0b3IoKS5nZXRFeHRlbnNpb25zKCkuZ2V0KDApLmdldE51bWJlcigpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9JRF8yID0KKyAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIuZ2V0RGVzY3JpcHRvcigpLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkuZ2V0TnVtYmVyKCk7CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6ZU1lc3NhZ2VTZXRFYWdlcmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdGVzdFNlcmlhbGl6ZU1lc3NhZ2VTZXRXaXRoRmxhZyh0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemVNZXNzYWdlU2V0Tm90RWFnZXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRlc3RTZXJpYWxpemVNZXNzYWdlU2V0V2l0aEZsYWcoZmFsc2UpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHRlc3RTZXJpYWxpemVNZXNzYWdlU2V0V2l0aEZsYWcoYm9vbGVhbiBlYWdlclBhcnNpbmcpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUuc2V0RWFnZXJseVBhcnNlTWVzc2FnZVNldHMoZWFnZXJQYXJzaW5nKTsKKyAgICAvLyBTZXQgdXAgYSBUZXN0TWVzc2FnZVNldCB3aXRoIHR3byBrbm93biBtZXNzYWdlcyBhbmQgYW4gdW5rbm93biBvbmUuCisgICAgVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZVNldCA9CisgICAgICBUZXN0TWVzc2FnZVNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEV4dGVuc2lvbigKKyAgICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubWVzc2FnZVNldEV4dGVuc2lvbiwKKyAgICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubmV3QnVpbGRlcigpLnNldEkoMTIzKS5idWlsZCgpKQorICAgICAgICAuc2V0RXh0ZW5zaW9uKAorICAgICAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMi5tZXNzYWdlU2V0RXh0ZW5zaW9uLAorICAgICAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMi5uZXdCdWlsZGVyKCkuc2V0U3RyKCJmb28iKS5idWlsZCgpKQorICAgICAgICAuc2V0VW5rbm93bkZpZWxkcygKKyAgICAgICAgICBVbmtub3duRmllbGRTZXQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkRmllbGQoVU5LTk9XTl9UWVBFX0lELAorICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQuRmllbGQubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFkZExlbmd0aERlbGltaXRlZChCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiYmFyIikpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBtZXNzYWdlU2V0LnRvQnl0ZVN0cmluZygpOworCisgICAgLy8gUGFyc2UgYmFjayB1c2luZyBSYXdNZXNzYWdlU2V0IGFuZCBjaGVjayB0aGUgY29udGVudHMuCisgICAgUmF3TWVzc2FnZVNldCByYXcgPSBSYXdNZXNzYWdlU2V0LnBhcnNlRnJvbShkYXRhKTsKKworICAgIGFzc2VydFRydWUocmF3LmdldFVua25vd25GaWVsZHMoKS5hc01hcCgpLmlzRW1wdHkoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoMywgcmF3LmdldEl0ZW1Db3VudCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVFlQRV9JRF8xLCByYXcuZ2V0SXRlbSgwKS5nZXRUeXBlSWQoKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRZUEVfSURfMiwgcmF3LmdldEl0ZW0oMSkuZ2V0VHlwZUlkKCkpOworICAgIGFzc2VydEVxdWFscyhVTktOT1dOX1RZUEVfSUQsIHJhdy5nZXRJdGVtKDIpLmdldFR5cGVJZCgpKTsKKworICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBtZXNzYWdlMSA9CisgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEucGFyc2VGcm9tKAorICAgICAgICByYXcuZ2V0SXRlbSgwKS5nZXRNZXNzYWdlKCkudG9CeXRlQXJyYXkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbWVzc2FnZTEuZ2V0SSgpKTsKKworICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBtZXNzYWdlMiA9CisgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIucGFyc2VGcm9tKAorICAgICAgICByYXcuZ2V0SXRlbSgxKS5nZXRNZXNzYWdlKCkudG9CeXRlQXJyYXkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBtZXNzYWdlMi5nZXRTdHIoKSk7CisKKyAgICBhc3NlcnRFcXVhbHMoImJhciIsIHJhdy5nZXRJdGVtKDIpLmdldE1lc3NhZ2UoKS50b1N0cmluZ1V0ZjgoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VNZXNzYWdlU2V0RWFnZXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRlc3RQYXJzZU1lc3NhZ2VTZXRXaXRoRmxhZyh0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU1lc3NhZ2VTZXROb3RFYWdlcmx5KCl0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0ZXN0UGFyc2VNZXNzYWdlU2V0V2l0aEZsYWcoZmFsc2UpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHRlc3RQYXJzZU1lc3NhZ2VTZXRXaXRoRmxhZyhib29sZWFuIGVhZ2VyUGFyc2luZykKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5zZXRFYWdlcmx5UGFyc2VNZXNzYWdlU2V0cyhlYWdlclBhcnNpbmcpOworICAgIEV4dGVuc2lvblJlZ2lzdHJ5IGV4dGVuc2lvblJlZ2lzdHJ5ID0gRXh0ZW5zaW9uUmVnaXN0cnkubmV3SW5zdGFuY2UoKTsKKyAgICBleHRlbnNpb25SZWdpc3RyeS5hZGQoVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2VTZXRFeHRlbnNpb24pOworICAgIGV4dGVuc2lvblJlZ2lzdHJ5LmFkZChUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIubWVzc2FnZVNldEV4dGVuc2lvbik7CisKKyAgICAvLyBTZXQgdXAgYSBSYXdNZXNzYWdlU2V0IHdpdGggdHdvIGtub3duIG1lc3NhZ2VzIGFuZCBhbiB1bmtub3duIG9uZS4KKyAgICBSYXdNZXNzYWdlU2V0IHJhdyA9CisgICAgICBSYXdNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkSXRlbSgKKyAgICAgICAgICBSYXdNZXNzYWdlU2V0Lkl0ZW0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VHlwZUlkKFRZUEVfSURfMSkKKyAgICAgICAgICAgIC5zZXRNZXNzYWdlKAorICAgICAgICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEkoMTIzKQorICAgICAgICAgICAgICAgIC5idWlsZCgpLnRvQnl0ZVN0cmluZygpKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5hZGRJdGVtKAorICAgICAgICAgIFJhd01lc3NhZ2VTZXQuSXRlbS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRUeXBlSWQoVFlQRV9JRF8yKQorICAgICAgICAgICAgLnNldE1lc3NhZ2UoCisgICAgICAgICAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMi5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0U3RyKCJmb28iKQorICAgICAgICAgICAgICAgIC5idWlsZCgpLnRvQnl0ZVN0cmluZygpKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5hZGRJdGVtKAorICAgICAgICAgIFJhd01lc3NhZ2VTZXQuSXRlbS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRUeXBlSWQoVU5LTk9XTl9UWVBFX0lEKQorICAgICAgICAgICAgLnNldE1lc3NhZ2UoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoImJhciIpKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgQnl0ZVN0cmluZyBkYXRhID0gcmF3LnRvQnl0ZVN0cmluZygpOworCisgICAgLy8gUGFyc2UgYXMgYSBUZXN0TWVzc2FnZVNldCBhbmQgY2hlY2sgdGhlIGNvbnRlbnRzLgorICAgIFRlc3RNZXNzYWdlU2V0IG1lc3NhZ2VTZXQgPQorICAgICAgVGVzdE1lc3NhZ2VTZXQucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKworICAgIGFzc2VydEVxdWFscygxMjMsIG1lc3NhZ2VTZXQuZ2V0RXh0ZW5zaW9uKAorICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2VTZXRFeHRlbnNpb24pLmdldEkoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBtZXNzYWdlU2V0LmdldEV4dGVuc2lvbigKKyAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMi5tZXNzYWdlU2V0RXh0ZW5zaW9uKS5nZXRTdHIoKSk7CisKKyAgICAvLyBDaGVjayBmb3IgdW5rbm93biBmaWVsZCB3aXRoIHR5cGUgTEVOR1RIX0RFTElNSVRFRCwKKyAgICAvLyAgIG51bWJlciBVTktOT1dOX1RZUEVfSUQsIGFuZCBjb250ZW50cyAiYmFyIi4KKyAgICBVbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcyA9IG1lc3NhZ2VTZXQuZ2V0VW5rbm93bkZpZWxkcygpOworICAgIGFzc2VydEVxdWFscygxLCB1bmtub3duRmllbGRzLmFzTWFwKCkuc2l6ZSgpKTsKKyAgICBhc3NlcnRUcnVlKHVua25vd25GaWVsZHMuaGFzRmllbGQoVU5LTk9XTl9UWVBFX0lEKSk7CisKKyAgICBVbmtub3duRmllbGRTZXQuRmllbGQgZmllbGQgPSB1bmtub3duRmllbGRzLmdldEZpZWxkKFVOS05PV05fVFlQRV9JRCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGZpZWxkLmdldExlbmd0aERlbGltaXRlZExpc3QoKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygiYmFyIiwgZmllbGQuZ2V0TGVuZ3RoRGVsaW1pdGVkTGlzdCgpLmdldCgwKS50b1N0cmluZ1V0ZjgoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VNZXNzYWdlU2V0RXh0ZW5zaW9uRWFnZXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRlc3RQYXJzZU1lc3NhZ2VTZXRFeHRlbnNpb25XaXRoRmxhZyh0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU1lc3NhZ2VTZXRFeHRlbnNpb25Ob3RFYWdlcmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdGVzdFBhcnNlTWVzc2FnZVNldEV4dGVuc2lvbldpdGhGbGFnKGZhbHNlKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB0ZXN0UGFyc2VNZXNzYWdlU2V0RXh0ZW5zaW9uV2l0aEZsYWcoYm9vbGVhbiBlYWdlclBhcnNpbmcpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUuc2V0RWFnZXJseVBhcnNlTWVzc2FnZVNldHMoZWFnZXJQYXJzaW5nKTsKKyAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSA9IEV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CisgICAgZXh0ZW5zaW9uUmVnaXN0cnkuYWRkKFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uKTsKKworICAgIC8vIFNldCB1cCBhIFJhd01lc3NhZ2VTZXQgd2l0aCBhIGtub3duIG1lc3NhZ2VzLgorICAgIGludCBUWVBFX0lEXzEgPQorICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEKKyAgICAgICAgICAgIC5nZXREZXNjcmlwdG9yKCkuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKS5nZXROdW1iZXIoKTsKKyAgICBSYXdNZXNzYWdlU2V0IHJhdyA9CisgICAgICBSYXdNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkSXRlbSgKKyAgICAgICAgICBSYXdNZXNzYWdlU2V0Lkl0ZW0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VHlwZUlkKFRZUEVfSURfMSkKKyAgICAgICAgICAgIC5zZXRNZXNzYWdlKAorICAgICAgICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEkoMTIzKQorICAgICAgICAgICAgICAgIC5idWlsZCgpLnRvQnl0ZVN0cmluZygpKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgQnl0ZVN0cmluZyBkYXRhID0gcmF3LnRvQnl0ZVN0cmluZygpOworCisgICAgLy8gUGFyc2UgYXMgYSBUZXN0TWVzc2FnZVNldCBhbmQgY2hlY2sgdGhlIGNvbnRlbnRzLgorICAgIFRlc3RNZXNzYWdlU2V0IG1lc3NhZ2VTZXQgPQorICAgICAgICBUZXN0TWVzc2FnZVNldC5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgIGFzc2VydEVxdWFscygxMjMsIG1lc3NhZ2VTZXQuZ2V0RXh0ZW5zaW9uKAorICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubWVzc2FnZVNldEV4dGVuc2lvbikuZ2V0SSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUxhenlNZXNzYWdlU2V0RXh0ZW5zaW9uRWFnZXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRlc3RNZXJnZUxhenlNZXNzYWdlU2V0RXh0ZW5zaW9uV2l0aEZsYWcodHJ1ZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VMYXp5TWVzc2FnZVNldEV4dGVuc2lvbk5vdEVhZ2VybHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0ZXN0TWVyZ2VMYXp5TWVzc2FnZVNldEV4dGVuc2lvbldpdGhGbGFnKGZhbHNlKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB0ZXN0TWVyZ2VMYXp5TWVzc2FnZVNldEV4dGVuc2lvbldpdGhGbGFnKGJvb2xlYW4gZWFnZXJQYXJzaW5nKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLnNldEVhZ2VybHlQYXJzZU1lc3NhZ2VTZXRzKGVhZ2VyUGFyc2luZyk7CisgICAgRXh0ZW5zaW9uUmVnaXN0cnkgZXh0ZW5zaW9uUmVnaXN0cnkgPSBFeHRlbnNpb25SZWdpc3RyeS5uZXdJbnN0YW5jZSgpOworICAgIGV4dGVuc2lvblJlZ2lzdHJ5LmFkZChUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubWVzc2FnZVNldEV4dGVuc2lvbik7CisKKyAgICAvLyBTZXQgdXAgYSBSYXdNZXNzYWdlU2V0IHdpdGggYSBrbm93biBtZXNzYWdlcy4KKyAgICBpbnQgVFlQRV9JRF8xID0KKyAgICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xCisgICAgICAgICAgICAuZ2V0RGVzY3JpcHRvcigpLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkuZ2V0TnVtYmVyKCk7CisgICAgUmF3TWVzc2FnZVNldCByYXcgPQorICAgICAgUmF3TWVzc2FnZVNldC5uZXdCdWlsZGVyKCkKKyAgICAgICAgLmFkZEl0ZW0oCisgICAgICAgICAgUmF3TWVzc2FnZVNldC5JdGVtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFR5cGVJZChUWVBFX0lEXzEpCisgICAgICAgICAgICAuc2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRJKDEyMykKKyAgICAgICAgICAgICAgICAuYnVpbGQoKS50b0J5dGVTdHJpbmcoKSkKKyAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuYnVpbGQoKTsKKworICAgIEJ5dGVTdHJpbmcgZGF0YSA9IHJhdy50b0J5dGVTdHJpbmcoKTsKKworICAgIC8vIFBhcnNlIGFzIGEgVGVzdE1lc3NhZ2VTZXQgYW5kIHN0b3JlIHZhbHVlIGludG8gbGF6eSBmaWVsZAorICAgIFRlc3RNZXNzYWdlU2V0IG1lc3NhZ2VTZXQgPQorICAgICAgICBUZXN0TWVzc2FnZVNldC5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgIC8vIE1lcmdlIGxhenkgZmllbGQgY2hlY2sgdGhlIGNvbnRlbnRzLgorICAgIG1lc3NhZ2VTZXQgPQorICAgICAgICBtZXNzYWdlU2V0LnRvQnVpbGRlcigpLm1lcmdlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSkuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBtZXNzYWdlU2V0LmdldEV4dGVuc2lvbigKKyAgICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2VTZXRFeHRlbnNpb24pLmdldEkoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VNZXNzYWdlU2V0RXh0ZW5zaW9uRWFnZXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRlc3RNZXJnZU1lc3NhZ2VTZXRFeHRlbnNpb25XaXRoRmxhZyh0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZU1lc3NhZ2VTZXRFeHRlbnNpb25Ob3RFYWdlcmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdGVzdE1lcmdlTWVzc2FnZVNldEV4dGVuc2lvbldpdGhGbGFnKGZhbHNlKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB0ZXN0TWVyZ2VNZXNzYWdlU2V0RXh0ZW5zaW9uV2l0aEZsYWcoYm9vbGVhbiBlYWdlclBhcnNpbmcpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUuc2V0RWFnZXJseVBhcnNlTWVzc2FnZVNldHMoZWFnZXJQYXJzaW5nKTsKKyAgICBFeHRlbnNpb25SZWdpc3RyeSBleHRlbnNpb25SZWdpc3RyeSA9IEV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CisgICAgZXh0ZW5zaW9uUmVnaXN0cnkuYWRkKFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uKTsKKworICAgIC8vIFNldCB1cCBhIFJhd01lc3NhZ2VTZXQgd2l0aCBhIGtub3duIG1lc3NhZ2VzLgorICAgIGludCBUWVBFX0lEXzEgPQorICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEKKyAgICAgICAgICAgIC5nZXREZXNjcmlwdG9yKCkuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKS5nZXROdW1iZXIoKTsKKyAgICBSYXdNZXNzYWdlU2V0IHJhdyA9CisgICAgICBSYXdNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKQorICAgICAgICAuYWRkSXRlbSgKKyAgICAgICAgICBSYXdNZXNzYWdlU2V0Lkl0ZW0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VHlwZUlkKFRZUEVfSURfMSkKKyAgICAgICAgICAgIC5zZXRNZXNzYWdlKAorICAgICAgICAgICAgICBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEkoMTIzKQorICAgICAgICAgICAgICAgIC5idWlsZCgpLnRvQnl0ZVN0cmluZygpKQorICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gU2VyaWFsaXplIFJhd01lc3NhZ2VTZXQgdW5ub3JtYWxseSAobWVzc2FnZSB2YWx1ZSBiZWZvcmUgdHlwZSBpZCkKKyAgICBCeXRlU3RyaW5nLkNvZGVkQnVpbGRlciBvdXQgPSBCeXRlU3RyaW5nLm5ld0NvZGVkQnVpbGRlcigKKyAgICAgICAgcmF3LmdldFNlcmlhbGl6ZWRTaXplKCkpOworICAgIENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCA9IG91dC5nZXRDb2RlZE91dHB1dCgpOworICAgIExpc3Q8UmF3TWVzc2FnZVNldC5JdGVtPiBpdGVtcyA9IHJhdy5nZXRJdGVtTGlzdCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaXRlbXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIFJhd01lc3NhZ2VTZXQuSXRlbSBpdGVtID0gaXRlbXMuZ2V0KGkpOworICAgICAgb3V0cHV0LndyaXRlVGFnKDEsIFdpcmVGb3JtYXQuV0lSRVRZUEVfU1RBUlRfR1JPVVApOworICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMywgaXRlbS5nZXRNZXNzYWdlKCkpOworICAgICAgb3V0cHV0LndyaXRlSW50MzIoMiwgaXRlbS5nZXRUeXBlSWQoKSk7CisgICAgICBvdXRwdXQud3JpdGVUYWcoMSwgV2lyZUZvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApOworICAgIH0KKyAgICBCeXRlU3RyaW5nIGRhdGEgPSBvdXQuYnVpbGQoKTsKKworICAgIC8vIE1lcmdlIGJ5dGVzIGludG8gVGVzdE1lc3NhZ2VTZXQgYW5kIGNoZWNrIHRoZSBjb250ZW50cy4KKyAgICBUZXN0TWVzc2FnZVNldCBtZXNzYWdlU2V0ID0KKyAgICAgICAgVGVzdE1lc3NhZ2VTZXQubmV3QnVpbGRlcigpLm1lcmdlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSkuYnVpbGQoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBtZXNzYWdlU2V0LmdldEV4dGVuc2lvbigKKyAgICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2VTZXRFeHRlbnNpb24pLmdldEkoKSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIG9uZW9mCisgIHB1YmxpYyB2b2lkIHRlc3RPbmVvZldpcmVGb3JtYXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0T25lb2YyLkJ1aWxkZXIgYnVpbGRlciA9IFRlc3RPbmVvZjIubmV3QnVpbGRlcigpOworICAgIFRlc3RVdGlsLnNldE9uZW9mKGJ1aWxkZXIpOworICAgIFRlc3RPbmVvZjIgbWVzc2FnZSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBCeXRlU3RyaW5nIHJhd0J5dGVzID0gbWVzc2FnZS50b0J5dGVTdHJpbmcoKTsKKworICAgIGFzc2VydEVxdWFscyhyYXdCeXRlcy5zaXplKCksIG1lc3NhZ2UuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisKKyAgICBUZXN0T25lb2YyIG1lc3NhZ2UyID0gVGVzdE9uZW9mMi5wYXJzZUZyb20ocmF3Qnl0ZXMpOworICAgIFRlc3RVdGlsLmFzc2VydE9uZW9mU2V0KG1lc3NhZ2UyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RPbmVvZk9ubHlMYXN0U2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBzb3VyY2UgPSBUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlCisgICAgICAgIC5uZXdCdWlsZGVyKCkuc2V0Rm9vSW50KDEwMCkuc2V0Rm9vU3RyaW5nKCIxMDEiKS5idWlsZCgpOworCisgICAgQnl0ZVN0cmluZyByYXdCeXRlcyA9IHNvdXJjZS50b0J5dGVTdHJpbmcoKTsKKyAgICBUZXN0T25lb2YyIG1lc3NhZ2UgPSBUZXN0T25lb2YyLnBhcnNlRnJvbShyYXdCeXRlcyk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNGb29JbnQoKSk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0Zvb1N0cmluZygpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvZmllbGRfcHJlc2VuY2VfdGVzdC5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX3ByZXNlbmNlX3Rlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQ4ZWE4ZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX3ByZXNlbmNlX3Rlc3QucHJvdG8KQEAgLTAsMCArMSw5MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGZpZWxkX3ByZXNlbmNlX3Rlc3Q7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvIjsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJGaWVsZFByZXNlbmNlVGVzdFByb3RvIjsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CisKK21lc3NhZ2UgVGVzdEFsbFR5cGVzIHsKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAwOworICAgIEJBUiA9IDE7CisgICAgQkFaID0gMjsKKyAgfQorICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgfQorCisgIG9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7CisgIG9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMzsKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7CisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OworCisgIG9uZW9mIG9uZW9mX2ZpZWxkIHsKKyAgICBpbnQzMiBvbmVvZl9pbnQzMiA9IDExOworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7CisgICAgYnl0ZXMgb25lb2ZfYnl0ZXMgPSAxNDsKKyAgICBOZXN0ZWRFbnVtIG9uZW9mX25lc3RlZF9lbnVtID0gMTU7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OworICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvbmVvZl9wcm90bzJfbWVzc2FnZSA9IDE3OworICB9CisKKyAgcmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOworICByZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOworICByZXBlYXRlZCBOZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7CisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7CisgIHJlcGVhdGVkIE5lc3RlZEVudW0gcGFja2VkX25lc3RlZF9lbnVtID0gMjcgW3BhY2tlZCA9IHRydWVdOworfQorCittZXNzYWdlIFRlc3RPcHRpb25hbEZpZWxkc09ubHkgeworICBvcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAyOworICBvcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDM7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OworfQorCittZXNzYWdlIFRlc3RSZXBlYXRlZEZpZWxkc09ubHkgeworICByZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7CisgIHJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbGF6eV9maWVsZHNfbGl0ZS5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2xhenlfZmllbGRzX2xpdGUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU4MGY3MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2xhenlfZmllbGRzX2xpdGUucHJvdG8KQEAgLTAsMCArMSw3MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogTmFva2kgSXdhc2FraSAobml3YXNha2lAZ29vZ2xlLmNvbSkKKy8vCisvLyBBIHByb3RvIGZpbGUgd2l0aCBsYXp5IGZpZWxkcworCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRTsKKworbWVzc2FnZSBMYXp5TWVzc2FnZUxpdGUgeworICBvcHRpb25hbCBpbnQzMiBudW0gPSAxOworICBvcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDQyMV07CisgIG9wdGlvbmFsIExhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOworICByZXBlYXRlZCBMYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTsKKworICBvbmVvZiBvbmVvZl9maWVsZCB7CisgICAgaW50MzIgb25lb2ZfbnVtID0gNTsKKyAgICBMYXp5SW5uZXJNZXNzYWdlTGl0ZSBvbmVvZl9pbm5lciA9IDYgW2xhenkgPSB0cnVlXTsKKyAgfQorfQorCittZXNzYWdlIExhenlJbm5lck1lc3NhZ2VMaXRlIHsKKyAgb3B0aW9uYWwgaW50MzIgbnVtID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgbnVtX3dpdGhfZGVmYXVsdCA9IDIgW2RlZmF1bHQgPSA0Ml07CisgIG9wdGlvbmFsIExhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIG5lc3RlZCA9IDMgW2xhenkgPSB0cnVlXTsKKworICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworfQorCittZXNzYWdlIExhenlFeHRlbnNpb24geworICBleHRlbmQgTGF6eUlubmVyTWVzc2FnZUxpdGUgeworICAgIG9wdGlvbmFsIExhenlFeHRlbnNpb24gZXh0ZW5zaW9uID0gMTAwMDsKKyAgfQorICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7Cit9CisKK21lc3NhZ2UgTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgeworICBvcHRpb25hbCBpbnQzMiBudW0gPSAxOworICBvcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDRdOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbGl0ZV9lcXVhbHNfYW5kX2hhc2gucHJvdG8gYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9saXRlX2VxdWFsc19hbmRfaGFzaC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjgzNzI1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbGl0ZV9lcXVhbHNfYW5kX2hhc2gucHJvdG8KQEAgLTAsMCArMSw3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogcGJvZ2xlQGdvb2dsZS5jb20gKFBoaWwgQm9nbGUpCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoOworCisvLyBUaGlzIHByb3RvIGRlZmluaXRpb24gaXMgdXNlZCB0byB0ZXN0IHRoYXQgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2gKKy8vIHdvcmtzIGNvcnJlY3RseSB3aXRoIHRoZSBMSVRFX1JVTlRJTUUuCitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRTsKKworbWVzc2FnZSBGb28geworICBvcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7CisgIHJlcGVhdGVkIEJhciBiYXIgPSAyOworCisgIGV4dGVuc2lvbnMgMTAwIHRvIG1heDsKK30KKworbWVzc2FnZSBCYXIgeworICBleHRlbmQgRm9vIHsKKyAgICBvcHRpb25hbCBCYXIgZm9vX2V4dCA9IDEwMDsKKyAgfQorCisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK30KKworbWVzc2FnZSBCYXJQcmltZSB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK30KKworbWVzc2FnZSBFbXB0eSB7Cit9CisKK2V4dGVuZCBGb28geworICBvcHRpb25hbCBpbnQzMiB2YXJpbnQgPSAxMDE7CisgIG9wdGlvbmFsIGZpeGVkMzIgZml4ZWQzMiA9IDEwMjsKKyAgb3B0aW9uYWwgZml4ZWQ2NCBmaXhlZDY0ID0gMTAzOworICBvcHRpb25hbCBncm91cCBNeUdyb3VwID0gMTA0IHsKKyAgICBvcHRpb25hbCBzdHJpbmcgZ3JvdXBfdmFsdWUgPSAxOworICB9Cit9CisKZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTQxOGYyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LnByb3RvCkBAIC0wLDAgKzEsNzUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8yIjsKKworCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiTWFwRm9yUHJvdG8yVGVzdFByb3RvIjsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CisKK21lc3NhZ2UgVGVzdE1hcCB7CisgIG1lc3NhZ2UgTWVzc2FnZVZhbHVlIHsKKyAgICBvcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7CisgIH0KKyAgZW51bSBFbnVtVmFsdWUgeworICAgIEZPTyA9IDA7CisgICAgQkFSID0gMTsKKyAgICBCQVogPSAyOworICAgIFFVWCA9IDM7CisgIH0KKworICBtYXA8aW50MzIsIGludDMyPiAgICAgICAgIGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTsKKyAgbWFwPGludDMyLCBzdHJpbmc+ICAgICAgICBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOworICBtYXA8aW50MzIsIGJ5dGVzPiAgICAgICAgIGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzsKKyAgbWFwPGludDMyLCBFbnVtVmFsdWU+ICAgICBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDsKKyAgbWFwPGludDMyLCBNZXNzYWdlVmFsdWU+ICBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTsKKyAgbWFwPHN0cmluZywgaW50MzI+ICAgICAgICBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OworCisgIG1lc3NhZ2UgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyB7CisgICAgcmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOworICB9CisgIG1hcDxpbnQzMiwgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTsKK30KKworbWVzc2FnZSBUZXN0VW5rbm93bkVudW1WYWx1ZSB7CisgIC8vIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKKyAgLy8gcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgorICBtYXA8aW50MzIsIGludDMyPiBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7Cit9CisKKy8vIFRlc3QgdGhhdCB0aGUgbWFwcyBpbml0aWFsaXphdGlvbiBjb2RlIHdvcmtzIGNvcnJlY3RseSB3aGVuIHRoZSBtYXAgZmllbGQKKy8vIHJlZmVyZW5jZXMgdGhlIGNvbnRhaW5pbmcgbWVzc2FnZS4KK21lc3NhZ2UgVGVzdFJlY3Vyc2l2ZU1hcCB7CisgIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgbWFwPGludDMyLCBUZXN0UmVjdXJzaXZlTWFwPiByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjsKK30KK3BhY2thZ2UgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0Oworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJtYXBfbGl0ZV90ZXN0IjsKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfZm9yX3Byb3RvMl90ZXN0LnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbWFwX2Zvcl9wcm90bzJfdGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOWJlNTE2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbWFwX2Zvcl9wcm90bzJfdGVzdC5wcm90bwpAQCAtMCwwICsxLDc0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgbWFwX2Zvcl9wcm90bzJfdGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJtYXBfdGVzdCI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiTWFwRm9yUHJvdG8yVGVzdFByb3RvIjsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CisKK21lc3NhZ2UgVGVzdE1hcCB7CisgIG1lc3NhZ2UgTWVzc2FnZVZhbHVlIHsKKyAgICBvcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7CisgIH0KKyAgZW51bSBFbnVtVmFsdWUgeworICAgIEZPTyA9IDA7CisgICAgQkFSID0gMTsKKyAgICBCQVogPSAyOworICAgIFFVWCA9IDM7CisgIH0KKworICBtYXA8aW50MzIsIGludDMyPiAgICAgICAgIGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTsKKyAgbWFwPGludDMyLCBzdHJpbmc+ICAgICAgICBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOworICBtYXA8aW50MzIsIGJ5dGVzPiAgICAgICAgIGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzsKKyAgbWFwPGludDMyLCBFbnVtVmFsdWU+ICAgICBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDsKKyAgbWFwPGludDMyLCBNZXNzYWdlVmFsdWU+ICBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTsKKyAgbWFwPHN0cmluZywgaW50MzI+ICAgICAgICBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OworCisgIG1lc3NhZ2UgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyB7CisgICAgcmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOworICB9CisgIG1hcDxpbnQzMiwgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTsKK30KKworbWVzc2FnZSBUZXN0VW5rbm93bkVudW1WYWx1ZSB7CisgIC8vIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKKyAgLy8gcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgorICBtYXA8aW50MzIsIGludDMyPiBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7Cit9CisKKy8vIFRlc3QgdGhhdCB0aGUgbWFwcyBpbml0aWFsaXphdGlvbiBjb2RlIHdvcmtzIGNvcnJlY3RseSB3aGVuIHRoZSBtYXAgZmllbGQKKy8vIHJlZmVyZW5jZXMgdGhlIGNvbnRhaW5pbmcgbWVzc2FnZS4KK21lc3NhZ2UgVGVzdFJlY3Vyc2l2ZU1hcCB7CisgIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgbWFwPGludDMyLCBUZXN0UmVjdXJzaXZlTWFwPiByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmY2OTJjMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LnByb3RvCkBAIC0wLDAgKzEsNjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBtYXBfdGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJtYXBfdGVzdCI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiTWFwVGVzdFByb3RvIjsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CisKKworbWVzc2FnZSBUZXN0TWFwIHsKKyAgbWVzc2FnZSBNZXNzYWdlVmFsdWUgeworICAgIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgfQorICBlbnVtIEVudW1WYWx1ZSB7CisgICAgRk9PID0gMDsKKyAgICBCQVIgPSAxOworICAgIEJBWiA9IDI7CisgICAgUVVYID0gMzsKKyAgfQorCisgIG1hcDxpbnQzMiwgaW50MzI+ICAgICAgICBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7CisgIG1hcDxpbnQzMiwgc3RyaW5nPiAgICAgICBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOworICBtYXA8aW50MzIsIGJ5dGVzPiAgICAgICAgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOworICBtYXA8aW50MzIsIEVudW1WYWx1ZT4gICAgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7CisgIG1hcDxpbnQzMiwgTWVzc2FnZVZhbHVlPiBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTsKKyAgbWFwPHN0cmluZywgaW50MzI+ICAgICAgIHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7Cit9CisKKy8vIFVzZWQgdG8gdGVzdCB0aGF0IGEgbmVzdGVkIGJ1bGlkZXIgY29udGFpbmluZyBtYXAgZmllbGRzIHdpbGwgcHJvcGVybHkKKy8vIHByb3BhZ2F0ZSB0aGUgb25DaGFuZ2UgZXZlbnQgYW5kIG1hcmsgaXRzIHBhcmVudCBkaXJ0eSB3aGVuIGEgY2hhbmdlCisvLyBpcyBtYWRlIHRvIGEgbWFwIGZpZWxkLgorbWVzc2FnZSBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIHsKKyAgb3B0aW9uYWwgVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL211bHRpcGxlX2ZpbGVzX3Rlc3QucHJvdG8gYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyNzkwNTAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvCkBAIC0wLDAgKzEsNzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gQSBwcm90byBmaWxlIHdoaWNoIHRlc3RzIHRoZSBqYXZhX211bHRpcGxlX2ZpbGVzIG9wdGlvbi4KKworc3ludGF4ID0gInByb3RvMiI7CisKKy8vIFNvbWUgZ2VuZXJpY19zZXJ2aWNlcyBvcHRpb24ocykgYWRkZWQgYXV0b21hdGljYWxseS4KKy8vIFNlZTogIGh0dHA6Ly9nby9wcm90bzItZ2VuZXJpYy1zZXJ2aWNlcy1kZWZhdWx0CitvcHRpb24gamF2YV9nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAvLyBhdXRvLWFkZGVkCisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiTXVsdGlwbGVGaWxlc1Rlc3RQcm90byI7CisKKworbWVzc2FnZSBNZXNzYWdlV2l0aE5vT3V0ZXIgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDMyIGkgPSAxOworICB9CisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgQkFaID0gMzsKKyAgfQorICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG5lc3RlZCA9IDE7CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjsKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBuZXN0ZWRfZW51bSA9IDM7CisgIG9wdGlvbmFsIEVudW1XaXRoTm9PdXRlciBmb3JlaWduX2VudW0gPSA0OworfQorCitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgeworICBvcHRpb25hbCBpbnQzMiBlbnVtX3ZhbHVlX29wdGlvbiA9IDc2NTQzMjE7Cit9CisKK2VudW0gRW51bVdpdGhOb091dGVyIHsKKyAgRk9PID0gMSBbKGVudW1fdmFsdWVfb3B0aW9uKSA9IDEyMzQ1XTsKKyAgQkFSID0gMjsKK30KKworc2VydmljZSBTZXJ2aWNlV2l0aE5vT3V0ZXIgeworICBycGMgRm9vKE1lc3NhZ2VXaXRoTm9PdXRlcikgcmV0dXJucyhUZXN0QWxsVHlwZXMpOworfQorCitleHRlbmQgVGVzdEFsbEV4dGVuc2lvbnMgeworICBvcHRpb25hbCBpbnQzMiBleHRlbnNpb25fd2l0aF9vdXRlciA9IDEyMzQ1Njc7Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGVzdC5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9idWlsZGVyc190ZXN0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1ZGQ2NmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGVzdC5wcm90bwpAQCAtMCwwICsxLDU0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisvLworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJOZXN0ZWRCdWlsZGVycyI7CisKKworbWVzc2FnZSBWZWhpY2xlIHsKKyAgb3B0aW9uYWwgRW5naW5lIGVuZ2luZSA9IDE7CisgIHJlcGVhdGVkIFdoZWVsIHdoZWVsID0gMjsKK30KKworbWVzc2FnZSBFbmdpbmUgeworICBvcHRpb25hbCBpbnQzMiBjeWxpbmRlciA9IDE7CisgIG9wdGlvbmFsIGludDMyIGxpdGVycyA9IDI7Cit9CisKK21lc3NhZ2UgV2hlZWwgeworICBvcHRpb25hbCBpbnQzMiByYWRpdXMgPSAxOworICBvcHRpb25hbCBpbnQzMiB3aWR0aCA9IDI7Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfZXh0ZW5zaW9uLnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2V4dGVuc2lvbi5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDRlNjQ5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2V4dGVuc2lvbi5wcm90bwpAQCAtMCwwICsxLDQ3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBEYXJpY2sgVG9uZyAoZGFyaWNrQGdvb2dsZS5jb20pCisvLworLy8gQSBwcm90byBmaWxlIHdpdGggbmVzdGVkIGV4dGVuc2lvbnMuIE5vdGUgdGhhdCB0aGlzIG11c3QgYmUgZGVmaW5lZCBpbgorLy8gYSBzZXBhcmF0ZSBmaWxlIHRvIHByb3Blcmx5IHRlc3QgdGhlIGluaXRpYWxpemF0aW9uIG9mIHRoZSBvdXRlciBjbGFzcy4KKworc3ludGF4ID0gInByb3RvMiI7CisKK2ltcG9ydCAiY29tL2dvb2dsZS9wcm90b2J1Zi9ub25fbmVzdGVkX2V4dGVuc2lvbi5wcm90byI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKworbWVzc2FnZSBNeU5lc3RlZEV4dGVuc2lvbiB7CisgIGV4dGVuZCBNZXNzYWdlVG9CZUV4dGVuZGVkIHsKKyAgICBvcHRpb25hbCBNZXNzYWdlVG9CZUV4dGVuZGVkIHJlY3Vyc2l2ZUV4dGVuc2lvbiA9IDI7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9leHRlbnNpb25fbGl0ZS5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9leHRlbnNpb25fbGl0ZS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTVjMzhiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2V4dGVuc2lvbl9saXRlLnByb3RvCkBAIC0wLDAgKzEsNDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IERhcmljayBUb25nIChkYXJpY2tAZ29vZ2xlLmNvbSkKKy8vCisvLyBBIHByb3RvIGZpbGUgd2l0aCBuZXN0ZWQgZXh0ZW5zaW9ucyBmb3IgYSBNZXNzYWdlTGl0ZSBtZXNzYWdlcy4gTm90ZSB0aGF0CisvLyB0aGlzIG11c3QgYmUgZGVmaW5lZCBpbiBhIHNlcGFyYXRlIGZpbGUgdG8gcHJvcGVybHkgdGVzdCB0aGUgaW5pdGlhbGl6YXRpb24KKy8vIG9mIHRoZSBvdXRlciBjbGFzcy4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK2ltcG9ydCAiY29tL2dvb2dsZS9wcm90b2J1Zi9ub25fbmVzdGVkX2V4dGVuc2lvbl9saXRlLnByb3RvIjsKKworbWVzc2FnZSBNeU5lc3RlZEV4dGVuc2lvbkxpdGUgeworICBleHRlbmQgTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgeworICAgIG9wdGlvbmFsIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIHJlY3Vyc2l2ZUV4dGVuc2lvbkxpdGUgPSAzOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ub25fbmVzdGVkX2V4dGVuc2lvbi5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25vbl9uZXN0ZWRfZXh0ZW5zaW9uLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxZmFjNTUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9ub25fbmVzdGVkX2V4dGVuc2lvbi5wcm90bwpAQCAtMCwwICsxLDUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBEYXJpY2sgVG9uZyAoZGFyaWNrQGdvb2dsZS5jb20pCisvLworLy8gQSBwcm90byBmaWxlIHdpdGggZXh0ZW5zaW9ucy4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKworbWVzc2FnZSBNZXNzYWdlVG9CZUV4dGVuZGVkIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworbWVzc2FnZSBNeU5vbk5lc3RlZEV4dGVuc2lvbiB7Cit9CisKK2V4dGVuZCBNZXNzYWdlVG9CZUV4dGVuZGVkIHsKKyAgb3B0aW9uYWwgTXlOb25OZXN0ZWRFeHRlbnNpb24gbm9uTmVzdGVkRXh0ZW5zaW9uID0gMTsKK30KKwpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbm9uX25lc3RlZF9leHRlbnNpb25fbGl0ZS5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25vbl9uZXN0ZWRfZXh0ZW5zaW9uX2xpdGUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzdjMzY5ZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25vbl9uZXN0ZWRfZXh0ZW5zaW9uX2xpdGUucHJvdG8KQEAgLTAsMCArMSw1MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogRGFyaWNrIFRvbmcgKGRhcmlja0Bnb29nbGUuY29tKQorLy8KKy8vIEEgcHJvdG8gZmlsZSB3aXRoIGV4dGVuc2lvbnMgZm9yIGEgTWVzc2FnZUxpdGUgbWVzc2FnZXMuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitvcHRpb24gb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FOworCittZXNzYWdlIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworbWVzc2FnZSBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgeworfQorCitleHRlbmQgTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgeworICBvcHRpb25hbCBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgbm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSA9IDE7Cit9CisKZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdC5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjA4MzY4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvb3V0ZXJfY2xhc3NfbmFtZV90ZXN0LnByb3RvCkBAIC0wLDAgKzEsNDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworCisvLyBUaGlzIG1lc3NhZ2UncyBuYW1lIGlzIHRoZSBzYW1lIHdpdGggdGhlIGRlZmF1bHQgb3V0ZXIgY2xhc3MgbmFtZSBvZiB0aGlzCisvLyBwcm90byBmaWxlLiBJdCdzIHVzZWQgdG8gdGVzdCBpZiB0aGUgY29tcGlsZXIgY2FuIGF2b2lkIHRoaXMgY29uZmxpY3QKKy8vIGNvcnJlY3RseS4KK21lc3NhZ2UgT3V0ZXJDbGFzc05hbWVUZXN0IHsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdDIucHJvdG8gYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3Rlc3QyLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlNTk1NmIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3Rlc3QyLnByb3RvCkBAIC0wLDAgKzEsNDQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworCittZXNzYWdlIFRlc3RNZXNzYWdlMiB7CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgLy8gVGhpcyBtZXNzYWdlJ3MgbmFtZSBpcyB0aGUgc2FtZSB3aXRoIHRoZSBkZWZhdWx0IG91dGVyIGNsYXNzIG5hbWUgb2YgdGhpcworICAgIC8vIHByb3RvIGZpbGUuIEl0J3MgdXNlZCB0byB0ZXN0IGlmIHRoZSBjb21waWxlciBjYW4gYXZvaWQgdGhpcyBjb25mbGljdAorICAgIC8vIGNvcnJlY3RseS4KKyAgICBtZXNzYWdlIE91dGVyQ2xhc3NOYW1lVGVzdDIgeworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvb3V0ZXJfY2xhc3NfbmFtZV90ZXN0My5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdDMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzRhOGJhMwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdDMucHJvdG8KQEAgLTAsMCArMSw0NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCisKK21lc3NhZ2UgVGVzdE1lc3NhZ2UzIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICAvLyBUaGlzIGVudW0ncyBuYW1lIGlzIHRoZSBzYW1lIHdpdGggdGhlIGRlZmF1bHQgb3V0ZXIgY2xhc3MgbmFtZSBvZiB0aGlzCisgICAgLy8gcHJvdG8gZmlsZS4gSXQncyB1c2VkIHRvIHRlc3QgaWYgdGhlIGNvbXBpbGVyIGNhbiBhdm9pZCB0aGlzIGNvbmZsaWN0CisgICAgLy8gY29ycmVjdGx5LgorICAgIGVudW0gT3V0ZXJDbGFzc05hbWVUZXN0MyB7CisgICAgICBEVU1NWV9WQUxVRSA9IDE7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjMDgyNjEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bwpAQCAtMCwwICsxLDE3MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorCisvLyBUaGlzIGZpbGUgdGVzdHMgdGhhdCB2YXJpb3VzIGlkZW50aWZpZXJzIHdvcmsgYXMgZmllbGQgYW5kIHR5cGUgbmFtZXMgZXZlbgorLy8gdGhvdWdoIHRoZSBzYW1lIGlkZW50aWZpZXJzIGFyZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIGphdmEgY29kZSBnZW5lcmF0b3IuCisKK3N5bnRheCA9ICJwcm90bzIiOworCisvLyBTb21lIGdlbmVyaWNfc2VydmljZXMgb3B0aW9uKHMpIGFkZGVkIGF1dG9tYXRpY2FsbHkuCisvLyBTZWU6ICBodHRwOi8vZ28vcHJvdG8yLWdlbmVyaWMtc2VydmljZXMtZGVmYXVsdAorb3B0aW9uIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgLy8gYXV0by1hZGRlZAorCitwYWNrYWdlIGlvX3Byb3RvY29sX3Rlc3RzOworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvIjsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CisKKworbWVzc2FnZSBUZXN0TWVzc2FnZSB7CisgIG9wdGlvbmFsIHN0cmluZyBjYWNoZWRfc2l6ZSA9IDE7CisgIG9wdGlvbmFsIHN0cmluZyBzZXJpYWxpemVkX3NpemUgPSAyOworICBvcHRpb25hbCBzdHJpbmcgY2xhc3MgPSAzOworfQorCittZXNzYWdlIERlc2NyaXB0b3IgeworICBvcHRpb24gbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IHRydWU7CisgIG9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTsKKyAgbWVzc2FnZSBOZXN0ZWREZXNjcmlwdG9yIHsKKyAgICBvcHRpb24gbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IHRydWU7CisgICAgb3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOworICB9CisgIG9wdGlvbmFsIE5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOworICBlbnVtIE5lc3RlZEVudW0geworICAgIFVOS05PV04gPSAwOworICAgIEZPTyA9IDE7CisgIH0KK30KKworbWVzc2FnZSBQYXJzZXIgeworICBlbnVtIFBhcnNlckVudW0geworICAgIFVOS05PV04gPSAwOworICAgIFBBUlNFUiA9IDE7CisgIH0KKyAgb3B0aW9uYWwgUGFyc2VyRW51bSBwYXJzZXIgPSAxOworfQorCittZXNzYWdlIERlcHJlY2F0ZWQgeworICBlbnVtIFRlc3RFbnVtIHsKKyAgICBVTktOT1dOID0gMDsKKyAgICBGT08gPSAxOworCisgICAgLy8gVGVzdCBpZiBARGVwcmVjYXRlZCBhbm5vdGF0aW9uIGNvbmZsaWN0cyB3aXRoIERlcHJlY2F0ZWQgbWVzc2FnZSBuYW1lLgorICAgIEJBUiA9IDIgWyBkZXByZWNhdGVkID0gdHJ1ZSBdOworICB9CisKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQxID0gMSBbZGVwcmVjYXRlZD10cnVlXTsKKyAgb3B0aW9uYWwgVGVzdEVudW0gZmllbGQyID0gMiBbZGVwcmVjYXRlZD10cnVlXTsKKyAgb3B0aW9uYWwgVGVzdE1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZD10cnVlXTsKK30KKworbWVzc2FnZSBPdmVycmlkZSB7CisgIG9wdGlvbmFsIGludDMyIG92ZXJyaWRlID0gMTsKK30KKworbWVzc2FnZSBPYmplY3QgeworICBvcHRpb25hbCBpbnQzMiBvYmplY3QgPSAxOworICBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX29iamVjdCA9IDI7Cit9CisKK21lc3NhZ2UgU3RyaW5nIHsKKyAgb3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE7Cit9CisKK21lc3NhZ2UgSW50ZWdlciB7CisgIG9wdGlvbmFsIGludDMyIGludGVnZXIgPSAxOworfQorCittZXNzYWdlIExvbmcgeworICBvcHRpb25hbCBpbnQzMiBsb25nID0gMTsKK30KKworbWVzc2FnZSBGbG9hdCB7CisgIG9wdGlvbmFsIGZsb2F0IGZsb2F0ID0gMTsKK30KKworbWVzc2FnZSBEb3VibGUgeworICBvcHRpb25hbCBkb3VibGUgZG91YmxlID0gMTsKK30KKworc2VydmljZSBUZXN0Q29uZmxpY3RpbmdNZXRob2ROYW1lcyB7CisgIHJwYyBPdmVycmlkZShUZXN0TWVzc2FnZSkgcmV0dXJucyAoVGVzdE1lc3NhZ2UpOworfQorCittZXNzYWdlIFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgeworICBlbnVtIFRlc3RFbnVtIHsKKyAgICBVTktOT1dOID0gMDsKKyAgICBGT08gPSAxOworICB9CisgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UgeworICB9CisgIHJlcGVhdGVkIGludDMyIGludDMyX2ZpZWxkID0gMTsKKyAgcmVwZWF0ZWQgVGVzdEVudW0gZW51bV9maWVsZCA9IDI7CisgIHJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOworICByZXBlYXRlZCBieXRlcyBieXRlc19maWVsZCA9IDQ7CisgIHJlcGVhdGVkIFRlc3RNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OworCisgIG9wdGlvbmFsIGludDMyIGludDMyX2ZpZWxkX2NvdW50ID0gMTE7CisgIG9wdGlvbmFsIFRlc3RFbnVtIGVudW1fZmllbGRfY291bnQgPSAxMjsKKyAgb3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZF9jb3VudCA9IDEzOworICBvcHRpb25hbCBieXRlcyBieXRlc19maWVsZF9jb3VudCA9IDE0OworICBvcHRpb25hbCBUZXN0TWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7CisKKyAgcmVwZWF0ZWQgaW50MzIgSW50MzJGaWVsZCA9IDIxOworICByZXBlYXRlZCBUZXN0RW51bSBFbnVtRmllbGQgPSAyMjsKKyAgcmVwZWF0ZWQgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjM7CisgIHJlcGVhdGVkIGJ5dGVzIEJ5dGVzRmllbGQgPSAyNDsKKyAgcmVwZWF0ZWQgVGVzdE1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7CisKKyAgLy8gVGhpcyBmaWVsZCBjb25mbGljdHMgd2l0aCAiaW50MzJfZmllbGQiIGFzIHRoZXkgYm90aCBnZW5lcmF0ZQorICAvLyB0aGUgbWV0aG9kIGdldEludDMyRmllbGRMaXN0KCkuCisgIHJlcXVpcmVkIGludDMyIGludDMyX2ZpZWxkX2xpc3QgPSAzMTsgIC8vIE5PX1BST1RPMworCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7ICAvLyBOT19QUk9UTzMKKworICByZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOworICBleHRlbmQgVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyB7ICAvLyBOT19QUk9UTzMKKyAgICAvLyBXZSBkb24ndCBnZW5lcmF0ZSBhY2Nlc3NvcnMgZm9yIGV4dGVuc2lvbnMgc28gdGhlIGZvbGxvd2luZyBleHRlbnNpb24KKyAgICAvLyBmaWVsZHMgZG9uJ3QgY29uZmxpY3Qgd2l0aCB0aGUgcmVwZWF0ZWQgZmllbGQgImludDY0X2ZpZWxkIi4KKyAgICBvcHRpb25hbCBpbnQ2NCBpbnQ2NF9maWVsZF9jb3VudCA9IDEwMDE7ICAvLyBOT19QUk9UTzMKKyAgICBvcHRpb25hbCBpbnQ2NCBpbnQ2NF9maWVsZF9saXN0ID0gMTAwMjsgIC8vIE5PX1BST1RPMworICB9ICAvLyBOT19QUk9UTzMKK30KKworbWVzc2FnZSBUZXN0TWFwRmllbGQgeworICBtZXNzYWdlIE1hcEZpZWxkIHt9CisgIG1lc3NhZ2UgUGFpciB7fQorICBtZXNzYWdlIE1lc3NhZ2Uge30KKworICBtYXA8aW50MzIsIGludDMyPiBtYXBfZmllbGQgPSAxOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jaGVja191dGY4LnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jaGVja191dGY4LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExOWMxZGMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2NoZWNrX3V0ZjgucHJvdG8KQEAgLTAsMCArMSw1MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogSmFjb2IgQnV0Y2hlciAoamJhdW1AZ29vZ2xlLmNvbSkKKy8vCisvLyBUZXN0IGZpbGUgb3B0aW9uIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjguCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90bzJfdGVzdF9jaGVja191dGY4OworCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiVGVzdENoZWNrVXRmOCI7CitvcHRpb24gamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IHRydWU7CisKK21lc3NhZ2UgU3RyaW5nV3JhcHBlciB7CisgIHJlcXVpcmVkIHN0cmluZyByZXEgPSAxOworICBvcHRpb25hbCBzdHJpbmcgb3B0ID0gMjsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7Cit9CisKK21lc3NhZ2UgQnl0ZXNXcmFwcGVyIHsKKyAgcmVxdWlyZWQgYnl0ZXMgcmVxID0gMTsKKyAgb3B0aW9uYWwgYnl0ZXMgb3B0ID0gMjsKKyAgcmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzsKK30KZGlmZiAtLWdpdCBhL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfY2hlY2tfdXRmOF9zaXplLnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jaGVja191dGY4X3NpemUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA2ZDc2ZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfY2hlY2tfdXRmOF9zaXplLnByb3RvCkBAIC0wLDAgKzEsNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IEphY29iIEJ1dGNoZXIgKGpiYXVtQGdvb2dsZS5jb20pCisvLworLy8gVGVzdCBmaWxlIG9wdGlvbiBqYXZhX3N0cmluZ19jaGVja191dGY4Lgorc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplOworCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiVGVzdENoZWNrVXRmOFNpemUiOworb3B0aW9uIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjggPSB0cnVlOworb3B0aW9uIG9wdGltaXplX2ZvciA9IENPREVfU0laRTsKKworbWVzc2FnZSBTdHJpbmdXcmFwcGVyU2l6ZSB7CisgIHJlcXVpcmVkIHN0cmluZyByZXEgPSAxOworICBvcHRpb25hbCBzdHJpbmcgb3B0ID0gMjsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7Cit9CisKK21lc3NhZ2UgQnl0ZXNXcmFwcGVyU2l6ZSB7CisgIHJlcXVpcmVkIGJ5dGVzIHJlcSA9IDE7CisgIG9wdGlvbmFsIGJ5dGVzIG9wdCA9IDI7CisgIHJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7Cit9CmRpZmYgLS1naXQgYS9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOGVmZDQ1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwpAQCAtMCwwICsxLDQ0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBGZW5nIFhpYW8gKHhpYW9mZW5nQGdvb2dsZS5jb20pCisvLworLy8gVGVzdCB0aGF0IGN1c3RvbSBvcHRpb25zIGRlZmluZWQgaW4gYSBwcm90byBmaWxlJ3MgZGVwZW5kZW5jaWVzIGFyZSBwcm9wZXJseQorLy8gaW5pdGlhbGl6ZWQuCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byI7CisKK21lc3NhZ2UgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciB7CisgIG9wdGlvbmFsIFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOworfQpkaWZmIC0tZ2l0IGEvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9leHRyYV9pbnRlcmZhY2VzLnByb3RvIGIvamF2YS9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9leHRyYV9pbnRlcmZhY2VzLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0NWY1N2IKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2V4dHJhX2ludGVyZmFjZXMucHJvdG8KQEAgLTAsMCArMSw2MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogRGFyaWNrIFRvbmcgKGRhcmlja0Bnb29nbGUuY29tKQorc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK21lc3NhZ2UgUHJvdG8xIHsKKyAgb3B0aW9uIGV4cGVyaW1lbnRhbF9qYXZhX21lc3NhZ2VfaW50ZXJmYWNlID0KKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkV4dHJhSW50ZXJmYWNlcy5IYXNCb29sVmFsdWUiOworCisgIG9wdGlvbiBleHBlcmltZW50YWxfamF2YV9pbnRlcmZhY2VfZXh0ZW5kcyA9CisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRyYUludGVyZmFjZXMuSGFzQnl0ZVZhbHVlIjsKKworICBvcHRpb24gZXhwZXJpbWVudGFsX2phdmFfbWVzc2FnZV9pbnRlcmZhY2UgPQorICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuRXh0cmFJbnRlcmZhY2VzLkhhc1N0cmluZ1ZhbHVlPFByb3RvMT4iOworCisgIG9wdGlvbiBleHBlcmltZW50YWxfamF2YV9idWlsZGVyX2ludGVyZmFjZSA9CisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRyYUludGVyZmFjZXMuSGFzU3RyaW5nVmFsdWVCdWlsZGVyIgorICAgICAgIjxQcm90bzEsIEJ1aWxkZXI+IjsKKworICBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3ZhbHVlID0gMTsKKyAgb3B0aW9uYWwgYm9vbCBib29sX3ZhbHVlID0gMjsKKyAgb3B0aW9uYWwgYnl0ZXMgYnl0ZV92YWx1ZSA9IDM7CisgIG9wdGlvbmFsIGludDMyIGludF92YWx1ZSA9IDQ7Cit9CisKK21lc3NhZ2UgUHJvdG8yIHsKKyAgb3B0aW9uIGV4cGVyaW1lbnRhbF9qYXZhX21lc3NhZ2VfaW50ZXJmYWNlID0KKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkV4dHJhSW50ZXJmYWNlcy5IYXNCb29sVmFsdWUiOworCisgIG9wdGlvbmFsIGJvb2wgYm9vbF92YWx1ZSA9IDE7Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9SRUFETUUudHh0IGIvamF2YW5hbm8vUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZmIzYzNiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vUkVBRE1FLnR4dApAQCAtMCwwICsxLDM1NiBAQAorUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CitDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLgorCitUaGlzIGRpcmVjdG9yeSBjb250YWlucyB0aGUgSmF2YSBQcm90b2NvbCBCdWZmZXJzIE5hbm8gcnVudGltZSBsaWJyYXJ5LgorCitJbnN0YWxsYXRpb24gLSBXaXRoIE1hdmVuCis9PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RoZSBQcm90b2NvbCBCdWZmZXJzIGJ1aWxkIGlzIG1hbmFnZWQgdXNpbmcgTWF2ZW4uICBJZiB5b3Ugd291bGQKK3JhdGhlciBidWlsZCB3aXRob3V0IE1hdmVuLCBzZWUgYmVsb3cuCisKKzEpIEluc3RhbGwgQXBhY2hlIE1hdmVuIGlmIHlvdSBkb24ndCBoYXZlIGl0OgorCisgICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnLworCisyKSBCdWlsZCB0aGUgQysrIGNvZGUsIG9yIG9idGFpbiBhIGJpbmFyeSBkaXN0cmlidXRpb24gb2YgcHJvdG9jLiAgSWYKKyAgIHlvdSBpbnN0YWxsIGEgYmluYXJ5IGRpc3RyaWJ1dGlvbiwgbWFrZSBzdXJlIHRoYXQgaXQgaXMgdGhlIHNhbWUKKyAgIHZlcnNpb24gYXMgdGhpcyBwYWNrYWdlLiAgSWYgaW4gZG91YnQsIHJ1bjoKKworICAgICAkIHByb3RvYyAtLXZlcnNpb24KKworICAgWW91IHdpbGwgbmVlZCB0byBwbGFjZSB0aGUgcHJvdG9jIGV4ZWN1dGFibGUgaW4gLi4vc3JjLiAgKElmIHlvdQorICAgYnVpbHQgaXQgeW91cnNlbGYsIGl0IHNob3VsZCBhbHJlYWR5IGJlIHRoZXJlLikKKworMykgUnVuIHRoZSB0ZXN0czoKKworICAgICAkIG12biB0ZXN0CisKKyAgIElmIHNvbWUgdGVzdHMgZmFpbCwgdGhpcyBsaWJyYXJ5IG1heSBub3Qgd29yayBjb3JyZWN0bHkgb24geW91cgorICAgc3lzdGVtLiAgQ29udGludWUgYXQgeW91ciBvd24gcmlzay4KKworNCkgSW5zdGFsbCB0aGUgbGlicmFyeSBpbnRvIHlvdXIgTWF2ZW4gcmVwb3NpdG9yeToKKworICAgICAkIG12biBpbnN0YWxsCisKKzUpIElmIHlvdSBkbyBub3QgdXNlIE1hdmVuIHRvIG1hbmFnZSB5b3VyIG93biBidWlsZCwgeW91IGNhbiBidWlsZCBhCisgICAuamFyIGZpbGUgdG8gdXNlOgorCisgICAgICQgbXZuIHBhY2thZ2UKKworICAgVGhlIC5qYXIgd2lsbCBiZSBwbGFjZWQgaW4gdGhlICJ0YXJnZXQiIGRpcmVjdG9yeS4KKworSW5zdGFsbGF0aW9uIC0gV2l0aG91dCBNYXZlbgorPT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJZiB5b3Ugd291bGQgcmF0aGVyIG5vdCBpbnN0YWxsIE1hdmVuIHRvIGJ1aWxkIHRoZSBsaWJyYXJ5LCB5b3UgbWF5Citmb2xsb3cgdGhlc2UgaW5zdHJ1Y3Rpb25zIGluc3RlYWQuICBOb3RlIHRoYXQgdGhlc2UgaW5zdHJ1Y3Rpb25zIHNraXAKK3J1bm5pbmcgdW5pdCB0ZXN0cy4KKworMSkgQnVpbGQgdGhlIEMrKyBjb2RlLCBvciBvYnRhaW4gYSBiaW5hcnkgZGlzdHJpYnV0aW9uIG9mIHByb3RvYy4gIElmCisgICB5b3UgaW5zdGFsbCBhIGJpbmFyeSBkaXN0cmlidXRpb24sIG1ha2Ugc3VyZSB0aGF0IGl0IGlzIHRoZSBzYW1lCisgICB2ZXJzaW9uIGFzIHRoaXMgcGFja2FnZS4gIElmIGluIGRvdWJ0LCBydW46CisKKyAgICAgJCBwcm90b2MgLS12ZXJzaW9uCisKKyAgIElmIHlvdSBidWlsdCB0aGUgQysrIGNvZGUgd2l0aG91dCBpbnN0YWxsaW5nLCB0aGUgY29tcGlsZXIgYmluYXJ5CisgICBzaG91bGQgYmUgbG9jYXRlZCBpbiAuLi9zcmMuCisKKzIpIEludm9rZSBwcm90b2MgdG8gYnVpbGQgRGVzY3JpcHRvclByb3Rvcy5qYXZhOgorCisgICAgICQgcHJvdG9jIC0tamF2YV9vdXQ9c3JjL21haW4vamF2YSAtSS4uL3NyYyBcCisgICAgICAgICAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KKworMykgQ29tcGlsZSB0aGUgY29kZSBpbiBzcmMvbWFpbi9qYXZhIHVzaW5nIHdoYXRldmVyIG1lYW5zIHlvdSBwcmVmZXIuCisKKzQpIEluc3RhbGwgdGhlIGNsYXNzZXMgd2hlcmV2ZXIgeW91IHByZWZlci4KKworTmFubyB2ZXJzaW9uCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0phdmFOYW5vIGlzIGEgc3BlY2lhbCBjb2RlIGdlbmVyYXRvciBhbmQgcnVudGltZSBsaWJyYXJ5IGRlc2lnbmVkIHNwZWNpYWxseSBmb3IKK3Jlc291cmNlLXJlc3RyaWN0ZWQgc3lzdGVtcywgbGlrZSBBbmRyb2lkLiBJdCBpcyB2ZXJ5IHJlc291cmNlLWZyaWVuZGx5IGluIGJvdGgKK3RoZSBhbW91bnQgb2YgY29kZSBhbmQgdGhlIHJ1bnRpbWUgb3ZlcmhlYWQuIEhlcmUgaXMgYW4gb3ZlcnZpZXcgb2YgSmF2YU5hbm8KK2ZlYXR1cmVzIGNvbXBhcmVkIHdpdGggdGhlIG9mZmljaWFsIEphdmEgcHJvdG9idWY6CisKKy0gTm8gZGVzY3JpcHRvcnMgb3IgbWVzc2FnZSBidWlsZGVycy4KKy0gQWxsIG1lc3NhZ2VzIGFyZSBtdXRhYmxlOyBmaWVsZHMgYXJlIHB1YmxpYyBKYXZhIGZpZWxkcy4KKy0gRm9yIG9wdGlvbmFsIGZpZWxkcyBvbmx5LCBlbmNhcHN1bGF0aW9uIGJlaGluZCBzZXR0ZXIvZ2V0dGVyL2hhenplci8KKyAgY2xlYXJlciBmdW5jdGlvbnMgaXMgb3B0LWluLCB3aGljaCBwcm92aWRlIHByb3BlciAnaGFzJyBzdGF0ZSBzdXBwb3J0LgorLSBGb3IgcHJvdG8yLCBpZiBub3Qgb3B0ZWQgaW4sIGhhcyBzdGF0ZSAoZmllbGQgcHJlc2VuY2UpIGlzIG5vdCBhdmFpbGFibGUuCisgIFNlcmlhbGl6YXRpb24gb3V0cHV0cyBhbGwgZmllbGRzIG5vdCBlcXVhbCB0byB0aGVpciBkZWZhdWx0cworICAoc2VlIGltcG9ydGFudCBpbXBsaWNhdGlvbnMgYmVsb3cpLgorICBUaGUgYmVoYXZpb3IgaXMgY29uc2lzdGVudCB3aXRoIHByb3RvMyBzZW1hbnRpY3MuCistIFJlcXVpcmVkIGZpZWxkcyAocHJvdG8yIG9ubHkpIGFyZSBhbHdheXMgc2VyaWFsaXplZC4KKy0gRW51bSBjb25zdGFudHMgYXJlIGludGVnZXJzOyBwcm90ZWN0aW9uIGFnYWluc3QgaW52YWxpZCB2YWx1ZXMgb25seQorICB3aGVuIHBhcnNpbmcgZnJvbSB0aGUgd2lyZS4KKy0gRW51bSBjb25zdGFudHMgY2FuIGJlIGdlbmVyYXRlZCBpbnRvIGNvbnRhaW5lciBpbnRlcmZhY2VzIGJlYXJpbmcKKyAgdGhlIGVudW0ncyBuYW1lIChzbyB0aGUgcmVmZXJlbmNpbmcgY29kZSBpcyBpbiBKYXZhIHN0eWxlKS4KKy0gQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGNhbiBvbmx5IHRha2UgYnl0ZVtdIChub3QgSW5wdXRTdHJlYW0pLgorLSBTaW1pbGFybHkgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBjYW4gb25seSB3cml0ZSB0byBieXRlW10uCistIFJlcGVhdGVkIGZpZWxkcyBhcmUgaW4gYXJyYXlzLCBub3QgQXJyYXlMaXN0IG9yIFZlY3Rvci4gTnVsbCBhcnJheQorICBlbGVtZW50cyBhcmUgYWxsb3dlZCBhbmQgc2lsZW50bHkgaWdub3JlZC4KKy0gRnVsbCBzdXBwb3J0IGZvciBzZXJpYWxpemluZy9kZXNlcmlhbGl6aW5nIHJlcGVhdGVkIHBhY2tlZCBmaWVsZHMuCistIFN1cHBvcnQgIGV4dGVuc2lvbnMgKGluIHByb3RvMikuCistIFVuc2V0IG1lc3NhZ2VzL2dyb3VwcyBhcmUgbnVsbCwgbm90IGFuIGltbXV0YWJsZSBlbXB0eSBkZWZhdWx0CisgIGluc3RhbmNlLgorLSB0b0J5dGVBcnJheSguLi4pIGFuZCBtZXJnZUZyb20oLi4uKSBhcmUgbm93IHN0YXRpYyBmdW5jdGlvbnMgb2YKKyAgTWVzc2FnZU5hbm8uCistIFRoZSAnYnl0ZXMnIHR5cGUgdHJhbnNsYXRlcyB0byB0aGUgSmF2YSB0eXBlIGJ5dGVbXS4KKworVGhlIGdlbmVyYXRlZCBtZXNzYWdlcyBhcmUgbm90IHRocmVhZC1zYWZlIGZvciB3cml0ZXMsIGJ1dCBtYXkgYmUKK3VzZWQgc2ltdWx0YW5lb3VzbHkgZnJvbSBtdWx0aXBsZSB0aHJlYWRzIGluIGEgcmVhZC1vbmx5IG1hbm5lci4KK0luIG90aGVyIHdvcmRzLCBhbiBhcHByb3ByaWF0ZSBzeW5jaHJvbml6YXRpb24gbWVjaGFuaXNtIChzdWNoIGFzCithIFJlYWRXcml0ZUxvY2spIG11c3QgYmUgdXNlZCB0byBlbnN1cmUgdGhhdCBhIG1lc3NhZ2UsIGl0cworYW5jZXN0b3JzLCBhbmQgZGVzY2VuZGFudHMgYXJlIG5vdCBhY2Nlc3NlZCBieSBhbnkgb3RoZXIgdGhyZWFkcword2hpbGUgdGhlIG1lc3NhZ2UgaXMgYmVpbmcgbW9kaWZpZWQuIEZpZWxkIHJlYWRzLCBnZXR0ZXIgbWV0aG9kcworKGJ1dCBub3QgZ2V0RXh0ZW5zaW9uKC4uLikpLCB0b0J5dGVBcnJheSguLi4pLCB3cml0ZVRvKC4uLiksCitnZXRDYWNoZWRTaXplKCksIGFuZCBnZXRTZXJpYWxpemVkU2l6ZSgpIGFyZSBhbGwgY29uc2lkZXJlZCByZWFkLW9ubHkKK29wZXJhdGlvbnMuCisKK0lNUE9SVEFOVDogSWYgeW91IGhhdmUgZmllbGRzIHdpdGggZGVmYXVsdHMgYW5kIG9wdCBvdXQgb2YgYWNjZXNzb3JzCisKK0hvdyBmaWVsZHMgd2l0aCBkZWZhdWx0cyBhcmUgc2VyaWFsaXplZCBoYXMgY2hhbmdlZC4gQmVjYXVzZSB3ZSBkb24ndAora2VlcCAiaGFzIiBzdGF0ZSwgYW55IGZpZWxkIGVxdWFsIHRvIGl0cyBkZWZhdWx0IGlzIGFzc3VtZWQgdG8gYmUgbm90CitzZXQgYW5kIHRoZXJlZm9yZSBpcyBub3Qgc2VyaWFsaXplZC4gQ29uc2lkZXIgdGhlIHNpdHVhdGlvbiB3aGVyZSB3ZQorY2hhbmdlIHRoZSBkZWZhdWx0IHZhbHVlIG9mIGEgZmllbGQuIFNlbmRlcnMgY29tcGlsZWQgYWdhaW5zdCBhbiBvbGRlcgordmVyc2lvbiBvZiB0aGUgcHJvdG8gY29udGludWUgdG8gbWF0Y2ggYWdhaW5zdCB0aGUgb2xkIGRlZmF1bHQsIGFuZAorZG9uJ3Qgc2VuZCB2YWx1ZXMgdG8gdGhlIHJlY2VpdmVyIGV2ZW4gdGhvdWdoIHRoZSByZWNlaXZlciBhc3N1bWVzIHRoZQorbmV3IGRlZmF1bHQgdmFsdWUuIFRoZXJlZm9yZSwgdGhpbmsgY2FyZWZ1bGx5IGFib3V0IHRoZSBpbXBsaWNhdGlvbnMKK29mIGNoYW5naW5nIHRoZSBkZWZhdWx0IHZhbHVlLiBBbHRlcm5hdGl2ZWx5LCB0dXJuIG9uIGFjY2Vzc29ycyBhbmQKK2Vuam95IHRoZSBiZW5lZml0IG9mIHRoZSBleHBsaWNpdCBoYXMoKSBjaGVja3MuCisKK0lNUE9SVEFOVDogSWYgeW91IGhhdmUgImJ5dGVzIiBmaWVsZHMgd2l0aCBub24tZW1wdHkgZGVmYXVsdHMKKworQmVjYXVzZSB0aGUgYnl0ZSBidWZmZXIgaXMgbm93IG9mIG11dGFibGUgdHlwZSBieXRlW10sIHRoZSBkZWZhdWx0CitzdGF0aWMgZmluYWwgY2Fubm90IGJlIGV4cG9zZWQgdGhyb3VnaCBhIHB1YmxpYyBmaWVsZC4gRWFjaCB0aW1lIGEKK21lc3NhZ2UncyBjb25zdHJ1Y3RvciBvciBjbGVhcigpIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhlIGRlZmF1bHQgdmFsdWUKKyhrZXB0IGluIGEgcHJpdmF0ZSBieXRlW10pIGlzIGNsb25lZC4gVGhpcyBjYXVzZXMgYSBzbWFsbCBtZW1vcnkKK3BlbmFsdHkuIFRoaXMgaXMgbm90IGEgcHJvYmxlbSBpZiB0aGUgZmllbGQgaGFzIG5vIGRlZmF1bHQgb3IgaXMgYW4KK2VtcHR5IGRlZmF1bHQuCisKK05hbm8gR2VuZXJhdG9yIG9wdGlvbnMKKworamF2YV9wYWNrYWdlICAgICAgICAgICAtPiA8ZmlsZS1uYW1lPnw8cGFja2FnZS1uYW1lPgoramF2YV9vdXRlcl9jbGFzc25hbWUgICAtPiA8ZmlsZS1uYW1lPnw8cGFja2FnZS1uYW1lPgoramF2YV9tdWx0aXBsZV9maWxlcyAgICAtPiB0cnVlIG9yIGZhbHNlCitqYXZhX25hbm9fZ2VuZXJhdGVfaGFzIC0+IHRydWUgb3IgZmFsc2UgW0RFUFJFQ0FURURdCitvcHRpb25hbF9maWVsZF9zdHlsZSAgIC0+IGRlZmF1bHQgb3IgYWNjZXNzb3JzCitlbnVtX3N0eWxlICAgICAgICAgICAgIC0+IGMgb3IgamF2YQoraWdub3JlX3NlcnZpY2VzICAgICAgICAtPiB0cnVlIG9yIGZhbHNlCitwYXJjZWxhYmxlX21lc3NhZ2VzICAgIC0+IHRydWUgb3IgZmFsc2UKKworamF2YV9wYWNrYWdlPTxmaWxlLW5hbWU+fDxwYWNrYWdlLW5hbWU+IChubyBkZWZhdWx0KQorICBUaGlzIGFsbG93cyBvdmVycmlkaW5nIHRoZSAnamF2YV9wYWNrYWdlJyBvcHRpb24gdmFsdWUKKyAgZm9yIHRoZSBnaXZlbiBmaWxlIGZyb20gdGhlIGNvbW1hbmQgbGluZS4gVXNlIG11bHRpcGxlCisgIGphdmFfcGFja2FnZSBvcHRpb25zIHRvIG92ZXJyaWRlIHRoZSBvcHRpb24gZm9yIG11bHRpcGxlCisgIGZpbGVzLiBUaGUgZmluYWwgSmF2YSBwYWNrYWdlIGZvciBlYWNoIGZpbGUgaXMgdGhlIHZhbHVlCisgIG9mIHRoaXMgY29tbWFuZCBsaW5lIG9wdGlvbiBpZiBwcmVzZW50LCBvciB0aGUgdmFsdWUgb2YKKyAgdGhlIHNhbWUgb3B0aW9uIGRlZmluZWQgaW4gdGhlIGZpbGUgaWYgcHJlc2VudCwgb3IgdGhlCisgIHByb3RvIHBhY2thZ2UgaWYgcHJlc2VudCwgb3IgdGhlIGRlZmF1bHQgSmF2YSBwYWNrYWdlLgorCitqYXZhX291dGVyX2NsYXNzbmFtZT08ZmlsZS1uYW1lPnw8b3V0ZXItY2xhc3NuYW1lPiAobm8gZGVmYXVsdCkKKyAgVGhpcyBhbGxvd3Mgb3ZlcnJpZGluZyB0aGUgJ2phdmFfb3V0ZXJfY2xhc3NuYW1lJyBvcHRpb24KKyAgZm9yIHRoZSBnaXZlbiBmaWxlIGZyb20gdGhlIGNvbW1hbmQgbGluZS4gVXNlIG11bHRpcGxlCisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lIG9wdGlvbnMgdG8gb3ZlcnJpZGUgdGhlIG9wdGlvbiBmb3IKKyAgbXVsdGlwbGUgZmlsZXMuIFRoZSBmaW5hbCBKYXZhIG91dGVyIGNsYXNzIG5hbWUgZm9yIGVhY2gKKyAgZmlsZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBjb21tYW5kIGxpbmUgb3B0aW9uIGlmIHByZXNlbnQsCisgIG9yIHRoZSB2YWx1ZSBvZiB0aGUgc2FtZSBvcHRpb24gZGVmaW5lZCBpbiB0aGUgZmlsZSBpZgorICBwcmVzZW50LCBvciB0aGUgZmlsZSBuYW1lIGNvbnZlcnRlZCB0byBDYW1lbENhc2UuIFRoaXMKKyAgb3V0ZXIgY2xhc3Mgd2lsbCBuZXN0IGFsbCBjbGFzc2VzIGFuZCBpbnRlZ2VyIGNvbnN0YW50cworICBnZW5lcmF0ZWQgZnJvbSBmaWxlLXNjb3BlIG1lc3NhZ2VzIGFuZCBlbnVtcy4KKworamF2YV9tdWx0aXBsZV9maWxlcz17dHJ1ZSxmYWxzZX0gKG5vIGRlZmF1bHQpCisgIFRoaXMgYWxsb3dzIG92ZXJyaWRpbmcgdGhlICdqYXZhX211bHRpcGxlX2ZpbGVzJyBvcHRpb24KKyAgaW4gYWxsIHNvdXJjZSBmaWxlcyBhbmQgdGhlaXIgaW1wb3J0ZWQgZmlsZXMgZnJvbSB0aGUKKyAgY29tbWFuZCBsaW5lLiBUaGUgZmluYWwgdmFsdWUgb2YgdGhpcyBvcHRpb24gZm9yIGVhY2gKKyAgZmlsZSBpcyB0aGUgdmFsdWUgZGVmaW5lZCBpbiB0aGlzIGNvbW1hbmQgbGluZSBvcHRpb24sIG9yCisgIHRoZSB2YWx1ZSBvZiB0aGUgc2FtZSBvcHRpb24gZGVmaW5lZCBpbiB0aGUgZmlsZSBpZgorICBwcmVzZW50LCBvciBmYWxzZS4gVGhpcyBzcGVjaWZpZXMgd2hldGhlciB0byBnZW5lcmF0ZQorICBwYWNrYWdlLWxldmVsIGNsYXNzZXMgZm9yIHRoZSBmaWxlLXNjb3BlIG1lc3NhZ2VzIGluIHRoZQorICBzYW1lIEphdmEgcGFja2FnZSBhcyB0aGUgb3V0ZXIgY2xhc3MgKGluc3RlYWQgb2YgbmVzdGVkCisgIGNsYXNzZXMgaW4gdGhlIG91dGVyIGNsYXNzKS4gRmlsZS1zY29wZSBlbnVtIGNvbnN0YW50cworICBhcmUgc3RpbGwgZ2VuZXJhdGVkIGFzIGludGVnZXIgY29uc3RhbnRzIGluIHRoZSBvdXRlcgorICBjbGFzcy4gVGhpcyBhZmZlY3RzIHRoZSBmdWxseSBxdWFsaWZpZWQgcmVmZXJlbmNlcyBpbiB0aGUKKyAgSmF2YSBjb2RlLiBOT1RFOiBiZWNhdXNlIHRoZSBjb21tYW5kIGxpbmUgb3B0aW9uCisgIG92ZXJyaWRlcyB0aGUgdmFsdWUgZm9yIGFsbCBmaWxlcyBhbmQgdGhlaXIgaW1wb3J0ZWQKKyAgZmlsZXMsIHVzaW5nIHRoaXMgb3B0aW9uIGluY29uc2lzdGVudGx5IG1heSByZXN1bHQgaW4KKyAgaW5jb3JyZWN0IHJlZmVyZW5jZXMgdG8gdGhlIGltcG9ydGVkIG1lc3NhZ2VzIGFuZCBlbnVtCisgIGNvbnN0YW50cy4KKworamF2YV9uYW5vX2dlbmVyYXRlX2hhcz17dHJ1ZSxmYWxzZX0gKGRlZmF1bHQ6IGZhbHNlKQorICBERVBSRUNBVEVELiBVc2Ugb3B0aW9uYWxfZmllbGRfc3R5bGU9YWNjZXNzb3JzLgorCisgIElmIHRydWUsIGdlbmVyYXRlcyBhIHB1YmxpYyBib29sZWFuIHZhcmlhYmxlIGhhczxmaWVsZG5hbWU+CisgIGFjY29tcGFueWluZyBlYWNoIG9wdGlvbmFsIG9yIHJlcXVpcmVkIGZpZWxkIChub3QgcHJlc2VudCBmb3IKKyAgcmVwZWF0ZWQgZmllbGRzLCBncm91cHMgb3IgbWVzc2FnZXMpLiBJdCBpcyBzZXQgdG8gZmFsc2UgaW5pdGlhbGx5CisgIGFuZCB1cG9uIGNsZWFyKCkuIElmIHBhcnNlRnJvbSguLi4pIHJlYWRzIHRoZSBmaWVsZCBmcm9tIHRoZSB3aXJlLAorICBpdCBpcyBzZXQgdG8gdHJ1ZS4gVGhpcyBpcyBhIHdheSBmb3IgY2xpZW50cyB0byBpbnNwZWN0IHRoZSAiaGFzIgorICB2YWx1ZSB1cG9uIHBhcnNlLiBJZiBpdCBpcyBzZXQgdG8gdHJ1ZSwgd3JpdGVUbyguLi4pIHdpbGwgQUxXQVlTCisgIG91dHB1dCB0aGF0IGZpZWxkIChldmVuIGlmIGZpZWxkIHZhbHVlIGlzIGVxdWFsIHRvIGl0cworICBkZWZhdWx0KS4KKworICBJTVBPUlRBTlQ6IFRoaXMgb3B0aW9uIGNvc3RzIGFuIGV4dHJhIDQgYnl0ZXMgcGVyIHByaW1pdGl2ZSBmaWVsZCBpbgorICB0aGUgbWVzc2FnZS4gVGhpbmsgY2FyZWZ1bGx5IGFib3V0IHdoZXRoZXIgeW91IHJlYWxseSBuZWVkIHRoaXMuIEluCisgIG1hbnkgY2FzZXMgcmVhZGluZyB0aGUgZGVmYXVsdCB3b3JrcyBhbmQgZGV0ZXJtaW5pbmcgd2hldGhlciB0aGUKKyAgZmllbGQgd2FzIHJlY2VpdmVkIG92ZXIgdGhlIHdpcmUgaXMgaXJyZWxldmFudC4KKworb3B0aW9uYWxfZmllbGRfc3R5bGU9e2RlZmF1bHQsYWNjZXNzb3JzLHJlZnR5cGVzfSAoZGVmYXVsdDogZGVmYXVsdCkKKyAgRGVmaW5lcyB0aGUgc3R5bGUgb2YgdGhlIGdlbmVyYXRlZCBjb2RlIGZvciBmaWVsZHMuCisKKyAgKiBkZWZhdWx0ICoKKworICBJbiB0aGUgZGVmYXVsdCBzdHlsZSwgb3B0aW9uYWwgZmllbGRzIHRyYW5zbGF0ZSBpbnRvIHB1YmxpYyBtdXRhYmxlCisgIEphdmEgZmllbGRzLCBhbmQgdGhlIHNlcmlhbGl6YXRpb24gcHJvY2VzcyBpcyBhcyBkaXNjdXNzZWQgaW4gdGhlCisgICJJTVBPUlRBTlQiIHNlY3Rpb24gYWJvdmUuCisKKyAgKiBhY2Nlc3NvcnMgKgorCisgIFdoZW4gc2V0IHRvICdhY2Nlc3NvcnMnLCBlYWNoIG9wdGlvbmFsIGZpZWxkIGlzIGVuY2Fwc3VsYXRlZCBiZWhpbmQKKyAgNCBhY2Nlc3NvcnMsIG5hbWVseSBnZXQ8ZmllbGRuYW1lPigpLCBzZXQ8ZmllbGRuYW1lPigpLCBoYXM8ZmllbGRuYW1lPigpCisgIGFuZCBjbGVhcjxmaWVsZG5hbWU+KCkgbWV0aG9kcywgd2l0aCB0aGUgc3RhbmRhcmQgc2VtYW50aWNzLiBUaGUgaGF6emVyJ3MKKyAgcmV0dXJuIHZhbHVlIGRldGVybWluZXMgd2hldGhlciBhIGZpZWxkIGlzIHNlcmlhbGl6ZWQsIHNvIHRoaXMgc3R5bGUgaXMKKyAgdXNlZnVsIHdoZW4geW91IG5lZWQgdG8gc2VyaWFsaXplIGEgZmllbGQgd2l0aCB0aGUgZGVmYXVsdCB2YWx1ZSwgb3IgY2hlY2sKKyAgaWYgYSBmaWVsZCBoYXMgYmVlbiBleHBsaWNpdGx5IHNldCB0byBpdHMgZGVmYXVsdCB2YWx1ZSBmcm9tIHRoZSB3aXJlLgorCisgIEluIHRoZSAnYWNjZXNzb3JzJyBzdHlsZSwgcmVxdWlyZWQgYW5kIG5lc3RlZCBtZXNzYWdlIGZpZWxkcyBhcmUgc3RpbGwKKyAgdHJhbnNsYXRlZCB0byBvbmUgcHVibGljIG11dGFibGUgSmF2YSBmaWVsZCBlYWNoLCByZXBlYXRlZCBmaWVsZHMgYXJlIHN0aWxsCisgIHRyYW5zbGF0ZWQgdG8gYXJyYXlzLiBObyBhY2Nlc3NvcnMgYXJlIGdlbmVyYXRlZCBmb3IgdGhlbS4KKworICBJTVBPUlRBTlQ6IFdoZW4gdXNpbmcgdGhlICdhY2Nlc3NvcnMnIHN0eWxlLCBQcm9HdWFyZCBzaG91bGQgYWx3YXlzCisgIGJlIGVuYWJsZWQgd2l0aCBvcHRpbWl6YXRpb24gKGRvbid0IHVzZSAtZG9udG9wdGltaXplKSBhbmQgYWxsb3dpbmcKKyAgYWNjZXNzIG1vZGlmaWNhdGlvbiAodXNlIC1hbGxvd2FjY2Vzc21vZGlmaWNhdGlvbikuIFRoaXMgcmVtb3ZlcyB0aGUKKyAgdW51c2VkIGFjY2Vzc29ycyBhbmQgbWF5YmUgaW5saW5lIHRoZSByZXN0IGF0IHRoZSBjYWxsIHNpdGVzLAorICByZWR1Y2luZyB0aGUgZmluYWwgY29kZSBzaXplLgorICBUT0RPKG1heHRyb3kpOiBmaW5kIFByb0d1YXJkIGNvbmZpZyB0aGF0IHdvdWxkIHdvcmsgdGhlIGJlc3QuCisKKyAgKiByZWZ0eXBlcyAqCisKKyAgV2hlbiBzZXQgdG8gJ3JlZnR5cGVzJywgZWFjaCBwcm90byBmaWVsZCBpcyBnZW5lcmF0ZWQgYXMgYSBwdWJsaWMgSmF2YQorICBmaWVsZC4gRm9yIHByaW1pdGl2ZSB0eXBlcywgdGhlc2UgZmllbGRzIHVzZSB0aGUgSmF2YSByZWZlcmVuY2UgdHlwZXMKKyAgc3VjaCBhcyBqYXZhLmxhbmcuSW50ZWdlciBpbnN0ZWFkIG9mIHByaW1pdGl2ZSB0eXBlcyBzdWNoIGFzIGludC4KKworICBJbiB0aGUgJ3JlZnR5cGVzJyBzdHlsZSwgZmllbGRzIGFyZSBpbml0aWFsaXplZCB0byBudWxsIChvciBlbXB0eQorICBhcnJheXMgZm9yIHJlcGVhdGVkIGZpZWxkcyksIGFuZCB0aGVpciBkZWZhdWx0IHZhbHVlcyBhcmUgbm90IGF2YWlsYWJsZS4KKyAgVGhleSBhcmUgc2VyaWFsaXplZCBvdmVyIHRoZSB3aXJlIGJhc2VkIG9uIGVxdWFsaXR5IHRvIG51bGwuCisKKyAgVGhlICdyZWZ0eXBlcycgbW9kZSBoYXMgc29tZSBhZGRpdGlvbmFsIGNvc3QgZHVlIHRvIGF1dG9ib3hpbmcgYW5kIHVzYWdlCisgIG9mIHJlZmVyZW5jZSB0eXBlcy4gSW4gcHJhY3RpY2UsIG1hbnkgYm94ZWQgdHlwZXMgYXJlIGNhY2hlZCwgYW5kIHNvIGRvbid0CisgIHJlc3VsdCBpbiBvYmplY3QgY3JlYXRpb24uIEhvd2V2ZXIsIHJlZmVyZW5jZXMgZG8gdGFrZSBzbGlnaHRseSBtb3JlIG1lbW9yeQorICB0aGFuIHByaW1pdGl2ZXMuCisKKyAgVGhlICdyZWZ0eXBlcycgbW9kZSBpcyB1c2VmdWwgd2hlbiB5b3Ugd2FudCB0byBiZSBhYmxlIHRvIHNlcmlhbGl6ZSBmaWVsZHMKKyAgd2l0aCBkZWZhdWx0IHZhbHVlcywgb3IgY2hlY2sgaWYgYSBmaWVsZCBoYXMgYmVlbiBleHBsaWNpdGx5IHNldCB0byB0aGUKKyAgZGVmYXVsdCBvdmVyIHRoZSB3aXJlIHdpdGhvdXQgcGF5aW5nIHRoZSBleHRyYSBtZXRob2QgY29zdCBvZiB0aGUKKyAgJ2FjY2Vzc29ycycgbW9kZS4KKworICBOb3RlIHRoYXQgaWYgeW91IGF0dGVtcHQgdG8gd3JpdGUgbnVsbCB0byBhIHJlcXVpcmVkIGZpZWxkIGluIHRoZSByZWZ0eXBlcworICBtb2RlLCBzZXJpYWxpemF0aW9uIG9mIHRoZSBwcm90byB3aWxsIGNhdXNlIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24uIFRoaXMgaXMKKyAgYW4gaW50ZW50aW9uYWwgaW5kaWNhdG9yIHRoYXQgeW91IG11c3Qgc2V0IHJlcXVpcmVkIGZpZWxkcy4KKworICBOT1RFCisgIG9wdGlvbmFsX2ZpZWxkX3N0eWxlPWFjY2Vzc29ycyBvciByZWZ0eXBlcyBjYW5ub3QgYmUgdXNlZCB0b2dldGhlciB3aXRoCisgIGphdmFfbmFub19nZW5lcmF0ZV9oYXM9dHJ1ZS4gSWYgeW91IG5lZWQgdGhlICdoYXMnIGZsYWcgZm9yIGFueQorICByZXF1aXJlZCBmaWVsZCAoeW91IGhhdmUgbm8gcmVhc29uIHRvKSwgeW91IGNhbiBvbmx5IHVzZQorICBqYXZhX25hbm9fZ2VuZXJhdGVfaGFzPXRydWUuCisKK2VudW1fc3R5bGU9e2MsamF2YX0gKGRlZmF1bHQ6IGMpCisgIERlZmluZXMgd2hlcmUgdG8gcHV0IHRoZSBpbnQgY29uc3RhbnRzIGdlbmVyYXRlZCBmcm9tIGVudW0gbWVtYmVycy4KKworICAqIGMgKgorCisgIFVzZSBDLXN0eWxlLCBzbyB0aGUgZW51bSBjb25zdGFudHMgYXJlIGF2YWlsYWJsZSBhdCB0aGUgc2NvcGUgd2hlcmUKKyAgdGhlIGVudW0gaXMgZGVmaW5lZC4gQSBmaWxlLXNjb3BlIGVudW0ncyBtZW1iZXJzIGFyZSByZWZlcmVuY2VkIGxpa2UKKyAgJ0ZpbGVPdXRlckNsYXNzLkVOVU1fVkFMVUUnOyBhIG1lc3NhZ2Utc2NvcGUgZW51bSdzIG1lbWJlcnMgYXJlCisgIHJlZmVyZW5jZWQgYXMgJ01lc3NhZ2UuRU5VTV9WQUxVRScuIFRoZSBlbnVtIG5hbWUgaXMgdW5hdmFpbGFibGUuCisgIFRoaXMgY29tcGxpZXMgd2l0aCB0aGUgTWljcm8gY29kZSBnZW5lcmF0b3IncyBiZWhhdmlvci4KKworICAqIGphdmEgKgorCisgIFVzZSBKYXZhLXN0eWxlLCBzbyB0aGUgZW51bSBjb25zdGFudHMgYXJlIGF2YWlsYWJsZSB1bmRlciB0aGUgZW51bQorICBuYW1lIGFuZCByZWZlcmVuY2VkIGxpa2UgJ0VudW1OYW1lLkVOVU1fVkFMVUUnICh0aGV5IGFyZSBzdGlsbCBpbnQKKyAgY29uc3RhbnRzKS4gVGhlIGVudW0gbmFtZSBiZWNvbWVzIHRoZSBuYW1lIG9mIGEgcHVibGljIGludGVyZmFjZSwgYXQKKyAgdGhlIHNjb3BlIHdoZXJlIHRoZSBlbnVtIGlzIGRlZmluZWQuIElmIHRoZSBlbnVtIGlzIGZpbGUtc2NvcGUgYW5kCisgIHRoZSBqYXZhX211bHRpcGxlX2ZpbGVzIG9wdGlvbiBpcyBvbiwgdGhlIGludGVyZmFjZSB3aWxsIGJlIGRlZmluZWQKKyAgaW4gaXRzIG93biBmaWxlLiBUbyByZWR1Y2UgY29kZSBzaXplLCB0aGlzIGludGVyZmFjZSBzaG91bGQgbm90IGJlCisgIGltcGxlbWVudGVkIGFuZCBQcm9HdWFyZCBzaHJpbmtpbmcgc2hvdWxkIGJlIHVzZWQsIHNvIGFmdGVyIHRoZSBKYXZhCisgIGNvbXBpbGVyIGlubGluZXMgYWxsIHJlZmVyZW5jZWQgZW51bSBjb25zdGFudHMgaW50byB0aGUgY2FsbCBzaXRlcywKKyAgdGhlIGludGVyZmFjZSByZW1haW5zIHVudXNlZCBhbmQgY2FuIGJlIHJlbW92ZWQgYnkgUHJvR3VhcmQuCisKK2lnbm9yZV9zZXJ2aWNlcz17dHJ1ZSxmYWxzZX0gKGRlZmF1bHQ6IGZhbHNlKQorICBTa2lwcyBzZXJ2aWNlcyBkZWZpbml0aW9ucy4KKworICBOYW5vIGRvZXNuJ3Qgc3VwcG9ydCBzZXJ2aWNlcy4gQnkgZGVmYXVsdCwgaWYgYSBzZXJ2aWNlIGlzIGRlZmluZWQKKyAgaXQgd2lsbCBnZW5lcmF0ZSBhIGNvbXBpbGF0aW9uIGVycm9yLiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIHRydWUsCisgIHNlcnZpY2VzIHdpbGwgYmUgc2lsZW50bHkgaWdub3JlZCwgaW5zdGVhZC4KKworcGFyY2VsYWJsZV9tZXNzYWdlcz17dHJ1ZSxmYWxzZX0gKGRlZmF1bHQ6IGZhbHNlKQorICBBbmRyb2lkLXNwZWNpZmljIG9wdGlvbiB0byBnZW5lcmF0ZSBQYXJjZWxhYmxlIG1lc3NhZ2VzLgorCisKK1RvIHVzZSBuYW5vIHByb3RvYnVmcyB3aXRoaW4gdGhlIEFuZHJvaWQgcmVwbzoKKworLSBTZXQgJ0xPQ0FMX1BST1RPQ19PUFRJTUlaRV9UWVBFIDo9IG5hbm8nIGluIHlvdXIgbG9jYWwgLm1rIGZpbGUuCisgIFdoZW4gYnVpbGRpbmcgYSBKYXZhIGxpYnJhcnkgb3IgYW4gYXBwIChwYWNrYWdlKSB0YXJnZXQsIHRoZSBidWlsZAorICBzeXN0ZW0gd2lsbCBhZGQgdGhlIEphdmEgbmFubyBydW50aW1lIGxpYnJhcnkgdG8gdGhlCisgIExPQ0FMX1NUQVRJQ19KQVZBX0xJQlJBUklFUyB2YXJpYWJsZSwgc28geW91IGRvbid0IG5lZWQgdG8uCistIFNldCAnTE9DQUxfUFJPVE9fSkFWQV9PVVRQVVRfUEFSQU1TIDo9IC4uLicgaW4geW91ciBsb2NhbCAubWsgZmlsZQorICBmb3IgYW55IGNvbW1hbmQtbGluZSBvcHRpb25zIHlvdSBuZWVkLiBVc2UgY29tbWFzIHRvIGpvaW4gbXVsdGlwbGUKKyAgb3B0aW9ucy4gSW4gdGhlIG5hbm8gZmxhdm9yIG9ubHksIHdoaXRlc3BhY2Ugc3Vycm91bmRpbmcgdGhlIG9wdGlvbgorICBuYW1lcyBhbmQgdmFsdWVzIGFyZSBpZ25vcmVkLCBzbyB5b3UgY2FuIHVzZSBiYWNrc2xhc2gtbmV3bGluZSBvcgorICAnKz0nIHRvIHN0cnVjdHVyZSB5b3VyIG1ha2UgZmlsZXMgbmljZWx5LgorLSBUaGUgb3B0aW9ucyB3aWxsIGJlIGFwcGxpZWQgdG8gKmFsbCogcHJvdG8gZmlsZXMgaW4gTE9DQUxfU1JDX0ZJTEVTCisgIHdoZW4geW91IGJ1aWxkIGEgSmF2YSBsaWJyYXJ5IG9yIHBhY2thZ2UuIEluIGNhc2UgZGlmZmVyZW50IG9wdGlvbnMKKyAgYXJlIG5lZWRlZCBmb3IgZGlmZmVyZW50IHByb3RvIGZpbGVzLCBidWlsZCBzZXBhcmF0ZSBKYXZhIGxpYnJhcmllcworICBhbmQgcmVmZXJlbmNlIHRoZW0gaW4geW91ciBtYWluIHRhcmdldC4gTm90ZTogeW91IHNob3VsZCBtYWtlIHN1cmUKKyAgdGhhdCwgZm9yIGVhY2ggc2VwYXJhdGUgdGFyZ2V0LCBhbGwgcHJvdG8gZmlsZXMgaW1wb3J0ZWQgZnJvbSBhbnkKKyAgcHJvdG8gZmlsZSBpbiBMT0NBTF9TUkNfRklMRVMgYXJlIGluY2x1ZGVkIGluIExPQ0FMX1NSQ19GSUxFUy4gVGhpcworICBpcyBiZWNhdXNlIHRoZSBnZW5lcmF0b3IgaGFzIHRvIGFzc3VtZSB0aGF0IHRoZSBpbXBvcnRlZCBmaWxlcyBhcmUKKyAgYnVpbHQgdXNpbmcgdGhlIHNhbWUgb3B0aW9ucywgYW5kIHdpbGwgZ2VuZXJhdGUgY29kZSB0aGF0IHJlZmVyZW5jZQorICB0aGUgZmllbGRzIGFuZCBlbnVtcyBmcm9tIHRoZSBpbXBvcnRlZCBmaWxlcyB1c2luZyB0aGUgc2FtZSBjb2RlCisgIHN0eWxlLgorLSBIaW50OiAnaW5jbHVkZSAkKENMRUFSX1ZBUlMpJyByZXNldHMgYWxsIExPQ0FMXyB2YXJpYWJsZXMsIGluY2x1ZGluZworICB0aGUgdHdvIGFib3ZlLgorCitUbyB1c2UgbmFubyBwcm90b2J1ZnMgb3V0c2lkZSBvZiBBbmRyb2lkIHJlcG86CisKKy0gTGluayB3aXRoIHRoZSBnZW5lcmF0ZWQgamFyIGZpbGUKKyAgPHByb3RvYnVmLXJvb3Q+amF2YS90YXJnZXQvcHJvdG9idWYtamF2YS0yLjMuMC1uYW5vLmphci4KKy0gSW52b2tlIHdpdGggLS1qYXZhbmFub19vdXQsIGUuZy46CisKKy4vcHJvdG9jICctLWphdmFuYW5vX291dD1cCisgICAgamF2YV9wYWNrYWdlPXNyYy9wcm90by9zaW1wbGUtZGF0YS5wcm90b3xteV9wYWNrYWdlLFwKKyAgICBqYXZhX291dGVyX2NsYXNzbmFtZT1zcmMvcHJvdG8vc2ltcGxlLWRhdGEucHJvdG98T3V0ZXJOYW1lXAorICA6Licgc3JjL3Byb3RvL3NpbXBsZS1kYXRhLnByb3RvCisKK0NvbnRyaWJ1dGluZyB0byBuYW5vOgorCitQbGVhc2UgYWRkL2VkaXQgdGVzdHMgaW4gTmFub1Rlc3QuamF2YS4KKworUGxlYXNlIHJ1biB0aGUgZm9sbG93aW5nIHN0ZXBzIHRvIHRlc3Q6CisKKy0gY2QgZXh0ZXJuYWwvcHJvdG9idWYKKy0gLi9jb25maWd1cmUKKy0gUnVuICJtYWtlIC1qMTIgY2hlY2siIGFuZCB2ZXJpZnkgYWxsIHRlc3RzIHBhc3MuCistIGNkIGphdmEKKy0gUnVuICJtdm4gdGVzdCIgYW5kIHZlcmlmeSBhbGwgdGVzdHMgcGFzcy4KKy0gY2QgLi4vLi4vLi4KKy0gLiBidWlsZC9lbnZzZXR1cC5zaAorLSBsdW5jaCAxCistICJtYWtlIC1qMTIgYXByb3RvYyBsaWJwcm90b2J1Zi1qYXZhLTIuMy4wLW5hbm8gYXByb3RvYy10ZXN0LW5hbm8tcGFyYW1zIE5hbm9BbmRyb2lkVGVzdCIgYW5kCisgIGNoZWNrIGZvciBidWlsZCBlcnJvcnMuCistIFBsdWcgaW4gYW4gQW5kcm9pZCBkZXZpY2Ugb3Igc3RhcnQgYW4gZW11bGF0b3IuCistIGFkYiBpbnN0YWxsIC1yIG91dC90YXJnZXQvcHJvZHVjdC9nZW5lcmljL2RhdGEvYXBwL05hbm9BbmRyb2lkVGVzdC5hcGsKKy0gUnVuOgorICAiYWRiIHNoZWxsIGFtIGluc3RydW1lbnQgLXcgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLnRlc3QvYW5kcm9pZC50ZXN0Lkluc3RydW1lbnRhdGlvblRlc3RSdW5uZXIiCisgIGFuZCB2ZXJpZnkgYWxsIHRlc3RzIHBhc3MuCistIHJlcG8gc3luYyAtYyAtajI1NgorLSAibWFrZSAtajEyIiBhbmQgY2hlY2sgZm9yIGJ1aWxkIGVycm9ycworCitVc2FnZQorPT09PT0KKworVGhlIGNvbXBsZXRlIGRvY3VtZW50YXRpb24gZm9yIFByb3RvY29sIEJ1ZmZlcnMgaXMgYXZhaWxhYmxlIHZpYSB0aGUKK3dlYiBhdDoKKworICAgIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCmRpZmYgLS1naXQgYS9qYXZhbmFuby9wb20ueG1sIGIvamF2YW5hbm8vcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTJiZTlkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vcG9tLnhtbApAQCAtMCwwICsxLDIyNSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisgIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisgIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgIDxwYXJlbnQ+CisgICAgPGdyb3VwSWQ+Y29tLmdvb2dsZTwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5nb29nbGU8L2FydGlmYWN0SWQ+CisgICAgPHZlcnNpb24+MTwvdmVyc2lvbj4KKyAgPC9wYXJlbnQ+CisgIDxncm91cElkPmNvbS5nb29nbGUucHJvdG9idWYubmFubzwvZ3JvdXBJZD4KKyAgPGFydGlmYWN0SWQ+cHJvdG9idWYtamF2YW5hbm88L2FydGlmYWN0SWQ+CisgIDx2ZXJzaW9uPjMuMC4wLWFscGhhLTMtcHJlPC92ZXJzaW9uPgorICA8cGFja2FnaW5nPmJ1bmRsZTwvcGFja2FnaW5nPgorICA8bmFtZT5Qcm90b2NvbCBCdWZmZXIgSmF2YU5hbm8gQVBJPC9uYW1lPgorICA8ZGVzY3JpcHRpb24+CisgICAgUHJvdG9jb2wgQnVmZmVycyBhcmUgYSB3YXkgb2YgZW5jb2Rpbmcgc3RydWN0dXJlZCBkYXRhIGluIGFuIGVmZmljaWVudCB5ZXQKKyAgICBleHRlbnNpYmxlIGZvcm1hdC4KKyAgPC9kZXNjcmlwdGlvbj4KKyAgPGluY2VwdGlvblllYXI+MjAwODwvaW5jZXB0aW9uWWVhcj4KKyAgPHVybD5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLzwvdXJsPgorICA8bGljZW5zZXM+CisgICAgPGxpY2Vuc2U+CisgICAgICA8bmFtZT5OZXcgQlNEIGxpY2Vuc2U8L25hbWU+CisgICAgICA8dXJsPmh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvYnNkLWxpY2Vuc2UucGhwPC91cmw+CisgICAgICA8ZGlzdHJpYnV0aW9uPnJlcG88L2Rpc3RyaWJ1dGlvbj4KKyAgICA8L2xpY2Vuc2U+CisgIDwvbGljZW5zZXM+CisgIDxzY20+CisgICAgPHVybD5odHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmPC91cmw+CisgICAgPGNvbm5lY3Rpb24+CisgICAgICBzY206Z2l0Omh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvcHJvdG9idWYuZ2l0CisgICAgPC9jb25uZWN0aW9uPgorICA8L3NjbT4KKyAgPHByb3BlcnRpZXM+CisgICAgPHByb2plY3QuYnVpbGQuc291cmNlRW5jb2Rpbmc+VVRGLTg8L3Byb2plY3QuYnVpbGQuc291cmNlRW5jb2Rpbmc+CisgIDwvcHJvcGVydGllcz4KKyAgPGRlcGVuZGVuY2llcz4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPmp1bml0PC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+anVuaXQ8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj40LjQ8L3ZlcnNpb24+CisgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgPC9kZXBlbmRlbmN5PgorICAgIDxkZXBlbmRlbmN5PgorICAgICAgPGdyb3VwSWQ+b3JnLmVhc3ltb2NrPC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+ZWFzeW1vY2s8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4yLjI8L3ZlcnNpb24+CisgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgPC9kZXBlbmRlbmN5PgorICAgIDxkZXBlbmRlbmN5PgorICAgICAgPGdyb3VwSWQ+b3JnLmVhc3ltb2NrPC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+ZWFzeW1vY2tjbGFzc2V4dGVuc2lvbjwvYXJ0aWZhY3RJZD4KKyAgICAgIDx2ZXJzaW9uPjIuMi4xPC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgPC9kZXBlbmRlbmNpZXM+CisgIDxidWlsZD4KKyAgICA8cGx1Z2lucz4KKyAgICAgIDxwbHVnaW4+CisgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgPHNvdXJjZT4xLjU8L3NvdXJjZT4KKyAgICAgICAgICA8dGFyZ2V0PjEuNTwvdGFyZ2V0PgorICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICAgIDxwbHVnaW4+CisgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLXN1cmVmaXJlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgPGluY2x1ZGVzPgorICAgICAgICAgICAgPGluY2x1ZGU+KiovKlRlc3QuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICA8L2luY2x1ZGVzPgorICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICAgIDxwbHVnaW4+CisgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWFudHJ1bi1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgIDxleGVjdXRpb25zPgorICAgICAgICAgIDxleGVjdXRpb24+CisgICAgICAgICAgICA8aWQ+Z2VuZXJhdGUtdGVzdC1zb3VyY2VzPC9pZD4KKyAgICAgICAgICAgIDxwaGFzZT5nZW5lcmF0ZS10ZXN0LXNvdXJjZXM8L3BoYXNlPgorICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgIDx0YXNrcz4KKyAgICAgICAgICAgICAgICA8bWtkaXIgZGlyPSJ0YXJnZXQvZ2VuZXJhdGVkLXRlc3Qtc291cmNlcyIgLz4KKyAgICAgICAgICAgICAgICA8ZXhlYyBleGVjdXRhYmxlPSIuLi9zcmMvcHJvdG9jIj4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii0tamF2YW5hbm9fb3V0PWdlbmVyYXRlX2VxdWFscz10cnVlOnRhcmdldC9nZW5lcmF0ZWQtdGVzdC1zb3VyY2VzIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLS1wcm90b19wYXRoPXNyYy90ZXN0L2phdmEvY29tIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3NpbXBsZV9uYW5vLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3Rfc3RyaW5ndXRmOF9uYW5vLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVjdXJzaXZlX25hbm8ucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9pbXBvcnRfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3NpbmdsZV9uYW5vLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbXVsdGlwbGVfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X211bHRpcGxlX25hbWVjbGFzaF9uYW5vLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV9jbGFzc19uYW5vLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVwZWF0ZWRfbWVyZ2VfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL21hcF90ZXN0LnByb3RvIiAvPgorICAgICAgICAgICAgICAgIDwvZXhlYz4KKyAgICAgICAgICAgICAgICA8ZXhlYyBleGVjdXRhYmxlPSIuLi9zcmMvcHJvdG9jIj4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii0tamF2YW5hbm9fb3V0PXN0b3JlX3Vua25vd25fZmllbGRzPXRydWUsZ2VuZXJhdGVfZXF1YWxzPXRydWU6dGFyZ2V0L2dlbmVyYXRlZC10ZXN0LXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YS9jb20iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9leHRlbnNpb25fbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9zaW5ndWxhcl9uYW5vLnByb3RvIiAvPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0ic3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3JlcGVhdGVkX25hbm8ucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgPC9leGVjPgorICAgICAgICAgICAgICAgIDxleGVjIGV4ZWN1dGFibGU9Ii4uL3NyYy9wcm90b2MiPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLS1qYXZhbmFub19vdXQ9c3RvcmVfdW5rbm93bl9maWVsZHM9dHJ1ZTp0YXJnZXQvZ2VuZXJhdGVkLXRlc3Qtc291cmNlcyIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9Ii0tcHJvdG9fcGF0aD1zcmMvdGVzdC9qYXZhL2NvbSIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9wYWNrZWRfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICA8L2V4ZWM+CisgICAgICAgICAgICAgICAgPGV4ZWMgZXhlY3V0YWJsZT0iLi4vc3JjL3Byb3RvYyI+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLWphdmFuYW5vX291dD1qYXZhX25hbm9fZ2VuZXJhdGVfaGFzPXRydWUsZ2VuZXJhdGVfZXF1YWxzPXRydWU6dGFyZ2V0L2dlbmVyYXRlZC10ZXN0LXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YS9jb20iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9oYXNfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICA8L2V4ZWM+CisgICAgICAgICAgICAgICAgPGV4ZWMgZXhlY3V0YWJsZT0iLi4vc3JjL3Byb3RvYyI+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLWphdmFuYW5vX291dD1vcHRpb25hbF9maWVsZF9zdHlsZT1hY2Nlc3NvcnMsZ2VuZXJhdGVfZXF1YWxzPXRydWU6dGFyZ2V0L2dlbmVyYXRlZC10ZXN0LXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YS9jb20iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9hY2Nlc3NvcnNfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICA8L2V4ZWM+CisgICAgICAgICAgICAgICAgPGV4ZWMgZXhlY3V0YWJsZT0iLi4vc3JjL3Byb3RvYyI+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLWphdmFuYW5vX291dD1lbnVtX3N0eWxlPWphdmE6dGFyZ2V0L2dlbmVyYXRlZC10ZXN0LXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YS9jb20iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9lbnVtX2NsYXNzX25hbm8ucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9lbnVtX2NsYXNzX211bHRpcGxlX25hbm8ucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZXBlYXRlZF9wYWNrYWJsZXNfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICAgIDxhcmcgdmFsdWU9InNyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2VudW1fdmFsaWRpdHlfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICA8L2V4ZWM+CisgICAgICAgICAgICAgICAgPGV4ZWMgZXhlY3V0YWJsZT0iLi4vc3JjL3Byb3RvYyI+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLWphdmFuYW5vX291dD0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9maWVsZF9zdHlsZT1hY2Nlc3NvcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YV9vdXRlcl9jbGFzc25hbWU9Z29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV92YWxpZGl0eV9uYW5vLnByb3RvfEVudW1WYWxpZGl0eUFjY2Vzc29ycworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6dGFyZ2V0L2dlbmVyYXRlZC10ZXN0LXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YS9jb20iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9lbnVtX3ZhbGlkaXR5X25hbm8ucHJvdG8iIC8+CisgICAgICAgICAgICAgICAgPC9leGVjPgorICAgICAgICAgICAgICAgIDxleGVjIGV4ZWN1dGFibGU9Ii4uL3NyYy9wcm90b2MiPgorICAgICAgICAgICAgICAgICAgPGFyZyB2YWx1ZT0iLS1qYXZhbmFub19vdXQ9b3B0aW9uYWxfZmllbGRfc3R5bGU9cmVmdHlwZXMsZ2VuZXJhdGVfZXF1YWxzPXRydWU6dGFyZ2V0L2dlbmVyYXRlZC10ZXN0LXNvdXJjZXMiIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSItLXByb3RvX3BhdGg9c3JjL3Rlc3QvamF2YS9jb20iIC8+CisgICAgICAgICAgICAgICAgICA8YXJnIHZhbHVlPSJzcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZWZlcmVuY2VfdHlwZXNfbmFuby5wcm90byIgLz4KKyAgICAgICAgICAgICAgICA8L2V4ZWM+CisgICAgICAgICAgICAgIDwvdGFza3M+CisgICAgICAgICAgICAgIDx0ZXN0U291cmNlUm9vdD50YXJnZXQvZ2VuZXJhdGVkLXRlc3Qtc291cmNlczwvdGVzdFNvdXJjZVJvb3Q+CisgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICA8Z29hbHM+CisgICAgICAgICAgICAgIDxnb2FsPnJ1bjwvZ29hbD4KKyAgICAgICAgICAgIDwvZ29hbHM+CisgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgIDwvcGx1Z2luPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKyAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tYnVuZGxlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPGV4dGVuc2lvbnM+dHJ1ZTwvZXh0ZW5zaW9ucz4KKyAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgPGluc3RydWN0aW9ucz4KKyAgICAgICAgICAgIDxCdW5kbGUtRG9jVVJMPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvPC9CdW5kbGUtRG9jVVJMPgorICAgICAgICAgICAgPEJ1bmRsZS1TeW1ib2xpY05hbWU+Y29tLmdvb2dsZS5wcm90b2J1ZjwvQnVuZGxlLVN5bWJvbGljTmFtZT4KKyAgICAgICAgICAgIDxFeHBvcnQtUGFja2FnZT5jb20uZ29vZ2xlLnByb3RvYnVmO3ZlcnNpb249My4wLjAtYWxwaGEtMy1wcmU8L0V4cG9ydC1QYWNrYWdlPgorICAgICAgICAgIDwvaW5zdHJ1Y3Rpb25zPgorICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICA8L3BsdWdpbnM+CisgIDwvYnVpbGQ+CisgIDxwcm9maWxlcz4KKyAgICA8cHJvZmlsZT4KKyAgICAgIDxpZD5yZWxlYXNlPC9pZD4KKyAgICAgIDxidWlsZD4KKyAgICAgICAgPHBsdWdpbnM+CisgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLXNvdXJjZS1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4yLjIuMTwvdmVyc2lvbj4KKyAgICAgICAgICAgIDxleGVjdXRpb25zPgorICAgICAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgIDxpZD5hdHRhY2gtc291cmNlczwvaWQ+CisgICAgICAgICAgICAgICAgPGdvYWxzPgorICAgICAgICAgICAgICAgICAgPGdvYWw+amFyLW5vLWZvcms8L2dvYWw+CisgICAgICAgICAgICAgICAgPC9nb2Fscz4KKyAgICAgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgICAgICA8L2V4ZWN1dGlvbnM+CisgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWphdmFkb2MtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+Mi45LjE8L3ZlcnNpb24+CisgICAgICAgICAgICA8ZXhlY3V0aW9ucz4KKyAgICAgICAgICAgICAgPGV4ZWN1dGlvbj4KKyAgICAgICAgICAgICAgICA8aWQ+YXR0YWNoLWphdmFkb2NzPC9pZD4KKyAgICAgICAgICAgICAgICA8Z29hbHM+CisgICAgICAgICAgICAgICAgICA8Z29hbD5qYXI8L2dvYWw+CisgICAgICAgICAgICAgICAgPC9nb2Fscz4KKyAgICAgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgICAgICA8L2V4ZWN1dGlvbnM+CisgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWdwZy1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4xLjU8L3ZlcnNpb24+CisgICAgICAgICAgICA8ZXhlY3V0aW9ucz4KKyAgICAgICAgICAgICAgPGV4ZWN1dGlvbj4KKyAgICAgICAgICAgICAgICA8aWQ+c2lnbi1hcnRpZmFjdHM8L2lkPgorICAgICAgICAgICAgICAgIDxwaGFzZT52ZXJpZnk8L3BoYXNlPgorICAgICAgICAgICAgICAgIDxnb2Fscz4KKyAgICAgICAgICAgICAgICAgIDxnb2FsPnNpZ248L2dvYWw+CisgICAgICAgICAgICAgICAgPC9nb2Fscz4KKyAgICAgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgICAgICA8L2V4ZWN1dGlvbnM+CisgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5zb25hdHlwZS5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bmV4dXMtc3RhZ2luZy1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICAgICAgICAgIDxleHRlbnNpb25zPnRydWU8L2V4dGVuc2lvbnM+CisgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgIDxzZXJ2ZXJJZD5zb25hdHlwZS1uZXh1cy1zdGFnaW5nPC9zZXJ2ZXJJZD4KKyAgICAgICAgICAgICAgIDxuZXh1c1VybD5odHRwczovL29zcy5zb25hdHlwZS5vcmcvPC9uZXh1c1VybD4KKyAgICAgICAgICAgICAgIDxhdXRvUmVsZWFzZUFmdGVyQ2xvc2U+ZmFsc2U8L2F1dG9SZWxlYXNlQWZ0ZXJDbG9zZT4KKyAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgPC9wbHVnaW5zPgorICAgICAgPC9idWlsZD4KKyAgICA8L3Byb2ZpbGU+CisgIDwvcHJvZmlsZXM+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9Db2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8uamF2YSBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0NvZGVkSW5wdXRCeXRlQnVmZmVyTmFuby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0ZjIwZmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9Db2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8uamF2YQpAQCAtMCwwICsxLDY4MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMyBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBSZWFkcyBhbmQgZGVjb2RlcyBwcm90b2NvbCBtZXNzYWdlIGZpZWxkcy4KKyAqCisgKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHR3byBraW5kcyBvZiBtZXRob2RzOiAgbWV0aG9kcyB0aGF0IHJlYWQgc3BlY2lmaWMKKyAqIHByb3RvY29sIG1lc3NhZ2UgY29uc3RydWN0cyBhbmQgZmllbGQgdHlwZXMgKGUuZy4ge0BsaW5rICNyZWFkVGFnKCl9IGFuZAorICoge0BsaW5rICNyZWFkSW50MzIoKX0pIGFuZCBtZXRob2RzIHRoYXQgcmVhZCBsb3ctbGV2ZWwgdmFsdWVzIChlLmcuCisgKiB7QGxpbmsgI3JlYWRSYXdWYXJpbnQzMigpfSBhbmQge0BsaW5rICNyZWFkUmF3Qnl0ZXN9KS4gIElmIHlvdSBhcmUgcmVhZGluZworICogZW5jb2RlZCBwcm90b2NvbCBtZXNzYWdlcywgeW91IHNob3VsZCB1c2UgdGhlIGZvcm1lciBtZXRob2RzLCBidXQgaWYgeW91IGFyZQorICogcmVhZGluZyBzb21lIG90aGVyIGZvcm1hdCBvZiB5b3VyIG93biBkZXNpZ24sIHVzZSB0aGUgbGF0dGVyLgorICoKKyAqIEBhdXRob3Iga2VudG9uQGdvb2dsZS5jb20gS2VudG9uIFZhcmRhCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8geworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IENvZGVkSW5wdXRTdHJlYW0gd3JhcHBpbmcgdGhlIGdpdmVuIGJ5dGUgYXJyYXkuCisgICAqLworICBwdWJsaWMgc3RhdGljIENvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBuZXdJbnN0YW5jZShmaW5hbCBieXRlW10gYnVmKSB7CisgICAgcmV0dXJuIG5ld0luc3RhbmNlKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IENvZGVkSW5wdXRTdHJlYW0gd3JhcHBpbmcgdGhlIGdpdmVuIGJ5dGUgYXJyYXkgc2xpY2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIENvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBuZXdJbnN0YW5jZShmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2ZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbikgeworICAgIHJldHVybiBuZXcgQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vKGJ1Ziwgb2ZmLCBsZW4pOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvKioKKyAgICogQXR0ZW1wdCB0byByZWFkIGEgZmllbGQgdGFnLCByZXR1cm5pbmcgemVybyBpZiB3ZSBoYXZlIHJlYWNoZWQgRU9GLgorICAgKiBQcm90b2NvbCBtZXNzYWdlIHBhcnNlcnMgdXNlIHRoaXMgdG8gcmVhZCB0YWdzLCBzaW5jZSBhIHByb3RvY29sIG1lc3NhZ2UKKyAgICogbWF5IGxlZ2FsbHkgZW5kIHdoZXJldmVyIGEgdGFnIG9jY3VycywgYW5kIHplcm8gaXMgbm90IGEgdmFsaWQgdGFnIG51bWJlci4KKyAgICovCisgIHB1YmxpYyBpbnQgcmVhZFRhZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGlzQXRFbmQoKSkgeworICAgICAgbGFzdFRhZyA9IDA7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBsYXN0VGFnID0gcmVhZFJhd1ZhcmludDMyKCk7CisgICAgaWYgKGxhc3RUYWcgPT0gMCkgeworICAgICAgLy8gSWYgd2UgYWN0dWFsbHkgcmVhZCB6ZXJvLCB0aGF0J3Mgbm90IGEgdmFsaWQgdGFnLgorICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi5pbnZhbGlkVGFnKCk7CisgICAgfQorICAgIHJldHVybiBsYXN0VGFnOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQgdGhlIGxhc3QgY2FsbCB0byByZWFkVGFnKCkgcmV0dXJuZWQgdGhlIGdpdmVuIHRhZyB2YWx1ZS4KKyAgICogVGhpcyBpcyB1c2VkIHRvIHZlcmlmeSB0aGF0IGEgbmVzdGVkIGdyb3VwIGVuZGVkIHdpdGggdGhlIGNvcnJlY3QKKyAgICogZW5kIHRhZy4KKyAgICoKKyAgICogQHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uIHtAY29kZSB2YWx1ZX0gZG9lcyBub3QgbWF0Y2ggdGhlCisgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3QgdGFnLgorICAgKi8KKyAgcHVibGljIHZvaWQgY2hlY2tMYXN0VGFnV2FzKGZpbmFsIGludCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uIHsKKyAgICBpZiAobGFzdFRhZyAhPSB2YWx1ZSkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi5pbnZhbGlkRW5kVGFnKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGFuZCBkaXNjYXJkcyBhIHNpbmdsZSBmaWVsZCwgZ2l2ZW4gaXRzIHRhZyB2YWx1ZS4KKyAgICoKKyAgICogQHJldHVybiB7QGNvZGUgZmFsc2V9IGlmIHRoZSB0YWcgaXMgYW4gZW5kZ3JvdXAgdGFnLCBpbiB3aGljaCBjYXNlCisgICAqICAgICAgICAgbm90aGluZyBpcyBza2lwcGVkLiAgT3RoZXJ3aXNlLCByZXR1cm5zIHtAY29kZSB0cnVlfS4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHNraXBGaWVsZChmaW5hbCBpbnQgdGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN3aXRjaCAoV2lyZUZvcm1hdE5hbm8uZ2V0VGFnV2lyZVR5cGUodGFnKSkgeworICAgICAgY2FzZSBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9WQVJJTlQ6CisgICAgICAgIHJlYWRJbnQzMigpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfRklYRUQ2NDoKKyAgICAgICAgcmVhZFJhd0xpdHRsZUVuZGlhbjY0KCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgY2FzZSBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgICBza2lwUmF3Qnl0ZXMocmVhZFJhd1ZhcmludDMyKCkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfU1RBUlRfR1JPVVA6CisgICAgICAgIHNraXBNZXNzYWdlKCk7CisgICAgICAgIGNoZWNrTGFzdFRhZ1dhcygKKyAgICAgICAgICBXaXJlRm9ybWF0TmFuby5tYWtlVGFnKFdpcmVGb3JtYXROYW5vLmdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0VORF9HUk9VUCkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfRU5EX0dST1VQOgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBjYXNlIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0ZJWEVEMzI6CisgICAgICAgIHJlYWRSYXdMaXR0bGVFbmRpYW4zMigpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24uaW52YWxpZFdpcmVUeXBlKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGFuZCBkaXNjYXJkcyBhbiBlbnRpcmUgbWVzc2FnZS4gIFRoaXMgd2lsbCByZWFkIGVpdGhlciB1bnRpbCBFT0YKKyAgICogb3IgdW50aWwgYW4gZW5kZ3JvdXAgdGFnLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCisgICAqLworICBwdWJsaWMgdm9pZCBza2lwTWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGZpbmFsIGludCB0YWcgPSByZWFkVGFnKCk7CisgICAgICBpZiAodGFnID09IDAgfHwgIXNraXBGaWVsZCh0YWcpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKiBSZWFkIGEge0Bjb2RlIGRvdWJsZX0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgZG91YmxlIHJlYWREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShyZWFkUmF3TGl0dGxlRW5kaWFuNjQoKSk7CisgIH0KKworICAvKiogUmVhZCBhIHtAY29kZSBmbG9hdH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgZmxvYXQgcmVhZEZsb2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQocmVhZFJhd0xpdHRsZUVuZGlhbjMyKCkpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgdWludDY0fSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBsb25nIHJlYWRVSW50NjQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3VmFyaW50NjQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBpbnQ2NH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkSW50NjQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3VmFyaW50NjQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBpbnQzMn0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgaW50IHJlYWRJbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHJlYWRSYXdWYXJpbnQzMigpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgZml4ZWQ2NH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgbG9uZyByZWFkRml4ZWQ2NCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHJlYWRSYXdMaXR0bGVFbmRpYW42NCgpOworICB9CisKKyAgLyoqIFJlYWQgYSB7QGNvZGUgZml4ZWQzMn0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgaW50IHJlYWRGaXhlZDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCk7CisgIH0KKworICAvKiogUmVhZCBhIHtAY29kZSBib29sfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBib29sZWFuIHJlYWRCb29sKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd1ZhcmludDMyKCkgIT0gMDsKKyAgfQorCisgIC8qKiBSZWFkIGEge0Bjb2RlIHN0cmluZ30gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgU3RyaW5nIHJlYWRTdHJpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIGludCBzaXplID0gcmVhZFJhd1ZhcmludDMyKCk7CisgICAgaWYgKHNpemUgPD0gKGJ1ZmZlclNpemUgLSBidWZmZXJQb3MpICYmIHNpemUgPiAwKSB7CisgICAgICAvLyBGYXN0IHBhdGg6ICBXZSBhbHJlYWR5IGhhdmUgdGhlIGJ5dGVzIGluIGEgY29udGlndW91cyBidWZmZXIsIHNvCisgICAgICAvLyAgIGp1c3QgY29weSBkaXJlY3RseSBmcm9tIGl0LgorICAgICAgZmluYWwgU3RyaW5nIHJlc3VsdCA9IG5ldyBTdHJpbmcoYnVmZmVyLCBidWZmZXJQb3MsIHNpemUsICJVVEYtOCIpOworICAgICAgYnVmZmVyUG9zICs9IHNpemU7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0gZWxzZSB7CisgICAgICAvLyBTbG93IHBhdGg6ICBCdWlsZCBhIGJ5dGUgYXJyYXkgZmlyc3QgdGhlbiBjb3B5IGl0LgorICAgICAgcmV0dXJuIG5ldyBTdHJpbmcocmVhZFJhd0J5dGVzKHNpemUpLCAiVVRGLTgiKTsKKyAgICB9CisgIH0KKworICAvKiogUmVhZCBhIHtAY29kZSBncm91cH0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCByZWFkR3JvdXAoZmluYWwgTWVzc2FnZU5hbm8gbXNnLCBmaW5hbCBpbnQgZmllbGROdW1iZXIpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChyZWN1cnNpb25EZXB0aCA+PSByZWN1cnNpb25MaW1pdCkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi5yZWN1cnNpb25MaW1pdEV4Y2VlZGVkKCk7CisgICAgfQorICAgICsrcmVjdXJzaW9uRGVwdGg7CisgICAgbXNnLm1lcmdlRnJvbSh0aGlzKTsKKyAgICBjaGVja0xhc3RUYWdXYXMoCisgICAgICBXaXJlRm9ybWF0TmFuby5tYWtlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9FTkRfR1JPVVApKTsKKyAgICAtLXJlY3Vyc2lvbkRlcHRoOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZE1lc3NhZ2UoZmluYWwgTWVzc2FnZU5hbm8gbXNnKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgbGVuZ3RoID0gcmVhZFJhd1ZhcmludDMyKCk7CisgICAgaWYgKHJlY3Vyc2lvbkRlcHRoID49IHJlY3Vyc2lvbkxpbWl0KSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLnJlY3Vyc2lvbkxpbWl0RXhjZWVkZWQoKTsKKyAgICB9CisgICAgZmluYWwgaW50IG9sZExpbWl0ID0gcHVzaExpbWl0KGxlbmd0aCk7CisgICAgKytyZWN1cnNpb25EZXB0aDsKKyAgICBtc2cubWVyZ2VGcm9tKHRoaXMpOworICAgIGNoZWNrTGFzdFRhZ1dhcygwKTsKKyAgICAtLXJlY3Vyc2lvbkRlcHRoOworICAgIHBvcExpbWl0KG9sZExpbWl0KTsKKyAgfQorCisgIC8qKiBSZWFkIGEge0Bjb2RlIGJ5dGVzfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBieXRlW10gcmVhZEJ5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgc2l6ZSA9IHJlYWRSYXdWYXJpbnQzMigpOworICAgIGlmIChzaXplIDw9IChidWZmZXJTaXplIC0gYnVmZmVyUG9zKSAmJiBzaXplID4gMCkgeworICAgICAgLy8gRmFzdCBwYXRoOiAgV2UgYWxyZWFkeSBoYXZlIHRoZSBieXRlcyBpbiBhIGNvbnRpZ3VvdXMgYnVmZmVyLCBzbworICAgICAgLy8gICBqdXN0IGNvcHkgZGlyZWN0bHkgZnJvbSBpdC4KKyAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBidWZmZXJQb3MsIHJlc3VsdCwgMCwgc2l6ZSk7CisgICAgICBidWZmZXJQb3MgKz0gc2l6ZTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFNsb3cgcGF0aDogIEJ1aWxkIGEgYnl0ZSBhcnJheSBmaXJzdCB0aGVuIGNvcHkgaXQuCisgICAgICByZXR1cm4gcmVhZFJhd0J5dGVzKHNpemUpOworICAgIH0KKyAgfQorCisgIC8qKiBSZWFkIGEge0Bjb2RlIHVpbnQzMn0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgaW50IHJlYWRVSW50MzIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkUmF3VmFyaW50MzIoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkIGFuIGVudW0gZmllbGQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLiAgQ2FsbGVyIGlzIHJlc3BvbnNpYmxlCisgICAqIGZvciBjb252ZXJ0aW5nIHRoZSBudW1lcmljIHZhbHVlIHRvIGFuIGFjdHVhbCBlbnVtLgorICAgKi8KKyAgcHVibGljIGludCByZWFkRW51bSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHJlYWRSYXdWYXJpbnQzMigpOworICB9CisKKyAgLyoqIFJlYWQgYW4ge0Bjb2RlIHNmaXhlZDMyfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBpbnQgcmVhZFNGaXhlZDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCk7CisgIH0KKworICAvKiogUmVhZCBhbiB7QGNvZGUgc2ZpeGVkNjR9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIGxvbmcgcmVhZFNGaXhlZDY0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZFJhd0xpdHRsZUVuZGlhbjY0KCk7CisgIH0KKworICAvKiogUmVhZCBhbiB7QGNvZGUgc2ludDMyfSBmaWVsZCB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBpbnQgcmVhZFNJbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGRlY29kZVppZ1phZzMyKHJlYWRSYXdWYXJpbnQzMigpKTsKKyAgfQorCisgIC8qKiBSZWFkIGFuIHtAY29kZSBzaW50NjR9IGZpZWxkIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIGxvbmcgcmVhZFNJbnQ2NCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGRlY29kZVppZ1phZzY0KHJlYWRSYXdWYXJpbnQ2NCgpKTsKKyAgfQorCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLyoqCisgICAqIFJlYWQgYSByYXcgVmFyaW50IGZyb20gdGhlIHN0cmVhbS4gIElmIGxhcmdlciB0aGFuIDMyIGJpdHMsIGRpc2NhcmQgdGhlCisgICAqIHVwcGVyIGJpdHMuCisgICAqLworICBwdWJsaWMgaW50IHJlYWRSYXdWYXJpbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZSB0bXAgPSByZWFkUmF3Qnl0ZSgpOworICAgIGlmICh0bXAgPj0gMCkgeworICAgICAgcmV0dXJuIHRtcDsKKyAgICB9CisgICAgaW50IHJlc3VsdCA9IHRtcCAmIDB4N2Y7CisgICAgaWYgKCh0bXAgPSByZWFkUmF3Qnl0ZSgpKSA+PSAwKSB7CisgICAgICByZXN1bHQgfD0gdG1wIDw8IDc7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdCB8PSAodG1wICYgMHg3ZikgPDwgNzsKKyAgICAgIGlmICgodG1wID0gcmVhZFJhd0J5dGUoKSkgPj0gMCkgeworICAgICAgICByZXN1bHQgfD0gdG1wIDw8IDE0OworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0IHw9ICh0bXAgJiAweDdmKSA8PCAxNDsKKyAgICAgICAgaWYgKCh0bXAgPSByZWFkUmF3Qnl0ZSgpKSA+PSAwKSB7CisgICAgICAgICAgcmVzdWx0IHw9IHRtcCA8PCAyMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQgfD0gKHRtcCAmIDB4N2YpIDw8IDIxOworICAgICAgICAgIHJlc3VsdCB8PSAodG1wID0gcmVhZFJhd0J5dGUoKSkgPDwgMjg7CisgICAgICAgICAgaWYgKHRtcCA8IDApIHsKKyAgICAgICAgICAgIC8vIERpc2NhcmQgdXBwZXIgMzIgYml0cy4KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgICAgICAgICAgIGlmIChyZWFkUmF3Qnl0ZSgpID49IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLm1hbGZvcm1lZFZhcmludCgpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqIFJlYWQgYSByYXcgVmFyaW50IGZyb20gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIGxvbmcgcmVhZFJhd1ZhcmludDY0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgc2hpZnQgPSAwOworICAgIGxvbmcgcmVzdWx0ID0gMDsKKyAgICB3aGlsZSAoc2hpZnQgPCA2NCkgeworICAgICAgZmluYWwgYnl0ZSBiID0gcmVhZFJhd0J5dGUoKTsKKyAgICAgIHJlc3VsdCB8PSAobG9uZykoYiAmIDB4N0YpIDw8IHNoaWZ0OworICAgICAgaWYgKChiICYgMHg4MCkgPT0gMCkgeworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgICAgc2hpZnQgKz0gNzsKKyAgICB9CisgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi5tYWxmb3JtZWRWYXJpbnQoKTsKKyAgfQorCisgIC8qKiBSZWFkIGEgMzItYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlciBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBpbnQgcmVhZFJhd0xpdHRsZUVuZGlhbjMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBieXRlIGIxID0gcmVhZFJhd0J5dGUoKTsKKyAgICBmaW5hbCBieXRlIGIyID0gcmVhZFJhd0J5dGUoKTsKKyAgICBmaW5hbCBieXRlIGIzID0gcmVhZFJhd0J5dGUoKTsKKyAgICBmaW5hbCBieXRlIGI0ID0gcmVhZFJhd0J5dGUoKTsKKyAgICByZXR1cm4gKChiMSAmIDB4ZmYpICAgICAgKSB8CisgICAgICAgICAgICgoYjIgJiAweGZmKSA8PCAgOCkgfAorICAgICAgICAgICAoKGIzICYgMHhmZikgPDwgMTYpIHwKKyAgICAgICAgICAgKChiNCAmIDB4ZmYpIDw8IDI0KTsKKyAgfQorCisgIC8qKiBSZWFkIGEgNjQtYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlciBmcm9tIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyBsb25nIHJlYWRSYXdMaXR0bGVFbmRpYW42NCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgYnl0ZSBiMSA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiMiA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiMyA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiNCA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiNSA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiNiA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiNyA9IHJlYWRSYXdCeXRlKCk7CisgICAgZmluYWwgYnl0ZSBiOCA9IHJlYWRSYXdCeXRlKCk7CisgICAgcmV0dXJuICgoKGxvbmcpYjEgJiAweGZmKSAgICAgICkgfAorICAgICAgICAgICAoKChsb25nKWIyICYgMHhmZikgPDwgIDgpIHwKKyAgICAgICAgICAgKCgobG9uZyliMyAmIDB4ZmYpIDw8IDE2KSB8CisgICAgICAgICAgICgoKGxvbmcpYjQgJiAweGZmKSA8PCAyNCkgfAorICAgICAgICAgICAoKChsb25nKWI1ICYgMHhmZikgPDwgMzIpIHwKKyAgICAgICAgICAgKCgobG9uZyliNiAmIDB4ZmYpIDw8IDQwKSB8CisgICAgICAgICAgICgoKGxvbmcpYjcgJiAweGZmKSA8PCA0OCkgfAorICAgICAgICAgICAoKChsb25nKWI4ICYgMHhmZikgPDwgNTYpOworICB9CisKKyAgLyoqCisgICAqIERlY29kZSBhIFppZ1phZy1lbmNvZGVkIDMyLWJpdCB2YWx1ZS4gIFppZ1phZyBlbmNvZGVzIHNpZ25lZCBpbnRlZ2VycworICAgKiBpbnRvIHZhbHVlcyB0aGF0IGNhbiBiZSBlZmZpY2llbnRseSBlbmNvZGVkIHdpdGggdmFyaW50LiAgKE90aGVyd2lzZSwKKyAgICogbmVnYXRpdmUgdmFsdWVzIG11c3QgYmUgc2lnbi1leHRlbmRlZCB0byA2NCBiaXRzIHRvIGJlIHZhcmludCBlbmNvZGVkLAorICAgKiB0aHVzIGFsd2F5cyB0YWtpbmcgMTAgYnl0ZXMgb24gdGhlIHdpcmUuKQorICAgKgorICAgKiBAcGFyYW0gbiBBbiB1bnNpZ25lZCAzMi1iaXQgaW50ZWdlciwgc3RvcmVkIGluIGEgc2lnbmVkIGludCBiZWNhdXNlCisgICAqICAgICAgICAgIEphdmEgaGFzIG5vIGV4cGxpY2l0IHVuc2lnbmVkIHN1cHBvcnQuCisgICAqIEByZXR1cm4gQSBzaWduZWQgMzItYml0IGludGVnZXIuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBkZWNvZGVaaWdaYWczMihmaW5hbCBpbnQgbikgeworICAgIHJldHVybiAobiA+Pj4gMSkgXiAtKG4gJiAxKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWNvZGUgYSBaaWdaYWctZW5jb2RlZCA2NC1iaXQgdmFsdWUuICBaaWdaYWcgZW5jb2RlcyBzaWduZWQgaW50ZWdlcnMKKyAgICogaW50byB2YWx1ZXMgdGhhdCBjYW4gYmUgZWZmaWNpZW50bHkgZW5jb2RlZCB3aXRoIHZhcmludC4gIChPdGhlcndpc2UsCisgICAqIG5lZ2F0aXZlIHZhbHVlcyBtdXN0IGJlIHNpZ24tZXh0ZW5kZWQgdG8gNjQgYml0cyB0byBiZSB2YXJpbnQgZW5jb2RlZCwKKyAgICogdGh1cyBhbHdheXMgdGFraW5nIDEwIGJ5dGVzIG9uIHRoZSB3aXJlLikKKyAgICoKKyAgICogQHBhcmFtIG4gQW4gdW5zaWduZWQgNjQtYml0IGludGVnZXIsIHN0b3JlZCBpbiBhIHNpZ25lZCBpbnQgYmVjYXVzZQorICAgKiAgICAgICAgICBKYXZhIGhhcyBubyBleHBsaWNpdCB1bnNpZ25lZCBzdXBwb3J0LgorICAgKiBAcmV0dXJuIEEgc2lnbmVkIDY0LWJpdCBpbnRlZ2VyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGRlY29kZVppZ1phZzY0KGZpbmFsIGxvbmcgbikgeworICAgIHJldHVybiAobiA+Pj4gMSkgXiAtKG4gJiAxKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmZmVyOworICBwcml2YXRlIGludCBidWZmZXJTdGFydDsKKyAgcHJpdmF0ZSBpbnQgYnVmZmVyU2l6ZTsKKyAgcHJpdmF0ZSBpbnQgYnVmZmVyU2l6ZUFmdGVyTGltaXQ7CisgIHByaXZhdGUgaW50IGJ1ZmZlclBvczsKKyAgcHJpdmF0ZSBpbnQgbGFzdFRhZzsKKworICAvKiogVGhlIGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgbWVzc2FnZS4gKi8KKyAgcHJpdmF0ZSBpbnQgY3VycmVudExpbWl0ID0gSW50ZWdlci5NQVhfVkFMVUU7CisKKyAgLyoqIFNlZSBzZXRSZWN1cnNpb25MaW1pdCgpICovCisgIHByaXZhdGUgaW50IHJlY3Vyc2lvbkRlcHRoOworICBwcml2YXRlIGludCByZWN1cnNpb25MaW1pdCA9IERFRkFVTFRfUkVDVVJTSU9OX0xJTUlUOworCisgIC8qKiBTZWUgc2V0U2l6ZUxpbWl0KCkgKi8KKyAgcHJpdmF0ZSBpbnQgc2l6ZUxpbWl0ID0gREVGQVVMVF9TSVpFX0xJTUlUOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1JFQ1VSU0lPTl9MSU1JVCA9IDY0OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TSVpFX0xJTUlUID0gNjQgPDwgMjA7ICAvLyA2NE1CCisKKyAgcHJpdmF0ZSBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8oZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgeworICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyOworICAgIGJ1ZmZlclN0YXJ0ID0gb2ZmOworICAgIGJ1ZmZlclNpemUgPSBvZmYgKyBsZW47CisgICAgYnVmZmVyUG9zID0gb2ZmOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgbWF4aW11bSBtZXNzYWdlIHJlY3Vyc2lvbiBkZXB0aC4gIEluIG9yZGVyIHRvIHByZXZlbnQgbWFsaWNpb3VzCisgICAqIG1lc3NhZ2VzIGZyb20gY2F1c2luZyBzdGFjayBvdmVyZmxvd3MsIHtAY29kZSBDb2RlZElucHV0U3RyZWFtfSBsaW1pdHMKKyAgICogaG93IGRlZXBseSBtZXNzYWdlcyBtYXkgYmUgbmVzdGVkLiAgVGhlIGRlZmF1bHQgbGltaXQgaXMgNjQuCisgICAqCisgICAqIEByZXR1cm4gdGhlIG9sZCBsaW1pdC4KKyAgICovCisgIHB1YmxpYyBpbnQgc2V0UmVjdXJzaW9uTGltaXQoZmluYWwgaW50IGxpbWl0KSB7CisgICAgaWYgKGxpbWl0IDwgMCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgIlJlY3Vyc2lvbiBsaW1pdCBjYW5ub3QgYmUgbmVnYXRpdmU6ICIgKyBsaW1pdCk7CisgICAgfQorICAgIGZpbmFsIGludCBvbGRMaW1pdCA9IHJlY3Vyc2lvbkxpbWl0OworICAgIHJlY3Vyc2lvbkxpbWl0ID0gbGltaXQ7CisgICAgcmV0dXJuIG9sZExpbWl0OworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgbWF4aW11bSBtZXNzYWdlIHNpemUuICBJbiBvcmRlciB0byBwcmV2ZW50IG1hbGljaW91cworICAgKiBtZXNzYWdlcyBmcm9tIGV4aGF1c3RpbmcgbWVtb3J5IG9yIGNhdXNpbmcgaW50ZWdlciBvdmVyZmxvd3MsCisgICAqIHtAY29kZSBDb2RlZElucHV0U3RyZWFtfSBsaW1pdHMgaG93IGxhcmdlIGEgbWVzc2FnZSBtYXkgYmUuCisgICAqIFRoZSBkZWZhdWx0IGxpbWl0IGlzIDY0TUIuICBZb3Ugc2hvdWxkIHNldCB0aGlzIGxpbWl0IGFzIHNtYWxsCisgICAqIGFzIHlvdSBjYW4gd2l0aG91dCBoYXJtaW5nIHlvdXIgYXBwJ3MgZnVuY3Rpb25hbGl0eS4gIE5vdGUgdGhhdAorICAgKiBzaXplIGxpbWl0cyBvbmx5IGFwcGx5IHdoZW4gcmVhZGluZyBmcm9tIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0sIG5vdAorICAgKiB3aGVuIGNvbnN0cnVjdGVkIGFyb3VuZCBhIHJhdyBieXRlIGFycmF5LgorICAgKiA8cD4KKyAgICogSWYgeW91IHdhbnQgdG8gcmVhZCBzZXZlcmFsIG1lc3NhZ2VzIGZyb20gYSBzaW5nbGUgQ29kZWRJbnB1dFN0cmVhbSwgeW91CisgICAqIGNvdWxkIGNhbGwge0BsaW5rICNyZXNldFNpemVDb3VudGVyKCl9IGFmdGVyIGVhY2ggb25lIHRvIGF2b2lkIGhpdHRpbmcgdGhlCisgICAqIHNpemUgbGltaXQuCisgICAqCisgICAqIEByZXR1cm4gdGhlIG9sZCBsaW1pdC4KKyAgICovCisgIHB1YmxpYyBpbnQgc2V0U2l6ZUxpbWl0KGZpbmFsIGludCBsaW1pdCkgeworICAgIGlmIChsaW1pdCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJTaXplIGxpbWl0IGNhbm5vdCBiZSBuZWdhdGl2ZTogIiArIGxpbWl0KTsKKyAgICB9CisgICAgZmluYWwgaW50IG9sZExpbWl0ID0gc2l6ZUxpbWl0OworICAgIHNpemVMaW1pdCA9IGxpbWl0OworICAgIHJldHVybiBvbGRMaW1pdDsKKyAgfQorCisgIC8qKgorICAgKiBSZXNldHMgdGhlIGN1cnJlbnQgc2l6ZSBjb3VudGVyIHRvIHplcm8gKHNlZSB7QGxpbmsgI3NldFNpemVMaW1pdChpbnQpfSkuCisgICAqLworICBwdWJsaWMgdm9pZCByZXNldFNpemVDb3VudGVyKCkgeworICB9CisKKyAgLyoqCisgICAqIFNldHMge0Bjb2RlIGN1cnJlbnRMaW1pdH0gdG8gKGN1cnJlbnQgcG9zaXRpb24pICsge0Bjb2RlIGJ5dGVMaW1pdH0uICBUaGlzCisgICAqIGlzIGNhbGxlZCB3aGVuIGRlc2NlbmRpbmcgaW50byBhIGxlbmd0aC1kZWxpbWl0ZWQgZW1iZWRkZWQgbWVzc2FnZS4KKyAgICoKKyAgICogQHJldHVybiB0aGUgb2xkIGxpbWl0LgorICAgKi8KKyAgcHVibGljIGludCBwdXNoTGltaXQoaW50IGJ5dGVMaW1pdCkgdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24geworICAgIGlmIChieXRlTGltaXQgPCAwKSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLm5lZ2F0aXZlU2l6ZSgpOworICAgIH0KKyAgICBieXRlTGltaXQgKz0gYnVmZmVyUG9zOworICAgIGZpbmFsIGludCBvbGRMaW1pdCA9IGN1cnJlbnRMaW1pdDsKKyAgICBpZiAoYnl0ZUxpbWl0ID4gb2xkTGltaXQpIHsKKyAgICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24udHJ1bmNhdGVkTWVzc2FnZSgpOworICAgIH0KKyAgICBjdXJyZW50TGltaXQgPSBieXRlTGltaXQ7CisKKyAgICByZWNvbXB1dGVCdWZmZXJTaXplQWZ0ZXJMaW1pdCgpOworCisgICAgcmV0dXJuIG9sZExpbWl0OworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlY29tcHV0ZUJ1ZmZlclNpemVBZnRlckxpbWl0KCkgeworICAgIGJ1ZmZlclNpemUgKz0gYnVmZmVyU2l6ZUFmdGVyTGltaXQ7CisgICAgZmluYWwgaW50IGJ1ZmZlckVuZCA9IGJ1ZmZlclNpemU7CisgICAgaWYgKGJ1ZmZlckVuZCA+IGN1cnJlbnRMaW1pdCkgeworICAgICAgLy8gTGltaXQgaXMgaW4gY3VycmVudCBidWZmZXIuCisgICAgICBidWZmZXJTaXplQWZ0ZXJMaW1pdCA9IGJ1ZmZlckVuZCAtIGN1cnJlbnRMaW1pdDsKKyAgICAgIGJ1ZmZlclNpemUgLT0gYnVmZmVyU2l6ZUFmdGVyTGltaXQ7CisgICAgfSBlbHNlIHsKKyAgICAgIGJ1ZmZlclNpemVBZnRlckxpbWl0ID0gMDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRGlzY2FyZHMgdGhlIGN1cnJlbnQgbGltaXQsIHJldHVybmluZyB0byB0aGUgcHJldmlvdXMgbGltaXQuCisgICAqCisgICAqIEBwYXJhbSBvbGRMaW1pdCBUaGUgb2xkIGxpbWl0LCBhcyByZXR1cm5lZCBieSB7QGNvZGUgcHVzaExpbWl0fS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHBvcExpbWl0KGZpbmFsIGludCBvbGRMaW1pdCkgeworICAgIGN1cnJlbnRMaW1pdCA9IG9sZExpbWl0OworICAgIHJlY29tcHV0ZUJ1ZmZlclNpemVBZnRlckxpbWl0KCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHJlYWQgYmVmb3JlIHRoZSBjdXJyZW50IGxpbWl0LgorICAgKiBJZiBubyBsaW1pdCBpcyBzZXQsIHJldHVybnMgLTEuCisgICAqLworICBwdWJsaWMgaW50IGdldEJ5dGVzVW50aWxMaW1pdCgpIHsKKyAgICBpZiAoY3VycmVudExpbWl0ID09IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgZmluYWwgaW50IGN1cnJlbnRBYnNvbHV0ZVBvc2l0aW9uID0gYnVmZmVyUG9zOworICAgIHJldHVybiBjdXJyZW50TGltaXQgLSBjdXJyZW50QWJzb2x1dGVQb3NpdGlvbjsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmVhbSBoYXMgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBpbnB1dC4gIFRoaXMgaXMgdGhlCisgICAqIGNhc2UgaWYgZWl0aGVyIHRoZSBlbmQgb2YgdGhlIHVuZGVybHlpbmcgaW5wdXQgc291cmNlIGhhcyBiZWVuIHJlYWNoZWQgb3IKKyAgICogaWYgdGhlIHN0cmVhbSBoYXMgcmVhY2hlZCBhIGxpbWl0IGNyZWF0ZWQgdXNpbmcge0BsaW5rICNwdXNoTGltaXQoaW50KX0uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0F0RW5kKCkgeworICAgIHJldHVybiBidWZmZXJQb3MgPT0gYnVmZmVyU2l6ZTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgY3VycmVudCBwb3NpdGlvbiBpbiBidWZmZXIgcmVsYXRpdmUgdG8gYmVnaW5uaW5nIG9mZnNldC4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7CisgICAgcmV0dXJuIGJ1ZmZlclBvcyAtIGJ1ZmZlclN0YXJ0OworICB9CisKKyAgLyoqCisgICAqIFJldHJpZXZlcyBhIHN1YnNldCBvZiBkYXRhIGluIHRoZSBidWZmZXIuIFRoZSByZXR1cm5lZCBhcnJheSBpcyBub3QgYmFja2VkIGJ5IHRoZSBvcmlnaW5hbAorICAgKiBidWZmZXIgYXJyYXkuCisgICAqCisgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHBvc2l0aW9uIChyZWxhdGl2ZSB0byB0aGUgYnVmZmVyIHN0YXJ0IHBvc2l0aW9uKSB0byBzdGFydCBhdC4KKyAgICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJldHJpZXZlLgorICAgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXREYXRhKGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgIHJldHVybiBXaXJlRm9ybWF0TmFuby5FTVBUWV9CWVRFUzsKKyAgICB9CisgICAgYnl0ZVtdIGNvcHkgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgIGludCBzdGFydCA9IGJ1ZmZlclN0YXJ0ICsgb2Zmc2V0OworICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBzdGFydCwgY29weSwgMCwgbGVuZ3RoKTsKKyAgICByZXR1cm4gY29weTsKKyAgfQorCisgIC8qKgorICAgKiBSZXdpbmQgdG8gcHJldmlvdXMgcG9zaXRpb24uIENhbm5vdCBnbyBmb3J3YXJkLgorICAgKi8KKyAgcHVibGljIHZvaWQgcmV3aW5kVG9Qb3NpdGlvbihpbnQgcG9zaXRpb24pIHsKKyAgICBpZiAocG9zaXRpb24gPiBidWZmZXJQb3MgLSBidWZmZXJTdGFydCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIlBvc2l0aW9uICIgKyBwb3NpdGlvbiArICIgaXMgYmV5b25kIGN1cnJlbnQgIiArIChidWZmZXJQb3MgLSBidWZmZXJTdGFydCkpOworICAgIH0KKyAgICBpZiAocG9zaXRpb24gPCAwKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgcG9zaXRpb24gIiArIHBvc2l0aW9uKTsKKyAgICB9CisgICAgYnVmZmVyUG9zID0gYnVmZmVyU3RhcnQgKyBwb3NpdGlvbjsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkIG9uZSBieXRlIGZyb20gdGhlIGlucHV0LgorICAgKgorICAgKiBAdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24gVGhlIGVuZCBvZiB0aGUgc3RyZWFtIG9yIHRoZSBjdXJyZW50CisgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0IHdhcyByZWFjaGVkLgorICAgKi8KKyAgcHVibGljIGJ5dGUgcmVhZFJhd0J5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChidWZmZXJQb3MgPT0gYnVmZmVyU2l6ZSkgeworICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi50cnVuY2F0ZWRNZXNzYWdlKCk7CisgICAgfQorICAgIHJldHVybiBidWZmZXJbYnVmZmVyUG9zKytdOworICB9CisKKyAgLyoqCisgICAqIFJlYWQgYSBmaXhlZCBzaXplIG9mIGJ5dGVzIGZyb20gdGhlIGlucHV0LgorICAgKgorICAgKiBAdGhyb3dzIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24gVGhlIGVuZCBvZiB0aGUgc3RyZWFtIG9yIHRoZSBjdXJyZW50CisgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0IHdhcyByZWFjaGVkLgorICAgKi8KKyAgcHVibGljIGJ5dGVbXSByZWFkUmF3Qnl0ZXMoZmluYWwgaW50IHNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLm5lZ2F0aXZlU2l6ZSgpOworICAgIH0KKworICAgIGlmIChidWZmZXJQb3MgKyBzaXplID4gY3VycmVudExpbWl0KSB7CisgICAgICAvLyBSZWFkIHRvIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBhbnl3YXkuCisgICAgICBza2lwUmF3Qnl0ZXMoY3VycmVudExpbWl0IC0gYnVmZmVyUG9zKTsKKyAgICAgIC8vIFRoZW4gZmFpbC4KKyAgICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24udHJ1bmNhdGVkTWVzc2FnZSgpOworICAgIH0KKworICAgIGlmIChzaXplIDw9IGJ1ZmZlclNpemUgLSBidWZmZXJQb3MpIHsKKyAgICAgIC8vIFdlIGhhdmUgYWxsIHRoZSBieXRlcyB3ZSBuZWVkIGFscmVhZHkuCisgICAgICBmaW5hbCBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBidWZmZXJQb3MsIGJ5dGVzLCAwLCBzaXplKTsKKyAgICAgIGJ1ZmZlclBvcyArPSBzaXplOworICAgICAgcmV0dXJuIGJ5dGVzOworICAgIH0gZWxzZSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLnRydW5jYXRlZE1lc3NhZ2UoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmVhZHMgYW5kIGRpc2NhcmRzIHtAY29kZSBzaXplfSBieXRlcy4KKyAgICoKKyAgICogQHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uIFRoZSBlbmQgb2YgdGhlIHN0cmVhbSBvciB0aGUgY3VycmVudAorICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCB3YXMgcmVhY2hlZC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNraXBSYXdCeXRlcyhmaW5hbCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc2l6ZSA8IDApIHsKKyAgICAgIHRocm93IEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24ubmVnYXRpdmVTaXplKCk7CisgICAgfQorCisgICAgaWYgKGJ1ZmZlclBvcyArIHNpemUgPiBjdXJyZW50TGltaXQpIHsKKyAgICAgIC8vIFJlYWQgdG8gdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGFueXdheS4KKyAgICAgIHNraXBSYXdCeXRlcyhjdXJyZW50TGltaXQgLSBidWZmZXJQb3MpOworICAgICAgLy8gVGhlbiBmYWlsLgorICAgICAgdGhyb3cgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbi50cnVuY2F0ZWRNZXNzYWdlKCk7CisgICAgfQorCisgICAgaWYgKHNpemUgPD0gYnVmZmVyU2l6ZSAtIGJ1ZmZlclBvcykgeworICAgICAgLy8gV2UgaGF2ZSBhbGwgdGhlIGJ5dGVzIHdlIG5lZWQgYWxyZWFkeS4KKyAgICAgIGJ1ZmZlclBvcyArPSBzaXplOworICAgIH0gZWxzZSB7CisgICAgICB0aHJvdyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLnRydW5jYXRlZE1lc3NhZ2UoKTsKKyAgICB9CisgIH0KKworICAvLyBSZWFkIGEgcHJpbWl0aXZlIHR5cGUuCisgIE9iamVjdCByZWFkUHJpbWl0aXZlRmllbGQoaW50IHR5cGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0RPVUJMRToKKyAgICAgICAgICByZXR1cm4gcmVhZERvdWJsZSgpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9GTE9BVDoKKyAgICAgICAgICByZXR1cm4gcmVhZEZsb2F0KCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0lOVDY0OgorICAgICAgICAgIHJldHVybiByZWFkSW50NjQoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfVUlOVDY0OgorICAgICAgICAgIHJldHVybiByZWFkVUludDY0KCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0lOVDMyOgorICAgICAgICAgIHJldHVybiByZWFkSW50MzIoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfRklYRUQ2NDoKKyAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfRklYRUQzMjoKKyAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkMzIoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfQk9PTDoKKyAgICAgICAgICByZXR1cm4gcmVhZEJvb2woKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfU1RSSU5HOgorICAgICAgICAgIHJldHVybiByZWFkU3RyaW5nKCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0JZVEVTOgorICAgICAgICAgIHJldHVybiByZWFkQnl0ZXMoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfVUlOVDMyOgorICAgICAgICAgIHJldHVybiByZWFkVUludDMyKCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0VOVU06CisgICAgICAgICAgcmV0dXJuIHJlYWRFbnVtKCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NGSVhFRDMyOgorICAgICAgICAgIHJldHVybiByZWFkU0ZpeGVkMzIoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfU0ZJWEVENjQ6CisgICAgICAgICAgcmV0dXJuIHJlYWRTRml4ZWQ2NCgpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9TSU5UMzI6CisgICAgICAgICAgcmV0dXJuIHJlYWRTSW50MzIoKTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfU0lOVDY0OgorICAgICAgICAgIHJldHVybiByZWFkU0ludDY0KCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24gdHlwZSAiICsgdHlwZSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjc3N2YzNAotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0NvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uamF2YQpAQCAtMCwwICsxLDEwMDMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTMgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworCisvKioKKyAqIEVuY29kZXMgYW5kIHdyaXRlcyBwcm90b2NvbCBtZXNzYWdlIGZpZWxkcy4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGNvbnRhaW5zIHR3byBraW5kcyBvZiBtZXRob2RzOiAgbWV0aG9kcyB0aGF0IHdyaXRlIHNwZWNpZmljCisgKiBwcm90b2NvbCBtZXNzYWdlIGNvbnN0cnVjdHMgYW5kIGZpZWxkIHR5cGVzIChlLmcuIHtAbGluayAjd3JpdGVUYWd9IGFuZAorICoge0BsaW5rICN3cml0ZUludDMyfSkgYW5kIG1ldGhvZHMgdGhhdCB3cml0ZSBsb3ctbGV2ZWwgdmFsdWVzIChlLmcuCisgKiB7QGxpbmsgI3dyaXRlUmF3VmFyaW50MzJ9IGFuZCB7QGxpbmsgI3dyaXRlUmF3Qnl0ZXN9KS4gIElmIHlvdSBhcmUKKyAqIHdyaXRpbmcgZW5jb2RlZCBwcm90b2NvbCBtZXNzYWdlcywgeW91IHNob3VsZCB1c2UgdGhlIGZvcm1lciBtZXRob2RzLCBidXQgaWYKKyAqIHlvdSBhcmUgd3JpdGluZyBzb21lIG90aGVyIGZvcm1hdCBvZiB5b3VyIG93biBkZXNpZ24sIHVzZSB0aGUgbGF0dGVyLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgdG90YWxseSB1bnN5bmNocm9uaXplZC4KKyAqCisgKiBAYXV0aG9yIGtuZXRvbkBnb29nbGUuY29tIEtlbnRvbiBWYXJkYQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyB7CisgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGJ1ZmZlcjsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgbGltaXQ7CisgIHByaXZhdGUgaW50IHBvc2l0aW9uOworCisgIHByaXZhdGUgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyhmaW5hbCBieXRlW10gYnVmZmVyLCBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjsKKyAgICBwb3NpdGlvbiA9IG9mZnNldDsKKyAgICBsaW1pdCA9IG9mZnNldCArIGxlbmd0aDsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIENvZGVkT3V0cHV0U3RyZWFtfSB0aGF0IHdyaXRlcyBkaXJlY3RseSB0byB0aGUgZ2l2ZW4KKyAgICogYnl0ZSBhcnJheS4gIElmIG1vcmUgYnl0ZXMgYXJlIHdyaXR0ZW4gdGhhbiBmaXQgaW4gdGhlIGFycmF5LAorICAgKiB7QGxpbmsgT3V0T2ZTcGFjZUV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24uICBXcml0aW5nIGRpcmVjdGx5IHRvIGEgZmxhdAorICAgKiBhcnJheSBpcyBmYXN0ZXIgdGhhbiB3cml0aW5nIHRvIGFuIHtAY29kZSBPdXRwdXRTdHJlYW19LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vIG5ld0luc3RhbmNlKGZpbmFsIGJ5dGVbXSBmbGF0QXJyYXkpIHsKKyAgICByZXR1cm4gbmV3SW5zdGFuY2UoZmxhdEFycmF5LCAwLCBmbGF0QXJyYXkubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIENvZGVkT3V0cHV0U3RyZWFtfSB0aGF0IHdyaXRlcyBkaXJlY3RseSB0byB0aGUgZ2l2ZW4KKyAgICogYnl0ZSBhcnJheSBzbGljZS4gIElmIG1vcmUgYnl0ZXMgYXJlIHdyaXR0ZW4gdGhhbiBmaXQgaW4gdGhlIHNsaWNlLAorICAgKiB7QGxpbmsgT3V0T2ZTcGFjZUV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24uICBXcml0aW5nIGRpcmVjdGx5IHRvIGEgZmxhdAorICAgKiBhcnJheSBpcyBmYXN0ZXIgdGhhbiB3cml0aW5nIHRvIGFuIHtAY29kZSBPdXRwdXRTdHJlYW19LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vIG5ld0luc3RhbmNlKGZpbmFsIGJ5dGVbXSBmbGF0QXJyYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgcmV0dXJuIG5ldyBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vKGZsYXRBcnJheSwgb2Zmc2V0LCBsZW5ndGgpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZG91YmxlfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVEb3VibGUoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBkb3VibGUgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0ZJWEVENjQpOworICAgIHdyaXRlRG91YmxlTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGZsb2F0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGbG9hdChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGZsb2F0IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0ZJWEVEMzIpOworICAgIHdyaXRlRmxvYXROb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgdWludDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVVSW50NjQoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBsb25nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9WQVJJTlQpOworICAgIHdyaXRlVUludDY0Tm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBpbnQ2NH0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlSW50NjQoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBsb25nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX1ZBUklOVCk7CisgICAgd3JpdGVJbnQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgaW50MzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUludDMyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX1ZBUklOVCk7CisgICAgd3JpdGVJbnQzMk5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBmaXhlZDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGaXhlZDY0KGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgbG9uZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0ZJWEVENjQpOworICAgIHdyaXRlRml4ZWQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBmaXhlZDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGaXhlZDMyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfRklYRUQzMik7CisgICAgd3JpdGVGaXhlZDMyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGJvb2x9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUJvb2woZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBib29sZWFuIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfVkFSSU5UKTsKKyAgICB3cml0ZUJvb2xOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgc3RyaW5nfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTdHJpbmcoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBTdHJpbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgIHdyaXRlU3RyaW5nTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGdyb3VwfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVHcm91cChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIE1lc3NhZ2VOYW5vIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX1NUQVJUX0dST1VQKTsKKyAgICB3cml0ZUdyb3VwTm9UYWcodmFsdWUpOworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9FTkRfR1JPVVApOworICB9CisKKyAgLyoqIFdyaXRlIGFuIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlTWVzc2FnZShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIE1lc3NhZ2VOYW5vIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgd3JpdGVNZXNzYWdlTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIGJ5dGVzfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVCeXRlcyhmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGJ5dGVbXSB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICB3cml0ZUJ5dGVzTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGEge0Bjb2RlIHVpbnQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVUludDMyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9WQVJJTlQpOworICAgIHdyaXRlVUludDMyTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlIGFuIGVudW0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICBDYWxsZXIgaXMgcmVzcG9uc2libGUKKyAgICogZm9yIGNvbnZlcnRpbmcgdGhlIGVudW0gdmFsdWUgdG8gaXRzIG51bWVyaWMgdmFsdWUuCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZUVudW0oZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBpbnQgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9WQVJJTlQpOworICAgIHdyaXRlRW51bU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgc2ZpeGVkMzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVNGaXhlZDMyKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0ZJWEVEMzIpOworICAgIHdyaXRlU0ZpeGVkMzJOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIHNmaXhlZDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTRml4ZWQ2NChmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGxvbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfRklYRUQ2NCk7CisgICAgd3JpdGVTRml4ZWQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgc2ludDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTSW50MzIoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBpbnQgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVUYWcoZmllbGROdW1iZXIsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX1ZBUklOVCk7CisgICAgd3JpdGVTSW50MzJOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIHNpbnQ2NH0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlU0ludDY0KGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgbG9uZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVRhZyhmaWVsZE51bWJlciwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfVkFSSU5UKTsKKyAgICB3cml0ZVNJbnQ2NE5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBGb3IgaGlzdG9yaWNhbCByZWFzb25zLAorICAgKiB0aGUgd2lyZSBmb3JtYXQgZGlmZmVycyBmcm9tIG5vcm1hbCBmaWVsZHMuCisgICAqLworLy8gIHB1YmxpYyB2b2lkIHdyaXRlTWVzc2FnZVNldEV4dGVuc2lvbihmaW5hbCBpbnQgZmllbGROdW1iZXIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VNaWNybyB2YWx1ZSkKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKy8vICAgIHdyaXRlVGFnKFdpcmVGb3JtYXRNaWNyby5NRVNTQUdFX1NFVF9JVEVNLCBXaXJlRm9ybWF0TWljcm8uV0lSRVRZUEVfU1RBUlRfR1JPVVApOworLy8gICAgd3JpdGVVSW50MzIoV2lyZUZvcm1hdE1pY3JvLk1FU1NBR0VfU0VUX1RZUEVfSUQsIGZpZWxkTnVtYmVyKTsKKy8vICAgIHdyaXRlTWVzc2FnZShXaXJlRm9ybWF0TWljcm8uTUVTU0FHRV9TRVRfTUVTU0FHRSwgdmFsdWUpOworLy8gICAgd3JpdGVUYWcoV2lyZUZvcm1hdE1pY3JvLk1FU1NBR0VfU0VUX0lURU0sIFdpcmVGb3JtYXRNaWNyby5XSVJFVFlQRV9FTkRfR1JPVVApOworLy8gIH0KKworICAvKioKKyAgICogV3JpdGUgYW4gdW5wYXJzZWQgTWVzc2FnZVNldCBleHRlbnNpb24gZmllbGQgdG8gdGhlIHN0cmVhbS4gIEZvcgorICAgKiBoaXN0b3JpY2FsIHJlYXNvbnMsIHRoZSB3aXJlIGZvcm1hdCBkaWZmZXJzIGZyb20gbm9ybWFsIGZpZWxkcy4KKyAgICovCisvLyAgcHVibGljIHZvaWQgd3JpdGVSYXdNZXNzYWdlU2V0RXh0ZW5zaW9uKGZpbmFsIGludCBmaWVsZE51bWJlciwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQnl0ZVN0cmluZ01pY3JvIHZhbHVlKQorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworLy8gICAgd3JpdGVUYWcoV2lyZUZvcm1hdE1pY3JvLk1FU1NBR0VfU0VUX0lURU0sIFdpcmVGb3JtYXRNaWNyby5XSVJFVFlQRV9TVEFSVF9HUk9VUCk7CisvLyAgICB3cml0ZVVJbnQzMihXaXJlRm9ybWF0TWljcm8uTUVTU0FHRV9TRVRfVFlQRV9JRCwgZmllbGROdW1iZXIpOworLy8gICAgd3JpdGVCeXRlcyhXaXJlRm9ybWF0TWljcm8uTUVTU0FHRV9TRVRfTUVTU0FHRSwgdmFsdWUpOworLy8gICAgd3JpdGVUYWcoV2lyZUZvcm1hdE1pY3JvLk1FU1NBR0VfU0VUX0lURU0sIFdpcmVGb3JtYXRNaWNyby5XSVJFVFlQRV9FTkRfR1JPVVApOworLy8gIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBkb3VibGV9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlRG91YmxlTm9UYWcoZmluYWwgZG91YmxlIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3TGl0dGxlRW5kaWFuNjQoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsdWUpKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBmbG9hdH0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGbG9hdE5vVGFnKGZpbmFsIGZsb2F0IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3TGl0dGxlRW5kaWFuMzIoRmxvYXQuZmxvYXRUb0ludEJpdHModmFsdWUpKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSB1aW50NjR9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVUludDY0Tm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd1ZhcmludDY0KHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhbiB7QGNvZGUgaW50NjR9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlSW50NjROb1RhZyhmaW5hbCBsb25nIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3VmFyaW50NjQodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBpbnQzMn0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVJbnQzMk5vVGFnKGZpbmFsIGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodmFsdWUgPj0gMCkgeworICAgICAgd3JpdGVSYXdWYXJpbnQzMih2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE11c3Qgc2lnbi1leHRlbmQuCisgICAgICB3cml0ZVJhd1ZhcmludDY0KHZhbHVlKTsKKyAgICB9CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgZml4ZWQ2NH0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVGaXhlZDY0Tm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0xpdHRsZUVuZGlhbjY0KHZhbHVlKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBmaXhlZDMyfSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZUZpeGVkMzJOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdMaXR0bGVFbmRpYW4zMih2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgYm9vbH0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVCb29sTm9UYWcoZmluYWwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0J5dGUodmFsdWUgPyAxIDogMCk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgc3RyaW5nfSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVN0cmluZ05vVGFnKGZpbmFsIFN0cmluZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGRvZXMgbm90IGFwcGVhciB0byBiZSBhbnkgd2F5IHRvIHRlbGwgSmF2YSB0byBlbmNvZGUKKyAgICAvLyBVVEYtOCBkaXJlY3RseSBpbnRvIG91ciBidWZmZXIsIHNvIHdlIGhhdmUgdG8gbGV0IGl0IGNyZWF0ZSBpdHMgb3duIGJ5dGUKKyAgICAvLyBhcnJheSBhbmQgdGhlbiBjb3B5LgorICAgIGZpbmFsIGJ5dGVbXSBieXRlcyA9IHZhbHVlLmdldEJ5dGVzKCJVVEYtOCIpOworICAgIHdyaXRlUmF3VmFyaW50MzIoYnl0ZXMubGVuZ3RoKTsKKyAgICB3cml0ZVJhd0J5dGVzKGJ5dGVzKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBncm91cH0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVHcm91cE5vVGFnKGZpbmFsIE1lc3NhZ2VOYW5vIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHZhbHVlLndyaXRlVG8odGhpcyk7CisgIH0KKworICAvKiogV3JpdGUgYW4gZW1iZWRkZWQgbWVzc2FnZSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZU1lc3NhZ2VOb1RhZyhmaW5hbCBNZXNzYWdlTmFubyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd1ZhcmludDMyKHZhbHVlLmdldENhY2hlZFNpemUoKSk7CisgICAgdmFsdWUud3JpdGVUbyh0aGlzKTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHtAY29kZSBieXRlc30gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVCeXRlc05vVGFnKGZpbmFsIGJ5dGVbXSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd1ZhcmludDMyKHZhbHVlLmxlbmd0aCk7CisgICAgd3JpdGVSYXdCeXRlcyh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYSB7QGNvZGUgdWludDMyfSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVVJbnQzMk5vVGFnKGZpbmFsIGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd1ZhcmludDMyKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhbiBlbnVtIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBDYWxsZXIgaXMgcmVzcG9uc2libGUKKyAgICogZm9yIGNvbnZlcnRpbmcgdGhlIGVudW0gdmFsdWUgdG8gaXRzIG51bWVyaWMgdmFsdWUuCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZUVudW1Ob1RhZyhmaW5hbCBpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQzMih2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIHNmaXhlZDMyfSBmaWVsZCB0byB0aGUgc3RyZWFtLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVNGaXhlZDMyTm9UYWcoZmluYWwgaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3TGl0dGxlRW5kaWFuMzIodmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBzZml4ZWQ2NH0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTRml4ZWQ2NE5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdMaXR0bGVFbmRpYW42NCh2YWx1ZSk7CisgIH0KKworICAvKiogV3JpdGUgYW4ge0Bjb2RlIHNpbnQzMn0gZmllbGQgdG8gdGhlIHN0cmVhbS4gKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTSW50MzJOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVSYXdWYXJpbnQzMihlbmNvZGVaaWdaYWczMih2YWx1ZSkpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIHtAY29kZSBzaW50NjR9IGZpZWxkIHRvIHRoZSBzdHJlYW0uICovCisgIHB1YmxpYyB2b2lkIHdyaXRlU0ludDY0Tm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd1ZhcmludDY0KGVuY29kZVppZ1phZzY0KHZhbHVlKSk7CisgIH0KKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGRvdWJsZX0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRG91YmxlU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGRvdWJsZSB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlRG91YmxlU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGZsb2F0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVGbG9hdFNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBmbG9hdCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlRmxvYXRTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgdWludDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVVSW50NjRTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlVUludDY0U2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBpbnQ2NH0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlSW50NjRTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlSW50NjRTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIGludDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVJbnQzMlNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUludDMyU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGZpeGVkNjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUZpeGVkNjRTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUZpeGVkNjRTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgZml4ZWQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlRml4ZWQzMlNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVGaXhlZDMyU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGJvb2x9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUJvb2xTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICsgY29tcHV0ZUJvb2xTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgc3RyaW5nfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTdHJpbmdTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVTdHJpbmdTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgZ3JvdXB9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUdyb3VwU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVzc2FnZU5hbm8gdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoZmllbGROdW1iZXIpICogMiArIGNvbXB1dGVHcm91cFNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhbgorICAgKiBlbWJlZGRlZCBtZXNzYWdlIGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZU1lc3NhZ2VTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2VOYW5vIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVNZXNzYWdlU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGJ5dGVzfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVCeXRlc1NpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlQnl0ZXNTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgdWludDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVVSW50MzJTaXplKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVVSW50MzJTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICogZW51bSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4gIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgY29udmVydGluZyB0aGUKKyAgICogZW51bSB2YWx1ZSB0byBpdHMgbnVtZXJpYyB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVFbnVtU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlRW51bVNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhbgorICAgKiB7QGNvZGUgc2ZpeGVkMzJ9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVNGaXhlZDMyU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVTRml4ZWQzMlNpemVOb1RhZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhbgorICAgKiB7QGNvZGUgc2ZpeGVkNjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVNGaXhlZDY0U2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlU0ZpeGVkNjRTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNpbnQzMn0gZmllbGQsIGluY2x1ZGluZyB0YWcuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlU0ludDMyU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIsIGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShmaWVsZE51bWJlcikgKyBjb21wdXRlU0ludDMyU2l6ZU5vVGFnKHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBzaW50NjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVNJbnQ2NFNpemUoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVUYWdTaXplKGZpZWxkTnVtYmVyKSArIGNvbXB1dGVTSW50NjRTaXplTm9UYWcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiBNZXNzYWdlU2V0IGV4dGVuc2lvbiB0byB0aGUgc3RyZWFtLiAgRm9yIGhpc3RvcmljYWwgcmVhc29ucywKKyAgICogdGhlIHdpcmUgZm9ybWF0IGRpZmZlcnMgZnJvbSBub3JtYWwgZmllbGRzLgorICAgKi8KKy8vICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlTWVzc2FnZVNldEV4dGVuc2lvblNpemUoCisvLyAgICAgIGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgTWVzc2FnZU1pY3JvIHZhbHVlKSB7CisvLyAgICByZXR1cm4gY29tcHV0ZVRhZ1NpemUoV2lyZUZvcm1hdE1pY3JvLk1FU1NBR0VfU0VUX0lURU0pICogMiArCisvLyAgICAgICAgICAgY29tcHV0ZVVJbnQzMlNpemUoV2lyZUZvcm1hdE1pY3JvLk1FU1NBR0VfU0VUX1RZUEVfSUQsIGZpZWxkTnVtYmVyKSArCisvLyAgICAgICAgICAgY29tcHV0ZU1lc3NhZ2VTaXplKFdpcmVGb3JtYXRNaWNyby5NRVNTQUdFX1NFVF9NRVNTQUdFLCB2YWx1ZSk7CisvLyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHVucGFyc2VkIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uIGZpZWxkIHRvIHRoZSBzdHJlYW0uICBGb3IKKyAgICogaGlzdG9yaWNhbCByZWFzb25zLCB0aGUgd2lyZSBmb3JtYXQgZGlmZmVycyBmcm9tIG5vcm1hbCBmaWVsZHMuCisgICAqLworLy8gIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVSYXdNZXNzYWdlU2V0RXh0ZW5zaW9uU2l6ZSgKKy8vICAgICAgZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBCeXRlU3RyaW5nTWljcm8gdmFsdWUpIHsKKy8vICAgIHJldHVybiBjb21wdXRlVGFnU2l6ZShXaXJlRm9ybWF0TWljcm8uTUVTU0FHRV9TRVRfSVRFTSkgKiAyICsKKy8vICAgICAgICAgICBjb21wdXRlVUludDMyU2l6ZShXaXJlRm9ybWF0TWljcm8uTUVTU0FHRV9TRVRfVFlQRV9JRCwgZmllbGROdW1iZXIpICsKKy8vICAgICAgICAgICBjb21wdXRlQnl0ZXNTaXplKFdpcmVGb3JtYXRNaWNyby5NRVNTQUdFX1NFVF9NRVNTQUdFLCB2YWx1ZSk7CisvLyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgZG91YmxlfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVEb3VibGVTaXplTm9UYWcoZmluYWwgZG91YmxlIHZhbHVlKSB7CisgICAgcmV0dXJuIExJVFRMRV9FTkRJQU5fNjRfU0laRTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGZsb2F0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVGbG9hdFNpemVOb1RhZyhmaW5hbCBmbG9hdCB2YWx1ZSkgeworICAgIHJldHVybiBMSVRUTEVfRU5ESUFOXzMyX1NJWkU7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSB1aW50NjR9IGZpZWxkLCBpbmNsdWRpbmcgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVSYXdWYXJpbnQ2NFNpemUodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIGludDY0fSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVJbnQ2NFNpemVOb1RhZyhmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVSYXdWYXJpbnQ2NFNpemUodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIGludDMyfSBmaWVsZCwgaW5jbHVkaW5nIHRhZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVJbnQzMlNpemVOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICBpZiAodmFsdWUgPj0gMCkgeworICAgICAgcmV0dXJuIGNvbXB1dGVSYXdWYXJpbnQzMlNpemUodmFsdWUpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBNdXN0IHNpZ24tZXh0ZW5kLgorICAgICAgcmV0dXJuIDEwOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGZpeGVkNjR9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUZpeGVkNjRTaXplTm9UYWcoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiBMSVRUTEVfRU5ESUFOXzY0X1NJWkU7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBmaXhlZDMyfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVGaXhlZDMyU2l6ZU5vVGFnKGZpbmFsIGludCB2YWx1ZSkgeworICAgIHJldHVybiBMSVRUTEVfRU5ESUFOXzMyX1NJWkU7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhCisgICAqIHtAY29kZSBib29sfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVCb29sU2l6ZU5vVGFnKGZpbmFsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIHN0cmluZ30gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKGZpbmFsIFN0cmluZyB2YWx1ZSkgeworICAgIHRyeSB7CisgICAgICBmaW5hbCBieXRlW10gYnl0ZXMgPSB2YWx1ZS5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKGJ5dGVzLmxlbmd0aCkgKworICAgICAgICAgICAgIGJ5dGVzLmxlbmd0aDsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVVEYtOCBub3Qgc3VwcG9ydGVkLiIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGdyb3VwfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVHcm91cFNpemVOb1RhZyhmaW5hbCBNZXNzYWdlTmFubyB2YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZS5nZXRTZXJpYWxpemVkU2l6ZSgpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4gZW1iZWRkZWQKKyAgICogbWVzc2FnZSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVNZXNzYWdlU2l6ZU5vVGFnKGZpbmFsIE1lc3NhZ2VOYW5vIHZhbHVlKSB7CisgICAgZmluYWwgaW50IHNpemUgPSB2YWx1ZS5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIHJldHVybiBjb21wdXRlUmF3VmFyaW50MzJTaXplKHNpemUpICsgc2l6ZTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEKKyAgICoge0Bjb2RlIGJ5dGVzfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVCeXRlc1NpemVOb1RhZyhmaW5hbCBieXRlW10gdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZSh2YWx1ZS5sZW5ndGgpICsgdmFsdWUubGVuZ3RoOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYQorICAgKiB7QGNvZGUgdWludDMyfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVVSW50MzJTaXplTm9UYWcoZmluYWwgaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVSYXdWYXJpbnQzMlNpemUodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4gZW51bSBmaWVsZC4KKyAgICogQ2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBjb252ZXJ0aW5nIHRoZSBlbnVtIHZhbHVlIHRvIGl0cyBudW1lcmljIHZhbHVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZUVudW1TaXplTm9UYWcoZmluYWwgaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIGNvbXB1dGVSYXdWYXJpbnQzMlNpemUodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNmaXhlZDMyfSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTRml4ZWQzMlNpemVOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gTElUVExFX0VORElBTl8zMl9TSVpFOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNmaXhlZDY0fSBmaWVsZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVTRml4ZWQ2NFNpemVOb1RhZyhmaW5hbCBsb25nIHZhbHVlKSB7CisgICAgcmV0dXJuIExJVFRMRV9FTkRJQU5fNjRfU0laRTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGFuCisgICAqIHtAY29kZSBzaW50MzJ9IGZpZWxkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShlbmNvZGVaaWdaYWczMih2YWx1ZSkpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYW4KKyAgICoge0Bjb2RlIHNpbnQ2NH0gZmllbGQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlU0ludDY0U2l6ZU5vVGFnKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDY0U2l6ZShlbmNvZGVaaWdaYWc2NCh2YWx1ZSkpOworICB9CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAvKioKKyAgICogSWYgd3JpdGluZyB0byBhIGZsYXQgYXJyYXksIHJldHVybiB0aGUgc3BhY2UgbGVmdCBpbiB0aGUgYXJyYXkuCisgICAqIE90aGVyd2lzZSwgdGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgICAqLworICBwdWJsaWMgaW50IHNwYWNlTGVmdCgpIHsKKyAgICByZXR1cm4gbGltaXQgLSBwb3NpdGlvbjsKKyAgfQorCisgIC8qKgorICAgKiBWZXJpZmllcyB0aGF0IHtAbGluayAjc3BhY2VMZWZ0KCl9IHJldHVybnMgemVyby4gIEl0J3MgY29tbW9uIHRvIGNyZWF0ZQorICAgKiBhIGJ5dGUgYXJyYXkgdGhhdCBpcyBleGFjdGx5IGJpZyBlbm91Z2ggdG8gaG9sZCBhIG1lc3NhZ2UsIHRoZW4gd3JpdGUgdG8KKyAgICogaXQgd2l0aCBhIHtAY29kZSBDb2RlZE91dHB1dFN0cmVhbX0uICBDYWxsaW5nIHtAY29kZSBjaGVja05vU3BhY2VMZWZ0KCl9CisgICAqIGFmdGVyIHdyaXRpbmcgdmVyaWZpZXMgdGhhdCB0aGUgbWVzc2FnZSB3YXMgYWN0dWFsbHkgYXMgYmlnIGFzIGV4cGVjdGVkLAorICAgKiB3aGljaCBjYW4gaGVscCBjYXRjaCBidWdzLgorICAgKi8KKyAgcHVibGljIHZvaWQgY2hlY2tOb1NwYWNlTGVmdCgpIHsKKyAgICBpZiAoc3BhY2VMZWZ0KCkgIT0gMCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgIkRpZCBub3Qgd3JpdGUgYXMgbXVjaCBkYXRhIGFzIGV4cGVjdGVkLiIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBJZiB5b3UgY3JlYXRlIGEgQ29kZWRPdXRwdXRTdHJlYW0gYXJvdW5kIGEgc2ltcGxlIGZsYXQgYXJyYXksIHlvdSBtdXN0CisgICAqIG5vdCBhdHRlbXB0IHRvIHdyaXRlIG1vcmUgYnl0ZXMgdGhhbiB0aGUgYXJyYXkgaGFzIHNwYWNlLiAgT3RoZXJ3aXNlLAorICAgKiB0aGlzIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgT3V0T2ZTcGFjZUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjk0NzQ4Njg4Njk5Nzg4OTQ5OUw7CisKKyAgICBPdXRPZlNwYWNlRXhjZXB0aW9uKGludCBwb3NpdGlvbiwgaW50IGxpbWl0KSB7CisgICAgICBzdXBlcigiQ29kZWRPdXRwdXRTdHJlYW0gd2FzIHdyaXRpbmcgdG8gYSBmbGF0IGJ5dGUgYXJyYXkgYW5kIHJhbiAiICsKKyAgICAgICAgICAgICJvdXQgb2Ygc3BhY2UgKHBvcyAiICsgcG9zaXRpb24gKyAiIGxpbWl0ICIgKyBsaW1pdCArICIpLiIpOworICAgIH0KKyAgfQorCisgIC8qKiBXcml0ZSBhIHNpbmdsZSBieXRlLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0J5dGUoZmluYWwgYnl0ZSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgIC8vIFdlJ3JlIHdyaXRpbmcgdG8gYSBzaW5nbGUgYnVmZmVyLgorICAgICAgdGhyb3cgbmV3IE91dE9mU3BhY2VFeGNlcHRpb24ocG9zaXRpb24sIGxpbWl0KTsKKyAgICB9CisKKyAgICBidWZmZXJbcG9zaXRpb24rK10gPSB2YWx1ZTsKKyAgfQorCisgIC8qKiBXcml0ZSBhIHNpbmdsZSBieXRlLCByZXByZXNlbnRlZCBieSBhbiBpbnRlZ2VyIHZhbHVlLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0J5dGUoZmluYWwgaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3Qnl0ZSgoYnl0ZSkgdmFsdWUpOworICB9CisKKyAgLyoqIFdyaXRlIGFuIGFycmF5IG9mIGJ5dGVzLiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd0J5dGVzKGZpbmFsIGJ5dGVbXSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0J5dGVzKHZhbHVlLCAwLCB2YWx1ZS5sZW5ndGgpOworICB9CisKKyAgLyoqIFdyaXRlIHBhcnQgb2YgYW4gYXJyYXkgb2YgYnl0ZXMuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlUmF3Qnl0ZXMoZmluYWwgYnl0ZVtdIHZhbHVlLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGxpbWl0IC0gcG9zaXRpb24gPj0gbGVuZ3RoKSB7CisgICAgICAvLyBXZSBoYXZlIHJvb20gaW4gdGhlIGN1cnJlbnQgYnVmZmVyLgorICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgb2Zmc2V0LCBidWZmZXIsIHBvc2l0aW9uLCBsZW5ndGgpOworICAgICAgcG9zaXRpb24gKz0gbGVuZ3RoOworICAgIH0gZWxzZSB7CisgICAgICAvLyBXZSdyZSB3cml0aW5nIHRvIGEgc2luZ2xlIGJ1ZmZlci4KKyAgICAgIHRocm93IG5ldyBPdXRPZlNwYWNlRXhjZXB0aW9uKHBvc2l0aW9uLCBsaW1pdCk7CisgICAgfQorICB9CisKKyAgLyoqIEVuY29kZSBhbmQgd3JpdGUgYSB0YWcuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVGFnKGZpbmFsIGludCBmaWVsZE51bWJlciwgZmluYWwgaW50IHdpcmVUeXBlKQorICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3VmFyaW50MzIoV2lyZUZvcm1hdE5hbm8ubWFrZVRhZyhmaWVsZE51bWJlciwgd2lyZVR5cGUpKTsKKyAgfQorCisgIC8qKiBDb21wdXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3b3VsZCBiZSBuZWVkZWQgdG8gZW5jb2RlIGEgdGFnLiAqLworICBwdWJsaWMgc3RhdGljIGludCBjb21wdXRlVGFnU2l6ZShmaW5hbCBpbnQgZmllbGROdW1iZXIpIHsKKyAgICByZXR1cm4gY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShXaXJlRm9ybWF0TmFuby5tYWtlVGFnKGZpZWxkTnVtYmVyLCAwKSk7CisgIH0KKworICAvKioKKyAgICogRW5jb2RlIGFuZCB3cml0ZSBhIHZhcmludC4gIHtAY29kZSB2YWx1ZX0gaXMgdHJlYXRlZCBhcworICAgKiB1bnNpZ25lZCwgc28gaXQgd29uJ3QgYmUgc2lnbi1leHRlbmRlZCBpZiBuZWdhdGl2ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlUmF3VmFyaW50MzIoaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpZiAoKHZhbHVlICYgfjB4N0YpID09IDApIHsKKyAgICAgICAgd3JpdGVSYXdCeXRlKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgd3JpdGVSYXdCeXRlKCh2YWx1ZSAmIDB4N0YpIHwgMHg4MCk7CisgICAgICAgIHZhbHVlID4+Pj0gNzsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd291bGQgYmUgbmVlZGVkIHRvIGVuY29kZSBhIHZhcmludC4KKyAgICoge0Bjb2RlIHZhbHVlfSBpcyB0cmVhdGVkIGFzIHVuc2lnbmVkLCBzbyBpdCB3b24ndCBiZSBzaWduLWV4dGVuZGVkIGlmCisgICAqIG5lZ2F0aXZlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmYgPDwgIDcpKSA9PSAwKSByZXR1cm4gMTsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmYgPDwgMTQpKSA9PSAwKSByZXR1cm4gMjsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmYgPDwgMjEpKSA9PSAwKSByZXR1cm4gMzsKKyAgICBpZiAoKHZhbHVlICYgKDB4ZmZmZmZmZmYgPDwgMjgpKSA9PSAwKSByZXR1cm4gNDsKKyAgICByZXR1cm4gNTsKKyAgfQorCisgIC8qKiBFbmNvZGUgYW5kIHdyaXRlIGEgdmFyaW50LiAqLworICBwdWJsaWMgdm9pZCB3cml0ZVJhd1ZhcmludDY0KGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGlmICgodmFsdWUgJiB+MHg3RkwpID09IDApIHsKKyAgICAgICAgd3JpdGVSYXdCeXRlKChpbnQpdmFsdWUpOworICAgICAgICByZXR1cm47CisgICAgICB9IGVsc2UgeworICAgICAgICB3cml0ZVJhd0J5dGUoKChpbnQpdmFsdWUgJiAweDdGKSB8IDB4ODApOworICAgICAgICB2YWx1ZSA+Pj49IDc7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIENvbXB1dGUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdvdWxkIGJlIG5lZWRlZCB0byBlbmNvZGUgYSB2YXJpbnQuICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXB1dGVSYXdWYXJpbnQ2NFNpemUoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCAgNykpID09IDApIHJldHVybiAxOworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCAxNCkpID09IDApIHJldHVybiAyOworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCAyMSkpID09IDApIHJldHVybiAzOworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCAyOCkpID09IDApIHJldHVybiA0OworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCAzNSkpID09IDApIHJldHVybiA1OworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCA0MikpID09IDApIHJldHVybiA2OworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCA0OSkpID09IDApIHJldHVybiA3OworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCA1NikpID09IDApIHJldHVybiA4OworICAgIGlmICgodmFsdWUgJiAoMHhmZmZmZmZmZmZmZmZmZmZmTCA8PCA2MykpID09IDApIHJldHVybiA5OworICAgIHJldHVybiAxMDsKKyAgfQorCisgIC8qKiBXcml0ZSBhIGxpdHRsZS1lbmRpYW4gMzItYml0IGludGVnZXIuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlUmF3TGl0dGxlRW5kaWFuMzIoZmluYWwgaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlUmF3Qnl0ZSgodmFsdWUgICAgICApICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKCh2YWx1ZSA+PiAgOCkgJiAweEZGKTsKKyAgICB3cml0ZVJhd0J5dGUoKHZhbHVlID4+IDE2KSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgodmFsdWUgPj4gMjQpICYgMHhGRik7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMSVRUTEVfRU5ESUFOXzMyX1NJWkUgPSA0OworCisgIC8qKiBXcml0ZSBhIGxpdHRsZS1lbmRpYW4gNjQtYml0IGludGVnZXIuICovCisgIHB1YmxpYyB2b2lkIHdyaXRlUmF3TGl0dGxlRW5kaWFuNjQoZmluYWwgbG9uZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZVJhd0J5dGUoKGludCkodmFsdWUgICAgICApICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKChpbnQpKHZhbHVlID4+ICA4KSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgoaW50KSh2YWx1ZSA+PiAxNikgJiAweEZGKTsKKyAgICB3cml0ZVJhd0J5dGUoKGludCkodmFsdWUgPj4gMjQpICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKChpbnQpKHZhbHVlID4+IDMyKSAmIDB4RkYpOworICAgIHdyaXRlUmF3Qnl0ZSgoaW50KSh2YWx1ZSA+PiA0MCkgJiAweEZGKTsKKyAgICB3cml0ZVJhd0J5dGUoKGludCkodmFsdWUgPj4gNDgpICYgMHhGRik7CisgICAgd3JpdGVSYXdCeXRlKChpbnQpKHZhbHVlID4+IDU2KSAmIDB4RkYpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTElUVExFX0VORElBTl82NF9TSVpFID0gODsKKworICAvKioKKyAgICogRW5jb2RlIGEgWmlnWmFnLWVuY29kZWQgMzItYml0IHZhbHVlLiAgWmlnWmFnIGVuY29kZXMgc2lnbmVkIGludGVnZXJzCisgICAqIGludG8gdmFsdWVzIHRoYXQgY2FuIGJlIGVmZmljaWVudGx5IGVuY29kZWQgd2l0aCB2YXJpbnQuICAoT3RoZXJ3aXNlLAorICAgKiBuZWdhdGl2ZSB2YWx1ZXMgbXVzdCBiZSBzaWduLWV4dGVuZGVkIHRvIDY0IGJpdHMgdG8gYmUgdmFyaW50IGVuY29kZWQsCisgICAqIHRodXMgYWx3YXlzIHRha2luZyAxMCBieXRlcyBvbiB0aGUgd2lyZS4pCisgICAqCisgICAqIEBwYXJhbSBuIEEgc2lnbmVkIDMyLWJpdCBpbnRlZ2VyLgorICAgKiBAcmV0dXJuIEFuIHVuc2lnbmVkIDMyLWJpdCBpbnRlZ2VyLCBzdG9yZWQgaW4gYSBzaWduZWQgaW50IGJlY2F1c2UKKyAgICogICAgICAgICBKYXZhIGhhcyBubyBleHBsaWNpdCB1bnNpZ25lZCBzdXBwb3J0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgZW5jb2RlWmlnWmFnMzIoZmluYWwgaW50IG4pIHsKKyAgICAvLyBOb3RlOiAgdGhlIHJpZ2h0LXNoaWZ0IG11c3QgYmUgYXJpdGhtZXRpYworICAgIHJldHVybiAobiA8PCAxKSBeIChuID4+IDMxKTsKKyAgfQorCisgIC8qKgorICAgKiBFbmNvZGUgYSBaaWdaYWctZW5jb2RlZCA2NC1iaXQgdmFsdWUuICBaaWdaYWcgZW5jb2RlcyBzaWduZWQgaW50ZWdlcnMKKyAgICogaW50byB2YWx1ZXMgdGhhdCBjYW4gYmUgZWZmaWNpZW50bHkgZW5jb2RlZCB3aXRoIHZhcmludC4gIChPdGhlcndpc2UsCisgICAqIG5lZ2F0aXZlIHZhbHVlcyBtdXN0IGJlIHNpZ24tZXh0ZW5kZWQgdG8gNjQgYml0cyB0byBiZSB2YXJpbnQgZW5jb2RlZCwKKyAgICogdGh1cyBhbHdheXMgdGFraW5nIDEwIGJ5dGVzIG9uIHRoZSB3aXJlLikKKyAgICoKKyAgICogQHBhcmFtIG4gQSBzaWduZWQgNjQtYml0IGludGVnZXIuCisgICAqIEByZXR1cm4gQW4gdW5zaWduZWQgNjQtYml0IGludGVnZXIsIHN0b3JlZCBpbiBhIHNpZ25lZCBpbnQgYmVjYXVzZQorICAgKiAgICAgICAgIEphdmEgaGFzIG5vIGV4cGxpY2l0IHVuc2lnbmVkIHN1cHBvcnQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGxvbmcgZW5jb2RlWmlnWmFnNjQoZmluYWwgbG9uZyBuKSB7CisgICAgLy8gTm90ZTogIHRoZSByaWdodC1zaGlmdCBtdXN0IGJlIGFyaXRobWV0aWMKKyAgICByZXR1cm4gKG4gPDwgMSkgXiAobiA+PiA2Myk7CisgIH0KKworICBzdGF0aWMgaW50IGNvbXB1dGVGaWVsZFNpemUoaW50IG51bWJlciwgaW50IHR5cGUsIE9iamVjdCBvYmplY3QpIHsKKyAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfQk9PTDoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVCb29sU2l6ZShudW1iZXIsIChCb29sZWFuKSBvYmplY3QpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9CWVRFUzoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVCeXRlc1NpemUobnVtYmVyLCAoYnl0ZVtdKSBvYmplY3QpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9TVFJJTkc6CisgICAgICAgIHJldHVybiBjb21wdXRlU3RyaW5nU2l6ZShudW1iZXIsIChTdHJpbmcpIG9iamVjdCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0ZMT0FUOgorICAgICAgICByZXR1cm4gY29tcHV0ZUZsb2F0U2l6ZShudW1iZXIsIChGbG9hdCkgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfRE9VQkxFOgorICAgICAgICByZXR1cm4gY29tcHV0ZURvdWJsZVNpemUobnVtYmVyLCAoRG91YmxlKSBvYmplY3QpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gY29tcHV0ZUVudW1TaXplKG51bWJlciwgKEludGVnZXIpIG9iamVjdCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0ZJWEVEMzI6CisgICAgICAgIHJldHVybiBjb21wdXRlRml4ZWQzMlNpemUobnVtYmVyLCAoSW50ZWdlcikgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfSU5UMzI6CisgICAgICAgIHJldHVybiBjb21wdXRlSW50MzJTaXplKG51bWJlciwgKEludGVnZXIpIG9iamVjdCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1VJTlQzMjoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVVSW50MzJTaXplKG51bWJlciwgKEludGVnZXIpIG9iamVjdCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NJTlQzMjoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVTSW50MzJTaXplKG51bWJlciwgKEludGVnZXIpIG9iamVjdCk7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NGSVhFRDMyOgorICAgICAgICByZXR1cm4gY29tcHV0ZVNGaXhlZDMyU2l6ZShudW1iZXIsIChJbnRlZ2VyKSBvYmplY3QpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9JTlQ2NDoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVJbnQ2NFNpemUobnVtYmVyLCAoTG9uZykgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfVUlOVDY0OgorICAgICAgICByZXR1cm4gY29tcHV0ZVVJbnQ2NFNpemUobnVtYmVyLCAoTG9uZykgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfU0lOVDY0OgorICAgICAgICByZXR1cm4gY29tcHV0ZVNJbnQ2NFNpemUobnVtYmVyLCAoTG9uZykgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfRklYRUQ2NDoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVGaXhlZDY0U2l6ZShudW1iZXIsIChMb25nKSBvYmplY3QpOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9TRklYRUQ2NDoKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVTRml4ZWQ2NFNpemUobnVtYmVyLCAoTG9uZykgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfTUVTU0FHRToKKyAgICAgICAgcmV0dXJuIGNvbXB1dGVNZXNzYWdlU2l6ZShudW1iZXIsIChNZXNzYWdlTmFubykgb2JqZWN0KTsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfR1JPVVA6CisgICAgICAgIHJldHVybiBjb21wdXRlR3JvdXBTaXplKG51bWJlciwgKE1lc3NhZ2VOYW5vKSBvYmplY3QpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5rbm93biB0eXBlOiAiICsgdHlwZSk7CisgICAgfQorICB9CisKKyAgdm9pZCB3cml0ZUZpZWxkKGludCBudW1iZXIsIGludCB0eXBlLCBPYmplY3QgdmFsdWUpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9ET1VCTEU6CisgICAgICAgIERvdWJsZSBkb3VibGVWYWx1ZSA9IChEb3VibGUpIHZhbHVlOworICAgICAgICB3cml0ZURvdWJsZShudW1iZXIsIGRvdWJsZVZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0ZMT0FUOgorICAgICAgICBGbG9hdCBmbG9hdFZhbHVlID0gKEZsb2F0KSB2YWx1ZTsKKyAgICAgICAgd3JpdGVGbG9hdChudW1iZXIsIGZsb2F0VmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfSU5UNjQ6CisgICAgICAgIExvbmcgaW50NjRWYWx1ZSA9IChMb25nKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVJbnQ2NChudW1iZXIsIGludDY0VmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfVUlOVDY0OgorICAgICAgICBMb25nIHVpbnQ2NFZhbHVlID0gKExvbmcpIHZhbHVlOworICAgICAgICB3cml0ZVVJbnQ2NChudW1iZXIsIHVpbnQ2NFZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0lOVDMyOgorICAgICAgICBJbnRlZ2VyIGludDMyVmFsdWUgPSAoSW50ZWdlcikgdmFsdWU7CisgICAgICAgIHdyaXRlSW50MzIobnVtYmVyLCBpbnQzMlZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0ZJWEVENjQ6CisgICAgICAgIExvbmcgZml4ZWQ2NFZhbHVlID0gKExvbmcpIHZhbHVlOworICAgICAgICB3cml0ZUZpeGVkNjQobnVtYmVyLCBmaXhlZDY0VmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfRklYRUQzMjoKKyAgICAgICAgSW50ZWdlciBmaXhlZDMyVmFsdWUgPSAoSW50ZWdlcikgdmFsdWU7CisgICAgICAgIHdyaXRlRml4ZWQzMihudW1iZXIsIGZpeGVkMzJWYWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9CT09MOgorICAgICAgICBCb29sZWFuIGJvb2xWYWx1ZSA9IChCb29sZWFuKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVCb29sKG51bWJlciwgYm9vbFZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NUUklORzoKKyAgICAgICAgU3RyaW5nIHN0cmluZ1ZhbHVlID0gKFN0cmluZykgdmFsdWU7CisgICAgICAgIHdyaXRlU3RyaW5nKG51bWJlciwgc3RyaW5nVmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfQllURVM6CisgICAgICAgIGJ5dGVbXSBieXRlc1ZhbHVlID0gKGJ5dGVbXSkgdmFsdWU7CisgICAgICAgIHdyaXRlQnl0ZXMobnVtYmVyLCBieXRlc1ZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1VJTlQzMjoKKyAgICAgICAgSW50ZWdlciB1aW50MzJWYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVVSW50MzIobnVtYmVyLCB1aW50MzJWYWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9FTlVNOgorICAgICAgICBJbnRlZ2VyIGVudW1WYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVFbnVtKG51bWJlciwgZW51bVZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NGSVhFRDMyOgorICAgICAgICBJbnRlZ2VyIHNmaXhlZDMyVmFsdWUgPSAoSW50ZWdlcikgdmFsdWU7CisgICAgICAgIHdyaXRlU0ZpeGVkMzIobnVtYmVyLCBzZml4ZWQzMlZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NGSVhFRDY0OgorICAgICAgICBMb25nIHNmaXhlZDY0VmFsdWUgPSAoTG9uZykgdmFsdWU7CisgICAgICAgIHdyaXRlU0ZpeGVkNjQobnVtYmVyLCBzZml4ZWQ2NFZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX1NJTlQzMjoKKyAgICAgICAgSW50ZWdlciBzaW50MzJWYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVTSW50MzIobnVtYmVyLCBzaW50MzJWYWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBJbnRlcm5hbE5hbm8uVFlQRV9TSU5UNjQ6CisgICAgICAgIExvbmcgc2ludDY0VmFsdWUgPSAoTG9uZykgdmFsdWU7CisgICAgICAgIHdyaXRlU0ludDY0KG51bWJlciwgc2ludDY0VmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSW50ZXJuYWxOYW5vLlRZUEVfTUVTU0FHRToKKyAgICAgICAgTWVzc2FnZU5hbm8gbWVzc2FnZVZhbHVlID0gKE1lc3NhZ2VOYW5vKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVNZXNzYWdlKG51bWJlciwgbWVzc2FnZVZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEludGVybmFsTmFuby5UWVBFX0dST1VQOgorICAgICAgICBNZXNzYWdlTmFubyBncm91cFZhbHVlID0gKE1lc3NhZ2VOYW5vKSB2YWx1ZTsKKyAgICAgICAgd3JpdGVHcm91cChudW1iZXIsIGdyb3VwVmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5rbm93biB0eXBlOiAiICsgdHlwZSk7CisgICAgfQorICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0V4dGVuZGFibGVNZXNzYWdlTmFuby5qYXZhIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRXh0ZW5kYWJsZU1lc3NhZ2VOYW5vLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjk3OTM5MAotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0V4dGVuZGFibGVNZXNzYWdlTmFuby5qYXZhCkBAIC0wLDAgKzEsMTg3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEzIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIEJhc2UgY2xhc3Mgb2YgdGhvc2UgUHJvdG9jb2wgQnVmZmVyIG1lc3NhZ2VzIHRoYXQgbmVlZCB0byBzdG9yZSB1bmtub3duIGZpZWxkcywKKyAqIHN1Y2ggYXMgZXh0ZW5zaW9ucy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEV4dGVuZGFibGVNZXNzYWdlTmFubzxNIGV4dGVuZHMgRXh0ZW5kYWJsZU1lc3NhZ2VOYW5vPE0+PgorICAgICAgICBleHRlbmRzIE1lc3NhZ2VOYW5vIHsKKyAgICAvKioKKyAgICAgKiBBIGNvbnRhaW5lciBmb3IgZmllbGRzIHVua25vd24gdG8gdGhlIG1lc3NhZ2UsIGluY2x1ZGluZyBleHRlbnNpb25zLiBFeHRlbnNpb24gZmllbGRzIGNhbgorICAgICAqIGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZSB7QGxpbmsgI2dldEV4dGVuc2lvbn0gYW5kIHtAbGluayAjc2V0RXh0ZW5zaW9ufSBtZXRob2RzLgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWVsZEFycmF5IHVua25vd25GaWVsZERhdGE7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGNvbXB1dGVTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICAgICAgaW50IHNpemUgPSAwOworICAgICAgICBpZiAodW5rbm93bkZpZWxkRGF0YSAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25GaWVsZERhdGEuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBGaWVsZERhdGEgZmllbGQgPSB1bmtub3duRmllbGREYXRhLmRhdGFBdChpKTsKKyAgICAgICAgICAgICAgICBzaXplICs9IGZpZWxkLmNvbXB1dGVTZXJpYWxpemVkU2l6ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh1bmtub3duRmllbGREYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25GaWVsZERhdGEuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIEZpZWxkRGF0YSBmaWVsZCA9IHVua25vd25GaWVsZERhdGEuZGF0YUF0KGkpOworICAgICAgICAgICAgZmllbGQud3JpdGVUbyhvdXRwdXQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZXJlIGlzIGEgdmFsdWUgc3RvcmVkIGZvciB0aGUgc3BlY2lmaWVkIGV4dGVuc2lvbiBpbiB0aGlzCisgICAgICogbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNFeHRlbnNpb24oRXh0ZW5zaW9uPE0sID8+IGV4dGVuc2lvbikgeworICAgICAgICBpZiAodW5rbm93bkZpZWxkRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgRmllbGREYXRhIGZpZWxkID0gdW5rbm93bkZpZWxkRGF0YS5nZXQoV2lyZUZvcm1hdE5hbm8uZ2V0VGFnRmllbGROdW1iZXIoZXh0ZW5zaW9uLnRhZykpOworICAgICAgICByZXR1cm4gZmllbGQgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBzdG9yZWQgaW4gdGhlIHNwZWNpZmllZCBleHRlbnNpb24gb2YgdGhpcyBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCA8VD4gVCBnZXRFeHRlbnNpb24oRXh0ZW5zaW9uPE0sIFQ+IGV4dGVuc2lvbikgeworICAgICAgICBpZiAodW5rbm93bkZpZWxkRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBGaWVsZERhdGEgZmllbGQgPSB1bmtub3duRmllbGREYXRhLmdldChXaXJlRm9ybWF0TmFuby5nZXRUYWdGaWVsZE51bWJlcihleHRlbnNpb24udGFnKSk7CisgICAgICAgIHJldHVybiBmaWVsZCA9PSBudWxsID8gbnVsbCA6IGZpZWxkLmdldFZhbHVlKGV4dGVuc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBleHRlbnNpb24gb2YgdGhpcyBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCA8VD4gTSBzZXRFeHRlbnNpb24oRXh0ZW5zaW9uPE0sIFQ+IGV4dGVuc2lvbiwgVCB2YWx1ZSkgeworICAgICAgICBpbnQgZmllbGROdW1iZXIgPSBXaXJlRm9ybWF0TmFuby5nZXRUYWdGaWVsZE51bWJlcihleHRlbnNpb24udGFnKTsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmICh1bmtub3duRmllbGREYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB1bmtub3duRmllbGREYXRhLnJlbW92ZShmaWVsZE51bWJlcik7CisgICAgICAgICAgICAgICAgaWYgKHVua25vd25GaWVsZERhdGEuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHVua25vd25GaWVsZERhdGEgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEZpZWxkRGF0YSBmaWVsZCA9IG51bGw7CisgICAgICAgICAgICBpZiAodW5rbm93bkZpZWxkRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdW5rbm93bkZpZWxkRGF0YSA9IG5ldyBGaWVsZEFycmF5KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZpZWxkID0gdW5rbm93bkZpZWxkRGF0YS5nZXQoZmllbGROdW1iZXIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB1bmtub3duRmllbGREYXRhLnB1dChmaWVsZE51bWJlciwgbmV3IEZpZWxkRGF0YShleHRlbnNpb24sIHZhbHVlKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZpZWxkLnNldFZhbHVlKGV4dGVuc2lvbiwgdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIEdlbmVyYXRlZCBjb2RlIHNob3VsZCBndWFyYW50ZWUgdHlwZSBzYWZldHkKKyAgICAgICAgTSB0eXBlZFRoaXMgPSAoTSkgdGhpczsKKyAgICAgICAgcmV0dXJuIHR5cGVkVGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgdGhlIGJpbmFyeSBkYXRhIG9mIGFuIHVua25vd24gZmllbGQuCisgICAgICoKKyAgICAgKiA8cD5HZW5lcmF0ZWQgbWVzc2FnZXMgd2lsbCBjYWxsIHRoaXMgZm9yIHVua25vd24gZmllbGRzIGlmIHRoZSBzdG9yZV91bmtub3duX2ZpZWxkcworICAgICAqIG9wdGlvbiBpcyBvbi4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgdGFnIG1pZ2h0IGJlIGEgZW5kLWdyb3VwIHRhZyAocmF0aGVyIHRoYW4gdGhlIHN0YXJ0IG9mIGFuIHVua25vd24gZmllbGQpIGluCisgICAgICogd2hpY2ggY2FzZSB3ZSBkbyBub3Qgd2FudCB0byBhZGQgYW4gdW5rbm93biBmaWVsZCBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dCB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSB0YWcgdGhlIHRhZyBvZiB0aGUgZmllbGQuCisKKyAgICAgKiBAcmV0dXJuIHtAbGl0ZXJhbCB0cnVlfSB1bmxlc3MgdGhlIHRhZyBpcyBhbiBlbmQtZ3JvdXAgdGFnLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHN0b3JlVW5rbm93bkZpZWxkKENvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBpbnB1dCwgaW50IHRhZykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzdGFydFBvcyA9IGlucHV0LmdldFBvc2l0aW9uKCk7CisgICAgICAgIGlmICghaW5wdXQuc2tpcEZpZWxkKHRhZykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIFRoaXMgd2Fzbid0IGFuIHVua25vd24gZmllbGQsIGl0J3MgYW4gZW5kLWdyb3VwIHRhZy4KKyAgICAgICAgfQorICAgICAgICBpbnQgZmllbGROdW1iZXIgPSBXaXJlRm9ybWF0TmFuby5nZXRUYWdGaWVsZE51bWJlcih0YWcpOworICAgICAgICBpbnQgZW5kUG9zID0gaW5wdXQuZ2V0UG9zaXRpb24oKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gaW5wdXQuZ2V0RGF0YShzdGFydFBvcywgZW5kUG9zIC0gc3RhcnRQb3MpOworICAgICAgICBVbmtub3duRmllbGREYXRhIHVua25vd25GaWVsZCA9IG5ldyBVbmtub3duRmllbGREYXRhKHRhZywgYnl0ZXMpOworCisgICAgICAgIEZpZWxkRGF0YSBmaWVsZCA9IG51bGw7CisgICAgICAgIGlmICh1bmtub3duRmllbGREYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIHVua25vd25GaWVsZERhdGEgPSBuZXcgRmllbGRBcnJheSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmllbGQgPSB1bmtub3duRmllbGREYXRhLmdldChmaWVsZE51bWJlcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIGZpZWxkID0gbmV3IEZpZWxkRGF0YSgpOworICAgICAgICAgICAgdW5rbm93bkZpZWxkRGF0YS5wdXQoZmllbGROdW1iZXIsIGZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICBmaWVsZC5hZGRVbmtub3duRmllbGQodW5rbm93bkZpZWxkKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzdG9yZWQgdW5rbm93biBmaWVsZCBkYXRhIGluIHRoaXMgbWVzc2FnZSBpcyBlcXVpdmFsZW50IHRvIHRoYXQgaW4gdGhlCisgICAgICogb3RoZXIgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlciB0aGUgb3RoZXIgbWVzc2FnZS4KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIHR3byBzZXRzIG9mIHVua25vd24gZmllbGQgZGF0YSBhcmUgZXF1YWwuCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gdW5rbm93bkZpZWxkRGF0YUVxdWFscyhNIG90aGVyKSB7CisgICAgICAgIGlmICh1bmtub3duRmllbGREYXRhID09IG51bGwgfHwgdW5rbm93bkZpZWxkRGF0YS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBvdGhlci51bmtub3duRmllbGREYXRhID09IG51bGwgfHwgb3RoZXIudW5rbm93bkZpZWxkRGF0YS5pc0VtcHR5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gdW5rbm93bkZpZWxkRGF0YS5lcXVhbHMob3RoZXIudW5rbm93bkZpZWxkRGF0YSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyB0aGUgaGFzaGNvZGUgcmVwcmVzZW50aW5nIHRoZSB1bmtub3duIGZpZWxkIGRhdGEgc3RvcmVkIGluIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2hjb2RlIGZvciB0aGUgdW5rbm93biBmaWVsZCBkYXRhLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgdW5rbm93bkZpZWxkRGF0YUhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gKHVua25vd25GaWVsZERhdGEgPT0gbnVsbCB8fCB1bmtub3duRmllbGREYXRhLmlzRW1wdHkoKQorICAgICAgICAgICAgICAgID8gMCA6IHVua25vd25GaWVsZERhdGEuaGFzaENvZGUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRXh0ZW5zaW9uLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9FeHRlbnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjliMDMwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRXh0ZW5zaW9uLmphdmEKQEAgLTAsMCArMSw2ODcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTMgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBSZXByZXNlbnRzIGFuIGV4dGVuc2lvbi4KKyAqCisgKiBAYXV0aG9yIGJkdWZmQGdvb2dsZS5jb20gKEJyaWFuIER1ZmYpCisgKiBAYXV0aG9yIG1heHRyb3lAZ29vZ2xlLmNvbSAoTWF4IENhaSkKKyAqIEBwYXJhbSA8TT4gdGhlIHR5cGUgb2YgdGhlIGV4dGVuZGFibGUgbWVzc2FnZSB0aGlzIGV4dGVuc2lvbiBpcyBmb3IuCisgKiBAcGFyYW0gPFQ+IHRoZSBKYXZhIHR5cGUgb2YgdGhlIGV4dGVuc2lvbjsgc2VlIHtAbGluayAjY2xhenp9LgorICovCitwdWJsaWMgY2xhc3MgRXh0ZW5zaW9uPE0gZXh0ZW5kcyBFeHRlbmRhYmxlTWVzc2FnZU5hbm88TT4sIFQ+IHsKKworICAgIC8qCisgICAgICogQmVjYXVzZSB3ZSB0eXBpY2FsbHkgb25seSBkZWZpbmUgbWVzc2FnZS10eXBlZCBleHRlbnNpb25zLCB0aGUgRXh0ZW5zaW9uIGNsYXNzIGhpZXJhcmNoeSBpcworICAgICAqIGRlc2lnbmVkIGFzIGZvbGxvd3MsIHRvIGFsbG93IGEgYmlnIGFtb3VudCBvZiBjb2RlIGluIHRoaXMgZmlsZSB0byBiZSByZW1vdmVkIGJ5IFByb0d1YXJkOgorICAgICAqCisgICAgICogICAgICAgICAgICBFeHRlbnNpb24gICAgICAgICAgLy8gcmVhZHkgdG8gdXNlIGZvciBtZXNzYWdlL2dyb3VwIHR5cGVkIGV4dGVuc2lvbnMKKyAgICAgKiAgICAgICAgICAgICAgICDOlAorICAgICAqICAgICAgICAgICAgICAgIHwKKyAgICAgKiAgICAgICBQcmltaXRpdmVFeHRlbnNpb24gICAgICAvLyBmb3IgcHJpbWl0aXZlL2VudW0gdHlwZWQgZXh0ZW5zaW9ucworICAgICAqLworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9ET1VCTEUgICA9IEludGVybmFsTmFuby5UWVBFX0RPVUJMRTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZMT0FUICAgID0gSW50ZXJuYWxOYW5vLlRZUEVfRkxPQVQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9JTlQ2NCAgICA9IEludGVybmFsTmFuby5UWVBFX0lOVDY0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfVUlOVDY0ICAgPSBJbnRlcm5hbE5hbm8uVFlQRV9VSU5UNjQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9JTlQzMiAgICA9IEludGVybmFsTmFuby5UWVBFX0lOVDMyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRklYRUQ2NCAgPSBJbnRlcm5hbE5hbm8uVFlQRV9GSVhFRDY0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRklYRUQzMiAgPSBJbnRlcm5hbE5hbm8uVFlQRV9GSVhFRDMyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQk9PTCAgICAgPSBJbnRlcm5hbE5hbm8uVFlQRV9CT09MOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfU1RSSU5HICAgPSBJbnRlcm5hbE5hbm8uVFlQRV9TVFJJTkc7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9HUk9VUCAgICA9IEludGVybmFsTmFuby5UWVBFX0dST1VQOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfTUVTU0FHRSAgPSBJbnRlcm5hbE5hbm8uVFlQRV9NRVNTQUdFOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQllURVMgICAgPSBJbnRlcm5hbE5hbm8uVFlQRV9CWVRFUzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1VJTlQzMiAgID0gSW50ZXJuYWxOYW5vLlRZUEVfVUlOVDMyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRU5VTSAgICAgPSBJbnRlcm5hbE5hbm8uVFlQRV9FTlVNOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfU0ZJWEVEMzIgPSBJbnRlcm5hbE5hbm8uVFlQRV9TRklYRUQzMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1NGSVhFRDY0ID0gSW50ZXJuYWxOYW5vLlRZUEVfU0ZJWEVENjQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9TSU5UMzIgICA9IEludGVybmFsTmFuby5UWVBFX1NJTlQzMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1NJTlQ2NCAgID0gSW50ZXJuYWxOYW5vLlRZUEVfU0lOVDY0OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgRXh0ZW5zaW9ufSBvZiB0aGUgZ2l2ZW4gbWVzc2FnZSB0eXBlIGFuZCB0YWcgbnVtYmVyLgorICAgICAqIFNob3VsZCBiZSB1c2VkIGJ5IHRoZSBnZW5lcmF0ZWQgY29kZSBvbmx5LgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUge0BsaW5rICNUWVBFX01FU1NBR0V9IG9yIHtAbGluayAjVFlQRV9HUk9VUH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxNIGV4dGVuZHMgRXh0ZW5kYWJsZU1lc3NhZ2VOYW5vPE0+LCBUIGV4dGVuZHMgTWVzc2FnZU5hbm8+CisgICAgICAgICAgICBFeHRlbnNpb248TSwgVD4gY3JlYXRlTWVzc2FnZVR5cGVkKGludCB0eXBlLCBDbGFzczxUPiBjbGF6eiwgaW50IHRhZykgeworICAgICAgICByZXR1cm4gbmV3IEV4dGVuc2lvbjxNLCBUPih0eXBlLCBjbGF6eiwgdGFnLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHJlcGVhdGVkIHtAY29kZSBFeHRlbnNpb259IG9mIHRoZSBnaXZlbiBtZXNzYWdlIHR5cGUgYW5kIHRhZyBudW1iZXIuCisgICAgICogU2hvdWxkIGJlIHVzZWQgYnkgdGhlIGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSB7QGxpbmsgI1RZUEVfTUVTU0FHRX0gb3Ige0BsaW5rICNUWVBFX0dST1VQfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPE0gZXh0ZW5kcyBFeHRlbmRhYmxlTWVzc2FnZU5hbm88TT4sIFQgZXh0ZW5kcyBNZXNzYWdlTmFubz4KKyAgICAgICAgICAgIEV4dGVuc2lvbjxNLCBUW10+IGNyZWF0ZVJlcGVhdGVkTWVzc2FnZVR5cGVkKGludCB0eXBlLCBDbGFzczxUW10+IGNsYXp6LCBpbnQgdGFnKSB7CisgICAgICAgIHJldHVybiBuZXcgRXh0ZW5zaW9uPE0sIFRbXT4odHlwZSwgY2xhenosIHRhZywgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgRXh0ZW5zaW9ufSBvZiB0aGUgZ2l2ZW4gcHJpbWl0aXZlIHR5cGUgYW5kIHRhZyBudW1iZXIuCisgICAgICogU2hvdWxkIGJlIHVzZWQgYnkgdGhlIGdlbmVyYXRlZCBjb2RlIG9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSBvbmUgb2Yge0Bjb2RlIFRZUEVfKn0sIGV4Y2VwdCB7QGxpbmsgI1RZUEVfTUVTU0FHRX0gYW5kIHtAbGluayAjVFlQRV9HUk9VUH0KKyAgICAgKiBAcGFyYW0gY2xhenogdGhlIGJveGVkIEphdmEgdHlwZSBvZiB0aGlzIGV4dGVuc2lvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPE0gZXh0ZW5kcyBFeHRlbmRhYmxlTWVzc2FnZU5hbm88TT4sIFQ+CisgICAgICAgICAgICBFeHRlbnNpb248TSwgVD4gY3JlYXRlUHJpbWl0aXZlVHlwZWQoaW50IHR5cGUsIENsYXNzPFQ+IGNsYXp6LCBpbnQgdGFnKSB7CisgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlRXh0ZW5zaW9uPE0sIFQ+KHR5cGUsIGNsYXp6LCB0YWcsIGZhbHNlLCAwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgcmVwZWF0ZWQge0Bjb2RlIEV4dGVuc2lvbn0gb2YgdGhlIGdpdmVuIHByaW1pdGl2ZSB0eXBlIGFuZCB0YWcgbnVtYmVyLgorICAgICAqIFNob3VsZCBiZSB1c2VkIGJ5IHRoZSBnZW5lcmF0ZWQgY29kZSBvbmx5LgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUgb25lIG9mIHtAY29kZSBUWVBFXyp9LCBleGNlcHQge0BsaW5rICNUWVBFX01FU1NBR0V9IGFuZCB7QGxpbmsgI1RZUEVfR1JPVVB9CisgICAgICogQHBhcmFtIGNsYXp6IHRoZSBKYXZhIGFycmF5IHR5cGUgb2YgdGhpcyBleHRlbnNpb24sIHdpdGggYW4gdW5ib3hlZCBjb21wb25lbnQgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPE0gZXh0ZW5kcyBFeHRlbmRhYmxlTWVzc2FnZU5hbm88TT4sIFQ+CisgICAgICAgICAgICBFeHRlbnNpb248TSwgVD4gY3JlYXRlUmVwZWF0ZWRQcmltaXRpdmVUeXBlZCgKKyAgICAgICAgICAgICAgICAgICAgaW50IHR5cGUsIENsYXNzPFQ+IGNsYXp6LCBpbnQgdGFnLCBpbnQgbm9uUGFja2VkVGFnLCBpbnQgcGFja2VkVGFnKSB7CisgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlRXh0ZW5zaW9uPE0sIFQ+KHR5cGUsIGNsYXp6LCB0YWcsIHRydWUsIG5vblBhY2tlZFRhZywgcGFja2VkVGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm90b2NvbCBCdWZmZXIgdHlwZSBvZiB0aGlzIGV4dGVuc2lvbjsgb25lIG9mIHRoZSB7QGNvZGUgVFlQRV99IGNvbnN0YW50cy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgaW50IHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBKYXZhIHR5cGUgb2YgdGhpcyBleHRlbnNpb24uIEZvciBhIHNpbmd1bGFyIGV4dGVuc2lvbiwgdGhpcyBpcyB0aGUgYm94ZWQgSmF2YSB0eXBlIGZvciB0aGUKKyAgICAgKiBQcm90b2NvbCBCdWZmZXIge0BsaW5rICN0eXBlfTsgZm9yIGEgcmVwZWF0ZWQgZXh0ZW5zaW9uLCB0aGlzIGlzIGFuIGFycmF5IHR5cGUgd2hvc2UKKyAgICAgKiBjb21wb25lbnQgdHlwZSBpcyB0aGUgdW5ib3hlZCBKYXZhIHR5cGUgZm9yIHtAbGluayAjdHlwZX0uIEZvciBleGFtcGxlLCBmb3IgYSBzaW5ndWxhcgorICAgICAqIHtAY29kZSBpbnQzMn0ve0BsaW5rICNUWVBFX0lOVDMyfSBleHRlbnNpb24sIHRoaXMgZXF1YWxzIHtAY29kZSBJbnRlZ2VyLmNsYXNzfTsgZm9yIGEKKyAgICAgKiByZXBlYXRlZCB7QGNvZGUgaW50MzJ9IGV4dGVuc2lvbiwgdGhpcyBlcXVhbHMge0Bjb2RlIGludFtdLmNsYXNzfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8VD4gY2xheno7CisKKyAgICAvKioKKyAgICAgKiBUYWcgbnVtYmVyIG9mIHRoaXMgZXh0ZW5zaW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgdGFnOworCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyByZXBlYXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiByZXBlYXRlZDsKKworICAgIHByaXZhdGUgRXh0ZW5zaW9uKGludCB0eXBlLCBDbGFzczxUPiBjbGF6eiwgaW50IHRhZywgYm9vbGVhbiByZXBlYXRlZCkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB0aGlzLmNsYXp6ID0gY2xheno7CisgICAgICAgIHRoaXMudGFnID0gdGFnOworICAgICAgICB0aGlzLnJlcGVhdGVkID0gcmVwZWF0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhpcyBleHRlbnNpb24gc3RvcmVkIGluIHRoZSBnaXZlbiBsaXN0IG9mIHVua25vd24gZmllbGRzLCBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiBubyB1bmtub3duIGZpZWxkcyBtYXRjaGVzIHRoaXMgZXh0ZW5zaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHVua25vd25GaWVsZHMgYSBsaXN0IG9mIHtAbGluayBVbmtub3duRmllbGREYXRhfS4gQWxsIG9mIHRoZSBlbGVtZW50cyBtdXN0IGhhdmUgYSB0YWcKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGF0IG1hdGNoZXMgdGhpcyBFeHRlbnNpb24ncyB0YWcuCisgICAgICoKKyAgICAgKi8KKyAgICBmaW5hbCBUIGdldFZhbHVlRnJvbShMaXN0PFVua25vd25GaWVsZERhdGE+IHVua25vd25GaWVsZHMpIHsKKyAgICAgICAgaWYgKHVua25vd25GaWVsZHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlcGVhdGVkID8gZ2V0UmVwZWF0ZWRWYWx1ZUZyb20odW5rbm93bkZpZWxkcykgOiBnZXRTaW5ndWxhclZhbHVlRnJvbSh1bmtub3duRmllbGRzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFQgZ2V0UmVwZWF0ZWRWYWx1ZUZyb20oTGlzdDxVbmtub3duRmllbGREYXRhPiB1bmtub3duRmllbGRzKSB7CisgICAgICAgIC8vIEZvciByZXBlYXRlZCBleHRlbnNpb25zLCByZWFkIGFsbCBtYXRjaGluZyB1bmtub3duIGZpZWxkcyBpbiB0aGVpciBvcmlnaW5hbCBvcmRlci4KKyAgICAgICAgTGlzdDxPYmplY3Q+IHJlc3VsdExpc3QgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duRmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBVbmtub3duRmllbGREYXRhIGRhdGEgPSB1bmtub3duRmllbGRzLmdldChpKTsKKyAgICAgICAgICAgIGlmIChkYXRhLmJ5dGVzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmVhZERhdGFJbnRvKGRhdGEsIHJlc3VsdExpc3QpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IHJlc3VsdFNpemUgPSByZXN1bHRMaXN0LnNpemUoKTsKKyAgICAgICAgaWYgKHJlc3VsdFNpemUgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBUIHJlc3VsdCA9IGNsYXp6LmNhc3QoQXJyYXkubmV3SW5zdGFuY2UoY2xhenouZ2V0Q29tcG9uZW50VHlwZSgpLCByZXN1bHRTaXplKSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdFNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIEFycmF5LnNldChyZXN1bHQsIGksIHJlc3VsdExpc3QuZ2V0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFQgZ2V0U2luZ3VsYXJWYWx1ZUZyb20oTGlzdDxVbmtub3duRmllbGREYXRhPiB1bmtub3duRmllbGRzKSB7CisgICAgICAgIC8vIEZvciBzaW5ndWxhciBleHRlbnNpb25zLCBnZXQgdGhlIGxhc3QgcGllY2Ugb2YgZGF0YSBzdG9yZWQgdW5kZXIgdGhpcyBleHRlbnNpb24uCisgICAgICAgIGlmICh1bmtub3duRmllbGRzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgVW5rbm93bkZpZWxkRGF0YSBsYXN0RGF0YSA9IHVua25vd25GaWVsZHMuZ2V0KHVua25vd25GaWVsZHMuc2l6ZSgpIC0gMSk7CisgICAgICAgIHJldHVybiBjbGF6ei5jYXN0KHJlYWREYXRhKENvZGVkSW5wdXRCeXRlQnVmZmVyTmFuby5uZXdJbnN0YW5jZShsYXN0RGF0YS5ieXRlcykpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWREYXRhKENvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBpbnB1dCkgeworICAgICAgICAvLyBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGZvciBtZXNzYWdlL2dyb3VwIGV4dGVuc2lvbnMuCisgICAgICAgIENsYXNzPD8+IG1lc3NhZ2VUeXBlID0gcmVwZWF0ZWQgPyBjbGF6ei5nZXRDb21wb25lbnRUeXBlKCkgOiBjbGF6ejsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9HUk9VUDoKKyAgICAgICAgICAgICAgICAgICAgTWVzc2FnZU5hbm8gZ3JvdXAgPSAoTWVzc2FnZU5hbm8pIG1lc3NhZ2VUeXBlLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cChncm91cCwgV2lyZUZvcm1hdE5hbm8uZ2V0VGFnRmllbGROdW1iZXIodGFnKSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBncm91cDsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfTUVTU0FHRToKKyAgICAgICAgICAgICAgICAgICAgTWVzc2FnZU5hbm8gbWVzc2FnZSA9IChNZXNzYWdlTmFubykgbWVzc2FnZVR5cGUubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UobWVzc2FnZSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24gdHlwZSAiICsgdHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIkVycm9yIGNyZWF0aW5nIGluc3RhbmNlIG9mIGNsYXNzICIgKyBtZXNzYWdlVHlwZSwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIkVycm9yIGNyZWF0aW5nIGluc3RhbmNlIG9mIGNsYXNzICIgKyBtZXNzYWdlVHlwZSwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkVycm9yIHJlYWRpbmcgZXh0ZW5zaW9uIGZpZWxkIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCByZWFkRGF0YUludG8oVW5rbm93bkZpZWxkRGF0YSBkYXRhLCBMaXN0PE9iamVjdD4gcmVzdWx0TGlzdCkgeworICAgICAgICAvLyBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGZvciBtZXNzYWdlL2dyb3VwIGV4dGVuc2lvbnMuCisgICAgICAgIHJlc3VsdExpc3QuYWRkKHJlYWREYXRhKENvZGVkSW5wdXRCeXRlQnVmZmVyTmFuby5uZXdJbnN0YW5jZShkYXRhLmJ5dGVzKSkpOworICAgIH0KKworICAgIHZvaWQgd3JpdGVUbyhPYmplY3QgdmFsdWUsIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocmVwZWF0ZWQpIHsKKyAgICAgICAgICAgIHdyaXRlUmVwZWF0ZWREYXRhKHZhbHVlLCBvdXRwdXQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd3JpdGVTaW5ndWxhckRhdGEodmFsdWUsIG91dHB1dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZVNpbmd1bGFyRGF0YShPYmplY3QgdmFsdWUsIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8gb3V0KSB7CisgICAgICAgIC8vIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgZm9yIG1lc3NhZ2UvZ3JvdXAgZXh0ZW5zaW9ucy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC53cml0ZVJhd1ZhcmludDMyKHRhZyk7CisgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfR1JPVVA6CisgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VOYW5vIGdyb3VwVmFsdWUgPSAoTWVzc2FnZU5hbm8pIHZhbHVlOworICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGROdW1iZXIgPSBXaXJlRm9ybWF0TmFuby5nZXRUYWdGaWVsZE51bWJlcih0YWcpOworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGVHcm91cE5vVGFnKGdyb3VwVmFsdWUpOworICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZW5kZ3JvdXAgdGFnIG11c3QgYmUgaW5jbHVkZWQgaW4gdGhlIGRhdGEgcGF5bG9hZC4KKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlVGFnKGZpZWxkTnVtYmVyLCBXaXJlRm9ybWF0TmFuby5XSVJFVFlQRV9FTkRfR1JPVVApOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfTUVTU0FHRToKKyAgICAgICAgICAgICAgICAgICAgTWVzc2FnZU5hbm8gbWVzc2FnZVZhbHVlID0gKE1lc3NhZ2VOYW5vKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlTWVzc2FnZU5vVGFnKG1lc3NhZ2VWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24gdHlwZSAiICsgdHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVSZXBlYXRlZERhdGEoT2JqZWN0IGFycmF5LCBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vIG91dHB1dCkgeworICAgICAgICAvLyBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGZvciBub24tcGFja2VkIGV4dGVuc2lvbnMuCisgICAgICAgIGludCBhcnJheUxlbmd0aCA9IEFycmF5LmdldExlbmd0aChhcnJheSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgT2JqZWN0IGVsZW1lbnQgPSBBcnJheS5nZXQoYXJyYXksIGkpOworICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHdyaXRlU2luZ3VsYXJEYXRhKGVsZW1lbnQsIG91dHB1dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpbnQgY29tcHV0ZVNlcmlhbGl6ZWRTaXplKE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAocmVwZWF0ZWQpIHsKKyAgICAgICAgICAgIHJldHVybiBjb21wdXRlUmVwZWF0ZWRTZXJpYWxpemVkU2l6ZSh2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gY29tcHV0ZVNpbmd1bGFyU2VyaWFsaXplZFNpemUodmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIGludCBjb21wdXRlUmVwZWF0ZWRTZXJpYWxpemVkU2l6ZShPYmplY3QgYXJyYXkpIHsKKyAgICAgICAgLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBmb3Igbm9uLXBhY2tlZCBleHRlbnNpb25zLgorICAgICAgICBpbnQgc2l6ZSA9IDA7CisgICAgICAgIGludCBhcnJheUxlbmd0aCA9IEFycmF5LmdldExlbmd0aChhcnJheSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgT2JqZWN0IGVsZW1lbnQgPSBBcnJheS5nZXQoYXJyYXksIGkpOworICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNpemUgKz0gY29tcHV0ZVNpbmd1bGFyU2VyaWFsaXplZFNpemUoQXJyYXkuZ2V0KGFycmF5LCBpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGludCBjb21wdXRlU2luZ3VsYXJTZXJpYWxpemVkU2l6ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBmb3IgbWVzc2FnZS9ncm91cCBleHRlbnNpb25zLgorICAgICAgICBpbnQgZmllbGROdW1iZXIgPSBXaXJlRm9ybWF0TmFuby5nZXRUYWdGaWVsZE51bWJlcih0YWcpOworICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgVFlQRV9HUk9VUDoKKyAgICAgICAgICAgICAgICBNZXNzYWdlTmFubyBncm91cFZhbHVlID0gKE1lc3NhZ2VOYW5vKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlR3JvdXBTaXplKGZpZWxkTnVtYmVyLCBncm91cFZhbHVlKTsKKyAgICAgICAgICAgIGNhc2UgVFlQRV9NRVNTQUdFOgorICAgICAgICAgICAgICAgIE1lc3NhZ2VOYW5vIG1lc3NhZ2VWYWx1ZSA9IChNZXNzYWdlTmFubykgdmFsdWU7CisgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZU1lc3NhZ2VTaXplKGZpZWxkTnVtYmVyLCBtZXNzYWdlVmFsdWUpOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHR5cGUgIiArIHR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwcmVzZW50cyBhbiBleHRlbnNpb24gb2YgYSBwcmltaXRpdmUgKGluY2x1ZGluZyBlbnVtKSB0eXBlLiBJZiB0aGVyZSBpcyBubyBwcmltaXRpdmUKKyAgICAgKiBleHRlbnNpb25zLCB0aGlzIHN1YmNsYXNzIHdpbGwgYmUgcmVtb3ZhYmxlIGJ5IFByb0d1YXJkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFByaW1pdGl2ZUV4dGVuc2lvbjxNIGV4dGVuZHMgRXh0ZW5kYWJsZU1lc3NhZ2VOYW5vPE0+LCBUPgorICAgICAgICAgICAgZXh0ZW5kcyBFeHRlbnNpb248TSwgVD4geworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUYWcgb2YgYSBwaWVjZSBvZiBub24tcGFja2VkIGRhdGEgZnJvbSB0aGUgd2lyZSBjb21wYXRpYmxlIHdpdGggdGhpcyBleHRlbnNpb24uCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBub25QYWNrZWRUYWc7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRhZyBvZiBhIHBpZWNlIG9mIHBhY2tlZCBkYXRhIGZyb20gdGhlIHdpcmUgY29tcGF0aWJsZSB3aXRoIHRoaXMgZXh0ZW5zaW9uLgorICAgICAgICAgKiAwIGlmIHRoZSB0eXBlIG9mIHRoaXMgZXh0ZW5zaW9uIGlzIG5vdCBwYWNrYWJsZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IHBhY2tlZFRhZzsKKworICAgICAgICBwdWJsaWMgUHJpbWl0aXZlRXh0ZW5zaW9uKGludCB0eXBlLCBDbGFzczxUPiBjbGF6eiwgaW50IHRhZywgYm9vbGVhbiByZXBlYXRlZCwKKyAgICAgICAgICAgICAgICBpbnQgbm9uUGFja2VkVGFnLCBpbnQgcGFja2VkVGFnKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlLCBjbGF6eiwgdGFnLCByZXBlYXRlZCk7CisgICAgICAgICAgICB0aGlzLm5vblBhY2tlZFRhZyA9IG5vblBhY2tlZFRhZzsKKyAgICAgICAgICAgIHRoaXMucGFja2VkVGFnID0gcGFja2VkVGFnOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBPYmplY3QgcmVhZERhdGEoQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGlucHV0KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICByZXR1cm4gaW5wdXQucmVhZFByaW1pdGl2ZUZpZWxkKHR5cGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkVycm9yIHJlYWRpbmcgZXh0ZW5zaW9uIGZpZWxkIiwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZERhdGFJbnRvKFVua25vd25GaWVsZERhdGEgZGF0YSwgTGlzdDxPYmplY3Q+IHJlc3VsdExpc3QpIHsKKyAgICAgICAgICAgIC8vIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgZm9yIHByaW1pdGl2ZSB0eXBlZCBleHRlbnNpb25zLAorICAgICAgICAgICAgLy8gd2hpY2ggY2FuIHJlYWQgYm90aCBwYWNrZWQgYW5kIG5vbi1wYWNrZWQgZGF0YS4KKyAgICAgICAgICAgIGlmIChkYXRhLnRhZyA9PSBub25QYWNrZWRUYWcpIHsKKyAgICAgICAgICAgICAgICByZXN1bHRMaXN0LmFkZChyZWFkRGF0YShDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8ubmV3SW5zdGFuY2UoZGF0YS5ieXRlcykpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGJ1ZmZlciA9CisgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8ubmV3SW5zdGFuY2UoZGF0YS5ieXRlcyk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnB1c2hMaW1pdChidWZmZXIucmVhZFJhd1ZhcmludDMyKCkpOyAvLyBsZW5ndGggbGltaXQKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkVycm9yIHJlYWRpbmcgZXh0ZW5zaW9uIGZpZWxkIiwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHdoaWxlICghYnVmZmVyLmlzQXRFbmQoKSkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHRMaXN0LmFkZChyZWFkRGF0YShidWZmZXIpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgd3JpdGVTaW5ndWxhckRhdGEoT2JqZWN0IHZhbHVlLCBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vIG91dHB1dCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0YWcpOworICAgICAgICAgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgICAgICAgICAgRG91YmxlIGRvdWJsZVZhbHVlID0gKERvdWJsZSkgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVEb3VibGVOb1RhZyhkb3VibGVWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgICAgICAgICAgRmxvYXQgZmxvYXRWYWx1ZSA9IChGbG9hdCkgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVGbG9hdE5vVGFnKGZsb2F0VmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9JTlQ2NDoKKyAgICAgICAgICAgICAgICAgICAgICAgIExvbmcgaW50NjRWYWx1ZSA9IChMb25nKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcoaW50NjRWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1VJTlQ2NDoKKyAgICAgICAgICAgICAgICAgICAgICAgIExvbmcgdWludDY0VmFsdWUgPSAoTG9uZykgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyh1aW50NjRWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0lOVDMyOgorICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlciBpbnQzMlZhbHVlID0gKEludGVnZXIpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50MzJOb1RhZyhpbnQzMlZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRklYRUQ2NDoKKyAgICAgICAgICAgICAgICAgICAgICAgIExvbmcgZml4ZWQ2NFZhbHVlID0gKExvbmcpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NE5vVGFnKGZpeGVkNjRWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0ZJWEVEMzI6CisgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyIGZpeGVkMzJWYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhmaXhlZDMyVmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9CT09MOgorICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhbiBib29sVmFsdWUgPSAoQm9vbGVhbikgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcoYm9vbFZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU1RSSU5HOgorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN0cmluZ1ZhbHVlID0gKFN0cmluZykgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVTdHJpbmdOb1RhZyhzdHJpbmdWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0JZVEVTOgorICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzVmFsdWUgPSAoYnl0ZVtdKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGVzTm9UYWcoYnl0ZXNWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1VJTlQzMjoKKyAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIgdWludDMyVmFsdWUgPSAoSW50ZWdlcikgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyh1aW50MzJWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0VOVU06CisgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyIGVudW1WYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhlbnVtVmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TRklYRUQzMjoKKyAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIgc2ZpeGVkMzJWYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyTm9UYWcoc2ZpeGVkMzJWYWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1NGSVhFRDY0OgorICAgICAgICAgICAgICAgICAgICAgICAgTG9uZyBzZml4ZWQ2NFZhbHVlID0gKExvbmcpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhzZml4ZWQ2NFZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU0lOVDMyOgorICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlciBzaW50MzJWYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKHNpbnQzMlZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU0lOVDY0OgorICAgICAgICAgICAgICAgICAgICAgICAgTG9uZyBzaW50NjRWYWx1ZSA9IChMb25nKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NE5vVGFnKHNpbnQ2NFZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5rbm93biB0eXBlICIgKyB0eXBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlUmVwZWF0ZWREYXRhKE9iamVjdCBhcnJheSwgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQpIHsKKyAgICAgICAgICAgIGlmICh0YWcgPT0gbm9uUGFja2VkVGFnKSB7CisgICAgICAgICAgICAgICAgLy8gVXNlIGJhc2UgaW1wbGVtZW50YXRpb24gZm9yIG5vbi1wYWNrZWQgZGF0YQorICAgICAgICAgICAgICAgIHN1cGVyLndyaXRlUmVwZWF0ZWREYXRhKGFycmF5LCBvdXRwdXQpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gcGFja2VkVGFnKSB7CisgICAgICAgICAgICAgICAgLy8gUGFja2VkLiBOb3RlIHRoYXQgdGhlIGFycmF5IGVsZW1lbnQgdHlwZSBpcyBndWFyYW50ZWVkIHRvIGJlIHByaW1pdGl2ZSwgc28gdGhlcmUKKyAgICAgICAgICAgICAgICAvLyB3b24ndCBiZSBhbnkgbnVsbCBlbGVtZW50cywgc28gbm8gbnVsbCBjaGVjayBpbiB0aGlzIGJsb2NrLgorICAgICAgICAgICAgICAgIGludCBhcnJheUxlbmd0aCA9IEFycmF5LmdldExlbmd0aChhcnJheSk7CisgICAgICAgICAgICAgICAgaW50IGRhdGFTaXplID0gY29tcHV0ZVBhY2tlZERhdGFTaXplKGFycmF5KTsKKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKHRhZyk7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKGRhdGFTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfQk9PTDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKEFycmF5LmdldEJvb2xlYW4oYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRklYRUQzMjoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKEFycmF5LmdldEludChhcnJheSwgaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TRklYRUQzMjoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhBcnJheS5nZXRJbnQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcoQXJyYXkuZ2V0RmxvYXQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRklYRUQ2NDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NE5vVGFnKEFycmF5LmdldExvbmcoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU0ZJWEVENjQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcoQXJyYXkuZ2V0TG9uZyhhcnJheSwgaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9ET1VCTEU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZURvdWJsZU5vVGFnKEFycmF5LmdldERvdWJsZShhcnJheSwgaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9JTlQzMjoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50MzJOb1RhZyhBcnJheS5nZXRJbnQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU0lOVDMyOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVTSW50MzJOb1RhZyhBcnJheS5nZXRJbnQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfVUlOVDMyOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhBcnJheS5nZXRJbnQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcoQXJyYXkuZ2V0TG9uZyhhcnJheSwgaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NE5vVGFnKEFycmF5LmdldExvbmcoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfVUlOVDY0OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhBcnJheS5nZXRMb25nKGFycmF5LCBpKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0VOVU06CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhBcnJheS5nZXRJbnQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVucGFja2FibGUgdHlwZSAiICsgdHlwZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuLgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5leHBlY3RlZCByZXBlYXRlZCBleHRlbnNpb24gdGFnICIgKyB0YWcKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgdW5lcXVhbCB0byBib3RoIG5vbi1wYWNrZWQgdmFyaWFudCAiICsgbm9uUGFja2VkVGFnCisgICAgICAgICAgICAgICAgICAgICAgICArICIgYW5kIHBhY2tlZCB2YXJpYW50ICIgKyBwYWNrZWRUYWcpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgY29tcHV0ZVBhY2tlZERhdGFTaXplKE9iamVjdCBhcnJheSkgeworICAgICAgICAgICAgaW50IGRhdGFTaXplID0gMDsKKyAgICAgICAgICAgIGludCBhcnJheUxlbmd0aCA9IEFycmF5LmdldExlbmd0aChhcnJheSk7CisgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfQk9PTDoKKyAgICAgICAgICAgICAgICAgICAgLy8gQm9vbHMgYXJlIHN0b3JlZCBhcyBpbnQzMiBidXQganVzdCBhcyAwIG9yIDEsIHNvIDEgYnl0ZSBlYWNoLgorICAgICAgICAgICAgICAgICAgICBkYXRhU2l6ZSA9IGFycmF5TGVuZ3RoOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRklYRUQzMjoKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU0ZJWEVEMzI6CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgICAgICBkYXRhU2l6ZSA9IGFycmF5TGVuZ3RoICogQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5MSVRUTEVfRU5ESUFOXzMyX1NJWkU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9GSVhFRDY0OgorICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TRklYRUQ2NDoKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgICAgICBkYXRhU2l6ZSA9IGFycmF5TGVuZ3RoICogQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5MSVRUTEVfRU5ESUFOXzY0X1NJWkU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9JTlQzMjoKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU2l6ZSArPSBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVJbnQzMlNpemVOb1RhZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuZ2V0SW50KGFycmF5LCBpKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1NJTlQzMjoKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU2l6ZSArPSBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVTSW50MzJTaXplTm9UYWcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5LmdldEludChhcnJheSwgaSkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9VSU5UMzI6CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNpemUgKz0gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlVUludDMyU2l6ZU5vVGFnKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5nZXRJbnQoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNpemUgKz0gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlSW50NjRTaXplTm9UYWcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5LmdldExvbmcoYXJyYXksIGkpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfU0lOVDY0OgorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTaXplICs9IENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZVNJbnQ2NFNpemVOb1RhZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuZ2V0TG9uZyhhcnJheSwgaSkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9VSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNpemUgKz0gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlVUludDY0U2l6ZU5vVGFnKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5nZXRMb25nKGFycmF5LCBpKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0VOVU06CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNpemUgKz0gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlRW51bVNpemVOb1RhZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuZ2V0SW50KGFycmF5LCBpKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5leHBlY3RlZCBub24tcGFja2FibGUgdHlwZSAiICsgdHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZGF0YVNpemU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBjb21wdXRlUmVwZWF0ZWRTZXJpYWxpemVkU2l6ZShPYmplY3QgYXJyYXkpIHsKKyAgICAgICAgICAgIGlmICh0YWcgPT0gbm9uUGFja2VkVGFnKSB7CisgICAgICAgICAgICAgICAgLy8gVXNlIGJhc2UgaW1wbGVtZW50YXRpb24gZm9yIG5vbi1wYWNrZWQgZGF0YQorICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5jb21wdXRlUmVwZWF0ZWRTZXJpYWxpemVkU2l6ZShhcnJheSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSBwYWNrZWRUYWcpIHsKKyAgICAgICAgICAgICAgICAvLyBQYWNrZWQuCisgICAgICAgICAgICAgICAgaW50IGRhdGFTaXplID0gY29tcHV0ZVBhY2tlZERhdGFTaXplKGFycmF5KTsKKyAgICAgICAgICAgICAgICBpbnQgcGF5bG9hZFNpemUgPQorICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNpemUgKyBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZGF0YVNpemUpOworICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkU2l6ZSArIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZVJhd1ZhcmludDMyU2l6ZSh0YWcpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmV4cGVjdGVkIHJlcGVhdGVkIGV4dGVuc2lvbiB0YWcgIiArIHRhZworICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCB1bmVxdWFsIHRvIGJvdGggbm9uLXBhY2tlZCB2YXJpYW50ICIgKyBub25QYWNrZWRUYWcKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBhbmQgcGFja2VkIHZhcmlhbnQgIiArIHBhY2tlZFRhZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGludCBjb21wdXRlU2luZ3VsYXJTZXJpYWxpemVkU2l6ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIGludCBmaWVsZE51bWJlciA9IFdpcmVGb3JtYXROYW5vLmdldFRhZ0ZpZWxkTnVtYmVyKHRhZyk7CisgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgICAgICBEb3VibGUgZG91YmxlVmFsdWUgPSAoRG91YmxlKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZURvdWJsZVNpemUoZmllbGROdW1iZXIsIGRvdWJsZVZhbHVlKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgICAgIEZsb2F0IGZsb2F0VmFsdWUgPSAoRmxvYXQpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlRmxvYXRTaXplKGZpZWxkTnVtYmVyLCBmbG9hdFZhbHVlKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgIExvbmcgaW50NjRWYWx1ZSA9IChMb25nKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZUludDY0U2l6ZShmaWVsZE51bWJlciwgaW50NjRWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1VJTlQ2NDoKKyAgICAgICAgICAgICAgICAgICAgTG9uZyB1aW50NjRWYWx1ZSA9IChMb25nKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZVVJbnQ2NFNpemUoZmllbGROdW1iZXIsIHVpbnQ2NFZhbHVlKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfSU5UMzI6CisgICAgICAgICAgICAgICAgICAgIEludGVnZXIgaW50MzJWYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZUludDMyU2l6ZShmaWVsZE51bWJlciwgaW50MzJWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0ZJWEVENjQ6CisgICAgICAgICAgICAgICAgICAgIExvbmcgZml4ZWQ2NFZhbHVlID0gKExvbmcpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlRml4ZWQ2NFNpemUoZmllbGROdW1iZXIsIGZpeGVkNjRWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0ZJWEVEMzI6CisgICAgICAgICAgICAgICAgICAgIEludGVnZXIgZml4ZWQzMlZhbHVlID0gKEludGVnZXIpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlRml4ZWQzMlNpemUoZmllbGROdW1iZXIsIGZpeGVkMzJWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0JPT0w6CisgICAgICAgICAgICAgICAgICAgIEJvb2xlYW4gYm9vbFZhbHVlID0gKEJvb2xlYW4pIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlQm9vbFNpemUoZmllbGROdW1iZXIsIGJvb2xWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1NUUklORzoKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN0cmluZ1ZhbHVlID0gKFN0cmluZykgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVTdHJpbmdTaXplKGZpZWxkTnVtYmVyLCBzdHJpbmdWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0JZVEVTOgorICAgICAgICAgICAgICAgICAgICBieXRlW10gYnl0ZXNWYWx1ZSA9IChieXRlW10pIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlQnl0ZXNTaXplKGZpZWxkTnVtYmVyLCBieXRlc1ZhbHVlKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRZUEVfVUlOVDMyOgorICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyIHVpbnQzMlZhbHVlID0gKEludGVnZXIpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlVUludDMyU2l6ZShmaWVsZE51bWJlciwgdWludDMyVmFsdWUpOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9FTlVNOgorICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyIGVudW1WYWx1ZSA9IChJbnRlZ2VyKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZUVudW1TaXplKGZpZWxkTnVtYmVyLCBlbnVtVmFsdWUpOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TRklYRUQzMjoKKyAgICAgICAgICAgICAgICAgICAgSW50ZWdlciBzZml4ZWQzMlZhbHVlID0gKEludGVnZXIpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlU0ZpeGVkMzJTaXplKGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmaXhlZDMyVmFsdWUpOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TRklYRUQ2NDoKKyAgICAgICAgICAgICAgICAgICAgTG9uZyBzZml4ZWQ2NFZhbHVlID0gKExvbmcpIHZhbHVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlU0ZpeGVkNjRTaXplKGZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmaXhlZDY0VmFsdWUpOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9TSU5UMzI6CisgICAgICAgICAgICAgICAgICAgIEludGVnZXIgc2ludDMyVmFsdWUgPSAoSW50ZWdlcikgdmFsdWU7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVTSW50MzJTaXplKGZpZWxkTnVtYmVyLCBzaW50MzJWYWx1ZSk7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX1NJTlQ2NDoKKyAgICAgICAgICAgICAgICAgICAgTG9uZyBzaW50NjRWYWx1ZSA9IChMb25nKSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZVNJbnQ2NFNpemUoZmllbGROdW1iZXIsIHNpbnQ2NFZhbHVlKTsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHR5cGUgIiArIHR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRmllbGRBcnJheS5qYXZhIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRmllbGRBcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNkYjY2ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9GaWVsZEFycmF5LmphdmEKQEAgLTAsMCArMSwyNzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworCisvKioKKyAqIEEgY3VzdG9tIHZlcnNpb24gb2Yge0BsaW5rIGFuZHJvaWQudXRpbC5TcGFyc2VBcnJheX0gd2l0aCB0aGUgbWluaW1hbCBBUEkKKyAqIGZvciBzdG9yaW5nIHtAbGluayBGaWVsZERhdGF9IG9iamVjdHMuCisgKgorICogQmFzZWQgb24ge0BsaW5rIGFuZHJvaWQuc3VwcG9ydC52NC51dGlsLlNwYXJlQXJyYXlDb21wYXR9LgorICovCitjbGFzcyBGaWVsZEFycmF5IHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZERhdGEgREVMRVRFRCA9IG5ldyBGaWVsZERhdGEoKTsKKyAgICBwcml2YXRlIGJvb2xlYW4gbUdhcmJhZ2UgPSBmYWxzZTsKKworICAgIHByaXZhdGUgaW50W10gbUZpZWxkTnVtYmVyczsKKyAgICBwcml2YXRlIEZpZWxkRGF0YVtdIG1EYXRhOworICAgIHByaXZhdGUgaW50IG1TaXplOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBGaWVsZEFycmF5IGNvbnRhaW5pbmcgbm8gZmllbGRzLgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZEFycmF5KCkgeworICAgICAgICB0aGlzKDEwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEZpZWxkQXJyYXkgY29udGFpbmluZyBubyBtYXBwaW5ncyB0aGF0IHdpbGwgbm90CisgICAgICogcmVxdWlyZSBhbnkgYWRkaXRpb25hbCBtZW1vcnkgYWxsb2NhdGlvbiB0byBzdG9yZSB0aGUgc3BlY2lmaWVkCisgICAgICogbnVtYmVyIG9mIG1hcHBpbmdzLgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZEFycmF5KGludCBpbml0aWFsQ2FwYWNpdHkpIHsKKyAgICAgICAgaW5pdGlhbENhcGFjaXR5ID0gaWRlYWxJbnRBcnJheVNpemUoaW5pdGlhbENhcGFjaXR5KTsKKyAgICAgICAgbUZpZWxkTnVtYmVycyA9IG5ldyBpbnRbaW5pdGlhbENhcGFjaXR5XTsKKyAgICAgICAgbURhdGEgPSBuZXcgRmllbGREYXRhW2luaXRpYWxDYXBhY2l0eV07CisgICAgICAgIG1TaXplID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBGaWVsZERhdGEgbWFwcGVkIGZyb20gdGhlIHNwZWNpZmllZCBmaWVsZE51bWJlciwgb3IgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiBpZiBubyBzdWNoIG1hcHBpbmcgaGFzIGJlZW4gbWFkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmllbGREYXRhIGdldChpbnQgZmllbGROdW1iZXIpIHsKKyAgICAgICAgaW50IGkgPSBiaW5hcnlTZWFyY2goZmllbGROdW1iZXIpOworCisgICAgICAgIGlmIChpIDwgMCB8fCBtRGF0YVtpXSA9PSBERUxFVEVEKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBtRGF0YVtpXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkIGZpZWxkTnVtYmVyLCBpZiB0aGVyZSB3YXMgYW55LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZShpbnQgZmllbGROdW1iZXIpIHsKKyAgICAgICAgaW50IGkgPSBiaW5hcnlTZWFyY2goZmllbGROdW1iZXIpOworCisgICAgICAgIGlmIChpID49IDAgJiYgbURhdGFbaV0gIT0gREVMRVRFRCkgeworICAgICAgICAgICAgbURhdGFbaV0gPSBERUxFVEVEOworICAgICAgICAgICAgbUdhcmJhZ2UgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGdjKCkgeworICAgICAgICBpbnQgbiA9IG1TaXplOworICAgICAgICBpbnQgbyA9IDA7CisgICAgICAgIGludFtdIGtleXMgPSBtRmllbGROdW1iZXJzOworICAgICAgICBGaWVsZERhdGFbXSB2YWx1ZXMgPSBtRGF0YTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICAgICAgRmllbGREYXRhIHZhbCA9IHZhbHVlc1tpXTsKKworICAgICAgICAgICAgaWYgKHZhbCAhPSBERUxFVEVEKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgIT0gbykgeworICAgICAgICAgICAgICAgICAgICBrZXlzW29dID0ga2V5c1tpXTsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWVzW29dID0gdmFsOworICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbaV0gPSBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG8rKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIG1HYXJiYWdlID0gZmFsc2U7CisgICAgICAgIG1TaXplID0gbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbWFwcGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgZmllbGROdW1iZXIgdG8gdGhlIHNwZWNpZmllZCBkYXRhLAorICAgICAqIHJlcGxhY2luZyB0aGUgcHJldmlvdXMgbWFwcGluZyBpZiB0aGVyZSB3YXMgb25lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChpbnQgZmllbGROdW1iZXIsIEZpZWxkRGF0YSBkYXRhKSB7CisgICAgICAgIGludCBpID0gYmluYXJ5U2VhcmNoKGZpZWxkTnVtYmVyKTsKKworICAgICAgICBpZiAoaSA+PSAwKSB7CisgICAgICAgICAgICBtRGF0YVtpXSA9IGRhdGE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpID0gfmk7CisKKyAgICAgICAgICAgIGlmIChpIDwgbVNpemUgJiYgbURhdGFbaV0gPT0gREVMRVRFRCkgeworICAgICAgICAgICAgICAgIG1GaWVsZE51bWJlcnNbaV0gPSBmaWVsZE51bWJlcjsKKyAgICAgICAgICAgICAgICBtRGF0YVtpXSA9IGRhdGE7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobUdhcmJhZ2UgJiYgbVNpemUgPj0gbUZpZWxkTnVtYmVycy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBnYygpOworCisgICAgICAgICAgICAgICAgLy8gU2VhcmNoIGFnYWluIGJlY2F1c2UgaW5kaWNlcyBtYXkgaGF2ZSBjaGFuZ2VkLgorICAgICAgICAgICAgICAgIGkgPSB+IGJpbmFyeVNlYXJjaChmaWVsZE51bWJlcik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChtU2l6ZSA+PSBtRmllbGROdW1iZXJzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGludCBuID0gaWRlYWxJbnRBcnJheVNpemUobVNpemUgKyAxKTsKKworICAgICAgICAgICAgICAgIGludFtdIG5rZXlzID0gbmV3IGludFtuXTsKKyAgICAgICAgICAgICAgICBGaWVsZERhdGFbXSBudmFsdWVzID0gbmV3IEZpZWxkRGF0YVtuXTsKKworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobUZpZWxkTnVtYmVycywgMCwgbmtleXMsIDAsIG1GaWVsZE51bWJlcnMubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1EYXRhLCAwLCBudmFsdWVzLCAwLCBtRGF0YS5sZW5ndGgpOworCisgICAgICAgICAgICAgICAgbUZpZWxkTnVtYmVycyA9IG5rZXlzOworICAgICAgICAgICAgICAgIG1EYXRhID0gbnZhbHVlczsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG1TaXplIC0gaSAhPSAwKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtRmllbGROdW1iZXJzLCBpLCBtRmllbGROdW1iZXJzLCBpICsgMSwgbVNpemUgLSBpKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1EYXRhLCBpLCBtRGF0YSwgaSArIDEsIG1TaXplIC0gaSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG1GaWVsZE51bWJlcnNbaV0gPSBmaWVsZE51bWJlcjsKKyAgICAgICAgICAgIG1EYXRhW2ldID0gZGF0YTsKKyAgICAgICAgICAgIG1TaXplKys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Yga2V5LXZhbHVlIG1hcHBpbmdzIHRoYXQgdGhpcyBGaWVsZEFycmF5CisgICAgICogY3VycmVudGx5IHN0b3Jlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIGlmIChtR2FyYmFnZSkgeworICAgICAgICAgICAgZ2MoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtU2l6ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSgpID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2l2ZW4gYW4gaW5kZXggaW4gdGhlIHJhbmdlIDxjb2RlPjAuLi5zaXplKCktMTwvY29kZT4sIHJldHVybnMKKyAgICAgKiB0aGUgdmFsdWUgZnJvbSB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGgga2V5LXZhbHVlIG1hcHBpbmcgdGhhdCB0aGlzCisgICAgICogRmllbGRBcnJheSBzdG9yZXMuCisgICAgICovCisgICAgcHVibGljIEZpZWxkRGF0YSBkYXRhQXQoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChtR2FyYmFnZSkgeworICAgICAgICAgICAgZ2MoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtRGF0YVtpbmRleF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBGaWVsZEFycmF5KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgRmllbGRBcnJheSBvdGhlciA9IChGaWVsZEFycmF5KSBvOworICAgICAgICBpZiAoc2l6ZSgpICE9IG90aGVyLnNpemUoKSkgeyAgLy8gc2l6ZSgpIHdpbGwgY2FsbCBnYygpIGlmIG5lY2Vzc2FyeS4KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXJyYXlFcXVhbHMobUZpZWxkTnVtYmVycywgb3RoZXIubUZpZWxkTnVtYmVycywgbVNpemUpICYmCisgICAgICAgICAgICAgICAgYXJyYXlFcXVhbHMobURhdGEsIG90aGVyLm1EYXRhLCBtU2l6ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaWYgKG1HYXJiYWdlKSB7CisgICAgICAgICAgICBnYygpOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHQgPSAxNzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIG1GaWVsZE51bWJlcnNbaV07CisgICAgICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIG1EYXRhW2ldLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBpZGVhbEludEFycmF5U2l6ZShpbnQgbmVlZCkgeworICAgICAgICByZXR1cm4gaWRlYWxCeXRlQXJyYXlTaXplKG5lZWQgKiA0KSAvIDQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgaWRlYWxCeXRlQXJyYXlTaXplKGludCBuZWVkKSB7CisgICAgICAgIGZvciAoaW50IGkgPSA0OyBpIDwgMzI7IGkrKykKKyAgICAgICAgICAgIGlmIChuZWVkIDw9ICgxIDw8IGkpIC0gMTIpCisgICAgICAgICAgICAgICAgcmV0dXJuICgxIDw8IGkpIC0gMTI7CisKKyAgICAgICAgcmV0dXJuIG5lZWQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgYmluYXJ5U2VhcmNoKGludCB2YWx1ZSkgeworICAgICAgICBpbnQgbG8gPSAwOworICAgICAgICBpbnQgaGkgPSBtU2l6ZSAtIDE7CisKKyAgICAgICAgd2hpbGUgKGxvIDw9IGhpKSB7CisgICAgICAgICAgICBpbnQgbWlkID0gKGxvICsgaGkpID4+PiAxOworICAgICAgICAgICAgaW50IG1pZFZhbCA9IG1GaWVsZE51bWJlcnNbbWlkXTsKKworICAgICAgICAgICAgaWYgKG1pZFZhbCA8IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgbG8gPSBtaWQgKyAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWRWYWwgPiB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGhpID0gbWlkIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZDsgLy8gdmFsdWUgZm91bmQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gfmxvOyAvLyB2YWx1ZSBub3QgcHJlc2VudAorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBhcnJheUVxdWFscyhpbnRbXSBhLCBpbnRbXSBiLCBpbnQgc2l6ZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgaWYgKGFbaV0gIT0gYltpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gYXJyYXlFcXVhbHMoRmllbGREYXRhW10gYSwgRmllbGREYXRhW10gYiwgaW50IHNpemUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgIGlmICghYVtpXS5lcXVhbHMoYltpXSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRmllbGREYXRhLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9GaWVsZERhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMWVhZDg4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vRmllbGREYXRhLmphdmEKQEAgLTAsMCArMSwxOTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFN0b3JlcyB1bmtub3duIGZpZWxkcy4gVGhlc2UgbWlnaHQgYmUgZXh0ZW5zaW9ucyBvciBmaWVsZHMgdGhhdCB0aGUgZ2VuZXJhdGVkIEFQSSBkb2Vzbid0CisgKiBrbm93IGFib3V0IHlldC4KKyAqLworY2xhc3MgRmllbGREYXRhIHsKKyAgICBwcml2YXRlIEV4dGVuc2lvbjw/LCA/PiBjYWNoZWRFeHRlbnNpb247CisgICAgcHJpdmF0ZSBPYmplY3QgdmFsdWU7CisgICAgLyoqIFRoZSBzZXJpYWxpc2VkIHZhbHVlcyBmb3IgdGhpcyBvYmplY3QuIFdpbGwgYmUgY2xlYXJlZCBpZiBnZXRWYWx1ZSBpcyBjYWxsZWQgKi8KKyAgICBwcml2YXRlIExpc3Q8VW5rbm93bkZpZWxkRGF0YT4gdW5rbm93bkZpZWxkRGF0YTsKKworICAgIDxUPiBGaWVsZERhdGEoRXh0ZW5zaW9uPD8sIFQ+IGV4dGVuc2lvbiwgVCBuZXdWYWx1ZSkgeworICAgICAgICBjYWNoZWRFeHRlbnNpb24gPSBleHRlbnNpb247CisgICAgICAgIHZhbHVlID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgRmllbGREYXRhKCkgeworICAgICAgICB1bmtub3duRmllbGREYXRhID0gbmV3IEFycmF5TGlzdDxVbmtub3duRmllbGREYXRhPigpOworICAgIH0KKworICAgIHZvaWQgYWRkVW5rbm93bkZpZWxkKFVua25vd25GaWVsZERhdGEgdW5rbm93bkZpZWxkKSB7CisgICAgICAgIHVua25vd25GaWVsZERhdGEuYWRkKHVua25vd25GaWVsZCk7CisgICAgfQorCisgICAgVW5rbm93bkZpZWxkRGF0YSBnZXRVbmtub3duRmllbGQoaW50IGluZGV4KSB7CisgICAgICAgIGlmICh1bmtub3duRmllbGREYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChpbmRleCA8IHVua25vd25GaWVsZERhdGEuc2l6ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gdW5rbm93bkZpZWxkRGF0YS5nZXQoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIGludCBnZXRVbmtub3duRmllbGRTaXplKCkgeworICAgICAgICBpZiAodW5rbm93bkZpZWxkRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdW5rbm93bkZpZWxkRGF0YS5zaXplKCk7CisgICAgfQorCisgICAgPFQ+IFQgZ2V0VmFsdWUoRXh0ZW5zaW9uPD8sIFQ+IGV4dGVuc2lvbikgeworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCl7CisgICAgICAgICAgICBpZiAoY2FjaGVkRXh0ZW5zaW9uICE9IGV4dGVuc2lvbikgeyAgLy8gRXh0ZW5zaW9uIG9iamVjdHMgYXJlIHNpbmdsZXRvbnMuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJUcmllZCB0byBnZXRFeHRlbnNpb24gd2l0aCBhIGRpZmZlcmVybnQgRXh0ZW5zaW9uLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2FjaGVkRXh0ZW5zaW9uID0gZXh0ZW5zaW9uOworICAgICAgICAgICAgdmFsdWUgPSBleHRlbnNpb24uZ2V0VmFsdWVGcm9tKHVua25vd25GaWVsZERhdGEpOworICAgICAgICAgICAgdW5rbm93bkZpZWxkRGF0YSA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChUKSB2YWx1ZTsKKyAgICB9CisKKyAgICA8VD4gdm9pZCBzZXRWYWx1ZShFeHRlbnNpb248PywgVD4gZXh0ZW5zaW9uLCBUIG5ld1ZhbHVlKSB7CisgICAgICAgIGNhY2hlZEV4dGVuc2lvbiA9IGV4dGVuc2lvbjsKKyAgICAgICAgdmFsdWUgPSBuZXdWYWx1ZTsKKyAgICAgICAgdW5rbm93bkZpZWxkRGF0YSA9IG51bGw7CisgICAgfQorCisgICAgaW50IGNvbXB1dGVTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICAgICAgaW50IHNpemUgPSAwOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgc2l6ZSA9IGNhY2hlZEV4dGVuc2lvbi5jb21wdXRlU2VyaWFsaXplZFNpemUodmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChVbmtub3duRmllbGREYXRhIHVua25vd25GaWVsZCA6IHVua25vd25GaWVsZERhdGEpIHsKKyAgICAgICAgICAgICAgICBzaXplICs9IHVua25vd25GaWVsZC5jb21wdXRlU2VyaWFsaXplZFNpemUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICB2b2lkIHdyaXRlVG8oQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBjYWNoZWRFeHRlbnNpb24ud3JpdGVUbyh2YWx1ZSwgb3V0cHV0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoVW5rbm93bkZpZWxkRGF0YSB1bmtub3duRmllbGQgOiB1bmtub3duRmllbGREYXRhKSB7CisgICAgICAgICAgICAgICAgdW5rbm93bkZpZWxkLndyaXRlVG8ob3V0cHV0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgRmllbGREYXRhKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgRmllbGREYXRhIG90aGVyID0gKEZpZWxkRGF0YSkgbzsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiYgb3RoZXIudmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gSWYgYm90aCBvYmplY3RzIGhhdmUgZGVzZXJpYWxpemVkIHZhbHVlcywgY29tcGFyZSB0aG9zZS4KKyAgICAgICAgICAgIC8vIFNpbmNlIHVua25vd24gZmllbGRzIGFyZSBvbmx5IGNvbXBhcmVkIGlmIG1lc3NhZ2VzIGhhdmUgZ2VuZXJhdGVkIGVxdWFscyBtZXRob2RzCisgICAgICAgICAgICAvLyB3ZSBrbm93IHRoaXMgd2lsbCBiZSBhIG1lYW5pbmdmdWwgY29tcGFyaXNvbiAobm90IGlkZW50aXR5KSBmb3IgYWxsIHZhbHVlcy4KKyAgICAgICAgICAgIGlmIChjYWNoZWRFeHRlbnNpb24gIT0gb3RoZXIuY2FjaGVkRXh0ZW5zaW9uKSB7ICAvLyBFeHRlbnNpb24gb2JqZWN0cyBhcmUgc2luZ2xldG9ucy4KKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWNhY2hlZEV4dGVuc2lvbi5jbGF6ei5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICAvLyBDYW4ndCB0ZXN0ICghY2FjaGVkRXh0ZW5zaW9uLnJlcGVhdGVkKSBkdWUgdG8gJ2J5dGVzJyAtPiAnYnl0ZVtdJworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5lcXVhbHMob3RoZXIudmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGJ5dGVbXSkgdmFsdWUsIChieXRlW10pIG90aGVyLnZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBpbnRbXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChpbnRbXSkgdmFsdWUsIChpbnRbXSkgb3RoZXIudmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIGxvbmdbXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChsb25nW10pIHZhbHVlLCAobG9uZ1tdKSBvdGhlci52YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgZmxvYXRbXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChmbG9hdFtdKSB2YWx1ZSwgKGZsb2F0W10pIG90aGVyLnZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBkb3VibGVbXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChkb3VibGVbXSkgdmFsdWUsIChkb3VibGVbXSkgb3RoZXIudmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIGJvb2xlYW5bXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChib29sZWFuW10pIHZhbHVlLCAoYm9vbGVhbltdKSBvdGhlci52YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZGVlcEVxdWFscygoT2JqZWN0W10pIHZhbHVlLCAoT2JqZWN0W10pIG90aGVyLnZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAodW5rbm93bkZpZWxkRGF0YSAhPSBudWxsICYmIG90aGVyLnVua25vd25GaWVsZERhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gSWYgYm90aCBvYmplY3RzIGhhdmUgYnl0ZSBhcnJheXMgY29tcGFyZSB0aG9zZSBkaXJlY3RseS4KKyAgICAgICAgICAgIHJldHVybiB1bmtub3duRmllbGREYXRhLmVxdWFscyhvdGhlci51bmtub3duRmllbGREYXRhKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gQXMgYSBsYXN0IHJlc29ydCwgc2VyaWFsaXplIGFuZCBjb21wYXJlIHRoZSByZXN1bHRpbmcgYnl0ZSBhcnJheXMuCisgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyh0b0J5dGVBcnJheSgpLCBvdGhlci50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4uCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IDE3OworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gVGhlIG9ubHkgd2F5IHRvIGdlbmVyYXRlIGEgY29uc2lzdGVudCBoYXNoIGlzIHRvIHVzZSB0aGUgc2VyaWFsaXplZCBmb3JtLgorICAgICAgICAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBBcnJheXMuaGFzaENvZGUodG9CeXRlQXJyYXkoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuLgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIHRvQnl0ZUFycmF5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2NvbXB1dGVTZXJpYWxpemVkU2l6ZSgpXTsKKyAgICAgICAgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQgPSBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLm5ld0luc3RhbmNlKHJlc3VsdCk7CisgICAgICAgIHdyaXRlVG8ob3V0cHV0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0ludGVybmFsTmFuby5qYXZhIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vSW50ZXJuYWxOYW5vLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGEwOGJiNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0ludGVybmFsTmFuby5qYXZhCkBAIC0wLDAgKzEsNTU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm87CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTWFwRmFjdG9yaWVzLk1hcEZhY3Rvcnk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworLyoqCisgKiBUaGUgY2xhc3NlcyBjb250YWluZWQgd2l0aGluIGFyZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIFByb3RvY29sIEJ1ZmZlcgorICogbGlicmFyeSBhbmQgZ2VuZXJhdGVkIG1lc3NhZ2UgaW1wbGVtZW50YXRpb25zLiBUaGV5IGFyZSBwdWJsaWMgb25seSBiZWNhdXNlCisgKiB0aG9zZSBnZW5lcmF0ZWQgbWVzc2FnZXMgZG8gbm90IHJlc2lkZSBpbiB0aGUge0Bjb2RlIHByb3RvYnVmfSBwYWNrYWdlLgorICogT3RoZXJzIHNob3VsZCBub3QgdXNlIHRoaXMgY2xhc3MgZGlyZWN0bHkuCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSW50ZXJuYWxOYW5vIHsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0RPVUJMRSAgID0gMTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9GTE9BVCAgICA9IDI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfSU5UNjQgICAgPSAzOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1VJTlQ2NCAgID0gNDsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9JTlQzMiAgICA9IDU7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRklYRUQ2NCAgPSA2OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZJWEVEMzIgID0gNzsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CT09MICAgICA9IDg7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfU1RSSU5HICAgPSA5OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0dST1VQICAgID0gMTA7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfTUVTU0FHRSAgPSAxMTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CWVRFUyAgICA9IDEyOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1VJTlQzMiAgID0gMTM7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRU5VTSAgICAgPSAxNDsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9TRklYRUQzMiA9IDE1OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1NGSVhFRDY0ID0gMTY7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfU0lOVDMyICAgPSAxNzsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9TSU5UNjQgICA9IDE4OworCisKKyAgcHJpdmF0ZSBJbnRlcm5hbE5hbm8oKSB7fQorCisgIC8qKgorICAgKiBBbiBvYmplY3QgdG8gcHJvdmlkZSBzeW5jaHJvbml6YXRpb24gd2hlbiBsYXppbHkgaW5pdGlhbGl6aW5nIHN0YXRpYyBmaWVsZHMKKyAgICogb2Yge0BsaW5rIE1lc3NhZ2VOYW5vfSBzdWJjbGFzc2VzLgorICAgKiA8cD4KKyAgICogVG8gZW5hYmxlIGVhcmxpZXIgdmVyc2lvbnMgb2YgUHJvR3VhcmQgdG8gaW5saW5lIHNob3J0IG1ldGhvZHMgZnJvbSBhCisgICAqIGdlbmVyYXRlZCBNZXNzYWdlTmFubyBzdWJjbGFzcyB0byB0aGUgY2FsbCBzaXRlcywgdGhhdCBjbGFzcyBtdXN0IG5vdCBoYXZlCisgICAqIGEgY2xhc3MgaW5pdGlhbGl6ZXIsIHdoaWNoIHdpbGwgYmUgY3JlYXRlZCBpZiB0aGVyZSBpcyBhbnkgc3RhdGljIHZhcmlhYmxlCisgICAqIGluaXRpYWxpemVycy4gVG8gbGF6aWx5IGluaXRpYWxpemUgdGhlIHN0YXRpYyB2YXJpYWJsZXMgaW4gYSB0aHJlYWQtc2FmZQorICAgKiBtYW5uZXIsIHRoZSBpbml0aWFsaXphdGlvbiBjb2RlIHdpbGwgc3luY2hyb25pemUgb24gdGhpcyBvYmplY3QuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBMQVpZX0lOSVRfTE9DSyA9IG5ldyBPYmplY3QoKTsKKworICAvKioKKyAgICogSGVscGVyIGNhbGxlZCBieSBnZW5lcmF0ZWQgY29kZSB0byBjb25zdHJ1Y3QgZGVmYXVsdCB2YWx1ZXMgZm9yIHN0cmluZworICAgKiBmaWVsZHMuCisgICAqIDxwPgorICAgKiBUaGUgcHJvdG9jb2wgY29tcGlsZXIgZG9lcyBub3QgYWN0dWFsbHkgY29udGFpbiBhIFVURi04IGRlY29kZXIgLS0gaXQKKyAgICoganVzdCBwdXNoZXMgVVRGLTgtZW5jb2RlZCB0ZXh0IGFyb3VuZCB3aXRob3V0IHRvdWNoaW5nIGl0LiAgVGhlIG9uZSBwbGFjZQorICAgKiB3aGVyZSB0aGlzIHByZXNlbnRzIGEgcHJvYmxlbSBpcyB3aGVuIGdlbmVyYXRpbmcgSmF2YSBzdHJpbmcgbGl0ZXJhbHMuCisgICAqIFVuaWNvZGUgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIGxpdGVyYWwgd291bGQgbm9ybWFsbHkgbmVlZCB0byBiZSBlbmNvZGVkCisgICAqIHVzaW5nIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UsIHdoaWNoIHdvdWxkIHJlcXVpcmUgZGVjb2RpbmcgdGhlbS4KKyAgICogVG8gZ2V0IGFyb3VuZCB0aGlzLCBwcm90b2MgaW5zdGVhZCBlbWJlZHMgdGhlIFVURi04IGJ5dGVzIGludG8gdGhlCisgICAqIGdlbmVyYXRlZCBjb2RlIGFuZCBsZWF2ZXMgaXQgdG8gdGhlIHJ1bnRpbWUgbGlicmFyeSB0byBkZWNvZGUgdGhlbS4KKyAgICogPHA+CisgICAqIEl0IGdldHMgd29yc2UsIHRob3VnaC4gIElmIHByb3RvYyBqdXN0IGdlbmVyYXRlZCBhIGJ5dGUgYXJyYXksIGxpa2U6CisgICAqICAgbmV3IGJ5dGVbXSB7MHgxMiwgMHgzNCwgMHg1NiwgMHg3OH0KKyAgICogSmF2YSBhY3R1YWxseSBnZW5lcmF0ZXMgKmNvZGUqIHdoaWNoIGFsbG9jYXRlcyBhbiBhcnJheSBhbmQgdGhlbiBmaWxscworICAgKiBpbiBlYWNoIHZhbHVlLiAgVGhpcyBpcyBtdWNoIGxlc3MgZWZmaWNpZW50IHRoYW4ganVzdCBlbWJlZGRpbmcgdGhlIGJ5dGVzCisgICAqIGRpcmVjdGx5IGludG8gdGhlIGJ5dGVjb2RlLiAgVG8gZ2V0IGFyb3VuZCB0aGlzLCB3ZSBuZWVkIGFub3RoZXIKKyAgICogd29yay1hcm91bmQuICBTdHJpbmcgbGl0ZXJhbHMgYXJlIGVtYmVkZGVkIGRpcmVjdGx5LCBzbyBwcm90b2MgYWN0dWFsbHkKKyAgICogZ2VuZXJhdGVzIGEgc3RyaW5nIGxpdGVyYWwgY29ycmVzcG9uZGluZyB0byB0aGUgYnl0ZXMuICBUaGUgZWFzaWVzdCB3YXkKKyAgICogdG8gZG8gdGhpcyBpcyB0byB1c2UgdGhlIElTTy04ODU5LTEgY2hhcmFjdGVyIHNldCwgd2hpY2ggY29ycmVzcG9uZHMgdG8KKyAgICogdGhlIGZpcnN0IDI1NiBjaGFyYWN0ZXJzIG9mIHRoZSBVbmljb2RlIHJhbmdlLiAgUHJvdG9jIGNhbiB0aGVuIHVzZQorICAgKiBnb29kIG9sZCBDRXNjYXBlIHRvIGdlbmVyYXRlIHRoZSBzdHJpbmcuCisgICAqIDxwPgorICAgKiBTbyB3ZSBoYXZlIGEgc3RyaW5nIGxpdGVyYWwgd2hpY2ggcmVwcmVzZW50cyBhIHNldCBvZiBieXRlcyB3aGljaAorICAgKiByZXByZXNlbnRzIGFub3RoZXIgc3RyaW5nLiAgVGhpcyBmdW5jdGlvbiAtLSBzdHJpbmdEZWZhdWx0VmFsdWUgLS0KKyAgICogY29udmVydHMgZnJvbSB0aGUgZ2VuZXJhdGVkIHN0cmluZyB0byB0aGUgc3RyaW5nIHdlIGFjdHVhbGx5IHdhbnQuICBUaGUKKyAgICogZ2VuZXJhdGVkIGNvZGUgY2FsbHMgdGhpcyBhdXRvbWF0aWNhbGx5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3RyaW5nRGVmYXVsdFZhbHVlKFN0cmluZyBieXRlcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gbmV3IFN0cmluZyhieXRlcy5nZXRCeXRlcygiSVNPLTg4NTktMSIpLCAiVVRGLTgiKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBzaW5jZSBhbGwgSlZNcyBhcmUgcmVxdWlyZWQgdG8gaW1wbGVtZW50CisgICAgICAvLyBib3RoIG9mIHRoZSBhYm92ZSBjaGFyYWN0ZXIgc2V0cy4KKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgIkphdmEgVk0gZG9lcyBub3Qgc3VwcG9ydCBhIHN0YW5kYXJkIGNoYXJhY3RlciBzZXQuIiwgZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBjYWxsZWQgYnkgZ2VuZXJhdGVkIGNvZGUgdG8gY29uc3RydWN0IGRlZmF1bHQgdmFsdWVzIGZvciBieXRlcworICAgKiBmaWVsZHMuCisgICAqIDxwPgorICAgKiBUaGlzIGlzIGEgbG90IGxpa2Uge0BsaW5rICNzdHJpbmdEZWZhdWx0VmFsdWV9LCBidXQgZm9yIGJ5dGVzIGZpZWxkcy4KKyAgICogSW4gdGhpcyBjYXNlIHdlIG9ubHkgbmVlZCB0aGUgc2Vjb25kIG9mIHRoZSB0d28gaGFja3MgLS0gYWxsb3dpbmcgdXMgdG8KKyAgICogZW1iZWQgcmF3IGJ5dGVzIGFzIGEgc3RyaW5nIGxpdGVyYWwgd2l0aCBJU08tODg1OS0xIGVuY29kaW5nLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlW10gYnl0ZXNEZWZhdWx0VmFsdWUoU3RyaW5nIGJ5dGVzKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBieXRlcy5nZXRCeXRlcygiSVNPLTg4NTktMSIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuIHNpbmNlIGFsbCBKVk1zIGFyZSByZXF1aXJlZCB0byBpbXBsZW1lbnQKKyAgICAgIC8vIElTTy04ODU5LTEuCisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICJKYXZhIFZNIGRvZXMgbm90IHN1cHBvcnQgYSBzdGFuZGFyZCBjaGFyYWN0ZXIgc2V0LiIsIGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gY29udmVydCBhIHN0cmluZyBpbnRvIFVURi04IHdoaWxlIHR1cm5pbmcgdGhlCisgICAqIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdG8gYSBSdW50aW1lRXhjZXB0aW9uLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlW10gY29weUZyb21VdGY4KGZpbmFsIFN0cmluZyB0ZXh0KSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiB0ZXh0LmdldEJ5dGVzKCJVVEYtOCIpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVURi04IG5vdCBzdXBwb3J0ZWQ/Iik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENoZWNrcyByZXBlYXRlZCBpbnQgZmllbGQgZXF1YWxpdHk7IG51bGwtdmFsdWUgYW5kIDAtbGVuZ3RoIGZpZWxkcyBhcmUKKyAgICogY29uc2lkZXJlZCBlcXVhbC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoaW50W10gZmllbGQxLCBpbnRbXSBmaWVsZDIpIHsKKyAgICBpZiAoZmllbGQxID09IG51bGwgfHwgZmllbGQxLmxlbmd0aCA9PSAwKSB7CisgICAgICByZXR1cm4gZmllbGQyID09IG51bGwgfHwgZmllbGQyLmxlbmd0aCA9PSAwOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhmaWVsZDEsIGZpZWxkMik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENoZWNrcyByZXBlYXRlZCBsb25nIGZpZWxkIGVxdWFsaXR5OyBudWxsLXZhbHVlIGFuZCAwLWxlbmd0aCBmaWVsZHMgYXJlCisgICAqIGNvbnNpZGVyZWQgZXF1YWwuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKGxvbmdbXSBmaWVsZDEsIGxvbmdbXSBmaWVsZDIpIHsKKyAgICBpZiAoZmllbGQxID09IG51bGwgfHwgZmllbGQxLmxlbmd0aCA9PSAwKSB7CisgICAgICByZXR1cm4gZmllbGQyID09IG51bGwgfHwgZmllbGQyLmxlbmd0aCA9PSAwOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhmaWVsZDEsIGZpZWxkMik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENoZWNrcyByZXBlYXRlZCBmbG9hdCBmaWVsZCBlcXVhbGl0eTsgbnVsbC12YWx1ZSBhbmQgMC1sZW5ndGggZmllbGRzIGFyZQorICAgKiBjb25zaWRlcmVkIGVxdWFsLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGVxdWFscyhmbG9hdFtdIGZpZWxkMSwgZmxvYXRbXSBmaWVsZDIpIHsKKyAgICBpZiAoZmllbGQxID09IG51bGwgfHwgZmllbGQxLmxlbmd0aCA9PSAwKSB7CisgICAgICByZXR1cm4gZmllbGQyID09IG51bGwgfHwgZmllbGQyLmxlbmd0aCA9PSAwOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhmaWVsZDEsIGZpZWxkMik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENoZWNrcyByZXBlYXRlZCBkb3VibGUgZmllbGQgZXF1YWxpdHk7IG51bGwtdmFsdWUgYW5kIDAtbGVuZ3RoIGZpZWxkcyBhcmUKKyAgICogY29uc2lkZXJlZCBlcXVhbC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoZG91YmxlW10gZmllbGQxLCBkb3VibGVbXSBmaWVsZDIpIHsKKyAgICBpZiAoZmllbGQxID09IG51bGwgfHwgZmllbGQxLmxlbmd0aCA9PSAwKSB7CisgICAgICByZXR1cm4gZmllbGQyID09IG51bGwgfHwgZmllbGQyLmxlbmd0aCA9PSAwOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhmaWVsZDEsIGZpZWxkMik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENoZWNrcyByZXBlYXRlZCBib29sZWFuIGZpZWxkIGVxdWFsaXR5OyBudWxsLXZhbHVlIGFuZCAwLWxlbmd0aCBmaWVsZHMgYXJlCisgICAqIGNvbnNpZGVyZWQgZXF1YWwuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKGJvb2xlYW5bXSBmaWVsZDEsIGJvb2xlYW5bXSBmaWVsZDIpIHsKKyAgICBpZiAoZmllbGQxID09IG51bGwgfHwgZmllbGQxLmxlbmd0aCA9PSAwKSB7CisgICAgICByZXR1cm4gZmllbGQyID09IG51bGwgfHwgZmllbGQyLmxlbmd0aCA9PSAwOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhmaWVsZDEsIGZpZWxkMik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENoZWNrcyByZXBlYXRlZCBieXRlcyBmaWVsZCBlcXVhbGl0eS4gT25seSBub24tbnVsbCBlbGVtZW50cyBhcmUgdGVzdGVkLgorICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBmaWVsZHMgaGF2ZSB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBub24tbnVsbAorICAgKiBlbGVtZW50cy4gTnVsbC12YWx1ZSBmaWVsZHMgYW5kIGZpZWxkcyBvZiBhbnkgbGVuZ3RoIHdpdGggb25seSBudWxsCisgICAqIGVsZW1lbnRzIGFyZSBjb25zaWRlcmVkIGVxdWFsLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGVxdWFscyhieXRlW11bXSBmaWVsZDEsIGJ5dGVbXVtdIGZpZWxkMikgeworICAgIGludCBpbmRleDEgPSAwOworICAgIGludCBsZW5ndGgxID0gZmllbGQxID09IG51bGwgPyAwIDogZmllbGQxLmxlbmd0aDsKKyAgICBpbnQgaW5kZXgyID0gMDsKKyAgICBpbnQgbGVuZ3RoMiA9IGZpZWxkMiA9PSBudWxsID8gMCA6IGZpZWxkMi5sZW5ndGg7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIHdoaWxlIChpbmRleDEgPCBsZW5ndGgxICYmIGZpZWxkMVtpbmRleDFdID09IG51bGwpIHsKKyAgICAgICAgaW5kZXgxKys7CisgICAgICB9CisgICAgICB3aGlsZSAoaW5kZXgyIDwgbGVuZ3RoMiAmJiBmaWVsZDJbaW5kZXgyXSA9PSBudWxsKSB7CisgICAgICAgIGluZGV4MisrOworICAgICAgfQorICAgICAgYm9vbGVhbiBhdEVuZE9mMSA9IGluZGV4MSA+PSBsZW5ndGgxOworICAgICAgYm9vbGVhbiBhdEVuZE9mMiA9IGluZGV4MiA+PSBsZW5ndGgyOworICAgICAgaWYgKGF0RW5kT2YxICYmIGF0RW5kT2YyKSB7CisgICAgICAgIC8vIG5vIG1vcmUgbm9uLW51bGwgZWxlbWVudHMgdG8gdGVzdCBpbiBib3RoIGFycmF5cworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gZWxzZSBpZiAoYXRFbmRPZjEgIT0gYXRFbmRPZjIpIHsKKyAgICAgICAgLy8gb25lIG9mIHRoZSBhcnJheXMgaGF2ZSBleHRyYSBub24tbnVsbCBlbGVtZW50cworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9IGVsc2UgaWYgKCFBcnJheXMuZXF1YWxzKGZpZWxkMVtpbmRleDFdLCBmaWVsZDJbaW5kZXgyXSkpIHsKKyAgICAgICAgLy8gZWxlbWVudCBtaXNtYXRjaAorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBpbmRleDErKzsKKyAgICAgIGluZGV4MisrOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDaGVja3MgcmVwZWF0ZWQgc3RyaW5nL21lc3NhZ2UgZmllbGQgZXF1YWxpdHkuIE9ubHkgbm9uLW51bGwgZWxlbWVudHMgYXJlCisgICAqIHRlc3RlZC4gUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gZmllbGRzIGhhdmUgdGhlIHNhbWUgc2VxdWVuY2Ugb2Ygbm9uLW51bGwKKyAgICogZWxlbWVudHMuIE51bGwtdmFsdWUgZmllbGRzIGFuZCBmaWVsZHMgb2YgYW55IGxlbmd0aCB3aXRoIG9ubHkgbnVsbAorICAgKiBlbGVtZW50cyBhcmUgY29uc2lkZXJlZCBlcXVhbC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0W10gZmllbGQxLCBPYmplY3RbXSBmaWVsZDIpIHsKKyAgICBpbnQgaW5kZXgxID0gMDsKKyAgICBpbnQgbGVuZ3RoMSA9IGZpZWxkMSA9PSBudWxsID8gMCA6IGZpZWxkMS5sZW5ndGg7CisgICAgaW50IGluZGV4MiA9IDA7CisgICAgaW50IGxlbmd0aDIgPSBmaWVsZDIgPT0gbnVsbCA/IDAgOiBmaWVsZDIubGVuZ3RoOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICB3aGlsZSAoaW5kZXgxIDwgbGVuZ3RoMSAmJiBmaWVsZDFbaW5kZXgxXSA9PSBudWxsKSB7CisgICAgICAgIGluZGV4MSsrOworICAgICAgfQorICAgICAgd2hpbGUgKGluZGV4MiA8IGxlbmd0aDIgJiYgZmllbGQyW2luZGV4Ml0gPT0gbnVsbCkgeworICAgICAgICBpbmRleDIrKzsKKyAgICAgIH0KKyAgICAgIGJvb2xlYW4gYXRFbmRPZjEgPSBpbmRleDEgPj0gbGVuZ3RoMTsKKyAgICAgIGJvb2xlYW4gYXRFbmRPZjIgPSBpbmRleDIgPj0gbGVuZ3RoMjsKKyAgICAgIGlmIChhdEVuZE9mMSAmJiBhdEVuZE9mMikgeworICAgICAgICAvLyBubyBtb3JlIG5vbi1udWxsIGVsZW1lbnRzIHRvIHRlc3QgaW4gYm90aCBhcnJheXMKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGVsc2UgaWYgKGF0RW5kT2YxICE9IGF0RW5kT2YyKSB7CisgICAgICAgIC8vIG9uZSBvZiB0aGUgYXJyYXlzIGhhdmUgZXh0cmEgbm9uLW51bGwgZWxlbWVudHMKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfSBlbHNlIGlmICghZmllbGQxW2luZGV4MV0uZXF1YWxzKGZpZWxkMltpbmRleDJdKSkgeworICAgICAgICAvLyBlbGVtZW50IG1pc21hdGNoCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGluZGV4MSsrOworICAgICAgaW5kZXgyKys7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbXB1dGVzIHRoZSBoYXNoIGNvZGUgb2YgYSByZXBlYXRlZCBpbnQgZmllbGQuIE51bGwtdmFsdWUgYW5kIDAtbGVuZ3RoCisgICAqIGZpZWxkcyBoYXZlIHRoZSBzYW1lIGhhc2ggY29kZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGludFtdIGZpZWxkKSB7CisgICAgcmV0dXJuIGZpZWxkID09IG51bGwgfHwgZmllbGQubGVuZ3RoID09IDAgPyAwIDogQXJyYXlzLmhhc2hDb2RlKGZpZWxkKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlcyB0aGUgaGFzaCBjb2RlIG9mIGEgcmVwZWF0ZWQgbG9uZyBmaWVsZC4gTnVsbC12YWx1ZSBhbmQgMC1sZW5ndGgKKyAgICogZmllbGRzIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2RlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUobG9uZ1tdIGZpZWxkKSB7CisgICAgcmV0dXJuIGZpZWxkID09IG51bGwgfHwgZmllbGQubGVuZ3RoID09IDAgPyAwIDogQXJyYXlzLmhhc2hDb2RlKGZpZWxkKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlcyB0aGUgaGFzaCBjb2RlIG9mIGEgcmVwZWF0ZWQgZmxvYXQgZmllbGQuIE51bGwtdmFsdWUgYW5kIDAtbGVuZ3RoCisgICAqIGZpZWxkcyBoYXZlIHRoZSBzYW1lIGhhc2ggY29kZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGZsb2F0W10gZmllbGQpIHsKKyAgICByZXR1cm4gZmllbGQgPT0gbnVsbCB8fCBmaWVsZC5sZW5ndGggPT0gMCA/IDAgOiBBcnJheXMuaGFzaENvZGUoZmllbGQpOworICB9CisKKyAgLyoqCisgICAqIENvbXB1dGVzIHRoZSBoYXNoIGNvZGUgb2YgYSByZXBlYXRlZCBkb3VibGUgZmllbGQuIE51bGwtdmFsdWUgYW5kIDAtbGVuZ3RoCisgICAqIGZpZWxkcyBoYXZlIHRoZSBzYW1lIGhhc2ggY29kZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGRvdWJsZVtdIGZpZWxkKSB7CisgICAgcmV0dXJuIGZpZWxkID09IG51bGwgfHwgZmllbGQubGVuZ3RoID09IDAgPyAwIDogQXJyYXlzLmhhc2hDb2RlKGZpZWxkKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlcyB0aGUgaGFzaCBjb2RlIG9mIGEgcmVwZWF0ZWQgYm9vbGVhbiBmaWVsZC4gTnVsbC12YWx1ZSBhbmQgMC1sZW5ndGgKKyAgICogZmllbGRzIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2RlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoYm9vbGVhbltdIGZpZWxkKSB7CisgICAgcmV0dXJuIGZpZWxkID09IG51bGwgfHwgZmllbGQubGVuZ3RoID09IDAgPyAwIDogQXJyYXlzLmhhc2hDb2RlKGZpZWxkKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlcyB0aGUgaGFzaCBjb2RlIG9mIGEgcmVwZWF0ZWQgYnl0ZXMgZmllbGQuIE9ubHkgdGhlIHNlcXVlbmNlIG9mIGFsbAorICAgKiBub24tbnVsbCBlbGVtZW50cyBhcmUgdXNlZCBpbiB0aGUgY29tcHV0YXRpb24uIE51bGwtdmFsdWUgZmllbGRzIGFuZCBmaWVsZHMKKyAgICogb2YgYW55IGxlbmd0aCB3aXRoIG9ubHkgbnVsbCBlbGVtZW50cyBoYXZlIHRoZSBzYW1lIGhhc2ggY29kZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGJ5dGVbXVtdIGZpZWxkKSB7CisgICAgaW50IHJlc3VsdCA9IDA7CisgICAgZm9yIChpbnQgaSA9IDAsIHNpemUgPSBmaWVsZCA9PSBudWxsID8gMCA6IGZpZWxkLmxlbmd0aDsgaSA8IHNpemU7IGkrKykgeworICAgICAgYnl0ZVtdIGVsZW1lbnQgPSBmaWVsZFtpXTsKKyAgICAgIGlmIChlbGVtZW50ICE9IG51bGwpIHsKKyAgICAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBBcnJheXMuaGFzaENvZGUoZWxlbWVudCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZXMgdGhlIGhhc2ggY29kZSBvZiBhIHJlcGVhdGVkIHN0cmluZy9tZXNzYWdlIGZpZWxkLiBPbmx5IHRoZQorICAgKiBzZXF1ZW5jZSBvZiBhbGwgbm9uLW51bGwgZWxlbWVudHMgYXJlIHVzZWQgaW4gdGhlIGNvbXB1dGF0aW9uLiBOdWxsLXZhbHVlCisgICAqIGZpZWxkcyBhbmQgZmllbGRzIG9mIGFueSBsZW5ndGggd2l0aCBvbmx5IG51bGwgZWxlbWVudHMgaGF2ZSB0aGUgc2FtZSBoYXNoCisgICAqIGNvZGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZShPYmplY3RbXSBmaWVsZCkgeworICAgIGludCByZXN1bHQgPSAwOworICAgIGZvciAoaW50IGkgPSAwLCBzaXplID0gZmllbGQgPT0gbnVsbCA/IDAgOiBmaWVsZC5sZW5ndGg7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgIE9iamVjdCBlbGVtZW50ID0gZmllbGRbaV07CisgICAgICBpZiAoZWxlbWVudCAhPSBudWxsKSB7CisgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgZWxlbWVudC5oYXNoQ29kZSgpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIHByaXZhdGUgc3RhdGljIE9iamVjdCBwcmltaXRpdmVEZWZhdWx0VmFsdWUoaW50IHR5cGUpIHsKKyAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgIGNhc2UgVFlQRV9CT09MOgorICAgICAgICByZXR1cm4gQm9vbGVhbi5GQUxTRTsKKyAgICAgIGNhc2UgVFlQRV9CWVRFUzoKKyAgICAgICAgcmV0dXJuIFdpcmVGb3JtYXROYW5vLkVNUFRZX0JZVEVTOworICAgICAgY2FzZSBUWVBFX1NUUklORzoKKyAgICAgICAgcmV0dXJuICIiOworICAgICAgY2FzZSBUWVBFX0ZMT0FUOgorICAgICAgICByZXR1cm4gRmxvYXQudmFsdWVPZigwKTsKKyAgICAgIGNhc2UgVFlQRV9ET1VCTEU6CisgICAgICAgIHJldHVybiBEb3VibGUudmFsdWVPZigwKTsKKyAgICAgIGNhc2UgVFlQRV9FTlVNOgorICAgICAgY2FzZSBUWVBFX0ZJWEVEMzI6CisgICAgICBjYXNlIFRZUEVfSU5UMzI6CisgICAgICBjYXNlIFRZUEVfVUlOVDMyOgorICAgICAgY2FzZSBUWVBFX1NJTlQzMjoKKyAgICAgIGNhc2UgVFlQRV9TRklYRUQzMjoKKyAgICAgICAgcmV0dXJuIEludGVnZXIudmFsdWVPZigwKTsKKyAgICAgIGNhc2UgVFlQRV9JTlQ2NDoKKyAgICAgIGNhc2UgVFlQRV9VSU5UNjQ6CisgICAgICBjYXNlIFRZUEVfU0lOVDY0OgorICAgICAgY2FzZSBUWVBFX0ZJWEVENjQ6CisgICAgICBjYXNlIFRZUEVfU0ZJWEVENjQ6CisgICAgICAgIHJldHVybiBMb25nLnZhbHVlT2YoMEwpOworICAgICAgY2FzZSBUWVBFX01FU1NBR0U6CisgICAgICBjYXNlIFRZUEVfR1JPVVA6CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIlR5cGU6ICIgKyB0eXBlICsgIiBpcyBub3QgYSBwcmltaXRpdmUgdHlwZS4iKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTWVyZ2VzIHRoZSBtYXAgZW50cnkgaW50byB0aGUgbWFwIGZpZWxkLiBOb3RlIHRoaXMgaXMgb25seSBzdXBwb3NlZCB0bworICAgKiBiZSBjYWxsZWQgYnkgZ2VuZXJhdGVkIG1lc3NhZ2VzLgorICAgKgorICAgKiBAcGFyYW0gbWFwIHRoZSBtYXAgZmllbGQ7IG1heSBiZSBudWxsLCBpbiB3aGljaCBjYXNlIGEgbWFwIHdpbGwgYmUKKyAgICogICAgICAgIGluc3RhbnRpYXRlZCB1c2luZyB0aGUge0BsaW5rIE1hcEZhY3Rvcmllcy5NYXBGYWN0b3J5fQorICAgKiBAcGFyYW0gaW5wdXQgdGhlIGlucHV0IGJ5dGUgYnVmZmVyCisgICAqIEBwYXJhbSBrZXlUeXBlIGtleSB0eXBlLCBhcyBkZWZpbmVkIGluIEludGVybmFsTmFuby5UWVBFXyoKKyAgICogQHBhcmFtIHZhbHVlVHlwZSB2YWx1ZSB0eXBlLCBhcyBkZWZpbmVkIGluIEludGVybmFsTmFuby5UWVBFXyoKKyAgICogQHBhcmFtIHZhbHVlIGFuIG5ldyBpbnN0YW5jZSBvZiB0aGUgdmFsdWUsIGlmIHRoZSB2YWx1ZSBpcyBhIFRZUEVfTUVTU0FHRTsKKyAgICogICAgICAgIG90aGVyd2lzZSB0aGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbCBhbmQgd2lsbCBiZSBpZ25vcmVkLgorICAgKiBAcGFyYW0ga2V5VGFnIHdpcmUgdGFnIGZvciB0aGUga2V5CisgICAqIEBwYXJhbSB2YWx1ZVRhZyB3aXJlIHRhZyBmb3IgdGhlIHZhbHVlCisgICAqIEByZXR1cm4gdGhlIG1hcCBmaWVsZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHN0YXRpYyBmaW5hbCA8SywgVj4gTWFwPEssIFY+IG1lcmdlTWFwRW50cnkoCisgICAgICBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8gaW5wdXQsCisgICAgICBNYXA8SywgVj4gbWFwLAorICAgICAgTWFwRmFjdG9yeSBtYXBGYWN0b3J5LAorICAgICAgaW50IGtleVR5cGUsCisgICAgICBpbnQgdmFsdWVUeXBlLAorICAgICAgViB2YWx1ZSwKKyAgICAgIGludCBrZXlUYWcsCisgICAgICBpbnQgdmFsdWVUYWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbWFwID0gbWFwRmFjdG9yeS5mb3JNYXAobWFwKTsKKyAgICBmaW5hbCBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CisgICAgZmluYWwgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CisgICAgSyBrZXkgPSBudWxsOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOworICAgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKHRhZyA9PSBrZXlUYWcpIHsKKyAgICAgICAga2V5ID0gKEspIGlucHV0LnJlYWRQcmltaXRpdmVGaWVsZChrZXlUeXBlKTsKKyAgICAgIH0gZWxzZSBpZiAodGFnID09IHZhbHVlVGFnKSB7CisgICAgICAgIGlmICh2YWx1ZVR5cGUgPT0gVFlQRV9NRVNTQUdFKSB7CisgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoKE1lc3NhZ2VOYW5vKSB2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdmFsdWUgPSAoVikgaW5wdXQucmVhZFByaW1pdGl2ZUZpZWxkKHZhbHVlVHlwZSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmICghaW5wdXQuc2tpcEZpZWxkKHRhZykpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBpbnB1dC5jaGVja0xhc3RUYWdXYXMoMCk7CisgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOworCisgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAvLyBrZXkgY2FuIG9ubHkgYmUgcHJpbWl0aXZlIHR5cGVzLgorICAgICAga2V5ID0gKEspIHByaW1pdGl2ZURlZmF1bHRWYWx1ZShrZXlUeXBlKTsKKyAgICB9CisKKyAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgLy8gbWVzc2FnZSB0eXBlIHZhbHVlIHdpbGwgYmUgaW5pdGlhbGl6ZWQgYnkgY29kZS1nZW4uCisgICAgICB2YWx1ZSA9IChWKSBwcmltaXRpdmVEZWZhdWx0VmFsdWUodmFsdWVUeXBlKTsKKyAgICB9CisKKyAgICBtYXAucHV0KGtleSwgdmFsdWUpOworICAgIHJldHVybiBtYXA7CisgIH0KKworICBwdWJsaWMgc3RhdGljIDxLLCBWPiB2b2lkIHNlcmlhbGl6ZU1hcEZpZWxkKAorICAgICAgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQsCisgICAgICBNYXA8SywgVj4gbWFwLCBpbnQgbnVtYmVyLCBpbnQga2V5VHlwZSwgaW50IHZhbHVlVHlwZSkKKyAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoRW50cnk8SywgVj4gZW50cnk6IG1hcC5lbnRyeVNldCgpKSB7CisgICAgICBLIGtleSA9IGVudHJ5LmdldEtleSgpOworICAgICAgViB2YWx1ZSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICBpZiAoa2V5ID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgImtleXMgYW5kIHZhbHVlcyBpbiBtYXBzIGNhbm5vdCBiZSBudWxsIik7CisgICAgICB9CisgICAgICBpbnQgZW50cnlTaXplID0KKyAgICAgICAgICBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVGaWVsZFNpemUoMSwga2V5VHlwZSwga2V5KSArCisgICAgICAgICAgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlRmllbGRTaXplKDIsIHZhbHVlVHlwZSwgdmFsdWUpOworICAgICAgb3V0cHV0LndyaXRlVGFnKG51bWJlciwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMihlbnRyeVNpemUpOworICAgICAgb3V0cHV0LndyaXRlRmllbGQoMSwga2V5VHlwZSwga2V5KTsKKyAgICAgIG91dHB1dC53cml0ZUZpZWxkKDIsIHZhbHVlVHlwZSwgdmFsdWUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPEssIFY+IGludCBjb21wdXRlTWFwRmllbGRTaXplKAorICAgICAgTWFwPEssIFY+IG1hcCwgaW50IG51bWJlciwgaW50IGtleVR5cGUsIGludCB2YWx1ZVR5cGUpIHsKKyAgICBpbnQgc2l6ZSA9IDA7CisgICAgaW50IHRhZ1NpemUgPSBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVUYWdTaXplKG51bWJlcik7CisgICAgZm9yIChFbnRyeTxLLCBWPiBlbnRyeTogbWFwLmVudHJ5U2V0KCkpIHsKKyAgICAgIEsga2V5ID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICBWIHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgIGlmIChrZXkgPT0gbnVsbCB8fCB2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAia2V5cyBhbmQgdmFsdWVzIGluIG1hcHMgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgIH0KKyAgICAgIGludCBlbnRyeVNpemUgPQorICAgICAgICAgIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZUZpZWxkU2l6ZSgxLCBrZXlUeXBlLCBrZXkpICsKKyAgICAgICAgICBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLmNvbXB1dGVGaWVsZFNpemUoMiwgdmFsdWVUeXBlLCB2YWx1ZSk7CisgICAgICBzaXplICs9IHRhZ1NpemUgKyBlbnRyeVNpemUKKyAgICAgICAgICArIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShlbnRyeVNpemUpOworICAgIH0KKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIC8qKgorICAgKiBDaGVja3Mgd2hldGhlciB0d28ge0BsaW5rIE1hcH0gYXJlIGVxdWFsLiBXZSBkb24ndCB1c2UgdGhlIGRlZmF1bHQgZXF1YWxzCisgICAqIG1ldGhvZCBvZiB7QGxpbmsgTWFwfSBiZWNhdXNlIGl0IGNvbXBhcmVzIGJ5IGlkZW50aXR5IG5vdCBieSBjb250ZW50IGZvcgorICAgKiBieXRlIGFycmF5cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgPEssIFY+IGJvb2xlYW4gZXF1YWxzKE1hcDxLLCBWPiBhLCBNYXA8SywgVj4gYikgeworICAgIGlmIChhID09IGIpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAoYSA9PSBudWxsKSB7CisgICAgICByZXR1cm4gYi5zaXplKCkgPT0gMDsKKyAgICB9CisgICAgaWYgKGIgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGEuc2l6ZSgpID09IDA7CisgICAgfQorICAgIGlmIChhLnNpemUoKSAhPSBiLnNpemUoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBmb3IgKEVudHJ5PEssIFY+IGVudHJ5IDogYS5lbnRyeVNldCgpKSB7CisgICAgICBpZiAoIWIuY29udGFpbnNLZXkoZW50cnkuZ2V0S2V5KCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmICghZXF1YWxzTWFwVmFsdWUoZW50cnkuZ2V0VmFsdWUoKSwgYi5nZXQoZW50cnkuZ2V0S2V5KCkpKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBlcXVhbHNNYXBWYWx1ZShPYmplY3QgYSwgT2JqZWN0IGIpIHsKKyAgICBpZiAoYSA9PSBudWxsIHx8IGIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAia2V5cyBhbmQgdmFsdWVzIGluIG1hcHMgY2Fubm90IGJlIG51bGwiKTsKKyAgICB9CisgICAgaWYgKGEgaW5zdGFuY2VvZiBieXRlW10gJiYgYiBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGJ5dGVbXSkgYSwgKGJ5dGVbXSkgYik7CisgICAgfQorICAgIHJldHVybiBhLmVxdWFscyhiKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPEssIFY+IGludCBoYXNoQ29kZShNYXA8SywgVj4gbWFwKSB7CisgICAgaWYgKG1hcCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaW50IHJlc3VsdCA9IDA7CisgICAgZm9yIChFbnRyeTxLLCBWPiBlbnRyeSA6IG1hcC5lbnRyeVNldCgpKSB7CisgICAgICByZXN1bHQgKz0gaGFzaENvZGVGb3JNYXAoZW50cnkuZ2V0S2V5KCkpCisgICAgICAgICAgXiBoYXNoQ29kZUZvck1hcChlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGludCBoYXNoQ29kZUZvck1hcChPYmplY3QgbykgeworICAgIGlmIChvIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICByZXR1cm4gQXJyYXlzLmhhc2hDb2RlKChieXRlW10pIG8pOworICAgIH0KKyAgICByZXR1cm4gby5oYXNoQ29kZSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9JbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9JbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg2NGQzOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL0ludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEzIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcHJvdG9jb2wgbWVzc2FnZSBiZWluZyBwYXJzZWQgaXMgaW52YWxpZCBpbiBzb21lIHdheSwKKyAqIGUuZy4gaXQgY29udGFpbnMgYSBtYWxmb3JtZWQgdmFyaW50IG9yIGEgbmVnYXRpdmUgYnl0ZSBsZW5ndGguCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGNsYXNzIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xNjE2MTUxNzYzMDcyNDUwNDc2TDsKKworICBwdWJsaWMgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbihmaW5hbCBTdHJpbmcgZGVzY3JpcHRpb24pIHsKKyAgICBzdXBlcihkZXNjcmlwdGlvbik7CisgIH0KKworICBzdGF0aWMgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiB0cnVuY2F0ZWRNZXNzYWdlKCkgeworICAgIHJldHVybiBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbigKKyAgICAgICJXaGlsZSBwYXJzaW5nIGEgcHJvdG9jb2wgbWVzc2FnZSwgdGhlIGlucHV0IGVuZGVkIHVuZXhwZWN0ZWRseSAiICsKKyAgICAgICJpbiB0aGUgbWlkZGxlIG9mIGEgZmllbGQuICBUaGlzIGNvdWxkIG1lYW4gZWl0aGVyIHRoYW4gdGhlICIgKworICAgICAgImlucHV0IGhhcyBiZWVuIHRydW5jYXRlZCBvciB0aGF0IGFuIGVtYmVkZGVkIG1lc3NhZ2UgIiArCisgICAgICAibWlzcmVwb3J0ZWQgaXRzIG93biBsZW5ndGguIik7CisgIH0KKworICBzdGF0aWMgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiBuZWdhdGl2ZVNpemUoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uKAorICAgICAgIkNvZGVkSW5wdXRTdHJlYW0gZW5jb3VudGVyZWQgYW4gZW1iZWRkZWQgc3RyaW5nIG9yIG1lc3NhZ2UgIiArCisgICAgICAid2hpY2ggY2xhaW1lZCB0byBoYXZlIG5lZ2F0aXZlIHNpemUuIik7CisgIH0KKworICBzdGF0aWMgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiBtYWxmb3JtZWRWYXJpbnQoKSB7CisgICAgcmV0dXJuIG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uKAorICAgICAgIkNvZGVkSW5wdXRTdHJlYW0gZW5jb3VudGVyZWQgYSBtYWxmb3JtZWQgdmFyaW50LiIpOworICB9CisKKyAgc3RhdGljIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24gaW52YWxpZFRhZygpIHsKKyAgICByZXR1cm4gbmV3IEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24oCisgICAgICAiUHJvdG9jb2wgbWVzc2FnZSBjb250YWluZWQgYW4gaW52YWxpZCB0YWcgKHplcm8pLiIpOworICB9CisKKyAgc3RhdGljIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24gaW52YWxpZEVuZFRhZygpIHsKKyAgICByZXR1cm4gbmV3IEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24oCisgICAgICAiUHJvdG9jb2wgbWVzc2FnZSBlbmQtZ3JvdXAgdGFnIGRpZCBub3QgbWF0Y2ggZXhwZWN0ZWQgdGFnLiIpOworICB9CisKKyAgc3RhdGljIEludmFsaWRQcm90b2NvbEJ1ZmZlck5hbm9FeGNlcHRpb24gaW52YWxpZFdpcmVUeXBlKCkgeworICAgIHJldHVybiBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbigKKyAgICAgICJQcm90b2NvbCBtZXNzYWdlIHRhZyBoYWQgaW52YWxpZCB3aXJlIHR5cGUuIik7CisgIH0KKworICBzdGF0aWMgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiByZWN1cnNpb25MaW1pdEV4Y2VlZGVkKCkgeworICAgIHJldHVybiBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbigKKyAgICAgICJQcm90b2NvbCBtZXNzYWdlIGhhZCB0b28gbWFueSBsZXZlbHMgb2YgbmVzdGluZy4gIE1heSBiZSBtYWxpY2lvdXMuICAiICsKKyAgICAgICJVc2UgQ29kZWRJbnB1dFN0cmVhbS5zZXRSZWN1cnNpb25MaW1pdCgpIHRvIGluY3JlYXNlIHRoZSBkZXB0aCBsaW1pdC4iKTsKKyAgfQorCisgIHN0YXRpYyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uIHNpemVMaW1pdEV4Y2VlZGVkKCkgeworICAgIHJldHVybiBuZXcgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbigKKyAgICAgICJQcm90b2NvbCBtZXNzYWdlIHdhcyB0b28gbGFyZ2UuICBNYXkgYmUgbWFsaWNpb3VzLiAgIiArCisgICAgICAiVXNlIENvZGVkSW5wdXRTdHJlYW0uc2V0U2l6ZUxpbWl0KCkgdG8gaW5jcmVhc2UgdGhlIHNpemUgbGltaXQuIik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL01hcEZhY3Rvcmllcy5qYXZhIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTWFwRmFjdG9yaWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThmYTQ4NwotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL01hcEZhY3Rvcmllcy5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTMgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogVXRpbGl0eSBjbGFzcyBmb3IgbWFwcyBzdXBwb3J0LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWFwRmFjdG9yaWVzIHsKKyAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgTWFwRmFjdG9yeSB7CisgICAgPEssIFY+IE1hcDxLLCBWPiBmb3JNYXAoTWFwPEssIFY+IG9sZE1hcCk7CisgIH0KKworICAvLyBOT1RFKGxpdWppc2kpOiBUaGUgZmFjdG9yeSBzZXR0ZXIgaXMgdGVtcG9yYXJpbHkgbWFya2VkIGFzIHBhY2thZ2UgcHJpdmF0ZS4KKyAgLy8gVGhlIHdheSB0byBwcm92aWRlIGN1c3RvbWl6ZWQgaW1wbGVtZW50YXRpb25zIG9mIG1hcHMgZm9yIGRpZmZlcmVudAorICAvLyBwbGF0Zm9ybXMgYXJlIHN0aWxsIHVuZGVyIGRpc2N1c3Npb24uICBNYXJrIGl0IGFzIHByaXZhdGUgdG8gYXZvaWQgZXhwb3NpbmcKKyAgLy8gdGhlIEFQSSBpbiBwcm90bzMgYWxwaGEgcmVsZWFzZS4KKyAgLyogcHVibGljICovIHN0YXRpYyB2b2lkIHNldE1hcEZhY3RvcnkoTWFwRmFjdG9yeSBuZXdNYXBGYWN0b3J5KSB7CisgICAgbWFwRmFjdG9yeSA9IG5ld01hcEZhY3Rvcnk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIE1hcEZhY3RvcnkgZ2V0TWFwRmFjdG9yeSgpIHsKKyAgICByZXR1cm4gbWFwRmFjdG9yeTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIERlZmF1bHRNYXBGYWN0b3J5IGltcGxlbWVudHMgTWFwRmFjdG9yeSB7CisgICAgcHVibGljIDxLLCBWPiBNYXA8SywgVj4gZm9yTWFwKE1hcDxLLCBWPiBvbGRNYXApIHsKKyAgICAgIGlmIChvbGRNYXAgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gbmV3IEhhc2hNYXA8SywgVj4oKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBvbGRNYXA7CisgICAgfQorICB9CisgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIE1hcEZhY3RvcnkgbWFwRmFjdG9yeSA9IG5ldyBEZWZhdWx0TWFwRmFjdG9yeSgpOworCisgIHByaXZhdGUgTWFwRmFjdG9yaWVzKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL01lc3NhZ2VOYW5vLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9NZXNzYWdlTmFuby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxZTU4NTcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9NZXNzYWdlTmFuby5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEzIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQWJzdHJhY3QgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IFByb3RvY29sIE1lc3NhZ2Ugb2JqZWN0cy4KKyAqCisgKiBAYXV0aG9yIHdpbmtAZ29vZ2xlLmNvbSBXaW5rIFNhdmlsbGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE1lc3NhZ2VOYW5vIHsKKyAgICBwcm90ZWN0ZWQgdm9sYXRpbGUgaW50IGNhY2hlZFNpemUgPSAtMTsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIGVuY29kZSB0aGlzIG1lc3NhZ2UuCisgICAgICogUmV0dXJucyB0aGUgY2FjaGVkIHNpemUgb3IgY2FsbHMgZ2V0U2VyaWFsaXplZFNpemUgd2hpY2gKKyAgICAgKiBzZXRzIHRoZSBjYWNoZWQgc2l6ZS4gVGhpcyBpcyB1c2VkIGludGVybmFsbHkgd2hlbiBzZXJpYWxpemluZworICAgICAqIHNvIHRoZSBzaXplIGlzIG9ubHkgY29tcHV0ZWQgb25jZS4gSWYgYSBtZW1iZXIgaXMgbW9kaWZpZWQKKyAgICAgKiB0aGVuIHRoaXMgY291bGQgYmUgc3RhbGUgY2FsbCBnZXRTZXJpYWxpemVkU2l6ZSBpZiBpbiBkb3VidC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENhY2hlZFNpemUoKSB7CisgICAgICAgIGlmIChjYWNoZWRTaXplIDwgMCkgeworICAgICAgICAgICAgLy8gZ2V0U2VyaWFsaXplZFNpemUgc2V0cyBjYWNoZWRTaXplCisgICAgICAgICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjYWNoZWRTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gZW5jb2RlIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBUaGUgc2l6ZSBpcyBjYWNoZWQgYW5kIHRoZSBjYWNoZWQgcmVzdWx0IGNhbiBiZSByZXRyaWV2ZWQKKyAgICAgKiB1c2luZyBnZXRDYWNoZWRTaXplKCkuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICAgICAgaW50IHNpemUgPSBjb21wdXRlU2VyaWFsaXplZFNpemUoKTsKKyAgICAgICAgY2FjaGVkU2l6ZSA9IHNpemU7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gZW5jb2RlIHRoaXMgbWVzc2FnZS4gVGhpcyBkb2VzIG5vdCB1cGRhdGUgdGhlCisgICAgICogY2FjaGVkIHNpemUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjb21wdXRlU2VyaWFsaXplZFNpemUoKSB7CisgICAgICAvLyBUaGlzIGlzIG92ZXJyaWRkZW4gaWYgdGhlIGdlbmVyYXRlZCBtZXNzYWdlIGhhcyBzZXJpYWxpemVkIGZpZWxkcy4KKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgYW5kIHdyaXRlcyBpdCB0byB7QGNvZGUgb3V0cHV0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRwdXQgdGhlIG91dHB1dCB0byByZWNlaXZlIHRoZSBzZXJpYWxpemVkIGZvcm0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnJlZCB3cml0aW5nIHRvIHtAY29kZSBvdXRwdXR9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIERvZXMgbm90aGluZyBieSBkZWZhdWx0LiBPdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMgd2hpY2ggaGF2ZSBkYXRhIHRvIHdyaXRlLgorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHtAY29kZSBpbnB1dH0gYXMgYSBtZXNzYWdlIG9mIHRoaXMgdHlwZSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBNZXNzYWdlTmFubyBtZXJnZUZyb20oQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemUgdG8gYSBieXRlIGFycmF5LgorICAgICAqIEByZXR1cm4gYnl0ZSBhcnJheSB3aXRoIHRoZSBzZXJpYWxpemVkIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlW10gdG9CeXRlQXJyYXkoTWVzc2FnZU5hbm8gbXNnKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVttc2cuZ2V0U2VyaWFsaXplZFNpemUoKV07CisgICAgICAgIHRvQnl0ZUFycmF5KG1zZywgcmVzdWx0LCAwLCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemUgdG8gYSBieXRlIGFycmF5IHN0YXJ0aW5nIGF0IG9mZnNldCB0aHJvdWdoIGxlbmd0aC4gVGhlCisgICAgICogbWV0aG9kIGdldFNlcmlhbGl6ZWRTaXplIG11c3QgaGF2ZSBiZWVuIGNhbGxlZCBwcmlvciB0byBjYWxsaW5nCisgICAgICogdGhpcyBtZXRob2Qgc28gdGhlIHByb3BlciBsZW5ndGggaXMga25vdy4gIElmIGFuIGF0dGVtcHQgdG8KKyAgICAgKiB3cml0ZSBtb3JlIHRoYW4gbGVuZ3RoIGJ5dGVzIE91dE9mU3BhY2VFeGNlcHRpb24gd2lsbCBiZSB0aHJvd24KKyAgICAgKiBhbmQgaWYgbGVuZ3RoIGJ5dGVzIGFyZSBub3Qgd3JpdHRlbiB0aGVuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqIGlzIHRocm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHZvaWQgdG9CeXRlQXJyYXkoTWVzc2FnZU5hbm8gbXNnLCBieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQgPQorICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8ubmV3SW5zdGFuY2UoZGF0YSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICAgICAgbXNnLndyaXRlVG8ob3V0cHV0KTsKKyAgICAgICAgICAgIG91dHB1dC5jaGVja05vU3BhY2VMZWZ0KCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJTZXJpYWxpemluZyB0byBhIGJ5dGUgYXJyYXkgdGhyZXcgYW4gSU9FeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICIoc2hvdWxkIG5ldmVyIGhhcHBlbikuIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB7QGNvZGUgZGF0YX0gYXMgYSBtZXNzYWdlIG9mIHRoaXMgdHlwZSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUKKyAgICAgKiBtZXNzYWdlIGJlaW5nIGJ1aWx0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgPFQgZXh0ZW5kcyBNZXNzYWdlTmFubz4gVCBtZXJnZUZyb20oVCBtc2csIGZpbmFsIGJ5dGVbXSBkYXRhKQorICAgICAgICB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBtZXJnZUZyb20obXNnLCBkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2Uge0Bjb2RlIGRhdGF9IGFzIGEgbWVzc2FnZSBvZiB0aGlzIHR5cGUgYW5kIG1lcmdlIGl0IHdpdGggdGhlCisgICAgICogbWVzc2FnZSBiZWluZyBidWlsdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIDxUIGV4dGVuZHMgTWVzc2FnZU5hbm8+IFQgbWVyZ2VGcm9tKFQgbXNnLCBmaW5hbCBieXRlW10gZGF0YSwKKyAgICAgICAgICAgIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIENvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBpbnB1dCA9CisgICAgICAgICAgICAgICAgQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vLm5ld0luc3RhbmNlKGRhdGEsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIG1zZy5tZXJnZUZyb20oaW5wdXQpOworICAgICAgICAgICAgaW5wdXQuY2hlY2tMYXN0VGFnV2FzKDApOworICAgICAgICAgICAgcmV0dXJuIG1zZzsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiUmVhZGluZyBmcm9tIGEgYnl0ZSBhcnJheSB0aHJldyBhbiBJT0V4Y2VwdGlvbiAoc2hvdWxkICIKKyAgICAgICAgICAgICAgICAgICAgKyAibmV2ZXIgaGFwcGVuKS4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHR3byB7QGNvZGUgTWVzc2FnZU5hbm99cyBhbmQgcmV0dXJucyB0cnVlIGlmIHRoZSBtZXNzYWdlJ3MgYXJlIHRoZSBzYW1lIGNsYXNzIGFuZAorICAgICAqIGhhdmUgc2VyaWFsaXplZCBmb3JtIGVxdWFsaXR5IChpLmUuIGFsbCBvZiB0aGUgZmllbGQgdmFsdWVzIGFyZSB0aGUgc2FtZSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIG1lc3NhZ2VOYW5vRXF1YWxzKE1lc3NhZ2VOYW5vIGEsIE1lc3NhZ2VOYW5vIGIpIHsKKyAgICAgICAgaWYgKGEgPT0gYikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYS5nZXRDbGFzcygpICE9IGIuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBpbnQgc2VyaWFsaXplZFNpemUgPSBhLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgICAgIGlmIChiLmdldFNlcmlhbGl6ZWRTaXplKCkgIT0gc2VyaWFsaXplZFNpemUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBieXRlW10gYUJ5dGVBcnJheSA9IG5ldyBieXRlW3NlcmlhbGl6ZWRTaXplXTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJCeXRlQXJyYXkgPSBuZXcgYnl0ZVtzZXJpYWxpemVkU2l6ZV07CisgICAgICAgIHRvQnl0ZUFycmF5KGEsIGFCeXRlQXJyYXksIDAsIHNlcmlhbGl6ZWRTaXplKTsKKyAgICAgICAgdG9CeXRlQXJyYXkoYiwgYkJ5dGVBcnJheSwgMCwgc2VyaWFsaXplZFNpemUpOworICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhhQnl0ZUFycmF5LCBiQnl0ZUFycmF5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHRoYXQgaXMgKG1vc3RseSkgY29tcGF0aWJsZSB3aXRoIFByb3RvQnVmZmVyJ3MgVGV4dEZvcm1hdC4gTm90ZSB0aGF0IGdyb3VwcworICAgICAqICh3aGljaCBhcmUgZGVwcmVjYXRlZCkgYXJlIG5vdCBzZXJpYWxpemVkIHdpdGggdGhlIGNvcnJlY3QgZmllbGQgbmFtZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgaW1wbGVtZW50ZWQgdXNpbmcgcmVmbGVjdGlvbiwgc28gaXQgaXMgbm90IGVzcGVjaWFsbHkgZmFzdCBub3IgaXMgaXQgZ3VhcmFudGVlZAorICAgICAqIHRvIGZpbmQgYWxsIGZpZWxkcyBpZiB5b3UgaGF2ZSBtZXRob2QgcmVtb3ZhbCB0dXJuZWQgb24gZm9yIHByb2d1YXJkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBNZXNzYWdlTmFub1ByaW50ZXIucHJpbnQodGhpcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTWVzc2FnZU5hbm9QcmludGVyLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9NZXNzYWdlTmFub1ByaW50ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNGIyYWQzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTWVzc2FnZU5hbm9QcmludGVyLmphdmEKQEAgLTAsMCArMSwyNzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTMgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1vZGlmaWVyOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogU3RhdGljIGhlbHBlciBtZXRob2RzIGZvciBwcmludGluZyBuYW5vIHByb3Rvcy4KKyAqCisgKiBAYXV0aG9yIGZseW5uQGdvb2dsZS5jb20gQW5kcmV3IEZseW5uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNZXNzYWdlTmFub1ByaW50ZXIgeworICAgIC8vIERvIG5vdCBhbGxvdyBpbnN0YW50aWF0aW9uCisgICAgcHJpdmF0ZSBNZXNzYWdlTmFub1ByaW50ZXIoKSB7fQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElOREVOVCA9ICIgICI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9TVFJJTkdfTEVOID0gMjAwOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGEgTWVzc2FnZU5hbm8gc3VpdGFibGUgZm9yIGRlYnVnZ2luZy4gVGhlIHJldHVybmVkIHN0cmluZworICAgICAqIGlzIG1vc3RseSBjb21wYXRpYmxlIHdpdGggUHJvdG9jb2wgQnVmZmVyJ3MgVGV4dEZvcm1hdCAoYXMgcHJvdmlkZWQgYnkgbm9uLW5hbm8gcHJvdG9jb2wKKyAgICAgKiBidWZmZXJzKSAtLSBncm91cHMgKHdoaWNoIGFyZSBkZXByZWNhdGVkKSBhcmUgb3V0cHV0IHdpdGggYW4gdW5kZXJzY29yZSBuYW1lIChlLmcuIGZvb19iYXIKKyAgICAgKiBpbnN0ZWFkIG9mIEZvb0JhcikgYW5kIHdpbGwgdGh1cyBub3QgcGFyc2UuCisgICAgICoKKyAgICAgKiA8cD5FbXBsb3lzIEphdmEgcmVmbGVjdGlvbiBvbiB0aGUgZ2l2ZW4gb2JqZWN0IGFuZCByZWN1cnNpdmVseSBwcmludHMgcHJpbWl0aXZlIGZpZWxkcywKKyAgICAgKiBncm91cHMsIGFuZCBtZXNzYWdlcy48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIE1lc3NhZ2VOYW5vPiBTdHJpbmcgcHJpbnQoVCBtZXNzYWdlKSB7CisgICAgICAgIGlmIChtZXNzYWdlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmludChudWxsLCBtZXNzYWdlLCBuZXcgU3RyaW5nQnVmZmVyKCksIGJ1Zik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuICJFcnJvciBwcmludGluZyBwcm90bzogIiArIGUuZ2V0TWVzc2FnZSgpOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAiRXJyb3IgcHJpbnRpbmcgcHJvdG86ICIgKyBlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRnVuY3Rpb24gdGhhdCB3aWxsIHByaW50IHRoZSBnaXZlbiBtZXNzYWdlL2ZpZWxkIGludG8gdGhlIFN0cmluZ0J1ZmZlci4KKyAgICAgKiBNZWFudCB0byBiZSBjYWxsZWQgcmVjdXJzaXZlbHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaWRlbnRpZmllciB0aGUgaWRlbnRpZmllciB0byB1c2UsIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzIGlzIHRoZSByb290IG1lc3NhZ2UgdG8KKyAgICAgKiAgICAgICAgcHJpbnQuCisgICAgICogQHBhcmFtIG9iamVjdCB0aGUgdmFsdWUgdG8gcHJpbnQuIE1heSBpbiBmYWN0IGJlIGEgcHJpbWl0aXZlIHZhbHVlIG9yIGJ5dGUgYXJyYXkgYW5kIG5vdCBhCisgICAgICogICAgICAgIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIGluZGVudEJ1ZiB0aGUgaW5kZW50YXRpb24gZWFjaCBsaW5lIHNob3VsZCBiZWdpbiB3aXRoLgorICAgICAqIEBwYXJhbSBidWYgdGhlIG91dHB1dCBidWZmZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludChTdHJpbmcgaWRlbnRpZmllciwgT2JqZWN0IG9iamVjdCwKKyAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBpbmRlbnRCdWYsIFN0cmluZ0J1ZmZlciBidWYpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmLi4uCisgICAgICAgICAgICAvLyAgIC0gd2UncmUgYWJvdXQgdG8gcHJpbnQgYSBtZXNzYWdlLCBTdHJpbmcsIG9yIGJ5dGVbXSwgYnV0IGl0IG5vdCBwcmVzZW50OworICAgICAgICAgICAgLy8gICAtIHdlJ3JlIGFib3V0IHRvIHByaW50IGEgcHJpbWl0aXZlLCBidXQgInJlZnR5cGUiIG9wdGlvbmFsIHN0eWxlIGlzIGVuYWJsZWQsIGFuZAorICAgICAgICAgICAgLy8gICAgIHRoZSBmaWVsZCBpcyB1bnNldC4KKyAgICAgICAgICAgIC8vIEluIGJvdGggY2FzZXMgdGhlIGFwcHJvcHJpYXRlIGJlaGF2aW9yIGlzIHRvIG91dHB1dCBub3RoaW5nLgorICAgICAgICB9IGVsc2UgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1lc3NhZ2VOYW5vKSB7ICAvLyBOYW5vIHByb3RvIG1lc3NhZ2UKKyAgICAgICAgICAgIGludCBvcmlnSW5kZW50QnVmTGVuZ3RoID0gaW5kZW50QnVmLmxlbmd0aCgpOworICAgICAgICAgICAgaWYgKGlkZW50aWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW5kZW50QnVmKS5hcHBlbmQoZGVDYW1lbENhc2VpZnkoaWRlbnRpZmllcikpLmFwcGVuZCgiIDxcbiIpOworICAgICAgICAgICAgICAgIGluZGVudEJ1Zi5hcHBlbmQoSU5ERU5UKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gb2JqZWN0LmdldENsYXNzKCk7CisKKyAgICAgICAgICAgIC8vIFByb3RvIGZpZWxkcyBmb2xsb3cgb25lIG9mIHR3byBmb3JtYXRzOgorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIDEpIFB1YmxpYywgbm9uLXN0YXRpYyB2YXJpYWJsZXMgdGhhdCBkbyBub3QgYmVnaW4gb3IgZW5kIHdpdGggJ18nCisgICAgICAgICAgICAvLyBGaW5kIGFuZCBwcmludCB0aGVzZSB1c2luZyBkZWNsYXJlZCBwdWJsaWMgZmllbGRzCisgICAgICAgICAgICBmb3IgKEZpZWxkIGZpZWxkIDogY2xhenouZ2V0RmllbGRzKCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgbW9kaWZpZXJzID0gZmllbGQuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGZpZWxkTmFtZSA9IGZpZWxkLmdldE5hbWUoKTsKKworICAgICAgICAgICAgICAgIGlmICgobW9kaWZpZXJzICYgTW9kaWZpZXIuUFVCTElDKSA9PSBNb2RpZmllci5QVUJMSUMKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIChtb2RpZmllcnMgJiBNb2RpZmllci5TVEFUSUMpICE9IE1vZGlmaWVyLlNUQVRJQworICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWZpZWxkTmFtZS5zdGFydHNXaXRoKCJfIikKKyAgICAgICAgICAgICAgICAgICAgICAgICYmICFmaWVsZE5hbWUuZW5kc1dpdGgoIl8iKSkgeworICAgICAgICAgICAgICAgICAgICBDbGFzczw/PiBmaWVsZFR5cGUgPSBmaWVsZC5nZXRUeXBlKCk7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGZpZWxkLmdldChvYmplY3QpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZFR5cGUuaXNBcnJheSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBDbGFzczw/PiBhcnJheVR5cGUgPSBmaWVsZFR5cGUuZ2V0Q29tcG9uZW50VHlwZSgpOworCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBieXRlcyBpcyBzcGVjaWFsIHNpbmNlIGl0J3Mgbm90IHJlcGVhdGVkLCBidXQgaXMgcmVwcmVzZW50ZWQgYnkgYW4gYXJyYXkKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJheVR5cGUgPT0gYnl0ZS5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KGZpZWxkTmFtZSwgdmFsdWUsIGluZGVudEJ1ZiwgYnVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbiA9IHZhbHVlID09IG51bGwgPyAwIDogQXJyYXkuZ2V0TGVuZ3RoKHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBlbGVtID0gQXJyYXkuZ2V0KHZhbHVlLCBpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoZmllbGROYW1lLCBlbGVtLCBpbmRlbnRCdWYsIGJ1Zik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoZmllbGROYW1lLCB2YWx1ZSwgaW5kZW50QnVmLCBidWYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyAyKSBGaWVsZHMgdGhhdCBhcmUgYWNjZXNzZWQgdmlhIGdldHRlciBtZXRob2RzICh3aGVuIGFjY2Vzc29ycworICAgICAgICAgICAgLy8gICAgbW9kZSBpcyB0dXJuZWQgb24pCisgICAgICAgICAgICAvLyBGaW5kIGFuZCBwcmludCB0aGVzZSB1c2luZyBnZXR0ZXIgbWV0aG9kcy4KKyAgICAgICAgICAgIGZvciAoTWV0aG9kIG1ldGhvZCA6IGNsYXp6LmdldE1ldGhvZHMoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbWV0aG9kLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgdGhlIHNldHRlciBhY2Nlc3NvciBtZXRob2Qgc2luY2UgZ2V0dGVycyBhbmQgaGF6emVycyBib3RoIGhhdmUKKyAgICAgICAgICAgICAgICAvLyBub24tcHJvdG8tZmllbGQgbmFtZSBjb2xsaXNpb25zIChoYXNoQ29kZSgpIGFuZCBnZXRTZXJpYWxpemVkU2l6ZSgpKQorICAgICAgICAgICAgICAgIGlmIChuYW1lLnN0YXJ0c1dpdGgoInNldCIpKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzdWJmaWVsZE5hbWUgPSBuYW1lLnN1YnN0cmluZygzKTsKKworICAgICAgICAgICAgICAgICAgICBNZXRob2QgaGF6emVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGhhenplciA9IGNsYXp6LmdldE1ldGhvZCgiaGFzIiArIHN1YmZpZWxkTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvLyBJZiBoYXp6ZXIgZG9lcyd0IGV4aXN0IG9yIHJldHVybnMgZmFsc2UsIG5vIG5lZWQgdG8gY29udGludWUKKyAgICAgICAgICAgICAgICAgICAgaWYgKCEoQm9vbGVhbikgaGF6emVyLmludm9rZShvYmplY3QpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIE1ldGhvZCBnZXR0ZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZ2V0dGVyID0gY2xhenouZ2V0TWV0aG9kKCJnZXQiICsgc3ViZmllbGROYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHJpbnQoc3ViZmllbGROYW1lLCBnZXR0ZXIuaW52b2tlKG9iamVjdCksIGluZGVudEJ1ZiwgYnVmKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaWRlbnRpZmllciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW5kZW50QnVmLnNldExlbmd0aChvcmlnSW5kZW50QnVmTGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGluZGVudEJ1ZikuYXBwZW5kKCI+XG4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXApIHsKKyAgICAgICAgICBNYXA8Pyw/PiBtYXAgPSAoTWFwPD8sPz4pIG9iamVjdDsKKyAgICAgICAgICBpZGVudGlmaWVyID0gZGVDYW1lbENhc2VpZnkoaWRlbnRpZmllcik7CisKKyAgICAgICAgICBmb3IgKE1hcC5FbnRyeTw/LD8+IGVudHJ5IDogbWFwLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW5kZW50QnVmKS5hcHBlbmQoaWRlbnRpZmllcikuYXBwZW5kKCIgPFxuIik7CisgICAgICAgICAgICBpbnQgb3JpZ0luZGVudEJ1Zkxlbmd0aCA9IGluZGVudEJ1Zi5sZW5ndGgoKTsKKyAgICAgICAgICAgIGluZGVudEJ1Zi5hcHBlbmQoSU5ERU5UKTsKKyAgICAgICAgICAgIHByaW50KCJrZXkiLCBlbnRyeS5nZXRLZXkoKSwgaW5kZW50QnVmLCBidWYpOworICAgICAgICAgICAgcHJpbnQoInZhbHVlIiwgZW50cnkuZ2V0VmFsdWUoKSwgaW5kZW50QnVmLCBidWYpOworICAgICAgICAgICAgaW5kZW50QnVmLnNldExlbmd0aChvcmlnSW5kZW50QnVmTGVuZ3RoKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW5kZW50QnVmKS5hcHBlbmQoIj5cbiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIE5vbi1udWxsIHByaW1pdGl2ZSB2YWx1ZQorICAgICAgICAgICAgaWRlbnRpZmllciA9IGRlQ2FtZWxDYXNlaWZ5KGlkZW50aWZpZXIpOworICAgICAgICAgICAgYnVmLmFwcGVuZChpbmRlbnRCdWYpLmFwcGVuZChpZGVudGlmaWVyKS5hcHBlbmQoIjogIik7CisgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHN0cmluZ01lc3NhZ2UgPSBzYW5pdGl6ZVN0cmluZygoU3RyaW5nKSBvYmplY3QpOworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlwiIikuYXBwZW5kKHN0cmluZ01lc3NhZ2UpLmFwcGVuZCgiXCIiKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAob2JqZWN0IGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICAgICAgYXBwZW5kUXVvdGVkQnl0ZXMoKGJ5dGVbXSkgb2JqZWN0LCBidWYpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG9iamVjdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWYuYXBwZW5kKCJcbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYW4gaWRlbnRpZmllciBvZiB0aGUgZm9ybWF0ICJGaWVsZE5hbWUiIGludG8gImZpZWxkX25hbWUiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZUNhbWVsQ2FzZWlmeShTdHJpbmcgaWRlbnRpZmllcikgeworICAgICAgICBTdHJpbmdCdWZmZXIgb3V0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlkZW50aWZpZXIubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgY2hhciBjdXJyZW50Q2hhciA9IGlkZW50aWZpZXIuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGkgPT0gMCkgeworICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGN1cnJlbnRDaGFyKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKENoYXJhY3Rlci5pc1VwcGVyQ2FzZShjdXJyZW50Q2hhcikpIHsKKyAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKCdfJykuYXBwZW5kKENoYXJhY3Rlci50b0xvd2VyQ2FzZShjdXJyZW50Q2hhcikpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKGN1cnJlbnRDaGFyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb3V0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hvcnRlbnMgYW5kIGVzY2FwZXMgdGhlIGdpdmVuIHN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgc2FuaXRpemVTdHJpbmcoU3RyaW5nIHN0cikgeworICAgICAgICBpZiAoIXN0ci5zdGFydHNXaXRoKCJodHRwIikgJiYgc3RyLmxlbmd0aCgpID4gTUFYX1NUUklOR19MRU4pIHsKKyAgICAgICAgICAgIC8vIFRyaW0gbm9uLVVSTCBzdHJpbmdzLgorICAgICAgICAgICAgc3RyID0gc3RyLnN1YnN0cmluZygwLCBNQVhfU1RSSU5HX0xFTikgKyAiWy4uLl0iOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlc2NhcGVTdHJpbmcoc3RyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFc2NhcGUgZXZlcnl0aGluZyBleGNlcHQgZm9yIGxvdyBBU0NJSSBjb2RlIHBvaW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZXNjYXBlU3RyaW5nKFN0cmluZyBzdHIpIHsKKyAgICAgICAgaW50IHN0ckxlbiA9IHN0ci5sZW5ndGgoKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBiID0gbmV3IFN0cmluZ0J1aWxkZXIoc3RyTGVuKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJMZW47IGkrKykgeworICAgICAgICAgICAgY2hhciBvcmlnaW5hbCA9IHN0ci5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAob3JpZ2luYWwgPj0gJyAnICYmIG9yaWdpbmFsIDw9ICd+JyAmJiBvcmlnaW5hbCAhPSAnIicgJiYgb3JpZ2luYWwgIT0gJ1wnJykgeworICAgICAgICAgICAgICAgIGIuYXBwZW5kKG9yaWdpbmFsKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiXFx1JTA0eCIsIChpbnQpIG9yaWdpbmFsKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIGEgcXVvdGVkIGJ5dGUgYXJyYXkgdG8gdGhlIHByb3ZpZGVkIHtAY29kZSBTdHJpbmdCdWZmZXJ9LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXBwZW5kUXVvdGVkQnl0ZXMoYnl0ZVtdIGJ5dGVzLCBTdHJpbmdCdWZmZXIgYnVpbGRlcikgeworICAgICAgICBpZiAoYnl0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoIlwiXCIiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCciJyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGludCBjaCA9IGJ5dGVzW2ldICYgMHhmZjsKKyAgICAgICAgICAgIGlmIChjaCA9PSAnXFwnIHx8IGNoID09ICciJykgeworICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCdcXCcpLmFwcGVuZCgoY2hhcikgY2gpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA+PSAzMiAmJiBjaCA8IDEyNykgeworICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSBjaCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKFN0cmluZy5mb3JtYXQoIlxcJTAzbyIsIGNoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnVpbGRlci5hcHBlbmQoJyInKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9Vbmtub3duRmllbGREYXRhLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9Vbmtub3duRmllbGREYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTE3ZmNjZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL1Vua25vd25GaWVsZERhdGEuamF2YQpAQCAtMCwwICsxLDg0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEzIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogU3RvcmVzIHVua25vd24gZmllbGRzLiBUaGVzZSBtaWdodCBiZSBleHRlbnNpb25zIG9yIGZpZWxkcyB0aGF0IHRoZSBnZW5lcmF0ZWQKKyAqIEFQSSBkb2Vzbid0IGtub3cgYWJvdXQgeWV0LgorICoKKyAqIEBhdXRob3IgYmR1ZmZAZ29vZ2xlLmNvbSAoQnJpYW4gRHVmZikKKyAqLworZmluYWwgY2xhc3MgVW5rbm93bkZpZWxkRGF0YSB7CisKKyAgICBmaW5hbCBpbnQgdGFnOworICAgIGZpbmFsIGJ5dGVbXSBieXRlczsKKworICAgIFVua25vd25GaWVsZERhdGEoaW50IHRhZywgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHRoaXMudGFnID0gdGFnOworICAgICAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7CisgICAgfQorCisgICAgaW50IGNvbXB1dGVTZXJpYWxpemVkU2l6ZSgpIHsKKyAgICAgICAgaW50IHNpemUgPSAwOworICAgICAgICBzaXplICs9IENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8uY29tcHV0ZVJhd1ZhcmludDMyU2l6ZSh0YWcpOworICAgICAgICBzaXplICs9IGJ5dGVzLmxlbmd0aDsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgdm9pZCB3cml0ZVRvKENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0YWcpOworICAgICAgICBvdXRwdXQud3JpdGVSYXdCeXRlcyhieXRlcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBVbmtub3duRmllbGREYXRhKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgVW5rbm93bkZpZWxkRGF0YSBvdGhlciA9IChVbmtub3duRmllbGREYXRhKSBvOworICAgICAgICByZXR1cm4gdGFnID09IG90aGVyLnRhZyAmJiBBcnJheXMuZXF1YWxzKGJ5dGVzLCBvdGhlci5ieXRlcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IDE3OworICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIHRhZzsKKyAgICAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBBcnJheXMuaGFzaENvZGUoYnl0ZXMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL1dpcmVGb3JtYXROYW5vLmphdmEgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9XaXJlRm9ybWF0TmFuby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiYjYzNzAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9XaXJlRm9ybWF0TmFuby5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEzIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBQcm90b2NvbCBCdWZmZXIgbGlicmFyeSBhbmQgZ2VuZXJhdGVkCisgKiBtZXNzYWdlIGltcGxlbWVudGF0aW9ucy4gIEl0IGlzIHB1YmxpYyBvbmx5IGJlY2F1c2UgdGhvc2UgZ2VuZXJhdGVkIG1lc3NhZ2VzCisgKiBkbyBub3QgcmVzaWRlIGluIHRoZSB7QGNvZGUgcHJvdG9idWZ9IHBhY2thZ2UuICBPdGhlcnMgc2hvdWxkIG5vdCB1c2UgdGhpcworICogY2xhc3MgZGlyZWN0bHkuCisgKgorICogVGhpcyBjbGFzcyBjb250YWlucyBjb25zdGFudHMgYW5kIGhlbHBlciBmdW5jdGlvbnMgdXNlZnVsIGZvciBkZWFsaW5nIHdpdGgKKyAqIHRoZSBQcm90b2NvbCBCdWZmZXIgd2lyZSBmb3JtYXQuCisgKgorICogQGF1dGhvciBrZW50b25AZ29vZ2xlLmNvbSBLZW50b24gVmFyZGEKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFdpcmVGb3JtYXROYW5vIHsKKyAgLy8gRG8gbm90IGFsbG93IGluc3RhbnRpYXRpb24uCisgIHByaXZhdGUgV2lyZUZvcm1hdE5hbm8oKSB7fQorCisgIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfVkFSSU5UICAgICAgICAgICA9IDA7CisgIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfRklYRUQ2NCAgICAgICAgICA9IDE7CisgIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCA9IDI7CisgIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfU1RBUlRfR1JPVVAgICAgICA9IDM7CisgIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfRU5EX0dST1VQICAgICAgICA9IDQ7CisgIHN0YXRpYyBmaW5hbCBpbnQgV0lSRVRZUEVfRklYRUQzMiAgICAgICAgICA9IDU7CisKKyAgc3RhdGljIGZpbmFsIGludCBUQUdfVFlQRV9CSVRTID0gMzsKKyAgc3RhdGljIGZpbmFsIGludCBUQUdfVFlQRV9NQVNLID0gKDEgPDwgVEFHX1RZUEVfQklUUykgLSAxOworCisgIC8qKiBHaXZlbiBhIHRhZyB2YWx1ZSwgZGV0ZXJtaW5lcyB0aGUgd2lyZSB0eXBlICh0aGUgbG93ZXIgMyBiaXRzKS4gKi8KKyAgc3RhdGljIGludCBnZXRUYWdXaXJlVHlwZShmaW5hbCBpbnQgdGFnKSB7CisgICAgcmV0dXJuIHRhZyAmIFRBR19UWVBFX01BU0s7CisgIH0KKworICAvKiogR2l2ZW4gYSB0YWcgdmFsdWUsIGRldGVybWluZXMgdGhlIGZpZWxkIG51bWJlciAodGhlIHVwcGVyIDI5IGJpdHMpLiAqLworICBwdWJsaWMgc3RhdGljIGludCBnZXRUYWdGaWVsZE51bWJlcihmaW5hbCBpbnQgdGFnKSB7CisgICAgcmV0dXJuIHRhZyA+Pj4gVEFHX1RZUEVfQklUUzsKKyAgfQorCisgIC8qKiBNYWtlcyBhIHRhZyB2YWx1ZSBnaXZlbiBhIGZpZWxkIG51bWJlciBhbmQgd2lyZSB0eXBlLiAqLworICBzdGF0aWMgaW50IG1ha2VUYWcoZmluYWwgaW50IGZpZWxkTnVtYmVyLCBmaW5hbCBpbnQgd2lyZVR5cGUpIHsKKyAgICByZXR1cm4gKGZpZWxkTnVtYmVyIDw8IFRBR19UWVBFX0JJVFMpIHwgd2lyZVR5cGU7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTVBUWV9JTlRfQVJSQVlbXSA9IHt9OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgRU1QVFlfTE9OR19BUlJBWVtdID0ge307CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgZmxvYXQgRU1QVFlfRkxPQVRfQVJSQVlbXSA9IHt9OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBFTVBUWV9ET1VCTEVfQVJSQVlbXSA9IHt9OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gRU1QVFlfQk9PTEVBTl9BUlJBWVtdID0ge307CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZX1NUUklOR19BUlJBWVtdID0ge307CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZVtdIEVNUFRZX0JZVEVTX0FSUkFZW10gPSB7fTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlW10gRU1QVFlfQllURVMgPSB7fTsKKworICAvKioKKyAgICogUGFyc2VzIGFuIHVua25vd24gZmllbGQuIFRoaXMgaW1wbGVtZW50YXRpb24gc2tpcHMgdGhlIGZpZWxkLgorICAgKgorICAgKiA8cD5HZW5lcmF0ZWQgbWVzc2FnZXMgd2lsbCBjYWxsIHRoaXMgZm9yIHVua25vd24gZmllbGRzIGlmIHRoZSBzdG9yZV91bmtub3duX2ZpZWxkcworICAgKiBvcHRpb24gaXMgb2ZmLgorICAgKgorICAgKiBAcmV0dXJuIHtAbGl0ZXJhbCB0cnVlfSB1bmxlc3MgdGhlIHRhZyBpcyBhbiBlbmQtZ3JvdXAgdGFnLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIHBhcnNlVW5rbm93bkZpZWxkKAorICAgICAgZmluYWwgQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGlucHV0LAorICAgICAgZmluYWwgaW50IHRhZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gaW5wdXQuc2tpcEZpZWxkKHRhZyk7CisgIH0KKworICAvKioKKyAgICogQ29tcHV0ZXMgdGhlIGFycmF5IGxlbmd0aCBvZiBhIHJlcGVhdGVkIGZpZWxkLiBXZSBhc3N1bWUgdGhhdCBpbiB0aGUgY29tbW9uIGNhc2UgcmVwZWF0ZWQKKyAgICogZmllbGRzIGFyZSBjb250aWd1b3VzbHkgc2VyaWFsaXplZCBidXQgd2Ugc3RpbGwgY29ycmVjdGx5IGhhbmRsZSBpbnRlcnNwZXJzZWQgdmFsdWVzIG9mIGEKKyAgICogcmVwZWF0ZWQgZmllbGQgKGJ1dCB3aXRoIGV4dHJhIGFsbG9jYXRpb25zKS4KKyAgICoKKyAgICogUmV3aW5kcyB0byBjdXJyZW50IGlucHV0IHBvc2l0aW9uIGJlZm9yZSByZXR1cm5pbmcuCisgICAqCisgICAqIEBwYXJhbSBpbnB1dCBzdHJlYW0gaW5wdXQsIHBvaW50aW5nIHRvIHRoZSBieXRlIGFmdGVyIHRoZSBmaXJzdCB0YWcKKyAgICogQHBhcmFtIHRhZyByZXBlYXRlZCBmaWVsZCB0YWcganVzdCByZWFkCisgICAqIEByZXR1cm4gbGVuZ3RoIG9mIGFycmF5CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGdldFJlcGVhdGVkRmllbGRBcnJheUxlbmd0aCgKKyAgICAgIGZpbmFsIENvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBpbnB1dCwKKyAgICAgIGZpbmFsIGludCB0YWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IGFycmF5TGVuZ3RoID0gMTsKKyAgICBpbnQgc3RhcnRQb3MgPSBpbnB1dC5nZXRQb3NpdGlvbigpOworICAgIGlucHV0LnNraXBGaWVsZCh0YWcpOworICAgIHdoaWxlIChpbnB1dC5yZWFkVGFnKCkgPT0gdGFnKSB7CisgICAgICBpbnB1dC5za2lwRmllbGQodGFnKTsKKyAgICAgIGFycmF5TGVuZ3RoKys7CisgICAgfQorICAgIGlucHV0LnJld2luZFRvUG9zaXRpb24oc3RhcnRQb3MpOworICAgIHJldHVybiBhcnJheUxlbmd0aDsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby9OYW5vVGVzdC5qYXZhIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTmFub1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Y2M3NzIyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vTmFub1Rlc3QuamF2YQpAQCAtMCwwICsxLDQzODggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTMgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYubmFubzsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NYXBUZXN0UHJvdG8uVGVzdE1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5OYW5vQWNjZXNzb3JzT3V0ZXJDbGFzcy5UZXN0TmFub0FjY2Vzc29yczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTmFub0hhc091dGVyQ2xhc3MuVGVzdEFsbFR5cGVzTmFub0hhczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTmFub091dGVyQ2xhc3MuVGVzdEFsbFR5cGVzTmFubzsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uVW5pdHRlc3RSZWN1cnNpdmVOYW5vLlJlY3Vyc2l2ZU1lc3NhZ2VOYW5vOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Vbml0dGVzdFNpbXBsZU5hbm8uU2ltcGxlTWVzc2FnZU5hbm87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLlVuaXR0ZXN0U2luZ2xlTmFuby5TaW5nbGVNZXNzYWdlTmFubzsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8udGVzdGV4dC5FeHRlbnNpb25zOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYubmFuby50ZXN0ZXh0LkV4dGVuc2lvbnMuQW5vdGhlck1lc3NhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLnRlc3RleHQuRXh0ZW5zaW9ucy5NZXNzYWdlV2l0aEdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYubmFuby50ZXN0aW1wb3J0LlVuaXR0ZXN0SW1wb3J0TmFubzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworLyoqCisgKiBUZXN0IG5hbm8gcnVudGltZS4KKyAqCisgKiBAYXV0aG9yIHVsYXNAZ29vZ2xlLmNvbSBVbGFzIEtpcmF6Y2kKKyAqLworcHVibGljIGNsYXNzIE5hbm9UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RTaW1wbGVNZXNzYWdlTmFubygpIHRocm93cyBFeGNlcHRpb24geworICAgIFNpbXBsZU1lc3NhZ2VOYW5vIG1zZyA9IG5ldyBTaW1wbGVNZXNzYWdlTmFubygpOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5kKTsKKyAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXNnLm5lc3RlZE1zZyk7CisgICAgYXNzZXJ0RXF1YWxzKFNpbXBsZU1lc3NhZ2VOYW5vLkJBWiwgbXNnLmRlZmF1bHROZXN0ZWRFbnVtKTsKKworICAgIG1zZy5kID0gNDU2OworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5kKTsKKworICAgIFNpbXBsZU1lc3NhZ2VOYW5vLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTXNnID0gbmV3IFNpbXBsZU1lc3NhZ2VOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBuZXN0ZWRNc2cuYmIgPSAyOworICAgIGFzc2VydEVxdWFscygyLCBuZXN0ZWRNc2cuYmIpOworICAgIG1zZy5uZXN0ZWRNc2cgPSBuZXN0ZWRNc2c7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5uZXN0ZWRNc2cuYmIpOworCisgICAgbXNnLmRlZmF1bHROZXN0ZWRFbnVtID0gU2ltcGxlTWVzc2FnZU5hbm8uQkFSOworICAgIGFzc2VydEVxdWFscyhTaW1wbGVNZXNzYWdlTmFuby5CQVIsIG1zZy5kZWZhdWx0TmVzdGVkRW51bSk7CisKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDkpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBTaW1wbGVNZXNzYWdlTmFubyBuZXdNc2cgPSBTaW1wbGVNZXNzYWdlTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cuZCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5uZXN0ZWRNc2cuYmIpOworICAgIGFzc2VydEVxdWFscyhTaW1wbGVNZXNzYWdlTmFuby5CQVIsIG1zZy5kZWZhdWx0TmVzdGVkRW51bSk7CisKKyAgICBtc2cubmVzdGVkTXNnID0gbnVsbDsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplICE9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0UmVjdXJzaXZlTWVzc2FnZU5hbm8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBSZWN1cnNpdmVNZXNzYWdlTmFubyBtc2cgPSBuZXcgUmVjdXJzaXZlTWVzc2FnZU5hbm8oKTsKKyAgICBhc3NlcnRUcnVlKG1zZy5yZXBlYXRlZFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vLmxlbmd0aCA9PSAwKTsKKworICAgIFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vIG1zZzEgPSBuZXcgUmVjdXJzaXZlTWVzc2FnZU5hbm8oKTsKKyAgICBtc2cxLmlkID0gMTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnMS5pZCk7CisgICAgUmVjdXJzaXZlTWVzc2FnZU5hbm8gbXNnMiA9IG5ldyBSZWN1cnNpdmVNZXNzYWdlTmFubygpOworICAgIG1zZzIuaWQgPSAyOworICAgIFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vIG1zZzMgPSBuZXcgUmVjdXJzaXZlTWVzc2FnZU5hbm8oKTsKKyAgICBtc2czLmlkID0gMzsKKworICAgIFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTXNnID0gbmV3IFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBuZXN0ZWRNc2cuYSA9IG1zZzE7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5lc3RlZE1zZy5hLmlkKTsKKworICAgIG1zZy5pZCA9IDA7CisgICAgbXNnLm5lc3RlZE1lc3NhZ2UgPSBuZXN0ZWRNc2c7CisgICAgbXNnLm9wdGlvbmFsUmVjdXJzaXZlTWVzc2FnZU5hbm8gPSBtc2cyOworICAgIG1zZy5yZXBlYXRlZFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vID0gbmV3IFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vW10geyBtc2czIH07CisKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDE2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgUmVjdXJzaXZlTWVzc2FnZU5hbm8gbmV3TXNnID0gUmVjdXJzaXZlTWVzc2FnZU5hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vLmxlbmd0aCk7CisKKyAgICBhc3NlcnRFcXVhbHMoMCwgbmV3TXNnLmlkKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLm5lc3RlZE1lc3NhZ2UuYS5pZCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5vcHRpb25hbFJlY3Vyc2l2ZU1lc3NhZ2VOYW5vLmlkKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbmV3TXNnLnJlcGVhdGVkUmVjdXJzaXZlTWVzc2FnZU5hbm9bMF0uaWQpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1lc3NhZ2VOb0ZpZWxkcygpIHsKKyAgICBTaW5nbGVNZXNzYWdlTmFubyBtc2cgPSBuZXcgU2luZ2xlTWVzc2FnZU5hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLmdldFNlcmlhbGl6ZWRTaXplKCkpOworICAgIGFzc2VydEVxdWFscygwLCBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpLmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcXVpcmVkSW50MzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLmlkID0gMTIzOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5pZCk7CisgICAgbXNnLmNsZWFyKCkuaWQgPSA0NTY7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLmlkKTsKKyAgICBtc2cuY2xlYXIoKTsKKworICAgIG1zZy5pZCA9IDEyMzsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDMpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLmlkKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxJbnQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxJbnQzMiA9IDEyMzsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBtc2cub3B0aW9uYWxJbnQzMik7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxJbnQzMiA9IDQ1NjsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cub3B0aW9uYWxJbnQzMik7CisgICAgbXNnLmNsZWFyKCk7CisKKyAgICBtc2cub3B0aW9uYWxJbnQzMiA9IDEyMzsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDUpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLm9wdGlvbmFsSW50MzIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbEludDY0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbEludDY0ID0gMTIzOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5vcHRpb25hbEludDY0KTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5vcHRpb25hbEludDY0ID0gNDU2OworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5vcHRpb25hbEludDY0KTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLm9wdGlvbmFsSW50NjQpOworCisgICAgbXNnLm9wdGlvbmFsSW50NjQgPSAxMjM7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA1KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5vcHRpb25hbEludDY0KTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxVaW50MzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsVWludDMyID0gMTIzOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5vcHRpb25hbFVpbnQzMik7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxVaW50MzIgPSA0NTY7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLm9wdGlvbmFsVWludDMyKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLm9wdGlvbmFsVWludDMyKTsKKworICAgIG1zZy5vcHRpb25hbFVpbnQzMiA9IDEyMzsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDUpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLm9wdGlvbmFsVWludDMyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxVaW50NjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsVWludDY0ID0gMTIzOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5vcHRpb25hbFVpbnQ2NCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxVaW50NjQgPSA0NTY7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLm9wdGlvbmFsVWludDY0KTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLm9wdGlvbmFsVWludDY0KTsKKworICAgIG1zZy5vcHRpb25hbFVpbnQ2NCA9IDEyMzsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDUpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLm9wdGlvbmFsVWludDY0KTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxTaW50MzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsU2ludDMyID0gMTIzOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5vcHRpb25hbFNpbnQzMik7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxTaW50MzIgPSA0NTY7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLm9wdGlvbmFsU2ludDMyKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLm9wdGlvbmFsU2ludDMyKTsKKworICAgIG1zZy5vcHRpb25hbFNpbnQzMiA9IC0xMjM7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygtMTIzLCBuZXdNc2cub3B0aW9uYWxTaW50MzIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbFNpbnQ2NCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxTaW50NjQgPSAxMjM7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbXNnLm9wdGlvbmFsU2ludDY0KTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5vcHRpb25hbFNpbnQ2NCA9IDQ1NjsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cub3B0aW9uYWxTaW50NjQpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cub3B0aW9uYWxTaW50NjQpOworCisgICAgbXNnLm9wdGlvbmFsU2ludDY0ID0gLTEyMzsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDYpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKC0xMjMsIG5ld01zZy5vcHRpb25hbFNpbnQ2NCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub09wdGlvbmFsRml4ZWQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxGaXhlZDMyID0gMTIzOworICAgIGFzc2VydEVxdWFscygxMjMsIG1zZy5vcHRpb25hbEZpeGVkMzIpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLm9wdGlvbmFsRml4ZWQzMiA9IDQ1NjsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cub3B0aW9uYWxGaXhlZDMyKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLm9wdGlvbmFsRml4ZWQzMik7CisKKyAgICBtc2cub3B0aW9uYWxGaXhlZDMyID0gMTIzOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cub3B0aW9uYWxGaXhlZDMyKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxGaXhlZDY0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbEZpeGVkNjQgPSAxMjM7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbXNnLm9wdGlvbmFsRml4ZWQ2NCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxGaXhlZDY0ID0gNDU2OworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5vcHRpb25hbEZpeGVkNjQpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cub3B0aW9uYWxGaXhlZDY0KTsKKworICAgIG1zZy5vcHRpb25hbEZpeGVkNjQgPSAxMjM7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cub3B0aW9uYWxGaXhlZDY0KTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxTZml4ZWQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxTZml4ZWQzMiA9IDEyMzsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBtc2cub3B0aW9uYWxTZml4ZWQzMik7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxTZml4ZWQzMiA9IDQ1NjsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cub3B0aW9uYWxTZml4ZWQzMik7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5vcHRpb25hbFNmaXhlZDMyKTsKKworICAgIG1zZy5vcHRpb25hbFNmaXhlZDMyID0gMTIzOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cub3B0aW9uYWxTZml4ZWQzMik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub09wdGlvbmFsU2ZpeGVkNjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsU2ZpeGVkNjQgPSAxMjM7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbXNnLm9wdGlvbmFsU2ZpeGVkNjQpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLm9wdGlvbmFsU2ZpeGVkNjQgPSA0NTY7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLm9wdGlvbmFsU2ZpeGVkNjQpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cub3B0aW9uYWxTZml4ZWQ2NCk7CisKKyAgICBtc2cub3B0aW9uYWxTZml4ZWQ2NCA9IC0xMjM7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoLTEyMywgbmV3TXNnLm9wdGlvbmFsU2ZpeGVkNjQpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbEZsb2F0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbEZsb2F0ID0gMTIzZjsKKyAgICBhc3NlcnRUcnVlKDEyMy4wZiA9PSBtc2cub3B0aW9uYWxGbG9hdCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxGbG9hdCA9IDQ1Ni4wZjsKKyAgICBhc3NlcnRUcnVlKDQ1Ni4wZiA9PSBtc2cub3B0aW9uYWxGbG9hdCk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0VHJ1ZSgwLjBmID09IG1zZy5vcHRpb25hbEZsb2F0KTsKKworICAgIG1zZy5vcHRpb25hbEZsb2F0ID0gLTEyMy40NTZmOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRUcnVlKC0xMjMuNDU2ZiA9PSBuZXdNc2cub3B0aW9uYWxGbG9hdCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub09wdGlvbmFsRG91YmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbERvdWJsZSA9IDEyMzsKKyAgICBhc3NlcnRUcnVlKDEyMy4wID09IG1zZy5vcHRpb25hbERvdWJsZSk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxEb3VibGUgPSA0NTYuMDsKKyAgICBhc3NlcnRUcnVlKDQ1Ni4wID09IG1zZy5vcHRpb25hbERvdWJsZSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0VHJ1ZSgwLjAgPT0gbXNnLm9wdGlvbmFsRG91YmxlKTsKKworICAgIG1zZy5vcHRpb25hbERvdWJsZSA9IC0xMjMuNDU2OworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTIpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0VHJ1ZSgtMTIzLjQ1NiA9PSBuZXdNc2cub3B0aW9uYWxEb3VibGUpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbEJvb2woKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsQm9vbCA9IHRydWU7CisgICAgYXNzZXJ0VHJ1ZShtc2cub3B0aW9uYWxCb29sKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5vcHRpb25hbEJvb2wgPSB0cnVlOworICAgIGFzc2VydFRydWUobXNnLm9wdGlvbmFsQm9vbCk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsQm9vbCk7CisKKyAgICBtc2cub3B0aW9uYWxCb29sID0gdHJ1ZTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDUpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cub3B0aW9uYWxCb29sKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsU3RyaW5nID0gImhlbGxvIjsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbXNnLm9wdGlvbmFsU3RyaW5nKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRUcnVlKG1zZy5vcHRpb25hbFN0cmluZy5pc0VtcHR5KCkpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLm9wdGlvbmFsU3RyaW5nID0gImhlbGxvMiI7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbzIiLCBtc2cub3B0aW9uYWxTdHJpbmcpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydFRydWUobXNnLm9wdGlvbmFsU3RyaW5nLmlzRW1wdHkoKSk7CisKKyAgICBtc2cub3B0aW9uYWxTdHJpbmcgPSAiYnllIjsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDgpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cub3B0aW9uYWxTdHJpbmcgIT0gbnVsbCk7CisgICAgYXNzZXJ0RXF1YWxzKCJieWUiLCBuZXdNc2cub3B0aW9uYWxTdHJpbmcpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbEJ5dGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIGFzc2VydEZhbHNlKG1zZy5vcHRpb25hbEJ5dGVzLmxlbmd0aCA+IDApOworICAgIG1zZy5vcHRpb25hbEJ5dGVzID0gSW50ZXJuYWxOYW5vLmNvcHlGcm9tVXRmOCgiaGVsbG8iKTsKKyAgICBhc3NlcnRUcnVlKG1zZy5vcHRpb25hbEJ5dGVzLmxlbmd0aCA+IDApOworICAgIGFzc2VydEVxdWFscygiaGVsbG8iLCBuZXcgU3RyaW5nKG1zZy5vcHRpb25hbEJ5dGVzLCAiVVRGLTgiKSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsQnl0ZXMubGVuZ3RoID4gMCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxCeXRlcyA9IEludGVybmFsTmFuby5jb3B5RnJvbVV0ZjgoImhlbGxvIik7CisgICAgYXNzZXJ0VHJ1ZShtc2cub3B0aW9uYWxCeXRlcy5sZW5ndGggPiAwKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRGYWxzZShtc2cub3B0aW9uYWxCeXRlcy5sZW5ndGggPiAwKTsKKworICAgIG1zZy5vcHRpb25hbEJ5dGVzID0gSW50ZXJuYWxOYW5vLmNvcHlGcm9tVXRmOCgiYnllIik7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA4KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydFRydWUobmV3TXNnLm9wdGlvbmFsQnl0ZXMubGVuZ3RoID4gMCk7CisgICAgYXNzZXJ0RXF1YWxzKCJieWUiLCBuZXcgU3RyaW5nKG5ld01zZy5vcHRpb25hbEJ5dGVzLCAiVVRGLTgiKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub09wdGlvbmFsR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgVGVzdEFsbFR5cGVzTmFuby5PcHRpb25hbEdyb3VwIGdycCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk9wdGlvbmFsR3JvdXAoKTsKKyAgICBncnAuYSA9IDE7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsR3JvdXAgIT0gbnVsbCk7CisgICAgbXNnLm9wdGlvbmFsR3JvdXAgPSBncnA7CisgICAgYXNzZXJ0VHJ1ZShtc2cub3B0aW9uYWxHcm91cCAhPSBudWxsKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLm9wdGlvbmFsR3JvdXAuYSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsR3JvdXAgIT0gbnVsbCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxHcm91cCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk9wdGlvbmFsR3JvdXAoKTsKKyAgICBtc2cub3B0aW9uYWxHcm91cC5hID0gMjsKKyAgICBhc3NlcnRUcnVlKG1zZy5vcHRpb25hbEdyb3VwICE9IG51bGwpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEZhbHNlKG1zZy5vcHRpb25hbEdyb3VwICE9IG51bGwpOworCisgICAgbXNnLm9wdGlvbmFsR3JvdXAgPSBncnA7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5vcHRpb25hbEdyb3VwICE9IG51bGwpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cub3B0aW9uYWxHcm91cC5hKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxHcm91cFdpdGhVbmtub3duRmllbGRzRW5hYmxlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1lc3NhZ2VXaXRoR3JvdXAgbXNnID0gbmV3IE1lc3NhZ2VXaXRoR3JvdXAoKTsKKyAgICBNZXNzYWdlV2l0aEdyb3VwLkdyb3VwIGdycCA9IG5ldyBNZXNzYWdlV2l0aEdyb3VwLkdyb3VwKCk7CisgICAgZ3JwLmEgPSAxOworICAgIG1zZy5ncm91cCA9IGdycDsKKyAgICBieXRlIFtdIHNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworCisgICAgTWVzc2FnZVdpdGhHcm91cCBwYXJzZWQgPSBNZXNzYWdlV2l0aEdyb3VwLnBhcnNlRnJvbShzZXJpYWxpemVkKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcGFyc2VkLmdyb3VwLmEpOworCisgICAgYnl0ZSBbXSBzZXJpYWxpemVkMiA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KHBhcnNlZCk7CisgICAgYXNzZXJ0RXF1YWxzKHNlcmlhbGl6ZWQubGVuZ3RoLCBzZXJpYWxpemVkMi5sZW5ndGgpOworICAgIE1lc3NhZ2VXaXRoR3JvdXAgcGFyc2VkMiA9IE1lc3NhZ2VXaXRoR3JvdXAucGFyc2VGcm9tKHNlcmlhbGl6ZWQyKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcGFyc2VkMi5ncm91cC5hKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSBuZXN0ZWRNc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbmVzdGVkTXNnLmJiID0gMTsKKyAgICBhc3NlcnRGYWxzZShtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlICE9IG51bGwpOworICAgIG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UgPSBuZXN0ZWRNc2c7CisgICAgYXNzZXJ0VHJ1ZShtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlICE9IG51bGwpOworICAgIGFzc2VydEVxdWFscygxLCBtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlLmJiKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRGYWxzZShtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlICE9IG51bGwpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlLmJiID0gMjsKKyAgICBhc3NlcnRUcnVlKG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UgIT0gbnVsbCk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSAhPSBudWxsKTsKKworICAgIG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UgPSBuZXN0ZWRNc2c7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA4KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydFRydWUobmV3TXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSAhPSBudWxsKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5iYik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgTmFub091dGVyQ2xhc3MuRm9yZWlnbk1lc3NhZ2VOYW5vIG5lc3RlZE1zZyA9IG5ldyBOYW5vT3V0ZXJDbGFzcy5Gb3JlaWduTWVzc2FnZU5hbm8oKTsKKyAgICBuZXN0ZWRNc2cuYyA9IDE7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgIT0gbnVsbCk7CisgICAgbXNnLm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgPSBuZXN0ZWRNc2c7CisgICAgYXNzZXJ0VHJ1ZShtc2cub3B0aW9uYWxGb3JlaWduTWVzc2FnZSAhPSBudWxsKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuYyk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgIT0gbnVsbCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxGb3JlaWduTWVzc2FnZSA9IG5ldyBOYW5vT3V0ZXJDbGFzcy5Gb3JlaWduTWVzc2FnZU5hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxGb3JlaWduTWVzc2FnZS5jID0gMjsKKyAgICBhc3NlcnRUcnVlKG1zZy5vcHRpb25hbEZvcmVpZ25NZXNzYWdlICE9IG51bGwpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEZhbHNlKG1zZy5vcHRpb25hbEZvcmVpZ25NZXNzYWdlICE9IG51bGwpOworCisgICAgbXNnLm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgPSBuZXN0ZWRNc2c7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA4KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydFRydWUobmV3TXNnLm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgIT0gbnVsbCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5vcHRpb25hbEZvcmVpZ25NZXNzYWdlLmMpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgVW5pdHRlc3RJbXBvcnROYW5vLkltcG9ydE1lc3NhZ2VOYW5vIG5lc3RlZE1zZyA9IG5ldyBVbml0dGVzdEltcG9ydE5hbm8uSW1wb3J0TWVzc2FnZU5hbm8oKTsKKyAgICBuZXN0ZWRNc2cuZCA9IDE7CisgICAgYXNzZXJ0RmFsc2UobXNnLm9wdGlvbmFsSW1wb3J0TWVzc2FnZSAhPSBudWxsKTsKKyAgICBtc2cub3B0aW9uYWxJbXBvcnRNZXNzYWdlID0gbmVzdGVkTXNnOworICAgIGFzc2VydFRydWUobXNnLm9wdGlvbmFsSW1wb3J0TWVzc2FnZSAhPSBudWxsKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLm9wdGlvbmFsSW1wb3J0TWVzc2FnZS5kKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRGYWxzZShtc2cub3B0aW9uYWxJbXBvcnRNZXNzYWdlICE9IG51bGwpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLm9wdGlvbmFsSW1wb3J0TWVzc2FnZSA9IG5ldyBVbml0dGVzdEltcG9ydE5hbm8uSW1wb3J0TWVzc2FnZU5hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxJbXBvcnRNZXNzYWdlLmQgPSAyOworICAgIGFzc2VydFRydWUobXNnLm9wdGlvbmFsSW1wb3J0TWVzc2FnZSAhPSBudWxsKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRGYWxzZShtc2cub3B0aW9uYWxJbXBvcnRNZXNzYWdlICE9IG51bGwpOworCisgICAgbXNnLm9wdGlvbmFsSW1wb3J0TWVzc2FnZSA9IG5lc3RlZE1zZzsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDgpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cub3B0aW9uYWxJbXBvcnRNZXNzYWdlICE9IG51bGwpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cub3B0aW9uYWxJbXBvcnRNZXNzYWdlLmQpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbE5lc3RlZEVudW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLm9wdGlvbmFsTmVzdGVkRW51bSA9IFRlc3RBbGxUeXBlc05hbm8uQkFSOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgbXNnLm9wdGlvbmFsTmVzdGVkRW51bSk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAub3B0aW9uYWxOZXN0ZWRFbnVtID0gVGVzdEFsbFR5cGVzTmFuby5CQVo7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm8uQkFaLCBtc2cub3B0aW9uYWxOZXN0ZWRFbnVtKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG1zZy5vcHRpb25hbE5lc3RlZEVudW0pOworCisgICAgbXNnLm9wdGlvbmFsTmVzdGVkRW51bSA9IFRlc3RBbGxUeXBlc05hbm8uQkFSOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVIsIG5ld01zZy5vcHRpb25hbE5lc3RlZEVudW0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbEZvcmVpZ25FbnVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbEZvcmVpZ25FbnVtID0gTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0JBUjsKKyAgICBhc3NlcnRFcXVhbHMoTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0JBUiwgbXNnLm9wdGlvbmFsRm9yZWlnbkVudW0pOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLm9wdGlvbmFsRm9yZWlnbkVudW0gPSBOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFaOworICAgIGFzc2VydEVxdWFscyhOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFaLCBtc2cub3B0aW9uYWxGb3JlaWduRW51bSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKE5hbm9PdXRlckNsYXNzLkZPUkVJR05fTkFOT19GT08sIG1zZy5vcHRpb25hbEZvcmVpZ25FbnVtKTsKKworICAgIG1zZy5vcHRpb25hbEZvcmVpZ25FbnVtID0gTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0JBUjsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDYpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKE5hbm9PdXRlckNsYXNzLkZPUkVJR05fTkFOT19CQVIsIG5ld01zZy5vcHRpb25hbEZvcmVpZ25FbnVtKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxJbXBvcnRFbnVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbEltcG9ydEVudW0gPSBVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFSOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFSLCBtc2cub3B0aW9uYWxJbXBvcnRFbnVtKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5vcHRpb25hbEltcG9ydEVudW0gPSBVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFaOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFaLCBtc2cub3B0aW9uYWxJbXBvcnRFbnVtKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0ZPTywgbXNnLm9wdGlvbmFsSW1wb3J0RW51bSk7CisKKyAgICBtc2cub3B0aW9uYWxJbXBvcnRFbnVtID0gVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0JBUjsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDYpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0SW1wb3J0TmFuby5JTVBPUlRfTkFOT19CQVIsIG5ld01zZy5vcHRpb25hbEltcG9ydEVudW0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9PcHRpb25hbFN0cmluZ1BpZWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbFN0cmluZ1BpZWNlID0gImhlbGxvIjsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbXNnLm9wdGlvbmFsU3RyaW5nUGllY2UpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydFRydWUobXNnLm9wdGlvbmFsU3RyaW5nUGllY2UuaXNFbXB0eSgpKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5vcHRpb25hbFN0cmluZ1BpZWNlID0gImhlbGxvMiI7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbzIiLCBtc2cub3B0aW9uYWxTdHJpbmdQaWVjZSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0VHJ1ZShtc2cub3B0aW9uYWxTdHJpbmdQaWVjZS5pc0VtcHR5KCkpOworCisgICAgbXNnLm9wdGlvbmFsU3RyaW5nUGllY2UgPSAiYnllIjsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDkpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cub3B0aW9uYWxTdHJpbmdQaWVjZSAhPSBudWxsKTsKKyAgICBhc3NlcnRFcXVhbHMoImJ5ZSIsIG5ld01zZy5vcHRpb25hbFN0cmluZ1BpZWNlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vT3B0aW9uYWxDb3JkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5vcHRpb25hbENvcmQgPSAiaGVsbG8iOworICAgIGFzc2VydEVxdWFscygiaGVsbG8iLCBtc2cub3B0aW9uYWxDb3JkKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRUcnVlKG1zZy5vcHRpb25hbENvcmQuaXNFbXB0eSgpKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5vcHRpb25hbENvcmQgPSAiaGVsbG8yIjsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvMiIsIG1zZy5vcHRpb25hbENvcmQpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydFRydWUobXNnLm9wdGlvbmFsQ29yZC5pc0VtcHR5KCkpOworCisgICAgbXNnLm9wdGlvbmFsQ29yZCA9ICJieWUiOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5vcHRpb25hbENvcmQgIT0gbnVsbCk7CisgICAgYXNzZXJ0RXF1YWxzKCJieWUiLCBuZXdNc2cub3B0aW9uYWxDb3JkKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRJbnQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkSW50MzIubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRJbnQzMiA9IG5ldyBpbnRbXSB7IDEyMywgNzg5LCA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBtc2cucmVwZWF0ZWRJbnQzMlsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkSW50MzJbMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRJbnQzMi5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRJbnQzMlswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEludDMyLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHsgMTIzIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEludDMyLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRJbnQzMlswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRJbnQzMi5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTApOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRJbnQzMi5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5yZXBlYXRlZEludDMyWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRJbnQzMlsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkSW50NjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEludDY0Lmxlbmd0aCk7CisgICAgbXNnLnJlcGVhdGVkSW50NjQgPSBuZXcgbG9uZ1tdIHsgMTIzLCA3ODksIDQ1NiB9OworICAgIGFzc2VydEVxdWFscyg3ODksIG1zZy5yZXBlYXRlZEludDY0WzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRJbnQ2NFsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEludDY0Lmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRJbnQ2NCA9IG5ldyBsb25nW10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkSW50NjQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRJbnQ2NFswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEludDY0Lmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEludDY0ID0gbmV3IGxvbmdbXSB7IDEyMyB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRJbnQ2NC5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEludDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkSW50NjRbMF0pOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEludDY0ID0gbmV3IGxvbmdbXSB7IDEyMywgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEludDY0Lmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZEludDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkSW50NjRbMF0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG5ld01zZy5yZXBlYXRlZEludDY0WzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRVaW50MzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFVpbnQzMi5sZW5ndGgpOworICAgIG1zZy5yZXBlYXRlZFVpbnQzMiA9IG5ldyBpbnRbXSB7IDEyMywgNzg5LCA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBtc2cucmVwZWF0ZWRVaW50MzJbMV0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZFVpbnQzMlsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFVpbnQzMi5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkVWludDMyID0gbmV3IGludFtdIHsgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFVpbnQzMi5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZFVpbnQzMlswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFVpbnQzMi5sZW5ndGgpOworCisgICAgLy8gVGVzdCAxIGVudHJ5CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRVaW50MzIgPSBuZXcgaW50W10geyAxMjMgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkVWludDMyLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkVWludDMyLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkVWludDMyWzBdKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRVaW50MzIgPSBuZXcgaW50W10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRVaW50MzIubGVuZ3RoKTsKKyAgICByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDEwKTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbmV3TXNnLnJlcGVhdGVkVWludDMyLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkVWludDMyWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRVaW50MzJbMV0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9SZXBlYXRlZFVpbnQ2NCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkVWludDY0Lmxlbmd0aCk7CisgICAgbXNnLnJlcGVhdGVkVWludDY0ID0gbmV3IGxvbmdbXSB7IDEyMywgNzg5LCA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBtc2cucmVwZWF0ZWRVaW50NjRbMV0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZFVpbnQ2NFsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFVpbnQ2NC5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkVWludDY0ID0gbmV3IGxvbmdbXSB7IDQ1NiB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRVaW50NjQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRVaW50NjRbMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRVaW50NjQubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkVWludDY0ID0gbmV3IGxvbmdbXSB7IDEyMyB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRVaW50NjQubGVuZ3RoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDYpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRVaW50NjQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRVaW50NjRbMF0pOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFVpbnQ2NCA9IG5ldyBsb25nW10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRVaW50NjQubGVuZ3RoKTsKKyAgICByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDEwKTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbmV3TXNnLnJlcGVhdGVkVWludDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkVWludDY0WzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRVaW50NjRbMV0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9SZXBlYXRlZFNpbnQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkU2ludDMyLmxlbmd0aCk7CisgICAgbXNnLnJlcGVhdGVkU2ludDMyID0gbmV3IGludFtdIHsgMTIzLCA3ODksIDQ1NiB9OworICAgIGFzc2VydEVxdWFscyg3ODksIG1zZy5yZXBlYXRlZFNpbnQzMlsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkU2ludDMyWzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkU2ludDMyLmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTaW50MzIgPSBuZXcgaW50W10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkU2ludDMyLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkU2ludDMyWzBdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkU2ludDMyLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFNpbnQzMiA9IG5ldyBpbnRbXSB7IDEyMyB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRTaW50MzIubGVuZ3RoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDcpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRTaW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRTaW50MzJbMF0pOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFNpbnQzMiA9IG5ldyBpbnRbXSB7IDEyMywgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZFNpbnQzMi5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTEpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRTaW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRTaW50MzJbMF0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG5ld01zZy5yZXBlYXRlZFNpbnQzMlsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkU2ludDY0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRTaW50NjQubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRTaW50NjQgPSBuZXcgbG9uZ1tdIHsgMTIzLCA3ODksIDQ1NiB9OworICAgIGFzc2VydEVxdWFscyg3ODksIG1zZy5yZXBlYXRlZFNpbnQ2NFsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkU2ludDY0WzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkU2ludDY0Lmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTaW50NjQgPSBuZXcgbG9uZ1tdIHsgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFNpbnQ2NC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZFNpbnQ2NFswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFNpbnQ2NC5sZW5ndGgpOworCisgICAgLy8gVGVzdCAxIGVudHJ5CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTaW50NjQgPSBuZXcgbG9uZ1tdIHsgMTIzIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFNpbnQ2NC5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNyk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZFNpbnQ2NC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5yZXBlYXRlZFNpbnQ2NFswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU2ludDY0ID0gbmV3IGxvbmdbXSB7IDEyMywgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZFNpbnQ2NC5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTEpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRTaW50NjQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRTaW50NjRbMF0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG5ld01zZy5yZXBlYXRlZFNpbnQ2NFsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkRml4ZWQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkRml4ZWQzMi5sZW5ndGgpOworICAgIG1zZy5yZXBlYXRlZEZpeGVkMzIgPSBuZXcgaW50W10geyAxMjMsIDc4OSwgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDc4OSwgbXNnLnJlcGVhdGVkRml4ZWQzMlsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkRml4ZWQzMlsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEZpeGVkMzIubGVuZ3RoKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZpeGVkMzIgPSBuZXcgaW50W10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkRml4ZWQzMi5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZEZpeGVkMzJbMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRGaXhlZDMyLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZpeGVkMzIgPSBuZXcgaW50W10geyAxMjMgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkRml4ZWQzMi5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEZpeGVkMzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRGaXhlZDMyWzBdKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRGaXhlZDMyID0gbmV3IGludFtdIHsgMTIzLCA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkRml4ZWQzMi5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTUpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRGaXhlZDMyLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkRml4ZWQzMlswXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbmV3TXNnLnJlcGVhdGVkRml4ZWQzMlsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkRml4ZWQ2NCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkRml4ZWQ2NC5sZW5ndGgpOworICAgIG1zZy5yZXBlYXRlZEZpeGVkNjQgPSBuZXcgbG9uZ1tdIHsgMTIzLCA3ODksIDQ1NiB9OworICAgIGFzc2VydEVxdWFscyg3ODksIG1zZy5yZXBlYXRlZEZpeGVkNjRbMV0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZEZpeGVkNjRbMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRGaXhlZDY0Lmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRGaXhlZDY0ID0gbmV3IGxvbmdbXSB7IDQ1NiB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRGaXhlZDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkRml4ZWQ2NFswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEZpeGVkNjQubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkRml4ZWQ2NCA9IG5ldyBsb25nW10geyAxMjMgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkRml4ZWQ2NC5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTMpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRGaXhlZDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkRml4ZWQ2NFswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkRml4ZWQ2NCA9IG5ldyBsb25nW10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRGaXhlZDY0Lmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAyMyk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZEZpeGVkNjQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRGaXhlZDY0WzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRGaXhlZDY0WzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRTZml4ZWQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkU2ZpeGVkMzIubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRTZml4ZWQzMiA9IG5ldyBpbnRbXSB7IDEyMywgNzg5LCA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBtc2cucmVwZWF0ZWRTZml4ZWQzMlsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkU2ZpeGVkMzJbMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRTZml4ZWQzMi5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU2ZpeGVkMzIgPSBuZXcgaW50W10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkU2ZpeGVkMzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRTZml4ZWQzMlswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFNmaXhlZDMyLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFNmaXhlZDMyID0gbmV3IGludFtdIHsgMTIzIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFNmaXhlZDMyLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA5KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkU2ZpeGVkMzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRTZml4ZWQzMlswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU2ZpeGVkMzIgPSBuZXcgaW50W10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRTZml4ZWQzMi5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTUpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRTZml4ZWQzMi5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5yZXBlYXRlZFNmaXhlZDMyWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRTZml4ZWQzMlsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkU2ZpeGVkNjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFNmaXhlZDY0Lmxlbmd0aCk7CisgICAgbXNnLnJlcGVhdGVkU2ZpeGVkNjQgPSBuZXcgbG9uZ1tdIHsgMTIzLCA3ODksIDQ1NiB9OworICAgIGFzc2VydEVxdWFscyg3ODksIG1zZy5yZXBlYXRlZFNmaXhlZDY0WzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRTZml4ZWQ2NFsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFNmaXhlZDY0Lmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTZml4ZWQ2NCA9IG5ldyBsb25nW10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkU2ZpeGVkNjQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRTZml4ZWQ2NFswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFNmaXhlZDY0Lmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFNmaXhlZDY0ID0gbmV3IGxvbmdbXSB7IDEyMyB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRTZml4ZWQ2NC5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTMpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRTZml4ZWQ2NC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5yZXBlYXRlZFNmaXhlZDY0WzBdKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTZml4ZWQ2NCA9IG5ldyBsb25nW10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRTZml4ZWQ2NC5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMjMpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRTZml4ZWQ2NC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5yZXBlYXRlZFNmaXhlZDY0WzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRTZml4ZWQ2NFsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkRmxvYXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEZsb2F0Lmxlbmd0aCk7CisgICAgbXNnLnJlcGVhdGVkRmxvYXQgPSBuZXcgZmxvYXRbXSB7IDEyM2YsIDc4OWYsIDQ1NmYgfTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5ZiwgbXNnLnJlcGVhdGVkRmxvYXRbMV0pOworICAgIGFzc2VydEVxdWFscyg0NTZmLCBtc2cucmVwZWF0ZWRGbG9hdFsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEZsb2F0Lmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRGbG9hdCA9IG5ldyBmbG9hdFtdIHsgNDU2ZiB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRGbG9hdC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyg0NTZmLCBtc2cucmVwZWF0ZWRGbG9hdFswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEZsb2F0Lmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZsb2F0ID0gbmV3IGZsb2F0W10geyAxMjNmIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEZsb2F0Lmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA5KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkRmxvYXQubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzZiwgbmV3TXNnLnJlcGVhdGVkRmxvYXRbMF0pOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZsb2F0ID0gbmV3IGZsb2F0W10geyAxMjNmLCA0NTZmIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEZsb2F0Lmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxNSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZEZsb2F0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyM2YsIG5ld01zZy5yZXBlYXRlZEZsb2F0WzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2ZiwgbmV3TXNnLnJlcGVhdGVkRmxvYXRbMV0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9SZXBlYXRlZERvdWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkRG91YmxlLmxlbmd0aCk7CisgICAgbXNnLnJlcGVhdGVkRG91YmxlID0gbmV3IGRvdWJsZVtdIHsgMTIzLjAsIDc4OS4wLCA0NTYuMCB9OworICAgIGFzc2VydEVxdWFscyg3ODkuMCwgbXNnLnJlcGVhdGVkRG91YmxlWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LjAsIG1zZy5yZXBlYXRlZERvdWJsZVsyXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZERvdWJsZS5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkRG91YmxlID0gbmV3IGRvdWJsZVtdIHsgNDU2LjAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkRG91YmxlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1Ni4wLCBtc2cucmVwZWF0ZWREb3VibGVbMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWREb3VibGUubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkRG91YmxlID0gbmV3IGRvdWJsZVtdIHsgMTIzLjAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkRG91YmxlLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMyk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZERvdWJsZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMuMCwgbmV3TXNnLnJlcGVhdGVkRG91YmxlWzBdKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWREb3VibGUgPSBuZXcgZG91YmxlW10geyAxMjMuMCwgNDU2LjAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkRG91YmxlLmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAyMyk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZERvdWJsZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxMjMuMCwgbmV3TXNnLnJlcGVhdGVkRG91YmxlWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LjAsIG5ld01zZy5yZXBlYXRlZERvdWJsZVsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkQm9vbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkQm9vbC5sZW5ndGgpOworICAgIG1zZy5yZXBlYXRlZEJvb2wgPSBuZXcgYm9vbGVhbltdIHsgZmFsc2UsIHRydWUsIGZhbHNlIH07CisgICAgYXNzZXJ0VHJ1ZShtc2cucmVwZWF0ZWRCb29sWzFdKTsKKyAgICBhc3NlcnRGYWxzZShtc2cucmVwZWF0ZWRCb29sWzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkQm9vbC5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkQm9vbCA9IG5ldyBib29sZWFuW10geyB0cnVlIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEJvb2wubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZy5yZXBlYXRlZEJvb2xbMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRCb29sLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEJvb2wgPSBuZXcgYm9vbGVhbltdIHsgZmFsc2UgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkQm9vbC5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEJvb2wubGVuZ3RoKTsKKyAgICBhc3NlcnRGYWxzZShuZXdNc2cucmVwZWF0ZWRCb29sWzBdKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRCb29sID0gbmV3IGJvb2xlYW5bXSB7IHRydWUsIGZhbHNlIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEJvb2wubGVuZ3RoKTsKKyAgICByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDkpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRCb29sLmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cucmVwZWF0ZWRCb29sWzBdKTsKKyAgICBhc3NlcnRGYWxzZShuZXdNc2cucmVwZWF0ZWRCb29sWzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFN0cmluZy5sZW5ndGgpOworICAgIG1zZy5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbXSB7ICJoZWxsbyIsICJieWUiLCAiYm9vIiB9OworICAgIGFzc2VydEVxdWFscygiYnllIiwgbXNnLnJlcGVhdGVkU3RyaW5nWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoImJvbyIsIG1zZy5yZXBlYXRlZFN0cmluZ1syXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFN0cmluZy5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU3RyaW5nID0gbmV3IFN0cmluZ1tdIHsgImJvbyIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkU3RyaW5nLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKCJib28iLCBtc2cucmVwZWF0ZWRTdHJpbmdbMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRTdHJpbmcubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU3RyaW5nID0gbmV3IFN0cmluZ1tdIHsgIiIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkU3RyaW5nLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkU3RyaW5nLmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cucmVwZWF0ZWRTdHJpbmdbMF0uaXNFbXB0eSgpKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTdHJpbmcgPSBuZXcgU3RyaW5nW10geyAiaGVsbG8iLCAid29ybGQiIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZFN0cmluZy5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTkpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRTdHJpbmcubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbmV3TXNnLnJlcGVhdGVkU3RyaW5nWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoIndvcmxkIiwgbmV3TXNnLnJlcGVhdGVkU3RyaW5nWzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRCeXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkQnl0ZXMubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlW11bXSB7CisgICAgICAgIEludGVybmFsTmFuby5jb3B5RnJvbVV0ZjgoImhlbGxvIiksCisgICAgICAgIEludGVybmFsTmFuby5jb3B5RnJvbVV0ZjgoImJ5ZSIpLAorICAgICAgICBJbnRlcm5hbE5hbm8uY29weUZyb21VdGY4KCJib28iKQorICAgIH07CisgICAgYXNzZXJ0RXF1YWxzKCJieWUiLCBuZXcgU3RyaW5nKG1zZy5yZXBlYXRlZEJ5dGVzWzFdLCAiVVRGLTgiKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJib28iLCBuZXcgU3RyaW5nKG1zZy5yZXBlYXRlZEJ5dGVzWzJdLCAiVVRGLTgiKSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEJ5dGVzLmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlW11bXSB7IEludGVybmFsTmFuby5jb3B5RnJvbVV0ZjgoImJvbyIpIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEJ5dGVzLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKCJib28iLCBuZXcgU3RyaW5nKG1zZy5yZXBlYXRlZEJ5dGVzWzBdLCAiVVRGLTgiKSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEJ5dGVzLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEJ5dGVzID0gbmV3IGJ5dGVbXVtdIHsgSW50ZXJuYWxOYW5vLmNvcHlGcm9tVXRmOCgiIikgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkQnl0ZXMubGVuZ3RoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDYpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRCeXRlcy5sZW5ndGgpOworICAgIGFzc2VydFRydWUobmV3TXNnLnJlcGVhdGVkQnl0ZXNbMF0ubGVuZ3RoID09IDApOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEJ5dGVzID0gbmV3IGJ5dGVbXVtdIHsKKyAgICAgIEludGVybmFsTmFuby5jb3B5RnJvbVV0ZjgoImhlbGxvIiksCisgICAgICBJbnRlcm5hbE5hbm8uY29weUZyb21VdGY4KCJ3b3JsZCIpCisgICAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkQnl0ZXMubGVuZ3RoKTsKKyAgICByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDE5KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbmV3TXNnLnJlcGVhdGVkQnl0ZXMubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbmV3IFN0cmluZyhuZXdNc2cucmVwZWF0ZWRCeXRlc1swXSwgIlVURi04IikpOworICAgIGFzc2VydEVxdWFscygid29ybGQiLCBuZXcgU3RyaW5nKG5ld01zZy5yZXBlYXRlZEJ5dGVzWzFdLCAiVVRGLTgiKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgVGVzdEFsbFR5cGVzTmFuby5SZXBlYXRlZEdyb3VwIGdyb3VwMCA9CisgICAgICBuZXcgVGVzdEFsbFR5cGVzTmFuby5SZXBlYXRlZEdyb3VwKCk7CisgICAgZ3JvdXAwLmEgPSAwOworICAgIFRlc3RBbGxUeXBlc05hbm8uUmVwZWF0ZWRHcm91cCBncm91cDEgPQorICAgICAgbmV3IFRlc3RBbGxUeXBlc05hbm8uUmVwZWF0ZWRHcm91cCgpOworICAgIGdyb3VwMS5hID0gMTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vLlJlcGVhdGVkR3JvdXAgZ3JvdXAyID0KKyAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLlJlcGVhdGVkR3JvdXAoKTsKKyAgICBncm91cDIuYSA9IDI7CisKKyAgICBtc2cucmVwZWF0ZWRHcm91cCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLlJlcGVhdGVkR3JvdXBbXSB7IGdyb3VwMCwgZ3JvdXAxLCBncm91cDIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbXNnLnJlcGVhdGVkR3JvdXAubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkR3JvdXBbMF0uYSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEdyb3VwWzFdLmEpOworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRHcm91cFsyXS5hKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkR3JvdXAubGVuZ3RoKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEdyb3VwID0gbmV3IFRlc3RBbGxUeXBlc05hbm8uUmVwZWF0ZWRHcm91cFtdIHsgZ3JvdXAxIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEdyb3VwLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZEdyb3VwWzBdLmEpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRHcm91cC5sZW5ndGgpOworCisgICAgLy8gVGVzdCAxIGVudHJ5CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRHcm91cCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLlJlcGVhdGVkR3JvdXBbXSB7IGdyb3VwMCB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRHcm91cC5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNyk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEdyb3VwLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5yZXBlYXRlZEdyb3VwWzBdLmEpOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEdyb3VwID0gbmV3IFRlc3RBbGxUeXBlc05hbm8uUmVwZWF0ZWRHcm91cFtdIHsgZ3JvdXAwLCBncm91cDEgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkR3JvdXAubGVuZ3RoKTsKKyAgICByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDE0KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbmV3TXNnLnJlcGVhdGVkR3JvdXAubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbmV3TXNnLnJlcGVhdGVkR3JvdXBbMF0uYSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEdyb3VwWzFdLmEpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9SZXBlYXRlZE5lc3RlZE1lc3NhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlIG5lc3RlZE1zZzAgPQorICAgICAgbmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSgpOworICAgIG5lc3RlZE1zZzAuYmIgPSAwOworICAgIFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSBuZXN0ZWRNc2cxID0KKyAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBuZXN0ZWRNc2cxLmJiID0gMTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTXNnMiA9CisgICAgICBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbmVzdGVkTXNnMi5iYiA9IDI7CisKKyAgICBtc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlID0KKyAgICAgICAgbmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZVtdIHsgbmVzdGVkTXNnMCwgbmVzdGVkTXNnMSwgbmVzdGVkTXNnMiB9OworICAgIGFzc2VydEVxdWFscygzLCBtc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMF0uYmIpOworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzFdLmJiKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVsyXS5iYik7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UubGVuZ3RoKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlW10geyBuZXN0ZWRNc2cxIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVswXS5iYik7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2VbXSB7IG5lc3RlZE1zZzAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZS5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbmV3TXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVswXS5iYik7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2VbXSB7IG5lc3RlZE1zZzAsIG5lc3RlZE1zZzEgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZS5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTEpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMF0uYmIpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzFdLmJiKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBOYW5vT3V0ZXJDbGFzcy5Gb3JlaWduTWVzc2FnZU5hbm8gZm9yZWlnbk1zZzAgPQorICAgICAgbmV3IE5hbm9PdXRlckNsYXNzLkZvcmVpZ25NZXNzYWdlTmFubygpOworICAgIGZvcmVpZ25Nc2cwLmMgPSAwOworICAgIE5hbm9PdXRlckNsYXNzLkZvcmVpZ25NZXNzYWdlTmFubyBmb3JlaWduTXNnMSA9CisgICAgICBuZXcgTmFub091dGVyQ2xhc3MuRm9yZWlnbk1lc3NhZ2VOYW5vKCk7CisgICAgZm9yZWlnbk1zZzEuYyA9IDE7CisgICAgTmFub091dGVyQ2xhc3MuRm9yZWlnbk1lc3NhZ2VOYW5vIGZvcmVpZ25Nc2cyID0KKyAgICAgIG5ldyBOYW5vT3V0ZXJDbGFzcy5Gb3JlaWduTWVzc2FnZU5hbm8oKTsKKyAgICBmb3JlaWduTXNnMi5jID0gMjsKKworICAgIG1zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlID0KKyAgICAgICAgbmV3IE5hbm9PdXRlckNsYXNzLkZvcmVpZ25NZXNzYWdlTmFub1tdIHsgZm9yZWlnbk1zZzAsIGZvcmVpZ25Nc2cxLCBmb3JlaWduTXNnMiB9OworICAgIGFzc2VydEVxdWFscygzLCBtc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZVswXS5jKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VbMV0uYyk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlWzJdLmMpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZS5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UgPSBuZXcgTmFub091dGVyQ2xhc3MuRm9yZWlnbk1lc3NhZ2VOYW5vW10geyBmb3JlaWduTXNnMSB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZVswXS5jKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UgPSBuZXcgTmFub091dGVyQ2xhc3MuRm9yZWlnbk1lc3NhZ2VOYW5vW10geyBmb3JlaWduTXNnMCB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZS5sZW5ndGgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlWzBdLmMpOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlID0gbmV3IE5hbm9PdXRlckNsYXNzLkZvcmVpZ25NZXNzYWdlTmFub1tdIHsgZm9yZWlnbk1zZzAsIGZvcmVpZ25Nc2cxIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlLmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlWzBdLmMpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRGb3JlaWduTWVzc2FnZVsxXS5jKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIFVuaXR0ZXN0SW1wb3J0TmFuby5JbXBvcnRNZXNzYWdlTmFubyBmb3JlaWduTXNnMCA9CisgICAgICBuZXcgVW5pdHRlc3RJbXBvcnROYW5vLkltcG9ydE1lc3NhZ2VOYW5vKCk7CisgICAgZm9yZWlnbk1zZzAuZCA9IDA7CisgICAgVW5pdHRlc3RJbXBvcnROYW5vLkltcG9ydE1lc3NhZ2VOYW5vIGZvcmVpZ25Nc2cxID0KKyAgICAgIG5ldyBVbml0dGVzdEltcG9ydE5hbm8uSW1wb3J0TWVzc2FnZU5hbm8oKTsKKyAgICBmb3JlaWduTXNnMS5kID0gMTsKKyAgICBVbml0dGVzdEltcG9ydE5hbm8uSW1wb3J0TWVzc2FnZU5hbm8gZm9yZWlnbk1zZzIgPQorICAgICAgbmV3IFVuaXR0ZXN0SW1wb3J0TmFuby5JbXBvcnRNZXNzYWdlTmFubygpOworICAgIGZvcmVpZ25Nc2cyLmQgPSAyOworCisgICAgbXNnLnJlcGVhdGVkSW1wb3J0TWVzc2FnZSA9CisgICAgICAgIG5ldyBVbml0dGVzdEltcG9ydE5hbm8uSW1wb3J0TWVzc2FnZU5hbm9bXSB7IGZvcmVpZ25Nc2cwLCBmb3JlaWduTXNnMSwgZm9yZWlnbk1zZzIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbXNnLnJlcGVhdGVkSW1wb3J0TWVzc2FnZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlWzBdLmQpOworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlWzFdLmQpOworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlWzJdLmQpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlLmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRJbXBvcnRNZXNzYWdlID0gbmV3IFVuaXR0ZXN0SW1wb3J0TmFuby5JbXBvcnRNZXNzYWdlTmFub1tdIHsgZm9yZWlnbk1zZzEgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkSW1wb3J0TWVzc2FnZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlWzBdLmQpOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEltcG9ydE1lc3NhZ2UgPSBuZXcgVW5pdHRlc3RJbXBvcnROYW5vLkltcG9ydE1lc3NhZ2VOYW5vW10geyBmb3JlaWduTXNnMCB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkSW1wb3J0TWVzc2FnZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygwLCBuZXdNc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlWzBdLmQpOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEltcG9ydE1lc3NhZ2UgPSBuZXcgVW5pdHRlc3RJbXBvcnROYW5vLkltcG9ydE1lc3NhZ2VOYW5vW10geyBmb3JlaWduTXNnMCwgZm9yZWlnbk1zZzEgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkSW1wb3J0TWVzc2FnZS5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTEpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRJbXBvcnRNZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5yZXBlYXRlZEltcG9ydE1lc3NhZ2VbMF0uZCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEltcG9ydE1lc3NhZ2VbMV0uZCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkTmVzdGVkRW51bSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cucmVwZWF0ZWROZXN0ZWRFbnVtID0gbmV3IGludFtdIHsKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5GT08sCisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uQkFSLAorICAgICAgICBUZXN0QWxsVHlwZXNOYW5vLkJBWgorICAgIH07CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1zZy5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG1zZy5yZXBlYXRlZE5lc3RlZEVudW1bMF0pOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgbXNnLnJlcGVhdGVkTmVzdGVkRW51bVsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm8uQkFaLCBtc2cucmVwZWF0ZWROZXN0ZWRFbnVtWzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7IFRlc3RBbGxUeXBlc05hbm8uQkFSIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVIsIG1zZy5yZXBlYXRlZE5lc3RlZEVudW1bMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWROZXN0ZWRFbnVtLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZE5lc3RlZEVudW0gPSBuZXcgaW50W10geyBUZXN0QWxsVHlwZXNOYW5vLkZPTyB9OworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG1zZy5yZXBlYXRlZE5lc3RlZEVudW1bMF0pOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZE5lc3RlZEVudW0gPSBuZXcgaW50W10geyBUZXN0QWxsVHlwZXNOYW5vLkZPTywgVGVzdEFsbFR5cGVzTmFuby5CQVIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG1zZy5yZXBlYXRlZE5lc3RlZEVudW1bMF0pOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgbXNnLnJlcGVhdGVkTmVzdGVkRW51bVsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkRm9yZWlnbkVudW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLnJlcGVhdGVkRm9yZWlnbkVudW0gPSBuZXcgaW50W10geworICAgICAgICBOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fRk9PLAorICAgICAgICBOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFSLAorICAgICAgICBOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFaCisgICAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbXNnLnJlcGVhdGVkRm9yZWlnbkVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0ZPTywgbXNnLnJlcGVhdGVkRm9yZWlnbkVudW1bMF0pOworICAgIGFzc2VydEVxdWFscyhOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFSLCBtc2cucmVwZWF0ZWRGb3JlaWduRW51bVsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKE5hbm9PdXRlckNsYXNzLkZPUkVJR05fTkFOT19CQVosIG1zZy5yZXBlYXRlZEZvcmVpZ25FbnVtWzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkRm9yZWlnbkVudW0ubGVuZ3RoKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZvcmVpZ25FbnVtID0gbmV3IGludFtdIHsgTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0JBUiB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRGb3JlaWduRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFSLCBtc2cucmVwZWF0ZWRGb3JlaWduRW51bVswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZEZvcmVpZ25FbnVtLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZEZvcmVpZ25FbnVtID0gbmV3IGludFtdIHsgTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0ZPTyB9OworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEZvcmVpZ25FbnVtLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKE5hbm9PdXRlckNsYXNzLkZPUkVJR05fTkFOT19GT08sIG1zZy5yZXBlYXRlZEZvcmVpZ25FbnVtWzBdKTsKKworICAgIC8vIFRlc3QgMiBlbnRyaWVzCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRGb3JlaWduRW51bSA9IG5ldyBpbnRbXSB7CisgICAgICBOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fRk9PLAorICAgICAgTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0JBUgorICAgIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEZvcmVpZ25FbnVtLmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA5KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbmV3TXNnLnJlcGVhdGVkRm9yZWlnbkVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0ZPTywgbXNnLnJlcGVhdGVkRm9yZWlnbkVudW1bMF0pOworICAgIGFzc2VydEVxdWFscyhOYW5vT3V0ZXJDbGFzcy5GT1JFSUdOX05BTk9fQkFSLCBtc2cucmVwZWF0ZWRGb3JlaWduRW51bVsxXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkSW1wb3J0RW51bSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cucmVwZWF0ZWRJbXBvcnRFbnVtID0gbmV3IGludFtdIHsKKyAgICAgICAgVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0ZPTywKKyAgICAgICAgVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0JBUiwKKyAgICAgICAgVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0JBWgorICAgIH07CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1zZy5yZXBlYXRlZEltcG9ydEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0ZPTywgbXNnLnJlcGVhdGVkSW1wb3J0RW51bVswXSk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0SW1wb3J0TmFuby5JTVBPUlRfTkFOT19CQVIsIG1zZy5yZXBlYXRlZEltcG9ydEVudW1bMV0pOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFaLCBtc2cucmVwZWF0ZWRJbXBvcnRFbnVtWzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkSW1wb3J0RW51bS5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkSW1wb3J0RW51bSA9IG5ldyBpbnRbXSB7IFVuaXR0ZXN0SW1wb3J0TmFuby5JTVBPUlRfTkFOT19CQVIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkSW1wb3J0RW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFSLCBtc2cucmVwZWF0ZWRJbXBvcnRFbnVtWzBdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkSW1wb3J0RW51bS5sZW5ndGgpOworCisgICAgLy8gVGVzdCAxIGVudHJ5CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRJbXBvcnRFbnVtID0gbmV3IGludFtdIHsgVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0ZPTyB9OworICAgIGJ5dGUgW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gNik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZEltcG9ydEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0ZPTywgbXNnLnJlcGVhdGVkSW1wb3J0RW51bVswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkSW1wb3J0RW51bSA9IG5ldyBpbnRbXSB7CisgICAgICBVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fRk9PLAorICAgICAgVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0JBUgorICAgIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZEltcG9ydEVudW0ubGVuZ3RoKTsKKyAgICByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDkpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRJbXBvcnRFbnVtLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKFVuaXR0ZXN0SW1wb3J0TmFuby5JTVBPUlRfTkFOT19GT08sIG1zZy5yZXBlYXRlZEltcG9ydEVudW1bMF0pOworICAgIGFzc2VydEVxdWFscyhVbml0dGVzdEltcG9ydE5hbm8uSU1QT1JUX05BTk9fQkFSLCBtc2cucmVwZWF0ZWRJbXBvcnRFbnVtWzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRTdHJpbmdQaWVjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkU3RyaW5nUGllY2UubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRTdHJpbmdQaWVjZSA9IG5ldyBTdHJpbmdbXSB7ICJoZWxsbyIsICJieWUiLCAiYm9vIiB9OworICAgIGFzc2VydEVxdWFscygiYnllIiwgbXNnLnJlcGVhdGVkU3RyaW5nUGllY2VbMV0pOworICAgIGFzc2VydEVxdWFscygiYm9vIiwgbXNnLnJlcGVhdGVkU3RyaW5nUGllY2VbMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRTdHJpbmdQaWVjZS5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU3RyaW5nUGllY2UgPSBuZXcgU3RyaW5nW10geyAiYm9vIiB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRTdHJpbmdQaWVjZS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygiYm9vIiwgbXNnLnJlcGVhdGVkU3RyaW5nUGllY2VbMF0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRTdHJpbmdQaWVjZS5sZW5ndGgpOworCisgICAgLy8gVGVzdCAxIGVudHJ5CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRTdHJpbmdQaWVjZSA9IG5ldyBTdHJpbmdbXSB7ICIiIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFN0cmluZ1BpZWNlLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA2KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkU3RyaW5nUGllY2UubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5yZXBlYXRlZFN0cmluZ1BpZWNlWzBdLmlzRW1wdHkoKSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkU3RyaW5nUGllY2UgPSBuZXcgU3RyaW5nW10geyAiaGVsbG8iLCAid29ybGQiIH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZFN0cmluZ1BpZWNlLmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxOSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZFN0cmluZ1BpZWNlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIG5ld01zZy5yZXBlYXRlZFN0cmluZ1BpZWNlWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoIndvcmxkIiwgbmV3TXNnLnJlcGVhdGVkU3RyaW5nUGllY2VbMV0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9SZXBlYXRlZENvcmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZENvcmQubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRDb3JkID0gbmV3IFN0cmluZ1tdIHsgImhlbGxvIiwgImJ5ZSIsICJib28iIH07CisgICAgYXNzZXJ0RXF1YWxzKCJieWUiLCBtc2cucmVwZWF0ZWRDb3JkWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoImJvbyIsIG1zZy5yZXBlYXRlZENvcmRbMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRDb3JkLmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRDb3JkID0gbmV3IFN0cmluZ1tdIHsgImJvbyIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkQ29yZC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygiYm9vIiwgbXNnLnJlcGVhdGVkQ29yZFswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZENvcmQubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkQ29yZCA9IG5ldyBTdHJpbmdbXSB7ICIiIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZENvcmQubGVuZ3RoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDYpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygxLCBuZXdNc2cucmVwZWF0ZWRDb3JkLmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cucmVwZWF0ZWRDb3JkWzBdLmlzRW1wdHkoKSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkQ29yZCA9IG5ldyBTdHJpbmdbXSB7ICJoZWxsbyIsICJ3b3JsZCIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbXNnLnJlcGVhdGVkQ29yZC5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gMTkpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydEVxdWFscygyLCBuZXdNc2cucmVwZWF0ZWRDb3JkLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIG5ld01zZy5yZXBlYXRlZENvcmRbMF0pOworICAgIGFzc2VydEVxdWFscygid29ybGQiLCBuZXdNc2cucmVwZWF0ZWRDb3JkWzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRQYWNrZWRJbnQzMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkUGFja2VkSW50MzIubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRQYWNrZWRJbnQzMiA9IG5ldyBpbnRbXSB7IDEyMywgNzg5LCA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBtc2cucmVwZWF0ZWRQYWNrZWRJbnQzMlsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQ1NiwgbXNnLnJlcGVhdGVkUGFja2VkSW50MzJbMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRQYWNrZWRJbnQzMi5sZW5ndGgpOworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkUGFja2VkSW50MzIgPSBuZXcgaW50W10geyA0NTYgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkUGFja2VkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBtc2cucmVwZWF0ZWRQYWNrZWRJbnQzMlswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFBhY2tlZEludDMyLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDEgZW50cnkKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFBhY2tlZEludDMyID0gbmV3IGludFtdIHsgMTIzIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFBhY2tlZEludDMyLmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA3KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkUGFja2VkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cucmVwZWF0ZWRQYWNrZWRJbnQzMlswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkUGFja2VkSW50MzIgPSBuZXcgaW50W10geyAxMjMsIDQ1NiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRQYWNrZWRJbnQzMi5sZW5ndGgpOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAvL1N5c3RlbS5vdXQucHJpbnRmKCJtc3M9JWQgcmVzdWx0Lmxlbmd0aD0lZFxuIiwgbXNnU2VyaWFsaXplZFNpemUsIHJlc3VsdC5sZW5ndGgpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPT0gOSk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZFBhY2tlZEludDMyLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkUGFja2VkSW50MzJbMF0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG5ld01zZy5yZXBlYXRlZFBhY2tlZEludDMyWzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRQYWNrZWRTZml4ZWQ2NCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjQubGVuZ3RoKTsKKyAgICBtc2cucmVwZWF0ZWRQYWNrZWRTZml4ZWQ2NCA9IG5ldyBsb25nW10geyAxMjMsIDc4OSwgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDc4OSwgbXNnLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjRbMV0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0WzJdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjQubGVuZ3RoKTsKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0ID0gbmV3IGxvbmdbXSB7IDQ1NiB9OworICAgIGFzc2VydEVxdWFscygxLCBtc2cucmVwZWF0ZWRQYWNrZWRTZml4ZWQ2NC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyg0NTYsIG1zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0WzBdKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjQubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjQgPSBuZXcgbG9uZ1tdIHsgMTIzIH07CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0Lmxlbmd0aCk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxNCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG5ld01zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjRbMF0pOworCisgICAgLy8gVGVzdCAyIGVudHJpZXMKKyAgICBtc2cuY2xlYXIoKQorICAgICAgIC5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0ID0gbmV3IGxvbmdbXSB7IDEyMywgNDU2IH07CisgICAgYXNzZXJ0RXF1YWxzKDIsIG1zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0Lmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAyMik7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbmV3TXNnLnJlcGVhdGVkUGFja2VkU2ZpeGVkNjRbMF0pOworICAgIGFzc2VydEVxdWFscyg0NTYsIG5ld01zZy5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0WzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRQYWNrZWROZXN0ZWRFbnVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW0gPSBuZXcgaW50W10geworICAgICAgICBUZXN0QWxsVHlwZXNOYW5vLkZPTywKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5CQVIsCisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uQkFaCisgICAgfTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkZPTywgbXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bVswXSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm8uQkFSLCBtc2cucmVwZWF0ZWRQYWNrZWROZXN0ZWRFbnVtWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVosIG1zZy5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW1bMl0pOworICAgIG1zZy5jbGVhcigpOworICAgIGFzc2VydEVxdWFscygwLCBtc2cucmVwZWF0ZWRQYWNrZWROZXN0ZWRFbnVtLmxlbmd0aCk7CisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAucmVwZWF0ZWRQYWNrZWROZXN0ZWRFbnVtID0gbmV3IGludFtdIHsgVGVzdEFsbFR5cGVzTmFuby5CQVIgfTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgbXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bVswXSk7CisgICAgbXNnLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1zZy5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMSBlbnRyeQorICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7IFRlc3RBbGxUeXBlc05hbm8uRk9PIH07CisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA3KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgbmV3TXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkZPTywgbXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bVswXSk7CisKKyAgICAvLyBUZXN0IDIgZW50cmllcworICAgIG1zZy5jbGVhcigpCisgICAgICAgLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7IFRlc3RBbGxUeXBlc05hbm8uRk9PLCBUZXN0QWxsVHlwZXNOYW5vLkJBUiB9OworICAgIGFzc2VydEVxdWFscygyLCBtc2cucmVwZWF0ZWRQYWNrZWROZXN0ZWRFbnVtLmxlbmd0aCk7CisgICAgcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSA4KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbmV3TXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkZPTywgbXNnLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bVswXSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm8uQkFSLCBtc2cucmVwZWF0ZWRQYWNrZWROZXN0ZWRFbnVtWzFdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWRQYWNrZWRTZXJpYWxpemVkU2l6ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cucmVwZWF0ZWRQYWNrZWRJbnQzMiA9IG5ldyBpbnRbXSB7IDEyMywgNzg5LCA0NTYgfTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDExKTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnMiA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnMi5yZXBlYXRlZFBhY2tlZEludDMyID0gbmV3IGludFtdIHsgMTIzLCA3ODksIDQ1NiB9OworICAgIGJ5dGUgW10gcmVzdWx0MiA9IG5ldyBieXRlW21zZ1NlcmlhbGl6ZWRTaXplXTsKKyAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cyLCByZXN1bHQyLCAwLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICAvLyBDaGVjayBlcXVhbCBzaXplIGFuZCBjb250ZW50LgorICAgIGFzc2VydEVxdWFscyhtc2dTZXJpYWxpemVkU2l6ZSwgbXNnMi5nZXRTZXJpYWxpemVkU2l6ZSgpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMocmVzdWx0LCByZXN1bHQyKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkSW50MzJSZU1lcmdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHsgMjM0IH07CisgICAgYnl0ZSBbXSByZXN1bHQxID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKworICAgIG1zZy5jbGVhcigpLm9wdGlvbmFsSW50MzIgPSA3ODk7CisgICAgYnl0ZSBbXSByZXN1bHQyID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKworICAgIG1zZy5jbGVhcigpLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyAxMjMsIDQ1NiB9OworICAgIGJ5dGUgW10gcmVzdWx0MyA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisKKyAgICAvLyBDb25jYXRlbmF0ZSB0aGUgdGhyZWUgc2VyaWFsaXphdGlvbnMgYW5kIHJlYWQgYXMgb25lIG1lc3NhZ2UuCisgICAgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtyZXN1bHQxLmxlbmd0aCArIHJlc3VsdDIubGVuZ3RoICsgcmVzdWx0My5sZW5ndGhdOworICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0MSwgMCwgcmVzdWx0LCAwLCByZXN1bHQxLmxlbmd0aCk7CisgICAgU3lzdGVtLmFycmF5Y29weShyZXN1bHQyLCAwLCByZXN1bHQsIHJlc3VsdDEubGVuZ3RoLCByZXN1bHQyLmxlbmd0aCk7CisgICAgU3lzdGVtLmFycmF5Y29weShyZXN1bHQzLCAwLCByZXN1bHQsIHJlc3VsdDEubGVuZ3RoICsgcmVzdWx0Mi5sZW5ndGgsIHJlc3VsdDMubGVuZ3RoKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBuZXdNc2cub3B0aW9uYWxJbnQzMik7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG5ld01zZy5yZXBlYXRlZEludDMyLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDIzNCwgbmV3TXNnLnJlcGVhdGVkSW50MzJbMF0pOworICAgIGFzc2VydEVxdWFscygxMjMsIG5ld01zZy5yZXBlYXRlZEludDMyWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoNDU2LCBuZXdNc2cucmVwZWF0ZWRJbnQzMlsyXSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1JlcGVhdGVkTmVzdGVkRW51bVJlTWVyZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7IFRlc3RBbGxUeXBlc05hbm8uRk9PIH07CisgICAgYnl0ZSBbXSByZXN1bHQxID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKworICAgIG1zZy5jbGVhcigpLm9wdGlvbmFsSW50MzIgPSA3ODk7CisgICAgYnl0ZSBbXSByZXN1bHQyID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKworICAgIG1zZy5jbGVhcigpLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7IFRlc3RBbGxUeXBlc05hbm8uQkFSLCBUZXN0QWxsVHlwZXNOYW5vLkZPTyB9OworICAgIGJ5dGUgW10gcmVzdWx0MyA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisKKyAgICAvLyBDb25jYXRlbmF0ZSB0aGUgdGhyZWUgc2VyaWFsaXphdGlvbnMgYW5kIHJlYWQgYXMgb25lIG1lc3NhZ2UuCisgICAgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtyZXN1bHQxLmxlbmd0aCArIHJlc3VsdDIubGVuZ3RoICsgcmVzdWx0My5sZW5ndGhdOworICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0MSwgMCwgcmVzdWx0LCAwLCByZXN1bHQxLmxlbmd0aCk7CisgICAgU3lzdGVtLmFycmF5Y29weShyZXN1bHQyLCAwLCByZXN1bHQsIHJlc3VsdDEubGVuZ3RoLCByZXN1bHQyLmxlbmd0aCk7CisgICAgU3lzdGVtLmFycmF5Y29weShyZXN1bHQzLCAwLCByZXN1bHQsIHJlc3VsdDEubGVuZ3RoICsgcmVzdWx0Mi5sZW5ndGgsIHJlc3VsdDMubGVuZ3RoKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFuby5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoNzg5LCBuZXdNc2cub3B0aW9uYWxJbnQzMik7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG5ld01zZy5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG5ld01zZy5yZXBlYXRlZE5lc3RlZEVudW1bMF0pOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgbmV3TXNnLnJlcGVhdGVkTmVzdGVkRW51bVsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm8uRk9PLCBuZXdNc2cucmVwZWF0ZWROZXN0ZWRFbnVtWzJdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vUmVwZWF0ZWROZXN0ZWRNZXNzYWdlUmVNZXJnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTXNnMCA9CisgICAgICBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbmVzdGVkTXNnMC5iYiA9IDA7CisgICAgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlIG5lc3RlZE1zZzEgPQorICAgICAgbmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSgpOworICAgIG5lc3RlZE1zZzEuYmIgPSAxOworICAgIFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSBuZXN0ZWRNc2cyID0KKyAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBuZXN0ZWRNc2cyLmJiID0gMjsKKworICAgIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlW10geyBuZXN0ZWRNc2cwIH07CisgICAgYnl0ZSBbXSByZXN1bHQxID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKworICAgIG1zZy5jbGVhcigpLm9wdGlvbmFsSW50MzIgPSA3ODk7CisgICAgYnl0ZSBbXSByZXN1bHQyID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKworICAgIG1zZy5jbGVhcigpLnJlcGVhdGVkTmVzdGVkTWVzc2FnZSA9CisgICAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2VbXSB7IG5lc3RlZE1zZzEsIG5lc3RlZE1zZzIgfTsKKyAgICBieXRlIFtdIHJlc3VsdDMgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworCisgICAgLy8gQ29uY2F0ZW5hdGUgdGhlIHRocmVlIHNlcmlhbGl6YXRpb25zIGFuZCByZWFkIGFzIG9uZSBtZXNzYWdlLgorICAgIGJ5dGUgW10gcmVzdWx0ID0gbmV3IGJ5dGVbcmVzdWx0MS5sZW5ndGggKyByZXN1bHQyLmxlbmd0aCArIHJlc3VsdDMubGVuZ3RoXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KHJlc3VsdDEsIDAsIHJlc3VsdCwgMCwgcmVzdWx0MS5sZW5ndGgpOworICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0MiwgMCwgcmVzdWx0LCByZXN1bHQxLmxlbmd0aCwgcmVzdWx0Mi5sZW5ndGgpOworICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0MywgMCwgcmVzdWx0LCByZXN1bHQxLmxlbmd0aCArIHJlc3VsdDIubGVuZ3RoLCByZXN1bHQzLmxlbmd0aCk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG5ld01zZyA9IFRlc3RBbGxUeXBlc05hbm8ucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDc4OSwgbmV3TXNnLm9wdGlvbmFsSW50MzIpOworICAgIGFzc2VydEVxdWFscygzLCBuZXdNc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKG5lc3RlZE1zZzAuYmIsIG5ld01zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMF0uYmIpOworICAgIGFzc2VydEVxdWFscyhuZXN0ZWRNc2cxLmJiLCBuZXdNc2cucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzFdLmJiKTsKKyAgICBhc3NlcnRFcXVhbHMobmVzdGVkTXNnMi5iYiwgbmV3TXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVsyXS5iYik7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCBpbnZhbGlkIGVudW0gdmFsdWVzIGZyb20gdGhlIHdpcmUgYXJlIG5vdCBhY2NlcHRlZC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vRW51bVZhbGlkaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IGludmFsaWQgPSAxMjA7CisgICAgZmluYWwgaW50IGFsc29JbnZhbGlkID0gMTIxOworCisgICAgRW51bVZhbGlkaXR5Lk0gbSA9IG5ldyBFbnVtVmFsaWRpdHkuTSgpOworICAgIC8vIFNhbml0eSBjaGVjayAmIGJhc2VsaW5lIG9mIHRoZSBhc3NlcnRpb25zIGZvciB0aGUgZmlyc3QgY2FzZSBiZWxvdy4KKyAgICBhc3NlcnRFcXVhbHMoRW51bVZhbGlkaXR5LkUuZGVmYXVsdF8sIG0ub3B0aW9uYWxFKTsKKyAgICBhc3NlcnRFcXVhbHMoRW51bVZhbGlkaXR5LkUuQkFaLCBtLmRlZmF1bHRFKTsKKworICAgIG0ub3B0aW9uYWxFID0gaW52YWxpZDsKKyAgICBtLmRlZmF1bHRFID0gaW52YWxpZDsKKyAgICAvLyBFIGNvbnRhaW5zIGFsbCB2YWxpZCB2YWx1ZXMKKyAgICBtLnJlcGVhdGVkRSA9IG5ldyBpbnRbXSB7RW51bVZhbGlkaXR5LkUuRk9PLCBFbnVtVmFsaWRpdHkuRS5CQVJ9OworICAgIG0ucGFja2VkRSA9IG5ldyBpbnRbXSB7RW51bVZhbGlkaXR5LkUuRk9PLCBFbnVtVmFsaWRpdHkuRS5CQVp9OworICAgIC8vIEUyIGNvbnRhaW5zIHNvbWUgaW52YWxpZCB2YWx1ZXMKKyAgICBtLnJlcGVhdGVkRTIgPSBuZXcgaW50W10ge2ludmFsaWQsIEVudW1WYWxpZGl0eS5FLkJBUiwgYWxzb0ludmFsaWR9OworICAgIG0ucGFja2VkRTIgPSBuZXcgaW50W10ge0VudW1WYWxpZGl0eS5FLkZPTywgaW52YWxpZCwgYWxzb0ludmFsaWR9OworICAgIC8vIEUzIGNvbnRhaW5zIGFsbCBpbnZhbGlkIHZhbHVlcworICAgIG0ucmVwZWF0ZWRFMyA9IG5ldyBpbnRbXSB7aW52YWxpZCwgaW52YWxpZH07CisgICAgbS5wYWNrZWRFMyA9IG5ldyBpbnRbXSB7YWxzb0ludmFsaWQsIGFsc29JbnZhbGlkfTsKKyAgICBieXRlW10gc2VyaWFsaXplZCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0pOworICAgIC8vIFNhbml0eSBjaGVjayB0aGF0IHdlIGRvIGhhdmUgYWxsIGRhdGEgaW4gdGhlIGJ5dGUgYXJyYXkuCisgICAgYXNzZXJ0RXF1YWxzKDMxLCBzZXJpYWxpemVkLmxlbmd0aCk7CisKKyAgICAvLyBUZXN0IDE6IHRlc3RzIHRoYXQgaW52YWxpZCB2YWx1ZXMgYXJlbid0IGluY2x1ZGVkIGluIHRoZSBkZXNlcmlhbGl6ZWQgbWVzc2FnZS4KKyAgICBFbnVtVmFsaWRpdHkuTSBkZXNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IEVudW1WYWxpZGl0eS5NKCksIHNlcmlhbGl6ZWQpOworICAgIGFzc2VydEVxdWFscyhFbnVtVmFsaWRpdHkuRS5kZWZhdWx0XywgZGVzZXJpYWxpemVkLm9wdGlvbmFsRSk7CisgICAgYXNzZXJ0RXF1YWxzKEVudW1WYWxpZGl0eS5FLkJBWiwgZGVzZXJpYWxpemVkLmRlZmF1bHRFKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoCisgICAgICAgIG5ldyBpbnRbXSB7RW51bVZhbGlkaXR5LkUuRk9PLCBFbnVtVmFsaWRpdHkuRS5CQVJ9LCBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRFKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKAorICAgICAgICBuZXcgaW50W10ge0VudW1WYWxpZGl0eS5FLkZPTywgRW51bVZhbGlkaXR5LkUuQkFafSwgZGVzZXJpYWxpemVkLnBhY2tlZEUpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoCisgICAgICAgIG5ldyBpbnRbXSB7RW51bVZhbGlkaXR5LkUuQkFSfSwgZGVzZXJpYWxpemVkLnJlcGVhdGVkRTIpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoCisgICAgICAgIG5ldyBpbnRbXSB7RW51bVZhbGlkaXR5LkUuRk9PfSwgZGVzZXJpYWxpemVkLnBhY2tlZEUyKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGRlc2VyaWFsaXplZC5yZXBlYXRlZEUzLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGRlc2VyaWFsaXplZC5wYWNrZWRFMy5sZW5ndGgpOworCisgICAgLy8gVGVzdCAyOiB0ZXN0cyB0aGF0IGludmFsaWQgdmFsdWVzIGRvIG5vdCBvdmVycmlkZSBwcmV2aW91cyB2YWx1ZXMgaW4gdGhlIGZpZWxkLCBpbmNsdWRpbmcKKyAgICAvLyBhcnJheXMsIGluY2x1ZGluZyBwcmUtZXhpc3RpbmcgaW52YWxpZCB2YWx1ZXMuCisgICAgZGVzZXJpYWxpemVkLm9wdGlvbmFsRSA9IEVudW1WYWxpZGl0eS5FLkJBUjsKKyAgICBkZXNlcmlhbGl6ZWQuZGVmYXVsdEUgPSBhbHNvSW52YWxpZDsKKyAgICBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRFID0gbmV3IGludFtdIHtFbnVtVmFsaWRpdHkuRS5CQVp9OworICAgIGRlc2VyaWFsaXplZC5wYWNrZWRFID0gbmV3IGludFtdIHtFbnVtVmFsaWRpdHkuRS5CQVosIGFsc29JbnZhbGlkfTsKKyAgICBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRFMiA9IG5ldyBpbnRbXSB7aW52YWxpZCwgYWxzb0ludmFsaWR9OworICAgIGRlc2VyaWFsaXplZC5wYWNrZWRFMiA9IG51bGw7CisgICAgZGVzZXJpYWxpemVkLnJlcGVhdGVkRTMgPSBudWxsOworICAgIGRlc2VyaWFsaXplZC5wYWNrZWRFMyA9IG5ldyBpbnRbMF07CisgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKGRlc2VyaWFsaXplZCwgc2VyaWFsaXplZCk7CisgICAgYXNzZXJ0RXF1YWxzKEVudW1WYWxpZGl0eS5FLkJBUiwgZGVzZXJpYWxpemVkLm9wdGlvbmFsRSk7CisgICAgYXNzZXJ0RXF1YWxzKGFsc29JbnZhbGlkLCBkZXNlcmlhbGl6ZWQuZGVmYXVsdEUpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscygKKyAgICAgICAgbmV3IGludFtdIHtFbnVtVmFsaWRpdHkuRS5CQVosIC8qICsgKi8gRW51bVZhbGlkaXR5LkUuRk9PLCBFbnVtVmFsaWRpdHkuRS5CQVJ9LAorICAgICAgICBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRFKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKAorICAgICAgICBuZXcgaW50W10ge0VudW1WYWxpZGl0eS5FLkJBWiwgYWxzb0ludmFsaWQsIC8qICsgKi8gRW51bVZhbGlkaXR5LkUuRk9PLCBFbnVtVmFsaWRpdHkuRS5CQVp9LAorICAgICAgICBkZXNlcmlhbGl6ZWQucGFja2VkRSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscygKKyAgICAgICAgbmV3IGludFtdIHtpbnZhbGlkLCBhbHNvSW52YWxpZCwgLyogKyAqLyBFbnVtVmFsaWRpdHkuRS5CQVJ9LAorICAgICAgICBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRFMikpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscygKKyAgICAgICAgbmV3IGludFtdIHsvKiA8bnVsbD4gKyAqLyBFbnVtVmFsaWRpdHkuRS5GT099LAorICAgICAgICBkZXNlcmlhbGl6ZWQucGFja2VkRTIpKTsKKyAgICBhc3NlcnROdWxsKGRlc2VyaWFsaXplZC5yZXBlYXRlZEUzKTsgLy8gbnVsbCArIGFsbCBpbnZhbGlkID09IG51bGwKKyAgICBhc3NlcnRFcXVhbHMoMCwgZGVzZXJpYWxpemVkLnBhY2tlZEUzLmxlbmd0aCk7IC8vIGVtcHR5ICsgYWxsIGludmFsaWQgPT0gZW1wdHkKKworICAgIC8vIFRlc3QgMzogcmVhZGluZyBieSBhbHRlcm5hdGl2ZSBmb3JtcworICAgIEVudW1WYWxpZGl0eS5BbHQgYWx0ID0gTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBFbnVtVmFsaWRpdHkuQWx0KCksIHNlcmlhbGl6ZWQpOworICAgIGFzc2VydEVxdWFscyhFbnVtVmFsaWRpdHkuRS5CQVIsIC8vIGxhc3QgdmFsaWQgdmFsdWUgaW4gbS5yZXBlYXRlZEUyCisgICAgICAgIGFsdC5yZXBlYXRlZEUyQXNPcHRpb25hbCk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBpbnRbXSB7RW51bVZhbGlkaXR5LkUuRk9PfSwgYWx0LnBhY2tlZEUyQXNOb25QYWNrZWQpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgYWx0Lm5vblBhY2tlZEUzQXNQYWNrZWQubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyB0aGUgc2FtZSBhcyB7QGxpbmsgI3Rlc3ROYW5vRW51bVZhbGlkaXR5KCl9IHdpdGggYWNjZXNzb3Igc3R5bGUuIFJlcGVhdGVkIGZpZWxkcyBhcmUKKyAgICogbm90IHJlLXRlc3RlZCBoZXJlIGJlY2F1c2UgdGhleSBhcmUgbm90IGFmZmVjdGVkIGJ5IHRoZSBhY2Nlc3NvciBzdHlsZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vRW51bVZhbGlkaXR5QWNjZXNzb3JzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IGludmFsaWQgPSAxMjA7CisgICAgZmluYWwgaW50IGFsc29JbnZhbGlkID0gMTIxOworCisgICAgRW51bVZhbGlkaXR5QWNjZXNzb3JzLk0gbSA9IG5ldyBFbnVtVmFsaWRpdHlBY2Nlc3NvcnMuTSgpOworICAgIC8vIFNhbml0eSBjaGVjayAmIGJhc2VsaW5lIG9mIHRoZSBhc3NlcnRpb25zIGZvciB0aGUgZmlyc3QgY2FzZSBiZWxvdy4KKyAgICBhc3NlcnRFcXVhbHMoRW51bVZhbGlkaXR5QWNjZXNzb3JzLmRlZmF1bHRfLCBtLmdldE9wdGlvbmFsRSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRW51bVZhbGlkaXR5QWNjZXNzb3JzLkJBWiwgbS5nZXREZWZhdWx0RSgpKTsKKworICAgIG0uc2V0T3B0aW9uYWxFKGludmFsaWQpOworICAgIG0uc2V0RGVmYXVsdEUoaW52YWxpZCk7CisgICAgLy8gU2V0IHJlcGVhdGVkRTIgZm9yIEFsdC5yZXBlYXRlZEUyQXNPcHRpb25hbAorICAgIG0ucmVwZWF0ZWRFMiA9IG5ldyBpbnRbXSB7aW52YWxpZCwgRW51bVZhbGlkaXR5QWNjZXNzb3JzLkJBUiwgYWxzb0ludmFsaWR9OworICAgIGJ5dGVbXSBzZXJpYWxpemVkID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobSk7CisgICAgLy8gU2FuaXR5IGNoZWNrIHRoYXQgd2UgZG8gaGF2ZSBhbGwgZGF0YSBpbiB0aGUgYnl0ZSBhcnJheS4KKyAgICBhc3NlcnRFcXVhbHMoMTAsIHNlcmlhbGl6ZWQubGVuZ3RoKTsKKworICAgIC8vIFRlc3QgMTogdGVzdHMgdGhhdCBpbnZhbGlkIHZhbHVlcyBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlIGRlc2VyaWFsaXplZCBtZXNzYWdlLgorICAgIEVudW1WYWxpZGl0eUFjY2Vzc29ycy5NIGRlc2VyaWFsaXplZCA9CisgICAgICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShuZXcgRW51bVZhbGlkaXR5QWNjZXNzb3JzLk0oKSwgc2VyaWFsaXplZCk7CisgICAgYXNzZXJ0RXF1YWxzKEVudW1WYWxpZGl0eUFjY2Vzc29ycy5kZWZhdWx0XywgZGVzZXJpYWxpemVkLmdldE9wdGlvbmFsRSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoRW51bVZhbGlkaXR5QWNjZXNzb3JzLkJBWiwgZGVzZXJpYWxpemVkLmdldERlZmF1bHRFKCkpOworCisgICAgLy8gVGVzdCAyOiB0ZXN0cyB0aGF0IGludmFsaWQgdmFsdWVzIGRvIG5vdCBvdmVycmlkZSBwcmV2aW91cyB2YWx1ZXMgaW4gdGhlIGZpZWxkLCBpbmNsdWRpbmcKKyAgICAvLyBwcmUtZXhpc3RpbmcgaW52YWxpZCB2YWx1ZXMuCisgICAgZGVzZXJpYWxpemVkLnNldE9wdGlvbmFsRShFbnVtVmFsaWRpdHlBY2Nlc3NvcnMuQkFSKTsKKyAgICBkZXNlcmlhbGl6ZWQuc2V0RGVmYXVsdEUoYWxzb0ludmFsaWQpOworICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShkZXNlcmlhbGl6ZWQsIHNlcmlhbGl6ZWQpOworICAgIGFzc2VydEVxdWFscyhFbnVtVmFsaWRpdHlBY2Nlc3NvcnMuQkFSLCBkZXNlcmlhbGl6ZWQuZ2V0T3B0aW9uYWxFKCkpOworICAgIGFzc2VydEVxdWFscyhhbHNvSW52YWxpZCwgZGVzZXJpYWxpemVkLmdldERlZmF1bHRFKCkpOworCisgICAgLy8gVGVzdCAzOiByZWFkaW5nIGJ5IGFsdGVybmF0aXZlIGZvcm1zCisgICAgRW51bVZhbGlkaXR5QWNjZXNzb3JzLkFsdCBhbHQgPQorICAgICAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IEVudW1WYWxpZGl0eUFjY2Vzc29ycy5BbHQoKSwgc2VyaWFsaXplZCk7CisgICAgYXNzZXJ0RXF1YWxzKEVudW1WYWxpZGl0eUFjY2Vzc29ycy5CQVIsIC8vIGxhc3QgdmFsaWQgdmFsdWUgaW4gbS5yZXBlYXRlZEUyCisgICAgICAgIGFsdC5nZXRSZXBlYXRlZEUyQXNPcHRpb25hbCgpKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyB0aGF0IGNvZGUgZ2VuZXJhdGlvbiBjb3JyZWN0bHkgd3JhcHMgYSBzaW5nbGUgbWVzc2FnZSBpbnRvIGl0cyBvdXRlcgorICAgKiBjbGFzcy4gVGhlIGNsYXNzIHtAY29kZSBTaW5nbGVNZXNzYWdlTmFub30gaXMgaW1wb3J0ZWQgZnJvbSB0aGUgb3V0ZXIKKyAgICogY2xhc3Mge0Bjb2RlIFVuaXR0ZXN0U2luZ2xlTmFub30sIHdob3NlIG5hbWUgaXMgaW1wbGljaXQuIEFueSBlcnJvciB3b3VsZAorICAgKiBjYXVzZSB0aGlzIG1ldGhvZCB0byBmYWlsIGNvbXBpbGF0aW9uLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE5hbm9TaW5nbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTaW5nbGVNZXNzYWdlTmFubyBtc2cgPSBuZXcgU2luZ2xlTWVzc2FnZU5hbm8oKTsKKyAgICBhc3NlcnROb3ROdWxsKG1zZyk7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCBjb2RlIGdlbmVyYXRpb24gY29ycmVjdGx5IHNraXBzIGdlbmVyYXRpbmcgdGhlIG91dGVyIGNsYXNzIGlmCisgICAqIHVubmVjZXNzYXJ5LCBsZXR0aW5nIGEgZmlsZS1zY29wZSBlbnRpdHkgaGF2ZSB0aGUgc2FtZSBuYW1lLiBUaGUgY2xhc3MKKyAgICoge0Bjb2RlIE11bHRpcGxlTmFtZUNsYXNoTmFub30gc2hhcmVzIHRoZSBzYW1lIG5hbWUgd2l0aCB0aGUgZmlsZSdzIG91dGVyCisgICAqIGNsYXNzIGRlZmluZWQgZXhwbGljaXRseSwgYnV0IHRoZSBmaWxlIGNvbnRhaW5zIG5vIG90aGVyIGVudGl0aWVzIGFuZCBoYXMKKyAgICogamF2YV9tdWx0aXBsZV9maWxlcyBzZXQuIEFueSBlcnJvciB3b3VsZCBjYXVzZSB0aGlzIG1ldGhvZCB0byBmYWlsCisgICAqIGNvbXBpbGF0aW9uLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE5hbm9NdWx0aXBsZU5hbWVDbGFzaCgpIHRocm93cyBFeGNlcHRpb24geworICAgIE11bHRpcGxlTmFtZUNsYXNoTmFubyBtc2cgPSBuZXcgTXVsdGlwbGVOYW1lQ2xhc2hOYW5vKCk7CisgICAgbXNnLmZpZWxkID0gMDsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyB0aGF0IGNvZGUgZ2VuZXJhdGlvbiBjb3JyZWN0bHkgaGFuZGxlcyBlbnVtcyBpbiBkaWZmZXJlbnQgc2NvcGVzIGluCisgICAqIGEgc291cmNlIGZpbGUgd2l0aCB0aGUgb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgc2V0IHRvIHRydWUuIEFueSBlcnJvcgorICAgKiB3b3VsZCBjYXVzZSB0aGlzIG1ldGhvZCB0byBmYWlsIGNvbXBpbGF0aW9uLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE5hbm9NdWx0aXBsZUVudW1TY29waW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZVNjb3BlRW51bVJlZk5hbm8gbXNnMSA9IG5ldyBGaWxlU2NvcGVFbnVtUmVmTmFubygpOworICAgIG1zZzEuZW51bUZpZWxkID0gVW5pdHRlc3RNdWx0aXBsZU5hbm8uT05FOworICAgIE1lc3NhZ2VTY29wZUVudW1SZWZOYW5vIG1zZzIgPSBuZXcgTWVzc2FnZVNjb3BlRW51bVJlZk5hbm8oKTsKKyAgICBtc2cyLmVudW1GaWVsZCA9IE1lc3NhZ2VTY29wZUVudW1SZWZOYW5vLlRXTzsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyB0aGF0IGNvZGUgZ2VuZXJhdGlvbiB3aXRoIG1peGVkIHZhbHVlcyBvZiB0aGUgamF2YV9tdWx0aXBsZV9maWxlcworICAgKiBvcHRpb25zIGJldHdlZW4gdGhlIG1haW4gc291cmNlIGZpbGUgYW5kIHRoZSBpbXBvcnRlZCBzb3VyY2UgZmlsZXMgd291bGQKKyAgICogZ2VuZXJhdGUgY29ycmVjdCByZWZlcmVuY2VzLiBBbnkgZXJyb3Igd291bGQgY2F1c2UgdGhpcyBtZXRob2QgdG8gZmFpbAorICAgKiBjb21waWxhdGlvbi4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vTXVsdGlwbGVJbXBvcnRpbmdOb25NdWx0aXBsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVuaXR0ZXN0SW1wb3J0TmFuby5JbXBvcnRNZXNzYWdlTmFubyBpbXBvcnRNc2cgPSBuZXcgVW5pdHRlc3RJbXBvcnROYW5vLkltcG9ydE1lc3NhZ2VOYW5vKCk7CisgICAgTXVsdGlwbGVJbXBvcnRpbmdOb25NdWx0aXBsZU5hbm8xIG5hbm8xID0gbmV3IE11bHRpcGxlSW1wb3J0aW5nTm9uTXVsdGlwbGVOYW5vMSgpOworICAgIG5hbm8xLmZpZWxkID0gaW1wb3J0TXNnOworICAgIE11bHRpcGxlSW1wb3J0aW5nTm9uTXVsdGlwbGVOYW5vMiBuYW5vMiA9IG5ldyBNdWx0aXBsZUltcG9ydGluZ05vbk11bHRpcGxlTmFubzIoKTsKKyAgICBuYW5vMi5uYW5vMSA9IG5hbm8xOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9EZWZhdWx0cygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgYXNzZXJ0RXF1YWxzKDQxLCBtc2cuZGVmYXVsdEludDMyKTsKKyAgICAgIGFzc2VydEVxdWFscyg0MiwgbXNnLmRlZmF1bHRJbnQ2NCk7CisgICAgICBhc3NlcnRFcXVhbHMoNDMsIG1zZy5kZWZhdWx0VWludDMyKTsKKyAgICAgIGFzc2VydEVxdWFscyg0NCwgbXNnLmRlZmF1bHRVaW50NjQpOworICAgICAgYXNzZXJ0RXF1YWxzKC00NSwgbXNnLmRlZmF1bHRTaW50MzIpOworICAgICAgYXNzZXJ0RXF1YWxzKDQ2LCBtc2cuZGVmYXVsdFNpbnQ2NCk7CisgICAgICBhc3NlcnRFcXVhbHMoNDcsIG1zZy5kZWZhdWx0Rml4ZWQzMik7CisgICAgICBhc3NlcnRFcXVhbHMoNDgsIG1zZy5kZWZhdWx0Rml4ZWQ2NCk7CisgICAgICBhc3NlcnRFcXVhbHMoNDksIG1zZy5kZWZhdWx0U2ZpeGVkMzIpOworICAgICAgYXNzZXJ0RXF1YWxzKC01MCwgbXNnLmRlZmF1bHRTZml4ZWQ2NCk7CisgICAgICBhc3NlcnRUcnVlKDUxLjVmID09IG1zZy5kZWZhdWx0RmxvYXQpOworICAgICAgYXNzZXJ0VHJ1ZSg1Mi4wZTMgPT0gbXNnLmRlZmF1bHREb3VibGUpOworICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG1zZy5kZWZhdWx0Qm9vbCk7CisgICAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbXNnLmRlZmF1bHRTdHJpbmcpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ3b3JsZCIsIG5ldyBTdHJpbmcobXNnLmRlZmF1bHRCeXRlcywgIlVURi04IikpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkw7xueWEiLCBtc2cuZGVmYXVsdFN0cmluZ05vbmFzY2lpKTsKKyAgICAgIGFzc2VydEVxdWFscygiZMO8bnlhYiIsIG5ldyBTdHJpbmcobXNnLmRlZmF1bHRCeXRlc05vbmFzY2lpLCAiVVRGLTgiKSk7CisgICAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVIsIG1zZy5kZWZhdWx0TmVzdGVkRW51bSk7CisgICAgICBhc3NlcnRFcXVhbHMoTmFub091dGVyQ2xhc3MuRk9SRUlHTl9OQU5PX0JBUiwgbXNnLmRlZmF1bHRGb3JlaWduRW51bSk7CisgICAgICBhc3NlcnRFcXVhbHMoVW5pdHRlc3RJbXBvcnROYW5vLklNUE9SVF9OQU5PX0JBUiwgbXNnLmRlZmF1bHRJbXBvcnRFbnVtKTsKKyAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgbXNnLmRlZmF1bHRGbG9hdEluZik7CisgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFksIG1zZy5kZWZhdWx0RmxvYXROZWdJbmYpOworICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0Lk5hTiwgbXNnLmRlZmF1bHRGbG9hdE5hbik7CisgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBtc2cuZGVmYXVsdERvdWJsZUluZik7CisgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBtc2cuZGVmYXVsdERvdWJsZU5lZ0luZik7CisgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5hTiwgbXNnLmRlZmF1bHREb3VibGVOYW4pOworCisgICAgICAvLyBEZWZhdWx0IHZhbHVlcyBhcmUgbm90IG91dHB1dCwgZXhjZXB0IGZvciByZXF1aXJlZCBmaWVsZHMuCisgICAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDMpOworICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgICAgIG1zZy5jbGVhcigpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vV2l0aEhhc1BhcnNlRnJvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm9IYXMgbXNnID0gbnVsbDsKKyAgICAvLyBUZXN0IGZhbHNlIG9uIGNyZWF0aW9uLCBhZnRlciBjbGVhciBhbmQgdXBvbiBlbXB0eSBwYXJzZS4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgaWYgKGkgPT0gMCkgeworICAgICAgICBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFub0hhcygpOworICAgICAgfSBlbHNlIGlmIChpID09IDEpIHsKKyAgICAgICAgbXNnLmNsZWFyKCk7CisgICAgICB9IGVsc2UgaWYgKGkgPT0gMikgeworICAgICAgICBtc2cgPSBUZXN0QWxsVHlwZXNOYW5vSGFzLnBhcnNlRnJvbShuZXcgYnl0ZVswXSk7CisgICAgICB9CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzT3B0aW9uYWxJbnQzMik7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzT3B0aW9uYWxTdHJpbmcpOworICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc09wdGlvbmFsQnl0ZXMpOworICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc09wdGlvbmFsTmVzdGVkRW51bSk7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzRGVmYXVsdEludDMyKTsKKyAgICAgIGFzc2VydEZhbHNlKG1zZy5oYXNEZWZhdWx0U3RyaW5nKTsKKyAgICAgIGFzc2VydEZhbHNlKG1zZy5oYXNEZWZhdWx0Qnl0ZXMpOworICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc0RlZmF1bHRGbG9hdE5hbik7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzRGVmYXVsdE5lc3RlZEVudW0pOworICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc0lkKTsKKyAgICAgIGFzc2VydEZhbHNlKG1zZy5oYXNSZXF1aXJlZEVudW0pOworICAgICAgbXNnLm9wdGlvbmFsSW50MzIgPSAxMjM7CisgICAgICBtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlc05hbm9IYXMuTmVzdGVkTWVzc2FnZSgpOworICAgICAgbXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5iYiA9IDI7CisgICAgICBtc2cub3B0aW9uYWxOZXN0ZWRFbnVtID0gVGVzdEFsbFR5cGVzTmFuby5CQVo7CisgICAgfQorCisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIC8vU3lzdGVtLm91dC5wcmludGYoIm1zcz0lZCByZXN1bHQubGVuZ3RoPSVkXG4iLCBtc2dTZXJpYWxpemVkU2l6ZSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShtc2dTZXJpYWxpemVkU2l6ZSA9PSAxMCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIC8vIEhhcyBmaWVsZHMgdHJ1ZSB1cG9uIHBhcnNlLgorICAgIFRlc3RBbGxUeXBlc05hbm9IYXMgbmV3TXNnID0gVGVzdEFsbFR5cGVzTmFub0hhcy5wYXJzZUZyb20ocmVzdWx0KTsKKyAgICBhc3NlcnRFcXVhbHMoMTIzLCBuZXdNc2cub3B0aW9uYWxJbnQzMik7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzT3B0aW9uYWxJbnQzMik7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuYmIpOworICAgIGFzc2VydFRydWUobmV3TXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5oYXNCYik7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm9IYXMuQkFaLCBuZXdNc2cub3B0aW9uYWxOZXN0ZWRFbnVtKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNPcHRpb25hbE5lc3RlZEVudW0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE5hbm9XaXRoSGFzU2VyaWFsaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFub0hhcyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFub0hhcygpOworICAgIG1zZy5oYXNPcHRpb25hbEludDMyID0gdHJ1ZTsKKyAgICBtc2cuaGFzT3B0aW9uYWxTdHJpbmcgPSB0cnVlOworICAgIG1zZy5oYXNPcHRpb25hbEJ5dGVzID0gdHJ1ZTsKKyAgICBtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlc05hbm9IYXMuTmVzdGVkTWVzc2FnZSgpOworICAgIG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuaGFzQmIgPSB0cnVlOworICAgIG1zZy5oYXNPcHRpb25hbE5lc3RlZEVudW0gPSB0cnVlOworICAgIG1zZy5oYXNEZWZhdWx0SW50MzIgPSB0cnVlOworICAgIG1zZy5oYXNEZWZhdWx0U3RyaW5nID0gdHJ1ZTsKKyAgICBtc2cuaGFzRGVmYXVsdEJ5dGVzID0gdHJ1ZTsKKyAgICBtc2cuaGFzRGVmYXVsdEZsb2F0TmFuID0gdHJ1ZTsKKyAgICBtc2cuaGFzRGVmYXVsdE5lc3RlZEVudW0gPSB0cnVlOworICAgIG1zZy5oYXNJZCA9IHRydWU7CisgICAgbXNnLmhhc1JlcXVpcmVkRW51bSA9IHRydWU7CisKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKworICAgIC8vIE5vdyBkZXNlcmlhbGl6ZSBhbmQgZmluZCB0aGF0IGFsbCBmaWVsZHMgYXJlIHNldCBhbmQgZXF1YWwgdG8gdGhlaXIgZGVmYXVsdHMuCisgICAgVGVzdEFsbFR5cGVzTmFub0hhcyBuZXdNc2cgPSBUZXN0QWxsVHlwZXNOYW5vSGFzLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc09wdGlvbmFsSW50MzIpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc09wdGlvbmFsU3RyaW5nKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNPcHRpb25hbEJ5dGVzKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuaGFzQmIpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc09wdGlvbmFsTmVzdGVkRW51bSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzRGVmYXVsdEludDMyKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNEZWZhdWx0U3RyaW5nKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNEZWZhdWx0Qnl0ZXMpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc0RlZmF1bHRGbG9hdE5hbik7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzRGVmYXVsdE5lc3RlZEVudW0pOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc0lkKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNSZXF1aXJlZEVudW0pOworICAgIGFzc2VydEVxdWFscygwLCBuZXdNc2cub3B0aW9uYWxJbnQzMik7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5vcHRpb25hbFN0cmluZy5sZW5ndGgoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5vcHRpb25hbEJ5dGVzLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuYmIpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vSGFzLkZPTywgbmV3TXNnLm9wdGlvbmFsTmVzdGVkRW51bSk7CisgICAgYXNzZXJ0RXF1YWxzKDQxLCBuZXdNc2cuZGVmYXVsdEludDMyKTsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbmV3TXNnLmRlZmF1bHRTdHJpbmcpOworICAgIGFzc2VydEVxdWFscygid29ybGQiLCBuZXcgU3RyaW5nKG5ld01zZy5kZWZhdWx0Qnl0ZXMsICJVVEYtOCIpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFub0hhcy5CQVIsIG5ld01zZy5kZWZhdWx0TmVzdGVkRW51bSk7CisgICAgYXNzZXJ0RXF1YWxzKEZsb2F0Lk5hTiwgbmV3TXNnLmRlZmF1bHRGbG9hdE5hbik7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5pZCk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm9IYXMuRk9PLCBuZXdNc2cucmVxdWlyZWRFbnVtKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vV2l0aEFjY2Vzc29yc0Jhc2ljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgbXNnID0gbmV3IFRlc3ROYW5vQWNjZXNzb3JzKCk7CisKKyAgICAvLyBNYWtlcyBzdXJlIHJlcXVpcmVkLCByZXBlYXRlZCwgYW5kIG1lc3NhZ2UgZmllbGRzIGFyZSBzdGlsbCBwdWJsaWMKKyAgICBtc2cuaWQgPSAzOworICAgIG1zZy5yZXBlYXRlZEJ5dGVzID0gbmV3IGJ5dGVbMl1bM107CisgICAgbXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSA9IG51bGw7CisKKyAgICAvLyBUZXN0IGFjY2Vzc29ycworICAgIGFzc2VydEVxdWFscygwLCBtc2cuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBhc3NlcnRGYWxzZShtc2cuaGFzT3B0aW9uYWxJbnQzMigpKTsKKyAgICBtc2cuc2V0T3B0aW9uYWxJbnQzMigxMzUpOworICAgIGFzc2VydEVxdWFscygxMzUsIG1zZy5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydFRydWUobXNnLmhhc09wdGlvbmFsSW50MzIoKSk7CisgICAgbXNnLmNsZWFyT3B0aW9uYWxJbnQzMigpOworICAgIGFzc2VydEZhbHNlKG1zZy5oYXNPcHRpb25hbEludDMyKCkpOworICAgIG1zZy5zZXRPcHRpb25hbEludDMyKDApOyAvLyBkZWZhdWx0IHZhbHVlCisgICAgYXNzZXJ0VHJ1ZShtc2cuaGFzT3B0aW9uYWxJbnQzMigpKTsKKworICAgIC8vIFRlc3QgTlBFCisgICAgdHJ5IHsKKyAgICAgIG1zZy5zZXRPcHRpb25hbEJ5dGVzKG51bGwpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7fQorICAgIHRyeSB7CisgICAgICBtc2cuc2V0T3B0aW9uYWxTdHJpbmcobnVsbCk7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHt9CisKKyAgICAvLyBUZXN0IGhhcyBiaXQgb24gYnl0ZXMgZmllbGQgd2l0aCBkZWZhdWx0cyBhbmQgY2xlYXIoKSByZS1jbG9uZXMgdGhlIGRlZmF1bHQgYXJyYXkKKyAgICBhc3NlcnRGYWxzZShtc2cuaGFzRGVmYXVsdEJ5dGVzKCkpOworICAgIGJ5dGVbXSBkZWZhdWx0Qnl0ZXMgPSBtc2cuZ2V0RGVmYXVsdEJ5dGVzKCk7CisgICAgbXNnLnNldERlZmF1bHRCeXRlcyhkZWZhdWx0Qnl0ZXMpOworICAgIGFzc2VydFRydWUobXNnLmhhc0RlZmF1bHRCeXRlcygpKTsKKyAgICBtc2cuY2xlYXJEZWZhdWx0Qnl0ZXMoKTsKKyAgICBhc3NlcnRGYWxzZShtc2cuaGFzRGVmYXVsdEJ5dGVzKCkpOworICAgIGRlZmF1bHRCeXRlc1swXSsrOyAvLyBtb2RpZnkgb3JpZ2luYWwgYXJyYXkKKyAgICBhc3NlcnRGYWxzZShBcnJheXMuZXF1YWxzKGRlZmF1bHRCeXRlcywgbXNnLmdldERlZmF1bHRCeXRlcygpKSk7CisKKyAgICAvLyBUZXN0IGhhcyBiaXRzIHRoYXQgcmVxdWlyZSBhZGRpdGlvbmFsIGJpdCBmaWVsZHMKKyAgICBhc3NlcnRGYWxzZShtc2cuaGFzQml0RmllbGRDaGVjaygpKTsKKyAgICBtc2cuc2V0Qml0RmllbGRDaGVjaygwKTsKKyAgICBhc3NlcnRUcnVlKG1zZy5oYXNCaXRGaWVsZENoZWNrKCkpOworICAgIGFzc2VydEZhbHNlKG1zZy5oYXNCZWZvcmVCaXRGaWVsZENoZWNrKCkpOyAvLyBjaGVja3MgYml0IGZpZWxkIGRvZXMgbm90IGxlYWsKKyAgICBhc3NlcnRGYWxzZShtc2cuaGFzQWZ0ZXJCaXRGaWVsZENoZWNrKCkpOworCisgICAgLy8gVGVzdCBjbGVhcigpIGNsZWFycyBoYXMgYml0cworICAgIG1zZy5zZXRPcHRpb25hbFN0cmluZygiaGkiKTsKKyAgICBtc2cuc2V0RGVmYXVsdFN0cmluZygidGhlcmUiKTsKKyAgICBtc2cuY2xlYXIoKTsKKyAgICBhc3NlcnRGYWxzZShtc2cuaGFzT3B0aW9uYWxTdHJpbmcoKSk7CisgICAgYXNzZXJ0RmFsc2UobXNnLmhhc0RlZmF1bHRTdHJpbmcoKSk7CisgICAgYXNzZXJ0RmFsc2UobXNnLmhhc0JpdEZpZWxkQ2hlY2soKSk7CisKKyAgICAvLyBUZXN0IHNldCgpIGFuZCBjbGVhcigpIHJldHVybnMgaXRzZWxmIChjb21waWxlcyA9IHN1Y2Nlc3MpCisgICAgbXNnLmNsZWFyKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoMykKKyAgICAgICAgLmNsZWFyRGVmYXVsdEJ5dGVzKCkKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCI0Iik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1dpdGhBY2Nlc3NvcnNQYXJzZUZyb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TmFub0FjY2Vzc29ycyBtc2cgPSBudWxsOworICAgIC8vIFRlc3QgZmFsc2Ugb24gY3JlYXRpb24sIGFmdGVyIGNsZWFyIGFuZCB1cG9uIGVtcHR5IHBhcnNlLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICBpZiAoaSA9PSAwKSB7CisgICAgICAgIG1zZyA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycygpOworICAgICAgfSBlbHNlIGlmIChpID09IDEpIHsKKyAgICAgICAgbXNnLmNsZWFyKCk7CisgICAgICB9IGVsc2UgaWYgKGkgPT0gMikgeworICAgICAgICBtc2cgPSBUZXN0TmFub0FjY2Vzc29ycy5wYXJzZUZyb20obmV3IGJ5dGVbMF0pOworICAgICAgfQorICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc09wdGlvbmFsSW50MzIoKSk7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzT3B0aW9uYWxTdHJpbmcoKSk7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzT3B0aW9uYWxCeXRlcygpKTsKKyAgICAgIGFzc2VydEZhbHNlKG1zZy5oYXNPcHRpb25hbE5lc3RlZEVudW0oKSk7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzRGVmYXVsdEludDMyKCkpOworICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc0RlZmF1bHRTdHJpbmcoKSk7CisgICAgICBhc3NlcnRGYWxzZShtc2cuaGFzRGVmYXVsdEJ5dGVzKCkpOworICAgICAgYXNzZXJ0RmFsc2UobXNnLmhhc0RlZmF1bHRGbG9hdE5hbigpKTsKKyAgICAgIGFzc2VydEZhbHNlKG1zZy5oYXNEZWZhdWx0TmVzdGVkRW51bSgpKTsKKyAgICAgIG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdE5hbm9BY2Nlc3NvcnMuTmVzdGVkTWVzc2FnZSgpOworICAgICAgbXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5zZXRCYigyKTsKKyAgICAgIG1zZy5zZXRPcHRpb25hbE5lc3RlZEVudW0oVGVzdE5hbm9BY2Nlc3NvcnMuQkFaKTsKKyAgICAgIG1zZy5zZXREZWZhdWx0SW50MzIobXNnLmdldERlZmF1bHRJbnQzMigpKTsKKyAgICB9CisKKyAgICBieXRlIFtdIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgaW50IG1zZ1NlcmlhbGl6ZWRTaXplID0gbXNnLmdldFNlcmlhbGl6ZWRTaXplKCk7CisgICAgLy9TeXN0ZW0ub3V0LnByaW50ZigibXNzPSVkIHJlc3VsdC5sZW5ndGg9JWRcbiIsIG1zZ1NlcmlhbGl6ZWRTaXplLCByZXN1bHQubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKG1zZ1NlcmlhbGl6ZWRTaXplID09IDE0KTsKKyAgICBhc3NlcnRFcXVhbHMocmVzdWx0Lmxlbmd0aCwgbXNnU2VyaWFsaXplZFNpemUpOworCisgICAgLy8gSGFzIGZpZWxkcyB0cnVlIHVwb24gcGFyc2UuCisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgbmV3TXNnID0gVGVzdE5hbm9BY2Nlc3NvcnMucGFyc2VGcm9tKHJlc3VsdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIG5ld01zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuZ2V0QmIoKSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlLmhhc0JiKCkpOworICAgIGFzc2VydEVxdWFscyhUZXN0TmFub0FjY2Vzc29ycy5CQVosIG5ld01zZy5nZXRPcHRpb25hbE5lc3RlZEVudW0oKSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworCisgICAgLy8gSGFzIGZpZWxkIHRydWUgb24gZmllbGRzIHdpdGggZXhwbGljaXQgZGVmYXVsdCB2YWx1ZXMgZnJvbSB3aXJlLgorICAgIGFzc2VydFRydWUobmV3TXNnLmhhc0RlZmF1bHRJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoNDEsIG5ld01zZy5nZXREZWZhdWx0SW50MzIoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1dpdGhBY2Nlc3NvcnNQdWJsaWNGaWVsZFR5cGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgbXNnID0gbmV3IFRlc3ROYW5vQWNjZXNzb3JzKCk7CisgICAgYXNzZXJ0TnVsbChtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLmlkKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbXNnLnJlcGVhdGVkTmVzdGVkRW51bS5sZW5ndGgpOworCisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgbmV3TXNnID0gVGVzdE5hbm9BY2Nlc3NvcnMucGFyc2VGcm9tKE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZykpOworICAgIGFzc2VydE51bGwobmV3TXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5pZCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKworICAgIFRlc3ROYW5vQWNjZXNzb3JzLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycy5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbmVzdGVkTWVzc2FnZS5zZXRCYig1KTsKKyAgICBuZXdNc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0gbmVzdGVkTWVzc2FnZTsKKyAgICBuZXdNc2cuaWQgPSAtMTsKKyAgICBuZXdNc2cucmVwZWF0ZWROZXN0ZWRFbnVtID0gbmV3IGludFtdIHsgVGVzdEFsbFR5cGVzTmFuby5GT08gfTsKKworICAgIFRlc3ROYW5vQWNjZXNzb3JzIG5ld01zZzIgPSBUZXN0TmFub0FjY2Vzc29ycy5wYXJzZUZyb20oTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobmV3TXNnKSk7CisgICAgYXNzZXJ0RXF1YWxzKG5lc3RlZE1lc3NhZ2UuZ2V0QmIoKSwgbmV3TXNnMi5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuZ2V0QmIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0xLCBuZXdNc2cyLmlkKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG5ld01zZzIucmVwZWF0ZWROZXN0ZWRFbnVtWzBdKTsKKworICAgIG5ld01zZzIub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0gbnVsbDsKKyAgICBuZXdNc2cyLmlkID0gMDsKKyAgICBuZXdNc2cyLnJlcGVhdGVkTmVzdGVkRW51bSA9IG51bGw7CisKKyAgICBUZXN0TmFub0FjY2Vzc29ycyBuZXdNc2czID0gVGVzdE5hbm9BY2Nlc3NvcnMucGFyc2VGcm9tKE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG5ld01zZzIpKTsKKyAgICBhc3NlcnROdWxsKG5ld01zZzMub3B0aW9uYWxOZXN0ZWRNZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbmV3TXNnMy5pZCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZzMucmVwZWF0ZWROZXN0ZWRFbnVtLmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub1dpdGhBY2Nlc3NvcnNTZXJpYWxpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TmFub0FjY2Vzc29ycyBtc2cgPSBuZXcgVGVzdE5hbm9BY2Nlc3NvcnMoKTsKKyAgICBtc2cuc2V0T3B0aW9uYWxJbnQzMihtc2cuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBtc2cuc2V0T3B0aW9uYWxTdHJpbmcobXNnLmdldE9wdGlvbmFsU3RyaW5nKCkpOworICAgIG1zZy5zZXRPcHRpb25hbEJ5dGVzKG1zZy5nZXRPcHRpb25hbEJ5dGVzKCkpOworICAgIFRlc3ROYW5vQWNjZXNzb3JzLk5lc3RlZE1lc3NhZ2UgbmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycy5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbmVzdGVkTWVzc2FnZS5zZXRCYihuZXN0ZWRNZXNzYWdlLmdldEJiKCkpOworICAgIG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UgPSBuZXN0ZWRNZXNzYWdlOworICAgIG1zZy5zZXRPcHRpb25hbE5lc3RlZEVudW0obXNnLmdldE9wdGlvbmFsTmVzdGVkRW51bSgpKTsKKyAgICBtc2cuc2V0RGVmYXVsdEludDMyKG1zZy5nZXREZWZhdWx0SW50MzIoKSk7CisgICAgbXNnLnNldERlZmF1bHRTdHJpbmcobXNnLmdldERlZmF1bHRTdHJpbmcoKSk7CisgICAgbXNnLnNldERlZmF1bHRCeXRlcyhtc2cuZ2V0RGVmYXVsdEJ5dGVzKCkpOworICAgIG1zZy5zZXREZWZhdWx0RmxvYXROYW4obXNnLmdldERlZmF1bHRGbG9hdE5hbigpKTsKKyAgICBtc2cuc2V0RGVmYXVsdE5lc3RlZEVudW0obXNnLmdldERlZmF1bHROZXN0ZWRFbnVtKCkpOworCisgICAgYnl0ZSBbXSByZXN1bHQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtc2cpOworICAgIGludCBtc2dTZXJpYWxpemVkU2l6ZSA9IG1zZy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBtc2dTZXJpYWxpemVkU2l6ZSk7CisKKyAgICAvLyBOb3cgZGVzZXJpYWxpemUgYW5kIGZpbmQgdGhhdCBhbGwgZmllbGRzIGFyZSBzZXQgYW5kIGVxdWFsIHRvIHRoZWlyIGRlZmF1bHRzLgorICAgIFRlc3ROYW5vQWNjZXNzb3JzIG5ld01zZyA9IFRlc3ROYW5vQWNjZXNzb3JzLnBhcnNlRnJvbShyZXN1bHQpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc09wdGlvbmFsSW50MzIoKSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzT3B0aW9uYWxTdHJpbmcoKSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzT3B0aW9uYWxCeXRlcygpKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuaGFzQmIoKSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc0RlZmF1bHRJbnQzMigpKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNEZWZhdWx0U3RyaW5nKCkpOworICAgIGFzc2VydFRydWUobmV3TXNnLmhhc0RlZmF1bHRCeXRlcygpKTsKKyAgICBhc3NlcnRUcnVlKG5ld01zZy5oYXNEZWZhdWx0RmxvYXROYW4oKSk7CisgICAgYXNzZXJ0VHJ1ZShuZXdNc2cuaGFzRGVmYXVsdE5lc3RlZEVudW0oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5nZXRPcHRpb25hbEludDMyKCkpOworICAgIGFzc2VydEVxdWFscygwLCBuZXdNc2cuZ2V0T3B0aW9uYWxTdHJpbmcoKS5sZW5ndGgoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5nZXRPcHRpb25hbEJ5dGVzKCkubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgbmV3TXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5nZXRCYigpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdE5hbm9BY2Nlc3NvcnMuRk9PLCBuZXdNc2cuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOworICAgIGFzc2VydEVxdWFscyg0MSwgbmV3TXNnLmdldERlZmF1bHRJbnQzMigpKTsKKyAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbmV3TXNnLmdldERlZmF1bHRTdHJpbmcoKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJ3b3JsZCIsIG5ldyBTdHJpbmcobmV3TXNnLmdldERlZmF1bHRCeXRlcygpLCAiVVRGLTgiKSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3ROYW5vQWNjZXNzb3JzLkJBUiwgbmV3TXNnLmdldERlZmF1bHROZXN0ZWRFbnVtKCkpOworICAgIGFzc2VydEVxdWFscyhGbG9hdC5OYU4sIG5ld01zZy5nZXREZWZhdWx0RmxvYXROYW4oKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG5ld01zZy5pZCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TmFub0phdmFFbnVtU3R5bGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFbnVtQ2xhc3NOYW5vcy5FbnVtQ2xhc3NOYW5vIG1zZyA9IG5ldyBFbnVtQ2xhc3NOYW5vcy5FbnVtQ2xhc3NOYW5vKCk7CisgICAgYXNzZXJ0RXF1YWxzKEVudW1DbGFzc05hbm9zLkZpbGVTY29wZUVudW0uT05FLCBtc2cub25lKTsKKyAgICBhc3NlcnRFcXVhbHMoRW51bUNsYXNzTmFub3MuRW51bUNsYXNzTmFuby5NZXNzYWdlU2NvcGVFbnVtLlRXTywgbXNnLnR3byk7CisKKyAgICBFbnVtQ2xhc3NOYW5vTXVsdGlwbGUgbXNnMiA9IG5ldyBFbnVtQ2xhc3NOYW5vTXVsdGlwbGUoKTsKKyAgICBhc3NlcnRFcXVhbHMoRmlsZVNjb3BlRW51bU11bHRpcGxlLlRIUkVFLCBtc2cyLnRocmVlKTsKKyAgICBhc3NlcnRFcXVhbHMoRW51bUNsYXNzTmFub011bHRpcGxlLk1lc3NhZ2VTY29wZUVudW1NdWx0aXBsZS5GT1VSLCBtc2cyLmZvdXIpOworICB9CisKKyAgLyoqCisgICAqIFRlc3RzIHRoYXQgZmllbGRzIHdpdGggYSBkZWZhdWx0IHZhbHVlIG9mIE5hTiBhcmUgbm90IHNlcmlhbGl6ZWQgd2hlbgorICAgKiBzZXQgdG8gTmFOLiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlIGFzIE5hTiAhPSBOYU4sIHNvIG5vcm1hbCBlcXVhbGl0eQorICAgKiBjaGVja3MgZG9uJ3Qgd29yay4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3ROYW5vTm90QU51bWJlckRlZmF1bHRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtc2cgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1zZy5kZWZhdWx0RG91YmxlTmFuID0gMDsKKyAgICBtc2cuZGVmYXVsdEZsb2F0TmFuID0gMDsKKyAgICBieXRlW10gcmVzdWx0ID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobXNnKTsKKyAgICBpbnQgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICBhc3NlcnRUcnVlKHJlc3VsdC5sZW5ndGggPT0gbXNnU2VyaWFsaXplZFNpemUpOworICAgIGFzc2VydFRydWUobXNnU2VyaWFsaXplZFNpemUgPiAzKTsKKworICAgIG1zZy5kZWZhdWx0RG91YmxlTmFuID0gRG91YmxlLk5hTjsKKyAgICBtc2cuZGVmYXVsdEZsb2F0TmFuID0gRmxvYXQuTmFOOworICAgIHJlc3VsdCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1zZyk7CisgICAgbXNnU2VyaWFsaXplZFNpemUgPSBtc2cuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgcmVzdWx0Lmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1zZ1NlcmlhbGl6ZWRTaXplKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0IHRoYXQgYSBidWcgaW4gc2tpcFJhd0J5dGVzKCkgaGFzIGJlZW4gZml4ZWQ6ICBpZiB0aGUgc2tpcCBza2lwcworICAgKiBleGFjdGx5IHVwIHRvIGEgbGltaXQsIHRoaXMgc2hvdWxkIG5vdCBicmVhayB0aGluZ3MuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U2tpcFJhd0J5dGVzQnVnKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIHJhd0J5dGVzID0gbmV3IGJ5dGVbXSB7IDEsIDIgfTsKKyAgICBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8gaW5wdXQgPSBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8ubmV3SW5zdGFuY2UocmF3Qnl0ZXMpOworCisgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KDEpOworICAgIGlucHV0LnNraXBSYXdCeXRlcygxKTsKKyAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGlucHV0LnJlYWRSYXdCeXRlKCkpOworICB9CisKKyAgLyoqCisgICAqIFRlc3QgdGhhdCBhIGJ1ZyBpbiBza2lwUmF3Qnl0ZXMoKSBoYXMgYmVlbiBmaXhlZDogIGlmIHRoZSBza2lwIHNraXBzCisgICAqIHBhc3QgdGhlIGVuZCBvZiBhIGJ1ZmZlciB3aXRoIGEgbGltaXQgdGhhdCBoYXMgYmVlbiBzZXQgcGFzdCB0aGUgZW5kIG9mCisgICAqIHRoYXQgYnVmZmVyLCB0aGlzIHNob3VsZCBub3QgYnJlYWsgdGhpbmdzLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNraXBSYXdCeXRlc1Bhc3RFbmRPZkJ1ZmZlcldpdGhMaW1pdCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGVbXSByYXdCeXRlcyA9IG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCA1IH07CisgICAgQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGlucHV0ID0gQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vLm5ld0luc3RhbmNlKHJhd0J5dGVzKTsKKworICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdCg0KTsKKyAgICAvLyBJbiBvcmRlciB0byBleHBvc2UgdGhlIGJ1ZyB3ZSBuZWVkIHRvIHJlYWQgYXQgbGVhc3Qgb25lIGJ5dGUgdG8gcHJpbWUgdGhlCisgICAgLy8gYnVmZmVyIGluc2lkZSB0aGUgQ29kZWRJbnB1dFN0cmVhbS4KKyAgICBhc3NlcnRFcXVhbHMoMSwgaW5wdXQucmVhZFJhd0J5dGUoKSk7CisgICAgLy8gU2tpcCB0byB0aGUgZW5kIG9mIHRoZSBsaW1pdC4KKyAgICBpbnB1dC5za2lwUmF3Qnl0ZXMoMyk7CisgICAgYXNzZXJ0VHJ1ZShpbnB1dC5pc0F0RW5kKCkpOworICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKKyAgICBhc3NlcnRFcXVhbHMoNSwgaW5wdXQucmVhZFJhd0J5dGUoKSk7CisgIH0KKworICAvLyBUZXN0IGEgc21hdHRlcmluZyBvZiB2YXJpb3VzIHByb3RvIHR5cGVzIGZvciBwcmludGluZworICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZU5hbm9QcmludGVyKCkgeworICAgIFRlc3RBbGxUeXBlc05hbm8gbXNnID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtc2cub3B0aW9uYWxJbnQzMiA9IDE0OworICAgIG1zZy5vcHRpb25hbEZsb2F0ID0gNDIuM2Y7CisgICAgbXNnLm9wdGlvbmFsU3RyaW5nID0gIlN0cmluZyBcIndpdGgnIGJvdGggcXVvdGVzIjsKKyAgICBtc2cub3B0aW9uYWxCeXRlcyA9IG5ldyBieXRlW10geyciJywgJ1wwJywgMSwgOH07CisgICAgbXNnLm9wdGlvbmFsR3JvdXAgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5PcHRpb25hbEdyb3VwKCk7CisgICAgbXNnLm9wdGlvbmFsR3JvdXAuYSA9IDE1OworICAgIG1zZy5yZXBlYXRlZEludDY0ID0gbmV3IGxvbmdbMl07CisgICAgbXNnLnJlcGVhdGVkSW50NjRbMF0gPSAxTDsKKyAgICBtc2cucmVwZWF0ZWRJbnQ2NFsxXSA9IC0xTDsKKyAgICBtc2cucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlWzJdW107CisgICAgbXNnLnJlcGVhdGVkQnl0ZXNbMV0gPSBuZXcgYnl0ZVtdIHsnaCcsICdlJywgJ2wnLCAnbCcsICdvJ307CisgICAgbXNnLnJlcGVhdGVkR3JvdXAgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5SZXBlYXRlZEdyb3VwWzJdOworICAgIG1zZy5yZXBlYXRlZEdyb3VwWzBdID0gbmV3IFRlc3RBbGxUeXBlc05hbm8uUmVwZWF0ZWRHcm91cCgpOworICAgIG1zZy5yZXBlYXRlZEdyb3VwWzBdLmEgPSAtMjc7CisgICAgbXNnLnJlcGVhdGVkR3JvdXBbMV0gPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5SZXBlYXRlZEdyb3VwKCk7CisgICAgbXNnLnJlcGVhdGVkR3JvdXBbMV0uYSA9IC03MjsKKyAgICBtc2cub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSgpOworICAgIG1zZy5vcHRpb25hbE5lc3RlZE1lc3NhZ2UuYmIgPSA3OworICAgIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlWzJdOworICAgIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMF0gPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVswXS5iYiA9IDc3OworICAgIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMV0gPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVsxXS5iYiA9IDg4OworICAgIG1zZy5vcHRpb25hbE5lc3RlZEVudW0gPSBUZXN0QWxsVHlwZXNOYW5vLkJBWjsKKyAgICBtc2cucmVwZWF0ZWROZXN0ZWRFbnVtID0gbmV3IGludFsyXTsKKyAgICBtc2cucmVwZWF0ZWROZXN0ZWRFbnVtWzBdID0gVGVzdEFsbFR5cGVzTmFuby5CQVI7CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkRW51bVsxXSA9IFRlc3RBbGxUeXBlc05hbm8uRk9POworICAgIG1zZy5yZXBlYXRlZFN0cmluZ1BpZWNlID0gbmV3IFN0cmluZ1tdIHtudWxsLCAid29ybGQifTsKKyAgICBtc2cuc2V0T25lb2ZTdHJpbmcoImhlbGxvIik7CisKKyAgICBTdHJpbmcgcHJvdG9QcmludCA9IG1zZy50b1N0cmluZygpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygib3B0aW9uYWxfaW50MzI6IDE0IikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygib3B0aW9uYWxfZmxvYXQ6IDQyLjMiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9kb3VibGU6IDAuMCIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoIm9wdGlvbmFsX3N0cmluZzogXCJTdHJpbmcgXFx1MDAyMndpdGhcXHUwMDI3IGJvdGggcXVvdGVzXCIiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9ieXRlczogXCJcXFwiXFwwMDBcXDAwMVxcMDEwXCIiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9ncm91cCA8XG4gIGE6IDE1XG4+IikpOworCisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJyZXBlYXRlZF9pbnQ2NDogMVxucmVwZWF0ZWRfaW50NjQ6IC0xIikpOworICAgIGFzc2VydEZhbHNlKHByb3RvUHJpbnQuY29udGFpbnMoInJlcGVhdGVkX2J5dGVzOiBcIlwiIikpOyAvLyBudWxsIHNob3VsZCBiZSBkcm9wcGVkCisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJyZXBlYXRlZF9ieXRlczogXCJoZWxsb1wiIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygicmVwZWF0ZWRfZ3JvdXAgPFxuICBhOiAtMjdcbj5cbiIKKyAgICAgICAgICAgICsgInJlcGVhdGVkX2dyb3VwIDxcbiAgYTogLTcyXG4+IikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPFxuICBiYjogN1xuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIDxcbiAgYmI6IDc3XG4+XG4iCisgICAgICAgICAgICArICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8XG4gIGJiOiA4OFxuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoIm9wdGlvbmFsX25lc3RlZF9lbnVtOiAzIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygicmVwZWF0ZWRfbmVzdGVkX2VudW06IDJcbnJlcGVhdGVkX25lc3RlZF9lbnVtOiAxIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygiZGVmYXVsdF9pbnQzMjogNDEiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJkZWZhdWx0X3N0cmluZzogXCJoZWxsb1wiIikpOworICAgIGFzc2VydEZhbHNlKHByb3RvUHJpbnQuY29udGFpbnMoInJlcGVhdGVkX3N0cmluZ19waWVjZTogXCJcIiIpKTsgIC8vIG51bGwgc2hvdWxkIGJlIGRyb3BwZWQKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoInJlcGVhdGVkX3N0cmluZ19waWVjZTogXCJ3b3JsZFwiIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygib25lb2Zfc3RyaW5nOiBcImhlbGxvXCIiKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZU5hbm9QcmludGVyQWNjZXNzb3JzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgbXNnID0gbmV3IFRlc3ROYW5vQWNjZXNzb3JzKCk7CisgICAgbXNnLnNldE9wdGlvbmFsSW50MzIoMTMpOworICAgIG1zZy5zZXRPcHRpb25hbFN0cmluZygiZm9vIik7CisgICAgbXNnLnNldE9wdGlvbmFsQnl0ZXMobmV3IGJ5dGVbXSB7JyInLCAnXDAnLCAxLCA4fSk7CisgICAgbXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycy5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbXNnLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5zZXRCYig3KTsKKyAgICBtc2cuc2V0T3B0aW9uYWxOZXN0ZWRFbnVtKFRlc3ROYW5vQWNjZXNzb3JzLkJBWik7CisgICAgbXNnLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyAxLCAtMSB9OworICAgIG1zZy5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbXSB7ICJIZWxsbyIsICJ3b3JsZCIgfTsKKyAgICBtc2cucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlWzJdW107CisgICAgbXNnLnJlcGVhdGVkQnl0ZXNbMV0gPSBuZXcgYnl0ZVtdIHsnaCcsICdlJywgJ2wnLCAnbCcsICdvJ307CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycy5OZXN0ZWRNZXNzYWdlWzJdOworICAgIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMF0gPSBuZXcgVGVzdE5hbm9BY2Nlc3NvcnMuTmVzdGVkTWVzc2FnZSgpOworICAgIG1zZy5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMF0uc2V0QmIoNSk7CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVsxXSA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycy5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbXNnLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVsxXS5zZXRCYig2KTsKKyAgICBtc2cucmVwZWF0ZWROZXN0ZWRFbnVtID0gbmV3IGludFtdIHsgVGVzdE5hbm9BY2Nlc3NvcnMuRk9PLCBUZXN0TmFub0FjY2Vzc29ycy5CQVIgfTsKKyAgICBtc2cuaWQgPSAzMzsKKworICAgIFN0cmluZyBwcm90b1ByaW50ID0gbXNnLnRvU3RyaW5nKCk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9pbnQzMjogMTMiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9zdHJpbmc6IFwiZm9vXCIiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9ieXRlczogXCJcXFwiXFwwMDBcXDAwMVxcMDEwXCIiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA8XG4gIGJiOiA3XG4+IikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygib3B0aW9uYWxfbmVzdGVkX2VudW06IDMiKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJyZXBlYXRlZF9pbnQzMjogMVxucmVwZWF0ZWRfaW50MzI6IC0xIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygicmVwZWF0ZWRfc3RyaW5nOiBcIkhlbGxvXCJcbnJlcGVhdGVkX3N0cmluZzogXCJ3b3JsZFwiIikpOworICAgIGFzc2VydEZhbHNlKHByb3RvUHJpbnQuY29udGFpbnMoInJlcGVhdGVkX2J5dGVzOiBcIlwiIikpOyAvLyBudWxsIHNob3VsZCBiZSBkcm9wcGVkCisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKCJyZXBlYXRlZF9ieXRlczogXCJoZWxsb1wiIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPFxuICBiYjogNVxuPlxuIgorICAgICAgICAgICAgKyAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPFxuICBiYjogNlxuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoInJlcGVhdGVkX25lc3RlZF9lbnVtOiAxXG5yZXBlYXRlZF9uZXN0ZWRfZW51bTogMiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoImlkOiAzMyIpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlTmFub1ByaW50ZXJGb3JNYXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdE1hcCBtc2cgPSBuZXcgVGVzdE1hcCgpOworICAgIE1lc3NhZ2VWYWx1ZSBtc2dWYWx1ZXNbXSA9IG5ldyBNZXNzYWdlVmFsdWVbXSB7CisgICAgICBuZXcgTWVzc2FnZVZhbHVlKCksIG5ldyBNZXNzYWdlVmFsdWUoKQorICAgIH07CisgICAgbXNnVmFsdWVzWzBdLnZhbHVlID0gMTsKKyAgICBtc2dWYWx1ZXNbMV0udmFsdWUgPSAyOworICAgIG1zZy5pbnQzMlRvQnl0ZXNGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIGJ5dGVbXT4oKTsKKyAgICBtc2cuaW50MzJUb0J5dGVzRmllbGQucHV0KDEsIG5ldyBieXRlW10geyciJywgJ1wwJ30pOworICAgIG1zZy5pbnQzMlRvQnl0ZXNGaWVsZC5wdXQoMiwgbmV3IGJ5dGVbXSB7MSwgOH0pOworICAgIG1zZy5zdHJpbmdUb0ludDMyRmllbGQgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+KCk7CisgICAgbXNnLnN0cmluZ1RvSW50MzJGaWVsZC5wdXQoImhlbGxvIiwgMSk7CisgICAgbXNnLnN0cmluZ1RvSW50MzJGaWVsZC5wdXQoIndvcmxkIiwgMik7CisgICAgbXNnLmludDMyVG9NZXNzYWdlRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBNYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+KCk7CisgICAgbXNnLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDAsIG1zZ1ZhbHVlc1swXSk7CisgICAgbXNnLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDEsIG1zZ1ZhbHVlc1sxXSk7CisgICAgbXNnLmludDMyVG9FbnVtRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgIG1zZy5pbnQzMlRvRW51bUZpZWxkLnB1dCgxLCAyKTsKKyAgICBtc2cuaW50MzJUb0VudW1GaWVsZC5wdXQoMiwgMyk7CisgICAgU3RyaW5nIHByb3RvUHJpbnQgPSBtc2cudG9TdHJpbmcoKTsKKworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygKKyAgICAgICAgImludDMyX3RvX2J5dGVzX2ZpZWxkIDxcbiAga2V5OiAxXG4gIHZhbHVlOiBcIlxcXCJcXDAwMFwiXG4+IikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygKKyAgICAgICAgImludDMyX3RvX2J5dGVzX2ZpZWxkIDxcbiAga2V5OiAyXG4gIHZhbHVlOiBcIlxcMDAxXFwwMTBcIlxuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoCisgICAgICAgICJzdHJpbmdfdG9faW50MzJfZmllbGQgPFxuICBrZXk6IFwiaGVsbG9cIlxuICB2YWx1ZTogMVxuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoCisgICAgICAgICJzdHJpbmdfdG9faW50MzJfZmllbGQgPFxuICBrZXk6IFwid29ybGRcIlxuICB2YWx1ZTogMlxuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoCisgICAgICAgICJpbnQzMl90b19tZXNzYWdlX2ZpZWxkIDxcbiAga2V5OiAwXG4gIHZhbHVlIDxcbiAgICB2YWx1ZTogMVxuIikpOworICAgIGFzc2VydFRydWUocHJvdG9QcmludC5jb250YWlucygKKyAgICAgICAgImludDMyX3RvX21lc3NhZ2VfZmllbGQgPFxuICBrZXk6IDFcbiAgdmFsdWUgPFxuICAgIHZhbHVlOiAyXG4iKSk7CisgICAgYXNzZXJ0VHJ1ZShwcm90b1ByaW50LmNvbnRhaW5zKAorICAgICAgICAiaW50MzJfdG9fZW51bV9maWVsZCA8XG4gIGtleTogMVxuICB2YWx1ZTogMlxuPiIpKTsKKyAgICBhc3NlcnRUcnVlKHByb3RvUHJpbnQuY29udGFpbnMoCisgICAgICAgICJpbnQzMl90b19lbnVtX2ZpZWxkIDxcbiAga2V5OiAyXG4gIHZhbHVlOiAzXG4+IikpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeHRlbnNpb25zLkV4dGVuZGFibGVNZXNzYWdlIG1lc3NhZ2UgPSBuZXcgRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZSgpOworICAgIG1lc3NhZ2UuZmllbGQgPSA1OworICAgIGludFtdIGludDMycyA9IHsxLCAyfTsKKyAgICBpbnRbXSB1aW50MzJzID0gezMsIDR9OworICAgIGludFtdIHNpbnQzMnMgPSB7LTUsIC02fTsKKyAgICBsb25nW10gaW50NjRzID0gezcsIDh9OworICAgIGxvbmdbXSB1aW50NjRzID0gezksIDEwfTsKKyAgICBsb25nW10gc2ludDY0cyA9IHstMTEsIC0xMn07CisgICAgaW50W10gZml4ZWQzMnMgPSB7MTMsIDE0fTsKKyAgICBpbnRbXSBzZml4ZWQzMnMgPSB7LTE1LCAtMTZ9OworICAgIGxvbmdbXSBmaXhlZDY0cyA9IHsxNywgMTh9OworICAgIGxvbmdbXSBzZml4ZWQ2NHMgPSB7LTE5LCAtMjB9OworICAgIGJvb2xlYW5bXSBib29scyA9IHt0cnVlLCBmYWxzZX07CisgICAgZmxvYXRbXSBmbG9hdHMgPSB7Mi4xZiwgMi4yZn07CisgICAgZG91YmxlW10gZG91YmxlcyA9IHsyLjMsIDIuNH07CisgICAgaW50W10gZW51bXMgPSB7RXh0ZW5zaW9ucy5TRUNPTkRfVkFMVUUsIEV4dGVuc2lvbnMuRklSU1RfVkFMVUV9OworICAgIFN0cmluZ1tdIHN0cmluZ3MgPSB7InZpamZlbnR3aW50aWciLCAidHdlbnR5LXNpeCJ9OworICAgIGJ5dGVbXVtdIGJ5dGVzcyA9IHt7MiwgN30sIHsyLCA4fX07CisgICAgQW5vdGhlck1lc3NhZ2UgYW5vdGhlcjEgPSBuZXcgQW5vdGhlck1lc3NhZ2UoKTsKKyAgICBhbm90aGVyMS5zdHJpbmcgPSAiZXIgc2hpIGppdSI7CisgICAgYW5vdGhlcjEudmFsdWUgPSBmYWxzZTsKKyAgICBBbm90aGVyTWVzc2FnZSBhbm90aGVyMiA9IG5ldyBBbm90aGVyTWVzc2FnZSgpOworICAgIGFub3RoZXIyLnN0cmluZyA9ICJ0cmVudGUiOworICAgIGFub3RoZXIyLnZhbHVlID0gdHJ1ZTsKKyAgICBBbm90aGVyTWVzc2FnZVtdIG1lc3NhZ2VzID0ge2Fub3RoZXIxLCBhbm90aGVyMn07CisgICAgUmVwZWF0ZWRFeHRlbnNpb25zLlJlcGVhdGVkR3JvdXAgZ3JvdXAxID0gbmV3IFJlcGVhdGVkRXh0ZW5zaW9ucy5SZXBlYXRlZEdyb3VwKCk7CisgICAgZ3JvdXAxLmEgPSAzMTsKKyAgICBSZXBlYXRlZEV4dGVuc2lvbnMuUmVwZWF0ZWRHcm91cCBncm91cDIgPSBuZXcgUmVwZWF0ZWRFeHRlbnNpb25zLlJlcGVhdGVkR3JvdXAoKTsKKyAgICBncm91cDIuYSA9IDMyOworICAgIFJlcGVhdGVkRXh0ZW5zaW9ucy5SZXBlYXRlZEdyb3VwW10gZ3JvdXBzID0ge2dyb3VwMSwgZ3JvdXAyfTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRJbnQzMikpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEludDMyLCBpbnQzMnMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkSW50MzIpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50MzIpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50MzIsIHVpbnQzMnMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkVWludDMyKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkU2ludDMyLCBzaW50MzJzKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRJbnQ2NCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEludDY0LCBpbnQ2NHMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkSW50NjQpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50NjQpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50NjQsIHVpbnQ2NHMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkVWludDY0KSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkU2ludDY0KSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkU2ludDY0LCBzaW50NjRzKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNpbnQ2NCkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkMzIpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGaXhlZDMyLCBmaXhlZDMycyk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGaXhlZDMyKSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkU2ZpeGVkMzIpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQzMiwgc2ZpeGVkMzJzKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNmaXhlZDMyKSk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRml4ZWQ2NCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkNjQsIGZpeGVkNjRzKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkNjQpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQ2NCkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNmaXhlZDY0LCBzZml4ZWQ2NHMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkU2ZpeGVkNjQpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRCb29sKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkQm9vbCwgYm9vbHMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkQm9vbCkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZsb2F0KSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRmxvYXQsIGZsb2F0cyk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGbG9hdCkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZERvdWJsZSkpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZERvdWJsZSwgZG91Ymxlcyk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWREb3VibGUpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRFbnVtKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRW51bSwgZW51bXMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRW51bSkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFN0cmluZykpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFN0cmluZywgc3RyaW5ncyk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTdHJpbmcpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRCeXRlcykpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEJ5dGVzLCBieXRlc3MpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkQnl0ZXMpKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRNZXNzYWdlKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkTWVzc2FnZSwgbWVzc2FnZXMpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkTWVzc2FnZSkpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEdyb3VwKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkR3JvdXAsIGdyb3Vwcyk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRHcm91cCkpOworCisgICAgYnl0ZVtdIGRhdGEgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKTsKKyAgICBtZXNzYWdlID0gRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZS5wYXJzZUZyb20oZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKDUsIG1lc3NhZ2UuZmllbGQpOworCisgICAgLy8gVGVzdCByZWFkaW5nIGJhY2sgdXNpbmcgU2luZ3VsYXJFeHRlbnNpb25zOiB0aGUgcmV0cmlldmVkIHZhbHVlIHNob3VsZCBlcXVhbCB0aGUgbGFzdAorICAgIC8vIGluIGVhY2ggYXJyYXkuCisgICAgYXNzZXJ0RXF1YWxzKGludDMyc1sxXSwgKGludCkgbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVJbnQzMikpOworICAgIGFzc2VydEVxdWFscyh1aW50MzJzWzFdLCAoaW50KSBtZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZVVpbnQzMikpOworICAgIGFzc2VydEVxdWFscyhzaW50MzJzWzFdLCAoaW50KSBtZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZVNpbnQzMikpOworICAgIGFzc2VydEVxdWFscyhpbnQ2NHNbMV0sIChsb25nKSBtZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZUludDY0KSk7CisgICAgYXNzZXJ0RXF1YWxzKHVpbnQ2NHNbMV0sIChsb25nKSBtZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZVVpbnQ2NCkpOworICAgIGFzc2VydEVxdWFscyhzaW50NjRzWzFdLCAobG9uZykgbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVTaW50NjQpKTsKKyAgICBhc3NlcnRFcXVhbHMoZml4ZWQzMnNbMV0sIChpbnQpIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lRml4ZWQzMikpOworICAgIGFzc2VydEVxdWFscyhzZml4ZWQzMnNbMV0sIChpbnQpIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lU2ZpeGVkMzIpKTsKKyAgICBhc3NlcnRFcXVhbHMoZml4ZWQ2NHNbMV0sIChsb25nKSBtZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZUZpeGVkNjQpKTsKKyAgICBhc3NlcnRFcXVhbHMoc2ZpeGVkNjRzWzFdLCAobG9uZykgbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVTZml4ZWQ2NCkpOworICAgIGFzc2VydEVxdWFscyhib29sc1sxXSwgKGJvb2xlYW4pIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lQm9vbCkpOworICAgIGFzc2VydEVxdWFscyhmbG9hdHNbMV0sIChmbG9hdCkgbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVGbG9hdCkpOworICAgIGFzc2VydEVxdWFscyhkb3VibGVzWzFdLCAoZG91YmxlKSBtZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZURvdWJsZSkpOworICAgIGFzc2VydEVxdWFscyhlbnVtc1sxXSwgKGludCkgbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVFbnVtKSk7CisgICAgYXNzZXJ0RXF1YWxzKHN0cmluZ3NbMV0sIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lU3RyaW5nKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGJ5dGVzc1sxXSwgbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVCeXRlcykpKTsKKyAgICBBbm90aGVyTWVzc2FnZSBkZXNlcmlhbGl6ZWRNZXNzYWdlID0gbWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlKTsKKyAgICBhc3NlcnRFcXVhbHMoYW5vdGhlcjIuc3RyaW5nLCBkZXNlcmlhbGl6ZWRNZXNzYWdlLnN0cmluZyk7CisgICAgYXNzZXJ0RXF1YWxzKGFub3RoZXIyLnZhbHVlLCBkZXNlcmlhbGl6ZWRNZXNzYWdlLnZhbHVlKTsKKyAgICBhc3NlcnRFcXVhbHMoZ3JvdXAyLmEsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lR3JvdXApLmEpOworCisgICAgLy8gVGVzdCByZWFkaW5nIGJhY2sgdXNpbmcgUmVwZWF0ZWRFeHRlbnNpb25zOiB0aGUgYXJyYXlzIHNob3VsZCBiZSBlcXVhbC4KKyAgICBtZXNzYWdlID0gRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZS5wYXJzZUZyb20oZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKDUsIG1lc3NhZ2UuZmllbGQpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhpbnQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEludDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyh1aW50MzJzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50MzIpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHNpbnQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNpbnQzMikpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoaW50NjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRJbnQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHModWludDY0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkVWludDY0KSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhzaW50NjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTaW50NjQpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZpeGVkMzJzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGaXhlZDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhzZml4ZWQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNmaXhlZDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhmaXhlZDY0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRml4ZWQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoc2ZpeGVkNjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoYm9vbHMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEJvb2wpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZsb2F0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRmxvYXQpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGRvdWJsZXMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZERvdWJsZSkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZW51bXMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEVudW0pKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHN0cmluZ3MsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFN0cmluZykpKTsKKyAgICBieXRlW11bXSBkZXNlcmlhbGl6ZWRSZXBlYXRlZEJ5dGVzID0gbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkQnl0ZXMpOworICAgIGFzc2VydEVxdWFscygyLCBkZXNlcmlhbGl6ZWRSZXBlYXRlZEJ5dGVzLmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGJ5dGVzc1swXSwgZGVzZXJpYWxpemVkUmVwZWF0ZWRCeXRlc1swXSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhieXRlc3NbMV0sIGRlc2VyaWFsaXplZFJlcGVhdGVkQnl0ZXNbMV0pKTsKKyAgICBBbm90aGVyTWVzc2FnZVtdIGRlc2VyaWFsaXplZFJlcGVhdGVkTWVzc2FnZSA9CisgICAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZE1lc3NhZ2UpOworICAgIGFzc2VydEVxdWFscygyLCBkZXNlcmlhbGl6ZWRSZXBlYXRlZE1lc3NhZ2UubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoYW5vdGhlcjEuc3RyaW5nLCBkZXNlcmlhbGl6ZWRSZXBlYXRlZE1lc3NhZ2VbMF0uc3RyaW5nKTsKKyAgICBhc3NlcnRFcXVhbHMoYW5vdGhlcjEudmFsdWUsIGRlc2VyaWFsaXplZFJlcGVhdGVkTWVzc2FnZVswXS52YWx1ZSk7CisgICAgYXNzZXJ0RXF1YWxzKGFub3RoZXIyLnN0cmluZywgZGVzZXJpYWxpemVkUmVwZWF0ZWRNZXNzYWdlWzFdLnN0cmluZyk7CisgICAgYXNzZXJ0RXF1YWxzKGFub3RoZXIyLnZhbHVlLCBkZXNlcmlhbGl6ZWRSZXBlYXRlZE1lc3NhZ2VbMV0udmFsdWUpOworICAgIFJlcGVhdGVkRXh0ZW5zaW9ucy5SZXBlYXRlZEdyb3VwW10gZGVzZXJpYWxpemVkUmVwZWF0ZWRHcm91cCA9CisgICAgICAgIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEdyb3VwKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgZGVzZXJpYWxpemVkUmVwZWF0ZWRHcm91cC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhncm91cDEuYSwgZGVzZXJpYWxpemVkUmVwZWF0ZWRHcm91cFswXS5hKTsKKyAgICBhc3NlcnRFcXVhbHMoZ3JvdXAyLmEsIGRlc2VyaWFsaXplZFJlcGVhdGVkR3JvdXBbMV0uYSk7CisKKyAgICBtZXNzYWdlID0gRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZS5wYXJzZUZyb20oZGF0YSk7CisgICAgYXNzZXJ0RXF1YWxzKDUsIG1lc3NhZ2UuZmllbGQpOworICAgIC8vIFRlc3QgaGFzRXh0ZW5zaW9uIHVzaW5nIFBhY2tlZEV4dGVuc2lvbnMuCisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZEludDMyKSk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFVpbnQzMikpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRTaW50MzIpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkSW50NjQpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkVWludDY0KSk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFNpbnQ2NCkpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRGaXhlZDMyKSk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFNmaXhlZDMyKSk7CisgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmhhc0V4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZEZpeGVkNjQpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkU2ZpeGVkNjQpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkQm9vbCkpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRGbG9hdCkpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWREb3VibGUpKTsKKyAgICBhc3NlcnRUcnVlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkRW51bSkpOworCisgICAgLy8gVGVzdCByZWFkaW5nIGJhY2sgdXNpbmcgUGFja2VkRXh0ZW5zaW9uczogdGhlIGFycmF5cyBzaG91bGQgYmUgZXF1YWwsIGV2ZW4gdGhlIGZpZWxkcworICAgIC8vIGFyZSBub24tcGFja2VkLgorICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhpbnQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkSW50MzIpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHVpbnQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkVWludDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhzaW50MzJzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFNpbnQzMikpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoaW50NjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZEludDY0KSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyh1aW50NjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFVpbnQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoc2ludDY0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRTaW50NjQpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZpeGVkMzJzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZEZpeGVkMzIpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHNmaXhlZDMycywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRTZml4ZWQzMikpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZml4ZWQ2NHMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkRml4ZWQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoc2ZpeGVkNjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFNmaXhlZDY0KSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhib29scywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRCb29sKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhmbG9hdHMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkRmxvYXQpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGRvdWJsZXMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkRG91YmxlKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhlbnVtcywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRFbnVtKSkpOworCisgICAgLy8gTm93IHNldCB0aGUgcGFja2FibGUgZXh0ZW5zaW9uIHZhbHVlcyB1c2luZyBQYWNrZWRFeHRlbnNpb25zIHNvIHRoZXkncmUgc2VyaWFsaXplZCBwYWNrZWQuCisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRJbnQzMiwgaW50MzJzKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFVpbnQzMiwgdWludDMycyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRTaW50MzIsIHNpbnQzMnMpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkSW50NjQsIGludDY0cyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRVaW50NjQsIHVpbnQ2NHMpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkU2ludDY0LCBzaW50NjRzKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZEZpeGVkMzIsIGZpeGVkMzJzKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZFNmaXhlZDMyLCBzZml4ZWQzMnMpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkRml4ZWQ2NCwgZml4ZWQ2NHMpOworICAgIG1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFBhY2tlZEV4dGVuc2lvbnMucGFja2VkU2ZpeGVkNjQsIHNmaXhlZDY0cyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRCb29sLCBib29scyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRGbG9hdCwgZmxvYXRzKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihQYWNrZWRFeHRlbnNpb25zLnBhY2tlZERvdWJsZSwgZG91Ymxlcyk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oUGFja2VkRXh0ZW5zaW9ucy5wYWNrZWRFbnVtLCBlbnVtcyk7CisKKyAgICAvLyBBbmQgcmVhZCBiYWNrIHVzaW5nIG5vbi1wYWNrZWQgUmVwZWF0ZWRFeHRlbnNpb25zLgorICAgIGJ5dGVbXSBkYXRhMiA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1lc3NhZ2UpOworICAgIG1lc3NhZ2UgPSBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IEV4dGVuc2lvbnMuRXh0ZW5kYWJsZU1lc3NhZ2UoKSwgZGF0YTIpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhpbnQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEludDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyh1aW50MzJzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50MzIpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHNpbnQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNpbnQzMikpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoaW50NjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRJbnQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHModWludDY0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkVWludDY0KSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhzaW50NjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTaW50NjQpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZpeGVkMzJzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGaXhlZDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhzZml4ZWQzMnMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNmaXhlZDMyKSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhmaXhlZDY0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRml4ZWQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoc2ZpeGVkNjRzLCBtZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQ2NCkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoYm9vbHMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEJvb2wpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZsb2F0cywgbWVzc2FnZS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkRmxvYXQpKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGRvdWJsZXMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZERvdWJsZSkpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZW51bXMsIG1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEVudW0pKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TnVsbEV4dGVuc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDaGVjayB0aGF0IGNsZWFyaW5nIHRoZSBleHRlbnNpb24gb24gYW4gZW1wdHkgbWVzc2FnZSBpcyBhIG5vLW9wLgorICAgIEV4dGVuc2lvbnMuRXh0ZW5kYWJsZU1lc3NhZ2UgbWVzc2FnZSA9IG5ldyBFeHRlbnNpb25zLkV4dGVuZGFibGVNZXNzYWdlKCk7CisgICAgYXNzZXJ0RmFsc2UobWVzc2FnZS5oYXNFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlKSk7CisgICAgbWVzc2FnZS5zZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlLCBudWxsKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZU1lc3NhZ2UpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobWVzc2FnZSkubGVuZ3RoKTsKKworICAgIC8vIENoZWNrIHRoYXQgdGhlIG1lc3NhZ2UgaXMgZW1wdHkgYWZ0ZXIgc2V0dGluZyBhbmQgY2xlYXJpbmcgYW4gZXh0ZW5zaW9uLgorICAgIEFub3RoZXJNZXNzYWdlIGFub3RoZXIgPSBuZXcgQW5vdGhlck1lc3NhZ2UoKTsKKyAgICBhc3NlcnRGYWxzZShtZXNzYWdlLmhhc0V4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZU1lc3NhZ2UpKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZU1lc3NhZ2UsIGFub3RoZXIpOworICAgIGFzc2VydFRydWUobWVzc2FnZS5oYXNFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlKSk7CisgICAgYXNzZXJ0VHJ1ZShNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKS5sZW5ndGggPiAwKTsKKyAgICBtZXNzYWdlLnNldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZU1lc3NhZ2UsIG51bGwpOworICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UuaGFzRXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lTWVzc2FnZSkpOworICAgIGFzc2VydEVxdWFscygwLCBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKS5sZW5ndGgpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEV4dGVuc2lvbnNNdXRhdGlvbigpIHsKKyAgICBFeHRlbnNpb25zLkV4dGVuZGFibGVNZXNzYWdlIGV4dGVuZGFibGVNZXNzYWdlID0gbmV3IEV4dGVuc2lvbnMuRXh0ZW5kYWJsZU1lc3NhZ2UoKTsKKyAgICBleHRlbmRhYmxlTWVzc2FnZS5zZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlLAorICAgICAgICBuZXcgRXh0ZW5zaW9ucy5Bbm90aGVyTWVzc2FnZSgpKTsKKworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZU1lc3NhZ2UpLnN0cmluZyA9ICJub3QgZW1wdHkiOworCisgICAgYXNzZXJ0RXF1YWxzKCJub3QgZW1wdHkiLAorICAgICAgICBleHRlbmRhYmxlTWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlKS5zdHJpbmcpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEV4dGVuc2lvbnNNdXRhdGlvbl9FcXVhbHMoKSB0aHJvd3MgSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiB7CisgICAgRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZSBleHRlbmRhYmxlTWVzc2FnZSA9IG5ldyBFeHRlbnNpb25zLkV4dGVuZGFibGVNZXNzYWdlKCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZmllbGQgPSA1OworICAgIGludCBpbnQzMiA9IDQyOworICAgIGludFtdIHVpbnQzMnMgPSB7MywgNH07CisgICAgaW50W10gc2ludDMycyA9IHstNSwgLTZ9OworICAgIGxvbmdbXSBpbnQ2NHMgPSB7NywgOH07CisgICAgbG9uZ1tdIHVpbnQ2NHMgPSB7OSwgMTB9OworICAgIGxvbmdbXSBzaW50NjRzID0gey0xMSwgLTEyfTsKKyAgICBpbnRbXSBmaXhlZDMycyA9IHsxMywgMTR9OworICAgIGludFtdIHNmaXhlZDMycyA9IHstMTUsIC0xNn07CisgICAgbG9uZ1tdIGZpeGVkNjRzID0gezE3LCAxOH07CisgICAgbG9uZ1tdIHNmaXhlZDY0cyA9IHstMTksIC0yMH07CisgICAgYm9vbGVhbltdIGJvb2xzID0ge3RydWUsIGZhbHNlfTsKKyAgICBmbG9hdFtdIGZsb2F0cyA9IHsyLjFmLCAyLjJmfTsKKyAgICBkb3VibGVbXSBkb3VibGVzID0gezIuMywgMi40fTsKKyAgICBpbnRbXSBlbnVtcyA9IHtFeHRlbnNpb25zLlNFQ09ORF9WQUxVRSwgRXh0ZW5zaW9ucy5GSVJTVF9WQUxVRX07CisgICAgU3RyaW5nW10gc3RyaW5ncyA9IHsidmlqZmVudHdpbnRpZyIsICJ0d2VudHktc2l4In07CisgICAgYnl0ZVtdW10gYnl0ZXNzID0ge3syLCA3fSwgezIsIDh9fTsKKyAgICBBbm90aGVyTWVzc2FnZSBhbm90aGVyMSA9IG5ldyBBbm90aGVyTWVzc2FnZSgpOworICAgIGFub3RoZXIxLnN0cmluZyA9ICJlciBzaGkgaml1IjsKKyAgICBhbm90aGVyMS52YWx1ZSA9IGZhbHNlOworICAgIEFub3RoZXJNZXNzYWdlIGFub3RoZXIyID0gbmV3IEFub3RoZXJNZXNzYWdlKCk7CisgICAgYW5vdGhlcjIuc3RyaW5nID0gInRyZW50ZSI7CisgICAgYW5vdGhlcjIudmFsdWUgPSB0cnVlOworICAgIEFub3RoZXJNZXNzYWdlW10gbWVzc2FnZXMgPSB7YW5vdGhlcjEsIGFub3RoZXIyfTsKKyAgICBSZXBlYXRlZEV4dGVuc2lvbnMuUmVwZWF0ZWRHcm91cCBncm91cDEgPSBuZXcgUmVwZWF0ZWRFeHRlbnNpb25zLlJlcGVhdGVkR3JvdXAoKTsKKyAgICBncm91cDEuYSA9IDMxOworICAgIFJlcGVhdGVkRXh0ZW5zaW9ucy5SZXBlYXRlZEdyb3VwIGdyb3VwMiA9IG5ldyBSZXBlYXRlZEV4dGVuc2lvbnMuUmVwZWF0ZWRHcm91cCgpOworICAgIGdyb3VwMi5hID0gMzI7CisgICAgUmVwZWF0ZWRFeHRlbnNpb25zLlJlcGVhdGVkR3JvdXBbXSBncm91cHMgPSB7Z3JvdXAxLCBncm91cDJ9OworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZUludDMyLCBpbnQzMik7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFVpbnQzMiwgdWludDMycyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNpbnQzMiwgc2ludDMycyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEludDY0LCBpbnQ2NHMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50NjQsIHVpbnQ2NHMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTaW50NjQsIHNpbnQ2NHMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGaXhlZDMyLCBmaXhlZDMycyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNmaXhlZDMyLCBzZml4ZWQzMnMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGaXhlZDY0LCBmaXhlZDY0cyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNmaXhlZDY0LCBzZml4ZWQ2NHMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRCb29sLCBib29scyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZsb2F0LCBmbG9hdHMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWREb3VibGUsIGRvdWJsZXMpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRFbnVtLCBlbnVtcyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFN0cmluZywgc3RyaW5ncyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEJ5dGVzLCBieXRlc3MpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLnNldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRNZXNzYWdlLCBtZXNzYWdlcyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEdyb3VwLCBncm91cHMpOworCisgICAgYnl0ZVtdIGRhdGEgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShleHRlbmRhYmxlTWVzc2FnZSk7CisKKyAgICBleHRlbmRhYmxlTWVzc2FnZSA9IEV4dGVuc2lvbnMuRXh0ZW5kYWJsZU1lc3NhZ2UucGFyc2VGcm9tKGRhdGEpOworICAgIEV4dGVuc2lvbnMuRXh0ZW5kYWJsZU1lc3NhZ2UgbWVzc2FnZUNvcHkgPSBFeHRlbnNpb25zLkV4dGVuZGFibGVNZXNzYWdlLnBhcnNlRnJvbShkYXRhKTsKKworICAgIC8vIFdpdGhvdXQgZGVzZXJpYWxpc2luZy4KKyAgICBhc3NlcnRFcXVhbHMoZXh0ZW5kYWJsZU1lc3NhZ2UsIG1lc3NhZ2VDb3B5KTsKKyAgICBhc3NlcnRFcXVhbHMoZXh0ZW5kYWJsZU1lc3NhZ2UuaGFzaENvZGUoKSwgbWVzc2FnZUNvcHkuaGFzaENvZGUoKSk7CisKKyAgICAvLyBPbmx5IG9uZSBkZXNlcmlhbGl6ZWQuCisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lSW50MzIpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50MzIpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTaW50MzIpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRJbnQ2NCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFVpbnQ2NCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNpbnQ2NCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkMzIpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQzMik7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkNjQpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQ2NCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEJvb2wpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGbG9hdCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZERvdWJsZSk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEVudW0pOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTdHJpbmcpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRCeXRlcyk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2UuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZE1lc3NhZ2UpOworICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRHcm91cCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4dGVuZGFibGVNZXNzYWdlLCBtZXNzYWdlQ29weSk7CisgICAgYXNzZXJ0RXF1YWxzKGV4dGVuZGFibGVNZXNzYWdlLmhhc2hDb2RlKCksIG1lc3NhZ2VDb3B5Lmhhc2hDb2RlKCkpOworCisgICAgLy8gQm90aCBkZXNlcmlhbGl6ZWQuCisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lSW50MzIpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRVaW50MzIpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTaW50MzIpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRJbnQ2NCk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFVpbnQ2NCk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZFNpbnQ2NCk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkMzIpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQzMik7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEZpeGVkNjQpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTZml4ZWQ2NCk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEJvb2wpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRGbG9hdCk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZERvdWJsZSk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZEVudW0pOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRTdHJpbmcpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRCeXRlcyk7CisgICAgbWVzc2FnZUNvcHkuZ2V0RXh0ZW5zaW9uKFJlcGVhdGVkRXh0ZW5zaW9ucy5yZXBlYXRlZE1lc3NhZ2UpOworICAgIG1lc3NhZ2VDb3B5LmdldEV4dGVuc2lvbihSZXBlYXRlZEV4dGVuc2lvbnMucmVwZWF0ZWRHcm91cCk7CisgICAgYXNzZXJ0RXF1YWxzKGV4dGVuZGFibGVNZXNzYWdlLCBtZXNzYWdlQ29weSk7CisgICAgYXNzZXJ0RXF1YWxzKGV4dGVuZGFibGVNZXNzYWdlLmhhc2hDb2RlKCksIG1lc3NhZ2VDb3B5Lmhhc2hDb2RlKCkpOworCisgICAgLy8gQ2hhbmdlIG9uZSwgbWFrZSBzdXJlIHRoZXkgYXJlIHN0aWxsIGRpZmZlcmVudC4KKyAgICBtZXNzYWdlQ29weS5nZXRFeHRlbnNpb24oUmVwZWF0ZWRFeHRlbnNpb25zLnJlcGVhdGVkTWVzc2FnZSlbMF0uc3RyaW5nID0gIm5vdCBlbXB0eSI7CisgICAgYXNzZXJ0RmFsc2UoZXh0ZW5kYWJsZU1lc3NhZ2UuZXF1YWxzKG1lc3NhZ2VDb3B5KSk7CisKKyAgICAvLyBFdmVuIGlmIHRoZSBleHRlbnNpb24gaGFzbid0IGJlZW4gZGVzZXJpYWxpemVkLgorICAgIGV4dGVuZGFibGVNZXNzYWdlID0gRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZS5wYXJzZUZyb20oZGF0YSk7CisgICAgYXNzZXJ0RmFsc2UoZXh0ZW5kYWJsZU1lc3NhZ2UuZXF1YWxzKG1lc3NhZ2VDb3B5KSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZW5zaW9uc0NhY2hpbmcoKSB7CisgICAgRXh0ZW5zaW9ucy5FeHRlbmRhYmxlTWVzc2FnZSBleHRlbmRhYmxlTWVzc2FnZSA9IG5ldyBFeHRlbnNpb25zLkV4dGVuZGFibGVNZXNzYWdlKCk7CisgICAgZXh0ZW5kYWJsZU1lc3NhZ2Uuc2V0RXh0ZW5zaW9uKFNpbmd1bGFyRXh0ZW5zaW9ucy5zb21lTWVzc2FnZSwKKyAgICAgICAgbmV3IEV4dGVuc2lvbnMuQW5vdGhlck1lc3NhZ2UoKSk7CisgICAgYXNzZXJ0U2FtZSgiQ29uc2VjdXRpdmUgY2FsbHMgdG8gZ2V0RXh0ZW5zaW9ucyBzaG91bGQgcmV0dXJuIHRoZSBzYW1lIG9iamVjdCIsCisgICAgICAgIGV4dGVuZGFibGVNZXNzYWdlLmdldEV4dGVuc2lvbihTaW5ndWxhckV4dGVuc2lvbnMuc29tZU1lc3NhZ2UpLAorICAgICAgICBleHRlbmRhYmxlTWVzc2FnZS5nZXRFeHRlbnNpb24oU2luZ3VsYXJFeHRlbnNpb25zLnNvbWVNZXNzYWdlKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0VW5rbm93bkZpZWxkcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENoZWNrIHRoYXQgd2Ugcm91bmR0cmlwIChzZXJpYWxpemUgYW5kIGRlc2VyaWFsaXplKSB1bnJlY29nbml6ZWQgZmllbGRzLgorICAgIEFub3RoZXJNZXNzYWdlIG1lc3NhZ2UgPSBuZXcgQW5vdGhlck1lc3NhZ2UoKTsKKyAgICBtZXNzYWdlLnN0cmluZyA9ICJIZWxsbyBXb3JsZCI7CisgICAgbWVzc2FnZS52YWx1ZSA9IGZhbHNlOworCisgICAgYnl0ZVtdIGJ5dGVzID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobWVzc2FnZSk7CisgICAgaW50IGV4dHJhRmllbGRTaXplID0gQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5jb21wdXRlU3RyaW5nU2l6ZSgKKyAgICAgICAgMTAwMSwgIlRoaXMgaXMgYW4gdW5rbm93biBmaWVsZCIpOworICAgIGJ5dGVbXSBuZXdCeXRlcyA9IG5ldyBieXRlW2J5dGVzLmxlbmd0aCArIGV4dHJhRmllbGRTaXplXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGJ5dGVzLCAwLCBuZXdCeXRlcywgMCwgYnl0ZXMubGVuZ3RoKTsKKyAgICBDb2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vLm5ld0luc3RhbmNlKG5ld0J5dGVzLCBieXRlcy5sZW5ndGgsIGV4dHJhRmllbGRTaXplKQorICAgICAgICAud3JpdGVTdHJpbmcoMTAwMSwgIlRoaXMgaXMgYW4gdW5rbm93biBmaWVsZCIpOworCisgICAgLy8gRGVzZXJpYWxpemUgd2l0aCBhbiB1bmtub3duIGZpZWxkLgorICAgIEFub3RoZXJNZXNzYWdlIGRlc2VyaWFsaXplZCA9IEFub3RoZXJNZXNzYWdlLnBhcnNlRnJvbShuZXdCeXRlcyk7CisgICAgYnl0ZVtdIHNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShkZXNlcmlhbGl6ZWQpOworCisgICAgYXNzZXJ0RXF1YWxzKG5ld0J5dGVzLmxlbmd0aCwgc2VyaWFsaXplZC5sZW5ndGgpOworCisgICAgLy8gQ2xlYXIsIGFuZCBtYWtlIHN1cmUgaXQgY2xlYXJzIGV2ZXJ5dGhpbmcuCisgICAgZGVzZXJpYWxpemVkLmNsZWFyKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KGRlc2VyaWFsaXplZCkubGVuZ3RoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUZyb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTaW1wbGVNZXNzYWdlTmFubyBtZXNzYWdlID0gbmV3IFNpbXBsZU1lc3NhZ2VOYW5vKCk7CisgICAgbWVzc2FnZS5kID0gMTIzOworICAgIGJ5dGVbXSBieXRlcyA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1lc3NhZ2UpOworCisgICAgU2ltcGxlTWVzc2FnZU5hbm8gbmV3TWVzc2FnZSA9IE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShuZXcgU2ltcGxlTWVzc2FnZU5hbm8oKSwgYnl0ZXMpOworICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLmQsIG5ld01lc3NhZ2UuZCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SmF2YUtleXdvcmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1zZyA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbXNnLnN5bmNocm9uaXplZF8gPSAxMjM7CisgICAgYXNzZXJ0RXF1YWxzKDEyMywgbXNnLnN5bmNocm9uaXplZF8pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlZmVyZW5jZVR5cGVzRm9yUHJpbWl0aXZlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vIG1lc3NhZ2UgPSBuZXcgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8oKTsKKworICAgIC8vIEJhc2UgY2hlY2sgLSB3aGVuIG5vdGhpbmcgaXMgc2V0LCB3ZSBzZXJpYWxpemUgbm90aGluZy4KKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCBmYWxzZSk7CisKKyAgICBtZXNzYWdlLmRlZmF1bHRCb29sID0gdHJ1ZTsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCB0cnVlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEJvb2wgPSBmYWxzZTsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCB0cnVlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEJvb2wgPSBudWxsOworICAgIGFzc2VydEhhc1dpcmVEYXRhKG1lc3NhZ2UsIGZhbHNlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEludDMyID0gNTsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCB0cnVlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEludDMyID0gbnVsbDsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCBmYWxzZSk7CisKKyAgICBtZXNzYWdlLmRlZmF1bHRJbnQ2NCA9IDEyMzQ1Nkw7CisgICAgYXNzZXJ0SGFzV2lyZURhdGEobWVzc2FnZSwgdHJ1ZSk7CisKKyAgICBtZXNzYWdlLmRlZmF1bHRJbnQ2NCA9IG51bGw7CisgICAgYXNzZXJ0SGFzV2lyZURhdGEobWVzc2FnZSwgZmFsc2UpOworCisgICAgbWVzc2FnZS5kZWZhdWx0RmxvYXQgPSAxZjsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCB0cnVlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEZsb2F0ID0gbnVsbDsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCBmYWxzZSk7CisKKyAgICBtZXNzYWdlLmRlZmF1bHREb3VibGUgPSAyLjE7CisgICAgYXNzZXJ0SGFzV2lyZURhdGEobWVzc2FnZSwgdHJ1ZSk7CisKKyAgICBtZXNzYWdlLmRlZmF1bHREb3VibGUgPSBudWxsOworICAgIGFzc2VydEhhc1dpcmVEYXRhKG1lc3NhZ2UsIGZhbHNlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdFN0cmluZyA9ICJoZWxsbyI7CisgICAgYXNzZXJ0SGFzV2lyZURhdGEobWVzc2FnZSwgdHJ1ZSk7CisKKyAgICBtZXNzYWdlLmRlZmF1bHRTdHJpbmcgPSBudWxsOworICAgIGFzc2VydEhhc1dpcmVEYXRhKG1lc3NhZ2UsIGZhbHNlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEJ5dGVzID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMgfTsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCB0cnVlKTsKKworICAgIG1lc3NhZ2UuZGVmYXVsdEJ5dGVzID0gbnVsbDsKKyAgICBhc3NlcnRIYXNXaXJlRGF0YShtZXNzYWdlLCBmYWxzZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGVFcXVhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDb21wbGV0ZSBlcXVhbGl0eToKKyAgICBUZXN0QWxsVHlwZXNOYW5vIGEgPSBjcmVhdGVNZXNzYWdlRm9ySGFzaENvZGVFcXVhbHNUZXN0KCk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBhRXF1aXZhbGVudCA9IGNyZWF0ZU1lc3NhZ2VGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKworICAgIGFzc2VydFRydWUoTWVzc2FnZU5hbm8ubWVzc2FnZU5hbm9FcXVhbHMoYSwgYUVxdWl2YWxlbnQpKTsKKyAgICBhc3NlcnRGYWxzZShNZXNzYWdlTmFuby5tZXNzYWdlTmFub0VxdWFscyhhLCBuZXcgVGVzdEFsbFR5cGVzTmFubygpKSk7CisKKyAgICAvLyBOdWxsIGFuZCBlbXB0eSBhcnJheSBmb3IgcmVwZWF0ZWQgZmllbGRzIGVxdWFsaXR5OgorICAgIFRlc3RBbGxUeXBlc05hbm8gYiA9IGNyZWF0ZU1lc3NhZ2VGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKyAgICBiLnJlcGVhdGVkQm9vbCA9IG51bGw7CisgICAgYi5yZXBlYXRlZEZsb2F0ID0gbmV3IGZsb2F0WzBdOworICAgIFRlc3RBbGxUeXBlc05hbm8gYkVxdWl2YWxlbnQgPSBjcmVhdGVNZXNzYWdlRm9ySGFzaENvZGVFcXVhbHNUZXN0KCk7CisgICAgYkVxdWl2YWxlbnQucmVwZWF0ZWRCb29sID0gbmV3IGJvb2xlYW5bMF07CisgICAgYkVxdWl2YWxlbnQucmVwZWF0ZWRGbG9hdCA9IG51bGw7CisKKyAgICAvLyBSZWYtZWxlbWVudC10eXBlIHJlcGVhdGVkIGZpZWxkcyB1c2Ugbm9uLW51bGwgc3Vic2VxdWVuY2UgZXF1YWxpdHk6CisgICAgVGVzdEFsbFR5cGVzTmFubyBjID0gY3JlYXRlTWVzc2FnZUZvckhhc2hDb2RlRXF1YWxzVGVzdCgpOworICAgIGMucmVwZWF0ZWRTdHJpbmcgPSBudWxsOworICAgIGMucmVwZWF0ZWRTdHJpbmdQaWVjZSA9IG5ldyBTdHJpbmdbXSB7bnVsbCwgIm9uZSIsIG51bGwsICJ0d28ifTsKKyAgICBjLnJlcGVhdGVkQnl0ZXMgPSBuZXcgYnl0ZVtdW10ge3szLCA0fSwgbnVsbH07CisgICAgVGVzdEFsbFR5cGVzTmFubyBjRXF1aXZhbGVudCA9IGNyZWF0ZU1lc3NhZ2VGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKyAgICBjRXF1aXZhbGVudC5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbM107CisgICAgY0VxdWl2YWxlbnQucmVwZWF0ZWRTdHJpbmdQaWVjZSA9IG5ldyBTdHJpbmdbXSB7Im9uZSIsICJ0d28iLCBudWxsfTsKKyAgICBjRXF1aXZhbGVudC5yZXBlYXRlZEJ5dGVzID0gbmV3IGJ5dGVbXVtdIHt7MywgNH19OworCisgICAgLy8gQ29tcGxldGUgZXF1YWxpdHkgZm9yIG1lc3NhZ2VzIHdpdGggaGFzIGZpZWxkczoKKyAgICBUZXN0QWxsVHlwZXNOYW5vSGFzIGQgPSBjcmVhdGVNZXNzYWdlV2l0aEhhc0Zvckhhc2hDb2RlRXF1YWxzVGVzdCgpOworICAgIFRlc3RBbGxUeXBlc05hbm9IYXMgZEVxdWl2YWxlbnQgPSBjcmVhdGVNZXNzYWdlV2l0aEhhc0Zvckhhc2hDb2RlRXF1YWxzVGVzdCgpOworCisgICAgLy8gSWYgaGFzLWZpZWxkcyBleGlzdCwgZmllbGRzIHdpdGggdGhlIHNhbWUgZGVmYXVsdCB2YWx1ZXMgYnV0CisgICAgLy8gZGlmZmVyZW50IGhhcy1maWVsZCB2YWx1ZXMgYXJlIGRpZmZlcmVudC4KKyAgICBUZXN0QWxsVHlwZXNOYW5vSGFzIGUgPSBjcmVhdGVNZXNzYWdlV2l0aEhhc0Zvckhhc2hDb2RlRXF1YWxzVGVzdCgpOworICAgIGUub3B0aW9uYWxJbnQzMisrOyAvLyBtYWtlIGRpZmZlcmVudCBmcm9tIGQKKyAgICBlLmhhc0RlZmF1bHRTdHJpbmcgPSBmYWxzZTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vSGFzIGVEaWZmZXJlbnQgPSBjcmVhdGVNZXNzYWdlV2l0aEhhc0Zvckhhc2hDb2RlRXF1YWxzVGVzdCgpOworICAgIGVEaWZmZXJlbnQub3B0aW9uYWxJbnQzMiA9IGUub3B0aW9uYWxJbnQzMjsKKyAgICBlRGlmZmVyZW50Lmhhc0RlZmF1bHRTdHJpbmcgPSB0cnVlOworCisgICAgLy8gQ29tcGxldGUgZXF1YWxpdHkgZm9yIG1lc3NhZ2VzIHdpdGggYWNjZXNzb3JzOgorICAgIFRlc3ROYW5vQWNjZXNzb3JzIGYgPSBjcmVhdGVNZXNzYWdlV2l0aEFjY2Vzc29yc0Zvckhhc2hDb2RlRXF1YWxzVGVzdCgpOworICAgIFRlc3ROYW5vQWNjZXNzb3JzIGZFcXVpdmFsZW50ID0gY3JlYXRlTWVzc2FnZVdpdGhBY2Nlc3NvcnNGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKworICAgIC8vIElmIHVzaW5nIGFjY2Vzc29ycywgZXhwbGljaXRseSBzZXR0aW5nIGEgZmllbGQgdG8gaXRzIGRlZmF1bHQgdmFsdWUKKyAgICAvLyBzaG91bGQgbWFrZSB0aGUgbWVzc2FnZSBkaWZmZXJlbnQuCisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgZyA9IGNyZWF0ZU1lc3NhZ2VXaXRoQWNjZXNzb3JzRm9ySGFzaENvZGVFcXVhbHNUZXN0KCk7CisgICAgZy5zZXRPcHRpb25hbEludDMyKGcuZ2V0T3B0aW9uYWxJbnQzMigpICsgMSk7IC8vIG1ha2UgZGlmZmVyZW50IGZyb20gZgorICAgIGcuY2xlYXJEZWZhdWx0U3RyaW5nKCk7CisgICAgVGVzdE5hbm9BY2Nlc3NvcnMgZ0RpZmZlcmVudCA9IGNyZWF0ZU1lc3NhZ2VXaXRoQWNjZXNzb3JzRm9ySGFzaENvZGVFcXVhbHNUZXN0KCk7CisgICAgZ0RpZmZlcmVudC5zZXRPcHRpb25hbEludDMyKGcuZ2V0T3B0aW9uYWxJbnQzMigpKTsKKyAgICBnRGlmZmVyZW50LnNldERlZmF1bHRTdHJpbmcoZy5nZXREZWZhdWx0U3RyaW5nKCkpOworCisgICAgLy8gQ29tcGxldGUgZXF1YWxpdHkgZm9yIHJlZmVyZW5jZSB0eXBlZCBtZXNzYWdlczoKKyAgICBOYW5vUmVmZXJlbmNlVHlwZXMuVGVzdEFsbFR5cGVzTmFubyBoID0gY3JlYXRlUmVmVHlwZWRNZXNzYWdlRm9ySGFzaENvZGVFcXVhbHNUZXN0KCk7CisgICAgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8gaEVxdWl2YWxlbnQgPSBjcmVhdGVSZWZUeXBlZE1lc3NhZ2VGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKworICAgIC8vIEluZXF1YWxpdHkgb2YgbnVsbCBhbmQgZGVmYXVsdCB2YWx1ZSBmb3IgcmVmZXJlbmNlIHR5cGVkIG1lc3NhZ2VzOgorICAgIE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vIGkgPSBjcmVhdGVSZWZUeXBlZE1lc3NhZ2VGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKyAgICBpLm9wdGlvbmFsSW50MzIgPSAxOyAvLyBtYWtlIGRpZmZlcmVudCBmcm9tIGgKKyAgICBpLm9wdGlvbmFsRmxvYXQgPSBudWxsOworICAgIE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vIGlEaWZmZXJlbnQgPSBjcmVhdGVSZWZUeXBlZE1lc3NhZ2VGb3JIYXNoQ29kZUVxdWFsc1Rlc3QoKTsKKyAgICBpRGlmZmVyZW50Lm9wdGlvbmFsSW50MzIgPSBpLm9wdGlvbmFsSW50MzI7CisgICAgaURpZmZlcmVudC5vcHRpb25hbEZsb2F0ID0gMC4wZjsKKworICAgIEhhc2hNYXA8TWVzc2FnZU5hbm8sIFN0cmluZz4gaGFzaE1hcCA9IG5ldyBIYXNoTWFwPE1lc3NhZ2VOYW5vLCBTdHJpbmc+KCk7CisgICAgaGFzaE1hcC5wdXQoYSwgImEiKTsKKyAgICBoYXNoTWFwLnB1dChiLCAiYiIpOworICAgIGhhc2hNYXAucHV0KGMsICJjIik7CisgICAgaGFzaE1hcC5wdXQoZCwgImQiKTsKKyAgICBoYXNoTWFwLnB1dChlLCAiZSIpOworICAgIGhhc2hNYXAucHV0KGYsICJmIik7CisgICAgaGFzaE1hcC5wdXQoZywgImciKTsKKyAgICBoYXNoTWFwLnB1dChoLCAiaCIpOworICAgIGhhc2hNYXAucHV0KGksICJpIik7CisKKyAgICBhc3NlcnRFcXVhbHMoOSwgaGFzaE1hcC5zaXplKCkpOyAvLyBhLWkgc2hvdWxkIGJlIGRpZmZlcmVudCBmcm9tIGVhY2ggb3RoZXIuCisKKyAgICBhc3NlcnRFcXVhbHMoImEiLCBoYXNoTWFwLmdldChhKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJhIiwgaGFzaE1hcC5nZXQoYUVxdWl2YWxlbnQpKTsKKworICAgIGFzc2VydEVxdWFscygiYiIsIGhhc2hNYXAuZ2V0KGIpKTsKKyAgICBhc3NlcnRFcXVhbHMoImIiLCBoYXNoTWFwLmdldChiRXF1aXZhbGVudCkpOworCisgICAgYXNzZXJ0RXF1YWxzKCJjIiwgaGFzaE1hcC5nZXQoYykpOworICAgIGFzc2VydEVxdWFscygiYyIsIGhhc2hNYXAuZ2V0KGNFcXVpdmFsZW50KSk7CisKKyAgICBhc3NlcnRFcXVhbHMoImQiLCBoYXNoTWFwLmdldChkKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJkIiwgaGFzaE1hcC5nZXQoZEVxdWl2YWxlbnQpKTsKKworICAgIGFzc2VydEVxdWFscygiZSIsIGhhc2hNYXAuZ2V0KGUpKTsKKyAgICBhc3NlcnROdWxsKGhhc2hNYXAuZ2V0KGVEaWZmZXJlbnQpKTsKKworICAgIGFzc2VydEVxdWFscygiZiIsIGhhc2hNYXAuZ2V0KGYpKTsKKyAgICBhc3NlcnRFcXVhbHMoImYiLCBoYXNoTWFwLmdldChmRXF1aXZhbGVudCkpOworCisgICAgYXNzZXJ0RXF1YWxzKCJnIiwgaGFzaE1hcC5nZXQoZykpOworICAgIGFzc2VydE51bGwoaGFzaE1hcC5nZXQoZ0RpZmZlcmVudCkpOworCisgICAgYXNzZXJ0RXF1YWxzKCJoIiwgaGFzaE1hcC5nZXQoaCkpOworICAgIGFzc2VydEVxdWFscygiaCIsIGhhc2hNYXAuZ2V0KGhFcXVpdmFsZW50KSk7CisKKyAgICBhc3NlcnRFcXVhbHMoImkiLCBoYXNoTWFwLmdldChpKSk7CisgICAgYXNzZXJ0TnVsbChoYXNoTWFwLmdldChpRGlmZmVyZW50KSk7CisgIH0KKworICBwcml2YXRlIFRlc3RBbGxUeXBlc05hbm8gY3JlYXRlTWVzc2FnZUZvckhhc2hDb2RlRXF1YWxzVGVzdCgpIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1lc3NhZ2Uub3B0aW9uYWxJbnQzMiA9IDU7CisgICAgbWVzc2FnZS5vcHRpb25hbEludDY0ID0gNzc3OworICAgIG1lc3NhZ2Uub3B0aW9uYWxGbG9hdCA9IDEuMGY7CisgICAgbWVzc2FnZS5vcHRpb25hbERvdWJsZSA9IDIuMDsKKyAgICBtZXNzYWdlLm9wdGlvbmFsQm9vbCA9IHRydWU7CisgICAgbWVzc2FnZS5vcHRpb25hbFN0cmluZyA9ICJIZWxsbyI7CisgICAgbWVzc2FnZS5vcHRpb25hbEJ5dGVzID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMgfTsKKyAgICBtZXNzYWdlLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBtZXNzYWdlLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5iYiA9IDI3OworICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRFbnVtID0gVGVzdEFsbFR5cGVzTmFuby5CQVI7CisgICAgbWVzc2FnZS5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHsgNSwgNiwgNywgOCB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRJbnQ2NCA9IG5ldyBsb25nW10geyAyN0wsIDI4TCwgMjlMIH07CisgICAgbWVzc2FnZS5yZXBlYXRlZEZsb2F0ID0gbmV3IGZsb2F0W10geyA1LjBmLCA2LjBmIH07CisgICAgbWVzc2FnZS5yZXBlYXRlZERvdWJsZSA9IG5ldyBkb3VibGVbXSB7IDk5LjEsIDIyLjUgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkQm9vbCA9IG5ldyBib29sZWFuW10geyB0cnVlLCBmYWxzZSwgdHJ1ZSB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRTdHJpbmcgPSBuZXcgU3RyaW5nW10geyAiT25lIiwgIlR3byIgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkQnl0ZXMgPSBuZXcgYnl0ZVtdW10geyB7IDIsIDcgfSwgeyAyLCA3IH0gfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkTmVzdGVkTWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2VbXSB7CisgICAgICBtZXNzYWdlLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSwKKyAgICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRNZXNzYWdlCisgICAgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7CisgICAgICBUZXN0QWxsVHlwZXNOYW5vLkJBUiwKKyAgICAgIFRlc3RBbGxUeXBlc05hbm8uQkFaCisgICAgfTsKKyAgICBtZXNzYWdlLnNldE9uZW9mVWludDMyKDMpOworICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgcHJpdmF0ZSBUZXN0QWxsVHlwZXNOYW5vSGFzIGNyZWF0ZU1lc3NhZ2VXaXRoSGFzRm9ySGFzaENvZGVFcXVhbHNUZXN0KCkgeworICAgIFRlc3RBbGxUeXBlc05hbm9IYXMgbWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vSGFzKCk7CisgICAgbWVzc2FnZS5vcHRpb25hbEludDMyID0gNTsKKyAgICBtZXNzYWdlLm9wdGlvbmFsU3RyaW5nID0gIkhlbGxvIjsKKyAgICBtZXNzYWdlLm9wdGlvbmFsQnl0ZXMgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMyB9OworICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlc05hbm9IYXMuTmVzdGVkTWVzc2FnZSgpOworICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRNZXNzYWdlLmJiID0gMjc7CisgICAgbWVzc2FnZS5vcHRpb25hbE5lc3RlZEVudW0gPSBUZXN0QWxsVHlwZXNOYW5vLkJBUjsKKyAgICBtZXNzYWdlLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyA1LCA2LCA3LCA4IH07CisgICAgbWVzc2FnZS5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbXSB7ICJPbmUiLCAiVHdvIiB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlW11bXSB7IHsgMiwgNyB9LCB7IDIsIDcgfSB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlc05hbm9IYXMuTmVzdGVkTWVzc2FnZVtdIHsKKyAgICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRNZXNzYWdlLAorICAgICAgbWVzc2FnZS5vcHRpb25hbE5lc3RlZE1lc3NhZ2UKKyAgICB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRFbnVtID0gbmV3IGludFtdIHsKKyAgICAgIFRlc3RBbGxUeXBlc05hbm8uQkFSLAorICAgICAgVGVzdEFsbFR5cGVzTmFuby5CQVoKKyAgICB9OworICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgcHJpdmF0ZSBUZXN0TmFub0FjY2Vzc29ycyBjcmVhdGVNZXNzYWdlV2l0aEFjY2Vzc29yc0Zvckhhc2hDb2RlRXF1YWxzVGVzdCgpIHsKKyAgICBUZXN0TmFub0FjY2Vzc29ycyBtZXNzYWdlID0gbmV3IFRlc3ROYW5vQWNjZXNzb3JzKCkKKyAgICAgICAgLnNldE9wdGlvbmFsSW50MzIoNSkKKyAgICAgICAgLnNldE9wdGlvbmFsU3RyaW5nKCJIZWxsbyIpCisgICAgICAgIC5zZXRPcHRpb25hbEJ5dGVzKG5ldyBieXRlW10gezEsIDIsIDN9KQorICAgICAgICAuc2V0T3B0aW9uYWxOZXN0ZWRFbnVtKFRlc3ROYW5vQWNjZXNzb3JzLkJBUik7CisgICAgbWVzc2FnZS5vcHRpb25hbE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdE5hbm9BY2Nlc3NvcnMuTmVzdGVkTWVzc2FnZSgpLnNldEJiKDI3KTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyA1LCA2LCA3LCA4IH07CisgICAgbWVzc2FnZS5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbXSB7ICJPbmUiLCAiVHdvIiB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlW11bXSB7IHsgMiwgNyB9LCB7IDIsIDcgfSB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3ROYW5vQWNjZXNzb3JzLk5lc3RlZE1lc3NhZ2VbXSB7CisgICAgICBtZXNzYWdlLm9wdGlvbmFsTmVzdGVkTWVzc2FnZSwKKyAgICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRNZXNzYWdlCisgICAgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7CisgICAgICBUZXN0QWxsVHlwZXNOYW5vLkJBUiwKKyAgICAgIFRlc3RBbGxUeXBlc05hbm8uQkFaCisgICAgfTsKKyAgICByZXR1cm4gbWVzc2FnZTsKKyAgfQorCisgIHByaXZhdGUgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8gY3JlYXRlUmVmVHlwZWRNZXNzYWdlRm9ySGFzaENvZGVFcXVhbHNUZXN0KCkgeworICAgIE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vIG1lc3NhZ2UgPSBuZXcgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtZXNzYWdlLm9wdGlvbmFsSW50MzIgPSA1OworICAgIG1lc3NhZ2Uub3B0aW9uYWxJbnQ2NCA9IDc3N0w7CisgICAgbWVzc2FnZS5vcHRpb25hbEZsb2F0ID0gMS4wZjsKKyAgICBtZXNzYWdlLm9wdGlvbmFsRG91YmxlID0gMi4wOworICAgIG1lc3NhZ2Uub3B0aW9uYWxCb29sID0gdHJ1ZTsKKyAgICBtZXNzYWdlLm9wdGlvbmFsU3RyaW5nID0gIkhlbGxvIjsKKyAgICBtZXNzYWdlLm9wdGlvbmFsQnl0ZXMgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMyB9OworICAgIG1lc3NhZ2Uub3B0aW9uYWxOZXN0ZWRNZXNzYWdlID0KKyAgICAgICAgbmV3IE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBtZXNzYWdlLm9wdGlvbmFsTmVzdGVkTWVzc2FnZS5mb28gPSAyNzsKKyAgICBtZXNzYWdlLm9wdGlvbmFsTmVzdGVkRW51bSA9IE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vLkJBUjsKKyAgICBtZXNzYWdlLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10geyA1LCA2LCA3LCA4IH07CisgICAgbWVzc2FnZS5yZXBlYXRlZEludDY0ID0gbmV3IGxvbmdbXSB7IDI3TCwgMjhMLCAyOUwgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkRmxvYXQgPSBuZXcgZmxvYXRbXSB7IDUuMGYsIDYuMGYgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkRG91YmxlID0gbmV3IGRvdWJsZVtdIHsgOTkuMSwgMjIuNSB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRCb29sID0gbmV3IGJvb2xlYW5bXSB7IHRydWUsIGZhbHNlLCB0cnVlIH07CisgICAgbWVzc2FnZS5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbXSB7ICJPbmUiLCAiVHdvIiB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlW11bXSB7IHsgMiwgNyB9LCB7IDIsIDcgfSB9OworICAgIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRNZXNzYWdlID0KKyAgICAgICAgbmV3IE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2VbXSB7CisgICAgICAgICAgbWVzc2FnZS5vcHRpb25hbE5lc3RlZE1lc3NhZ2UsCisgICAgICAgICAgbWVzc2FnZS5vcHRpb25hbE5lc3RlZE1lc3NhZ2UKKyAgICAgICAgfTsKKyAgICBtZXNzYWdlLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7CisgICAgICBOYW5vUmVmZXJlbmNlVHlwZXMuVGVzdEFsbFR5cGVzTmFuby5CQVIsCisgICAgICBOYW5vUmVmZXJlbmNlVHlwZXMuVGVzdEFsbFR5cGVzTmFuby5CQVoKKyAgICB9OworICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEVxdWFsc1dpdGhTcGVjaWFsRmxvYXRpbmdQb2ludFZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENoZWNrcyB0aGF0IHRoZSBuYW5vIGltcGxlbWVudGF0aW9uIGNvbXBsaWVzIHdpdGggT2JqZWN0LmVxdWFscygpIHdoZW4gdHJlYXRpbmcKKyAgICAvLyBmbG9hdGluZyBwb2ludCBudW1iZXJzLCBpLmUuIE5hTiA9PSBOYU4gYW5kICswLjAgIT0gLTAuMC4KKyAgICAvLyBUaGlzIHRlc3QgYXNzdW1lcyB0aGF0IHRoZSBnZW5lcmF0ZWQgZXF1YWxzKCkgaW1wbGVtZW50YXRpb25zIGFyZSBzeW1tZXRyaWMsIHNvCisgICAgLy8gdGhlcmUgd2lsbCBvbmx5IGJlIG9uZSBkaXJlY3Rpb24gZm9yIGVhY2ggZXF1YWxpdHkgY2hlY2suCisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG0xID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtMS5vcHRpb25hbEZsb2F0ID0gRmxvYXQuTmFOOworICAgIG0xLm9wdGlvbmFsRG91YmxlID0gRG91YmxlLk5hTjsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG0yID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtMi5vcHRpb25hbEZsb2F0ID0gRmxvYXQuTmFOOworICAgIG0yLm9wdGlvbmFsRG91YmxlID0gRG91YmxlLk5hTjsKKyAgICBhc3NlcnRUcnVlKG0xLmVxdWFscyhtMikpOworICAgIGFzc2VydFRydWUobTEuZXF1YWxzKAorICAgICAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IFRlc3RBbGxUeXBlc05hbm8oKSwgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobTEpKSkpOworCisgICAgbTEub3B0aW9uYWxGbG9hdCA9ICswZjsKKyAgICBtMi5vcHRpb25hbEZsb2F0ID0gLTBmOworICAgIGFzc2VydEZhbHNlKG0xLmVxdWFscyhtMikpOworCisgICAgbTEub3B0aW9uYWxGbG9hdCA9IC0wZjsKKyAgICBtMS5vcHRpb25hbERvdWJsZSA9ICswZDsKKyAgICBtMi5vcHRpb25hbERvdWJsZSA9IC0wZDsKKyAgICBhc3NlcnRGYWxzZShtMS5lcXVhbHMobTIpKTsKKworICAgIG0xLm9wdGlvbmFsRG91YmxlID0gLTBkOworICAgIGFzc2VydFRydWUobTEuZXF1YWxzKG0yKSk7CisgICAgYXNzZXJ0RmFsc2UobTEuZXF1YWxzKG5ldyBUZXN0QWxsVHlwZXNOYW5vKCkpKTsgLy8gLTAgZG9lcyBub3QgZXF1YWxzKCkgdGhlIGRlZmF1bHQgKzAKKyAgICBhc3NlcnRUcnVlKG0xLmVxdWFscygKKyAgICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBUZXN0QWxsVHlwZXNOYW5vKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0xKSkpKTsKKworICAgIC8vIC0tLS0tLS0KKworICAgIFRlc3RBbGxUeXBlc05hbm9IYXMgbTMgPSBuZXcgVGVzdEFsbFR5cGVzTmFub0hhcygpOworICAgIG0zLm9wdGlvbmFsRmxvYXQgPSBGbG9hdC5OYU47CisgICAgbTMuaGFzT3B0aW9uYWxGbG9hdCA9IHRydWU7CisgICAgbTMub3B0aW9uYWxEb3VibGUgPSBEb3VibGUuTmFOOworICAgIG0zLmhhc09wdGlvbmFsRG91YmxlID0gdHJ1ZTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vSGFzIG00ID0gbmV3IFRlc3RBbGxUeXBlc05hbm9IYXMoKTsKKyAgICBtNC5vcHRpb25hbEZsb2F0ID0gRmxvYXQuTmFOOworICAgIG00Lmhhc09wdGlvbmFsRmxvYXQgPSB0cnVlOworICAgIG00Lm9wdGlvbmFsRG91YmxlID0gRG91YmxlLk5hTjsKKyAgICBtNC5oYXNPcHRpb25hbERvdWJsZSA9IHRydWU7CisgICAgYXNzZXJ0VHJ1ZShtMy5lcXVhbHMobTQpKTsKKyAgICBhc3NlcnRUcnVlKG0zLmVxdWFscygKKyAgICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBUZXN0QWxsVHlwZXNOYW5vSGFzKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0zKSkpKTsKKworICAgIG0zLm9wdGlvbmFsRmxvYXQgPSArMGY7CisgICAgbTQub3B0aW9uYWxGbG9hdCA9IC0wZjsKKyAgICBhc3NlcnRGYWxzZShtMy5lcXVhbHMobTQpKTsKKworICAgIG0zLm9wdGlvbmFsRmxvYXQgPSAtMGY7CisgICAgbTMub3B0aW9uYWxEb3VibGUgPSArMGQ7CisgICAgbTQub3B0aW9uYWxEb3VibGUgPSAtMGQ7CisgICAgYXNzZXJ0RmFsc2UobTMuZXF1YWxzKG00KSk7CisKKyAgICBtMy5vcHRpb25hbERvdWJsZSA9IC0wZDsKKyAgICBtMy5oYXNPcHRpb25hbEZsb2F0ID0gZmFsc2U7ICAvLyAtMCBkb2VzIG5vdCBlcXVhbHMoKSB0aGUgZGVmYXVsdCArMCwKKyAgICBtMy5oYXNPcHRpb25hbERvdWJsZSA9IGZhbHNlOyAvLyBzbyB0aGVzZSBpbmNvcnJlY3QgJ2hhcycgZmxhZ3Mgc2hvdWxkIGJlIGRpc3JlZ2FyZGVkLgorICAgIGFzc2VydFRydWUobTMuZXF1YWxzKG00KSk7ICAgIC8vIG5vdGU6IG00IGhhcyB0aGUgJ2hhcycgZmxhZ3Mgc2V0LgorICAgIGFzc2VydEZhbHNlKG0zLmVxdWFscyhuZXcgVGVzdEFsbFR5cGVzTmFub0hhcygpKSk7IC8vIG5vdGU6IHRoZSBuZXcgbWVzc2FnZSBoYXMgKzAgZGVmYXVsdHMKKyAgICBhc3NlcnRUcnVlKG0zLmVxdWFscygKKyAgICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBUZXN0QWxsVHlwZXNOYW5vSGFzKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0zKSkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3RlOiB0aGUgZGVzZXJpYWxpemVkIG1lc3NhZ2UgaGFzIHRoZSAnaGFzJyBmbGFncyBzZXQuCisKKyAgICAvLyAtLS0tLS0tCisKKyAgICBUZXN0TmFub0FjY2Vzc29ycyBtNSA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycygpOworICAgIG01LnNldE9wdGlvbmFsRmxvYXQoRmxvYXQuTmFOKTsKKyAgICBtNS5zZXRPcHRpb25hbERvdWJsZShEb3VibGUuTmFOKTsKKyAgICBUZXN0TmFub0FjY2Vzc29ycyBtNiA9IG5ldyBUZXN0TmFub0FjY2Vzc29ycygpOworICAgIG02LnNldE9wdGlvbmFsRmxvYXQoRmxvYXQuTmFOKTsKKyAgICBtNi5zZXRPcHRpb25hbERvdWJsZShEb3VibGUuTmFOKTsKKyAgICBhc3NlcnRUcnVlKG01LmVxdWFscyhtNikpOworICAgIGFzc2VydFRydWUobTUuZXF1YWxzKAorICAgICAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IFRlc3ROYW5vQWNjZXNzb3JzKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG02KSkpKTsKKworICAgIG01LnNldE9wdGlvbmFsRmxvYXQoKzBmKTsKKyAgICBtNi5zZXRPcHRpb25hbEZsb2F0KC0wZik7CisgICAgYXNzZXJ0RmFsc2UobTUuZXF1YWxzKG02KSk7CisKKyAgICBtNS5zZXRPcHRpb25hbEZsb2F0KC0wZik7CisgICAgbTUuc2V0T3B0aW9uYWxEb3VibGUoKzBkKTsKKyAgICBtNi5zZXRPcHRpb25hbERvdWJsZSgtMGQpOworICAgIGFzc2VydEZhbHNlKG01LmVxdWFscyhtNikpOworCisgICAgbTUuc2V0T3B0aW9uYWxEb3VibGUoLTBkKTsKKyAgICBhc3NlcnRUcnVlKG01LmVxdWFscyhtNikpOworICAgIGFzc2VydEZhbHNlKG01LmVxdWFscyhuZXcgVGVzdE5hbm9BY2Nlc3NvcnMoKSkpOworICAgIGFzc2VydFRydWUobTUuZXF1YWxzKAorICAgICAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IFRlc3ROYW5vQWNjZXNzb3JzKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG02KSkpKTsKKworICAgIC8vIC0tLS0tLS0KKworICAgIE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vIG03ID0gbmV3IE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbTcub3B0aW9uYWxGbG9hdCA9IEZsb2F0Lk5hTjsKKyAgICBtNy5vcHRpb25hbERvdWJsZSA9IERvdWJsZS5OYU47CisgICAgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8gbTggPSBuZXcgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBtOC5vcHRpb25hbEZsb2F0ID0gRmxvYXQuTmFOOworICAgIG04Lm9wdGlvbmFsRG91YmxlID0gRG91YmxlLk5hTjsKKyAgICBhc3NlcnRUcnVlKG03LmVxdWFscyhtOCkpOworICAgIGFzc2VydFRydWUobTcuZXF1YWxzKE1lc3NhZ2VOYW5vLm1lcmdlRnJvbSgKKyAgICAgICAgbmV3IE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG03KSkpKTsKKworICAgIG03Lm9wdGlvbmFsRmxvYXQgPSArMGY7CisgICAgbTgub3B0aW9uYWxGbG9hdCA9IC0wZjsKKyAgICBhc3NlcnRGYWxzZShtNy5lcXVhbHMobTgpKTsKKworICAgIG03Lm9wdGlvbmFsRmxvYXQgPSAtMGY7CisgICAgbTcub3B0aW9uYWxEb3VibGUgPSArMGQ7CisgICAgbTgub3B0aW9uYWxEb3VibGUgPSAtMGQ7CisgICAgYXNzZXJ0RmFsc2UobTcuZXF1YWxzKG04KSk7CisKKyAgICBtNy5vcHRpb25hbERvdWJsZSA9IC0wZDsKKyAgICBhc3NlcnRUcnVlKG03LmVxdWFscyhtOCkpOworICAgIGFzc2VydEZhbHNlKG03LmVxdWFscyhuZXcgTmFub1JlZmVyZW5jZVR5cGVzLlRlc3RBbGxUeXBlc05hbm8oKSkpOworICAgIGFzc2VydFRydWUobTcuZXF1YWxzKE1lc3NhZ2VOYW5vLm1lcmdlRnJvbSgKKyAgICAgICAgbmV3IE5hbm9SZWZlcmVuY2VUeXBlcy5UZXN0QWxsVHlwZXNOYW5vKCksIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG03KSkpKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFRlc3RBbGxUeXBlc05hbm8gZ2VuZXJhdGVNZXNzYWdlRm9yT25lb2YoaW50IGNhc2VOdW1iZXIpIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIHJlc3VsdCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlIG5lc3RlZCA9CisgICAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBuZXN0ZWQuYmIgPSAyOworICAgIHN3aXRjaCAoY2FzZU51bWJlcikgeworICAgICAgY2FzZSBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX1VJTlQzMl9GSUVMRF9OVU1CRVI6CisgICAgICAgIHJlc3VsdC5zZXRPbmVvZlVpbnQzMigxKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfRU5VTV9GSUVMRF9OVU1CRVI6CisgICAgICAgIHJlc3VsdC5zZXRPbmVvZkVudW0oVGVzdEFsbFR5cGVzTmFuby5CQVIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI6CisgICAgICAgIHJlc3VsdC5zZXRPbmVvZk5lc3RlZE1lc3NhZ2UobmVzdGVkKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfQllURVNfRklFTERfTlVNQkVSOgorICAgICAgICByZXN1bHQuc2V0T25lb2ZCeXRlcyhuZXcgYnl0ZVtdIHsxLCAyfSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX1NUUklOR19GSUVMRF9OVU1CRVI6CisgICAgICAgIHJlc3VsdC5zZXRPbmVvZlN0cmluZygiaGVsbG8iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfRklYRUQ2NF9GSUVMRF9OVU1CRVI6CisgICAgICAgIHJlc3VsdC5zZXRPbmVvZkZpeGVkNjQoLTFMKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigidW5leHBlY3RlZCBjYXNlIG51bWJlcjogIiArIGNhc2VOdW1iZXIpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE9uZW9mSGFzaENvZGVFcXVhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG0xID0gZ2VuZXJhdGVNZXNzYWdlRm9yT25lb2YoCisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKG0xLCBnZW5lcmF0ZU1lc3NhZ2VGb3JPbmVvZigKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSKSk7CisgICAgYXNzZXJ0RmFsc2UobTEuZXF1YWxzKG5ldyBUZXN0QWxsVHlwZXNOYW5vKCkpKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbTIgPSBnZW5lcmF0ZU1lc3NhZ2VGb3JPbmVvZigKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9FTlVNX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKG0yLCBnZW5lcmF0ZU1lc3NhZ2VGb3JPbmVvZigKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9FTlVNX0ZJRUxEX05VTUJFUikpOworICAgIGFzc2VydEZhbHNlKG0yLmVxdWFscyhuZXcgVGVzdEFsbFR5cGVzTmFubygpKSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG0zID0gZ2VuZXJhdGVNZXNzYWdlRm9yT25lb2YoCisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSKTsKKyAgICBhc3NlcnRFcXVhbHMobTMsIGdlbmVyYXRlTWVzc2FnZUZvck9uZW9mKAorICAgICAgICBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUikpOworICAgIGFzc2VydEZhbHNlKG0zLmVxdWFscyhuZXcgVGVzdEFsbFR5cGVzTmFubygpKSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG00ID0gZ2VuZXJhdGVNZXNzYWdlRm9yT25lb2YoCisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfQllURVNfRklFTERfTlVNQkVSKTsKKyAgICBhc3NlcnRFcXVhbHMobTQsIGdlbmVyYXRlTWVzc2FnZUZvck9uZW9mKAorICAgICAgICBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUikpOworICAgIGFzc2VydEZhbHNlKG00LmVxdWFscyhuZXcgVGVzdEFsbFR5cGVzTmFubygpKSk7CisKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG01ID0gZ2VuZXJhdGVNZXNzYWdlRm9yT25lb2YoCisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKG01LCBnZW5lcmF0ZU1lc3NhZ2VGb3JPbmVvZigKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9TVFJJTkdfRklFTERfTlVNQkVSKSk7CisgICAgYXNzZXJ0RmFsc2UobTUuZXF1YWxzKG5ldyBUZXN0QWxsVHlwZXNOYW5vKCkpKTsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbTYgPSBnZW5lcmF0ZU1lc3NhZ2VGb3JPbmVvZigKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9GSVhFRDY0X0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKG02LCBnZW5lcmF0ZU1lc3NhZ2VGb3JPbmVvZigKKyAgICAgICAgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9GSVhFRDY0X0ZJRUxEX05VTUJFUikpOworICAgIGFzc2VydEZhbHNlKG02LmVxdWFscyhuZXcgVGVzdEFsbFR5cGVzTmFubygpKSk7CisKKyAgICBNYXA8VGVzdEFsbFR5cGVzTmFubywgSW50ZWdlcj4gbWFwID0KKyAgICAgICAgbmV3IEhhc2hNYXA8VGVzdEFsbFR5cGVzTmFubywgSW50ZWdlcj4oKTsKKyAgICBtYXAucHV0KG0xLCAxKTsKKyAgICBtYXAucHV0KG0yLCAyKTsKKyAgICBtYXAucHV0KG0zLCAzKTsKKyAgICBtYXAucHV0KG00LCA0KTsKKyAgICBtYXAucHV0KG01LCA1KTsKKyAgICBtYXAucHV0KG02LCA2KTsKKworICAgIGFzc2VydEVxdWFscyg2LCBtYXAuc2l6ZSgpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBjaGVja09uZW9mQ2FzZShUZXN0QWxsVHlwZXNOYW5vIG5hbm8sIGludCBmaWVsZCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEVxdWFscyhmaWVsZCwgbmFuby5nZXRPbmVvZkZpZWxkQ2FzZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIGZpZWxkID09IFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfQllURVNfRklFTERfTlVNQkVSLAorICAgICAgICBuYW5vLmhhc09uZW9mQnl0ZXMoKSk7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICBmaWVsZCA9PSBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0VOVU1fRklFTERfTlVNQkVSLAorICAgICAgICBuYW5vLmhhc09uZW9mRW51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgIGZpZWxkID09IFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfRklYRUQ2NF9GSUVMRF9OVU1CRVIsCisgICAgICAgIG5hbm8uaGFzT25lb2ZGaXhlZDY0KCkpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgZmllbGQgPT0gVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIsCisgICAgICAgIG5hbm8uaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCkpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgZmllbGQgPT0gVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9TVFJJTkdfRklFTERfTlVNQkVSLAorICAgICAgICBuYW5vLmhhc09uZW9mU3RyaW5nKCkpOworICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgZmllbGQgPT0gVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSLAorICAgICAgICBuYW5vLmhhc09uZW9mVWludDMyKCkpOworCisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZEZWZhdWx0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtMSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgY2hlY2tPbmVvZkNhc2UobTEsIDApOworICAgIGFzc2VydEVxdWFscyhXaXJlRm9ybWF0TmFuby5FTVBUWV9CWVRFUywgbTEuZ2V0T25lb2ZCeXRlcygpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG0xLmdldE9uZW9mRW51bSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMEwsIG0xLmdldE9uZW9mRml4ZWQ2NCgpKTsKKyAgICBhc3NlcnRFcXVhbHMobnVsbCwgbTEuZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkpOworICAgIGFzc2VydEVxdWFscygiIiwgbTEuZ2V0T25lb2ZTdHJpbmcoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG0xLmdldE9uZW9mVWludDMyKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE9uZW9mRXhjbHVzaXZlbmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgY2hlY2tPbmVvZkNhc2UobSwgMCk7CisKKyAgICBtLnNldE9uZW9mQnl0ZXMobmV3IGJ5dGVbXXswLCAxfSk7CisgICAgY2hlY2tPbmVvZkNhc2UobSwgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9CWVRFU19GSUVMRF9OVU1CRVIpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhuZXcgYnl0ZVtdezAsICAxfSwgbS5nZXRPbmVvZkJ5dGVzKCkpKTsKKworICAgIG0uc2V0T25lb2ZFbnVtKFRlc3RBbGxUeXBlc05hbm8uQkFaKTsKKyAgICBjaGVja09uZW9mQ2FzZShtLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0VOVU1fRklFTERfTlVNQkVSKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVosIG0uZ2V0T25lb2ZFbnVtKCkpOworICAgIGFzc2VydEVxdWFscyhXaXJlRm9ybWF0TmFuby5FTVBUWV9CWVRFUywgbS5nZXRPbmVvZkJ5dGVzKCkpOworCisgICAgbS5zZXRPbmVvZkZpeGVkNjQoLTFMKTsKKyAgICBjaGVja09uZW9mQ2FzZShtLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0ZJWEVENjRfRklFTERfTlVNQkVSKTsKKyAgICBhc3NlcnRFcXVhbHMoLTFMLCBtLmdldE9uZW9mRml4ZWQ2NCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG0uZ2V0T25lb2ZFbnVtKCkpOworCisgICAgbS5zZXRPbmVvZk5lc3RlZE1lc3NhZ2UobmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSgpKTsKKyAgICBjaGVja09uZW9mQ2FzZShtLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCksIG0uZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkpOworICAgIGFzc2VydEVxdWFscygwTCwgbS5nZXRPbmVvZkZpeGVkNjQoKSk7CisKKyAgICBtLnNldE9uZW9mU3RyaW5nKCJoZWxsbyIpOworICAgIGNoZWNrT25lb2ZDYXNlKG0sIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIG0uZ2V0T25lb2ZTdHJpbmcoKSk7CisgICAgYXNzZXJ0TnVsbChtLmdldE9uZW9mTmVzdGVkTWVzc2FnZSgpKTsKKworICAgIG0uc2V0T25lb2ZVaW50MzIoMTApOworICAgIGNoZWNrT25lb2ZDYXNlKG0sIFRlc3RBbGxUeXBlc05hbm8uT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0RXF1YWxzKDEwLCBtLmdldE9uZW9mVWludDMyKCkpOworICAgIGFzc2VydEVxdWFscygiIiwgbS5nZXRPbmVvZlN0cmluZygpKTsKKworICAgIG0uc2V0T25lb2ZCeXRlcyhuZXcgYnl0ZVtdezAsIDF9KTsKKyAgICBjaGVja09uZW9mQ2FzZShtLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUik7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBieXRlW117MCwgIDF9LCBtLmdldE9uZW9mQnl0ZXMoKSkpOworICAgIGFzc2VydEVxdWFscygwLCBtLmdldE9uZW9mVWludDMyKCkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE9uZW9mQ2xlYXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIG0gPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG0uc2V0T25lb2ZCeXRlcyhuZXcgYnl0ZVtdezAsIDF9KTsKKyAgICBtLmNsZWFyT25lb2ZGaWVsZCgpOworICAgIGNoZWNrT25lb2ZDYXNlKG0sIDApOworCisgICAgbS5zZXRPbmVvZkVudW0oVGVzdEFsbFR5cGVzTmFuby5CQVopOworICAgIG0uY2xlYXJPbmVvZkZpZWxkKCk7CisgICAgY2hlY2tPbmVvZkNhc2UobSwgMCk7CisKKyAgICBtLnNldE9uZW9mRml4ZWQ2NCgtMUwpOworICAgIG0uY2xlYXJPbmVvZkZpZWxkKCk7CisgICAgY2hlY2tPbmVvZkNhc2UobSwgMCk7CisKKyAgICBtLnNldE9uZW9mTmVzdGVkTWVzc2FnZShuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCkpOworICAgIG0uY2xlYXJPbmVvZkZpZWxkKCk7CisgICAgY2hlY2tPbmVvZkNhc2UobSwgMCk7CisKKyAgICBtLnNldE9uZW9mU3RyaW5nKCJoZWxsbyIpOworICAgIG0uY2xlYXJPbmVvZkZpZWxkKCk7CisgICAgY2hlY2tPbmVvZkNhc2UobSwgMCk7CisKKyAgICBtLnNldE9uZW9mVWludDMyKDEwKTsKKyAgICBtLmNsZWFyT25lb2ZGaWVsZCgpOworICAgIGNoZWNrT25lb2ZDYXNlKG0sIDApOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE9uZW9mTWFyc2hhbGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RBbGxUeXBlc05hbm8gbSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgVGVzdEFsbFR5cGVzTmFubyBwYXJzZWQgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIHsKKyAgICAgIG0uc2V0T25lb2ZCeXRlcyhuZXcgYnl0ZVtdezAsIDF9KTsKKyAgICAgIGJ5dGVbXSBzZXJpYWxpemVkID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobSk7CisgICAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20ocGFyc2VkLCBzZXJpYWxpemVkKTsKKyAgICAgIGNoZWNrT25lb2ZDYXNlKHBhcnNlZCwgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9CWVRFU19GSUVMRF9OVU1CRVIpOworICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBieXRlW117MCwgMX0sIHBhcnNlZC5nZXRPbmVvZkJ5dGVzKCkpKTsKKyAgICB9CisgICAgeworICAgICAgbS5zZXRPbmVvZkVudW0oVGVzdEFsbFR5cGVzTmFuby5CQVopOworICAgICAgYnl0ZVtdIHNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtKTsKKyAgICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShwYXJzZWQsIHNlcmlhbGl6ZWQpOworICAgICAgY2hlY2tPbmVvZkNhc2UobSwgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9FTlVNX0ZJRUxEX05VTUJFUik7CisgICAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVosIG0uZ2V0T25lb2ZFbnVtKCkpOworICAgIH0KKyAgICB7CisgICAgICBtLnNldE9uZW9mRW51bShUZXN0QWxsVHlwZXNOYW5vLkJBWik7CisgICAgICBieXRlW10gc2VyaWFsaXplZCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0pOworICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKHBhcnNlZCwgc2VyaWFsaXplZCk7CisgICAgICBjaGVja09uZW9mQ2FzZShtLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0VOVU1fRklFTERfTlVNQkVSKTsKKyAgICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBWiwgbS5nZXRPbmVvZkVudW0oKSk7CisgICAgfQorICAgIHsKKyAgICAgIG0uc2V0T25lb2ZGaXhlZDY0KC0xTCk7CisgICAgICBieXRlW10gc2VyaWFsaXplZCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0pOworICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKHBhcnNlZCwgc2VyaWFsaXplZCk7CisgICAgICBjaGVja09uZW9mQ2FzZShtLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0ZJWEVENjRfRklFTERfTlVNQkVSKTsKKyAgICAgIGFzc2VydEVxdWFscygtMUwsIG0uZ2V0T25lb2ZGaXhlZDY0KCkpOworICAgIH0KKyAgICB7CisgICAgICBtLnNldE9uZW9mTmVzdGVkTWVzc2FnZShuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCkpOworICAgICAgYnl0ZVtdIHNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtKTsKKyAgICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShwYXJzZWQsIHNlcmlhbGl6ZWQpOworICAgICAgY2hlY2tPbmVvZkNhc2UobSwgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIpOworICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKSwgbS5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSk7CisgICAgfQorICAgIHsKKyAgICAgIG0uc2V0T25lb2ZTdHJpbmcoImhlbGxvIik7CisgICAgICBieXRlW10gc2VyaWFsaXplZCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG0pOworICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKHBhcnNlZCwgc2VyaWFsaXplZCk7CisgICAgICBhc3NlcnRFcXVhbHMoImhlbGxvIiwgbS5nZXRPbmVvZlN0cmluZygpKTsKKyAgICAgIGFzc2VydE51bGwobS5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSk7CisgICAgfQorICAgIHsKKyAgICAgIG0uc2V0T25lb2ZVaW50MzIoMTApOworICAgICAgYnl0ZVtdIHNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtKTsKKyAgICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShwYXJzZWQsIHNlcmlhbGl6ZWQpOworICAgICAgY2hlY2tPbmVvZkNhc2UobSwgVGVzdEFsbFR5cGVzTmFuby5PTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSKTsKKyAgICAgIGFzc2VydEVxdWFscygxMCwgbS5nZXRPbmVvZlVpbnQzMigpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0T25lb2ZTZXJpYWxpemVkQ29uY2F0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVGVzdEFsbFR5cGVzTmFubyBtMSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbTEuc2V0T25lb2ZCeXRlcyhuZXcgYnl0ZVtdIHswLCAxfSk7CisgICAgYnl0ZVtdIGIxID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobTEpOworICAgIFRlc3RBbGxUeXBlc05hbm8gbTIgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG0yLnNldE9uZW9mRW51bShUZXN0QWxsVHlwZXNOYW5vLkJBWik7CisgICAgYnl0ZVtdIGIyID0gTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobTIpOworICAgIGJ5dGVbXSBiMyA9IG5ldyBieXRlW2IxLmxlbmd0aCArIGIyLmxlbmd0aF07CisgICAgU3lzdGVtLmFycmF5Y29weShiMSwgMCwgYjMsIDAsIGIxLmxlbmd0aCk7CisgICAgU3lzdGVtLmFycmF5Y29weShiMiwgMCwgYjMsIGIxLmxlbmd0aCwgYjIubGVuZ3RoKTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIHBhcnNlZCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKHBhcnNlZCwgYjMpOworICAgIC8vIHRoZSBsYXN0IG9uIHRoZSB3aXJlIHdpbnMuCisgICAgY2hlY2tPbmVvZkNhc2UocGFyc2VkLCBUZXN0QWxsVHlwZXNOYW5vLk9ORU9GX0VOVU1fRklFTERfTlVNQkVSKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVosIHBhcnNlZC5nZXRPbmVvZkVudW0oKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TnVsbFJlcGVhdGVkRmllbGRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQ2hlY2sgdGhhdCBzZXJpYWxpemF0aW9uIGFmdGVyIGV4cGxpY2l0bHkgc2V0dGluZyBhIHJlcGVhdGVkIGZpZWxkCisgICAgLy8gdG8gbnVsbCBkb2Vzbid0IE5QRS4KKyAgICBUZXN0QWxsVHlwZXNOYW5vIG1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIG1lc3NhZ2UucmVwZWF0ZWRJbnQzMiA9IG51bGw7CisgICAgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobWVzc2FnZSk7ICAvLyBzaG91bGQgbm90IE5QRQorICAgIG1lc3NhZ2UudG9TdHJpbmcoKTsgLy8gc2hvdWxkIG5vdCBOUEUKKworICAgIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRFbnVtID0gbnVsbDsKKyAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKTsgIC8vIHNob3VsZCBub3QgTlBFCisgICAgbWVzc2FnZS50b1N0cmluZygpOyAvLyBzaG91bGQgbm90IE5QRQorCisgICAgbWVzc2FnZS5yZXBlYXRlZEJ5dGVzID0gbnVsbDsKKyAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKTsgLy8gc2hvdWxkIG5vdCBOUEUKKyAgICBtZXNzYWdlLnRvU3RyaW5nKCk7IC8vIHNob3VsZCBub3QgTlBFCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkTmVzdGVkTWVzc2FnZSA9IG51bGw7CisgICAgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobWVzc2FnZSk7IC8vIHNob3VsZCBub3QgTlBFCisgICAgbWVzc2FnZS50b1N0cmluZygpOyAvLyBzaG91bGQgbm90IE5QRQorCisgICAgbWVzc2FnZS5yZXBlYXRlZFBhY2tlZEludDMyID0gbnVsbDsKKyAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKTsgLy8gc2hvdWxkIG5vdCBOUEUKKyAgICBtZXNzYWdlLnRvU3RyaW5nKCk7IC8vIHNob3VsZCBub3QgTlBFCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bSA9IG51bGw7CisgICAgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkobWVzc2FnZSk7IC8vIHNob3VsZCBub3QgTlBFCisgICAgbWVzc2FnZS50b1N0cmluZygpOyAvLyBzaG91bGQgbm90IE5QRQorCisgICAgLy8gQ3JlYXRlIGEgc2Vjb25kIG1lc3NhZ2UgdG8gbWVyZ2UgaW50byBtZXNzYWdlLgorICAgIFRlc3RBbGxUeXBlc05hbm8gc2Vjb25kTWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgc2Vjb25kTWVzc2FnZS5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHsxLCAyLCAzfTsKKyAgICBzZWNvbmRNZXNzYWdlLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7CisgICAgICBUZXN0QWxsVHlwZXNOYW5vLkZPTywgVGVzdEFsbFR5cGVzTmFuby5CQVIKKyAgICB9OworICAgIHNlY29uZE1lc3NhZ2UucmVwZWF0ZWRCeXRlcyA9IG5ldyBieXRlW11bXSB7ezEsIDJ9LCB7MywgNH19OworICAgIFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSBuZXN0ZWQgPQorICAgICAgICBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlKCk7CisgICAgbmVzdGVkLmJiID0gNTU7CisgICAgc2Vjb25kTWVzc2FnZS5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UgPQorICAgICAgICBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlW10ge25lc3RlZH07CisgICAgc2Vjb25kTWVzc2FnZS5yZXBlYXRlZFBhY2tlZEludDMyID0gbmV3IGludFtdIHsxLCAyLCAzfTsKKyAgICBzZWNvbmRNZXNzYWdlLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7CisgICAgICAgIFRlc3RBbGxUeXBlc05hbm8uRk9PLCBUZXN0QWxsVHlwZXNOYW5vLkJBUgorICAgICAgfTsKKworICAgIC8vIFNob3VsZCBub3QgTlBFCisgICAgbWVzc2FnZS5tZXJnZUZyb20oQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vLm5ld0luc3RhbmNlKAorICAgICAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShzZWNvbmRNZXNzYWdlKSkpOworICAgIGFzc2VydEVxdWFscygzLCBtZXNzYWdlLnJlcGVhdGVkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5yZXBlYXRlZEludDMyWzJdKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5yZXBlYXRlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRFbnVtWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgbWVzc2FnZS5yZXBlYXRlZEJ5dGVzLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIG1lc3NhZ2UucmVwZWF0ZWRCeXRlc1sxXVsxXSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIG1lc3NhZ2UucmVwZWF0ZWROZXN0ZWRNZXNzYWdlLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDU1LCBtZXNzYWdlLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVswXS5iYik7CisgICAgYXNzZXJ0RXF1YWxzKDMsIG1lc3NhZ2UucmVwZWF0ZWRQYWNrZWRJbnQzMi5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygyLCBtZXNzYWdlLnJlcGVhdGVkUGFja2VkSW50MzJbMV0pOworICAgIGFzc2VydEVxdWFscygyLCBtZXNzYWdlLnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgbWVzc2FnZS5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW1bMV0pOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE51bGxSZXBlYXRlZEZpZWxkRWxlbWVudHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDaGVjayB0aGF0IHNlcmlhbGl6YXRpb24gd2l0aCBudWxsIGFycmF5IGVsZW1lbnRzIGRvZXNuJ3QgTlBFLgorICAgIFN0cmluZyBzdHJpbmcxID0gIjEiOworICAgIFN0cmluZyBzdHJpbmcyID0gIjIiOworICAgIGJ5dGVbXSBieXRlczEgPSB7MywgNH07CisgICAgYnl0ZVtdIGJ5dGVzMiA9IHs1LCA2fTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UgbXNnMSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBtc2cxLmJiID0gNzsKKyAgICBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UgbXNnMiA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKTsKKyAgICBtc2cyLmJiID0gODsKKworICAgIFRlc3RBbGxUeXBlc05hbm8gbWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgbWVzc2FnZS5yZXBlYXRlZFN0cmluZyA9IG5ldyBTdHJpbmdbXSB7bnVsbCwgc3RyaW5nMSwgc3RyaW5nMn07CisgICAgbWVzc2FnZS5yZXBlYXRlZEJ5dGVzID0gbmV3IGJ5dGVbXVtdIHtieXRlczEsIG51bGwsIGJ5dGVzMn07CisgICAgbWVzc2FnZS5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlW10ge21zZzEsIG1zZzIsIG51bGx9OworICAgIG1lc3NhZ2UucmVwZWF0ZWRHcm91cCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vLlJlcGVhdGVkR3JvdXBbXSB7bnVsbCwgbnVsbCwgbnVsbH07CisKKyAgICBieXRlW10gc2VyaWFsaXplZCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG1lc3NhZ2UpOyAvLyBzaG91bGQgbm90IE5QRQorICAgIFRlc3RBbGxUeXBlc05hbm8gZGVzZXJpYWxpemVkID0gTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBUZXN0QWxsVHlwZXNOYW5vKCksIHNlcmlhbGl6ZWQpOworICAgIGFzc2VydEVxdWFscygyLCBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRTdHJpbmcubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoc3RyaW5nMSwgZGVzZXJpYWxpemVkLnJlcGVhdGVkU3RyaW5nWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoc3RyaW5nMiwgZGVzZXJpYWxpemVkLnJlcGVhdGVkU3RyaW5nWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgZGVzZXJpYWxpemVkLnJlcGVhdGVkQnl0ZXMubGVuZ3RoKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoYnl0ZXMxLCBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRCeXRlc1swXSkpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhieXRlczIsIGRlc2VyaWFsaXplZC5yZXBlYXRlZEJ5dGVzWzFdKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGRlc2VyaWFsaXplZC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMobXNnMS5iYiwgZGVzZXJpYWxpemVkLnJlcGVhdGVkTmVzdGVkTWVzc2FnZVswXS5iYik7CisgICAgYXNzZXJ0RXF1YWxzKG1zZzIuYmIsIGRlc2VyaWFsaXplZC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VbMV0uYmIpOworICAgIGFzc2VydEVxdWFscygwLCBkZXNlcmlhbGl6ZWQucmVwZWF0ZWRHcm91cC5sZW5ndGgpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJlcGVhdGVkTWVyZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDaGVjayB0aGF0IG1lcmdpbmcgcmVwZWF0ZWQgZmllbGRzIGNhdXNlIHRoZSBhcnJheXMgdG8gZXhwYW5kIHdpdGgKKyAgICAvLyBuZXcgZGF0YS4KKyAgICBUZXN0QWxsVHlwZXNOYW5vIGZpcnN0ID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBmaXJzdC5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHsxLCAyLCAzfTsKKyAgICBUZXN0QWxsVHlwZXNOYW5vIHNlY29uZCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgc2Vjb25kLnJlcGVhdGVkSW50MzIgPSBuZXcgaW50W10gezQsIDV9OworICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShmaXJzdCwgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkoc2Vjb25kKSk7CisgICAgYXNzZXJ0RXF1YWxzKDUsIGZpcnN0LnJlcGVhdGVkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgZmlyc3QucmVwZWF0ZWRJbnQzMlswXSk7CisgICAgYXNzZXJ0RXF1YWxzKDQsIGZpcnN0LnJlcGVhdGVkSW50MzJbM10pOworCisgICAgZmlyc3QgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIGZpcnN0LnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7VGVzdEFsbFR5cGVzTmFuby5CQVJ9OworICAgIHNlY29uZCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgc2Vjb25kLnJlcGVhdGVkTmVzdGVkRW51bSA9IG5ldyBpbnRbXSB7VGVzdEFsbFR5cGVzTmFuby5GT099OworICAgIE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShmaXJzdCwgTWVzc2FnZU5hbm8udG9CeXRlQXJyYXkoc2Vjb25kKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGZpcnN0LnJlcGVhdGVkTmVzdGVkRW51bS5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyhUZXN0QWxsVHlwZXNOYW5vLkJBUiwgZmlyc3QucmVwZWF0ZWROZXN0ZWRFbnVtWzBdKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5GT08sIGZpcnN0LnJlcGVhdGVkTmVzdGVkRW51bVsxXSk7CisKKyAgICBmaXJzdCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgZmlyc3QucmVwZWF0ZWROZXN0ZWRNZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZVtdIHsKKyAgICAgIG5ldyBUZXN0QWxsVHlwZXNOYW5vLk5lc3RlZE1lc3NhZ2UoKQorICAgIH07CisgICAgZmlyc3QucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzBdLmJiID0gMzsKKyAgICBzZWNvbmQgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIHNlY29uZC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UgPSBuZXcgVGVzdEFsbFR5cGVzTmFuby5OZXN0ZWRNZXNzYWdlW10geworICAgICAgbmV3IFRlc3RBbGxUeXBlc05hbm8uTmVzdGVkTWVzc2FnZSgpCisgICAgfTsKKyAgICBzZWNvbmQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzBdLmJiID0gNTsKKyAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20oZmlyc3QsIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KHNlY29uZCkpOworICAgIGFzc2VydEVxdWFscygyLCBmaXJzdC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2UubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgZmlyc3QucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzBdLmJiKTsKKyAgICBhc3NlcnRFcXVhbHMoNSwgZmlyc3QucmVwZWF0ZWROZXN0ZWRNZXNzYWdlWzFdLmJiKTsKKworICAgIGZpcnN0ID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBmaXJzdC5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0ID0gbmV3IGxvbmdbXSB7LTEsIC0yLCAtM307CisgICAgc2Vjb25kID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBzZWNvbmQucmVwZWF0ZWRQYWNrZWRTZml4ZWQ2NCA9IG5ldyBsb25nW10gey00LCAtNX07CisgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKGZpcnN0LCBNZXNzYWdlTmFuby50b0J5dGVBcnJheShzZWNvbmQpKTsKKyAgICBhc3NlcnRFcXVhbHMoNSwgZmlyc3QucmVwZWF0ZWRQYWNrZWRTZml4ZWQ2NC5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscygtMSwgZmlyc3QucmVwZWF0ZWRQYWNrZWRTZml4ZWQ2NFswXSk7CisgICAgYXNzZXJ0RXF1YWxzKC00LCBmaXJzdC5yZXBlYXRlZFBhY2tlZFNmaXhlZDY0WzNdKTsKKworICAgIGZpcnN0ID0gbmV3IFRlc3RBbGxUeXBlc05hbm8oKTsKKyAgICBmaXJzdC5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW0gPSBuZXcgaW50W10ge1Rlc3RBbGxUeXBlc05hbm8uQkFSfTsKKyAgICBzZWNvbmQgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIHNlY29uZC5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW0gPSBuZXcgaW50W10ge1Rlc3RBbGxUeXBlc05hbm8uRk9PfTsKKyAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20oZmlyc3QsIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KHNlY29uZCkpOworICAgIGFzc2VydEVxdWFscygyLCBmaXJzdC5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW0ubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoVGVzdEFsbFR5cGVzTmFuby5CQVIsIGZpcnN0LnJlcGVhdGVkUGFja2VkTmVzdGVkRW51bVswXSk7CisgICAgYXNzZXJ0RXF1YWxzKFRlc3RBbGxUeXBlc05hbm8uRk9PLCBmaXJzdC5yZXBlYXRlZFBhY2tlZE5lc3RlZEVudW1bMV0pOworCisgICAgLy8gTm93IHRlc3QgcmVwZWF0ZWQgbWVyZ2luZyBpbiBhIG5lc3RlZCBzY29wZQorICAgIFRlc3RSZXBlYXRlZE1lcmdlTmFubyBmaXJzdENvbnRhaW5lciA9IG5ldyBUZXN0UmVwZWF0ZWRNZXJnZU5hbm8oKTsKKyAgICBmaXJzdENvbnRhaW5lci5jb250YWluZWQgPSBuZXcgVGVzdEFsbFR5cGVzTmFubygpOworICAgIGZpcnN0Q29udGFpbmVyLmNvbnRhaW5lZC5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHsxMCwgMjB9OworICAgIFRlc3RSZXBlYXRlZE1lcmdlTmFubyBzZWNvbmRDb250YWluZXIgPSBuZXcgVGVzdFJlcGVhdGVkTWVyZ2VOYW5vKCk7CisgICAgc2Vjb25kQ29udGFpbmVyLmNvbnRhaW5lZCA9IG5ldyBUZXN0QWxsVHlwZXNOYW5vKCk7CisgICAgc2Vjb25kQ29udGFpbmVyLmNvbnRhaW5lZC5yZXBlYXRlZEludDMyID0gbmV3IGludFtdIHszMH07CisgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKGZpcnN0Q29udGFpbmVyLCBNZXNzYWdlTmFuby50b0J5dGVBcnJheShzZWNvbmRDb250YWluZXIpKTsKKyAgICBhc3NlcnRFcXVhbHMoMywgZmlyc3RDb250YWluZXIuY29udGFpbmVkLnJlcGVhdGVkSW50MzIubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMjAsIGZpcnN0Q29udGFpbmVyLmNvbnRhaW5lZC5yZXBlYXRlZEludDMyWzFdKTsKKyAgICBhc3NlcnRFcXVhbHMoMzAsIGZpcnN0Q29udGFpbmVyLmNvbnRhaW5lZC5yZXBlYXRlZEludDMyWzJdKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RSZXBlYXRlZFBhY2thYmxlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENoZWNrIHRoYXQgcmVwZWF0ZWQgZmllbGRzIHdpdGggcGFja2FibGUgdHlwZXMgY2FuIGFjY2VwdCBib3RoIHBhY2tlZCBhbmQgdW5wYWNrZWQKKyAgICAvLyBzZXJpYWxpemVkIGZvcm1zLgorICAgIE5hbm9SZXBlYXRlZFBhY2thYmxlcy5Ob25QYWNrZWQgbm9uUGFja2VkID0gbmV3IE5hbm9SZXBlYXRlZFBhY2thYmxlcy5Ob25QYWNrZWQoKTsKKyAgICAvLyBFeGFnZ2VyYXRlcyB0aGUgZmlyc3QgdmFsdWVzIG9mIHZhcmludC10eXBlZCBhcnJheXMuIFRoaXMgaXMgdG8gdGVzdCB0aGF0IHRoZSBwYXJzaW5nIGNvZGUKKyAgICAvLyBvZiBwYWNrZWQgZmllbGRzIGhhbmRsZXMgbm9uLXBhY2tlZCBkYXRhIGNvcnJlY3RseS4gSWYgdGhlIGNvZGUgaW5jb3JyZWN0bHkgdGhpbmtzIGl0IGlzCisgICAgLy8gcmVhZGluZyBmcm9tIGEgcGFja2VkIHRhZywgaXQgd2lsbCByZWFkIHRoZSBmaXJzdCB2YWx1ZSBhcyB0aGUgYnl0ZSBsZW5ndGggb2YgdGhlIGZpZWxkLAorICAgIC8vIGFuZCB0aGUgbGFyZ2UgbnVtYmVyIHdpbGwgY2F1c2UgdGhlIGlucHV0IHRvIGdvIG91dCBvZiBib3VuZHMsIHRodXMgY2FwdHVyaW5nIHRoZSBlcnJvci4KKyAgICBub25QYWNrZWQuaW50MzJTID0gbmV3IGludFtdIHsxMDAwLCAyLCAzfTsKKyAgICBub25QYWNrZWQuaW50NjRTID0gbmV3IGxvbmdbXSB7NDAwMCwgNSwgNn07CisgICAgbm9uUGFja2VkLnVpbnQzMlMgPSBuZXcgaW50W10gezcwMDAsIDgsIDl9OworICAgIG5vblBhY2tlZC51aW50NjRTID0gbmV3IGxvbmdbXSB7MTAwMDAsIDExLCAxMn07CisgICAgbm9uUGFja2VkLnNpbnQzMlMgPSBuZXcgaW50W10gezEzMDAwLCAxNCwgMTV9OworICAgIG5vblBhY2tlZC5zaW50NjRTID0gbmV3IGxvbmdbXSB7MTYwMDAsIDE3LCAxOH07CisgICAgbm9uUGFja2VkLmZpeGVkMzJTID0gbmV3IGludFtdIHsxOSwgMjAsIDIxfTsKKyAgICBub25QYWNrZWQuZml4ZWQ2NFMgPSBuZXcgbG9uZ1tdIHsyMiwgMjMsIDI0fTsKKyAgICBub25QYWNrZWQuc2ZpeGVkMzJTID0gbmV3IGludFtdIHsyNSwgMjYsIDI3fTsKKyAgICBub25QYWNrZWQuc2ZpeGVkNjRTID0gbmV3IGxvbmdbXSB7MjgsIDI5LCAzMH07CisgICAgbm9uUGFja2VkLmZsb2F0cyA9IG5ldyBmbG9hdFtdIHszMSwgMzIsIDMzfTsKKyAgICBub25QYWNrZWQuZG91YmxlcyA9IG5ldyBkb3VibGVbXSB7MzQsIDM1LCAzNn07CisgICAgbm9uUGFja2VkLmJvb2xzID0gbmV3IGJvb2xlYW5bXSB7ZmFsc2UsIHRydWV9OworICAgIG5vblBhY2tlZC5lbnVtcyA9IG5ldyBpbnRbXSB7CisgICAgICBOYW5vUmVwZWF0ZWRQYWNrYWJsZXMuRW51bS5PUFRJT05fT05FLAorICAgICAgTmFub1JlcGVhdGVkUGFja2FibGVzLkVudW0uT1BUSU9OX1RXTywKKyAgICB9OworICAgIG5vblBhY2tlZC5ub2lzZSA9IDEzNTc5OworCisgICAgYnl0ZVtdIG5vblBhY2tlZFNlcmlhbGl6ZWQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShub25QYWNrZWQpOworCisgICAgTmFub1JlcGVhdGVkUGFja2FibGVzLlBhY2tlZCBwYWNrZWQgPQorICAgICAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20obmV3IE5hbm9SZXBlYXRlZFBhY2thYmxlcy5QYWNrZWQoKSwgbm9uUGFja2VkU2VyaWFsaXplZCk7CisgICAgYXNzZXJ0UmVwZWF0ZWRQYWNrYWJsZXNFcXVhbChub25QYWNrZWQsIHBhY2tlZCk7CisKKyAgICBieXRlW10gcGFja2VkU2VyaWFsaXplZCA9IE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KHBhY2tlZCk7CisgICAgLy8gSnVzdCBhIGNhdXRpb3VzIGNoZWNrIHRoYXQgdGhlIHR3byBzZXJpYWxpemVkIGZvcm1zIGFyZSBkaWZmZXJlbnQsCisgICAgLy8gdG8gbWFrZSBzdXJlIHRoZSByZW1haW5pbmcgb2YgdGhpcyB0ZXN0IGlzIHVzZWZ1bDoKKyAgICBhc3NlcnRGYWxzZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZFNlcmlhbGl6ZWQsIHBhY2tlZFNlcmlhbGl6ZWQpKTsKKworICAgIG5vblBhY2tlZCA9IE1lc3NhZ2VOYW5vLm1lcmdlRnJvbShuZXcgTmFub1JlcGVhdGVkUGFja2FibGVzLk5vblBhY2tlZCgpLCBwYWNrZWRTZXJpYWxpemVkKTsKKyAgICBhc3NlcnRSZXBlYXRlZFBhY2thYmxlc0VxdWFsKG5vblBhY2tlZCwgcGFja2VkKTsKKworICAgIC8vIFRlc3QgbWl4ZWQgc2VyaWFsaXplZCBmb3JtLgorICAgIGJ5dGVbXSBtaXhlZFNlcmlhbGl6ZWQgPSBuZXcgYnl0ZVtub25QYWNrZWRTZXJpYWxpemVkLmxlbmd0aCArIHBhY2tlZFNlcmlhbGl6ZWQubGVuZ3RoXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KG5vblBhY2tlZFNlcmlhbGl6ZWQsIDAsIG1peGVkU2VyaWFsaXplZCwgMCwgbm9uUGFja2VkU2VyaWFsaXplZC5sZW5ndGgpOworICAgIFN5c3RlbS5hcnJheWNvcHkocGFja2VkU2VyaWFsaXplZCwgMCwKKyAgICAgICAgbWl4ZWRTZXJpYWxpemVkLCBub25QYWNrZWRTZXJpYWxpemVkLmxlbmd0aCwgcGFja2VkU2VyaWFsaXplZC5sZW5ndGgpOworCisgICAgbm9uUGFja2VkID0gTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBOYW5vUmVwZWF0ZWRQYWNrYWJsZXMuTm9uUGFja2VkKCksIG1peGVkU2VyaWFsaXplZCk7CisgICAgcGFja2VkID0gTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKG5ldyBOYW5vUmVwZWF0ZWRQYWNrYWJsZXMuUGFja2VkKCksIG1peGVkU2VyaWFsaXplZCk7CisgICAgYXNzZXJ0UmVwZWF0ZWRQYWNrYWJsZXNFcXVhbChub25QYWNrZWQsIHBhY2tlZCk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBpbnRbXSB7MTAwMCwgMiwgMywgMTAwMCwgMiwgM30sIG5vblBhY2tlZC5pbnQzMlMpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobmV3IGludFtdIHsxMzAwMCwgMTQsIDE1LCAxMzAwMCwgMTQsIDE1fSwgbm9uUGFja2VkLnNpbnQzMlMpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobmV3IGludFtdIHsyNSwgMjYsIDI3LCAyNSwgMjYsIDI3fSwgbm9uUGFja2VkLnNmaXhlZDMyUykpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhuZXcgYm9vbGVhbltdIHtmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWV9LCBub25QYWNrZWQuYm9vbHMpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNYXBzU2VyaWFsaXplQW5kUGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwIG9yaWdpbiA9IG5ldyBUZXN0TWFwKCk7CisgICAgc2V0TWFwTWVzc2FnZShvcmlnaW4pOworICAgIGFzc2VydE1hcE1lc3NhZ2VTZXQob3JpZ2luKTsKKworICAgIGJ5dGVbXSBvdXRwdXQgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShvcmlnaW4pOworICAgIFRlc3RNYXAgcGFyc2VkID0gbmV3IFRlc3RNYXAoKTsKKyAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20ocGFyc2VkLCBvdXRwdXQpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1hcFNlcmlhbGl6ZVJlamVjdE51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0TWFwIHByaW1pdGl2ZU1hcCA9IG5ldyBUZXN0TWFwKCk7CisgICAgcHJpbWl0aXZlTWFwLmludDMyVG9JbnQzMkZpZWxkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICBwcmltaXRpdmVNYXAuaW50MzJUb0ludDMyRmllbGQucHV0KG51bGwsIDEpOworICAgIHRyeSB7CisgICAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShwcmltaXRpdmVNYXApOworICAgICAgZmFpbCgic2hvdWxkIHJlamVjdCBudWxsIGtleXMiKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgLy8gcGFzcy4KKyAgICB9CisKKyAgICBUZXN0TWFwIG1lc3NhZ2VNYXAgPSBuZXcgVGVzdE1hcCgpOworICAgIG1lc3NhZ2VNYXAuaW50MzJUb01lc3NhZ2VGaWVsZCA9CisgICAgICAgIG5ldyBIYXNoTWFwPEludGVnZXIsIE1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4oKTsKKyAgICBtZXNzYWdlTWFwLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDAsIG51bGwpOworICAgIHRyeSB7CisgICAgICBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlTWFwKTsKKyAgICAgIGZhaWwoInNob3VsZCByZWplY3QgbnVsbCB2YWx1ZXMiKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgLy8gcGFzcy4KKyAgICB9CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCBtZXJnaW5nIGJ5dGVzIGNvbnRhaW5pbmcgY29uZmxpY3Rpbmcga2V5cyB3aXRoIG92ZXJyaWRlIHRoZQorICAgKiBtZXNzYWdlIHZhbHVlIGluc3RlYWQgb2YgbWVyZ2luZyB0aGUgbWVzc2FnZSB2YWx1ZSBpbnRvIHRoZSBleGlzdGluZyBlbnRyeS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RNYXBNZXJnZU92ZXJyaWRlTWVzc2FnZVZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RNYXAuTWVzc2FnZVZhbHVlIG9yaWdWYWx1ZSA9IG5ldyBUZXN0TWFwLk1lc3NhZ2VWYWx1ZSgpOworICAgIG9yaWdWYWx1ZS52YWx1ZSA9IDE7CisgICAgb3JpZ1ZhbHVlLnZhbHVlMiA9IDI7CisgICAgVGVzdE1hcC5NZXNzYWdlVmFsdWUgbmV3VmFsdWUgPSBuZXcgVGVzdE1hcC5NZXNzYWdlVmFsdWUoKTsKKyAgICBuZXdWYWx1ZS52YWx1ZSA9IDM7CisKKyAgICBUZXN0TWFwIG9yaWdNZXNzYWdlID0gbmV3IFRlc3RNYXAoKTsKKyAgICBvcmlnTWVzc2FnZS5pbnQzMlRvTWVzc2FnZUZpZWxkID0KKyAgICAgICAgbmV3IEhhc2hNYXA8SW50ZWdlciwgTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPigpOworICAgIG9yaWdNZXNzYWdlLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDEsIG9yaWdWYWx1ZSk7CisKKyAgICBUZXN0TWFwIG5ld01lc3NhZ2UgPSBuZXcgVGVzdE1hcCgpOworICAgIG5ld01lc3NhZ2UuaW50MzJUb01lc3NhZ2VGaWVsZCA9CisgICAgICAgIG5ldyBIYXNoTWFwPEludGVnZXIsIE1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4oKTsKKyAgICBuZXdNZXNzYWdlLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDEsIG5ld1ZhbHVlKTsKKyAgICBNZXNzYWdlTmFuby5tZXJnZUZyb20ob3JpZ01lc3NhZ2UsCisgICAgICAgIE1lc3NhZ2VOYW5vLnRvQnl0ZUFycmF5KG5ld01lc3NhZ2UpKTsKKyAgICBUZXN0TWFwLk1lc3NhZ2VWYWx1ZSBtZXJnZWRWYWx1ZSA9IG9yaWdNZXNzYWdlLmludDMyVG9NZXNzYWdlRmllbGQuZ2V0KDEpOworICAgIGFzc2VydEVxdWFscygzLCBtZXJnZWRWYWx1ZS52YWx1ZSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lcmdlZFZhbHVlLnZhbHVlMik7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhhdCB3aGVuIG1lcmdpbmcgd2l0aCBlbXB0eSBlbnRyaWVzLAorICAgKiB3ZSB3aWxsIHVzZSBkZWZhdWx0IGZvciB0aGUga2V5IGFuZCB2YWx1ZSwgaW5zdGVhZCBvZiBudWxsLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE1hcE1lcmdlRW1wdHlFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RNYXAgdGVzdE1hcCA9IG5ldyBUZXN0TWFwKCk7CisgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzEwMjRdOworICAgIENvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm8gb3V0cHV0ID0KKyAgICAgICAgQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFuby5uZXdJbnN0YW5jZShidWZmZXIpOworICAgIC8vIEFuIGVtcHR5IGVudHJ5IGZvciBpbnQzMl90b19pbnQzMiBtYXAuCisgICAgb3V0cHV0LndyaXRlVGFnKDEsIFdpcmVGb3JtYXROYW5vLldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKDApOworICAgIC8vIEFuIGVtcHR5IGVudHJ5IGZvciBpbnQzMl90b19tZXNzYWdlIG1hcC4KKyAgICBvdXRwdXQud3JpdGVUYWcoNSwgV2lyZUZvcm1hdE5hbm8uV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoMCk7CisKKyAgICBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8gaW5wdXQgPSBDb2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8ubmV3SW5zdGFuY2UoCisgICAgICAgIGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIG91dHB1dC5zcGFjZUxlZnQoKSk7CisgICAgdGVzdE1hcC5tZXJnZUZyb20oaW5wdXQpOworICAgIGFzc2VydE5vdE51bGwodGVzdE1hcC5pbnQzMlRvSW50MzJGaWVsZCk7OworICAgIGFzc2VydEVxdWFscygxLCB0ZXN0TWFwLmludDMyVG9JbnQzMkZpZWxkLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIudmFsdWVPZigwKSwgdGVzdE1hcC5pbnQzMlRvSW50MzJGaWVsZC5nZXQoMCkpOworICAgIGFzc2VydE5vdE51bGwodGVzdE1hcC5pbnQzMlRvTWVzc2FnZUZpZWxkKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgdGVzdE1hcC5pbnQzMlRvTWVzc2FnZUZpZWxkLnNpemUoKSk7CisgICAgVGVzdE1hcC5NZXNzYWdlVmFsdWUgbWVzc2FnZVZhbHVlID0gdGVzdE1hcC5pbnQzMlRvTWVzc2FnZUZpZWxkLmdldCgwKTsKKyAgICBhc3NlcnROb3ROdWxsKG1lc3NhZ2VWYWx1ZSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2VWYWx1ZS52YWx1ZSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIG1lc3NhZ2VWYWx1ZS52YWx1ZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdE1hcEVxdWFscygpIHRocm93cyBFeGNlcHRpb24geworICAgIFRlc3RNYXAgYSA9IG5ldyBUZXN0TWFwKCk7CisgICAgVGVzdE1hcCBiID0gbmV3IFRlc3RNYXAoKTsKKworICAgIC8vIGVtcHR5IGFuZCBudWxsIG1hcCBmaWVsZHMgYXJlIGVxdWFsLgorICAgIGFzc2VydFRlc3RNYXBFcXVhbChhLCBiKTsKKyAgICBhLmludDMyVG9CeXRlc0ZpZWxkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgYnl0ZVtdPigpOworICAgIGFzc2VydFRlc3RNYXBFcXVhbChhLCBiKTsKKworICAgIGEuaW50MzJUb0ludDMyRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgIGIuaW50MzJUb0ludDMyRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgIHNldE1hcChhLmludDMyVG9JbnQzMkZpZWxkLCBkZWVwQ29weShpbnQzMlZhbHVlcyksIGRlZXBDb3B5KGludDMyVmFsdWVzKSk7CisgICAgc2V0TWFwKGIuaW50MzJUb0ludDMyRmllbGQsIGRlZXBDb3B5KGludDMyVmFsdWVzKSwgZGVlcENvcHkoaW50MzJWYWx1ZXMpKTsKKyAgICBhc3NlcnRUZXN0TWFwRXF1YWwoYSwgYik7CisKKyAgICBhLmludDMyVG9NZXNzYWdlRmllbGQgPQorICAgICAgICBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBNYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+KCk7CisgICAgYi5pbnQzMlRvTWVzc2FnZUZpZWxkID0KKyAgICAgICAgbmV3IEhhc2hNYXA8SW50ZWdlciwgTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPigpOworICAgIHNldE1hcChhLmludDMyVG9NZXNzYWdlRmllbGQsCisgICAgICAgIGRlZXBDb3B5KGludDMyVmFsdWVzKSwgZGVlcENvcHkobWVzc2FnZVZhbHVlcykpOworICAgIHNldE1hcChiLmludDMyVG9NZXNzYWdlRmllbGQsCisgICAgICAgIGRlZXBDb3B5KGludDMyVmFsdWVzKSwgZGVlcENvcHkobWVzc2FnZVZhbHVlcykpOworICAgIGFzc2VydFRlc3RNYXBFcXVhbChhLCBiKTsKKworICAgIGEuc3RyaW5nVG9JbnQzMkZpZWxkID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBJbnRlZ2VyPigpOworICAgIGIuc3RyaW5nVG9JbnQzMkZpZWxkID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBJbnRlZ2VyPigpOworICAgIHNldE1hcChhLnN0cmluZ1RvSW50MzJGaWVsZCwgZGVlcENvcHkoc3RyaW5nVmFsdWVzKSwgZGVlcENvcHkoaW50MzJWYWx1ZXMpKTsKKyAgICBzZXRNYXAoYi5zdHJpbmdUb0ludDMyRmllbGQsIGRlZXBDb3B5KHN0cmluZ1ZhbHVlcyksIGRlZXBDb3B5KGludDMyVmFsdWVzKSk7CisgICAgYXNzZXJ0VGVzdE1hcEVxdWFsKGEsIGIpOworCisgICAgYS5pbnQzMlRvQnl0ZXNGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIGJ5dGVbXT4oKTsKKyAgICBiLmludDMyVG9CeXRlc0ZpZWxkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgYnl0ZVtdPigpOworICAgIHNldE1hcChhLmludDMyVG9CeXRlc0ZpZWxkLCBkZWVwQ29weShpbnQzMlZhbHVlcyksIGRlZXBDb3B5KGJ5dGVzVmFsdWVzKSk7CisgICAgc2V0TWFwKGIuaW50MzJUb0J5dGVzRmllbGQsIGRlZXBDb3B5KGludDMyVmFsdWVzKSwgZGVlcENvcHkoYnl0ZXNWYWx1ZXMpKTsKKyAgICBhc3NlcnRUZXN0TWFwRXF1YWwoYSwgYik7CisKKyAgICAvLyBNYWtlIHN1cmUgdGhlIG1hcCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBtYXR0ZXIuCisgICAgYS5pbnQzMlRvU3RyaW5nRmllbGQgPSBuZXcgVHJlZU1hcDxJbnRlZ2VyLCBTdHJpbmc+KCk7CisgICAgYi5pbnQzMlRvU3RyaW5nRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+KCk7CisgICAgc2V0TWFwKGEuaW50MzJUb1N0cmluZ0ZpZWxkLCBkZWVwQ29weShpbnQzMlZhbHVlcyksIGRlZXBDb3B5KHN0cmluZ1ZhbHVlcykpOworICAgIHNldE1hcChiLmludDMyVG9TdHJpbmdGaWVsZCwgZGVlcENvcHkoaW50MzJWYWx1ZXMpLCBkZWVwQ29weShzdHJpbmdWYWx1ZXMpKTsKKyAgICBhc3NlcnRUZXN0TWFwRXF1YWwoYSwgYik7CisKKyAgICBhLmNsZWFyKCk7CisgICAgYi5jbGVhcigpOworCisgICAgLy8gdW5lcXVhbCBjYXNlczogZGlmZmVyZW50IHZhbHVlCisgICAgYS5pbnQzMlRvSW50MzJGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+KCk7CisgICAgYi5pbnQzMlRvSW50MzJGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+KCk7CisgICAgYS5pbnQzMlRvSW50MzJGaWVsZC5wdXQoMSwgMSk7CisgICAgYi5pbnQzMlRvSW50MzJGaWVsZC5wdXQoMSwgMik7CisgICAgYXNzZXJ0VGVzdE1hcFVuZXF1YWwoYSwgYik7CisgICAgLy8gdW5lcXVhbCBjYXNlOiBhZGRpdGlvbmFsIGVudHJ5CisgICAgYi5pbnQzMlRvSW50MzJGaWVsZC5wdXQoMSwgMSk7CisgICAgYi5pbnQzMlRvSW50MzJGaWVsZC5wdXQoMiwgMSk7CisgICAgYXNzZXJ0VGVzdE1hcFVuZXF1YWwoYSwgYik7CisgICAgYS5pbnQzMlRvSW50MzJGaWVsZC5wdXQoMiwgMSk7CisgICAgYXNzZXJ0VGVzdE1hcEVxdWFsKGEsIGIpOworCisgICAgLy8gdW5lcXVhbCBjYXNlOiBkaWZmZXJlbnQgbWVzc2FnZSB2YWx1ZS4KKyAgICBhLmludDMyVG9NZXNzYWdlRmllbGQgPQorICAgICAgICBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBNYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+KCk7CisgICAgYi5pbnQzMlRvTWVzc2FnZUZpZWxkID0KKyAgICAgICAgbmV3IEhhc2hNYXA8SW50ZWdlciwgTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPigpOworICAgIE1lc3NhZ2VWYWx1ZSB2YSA9IG5ldyBNZXNzYWdlVmFsdWUoKTsKKyAgICB2YS52YWx1ZSA9IDE7CisgICAgTWVzc2FnZVZhbHVlIHZiID0gbmV3IE1lc3NhZ2VWYWx1ZSgpOworICAgIHZiLnZhbHVlID0gMTsKKyAgICBhLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDEsIHZhKTsKKyAgICBiLmludDMyVG9NZXNzYWdlRmllbGQucHV0KDEsIHZiKTsKKyAgICBhc3NlcnRUZXN0TWFwRXF1YWwoYSwgYik7CisgICAgdmIudmFsdWUgPSAyOworICAgIGFzc2VydFRlc3RNYXBVbmVxdWFsKGEsIGIpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRUZXN0TWFwRXF1YWwoVGVzdE1hcCBhLCBUZXN0TWFwIGIpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRFcXVhbHMoYS5oYXNoQ29kZSgpLCBiLmhhc2hDb2RlKCkpOworICAgIGFzc2VydFRydWUoYS5lcXVhbHMoYikpOworICAgIGFzc2VydFRydWUoYi5lcXVhbHMoYSkpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRUZXN0TWFwVW5lcXVhbChUZXN0TWFwIGEsIFRlc3RNYXAgYikKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEZhbHNlKGEuZXF1YWxzKGIpKTsKKyAgICBhc3NlcnRGYWxzZShiLmVxdWFscyhhKSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnRlZ2VyW10gaW50MzJWYWx1ZXMgPSBuZXcgSW50ZWdlcltdIHsKKyAgICAwLCAxLCAtMSwgSW50ZWdlci5NQVhfVkFMVUUsIEludGVnZXIuTUlOX1ZBTFVFLAorICB9OworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvbmdbXSBpbnQ2NFZhbHVlcyA9IG5ldyBMb25nW10geworICAgIDBMLCAxTCwgLTFMLCBMb25nLk1BWF9WQUxVRSwgTG9uZy5NSU5fVkFMVUUsCisgIH07CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gc3RyaW5nVmFsdWVzID0gbmV3IFN0cmluZ1tdIHsKKyAgICAiIiwgImhlbGxvIiwgIndvcmxkIiwgImZvbyIsICJiYXIiLAorICB9OworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXVtdIGJ5dGVzVmFsdWVzID0gbmV3IGJ5dGVbXVtdIHsKKyAgICBuZXcgYnl0ZVtdIHt9LAorICAgIG5ldyBieXRlW10gezB9LAorICAgIG5ldyBieXRlW10gezEsIC0xfSwKKyAgICBuZXcgYnl0ZVtdIHsxMjcsIC0xMjh9LAorICAgIG5ldyBieXRlW10geydhJywgJ2InLCAnMCcsICcxJ30sCisgIH07CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIGJvb2xWYWx1ZXMgPSBuZXcgQm9vbGVhbltdIHsKKyAgICBmYWxzZSwgdHJ1ZSwKKyAgfTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnRlZ2VyW10gZW51bVZhbHVlcyA9IG5ldyBJbnRlZ2VyW10geworICAgIFRlc3RNYXAuRk9PLCBUZXN0TWFwLkJBUiwgVGVzdE1hcC5CQVosIFRlc3RNYXAuUVVYLAorICAgIEludGVnZXIuTUFYX1ZBTFVFIC8qIHVua25vd24gKi8sCisgIH07CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGVzdE1hcC5NZXNzYWdlVmFsdWVbXSBtZXNzYWdlVmFsdWVzID0KKyAgICAgIG5ldyBUZXN0TWFwLk1lc3NhZ2VWYWx1ZVtdIHsKKyAgICBuZXdNYXBWYWx1ZU1lc3NhZ2UoMCksCisgICAgbmV3TWFwVmFsdWVNZXNzYWdlKDEpLAorICAgIG5ld01hcFZhbHVlTWVzc2FnZSgtMSksCisgICAgbmV3TWFwVmFsdWVNZXNzYWdlKEludGVnZXIuTUFYX1ZBTFVFKSwKKyAgICBuZXdNYXBWYWx1ZU1lc3NhZ2UoSW50ZWdlci5NSU5fVkFMVUUpLAorICB9OworCisgIHByaXZhdGUgc3RhdGljIFRlc3RNYXAuTWVzc2FnZVZhbHVlIG5ld01hcFZhbHVlTWVzc2FnZShpbnQgdmFsdWUpIHsKKyAgICBUZXN0TWFwLk1lc3NhZ2VWYWx1ZSByZXN1bHQgPSBuZXcgVGVzdE1hcC5NZXNzYWdlVmFsdWUoKTsKKyAgICByZXN1bHQudmFsdWUgPSB2YWx1ZTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHByaXZhdGUgc3RhdGljIDxUPiBUW10gZGVlcENvcHkoVFtdIG9yaWcpIHRocm93cyBFeGNlcHRpb24geworICAgIGlmIChvcmlnIGluc3RhbmNlb2YgTWVzc2FnZVZhbHVlW10pIHsKKyAgICAgIE1lc3NhZ2VWYWx1ZVtdIHJlc3VsdCA9IG5ldyBNZXNzYWdlVmFsdWVbb3JpZy5sZW5ndGhdOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcmlnLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIHJlc3VsdFtpXSA9IG5ldyBNZXNzYWdlVmFsdWUoKTsKKyAgICAgICAgTWVzc2FnZU5hbm8ubWVyZ2VGcm9tKAorICAgICAgICAgICAgcmVzdWx0W2ldLCBNZXNzYWdlTmFuby50b0J5dGVBcnJheSgoTWVzc2FnZVZhbHVlKSBvcmlnW2ldKSk7CisgICAgICB9CisgICAgICByZXR1cm4gKFRbXSkgcmVzdWx0OworICAgIH0KKyAgICBpZiAob3JpZyBpbnN0YW5jZW9mIGJ5dGVbXVtdKSB7CisgICAgICBieXRlW11bXSByZXN1bHQgPSBuZXcgYnl0ZVtvcmlnLmxlbmd0aF1bXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb3JpZy5sZW5ndGg7IGkrKykgeworICAgICAgICBieXRlW10gb3JpZ0J5dGVzID0gKGJ5dGVbXSkgb3JpZ1tpXTsKKyAgICAgICAgcmVzdWx0W2ldID0gQXJyYXlzLmNvcHlPZihvcmlnQnl0ZXMsIG9yaWdCeXRlcy5sZW5ndGgpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gQXJyYXlzLmNvcHlPZihvcmlnLCBvcmlnLmxlbmd0aCk7CisgIH0KKworICBwcml2YXRlIDxLLCBWPiB2b2lkIHNldE1hcChNYXA8SywgVj4gbWFwLCBLW10ga2V5cywgVltdIHZhbHVlcykgeworICAgIGFzc2VydChrZXlzLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIG1hcC5wdXQoa2V5c1tpXSwgdmFsdWVzW2ldKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIDxLLCBWPiB2b2lkIGFzc2VydE1hcFNldCgKKyAgICAgIE1hcDxLLCBWPiBtYXAsIEtbXSBrZXlzLCBWW10gdmFsdWVzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnQoa2V5cy5sZW5ndGggPT0gdmFsdWVzLmxlbmd0aCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIGFzc2VydEVxdWFscyh2YWx1ZXNbaV0sIG1hcC5nZXQoa2V5c1tpXSkpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoa2V5cy5sZW5ndGgsIG1hcC5zaXplKCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNldE1hcE1lc3NhZ2UoVGVzdE1hcCB0ZXN0TWFwKSB7CisgICAgdGVzdE1hcC5pbnQzMlRvSW50MzJGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+KCk7CisgICAgdGVzdE1hcC5pbnQzMlRvQnl0ZXNGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIGJ5dGVbXT4oKTsKKyAgICB0ZXN0TWFwLmludDMyVG9FbnVtRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgIHRlc3RNYXAuaW50MzJUb01lc3NhZ2VGaWVsZCA9CisgICAgICAgIG5ldyBIYXNoTWFwPEludGVnZXIsIE1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4oKTsKKyAgICB0ZXN0TWFwLmludDMyVG9TdHJpbmdGaWVsZCA9IG5ldyBIYXNoTWFwPEludGVnZXIsIFN0cmluZz4oKTsKKyAgICB0ZXN0TWFwLnN0cmluZ1RvSW50MzJGaWVsZCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKyAgICB0ZXN0TWFwLmJvb2xUb0Jvb2xGaWVsZCA9IG5ldyBIYXNoTWFwPEJvb2xlYW4sIEJvb2xlYW4+KCk7CisgICAgdGVzdE1hcC51aW50MzJUb1VpbnQzMkZpZWxkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICB0ZXN0TWFwLnNpbnQzMlRvU2ludDMyRmllbGQgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgIHRlc3RNYXAuZml4ZWQzMlRvRml4ZWQzMkZpZWxkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICB0ZXN0TWFwLnNmaXhlZDMyVG9TZml4ZWQzMkZpZWxkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICB0ZXN0TWFwLmludDY0VG9JbnQ2NEZpZWxkID0gbmV3IEhhc2hNYXA8TG9uZywgTG9uZz4oKTsKKyAgICB0ZXN0TWFwLnVpbnQ2NFRvVWludDY0RmllbGQgPSBuZXcgSGFzaE1hcDxMb25nLCBMb25nPigpOworICAgIHRlc3RNYXAuc2ludDY0VG9TaW50NjRGaWVsZCA9IG5ldyBIYXNoTWFwPExvbmcsIExvbmc+KCk7CisgICAgdGVzdE1hcC5maXhlZDY0VG9GaXhlZDY0RmllbGQgPSBuZXcgSGFzaE1hcDxMb25nLCBMb25nPigpOworICAgIHRlc3RNYXAuc2ZpeGVkNjRUb1NmaXhlZDY0RmllbGQgPSBuZXcgSGFzaE1hcDxMb25nLCBMb25nPigpOworICAgIHNldE1hcCh0ZXN0TWFwLmludDMyVG9JbnQzMkZpZWxkLCBpbnQzMlZhbHVlcywgaW50MzJWYWx1ZXMpOworICAgIHNldE1hcCh0ZXN0TWFwLmludDMyVG9CeXRlc0ZpZWxkLCBpbnQzMlZhbHVlcywgYnl0ZXNWYWx1ZXMpOworICAgIHNldE1hcCh0ZXN0TWFwLmludDMyVG9FbnVtRmllbGQsIGludDMyVmFsdWVzLCBlbnVtVmFsdWVzKTsKKyAgICBzZXRNYXAodGVzdE1hcC5pbnQzMlRvTWVzc2FnZUZpZWxkLCBpbnQzMlZhbHVlcywgbWVzc2FnZVZhbHVlcyk7CisgICAgc2V0TWFwKHRlc3RNYXAuaW50MzJUb1N0cmluZ0ZpZWxkLCBpbnQzMlZhbHVlcywgc3RyaW5nVmFsdWVzKTsKKyAgICBzZXRNYXAodGVzdE1hcC5zdHJpbmdUb0ludDMyRmllbGQsIHN0cmluZ1ZhbHVlcywgaW50MzJWYWx1ZXMpOworICAgIHNldE1hcCh0ZXN0TWFwLmJvb2xUb0Jvb2xGaWVsZCwgYm9vbFZhbHVlcywgYm9vbFZhbHVlcyk7CisgICAgc2V0TWFwKHRlc3RNYXAudWludDMyVG9VaW50MzJGaWVsZCwgaW50MzJWYWx1ZXMsIGludDMyVmFsdWVzKTsKKyAgICBzZXRNYXAodGVzdE1hcC5zaW50MzJUb1NpbnQzMkZpZWxkLCBpbnQzMlZhbHVlcywgaW50MzJWYWx1ZXMpOworICAgIHNldE1hcCh0ZXN0TWFwLmZpeGVkMzJUb0ZpeGVkMzJGaWVsZCwgaW50MzJWYWx1ZXMsIGludDMyVmFsdWVzKTsKKyAgICBzZXRNYXAodGVzdE1hcC5zZml4ZWQzMlRvU2ZpeGVkMzJGaWVsZCwgaW50MzJWYWx1ZXMsIGludDMyVmFsdWVzKTsKKyAgICBzZXRNYXAodGVzdE1hcC5pbnQ2NFRvSW50NjRGaWVsZCwgaW50NjRWYWx1ZXMsIGludDY0VmFsdWVzKTsKKyAgICBzZXRNYXAodGVzdE1hcC51aW50NjRUb1VpbnQ2NEZpZWxkLCBpbnQ2NFZhbHVlcywgaW50NjRWYWx1ZXMpOworICAgIHNldE1hcCh0ZXN0TWFwLnNpbnQ2NFRvU2ludDY0RmllbGQsIGludDY0VmFsdWVzLCBpbnQ2NFZhbHVlcyk7CisgICAgc2V0TWFwKHRlc3RNYXAuZml4ZWQ2NFRvRml4ZWQ2NEZpZWxkLCBpbnQ2NFZhbHVlcywgaW50NjRWYWx1ZXMpOworICAgIHNldE1hcCh0ZXN0TWFwLnNmaXhlZDY0VG9TZml4ZWQ2NEZpZWxkLCBpbnQ2NFZhbHVlcywgaW50NjRWYWx1ZXMpOworICB9CisgIHByaXZhdGUgdm9pZCBhc3NlcnRNYXBNZXNzYWdlU2V0KFRlc3RNYXAgdGVzdE1hcCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuaW50MzJUb0ludDMyRmllbGQsIGludDMyVmFsdWVzLCBpbnQzMlZhbHVlcyk7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuaW50MzJUb0J5dGVzRmllbGQsIGludDMyVmFsdWVzLCBieXRlc1ZhbHVlcyk7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuaW50MzJUb0VudW1GaWVsZCwgaW50MzJWYWx1ZXMsIGVudW1WYWx1ZXMpOworICAgIGFzc2VydE1hcFNldCh0ZXN0TWFwLmludDMyVG9NZXNzYWdlRmllbGQsIGludDMyVmFsdWVzLCBtZXNzYWdlVmFsdWVzKTsKKyAgICBhc3NlcnRNYXBTZXQodGVzdE1hcC5pbnQzMlRvU3RyaW5nRmllbGQsIGludDMyVmFsdWVzLCBzdHJpbmdWYWx1ZXMpOworICAgIGFzc2VydE1hcFNldCh0ZXN0TWFwLnN0cmluZ1RvSW50MzJGaWVsZCwgc3RyaW5nVmFsdWVzLCBpbnQzMlZhbHVlcyk7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuYm9vbFRvQm9vbEZpZWxkLCBib29sVmFsdWVzLCBib29sVmFsdWVzKTsKKyAgICBhc3NlcnRNYXBTZXQodGVzdE1hcC51aW50MzJUb1VpbnQzMkZpZWxkLCBpbnQzMlZhbHVlcywgaW50MzJWYWx1ZXMpOworICAgIGFzc2VydE1hcFNldCh0ZXN0TWFwLnNpbnQzMlRvU2ludDMyRmllbGQsIGludDMyVmFsdWVzLCBpbnQzMlZhbHVlcyk7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuZml4ZWQzMlRvRml4ZWQzMkZpZWxkLCBpbnQzMlZhbHVlcywgaW50MzJWYWx1ZXMpOworICAgIGFzc2VydE1hcFNldCh0ZXN0TWFwLnNmaXhlZDMyVG9TZml4ZWQzMkZpZWxkLCBpbnQzMlZhbHVlcywgaW50MzJWYWx1ZXMpOworICAgIGFzc2VydE1hcFNldCh0ZXN0TWFwLmludDY0VG9JbnQ2NEZpZWxkLCBpbnQ2NFZhbHVlcywgaW50NjRWYWx1ZXMpOworICAgIGFzc2VydE1hcFNldCh0ZXN0TWFwLnVpbnQ2NFRvVWludDY0RmllbGQsIGludDY0VmFsdWVzLCBpbnQ2NFZhbHVlcyk7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuc2ludDY0VG9TaW50NjRGaWVsZCwgaW50NjRWYWx1ZXMsIGludDY0VmFsdWVzKTsKKyAgICBhc3NlcnRNYXBTZXQodGVzdE1hcC5maXhlZDY0VG9GaXhlZDY0RmllbGQsIGludDY0VmFsdWVzLCBpbnQ2NFZhbHVlcyk7CisgICAgYXNzZXJ0TWFwU2V0KHRlc3RNYXAuc2ZpeGVkNjRUb1NmaXhlZDY0RmllbGQsIGludDY0VmFsdWVzLCBpbnQ2NFZhbHVlcyk7CisgIH0KKworICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVwZWF0ZWRQYWNrYWJsZXNFcXVhbCgKKyAgICAgIE5hbm9SZXBlYXRlZFBhY2thYmxlcy5Ob25QYWNrZWQgbm9uUGFja2VkLCBOYW5vUmVwZWF0ZWRQYWNrYWJsZXMuUGFja2VkIHBhY2tlZCkgeworICAgIC8vIE5vdCB1c2luZyBNZXNzYWdlTmFuby5lcXVhbHMoKSAtLSB0aGF0IGJlbG9uZ3MgdG8gYSBzZXBhcmF0ZSB0ZXN0LgorICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhub25QYWNrZWQuaW50MzJTLCBwYWNrZWQuaW50MzJTKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZC5pbnQ2NFMsIHBhY2tlZC5pbnQ2NFMpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobm9uUGFja2VkLnVpbnQzMlMsIHBhY2tlZC51aW50MzJTKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZC51aW50NjRTLCBwYWNrZWQudWludDY0UykpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhub25QYWNrZWQuc2ludDMyUywgcGFja2VkLnNpbnQzMlMpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobm9uUGFja2VkLnNpbnQ2NFMsIHBhY2tlZC5zaW50NjRTKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZC5maXhlZDMyUywgcGFja2VkLmZpeGVkMzJTKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZC5maXhlZDY0UywgcGFja2VkLmZpeGVkNjRTKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZC5zZml4ZWQzMlMsIHBhY2tlZC5zZml4ZWQzMlMpKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobm9uUGFja2VkLnNmaXhlZDY0UywgcGFja2VkLnNmaXhlZDY0UykpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhub25QYWNrZWQuZmxvYXRzLCBwYWNrZWQuZmxvYXRzKSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5vblBhY2tlZC5kb3VibGVzLCBwYWNrZWQuZG91YmxlcykpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhub25QYWNrZWQuYm9vbHMsIHBhY2tlZC5ib29scykpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhub25QYWNrZWQuZW51bXMsIHBhY2tlZC5lbnVtcykpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydEhhc1dpcmVEYXRhKE1lc3NhZ2VOYW5vIG1lc3NhZ2UsIGJvb2xlYW4gZXhwZWN0ZWQpIHsKKyAgICBieXRlW10gYnl0ZXMgPSBNZXNzYWdlTmFuby50b0J5dGVBcnJheShtZXNzYWdlKTsKKyAgICBpbnQgd2lyZUxlbmd0aCA9IGJ5dGVzLmxlbmd0aDsKKyAgICBpZiAoZXhwZWN0ZWQpIHsKKyAgICAgIGFzc2VydEZhbHNlKHdpcmVMZW5ndGggPT0gMCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmICh3aXJlTGVuZ3RoICE9IDApIHsKKyAgICAgICAgZmFpbCgiRXhwZWN0ZWQgbm8gd2lyZSBkYXRhIGZvciBtZXNzYWdlIFxuIiArIG1lc3NhZ2UKKyAgICAgICAgICAgICsgIlxuQnV0IGdvdDpcbiIKKyAgICAgICAgICAgICsgaGV4RHVtcChieXRlcykpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBoZXhEdW1wKGJ5dGVbXSBieXRlcykgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIGZvciAoYnl0ZSBiIDogYnl0ZXMpIHsKKyAgICAgIHNiLmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlMDJ4ICIsIGIpKTsKKyAgICB9CisgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL21hcF90ZXN0LnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vbWFwX3Rlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjcyODMzYQotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL21hcF90ZXN0LnByb3RvCkBAIC0wLDAgKzEsNzAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBtYXBfdGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk1hcFRlc3RQcm90byI7CisKK21lc3NhZ2UgVGVzdE1hcCB7CisgIG1lc3NhZ2UgTWVzc2FnZVZhbHVlIHsKKyAgICBpbnQzMiB2YWx1ZSA9IDE7CisgICAgaW50MzIgdmFsdWUyID0gMjsKKyAgfQorICBlbnVtIEVudW1WYWx1ZSB7CisgICAgRk9PID0gMDsKKyAgICBCQVIgPSAxOworICAgIEJBWiA9IDI7CisgICAgUVVYID0gMzsKKyAgfQorCisgIG1hcDxpbnQzMiwgaW50MzI+ICAgICAgICBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7CisgIG1hcDxpbnQzMiwgc3RyaW5nPiAgICAgICBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOworICBtYXA8aW50MzIsIGJ5dGVzPiAgICAgICAgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOworICBtYXA8aW50MzIsIEVudW1WYWx1ZT4gICAgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7CisgIG1hcDxpbnQzMiwgTWVzc2FnZVZhbHVlPiBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTsKKyAgbWFwPHN0cmluZywgaW50MzI+ICAgICAgIHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7CisgIG1hcDxib29sLCBib29sPiAgICAgICAgICBib29sX3RvX2Jvb2xfZmllbGQgPSA3OworCisgIC8vIFRlc3QgYWxsIHRoZSBvdGhlciBwcmltaXRpdmUgdHlwZXMuIEFzIHRoZSBrZXkgYW5kIHZhbHVlIGFyZSBub3QgY291cGxlZCBpbgorICAvLyB0aGUgaW1wbGVtZW50YXRpb24sIHdlIGRvIG5vdCB0ZXN0IGFsbCB0aGUgY29tYmluYXRpb25zIG9mIGtleS92YWx1ZSBwYWlycywKKyAgLy8gc28gdGhhdCB3ZSBjYW4ga2VlcCB0aGUgbnVtYmVyIG9mIHRlc3QgY2FzZXMgbWFuYWdlYWJsZQorICBtYXA8dWludDMyLCB1aW50MzI+ICAgICAgdWludDMyX3RvX3VpbnQzMl9maWVsZCA9IDExOworICBtYXA8c2ludDMyLCBzaW50MzI+ICAgICAgc2ludDMyX3RvX3NpbnQzMl9maWVsZCA9IDEyOworICBtYXA8Zml4ZWQzMiwgZml4ZWQzMj4gICAgZml4ZWQzMl90b19maXhlZDMyX2ZpZWxkID0gMTM7CisgIG1hcDxzZml4ZWQzMiwgc2ZpeGVkMzI+ICBzZml4ZWQzMl90b19zZml4ZWQzMl9maWVsZCA9IDE0OworICBtYXA8aW50NjQsIGludDY0PiAgICAgICAgaW50NjRfdG9faW50NjRfZmllbGQgPSAxNTsKKyAgbWFwPHVpbnQ2NCwgdWludDY0PiAgICAgIHVpbnQ2NF90b191aW50NjRfZmllbGQgPSAxNjsKKyAgbWFwPHNpbnQ2NCwgc2ludDY0PiAgICAgIHNpbnQ2NF90b19zaW50NjRfZmllbGQgPSAxNzsKKyAgbWFwPGZpeGVkNjQsIGZpeGVkNjQ+ICAgIGZpeGVkNjRfdG9fZml4ZWQ2NF9maWVsZCA9IDE4OworICBtYXA8c2ZpeGVkNjQsIHNmaXhlZDY0PiAgc2ZpeGVkNjRfdG9fc2ZpeGVkNjRfZmllbGQgPSAxOTsKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2FjY2Vzc29yc19uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfYWNjZXNzb3JzX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU1YTQwZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2FjY2Vzc29yc19uYW5vLnByb3RvCkBAIC0wLDAgKzEsMTE4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBtYXh0cm95QGdvb2dsZS5jb20gKE1heCBDYWkpCisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJOYW5vQWNjZXNzb3JzT3V0ZXJDbGFzcyI7CisKK21lc3NhZ2UgVGVzdE5hbm9BY2Nlc3NvcnMgeworCisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgaW50MzIgYmIgPSAxOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAxOworICAgIEJBUiA9IDI7CisgICAgQkFaID0gMzsKKyAgfQorCisgIC8vIFNpbmd1bGFyCisgIG9wdGlvbmFsIGludDMyICBvcHRpb25hbF9pbnQzMiAgICA9ICAxOworICBvcHRpb25hbCBmbG9hdCAgb3B0aW9uYWxfZmxvYXQgICAgPSAxMTsKKyAgb3B0aW9uYWwgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgICA9IDE0OworICBvcHRpb25hbCBieXRlcyAgb3B0aW9uYWxfYnl0ZXMgICAgPSAxNTsKKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOworCisgIC8vIFJlcGVhdGVkCisgIHJlcGVhdGVkIGludDMyICByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nICAgPSA0NDsKKyAgcmVwZWF0ZWQgYnl0ZXMgIHJlcGVhdGVkX2J5dGVzICAgID0gNDU7CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAgPSA0ODsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtICA9IDUxOworCisgIC8vIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKKyAgb3B0aW9uYWwgaW50MzIgIGRlZmF1bHRfaW50MzIgICAgPSA2MSBbZGVmYXVsdCA9ICA0MSAgICBdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsIGJ5dGVzICBkZWZhdWx0X2J5dGVzICAgID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTsKKworICBvcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0X25hbiA9IDk5ICBbZGVmYXVsdCA9ICBuYW5dOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gZGVmYXVsdF9uZXN0ZWRfZW51bSA9IDgxIFtkZWZhdWx0ID0gQkFSXTsKKworICAvLyBSZXF1aXJlZAorICByZXF1aXJlZCBpbnQzMiBpZCA9IDg2OworCisgIC8vIEFkZCBlbm91Z2ggb3B0aW9uYWwgZmllbGRzIHRvIG1ha2UgMiBiaXQgZmllbGRzIGluIHRvdGFsCisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEwMCA9IDEwMDsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTAxID0gMTAxOworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMDIgPSAxMDI7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEwMyA9IDEwMzsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTA0ID0gMTA0OworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMDUgPSAxMDU7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEwNiA9IDEwNjsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTA3ID0gMTA3OworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMDggPSAxMDg7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEwOSA9IDEwOTsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTEwID0gMTEwOworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMTEgPSAxMTE7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjExMiA9IDExMjsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTEzID0gMTEzOworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMTQgPSAxMTQ7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjExNSA9IDExNTsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTE2ID0gMTE2OworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMTcgPSAxMTc7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjExOCA9IDExODsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTE5ID0gMTE5OworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMjAgPSAxMjA7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEyMSA9IDEyMTsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTIyID0gMTIyOworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMjMgPSAxMjM7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEyNCA9IDEyNDsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTI1ID0gMTI1OworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMjYgPSAxMjY7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEyNyA9IDEyNzsKKyAgb3B0aW9uYWwgaW50MzIgZmlsbGVyMTI4ID0gMTI4OworICBvcHRpb25hbCBpbnQzMiBmaWxsZXIxMjkgPSAxMjk7CisgIG9wdGlvbmFsIGludDMyIGZpbGxlcjEzMCA9IDEzMDsKKworICBvcHRpb25hbCBpbnQzMiBiZWZvcmVfYml0X2ZpZWxkX2NoZWNrID0gMTM5OworICBvcHRpb25hbCBpbnQzMiBiaXRfZmllbGRfY2hlY2sgPSAxNDA7CisgIG9wdGlvbmFsIGludDMyIGFmdGVyX2JpdF9maWVsZF9jaGVjayA9IDE0MTsKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2VudW1fY2xhc3NfbXVsdGlwbGVfbmFuby5wcm90byBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2VudW1fY2xhc3NfbXVsdGlwbGVfbmFuby5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjI0NmJiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV9jbGFzc19tdWx0aXBsZV9uYW5vLnByb3RvCkBAIC0wLDAgKzEsNDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IG1heHRyb3lAZ29vZ2xlLmNvbSAoTWF4IENhaSkKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworCitlbnVtIEZpbGVTY29wZUVudW1NdWx0aXBsZSB7CisgIFRIUkVFID0gMzsKK30KKworbWVzc2FnZSBFbnVtQ2xhc3NOYW5vTXVsdGlwbGUgeworICBlbnVtIE1lc3NhZ2VTY29wZUVudW1NdWx0aXBsZSB7CisgICAgRk9VUiA9IDQ7CisgIH0KKyAgb3B0aW9uYWwgRmlsZVNjb3BlRW51bU11bHRpcGxlIHRocmVlID0gMyBbIGRlZmF1bHQgPSBUSFJFRSBdOworICBvcHRpb25hbCBNZXNzYWdlU2NvcGVFbnVtTXVsdGlwbGUgZm91ciA9IDQgWyBkZWZhdWx0ID0gRk9VUiBdOworfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV9jbGFzc19uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZW51bV9jbGFzc19uYW5vLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzYTg2MjIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9lbnVtX2NsYXNzX25hbm8ucHJvdG8KQEAgLTAsMCArMSw0OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbWF4dHJveUBnb29nbGUuY29tIChNYXggQ2FpKQorCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFubyI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiRW51bUNsYXNzTmFub3MiOworCitlbnVtIEZpbGVTY29wZUVudW0geworICBPTkUgPSAxOworfQorCittZXNzYWdlIEVudW1DbGFzc05hbm8geworICBlbnVtIE1lc3NhZ2VTY29wZUVudW0geworICAgIFRXTyA9IDI7CisgIH0KKyAgb3B0aW9uYWwgRmlsZVNjb3BlRW51bSBvbmUgPSAxIFsgZGVmYXVsdCA9IE9ORSBdOworICBvcHRpb25hbCBNZXNzYWdlU2NvcGVFbnVtIHR3byA9IDIgWyBkZWZhdWx0ID0gVFdPIF07Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9lbnVtX3ZhbGlkaXR5X25hbm8ucHJvdG8gYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9lbnVtX3ZhbGlkaXR5X25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjdmNTc0MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2VudW1fdmFsaWRpdHlfbmFuby5wcm90bwpAQCAtMCwwICsxLDI4IEBACitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFubyI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiRW51bVZhbGlkaXR5IjsKKworZW51bSBFIHsKKyAgZGVmYXVsdCA9IDE7IC8vIHRlc3QgamF2YSBrZXl3b3JkIHJlbmFtaW5nCisgIEZPTyA9IDI7CisgIEJBUiA9IDM7CisgIEJBWiA9IDQ7Cit9CisKK21lc3NhZ2UgTSB7CisgIG9wdGlvbmFsIEUgb3B0aW9uYWxfZSA9IDE7CisgIG9wdGlvbmFsIEUgZGVmYXVsdF9lID0gMiBbIGRlZmF1bHQgPSBCQVogXTsKKyAgcmVwZWF0ZWQgRSByZXBlYXRlZF9lID0gMzsKKyAgcmVwZWF0ZWQgRSBwYWNrZWRfZSA9IDQgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkIEUgcmVwZWF0ZWRfZTIgPSA1OworICByZXBlYXRlZCBFIHBhY2tlZF9lMiA9IDYgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkIEUgcmVwZWF0ZWRfZTMgPSA3OworICByZXBlYXRlZCBFIHBhY2tlZF9lMyA9IDggWyBwYWNrZWQgPSB0cnVlIF07Cit9CisKK21lc3NhZ2UgQWx0IHsKKyAgb3B0aW9uYWwgRSByZXBlYXRlZF9lMl9hc19vcHRpb25hbCA9IDU7CisgIHJlcGVhdGVkIEUgcGFja2VkX2UyX2FzX25vbl9wYWNrZWQgPSA2OworICByZXBlYXRlZCBFIG5vbl9wYWNrZWRfZTNfYXNfcGFja2VkID0gNyBbIHBhY2tlZCA9IHRydWUgXTsKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmE2NzhhOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9uYW5vLnByb3RvCkBAIC0wLDAgKzEsMzMgQEAKK3N5bnRheCA9ICJwcm90bzIiOworCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiRXh0ZW5zaW9ucyI7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFuby50ZXN0ZXh0IjsKKworbWVzc2FnZSBFeHRlbmRhYmxlTWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIGZpZWxkID0gMTsKKyAgZXh0ZW5zaW9ucyAxMCB0byBtYXg7Cit9CisKK2VudW0gQW5FbnVtIHsKKyAgRklSU1RfVkFMVUUgPSAxOworICBTRUNPTkRfVkFMVUUgPSAyOworfQorCittZXNzYWdlIEFub3RoZXJNZXNzYWdlIHsKKyAgb3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE7CisgIG9wdGlvbmFsIGJvb2wgdmFsdWUgPSAyOworfQorCittZXNzYWdlIENvbnRhaW5lck1lc3NhZ2UgeworICBleHRlbmQgRXh0ZW5kYWJsZU1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGJvb2wgYW5vdGhlcl90aGluZyA9IDEwMDsKKyAgfQorfQorCisvLyBGb3IgdGVzdE5hbm9PcHRpb25hbEdyb3VwV2l0aFVua25vd25GaWVsZHNFbmFibGVkOworLy8gbm90IHBhcnQgb2YgdGhlIGV4dGVuc2lvbnMgdGVzdHMuCittZXNzYWdlIE1lc3NhZ2VXaXRoR3JvdXAgeworICBvcHRpb25hbCBncm91cCBHcm91cCA9IDEgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSAyOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9leHRlbnNpb25fcGFja2VkX25hbm8ucHJvdG8gYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9leHRlbnNpb25fcGFja2VkX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Q0NzY4MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9wYWNrZWRfbmFuby5wcm90bwpAQCAtMCwwICsxLDI5IEBACitzeW50YXggPSAicHJvdG8yIjsKKworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9uYW5vLnByb3RvIjsKKworLy8gTXVzdCBiZSBjb21waWxlZCBzZXBhcmF0ZWx5IGR1ZSB0byBleHRlbnNpb24gbnVtYmVyIHJldXNlLgorLy8gVGhlIHJldXNlIGlzIGRlbGliZXJhdGUsIGZvciB0ZXN0aW5nIHdpcmUgY29tcGF0aWJpbGl0eS4KKworbWVzc2FnZSBQYWNrZWRFeHRlbnNpb25zIHsKKyAgZXh0ZW5kIEV4dGVuZGFibGVNZXNzYWdlIHsKKyAgICByZXBlYXRlZCBpbnQzMiAgICBwYWNrZWRfaW50MzIgICAgPSAxMCBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCB1aW50MzIgICBwYWNrZWRfdWludDMyICAgPSAxMSBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBzaW50MzIgICBwYWNrZWRfc2ludDMyICAgPSAxMiBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBpbnQ2NCAgICBwYWNrZWRfaW50NjQgICAgPSAxMyBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCB1aW50NjQgICBwYWNrZWRfdWludDY0ICAgPSAxNCBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBzaW50NjQgICBwYWNrZWRfc2ludDY0ICAgPSAxNSBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBmaXhlZDMyICBwYWNrZWRfZml4ZWQzMiAgPSAxNiBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSAxNyBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBmaXhlZDY0ICBwYWNrZWRfZml4ZWQ2NCAgPSAxOCBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSAxOSBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBib29sICAgICBwYWNrZWRfYm9vbCAgICAgPSAyMCBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBmbG9hdCAgICBwYWNrZWRfZmxvYXQgICAgPSAyMSBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBkb3VibGUgICBwYWNrZWRfZG91YmxlICAgPSAyMiBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICByZXBlYXRlZCBBbkVudW0gICBwYWNrZWRfZW51bSAgICAgPSAyMyBbIHBhY2tlZCA9IHRydWUgXTsKKyAgICAvLyBOb24tcGFja2FibGUgdHlwZXMgb21pdHRlZC4KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3JlcGVhdGVkX25hbm8ucHJvdG8gYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9leHRlbnNpb25fcmVwZWF0ZWRfbmFuby5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZDRiNWRmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3JlcGVhdGVkX25hbm8ucHJvdG8KQEAgLTAsMCArMSwzNCBAQAorc3ludGF4ID0gInByb3RvMiI7CisKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9leHRlbnNpb25fbmFuby5wcm90byI7CisKKy8vIE11c3QgYmUgY29tcGlsZWQgc2VwYXJhdGVseSBkdWUgdG8gZXh0ZW5zaW9uIG51bWJlciByZXVzZS4KKy8vIFRoZSByZXVzZSBpcyBkZWxpYmVyYXRlLCBmb3IgdGVzdGluZyB3aXJlIGNvbXBhdGliaWxpdHkuCisKK21lc3NhZ2UgUmVwZWF0ZWRFeHRlbnNpb25zIHsKKyAgZXh0ZW5kIEV4dGVuZGFibGVNZXNzYWdlIHsKKyAgICByZXBlYXRlZCBpbnQzMiAgICAgICAgICByZXBlYXRlZF9pbnQzMiAgICA9IDEwOworICAgIHJlcGVhdGVkIHVpbnQzMiAgICAgICAgIHJlcGVhdGVkX3VpbnQzMiAgID0gMTE7CisgICAgcmVwZWF0ZWQgc2ludDMyICAgICAgICAgcmVwZWF0ZWRfc2ludDMyICAgPSAxMjsKKyAgICByZXBlYXRlZCBpbnQ2NCAgICAgICAgICByZXBlYXRlZF9pbnQ2NCAgICA9IDEzOworICAgIHJlcGVhdGVkIHVpbnQ2NCAgICAgICAgIHJlcGVhdGVkX3VpbnQ2NCAgID0gMTQ7CisgICAgcmVwZWF0ZWQgc2ludDY0ICAgICAgICAgcmVwZWF0ZWRfc2ludDY0ICAgPSAxNTsKKyAgICByZXBlYXRlZCBmaXhlZDMyICAgICAgICByZXBlYXRlZF9maXhlZDMyICA9IDE2OworICAgIHJlcGVhdGVkIHNmaXhlZDMyICAgICAgIHJlcGVhdGVkX3NmaXhlZDMyID0gMTc7CisgICAgcmVwZWF0ZWQgZml4ZWQ2NCAgICAgICAgcmVwZWF0ZWRfZml4ZWQ2NCAgPSAxODsKKyAgICByZXBlYXRlZCBzZml4ZWQ2NCAgICAgICByZXBlYXRlZF9zZml4ZWQ2NCA9IDE5OworICAgIHJlcGVhdGVkIGJvb2wgICAgICAgICAgIHJlcGVhdGVkX2Jvb2wgICAgID0gMjA7CisgICAgcmVwZWF0ZWQgZmxvYXQgICAgICAgICAgcmVwZWF0ZWRfZmxvYXQgICAgPSAyMTsKKyAgICByZXBlYXRlZCBkb3VibGUgICAgICAgICByZXBlYXRlZF9kb3VibGUgICA9IDIyOworICAgIHJlcGVhdGVkIEFuRW51bSAgICAgICAgIHJlcGVhdGVkX2VudW0gICAgID0gMjM7CisgICAgcmVwZWF0ZWQgc3RyaW5nICAgICAgICAgcmVwZWF0ZWRfc3RyaW5nICAgPSAyNDsKKyAgICByZXBlYXRlZCBieXRlcyAgICAgICAgICByZXBlYXRlZF9ieXRlcyAgICA9IDI1OworICAgIHJlcGVhdGVkIEFub3RoZXJNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgID0gMjY7CisgICAgcmVwZWF0ZWQgZ3JvdXAgICAgICAgICAgUmVwZWF0ZWRHcm91cCAgICAgPSAyNyB7CisgICAgICBvcHRpb25hbCBpbnQzMiBhID0gMTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9zaW5ndWxhcl9uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX3Npbmd1bGFyX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg5NzU0ZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2V4dGVuc2lvbl9zaW5ndWxhcl9uYW5vLnByb3RvCkBAIC0wLDAgKzEsMzQgQEAKK3N5bnRheCA9ICJwcm90bzIiOworCitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFubyI7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfZXh0ZW5zaW9uX25hbm8ucHJvdG8iOworCisvLyBNdXN0IGJlIGNvbXBpbGVkIHNlcGFyYXRlbHkgZHVlIHRvIGV4dGVuc2lvbiBudW1iZXIgcmV1c2UuCisvLyBUaGUgcmV1c2UgaXMgZGVsaWJlcmF0ZSwgZm9yIHRlc3Rpbmcgd2lyZSBjb21wYXRpYmlsaXR5LgorCittZXNzYWdlIFNpbmd1bGFyRXh0ZW5zaW9ucyB7CisgIGV4dGVuZCBFeHRlbmRhYmxlTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgaW50MzIgICAgICAgICAgc29tZV9pbnQzMiAgICA9IDEwOworICAgIG9wdGlvbmFsIHVpbnQzMiAgICAgICAgIHNvbWVfdWludDMyICAgPSAxMTsKKyAgICBvcHRpb25hbCBzaW50MzIgICAgICAgICBzb21lX3NpbnQzMiAgID0gMTI7CisgICAgb3B0aW9uYWwgaW50NjQgICAgICAgICAgc29tZV9pbnQ2NCAgICA9IDEzOworICAgIG9wdGlvbmFsIHVpbnQ2NCAgICAgICAgIHNvbWVfdWludDY0ICAgPSAxNDsKKyAgICBvcHRpb25hbCBzaW50NjQgICAgICAgICBzb21lX3NpbnQ2NCAgID0gMTU7CisgICAgb3B0aW9uYWwgZml4ZWQzMiAgICAgICAgc29tZV9maXhlZDMyICA9IDE2OworICAgIG9wdGlvbmFsIHNmaXhlZDMyICAgICAgIHNvbWVfc2ZpeGVkMzIgPSAxNzsKKyAgICBvcHRpb25hbCBmaXhlZDY0ICAgICAgICBzb21lX2ZpeGVkNjQgID0gMTg7CisgICAgb3B0aW9uYWwgc2ZpeGVkNjQgICAgICAgc29tZV9zZml4ZWQ2NCA9IDE5OworICAgIG9wdGlvbmFsIGJvb2wgICAgICAgICAgIHNvbWVfYm9vbCAgICAgPSAyMDsKKyAgICBvcHRpb25hbCBmbG9hdCAgICAgICAgICBzb21lX2Zsb2F0ICAgID0gMjE7CisgICAgb3B0aW9uYWwgZG91YmxlICAgICAgICAgc29tZV9kb3VibGUgICA9IDIyOworICAgIG9wdGlvbmFsIEFuRW51bSAgICAgICAgIHNvbWVfZW51bSAgICAgPSAyMzsKKyAgICBvcHRpb25hbCBzdHJpbmcgICAgICAgICBzb21lX3N0cmluZyAgID0gMjQ7CisgICAgb3B0aW9uYWwgYnl0ZXMgICAgICAgICAgc29tZV9ieXRlcyAgICA9IDI1OworICAgIG9wdGlvbmFsIEFub3RoZXJNZXNzYWdlIHNvbWVfbWVzc2FnZSAgPSAyNjsKKyAgICBvcHRpb25hbCBncm91cCAgICAgICAgICBTb21lR3JvdXAgICAgID0gMjcgeworICAgICAgb3B0aW9uYWwgaW50MzIgYSA9IDE7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9oYXNfbmFuby5wcm90byBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2hhc19uYW5vLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkYTFhNmUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9oYXNfbmFuby5wcm90bwpAQCAtMCwwICsxLDgyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB1bGFzQGdvb2dsZS5jb20gKFVsYXMgS2lyYXpjaSkKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk5hbm9IYXNPdXRlckNsYXNzIjsKKworbWVzc2FnZSBUZXN0QWxsVHlwZXNOYW5vSGFzIHsKKworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDMyIGJiID0gMTsKKyAgfQorCisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgRk9PID0gMTsKKyAgICBCQVIgPSAyOworICAgIEJBWiA9IDM7CisgIH0KKworICAvLyBTaW5ndWxhcgorICBvcHRpb25hbCBpbnQzMiAgb3B0aW9uYWxfaW50MzIgICAgPSAgMTsKKyAgb3B0aW9uYWwgZmxvYXQgIG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgIG9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgICA9IDEyOworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nICAgPSAxNDsKKyAgb3B0aW9uYWwgYnl0ZXMgIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCBpbnQzMiAgcmVwZWF0ZWRfaW50MzIgICAgPSAzMTsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyAgID0gNDQ7CisgIHJlcGVhdGVkIGJ5dGVzICByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgID0gNDg7CisKKyAgcmVwZWF0ZWQgTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSAgPSA1MTsKKworICAvLyBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCisgIG9wdGlvbmFsIGludDMyICBkZWZhdWx0X2ludDMyICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nICAgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOworICBvcHRpb25hbCBieXRlcyAgZGVmYXVsdF9ieXRlcyAgICA9IDc1IFtkZWZhdWx0ID0gIndvcmxkIl07CisKKyAgb3B0aW9uYWwgZmxvYXQgZGVmYXVsdF9mbG9hdF9uYW4gPSA5OSAgW2RlZmF1bHQgPSAgbmFuXTsKKworICBvcHRpb25hbCBOZXN0ZWRFbnVtIGRlZmF1bHRfbmVzdGVkX2VudW0gPSA4MSBbZGVmYXVsdCA9IEJBUl07CisKKyAgcmVxdWlyZWQgaW50MzIgaWQgPSA4NjsKKyAgcmVxdWlyZWQgTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtID0gODc7CisKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2ltcG9ydF9uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfaW1wb3J0X25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWEzZGRjNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2ltcG9ydF9uYW5vLnByb3RvCkBAIC0wLDAgKzEsNDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gVGhpcyBpcyBsaWtlIHVuaXR0ZXN0X2ltcG9ydC5wcm90byBidXQgd2l0aCBvcHRpbWl6ZV9mb3IgPSBOQU5PX1JVTlRJTUUuCisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFuby50ZXN0aW1wb3J0IjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJVbml0dGVzdEltcG9ydE5hbm8iOworCittZXNzYWdlIEltcG9ydE1lc3NhZ2VOYW5vIHsKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDE7Cit9CisKK2VudW0gSW1wb3J0RW51bU5hbm8geworICBJTVBPUlRfTkFOT19GT08gPSA3OworICBJTVBPUlRfTkFOT19CQVIgPSA4OworICBJTVBPUlRfTkFOT19CQVogPSA5OworfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbXVsdGlwbGVfbmFtZWNsYXNoX25hbm8ucHJvdG8gYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9tdWx0aXBsZV9uYW1lY2xhc2hfbmFuby5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGIyZDNlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbXVsdGlwbGVfbmFtZWNsYXNoX25hbm8ucHJvdG8KQEAgLTAsMCArMSw0MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbWF4dHJveUBnb29nbGUuY29tIChNYXggQ2FpKQorCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk11bHRpcGxlTmFtZUNsYXNoTmFubyI7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CisKK21lc3NhZ2UgTXVsdGlwbGVOYW1lQ2xhc2hOYW5vIHsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGQgPSAxOworfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbXVsdGlwbGVfbmFuby5wcm90byBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X211bHRpcGxlX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWRiZjBkZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X211bHRpcGxlX25hbm8ucHJvdG8KQEAgLTAsMCArMSw2MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbWF4dHJveUBnb29nbGUuY29tIChNYXggQ2FpKQorCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9pbXBvcnRfbmFuby5wcm90byI7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vIjsKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKKworZW51bSBGaWxlU2NvcGVFbnVtIHsKKyAgT05FID0gMTsKKyAgVFdPID0gMjsKK30KKworbWVzc2FnZSBGaWxlU2NvcGVFbnVtUmVmTmFubyB7CisgIG9wdGlvbmFsIEZpbGVTY29wZUVudW0gZW51bV9maWVsZCA9IDE7Cit9CisKK21lc3NhZ2UgTWVzc2FnZVNjb3BlRW51bVJlZk5hbm8geworICBlbnVtIE1lc3NhZ2VTY29wZUVudW0geworICAgIE9ORSA9IDE7CisgICAgVFdPID0gMjsKKyAgfQorICBvcHRpb25hbCBNZXNzYWdlU2NvcGVFbnVtIGVudW1fZmllbGQgPSAxOworfQorCittZXNzYWdlIE11bHRpcGxlSW1wb3J0aW5nTm9uTXVsdGlwbGVOYW5vMSB7CisgIG9wdGlvbmFsIEltcG9ydE1lc3NhZ2VOYW5vIGZpZWxkID0gMTsKK30KKworbWVzc2FnZSBNdWx0aXBsZUltcG9ydGluZ05vbk11bHRpcGxlTmFubzIgeworICBvcHRpb25hbCBNdWx0aXBsZUltcG9ydGluZ05vbk11bHRpcGxlTmFubzEgbmFubzEgPSAxOworfQpkaWZmIC0tZ2l0IGEvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbmFuby5wcm90byBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWZhZjUyNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X25hbm8ucHJvdG8KQEAgLTAsMCArMSwxOTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IHdpbmtAZ29vZ2xlLmNvbSAoV2luayBTYXZpbGxlKQorCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X2ltcG9ydF9uYW5vLnByb3RvIjsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk5hbm9PdXRlckNsYXNzIjsKKworLy8gU2FtZSBhcyBUZXN0QWxsVHlwZXMgYnV0IHdpdGggdGhlIG5hbm8gcnVudGltZS4KK21lc3NhZ2UgVGVzdEFsbFR5cGVzTmFubyB7CisKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBvcHRpb25hbCBpbnQzMiBiYiA9IDE7CisgIH0KKworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDE7CisgICAgQkFSID0gMjsKKyAgICBCQVogPSAzOworICB9CisKKyAgLy8gU2luZ3VsYXIKKyAgb3B0aW9uYWwgICAgaW50MzIgb3B0aW9uYWxfaW50MzIgICAgPSAgMTsKKyAgb3B0aW9uYWwgICAgaW50NjQgb3B0aW9uYWxfaW50NjQgICAgPSAgMjsKKyAgb3B0aW9uYWwgICB1aW50MzIgb3B0aW9uYWxfdWludDMyICAgPSAgMzsKKyAgb3B0aW9uYWwgICB1aW50NjQgb3B0aW9uYWxfdWludDY0ICAgPSAgNDsKKyAgb3B0aW9uYWwgICBzaW50MzIgb3B0aW9uYWxfc2ludDMyICAgPSAgNTsKKyAgb3B0aW9uYWwgICBzaW50NjQgb3B0aW9uYWxfc2ludDY0ICAgPSAgNjsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiAgPSAgNzsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCAgPSAgODsKKyAgb3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSAgOTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDsKKyAgb3B0aW9uYWwgICAgZmxvYXQgb3B0aW9uYWxfZmxvYXQgICAgPSAxMTsKKyAgb3B0aW9uYWwgICBkb3VibGUgb3B0aW9uYWxfZG91YmxlICAgPSAxMjsKKyAgb3B0aW9uYWwgICAgIGJvb2wgb3B0aW9uYWxfYm9vbCAgICAgPSAxMzsKKyAgb3B0aW9uYWwgICBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nICAgPSAxNDsKKyAgb3B0aW9uYWwgICAgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgICAgPSAxNTsKKworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSAxNzsKKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2UgICAgICBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgPSAxODsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2VOYW5vIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZU5hbm8KKyAgICBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gICAgICBvcHRpb25hbF9uZXN0ZWRfZW51bSAgICAgPSAyMTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW1OYW5vIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSAgICA9IDIyOworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bU5hbm8gb3B0aW9uYWxfaW1wb3J0X2VudW0gPSAyMzsKKworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlPUNPUkRdOworCisgIC8vIFJlcGVhdGVkCisgIHJlcGVhdGVkICAgIGludDMyIHJlcGVhdGVkX2ludDMyICAgID0gMzE7CisgIHJlcGVhdGVkICAgIGludDY0IHJlcGVhdGVkX2ludDY0ICAgID0gMzI7CisgIHJlcGVhdGVkICAgdWludDMyIHJlcGVhdGVkX3VpbnQzMiAgID0gMzM7CisgIHJlcGVhdGVkICAgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCAgID0gMzQ7CisgIHJlcGVhdGVkICAgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiAgID0gMzU7CisgIHJlcGVhdGVkICAgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCAgID0gMzY7CisgIHJlcGVhdGVkICBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgID0gMzc7CisgIHJlcGVhdGVkICBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgID0gMzg7CisgIHJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7CisgIHJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7CisgIHJlcGVhdGVkICAgIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ICAgID0gNDE7CisgIHJlcGVhdGVkICAgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSAgID0gNDI7CisgIHJlcGVhdGVkICAgICBib29sIHJlcGVhdGVkX2Jvb2wgICAgID0gNDM7CisgIHJlcGVhdGVkICAgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyAgID0gNDQ7CisgIHJlcGVhdGVkICAgIGJ5dGVzIHJlcGVhdGVkX2J5dGVzICAgID0gNDU7CisKKyAgcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gNDc7CisgIH0KKworICByZXBlYXRlZCBOZXN0ZWRNZXNzYWdlICAgICAgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgID0gNDg7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlTmFubyByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2VOYW5vCisgICAgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtICAgICAgcmVwZWF0ZWRfbmVzdGVkX2VudW0gID0gNTE7CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtTmFubyByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1MjsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1OYW5vIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7CisKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZT1TVFJJTkdfUElFQ0VdOworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZT1DT1JEXTsKKworICAvLyBSZXBlYXRlZCBwYWNrZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfcGFja2VkX2ludDMyICAgID0gODcgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfcGFja2VkX3NmaXhlZDY0ID0gODggW3BhY2tlZD10cnVlXTsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtIHJlcGVhdGVkX3BhY2tlZF9uZXN0ZWRfZW51bSAgPSA4OSBbcGFja2VkPXRydWVdOworCisgIC8vIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKKyAgb3B0aW9uYWwgICAgaW50MzIgZGVmYXVsdF9pbnQzMiAgICA9IDYxIFtkZWZhdWx0ID0gIDQxICAgIF07CisgIG9wdGlvbmFsICAgIGludDY0IGRlZmF1bHRfaW50NjQgICAgPSA2MiBbZGVmYXVsdCA9ICA0MiAgICBdOworICBvcHRpb25hbCAgIHVpbnQzMiBkZWZhdWx0X3VpbnQzMiAgID0gNjMgW2RlZmF1bHQgPSAgNDMgICAgXTsKKyAgb3B0aW9uYWwgICB1aW50NjQgZGVmYXVsdF91aW50NjQgICA9IDY0IFtkZWZhdWx0ID0gIDQ0ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDMyIGRlZmF1bHRfc2ludDMyICAgPSA2NSBbZGVmYXVsdCA9IC00NSAgICBdOworICBvcHRpb25hbCAgIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NCAgID0gNjYgW2RlZmF1bHQgPSAgNDYgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgZGVmYXVsdF9maXhlZDMyICA9IDY3IFtkZWZhdWx0ID0gIDQ3ICAgIF07CisgIG9wdGlvbmFsICBmaXhlZDY0IGRlZmF1bHRfZml4ZWQ2NCAgPSA2OCBbZGVmYXVsdCA9ICA0OCAgICBdOworICBvcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyID0gNjkgW2RlZmF1bHQgPSAgNDkgICAgXTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NCA9IDcwIFtkZWZhdWx0ID0gLTUwICAgIF07CisgIG9wdGlvbmFsICAgIGZsb2F0IGRlZmF1bHRfZmxvYXQgICAgPSA3MSBbZGVmYXVsdCA9ICA1MS41ICBdOworICBvcHRpb25hbCAgIGRvdWJsZSBkZWZhdWx0X2RvdWJsZSAgID0gNzIgW2RlZmF1bHQgPSAgNTJlMyAgXTsKKyAgb3B0aW9uYWwgICAgIGJvb2wgZGVmYXVsdF9ib29sICAgICA9IDczIFtkZWZhdWx0ID0gdHJ1ZSAgIF07CisgIG9wdGlvbmFsICAgc3RyaW5nIGRlZmF1bHRfc3RyaW5nICAgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOworICBvcHRpb25hbCAgICBieXRlcyBkZWZhdWx0X2J5dGVzICAgID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfbm9uYXNjaWkgPSA3NiBbZGVmYXVsdCA9ICJkw7xueWEiXTsKKyAgb3B0aW9uYWwgIGJ5dGVzIGRlZmF1bHRfYnl0ZXNfbm9uYXNjaWkgID0gNzcgW2RlZmF1bHQgPSAiZMO8bnlhYiJdOworCisgIG9wdGlvbmFsICBmbG9hdCBkZWZhdWx0X2Zsb2F0X2luZiAgICAgID0gOTcgIFtkZWZhdWx0ID0gIGluZl07CisgIG9wdGlvbmFsICBmbG9hdCBkZWZhdWx0X2Zsb2F0X25lZ19pbmYgID0gOTggIFtkZWZhdWx0ID0gLWluZl07CisgIG9wdGlvbmFsICBmbG9hdCBkZWZhdWx0X2Zsb2F0X25hbiAgICAgID0gOTkgIFtkZWZhdWx0ID0gIG5hbl07CisgIG9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9pbmYgICAgID0gMTAwIFtkZWZhdWx0ID0gIGluZl07CisgIG9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9uZWdfaW5mID0gMTAxIFtkZWZhdWx0ID0gLWluZl07CisgIG9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9uYW4gICAgID0gMTAyIFtkZWZhdWx0ID0gIG5hbl07CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBkZWZhdWx0X25lc3RlZF9lbnVtID0gODEgW2RlZmF1bHQgPSBCQVJdOworICBvcHRpb25hbCBGb3JlaWduRW51bU5hbm8gZGVmYXVsdF9mb3JlaWduX2VudW0gPSA4MgorICAgICAgW2RlZmF1bHQgPSBGT1JFSUdOX05BTk9fQkFSXTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1OYW5vCisgICAgICBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfTkFOT19CQVJdOworCisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZ19waWVjZSA9IDg0IFtjdHlwZT1TVFJJTkdfUElFQ0UsZGVmYXVsdD0iYWJjIl07CisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmQgPSA4NSBbY3R5cGU9Q09SRCxkZWZhdWx0PSIxMjMiXTsKKworICByZXF1aXJlZCBpbnQzMiBpZCA9IDg2OworCisgIC8vIFRyeSB0byBjYXVzZSBjb25mbGljdHMuCisgIG9wdGlvbmFsIGludDMyIHRhZyA9IDkzOworICBvcHRpb25hbCBpbnQzMiBnZXRfc2VyaWFsaXplZF9zaXplID0gOTQ7CisgIG9wdGlvbmFsIGludDMyIHdyaXRlX3RvID0gOTU7CisKKyAgLy8gVHJ5IHRvIGZhaWwgd2l0aCBqYXZhIHJlc2VydmVkIGtleXdvcmRzCisgIG9wdGlvbmFsIGludDMyIHN5bmNocm9uaXplZCA9IDk2OworCisgIG9uZW9mIG9uZW9mX2ZpZWxkIHsKKyAgICB1aW50MzIgb25lb2ZfdWludDMyID0gMTExOworICAgIE5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7CisgICAgc3RyaW5nIG9uZW9mX3N0cmluZyA9IDEyMzsKKyAgICBieXRlcyBvbmVvZl9ieXRlcyA9IDEyNDsKKyAgICBmaXhlZDY0IG9uZW9mX2ZpeGVkNjQgPSAxMTU7CisgICAgTmVzdGVkRW51bSBvbmVvZl9lbnVtID0gMTE2OworICB9Cit9CisKK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2VOYW5vIHsKKyAgb3B0aW9uYWwgaW50MzIgYyA9IDE7Cit9CisKK2VudW0gRm9yZWlnbkVudW1OYW5vIHsKKyAgRk9SRUlHTl9OQU5PX0ZPTyA9IDQ7CisgIEZPUkVJR05fTkFOT19CQVIgPSA1OworICBGT1JFSUdOX05BTk9fQkFaID0gNjsKK30KKworLy8gVGVzdCB0aGF0IGRlcHJlY2F0ZWQgZmllbGRzIHdvcmsuICBXZSBvbmx5IHZlcmlmeSB0aGF0IHRoZXkgY29tcGlsZSAoYXQgb25lCisvLyBwb2ludCB0aGlzIGZhaWxlZCkuCittZXNzYWdlIFRlc3REZXByZWNhdGVkTmFubyB7CisgIG9wdGlvbmFsIGludDMyIGRlcHJlY2F0ZWRfZmllbGQgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZWN1cnNpdmVfbmFuby5wcm90byBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3JlY3Vyc2l2ZV9uYW5vLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5ZDA1ODMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZWN1cnNpdmVfbmFuby5wcm90bwpAQCAtMCwwICsxLDQ5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSkKKy8vCisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFubyI7CisvLyBFeHBsaWNpdCBvdXRlciBjbGFzc25hbWUgdG8gc3VwcHJlc3MgbGVnYWN5IGluZm8uCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiVW5pdHRlc3RSZWN1cnNpdmVOYW5vIjsKKworbWVzc2FnZSBSZWN1cnNpdmVNZXNzYWdlTmFubyB7CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgUmVjdXJzaXZlTWVzc2FnZU5hbm8gYSA9IDE7CisgIH0KKworICByZXF1aXJlZCBpbnQzMiBpZCA9IDE7CisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAyOworICBvcHRpb25hbCBSZWN1cnNpdmVNZXNzYWdlTmFubyBvcHRpb25hbF9yZWN1cnNpdmVfbWVzc2FnZV9uYW5vID0gMzsKKyAgcmVwZWF0ZWQgUmVjdXJzaXZlTWVzc2FnZU5hbm8gcmVwZWF0ZWRfcmVjdXJzaXZlX21lc3NhZ2VfbmFubyA9IDQ7Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZWZlcmVuY2VfdHlwZXNfbmFuby5wcm90byBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3JlZmVyZW5jZV90eXBlc19uYW5vLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiMjQ2MTUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZWZlcmVuY2VfdHlwZXNfbmFuby5wcm90bwpAQCAtMCwwICsxLDExNiBAQAorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk5hbm9SZWZlcmVuY2VUeXBlcyI7CisKK21lc3NhZ2UgVGVzdEFsbFR5cGVzTmFubyB7CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAxOworICAgIEJBUiA9IDI7CisgICAgQkFaID0gMzsKKyAgfQorCisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgaW50MzIgZm9vID0gMTsKKyAgfQorCisgIC8vIFNpbmd1bGFyCisgIG9wdGlvbmFsICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7CisgIG9wdGlvbmFsICAgIGludDY0IG9wdGlvbmFsX2ludDY0ICAgID0gIDI7CisgIG9wdGlvbmFsICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMiAgID0gIDM7CisgIG9wdGlvbmFsICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCAgID0gIDQ7CisgIG9wdGlvbmFsICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiAgID0gIDU7CisgIG9wdGlvbmFsICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCAgID0gIDY7CisgIG9wdGlvbmFsICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgID0gIDc7CisgIG9wdGlvbmFsICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgID0gIDg7CisgIG9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gIDk7CisgIG9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7CisgIG9wdGlvbmFsICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgIG9wdGlvbmFsICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgIG9wdGlvbmFsICAgICBib29sIG9wdGlvbmFsX2Jvb2wgICAgID0gMTM7CisgIG9wdGlvbmFsICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyAgID0gMTQ7CisgIG9wdGlvbmFsICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgb3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gMTc7CisgIH0KKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlICAgICAgb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgID0gMTg7CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSAgICAgIG9wdGlvbmFsX25lc3RlZF9lbnVtICAgICA9IDIxOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgLy8gUmVwZWF0ZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfaW50MzIgICAgPSAzMTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcmVwZWF0ZWRfaW50NjQgICAgPSAzMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyICAgPSAzMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcmVwZWF0ZWRfdWludDY0ICAgPSAzNDsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcmVwZWF0ZWRfc2ludDMyICAgPSAzNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ICAgPSAzNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiAgPSAzNzsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCAgPSAzODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgICAgPSA0MTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlICAgPSA0MjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcmVwZWF0ZWRfYm9vbCAgICAgPSA0MzsKKyAgcmVwZWF0ZWQgICBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nICAgPSA0NDsKKyAgcmVwZWF0ZWQgICAgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgICAgPSA0NTsKKworICByZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSA0NzsKKyAgfQorCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgICAgICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAgPSA0ODsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtICAgICAgcmVwZWF0ZWRfbmVzdGVkX2VudW0gID0gNTE7CisKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZT1TVFJJTkdfUElFQ0VdOworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZT1DT1JEXTsKKworICAvLyBSZXBlYXRlZCBwYWNrZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfcGFja2VkX2ludDMyICAgID0gODcgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfcGFja2VkX3NmaXhlZDY0ID0gODggW3BhY2tlZD10cnVlXTsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtIHJlcGVhdGVkX3BhY2tlZF9uZXN0ZWRfZW51bSAgPSA4OSBbcGFja2VkPXRydWVdOworCisgIC8vIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKKyAgb3B0aW9uYWwgICAgaW50MzIgZGVmYXVsdF9pbnQzMiAgICA9IDYxIFtkZWZhdWx0ID0gIDQxICAgIF07CisgIG9wdGlvbmFsICAgIGludDY0IGRlZmF1bHRfaW50NjQgICAgPSA2MiBbZGVmYXVsdCA9ICA0MiAgICBdOworICBvcHRpb25hbCAgIHVpbnQzMiBkZWZhdWx0X3VpbnQzMiAgID0gNjMgW2RlZmF1bHQgPSAgNDMgICAgXTsKKyAgb3B0aW9uYWwgICB1aW50NjQgZGVmYXVsdF91aW50NjQgICA9IDY0IFtkZWZhdWx0ID0gIDQ0ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDMyIGRlZmF1bHRfc2ludDMyICAgPSA2NSBbZGVmYXVsdCA9IC00NSAgICBdOworICBvcHRpb25hbCAgIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NCAgID0gNjYgW2RlZmF1bHQgPSAgNDYgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgZGVmYXVsdF9maXhlZDMyICA9IDY3IFtkZWZhdWx0ID0gIDQ3ICAgIF07CisgIG9wdGlvbmFsICBmaXhlZDY0IGRlZmF1bHRfZml4ZWQ2NCAgPSA2OCBbZGVmYXVsdCA9ICA0OCAgICBdOworICBvcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyID0gNjkgW2RlZmF1bHQgPSAgNDkgICAgXTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NCA9IDcwIFtkZWZhdWx0ID0gLTUwICAgIF07CisgIG9wdGlvbmFsICAgIGZsb2F0IGRlZmF1bHRfZmxvYXQgICAgPSA3MSBbZGVmYXVsdCA9ICA1MS41ICBdOworICBvcHRpb25hbCAgIGRvdWJsZSBkZWZhdWx0X2RvdWJsZSAgID0gNzIgW2RlZmF1bHQgPSAgNTJlMyAgXTsKKyAgb3B0aW9uYWwgICAgIGJvb2wgZGVmYXVsdF9ib29sICAgICA9IDczIFtkZWZhdWx0ID0gdHJ1ZSAgIF07CisgIG9wdGlvbmFsICAgc3RyaW5nIGRlZmF1bHRfc3RyaW5nICAgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOworICBvcHRpb25hbCAgICBieXRlcyBkZWZhdWx0X2J5dGVzICAgID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTsKKworCisgIG9wdGlvbmFsICBmbG9hdCBkZWZhdWx0X2Zsb2F0X2luZiAgICAgID0gOTcgIFtkZWZhdWx0ID0gIGluZl07CisgIG9wdGlvbmFsICBmbG9hdCBkZWZhdWx0X2Zsb2F0X25lZ19pbmYgID0gOTggIFtkZWZhdWx0ID0gLWluZl07CisgIG9wdGlvbmFsICBmbG9hdCBkZWZhdWx0X2Zsb2F0X25hbiAgICAgID0gOTkgIFtkZWZhdWx0ID0gIG5hbl07CisgIG9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9pbmYgICAgID0gMTAwIFtkZWZhdWx0ID0gIGluZl07CisgIG9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9uZWdfaW5mID0gMTAxIFtkZWZhdWx0ID0gLWluZl07CisgIG9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9uYW4gICAgID0gMTAyIFtkZWZhdWx0ID0gIG5hbl07CisKK30KKworbWVzc2FnZSBGb3JlaWduTWVzc2FnZU5hbm8geworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bU5hbm8geworICBGT1JFSUdOX05BTk9fRk9PID0gNDsKKyAgRk9SRUlHTl9OQU5PX0JBUiA9IDU7CisgIEZPUkVJR05fTkFOT19CQVogPSA2OworfQorCmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9yZXBlYXRlZF9tZXJnZV9uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVwZWF0ZWRfbWVyZ2VfbmFuby5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YmZjM2FkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVwZWF0ZWRfbWVyZ2VfbmFuby5wcm90bwpAQCAtMCwwICsxLDQ3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBtYXh0cm95QGdvb2dsZS5jb20gKE1heCBDYWkpCisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfbmFuby5wcm90byI7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vIjsKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKKworLy8gQSBjb250YWluZXIgbWVzc2FnZSBmb3IgdGVzdGluZyB0aGUgbWVyZ2luZyBvZiByZXBlYXRlZCBmaWVsZHMgYXQgYQorLy8gbmVzdGVkIGxldmVsLiBPdGhlciB0ZXN0cyB3aWxsIGJlIGRvbmUgdXNpbmcgdGhlIHJlcGVhdGVkIGZpZWxkcyBpbgorLy8gVGVzdEFsbFR5cGVzTmFuby4KK21lc3NhZ2UgVGVzdFJlcGVhdGVkTWVyZ2VOYW5vIHsKKworICBvcHRpb25hbCBUZXN0QWxsVHlwZXNOYW5vIGNvbnRhaW5lZCA9IDE7CisKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3JlcGVhdGVkX3BhY2thYmxlc19uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3RfcmVwZWF0ZWRfcGFja2FibGVzX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdjYTc1MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3JlcGVhdGVkX3BhY2thYmxlc19uYW5vLnByb3RvCkBAIC0wLDAgKzEsOTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IG1heHRyb3lAZ29vZ2xlLmNvbSAoTWF4IENhaSkKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8iOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk5hbm9SZXBlYXRlZFBhY2thYmxlcyI7CisKK2VudW0gRW51bSB7CisgIE9QVElPTl9PTkUgPSAxOworICBPUFRJT05fVFdPID0gMjsKK30KKworLy8gVHdvIGFsbW9zdCBpZGVudGljYWwgbWVzc2FnZXMgd2l0aCBhbGwgcGFja2FibGUgcmVwZWF0ZWQgZmllbGQgdHlwZXMuCisvLyBPbmUgd2l0aCBub25lIG1hcmtlZCBhcyBwYWNrZWQgYW5kIHRoZSBvdGhlciBhbGwgcGFja2VkLiBGb3IKKy8vIGNvbXBhdGliaWxpdHksIHRoZXkgc2hvdWxkIGJlIGFibGUgdG8gcGFyc2UgZWFjaCBvdGhlcidzIHNlcmlhbGl6ZWQKKy8vIGZvcm1zLgorCittZXNzYWdlIE5vblBhY2tlZCB7CisKKyAgLy8gQWxsIHBhY2thYmxlIHR5cGVzLCBub25lIG1hcmtlZCBhcyBwYWNrZWQuCisKKyAgcmVwZWF0ZWQgICAgaW50MzIgaW50MzJzICAgID0gMTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgaW50NjRzICAgID0gMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgdWludDMycyAgID0gMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgdWludDY0cyAgID0gNDsKKyAgcmVwZWF0ZWQgICBzaW50MzIgc2ludDMycyAgID0gNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgc2ludDY0cyAgID0gNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgZml4ZWQzMnMgID0gNzsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgZml4ZWQ2NHMgID0gODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgc2ZpeGVkMzJzID0gOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgc2ZpeGVkNjRzID0gMTA7CisgIHJlcGVhdGVkICAgIGZsb2F0IGZsb2F0cyAgICA9IDExOworICByZXBlYXRlZCAgIGRvdWJsZSBkb3VibGVzICAgPSAxMjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgYm9vbHMgICAgID0gMTM7CisgIHJlcGVhdGVkICAgICBFbnVtIGVudW1zICAgICA9IDE0OworCisgIC8vIE5vaXNlIGZvciB0ZXN0aW5nIG1lcmdlZCBkZXNlcmlhbGl6YXRpb24uCisgIG9wdGlvbmFsIGludDMyIG5vaXNlID0gMTU7CisKK30KKworbWVzc2FnZSBQYWNrZWQgeworCisgIC8vIEFsbCBwYWNrYWJsZSB0eXBlcywgYWxsIG1hdGNoaW5nIHRoZSBmaWVsZCBudW1iZXJzIGluIE5vblBhY2tlZCwKKyAgLy8gYWxsIG1hcmtlZCBhcyBwYWNrZWQuCisKKyAgcmVwZWF0ZWQgICAgaW50MzIgaW50MzJzICAgID0gMSAgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkICAgIGludDY0IGludDY0cyAgICA9IDIgIFsgcGFja2VkID0gdHJ1ZSBdOworICByZXBlYXRlZCAgIHVpbnQzMiB1aW50MzJzICAgPSAzICBbIHBhY2tlZCA9IHRydWUgXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgdWludDY0cyAgID0gNCAgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkICAgc2ludDMyIHNpbnQzMnMgICA9IDUgIFsgcGFja2VkID0gdHJ1ZSBdOworICByZXBlYXRlZCAgIHNpbnQ2NCBzaW50NjRzICAgPSA2ICBbIHBhY2tlZCA9IHRydWUgXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgZml4ZWQzMnMgID0gNyAgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkICBmaXhlZDY0IGZpeGVkNjRzICA9IDggIFsgcGFja2VkID0gdHJ1ZSBdOworICByZXBlYXRlZCBzZml4ZWQzMiBzZml4ZWQzMnMgPSA5ICBbIHBhY2tlZCA9IHRydWUgXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgc2ZpeGVkNjRzID0gMTAgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkICAgIGZsb2F0IGZsb2F0cyAgICA9IDExIFsgcGFja2VkID0gdHJ1ZSBdOworICByZXBlYXRlZCAgIGRvdWJsZSBkb3VibGVzICAgPSAxMiBbIHBhY2tlZCA9IHRydWUgXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgYm9vbHMgICAgID0gMTMgWyBwYWNrZWQgPSB0cnVlIF07CisgIHJlcGVhdGVkICAgICBFbnVtIGVudW1zICAgICA9IDE0IFsgcGFja2VkID0gdHJ1ZSBdOworCisgIC8vIE5vaXNlIGZvciB0ZXN0aW5nIG1lcmdlZCBkZXNlcmlhbGl6YXRpb24uCisgIG9wdGlvbmFsIGludDMyIG5vaXNlID0gMTU7CisKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3NpbXBsZV9uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3Rfc2ltcGxlX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDgzMzNhYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3NpbXBsZV9uYW5vLnByb3RvCkBAIC0wLDAgKzEsNTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IHdpbmtAZ29vZ2xlLmNvbSAoV2luayBTYXZpbGxlKQorLy8KKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vIjsKKy8vIEV4cGxpY2l0IG91dGVyIGNsYXNzbmFtZSB0byBzdXBwcmVzcyBsZWdhY3kgaW5mby4KK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJVbml0dGVzdFNpbXBsZU5hbm8iOworCittZXNzYWdlIFNpbXBsZU1lc3NhZ2VOYW5vIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBvcHRpb25hbCBpbnQzMiBiYiA9IDE7CisgIH0KKworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDE7CisgICAgQkFSID0gMjsKKyAgICBCQVogPSAzOworICB9CisKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDEgW2RlZmF1bHQgPSAxMjNdOworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG5lc3RlZF9tc2cgPSAyOworICBvcHRpb25hbCBOZXN0ZWRFbnVtIGRlZmF1bHRfbmVzdGVkX2VudW0gPSAzIFtkZWZhdWx0ID0gQkFaXTsKK30KZGlmZiAtLWdpdCBhL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3NpbmdsZV9uYW5vLnByb3RvIGIvamF2YW5hbm8vc3JjL3Rlc3QvamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL25hbm8vdW5pdHRlc3Rfc2luZ2xlX25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDI1NDI4ZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3NpbmdsZV9uYW5vLnByb3RvCkBAIC0wLDAgKzEsMzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IG1heHRyb3lAZ29vZ2xlLmNvbSAoTWF4IENhaSkKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vIjsKKworbWVzc2FnZSBTaW5nbGVNZXNzYWdlTmFubyB7Cit9CmRpZmYgLS1naXQgYS9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9zdHJpbmd1dGY4X25hbm8ucHJvdG8gYi9qYXZhbmFuby9zcmMvdGVzdC9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvbmFuby91bml0dGVzdF9zdHJpbmd1dGY4X25hbm8ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjFiZDhjMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmFuYW5vL3NyYy90ZXN0L2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9uYW5vL3VuaXR0ZXN0X3N0cmluZ3V0ZjhfbmFuby5wcm90bwpAQCAtMCwwICsxLDQzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSkKKy8vCisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYubmFubyI7CisvLyBFeHBsaWNpdCBvdXRlciBjbGFzc25hbWUgdG8gc3VwcHJlc3MgbGVnYWN5IGluZm8uCitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiVW5pdHRlc3RTdHJpbmd1dGY4TmFubyI7CisKK21lc3NhZ2UgU3RyaW5nVXRmOCB7CisgIG9wdGlvbmFsIHN0cmluZyBpZCA9IDE7CisgIHJlcGVhdGVkIHN0cmluZyBycyA9IDI7Cit9CmRpZmYgLS1naXQgYS9tNC9hY19zeXN0ZW1fZXh0ZW5zaW9ucy5tNCBiL200L2FjX3N5c3RlbV9leHRlbnNpb25zLm00Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjYTJlZWIKLS0tIC9kZXYvbnVsbAorKysgYi9tNC9hY19zeXN0ZW1fZXh0ZW5zaW9ucy5tNApAQCAtMCwwICsxLDM3IEBACitkbmwgUHJvdmlkZSBBQ19VU0VfU1lTVEVNX0VYVEVOU0lPTlMgZm9yIG9sZCBhdXRvY29uZiBtYWNoaW5lcy4KK0FDX0RFRlVOKFtBQ1hfVVNFX1NZU1RFTV9FWFRFTlNJT05TXSxbCisgIGlmZGVmKFtBQ19VU0VfU1lTVEVNX0VYVEVOU0lPTlNdLFsKKyAgICBBQ19VU0VfU1lTVEVNX0VYVEVOU0lPTlMKKyAgXSxbCisgICAgQUNfQkVGT1JFKFskMF0sIFtBQ19DT01QSUxFX0lGRUxTRV0pCisgICAgQUNfQkVGT1JFKFskMF0sIFtBQ19SVU5fSUZFTFNFXSkKKworICAgIEFDX1JFUVVJUkUoW0FDX0dOVV9TT1VSQ0VdKQorICAgIEFDX1JFUVVJUkUoW0FDX0FJWF0pCisgICAgQUNfUkVRVUlSRShbQUNfTUlOSVhdKQorCisgICAgQUhfVkVSQkFUSU0oW19fRVhURU5TSU9OU19fXSwKK1svKiBFbmFibGUgZXh0ZW5zaW9ucyBvbiBTb2xhcmlzLiAgKi8KKyNpZm5kZWYgX19FWFRFTlNJT05TX18KKyMgdW5kZWYgX19FWFRFTlNJT05TX18KKyNlbmRpZgorI2lmbmRlZiBfUE9TSVhfUFRIUkVBRF9TRU1BTlRJQ1MKKyMgdW5kZWYgX1BPU0lYX1BUSFJFQURfU0VNQU5USUNTCisjZW5kaWYKKyNpZm5kZWYgX1RBTkRFTV9TT1VSQ0UKKyMgdW5kZWYgX1RBTkRFTV9TT1VSQ0UKKyNlbmRpZl0pCisgICAgQUNfQ0FDSEVfQ0hFQ0soW3doZXRoZXIgaXQgaXMgc2FmZSB0byBkZWZpbmUgX19FWFRFTlNJT05TX19dLAorICAgICAgW2FjX2N2X3NhZmVfdG9fZGVmaW5lX19fZXh0ZW5zaW9uc19fXSwKKyAgICAgIFtBQ19DT01QSUxFX0lGRUxTRSgKKyAgICAgICAgIFtBQ19MQU5HX1BST0dSQU0oWworIyAgICAgICAgICAgZGVmaW5lIF9fRVhURU5TSU9OU19fIDEKKyAgICAgICAgICAgIEFDX0lOQ0xVREVTX0RFRkFVTFRdKV0sCisgICAgICAgICBbYWNfY3Zfc2FmZV90b19kZWZpbmVfX19leHRlbnNpb25zX189eWVzXSwKKyAgICAgICAgIFthY19jdl9zYWZlX3RvX2RlZmluZV9fX2V4dGVuc2lvbnNfXz1ub10pXSkKKyAgICB0ZXN0ICRhY19jdl9zYWZlX3RvX2RlZmluZV9fX2V4dGVuc2lvbnNfXyA9IHllcyAmJgorICAgICAgQUNfREVGSU5FKFtfX0VYVEVOU0lPTlNfX10pCisgICAgQUNfREVGSU5FKFtfUE9TSVhfUFRIUkVBRF9TRU1BTlRJQ1NdKQorICAgIEFDX0RFRklORShbX1RBTkRFTV9TT1VSQ0VdKQorICBdKQorXSkKZGlmZiAtLWdpdCBhL200L2FjeF9jaGVja19zdW5jYy5tNCBiL200L2FjeF9jaGVja19zdW5jYy5tNApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTE4NTkzCi0tLSAvZGV2L251bGwKKysrIGIvbTQvYWN4X2NoZWNrX3N1bmNjLm00CkBAIC0wLDAgKzEsNzUgQEAKK2RubCBDaGVjayBmb3IgdGhlIHByZXNlbmNlIG9mIHRoZSBTdW4gU3R1ZGlvIGNvbXBpbGVyLgorZG5sIElmIFN1biBTdHVkaW8gY29tcGlsZXIgaXMgZm91bmQsIHNldCBhcHByb3ByaWF0ZSBmbGFncy4KK2RubCBBZGRpdGlvbmFsbHksIFN1biBTdHVkaW8gZG9lc24ndCBkZWZhdWx0IHRvIDY0LWJpdCBieSBpdHNlbGYsCitkbmwgbm9yIGRvZXMgaXQgYXV0b21hdGljYWxseSBsb29rIGluIHN0YW5kYXJkIFNvbGFyaXMgcGxhY2VzIGZvcgorZG5sIDY0LWJpdCBsaWJzLCBzbyB3ZSBtdXN0IGFkZCB0aG9zZSBvcHRpb25zIGFuZCBwYXRocyB0byB0aGUgc2VhcmNoCitkbmwgcGF0aHMuCisKK2RubCBUT0RPKGtlbnRvbik6ICBUaGlzIGlzIHByZXR0eSBoYWNreS4gIEl0IHNldHMgQ1hYRkxBR1MsIHdoaWNoIHRoZSBhdXRvY29uZgorZG5sIGRvY3Mgc2F5IHNob3VsZCBuZXZlciBiZSBvdmVycmlkZGVuIGV4Y2VwdCBieSB0aGUgdXNlci4gIEl0IGFsc28gaXNuJ3QKK2RubCBjcm9zcy1jb21waWxlIHNhZmUuICBXZSBzaG91bGQgZml4IHRoZXNlIHByb2JsZW1zLCBidXQgc2luY2UgSSBkb24ndCBoYXZlCitkbmwgU3VuIENDIGF0IG15IGRpc3Bvc2FsIGZvciB0ZXN0aW5nLCBzb21lb25lIGVsc2Ugd2lsbCBoYXZlIHRvIGRvIGl0LgorCitBQ19ERUZVTihbQUNYX0NIRUNLX1NVTkNDXSxbCisKKyAgQUNfTEFOR19QVVNIKFtDKytdKQorICBBQ19DSEVDS19ERUNMKFtfX1NVTlBST19DQ10sIFtTVU5DQz0ieWVzIl0sIFtTVU5DQz0ibm8iXSkKKyAgQUNfTEFOR19QT1AoKQorCisKKyAgQUNfQVJHX0VOQUJMRShbNjRiaXQtc29sYXJpc10sCisgICAgW0FTX0hFTFBfU1RSSU5HKFstLWRpc2FibGUtNjRiaXQtc29sYXJpc10sCisgICAgICBbQnVpbGQgNjQgYml0IGJpbmFyeSBvbiBTb2xhcmlzIEA8OkBkZWZhdWx0PW9uQDo+QF0pXSwKKyAgICAgICAgICAgICBbYWNfZW5hYmxlXzY0Yml0PSIkZW5hYmxldmFsIl0sCisgICAgICAgICAgICAgW2FjX2VuYWJsZV82NGJpdD0ieWVzIl0pCisKKyAgQVNfSUYoW3Rlc3QgIiRTVU5DQyIgPSAieWVzIiAtYSAieCR7YWNfY3ZfZW52X0NYWEZMQUdTX3NldH0iID0gIngiXSxbCisgICAgZG5sIFN1biBTdHVkaW8gaGFzIGEgY3Jhc2hpbmcgYnVnIHdpdGggLXhPNCBpbiBzb21lIGNhc2VzLiBLZWVwIHRoaXMKKyAgICBkbmwgYXQgLXhPMyB1bnRpbCBhIHByb3BlciB0ZXN0IHRvIGRldGVjdCB0aG9zZSBjcmFzaGVzIGNhbiBiZSBkb25lLgorICAgIENYWEZMQUdTPSItZzAgLXhPMyAteGxpYm1pbCAteGRlcGVuZCAteGJ1aWx0aW4gLW10IC1jb21wYXQ9NSAtbGlicmFyeT1zdGxwb3J0NCAtbGlicmFyeT1DcnVuIC10ZW1wbGF0ZT1ubyVleHRkZWYgJHtDWFhGTEFHU30iCisgIF0pCisKKyAgY2FzZSAkaG9zdF9vcyBpbgorICAgICpzb2xhcmlzKikKKyAgICAgIEFDX0NIRUNLX1BST0dTKElTQUlORk8sIFtpc2FpbmZvXSwgW25vXSkKKyAgICAgIEFTX0lGKFt0ZXN0ICJ4JElTQUlORk8iICE9ICJ4bm8iXSwKKyAgICAgICAgICAgIFtpc2FpbmZvX2I9YCR7SVNBSU5GT30gLWJgXSwKKyAgICAgICAgICAgIFtpc2FpbmZvX2I9IngiXSkKKworICAgICAgQVNfSUYoW3Rlc3QgIiRpc2FpbmZvX2IiICE9ICJ4Il0sWworCisgICAgICAgIGlzYWluZm9faz1gJHtJU0FJTkZPfSAta2AKKworICAgICAgICBBU19JRihbdGVzdCAieCRhY19lbmFibGVfNjRiaXQiID0gInh5ZXMiXSxbCisKKyAgICAgICAgICBBQ19ERUZJTkUoW1NPTEFSSVNfNjRCSVRfRU5BQkxFRF0sIFsxXSwgWzY0Yml0IGVuYWJsZWRdKQorICAgICAgICAgIEFTX0lGKFt0ZXN0ICJ4JGxpYmRpciIgPSAieFwke2V4ZWNfcHJlZml4fS9saWIiXSxbCisgICAgICAgICAgIGRubCBUaGUgdXNlciBoYXNuJ3Qgb3ZlcnJpZGRlbiB0aGUgZGVmYXVsdCBsaWJkaXIsIHNvIHdlJ2xsCisgICAgICAgICAgIGRubCB0aGUgZGlyIHN1ZmZpeCB0byBtYXRjaCBzb2xhcmlzIDMyLzY0LWJpdCBwb2xpY3kKKyAgICAgICAgICAgbGliZGlyPSIke2xpYmRpcn0vJHtpc2FpbmZvX2t9IgorICAgICAgICAgIF0pCisKKyAgICAgICAgICBkbmwgVGhpcyBzaG91bGQganVzdCBiZSBzZXQgaW4gQ1BQRkxBR1MgYW5kIGluIExERkxBR1MsIGJ1dCBsaWJ0b29sCisgICAgICAgICAgZG5sIGRvZXMgdGhlIHdyb25nIHRoaW5nIGlmIHlvdSBkb24ndCBwdXQgaXQgaW50byBDWFhGTEFHUy4gc2lnaC4KKyAgICAgICAgICBkbmwgKEl0IGFsc28gbmVlZHMgaXQgaW4gQ0ZMQUdTLCBvciBpdCBkb2VzIGEgZGlmZmVyZW50IHdyb25nIHRoaW5nISkKKyAgICAgICAgICBBU19JRihbdGVzdCAieCR7YWNfY3ZfZW52X0NYWEZMQUdTX3NldH0iID0gIngiXSxbCisgICAgICAgICAgICBDWFhGTEFHUz0iJHtDWFhGTEFHU30gLW02NCIKKyAgICAgICAgICAgIGFjX2N2X2Vudl9DWFhGTEFHU19zZXQ9c2V0CisgICAgICAgICAgICBhY19jdl9lbnZfQ1hYRkxBR1NfdmFsdWU9Jy1tNjQnCisgICAgICAgICAgXSkKKworICAgICAgICAgIEFTX0lGKFt0ZXN0ICJ4JHthY19jdl9lbnZfQ0ZMQUdTX3NldH0iID0gIngiXSxbCisgICAgICAgICAgICBDRkxBR1M9IiR7Q0ZMQUdTfSAtbTY0IgorICAgICAgICAgICAgYWNfY3ZfZW52X0NGTEFHU19zZXQ9c2V0CisgICAgICAgICAgICBhY19jdl9lbnZfQ0ZMQUdTX3ZhbHVlPSctbTY0JworICAgICAgICAgIF0pCisKKyAgICAgICAgICBBU19JRihbdGVzdCAiJHRhcmdldF9jcHUiID0gInNwYXJjIiAtYSAieCRTVU5DQyIgPSAieHllcyIgXSxbCisgICAgICAgICAgICBDWFhGTEFHUz0iLXhtZW1hbGlnbj04cyAke0NYWEZMQUdTfSIKKyAgICAgICAgICBdKQorICAgICAgICBdKQorICAgICAgXSkKKyAgICA7OworICBlc2FjCisKK10pCmRpZmYgLS1naXQgYS9tNC9hY3hfcHRocmVhZC5tNCBiL200L2FjeF9wdGhyZWFkLm00Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5ZDQyYzcKLS0tIC9kZXYvbnVsbAorKysgYi9tNC9hY3hfcHRocmVhZC5tNApAQCAtMCwwICsxLDM5NyBAQAorIyBUaGlzIHdhcyByZXRyaWV2ZWQgZnJvbQorIyAgICBodHRwOi8vc3ZuLjBwb2ludGVyLmRlL3ZpZXd2Yy90cnVuay9jb21tb24vYWN4X3B0aHJlYWQubTQ/cmV2aXNpb249MTI3NyZyb290PWF2YWhpCisjIFNlZSBhbHNvIChwZXJoYXBzIGZvciBuZXcgdmVyc2lvbnM/KQorIyAgICBodHRwOi8vc3ZuLjBwb2ludGVyLmRlL3ZpZXd2Yy90cnVuay9jb21tb24vYWN4X3B0aHJlYWQubTQ/cm9vdD1hdmFoaQorIworIyBXZSd2ZSByZXdyaXR0ZW4gdGhlIGluY29uc2lzdGVuY3kgY2hlY2sgY29kZSAoZnJvbSBhdmFoaSksIHRvIHdvcmsKKyMgbW9yZSBicm9hZGx5LiAgSW4gcGFydGljdWxhciwgaXQgbm8gbG9uZ2VyIGFzc3VtZXMgbGQgYWNjZXB0cyAtemRlZnMuCisjIFRoaXMgY2F1c2VkIGEgcmVzdHJ1Y3Rpbmcgb2YgdGhlIGNvZGUsIGJ1dCB0aGUgZnVuY3Rpb25hbGl0eSBoYXMgb25seQorIyBjaGFuZ2VkIGEgbGl0dGxlLgorCitkbmwgQHN5bm9wc2lzIEFDWF9QVEhSRUFEKFtBQ1RJT04tSUYtRk9VTkRbLCBBQ1RJT04tSUYtTk9ULUZPVU5EXV0pCitkbmwKK2RubCBAc3VtbWFyeSBmaWd1cmUgb3V0IGhvdyB0byBidWlsZCBDIHByb2dyYW1zIHVzaW5nIFBPU0lYIHRocmVhZHMKK2RubAorZG5sIFRoaXMgbWFjcm8gZmlndXJlcyBvdXQgaG93IHRvIGJ1aWxkIEMgcHJvZ3JhbXMgdXNpbmcgUE9TSVggdGhyZWFkcy4KK2RubCBJdCBzZXRzIHRoZSBQVEhSRUFEX0xJQlMgb3V0cHV0IHZhcmlhYmxlIHRvIHRoZSB0aHJlYWRzIGxpYnJhcnkgYW5kCitkbmwgbGlua2VyIGZsYWdzLCBhbmQgdGhlIFBUSFJFQURfQ0ZMQUdTIG91dHB1dCB2YXJpYWJsZSB0byBhbnkgc3BlY2lhbAorZG5sIEMgY29tcGlsZXIgZmxhZ3MgdGhhdCBhcmUgbmVlZGVkLiAoVGhlIHVzZXIgY2FuIGFsc28gZm9yY2UgY2VydGFpbgorZG5sIGNvbXBpbGVyIGZsYWdzL2xpYnMgdG8gYmUgdGVzdGVkIGJ5IHNldHRpbmcgdGhlc2UgZW52aXJvbm1lbnQKK2RubCB2YXJpYWJsZXMuKQorZG5sCitkbmwgQWxzbyBzZXRzIFBUSFJFQURfQ0MgdG8gYW55IHNwZWNpYWwgQyBjb21waWxlciB0aGF0IGlzIG5lZWRlZCBmb3IKK2RubCBtdWx0aS10aHJlYWRlZCBwcm9ncmFtcyAoZGVmYXVsdHMgdG8gdGhlIHZhbHVlIG9mIENDIG90aGVyd2lzZSkuCitkbmwgKFRoaXMgaXMgbmVjZXNzYXJ5IG9uIEFJWCB0byB1c2UgdGhlIHNwZWNpYWwgY2NfciBjb21waWxlciBhbGlhcy4pCitkbmwKK2RubCBOT1RFOiBZb3UgYXJlIGFzc3VtZWQgdG8gbm90IG9ubHkgY29tcGlsZSB5b3VyIHByb2dyYW0gd2l0aCB0aGVzZQorZG5sIGZsYWdzLCBidXQgYWxzbyBsaW5rIGl0IHdpdGggdGhlbSBhcyB3ZWxsLiBlLmcuIHlvdSBzaG91bGQgbGluaworZG5sIHdpdGggJFBUSFJFQURfQ0MgJENGTEFHUyAkUFRIUkVBRF9DRkxBR1MgJExERkxBR1MgLi4uICRQVEhSRUFEX0xJQlMKK2RubCAkTElCUworZG5sCitkbmwgSWYgeW91IGFyZSBvbmx5IGJ1aWxkaW5nIHRocmVhZHMgcHJvZ3JhbXMsIHlvdSBtYXkgd2lzaCB0byB1c2UKK2RubCB0aGVzZSB2YXJpYWJsZXMgaW4geW91ciBkZWZhdWx0IExJQlMsIENGTEFHUywgYW5kIENDOgorZG5sCitkbmwgICAgICAgIExJQlM9IiRQVEhSRUFEX0xJQlMgJExJQlMiCitkbmwgICAgICAgIENGTEFHUz0iJENGTEFHUyAkUFRIUkVBRF9DRkxBR1MiCitkbmwgICAgICAgIENDPSIkUFRIUkVBRF9DQyIKK2RubAorZG5sIEluIGFkZGl0aW9uLCBpZiB0aGUgUFRIUkVBRF9DUkVBVEVfSk9JTkFCTEUgdGhyZWFkLWF0dHJpYnV0ZQorZG5sIGNvbnN0YW50IGhhcyBhIG5vbnN0YW5kYXJkIG5hbWUsIGRlZmluZXMgUFRIUkVBRF9DUkVBVEVfSk9JTkFCTEUgdG8KK2RubCB0aGF0IG5hbWUgKGUuZy4gUFRIUkVBRF9DUkVBVEVfVU5ERVRBQ0hFRCBvbiBBSVgpLgorZG5sCitkbmwgQUNUSU9OLUlGLUZPVU5EIGlzIGEgbGlzdCBvZiBzaGVsbCBjb21tYW5kcyB0byBydW4gaWYgYSB0aHJlYWRzCitkbmwgbGlicmFyeSBpcyBmb3VuZCwgYW5kIEFDVElPTi1JRi1OT1QtRk9VTkQgaXMgYSBsaXN0IG9mIGNvbW1hbmRzIHRvCitkbmwgcnVuIGl0IGlmIGl0IGlzIG5vdCBmb3VuZC4gSWYgQUNUSU9OLUlGLUZPVU5EIGlzIG5vdCBzcGVjaWZpZWQsIHRoZQorZG5sIGRlZmF1bHQgYWN0aW9uIHdpbGwgZGVmaW5lIEhBVkVfUFRIUkVBRC4KK2RubAorZG5sIFBsZWFzZSBsZXQgdGhlIGF1dGhvcnMga25vdyBpZiB0aGlzIG1hY3JvIGZhaWxzIG9uIGFueSBwbGF0Zm9ybSwgb3IKK2RubCBpZiB5b3UgaGF2ZSBhbnkgb3RoZXIgc3VnZ2VzdGlvbnMgb3IgY29tbWVudHMuIFRoaXMgbWFjcm8gd2FzIGJhc2VkCitkbmwgb24gd29yayBieSBTR0ogb24gYXV0b2NvbmYgc2NyaXB0cyBmb3IgRkZUVyAod3d3LmZmdHcub3JnKSAod2l0aAorZG5sIGhlbHAgZnJvbSBNLiBGcmlnbyksIGFzIHdlbGwgYXMgYWNfcHRocmVhZCBhbmQgaGJfcHRocmVhZCBtYWNyb3MKK2RubCBwb3N0ZWQgYnkgQWxlamFuZHJvIEZvcmVybyBDdWVydm8gdG8gdGhlIGF1dG9jb25mIG1hY3JvIHJlcG9zaXRvcnkuCitkbmwgV2UgYXJlIGFsc28gZ3JhdGVmdWwgZm9yIHRoZSBoZWxwZnVsIGZlZWRiYWNrIG9mIG51bWVyb3VzIHVzZXJzLgorZG5sCitkbmwgQGNhdGVnb3J5IEluc3RhbGxlZFBhY2thZ2VzCitkbmwgQGF1dGhvciBTdGV2ZW4gRy4gSm9obnNvbiA8c3RldmVuakBhbHVtLm1pdC5lZHU+CitkbmwgQHZlcnNpb24gMjAwNi0wNS0yOQorZG5sIEBsaWNlbnNlIEdQTFdpdGhBQ0V4Y2VwdGlvbgorZG5sIAorZG5sIENoZWNrcyBmb3IgR0NDIHNoYXJlZC9wdGhyZWFkIGluY29uc2lzdGVuY3kgYmFzZWQgb24gd29yayBieQorZG5sIE1hcmNpbiBPd3NpYW55IDxtYXJjaW5Ab3dzaWFueS5wbD4KKworCitBQ19ERUZVTihbQUNYX1BUSFJFQURdLCBbCitBQ19SRVFVSVJFKFtBQ19DQU5PTklDQUxfSE9TVF0pCitBQ19MQU5HX1NBVkUKK0FDX0xBTkdfQworYWN4X3B0aHJlYWRfb2s9bm8KKworIyBXZSB1c2VkIHRvIGNoZWNrIGZvciBwdGhyZWFkLmggZmlyc3QsIGJ1dCB0aGlzIGZhaWxzIGlmIHB0aHJlYWQuaAorIyByZXF1aXJlcyBzcGVjaWFsIGNvbXBpbGVyIGZsYWdzIChlLmcuIG9uIFRydWU2NCBvciBTZXF1ZW50KS4KKyMgSXQgZ2V0cyBjaGVja2VkIGZvciBpbiB0aGUgbGluayB0ZXN0IGFueXdheS4KKworIyBGaXJzdCBvZiBhbGwsIGNoZWNrIGlmIHRoZSB1c2VyIGhhcyBzZXQgYW55IG9mIHRoZSBQVEhSRUFEX0xJQlMsCisjIGV0Y2V0ZXJhIGVudmlyb25tZW50IHZhcmlhYmxlcywgYW5kIGlmIHRocmVhZHMgbGlua2luZyB3b3JrcyB1c2luZworIyB0aGVtOgoraWYgdGVzdCB4IiRQVEhSRUFEX0xJQlMkUFRIUkVBRF9DRkxBR1MiICE9IHg7IHRoZW4KKyAgICAgICAgc2F2ZV9DRkxBR1M9IiRDRkxBR1MiCisgICAgICAgIENGTEFHUz0iJENGTEFHUyAkUFRIUkVBRF9DRkxBR1MiCisgICAgICAgIHNhdmVfTElCUz0iJExJQlMiCisgICAgICAgIExJQlM9IiRQVEhSRUFEX0xJQlMgJExJQlMiCisgICAgICAgIEFDX01TR19DSEVDS0lORyhbZm9yIHB0aHJlYWRfam9pbiBpbiBMSUJTPSRQVEhSRUFEX0xJQlMgd2l0aCBDRkxBR1M9JFBUSFJFQURfQ0ZMQUdTXSkKKyAgICAgICAgQUNfVFJZX0xJTktfRlVOQyhwdGhyZWFkX2pvaW4sIGFjeF9wdGhyZWFkX29rPXllcykKKyAgICAgICAgQUNfTVNHX1JFU1VMVCgkYWN4X3B0aHJlYWRfb2spCisgICAgICAgIGlmIHRlc3QgeCIkYWN4X3B0aHJlYWRfb2siID0geG5vOyB0aGVuCisgICAgICAgICAgICAgICAgUFRIUkVBRF9MSUJTPSIiCisgICAgICAgICAgICAgICAgUFRIUkVBRF9DRkxBR1M9IiIKKyAgICAgICAgZmkKKyAgICAgICAgTElCUz0iJHNhdmVfTElCUyIKKyAgICAgICAgQ0ZMQUdTPSIkc2F2ZV9DRkxBR1MiCitmaQorCisjIFdlIG11c3QgY2hlY2sgZm9yIHRoZSB0aHJlYWRzIGxpYnJhcnkgdW5kZXIgYSBudW1iZXIgb2YgZGlmZmVyZW50CisjIG5hbWVzOyB0aGUgb3JkZXJpbmcgaXMgdmVyeSBpbXBvcnRhbnQgYmVjYXVzZSBzb21lIHN5c3RlbXMKKyMgKGUuZy4gREVDKSBoYXZlIGJvdGggLWxwdGhyZWFkIGFuZCAtbHB0aHJlYWRzLCB3aGVyZSBvbmUgb2YgdGhlCisjIGxpYnJhcmllcyBpcyBicm9rZW4gKG5vbi1QT1NJWCkuCisKKyMgQ3JlYXRlIGEgbGlzdCBvZiB0aHJlYWQgZmxhZ3MgdG8gdHJ5LiAgSXRlbXMgc3RhcnRpbmcgd2l0aCBhICItIiBhcmUKKyMgQyBjb21waWxlciBmbGFncywgYW5kIG90aGVyIGl0ZW1zIGFyZSBsaWJyYXJ5IG5hbWVzLCBleGNlcHQgZm9yICJub25lIgorIyB3aGljaCBpbmRpY2F0ZXMgdGhhdCB3ZSB0cnkgd2l0aG91dCBhbnkgZmxhZ3MgYXQgYWxsLCBhbmQgInB0aHJlYWQtY29uZmlnIgorIyB3aGljaCBpcyBhIHByb2dyYW0gcmV0dXJuaW5nIHRoZSBmbGFncyBmb3IgdGhlIFB0aCBlbXVsYXRpb24gbGlicmFyeS4KKworYWN4X3B0aHJlYWRfZmxhZ3M9InB0aHJlYWRzIG5vbmUgLUt0aHJlYWQgLWt0aHJlYWQgbHRocmVhZCAtcHRocmVhZCAtcHRocmVhZHMgLW10aHJlYWRzIHB0aHJlYWQgLS10aHJlYWQtc2FmZSAtbXQgcHRocmVhZC1jb25maWciCisKKyMgVGhlIG9yZGVyaW5nICppcyogKHNvbWV0aW1lcykgaW1wb3J0YW50LiAgU29tZSBub3RlcyBvbiB0aGUKKyMgaW5kaXZpZHVhbCBpdGVtcyBmb2xsb3c6CisKKyMgcHRocmVhZHM6IEFJWCAobXVzdCBjaGVjayB0aGlzIGJlZm9yZSAtbHB0aHJlYWQpCisjIG5vbmU6IGluIGNhc2UgdGhyZWFkcyBhcmUgaW4gbGliYzsgc2hvdWxkIGJlIHRyaWVkIGJlZm9yZSAtS3RocmVhZCBhbmQKKyMgICAgICAgb3RoZXIgY29tcGlsZXIgZmxhZ3MgdG8gcHJldmVudCBjb250aW51YWwgY29tcGlsZXIgd2FybmluZ3MKKyMgLUt0aHJlYWQ6IFNlcXVlbnQgKHRocmVhZHMgaW4gbGliYywgYnV0IC1LdGhyZWFkIG5lZWRlZCBmb3IgcHRocmVhZC5oKQorIyAta3RocmVhZDogRnJlZUJTRCBrZXJuZWwgdGhyZWFkcyAocHJlZmVycmVkIHRvIC1wdGhyZWFkIHNpbmNlIFNNUC1hYmxlKQorIyBsdGhyZWFkOiBMaW51eFRocmVhZHMgcG9ydCBvbiBGcmVlQlNEIChhbHNvIHByZWZlcnJlZCB0byAtcHRocmVhZCkKKyMgLXB0aHJlYWQ6IExpbnV4L2djYyAoa2VybmVsIHRocmVhZHMpLCBCU0QvZ2NjICh1c2VybGFuZCB0aHJlYWRzKQorIyAtcHRocmVhZHM6IFNvbGFyaXMvZ2NjCisjIC1tdGhyZWFkczogTWluZ3czMi9nY2MsIEx5bngvZ2NjCisjIC1tdDogU3VuIFdvcmtzaG9wIEMgKG1heSBvbmx5IGxpbmsgU3VuT1MgdGhyZWFkcyBbLWx0aHJlYWRdLCBidXQgaXQKKyMgICAgICBkb2Vzbid0IGh1cnQgdG8gY2hlY2sgc2luY2UgdGhpcyBzb21ldGltZXMgZGVmaW5lcyBwdGhyZWFkcyB0b287CisjICAgICAgYWxzbyBkZWZpbmVzIC1EX1JFRU5UUkFOVCkKKyMgICAgICAuLi4gLW10IGlzIGFsc28gdGhlIHB0aHJlYWRzIGZsYWcgZm9yIEhQL2FDQworIyBwdGhyZWFkOiBMaW51eCwgZXRjZXRlcmEKKyMgLS10aHJlYWQtc2FmZTogS0FJIEMrKworIyBwdGhyZWFkLWNvbmZpZzogdXNlIHB0aHJlYWQtY29uZmlnIHByb2dyYW0gKGZvciBHTlUgUHRoIGxpYnJhcnkpCisKK2Nhc2UgIiR7aG9zdF9jcHV9LSR7aG9zdF9vc30iIGluCisgICAgICAgICpzb2xhcmlzKikKKworICAgICAgICAjIE9uIFNvbGFyaXMgKGF0IGxlYXN0LCBmb3Igc29tZSB2ZXJzaW9ucyksIGxpYmMgY29udGFpbnMgc3R1YmJlZAorICAgICAgICAjIChub24tZnVuY3Rpb25hbCkgdmVyc2lvbnMgb2YgdGhlIHB0aHJlYWRzIHJvdXRpbmVzLCBzbyBsaW5rLWJhc2VkCisgICAgICAgICMgdGVzdHMgd2lsbCBlcnJvbmVvdXNseSBzdWNjZWVkLiAgKFdlIG5lZWQgdG8gbGluayB3aXRoIC1wdGhyZWFkcy8tbXQvCisgICAgICAgICMgLWxwdGhyZWFkLikgIChUaGUgc3R1YnMgYXJlIG1pc3NpbmcgcHRocmVhZF9jbGVhbnVwX3B1c2gsIG9yIHJhdGhlcgorICAgICAgICAjIGEgZnVuY3Rpb24gY2FsbGVkIGJ5IHRoaXMgbWFjcm8sIHNvIHdlIGNvdWxkIGNoZWNrIGZvciB0aGF0LCBidXQKKyAgICAgICAgIyB3aG8ga25vd3Mgd2hldGhlciB0aGV5J2xsIHN0dWIgdGhhdCB0b28gaW4gYSBmdXR1cmUgbGliYy4pICBTbywKKyAgICAgICAgIyB3ZSdsbCBqdXN0IGxvb2sgZm9yIC1wdGhyZWFkcyBhbmQgLWxwdGhyZWFkIGZpcnN0OgorCisgICAgICAgIGFjeF9wdGhyZWFkX2ZsYWdzPSItcHRocmVhZHMgcHRocmVhZCAtbXQgLXB0aHJlYWQgJGFjeF9wdGhyZWFkX2ZsYWdzIgorICAgICAgICA7OworZXNhYworCitpZiB0ZXN0IHgiJGFjeF9wdGhyZWFkX29rIiA9IHhubzsgdGhlbgorZm9yIGZsYWcgaW4gJGFjeF9wdGhyZWFkX2ZsYWdzOyBkbworCisgICAgICAgIGNhc2UgJGZsYWcgaW4KKyAgICAgICAgICAgICAgICBub25lKQorICAgICAgICAgICAgICAgIEFDX01TR19DSEVDS0lORyhbd2hldGhlciBwdGhyZWFkcyB3b3JrIHdpdGhvdXQgYW55IGZsYWdzXSkKKyAgICAgICAgICAgICAgICA7OworCisgICAgICAgICAgICAgICAgLSopCisgICAgICAgICAgICAgICAgQUNfTVNHX0NIRUNLSU5HKFt3aGV0aGVyIHB0aHJlYWRzIHdvcmsgd2l0aCAkZmxhZ10pCisgICAgICAgICAgICAgICAgUFRIUkVBRF9DRkxBR1M9IiRmbGFnIgorICAgICAgICAgICAgICAgIDs7CisKKwkJcHRocmVhZC1jb25maWcpCisJCUFDX0NIRUNLX1BST0coYWN4X3B0aHJlYWRfY29uZmlnLCBwdGhyZWFkLWNvbmZpZywgeWVzLCBubykKKwkJaWYgdGVzdCB4IiRhY3hfcHRocmVhZF9jb25maWciID0geG5vOyB0aGVuIGNvbnRpbnVlOyBmaQorCQlQVEhSRUFEX0NGTEFHUz0iYHB0aHJlYWQtY29uZmlnIC0tY2ZsYWdzYCIKKwkJUFRIUkVBRF9MSUJTPSJgcHRocmVhZC1jb25maWcgLS1sZGZsYWdzYCBgcHRocmVhZC1jb25maWcgLS1saWJzYCIKKwkJOzsKKworICAgICAgICAgICAgICAgICopCisgICAgICAgICAgICAgICAgQUNfTVNHX0NIRUNLSU5HKFtmb3IgdGhlIHB0aHJlYWRzIGxpYnJhcnkgLWwkZmxhZ10pCisgICAgICAgICAgICAgICAgUFRIUkVBRF9MSUJTPSItbCRmbGFnIgorICAgICAgICAgICAgICAgIDs7CisgICAgICAgIGVzYWMKKworICAgICAgICBzYXZlX0xJQlM9IiRMSUJTIgorICAgICAgICBzYXZlX0NGTEFHUz0iJENGTEFHUyIKKyAgICAgICAgTElCUz0iJFBUSFJFQURfTElCUyAkTElCUyIKKyAgICAgICAgQ0ZMQUdTPSIkQ0ZMQUdTICRQVEhSRUFEX0NGTEFHUyIKKworICAgICAgICAjIENoZWNrIGZvciB2YXJpb3VzIGZ1bmN0aW9ucy4gIFdlIG11c3QgaW5jbHVkZSBwdGhyZWFkLmgsCisgICAgICAgICMgc2luY2Ugc29tZSBmdW5jdGlvbnMgbWF5IGJlIG1hY3Jvcy4gIChPbiB0aGUgU2VxdWVudCwgd2UKKyAgICAgICAgIyBuZWVkIGEgc3BlY2lhbCBmbGFnIC1LdGhyZWFkIHRvIG1ha2UgdGhpcyBoZWFkZXIgY29tcGlsZS4pCisgICAgICAgICMgV2UgY2hlY2sgZm9yIHB0aHJlYWRfam9pbiBiZWNhdXNlIGl0IGlzIGluIC1scHRocmVhZCBvbiBJUklYCisgICAgICAgICMgd2hpbGUgcHRocmVhZF9jcmVhdGUgaXMgaW4gbGliYy4gIFdlIGNoZWNrIGZvciBwdGhyZWFkX2F0dHJfaW5pdAorICAgICAgICAjIGR1ZSB0byBERUMgY3JhemluZXNzIHdpdGggLWxwdGhyZWFkcy4gIFdlIGNoZWNrIGZvcgorICAgICAgICAjIHB0aHJlYWRfY2xlYW51cF9wdXNoIGJlY2F1c2UgaXQgaXMgb25lIG9mIHRoZSBmZXcgcHRocmVhZAorICAgICAgICAjIGZ1bmN0aW9ucyBvbiBTb2xhcmlzIHRoYXQgZG9lc24ndCBoYXZlIGEgbm9uLWZ1bmN0aW9uYWwgbGliYyBzdHViLgorICAgICAgICAjIFdlIHRyeSBwdGhyZWFkX2NyZWF0ZSBvbiBnZW5lcmFsIHByaW5jaXBsZXMuCisgICAgICAgIEFDX1RSWV9MSU5LKFsjaW5jbHVkZSA8cHRocmVhZC5oPl0sCisgICAgICAgICAgICAgICAgICAgIFtwdGhyZWFkX3QgdGg7IHB0aHJlYWRfam9pbih0aCwgMCk7CisgICAgICAgICAgICAgICAgICAgICBwdGhyZWFkX2F0dHJfaW5pdCgwKTsgcHRocmVhZF9jbGVhbnVwX3B1c2goMCwgMCk7CisgICAgICAgICAgICAgICAgICAgICBwdGhyZWFkX2NyZWF0ZSgwLDAsMCwwKTsgcHRocmVhZF9jbGVhbnVwX3BvcCgwKTsgXSwKKyAgICAgICAgICAgICAgICAgICAgW2FjeF9wdGhyZWFkX29rPXllc10pCisKKyAgICAgICAgTElCUz0iJHNhdmVfTElCUyIKKyAgICAgICAgQ0ZMQUdTPSIkc2F2ZV9DRkxBR1MiCisKKyAgICAgICAgQUNfTVNHX1JFU1VMVCgkYWN4X3B0aHJlYWRfb2spCisgICAgICAgIGlmIHRlc3QgIngkYWN4X3B0aHJlYWRfb2siID0geHllczsgdGhlbgorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICBmaQorCisgICAgICAgIFBUSFJFQURfTElCUz0iIgorICAgICAgICBQVEhSRUFEX0NGTEFHUz0iIgorZG9uZQorZmkKKworIyBWYXJpb3VzIG90aGVyIGNoZWNrczoKK2lmIHRlc3QgIngkYWN4X3B0aHJlYWRfb2siID0geHllczsgdGhlbgorICAgICAgICBzYXZlX0xJQlM9IiRMSUJTIgorICAgICAgICBMSUJTPSIkUFRIUkVBRF9MSUJTICRMSUJTIgorICAgICAgICBzYXZlX0NGTEFHUz0iJENGTEFHUyIKKyAgICAgICAgQ0ZMQUdTPSIkQ0ZMQUdTICRQVEhSRUFEX0NGTEFHUyIKKworICAgICAgICAjIERldGVjdCBBSVggbG9zc2FnZTogSk9JTkFCTEUgYXR0cmlidXRlIGlzIGNhbGxlZCBVTkRFVEFDSEVELgorCUFDX01TR19DSEVDS0lORyhbZm9yIGpvaW5hYmxlIHB0aHJlYWQgYXR0cmlidXRlXSkKKwlhdHRyX25hbWU9dW5rbm93bgorCWZvciBhdHRyIGluIFBUSFJFQURfQ1JFQVRFX0pPSU5BQkxFIFBUSFJFQURfQ1JFQVRFX1VOREVUQUNIRUQ7IGRvCisJICAgIEFDX1RSWV9MSU5LKFsjaW5jbHVkZSA8cHRocmVhZC5oPl0sIFtpbnQgYXR0cj0kYXR0cjsgcmV0dXJuIGF0dHI7XSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyX25hbWU9JGF0dHI7IGJyZWFrXSkKKwlkb25lCisgICAgICAgIEFDX01TR19SRVNVTFQoJGF0dHJfbmFtZSkKKyAgICAgICAgaWYgdGVzdCAiJGF0dHJfbmFtZSIgIT0gUFRIUkVBRF9DUkVBVEVfSk9JTkFCTEU7IHRoZW4KKyAgICAgICAgICAgIEFDX0RFRklORV9VTlFVT1RFRChQVEhSRUFEX0NSRUFURV9KT0lOQUJMRSwgJGF0dHJfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbRGVmaW5lIHRvIG5lY2Vzc2FyeSBzeW1ib2wgaWYgdGhpcyBjb25zdGFudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VzIGEgbm9uLXN0YW5kYXJkIG5hbWUgb24geW91ciBzeXN0ZW0uXSkKKyAgICAgICAgZmkKKworICAgICAgICBBQ19NU0dfQ0hFQ0tJTkcoW2lmIG1vcmUgc3BlY2lhbCBmbGFncyBhcmUgcmVxdWlyZWQgZm9yIHB0aHJlYWRzXSkKKyAgICAgICAgZmxhZz1ubworICAgICAgICBjYXNlICIke2hvc3RfY3B1fS0ke2hvc3Rfb3N9IiBpbgorICAgICAgICAgICAgKi1haXgqIHwgKi1mcmVlYnNkKiB8ICotZGFyd2luKikgZmxhZz0iLURfVEhSRUFEX1NBRkUiOzsKKyAgICAgICAgICAgICpzb2xhcmlzKiB8ICotb3NmKiB8ICotaHB1eCopIGZsYWc9Ii1EX1JFRU5UUkFOVCI7OworICAgICAgICBlc2FjCisgICAgICAgIEFDX01TR19SRVNVTFQoJHtmbGFnfSkKKyAgICAgICAgaWYgdGVzdCAieCRmbGFnIiAhPSB4bm87IHRoZW4KKyAgICAgICAgICAgIFBUSFJFQURfQ0ZMQUdTPSIkZmxhZyAkUFRIUkVBRF9DRkxBR1MiCisgICAgICAgIGZpCisKKyAgICAgICAgTElCUz0iJHNhdmVfTElCUyIKKyAgICAgICAgQ0ZMQUdTPSIkc2F2ZV9DRkxBR1MiCisgICAgICAgICMgTW9yZSBBSVggbG9zc2FnZTogbXVzdCBjb21waWxlIHdpdGggeGxjX3Igb3IgY2NfcgorCWlmIHRlc3QgeCIkR0NDIiAhPSB4eWVzOyB0aGVuCisgICAgICAgICAgQUNfQ0hFQ0tfUFJPR1MoUFRIUkVBRF9DQywgeGxjX3IgY2NfciwgJHtDQ30pCisgICAgICAgIGVsc2UKKyAgICAgICAgICBQVEhSRUFEX0NDPSRDQworCWZpCisKKwkjIFRoZSBuZXh0IHBhcnQgdHJpZXMgdG8gZGV0ZWN0IEdDQyBpbmNvbnNpc3RlbmN5IHdpdGggLXNoYXJlZCBvbiBzb21lCisJIyBhcmNoaXRlY3R1cmVzIGFuZCBzeXN0ZW1zLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGluIGNlcnRhaW4KKwkjIGNvbmZpZ3VyYXRpb25zLCB3aGVuIC1zaGFyZWQgaXMgc3BlY2lmaWVkLCBHQ0MgImZvcmdldHMiIHRvCisJIyBpbnRlcm5hbGx5IHVzZSB2YXJpb3VzIGZsYWdzIHdoaWNoIGFyZSBzdGlsbCBuZWNlc3NhcnkuCisJCisJIworCSMgUHJlcGFyZSB0aGUgZmxhZ3MKKwkjCisJc2F2ZV9DRkxBR1M9IiRDRkxBR1MiCisJc2F2ZV9MSUJTPSIkTElCUyIKKwlzYXZlX0NDPSIkQ0MiCisJCisJIyBUcnkgd2l0aCB0aGUgZmxhZ3MgZGV0ZXJtaW5lZCBieSB0aGUgZWFybGllciBjaGVja3MuCisJIworCSMgLVdsLC16LGRlZnMgZm9yY2VzIGxpbmstdGltZSBzeW1ib2wgcmVzb2x1dGlvbiwgc28gdGhhdCB0aGUKKwkjIGxpbmtpbmcgY2hlY2tzIHdpdGggLXNoYXJlZCBhY3R1YWxseSBoYXZlIGFueSB2YWx1ZQorCSMKKwkjIEZJWE1FOiAtZlBJQyBpcyByZXF1aXJlZCBmb3IgLXNoYXJlZCBvbiBtYW55IGFyY2hpdGVjdHVyZXMsCisJIyBzbyB3ZSBzcGVjaWZ5IGl0IGhlcmUsIGJ1dCB0aGUgcmlnaHQgd2F5IHdvdWxkIHByb2JhYmx5IGJlIHRvCisJIyBwcm9wZXJseSBkZXRlY3Qgd2hldGhlciBpdCBpcyBhY3R1YWxseSByZXF1aXJlZC4KKwlDRkxBR1M9Ii1zaGFyZWQgLWZQSUMgLVdsLC16LGRlZnMgJENGTEFHUyAkUFRIUkVBRF9DRkxBR1MiCisJTElCUz0iJFBUSFJFQURfTElCUyAkTElCUyIKKwlDQz0iJFBUSFJFQURfQ0MiCisJCisJIyBJbiBvcmRlciBub3QgdG8gY3JlYXRlIHNldmVyYWwgbGV2ZWxzIG9mIGluZGVudGF0aW9uLCB3ZSB0ZXN0CisJIyB0aGUgdmFsdWUgb2YgIiRkb25lIiB1bnRpbCB3ZSBmaW5kIHRoZSBjdXJlIG9yIHJ1biBvdXQgb2YgaWRlYXMuCisJZG9uZT0ibm8iCisJCisJIyBGaXJzdCwgbWFrZSBzdXJlIHRoZSBDRkxBR1Mgd2UgYWRkZWQgYXJlIGFjdHVhbGx5IGFjY2VwdGVkIGJ5IG91cgorCSMgY29tcGlsZXIuICBJZiBub3QgKGFuZCBPUyBYJ3MgbGQsIGZvciBpbnN0YW5jZSwgZG9lcyBub3QgYWNjZXB0IC16KSwKKwkjIHRoZW4gd2UgY2FuJ3QgZG8gdGhpcyB0ZXN0LgorCWlmIHRlc3QgeCIkZG9uZSIgPSB4bm87IHRoZW4KKwkgICBBQ19NU0dfQ0hFQ0tJTkcoW3doZXRoZXIgdG8gY2hlY2sgZm9yIEdDQyBwdGhyZWFkL3NoYXJlZCBpbmNvbnNpc3RlbmNpZXNdKQorCSAgIEFDX1RSWV9MSU5LKCwsICwgW2RvbmU9eWVzXSkKKwkKKwkgICBpZiB0ZXN0ICJ4JGRvbmUiID0geHllcyA7IHRoZW4KKwkgICAgICBBQ19NU0dfUkVTVUxUKFtub10pCisJICAgZWxzZQorCSAgICAgIEFDX01TR19SRVNVTFQoW3llc10pCisJICAgZmkKKwlmaQorCQorCWlmIHRlc3QgeCIkZG9uZSIgPSB4bm87IHRoZW4KKwkgICBBQ19NU0dfQ0hFQ0tJTkcoW3doZXRoZXIgLXB0aHJlYWQgaXMgc3VmZmljaWVudCB3aXRoIC1zaGFyZWRdKQorCSAgIEFDX1RSWV9MSU5LKFsjaW5jbHVkZSA8cHRocmVhZC5oPl0sCisJICAgICAgW3B0aHJlYWRfdCB0aDsgcHRocmVhZF9qb2luKHRoLCAwKTsKKwkgICAgICBwdGhyZWFkX2F0dHJfaW5pdCgwKTsgcHRocmVhZF9jbGVhbnVwX3B1c2goMCwgMCk7CisJICAgICAgcHRocmVhZF9jcmVhdGUoMCwwLDAsMCk7IHB0aHJlYWRfY2xlYW51cF9wb3AoMCk7IF0sCisJICAgICAgW2RvbmU9eWVzXSkKKwkgICAKKwkgICBpZiB0ZXN0ICJ4JGRvbmUiID0geHllczsgdGhlbgorCSAgICAgIEFDX01TR19SRVNVTFQoW3llc10pCisJICAgZWxzZQorCSAgICAgIEFDX01TR19SRVNVTFQoW25vXSkKKwkgICBmaQorCWZpCisJCisJIworCSMgTGludXggZ2NjIG9uIHNvbWUgYXJjaGl0ZWN0dXJlcyBzdWNoIGFzIG1pcHMvbWlwc2VsIGZvcmdldHMKKwkjIGFib3V0IC1scHRocmVhZAorCSMKKwlpZiB0ZXN0IHgiJGRvbmUiID0geG5vOyB0aGVuCisJICAgQUNfTVNHX0NIRUNLSU5HKFt3aGV0aGVyIC1scHRocmVhZCBmaXhlcyB0aGF0XSkKKwkgICBMSUJTPSItbHB0aHJlYWQgJFBUSFJFQURfTElCUyAkc2F2ZV9MSUJTIgorCSAgIEFDX1RSWV9MSU5LKFsjaW5jbHVkZSA8cHRocmVhZC5oPl0sCisJICAgICAgW3B0aHJlYWRfdCB0aDsgcHRocmVhZF9qb2luKHRoLCAwKTsKKwkgICAgICBwdGhyZWFkX2F0dHJfaW5pdCgwKTsgcHRocmVhZF9jbGVhbnVwX3B1c2goMCwgMCk7CisJICAgICAgcHRocmVhZF9jcmVhdGUoMCwwLDAsMCk7IHB0aHJlYWRfY2xlYW51cF9wb3AoMCk7IF0sCisJICAgICAgW2RvbmU9eWVzXSkKKwkKKwkgICBpZiB0ZXN0ICJ4JGRvbmUiID0geHllczsgdGhlbgorCSAgICAgIEFDX01TR19SRVNVTFQoW3llc10pCisJICAgICAgUFRIUkVBRF9MSUJTPSItbHB0aHJlYWQgJFBUSFJFQURfTElCUyIKKwkgICBlbHNlCisJICAgICAgQUNfTVNHX1JFU1VMVChbbm9dKQorCSAgIGZpCisJZmkKKwkjCisJIyBGcmVlQlNEIDQuMTAgZ2NjIGZvcmdldHMgdG8gdXNlIC1sY19yIGluc3RlYWQgb2YgLWxjCisJIworCWlmIHRlc3QgeCIkZG9uZSIgPSB4bm87IHRoZW4KKwkgICBBQ19NU0dfQ0hFQ0tJTkcoW3doZXRoZXIgLWxjX3IgZml4ZXMgdGhhdF0pCisJICAgTElCUz0iLWxjX3IgJFBUSFJFQURfTElCUyAkc2F2ZV9MSUJTIgorCSAgIEFDX1RSWV9MSU5LKFsjaW5jbHVkZSA8cHRocmVhZC5oPl0sCisJICAgICAgIFtwdGhyZWFkX3QgdGg7IHB0aHJlYWRfam9pbih0aCwgMCk7CisJICAgICAgICBwdGhyZWFkX2F0dHJfaW5pdCgwKTsgcHRocmVhZF9jbGVhbnVwX3B1c2goMCwgMCk7CisJICAgICAgICBwdGhyZWFkX2NyZWF0ZSgwLDAsMCwwKTsgcHRocmVhZF9jbGVhbnVwX3BvcCgwKTsgXSwKKwkgICAgICAgW2RvbmU9eWVzXSkKKwkKKwkgICBpZiB0ZXN0ICJ4JGRvbmUiID0geHllczsgdGhlbgorCSAgICAgIEFDX01TR19SRVNVTFQoW3llc10pCisJICAgICAgUFRIUkVBRF9MSUJTPSItbGNfciAkUFRIUkVBRF9MSUJTIgorCSAgIGVsc2UKKwkgICAgICBBQ19NU0dfUkVTVUxUKFtub10pCisJICAgZmkKKwlmaQorCWlmIHRlc3QgeCIkZG9uZSIgPSB4bm87IHRoZW4KKwkgICAjIE9LLCB3ZSBoYXZlIHJ1biBvdXQgb2YgaWRlYXMKKwkgICBBQ19NU0dfV0FSTihbSW1wb3NzaWJsZSB0byBkZXRlcm1pbmUgaG93IHRvIHVzZSBwdGhyZWFkcyB3aXRoIHNoYXJlZCBsaWJyYXJpZXNdKQorCQorCSAgICMgc28gaXQncyBub3Qgc2FmZSB0byBhc3N1bWUgdGhhdCB3ZSBtYXkgdXNlIHB0aHJlYWRzCisJICAgYWN4X3B0aHJlYWRfb2s9bm8KKwlmaQorCQorCUFDX01TR19DSEVDS0lORyhbd2hldGhlciB3aGF0IHdlIGhhdmUgc28gZmFyIGlzIHN1ZmZpY2llbnQgd2l0aCAtbm9zdGRsaWJdKQorCUNGTEFHUz0iLW5vc3RkbGliICRDRkxBR1MiCisJIyB3ZSBuZWVkIGMgd2l0aCBub3N0ZGxpYgorCUxJQlM9IiRMSUJTIC1sYyIKKwlBQ19UUllfTElOSyhbI2luY2x1ZGUgPHB0aHJlYWQuaD5dLAorCSAgICAgIFtwdGhyZWFkX3QgdGg7IHB0aHJlYWRfam9pbih0aCwgMCk7CisJICAgICAgIHB0aHJlYWRfYXR0cl9pbml0KDApOyBwdGhyZWFkX2NsZWFudXBfcHVzaCgwLCAwKTsKKwkgICAgICAgcHRocmVhZF9jcmVhdGUoMCwwLDAsMCk7IHB0aHJlYWRfY2xlYW51cF9wb3AoMCk7IF0sCisJICAgICAgW2RvbmU9eWVzXSxbZG9uZT1ub10pCisKKwlpZiB0ZXN0ICJ4JGRvbmUiID0geHllczsgdGhlbgorCSAgIEFDX01TR19SRVNVTFQoW3llc10pCisJZWxzZQorCSAgIEFDX01TR19SRVNVTFQoW25vXSkKKwlmaQorCQorCWlmIHRlc3QgeCIkZG9uZSIgPSB4bm87IHRoZW4KKwkgICBBQ19NU0dfQ0hFQ0tJTkcoW3doZXRoZXIgLWxwdGhyZWFkIHNhdmVzIHRoZSBkYXldKQorCSAgIExJQlM9Ii1scHRocmVhZCAkTElCUyIKKwkgICBBQ19UUllfTElOSyhbI2luY2x1ZGUgPHB0aHJlYWQuaD5dLAorCSAgICAgIFtwdGhyZWFkX3QgdGg7IHB0aHJlYWRfam9pbih0aCwgMCk7CisJICAgICAgIHB0aHJlYWRfYXR0cl9pbml0KDApOyBwdGhyZWFkX2NsZWFudXBfcHVzaCgwLCAwKTsKKwkgICAgICAgcHRocmVhZF9jcmVhdGUoMCwwLDAsMCk7IHB0aHJlYWRfY2xlYW51cF9wb3AoMCk7IF0sCisJICAgICAgW2RvbmU9eWVzXSxbZG9uZT1ub10pCisKKwkgICBpZiB0ZXN0ICJ4JGRvbmUiID0geHllczsgdGhlbgorCSAgICAgIEFDX01TR19SRVNVTFQoW3llc10pCisJICAgICAgUFRIUkVBRF9MSUJTPSIkUFRIUkVBRF9MSUJTIC1scHRocmVhZCIKKwkgICBlbHNlCisJICAgICAgQUNfTVNHX1JFU1VMVChbbm9dKQorCSAgICAgIEFDX01TR19XQVJOKFtJbXBvc3NpYmxlIHRvIGRldGVybWluZSBob3cgdG8gdXNlIHB0aHJlYWRzIHdpdGggc2hhcmVkIGxpYnJhcmllcyBhbmQgLW5vc3RkbGliXSkKKwkgICBmaQorCWZpCisKKwlDRkxBR1M9IiRzYXZlX0NGTEFHUyIKKwlMSUJTPSIkc2F2ZV9MSUJTIgorCUNDPSIkc2F2ZV9DQyIKK2Vsc2UKKyAgICAgICAgUFRIUkVBRF9DQz0iJENDIgorZmkKKworQUNfU1VCU1QoUFRIUkVBRF9MSUJTKQorQUNfU1VCU1QoUFRIUkVBRF9DRkxBR1MpCitBQ19TVUJTVChQVEhSRUFEX0NDKQorCisjIEZpbmFsbHksIGV4ZWN1dGUgQUNUSU9OLUlGLUZPVU5EL0FDVElPTi1JRi1OT1QtRk9VTkQ6CitpZiB0ZXN0IHgiJGFjeF9wdGhyZWFkX29rIiA9IHh5ZXM7IHRoZW4KKyAgICAgICAgaWZlbHNlKFskMV0sLEFDX0RFRklORShIQVZFX1BUSFJFQUQsMSxbRGVmaW5lIGlmIHlvdSBoYXZlIFBPU0lYIHRocmVhZHMgbGlicmFyaWVzIGFuZCBoZWFkZXIgZmlsZXMuXSksWyQxXSkKKyAgICAgICAgOgorZWxzZQorICAgICAgICBhY3hfcHRocmVhZF9vaz1ubworICAgICAgICAkMgorZmkKK0FDX0xBTkdfUkVTVE9SRQorXSlkbmwgQUNYX1BUSFJFQUQKZGlmZiAtLWdpdCBhL200L3N0bF9oYXNoLm00IGIvbTQvc3RsX2hhc2gubTQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDcyMmIxNAotLS0gL2Rldi9udWxsCisrKyBiL200L3N0bF9oYXNoLm00CkBAIC0wLDAgKzEsNzIgQEAKKyMgV2UgY2hlY2sgdHdvIHRoaW5nczogd2hlcmUgdGhlIGluY2x1ZGUgZmlsZSBpcyBmb3IKKyMgdW5vcmRlcmVkX21hcC9oYXNoX21hcCAod2UgcHJlZmVyIHRoZSBmaXJzdCBmb3JtKSwgYW5kIHdoYXQKKyMgbmFtZXNwYWNlIHVub3JkZXJlZC9oYXNoX21hcCBsaXZlcyBpbiB3aXRoaW4gdGhhdCBpbmNsdWRlIGZpbGUuICBXZQorIyBpbmNsdWRlIEFDX1RSWV9DT01QSUxFIGZvciBhbGwgdGhlIGNvbWJpbmF0aW9ucyB3ZSd2ZSBzZWVuIGluIHRoZQorIyB3aWxkLiAgV2UgZGVmaW5lIEhBU0hfTUFQX0ggdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBoZWFkZXIgZmlsZSwgYW5kCisjIEhBU0hfTkFNRVNQQUNFIHRvIHRoZSBuYW1lc3BhY2UgdGhlIGNsYXNzICh1bm9yZGVyZWRfbWFwIG9yCisjIGhhc2hfbWFwKSBpcyBpbi4gIFdlIGRlZmluZSBIQVZFX1VOT1JERVJFRF9NQVAgaWYgdGhlIGNsYXNzIHdlIGZvdW5kCisjIGlzIG5hbWVkIHVub3JkZXJlZF9tYXAsIG9yIGxlYXZlIGl0IHVuZGVmaW5lZCBpZiBub3QuCisKKyMgVGhpcyBhbHNvIGNoZWNrcyBpZiB1bm9yZGVyZWQgbWFwIGV4aXN0cy4KK0FDX0RFRlVOKFtBQ19DWFhfU1RMX0hBU0hdLAorICBbCisgICBBQ19NU0dfQ0hFQ0tJTkcodGhlIGxvY2F0aW9uIG9mIGhhc2hfbWFwKQorICAgQUNfTEFOR19TQVZFCisgICBBQ19MQU5HX0NQTFVTUExVUworICAgYWNfY3ZfY3h4X2hhc2hfbWFwPSIiCisgICAjIEZpcnN0IHRyeSB1bm9yZGVyZWRfbWFwLCBidXQgbm90IG9uIGdjYydzIGJlZm9yZSA0LjIgLS0gSSd2ZQorICAgIyBzZWVuIHVuZXhwbGFpbmFibGUgdW5vcmRlcmVkX21hcCBidWdzIHdpdGggLU8yIG9uIG9sZGVyIGdjYydzLgorICAgQUNfVFJZX0NPTVBJTEUoWyNpZiBkZWZpbmVkKF9fR05VQ19fKSAmJiAoX19HTlVDX18gPCA0IHx8IChfX0dOVUNfXyA9PSA0ICYmIF9fR05VQ19NSU5PUl9fIDwgMikpCisgICAgICAgICAgICAgICAgICAgIyBlcnJvciBHQ0MgdG9vIG9sZCBmb3IgdW5vcmRlcmVkX21hcAorICAgICAgICAgICAgICAgICAgICNlbmRpZgorICAgICAgICAgICAgICAgICAgIF0sCisgICAgICAgICAgICAgICAgICAgWy8qIG5vIHByb2dyYW0gYm9keSBuZWNlc3NhcnkgKi9dLAorICAgICAgICAgICAgICAgICAgIFtzdGxfaGFzaF9vbGRfZ2NjPW5vXSwKKyAgICAgICAgICAgICAgICAgICBbc3RsX2hhc2hfb2xkX2djYz15ZXNdKQorICAgZm9yIGxvY2F0aW9uIGluIHVub3JkZXJlZF9tYXAgdHIxL3Vub3JkZXJlZF9tYXA7IGRvCisgICAgIGZvciBuYW1lc3BhY2UgaW4gc3RkIHN0ZDo6dHIxOyBkbworICAgICAgIGlmIHRlc3QgLXogIiRhY19jdl9jeHhfaGFzaF9tYXAiIC1hICIkc3RsX2hhc2hfb2xkX2djYyIgIT0geWVzOyB0aGVuCisgICAgICAgICAjIFNvbWUgb2xkZXIgZ2NjJ3MgaGF2ZSBhIGJ1Z2d5IHRyMSwgc28gdGVzdCBhIGJpdCBvZiBjb2RlLgorICAgICAgICAgQUNfVFJZX0NPTVBJTEUoWyNpbmNsdWRlIDwkbG9jYXRpb24+XSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFtjb25zdCAke25hbWVzcGFjZX06OnVub3JkZXJlZF9tYXA8aW50LCBpbnQ+IHQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQuZmluZCg1KSA9PSB0LmVuZCgpO10sCisgICAgICAgICAgICAgICAgICAgICAgICBbYWNfY3ZfY3h4X2hhc2hfbWFwPSI8JGxvY2F0aW9uPiI7CisgICAgICAgICAgICAgICAgICAgICAgICAgYWNfY3ZfY3h4X2hhc2hfbmFtZXNwYWNlPSIkbmFtZXNwYWNlIjsKKyAgICAgICAgICAgICAgICAgICAgICAgICBhY19jdl9jeHhfaGFzaF9tYXBfY2xhc3M9InVub3JkZXJlZF9tYXAiO10pCisgICAgICAgZmkKKyAgICAgZG9uZQorICAgZG9uZQorICAgIyBOb3cgdHJ5IGhhc2hfbWFwCisgICBmb3IgbG9jYXRpb24gaW4gZXh0L2hhc2hfbWFwIGhhc2hfbWFwOyBkbworICAgICBmb3IgbmFtZXNwYWNlIGluIF9fZ251X2N4eCAiIiBzdGQgc3RkZXh0OyBkbworICAgICAgIGlmIHRlc3QgLXogIiRhY19jdl9jeHhfaGFzaF9tYXAiOyB0aGVuCisgICAgICAgICBBQ19UUllfQ09NUElMRShbI2luY2x1ZGUgPCRsb2NhdGlvbj5dLAorICAgICAgICAgICAgICAgICAgICAgICAgWyR7bmFtZXNwYWNlfTo6aGFzaF9tYXA8aW50LCBpbnQ+IHRdLAorICAgICAgICAgICAgICAgICAgICAgICAgW2FjX2N2X2N4eF9oYXNoX21hcD0iPCRsb2NhdGlvbj4iOworICAgICAgICAgICAgICAgICAgICAgICAgIGFjX2N2X2N4eF9oYXNoX25hbWVzcGFjZT0iJG5hbWVzcGFjZSI7CisgICAgICAgICAgICAgICAgICAgICAgICAgYWNfY3ZfY3h4X2hhc2hfbWFwX2NsYXNzPSJoYXNoX21hcCI7XSkKKyAgICAgICBmaQorICAgICBkb25lCisgICBkb25lCisgICBhY19jdl9jeHhfaGFzaF9zZXQ9YGVjaG8gIiRhY19jdl9jeHhfaGFzaF9tYXAiIHwgc2VkIHMvbWFwL3NldC9gOworICAgYWNfY3ZfY3h4X2hhc2hfc2V0X2NsYXNzPWBlY2hvICIkYWNfY3ZfY3h4X2hhc2hfbWFwX2NsYXNzIiB8IHNlZCBzL21hcC9zZXQvYDsKKyAgIGlmIHRlc3QgLW4gIiRhY19jdl9jeHhfaGFzaF9tYXAiOyB0aGVuCisgICAgICBBQ19ERUZJTkUoSEFWRV9IQVNIX01BUCwgMSwgW2RlZmluZSBpZiB0aGUgY29tcGlsZXIgaGFzIGhhc2hfbWFwXSkKKyAgICAgIEFDX0RFRklORShIQVZFX0hBU0hfU0VULCAxLCBbZGVmaW5lIGlmIHRoZSBjb21waWxlciBoYXMgaGFzaF9zZXRdKQorICAgICAgQUNfREVGSU5FX1VOUVVPVEVEKEhBU0hfTUFQX0gsJGFjX2N2X2N4eF9oYXNoX21hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBbdGhlIGxvY2F0aW9uIG9mIDx1bm9yZGVyZWRfbWFwPiBvciA8aGFzaF9tYXA+XSkKKyAgICAgIEFDX0RFRklORV9VTlFVT1RFRChIQVNIX1NFVF9ILCRhY19jdl9jeHhfaGFzaF9zZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgW3RoZSBsb2NhdGlvbiBvZiA8dW5vcmRlcmVkX3NldD4gb3IgPGhhc2hfc2V0Pl0pCisgICAgICBBQ19ERUZJTkVfVU5RVU9URUQoSEFTSF9OQU1FU1BBQ0UsJGFjX2N2X2N4eF9oYXNoX25hbWVzcGFjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBbdGhlIG5hbWVzcGFjZSBvZiBoYXNoX21hcC9oYXNoX3NldF0pCisgICAgICBBQ19ERUZJTkVfVU5RVU9URUQoSEFTSF9NQVBfQ0xBU1MsJGFjX2N2X2N4eF9oYXNoX21hcF9jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICBbdGhlIG5hbWUgb2YgPGhhc2hfbWFwPl0pCisgICAgICBBQ19ERUZJTkVfVU5RVU9URUQoSEFTSF9TRVRfQ0xBU1MsJGFjX2N2X2N4eF9oYXNoX3NldF9jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICBbdGhlIG5hbWUgb2YgPGhhc2hfc2V0Pl0pCisgICAgICBBQ19NU0dfUkVTVUxUKFskYWNfY3ZfY3h4X2hhc2hfbWFwXSkKKyAgIGVsc2UKKyAgICAgIEFDX01TR19SRVNVTFQoKQorICAgICAgQUNfTVNHX1dBUk4oW2NvdWxkIG5vdCBmaW5kIGFuIFNUTCBoYXNoX21hcF0pCisgICBmaQorXSkKKwpkaWZmIC0tZ2l0IGEvbW9yZV90ZXN0cy9NYWtlZmlsZSBiL21vcmVfdGVzdHMvTWFrZWZpbGUKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMjg2Y2YwZgotLS0gL2Rldi9udWxsCisrKyBiL21vcmVfdGVzdHMvTWFrZWZpbGUKQEAgLTAsMCArMSw0MSBAQAorIyBBZGRpdGlvbmFsIHRlc3RzIHRvIHJ1biBiZWZvcmUgcmVsZWFzaW5nIGEgcGFja2FnZS4KKyMKKyMgUnVuIGxpa2U6CisjICAgbWFrZSBQQUNLQUdFPS9wYXRoL3RvL3Byb3RvYnVmLVZFUlNJT04udGFyLmd6CisjCisjIFNvbWUgb2YgdGhlc2UgdGVzdHMgcmVxdWlyZSB0b29scyBvciBtYWtlIGFzc3VtcHRpb25zIHRoYXQgbWF5IG5vdCBiZQorIyBhdmFpbGFibGUgb24gZW5kLXVzZXIgbWFjaGluZXMsIHNvIHRoZXNlIGNhbm5vdCBiZSBwYXJ0IG9mICJtYWtlIGNoZWNrIi4gIEZvcgorIyBleGFtcGxlLCB3ZSB0ZXN0IHRoYXQgdGhlIGhlYWRlcnMgY29tcGlsZSB3aXRoIHN0cmljdCB3YXJuaW5nIHNldHRpbmdzLCBidXQKKyMgc2luY2UgZGlmZmVyZW50IGNvbXBpbGVycyBwcm9kdWNlIHdpbGRseSBkaWZmZXJlbnQgd2FybmluZ3Mgd2UgY2Fubm90IGFzc3VtZQorIyB0aGF0IHRoaXMgdGVzdCB3aWxsIHBhc3MgZXZlcnl3aGVyZS4gIElmIHdlIHJhbiBpdCBhcyBwYXJ0IG9mICJtYWtlIGNoZWNrIiwKKyMgaXQgY291bGQgdW5uZWNlc3NhcmlseSBibG9jayB1c2VycyBmcm9tIHJ1bm5pbmcgdGhlIHJlYWwgdGVzdHMganVzdCBiZWNhdXNlCisjIHRoZWlyIGNvbXBpbGVyIHByb2R1Y2VzIHNvbWUgZXh0cmEgd2FybmluZ3MgdGhhdCBwcm9iYWJseSBhcmVuJ3QgYSBiaWcgZGVhbC4KKyMgU28gd2UgcnVuIGl0IHNlcGFyYXRlbHkuIAorCithbGw6IGhlYWRlcl93YXJuaW5nX3Rlc3QKKworY2xlYW46CisJcm0gLXJmIHNyYyB0YXJnZXQgaGVhZGVyX3dhcm5pbmdfdGVzdC5jYyBoZWFkZXJfd2FybmluZ190ZXN0Lm8gaGVhZGVyX3dhcm5pbmdfdGVzdAorCisjIFVucGFjayB0aGUgcGFja2FnZSBpbnRvIHNyYywgdGhlbiBpbnN0YWxsIGl0IGludG8gdGFyZ2V0LgorUEFDS0FHRT1wcm90b2J1Zi50YXIuZ3oKKworc3JjOiAkKFBBQ0tBR0UpCisJdGFyIHp4dmYgJChQQUNLQUdFKQorCW12IGBiYXNlbmFtZSAkKFBBQ0tBR0UpIC50YXIuZ3pgIHNyYworCit0YXJnZXQ6IHNyYworCShjZCBzcmMgJiYgLi9jb25maWd1cmUgLS1wcmVmaXg9JCRQV0QvLi4vdGFyZ2V0IC0tZGlzYWJsZS1zaGFyZWQpCisJKGNkIHNyYyAmJiBtYWtlIC1qNCBjaGVjaykKKwkoY2Qgc3JjICYmIG1ha2UgaW5zdGFsbCkKKworIyBWZXJpZnkgdGhhdCBoZWFkZXJzIHByb2R1Y2Ugbm8gd2FybmluZ3MgZXZlbiB1bmRlciBzdHJpY3Qgc2V0dGluZ3MuCitoZWFkZXJfd2FybmluZ190ZXN0LmNjOiB0YXJnZXQKKwkoIChjZCB0YXJnZXQvaW5jbHVkZSAmJiBmaW5kIGdvb2dsZS9wcm90b2J1ZiAtbmFtZSAnKi5oJykgfCBcCisJICBhd2sgJ3twcmludCAiI2luY2x1ZGUgXCIiJCQxIlwiIn0gJyA+IGhlYWRlcl93YXJuaW5nX3Rlc3QuY2MgKQorCitoZWFkZXJfd2FybmluZ190ZXN0OiBoZWFkZXJfd2FybmluZ190ZXN0LmNjCisJIyBUT0RPKGtlbnRvbik6ICBDb25zaWRlciBhZGRpbmcgLXBlZGFudGljIGFuZCAtV2VmZmMrKy4gIEN1cnJlbnRseSB0aGVzZQorCSMgICBwcm9kdWNlIHRvbnMgb2YgZXh0cmEgd2FybmluZ3Mgc28gd2UnbGwgbmVlZCB0byBkbyBzb21lIHdvcmsgZmlyc3QuCisJZysrIC1JdGFyZ2V0L2luY2x1ZGUgLVdhbGwgLVdlcnJvciAtV3NpZ24tY29tcGFyZSAtTzIgLWMgaGVhZGVyX3dhcm5pbmdfdGVzdC5jYworCXRvdWNoIGhlYWRlcl93YXJuaW5nX3Rlc3QKZGlmZiAtLWdpdCBhL3Bvc3RfcHJvY2Vzc19kaXN0LnNoIGIvcG9zdF9wcm9jZXNzX2Rpc3Quc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uM2MwMWVkOAotLS0gL2Rldi9udWxsCisrKyBiL3Bvc3RfcHJvY2Vzc19kaXN0LnNoCkBAIC0wLDAgKzEsNjggQEAKKyMhIC9iaW4vc2gKKworIyBUaGlzIHNjcmlwdCB0YWtlcyB0aGUgcmVzdWx0IG9mICJtYWtlIGRpc3QiIGFuZDoKKyMgMSkgVW5wYWNrcyBpdC4KKyMgMikgRW5zdXJlcyBhbGwgY29udGVudHMgYXJlIHVzZXItd3JpdGFibGUuICBTb21lIHZlcnNpb24gY29udHJvbCBzeXN0ZW1zCisjICAgIGtlZXAgY29kZSByZWFkLW9ubHkgdW50aWwgeW91IGV4cGxpY2l0bHkgYXNrIHRvIGVkaXQgaXQsIGFuZCB0aGUgbm9ybWFsCisjICAgICJtYWtlIGRpc3QiIHByb2Nlc3MgZG9lcyBub3QgY29ycmVjdCBmb3IgdGhpcywgc28gdGhlIHJlc3VsdCBpcyB0aGF0CisjICAgIHRoZSBlbnRpcmUgZGlzdCBpcyBzdGlsbCBtYXJrZWQgcmVhZC1vbmx5IHdoZW4gdW5wYWNrZWQsIHdoaWNoIGlzCisjICAgIGFubm95aW5nLiAgU28sIHdlIGZpeCBpdC4KKyMgMykgQ29udmVydCBNU1ZDIHByb2plY3QgZmlsZXMgdG8gTVNWQyAyMDA1LCBzbyB0aGF0IGFueW9uZSB3aG8gaGFzIHZlcnNpb24KKyMgICAgMjAwNSAqb3IqIDIwMDggY2FuIG9wZW4gdGhlbS4gIChJbiB2ZXJzaW9uIGNvbnRyb2wsIHdlIGtlZXAgdGhpbmdzIGluCisjICAgIE1TVkMgMjAwOCBmb3JtYXQgc2luY2UgdGhhdCdzIHdoYXQgd2UgdXNlIGluIGRldmVsb3BtZW50LikKKyMgNCkgVXNlcyB0aGUgcmVzdWx0IHRvIGNyZWF0ZSAudGFyLmd6LCAudGFyLmJ6MiwgYW5kIC56aXAgdmVyc2lvbnMgYW5kCisjICAgIGRlcG9zaXRlcyB0aGVtIGluIHRoZSAiZGlzdCIgZGlyZWN0b3J5LiAgSW4gdGhlIC56aXAgdmVyc2lvbiwgYWxsCisjICAgIG5vbi10ZXN0ZGF0YSAudHh0IGZpbGVzIGFyZSBjb252ZXJ0ZWQgdG8gV2luZG93cy1zdHlsZSBsaW5lIGVuZGluZ3MuCisjIDUpIENsZWFucyB1cCBhZnRlciBpdHNlbGYuCisKK2lmIFsgIiQxIiA9PSAiIiBdOyB0aGVuCisgIGVjaG8gIlVTQUdFOiAgJDAgRElTVEZJTEUiID4mMgorICBleGl0IDEKK2ZpCisKK2lmIFsgISAtZSAkMSBdOyB0aGVuCisgIGVjaG8gJDEiOiBGaWxlIG5vdCBmb3VuZC4iID4mMgorICBleGl0IDEKK2ZpCisKK3NldCAtZXgKKworTEFOR1VBR0VTPSJjcHAgamF2YSBqYXZhbmFubyBweXRob24gcnVieSIKK0JBU0VOQU1FPWBiYXNlbmFtZSAkMSAudGFyLmd6YAorVkVSU0lPTj0ke0JBU0VOQU1FOjl9CisKKyMgQ3JlYXRlIGEgZGlyZWN0b3J5IGNhbGxlZCAiZGlzdCIsIGNvcHkgdGhlIHRhcmJhbGwgdGhlcmUgYW5kIHVucGFjayBpdC4KK21rZGlyIGRpc3QKK2NwICQxIGRpc3QKK2NkIGRpc3QKK3RhciB6eHZmICRCQVNFTkFNRS50YXIuZ3oKK3JtICRCQVNFTkFNRS50YXIuZ3oKKworIyBTZXQgdGhlIGVudGlyZSBjb250ZW50cyB0byBiZSB1c2VyLXdyaXRhYmxlLgorY2htb2QgLVIgdSt3ICRCQVNFTkFNRQorCisjIENvbnZlcnQgdGhlIE1TVkMgcHJvamVjdHMgdG8gTVNWQyAyMDA1IGZvcm1hdC4KK2NkICRCQVNFTkFNRS92c3Byb2plY3RzCisuL2NvbnZlcnQyMDA4dG8yMDA1LnNoCitjZCAuLgorCitmb3IgTEFORyBpbiAkTEFOR1VBR0VTOyBkbworICAjIEJ1aWxkIHRoZSBkaXN0IGFnYWluIGluIC50YXIuZ3oKKyAgLi9jb25maWd1cmUgRElTVF9MQU5HPSRMQU5HCisgIG1ha2UgZGlzdC1nemlwCisgIG12ICRCQVNFTkFNRS50YXIuZ3ogLi4vcHJvdG9idWYtJExBTkctJFZFUlNJT04udGFyLmd6Citkb25lCisKKyMgQ29udmVydCBhbGwgdGV4dCBmaWxlcyB0byB1c2UgRE9TLXN0eWxlIGxpbmUgZW5kaW5ncywgdGhlbiBidWlsZCBhIC56aXAKKyMgZGlzdHJpYnV0aW9uLgordG9kb3MgKi50eHQgKi8qLnR4dAorCitmb3IgTEFORyBpbiAkTEFOR1VBR0VTOyBkbworICAjIEJ1aWxkIHRoZSBkaXN0IGFnYWluIGluIC56aXAKKyAgLi9jb25maWd1cmUgRElTVF9MQU5HPSRMQU5HCisgIG1ha2UgZGlzdC16aXAKKyAgbXYgJEJBU0VOQU1FLnppcCAuLi9wcm90b2J1Zi0kTEFORy0kVkVSU0lPTi56aXAKK2RvbmUKKworY2QgLi4KK3JtIC1yZiAkQkFTRU5BTUUKZGlmZiAtLWdpdCBhL3Byb3RvYnVmLWxpdGUucGMuaW4gYi9wcm90b2J1Zi1saXRlLnBjLmluCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5YzIxOGUKLS0tIC9kZXYvbnVsbAorKysgYi9wcm90b2J1Zi1saXRlLnBjLmluCkBAIC0wLDAgKzEsMTMgQEAKK3ByZWZpeD1AcHJlZml4QAorZXhlY19wcmVmaXg9QGV4ZWNfcHJlZml4QAorbGliZGlyPUBsaWJkaXJACitpbmNsdWRlZGlyPUBpbmNsdWRlZGlyQAorCitOYW1lOiBQcm90b2NvbCBCdWZmZXJzCitEZXNjcmlwdGlvbjogR29vZ2xlJ3MgRGF0YSBJbnRlcmNoYW5nZSBGb3JtYXQKK1ZlcnNpb246IEBWRVJTSU9OQAorTGliczogLUwke2xpYmRpcn0gLWxwcm90b2J1Zi1saXRlIEBQVEhSRUFEX0NGTEFHU0AgQFBUSFJFQURfTElCU0AKK0NmbGFnczogLUkke2luY2x1ZGVkaXJ9IEBQVEhSRUFEX0NGTEFHU0AKKyMgQ29tbWVudGVkIG91dCBiZWNhdXNlIGl0IGNyYXNoZXMgcGtnLWNvbmZpZyAqc2lnaCo6CisjICAgaHR0cDovL2J1Z3MuZnJlZWRlc2t0b3Aub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzI2NQorIyBDb25mbGljdHM6IHByb3RvYnVmCmRpZmYgLS1naXQgYS9wcm90b2J1Zi5wYy5pbiBiL3Byb3RvYnVmLnBjLmluCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5ZjI0ODcKLS0tIC9kZXYvbnVsbAorKysgYi9wcm90b2J1Zi5wYy5pbgpAQCAtMCwwICsxLDE0IEBACitwcmVmaXg9QHByZWZpeEAKK2V4ZWNfcHJlZml4PUBleGVjX3ByZWZpeEAKK2xpYmRpcj1AbGliZGlyQAoraW5jbHVkZWRpcj1AaW5jbHVkZWRpckAKKworTmFtZTogUHJvdG9jb2wgQnVmZmVycworRGVzY3JpcHRpb246IEdvb2dsZSdzIERhdGEgSW50ZXJjaGFuZ2UgRm9ybWF0CitWZXJzaW9uOiBAVkVSU0lPTkAKK0xpYnM6IC1MJHtsaWJkaXJ9IC1scHJvdG9idWYgQFBUSFJFQURfQ0ZMQUdTQCBAUFRIUkVBRF9MSUJTQAorTGlicy5wcml2YXRlOiBATElCU0AKK0NmbGFnczogLUkke2luY2x1ZGVkaXJ9IEBQVEhSRUFEX0NGTEFHU0AKKyMgQ29tbWVudGVkIG91dCBiZWNhdXNlIGl0IGNyYXNoZXMgcGtnLWNvbmZpZyAqc2lnaCo6CisjICAgaHR0cDovL2J1Z3MuZnJlZWRlc2t0b3Aub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzI2NQorIyBDb25mbGljdHM6IHByb3RvYnVmLWxpdGUKZGlmZiAtLWdpdCBhL3B5dGhvbi9SRUFETUUudHh0IGIvcHl0aG9uL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRjYjE3NgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9SRUFETUUudHh0CkBAIC0wLDAgKzEsMTA2IEBACitQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKK0NvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuCisKK1RoaXMgZGlyZWN0b3J5IGNvbnRhaW5zIHRoZSBQeXRob24gUHJvdG9jb2wgQnVmZmVycyBydW50aW1lIGxpYnJhcnkuCisKK05vcm1hbGx5LCB0aGlzIGRpcmVjdG9yeSBjb21lcyBhcyBwYXJ0IG9mIHRoZSBwcm90b2J1ZiBwYWNrYWdlLCBhdmFpbGFibGUKK2Zyb206CisKKyAgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKworVGhlIGNvbXBsZXRlIHBhY2thZ2UgaW5jbHVkZXMgdGhlIEMrKyBzb3VyY2UgY29kZSwgd2hpY2ggaW5jbHVkZXMgdGhlCitQcm90b2NvbCBDb21waWxlciAocHJvdG9jKS4gIElmIHlvdSBkb3dubG9hZGVkIHRoaXMgcGFja2FnZSBmcm9tIFB5UEkKK29yIHNvbWUgb3RoZXIgUHl0aG9uLXNwZWNpZmljIHNvdXJjZSwgeW91IG1heSBoYXZlIHJlY2VpdmVkIG9ubHkgdGhlCitQeXRob24gcGFydCBvZiB0aGUgY29kZS4gIEluIHRoaXMgY2FzZSwgeW91IHdpbGwgbmVlZCB0byBvYnRhaW4gdGhlCitQcm90b2NvbCBDb21waWxlciBmcm9tIHNvbWUgb3RoZXIgc291cmNlIGJlZm9yZSB5b3UgY2FuIHVzZSB0aGlzCitwYWNrYWdlLgorCitEZXZlbG9wbWVudCBXYXJuaW5nCis9PT09PT09PT09PT09PT09PT09CisKK1RoZSBQeXRob24gaW1wbGVtZW50YXRpb24gb2YgUHJvdG9jb2wgQnVmZmVycyBpcyBub3QgYXMgbWF0dXJlIGFzIHRoZSBDKysKK2FuZCBKYXZhIGltcGxlbWVudGF0aW9ucy4gIEl0IG1heSBiZSBtb3JlIGJ1Z2d5LCBhbmQgaXQgaXMga25vd24gdG8gYmUKK3ByZXR0eSBzbG93IGF0IHRoaXMgdGltZS4gIElmIHlvdSB3b3VsZCBsaWtlIHRvIGhlbHAgZml4IHRoZXNlIGlzc3VlcywKK2pvaW4gdGhlIFByb3RvY29sIEJ1ZmZlcnMgZGlzY3Vzc2lvbiBsaXN0IGFuZCBsZXQgdXMga25vdyEKKworSW5zdGFsbGF0aW9uCis9PT09PT09PT09PT0KKworMSkgTWFrZSBzdXJlIHlvdSBoYXZlIFB5dGhvbiAyLjYgb3IgbmV3ZXIuICBJZiBpbiBkb3VidCwgcnVuOgorCisgICAgICQgcHl0aG9uIC1WCisKKzIpIElmIHlvdSBkbyBub3QgaGF2ZSBzZXR1cHRvb2xzIGluc3RhbGxlZCwgbm90ZSB0aGF0IGl0IHdpbGwgYmUKKyAgIGRvd25sb2FkZWQgYW5kIGluc3RhbGxlZCBhdXRvbWF0aWNhbGx5IGFzIHNvb24gYXMgeW91IHJ1biBzZXR1cC5weS4KKyAgIElmIHlvdSB3b3VsZCByYXRoZXIgaW5zdGFsbCBpdCBtYW51YWxseSwgeW91IG1heSBkbyBzbyBieSBmb2xsb3dpbmcKKyAgIHRoZSBpbnN0cnVjdGlvbnMgb24gdGhpcyBwYWdlOgorCisgICAgIGh0dHBzOi8vcGFja2FnaW5nLnB5dGhvbi5vcmcvZW4vbGF0ZXN0L2luc3RhbGxpbmcuaHRtbCNzZXR1cC1mb3ItaW5zdGFsbGluZy1wYWNrYWdlcworCiszKSBCdWlsZCB0aGUgQysrIGNvZGUsIG9yIGluc3RhbGwgYSBiaW5hcnkgZGlzdHJpYnV0aW9uIG9mIHByb3RvYy4gIElmCisgICB5b3UgaW5zdGFsbCBhIGJpbmFyeSBkaXN0cmlidXRpb24sIG1ha2Ugc3VyZSB0aGF0IGl0IGlzIHRoZSBzYW1lCisgICB2ZXJzaW9uIGFzIHRoaXMgcGFja2FnZS4gIElmIGluIGRvdWJ0LCBydW46CisKKyAgICAgJCBwcm90b2MgLS12ZXJzaW9uCisKKzQpIEJ1aWxkIGFuZCBydW4gdGhlIHRlc3RzOgorCisgICAgICQgcHl0aG9uIHNldHVwLnB5IGJ1aWxkCisgICAgICQgcHl0aG9uIHNldHVwLnB5IGdvb2dsZV90ZXN0CisKKyAgICAgSWYgeW91IHdhbnQgdG8gYnVpbGQvdGVzdCBjKysgaW1wbGVtZW50YXRpb24sIHJ1bjoKKyAgICAgJCBweXRob24gc2V0dXAucHkgYnVpbGQgLS1jcHBfaW1wbGVtZW50YXRpb24KKyAgICAgJCBweXRob24gc2V0dXAucHkgZ29vZ2xlX3Rlc3QgLS1jcHBfaW1wbGVtZW50YXRpb24KKworICAgSWYgc29tZSB0ZXN0cyBmYWlsLCB0aGlzIGxpYnJhcnkgbWF5IG5vdCB3b3JrIGNvcnJlY3RseSBvbiB5b3VyCisgICBzeXN0ZW0uICBDb250aW51ZSBhdCB5b3VyIG93biByaXNrLgorCisgICBQbGVhc2Ugbm90ZSB0aGF0IHRoZXJlIGlzIGEga25vd24gcHJvYmxlbSB3aXRoIHNvbWUgdmVyc2lvbnMgb2YKKyAgIFB5dGhvbiBvbiBDeWd3aW4gd2hpY2ggY2F1c2VzIHRoZSB0ZXN0cyB0byBmYWlsIGFmdGVyIHByaW50aW5nIHRoZQorICAgZXJyb3I6ICAic2VtX2luaXQ6IFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlIi4gIFRoaXMgYXBwZWFycworICAgdG8gYmUgYSBidWcgZWl0aGVyIGluIEN5Z3dpbiBvciBpbiBQeXRob246CisgICAgIGh0dHA6Ly93d3cuY3lnd2luLmNvbS9tbC9jeWd3aW4vMjAwNS0wNy9tc2cwMTM3OC5odG1sCisgICBXZSBkbyBub3Qga25vdyBpZiBvciB3aGVuIGl0IG1pZ2h0IG1lIGZpeGVkLiAgV2UgYWxzbyBkbyBub3Qga25vdworICAgaG93IGxpa2VseSBpdCBpcyB0aGF0IHRoaXMgYnVnIHdpbGwgYWZmZWN0IHVzZXJzIGluIHByYWN0aWNlLgorCis1KSBJbnN0YWxsOgorCisgICAgICQgcHl0aG9uIHNldHVwLnB5IGluc3RhbGwKKyAgICAgb3I6CisgICAgICQgcHl0aG9uIHNldHVwLnB5IGluc3RhbGwgLS1jcHBfaW1wbGVtZW50YXRpb24KKworICAgVGhpcyBzdGVwIG1heSByZXF1aXJlIHN1cGVydXNlciBwcml2aWxlZ2VzLgorICAgTk9URTogVG8gdXNlIEMrKyBpbXBsZW1lbnRhdGlvbiwgeW91IG5lZWQgdG8gaW5zdGFsbCBDKysgcHJvdG9idWYgcnVudGltZQorICAgbGlicmFyeSBvZiB0aGUgc2FtZSB2ZXJzaW9uIGFuZCBleHBvcnQgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIGJlZm9yZSB0aGlzCisgICBzdGVwLiBTZWUgdGhlICJDKysgSW1wbGVtZW50YXRpb24iIHNlY3Rpb24gYmVsb3cgZm9yIG1vcmUgZGV0YWlscy4KKworVXNhZ2UKKz09PT09CisKK1RoZSBjb21wbGV0ZSBkb2N1bWVudGF0aW9uIGZvciBQcm90b2NvbCBCdWZmZXJzIGlzIGF2YWlsYWJsZSB2aWEgdGhlCit3ZWIgYXQ6CisKKyAgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKworQysrIEltcGxlbWVudGF0aW9uCis9PT09PT09PT09PT09PT09PT0KKworVGhlIEMrKyBpbXBsZW1lbnRhdGlvbiBmb3IgUHl0aG9uIG1lc3NhZ2VzIGlzIGJ1aWx0IGFzIGEgUHl0aG9uIGV4dGVuc2lvbiB0bworaW1wcm92ZSB0aGUgb3ZlcmFsbCBwcm90b2J1ZiBQeXRob24gcGVyZm9ybWFuY2UuCisKK1RvIHVzZSB0aGUgQysrIGltcGxlbWVudGF0aW9uLCB5b3UgbmVlZCB0bzoKKzEpIEluc3RhbGwgdGhlIEMrKyBwcm90b2J1ZiBydW50aW1lIGxpYnJhcnksIHBsZWFzZSBzZWUgaW5zdHJ1Y3Rpb25zIGluIHRoZQorICAgcGFyZW50IGRpcmVjdG9yeS4KKzIpIEV4cG9ydCBhbiBlbnZpcm9ubWVudCB2YXJpYWJsZToKKworICAkIGV4cG9ydCBQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTj1jcHAKKyAgJCBleHBvcnQgUFJPVE9DT0xfQlVGRkVSU19QWVRIT05fSU1QTEVNRU5UQVRJT05fVkVSU0lPTj0yCisKK1lvdSBuZWVkIHRvIGV4cG9ydCB0aGlzIHZhcmlhYmxlIGJlZm9yZSBydW5uaW5nIHNldHVwLnB5IHNjcmlwdCB0byBidWlsZCBhbmQKK2luc3RhbGwgdGhlIGV4dGVuc2lvbi4gIFlvdSBtdXN0IGFsc28gc2V0IHRoZSB2YXJpYWJsZSBhdCBydW50aW1lLCBvdGhlcndpc2UKK3RoZSBwdXJlLVB5dGhvbiBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQuIEluIGEgZnV0dXJlIHJlbGVhc2UsIHdlIHdpbGwKK2NoYW5nZSB0aGUgZGVmYXVsdCBzbyB0aGF0IEMrKyBpbXBsZW1lbnRhdGlvbiBpcyB1c2VkIHdoZW5ldmVyIGl0IGlzIGF2YWlsYWJsZS4KK0l0IGlzIHN0cm9uZ2x5IHJlY29tbWVuZGVkIHRvIHJ1biBgcHl0aG9uIHNldHVwLnB5IHRlc3RgIGFmdGVyIHNldHRpbmcgdGhlCit2YXJpYWJsZSB0byAiY3BwIiwgc28gdGhlIHRlc3RzIHdpbGwgYmUgYWdhaW5zdCBDKysgaW1wbGVtZW50ZWQgUHl0aG9uCittZXNzYWdlcy4KKwpkaWZmIC0tZ2l0IGEvcHl0aG9uL2V6X3NldHVwLnB5IGIvcHl0aG9uL2V6X3NldHVwLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjNhZWM5OGUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZXpfc2V0dXAucHkKQEAgLTAsMCArMSwyODQgQEAKKyMhcHl0aG9uCisKKyMgVGhpcyBmaWxlIHdhcyBvYnRhaW5lZCBmcm9tOgorIyAgIGh0dHA6Ly9wZWFrLnRlbGVjb21tdW5pdHkuY29tL2Rpc3QvZXpfc2V0dXAucHkKKyMgb24gMjAxMS8xLzIxLgorCisiIiJCb290c3RyYXAgc2V0dXB0b29scyBpbnN0YWxsYXRpb24KKworSWYgeW91IHdhbnQgdG8gdXNlIHNldHVwdG9vbHMgaW4geW91ciBwYWNrYWdlJ3Mgc2V0dXAucHksIGp1c3QgaW5jbHVkZSB0aGlzCitmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeSB3aXRoIGl0LCBhbmQgYWRkIHRoaXMgdG8gdGhlIHRvcCBvZiB5b3VyIHNldHVwLnB5OjoKKworICAgIGZyb20gZXpfc2V0dXAgaW1wb3J0IHVzZV9zZXR1cHRvb2xzCisgICAgdXNlX3NldHVwdG9vbHMoKQorCitJZiB5b3Ugd2FudCB0byByZXF1aXJlIGEgc3BlY2lmaWMgdmVyc2lvbiBvZiBzZXR1cHRvb2xzLCBzZXQgYSBkb3dubG9hZAorbWlycm9yLCBvciB1c2UgYW4gYWx0ZXJuYXRlIGRvd25sb2FkIGRpcmVjdG9yeSwgeW91IGNhbiBkbyBzbyBieSBzdXBwbHlpbmcKK3RoZSBhcHByb3ByaWF0ZSBvcHRpb25zIHRvIGBgdXNlX3NldHVwdG9vbHMoKWBgLgorCitUaGlzIGZpbGUgY2FuIGFsc28gYmUgcnVuIGFzIGEgc2NyaXB0IHRvIGluc3RhbGwgb3IgdXBncmFkZSBzZXR1cHRvb2xzLgorIiIiCitpbXBvcnQgc3lzCitERUZBVUxUX1ZFUlNJT04gPSAiMC42YzExIgorREVGQVVMVF9VUkwgICAgID0gImh0dHA6Ly9weXBpLnB5dGhvbi5vcmcvcGFja2FnZXMvJXMvcy9zZXR1cHRvb2xzLyIgJSBzeXMudmVyc2lvbls6M10KKworbWQ1X2RhdGEgPSB7CisgICAgJ3NldHVwdG9vbHMtMC42YjEtcHkyLjMuZWdnJzogJzg4MjJjYWY5MDEyNTBkODQ4Yjk5NmI3ZjI1YzZlNmNhJywKKyAgICAnc2V0dXB0b29scy0wLjZiMS1weTIuNC5lZ2cnOiAnYjc5YThhNDAzZTQ1MDJmYmI4NWVlM2YxOTQxNzM1Y2InLAorICAgICdzZXR1cHRvb2xzLTAuNmIyLXB5Mi4zLmVnZyc6ICc1NjU3NzU5ZDhhNmQ4ZmM0NDA3MGE5ZDA3MjcyZDk5YicsCisgICAgJ3NldHVwdG9vbHMtMC42YjItcHkyLjQuZWdnJzogJzQ5OTZhOGQxNjlkMmJlNjYxZmEzMmE2ZTUyZTRmODJhJywKKyAgICAnc2V0dXB0b29scy0wLjZiMy1weTIuMy5lZ2cnOiAnYmIzMWMwZmM3Mzk5YTYzNTc5OTc1Y2FkOWY1YTA2MTgnLAorICAgICdzZXR1cHRvb2xzLTAuNmIzLXB5Mi40LmVnZyc6ICczOGE4YzZiM2Q2ZWNkMjIyNDdmMTc5ZjdkYTY2OWZhYycsCisgICAgJ3NldHVwdG9vbHMtMC42YjQtcHkyLjMuZWdnJzogJzYyMDQ1YTI0ZWQ0ZTFlYmM3N2ZlMDM5YWE0ZTZmN2U1JywKKyAgICAnc2V0dXB0b29scy0wLjZiNC1weTIuNC5lZ2cnOiAnNGNiMmExODVkMjI4ZGFjZmZiMmQxN2YxMDNiM2IxYzQnLAorICAgICdzZXR1cHRvb2xzLTAuNmMxLXB5Mi4zLmVnZyc6ICdiM2YyYjU1MzlkNjVjYjdmNzRhZDc5MTI3ZjFhOTA4YycsCisgICAgJ3NldHVwdG9vbHMtMC42YzEtcHkyLjQuZWdnJzogJ2I0NWFkZWRhMDY2N2QyZDJmZmUxNDAwOTM2NGYyYTRiJywKKyAgICAnc2V0dXB0b29scy0wLjZjMTAtcHkyLjMuZWdnJzogJ2NlMWUyYWI1ZDNhMDI1NjQ1NmQ5ZmMxMzgwMGE3MDkwJywKKyAgICAnc2V0dXB0b29scy0wLjZjMTAtcHkyLjQuZWdnJzogJzU3ZDZkOWQ2ZTliODA3NzJjNTlhNTNhODQzM2E1ZGQ0JywKKyAgICAnc2V0dXB0b29scy0wLjZjMTAtcHkyLjUuZWdnJzogJ2RlNDZhYzhiMWM5N2M4OTU1NzJlNWU4NTk2YWViOGM3JywKKyAgICAnc2V0dXB0b29scy0wLjZjMTAtcHkyLjYuZWdnJzogJzU4ZWE0MGFlZjA2ZGEwMmNlNjQxNDk1NTIzYTBiN2Y1JywKKyAgICAnc2V0dXB0b29scy0wLjZjMTEtcHkyLjMuZWdnJzogJzJiYWVhYzZlMTNkNDE0YTlkMjhlN2JhNWI1YTU5NmRlJywKKyAgICAnc2V0dXB0b29scy0wLjZjMTEtcHkyLjQuZWdnJzogJ2JkNjM5ZjliMGVhYzRjNDI0OTcwMzRkZWMyZWMwYzJiJywKKyAgICAnc2V0dXB0b29scy0wLjZjMTEtcHkyLjUuZWdnJzogJzY0Yzk0ZjNiZjdhNzJhMTNlYzgzZTBiMjRmMjc0OWIyJywKKyAgICAnc2V0dXB0b29scy0wLjZjMTEtcHkyLjYuZWdnJzogJ2JmYTkyMTAwYmQ3NzJkNWEyMTNlZWRkMzU2ZDY0MDg2JywKKyAgICAnc2V0dXB0b29scy0wLjZjMi1weTIuMy5lZ2cnOiAnZjAwNjRiZjZhYTJiN2QwZjNiYTBiNDNmMjA4MTdjMjcnLAorICAgICdzZXR1cHRvb2xzLTAuNmMyLXB5Mi40LmVnZyc6ICc2MTYxOTJlZWMzNWY0N2U4ZWExNmNkNmExMjJiNzI3NycsCisgICAgJ3NldHVwdG9vbHMtMC42YzMtcHkyLjMuZWdnJzogJ2YxODFmYTEyNWRmZTg1YTI1OWM5Y2Q2ZjFkN2I3OGZhJywKKyAgICAnc2V0dXB0b29scy0wLjZjMy1weTIuNC5lZ2cnOiAnZTBlZDc0NjgyYzk5OGJmYjczYmY4MDNhNTBlN2I3MWUnLAorICAgICdzZXR1cHRvb2xzLTAuNmMzLXB5Mi41LmVnZyc6ICdhYmVmMTZmZGQ2MTk1NTUxNDg0MWM3YzZiZDk4OTY1ZScsCisgICAgJ3NldHVwdG9vbHMtMC42YzQtcHkyLjMuZWdnJzogJ2IwYjkxMzFhY2FiMzIwMjJiZmFjN2Y0NGM1ZDc5NzFmJywKKyAgICAnc2V0dXB0b29scy0wLjZjNC1weTIuNC5lZ2cnOiAnMmExZjk2NTZkNGZiZjNjOTdiZjk0NmMwYTEyNGU2ZTInLAorICAgICdzZXR1cHRvb2xzLTAuNmM0LXB5Mi41LmVnZyc6ICc4ZjVhMDUyZTMyY2RiOWM3MmJjZjRiNTUyNmYyOGFmYycsCisgICAgJ3NldHVwdG9vbHMtMC42YzUtcHkyLjMuZWdnJzogJ2VlOWZkODA5NjVkYTA0ZjJmM2U2YjM1NzZlOWQ4MTY3JywKKyAgICAnc2V0dXB0b29scy0wLjZjNS1weTIuNC5lZ2cnOiAnYWZlMmFkZjFjMDE3MDFlZTg0MTc2MWY1YmNkOGFhNjQnLAorICAgICdzZXR1cHRvb2xzLTAuNmM1LXB5Mi41LmVnZyc6ICdhOGQzZjYxNDk0Y2NhYTg3MTRkZmVkMzdiY2NkM2Q1ZCcsCisgICAgJ3NldHVwdG9vbHMtMC42YzYtcHkyLjMuZWdnJzogJzM1Njg2Yjc4MTE2YTY2ODg0NzIzN2I2OWQ1NDllYzIwJywKKyAgICAnc2V0dXB0b29scy0wLjZjNi1weTIuNC5lZ2cnOiAnM2M1NmFmNTdiZTMyMjUwMTkyNjBhNjQ0NDMwMDY1YWInLAorICAgICdzZXR1cHRvb2xzLTAuNmM2LXB5Mi41LmVnZyc6ICdiMmY4YTc1MjA3MDlhNWIzNGY4MDk0NmRlNWYwMmY1MycsCisgICAgJ3NldHVwdG9vbHMtMC42YzctcHkyLjMuZWdnJzogJzIwOWZkZjlhZGMzYTYxNWU1MTE1YjcyNTY1OGUxM2UyJywKKyAgICAnc2V0dXB0b29scy0wLjZjNy1weTIuNC5lZ2cnOiAnNWE4Zjk1NDgwN2Q0NmEwZmI2N2NmMWYyNmM1NWE4MmUnLAorICAgICdzZXR1cHRvb2xzLTAuNmM3LXB5Mi41LmVnZyc6ICc0NWQyYWQyOGY5NzUwZTc0MzQxMTFmZGU4MzFlODM3MicsCisgICAgJ3NldHVwdG9vbHMtMC42YzgtcHkyLjMuZWdnJzogJzUwNzU5ZDI5YjM0OWRiOGNmZDgwN2JhODMwM2YxOTAyJywKKyAgICAnc2V0dXB0b29scy0wLjZjOC1weTIuNC5lZ2cnOiAnY2JhMzhkNzRmN2Q0ODNjMDZlOWRhYTYwNzBjY2U2ZGUnLAorICAgICdzZXR1cHRvb2xzLTAuNmM4LXB5Mi41LmVnZyc6ICcxNzIxNzQ3ZWUzMjlkYzE1MDU5MGE1OGIzZTFhYzk1YicsCisgICAgJ3NldHVwdG9vbHMtMC42YzktcHkyLjMuZWdnJzogJ2E4M2M0MDIwNDE0ODA3YjQ5NmU0Y2ZiZTA4NTA3YzAzJywKKyAgICAnc2V0dXB0b29scy0wLjZjOS1weTIuNC5lZ2cnOiAnMjYwYTJiZTJlNTM4OGQ2NmJkYWVlMDZhYmVjNjM0MmEnLAorICAgICdzZXR1cHRvb2xzLTAuNmM5LXB5Mi41LmVnZyc6ICdmZTY3YzNlNWExN2IxMmMwZTdjNTQxYjdlYTQzYThlNicsCisgICAgJ3NldHVwdG9vbHMtMC42YzktcHkyLjYuZWdnJzogJ2NhMzdiMWZmMTZmYTJlZGU2ZTE5MzgzZTdiNTkyNDVhJywKK30KKworaW1wb3J0IHN5cywgb3MKK3RyeTogZnJvbSBoYXNobGliIGltcG9ydCBtZDUKK2V4Y2VwdCBJbXBvcnRFcnJvcjogZnJvbSBtZDUgaW1wb3J0IG1kNQorCitkZWYgX3ZhbGlkYXRlX21kNShlZ2dfbmFtZSwgZGF0YSk6CisgICAgaWYgZWdnX25hbWUgaW4gbWQ1X2RhdGE6CisgICAgICAgIGRpZ2VzdCA9IG1kNShkYXRhKS5oZXhkaWdlc3QoKQorICAgICAgICBpZiBkaWdlc3QgIT0gbWQ1X2RhdGFbZWdnX25hbWVdOgorICAgICAgICAgICAgcHJpbnQgPj5zeXMuc3RkZXJyLCAoCisgICAgICAgICAgICAgICAgIm1kNSB2YWxpZGF0aW9uIG9mICVzIGZhaWxlZCEgIChQb3NzaWJsZSBkb3dubG9hZCBwcm9ibGVtPykiCisgICAgICAgICAgICAgICAgJSBlZ2dfbmFtZQorICAgICAgICAgICAgKQorICAgICAgICAgICAgc3lzLmV4aXQoMikKKyAgICByZXR1cm4gZGF0YQorCitkZWYgdXNlX3NldHVwdG9vbHMoCisgICAgdmVyc2lvbj1ERUZBVUxUX1ZFUlNJT04sIGRvd25sb2FkX2Jhc2U9REVGQVVMVF9VUkwsIHRvX2Rpcj1vcy5jdXJkaXIsCisgICAgZG93bmxvYWRfZGVsYXk9MTUKKyk6CisgICAgIiIiQXV0b21hdGljYWxseSBmaW5kL2Rvd25sb2FkIHNldHVwdG9vbHMgYW5kIG1ha2UgaXQgYXZhaWxhYmxlIG9uIHN5cy5wYXRoCisKKyAgICBgdmVyc2lvbmAgc2hvdWxkIGJlIGEgdmFsaWQgc2V0dXB0b29scyB2ZXJzaW9uIG51bWJlciB0aGF0IGlzIGF2YWlsYWJsZQorICAgIGFzIGFuIGVnZyBmb3IgZG93bmxvYWQgdW5kZXIgdGhlIGBkb3dubG9hZF9iYXNlYCBVUkwgKHdoaWNoIHNob3VsZCBlbmQgd2l0aAorICAgIGEgJy8nKS4gIGB0b19kaXJgIGlzIHRoZSBkaXJlY3Rvcnkgd2hlcmUgc2V0dXB0b29scyB3aWxsIGJlIGRvd25sb2FkZWQsIGlmCisgICAgaXQgaXMgbm90IGFscmVhZHkgYXZhaWxhYmxlLiAgSWYgYGRvd25sb2FkX2RlbGF5YCBpcyBzcGVjaWZpZWQsIGl0IHNob3VsZAorICAgIGJlIHRoZSBudW1iZXIgb2Ygc2Vjb25kcyB0aGF0IHdpbGwgYmUgcGF1c2VkIGJlZm9yZSBpbml0aWF0aW5nIGEgZG93bmxvYWQsCisgICAgc2hvdWxkIG9uZSBiZSByZXF1aXJlZC4gIElmIGFuIG9sZGVyIHZlcnNpb24gb2Ygc2V0dXB0b29scyBpcyBpbnN0YWxsZWQsCisgICAgdGhpcyByb3V0aW5lIHdpbGwgcHJpbnQgYSBtZXNzYWdlIHRvIGBgc3lzLnN0ZGVycmBgIGFuZCByYWlzZSBTeXN0ZW1FeGl0IGluCisgICAgYW4gYXR0ZW1wdCB0byBhYm9ydCB0aGUgY2FsbGluZyBzY3JpcHQuCisgICAgIiIiCisgICAgd2FzX2ltcG9ydGVkID0gJ3BrZ19yZXNvdXJjZXMnIGluIHN5cy5tb2R1bGVzIG9yICdzZXR1cHRvb2xzJyBpbiBzeXMubW9kdWxlcworICAgIGRlZiBkb19kb3dubG9hZCgpOgorICAgICAgICBlZ2cgPSBkb3dubG9hZF9zZXR1cHRvb2xzKHZlcnNpb24sIGRvd25sb2FkX2Jhc2UsIHRvX2RpciwgZG93bmxvYWRfZGVsYXkpCisgICAgICAgIHN5cy5wYXRoLmluc2VydCgwLCBlZ2cpCisgICAgICAgIGltcG9ydCBzZXR1cHRvb2xzOyBzZXR1cHRvb2xzLmJvb3RzdHJhcF9pbnN0YWxsX2Zyb20gPSBlZ2cKKyAgICB0cnk6CisgICAgICAgIGltcG9ydCBwa2dfcmVzb3VyY2VzCisgICAgZXhjZXB0IEltcG9ydEVycm9yOgorICAgICAgICByZXR1cm4gZG9fZG93bmxvYWQoKSAgICAgICAKKyAgICB0cnk6CisgICAgICAgIHJldHVybiBkb19kb3dubG9hZCgpCisgICAgICAgIHBrZ19yZXNvdXJjZXMucmVxdWlyZSgic2V0dXB0b29scz49Iit2ZXJzaW9uKTsgcmV0dXJuCisgICAgZXhjZXB0IHBrZ19yZXNvdXJjZXMuVmVyc2lvbkNvbmZsaWN0LCBlOgorICAgICAgICBpZiB3YXNfaW1wb3J0ZWQ6CisgICAgICAgICAgICBwcmludCA+PnN5cy5zdGRlcnIsICgKKyAgICAgICAgICAgICJUaGUgcmVxdWlyZWQgdmVyc2lvbiBvZiBzZXR1cHRvb2xzICg+PSVzKSBpcyBub3QgYXZhaWxhYmxlLCBhbmRcbiIKKyAgICAgICAgICAgICJjYW4ndCBiZSBpbnN0YWxsZWQgd2hpbGUgdGhpcyBzY3JpcHQgaXMgcnVubmluZy4gUGxlYXNlIGluc3RhbGxcbiIKKyAgICAgICAgICAgICIgYSBtb3JlIHJlY2VudCB2ZXJzaW9uIGZpcnN0LCB1c2luZyAnZWFzeV9pbnN0YWxsIC1VIHNldHVwdG9vbHMnLiIKKyAgICAgICAgICAgICJcblxuKEN1cnJlbnRseSB1c2luZyAlcikiCisgICAgICAgICAgICApICUgKHZlcnNpb24sIGUuYXJnc1swXSkKKyAgICAgICAgICAgIHN5cy5leGl0KDIpCisgICAgZXhjZXB0IHBrZ19yZXNvdXJjZXMuRGlzdHJpYnV0aW9uTm90Rm91bmQ6CisgICAgICAgIHBhc3MKKworICAgIGRlbCBwa2dfcmVzb3VyY2VzLCBzeXMubW9kdWxlc1sncGtnX3Jlc291cmNlcyddICAgICMgcmVsb2FkIG9rCisgICAgcmV0dXJuIGRvX2Rvd25sb2FkKCkKKworZGVmIGRvd25sb2FkX3NldHVwdG9vbHMoCisgICAgdmVyc2lvbj1ERUZBVUxUX1ZFUlNJT04sIGRvd25sb2FkX2Jhc2U9REVGQVVMVF9VUkwsIHRvX2Rpcj1vcy5jdXJkaXIsCisgICAgZGVsYXkgPSAxNQorKToKKyAgICAiIiJEb3dubG9hZCBzZXR1cHRvb2xzIGZyb20gYSBzcGVjaWZpZWQgbG9jYXRpb24gYW5kIHJldHVybiBpdHMgZmlsZW5hbWUKKworICAgIGB2ZXJzaW9uYCBzaG91bGQgYmUgYSB2YWxpZCBzZXR1cHRvb2xzIHZlcnNpb24gbnVtYmVyIHRoYXQgaXMgYXZhaWxhYmxlCisgICAgYXMgYW4gZWdnIGZvciBkb3dubG9hZCB1bmRlciB0aGUgYGRvd25sb2FkX2Jhc2VgIFVSTCAod2hpY2ggc2hvdWxkIGVuZAorICAgIHdpdGggYSAnLycpLiBgdG9fZGlyYCBpcyB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBlZ2cgd2lsbCBiZSBkb3dubG9hZGVkLgorICAgIGBkZWxheWAgaXMgdGhlIG51bWJlciBvZiBzZWNvbmRzIHRvIHBhdXNlIGJlZm9yZSBhbiBhY3R1YWwgZG93bmxvYWQgYXR0ZW1wdC4KKyAgICAiIiIKKyAgICBpbXBvcnQgdXJsbGliMiwgc2h1dGlsCisgICAgZWdnX25hbWUgPSAic2V0dXB0b29scy0lcy1weSVzLmVnZyIgJSAodmVyc2lvbixzeXMudmVyc2lvbls6M10pCisgICAgdXJsID0gZG93bmxvYWRfYmFzZSArIGVnZ19uYW1lCisgICAgc2F2ZXRvID0gb3MucGF0aC5qb2luKHRvX2RpciwgZWdnX25hbWUpCisgICAgc3JjID0gZHN0ID0gTm9uZQorICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhzYXZldG8pOiAgIyBBdm9pZCByZXBlYXRlZCBkb3dubG9hZHMKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgZnJvbSBkaXN0dXRpbHMgaW1wb3J0IGxvZworICAgICAgICAgICAgaWYgZGVsYXk6CisgICAgICAgICAgICAgICAgbG9nLndhcm4oIiIiCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoaXMgc2NyaXB0IHJlcXVpcmVzIHNldHVwdG9vbHMgdmVyc2lvbiAlcyB0byBydW4gKGV2ZW4gdG8gZGlzcGxheQoraGVscCkuICBJIHdpbGwgYXR0ZW1wdCB0byBkb3dubG9hZCBpdCBmb3IgeW91IChmcm9tCislcyksIGJ1dAoreW91IG1heSBuZWVkIHRvIGVuYWJsZSBmaXJld2FsbCBhY2Nlc3MgZm9yIHRoaXMgc2NyaXB0IGZpcnN0LgorSSB3aWxsIHN0YXJ0IHRoZSBkb3dubG9hZCBpbiAlZCBzZWNvbmRzLgorCisoTm90ZTogaWYgdGhpcyBtYWNoaW5lIGRvZXMgbm90IGhhdmUgbmV0d29yayBhY2Nlc3MsIHBsZWFzZSBvYnRhaW4gdGhlIGZpbGUKKworICAgJXMKKworYW5kIHBsYWNlIGl0IGluIHRoaXMgZGlyZWN0b3J5IGJlZm9yZSByZXJ1bm5pbmcgdGhpcyBzY3JpcHQuKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIiIiLAorICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uLCBkb3dubG9hZF9iYXNlLCBkZWxheSwgdXJsCisgICAgICAgICAgICAgICAgKTsgZnJvbSB0aW1lIGltcG9ydCBzbGVlcDsgc2xlZXAoZGVsYXkpCisgICAgICAgICAgICBsb2cud2FybigiRG93bmxvYWRpbmcgJXMiLCB1cmwpCisgICAgICAgICAgICBzcmMgPSB1cmxsaWIyLnVybG9wZW4odXJsKQorICAgICAgICAgICAgIyBSZWFkL3dyaXRlIGFsbCBpbiBvbmUgYmxvY2ssIHNvIHdlIGRvbid0IGNyZWF0ZSBhIGNvcnJ1cHQgZmlsZQorICAgICAgICAgICAgIyBpZiB0aGUgZG93bmxvYWQgaXMgaW50ZXJydXB0ZWQuCisgICAgICAgICAgICBkYXRhID0gX3ZhbGlkYXRlX21kNShlZ2dfbmFtZSwgc3JjLnJlYWQoKSkKKyAgICAgICAgICAgIGRzdCA9IG9wZW4oc2F2ZXRvLCJ3YiIpOyBkc3Qud3JpdGUoZGF0YSkKKyAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgIGlmIHNyYzogc3JjLmNsb3NlKCkKKyAgICAgICAgICAgIGlmIGRzdDogZHN0LmNsb3NlKCkKKyAgICByZXR1cm4gb3MucGF0aC5yZWFscGF0aChzYXZldG8pCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCitkZWYgbWFpbihhcmd2LCB2ZXJzaW9uPURFRkFVTFRfVkVSU0lPTik6CisgICAgIiIiSW5zdGFsbCBvciB1cGdyYWRlIHNldHVwdG9vbHMgYW5kIEVhc3lJbnN0YWxsIiIiCisgICAgdHJ5OgorICAgICAgICBpbXBvcnQgc2V0dXB0b29scworICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgICAgICAgZWdnID0gTm9uZQorICAgICAgICB0cnk6CisgICAgICAgICAgICBlZ2cgPSBkb3dubG9hZF9zZXR1cHRvb2xzKHZlcnNpb24sIGRlbGF5PTApCisgICAgICAgICAgICBzeXMucGF0aC5pbnNlcnQoMCxlZ2cpCisgICAgICAgICAgICBmcm9tIHNldHVwdG9vbHMuY29tbWFuZC5lYXN5X2luc3RhbGwgaW1wb3J0IG1haW4KKyAgICAgICAgICAgIHJldHVybiBtYWluKGxpc3QoYXJndikrW2VnZ10pICAgIyB3ZSdyZSBkb25lIGhlcmUKKyAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgIGlmIGVnZyBhbmQgb3MucGF0aC5leGlzdHMoZWdnKToKKyAgICAgICAgICAgICAgICBvcy51bmxpbmsoZWdnKQorICAgIGVsc2U6CisgICAgICAgIGlmIHNldHVwdG9vbHMuX192ZXJzaW9uX18gPT0gJzAuMC4xJzoKKyAgICAgICAgICAgIHByaW50ID4+c3lzLnN0ZGVyciwgKAorICAgICAgICAgICAgIllvdSBoYXZlIGFuIG9ic29sZXRlIHZlcnNpb24gb2Ygc2V0dXB0b29scyBpbnN0YWxsZWQuICBQbGVhc2VcbiIKKyAgICAgICAgICAgICJyZW1vdmUgaXQgZnJvbSB5b3VyIHN5c3RlbSBlbnRpcmVseSBiZWZvcmUgcmVydW5uaW5nIHRoaXMgc2NyaXB0LiIKKyAgICAgICAgICAgICkKKyAgICAgICAgICAgIHN5cy5leGl0KDIpCisKKyAgICByZXEgPSAic2V0dXB0b29scz49Iit2ZXJzaW9uCisgICAgaW1wb3J0IHBrZ19yZXNvdXJjZXMKKyAgICB0cnk6CisgICAgICAgIHBrZ19yZXNvdXJjZXMucmVxdWlyZShyZXEpCisgICAgZXhjZXB0IHBrZ19yZXNvdXJjZXMuVmVyc2lvbkNvbmZsaWN0OgorICAgICAgICB0cnk6CisgICAgICAgICAgICBmcm9tIHNldHVwdG9vbHMuY29tbWFuZC5lYXN5X2luc3RhbGwgaW1wb3J0IG1haW4KKyAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgorICAgICAgICAgICAgZnJvbSBlYXN5X2luc3RhbGwgaW1wb3J0IG1haW4KKyAgICAgICAgbWFpbihsaXN0KGFyZ3YpK1tkb3dubG9hZF9zZXR1cHRvb2xzKGRlbGF5PTApXSkKKyAgICAgICAgc3lzLmV4aXQoMCkgIyB0cnkgdG8gZm9yY2UgYW4gZXhpdAorICAgIGVsc2U6CisgICAgICAgIGlmIGFyZ3Y6CisgICAgICAgICAgICBmcm9tIHNldHVwdG9vbHMuY29tbWFuZC5lYXN5X2luc3RhbGwgaW1wb3J0IG1haW4KKyAgICAgICAgICAgIG1haW4oYXJndikKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHByaW50ICJTZXR1cHRvb2xzIHZlcnNpb24iLHZlcnNpb24sIm9yIGdyZWF0ZXIgaGFzIGJlZW4gaW5zdGFsbGVkLiIKKyAgICAgICAgICAgIHByaW50ICcoUnVuICJlel9zZXR1cC5weSAtVSBzZXR1cHRvb2xzIiB0byByZWluc3RhbGwgb3IgdXBncmFkZS4pJworCitkZWYgdXBkYXRlX21kNShmaWxlbmFtZXMpOgorICAgICIiIlVwZGF0ZSBvdXIgYnVpbHQtaW4gbWQ1IHJlZ2lzdHJ5IiIiCisKKyAgICBpbXBvcnQgcmUKKworICAgIGZvciBuYW1lIGluIGZpbGVuYW1lczoKKyAgICAgICAgYmFzZSA9IG9zLnBhdGguYmFzZW5hbWUobmFtZSkKKyAgICAgICAgZiA9IG9wZW4obmFtZSwncmInKQorICAgICAgICBtZDVfZGF0YVtiYXNlXSA9IG1kNShmLnJlYWQoKSkuaGV4ZGlnZXN0KCkKKyAgICAgICAgZi5jbG9zZSgpCisKKyAgICBkYXRhID0gWyIgICAgJXI6ICVyLFxuIiAlIGl0IGZvciBpdCBpbiBtZDVfZGF0YS5pdGVtcygpXQorICAgIGRhdGEuc29ydCgpCisgICAgcmVwbCA9ICIiLmpvaW4oZGF0YSkKKworICAgIGltcG9ydCBpbnNwZWN0CisgICAgc3JjZmlsZSA9IGluc3BlY3QuZ2V0c291cmNlZmlsZShzeXMubW9kdWxlc1tfX25hbWVfX10pCisgICAgZiA9IG9wZW4oc3JjZmlsZSwgJ3JiJyk7IHNyYyA9IGYucmVhZCgpOyBmLmNsb3NlKCkKKworICAgIG1hdGNoID0gcmUuc2VhcmNoKCJcbm1kNV9kYXRhID0ge1xuKFtefV0rKX0iLCBzcmMpCisgICAgaWYgbm90IG1hdGNoOgorICAgICAgICBwcmludCA+PnN5cy5zdGRlcnIsICJJbnRlcm5hbCBlcnJvciEiCisgICAgICAgIHN5cy5leGl0KDIpCisKKyAgICBzcmMgPSBzcmNbOm1hdGNoLnN0YXJ0KDEpXSArIHJlcGwgKyBzcmNbbWF0Y2guZW5kKDEpOl0KKyAgICBmID0gb3BlbihzcmNmaWxlLCd3JykKKyAgICBmLndyaXRlKHNyYykKKyAgICBmLmNsb3NlKCkKKworCitpZiBfX25hbWVfXz09J19fbWFpbl9fJzoKKyAgICBpZiBsZW4oc3lzLmFyZ3YpPjIgYW5kIHN5cy5hcmd2WzFdPT0nLS1tZDV1cGRhdGUnOgorICAgICAgICB1cGRhdGVfbWQ1KHN5cy5hcmd2WzI6XSkKKyAgICBlbHNlOgorICAgICAgICBtYWluKHN5cy5hcmd2WzE6XSkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvX19pbml0X18ucHkgYi9weXRob24vZ29vZ2xlL19faW5pdF9fLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmRlNDBlYTcKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL19faW5pdF9fLnB5CkBAIC0wLDAgKzEgQEAKK19faW1wb3J0X18oJ3BrZ19yZXNvdXJjZXMnKS5kZWNsYXJlX25hbWVzcGFjZShfX25hbWVfXykKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvX19pbml0X18ucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL19faW5pdF9fLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjEzNDViZDUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL19faW5pdF9fLnB5CkBAIC0wLDAgKzEsMzUgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIyBOZWVkcyB0byBzdGF5IGNvbXBhdGlibGUgd2l0aCBQeXRob24gMi41IGR1ZSB0byBHQUUuCisjCisjIENvcHlyaWdodCAyMDA3IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisKK19fdmVyc2lvbl9fID0gJzMuMC4wYTMuZGV2MCcKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5mN2E1OGNhCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnB5CkBAIC0wLDAgKzEsOTM4IEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyMgTmVlZHMgdG8gc3RheSBjb21wYXRpYmxlIHdpdGggUHl0aG9uIDIuNSBkdWUgdG8gR0FFLgorIworIyBDb3B5cmlnaHQgMjAwNyBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorCisiIiJEZXNjcmlwdG9ycyBlc3NlbnRpYWxseSBjb250YWluIGV4YWN0bHkgdGhlIGluZm9ybWF0aW9uIGZvdW5kIGluIGEgLnByb3RvCitmaWxlLCBpbiB0eXBlcyB0aGF0IG1ha2UgdGhpcyBpbmZvcm1hdGlvbiBhY2Nlc3NpYmxlIGluIFB5dGhvbi4KKyIiIgorCitfX2F1dGhvcl9fID0gJ3JvYmluc29uQGdvb2dsZS5jb20gKFdpbGwgUm9iaW5zb24pJworCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgYXBpX2ltcGxlbWVudGF0aW9uCisKKworX1VTRV9DX0RFU0NSSVBUT1JTID0gRmFsc2UKK2lmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgPT0gJ2NwcCc6CisgICMgVXNlZCBieSBNYWtlRGVzY3JpcHRvciBpbiBjcHAgbW9kZQorICBpbXBvcnQgb3MKKyAgaW1wb3J0IHV1aWQKKyAgZnJvbSBnb29nbGUucHJvdG9idWYucHlleHQgaW1wb3J0IF9tZXNzYWdlCisgIF9VU0VfQ19ERVNDUklQVE9SUyA9IGdldGF0dHIoX21lc3NhZ2UsICdfVVNFX0NfREVTQ1JJUFRPUlMnLCBGYWxzZSkKKworCitjbGFzcyBFcnJvcihFeGNlcHRpb24pOgorICAiIiJCYXNlIGVycm9yIGZvciB0aGlzIG1vZHVsZS4iIiIKKworCitjbGFzcyBUeXBlVHJhbnNmb3JtYXRpb25FcnJvcihFcnJvcik6CisgICIiIkVycm9yIHRyYW5zZm9ybWluZyBiZXR3ZWVuIHB5dGhvbiBwcm90byB0eXBlIGFuZCBjb3JyZXNwb25kaW5nIEMrKyB0eXBlLiIiIgorCisKK2lmIF9VU0VfQ19ERVNDUklQVE9SUzoKKyAgIyBUaGlzIG1ldGFjbGFzcyBhbGxvd3MgdG8gb3ZlcnJpZGUgdGhlIGJlaGF2aW9yIG9mIGNvZGUgbGlrZQorICAjICAgICBpc2luc3RhbmNlKG15X2Rlc2NyaXB0b3IsIEZpZWxkRGVzY3JpcHRvcikKKyAgIyBhbmQgbWFrZSBpdCByZXR1cm4gVHJ1ZSB3aGVuIHRoZSBkZXNjcmlwdG9yIGlzIGFuIGluc3RhbmNlIG9mIHRoZSBleHRlbnNpb24KKyAgIyB0eXBlIHdyaXR0ZW4gaW4gQysrLgorICBjbGFzcyBEZXNjcmlwdG9yTWV0YWNsYXNzKHR5cGUpOgorICAgIGRlZiBfX2luc3RhbmNlY2hlY2tfXyhjbHMsIG9iaik6CisgICAgICBpZiBzdXBlcihEZXNjcmlwdG9yTWV0YWNsYXNzLCBjbHMpLl9faW5zdGFuY2VjaGVja19fKG9iaik6CisgICAgICAgIHJldHVybiBUcnVlCisgICAgICBpZiBpc2luc3RhbmNlKG9iaiwgY2xzLl9DX0RFU0NSSVBUT1JfQ0xBU1MpOgorICAgICAgICByZXR1cm4gVHJ1ZQorICAgICAgcmV0dXJuIEZhbHNlCitlbHNlOgorICAjIFRoZSBzdGFuZGFyZCBtZXRhY2xhc3M7IG5vdGhpbmcgY2hhbmdlcy4KKyAgRGVzY3JpcHRvck1ldGFjbGFzcyA9IHR5cGUKKworCitjbGFzcyBEZXNjcmlwdG9yQmFzZShvYmplY3QpOgorCisgICIiIkRlc2NyaXB0b3JzIGJhc2UgY2xhc3MuCisKKyAgVGhpcyBjbGFzcyBpcyB0aGUgYmFzZSBvZiBhbGwgZGVzY3JpcHRvciBjbGFzc2VzLiBJdCBwcm92aWRlcyBjb21tb24gb3B0aW9ucworICByZWxhdGVkIGZ1bmN0aW9uYWxpdHkuCisKKyAgQXR0cmlidXRlczoKKyAgICBoYXNfb3B0aW9uczogIFRydWUgaWYgdGhlIGRlc2NyaXB0b3IgaGFzIG5vbi1kZWZhdWx0IG9wdGlvbnMuICBVc3VhbGx5IGl0CisgICAgICAgIGlzIG5vdCBuZWNlc3NhcnkgdG8gcmVhZCB0aGlzIC0tIGp1c3QgY2FsbCBHZXRPcHRpb25zKCkgd2hpY2ggd2lsbAorICAgICAgICBoYXBwaWx5IHJldHVybiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4gIEhvd2V2ZXIsIGl0J3Mgc29tZXRpbWVzIHVzZWZ1bAorICAgICAgICBmb3IgZWZmaWNpZW5jeSwgYW5kIGFsc28gdXNlZnVsIGluc2lkZSB0aGUgcHJvdG9idWYgaW1wbGVtZW50YXRpb24gdG8KKyAgICAgICAgYXZvaWQgc29tZSBib290c3RyYXBwaW5nIGlzc3Vlcy4KKyAgIiIiCisKKyAgX19tZXRhY2xhc3NfXyA9IERlc2NyaXB0b3JNZXRhY2xhc3MKKyAgaWYgX1VTRV9DX0RFU0NSSVBUT1JTOgorICAgICMgVGhlIGNsYXNzLCBvciB0dXBsZSBvZiBjbGFzc2VzLCB0aGF0IGFyZSBjb25zaWRlcmVkIGFzICJ2aXJ0dWFsCisgICAgIyBzdWJjbGFzc2VzIiBvZiB0aGlzIGRlc2NyaXB0b3IgY2xhc3MuCisgICAgX0NfREVTQ1JJUFRPUl9DTEFTUyA9ICgpCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG9wdGlvbnMsIG9wdGlvbnNfY2xhc3NfbmFtZSk6CisgICAgIiIiSW5pdGlhbGl6ZSB0aGUgZGVzY3JpcHRvciBnaXZlbiBpdHMgb3B0aW9ucyBtZXNzYWdlIGFuZCB0aGUgbmFtZSBvZiB0aGUKKyAgICBjbGFzcyBvZiB0aGUgb3B0aW9ucyBtZXNzYWdlLiBUaGUgbmFtZSBvZiB0aGUgY2xhc3MgaXMgcmVxdWlyZWQgaW4gY2FzZQorICAgIHRoZSBvcHRpb25zIG1lc3NhZ2UgaXMgTm9uZSBhbmQgaGFzIHRvIGJlIGNyZWF0ZWQuCisgICAgIiIiCisgICAgc2VsZi5fb3B0aW9ucyA9IG9wdGlvbnMKKyAgICBzZWxmLl9vcHRpb25zX2NsYXNzX25hbWUgPSBvcHRpb25zX2NsYXNzX25hbWUKKworICAgICMgRG9lcyB0aGlzIGRlc2NyaXB0b3IgaGF2ZSBub24tZGVmYXVsdCBvcHRpb25zPworICAgIHNlbGYuaGFzX29wdGlvbnMgPSBvcHRpb25zIGlzIG5vdCBOb25lCisKKyAgZGVmIF9TZXRPcHRpb25zKHNlbGYsIG9wdGlvbnMsIG9wdGlvbnNfY2xhc3NfbmFtZSk6CisgICAgIiIiU2V0cyB0aGUgZGVzY3JpcHRvcidzIG9wdGlvbnMKKworICAgIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBnZW5lcmF0ZWQgcHJvdG8yIGZpbGVzIHRvIHVwZGF0ZSBkZXNjcmlwdG9yCisgICAgb3B0aW9ucy4gSXQgbXVzdCBub3QgYmUgdXNlZCBvdXRzaWRlIHByb3RvMi4KKyAgICAiIiIKKyAgICBzZWxmLl9vcHRpb25zID0gb3B0aW9ucworICAgIHNlbGYuX29wdGlvbnNfY2xhc3NfbmFtZSA9IG9wdGlvbnNfY2xhc3NfbmFtZQorCisgICAgIyBEb2VzIHRoaXMgZGVzY3JpcHRvciBoYXZlIG5vbi1kZWZhdWx0IG9wdGlvbnM/CisgICAgc2VsZi5oYXNfb3B0aW9ucyA9IG9wdGlvbnMgaXMgbm90IE5vbmUKKworICBkZWYgR2V0T3B0aW9ucyhzZWxmKToKKyAgICAiIiJSZXRyaWV2ZXMgZGVzY3JpcHRvciBvcHRpb25zLgorCisgICAgVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgb3B0aW9ucyBzZXQgb3IgY3JlYXRlcyB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciB0aGUKKyAgICBkZXNjcmlwdG9yLgorICAgICIiIgorICAgIGlmIHNlbGYuX29wdGlvbnM6CisgICAgICByZXR1cm4gc2VsZi5fb3B0aW9ucworICAgIGZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yX3BiMgorICAgIHRyeToKKyAgICAgIG9wdGlvbnNfY2xhc3MgPSBnZXRhdHRyKGRlc2NyaXB0b3JfcGIyLCBzZWxmLl9vcHRpb25zX2NsYXNzX25hbWUpCisgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgorICAgICAgcmFpc2UgUnVudGltZUVycm9yKCdVbmtub3duIG9wdGlvbnMgY2xhc3MgbmFtZSAlcyEnICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAoc2VsZi5fb3B0aW9uc19jbGFzc19uYW1lKSkKKyAgICBzZWxmLl9vcHRpb25zID0gb3B0aW9uc19jbGFzcygpCisgICAgcmV0dXJuIHNlbGYuX29wdGlvbnMKKworCitjbGFzcyBfTmVzdGVkRGVzY3JpcHRvckJhc2UoRGVzY3JpcHRvckJhc2UpOgorICAiIiJDb21tb24gY2xhc3MgZm9yIGRlc2NyaXB0b3JzIHRoYXQgY2FuIGJlIG5lc3RlZC4iIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgb3B0aW9ucywgb3B0aW9uc19jbGFzc19uYW1lLCBuYW1lLCBmdWxsX25hbWUsCisgICAgICAgICAgICAgICBmaWxlLCBjb250YWluaW5nX3R5cGUsIHNlcmlhbGl6ZWRfc3RhcnQ9Tm9uZSwKKyAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRfZW5kPU5vbmUpOgorICAgICIiIkNvbnN0cnVjdG9yLgorCisgICAgQXJnczoKKyAgICAgIG9wdGlvbnM6IFByb3RvY29sIG1lc3NhZ2Ugb3B0aW9ucyBvciBOb25lCisgICAgICAgIHRvIHVzZSBkZWZhdWx0IG1lc3NhZ2Ugb3B0aW9ucy4KKyAgICAgIG9wdGlvbnNfY2xhc3NfbmFtZTogKHN0cikgVGhlIGNsYXNzIG5hbWUgb2YgdGhlIGFib3ZlIG9wdGlvbnMuCisKKyAgICAgIG5hbWU6IChzdHIpIE5hbWUgb2YgdGhpcyBwcm90b2NvbCBtZXNzYWdlIHR5cGUuCisgICAgICBmdWxsX25hbWU6IChzdHIpIEZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoaXMgcHJvdG9jb2wgbWVzc2FnZSB0eXBlLAorICAgICAgICB3aGljaCB3aWxsIGluY2x1ZGUgcHJvdG9jb2wgInBhY2thZ2UiIG5hbWUgYW5kIHRoZSBuYW1lIG9mIGFueQorICAgICAgICBlbmNsb3NpbmcgdHlwZXMuCisgICAgICBmaWxlOiAoRmlsZURlc2NyaXB0b3IpIFJlZmVyZW5jZSB0byBmaWxlIGluZm8uCisgICAgICBjb250YWluaW5nX3R5cGU6IGlmIHByb3ZpZGVkLCB0aGlzIGlzIGEgbmVzdGVkIGRlc2NyaXB0b3IsIHdpdGggdGhpcworICAgICAgICBkZXNjcmlwdG9yIGFzIHBhcmVudCwgb3RoZXJ3aXNlIE5vbmUuCisgICAgICBzZXJpYWxpemVkX3N0YXJ0OiBUaGUgc3RhcnQgaW5kZXggKGluY2x1c2l2ZSkgaW4gYmxvY2sgaW4gdGhlCisgICAgICAgIGZpbGUuc2VyaWFsaXplZF9wYiB0aGF0IGRlc2NyaWJlcyB0aGlzIGRlc2NyaXB0b3IuCisgICAgICBzZXJpYWxpemVkX2VuZDogVGhlIGVuZCBpbmRleCAoZXhjbHVzaXZlKSBpbiBibG9jayBpbiB0aGUKKyAgICAgICAgZmlsZS5zZXJpYWxpemVkX3BiIHRoYXQgZGVzY3JpYmVzIHRoaXMgZGVzY3JpcHRvci4KKyAgICAiIiIKKyAgICBzdXBlcihfTmVzdGVkRGVzY3JpcHRvckJhc2UsIHNlbGYpLl9faW5pdF9fKAorICAgICAgICBvcHRpb25zLCBvcHRpb25zX2NsYXNzX25hbWUpCisKKyAgICBzZWxmLm5hbWUgPSBuYW1lCisgICAgIyBUT0RPKGZhbGspOiBBZGQgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGZ1bGxfbmFtZSBpbnN0ZWFkIG9mIGhhdmluZyBpdCBpbgorICAgICMgICAgICAgICAgICAgbWVtb3J5PworICAgIHNlbGYuZnVsbF9uYW1lID0gZnVsbF9uYW1lCisgICAgc2VsZi5maWxlID0gZmlsZQorICAgIHNlbGYuY29udGFpbmluZ190eXBlID0gY29udGFpbmluZ190eXBlCisKKyAgICBzZWxmLl9zZXJpYWxpemVkX3N0YXJ0ID0gc2VyaWFsaXplZF9zdGFydAorICAgIHNlbGYuX3NlcmlhbGl6ZWRfZW5kID0gc2VyaWFsaXplZF9lbmQKKworICBkZWYgR2V0VG9wTGV2ZWxDb250YWluaW5nVHlwZShzZWxmKToKKyAgICAiIiJSZXR1cm5zIHRoZSByb290IGlmIHRoaXMgaXMgYSBuZXN0ZWQgdHlwZSwgb3IgaXRzZWxmIGlmIGl0cyB0aGUgcm9vdC4iIiIKKyAgICBkZXNjID0gc2VsZgorICAgIHdoaWxlIGRlc2MuY29udGFpbmluZ190eXBlIGlzIG5vdCBOb25lOgorICAgICAgZGVzYyA9IGRlc2MuY29udGFpbmluZ190eXBlCisgICAgcmV0dXJuIGRlc2MKKworICBkZWYgQ29weVRvUHJvdG8oc2VsZiwgcHJvdG8pOgorICAgICIiIkNvcGllcyB0aGlzIHRvIHRoZSBtYXRjaGluZyBwcm90byBpbiBkZXNjcmlwdG9yX3BiMi4KKworICAgIEFyZ3M6CisgICAgICBwcm90bzogQW4gZW1wdHkgcHJvdG8gaW5zdGFuY2UgZnJvbSBkZXNjcmlwdG9yX3BiMi4KKworICAgIFJhaXNlczoKKyAgICAgIEVycm9yOiBJZiBzZWxmIGNvdWxkbnQgYmUgc2VyaWFsaXplZCwgZHVlIHRvIHRvIGZldyBjb25zdHJ1Y3RvciBhcmd1bWVudHMuCisgICAgIiIiCisgICAgaWYgKHNlbGYuZmlsZSBpcyBub3QgTm9uZSBhbmQKKyAgICAgICAgc2VsZi5fc2VyaWFsaXplZF9zdGFydCBpcyBub3QgTm9uZSBhbmQKKyAgICAgICAgc2VsZi5fc2VyaWFsaXplZF9lbmQgaXMgbm90IE5vbmUpOgorICAgICAgcHJvdG8uUGFyc2VGcm9tU3RyaW5nKHNlbGYuZmlsZS5zZXJpYWxpemVkX3BiWworICAgICAgICAgIHNlbGYuX3NlcmlhbGl6ZWRfc3RhcnQ6c2VsZi5fc2VyaWFsaXplZF9lbmRdKQorICAgIGVsc2U6CisgICAgICByYWlzZSBFcnJvcignRGVzY3JpcHRvciBkb2VzIG5vdCBjb250YWluIHNlcmlhbGl6YXRpb24uJykKKworCitjbGFzcyBEZXNjcmlwdG9yKF9OZXN0ZWREZXNjcmlwdG9yQmFzZSk6CisKKyAgIiIiRGVzY3JpcHRvciBmb3IgYSBwcm90b2NvbCBtZXNzYWdlIHR5cGUuCisKKyAgQSBEZXNjcmlwdG9yIGluc3RhbmNlIGhhcyB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6CisKKyAgICBuYW1lOiAoc3RyKSBOYW1lIG9mIHRoaXMgcHJvdG9jb2wgbWVzc2FnZSB0eXBlLgorICAgIGZ1bGxfbmFtZTogKHN0cikgRnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyBwcm90b2NvbCBtZXNzYWdlIHR5cGUsCisgICAgICB3aGljaCB3aWxsIGluY2x1ZGUgcHJvdG9jb2wgInBhY2thZ2UiIG5hbWUgYW5kIHRoZSBuYW1lIG9mIGFueQorICAgICAgZW5jbG9zaW5nIHR5cGVzLgorCisgICAgY29udGFpbmluZ190eXBlOiAoRGVzY3JpcHRvcikgUmVmZXJlbmNlIHRvIHRoZSBkZXNjcmlwdG9yIG9mIHRoZQorICAgICAgdHlwZSBjb250YWluaW5nIHVzLCBvciBOb25lIGlmIHRoaXMgaXMgdG9wLWxldmVsLgorCisgICAgZmllbGRzOiAobGlzdCBvZiBGaWVsZERlc2NyaXB0b3JzKSBGaWVsZCBkZXNjcmlwdG9ycyBmb3IgYWxsCisgICAgICBmaWVsZHMgaW4gdGhpcyB0eXBlLgorICAgIGZpZWxkc19ieV9udW1iZXI6IChkaWN0IGludCAtPiBGaWVsZERlc2NyaXB0b3IpIFNhbWUgRmllbGREZXNjcmlwdG9yCisgICAgICBvYmplY3RzIGFzIGluIHxmaWVsZHN8LCBidXQgaW5kZXhlZCBieSAibnVtYmVyIiBhdHRyaWJ1dGUgaW4gZWFjaAorICAgICAgRmllbGREZXNjcmlwdG9yLgorICAgIGZpZWxkc19ieV9uYW1lOiAoZGljdCBzdHIgLT4gRmllbGREZXNjcmlwdG9yKSBTYW1lIEZpZWxkRGVzY3JpcHRvcgorICAgICAgb2JqZWN0cyBhcyBpbiB8ZmllbGRzfCwgYnV0IGluZGV4ZWQgYnkgIm5hbWUiIGF0dHJpYnV0ZSBpbiBlYWNoCisgICAgICBGaWVsZERlc2NyaXB0b3IuCisKKyAgICBuZXN0ZWRfdHlwZXM6IChsaXN0IG9mIERlc2NyaXB0b3JzKSBEZXNjcmlwdG9yIHJlZmVyZW5jZXMKKyAgICAgIGZvciBhbGwgcHJvdG9jb2wgbWVzc2FnZSB0eXBlcyBuZXN0ZWQgd2l0aGluIHRoaXMgb25lLgorICAgIG5lc3RlZF90eXBlc19ieV9uYW1lOiAoZGljdCBzdHIgLT4gRGVzY3JpcHRvcikgU2FtZSBEZXNjcmlwdG9yCisgICAgICBvYmplY3RzIGFzIGluIHxuZXN0ZWRfdHlwZXN8LCBidXQgaW5kZXhlZCBieSAibmFtZSIgYXR0cmlidXRlCisgICAgICBpbiBlYWNoIERlc2NyaXB0b3IuCisKKyAgICBlbnVtX3R5cGVzOiAobGlzdCBvZiBFbnVtRGVzY3JpcHRvcnMpIEVudW1EZXNjcmlwdG9yIHJlZmVyZW5jZXMKKyAgICAgIGZvciBhbGwgZW51bXMgY29udGFpbmVkIHdpdGhpbiB0aGlzIHR5cGUuCisgICAgZW51bV90eXBlc19ieV9uYW1lOiAoZGljdCBzdHIgLT5FbnVtRGVzY3JpcHRvcikgU2FtZSBFbnVtRGVzY3JpcHRvcgorICAgICAgb2JqZWN0cyBhcyBpbiB8ZW51bV90eXBlc3wsIGJ1dCBpbmRleGVkIGJ5ICJuYW1lIiBhdHRyaWJ1dGUKKyAgICAgIGluIGVhY2ggRW51bURlc2NyaXB0b3IuCisgICAgZW51bV92YWx1ZXNfYnlfbmFtZTogKGRpY3Qgc3RyIC0+IEVudW1WYWx1ZURlc2NyaXB0b3IpIERpY3QgbWFwcGluZworICAgICAgZnJvbSBlbnVtIHZhbHVlIG5hbWUgdG8gRW51bVZhbHVlRGVzY3JpcHRvciBmb3IgdGhhdCB2YWx1ZS4KKworICAgIGV4dGVuc2lvbnM6IChsaXN0IG9mIEZpZWxkRGVzY3JpcHRvcikgQWxsIGV4dGVuc2lvbnMgZGVmaW5lZCBkaXJlY3RseQorICAgICAgd2l0aGluIHRoaXMgbWVzc2FnZSB0eXBlIChOT1Qgd2l0aGluIGEgbmVzdGVkIHR5cGUpLgorICAgIGV4dGVuc2lvbnNfYnlfbmFtZTogKGRpY3QsIHN0cmluZyAtPiBGaWVsZERlc2NyaXB0b3IpIFNhbWUgRmllbGREZXNjcmlwdG9yCisgICAgICBvYmplY3RzIGFzIHxleHRlbnNpb25zfCwgYnV0IGluZGV4ZWQgYnkgIm5hbWUiIGF0dHJpYnV0ZSBvZiBlYWNoCisgICAgICBGaWVsZERlc2NyaXB0b3IuCisKKyAgICBpc19leHRlbmRhYmxlOiAgRG9lcyB0aGlzIHR5cGUgZGVmaW5lIGFueSBleHRlbnNpb24gcmFuZ2VzPworCisgICAgb3B0aW9uczogKGRlc2NyaXB0b3JfcGIyLk1lc3NhZ2VPcHRpb25zKSBQcm90b2NvbCBtZXNzYWdlIG9wdGlvbnMgb3IgTm9uZQorICAgICAgdG8gdXNlIGRlZmF1bHQgbWVzc2FnZSBvcHRpb25zLgorCisgICAgb25lb2ZzOiAobGlzdCBvZiBPbmVvZkRlc2NyaXB0b3IpIFRoZSBsaXN0IG9mIGRlc2NyaXB0b3JzIGZvciBvbmVvZiBmaWVsZHMKKyAgICAgIGluIHRoaXMgbWVzc2FnZS4KKyAgICBvbmVvZnNfYnlfbmFtZTogKGRpY3Qgc3RyIC0+IE9uZW9mRGVzY3JpcHRvcikgU2FtZSBvYmplY3RzIGFzIGluIHxvbmVvZnN8LAorICAgICAgYnV0IGluZGV4ZWQgYnkgIm5hbWUiIGF0dHJpYnV0ZS4KKworICAgIGZpbGU6IChGaWxlRGVzY3JpcHRvcikgUmVmZXJlbmNlIHRvIGZpbGUgZGVzY3JpcHRvci4KKyAgIiIiCisKKyAgaWYgX1VTRV9DX0RFU0NSSVBUT1JTOgorICAgIF9DX0RFU0NSSVBUT1JfQ0xBU1MgPSBfbWVzc2FnZS5EZXNjcmlwdG9yCisKKyAgICBkZWYgX19uZXdfXyhjbHMsIG5hbWUsIGZ1bGxfbmFtZSwgZmlsZW5hbWUsIGNvbnRhaW5pbmdfdHlwZSwgZmllbGRzLAorICAgICAgICAgICAgICAgIG5lc3RlZF90eXBlcywgZW51bV90eXBlcywgZXh0ZW5zaW9ucywgb3B0aW9ucz1Ob25lLAorICAgICAgICAgICAgICAgIGlzX2V4dGVuZGFibGU9VHJ1ZSwgZXh0ZW5zaW9uX3Jhbmdlcz1Ob25lLCBvbmVvZnM9Tm9uZSwKKyAgICAgICAgICAgICAgICBmaWxlPU5vbmUsIHNlcmlhbGl6ZWRfc3RhcnQ9Tm9uZSwgc2VyaWFsaXplZF9lbmQ9Tm9uZSwKKyAgICAgICAgICAgICAgICBzeW50YXg9Tm9uZSk6CisgICAgICBfbWVzc2FnZS5NZXNzYWdlLl9DaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKCkKKyAgICAgIHJldHVybiBfbWVzc2FnZS5NZXNzYWdlLl9HZXRNZXNzYWdlRGVzY3JpcHRvcihmdWxsX25hbWUpCisKKyAgIyBOT1RFKHRtYXJlayk6IFRoZSBmaWxlIGFyZ3VtZW50IHJlZGVmaW5pbmcgYSBidWlsdGluIGlzIG5vdGhpbmcgd2UgY2FuCisgICMgZml4IHJpZ2h0IG5vdyBzaW5jZSB3ZSBkb24ndCBrbm93IGhvdyBtYW55IGNsaWVudHMgYWxyZWFkeSByZWx5IG9uIHRoZQorICAjIG5hbWUgb2YgdGhlIGFyZ3VtZW50LgorICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgZnVsbF9uYW1lLCBmaWxlbmFtZSwgY29udGFpbmluZ190eXBlLCBmaWVsZHMsCisgICAgICAgICAgICAgICBuZXN0ZWRfdHlwZXMsIGVudW1fdHlwZXMsIGV4dGVuc2lvbnMsIG9wdGlvbnM9Tm9uZSwKKyAgICAgICAgICAgICAgIGlzX2V4dGVuZGFibGU9VHJ1ZSwgZXh0ZW5zaW9uX3Jhbmdlcz1Ob25lLCBvbmVvZnM9Tm9uZSwKKyAgICAgICAgICAgICAgIGZpbGU9Tm9uZSwgc2VyaWFsaXplZF9zdGFydD1Ob25lLCBzZXJpYWxpemVkX2VuZD1Ob25lLAorICAgICAgICAgICAgICAgc3ludGF4PU5vbmUpOiAgIyBweWxpbnQ6ZGlzYWJsZT1yZWRlZmluZWQtYnVpbHRpbgorICAgICIiIkFyZ3VtZW50cyB0byBfX2luaXRfXygpIGFyZSBhcyBkZXNjcmliZWQgaW4gdGhlIGRlc2NyaXB0aW9uCisgICAgb2YgRGVzY3JpcHRvciBmaWVsZHMgYWJvdmUuCisKKyAgICBOb3RlIHRoYXQgZmlsZW5hbWUgaXMgYW4gb2Jzb2xldGUgYXJndW1lbnQsIHRoYXQgaXMgbm90IHVzZWQgYW55bW9yZS4KKyAgICBQbGVhc2UgdXNlIGZpbGUubmFtZSB0byBhY2Nlc3MgdGhpcyBhcyBhbiBhdHRyaWJ1dGUuCisgICAgIiIiCisgICAgc3VwZXIoRGVzY3JpcHRvciwgc2VsZikuX19pbml0X18oCisgICAgICAgIG9wdGlvbnMsICdNZXNzYWdlT3B0aW9ucycsIG5hbWUsIGZ1bGxfbmFtZSwgZmlsZSwKKyAgICAgICAgY29udGFpbmluZ190eXBlLCBzZXJpYWxpemVkX3N0YXJ0PXNlcmlhbGl6ZWRfc3RhcnQsCisgICAgICAgIHNlcmlhbGl6ZWRfZW5kPXNlcmlhbGl6ZWRfZW5kKQorCisgICAgIyBXZSBoYXZlIGZpZWxkcyBpbiBhZGRpdGlvbiB0byBmaWVsZHNfYnlfbmFtZSBhbmQgZmllbGRzX2J5X251bWJlciwKKyAgICAjIHNvIHRoYXQ6CisgICAgIyAgIDEuIENsaWVudHMgY2FuIGluZGV4IGZpZWxkcyBieSAib3JkZXIgaW4gd2hpY2ggdGhleSdyZSBsaXN0ZWQuIgorICAgICMgICAyLiBDbGllbnRzIGNhbiBlYXNpbHkgaXRlcmF0ZSBvdmVyIGFsbCBmaWVsZHMgd2l0aCB0aGUgdGVyc2UKKyAgICAjICAgICAgc3ludGF4OiBmb3IgZiBpbiBkZXNjcmlwdG9yLmZpZWxkczogLi4uCisgICAgc2VsZi5maWVsZHMgPSBmaWVsZHMKKyAgICBmb3IgZmllbGQgaW4gc2VsZi5maWVsZHM6CisgICAgICBmaWVsZC5jb250YWluaW5nX3R5cGUgPSBzZWxmCisgICAgc2VsZi5maWVsZHNfYnlfbnVtYmVyID0gZGljdCgoZi5udW1iZXIsIGYpIGZvciBmIGluIGZpZWxkcykKKyAgICBzZWxmLmZpZWxkc19ieV9uYW1lID0gZGljdCgoZi5uYW1lLCBmKSBmb3IgZiBpbiBmaWVsZHMpCisKKyAgICBzZWxmLm5lc3RlZF90eXBlcyA9IG5lc3RlZF90eXBlcworICAgIGZvciBuZXN0ZWRfdHlwZSBpbiBuZXN0ZWRfdHlwZXM6CisgICAgICBuZXN0ZWRfdHlwZS5jb250YWluaW5nX3R5cGUgPSBzZWxmCisgICAgc2VsZi5uZXN0ZWRfdHlwZXNfYnlfbmFtZSA9IGRpY3QoKHQubmFtZSwgdCkgZm9yIHQgaW4gbmVzdGVkX3R5cGVzKQorCisgICAgc2VsZi5lbnVtX3R5cGVzID0gZW51bV90eXBlcworICAgIGZvciBlbnVtX3R5cGUgaW4gc2VsZi5lbnVtX3R5cGVzOgorICAgICAgZW51bV90eXBlLmNvbnRhaW5pbmdfdHlwZSA9IHNlbGYKKyAgICBzZWxmLmVudW1fdHlwZXNfYnlfbmFtZSA9IGRpY3QoKHQubmFtZSwgdCkgZm9yIHQgaW4gZW51bV90eXBlcykKKyAgICBzZWxmLmVudW1fdmFsdWVzX2J5X25hbWUgPSBkaWN0KAorICAgICAgICAodi5uYW1lLCB2KSBmb3IgdCBpbiBlbnVtX3R5cGVzIGZvciB2IGluIHQudmFsdWVzKQorCisgICAgc2VsZi5leHRlbnNpb25zID0gZXh0ZW5zaW9ucworICAgIGZvciBleHRlbnNpb24gaW4gc2VsZi5leHRlbnNpb25zOgorICAgICAgZXh0ZW5zaW9uLmV4dGVuc2lvbl9zY29wZSA9IHNlbGYKKyAgICBzZWxmLmV4dGVuc2lvbnNfYnlfbmFtZSA9IGRpY3QoKGYubmFtZSwgZikgZm9yIGYgaW4gZXh0ZW5zaW9ucykKKyAgICBzZWxmLmlzX2V4dGVuZGFibGUgPSBpc19leHRlbmRhYmxlCisgICAgc2VsZi5leHRlbnNpb25fcmFuZ2VzID0gZXh0ZW5zaW9uX3JhbmdlcworICAgIHNlbGYub25lb2ZzID0gb25lb2ZzIGlmIG9uZW9mcyBpcyBub3QgTm9uZSBlbHNlIFtdCisgICAgc2VsZi5vbmVvZnNfYnlfbmFtZSA9IGRpY3QoKG8ubmFtZSwgbykgZm9yIG8gaW4gc2VsZi5vbmVvZnMpCisgICAgZm9yIG9uZW9mIGluIHNlbGYub25lb2ZzOgorICAgICAgb25lb2YuY29udGFpbmluZ190eXBlID0gc2VsZgorICAgIHNlbGYuc3ludGF4ID0gc3ludGF4IG9yICJwcm90bzIiCisKKyAgZGVmIEVudW1WYWx1ZU5hbWUoc2VsZiwgZW51bSwgdmFsdWUpOgorICAgICIiIlJldHVybnMgdGhlIHN0cmluZyBuYW1lIG9mIGFuIGVudW0gdmFsdWUuCisKKyAgICBUaGlzIGlzIGp1c3QgYSBzbWFsbCBoZWxwZXIgbWV0aG9kIHRvIHNpbXBsaWZ5IGEgY29tbW9uIG9wZXJhdGlvbi4KKworICAgIEFyZ3M6CisgICAgICBlbnVtOiBzdHJpbmcgbmFtZSBvZiB0aGUgRW51bS4KKyAgICAgIHZhbHVlOiBpbnQsIHZhbHVlIG9mIHRoZSBlbnVtLgorCisgICAgUmV0dXJuczoKKyAgICAgIHN0cmluZyBuYW1lIG9mIHRoZSBlbnVtIHZhbHVlLgorCisgICAgUmFpc2VzOgorICAgICAgS2V5RXJyb3IgaWYgZWl0aGVyIHRoZSBFbnVtIGRvZXNuJ3QgZXhpc3Qgb3IgdGhlIHZhbHVlIGlzIG5vdCBhIHZhbGlkCisgICAgICAgIHZhbHVlIGZvciB0aGUgZW51bS4KKyAgICAiIiIKKyAgICByZXR1cm4gc2VsZi5lbnVtX3R5cGVzX2J5X25hbWVbZW51bV0udmFsdWVzX2J5X251bWJlclt2YWx1ZV0ubmFtZQorCisgIGRlZiBDb3B5VG9Qcm90byhzZWxmLCBwcm90byk6CisgICAgIiIiQ29waWVzIHRoaXMgdG8gYSBkZXNjcmlwdG9yX3BiMi5EZXNjcmlwdG9yUHJvdG8uCisKKyAgICBBcmdzOgorICAgICAgcHJvdG86IEFuIGVtcHR5IGRlc2NyaXB0b3JfcGIyLkRlc2NyaXB0b3JQcm90by4KKyAgICAiIiIKKyAgICAjIFRoaXMgZnVuY3Rpb24gaXMgb3ZlcnJpZGVuIHRvIGdpdmUgYSBiZXR0ZXIgZG9jIGNvbW1lbnQuCisgICAgc3VwZXIoRGVzY3JpcHRvciwgc2VsZikuQ29weVRvUHJvdG8ocHJvdG8pCisKKworIyBUT0RPKHJvYmluc29uKTogV2Ugc2hvdWxkIGhhdmUgYWdncmVzc2l2ZSBjaGVja2luZyBoZXJlLAorIyBmb3IgZXhhbXBsZToKKyMgICAqIElmIHlvdSBzcGVjaWZ5IGEgcmVwZWF0ZWQgZmllbGQsIHlvdSBzaG91bGQgbm90IGJlIGFsbG93ZWQKKyMgICAgIHRvIHNwZWNpZnkgYSBkZWZhdWx0IHZhbHVlLgorIyAgICogW090aGVyIGV4YW1wbGVzIGhlcmUgYXMgbmVlZGVkXS4KKyMKKyMgVE9ETyhyb2JpbnNvbik6IGZvciB0aGlzIGFuZCBvdGhlciAqRGVzY3JpcHRvciBjbGFzc2VzLCB3ZQorIyBtaWdodCBhbHNvIHdhbnQgdG8gbG9jayB0aGluZ3MgZG93biBhZ2dyZXNzaXZlbHkgKGUuZy4sCisjIHByZXZlbnQgY2xpZW50cyBmcm9tIHNldHRpbmcgdGhlIGF0dHJpYnV0ZXMpLiAgSGF2aW5nCisjIHN0cm9uZ2VyIGludmFyaWFudHMgaGVyZSBpbiBnZW5lcmFsIHdpbGwgcmVkdWNlIHRoZSBudW1iZXIKKyMgb2YgcnVudGltZSBjaGVja3Mgd2UgbXVzdCBkbyBpbiByZWZsZWN0aW9uLnB5Li4uCitjbGFzcyBGaWVsZERlc2NyaXB0b3IoRGVzY3JpcHRvckJhc2UpOgorCisgICIiIkRlc2NyaXB0b3IgZm9yIGEgc2luZ2xlIGZpZWxkIGluIGEgLnByb3RvIGZpbGUuCisKKyAgQSBGaWVsZERlc2NyaXB0b3IgaW5zdGFuY2UgaGFzIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczoKKworICAgIG5hbWU6IChzdHIpIE5hbWUgb2YgdGhpcyBmaWVsZCwgZXhhY3RseSBhcyBpdCBhcHBlYXJzIGluIC5wcm90by4KKyAgICBmdWxsX25hbWU6IChzdHIpIE5hbWUgb2YgdGhpcyBmaWVsZCwgaW5jbHVkaW5nIGNvbnRhaW5pbmcgc2NvcGUuICBUaGlzIGlzCisgICAgICBwYXJ0aWN1bGFybHkgcmVsZXZhbnQgZm9yIGV4dGVuc2lvbnMuCisgICAgaW5kZXg6IChpbnQpIERlbnNlLCAwLWluZGV4ZWQgaW5kZXggZ2l2aW5nIHRoZSBvcmRlciB0aGF0IHRoaXMKKyAgICAgIGZpZWxkIHRleHR1YWxseSBhcHBlYXJzIHdpdGhpbiBpdHMgbWVzc2FnZSBpbiB0aGUgLnByb3RvIGZpbGUuCisgICAgbnVtYmVyOiAoaW50KSBUYWcgbnVtYmVyIGRlY2xhcmVkIGZvciB0aGlzIGZpZWxkIGluIHRoZSAucHJvdG8gZmlsZS4KKworICAgIHR5cGU6IChPbmUgb2YgdGhlIFRZUEVfKiBjb25zdGFudHMgYmVsb3cpIERlY2xhcmVkIHR5cGUuCisgICAgY3BwX3R5cGU6IChPbmUgb2YgdGhlIENQUFRZUEVfKiBjb25zdGFudHMgYmVsb3cpIEMrKyB0eXBlIHVzZWQgdG8KKyAgICAgIHJlcHJlc2VudCB0aGlzIGZpZWxkLgorCisgICAgbGFiZWw6IChPbmUgb2YgdGhlIExBQkVMXyogY29uc3RhbnRzIGJlbG93KSBUZWxscyB3aGV0aGVyIHRoaXMKKyAgICAgIGZpZWxkIGlzIG9wdGlvbmFsLCByZXF1aXJlZCwgb3IgcmVwZWF0ZWQuCisgICAgaGFzX2RlZmF1bHRfdmFsdWU6IChib29sKSBUcnVlIGlmIHRoaXMgZmllbGQgaGFzIGEgZGVmYXVsdCB2YWx1ZSBkZWZpbmVkLAorICAgICAgb3RoZXJ3aXNlIGZhbHNlLgorICAgIGRlZmF1bHRfdmFsdWU6IChWYXJpZXMpIERlZmF1bHQgdmFsdWUgb2YgdGhpcyBmaWVsZC4gIE9ubHkKKyAgICAgIG1lYW5pbmdmdWwgZm9yIG5vbi1yZXBlYXRlZCBzY2FsYXIgZmllbGRzLiAgUmVwZWF0ZWQgZmllbGRzCisgICAgICBzaG91bGQgYWx3YXlzIHNldCB0aGlzIHRvIFtdLCBhbmQgbm9uLXJlcGVhdGVkIGNvbXBvc2l0ZQorICAgICAgZmllbGRzIHNob3VsZCBhbHdheXMgc2V0IHRoaXMgdG8gTm9uZS4KKworICAgIGNvbnRhaW5pbmdfdHlwZTogKERlc2NyaXB0b3IpIERlc2NyaXB0b3Igb2YgdGhlIHByb3RvY29sIG1lc3NhZ2UKKyAgICAgIHR5cGUgdGhhdCBjb250YWlucyB0aGlzIGZpZWxkLiAgU2V0IGJ5IHRoZSBEZXNjcmlwdG9yIGNvbnN0cnVjdG9yCisgICAgICBpZiB3ZSdyZSBwYXNzZWQgaW50byBvbmUuCisgICAgICBTb21ld2hhdCBjb25mdXNpbmdseSwgZm9yIGV4dGVuc2lvbiBmaWVsZHMsIHRoaXMgaXMgdGhlCisgICAgICBkZXNjcmlwdG9yIG9mIHRoZSBFWFRFTkRFRCBtZXNzYWdlLCBub3QgdGhlIGRlc2NyaXB0b3IKKyAgICAgIG9mIHRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhpcyBmaWVsZC4gIChTZWUgaXNfZXh0ZW5zaW9uIGFuZAorICAgICAgZXh0ZW5zaW9uX3Njb3BlIGJlbG93KS4KKyAgICBtZXNzYWdlX3R5cGU6IChEZXNjcmlwdG9yKSBJZiBhIGNvbXBvc2l0ZSBmaWVsZCwgYSBkZXNjcmlwdG9yCisgICAgICBvZiB0aGUgbWVzc2FnZSB0eXBlIGNvbnRhaW5lZCBpbiB0aGlzIGZpZWxkLiAgT3RoZXJ3aXNlLCB0aGlzIGlzIE5vbmUuCisgICAgZW51bV90eXBlOiAoRW51bURlc2NyaXB0b3IpIElmIHRoaXMgZmllbGQgY29udGFpbnMgYW4gZW51bSwgYQorICAgICAgZGVzY3JpcHRvciBvZiB0aGF0IGVudW0uICBPdGhlcndpc2UsIHRoaXMgaXMgTm9uZS4KKworICAgIGlzX2V4dGVuc2lvbjogVHJ1ZSBpZmYgdGhpcyBkZXNjcmliZXMgYW4gZXh0ZW5zaW9uIGZpZWxkLgorICAgIGV4dGVuc2lvbl9zY29wZTogKERlc2NyaXB0b3IpIE9ubHkgbWVhbmluZ2Z1bCBpZiBpc19leHRlbnNpb24gaXMgVHJ1ZS4KKyAgICAgIEdpdmVzIHRoZSBtZXNzYWdlIHRoYXQgaW1tZWRpYXRlbHkgY29udGFpbnMgdGhpcyBleHRlbnNpb24gZmllbGQuCisgICAgICBXaWxsIGJlIE5vbmUgaWZmIHdlJ3JlIGEgdG9wLWxldmVsIChmaWxlLWxldmVsKSBleHRlbnNpb24gZmllbGQuCisKKyAgICBvcHRpb25zOiAoZGVzY3JpcHRvcl9wYjIuRmllbGRPcHRpb25zKSBQcm90b2NvbCBtZXNzYWdlIGZpZWxkIG9wdGlvbnMgb3IKKyAgICAgIE5vbmUgdG8gdXNlIGRlZmF1bHQgZmllbGQgb3B0aW9ucy4KKworICAgIGNvbnRhaW5pbmdfb25lb2Y6IChPbmVvZkRlc2NyaXB0b3IpIElmIHRoZSBmaWVsZCBpcyBhIG1lbWJlciBvZiBhIG9uZW9mCisgICAgICB1bmlvbiwgY29udGFpbnMgaXRzIGRlc2NyaXB0b3IuIE90aGVyd2lzZSwgTm9uZS4KKyAgIiIiCisKKyAgIyBNdXN0IGJlIGNvbnNpc3RlbnQgd2l0aCBDKysgRmllbGREZXNjcmlwdG9yOjpUeXBlIGVudW0gaW4KKyAgIyBkZXNjcmlwdG9yLmguCisgICMKKyAgIyBUT0RPKHJvYmluc29uKTogRmluZCBhIHdheSB0byBlbGltaW5hdGUgdGhpcyByZXBldGl0aW9uLgorICBUWVBFX0RPVUJMRSAgICAgICAgID0gMQorICBUWVBFX0ZMT0FUICAgICAgICAgID0gMgorICBUWVBFX0lOVDY0ICAgICAgICAgID0gMworICBUWVBFX1VJTlQ2NCAgICAgICAgID0gNAorICBUWVBFX0lOVDMyICAgICAgICAgID0gNQorICBUWVBFX0ZJWEVENjQgICAgICAgID0gNgorICBUWVBFX0ZJWEVEMzIgICAgICAgID0gNworICBUWVBFX0JPT0wgICAgICAgICAgID0gOAorICBUWVBFX1NUUklORyAgICAgICAgID0gOQorICBUWVBFX0dST1VQICAgICAgICAgID0gMTAKKyAgVFlQRV9NRVNTQUdFICAgICAgICA9IDExCisgIFRZUEVfQllURVMgICAgICAgICAgPSAxMgorICBUWVBFX1VJTlQzMiAgICAgICAgID0gMTMKKyAgVFlQRV9FTlVNICAgICAgICAgICA9IDE0CisgIFRZUEVfU0ZJWEVEMzIgICAgICAgPSAxNQorICBUWVBFX1NGSVhFRDY0ICAgICAgID0gMTYKKyAgVFlQRV9TSU5UMzIgICAgICAgICA9IDE3CisgIFRZUEVfU0lOVDY0ICAgICAgICAgPSAxOAorICBNQVhfVFlQRSAgICAgICAgICAgID0gMTgKKworICAjIE11c3QgYmUgY29uc2lzdGVudCB3aXRoIEMrKyBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgZW51bSBpbgorICAjIGRlc2NyaXB0b3IuaC4KKyAgIworICAjIFRPRE8ocm9iaW5zb24pOiBGaW5kIGEgd2F5IHRvIGVsaW1pbmF0ZSB0aGlzIHJlcGV0aXRpb24uCisgIENQUFRZUEVfSU5UMzIgICAgICAgPSAxCisgIENQUFRZUEVfSU5UNjQgICAgICAgPSAyCisgIENQUFRZUEVfVUlOVDMyICAgICAgPSAzCisgIENQUFRZUEVfVUlOVDY0ICAgICAgPSA0CisgIENQUFRZUEVfRE9VQkxFICAgICAgPSA1CisgIENQUFRZUEVfRkxPQVQgICAgICAgPSA2CisgIENQUFRZUEVfQk9PTCAgICAgICAgPSA3CisgIENQUFRZUEVfRU5VTSAgICAgICAgPSA4CisgIENQUFRZUEVfU1RSSU5HICAgICAgPSA5CisgIENQUFRZUEVfTUVTU0FHRSAgICAgPSAxMAorICBNQVhfQ1BQVFlQRSAgICAgICAgID0gMTAKKworICBfUFlUSE9OX1RPX0NQUF9QUk9UT19UWVBFX01BUCA9IHsKKyAgICAgIFRZUEVfRE9VQkxFOiBDUFBUWVBFX0RPVUJMRSwKKyAgICAgIFRZUEVfRkxPQVQ6IENQUFRZUEVfRkxPQVQsCisgICAgICBUWVBFX0VOVU06IENQUFRZUEVfRU5VTSwKKyAgICAgIFRZUEVfSU5UNjQ6IENQUFRZUEVfSU5UNjQsCisgICAgICBUWVBFX1NJTlQ2NDogQ1BQVFlQRV9JTlQ2NCwKKyAgICAgIFRZUEVfU0ZJWEVENjQ6IENQUFRZUEVfSU5UNjQsCisgICAgICBUWVBFX1VJTlQ2NDogQ1BQVFlQRV9VSU5UNjQsCisgICAgICBUWVBFX0ZJWEVENjQ6IENQUFRZUEVfVUlOVDY0LAorICAgICAgVFlQRV9JTlQzMjogQ1BQVFlQRV9JTlQzMiwKKyAgICAgIFRZUEVfU0ZJWEVEMzI6IENQUFRZUEVfSU5UMzIsCisgICAgICBUWVBFX1NJTlQzMjogQ1BQVFlQRV9JTlQzMiwKKyAgICAgIFRZUEVfVUlOVDMyOiBDUFBUWVBFX1VJTlQzMiwKKyAgICAgIFRZUEVfRklYRUQzMjogQ1BQVFlQRV9VSU5UMzIsCisgICAgICBUWVBFX0JZVEVTOiBDUFBUWVBFX1NUUklORywKKyAgICAgIFRZUEVfU1RSSU5HOiBDUFBUWVBFX1NUUklORywKKyAgICAgIFRZUEVfQk9PTDogQ1BQVFlQRV9CT09MLAorICAgICAgVFlQRV9NRVNTQUdFOiBDUFBUWVBFX01FU1NBR0UsCisgICAgICBUWVBFX0dST1VQOiBDUFBUWVBFX01FU1NBR0UKKyAgICAgIH0KKworICAjIE11c3QgYmUgY29uc2lzdGVudCB3aXRoIEMrKyBGaWVsZERlc2NyaXB0b3I6OkxhYmVsIGVudW0gaW4KKyAgIyBkZXNjcmlwdG9yLmguCisgICMKKyAgIyBUT0RPKHJvYmluc29uKTogRmluZCBhIHdheSB0byBlbGltaW5hdGUgdGhpcyByZXBldGl0aW9uLgorICBMQUJFTF9PUFRJT05BTCAgICAgID0gMQorICBMQUJFTF9SRVFVSVJFRCAgICAgID0gMgorICBMQUJFTF9SRVBFQVRFRCAgICAgID0gMworICBNQVhfTEFCRUwgICAgICAgICAgID0gMworCisgICMgTXVzdCBiZSBjb25zaXN0ZW50IHdpdGggQysrIGNvbnN0YW50cyBrTWF4TnVtYmVyLCBrRmlyc3RSZXNlcnZlZE51bWJlciwKKyAgIyBhbmQga0xhc3RSZXNlcnZlZE51bWJlciBpbiBkZXNjcmlwdG9yLmgKKyAgTUFYX0ZJRUxEX05VTUJFUiA9ICgxIDw8IDI5KSAtIDEKKyAgRklSU1RfUkVTRVJWRURfRklFTERfTlVNQkVSID0gMTkwMDAKKyAgTEFTVF9SRVNFUlZFRF9GSUVMRF9OVU1CRVIgPSAxOTk5OQorCisgIGlmIF9VU0VfQ19ERVNDUklQVE9SUzoKKyAgICBfQ19ERVNDUklQVE9SX0NMQVNTID0gX21lc3NhZ2UuRmllbGREZXNjcmlwdG9yCisKKyAgICBkZWYgX19uZXdfXyhjbHMsIG5hbWUsIGZ1bGxfbmFtZSwgaW5kZXgsIG51bWJlciwgdHlwZSwgY3BwX3R5cGUsIGxhYmVsLAorICAgICAgICAgICAgICAgIGRlZmF1bHRfdmFsdWUsIG1lc3NhZ2VfdHlwZSwgZW51bV90eXBlLCBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uLCBleHRlbnNpb25fc2NvcGUsIG9wdGlvbnM9Tm9uZSwKKyAgICAgICAgICAgICAgICBoYXNfZGVmYXVsdF92YWx1ZT1UcnVlLCBjb250YWluaW5nX29uZW9mPU5vbmUpOgorICAgICAgX21lc3NhZ2UuTWVzc2FnZS5fQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgpCisgICAgICBpZiBpc19leHRlbnNpb246CisgICAgICAgIHJldHVybiBfbWVzc2FnZS5NZXNzYWdlLl9HZXRFeHRlbnNpb25EZXNjcmlwdG9yKGZ1bGxfbmFtZSkKKyAgICAgIGVsc2U6CisgICAgICAgIHJldHVybiBfbWVzc2FnZS5NZXNzYWdlLl9HZXRGaWVsZERlc2NyaXB0b3IoZnVsbF9uYW1lKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lLCBmdWxsX25hbWUsIGluZGV4LCBudW1iZXIsIHR5cGUsIGNwcF90eXBlLCBsYWJlbCwKKyAgICAgICAgICAgICAgIGRlZmF1bHRfdmFsdWUsIG1lc3NhZ2VfdHlwZSwgZW51bV90eXBlLCBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICBpc19leHRlbnNpb24sIGV4dGVuc2lvbl9zY29wZSwgb3B0aW9ucz1Ob25lLAorICAgICAgICAgICAgICAgaGFzX2RlZmF1bHRfdmFsdWU9VHJ1ZSwgY29udGFpbmluZ19vbmVvZj1Ob25lKToKKyAgICAiIiJUaGUgYXJndW1lbnRzIGFyZSBhcyBkZXNjcmliZWQgaW4gdGhlIGRlc2NyaXB0aW9uIG9mIEZpZWxkRGVzY3JpcHRvcgorICAgIGF0dHJpYnV0ZXMgYWJvdmUuCisKKyAgICBOb3RlIHRoYXQgY29udGFpbmluZ190eXBlIG1heSBiZSBOb25lLCBhbmQgbWF5IGJlIHNldCBsYXRlciBpZiBuZWNlc3NhcnkKKyAgICAodG8gZGVhbCB3aXRoIGNpcmN1bGFyIHJlZmVyZW5jZXMgYmV0d2VlbiBtZXNzYWdlIHR5cGVzLCBmb3IgZXhhbXBsZSkuCisgICAgTGlrZXdpc2UgZm9yIGV4dGVuc2lvbl9zY29wZS4KKyAgICAiIiIKKyAgICBzdXBlcihGaWVsZERlc2NyaXB0b3IsIHNlbGYpLl9faW5pdF9fKG9wdGlvbnMsICdGaWVsZE9wdGlvbnMnKQorICAgIHNlbGYubmFtZSA9IG5hbWUKKyAgICBzZWxmLmZ1bGxfbmFtZSA9IGZ1bGxfbmFtZQorICAgIHNlbGYuaW5kZXggPSBpbmRleAorICAgIHNlbGYubnVtYmVyID0gbnVtYmVyCisgICAgc2VsZi50eXBlID0gdHlwZQorICAgIHNlbGYuY3BwX3R5cGUgPSBjcHBfdHlwZQorICAgIHNlbGYubGFiZWwgPSBsYWJlbAorICAgIHNlbGYuaGFzX2RlZmF1bHRfdmFsdWUgPSBoYXNfZGVmYXVsdF92YWx1ZQorICAgIHNlbGYuZGVmYXVsdF92YWx1ZSA9IGRlZmF1bHRfdmFsdWUKKyAgICBzZWxmLmNvbnRhaW5pbmdfdHlwZSA9IGNvbnRhaW5pbmdfdHlwZQorICAgIHNlbGYubWVzc2FnZV90eXBlID0gbWVzc2FnZV90eXBlCisgICAgc2VsZi5lbnVtX3R5cGUgPSBlbnVtX3R5cGUKKyAgICBzZWxmLmlzX2V4dGVuc2lvbiA9IGlzX2V4dGVuc2lvbgorICAgIHNlbGYuZXh0ZW5zaW9uX3Njb3BlID0gZXh0ZW5zaW9uX3Njb3BlCisgICAgc2VsZi5jb250YWluaW5nX29uZW9mID0gY29udGFpbmluZ19vbmVvZgorICAgIGlmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgPT0gJ2NwcCc6CisgICAgICBpZiBpc19leHRlbnNpb246CisgICAgICAgICMgcHlsaW50OiBkaXNhYmxlPXByb3RlY3RlZC1hY2Nlc3MKKyAgICAgICAgc2VsZi5fY2Rlc2NyaXB0b3IgPSAoCisgICAgICAgICAgICBfbWVzc2FnZS5NZXNzYWdlLl9HZXRFeHRlbnNpb25EZXNjcmlwdG9yKGZ1bGxfbmFtZSkpCisgICAgICAgICMgcHlsaW50OiBlbmFibGU9cHJvdGVjdGVkLWFjY2VzcworICAgICAgZWxzZToKKyAgICAgICAgIyBweWxpbnQ6IGRpc2FibGU9cHJvdGVjdGVkLWFjY2VzcworICAgICAgICBzZWxmLl9jZGVzY3JpcHRvciA9IF9tZXNzYWdlLk1lc3NhZ2UuX0dldEZpZWxkRGVzY3JpcHRvcihmdWxsX25hbWUpCisgICAgICAgICMgcHlsaW50OiBlbmFibGU9cHJvdGVjdGVkLWFjY2VzcworICAgIGVsc2U6CisgICAgICBzZWxmLl9jZGVzY3JpcHRvciA9IE5vbmUKKworICBAc3RhdGljbWV0aG9kCisgIGRlZiBQcm90b1R5cGVUb0NwcFByb3RvVHlwZShwcm90b190eXBlKToKKyAgICAiIiJDb252ZXJ0cyBmcm9tIGEgUHl0aG9uIHByb3RvIHR5cGUgdG8gYSBDKysgUHJvdG8gVHlwZS4KKworICAgIFRoZSBQeXRob24gUHJvdG9jb2xCdWZmZXIgY2xhc3NlcyBzcGVjaWZ5IGJvdGggdGhlICdQeXRob24nIGRhdGF0eXBlIGFuZCB0aGUKKyAgICAnQysrJyBkYXRhdHlwZSAtIGFuZCB0aGV5J3JlIG5vdCB0aGUgc2FtZS4gVGhpcyBoZWxwZXIgbWV0aG9kIHNob3VsZAorICAgIHRyYW5zbGF0ZSBmcm9tIG9uZSB0byBhbm90aGVyLgorCisgICAgQXJnczoKKyAgICAgIHByb3RvX3R5cGU6IHRoZSBQeXRob24gcHJvdG8gdHlwZSAoZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV8qKQorICAgIFJldHVybnM6CisgICAgICBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5DUFBUWVBFXyosIHRoZSBDKysgdHlwZS4KKyAgICBSYWlzZXM6CisgICAgICBUeXBlVHJhbnNmb3JtYXRpb25FcnJvcjogd2hlbiB0aGUgUHl0aG9uIHByb3RvIHR5cGUgaXNuJ3Qga25vd24uCisgICAgIiIiCisgICAgdHJ5OgorICAgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvci5fUFlUSE9OX1RPX0NQUF9QUk9UT19UWVBFX01BUFtwcm90b190eXBlXQorICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgIHJhaXNlIFR5cGVUcmFuc2Zvcm1hdGlvbkVycm9yKCdVbmtub3duIHByb3RvX3R5cGU6ICVzJyAlIHByb3RvX3R5cGUpCisKKworY2xhc3MgRW51bURlc2NyaXB0b3IoX05lc3RlZERlc2NyaXB0b3JCYXNlKToKKworICAiIiJEZXNjcmlwdG9yIGZvciBhbiBlbnVtIGRlZmluZWQgaW4gYSAucHJvdG8gZmlsZS4KKworICBBbiBFbnVtRGVzY3JpcHRvciBpbnN0YW5jZSBoYXMgdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOgorCisgICAgbmFtZTogKHN0cikgTmFtZSBvZiB0aGUgZW51bSB0eXBlLgorICAgIGZ1bGxfbmFtZTogKHN0cikgRnVsbCBuYW1lIG9mIHRoZSB0eXBlLCBpbmNsdWRpbmcgcGFja2FnZSBuYW1lCisgICAgICBhbmQgYW55IGVuY2xvc2luZyB0eXBlKHMpLgorCisgICAgdmFsdWVzOiAobGlzdCBvZiBFbnVtVmFsdWVEZXNjcmlwdG9ycykgTGlzdCBvZiB0aGUgdmFsdWVzCisgICAgICBpbiB0aGlzIGVudW0uCisgICAgdmFsdWVzX2J5X25hbWU6IChkaWN0IHN0ciAtPiBFbnVtVmFsdWVEZXNjcmlwdG9yKSBTYW1lIGFzIHx2YWx1ZXN8LAorICAgICAgYnV0IGluZGV4ZWQgYnkgdGhlICJuYW1lIiBmaWVsZCBvZiBlYWNoIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgICAgdmFsdWVzX2J5X251bWJlcjogKGRpY3QgaW50IC0+IEVudW1WYWx1ZURlc2NyaXB0b3IpIFNhbWUgYXMgfHZhbHVlc3wsCisgICAgICBidXQgaW5kZXhlZCBieSB0aGUgIm51bWJlciIgZmllbGQgb2YgZWFjaCBFbnVtVmFsdWVEZXNjcmlwdG9yLgorICAgIGNvbnRhaW5pbmdfdHlwZTogKERlc2NyaXB0b3IpIERlc2NyaXB0b3Igb2YgdGhlIGltbWVkaWF0ZSBjb250YWluaW5nCisgICAgICB0eXBlIG9mIHRoaXMgZW51bSwgb3IgTm9uZSBpZiB0aGlzIGlzIGFuIGVudW0gZGVmaW5lZCBhdCB0aGUKKyAgICAgIHRvcCBsZXZlbCBpbiBhIC5wcm90byBmaWxlLiAgU2V0IGJ5IERlc2NyaXB0b3IncyBjb25zdHJ1Y3RvcgorICAgICAgaWYgd2UncmUgcGFzc2VkIGludG8gb25lLgorICAgIGZpbGU6IChGaWxlRGVzY3JpcHRvcikgUmVmZXJlbmNlIHRvIGZpbGUgZGVzY3JpcHRvci4KKyAgICBvcHRpb25zOiAoZGVzY3JpcHRvcl9wYjIuRW51bU9wdGlvbnMpIEVudW0gb3B0aW9ucyBtZXNzYWdlIG9yCisgICAgICBOb25lIHRvIHVzZSBkZWZhdWx0IGVudW0gb3B0aW9ucy4KKyAgIiIiCisKKyAgaWYgX1VTRV9DX0RFU0NSSVBUT1JTOgorICAgIF9DX0RFU0NSSVBUT1JfQ0xBU1MgPSBfbWVzc2FnZS5FbnVtRGVzY3JpcHRvcgorCisgICAgZGVmIF9fbmV3X18oY2xzLCBuYW1lLCBmdWxsX25hbWUsIGZpbGVuYW1lLCB2YWx1ZXMsCisgICAgICAgICAgICAgICAgY29udGFpbmluZ190eXBlPU5vbmUsIG9wdGlvbnM9Tm9uZSwgZmlsZT1Ob25lLAorICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRfc3RhcnQ9Tm9uZSwgc2VyaWFsaXplZF9lbmQ9Tm9uZSk6CisgICAgICBfbWVzc2FnZS5NZXNzYWdlLl9DaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKCkKKyAgICAgIHJldHVybiBfbWVzc2FnZS5NZXNzYWdlLl9HZXRFbnVtRGVzY3JpcHRvcihmdWxsX25hbWUpCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIGZ1bGxfbmFtZSwgZmlsZW5hbWUsIHZhbHVlcywKKyAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZT1Ob25lLCBvcHRpb25zPU5vbmUsIGZpbGU9Tm9uZSwKKyAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRfc3RhcnQ9Tm9uZSwgc2VyaWFsaXplZF9lbmQ9Tm9uZSk6CisgICAgIiIiQXJndW1lbnRzIGFyZSBhcyBkZXNjcmliZWQgaW4gdGhlIGF0dHJpYnV0ZSBkZXNjcmlwdGlvbiBhYm92ZS4KKworICAgIE5vdGUgdGhhdCBmaWxlbmFtZSBpcyBhbiBvYnNvbGV0ZSBhcmd1bWVudCwgdGhhdCBpcyBub3QgdXNlZCBhbnltb3JlLgorICAgIFBsZWFzZSB1c2UgZmlsZS5uYW1lIHRvIGFjY2VzcyB0aGlzIGFzIGFuIGF0dHJpYnV0ZS4KKyAgICAiIiIKKyAgICBzdXBlcihFbnVtRGVzY3JpcHRvciwgc2VsZikuX19pbml0X18oCisgICAgICAgIG9wdGlvbnMsICdFbnVtT3B0aW9ucycsIG5hbWUsIGZ1bGxfbmFtZSwgZmlsZSwKKyAgICAgICAgY29udGFpbmluZ190eXBlLCBzZXJpYWxpemVkX3N0YXJ0PXNlcmlhbGl6ZWRfc3RhcnQsCisgICAgICAgIHNlcmlhbGl6ZWRfZW5kPXNlcmlhbGl6ZWRfZW5kKQorCisgICAgc2VsZi52YWx1ZXMgPSB2YWx1ZXMKKyAgICBmb3IgdmFsdWUgaW4gc2VsZi52YWx1ZXM6CisgICAgICB2YWx1ZS50eXBlID0gc2VsZgorICAgIHNlbGYudmFsdWVzX2J5X25hbWUgPSBkaWN0KCh2Lm5hbWUsIHYpIGZvciB2IGluIHZhbHVlcykKKyAgICBzZWxmLnZhbHVlc19ieV9udW1iZXIgPSBkaWN0KCh2Lm51bWJlciwgdikgZm9yIHYgaW4gdmFsdWVzKQorCisgIGRlZiBDb3B5VG9Qcm90byhzZWxmLCBwcm90byk6CisgICAgIiIiQ29waWVzIHRoaXMgdG8gYSBkZXNjcmlwdG9yX3BiMi5FbnVtRGVzY3JpcHRvclByb3RvLgorCisgICAgQXJnczoKKyAgICAgIHByb3RvOiBBbiBlbXB0eSBkZXNjcmlwdG9yX3BiMi5FbnVtRGVzY3JpcHRvclByb3RvLgorICAgICIiIgorICAgICMgVGhpcyBmdW5jdGlvbiBpcyBvdmVycmlkZW4gdG8gZ2l2ZSBhIGJldHRlciBkb2MgY29tbWVudC4KKyAgICBzdXBlcihFbnVtRGVzY3JpcHRvciwgc2VsZikuQ29weVRvUHJvdG8ocHJvdG8pCisKKworY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvcihEZXNjcmlwdG9yQmFzZSk6CisKKyAgIiIiRGVzY3JpcHRvciBmb3IgYSBzaW5nbGUgdmFsdWUgd2l0aGluIGFuIGVudW0uCisKKyAgICBuYW1lOiAoc3RyKSBOYW1lIG9mIHRoaXMgdmFsdWUuCisgICAgaW5kZXg6IChpbnQpIERlbnNlLCAwLWluZGV4ZWQgaW5kZXggZ2l2aW5nIHRoZSBvcmRlciB0aGF0IHRoaXMKKyAgICAgIHZhbHVlIGFwcGVhcnMgdGV4dHVhbGx5IHdpdGhpbiBpdHMgZW51bSBpbiB0aGUgLnByb3RvIGZpbGUuCisgICAgbnVtYmVyOiAoaW50KSBBY3R1YWwgbnVtYmVyIGFzc2lnbmVkIHRvIHRoaXMgZW51bSB2YWx1ZS4KKyAgICB0eXBlOiAoRW51bURlc2NyaXB0b3IpIEVudW1EZXNjcmlwdG9yIHRvIHdoaWNoIHRoaXMgdmFsdWUKKyAgICAgIGJlbG9uZ3MuICBTZXQgYnkgRW51bURlc2NyaXB0b3IncyBjb25zdHJ1Y3RvciBpZiB3ZSdyZQorICAgICAgcGFzc2VkIGludG8gb25lLgorICAgIG9wdGlvbnM6IChkZXNjcmlwdG9yX3BiMi5FbnVtVmFsdWVPcHRpb25zKSBFbnVtIHZhbHVlIG9wdGlvbnMgbWVzc2FnZSBvcgorICAgICAgTm9uZSB0byB1c2UgZGVmYXVsdCBlbnVtIHZhbHVlIG9wdGlvbnMgb3B0aW9ucy4KKyAgIiIiCisKKyAgaWYgX1VTRV9DX0RFU0NSSVBUT1JTOgorICAgIF9DX0RFU0NSSVBUT1JfQ0xBU1MgPSBfbWVzc2FnZS5FbnVtVmFsdWVEZXNjcmlwdG9yCisKKyAgICBkZWYgX19uZXdfXyhjbHMsIG5hbWUsIGluZGV4LCBudW1iZXIsIHR5cGU9Tm9uZSwgb3B0aW9ucz1Ob25lKToKKyAgICAgIF9tZXNzYWdlLk1lc3NhZ2UuX0NoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoKQorICAgICAgIyBUaGVyZSBpcyBubyB3YXkgd2UgY2FuIGJ1aWxkIGEgY29tcGxldGUgRW51bVZhbHVlRGVzY3JpcHRvciB3aXRoIHRoZQorICAgICAgIyBnaXZlbiBwYXJhbWV0ZXJzICh0aGUgbmFtZSBvZiB0aGUgRW51bSBpcyBub3Qga25vd24sIGZvciBleGFtcGxlKS4KKyAgICAgICMgRm9ydHVuYXRlbHkgZ2VuZXJhdGVkIGZpbGVzIGp1c3QgcGFzcyBpdCB0byB0aGUgRW51bURlc2NyaXB0b3IoKQorICAgICAgIyBjb25zdHJ1Y3Rvciwgd2hpY2ggd2lsbCBpZ25vcmUgaXQsIHNvIHJldHVybmluZyBOb25lIGlzIGdvb2QgZW5vdWdoLgorICAgICAgcmV0dXJuIE5vbmUKKworICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgaW5kZXgsIG51bWJlciwgdHlwZT1Ob25lLCBvcHRpb25zPU5vbmUpOgorICAgICIiIkFyZ3VtZW50cyBhcmUgYXMgZGVzY3JpYmVkIGluIHRoZSBhdHRyaWJ1dGUgZGVzY3JpcHRpb24gYWJvdmUuIiIiCisgICAgc3VwZXIoRW51bVZhbHVlRGVzY3JpcHRvciwgc2VsZikuX19pbml0X18ob3B0aW9ucywgJ0VudW1WYWx1ZU9wdGlvbnMnKQorICAgIHNlbGYubmFtZSA9IG5hbWUKKyAgICBzZWxmLmluZGV4ID0gaW5kZXgKKyAgICBzZWxmLm51bWJlciA9IG51bWJlcgorICAgIHNlbGYudHlwZSA9IHR5cGUKKworCitjbGFzcyBPbmVvZkRlc2NyaXB0b3Iob2JqZWN0KToKKyAgIiIiRGVzY3JpcHRvciBmb3IgYSBvbmVvZiBmaWVsZC4KKworICAgIG5hbWU6IChzdHIpIE5hbWUgb2YgdGhlIG9uZW9mIGZpZWxkLgorICAgIGZ1bGxfbmFtZTogKHN0cikgRnVsbCBuYW1lIG9mIHRoZSBvbmVvZiBmaWVsZCwgaW5jbHVkaW5nIHBhY2thZ2UgbmFtZS4KKyAgICBpbmRleDogKGludCkgMC1iYXNlZCBpbmRleCBnaXZpbmcgdGhlIG9yZGVyIG9mIHRoZSBvbmVvZiBmaWVsZCBpbnNpZGUKKyAgICAgIGl0cyBjb250YWluaW5nIHR5cGUuCisgICAgY29udGFpbmluZ190eXBlOiAoRGVzY3JpcHRvcikgRGVzY3JpcHRvciBvZiB0aGUgcHJvdG9jb2wgbWVzc2FnZQorICAgICAgdHlwZSB0aGF0IGNvbnRhaW5zIHRoaXMgZmllbGQuICBTZXQgYnkgdGhlIERlc2NyaXB0b3IgY29uc3RydWN0b3IKKyAgICAgIGlmIHdlJ3JlIHBhc3NlZCBpbnRvIG9uZS4KKyAgICBmaWVsZHM6IChsaXN0IG9mIEZpZWxkRGVzY3JpcHRvcikgVGhlIGxpc3Qgb2YgZmllbGQgZGVzY3JpcHRvcnMgdGhpcworICAgICAgb25lb2YgY2FuIGNvbnRhaW4uCisgICIiIgorCisgIGlmIF9VU0VfQ19ERVNDUklQVE9SUzoKKyAgICBfQ19ERVNDUklQVE9SX0NMQVNTID0gX21lc3NhZ2UuT25lb2ZEZXNjcmlwdG9yCisKKyAgICBkZWYgX19uZXdfXyhjbHMsIG5hbWUsIGZ1bGxfbmFtZSwgaW5kZXgsIGNvbnRhaW5pbmdfdHlwZSwgZmllbGRzKToKKyAgICAgIF9tZXNzYWdlLk1lc3NhZ2UuX0NoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoKQorICAgICAgcmV0dXJuIF9tZXNzYWdlLk1lc3NhZ2UuX0dldE9uZW9mRGVzY3JpcHRvcihmdWxsX25hbWUpCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIGZ1bGxfbmFtZSwgaW5kZXgsIGNvbnRhaW5pbmdfdHlwZSwgZmllbGRzKToKKyAgICAiIiJBcmd1bWVudHMgYXJlIGFzIGRlc2NyaWJlZCBpbiB0aGUgYXR0cmlidXRlIGRlc2NyaXB0aW9uIGFib3ZlLiIiIgorICAgIHNlbGYubmFtZSA9IG5hbWUKKyAgICBzZWxmLmZ1bGxfbmFtZSA9IGZ1bGxfbmFtZQorICAgIHNlbGYuaW5kZXggPSBpbmRleAorICAgIHNlbGYuY29udGFpbmluZ190eXBlID0gY29udGFpbmluZ190eXBlCisgICAgc2VsZi5maWVsZHMgPSBmaWVsZHMKKworCitjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcihfTmVzdGVkRGVzY3JpcHRvckJhc2UpOgorCisgICIiIkRlc2NyaXB0b3IgZm9yIGEgc2VydmljZS4KKworICAgIG5hbWU6IChzdHIpIE5hbWUgb2YgdGhlIHNlcnZpY2UuCisgICAgZnVsbF9uYW1lOiAoc3RyKSBGdWxsIG5hbWUgb2YgdGhlIHNlcnZpY2UsIGluY2x1ZGluZyBwYWNrYWdlIG5hbWUuCisgICAgaW5kZXg6IChpbnQpIDAtaW5kZXhlZCBpbmRleCBnaXZpbmcgdGhlIG9yZGVyIHRoYXQgdGhpcyBzZXJ2aWNlcworICAgICAgZGVmaW5pdGlvbiBhcHBlYXJzIHdpdGhpbmcgdGhlIC5wcm90byBmaWxlLgorICAgIG1ldGhvZHM6IChsaXN0IG9mIE1ldGhvZERlc2NyaXB0b3IpIExpc3Qgb2YgbWV0aG9kcyBwcm92aWRlZCBieSB0aGlzCisgICAgICBzZXJ2aWNlLgorICAgIG9wdGlvbnM6IChkZXNjcmlwdG9yX3BiMi5TZXJ2aWNlT3B0aW9ucykgU2VydmljZSBvcHRpb25zIG1lc3NhZ2Ugb3IKKyAgICAgIE5vbmUgdG8gdXNlIGRlZmF1bHQgc2VydmljZSBvcHRpb25zLgorICAgIGZpbGU6IChGaWxlRGVzY3JpcHRvcikgUmVmZXJlbmNlIHRvIGZpbGUgaW5mby4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIGZ1bGxfbmFtZSwgaW5kZXgsIG1ldGhvZHMsIG9wdGlvbnM9Tm9uZSwgZmlsZT1Ob25lLAorICAgICAgICAgICAgICAgc2VyaWFsaXplZF9zdGFydD1Ob25lLCBzZXJpYWxpemVkX2VuZD1Ob25lKToKKyAgICBzdXBlcihTZXJ2aWNlRGVzY3JpcHRvciwgc2VsZikuX19pbml0X18oCisgICAgICAgIG9wdGlvbnMsICdTZXJ2aWNlT3B0aW9ucycsIG5hbWUsIGZ1bGxfbmFtZSwgZmlsZSwKKyAgICAgICAgTm9uZSwgc2VyaWFsaXplZF9zdGFydD1zZXJpYWxpemVkX3N0YXJ0LAorICAgICAgICBzZXJpYWxpemVkX2VuZD1zZXJpYWxpemVkX2VuZCkKKyAgICBzZWxmLmluZGV4ID0gaW5kZXgKKyAgICBzZWxmLm1ldGhvZHMgPSBtZXRob2RzCisgICAgIyBTZXQgdGhlIGNvbnRhaW5pbmcgc2VydmljZSBmb3IgZWFjaCBtZXRob2QgaW4gdGhpcyBzZXJ2aWNlLgorICAgIGZvciBtZXRob2QgaW4gc2VsZi5tZXRob2RzOgorICAgICAgbWV0aG9kLmNvbnRhaW5pbmdfc2VydmljZSA9IHNlbGYKKworICBkZWYgRmluZE1ldGhvZEJ5TmFtZShzZWxmLCBuYW1lKToKKyAgICAiIiJTZWFyY2hlcyBmb3IgdGhlIHNwZWNpZmllZCBtZXRob2QsIGFuZCByZXR1cm5zIGl0cyBkZXNjcmlwdG9yLiIiIgorICAgIGZvciBtZXRob2QgaW4gc2VsZi5tZXRob2RzOgorICAgICAgaWYgbmFtZSA9PSBtZXRob2QubmFtZToKKyAgICAgICAgcmV0dXJuIG1ldGhvZAorICAgIHJldHVybiBOb25lCisKKyAgZGVmIENvcHlUb1Byb3RvKHNlbGYsIHByb3RvKToKKyAgICAiIiJDb3BpZXMgdGhpcyB0byBhIGRlc2NyaXB0b3JfcGIyLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8uCisKKyAgICBBcmdzOgorICAgICAgcHJvdG86IEFuIGVtcHR5IGRlc2NyaXB0b3JfcGIyLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8uCisgICAgIiIiCisgICAgIyBUaGlzIGZ1bmN0aW9uIGlzIG92ZXJyaWRlbiB0byBnaXZlIGEgYmV0dGVyIGRvYyBjb21tZW50LgorICAgIHN1cGVyKFNlcnZpY2VEZXNjcmlwdG9yLCBzZWxmKS5Db3B5VG9Qcm90byhwcm90bykKKworCitjbGFzcyBNZXRob2REZXNjcmlwdG9yKERlc2NyaXB0b3JCYXNlKToKKworICAiIiJEZXNjcmlwdG9yIGZvciBhIG1ldGhvZCBpbiBhIHNlcnZpY2UuCisKKyAgbmFtZTogKHN0cikgTmFtZSBvZiB0aGUgbWV0aG9kIHdpdGhpbiB0aGUgc2VydmljZS4KKyAgZnVsbF9uYW1lOiAoc3RyKSBGdWxsIG5hbWUgb2YgbWV0aG9kLgorICBpbmRleDogKGludCkgMC1pbmRleGVkIGluZGV4IG9mIHRoZSBtZXRob2QgaW5zaWRlIHRoZSBzZXJ2aWNlLgorICBjb250YWluaW5nX3NlcnZpY2U6IChTZXJ2aWNlRGVzY3JpcHRvcikgVGhlIHNlcnZpY2UgdGhhdCBjb250YWlucyB0aGlzCisgICAgbWV0aG9kLgorICBpbnB1dF90eXBlOiBUaGUgZGVzY3JpcHRvciBvZiB0aGUgbWVzc2FnZSB0aGF0IHRoaXMgbWV0aG9kIGFjY2VwdHMuCisgIG91dHB1dF90eXBlOiBUaGUgZGVzY3JpcHRvciBvZiB0aGUgbWVzc2FnZSB0aGF0IHRoaXMgbWV0aG9kIHJldHVybnMuCisgIG9wdGlvbnM6IChkZXNjcmlwdG9yX3BiMi5NZXRob2RPcHRpb25zKSBNZXRob2Qgb3B0aW9ucyBtZXNzYWdlIG9yCisgICAgTm9uZSB0byB1c2UgZGVmYXVsdCBtZXRob2Qgb3B0aW9ucy4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIGZ1bGxfbmFtZSwgaW5kZXgsIGNvbnRhaW5pbmdfc2VydmljZSwKKyAgICAgICAgICAgICAgIGlucHV0X3R5cGUsIG91dHB1dF90eXBlLCBvcHRpb25zPU5vbmUpOgorICAgICIiIlRoZSBhcmd1bWVudHMgYXJlIGFzIGRlc2NyaWJlZCBpbiB0aGUgZGVzY3JpcHRpb24gb2YgTWV0aG9kRGVzY3JpcHRvcgorICAgIGF0dHJpYnV0ZXMgYWJvdmUuCisKKyAgICBOb3RlIHRoYXQgY29udGFpbmluZ19zZXJ2aWNlIG1heSBiZSBOb25lLCBhbmQgbWF5IGJlIHNldCBsYXRlciBpZiBuZWNlc3NhcnkuCisgICAgIiIiCisgICAgc3VwZXIoTWV0aG9kRGVzY3JpcHRvciwgc2VsZikuX19pbml0X18ob3B0aW9ucywgJ01ldGhvZE9wdGlvbnMnKQorICAgIHNlbGYubmFtZSA9IG5hbWUKKyAgICBzZWxmLmZ1bGxfbmFtZSA9IGZ1bGxfbmFtZQorICAgIHNlbGYuaW5kZXggPSBpbmRleAorICAgIHNlbGYuY29udGFpbmluZ19zZXJ2aWNlID0gY29udGFpbmluZ19zZXJ2aWNlCisgICAgc2VsZi5pbnB1dF90eXBlID0gaW5wdXRfdHlwZQorICAgIHNlbGYub3V0cHV0X3R5cGUgPSBvdXRwdXRfdHlwZQorCisKK2NsYXNzIEZpbGVEZXNjcmlwdG9yKERlc2NyaXB0b3JCYXNlKToKKyAgIiIiRGVzY3JpcHRvciBmb3IgYSBmaWxlLiBNaW1pY3MgdGhlIGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8uCisKKyAgTm90ZSB0aGF0IGVudW1fdHlwZXNfYnlfbmFtZSwgZXh0ZW5zaW9uc19ieV9uYW1lLCBhbmQgZGVwZW5kZW5jaWVzCisgIGZpZWxkcyBhcmUgb25seSBzZXQgYnkgdGhlIG1lc3NhZ2VfZmFjdG9yeSBtb2R1bGUsIGFuZCBub3QgYnkgdGhlCisgIGdlbmVyYXRlZCBwcm90byBjb2RlLgorCisgIG5hbWU6IG5hbWUgb2YgZmlsZSwgcmVsYXRpdmUgdG8gcm9vdCBvZiBzb3VyY2UgdHJlZS4KKyAgcGFja2FnZTogbmFtZSBvZiB0aGUgcGFja2FnZQorICBzeW50YXg6IHN0cmluZyBpbmRpY2F0aW5nIHN5bnRheCBvZiB0aGUgZmlsZSAoY2FuIGJlICJwcm90bzIiIG9yICJwcm90bzMiKQorICBzZXJpYWxpemVkX3BiOiAoc3RyKSBCeXRlIHN0cmluZyBvZiBzZXJpYWxpemVkCisgICAgZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by4KKyAgZGVwZW5kZW5jaWVzOiBMaXN0IG9mIG90aGVyIEZpbGVEZXNjcmlwdG9ycyB0aGlzIEZpbGVEZXNjcmlwdG9yIGRlcGVuZHMgb24uCisgIG1lc3NhZ2VfdHlwZXNfYnlfbmFtZTogRGljdCBvZiBtZXNzYWdlIG5hbWVzIG9mIHRoZWlyIGRlc2NyaXB0b3JzLgorICBlbnVtX3R5cGVzX2J5X25hbWU6IERpY3Qgb2YgZW51bSBuYW1lcyBhbmQgdGhlaXIgZGVzY3JpcHRvcnMuCisgIGV4dGVuc2lvbnNfYnlfbmFtZTogRGljdCBvZiBleHRlbnNpb24gbmFtZXMgYW5kIHRoZWlyIGRlc2NyaXB0b3JzLgorICAiIiIKKworICBpZiBfVVNFX0NfREVTQ1JJUFRPUlM6CisgICAgX0NfREVTQ1JJUFRPUl9DTEFTUyA9IF9tZXNzYWdlLkZpbGVEZXNjcmlwdG9yCisKKyAgICBkZWYgX19uZXdfXyhjbHMsIG5hbWUsIHBhY2thZ2UsIG9wdGlvbnM9Tm9uZSwgc2VyaWFsaXplZF9wYj1Ob25lLAorICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llcz1Ob25lLCBzeW50YXg9Tm9uZSk6CisgICAgICAjIEZpbGVEZXNjcmlwdG9yKCkgaXMgY2FsbGVkIGZyb20gdmFyaW91cyBwbGFjZXMsIG5vdCBvbmx5IGZyb20gZ2VuZXJhdGVkCisgICAgICAjIGZpbGVzLCB0byByZWdpc3RlciBkeW5hbWljIHByb3RvIGZpbGVzIGFuZCBtZXNzYWdlcy4KKyAgICAgICMgVE9ETyhhbWF1cnlmYSk6IEV4cG9zZSBCdWlsZEZpbGUoKSBhcyBhIHB1YmxpYyBmdW5jdGlvbiBhbmQgbWFrZSB0aGlzCisgICAgICAjIGNvbnN0cnVjdG9yIGFuIGltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgIGlmIHNlcmlhbGl6ZWRfcGI6CisgICAgICAgICMgcHlsaW50OiBkaXNhYmxlPXByb3RlY3RlZC1hY2Nlc3MyCisgICAgICAgIHJldHVybiBfbWVzc2FnZS5NZXNzYWdlLl9CdWlsZEZpbGUoc2VyaWFsaXplZF9wYikKKyAgICAgICAgIyBweWxpbnQ6IGVuYWJsZT1wcm90ZWN0ZWQtYWNjZXNzCisgICAgICBlbHNlOgorICAgICAgICByZXR1cm4gc3VwZXIoRmlsZURlc2NyaXB0b3IsIGNscykuX19uZXdfXyhjbHMpCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIHBhY2thZ2UsIG9wdGlvbnM9Tm9uZSwgc2VyaWFsaXplZF9wYj1Ob25lLAorICAgICAgICAgICAgICAgZGVwZW5kZW5jaWVzPU5vbmUsIHN5bnRheD1Ob25lKToKKyAgICAiIiJDb25zdHJ1Y3Rvci4iIiIKKyAgICBzdXBlcihGaWxlRGVzY3JpcHRvciwgc2VsZikuX19pbml0X18ob3B0aW9ucywgJ0ZpbGVPcHRpb25zJykKKworICAgIHNlbGYubWVzc2FnZV90eXBlc19ieV9uYW1lID0ge30KKyAgICBzZWxmLm5hbWUgPSBuYW1lCisgICAgc2VsZi5wYWNrYWdlID0gcGFja2FnZQorICAgIHNlbGYuc3ludGF4ID0gc3ludGF4IG9yICJwcm90bzIiCisgICAgc2VsZi5zZXJpYWxpemVkX3BiID0gc2VyaWFsaXplZF9wYgorCisgICAgc2VsZi5lbnVtX3R5cGVzX2J5X25hbWUgPSB7fQorICAgIHNlbGYuZXh0ZW5zaW9uc19ieV9uYW1lID0ge30KKyAgICBzZWxmLmRlcGVuZGVuY2llcyA9IChkZXBlbmRlbmNpZXMgb3IgW10pCisKKyAgICBpZiAoYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSA9PSAnY3BwJyBhbmQKKyAgICAgICAgc2VsZi5zZXJpYWxpemVkX3BiIGlzIG5vdCBOb25lKToKKyAgICAgICMgcHlsaW50OiBkaXNhYmxlPXByb3RlY3RlZC1hY2Nlc3MKKyAgICAgIF9tZXNzYWdlLk1lc3NhZ2UuX0J1aWxkRmlsZShzZWxmLnNlcmlhbGl6ZWRfcGIpCisgICAgICAjIHB5bGludDogZW5hYmxlPXByb3RlY3RlZC1hY2Nlc3MKKworICBkZWYgQ29weVRvUHJvdG8oc2VsZiwgcHJvdG8pOgorICAgICIiIkNvcGllcyB0aGlzIHRvIGEgZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by4KKworICAgIEFyZ3M6CisgICAgICBwcm90bzogQW4gZW1wdHkgZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by4KKyAgICAiIiIKKyAgICBwcm90by5QYXJzZUZyb21TdHJpbmcoc2VsZi5zZXJpYWxpemVkX3BiKQorCisKK2RlZiBfUGFyc2VPcHRpb25zKG1lc3NhZ2UsIHN0cmluZyk6CisgICIiIlBhcnNlcyBzZXJpYWxpemVkIG9wdGlvbnMuCisKKyAgVGhpcyBoZWxwZXIgZnVuY3Rpb24gaXMgdXNlZCB0byBwYXJzZSBzZXJpYWxpemVkIG9wdGlvbnMgaW4gZ2VuZXJhdGVkCisgIHByb3RvMiBmaWxlcy4gSXQgbXVzdCBub3QgYmUgdXNlZCBvdXRzaWRlIHByb3RvMi4KKyAgIiIiCisgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHN0cmluZykKKyAgcmV0dXJuIG1lc3NhZ2UKKworCitkZWYgTWFrZURlc2NyaXB0b3IoZGVzY19wcm90bywgcGFja2FnZT0nJywgYnVpbGRfZmlsZV9pZl9jcHA9VHJ1ZSwKKyAgICAgICAgICAgICAgICAgICBzeW50YXg9Tm9uZSk6CisgICIiIk1ha2UgYSBwcm90b2J1ZiBEZXNjcmlwdG9yIGdpdmVuIGEgRGVzY3JpcHRvclByb3RvIHByb3RvYnVmLgorCisgIEhhbmRsZXMgbmVzdGVkIGRlc2NyaXB0b3JzLiBOb3RlIHRoYXQgdGhpcyBpcyBsaW1pdGVkIHRvIHRoZSBzY29wZSBvZiBkZWZpbmluZworICBhIG1lc3NhZ2UgaW5zaWRlIG9mIGFub3RoZXIgbWVzc2FnZS4gQ29tcG9zaXRlIGZpZWxkcyBjYW4gY3VycmVudGx5IG9ubHkgYmUKKyAgcmVzb2x2ZWQgaWYgdGhlIG1lc3NhZ2UgaXMgZGVmaW5lZCBpbiB0aGUgc2FtZSBzY29wZSBhcyB0aGUgZmllbGQuCisKKyAgQXJnczoKKyAgICBkZXNjX3Byb3RvOiBUaGUgZGVzY3JpcHRvcl9wYjIuRGVzY3JpcHRvclByb3RvIHByb3RvYnVmIG1lc3NhZ2UuCisgICAgcGFja2FnZTogT3B0aW9uYWwgcGFja2FnZSBuYW1lIGZvciB0aGUgbmV3IG1lc3NhZ2UgRGVzY3JpcHRvciAoc3RyaW5nKS4KKyAgICBidWlsZF9maWxlX2lmX2NwcDogVXBkYXRlIHRoZSBDKysgZGVzY3JpcHRvciBwb29sIGlmIGFwaSBtYXRjaGVzLgorICAgICAgICAgICAgICAgICAgICAgICBTZXQgdG8gRmFsc2Ugb24gcmVjdXJzaW9uLCBzbyBubyBkdXBsaWNhdGVzIGFyZSBjcmVhdGVkLgorICAgIHN5bnRheDogVGhlIHN5bnRheC9zZW1hbnRpY3MgdGhhdCBzaG91bGQgYmUgdXNlZC4gIFNldCB0byAicHJvdG8zIiB0byBnZXQKKyAgICAgICAgICAgIHByb3RvMyBmaWVsZCBwcmVzZW5jZSBzZW1hbnRpY3MuCisgIFJldHVybnM6CisgICAgQSBEZXNjcmlwdG9yIGZvciBwcm90b2J1ZiBtZXNzYWdlcy4KKyAgIiIiCisgIGlmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgPT0gJ2NwcCcgYW5kIGJ1aWxkX2ZpbGVfaWZfY3BwOgorICAgICMgVGhlIEMrKyBpbXBsZW1lbnRhdGlvbiByZXF1aXJlcyBhbGwgZGVzY3JpcHRvcnMgdG8gYmUgYmFja2VkIGJ5IHRoZSBzYW1lCisgICAgIyBkZWZpbml0aW9uIGluIHRoZSBDKysgZGVzY3JpcHRvciBwb29sLiBUbyBkbyB0aGlzLCB3ZSBidWlsZCBhCisgICAgIyBGaWxlRGVzY3JpcHRvclByb3RvIHdpdGggdGhlIHNhbWUgZGVmaW5pdGlvbiBhcyB0aGlzIGRlc2NyaXB0b3IgYW5kIGJ1aWxkCisgICAgIyBpdCBpbnRvIHRoZSBwb29sLgorICAgIGZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yX3BiMgorICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90byA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8oKQorICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by5tZXNzYWdlX3R5cGUuYWRkKCkuTWVyZ2VGcm9tKGRlc2NfcHJvdG8pCisKKyAgICAjIEdlbmVyYXRlIGEgcmFuZG9tIG5hbWUgZm9yIHRoaXMgcHJvdG8gZmlsZSB0byBwcmV2ZW50IGNvbmZsaWN0cyB3aXRoCisgICAgIyBhbnkgaW1wb3J0ZWQgb25lcy4gV2UgbmVlZCB0byBzcGVjaWZ5IGEgZmlsZSBuYW1lIHNvIEJ1aWxkRmlsZSBhY2NlcHRzCisgICAgIyBvdXIgRmlsZURlc2NyaXB0b3JQcm90bywgYnV0IGl0IGlzIG5vdCBpbXBvcnRhbnQgd2hhdCB0aGF0IGZpbGUgbmFtZQorICAgICMgaXMgYWN0dWFsbHkgc2V0IHRvLgorICAgIHByb3RvX25hbWUgPSBzdHIodXVpZC51dWlkNCgpKQorCisgICAgaWYgcGFja2FnZToKKyAgICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by5uYW1lID0gb3MucGF0aC5qb2luKHBhY2thZ2UucmVwbGFjZSgnLicsICcvJyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b19uYW1lICsgJy5wcm90bycpCisgICAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ucGFja2FnZSA9IHBhY2thZ2UKKyAgICBlbHNlOgorICAgICAgZmlsZV9kZXNjcmlwdG9yX3Byb3RvLm5hbWUgPSBwcm90b19uYW1lICsgJy5wcm90bycKKworICAgICMgcHlsaW50OiBkaXNhYmxlPXByb3RlY3RlZC1hY2Nlc3MKKyAgICByZXN1bHQgPSBfbWVzc2FnZS5NZXNzYWdlLl9CdWlsZEZpbGUoCisgICAgICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by5TZXJpYWxpemVUb1N0cmluZygpKQorICAgICMgcHlsaW50OiBlbmFibGU9cHJvdGVjdGVkLWFjY2VzcworCisgICAgaWYgX1VTRV9DX0RFU0NSSVBUT1JTOgorICAgICAgcmV0dXJuIHJlc3VsdC5tZXNzYWdlX3R5cGVzX2J5X25hbWVbZGVzY19wcm90by5uYW1lXQorCisgIGZ1bGxfbWVzc2FnZV9uYW1lID0gW2Rlc2NfcHJvdG8ubmFtZV0KKyAgaWYgcGFja2FnZTogZnVsbF9tZXNzYWdlX25hbWUuaW5zZXJ0KDAsIHBhY2thZ2UpCisKKyAgIyBDcmVhdGUgRGVzY3JpcHRvcnMgZm9yIGVudW0gdHlwZXMKKyAgZW51bV90eXBlcyA9IHt9CisgIGZvciBlbnVtX3Byb3RvIGluIGRlc2NfcHJvdG8uZW51bV90eXBlOgorICAgIGZ1bGxfbmFtZSA9ICcuJy5qb2luKGZ1bGxfbWVzc2FnZV9uYW1lICsgW2VudW1fcHJvdG8ubmFtZV0pCisgICAgZW51bV9kZXNjID0gRW51bURlc2NyaXB0b3IoCisgICAgICBlbnVtX3Byb3RvLm5hbWUsIGZ1bGxfbmFtZSwgTm9uZSwgWworICAgICAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3IoZW51bV92YWwubmFtZSwgaWksIGVudW1fdmFsLm51bWJlcikKKyAgICAgICAgICBmb3IgaWksIGVudW1fdmFsIGluIGVudW1lcmF0ZShlbnVtX3Byb3RvLnZhbHVlKV0pCisgICAgZW51bV90eXBlc1tmdWxsX25hbWVdID0gZW51bV9kZXNjCisKKyAgIyBDcmVhdGUgRGVzY3JpcHRvcnMgZm9yIG5lc3RlZCB0eXBlcworICBuZXN0ZWRfdHlwZXMgPSB7fQorICBmb3IgbmVzdGVkX3Byb3RvIGluIGRlc2NfcHJvdG8ubmVzdGVkX3R5cGU6CisgICAgZnVsbF9uYW1lID0gJy4nLmpvaW4oZnVsbF9tZXNzYWdlX25hbWUgKyBbbmVzdGVkX3Byb3RvLm5hbWVdKQorICAgICMgTmVzdGVkIHR5cGVzIGFyZSBqdXN0IHRob3NlIGRlZmluZWQgaW5zaWRlIG9mIHRoZSBtZXNzYWdlLCBub3QgYWxsIHR5cGVzCisgICAgIyB1c2VkIGJ5IGZpZWxkcyBpbiB0aGUgbWVzc2FnZSwgc28gbm8gbG9vcHMgYXJlIHBvc3NpYmxlIGhlcmUuCisgICAgbmVzdGVkX2Rlc2MgPSBNYWtlRGVzY3JpcHRvcihuZXN0ZWRfcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlPScuJy5qb2luKGZ1bGxfbWVzc2FnZV9uYW1lKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkX2ZpbGVfaWZfY3BwPUZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4PXN5bnRheCkKKyAgICBuZXN0ZWRfdHlwZXNbZnVsbF9uYW1lXSA9IG5lc3RlZF9kZXNjCisKKyAgZmllbGRzID0gW10KKyAgZm9yIGZpZWxkX3Byb3RvIGluIGRlc2NfcHJvdG8uZmllbGQ6CisgICAgZnVsbF9uYW1lID0gJy4nLmpvaW4oZnVsbF9tZXNzYWdlX25hbWUgKyBbZmllbGRfcHJvdG8ubmFtZV0pCisgICAgZW51bV9kZXNjID0gTm9uZQorICAgIG5lc3RlZF9kZXNjID0gTm9uZQorICAgIGlmIGZpZWxkX3Byb3RvLkhhc0ZpZWxkKCd0eXBlX25hbWUnKToKKyAgICAgIHR5cGVfbmFtZSA9IGZpZWxkX3Byb3RvLnR5cGVfbmFtZQorICAgICAgZnVsbF90eXBlX25hbWUgPSAnLicuam9pbihmdWxsX21lc3NhZ2VfbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlX25hbWVbdHlwZV9uYW1lLnJmaW5kKCcuJykrMTpdXSkKKyAgICAgIGlmIGZ1bGxfdHlwZV9uYW1lIGluIG5lc3RlZF90eXBlczoKKyAgICAgICAgbmVzdGVkX2Rlc2MgPSBuZXN0ZWRfdHlwZXNbZnVsbF90eXBlX25hbWVdCisgICAgICBlbGlmIGZ1bGxfdHlwZV9uYW1lIGluIGVudW1fdHlwZXM6CisgICAgICAgIGVudW1fZGVzYyA9IGVudW1fdHlwZXNbZnVsbF90eXBlX25hbWVdCisgICAgICAjIEVsc2UgdHlwZV9uYW1lIHJlZmVyZW5jZXMgYSBub24tbG9jYWwgdHlwZSwgd2hpY2ggaXNuJ3QgaW1wbGVtZW50ZWQKKyAgICBmaWVsZCA9IEZpZWxkRGVzY3JpcHRvcigKKyAgICAgICAgZmllbGRfcHJvdG8ubmFtZSwgZnVsbF9uYW1lLCBmaWVsZF9wcm90by5udW1iZXIgLSAxLAorICAgICAgICBmaWVsZF9wcm90by5udW1iZXIsIGZpZWxkX3Byb3RvLnR5cGUsCisgICAgICAgIEZpZWxkRGVzY3JpcHRvci5Qcm90b1R5cGVUb0NwcFByb3RvVHlwZShmaWVsZF9wcm90by50eXBlKSwKKyAgICAgICAgZmllbGRfcHJvdG8ubGFiZWwsIE5vbmUsIG5lc3RlZF9kZXNjLCBlbnVtX2Rlc2MsIE5vbmUsIEZhbHNlLCBOb25lLAorICAgICAgICBvcHRpb25zPWZpZWxkX3Byb3RvLm9wdGlvbnMsIGhhc19kZWZhdWx0X3ZhbHVlPUZhbHNlKQorICAgIGZpZWxkcy5hcHBlbmQoZmllbGQpCisKKyAgZGVzY19uYW1lID0gJy4nLmpvaW4oZnVsbF9tZXNzYWdlX25hbWUpCisgIHJldHVybiBEZXNjcmlwdG9yKGRlc2NfcHJvdG8ubmFtZSwgZGVzY19uYW1lLCBOb25lLCBOb25lLCBmaWVsZHMsCisgICAgICAgICAgICAgICAgICAgIG5lc3RlZF90eXBlcy52YWx1ZXMoKSwgZW51bV90eXBlcy52YWx1ZXMoKSwgW10sCisgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM9ZGVzY19wcm90by5vcHRpb25zKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxMDAyMWUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UucHkKQEAgLTAsMCArMSwxMzcgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiUHJvdmlkZXMgYSBjb250YWluZXIgZm9yIERlc2NyaXB0b3JQcm90b3MuIiIiCisKK19fYXV0aG9yX18gPSAnbWF0dGhld3RvaWFAZ29vZ2xlLmNvbSAoTWF0dCBUb2lhKScKKworCitjbGFzcyBFcnJvcihFeGNlcHRpb24pOgorICBwYXNzCisKKworY2xhc3MgRGVzY3JpcHRvckRhdGFiYXNlQ29uZmxpY3RpbmdEZWZpbml0aW9uRXJyb3IoRXJyb3IpOgorICAiIiJSYWlzZWQgd2hlbiBhIHByb3RvIGlzIGFkZGVkIHdpdGggdGhlIHNhbWUgbmFtZSAmIGRpZmZlcmVudCBkZXNjcmlwdG9yLiIiIgorCisKK2NsYXNzIERlc2NyaXB0b3JEYXRhYmFzZShvYmplY3QpOgorICAiIiJBIGNvbnRhaW5lciBhY2NlcHRpbmcgRmlsZURlc2NyaXB0b3JQcm90b3MgYW5kIG1hcHMgRGVzY3JpcHRvclByb3Rvcy4iIiIKKworICBkZWYgX19pbml0X18oc2VsZik6CisgICAgc2VsZi5fZmlsZV9kZXNjX3Byb3Rvc19ieV9maWxlID0ge30KKyAgICBzZWxmLl9maWxlX2Rlc2NfcHJvdG9zX2J5X3N5bWJvbCA9IHt9CisKKyAgZGVmIEFkZChzZWxmLCBmaWxlX2Rlc2NfcHJvdG8pOgorICAgICIiIkFkZHMgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gYW5kIGl0cyB0eXBlcyB0byB0aGlzIGRhdGFiYXNlLgorCisgICAgQXJnczoKKyAgICAgIGZpbGVfZGVzY19wcm90bzogVGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gYWRkLgorICAgIFJhaXNlczoKKyAgICAgIERlc2NyaXB0b3JEYXRhYmFzZUV4Y2VwdGlvbjogaWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFkZCBhIHByb3RvCisgICAgICAgIHdpdGggdGhlIHNhbWUgbmFtZSBidXQgZGlmZmVyZW50IGRlZmluaXRpb24gdGhhbiBhbiBleGlzaXRpbmcKKyAgICAgICAgcHJvdG8gaW4gdGhlIGRhdGFiYXNlLgorICAgICIiIgorICAgIHByb3RvX25hbWUgPSBmaWxlX2Rlc2NfcHJvdG8ubmFtZQorICAgIGlmIHByb3RvX25hbWUgbm90IGluIHNlbGYuX2ZpbGVfZGVzY19wcm90b3NfYnlfZmlsZToKKyAgICAgIHNlbGYuX2ZpbGVfZGVzY19wcm90b3NfYnlfZmlsZVtwcm90b19uYW1lXSA9IGZpbGVfZGVzY19wcm90bworICAgIGVsaWYgc2VsZi5fZmlsZV9kZXNjX3Byb3Rvc19ieV9maWxlW3Byb3RvX25hbWVdICE9IGZpbGVfZGVzY19wcm90bzoKKyAgICAgIHJhaXNlIERlc2NyaXB0b3JEYXRhYmFzZUNvbmZsaWN0aW5nRGVmaW5pdGlvbkVycm9yKAorICAgICAgICAgICclcyBhbHJlYWR5IGFkZGVkLCBidXQgd2l0aCBkaWZmZXJlbnQgZGVzY3JpcHRvci4nICUgcHJvdG9fbmFtZSkKKworICAgIHBhY2thZ2UgPSBmaWxlX2Rlc2NfcHJvdG8ucGFja2FnZQorICAgIGZvciBtZXNzYWdlIGluIGZpbGVfZGVzY19wcm90by5tZXNzYWdlX3R5cGU6CisgICAgICBzZWxmLl9maWxlX2Rlc2NfcHJvdG9zX2J5X3N5bWJvbC51cGRhdGUoCisgICAgICAgICAgKG5hbWUsIGZpbGVfZGVzY19wcm90bykgZm9yIG5hbWUgaW4gX0V4dHJhY3RTeW1ib2xzKG1lc3NhZ2UsIHBhY2thZ2UpKQorICAgIGZvciBlbnVtIGluIGZpbGVfZGVzY19wcm90by5lbnVtX3R5cGU6CisgICAgICBzZWxmLl9maWxlX2Rlc2NfcHJvdG9zX2J5X3N5bWJvbFsKKyAgICAgICAgICAnLicuam9pbigocGFja2FnZSwgZW51bS5uYW1lKSldID0gZmlsZV9kZXNjX3Byb3RvCisKKyAgZGVmIEZpbmRGaWxlQnlOYW1lKHNlbGYsIG5hbWUpOgorICAgICIiIkZpbmRzIHRoZSBmaWxlIGRlc2NyaXB0b3IgcHJvdG8gYnkgZmlsZSBuYW1lLgorCisgICAgVHlwaWNhbGx5IHRoZSBmaWxlIG5hbWUgaXMgYSByZWxhdGl2ZSBwYXRoIGVuZGluZyB0byBhIC5wcm90byBmaWxlLiBUaGUKKyAgICBwcm90byB3aXRoIHRoZSBnaXZlbiBuYW1lIHdpbGwgaGF2ZSB0byBoYXZlIGJlZW4gYWRkZWQgdG8gdGhpcyBkYXRhYmFzZQorICAgIHVzaW5nIHRoZSBBZGQgbWV0aG9kIG9yIGVsc2UgYW4gZXJyb3Igd2lsbCBiZSByYWlzZWQuCisKKyAgICBBcmdzOgorICAgICAgbmFtZTogVGhlIGZpbGUgbmFtZSB0byBmaW5kLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBmaWxlIGRlc2NyaXB0b3IgcHJvdG8gbWF0Y2hpbmcgdGhlIG5hbWUuCisKKyAgICBSYWlzZXM6CisgICAgICBLZXlFcnJvciBpZiBubyBmaWxlIGJ5IHRoZSBnaXZlbiBuYW1lIHdhcyBhZGRlZC4KKyAgICAiIiIKKworICAgIHJldHVybiBzZWxmLl9maWxlX2Rlc2NfcHJvdG9zX2J5X2ZpbGVbbmFtZV0KKworICBkZWYgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKHNlbGYsIHN5bWJvbCk6CisgICAgIiIiRmluZHMgdGhlIGZpbGUgZGVzY3JpcHRvciBwcm90byBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sLgorCisgICAgVGhlIHN5bWJvbCBzaG91bGQgYmUgYSBmdWxseSBxdWFsaWZpZWQgbmFtZSBpbmNsdWRpbmcgdGhlIGZpbGUgZGVzY3JpcHRvcidzCisgICAgcGFja2FnZSBhbmQgYW55IGNvbnRhaW5pbmcgbWVzc2FnZXMuIFNvbWUgZXhhbXBsZXM6CisKKyAgICAnc29tZS5wYWNrYWdlLm5hbWUuTWVzc2FnZScKKyAgICAnc29tZS5wYWNrYWdlLm5hbWUuTWVzc2FnZS5OZXN0ZWRFbnVtJworCisgICAgVGhlIGZpbGUgZGVzY3JpcHRvciBwcm90byBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIG11c3QgYmUgYWRkZWQgdG8KKyAgICB0aGlzIGRhdGFiYXNlIHVzaW5nIHRoZSBBZGQgbWV0aG9kIG9yIGVsc2UgYW4gZXJyb3Igd2lsbCBiZSByYWlzZWQuCisKKyAgICBBcmdzOgorICAgICAgc3ltYm9sOiBUaGUgZnVsbHkgcXVhbGlmaWVkIHN5bWJvbCBuYW1lLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBmaWxlIGRlc2NyaXB0b3IgcHJvdG8gY29udGFpbmluZyB0aGUgc3ltYm9sLgorCisgICAgUmFpc2VzOgorICAgICAgS2V5RXJyb3IgaWYgbm8gZmlsZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIHN5bWJvbC4KKyAgICAiIiIKKworICAgIHJldHVybiBzZWxmLl9maWxlX2Rlc2NfcHJvdG9zX2J5X3N5bWJvbFtzeW1ib2xdCisKKworZGVmIF9FeHRyYWN0U3ltYm9scyhkZXNjX3Byb3RvLCBwYWNrYWdlKToKKyAgIiIiUHVsbHMgb3V0IGFsbCB0aGUgc3ltYm9scyBmcm9tIGEgZGVzY3JpcHRvciBwcm90by4KKworICBBcmdzOgorICAgIGRlc2NfcHJvdG86IFRoZSBwcm90byB0byBleHRyYWN0IHN5bWJvbHMgZnJvbS4KKyAgICBwYWNrYWdlOiBUaGUgcGFja2FnZSBjb250YWluaW5nIHRoZSBkZXNjcmlwdG9yIHR5cGUuCisKKyAgWWllbGRzOgorICAgIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBmb3VuZCBpbiB0aGUgZGVzY3JpcHRvci4KKyAgIiIiCisKKyAgbWVzc2FnZV9uYW1lID0gJy4nLmpvaW4oKHBhY2thZ2UsIGRlc2NfcHJvdG8ubmFtZSkpCisgIHlpZWxkIG1lc3NhZ2VfbmFtZQorICBmb3IgbmVzdGVkX3R5cGUgaW4gZGVzY19wcm90by5uZXN0ZWRfdHlwZToKKyAgICBmb3Igc3ltYm9sIGluIF9FeHRyYWN0U3ltYm9scyhuZXN0ZWRfdHlwZSwgbWVzc2FnZV9uYW1lKToKKyAgICAgIHlpZWxkIHN5bWJvbAorICBmb3IgZW51bV90eXBlIGluIGRlc2NfcHJvdG8uZW51bV90eXBlOgorICAgIHlpZWxkICcuJy5qb2luKChtZXNzYWdlX25hbWUsIGVudW1fdHlwZS5uYW1lKSkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9wb29sLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX3Bvb2wucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2U3NzAxZgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9wb29sLnB5CkBAIC0wLDAgKzEsNjcxIEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyIiIlByb3ZpZGVzIERlc2NyaXB0b3JQb29sIHRvIHVzZSBhcyBhIGNvbnRhaW5lciBmb3IgcHJvdG8yIGRlc2NyaXB0b3JzLgorCitUaGUgRGVzY3JpcHRvclBvb2wgaXMgdXNlZCBpbiBjb25qZWN0aW9uIHdpdGggYSBEZXNjcmlwdG9yRGF0YWJhc2UgdG8gbWFpbnRhaW4KK2EgY29sbGVjdGlvbiBvZiBwcm90b2NvbCBidWZmZXIgZGVzY3JpcHRvcnMgZm9yIHVzZSB3aGVuIGR5bmFtaWNhbGx5IGNyZWF0aW5nCittZXNzYWdlIHR5cGVzIGF0IHJ1bnRpbWUuCisKK0ZvciBtb3N0IGFwcGxpY2F0aW9ucyBwcm90b2NvbCBidWZmZXJzIHNob3VsZCBiZSB1c2VkIHZpYSBtb2R1bGVzIGdlbmVyYXRlZCBieQordGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlciB0b29sLiBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiB0aGUgdHlwZSBvZgorcHJvdG9jb2wgYnVmZmVycyB1c2VkIGluIGFuIGFwcGxpY2F0aW9uIG9yIGxpYnJhcnkgY2Fubm90IGJlIHByZWRldGVybWluZWQuCisKK0JlbG93IGlzIGEgc3RyYWlnaHRmb3J3YXJkIGV4YW1wbGUgb24gaG93IHRvIHVzZSB0aGlzIGNsYXNzOgorCisgIHBvb2wgPSBEZXNjcmlwdG9yUG9vbCgpCisgIGZpbGVfZGVzY3JpcHRvcl9wcm90b3MgPSBbIC4uLiBdCisgIGZvciBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8gaW4gZmlsZV9kZXNjcmlwdG9yX3Byb3RvczoKKyAgICBwb29sLkFkZChmaWxlX2Rlc2NyaXB0b3JfcHJvdG8pCisgIG15X21lc3NhZ2VfZGVzY3JpcHRvciA9IHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCdzb21lLnBhY2thZ2UuTWVzc2FnZVR5cGUnKQorCitUaGUgbWVzc2FnZSBkZXNjcmlwdG9yIGNhbiBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIG1lc3NhZ2VfZmFjdG9yeQorbW9kdWxlIGluIG9yZGVyIHRvIGNyZWF0ZSBhIHByb3RvY29sIGJ1ZmZlciBjbGFzcyB0aGF0IGNhbiBiZSBlbmNvZGVkIGFuZAorZGVjb2RlZC4KKworSWYgeW91IHdhbnQgdG8gZ2V0IGEgUHl0aG9uIGNsYXNzIGZvciB0aGUgc3BlY2lmaWVkIHByb3RvLCB1c2UgdGhlCitoZWxwZXIgZnVuY3Rpb25zIGluc2lkZSBnb29nbGUucHJvdG9idWYubWVzc2FnZV9mYWN0b3J5CitkaXJlY3RseSBpbnN0ZWFkIG9mIHRoaXMgY2xhc3MuCisiIiIKKworX19hdXRob3JfXyA9ICdtYXR0aGV3dG9pYUBnb29nbGUuY29tIChNYXR0IFRvaWEpJworCitpbXBvcnQgc3lzCisKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9kYXRhYmFzZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHRleHRfZW5jb2RpbmcKKworCitfVVNFX0NfREVTQ1JJUFRPUlMgPSBkZXNjcmlwdG9yLl9VU0VfQ19ERVNDUklQVE9SUworCisKK2RlZiBfTm9ybWFsaXplRnVsbHlRdWFsaWZpZWROYW1lKG5hbWUpOgorICAiIiJSZW1vdmUgbGVhZGluZyBwZXJpb2QgZnJvbSBmdWxseS1xdWFsaWZpZWQgdHlwZSBuYW1lLgorCisgIER1ZSB0byBiLzEzODYwMzUxIGluIGRlc2NyaXB0b3JfZGF0YWJhc2UucHksIHR5cGVzIGluIHRoZSByb290IG5hbWVzcGFjZSBhcmUKKyAgZ2VuZXJhdGVkIHdpdGggYSBsZWFkaW5nIHBlcmlvZC4gVGhpcyBmdW5jdGlvbiByZW1vdmVzIHRoYXQgcHJlZml4LgorCisgIEFyZ3M6CisgICAgbmFtZTogQSBzdHIsIHRoZSBmdWxseS1xdWFsaWZpZWQgc3ltYm9sIG5hbWUuCisKKyAgUmV0dXJuczoKKyAgICBBIHN0ciwgdGhlIG5vcm1hbGl6ZWQgZnVsbHktcXVhbGlmaWVkIHN5bWJvbCBuYW1lLgorICAiIiIKKyAgcmV0dXJuIG5hbWUubHN0cmlwKCcuJykKKworCitjbGFzcyBEZXNjcmlwdG9yUG9vbChvYmplY3QpOgorICAiIiJBIGNvbGxlY3Rpb24gb2YgcHJvdG9idWZzIGR5bmFtaWNhbGx5IGNvbnN0cnVjdGVkIGJ5IGRlc2NyaXB0b3IgcHJvdG9zLiIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkZXNjcmlwdG9yX2RiPU5vbmUpOgorICAgICIiIkluaXRpYWxpemVzIGEgUG9vbCBvZiBwcm90byBidWZmcy4KKworICAgIFRoZSBkZXNjcmlwdG9yX2RiIGFyZ3VtZW50IHRvIHRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCB0byBhbGxvdworICAgIHNwZWNpYWxpemVkIGZpbGUgZGVzY3JpcHRvciBwcm90byBsb29rdXAgY29kZSB0byBiZSB0cmlnZ2VyZWQgb24gZGVtYW5kLiBBbgorICAgIGV4YW1wbGUgd291bGQgYmUgYW4gaW1wbGVtZW50YXRpb24gd2hpY2ggd2lsbCByZWFkIGFuZCBjb21waWxlIGEgZmlsZQorICAgIHNwZWNpZmllZCBpbiBhIGNhbGwgdG8gRmluZEZpbGVCeU5hbWUoKSBhbmQgbm90IHJlcXVpcmUgdGhlIGNhbGwgdG8gQWRkKCkKKyAgICBhdCBhbGwuIFJlc3VsdHMgZnJvbSB0aGlzIGRhdGFiYXNlIHdpbGwgYmUgY2FjaGVkIGludGVybmFsbHkgaGVyZSBhcyB3ZWxsLgorCisgICAgQXJnczoKKyAgICAgIGRlc2NyaXB0b3JfZGI6IEEgc2Vjb25kYXJ5IHNvdXJjZSBvZiBmaWxlIGRlc2NyaXB0b3JzLgorICAgICIiIgorCisgICAgc2VsZi5faW50ZXJuYWxfZGIgPSBkZXNjcmlwdG9yX2RhdGFiYXNlLkRlc2NyaXB0b3JEYXRhYmFzZSgpCisgICAgc2VsZi5fZGVzY3JpcHRvcl9kYiA9IGRlc2NyaXB0b3JfZGIKKyAgICBzZWxmLl9kZXNjcmlwdG9ycyA9IHt9CisgICAgc2VsZi5fZW51bV9kZXNjcmlwdG9ycyA9IHt9CisgICAgc2VsZi5fZmlsZV9kZXNjcmlwdG9ycyA9IHt9CisKKyAgZGVmIEFkZChzZWxmLCBmaWxlX2Rlc2NfcHJvdG8pOgorICAgICIiIkFkZHMgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gYW5kIGl0cyB0eXBlcyB0byB0aGlzIHBvb2wuCisKKyAgICBBcmdzOgorICAgICAgZmlsZV9kZXNjX3Byb3RvOiBUaGUgRmlsZURlc2NyaXB0b3JQcm90byB0byBhZGQuCisgICAgIiIiCisKKyAgICBzZWxmLl9pbnRlcm5hbF9kYi5BZGQoZmlsZV9kZXNjX3Byb3RvKQorCisgIGRlZiBBZGREZXNjcmlwdG9yKHNlbGYsIGRlc2MpOgorICAgICIiIkFkZHMgYSBEZXNjcmlwdG9yIHRvIHRoZSBwb29sLCBub24tcmVjdXJzaXZlbHkuCisKKyAgICBJZiB0aGUgRGVzY3JpcHRvciBjb250YWlucyBuZXN0ZWQgbWVzc2FnZXMgb3IgZW51bXMsIHRoZSBjYWxsZXIgbXVzdAorICAgIGV4cGxpY2l0bHkgcmVnaXN0ZXIgdGhlbS4gVGhpcyBtZXRob2QgYWxzbyByZWdpc3RlcnMgdGhlIEZpbGVEZXNjcmlwdG9yCisgICAgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZXNzYWdlLgorCisgICAgQXJnczoKKyAgICAgIGRlc2M6IEEgRGVzY3JpcHRvci4KKyAgICAiIiIKKyAgICBpZiBub3QgaXNpbnN0YW5jZShkZXNjLCBkZXNjcmlwdG9yLkRlc2NyaXB0b3IpOgorICAgICAgcmFpc2UgVHlwZUVycm9yKCdFeHBlY3RlZCBpbnN0YW5jZSBvZiBkZXNjcmlwdG9yLkRlc2NyaXB0b3IuJykKKworICAgIHNlbGYuX2Rlc2NyaXB0b3JzW2Rlc2MuZnVsbF9uYW1lXSA9IGRlc2MKKyAgICBzZWxmLkFkZEZpbGVEZXNjcmlwdG9yKGRlc2MuZmlsZSkKKworICBkZWYgQWRkRW51bURlc2NyaXB0b3Ioc2VsZiwgZW51bV9kZXNjKToKKyAgICAiIiJBZGRzIGFuIEVudW1EZXNjcmlwdG9yIHRvIHRoZSBwb29sLgorCisgICAgVGhpcyBtZXRob2QgYWxzbyByZWdpc3RlcnMgdGhlIEZpbGVEZXNjcmlwdG9yIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWVzc2FnZS4KKworICAgIEFyZ3M6CisgICAgICBlbnVtX2Rlc2M6IEFuIEVudW1EZXNjcmlwdG9yLgorICAgICIiIgorCisgICAgaWYgbm90IGlzaW5zdGFuY2UoZW51bV9kZXNjLCBkZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yKToKKyAgICAgIHJhaXNlIFR5cGVFcnJvcignRXhwZWN0ZWQgaW5zdGFuY2Ugb2YgZGVzY3JpcHRvci5FbnVtRGVzY3JpcHRvci4nKQorCisgICAgc2VsZi5fZW51bV9kZXNjcmlwdG9yc1tlbnVtX2Rlc2MuZnVsbF9uYW1lXSA9IGVudW1fZGVzYworICAgIHNlbGYuQWRkRmlsZURlc2NyaXB0b3IoZW51bV9kZXNjLmZpbGUpCisKKyAgZGVmIEFkZEZpbGVEZXNjcmlwdG9yKHNlbGYsIGZpbGVfZGVzYyk6CisgICAgIiIiQWRkcyBhIEZpbGVEZXNjcmlwdG9yIHRvIHRoZSBwb29sLCBub24tcmVjdXJzaXZlbHkuCisKKyAgICBJZiB0aGUgRmlsZURlc2NyaXB0b3IgY29udGFpbnMgbWVzc2FnZXMgb3IgZW51bXMsIHRoZSBjYWxsZXIgbXVzdCBleHBsaWNpdGx5CisgICAgcmVnaXN0ZXIgdGhlbS4KKworICAgIEFyZ3M6CisgICAgICBmaWxlX2Rlc2M6IEEgRmlsZURlc2NyaXB0b3IuCisgICAgIiIiCisKKyAgICBpZiBub3QgaXNpbnN0YW5jZShmaWxlX2Rlc2MsIGRlc2NyaXB0b3IuRmlsZURlc2NyaXB0b3IpOgorICAgICAgcmFpc2UgVHlwZUVycm9yKCdFeHBlY3RlZCBpbnN0YW5jZSBvZiBkZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yLicpCisgICAgc2VsZi5fZmlsZV9kZXNjcmlwdG9yc1tmaWxlX2Rlc2MubmFtZV0gPSBmaWxlX2Rlc2MKKworICBkZWYgRmluZEZpbGVCeU5hbWUoc2VsZiwgZmlsZV9uYW1lKToKKyAgICAiIiJHZXRzIGEgRmlsZURlc2NyaXB0b3IgYnkgZmlsZSBuYW1lLgorCisgICAgQXJnczoKKyAgICAgIGZpbGVfbmFtZTogVGhlIHBhdGggdG8gdGhlIGZpbGUgdG8gZ2V0IGEgZGVzY3JpcHRvciBmb3IuCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBGaWxlRGVzY3JpcHRvciBmb3IgdGhlIG5hbWVkIGZpbGUuCisKKyAgICBSYWlzZXM6CisgICAgICBLZXlFcnJvcjogaWYgdGhlIGZpbGUgY2FuIG5vdCBiZSBmb3VuZCBpbiB0aGUgcG9vbC4KKyAgICAiIiIKKworICAgIHRyeToKKyAgICAgIHJldHVybiBzZWxmLl9maWxlX2Rlc2NyaXB0b3JzW2ZpbGVfbmFtZV0KKyAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICBwYXNzCisKKyAgICB0cnk6CisgICAgICBmaWxlX3Byb3RvID0gc2VsZi5faW50ZXJuYWxfZGIuRmluZEZpbGVCeU5hbWUoZmlsZV9uYW1lKQorICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgIF8sIGVycm9yLCBfID0gc3lzLmV4Y19pbmZvKCkgICNQWTI1IGNvbXBhdGlibGUgZm9yIEdBRS4KKyAgICAgIGlmIHNlbGYuX2Rlc2NyaXB0b3JfZGI6CisgICAgICAgIGZpbGVfcHJvdG8gPSBzZWxmLl9kZXNjcmlwdG9yX2RiLkZpbmRGaWxlQnlOYW1lKGZpbGVfbmFtZSkKKyAgICAgIGVsc2U6CisgICAgICAgIHJhaXNlIGVycm9yCisgICAgaWYgbm90IGZpbGVfcHJvdG86CisgICAgICByYWlzZSBLZXlFcnJvcignQ2Fubm90IGZpbmQgYSBmaWxlIG5hbWVkICVzJyAlIGZpbGVfbmFtZSkKKyAgICByZXR1cm4gc2VsZi5fQ29udmVydEZpbGVQcm90b1RvRmlsZURlc2NyaXB0b3IoZmlsZV9wcm90bykKKworICBkZWYgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKHNlbGYsIHN5bWJvbCk6CisgICAgIiIiR2V0cyB0aGUgRmlsZURlc2NyaXB0b3IgZm9yIHRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wuCisKKyAgICBBcmdzOgorICAgICAgc3ltYm9sOiBUaGUgbmFtZSBvZiB0aGUgc3ltYm9sIHRvIHNlYXJjaCBmb3IuCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBGaWxlRGVzY3JpcHRvciB0aGF0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgc3ltYm9sLgorCisgICAgUmFpc2VzOgorICAgICAgS2V5RXJyb3I6IGlmIHRoZSBmaWxlIGNhbiBub3QgYmUgZm91bmQgaW4gdGhlIHBvb2wuCisgICAgIiIiCisKKyAgICBzeW1ib2wgPSBfTm9ybWFsaXplRnVsbHlRdWFsaWZpZWROYW1lKHN5bWJvbCkKKyAgICB0cnk6CisgICAgICByZXR1cm4gc2VsZi5fZGVzY3JpcHRvcnNbc3ltYm9sXS5maWxlCisgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgcGFzcworCisgICAgdHJ5OgorICAgICAgcmV0dXJuIHNlbGYuX2VudW1fZGVzY3JpcHRvcnNbc3ltYm9sXS5maWxlCisgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgcGFzcworCisgICAgdHJ5OgorICAgICAgZmlsZV9wcm90byA9IHNlbGYuX2ludGVybmFsX2RiLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChzeW1ib2wpCisgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgXywgZXJyb3IsIF8gPSBzeXMuZXhjX2luZm8oKSAgI1BZMjUgY29tcGF0aWJsZSBmb3IgR0FFLgorICAgICAgaWYgc2VsZi5fZGVzY3JpcHRvcl9kYjoKKyAgICAgICAgZmlsZV9wcm90byA9IHNlbGYuX2Rlc2NyaXB0b3JfZGIuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKHN5bWJvbCkKKyAgICAgIGVsc2U6CisgICAgICAgIHJhaXNlIGVycm9yCisgICAgaWYgbm90IGZpbGVfcHJvdG86CisgICAgICByYWlzZSBLZXlFcnJvcignQ2Fubm90IGZpbmQgYSBmaWxlIGNvbnRhaW5pbmcgJXMnICUgc3ltYm9sKQorICAgIHJldHVybiBzZWxmLl9Db252ZXJ0RmlsZVByb3RvVG9GaWxlRGVzY3JpcHRvcihmaWxlX3Byb3RvKQorCisgIGRlZiBGaW5kTWVzc2FnZVR5cGVCeU5hbWUoc2VsZiwgZnVsbF9uYW1lKToKKyAgICAiIiJMb2FkcyB0aGUgbmFtZWQgZGVzY3JpcHRvciBmcm9tIHRoZSBwb29sLgorCisgICAgQXJnczoKKyAgICAgIGZ1bGxfbmFtZTogVGhlIGZ1bGwgbmFtZSBvZiB0aGUgZGVzY3JpcHRvciB0byBsb2FkLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBkZXNjcmlwdG9yIGZvciB0aGUgbmFtZWQgdHlwZS4KKyAgICAiIiIKKworICAgIGZ1bGxfbmFtZSA9IF9Ob3JtYWxpemVGdWxseVF1YWxpZmllZE5hbWUoZnVsbF9uYW1lKQorICAgIGlmIGZ1bGxfbmFtZSBub3QgaW4gc2VsZi5fZGVzY3JpcHRvcnM6CisgICAgICBzZWxmLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChmdWxsX25hbWUpCisgICAgcmV0dXJuIHNlbGYuX2Rlc2NyaXB0b3JzW2Z1bGxfbmFtZV0KKworICBkZWYgRmluZEVudW1UeXBlQnlOYW1lKHNlbGYsIGZ1bGxfbmFtZSk6CisgICAgIiIiTG9hZHMgdGhlIG5hbWVkIGVudW0gZGVzY3JpcHRvciBmcm9tIHRoZSBwb29sLgorCisgICAgQXJnczoKKyAgICAgIGZ1bGxfbmFtZTogVGhlIGZ1bGwgbmFtZSBvZiB0aGUgZW51bSBkZXNjcmlwdG9yIHRvIGxvYWQuCisKKyAgICBSZXR1cm5zOgorICAgICAgVGhlIGVudW0gZGVzY3JpcHRvciBmb3IgdGhlIG5hbWVkIHR5cGUuCisgICAgIiIiCisKKyAgICBmdWxsX25hbWUgPSBfTm9ybWFsaXplRnVsbHlRdWFsaWZpZWROYW1lKGZ1bGxfbmFtZSkKKyAgICBpZiBmdWxsX25hbWUgbm90IGluIHNlbGYuX2VudW1fZGVzY3JpcHRvcnM6CisgICAgICBzZWxmLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChmdWxsX25hbWUpCisgICAgcmV0dXJuIHNlbGYuX2VudW1fZGVzY3JpcHRvcnNbZnVsbF9uYW1lXQorCisgIGRlZiBfQ29udmVydEZpbGVQcm90b1RvRmlsZURlc2NyaXB0b3Ioc2VsZiwgZmlsZV9wcm90byk6CisgICAgIiIiQ3JlYXRlcyBhIEZpbGVEZXNjcmlwdG9yIGZyb20gYSBwcm90byBvciByZXR1cm5zIGEgY2FjaGVkIGNvcHkuCisKKyAgICBUaGlzIG1ldGhvZCBhbHNvIGhhcyB0aGUgc2lkZSBlZmZlY3Qgb2YgbG9hZGluZyBhbGwgdGhlIHN5bWJvbHMgZm91bmQgaW4KKyAgICB0aGUgZmlsZSBpbnRvIHRoZSBhcHByb3ByaWF0ZSBkaWN0aW9uYXJpZXMgaW4gdGhlIHBvb2wuCisKKyAgICBBcmdzOgorICAgICAgZmlsZV9wcm90bzogVGhlIHByb3RvIHRvIGNvbnZlcnQuCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBGaWxlRGVzY3JpcHRvciBtYXRjaGluZyB0aGUgcGFzc2VkIGluIHByb3RvLgorICAgICIiIgorCisgICAgaWYgZmlsZV9wcm90by5uYW1lIG5vdCBpbiBzZWxmLl9maWxlX2Rlc2NyaXB0b3JzOgorICAgICAgYnVpbHRfZGVwcyA9IGxpc3Qoc2VsZi5fR2V0RGVwcyhmaWxlX3Byb3RvLmRlcGVuZGVuY3kpKQorICAgICAgZGlyZWN0X2RlcHMgPSBbc2VsZi5GaW5kRmlsZUJ5TmFtZShuKSBmb3IgbiBpbiBmaWxlX3Byb3RvLmRlcGVuZGVuY3ldCisKKyAgICAgIGZpbGVfZGVzY3JpcHRvciA9IGRlc2NyaXB0b3IuRmlsZURlc2NyaXB0b3IoCisgICAgICAgICAgbmFtZT1maWxlX3Byb3RvLm5hbWUsCisgICAgICAgICAgcGFja2FnZT1maWxlX3Byb3RvLnBhY2thZ2UsCisgICAgICAgICAgc3ludGF4PWZpbGVfcHJvdG8uc3ludGF4LAorICAgICAgICAgIG9wdGlvbnM9ZmlsZV9wcm90by5vcHRpb25zLAorICAgICAgICAgIHNlcmlhbGl6ZWRfcGI9ZmlsZV9wcm90by5TZXJpYWxpemVUb1N0cmluZygpLAorICAgICAgICAgIGRlcGVuZGVuY2llcz1kaXJlY3RfZGVwcykKKyAgICAgIGlmIF9VU0VfQ19ERVNDUklQVE9SUzoKKyAgICAgICAgIyBXaGVuIHVzaW5nIEMrKyBkZXNjcmlwdG9ycywgYWxsIG9iamVjdHMgZGVmaW5lZCBpbiB0aGUgZmlsZSB3ZXJlIGFkZGVkCisgICAgICAgICMgdG8gdGhlIEMrKyBkYXRhYmFzZSB3aGVuIHRoZSBGaWxlRGVzY3JpcHRvciB3YXMgYnVpbHQgYWJvdmUuCisgICAgICAgICMgSnVzdCBhZGQgdGhlbSB0byB0aGlzIGRlc2NyaXB0b3IgcG9vbC4KKyAgICAgICAgZGVmIF9BZGRNZXNzYWdlRGVzY3JpcHRvcihtZXNzYWdlX2Rlc2MpOgorICAgICAgICAgIHNlbGYuX2Rlc2NyaXB0b3JzW21lc3NhZ2VfZGVzYy5mdWxsX25hbWVdID0gbWVzc2FnZV9kZXNjCisgICAgICAgICAgZm9yIG5lc3RlZCBpbiBtZXNzYWdlX2Rlc2MubmVzdGVkX3R5cGVzOgorICAgICAgICAgICAgX0FkZE1lc3NhZ2VEZXNjcmlwdG9yKG5lc3RlZCkKKyAgICAgICAgICBmb3IgZW51bV90eXBlIGluIG1lc3NhZ2VfZGVzYy5lbnVtX3R5cGVzOgorICAgICAgICAgICAgX0FkZEVudW1EZXNjcmlwdG9yKGVudW1fdHlwZSkKKyAgICAgICAgZGVmIF9BZGRFbnVtRGVzY3JpcHRvcihlbnVtX2Rlc2MpOgorICAgICAgICAgIHNlbGYuX2VudW1fZGVzY3JpcHRvcnNbZW51bV9kZXNjLmZ1bGxfbmFtZV0gPSBlbnVtX2Rlc2MKKyAgICAgICAgZm9yIG1lc3NhZ2VfdHlwZSBpbiBmaWxlX2Rlc2NyaXB0b3IubWVzc2FnZV90eXBlc19ieV9uYW1lLnZhbHVlcygpOgorICAgICAgICAgIF9BZGRNZXNzYWdlRGVzY3JpcHRvcihtZXNzYWdlX3R5cGUpCisgICAgICAgIGZvciBlbnVtX3R5cGUgaW4gZmlsZV9kZXNjcmlwdG9yLmVudW1fdHlwZXNfYnlfbmFtZS52YWx1ZXMoKToKKyAgICAgICAgICBfQWRkRW51bURlc2NyaXB0b3IoZW51bV90eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgc2NvcGUgPSB7fQorCisgICAgICAgICMgVGhpcyBsb29wIGV4dHJhY3RzIGFsbCB0aGUgbWVzc2FnZSBhbmQgZW51bSB0eXBlcyBmcm9tIGFsbCB0aGUKKyAgICAgICAgIyBkZXBlbmRlbmNpZXMgb2YgdGhlIGZpbGVfcHJvdG8uIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGNyZWF0ZSB0aGUKKyAgICAgICAgIyBzY29wZSBvZiBhdmFpbGFibGUgbWVzc2FnZSB0eXBlcyB3aGVuIGRlZmluaW5nIHRoZSBwYXNzZWQgaW4KKyAgICAgICAgIyBmaWxlIHByb3RvLgorICAgICAgICBmb3IgZGVwZW5kZW5jeSBpbiBidWlsdF9kZXBzOgorICAgICAgICAgIHNjb3BlLnVwZGF0ZShzZWxmLl9FeHRyYWN0U3ltYm9scygKKyAgICAgICAgICAgICAgZGVwZW5kZW5jeS5tZXNzYWdlX3R5cGVzX2J5X25hbWUudmFsdWVzKCkpKQorICAgICAgICAgIHNjb3BlLnVwZGF0ZSgoX1ByZWZpeFdpdGhEb3QoZW51bS5mdWxsX25hbWUpLCBlbnVtKQorICAgICAgICAgICAgICAgICAgICAgICBmb3IgZW51bSBpbiBkZXBlbmRlbmN5LmVudW1fdHlwZXNfYnlfbmFtZS52YWx1ZXMoKSkKKworICAgICAgICBmb3IgbWVzc2FnZV90eXBlIGluIGZpbGVfcHJvdG8ubWVzc2FnZV90eXBlOgorICAgICAgICAgIG1lc3NhZ2VfZGVzYyA9IHNlbGYuX0NvbnZlcnRNZXNzYWdlRGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgbWVzc2FnZV90eXBlLCBmaWxlX3Byb3RvLnBhY2thZ2UsIGZpbGVfZGVzY3JpcHRvciwgc2NvcGUsCisgICAgICAgICAgICAgIGZpbGVfcHJvdG8uc3ludGF4KQorICAgICAgICAgIGZpbGVfZGVzY3JpcHRvci5tZXNzYWdlX3R5cGVzX2J5X25hbWVbbWVzc2FnZV9kZXNjLm5hbWVdID0gKAorICAgICAgICAgICAgICBtZXNzYWdlX2Rlc2MpCisKKyAgICAgICAgZm9yIGVudW1fdHlwZSBpbiBmaWxlX3Byb3RvLmVudW1fdHlwZToKKyAgICAgICAgICBmaWxlX2Rlc2NyaXB0b3IuZW51bV90eXBlc19ieV9uYW1lW2VudW1fdHlwZS5uYW1lXSA9ICgKKyAgICAgICAgICAgICAgc2VsZi5fQ29udmVydEVudW1EZXNjcmlwdG9yKGVudW1fdHlwZSwgZmlsZV9wcm90by5wYWNrYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9kZXNjcmlwdG9yLCBOb25lLCBzY29wZSkpCisKKyAgICAgICAgZm9yIGluZGV4LCBleHRlbnNpb25fcHJvdG8gaW4gZW51bWVyYXRlKGZpbGVfcHJvdG8uZXh0ZW5zaW9uKToKKyAgICAgICAgICBleHRlbnNpb25fZGVzYyA9IHNlbGYuTWFrZUZpZWxkRGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgZXh0ZW5zaW9uX3Byb3RvLCBmaWxlX3Byb3RvLnBhY2thZ2UsIGluZGV4LCBpc19leHRlbnNpb249VHJ1ZSkKKyAgICAgICAgICBleHRlbnNpb25fZGVzYy5jb250YWluaW5nX3R5cGUgPSBzZWxmLl9HZXRUeXBlRnJvbVNjb3BlKAorICAgICAgICAgICAgICBmaWxlX2Rlc2NyaXB0b3IucGFja2FnZSwgZXh0ZW5zaW9uX3Byb3RvLmV4dGVuZGVlLCBzY29wZSkKKyAgICAgICAgICBzZWxmLlNldEZpZWxkVHlwZShleHRlbnNpb25fcHJvdG8sIGV4dGVuc2lvbl9kZXNjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfZGVzY3JpcHRvci5wYWNrYWdlLCBzY29wZSkKKyAgICAgICAgICBmaWxlX2Rlc2NyaXB0b3IuZXh0ZW5zaW9uc19ieV9uYW1lW2V4dGVuc2lvbl9kZXNjLm5hbWVdID0gKAorICAgICAgICAgICAgICBleHRlbnNpb25fZGVzYykKKworICAgICAgICBmb3IgZGVzY19wcm90byBpbiBmaWxlX3Byb3RvLm1lc3NhZ2VfdHlwZToKKyAgICAgICAgICBzZWxmLlNldEFsbEZpZWxkVHlwZXMoZmlsZV9wcm90by5wYWNrYWdlLCBkZXNjX3Byb3RvLCBzY29wZSkKKworICAgICAgICBpZiBmaWxlX3Byb3RvLnBhY2thZ2U6CisgICAgICAgICAgZGVzY19wcm90b19wcmVmaXggPSBfUHJlZml4V2l0aERvdChmaWxlX3Byb3RvLnBhY2thZ2UpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgZGVzY19wcm90b19wcmVmaXggPSAnJworCisgICAgICAgIGZvciBkZXNjX3Byb3RvIGluIGZpbGVfcHJvdG8ubWVzc2FnZV90eXBlOgorICAgICAgICAgIGRlc2MgPSBzZWxmLl9HZXRUeXBlRnJvbVNjb3BlKAorICAgICAgICAgICAgICBkZXNjX3Byb3RvX3ByZWZpeCwgZGVzY19wcm90by5uYW1lLCBzY29wZSkKKyAgICAgICAgICBmaWxlX2Rlc2NyaXB0b3IubWVzc2FnZV90eXBlc19ieV9uYW1lW2Rlc2NfcHJvdG8ubmFtZV0gPSBkZXNjCisKKyAgICAgIHNlbGYuQWRkKGZpbGVfcHJvdG8pCisgICAgICBzZWxmLl9maWxlX2Rlc2NyaXB0b3JzW2ZpbGVfcHJvdG8ubmFtZV0gPSBmaWxlX2Rlc2NyaXB0b3IKKworICAgIHJldHVybiBzZWxmLl9maWxlX2Rlc2NyaXB0b3JzW2ZpbGVfcHJvdG8ubmFtZV0KKworICBkZWYgX0NvbnZlcnRNZXNzYWdlRGVzY3JpcHRvcihzZWxmLCBkZXNjX3Byb3RvLCBwYWNrYWdlPU5vbmUsIGZpbGVfZGVzYz1Ob25lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY29wZT1Ob25lLCBzeW50YXg9Tm9uZSk6CisgICAgIiIiQWRkcyB0aGUgcHJvdG8gdG8gdGhlIHBvb2wgaW4gdGhlIHNwZWNpZmllZCBwYWNrYWdlLgorCisgICAgQXJnczoKKyAgICAgIGRlc2NfcHJvdG86IFRoZSBkZXNjcmlwdG9yX3BiMi5EZXNjcmlwdG9yUHJvdG8gcHJvdG9idWYgbWVzc2FnZS4KKyAgICAgIHBhY2thZ2U6IFRoZSBwYWNrYWdlIHRoZSBwcm90byBzaG91bGQgYmUgbG9jYXRlZCBpbi4KKyAgICAgIGZpbGVfZGVzYzogVGhlIGZpbGUgY29udGFpbmluZyB0aGlzIG1lc3NhZ2UuCisgICAgICBzY29wZTogRGljdCBtYXBwaW5nIHNob3J0IGFuZCBmdWxsIHN5bWJvbHMgdG8gbWVzc2FnZSBhbmQgZW51bSB0eXBlcy4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgYWRkZWQgZGVzY3JpcHRvci4KKyAgICAiIiIKKworICAgIGlmIHBhY2thZ2U6CisgICAgICBkZXNjX25hbWUgPSAnLicuam9pbigocGFja2FnZSwgZGVzY19wcm90by5uYW1lKSkKKyAgICBlbHNlOgorICAgICAgZGVzY19uYW1lID0gZGVzY19wcm90by5uYW1lCisKKyAgICBpZiBmaWxlX2Rlc2MgaXMgTm9uZToKKyAgICAgIGZpbGVfbmFtZSA9IE5vbmUKKyAgICBlbHNlOgorICAgICAgZmlsZV9uYW1lID0gZmlsZV9kZXNjLm5hbWUKKworICAgIGlmIHNjb3BlIGlzIE5vbmU6CisgICAgICBzY29wZSA9IHt9CisKKyAgICBuZXN0ZWQgPSBbCisgICAgICAgIHNlbGYuX0NvbnZlcnRNZXNzYWdlRGVzY3JpcHRvcigKKyAgICAgICAgICAgIG5lc3RlZCwgZGVzY19uYW1lLCBmaWxlX2Rlc2MsIHNjb3BlLCBzeW50YXgpCisgICAgICAgIGZvciBuZXN0ZWQgaW4gZGVzY19wcm90by5uZXN0ZWRfdHlwZV0KKyAgICBlbnVtcyA9IFsKKyAgICAgICAgc2VsZi5fQ29udmVydEVudW1EZXNjcmlwdG9yKGVudW0sIGRlc2NfbmFtZSwgZmlsZV9kZXNjLCBOb25lLCBzY29wZSkKKyAgICAgICAgZm9yIGVudW0gaW4gZGVzY19wcm90by5lbnVtX3R5cGVdCisgICAgZmllbGRzID0gW3NlbGYuTWFrZUZpZWxkRGVzY3JpcHRvcihmaWVsZCwgZGVzY19uYW1lLCBpbmRleCkKKyAgICAgICAgICAgICAgZm9yIGluZGV4LCBmaWVsZCBpbiBlbnVtZXJhdGUoZGVzY19wcm90by5maWVsZCldCisgICAgZXh0ZW5zaW9ucyA9IFsKKyAgICAgICAgc2VsZi5NYWtlRmllbGREZXNjcmlwdG9yKGV4dGVuc2lvbiwgZGVzY19uYW1lLCBpbmRleCwgaXNfZXh0ZW5zaW9uPVRydWUpCisgICAgICAgIGZvciBpbmRleCwgZXh0ZW5zaW9uIGluIGVudW1lcmF0ZShkZXNjX3Byb3RvLmV4dGVuc2lvbildCisgICAgb25lb2ZzID0gWworICAgICAgICBkZXNjcmlwdG9yLk9uZW9mRGVzY3JpcHRvcihkZXNjLm5hbWUsICcuJy5qb2luKChkZXNjX25hbWUsIGRlc2MubmFtZSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCwgTm9uZSwgW10pCisgICAgICAgIGZvciBpbmRleCwgZGVzYyBpbiBlbnVtZXJhdGUoZGVzY19wcm90by5vbmVvZl9kZWNsKV0KKyAgICBleHRlbnNpb25fcmFuZ2VzID0gWyhyLnN0YXJ0LCByLmVuZCkgZm9yIHIgaW4gZGVzY19wcm90by5leHRlbnNpb25fcmFuZ2VdCisgICAgaWYgZXh0ZW5zaW9uX3JhbmdlczoKKyAgICAgIGlzX2V4dGVuZGFibGUgPSBUcnVlCisgICAgZWxzZToKKyAgICAgIGlzX2V4dGVuZGFibGUgPSBGYWxzZQorICAgIGRlc2MgPSBkZXNjcmlwdG9yLkRlc2NyaXB0b3IoCisgICAgICAgIG5hbWU9ZGVzY19wcm90by5uYW1lLAorICAgICAgICBmdWxsX25hbWU9ZGVzY19uYW1lLAorICAgICAgICBmaWxlbmFtZT1maWxlX25hbWUsCisgICAgICAgIGNvbnRhaW5pbmdfdHlwZT1Ob25lLAorICAgICAgICBmaWVsZHM9ZmllbGRzLAorICAgICAgICBvbmVvZnM9b25lb2ZzLAorICAgICAgICBuZXN0ZWRfdHlwZXM9bmVzdGVkLAorICAgICAgICBlbnVtX3R5cGVzPWVudW1zLAorICAgICAgICBleHRlbnNpb25zPWV4dGVuc2lvbnMsCisgICAgICAgIG9wdGlvbnM9ZGVzY19wcm90by5vcHRpb25zLAorICAgICAgICBpc19leHRlbmRhYmxlPWlzX2V4dGVuZGFibGUsCisgICAgICAgIGV4dGVuc2lvbl9yYW5nZXM9ZXh0ZW5zaW9uX3JhbmdlcywKKyAgICAgICAgZmlsZT1maWxlX2Rlc2MsCisgICAgICAgIHNlcmlhbGl6ZWRfc3RhcnQ9Tm9uZSwKKyAgICAgICAgc2VyaWFsaXplZF9lbmQ9Tm9uZSwKKyAgICAgICAgc3ludGF4PXN5bnRheCkKKyAgICBmb3IgbmVzdGVkIGluIGRlc2MubmVzdGVkX3R5cGVzOgorICAgICAgbmVzdGVkLmNvbnRhaW5pbmdfdHlwZSA9IGRlc2MKKyAgICBmb3IgZW51bSBpbiBkZXNjLmVudW1fdHlwZXM6CisgICAgICBlbnVtLmNvbnRhaW5pbmdfdHlwZSA9IGRlc2MKKyAgICBmb3IgZmllbGRfaW5kZXgsIGZpZWxkX2Rlc2MgaW4gZW51bWVyYXRlKGRlc2NfcHJvdG8uZmllbGQpOgorICAgICAgaWYgZmllbGRfZGVzYy5IYXNGaWVsZCgnb25lb2ZfaW5kZXgnKToKKyAgICAgICAgb25lb2ZfaW5kZXggPSBmaWVsZF9kZXNjLm9uZW9mX2luZGV4CisgICAgICAgIG9uZW9mc1tvbmVvZl9pbmRleF0uZmllbGRzLmFwcGVuZChmaWVsZHNbZmllbGRfaW5kZXhdKQorICAgICAgICBmaWVsZHNbZmllbGRfaW5kZXhdLmNvbnRhaW5pbmdfb25lb2YgPSBvbmVvZnNbb25lb2ZfaW5kZXhdCisKKyAgICBzY29wZVtfUHJlZml4V2l0aERvdChkZXNjX25hbWUpXSA9IGRlc2MKKyAgICBzZWxmLl9kZXNjcmlwdG9yc1tkZXNjX25hbWVdID0gZGVzYworICAgIHJldHVybiBkZXNjCisKKyAgZGVmIF9Db252ZXJ0RW51bURlc2NyaXB0b3Ioc2VsZiwgZW51bV9wcm90bywgcGFja2FnZT1Ob25lLCBmaWxlX2Rlc2M9Tm9uZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ190eXBlPU5vbmUsIHNjb3BlPU5vbmUpOgorICAgICIiIk1ha2UgYSBwcm90b2J1ZiBFbnVtRGVzY3JpcHRvciBnaXZlbiBhbiBFbnVtRGVzY3JpcHRvclByb3RvIHByb3RvYnVmLgorCisgICAgQXJnczoKKyAgICAgIGVudW1fcHJvdG86IFRoZSBkZXNjcmlwdG9yX3BiMi5FbnVtRGVzY3JpcHRvclByb3RvIHByb3RvYnVmIG1lc3NhZ2UuCisgICAgICBwYWNrYWdlOiBPcHRpb25hbCBwYWNrYWdlIG5hbWUgZm9yIHRoZSBuZXcgbWVzc2FnZSBFbnVtRGVzY3JpcHRvci4KKyAgICAgIGZpbGVfZGVzYzogVGhlIGZpbGUgY29udGFpbmluZyB0aGUgZW51bSBkZXNjcmlwdG9yLgorICAgICAgY29udGFpbmluZ190eXBlOiBUaGUgdHlwZSBjb250YWluaW5nIHRoaXMgZW51bS4KKyAgICAgIHNjb3BlOiBTY29wZSBjb250YWluaW5nIGF2YWlsYWJsZSB0eXBlcy4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgYWRkZWQgZGVzY3JpcHRvcgorICAgICIiIgorCisgICAgaWYgcGFja2FnZToKKyAgICAgIGVudW1fbmFtZSA9ICcuJy5qb2luKChwYWNrYWdlLCBlbnVtX3Byb3RvLm5hbWUpKQorICAgIGVsc2U6CisgICAgICBlbnVtX25hbWUgPSBlbnVtX3Byb3RvLm5hbWUKKworICAgIGlmIGZpbGVfZGVzYyBpcyBOb25lOgorICAgICAgZmlsZV9uYW1lID0gTm9uZQorICAgIGVsc2U6CisgICAgICBmaWxlX25hbWUgPSBmaWxlX2Rlc2MubmFtZQorCisgICAgdmFsdWVzID0gW3NlbGYuX01ha2VFbnVtVmFsdWVEZXNjcmlwdG9yKHZhbHVlLCBpbmRleCkKKyAgICAgICAgICAgICAgZm9yIGluZGV4LCB2YWx1ZSBpbiBlbnVtZXJhdGUoZW51bV9wcm90by52YWx1ZSldCisgICAgZGVzYyA9IGRlc2NyaXB0b3IuRW51bURlc2NyaXB0b3IobmFtZT1lbnVtX3Byb3RvLm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVsbF9uYW1lPWVudW1fbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZT1maWxlX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZT1maWxlX2Rlc2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXZhbHVlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGU9Y29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM9ZW51bV9wcm90by5vcHRpb25zKQorICAgIHNjb3BlWycuJXMnICUgZW51bV9uYW1lXSA9IGRlc2MKKyAgICBzZWxmLl9lbnVtX2Rlc2NyaXB0b3JzW2VudW1fbmFtZV0gPSBkZXNjCisgICAgcmV0dXJuIGRlc2MKKworICBkZWYgTWFrZUZpZWxkRGVzY3JpcHRvcihzZWxmLCBmaWVsZF9wcm90bywgbWVzc2FnZV9uYW1lLCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uPUZhbHNlKToKKyAgICAiIiJDcmVhdGVzIGEgZmllbGQgZGVzY3JpcHRvciBmcm9tIGEgRmllbGREZXNjcmlwdG9yUHJvdG8uCisKKyAgICBGb3IgbWVzc2FnZSBhbmQgZW51bSB0eXBlIGZpZWxkcywgdGhpcyBtZXRob2Qgd2lsbCBkbyBhIGxvb2sgdXAKKyAgICBpbiB0aGUgcG9vbCBmb3IgdGhlIGFwcHJvcHJpYXRlIGRlc2NyaXB0b3IgZm9yIHRoYXQgdHlwZS4gSWYgaXQKKyAgICBpcyB1bmF2YWlsYWJsZSwgaXQgd2lsbCBmYWxsIGJhY2sgdG8gdGhlIF9zb3VyY2UgZnVuY3Rpb24gdG8KKyAgICBjcmVhdGUgaXQuIElmIHRoaXMgdHlwZSBpcyBzdGlsbCB1bmF2YWlsYWJsZSwgY29uc3RydWN0aW9uIHdpbGwKKyAgICBmYWlsLgorCisgICAgQXJnczoKKyAgICAgIGZpZWxkX3Byb3RvOiBUaGUgcHJvdG8gZGVzY3JpYmluZyB0aGUgZmllbGQuCisgICAgICBtZXNzYWdlX25hbWU6IFRoZSBuYW1lIG9mIHRoZSBjb250YWluaW5nIG1lc3NhZ2UuCisgICAgICBpbmRleDogSW5kZXggb2YgdGhlIGZpZWxkCisgICAgICBpc19leHRlbnNpb246IEluZGljYXRpb24gdGhhdCB0aGlzIGZpZWxkIGlzIGZvciBhbiBleHRlbnNpb24uCisKKyAgICBSZXR1cm5zOgorICAgICAgQW4gaW5pdGlhbGl6ZWQgRmllbGREZXNjcmlwdG9yIG9iamVjdAorICAgICIiIgorCisgICAgaWYgbWVzc2FnZV9uYW1lOgorICAgICAgZnVsbF9uYW1lID0gJy4nLmpvaW4oKG1lc3NhZ2VfbmFtZSwgZmllbGRfcHJvdG8ubmFtZSkpCisgICAgZWxzZToKKyAgICAgIGZ1bGxfbmFtZSA9IGZpZWxkX3Byb3RvLm5hbWUKKworICAgIHJldHVybiBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvcigKKyAgICAgICAgbmFtZT1maWVsZF9wcm90by5uYW1lLAorICAgICAgICBmdWxsX25hbWU9ZnVsbF9uYW1lLAorICAgICAgICBpbmRleD1pbmRleCwKKyAgICAgICAgbnVtYmVyPWZpZWxkX3Byb3RvLm51bWJlciwKKyAgICAgICAgdHlwZT1maWVsZF9wcm90by50eXBlLAorICAgICAgICBjcHBfdHlwZT1Ob25lLAorICAgICAgICBtZXNzYWdlX3R5cGU9Tm9uZSwKKyAgICAgICAgZW51bV90eXBlPU5vbmUsCisgICAgICAgIGNvbnRhaW5pbmdfdHlwZT1Ob25lLAorICAgICAgICBsYWJlbD1maWVsZF9wcm90by5sYWJlbCwKKyAgICAgICAgaGFzX2RlZmF1bHRfdmFsdWU9RmFsc2UsCisgICAgICAgIGRlZmF1bHRfdmFsdWU9Tm9uZSwKKyAgICAgICAgaXNfZXh0ZW5zaW9uPWlzX2V4dGVuc2lvbiwKKyAgICAgICAgZXh0ZW5zaW9uX3Njb3BlPU5vbmUsCisgICAgICAgIG9wdGlvbnM9ZmllbGRfcHJvdG8ub3B0aW9ucykKKworICBkZWYgU2V0QWxsRmllbGRUeXBlcyhzZWxmLCBwYWNrYWdlLCBkZXNjX3Byb3RvLCBzY29wZSk6CisgICAgIiIiU2V0cyBhbGwgdGhlIGRlc2NyaXB0b3IncyBmaWVsZHMncyB0eXBlcy4KKworICAgIFRoaXMgbWV0aG9kIGFsc28gc2V0cyB0aGUgY29udGFpbmluZyB0eXBlcyBvbiBhbnkgZXh0ZW5zaW9ucy4KKworICAgIEFyZ3M6CisgICAgICBwYWNrYWdlOiBUaGUgY3VycmVudCBwYWNrYWdlIG9mIGRlc2NfcHJvdG8uCisgICAgICBkZXNjX3Byb3RvOiBUaGUgbWVzc2FnZSBkZXNjcmlwdG9yIHRvIHVwZGF0ZS4KKyAgICAgIHNjb3BlOiBFbmNsb3Npbmcgc2NvcGUgb2YgYXZhaWxhYmxlIHR5cGVzLgorICAgICIiIgorCisgICAgcGFja2FnZSA9IF9QcmVmaXhXaXRoRG90KHBhY2thZ2UpCisKKyAgICBtYWluX2Rlc2MgPSBzZWxmLl9HZXRUeXBlRnJvbVNjb3BlKHBhY2thZ2UsIGRlc2NfcHJvdG8ubmFtZSwgc2NvcGUpCisKKyAgICBpZiBwYWNrYWdlID09ICcuJzoKKyAgICAgIG5lc3RlZF9wYWNrYWdlID0gX1ByZWZpeFdpdGhEb3QoZGVzY19wcm90by5uYW1lKQorICAgIGVsc2U6CisgICAgICBuZXN0ZWRfcGFja2FnZSA9ICcuJy5qb2luKFtwYWNrYWdlLCBkZXNjX3Byb3RvLm5hbWVdKQorCisgICAgZm9yIGZpZWxkX3Byb3RvLCBmaWVsZF9kZXNjIGluIHppcChkZXNjX3Byb3RvLmZpZWxkLCBtYWluX2Rlc2MuZmllbGRzKToKKyAgICAgIHNlbGYuU2V0RmllbGRUeXBlKGZpZWxkX3Byb3RvLCBmaWVsZF9kZXNjLCBuZXN0ZWRfcGFja2FnZSwgc2NvcGUpCisKKyAgICBmb3IgZXh0ZW5zaW9uX3Byb3RvLCBleHRlbnNpb25fZGVzYyBpbiAoCisgICAgICAgIHppcChkZXNjX3Byb3RvLmV4dGVuc2lvbiwgbWFpbl9kZXNjLmV4dGVuc2lvbnMpKToKKyAgICAgIGV4dGVuc2lvbl9kZXNjLmNvbnRhaW5pbmdfdHlwZSA9IHNlbGYuX0dldFR5cGVGcm9tU2NvcGUoCisgICAgICAgICAgbmVzdGVkX3BhY2thZ2UsIGV4dGVuc2lvbl9wcm90by5leHRlbmRlZSwgc2NvcGUpCisgICAgICBzZWxmLlNldEZpZWxkVHlwZShleHRlbnNpb25fcHJvdG8sIGV4dGVuc2lvbl9kZXNjLCBuZXN0ZWRfcGFja2FnZSwgc2NvcGUpCisKKyAgICBmb3IgbmVzdGVkX3R5cGUgaW4gZGVzY19wcm90by5uZXN0ZWRfdHlwZToKKyAgICAgIHNlbGYuU2V0QWxsRmllbGRUeXBlcyhuZXN0ZWRfcGFja2FnZSwgbmVzdGVkX3R5cGUsIHNjb3BlKQorCisgIGRlZiBTZXRGaWVsZFR5cGUoc2VsZiwgZmllbGRfcHJvdG8sIGZpZWxkX2Rlc2MsIHBhY2thZ2UsIHNjb3BlKToKKyAgICAiIiJTZXRzIHRoZSBmaWVsZCdzIHR5cGUsIGNwcF90eXBlLCBtZXNzYWdlX3R5cGUgYW5kIGVudW1fdHlwZS4KKworICAgIEFyZ3M6CisgICAgICBmaWVsZF9wcm90bzogRGF0YSBhYm91dCB0aGUgZmllbGQgaW4gcHJvdG8gZm9ybWF0LgorICAgICAgZmllbGRfZGVzYzogVGhlIGRlc2NyaXB0b3IgdG8gbW9kaXkuCisgICAgICBwYWNrYWdlOiBUaGUgcGFja2FnZSB0aGUgZmllbGQncyBjb250YWluZXIgaXMgaW4uCisgICAgICBzY29wZTogRW5jbG9zaW5nIHNjb3BlIG9mIGF2YWlsYWJsZSB0eXBlcy4KKyAgICAiIiIKKyAgICBpZiBmaWVsZF9wcm90by50eXBlX25hbWU6CisgICAgICBkZXNjID0gc2VsZi5fR2V0VHlwZUZyb21TY29wZShwYWNrYWdlLCBmaWVsZF9wcm90by50eXBlX25hbWUsIHNjb3BlKQorICAgIGVsc2U6CisgICAgICBkZXNjID0gTm9uZQorCisgICAgaWYgbm90IGZpZWxkX3Byb3RvLkhhc0ZpZWxkKCd0eXBlJyk6CisgICAgICBpZiBpc2luc3RhbmNlKGRlc2MsIGRlc2NyaXB0b3IuRGVzY3JpcHRvcik6CisgICAgICAgIGZpZWxkX3Byb3RvLnR5cGUgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0UKKyAgICAgIGVsc2U6CisgICAgICAgIGZpZWxkX3Byb3RvLnR5cGUgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU0KKworICAgIGZpZWxkX2Rlc2MuY3BwX3R5cGUgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5Qcm90b1R5cGVUb0NwcFByb3RvVHlwZSgKKyAgICAgICAgZmllbGRfcHJvdG8udHlwZSkKKworICAgIGlmIChmaWVsZF9wcm90by50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfTUVTU0FHRQorICAgICAgICBvciBmaWVsZF9wcm90by50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfR1JPVVApOgorICAgICAgZmllbGRfZGVzYy5tZXNzYWdlX3R5cGUgPSBkZXNjCisKKyAgICBpZiBmaWVsZF9wcm90by50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfRU5VTToKKyAgICAgIGZpZWxkX2Rlc2MuZW51bV90eXBlID0gZGVzYworCisgICAgaWYgZmllbGRfcHJvdG8ubGFiZWwgPT0gZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuTEFCRUxfUkVQRUFURUQ6CisgICAgICBmaWVsZF9kZXNjLmhhc19kZWZhdWx0X3ZhbHVlID0gRmFsc2UKKyAgICAgIGZpZWxkX2Rlc2MuZGVmYXVsdF92YWx1ZSA9IFtdCisgICAgZWxpZiBmaWVsZF9wcm90by5IYXNGaWVsZCgnZGVmYXVsdF92YWx1ZScpOgorICAgICAgZmllbGRfZGVzYy5oYXNfZGVmYXVsdF92YWx1ZSA9IFRydWUKKyAgICAgIGlmIChmaWVsZF9wcm90by50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfRE9VQkxFIG9yCisgICAgICAgICAgZmllbGRfcHJvdG8udHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0ZMT0FUKToKKyAgICAgICAgZmllbGRfZGVzYy5kZWZhdWx0X3ZhbHVlID0gZmxvYXQoZmllbGRfcHJvdG8uZGVmYXVsdF92YWx1ZSkKKyAgICAgIGVsaWYgZmllbGRfcHJvdG8udHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX1NUUklORzoKKyAgICAgICAgZmllbGRfZGVzYy5kZWZhdWx0X3ZhbHVlID0gZmllbGRfcHJvdG8uZGVmYXVsdF92YWx1ZQorICAgICAgZWxpZiBmaWVsZF9wcm90by50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfQk9PTDoKKyAgICAgICAgZmllbGRfZGVzYy5kZWZhdWx0X3ZhbHVlID0gZmllbGRfcHJvdG8uZGVmYXVsdF92YWx1ZS5sb3dlcigpID09ICd0cnVlJworICAgICAgZWxpZiBmaWVsZF9wcm90by50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfRU5VTToKKyAgICAgICAgZmllbGRfZGVzYy5kZWZhdWx0X3ZhbHVlID0gZmllbGRfZGVzYy5lbnVtX3R5cGUudmFsdWVzX2J5X25hbWVbCisgICAgICAgICAgICBmaWVsZF9wcm90by5kZWZhdWx0X3ZhbHVlXS5udW1iZXIKKyAgICAgIGVsaWYgZmllbGRfcHJvdG8udHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0JZVEVTOgorICAgICAgICBmaWVsZF9kZXNjLmRlZmF1bHRfdmFsdWUgPSB0ZXh0X2VuY29kaW5nLkNVbmVzY2FwZSgKKyAgICAgICAgICAgIGZpZWxkX3Byb3RvLmRlZmF1bHRfdmFsdWUpCisgICAgICBlbHNlOgorICAgICAgICBmaWVsZF9kZXNjLmRlZmF1bHRfdmFsdWUgPSBpbnQoZmllbGRfcHJvdG8uZGVmYXVsdF92YWx1ZSkKKyAgICBlbHNlOgorICAgICAgZmllbGRfZGVzYy5oYXNfZGVmYXVsdF92YWx1ZSA9IEZhbHNlCisgICAgICBmaWVsZF9kZXNjLmRlZmF1bHRfdmFsdWUgPSBOb25lCisKKyAgICBmaWVsZF9kZXNjLnR5cGUgPSBmaWVsZF9wcm90by50eXBlCisKKyAgZGVmIF9NYWtlRW51bVZhbHVlRGVzY3JpcHRvcihzZWxmLCB2YWx1ZV9wcm90bywgaW5kZXgpOgorICAgICIiIkNyZWF0ZXMgYSBlbnVtIHZhbHVlIGRlc2NyaXB0b3Igb2JqZWN0IGZyb20gYSBlbnVtIHZhbHVlIHByb3RvLgorCisgICAgQXJnczoKKyAgICAgIHZhbHVlX3Byb3RvOiBUaGUgcHJvdG8gZGVzY3JpYmluZyB0aGUgZW51bSB2YWx1ZS4KKyAgICAgIGluZGV4OiBUaGUgaW5kZXggb2YgdGhlIGVudW0gdmFsdWUuCisKKyAgICBSZXR1cm5zOgorICAgICAgQW4gaW5pdGlhbGl6ZWQgRW51bVZhbHVlRGVzY3JpcHRvciBvYmplY3QuCisgICAgIiIiCisKKyAgICByZXR1cm4gZGVzY3JpcHRvci5FbnVtVmFsdWVEZXNjcmlwdG9yKAorICAgICAgICBuYW1lPXZhbHVlX3Byb3RvLm5hbWUsCisgICAgICAgIGluZGV4PWluZGV4LAorICAgICAgICBudW1iZXI9dmFsdWVfcHJvdG8ubnVtYmVyLAorICAgICAgICBvcHRpb25zPXZhbHVlX3Byb3RvLm9wdGlvbnMsCisgICAgICAgIHR5cGU9Tm9uZSkKKworICBkZWYgX0V4dHJhY3RTeW1ib2xzKHNlbGYsIGRlc2NyaXB0b3JzKToKKyAgICAiIiJQdWxscyBvdXQgYWxsIHRoZSBzeW1ib2xzIGZyb20gZGVzY3JpcHRvciBwcm90b3MuCisKKyAgICBBcmdzOgorICAgICAgZGVzY3JpcHRvcnM6IFRoZSBtZXNzYWdlcyB0byBleHRyYWN0IGRlc2NyaXB0b3JzIGZyb20uCisgICAgWWllbGRzOgorICAgICAgQSB0d28gZWxlbWVudCB0dXBsZSBvZiB0aGUgdHlwZSBuYW1lIGFuZCBkZXNjcmlwdG9yIG9iamVjdC4KKyAgICAiIiIKKworICAgIGZvciBkZXNjIGluIGRlc2NyaXB0b3JzOgorICAgICAgeWllbGQgKF9QcmVmaXhXaXRoRG90KGRlc2MuZnVsbF9uYW1lKSwgZGVzYykKKyAgICAgIGZvciBzeW1ib2wgaW4gc2VsZi5fRXh0cmFjdFN5bWJvbHMoZGVzYy5uZXN0ZWRfdHlwZXMpOgorICAgICAgICB5aWVsZCBzeW1ib2wKKyAgICAgIGZvciBlbnVtIGluIGRlc2MuZW51bV90eXBlczoKKyAgICAgICAgeWllbGQgKF9QcmVmaXhXaXRoRG90KGVudW0uZnVsbF9uYW1lKSwgZW51bSkKKworICBkZWYgX0dldERlcHMoc2VsZiwgZGVwZW5kZW5jaWVzKToKKyAgICAiIiJSZWN1cnNpdmVseSBmaW5kcyBkZXBlbmRlbmNpZXMgZm9yIGZpbGUgcHJvdG9zLgorCisgICAgQXJnczoKKyAgICAgIGRlcGVuZGVuY2llczogVGhlIG5hbWVzIG9mIHRoZSBmaWxlcyBiZWluZyBkZXBlbmRlZCBvbi4KKworICAgIFlpZWxkczoKKyAgICAgIEVhY2ggZGlyZWN0IGFuZCBpbmRpcmVjdCBkZXBlbmRlbmN5LgorICAgICIiIgorCisgICAgZm9yIGRlcGVuZGVuY3kgaW4gZGVwZW5kZW5jaWVzOgorICAgICAgZGVwX2Rlc2MgPSBzZWxmLkZpbmRGaWxlQnlOYW1lKGRlcGVuZGVuY3kpCisgICAgICB5aWVsZCBkZXBfZGVzYworICAgICAgZm9yIHBhcmVudF9kZXAgaW4gZGVwX2Rlc2MuZGVwZW5kZW5jaWVzOgorICAgICAgICB5aWVsZCBwYXJlbnRfZGVwCisKKyAgZGVmIF9HZXRUeXBlRnJvbVNjb3BlKHNlbGYsIHBhY2thZ2UsIHR5cGVfbmFtZSwgc2NvcGUpOgorICAgICIiIkZpbmRzIGEgZ2l2ZW4gdHlwZSBuYW1lIGluIHRoZSBjdXJyZW50IHNjb3BlLgorCisgICAgQXJnczoKKyAgICAgIHBhY2thZ2U6IFRoZSBwYWNrYWdlIHRoZSBwcm90byBzaG91bGQgYmUgbG9jYXRlZCBpbi4KKyAgICAgIHR5cGVfbmFtZTogVGhlIG5hbWUgb2YgdGhlIHR5cGUgdG8gYmUgZm91bmQgaW4gdGhlIHNjb3BlLgorICAgICAgc2NvcGU6IERpY3QgbWFwcGluZyBzaG9ydCBhbmQgZnVsbCBzeW1ib2xzIHRvIG1lc3NhZ2UgYW5kIGVudW0gdHlwZXMuCisKKyAgICBSZXR1cm5zOgorICAgICAgVGhlIGRlc2NyaXB0b3IgZm9yIHRoZSByZXF1ZXN0ZWQgdHlwZS4KKyAgICAiIiIKKyAgICBpZiB0eXBlX25hbWUgbm90IGluIHNjb3BlOgorICAgICAgY29tcG9uZW50cyA9IF9QcmVmaXhXaXRoRG90KHBhY2thZ2UpLnNwbGl0KCcuJykKKyAgICAgIHdoaWxlIGNvbXBvbmVudHM6CisgICAgICAgIHBvc3NpYmxlX21hdGNoID0gJy4nLmpvaW4oY29tcG9uZW50cyArIFt0eXBlX25hbWVdKQorICAgICAgICBpZiBwb3NzaWJsZV9tYXRjaCBpbiBzY29wZToKKyAgICAgICAgICB0eXBlX25hbWUgPSBwb3NzaWJsZV9tYXRjaAorICAgICAgICAgIGJyZWFrCisgICAgICAgIGVsc2U6CisgICAgICAgICAgY29tcG9uZW50cy5wb3AoLTEpCisgICAgcmV0dXJuIHNjb3BlW3R5cGVfbmFtZV0KKworCitkZWYgX1ByZWZpeFdpdGhEb3QobmFtZSk6CisgIHJldHVybiBuYW1lIGlmIG5hbWUuc3RhcnRzd2l0aCgnLicpIGVsc2UgJy4lcycgJSBuYW1lCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL19faW5pdF9fLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9fX2luaXRfXy5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9fX2luaXRfXy5weQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9fcGFyYW1ldGVyaXplZC5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvX3BhcmFtZXRlcml6ZWQucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNmVkMjMzMAotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvX3BhcmFtZXRlcml6ZWQucHkKQEAgLTAsMCArMSw0MzggQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJBZGRzIHN1cHBvcnQgZm9yIHBhcmFtZXRlcml6ZWQgdGVzdHMgdG8gUHl0aG9uJ3MgdW5pdHRlc3QgVGVzdENhc2UgY2xhc3MuCisKK0EgcGFyYW1ldGVyaXplZCB0ZXN0IGlzIGEgbWV0aG9kIGluIGEgdGVzdCBjYXNlIHRoYXQgaXMgaW52b2tlZCB3aXRoIGRpZmZlcmVudAorYXJndW1lbnQgdHVwbGVzLgorCitBIHNpbXBsZSBleGFtcGxlOgorCisgIGNsYXNzIEFkZGl0aW9uRXhhbXBsZShwYXJhbWV0ZXJpemVkLlBhcmFtZXRlcml6ZWRUZXN0Q2FzZSk6CisgICAgQHBhcmFtZXRlcml6ZWQuUGFyYW1ldGVycygKKyAgICAgICAoMSwgMiwgMyksCisgICAgICAgKDQsIDUsIDkpLAorICAgICAgICgxLCAxLCAzKSkKKyAgICBkZWYgdGVzdEFkZGl0aW9uKHNlbGYsIG9wMSwgb3AyLCByZXN1bHQpOgorICAgICAgc2VsZi5hc3NlcnRFcXVhbHMocmVzdWx0LCBvcDEgKyBvcDIpCisKKworRWFjaCBpbnZvY2F0aW9uIGlzIGEgc2VwYXJhdGUgdGVzdCBjYXNlIGFuZCBwcm9wZXJseSBpc29sYXRlZCBqdXN0CitsaWtlIGEgbm9ybWFsIHRlc3QgbWV0aG9kLCB3aXRoIGl0cyBvd24gc2V0VXAvdGVhckRvd24gY3ljbGUuIEluIHRoZQorZXhhbXBsZSBhYm92ZSwgdGhlcmUgYXJlIHRocmVlIHNlcGFyYXRlIHRlc3RjYXNlcywgb25lIG9mIHdoaWNoIHdpbGwKK2ZhaWwgZHVlIHRvIGFuIGFzc2VydGlvbiBlcnJvciAoMSArIDEgIT0gMykuCisKK1BhcmFtZXRlcnMgZm9yIGludmlkaWR1YWwgdGVzdCBjYXNlcyBjYW4gYmUgdHVwbGVzICh3aXRoIHBvc2l0aW9uYWwgcGFyYW1ldGVycykKK29yIGRpY3Rpb25hcmllcyAod2l0aCBuYW1lZCBwYXJhbWV0ZXJzKToKKworICBjbGFzcyBBZGRpdGlvbkV4YW1wbGUocGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJpemVkVGVzdENhc2UpOgorICAgIEBwYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnMoCisgICAgICAgeydvcDEnOiAxLCAnb3AyJzogMiwgJ3Jlc3VsdCc6IDN9LAorICAgICAgIHsnb3AxJzogNCwgJ29wMic6IDUsICdyZXN1bHQnOiA5fSwKKyAgICApCisgICAgZGVmIHRlc3RBZGRpdGlvbihzZWxmLCBvcDEsIG9wMiwgcmVzdWx0KToKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWxzKHJlc3VsdCwgb3AxICsgb3AyKQorCitJZiBhIHBhcmFtZXRlcml6ZWQgdGVzdCBmYWlscywgdGhlIGVycm9yIG1lc3NhZ2Ugd2lsbCBzaG93IHRoZQorb3JpZ2luYWwgdGVzdCBuYW1lICh3aGljaCBpcyBtb2RpZmllZCBpbnRlcm5hbGx5KSBhbmQgdGhlIGFyZ3VtZW50cworZm9yIHRoZSBzcGVjaWZpYyBpbnZvY2F0aW9uLCB3aGljaCBhcmUgcGFydCBvZiB0aGUgc3RyaW5nIHJldHVybmVkIGJ5Cit0aGUgc2hvcnREZXNjcmlwdGlvbigpIG1ldGhvZCBvbiB0ZXN0IGNhc2VzLgorCitUaGUgaWQgbWV0aG9kIG9mIHRoZSB0ZXN0LCB1c2VkIGludGVybmFsbHkgYnkgdGhlIHVuaXR0ZXN0IGZyYW1ld29yaywKK2lzIGFsc28gbW9kaWZpZWQgdG8gc2hvdyB0aGUgYXJndW1lbnRzLiBUbyBtYWtlIHN1cmUgdGhhdCB0ZXN0IG5hbWVzCitzdGF5IHRoZSBzYW1lIGFjcm9zcyBzZXZlcmFsIGludm9jYXRpb25zLCBvYmplY3QgcmVwcmVzZW50YXRpb25zIGxpa2UKKworICA+Pj4gY2xhc3MgRm9vKG9iamVjdCk6CisgIC4uLiAgcGFzcworICA+Pj4gcmVwcihGb28oKSkKKyAgJzxfX21haW5fXy5Gb28gb2JqZWN0IGF0IDB4MjNkODYxMD4nCisKK2FyZSB0dXJuZWQgaW50byAnPF9fbWFpbl9fLkZvbz4nLiBGb3IgZXZlbiBtb3JlIGRlc2NyaXB0aXZlIG5hbWVzLAorZXNwZWNpYWxseSBpbiB0ZXN0IGxvZ3MsIHlvdSBjYW4gdXNlIHRoZSBOYW1lZFBhcmFtZXRlcnMgZGVjb3JhdG9yLiBJbgordGhpcyBjYXNlLCBvbmx5IHR1cGxlcyBhcmUgc3VwcG9ydGVkLCBhbmQgdGhlIGZpcnN0IHBhcmFtZXRlcnMgaGFzIHRvCitiZSBhIHN0cmluZyAob3IgYW4gb2JqZWN0IHRoYXQgcmV0dXJucyBhbiBhcHQgbmFtZSB3aGVuIGNvbnZlcnRlZCB2aWEKK3N0cigpKToKKworICBjbGFzcyBOYW1lZEV4YW1wbGUocGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJpemVkVGVzdENhc2UpOgorICAgIEBwYXJhbWV0ZXJpemVkLk5hbWVkUGFyYW1ldGVycygKKyAgICAgICAoJ05vcm1hbCcsICdhYScsICdhYWEnLCBUcnVlKSwKKyAgICAgICAoJ0VtcHR5UHJlZml4JywgJycsICdhYmMnLCBUcnVlKSwKKyAgICAgICAoJ0JvdGhFbXB0eScsICcnLCAnJywgVHJ1ZSkpCisgICAgZGVmIHRlc3RTdGFydHNXaXRoKHNlbGYsIHByZWZpeCwgc3RyaW5nLCByZXN1bHQpOgorICAgICAgc2VsZi5hc3NlcnRFcXVhbHMocmVzdWx0LCBzdHJpbmdzLnN0YXJ0c3dpdGgocHJlZml4KSkKKworTmFtZWQgdGVzdHMgYWxzbyBoYXZlIHRoZSBiZW5lZml0IHRoYXQgdGhleSBjYW4gYmUgcnVuIGluZGl2aWR1YWxseQorZnJvbSB0aGUgY29tbWFuZCBsaW5lOgorCisgICQgdGVzdG1vZHVsZS5weSBOYW1lZEV4YW1wbGUudGVzdFN0YXJ0c1dpdGhOb3JtYWwKKyAgLgorICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBSYW4gMSB0ZXN0IGluIDAuMDAwcworCisgIE9LCisKK1BhcmFtZXRlcml6ZWQgQ2xhc3NlcworPT09PT09PT09PT09PT09PT09PT09CitJZiBpbnZvY2F0aW9uIGFyZ3VtZW50cyBhcmUgc2hhcmVkIGFjcm9zcyB0ZXN0IG1ldGhvZHMgaW4gYSBzaW5nbGUKK1BhcmFtZXRlcml6ZWRUZXN0Q2FzZSBjbGFzcywgaW5zdGVhZCBvZiBkZWNvcmF0aW5nIGFsbCB0ZXN0IG1ldGhvZHMKK2luZGl2aWR1YWxseSwgdGhlIGNsYXNzIGl0c2VsZiBjYW4gYmUgZGVjb3JhdGVkOgorCisgIEBwYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnMoCisgICAgKDEsIDIsIDMpCisgICAgKDQsIDUsIDkpKQorICBjbGFzcyBBcml0aG1ldGljVGVzdChwYXJhbWV0ZXJpemVkLlBhcmFtZXRlcml6ZWRUZXN0Q2FzZSk6CisgICAgZGVmIHRlc3RBZGQoc2VsZiwgYXJnMSwgYXJnMiwgcmVzdWx0KToKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoYXJnMSArIGFyZzIsIHJlc3VsdCkKKworICAgIGRlZiB0ZXN0U3VidHJhY3Qoc2VsZiwgYXJnMiwgYXJnMiwgcmVzdWx0KToKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0IC0gYXJnMSwgYXJnMikKKworSW5wdXRzIGZyb20gSXRlcmFibGVzCis9PT09PT09PT09PT09PT09PT09PT0KK0lmIHBhcmFtZXRlcnMgc2hvdWxkIGJlIHNoYXJlZCBhY3Jvc3Mgc2V2ZXJhbCB0ZXN0IGNhc2VzLCBvciBhcmUgZHluYW1pY2FsbHkKK2NyZWF0ZWQgZnJvbSBvdGhlciBzb3VyY2VzLCBhIHNpbmdsZSBub24tdHVwbGUgaXRlcmFibGUgY2FuIGJlIHBhc3NlZCBpbnRvCit0aGUgZGVjb3JhdG9yLiBUaGlzIGl0ZXJhYmxlIHdpbGwgYmUgdXNlZCB0byBvYnRhaW4gdGhlIHRlc3QgY2FzZXM6CisKKyAgY2xhc3MgQWRkaXRpb25FeGFtcGxlKHBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyaXplZFRlc3RDYXNlKToKKyAgICBAcGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzKAorICAgICAgYy5vcDEsIGMub3AyLCBjLnJlc3VsdCBmb3IgYyBpbiB0ZXN0Y2FzZXMKKyAgICApCisgICAgZGVmIHRlc3RBZGRpdGlvbihzZWxmLCBvcDEsIG9wMiwgcmVzdWx0KToKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWxzKHJlc3VsdCwgb3AxICsgb3AyKQorCisKK1NpbmdsZS1Bcmd1bWVudCBUZXN0IE1ldGhvZHMKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK0lmIGEgdGVzdCBtZXRob2QgdGFrZXMgb25seSBvbmUgYXJndW1lbnQsIHRoZSBzaW5nbGUgYXJndW1lbnQgZG9lcyBub3QgbmVlZCB0bworYmUgd3JhcHBlZCBpbnRvIGEgdHVwbGU6CisKKyAgY2xhc3MgTmVnYXRpdmVOdW1iZXJFeGFtcGxlKHBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyaXplZFRlc3RDYXNlKToKKyAgICBAcGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzKAorICAgICAgIC0xLCAtMywgLTQsIC01CisgICAgKQorICAgIGRlZiB0ZXN0SXNOZWdhdGl2ZShzZWxmLCBhcmcpOgorICAgICAgc2VsZi5hc3NlcnRUcnVlKElzTmVnYXRpdmUoYXJnKSkKKyIiIgorCitfX2F1dGhvcl9fID0gJ3RtYXJla0Bnb29nbGUuY29tIChUb3JzdGVuIE1hcmVrKScKKworaW1wb3J0IGNvbGxlY3Rpb25zCitpbXBvcnQgZnVuY3Rvb2xzCitpbXBvcnQgcmUKK2ltcG9ydCB0eXBlcworaW1wb3J0IHVuaXR0ZXN0CitpbXBvcnQgdXVpZAorCitmcm9tIGdvb2dsZS5hcHB1dGlscyBpbXBvcnQgYmFzZXRlc3QKKworQUREUl9SRSA9IHJlLmNvbXBpbGUocidcPChbYS16QS1aMC05X1wtXC5dKykgb2JqZWN0IGF0IDB4W2EtZkEtRjAtOV0rXD4nKQorX1NFUEFSQVRPUiA9IHV1aWQudXVpZDEoKS5oZXgKK19GSVJTVF9BUkcgPSBvYmplY3QoKQorX0FSR1VNRU5UX1JFUFIgPSBvYmplY3QoKQorCisKK2RlZiBfQ2xlYW5SZXByKG9iaik6CisgIHJldHVybiBBRERSX1JFLnN1YihyJzxcMT4nLCByZXByKG9iaikpCisKKworIyBIZWxwZXIgZnVuY3Rpb24gZm9ybWVybHkgZnJvbSB0aGUgdW5pdHRlc3QgbW9kdWxlLCByZW1vdmVkIGZyb20gaXQgaW4KKyMgUHl0aG9uIDIuNy4KK2RlZiBfU3RyQ2xhc3MoY2xzKToKKyAgcmV0dXJuICclcy4lcycgJSAoY2xzLl9fbW9kdWxlX18sIGNscy5fX25hbWVfXykKKworCitkZWYgX05vblN0cmluZ0l0ZXJhYmxlKG9iaik6CisgIHJldHVybiAoaXNpbnN0YW5jZShvYmosIGNvbGxlY3Rpb25zLkl0ZXJhYmxlKSBhbmQgbm90CisgICAgICAgICAgaXNpbnN0YW5jZShvYmosIGJhc2VzdHJpbmcpKQorCisKK2RlZiBfRm9ybWF0UGFyYW1ldGVyTGlzdCh0ZXN0Y2FzZV9wYXJhbXMpOgorICBpZiBpc2luc3RhbmNlKHRlc3RjYXNlX3BhcmFtcywgY29sbGVjdGlvbnMuTWFwcGluZyk6CisgICAgcmV0dXJuICcsICcuam9pbignJXM9JXMnICUgKGFyZ25hbWUsIF9DbGVhblJlcHIodmFsdWUpKQorICAgICAgICAgICAgICAgICAgICAgZm9yIGFyZ25hbWUsIHZhbHVlIGluIHRlc3RjYXNlX3BhcmFtcy5pdGVyaXRlbXMoKSkKKyAgZWxpZiBfTm9uU3RyaW5nSXRlcmFibGUodGVzdGNhc2VfcGFyYW1zKToKKyAgICByZXR1cm4gJywgJy5qb2luKG1hcChfQ2xlYW5SZXByLCB0ZXN0Y2FzZV9wYXJhbXMpKQorICBlbHNlOgorICAgIHJldHVybiBfRm9ybWF0UGFyYW1ldGVyTGlzdCgodGVzdGNhc2VfcGFyYW1zLCkpCisKKworY2xhc3MgX1BhcmFtZXRlcml6ZWRUZXN0SXRlcihvYmplY3QpOgorICAiIiJDYWxsYWJsZSBhbmQgaXRlcmFibGUgY2xhc3MgZm9yIHByb2R1Y2luZyBuZXcgdGVzdCBjYXNlcy4iIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgdGVzdF9tZXRob2QsIHRlc3RjYXNlcywgbmFtaW5nX3R5cGUpOgorICAgICIiIlJldHVybnMgY29uY3JldGUgdGVzdCBmdW5jdGlvbnMgZm9yIGEgdGVzdCBhbmQgYSBsaXN0IG9mIHBhcmFtZXRlcnMuCisKKyAgICBUaGUgbmFtaW5nX3R5cGUgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIG5hbWUgb2YgdGhlIGNvbmNyZXRlCisgICAgZnVuY3Rpb25zIGFzIHJlcG9ydGVkIGJ5IHRoZSB1bml0dGVzdCBmcmFtZXdvcmsuIElmIG5hbWluZ190eXBlIGlzCisgICAgX0ZJUlNUX0FSRywgdGhlIHRlc3RjYXNlcyBtdXN0IGJlIHR1cGxlcywgYW5kIHRoZSBmaXJzdCBlbGVtZW50IG11c3QKKyAgICBoYXZlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIHRoYXQgaXMgYSB2YWxpZCBQeXRob24gaWRlbnRpZmllci4KKworICAgIEFyZ3M6CisgICAgICB0ZXN0X21ldGhvZDogVGhlIGRlY29yYXRlZCB0ZXN0IG1ldGhvZC4KKyAgICAgIHRlc3RjYXNlczogKGxpc3Qgb2YgdHVwbGUvZGljdCkgQSBsaXN0IG9mIHBhcmFtZXRlcgorICAgICAgICAgICAgICAgICB0dXBsZXMvZGljdHMgZm9yIGluZGl2aWR1YWwgdGVzdCBpbnZvY2F0aW9ucy4KKyAgICAgIG5hbWluZ190eXBlOiBUaGUgdGVzdCBuYW1pbmcgdHlwZSwgZWl0aGVyIF9OQU1FRCBvciBfQVJHVU1FTlRfUkVQUi4KKyAgICAiIiIKKyAgICBzZWxmLl90ZXN0X21ldGhvZCA9IHRlc3RfbWV0aG9kCisgICAgc2VsZi50ZXN0Y2FzZXMgPSB0ZXN0Y2FzZXMKKyAgICBzZWxmLl9uYW1pbmdfdHlwZSA9IG5hbWluZ190eXBlCisKKyAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzLCAqKmt3YXJncyk6CisgICAgcmFpc2UgUnVudGltZUVycm9yKCdZb3UgYXBwZWFyIHRvIGJlIHJ1bm5pbmcgYSBwYXJhbWV0ZXJpemVkIHRlc3QgY2FzZSAnCisgICAgICAgICAgICAgICAgICAgICAgICd3aXRob3V0IGhhdmluZyBpbmhlcml0ZWQgZnJvbSBwYXJhbWV0ZXJpemVkLicKKyAgICAgICAgICAgICAgICAgICAgICAgJ1BhcmFtZXRlcml6ZWRUZXN0Q2FzZS4gVGhpcyBpcyBiYWQgYmVjYXVzZSBub25lIG9mICcKKyAgICAgICAgICAgICAgICAgICAgICAgJ3lvdXIgdGVzdCBjYXNlcyBhcmUgYWN0dWFsbHkgYmVpbmcgcnVuLicpCisKKyAgZGVmIF9faXRlcl9fKHNlbGYpOgorICAgIHRlc3RfbWV0aG9kID0gc2VsZi5fdGVzdF9tZXRob2QKKyAgICBuYW1pbmdfdHlwZSA9IHNlbGYuX25hbWluZ190eXBlCisKKyAgICBkZWYgTWFrZUJvdW5kUGFyYW1UZXN0KHRlc3RjYXNlX3BhcmFtcyk6CisgICAgICBAZnVuY3Rvb2xzLndyYXBzKHRlc3RfbWV0aG9kKQorICAgICAgZGVmIEJvdW5kUGFyYW1UZXN0KHNlbGYpOgorICAgICAgICBpZiBpc2luc3RhbmNlKHRlc3RjYXNlX3BhcmFtcywgY29sbGVjdGlvbnMuTWFwcGluZyk6CisgICAgICAgICAgdGVzdF9tZXRob2Qoc2VsZiwgKip0ZXN0Y2FzZV9wYXJhbXMpCisgICAgICAgIGVsaWYgX05vblN0cmluZ0l0ZXJhYmxlKHRlc3RjYXNlX3BhcmFtcyk6CisgICAgICAgICAgdGVzdF9tZXRob2Qoc2VsZiwgKnRlc3RjYXNlX3BhcmFtcykKKyAgICAgICAgZWxzZToKKyAgICAgICAgICB0ZXN0X21ldGhvZChzZWxmLCB0ZXN0Y2FzZV9wYXJhbXMpCisKKyAgICAgIGlmIG5hbWluZ190eXBlIGlzIF9GSVJTVF9BUkc6CisgICAgICAgICMgU2lnbmFsIHRoZSBtZXRhY2xhc3MgdGhhdCB0aGUgbmFtZSBvZiB0aGUgdGVzdCBmdW5jdGlvbiBpcyB1bmlxdWUKKyAgICAgICAgIyBhbmQgZGVzY3JpcHRpdmUuCisgICAgICAgIEJvdW5kUGFyYW1UZXN0Ll9feF91c2VfbmFtZV9fID0gVHJ1ZQorICAgICAgICBCb3VuZFBhcmFtVGVzdC5fX25hbWVfXyArPSBzdHIodGVzdGNhc2VfcGFyYW1zWzBdKQorICAgICAgICB0ZXN0Y2FzZV9wYXJhbXMgPSB0ZXN0Y2FzZV9wYXJhbXNbMTpdCisgICAgICBlbGlmIG5hbWluZ190eXBlIGlzIF9BUkdVTUVOVF9SRVBSOgorICAgICAgICAjIF9feF9leHRyYV9pZF9fIGlzIHVzZWQgdG8gcGFzcyBuYW1pbmcgaW5mb3JtYXRpb24gdG8gdGhlIF9fbmV3X18KKyAgICAgICAgIyBtZXRob2Qgb2YgVGVzdEdlbmVyYXRvck1ldGFjbGFzcy4KKyAgICAgICAgIyBUaGUgbWV0YWNsYXNzIHdpbGwgbWFrZSBzdXJlIHRvIGNyZWF0ZSBhIHVuaXF1ZSwgYnV0IG5vbmRlc2NyaXB0aXZlCisgICAgICAgICMgbmFtZSBmb3IgdGhpcyB0ZXN0LgorICAgICAgICBCb3VuZFBhcmFtVGVzdC5fX3hfZXh0cmFfaWRfXyA9ICcoJXMpJyAlICgKKyAgICAgICAgICAgIF9Gb3JtYXRQYXJhbWV0ZXJMaXN0KHRlc3RjYXNlX3BhcmFtcyksKQorICAgICAgZWxzZToKKyAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKCclcyBpcyBub3QgYSB2YWxpZCBuYW1pbmcgdHlwZS4nICUgKG5hbWluZ190eXBlLCkpCisKKyAgICAgIEJvdW5kUGFyYW1UZXN0Ll9fZG9jX18gPSAnJXMoJXMpJyAlICgKKyAgICAgICAgICBCb3VuZFBhcmFtVGVzdC5fX25hbWVfXywgX0Zvcm1hdFBhcmFtZXRlckxpc3QodGVzdGNhc2VfcGFyYW1zKSkKKyAgICAgIGlmIHRlc3RfbWV0aG9kLl9fZG9jX186CisgICAgICAgIEJvdW5kUGFyYW1UZXN0Ll9fZG9jX18gKz0gJ1xuJXMnICUgKHRlc3RfbWV0aG9kLl9fZG9jX18sKQorICAgICAgcmV0dXJuIEJvdW5kUGFyYW1UZXN0CisgICAgcmV0dXJuIChNYWtlQm91bmRQYXJhbVRlc3QoYykgZm9yIGMgaW4gc2VsZi50ZXN0Y2FzZXMpCisKKworZGVmIF9Jc1NpbmdsZXRvbkxpc3QodGVzdGNhc2VzKToKKyAgIiIiVHJ1ZSBpZmYgdGVzdGNhc2VzIGNvbnRhaW5zIG9ubHkgYSBzaW5nbGUgbm9uLXR1cGxlIGVsZW1lbnQuIiIiCisgIHJldHVybiBsZW4odGVzdGNhc2VzKSA9PSAxIGFuZCBub3QgaXNpbnN0YW5jZSh0ZXN0Y2FzZXNbMF0sIHR1cGxlKQorCisKK2RlZiBfTW9kaWZ5Q2xhc3MoY2xhc3Nfb2JqZWN0LCB0ZXN0Y2FzZXMsIG5hbWluZ190eXBlKToKKyAgYXNzZXJ0IG5vdCBnZXRhdHRyKGNsYXNzX29iamVjdCwgJ19pZF9zdWZmaXgnLCBOb25lKSwgKAorICAgICAgJ0Nhbm5vdCBhZGQgcGFyYW1ldGVycyB0byAlcywnCisgICAgICAnIHdoaWNoIGFscmVhZHkgaGFzIHBhcmFtZXRlcml6ZWQgbWV0aG9kcy4nICUgKGNsYXNzX29iamVjdCwpKQorICBjbGFzc19vYmplY3QuX2lkX3N1ZmZpeCA9IGlkX3N1ZmZpeCA9IHt9CisgIGZvciBuYW1lLCBvYmogaW4gY2xhc3Nfb2JqZWN0Ll9fZGljdF9fLml0ZW1zKCk6CisgICAgaWYgKG5hbWUuc3RhcnRzd2l0aCh1bml0dGVzdC5UZXN0TG9hZGVyLnRlc3RNZXRob2RQcmVmaXgpCisgICAgICAgIGFuZCBpc2luc3RhbmNlKG9iaiwgdHlwZXMuRnVuY3Rpb25UeXBlKSk6CisgICAgICBkZWxhdHRyKGNsYXNzX29iamVjdCwgbmFtZSkKKyAgICAgIG1ldGhvZHMgPSB7fQorICAgICAgX1VwZGF0ZUNsYXNzRGljdEZvclBhcmFtVGVzdENhc2UoCisgICAgICAgICAgbWV0aG9kcywgaWRfc3VmZml4LCBuYW1lLAorICAgICAgICAgIF9QYXJhbWV0ZXJpemVkVGVzdEl0ZXIob2JqLCB0ZXN0Y2FzZXMsIG5hbWluZ190eXBlKSkKKyAgICAgIGZvciBuYW1lLCBtZXRoIGluIG1ldGhvZHMuaXRlcml0ZW1zKCk6CisgICAgICAgIHNldGF0dHIoY2xhc3Nfb2JqZWN0LCBuYW1lLCBtZXRoKQorCisKK2RlZiBfUGFyYW1ldGVyRGVjb3JhdG9yKG5hbWluZ190eXBlLCB0ZXN0Y2FzZXMpOgorICAiIiJJbXBsZW1lbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyaXphdGlvbiBkZWNvcmF0b3JzLgorCisgIEFyZ3M6CisgICAgbmFtaW5nX3R5cGU6IFRoZSBuYW1pbmcgdHlwZS4KKyAgICB0ZXN0Y2FzZXM6IFRlc3RjYXNlIHBhcmFtZXRlcnMuCisKKyAgUmV0dXJuczoKKyAgICBBIGZ1bmN0aW9uIGZvciBtb2RpZnlpbmcgdGhlIGRlY29yYXRlZCBvYmplY3QuCisgICIiIgorICBkZWYgX0FwcGx5KG9iaik6CisgICAgaWYgaXNpbnN0YW5jZShvYmosIHR5cGUpOgorICAgICAgX01vZGlmeUNsYXNzKAorICAgICAgICAgIG9iaiwKKyAgICAgICAgICBsaXN0KHRlc3RjYXNlcykgaWYgbm90IGlzaW5zdGFuY2UodGVzdGNhc2VzLCBjb2xsZWN0aW9ucy5TZXF1ZW5jZSkKKyAgICAgICAgICBlbHNlIHRlc3RjYXNlcywKKyAgICAgICAgICBuYW1pbmdfdHlwZSkKKyAgICAgIHJldHVybiBvYmoKKyAgICBlbHNlOgorICAgICAgcmV0dXJuIF9QYXJhbWV0ZXJpemVkVGVzdEl0ZXIob2JqLCB0ZXN0Y2FzZXMsIG5hbWluZ190eXBlKQorCisgIGlmIF9Jc1NpbmdsZXRvbkxpc3QodGVzdGNhc2VzKToKKyAgICBhc3NlcnQgX05vblN0cmluZ0l0ZXJhYmxlKHRlc3RjYXNlc1swXSksICgKKyAgICAgICAgJ1NpbmdsZSBwYXJhbWV0ZXIgYXJndW1lbnQgbXVzdCBiZSBhIG5vbi1zdHJpbmcgaXRlcmFibGUnKQorICAgIHRlc3RjYXNlcyA9IHRlc3RjYXNlc1swXQorCisgIHJldHVybiBfQXBwbHkKKworCitkZWYgUGFyYW1ldGVycygqdGVzdGNhc2VzKToKKyAgIiIiQSBkZWNvcmF0b3IgZm9yIGNyZWF0aW5nIHBhcmFtZXRlcml6ZWQgdGVzdHMuCisKKyAgU2VlIHRoZSBtb2R1bGUgZG9jc3RyaW5nIGZvciBhIHVzYWdlIGV4YW1wbGUuCisgIEFyZ3M6CisgICAgKnRlc3RjYXNlczogUGFyYW1ldGVycyBmb3IgdGhlIGRlY29yYXRlZCBtZXRob2QsIGVpdGhlciBhIHNpbmdsZQorICAgICAgICAgICAgICAgIGl0ZXJhYmxlLCBvciBhIGxpc3Qgb2YgdHVwbGVzL2RpY3RzL29iamVjdHMgKGZvciB0ZXN0cworICAgICAgICAgICAgICAgIHdpdGggb25seSBvbmUgYXJndW1lbnQpLgorCisgIFJldHVybnM6CisgICAgIEEgdGVzdCBnZW5lcmF0b3IgdG8gYmUgaGFuZGxlZCBieSBUZXN0R2VuZXJhdG9yTWV0YWNsYXNzLgorICAiIiIKKyAgcmV0dXJuIF9QYXJhbWV0ZXJEZWNvcmF0b3IoX0FSR1VNRU5UX1JFUFIsIHRlc3RjYXNlcykKKworCitkZWYgTmFtZWRQYXJhbWV0ZXJzKCp0ZXN0Y2FzZXMpOgorICAiIiJBIGRlY29yYXRvciBmb3IgY3JlYXRpbmcgcGFyYW1ldGVyaXplZCB0ZXN0cy4KKworICBTZWUgdGhlIG1vZHVsZSBkb2NzdHJpbmcgZm9yIGEgdXNhZ2UgZXhhbXBsZS4gVGhlIGZpcnN0IGVsZW1lbnQgb2YKKyAgZWFjaCBwYXJhbWV0ZXIgdHVwbGUgc2hvdWxkIGJlIGEgc3RyaW5nIGFuZCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZQorICBuYW1lIG9mIHRoZSB0ZXN0IG1ldGhvZC4KKworICBBcmdzOgorICAgICp0ZXN0Y2FzZXM6IFBhcmFtZXRlcnMgZm9yIHRoZSBkZWNvcmF0ZWQgbWV0aG9kLCBlaXRoZXIgYSBzaW5nbGUKKyAgICAgICAgICAgICAgICBpdGVyYWJsZSwgb3IgYSBsaXN0IG9mIHR1cGxlcy4KKworICBSZXR1cm5zOgorICAgICBBIHRlc3QgZ2VuZXJhdG9yIHRvIGJlIGhhbmRsZWQgYnkgVGVzdEdlbmVyYXRvck1ldGFjbGFzcy4KKyAgIiIiCisgIHJldHVybiBfUGFyYW1ldGVyRGVjb3JhdG9yKF9GSVJTVF9BUkcsIHRlc3RjYXNlcykKKworCitjbGFzcyBUZXN0R2VuZXJhdG9yTWV0YWNsYXNzKHR5cGUpOgorICAiIiJNZXRhY2xhc3MgZm9yIHRlc3QgY2FzZXMgd2l0aCB0ZXN0IGdlbmVyYXRvcnMuCisKKyAgQSB0ZXN0IGdlbmVyYXRvciBpcyBhbiBpdGVyYWJsZSBpbiBhIHRlc3RjYXNlIHRoYXQgcHJvZHVjZXMgY2FsbGFibGVzLiBUaGVzZQorICBjYWxsYWJsZXMgbXVzdCBiZSBzaW5nbGUtYXJndW1lbnQgbWV0aG9kcy4gVGhlc2UgbWV0aG9kcyBhcmUgaW5qZWN0ZWQgaW50bworICB0aGUgY2xhc3MgbmFtZXNwYWNlIGFuZCB0aGUgb3JpZ2luYWwgaXRlcmFibGUgaXMgcmVtb3ZlZC4gSWYgdGhlIG5hbWUgb2YgdGhlCisgIGl0ZXJhYmxlIGNvbmZvcm1zIHRvIHRoZSB0ZXN0IHBhdHRlcm4sIHRoZSBpbmplY3RlZCBtZXRob2RzIHdpbGwgYmUgcGlja2VkCisgIHVwIGFzIHRlc3RzIGJ5IHRoZSB1bml0dGVzdCBmcmFtZXdvcmsuCisKKyAgSW4gZ2VuZXJhbCwgaXQgaXMgc3VwcG9zZWQgdG8gYmUgdXNlZCBpbiBjb25qdWN0aW9uIHdpdGggdGhlCisgIFBhcmFtZXRlcnMgZGVjb3JhdG9yLgorICAiIiIKKworICBkZWYgX19uZXdfXyhtY3MsIGNsYXNzX25hbWUsIGJhc2VzLCBkY3QpOgorICAgIGRjdFsnX2lkX3N1ZmZpeCddID0gaWRfc3VmZml4ID0ge30KKyAgICBmb3IgbmFtZSwgb2JqIGluIGRjdC5pdGVtcygpOgorICAgICAgaWYgKG5hbWUuc3RhcnRzd2l0aCh1bml0dGVzdC5UZXN0TG9hZGVyLnRlc3RNZXRob2RQcmVmaXgpIGFuZAorICAgICAgICAgIF9Ob25TdHJpbmdJdGVyYWJsZShvYmopKToKKyAgICAgICAgaXRlcmF0b3IgPSBpdGVyKG9iaikKKyAgICAgICAgZGN0LnBvcChuYW1lKQorICAgICAgICBfVXBkYXRlQ2xhc3NEaWN0Rm9yUGFyYW1UZXN0Q2FzZShkY3QsIGlkX3N1ZmZpeCwgbmFtZSwgaXRlcmF0b3IpCisKKyAgICByZXR1cm4gdHlwZS5fX25ld19fKG1jcywgY2xhc3NfbmFtZSwgYmFzZXMsIGRjdCkKKworCitkZWYgX1VwZGF0ZUNsYXNzRGljdEZvclBhcmFtVGVzdENhc2UoZGN0LCBpZF9zdWZmaXgsIG5hbWUsIGl0ZXJhdG9yKToKKyAgIiIiQWRkcyBpbmRpdmlkdWFsIHRlc3QgY2FzZXMgdG8gYSBkaWN0aW9uYXJ5LgorCisgIEFyZ3M6CisgICAgZGN0OiBUaGUgdGFyZ2V0IGRpY3Rpb25hcnkuCisgICAgaWRfc3VmZml4OiBUaGUgZGljdGlvbmFyeSBmb3IgbWFwcGluZyBuYW1lcyB0byB0ZXN0IElEcy4KKyAgICBuYW1lOiBUaGUgb3JpZ2luYWwgbmFtZSBvZiB0aGUgdGVzdCBjYXNlLgorICAgIGl0ZXJhdG9yOiBUaGUgaXRlcmF0b3IgZ2VuZXJhdGluZyB0aGUgaW5kaXZpZHVhbCB0ZXN0IGNhc2VzLgorICAiIiIKKyAgZm9yIGlkeCwgZnVuYyBpbiBlbnVtZXJhdGUoaXRlcmF0b3IpOgorICAgIGFzc2VydCBjYWxsYWJsZShmdW5jKSwgJ1Rlc3QgZ2VuZXJhdG9ycyBtdXN0IHlpZWxkIGNhbGxhYmxlcywgZ290ICVyJyAlICgKKyAgICAgICAgZnVuYywpCisgICAgaWYgZ2V0YXR0cihmdW5jLCAnX194X3VzZV9uYW1lX18nLCBGYWxzZSk6CisgICAgICBuZXdfbmFtZSA9IGZ1bmMuX19uYW1lX18KKyAgICBlbHNlOgorICAgICAgbmV3X25hbWUgPSAnJXMlcyVkJyAlIChuYW1lLCBfU0VQQVJBVE9SLCBpZHgpCisgICAgYXNzZXJ0IG5ld19uYW1lIG5vdCBpbiBkY3QsICgKKyAgICAgICAgJ05hbWUgb2YgcGFyYW1ldGVyaXplZCB0ZXN0IGNhc2UgIiVzIiBub3QgdW5pcXVlJyAlIChuZXdfbmFtZSwpKQorICAgIGRjdFtuZXdfbmFtZV0gPSBmdW5jCisgICAgaWRfc3VmZml4W25ld19uYW1lXSA9IGdldGF0dHIoZnVuYywgJ19feF9leHRyYV9pZF9fJywgJycpCisKKworY2xhc3MgUGFyYW1ldGVyaXplZFRlc3RDYXNlKGJhc2V0ZXN0LlRlc3RDYXNlKToKKyAgIiIiQmFzZSBjbGFzcyBmb3IgdGVzdCBjYXNlcyB1c2luZyB0aGUgUGFyYW1ldGVycyBkZWNvcmF0b3IuIiIiCisgIF9fbWV0YWNsYXNzX18gPSBUZXN0R2VuZXJhdG9yTWV0YWNsYXNzCisKKyAgZGVmIF9PcmlnaW5hbE5hbWUoc2VsZik6CisgICAgcmV0dXJuIHNlbGYuX3Rlc3RNZXRob2ROYW1lLnNwbGl0KF9TRVBBUkFUT1IpWzBdCisKKyAgZGVmIF9fc3RyX18oc2VsZik6CisgICAgcmV0dXJuICclcyAoJXMpJyAlIChzZWxmLl9PcmlnaW5hbE5hbWUoKSwgX1N0ckNsYXNzKHNlbGYuX19jbGFzc19fKSkKKworICBkZWYgaWQoc2VsZik6ICAjIHB5bGludDogZGlzYWJsZT1pbnZhbGlkLW5hbWUKKyAgICAiIiJSZXR1cm5zIHRoZSBkZXNjcmlwdGl2ZSBJRCBvZiB0aGUgdGVzdC4KKworICAgIFRoaXMgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSB1bml0dGVzdGluZyBmcmFtZXdvcmsgdG8gZ2V0IGEgbmFtZQorICAgIGZvciB0aGUgdGVzdCB0byBiZSB1c2VkIGluIHJlcG9ydHMuCisKKyAgICBSZXR1cm5zOgorICAgICAgVGhlIHRlc3QgaWQuCisgICAgIiIiCisgICAgcmV0dXJuICclcy4lcyVzJyAlIChfU3RyQ2xhc3Moc2VsZi5fX2NsYXNzX18pLAorICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fT3JpZ2luYWxOYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9pZF9zdWZmaXguZ2V0KHNlbGYuX3Rlc3RNZXRob2ROYW1lLCAnJykpCisKKworZGVmIENvb3BQYXJhbWV0ZXJpemVkVGVzdENhc2Uob3RoZXJfYmFzZV9jbGFzcyk6CisgICIiIlJldHVybnMgYSBuZXcgYmFzZSBjbGFzcyB3aXRoIGEgY29vcGVyYXRpdmUgbWV0YWNsYXNzIGJhc2UuCisKKyAgVGhpcyBlbmFibGVzIHRoZSBQYXJhbWV0ZXJpemVkVGVzdENhc2UgdG8gYmUgdXNlZCBpbiBjb21iaW5hdGlvbgorICB3aXRoIG90aGVyIGJhc2UgY2xhc3NlcyB0aGF0IGhhdmUgY3VzdG9tIG1ldGFjbGFzc2VzLCBzdWNoIGFzCisgIG1veC5Nb3hUZXN0QmFzZS4KKworICBPbmx5IHdvcmtzIHdpdGggbWV0YWNsYXNzZXMgdGhhdCBkbyBub3Qgb3ZlcnJpZGUgdHlwZS5fX25ld19fLgorCisgIEV4YW1wbGU6CisKKyAgICBpbXBvcnQgZ29vZ2xlMworICAgIGltcG9ydCBtb3gKKworICAgIGZyb20gZ29vZ2xlMy50ZXN0aW5nLnB5YmFzZSBpbXBvcnQgcGFyYW1ldGVyaXplZAorCisgICAgY2xhc3MgRXhhbXBsZVRlc3QocGFyYW1ldGVyaXplZC5Db29wUGFyYW1ldGVyaXplZFRlc3RDYXNlKG1veC5Nb3hUZXN0QmFzZSkpOgorICAgICAgLi4uCisKKyAgQXJnczoKKyAgICBvdGhlcl9iYXNlX2NsYXNzOiAoY2xhc3MpIEEgdGVzdCBjYXNlIGJhc2UgY2xhc3MuCisKKyAgUmV0dXJuczoKKyAgICBBIG5ldyBjbGFzcyBvYmplY3QuCisgICIiIgorICBtZXRhY2xhc3MgPSB0eXBlKAorICAgICAgJ0Nvb3BNZXRhY2xhc3MnLAorICAgICAgKG90aGVyX2Jhc2VfY2xhc3MuX19tZXRhY2xhc3NfXywKKyAgICAgICBUZXN0R2VuZXJhdG9yTWV0YWNsYXNzKSwge30pCisgIHJldHVybiBtZXRhY2xhc3MoCisgICAgICAnQ29vcFBhcmFtZXRlcml6ZWRUZXN0Q2FzZScsCisgICAgICAob3RoZXJfYmFzZV9jbGFzcywgUGFyYW1ldGVyaXplZFRlc3RDYXNlKSwge30pCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2FwaV9pbXBsZW1lbnRhdGlvbi5jYyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvYXBpX2ltcGxlbWVudGF0aW9uLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkYjEyZTgKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2FwaV9pbXBsZW1lbnRhdGlvbi5jYwpAQCAtMCwwICsxLDEyOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxQeXRob24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHB5dGhvbiB7CisKKy8vIFZlcnNpb24gY29uc3RhbnQuCisvLyBUaGlzIGlzIGVpdGhlciAwIGZvciBweXRob24sIDEgZm9yIENQUCBWMSwgMiBmb3IgQ1BQIFYyLgorLy8KKy8vIDAgaXMgZGVmYXVsdCBhbmQgaXMgZXF1aXZhbGVudCB0bworLy8gICBQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTj1weXRob24KKy8vCisvLyAxIGlzIHNldCB3aXRoIC1EUFlUSE9OX1BST1RPMl9DUFBfSU1QTF9WMSBhbmQgaXMgZXF1aXZhbGVudCB0bworLy8gICBQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTj1jcHAKKy8vIGFuZAorLy8gICBQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTl9WRVJTSU9OPTEKKy8vCisvLyAyIGlzIHNldCB3aXRoIC1EUFlUSE9OX1BST1RPMl9DUFBfSU1QTF9WMiBhbmQgaXMgZXF1aXZhbGVudCB0bworLy8gICBQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTj1jcHAKKy8vIGFuZAorLy8gICBQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTl9WRVJTSU9OPTIKKyNpZmRlZiBQWVRIT05fUFJPVE8yX0NQUF9JTVBMX1YxCisjZXJyb3IgIlBZVEhPTl9QUk9UTzJfQ1BQX0lNUExfVjEgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC4iCisjZWxzZQorI2lmZGVmIFBZVEhPTl9QUk9UTzJfQ1BQX0lNUExfVjIKK3N0YXRpYyBpbnQga0ltcGxWZXJzaW9uID0gMjsKKyNlbHNlCisjaWZkZWYgUFlUSE9OX1BST1RPMl9QWVRIT05fSU1QTAorc3RhdGljIGludCBrSW1wbFZlcnNpb24gPSAwOworI2Vsc2UKKworc3RhdGljIGludCBrSW1wbFZlcnNpb24gPSAtMTsgIC8vIC0xIG1lYW5zICJVbnNwZWNpZmllZCBieSBjb21waWxlciBmbGFncyIuCisKKyNlbmRpZiAgLy8gUFlUSE9OX1BST1RPMl9QWVRIT05fSU1QTAorI2VuZGlmICAvLyBQWVRIT05fUFJPVE8yX0NQUF9JTVBMX1YyCisjZW5kaWYgIC8vIFBZVEhPTl9QUk9UTzJfQ1BQX0lNUExfVjEKKworc3RhdGljIGNvbnN0IGNoYXIqIGtJbXBsVmVyc2lvbk5hbWUgPSAiYXBpX3ZlcnNpb24iOworCitzdGF0aWMgY29uc3QgY2hhcioga01vZHVsZU5hbWUgPSAiX2FwaV9pbXBsZW1lbnRhdGlvbiI7CitzdGF0aWMgY29uc3QgY2hhciBrTW9kdWxlRG9jc3RyaW5nW10gPQorIl9hcGlfaW1wbGVtZW50YXRpb24gaXMgYSBtb2R1bGUgdGhhdCBleHBvc2VzIGNvbXBpbGUtdGltZSBjb25zdGFudHMgdGhhdFxuIgorImRldGVybWluZSB0aGUgZGVmYXVsdCBBUEkgaW1wbGVtZW50YXRpb24gdG8gdXNlIGZvciBQeXRob24gcHJvdG8yLlxuIgorIlxuIgorIkl0IGNvbXBsZW1lbnRzIGFwaV9pbXBsZW1lbnRhdGlvbi5weSBieSBzZXR0aW5nIGRlZmF1bHRzIHVzaW5nIGNvbXBpbGUtdGltZVxuIgorImNvbnN0YW50cyBkZWZpbmVkIGluIEMsIHN1Y2ggdGhhdCBvbmUgY2FuIHNldCBkZWZhdWx0cyBhdCBjb21waWxhdGlvblxuIgorIihlLmcuIHdpdGggYmxhemUgZmxhZyAtLWNvcHQ9LURQWVRIT05fUFJPVE8yX0NQUF9JTVBMX1YyKS4iOworCisjaWYgUFlfTUFKT1JfVkVSU0lPTiA+PSAzCitzdGF0aWMgc3RydWN0IFB5TW9kdWxlRGVmIF9tb2R1bGUgPSB7CisgIFB5TW9kdWxlRGVmX0hFQURfSU5JVCwKKyAga01vZHVsZU5hbWUsCisgIGtNb2R1bGVEb2NzdHJpbmcsCisgIC0xLAorICBOVUxMLAorICBOVUxMLAorICBOVUxMLAorICBOVUxMLAorICBOVUxMCit9OworI2RlZmluZSBJTklURlVOQyBQeUluaXRfX2FwaV9pbXBsZW1lbnRhdGlvbgorI2RlZmluZSBJTklURlVOQ19FUlJPUlZBTCBOVUxMCisjZWxzZQorI2RlZmluZSBJTklURlVOQyBpbml0X2FwaV9pbXBsZW1lbnRhdGlvbgorI2RlZmluZSBJTklURlVOQ19FUlJPUlZBTAorI2VuZGlmCisKK2V4dGVybiAiQyIgeworICBQeU1PRElOSVRfRlVOQyBJTklURlVOQygpIHsKKyNpZiBQWV9NQUpPUl9WRVJTSU9OID49IDMKKyAgICBQeU9iamVjdCAqbW9kdWxlID0gUHlNb2R1bGVfQ3JlYXRlKCZfbW9kdWxlKTsKKyNlbHNlCisgICAgUHlPYmplY3QgKm1vZHVsZSA9IFB5X0luaXRNb2R1bGUzKAorICAgICAgICBjb25zdF9jYXN0PGNoYXIqPihrTW9kdWxlTmFtZSksCisgICAgICAgIE5VTEwsCisgICAgICAgIGNvbnN0X2Nhc3Q8Y2hhcio+KGtNb2R1bGVEb2NzdHJpbmcpKTsKKyNlbmRpZgorICAgIGlmIChtb2R1bGUgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIElOSVRGVU5DX0VSUk9SVkFMOworICAgIH0KKworICAgIC8vIEFkZHMgdGhlIG1vZHVsZSB2YXJpYWJsZSAiYXBpX3ZlcnNpb24iLgorICAgIGlmIChQeU1vZHVsZV9BZGRJbnRDb25zdGFudCgKKyAgICAgICAgbW9kdWxlLAorICAgICAgICBjb25zdF9jYXN0PGNoYXIqPihrSW1wbFZlcnNpb25OYW1lKSwKKyAgICAgICAga0ltcGxWZXJzaW9uKSkKKyNpZiBQWV9NQUpPUl9WRVJTSU9OIDwgMworICAgICAgcmV0dXJuOworI2Vsc2UKKyAgICAgIHsgUHlfREVDUkVGKG1vZHVsZSk7IHJldHVybiBOVUxMOyB9CisKKyAgICByZXR1cm4gbW9kdWxlOworI2VuZGlmCisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHB5dGhvbgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2FwaV9pbXBsZW1lbnRhdGlvbi5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvYXBpX2ltcGxlbWVudGF0aW9uLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjhiYTQzNTcKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2FwaV9pbXBsZW1lbnRhdGlvbi5weQpAQCAtMCwwICsxLDEwNyBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJEZXRlcm1pbmUgd2hpY2ggaW1wbGVtZW50YXRpb24gb2YgdGhlIHByb3RvYnVmIEFQSSBpcyB1c2VkIGluIHRoaXMgcHJvY2Vzcy4KKyIiIgorCitpbXBvcnQgb3MKK2ltcG9ydCBzeXMKKwordHJ5OgorICAjIHB5bGludDogZGlzYWJsZT1nLWltcG9ydC1ub3QtYXQtdG9wCisgIGZyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBfYXBpX2ltcGxlbWVudGF0aW9uCisgICMgVGhlIGNvbXBpbGUtdGltZSBjb25zdGFudHMgaW4gdGhlIF9hcGlfaW1wbGVtZW50YXRpb24gbW9kdWxlIGNhbiBiZSB1c2VkIHRvCisgICMgc3dpdGNoIHRvIGEgY2VydGFpbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUHl0aG9uIEFQSSBhdCBidWlsZCB0aW1lLgorICBfYXBpX3ZlcnNpb24gPSBfYXBpX2ltcGxlbWVudGF0aW9uLmFwaV92ZXJzaW9uCisgIF9wcm90b19leHRlbnNpb25fbW9kdWxlc19leGlzdF9pbl9idWlsZCA9IFRydWUKK2V4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgX2FwaV92ZXJzaW9uID0gLTEgICMgVW5zcGVjaWZpZWQgYnkgY29tcGlsZXIgZmxhZ3MuCisgIF9wcm90b19leHRlbnNpb25fbW9kdWxlc19leGlzdF9pbl9idWlsZCA9IEZhbHNlCisKK2lmIF9hcGlfdmVyc2lvbiA9PSAxOgorICByYWlzZSBWYWx1ZUVycm9yKCdhcGlfdmVyc2lvbj0xIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuJykKK2lmIF9hcGlfdmVyc2lvbiA8IDA6ICAjIFN0aWxsIHVuc3BlY2lmaWVkPworICB0cnk6CisgICAgIyBUaGUgcHJlc2VuY2Ugb2YgdGhpcyBtb2R1bGUgaW4gYSBidWlsZCBhbGxvd3MgdGhlIHByb3RvIGltcGxlbWVudGF0aW9uIHRvCisgICAgIyBiZSB1cGdyYWRlZCBtZXJlbHkgdmlhIGJ1aWxkIGRlcHMgcmF0aGVyIHRoYW4gYSBjb21waWxlciBmbGFnIG9yIHRoZQorICAgICMgcnVudGltZSBlbnZpcm9ubWVudCB2YXJpYWJsZS4KKyAgICAjIHB5bGludDogZGlzYWJsZT1nLWltcG9ydC1ub3QtYXQtdG9wCisgICAgZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IF91c2VfZmFzdF9jcHBfcHJvdG9zCisgICAgIyBXb3JrIGFyb3VuZCBhIGtub3duIGlzc3VlIGluIHRoZSBjbGFzc2ljIGJvb3RzdHJhcCAucGFyIGltcG9ydCBob29rLgorICAgIGlmIG5vdCBfdXNlX2Zhc3RfY3BwX3Byb3RvczoKKyAgICAgIHJhaXNlIEltcG9ydEVycm9yKCdfdXNlX2Zhc3RfY3BwX3Byb3RvcyBpbXBvcnQgc3VjY2VlZGVkIGJ1dCB3YXMgTm9uZScpCisgICAgZGVsIF91c2VfZmFzdF9jcHBfcHJvdG9zCisgICAgX2FwaV92ZXJzaW9uID0gMgorICBleGNlcHQgSW1wb3J0RXJyb3I6CisgICAgaWYgX3Byb3RvX2V4dGVuc2lvbl9tb2R1bGVzX2V4aXN0X2luX2J1aWxkOgorICAgICAgaWYgc3lzLnZlcnNpb25faW5mb1swXSA+PSAzOiAgIyBQeXRob24gMyBkZWZhdWx0cyB0byBDKysgaW1wbCB2Mi4KKyAgICAgICAgX2FwaV92ZXJzaW9uID0gMgorICAgICAgIyBUT0RPKGIvMTc0Mjc0ODYpOiBNYWtlIFB5dGhvbiAyIGRlZmF1bHQgdG8gQysrIGltcGwgdjIuCisKK19kZWZhdWx0X2ltcGxlbWVudGF0aW9uX3R5cGUgPSAoCisgICAgJ3B5dGhvbicgaWYgX2FwaV92ZXJzaW9uIDw9IDAgZWxzZSAnY3BwJykKKworIyBUaGlzIGVudmlyb25tZW50IHZhcmlhYmxlIGNhbiBiZSB1c2VkIHRvIHN3aXRjaCB0byBhIGNlcnRhaW4gaW1wbGVtZW50YXRpb24KKyMgb2YgdGhlIFB5dGhvbiBBUEksIG92ZXJyaWRpbmcgdGhlIGNvbXBpbGUtdGltZSBjb25zdGFudHMgaW4gdGhlCisjIF9hcGlfaW1wbGVtZW50YXRpb24gbW9kdWxlLiBSaWdodCBub3cgb25seSAncHl0aG9uJyBhbmQgJ2NwcCcgYXJlIHZhbGlkCisjIHZhbHVlcy4gQW55IG90aGVyIHZhbHVlIHdpbGwgYmUgaWdub3JlZC4KK19pbXBsZW1lbnRhdGlvbl90eXBlID0gb3MuZ2V0ZW52KCdQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTicsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZGVmYXVsdF9pbXBsZW1lbnRhdGlvbl90eXBlKQorCitpZiBfaW1wbGVtZW50YXRpb25fdHlwZSAhPSAncHl0aG9uJzoKKyAgX2ltcGxlbWVudGF0aW9uX3R5cGUgPSAnY3BwJworCisjIFRoaXMgZW52aXJvbm1lbnQgdmFyaWFibGUgY2FuIGJlIHVzZWQgdG8gc3dpdGNoIGJldHdlZW4gdGhlIHR3bworIyAnY3BwJyBpbXBsZW1lbnRhdGlvbnMsIG92ZXJyaWRpbmcgdGhlIGNvbXBpbGUtdGltZSBjb25zdGFudHMgaW4gdGhlCisjIF9hcGlfaW1wbGVtZW50YXRpb24gbW9kdWxlLiBSaWdodCBub3cgb25seSAxIGFuZCAyIGFyZSB2YWxpZCB2YWx1ZXMuIEFueSBvdGhlcgorIyB2YWx1ZSB3aWxsIGJlIGlnbm9yZWQuCitfaW1wbGVtZW50YXRpb25fdmVyc2lvbl9zdHIgPSBvcy5nZXRlbnYoCisgICAgJ1BST1RPQ09MX0JVRkZFUlNfUFlUSE9OX0lNUExFTUVOVEFUSU9OX1ZFUlNJT04nLCAnMicpCisKK2lmIF9pbXBsZW1lbnRhdGlvbl92ZXJzaW9uX3N0ciAhPSAnMic6CisgIHJhaXNlIFZhbHVlRXJyb3IoCisgICAgICAndW5zdXBwb3J0ZWQgUFJPVE9DT0xfQlVGRkVSU19QWVRIT05fSU1QTEVNRU5UQVRJT05fVkVSU0lPTjogIicgKworICAgICAgX2ltcGxlbWVudGF0aW9uX3ZlcnNpb25fc3RyICsgJyIgKHN1cHBvcnRlZCB2ZXJzaW9uczogMiknCisgICAgICApCisKK19pbXBsZW1lbnRhdGlvbl92ZXJzaW9uID0gaW50KF9pbXBsZW1lbnRhdGlvbl92ZXJzaW9uX3N0cikKKworCisjIFVzYWdlIG9mIHRoaXMgZnVuY3Rpb24gaXMgZGlzY291cmFnZWQuIENsaWVudHMgc2hvdWxkbid0IGNhcmUgd2hpY2gKKyMgaW1wbGVtZW50YXRpb24gb2YgdGhlIEFQSSBpcyBpbiB1c2UuIE5vdGUgdGhhdCB0aGVyZSBpcyBubyBndWFyYW50ZWUKKyMgdGhhdCBkaWZmZXJlbmNlcyBiZXR3ZWVuIEFQSXMgd2lsbCBiZSBtYWludGFpbmVkLgorIyBQbGVhc2UgZG9uJ3QgdXNlIHRoaXMgZnVuY3Rpb24gaWYgcG9zc2libGUuCitkZWYgVHlwZSgpOgorICByZXR1cm4gX2ltcGxlbWVudGF0aW9uX3R5cGUKKworCisjIFNlZSBjb21tZW50IG9uICdUeXBlJyBhYm92ZS4KK2RlZiBWZXJzaW9uKCk6CisgIHJldHVybiBfaW1wbGVtZW50YXRpb25fdmVyc2lvbgpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9jb250YWluZXJzLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9jb250YWluZXJzLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmQ5NzZmOWUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2NvbnRhaW5lcnMucHkKQEAgLTAsMCArMSwyODggQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiQ29udGFpbnMgY29udGFpbmVyIGNsYXNzZXMgdG8gcmVwcmVzZW50IGRpZmZlcmVudCBwcm90b2NvbCBidWZmZXIgdHlwZXMuCisKK1RoaXMgZmlsZSBkZWZpbmVzIGNvbnRhaW5lciBjbGFzc2VzIHdoaWNoIHJlcHJlc2VudCBjYXRlZ29yaWVzIG9mIHByb3RvY29sCitidWZmZXIgZmllbGQgdHlwZXMgd2hpY2ggbmVlZCBleHRyYSBtYWludGVuYW5jZS4gQ3VycmVudGx5IHRoZXNlIGNhdGVnb3JpZXMKK2FyZToKKyAgLSBSZXBlYXRlZCBzY2FsYXIgZmllbGRzIC0gVGhlc2UgYXJlIGFsbCByZXBlYXRlZCBmaWVsZHMgd2hpY2ggYXJlbid0CisgICAgY29tcG9zaXRlIChlLmcuIHRoZXkgYXJlIG9mIHNpbXBsZSB0eXBlcyBsaWtlIGludDMyLCBzdHJpbmcsIGV0YykuCisgIC0gUmVwZWF0ZWQgY29tcG9zaXRlIGZpZWxkcyAtIFJlcGVhdGVkIGZpZWxkcyB3aGljaCBhcmUgY29tcG9zaXRlLiBUaGlzCisgICAgaW5jbHVkZXMgZ3JvdXBzIGFuZCBuZXN0ZWQgbWVzc2FnZXMuCisiIiIKKworX19hdXRob3JfXyA9ICdwZXRhckBnb29nbGUuY29tIChQZXRhciBQZXRyb3YpJworCitjbGFzcyBCYXNlQ29udGFpbmVyKG9iamVjdCk6CisKKyAgIiIiQmFzZSBjb250YWluZXIgY2xhc3MuIiIiCisKKyAgIyBNaW5pbWl6ZXMgbWVtb3J5IHVzYWdlIGFuZCBkaXNhbGxvd3MgYXNzaWdubWVudCB0byBvdGhlciBhdHRyaWJ1dGVzLgorICBfX3Nsb3RzX18gPSBbJ19tZXNzYWdlX2xpc3RlbmVyJywgJ192YWx1ZXMnXQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBtZXNzYWdlX2xpc3RlbmVyKToKKyAgICAiIiIKKyAgICBBcmdzOgorICAgICAgbWVzc2FnZV9saXN0ZW5lcjogQSBNZXNzYWdlTGlzdGVuZXIgaW1wbGVtZW50YXRpb24uCisgICAgICAgIFRoZSBSZXBlYXRlZFNjYWxhckZpZWxkQ29udGFpbmVyIHdpbGwgY2FsbCB0aGlzIG9iamVjdCdzCisgICAgICAgIE1vZGlmaWVkKCkgbWV0aG9kIHdoZW4gaXQgaXMgbW9kaWZpZWQuCisgICAgIiIiCisgICAgc2VsZi5fbWVzc2FnZV9saXN0ZW5lciA9IG1lc3NhZ2VfbGlzdGVuZXIKKyAgICBzZWxmLl92YWx1ZXMgPSBbXQorCisgIGRlZiBfX2dldGl0ZW1fXyhzZWxmLCBrZXkpOgorICAgICIiIlJldHJpZXZlcyBpdGVtIGJ5IHRoZSBzcGVjaWZpZWQga2V5LiIiIgorICAgIHJldHVybiBzZWxmLl92YWx1ZXNba2V5XQorCisgIGRlZiBfX2xlbl9fKHNlbGYpOgorICAgICIiIlJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgY29udGFpbmVyLiIiIgorICAgIHJldHVybiBsZW4oc2VsZi5fdmFsdWVzKQorCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgICIiIkNoZWNrcyBpZiBhbm90aGVyIGluc3RhbmNlIGlzbid0IGVxdWFsIHRvIHRoaXMgb25lLiIiIgorICAgICMgVGhlIGNvbmNyZXRlIGNsYXNzZXMgc2hvdWxkIGRlZmluZSBfX2VxX18uCisgICAgcmV0dXJuIG5vdCBzZWxmID09IG90aGVyCisKKyAgZGVmIF9faGFzaF9fKHNlbGYpOgorICAgIHJhaXNlIFR5cGVFcnJvcigndW5oYXNoYWJsZSBvYmplY3QnKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKToKKyAgICByZXR1cm4gcmVwcihzZWxmLl92YWx1ZXMpCisKKyAgZGVmIHNvcnQoc2VsZiwgKmFyZ3MsICoqa3dhcmdzKToKKyAgICAjIENvbnRpbnVlIHRvIHN1cHBvcnQgdGhlIG9sZCBzb3J0X2Z1bmN0aW9uIGtleXdvcmQgYXJndW1lbnQuCisgICAgIyBUaGlzIGlzIGV4cGVjdGVkIHRvIGJlIGEgcmFyZSBvY2N1cnJlbmNlLCBzbyB1c2UgTEJZTCB0byBhdm9pZAorICAgICMgdGhlIG92ZXJoZWFkIG9mIGFjdHVhbGx5IGNhdGNoaW5nIEtleUVycm9yLgorICAgIGlmICdzb3J0X2Z1bmN0aW9uJyBpbiBrd2FyZ3M6CisgICAgICBrd2FyZ3NbJ2NtcCddID0ga3dhcmdzLnBvcCgnc29ydF9mdW5jdGlvbicpCisgICAgc2VsZi5fdmFsdWVzLnNvcnQoKmFyZ3MsICoqa3dhcmdzKQorCisKK2NsYXNzIFJlcGVhdGVkU2NhbGFyRmllbGRDb250YWluZXIoQmFzZUNvbnRhaW5lcik6CisKKyAgIiIiU2ltcGxlLCB0eXBlLWNoZWNrZWQsIGxpc3QtbGlrZSBjb250YWluZXIgZm9yIGhvbGRpbmcgcmVwZWF0ZWQgc2NhbGFycy4iIiIKKworICAjIERpc2FsbG93cyBhc3NpZ25tZW50IHRvIG90aGVyIGF0dHJpYnV0ZXMuCisgIF9fc2xvdHNfXyA9IFsnX3R5cGVfY2hlY2tlciddCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG1lc3NhZ2VfbGlzdGVuZXIsIHR5cGVfY2hlY2tlcik6CisgICAgIiIiCisgICAgQXJnczoKKyAgICAgIG1lc3NhZ2VfbGlzdGVuZXI6IEEgTWVzc2FnZUxpc3RlbmVyIGltcGxlbWVudGF0aW9uLgorICAgICAgICBUaGUgUmVwZWF0ZWRTY2FsYXJGaWVsZENvbnRhaW5lciB3aWxsIGNhbGwgdGhpcyBvYmplY3QncworICAgICAgICBNb2RpZmllZCgpIG1ldGhvZCB3aGVuIGl0IGlzIG1vZGlmaWVkLgorICAgICAgdHlwZV9jaGVja2VyOiBBIHR5cGVfY2hlY2tlcnMuVmFsdWVDaGVja2VyIGluc3RhbmNlIHRvIHJ1biBvbiBlbGVtZW50cworICAgICAgICBpbnNlcnRlZCBpbnRvIHRoaXMgY29udGFpbmVyLgorICAgICIiIgorICAgIHN1cGVyKFJlcGVhdGVkU2NhbGFyRmllbGRDb250YWluZXIsIHNlbGYpLl9faW5pdF9fKG1lc3NhZ2VfbGlzdGVuZXIpCisgICAgc2VsZi5fdHlwZV9jaGVja2VyID0gdHlwZV9jaGVja2VyCisKKyAgZGVmIGFwcGVuZChzZWxmLCB2YWx1ZSk6CisgICAgIiIiQXBwZW5kcyBhbiBpdGVtIHRvIHRoZSBsaXN0LiBTaW1pbGFyIHRvIGxpc3QuYXBwZW5kKCkuIiIiCisgICAgc2VsZi5fdmFsdWVzLmFwcGVuZChzZWxmLl90eXBlX2NoZWNrZXIuQ2hlY2tWYWx1ZSh2YWx1ZSkpCisgICAgaWYgbm90IHNlbGYuX21lc3NhZ2VfbGlzdGVuZXIuZGlydHk6CisgICAgICBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyLk1vZGlmaWVkKCkKKworICBkZWYgaW5zZXJ0KHNlbGYsIGtleSwgdmFsdWUpOgorICAgICIiIkluc2VydHMgdGhlIGl0ZW0gYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbi4gU2ltaWxhciB0byBsaXN0Lmluc2VydCgpLiIiIgorICAgIHNlbGYuX3ZhbHVlcy5pbnNlcnQoa2V5LCBzZWxmLl90eXBlX2NoZWNrZXIuQ2hlY2tWYWx1ZSh2YWx1ZSkpCisgICAgaWYgbm90IHNlbGYuX21lc3NhZ2VfbGlzdGVuZXIuZGlydHk6CisgICAgICBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyLk1vZGlmaWVkKCkKKworICBkZWYgZXh0ZW5kKHNlbGYsIGVsZW1fc2VxKToKKyAgICAiIiJFeHRlbmRzIGJ5IGFwcGVuZGluZyB0aGUgZ2l2ZW4gaXRlcmFibGUuIFNpbWlsYXIgdG8gbGlzdC5leHRlbmQoKS4iIiIKKworICAgIGlmIGVsZW1fc2VxIGlzIE5vbmU6CisgICAgICByZXR1cm4KKyAgICB0cnk6CisgICAgICBlbGVtX3NlcV9pdGVyID0gaXRlcihlbGVtX3NlcSkKKyAgICBleGNlcHQgVHlwZUVycm9yOgorICAgICAgaWYgbm90IGVsZW1fc2VxOgorICAgICAgICAjIHNpbGVudGx5IGlnbm9yZSBmYWxzeSBpbnB1dHMgOi0vLgorICAgICAgICAjIFRPRE8ocHR1Y2tlcik6IERlcHJlY2F0ZSB0aGlzIGJlaGF2aW9yLiBiLzE4NDEzODYyCisgICAgICAgIHJldHVybgorICAgICAgcmFpc2UKKworICAgIG5ld192YWx1ZXMgPSBbc2VsZi5fdHlwZV9jaGVja2VyLkNoZWNrVmFsdWUoZWxlbSkgZm9yIGVsZW0gaW4gZWxlbV9zZXFfaXRlcl0KKyAgICBpZiBuZXdfdmFsdWVzOgorICAgICAgc2VsZi5fdmFsdWVzLmV4dGVuZChuZXdfdmFsdWVzKQorICAgICAgc2VsZi5fbWVzc2FnZV9saXN0ZW5lci5Nb2RpZmllZCgpCisKKyAgZGVmIE1lcmdlRnJvbShzZWxmLCBvdGhlcik6CisgICAgIiIiQXBwZW5kcyB0aGUgY29udGVudHMgb2YgYW5vdGhlciByZXBlYXRlZCBmaWVsZCBvZiB0aGUgc2FtZSB0eXBlIHRvIHRoaXMKKyAgICBvbmUuIFdlIGRvIG5vdCBjaGVjayB0aGUgdHlwZXMgb2YgdGhlIGluZGl2aWR1YWwgZmllbGRzLgorICAgICIiIgorICAgIHNlbGYuX3ZhbHVlcy5leHRlbmQob3RoZXIuX3ZhbHVlcykKKyAgICBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyLk1vZGlmaWVkKCkKKworICBkZWYgcmVtb3ZlKHNlbGYsIGVsZW0pOgorICAgICIiIlJlbW92ZXMgYW4gaXRlbSBmcm9tIHRoZSBsaXN0LiBTaW1pbGFyIHRvIGxpc3QucmVtb3ZlKCkuIiIiCisgICAgc2VsZi5fdmFsdWVzLnJlbW92ZShlbGVtKQorICAgIHNlbGYuX21lc3NhZ2VfbGlzdGVuZXIuTW9kaWZpZWQoKQorCisgIGRlZiBwb3Aoc2VsZiwga2V5PS0xKToKKyAgICAiIiJSZW1vdmVzIGFuZCByZXR1cm5zIGFuIGl0ZW0gYXQgYSBnaXZlbiBpbmRleC4gU2ltaWxhciB0byBsaXN0LnBvcCgpLiIiIgorICAgIHZhbHVlID0gc2VsZi5fdmFsdWVzW2tleV0KKyAgICBzZWxmLl9fZGVsaXRlbV9fKGtleSkKKyAgICByZXR1cm4gdmFsdWUKKworICBkZWYgX19zZXRpdGVtX18oc2VsZiwga2V5LCB2YWx1ZSk6CisgICAgIiIiU2V0cyB0aGUgaXRlbSBvbiB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLiIiIgorICAgIGlmIGlzaW5zdGFuY2Uoa2V5LCBzbGljZSk6ICAjIFBZMworICAgICAgaWYga2V5LnN0ZXAgaXMgbm90IE5vbmU6CisgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ0V4dGVuZGVkIHNsaWNlcyBub3Qgc3VwcG9ydGVkJykKKyAgICAgIHNlbGYuX19zZXRzbGljZV9fKGtleS5zdGFydCwga2V5LnN0b3AsIHZhbHVlKQorICAgIGVsc2U6CisgICAgICBzZWxmLl92YWx1ZXNba2V5XSA9IHNlbGYuX3R5cGVfY2hlY2tlci5DaGVja1ZhbHVlKHZhbHVlKQorICAgICAgc2VsZi5fbWVzc2FnZV9saXN0ZW5lci5Nb2RpZmllZCgpCisKKyAgZGVmIF9fZ2V0c2xpY2VfXyhzZWxmLCBzdGFydCwgc3RvcCk6CisgICAgIiIiUmV0cmlldmVzIHRoZSBzdWJzZXQgb2YgaXRlbXMgZnJvbSBiZXR3ZWVuIHRoZSBzcGVjaWZpZWQgaW5kaWNlcy4iIiIKKyAgICByZXR1cm4gc2VsZi5fdmFsdWVzW3N0YXJ0OnN0b3BdCisKKyAgZGVmIF9fc2V0c2xpY2VfXyhzZWxmLCBzdGFydCwgc3RvcCwgdmFsdWVzKToKKyAgICAiIiJTZXRzIHRoZSBzdWJzZXQgb2YgaXRlbXMgZnJvbSBiZXR3ZWVuIHRoZSBzcGVjaWZpZWQgaW5kaWNlcy4iIiIKKyAgICBuZXdfdmFsdWVzID0gW10KKyAgICBmb3IgdmFsdWUgaW4gdmFsdWVzOgorICAgICAgbmV3X3ZhbHVlcy5hcHBlbmQoc2VsZi5fdHlwZV9jaGVja2VyLkNoZWNrVmFsdWUodmFsdWUpKQorICAgIHNlbGYuX3ZhbHVlc1tzdGFydDpzdG9wXSA9IG5ld192YWx1ZXMKKyAgICBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyLk1vZGlmaWVkKCkKKworICBkZWYgX19kZWxpdGVtX18oc2VsZiwga2V5KToKKyAgICAiIiJEZWxldGVzIHRoZSBpdGVtIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uIiIiCisgICAgZGVsIHNlbGYuX3ZhbHVlc1trZXldCisgICAgc2VsZi5fbWVzc2FnZV9saXN0ZW5lci5Nb2RpZmllZCgpCisKKyAgZGVmIF9fZGVsc2xpY2VfXyhzZWxmLCBzdGFydCwgc3RvcCk6CisgICAgIiIiRGVsZXRlcyB0aGUgc3Vic2V0IG9mIGl0ZW1zIGZyb20gYmV0d2VlbiB0aGUgc3BlY2lmaWVkIGluZGljZXMuIiIiCisgICAgZGVsIHNlbGYuX3ZhbHVlc1tzdGFydDpzdG9wXQorICAgIHNlbGYuX21lc3NhZ2VfbGlzdGVuZXIuTW9kaWZpZWQoKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgICIiIkNvbXBhcmVzIHRoZSBjdXJyZW50IGluc3RhbmNlIHdpdGggYW5vdGhlciBvbmUuIiIiCisgICAgaWYgc2VsZiBpcyBvdGhlcjoKKyAgICAgIHJldHVybiBUcnVlCisgICAgIyBTcGVjaWFsIGNhc2UgZm9yIHRoZSBzYW1lIHR5cGUgd2hpY2ggc2hvdWxkIGJlIGNvbW1vbiBhbmQgZmFzdC4KKyAgICBpZiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXyk6CisgICAgICByZXR1cm4gb3RoZXIuX3ZhbHVlcyA9PSBzZWxmLl92YWx1ZXMKKyAgICAjIFdlIGFyZSBwcmVzdW1hYmx5IGNvbXBhcmluZyBhZ2FpbnN0IHNvbWUgb3RoZXIgc2VxdWVuY2UgdHlwZS4KKyAgICByZXR1cm4gb3RoZXIgPT0gc2VsZi5fdmFsdWVzCisKKworY2xhc3MgUmVwZWF0ZWRDb21wb3NpdGVGaWVsZENvbnRhaW5lcihCYXNlQ29udGFpbmVyKToKKworICAiIiJTaW1wbGUsIGxpc3QtbGlrZSBjb250YWluZXIgZm9yIGhvbGRpbmcgcmVwZWF0ZWQgY29tcG9zaXRlIGZpZWxkcy4iIiIKKworICAjIERpc2FsbG93cyBhc3NpZ25tZW50IHRvIG90aGVyIGF0dHJpYnV0ZXMuCisgIF9fc2xvdHNfXyA9IFsnX21lc3NhZ2VfZGVzY3JpcHRvciddCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG1lc3NhZ2VfbGlzdGVuZXIsIG1lc3NhZ2VfZGVzY3JpcHRvcik6CisgICAgIiIiCisgICAgTm90ZSB0aGF0IHdlIHBhc3MgaW4gYSBkZXNjcmlwdG9yIGluc3RlYWQgb2YgdGhlIGdlbmVyYXRlZCBkaXJlY3RseSwKKyAgICBzaW5jZSBhdCB0aGUgdGltZSB3ZSBjb25zdHJ1Y3QgYSBfUmVwZWF0ZWRDb21wb3NpdGVGaWVsZENvbnRhaW5lciB3ZQorICAgIGhhdmVuJ3QgeWV0IG5lY2Vzc2FyaWx5IGluaXRpYWxpemVkIHRoZSB0eXBlIHRoYXQgd2lsbCBiZSBjb250YWluZWQgaW4gdGhlCisgICAgY29udGFpbmVyLgorCisgICAgQXJnczoKKyAgICAgIG1lc3NhZ2VfbGlzdGVuZXI6IEEgTWVzc2FnZUxpc3RlbmVyIGltcGxlbWVudGF0aW9uLgorICAgICAgICBUaGUgUmVwZWF0ZWRDb21wb3NpdGVGaWVsZENvbnRhaW5lciB3aWxsIGNhbGwgdGhpcyBvYmplY3QncworICAgICAgICBNb2RpZmllZCgpIG1ldGhvZCB3aGVuIGl0IGlzIG1vZGlmaWVkLgorICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yOiBBIERlc2NyaXB0b3IgaW5zdGFuY2UgZGVzY3JpYmluZyB0aGUgcHJvdG9jb2wgdHlwZQorICAgICAgICB0aGF0IHNob3VsZCBiZSBwcmVzZW50IGluIHRoaXMgY29udGFpbmVyLiAgV2UnbGwgdXNlIHRoZQorICAgICAgICBfY29uY3JldGVfY2xhc3MgZmllbGQgb2YgdGhpcyBkZXNjcmlwdG9yIHdoZW4gdGhlIGNsaWVudCBjYWxscyBhZGQoKS4KKyAgICAiIiIKKyAgICBzdXBlcihSZXBlYXRlZENvbXBvc2l0ZUZpZWxkQ29udGFpbmVyLCBzZWxmKS5fX2luaXRfXyhtZXNzYWdlX2xpc3RlbmVyKQorICAgIHNlbGYuX21lc3NhZ2VfZGVzY3JpcHRvciA9IG1lc3NhZ2VfZGVzY3JpcHRvcgorCisgIGRlZiBhZGQoc2VsZiwgKiprd2FyZ3MpOgorICAgICIiIkFkZHMgYSBuZXcgZWxlbWVudCBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0IGFuZCByZXR1cm5zIGl0LiBLZXl3b3JkCisgICAgYXJndW1lbnRzIG1heSBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhlIGVsZW1lbnQuCisgICAgIiIiCisgICAgbmV3X2VsZW1lbnQgPSBzZWxmLl9tZXNzYWdlX2Rlc2NyaXB0b3IuX2NvbmNyZXRlX2NsYXNzKCoqa3dhcmdzKQorICAgIG5ld19lbGVtZW50Ll9TZXRMaXN0ZW5lcihzZWxmLl9tZXNzYWdlX2xpc3RlbmVyKQorICAgIHNlbGYuX3ZhbHVlcy5hcHBlbmQobmV3X2VsZW1lbnQpCisgICAgaWYgbm90IHNlbGYuX21lc3NhZ2VfbGlzdGVuZXIuZGlydHk6CisgICAgICBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyLk1vZGlmaWVkKCkKKyAgICByZXR1cm4gbmV3X2VsZW1lbnQKKworICBkZWYgZXh0ZW5kKHNlbGYsIGVsZW1fc2VxKToKKyAgICAiIiJFeHRlbmRzIGJ5IGFwcGVuZGluZyB0aGUgZ2l2ZW4gc2VxdWVuY2Ugb2YgZWxlbWVudHMgb2YgdGhlIHNhbWUgdHlwZQorICAgIGFzIHRoaXMgb25lLCBjb3B5aW5nIGVhY2ggaW5kaXZpZHVhbCBtZXNzYWdlLgorICAgICIiIgorICAgIG1lc3NhZ2VfY2xhc3MgPSBzZWxmLl9tZXNzYWdlX2Rlc2NyaXB0b3IuX2NvbmNyZXRlX2NsYXNzCisgICAgbGlzdGVuZXIgPSBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyCisgICAgdmFsdWVzID0gc2VsZi5fdmFsdWVzCisgICAgZm9yIG1lc3NhZ2UgaW4gZWxlbV9zZXE6CisgICAgICBuZXdfZWxlbWVudCA9IG1lc3NhZ2VfY2xhc3MoKQorICAgICAgbmV3X2VsZW1lbnQuX1NldExpc3RlbmVyKGxpc3RlbmVyKQorICAgICAgbmV3X2VsZW1lbnQuTWVyZ2VGcm9tKG1lc3NhZ2UpCisgICAgICB2YWx1ZXMuYXBwZW5kKG5ld19lbGVtZW50KQorICAgIGxpc3RlbmVyLk1vZGlmaWVkKCkKKworICBkZWYgTWVyZ2VGcm9tKHNlbGYsIG90aGVyKToKKyAgICAiIiJBcHBlbmRzIHRoZSBjb250ZW50cyBvZiBhbm90aGVyIHJlcGVhdGVkIGZpZWxkIG9mIHRoZSBzYW1lIHR5cGUgdG8gdGhpcworICAgIG9uZSwgY29weWluZyBlYWNoIGluZGl2aWR1YWwgbWVzc2FnZS4KKyAgICAiIiIKKyAgICBzZWxmLmV4dGVuZChvdGhlci5fdmFsdWVzKQorCisgIGRlZiByZW1vdmUoc2VsZiwgZWxlbSk6CisgICAgIiIiUmVtb3ZlcyBhbiBpdGVtIGZyb20gdGhlIGxpc3QuIFNpbWlsYXIgdG8gbGlzdC5yZW1vdmUoKS4iIiIKKyAgICBzZWxmLl92YWx1ZXMucmVtb3ZlKGVsZW0pCisgICAgc2VsZi5fbWVzc2FnZV9saXN0ZW5lci5Nb2RpZmllZCgpCisKKyAgZGVmIHBvcChzZWxmLCBrZXk9LTEpOgorICAgICIiIlJlbW92ZXMgYW5kIHJldHVybnMgYW4gaXRlbSBhdCBhIGdpdmVuIGluZGV4LiBTaW1pbGFyIHRvIGxpc3QucG9wKCkuIiIiCisgICAgdmFsdWUgPSBzZWxmLl92YWx1ZXNba2V5XQorICAgIHNlbGYuX19kZWxpdGVtX18oa2V5KQorICAgIHJldHVybiB2YWx1ZQorCisgIGRlZiBfX2dldHNsaWNlX18oc2VsZiwgc3RhcnQsIHN0b3ApOgorICAgICIiIlJldHJpZXZlcyB0aGUgc3Vic2V0IG9mIGl0ZW1zIGZyb20gYmV0d2VlbiB0aGUgc3BlY2lmaWVkIGluZGljZXMuIiIiCisgICAgcmV0dXJuIHNlbGYuX3ZhbHVlc1tzdGFydDpzdG9wXQorCisgIGRlZiBfX2RlbGl0ZW1fXyhzZWxmLCBrZXkpOgorICAgICIiIkRlbGV0ZXMgdGhlIGl0ZW0gYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbi4iIiIKKyAgICBkZWwgc2VsZi5fdmFsdWVzW2tleV0KKyAgICBzZWxmLl9tZXNzYWdlX2xpc3RlbmVyLk1vZGlmaWVkKCkKKworICBkZWYgX19kZWxzbGljZV9fKHNlbGYsIHN0YXJ0LCBzdG9wKToKKyAgICAiIiJEZWxldGVzIHRoZSBzdWJzZXQgb2YgaXRlbXMgZnJvbSBiZXR3ZWVuIHRoZSBzcGVjaWZpZWQgaW5kaWNlcy4iIiIKKyAgICBkZWwgc2VsZi5fdmFsdWVzW3N0YXJ0OnN0b3BdCisgICAgc2VsZi5fbWVzc2FnZV9saXN0ZW5lci5Nb2RpZmllZCgpCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgIiIiQ29tcGFyZXMgdGhlIGN1cnJlbnQgaW5zdGFuY2Ugd2l0aCBhbm90aGVyIG9uZS4iIiIKKyAgICBpZiBzZWxmIGlzIG90aGVyOgorICAgICAgcmV0dXJuIFRydWUKKyAgICBpZiBub3QgaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pOgorICAgICAgcmFpc2UgVHlwZUVycm9yKCdDYW4gb25seSBjb21wYXJlIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZHMgYWdhaW5zdCAnCisgICAgICAgICAgICAgICAgICAgICAgJ290aGVyIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZHMuJykKKyAgICByZXR1cm4gc2VsZi5fdmFsdWVzID09IG90aGVyLl92YWx1ZXMKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvY3BwX21lc3NhZ2UucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2NwcF9tZXNzYWdlLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjAzMTNjYjAKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2NwcF9tZXNzYWdlLnB5CkBAIC0wLDAgKzEsNjYzIEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyIiIkNvbnRhaW5zIGhlbHBlciBmdW5jdGlvbnMgdXNlZCB0byBjcmVhdGUgcHJvdG9jb2wgbWVzc2FnZSBjbGFzc2VzIGZyb20KK0Rlc2NyaXB0b3Igb2JqZWN0cyBhdCBydW50aW1lIGJhY2tlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIEMrKyBBUEkuCisiIiIKKworX19hdXRob3JfXyA9ICdwZXRhckBnb29nbGUuY29tIChQZXRhciBQZXRyb3YpJworCitpbXBvcnQgY29weV9yZWcKK2ltcG9ydCBvcGVyYXRvcgorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IF9uZXRfcHJvdG8yX19fcHl0aG9uCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgZW51bV90eXBlX3dyYXBwZXIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBtZXNzYWdlCisKKworX0xBQkVMX1JFUEVBVEVEID0gX25ldF9wcm90bzJfX19weXRob24uTEFCRUxfUkVQRUFURUQKK19MQUJFTF9PUFRJT05BTCA9IF9uZXRfcHJvdG8yX19fcHl0aG9uLkxBQkVMX09QVElPTkFMCitfQ1BQVFlQRV9NRVNTQUdFID0gX25ldF9wcm90bzJfX19weXRob24uQ1BQVFlQRV9NRVNTQUdFCitfVFlQRV9NRVNTQUdFID0gX25ldF9wcm90bzJfX19weXRob24uVFlQRV9NRVNTQUdFCisKKworZGVmIEdldERlc2NyaXB0b3JQb29sKCk6CisgICIiIkNyZWF0ZXMgYSBuZXcgRGVzY3JpcHRvclBvb2wgQysrIG9iamVjdC4iIiIKKyAgcmV0dXJuIF9uZXRfcHJvdG8yX19fcHl0aG9uLk5ld0NEZXNjcmlwdG9yUG9vbCgpCisKKworX3Bvb2wgPSBHZXREZXNjcmlwdG9yUG9vbCgpCisKKworZGVmIEdldEZpZWxkRGVzY3JpcHRvcihmdWxsX2ZpZWxkX25hbWUpOgorICAiIiJTZWFyY2hlcyBmb3IgYSBmaWVsZCBkZXNjcmlwdG9yIGdpdmVuIGEgZnVsbCBmaWVsZCBuYW1lLiIiIgorICByZXR1cm4gX3Bvb2wuRmluZEZpZWxkQnlOYW1lKGZ1bGxfZmllbGRfbmFtZSkKKworCitkZWYgQnVpbGRGaWxlKGNvbnRlbnQpOgorICAiIiJSZWdpc3RlcnMgYSBuZXcgcHJvdG8gZmlsZSBpbiB0aGUgdW5kZXJseWluZyBDKysgZGVzY3JpcHRvciBwb29sLiIiIgorICBfbmV0X3Byb3RvMl9fX3B5dGhvbi5CdWlsZEZpbGUoY29udGVudCkKKworCitkZWYgR2V0RXh0ZW5zaW9uRGVzY3JpcHRvcihmdWxsX2V4dGVuc2lvbl9uYW1lKToKKyAgIiIiU2VhcmNoZXMgZm9yIGV4dGVuc2lvbiBkZXNjcmlwdG9yIGdpdmVuIGEgZnVsbCBmaWVsZCBuYW1lLiIiIgorICByZXR1cm4gX3Bvb2wuRmluZEV4dGVuc2lvbkJ5TmFtZShmdWxsX2V4dGVuc2lvbl9uYW1lKQorCisKK2RlZiBOZXdDTWVzc2FnZShmdWxsX21lc3NhZ2VfbmFtZSk6CisgICIiIkNyZWF0ZXMgYSBuZXcgQysrIHByb3RvY29sIG1lc3NhZ2UgYnkgaXRzIG5hbWUuIiIiCisgIHJldHVybiBfbmV0X3Byb3RvMl9fX3B5dGhvbi5OZXdDTWVzc2FnZShmdWxsX21lc3NhZ2VfbmFtZSkKKworCitkZWYgU2NhbGFyUHJvcGVydHkoY2Rlc2NyaXB0b3IpOgorICAiIiJSZXR1cm5zIGEgc2NhbGFyIHByb3BlcnR5IGZvciB0aGUgZ2l2ZW4gZGVzY3JpcHRvci4iIiIKKworICBkZWYgR2V0dGVyKHNlbGYpOgorICAgIHJldHVybiBzZWxmLl9jbXNnLkdldFNjYWxhcihjZGVzY3JpcHRvcikKKworICBkZWYgU2V0dGVyKHNlbGYsIHZhbHVlKToKKyAgICBzZWxmLl9jbXNnLlNldFNjYWxhcihjZGVzY3JpcHRvciwgdmFsdWUpCisKKyAgcmV0dXJuIHByb3BlcnR5KEdldHRlciwgU2V0dGVyKQorCisKK2RlZiBDb21wb3NpdGVQcm9wZXJ0eShjZGVzY3JpcHRvciwgbWVzc2FnZV90eXBlKToKKyAgIiIiUmV0dXJucyBhIFB5dGhvbiBwcm9wZXJ0eSB0aGUgZ2l2ZW4gY29tcG9zaXRlIGZpZWxkLiIiIgorCisgIGRlZiBHZXR0ZXIoc2VsZik6CisgICAgc3ViX21lc3NhZ2UgPSBzZWxmLl9jb21wb3NpdGVfZmllbGRzLmdldChjZGVzY3JpcHRvci5uYW1lLCBOb25lKQorICAgIGlmIHN1Yl9tZXNzYWdlIGlzIE5vbmU6CisgICAgICBjbWVzc2FnZSA9IHNlbGYuX2Ntc2cuTmV3U3ViTWVzc2FnZShjZGVzY3JpcHRvcikKKyAgICAgIHN1Yl9tZXNzYWdlID0gbWVzc2FnZV90eXBlLl9jb25jcmV0ZV9jbGFzcyhfX2NtZXNzYWdlPWNtZXNzYWdlKQorICAgICAgc2VsZi5fY29tcG9zaXRlX2ZpZWxkc1tjZGVzY3JpcHRvci5uYW1lXSA9IHN1Yl9tZXNzYWdlCisgICAgcmV0dXJuIHN1Yl9tZXNzYWdlCisKKyAgcmV0dXJuIHByb3BlcnR5KEdldHRlcikKKworCitjbGFzcyBSZXBlYXRlZFNjYWxhckNvbnRhaW5lcihvYmplY3QpOgorICAiIiJDb250YWluZXIgZm9yIHJlcGVhdGVkIHNjYWxhciBmaWVsZHMuIiIiCisKKyAgX19zbG90c19fID0gWydfbWVzc2FnZScsICdfY2ZpZWxkX2Rlc2NyaXB0b3InLCAnX2Ntc2cnXQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBtc2csIGNmaWVsZF9kZXNjcmlwdG9yKToKKyAgICBzZWxmLl9tZXNzYWdlID0gbXNnCisgICAgc2VsZi5fY21zZyA9IG1zZy5fY21zZworICAgIHNlbGYuX2NmaWVsZF9kZXNjcmlwdG9yID0gY2ZpZWxkX2Rlc2NyaXB0b3IKKworICBkZWYgYXBwZW5kKHNlbGYsIHZhbHVlKToKKyAgICBzZWxmLl9jbXNnLkFkZFJlcGVhdGVkU2NhbGFyKAorICAgICAgICBzZWxmLl9jZmllbGRfZGVzY3JpcHRvciwgdmFsdWUpCisKKyAgZGVmIGV4dGVuZChzZWxmLCBzZXF1ZW5jZSk6CisgICAgZm9yIGVsZW1lbnQgaW4gc2VxdWVuY2U6CisgICAgICBzZWxmLmFwcGVuZChlbGVtZW50KQorCisgIGRlZiBpbnNlcnQoc2VsZiwga2V5LCB2YWx1ZSk6CisgICAgdmFsdWVzID0gc2VsZltzbGljZShOb25lLCBOb25lLCBOb25lKV0KKyAgICB2YWx1ZXMuaW5zZXJ0KGtleSwgdmFsdWUpCisgICAgc2VsZi5fY21zZy5Bc3NpZ25SZXBlYXRlZFNjYWxhcihzZWxmLl9jZmllbGRfZGVzY3JpcHRvciwgdmFsdWVzKQorCisgIGRlZiByZW1vdmUoc2VsZiwgdmFsdWUpOgorICAgIHZhbHVlcyA9IHNlbGZbc2xpY2UoTm9uZSwgTm9uZSwgTm9uZSldCisgICAgdmFsdWVzLnJlbW92ZSh2YWx1ZSkKKyAgICBzZWxmLl9jbXNnLkFzc2lnblJlcGVhdGVkU2NhbGFyKHNlbGYuX2NmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZXMpCisKKyAgZGVmIF9fc2V0aXRlbV9fKHNlbGYsIGtleSwgdmFsdWUpOgorICAgIHZhbHVlcyA9IHNlbGZbc2xpY2UoTm9uZSwgTm9uZSwgTm9uZSldCisgICAgdmFsdWVzW2tleV0gPSB2YWx1ZQorICAgIHNlbGYuX2Ntc2cuQXNzaWduUmVwZWF0ZWRTY2FsYXIoc2VsZi5fY2ZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlcykKKworICBkZWYgX19nZXRpdGVtX18oc2VsZiwga2V5KToKKyAgICByZXR1cm4gc2VsZi5fY21zZy5HZXRSZXBlYXRlZFNjYWxhcihzZWxmLl9jZmllbGRfZGVzY3JpcHRvciwga2V5KQorCisgIGRlZiBfX2RlbGl0ZW1fXyhzZWxmLCBrZXkpOgorICAgIHNlbGYuX2Ntc2cuRGVsZXRlUmVwZWF0ZWRGaWVsZChzZWxmLl9jZmllbGRfZGVzY3JpcHRvciwga2V5KQorCisgIGRlZiBfX2xlbl9fKHNlbGYpOgorICAgIHJldHVybiBsZW4oc2VsZltzbGljZShOb25lLCBOb25lLCBOb25lKV0pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgaWYgc2VsZiBpcyBvdGhlcjoKKyAgICAgIHJldHVybiBUcnVlCisgICAgaWYgbm90IG9wZXJhdG9yLmlzU2VxdWVuY2VUeXBlKG90aGVyKToKKyAgICAgIHJhaXNlIFR5cGVFcnJvcigKKyAgICAgICAgICAnQ2FuIG9ubHkgY29tcGFyZSByZXBlYXRlZCBzY2FsYXIgZmllbGRzIGFnYWluc3Qgc2VxdWVuY2VzLicpCisgICAgIyBXZSBhcmUgcHJlc3VtYWJseSBjb21wYXJpbmcgYWdhaW5zdCBzb21lIG90aGVyIHNlcXVlbmNlIHR5cGUuCisgICAgcmV0dXJuIG90aGVyID09IHNlbGZbc2xpY2UoTm9uZSwgTm9uZSwgTm9uZSldCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCBzZWxmID09IG90aGVyCisKKyAgZGVmIF9faGFzaF9fKHNlbGYpOgorICAgIHJhaXNlIFR5cGVFcnJvcigndW5oYXNoYWJsZSBvYmplY3QnKQorCisgIGRlZiBzb3J0KHNlbGYsICphcmdzLCAqKmt3YXJncyk6CisgICAgIyBNYWludGFpbiBjb21wYXRpYmlsaXR5IHdpdGggdGhlIHByZXZpb3VzIGludGVyZmFjZS4KKyAgICBpZiAnc29ydF9mdW5jdGlvbicgaW4ga3dhcmdzOgorICAgICAga3dhcmdzWydjbXAnXSA9IGt3YXJncy5wb3AoJ3NvcnRfZnVuY3Rpb24nKQorICAgIHNlbGYuX2Ntc2cuQXNzaWduUmVwZWF0ZWRTY2FsYXIoc2VsZi5fY2ZpZWxkX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3J0ZWQoc2VsZiwgKmFyZ3MsICoqa3dhcmdzKSkKKworCitkZWYgUmVwZWF0ZWRTY2FsYXJQcm9wZXJ0eShjZGVzY3JpcHRvcik6CisgICIiIlJldHVybnMgYSBQeXRob24gcHJvcGVydHkgdGhlIGdpdmVuIHJlcGVhdGVkIHNjYWxhciBmaWVsZC4iIiIKKworICBkZWYgR2V0dGVyKHNlbGYpOgorICAgIGNvbnRhaW5lciA9IHNlbGYuX2NvbXBvc2l0ZV9maWVsZHMuZ2V0KGNkZXNjcmlwdG9yLm5hbWUsIE5vbmUpCisgICAgaWYgY29udGFpbmVyIGlzIE5vbmU6CisgICAgICBjb250YWluZXIgPSBSZXBlYXRlZFNjYWxhckNvbnRhaW5lcihzZWxmLCBjZGVzY3JpcHRvcikKKyAgICAgIHNlbGYuX2NvbXBvc2l0ZV9maWVsZHNbY2Rlc2NyaXB0b3IubmFtZV0gPSBjb250YWluZXIKKyAgICByZXR1cm4gY29udGFpbmVyCisKKyAgZGVmIFNldHRlcihzZWxmLCBuZXdfdmFsdWUpOgorICAgIHJhaXNlIEF0dHJpYnV0ZUVycm9yKCdBc3NpZ25tZW50IG5vdCBhbGxvd2VkIHRvIHJlcGVhdGVkIGZpZWxkICcKKyAgICAgICAgICAgICAgICAgICAgICAgICAnIiVzIiBpbiBwcm90b2NvbCBtZXNzYWdlIG9iamVjdC4nICUgY2Rlc2NyaXB0b3IubmFtZSkKKworICBkb2MgPSAnTWFnaWMgYXR0cmlidXRlIGdlbmVyYXRlZCBmb3IgIiVzIiBwcm90byBmaWVsZC4nICUgY2Rlc2NyaXB0b3IubmFtZQorICByZXR1cm4gcHJvcGVydHkoR2V0dGVyLCBTZXR0ZXIsIGRvYz1kb2MpCisKKworY2xhc3MgUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIob2JqZWN0KToKKyAgIiIiQ29udGFpbmVyIGZvciByZXBlYXRlZCBjb21wb3NpdGUgZmllbGRzLiIiIgorCisgIF9fc2xvdHNfXyA9IFsnX21lc3NhZ2UnLCAnX3N1YmNsYXNzJywgJ19jZmllbGRfZGVzY3JpcHRvcicsICdfY21zZyddCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG1zZywgY2ZpZWxkX2Rlc2NyaXB0b3IsIHN1YmNsYXNzKToKKyAgICBzZWxmLl9tZXNzYWdlID0gbXNnCisgICAgc2VsZi5fY21zZyA9IG1zZy5fY21zZworICAgIHNlbGYuX3N1YmNsYXNzID0gc3ViY2xhc3MKKyAgICBzZWxmLl9jZmllbGRfZGVzY3JpcHRvciA9IGNmaWVsZF9kZXNjcmlwdG9yCisKKyAgZGVmIGFkZChzZWxmLCAqKmt3YXJncyk6CisgICAgY21lc3NhZ2UgPSBzZWxmLl9jbXNnLkFkZE1lc3NhZ2Uoc2VsZi5fY2ZpZWxkX2Rlc2NyaXB0b3IpCisgICAgcmV0dXJuIHNlbGYuX3N1YmNsYXNzKF9fY21lc3NhZ2U9Y21lc3NhZ2UsIF9fb3duZXI9c2VsZi5fbWVzc2FnZSwgKiprd2FyZ3MpCisKKyAgZGVmIGV4dGVuZChzZWxmLCBlbGVtX3NlcSk6CisgICAgIiIiRXh0ZW5kcyBieSBhcHBlbmRpbmcgdGhlIGdpdmVuIHNlcXVlbmNlIG9mIGVsZW1lbnRzIG9mIHRoZSBzYW1lIHR5cGUKKyAgICBhcyB0aGlzIG9uZSwgY29weWluZyBlYWNoIGluZGl2aWR1YWwgbWVzc2FnZS4KKyAgICAiIiIKKyAgICBmb3IgbWVzc2FnZSBpbiBlbGVtX3NlcToKKyAgICAgIHNlbGYuYWRkKCkuTWVyZ2VGcm9tKG1lc3NhZ2UpCisKKyAgZGVmIHJlbW92ZShzZWxmLCB2YWx1ZSk6CisgICAgIyBUT0RPKHByb3RvY29sLWRldmVsKTogVGhpcyBpcyBpbmVmZmljaWVudCBhcyBpdCBuZWVkcyB0byBnZW5lcmF0ZSBhCisgICAgIyBtZXNzYWdlIHBvaW50ZXIgZm9yIGVhY2ggbWVzc2FnZSBvbmx5IHRvIGRvIGluZGV4KCkuICBNb3ZlIHRoaXMgdG8gYSBDKysKKyAgICAjIGV4dGVuc2lvbiBmdW5jdGlvbi4KKyAgICBzZWxmLl9fZGVsaXRlbV9fKHNlbGZbc2xpY2UoTm9uZSwgTm9uZSwgTm9uZSldLmluZGV4KHZhbHVlKSkKKworICBkZWYgTWVyZ2VGcm9tKHNlbGYsIG90aGVyKToKKyAgICBmb3IgbWVzc2FnZSBpbiBvdGhlcls6XToKKyAgICAgIHNlbGYuYWRkKCkuTWVyZ2VGcm9tKG1lc3NhZ2UpCisKKyAgZGVmIF9fZ2V0aXRlbV9fKHNlbGYsIGtleSk6CisgICAgY21lc3NhZ2VzID0gc2VsZi5fY21zZy5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAgIHNlbGYuX2NmaWVsZF9kZXNjcmlwdG9yLCBrZXkpCisgICAgc3ViY2xhc3MgPSBzZWxmLl9zdWJjbGFzcworICAgIGlmIG5vdCBpc2luc3RhbmNlKGNtZXNzYWdlcywgbGlzdCk6CisgICAgICByZXR1cm4gc3ViY2xhc3MoX19jbWVzc2FnZT1jbWVzc2FnZXMsIF9fb3duZXI9c2VsZi5fbWVzc2FnZSkKKworICAgIHJldHVybiBbc3ViY2xhc3MoX19jbWVzc2FnZT1tLCBfX293bmVyPXNlbGYuX21lc3NhZ2UpIGZvciBtIGluIGNtZXNzYWdlc10KKworICBkZWYgX19kZWxpdGVtX18oc2VsZiwga2V5KToKKyAgICBzZWxmLl9jbXNnLkRlbGV0ZVJlcGVhdGVkRmllbGQoCisgICAgICAgIHNlbGYuX2NmaWVsZF9kZXNjcmlwdG9yLCBrZXkpCisKKyAgZGVmIF9fbGVuX18oc2VsZik6CisgICAgcmV0dXJuIHNlbGYuX2Ntc2cuRmllbGRMZW5ndGgoc2VsZi5fY2ZpZWxkX2Rlc2NyaXB0b3IpCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgIiIiQ29tcGFyZXMgdGhlIGN1cnJlbnQgaW5zdGFuY2Ugd2l0aCBhbm90aGVyIG9uZS4iIiIKKyAgICBpZiBzZWxmIGlzIG90aGVyOgorICAgICAgcmV0dXJuIFRydWUKKyAgICBpZiBub3QgaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pOgorICAgICAgcmFpc2UgVHlwZUVycm9yKCdDYW4gb25seSBjb21wYXJlIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZHMgYWdhaW5zdCAnCisgICAgICAgICAgICAgICAgICAgICAgJ290aGVyIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZHMuJykKKyAgICBtZXNzYWdlcyA9IHNlbGZbc2xpY2UoTm9uZSwgTm9uZSwgTm9uZSldCisgICAgb3RoZXJfbWVzc2FnZXMgPSBvdGhlcltzbGljZShOb25lLCBOb25lLCBOb25lKV0KKyAgICByZXR1cm4gbWVzc2FnZXMgPT0gb3RoZXJfbWVzc2FnZXMKKworICBkZWYgX19oYXNoX18oc2VsZik6CisgICAgcmFpc2UgVHlwZUVycm9yKCd1bmhhc2hhYmxlIG9iamVjdCcpCisKKyAgZGVmIHNvcnQoc2VsZiwgY21wPU5vbmUsIGtleT1Ob25lLCByZXZlcnNlPUZhbHNlLCAqKmt3YXJncyk6CisgICAgIyBNYWludGFpbiBjb21wYXRpYmlsaXR5IHdpdGggdGhlIG9sZCBpbnRlcmZhY2UuCisgICAgaWYgY21wIGlzIE5vbmUgYW5kICdzb3J0X2Z1bmN0aW9uJyBpbiBrd2FyZ3M6CisgICAgICBjbXAgPSBrd2FyZ3MucG9wKCdzb3J0X2Z1bmN0aW9uJykKKworICAgICMgVGhlIGNtcCBmdW5jdGlvbiwgaWYgcHJvdmlkZWQsIGlzIHBhc3NlZCB0aGUgcmVzdWx0cyBvZiB0aGUga2V5IGZ1bmN0aW9uLAorICAgICMgc28gd2Ugb25seSBuZWVkIHRvIHdyYXAgb25lIG9mIHRoZW0uCisgICAgaWYga2V5IGlzIE5vbmU6CisgICAgICBpbmRleF9rZXkgPSBzZWxmLl9fZ2V0aXRlbV9fCisgICAgZWxzZToKKyAgICAgIGluZGV4X2tleSA9IGxhbWJkYSBpOiBrZXkoc2VsZltpXSkKKworICAgICMgU29ydCB0aGUgbGlzdCBvZiBjdXJyZW50IGluZGV4ZXMgYnkgdGhlIHVuZGVybHlpbmcgb2JqZWN0LgorICAgIGluZGV4ZXMgPSByYW5nZShsZW4oc2VsZikpCisgICAgaW5kZXhlcy5zb3J0KGNtcD1jbXAsIGtleT1pbmRleF9rZXksIHJldmVyc2U9cmV2ZXJzZSkKKworICAgICMgQXBwbHkgdGhlIHRyYW5zcG9zaXRpb24uCisgICAgZm9yIGRlc3QsIHNyYyBpbiBlbnVtZXJhdGUoaW5kZXhlcyk6CisgICAgICBpZiBkZXN0ID09IHNyYzoKKyAgICAgICAgY29udGludWUKKyAgICAgIHNlbGYuX2Ntc2cuU3dhcFJlcGVhdGVkRmllbGRFbGVtZW50cyhzZWxmLl9jZmllbGRfZGVzY3JpcHRvciwgZGVzdCwgc3JjKQorICAgICAgIyBEb24ndCBzd2FwIHRoZSBzYW1lIHZhbHVlIHR3aWNlLgorICAgICAgaW5kZXhlc1tzcmNdID0gc3JjCisKKworZGVmIFJlcGVhdGVkQ29tcG9zaXRlUHJvcGVydHkoY2Rlc2NyaXB0b3IsIG1lc3NhZ2VfdHlwZSk6CisgICIiIlJldHVybnMgYSBQeXRob24gcHJvcGVydHkgZm9yIHRoZSBnaXZlbiByZXBlYXRlZCBjb21wb3NpdGUgZmllbGQuIiIiCisKKyAgZGVmIEdldHRlcihzZWxmKToKKyAgICBjb250YWluZXIgPSBzZWxmLl9jb21wb3NpdGVfZmllbGRzLmdldChjZGVzY3JpcHRvci5uYW1lLCBOb25lKQorICAgIGlmIGNvbnRhaW5lciBpcyBOb25lOgorICAgICAgY29udGFpbmVyID0gUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIoCisgICAgICAgICAgc2VsZiwgY2Rlc2NyaXB0b3IsIG1lc3NhZ2VfdHlwZS5fY29uY3JldGVfY2xhc3MpCisgICAgICBzZWxmLl9jb21wb3NpdGVfZmllbGRzW2NkZXNjcmlwdG9yLm5hbWVdID0gY29udGFpbmVyCisgICAgcmV0dXJuIGNvbnRhaW5lcgorCisgIGRlZiBTZXR0ZXIoc2VsZiwgbmV3X3ZhbHVlKToKKyAgICByYWlzZSBBdHRyaWJ1dGVFcnJvcignQXNzaWdubWVudCBub3QgYWxsb3dlZCB0byByZXBlYXRlZCBmaWVsZCAnCisgICAgICAgICAgICAgICAgICAgICAgICAgJyIlcyIgaW4gcHJvdG9jb2wgbWVzc2FnZSBvYmplY3QuJyAlIGNkZXNjcmlwdG9yLm5hbWUpCisKKyAgZG9jID0gJ01hZ2ljIGF0dHJpYnV0ZSBnZW5lcmF0ZWQgZm9yICIlcyIgcHJvdG8gZmllbGQuJyAlIGNkZXNjcmlwdG9yLm5hbWUKKyAgcmV0dXJuIHByb3BlcnR5KEdldHRlciwgU2V0dGVyLCBkb2M9ZG9jKQorCisKK2NsYXNzIEV4dGVuc2lvbkRpY3Qob2JqZWN0KToKKyAgIiIiRXh0ZW5zaW9uIGRpY3Rpb25hcnkgYWRkZWQgdG8gZWFjaCBwcm90b2NvbCBtZXNzYWdlLiIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBtc2cpOgorICAgIHNlbGYuX21lc3NhZ2UgPSBtc2cKKyAgICBzZWxmLl9jbXNnID0gbXNnLl9jbXNnCisgICAgc2VsZi5fdmFsdWVzID0ge30KKworICBkZWYgX19zZXRpdGVtX18oc2VsZiwgZXh0ZW5zaW9uLCB2YWx1ZSk6CisgICAgZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3IKKyAgICBpZiBub3QgaXNpbnN0YW5jZShleHRlbnNpb24sIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yKToKKyAgICAgIHJhaXNlIEtleUVycm9yKCdCYWQgZXh0ZW5zaW9uICVyLicgJSAoZXh0ZW5zaW9uLCkpCisgICAgY2Rlc2NyaXB0b3IgPSBleHRlbnNpb24uX2NkZXNjcmlwdG9yCisgICAgaWYgKGNkZXNjcmlwdG9yLmxhYmVsICE9IF9MQUJFTF9PUFRJT05BTCBvcgorICAgICAgICBjZGVzY3JpcHRvci5jcHBfdHlwZSA9PSBfQ1BQVFlQRV9NRVNTQUdFKToKKyAgICAgIHJhaXNlIFR5cGVFcnJvcignRXh0ZW5zaW9uICVyIGlzIHJlcGVhdGVkIGFuZC9vciBhIGNvbXBvc2l0ZSB0eXBlLicgJSAoCisgICAgICAgICAgZXh0ZW5zaW9uLmZ1bGxfbmFtZSwpKQorICAgIHNlbGYuX2Ntc2cuU2V0U2NhbGFyKGNkZXNjcmlwdG9yLCB2YWx1ZSkKKyAgICBzZWxmLl92YWx1ZXNbZXh0ZW5zaW9uXSA9IHZhbHVlCisKKyAgZGVmIF9fZ2V0aXRlbV9fKHNlbGYsIGV4dGVuc2lvbik6CisgICAgZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3IKKyAgICBpZiBub3QgaXNpbnN0YW5jZShleHRlbnNpb24sIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yKToKKyAgICAgIHJhaXNlIEtleUVycm9yKCdCYWQgZXh0ZW5zaW9uICVyLicgJSAoZXh0ZW5zaW9uLCkpCisKKyAgICBjZGVzY3JpcHRvciA9IGV4dGVuc2lvbi5fY2Rlc2NyaXB0b3IKKyAgICBpZiAoY2Rlc2NyaXB0b3IubGFiZWwgIT0gX0xBQkVMX1JFUEVBVEVEIGFuZAorICAgICAgICBjZGVzY3JpcHRvci5jcHBfdHlwZSAhPSBfQ1BQVFlQRV9NRVNTQUdFKToKKyAgICAgIHJldHVybiBzZWxmLl9jbXNnLkdldFNjYWxhcihjZGVzY3JpcHRvcikKKworICAgIGV4dCA9IHNlbGYuX3ZhbHVlcy5nZXQoZXh0ZW5zaW9uLCBOb25lKQorICAgIGlmIGV4dCBpcyBub3QgTm9uZToKKyAgICAgIHJldHVybiBleHQKKworICAgIGV4dCA9IHNlbGYuX0NyZWF0ZU5ld0hhbmRsZShleHRlbnNpb24pCisgICAgc2VsZi5fdmFsdWVzW2V4dGVuc2lvbl0gPSBleHQKKyAgICByZXR1cm4gZXh0CisKKyAgZGVmIENsZWFyRXh0ZW5zaW9uKHNlbGYsIGV4dGVuc2lvbik6CisgICAgZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3IKKyAgICBpZiBub3QgaXNpbnN0YW5jZShleHRlbnNpb24sIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yKToKKyAgICAgIHJhaXNlIEtleUVycm9yKCdCYWQgZXh0ZW5zaW9uICVyLicgJSAoZXh0ZW5zaW9uLCkpCisgICAgc2VsZi5fY21zZy5DbGVhckZpZWxkQnlEZXNjcmlwdG9yKGV4dGVuc2lvbi5fY2Rlc2NyaXB0b3IpCisgICAgaWYgZXh0ZW5zaW9uIGluIHNlbGYuX3ZhbHVlczoKKyAgICAgIGRlbCBzZWxmLl92YWx1ZXNbZXh0ZW5zaW9uXQorCisgIGRlZiBIYXNFeHRlbnNpb24oc2VsZiwgZXh0ZW5zaW9uKToKKyAgICBmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcgorICAgIGlmIG5vdCBpc2luc3RhbmNlKGV4dGVuc2lvbiwgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IpOgorICAgICAgcmFpc2UgS2V5RXJyb3IoJ0JhZCBleHRlbnNpb24gJXIuJyAlIChleHRlbnNpb24sKSkKKyAgICByZXR1cm4gc2VsZi5fY21zZy5IYXNGaWVsZEJ5RGVzY3JpcHRvcihleHRlbnNpb24uX2NkZXNjcmlwdG9yKQorCisgIGRlZiBfRmluZEV4dGVuc2lvbkJ5TmFtZShzZWxmLCBuYW1lKToKKyAgICAiIiJUcmllcyB0byBmaW5kIGEga25vd24gZXh0ZW5zaW9uIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorCisgICAgQXJnczoKKyAgICAgIG5hbWU6IEV4dGVuc2lvbiBmdWxsIG5hbWUuCisKKyAgICBSZXR1cm5zOgorICAgICAgRXh0ZW5zaW9uIGZpZWxkIGRlc2NyaXB0b3IuCisgICAgIiIiCisgICAgcmV0dXJuIHNlbGYuX21lc3NhZ2UuX2V4dGVuc2lvbnNfYnlfbmFtZS5nZXQobmFtZSwgTm9uZSkKKworICBkZWYgX0NyZWF0ZU5ld0hhbmRsZShzZWxmLCBleHRlbnNpb24pOgorICAgIGNkZXNjcmlwdG9yID0gZXh0ZW5zaW9uLl9jZGVzY3JpcHRvcgorICAgIGlmIChjZGVzY3JpcHRvci5sYWJlbCAhPSBfTEFCRUxfUkVQRUFURUQgYW5kCisgICAgICAgIGNkZXNjcmlwdG9yLmNwcF90eXBlID09IF9DUFBUWVBFX01FU1NBR0UpOgorICAgICAgY21lc3NhZ2UgPSBzZWxmLl9jbXNnLk5ld1N1Yk1lc3NhZ2UoY2Rlc2NyaXB0b3IpCisgICAgICByZXR1cm4gZXh0ZW5zaW9uLm1lc3NhZ2VfdHlwZS5fY29uY3JldGVfY2xhc3MoX19jbWVzc2FnZT1jbWVzc2FnZSkKKworICAgIGlmIGNkZXNjcmlwdG9yLmxhYmVsID09IF9MQUJFTF9SRVBFQVRFRDoKKyAgICAgIGlmIGNkZXNjcmlwdG9yLmNwcF90eXBlID09IF9DUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHJldHVybiBSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lcigKKyAgICAgICAgICAgIHNlbGYuX21lc3NhZ2UsIGNkZXNjcmlwdG9yLCBleHRlbnNpb24ubWVzc2FnZV90eXBlLl9jb25jcmV0ZV9jbGFzcykKKyAgICAgIGVsc2U6CisgICAgICAgIHJldHVybiBSZXBlYXRlZFNjYWxhckNvbnRhaW5lcihzZWxmLl9tZXNzYWdlLCBjZGVzY3JpcHRvcikKKyAgICAjIFRoaXMgc2hvdWxkbid0IGhhcHBlbiEKKyAgICBhc3NlcnQgRmFsc2UKKyAgICByZXR1cm4gTm9uZQorCisKK2RlZiBOZXdNZXNzYWdlKGJhc2VzLCBtZXNzYWdlX2Rlc2NyaXB0b3IsIGRpY3Rpb25hcnkpOgorICAiIiJDcmVhdGVzIGEgbmV3IHByb3RvY29sIG1lc3NhZ2UgKmNsYXNzKi4iIiIKKyAgX0FkZENsYXNzQXR0cmlidXRlc0Zvck5lc3RlZEV4dGVuc2lvbnMobWVzc2FnZV9kZXNjcmlwdG9yLCBkaWN0aW9uYXJ5KQorICBfQWRkRW51bVZhbHVlcyhtZXNzYWdlX2Rlc2NyaXB0b3IsIGRpY3Rpb25hcnkpCisgIF9BZGREZXNjcmlwdG9ycyhtZXNzYWdlX2Rlc2NyaXB0b3IsIGRpY3Rpb25hcnkpCisgIHJldHVybiBiYXNlcworCisKK2RlZiBJbml0TWVzc2FnZShtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkNvbnN0cnVjdHMgYSBuZXcgbWVzc2FnZSBpbnN0YW5jZSAoY2FsbGVkIGJlZm9yZSBpbnN0YW5jZSdzIF9faW5pdF9fKS4iIiIKKyAgY2xzLl9leHRlbnNpb25zX2J5X25hbWUgPSB7fQorICBfQWRkSW5pdE1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscykKKyAgX0FkZE1lc3NhZ2VNZXRob2RzKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkUHJvcGVydGllc0ZvckV4dGVuc2lvbnMobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpCisgIGNvcHlfcmVnLnBpY2tsZShjbHMsIGxhbWJkYSBvYmo6IChjbHMsICgpLCBvYmouX19nZXRzdGF0ZV9fKCkpKQorCisKK2RlZiBfQWRkRGVzY3JpcHRvcnMobWVzc2FnZV9kZXNjcmlwdG9yLCBkaWN0aW9uYXJ5KToKKyAgIiIiU2V0cyB1cCBhIG5ldyBwcm90b2NvbCBtZXNzYWdlIGNsYXNzIGRpY3Rpb25hcnkuCisKKyAgQXJnczoKKyAgICBtZXNzYWdlX2Rlc2NyaXB0b3I6IEEgRGVzY3JpcHRvciBpbnN0YW5jZSBkZXNjcmliaW5nIHRoaXMgbWVzc2FnZSB0eXBlLgorICAgIGRpY3Rpb25hcnk6IENsYXNzIGRpY3Rpb25hcnkgdG8gd2hpY2ggd2UnbGwgYWRkIGEgJ19fc2xvdHNfXycgZW50cnkuCisgICIiIgorICBkaWN0aW9uYXJ5WydfX2Rlc2NyaXB0b3JzJ10gPSB7fQorICBmb3IgZmllbGQgaW4gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkczoKKyAgICBkaWN0aW9uYXJ5WydfX2Rlc2NyaXB0b3JzJ11bZmllbGQubmFtZV0gPSBHZXRGaWVsZERlc2NyaXB0b3IoCisgICAgICAgIGZpZWxkLmZ1bGxfbmFtZSkKKworICBkaWN0aW9uYXJ5WydfX3Nsb3RzX18nXSA9IGxpc3QoZGljdGlvbmFyeVsnX19kZXNjcmlwdG9ycyddLml0ZXJrZXlzKCkpICsgWworICAgICAgJ19jbXNnJywgJ19vd25lcicsICdfY29tcG9zaXRlX2ZpZWxkcycsICdFeHRlbnNpb25zJywgJ19IQUNLX1JFRkNPVU5UUyddCisKKworZGVmIF9BZGRFbnVtVmFsdWVzKG1lc3NhZ2VfZGVzY3JpcHRvciwgZGljdGlvbmFyeSk6CisgICIiIlNldHMgY2xhc3MtbGV2ZWwgYXR0cmlidXRlcyBmb3IgYWxsIGVudW0gZmllbGRzIGRlZmluZWQgaW4gdGhpcyBtZXNzYWdlLgorCisgIEFyZ3M6CisgICAgbWVzc2FnZV9kZXNjcmlwdG9yOiBEZXNjcmlwdG9yIG9iamVjdCBmb3IgdGhpcyBtZXNzYWdlIHR5cGUuCisgICAgZGljdGlvbmFyeTogQ2xhc3MgZGljdGlvbmFyeSB0aGF0IHNob3VsZCBiZSBwb3B1bGF0ZWQuCisgICIiIgorICBmb3IgZW51bV90eXBlIGluIG1lc3NhZ2VfZGVzY3JpcHRvci5lbnVtX3R5cGVzOgorICAgIGRpY3Rpb25hcnlbZW51bV90eXBlLm5hbWVdID0gZW51bV90eXBlX3dyYXBwZXIuRW51bVR5cGVXcmFwcGVyKGVudW1fdHlwZSkKKyAgICBmb3IgZW51bV92YWx1ZSBpbiBlbnVtX3R5cGUudmFsdWVzOgorICAgICAgZGljdGlvbmFyeVtlbnVtX3ZhbHVlLm5hbWVdID0gZW51bV92YWx1ZS5udW1iZXIKKworCitkZWYgX0FkZENsYXNzQXR0cmlidXRlc0Zvck5lc3RlZEV4dGVuc2lvbnMobWVzc2FnZV9kZXNjcmlwdG9yLCBkaWN0aW9uYXJ5KToKKyAgIiIiQWRkcyBjbGFzcyBhdHRyaWJ1dGVzIGZvciB0aGUgbmVzdGVkIGV4dGVuc2lvbnMuIiIiCisgIGV4dGVuc2lvbl9kaWN0ID0gbWVzc2FnZV9kZXNjcmlwdG9yLmV4dGVuc2lvbnNfYnlfbmFtZQorICBmb3IgZXh0ZW5zaW9uX25hbWUsIGV4dGVuc2lvbl9maWVsZCBpbiBleHRlbnNpb25fZGljdC5pdGVyaXRlbXMoKToKKyAgICBhc3NlcnQgZXh0ZW5zaW9uX25hbWUgbm90IGluIGRpY3Rpb25hcnkKKyAgICBkaWN0aW9uYXJ5W2V4dGVuc2lvbl9uYW1lXSA9IGV4dGVuc2lvbl9maWVsZAorCisKK2RlZiBfQWRkSW5pdE1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkFkZHMgYW4gX19pbml0X18gbWV0aG9kIHRvIGNscy4iIiIKKworICAjIENyZWF0ZSBhbmQgYXR0YWNoIG1lc3NhZ2UgZmllbGQgcHJvcGVydGllcyB0byB0aGUgbWVzc2FnZSBjbGFzcy4KKyAgIyBUaGlzIGNhbiBiZSBkb25lIGp1c3Qgb25jZSBwZXIgbWVzc2FnZSBjbGFzcywgc2luY2UgcHJvcGVydHkgc2V0dGVycyBhbmQKKyAgIyBnZXR0ZXJzIGFyZSBwYXNzZWQgdGhlIG1lc3NhZ2UgaW5zdGFuY2UuCisgICMgVGhpcyBtYWtlcyBtZXNzYWdlIGluc3RhbnRpYXRpb24gZXh0cmVtZWx5IGZhc3QsIGFuZCBhdCB0aGUgc2FtZSB0aW1lIGl0CisgICMgZG9lc24ndCByZXF1aXJlIHRoZSBjcmVhdGlvbiBvZiBwcm9wZXJ0eSBvYmplY3RzIGZvciBlYWNoIG1lc3NhZ2UgaW5zdGFuY2UsCisgICMgd2hpY2ggc2F2ZXMgYSBsb3Qgb2YgbWVtb3J5LgorICBmb3IgZmllbGQgaW4gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkczoKKyAgICBmaWVsZF9jZGVzY3JpcHRvciA9IGNscy5fX2Rlc2NyaXB0b3JzW2ZpZWxkLm5hbWVdCisgICAgaWYgZmllbGQubGFiZWwgPT0gX0xBQkVMX1JFUEVBVEVEOgorICAgICAgaWYgZmllbGQuY3BwX3R5cGUgPT0gX0NQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgdmFsdWUgPSBSZXBlYXRlZENvbXBvc2l0ZVByb3BlcnR5KGZpZWxkX2NkZXNjcmlwdG9yLCBmaWVsZC5tZXNzYWdlX3R5cGUpCisgICAgICBlbHNlOgorICAgICAgICB2YWx1ZSA9IFJlcGVhdGVkU2NhbGFyUHJvcGVydHkoZmllbGRfY2Rlc2NyaXB0b3IpCisgICAgZWxpZiBmaWVsZC5jcHBfdHlwZSA9PSBfQ1BQVFlQRV9NRVNTQUdFOgorICAgICAgdmFsdWUgPSBDb21wb3NpdGVQcm9wZXJ0eShmaWVsZF9jZGVzY3JpcHRvciwgZmllbGQubWVzc2FnZV90eXBlKQorICAgIGVsc2U6CisgICAgICB2YWx1ZSA9IFNjYWxhclByb3BlcnR5KGZpZWxkX2NkZXNjcmlwdG9yKQorICAgIHNldGF0dHIoY2xzLCBmaWVsZC5uYW1lLCB2YWx1ZSkKKworICAgICMgQXR0YWNoIGEgY29uc3RhbnQgd2l0aCB0aGUgZmllbGQgbnVtYmVyLgorICAgIGNvbnN0YW50X25hbWUgPSBmaWVsZC5uYW1lLnVwcGVyKCkgKyAnX0ZJRUxEX05VTUJFUicKKyAgICBzZXRhdHRyKGNscywgY29uc3RhbnRfbmFtZSwgZmllbGQubnVtYmVyKQorCisgIGRlZiBJbml0KHNlbGYsICoqa3dhcmdzKToKKyAgICAiIiJNZXNzYWdlIGNvbnN0cnVjdG9yLiIiIgorICAgIGNtZXNzYWdlID0ga3dhcmdzLnBvcCgnX19jbWVzc2FnZScsIE5vbmUpCisgICAgaWYgY21lc3NhZ2U6CisgICAgICBzZWxmLl9jbXNnID0gY21lc3NhZ2UKKyAgICBlbHNlOgorICAgICAgc2VsZi5fY21zZyA9IE5ld0NNZXNzYWdlKG1lc3NhZ2VfZGVzY3JpcHRvci5mdWxsX25hbWUpCisKKyAgICAjIEtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIG93bmVyLCBhcyB0aGUgb3duZXIga2VlcHMgYSByZWZlcmVuY2UgdG8gdGhlCisgICAgIyB1bmRlcmx5aW5nIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlLgorICAgIG93bmVyID0ga3dhcmdzLnBvcCgnX19vd25lcicsIE5vbmUpCisgICAgaWYgb3duZXI6CisgICAgICBzZWxmLl9vd25lciA9IG93bmVyCisKKyAgICBpZiBtZXNzYWdlX2Rlc2NyaXB0b3IuaXNfZXh0ZW5kYWJsZToKKyAgICAgIHNlbGYuRXh0ZW5zaW9ucyA9IEV4dGVuc2lvbkRpY3Qoc2VsZikKKyAgICBlbHNlOgorICAgICAgIyBSZWZlcmVuY2UgY291bnRpbmcgaW4gdGhlIEMrKyBjb2RlIGlzIGJyb2tlbiBhbmQgZGVwZW5kcyBvbgorICAgICAgIyB0aGUgRXh0ZW5zaW9ucyByZWZlcmVuY2UgdG8ga2VlcCB0aGlzIG9iamVjdCBhbGl2ZSBkdXJpbmcgdW5pdAorICAgICAgIyB0ZXN0cyAoc2VlIGIvNDg1NjA1MikuICBSZW1vdmUgdGhpcyBvbmNlIGIvNDk0NTkwNCBpcyBmaXhlZC4KKyAgICAgIHNlbGYuX0hBQ0tfUkVGQ09VTlRTID0gc2VsZgorICAgIHNlbGYuX2NvbXBvc2l0ZV9maWVsZHMgPSB7fQorCisgICAgZm9yIGZpZWxkX25hbWUsIGZpZWxkX3ZhbHVlIGluIGt3YXJncy5pdGVyaXRlbXMoKToKKyAgICAgIGZpZWxkX2NkZXNjcmlwdG9yID0gc2VsZi5fX2Rlc2NyaXB0b3JzLmdldChmaWVsZF9uYW1lLCBOb25lKQorICAgICAgaWYgbm90IGZpZWxkX2NkZXNjcmlwdG9yOgorICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdQcm90b2NvbCBtZXNzYWdlIGhhcyBubyAiJXMiIGZpZWxkLicgJSBmaWVsZF9uYW1lKQorICAgICAgaWYgZmllbGRfY2Rlc2NyaXB0b3IubGFiZWwgPT0gX0xBQkVMX1JFUEVBVEVEOgorICAgICAgICBpZiBmaWVsZF9jZGVzY3JpcHRvci5jcHBfdHlwZSA9PSBfQ1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIGZpZWxkX25hbWUgPSBnZXRhdHRyKHNlbGYsIGZpZWxkX25hbWUpCisgICAgICAgICAgZm9yIHZhbCBpbiBmaWVsZF92YWx1ZToKKyAgICAgICAgICAgIGZpZWxkX25hbWUuYWRkKCkuTWVyZ2VGcm9tKHZhbCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBnZXRhdHRyKHNlbGYsIGZpZWxkX25hbWUpLmV4dGVuZChmaWVsZF92YWx1ZSkKKyAgICAgIGVsaWYgZmllbGRfY2Rlc2NyaXB0b3IuY3BwX3R5cGUgPT0gX0NQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgZ2V0YXR0cihzZWxmLCBmaWVsZF9uYW1lKS5NZXJnZUZyb20oZmllbGRfdmFsdWUpCisgICAgICBlbHNlOgorICAgICAgICBzZXRhdHRyKHNlbGYsIGZpZWxkX25hbWUsIGZpZWxkX3ZhbHVlKQorCisgIEluaXQuX19tb2R1bGVfXyA9IE5vbmUKKyAgSW5pdC5fX2RvY19fID0gTm9uZQorICBjbHMuX19pbml0X18gPSBJbml0CisKKworZGVmIF9Jc01lc3NhZ2VTZXRFeHRlbnNpb24oZmllbGQpOgorICAiIiJDaGVja3MgaWYgYSBmaWVsZCBpcyBhIG1lc3NhZ2Ugc2V0IGV4dGVuc2lvbi4iIiIKKyAgcmV0dXJuIChmaWVsZC5pc19leHRlbnNpb24gYW5kCisgICAgICAgICAgZmllbGQuY29udGFpbmluZ190eXBlLmhhc19vcHRpb25zIGFuZAorICAgICAgICAgIGZpZWxkLmNvbnRhaW5pbmdfdHlwZS5HZXRPcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgYW5kCisgICAgICAgICAgZmllbGQudHlwZSA9PSBfVFlQRV9NRVNTQUdFIGFuZAorICAgICAgICAgIGZpZWxkLm1lc3NhZ2VfdHlwZSA9PSBmaWVsZC5leHRlbnNpb25fc2NvcGUgYW5kCisgICAgICAgICAgZmllbGQubGFiZWwgPT0gX0xBQkVMX09QVElPTkFMKQorCisKK2RlZiBfQWRkTWVzc2FnZU1ldGhvZHMobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJBZGRzIHRoZSBtZXRob2RzIHRvIGEgcHJvdG9jb2wgbWVzc2FnZSBjbGFzcy4iIiIKKyAgaWYgbWVzc2FnZV9kZXNjcmlwdG9yLmlzX2V4dGVuZGFibGU6CisKKyAgICBkZWYgQ2xlYXJFeHRlbnNpb24oc2VsZiwgZXh0ZW5zaW9uKToKKyAgICAgIHNlbGYuRXh0ZW5zaW9ucy5DbGVhckV4dGVuc2lvbihleHRlbnNpb24pCisKKyAgICBkZWYgSGFzRXh0ZW5zaW9uKHNlbGYsIGV4dGVuc2lvbik6CisgICAgICByZXR1cm4gc2VsZi5FeHRlbnNpb25zLkhhc0V4dGVuc2lvbihleHRlbnNpb24pCisKKyAgZGVmIEhhc0ZpZWxkKHNlbGYsIGZpZWxkX25hbWUpOgorICAgIHJldHVybiBzZWxmLl9jbXNnLkhhc0ZpZWxkKGZpZWxkX25hbWUpCisKKyAgZGVmIENsZWFyRmllbGQoc2VsZiwgZmllbGRfbmFtZSk6CisgICAgY2hpbGRfY21lc3NhZ2UgPSBOb25lCisgICAgaWYgZmllbGRfbmFtZSBpbiBzZWxmLl9jb21wb3NpdGVfZmllbGRzOgorICAgICAgY2hpbGRfZmllbGQgPSBzZWxmLl9jb21wb3NpdGVfZmllbGRzW2ZpZWxkX25hbWVdCisgICAgICBkZWwgc2VsZi5fY29tcG9zaXRlX2ZpZWxkc1tmaWVsZF9uYW1lXQorCisgICAgICBjaGlsZF9jZGVzY3JpcHRvciA9IHNlbGYuX19kZXNjcmlwdG9yc1tmaWVsZF9uYW1lXQorICAgICAgIyBUT0RPKGFudXJhYWcpOiBTdXBwb3J0IGNsZWFyaW5nIHJlcGVhdGVkIG1lc3NhZ2UgZmllbGRzIGFzIHdlbGwuCisgICAgICBpZiAoY2hpbGRfY2Rlc2NyaXB0b3IubGFiZWwgIT0gX0xBQkVMX1JFUEVBVEVEIGFuZAorICAgICAgICAgIGNoaWxkX2NkZXNjcmlwdG9yLmNwcF90eXBlID09IF9DUFBUWVBFX01FU1NBR0UpOgorICAgICAgICBjaGlsZF9maWVsZC5fb3duZXIgPSBOb25lCisgICAgICAgIGNoaWxkX2NtZXNzYWdlID0gY2hpbGRfZmllbGQuX2Ntc2cKKworICAgIGlmIGNoaWxkX2NtZXNzYWdlIGlzIG5vdCBOb25lOgorICAgICAgc2VsZi5fY21zZy5DbGVhckZpZWxkKGZpZWxkX25hbWUsIGNoaWxkX2NtZXNzYWdlKQorICAgIGVsc2U6CisgICAgICBzZWxmLl9jbXNnLkNsZWFyRmllbGQoZmllbGRfbmFtZSkKKworICBkZWYgQ2xlYXIoc2VsZik6CisgICAgY21lc3NhZ2VzX3RvX3JlbGVhc2UgPSBbXQorICAgIGZvciBmaWVsZF9uYW1lLCBjaGlsZF9maWVsZCBpbiBzZWxmLl9jb21wb3NpdGVfZmllbGRzLml0ZXJpdGVtcygpOgorICAgICAgY2hpbGRfY2Rlc2NyaXB0b3IgPSBzZWxmLl9fZGVzY3JpcHRvcnNbZmllbGRfbmFtZV0KKyAgICAgICMgVE9ETyhhbnVyYWFnKTogU3VwcG9ydCBjbGVhcmluZyByZXBlYXRlZCBtZXNzYWdlIGZpZWxkcyBhcyB3ZWxsLgorICAgICAgaWYgKGNoaWxkX2NkZXNjcmlwdG9yLmxhYmVsICE9IF9MQUJFTF9SRVBFQVRFRCBhbmQKKyAgICAgICAgICBjaGlsZF9jZGVzY3JpcHRvci5jcHBfdHlwZSA9PSBfQ1BQVFlQRV9NRVNTQUdFKToKKyAgICAgICAgY2hpbGRfZmllbGQuX293bmVyID0gTm9uZQorICAgICAgICBjbWVzc2FnZXNfdG9fcmVsZWFzZS5hcHBlbmQoKGNoaWxkX2NkZXNjcmlwdG9yLCBjaGlsZF9maWVsZC5fY21zZykpCisgICAgc2VsZi5fY29tcG9zaXRlX2ZpZWxkcy5jbGVhcigpCisgICAgc2VsZi5fY21zZy5DbGVhcihjbWVzc2FnZXNfdG9fcmVsZWFzZSkKKworICBkZWYgSXNJbml0aWFsaXplZChzZWxmLCBlcnJvcnM9Tm9uZSk6CisgICAgaWYgc2VsZi5fY21zZy5Jc0luaXRpYWxpemVkKCk6CisgICAgICByZXR1cm4gVHJ1ZQorICAgIGlmIGVycm9ycyBpcyBub3QgTm9uZToKKyAgICAgIGVycm9ycy5leHRlbmQoc2VsZi5GaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoKSk7CisgICAgcmV0dXJuIEZhbHNlCisKKyAgZGVmIFNlcmlhbGl6ZVRvU3RyaW5nKHNlbGYpOgorICAgIGlmIG5vdCBzZWxmLklzSW5pdGlhbGl6ZWQoKToKKyAgICAgIHJhaXNlIG1lc3NhZ2UuRW5jb2RlRXJyb3IoCisgICAgICAgICAgJ01lc3NhZ2UgJXMgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICVzJyAlICgKKyAgICAgICAgICBzZWxmLl9jbXNnLmZ1bGxfbmFtZSwgJywnLmpvaW4oc2VsZi5GaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoKSkpKQorICAgIHJldHVybiBzZWxmLl9jbXNnLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICBkZWYgU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKHNlbGYpOgorICAgIHJldHVybiBzZWxmLl9jbXNnLlNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZygpCisKKyAgZGVmIFBhcnNlRnJvbVN0cmluZyhzZWxmLCBzZXJpYWxpemVkKToKKyAgICBzZWxmLkNsZWFyKCkKKyAgICBzZWxmLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKQorCisgIGRlZiBNZXJnZUZyb21TdHJpbmcoc2VsZiwgc2VyaWFsaXplZCk6CisgICAgYnl0ZV9zaXplID0gc2VsZi5fY21zZy5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkKKyAgICBpZiBieXRlX3NpemUgPCAwOgorICAgICAgcmFpc2UgbWVzc2FnZS5EZWNvZGVFcnJvcignVW5hYmxlIHRvIG1lcmdlIGZyb20gc3RyaW5nLicpCisgICAgcmV0dXJuIGJ5dGVfc2l6ZQorCisgIGRlZiBNZXJnZUZyb20oc2VsZiwgbXNnKToKKyAgICBpZiBub3QgaXNpbnN0YW5jZShtc2csIGNscyk6CisgICAgICByYWlzZSBUeXBlRXJyb3IoCisgICAgICAgICAgIlBhcmFtZXRlciB0byBNZXJnZUZyb20oKSBtdXN0IGJlIGluc3RhbmNlIG9mIHNhbWUgY2xhc3M6ICIKKyAgICAgICAgICAiZXhwZWN0ZWQgJXMgZ290ICVzLiIgJSAoY2xzLl9fbmFtZV9fLCB0eXBlKG1zZykuX19uYW1lX18pKQorICAgIHNlbGYuX2Ntc2cuTWVyZ2VGcm9tKG1zZy5fY21zZykKKworICBkZWYgQ29weUZyb20oc2VsZiwgbXNnKToKKyAgICBzZWxmLl9jbXNnLkNvcHlGcm9tKG1zZy5fY21zZykKKworICBkZWYgQnl0ZVNpemUoc2VsZik6CisgICAgcmV0dXJuIHNlbGYuX2Ntc2cuQnl0ZVNpemUoKQorCisgIGRlZiBTZXRJblBhcmVudChzZWxmKToKKyAgICByZXR1cm4gc2VsZi5fY21zZy5TZXRJblBhcmVudCgpCisKKyAgZGVmIExpc3RGaWVsZHMoc2VsZik6CisgICAgYWxsX2ZpZWxkcyA9IFtdCisgICAgZmllbGRfbGlzdCA9IHNlbGYuX2Ntc2cuTGlzdEZpZWxkcygpCisgICAgZmllbGRzX2J5X25hbWUgPSBjbHMuREVTQ1JJUFRPUi5maWVsZHNfYnlfbmFtZQorICAgIGZvciBpc19leHRlbnNpb24sIGZpZWxkX25hbWUgaW4gZmllbGRfbGlzdDoKKyAgICAgIGlmIGlzX2V4dGVuc2lvbjoKKyAgICAgICAgZXh0ZW5zaW9uID0gY2xzLl9leHRlbnNpb25zX2J5X25hbWVbZmllbGRfbmFtZV0KKyAgICAgICAgYWxsX2ZpZWxkcy5hcHBlbmQoKGV4dGVuc2lvbiwgc2VsZi5FeHRlbnNpb25zW2V4dGVuc2lvbl0pKQorICAgICAgZWxzZToKKyAgICAgICAgZmllbGRfZGVzY3JpcHRvciA9IGZpZWxkc19ieV9uYW1lW2ZpZWxkX25hbWVdCisgICAgICAgIGFsbF9maWVsZHMuYXBwZW5kKAorICAgICAgICAgICAgKGZpZWxkX2Rlc2NyaXB0b3IsIGdldGF0dHIoc2VsZiwgZmllbGRfbmFtZSkpKQorICAgIGFsbF9maWVsZHMuc29ydChrZXk9bGFtYmRhIGl0ZW06IGl0ZW1bMF0ubnVtYmVyKQorICAgIHJldHVybiBhbGxfZmllbGRzCisKKyAgZGVmIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhzZWxmKToKKyAgICByZXR1cm4gc2VsZi5fY21zZy5GaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOgorICAgIHJldHVybiBzdHIoc2VsZi5fY21zZykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICBpZiBzZWxmIGlzIG90aGVyOgorICAgICAgcmV0dXJuIFRydWUKKyAgICBpZiBub3QgaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pOgorICAgICAgcmV0dXJuIEZhbHNlCisgICAgcmV0dXJuIHNlbGYuTGlzdEZpZWxkcygpID09IG90aGVyLkxpc3RGaWVsZHMoKQorCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3Qgc2VsZiA9PSBvdGhlcgorCisgIGRlZiBfX2hhc2hfXyhzZWxmKToKKyAgICByYWlzZSBUeXBlRXJyb3IoJ3VuaGFzaGFibGUgb2JqZWN0JykKKworICBkZWYgX191bmljb2RlX18oc2VsZik6CisgICAgIyBMYXp5IGltcG9ydCB0byBwcmV2ZW50IGNpcmN1bGFyIGltcG9ydCB3aGVuIHRleHRfZm9ybWF0IGltcG9ydHMgdGhpcyBmaWxlLgorICAgIGZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB0ZXh0X2Zvcm1hdAorICAgIHJldHVybiB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcoc2VsZiwgYXNfdXRmOD1UcnVlKS5kZWNvZGUoJ3V0Zi04JykKKworICAjIEF0dGFjaCB0aGUgbG9jYWwgbWV0aG9kcyB0byB0aGUgbWVzc2FnZSBjbGFzcy4KKyAgZm9yIGtleSwgdmFsdWUgaW4gbG9jYWxzKCkuY29weSgpLml0ZXJpdGVtcygpOgorICAgIGlmIGtleSBub3QgaW4gKCdrZXknLCAndmFsdWUnLCAnX19idWlsdGluc19fJywgJ19fbmFtZV9fJywgJ19fZG9jX18nKToKKyAgICAgIHNldGF0dHIoY2xzLCBrZXksIHZhbHVlKQorCisgICMgU3RhdGljIG1ldGhvZHM6CisKKyAgZGVmIFJlZ2lzdGVyRXh0ZW5zaW9uKGV4dGVuc2lvbl9oYW5kbGUpOgorICAgIGV4dGVuc2lvbl9oYW5kbGUuY29udGFpbmluZ190eXBlID0gY2xzLkRFU0NSSVBUT1IKKyAgICBjbHMuX2V4dGVuc2lvbnNfYnlfbmFtZVtleHRlbnNpb25faGFuZGxlLmZ1bGxfbmFtZV0gPSBleHRlbnNpb25faGFuZGxlCisKKyAgICBpZiBfSXNNZXNzYWdlU2V0RXh0ZW5zaW9uKGV4dGVuc2lvbl9oYW5kbGUpOgorICAgICAgIyBNZXNzYWdlU2V0IGV4dGVuc2lvbi4gIEFsc28gcmVnaXN0ZXIgdW5kZXIgdHlwZSBuYW1lLgorICAgICAgY2xzLl9leHRlbnNpb25zX2J5X25hbWVbCisgICAgICAgICAgZXh0ZW5zaW9uX2hhbmRsZS5tZXNzYWdlX3R5cGUuZnVsbF9uYW1lXSA9IGV4dGVuc2lvbl9oYW5kbGUKKyAgY2xzLlJlZ2lzdGVyRXh0ZW5zaW9uID0gc3RhdGljbWV0aG9kKFJlZ2lzdGVyRXh0ZW5zaW9uKQorCisgIGRlZiBGcm9tU3RyaW5nKHN0cmluZyk6CisgICAgbXNnID0gY2xzKCkKKyAgICBtc2cuTWVyZ2VGcm9tU3RyaW5nKHN0cmluZykKKyAgICByZXR1cm4gbXNnCisgIGNscy5Gcm9tU3RyaW5nID0gc3RhdGljbWV0aG9kKEZyb21TdHJpbmcpCisKKworCitkZWYgX0FkZFByb3BlcnRpZXNGb3JFeHRlbnNpb25zKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKToKKyAgIiIiQWRkcyBwcm9wZXJ0aWVzIGZvciBhbGwgZmllbGRzIGluIHRoaXMgcHJvdG9jb2wgbWVzc2FnZSB0eXBlLiIiIgorICBleHRlbnNpb25fZGljdCA9IG1lc3NhZ2VfZGVzY3JpcHRvci5leHRlbnNpb25zX2J5X25hbWUKKyAgZm9yIGV4dGVuc2lvbl9uYW1lLCBleHRlbnNpb25fZmllbGQgaW4gZXh0ZW5zaW9uX2RpY3QuaXRlcml0ZW1zKCk6CisgICAgY29uc3RhbnRfbmFtZSA9IGV4dGVuc2lvbl9uYW1lLnVwcGVyKCkgKyAnX0ZJRUxEX05VTUJFUicKKyAgICBzZXRhdHRyKGNscywgY29uc3RhbnRfbmFtZSwgZXh0ZW5zaW9uX2ZpZWxkLm51bWJlcikKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVjb2Rlci5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVjb2Rlci5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4wZjUwMDYwCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZWNvZGVyLnB5CkBAIC0wLDAgKzEsODI4IEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNQWTI1IGNvbXBhdGlibGUgZm9yIEdBRS4KKyMKKyMgQ29weXJpZ2h0IDIwMDkgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKworIiIiQ29kZSBmb3IgZGVjb2RpbmcgcHJvdG9jb2wgYnVmZmVyIHByaW1pdGl2ZXMuCisKK1RoaXMgY29kZSBpcyB2ZXJ5IHNpbWlsYXIgdG8gZW5jb2Rlci5weSAtLSByZWFkIHRoZSBkb2NzIGZvciB0aGF0IG1vZHVsZSBmaXJzdC4KKworQSAiZGVjb2RlciIgaXMgYSBmdW5jdGlvbiB3aXRoIHRoZSBzaWduYXR1cmU6CisgIERlY29kZShidWZmZXIsIHBvcywgZW5kLCBtZXNzYWdlLCBmaWVsZF9kaWN0KQorVGhlIGFyZ3VtZW50cyBhcmU6CisgIGJ1ZmZlcjogICAgIFRoZSBzdHJpbmcgY29udGFpbmluZyB0aGUgZW5jb2RlZCBtZXNzYWdlLgorICBwb3M6ICAgICAgICBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgc3RyaW5nLgorICBlbmQ6ICAgICAgICBUaGUgcG9zaXRpb24gaW4gdGhlIHN0cmluZyB3aGVyZSB0aGUgY3VycmVudCBtZXNzYWdlIGVuZHMuICBNYXkgYmUKKyAgICAgICAgICAgICAgbGVzcyB0aGFuIGxlbihidWZmZXIpIGlmIHdlJ3JlIHJlYWRpbmcgYSBzdWItbWVzc2FnZS4KKyAgbWVzc2FnZTogICAgVGhlIG1lc3NhZ2Ugb2JqZWN0IGludG8gd2hpY2ggd2UncmUgcGFyc2luZy4KKyAgZmllbGRfZGljdDogbWVzc2FnZS5fZmllbGRzIChhdm9pZHMgYSBoYXNodGFibGUgbG9va3VwKS4KK1RoZSBkZWNvZGVyIHJlYWRzIHRoZSBmaWVsZCBhbmQgc3RvcmVzIGl0IGludG8gZmllbGRfZGljdCwgcmV0dXJuaW5nIHRoZSBuZXcKK2J1ZmZlciBwb3NpdGlvbi4gIEEgZGVjb2RlciBmb3IgYSByZXBlYXRlZCBmaWVsZCBtYXkgcHJvYWN0aXZlbHkgZGVjb2RlIGFsbCBvZgordGhlIGVsZW1lbnRzIG9mIHRoYXQgZmllbGQsIGlmIHRoZXkgYXBwZWFyIGNvbnNlY3V0aXZlbHkuCisKK05vdGUgdGhhdCBkZWNvZGVycyBtYXkgdGhyb3cgYW55IG9mIHRoZSBmb2xsb3dpbmc6CisgIEluZGV4RXJyb3I6ICBJbmRpY2F0ZXMgYSB0cnVuY2F0ZWQgbWVzc2FnZS4KKyAgc3RydWN0LmVycm9yOiAgVW5wYWNraW5nIG9mIGEgZml4ZWQtd2lkdGggZmllbGQgZmFpbGVkLgorICBtZXNzYWdlLkRlY29kZUVycm9yOiAgT3RoZXIgZXJyb3JzLgorCitEZWNvZGVycyBhcmUgZXhwZWN0ZWQgdG8gcmFpc2UgYW4gZXhjZXB0aW9uIGlmIHRoZXkgYXJlIGNhbGxlZCB3aXRoIHBvcyA+IGVuZC4KK1RoaXMgYWxsb3dzIGNhbGxlcnMgdG8gYmUgbGF4IGFib3V0IGJvdW5kcyBjaGVja2luZzogIGl0J3MgZmluZXRvIHJlYWQgcGFzdAorImVuZCIgYXMgbG9uZyBhcyB5b3UgYXJlIHN1cmUgdGhhdCBzb21lb25lIGVsc2Ugd2lsbCBub3RpY2UgYW5kIHRocm93IGFuCitleGNlcHRpb24gbGF0ZXIgb24uCisKK1NvbWV0aGluZyB1cCB0aGUgY2FsbCBzdGFjayBpcyBleHBlY3RlZCB0byBjYXRjaCBJbmRleEVycm9yIGFuZCBzdHJ1Y3QuZXJyb3IKK2FuZCBjb252ZXJ0IHRoZW0gdG8gbWVzc2FnZS5EZWNvZGVFcnJvci4KKworRGVjb2RlcnMgYXJlIGNvbnN0cnVjdGVkIHVzaW5nIGRlY29kZXIgY29uc3RydWN0b3JzIHdpdGggdGhlIHNpZ25hdHVyZToKKyAgTWFrZURlY29kZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkLCBrZXksIG5ld19kZWZhdWx0KQorVGhlIGFyZ3VtZW50cyBhcmU6CisgIGZpZWxkX251bWJlcjogIFRoZSBmaWVsZCBudW1iZXIgb2YgdGhlIGZpZWxkIHdlIHdhbnQgdG8gZGVjb2RlLgorICBpc19yZXBlYXRlZDogICBJcyB0aGUgZmllbGQgYSByZXBlYXRlZCBmaWVsZD8gKGJvb2wpCisgIGlzX3BhY2tlZDogICAgIElzIHRoZSBmaWVsZCBhIHBhY2tlZCBmaWVsZD8gKGJvb2wpCisgIGtleTogICAgICAgICAgIFRoZSBrZXkgdG8gdXNlIHdoZW4gbG9va2luZyB1cCB0aGUgZmllbGQgd2l0aGluIGZpZWxkX2RpY3QuCisgICAgICAgICAgICAgICAgIChUaGlzIGlzIGFjdHVhbGx5IHRoZSBGaWVsZERlc2NyaXB0b3IgYnV0IG5vdGhpbmcgaW4gdGhpcworICAgICAgICAgICAgICAgICBmaWxlIHNob3VsZCBkZXBlbmQgb24gdGhhdC4pCisgIG5ld19kZWZhdWx0OiAgIEEgZnVuY3Rpb24gd2hpY2ggdGFrZXMgYSBtZXNzYWdlIG9iamVjdCBhcyBhIHBhcmFtZXRlciBhbmQKKyAgICAgICAgICAgICAgICAgcmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KKyAgICAgICAgICAgICAgICAgKFRoaXMgaXMgY2FsbGVkIGZvciByZXBlYXRlZCBmaWVsZHMgYW5kIHN1Yi1tZXNzYWdlcywgd2hlbiBhbgorICAgICAgICAgICAgICAgICBpbnN0YW5jZSBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0LikKKworQXMgd2l0aCBlbmNvZGVycywgd2UgZGVmaW5lIGEgZGVjb2RlciBjb25zdHJ1Y3RvciBmb3IgZXZlcnkgdHlwZSBvZiBmaWVsZC4KK1RoZW4sIGZvciBldmVyeSBmaWVsZCBvZiBldmVyeSBtZXNzYWdlIGNsYXNzIHdlIGNvbnN0cnVjdCBhbiBhY3R1YWwgZGVjb2Rlci4KK1RoYXQgZGVjb2RlciBnb2VzIGludG8gYSBkaWN0IGluZGV4ZWQgYnkgdGFnLCBzbyB3aGVuIHdlIGRlY29kZSBhIG1lc3NhZ2UKK3dlIHJlcGVhdGVkbHkgcmVhZCBhIHRhZywgbG9vayB1cCB0aGUgY29ycmVzcG9uZGluZyBkZWNvZGVyLCBhbmQgaW52b2tlIGl0LgorIiIiCisKK19fYXV0aG9yX18gPSAna2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSknCisKK2ltcG9ydCBzdHJ1Y3QKK2ltcG9ydCBzeXMgICMjUFkyNQorX1BZMiA9IHN5cy52ZXJzaW9uX2luZm9bMF0gPCAzICAjI1BZMjUKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBlbmNvZGVyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgd2lyZV9mb3JtYXQKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBtZXNzYWdlCisKKworIyBUaGlzIHdpbGwgb3ZlcmZsb3cgYW5kIHRodXMgYmVjb21lIElFRUUtNzU0ICJpbmZpbml0eSIuICBXZSB3b3VsZCB1c2UKKyMgImZsb2F0KCdpbmYnKSIgYnV0IGl0IGRvZXNuJ3Qgd29yayBvbiBXaW5kb3dzIHByZS1QeXRob24tMi42LgorX1BPU19JTkYgPSAxZTEwMDAwCitfTkVHX0lORiA9IC1fUE9TX0lORgorX05BTiA9IF9QT1NfSU5GICogMAorCisKKyMgVGhpcyBpcyBub3QgZm9yIG9wdGltaXphdGlvbiwgYnV0IHJhdGhlciB0byBhdm9pZCBjb25mbGljdHMgd2l0aCBsb2NhbAorIyB2YXJpYWJsZXMgbmFtZWQgIm1lc3NhZ2UiLgorX0RlY29kZUVycm9yID0gbWVzc2FnZS5EZWNvZGVFcnJvcgorCisKK2RlZiBfVmFyaW50RGVjb2RlcihtYXNrLCByZXN1bHRfdHlwZSk6CisgICIiIlJldHVybiBhbiBlbmNvZGVyIGZvciBhIGJhc2ljIHZhcmludCB2YWx1ZSAoZG9lcyBub3QgaW5jbHVkZSB0YWcpLgorCisgIERlY29kZWQgdmFsdWVzIHdpbGwgYmUgYml0d2lzZS1hbmRlZCB3aXRoIHRoZSBnaXZlbiBtYXNrIGJlZm9yZSBiZWluZworICByZXR1cm5lZCwgZS5nLiB0byBsaW1pdCB0aGVtIHRvIDMyIGJpdHMuICBUaGUgcmV0dXJuZWQgZGVjb2RlciBkb2VzIG5vdAorICB0YWtlIHRoZSB1c3VhbCAiZW5kIiBwYXJhbWV0ZXIgLS0gdGhlIGNhbGxlciBpcyBleHBlY3RlZCB0byBkbyBib3VuZHMgY2hlY2tpbmcKKyAgYWZ0ZXIgdGhlIGZhY3QgKG9mdGVuIHRoZSBjYWxsZXIgY2FuIGRlZmVyIHN1Y2ggY2hlY2tpbmcgdW50aWwgbGF0ZXIpLiAgVGhlCisgIGRlY29kZXIgcmV0dXJucyBhICh2YWx1ZSwgbmV3X3BvcykgcGFpci4KKyAgIiIiCisKKyAgbG9jYWxfb3JkID0gb3JkCisgIHB5MiA9IF9QWTIgICMjUFkyNQorIyMhUFkyNSAgcHkyID0gc3RyIGlzIGJ5dGVzCisgIGRlZiBEZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpOgorICAgIHJlc3VsdCA9IDAKKyAgICBzaGlmdCA9IDAKKyAgICB3aGlsZSAxOgorICAgICAgYiA9IGxvY2FsX29yZChidWZmZXJbcG9zXSkgaWYgcHkyIGVsc2UgYnVmZmVyW3Bvc10KKyAgICAgIHJlc3VsdCB8PSAoKGIgJiAweDdmKSA8PCBzaGlmdCkKKyAgICAgIHBvcyArPSAxCisgICAgICBpZiBub3QgKGIgJiAweDgwKToKKyAgICAgICAgcmVzdWx0ICY9IG1hc2sKKyAgICAgICAgcmVzdWx0ID0gcmVzdWx0X3R5cGUocmVzdWx0KQorICAgICAgICByZXR1cm4gKHJlc3VsdCwgcG9zKQorICAgICAgc2hpZnQgKz0gNworICAgICAgaWYgc2hpZnQgPj0gNjQ6CisgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVG9vIG1hbnkgYnl0ZXMgd2hlbiBkZWNvZGluZyB2YXJpbnQuJykKKyAgcmV0dXJuIERlY29kZVZhcmludAorCisKK2RlZiBfU2lnbmVkVmFyaW50RGVjb2RlcihtYXNrLCByZXN1bHRfdHlwZSk6CisgICIiIkxpa2UgX1ZhcmludERlY29kZXIoKSBidXQgZGVjb2RlcyBzaWduZWQgdmFsdWVzLiIiIgorCisgIGxvY2FsX29yZCA9IG9yZAorICBweTIgPSBfUFkyICAjI1BZMjUKKyMjIVBZMjUgIHB5MiA9IHN0ciBpcyBieXRlcworICBkZWYgRGVjb2RlVmFyaW50KGJ1ZmZlciwgcG9zKToKKyAgICByZXN1bHQgPSAwCisgICAgc2hpZnQgPSAwCisgICAgd2hpbGUgMToKKyAgICAgIGIgPSBsb2NhbF9vcmQoYnVmZmVyW3Bvc10pIGlmIHB5MiBlbHNlIGJ1ZmZlcltwb3NdCisgICAgICByZXN1bHQgfD0gKChiICYgMHg3ZikgPDwgc2hpZnQpCisgICAgICBwb3MgKz0gMQorICAgICAgaWYgbm90IChiICYgMHg4MCk6CisgICAgICAgIGlmIHJlc3VsdCA+IDB4N2ZmZmZmZmZmZmZmZmZmZjoKKyAgICAgICAgICByZXN1bHQgLT0gKDEgPDwgNjQpCisgICAgICAgICAgcmVzdWx0IHw9IH5tYXNrCisgICAgICAgIGVsc2U6CisgICAgICAgICAgcmVzdWx0ICY9IG1hc2sKKyAgICAgICAgcmVzdWx0ID0gcmVzdWx0X3R5cGUocmVzdWx0KQorICAgICAgICByZXR1cm4gKHJlc3VsdCwgcG9zKQorICAgICAgc2hpZnQgKz0gNworICAgICAgaWYgc2hpZnQgPj0gNjQ6CisgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVG9vIG1hbnkgYnl0ZXMgd2hlbiBkZWNvZGluZyB2YXJpbnQuJykKKyAgcmV0dXJuIERlY29kZVZhcmludAorCisjIFdlIGZvcmNlIDMyLWJpdCB2YWx1ZXMgdG8gaW50IGFuZCA2NC1iaXQgdmFsdWVzIHRvIGxvbmcgdG8gbWFrZQorIyBhbHRlcm5hdGUgaW1wbGVtZW50YXRpb25zIHdoZXJlIHRoZSBkaXN0aW5jdGlvbiBpcyBtb3JlIHNpZ25pZmljYW50CisjIChlLmcuIHRoZSBDKysgaW1wbGVtZW50YXRpb24pIHNpbXBsZXIuCisKK19EZWNvZGVWYXJpbnQgPSBfVmFyaW50RGVjb2RlcigoMSA8PCA2NCkgLSAxLCBsb25nKQorX0RlY29kZVNpZ25lZFZhcmludCA9IF9TaWduZWRWYXJpbnREZWNvZGVyKCgxIDw8IDY0KSAtIDEsIGxvbmcpCisKKyMgVXNlIHRoZXNlIHZlcnNpb25zIGZvciB2YWx1ZXMgd2hpY2ggbXVzdCBiZSBsaW1pdGVkIHRvIDMyIGJpdHMuCitfRGVjb2RlVmFyaW50MzIgPSBfVmFyaW50RGVjb2RlcigoMSA8PCAzMikgLSAxLCBpbnQpCitfRGVjb2RlU2lnbmVkVmFyaW50MzIgPSBfU2lnbmVkVmFyaW50RGVjb2RlcigoMSA8PCAzMikgLSAxLCBpbnQpCisKKworZGVmIFJlYWRUYWcoYnVmZmVyLCBwb3MpOgorICAiIiJSZWFkIGEgdGFnIGZyb20gdGhlIGJ1ZmZlciwgYW5kIHJldHVybiBhICh0YWdfYnl0ZXMsIG5ld19wb3MpIHR1cGxlLgorCisgIFdlIHJldHVybiB0aGUgcmF3IGJ5dGVzIG9mIHRoZSB0YWcgcmF0aGVyIHRoYW4gZGVjb2RpbmcgdGhlbS4gIFRoZSByYXcKKyAgYnl0ZXMgY2FuIHRoZW4gYmUgdXNlZCB0byBsb29rIHVwIHRoZSBwcm9wZXIgZGVjb2Rlci4gIFRoaXMgZWZmZWN0aXZlbHkgYWxsb3dzCisgIHVzIHRvIHRyYWRlIHNvbWUgd29yayB0aGF0IHdvdWxkIGJlIGRvbmUgaW4gcHVyZS1weXRob24gKGRlY29kaW5nIGEgdmFyaW50KQorICBmb3Igd29yayB0aGF0IGlzIGRvbmUgaW4gQyAoc2VhcmNoaW5nIGZvciBhIGJ5dGUgc3RyaW5nIGluIGEgaGFzaCB0YWJsZSkuCisgIEluIGEgbG93LWxldmVsIGxhbmd1YWdlIGl0IHdvdWxkIGJlIG11Y2ggY2hlYXBlciB0byBkZWNvZGUgdGhlIHZhcmludCBhbmQKKyAgdXNlIHRoYXQsIGJ1dCBub3QgaW4gUHl0aG9uLgorICAiIiIKKworICBweTIgPSBfUFkyICAjI1BZMjUKKyMjIVBZMjUgIHB5MiA9IHN0ciBpcyBieXRlcworICBzdGFydCA9IHBvcworICB3aGlsZSAob3JkKGJ1ZmZlcltwb3NdKSBpZiBweTIgZWxzZSBidWZmZXJbcG9zXSkgJiAweDgwOgorICAgIHBvcyArPSAxCisgIHBvcyArPSAxCisgIHJldHVybiAoYnVmZmVyW3N0YXJ0OnBvc10sIHBvcykKKworCisjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworZGVmIF9TaW1wbGVEZWNvZGVyKHdpcmVfdHlwZSwgZGVjb2RlX3ZhbHVlKToKKyAgIiIiUmV0dXJuIGEgY29uc3RydWN0b3IgZm9yIGEgZGVjb2RlciBmb3IgZmllbGRzIG9mIGEgcGFydGljdWxhciB0eXBlLgorCisgIEFyZ3M6CisgICAgICB3aXJlX3R5cGU6ICBUaGUgZmllbGQncyB3aXJlIHR5cGUuCisgICAgICBkZWNvZGVfdmFsdWU6ICBBIGZ1bmN0aW9uIHdoaWNoIGRlY29kZXMgYW4gaW5kaXZpZHVhbCB2YWx1ZSwgZS5nLgorICAgICAgICBfRGVjb2RlVmFyaW50KCkKKyAgIiIiCisKKyAgZGVmIFNwZWNpZmljRGVjb2RlcihmaWVsZF9udW1iZXIsIGlzX3JlcGVhdGVkLCBpc19wYWNrZWQsIGtleSwgbmV3X2RlZmF1bHQpOgorICAgIGlmIGlzX3BhY2tlZDoKKyAgICAgIGxvY2FsX0RlY29kZVZhcmludCA9IF9EZWNvZGVWYXJpbnQKKyAgICAgIGRlZiBEZWNvZGVQYWNrZWRGaWVsZChidWZmZXIsIHBvcywgZW5kLCBtZXNzYWdlLCBmaWVsZF9kaWN0KToKKyAgICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LmdldChrZXkpCisgICAgICAgIGlmIHZhbHVlIGlzIE5vbmU6CisgICAgICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LnNldGRlZmF1bHQoa2V5LCBuZXdfZGVmYXVsdChtZXNzYWdlKSkKKyAgICAgICAgKGVuZHBvaW50LCBwb3MpID0gbG9jYWxfRGVjb2RlVmFyaW50KGJ1ZmZlciwgcG9zKQorICAgICAgICBlbmRwb2ludCArPSBwb3MKKyAgICAgICAgaWYgZW5kcG9pbnQgPiBlbmQ6CisgICAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICAgICAgICB3aGlsZSBwb3MgPCBlbmRwb2ludDoKKyAgICAgICAgICAoZWxlbWVudCwgcG9zKSA9IGRlY29kZV92YWx1ZShidWZmZXIsIHBvcykKKyAgICAgICAgICB2YWx1ZS5hcHBlbmQoZWxlbWVudCkKKyAgICAgICAgaWYgcG9zID4gZW5kcG9pbnQ6CisgICAgICAgICAgZGVsIHZhbHVlWy0xXSAgICMgRGlzY2FyZCBjb3JydXB0IHZhbHVlLgorICAgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignUGFja2VkIGVsZW1lbnQgd2FzIHRydW5jYXRlZC4nKQorICAgICAgICByZXR1cm4gcG9zCisgICAgICByZXR1cm4gRGVjb2RlUGFja2VkRmllbGQKKyAgICBlbGlmIGlzX3JlcGVhdGVkOgorICAgICAgdGFnX2J5dGVzID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfdHlwZSkKKyAgICAgIHRhZ19sZW4gPSBsZW4odGFnX2J5dGVzKQorICAgICAgZGVmIERlY29kZVJlcGVhdGVkRmllbGQoYnVmZmVyLCBwb3MsIGVuZCwgbWVzc2FnZSwgZmllbGRfZGljdCk6CisgICAgICAgIHZhbHVlID0gZmllbGRfZGljdC5nZXQoa2V5KQorICAgICAgICBpZiB2YWx1ZSBpcyBOb25lOgorICAgICAgICAgIHZhbHVlID0gZmllbGRfZGljdC5zZXRkZWZhdWx0KGtleSwgbmV3X2RlZmF1bHQobWVzc2FnZSkpCisgICAgICAgIHdoaWxlIDE6CisgICAgICAgICAgKGVsZW1lbnQsIG5ld19wb3MpID0gZGVjb2RlX3ZhbHVlKGJ1ZmZlciwgcG9zKQorICAgICAgICAgIHZhbHVlLmFwcGVuZChlbGVtZW50KQorICAgICAgICAgICMgUHJlZGljdCB0aGF0IHRoZSBuZXh0IHRhZyBpcyBhbm90aGVyIGNvcHkgb2YgdGhlIHNhbWUgcmVwZWF0ZWQKKyAgICAgICAgICAjIGZpZWxkLgorICAgICAgICAgIHBvcyA9IG5ld19wb3MgKyB0YWdfbGVuCisgICAgICAgICAgaWYgYnVmZmVyW25ld19wb3M6cG9zXSAhPSB0YWdfYnl0ZXMgb3IgbmV3X3BvcyA+PSBlbmQ6CisgICAgICAgICAgICAjIFByZWRpY3Rpb24gZmFpbGVkLiAgUmV0dXJuLgorICAgICAgICAgICAgaWYgbmV3X3BvcyA+IGVuZDoKKyAgICAgICAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICAgICAgICAgICAgcmV0dXJuIG5ld19wb3MKKyAgICAgIHJldHVybiBEZWNvZGVSZXBlYXRlZEZpZWxkCisgICAgZWxzZToKKyAgICAgIGRlZiBEZWNvZGVGaWVsZChidWZmZXIsIHBvcywgZW5kLCBtZXNzYWdlLCBmaWVsZF9kaWN0KToKKyAgICAgICAgKGZpZWxkX2RpY3Rba2V5XSwgcG9zKSA9IGRlY29kZV92YWx1ZShidWZmZXIsIHBvcykKKyAgICAgICAgaWYgcG9zID4gZW5kOgorICAgICAgICAgIGRlbCBmaWVsZF9kaWN0W2tleV0gICMgRGlzY2FyZCBjb3JydXB0IHZhbHVlLgorICAgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVHJ1bmNhdGVkIG1lc3NhZ2UuJykKKyAgICAgICAgcmV0dXJuIHBvcworICAgICAgcmV0dXJuIERlY29kZUZpZWxkCisKKyAgcmV0dXJuIFNwZWNpZmljRGVjb2RlcgorCisKK2RlZiBfTW9kaWZpZWREZWNvZGVyKHdpcmVfdHlwZSwgZGVjb2RlX3ZhbHVlLCBtb2RpZnlfdmFsdWUpOgorICAiIiJMaWtlIFNpbXBsZURlY29kZXIgYnV0IGFkZGl0aW9uYWxseSBpbnZva2VzIG1vZGlmeV92YWx1ZSBvbiBldmVyeSB2YWx1ZQorICBiZWZvcmUgc3RvcmluZyBpdC4gIFVzdWFsbHkgbW9kaWZ5X3ZhbHVlIGlzIFppZ1phZ0RlY29kZS4KKyAgIiIiCisKKyAgIyBSZXVzaW5nIF9TaW1wbGVEZWNvZGVyIGlzIHNsaWdodGx5IHNsb3dlciB0aGFuIGNvcHlpbmcgYSBidW5jaCBvZiBjb2RlLCBidXQKKyAgIyBub3QgZW5vdWdoIHRvIG1ha2UgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlLgorCisgIGRlZiBJbm5lckRlY29kZShidWZmZXIsIHBvcyk6CisgICAgKHJlc3VsdCwgbmV3X3BvcykgPSBkZWNvZGVfdmFsdWUoYnVmZmVyLCBwb3MpCisgICAgcmV0dXJuIChtb2RpZnlfdmFsdWUocmVzdWx0KSwgbmV3X3BvcykKKyAgcmV0dXJuIF9TaW1wbGVEZWNvZGVyKHdpcmVfdHlwZSwgSW5uZXJEZWNvZGUpCisKKworZGVmIF9TdHJ1Y3RQYWNrRGVjb2Rlcih3aXJlX3R5cGUsIGZvcm1hdCk6CisgICIiIlJldHVybiBhIGNvbnN0cnVjdG9yIGZvciBhIGRlY29kZXIgZm9yIGEgZml4ZWQtd2lkdGggZmllbGQuCisKKyAgQXJnczoKKyAgICAgIHdpcmVfdHlwZTogIFRoZSBmaWVsZCdzIHdpcmUgdHlwZS4KKyAgICAgIGZvcm1hdDogIFRoZSBmb3JtYXQgc3RyaW5nIHRvIHBhc3MgdG8gc3RydWN0LnVucGFjaygpLgorICAiIiIKKworICB2YWx1ZV9zaXplID0gc3RydWN0LmNhbGNzaXplKGZvcm1hdCkKKyAgbG9jYWxfdW5wYWNrID0gc3RydWN0LnVucGFjaworCisgICMgUmV1c2luZyBfU2ltcGxlRGVjb2RlciBpcyBzbGlnaHRseSBzbG93ZXIgdGhhbiBjb3B5aW5nIGEgYnVuY2ggb2YgY29kZSwgYnV0CisgICMgbm90IGVub3VnaCB0byBtYWtlIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZS4KKworICAjIE5vdGUgdGhhdCB3ZSBleHBlY3Qgc29tZW9uZSB1cC1zdGFjayB0byBjYXRjaCBzdHJ1Y3QuZXJyb3IgYW5kIGNvbnZlcnQKKyAgIyBpdCB0byBfRGVjb2RlRXJyb3IgLS0gdGhpcyB3YXkgd2UgZG9uJ3QgaGF2ZSB0byBzZXQgdXAgZXhjZXB0aW9uLQorICAjIGhhbmRsaW5nIGJsb2NrcyBldmVyeSB0aW1lIHdlIHBhcnNlIG9uZSB2YWx1ZS4KKworICBkZWYgSW5uZXJEZWNvZGUoYnVmZmVyLCBwb3MpOgorICAgIG5ld19wb3MgPSBwb3MgKyB2YWx1ZV9zaXplCisgICAgcmVzdWx0ID0gbG9jYWxfdW5wYWNrKGZvcm1hdCwgYnVmZmVyW3BvczpuZXdfcG9zXSlbMF0KKyAgICByZXR1cm4gKHJlc3VsdCwgbmV3X3BvcykKKyAgcmV0dXJuIF9TaW1wbGVEZWNvZGVyKHdpcmVfdHlwZSwgSW5uZXJEZWNvZGUpCisKKworZGVmIF9GbG9hdERlY29kZXIoKToKKyAgIiIiUmV0dXJucyBhIGRlY29kZXIgZm9yIGEgZmxvYXQgZmllbGQuCisKKyAgVGhpcyBjb2RlIHdvcmtzIGFyb3VuZCBhIGJ1ZyBpbiBzdHJ1Y3QudW5wYWNrIGZvciBub24tZmluaXRlIDMyLWJpdAorICBmbG9hdGluZy1wb2ludCB2YWx1ZXMuCisgICIiIgorCisgIGxvY2FsX3VucGFjayA9IHN0cnVjdC51bnBhY2sKKyAgYiA9IChsYW1iZGEgeDp4KSBpZiBfUFkyIGVsc2UgbGFtYmRhIHg6eC5lbmNvZGUoJ2xhdGluMScpICAjI1BZMjUKKworICBkZWYgSW5uZXJEZWNvZGUoYnVmZmVyLCBwb3MpOgorICAgICMgV2UgZXhwZWN0IGEgMzItYml0IHZhbHVlIGluIGxpdHRsZS1lbmRpYW4gYnl0ZSBvcmRlci4gIEJpdCAxIGlzIHRoZSBzaWduCisgICAgIyBiaXQsIGJpdHMgMi05IHJlcHJlc2VudCB0aGUgZXhwb25lbnQsIGFuZCBiaXRzIDEwLTMyIGFyZSB0aGUgc2lnbmlmaWNhbmQuCisgICAgbmV3X3BvcyA9IHBvcyArIDQKKyAgICBmbG9hdF9ieXRlcyA9IGJ1ZmZlcltwb3M6bmV3X3Bvc10KKworICAgICMgSWYgdGhpcyB2YWx1ZSBoYXMgYWxsIGl0cyBleHBvbmVudCBiaXRzIHNldCwgdGhlbiBpdCdzIG5vbi1maW5pdGUuCisgICAgIyBJbiBQeXRob24gMi40LCBzdHJ1Y3QudW5wYWNrIHdpbGwgY29udmVydCBpdCB0byBhIGZpbml0ZSA2NC1iaXQgdmFsdWUuCisgICAgIyBUbyBhdm9pZCB0aGF0LCB3ZSBwYXJzZSBpdCBzcGVjaWFsbHkuCisgICAgaWYgKChmbG9hdF9ieXRlc1szOjRdIGluIGIoJ1x4N0ZceEZGJykpICAjI1BZMjUKKyMjIVBZMjUgICAgaWYgKChmbG9hdF9ieXRlc1szOjRdIGluIGInXHg3Rlx4RkYnKQorICAgICAgICBhbmQgKGZsb2F0X2J5dGVzWzI6M10gPj0gYignXHg4MCcpKSk6ICAjI1BZMjUKKyMjIVBZMjUgICAgICAgIGFuZCAoZmxvYXRfYnl0ZXNbMjozXSA+PSBiJ1x4ODAnKSk6CisgICAgICAjIElmIGF0IGxlYXN0IG9uZSBzaWduaWZpY2FuZCBiaXQgaXMgc2V0Li4uCisgICAgICBpZiBmbG9hdF9ieXRlc1swOjNdICE9IGIoJ1x4MDBceDAwXHg4MCcpOiAgIyNQWTI1CisjIyFQWTI1ICAgICAgaWYgZmxvYXRfYnl0ZXNbMDozXSAhPSBiJ1x4MDBceDAwXHg4MCc6CisgICAgICAgIHJldHVybiAoX05BTiwgbmV3X3BvcykKKyAgICAgICMgSWYgc2lnbiBiaXQgaXMgc2V0Li4uCisgICAgICBpZiBmbG9hdF9ieXRlc1szOjRdID09IGIoJ1x4RkYnKTogICMjUFkyNQorIyMhUFkyNSAgICAgIGlmIGZsb2F0X2J5dGVzWzM6NF0gPT0gYidceEZGJzoKKyAgICAgICAgcmV0dXJuIChfTkVHX0lORiwgbmV3X3BvcykKKyAgICAgIHJldHVybiAoX1BPU19JTkYsIG5ld19wb3MpCisKKyAgICAjIE5vdGUgdGhhdCB3ZSBleHBlY3Qgc29tZW9uZSB1cC1zdGFjayB0byBjYXRjaCBzdHJ1Y3QuZXJyb3IgYW5kIGNvbnZlcnQKKyAgICAjIGl0IHRvIF9EZWNvZGVFcnJvciAtLSB0aGlzIHdheSB3ZSBkb24ndCBoYXZlIHRvIHNldCB1cCBleGNlcHRpb24tCisgICAgIyBoYW5kbGluZyBibG9ja3MgZXZlcnkgdGltZSB3ZSBwYXJzZSBvbmUgdmFsdWUuCisgICAgcmVzdWx0ID0gbG9jYWxfdW5wYWNrKCc8ZicsIGZsb2F0X2J5dGVzKVswXQorICAgIHJldHVybiAocmVzdWx0LCBuZXdfcG9zKQorICByZXR1cm4gX1NpbXBsZURlY29kZXIod2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQzMiwgSW5uZXJEZWNvZGUpCisKKworZGVmIF9Eb3VibGVEZWNvZGVyKCk6CisgICIiIlJldHVybnMgYSBkZWNvZGVyIGZvciBhIGRvdWJsZSBmaWVsZC4KKworICBUaGlzIGNvZGUgd29ya3MgYXJvdW5kIGEgYnVnIGluIHN0cnVjdC51bnBhY2sgZm9yIG5vdC1hLW51bWJlci4KKyAgIiIiCisKKyAgbG9jYWxfdW5wYWNrID0gc3RydWN0LnVucGFjaworICBiID0gKGxhbWJkYSB4OngpIGlmIF9QWTIgZWxzZSBsYW1iZGEgeDp4LmVuY29kZSgnbGF0aW4xJykgICMjUFkyNQorCisgIGRlZiBJbm5lckRlY29kZShidWZmZXIsIHBvcyk6CisgICAgIyBXZSBleHBlY3QgYSA2NC1iaXQgdmFsdWUgaW4gbGl0dGxlLWVuZGlhbiBieXRlIG9yZGVyLiAgQml0IDEgaXMgdGhlIHNpZ24KKyAgICAjIGJpdCwgYml0cyAyLTEyIHJlcHJlc2VudCB0aGUgZXhwb25lbnQsIGFuZCBiaXRzIDEzLTY0IGFyZSB0aGUgc2lnbmlmaWNhbmQuCisgICAgbmV3X3BvcyA9IHBvcyArIDgKKyAgICBkb3VibGVfYnl0ZXMgPSBidWZmZXJbcG9zOm5ld19wb3NdCisKKyAgICAjIElmIHRoaXMgdmFsdWUgaGFzIGFsbCBpdHMgZXhwb25lbnQgYml0cyBzZXQgYW5kIGF0IGxlYXN0IG9uZSBzaWduaWZpY2FuZAorICAgICMgYml0IHNldCwgaXQncyBub3QgYSBudW1iZXIuICBJbiBQeXRob24gMi40LCBzdHJ1Y3QudW5wYWNrIHdpbGwgdHJlYXQgaXQKKyAgICAjIGFzIGluZiBvciAtaW5mLiAgVG8gYXZvaWQgdGhhdCwgd2UgdHJlYXQgaXQgc3BlY2lhbGx5LgorIyMhUFkyNSAgICBpZiAoKGRvdWJsZV9ieXRlc1s3OjhdIGluIGInXHg3Rlx4RkYnKQorIyMhUFkyNSAgICAgICAgYW5kIChkb3VibGVfYnl0ZXNbNjo3XSA+PSBiJ1x4RjAnKQorIyMhUFkyNSAgICAgICAgYW5kIChkb3VibGVfYnl0ZXNbMDo3XSAhPSBiJ1x4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4RjAnKSk6CisgICAgaWYgKChkb3VibGVfYnl0ZXNbNzo4XSBpbiBiKCdceDdGXHhGRicpKSAgIyNQWTI1CisgICAgICAgIGFuZCAoZG91YmxlX2J5dGVzWzY6N10gPj0gYignXHhGMCcpKSAgIyNQWTI1CisgICAgICAgIGFuZCAoZG91YmxlX2J5dGVzWzA6N10gIT0gYignXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhGMCcpKSk6ICAjI1BZMjUKKyAgICAgIHJldHVybiAoX05BTiwgbmV3X3BvcykKKworICAgICMgTm90ZSB0aGF0IHdlIGV4cGVjdCBzb21lb25lIHVwLXN0YWNrIHRvIGNhdGNoIHN0cnVjdC5lcnJvciBhbmQgY29udmVydAorICAgICMgaXQgdG8gX0RlY29kZUVycm9yIC0tIHRoaXMgd2F5IHdlIGRvbid0IGhhdmUgdG8gc2V0IHVwIGV4Y2VwdGlvbi0KKyAgICAjIGhhbmRsaW5nIGJsb2NrcyBldmVyeSB0aW1lIHdlIHBhcnNlIG9uZSB2YWx1ZS4KKyAgICByZXN1bHQgPSBsb2NhbF91bnBhY2soJzxkJywgZG91YmxlX2J5dGVzKVswXQorICAgIHJldHVybiAocmVzdWx0LCBuZXdfcG9zKQorICByZXR1cm4gX1NpbXBsZURlY29kZXIod2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQ2NCwgSW5uZXJEZWNvZGUpCisKKworZGVmIEVudW1EZWNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCwga2V5LCBuZXdfZGVmYXVsdCk6CisgIGVudW1fdHlwZSA9IGtleS5lbnVtX3R5cGUKKyAgaWYgaXNfcGFja2VkOgorICAgIGxvY2FsX0RlY29kZVZhcmludCA9IF9EZWNvZGVWYXJpbnQKKyAgICBkZWYgRGVjb2RlUGFja2VkRmllbGQoYnVmZmVyLCBwb3MsIGVuZCwgbWVzc2FnZSwgZmllbGRfZGljdCk6CisgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3QuZ2V0KGtleSkKKyAgICAgIGlmIHZhbHVlIGlzIE5vbmU6CisgICAgICAgIHZhbHVlID0gZmllbGRfZGljdC5zZXRkZWZhdWx0KGtleSwgbmV3X2RlZmF1bHQobWVzc2FnZSkpCisgICAgICAoZW5kcG9pbnQsIHBvcykgPSBsb2NhbF9EZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpCisgICAgICBlbmRwb2ludCArPSBwb3MKKyAgICAgIGlmIGVuZHBvaW50ID4gZW5kOgorICAgICAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1RydW5jYXRlZCBtZXNzYWdlLicpCisgICAgICB3aGlsZSBwb3MgPCBlbmRwb2ludDoKKyAgICAgICAgdmFsdWVfc3RhcnRfcG9zID0gcG9zCisgICAgICAgIChlbGVtZW50LCBwb3MpID0gX0RlY29kZVNpZ25lZFZhcmludDMyKGJ1ZmZlciwgcG9zKQorICAgICAgICBpZiBlbGVtZW50IGluIGVudW1fdHlwZS52YWx1ZXNfYnlfbnVtYmVyOgorICAgICAgICAgIHZhbHVlLmFwcGVuZChlbGVtZW50KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlmIG5vdCBtZXNzYWdlLl91bmtub3duX2ZpZWxkczoKKyAgICAgICAgICAgIG1lc3NhZ2UuX3Vua25vd25fZmllbGRzID0gW10KKyAgICAgICAgICB0YWdfYnl0ZXMgPSBlbmNvZGVyLlRhZ0J5dGVzKGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCkKKyAgICAgICAgICBtZXNzYWdlLl91bmtub3duX2ZpZWxkcy5hcHBlbmQoCisgICAgICAgICAgICAgICh0YWdfYnl0ZXMsIGJ1ZmZlclt2YWx1ZV9zdGFydF9wb3M6cG9zXSkpCisgICAgICBpZiBwb3MgPiBlbmRwb2ludDoKKyAgICAgICAgaWYgZWxlbWVudCBpbiBlbnVtX3R5cGUudmFsdWVzX2J5X251bWJlcjoKKyAgICAgICAgICBkZWwgdmFsdWVbLTFdICAgIyBEaXNjYXJkIGNvcnJ1cHQgdmFsdWUuCisgICAgICAgIGVsc2U6CisgICAgICAgICAgZGVsIG1lc3NhZ2UuX3Vua25vd25fZmllbGRzWy0xXQorICAgICAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1BhY2tlZCBlbGVtZW50IHdhcyB0cnVuY2F0ZWQuJykKKyAgICAgIHJldHVybiBwb3MKKyAgICByZXR1cm4gRGVjb2RlUGFja2VkRmllbGQKKyAgZWxpZiBpc19yZXBlYXRlZDoKKyAgICB0YWdfYnl0ZXMgPSBlbmNvZGVyLlRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5UKQorICAgIHRhZ19sZW4gPSBsZW4odGFnX2J5dGVzKQorICAgIGRlZiBEZWNvZGVSZXBlYXRlZEZpZWxkKGJ1ZmZlciwgcG9zLCBlbmQsIG1lc3NhZ2UsIGZpZWxkX2RpY3QpOgorICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LmdldChrZXkpCisgICAgICBpZiB2YWx1ZSBpcyBOb25lOgorICAgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3Quc2V0ZGVmYXVsdChrZXksIG5ld19kZWZhdWx0KG1lc3NhZ2UpKQorICAgICAgd2hpbGUgMToKKyAgICAgICAgKGVsZW1lbnQsIG5ld19wb3MpID0gX0RlY29kZVNpZ25lZFZhcmludDMyKGJ1ZmZlciwgcG9zKQorICAgICAgICBpZiBlbGVtZW50IGluIGVudW1fdHlwZS52YWx1ZXNfYnlfbnVtYmVyOgorICAgICAgICAgIHZhbHVlLmFwcGVuZChlbGVtZW50KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlmIG5vdCBtZXNzYWdlLl91bmtub3duX2ZpZWxkczoKKyAgICAgICAgICAgIG1lc3NhZ2UuX3Vua25vd25fZmllbGRzID0gW10KKyAgICAgICAgICBtZXNzYWdlLl91bmtub3duX2ZpZWxkcy5hcHBlbmQoCisgICAgICAgICAgICAgICh0YWdfYnl0ZXMsIGJ1ZmZlcltwb3M6bmV3X3Bvc10pKQorICAgICAgICAjIFByZWRpY3QgdGhhdCB0aGUgbmV4dCB0YWcgaXMgYW5vdGhlciBjb3B5IG9mIHRoZSBzYW1lIHJlcGVhdGVkCisgICAgICAgICMgZmllbGQuCisgICAgICAgIHBvcyA9IG5ld19wb3MgKyB0YWdfbGVuCisgICAgICAgIGlmIGJ1ZmZlcltuZXdfcG9zOnBvc10gIT0gdGFnX2J5dGVzIG9yIG5ld19wb3MgPj0gZW5kOgorICAgICAgICAgICMgUHJlZGljdGlvbiBmYWlsZWQuICBSZXR1cm4uCisgICAgICAgICAgaWYgbmV3X3BvcyA+IGVuZDoKKyAgICAgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVHJ1bmNhdGVkIG1lc3NhZ2UuJykKKyAgICAgICAgICByZXR1cm4gbmV3X3BvcworICAgIHJldHVybiBEZWNvZGVSZXBlYXRlZEZpZWxkCisgIGVsc2U6CisgICAgZGVmIERlY29kZUZpZWxkKGJ1ZmZlciwgcG9zLCBlbmQsIG1lc3NhZ2UsIGZpZWxkX2RpY3QpOgorICAgICAgdmFsdWVfc3RhcnRfcG9zID0gcG9zCisgICAgICAoZW51bV92YWx1ZSwgcG9zKSA9IF9EZWNvZGVTaWduZWRWYXJpbnQzMihidWZmZXIsIHBvcykKKyAgICAgIGlmIHBvcyA+IGVuZDoKKyAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICAgICAgaWYgZW51bV92YWx1ZSBpbiBlbnVtX3R5cGUudmFsdWVzX2J5X251bWJlcjoKKyAgICAgICAgZmllbGRfZGljdFtrZXldID0gZW51bV92YWx1ZQorICAgICAgZWxzZToKKyAgICAgICAgaWYgbm90IG1lc3NhZ2UuX3Vua25vd25fZmllbGRzOgorICAgICAgICAgIG1lc3NhZ2UuX3Vua25vd25fZmllbGRzID0gW10KKyAgICAgICAgdGFnX2J5dGVzID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5UKQorICAgICAgICBtZXNzYWdlLl91bmtub3duX2ZpZWxkcy5hcHBlbmQoCisgICAgICAgICAgKHRhZ19ieXRlcywgYnVmZmVyW3ZhbHVlX3N0YXJ0X3Bvczpwb3NdKSkKKyAgICAgIHJldHVybiBwb3MKKyAgICByZXR1cm4gRGVjb2RlRmllbGQKKworCisjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworSW50MzJEZWNvZGVyID0gX1NpbXBsZURlY29kZXIoCisgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5ULCBfRGVjb2RlU2lnbmVkVmFyaW50MzIpCisKK0ludDY0RGVjb2RlciA9IF9TaW1wbGVEZWNvZGVyKAorICAgIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwgX0RlY29kZVNpZ25lZFZhcmludCkKKworVUludDMyRGVjb2RlciA9IF9TaW1wbGVEZWNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwgX0RlY29kZVZhcmludDMyKQorVUludDY0RGVjb2RlciA9IF9TaW1wbGVEZWNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwgX0RlY29kZVZhcmludCkKKworU0ludDMyRGVjb2RlciA9IF9Nb2RpZmllZERlY29kZXIoCisgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5ULCBfRGVjb2RlVmFyaW50MzIsIHdpcmVfZm9ybWF0LlppZ1phZ0RlY29kZSkKK1NJbnQ2NERlY29kZXIgPSBfTW9kaWZpZWREZWNvZGVyKAorICAgIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwgX0RlY29kZVZhcmludCwgd2lyZV9mb3JtYXQuWmlnWmFnRGVjb2RlKQorCisjIE5vdGUgdGhhdCBQeXRob24gY29udmVuaWVudGx5IGd1YXJhbnRlZXMgdGhhdCB3aGVuIHVzaW5nIHRoZSAnPCcgcHJlZml4IG9uCisjIGZvcm1hdHMsIHRoZXkgd2lsbCBhbHNvIGhhdmUgdGhlIHNhbWUgc2l6ZSBhY3Jvc3MgYWxsIHBsYXRmb3JtcyAoYXMgb3Bwb3NlZAorIyB0byB3aXRob3V0IHRoZSBwcmVmaXgsIHdoZXJlIHRoZWlyIHNpemVzIGRlcGVuZCBvbiB0aGUgQyBjb21waWxlcidzIGJhc2ljCisjIHR5cGUgc2l6ZXMpLgorRml4ZWQzMkRlY29kZXIgID0gX1N0cnVjdFBhY2tEZWNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVEMzIsICc8SScpCitGaXhlZDY0RGVjb2RlciAgPSBfU3RydWN0UGFja0RlY29kZXIod2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQ2NCwgJzxRJykKK1NGaXhlZDMyRGVjb2RlciA9IF9TdHJ1Y3RQYWNrRGVjb2Rlcih3aXJlX2Zvcm1hdC5XSVJFVFlQRV9GSVhFRDMyLCAnPGknKQorU0ZpeGVkNjREZWNvZGVyID0gX1N0cnVjdFBhY2tEZWNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVENjQsICc8cScpCitGbG9hdERlY29kZXIgPSBfRmxvYXREZWNvZGVyKCkKK0RvdWJsZURlY29kZXIgPSBfRG91YmxlRGVjb2RlcigpCisKK0Jvb2xEZWNvZGVyID0gX01vZGlmaWVkRGVjb2RlcigKKyAgICB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQsIF9EZWNvZGVWYXJpbnQsIGJvb2wpCisKKworZGVmIFN0cmluZ0RlY29kZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkLCBrZXksIG5ld19kZWZhdWx0KToKKyAgIiIiUmV0dXJucyBhIGRlY29kZXIgZm9yIGEgc3RyaW5nIGZpZWxkLiIiIgorCisgIGxvY2FsX0RlY29kZVZhcmludCA9IF9EZWNvZGVWYXJpbnQKKyAgbG9jYWxfdW5pY29kZSA9IHVuaWNvZGUKKworICBkZWYgX0NvbnZlcnRUb1VuaWNvZGUoYnl0ZV9zdHIpOgorICAgIHRyeToKKyAgICAgIHJldHVybiBsb2NhbF91bmljb2RlKGJ5dGVfc3RyLCAndXRmLTgnKQorICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3IsIGU6CisgICAgICAjIGFkZCBtb3JlIGluZm9ybWF0aW9uIHRvIHRoZSBlcnJvciBtZXNzYWdlIGFuZCByZS1yYWlzZSBpdC4KKyAgICAgIGUucmVhc29uID0gJyVzIGluIGZpZWxkOiAlcycgJSAoZSwga2V5LmZ1bGxfbmFtZSkKKyAgICAgIHJhaXNlCisKKyAgYXNzZXJ0IG5vdCBpc19wYWNrZWQKKyAgaWYgaXNfcmVwZWF0ZWQ6CisgICAgdGFnX2J5dGVzID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKQorICAgIHRhZ19sZW4gPSBsZW4odGFnX2J5dGVzKQorICAgIGRlZiBEZWNvZGVSZXBlYXRlZEZpZWxkKGJ1ZmZlciwgcG9zLCBlbmQsIG1lc3NhZ2UsIGZpZWxkX2RpY3QpOgorICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LmdldChrZXkpCisgICAgICBpZiB2YWx1ZSBpcyBOb25lOgorICAgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3Quc2V0ZGVmYXVsdChrZXksIG5ld19kZWZhdWx0KG1lc3NhZ2UpKQorICAgICAgd2hpbGUgMToKKyAgICAgICAgKHNpemUsIHBvcykgPSBsb2NhbF9EZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpCisgICAgICAgIG5ld19wb3MgPSBwb3MgKyBzaXplCisgICAgICAgIGlmIG5ld19wb3MgPiBlbmQ6CisgICAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgc3RyaW5nLicpCisgICAgICAgIHZhbHVlLmFwcGVuZChfQ29udmVydFRvVW5pY29kZShidWZmZXJbcG9zOm5ld19wb3NdKSkKKyAgICAgICAgIyBQcmVkaWN0IHRoYXQgdGhlIG5leHQgdGFnIGlzIGFub3RoZXIgY29weSBvZiB0aGUgc2FtZSByZXBlYXRlZCBmaWVsZC4KKyAgICAgICAgcG9zID0gbmV3X3BvcyArIHRhZ19sZW4KKyAgICAgICAgaWYgYnVmZmVyW25ld19wb3M6cG9zXSAhPSB0YWdfYnl0ZXMgb3IgbmV3X3BvcyA9PSBlbmQ6CisgICAgICAgICAgIyBQcmVkaWN0aW9uIGZhaWxlZC4gIFJldHVybi4KKyAgICAgICAgICByZXR1cm4gbmV3X3BvcworICAgIHJldHVybiBEZWNvZGVSZXBlYXRlZEZpZWxkCisgIGVsc2U6CisgICAgZGVmIERlY29kZUZpZWxkKGJ1ZmZlciwgcG9zLCBlbmQsIG1lc3NhZ2UsIGZpZWxkX2RpY3QpOgorICAgICAgKHNpemUsIHBvcykgPSBsb2NhbF9EZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpCisgICAgICBuZXdfcG9zID0gcG9zICsgc2l6ZQorICAgICAgaWYgbmV3X3BvcyA+IGVuZDoKKyAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgc3RyaW5nLicpCisgICAgICBmaWVsZF9kaWN0W2tleV0gPSBfQ29udmVydFRvVW5pY29kZShidWZmZXJbcG9zOm5ld19wb3NdKQorICAgICAgcmV0dXJuIG5ld19wb3MKKyAgICByZXR1cm4gRGVjb2RlRmllbGQKKworCitkZWYgQnl0ZXNEZWNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCwga2V5LCBuZXdfZGVmYXVsdCk6CisgICIiIlJldHVybnMgYSBkZWNvZGVyIGZvciBhIGJ5dGVzIGZpZWxkLiIiIgorCisgIGxvY2FsX0RlY29kZVZhcmludCA9IF9EZWNvZGVWYXJpbnQKKworICBhc3NlcnQgbm90IGlzX3BhY2tlZAorICBpZiBpc19yZXBlYXRlZDoKKyAgICB0YWdfYnl0ZXMgPSBlbmNvZGVyLlRhZ0J5dGVzKGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpCisgICAgdGFnX2xlbiA9IGxlbih0YWdfYnl0ZXMpCisgICAgZGVmIERlY29kZVJlcGVhdGVkRmllbGQoYnVmZmVyLCBwb3MsIGVuZCwgbWVzc2FnZSwgZmllbGRfZGljdCk6CisgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3QuZ2V0KGtleSkKKyAgICAgIGlmIHZhbHVlIGlzIE5vbmU6CisgICAgICAgIHZhbHVlID0gZmllbGRfZGljdC5zZXRkZWZhdWx0KGtleSwgbmV3X2RlZmF1bHQobWVzc2FnZSkpCisgICAgICB3aGlsZSAxOgorICAgICAgICAoc2l6ZSwgcG9zKSA9IGxvY2FsX0RlY29kZVZhcmludChidWZmZXIsIHBvcykKKyAgICAgICAgbmV3X3BvcyA9IHBvcyArIHNpemUKKyAgICAgICAgaWYgbmV3X3BvcyA+IGVuZDoKKyAgICAgICAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1RydW5jYXRlZCBzdHJpbmcuJykKKyAgICAgICAgdmFsdWUuYXBwZW5kKGJ1ZmZlcltwb3M6bmV3X3Bvc10pCisgICAgICAgICMgUHJlZGljdCB0aGF0IHRoZSBuZXh0IHRhZyBpcyBhbm90aGVyIGNvcHkgb2YgdGhlIHNhbWUgcmVwZWF0ZWQgZmllbGQuCisgICAgICAgIHBvcyA9IG5ld19wb3MgKyB0YWdfbGVuCisgICAgICAgIGlmIGJ1ZmZlcltuZXdfcG9zOnBvc10gIT0gdGFnX2J5dGVzIG9yIG5ld19wb3MgPT0gZW5kOgorICAgICAgICAgICMgUHJlZGljdGlvbiBmYWlsZWQuICBSZXR1cm4uCisgICAgICAgICAgcmV0dXJuIG5ld19wb3MKKyAgICByZXR1cm4gRGVjb2RlUmVwZWF0ZWRGaWVsZAorICBlbHNlOgorICAgIGRlZiBEZWNvZGVGaWVsZChidWZmZXIsIHBvcywgZW5kLCBtZXNzYWdlLCBmaWVsZF9kaWN0KToKKyAgICAgIChzaXplLCBwb3MpID0gbG9jYWxfRGVjb2RlVmFyaW50KGJ1ZmZlciwgcG9zKQorICAgICAgbmV3X3BvcyA9IHBvcyArIHNpemUKKyAgICAgIGlmIG5ld19wb3MgPiBlbmQ6CisgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVHJ1bmNhdGVkIHN0cmluZy4nKQorICAgICAgZmllbGRfZGljdFtrZXldID0gYnVmZmVyW3BvczpuZXdfcG9zXQorICAgICAgcmV0dXJuIG5ld19wb3MKKyAgICByZXR1cm4gRGVjb2RlRmllbGQKKworCitkZWYgR3JvdXBEZWNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCwga2V5LCBuZXdfZGVmYXVsdCk6CisgICIiIlJldHVybnMgYSBkZWNvZGVyIGZvciBhIGdyb3VwIGZpZWxkLiIiIgorCisgIGVuZF90YWdfYnl0ZXMgPSBlbmNvZGVyLlRhZ0J5dGVzKGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKQorICBlbmRfdGFnX2xlbiA9IGxlbihlbmRfdGFnX2J5dGVzKQorCisgIGFzc2VydCBub3QgaXNfcGFja2VkCisgIGlmIGlzX3JlcGVhdGVkOgorICAgIHRhZ19ieXRlcyA9IGVuY29kZXIuVGFnQnl0ZXMoZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfU1RBUlRfR1JPVVApCisgICAgdGFnX2xlbiA9IGxlbih0YWdfYnl0ZXMpCisgICAgZGVmIERlY29kZVJlcGVhdGVkRmllbGQoYnVmZmVyLCBwb3MsIGVuZCwgbWVzc2FnZSwgZmllbGRfZGljdCk6CisgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3QuZ2V0KGtleSkKKyAgICAgIGlmIHZhbHVlIGlzIE5vbmU6CisgICAgICAgIHZhbHVlID0gZmllbGRfZGljdC5zZXRkZWZhdWx0KGtleSwgbmV3X2RlZmF1bHQobWVzc2FnZSkpCisgICAgICB3aGlsZSAxOgorICAgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3QuZ2V0KGtleSkKKyAgICAgICAgaWYgdmFsdWUgaXMgTm9uZToKKyAgICAgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3Quc2V0ZGVmYXVsdChrZXksIG5ld19kZWZhdWx0KG1lc3NhZ2UpKQorICAgICAgICAjIFJlYWQgc3ViLW1lc3NhZ2UuCisgICAgICAgIHBvcyA9IHZhbHVlLmFkZCgpLl9JbnRlcm5hbFBhcnNlKGJ1ZmZlciwgcG9zLCBlbmQpCisgICAgICAgICMgUmVhZCBlbmQgdGFnLgorICAgICAgICBuZXdfcG9zID0gcG9zK2VuZF90YWdfbGVuCisgICAgICAgIGlmIGJ1ZmZlcltwb3M6bmV3X3Bvc10gIT0gZW5kX3RhZ19ieXRlcyBvciBuZXdfcG9zID4gZW5kOgorICAgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignTWlzc2luZyBncm91cCBlbmQgdGFnLicpCisgICAgICAgICMgUHJlZGljdCB0aGF0IHRoZSBuZXh0IHRhZyBpcyBhbm90aGVyIGNvcHkgb2YgdGhlIHNhbWUgcmVwZWF0ZWQgZmllbGQuCisgICAgICAgIHBvcyA9IG5ld19wb3MgKyB0YWdfbGVuCisgICAgICAgIGlmIGJ1ZmZlcltuZXdfcG9zOnBvc10gIT0gdGFnX2J5dGVzIG9yIG5ld19wb3MgPT0gZW5kOgorICAgICAgICAgICMgUHJlZGljdGlvbiBmYWlsZWQuICBSZXR1cm4uCisgICAgICAgICAgcmV0dXJuIG5ld19wb3MKKyAgICByZXR1cm4gRGVjb2RlUmVwZWF0ZWRGaWVsZAorICBlbHNlOgorICAgIGRlZiBEZWNvZGVGaWVsZChidWZmZXIsIHBvcywgZW5kLCBtZXNzYWdlLCBmaWVsZF9kaWN0KToKKyAgICAgIHZhbHVlID0gZmllbGRfZGljdC5nZXQoa2V5KQorICAgICAgaWYgdmFsdWUgaXMgTm9uZToKKyAgICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LnNldGRlZmF1bHQoa2V5LCBuZXdfZGVmYXVsdChtZXNzYWdlKSkKKyAgICAgICMgUmVhZCBzdWItbWVzc2FnZS4KKyAgICAgIHBvcyA9IHZhbHVlLl9JbnRlcm5hbFBhcnNlKGJ1ZmZlciwgcG9zLCBlbmQpCisgICAgICAjIFJlYWQgZW5kIHRhZy4KKyAgICAgIG5ld19wb3MgPSBwb3MrZW5kX3RhZ19sZW4KKyAgICAgIGlmIGJ1ZmZlcltwb3M6bmV3X3Bvc10gIT0gZW5kX3RhZ19ieXRlcyBvciBuZXdfcG9zID4gZW5kOgorICAgICAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ01pc3NpbmcgZ3JvdXAgZW5kIHRhZy4nKQorICAgICAgcmV0dXJuIG5ld19wb3MKKyAgICByZXR1cm4gRGVjb2RlRmllbGQKKworCitkZWYgTWVzc2FnZURlY29kZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkLCBrZXksIG5ld19kZWZhdWx0KToKKyAgIiIiUmV0dXJucyBhIGRlY29kZXIgZm9yIGEgbWVzc2FnZSBmaWVsZC4iIiIKKworICBsb2NhbF9EZWNvZGVWYXJpbnQgPSBfRGVjb2RlVmFyaW50CisKKyAgYXNzZXJ0IG5vdCBpc19wYWNrZWQKKyAgaWYgaXNfcmVwZWF0ZWQ6CisgICAgdGFnX2J5dGVzID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKQorICAgIHRhZ19sZW4gPSBsZW4odGFnX2J5dGVzKQorICAgIGRlZiBEZWNvZGVSZXBlYXRlZEZpZWxkKGJ1ZmZlciwgcG9zLCBlbmQsIG1lc3NhZ2UsIGZpZWxkX2RpY3QpOgorICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LmdldChrZXkpCisgICAgICBpZiB2YWx1ZSBpcyBOb25lOgorICAgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3Quc2V0ZGVmYXVsdChrZXksIG5ld19kZWZhdWx0KG1lc3NhZ2UpKQorICAgICAgd2hpbGUgMToKKyAgICAgICAgIyBSZWFkIGxlbmd0aC4KKyAgICAgICAgKHNpemUsIHBvcykgPSBsb2NhbF9EZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpCisgICAgICAgIG5ld19wb3MgPSBwb3MgKyBzaXplCisgICAgICAgIGlmIG5ld19wb3MgPiBlbmQ6CisgICAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICAgICAgICAjIFJlYWQgc3ViLW1lc3NhZ2UuCisgICAgICAgIGlmIHZhbHVlLmFkZCgpLl9JbnRlcm5hbFBhcnNlKGJ1ZmZlciwgcG9zLCBuZXdfcG9zKSAhPSBuZXdfcG9zOgorICAgICAgICAgICMgVGhlIG9ubHkgcmVhc29uIF9JbnRlcm5hbFBhcnNlIHdvdWxkIHJldHVybiBlYXJseSBpcyBpZiBpdAorICAgICAgICAgICMgZW5jb3VudGVyZWQgYW4gZW5kLWdyb3VwIHRhZy4KKyAgICAgICAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1VuZXhwZWN0ZWQgZW5kLWdyb3VwIHRhZy4nKQorICAgICAgICAjIFByZWRpY3QgdGhhdCB0aGUgbmV4dCB0YWcgaXMgYW5vdGhlciBjb3B5IG9mIHRoZSBzYW1lIHJlcGVhdGVkIGZpZWxkLgorICAgICAgICBwb3MgPSBuZXdfcG9zICsgdGFnX2xlbgorICAgICAgICBpZiBidWZmZXJbbmV3X3Bvczpwb3NdICE9IHRhZ19ieXRlcyBvciBuZXdfcG9zID09IGVuZDoKKyAgICAgICAgICAjIFByZWRpY3Rpb24gZmFpbGVkLiAgUmV0dXJuLgorICAgICAgICAgIHJldHVybiBuZXdfcG9zCisgICAgcmV0dXJuIERlY29kZVJlcGVhdGVkRmllbGQKKyAgZWxzZToKKyAgICBkZWYgRGVjb2RlRmllbGQoYnVmZmVyLCBwb3MsIGVuZCwgbWVzc2FnZSwgZmllbGRfZGljdCk6CisgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3QuZ2V0KGtleSkKKyAgICAgIGlmIHZhbHVlIGlzIE5vbmU6CisgICAgICAgIHZhbHVlID0gZmllbGRfZGljdC5zZXRkZWZhdWx0KGtleSwgbmV3X2RlZmF1bHQobWVzc2FnZSkpCisgICAgICAjIFJlYWQgbGVuZ3RoLgorICAgICAgKHNpemUsIHBvcykgPSBsb2NhbF9EZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpCisgICAgICBuZXdfcG9zID0gcG9zICsgc2l6ZQorICAgICAgaWYgbmV3X3BvcyA+IGVuZDoKKyAgICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICAgICAgIyBSZWFkIHN1Yi1tZXNzYWdlLgorICAgICAgaWYgdmFsdWUuX0ludGVybmFsUGFyc2UoYnVmZmVyLCBwb3MsIG5ld19wb3MpICE9IG5ld19wb3M6CisgICAgICAgICMgVGhlIG9ubHkgcmVhc29uIF9JbnRlcm5hbFBhcnNlIHdvdWxkIHJldHVybiBlYXJseSBpcyBpZiBpdCBlbmNvdW50ZXJlZAorICAgICAgICAjIGFuIGVuZC1ncm91cCB0YWcuCisgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVW5leHBlY3RlZCBlbmQtZ3JvdXAgdGFnLicpCisgICAgICByZXR1cm4gbmV3X3BvcworICAgIHJldHVybiBEZWNvZGVGaWVsZAorCisKKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTUVTU0FHRV9TRVRfSVRFTV9UQUcgPSBlbmNvZGVyLlRhZ0J5dGVzKDEsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQKQorCitkZWYgTWVzc2FnZVNldEl0ZW1EZWNvZGVyKGV4dGVuc2lvbnNfYnlfbnVtYmVyKToKKyAgIiIiUmV0dXJucyBhIGRlY29kZXIgZm9yIGEgTWVzc2FnZVNldCBpdGVtLgorCisgIFRoZSBwYXJhbWV0ZXIgaXMgdGhlIF9leHRlbnNpb25zX2J5X251bWJlciBtYXAgZm9yIHRoZSBtZXNzYWdlIGNsYXNzLgorCisgIFRoZSBtZXNzYWdlIHNldCBtZXNzYWdlIGxvb2tzIGxpa2UgdGhpczoKKyAgICBtZXNzYWdlIE1lc3NhZ2VTZXQgeworICAgICAgcmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeworICAgICAgICByZXF1aXJlZCBpbnQzMiB0eXBlX2lkID0gMjsKKyAgICAgICAgcmVxdWlyZWQgc3RyaW5nIG1lc3NhZ2UgPSAzOworICAgICAgfQorICAgIH0KKyAgIiIiCisKKyAgdHlwZV9pZF90YWdfYnl0ZXMgPSBlbmNvZGVyLlRhZ0J5dGVzKDIsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCkKKyAgbWVzc2FnZV90YWdfYnl0ZXMgPSBlbmNvZGVyLlRhZ0J5dGVzKDMsIHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpCisgIGl0ZW1fZW5kX3RhZ19ieXRlcyA9IGVuY29kZXIuVGFnQnl0ZXMoMSwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKQorCisgIGxvY2FsX1JlYWRUYWcgPSBSZWFkVGFnCisgIGxvY2FsX0RlY29kZVZhcmludCA9IF9EZWNvZGVWYXJpbnQKKyAgbG9jYWxfU2tpcEZpZWxkID0gU2tpcEZpZWxkCisKKyAgZGVmIERlY29kZUl0ZW0oYnVmZmVyLCBwb3MsIGVuZCwgbWVzc2FnZSwgZmllbGRfZGljdCk6CisgICAgbWVzc2FnZV9zZXRfaXRlbV9zdGFydCA9IHBvcworICAgIHR5cGVfaWQgPSAtMQorICAgIG1lc3NhZ2Vfc3RhcnQgPSAtMQorICAgIG1lc3NhZ2VfZW5kID0gLTEKKworICAgICMgVGVjaG5pY2FsbHksIHR5cGVfaWQgYW5kIG1lc3NhZ2UgY2FuIGFwcGVhciBpbiBhbnkgb3JkZXIsIHNvIHdlIG5lZWQKKyAgICAjIGEgbGl0dGxlIGxvb3AgaGVyZS4KKyAgICB3aGlsZSAxOgorICAgICAgKHRhZ19ieXRlcywgcG9zKSA9IGxvY2FsX1JlYWRUYWcoYnVmZmVyLCBwb3MpCisgICAgICBpZiB0YWdfYnl0ZXMgPT0gdHlwZV9pZF90YWdfYnl0ZXM6CisgICAgICAgICh0eXBlX2lkLCBwb3MpID0gbG9jYWxfRGVjb2RlVmFyaW50KGJ1ZmZlciwgcG9zKQorICAgICAgZWxpZiB0YWdfYnl0ZXMgPT0gbWVzc2FnZV90YWdfYnl0ZXM6CisgICAgICAgIChzaXplLCBtZXNzYWdlX3N0YXJ0KSA9IGxvY2FsX0RlY29kZVZhcmludChidWZmZXIsIHBvcykKKyAgICAgICAgcG9zID0gbWVzc2FnZV9lbmQgPSBtZXNzYWdlX3N0YXJ0ICsgc2l6ZQorICAgICAgZWxpZiB0YWdfYnl0ZXMgPT0gaXRlbV9lbmRfdGFnX2J5dGVzOgorICAgICAgICBicmVhaworICAgICAgZWxzZToKKyAgICAgICAgcG9zID0gU2tpcEZpZWxkKGJ1ZmZlciwgcG9zLCBlbmQsIHRhZ19ieXRlcykKKyAgICAgICAgaWYgcG9zID09IC0xOgorICAgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignTWlzc2luZyBncm91cCBlbmQgdGFnLicpCisKKyAgICBpZiBwb3MgPiBlbmQ6CisgICAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1RydW5jYXRlZCBtZXNzYWdlLicpCisKKyAgICBpZiB0eXBlX2lkID09IC0xOgorICAgICAgcmFpc2UgX0RlY29kZUVycm9yKCdNZXNzYWdlU2V0IGl0ZW0gbWlzc2luZyB0eXBlX2lkLicpCisgICAgaWYgbWVzc2FnZV9zdGFydCA9PSAtMToKKyAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignTWVzc2FnZVNldCBpdGVtIG1pc3NpbmcgbWVzc2FnZS4nKQorCisgICAgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc19ieV9udW1iZXIuZ2V0KHR5cGVfaWQpCisgICAgaWYgZXh0ZW5zaW9uIGlzIG5vdCBOb25lOgorICAgICAgdmFsdWUgPSBmaWVsZF9kaWN0LmdldChleHRlbnNpb24pCisgICAgICBpZiB2YWx1ZSBpcyBOb25lOgorICAgICAgICB2YWx1ZSA9IGZpZWxkX2RpY3Quc2V0ZGVmYXVsdCgKKyAgICAgICAgICAgIGV4dGVuc2lvbiwgZXh0ZW5zaW9uLm1lc3NhZ2VfdHlwZS5fY29uY3JldGVfY2xhc3MoKSkKKyAgICAgIGlmIHZhbHVlLl9JbnRlcm5hbFBhcnNlKGJ1ZmZlciwgbWVzc2FnZV9zdGFydCxtZXNzYWdlX2VuZCkgIT0gbWVzc2FnZV9lbmQ6CisgICAgICAgICMgVGhlIG9ubHkgcmVhc29uIF9JbnRlcm5hbFBhcnNlIHdvdWxkIHJldHVybiBlYXJseSBpcyBpZiBpdCBlbmNvdW50ZXJlZAorICAgICAgICAjIGFuIGVuZC1ncm91cCB0YWcuCisgICAgICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVW5leHBlY3RlZCBlbmQtZ3JvdXAgdGFnLicpCisgICAgZWxzZToKKyAgICAgIGlmIG5vdCBtZXNzYWdlLl91bmtub3duX2ZpZWxkczoKKyAgICAgICAgbWVzc2FnZS5fdW5rbm93bl9maWVsZHMgPSBbXQorICAgICAgbWVzc2FnZS5fdW5rbm93bl9maWVsZHMuYXBwZW5kKChNRVNTQUdFX1NFVF9JVEVNX1RBRywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyW21lc3NhZ2Vfc2V0X2l0ZW1fc3RhcnQ6cG9zXSkpCisKKyAgICByZXR1cm4gcG9zCisKKyAgcmV0dXJuIERlY29kZUl0ZW0KKworIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBPcHRpbWl6YXRpb24gaXMgbm90IGFzIGhlYXZ5IGhlcmUgYmVjYXVzZSBjYWxscyB0byBTa2lwRmllbGQoKSBhcmUgcmFyZSwKKyMgZXhjZXB0IGZvciBoYW5kbGluZyBlbmQtZ3JvdXAgdGFncy4KKworZGVmIF9Ta2lwVmFyaW50KGJ1ZmZlciwgcG9zLCBlbmQpOgorICAiIiJTa2lwIGEgdmFyaW50IHZhbHVlLiAgUmV0dXJucyB0aGUgbmV3IHBvc2l0aW9uLiIiIgorICAjIFByZXZpb3VzbHkgb3JkKGJ1ZmZlcltwb3NdKSByYWlzZWQgSW5kZXhFcnJvciB3aGVuIHBvcyBpcyBvdXQgb2YgcmFuZ2UuCisgICMgV2l0aCB0aGlzIGNvZGUsIG9yZChiJycpIHJhaXNlcyBUeXBlRXJyb3IuICBCb3RoIGFyZSBoYW5kbGVkIGluCisgICMgcHl0aG9uX21lc3NhZ2UucHkgdG8gZ2VuZXJhdGUgYSAnVHJ1bmNhdGVkIG1lc3NhZ2UnIGVycm9yLgorICB3aGlsZSBvcmQoYnVmZmVyW3Bvczpwb3MrMV0pICYgMHg4MDoKKyAgICBwb3MgKz0gMQorICBwb3MgKz0gMQorICBpZiBwb3MgPiBlbmQ6CisgICAgcmFpc2UgX0RlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICByZXR1cm4gcG9zCisKK2RlZiBfU2tpcEZpeGVkNjQoYnVmZmVyLCBwb3MsIGVuZCk6CisgICIiIlNraXAgYSBmaXhlZDY0IHZhbHVlLiAgUmV0dXJucyB0aGUgbmV3IHBvc2l0aW9uLiIiIgorCisgIHBvcyArPSA4CisgIGlmIHBvcyA+IGVuZDoKKyAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1RydW5jYXRlZCBtZXNzYWdlLicpCisgIHJldHVybiBwb3MKKworZGVmIF9Ta2lwTGVuZ3RoRGVsaW1pdGVkKGJ1ZmZlciwgcG9zLCBlbmQpOgorICAiIiJTa2lwIGEgbGVuZ3RoLWRlbGltaXRlZCB2YWx1ZS4gIFJldHVybnMgdGhlIG5ldyBwb3NpdGlvbi4iIiIKKworICAoc2l6ZSwgcG9zKSA9IF9EZWNvZGVWYXJpbnQoYnVmZmVyLCBwb3MpCisgIHBvcyArPSBzaXplCisgIGlmIHBvcyA+IGVuZDoKKyAgICByYWlzZSBfRGVjb2RlRXJyb3IoJ1RydW5jYXRlZCBtZXNzYWdlLicpCisgIHJldHVybiBwb3MKKworZGVmIF9Ta2lwR3JvdXAoYnVmZmVyLCBwb3MsIGVuZCk6CisgICIiIlNraXAgc3ViLWdyb3VwLiAgUmV0dXJucyB0aGUgbmV3IHBvc2l0aW9uLiIiIgorCisgIHdoaWxlIDE6CisgICAgKHRhZ19ieXRlcywgcG9zKSA9IFJlYWRUYWcoYnVmZmVyLCBwb3MpCisgICAgbmV3X3BvcyA9IFNraXBGaWVsZChidWZmZXIsIHBvcywgZW5kLCB0YWdfYnl0ZXMpCisgICAgaWYgbmV3X3BvcyA9PSAtMToKKyAgICAgIHJldHVybiBwb3MKKyAgICBwb3MgPSBuZXdfcG9zCisKK2RlZiBfRW5kR3JvdXAoYnVmZmVyLCBwb3MsIGVuZCk6CisgICIiIlNraXBwaW5nIGFuIEVORF9HUk9VUCB0YWcgcmV0dXJucyAtMSB0byB0ZWxsIHRoZSBwYXJlbnQgbG9vcCB0byBicmVhay4iIiIKKworICByZXR1cm4gLTEKKworZGVmIF9Ta2lwRml4ZWQzMihidWZmZXIsIHBvcywgZW5kKToKKyAgIiIiU2tpcCBhIGZpeGVkMzIgdmFsdWUuICBSZXR1cm5zIHRoZSBuZXcgcG9zaXRpb24uIiIiCisKKyAgcG9zICs9IDQKKyAgaWYgcG9zID4gZW5kOgorICAgIHJhaXNlIF9EZWNvZGVFcnJvcignVHJ1bmNhdGVkIG1lc3NhZ2UuJykKKyAgcmV0dXJuIHBvcworCitkZWYgX1JhaXNlSW52YWxpZFdpcmVUeXBlKGJ1ZmZlciwgcG9zLCBlbmQpOgorICAiIiJTa2lwIGZ1bmN0aW9uIGZvciB1bmtub3duIHdpcmUgdHlwZXMuICBSYWlzZXMgYW4gZXhjZXB0aW9uLiIiIgorCisgIHJhaXNlIF9EZWNvZGVFcnJvcignVGFnIGhhZCBpbnZhbGlkIHdpcmUgdHlwZS4nKQorCitkZWYgX0ZpZWxkU2tpcHBlcigpOgorICAiIiJDb25zdHJ1Y3RzIHRoZSBTa2lwRmllbGQgZnVuY3Rpb24uIiIiCisKKyAgV0lSRVRZUEVfVE9fU0tJUFBFUiA9IFsKKyAgICAgIF9Ta2lwVmFyaW50LAorICAgICAgX1NraXBGaXhlZDY0LAorICAgICAgX1NraXBMZW5ndGhEZWxpbWl0ZWQsCisgICAgICBfU2tpcEdyb3VwLAorICAgICAgX0VuZEdyb3VwLAorICAgICAgX1NraXBGaXhlZDMyLAorICAgICAgX1JhaXNlSW52YWxpZFdpcmVUeXBlLAorICAgICAgX1JhaXNlSW52YWxpZFdpcmVUeXBlLAorICAgICAgXQorCisgIHdpcmV0eXBlX21hc2sgPSB3aXJlX2Zvcm1hdC5UQUdfVFlQRV9NQVNLCisKKyAgZGVmIFNraXBGaWVsZChidWZmZXIsIHBvcywgZW5kLCB0YWdfYnl0ZXMpOgorICAgICIiIlNraXBzIGEgZmllbGQgd2l0aCB0aGUgc3BlY2lmaWVkIHRhZy4KKworICAgIHxwb3N8IHNob3VsZCBwb2ludCB0byB0aGUgYnl0ZSBpbW1lZGlhdGVseSBhZnRlciB0aGUgdGFnLgorCisgICAgUmV0dXJuczoKKyAgICAgICAgVGhlIG5ldyBwb3NpdGlvbiAoYWZ0ZXIgdGhlIHRhZyB2YWx1ZSksIG9yIC0xIGlmIHRoZSB0YWcgaXMgYW4gZW5kLWdyb3VwCisgICAgICAgIHRhZyAoaW4gd2hpY2ggY2FzZSB0aGUgY2FsbGluZyBsb29wIHNob3VsZCBicmVhaykuCisgICAgIiIiCisKKyAgICAjIFRoZSB3aXJlIHR5cGUgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCBieXRlIHNpbmNlIHZhcmludHMgYXJlIGxpdHRsZS1lbmRpYW4uCisgICAgd2lyZV90eXBlID0gb3JkKHRhZ19ieXRlc1swOjFdKSAmIHdpcmV0eXBlX21hc2sKKyAgICByZXR1cm4gV0lSRVRZUEVfVE9fU0tJUFBFUlt3aXJlX3R5cGVdKGJ1ZmZlciwgcG9zLCBlbmQpCisKKyAgcmV0dXJuIFNraXBGaWVsZAorCitTa2lwRmllbGQgPSBfRmllbGRTa2lwcGVyKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9kYXRhYmFzZV90ZXN0LnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX2RhdGFiYXNlX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODk3MGY1YwotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9kYXRhYmFzZV90ZXN0LnB5CkBAIC0wLDAgKzEsNjUgQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJUZXN0cyBmb3IgZ29vZ2xlLnByb3RvYnVmLmRlc2NyaXB0b3JfZGF0YWJhc2UuIiIiCisKK19fYXV0aG9yX18gPSAnbWF0dGhld3RvaWFAZ29vZ2xlLmNvbSAoTWF0dCBUb2lhKScKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBmYWN0b3J5X3Rlc3QyX3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfZGF0YWJhc2UKKworCitjbGFzcyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdEFkZChzZWxmKToKKyAgICBkYiA9IGRlc2NyaXB0b3JfZGF0YWJhc2UuRGVzY3JpcHRvckRhdGFiYXNlKCkKKyAgICBmaWxlX2Rlc2NfcHJvdG8gPSBkZXNjcmlwdG9yX3BiMi5GaWxlRGVzY3JpcHRvclByb3RvLkZyb21TdHJpbmcoCisgICAgICAgIGZhY3RvcnlfdGVzdDJfcGIyLkRFU0NSSVBUT1Iuc2VyaWFsaXplZF9wYikKKyAgICBkYi5BZGQoZmlsZV9kZXNjX3Byb3RvKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoZmlsZV9kZXNjX3Byb3RvLCBkYi5GaW5kRmlsZUJ5TmFtZSgKKyAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9mYWN0b3J5X3Rlc3QyLnByb3RvJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoZmlsZV9kZXNjX3Byb3RvLCBkYi5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkyTWVzc2FnZScpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKGZpbGVfZGVzY19wcm90bywgZGIuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UuTmVzdGVkRmFjdG9yeTJNZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoZmlsZV9kZXNjX3Byb3RvLCBkYi5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkyRW51bScpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKGZpbGVfZGVzY19wcm90bywgZGIuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UuTmVzdGVkRmFjdG9yeTJFbnVtJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoZmlsZV9kZXNjX3Byb3RvLCBkYi5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLk1lc3NhZ2VXaXRoTmVzdGVkRW51bU9ubHkuTmVzdGVkRW51bScpKQorCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9wb29sX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExZWY2MWMKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0LnB5CkBAIC0wLDAgKzEsNTkxIEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgZm9yIGdvb2dsZS5wcm90b2J1Zi5kZXNjcmlwdG9yX3Bvb2wuIiIiCisKK19fYXV0aG9yX18gPSAnbWF0dGhld3RvaWFAZ29vZ2xlLmNvbSAoTWF0dCBUb2lhKScKKworaW1wb3J0IG9zCitpbXBvcnQgdW5pdHRlc3QKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBhcGlfaW1wbGVtZW50YXRpb24KK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBkZXNjcmlwdG9yX3Bvb2xfdGVzdDFfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgZGVzY3JpcHRvcl9wb29sX3Rlc3QyX3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGZhY3RvcnlfdGVzdDFfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgZmFjdG9yeV90ZXN0Ml9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9kYXRhYmFzZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcG9vbAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHN5bWJvbF9kYXRhYmFzZQorCisKK2NsYXNzIERlc2NyaXB0b3JQb29sVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHNldFVwKHNlbGYpOgorICAgIHNlbGYucG9vbCA9IGRlc2NyaXB0b3JfcG9vbC5EZXNjcmlwdG9yUG9vbCgpCisgICAgc2VsZi5mYWN0b3J5X3Rlc3QxX2ZkID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by5Gcm9tU3RyaW5nKAorICAgICAgICBmYWN0b3J5X3Rlc3QxX3BiMi5ERVNDUklQVE9SLnNlcmlhbGl6ZWRfcGIpCisgICAgc2VsZi5mYWN0b3J5X3Rlc3QyX2ZkID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by5Gcm9tU3RyaW5nKAorICAgICAgICBmYWN0b3J5X3Rlc3QyX3BiMi5ERVNDUklQVE9SLnNlcmlhbGl6ZWRfcGIpCisgICAgc2VsZi5wb29sLkFkZChzZWxmLmZhY3RvcnlfdGVzdDFfZmQpCisgICAgc2VsZi5wb29sLkFkZChzZWxmLmZhY3RvcnlfdGVzdDJfZmQpCisKKyAgZGVmIHRlc3RGaW5kRmlsZUJ5TmFtZShzZWxmKToKKyAgICBuYW1lMSA9ICdnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0MS5wcm90bycKKyAgICBmaWxlX2Rlc2MxID0gc2VsZi5wb29sLkZpbmRGaWxlQnlOYW1lKG5hbWUxKQorICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShmaWxlX2Rlc2MxLCBkZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKG5hbWUxLCBmaWxlX2Rlc2MxLm5hbWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwnLCBmaWxlX2Rlc2MxLnBhY2thZ2UpCisgICAgc2VsZi5hc3NlcnRJbignRmFjdG9yeTFNZXNzYWdlJywgZmlsZV9kZXNjMS5tZXNzYWdlX3R5cGVzX2J5X25hbWUpCisKKyAgICBuYW1lMiA9ICdnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0Mi5wcm90bycKKyAgICBmaWxlX2Rlc2MyID0gc2VsZi5wb29sLkZpbmRGaWxlQnlOYW1lKG5hbWUyKQorICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShmaWxlX2Rlc2MyLCBkZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKG5hbWUyLCBmaWxlX2Rlc2MyLm5hbWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwnLCBmaWxlX2Rlc2MyLnBhY2thZ2UpCisgICAgc2VsZi5hc3NlcnRJbignRmFjdG9yeTJNZXNzYWdlJywgZmlsZV9kZXNjMi5tZXNzYWdlX3R5cGVzX2J5X25hbWUpCisKKyAgZGVmIHRlc3RGaW5kRmlsZUJ5TmFtZUZhaWx1cmUoc2VsZik6CisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhLZXlFcnJvcik6CisgICAgICBzZWxmLnBvb2wuRmluZEZpbGVCeU5hbWUoJ0RvZXMgbm90IGV4aXN0JykKKworICBkZWYgdGVzdEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChzZWxmKToKKyAgICBmaWxlX2Rlc2MxID0gc2VsZi5wb29sLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTFNZXNzYWdlJykKKyAgICBzZWxmLmFzc2VydElzSW5zdGFuY2UoZmlsZV9kZXNjMSwgZGVzY3JpcHRvci5GaWxlRGVzY3JpcHRvcikKKyAgICBzZWxmLmFzc2VydEVxdWFscygnZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ZhY3RvcnlfdGVzdDEucHJvdG8nLAorICAgICAgICAgICAgICAgICAgICAgIGZpbGVfZGVzYzEubmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbCcsIGZpbGVfZGVzYzEucGFja2FnZSkKKyAgICBzZWxmLmFzc2VydEluKCdGYWN0b3J5MU1lc3NhZ2UnLCBmaWxlX2Rlc2MxLm1lc3NhZ2VfdHlwZXNfYnlfbmFtZSkKKworICAgIGZpbGVfZGVzYzIgPSBzZWxmLnBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UnKQorICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShmaWxlX2Rlc2MyLCBkZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCdnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0Mi5wcm90bycsCisgICAgICAgICAgICAgICAgICAgICAgZmlsZV9kZXNjMi5uYW1lKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsJywgZmlsZV9kZXNjMi5wYWNrYWdlKQorICAgIHNlbGYuYXNzZXJ0SW4oJ0ZhY3RvcnkyTWVzc2FnZScsIGZpbGVfZGVzYzIubWVzc2FnZV90eXBlc19ieV9uYW1lKQorCisgIGRlZiB0ZXN0RmluZEZpbGVDb250YWluaW5nU3ltYm9sRmFpbHVyZShzZWxmKToKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yKToKKyAgICAgIHNlbGYucG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woJ0RvZXMgbm90IGV4aXN0JykKKworICBkZWYgdGVzdEZpbmRNZXNzYWdlVHlwZUJ5TmFtZShzZWxmKToKKyAgICBtc2cxID0gc2VsZi5wb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgKKyAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTFNZXNzYWdlJykKKyAgICBzZWxmLmFzc2VydElzSW5zdGFuY2UobXNnMSwgZGVzY3JpcHRvci5EZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCdGYWN0b3J5MU1lc3NhZ2UnLCBtc2cxLm5hbWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTFNZXNzYWdlJywKKyAgICAgICAgICAgICAgICAgICAgICBtc2cxLmZ1bGxfbmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhOb25lLCBtc2cxLmNvbnRhaW5pbmdfdHlwZSkKKworICAgIG5lc3RlZF9tc2cxID0gbXNnMS5uZXN0ZWRfdHlwZXNbMF0KKyAgICBzZWxmLmFzc2VydEVxdWFscygnTmVzdGVkRmFjdG9yeTFNZXNzYWdlJywgbmVzdGVkX21zZzEubmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhtc2cxLCBuZXN0ZWRfbXNnMS5jb250YWluaW5nX3R5cGUpCisKKyAgICBuZXN0ZWRfZW51bTEgPSBtc2cxLmVudW1fdHlwZXNbMF0KKyAgICBzZWxmLmFzc2VydEVxdWFscygnTmVzdGVkRmFjdG9yeTFFbnVtJywgbmVzdGVkX2VudW0xLm5hbWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobXNnMSwgbmVzdGVkX2VudW0xLmNvbnRhaW5pbmdfdHlwZSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWxzKG5lc3RlZF9tc2cxLCBtc2cxLmZpZWxkc19ieV9uYW1lWworICAgICAgICAnbmVzdGVkX2ZhY3RvcnlfMV9tZXNzYWdlJ10ubWVzc2FnZV90eXBlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKG5lc3RlZF9lbnVtMSwgbXNnMS5maWVsZHNfYnlfbmFtZVsKKyAgICAgICAgJ25lc3RlZF9mYWN0b3J5XzFfZW51bSddLmVudW1fdHlwZSkKKworICAgIG1zZzIgPSBzZWxmLnBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UnKQorICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShtc2cyLCBkZXNjcmlwdG9yLkRlc2NyaXB0b3IpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoJ0ZhY3RvcnkyTWVzc2FnZScsIG1zZzIubmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UnLAorICAgICAgICAgICAgICAgICAgICAgIG1zZzIuZnVsbF9uYW1lKQorICAgIHNlbGYuYXNzZXJ0SXNOb25lKG1zZzIuY29udGFpbmluZ190eXBlKQorCisgICAgbmVzdGVkX21zZzIgPSBtc2cyLm5lc3RlZF90eXBlc1swXQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCdOZXN0ZWRGYWN0b3J5Mk1lc3NhZ2UnLCBuZXN0ZWRfbXNnMi5uYW1lKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKG1zZzIsIG5lc3RlZF9tc2cyLmNvbnRhaW5pbmdfdHlwZSkKKworICAgIG5lc3RlZF9lbnVtMiA9IG1zZzIuZW51bV90eXBlc1swXQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCdOZXN0ZWRGYWN0b3J5MkVudW0nLCBuZXN0ZWRfZW51bTIubmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhtc2cyLCBuZXN0ZWRfZW51bTIuY29udGFpbmluZ190eXBlKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobmVzdGVkX21zZzIsIG1zZzIuZmllbGRzX2J5X25hbWVbCisgICAgICAgICduZXN0ZWRfZmFjdG9yeV8yX21lc3NhZ2UnXS5tZXNzYWdlX3R5cGUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobmVzdGVkX2VudW0yLCBtc2cyLmZpZWxkc19ieV9uYW1lWworICAgICAgICAnbmVzdGVkX2ZhY3RvcnlfMl9lbnVtJ10uZW51bV90eXBlKQorCisgICAgc2VsZi5hc3NlcnRUcnVlKG1zZzIuZmllbGRzX2J5X25hbWVbJ2ludF93aXRoX2RlZmF1bHQnXS5oYXNfZGVmYXVsdF92YWx1ZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgMTc3NiwgbXNnMi5maWVsZHNfYnlfbmFtZVsnaW50X3dpdGhfZGVmYXVsdCddLmRlZmF1bHRfdmFsdWUpCisKKyAgICBzZWxmLmFzc2VydFRydWUoCisgICAgICAgIG1zZzIuZmllbGRzX2J5X25hbWVbJ2RvdWJsZV93aXRoX2RlZmF1bHQnXS5oYXNfZGVmYXVsdF92YWx1ZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgOS45OSwgbXNnMi5maWVsZHNfYnlfbmFtZVsnZG91YmxlX3dpdGhfZGVmYXVsdCddLmRlZmF1bHRfdmFsdWUpCisKKyAgICBzZWxmLmFzc2VydFRydWUoCisgICAgICAgIG1zZzIuZmllbGRzX2J5X25hbWVbJ3N0cmluZ193aXRoX2RlZmF1bHQnXS5oYXNfZGVmYXVsdF92YWx1ZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ2hlbGxvIHdvcmxkJywgbXNnMi5maWVsZHNfYnlfbmFtZVsnc3RyaW5nX3dpdGhfZGVmYXVsdCddLmRlZmF1bHRfdmFsdWUpCisKKyAgICBzZWxmLmFzc2VydFRydWUobXNnMi5maWVsZHNfYnlfbmFtZVsnYm9vbF93aXRoX2RlZmF1bHQnXS5oYXNfZGVmYXVsdF92YWx1ZSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG1zZzIuZmllbGRzX2J5X25hbWVbJ2Jvb2xfd2l0aF9kZWZhdWx0J10uZGVmYXVsdF92YWx1ZSkKKworICAgIHNlbGYuYXNzZXJ0VHJ1ZShtc2cyLmZpZWxkc19ieV9uYW1lWydlbnVtX3dpdGhfZGVmYXVsdCddLmhhc19kZWZhdWx0X3ZhbHVlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAxLCBtc2cyLmZpZWxkc19ieV9uYW1lWydlbnVtX3dpdGhfZGVmYXVsdCddLmRlZmF1bHRfdmFsdWUpCisKKyAgICBtc2czID0gc2VsZi5wb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgKKyAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTJNZXNzYWdlLk5lc3RlZEZhY3RvcnkyTWVzc2FnZScpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobmVzdGVkX21zZzIsIG1zZzMpCisKKyAgICBzZWxmLmFzc2VydFRydWUobXNnMi5maWVsZHNfYnlfbmFtZVsnYnl0ZXNfd2l0aF9kZWZhdWx0J10uaGFzX2RlZmF1bHRfdmFsdWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgIGInYVx4ZmJceDAwYycsCisgICAgICAgIG1zZzIuZmllbGRzX2J5X25hbWVbJ2J5dGVzX3dpdGhfZGVmYXVsdCddLmRlZmF1bHRfdmFsdWUpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIGxlbihtc2cyLm9uZW9mcykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBsZW4obXNnMi5vbmVvZnNfYnlfbmFtZSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBsZW4obXNnMi5vbmVvZnNbMF0uZmllbGRzKSkKKyAgICBmb3IgbmFtZSBpbiBbJ29uZW9mX2ludCcsICdvbmVvZl9zdHJpbmcnXToKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobXNnMi5vbmVvZnNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgIG1zZzIuZmllbGRzX2J5X25hbWVbbmFtZV0uY29udGFpbmluZ19vbmVvZikKKyAgICAgIHNlbGYuYXNzZXJ0SW4obXNnMi5maWVsZHNfYnlfbmFtZVtuYW1lXSwgbXNnMi5vbmVvZnNbMF0uZmllbGRzKQorCisgIGRlZiB0ZXN0RmluZE1lc3NhZ2VUeXBlQnlOYW1lRmFpbHVyZShzZWxmKToKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yKToKKyAgICAgIHNlbGYucG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoJ0RvZXMgbm90IGV4aXN0JykKKworICBkZWYgdGVzdEZpbmRFbnVtVHlwZUJ5TmFtZShzZWxmKToKKyAgICBlbnVtMSA9IHNlbGYucG9vbC5GaW5kRW51bVR5cGVCeU5hbWUoCisgICAgICAgICdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkxRW51bScpCisgICAgc2VsZi5hc3NlcnRJc0luc3RhbmNlKGVudW0xLCBkZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKDAsIGVudW0xLnZhbHVlc19ieV9uYW1lWydGQUNUT1JZXzFfVkFMVUVfMCddLm51bWJlcikKKyAgICBzZWxmLmFzc2VydEVxdWFscygxLCBlbnVtMS52YWx1ZXNfYnlfbmFtZVsnRkFDVE9SWV8xX1ZBTFVFXzEnXS5udW1iZXIpCisKKyAgICBuZXN0ZWRfZW51bTEgPSBzZWxmLnBvb2wuRmluZEVudW1UeXBlQnlOYW1lKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5MU1lc3NhZ2UuTmVzdGVkRmFjdG9yeTFFbnVtJykKKyAgICBzZWxmLmFzc2VydElzSW5zdGFuY2UobmVzdGVkX2VudW0xLCBkZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAwLCBuZXN0ZWRfZW51bTEudmFsdWVzX2J5X25hbWVbJ05FU1RFRF9GQUNUT1JZXzFfVkFMVUVfMCddLm51bWJlcikKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgMSwgbmVzdGVkX2VudW0xLnZhbHVlc19ieV9uYW1lWydORVNURURfRkFDVE9SWV8xX1ZBTFVFXzEnXS5udW1iZXIpCisKKyAgICBlbnVtMiA9IHNlbGYucG9vbC5GaW5kRW51bVR5cGVCeU5hbWUoCisgICAgICAgICdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkyRW51bScpCisgICAgc2VsZi5hc3NlcnRJc0luc3RhbmNlKGVudW0yLCBkZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKDAsIGVudW0yLnZhbHVlc19ieV9uYW1lWydGQUNUT1JZXzJfVkFMVUVfMCddLm51bWJlcikKKyAgICBzZWxmLmFzc2VydEVxdWFscygxLCBlbnVtMi52YWx1ZXNfYnlfbmFtZVsnRkFDVE9SWV8yX1ZBTFVFXzEnXS5udW1iZXIpCisKKyAgICBuZXN0ZWRfZW51bTIgPSBzZWxmLnBvb2wuRmluZEVudW1UeXBlQnlOYW1lKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UuTmVzdGVkRmFjdG9yeTJFbnVtJykKKyAgICBzZWxmLmFzc2VydElzSW5zdGFuY2UobmVzdGVkX2VudW0yLCBkZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAwLCBuZXN0ZWRfZW51bTIudmFsdWVzX2J5X25hbWVbJ05FU1RFRF9GQUNUT1JZXzJfVkFMVUVfMCddLm51bWJlcikKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgMSwgbmVzdGVkX2VudW0yLnZhbHVlc19ieV9uYW1lWydORVNURURfRkFDVE9SWV8yX1ZBTFVFXzEnXS5udW1iZXIpCisKKyAgZGVmIHRlc3RGaW5kRW51bVR5cGVCeU5hbWVGYWlsdXJlKHNlbGYpOgorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IpOgorICAgICAgc2VsZi5wb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgnRG9lcyBub3QgZXhpc3QnKQorCisgIGRlZiB0ZXN0VXNlckRlZmluZWREQihzZWxmKToKKyAgICBkYiA9IGRlc2NyaXB0b3JfZGF0YWJhc2UuRGVzY3JpcHRvckRhdGFiYXNlKCkKKyAgICBzZWxmLnBvb2wgPSBkZXNjcmlwdG9yX3Bvb2wuRGVzY3JpcHRvclBvb2woZGIpCisgICAgZGIuQWRkKHNlbGYuZmFjdG9yeV90ZXN0MV9mZCkKKyAgICBkYi5BZGQoc2VsZi5mYWN0b3J5X3Rlc3QyX2ZkKQorICAgIHNlbGYudGVzdEZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgpCisKKyAgZGVmIHRlc3RDb21wbGV4TmVzdGluZyhzZWxmKToKKyAgICB0ZXN0MV9kZXNjID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by5Gcm9tU3RyaW5nKAorICAgICAgICBkZXNjcmlwdG9yX3Bvb2xfdGVzdDFfcGIyLkRFU0NSSVBUT1Iuc2VyaWFsaXplZF9wYikKKyAgICB0ZXN0Ml9kZXNjID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90by5Gcm9tU3RyaW5nKAorICAgICAgICBkZXNjcmlwdG9yX3Bvb2xfdGVzdDJfcGIyLkRFU0NSSVBUT1Iuc2VyaWFsaXplZF9wYikKKyAgICBzZWxmLnBvb2wuQWRkKHRlc3QxX2Rlc2MpCisgICAgc2VsZi5wb29sLkFkZCh0ZXN0Ml9kZXNjKQorICAgIFRFU1QxX0ZJTEUuQ2hlY2tGaWxlKHNlbGYsIHNlbGYucG9vbCkKKyAgICBURVNUMl9GSUxFLkNoZWNrRmlsZShzZWxmLCBzZWxmLnBvb2wpCisKKworICBkZWYgdGVzdEVudW1EZWZhdWx0VmFsdWUoc2VsZik6CisgICAgIiIiVGVzdCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBlbnVtcyB3aGljaCBkb24ndCBzdGFydCBhdCB6ZXJvLiIiIgorICAgIGRlZiBfQ2hlY2tEZWZhdWx0VmFsdWUoZmlsZV9kZXNjcmlwdG9yKToKKyAgICAgIGRlZmF1bHRfdmFsdWUgPSAoZmlsZV9kZXNjcmlwdG9yCisgICAgICAgICAgICAgICAgICAgICAgIC5tZXNzYWdlX3R5cGVzX2J5X25hbWVbJ0Rlc2NyaXB0b3JQb29sVGVzdDEnXQorICAgICAgICAgICAgICAgICAgICAgICAuZmllbGRzX2J5X25hbWVbJ25lc3RlZF9lbnVtJ10KKyAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHRfdmFsdWUpCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfcG9vbF90ZXN0MV9wYjIuRGVzY3JpcHRvclBvb2xUZXN0MS5CRVRBKQorICAgICMgRmlyc3QgY2hlY2sgd2hhdCB0aGUgZ2VuZXJhdGVkIGRlc2NyaXB0b3IgY29udGFpbnMuCisgICAgX0NoZWNrRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3JfcG9vbF90ZXN0MV9wYjIuREVTQ1JJUFRPUikKKyAgICAjIFRoZW4gY2hlY2sgdGhlIGdlbmVyYXRlZCBwb29sLiBOb3JtYWxseSB0aGlzIGlzIHRoZSBzYW1lIGRlc2NyaXB0b3IuCisgICAgZmlsZV9kZXNjcmlwdG9yID0gc3ltYm9sX2RhdGFiYXNlLkRlZmF1bHQoKS5wb29sLkZpbmRGaWxlQnlOYW1lKAorICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0MS5wcm90bycpCisgICAgc2VsZi5hc3NlcnRJcyhmaWxlX2Rlc2NyaXB0b3IsIGRlc2NyaXB0b3JfcG9vbF90ZXN0MV9wYjIuREVTQ1JJUFRPUikKKyAgICBfQ2hlY2tEZWZhdWx0VmFsdWUoZmlsZV9kZXNjcmlwdG9yKQorCisgICAgIyBUaGVuIGNoZWNrIHRoZSBkeW5hbWljIHBvb2wgYW5kIGl0cyBpbnRlcm5hbCBEZXNjcmlwdG9yRGF0YWJhc2UuCisgICAgZGVzY3JpcHRvcl9wcm90byA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8uRnJvbVN0cmluZygKKyAgICAgICAgZGVzY3JpcHRvcl9wb29sX3Rlc3QxX3BiMi5ERVNDUklQVE9SLnNlcmlhbGl6ZWRfcGIpCisgICAgc2VsZi5wb29sLkFkZChkZXNjcmlwdG9yX3Byb3RvKQorICAgICMgQW5kIGRvIHRoZSBzYW1lIGNoZWNrIGFzIGFib3ZlCisgICAgZmlsZV9kZXNjcmlwdG9yID0gc2VsZi5wb29sLkZpbmRGaWxlQnlOYW1lKAorICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0MS5wcm90bycpCisgICAgX0NoZWNrRGVmYXVsdFZhbHVlKGZpbGVfZGVzY3JpcHRvcikKKworCitjbGFzcyBQcm90b0ZpbGUob2JqZWN0KToKKworICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgcGFja2FnZSwgbWVzc2FnZXMsIGRlcGVuZGVuY2llcz1Ob25lKToKKyAgICBzZWxmLm5hbWUgPSBuYW1lCisgICAgc2VsZi5wYWNrYWdlID0gcGFja2FnZQorICAgIHNlbGYubWVzc2FnZXMgPSBtZXNzYWdlcworICAgIHNlbGYuZGVwZW5kZW5jaWVzID0gZGVwZW5kZW5jaWVzIG9yIFtdCisKKyAgZGVmIENoZWNrRmlsZShzZWxmLCB0ZXN0LCBwb29sKToKKyAgICBmaWxlX2Rlc2MgPSBwb29sLkZpbmRGaWxlQnlOYW1lKHNlbGYubmFtZSkKKyAgICB0ZXN0LmFzc2VydEVxdWFscyhzZWxmLm5hbWUsIGZpbGVfZGVzYy5uYW1lKQorICAgIHRlc3QuYXNzZXJ0RXF1YWxzKHNlbGYucGFja2FnZSwgZmlsZV9kZXNjLnBhY2thZ2UpCisgICAgZGVwZW5kZW5jaWVzX25hbWVzID0gW2YubmFtZSBmb3IgZiBpbiBmaWxlX2Rlc2MuZGVwZW5kZW5jaWVzXQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoc2VsZi5kZXBlbmRlbmNpZXMsIGRlcGVuZGVuY2llc19uYW1lcykKKyAgICBmb3IgbmFtZSwgbXNnX3R5cGUgaW4gc2VsZi5tZXNzYWdlcy5pdGVtcygpOgorICAgICAgbXNnX3R5cGUuQ2hlY2tUeXBlKHRlc3QsIE5vbmUsIG5hbWUsIGZpbGVfZGVzYykKKworCitjbGFzcyBFbnVtVHlwZShvYmplY3QpOgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCB2YWx1ZXMpOgorICAgIHNlbGYudmFsdWVzID0gdmFsdWVzCisKKyAgZGVmIENoZWNrVHlwZShzZWxmLCB0ZXN0LCBtc2dfZGVzYywgbmFtZSwgZmlsZV9kZXNjKToKKyAgICBlbnVtX2Rlc2MgPSBtc2dfZGVzYy5lbnVtX3R5cGVzX2J5X25hbWVbbmFtZV0KKyAgICB0ZXN0LmFzc2VydEVxdWFsKG5hbWUsIGVudW1fZGVzYy5uYW1lKQorICAgIGV4cGVjdGVkX2VudW1fZnVsbF9uYW1lID0gJy4nLmpvaW4oW21zZ19kZXNjLmZ1bGxfbmFtZSwgbmFtZV0pCisgICAgdGVzdC5hc3NlcnRFcXVhbChleHBlY3RlZF9lbnVtX2Z1bGxfbmFtZSwgZW51bV9kZXNjLmZ1bGxfbmFtZSkKKyAgICB0ZXN0LmFzc2VydEVxdWFsKG1zZ19kZXNjLCBlbnVtX2Rlc2MuY29udGFpbmluZ190eXBlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoZmlsZV9kZXNjLCBlbnVtX2Rlc2MuZmlsZSkKKyAgICBmb3IgaW5kZXgsICh2YWx1ZSwgbnVtYmVyKSBpbiBlbnVtZXJhdGUoc2VsZi52YWx1ZXMpOgorICAgICAgdmFsdWVfZGVzYyA9IGVudW1fZGVzYy52YWx1ZXNfYnlfbmFtZVt2YWx1ZV0KKyAgICAgIHRlc3QuYXNzZXJ0RXF1YWwodmFsdWUsIHZhbHVlX2Rlc2MubmFtZSkKKyAgICAgIHRlc3QuYXNzZXJ0RXF1YWwoaW5kZXgsIHZhbHVlX2Rlc2MuaW5kZXgpCisgICAgICB0ZXN0LmFzc2VydEVxdWFsKG51bWJlciwgdmFsdWVfZGVzYy5udW1iZXIpCisgICAgICB0ZXN0LmFzc2VydEVxdWFsKGVudW1fZGVzYywgdmFsdWVfZGVzYy50eXBlKQorICAgICAgdGVzdC5hc3NlcnRJbih2YWx1ZSwgbXNnX2Rlc2MuZW51bV92YWx1ZXNfYnlfbmFtZSkKKworCitjbGFzcyBNZXNzYWdlVHlwZShvYmplY3QpOgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCB0eXBlX2RpY3QsIGZpZWxkX2xpc3QsIGlzX2V4dGVuZGFibGU9RmFsc2UsCisgICAgICAgICAgICAgICBleHRlbnNpb25zPU5vbmUpOgorICAgIHNlbGYudHlwZV9kaWN0ID0gdHlwZV9kaWN0CisgICAgc2VsZi5maWVsZF9saXN0ID0gZmllbGRfbGlzdAorICAgIHNlbGYuaXNfZXh0ZW5kYWJsZSA9IGlzX2V4dGVuZGFibGUKKyAgICBzZWxmLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zIG9yIFtdCisKKyAgZGVmIENoZWNrVHlwZShzZWxmLCB0ZXN0LCBjb250YWluaW5nX3R5cGVfZGVzYywgbmFtZSwgZmlsZV9kZXNjKToKKyAgICBpZiBjb250YWluaW5nX3R5cGVfZGVzYyBpcyBOb25lOgorICAgICAgZGVzYyA9IGZpbGVfZGVzYy5tZXNzYWdlX3R5cGVzX2J5X25hbWVbbmFtZV0KKyAgICAgIGV4cGVjdGVkX2Z1bGxfbmFtZSA9ICcuJy5qb2luKFtmaWxlX2Rlc2MucGFja2FnZSwgbmFtZV0pCisgICAgZWxzZToKKyAgICAgIGRlc2MgPSBjb250YWluaW5nX3R5cGVfZGVzYy5uZXN0ZWRfdHlwZXNfYnlfbmFtZVtuYW1lXQorICAgICAgZXhwZWN0ZWRfZnVsbF9uYW1lID0gJy4nLmpvaW4oW2NvbnRhaW5pbmdfdHlwZV9kZXNjLmZ1bGxfbmFtZSwgbmFtZV0pCisKKyAgICB0ZXN0LmFzc2VydEVxdWFsKG5hbWUsIGRlc2MubmFtZSkKKyAgICB0ZXN0LmFzc2VydEVxdWFsKGV4cGVjdGVkX2Z1bGxfbmFtZSwgZGVzYy5mdWxsX25hbWUpCisgICAgdGVzdC5hc3NlcnRFcXVhbChjb250YWluaW5nX3R5cGVfZGVzYywgZGVzYy5jb250YWluaW5nX3R5cGUpCisgICAgdGVzdC5hc3NlcnRFcXVhbChkZXNjLmZpbGUsIGZpbGVfZGVzYykKKyAgICB0ZXN0LmFzc2VydEVxdWFsKHNlbGYuaXNfZXh0ZW5kYWJsZSwgZGVzYy5pc19leHRlbmRhYmxlKQorICAgIGZvciBuYW1lLCBzdWJ0eXBlIGluIHNlbGYudHlwZV9kaWN0Lml0ZW1zKCk6CisgICAgICBzdWJ0eXBlLkNoZWNrVHlwZSh0ZXN0LCBkZXNjLCBuYW1lLCBmaWxlX2Rlc2MpCisKKyAgICBmb3IgaW5kZXgsIChuYW1lLCBmaWVsZCkgaW4gZW51bWVyYXRlKHNlbGYuZmllbGRfbGlzdCk6CisgICAgICBmaWVsZC5DaGVja0ZpZWxkKHRlc3QsIGRlc2MsIG5hbWUsIGluZGV4KQorCisgICAgZm9yIGluZGV4LCAobmFtZSwgZmllbGQpIGluIGVudW1lcmF0ZShzZWxmLmV4dGVuc2lvbnMpOgorICAgICAgZmllbGQuQ2hlY2tGaWVsZCh0ZXN0LCBkZXNjLCBuYW1lLCBpbmRleCkKKworCitjbGFzcyBFbnVtRmllbGQob2JqZWN0KToKKworICBkZWYgX19pbml0X18oc2VsZiwgbnVtYmVyLCB0eXBlX25hbWUsIGRlZmF1bHRfdmFsdWUpOgorICAgIHNlbGYubnVtYmVyID0gbnVtYmVyCisgICAgc2VsZi50eXBlX25hbWUgPSB0eXBlX25hbWUKKyAgICBzZWxmLmRlZmF1bHRfdmFsdWUgPSBkZWZhdWx0X3ZhbHVlCisKKyAgZGVmIENoZWNrRmllbGQoc2VsZiwgdGVzdCwgbXNnX2Rlc2MsIG5hbWUsIGluZGV4KToKKyAgICBmaWVsZF9kZXNjID0gbXNnX2Rlc2MuZmllbGRzX2J5X25hbWVbbmFtZV0KKyAgICBlbnVtX2Rlc2MgPSBtc2dfZGVzYy5lbnVtX3R5cGVzX2J5X25hbWVbc2VsZi50eXBlX25hbWVdCisgICAgdGVzdC5hc3NlcnRFcXVhbChuYW1lLCBmaWVsZF9kZXNjLm5hbWUpCisgICAgZXhwZWN0ZWRfZmllbGRfZnVsbF9uYW1lID0gJy4nLmpvaW4oW21zZ19kZXNjLmZ1bGxfbmFtZSwgbmFtZV0pCisgICAgdGVzdC5hc3NlcnRFcXVhbChleHBlY3RlZF9maWVsZF9mdWxsX25hbWUsIGZpZWxkX2Rlc2MuZnVsbF9uYW1lKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoaW5kZXgsIGZpZWxkX2Rlc2MuaW5kZXgpCisgICAgdGVzdC5hc3NlcnRFcXVhbChzZWxmLm51bWJlciwgZmllbGRfZGVzYy5udW1iZXIpCisgICAgdGVzdC5hc3NlcnRFcXVhbChkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU0sIGZpZWxkX2Rlc2MudHlwZSkKKyAgICB0ZXN0LmFzc2VydEVxdWFsKGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfRU5VTSwKKyAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Rlc2MuY3BwX3R5cGUpCisgICAgdGVzdC5hc3NlcnRUcnVlKGZpZWxkX2Rlc2MuaGFzX2RlZmF1bHRfdmFsdWUpCisgICAgdGVzdC5hc3NlcnRFcXVhbChlbnVtX2Rlc2MudmFsdWVzX2J5X25hbWVbc2VsZi5kZWZhdWx0X3ZhbHVlXS5udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kZXNjLmRlZmF1bHRfdmFsdWUpCisgICAgdGVzdC5hc3NlcnRFcXVhbChtc2dfZGVzYywgZmllbGRfZGVzYy5jb250YWluaW5nX3R5cGUpCisgICAgdGVzdC5hc3NlcnRFcXVhbChlbnVtX2Rlc2MsIGZpZWxkX2Rlc2MuZW51bV90eXBlKQorCisKK2NsYXNzIE1lc3NhZ2VGaWVsZChvYmplY3QpOgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBudW1iZXIsIHR5cGVfbmFtZSk6CisgICAgc2VsZi5udW1iZXIgPSBudW1iZXIKKyAgICBzZWxmLnR5cGVfbmFtZSA9IHR5cGVfbmFtZQorCisgIGRlZiBDaGVja0ZpZWxkKHNlbGYsIHRlc3QsIG1zZ19kZXNjLCBuYW1lLCBpbmRleCk6CisgICAgZmllbGRfZGVzYyA9IG1zZ19kZXNjLmZpZWxkc19ieV9uYW1lW25hbWVdCisgICAgZmllbGRfdHlwZV9kZXNjID0gbXNnX2Rlc2MubmVzdGVkX3R5cGVzX2J5X25hbWVbc2VsZi50eXBlX25hbWVdCisgICAgdGVzdC5hc3NlcnRFcXVhbChuYW1lLCBmaWVsZF9kZXNjLm5hbWUpCisgICAgZXhwZWN0ZWRfZmllbGRfZnVsbF9uYW1lID0gJy4nLmpvaW4oW21zZ19kZXNjLmZ1bGxfbmFtZSwgbmFtZV0pCisgICAgdGVzdC5hc3NlcnRFcXVhbChleHBlY3RlZF9maWVsZF9mdWxsX25hbWUsIGZpZWxkX2Rlc2MuZnVsbF9uYW1lKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoaW5kZXgsIGZpZWxkX2Rlc2MuaW5kZXgpCisgICAgdGVzdC5hc3NlcnRFcXVhbChzZWxmLm51bWJlciwgZmllbGRfZGVzYy5udW1iZXIpCisgICAgdGVzdC5hc3NlcnRFcXVhbChkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0UsIGZpZWxkX2Rlc2MudHlwZSkKKyAgICB0ZXN0LmFzc2VydEVxdWFsKGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Rlc2MuY3BwX3R5cGUpCisgICAgdGVzdC5hc3NlcnRGYWxzZShmaWVsZF9kZXNjLmhhc19kZWZhdWx0X3ZhbHVlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwobXNnX2Rlc2MsIGZpZWxkX2Rlc2MuY29udGFpbmluZ190eXBlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoZmllbGRfdHlwZV9kZXNjLCBmaWVsZF9kZXNjLm1lc3NhZ2VfdHlwZSkKKworCitjbGFzcyBTdHJpbmdGaWVsZChvYmplY3QpOgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBudW1iZXIsIGRlZmF1bHRfdmFsdWUpOgorICAgIHNlbGYubnVtYmVyID0gbnVtYmVyCisgICAgc2VsZi5kZWZhdWx0X3ZhbHVlID0gZGVmYXVsdF92YWx1ZQorCisgIGRlZiBDaGVja0ZpZWxkKHNlbGYsIHRlc3QsIG1zZ19kZXNjLCBuYW1lLCBpbmRleCk6CisgICAgZmllbGRfZGVzYyA9IG1zZ19kZXNjLmZpZWxkc19ieV9uYW1lW25hbWVdCisgICAgdGVzdC5hc3NlcnRFcXVhbChuYW1lLCBmaWVsZF9kZXNjLm5hbWUpCisgICAgZXhwZWN0ZWRfZmllbGRfZnVsbF9uYW1lID0gJy4nLmpvaW4oW21zZ19kZXNjLmZ1bGxfbmFtZSwgbmFtZV0pCisgICAgdGVzdC5hc3NlcnRFcXVhbChleHBlY3RlZF9maWVsZF9mdWxsX25hbWUsIGZpZWxkX2Rlc2MuZnVsbF9uYW1lKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoaW5kZXgsIGZpZWxkX2Rlc2MuaW5kZXgpCisgICAgdGVzdC5hc3NlcnRFcXVhbChzZWxmLm51bWJlciwgZmllbGRfZGVzYy5udW1iZXIpCisgICAgdGVzdC5hc3NlcnRFcXVhbChkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX1NUUklORywgZmllbGRfZGVzYy50eXBlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9TVFJJTkcsCisgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kZXNjLmNwcF90eXBlKQorICAgIHRlc3QuYXNzZXJ0VHJ1ZShmaWVsZF9kZXNjLmhhc19kZWZhdWx0X3ZhbHVlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoc2VsZi5kZWZhdWx0X3ZhbHVlLCBmaWVsZF9kZXNjLmRlZmF1bHRfdmFsdWUpCisKKworY2xhc3MgRXh0ZW5zaW9uRmllbGQob2JqZWN0KToKKworICBkZWYgX19pbml0X18oc2VsZiwgbnVtYmVyLCBleHRlbmRlZF90eXBlKToKKyAgICBzZWxmLm51bWJlciA9IG51bWJlcgorICAgIHNlbGYuZXh0ZW5kZWRfdHlwZSA9IGV4dGVuZGVkX3R5cGUKKworICBkZWYgQ2hlY2tGaWVsZChzZWxmLCB0ZXN0LCBtc2dfZGVzYywgbmFtZSwgaW5kZXgpOgorICAgIGZpZWxkX2Rlc2MgPSBtc2dfZGVzYy5leHRlbnNpb25zX2J5X25hbWVbbmFtZV0KKyAgICB0ZXN0LmFzc2VydEVxdWFsKG5hbWUsIGZpZWxkX2Rlc2MubmFtZSkKKyAgICBleHBlY3RlZF9maWVsZF9mdWxsX25hbWUgPSAnLicuam9pbihbbXNnX2Rlc2MuZnVsbF9uYW1lLCBuYW1lXSkKKyAgICB0ZXN0LmFzc2VydEVxdWFsKGV4cGVjdGVkX2ZpZWxkX2Z1bGxfbmFtZSwgZmllbGRfZGVzYy5mdWxsX25hbWUpCisgICAgdGVzdC5hc3NlcnRFcXVhbChzZWxmLm51bWJlciwgZmllbGRfZGVzYy5udW1iZXIpCisgICAgdGVzdC5hc3NlcnRFcXVhbChpbmRleCwgZmllbGRfZGVzYy5pbmRleCkKKyAgICB0ZXN0LmFzc2VydEVxdWFsKGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfTUVTU0FHRSwgZmllbGRfZGVzYy50eXBlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgZmllbGRfZGVzYy5jcHBfdHlwZSkKKyAgICB0ZXN0LmFzc2VydEZhbHNlKGZpZWxkX2Rlc2MuaGFzX2RlZmF1bHRfdmFsdWUpCisgICAgdGVzdC5hc3NlcnRUcnVlKGZpZWxkX2Rlc2MuaXNfZXh0ZW5zaW9uKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwobXNnX2Rlc2MsIGZpZWxkX2Rlc2MuZXh0ZW5zaW9uX3Njb3BlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwobXNnX2Rlc2MsIGZpZWxkX2Rlc2MubWVzc2FnZV90eXBlKQorICAgIHRlc3QuYXNzZXJ0RXF1YWwoc2VsZi5leHRlbmRlZF90eXBlLCBmaWVsZF9kZXNjLmNvbnRhaW5pbmdfdHlwZS5uYW1lKQorCisKK2NsYXNzIEFkZERlc2NyaXB0b3JUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgX1Rlc3RNZXNzYWdlKHNlbGYsIHByZWZpeCk6CisgICAgcG9vbCA9IGRlc2NyaXB0b3JfcG9vbC5EZXNjcmlwdG9yUG9vbCgpCisgICAgcG9vbC5BZGREZXNjcmlwdG9yKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuREVTQ1JJUFRPUikKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcycsCisgICAgICAgIHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAgICAgcHJlZml4ICsgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcycpLmZ1bGxfbmFtZSkKKworICAgICMgQWRkRGVzY3JpcHRvciBpcyBub3QgcmVjdXJzaXZlLgorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IpOgorICAgICAgcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoCisgICAgICAgICAgcHJlZml4ICsgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlJykKKworICAgIHBvb2wuQWRkRGVzY3JpcHRvcih1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuREVTQ1JJUFRPUikKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlJywKKyAgICAgICAgcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoCisgICAgICAgICAgICBwcmVmaXggKyAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UnKS5mdWxsX25hbWUpCisKKyAgICAjIEZpbGVzIGFyZSBpbXBsaWNpdGx5IGFsc28gaW5kZXhlZCB3aGVuIG1lc3NhZ2VzIGFyZSBhZGRlZC4KKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bycsCisgICAgICAgIHBvb2wuRmluZEZpbGVCeU5hbWUoCisgICAgICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvJykubmFtZSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvJywKKyAgICAgICAgcG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICAgICBwcmVmaXggKyAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UnKS5uYW1lKQorCisgIGRlZiB0ZXN0TWVzc2FnZShzZWxmKToKKyAgICBzZWxmLl9UZXN0TWVzc2FnZSgnJykKKyAgICBzZWxmLl9UZXN0TWVzc2FnZSgnLicpCisKKyAgZGVmIF9UZXN0RW51bShzZWxmLCBwcmVmaXgpOgorICAgIHBvb2wgPSBkZXNjcmlwdG9yX3Bvb2wuRGVzY3JpcHRvclBvb2woKQorICAgIHBvb2wuQWRkRW51bURlc2NyaXB0b3IodW5pdHRlc3RfcGIyLkZvcmVpZ25FbnVtLkRFU0NSSVBUT1IpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bScsCisgICAgICAgIHBvb2wuRmluZEVudW1UeXBlQnlOYW1lKAorICAgICAgICAgICAgcHJlZml4ICsgJ3Byb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtJykuZnVsbF9uYW1lKQorCisgICAgIyBBZGRFbnVtRGVzY3JpcHRvciBpcyBub3QgcmVjdXJzaXZlLgorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IpOgorICAgICAgcG9vbC5GaW5kRW51bVR5cGVCeU5hbWUoCisgICAgICAgICAgcHJlZml4ICsgJ3Byb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtLk5lc3RlZEVudW0nKQorCisgICAgcG9vbC5BZGRFbnVtRGVzY3JpcHRvcih1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uREVTQ1JJUFRPUikKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtJywKKyAgICAgICAgcG9vbC5GaW5kRW51bVR5cGVCeU5hbWUoCisgICAgICAgICAgICBwcmVmaXggKyAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0nKS5mdWxsX25hbWUpCisKKyAgICAjIEZpbGVzIGFyZSBpbXBsaWNpdGx5IGFsc28gaW5kZXhlZCB3aGVuIGVudW1zIGFyZSBhZGRlZC4KKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bycsCisgICAgICAgIHBvb2wuRmluZEZpbGVCeU5hbWUoCisgICAgICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvJykubmFtZSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvJywKKyAgICAgICAgcG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICAgICBwcmVmaXggKyAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0nKS5uYW1lKQorCisgIGRlZiB0ZXN0RW51bShzZWxmKToKKyAgICBzZWxmLl9UZXN0RW51bSgnJykKKyAgICBzZWxmLl9UZXN0RW51bSgnLicpCisKKyAgZGVmIHRlc3RGaWxlKHNlbGYpOgorICAgIHBvb2wgPSBkZXNjcmlwdG9yX3Bvb2wuRGVzY3JpcHRvclBvb2woKQorICAgIHBvb2wuQWRkRmlsZURlc2NyaXB0b3IodW5pdHRlc3RfcGIyLkRFU0NSSVBUT1IpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgICdnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8nLAorICAgICAgICBwb29sLkZpbmRGaWxlQnlOYW1lKAorICAgICAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bycpLm5hbWUpCisKKyAgICAjIEFkZEZpbGVEZXNjcmlwdG9yIGlzIG5vdCByZWN1cnNpdmU7IG1lc3NhZ2VzIGFuZCBlbnVtcyB3aXRoaW4gZmlsZXMgbXVzdAorICAgICMgYmUgZXhwbGljaXRseSByZWdpc3RlcmVkLgorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IpOgorICAgICAgcG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcycpCisKKworVEVTVDFfRklMRSA9IFByb3RvRmlsZSgKKyAgICAnZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0MS5wcm90bycsCisgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwnLAorICAgIHsKKyAgICAgICAgJ0Rlc2NyaXB0b3JQb29sVGVzdDEnOiBNZXNzYWdlVHlwZSh7CisgICAgICAgICAgICAnTmVzdGVkRW51bSc6IEVudW1UeXBlKFsoJ0FMUEhBJywgMSksICgnQkVUQScsIDIpXSksCisgICAgICAgICAgICAnTmVzdGVkTWVzc2FnZSc6IE1lc3NhZ2VUeXBlKHsKKyAgICAgICAgICAgICAgICAnTmVzdGVkRW51bSc6IEVudW1UeXBlKFsoJ0VQU0lMT04nLCA1KSwgKCdaRVRBJywgNildKSwKKyAgICAgICAgICAgICAgICAnRGVlcE5lc3RlZE1lc3NhZ2UnOiBNZXNzYWdlVHlwZSh7CisgICAgICAgICAgICAgICAgICAgICdOZXN0ZWRFbnVtJzogRW51bVR5cGUoWygnRVRBJywgNyksICgnVEhFVEEnLCA4KV0pLAorICAgICAgICAgICAgICAgIH0sIFsKKyAgICAgICAgICAgICAgICAgICAgKCduZXN0ZWRfZW51bScsIEVudW1GaWVsZCgxLCAnTmVzdGVkRW51bScsICdFVEEnKSksCisgICAgICAgICAgICAgICAgICAgICgnbmVzdGVkX2ZpZWxkJywgU3RyaW5nRmllbGQoMiwgJ3RoZXRhJykpLAorICAgICAgICAgICAgICAgIF0pLAorICAgICAgICAgICAgfSwgWworICAgICAgICAgICAgICAgICgnbmVzdGVkX2VudW0nLCBFbnVtRmllbGQoMSwgJ05lc3RlZEVudW0nLCAnWkVUQScpKSwKKyAgICAgICAgICAgICAgICAoJ25lc3RlZF9maWVsZCcsIFN0cmluZ0ZpZWxkKDIsICdiZXRhJykpLAorICAgICAgICAgICAgICAgICgnZGVlcF9uZXN0ZWRfbWVzc2FnZScsIE1lc3NhZ2VGaWVsZCgzLCAnRGVlcE5lc3RlZE1lc3NhZ2UnKSksCisgICAgICAgICAgICBdKQorICAgICAgICB9LCBbCisgICAgICAgICAgICAoJ25lc3RlZF9lbnVtJywgRW51bUZpZWxkKDEsICdOZXN0ZWRFbnVtJywgJ0JFVEEnKSksCisgICAgICAgICAgICAoJ25lc3RlZF9tZXNzYWdlJywgTWVzc2FnZUZpZWxkKDIsICdOZXN0ZWRNZXNzYWdlJykpLAorICAgICAgICBdLCBpc19leHRlbmRhYmxlPVRydWUpLAorCisgICAgICAgICdEZXNjcmlwdG9yUG9vbFRlc3QyJzogTWVzc2FnZVR5cGUoeworICAgICAgICAgICAgJ05lc3RlZEVudW0nOiBFbnVtVHlwZShbKCdHQU1NQScsIDMpLCAoJ0RFTFRBJywgNCldKSwKKyAgICAgICAgICAgICdOZXN0ZWRNZXNzYWdlJzogTWVzc2FnZVR5cGUoeworICAgICAgICAgICAgICAgICdOZXN0ZWRFbnVtJzogRW51bVR5cGUoWygnSU9UQScsIDkpLCAoJ0tBUFBBJywgMTApXSksCisgICAgICAgICAgICAgICAgJ0RlZXBOZXN0ZWRNZXNzYWdlJzogTWVzc2FnZVR5cGUoeworICAgICAgICAgICAgICAgICAgICAnTmVzdGVkRW51bSc6IEVudW1UeXBlKFsoJ0xBTUJEQScsIDExKSwgKCdNVScsIDEyKV0pLAorICAgICAgICAgICAgICAgIH0sIFsKKyAgICAgICAgICAgICAgICAgICAgKCduZXN0ZWRfZW51bScsIEVudW1GaWVsZCgxLCAnTmVzdGVkRW51bScsICdNVScpKSwKKyAgICAgICAgICAgICAgICAgICAgKCduZXN0ZWRfZmllbGQnLCBTdHJpbmdGaWVsZCgyLCAnbGFtYmRhJykpLAorICAgICAgICAgICAgICAgIF0pLAorICAgICAgICAgICAgfSwgWworICAgICAgICAgICAgICAgICgnbmVzdGVkX2VudW0nLCBFbnVtRmllbGQoMSwgJ05lc3RlZEVudW0nLCAnSU9UQScpKSwKKyAgICAgICAgICAgICAgICAoJ25lc3RlZF9maWVsZCcsIFN0cmluZ0ZpZWxkKDIsICdkZWx0YScpKSwKKyAgICAgICAgICAgICAgICAoJ2RlZXBfbmVzdGVkX21lc3NhZ2UnLCBNZXNzYWdlRmllbGQoMywgJ0RlZXBOZXN0ZWRNZXNzYWdlJykpLAorICAgICAgICAgICAgXSkKKyAgICAgICAgfSwgWworICAgICAgICAgICAgKCduZXN0ZWRfZW51bScsIEVudW1GaWVsZCgxLCAnTmVzdGVkRW51bScsICdHQU1NQScpKSwKKyAgICAgICAgICAgICgnbmVzdGVkX21lc3NhZ2UnLCBNZXNzYWdlRmllbGQoMiwgJ05lc3RlZE1lc3NhZ2UnKSksCisgICAgICAgIF0pLAorICAgIH0pCisKKworVEVTVDJfRklMRSA9IFByb3RvRmlsZSgKKyAgICAnZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0Mi5wcm90bycsCisgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwnLAorICAgIHsKKyAgICAgICAgJ0Rlc2NyaXB0b3JQb29sVGVzdDMnOiBNZXNzYWdlVHlwZSh7CisgICAgICAgICAgICAnTmVzdGVkRW51bSc6IEVudW1UeXBlKFsoJ05VJywgMTMpLCAoJ1hJJywgMTQpXSksCisgICAgICAgICAgICAnTmVzdGVkTWVzc2FnZSc6IE1lc3NhZ2VUeXBlKHsKKyAgICAgICAgICAgICAgICAnTmVzdGVkRW51bSc6IEVudW1UeXBlKFsoJ09NSUNST04nLCAxNSksICgnUEknLCAxNildKSwKKyAgICAgICAgICAgICAgICAnRGVlcE5lc3RlZE1lc3NhZ2UnOiBNZXNzYWdlVHlwZSh7CisgICAgICAgICAgICAgICAgICAgICdOZXN0ZWRFbnVtJzogRW51bVR5cGUoWygnUkhPJywgMTcpLCAoJ1NJR01BJywgMTgpXSksCisgICAgICAgICAgICAgICAgfSwgWworICAgICAgICAgICAgICAgICAgICAoJ25lc3RlZF9lbnVtJywgRW51bUZpZWxkKDEsICdOZXN0ZWRFbnVtJywgJ1JITycpKSwKKyAgICAgICAgICAgICAgICAgICAgKCduZXN0ZWRfZmllbGQnLCBTdHJpbmdGaWVsZCgyLCAnc2lnbWEnKSksCisgICAgICAgICAgICAgICAgXSksCisgICAgICAgICAgICB9LCBbCisgICAgICAgICAgICAgICAgKCduZXN0ZWRfZW51bScsIEVudW1GaWVsZCgxLCAnTmVzdGVkRW51bScsICdQSScpKSwKKyAgICAgICAgICAgICAgICAoJ25lc3RlZF9maWVsZCcsIFN0cmluZ0ZpZWxkKDIsICdudScpKSwKKyAgICAgICAgICAgICAgICAoJ2RlZXBfbmVzdGVkX21lc3NhZ2UnLCBNZXNzYWdlRmllbGQoMywgJ0RlZXBOZXN0ZWRNZXNzYWdlJykpLAorICAgICAgICAgICAgXSkKKyAgICAgICAgfSwgWworICAgICAgICAgICAgKCduZXN0ZWRfZW51bScsIEVudW1GaWVsZCgxLCAnTmVzdGVkRW51bScsICdYSScpKSwKKyAgICAgICAgICAgICgnbmVzdGVkX21lc3NhZ2UnLCBNZXNzYWdlRmllbGQoMiwgJ05lc3RlZE1lc3NhZ2UnKSksCisgICAgICAgIF0sIGV4dGVuc2lvbnM9WworICAgICAgICAgICAgKCdkZXNjcmlwdG9yX3Bvb2xfdGVzdCcsCisgICAgICAgICAgICAgRXh0ZW5zaW9uRmllbGQoMTAwMSwgJ0Rlc2NyaXB0b3JQb29sVGVzdDEnKSksCisgICAgICAgIF0pLAorICAgIH0sCisgICAgZGVwZW5kZW5jaWVzPVsnZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0MS5wcm90byddKQorCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIGJhc2V0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX3Bvb2xfdGVzdDEucHJvdG8gYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0MS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMDgxNmI3Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX3Bvb2xfdGVzdDEucHJvdG8KQEAgLTAsMCArMSw5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWw7CisKKworbWVzc2FnZSBEZXNjcmlwdG9yUG9vbFRlc3QxIHsKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKKworICBlbnVtIE5lc3RlZEVudW0geworICAgIEFMUEhBID0gMTsKKyAgICBCRVRBID0gMjsKKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAxIFtkZWZhdWx0ID0gQkVUQV07CisKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBlbnVtIE5lc3RlZEVudW0geworICAgICAgRVBTSUxPTiA9IDU7CisgICAgICBaRVRBID0gNjsKKyAgICB9CisgICAgb3B0aW9uYWwgTmVzdGVkRW51bSBuZXN0ZWRfZW51bSA9IDEgW2RlZmF1bHQgPSBaRVRBXTsKKyAgICBvcHRpb25hbCBzdHJpbmcgbmVzdGVkX2ZpZWxkID0gMiBbZGVmYXVsdCA9ICJiZXRhIl07CisgICAgb3B0aW9uYWwgRGVlcE5lc3RlZE1lc3NhZ2UgZGVlcF9uZXN0ZWRfbWVzc2FnZSA9IDM7CisKKyAgICBtZXNzYWdlIERlZXBOZXN0ZWRNZXNzYWdlIHsKKyAgICAgIGVudW0gTmVzdGVkRW51bSB7CisgICAgICAgIEVUQSA9IDc7CisgICAgICAgIFRIRVRBID0gODsKKyAgICAgIH0KKyAgICAgIG9wdGlvbmFsIE5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAxIFtkZWZhdWx0ID0gRVRBXTsKKyAgICAgIG9wdGlvbmFsIHN0cmluZyBuZXN0ZWRfZmllbGQgPSAyIFtkZWZhdWx0ID0gInRoZXRhIl07CisgICAgfQorICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZSA9IDI7Cit9CisKK21lc3NhZ2UgRGVzY3JpcHRvclBvb2xUZXN0MiB7CisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgR0FNTUEgPSAzOworICAgIERFTFRBID0gNDsKKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAxIFtkZWZhdWx0ID0gR0FNTUFdOworCisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICAgIElPVEEgPSA5OworICAgICAgS0FQUEEgPSAxMDsKKyAgICB9CisgICAgb3B0aW9uYWwgTmVzdGVkRW51bSBuZXN0ZWRfZW51bSA9IDEgW2RlZmF1bHQgPSBJT1RBXTsKKyAgICBvcHRpb25hbCBzdHJpbmcgbmVzdGVkX2ZpZWxkID0gMiBbZGVmYXVsdCA9ICJkZWx0YSJdOworICAgIG9wdGlvbmFsIERlZXBOZXN0ZWRNZXNzYWdlIGRlZXBfbmVzdGVkX21lc3NhZ2UgPSAzOworCisgICAgbWVzc2FnZSBEZWVwTmVzdGVkTWVzc2FnZSB7CisgICAgICBlbnVtIE5lc3RlZEVudW0geworICAgICAgICBMQU1CREEgPSAxMTsKKyAgICAgICAgTVUgPSAxMjsKKyAgICAgIH0KKyAgICAgIG9wdGlvbmFsIE5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAxIFtkZWZhdWx0ID0gTVVdOworICAgICAgb3B0aW9uYWwgc3RyaW5nIG5lc3RlZF9maWVsZCA9IDIgW2RlZmF1bHQgPSAibGFtYmRhIl07CisgICAgfQorICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZSA9IDI7Cit9CmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0Mi5wcm90byBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9wb29sX3Rlc3QyLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzZmE2NjAKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0Mi5wcm90bwpAQCAtMCwwICsxLDcyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9wb29sX3Rlc3QxLnByb3RvIjsKKworCittZXNzYWdlIERlc2NyaXB0b3JQb29sVGVzdDMgeworCisgIGV4dGVuZCBEZXNjcmlwdG9yUG9vbFRlc3QxIHsKKyAgICBvcHRpb25hbCBEZXNjcmlwdG9yUG9vbFRlc3QzIGRlc2NyaXB0b3JfcG9vbF90ZXN0ID0gMTAwMTsKKyAgfQorCisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgTlUgPSAxMzsKKyAgICBYSSA9IDE0OworICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBuZXN0ZWRfZW51bSA9IDEgW2RlZmF1bHQgPSBYSV07CisKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBlbnVtIE5lc3RlZEVudW0geworICAgICAgT01JQ1JPTiA9IDE1OworICAgICAgUEkgPSAxNjsKKyAgICB9CisgICAgb3B0aW9uYWwgTmVzdGVkRW51bSBuZXN0ZWRfZW51bSA9IDEgW2RlZmF1bHQgPSBQSV07CisgICAgb3B0aW9uYWwgc3RyaW5nIG5lc3RlZF9maWVsZCA9IDIgW2RlZmF1bHQgPSAibnUiXTsKKyAgICBvcHRpb25hbCBEZWVwTmVzdGVkTWVzc2FnZSBkZWVwX25lc3RlZF9tZXNzYWdlID0gMzsKKworICAgIG1lc3NhZ2UgRGVlcE5lc3RlZE1lc3NhZ2UgeworICAgICAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICAgICAgUkhPID0gMTc7CisgICAgICAgIFNJR01BID0gMTg7CisgICAgICB9CisgICAgICBvcHRpb25hbCBOZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0gMSBbZGVmYXVsdCA9IFJIT107CisgICAgICBvcHRpb25hbCBzdHJpbmcgbmVzdGVkX2ZpZWxkID0gMiBbZGVmYXVsdCA9ICJzaWdtYSJdOworICAgIH0KKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAyOworfQorCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcHl0aG9uX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcHl0aG9uX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQ3MWFlMAotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZGVzY3JpcHRvcl9weXRob25fdGVzdC5weQpAQCAtMCwwICsxLDU0IEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVW5pdHRlc3QgZm9yIGRlc2NyaXB0b3IucHkgZm9yIHRoZSBwdXJlIFB5dGhvbiBpbXBsZW1lbnRhdGlvbi4iIiIKKworaW1wb3J0IG9zCitvcy5lbnZpcm9uWydQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTiddID0gJ3B5dGhvbicKKworIyBXZSBtdXN0IHNldCB0aGUgaW1wbGVtZW50YXRpb24gdmVyc2lvbiBhYm92ZSBiZWZvcmUgdGhlIGdvb2dsZTMgaW1wb3J0cy4KKyMgcHlsaW50OiBkaXNhYmxlPWctaW1wb3J0LW5vdC1hdC10b3AKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGFwaV9pbXBsZW1lbnRhdGlvbgorIyBSdW4gYWxsIHRlc3RzIGZyb20gdGhlIG9yaWdpbmFsIG1vZHVsZSBieSBwdXR0aW5nIHRoZW0gaW4gb3VyIG5hbWVzcGFjZS4KKyMgcHlsaW50OiBkaXNhYmxlPXdpbGRjYXJkLWltcG9ydAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuZGVzY3JpcHRvcl90ZXN0IGltcG9ydCAqCisKKworY2xhc3MgQ29uZmlybVB1cmVQeXRob25UZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdEltcGxlbWVudGF0aW9uU2V0dGluZyhzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdweXRob24nLCBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpKQorCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIGJhc2V0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfdGVzdC5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi41MGM0ZGJiCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX3Rlc3QucHkKQEAgLTAsMCArMSw3NzkgQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJVbml0dGVzdCBmb3IgZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLmRlc2NyaXB0b3IuIiIiCisKK19fYXV0aG9yX18gPSAncm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbiknCisKK2ltcG9ydCBzeXMKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfaW1wb3J0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgYXBpX2ltcGxlbWVudGF0aW9uCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHN5bWJvbF9kYXRhYmFzZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHRleHRfZm9ybWF0CisKKworVEVTVF9FTVBUWV9NRVNTQUdFX0RFU0NSSVBUT1JfQVNDSUkgPSAiIiIKK25hbWU6ICdUZXN0RW1wdHlNZXNzYWdlJworIiIiCisKKworY2xhc3MgRGVzY3JpcHRvclRlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiBzZXRVcChzZWxmKToKKyAgICBmaWxlX3Byb3RvID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90bygKKyAgICAgICAgbmFtZT0nc29tZS9maWxlbmFtZS9zb21lLnByb3RvJywKKyAgICAgICAgcGFja2FnZT0ncHJvdG9idWZfdW5pdHRlc3QnKQorICAgIG1lc3NhZ2VfcHJvdG8gPSBmaWxlX3Byb3RvLm1lc3NhZ2VfdHlwZS5hZGQoCisgICAgICAgIG5hbWU9J05lc3RlZE1lc3NhZ2UnKQorICAgIG1lc3NhZ2VfcHJvdG8uZmllbGQuYWRkKAorICAgICAgICBuYW1lPSdiYicsCisgICAgICAgIG51bWJlcj0xLAorICAgICAgICB0eXBlPWRlc2NyaXB0b3JfcGIyLkZpZWxkRGVzY3JpcHRvclByb3RvLlRZUEVfSU5UMzIsCisgICAgICAgIGxhYmVsPWRlc2NyaXB0b3JfcGIyLkZpZWxkRGVzY3JpcHRvclByb3RvLkxBQkVMX09QVElPTkFMKQorICAgIGVudW1fcHJvdG8gPSBtZXNzYWdlX3Byb3RvLmVudW1fdHlwZS5hZGQoCisgICAgICAgIG5hbWU9J0ZvcmVpZ25FbnVtJykKKyAgICBlbnVtX3Byb3RvLnZhbHVlLmFkZChuYW1lPSdGT1JFSUdOX0ZPTycsIG51bWJlcj00KQorICAgIGVudW1fcHJvdG8udmFsdWUuYWRkKG5hbWU9J0ZPUkVJR05fQkFSJywgbnVtYmVyPTUpCisgICAgZW51bV9wcm90by52YWx1ZS5hZGQobmFtZT0nRk9SRUlHTl9CQVonLCBudW1iZXI9NikKKworICAgIGRlc2NyaXB0b3JfcG9vbCA9IHN5bWJvbF9kYXRhYmFzZS5EZWZhdWx0KCkucG9vbAorICAgIGRlc2NyaXB0b3JfcG9vbC5BZGQoZmlsZV9wcm90bykKKyAgICBzZWxmLm15X2ZpbGUgPSBkZXNjcmlwdG9yX3Bvb2wuRmluZEZpbGVCeU5hbWUoZmlsZV9wcm90by5uYW1lKQorICAgIHNlbGYubXlfbWVzc2FnZSA9IHNlbGYubXlfZmlsZS5tZXNzYWdlX3R5cGVzX2J5X25hbWVbbWVzc2FnZV9wcm90by5uYW1lXQorICAgIHNlbGYubXlfZW51bSA9IHNlbGYubXlfbWVzc2FnZS5lbnVtX3R5cGVzX2J5X25hbWVbZW51bV9wcm90by5uYW1lXQorCisgICAgc2VsZi5teV9tZXRob2QgPSBkZXNjcmlwdG9yLk1ldGhvZERlc2NyaXB0b3IoCisgICAgICAgIG5hbWU9J0JhcicsCisgICAgICAgIGZ1bGxfbmFtZT0ncHJvdG9idWZfdW5pdHRlc3QuVGVzdFNlcnZpY2UuQmFyJywKKyAgICAgICAgaW5kZXg9MCwKKyAgICAgICAgY29udGFpbmluZ19zZXJ2aWNlPU5vbmUsCisgICAgICAgIGlucHV0X3R5cGU9Tm9uZSwKKyAgICAgICAgb3V0cHV0X3R5cGU9Tm9uZSkKKyAgICBzZWxmLm15X3NlcnZpY2UgPSBkZXNjcmlwdG9yLlNlcnZpY2VEZXNjcmlwdG9yKAorICAgICAgICBuYW1lPSdUZXN0U2VydmljZVdpdGhPcHRpb25zJywKKyAgICAgICAgZnVsbF9uYW1lPSdwcm90b2J1Zl91bml0dGVzdC5UZXN0U2VydmljZVdpdGhPcHRpb25zJywKKyAgICAgICAgZmlsZT1zZWxmLm15X2ZpbGUsCisgICAgICAgIGluZGV4PTAsCisgICAgICAgIG1ldGhvZHM9WworICAgICAgICAgICAgc2VsZi5teV9tZXRob2QKKyAgICAgICAgXSkKKworICBkZWYgdGVzdEVudW1WYWx1ZU5hbWUoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLm15X21lc3NhZ2UuRW51bVZhbHVlTmFtZSgnRm9yZWlnbkVudW0nLCA0KSwKKyAgICAgICAgICAgICAgICAgICAgICdGT1JFSUdOX0ZPTycpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBzZWxmLm15X21lc3NhZ2UuZW51bV90eXBlc19ieV9uYW1lWworICAgICAgICAgICAgJ0ZvcmVpZ25FbnVtJ10udmFsdWVzX2J5X251bWJlcls0XS5uYW1lLAorICAgICAgICBzZWxmLm15X21lc3NhZ2UuRW51bVZhbHVlTmFtZSgnRm9yZWlnbkVudW0nLCA0KSkKKworICBkZWYgdGVzdEVudW1GaXh1cHMoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLm15X2VudW0sIHNlbGYubXlfZW51bS52YWx1ZXNbMF0udHlwZSkKKworICBkZWYgdGVzdENvbnRhaW5pbmdUeXBlRml4dXBzKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5teV9tZXNzYWdlLCBzZWxmLm15X21lc3NhZ2UuZmllbGRzWzBdLmNvbnRhaW5pbmdfdHlwZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubXlfbWVzc2FnZSwgc2VsZi5teV9lbnVtLmNvbnRhaW5pbmdfdHlwZSkKKworICBkZWYgdGVzdENvbnRhaW5pbmdTZXJ2aWNlRml4dXBzKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5teV9zZXJ2aWNlLCBzZWxmLm15X21ldGhvZC5jb250YWluaW5nX3NlcnZpY2UpCisKKyAgZGVmIHRlc3RHZXRPcHRpb25zKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5teV9lbnVtLkdldE9wdGlvbnMoKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfcGIyLkVudW1PcHRpb25zKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLm15X2VudW0udmFsdWVzWzBdLkdldE9wdGlvbnMoKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfcGIyLkVudW1WYWx1ZU9wdGlvbnMoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubXlfbWVzc2FnZS5HZXRPcHRpb25zKCksCisgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yX3BiMi5NZXNzYWdlT3B0aW9ucygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5teV9tZXNzYWdlLmZpZWxkc1swXS5HZXRPcHRpb25zKCksCisgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yX3BiMi5GaWVsZE9wdGlvbnMoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubXlfbWV0aG9kLkdldE9wdGlvbnMoKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfcGIyLk1ldGhvZE9wdGlvbnMoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubXlfc2VydmljZS5HZXRPcHRpb25zKCksCisgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yX3BiMi5TZXJ2aWNlT3B0aW9ucygpKQorCisgIGRlZiB0ZXN0U2ltcGxlQ3VzdG9tT3B0aW9ucyhzZWxmKToKKyAgICBmaWxlX2Rlc2NyaXB0b3IgPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuREVTQ1JJUFRPUgorICAgIG1lc3NhZ2VfZGVzY3JpcHRvciA9XAorICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucy5ERVNDUklQVE9SCisgICAgZmllbGRfZGVzY3JpcHRvciA9IG1lc3NhZ2VfZGVzY3JpcHRvci5maWVsZHNfYnlfbmFtZVsiZmllbGQxIl0KKyAgICBlbnVtX2Rlc2NyaXB0b3IgPSBtZXNzYWdlX2Rlc2NyaXB0b3IuZW51bV90eXBlc19ieV9uYW1lWyJBbkVudW0iXQorICAgIGVudW1fdmFsdWVfZGVzY3JpcHRvciA9XAorICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IuZW51bV92YWx1ZXNfYnlfbmFtZVsiQU5FTlVNX1ZBTDIiXQorICAgIHNlcnZpY2VfZGVzY3JpcHRvciA9XAorICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucy5ERVNDUklQVE9SCisgICAgbWV0aG9kX2Rlc2NyaXB0b3IgPSBzZXJ2aWNlX2Rlc2NyaXB0b3IuRmluZE1ldGhvZEJ5TmFtZSgiRm9vIikKKworICAgIGZpbGVfb3B0aW9ucyA9IGZpbGVfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBmaWxlX29wdDEgPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZmlsZV9vcHQxCisgICAgc2VsZi5hc3NlcnRFcXVhbCg5ODc2NTQzMjEwLCBmaWxlX29wdGlvbnMuRXh0ZW5zaW9uc1tmaWxlX29wdDFdKQorICAgIG1lc3NhZ2Vfb3B0aW9ucyA9IG1lc3NhZ2VfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBtZXNzYWdlX29wdDEgPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIubWVzc2FnZV9vcHQxCisgICAgc2VsZi5hc3NlcnRFcXVhbCgtNTYsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zW21lc3NhZ2Vfb3B0MV0pCisgICAgZmllbGRfb3B0aW9ucyA9IGZpZWxkX2Rlc2NyaXB0b3IuR2V0T3B0aW9ucygpCisgICAgZmllbGRfb3B0MSA9IHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maWVsZF9vcHQxCisgICAgc2VsZi5hc3NlcnRFcXVhbCg4NzY1NDMyMTA5LCBmaWVsZF9vcHRpb25zLkV4dGVuc2lvbnNbZmllbGRfb3B0MV0pCisgICAgZmllbGRfb3B0MiA9IHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maWVsZF9vcHQyCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0MiwgZmllbGRfb3B0aW9ucy5FeHRlbnNpb25zW2ZpZWxkX29wdDJdKQorICAgIGVudW1fb3B0aW9ucyA9IGVudW1fZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBlbnVtX29wdDEgPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZW51bV9vcHQxCisgICAgc2VsZi5hc3NlcnRFcXVhbCgtNzg5LCBlbnVtX29wdGlvbnMuRXh0ZW5zaW9uc1tlbnVtX29wdDFdKQorICAgIGVudW1fdmFsdWVfb3B0aW9ucyA9IGVudW1fdmFsdWVfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBlbnVtX3ZhbHVlX29wdDEgPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZW51bV92YWx1ZV9vcHQxCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMjMsIGVudW1fdmFsdWVfb3B0aW9ucy5FeHRlbnNpb25zW2VudW1fdmFsdWVfb3B0MV0pCisKKyAgICBzZXJ2aWNlX29wdGlvbnMgPSBzZXJ2aWNlX2Rlc2NyaXB0b3IuR2V0T3B0aW9ucygpCisgICAgc2VydmljZV9vcHQxID0gdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNlcnZpY2Vfb3B0MQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoLTk4NzY1NDMyMTAsIHNlcnZpY2Vfb3B0aW9ucy5FeHRlbnNpb25zW3NlcnZpY2Vfb3B0MV0pCisgICAgbWV0aG9kX29wdGlvbnMgPSBtZXRob2RfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBtZXRob2Rfb3B0MSA9IHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5tZXRob2Rfb3B0MQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLk1FVEhPRE9QVDFfVkFMMiwKKyAgICAgICAgICAgICAgICAgICAgIG1ldGhvZF9vcHRpb25zLkV4dGVuc2lvbnNbbWV0aG9kX29wdDFdKQorCisgICAgbWVzc2FnZV9kZXNjcmlwdG9yID0gKAorICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uREVTQ1JJUFRPUikKKyAgICBzZWxmLmFzc2VydFRydWUoZmlsZV9kZXNjcmlwdG9yLmhhc19vcHRpb25zKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobWVzc2FnZV9kZXNjcmlwdG9yLmhhc19vcHRpb25zKQorCisgIGRlZiB0ZXN0RGlmZmVyZW50Q3VzdG9tT3B0aW9uVHlwZXMoc2VsZik6CisgICAga2ludDMybWluID0gLTIqKjMxCisgICAga2ludDY0bWluID0gLTIqKjYzCisgICAga2ludDMybWF4ID0gMioqMzEgLSAxCisgICAga2ludDY0bWF4ID0gMioqNjMgLSAxCisgICAga3VpbnQzMm1heCA9IDIqKjMyIC0gMQorICAgIGt1aW50NjRtYXggPSAyKio2NCAtIDEKKworICAgIG1lc3NhZ2VfZGVzY3JpcHRvciA9XAorICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcy5ERVNDUklQVE9SCisgICAgbWVzc2FnZV9vcHRpb25zID0gbWVzc2FnZV9kZXNjcmlwdG9yLkdldE9wdGlvbnMoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoRmFsc2UsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuYm9vbF9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDMybWluLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmludDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChraW50NjRtaW4sIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuaW50NjRfb3B0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIudWludDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnVpbnQ2NF9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDMybWluLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNpbnQzMl9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDY0bWluLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNpbnQ2NF9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maXhlZDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmZpeGVkNjRfb3B0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGtpbnQzMm1pbiwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5zZml4ZWQzMl9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDY0bWluLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNmaXhlZDY0X29wdF0pCisKKyAgICBtZXNzYWdlX2Rlc2NyaXB0b3IgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMuREVTQ1JJUFRPUgorICAgIG1lc3NhZ2Vfb3B0aW9ucyA9IG1lc3NhZ2VfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFRydWUsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuYm9vbF9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDMybWF4LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmludDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChraW50NjRtYXgsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuaW50NjRfb3B0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGt1aW50MzJtYXgsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIudWludDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChrdWludDY0bWF4LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnVpbnQ2NF9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDMybWF4LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNpbnQzMl9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDY0bWF4LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNpbnQ2NF9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa3VpbnQzMm1heCwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maXhlZDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChrdWludDY0bWF4LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmZpeGVkNjRfb3B0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGtpbnQzMm1heCwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5zZml4ZWQzMl9vcHRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoa2ludDY0bWF4LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLnNmaXhlZDY0X29wdF0pCisKKyAgICBtZXNzYWdlX2Rlc2NyaXB0b3IgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzLkRFU0NSSVBUT1IKKyAgICBtZXNzYWdlX29wdGlvbnMgPSBtZXNzYWdlX2Rlc2NyaXB0b3IuR2V0T3B0aW9ucygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgtMTAwLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmludDMyX29wdF0pCisgICAgc2VsZi5hc3NlcnRBbG1vc3RFcXVhbCgxMi4zNDU2Nzg5LCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmZsb2F0X29wdF0sIDYpCisgICAgc2VsZi5hc3NlcnRBbG1vc3RFcXVhbCgxLjIzNDU2Nzg5MDEyMzQ1Njc4OSwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5kb3VibGVfb3B0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCJIZWxsbywgXCJXb3JsZFwiIiwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5zdHJpbmdfb3B0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGIiSGVsbG9cMFdvcmxkIiwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5ieXRlc19vcHRdKQorICAgIGR1bW15X2VudW0gPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0KKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBkdW1teV9lbnVtLlRFU1RfT1BUSU9OX0VOVU1fVFlQRTIsCisgICAgICAgIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zW3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5lbnVtX29wdF0pCisKKyAgICBtZXNzYWdlX2Rlc2NyaXB0b3IgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMuREVTQ1JJUFRPUgorICAgIG1lc3NhZ2Vfb3B0aW9ucyA9IG1lc3NhZ2VfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBzZWxmLmFzc2VydEFsbW9zdEVxdWFsKDEyLCBtZXNzYWdlX29wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmZsb2F0X29wdF0sIDYpCisgICAgc2VsZi5hc3NlcnRBbG1vc3RFcXVhbCgxNTQsIG1lc3NhZ2Vfb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZG91YmxlX29wdF0pCisKKyAgICBtZXNzYWdlX2Rlc2NyaXB0b3IgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMuREVTQ1JJUFRPUgorICAgIG1lc3NhZ2Vfb3B0aW9ucyA9IG1lc3NhZ2VfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBzZWxmLmFzc2VydEFsbW9zdEVxdWFsKC0xMiwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5mbG9hdF9vcHRdLCA2KQorICAgIHNlbGYuYXNzZXJ0QWxtb3N0RXF1YWwoLTE1NCwgbWVzc2FnZV9vcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5kb3VibGVfb3B0XSkKKworICBkZWYgdGVzdENvbXBsZXhFeHRlbnNpb25PcHRpb25zKHNlbGYpOgorICAgIGRlc2NyaXB0b3IgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLlZhcmlvdXNDb21wbGV4T3B0aW9ucy5ERVNDUklQVE9SCisgICAgb3B0aW9ucyA9IGRlc2NyaXB0b3IuR2V0T3B0aW9ucygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0Miwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQxXS5mb28pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzMjQsIG9wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmNvbXBsZXhfb3B0MV0uRXh0ZW5zaW9uc1sKKyAgICAgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5xdXV4XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDg3Niwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQxXS5FeHRlbnNpb25zWworICAgICAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmNvcmdlXS5xdXgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg5ODcsIG9wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmNvbXBsZXhfb3B0Ml0uYmF6KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNjU0LCBvcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5jb21wbGV4X29wdDJdLkV4dGVuc2lvbnNbCisgICAgICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZ3JhdWx0XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDc0Mywgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQyXS5iYXIuZm9vKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTk5OSwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQyXS5iYXIuRXh0ZW5zaW9uc1sKKyAgICAgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5xdXV4XSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIwMDgsIG9wdGlvbnMuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmNvbXBsZXhfb3B0Ml0uYmFyLkV4dGVuc2lvbnNbCisgICAgICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29yZ2VdLnF1eCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDc0MSwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQyXS5FeHRlbnNpb25zWworICAgICAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmdhcnBseV0uZm9vKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTk5OCwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQyXS5FeHRlbnNpb25zWworICAgICAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmdhcnBseV0uRXh0ZW5zaW9uc1sKKyAgICAgICAgICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIucXV1eF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyMTIxLCBvcHRpb25zLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5jb21wbGV4X29wdDJdLkV4dGVuc2lvbnNbCisgICAgICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZ2FycGx5XS5FeHRlbnNpb25zWworICAgICAgICAgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5jb3JnZV0ucXV4KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTk3MSwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuQ29tcGxleE9wdGlvblR5cGUyCisgICAgICAgIC5Db21wbGV4T3B0aW9uVHlwZTQuY29tcGxleF9vcHQ0XS53YWxkbykKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMyMSwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQyXS5mcmVkLndhbGRvKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoOSwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQzXS5xdXgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyMiwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleF9vcHQzXS5jb21wbGV4b3B0aW9udHlwZTUucGx1Z2gpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyNCwgb3B0aW9ucy5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuY29tcGxleG9wdDZdLnh5enp5KQorCisgICMgQ2hlY2sgdGhhdCBhZ2dyZWdhdGUgb3B0aW9ucyB3ZXJlIHBhcnNlZCBhbmQgc2F2ZWQgY29ycmVjdGx5IGluCisgICMgdGhlIGFwcHJvcHJpYXRlIGRlc2NyaXB0b3JzLgorICBkZWYgdGVzdEFnZ3JlZ2F0ZU9wdGlvbnMoc2VsZik6CisgICAgZmlsZV9kZXNjcmlwdG9yID0gdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLkRFU0NSSVBUT1IKKyAgICBtZXNzYWdlX2Rlc2NyaXB0b3IgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLkFnZ3JlZ2F0ZU1lc3NhZ2UuREVTQ1JJUFRPUgorICAgIGZpZWxkX2Rlc2NyaXB0b3IgPSBtZXNzYWdlX2Rlc2NyaXB0b3IuZmllbGRzX2J5X25hbWVbImZpZWxkbmFtZSJdCisgICAgZW51bV9kZXNjcmlwdG9yID0gdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLkFnZ3JlZ2F0ZUVudW0uREVTQ1JJUFRPUgorICAgIGVudW1fdmFsdWVfZGVzY3JpcHRvciA9IGVudW1fZGVzY3JpcHRvci52YWx1ZXNfYnlfbmFtZVsiVkFMVUUiXQorICAgIHNlcnZpY2VfZGVzY3JpcHRvciA9XAorICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuQWdncmVnYXRlU2VydmljZS5ERVNDUklQVE9SCisgICAgbWV0aG9kX2Rlc2NyaXB0b3IgPSBzZXJ2aWNlX2Rlc2NyaXB0b3IuRmluZE1ldGhvZEJ5TmFtZSgiTWV0aG9kIikKKworICAgICMgVGVzdHMgZm9yIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2YgZGF0YSBlbWJlZGRlZCBpbiBmaWxlb3B0CisgICAgZmlsZV9vcHRpb25zID0gZmlsZV9kZXNjcmlwdG9yLkdldE9wdGlvbnMoKS5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZmlsZW9wdF0KKyAgICBzZWxmLmFzc2VydEVxdWFsKDEwMCwgZmlsZV9vcHRpb25zLmkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgiRmlsZUFubm90YXRpb24iLCBmaWxlX29wdGlvbnMucykKKyAgICBzZWxmLmFzc2VydEVxdWFsKCJOZXN0ZWRGaWxlQW5ub3RhdGlvbiIsIGZpbGVfb3B0aW9ucy5zdWIucykKKyAgICBzZWxmLmFzc2VydEVxdWFsKCJGaWxlRXh0ZW5zaW9uQW5ub3RhdGlvbiIsIGZpbGVfb3B0aW9ucy5maWxlLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maWxlb3B0XS5zKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoIkVtYmVkZGVkTWVzc2FnZVNldEVsZW1lbnQiLCBmaWxlX29wdGlvbnMubXNldC5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQKKyAgICAgICAgLm1lc3NhZ2Vfc2V0X2V4dGVuc2lvbl0ucykKKworICAgICMgU2ltcGxlIHRlc3RzIGZvciBhbGwgdGhlIG90aGVyIHR5cGVzIG9mIGFubm90YXRpb25zCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgIk1lc3NhZ2VBbm5vdGF0aW9uIiwKKyAgICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yLkdldE9wdGlvbnMoKS5FeHRlbnNpb25zWworICAgICAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLm1zZ29wdF0ucykKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICAiRmllbGRBbm5vdGF0aW9uIiwKKyAgICAgICAgZmllbGRfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkuRXh0ZW5zaW9uc1sKKyAgICAgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maWVsZG9wdF0ucykKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICAiRW51bUFubm90YXRpb24iLAorICAgICAgICBlbnVtX2Rlc2NyaXB0b3IuR2V0T3B0aW9ucygpLkV4dGVuc2lvbnNbCisgICAgICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuZW51bW9wdF0ucykKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICAiRW51bVZhbHVlQW5ub3RhdGlvbiIsCisgICAgICAgIGVudW1fdmFsdWVfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkuRXh0ZW5zaW9uc1sKKyAgICAgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5lbnVtdmFsb3B0XS5zKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgICJTZXJ2aWNlQW5ub3RhdGlvbiIsCisgICAgICAgIHNlcnZpY2VfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkuRXh0ZW5zaW9uc1sKKyAgICAgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5zZXJ2aWNlb3B0XS5zKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgICJNZXRob2RBbm5vdGF0aW9uIiwKKyAgICAgICAgbWV0aG9kX2Rlc2NyaXB0b3IuR2V0T3B0aW9ucygpLkV4dGVuc2lvbnNbCisgICAgICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIubWV0aG9kb3B0XS5zKQorCisgIGRlZiB0ZXN0TmVzdGVkT3B0aW9ucyhzZWxmKToKKyAgICBuZXN0ZWRfbWVzc2FnZSA9XAorICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlLkRFU0NSSVBUT1IKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEwMDEsIG5lc3RlZF9tZXNzYWdlLkdldE9wdGlvbnMoKS5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIubWVzc2FnZV9vcHQxXSkKKyAgICBuZXN0ZWRfZmllbGQgPSBuZXN0ZWRfbWVzc2FnZS5maWVsZHNfYnlfbmFtZVsibmVzdGVkX2ZpZWxkIl0KKyAgICBzZWxmLmFzc2VydEVxdWFsKDEwMDIsIG5lc3RlZF9maWVsZC5HZXRPcHRpb25zKCkuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmZpZWxkX29wdDFdKQorICAgIG91dGVyX21lc3NhZ2UgPVwKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLk5lc3RlZE9wdGlvblR5cGUuREVTQ1JJUFRPUgorICAgIG5lc3RlZF9lbnVtID0gb3V0ZXJfbWVzc2FnZS5lbnVtX3R5cGVzX2J5X25hbWVbIk5lc3RlZEVudW0iXQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTAwMywgbmVzdGVkX2VudW0uR2V0T3B0aW9ucygpLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5lbnVtX29wdDFdKQorICAgIG5lc3RlZF9lbnVtX3ZhbHVlID0gb3V0ZXJfbWVzc2FnZS5lbnVtX3ZhbHVlc19ieV9uYW1lWyJORVNURURfRU5VTV9WQUxVRSJdCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMDA0LCBuZXN0ZWRfZW51bV92YWx1ZS5HZXRPcHRpb25zKCkuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnNfcGIyLmVudW1fdmFsdWVfb3B0MV0pCisgICAgbmVzdGVkX2V4dGVuc2lvbiA9IG91dGVyX21lc3NhZ2UuZXh0ZW5zaW9uc19ieV9uYW1lWyJuZXN0ZWRfZXh0ZW5zaW9uIl0KKyAgICBzZWxmLmFzc2VydEVxdWFsKDEwMDUsIG5lc3RlZF9leHRlbnNpb24uR2V0T3B0aW9ucygpLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5maWVsZF9vcHQyXSkKKworICBkZWYgdGVzdEZpbGVEZXNjcmlwdG9yUmVmZXJlbmNlcyhzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubXlfZW51bS5maWxlLCBzZWxmLm15X2ZpbGUpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLm15X21lc3NhZ2UuZmlsZSwgc2VsZi5teV9maWxlKQorCisgIGRlZiB0ZXN0RmlsZURlc2NyaXB0b3Ioc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLm15X2ZpbGUubmFtZSwgJ3NvbWUvZmlsZW5hbWUvc29tZS5wcm90bycpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLm15X2ZpbGUucGFja2FnZSwgJ3Byb3RvYnVmX3VuaXR0ZXN0JykKKworICBAYmFzZXRlc3QudW5pdHRlc3Quc2tpcElmKAorICAgICAgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSAhPSAnY3BwJyBvciBhcGlfaW1wbGVtZW50YXRpb24uVmVyc2lvbigpICE9IDIsCisgICAgICAnSW1tdXRhYmlsaXR5IG9mIGRlc2NyaXB0b3JzIGlzIG9ubHkgZW5mb3JjZWQgaW4gdjIgaW1wbGVtZW50YXRpb24nKQorICBkZWYgdGVzdEltbXV0YWJsZUNwcERlc2NyaXB0b3Ioc2VsZik6CisgICAgbWVzc2FnZV9kZXNjcmlwdG9yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5ERVNDUklQVE9SCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhBdHRyaWJ1dGVFcnJvcik6CisgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IuZmllbGRzX2J5X25hbWUgPSBOb25lCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IpOgorICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lWydBbm90aGVyJ10gPSBOb25lCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IpOgorICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkcy5hcHBlbmQoTm9uZSkKKworCitjbGFzcyBHZW5lcmF0ZWREZXNjcmlwdG9yVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisgICIiIlRlc3RzIGZvciB0aGUgcHJvcGVydGllcyBvZiBkZXNjcmlwdG9ycyBpbiBnZW5lcmF0ZWQgY29kZS4iIiIKKworICBkZWYgQ2hlY2tNZXNzYWdlRGVzY3JpcHRvcihzZWxmLCBtZXNzYWdlX2Rlc2NyaXB0b3IpOgorICAgICMgQmFzaWMgcHJvcGVydGllcworICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZV9kZXNjcmlwdG9yLm5hbWUsICdUZXN0QWxsVHlwZXMnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZV9kZXNjcmlwdG9yLmZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMnKQorICAgICMgVGVzdCBlcXVhbGl0eSBhbmQgaGFzaGFiaWxpdHkKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2VfZGVzY3JpcHRvciwgbWVzc2FnZV9kZXNjcmlwdG9yKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc1swXS5jb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IpCisgICAgc2VsZi5hc3NlcnRJbihtZXNzYWdlX2Rlc2NyaXB0b3IsIFttZXNzYWdlX2Rlc2NyaXB0b3JdKQorICAgIHNlbGYuYXNzZXJ0SW4obWVzc2FnZV9kZXNjcmlwdG9yLCB7bWVzc2FnZV9kZXNjcmlwdG9yOiBOb25lfSkKKyAgICAjIFRlc3QgZmllbGQgY29udGFpbmVycworICAgIHNlbGYuQ2hlY2tEZXNjcmlwdG9yU2VxdWVuY2UobWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkcykKKyAgICBzZWxmLkNoZWNrRGVzY3JpcHRvck1hcHBpbmcobWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lKQorICAgIHNlbGYuQ2hlY2tEZXNjcmlwdG9yTWFwcGluZyhtZXNzYWdlX2Rlc2NyaXB0b3IuZmllbGRzX2J5X251bWJlcikKKworICBkZWYgQ2hlY2tGaWVsZERlc2NyaXB0b3Ioc2VsZiwgZmllbGRfZGVzY3JpcHRvcik6CisgICAgIyBCYXNpYyBwcm9wZXJ0aWVzCisgICAgc2VsZi5hc3NlcnRFcXVhbChmaWVsZF9kZXNjcmlwdG9yLm5hbWUsICdvcHRpb25hbF9pbnQzMicpCisgICAgc2VsZi5hc3NlcnRFcXVhbChmaWVsZF9kZXNjcmlwdG9yLmZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMub3B0aW9uYWxfaW50MzInKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmllbGRfZGVzY3JpcHRvci5jb250YWluaW5nX3R5cGUubmFtZSwgJ1Rlc3RBbGxUeXBlcycpCisgICAgIyBUZXN0IGVxdWFsaXR5IGFuZCBoYXNoYWJpbGl0eQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmllbGRfZGVzY3JpcHRvciwgZmllbGRfZGVzY3JpcHRvcikKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLmNvbnRhaW5pbmdfdHlwZS5maWVsZHNfYnlfbmFtZVsnb3B0aW9uYWxfaW50MzInXSwKKyAgICAgICAgZmllbGRfZGVzY3JpcHRvcikKKyAgICBzZWxmLmFzc2VydEluKGZpZWxkX2Rlc2NyaXB0b3IsIFtmaWVsZF9kZXNjcmlwdG9yXSkKKyAgICBzZWxmLmFzc2VydEluKGZpZWxkX2Rlc2NyaXB0b3IsIHtmaWVsZF9kZXNjcmlwdG9yOiBOb25lfSkKKworICBkZWYgQ2hlY2tEZXNjcmlwdG9yU2VxdWVuY2Uoc2VsZiwgc2VxdWVuY2UpOgorICAgICMgVmVyaWZpZXMgdGhhdCBhIHByb3BlcnR5IGxpa2UgJ21lc3NhZ2VEZXNjcmlwdG9yLmZpZWxkcycgaGFzIGFsbCB0aGUKKyAgICAjIHByb3BlcnRpZXMgb2YgYW4gaW1tdXRhYmxlIGFiYy5TZXF1ZW5jZS4KKyAgICBzZWxmLmFzc2VydEdyZWF0ZXIobGVuKHNlcXVlbmNlKSwgMCkgICMgU2l6ZWQKKyAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihzZXF1ZW5jZSksIGxlbihsaXN0KHNlcXVlbmNlKSkpICAjIEl0ZXJhYmxlCisgICAgaXRlbSA9IHNlcXVlbmNlWzBdCisgICAgc2VsZi5hc3NlcnRFcXVhbChpdGVtLCBzZXF1ZW5jZVswXSkKKyAgICBzZWxmLmFzc2VydEluKGl0ZW0sIHNlcXVlbmNlKSAgIyBDb250YWluZXIKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlcXVlbmNlLmluZGV4KGl0ZW0pLCAwKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VxdWVuY2UuY291bnQoaXRlbSksIDEpCisgICAgcmV2ZXJzZWRfaXRlcmF0b3IgPSByZXZlcnNlZChzZXF1ZW5jZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGxpc3QocmV2ZXJzZWRfaXRlcmF0b3IpLCBsaXN0KHNlcXVlbmNlKVs6Oi0xXSkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhTdG9wSXRlcmF0aW9uLCBuZXh0LCByZXZlcnNlZF9pdGVyYXRvcikKKworICBkZWYgQ2hlY2tEZXNjcmlwdG9yTWFwcGluZyhzZWxmLCBtYXBwaW5nKToKKyAgICAjIFZlcmlmaWVzIHRoYXQgYSBwcm9wZXJ0eSBsaWtlICdtZXNzYWdlRGVzY3JpcHRvci5maWVsZHMnIGhhcyBhbGwgdGhlCisgICAgIyBwcm9wZXJ0aWVzIG9mIGFuIGltbXV0YWJsZSBhYmMuTWFwcGluZy4KKyAgICBzZWxmLmFzc2VydEdyZWF0ZXIobGVuKG1hcHBpbmcpLCAwKSAgIyBTaXplZAorICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKG1hcHBpbmcpLCBsZW4obGlzdChtYXBwaW5nKSkpICAjIEl0ZXJhYmxlCisgICAgaWYgc3lzLnZlcnNpb25faW5mby5tYWpvciA+PSAzOgorICAgICAga2V5LCBpdGVtID0gbmV4dChpdGVyKG1hcHBpbmcuaXRlbXMoKSkpCisgICAgZWxzZToKKyAgICAgIGtleSwgaXRlbSA9IG1hcHBpbmcuaXRlbXMoKVswXQorICAgIHNlbGYuYXNzZXJ0SW4oa2V5LCBtYXBwaW5nKSAgIyBDb250YWluZXIKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1hcHBpbmcuZ2V0KGtleSksIGl0ZW0pCisgICAgIyBrZXlzKCksIGl0ZXJrZXlzKCkgJmNvCisgICAgaXRlbSA9IChuZXh0KGl0ZXIobWFwcGluZy5rZXlzKCkpKSwgbmV4dChpdGVyKG1hcHBpbmcudmFsdWVzKCkpKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGl0ZW0sIG5leHQoaXRlcihtYXBwaW5nLml0ZW1zKCkpKSkKKyAgICBpZiBzeXMudmVyc2lvbl9pbmZvLm1ham9yIDwgMzoKKyAgICAgIGRlZiBDaGVja0l0ZW1zKHNlcSwgaXRlcmF0b3IpOgorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG5leHQoaXRlcmF0b3IpLCBzZXFbMF0pCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGlzdChpdGVyYXRvciksIHNlcVsxOl0pCisgICAgICBDaGVja0l0ZW1zKG1hcHBpbmcua2V5cygpLCBtYXBwaW5nLml0ZXJrZXlzKCkpCisgICAgICBDaGVja0l0ZW1zKG1hcHBpbmcudmFsdWVzKCksIG1hcHBpbmcuaXRlcnZhbHVlcygpKQorICAgICAgQ2hlY2tJdGVtcyhtYXBwaW5nLml0ZW1zKCksIG1hcHBpbmcuaXRlcml0ZW1zKCkpCisKKyAgZGVmIHRlc3REZXNjcmlwdG9yKHNlbGYpOgorICAgIG1lc3NhZ2VfZGVzY3JpcHRvciA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuREVTQ1JJUFRPUgorICAgIHNlbGYuQ2hlY2tNZXNzYWdlRGVzY3JpcHRvcihtZXNzYWdlX2Rlc2NyaXB0b3IpCisgICAgZmllbGRfZGVzY3JpcHRvciA9IG1lc3NhZ2VfZGVzY3JpcHRvci5maWVsZHNfYnlfbmFtZVsnb3B0aW9uYWxfaW50MzInXQorICAgIHNlbGYuQ2hlY2tGaWVsZERlc2NyaXB0b3IoZmllbGRfZGVzY3JpcHRvcikKKworICBkZWYgdGVzdENwcERlc2NyaXB0b3JDb250YWluZXIoc2VsZik6CisgICAgIyBDaGVjayB0aGF0IHRoZSBjb2xsZWN0aW9uIGlzIHN0aWxsIHZhbGlkIGV2ZW4gaWYgdGhlIHBhcmVudCBkaXNhcHBlYXJlZC4KKyAgICBlbnVtID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5ERVNDUklQVE9SLmVudW1fdHlwZXNfYnlfbmFtZVsnTmVzdGVkRW51bSddCisgICAgdmFsdWVzID0gZW51bS52YWx1ZXMKKyAgICBkZWwgZW51bQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ0ZPTycsIHZhbHVlc1swXS5uYW1lKQorCisgIGRlZiB0ZXN0Q3BwRGVzY3JpcHRvckNvbnRhaW5lcl9JdGVyYXRvcihzZWxmKToKKyAgICAjIFNhbWUgdGVzdCB3aXRoIHRoZSBpdGVyYXRvcgorICAgIGVudW0gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IuZW51bV90eXBlc19ieV9uYW1lWydOZXN0ZWRFbnVtJ10KKyAgICB2YWx1ZXNfaXRlciA9IGl0ZXIoZW51bS52YWx1ZXMpCisgICAgZGVsIGVudW0KKyAgICBzZWxmLmFzc2VydEVxdWFsKCdGT08nLCBuZXh0KHZhbHVlc19pdGVyKS5uYW1lKQorCisKK2NsYXNzIERlc2NyaXB0b3JDb3B5VG9Qcm90b1Rlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorICAiIiJUZXN0cyBmb3IgQ29weVRvIGZ1bmN0aW9ucyBvZiBEZXNjcmlwdG9yLiIiIgorCisgIGRlZiBfQXNzZXJ0UHJvdG9FcXVhbChzZWxmLCBhY3R1YWxfcHJvdG8sIGV4cGVjdGVkX2NsYXNzLCBleHBlY3RlZF9hc2NpaSk6CisgICAgZXhwZWN0ZWRfcHJvdG8gPSBleHBlY3RlZF9jbGFzcygpCisgICAgdGV4dF9mb3JtYXQuTWVyZ2UoZXhwZWN0ZWRfYXNjaWksIGV4cGVjdGVkX3Byb3RvKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgYWN0dWFsX3Byb3RvLCBleHBlY3RlZF9wcm90bywKKyAgICAgICAgJ05vdCBlcXVhbCxcbkFjdHVhbDpcbiVzXG5FeHBlY3RlZDpcbiVzXG4nCisgICAgICAgICUgKHN0cihhY3R1YWxfcHJvdG8pLCBzdHIoZXhwZWN0ZWRfcHJvdG8pKSkKKworICBkZWYgX0ludGVybmFsVGVzdENvcHlUb1Byb3RvKHNlbGYsIGRlc2MsIGV4cGVjdGVkX3Byb3RvX2NsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkX3Byb3RvX2FzY2lpKToKKyAgICBhY3R1YWwgPSBleHBlY3RlZF9wcm90b19jbGFzcygpCisgICAgZGVzYy5Db3B5VG9Qcm90byhhY3R1YWwpCisgICAgc2VsZi5fQXNzZXJ0UHJvdG9FcXVhbCgKKyAgICAgICAgYWN0dWFsLCBleHBlY3RlZF9wcm90b19jbGFzcywgZXhwZWN0ZWRfcHJvdG9fYXNjaWkpCisKKyAgZGVmIHRlc3RDb3B5VG9Qcm90b19FbXB0eU1lc3NhZ2Uoc2VsZik6CisgICAgc2VsZi5fSW50ZXJuYWxUZXN0Q29weVRvUHJvdG8oCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlLkRFU0NSSVBUT1IsCisgICAgICAgIGRlc2NyaXB0b3JfcGIyLkRlc2NyaXB0b3JQcm90bywKKyAgICAgICAgVEVTVF9FTVBUWV9NRVNTQUdFX0RFU0NSSVBUT1JfQVNDSUkpCisKKyAgZGVmIHRlc3RDb3B5VG9Qcm90b19OZXN0ZWRNZXNzYWdlKHNlbGYpOgorICAgIFRFU1RfTkVTVEVEX01FU1NBR0VfQVNDSUkgPSAiIiIKKyAgICAgIG5hbWU6ICdOZXN0ZWRNZXNzYWdlJworICAgICAgZmllbGQ6IDwKKyAgICAgICAgbmFtZTogJ2JiJworICAgICAgICBudW1iZXI6IDEKKyAgICAgICAgbGFiZWw6IDEgICMgT3B0aW9uYWwKKyAgICAgICAgdHlwZTogNSAgIyBUWVBFX0lOVDMyCisgICAgICA+CisgICAgICAiIiIKKworICAgIHNlbGYuX0ludGVybmFsVGVzdENvcHlUb1Byb3RvKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuREVTQ1JJUFRPUiwKKyAgICAgICAgZGVzY3JpcHRvcl9wYjIuRGVzY3JpcHRvclByb3RvLAorICAgICAgICBURVNUX05FU1RFRF9NRVNTQUdFX0FTQ0lJKQorCisgIGRlZiB0ZXN0Q29weVRvUHJvdG9fRm9yZWlnbk5lc3RlZE1lc3NhZ2Uoc2VsZik6CisgICAgVEVTVF9GT1JFSUdOX05FU1RFRF9BU0NJSSA9ICIiIgorICAgICAgbmFtZTogJ1Rlc3RGb3JlaWduTmVzdGVkJworICAgICAgZmllbGQ6IDwKKyAgICAgICAgbmFtZTogJ2ZvcmVpZ25fbmVzdGVkJworICAgICAgICBudW1iZXI6IDEKKyAgICAgICAgbGFiZWw6IDEgICMgT3B0aW9uYWwKKyAgICAgICAgdHlwZTogMTEgICMgVFlQRV9NRVNTQUdFCisgICAgICAgIHR5cGVfbmFtZTogJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZScKKyAgICAgID4KKyAgICAgICIiIgorCisgICAgc2VsZi5fSW50ZXJuYWxUZXN0Q29weVRvUHJvdG8oCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0Rm9yZWlnbk5lc3RlZC5ERVNDUklQVE9SLAorICAgICAgICBkZXNjcmlwdG9yX3BiMi5EZXNjcmlwdG9yUHJvdG8sCisgICAgICAgIFRFU1RfRk9SRUlHTl9ORVNURURfQVNDSUkpCisKKyAgZGVmIHRlc3RDb3B5VG9Qcm90b19Gb3JlaWduRW51bShzZWxmKToKKyAgICBURVNUX0ZPUkVJR05fRU5VTV9BU0NJSSA9ICIiIgorICAgICAgbmFtZTogJ0ZvcmVpZ25FbnVtJworICAgICAgdmFsdWU6IDwKKyAgICAgICAgbmFtZTogJ0ZPUkVJR05fRk9PJworICAgICAgICBudW1iZXI6IDQKKyAgICAgID4KKyAgICAgIHZhbHVlOiA8CisgICAgICAgIG5hbWU6ICdGT1JFSUdOX0JBUicKKyAgICAgICAgbnVtYmVyOiA1CisgICAgICA+CisgICAgICB2YWx1ZTogPAorICAgICAgICBuYW1lOiAnRk9SRUlHTl9CQVonCisgICAgICAgIG51bWJlcjogNgorICAgICAgPgorICAgICAgIiIiCisKKyAgICBzZWxmLl9JbnRlcm5hbFRlc3RDb3B5VG9Qcm90bygKKyAgICAgICAgdW5pdHRlc3RfcGIyLl9GT1JFSUdORU5VTSwKKyAgICAgICAgZGVzY3JpcHRvcl9wYjIuRW51bURlc2NyaXB0b3JQcm90bywKKyAgICAgICAgVEVTVF9GT1JFSUdOX0VOVU1fQVNDSUkpCisKKyAgZGVmIHRlc3RDb3B5VG9Qcm90b19PcHRpb25zKHNlbGYpOgorICAgIFRFU1RfREVQUkVDQVRFRF9GSUVMRFNfQVNDSUkgPSAiIiIKKyAgICAgIG5hbWU6ICdUZXN0RGVwcmVjYXRlZEZpZWxkcycKKyAgICAgIGZpZWxkOiA8CisgICAgICAgIG5hbWU6ICdkZXByZWNhdGVkX2ludDMyJworICAgICAgICBudW1iZXI6IDEKKyAgICAgICAgbGFiZWw6IDEgICMgT3B0aW9uYWwKKyAgICAgICAgdHlwZTogNSAgIyBUWVBFX0lOVDMyCisgICAgICAgIG9wdGlvbnM6IDwKKyAgICAgICAgICBkZXByZWNhdGVkOiB0cnVlCisgICAgICAgID4KKyAgICAgID4KKyAgICAgICIiIgorCisgICAgc2VsZi5fSW50ZXJuYWxUZXN0Q29weVRvUHJvdG8oCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0RGVwcmVjYXRlZEZpZWxkcy5ERVNDUklQVE9SLAorICAgICAgICBkZXNjcmlwdG9yX3BiMi5EZXNjcmlwdG9yUHJvdG8sCisgICAgICAgIFRFU1RfREVQUkVDQVRFRF9GSUVMRFNfQVNDSUkpCisKKyAgZGVmIHRlc3RDb3B5VG9Qcm90b19BbGxFeHRlbnNpb25zKHNlbGYpOgorICAgIFRFU1RfRU1QVFlfTUVTU0FHRV9XSVRIX0VYVEVOU0lPTlNfQVNDSUkgPSAiIiIKKyAgICAgIG5hbWU6ICdUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMnCisgICAgICBleHRlbnNpb25fcmFuZ2U6IDwKKyAgICAgICAgc3RhcnQ6IDEKKyAgICAgICAgZW5kOiA1MzY4NzA5MTIKKyAgICAgID4KKyAgICAgICIiIgorCisgICAgc2VsZi5fSW50ZXJuYWxUZXN0Q29weVRvUHJvdG8oCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMuREVTQ1JJUFRPUiwKKyAgICAgICAgZGVzY3JpcHRvcl9wYjIuRGVzY3JpcHRvclByb3RvLAorICAgICAgICBURVNUX0VNUFRZX01FU1NBR0VfV0lUSF9FWFRFTlNJT05TX0FTQ0lJKQorCisgIGRlZiB0ZXN0Q29weVRvUHJvdG9fU2V2ZXJhbEV4dGVuc2lvbnMoc2VsZik6CisgICAgVEVTVF9NRVNTQUdFX1dJVEhfU0VWRVJBTF9FWFRFTlNJT05TX0FTQ0lJID0gIiIiCisgICAgICBuYW1lOiAnVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzJworICAgICAgZXh0ZW5zaW9uX3JhbmdlOiA8CisgICAgICAgIHN0YXJ0OiA0MgorICAgICAgICBlbmQ6IDQzCisgICAgICA+CisgICAgICBleHRlbnNpb25fcmFuZ2U6IDwKKyAgICAgICAgc3RhcnQ6IDQxNDMKKyAgICAgICAgZW5kOiA0MjQ0CisgICAgICA+CisgICAgICBleHRlbnNpb25fcmFuZ2U6IDwKKyAgICAgICAgc3RhcnQ6IDY1NTM2CisgICAgICAgIGVuZDogNTM2ODcwOTEyCisgICAgICA+CisgICAgICAiIiIKKworICAgIHNlbGYuX0ludGVybmFsVGVzdENvcHlUb1Byb3RvKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzLkRFU0NSSVBUT1IsCisgICAgICAgIGRlc2NyaXB0b3JfcGIyLkRlc2NyaXB0b3JQcm90bywKKyAgICAgICAgVEVTVF9NRVNTQUdFX1dJVEhfU0VWRVJBTF9FWFRFTlNJT05TX0FTQ0lJKQorCisgICMgRGlzYWJsZSB0aGlzIHRlc3Qgc28gd2UgY2FuIG1ha2UgY2hhbmdlcyB0byB0aGUgcHJvdG8gZmlsZS4KKyAgIyBUT0RPKHhpYW9mZW5nKTogRW5hYmxlIHRoaXMgdGVzdCBhZnRlciBjbC81NTUzMDY1OSBpcyBzdWJtaXR0ZWQuCisgICMKKyAgIyBkZWYgdGVzdENvcHlUb1Byb3RvX0ZpbGVEZXNjcmlwdG9yKHNlbGYpOgorICAjICAgVU5JVFRFU1RfSU1QT1JUX0ZJTEVfREVTQ1JJUFRPUl9BU0NJSSA9ICgiIiIKKyAgIyAgICAgbmFtZTogJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG8nCisgICMgICAgIHBhY2thZ2U6ICdwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQnCisgICMgICAgIGRlcGVuZGVuY3k6ICdnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bycKKyAgIyAgICAgbWVzc2FnZV90eXBlOiA8CisgICMgICAgICAgbmFtZTogJ0ltcG9ydE1lc3NhZ2UnCisgICMgICAgICAgZmllbGQ6IDwKKyAgIyAgICAgICAgIG5hbWU6ICdkJworICAjICAgICAgICAgbnVtYmVyOiAxCisgICMgICAgICAgICBsYWJlbDogMSAgIyBPcHRpb25hbAorICAjICAgICAgICAgdHlwZTogNSAgIyBUWVBFX0lOVDMyCisgICMgICAgICAgPgorICAjICAgICA+CisgICMgICAgICIiIiArCisgICMgICAgICIiImVudW1fdHlwZTogPAorICAjICAgICAgIG5hbWU6ICdJbXBvcnRFbnVtJworICAjICAgICAgIHZhbHVlOiA8CisgICMgICAgICAgICBuYW1lOiAnSU1QT1JUX0ZPTycKKyAgIyAgICAgICAgIG51bWJlcjogNworICAjICAgICAgID4KKyAgIyAgICAgICB2YWx1ZTogPAorICAjICAgICAgICAgbmFtZTogJ0lNUE9SVF9CQVInCisgICMgICAgICAgICBudW1iZXI6IDgKKyAgIyAgICAgICA+CisgICMgICAgICAgdmFsdWU6IDwKKyAgIyAgICAgICAgIG5hbWU6ICdJTVBPUlRfQkFaJworICAjICAgICAgICAgbnVtYmVyOiA5CisgICMgICAgICAgPgorICAjICAgICA+CisgICMgICAgIG9wdGlvbnM6IDwKKyAgIyAgICAgICBqYXZhX3BhY2thZ2U6ICdjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QnCisgICMgICAgICAgb3B0aW1pemVfZm9yOiAxICAjIFNQRUVECisgICMgICAgID4KKyAgIyAgICAgcHVibGljX2RlcGVuZGVuY3k6IDAKKyAgIyAgIiIiKQorICAjICBzZWxmLl9JbnRlcm5hbFRlc3RDb3B5VG9Qcm90bygKKyAgIyAgICAgIHVuaXR0ZXN0X2ltcG9ydF9wYjIuREVTQ1JJUFRPUiwKKyAgIyAgICAgIGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8sCisgICMgICAgICBVTklUVEVTVF9JTVBPUlRfRklMRV9ERVNDUklQVE9SX0FTQ0lJKQorCisgIGRlZiB0ZXN0Q29weVRvUHJvdG9fU2VydmljZURlc2NyaXB0b3Ioc2VsZik6CisgICAgVEVTVF9TRVJWSUNFX0FTQ0lJID0gIiIiCisgICAgICBuYW1lOiAnVGVzdFNlcnZpY2UnCisgICAgICBtZXRob2Q6IDwKKyAgICAgICAgbmFtZTogJ0ZvbycKKyAgICAgICAgaW5wdXRfdHlwZTogJy5wcm90b2J1Zl91bml0dGVzdC5Gb29SZXF1ZXN0JworICAgICAgICBvdXRwdXRfdHlwZTogJy5wcm90b2J1Zl91bml0dGVzdC5Gb29SZXNwb25zZScKKyAgICAgID4KKyAgICAgIG1ldGhvZDogPAorICAgICAgICBuYW1lOiAnQmFyJworICAgICAgICBpbnB1dF90eXBlOiAnLnByb3RvYnVmX3VuaXR0ZXN0LkJhclJlcXVlc3QnCisgICAgICAgIG91dHB1dF90eXBlOiAnLnByb3RvYnVmX3VuaXR0ZXN0LkJhclJlc3BvbnNlJworICAgICAgPgorICAgICAgIiIiCisgICAgIyBUT0RPKHJvY2tpbmcpOiBlbmFibGUgdGhpcyB0ZXN0IGFmdGVyIHRoZSBwcm90byBkZXNjcmlwdG9yIGNoYW5nZSBpcworICAgICMgY2hlY2tlZCBpbi4KKyAgICAjc2VsZi5fSW50ZXJuYWxUZXN0Q29weVRvUHJvdG8oCisgICAgIyAgICB1bml0dGVzdF9wYjIuVGVzdFNlcnZpY2UuREVTQ1JJUFRPUiwKKyAgICAjICAgIGRlc2NyaXB0b3JfcGIyLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8sCisgICAgIyAgICBURVNUX1NFUlZJQ0VfQVNDSUkpCisKKworY2xhc3MgTWFrZURlc2NyaXB0b3JUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdE1ha2VEZXNjcmlwdG9yV2l0aE5lc3RlZEZpZWxkcyhzZWxmKToKKyAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8gPSBkZXNjcmlwdG9yX3BiMi5GaWxlRGVzY3JpcHRvclByb3RvKCkKKyAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubmFtZSA9ICdGb28yJworICAgIG1lc3NhZ2VfdHlwZSA9IGZpbGVfZGVzY3JpcHRvcl9wcm90by5tZXNzYWdlX3R5cGUuYWRkKCkKKyAgICBtZXNzYWdlX3R5cGUubmFtZSA9IGZpbGVfZGVzY3JpcHRvcl9wcm90by5uYW1lCisgICAgbmVzdGVkX3R5cGUgPSBtZXNzYWdlX3R5cGUubmVzdGVkX3R5cGUuYWRkKCkKKyAgICBuZXN0ZWRfdHlwZS5uYW1lID0gJ1N1YicKKyAgICBlbnVtX3R5cGUgPSBuZXN0ZWRfdHlwZS5lbnVtX3R5cGUuYWRkKCkKKyAgICBlbnVtX3R5cGUubmFtZSA9ICdGT08nCisgICAgZW51bV90eXBlX3ZhbCA9IGVudW1fdHlwZS52YWx1ZS5hZGQoKQorICAgIGVudW1fdHlwZV92YWwubmFtZSA9ICdCQVInCisgICAgZW51bV90eXBlX3ZhbC5udW1iZXIgPSAzCisgICAgZmllbGQgPSBtZXNzYWdlX3R5cGUuZmllbGQuYWRkKCkKKyAgICBmaWVsZC5udW1iZXIgPSAxCisgICAgZmllbGQubmFtZSA9ICd1aW50NjRfZmllbGQnCisgICAgZmllbGQubGFiZWwgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVFVSVJFRAorICAgIGZpZWxkLnR5cGUgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX1VJTlQ2NAorICAgIGZpZWxkID0gbWVzc2FnZV90eXBlLmZpZWxkLmFkZCgpCisgICAgZmllbGQubnVtYmVyID0gMgorICAgIGZpZWxkLm5hbWUgPSAnbmVzdGVkX21lc3NhZ2VfZmllbGQnCisgICAgZmllbGQubGFiZWwgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVFVSVJFRAorICAgIGZpZWxkLnR5cGUgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0UKKyAgICBmaWVsZC50eXBlX25hbWUgPSAnU3ViJworICAgIGVudW1fZmllbGQgPSBuZXN0ZWRfdHlwZS5maWVsZC5hZGQoKQorICAgIGVudW1fZmllbGQubnVtYmVyID0gMgorICAgIGVudW1fZmllbGQubmFtZSA9ICdiYXJfZmllbGQnCisgICAgZW51bV9maWVsZC5sYWJlbCA9IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkxBQkVMX1JFUVVJUkVECisgICAgZW51bV9maWVsZC50eXBlID0gZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9FTlVNCisgICAgZW51bV9maWVsZC50eXBlX25hbWUgPSAnRm9vMi5TdWIuRk9PJworCisgICAgcmVzdWx0ID0gZGVzY3JpcHRvci5NYWtlRGVzY3JpcHRvcihtZXNzYWdlX3R5cGUpCisgICAgc2VsZi5hc3NlcnRFcXVhbChyZXN1bHQuZmllbGRzWzBdLmNwcF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9VSU5UNjQpCisgICAgc2VsZi5hc3NlcnRFcXVhbChyZXN1bHQuZmllbGRzWzFdLmNwcF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9NRVNTQUdFKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0LmZpZWxkc1sxXS5tZXNzYWdlX3R5cGUuY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgcmVzdWx0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0Lm5lc3RlZF90eXBlc1swXS5maWVsZHNbMF0uZnVsbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgJ0ZvbzIuU3ViLmJhcl9maWVsZCcpCisgICAgc2VsZi5hc3NlcnRFcXVhbChyZXN1bHQubmVzdGVkX3R5cGVzWzBdLmZpZWxkc1swXS5lbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICByZXN1bHQubmVzdGVkX3R5cGVzWzBdLmVudW1fdHlwZXNbMF0pCisKKyAgZGVmIHRlc3RNYWtlRGVzY3JpcHRvcldpdGhVbnNpZ25lZEludEZpZWxkKHNlbGYpOgorICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90byA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8oKQorICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by5uYW1lID0gJ0ZvbycKKyAgICBtZXNzYWdlX3R5cGUgPSBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubWVzc2FnZV90eXBlLmFkZCgpCisgICAgbWVzc2FnZV90eXBlLm5hbWUgPSBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubmFtZQorICAgIGVudW1fdHlwZSA9IG1lc3NhZ2VfdHlwZS5lbnVtX3R5cGUuYWRkKCkKKyAgICBlbnVtX3R5cGUubmFtZSA9ICdGT08nCisgICAgZW51bV90eXBlX3ZhbCA9IGVudW1fdHlwZS52YWx1ZS5hZGQoKQorICAgIGVudW1fdHlwZV92YWwubmFtZSA9ICdCQVInCisgICAgZW51bV90eXBlX3ZhbC5udW1iZXIgPSAzCisgICAgZmllbGQgPSBtZXNzYWdlX3R5cGUuZmllbGQuYWRkKCkKKyAgICBmaWVsZC5udW1iZXIgPSAxCisgICAgZmllbGQubmFtZSA9ICd1aW50NjRfZmllbGQnCisgICAgZmllbGQubGFiZWwgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVFVSVJFRAorICAgIGZpZWxkLnR5cGUgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX1VJTlQ2NAorICAgIGVudW1fZmllbGQgPSBtZXNzYWdlX3R5cGUuZmllbGQuYWRkKCkKKyAgICBlbnVtX2ZpZWxkLm51bWJlciA9IDIKKyAgICBlbnVtX2ZpZWxkLm5hbWUgPSAnYmFyX2ZpZWxkJworICAgIGVudW1fZmllbGQubGFiZWwgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVFVSVJFRAorICAgIGVudW1fZmllbGQudHlwZSA9IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfRU5VTQorICAgIGVudW1fZmllbGQudHlwZV9uYW1lID0gJ0Zvby5GT08nCisKKyAgICByZXN1bHQgPSBkZXNjcmlwdG9yLk1ha2VEZXNjcmlwdG9yKG1lc3NhZ2VfdHlwZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdC5maWVsZHNbMF0uY3BwX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX1VJTlQ2NCkKKworCisgIGRlZiB0ZXN0TWFrZURlc2NyaXB0b3JXaXRoT3B0aW9ucyhzZWxmKToKKyAgICBkZXNjcmlwdG9yX3Byb3RvID0gZGVzY3JpcHRvcl9wYjIuRGVzY3JpcHRvclByb3RvKCkKKyAgICBhZ2dyZWdhdGVfbWVzc2FnZSA9IHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5BZ2dyZWdhdGVNZXNzYWdlCisgICAgYWdncmVnYXRlX21lc3NhZ2UuREVTQ1JJUFRPUi5Db3B5VG9Qcm90byhkZXNjcmlwdG9yX3Byb3RvKQorICAgIHJlZm9ybWVkX2Rlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLk1ha2VEZXNjcmlwdG9yKGRlc2NyaXB0b3JfcHJvdG8pCisKKyAgICBvcHRpb25zID0gcmVmb3JtZWRfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkKKyAgICBzZWxmLmFzc2VydEVxdWFscygxMDEsCisgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5FeHRlbnNpb25zW3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zX3BiMi5tc2dvcHRdLmkpCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIGJhc2V0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9lbmNvZGVyLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9lbmNvZGVyLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjM4YTUxMzgKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2VuY29kZXIucHkKQEAgLTAsMCArMSw3ODggQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI1BZMjUgY29tcGF0aWJsZSBmb3IgR0FFLgorIworIyBDb3B5cmlnaHQgMjAwOSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorCisiIiJDb2RlIGZvciBlbmNvZGluZyBwcm90b2NvbCBtZXNzYWdlIHByaW1pdGl2ZXMuCisKK0NvbnRhaW5zIHRoZSBsb2dpYyBmb3IgZW5jb2RpbmcgZXZlcnkgbG9naWNhbCBwcm90b2NvbCBmaWVsZCB0eXBlCitpbnRvIG9uZSBvZiB0aGUgNSBwaHlzaWNhbCB3aXJlIHR5cGVzLgorCitUaGlzIGNvZGUgaXMgZGVzaWduZWQgdG8gcHVzaCB0aGUgUHl0aG9uIGludGVycHJldGVyJ3MgcGVyZm9ybWFuY2UgdG8gdGhlCitsaW1pdHMuCisKK1RoZSBiYXNpYyBpZGVhIGlzIHRoYXQgYXQgc3RhcnR1cCB0aW1lLCBmb3IgZXZlcnkgZmllbGQgKGkuZS4gZXZlcnkKK0ZpZWxkRGVzY3JpcHRvcikgd2UgY29uc3RydWN0IHR3byBmdW5jdGlvbnM6ICBhICJzaXplciIgYW5kIGFuICJlbmNvZGVyIi4gIFRoZQorc2l6ZXIgdGFrZXMgYSB2YWx1ZSBvZiB0aGlzIGZpZWxkJ3MgdHlwZSBhbmQgY29tcHV0ZXMgaXRzIGJ5dGUgc2l6ZS4gIFRoZQorZW5jb2RlciB0YWtlcyBhIHdyaXRlciBmdW5jdGlvbiBhbmQgYSB2YWx1ZS4gIEl0IGVuY29kZXMgdGhlIHZhbHVlIGludG8gYnl0ZQorc3RyaW5ncyBhbmQgaW52b2tlcyB0aGUgd3JpdGVyIGZ1bmN0aW9uIHRvIHdyaXRlIHRob3NlIHN0cmluZ3MuICBUeXBpY2FsbHkgdGhlCit3cml0ZXIgZnVuY3Rpb24gaXMgdGhlIHdyaXRlKCkgbWV0aG9kIG9mIGEgY1N0cmluZ0lPLgorCitXZSB0cnkgdG8gZG8gYXMgbXVjaCB3b3JrIGFzIHBvc3NpYmxlIHdoZW4gY29uc3RydWN0aW5nIHRoZSB3cml0ZXIgYW5kIHRoZQorc2l6ZXIgcmF0aGVyIHRoYW4gd2hlbiBjYWxsaW5nIHRoZW0uICBJbiBwYXJ0aWN1bGFyOgorKiBXZSBjb3B5IGFueSBuZWVkZWQgZ2xvYmFsIGZ1bmN0aW9ucyB0byBsb2NhbCB2YXJpYWJsZXMsIHNvIHRoYXQgd2UgZG8gbm90IG5lZWQKKyAgdG8gZG8gY29zdGx5IGdsb2JhbCB0YWJsZSBsb29rdXBzIGF0IHJ1bnRpbWUuCisqIFNpbWlsYXJseSwgd2UgdHJ5IHRvIGRvIGFueSBhdHRyaWJ1dGUgbG9va3VwcyBhdCBzdGFydHVwIHRpbWUgaWYgcG9zc2libGUuCisqIEV2ZXJ5IGZpZWxkJ3MgdGFnIGlzIGVuY29kZWQgdG8gYnl0ZXMgYXQgc3RhcnR1cCwgc2luY2UgaXQgY2FuJ3QgY2hhbmdlIGF0CisgIHJ1bnRpbWUuCisqIFdoYXRldmVyIGNvbXBvbmVudCBvZiB0aGUgZmllbGQgc2l6ZSB3ZSBjYW4gY29tcHV0ZSBhdCBzdGFydHVwLCB3ZSBkby4KKyogV2UgKmF2b2lkKiBzaGFyaW5nIGNvZGUgaWYgZG9pbmcgc28gd291bGQgbWFrZSB0aGUgY29kZSBzbG93ZXIgYW5kIG5vdCBzaGFyaW5nCisgIGRvZXMgbm90IGJ1cmRlbiB1cyB0b28gbXVjaC4gIEZvciBleGFtcGxlLCBlbmNvZGVycyBmb3IgcmVwZWF0ZWQgZmllbGRzIGRvCisgIG5vdCBqdXN0IGNhbGwgdGhlIGVuY29kZXJzIGZvciBzaW5ndWxhciBmaWVsZHMgaW4gYSBsb29wIGJlY2F1c2UgdGhpcyB3b3VsZAorICBhZGQgYW4gZXh0cmEgZnVuY3Rpb24gY2FsbCBvdmVyaGVhZCBmb3IgZXZlcnkgbG9vcCBpdGVyYXRpb247IGluc3RlYWQsIHdlCisgIG1hbnVhbGx5IGlubGluZSB0aGUgc2luZ2xlLXZhbHVlIGVuY29kZXIgaW50byB0aGUgbG9vcC4KKyogSWYgYSBQeXRob24gZnVuY3Rpb24gbGFja3MgYSByZXR1cm4gc3RhdGVtZW50LCBQeXRob24gYWN0dWFsbHkgZ2VuZXJhdGVzCisgIGluc3RydWN0aW9ucyB0byBwb3AgdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBzdGF0ZW1lbnQgb2ZmIHRoZSBzdGFjaywgcHVzaAorICBOb25lIG9udG8gdGhlIHN0YWNrLCBhbmQgdGhlbiByZXR1cm4gdGhhdC4gIElmIHdlIHJlYWxseSBkb24ndCBjYXJlIHdoYXQKKyAgdmFsdWUgaXMgcmV0dXJuZWQsIHRoZW4gd2UgY2FuIHNhdmUgdHdvIGluc3RydWN0aW9ucyBieSByZXR1cm5pbmcgdGhlCisgIHJlc3VsdCBvZiB0aGUgbGFzdCBzdGF0ZW1lbnQuICBJdCBsb29rcyBmdW5ueSBidXQgaXQgaGVscHMuCisqIFdlIGFzc3VtZSB0aGF0IHR5cGUgYW5kIGJvdW5kcyBjaGVja2luZyBoYXMgaGFwcGVuZWQgYXQgYSBoaWdoZXIgbGV2ZWwuCisiIiIKKworX19hdXRob3JfXyA9ICdrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKScKKworaW1wb3J0IHN0cnVjdAoraW1wb3J0IHN5cyAgIyNQWTI1CitfUFkyID0gc3lzLnZlcnNpb25faW5mb1swXSA8IDMgICMjUFkyNQorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IHdpcmVfZm9ybWF0CisKKworIyBUaGlzIHdpbGwgb3ZlcmZsb3cgYW5kIHRodXMgYmVjb21lIElFRUUtNzU0ICJpbmZpbml0eSIuICBXZSB3b3VsZCB1c2UKKyMgImZsb2F0KCdpbmYnKSIgYnV0IGl0IGRvZXNuJ3Qgd29yayBvbiBXaW5kb3dzIHByZS1QeXRob24tMi42LgorX1BPU19JTkYgPSAxZTEwMDAwCitfTkVHX0lORiA9IC1fUE9TX0lORgorCisKK2RlZiBfVmFyaW50U2l6ZSh2YWx1ZSk6CisgICIiIkNvbXB1dGUgdGhlIHNpemUgb2YgYSB2YXJpbnQgdmFsdWUuIiIiCisgIGlmIHZhbHVlIDw9IDB4N2Y6IHJldHVybiAxCisgIGlmIHZhbHVlIDw9IDB4M2ZmZjogcmV0dXJuIDIKKyAgaWYgdmFsdWUgPD0gMHgxZmZmZmY6IHJldHVybiAzCisgIGlmIHZhbHVlIDw9IDB4ZmZmZmZmZjogcmV0dXJuIDQKKyAgaWYgdmFsdWUgPD0gMHg3ZmZmZmZmZmY6IHJldHVybiA1CisgIGlmIHZhbHVlIDw9IDB4M2ZmZmZmZmZmZmY6IHJldHVybiA2CisgIGlmIHZhbHVlIDw9IDB4MWZmZmZmZmZmZmZmZjogcmV0dXJuIDcKKyAgaWYgdmFsdWUgPD0gMHhmZmZmZmZmZmZmZmZmZjogcmV0dXJuIDgKKyAgaWYgdmFsdWUgPD0gMHg3ZmZmZmZmZmZmZmZmZmZmOiByZXR1cm4gOQorICByZXR1cm4gMTAKKworCitkZWYgX1NpZ25lZFZhcmludFNpemUodmFsdWUpOgorICAiIiJDb21wdXRlIHRoZSBzaXplIG9mIGEgc2lnbmVkIHZhcmludCB2YWx1ZS4iIiIKKyAgaWYgdmFsdWUgPCAwOiByZXR1cm4gMTAKKyAgaWYgdmFsdWUgPD0gMHg3ZjogcmV0dXJuIDEKKyAgaWYgdmFsdWUgPD0gMHgzZmZmOiByZXR1cm4gMgorICBpZiB2YWx1ZSA8PSAweDFmZmZmZjogcmV0dXJuIDMKKyAgaWYgdmFsdWUgPD0gMHhmZmZmZmZmOiByZXR1cm4gNAorICBpZiB2YWx1ZSA8PSAweDdmZmZmZmZmZjogcmV0dXJuIDUKKyAgaWYgdmFsdWUgPD0gMHgzZmZmZmZmZmZmZjogcmV0dXJuIDYKKyAgaWYgdmFsdWUgPD0gMHgxZmZmZmZmZmZmZmZmOiByZXR1cm4gNworICBpZiB2YWx1ZSA8PSAweGZmZmZmZmZmZmZmZmZmOiByZXR1cm4gOAorICBpZiB2YWx1ZSA8PSAweDdmZmZmZmZmZmZmZmZmZmY6IHJldHVybiA5CisgIHJldHVybiAxMAorCisKK2RlZiBfVGFnU2l6ZShmaWVsZF9udW1iZXIpOgorICAiIiJSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc2VyaWFsaXplIGEgdGFnIHdpdGggdGhpcyBmaWVsZAorICBudW1iZXIuIiIiCisgICMgSnVzdCBwYXNzIGluIHR5cGUgMCwgc2luY2UgdGhlIHR5cGUgd29uJ3QgYWZmZWN0IHRoZSB0YWcrdHlwZSBzaXplLgorICByZXR1cm4gX1ZhcmludFNpemUod2lyZV9mb3JtYXQuUGFja1RhZyhmaWVsZF9udW1iZXIsIDApKQorCisKKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyMgSW4gdGhpcyBzZWN0aW9uIHdlIGRlZmluZSBzb21lIGdlbmVyaWMgc2l6ZXJzLiAgRWFjaCBvZiB0aGVzZSBmdW5jdGlvbnMKKyMgdGFrZXMgcGFyYW1ldGVycyBzcGVjaWZpYyB0byBhIHBhcnRpY3VsYXIgZmllbGQgdHlwZSwgZS5nLiBpbnQzMiBvciBmaXhlZDY0LgorIyBJdCByZXR1cm5zIGFub3RoZXIgZnVuY3Rpb24gd2hpY2ggaW4gdHVybiB0YWtlcyBwYXJhbWV0ZXJzIHNwZWNpZmljIHRvIGEKKyMgcGFydGljdWxhciBmaWVsZCwgZS5nLiB0aGUgZmllbGQgbnVtYmVyIGFuZCB3aGV0aGVyIGl0IGlzIHJlcGVhdGVkIG9yIHBhY2tlZC4KKyMgTG9vayBhdCB0aGUgbmV4dCBzZWN0aW9uIHRvIHNlZSBob3cgdGhlc2UgYXJlIHVzZWQuCisKKworZGVmIF9TaW1wbGVTaXplcihjb21wdXRlX3ZhbHVlX3NpemUpOgorICAiIiJBIHNpemVyIHdoaWNoIHVzZXMgdGhlIGZ1bmN0aW9uIGNvbXB1dGVfdmFsdWVfc2l6ZSB0byBjb21wdXRlIHRoZSBzaXplIG9mCisgIGVhY2ggdmFsdWUuICBUeXBpY2FsbHkgY29tcHV0ZV92YWx1ZV9zaXplIGlzIF9WYXJpbnRTaXplLiIiIgorCisgIGRlZiBTcGVjaWZpY1NpemVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICAgdGFnX3NpemUgPSBfVGFnU2l6ZShmaWVsZF9udW1iZXIpCisgICAgaWYgaXNfcGFja2VkOgorICAgICAgbG9jYWxfVmFyaW50U2l6ZSA9IF9WYXJpbnRTaXplCisgICAgICBkZWYgUGFja2VkRmllbGRTaXplKHZhbHVlKToKKyAgICAgICAgcmVzdWx0ID0gMAorICAgICAgICBmb3IgZWxlbWVudCBpbiB2YWx1ZToKKyAgICAgICAgICByZXN1bHQgKz0gY29tcHV0ZV92YWx1ZV9zaXplKGVsZW1lbnQpCisgICAgICAgIHJldHVybiByZXN1bHQgKyBsb2NhbF9WYXJpbnRTaXplKHJlc3VsdCkgKyB0YWdfc2l6ZQorICAgICAgcmV0dXJuIFBhY2tlZEZpZWxkU2l6ZQorICAgIGVsaWYgaXNfcmVwZWF0ZWQ6CisgICAgICBkZWYgUmVwZWF0ZWRGaWVsZFNpemUodmFsdWUpOgorICAgICAgICByZXN1bHQgPSB0YWdfc2l6ZSAqIGxlbih2YWx1ZSkKKyAgICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgICAgcmVzdWx0ICs9IGNvbXB1dGVfdmFsdWVfc2l6ZShlbGVtZW50KQorICAgICAgICByZXR1cm4gcmVzdWx0CisgICAgICByZXR1cm4gUmVwZWF0ZWRGaWVsZFNpemUKKyAgICBlbHNlOgorICAgICAgZGVmIEZpZWxkU2l6ZSh2YWx1ZSk6CisgICAgICAgIHJldHVybiB0YWdfc2l6ZSArIGNvbXB1dGVfdmFsdWVfc2l6ZSh2YWx1ZSkKKyAgICAgIHJldHVybiBGaWVsZFNpemUKKworICByZXR1cm4gU3BlY2lmaWNTaXplcgorCisKK2RlZiBfTW9kaWZpZWRTaXplcihjb21wdXRlX3ZhbHVlX3NpemUsIG1vZGlmeV92YWx1ZSk6CisgICIiIkxpa2UgU2ltcGxlU2l6ZXIsIGJ1dCBtb2RpZnlfdmFsdWUgaXMgaW52b2tlZCBvbiBlYWNoIHZhbHVlIGJlZm9yZSBpdCBpcworICBwYXNzZWQgdG8gY29tcHV0ZV92YWx1ZV9zaXplLiAgbW9kaWZ5X3ZhbHVlIGlzIHR5cGljYWxseSBaaWdaYWdFbmNvZGUuIiIiCisKKyAgZGVmIFNwZWNpZmljU2l6ZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKToKKyAgICB0YWdfc2l6ZSA9IF9UYWdTaXplKGZpZWxkX251bWJlcikKKyAgICBpZiBpc19wYWNrZWQ6CisgICAgICBsb2NhbF9WYXJpbnRTaXplID0gX1ZhcmludFNpemUKKyAgICAgIGRlZiBQYWNrZWRGaWVsZFNpemUodmFsdWUpOgorICAgICAgICByZXN1bHQgPSAwCisgICAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICAgIHJlc3VsdCArPSBjb21wdXRlX3ZhbHVlX3NpemUobW9kaWZ5X3ZhbHVlKGVsZW1lbnQpKQorICAgICAgICByZXR1cm4gcmVzdWx0ICsgbG9jYWxfVmFyaW50U2l6ZShyZXN1bHQpICsgdGFnX3NpemUKKyAgICAgIHJldHVybiBQYWNrZWRGaWVsZFNpemUKKyAgICBlbGlmIGlzX3JlcGVhdGVkOgorICAgICAgZGVmIFJlcGVhdGVkRmllbGRTaXplKHZhbHVlKToKKyAgICAgICAgcmVzdWx0ID0gdGFnX3NpemUgKiBsZW4odmFsdWUpCisgICAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICAgIHJlc3VsdCArPSBjb21wdXRlX3ZhbHVlX3NpemUobW9kaWZ5X3ZhbHVlKGVsZW1lbnQpKQorICAgICAgICByZXR1cm4gcmVzdWx0CisgICAgICByZXR1cm4gUmVwZWF0ZWRGaWVsZFNpemUKKyAgICBlbHNlOgorICAgICAgZGVmIEZpZWxkU2l6ZSh2YWx1ZSk6CisgICAgICAgIHJldHVybiB0YWdfc2l6ZSArIGNvbXB1dGVfdmFsdWVfc2l6ZShtb2RpZnlfdmFsdWUodmFsdWUpKQorICAgICAgcmV0dXJuIEZpZWxkU2l6ZQorCisgIHJldHVybiBTcGVjaWZpY1NpemVyCisKKworZGVmIF9GaXhlZFNpemVyKHZhbHVlX3NpemUpOgorICAiIiJMaWtlIF9TaW1wbGVTaXplciBleGNlcHQgZm9yIGEgZml4ZWQtc2l6ZSBmaWVsZC4gIFRoZSBpbnB1dCBpcyB0aGUgc2l6ZQorICBvZiBvbmUgdmFsdWUuIiIiCisKKyAgZGVmIFNwZWNpZmljU2l6ZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKToKKyAgICB0YWdfc2l6ZSA9IF9UYWdTaXplKGZpZWxkX251bWJlcikKKyAgICBpZiBpc19wYWNrZWQ6CisgICAgICBsb2NhbF9WYXJpbnRTaXplID0gX1ZhcmludFNpemUKKyAgICAgIGRlZiBQYWNrZWRGaWVsZFNpemUodmFsdWUpOgorICAgICAgICByZXN1bHQgPSBsZW4odmFsdWUpICogdmFsdWVfc2l6ZQorICAgICAgICByZXR1cm4gcmVzdWx0ICsgbG9jYWxfVmFyaW50U2l6ZShyZXN1bHQpICsgdGFnX3NpemUKKyAgICAgIHJldHVybiBQYWNrZWRGaWVsZFNpemUKKyAgICBlbGlmIGlzX3JlcGVhdGVkOgorICAgICAgZWxlbWVudF9zaXplID0gdmFsdWVfc2l6ZSArIHRhZ19zaXplCisgICAgICBkZWYgUmVwZWF0ZWRGaWVsZFNpemUodmFsdWUpOgorICAgICAgICByZXR1cm4gbGVuKHZhbHVlKSAqIGVsZW1lbnRfc2l6ZQorICAgICAgcmV0dXJuIFJlcGVhdGVkRmllbGRTaXplCisgICAgZWxzZToKKyAgICAgIGZpZWxkX3NpemUgPSB2YWx1ZV9zaXplICsgdGFnX3NpemUKKyAgICAgIGRlZiBGaWVsZFNpemUodmFsdWUpOgorICAgICAgICByZXR1cm4gZmllbGRfc2l6ZQorICAgICAgcmV0dXJuIEZpZWxkU2l6ZQorCisgIHJldHVybiBTcGVjaWZpY1NpemVyCisKKworIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorIyBIZXJlIHdlIGRlY2xhcmUgYSBzaXplciBjb25zdHJ1Y3RvciBmb3IgZWFjaCBmaWVsZCB0eXBlLiAgRWFjaCAic2l6ZXIKKyMgY29uc3RydWN0b3IiIGlzIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyAoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKQorIyBhcyBwYXJhbWV0ZXJzIGFuZCByZXR1cm5zIGEgc2l6ZXIsIHdoaWNoIGluIHR1cm4gdGFrZXMgYSBmaWVsZCB2YWx1ZSBhcworIyBhIHBhcmFtZXRlciBhbmQgcmV0dXJucyBpdHMgZW5jb2RlZCBzaXplLgorCisKK0ludDMyU2l6ZXIgPSBJbnQ2NFNpemVyID0gRW51bVNpemVyID0gX1NpbXBsZVNpemVyKF9TaWduZWRWYXJpbnRTaXplKQorCitVSW50MzJTaXplciA9IFVJbnQ2NFNpemVyID0gX1NpbXBsZVNpemVyKF9WYXJpbnRTaXplKQorCitTSW50MzJTaXplciA9IFNJbnQ2NFNpemVyID0gX01vZGlmaWVkU2l6ZXIoCisgICAgX1NpZ25lZFZhcmludFNpemUsIHdpcmVfZm9ybWF0LlppZ1phZ0VuY29kZSkKKworRml4ZWQzMlNpemVyID0gU0ZpeGVkMzJTaXplciA9IEZsb2F0U2l6ZXIgID0gX0ZpeGVkU2l6ZXIoNCkKK0ZpeGVkNjRTaXplciA9IFNGaXhlZDY0U2l6ZXIgPSBEb3VibGVTaXplciA9IF9GaXhlZFNpemVyKDgpCisKK0Jvb2xTaXplciA9IF9GaXhlZFNpemVyKDEpCisKKworZGVmIFN0cmluZ1NpemVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICIiIlJldHVybnMgYSBzaXplciBmb3IgYSBzdHJpbmcgZmllbGQuIiIiCisKKyAgdGFnX3NpemUgPSBfVGFnU2l6ZShmaWVsZF9udW1iZXIpCisgIGxvY2FsX1ZhcmludFNpemUgPSBfVmFyaW50U2l6ZQorICBsb2NhbF9sZW4gPSBsZW4KKyAgYXNzZXJ0IG5vdCBpc19wYWNrZWQKKyAgaWYgaXNfcmVwZWF0ZWQ6CisgICAgZGVmIFJlcGVhdGVkRmllbGRTaXplKHZhbHVlKToKKyAgICAgIHJlc3VsdCA9IHRhZ19zaXplICogbGVuKHZhbHVlKQorICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgIGwgPSBsb2NhbF9sZW4oZWxlbWVudC5lbmNvZGUoJ3V0Zi04JykpCisgICAgICAgIHJlc3VsdCArPSBsb2NhbF9WYXJpbnRTaXplKGwpICsgbAorICAgICAgcmV0dXJuIHJlc3VsdAorICAgIHJldHVybiBSZXBlYXRlZEZpZWxkU2l6ZQorICBlbHNlOgorICAgIGRlZiBGaWVsZFNpemUodmFsdWUpOgorICAgICAgbCA9IGxvY2FsX2xlbih2YWx1ZS5lbmNvZGUoJ3V0Zi04JykpCisgICAgICByZXR1cm4gdGFnX3NpemUgKyBsb2NhbF9WYXJpbnRTaXplKGwpICsgbAorICAgIHJldHVybiBGaWVsZFNpemUKKworCitkZWYgQnl0ZXNTaXplcihmaWVsZF9udW1iZXIsIGlzX3JlcGVhdGVkLCBpc19wYWNrZWQpOgorICAiIiJSZXR1cm5zIGEgc2l6ZXIgZm9yIGEgYnl0ZXMgZmllbGQuIiIiCisKKyAgdGFnX3NpemUgPSBfVGFnU2l6ZShmaWVsZF9udW1iZXIpCisgIGxvY2FsX1ZhcmludFNpemUgPSBfVmFyaW50U2l6ZQorICBsb2NhbF9sZW4gPSBsZW4KKyAgYXNzZXJ0IG5vdCBpc19wYWNrZWQKKyAgaWYgaXNfcmVwZWF0ZWQ6CisgICAgZGVmIFJlcGVhdGVkRmllbGRTaXplKHZhbHVlKToKKyAgICAgIHJlc3VsdCA9IHRhZ19zaXplICogbGVuKHZhbHVlKQorICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgIGwgPSBsb2NhbF9sZW4oZWxlbWVudCkKKyAgICAgICAgcmVzdWx0ICs9IGxvY2FsX1ZhcmludFNpemUobCkgKyBsCisgICAgICByZXR1cm4gcmVzdWx0CisgICAgcmV0dXJuIFJlcGVhdGVkRmllbGRTaXplCisgIGVsc2U6CisgICAgZGVmIEZpZWxkU2l6ZSh2YWx1ZSk6CisgICAgICBsID0gbG9jYWxfbGVuKHZhbHVlKQorICAgICAgcmV0dXJuIHRhZ19zaXplICsgbG9jYWxfVmFyaW50U2l6ZShsKSArIGwKKyAgICByZXR1cm4gRmllbGRTaXplCisKKworZGVmIEdyb3VwU2l6ZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKToKKyAgIiIiUmV0dXJucyBhIHNpemVyIGZvciBhIGdyb3VwIGZpZWxkLiIiIgorCisgIHRhZ19zaXplID0gX1RhZ1NpemUoZmllbGRfbnVtYmVyKSAqIDIKKyAgYXNzZXJ0IG5vdCBpc19wYWNrZWQKKyAgaWYgaXNfcmVwZWF0ZWQ6CisgICAgZGVmIFJlcGVhdGVkRmllbGRTaXplKHZhbHVlKToKKyAgICAgIHJlc3VsdCA9IHRhZ19zaXplICogbGVuKHZhbHVlKQorICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgIHJlc3VsdCArPSBlbGVtZW50LkJ5dGVTaXplKCkKKyAgICAgIHJldHVybiByZXN1bHQKKyAgICByZXR1cm4gUmVwZWF0ZWRGaWVsZFNpemUKKyAgZWxzZToKKyAgICBkZWYgRmllbGRTaXplKHZhbHVlKToKKyAgICAgIHJldHVybiB0YWdfc2l6ZSArIHZhbHVlLkJ5dGVTaXplKCkKKyAgICByZXR1cm4gRmllbGRTaXplCisKKworZGVmIE1lc3NhZ2VTaXplcihmaWVsZF9udW1iZXIsIGlzX3JlcGVhdGVkLCBpc19wYWNrZWQpOgorICAiIiJSZXR1cm5zIGEgc2l6ZXIgZm9yIGEgbWVzc2FnZSBmaWVsZC4iIiIKKworICB0YWdfc2l6ZSA9IF9UYWdTaXplKGZpZWxkX251bWJlcikKKyAgbG9jYWxfVmFyaW50U2l6ZSA9IF9WYXJpbnRTaXplCisgIGFzc2VydCBub3QgaXNfcGFja2VkCisgIGlmIGlzX3JlcGVhdGVkOgorICAgIGRlZiBSZXBlYXRlZEZpZWxkU2l6ZSh2YWx1ZSk6CisgICAgICByZXN1bHQgPSB0YWdfc2l6ZSAqIGxlbih2YWx1ZSkKKyAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICBsID0gZWxlbWVudC5CeXRlU2l6ZSgpCisgICAgICAgIHJlc3VsdCArPSBsb2NhbF9WYXJpbnRTaXplKGwpICsgbAorICAgICAgcmV0dXJuIHJlc3VsdAorICAgIHJldHVybiBSZXBlYXRlZEZpZWxkU2l6ZQorICBlbHNlOgorICAgIGRlZiBGaWVsZFNpemUodmFsdWUpOgorICAgICAgbCA9IHZhbHVlLkJ5dGVTaXplKCkKKyAgICAgIHJldHVybiB0YWdfc2l6ZSArIGxvY2FsX1ZhcmludFNpemUobCkgKyBsCisgICAgcmV0dXJuIEZpZWxkU2l6ZQorCisKKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyMgTWVzc2FnZVNldCBpcyBzcGVjaWFsLgorCisKK2RlZiBNZXNzYWdlU2V0SXRlbVNpemVyKGZpZWxkX251bWJlcik6CisgICIiIlJldHVybnMgYSBzaXplciBmb3IgZXh0ZW5zaW9ucyBvZiBNZXNzYWdlU2V0LgorCisgIFRoZSBtZXNzYWdlIHNldCBtZXNzYWdlIGxvb2tzIGxpa2UgdGhpczoKKyAgICBtZXNzYWdlIE1lc3NhZ2VTZXQgeworICAgICAgcmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeworICAgICAgICByZXF1aXJlZCBpbnQzMiB0eXBlX2lkID0gMjsKKyAgICAgICAgcmVxdWlyZWQgc3RyaW5nIG1lc3NhZ2UgPSAzOworICAgICAgfQorICAgIH0KKyAgIiIiCisgIHN0YXRpY19zaXplID0gKF9UYWdTaXplKDEpICogMiArIF9UYWdTaXplKDIpICsgX1ZhcmludFNpemUoZmllbGRfbnVtYmVyKSArCisgICAgICAgICAgICAgICAgIF9UYWdTaXplKDMpKQorICBsb2NhbF9WYXJpbnRTaXplID0gX1ZhcmludFNpemUKKworICBkZWYgRmllbGRTaXplKHZhbHVlKToKKyAgICBsID0gdmFsdWUuQnl0ZVNpemUoKQorICAgIHJldHVybiBzdGF0aWNfc2l6ZSArIGxvY2FsX1ZhcmludFNpemUobCkgKyBsCisKKyAgcmV0dXJuIEZpZWxkU2l6ZQorCisKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyMgRW5jb2RlcnMhCisKKworZGVmIF9WYXJpbnRFbmNvZGVyKCk6CisgICIiIlJldHVybiBhbiBlbmNvZGVyIGZvciBhIGJhc2ljIHZhcmludCB2YWx1ZSAoZG9lcyBub3QgaW5jbHVkZSB0YWcpLiIiIgorCisgIGxvY2FsX2NociA9IF9QWTIgYW5kIGNociBvciAobGFtYmRhIHg6IGJ5dGVzKCh4LCkpKSAgIyNQWTI1CisjIyFQWTI1ICBsb2NhbF9jaHIgPSBjaHIgaWYgYnl0ZXMgaXMgc3RyIGVsc2UgbGFtYmRhIHg6IGJ5dGVzKCh4LCkpCisgIGRlZiBFbmNvZGVWYXJpbnQod3JpdGUsIHZhbHVlKToKKyAgICBiaXRzID0gdmFsdWUgJiAweDdmCisgICAgdmFsdWUgPj49IDcKKyAgICB3aGlsZSB2YWx1ZToKKyAgICAgIHdyaXRlKGxvY2FsX2NocigweDgwfGJpdHMpKQorICAgICAgYml0cyA9IHZhbHVlICYgMHg3ZgorICAgICAgdmFsdWUgPj49IDcKKyAgICByZXR1cm4gd3JpdGUobG9jYWxfY2hyKGJpdHMpKQorCisgIHJldHVybiBFbmNvZGVWYXJpbnQKKworCitkZWYgX1NpZ25lZFZhcmludEVuY29kZXIoKToKKyAgIiIiUmV0dXJuIGFuIGVuY29kZXIgZm9yIGEgYmFzaWMgc2lnbmVkIHZhcmludCB2YWx1ZSAoZG9lcyBub3QgaW5jbHVkZQorICB0YWcpLiIiIgorCisgIGxvY2FsX2NociA9IF9QWTIgYW5kIGNociBvciAobGFtYmRhIHg6IGJ5dGVzKCh4LCkpKSAgIyNQWTI1CisjIyFQWTI1ICBsb2NhbF9jaHIgPSBjaHIgaWYgYnl0ZXMgaXMgc3RyIGVsc2UgbGFtYmRhIHg6IGJ5dGVzKCh4LCkpCisgIGRlZiBFbmNvZGVTaWduZWRWYXJpbnQod3JpdGUsIHZhbHVlKToKKyAgICBpZiB2YWx1ZSA8IDA6CisgICAgICB2YWx1ZSArPSAoMSA8PCA2NCkKKyAgICBiaXRzID0gdmFsdWUgJiAweDdmCisgICAgdmFsdWUgPj49IDcKKyAgICB3aGlsZSB2YWx1ZToKKyAgICAgIHdyaXRlKGxvY2FsX2NocigweDgwfGJpdHMpKQorICAgICAgYml0cyA9IHZhbHVlICYgMHg3ZgorICAgICAgdmFsdWUgPj49IDcKKyAgICByZXR1cm4gd3JpdGUobG9jYWxfY2hyKGJpdHMpKQorCisgIHJldHVybiBFbmNvZGVTaWduZWRWYXJpbnQKKworCitfRW5jb2RlVmFyaW50ID0gX1ZhcmludEVuY29kZXIoKQorX0VuY29kZVNpZ25lZFZhcmludCA9IF9TaWduZWRWYXJpbnRFbmNvZGVyKCkKKworCitkZWYgX1ZhcmludEJ5dGVzKHZhbHVlKToKKyAgIiIiRW5jb2RlIHRoZSBnaXZlbiBpbnRlZ2VyIGFzIGEgdmFyaW50IGFuZCByZXR1cm4gdGhlIGJ5dGVzLiAgVGhpcyBpcyBvbmx5CisgIGNhbGxlZCBhdCBzdGFydHVwIHRpbWUgc28gaXQgZG9lc24ndCBuZWVkIHRvIGJlIGZhc3QuIiIiCisKKyAgcGllY2VzID0gW10KKyAgX0VuY29kZVZhcmludChwaWVjZXMuYXBwZW5kLCB2YWx1ZSkKKyAgcmV0dXJuICIiLmVuY29kZSgibGF0aW4xIikuam9pbihwaWVjZXMpICAjI1BZMjUKKyMjIVBZMjUgIHJldHVybiBiIiIuam9pbihwaWVjZXMpCisKKworZGVmIFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV90eXBlKToKKyAgIiIiRW5jb2RlIHRoZSBnaXZlbiB0YWcgYW5kIHJldHVybiB0aGUgYnl0ZXMuICBPbmx5IGNhbGxlZCBhdCBzdGFydHVwLiIiIgorCisgIHJldHVybiBfVmFyaW50Qnl0ZXMod2lyZV9mb3JtYXQuUGFja1RhZyhmaWVsZF9udW1iZXIsIHdpcmVfdHlwZSkpCisKKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyMgQXMgd2l0aCBzaXplcnMgKHNlZSBhYm92ZSksIHdlIGhhdmUgYSBudW1iZXIgb2YgY29tbW9uIGVuY29kZXIKKyMgaW1wbGVtZW50YXRpb25zLgorCisKK2RlZiBfU2ltcGxlRW5jb2Rlcih3aXJlX3R5cGUsIGVuY29kZV92YWx1ZSwgY29tcHV0ZV92YWx1ZV9zaXplKToKKyAgIiIiUmV0dXJuIGEgY29uc3RydWN0b3IgZm9yIGFuIGVuY29kZXIgZm9yIGZpZWxkcyBvZiBhIHBhcnRpY3VsYXIgdHlwZS4KKworICBBcmdzOgorICAgICAgd2lyZV90eXBlOiAgVGhlIGZpZWxkJ3Mgd2lyZSB0eXBlLCBmb3IgZW5jb2RpbmcgdGFncy4KKyAgICAgIGVuY29kZV92YWx1ZTogIEEgZnVuY3Rpb24gd2hpY2ggZW5jb2RlcyBhbiBpbmRpdmlkdWFsIHZhbHVlLCBlLmcuCisgICAgICAgIF9FbmNvZGVWYXJpbnQoKS4KKyAgICAgIGNvbXB1dGVfdmFsdWVfc2l6ZTogIEEgZnVuY3Rpb24gd2hpY2ggY29tcHV0ZXMgdGhlIHNpemUgb2YgYW4gaW5kaXZpZHVhbAorICAgICAgICB2YWx1ZSwgZS5nLiBfVmFyaW50U2l6ZSgpLgorICAiIiIKKworICBkZWYgU3BlY2lmaWNFbmNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICAgaWYgaXNfcGFja2VkOgorICAgICAgdGFnX2J5dGVzID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKQorICAgICAgbG9jYWxfRW5jb2RlVmFyaW50ID0gX0VuY29kZVZhcmludAorICAgICAgZGVmIEVuY29kZVBhY2tlZEZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgICAgc2l6ZSA9IDAKKyAgICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgICAgc2l6ZSArPSBjb21wdXRlX3ZhbHVlX3NpemUoZWxlbWVudCkKKyAgICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBzaXplKQorICAgICAgICBmb3IgZWxlbWVudCBpbiB2YWx1ZToKKyAgICAgICAgICBlbmNvZGVfdmFsdWUod3JpdGUsIGVsZW1lbnQpCisgICAgICByZXR1cm4gRW5jb2RlUGFja2VkRmllbGQKKyAgICBlbGlmIGlzX3JlcGVhdGVkOgorICAgICAgdGFnX2J5dGVzID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX3R5cGUpCisgICAgICBkZWYgRW5jb2RlUmVwZWF0ZWRGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgICBmb3IgZWxlbWVudCBpbiB2YWx1ZToKKyAgICAgICAgICB3cml0ZSh0YWdfYnl0ZXMpCisgICAgICAgICAgZW5jb2RlX3ZhbHVlKHdyaXRlLCBlbGVtZW50KQorICAgICAgcmV0dXJuIEVuY29kZVJlcGVhdGVkRmllbGQKKyAgICBlbHNlOgorICAgICAgdGFnX2J5dGVzID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX3R5cGUpCisgICAgICBkZWYgRW5jb2RlRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgICAgd3JpdGUodGFnX2J5dGVzKQorICAgICAgICByZXR1cm4gZW5jb2RlX3ZhbHVlKHdyaXRlLCB2YWx1ZSkKKyAgICAgIHJldHVybiBFbmNvZGVGaWVsZAorCisgIHJldHVybiBTcGVjaWZpY0VuY29kZXIKKworCitkZWYgX01vZGlmaWVkRW5jb2Rlcih3aXJlX3R5cGUsIGVuY29kZV92YWx1ZSwgY29tcHV0ZV92YWx1ZV9zaXplLCBtb2RpZnlfdmFsdWUpOgorICAiIiJMaWtlIFNpbXBsZUVuY29kZXIgYnV0IGFkZGl0aW9uYWxseSBpbnZva2VzIG1vZGlmeV92YWx1ZSBvbiBldmVyeSB2YWx1ZQorICBiZWZvcmUgcGFzc2luZyBpdCB0byBlbmNvZGVfdmFsdWUuICBVc3VhbGx5IG1vZGlmeV92YWx1ZSBpcyBaaWdaYWdFbmNvZGUuIiIiCisKKyAgZGVmIFNwZWNpZmljRW5jb2RlcihmaWVsZF9udW1iZXIsIGlzX3JlcGVhdGVkLCBpc19wYWNrZWQpOgorICAgIGlmIGlzX3BhY2tlZDoKKyAgICAgIHRhZ19ieXRlcyA9IFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkKKyAgICAgIGxvY2FsX0VuY29kZVZhcmludCA9IF9FbmNvZGVWYXJpbnQKKyAgICAgIGRlZiBFbmNvZGVQYWNrZWRGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgICB3cml0ZSh0YWdfYnl0ZXMpCisgICAgICAgIHNpemUgPSAwCisgICAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICAgIHNpemUgKz0gY29tcHV0ZV92YWx1ZV9zaXplKG1vZGlmeV92YWx1ZShlbGVtZW50KSkKKyAgICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBzaXplKQorICAgICAgICBmb3IgZWxlbWVudCBpbiB2YWx1ZToKKyAgICAgICAgICBlbmNvZGVfdmFsdWUod3JpdGUsIG1vZGlmeV92YWx1ZShlbGVtZW50KSkKKyAgICAgIHJldHVybiBFbmNvZGVQYWNrZWRGaWVsZAorICAgIGVsaWYgaXNfcmVwZWF0ZWQ6CisgICAgICB0YWdfYnl0ZXMgPSBUYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfdHlwZSkKKyAgICAgIGRlZiBFbmNvZGVSZXBlYXRlZEZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgICAgICBlbmNvZGVfdmFsdWUod3JpdGUsIG1vZGlmeV92YWx1ZShlbGVtZW50KSkKKyAgICAgIHJldHVybiBFbmNvZGVSZXBlYXRlZEZpZWxkCisgICAgZWxzZToKKyAgICAgIHRhZ19ieXRlcyA9IFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV90eXBlKQorICAgICAgZGVmIEVuY29kZUZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgICAgcmV0dXJuIGVuY29kZV92YWx1ZSh3cml0ZSwgbW9kaWZ5X3ZhbHVlKHZhbHVlKSkKKyAgICAgIHJldHVybiBFbmNvZGVGaWVsZAorCisgIHJldHVybiBTcGVjaWZpY0VuY29kZXIKKworCitkZWYgX1N0cnVjdFBhY2tFbmNvZGVyKHdpcmVfdHlwZSwgZm9ybWF0KToKKyAgIiIiUmV0dXJuIGEgY29uc3RydWN0b3IgZm9yIGFuIGVuY29kZXIgZm9yIGEgZml4ZWQtd2lkdGggZmllbGQuCisKKyAgQXJnczoKKyAgICAgIHdpcmVfdHlwZTogIFRoZSBmaWVsZCdzIHdpcmUgdHlwZSwgZm9yIGVuY29kaW5nIHRhZ3MuCisgICAgICBmb3JtYXQ6ICBUaGUgZm9ybWF0IHN0cmluZyB0byBwYXNzIHRvIHN0cnVjdC5wYWNrKCkuCisgICIiIgorCisgIHZhbHVlX3NpemUgPSBzdHJ1Y3QuY2FsY3NpemUoZm9ybWF0KQorCisgIGRlZiBTcGVjaWZpY0VuY29kZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKToKKyAgICBsb2NhbF9zdHJ1Y3RfcGFjayA9IHN0cnVjdC5wYWNrCisgICAgaWYgaXNfcGFja2VkOgorICAgICAgdGFnX2J5dGVzID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKQorICAgICAgbG9jYWxfRW5jb2RlVmFyaW50ID0gX0VuY29kZVZhcmludAorICAgICAgZGVmIEVuY29kZVBhY2tlZEZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBsZW4odmFsdWUpICogdmFsdWVfc2l6ZSkKKyAgICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgICAgd3JpdGUobG9jYWxfc3RydWN0X3BhY2soZm9ybWF0LCBlbGVtZW50KSkKKyAgICAgIHJldHVybiBFbmNvZGVQYWNrZWRGaWVsZAorICAgIGVsaWYgaXNfcmVwZWF0ZWQ6CisgICAgICB0YWdfYnl0ZXMgPSBUYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfdHlwZSkKKyAgICAgIGRlZiBFbmNvZGVSZXBlYXRlZEZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgICAgICB3cml0ZShsb2NhbF9zdHJ1Y3RfcGFjayhmb3JtYXQsIGVsZW1lbnQpKQorICAgICAgcmV0dXJuIEVuY29kZVJlcGVhdGVkRmllbGQKKyAgICBlbHNlOgorICAgICAgdGFnX2J5dGVzID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX3R5cGUpCisgICAgICBkZWYgRW5jb2RlRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgICAgd3JpdGUodGFnX2J5dGVzKQorICAgICAgICByZXR1cm4gd3JpdGUobG9jYWxfc3RydWN0X3BhY2soZm9ybWF0LCB2YWx1ZSkpCisgICAgICByZXR1cm4gRW5jb2RlRmllbGQKKworICByZXR1cm4gU3BlY2lmaWNFbmNvZGVyCisKKworZGVmIF9GbG9hdGluZ1BvaW50RW5jb2Rlcih3aXJlX3R5cGUsIGZvcm1hdCk6CisgICIiIlJldHVybiBhIGNvbnN0cnVjdG9yIGZvciBhbiBlbmNvZGVyIGZvciBmbG9hdCBmaWVsZHMuCisKKyAgVGhpcyBpcyBsaWtlIFN0cnVjdFBhY2tFbmNvZGVyLCBidXQgY2F0Y2hlcyBlcnJvcnMgdGhhdCBtYXkgYmUgZHVlIHRvCisgIHBhc3Npbmcgbm9uLWZpbml0ZSBmbG9hdGluZy1wb2ludCB2YWx1ZXMgdG8gc3RydWN0LnBhY2ssIGFuZCBtYWtlcyBhCisgIHNlY29uZCBhdHRlbXB0IHRvIGVuY29kZSB0aG9zZSB2YWx1ZXMuCisKKyAgQXJnczoKKyAgICAgIHdpcmVfdHlwZTogIFRoZSBmaWVsZCdzIHdpcmUgdHlwZSwgZm9yIGVuY29kaW5nIHRhZ3MuCisgICAgICBmb3JtYXQ6ICBUaGUgZm9ybWF0IHN0cmluZyB0byBwYXNzIHRvIHN0cnVjdC5wYWNrKCkuCisgICIiIgorCisgIGIgPSBfUFkyIGFuZCAobGFtYmRhIHg6eCkgb3IgKGxhbWJkYSB4OnguZW5jb2RlKCdsYXRpbjEnKSkgICMjUFkyNQorICB2YWx1ZV9zaXplID0gc3RydWN0LmNhbGNzaXplKGZvcm1hdCkKKyAgaWYgdmFsdWVfc2l6ZSA9PSA0OgorICAgIGRlZiBFbmNvZGVOb25GaW5pdGVPclJhaXNlKHdyaXRlLCB2YWx1ZSk6CisgICAgICAjIFJlbWVtYmVyIHRoYXQgdGhlIHNlcmlhbGl6ZWQgZm9ybSB1c2VzIGxpdHRsZS1lbmRpYW4gYnl0ZSBvcmRlci4KKyAgICAgIGlmIHZhbHVlID09IF9QT1NfSU5GOgorICAgICAgICB3cml0ZShiKCdceDAwXHgwMFx4ODBceDdGJykpICAjI1BZMjUKKyMjIVBZMjUgICAgICAgIHdyaXRlKGInXHgwMFx4MDBceDgwXHg3RicpCisgICAgICBlbGlmIHZhbHVlID09IF9ORUdfSU5GOgorICAgICAgICB3cml0ZShiKCdceDAwXHgwMFx4ODBceEZGJykpICAjI1BZMjUKKyMjIVBZMjUgICAgICAgIHdyaXRlKGInXHgwMFx4MDBceDgwXHhGRicpCisgICAgICBlbGlmIHZhbHVlICE9IHZhbHVlOiAgICAgICAgICAgIyBOYU4KKyAgICAgICAgd3JpdGUoYignXHgwMFx4MDBceEMwXHg3RicpKSAgIyNQWTI1CisjIyFQWTI1ICAgICAgICB3cml0ZShiJ1x4MDBceDAwXHhDMFx4N0YnKQorICAgICAgZWxzZToKKyAgICAgICAgcmFpc2UKKyAgZWxpZiB2YWx1ZV9zaXplID09IDg6CisgICAgZGVmIEVuY29kZU5vbkZpbml0ZU9yUmFpc2Uod3JpdGUsIHZhbHVlKToKKyAgICAgIGlmIHZhbHVlID09IF9QT1NfSU5GOgorICAgICAgICB3cml0ZShiKCdceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceEYwXHg3RicpKSAgIyNQWTI1CisjIyFQWTI1ICAgICAgICB3cml0ZShiJ1x4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4RjBceDdGJykKKyAgICAgIGVsaWYgdmFsdWUgPT0gX05FR19JTkY6CisgICAgICAgIHdyaXRlKGIoJ1x4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4RjBceEZGJykpICAjI1BZMjUKKyMjIVBZMjUgICAgICAgIHdyaXRlKGInXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhGMFx4RkYnKQorICAgICAgZWxpZiB2YWx1ZSAhPSB2YWx1ZTogICAgICAgICAgICAgICAgICAgICAgICAgIyBOYU4KKyAgICAgICAgd3JpdGUoYignXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhGOFx4N0YnKSkgICMjUFkyNQorIyMhUFkyNSAgICAgICAgd3JpdGUoYidceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceEY4XHg3RicpCisgICAgICBlbHNlOgorICAgICAgICByYWlzZQorICBlbHNlOgorICAgIHJhaXNlIFZhbHVlRXJyb3IoJ0NhblwndCBlbmNvZGUgZmxvYXRpbmctcG9pbnQgdmFsdWVzIHRoYXQgYXJlICcKKyAgICAgICAgICAgICAgICAgICAgICclZCBieXRlcyBsb25nIChvbmx5IDQgb3IgOCknICUgdmFsdWVfc2l6ZSkKKworICBkZWYgU3BlY2lmaWNFbmNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICAgbG9jYWxfc3RydWN0X3BhY2sgPSBzdHJ1Y3QucGFjaworICAgIGlmIGlzX3BhY2tlZDoKKyAgICAgIHRhZ19ieXRlcyA9IFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkKKyAgICAgIGxvY2FsX0VuY29kZVZhcmludCA9IF9FbmNvZGVWYXJpbnQKKyAgICAgIGRlZiBFbmNvZGVQYWNrZWRGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgICB3cml0ZSh0YWdfYnl0ZXMpCisgICAgICAgIGxvY2FsX0VuY29kZVZhcmludCh3cml0ZSwgbGVuKHZhbHVlKSAqIHZhbHVlX3NpemUpCisgICAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICAgICMgVGhpcyB0cnkvZXhjZXB0IGJsb2NrIGlzIGdvaW5nIHRvIGJlIGZhc3RlciB0aGFuIGFueSBjb2RlIHRoYXQKKyAgICAgICAgICAjIHdlIGNvdWxkIHdyaXRlIHRvIGNoZWNrIHdoZXRoZXIgZWxlbWVudCBpcyBmaW5pdGUuCisgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgd3JpdGUobG9jYWxfc3RydWN0X3BhY2soZm9ybWF0LCBlbGVtZW50KSkKKyAgICAgICAgICBleGNlcHQgU3lzdGVtRXJyb3I6CisgICAgICAgICAgICBFbmNvZGVOb25GaW5pdGVPclJhaXNlKHdyaXRlLCBlbGVtZW50KQorICAgICAgcmV0dXJuIEVuY29kZVBhY2tlZEZpZWxkCisgICAgZWxpZiBpc19yZXBlYXRlZDoKKyAgICAgIHRhZ19ieXRlcyA9IFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV90eXBlKQorICAgICAgZGVmIEVuY29kZVJlcGVhdGVkRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgICAgd3JpdGUodGFnX2J5dGVzKQorICAgICAgICAgIHRyeToKKyAgICAgICAgICAgIHdyaXRlKGxvY2FsX3N0cnVjdF9wYWNrKGZvcm1hdCwgZWxlbWVudCkpCisgICAgICAgICAgZXhjZXB0IFN5c3RlbUVycm9yOgorICAgICAgICAgICAgRW5jb2RlTm9uRmluaXRlT3JSYWlzZSh3cml0ZSwgZWxlbWVudCkKKyAgICAgIHJldHVybiBFbmNvZGVSZXBlYXRlZEZpZWxkCisgICAgZWxzZToKKyAgICAgIHRhZ19ieXRlcyA9IFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV90eXBlKQorICAgICAgZGVmIEVuY29kZUZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgICAgdHJ5OgorICAgICAgICAgIHdyaXRlKGxvY2FsX3N0cnVjdF9wYWNrKGZvcm1hdCwgdmFsdWUpKQorICAgICAgICBleGNlcHQgU3lzdGVtRXJyb3I6CisgICAgICAgICAgRW5jb2RlTm9uRmluaXRlT3JSYWlzZSh3cml0ZSwgdmFsdWUpCisgICAgICByZXR1cm4gRW5jb2RlRmllbGQKKworICByZXR1cm4gU3BlY2lmaWNFbmNvZGVyCisKKworIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorIyBIZXJlIHdlIGRlY2xhcmUgYW4gZW5jb2RlciBjb25zdHJ1Y3RvciBmb3IgZWFjaCBmaWVsZCB0eXBlLiAgVGhlc2Ugd29yaworIyB2ZXJ5IHNpbWlsYXJseSB0byBzaXplciBjb25zdHJ1Y3RvcnMsIGRlc2NyaWJlZCBlYXJsaWVyLgorCisKK0ludDMyRW5jb2RlciA9IEludDY0RW5jb2RlciA9IEVudW1FbmNvZGVyID0gX1NpbXBsZUVuY29kZXIoCisgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5ULCBfRW5jb2RlU2lnbmVkVmFyaW50LCBfU2lnbmVkVmFyaW50U2l6ZSkKKworVUludDMyRW5jb2RlciA9IFVJbnQ2NEVuY29kZXIgPSBfU2ltcGxlRW5jb2RlcigKKyAgICB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQsIF9FbmNvZGVWYXJpbnQsIF9WYXJpbnRTaXplKQorCitTSW50MzJFbmNvZGVyID0gU0ludDY0RW5jb2RlciA9IF9Nb2RpZmllZEVuY29kZXIoCisgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5ULCBfRW5jb2RlVmFyaW50LCBfVmFyaW50U2l6ZSwKKyAgICB3aXJlX2Zvcm1hdC5aaWdaYWdFbmNvZGUpCisKKyMgTm90ZSB0aGF0IFB5dGhvbiBjb252ZW5pZW50bHkgZ3VhcmFudGVlcyB0aGF0IHdoZW4gdXNpbmcgdGhlICc8JyBwcmVmaXggb24KKyMgZm9ybWF0cywgdGhleSB3aWxsIGFsc28gaGF2ZSB0aGUgc2FtZSBzaXplIGFjcm9zcyBhbGwgcGxhdGZvcm1zIChhcyBvcHBvc2VkCisjIHRvIHdpdGhvdXQgdGhlIHByZWZpeCwgd2hlcmUgdGhlaXIgc2l6ZXMgZGVwZW5kIG9uIHRoZSBDIGNvbXBpbGVyJ3MgYmFzaWMKKyMgdHlwZSBzaXplcykuCitGaXhlZDMyRW5jb2RlciAgPSBfU3RydWN0UGFja0VuY29kZXIod2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQzMiwgJzxJJykKK0ZpeGVkNjRFbmNvZGVyICA9IF9TdHJ1Y3RQYWNrRW5jb2Rlcih3aXJlX2Zvcm1hdC5XSVJFVFlQRV9GSVhFRDY0LCAnPFEnKQorU0ZpeGVkMzJFbmNvZGVyID0gX1N0cnVjdFBhY2tFbmNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVEMzIsICc8aScpCitTRml4ZWQ2NEVuY29kZXIgPSBfU3RydWN0UGFja0VuY29kZXIod2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQ2NCwgJzxxJykKK0Zsb2F0RW5jb2RlciAgICA9IF9GbG9hdGluZ1BvaW50RW5jb2Rlcih3aXJlX2Zvcm1hdC5XSVJFVFlQRV9GSVhFRDMyLCAnPGYnKQorRG91YmxlRW5jb2RlciAgID0gX0Zsb2F0aW5nUG9pbnRFbmNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVENjQsICc8ZCcpCisKKworZGVmIEJvb2xFbmNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICIiIlJldHVybnMgYW4gZW5jb2RlciBmb3IgYSBib29sZWFuIGZpZWxkLiIiIgorCisjIyFQWTI1ICBmYWxzZV9ieXRlID0gYidceDAwJworIyMhUFkyNSAgdHJ1ZV9ieXRlID0gYidceDAxJworICBmYWxzZV9ieXRlID0gJ1x4MDAnLmVuY29kZSgnbGF0aW4xJykgICMjUFkyNQorICB0cnVlX2J5dGUgPSAnXHgwMScuZW5jb2RlKCdsYXRpbjEnKSAgIyNQWTI1CisgIGlmIGlzX3BhY2tlZDoKKyAgICB0YWdfYnl0ZXMgPSBUYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpCisgICAgbG9jYWxfRW5jb2RlVmFyaW50ID0gX0VuY29kZVZhcmludAorICAgIGRlZiBFbmNvZGVQYWNrZWRGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgd3JpdGUodGFnX2J5dGVzKQorICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBsZW4odmFsdWUpKQorICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgIGlmIGVsZW1lbnQ6CisgICAgICAgICAgd3JpdGUodHJ1ZV9ieXRlKQorICAgICAgICBlbHNlOgorICAgICAgICAgIHdyaXRlKGZhbHNlX2J5dGUpCisgICAgcmV0dXJuIEVuY29kZVBhY2tlZEZpZWxkCisgIGVsaWYgaXNfcmVwZWF0ZWQ6CisgICAgdGFnX2J5dGVzID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQpCisgICAgZGVmIEVuY29kZVJlcGVhdGVkRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICB3cml0ZSh0YWdfYnl0ZXMpCisgICAgICAgIGlmIGVsZW1lbnQ6CisgICAgICAgICAgd3JpdGUodHJ1ZV9ieXRlKQorICAgICAgICBlbHNlOgorICAgICAgICAgIHdyaXRlKGZhbHNlX2J5dGUpCisgICAgcmV0dXJuIEVuY29kZVJlcGVhdGVkRmllbGQKKyAgZWxzZToKKyAgICB0YWdfYnl0ZXMgPSBUYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCkKKyAgICBkZWYgRW5jb2RlRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgIHdyaXRlKHRhZ19ieXRlcykKKyAgICAgIGlmIHZhbHVlOgorICAgICAgICByZXR1cm4gd3JpdGUodHJ1ZV9ieXRlKQorICAgICAgcmV0dXJuIHdyaXRlKGZhbHNlX2J5dGUpCisgICAgcmV0dXJuIEVuY29kZUZpZWxkCisKKworZGVmIFN0cmluZ0VuY29kZXIoZmllbGRfbnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKToKKyAgIiIiUmV0dXJucyBhbiBlbmNvZGVyIGZvciBhIHN0cmluZyBmaWVsZC4iIiIKKworICB0YWcgPSBUYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpCisgIGxvY2FsX0VuY29kZVZhcmludCA9IF9FbmNvZGVWYXJpbnQKKyAgbG9jYWxfbGVuID0gbGVuCisgIGFzc2VydCBub3QgaXNfcGFja2VkCisgIGlmIGlzX3JlcGVhdGVkOgorICAgIGRlZiBFbmNvZGVSZXBlYXRlZEZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICBmb3IgZWxlbWVudCBpbiB2YWx1ZToKKyAgICAgICAgZW5jb2RlZCA9IGVsZW1lbnQuZW5jb2RlKCd1dGYtOCcpCisgICAgICAgIHdyaXRlKHRhZykKKyAgICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBsb2NhbF9sZW4oZW5jb2RlZCkpCisgICAgICAgIHdyaXRlKGVuY29kZWQpCisgICAgcmV0dXJuIEVuY29kZVJlcGVhdGVkRmllbGQKKyAgZWxzZToKKyAgICBkZWYgRW5jb2RlRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgIGVuY29kZWQgPSB2YWx1ZS5lbmNvZGUoJ3V0Zi04JykKKyAgICAgIHdyaXRlKHRhZykKKyAgICAgIGxvY2FsX0VuY29kZVZhcmludCh3cml0ZSwgbG9jYWxfbGVuKGVuY29kZWQpKQorICAgICAgcmV0dXJuIHdyaXRlKGVuY29kZWQpCisgICAgcmV0dXJuIEVuY29kZUZpZWxkCisKKworZGVmIEJ5dGVzRW5jb2RlcihmaWVsZF9udW1iZXIsIGlzX3JlcGVhdGVkLCBpc19wYWNrZWQpOgorICAiIiJSZXR1cm5zIGFuIGVuY29kZXIgZm9yIGEgYnl0ZXMgZmllbGQuIiIiCisKKyAgdGFnID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKQorICBsb2NhbF9FbmNvZGVWYXJpbnQgPSBfRW5jb2RlVmFyaW50CisgIGxvY2FsX2xlbiA9IGxlbgorICBhc3NlcnQgbm90IGlzX3BhY2tlZAorICBpZiBpc19yZXBlYXRlZDoKKyAgICBkZWYgRW5jb2RlUmVwZWF0ZWRGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgIHdyaXRlKHRhZykKKyAgICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBsb2NhbF9sZW4oZWxlbWVudCkpCisgICAgICAgIHdyaXRlKGVsZW1lbnQpCisgICAgcmV0dXJuIEVuY29kZVJlcGVhdGVkRmllbGQKKyAgZWxzZToKKyAgICBkZWYgRW5jb2RlRmllbGQod3JpdGUsIHZhbHVlKToKKyAgICAgIHdyaXRlKHRhZykKKyAgICAgIGxvY2FsX0VuY29kZVZhcmludCh3cml0ZSwgbG9jYWxfbGVuKHZhbHVlKSkKKyAgICAgIHJldHVybiB3cml0ZSh2YWx1ZSkKKyAgICByZXR1cm4gRW5jb2RlRmllbGQKKworCitkZWYgR3JvdXBFbmNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICIiIlJldHVybnMgYW4gZW5jb2RlciBmb3IgYSBncm91cCBmaWVsZC4iIiIKKworICBzdGFydF90YWcgPSBUYWdCeXRlcyhmaWVsZF9udW1iZXIsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQKQorICBlbmRfdGFnID0gVGFnQnl0ZXMoZmllbGRfbnVtYmVyLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9FTkRfR1JPVVApCisgIGFzc2VydCBub3QgaXNfcGFja2VkCisgIGlmIGlzX3JlcGVhdGVkOgorICAgIGRlZiBFbmNvZGVSZXBlYXRlZEZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICBmb3IgZWxlbWVudCBpbiB2YWx1ZToKKyAgICAgICAgd3JpdGUoc3RhcnRfdGFnKQorICAgICAgICBlbGVtZW50Ll9JbnRlcm5hbFNlcmlhbGl6ZSh3cml0ZSkKKyAgICAgICAgd3JpdGUoZW5kX3RhZykKKyAgICByZXR1cm4gRW5jb2RlUmVwZWF0ZWRGaWVsZAorICBlbHNlOgorICAgIGRlZiBFbmNvZGVGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgd3JpdGUoc3RhcnRfdGFnKQorICAgICAgdmFsdWUuX0ludGVybmFsU2VyaWFsaXplKHdyaXRlKQorICAgICAgcmV0dXJuIHdyaXRlKGVuZF90YWcpCisgICAgcmV0dXJuIEVuY29kZUZpZWxkCisKKworZGVmIE1lc3NhZ2VFbmNvZGVyKGZpZWxkX251bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk6CisgICIiIlJldHVybnMgYW4gZW5jb2RlciBmb3IgYSBtZXNzYWdlIGZpZWxkLiIiIgorCisgIHRhZyA9IFRhZ0J5dGVzKGZpZWxkX251bWJlciwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkKKyAgbG9jYWxfRW5jb2RlVmFyaW50ID0gX0VuY29kZVZhcmludAorICBhc3NlcnQgbm90IGlzX3BhY2tlZAorICBpZiBpc19yZXBlYXRlZDoKKyAgICBkZWYgRW5jb2RlUmVwZWF0ZWRGaWVsZCh3cml0ZSwgdmFsdWUpOgorICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgIHdyaXRlKHRhZykKKyAgICAgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCBlbGVtZW50LkJ5dGVTaXplKCkpCisgICAgICAgIGVsZW1lbnQuX0ludGVybmFsU2VyaWFsaXplKHdyaXRlKQorICAgIHJldHVybiBFbmNvZGVSZXBlYXRlZEZpZWxkCisgIGVsc2U6CisgICAgZGVmIEVuY29kZUZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgICB3cml0ZSh0YWcpCisgICAgICBsb2NhbF9FbmNvZGVWYXJpbnQod3JpdGUsIHZhbHVlLkJ5dGVTaXplKCkpCisgICAgICByZXR1cm4gdmFsdWUuX0ludGVybmFsU2VyaWFsaXplKHdyaXRlKQorICAgIHJldHVybiBFbmNvZGVGaWVsZAorCisKKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyMgQXMgYmVmb3JlLCBNZXNzYWdlU2V0IGlzIHNwZWNpYWwuCisKKworZGVmIE1lc3NhZ2VTZXRJdGVtRW5jb2RlcihmaWVsZF9udW1iZXIpOgorICAiIiJFbmNvZGVyIGZvciBleHRlbnNpb25zIG9mIE1lc3NhZ2VTZXQuCisKKyAgVGhlIG1lc3NhZ2Ugc2V0IG1lc3NhZ2UgbG9va3MgbGlrZSB0aGlzOgorICAgIG1lc3NhZ2UgTWVzc2FnZVNldCB7CisgICAgICByZXBlYXRlZCBncm91cCBJdGVtID0gMSB7CisgICAgICAgIHJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOworICAgICAgICByZXF1aXJlZCBzdHJpbmcgbWVzc2FnZSA9IDM7CisgICAgICB9CisgICAgfQorICAiIiIKKyAgc3RhcnRfYnl0ZXMgPSAiIi5lbmNvZGUoImxhdGluMSIpLmpvaW4oWyAgIyNQWTI1CisjIyFQWTI1ICBzdGFydF9ieXRlcyA9IGIiIi5qb2luKFsKKyAgICAgIFRhZ0J5dGVzKDEsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQKSwKKyAgICAgIFRhZ0J5dGVzKDIsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCksCisgICAgICBfVmFyaW50Qnl0ZXMoZmllbGRfbnVtYmVyKSwKKyAgICAgIFRhZ0J5dGVzKDMsIHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpXSkKKyAgZW5kX2J5dGVzID0gVGFnQnl0ZXMoMSwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfRU5EX0dST1VQKQorICBsb2NhbF9FbmNvZGVWYXJpbnQgPSBfRW5jb2RlVmFyaW50CisKKyAgZGVmIEVuY29kZUZpZWxkKHdyaXRlLCB2YWx1ZSk6CisgICAgd3JpdGUoc3RhcnRfYnl0ZXMpCisgICAgbG9jYWxfRW5jb2RlVmFyaW50KHdyaXRlLCB2YWx1ZS5CeXRlU2l6ZSgpKQorICAgIHZhbHVlLl9JbnRlcm5hbFNlcmlhbGl6ZSh3cml0ZSkKKyAgICByZXR1cm4gd3JpdGUoZW5kX2J5dGVzKQorCisgIHJldHVybiBFbmNvZGVGaWVsZApkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9lbnVtX3R5cGVfd3JhcHBlci5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZW51bV90eXBlX3dyYXBwZXIucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWNmZmUzNQotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZW51bV90eXBlX3dyYXBwZXIucHkKQEAgLTAsMCArMSw4OSBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJBIHNpbXBsZSB3cmFwcGVyIGFyb3VuZCBlbnVtIHR5cGVzIHRvIGV4cG9zZSB1dGlsaXR5IGZ1bmN0aW9ucy4KKworSW5zdGFuY2VzIGFyZSBjcmVhdGVkIGFzIHByb3BlcnRpZXMgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBlbnVtIHRoZXkgd3JhcAorb24gcHJvdG8gY2xhc3Nlcy4gIEZvciB1c2FnZSwgc2VlOgorICByZWZsZWN0aW9uX3Rlc3QucHkKKyIiIgorCitfX2F1dGhvcl9fID0gJ3JhYnNhdHRAZ29vZ2xlLmNvbSAoS2V2aW4gUmFic2F0dCknCisKKworY2xhc3MgRW51bVR5cGVXcmFwcGVyKG9iamVjdCk6CisgICIiIkEgdXRpbGl0eSBmb3IgZmluZGluZyB0aGUgbmFtZXMgb2YgZW51bSB2YWx1ZXMuIiIiCisKKyAgREVTQ1JJUFRPUiA9IE5vbmUKKworICBkZWYgX19pbml0X18oc2VsZiwgZW51bV90eXBlKToKKyAgICAiIiJJbml0cyBFbnVtVHlwZVdyYXBwZXIgd2l0aCBhbiBFbnVtRGVzY3JpcHRvci4iIiIKKyAgICBzZWxmLl9lbnVtX3R5cGUgPSBlbnVtX3R5cGUKKyAgICBzZWxmLkRFU0NSSVBUT1IgPSBlbnVtX3R5cGU7CisKKyAgZGVmIE5hbWUoc2VsZiwgbnVtYmVyKToKKyAgICAiIiJSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIG5hbWUgb2YgYW4gZW51bSB2YWx1ZS4iIiIKKyAgICBpZiBudW1iZXIgaW4gc2VsZi5fZW51bV90eXBlLnZhbHVlc19ieV9udW1iZXI6CisgICAgICByZXR1cm4gc2VsZi5fZW51bV90eXBlLnZhbHVlc19ieV9udW1iZXJbbnVtYmVyXS5uYW1lCisgICAgcmFpc2UgVmFsdWVFcnJvcignRW51bSAlcyBoYXMgbm8gbmFtZSBkZWZpbmVkIGZvciB2YWx1ZSAlZCcgJSAoCisgICAgICAgIHNlbGYuX2VudW1fdHlwZS5uYW1lLCBudW1iZXIpKQorCisgIGRlZiBWYWx1ZShzZWxmLCBuYW1lKToKKyAgICAiIiJSZXR1cm5zIHRoZSB2YWx1ZSBjb3Jlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGVudW0gbmFtZS4iIiIKKyAgICBpZiBuYW1lIGluIHNlbGYuX2VudW1fdHlwZS52YWx1ZXNfYnlfbmFtZToKKyAgICAgIHJldHVybiBzZWxmLl9lbnVtX3R5cGUudmFsdWVzX2J5X25hbWVbbmFtZV0ubnVtYmVyCisgICAgcmFpc2UgVmFsdWVFcnJvcignRW51bSAlcyBoYXMgbm8gdmFsdWUgZGVmaW5lZCBmb3IgbmFtZSAlcycgJSAoCisgICAgICAgIHNlbGYuX2VudW1fdHlwZS5uYW1lLCBuYW1lKSkKKworICBkZWYga2V5cyhzZWxmKToKKyAgICAiIiJSZXR1cm4gYSBsaXN0IG9mIHRoZSBzdHJpbmcgbmFtZXMgaW4gdGhlIGVudW0uCisKKyAgICBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgICAiIiIKKworICAgIHJldHVybiBbdmFsdWVfZGVzY3JpcHRvci5uYW1lCisgICAgICAgICAgICBmb3IgdmFsdWVfZGVzY3JpcHRvciBpbiBzZWxmLl9lbnVtX3R5cGUudmFsdWVzXQorCisgIGRlZiB2YWx1ZXMoc2VsZik6CisgICAgIiIiUmV0dXJuIGEgbGlzdCBvZiB0aGUgaW50ZWdlciB2YWx1ZXMgaW4gdGhlIGVudW0uCisKKyAgICBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgICAiIiIKKworICAgIHJldHVybiBbdmFsdWVfZGVzY3JpcHRvci5udW1iZXIKKyAgICAgICAgICAgIGZvciB2YWx1ZV9kZXNjcmlwdG9yIGluIHNlbGYuX2VudW1fdHlwZS52YWx1ZXNdCisKKyAgZGVmIGl0ZW1zKHNlbGYpOgorICAgICIiIlJldHVybiBhIGxpc3Qgb2YgdGhlIChuYW1lLCB2YWx1ZSkgcGFpcnMgb2YgdGhlIGVudW0uCisKKyAgICBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgICAiIiIKKyAgICByZXR1cm4gWyh2YWx1ZV9kZXNjcmlwdG9yLm5hbWUsIHZhbHVlX2Rlc2NyaXB0b3IubnVtYmVyKQorICAgICAgICAgICAgZm9yIHZhbHVlX2Rlc2NyaXB0b3IgaW4gc2VsZi5fZW51bV90eXBlLnZhbHVlc10KZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0MS5wcm90byBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0MS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMmZiYmVlCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9mYWN0b3J5X3Rlc3QxLnByb3RvCkBAIC0wLDAgKzEsNTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IG1hdHRoZXd0b2lhQGdvb2dsZS5jb20gKE1hdHQgVG9pYSkKKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbDsKKworCitlbnVtIEZhY3RvcnkxRW51bSB7CisgIEZBQ1RPUllfMV9WQUxVRV8wID0gMDsKKyAgRkFDVE9SWV8xX1ZBTFVFXzEgPSAxOworfQorCittZXNzYWdlIEZhY3RvcnkxTWVzc2FnZSB7CisgIG9wdGlvbmFsIEZhY3RvcnkxRW51bSBmYWN0b3J5XzFfZW51bSA9IDE7CisgIGVudW0gTmVzdGVkRmFjdG9yeTFFbnVtIHsKKyAgICBORVNURURfRkFDVE9SWV8xX1ZBTFVFXzAgPSAwOworICAgIE5FU1RFRF9GQUNUT1JZXzFfVkFMVUVfMSA9IDE7CisgIH0KKyAgb3B0aW9uYWwgTmVzdGVkRmFjdG9yeTFFbnVtIG5lc3RlZF9mYWN0b3J5XzFfZW51bSA9IDI7CisgIG1lc3NhZ2UgTmVzdGVkRmFjdG9yeTFNZXNzYWdlIHsKKyAgICBvcHRpb25hbCBzdHJpbmcgdmFsdWUgPSAxOworICB9CisgIG9wdGlvbmFsIE5lc3RlZEZhY3RvcnkxTWVzc2FnZSBuZXN0ZWRfZmFjdG9yeV8xX21lc3NhZ2UgPSAzOworICBvcHRpb25hbCBpbnQzMiBzY2FsYXJfdmFsdWUgPSA0OworICByZXBlYXRlZCBzdHJpbmcgbGlzdF92YWx1ZSA9IDU7CisKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0Mi5wcm90byBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0Mi5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYjFiNTRhCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9mYWN0b3J5X3Rlc3QyLnByb3RvCkBAIC0wLDAgKzEsOTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IG1hdHRoZXd0b2lhQGdvb2dsZS5jb20gKE1hdHQgVG9pYSkKKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZmFjdG9yeV90ZXN0MS5wcm90byI7CisKKworZW51bSBGYWN0b3J5MkVudW0geworICBGQUNUT1JZXzJfVkFMVUVfMCA9IDA7CisgIEZBQ1RPUllfMl9WQUxVRV8xID0gMTsKK30KKworbWVzc2FnZSBGYWN0b3J5Mk1lc3NhZ2UgeworICByZXF1aXJlZCBpbnQzMiBtYW5kYXRvcnkgPSAxOworICBvcHRpb25hbCBGYWN0b3J5MkVudW0gZmFjdG9yeV8yX2VudW0gPSAyOworICBlbnVtIE5lc3RlZEZhY3RvcnkyRW51bSB7CisgICAgTkVTVEVEX0ZBQ1RPUllfMl9WQUxVRV8wID0gMDsKKyAgICBORVNURURfRkFDVE9SWV8yX1ZBTFVFXzEgPSAxOworICB9CisgIG9wdGlvbmFsIE5lc3RlZEZhY3RvcnkyRW51bSBuZXN0ZWRfZmFjdG9yeV8yX2VudW0gPSAzOworICBtZXNzYWdlIE5lc3RlZEZhY3RvcnkyTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgc3RyaW5nIHZhbHVlID0gMTsKKyAgfQorICBvcHRpb25hbCBOZXN0ZWRGYWN0b3J5Mk1lc3NhZ2UgbmVzdGVkX2ZhY3RvcnlfMl9tZXNzYWdlID0gNDsKKyAgb3B0aW9uYWwgRmFjdG9yeTFNZXNzYWdlIGZhY3RvcnlfMV9tZXNzYWdlID0gNTsKKyAgb3B0aW9uYWwgRmFjdG9yeTFFbnVtIGZhY3RvcnlfMV9lbnVtID0gNjsKKyAgb3B0aW9uYWwgRmFjdG9yeTFNZXNzYWdlLk5lc3RlZEZhY3RvcnkxRW51bSBuZXN0ZWRfZmFjdG9yeV8xX2VudW0gPSA3OworICBvcHRpb25hbCBGYWN0b3J5MU1lc3NhZ2UuTmVzdGVkRmFjdG9yeTFNZXNzYWdlIG5lc3RlZF9mYWN0b3J5XzFfbWVzc2FnZSA9IDg7CisgIG9wdGlvbmFsIEZhY3RvcnkyTWVzc2FnZSBjaXJjdWxhcl9tZXNzYWdlID0gOTsKKyAgb3B0aW9uYWwgc3RyaW5nIHNjYWxhcl92YWx1ZSA9IDEwOworICByZXBlYXRlZCBzdHJpbmcgbGlzdF92YWx1ZSA9IDExOworICByZXBlYXRlZCBncm91cCBHcm91cGVkID0gMTIgeworICAgIG9wdGlvbmFsIHN0cmluZyBwYXJ0XzEgPSAxMzsKKyAgICBvcHRpb25hbCBzdHJpbmcgcGFydF8yID0gMTQ7CisgIH0KKyAgb3B0aW9uYWwgTG9vcE1lc3NhZ2UgbG9vcCA9IDE1OworICBvcHRpb25hbCBpbnQzMiBpbnRfd2l0aF9kZWZhdWx0ID0gMTYgW2RlZmF1bHQgPSAxNzc2XTsKKyAgb3B0aW9uYWwgZG91YmxlIGRvdWJsZV93aXRoX2RlZmF1bHQgPSAxNyBbZGVmYXVsdCA9IDkuOTldOworICBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3dpdGhfZGVmYXVsdCA9IDE4IFtkZWZhdWx0ID0gImhlbGxvIHdvcmxkIl07CisgIG9wdGlvbmFsIGJvb2wgYm9vbF93aXRoX2RlZmF1bHQgPSAxOSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgb3B0aW9uYWwgRmFjdG9yeTJFbnVtIGVudW1fd2l0aF9kZWZhdWx0ID0gMjAgW2RlZmF1bHQgPSBGQUNUT1JZXzJfVkFMVUVfMV07CisgIG9wdGlvbmFsIGJ5dGVzIGJ5dGVzX3dpdGhfZGVmYXVsdCA9IDIxIFtkZWZhdWx0ID0gImFcMzczXDAwMGMiXTsKKworCisgIGV4dGVuZCBGYWN0b3J5MU1lc3NhZ2UgeworICAgIG9wdGlvbmFsIHN0cmluZyBvbmVfbW9yZV9maWVsZCA9IDEwMDE7CisgIH0KKworICBvbmVvZiBvbmVvZl9maWVsZCB7CisgICAgaW50MzIgb25lb2ZfaW50ID0gMjI7CisgICAgc3RyaW5nIG9uZW9mX3N0cmluZyA9IDIzOworICB9Cit9CisKK21lc3NhZ2UgTG9vcE1lc3NhZ2UgeworICBvcHRpb25hbCBGYWN0b3J5Mk1lc3NhZ2UgbG9vcCA9IDE7Cit9CisKK21lc3NhZ2UgTWVzc2FnZVdpdGhOZXN0ZWRFbnVtT25seSB7CisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgTkVTVEVEX01FU1NBR0VfRU5VTV8wID0gMDsKKyAgfQorfQorCitleHRlbmQgRmFjdG9yeTFNZXNzYWdlIHsKKyAgb3B0aW9uYWwgc3RyaW5nIGFub3RoZXJfZmllbGQgPSAxMDAyOworfQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9nZW5lcmF0b3JfdGVzdC5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZ2VuZXJhdG9yX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDMzNjFlNgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvZ2VuZXJhdG9yX3Rlc3QucHkKQEAgLTAsMCArMSwzNDMgQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjIFRPRE8ocm9iaW5zb24pOiBGbGVzaCB0aGlzIG91dCBjb25zaWRlcmFibHkuICBXZSBmb2N1c2VkIG9uIHJlZmxlY3Rpb25fdGVzdC5weQorIyBmaXJzdCwgc2luY2UgaXQncyB0ZXN0aW5nIHRoZSBzdWJ0bGVyIGNvZGUsIGFuZCBzaW5jZSBpdCBwcm92aWRlcyBkZWNlbnQKKyMgaW5kaXJlY3QgdGVzdGluZyBvZiB0aGUgcHJvdG9jb2wgY29tcGlsZXIgb3V0cHV0LgorCisiIiJVbml0dGVzdCB0aGF0IGRpcmVjdGx5IHRlc3RzIHRoZSBvdXRwdXQgb2YgdGhlIHB1cmUtUHl0aG9uIHByb3RvY29sCitjb21waWxlci4gIFNlZSAvL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9yZWZsZWN0aW9uX3Rlc3QucHkgZm9yIGEgdGVzdCB3aGljaAorZnVydGhlciBlbnN1cmVzIHRoYXQgd2UgY2FuIHVzZSBQeXRob24gcHJvdG9jb2wgbWVzc2FnZSBvYmplY3RzIGFzIHdlIGV4cGVjdC4KKyIiIgorCitfX2F1dGhvcl9fID0gJ3JvYmluc29uQGdvb2dsZS5jb20gKFdpbGwgUm9iaW5zb24pJworCitmcm9tIGdvb2dsZS5hcHB1dGlscyBpbXBvcnQgYmFzZXRlc3QKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCB0ZXN0X2JhZF9pZGVudGlmaWVyc19wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9pbXBvcnRfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9tc2V0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgc2VydmljZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHN5bWJvbF9kYXRhYmFzZQorCitNQVhfRVhURU5TSU9OID0gNTM2ODcwOTEyCisKKworY2xhc3MgR2VuZXJhdG9yVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3ROZXN0ZWRNZXNzYWdlRGVzY3JpcHRvcihzZWxmKToKKyAgICBmaWVsZF9uYW1lID0gJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJworICAgIHByb3RvX3R5cGUgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgcHJvdG9fdHlwZS5OZXN0ZWRNZXNzYWdlLkRFU0NSSVBUT1IsCisgICAgICAgIHByb3RvX3R5cGUuREVTQ1JJUFRPUi5maWVsZHNfYnlfbmFtZVtmaWVsZF9uYW1lXS5tZXNzYWdlX3R5cGUpCisKKyAgZGVmIHRlc3RFbnVtcyhzZWxmKToKKyAgICAjIFdlIHRlc3Qgb25seSBtb2R1bGUtbGV2ZWwgZW51bXMgaGVyZS4KKyAgICAjIFRPRE8ocm9iaW5zb24pOiBFeGFtaW5lIGRlc2NyaXB0b3JzIGRpcmVjdGx5IHRvIGNoZWNrCisgICAgIyBlbnVtIGRlc2NyaXB0b3Igb3V0cHV0LgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNCwgdW5pdHRlc3RfcGIyLkZPUkVJR05fRk9PKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNSwgdW5pdHRlc3RfcGIyLkZPUkVJR05fQkFSKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNiwgdW5pdHRlc3RfcGIyLkZPUkVJR05fQkFaKQorCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLkZPTykKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuRk9PKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgcHJvdG8uQkFSKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5CQVIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCBwcm90by5CQVopCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkJBWikKKworICBkZWYgdGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKHNlbGYpOgorICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKCkKKworICAgICMgUHl0aG9uIHByZS0yLjYgZG9lcyBub3QgaGF2ZSBpc2luZigpIG9yIGlzbmFuKCkgZnVuY3Rpb25zLCBzbyB3ZSBoYXZlCisgICAgIyB0byBwcm92aWRlIG91ciBvd24uCisgICAgZGVmIGlzbmFuKHZhbCk6CisgICAgICAjIE5hTiBpcyBuZXZlciBlcXVhbCB0byBpdHNlbGYuCisgICAgICByZXR1cm4gdmFsICE9IHZhbAorICAgIGRlZiBpc2luZih2YWwpOgorICAgICAgIyBJbmZpbml0eSB0aW1lcyB6ZXJvIGVxdWFscyBOYU4uCisgICAgICByZXR1cm4gbm90IGlzbmFuKHZhbCkgYW5kIGlzbmFuKHZhbCAqIDApCisKKyAgICBzZWxmLmFzc2VydFRydWUoaXNpbmYobWVzc2FnZS5pbmZfZG91YmxlKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5pbmZfZG91YmxlID4gMCkKKyAgICBzZWxmLmFzc2VydFRydWUoaXNpbmYobWVzc2FnZS5uZWdfaW5mX2RvdWJsZSkpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2UubmVnX2luZl9kb3VibGUgPCAwKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihtZXNzYWdlLm5hbl9kb3VibGUpKQorCisgICAgc2VsZi5hc3NlcnRUcnVlKGlzaW5mKG1lc3NhZ2UuaW5mX2Zsb2F0KSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5pbmZfZmxvYXQgPiAwKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc2luZihtZXNzYWdlLm5lZ19pbmZfZmxvYXQpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtZXNzYWdlLm5lZ19pbmZfZmxvYXQgPCAwKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihtZXNzYWdlLm5hbl9mbG9hdCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIiwgbWVzc2FnZS5jcHBfdHJpZ3JhcGgpCisKKyAgZGVmIHRlc3RIYXNEZWZhdWx0VmFsdWVzKHNlbGYpOgorICAgIGRlc2MgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IKKworICAgIGV4cGVjdGVkX2hhc19kZWZhdWx0X2J5X25hbWUgPSB7CisgICAgICAgICdvcHRpb25hbF9pbnQzMic6IEZhbHNlLAorICAgICAgICAncmVwZWF0ZWRfaW50MzInOiBGYWxzZSwKKyAgICAgICAgJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJzogRmFsc2UsCisgICAgICAgICdkZWZhdWx0X2ludDMyJzogVHJ1ZSwKKyAgICB9CisKKyAgICBoYXNfZGVmYXVsdF9ieV9uYW1lID0gZGljdCgKKyAgICAgICAgWyhmLm5hbWUsIGYuaGFzX2RlZmF1bHRfdmFsdWUpCisgICAgICAgICBmb3IgZiBpbiBkZXNjLmZpZWxkcworICAgICAgICAgaWYgZi5uYW1lIGluIGV4cGVjdGVkX2hhc19kZWZhdWx0X2J5X25hbWVdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZXhwZWN0ZWRfaGFzX2RlZmF1bHRfYnlfbmFtZSwgaGFzX2RlZmF1bHRfYnlfbmFtZSkKKworICBkZWYgdGVzdENvbnRhaW5pbmdUeXBlQmVoYXZpb3JGb3JFeHRlbnNpb25zKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbi5jb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMuREVTQ1JJUFRPUikKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWQuc2luZ2xlLmNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucy5ERVNDUklQVE9SKQorCisgIGRlZiB0ZXN0RXh0ZW5zaW9uU2NvcGUoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uLmV4dGVuc2lvbl9zY29wZSwKKyAgICAgICAgICAgICAgICAgICAgIE5vbmUpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkLnNpbmdsZS5leHRlbnNpb25fc2NvcGUsCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkLkRFU0NSSVBUT1IpCisKKyAgZGVmIHRlc3RJc0V4dGVuc2lvbihzZWxmKToKKyAgICBzZWxmLmFzc2VydFRydWUodW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbi5pc19leHRlbnNpb24pCisgICAgc2VsZi5hc3NlcnRUcnVlKHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWQuc2luZ2xlLmlzX2V4dGVuc2lvbikKKworICAgIG1lc3NhZ2VfZGVzY3JpcHRvciA9IHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWQuREVTQ1JJUFRPUgorICAgIG5vbl9leHRlbnNpb25fZGVzY3JpcHRvciA9IG1lc3NhZ2VfZGVzY3JpcHRvci5maWVsZHNfYnlfbmFtZVsnYSddCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBub25fZXh0ZW5zaW9uX2Rlc2NyaXB0b3IuaXNfZXh0ZW5zaW9uKQorCisgIGRlZiB0ZXN0T3B0aW9ucyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0KCkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uREVTQ1JJUFRPUi5HZXRPcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQpCisKKyAgZGVmIHRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wYjIuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucygpCisgICAgZW51bV9vcHRpb25zID0gcHJvdG8uREVTQ1JJUFRPUi5lbnVtX3R5cGVzX2J5X25hbWVbJ0FuRW51bSddLkdldE9wdGlvbnMoKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShlbnVtX29wdGlvbnMgaXMgbm90IE5vbmUpCisgICAgIyBUT0RPKGdwcyk6IFdlIHJlYWxseSBzaG91bGQgdGVzdCBmb3IgdGhlIHByZXNlbmNlIG9mIHRoZSBlbnVtX29wdDEKKyAgICAjIGV4dGVuc2lvbiBhbmQgZm9yIGl0cyB2YWx1ZSB0byBiZSBzZXQgdG8gLTc4OS4KKworICBkZWYgdGVzdE5lc3RlZFR5cGVzKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICBzZXQodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5ERVNDUklQVE9SLm5lc3RlZF90eXBlcyksCisgICAgICAgIHNldChbCisgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuREVTQ1JJUFRPUiwKKyAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5ERVNDUklQVE9SLAorICAgICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLkRFU0NSSVBUT1IsCisgICAgICAgIF0pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RFbXB0eU1lc3NhZ2UuREVTQ1JJUFRPUi5uZXN0ZWRfdHlwZXMsIFtdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5ERVNDUklQVE9SLm5lc3RlZF90eXBlcywgW10pCisKKyAgZGVmIHRlc3RDb250YWluaW5nVHlwZShzZWxmKToKKyAgICBzZWxmLmFzc2VydFRydWUoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlLkRFU0NSSVBUT1IuY29udGFpbmluZ190eXBlIGlzIE5vbmUpCisgICAgc2VsZi5hc3NlcnRUcnVlKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IuY29udGFpbmluZ190eXBlIGlzIE5vbmUpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkRFU0NSSVBUT1IuY29udGFpbmluZ190eXBlLAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkRFU0NSSVBUT1IuY29udGFpbmluZ190eXBlLAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLkRFU0NSSVBUT1IuY29udGFpbmluZ190eXBlLAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IpCisKKyAgZGVmIHRlc3RDb250YWluaW5nVHlwZUluRW51bURlc2NyaXB0b3Ioc2VsZik6CisgICAgc2VsZi5hc3NlcnRUcnVlKHVuaXR0ZXN0X3BiMi5fRk9SRUlHTkVOVU0uY29udGFpbmluZ190eXBlIGlzIE5vbmUpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuX1RFU1RBTExUWVBFU19ORVNURURFTlVNLmNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuREVTQ1JJUFRPUikKKworICBkZWYgdGVzdFBhY2thZ2Uoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5ERVNDUklQVE9SLmZpbGUucGFja2FnZSwKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0JykKKyAgICBkZXNjID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkRFU0NSSVBUT1IKKyAgICBzZWxmLmFzc2VydEVxdWFsKGRlc2MuZmlsZS5wYWNrYWdlLCAncHJvdG9idWZfdW5pdHRlc3QnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIHVuaXR0ZXN0X2ltcG9ydF9wYjIuSW1wb3J0TWVzc2FnZS5ERVNDUklQVE9SLmZpbGUucGFja2FnZSwKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCcpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICB1bml0dGVzdF9wYjIuX0ZPUkVJR05FTlVNLmZpbGUucGFja2FnZSwgJ3Byb3RvYnVmX3VuaXR0ZXN0JykKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICB1bml0dGVzdF9wYjIuX1RFU1RBTExUWVBFU19ORVNURURFTlVNLmZpbGUucGFja2FnZSwKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0JykKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICB1bml0dGVzdF9pbXBvcnRfcGIyLl9JTVBPUlRFTlVNLmZpbGUucGFja2FnZSwKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCcpCisKKyAgZGVmIHRlc3RFeHRlbnNpb25SYW5nZShzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IuZXh0ZW5zaW9uX3JhbmdlcywgW10pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zLkRFU0NSSVBUT1IuZXh0ZW5zaW9uX3JhbmdlcywKKyAgICAgICAgWygxLCBNQVhfRVhURU5TSU9OKV0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5ERVNDUklQVE9SLmV4dGVuc2lvbl9yYW5nZXMsCisgICAgICAgIFsoNDIsIDQzKSwgKDQxNDMsIDQyNDQpLCAoNjU1MzYsIE1BWF9FWFRFTlNJT04pXSkKKworICBkZWYgdGVzdEZpbGVEZXNjcmlwdG9yKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLkRFU0NSSVBUT1IubmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICdnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8nKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLkRFU0NSSVBUT1IucGFja2FnZSwgJ3Byb3RvYnVmX3VuaXR0ZXN0JykKKyAgICBzZWxmLmFzc2VydEZhbHNlKHVuaXR0ZXN0X3BiMi5ERVNDUklQVE9SLnNlcmlhbGl6ZWRfcGIgaXMgTm9uZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5ERVNDUklQVE9SLmRlcGVuZGVuY2llcywKKyAgICAgICAgICAgICAgICAgICAgIFt1bml0dGVzdF9pbXBvcnRfcGIyLkRFU0NSSVBUT1JdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfaW1wb3J0X3BiMi5ERVNDUklQVE9SLmRlcGVuZGVuY2llcywKKyAgICAgICAgICAgICAgICAgICAgIFt1bml0dGVzdF9pbXBvcnRfcHVibGljX3BiMi5ERVNDUklQVE9SXSkKKworICBkZWYgdGVzdE5vR2VuZXJpY1NlcnZpY2VzKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0VHJ1ZShoYXNhdHRyKHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfcGIyLCAiVGVzdE1lc3NhZ2UiKSkKKyAgICBzZWxmLmFzc2VydFRydWUoaGFzYXR0cih1bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzX3BiMiwgIkZPTyIpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShoYXNhdHRyKHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfcGIyLCAidGVzdF9leHRlbnNpb24iKSkKKworICAgICMgTWFrZSBzdXJlIHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfcGIyIGhhcyBubyBzZXJ2aWNlcyBzdWJjbGFzc2luZworICAgICMgUHJvdG8yIFNlcnZpY2UgY2xhc3MuCisgICAgaWYgaGFzYXR0cih1bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzX3BiMiwgIlRlc3RTZXJ2aWNlIik6CisgICAgICBzZWxmLmFzc2VydEZhbHNlKGlzc3ViY2xhc3ModW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlc19wYjIuVGVzdFNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZS5TZXJ2aWNlKSkKKworICBkZWYgdGVzdE1lc3NhZ2VUeXBlc0J5TmFtZShzZWxmKToKKyAgICBmaWxlX3R5cGUgPSB1bml0dGVzdF9wYjIuREVTQ1JJUFRPUgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5fVEVTVEFMTFRZUEVTLAorICAgICAgICBmaWxlX3R5cGUubWVzc2FnZV90eXBlc19ieV9uYW1lW3VuaXR0ZXN0X3BiMi5fVEVTVEFMTFRZUEVTLm5hbWVdKQorCisgICAgIyBOZXN0ZWQgbWVzc2FnZXMgc2hvdWxkbid0IGJlIGluY2x1ZGVkIGluIHRoZSBtZXNzYWdlX3R5cGVzX2J5X25hbWUKKyAgICAjIGRpY3Rpb25hcnkgKGxpa2UgaW4gdGhlIEMrKyBBUEkpLgorICAgIHNlbGYuYXNzZXJ0RmFsc2UoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5fVEVTVEFMTFRZUEVTX05FU1RFRE1FU1NBR0UubmFtZSBpbgorICAgICAgICBmaWxlX3R5cGUubWVzc2FnZV90eXBlc19ieV9uYW1lKQorCisgIGRlZiB0ZXN0RW51bVR5cGVzQnlOYW1lKHNlbGYpOgorICAgIGZpbGVfdHlwZSA9IHVuaXR0ZXN0X3BiMi5ERVNDUklQVE9SCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgdW5pdHRlc3RfcGIyLl9GT1JFSUdORU5VTSwKKyAgICAgICAgZmlsZV90eXBlLmVudW1fdHlwZXNfYnlfbmFtZVt1bml0dGVzdF9wYjIuX0ZPUkVJR05FTlVNLm5hbWVdKQorCisgIGRlZiB0ZXN0RXh0ZW5zaW9uc0J5TmFtZShzZWxmKToKKyAgICBmaWxlX3R5cGUgPSB1bml0dGVzdF9wYjIuREVTQ1JJUFRPUgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5teV9leHRlbnNpb25fc3RyaW5nLAorICAgICAgICBmaWxlX3R5cGUuZXh0ZW5zaW9uc19ieV9uYW1lW3VuaXR0ZXN0X3BiMi5teV9leHRlbnNpb25fc3RyaW5nLm5hbWVdKQorCisgIGRlZiB0ZXN0UHVibGljSW1wb3J0cyhzZWxmKToKKyAgICAjIFRlc3QgcHVibGljIGltcG9ydHMgYXMgZW1iZWRkZWQgbWVzc2FnZS4KKyAgICBhbGxfdHlwZV9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgYWxsX3R5cGVfcHJvdG8ub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlLmUpCisKKyAgICAjIFB1YmxpY0ltcG9ydE1lc3NhZ2UgaXMgYWN0dWFsbHkgZGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljX3BiMgorICAgICMgbW9kdWxlLCBhbmQgaXMgcHVibGljIGltcG9ydGVkIGJ5IHVuaXR0ZXN0X2ltcG9ydF9wYjIgbW9kdWxlLgorICAgIHB1YmxpY19pbXBvcnRfcHJvdG8gPSB1bml0dGVzdF9pbXBvcnRfcGIyLlB1YmxpY0ltcG9ydE1lc3NhZ2UoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHVibGljX2ltcG9ydF9wcm90by5lKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1bml0dGVzdF9pbXBvcnRfcHVibGljX3BiMi5QdWJsaWNJbXBvcnRNZXNzYWdlIGlzCisgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X2ltcG9ydF9wYjIuUHVibGljSW1wb3J0TWVzc2FnZSkKKworICBkZWYgdGVzdEJhZElkZW50aWZpZXJzKHNlbGYpOgorICAgICMgV2UncmUganVzdCB0ZXN0aW5nIHRoYXQgdGhlIGNvZGUgd2FzIGltcG9ydGVkIHdpdGhvdXQgcHJvYmxlbXMuCisgICAgbWVzc2FnZSA9IHRlc3RfYmFkX2lkZW50aWZpZXJzX3BiMi5UZXN0QmFkSWRlbnRpZmllcnMoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5FeHRlbnNpb25zW3Rlc3RfYmFkX2lkZW50aWZpZXJzX3BiMi5tZXNzYWdlXSwKKyAgICAgICAgICAgICAgICAgICAgICJmb28iKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5FeHRlbnNpb25zW3Rlc3RfYmFkX2lkZW50aWZpZXJzX3BiMi5kZXNjcmlwdG9yXSwKKyAgICAgICAgICAgICAgICAgICAgICJiYXIiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5FeHRlbnNpb25zW3Rlc3RfYmFkX2lkZW50aWZpZXJzX3BiMi5yZWZsZWN0aW9uXSwKKyAgICAgICAgICAgICAgICAgICAgICJiYXoiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5FeHRlbnNpb25zW3Rlc3RfYmFkX2lkZW50aWZpZXJzX3BiMi5zZXJ2aWNlXSwKKyAgICAgICAgICAgICAgICAgICAgICJxdXgiKQorCisgIGRlZiB0ZXN0T25lb2Yoc2VsZik6CisgICAgZGVzYyA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuREVTQ1JJUFRPUgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgbGVuKGRlc2Mub25lb2ZzKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdvbmVvZl9maWVsZCcsIGRlc2Mub25lb2ZzWzBdLm5hbWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBkZXNjLm9uZW9mc1swXS5pbmRleCkKKyAgICBzZWxmLmFzc2VydElzKGRlc2MsIGRlc2Mub25lb2ZzWzBdLmNvbnRhaW5pbmdfdHlwZSkKKyAgICBzZWxmLmFzc2VydElzKGRlc2Mub25lb2ZzWzBdLCBkZXNjLm9uZW9mc19ieV9uYW1lWydvbmVvZl9maWVsZCddKQorICAgIG5lc3RlZF9uYW1lcyA9IHNldChbJ29uZW9mX3VpbnQzMicsICdvbmVvZl9uZXN0ZWRfbWVzc2FnZScsCisgICAgICAgICAgICAgICAgICAgICAgICAnb25lb2Zfc3RyaW5nJywgJ29uZW9mX2J5dGVzJ10pCisgICAgc2VsZi5hc3NlcnRTYW1lRWxlbWVudHMoCisgICAgICAgIG5lc3RlZF9uYW1lcywKKyAgICAgICAgW2ZpZWxkLm5hbWUgZm9yIGZpZWxkIGluIGRlc2Mub25lb2ZzWzBdLmZpZWxkc10pCisgICAgZm9yIGZpZWxkX25hbWUsIGZpZWxkX2Rlc2MgaW4gZGVzYy5maWVsZHNfYnlfbmFtZS5pdGVyaXRlbXMoKToKKyAgICAgIGlmIGZpZWxkX25hbWUgaW4gbmVzdGVkX25hbWVzOgorICAgICAgICBzZWxmLmFzc2VydElzKGRlc2Mub25lb2ZzWzBdLCBmaWVsZF9kZXNjLmNvbnRhaW5pbmdfb25lb2YpCisgICAgICBlbHNlOgorICAgICAgICBzZWxmLmFzc2VydElzTm9uZShmaWVsZF9kZXNjLmNvbnRhaW5pbmdfb25lb2YpCisKKworY2xhc3MgU3ltYm9sRGF0YWJhc2VSZWdpc3RyYXRpb25UZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKyAgIiIiQ2hlY2tzIHRoYXQgbWVzc2FnZXMsIGVudW1zIGFuZCBmaWxlcyBhcmUgY29ycmVjdGx5IHJlZ2lzdGVyZWQuIiIiCisKKyAgZGVmIHRlc3RHZXRTeW1ib2woc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMsIHN5bWJvbF9kYXRhYmFzZS5EZWZhdWx0KCkuR2V0U3ltYm9sKAorICAgICAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcycpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsCisgICAgICAgIHN5bWJvbF9kYXRhYmFzZS5EZWZhdWx0KCkuR2V0U3ltYm9sKAorICAgICAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlJykpCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhLZXlFcnJvcik6CisgICAgICBzeW1ib2xfZGF0YWJhc2UuRGVmYXVsdCgpLkdldFN5bWJvbCgncHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkTWVzc2FnZScpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCwKKyAgICAgICAgc3ltYm9sX2RhdGFiYXNlLkRlZmF1bHQoKS5HZXRTeW1ib2woCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLAorICAgICAgICBzeW1ib2xfZGF0YWJhc2UuRGVmYXVsdCgpLkdldFN5bWJvbCgKKyAgICAgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCcpKQorCisgIGRlZiB0ZXN0RW51bXMoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bScsCisgICAgICAgIHN5bWJvbF9kYXRhYmFzZS5EZWZhdWx0KCkucG9vbC5GaW5kRW51bVR5cGVCeU5hbWUoCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0nKS5mdWxsX25hbWUpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bScsCisgICAgICAgIHN5bWJvbF9kYXRhYmFzZS5EZWZhdWx0KCkucG9vbC5GaW5kRW51bVR5cGVCeU5hbWUoCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0nKS5mdWxsX25hbWUpCisKKyAgZGVmIHRlc3RGaW5kRmlsZUJ5TmFtZShzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bycsCisgICAgICAgIHN5bWJvbF9kYXRhYmFzZS5EZWZhdWx0KCkucG9vbC5GaW5kRmlsZUJ5TmFtZSgKKyAgICAgICAgICAgICdnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8nKS5uYW1lKQorCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvaW1wb3J0X3Rlc3RfcGFja2FnZS9fX2luaXRfXy5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvaW1wb3J0X3Rlc3RfcGFja2FnZS9fX2luaXRfXy5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MTIxZGQwCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9pbXBvcnRfdGVzdF9wYWNrYWdlL19faW5pdF9fLnB5CkBAIC0wLDAgKzEsMzMgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiU2FtcGxlIG1vZHVsZSBpbXBvcnRpbmcgYSBuZXN0ZWQgcHJvdG8gZnJvbSBpdHNlbGYuIiIiCisKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLmltcG9ydF90ZXN0X3BhY2thZ2UgaW1wb3J0IG91dGVyX3BiMiBhcyBteXByb3RvCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ltcG9ydF90ZXN0X3BhY2thZ2UvaW5uZXIucHJvdG8gYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ltcG9ydF90ZXN0X3BhY2thZ2UvaW5uZXIucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg4N2MxMgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvaW1wb3J0X3Rlc3RfcGFja2FnZS9pbm5lci5wcm90bwpAQCAtMCwwICsxLDM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5pbXBvcnRfdGVzdF9wYWNrYWdlOworCittZXNzYWdlIElubmVyIHsKKyAgb3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxIFtkZWZhdWx0ID0gNTddOworfQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9pbXBvcnRfdGVzdF9wYWNrYWdlL291dGVyLnByb3RvIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9pbXBvcnRfdGVzdF9wYWNrYWdlL291dGVyLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyN2ZiNWMKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ltcG9ydF90ZXN0X3BhY2thZ2Uvb3V0ZXIucHJvdG8KQEAgLTAsMCArMSwzOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuaW1wb3J0X3Rlc3RfcGFja2FnZTsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvaW1wb3J0X3Rlc3RfcGFja2FnZS9pbm5lci5wcm90byI7CisKK21lc3NhZ2UgT3V0ZXIgeworICBvcHRpb25hbCBJbm5lciBpbm5lciA9IDE7Cit9CmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfZmFjdG9yeV9weXRob25fdGVzdC5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9mYWN0b3J5X3B5dGhvbl90ZXN0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1ZTAyYjIKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfZmFjdG9yeV9weXRob25fdGVzdC5weQpAQCAtMCwwICsxLDU0IEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgZm9yIC4ucHVibGljLm1lc3NhZ2VfZmFjdG9yeSBmb3IgdGhlIHB1cmUgUHl0aG9uIGltcGxlbWVudGF0aW9uLiIiIgorCitpbXBvcnQgb3MKK29zLmVudmlyb25bJ1BST1RPQ09MX0JVRkZFUlNfUFlUSE9OX0lNUExFTUVOVEFUSU9OJ10gPSAncHl0aG9uJworCisjIFdlIG11c3Qgc2V0IHRoZSBpbXBsZW1lbnRhdGlvbiB2ZXJzaW9uIGFib3ZlIGJlZm9yZSB0aGUgZ29vZ2xlMyBpbXBvcnRzLgorIyBweWxpbnQ6IGRpc2FibGU9Zy1pbXBvcnQtbm90LWF0LXRvcAorZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgYXBpX2ltcGxlbWVudGF0aW9uCisjIFJ1biBhbGwgdGVzdHMgZnJvbSB0aGUgb3JpZ2luYWwgbW9kdWxlIGJ5IHB1dHRpbmcgdGhlbSBpbiBvdXIgbmFtZXNwYWNlLgorIyBweWxpbnQ6IGRpc2FibGU9d2lsZGNhcmQtaW1wb3J0Citmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC5tZXNzYWdlX2ZhY3RvcnlfdGVzdCBpbXBvcnQgKgorCisKK2NsYXNzIENvbmZpcm1QdXJlUHl0aG9uVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3RJbXBsZW1lbnRhdGlvblNldHRpbmcoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbCgncHl0aG9uJywgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSkKKworCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9mYWN0b3J5X3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfZmFjdG9yeV90ZXN0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjZjEzNDEKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfZmFjdG9yeV90ZXN0LnB5CkBAIC0wLDAgKzEsMTMxIEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgZm9yIGdvb2dsZS5wcm90b2J1Zi5tZXNzYWdlX2ZhY3RvcnkuIiIiCisKK19fYXV0aG9yX18gPSAnbWF0dGhld3RvaWFAZ29vZ2xlLmNvbSAoTWF0dCBUb2lhKScKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBmYWN0b3J5X3Rlc3QxX3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGZhY3RvcnlfdGVzdDJfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9kYXRhYmFzZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcG9vbAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2VfZmFjdG9yeQorCisKK2NsYXNzIE1lc3NhZ2VGYWN0b3J5VGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHNldFVwKHNlbGYpOgorICAgIHNlbGYuZmFjdG9yeV90ZXN0MV9mZCA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8uRnJvbVN0cmluZygKKyAgICAgICAgZmFjdG9yeV90ZXN0MV9wYjIuREVTQ1JJUFRPUi5zZXJpYWxpemVkX3BiKQorICAgIHNlbGYuZmFjdG9yeV90ZXN0Ml9mZCA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8uRnJvbVN0cmluZygKKyAgICAgICAgZmFjdG9yeV90ZXN0Ml9wYjIuREVTQ1JJUFRPUi5zZXJpYWxpemVkX3BiKQorCisgIGRlZiBfRXhlcmNpc2VEeW5hbWljQ2xhc3Moc2VsZiwgY2xzKToKKyAgICBtc2cgPSBjbHMoKQorICAgIG1zZy5tYW5kYXRvcnkgPSA0MgorICAgIG1zZy5uZXN0ZWRfZmFjdG9yeV8yX2VudW0gPSAwCisgICAgbXNnLm5lc3RlZF9mYWN0b3J5XzJfbWVzc2FnZS52YWx1ZSA9ICduZXN0ZWQgbWVzc2FnZSB2YWx1ZScKKyAgICBtc2cuZmFjdG9yeV8xX21lc3NhZ2UuZmFjdG9yeV8xX2VudW0gPSAxCisgICAgbXNnLmZhY3RvcnlfMV9tZXNzYWdlLm5lc3RlZF9mYWN0b3J5XzFfZW51bSA9IDAKKyAgICBtc2cuZmFjdG9yeV8xX21lc3NhZ2UubmVzdGVkX2ZhY3RvcnlfMV9tZXNzYWdlLnZhbHVlID0gKAorICAgICAgICAnbmVzdGVkIG1lc3NhZ2UgdmFsdWUnKQorICAgIG1zZy5mYWN0b3J5XzFfbWVzc2FnZS5zY2FsYXJfdmFsdWUgPSAyMgorICAgIG1zZy5mYWN0b3J5XzFfbWVzc2FnZS5saXN0X3ZhbHVlLmV4dGVuZChbdSdvbmUnLCB1J3R3bycsIHUndGhyZWUnXSkKKyAgICBtc2cuZmFjdG9yeV8xX21lc3NhZ2UubGlzdF92YWx1ZS5hcHBlbmQodSdmb3VyJykKKyAgICBtc2cuZmFjdG9yeV8xX2VudW0gPSAxCisgICAgbXNnLm5lc3RlZF9mYWN0b3J5XzFfZW51bSA9IDAKKyAgICBtc2cubmVzdGVkX2ZhY3RvcnlfMV9tZXNzYWdlLnZhbHVlID0gJ25lc3RlZCBtZXNzYWdlIHZhbHVlJworICAgIG1zZy5jaXJjdWxhcl9tZXNzYWdlLm1hbmRhdG9yeSA9IDEKKyAgICBtc2cuY2lyY3VsYXJfbWVzc2FnZS5jaXJjdWxhcl9tZXNzYWdlLm1hbmRhdG9yeSA9IDIKKyAgICBtc2cuY2lyY3VsYXJfbWVzc2FnZS5zY2FsYXJfdmFsdWUgPSAnb25lIGRlZXAnCisgICAgbXNnLnNjYWxhcl92YWx1ZSA9ICd6ZXJvIGRlZXAnCisgICAgbXNnLmxpc3RfdmFsdWUuZXh0ZW5kKFt1J2ZvdXInLCB1J3RocmVlJywgdSd0d28nXSkKKyAgICBtc2cubGlzdF92YWx1ZS5hcHBlbmQodSdvbmUnKQorICAgIG1zZy5ncm91cGVkLmFkZCgpCisgICAgbXNnLmdyb3VwZWRbMF0ucGFydF8xID0gJ2hlbGxvJworICAgIG1zZy5ncm91cGVkWzBdLnBhcnRfMiA9ICd3b3JsZCcKKyAgICBtc2cuZ3JvdXBlZC5hZGQocGFydF8xPSd0ZXN0aW5nJywgcGFydF8yPScxMjMnKQorICAgIG1zZy5sb29wLmxvb3AubWFuZGF0b3J5ID0gMgorICAgIG1zZy5sb29wLmxvb3AubG9vcC5sb29wLm1hbmRhdG9yeSA9IDQKKyAgICBzZXJpYWxpemVkID0gbXNnLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBjb252ZXJ0ZWQgPSBmYWN0b3J5X3Rlc3QyX3BiMi5GYWN0b3J5Mk1lc3NhZ2UuRnJvbVN0cmluZyhzZXJpYWxpemVkKQorICAgIHJlc2VyaWFsaXplZCA9IGNvbnZlcnRlZC5TZXJpYWxpemVUb1N0cmluZygpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoc2VyaWFsaXplZCwgcmVzZXJpYWxpemVkKQorICAgIHJlc3VsdCA9IGNscy5Gcm9tU3RyaW5nKHJlc2VyaWFsaXplZCkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhtc2csIHJlc3VsdCkKKworICBkZWYgdGVzdEdldFByb3RvdHlwZShzZWxmKToKKyAgICBkYiA9IGRlc2NyaXB0b3JfZGF0YWJhc2UuRGVzY3JpcHRvckRhdGFiYXNlKCkKKyAgICBwb29sID0gZGVzY3JpcHRvcl9wb29sLkRlc2NyaXB0b3JQb29sKGRiKQorICAgIGRiLkFkZChzZWxmLmZhY3RvcnlfdGVzdDFfZmQpCisgICAgZGIuQWRkKHNlbGYuZmFjdG9yeV90ZXN0Ml9mZCkKKyAgICBmYWN0b3J5ID0gbWVzc2FnZV9mYWN0b3J5Lk1lc3NhZ2VGYWN0b3J5KCkKKyAgICBjbHMgPSBmYWN0b3J5LkdldFByb3RvdHlwZShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgKKyAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTJNZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRJc05vdChjbHMsIGZhY3RvcnlfdGVzdDJfcGIyLkZhY3RvcnkyTWVzc2FnZSkKKyAgICBzZWxmLl9FeGVyY2lzZUR5bmFtaWNDbGFzcyhjbHMpCisgICAgY2xzMiA9IGZhY3RvcnkuR2V0UHJvdG90eXBlKHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5Mk1lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydElzKGNscywgY2xzMikKKworICBkZWYgdGVzdEdldE1lc3NhZ2VzKHNlbGYpOgorICAgICMgcGVyZm9ybWVkIHR3aWNlIGJlY2F1c2UgbXVsdGlwbGUgY2FsbHMgd2l0aCB0aGUgc2FtZSBpbnB1dCBtdXN0IGJlIGFsbG93ZWQKKyAgICBmb3IgXyBpbiByYW5nZSgyKToKKyAgICAgIG1lc3NhZ2VzID0gbWVzc2FnZV9mYWN0b3J5LkdldE1lc3NhZ2VzKFtzZWxmLmZhY3RvcnlfdGVzdDJfZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5mYWN0b3J5X3Rlc3QxX2ZkXSkKKyAgICAgIHNlbGYuYXNzZXJ0Q29udGFpbnNTdWJzZXQoCisgICAgICAgICAgWydnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkyTWVzc2FnZScsCisgICAgICAgICAgICdnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkxTWVzc2FnZSddLAorICAgICAgICAgIG1lc3NhZ2VzLmtleXMoKSkKKyAgICAgIHNlbGYuX0V4ZXJjaXNlRHluYW1pY0NsYXNzKAorICAgICAgICAgIG1lc3NhZ2VzWydnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsLkZhY3RvcnkyTWVzc2FnZSddKQorICAgICAgc2VsZi5hc3NlcnRDb250YWluc1N1YnNldCgKKyAgICAgICAgICBbJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTJNZXNzYWdlLm9uZV9tb3JlX2ZpZWxkJywKKyAgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuYW5vdGhlcl9maWVsZCddLAorICAgICAgICAgIChtZXNzYWdlc1snZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5MU1lc3NhZ2UnXQorICAgICAgICAgICAuX2V4dGVuc2lvbnNfYnlfbmFtZS5rZXlzKCkpKQorICAgICAgZmFjdG9yeV9tc2cxID0gbWVzc2FnZXNbJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTFNZXNzYWdlJ10KKyAgICAgIG1zZzEgPSBtZXNzYWdlc1snZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5GYWN0b3J5MU1lc3NhZ2UnXSgpCisgICAgICBleHQxID0gZmFjdG9yeV9tc2cxLl9leHRlbnNpb25zX2J5X25hbWVbCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weXRob24uaW50ZXJuYWwuRmFjdG9yeTJNZXNzYWdlLm9uZV9tb3JlX2ZpZWxkJ10KKyAgICAgIGV4dDIgPSBmYWN0b3J5X21zZzEuX2V4dGVuc2lvbnNfYnlfbmFtZVsKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbC5hbm90aGVyX2ZpZWxkJ10KKyAgICAgIG1zZzEuRXh0ZW5zaW9uc1tleHQxXSA9ICd0ZXN0MScKKyAgICAgIG1zZzEuRXh0ZW5zaW9uc1tleHQyXSA9ICd0ZXN0MicKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCd0ZXN0MScsIG1zZzEuRXh0ZW5zaW9uc1tleHQxXSkKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCd0ZXN0MicsIG1zZzEuRXh0ZW5zaW9uc1tleHQyXSkKKworCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9saXN0ZW5lci5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9saXN0ZW5lci5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4wZmMyNTVhCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tZXNzYWdlX2xpc3RlbmVyLnB5CkBAIC0wLDAgKzEsNzggQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiRGVmaW5lcyBhIGxpc3RlbmVyIGludGVyZmFjZSBmb3Igb2JzZXJ2aW5nIGNlcnRhaW4KK3N0YXRlIHRyYW5zaXRpb25zIG9uIE1lc3NhZ2Ugb2JqZWN0cy4KKworQWxzbyBkZWZpbmVzIGEgbnVsbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGludGVyZmFjZS4KKyIiIgorCitfX2F1dGhvcl9fID0gJ3JvYmluc29uQGdvb2dsZS5jb20gKFdpbGwgUm9iaW5zb24pJworCisKK2NsYXNzIE1lc3NhZ2VMaXN0ZW5lcihvYmplY3QpOgorCisgICIiIkxpc3RlbnMgZm9yIG1vZGlmaWNhdGlvbnMgbWFkZSB0byBhIG1lc3NhZ2UuICBNZWFudCB0byBiZSByZWdpc3RlcmVkIHZpYQorICBNZXNzYWdlLl9TZXRMaXN0ZW5lcigpLgorCisgIEF0dHJpYnV0ZXM6CisgICAgZGlydHk6ICBJZiBUcnVlLCB0aGVuIGNhbGxpbmcgTW9kaWZpZWQoKSB3b3VsZCBiZSBhIG5vLW9wLiAgVGhpcyBjYW4gYmUKKyAgICAgICAgICAgIHVzZWQgdG8gYXZvaWQgdGhlc2UgY2FsbHMgZW50aXJlbHkgaW4gdGhlIGNvbW1vbiBjYXNlLgorICAiIiIKKworICBkZWYgTW9kaWZpZWQoc2VsZik6CisgICAgIiIiQ2FsbGVkIGV2ZXJ5IHRpbWUgdGhlIG1lc3NhZ2UgaXMgbW9kaWZpZWQgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSBwYXJlbnQKKyAgICBtZXNzYWdlIG1heSBuZWVkIHRvIGJlIHVwZGF0ZWQuICBUaGlzIGN1cnJlbnRseSBtZWFucyBlaXRoZXI6CisgICAgKGEpIFRoZSBtZXNzYWdlIHdhcyBtb2RpZmllZCBmb3IgdGhlIGZpcnN0IHRpbWUsIHNvIHRoZSBwYXJlbnQgbWVzc2FnZQorICAgICAgICBzaG91bGQgaGVuY2Vmb3J0aCBtYXJrIHRoZSBtZXNzYWdlIGFzIHByZXNlbnQuCisgICAgKGIpIFRoZSBtZXNzYWdlJ3MgY2FjaGVkIGJ5dGUgc2l6ZSBiZWNhbWUgZGlydHkgLS0gaS5lLiB0aGUgbWVzc2FnZSB3YXMKKyAgICAgICAgbW9kaWZpZWQgZm9yIHRoZSBmaXJzdCB0aW1lIGFmdGVyIGEgcHJldmlvdXMgY2FsbCB0byBCeXRlU2l6ZSgpLgorICAgICAgICBUaGVyZWZvcmUgdGhlIHBhcmVudCBzaG91bGQgYWxzbyBtYXJrIGl0cyBieXRlIHNpemUgYXMgZGlydHkuCisgICAgTm90ZSB0aGF0IChhKSBpbXBsaWVzIChiKSwgc2luY2UgbmV3IG9iamVjdHMgc3RhcnQgb3V0IHdpdGggYSBjbGllbnQgY2FjaGVkCisgICAgc2l6ZSAoemVybykuICBIb3dldmVyLCB3ZSBkb2N1bWVudCAoYSkgZXhwbGljaXRseSBiZWNhdXNlIGl0IGlzIGltcG9ydGFudC4KKworICAgIE1vZGlmaWVkKCkgd2lsbCAqb25seSogYmUgY2FsbGVkIGluIHJlc3BvbnNlIHRvIG9uZSBvZiB0aGVzZSB0d28gZXZlbnRzIC0tCisgICAgbm90IGV2ZXJ5IHRpbWUgdGhlIHN1Yi1tZXNzYWdlIGlzIG1vZGlmaWVkLgorCisgICAgTm90ZSB0aGF0IGlmIHRoZSBsaXN0ZW5lcidzIHxkaXJ0eXwgYXR0cmlidXRlIGlzIHRydWUsIHRoZW4gY2FsbGluZworICAgIE1vZGlmaWVkIGF0IHRoZSBtb21lbnQgd291bGQgYmUgYSBuby1vcCwgc28gaXQgY2FuIGJlIHNraXBwZWQuICBQZXJmb3JtYW5jZS0KKyAgICBzZW5zaXRpdmUgY2FsbGVycyBzaG91bGQgY2hlY2sgdGhpcyBhdHRyaWJ1dGUgZGlyZWN0bHkgYmVmb3JlIGNhbGxpbmcgc2luY2UKKyAgICBpdCB3aWxsIGJlIHRydWUgbW9zdCBvZiB0aGUgdGltZS4KKyAgICAiIiIKKworICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworCitjbGFzcyBOdWxsTWVzc2FnZUxpc3RlbmVyKG9iamVjdCk6CisKKyAgIiIiTm8tb3AgTWVzc2FnZUxpc3RlbmVyIGltcGxlbWVudGF0aW9uLiIiIgorCisgIGRlZiBNb2RpZmllZChzZWxmKToKKyAgICBwYXNzCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfcHl0aG9uX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfcHl0aG9uX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzQwNjIzYQotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWVzc2FnZV9weXRob25fdGVzdC5weQpAQCAtMCwwICsxLDU0IEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgZm9yIC4ucHVibGljLm1lc3NhZ2UgZm9yIHRoZSBwdXJlIFB5dGhvbiBpbXBsZW1lbnRhdGlvbi4iIiIKKworaW1wb3J0IG9zCitvcy5lbnZpcm9uWydQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTiddID0gJ3B5dGhvbicKKworIyBXZSBtdXN0IHNldCB0aGUgaW1wbGVtZW50YXRpb24gdmVyc2lvbiBhYm92ZSBiZWZvcmUgdGhlIGdvb2dsZTMgaW1wb3J0cy4KKyMgcHlsaW50OiBkaXNhYmxlPWctaW1wb3J0LW5vdC1hdC10b3AKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGFwaV9pbXBsZW1lbnRhdGlvbgorIyBSdW4gYWxsIHRlc3RzIGZyb20gdGhlIG9yaWdpbmFsIG1vZHVsZSBieSBwdXR0aW5nIHRoZW0gaW4gb3VyIG5hbWVzcGFjZS4KKyMgcHlsaW50OiBkaXNhYmxlPXdpbGRjYXJkLWltcG9ydAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwubWVzc2FnZV90ZXN0IGltcG9ydCAqCisKKworY2xhc3MgQ29uZmlybVB1cmVQeXRob25UZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdEltcGxlbWVudGF0aW9uU2V0dGluZyhzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdweXRob24nLCBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpKQorCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIGJhc2V0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tZXNzYWdlX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21lc3NhZ2VfdGVzdC5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5lZDEyOThhCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tZXNzYWdlX3Rlc3QucHkKQEAgLTAsMCArMSwxMTQxIEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgcHl0aG9uIHByb3RvY29sIGJ1ZmZlcnMgYWdhaW5zdCB0aGUgZ29sZGVuIG1lc3NhZ2UuCisKK05vdGUgdGhhdCB0aGUgZ29sZGVuIG1lc3NhZ2VzIGV4ZXJjaXNlIGV2ZXJ5IGtub3duIGZpZWxkIHR5cGUsIHRodXMgdGhpcwordGVzdCBlbmRzIHVwIGV4ZXJjaXNpbmcgYW5kIHZlcmlmeWluZyBuZWFybHkgYWxsIG9mIHRoZSBwYXJzaW5nIGFuZAorc2VyaWFsaXphdGlvbiBjb2RlIGluIHRoZSB3aG9sZSBsaWJyYXJ5LgorCitUT0RPKGtlbnRvbik6ICBNZXJnZSB3aXRoIHdpcmVfZm9ybWF0X3Rlc3Q/ICBJdCBkb2Vzbid0IG1ha2UgYSB3aG9sZSBsb3Qgb2YKK3NlbnNlIHRvIGNhbGwgdGhpcyBhIHRlc3Qgb2YgdGhlICJtZXNzYWdlIiBtb2R1bGUsIHdoaWNoIG9ubHkgZGVjbGFyZXMgYW4KK2Fic3RyYWN0IGludGVyZmFjZS4KKyIiIgorCitfX2F1dGhvcl9fID0gJ2dwc0Bnb29nbGUuY29tIChHcmVnb3J5IFAuIFNtaXRoKScKKworaW1wb3J0IGNvcHkKK2ltcG9ydCBtYXRoCitpbXBvcnQgb3BlcmF0b3IKK2ltcG9ydCBwaWNrbGUKK2ltcG9ydCBzeXMKK2ltcG9ydCB1bml0dGVzdAorCitmcm9tIGdvb2dsZS5hcHB1dGlscyBpbXBvcnQgYmFzZXRlc3QKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBfcGFyYW1ldGVyaXplZAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3Byb3RvM19hcmVuYV9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBhcGlfaW1wbGVtZW50YXRpb24KK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCB0ZXN0X3V0aWwKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBtZXNzYWdlCisKKyMgUHl0aG9uIHByZS0yLjYgZG9lcyBub3QgaGF2ZSBpc2luZigpIG9yIGlzbmFuKCkgZnVuY3Rpb25zLCBzbyB3ZSBoYXZlCisjIHRvIHByb3ZpZGUgb3VyIG93bi4KK2RlZiBpc25hbih2YWwpOgorICAjIE5hTiBpcyBuZXZlciBlcXVhbCB0byBpdHNlbGYuCisgIHJldHVybiB2YWwgIT0gdmFsCitkZWYgaXNpbmYodmFsKToKKyAgIyBJbmZpbml0eSB0aW1lcyB6ZXJvIGVxdWFscyBOYU4uCisgIHJldHVybiBub3QgaXNuYW4odmFsKSBhbmQgaXNuYW4odmFsICogMCkKK2RlZiBJc1Bvc0luZih2YWwpOgorICByZXR1cm4gaXNpbmYodmFsKSBhbmQgKHZhbCA+IDApCitkZWYgSXNOZWdJbmYodmFsKToKKyAgcmV0dXJuIGlzaW5mKHZhbCkgYW5kICh2YWwgPCAwKQorCisKK0BfcGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzKAorICAgICh1bml0dGVzdF9wYjIpLAorICAgICh1bml0dGVzdF9wcm90bzNfYXJlbmFfcGIyKSkKK2NsYXNzIE1lc3NhZ2VUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdEJhZFV0ZjhTdHJpbmcoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIGlmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgIT0gJ3B5dGhvbic6CisgICAgICBzZWxmLnNraXBUZXN0KCJTa2lwcGluZyB0ZXN0QmFkVXRmOFN0cmluZywgY3VycmVudGx5IG9ubHkgdGhlIHB5dGhvbiAiCisgICAgICAgICAgICAgICAgICAgICJhcGkgaW1wbGVtZW50YXRpb24gcmFpc2VzIFVuaWNvZGVEZWNvZGVFcnJvciB3aGVuIGEgIgorICAgICAgICAgICAgICAgICAgICAic3RyaW5nIGZpZWxkIGNvbnRhaW5zIGJhZCB1dGYtOC4iKQorICAgIGJhZF91dGY4X2RhdGEgPSB0ZXN0X3V0aWwuR29sZGVuRmlsZURhdGEoJ2JhZF91dGY4X3N0cmluZycpCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhVbmljb2RlRGVjb2RlRXJyb3IpIGFzIGNvbnRleHQ6CisgICAgICBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMuRnJvbVN0cmluZyhiYWRfdXRmOF9kYXRhKQorICAgIHNlbGYuYXNzZXJ0SW4oJ1Rlc3RBbGxUeXBlcy5vcHRpb25hbF9zdHJpbmcnLCBzdHIoY29udGV4dC5leGNlcHRpb24pKQorCisgIGRlZiB0ZXN0R29sZGVuTWVzc2FnZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIyBQcm90bzMgZG9lc24ndCBoYXZlIHRoZSAiZGVmYXVsdF9mb28iIG1lbWJlcnMgb3IgZm9yZWlnbiBlbnVtcywKKyAgICAjIGFuZCBkb2Vzbid0IHByZXNlcnZlIHVua25vd24gZmllbGRzLCBzbyBmb3IgcHJvdG8zIHdlIHVzZSBhIGdvbGRlbgorICAgICMgbWVzc2FnZSB0aGF0IGRvZXNuJ3QgaGF2ZSB0aGVzZSBmaWVsZHMgc2V0LgorICAgIGlmIG1lc3NhZ2VfbW9kdWxlIGlzIHVuaXR0ZXN0X3BiMjoKKyAgICAgIGdvbGRlbl9kYXRhID0gdGVzdF91dGlsLkdvbGRlbkZpbGVEYXRhKAorICAgICAgICAgICdnb2xkZW5fbWVzc2FnZV9vbmVvZl9pbXBsZW1lbnRlZCcpCisgICAgZWxzZToKKyAgICAgIGdvbGRlbl9kYXRhID0gdGVzdF91dGlsLkdvbGRlbkZpbGVEYXRhKCdnb2xkZW5fbWVzc2FnZV9wcm90bzMnKQorCisgICAgZ29sZGVuX21lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIGdvbGRlbl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhnb2xkZW5fZGF0YSkKKyAgICBpZiBtZXNzYWdlX21vZHVsZSBpcyB1bml0dGVzdF9wYjI6CisgICAgICB0ZXN0X3V0aWwuRXhwZWN0QWxsRmllbGRzU2V0KHNlbGYsIGdvbGRlbl9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZ29sZGVuX2RhdGEsIGdvbGRlbl9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgZ29sZGVuX2NvcHkgPSBjb3B5LmRlZXBjb3B5KGdvbGRlbl9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZ29sZGVuX2RhdGEsIGdvbGRlbl9jb3B5LlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisKKyAgZGVmIHRlc3RHb2xkZW5QYWNrZWRNZXNzYWdlKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBnb2xkZW5fZGF0YSA9IHRlc3RfdXRpbC5Hb2xkZW5GaWxlRGF0YSgnZ29sZGVuX3BhY2tlZF9maWVsZHNfbWVzc2FnZScpCisgICAgZ29sZGVuX21lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0UGFja2VkVHlwZXMoKQorICAgIGdvbGRlbl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhnb2xkZW5fZGF0YSkKKyAgICBhbGxfc2V0ID0gbWVzc2FnZV9tb2R1bGUuVGVzdFBhY2tlZFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsUGFja2VkRmllbGRzKGFsbF9zZXQpCisgICAgc2VsZi5hc3NlcnRFcXVhbChhbGxfc2V0LCBnb2xkZW5fbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGdvbGRlbl9kYXRhLCBhbGxfc2V0LlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgZ29sZGVuX2NvcHkgPSBjb3B5LmRlZXBjb3B5KGdvbGRlbl9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZ29sZGVuX2RhdGEsIGdvbGRlbl9jb3B5LlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisKKyAgZGVmIHRlc3RQaWNrbGVTdXBwb3J0KHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBnb2xkZW5fZGF0YSA9IHRlc3RfdXRpbC5Hb2xkZW5GaWxlRGF0YSgnZ29sZGVuX21lc3NhZ2UnKQorICAgIGdvbGRlbl9tZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBnb2xkZW5fbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZ29sZGVuX2RhdGEpCisgICAgcGlja2xlZF9tZXNzYWdlID0gcGlja2xlLmR1bXBzKGdvbGRlbl9tZXNzYWdlKQorCisgICAgdW5waWNrbGVkX21lc3NhZ2UgPSBwaWNrbGUubG9hZHMocGlja2xlZF9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5waWNrbGVkX21lc3NhZ2UsIGdvbGRlbl9tZXNzYWdlKQorCisgIGRlZiB0ZXN0UG9zaXRpdmVJbmZpbml0eShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgZ29sZGVuX2RhdGEgPSAoYidceDVEXHgwMFx4MDBceDgwXHg3RicKKyAgICAgICAgICAgICAgICAgICBiJ1x4NjFceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceEYwXHg3RicKKyAgICAgICAgICAgICAgICAgICBiJ1x4Q0RceDAyXHgwMFx4MDBceDgwXHg3RicKKyAgICAgICAgICAgICAgICAgICBiJ1x4RDFceDAyXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhGMFx4N0YnKQorICAgIGdvbGRlbl9tZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBnb2xkZW5fbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZ29sZGVuX2RhdGEpCisgICAgc2VsZi5hc3NlcnRUcnVlKElzUG9zSW5mKGdvbGRlbl9tZXNzYWdlLm9wdGlvbmFsX2Zsb2F0KSkKKyAgICBzZWxmLmFzc2VydFRydWUoSXNQb3NJbmYoZ29sZGVuX21lc3NhZ2Uub3B0aW9uYWxfZG91YmxlKSkKKyAgICBzZWxmLmFzc2VydFRydWUoSXNQb3NJbmYoZ29sZGVuX21lc3NhZ2UucmVwZWF0ZWRfZmxvYXRbMF0pKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShJc1Bvc0luZihnb2xkZW5fbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVbMF0pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZ29sZGVuX2RhdGEsIGdvbGRlbl9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisKKyAgZGVmIHRlc3ROZWdhdGl2ZUluZmluaXR5KHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBnb2xkZW5fZGF0YSA9IChiJ1x4NURceDAwXHgwMFx4ODBceEZGJworICAgICAgICAgICAgICAgICAgIGInXHg2MVx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4RjBceEZGJworICAgICAgICAgICAgICAgICAgIGInXHhDRFx4MDJceDAwXHgwMFx4ODBceEZGJworICAgICAgICAgICAgICAgICAgIGInXHhEMVx4MDJceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceEYwXHhGRicpCisgICAgZ29sZGVuX21lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIGdvbGRlbl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhnb2xkZW5fZGF0YSkKKyAgICBzZWxmLmFzc2VydFRydWUoSXNOZWdJbmYoZ29sZGVuX21lc3NhZ2Uub3B0aW9uYWxfZmxvYXQpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShJc05lZ0luZihnb2xkZW5fbWVzc2FnZS5vcHRpb25hbF9kb3VibGUpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShJc05lZ0luZihnb2xkZW5fbWVzc2FnZS5yZXBlYXRlZF9mbG9hdFswXSkpCisgICAgc2VsZi5hc3NlcnRUcnVlKElzTmVnSW5mKGdvbGRlbl9tZXNzYWdlLnJlcGVhdGVkX2RvdWJsZVswXSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChnb2xkZW5fZGF0YSwgZ29sZGVuX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKworICBkZWYgdGVzdE5vdEFOdW1iZXIoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIGdvbGRlbl9kYXRhID0gKGInXHg1RFx4MDBceDAwXHhDMFx4N0YnCisgICAgICAgICAgICAgICAgICAgYidceDYxXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhGOFx4N0YnCisgICAgICAgICAgICAgICAgICAgYidceENEXHgwMlx4MDBceDAwXHhDMFx4N0YnCisgICAgICAgICAgICAgICAgICAgYidceEQxXHgwMlx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4RjhceDdGJykKKyAgICBnb2xkZW5fbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgZ29sZGVuX21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGdvbGRlbl9kYXRhKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihnb2xkZW5fbWVzc2FnZS5vcHRpb25hbF9mbG9hdCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKGlzbmFuKGdvbGRlbl9tZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSkpCisgICAgc2VsZi5hc3NlcnRUcnVlKGlzbmFuKGdvbGRlbl9tZXNzYWdlLnJlcGVhdGVkX2Zsb2F0WzBdKSkKKyAgICBzZWxmLmFzc2VydFRydWUoaXNuYW4oZ29sZGVuX21lc3NhZ2UucmVwZWF0ZWRfZG91YmxlWzBdKSkKKworICAgICMgVGhlIHByb3RvY29sIGJ1ZmZlciBtYXkgc2VyaWFsaXplIHRvIGFueSBvbmUgb2YgbXVsdGlwbGUgZGlmZmVyZW50CisgICAgIyByZXByZXNlbnRhdGlvbnMgb2YgYSBOYU4uICBSYXRoZXIgdGhhbiB2ZXJpZnkgYSBzcGVjaWZpYyByZXByZXNlbnRhdGlvbiwKKyAgICAjIHZlcmlmeSB0aGUgc2VyaWFsaXplZCBzdHJpbmcgY2FuIGJlIGNvbnZlcnRlZCBpbnRvIGEgY29ycmVjdGx5CisgICAgIyBiZWhhdmluZyBwcm90b2NvbCBidWZmZXIuCisgICAgc2VyaWFsaXplZCA9IGdvbGRlbl9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0KSkKKyAgICBzZWxmLmFzc2VydFRydWUoaXNuYW4obWVzc2FnZS5vcHRpb25hbF9kb3VibGUpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0WzBdKSkKKyAgICBzZWxmLmFzc2VydFRydWUoaXNuYW4obWVzc2FnZS5yZXBlYXRlZF9kb3VibGVbMF0pKQorCisgIGRlZiB0ZXN0UG9zaXRpdmVJbmZpbml0eVBhY2tlZChzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgZ29sZGVuX2RhdGEgPSAoYidceEEyXHgwNlx4MDRceDAwXHgwMFx4ODBceDdGJworICAgICAgICAgICAgICAgICAgIGInXHhBQVx4MDZceDA4XHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhGMFx4N0YnKQorICAgIGdvbGRlbl9tZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdFBhY2tlZFR5cGVzKCkKKyAgICBnb2xkZW5fbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZ29sZGVuX2RhdGEpCisgICAgc2VsZi5hc3NlcnRUcnVlKElzUG9zSW5mKGdvbGRlbl9tZXNzYWdlLnBhY2tlZF9mbG9hdFswXSkpCisgICAgc2VsZi5hc3NlcnRUcnVlKElzUG9zSW5mKGdvbGRlbl9tZXNzYWdlLnBhY2tlZF9kb3VibGVbMF0pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZ29sZGVuX2RhdGEsIGdvbGRlbl9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisKKyAgZGVmIHRlc3ROZWdhdGl2ZUluZmluaXR5UGFja2VkKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBnb2xkZW5fZGF0YSA9IChiJ1x4QTJceDA2XHgwNFx4MDBceDAwXHg4MFx4RkYnCisgICAgICAgICAgICAgICAgICAgYidceEFBXHgwNlx4MDhceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceEYwXHhGRicpCisgICAgZ29sZGVuX21lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0UGFja2VkVHlwZXMoKQorICAgIGdvbGRlbl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhnb2xkZW5fZGF0YSkKKyAgICBzZWxmLmFzc2VydFRydWUoSXNOZWdJbmYoZ29sZGVuX21lc3NhZ2UucGFja2VkX2Zsb2F0WzBdKSkKKyAgICBzZWxmLmFzc2VydFRydWUoSXNOZWdJbmYoZ29sZGVuX21lc3NhZ2UucGFja2VkX2RvdWJsZVswXSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChnb2xkZW5fZGF0YSwgZ29sZGVuX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKworICBkZWYgdGVzdE5vdEFOdW1iZXJQYWNrZWQoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIGdvbGRlbl9kYXRhID0gKGInXHhBMlx4MDZceDA0XHgwMFx4MDBceEMwXHg3RicKKyAgICAgICAgICAgICAgICAgICBiJ1x4QUFceDA2XHgwOFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4RjhceDdGJykKKyAgICBnb2xkZW5fbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RQYWNrZWRUeXBlcygpCisgICAgZ29sZGVuX21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGdvbGRlbl9kYXRhKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihnb2xkZW5fbWVzc2FnZS5wYWNrZWRfZmxvYXRbMF0pKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihnb2xkZW5fbWVzc2FnZS5wYWNrZWRfZG91YmxlWzBdKSkKKworICAgIHNlcmlhbGl6ZWQgPSBnb2xkZW5fbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpCisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RQYWNrZWRUeXBlcygpCisgICAgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkKKyAgICBzZWxmLmFzc2VydFRydWUoaXNuYW4obWVzc2FnZS5wYWNrZWRfZmxvYXRbMF0pKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc25hbihtZXNzYWdlLnBhY2tlZF9kb3VibGVbMF0pKQorCisgIGRlZiB0ZXN0RXh0cmVtZUZsb2F0VmFsdWVzKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKworICAgICMgTW9zdCBwb3NpdGl2ZSBleHBvbmVudCwgbm8gc2lnbmlmaWNhbmQgYml0cyBzZXQuCisgICAga01vc3RQb3NFeHBvbmVudE5vU2lnQml0cyA9IG1hdGgucG93KDIsIDEyNykKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ID0ga01vc3RQb3NFeHBvbmVudE5vU2lnQml0cworICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9PSBrTW9zdFBvc0V4cG9uZW50Tm9TaWdCaXRzKQorCisgICAgIyBNb3N0IHBvc2l0aXZlIGV4cG9uZW50LCBvbmUgc2lnbmlmaWNhbmQgYml0IHNldC4KKyAgICBrTW9zdFBvc0V4cG9uZW50T25lU2lnQml0ID0gMS41ICogbWF0aC5wb3coMiwgMTI3KQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPSBrTW9zdFBvc0V4cG9uZW50T25lU2lnQml0CisgICAgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ID09IGtNb3N0UG9zRXhwb25lbnRPbmVTaWdCaXQpCisKKyAgICAjIFJlcGVhdCBsYXN0IHR3byBjYXNlcyB3aXRoIHZhbHVlcyBvZiBzYW1lIG1hZ25pdHVkZSwgYnV0IG5lZ2F0aXZlLgorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPSAta01vc3RQb3NFeHBvbmVudE5vU2lnQml0cworICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9PSAta01vc3RQb3NFeHBvbmVudE5vU2lnQml0cykKKworICAgIG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPSAta01vc3RQb3NFeHBvbmVudE9uZVNpZ0JpdAorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9PSAta01vc3RQb3NFeHBvbmVudE9uZVNpZ0JpdCkKKworICAgICMgTW9zdCBuZWdhdGl2ZSBleHBvbmVudCwgbm8gc2lnbmlmaWNhbmQgYml0cyBzZXQuCisgICAga01vc3ROZWdFeHBvbmVudE5vU2lnQml0cyA9IG1hdGgucG93KDIsIC0xMjcpCisgICAgbWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9IGtNb3N0TmVnRXhwb25lbnROb1NpZ0JpdHMKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPT0ga01vc3ROZWdFeHBvbmVudE5vU2lnQml0cykKKworICAgICMgTW9zdCBuZWdhdGl2ZSBleHBvbmVudCwgb25lIHNpZ25pZmljYW5kIGJpdCBzZXQuCisgICAga01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdCA9IDEuNSAqIG1hdGgucG93KDIsIC0xMjcpCisgICAgbWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9IGtNb3N0TmVnRXhwb25lbnRPbmVTaWdCaXQKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPT0ga01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdCkKKworICAgICMgUmVwZWF0IGxhc3QgdHdvIGNhc2VzIHdpdGggdmFsdWVzIG9mIHRoZSBzYW1lIG1hZ25pdHVkZSwgYnV0IG5lZ2F0aXZlLgorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPSAta01vc3ROZWdFeHBvbmVudE5vU2lnQml0cworICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9PSAta01vc3ROZWdFeHBvbmVudE5vU2lnQml0cykKKworICAgIG1lc3NhZ2Uub3B0aW9uYWxfZmxvYXQgPSAta01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdAorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9mbG9hdCA9PSAta01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdCkKKworICBkZWYgdGVzdEV4dHJlbWVEb3VibGVWYWx1ZXMoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorCisgICAgIyBNb3N0IHBvc2l0aXZlIGV4cG9uZW50LCBubyBzaWduaWZpY2FuZCBiaXRzIHNldC4KKyAgICBrTW9zdFBvc0V4cG9uZW50Tm9TaWdCaXRzID0gbWF0aC5wb3coMiwgMTAyMykKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSA9IGtNb3N0UG9zRXhwb25lbnROb1NpZ0JpdHMKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID09IGtNb3N0UG9zRXhwb25lbnROb1NpZ0JpdHMpCisKKyAgICAjIE1vc3QgcG9zaXRpdmUgZXhwb25lbnQsIG9uZSBzaWduaWZpY2FuZCBiaXQgc2V0LgorICAgIGtNb3N0UG9zRXhwb25lbnRPbmVTaWdCaXQgPSAxLjUgKiBtYXRoLnBvdygyLCAxMDIzKQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID0ga01vc3RQb3NFeHBvbmVudE9uZVNpZ0JpdAorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPT0ga01vc3RQb3NFeHBvbmVudE9uZVNpZ0JpdCkKKworICAgICMgUmVwZWF0IGxhc3QgdHdvIGNhc2VzIHdpdGggdmFsdWVzIG9mIHNhbWUgbWFnbml0dWRlLCBidXQgbmVnYXRpdmUuCisgICAgbWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPSAta01vc3RQb3NFeHBvbmVudE5vU2lnQml0cworICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPT0gLWtNb3N0UG9zRXhwb25lbnROb1NpZ0JpdHMpCisKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSA9IC1rTW9zdFBvc0V4cG9uZW50T25lU2lnQml0CisgICAgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSA9PSAta01vc3RQb3NFeHBvbmVudE9uZVNpZ0JpdCkKKworICAgICMgTW9zdCBuZWdhdGl2ZSBleHBvbmVudCwgbm8gc2lnbmlmaWNhbmQgYml0cyBzZXQuCisgICAga01vc3ROZWdFeHBvbmVudE5vU2lnQml0cyA9IG1hdGgucG93KDIsIC0xMDIzKQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID0ga01vc3ROZWdFeHBvbmVudE5vU2lnQml0cworICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPT0ga01vc3ROZWdFeHBvbmVudE5vU2lnQml0cykKKworICAgICMgTW9zdCBuZWdhdGl2ZSBleHBvbmVudCwgb25lIHNpZ25pZmljYW5kIGJpdCBzZXQuCisgICAga01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdCA9IDEuNSAqIG1hdGgucG93KDIsIC0xMDIzKQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID0ga01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdAorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPT0ga01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdCkKKworICAgICMgUmVwZWF0IGxhc3QgdHdvIGNhc2VzIHdpdGggdmFsdWVzIG9mIHRoZSBzYW1lIG1hZ25pdHVkZSwgYnV0IG5lZ2F0aXZlLgorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID0gLWtNb3N0TmVnRXhwb25lbnROb1NpZ0JpdHMKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID09IC1rTW9zdE5lZ0V4cG9uZW50Tm9TaWdCaXRzKQorCisgICAgbWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPSAta01vc3ROZWdFeHBvbmVudE9uZVNpZ0JpdAorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9kb3VibGUgPT0gLWtNb3N0TmVnRXhwb25lbnRPbmVTaWdCaXQpCisKKyAgZGVmIHRlc3RGbG9hdFByaW50aW5nKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ID0gMi4wCisgICAgc2VsZi5hc3NlcnRFcXVhbChzdHIobWVzc2FnZSksICdvcHRpb25hbF9mbG9hdDogMi4wXG4nKQorCisgIGRlZiB0ZXN0SGlnaFByZWNpc2lvbkZsb2F0UHJpbnRpbmcoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlID0gMC4xMjM0NTY3ODkxMjM0NTY3OAorICAgIGlmIHN5cy52ZXJzaW9uX2luZm8ubWFqb3IgPj0gMzoKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc3RyKG1lc3NhZ2UpLCAnb3B0aW9uYWxfZG91YmxlOiAwLjEyMzQ1Njc4OTEyMzQ1Njc4XG4nKQorICAgIGVsc2U6CisgICAgICBzZWxmLmFzc2VydEVxdWFsKHN0cihtZXNzYWdlKSwgJ29wdGlvbmFsX2RvdWJsZTogMC4xMjM0NTY3ODkxMjNcbicpCisKKyAgZGVmIHRlc3RVbmtub3duRmllbGRQcmludGluZyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgcG9wdWxhdGVkID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsTm9uTGF6eUZpZWxkcyhwb3B1bGF0ZWQpCisgICAgZW1wdHkgPSBtZXNzYWdlX21vZHVsZS5UZXN0RW1wdHlNZXNzYWdlKCkKKyAgICBlbXB0eS5QYXJzZUZyb21TdHJpbmcocG9wdWxhdGVkLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzdHIoZW1wdHkpLCAnJykKKworICBkZWYgdGVzdFJlcGVhdGVkTmVzdGVkRmllbGRJdGVyYXRpb24oc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1zZyA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbXNnLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZChiYj0xKQorICAgIG1zZy5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoYmI9MikKKyAgICBtc2cucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKGJiPTMpCisgICAgbXNnLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZChiYj00KQorCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMSwgMiwgMywgNF0sCisgICAgICAgICAgICAgICAgICAgICBbbS5iYiBmb3IgbSBpbiBtc2cucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWzQsIDMsIDIsIDFdLAorICAgICAgICAgICAgICAgICAgICAgW20uYmIgZm9yIG0gaW4gcmV2ZXJzZWQobXNnLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKV0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNCwgMywgMiwgMV0sCisgICAgICAgICAgICAgICAgICAgICBbbS5iYiBmb3IgbSBpbiBtc2cucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbOjotMV1dKQorCisgIGRlZiB0ZXN0U29ydGluZ1JlcGVhdGVkU2NhbGFyRmllbGRzRGVmYXVsdENvbXBhcmF0b3Ioc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgICIiIkNoZWNrIHNvbWUgZGlmZmVyZW50IHR5cGVzIHdpdGggdGhlIGRlZmF1bHQgY29tcGFyYXRvci4iIiIKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKworICAgICMgVE9ETyhtYXR0cCk6IHdvdWxkIHRlc3RpbmcgbW9yZSBzY2FsYXIgdHlwZXMgc3RyZW5ndGhlbiB0ZXN0PworICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDEpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgyKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuc29ydCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLnJlcGVhdGVkX2ludDMyWzBdLCAxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9pbnQzMlsxXSwgMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJbMl0sIDMpCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0LmFwcGVuZCgxLjEpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdC5hcHBlbmQoMS4zKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQuYXBwZW5kKDEuMikKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0LnNvcnQoKQorICAgIHNlbGYuYXNzZXJ0QWxtb3N0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9mbG9hdFswXSwgMS4xKQorICAgIHNlbGYuYXNzZXJ0QWxtb3N0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9mbG9hdFsxXSwgMS4yKQorICAgIHNlbGYuYXNzZXJ0QWxtb3N0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9mbG9hdFsyXSwgMS4zKQorCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKCdhJykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQoJ2MnKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZCgnYicpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuc29ydCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ1swXSwgJ2EnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbMV0sICdiJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzJdLCAnYycpCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzLmFwcGVuZChiJ2EnKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMuYXBwZW5kKGInYycpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcy5hcHBlbmQoYidiJykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzLnNvcnQoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9ieXRlc1swXSwgYidhJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXNbMV0sIGInYicpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLnJlcGVhdGVkX2J5dGVzWzJdLCBiJ2MnKQorCisgIGRlZiB0ZXN0U29ydGluZ1JlcGVhdGVkU2NhbGFyRmllbGRzQ3VzdG9tQ29tcGFyYXRvcihzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiQ2hlY2sgc29tZSBkaWZmZXJlbnQgdHlwZXMgd2l0aCBjdXN0b20gY29tcGFyYXRvci4iIiIKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKworICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuYXBwZW5kKC0zKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuYXBwZW5kKC0yKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuYXBwZW5kKC0xKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuc29ydChrZXk9YWJzKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9pbnQzMlswXSwgLTEpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLnJlcGVhdGVkX2ludDMyWzFdLCAtMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJbMl0sIC0zKQorCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKCdhYWEnKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZCgnYmInKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZCgnYycpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuc29ydChrZXk9bGVuKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbMF0sICdjJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzFdLCAnYmInKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbMl0sICdhYWEnKQorCisgIGRlZiB0ZXN0U29ydGluZ1JlcGVhdGVkQ29tcG9zaXRlRmllbGRzQ3VzdG9tQ29tcGFyYXRvcihzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiQ2hlY2sgcGFzc2luZyBhIGN1c3RvbSBjb21wYXJhdG9yIHRvIHNvcnQgYSByZXBlYXRlZCBjb21wb3NpdGUgZmllbGQuIiIiCisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpLmJiID0gMQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkuYmIgPSAzCisgICAgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDIKKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpLmJiID0gNgorICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkuYmIgPSA1CisgICAgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDQKKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLnNvcnQoa2V5PW9wZXJhdG9yLmF0dHJnZXR0ZXIoJ2JiJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdLmJiLCAxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsxXS5iYiwgMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbMl0uYmIsIDMpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzNdLmJiLCA0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVs0XS5iYiwgNSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbNV0uYmIsIDYpCisKKyAgZGVmIHRlc3RSZXBlYXRlZENvbXBvc2l0ZUZpZWxkU29ydEFyZ3VtZW50cyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiQ2hlY2sgc29ydGluZyBhIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZCB1c2luZyBsaXN0LnNvcnQoKSBhcmd1bWVudHMuIiIiCisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisKKyAgICBnZXRfYmIgPSBvcGVyYXRvci5hdHRyZ2V0dGVyKCdiYicpCisgICAgY21wX2JiID0gbGFtYmRhIGEsIGI6IGNtcChhLmJiLCBiLmJiKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkuYmIgPSAxCisgICAgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDMKKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpLmJiID0gMgorICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkuYmIgPSA2CisgICAgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDUKKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpLmJiID0gNAorICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Uuc29ydChrZXk9Z2V0X2JiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoW2suYmIgZm9yIGsgaW4gbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV0sCisgICAgICAgICAgICAgICAgICAgICBbMSwgMiwgMywgNCwgNSwgNl0pCisgICAgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5zb3J0KGtleT1nZXRfYmIsIHJldmVyc2U9VHJ1ZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFtrLmJiIGZvciBrIGluIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VdLAorICAgICAgICAgICAgICAgICAgICAgWzYsIDUsIDQsIDMsIDIsIDFdKQorICAgIGlmIHN5cy52ZXJzaW9uX2luZm8ubWFqb3IgPj0gMzogcmV0dXJuICAjIE5vIGNtcCBzb3J0aW5nIGluIFBZMy4KKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLnNvcnQoc29ydF9mdW5jdGlvbj1jbXBfYmIpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbay5iYiBmb3IgayBpbiBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlXSwKKyAgICAgICAgICAgICAgICAgICAgIFsxLCAyLCAzLCA0LCA1LCA2XSkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLnNvcnQoY21wPWNtcF9iYiwgcmV2ZXJzZT1UcnVlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoW2suYmIgZm9yIGsgaW4gbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV0sCisgICAgICAgICAgICAgICAgICAgICBbNiwgNSwgNCwgMywgMiwgMV0pCisKKyAgZGVmIHRlc3RSZXBlYXRlZFNjYWxhckZpZWxkU29ydEFyZ3VtZW50cyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiQ2hlY2sgc29ydGluZyBhIHNjYWxhciBmaWVsZCB1c2luZyBsaXN0LnNvcnQoKSBhcmd1bWVudHMuIiIiCisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgtMykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgtMikKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgtMSkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLnNvcnQoa2V5PWFicykKKyAgICBzZWxmLmFzc2VydEVxdWFsKGxpc3QobWVzc2FnZS5yZXBlYXRlZF9pbnQzMiksIFstMSwgLTIsIC0zXSkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLnNvcnQoa2V5PWFicywgcmV2ZXJzZT1UcnVlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobGlzdChtZXNzYWdlLnJlcGVhdGVkX2ludDMyKSwgWy0zLCAtMiwgLTFdKQorICAgIGlmIHN5cy52ZXJzaW9uX2luZm8ubWFqb3IgPCAzOiAgIyBObyBjbXAgc29ydGluZyBpbiBQWTMuCisgICAgICBhYnNfY21wID0gbGFtYmRhIGEsIGI6IGNtcChhYnMoYSksIGFicyhiKSkKKyAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuc29ydChzb3J0X2Z1bmN0aW9uPWFic19jbXApCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGxpc3QobWVzc2FnZS5yZXBlYXRlZF9pbnQzMiksIFstMSwgLTIsIC0zXSkKKyAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuc29ydChjbXA9YWJzX2NtcCwgcmV2ZXJzZT1UcnVlKQorICAgICAgc2VsZi5hc3NlcnRFcXVhbChsaXN0KG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIpLCBbLTMsIC0yLCAtMV0pCisKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQoJ2FhYScpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKCdiYicpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKCdjJykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5zb3J0KGtleT1sZW4pCisgICAgc2VsZi5hc3NlcnRFcXVhbChsaXN0KG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKSwgWydjJywgJ2JiJywgJ2FhYSddKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLnNvcnQoa2V5PWxlbiwgcmV2ZXJzZT1UcnVlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobGlzdChtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyksIFsnYWFhJywgJ2JiJywgJ2MnXSkKKyAgICBpZiBzeXMudmVyc2lvbl9pbmZvLm1ham9yIDwgMzogICMgTm8gY21wIHNvcnRpbmcgaW4gUFkzLgorICAgICAgbGVuX2NtcCA9IGxhbWJkYSBhLCBiOiBjbXAobGVuKGEpLCBsZW4oYikpCisgICAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5zb3J0KHNvcnRfZnVuY3Rpb249bGVuX2NtcCkKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGlzdChtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyksIFsnYycsICdiYicsICdhYWEnXSkKKyAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLnNvcnQoY21wPWxlbl9jbXAsIHJldmVyc2U9VHJ1ZSkKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGlzdChtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyksIFsnYWFhJywgJ2JiJywgJ2MnXSkKKworICBkZWYgdGVzdFJlcGVhdGVkRmllbGRzQ29tcGFyYWJsZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbTEgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG0yID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtMS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMCkKKyAgICBtMS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMSkKKyAgICBtMS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMikKKyAgICBtMi5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMCkKKyAgICBtMi5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMSkKKyAgICBtMi5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMikKKyAgICBtMS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDEKKyAgICBtMS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDIKKyAgICBtMS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDMKKyAgICBtMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDEKKyAgICBtMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDIKKyAgICBtMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDMKKworICAgIGlmIHN5cy52ZXJzaW9uX2luZm8ubWFqb3IgPj0gMzogcmV0dXJuICAjIE5vIGNtcCgpIGluIFBZMy4KKworICAgICMgVGhlc2UgY29tcGFyaXNvbnMgc2hvdWxkIG5vdCByYWlzZSBlcnJvcnMuCisgICAgXyA9IG0xIDwgbTIKKyAgICBfID0gbTEucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPCBtMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZQorCisgICAgIyBNYWtlIHN1cmUgY21wIGFsd2F5cyB3b3Jrcy4gSWYgaXQgd2Fzbid0IGRlZmluZWQsIHRoZXNlIHdvdWxkIGJlCisgICAgIyBpZCgpIGNvbXBhcmlzb25zIGFuZCB3b3VsZCBhbGwgZmFpbC4KKyAgICBzZWxmLmFzc2VydEVxdWFsKGNtcChtMSwgbTIpLCAwKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoY21wKG0xLnJlcGVhdGVkX2ludDMyLCBtMi5yZXBlYXRlZF9pbnQzMiksIDApCisgICAgc2VsZi5hc3NlcnRFcXVhbChjbXAobTEucmVwZWF0ZWRfaW50MzIsIFswLCAxLCAyXSksIDApCisgICAgc2VsZi5hc3NlcnRFcXVhbChjbXAobTEucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgbTIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpLCAwKQorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yKToKKyAgICAgICMgQ2FuJ3QgY29tcGFyZSByZXBlYXRlZCBjb21wb3NpdGUgY29udGFpbmVycyB0byBsaXN0cy4KKyAgICAgIGNtcChtMS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSwgbTIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbOl0pCisKKyAgICAjIFRPRE8oYW51cmFhZyk6IEltcGxlbWVudCBleHRlbnNpb25kaWN0IGNvbXBhcmlzb24gaW4gQysrIGFuZCB0aGVuIGFkZCB0ZXN0CisKKyAgZGVmIGVuc3VyZU5lc3RlZE1lc3NhZ2VFeGlzdHMoc2VsZiwgbXNnLCBhdHRyaWJ1dGUpOgorICAgICIiIk1ha2Ugc3VyZSB0aGF0IGEgbmVzdGVkIG1lc3NhZ2Ugb2JqZWN0IGV4aXN0cy4KKworICAgIEFzIHNvb24gYXMgYSBuZXN0ZWQgbWVzc2FnZSBhdHRyaWJ1dGUgaXMgYWNjZXNzZWQsIGl0IHdpbGwgYmUgcHJlc2VudCBpbiB0aGUKKyAgICBfZmllbGRzIGRpY3QsIHdpdGhvdXQgYmVpbmcgbWFya2VkIGFzIGFjdHVhbGx5IGJlaW5nIHNldC4KKyAgICAiIiIKKyAgICBnZXRhdHRyKG1zZywgYXR0cmlidXRlKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobXNnLkhhc0ZpZWxkKGF0dHJpYnV0ZSkpCisKKyAgZGVmIHRlc3RPbmVvZkdldENhc2VOb25leGlzdGluZ0ZpZWxkKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBtLldoaWNoT25lb2YsICdub19zdWNoX29uZW9mX2ZpZWxkJykKKworICBkZWYgdGVzdE9uZW9mRGVmYXVsdFZhbHVlcyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRJcyhOb25lLCBtLldoaWNoT25lb2YoJ29uZW9mX2ZpZWxkJykpCisgICAgc2VsZi5hc3NlcnRGYWxzZShtLkhhc0ZpZWxkKCdvbmVvZl91aW50MzInKSkKKworICAgICMgT25lb2YgaXMgc2V0IGV2ZW4gd2hlbiBzZXR0aW5nIGl0IHRvIGEgZGVmYXVsdCB2YWx1ZS4KKyAgICBtLm9uZW9mX3VpbnQzMiA9IDAKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdvbmVvZl91aW50MzInLCBtLldoaWNoT25lb2YoJ29uZW9mX2ZpZWxkJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKG0uSGFzRmllbGQoJ29uZW9mX3VpbnQzMicpKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobS5IYXNGaWVsZCgnb25lb2Zfc3RyaW5nJykpCisKKyAgICBtLm9uZW9mX3N0cmluZyA9ICIiCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnb25lb2Zfc3RyaW5nJywgbS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtLkhhc0ZpZWxkKCdvbmVvZl9zdHJpbmcnKSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX3VpbnQzMicpKQorCisgIGRlZiB0ZXN0T25lb2ZTZW1hbnRpY3Moc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0SXMoTm9uZSwgbS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorCisgICAgbS5vbmVvZl91aW50MzIgPSAxMQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX3VpbnQzMicsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKyAgICBzZWxmLmFzc2VydFRydWUobS5IYXNGaWVsZCgnb25lb2ZfdWludDMyJykpCisKKyAgICBtLm9uZW9mX3N0cmluZyA9IHUnZm9vJworICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX3N0cmluZycsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX3VpbnQzMicpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtLkhhc0ZpZWxkKCdvbmVvZl9zdHJpbmcnKSkKKworICAgIG0ub25lb2ZfbmVzdGVkX21lc3NhZ2UuYmIgPSAxMQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX25lc3RlZF9tZXNzYWdlJywgbS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobS5IYXNGaWVsZCgnb25lb2Zfc3RyaW5nJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKG0uSGFzRmllbGQoJ29uZW9mX25lc3RlZF9tZXNzYWdlJykpCisKKyAgICBtLm9uZW9mX2J5dGVzID0gYidiYicKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdvbmVvZl9ieXRlcycsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX25lc3RlZF9tZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKG0uSGFzRmllbGQoJ29uZW9mX2J5dGVzJykpCisKKyAgZGVmIHRlc3RPbmVvZkNvbXBvc2l0ZUZpZWxkUmVhZEFjY2VzcyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbS5vbmVvZl91aW50MzIgPSAxMQorCisgICAgc2VsZi5lbnN1cmVOZXN0ZWRNZXNzYWdlRXhpc3RzKG0sICdvbmVvZl9uZXN0ZWRfbWVzc2FnZScpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnb25lb2ZfdWludDMyJywgbS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTEsIG0ub25lb2ZfdWludDMyKQorCisgIGRlZiB0ZXN0T25lb2ZXaGljaE9uZW9mKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydElzKE5vbmUsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKyAgICBpZiBtZXNzYWdlX21vZHVsZSBpcyB1bml0dGVzdF9wYjI6CisgICAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX2ZpZWxkJykpCisKKyAgICBtLm9uZW9mX3VpbnQzMiA9IDExCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnb25lb2ZfdWludDMyJywgbS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorICAgIGlmIG1lc3NhZ2VfbW9kdWxlIGlzIHVuaXR0ZXN0X3BiMjoKKyAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShtLkhhc0ZpZWxkKCdvbmVvZl9maWVsZCcpKQorCisgICAgbS5vbmVvZl9ieXRlcyA9IGInYmInCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnb25lb2ZfYnl0ZXMnLCBtLldoaWNoT25lb2YoJ29uZW9mX2ZpZWxkJykpCisKKyAgICBtLkNsZWFyRmllbGQoJ29uZW9mX2J5dGVzJykKKyAgICBzZWxmLmFzc2VydElzKE5vbmUsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKyAgICBpZiBtZXNzYWdlX21vZHVsZSBpcyB1bml0dGVzdF9wYjI6CisgICAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX2ZpZWxkJykpCisKKyAgZGVmIHRlc3RPbmVvZkNsZWFyRmllbGQoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG0ub25lb2ZfdWludDMyID0gMTEKKyAgICBtLkNsZWFyRmllbGQoJ29uZW9mX2ZpZWxkJykKKyAgICBpZiBtZXNzYWdlX21vZHVsZSBpcyB1bml0dGVzdF9wYjI6CisgICAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX2ZpZWxkJykpCisgICAgc2VsZi5hc3NlcnRGYWxzZShtLkhhc0ZpZWxkKCdvbmVvZl91aW50MzInKSkKKyAgICBzZWxmLmFzc2VydElzKE5vbmUsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKworICBkZWYgdGVzdE9uZW9mQ2xlYXJTZXRGaWVsZChzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbS5vbmVvZl91aW50MzIgPSAxMQorICAgIG0uQ2xlYXJGaWVsZCgnb25lb2ZfdWludDMyJykKKyAgICBpZiBtZXNzYWdlX21vZHVsZSBpcyB1bml0dGVzdF9wYjI6CisgICAgICBzZWxmLmFzc2VydEZhbHNlKG0uSGFzRmllbGQoJ29uZW9mX2ZpZWxkJykpCisgICAgc2VsZi5hc3NlcnRGYWxzZShtLkhhc0ZpZWxkKCdvbmVvZl91aW50MzInKSkKKyAgICBzZWxmLmFzc2VydElzKE5vbmUsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKworICBkZWYgdGVzdE9uZW9mQ2xlYXJVbnNldEZpZWxkKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtLm9uZW9mX3VpbnQzMiA9IDExCisgICAgc2VsZi5lbnN1cmVOZXN0ZWRNZXNzYWdlRXhpc3RzKG0sICdvbmVvZl9uZXN0ZWRfbWVzc2FnZScpCisgICAgbS5DbGVhckZpZWxkKCdvbmVvZl9uZXN0ZWRfbWVzc2FnZScpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMSwgbS5vbmVvZl91aW50MzIpCisgICAgaWYgbWVzc2FnZV9tb2R1bGUgaXMgdW5pdHRlc3RfcGIyOgorICAgICAgc2VsZi5hc3NlcnRUcnVlKG0uSGFzRmllbGQoJ29uZW9mX2ZpZWxkJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKG0uSGFzRmllbGQoJ29uZW9mX3VpbnQzMicpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX3VpbnQzMicsIG0uV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKworICBkZWYgdGVzdE9uZW9mRGVzZXJpYWxpemUoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG0ub25lb2ZfdWludDMyID0gMTEKKyAgICBtMiA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbTIuUGFyc2VGcm9tU3RyaW5nKG0uU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdvbmVvZl91aW50MzInLCBtMi5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorCisgIGRlZiB0ZXN0T25lb2ZDb3B5RnJvbShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbS5vbmVvZl91aW50MzIgPSAxMQorICAgIG0yID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtMi5Db3B5RnJvbShtKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX3VpbnQzMicsIG0yLldoaWNoT25lb2YoJ29uZW9mX2ZpZWxkJykpCisKKyAgZGVmIHRlc3RPbmVvZk5lc3RlZE1lcmdlRnJvbShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLk5lc3RlZFRlc3RBbGxUeXBlcygpCisgICAgbS5wYXlsb2FkLm9uZW9mX3VpbnQzMiA9IDExCisgICAgbTIgPSBtZXNzYWdlX21vZHVsZS5OZXN0ZWRUZXN0QWxsVHlwZXMoKQorICAgIG0yLnBheWxvYWQub25lb2ZfYnl0ZXMgPSBiJ2JiJworICAgIG0yLmNoaWxkLnBheWxvYWQub25lb2ZfYnl0ZXMgPSBiJ2JiJworICAgIG0yLk1lcmdlRnJvbShtKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX3VpbnQzMicsIG0yLnBheWxvYWQuV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdvbmVvZl9ieXRlcycsIG0yLmNoaWxkLnBheWxvYWQuV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKworICBkZWYgdGVzdE9uZW9mTWVzc2FnZU1lcmdlRnJvbShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLk5lc3RlZFRlc3RBbGxUeXBlcygpCisgICAgbS5wYXlsb2FkLm9uZW9mX25lc3RlZF9tZXNzYWdlLmJiID0gMTEKKyAgICBtLmNoaWxkLnBheWxvYWQub25lb2ZfbmVzdGVkX21lc3NhZ2UuYmIgPSAxMgorICAgIG0yID0gbWVzc2FnZV9tb2R1bGUuTmVzdGVkVGVzdEFsbFR5cGVzKCkKKyAgICBtMi5wYXlsb2FkLm9uZW9mX3VpbnQzMiA9IDEzCisgICAgbTIuTWVyZ2VGcm9tKG0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnb25lb2ZfbmVzdGVkX21lc3NhZ2UnLAorICAgICAgICAgICAgICAgICAgICAgbTIucGF5bG9hZC5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX25lc3RlZF9tZXNzYWdlJywKKyAgICAgICAgICAgICAgICAgICAgIG0yLmNoaWxkLnBheWxvYWQuV2hpY2hPbmVvZignb25lb2ZfZmllbGQnKSkKKworICBkZWYgdGVzdE9uZW9mTmVzdGVkTWVzc2FnZUluaXQoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoCisgICAgICAgIG9uZW9mX25lc3RlZF9tZXNzYWdlPW1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnb25lb2ZfbmVzdGVkX21lc3NhZ2UnLCBtLldoaWNoT25lb2YoJ29uZW9mX2ZpZWxkJykpCisKKyAgZGVmIHRlc3RPbmVvZkNsZWFyKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtLm9uZW9mX3VpbnQzMiA9IDExCisgICAgbS5DbGVhcigpCisgICAgc2VsZi5hc3NlcnRJc05vbmUobS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorICAgIG0ub25lb2ZfYnl0ZXMgPSBiJ2JiJworICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29uZW9mX2J5dGVzJywgbS5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorCisgIGRlZiB0ZXN0QXNzaWduQnl0ZVN0cmluZ1RvVW5pY29kZUZpZWxkKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICAiIiJBc3NpZ25pbmcgYSBieXRlIHN0cmluZyB0byBhIHN0cmluZyBmaWVsZCBzaG91bGQgcmVzdWx0CisgICAgaW4gdGhlIHZhbHVlIGJlaW5nIGNvbnZlcnRlZCB0byBhIFVuaWNvZGUgc3RyaW5nLiIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG0ub3B0aW9uYWxfc3RyaW5nID0gc3RyKCcnKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc2luc3RhbmNlKG0ub3B0aW9uYWxfc3RyaW5nLCB1bmljb2RlKSkKKworIyBUT0RPKGhhYmVybWFuKTogd2h5IGFyZSB0aGVzZSB0ZXN0cyBHb29nbGUtaW50ZXJuYWwgb25seT8KKworICBkZWYgdGVzdExvbmdWYWx1ZWRTbGljZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiSXQgc2hvdWxkIGJlIHBvc3NpYmxlIHRvIHVzZSBsb25nLXZhbHVlZCBpbmRpY2llcyBpbiBzbGljZXMKKworICAgIFRoaXMgZGlkbid0IHVzZWQgdG8gd29yayBpbiB0aGUgdjIgQysrIGltcGxlbWVudGF0aW9uLgorICAgICIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorCisgICAgIyBSZXBlYXRlZCBzY2FsYXIKKyAgICBtLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxKQorICAgIHNsID0gbS5yZXBlYXRlZF9pbnQzMltsb25nKDApOmxvbmcobGVuKG0ucmVwZWF0ZWRfaW50MzIpKV0KKyAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihtLnJlcGVhdGVkX2ludDMyKSwgbGVuKHNsKSkKKworICAgICMgUmVwZWF0ZWQgY29tcG9zaXRlCisgICAgbS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDMKKyAgICBzbCA9IG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbbG9uZygwKTpsb25nKGxlbihtLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKSldCisgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4obS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSksIGxlbihzbCkpCisKKyAgZGVmIHRlc3RFeHRlbmRTaG91bGROb3RTd2FsbG93RXhjZXB0aW9ucyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiVGhpcyBkaWRuJ3QgdXNlIHRvIHdvcmsgaW4gdGhlIHYyIEMrKyBpbXBsZW1lbnRhdGlvbi4iIiIKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKE5hbWVFcnJvcikgYXMgXzoKKyAgICAgIG0ucmVwZWF0ZWRfaW50MzIuZXh0ZW5kKGEgZm9yIGkgaW4gcmFuZ2UoMTApKSAgIyBweWxpbnQ6IGRpc2FibGU9dW5kZWZpbmVkLXZhcmlhYmxlCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhOYW1lRXJyb3IpIGFzIF86CisgICAgICBtLnJlcGVhdGVkX25lc3RlZF9lbnVtLmV4dGVuZCgKKyAgICAgICAgICBhIGZvciBpIGluIHJhbmdlKDEwKSkgICMgcHlsaW50OiBkaXNhYmxlPXVuZGVmaW5lZC12YXJpYWJsZQorCisgIEZBTFNZX1ZBTFVFUyA9IFtOb25lLCBGYWxzZSwgMCwgMC4wLCBiJycsIHUnJywgYnl0ZWFycmF5KCksIFtdLCB7fSwgc2V0KCldCisKKyAgZGVmIHRlc3RFeHRlbmRJbnQzMldpdGhOb3RoaW5nKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICAiIiJUZXN0IG5vLW9wcyBleHRlbmRpbmcgcmVwZWF0ZWQgaW50MzIgZmllbGRzLiIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbXSwgbS5yZXBlYXRlZF9pbnQzMikKKworICAgICMgVE9ETyhwdHVja2VyKTogRGVwcmVjYXRlIHRoaXMgYmVoYXZpb3IuIGIvMTg0MTM4NjIKKyAgICBmb3IgZmFsc3lfdmFsdWUgaW4gTWVzc2FnZVRlc3QuRkFMU1lfVkFMVUVTOgorICAgICAgbS5yZXBlYXRlZF9pbnQzMi5leHRlbmQoZmFsc3lfdmFsdWUpCisgICAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfaW50MzIpCisKKyAgICBtLnJlcGVhdGVkX2ludDMyLmV4dGVuZChbXSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfaW50MzIpCisKKyAgZGVmIHRlc3RFeHRlbmRGbG9hdFdpdGhOb3RoaW5nKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICAiIiJUZXN0IG5vLW9wcyBleHRlbmRpbmcgcmVwZWF0ZWQgZmxvYXQgZmllbGRzLiIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbXSwgbS5yZXBlYXRlZF9mbG9hdCkKKworICAgICMgVE9ETyhwdHVja2VyKTogRGVwcmVjYXRlIHRoaXMgYmVoYXZpb3IuIGIvMTg0MTM4NjIKKyAgICBmb3IgZmFsc3lfdmFsdWUgaW4gTWVzc2FnZVRlc3QuRkFMU1lfVkFMVUVTOgorICAgICAgbS5yZXBlYXRlZF9mbG9hdC5leHRlbmQoZmFsc3lfdmFsdWUpCisgICAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfZmxvYXQpCisKKyAgICBtLnJlcGVhdGVkX2Zsb2F0LmV4dGVuZChbXSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfZmxvYXQpCisKKyAgZGVmIHRlc3RFeHRlbmRTdHJpbmdXaXRoTm90aGluZyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiVGVzdCBuby1vcHMgZXh0ZW5kaW5nIHJlcGVhdGVkIHN0cmluZyBmaWVsZHMuIiIiCisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFtdLCBtLnJlcGVhdGVkX3N0cmluZykKKworICAgICMgVE9ETyhwdHVja2VyKTogRGVwcmVjYXRlIHRoaXMgYmVoYXZpb3IuIGIvMTg0MTM4NjIKKyAgICBmb3IgZmFsc3lfdmFsdWUgaW4gTWVzc2FnZVRlc3QuRkFMU1lfVkFMVUVTOgorICAgICAgbS5yZXBlYXRlZF9zdHJpbmcuZXh0ZW5kKGZhbHN5X3ZhbHVlKQorICAgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFtdLCBtLnJlcGVhdGVkX3N0cmluZykKKworICAgIG0ucmVwZWF0ZWRfc3RyaW5nLmV4dGVuZChbXSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfc3RyaW5nKQorCisgIGRlZiB0ZXN0RXh0ZW5kSW50MzJXaXRoUHl0aG9uTGlzdChzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiVGVzdCBleHRlbmRpbmcgcmVwZWF0ZWQgaW50MzIgZmllbGRzIHdpdGggcHl0aG9uIGxpc3RzLiIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbXSwgbS5yZXBlYXRlZF9pbnQzMikKKyAgICBtLnJlcGVhdGVkX2ludDMyLmV4dGVuZChbMF0pCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswXSwgbS5yZXBlYXRlZF9pbnQzMikKKyAgICBtLnJlcGVhdGVkX2ludDMyLmV4dGVuZChbMSwgMl0pCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswLCAxLCAyXSwgbS5yZXBlYXRlZF9pbnQzMikKKyAgICBtLnJlcGVhdGVkX2ludDMyLmV4dGVuZChbMywgNF0pCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswLCAxLCAyLCAzLCA0XSwgbS5yZXBlYXRlZF9pbnQzMikKKworICBkZWYgdGVzdEV4dGVuZEZsb2F0V2l0aFB5dGhvbkxpc3Qoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgICIiIlRlc3QgZXh0ZW5kaW5nIHJlcGVhdGVkIGZsb2F0IGZpZWxkcyB3aXRoIHB5dGhvbiBsaXN0cy4iIiIKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfZmxvYXQpCisgICAgbS5yZXBlYXRlZF9mbG9hdC5leHRlbmQoWzAuMF0pCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswLjBdLCBtLnJlcGVhdGVkX2Zsb2F0KQorICAgIG0ucmVwZWF0ZWRfZmxvYXQuZXh0ZW5kKFsxLjAsIDIuMF0pCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswLjAsIDEuMCwgMi4wXSwgbS5yZXBlYXRlZF9mbG9hdCkKKyAgICBtLnJlcGVhdGVkX2Zsb2F0LmV4dGVuZChbMy4wLCA0LjBdKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbMC4wLCAxLjAsIDIuMCwgMy4wLCA0LjBdLCBtLnJlcGVhdGVkX2Zsb2F0KQorCisgIGRlZiB0ZXN0RXh0ZW5kU3RyaW5nV2l0aFB5dGhvbkxpc3Qoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgICIiIlRlc3QgZXh0ZW5kaW5nIHJlcGVhdGVkIHN0cmluZyBmaWVsZHMgd2l0aCBweXRob24gbGlzdHMuIiIiCisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFtdLCBtLnJlcGVhdGVkX3N0cmluZykKKyAgICBtLnJlcGVhdGVkX3N0cmluZy5leHRlbmQoWycnXSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWycnXSwgbS5yZXBlYXRlZF9zdHJpbmcpCisgICAgbS5yZXBlYXRlZF9zdHJpbmcuZXh0ZW5kKFsnMTEnLCAnMjInXSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWycnLCAnMTEnLCAnMjInXSwgbS5yZXBlYXRlZF9zdHJpbmcpCisgICAgbS5yZXBlYXRlZF9zdHJpbmcuZXh0ZW5kKFsnMzMnLCAnNDQnXSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWycnLCAnMTEnLCAnMjInLCAnMzMnLCAnNDQnXSwgbS5yZXBlYXRlZF9zdHJpbmcpCisKKyAgZGVmIHRlc3RFeHRlbmRTdHJpbmdXaXRoU3RyaW5nKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICAiIiJUZXN0IGV4dGVuZGluZyByZXBlYXRlZCBzdHJpbmcgZmllbGRzIHdpdGggY2hhcmFjdGVycyBmcm9tIGEgc3RyaW5nLiIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbXSwgbS5yZXBlYXRlZF9zdHJpbmcpCisgICAgbS5yZXBlYXRlZF9zdHJpbmcuZXh0ZW5kKCdhYmMnKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbJ2EnLCAnYicsICdjJ10sIG0ucmVwZWF0ZWRfc3RyaW5nKQorCisgIGNsYXNzIFRlc3RJdGVyYWJsZShvYmplY3QpOgorICAgICIiIlRoaXMgaXRlcmFibGUgb2JqZWN0IG1pbWljcyB0aGUgYmVoYXZpb3Igb2YgbnVtcHkuYXJyYXkuCisKKyAgICBfX25vbnplcm9fXyBmYWlscyBmb3IgbGVuZ3RoID4gMSwgYW5kIHJldHVybnMgYm9vbChpdGVtWzBdKSBmb3IgbGVuZ3RoID09IDEuCisKKyAgICAiIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCB2YWx1ZXM9Tm9uZSk6CisgICAgICBzZWxmLl9saXN0ID0gdmFsdWVzIG9yIFtdCisKKyAgICBkZWYgX19ub256ZXJvX18oc2VsZik6CisgICAgICBzaXplID0gbGVuKHNlbGYuX2xpc3QpCisgICAgICBpZiBzaXplID09IDA6CisgICAgICAgIHJldHVybiBGYWxzZQorICAgICAgaWYgc2l6ZSA9PSAxOgorICAgICAgICByZXR1cm4gYm9vbChzZWxmLl9saXN0WzBdKQorICAgICAgcmFpc2UgVmFsdWVFcnJvcignVHJ1dGggdmFsdWUgaXMgYW1iaWd1b3VzLicpCisKKyAgICBkZWYgX19sZW5fXyhzZWxmKToKKyAgICAgIHJldHVybiBsZW4oc2VsZi5fbGlzdCkKKworICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKKyAgICAgIHJldHVybiBzZWxmLl9saXN0Ll9faXRlcl9fKCkKKworICBkZWYgdGVzdEV4dGVuZEludDMyV2l0aEl0ZXJhYmxlKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICAiIiJUZXN0IGV4dGVuZGluZyByZXBlYXRlZCBpbnQzMiBmaWVsZHMgd2l0aCBpdGVyYWJsZS4iIiIKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfaW50MzIpCisgICAgbS5yZXBlYXRlZF9pbnQzMi5leHRlbmQoTWVzc2FnZVRlc3QuVGVzdEl0ZXJhYmxlKFtdKSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoW10sIG0ucmVwZWF0ZWRfaW50MzIpCisgICAgbS5yZXBlYXRlZF9pbnQzMi5leHRlbmQoTWVzc2FnZVRlc3QuVGVzdEl0ZXJhYmxlKFswXSkpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswXSwgbS5yZXBlYXRlZF9pbnQzMikKKyAgICBtLnJlcGVhdGVkX2ludDMyLmV4dGVuZChNZXNzYWdlVGVzdC5UZXN0SXRlcmFibGUoWzEsIDJdKSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWzAsIDEsIDJdLCBtLnJlcGVhdGVkX2ludDMyKQorICAgIG0ucmVwZWF0ZWRfaW50MzIuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbMywgNF0pKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbMCwgMSwgMiwgMywgNF0sIG0ucmVwZWF0ZWRfaW50MzIpCisKKyAgZGVmIHRlc3RFeHRlbmRGbG9hdFdpdGhJdGVyYWJsZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiVGVzdCBleHRlbmRpbmcgcmVwZWF0ZWQgZmxvYXQgZmllbGRzIHdpdGggaXRlcmFibGUuIiIiCisgICAgbSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFtdLCBtLnJlcGVhdGVkX2Zsb2F0KQorICAgIG0ucmVwZWF0ZWRfZmxvYXQuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbXSkpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFtdLCBtLnJlcGVhdGVkX2Zsb2F0KQorICAgIG0ucmVwZWF0ZWRfZmxvYXQuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbMC4wXSkpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFswLjBdLCBtLnJlcGVhdGVkX2Zsb2F0KQorICAgIG0ucmVwZWF0ZWRfZmxvYXQuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbMS4wLCAyLjBdKSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWzAuMCwgMS4wLCAyLjBdLCBtLnJlcGVhdGVkX2Zsb2F0KQorICAgIG0ucmVwZWF0ZWRfZmxvYXQuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbMy4wLCA0LjBdKSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWzAuMCwgMS4wLCAyLjAsIDMuMCwgNC4wXSwgbS5yZXBlYXRlZF9mbG9hdCkKKworICBkZWYgdGVzdEV4dGVuZFN0cmluZ1dpdGhJdGVyYWJsZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgIiIiVGVzdCBleHRlbmRpbmcgcmVwZWF0ZWQgc3RyaW5nIGZpZWxkcyB3aXRoIGl0ZXJhYmxlLiIiIgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbXSwgbS5yZXBlYXRlZF9zdHJpbmcpCisgICAgbS5yZXBlYXRlZF9zdHJpbmcuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbXSkpCisgICAgc2VsZi5hc3NlcnRTZXF1ZW5jZUVxdWFsKFtdLCBtLnJlcGVhdGVkX3N0cmluZykKKyAgICBtLnJlcGVhdGVkX3N0cmluZy5leHRlbmQoTWVzc2FnZVRlc3QuVGVzdEl0ZXJhYmxlKFsnJ10pKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbJyddLCBtLnJlcGVhdGVkX3N0cmluZykKKyAgICBtLnJlcGVhdGVkX3N0cmluZy5leHRlbmQoTWVzc2FnZVRlc3QuVGVzdEl0ZXJhYmxlKFsnMScsICcyJ10pKQorICAgIHNlbGYuYXNzZXJ0U2VxdWVuY2VFcXVhbChbJycsICcxJywgJzInXSwgbS5yZXBlYXRlZF9zdHJpbmcpCisgICAgbS5yZXBlYXRlZF9zdHJpbmcuZXh0ZW5kKE1lc3NhZ2VUZXN0LlRlc3RJdGVyYWJsZShbJzMnLCAnNCddKSkKKyAgICBzZWxmLmFzc2VydFNlcXVlbmNlRXF1YWwoWycnLCAnMScsICcyJywgJzMnLCAnNCddLCBtLnJlcGVhdGVkX3N0cmluZykKKworICBkZWYgdGVzdFBpY2tsZVJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICAjIFRPRE8odGliZWxsKTogVGhlIHB1cmUtUHl0aG9uIGltcGxlbWVudGF0aW9uIHN1cHBvcnQgcGlja2xpbmcgb2YKKyAgICAjICAgc2NhbGFyIGNvbnRhaW5lcnMgaW4gKnNvbWUqIGNhc2VzLiBGb3Igbm93IHRoZSBjcHAyIHZlcnNpb24KKyAgICAjICAgdGhyb3dzIGFuIGV4Y2VwdGlvbiB0byBhdm9pZCBhIHNlZ2ZhdWx0LiBJbnZlc3RpZ2F0ZSBpZiB3ZQorICAgICMgICB3YW50IHRvIHN1cHBvcnQgcGlja2xpbmcgb2YgdGhlc2UgZmllbGRzLgorICAgICMKKyAgICAjIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZTogaHR0cHM6Ly9iMi5jb3JwLmdvb2dsZS5jb20vdS8wL2lzc3Vlcy8xODY3Nzg5NworICAgIGlmIChhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpICE9ICdjcHAnIG9yCisgICAgICAgIGFwaV9pbXBsZW1lbnRhdGlvbi5WZXJzaW9uKCkgPT0gMik6CisgICAgICByZXR1cm4KKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHBpY2tsZS5QaWNrbGVFcnJvcikgYXMgXzoKKyAgICAgIHBpY2tsZS5kdW1wcyhtLnJlcGVhdGVkX2ludDMyLCBwaWNrbGUuSElHSEVTVF9QUk9UT0NPTCkKKworCisgIGRlZiB0ZXN0U29ydEVtcHR5UmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgICIiIkV4ZXJjaXNlIGEgc2NlbmFyaW8gdGhhdCBoYXMgbGVkIHRvIHNlZ2ZhdWx0cyBpbiB0aGUgcGFzdC4KKyAgICAiIiIKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLnNvcnQoKQorCisgIGRlZiB0ZXN0SGFzRmllbGRPblJlcGVhdGVkRmllbGQoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgICIiIlVzaW5nIEhhc0ZpZWxkIG9uIGEgcmVwZWF0ZWQgZmllbGQgc2hvdWxkIHJhaXNlIGFuIGV4Y2VwdGlvbi4KKyAgICAiIiIKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpIGFzIF86CisgICAgICBtLkhhc0ZpZWxkKCdyZXBlYXRlZF9pbnQzMicpCisKKyAgZGVmIHRlc3RSZXBlYXRlZFNjYWxhckZpZWxkUG9wKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKEluZGV4RXJyb3IpIGFzIF86CisgICAgICBtLnJlcGVhdGVkX2ludDMyLnBvcCgpCisgICAgbS5yZXBlYXRlZF9pbnQzMi5leHRlbmQocmFuZ2UoNSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0LCBtLnJlcGVhdGVkX2ludDMyLnBvcCgpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbS5yZXBlYXRlZF9pbnQzMi5wb3AoMCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBtLnJlcGVhdGVkX2ludDMyLnBvcCgxKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFsxLCAzXSwgbS5yZXBlYXRlZF9pbnQzMikKKworICBkZWYgdGVzdFJlcGVhdGVkQ29tcG9zaXRlRmllbGRQb3Aoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoSW5kZXhFcnJvcikgYXMgXzoKKyAgICAgIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UucG9wKCkKKyAgICBmb3IgaSBpbiByYW5nZSg1KToKKyAgICAgIG4gPSBtLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgICBuLmJiID0gaQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNCwgbS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5wb3AoKS5iYikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UucG9wKDApLmJiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgbS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5wb3AoMSkuYmIpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMSwgM10sIFtuLmJiIGZvciBuIGluIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VdKQorCisKKyMgQ2xhc3MgdG8gdGVzdCBwcm90bzItb25seSBmZWF0dXJlcyAocmVxdWlyZWQsIGV4dGVuc2lvbnMsIGV0Yy4pCitjbGFzcyBQcm90bzJUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdEZpZWxkUHJlc2VuY2Uoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorCisgICAgc2VsZi5hc3NlcnRGYWxzZShtZXNzYWdlLkhhc0ZpZWxkKCJvcHRpb25hbF9pbnQzMiIpKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfYm9vbCIpKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkKKworICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6CisgICAgICBtZXNzYWdlLkhhc0ZpZWxkKCJmaWVsZF9kb2VzbnRfZXhpc3QiKQorCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKToKKyAgICAgIG1lc3NhZ2UuSGFzRmllbGQoInJlcGVhdGVkX2ludDMyIikKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOgorICAgICAgbWVzc2FnZS5IYXNGaWVsZCgicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoRmFsc2UsIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIpCisKKyAgICAjIEZpZWxkcyBhcmUgc2V0IGV2ZW4gd2hlbiBzZXR0aW5nIHRoZSB2YWx1ZXMgdG8gZGVmYXVsdCB2YWx1ZXMuCisgICAgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiA9IDAKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2Jvb2wgPSBGYWxzZQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIgPSAwCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX2ludDMyIikpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX2Jvb2wiKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkKKworICAgICMgU2V0IHRoZSBmaWVsZHMgdG8gbm9uLWRlZmF1bHQgdmFsdWVzLgorICAgIG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIgPSA1CisgICAgbWVzc2FnZS5vcHRpb25hbF9ib29sID0gVHJ1ZQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIgPSAxNQorCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX2ludDMyIikpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX2Jvb2wiKSkKKyAgICBzZWxmLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkKKworICAgICMgQ2xlYXJpbmcgdGhlIGZpZWxkcyB1bnNldHMgdGhlbSBhbmQgcmVzZXRzIHRoZWlyIHZhbHVlIHRvIGRlZmF1bHQuCisgICAgbWVzc2FnZS5DbGVhckZpZWxkKCJvcHRpb25hbF9pbnQzMiIpCisgICAgbWVzc2FnZS5DbGVhckZpZWxkKCJvcHRpb25hbF9ib29sIikKKyAgICBtZXNzYWdlLkNsZWFyRmllbGQoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIikKKworICAgIHNlbGYuYXNzZXJ0RmFsc2UobWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfaW50MzIiKSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX2Jvb2wiKSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoRmFsc2UsIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIpCisKKyAgIyBUT0RPKHRpYmVsbCk6IFRoZSBDKysgaW1wbGVtZW50YXRpb25zIGFjdHVhbGx5IGFsbG93cyBhc3NpZ25tZW50CisgICMgb2YgdW5rbm93biBlbnVtIHZhbHVlcyB0byAqc2NhbGFyKiBmaWVsZHMgKGJ1dCBub3QgcmVwZWF0ZWQKKyAgIyBmaWVsZHMpLiBPbmNlIGNoZWNrZWQgZW51bSBmaWVsZHMgYmVjb21lcyB0aGUgZGVmYXVsdCBpbiB0aGUKKyAgIyBQeXRob24gaW1wbGVtZW50YXRpb24sIHRoZSBDKysgaW1wbGVtZW50YXRpb24gc2hvdWxkIGZvbGxvdyBzdWl0LgorICBkZWYgdGVzdEFzc2lnbkludmFsaWRFbnVtKHNlbGYpOgorICAgICIiIkl0IHNob3VsZCBub3QgYmUgcG9zc2libGUgdG8gYXNzaWduIGFuIGludmFsaWQgZW51bSBudW1iZXIgdG8gYW4KKyAgICBlbnVtIGZpZWxkLiIiIgorICAgIG0gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKworICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcikgYXMgXzoKKyAgICAgIG0ub3B0aW9uYWxfbmVzdGVkX2VudW0gPSAxMjM0NTY3CisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgbS5yZXBlYXRlZF9uZXN0ZWRfZW51bS5hcHBlbmQsIDEyMzQ1NjcpCisKKyAgZGVmIHRlc3RHb2xkZW5FeHRlbnNpb25zKHNlbGYpOgorICAgIGdvbGRlbl9kYXRhID0gdGVzdF91dGlsLkdvbGRlbkZpbGVEYXRhKCdnb2xkZW5fbWVzc2FnZScpCisgICAgZ29sZGVuX21lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIGdvbGRlbl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhnb2xkZW5fZGF0YSkKKyAgICBhbGxfc2V0ID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRXh0ZW5zaW9ucyhhbGxfc2V0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoYWxsX3NldCwgZ29sZGVuX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChnb2xkZW5fZGF0YSwgZ29sZGVuX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBnb2xkZW5fY29weSA9IGNvcHkuZGVlcGNvcHkoZ29sZGVuX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChnb2xkZW5fZGF0YSwgZ29sZGVuX2NvcHkuU2VyaWFsaXplVG9TdHJpbmcoKSkKKworICBkZWYgdGVzdEdvbGRlblBhY2tlZEV4dGVuc2lvbnMoc2VsZik6CisgICAgZ29sZGVuX2RhdGEgPSB0ZXN0X3V0aWwuR29sZGVuRmlsZURhdGEoJ2dvbGRlbl9wYWNrZWRfZmllbGRzX21lc3NhZ2UnKQorICAgIGdvbGRlbl9tZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RQYWNrZWRFeHRlbnNpb25zKCkKKyAgICBnb2xkZW5fbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZ29sZGVuX2RhdGEpCisgICAgYWxsX3NldCA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkRXh0ZW5zaW9ucygpCisgICAgdGVzdF91dGlsLlNldEFsbFBhY2tlZEV4dGVuc2lvbnMoYWxsX3NldCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGFsbF9zZXQsIGdvbGRlbl9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZ29sZGVuX2RhdGEsIGFsbF9zZXQuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICBnb2xkZW5fY29weSA9IGNvcHkuZGVlcGNvcHkoZ29sZGVuX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChnb2xkZW5fZGF0YSwgZ29sZGVuX2NvcHkuU2VyaWFsaXplVG9TdHJpbmcoKSkKKworICBkZWYgdGVzdFBpY2tsZUluY29tcGxldGVQcm90byhzZWxmKToKKyAgICBnb2xkZW5fbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWQoYT0xKQorICAgIHBpY2tsZWRfbWVzc2FnZSA9IHBpY2tsZS5kdW1wcyhnb2xkZW5fbWVzc2FnZSkKKworICAgIHVucGlja2xlZF9tZXNzYWdlID0gcGlja2xlLmxvYWRzKHBpY2tsZWRfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVucGlja2xlZF9tZXNzYWdlLCBnb2xkZW5fbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVucGlja2xlZF9tZXNzYWdlLmEsIDEpCisgICAgIyBUaGlzIGlzIHN0aWxsIGFuIGluY29tcGxldGUgcHJvdG8gLSBzbyBzZXJpYWxpemluZyBzaG91bGQgZmFpbAorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKG1lc3NhZ2UuRW5jb2RlRXJyb3IsIHVucGlja2xlZF9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKQorCisKKyAgIyBUT0RPKGhhYmVybWFuKTogdGhpcyBpc24ndCByZWFsbHkgYSBwcm90bzItc3BlY2lmaWMgdGVzdCBleGNlcHQgdGhhdCB0aGlzCisgICMgbWVzc2FnZSBoYXMgYSByZXF1aXJlZCBmaWVsZCBpbiBpdC4gIFNob3VsZCBwcm9iYWJseSBiZSBmYWN0b3JlZCBvdXQgc28KKyAgIyB0aGF0IHdlIGNhbiB0ZXN0IHRoZSBvdGhlciBwYXJ0cyB3aXRoIHByb3RvMy4KKyAgZGVmIHRlc3RQYXJzaW5nTWVyZ2Uoc2VsZik6CisgICAgIiIiQ2hlY2sgdGhlIG1lcmdlIGJlaGF2aW9yIHdoZW4gYSByZXF1aXJlZCBvciBvcHRpb25hbCBmaWVsZCBhcHBlYXJzCisgICAgbXVsdGlwbGUgdGltZXMgaW4gdGhlIGlucHV0LiIiIgorICAgIG1lc3NhZ2VzID0gWworICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCksCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKSwKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpIF0KKyAgICBtZXNzYWdlc1swXS5vcHRpb25hbF9pbnQzMiA9IDEKKyAgICBtZXNzYWdlc1sxXS5vcHRpb25hbF9pbnQ2NCA9IDIKKyAgICBtZXNzYWdlc1syXS5vcHRpb25hbF9pbnQzMiA9IDMKKyAgICBtZXNzYWdlc1syXS5vcHRpb25hbF9zdHJpbmcgPSAnaGVsbG8nCisKKyAgICBtZXJnZWRfbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIG1lcmdlZF9tZXNzYWdlLm9wdGlvbmFsX2ludDMyID0gMworICAgIG1lcmdlZF9tZXNzYWdlLm9wdGlvbmFsX2ludDY0ID0gMgorICAgIG1lcmdlZF9tZXNzYWdlLm9wdGlvbmFsX3N0cmluZyA9ICdoZWxsbycKKworICAgIGdlbmVyYXRvciA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yKCkKKyAgICBnZW5lcmF0b3IuZmllbGQxLmV4dGVuZChtZXNzYWdlcykKKyAgICBnZW5lcmF0b3IuZmllbGQyLmV4dGVuZChtZXNzYWdlcykKKyAgICBnZW5lcmF0b3IuZmllbGQzLmV4dGVuZChtZXNzYWdlcykKKyAgICBnZW5lcmF0b3IuZXh0MS5leHRlbmQobWVzc2FnZXMpCisgICAgZ2VuZXJhdG9yLmV4dDIuZXh0ZW5kKG1lc3NhZ2VzKQorICAgIGdlbmVyYXRvci5ncm91cDEuYWRkKCkuZmllbGQxLk1lcmdlRnJvbShtZXNzYWdlc1swXSkKKyAgICBnZW5lcmF0b3IuZ3JvdXAxLmFkZCgpLmZpZWxkMS5NZXJnZUZyb20obWVzc2FnZXNbMV0pCisgICAgZ2VuZXJhdG9yLmdyb3VwMS5hZGQoKS5maWVsZDEuTWVyZ2VGcm9tKG1lc3NhZ2VzWzJdKQorICAgIGdlbmVyYXRvci5ncm91cDIuYWRkKCkuZmllbGQxLk1lcmdlRnJvbShtZXNzYWdlc1swXSkKKyAgICBnZW5lcmF0b3IuZ3JvdXAyLmFkZCgpLmZpZWxkMS5NZXJnZUZyb20obWVzc2FnZXNbMV0pCisgICAgZ2VuZXJhdG9yLmdyb3VwMi5hZGQoKS5maWVsZDEuTWVyZ2VGcm9tKG1lc3NhZ2VzWzJdKQorCisgICAgZGF0YSA9IGdlbmVyYXRvci5TZXJpYWxpemVUb1N0cmluZygpCisgICAgcGFyc2luZ19tZXJnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFyc2luZ01lcmdlKCkKKyAgICBwYXJzaW5nX21lcmdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKQorCisgICAgIyBSZXF1aXJlZCBhbmQgb3B0aW9uYWwgZmllbGRzIHNob3VsZCBiZSBtZXJnZWQuCisgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzaW5nX21lcmdlLnJlcXVpcmVkX2FsbF90eXBlcywgbWVyZ2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzaW5nX21lcmdlLm9wdGlvbmFsX2FsbF90eXBlcywgbWVyZ2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzaW5nX21lcmdlLm9wdGlvbmFsZ3JvdXAub3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzLAorICAgICAgICAgICAgICAgICAgICAgbWVyZ2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzaW5nX21lcmdlLkV4dGVuc2lvbnNbCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdFBhcnNpbmdNZXJnZS5vcHRpb25hbF9leHRdLAorICAgICAgICAgICAgICAgICAgICAgbWVyZ2VkX21lc3NhZ2UpCisKKyAgICAjIFJlcGVhdGVkIGZpZWxkcyBzaG91bGQgbm90IGJlIG1lcmdlZC4KKyAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihwYXJzaW5nX21lcmdlLnJlcGVhdGVkX2FsbF90eXBlcyksIDMpCisgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocGFyc2luZ19tZXJnZS5yZXBlYXRlZGdyb3VwKSwgMykKKyAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihwYXJzaW5nX21lcmdlLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0UGFyc2luZ01lcmdlLnJlcGVhdGVkX2V4dF0pLCAzKQorCisKKyMgQ2xhc3MgdG8gdGVzdCBwcm90bzMtb25seSBmZWF0dXJlcy9iZWhhdmlvciAodXBkYXRlZCBmaWVsZCBwcmVzZW5jZSAmIGVudW1zKQorY2xhc3MgUHJvdG8zVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3RGaWVsZFByZXNlbmNlKHNlbGYpOgorICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wcm90bzNfYXJlbmFfcGIyLlRlc3RBbGxUeXBlcygpCisKKyAgICAjIFdlIGNhbid0IHRlc3QgcHJlc2VuY2Ugb2Ygbm9uLXJlcGVhdGVkLCBub24tc3VibWVzc2FnZSBmaWVsZHMuCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKToKKyAgICAgIG1lc3NhZ2UuSGFzRmllbGQoIm9wdGlvbmFsX2ludDMyIikKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOgorICAgICAgbWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfZmxvYXQiKQorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6CisgICAgICBtZXNzYWdlLkhhc0ZpZWxkKCJvcHRpb25hbF9zdHJpbmciKQorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6CisgICAgICBtZXNzYWdlLkhhc0ZpZWxkKCJvcHRpb25hbF9ib29sIikKKworICAgICMgQnV0IHdlIGNhbiBzdGlsbCB0ZXN0IHByZXNlbmNlIG9mIHN1Ym1lc3NhZ2UgZmllbGRzLgorICAgIHNlbGYuYXNzZXJ0RmFsc2UobWVzc2FnZS5IYXNGaWVsZCgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkKKworICAgICMgQXMgd2l0aCBwcm90bzIsIHdlIGNhbid0IHRlc3QgcHJlc2VuY2Ugb2YgZmllbGRzIHRoYXQgZG9uJ3QgZXhpc3QsIG9yCisgICAgIyByZXBlYXRlZCBmaWVsZHMuCisgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKToKKyAgICAgIG1lc3NhZ2UuSGFzRmllbGQoImZpZWxkX2RvZXNudF9leGlzdCIpCisKKyAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOgorICAgICAgbWVzc2FnZS5IYXNGaWVsZCgicmVwZWF0ZWRfaW50MzIiKQorICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6CisgICAgICBtZXNzYWdlLkhhc0ZpZWxkKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpCisKKyAgICAjIEZpZWxkcyBzaG91bGQgZGVmYXVsdCB0byB0aGVpciB0eXBlLXNwZWNpZmljIGRlZmF1bHQuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbWVzc2FnZS5vcHRpb25hbF9mbG9hdCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCIiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZykKKyAgICBzZWxmLmFzc2VydEVxdWFsKEZhbHNlLCBtZXNzYWdlLm9wdGlvbmFsX2Jvb2wpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiKQorCisgICAgIyBTZXR0aW5nIGEgc3VibWVzc2FnZSBzaG91bGQgc3RpbGwgcmV0dXJuIHByb3BlciBwcmVzZW5jZSBpbmZvcm1hdGlvbi4KKyAgICBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiID0gMAorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKQorCisgICAgIyBTZXQgdGhlIGZpZWxkcyB0byBub24tZGVmYXVsdCB2YWx1ZXMuCisgICAgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiA9IDUKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ID0gMS4xCisgICAgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmcgPSAiYWJjIgorICAgIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCA9IFRydWUKKyAgICBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiID0gMTUKKworICAgICMgQ2xlYXJpbmcgdGhlIGZpZWxkcyB1bnNldHMgdGhlbSBhbmQgcmVzZXRzIHRoZWlyIHZhbHVlIHRvIGRlZmF1bHQuCisgICAgbWVzc2FnZS5DbGVhckZpZWxkKCJvcHRpb25hbF9pbnQzMiIpCisgICAgbWVzc2FnZS5DbGVhckZpZWxkKCJvcHRpb25hbF9mbG9hdCIpCisgICAgbWVzc2FnZS5DbGVhckZpZWxkKCJvcHRpb25hbF9zdHJpbmciKQorICAgIG1lc3NhZ2UuQ2xlYXJGaWVsZCgib3B0aW9uYWxfYm9vbCIpCisgICAgbWVzc2FnZS5DbGVhckZpZWxkKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoIiIsIG1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoRmFsc2UsIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIpCisKKyAgZGVmIHRlc3RBc3NpZ25Vbmtub3duRW51bShzZWxmKToKKyAgICAiIiJBc3NpZ25pbmcgYW4gdW5rbm93biBlbnVtIHZhbHVlIGlzIGFsbG93ZWQgYW5kIHByZXNlcnZlcyB0aGUgdmFsdWUuIiIiCisgICAgbSA9IHVuaXR0ZXN0X3Byb3RvM19hcmVuYV9wYjIuVGVzdEFsbFR5cGVzKCkKKworICAgIG0ub3B0aW9uYWxfbmVzdGVkX2VudW0gPSAxMjM0NTY3CisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMjM0NTY3LCBtLm9wdGlvbmFsX25lc3RlZF9lbnVtKQorICAgIG0ucmVwZWF0ZWRfbmVzdGVkX2VudW0uYXBwZW5kKDIyMzM0NDU1KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMjIzMzQ0NTUsIG0ucmVwZWF0ZWRfbmVzdGVkX2VudW1bMF0pCisgICAgIyBBc3NpZ25tZW50IGlzIGEgZGlmZmVyZW50IGNvZGUgcGF0aCB0aGFuIGFwcGVuZCBmb3IgdGhlIEMrKyBpbXBsLgorICAgIG0ucmVwZWF0ZWRfbmVzdGVkX2VudW1bMF0gPSA3NjU0MzIxCisgICAgc2VsZi5hc3NlcnRFcXVhbCg3NjU0MzIxLCBtLnJlcGVhdGVkX25lc3RlZF9lbnVtWzBdKQorICAgIHNlcmlhbGl6ZWQgPSBtLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICAgIG0yID0gdW5pdHRlc3RfcHJvdG8zX2FyZW5hX3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIG0yLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTIzNDU2NywgbTIub3B0aW9uYWxfbmVzdGVkX2VudW0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCg3NjU0MzIxLCBtMi5yZXBlYXRlZF9uZXN0ZWRfZW51bVswXSkKKworCitjbGFzcyBWYWxpZFR5cGVOYW1lc1Rlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiBhc3NlcnRJbXBvcnRGcm9tTmFtZShzZWxmLCBtc2csIGJhc2VfbmFtZSk6CisgICAgIyBQYXJzZSA8dHlwZSAnbW9kdWxlLmNsYXNzX25hbWUnPiB0byBleHRyYSAnc29tZS5uYW1lJyBhcyBhIHN0cmluZy4KKyAgICB0cF9uYW1lID0gc3RyKHR5cGUobXNnKSkuc3BsaXQoIiciKVsxXQorICAgIHZhbGlkX25hbWVzID0gKCdSZXBlYXRlZCVzQ29udGFpbmVyJyAlIGJhc2VfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAnUmVwZWF0ZWQlc0ZpZWxkQ29udGFpbmVyJyAlIGJhc2VfbmFtZSkKKyAgICBzZWxmLmFzc2VydFRydWUoYW55KHRwX25hbWUuZW5kc3dpdGgodikgZm9yIHYgaW4gdmFsaWRfbmFtZXMpLAorICAgICAgICAgICAgICAgICAgICAnJXIgZG9lcyBlbmQgd2l0aCBhbnkgb2YgJXInICUgKHRwX25hbWUsIHZhbGlkX25hbWVzKSkKKworICAgIHBhcnRzID0gdHBfbmFtZS5zcGxpdCgnLicpCisgICAgY2xhc3NfbmFtZSA9IHBhcnRzWy0xXQorICAgIG1vZHVsZV9uYW1lID0gJy4nLmpvaW4ocGFydHNbOi0xXSkKKyAgICBfX2ltcG9ydF9fKG1vZHVsZV9uYW1lLCBmcm9tbGlzdD1bY2xhc3NfbmFtZV0pCisKKyAgZGVmIHRlc3RUeXBlTmFtZXNDYW5CZUltcG9ydGVkKHNlbGYpOgorICAgICMgSWYgaW1wb3J0IGRvZXNuJ3Qgd29yaywgcGlja2xpbmcgd29uJ3Qgd29yayBlaXRoZXIuCisgICAgcGIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEltcG9ydEZyb21OYW1lKHBiLnJlcGVhdGVkX2ludDMyLCAnU2NhbGFyJykKKyAgICBzZWxmLmFzc2VydEltcG9ydEZyb21OYW1lKHBiLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLCAnQ29tcG9zaXRlJykKKworCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWlzc2luZ19lbnVtX3ZhbHVlcy5wcm90byBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbWlzc2luZ19lbnVtX3ZhbHVlcy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjFmYzVlCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9taXNzaW5nX2VudW1fdmFsdWVzLnByb3RvCkBAIC0wLDAgKzEsNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsOworCittZXNzYWdlIFRlc3RFbnVtVmFsdWVzIHsKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBaRVJPID0gMDsKKyAgICBPTkUgPSAxOworICB9CisgIG9wdGlvbmFsIE5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAxOworICByZXBlYXRlZCBOZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjsKKyAgcmVwZWF0ZWQgTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAzIFtwYWNrZWQgPSB0cnVlXTsKK30KKworbWVzc2FnZSBUZXN0TWlzc2luZ0VudW1WYWx1ZXMgeworICBlbnVtIE5lc3RlZEVudW0geworICAgIFRXTyA9IDI7CisgIH0KKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDE7CisgIHJlcGVhdGVkIE5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyOworICByZXBlYXRlZCBOZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDMgW3BhY2tlZCA9IHRydWVdOworfQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tb3JlX2V4dGVuc2lvbnMucHJvdG8gYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfZXh0ZW5zaW9ucy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OGYxNDY3Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9tb3JlX2V4dGVuc2lvbnMucHJvdG8KQEAgLTAsMCArMSw1OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogcm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbikKKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLmludGVybmFsOworCisKK21lc3NhZ2UgVG9wTGV2ZWxNZXNzYWdlIHsKKyAgb3B0aW9uYWwgRXh0ZW5kZWRNZXNzYWdlIHN1Ym1lc3NhZ2UgPSAxOworfQorCisKK21lc3NhZ2UgRXh0ZW5kZWRNZXNzYWdlIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworCittZXNzYWdlIEZvcmVpZ25NZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgZm9yZWlnbl9tZXNzYWdlX2ludCA9IDE7Cit9CisKKworZXh0ZW5kIEV4dGVuZGVkTWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludF9leHRlbnNpb24gPSAxOworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSBvcHRpb25hbF9tZXNzYWdlX2V4dGVuc2lvbiA9IDI7CisKKyAgcmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50X2V4dGVuc2lvbiA9IDM7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2VfZXh0ZW5zaW9uID0gNDsKK30KZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbW9yZV9leHRlbnNpb25zX2R5bmFtaWMucHJvdG8gYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfZXh0ZW5zaW9uc19keW5hbWljLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExZjg1ZWYKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfZXh0ZW5zaW9uc19keW5hbWljLnByb3RvCkBAIC0wLDAgKzEsNTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGphc29uaEBnb29nbGUuY29tIChKYXNvbiBIc3VlaCkKKy8vCisvLyBUaGlzIGZpbGUgaXMgdXNlZCB0byB0ZXN0IGEgY29ybmVyIGNhc2UgaW4gdGhlIENQUCBpbXBsZW1lbnRhdGlvbiB3aGVyZSB0aGUKKy8vIGdlbmVyYXRlZCBDKysgdHlwZSBpcyBhdmFpbGFibGUgZm9yIHRoZSBleHRlbmRlZSwgYnV0IHRoZSBleHRlbnNpb24gaXMKKy8vIGRlZmluZWQgaW4gYSBmaWxlIHdob3NlIEMrKyB0eXBlIGlzIG5vdCBpbiB0aGUgYmluYXJ5LgorCitzeW50YXggPSAicHJvdG8yIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbW9yZV9leHRlbnNpb25zLnByb3RvIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWw7CisKK21lc3NhZ2UgRHluYW1pY01lc3NhZ2VUeXBlIHsKKyAgb3B0aW9uYWwgaW50MzIgYSA9IDE7Cit9CisKK2V4dGVuZCBFeHRlbmRlZE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBkeW5hbWljX2ludDMyX2V4dGVuc2lvbiA9IDEwMDsKKyAgb3B0aW9uYWwgRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gPSAxMDE7Cit9CmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfbWVzc2FnZXMucHJvdG8gYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfbWVzc2FnZXMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmM2YWI5ZQotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbW9yZV9tZXNzYWdlcy5wcm90bwpAQCAtMCwwICsxLDUyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiByb2JpbnNvbkBnb29nbGUuY29tIChXaWxsIFJvYmluc29uKQorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWw7CisKKy8vIEEgbWVzc2FnZSB3aGVyZSB0YWcgbnVtYmVycyBhcmUgbGlzdGVkIG91dCBvZiBvcmRlciwgdG8gYWxsb3cgdXMgdG8gdGVzdCBvdXIKKy8vIGNhbm9uaWNhbGl6YXRpb24gb2Ygc2VyaWFsaXplZCBvdXRwdXQsIHdoaWNoIHNob3VsZCBhbHdheXMgYmUgaW4gdGFnIG9yZGVyLgorLy8gV2UgYWxzbyBtaXggaW4gc29tZSBleHRlbnNpb25zIGZvciBleHRyYSBmdW4uCittZXNzYWdlIE91dE9mT3JkZXJGaWVsZHMgeworICBvcHRpb25hbCAgIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgICA9ICA1OworICBleHRlbnNpb25zIDQgdG8gNDsKKyAgb3B0aW9uYWwgICB1aW50MzIgb3B0aW9uYWxfdWludDMyICAgPSAgMzsKKyAgZXh0ZW5zaW9ucyAyIHRvIDI7CisgIG9wdGlvbmFsICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7Cit9OworCisKK2V4dGVuZCBPdXRPZk9yZGVyRmllbGRzIHsKKyAgb3B0aW9uYWwgICB1aW50NjQgb3B0aW9uYWxfdWludDY0ICAgPSAgNDsKKyAgb3B0aW9uYWwgICAgaW50NjQgb3B0aW9uYWxfaW50NjQgICAgPSAgMjsKK30KZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvcHJvdG9fYnVpbGRlcl90ZXN0LnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9wcm90b19idWlsZGVyX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc0ZGI3ZQotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvcHJvdG9fYnVpbGRlcl90ZXN0LnB5CkBAIC0wLDAgKzEsNzcgQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJUZXN0cyBmb3IgZ29vZ2xlLnByb3RvYnVmLnByb3RvX2J1aWxkZXIuIiIiCisKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yX3Bvb2wKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBwcm90b19idWlsZGVyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdGV4dF9mb3JtYXQKKworCitjbGFzcyBQcm90b0J1aWxkZXJUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgc2V0VXAoc2VsZik6CisgICAgc2VsZi5fZmllbGRzID0geworICAgICAgICAnZm9vJzogZGVzY3JpcHRvcl9wYjIuRmllbGREZXNjcmlwdG9yUHJvdG8uVFlQRV9JTlQ2NCwKKyAgICAgICAgJ2Jhcic6IGRlc2NyaXB0b3JfcGIyLkZpZWxkRGVzY3JpcHRvclByb3RvLlRZUEVfU1RSSU5HLAorICAgICAgICB9CisKKyAgZGVmIHRlc3RNYWtlU2ltcGxlUHJvdG9DbGFzcyhzZWxmKToKKyAgICAiIiJUZXN0IHRoYXQgd2UgY2FuIGNyZWF0ZSBhIHByb3RvIGNsYXNzLiIiIgorICAgIHByb3RvX2NscyA9IHByb3RvX2J1aWxkZXIuTWFrZVNpbXBsZVByb3RvQ2xhc3MoCisgICAgICAgIHNlbGYuX2ZpZWxkcywKKyAgICAgICAgZnVsbF9uYW1lPSduZXQucHJvdG8yLnB5dGhvbi5wdWJsaWMucHJvdG9fYnVpbGRlcl90ZXN0LlRlc3QnKQorICAgIHByb3RvID0gcHJvdG9fY2xzKCkKKyAgICBwcm90by5mb28gPSAxMjM0NQorICAgIHByb3RvLmJhciA9ICdhc2RmJworICAgIHNlbGYuYXNzZXJ0TXVsdGlMaW5lRXF1YWwoCisgICAgICAgICdiYXI6ICJhc2RmIlxuZm9vOiAxMjM0NVxuJywgdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKHByb3RvKSkKKworICBkZWYgdGVzdE1ha2VTYW1lUHJvdG9DbGFzc1R3aWNlKHNlbGYpOgorICAgICIiIlRlc3QgdGhhdCB0aGUgRGVzY3JpcHRvclBvb2wgaXMgdXNlZC4iIiIKKyAgICBwb29sID0gZGVzY3JpcHRvcl9wb29sLkRlc2NyaXB0b3JQb29sKCkKKyAgICBwcm90b19jbHMxID0gcHJvdG9fYnVpbGRlci5NYWtlU2ltcGxlUHJvdG9DbGFzcygKKyAgICAgICAgc2VsZi5fZmllbGRzLAorICAgICAgICBmdWxsX25hbWU9J25ldC5wcm90bzIucHl0aG9uLnB1YmxpYy5wcm90b19idWlsZGVyX3Rlc3QuVGVzdCcsCisgICAgICAgIHBvb2w9cG9vbCkKKyAgICBwcm90b19jbHMyID0gcHJvdG9fYnVpbGRlci5NYWtlU2ltcGxlUHJvdG9DbGFzcygKKyAgICAgICAgc2VsZi5fZmllbGRzLAorICAgICAgICBmdWxsX25hbWU9J25ldC5wcm90bzIucHl0aG9uLnB1YmxpYy5wcm90b19idWlsZGVyX3Rlc3QuVGVzdCcsCisgICAgICAgIHBvb2w9cG9vbCkKKyAgICBzZWxmLmFzc2VydElzKHByb3RvX2NsczEuREVTQ1JJUFRPUiwgcHJvdG9fY2xzMi5ERVNDUklQVE9SKQorCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIGJhc2V0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9weXRob25fbWVzc2FnZS5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvcHl0aG9uX21lc3NhZ2UucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNmFkMGY5MAotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvcHl0aG9uX21lc3NhZ2UucHkKQEAgLTAsMCArMSwxMzA2IEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyMgS2VlcCBpdCBQeXRob24yLjUgY29tcGF0aWJsZSBmb3IgR0FFLgorIworIyBDb3B5cmlnaHQgMjAwNyBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorIworIyBUaGlzIGNvZGUgaXMgbWVhbnQgdG8gd29yayBvbiBQeXRob24gMi40IGFuZCBhYm92ZSBvbmx5LgorIworIyBUT0RPKHJvYmluc29uKTogSGVscGVycyBmb3IgdmVyYm9zZSwgY29tbW9uIGNoZWNrcyBsaWtlIHNlZWluZyBpZiBhCisjIGRlc2NyaXB0b3IncyBjcHBfdHlwZSBpcyBDUFBUWVBFX01FU1NBR0UuCisKKyIiIkNvbnRhaW5zIGEgbWV0YWNsYXNzIGFuZCBoZWxwZXIgZnVuY3Rpb25zIHVzZWQgdG8gY3JlYXRlCitwcm90b2NvbCBtZXNzYWdlIGNsYXNzZXMgZnJvbSBEZXNjcmlwdG9yIG9iamVjdHMgYXQgcnVudGltZS4KKworUmVjYWxsIHRoYXQgYSBtZXRhY2xhc3MgaXMgdGhlICJ0eXBlIiBvZiBhIGNsYXNzLgorKEEgY2xhc3MgaXMgdG8gYSBtZXRhY2xhc3Mgd2hhdCBhbiBpbnN0YW5jZSBpcyB0byBhIGNsYXNzLikKKworSW4gdGhpcyBjYXNlLCB3ZSB1c2UgdGhlIEdlbmVyYXRlZFByb3RvY29sTWVzc2FnZVR5cGUgbWV0YWNsYXNzCit0byBpbmplY3QgYWxsIHRoZSB1c2VmdWwgZnVuY3Rpb25hbGl0eSBpbnRvIHRoZSBjbGFzc2VzCitvdXRwdXQgYnkgdGhlIHByb3RvY29sIGNvbXBpbGVyIGF0IGNvbXBpbGUtdGltZS4KKworVGhlIHVwc2hvdCBvZiBhbGwgdGhpcyBpcyB0aGF0IHRoZSByZWFsIGltcGxlbWVudGF0aW9uCitkZXRhaWxzIGZvciBBTEwgcHVyZS1QeXRob24gcHJvdG9jb2wgYnVmZmVycyBhcmUgKmhlcmUgaW4KK3RoaXMgZmlsZSouCisiIiIKKworX19hdXRob3JfXyA9ICdyb2JpbnNvbkBnb29nbGUuY29tIChXaWxsIFJvYmluc29uKScKKworaW1wb3J0IHN5cworaWYgc3lzLnZlcnNpb25faW5mb1swXSA8IDM6CisgIHRyeToKKyAgICBmcm9tIGNTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8gYXMgQnl0ZXNJTworICBleGNlcHQgSW1wb3J0RXJyb3I6CisgICAgZnJvbSBTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8gYXMgQnl0ZXNJTworICBpbXBvcnQgY29weV9yZWcgYXMgY29weXJlZworZWxzZToKKyAgZnJvbSBpbyBpbXBvcnQgQnl0ZXNJTworICBpbXBvcnQgY29weXJlZworaW1wb3J0IHN0cnVjdAoraW1wb3J0IHdlYWtyZWYKKworIyBXZSB1c2UgImFzIiB0byBhdm9pZCBuYW1lIGNvbGxpc2lvbnMgd2l0aCB2YXJpYWJsZXMuCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgY29udGFpbmVycworZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGRlY29kZXIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBlbmNvZGVyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgZW51bV90eXBlX3dyYXBwZXIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBtZXNzYWdlX2xpc3RlbmVyIGFzIG1lc3NhZ2VfbGlzdGVuZXJfbW9kCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgdHlwZV9jaGVja2VycworZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IHdpcmVfZm9ybWF0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvciBhcyBkZXNjcmlwdG9yX21vZAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2UgYXMgbWVzc2FnZV9tb2QKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB0ZXh0X2Zvcm1hdAorCitfRmllbGREZXNjcmlwdG9yID0gZGVzY3JpcHRvcl9tb2QuRmllbGREZXNjcmlwdG9yCisKKworZGVmIE5ld01lc3NhZ2UoYmFzZXMsIGRlc2NyaXB0b3IsIGRpY3Rpb25hcnkpOgorICBfQWRkQ2xhc3NBdHRyaWJ1dGVzRm9yTmVzdGVkRXh0ZW5zaW9ucyhkZXNjcmlwdG9yLCBkaWN0aW9uYXJ5KQorICBfQWRkU2xvdHMoZGVzY3JpcHRvciwgZGljdGlvbmFyeSkKKyAgcmV0dXJuIGJhc2VzCisKKworZGVmIEluaXRNZXNzYWdlKGRlc2NyaXB0b3IsIGNscyk6CisgIGNscy5fZGVjb2RlcnNfYnlfdGFnID0ge30KKyAgY2xzLl9leHRlbnNpb25zX2J5X25hbWUgPSB7fQorICBjbHMuX2V4dGVuc2lvbnNfYnlfbnVtYmVyID0ge30KKyAgaWYgKGRlc2NyaXB0b3IuaGFzX29wdGlvbnMgYW5kCisgICAgICBkZXNjcmlwdG9yLkdldE9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCk6CisgICAgY2xzLl9kZWNvZGVyc19ieV90YWdbZGVjb2Rlci5NRVNTQUdFX1NFVF9JVEVNX1RBR10gPSAoCisgICAgICAgIGRlY29kZXIuTWVzc2FnZVNldEl0ZW1EZWNvZGVyKGNscy5fZXh0ZW5zaW9uc19ieV9udW1iZXIpLCBOb25lKQorCisgICMgQXR0YWNoIHN0dWZmIHRvIGVhY2ggRmllbGREZXNjcmlwdG9yIGZvciBxdWljayBsb29rdXAgbGF0ZXIgb24uCisgIGZvciBmaWVsZCBpbiBkZXNjcmlwdG9yLmZpZWxkczoKKyAgICBfQXR0YWNoRmllbGRIZWxwZXJzKGNscywgZmllbGQpCisKKyAgX0FkZEVudW1WYWx1ZXMoZGVzY3JpcHRvciwgY2xzKQorICBfQWRkSW5pdE1ldGhvZChkZXNjcmlwdG9yLCBjbHMpCisgIF9BZGRQcm9wZXJ0aWVzRm9yRmllbGRzKGRlc2NyaXB0b3IsIGNscykKKyAgX0FkZFByb3BlcnRpZXNGb3JFeHRlbnNpb25zKGRlc2NyaXB0b3IsIGNscykKKyAgX0FkZFN0YXRpY01ldGhvZHMoY2xzKQorICBfQWRkTWVzc2FnZU1ldGhvZHMoZGVzY3JpcHRvciwgY2xzKQorICBfQWRkUHJpdmF0ZUhlbHBlck1ldGhvZHMoZGVzY3JpcHRvciwgY2xzKQorICBjb3B5cmVnLnBpY2tsZShjbHMsIGxhbWJkYSBvYmo6IChjbHMsICgpLCBvYmouX19nZXRzdGF0ZV9fKCkpKQorCisKKyMgU3RhdGVsZXNzIGhlbHBlcnMgZm9yIEdlbmVyYXRlZFByb3RvY29sTWVzc2FnZVR5cGUgYmVsb3cuCisjIE91dHNpZGUgY2xpZW50cyBzaG91bGQgbm90IGFjY2VzcyB0aGVzZSBkaXJlY3RseS4KKyMKKyMgSSBvcHRlZCBub3QgdG8gbWFrZSBhbnkgb2YgdGhlc2UgbWV0aG9kcyBvbiB0aGUgbWV0YWNsYXNzLCB0byBtYWtlIGl0IG1vcmUKKyMgY2xlYXIgdGhhdCBJJ20gbm90IHJlYWxseSB1c2luZyBhbnkgc3RhdGUgdGhlcmUgYW5kIHRvIGtlZXAgY2xpZW50cyBmcm9tCisjIHRoaW5raW5nIHRoYXQgdGhleSBoYXZlIGRpcmVjdCBhY2Nlc3MgdG8gdGhlc2UgY29uc3RydWN0aW9uIGhlbHBlcnMuCisKKworZGVmIF9Qcm9wZXJ0eU5hbWUocHJvdG9fZmllbGRfbmFtZSk6CisgICIiIlJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHB1YmxpYyBwcm9wZXJ0eSBhdHRyaWJ1dGUgd2hpY2gKKyAgY2xpZW50cyBjYW4gdXNlIHRvIGdldCBhbmQgKGluIHNvbWUgY2FzZXMpIHNldCB0aGUgdmFsdWUKKyAgb2YgYSBwcm90b2NvbCBtZXNzYWdlIGZpZWxkLgorCisgIEFyZ3M6CisgICAgcHJvdG9fZmllbGRfbmFtZTogVGhlIHByb3RvY29sIG1lc3NhZ2UgZmllbGQgbmFtZSwgZXhhY3RseQorICAgICAgYXMgaXQgYXBwZWFycyAob3Igd291bGQgYXBwZWFyKSBpbiBhIC5wcm90byBmaWxlLgorICAiIiIKKyAgIyBUT0RPKHJvYmluc29uKTogRXNjYXBlIFB5dGhvbiBrZXl3b3JkcyAoZS5nLiwgeWllbGQpLCBhbmQgdGVzdCB0aGlzIHN1cHBvcnQuCisgICMgbm5vcndpdHogbWFrZXMgbXkgZGF5IGJ5IHdyaXRpbmc6CisgICMgIiIiCisgICMgRllJLiAgU2VlIHRoZSBrZXl3b3JkIG1vZHVsZSBpbiB0aGUgc3RkbGliLiBUaGlzIGNvdWxkIGJlIGFzIHNpbXBsZSBhczoKKyAgIworICAjIGlmIGtleXdvcmQuaXNrZXl3b3JkKHByb3RvX2ZpZWxkX25hbWUpOgorICAjICAgcmV0dXJuIHByb3RvX2ZpZWxkX25hbWUgKyAiXyIKKyAgIyByZXR1cm4gcHJvdG9fZmllbGRfbmFtZQorICAjICIiIgorICAjIEtlbnRvbiBzYXlzOiAgVGhlIGFib3ZlIGlzIGEgQkFEIElERUEuICBQZW9wbGUgcmVseSBvbiBiZWluZyBhYmxlIHRvIHVzZQorICAjICAgZ2V0YXR0cigpIGFuZCBzZXRhdHRyKCkgdG8gcmVmbGVjdGl2ZWx5IG1hbmlwdWxhdGUgZmllbGQgdmFsdWVzLiAgSWYgd2UKKyAgIyAgIHJlbmFtZSB0aGUgcHJvcGVydGllcywgdGhlbiBldmVyeSBzdWNoIHVzZXIgaGFzIHRvIGFsc28gbWFrZSBzdXJlIHRvIGFwcGx5CisgICMgICB0aGUgc2FtZSB0cmFuc2Zvcm1hdGlvbi4gIE5vdGUgdGhhdCBjdXJyZW50bHkgaWYgeW91IG5hbWUgYSBmaWVsZCAieWllbGQiLAorICAjICAgeW91IGNhbiBzdGlsbCBhY2Nlc3MgaXQganVzdCBmaW5lIHVzaW5nIGdldGF0dHIvc2V0YXR0ciAtLSBpdCdzIG5vdCBldmVuCisgICMgICB0aGF0IGN1bWJlcnNvbWUgdG8gZG8gc28uCisgICMgVE9ETyhrZW50b24pOiAgUmVtb3ZlIHRoaXMgbWV0aG9kIGVudGlyZWx5IGlmL3doZW4gZXZlcnlvbmUgYWdyZWVzIHdpdGggbXkKKyAgIyAgIHBvc2l0aW9uLgorICByZXR1cm4gcHJvdG9fZmllbGRfbmFtZQorCisKK2RlZiBfVmVyaWZ5RXh0ZW5zaW9uSGFuZGxlKG1lc3NhZ2UsIGV4dGVuc2lvbl9oYW5kbGUpOgorICAiIiJWZXJpZnkgdGhhdCB0aGUgZ2l2ZW4gZXh0ZW5zaW9uIGhhbmRsZSBpcyB2YWxpZC4iIiIKKworICBpZiBub3QgaXNpbnN0YW5jZShleHRlbnNpb25faGFuZGxlLCBfRmllbGREZXNjcmlwdG9yKToKKyAgICByYWlzZSBLZXlFcnJvcignSGFzRXh0ZW5zaW9uKCkgZXhwZWN0cyBhbiBleHRlbnNpb24gaGFuZGxlLCBnb3Q6ICVzJyAlCisgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX2hhbmRsZSkKKworICBpZiBub3QgZXh0ZW5zaW9uX2hhbmRsZS5pc19leHRlbnNpb246CisgICAgcmFpc2UgS2V5RXJyb3IoJyIlcyIgaXMgbm90IGFuIGV4dGVuc2lvbi4nICUgZXh0ZW5zaW9uX2hhbmRsZS5mdWxsX25hbWUpCisKKyAgaWYgbm90IGV4dGVuc2lvbl9oYW5kbGUuY29udGFpbmluZ190eXBlOgorICAgIHJhaXNlIEtleUVycm9yKCciJXMiIGlzIG1pc3NpbmcgYSBjb250YWluaW5nX3R5cGUuJworICAgICAgICAgICAgICAgICAgICUgZXh0ZW5zaW9uX2hhbmRsZS5mdWxsX25hbWUpCisKKyAgaWYgZXh0ZW5zaW9uX2hhbmRsZS5jb250YWluaW5nX3R5cGUgaXMgbm90IG1lc3NhZ2UuREVTQ1JJUFRPUjoKKyAgICByYWlzZSBLZXlFcnJvcignRXh0ZW5zaW9uICIlcyIgZXh0ZW5kcyBtZXNzYWdlIHR5cGUgIiVzIiwgYnV0IHRoaXMgJworICAgICAgICAgICAgICAgICAgICdtZXNzYWdlIGlzIG9mIHR5cGUgIiVzIi4nICUKKyAgICAgICAgICAgICAgICAgICAoZXh0ZW5zaW9uX2hhbmRsZS5mdWxsX25hbWUsCisgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbl9oYW5kbGUuY29udGFpbmluZ190eXBlLmZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5ERVNDUklQVE9SLmZ1bGxfbmFtZSkpCisKKworZGVmIF9BZGRTbG90cyhtZXNzYWdlX2Rlc2NyaXB0b3IsIGRpY3Rpb25hcnkpOgorICAiIiJBZGRzIGEgX19zbG90c19fIGVudHJ5IHRvIGRpY3Rpb25hcnksIGNvbnRhaW5pbmcgdGhlIG5hbWVzIG9mIGFsbCB2YWxpZAorICBhdHRyaWJ1dGVzIGZvciB0aGlzIG1lc3NhZ2UgdHlwZS4KKworICBBcmdzOgorICAgIG1lc3NhZ2VfZGVzY3JpcHRvcjogQSBEZXNjcmlwdG9yIGluc3RhbmNlIGRlc2NyaWJpbmcgdGhpcyBtZXNzYWdlIHR5cGUuCisgICAgZGljdGlvbmFyeTogQ2xhc3MgZGljdGlvbmFyeSB0byB3aGljaCB3ZSdsbCBhZGQgYSAnX19zbG90c19fJyBlbnRyeS4KKyAgIiIiCisgIGRpY3Rpb25hcnlbJ19fc2xvdHNfXyddID0gWydfY2FjaGVkX2J5dGVfc2l6ZScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdfY2FjaGVkX2J5dGVfc2l6ZV9kaXJ0eScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdfZmllbGRzJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ191bmtub3duX2ZpZWxkcycsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdfaXNfcHJlc2VudF9pbl9wYXJlbnQnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnX2xpc3RlbmVyJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ19saXN0ZW5lcl9mb3JfY2hpbGRyZW4nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnX193ZWFrcmVmX18nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnX29uZW9mcyddCisKKworZGVmIF9Jc01lc3NhZ2VTZXRFeHRlbnNpb24oZmllbGQpOgorICByZXR1cm4gKGZpZWxkLmlzX2V4dGVuc2lvbiBhbmQKKyAgICAgICAgICBmaWVsZC5jb250YWluaW5nX3R5cGUuaGFzX29wdGlvbnMgYW5kCisgICAgICAgICAgZmllbGQuY29udGFpbmluZ190eXBlLkdldE9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCBhbmQKKyAgICAgICAgICBmaWVsZC50eXBlID09IF9GaWVsZERlc2NyaXB0b3IuVFlQRV9NRVNTQUdFIGFuZAorICAgICAgICAgIGZpZWxkLm1lc3NhZ2VfdHlwZSA9PSBmaWVsZC5leHRlbnNpb25fc2NvcGUgYW5kCisgICAgICAgICAgZmllbGQubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9PUFRJT05BTCkKKworCitkZWYgX0F0dGFjaEZpZWxkSGVscGVycyhjbHMsIGZpZWxkX2Rlc2NyaXB0b3IpOgorICBpc19yZXBlYXRlZCA9IChmaWVsZF9kZXNjcmlwdG9yLmxhYmVsID09IF9GaWVsZERlc2NyaXB0b3IuTEFCRUxfUkVQRUFURUQpCisgIGlzX3BhY2tlZCA9IChmaWVsZF9kZXNjcmlwdG9yLmhhc19vcHRpb25zIGFuZAorICAgICAgICAgICAgICAgZmllbGRfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkucGFja2VkKQorCisgIGlmIF9Jc01lc3NhZ2VTZXRFeHRlbnNpb24oZmllbGRfZGVzY3JpcHRvcik6CisgICAgZmllbGRfZW5jb2RlciA9IGVuY29kZXIuTWVzc2FnZVNldEl0ZW1FbmNvZGVyKGZpZWxkX2Rlc2NyaXB0b3IubnVtYmVyKQorICAgIHNpemVyID0gZW5jb2Rlci5NZXNzYWdlU2V0SXRlbVNpemVyKGZpZWxkX2Rlc2NyaXB0b3IubnVtYmVyKQorICBlbHNlOgorICAgIGZpZWxkX2VuY29kZXIgPSB0eXBlX2NoZWNrZXJzLlRZUEVfVE9fRU5DT0RFUltmaWVsZF9kZXNjcmlwdG9yLnR5cGVdKAorICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLm51bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCkKKyAgICBzaXplciA9IHR5cGVfY2hlY2tlcnMuVFlQRV9UT19TSVpFUltmaWVsZF9kZXNjcmlwdG9yLnR5cGVdKAorICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLm51bWJlciwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCkKKworICBmaWVsZF9kZXNjcmlwdG9yLl9lbmNvZGVyID0gZmllbGRfZW5jb2RlcgorICBmaWVsZF9kZXNjcmlwdG9yLl9zaXplciA9IHNpemVyCisgIGZpZWxkX2Rlc2NyaXB0b3IuX2RlZmF1bHRfY29uc3RydWN0b3IgPSBfRGVmYXVsdFZhbHVlQ29uc3RydWN0b3JGb3JGaWVsZCgKKyAgICAgIGZpZWxkX2Rlc2NyaXB0b3IpCisKKyAgZGVmIEFkZERlY29kZXIod2lyZXR5cGUsIGlzX3BhY2tlZCk6CisgICAgdGFnX2J5dGVzID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9kZXNjcmlwdG9yLm51bWJlciwgd2lyZXR5cGUpCisgICAgZGVjb2RlX3R5cGUgPSBmaWVsZF9kZXNjcmlwdG9yLnR5cGUKKyAgICBpZiAoZGVjb2RlX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU0gYW5kCisgICAgICAgIHR5cGVfY2hlY2tlcnMuU3VwcG9ydHNPcGVuRW51bXMoZmllbGRfZGVzY3JpcHRvcikpOgorICAgICAgZGVjb2RlX3R5cGUgPSBfRmllbGREZXNjcmlwdG9yLlRZUEVfSU5UMzIKKworICAgIG9uZW9mX2Rlc2NyaXB0b3IgPSBOb25lCisgICAgaWYgZmllbGRfZGVzY3JpcHRvci5jb250YWluaW5nX29uZW9mIGlzIG5vdCBOb25lOgorICAgICAgb25lb2ZfZGVzY3JpcHRvciA9IGZpZWxkX2Rlc2NyaXB0b3IKKworICAgIGZpZWxkX2RlY29kZXIgPSB0eXBlX2NoZWNrZXJzLlRZUEVfVE9fREVDT0RFUltkZWNvZGVfdHlwZV0oCisgICAgICAgIGZpZWxkX2Rlc2NyaXB0b3IubnVtYmVyLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkLAorICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLCBmaWVsZF9kZXNjcmlwdG9yLl9kZWZhdWx0X2NvbnN0cnVjdG9yKQorCisgICAgY2xzLl9kZWNvZGVyc19ieV90YWdbdGFnX2J5dGVzXSA9IChmaWVsZF9kZWNvZGVyLCBvbmVvZl9kZXNjcmlwdG9yKQorCisgIEFkZERlY29kZXIodHlwZV9jaGVja2Vycy5GSUVMRF9UWVBFX1RPX1dJUkVfVFlQRVtmaWVsZF9kZXNjcmlwdG9yLnR5cGVdLAorICAgICAgICAgICAgIEZhbHNlKQorCisgIGlmIGlzX3JlcGVhdGVkIGFuZCB3aXJlX2Zvcm1hdC5Jc1R5cGVQYWNrYWJsZShmaWVsZF9kZXNjcmlwdG9yLnR5cGUpOgorICAgICMgVG8gc3VwcG9ydCB3aXJlIGNvbXBhdGliaWxpdHkgb2YgYWRkaW5nIHBhY2tlZCA9IHRydWUsIGFkZCBhIGRlY29kZXIgZm9yCisgICAgIyBwYWNrZWQgdmFsdWVzIHJlZ2FyZGxlc3Mgb2YgdGhlIGZpZWxkJ3Mgb3B0aW9ucy4KKyAgICBBZGREZWNvZGVyKHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIFRydWUpCisKKworZGVmIF9BZGRDbGFzc0F0dHJpYnV0ZXNGb3JOZXN0ZWRFeHRlbnNpb25zKGRlc2NyaXB0b3IsIGRpY3Rpb25hcnkpOgorICBleHRlbnNpb25fZGljdCA9IGRlc2NyaXB0b3IuZXh0ZW5zaW9uc19ieV9uYW1lCisgIGZvciBleHRlbnNpb25fbmFtZSwgZXh0ZW5zaW9uX2ZpZWxkIGluIGV4dGVuc2lvbl9kaWN0Lml0ZXJpdGVtcygpOgorICAgIGFzc2VydCBleHRlbnNpb25fbmFtZSBub3QgaW4gZGljdGlvbmFyeQorICAgIGRpY3Rpb25hcnlbZXh0ZW5zaW9uX25hbWVdID0gZXh0ZW5zaW9uX2ZpZWxkCisKKworZGVmIF9BZGRFbnVtVmFsdWVzKGRlc2NyaXB0b3IsIGNscyk6CisgICIiIlNldHMgY2xhc3MtbGV2ZWwgYXR0cmlidXRlcyBmb3IgYWxsIGVudW0gZmllbGRzIGRlZmluZWQgaW4gdGhpcyBtZXNzYWdlLgorCisgIEFsc28gZXhwb3J0aW5nIGEgY2xhc3MtbGV2ZWwgb2JqZWN0IHRoYXQgY2FuIG5hbWUgZW51bSB2YWx1ZXMuCisKKyAgQXJnczoKKyAgICBkZXNjcmlwdG9yOiBEZXNjcmlwdG9yIG9iamVjdCBmb3IgdGhpcyBtZXNzYWdlIHR5cGUuCisgICAgY2xzOiBDbGFzcyB3ZSdyZSBjb25zdHJ1Y3RpbmcgZm9yIHRoaXMgbWVzc2FnZSB0eXBlLgorICAiIiIKKyAgZm9yIGVudW1fdHlwZSBpbiBkZXNjcmlwdG9yLmVudW1fdHlwZXM6CisgICAgc2V0YXR0cihjbHMsIGVudW1fdHlwZS5uYW1lLCBlbnVtX3R5cGVfd3JhcHBlci5FbnVtVHlwZVdyYXBwZXIoZW51bV90eXBlKSkKKyAgICBmb3IgZW51bV92YWx1ZSBpbiBlbnVtX3R5cGUudmFsdWVzOgorICAgICAgc2V0YXR0cihjbHMsIGVudW1fdmFsdWUubmFtZSwgZW51bV92YWx1ZS5udW1iZXIpCisKKworZGVmIF9EZWZhdWx0VmFsdWVDb25zdHJ1Y3RvckZvckZpZWxkKGZpZWxkKToKKyAgIiIiUmV0dXJucyBhIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSBkZWZhdWx0IHZhbHVlIGZvciBhIGZpZWxkLgorCisgIEFyZ3M6CisgICAgZmllbGQ6IEZpZWxkRGVzY3JpcHRvciBvYmplY3QgZm9yIHRoaXMgZmllbGQuCisKKyAgVGhlIHJldHVybmVkIGZ1bmN0aW9uIGhhcyBvbmUgYXJndW1lbnQ6CisgICAgbWVzc2FnZTogTWVzc2FnZSBpbnN0YW5jZSBjb250YWluaW5nIHRoaXMgZmllbGQsIG9yIGEgd2Vha3JlZiBwcm94eQorICAgICAgb2Ygc2FtZS4KKworICBUaGF0IGZ1bmN0aW9uIGluIHR1cm4gcmV0dXJucyBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgZmllbGQuICBUaGUgZGVmYXVsdAorICAgIHZhbHVlIG1heSByZWZlciBiYWNrIHRvIHxtZXNzYWdlfCB2aWEgYSB3ZWFrIHJlZmVyZW5jZS4KKyAgIiIiCisKKyAgaWYgZmllbGQubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICBpZiBmaWVsZC5oYXNfZGVmYXVsdF92YWx1ZSBhbmQgZmllbGQuZGVmYXVsdF92YWx1ZSAhPSBbXToKKyAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ1JlcGVhdGVkIGZpZWxkIGRlZmF1bHQgdmFsdWUgbm90IGVtcHR5IGxpc3Q6ICVzJyAlICgKKyAgICAgICAgICBmaWVsZC5kZWZhdWx0X3ZhbHVlKSkKKyAgICBpZiBmaWVsZC5jcHBfdHlwZSA9PSBfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICMgV2UgY2FuJ3QgbG9vayBhdCBfY29uY3JldGVfY2xhc3MgeWV0IHNpbmNlIGl0IG1pZ2h0IG5vdCBoYXZlCisgICAgICAjIGJlZW4gc2V0LiAgKERlcGVuZHMgb24gb3JkZXIgaW4gd2hpY2ggd2UgaW5pdGlhbGl6ZSB0aGUgY2xhc3NlcykuCisgICAgICBtZXNzYWdlX3R5cGUgPSBmaWVsZC5tZXNzYWdlX3R5cGUKKyAgICAgIGRlZiBNYWtlUmVwZWF0ZWRNZXNzYWdlRGVmYXVsdChtZXNzYWdlKToKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5lcnMuUmVwZWF0ZWRDb21wb3NpdGVGaWVsZENvbnRhaW5lcigKKyAgICAgICAgICAgIG1lc3NhZ2UuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbiwgZmllbGQubWVzc2FnZV90eXBlKQorICAgICAgcmV0dXJuIE1ha2VSZXBlYXRlZE1lc3NhZ2VEZWZhdWx0CisgICAgZWxzZToKKyAgICAgIHR5cGVfY2hlY2tlciA9IHR5cGVfY2hlY2tlcnMuR2V0VHlwZUNoZWNrZXIoZmllbGQpCisgICAgICBkZWYgTWFrZVJlcGVhdGVkU2NhbGFyRGVmYXVsdChtZXNzYWdlKToKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5lcnMuUmVwZWF0ZWRTY2FsYXJGaWVsZENvbnRhaW5lcigKKyAgICAgICAgICAgIG1lc3NhZ2UuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbiwgdHlwZV9jaGVja2VyKQorICAgICAgcmV0dXJuIE1ha2VSZXBlYXRlZFNjYWxhckRlZmF1bHQKKworICBpZiBmaWVsZC5jcHBfdHlwZSA9PSBfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfTUVTU0FHRToKKyAgICAjIF9jb25jcmV0ZV9jbGFzcyBtYXkgbm90IHlldCBiZSBpbml0aWFsaXplZC4KKyAgICBtZXNzYWdlX3R5cGUgPSBmaWVsZC5tZXNzYWdlX3R5cGUKKyAgICBkZWYgTWFrZVN1Yk1lc3NhZ2VEZWZhdWx0KG1lc3NhZ2UpOgorICAgICAgcmVzdWx0ID0gbWVzc2FnZV90eXBlLl9jb25jcmV0ZV9jbGFzcygpCisgICAgICByZXN1bHQuX1NldExpc3RlbmVyKG1lc3NhZ2UuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbikKKyAgICAgIGlmIGZpZWxkLmNvbnRhaW5pbmdfb25lb2Y6CisgICAgICAgIG1lc3NhZ2UuX1VwZGF0ZU9uZW9mU3RhdGUoZmllbGQpCisgICAgICByZXR1cm4gcmVzdWx0CisgICAgcmV0dXJuIE1ha2VTdWJNZXNzYWdlRGVmYXVsdAorCisgIGRlZiBNYWtlU2NhbGFyRGVmYXVsdChtZXNzYWdlKToKKyAgICAjIFRPRE8ocHJvdG9idWYtdGVhbSk6IFRoaXMgbWF5IGJlIGJyb2tlbiBzaW5jZSB0aGVyZSBtYXkgbm90IGJlCisgICAgIyBkZWZhdWx0X3ZhbHVlLiAgQ29tYmluZSB3aXRoIGhhc19kZWZhdWx0X3ZhbHVlIHNvbWVob3cuCisgICAgcmV0dXJuIGZpZWxkLmRlZmF1bHRfdmFsdWUKKyAgcmV0dXJuIE1ha2VTY2FsYXJEZWZhdWx0CisKKworZGVmIF9SZXJhaXNlVHlwZUVycm9yV2l0aEZpZWxkTmFtZShtZXNzYWdlX25hbWUsIGZpZWxkX25hbWUpOgorICAiIiJSZS1yYWlzZSB0aGUgY3VycmVudGx5LWhhbmRsZWQgVHlwZUVycm9yIHdpdGggdGhlIGZpZWxkIG5hbWUgYWRkZWQuIiIiCisgIGV4YyA9IHN5cy5leGNfaW5mbygpWzFdCisgIGlmIGxlbihleGMuYXJncykgPT0gMSBhbmQgdHlwZShleGMpIGlzIFR5cGVFcnJvcjoKKyAgICAjIHNpbXBsZSBUeXBlRXJyb3I7IGFkZCBmaWVsZCBuYW1lIHRvIGV4Y2VwdGlvbiBtZXNzYWdlCisgICAgZXhjID0gVHlwZUVycm9yKCclcyBmb3IgZmllbGQgJXMuJXMnICUgKHN0cihleGMpLCBtZXNzYWdlX25hbWUsIGZpZWxkX25hbWUpKQorCisgICMgcmUtcmFpc2UgcG9zc2libHktYW1lbmRlZCBleGNlcHRpb24gd2l0aCBvcmlnaW5hbCB0cmFjZWJhY2s6CisgIHJhaXNlIHR5cGUoZXhjKSwgZXhjLCBzeXMuZXhjX2luZm8oKVsyXQorCisKK2RlZiBfQWRkSW5pdE1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkFkZHMgYW4gX19pbml0X18gbWV0aG9kIHRvIGNscy4iIiIKKyAgZmllbGRzID0gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkcworICBkZWYgaW5pdChzZWxmLCAqKmt3YXJncyk6CisgICAgc2VsZi5fY2FjaGVkX2J5dGVfc2l6ZSA9IDAKKyAgICBzZWxmLl9jYWNoZWRfYnl0ZV9zaXplX2RpcnR5ID0gbGVuKGt3YXJncykgPiAwCisgICAgc2VsZi5fZmllbGRzID0ge30KKyAgICAjIENvbnRhaW5zIGEgbWFwcGluZyBmcm9tIG9uZW9mIGZpZWxkIGRlc2NyaXB0b3JzIHRvIHRoZSBkZXNjcmlwdG9yCisgICAgIyBvZiB0aGUgY3VycmVudGx5IHNldCBmaWVsZCBpbiB0aGF0IG9uZW9mIGZpZWxkLgorICAgIHNlbGYuX29uZW9mcyA9IHt9CisKKyAgICAjIF91bmtub3duX2ZpZWxkcyBpcyAoKSB3aGVuIGVtcHR5IGZvciBlZmZpY2llbmN5LCBhbmQgd2lsbCBiZSB0dXJuZWQgaW50bworICAgICMgYSBsaXN0IGlmIGZpZWxkcyBhcmUgYWRkZWQuCisgICAgc2VsZi5fdW5rbm93bl9maWVsZHMgPSAoKQorICAgIHNlbGYuX2lzX3ByZXNlbnRfaW5fcGFyZW50ID0gRmFsc2UKKyAgICBzZWxmLl9saXN0ZW5lciA9IG1lc3NhZ2VfbGlzdGVuZXJfbW9kLk51bGxNZXNzYWdlTGlzdGVuZXIoKQorICAgIHNlbGYuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbiA9IF9MaXN0ZW5lcihzZWxmKQorICAgIGZvciBmaWVsZF9uYW1lLCBmaWVsZF92YWx1ZSBpbiBrd2FyZ3MuaXRlcml0ZW1zKCk6CisgICAgICBmaWVsZCA9IF9HZXRGaWVsZEJ5TmFtZShtZXNzYWdlX2Rlc2NyaXB0b3IsIGZpZWxkX25hbWUpCisgICAgICBpZiBmaWVsZCBpcyBOb25lOgorICAgICAgICByYWlzZSBUeXBlRXJyb3IoIiVzKCkgZ290IGFuIHVuZXhwZWN0ZWQga2V5d29yZCBhcmd1bWVudCAnJXMnIiAlCisgICAgICAgICAgICAgICAgICAgICAgICAobWVzc2FnZV9kZXNjcmlwdG9yLm5hbWUsIGZpZWxkX25hbWUpKQorICAgICAgaWYgZmllbGQubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICAgICAgY29weSA9IGZpZWxkLl9kZWZhdWx0X2NvbnN0cnVjdG9yKHNlbGYpCisgICAgICAgIGlmIGZpZWxkLmNwcF90eXBlID09IF9GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9NRVNTQUdFOiAgIyBDb21wb3NpdGUKKyAgICAgICAgICBmb3IgdmFsIGluIGZpZWxkX3ZhbHVlOgorICAgICAgICAgICAgY29weS5hZGQoKS5NZXJnZUZyb20odmFsKQorICAgICAgICBlbHNlOiAgIyBTY2FsYXIKKyAgICAgICAgICBjb3B5LmV4dGVuZChmaWVsZF92YWx1ZSkKKyAgICAgICAgc2VsZi5fZmllbGRzW2ZpZWxkXSA9IGNvcHkKKyAgICAgIGVsaWYgZmllbGQuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGNvcHkgPSBmaWVsZC5fZGVmYXVsdF9jb25zdHJ1Y3RvcihzZWxmKQorICAgICAgICB0cnk6CisgICAgICAgICAgY29weS5NZXJnZUZyb20oZmllbGRfdmFsdWUpCisgICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CisgICAgICAgICAgX1JlcmFpc2VUeXBlRXJyb3JXaXRoRmllbGROYW1lKG1lc3NhZ2VfZGVzY3JpcHRvci5uYW1lLCBmaWVsZF9uYW1lKQorICAgICAgICBzZWxmLl9maWVsZHNbZmllbGRdID0gY29weQorICAgICAgZWxzZToKKyAgICAgICAgdHJ5OgorICAgICAgICAgIHNldGF0dHIoc2VsZiwgZmllbGRfbmFtZSwgZmllbGRfdmFsdWUpCisgICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CisgICAgICAgICAgX1JlcmFpc2VUeXBlRXJyb3JXaXRoRmllbGROYW1lKG1lc3NhZ2VfZGVzY3JpcHRvci5uYW1lLCBmaWVsZF9uYW1lKQorCisgIGluaXQuX19tb2R1bGVfXyA9IE5vbmUKKyAgaW5pdC5fX2RvY19fID0gTm9uZQorICBjbHMuX19pbml0X18gPSBpbml0CisKKworZGVmIF9HZXRGaWVsZEJ5TmFtZShtZXNzYWdlX2Rlc2NyaXB0b3IsIGZpZWxkX25hbWUpOgorICAiIiJSZXR1cm5zIGEgZmllbGQgZGVzY3JpcHRvciBieSBmaWVsZCBuYW1lLgorCisgIEFyZ3M6CisgICAgbWVzc2FnZV9kZXNjcmlwdG9yOiBBIERlc2NyaXB0b3IgZGVzY3JpYmluZyBhbGwgZmllbGRzIGluIG1lc3NhZ2UuCisgICAgZmllbGRfbmFtZTogVGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHJldHJpZXZlLgorICBSZXR1cm5zOgorICAgIFRoZSBmaWVsZCBkZXNjcmlwdG9yIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmllbGQgbmFtZS4KKyAgIiIiCisgIHRyeToKKyAgICByZXR1cm4gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lW2ZpZWxkX25hbWVdCisgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICByYWlzZSBWYWx1ZUVycm9yKCdQcm90b2NvbCBtZXNzYWdlIGhhcyBubyAiJXMiIGZpZWxkLicgJSBmaWVsZF9uYW1lKQorCisKK2RlZiBfQWRkUHJvcGVydGllc0ZvckZpZWxkcyhkZXNjcmlwdG9yLCBjbHMpOgorICAiIiJBZGRzIHByb3BlcnRpZXMgZm9yIGFsbCBmaWVsZHMgaW4gdGhpcyBwcm90b2NvbCBtZXNzYWdlIHR5cGUuIiIiCisgIGZvciBmaWVsZCBpbiBkZXNjcmlwdG9yLmZpZWxkczoKKyAgICBfQWRkUHJvcGVydGllc0ZvckZpZWxkKGZpZWxkLCBjbHMpCisKKyAgaWYgZGVzY3JpcHRvci5pc19leHRlbmRhYmxlOgorICAgICMgX0V4dGVuc2lvbkRpY3QgaXMganVzdCBhbiBhZGFwdG9yIHdpdGggbm8gc3RhdGUgc28gd2UgYWxsb2NhdGUgYSBuZXcgb25lCisgICAgIyBldmVyeSB0aW1lIGl0IGlzIGFjY2Vzc2VkLgorICAgIGNscy5FeHRlbnNpb25zID0gcHJvcGVydHkobGFtYmRhIHNlbGY6IF9FeHRlbnNpb25EaWN0KHNlbGYpKQorCisKK2RlZiBfQWRkUHJvcGVydGllc0ZvckZpZWxkKGZpZWxkLCBjbHMpOgorICAiIiJBZGRzIGEgcHVibGljIHByb3BlcnR5IGZvciBhIHByb3RvY29sIG1lc3NhZ2UgZmllbGQuCisgIENsaWVudHMgY2FuIHVzZSB0aGlzIHByb3BlcnR5IHRvIGdldCBhbmQgKGluIHRoZSBjYXNlCisgIG9mIG5vbi1yZXBlYXRlZCBzY2FsYXIgZmllbGRzKSBkaXJlY3RseSBzZXQgdGhlIHZhbHVlCisgIG9mIGEgcHJvdG9jb2wgbWVzc2FnZSBmaWVsZC4KKworICBBcmdzOgorICAgIGZpZWxkOiBBIEZpZWxkRGVzY3JpcHRvciBmb3IgdGhpcyBmaWVsZC4KKyAgICBjbHM6IFRoZSBjbGFzcyB3ZSdyZSBjb25zdHJ1Y3RpbmcuCisgICIiIgorICAjIENhdGNoIGl0IGlmIHdlIGFkZCBvdGhlciB0eXBlcyB0aGF0IHdlIHNob3VsZAorICAjIGhhbmRsZSBzcGVjaWFsbHkgaGVyZS4KKyAgYXNzZXJ0IF9GaWVsZERlc2NyaXB0b3IuTUFYX0NQUFRZUEUgPT0gMTAKKworICBjb25zdGFudF9uYW1lID0gZmllbGQubmFtZS51cHBlcigpICsgIl9GSUVMRF9OVU1CRVIiCisgIHNldGF0dHIoY2xzLCBjb25zdGFudF9uYW1lLCBmaWVsZC5udW1iZXIpCisKKyAgaWYgZmllbGQubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICBfQWRkUHJvcGVydGllc0ZvclJlcGVhdGVkRmllbGQoZmllbGQsIGNscykKKyAgZWxpZiBmaWVsZC5jcHBfdHlwZSA9PSBfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfTUVTU0FHRToKKyAgICBfQWRkUHJvcGVydGllc0Zvck5vblJlcGVhdGVkQ29tcG9zaXRlRmllbGQoZmllbGQsIGNscykKKyAgZWxzZToKKyAgICBfQWRkUHJvcGVydGllc0Zvck5vblJlcGVhdGVkU2NhbGFyRmllbGQoZmllbGQsIGNscykKKworCitkZWYgX0FkZFByb3BlcnRpZXNGb3JSZXBlYXRlZEZpZWxkKGZpZWxkLCBjbHMpOgorICAiIiJBZGRzIGEgcHVibGljIHByb3BlcnR5IGZvciBhICJyZXBlYXRlZCIgcHJvdG9jb2wgbWVzc2FnZSBmaWVsZC4gIENsaWVudHMKKyAgY2FuIHVzZSB0aGlzIHByb3BlcnR5IHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkLCB3aGljaCB3aWxsIGJlIGVpdGhlciBhCisgIF9SZXBlYXRlZFNjYWxhckZpZWxkQ29udGFpbmVyIG9yIF9SZXBlYXRlZENvbXBvc2l0ZUZpZWxkQ29udGFpbmVyIChzZWUKKyAgYmVsb3cpLgorCisgIE5vdGUgdGhhdCB3aGVuIGNsaWVudHMgYWRkIHZhbHVlcyB0byB0aGVzZSBjb250YWluZXJzLCB3ZSBwZXJmb3JtCisgIHR5cGUtY2hlY2tpbmcgaW4gdGhlIGNhc2Ugb2YgcmVwZWF0ZWQgc2NhbGFyIGZpZWxkcywgYW5kIHdlIGFsc28gc2V0IGFueQorICBuZWNlc3NhcnkgImhhcyIgYml0cyBhcyBhIHNpZGUtZWZmZWN0LgorCisgIEFyZ3M6CisgICAgZmllbGQ6IEEgRmllbGREZXNjcmlwdG9yIGZvciB0aGlzIGZpZWxkLgorICAgIGNsczogVGhlIGNsYXNzIHdlJ3JlIGNvbnN0cnVjdGluZy4KKyAgIiIiCisgIHByb3RvX2ZpZWxkX25hbWUgPSBmaWVsZC5uYW1lCisgIHByb3BlcnR5X25hbWUgPSBfUHJvcGVydHlOYW1lKHByb3RvX2ZpZWxkX25hbWUpCisKKyAgZGVmIGdldHRlcihzZWxmKToKKyAgICBmaWVsZF92YWx1ZSA9IHNlbGYuX2ZpZWxkcy5nZXQoZmllbGQpCisgICAgaWYgZmllbGRfdmFsdWUgaXMgTm9uZToKKyAgICAgICMgQ29uc3RydWN0IGEgbmV3IG9iamVjdCB0byByZXByZXNlbnQgdGhpcyBmaWVsZC4KKyAgICAgIGZpZWxkX3ZhbHVlID0gZmllbGQuX2RlZmF1bHRfY29uc3RydWN0b3Ioc2VsZikKKworICAgICAgIyBBdG9taWNhbGx5IGNoZWNrIGlmIGFub3RoZXIgdGhyZWFkIGhhcyBwcmVlbXB0ZWQgdXMgYW5kLCBpZiBub3QsIHN3YXAKKyAgICAgICMgaW4gdGhlIG5ldyBvYmplY3Qgd2UganVzdCBjcmVhdGVkLiAgSWYgc29tZW9uZSBoYXMgcHJlZW1wdGVkIHVzLCB3ZQorICAgICAgIyB0YWtlIHRoYXQgb2JqZWN0IGFuZCBkaXNjYXJkIG91cnMuCisgICAgICAjIFdBUk5JTkc6ICBXZSBhcmUgcmVseWluZyBvbiBzZXRkZWZhdWx0KCkgYmVpbmcgYXRvbWljLiAgVGhpcyBpcyB0cnVlCisgICAgICAjICAgaW4gQ1B5dGhvbiBidXQgd2UgaGF2ZW4ndCBpbnZlc3RpZ2F0ZWQgb3RoZXJzLiAgVGhpcyB3YXJuaW5nIGFwcGVhcnMKKyAgICAgICMgICBpbiBzZXZlcmFsIG90aGVyIGxvY2F0aW9ucyBpbiB0aGlzIGZpbGUuCisgICAgICBmaWVsZF92YWx1ZSA9IHNlbGYuX2ZpZWxkcy5zZXRkZWZhdWx0KGZpZWxkLCBmaWVsZF92YWx1ZSkKKyAgICByZXR1cm4gZmllbGRfdmFsdWUKKyAgZ2V0dGVyLl9fbW9kdWxlX18gPSBOb25lCisgIGdldHRlci5fX2RvY19fID0gJ0dldHRlciBmb3IgJXMuJyAlIHByb3RvX2ZpZWxkX25hbWUKKworICAjIFdlIGRlZmluZSBhIHNldHRlciBqdXN0IHNvIHdlIGNhbiB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBhIG1vcmUKKyAgIyBoZWxwZnVsIGVycm9yIG1lc3NhZ2UuCisgIGRlZiBzZXR0ZXIoc2VsZiwgbmV3X3ZhbHVlKToKKyAgICByYWlzZSBBdHRyaWJ1dGVFcnJvcignQXNzaWdubWVudCBub3QgYWxsb3dlZCB0byByZXBlYXRlZCBmaWVsZCAnCisgICAgICAgICAgICAgICAgICAgICAgICAgJyIlcyIgaW4gcHJvdG9jb2wgbWVzc2FnZSBvYmplY3QuJyAlIHByb3RvX2ZpZWxkX25hbWUpCisKKyAgZG9jID0gJ01hZ2ljIGF0dHJpYnV0ZSBnZW5lcmF0ZWQgZm9yICIlcyIgcHJvdG8gZmllbGQuJyAlIHByb3RvX2ZpZWxkX25hbWUKKyAgc2V0YXR0cihjbHMsIHByb3BlcnR5X25hbWUsIHByb3BlcnR5KGdldHRlciwgc2V0dGVyLCBkb2M9ZG9jKSkKKworCitkZWYgX0FkZFByb3BlcnRpZXNGb3JOb25SZXBlYXRlZFNjYWxhckZpZWxkKGZpZWxkLCBjbHMpOgorICAiIiJBZGRzIGEgcHVibGljIHByb3BlcnR5IGZvciBhIG5vbnJlcGVhdGVkLCBzY2FsYXIgcHJvdG9jb2wgbWVzc2FnZSBmaWVsZC4KKyAgQ2xpZW50cyBjYW4gdXNlIHRoaXMgcHJvcGVydHkgdG8gZ2V0IGFuZCBkaXJlY3RseSBzZXQgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZC4KKyAgTm90ZSB0aGF0IHdoZW4gdGhlIGNsaWVudCBzZXRzIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGJ5IHVzaW5nIHRoaXMgcHJvcGVydHksCisgIGFsbCBuZWNlc3NhcnkgImhhcyIgYml0cyBhcmUgc2V0IGFzIGEgc2lkZS1lZmZlY3QsIGFuZCB3ZSBhbHNvIHBlcmZvcm0KKyAgdHlwZS1jaGVja2luZy4KKworICBBcmdzOgorICAgIGZpZWxkOiBBIEZpZWxkRGVzY3JpcHRvciBmb3IgdGhpcyBmaWVsZC4KKyAgICBjbHM6IFRoZSBjbGFzcyB3ZSdyZSBjb25zdHJ1Y3RpbmcuCisgICIiIgorICBwcm90b19maWVsZF9uYW1lID0gZmllbGQubmFtZQorICBwcm9wZXJ0eV9uYW1lID0gX1Byb3BlcnR5TmFtZShwcm90b19maWVsZF9uYW1lKQorICB0eXBlX2NoZWNrZXIgPSB0eXBlX2NoZWNrZXJzLkdldFR5cGVDaGVja2VyKGZpZWxkKQorICBkZWZhdWx0X3ZhbHVlID0gZmllbGQuZGVmYXVsdF92YWx1ZQorICB2YWxpZF92YWx1ZXMgPSBzZXQoKQorICBpc19wcm90bzMgPSBmaWVsZC5jb250YWluaW5nX3R5cGUuc3ludGF4ID09ICJwcm90bzMiCisKKyAgZGVmIGdldHRlcihzZWxmKToKKyAgICAjIFRPRE8ocHJvdG9idWYtdGVhbSk6IFRoaXMgbWF5IGJlIGJyb2tlbiBzaW5jZSB0aGVyZSBtYXkgbm90IGJlCisgICAgIyBkZWZhdWx0X3ZhbHVlLiAgQ29tYmluZSB3aXRoIGhhc19kZWZhdWx0X3ZhbHVlIHNvbWVob3cuCisgICAgcmV0dXJuIHNlbGYuX2ZpZWxkcy5nZXQoZmllbGQsIGRlZmF1bHRfdmFsdWUpCisgIGdldHRlci5fX21vZHVsZV9fID0gTm9uZQorICBnZXR0ZXIuX19kb2NfXyA9ICdHZXR0ZXIgZm9yICVzLicgJSBwcm90b19maWVsZF9uYW1lCisKKyAgY2xlYXJfd2hlbl9zZXRfdG9fZGVmYXVsdCA9IGlzX3Byb3RvMyBhbmQgbm90IGZpZWxkLmNvbnRhaW5pbmdfb25lb2YKKworICBkZWYgZmllbGRfc2V0dGVyKHNlbGYsIG5ld192YWx1ZSk6CisgICAgIyBweWxpbnQ6IGRpc2FibGU9cHJvdGVjdGVkLWFjY2VzcworICAgICMgVGVzdGluZyB0aGUgdmFsdWUgZm9yIHRydXRoaW5lc3MgY2FwdHVyZXMgYWxsIG9mIHRoZSBwcm90bzMgZGVmYXVsdHMKKyAgICAjICgwLCAwLjAsIGVudW0gMCwgYW5kIEZhbHNlKS4KKyAgICBuZXdfdmFsdWUgPSB0eXBlX2NoZWNrZXIuQ2hlY2tWYWx1ZShuZXdfdmFsdWUpCisgICAgaWYgY2xlYXJfd2hlbl9zZXRfdG9fZGVmYXVsdCBhbmQgbm90IG5ld192YWx1ZToKKyAgICAgIHNlbGYuX2ZpZWxkcy5wb3AoZmllbGQsIE5vbmUpCisgICAgZWxzZToKKyAgICAgIHNlbGYuX2ZpZWxkc1tmaWVsZF0gPSBuZXdfdmFsdWUKKyAgICAjIENoZWNrIF9jYWNoZWRfYnl0ZV9zaXplX2RpcnR5IGlubGluZSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLCBzaW5jZSBzY2FsYXIKKyAgICAjIHNldHRlcnMgYXJlIGNhbGxlZCBmcmVxdWVudGx5LgorICAgIGlmIG5vdCBzZWxmLl9jYWNoZWRfYnl0ZV9zaXplX2RpcnR5OgorICAgICAgc2VsZi5fTW9kaWZpZWQoKQorCisgIGlmIGZpZWxkLmNvbnRhaW5pbmdfb25lb2Y6CisgICAgZGVmIHNldHRlcihzZWxmLCBuZXdfdmFsdWUpOgorICAgICAgZmllbGRfc2V0dGVyKHNlbGYsIG5ld192YWx1ZSkKKyAgICAgIHNlbGYuX1VwZGF0ZU9uZW9mU3RhdGUoZmllbGQpCisgIGVsc2U6CisgICAgc2V0dGVyID0gZmllbGRfc2V0dGVyCisKKyAgc2V0dGVyLl9fbW9kdWxlX18gPSBOb25lCisgIHNldHRlci5fX2RvY19fID0gJ1NldHRlciBmb3IgJXMuJyAlIHByb3RvX2ZpZWxkX25hbWUKKworICAjIEFkZCBhIHByb3BlcnR5IHRvIGVuY2Fwc3VsYXRlIHRoZSBnZXR0ZXIvc2V0dGVyLgorICBkb2MgPSAnTWFnaWMgYXR0cmlidXRlIGdlbmVyYXRlZCBmb3IgIiVzIiBwcm90byBmaWVsZC4nICUgcHJvdG9fZmllbGRfbmFtZQorICBzZXRhdHRyKGNscywgcHJvcGVydHlfbmFtZSwgcHJvcGVydHkoZ2V0dGVyLCBzZXR0ZXIsIGRvYz1kb2MpKQorCisKK2RlZiBfQWRkUHJvcGVydGllc0Zvck5vblJlcGVhdGVkQ29tcG9zaXRlRmllbGQoZmllbGQsIGNscyk6CisgICIiIkFkZHMgYSBwdWJsaWMgcHJvcGVydHkgZm9yIGEgbm9ucmVwZWF0ZWQsIGNvbXBvc2l0ZSBwcm90b2NvbCBtZXNzYWdlIGZpZWxkLgorICBBIGNvbXBvc2l0ZSBmaWVsZCBpcyBhICJncm91cCIgb3IgIm1lc3NhZ2UiIGZpZWxkLgorCisgIENsaWVudHMgY2FuIHVzZSB0aGlzIHByb3BlcnR5IHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkLCBidXQgY2Fubm90CisgIGFzc2lnbiB0byB0aGUgcHJvcGVydHkgZGlyZWN0bHkuCisKKyAgQXJnczoKKyAgICBmaWVsZDogQSBGaWVsZERlc2NyaXB0b3IgZm9yIHRoaXMgZmllbGQuCisgICAgY2xzOiBUaGUgY2xhc3Mgd2UncmUgY29uc3RydWN0aW5nLgorICAiIiIKKyAgIyBUT0RPKHJvYmluc29uKTogUmVtb3ZlIGR1cGxpY2F0aW9uIHdpdGggc2ltaWxhciBtZXRob2QKKyAgIyBmb3Igbm9uLXJlcGVhdGVkIHNjYWxhcnMuCisgIHByb3RvX2ZpZWxkX25hbWUgPSBmaWVsZC5uYW1lCisgIHByb3BlcnR5X25hbWUgPSBfUHJvcGVydHlOYW1lKHByb3RvX2ZpZWxkX25hbWUpCisKKyAgIyBUT0RPKGtvbWFyZWspOiBDYW4gYW55b25lIGV4cGxhaW4gdG8gbWUgd2h5IHdlIGNhY2hlIHRoZSBtZXNzYWdlX3R5cGUgdGhpcworICAjIHdheSwgaW5zdGVhZCBvZiByZWZlcnJpbmcgdG8gZmllbGQubWVzc2FnZV90eXBlIGluc2lkZSBvZiBnZXR0ZXIoc2VsZik/CisgICMgV2hhdCBpZiBzb21lb25lIHNldHMgbWVzc2FnZV90eXBlIGxhdGVyIG9uICh3aGljaCBtYWtlcyBmb3Igc2ltcGxlcgorICAjIGR5YW5taWMgcHJvdG8gZGVzY3JpcHRvciBhbmQgY2xhc3MgY3JlYXRpb24gY29kZSkuCisgIG1lc3NhZ2VfdHlwZSA9IGZpZWxkLm1lc3NhZ2VfdHlwZQorCisgIGRlZiBnZXR0ZXIoc2VsZik6CisgICAgZmllbGRfdmFsdWUgPSBzZWxmLl9maWVsZHMuZ2V0KGZpZWxkKQorICAgIGlmIGZpZWxkX3ZhbHVlIGlzIE5vbmU6CisgICAgICAjIENvbnN0cnVjdCBhIG5ldyBvYmplY3QgdG8gcmVwcmVzZW50IHRoaXMgZmllbGQuCisgICAgICBmaWVsZF92YWx1ZSA9IG1lc3NhZ2VfdHlwZS5fY29uY3JldGVfY2xhc3MoKSAgIyB1c2UgZmllbGQubWVzc2FnZV90eXBlPworICAgICAgZmllbGRfdmFsdWUuX1NldExpc3RlbmVyKAorICAgICAgICAgIF9PbmVvZkxpc3RlbmVyKHNlbGYsIGZpZWxkKQorICAgICAgICAgIGlmIGZpZWxkLmNvbnRhaW5pbmdfb25lb2YgaXMgbm90IE5vbmUKKyAgICAgICAgICBlbHNlIHNlbGYuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbikKKworICAgICAgIyBBdG9taWNhbGx5IGNoZWNrIGlmIGFub3RoZXIgdGhyZWFkIGhhcyBwcmVlbXB0ZWQgdXMgYW5kLCBpZiBub3QsIHN3YXAKKyAgICAgICMgaW4gdGhlIG5ldyBvYmplY3Qgd2UganVzdCBjcmVhdGVkLiAgSWYgc29tZW9uZSBoYXMgcHJlZW1wdGVkIHVzLCB3ZQorICAgICAgIyB0YWtlIHRoYXQgb2JqZWN0IGFuZCBkaXNjYXJkIG91cnMuCisgICAgICAjIFdBUk5JTkc6ICBXZSBhcmUgcmVseWluZyBvbiBzZXRkZWZhdWx0KCkgYmVpbmcgYXRvbWljLiAgVGhpcyBpcyB0cnVlCisgICAgICAjICAgaW4gQ1B5dGhvbiBidXQgd2UgaGF2ZW4ndCBpbnZlc3RpZ2F0ZWQgb3RoZXJzLiAgVGhpcyB3YXJuaW5nIGFwcGVhcnMKKyAgICAgICMgICBpbiBzZXZlcmFsIG90aGVyIGxvY2F0aW9ucyBpbiB0aGlzIGZpbGUuCisgICAgICBmaWVsZF92YWx1ZSA9IHNlbGYuX2ZpZWxkcy5zZXRkZWZhdWx0KGZpZWxkLCBmaWVsZF92YWx1ZSkKKyAgICByZXR1cm4gZmllbGRfdmFsdWUKKyAgZ2V0dGVyLl9fbW9kdWxlX18gPSBOb25lCisgIGdldHRlci5fX2RvY19fID0gJ0dldHRlciBmb3IgJXMuJyAlIHByb3RvX2ZpZWxkX25hbWUKKworICAjIFdlIGRlZmluZSBhIHNldHRlciBqdXN0IHNvIHdlIGNhbiB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBhIG1vcmUKKyAgIyBoZWxwZnVsIGVycm9yIG1lc3NhZ2UuCisgIGRlZiBzZXR0ZXIoc2VsZiwgbmV3X3ZhbHVlKToKKyAgICByYWlzZSBBdHRyaWJ1dGVFcnJvcignQXNzaWdubWVudCBub3QgYWxsb3dlZCB0byBjb21wb3NpdGUgZmllbGQgJworICAgICAgICAgICAgICAgICAgICAgICAgICciJXMiIGluIHByb3RvY29sIG1lc3NhZ2Ugb2JqZWN0LicgJSBwcm90b19maWVsZF9uYW1lKQorCisgICMgQWRkIGEgcHJvcGVydHkgdG8gZW5jYXBzdWxhdGUgdGhlIGdldHRlci4KKyAgZG9jID0gJ01hZ2ljIGF0dHJpYnV0ZSBnZW5lcmF0ZWQgZm9yICIlcyIgcHJvdG8gZmllbGQuJyAlIHByb3RvX2ZpZWxkX25hbWUKKyAgc2V0YXR0cihjbHMsIHByb3BlcnR5X25hbWUsIHByb3BlcnR5KGdldHRlciwgc2V0dGVyLCBkb2M9ZG9jKSkKKworCitkZWYgX0FkZFByb3BlcnRpZXNGb3JFeHRlbnNpb25zKGRlc2NyaXB0b3IsIGNscyk6CisgICIiIkFkZHMgcHJvcGVydGllcyBmb3IgYWxsIGZpZWxkcyBpbiB0aGlzIHByb3RvY29sIG1lc3NhZ2UgdHlwZS4iIiIKKyAgZXh0ZW5zaW9uX2RpY3QgPSBkZXNjcmlwdG9yLmV4dGVuc2lvbnNfYnlfbmFtZQorICBmb3IgZXh0ZW5zaW9uX25hbWUsIGV4dGVuc2lvbl9maWVsZCBpbiBleHRlbnNpb25fZGljdC5pdGVyaXRlbXMoKToKKyAgICBjb25zdGFudF9uYW1lID0gZXh0ZW5zaW9uX25hbWUudXBwZXIoKSArICJfRklFTERfTlVNQkVSIgorICAgIHNldGF0dHIoY2xzLCBjb25zdGFudF9uYW1lLCBleHRlbnNpb25fZmllbGQubnVtYmVyKQorCisKK2RlZiBfQWRkU3RhdGljTWV0aG9kcyhjbHMpOgorICAjIFRPRE8ocm9iaW5zb24pOiBUaGlzIHByb2JhYmx5IG5lZWRzIHRvIGJlIHRocmVhZC1zYWZlKD8pCisgIGRlZiBSZWdpc3RlckV4dGVuc2lvbihleHRlbnNpb25faGFuZGxlKToKKyAgICBleHRlbnNpb25faGFuZGxlLmNvbnRhaW5pbmdfdHlwZSA9IGNscy5ERVNDUklQVE9SCisgICAgX0F0dGFjaEZpZWxkSGVscGVycyhjbHMsIGV4dGVuc2lvbl9oYW5kbGUpCisKKyAgICAjIFRyeSB0byBpbnNlcnQgb3VyIGV4dGVuc2lvbiwgZmFpbGluZyBpZiBhbiBleHRlbnNpb24gd2l0aCB0aGUgc2FtZSBudW1iZXIKKyAgICAjIGFscmVhZHkgZXhpc3RzLgorICAgIGFjdHVhbF9oYW5kbGUgPSBjbHMuX2V4dGVuc2lvbnNfYnlfbnVtYmVyLnNldGRlZmF1bHQoCisgICAgICAgIGV4dGVuc2lvbl9oYW5kbGUubnVtYmVyLCBleHRlbnNpb25faGFuZGxlKQorICAgIGlmIGFjdHVhbF9oYW5kbGUgaXMgbm90IGV4dGVuc2lvbl9oYW5kbGU6CisgICAgICByYWlzZSBBc3NlcnRpb25FcnJvcigKKyAgICAgICAgICAnRXh0ZW5zaW9ucyAiJXMiIGFuZCAiJXMiIGJvdGggdHJ5IHRvIGV4dGVuZCBtZXNzYWdlIHR5cGUgIiVzIiB3aXRoICcKKyAgICAgICAgICAnZmllbGQgbnVtYmVyICVkLicgJQorICAgICAgICAgIChleHRlbnNpb25faGFuZGxlLmZ1bGxfbmFtZSwgYWN0dWFsX2hhbmRsZS5mdWxsX25hbWUsCisgICAgICAgICAgIGNscy5ERVNDUklQVE9SLmZ1bGxfbmFtZSwgZXh0ZW5zaW9uX2hhbmRsZS5udW1iZXIpKQorCisgICAgY2xzLl9leHRlbnNpb25zX2J5X25hbWVbZXh0ZW5zaW9uX2hhbmRsZS5mdWxsX25hbWVdID0gZXh0ZW5zaW9uX2hhbmRsZQorCisgICAgaGFuZGxlID0gZXh0ZW5zaW9uX2hhbmRsZSAgIyBhdm9pZCBsaW5lIHdyYXBwaW5nCisgICAgaWYgX0lzTWVzc2FnZVNldEV4dGVuc2lvbihoYW5kbGUpOgorICAgICAgIyBNZXNzYWdlU2V0IGV4dGVuc2lvbi4gIEFsc28gcmVnaXN0ZXIgdW5kZXIgdHlwZSBuYW1lLgorICAgICAgY2xzLl9leHRlbnNpb25zX2J5X25hbWVbCisgICAgICAgICAgZXh0ZW5zaW9uX2hhbmRsZS5tZXNzYWdlX3R5cGUuZnVsbF9uYW1lXSA9IGV4dGVuc2lvbl9oYW5kbGUKKworICBjbHMuUmVnaXN0ZXJFeHRlbnNpb24gPSBzdGF0aWNtZXRob2QoUmVnaXN0ZXJFeHRlbnNpb24pCisKKyAgZGVmIEZyb21TdHJpbmcocyk6CisgICAgbWVzc2FnZSA9IGNscygpCisgICAgbWVzc2FnZS5NZXJnZUZyb21TdHJpbmcocykKKyAgICByZXR1cm4gbWVzc2FnZQorICBjbHMuRnJvbVN0cmluZyA9IHN0YXRpY21ldGhvZChGcm9tU3RyaW5nKQorCisKK2RlZiBfSXNQcmVzZW50KGl0ZW0pOgorICAiIiJHaXZlbiBhIChGaWVsZERlc2NyaXB0b3IsIHZhbHVlKSB0dXBsZSBmcm9tIF9maWVsZHMsIHJldHVybiB0cnVlIGlmIHRoZQorICB2YWx1ZSBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIGxpc3QgcmV0dXJuZWQgYnkgTGlzdEZpZWxkcygpLiIiIgorCisgIGlmIGl0ZW1bMF0ubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICByZXR1cm4gYm9vbChpdGVtWzFdKQorICBlbGlmIGl0ZW1bMF0uY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgcmV0dXJuIGl0ZW1bMV0uX2lzX3ByZXNlbnRfaW5fcGFyZW50CisgIGVsc2U6CisgICAgcmV0dXJuIFRydWUKKworCitkZWYgX0FkZExpc3RGaWVsZHNNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJIZWxwZXIgZm9yIF9BZGRNZXNzYWdlTWV0aG9kcygpLiIiIgorCisgIGRlZiBMaXN0RmllbGRzKHNlbGYpOgorICAgIGFsbF9maWVsZHMgPSBbaXRlbSBmb3IgaXRlbSBpbiBzZWxmLl9maWVsZHMuaXRlcml0ZW1zKCkgaWYgX0lzUHJlc2VudChpdGVtKV0KKyAgICBhbGxfZmllbGRzLnNvcnQoa2V5ID0gbGFtYmRhIGl0ZW06IGl0ZW1bMF0ubnVtYmVyKQorICAgIHJldHVybiBhbGxfZmllbGRzCisKKyAgY2xzLkxpc3RGaWVsZHMgPSBMaXN0RmllbGRzCisKK19Qcm90bzNIYXNFcnJvciA9ICdQcm90b2NvbCBtZXNzYWdlIGhhcyBubyBub24tcmVwZWF0ZWQgc3VibWVzc2FnZSBmaWVsZCAiJXMiJworX1Byb3RvMkhhc0Vycm9yID0gJ1Byb3RvY29sIG1lc3NhZ2UgaGFzIG5vIG5vbi1yZXBlYXRlZCBmaWVsZCAiJXMiJworCitkZWYgX0FkZEhhc0ZpZWxkTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKToKKyAgIiIiSGVscGVyIGZvciBfQWRkTWVzc2FnZU1ldGhvZHMoKS4iIiIKKworICBpc19wcm90bzMgPSAobWVzc2FnZV9kZXNjcmlwdG9yLnN5bnRheCA9PSAicHJvdG8zIikKKyAgZXJyb3JfbXNnID0gX1Byb3RvM0hhc0Vycm9yIGlmIGlzX3Byb3RvMyBlbHNlIF9Qcm90bzJIYXNFcnJvcgorCisgIGhhc3NhYmxlX2ZpZWxkcyA9IHt9CisgIGZvciBmaWVsZCBpbiBtZXNzYWdlX2Rlc2NyaXB0b3IuZmllbGRzOgorICAgIGlmIGZpZWxkLmxhYmVsID09IF9GaWVsZERlc2NyaXB0b3IuTEFCRUxfUkVQRUFURUQ6CisgICAgICBjb250aW51ZQorICAgICMgRm9yIHByb3RvMywgb25seSBzdWJtZXNzYWdlcyBhbmQgZmllbGRzIGluc2lkZSBhIG9uZW9mIGhhdmUgcHJlc2VuY2UuCisgICAgaWYgKGlzX3Byb3RvMyBhbmQgZmllbGQuY3BwX3R5cGUgIT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0UgYW5kCisgICAgICAgIG5vdCBmaWVsZC5jb250YWluaW5nX29uZW9mKToKKyAgICAgIGNvbnRpbnVlCisgICAgaGFzc2FibGVfZmllbGRzW2ZpZWxkLm5hbWVdID0gZmllbGQKKworICBpZiBub3QgaXNfcHJvdG8zOgorICAgICMgRmllbGRzIGluc2lkZSBvbmVvZnMgYXJlIG5ldmVyIHJlcGVhdGVkIChlbmZvcmNlZCBieSB0aGUgY29tcGlsZXIpLgorICAgIGZvciBvbmVvZiBpbiBtZXNzYWdlX2Rlc2NyaXB0b3Iub25lb2ZzOgorICAgICAgaGFzc2FibGVfZmllbGRzW29uZW9mLm5hbWVdID0gb25lb2YKKworICBkZWYgSGFzRmllbGQoc2VsZiwgZmllbGRfbmFtZSk6CisgICAgdHJ5OgorICAgICAgZmllbGQgPSBoYXNzYWJsZV9maWVsZHNbZmllbGRfbmFtZV0KKyAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICByYWlzZSBWYWx1ZUVycm9yKGVycm9yX21zZyAlIGZpZWxkX25hbWUpCisKKyAgICBpZiBpc2luc3RhbmNlKGZpZWxkLCBkZXNjcmlwdG9yX21vZC5PbmVvZkRlc2NyaXB0b3IpOgorICAgICAgdHJ5OgorICAgICAgICByZXR1cm4gSGFzRmllbGQoc2VsZiwgc2VsZi5fb25lb2ZzW2ZpZWxkXS5uYW1lKQorICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICByZXR1cm4gRmFsc2UKKyAgICBlbHNlOgorICAgICAgaWYgZmllbGQuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHZhbHVlID0gc2VsZi5fZmllbGRzLmdldChmaWVsZCkKKyAgICAgICAgcmV0dXJuIHZhbHVlIGlzIG5vdCBOb25lIGFuZCB2YWx1ZS5faXNfcHJlc2VudF9pbl9wYXJlbnQKKyAgICAgIGVsc2U6CisgICAgICAgIHJldHVybiBmaWVsZCBpbiBzZWxmLl9maWVsZHMKKworICBjbHMuSGFzRmllbGQgPSBIYXNGaWVsZAorCisKK2RlZiBfQWRkQ2xlYXJGaWVsZE1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkhlbHBlciBmb3IgX0FkZE1lc3NhZ2VNZXRob2RzKCkuIiIiCisgIGRlZiBDbGVhckZpZWxkKHNlbGYsIGZpZWxkX25hbWUpOgorICAgIHRyeToKKyAgICAgIGZpZWxkID0gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lW2ZpZWxkX25hbWVdCisgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgdHJ5OgorICAgICAgICBmaWVsZCA9IG1lc3NhZ2VfZGVzY3JpcHRvci5vbmVvZnNfYnlfbmFtZVtmaWVsZF9uYW1lXQorICAgICAgICBpZiBmaWVsZCBpbiBzZWxmLl9vbmVvZnM6CisgICAgICAgICAgZmllbGQgPSBzZWxmLl9vbmVvZnNbZmllbGRdCisgICAgICAgIGVsc2U6CisgICAgICAgICAgcmV0dXJuCisgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ1Byb3RvY29sIG1lc3NhZ2UgaGFzIG5vICIlcyIgZmllbGQuJyAlIGZpZWxkX25hbWUpCisKKyAgICBpZiBmaWVsZCBpbiBzZWxmLl9maWVsZHM6CisgICAgICAjIE5vdGU6ICBJZiB0aGUgZmllbGQgaXMgYSBzdWItbWVzc2FnZSwgaXRzIGxpc3RlbmVyIHdpbGwgc3RpbGwgcG9pbnQKKyAgICAgICMgICBhdCB1cy4gIFRoYXQncyBmaW5lLCBiZWNhdXNlIHRoZSB3b3JzdCB0aGFuIGNhbiBoYXBwZW4gaXMgdGhhdCBpdAorICAgICAgIyAgIHdpbGwgY2FsbCBfTW9kaWZpZWQoKSBhbmQgaW52YWxpZGF0ZSBvdXIgYnl0ZSBzaXplLiAgQmlnIGRlYWwuCisgICAgICBkZWwgc2VsZi5fZmllbGRzW2ZpZWxkXQorCisgICAgICBpZiBzZWxmLl9vbmVvZnMuZ2V0KGZpZWxkLmNvbnRhaW5pbmdfb25lb2YsIE5vbmUpIGlzIGZpZWxkOgorICAgICAgICBkZWwgc2VsZi5fb25lb2ZzW2ZpZWxkLmNvbnRhaW5pbmdfb25lb2ZdCisKKyAgICAjIEFsd2F5cyBjYWxsIF9Nb2RpZmllZCgpIC0tIGV2ZW4gaWYgbm90aGluZyB3YXMgY2hhbmdlZCwgdGhpcyBpcworICAgICMgYSBtdXRhdGluZyBtZXRob2QsIGFuZCB0aHVzIGNhbGxpbmcgaXQgc2hvdWxkIGNhdXNlIHRoZSBmaWVsZCB0byBiZWNvbWUKKyAgICAjIHByZXNlbnQgaW4gdGhlIHBhcmVudCBtZXNzYWdlLgorICAgIHNlbGYuX01vZGlmaWVkKCkKKworICBjbHMuQ2xlYXJGaWVsZCA9IENsZWFyRmllbGQKKworCitkZWYgX0FkZENsZWFyRXh0ZW5zaW9uTWV0aG9kKGNscyk6CisgICIiIkhlbHBlciBmb3IgX0FkZE1lc3NhZ2VNZXRob2RzKCkuIiIiCisgIGRlZiBDbGVhckV4dGVuc2lvbihzZWxmLCBleHRlbnNpb25faGFuZGxlKToKKyAgICBfVmVyaWZ5RXh0ZW5zaW9uSGFuZGxlKHNlbGYsIGV4dGVuc2lvbl9oYW5kbGUpCisKKyAgICAjIFNpbWlsYXIgdG8gQ2xlYXJGaWVsZCgpLCBhYm92ZS4KKyAgICBpZiBleHRlbnNpb25faGFuZGxlIGluIHNlbGYuX2ZpZWxkczoKKyAgICAgIGRlbCBzZWxmLl9maWVsZHNbZXh0ZW5zaW9uX2hhbmRsZV0KKyAgICBzZWxmLl9Nb2RpZmllZCgpCisgIGNscy5DbGVhckV4dGVuc2lvbiA9IENsZWFyRXh0ZW5zaW9uCisKKworZGVmIF9BZGRDbGVhck1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkhlbHBlciBmb3IgX0FkZE1lc3NhZ2VNZXRob2RzKCkuIiIiCisgIGRlZiBDbGVhcihzZWxmKToKKyAgICAjIENsZWFyIGZpZWxkcy4KKyAgICBzZWxmLl9maWVsZHMgPSB7fQorICAgIHNlbGYuX3Vua25vd25fZmllbGRzID0gKCkKKyAgICBzZWxmLl9vbmVvZnMgPSB7fQorICAgIHNlbGYuX01vZGlmaWVkKCkKKyAgY2xzLkNsZWFyID0gQ2xlYXIKKworCitkZWYgX0FkZEhhc0V4dGVuc2lvbk1ldGhvZChjbHMpOgorICAiIiJIZWxwZXIgZm9yIF9BZGRNZXNzYWdlTWV0aG9kcygpLiIiIgorICBkZWYgSGFzRXh0ZW5zaW9uKHNlbGYsIGV4dGVuc2lvbl9oYW5kbGUpOgorICAgIF9WZXJpZnlFeHRlbnNpb25IYW5kbGUoc2VsZiwgZXh0ZW5zaW9uX2hhbmRsZSkKKyAgICBpZiBleHRlbnNpb25faGFuZGxlLmxhYmVsID09IF9GaWVsZERlc2NyaXB0b3IuTEFCRUxfUkVQRUFURUQ6CisgICAgICByYWlzZSBLZXlFcnJvcignIiVzIiBpcyByZXBlYXRlZC4nICUgZXh0ZW5zaW9uX2hhbmRsZS5mdWxsX25hbWUpCisKKyAgICBpZiBleHRlbnNpb25faGFuZGxlLmNwcF90eXBlID09IF9GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9NRVNTQUdFOgorICAgICAgdmFsdWUgPSBzZWxmLl9maWVsZHMuZ2V0KGV4dGVuc2lvbl9oYW5kbGUpCisgICAgICByZXR1cm4gdmFsdWUgaXMgbm90IE5vbmUgYW5kIHZhbHVlLl9pc19wcmVzZW50X2luX3BhcmVudAorICAgIGVsc2U6CisgICAgICByZXR1cm4gZXh0ZW5zaW9uX2hhbmRsZSBpbiBzZWxmLl9maWVsZHMKKyAgY2xzLkhhc0V4dGVuc2lvbiA9IEhhc0V4dGVuc2lvbgorCisKK2RlZiBfQWRkRXF1YWxzTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKToKKyAgIiIiSGVscGVyIGZvciBfQWRkTWVzc2FnZU1ldGhvZHMoKS4iIiIKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgaWYgKG5vdCBpc2luc3RhbmNlKG90aGVyLCBtZXNzYWdlX21vZC5NZXNzYWdlKSBvcgorICAgICAgICBvdGhlci5ERVNDUklQVE9SICE9IHNlbGYuREVTQ1JJUFRPUik6CisgICAgICByZXR1cm4gRmFsc2UKKworICAgIGlmIHNlbGYgaXMgb3RoZXI6CisgICAgICByZXR1cm4gVHJ1ZQorCisgICAgaWYgbm90IHNlbGYuTGlzdEZpZWxkcygpID09IG90aGVyLkxpc3RGaWVsZHMoKToKKyAgICAgIHJldHVybiBGYWxzZQorCisgICAgIyBTb3J0IHVua25vd24gZmllbGRzIGJlY2F1c2UgdGhlaXIgb3JkZXIgc2hvdWxkbid0IGFmZmVjdCBlcXVhbGl0eSB0ZXN0LgorICAgIHVua25vd25fZmllbGRzID0gbGlzdChzZWxmLl91bmtub3duX2ZpZWxkcykKKyAgICB1bmtub3duX2ZpZWxkcy5zb3J0KCkKKyAgICBvdGhlcl91bmtub3duX2ZpZWxkcyA9IGxpc3Qob3RoZXIuX3Vua25vd25fZmllbGRzKQorICAgIG90aGVyX3Vua25vd25fZmllbGRzLnNvcnQoKQorCisgICAgcmV0dXJuIHVua25vd25fZmllbGRzID09IG90aGVyX3Vua25vd25fZmllbGRzCisKKyAgY2xzLl9fZXFfXyA9IF9fZXFfXworCisKK2RlZiBfQWRkU3RyTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKToKKyAgIiIiSGVscGVyIGZvciBfQWRkTWVzc2FnZU1ldGhvZHMoKS4iIiIKKyAgZGVmIF9fc3RyX18oc2VsZik6CisgICAgcmV0dXJuIHRleHRfZm9ybWF0Lk1lc3NhZ2VUb1N0cmluZyhzZWxmKQorICBjbHMuX19zdHJfXyA9IF9fc3RyX18KKworCitkZWYgX0FkZFVuaWNvZGVNZXRob2QodW51c2VkX21lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKToKKyAgIiIiSGVscGVyIGZvciBfQWRkTWVzc2FnZU1ldGhvZHMoKS4iIiIKKworICBkZWYgX191bmljb2RlX18oc2VsZik6CisgICAgcmV0dXJuIHRleHRfZm9ybWF0Lk1lc3NhZ2VUb1N0cmluZyhzZWxmLCBhc191dGY4PVRydWUpLmRlY29kZSgndXRmLTgnKQorICBjbHMuX191bmljb2RlX18gPSBfX3VuaWNvZGVfXworCisKK2RlZiBfQWRkU2V0TGlzdGVuZXJNZXRob2QoY2xzKToKKyAgIiIiSGVscGVyIGZvciBfQWRkTWVzc2FnZU1ldGhvZHMoKS4iIiIKKyAgZGVmIFNldExpc3RlbmVyKHNlbGYsIGxpc3RlbmVyKToKKyAgICBpZiBsaXN0ZW5lciBpcyBOb25lOgorICAgICAgc2VsZi5fbGlzdGVuZXIgPSBtZXNzYWdlX2xpc3RlbmVyX21vZC5OdWxsTWVzc2FnZUxpc3RlbmVyKCkKKyAgICBlbHNlOgorICAgICAgc2VsZi5fbGlzdGVuZXIgPSBsaXN0ZW5lcgorICBjbHMuX1NldExpc3RlbmVyID0gU2V0TGlzdGVuZXIKKworCitkZWYgX0J5dGVzRm9yTm9uUmVwZWF0ZWRFbGVtZW50KHZhbHVlLCBmaWVsZF9udW1iZXIsIGZpZWxkX3R5cGUpOgorICAiIiJSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIHRvIHNlcmlhbGl6ZSBhIG5vbi1yZXBlYXRlZCBlbGVtZW50LgorICBUaGUgcmV0dXJuZWQgYnl0ZSBjb3VudCBpbmNsdWRlcyBzcGFjZSBmb3IgdGFnIGluZm9ybWF0aW9uIGFuZCBhbnkKKyAgb3RoZXIgYWRkaXRpb25hbCBzcGFjZSBhc3NvY2lhdGVkIHdpdGggc2VyaWFsaXppbmcgdmFsdWUuCisKKyAgQXJnczoKKyAgICB2YWx1ZTogVmFsdWUgd2UncmUgc2VyaWFsaXppbmcuCisgICAgZmllbGRfbnVtYmVyOiBGaWVsZCBudW1iZXIgb2YgdGhpcyB2YWx1ZS4gIChTaW5jZSB0aGUgZmllbGQgbnVtYmVyCisgICAgICBpcyBzdG9yZWQgYXMgcGFydCBvZiBhIHZhcmludC1lbmNvZGVkIHRhZywgdGhpcyBoYXMgYW4gaW1wYWN0CisgICAgICBvbiB0aGUgdG90YWwgYnl0ZXMgcmVxdWlyZWQgdG8gc2VyaWFsaXplIHRoZSB2YWx1ZSkuCisgICAgZmllbGRfdHlwZTogVGhlIHR5cGUgb2YgdGhlIGZpZWxkLiAgT25lIG9mIHRoZSBUWVBFXyogY29uc3RhbnRzCisgICAgICB3aXRoaW4gRmllbGREZXNjcmlwdG9yLgorICAiIiIKKyAgdHJ5OgorICAgIGZuID0gdHlwZV9jaGVja2Vycy5UWVBFX1RPX0JZVEVfU0laRV9GTltmaWVsZF90eXBlXQorICAgIHJldHVybiBmbihmaWVsZF9udW1iZXIsIHZhbHVlKQorICBleGNlcHQgS2V5RXJyb3I6CisgICAgcmFpc2UgbWVzc2FnZV9tb2QuRW5jb2RlRXJyb3IoJ1VucmVjb2duaXplZCBmaWVsZCB0eXBlOiAlZCcgJSBmaWVsZF90eXBlKQorCisKK2RlZiBfQWRkQnl0ZVNpemVNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJIZWxwZXIgZm9yIF9BZGRNZXNzYWdlTWV0aG9kcygpLiIiIgorCisgIGRlZiBCeXRlU2l6ZShzZWxmKToKKyAgICBpZiBub3Qgc2VsZi5fY2FjaGVkX2J5dGVfc2l6ZV9kaXJ0eToKKyAgICAgIHJldHVybiBzZWxmLl9jYWNoZWRfYnl0ZV9zaXplCisKKyAgICBzaXplID0gMAorICAgIGZvciBmaWVsZF9kZXNjcmlwdG9yLCBmaWVsZF92YWx1ZSBpbiBzZWxmLkxpc3RGaWVsZHMoKToKKyAgICAgIHNpemUgKz0gZmllbGRfZGVzY3JpcHRvci5fc2l6ZXIoZmllbGRfdmFsdWUpCisKKyAgICBmb3IgdGFnX2J5dGVzLCB2YWx1ZV9ieXRlcyBpbiBzZWxmLl91bmtub3duX2ZpZWxkczoKKyAgICAgIHNpemUgKz0gbGVuKHRhZ19ieXRlcykgKyBsZW4odmFsdWVfYnl0ZXMpCisKKyAgICBzZWxmLl9jYWNoZWRfYnl0ZV9zaXplID0gc2l6ZQorICAgIHNlbGYuX2NhY2hlZF9ieXRlX3NpemVfZGlydHkgPSBGYWxzZQorICAgIHNlbGYuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbi5kaXJ0eSA9IEZhbHNlCisgICAgcmV0dXJuIHNpemUKKworICBjbHMuQnl0ZVNpemUgPSBCeXRlU2l6ZQorCisKK2RlZiBfQWRkU2VyaWFsaXplVG9TdHJpbmdNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJIZWxwZXIgZm9yIF9BZGRNZXNzYWdlTWV0aG9kcygpLiIiIgorCisgIGRlZiBTZXJpYWxpemVUb1N0cmluZyhzZWxmKToKKyAgICAjIENoZWNrIGlmIHRoZSBtZXNzYWdlIGhhcyBhbGwgb2YgaXRzIHJlcXVpcmVkIGZpZWxkcyBzZXQuCisgICAgZXJyb3JzID0gW10KKyAgICBpZiBub3Qgc2VsZi5Jc0luaXRpYWxpemVkKCk6CisgICAgICByYWlzZSBtZXNzYWdlX21vZC5FbmNvZGVFcnJvcigKKyAgICAgICAgICAnTWVzc2FnZSAlcyBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogJXMnICUgKAorICAgICAgICAgIHNlbGYuREVTQ1JJUFRPUi5mdWxsX25hbWUsICcsJy5qb2luKHNlbGYuRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCkpKSkKKyAgICByZXR1cm4gc2VsZi5TZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmcoKQorICBjbHMuU2VyaWFsaXplVG9TdHJpbmcgPSBTZXJpYWxpemVUb1N0cmluZworCisKK2RlZiBfQWRkU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKToKKyAgIiIiSGVscGVyIGZvciBfQWRkTWVzc2FnZU1ldGhvZHMoKS4iIiIKKworICBkZWYgU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKHNlbGYpOgorICAgIG91dCA9IEJ5dGVzSU8oKQorICAgIHNlbGYuX0ludGVybmFsU2VyaWFsaXplKG91dC53cml0ZSkKKyAgICByZXR1cm4gb3V0LmdldHZhbHVlKCkKKyAgY2xzLlNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyA9IFNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZworCisgIGRlZiBJbnRlcm5hbFNlcmlhbGl6ZShzZWxmLCB3cml0ZV9ieXRlcyk6CisgICAgZm9yIGZpZWxkX2Rlc2NyaXB0b3IsIGZpZWxkX3ZhbHVlIGluIHNlbGYuTGlzdEZpZWxkcygpOgorICAgICAgZmllbGRfZGVzY3JpcHRvci5fZW5jb2Rlcih3cml0ZV9ieXRlcywgZmllbGRfdmFsdWUpCisgICAgZm9yIHRhZ19ieXRlcywgdmFsdWVfYnl0ZXMgaW4gc2VsZi5fdW5rbm93bl9maWVsZHM6CisgICAgICB3cml0ZV9ieXRlcyh0YWdfYnl0ZXMpCisgICAgICB3cml0ZV9ieXRlcyh2YWx1ZV9ieXRlcykKKyAgY2xzLl9JbnRlcm5hbFNlcmlhbGl6ZSA9IEludGVybmFsU2VyaWFsaXplCisKKworZGVmIF9BZGRNZXJnZUZyb21TdHJpbmdNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJIZWxwZXIgZm9yIF9BZGRNZXNzYWdlTWV0aG9kcygpLiIiIgorICBkZWYgTWVyZ2VGcm9tU3RyaW5nKHNlbGYsIHNlcmlhbGl6ZWQpOgorICAgIGxlbmd0aCA9IGxlbihzZXJpYWxpemVkKQorICAgIHRyeToKKyAgICAgIGlmIHNlbGYuX0ludGVybmFsUGFyc2Uoc2VyaWFsaXplZCwgMCwgbGVuZ3RoKSAhPSBsZW5ndGg6CisgICAgICAgICMgVGhlIG9ubHkgcmVhc29uIF9JbnRlcm5hbFBhcnNlIHdvdWxkIHJldHVybiBlYXJseSBpcyBpZiBpdAorICAgICAgICAjIGVuY291bnRlcmVkIGFuIGVuZC1ncm91cCB0YWcuCisgICAgICAgIHJhaXNlIG1lc3NhZ2VfbW9kLkRlY29kZUVycm9yKCdVbmV4cGVjdGVkIGVuZC1ncm91cCB0YWcuJykKKyAgICBleGNlcHQgKEluZGV4RXJyb3IsIFR5cGVFcnJvcik6CisgICAgICAjIE5vdyBvcmQoYnVmW3A6cCsxXSkgPT0gb3JkKCcnKSBnZXRzIFR5cGVFcnJvci4KKyAgICAgIHJhaXNlIG1lc3NhZ2VfbW9kLkRlY29kZUVycm9yKCdUcnVuY2F0ZWQgbWVzc2FnZS4nKQorICAgIGV4Y2VwdCBzdHJ1Y3QuZXJyb3IsIGU6CisgICAgICByYWlzZSBtZXNzYWdlX21vZC5EZWNvZGVFcnJvcihlKQorICAgIHJldHVybiBsZW5ndGggICAjIFJldHVybiB0aGlzIGZvciBsZWdhY3kgcmVhc29ucy4KKyAgY2xzLk1lcmdlRnJvbVN0cmluZyA9IE1lcmdlRnJvbVN0cmluZworCisgIGxvY2FsX1JlYWRUYWcgPSBkZWNvZGVyLlJlYWRUYWcKKyAgbG9jYWxfU2tpcEZpZWxkID0gZGVjb2Rlci5Ta2lwRmllbGQKKyAgZGVjb2RlcnNfYnlfdGFnID0gY2xzLl9kZWNvZGVyc19ieV90YWcKKyAgaXNfcHJvdG8zID0gbWVzc2FnZV9kZXNjcmlwdG9yLnN5bnRheCA9PSAicHJvdG8zIgorCisgIGRlZiBJbnRlcm5hbFBhcnNlKHNlbGYsIGJ1ZmZlciwgcG9zLCBlbmQpOgorICAgIHNlbGYuX01vZGlmaWVkKCkKKyAgICBmaWVsZF9kaWN0ID0gc2VsZi5fZmllbGRzCisgICAgdW5rbm93bl9maWVsZF9saXN0ID0gc2VsZi5fdW5rbm93bl9maWVsZHMKKyAgICB3aGlsZSBwb3MgIT0gZW5kOgorICAgICAgKHRhZ19ieXRlcywgbmV3X3BvcykgPSBsb2NhbF9SZWFkVGFnKGJ1ZmZlciwgcG9zKQorICAgICAgZmllbGRfZGVjb2RlciwgZmllbGRfZGVzYyA9IGRlY29kZXJzX2J5X3RhZy5nZXQodGFnX2J5dGVzLCAoTm9uZSwgTm9uZSkpCisgICAgICBpZiBmaWVsZF9kZWNvZGVyIGlzIE5vbmU6CisgICAgICAgIHZhbHVlX3N0YXJ0X3BvcyA9IG5ld19wb3MKKyAgICAgICAgbmV3X3BvcyA9IGxvY2FsX1NraXBGaWVsZChidWZmZXIsIG5ld19wb3MsIGVuZCwgdGFnX2J5dGVzKQorICAgICAgICBpZiBuZXdfcG9zID09IC0xOgorICAgICAgICAgIHJldHVybiBwb3MKKyAgICAgICAgaWYgbm90IGlzX3Byb3RvMzoKKyAgICAgICAgICBpZiBub3QgdW5rbm93bl9maWVsZF9saXN0OgorICAgICAgICAgICAgdW5rbm93bl9maWVsZF9saXN0ID0gc2VsZi5fdW5rbm93bl9maWVsZHMgPSBbXQorICAgICAgICAgIHVua25vd25fZmllbGRfbGlzdC5hcHBlbmQoCisgICAgICAgICAgICAgICh0YWdfYnl0ZXMsIGJ1ZmZlclt2YWx1ZV9zdGFydF9wb3M6bmV3X3Bvc10pKQorICAgICAgICBwb3MgPSBuZXdfcG9zCisgICAgICBlbHNlOgorICAgICAgICBwb3MgPSBmaWVsZF9kZWNvZGVyKGJ1ZmZlciwgbmV3X3BvcywgZW5kLCBzZWxmLCBmaWVsZF9kaWN0KQorICAgICAgICBpZiBmaWVsZF9kZXNjOgorICAgICAgICAgIHNlbGYuX1VwZGF0ZU9uZW9mU3RhdGUoZmllbGRfZGVzYykKKyAgICByZXR1cm4gcG9zCisgIGNscy5fSW50ZXJuYWxQYXJzZSA9IEludGVybmFsUGFyc2UKKworCitkZWYgX0FkZElzSW5pdGlhbGl6ZWRNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJBZGRzIHRoZSBJc0luaXRpYWxpemVkIGFuZCBGaW5kSW5pdGlhbGl6YXRpb25FcnJvciBtZXRob2RzIHRvIHRoZQorICBwcm90b2NvbCBtZXNzYWdlIGNsYXNzLiIiIgorCisgIHJlcXVpcmVkX2ZpZWxkcyA9IFtmaWVsZCBmb3IgZmllbGQgaW4gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkcworICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmllbGQubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVFVSVJFRF0KKworICBkZWYgSXNJbml0aWFsaXplZChzZWxmLCBlcnJvcnM9Tm9uZSk6CisgICAgIiIiQ2hlY2tzIGlmIGFsbCByZXF1aXJlZCBmaWVsZHMgb2YgYSBtZXNzYWdlIGFyZSBzZXQuCisKKyAgICBBcmdzOgorICAgICAgZXJyb3JzOiAgQSBsaXN0IHdoaWNoLCBpZiBwcm92aWRlZCwgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCB0aGUgZmllbGQKKyAgICAgICAgICAgICAgIHBhdGhzIG9mIGFsbCBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKworICAgIFJldHVybnM6CisgICAgICBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UgaGFzIGFsbCByZXF1aXJlZCBmaWVsZHMgc2V0LgorICAgICIiIgorCisgICAgIyBQZXJmb3JtYW5jZSBpcyBjcml0aWNhbCBzbyB3ZSBhdm9pZCBIYXNGaWVsZCgpIGFuZCBMaXN0RmllbGRzKCkuCisKKyAgICBmb3IgZmllbGQgaW4gcmVxdWlyZWRfZmllbGRzOgorICAgICAgaWYgKGZpZWxkIG5vdCBpbiBzZWxmLl9maWVsZHMgb3IKKyAgICAgICAgICAoZmllbGQuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0UgYW5kCisgICAgICAgICAgIG5vdCBzZWxmLl9maWVsZHNbZmllbGRdLl9pc19wcmVzZW50X2luX3BhcmVudCkpOgorICAgICAgICBpZiBlcnJvcnMgaXMgbm90IE5vbmU6CisgICAgICAgICAgZXJyb3JzLmV4dGVuZChzZWxmLkZpbmRJbml0aWFsaXphdGlvbkVycm9ycygpKQorICAgICAgICByZXR1cm4gRmFsc2UKKworICAgIGZvciBmaWVsZCwgdmFsdWUgaW4gbGlzdChzZWxmLl9maWVsZHMuaXRlbXMoKSk6ICAjIGRpY3QgY2FuIGNoYW5nZSBzaXplIQorICAgICAgaWYgZmllbGQuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIGZpZWxkLmxhYmVsID09IF9GaWVsZERlc2NyaXB0b3IuTEFCRUxfUkVQRUFURUQ6CisgICAgICAgICAgZm9yIGVsZW1lbnQgaW4gdmFsdWU6CisgICAgICAgICAgICBpZiBub3QgZWxlbWVudC5Jc0luaXRpYWxpemVkKCk6CisgICAgICAgICAgICAgIGlmIGVycm9ycyBpcyBub3QgTm9uZToKKyAgICAgICAgICAgICAgICBlcnJvcnMuZXh0ZW5kKHNlbGYuRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCkpCisgICAgICAgICAgICAgIHJldHVybiBGYWxzZQorICAgICAgICBlbGlmIHZhbHVlLl9pc19wcmVzZW50X2luX3BhcmVudCBhbmQgbm90IHZhbHVlLklzSW5pdGlhbGl6ZWQoKToKKyAgICAgICAgICBpZiBlcnJvcnMgaXMgbm90IE5vbmU6CisgICAgICAgICAgICBlcnJvcnMuZXh0ZW5kKHNlbGYuRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCkpCisgICAgICAgICAgcmV0dXJuIEZhbHNlCisKKyAgICByZXR1cm4gVHJ1ZQorCisgIGNscy5Jc0luaXRpYWxpemVkID0gSXNJbml0aWFsaXplZAorCisgIGRlZiBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoc2VsZik6CisgICAgIiIiRmluZHMgcmVxdWlyZWQgZmllbGRzIHdoaWNoIGFyZSBub3QgaW5pdGlhbGl6ZWQuCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBsaXN0IG9mIHN0cmluZ3MuICBFYWNoIHN0cmluZyBpcyBhIHBhdGggdG8gYW4gdW5pbml0aWFsaXplZCBmaWVsZCBmcm9tCisgICAgICB0aGUgdG9wLWxldmVsIG1lc3NhZ2UsIGUuZy4gImZvby5iYXJbNV0uYmF6Ii4KKyAgICAiIiIKKworICAgIGVycm9ycyA9IFtdICAjIHNpbXBsaWZ5IHRoaW5ncworCisgICAgZm9yIGZpZWxkIGluIHJlcXVpcmVkX2ZpZWxkczoKKyAgICAgIGlmIG5vdCBzZWxmLkhhc0ZpZWxkKGZpZWxkLm5hbWUpOgorICAgICAgICBlcnJvcnMuYXBwZW5kKGZpZWxkLm5hbWUpCisKKyAgICBmb3IgZmllbGQsIHZhbHVlIGluIHNlbGYuTGlzdEZpZWxkcygpOgorICAgICAgaWYgZmllbGQuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIGZpZWxkLmlzX2V4dGVuc2lvbjoKKyAgICAgICAgICBuYW1lID0gIiglcykiICUgZmllbGQuZnVsbF9uYW1lCisgICAgICAgIGVsc2U6CisgICAgICAgICAgbmFtZSA9IGZpZWxkLm5hbWUKKworICAgICAgICBpZiBmaWVsZC5sYWJlbCA9PSBfRmllbGREZXNjcmlwdG9yLkxBQkVMX1JFUEVBVEVEOgorICAgICAgICAgIGZvciBpIGluIHhyYW5nZShsZW4odmFsdWUpKToKKyAgICAgICAgICAgIGVsZW1lbnQgPSB2YWx1ZVtpXQorICAgICAgICAgICAgcHJlZml4ID0gIiVzWyVkXS4iICUgKG5hbWUsIGkpCisgICAgICAgICAgICBzdWJfZXJyb3JzID0gZWxlbWVudC5GaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoKQorICAgICAgICAgICAgZXJyb3JzICs9IFsgcHJlZml4ICsgZXJyb3IgZm9yIGVycm9yIGluIHN1Yl9lcnJvcnMgXQorICAgICAgICBlbHNlOgorICAgICAgICAgIHByZWZpeCA9IG5hbWUgKyAiLiIKKyAgICAgICAgICBzdWJfZXJyb3JzID0gdmFsdWUuRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCkKKyAgICAgICAgICBlcnJvcnMgKz0gWyBwcmVmaXggKyBlcnJvciBmb3IgZXJyb3IgaW4gc3ViX2Vycm9ycyBdCisKKyAgICByZXR1cm4gZXJyb3JzCisKKyAgY2xzLkZpbmRJbml0aWFsaXphdGlvbkVycm9ycyA9IEZpbmRJbml0aWFsaXphdGlvbkVycm9ycworCisKK2RlZiBfQWRkTWVyZ2VGcm9tTWV0aG9kKGNscyk6CisgIExBQkVMX1JFUEVBVEVEID0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRAorICBDUFBUWVBFX01FU1NBR0UgPSBfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfTUVTU0FHRQorCisgIGRlZiBNZXJnZUZyb20oc2VsZiwgbXNnKToKKyAgICBpZiBub3QgaXNpbnN0YW5jZShtc2csIGNscyk6CisgICAgICByYWlzZSBUeXBlRXJyb3IoCisgICAgICAgICAgIlBhcmFtZXRlciB0byBNZXJnZUZyb20oKSBtdXN0IGJlIGluc3RhbmNlIG9mIHNhbWUgY2xhc3M6ICIKKyAgICAgICAgICAiZXhwZWN0ZWQgJXMgZ290ICVzLiIgJSAoY2xzLl9fbmFtZV9fLCB0eXBlKG1zZykuX19uYW1lX18pKQorCisgICAgYXNzZXJ0IG1zZyBpcyBub3Qgc2VsZgorICAgIHNlbGYuX01vZGlmaWVkKCkKKworICAgIGZpZWxkcyA9IHNlbGYuX2ZpZWxkcworCisgICAgZm9yIGZpZWxkLCB2YWx1ZSBpbiBtc2cuX2ZpZWxkcy5pdGVyaXRlbXMoKToKKyAgICAgIGlmIGZpZWxkLmxhYmVsID09IExBQkVMX1JFUEVBVEVEOgorICAgICAgICBmaWVsZF92YWx1ZSA9IGZpZWxkcy5nZXQoZmllbGQpCisgICAgICAgIGlmIGZpZWxkX3ZhbHVlIGlzIE5vbmU6CisgICAgICAgICAgIyBDb25zdHJ1Y3QgYSBuZXcgb2JqZWN0IHRvIHJlcHJlc2VudCB0aGlzIGZpZWxkLgorICAgICAgICAgIGZpZWxkX3ZhbHVlID0gZmllbGQuX2RlZmF1bHRfY29uc3RydWN0b3Ioc2VsZikKKyAgICAgICAgICBmaWVsZHNbZmllbGRdID0gZmllbGRfdmFsdWUKKyAgICAgICAgZmllbGRfdmFsdWUuTWVyZ2VGcm9tKHZhbHVlKQorICAgICAgZWxpZiBmaWVsZC5jcHBfdHlwZSA9PSBDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIHZhbHVlLl9pc19wcmVzZW50X2luX3BhcmVudDoKKyAgICAgICAgICBmaWVsZF92YWx1ZSA9IGZpZWxkcy5nZXQoZmllbGQpCisgICAgICAgICAgaWYgZmllbGRfdmFsdWUgaXMgTm9uZToKKyAgICAgICAgICAgICMgQ29uc3RydWN0IGEgbmV3IG9iamVjdCB0byByZXByZXNlbnQgdGhpcyBmaWVsZC4KKyAgICAgICAgICAgIGZpZWxkX3ZhbHVlID0gZmllbGQuX2RlZmF1bHRfY29uc3RydWN0b3Ioc2VsZikKKyAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSBmaWVsZF92YWx1ZQorICAgICAgICAgICAgaWYgZmllbGQuY29udGFpbmluZ19vbmVvZjoKKyAgICAgICAgICAgICAgc2VsZi5fVXBkYXRlT25lb2ZTdGF0ZShmaWVsZCkKKyAgICAgICAgICBmaWVsZF92YWx1ZS5NZXJnZUZyb20odmFsdWUpCisgICAgICBlbHNlOgorICAgICAgICBzZWxmLl9maWVsZHNbZmllbGRdID0gdmFsdWUKKyAgICAgICAgaWYgZmllbGQuY29udGFpbmluZ19vbmVvZjoKKyAgICAgICAgICBzZWxmLl9VcGRhdGVPbmVvZlN0YXRlKGZpZWxkKQorCisgICAgaWYgbXNnLl91bmtub3duX2ZpZWxkczoKKyAgICAgIGlmIG5vdCBzZWxmLl91bmtub3duX2ZpZWxkczoKKyAgICAgICAgc2VsZi5fdW5rbm93bl9maWVsZHMgPSBbXQorICAgICAgc2VsZi5fdW5rbm93bl9maWVsZHMuZXh0ZW5kKG1zZy5fdW5rbm93bl9maWVsZHMpCisKKyAgY2xzLk1lcmdlRnJvbSA9IE1lcmdlRnJvbQorCisKK2RlZiBfQWRkV2hpY2hPbmVvZk1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgIGRlZiBXaGljaE9uZW9mKHNlbGYsIG9uZW9mX25hbWUpOgorICAgICIiIlJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGN1cnJlbnRseSBzZXQgZmllbGQgaW5zaWRlIGEgb25lb2YsIG9yIE5vbmUuIiIiCisgICAgdHJ5OgorICAgICAgZmllbGQgPSBtZXNzYWdlX2Rlc2NyaXB0b3Iub25lb2ZzX2J5X25hbWVbb25lb2ZfbmFtZV0KKyAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICByYWlzZSBWYWx1ZUVycm9yKAorICAgICAgICAgICdQcm90b2NvbCBtZXNzYWdlIGhhcyBubyBvbmVvZiAiJXMiIGZpZWxkLicgJSBvbmVvZl9uYW1lKQorCisgICAgbmVzdGVkX2ZpZWxkID0gc2VsZi5fb25lb2ZzLmdldChmaWVsZCwgTm9uZSkKKyAgICBpZiBuZXN0ZWRfZmllbGQgaXMgbm90IE5vbmUgYW5kIHNlbGYuSGFzRmllbGQobmVzdGVkX2ZpZWxkLm5hbWUpOgorICAgICAgcmV0dXJuIG5lc3RlZF9maWVsZC5uYW1lCisgICAgZWxzZToKKyAgICAgIHJldHVybiBOb25lCisKKyAgY2xzLldoaWNoT25lb2YgPSBXaGljaE9uZW9mCisKKworZGVmIF9BZGRNZXNzYWdlTWV0aG9kcyhtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkFkZHMgaW1wbGVtZW50YXRpb25zIG9mIGFsbCBNZXNzYWdlIG1ldGhvZHMgdG8gY2xzLiIiIgorICBfQWRkTGlzdEZpZWxkc01ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscykKKyAgX0FkZEhhc0ZpZWxkTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkQ2xlYXJGaWVsZE1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscykKKyAgaWYgbWVzc2FnZV9kZXNjcmlwdG9yLmlzX2V4dGVuZGFibGU6CisgICAgX0FkZENsZWFyRXh0ZW5zaW9uTWV0aG9kKGNscykKKyAgICBfQWRkSGFzRXh0ZW5zaW9uTWV0aG9kKGNscykKKyAgX0FkZENsZWFyTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkRXF1YWxzTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkU3RyTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkVW5pY29kZU1ldGhvZChtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscykKKyAgX0FkZFNldExpc3RlbmVyTWV0aG9kKGNscykKKyAgX0FkZEJ5dGVTaXplTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkU2VyaWFsaXplVG9TdHJpbmdNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpCisgIF9BZGRTZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmdNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpCisgIF9BZGRNZXJnZUZyb21TdHJpbmdNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpCisgIF9BZGRJc0luaXRpYWxpemVkTWV0aG9kKG1lc3NhZ2VfZGVzY3JpcHRvciwgY2xzKQorICBfQWRkTWVyZ2VGcm9tTWV0aG9kKGNscykKKyAgX0FkZFdoaWNoT25lb2ZNZXRob2QobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpCisKK2RlZiBfQWRkUHJpdmF0ZUhlbHBlck1ldGhvZHMobWVzc2FnZV9kZXNjcmlwdG9yLCBjbHMpOgorICAiIiJBZGRzIGltcGxlbWVudGF0aW9uIG9mIHByaXZhdGUgaGVscGVyIG1ldGhvZHMgdG8gY2xzLiIiIgorCisgIGRlZiBNb2RpZmllZChzZWxmKToKKyAgICAiIiJTZXRzIHRoZSBfY2FjaGVkX2J5dGVfc2l6ZV9kaXJ0eSBiaXQgdG8gdHJ1ZSwKKyAgICBhbmQgcHJvcGFnYXRlcyB0aGlzIHRvIG91ciBsaXN0ZW5lciBpZmYgdGhpcyB3YXMgYSBzdGF0ZSBjaGFuZ2UuCisgICAgIiIiCisKKyAgICAjIE5vdGU6ICBTb21lIGNhbGxlcnMgY2hlY2sgX2NhY2hlZF9ieXRlX3NpemVfZGlydHkgYmVmb3JlIGNhbGxpbmcKKyAgICAjICAgX01vZGlmaWVkKCkgYXMgYW4gZXh0cmEgb3B0aW1pemF0aW9uLiAgU28sIGlmIHRoaXMgbWV0aG9kIGlzIGV2ZXIKKyAgICAjICAgY2hhbmdlZCBzdWNoIHRoYXQgaXQgZG9lcyBzdHVmZiBldmVuIHdoZW4gX2NhY2hlZF9ieXRlX3NpemVfZGlydHkgaXMKKyAgICAjICAgYWxyZWFkeSB0cnVlLCB0aGUgY2FsbGVycyBuZWVkIHRvIGJlIHVwZGF0ZWQuCisgICAgaWYgbm90IHNlbGYuX2NhY2hlZF9ieXRlX3NpemVfZGlydHk6CisgICAgICBzZWxmLl9jYWNoZWRfYnl0ZV9zaXplX2RpcnR5ID0gVHJ1ZQorICAgICAgc2VsZi5fbGlzdGVuZXJfZm9yX2NoaWxkcmVuLmRpcnR5ID0gVHJ1ZQorICAgICAgc2VsZi5faXNfcHJlc2VudF9pbl9wYXJlbnQgPSBUcnVlCisgICAgICBzZWxmLl9saXN0ZW5lci5Nb2RpZmllZCgpCisKKyAgZGVmIF9VcGRhdGVPbmVvZlN0YXRlKHNlbGYsIGZpZWxkKToKKyAgICAiIiJTZXRzIGZpZWxkIGFzIHRoZSBhY3RpdmUgZmllbGQgaW4gaXRzIGNvbnRhaW5pbmcgb25lb2YuCisKKyAgICBXaWxsIGFsc28gZGVsZXRlIGN1cnJlbnRseSBhY3RpdmUgZmllbGQgaW4gdGhlIG9uZW9mLCBpZiBpdCBpcyBkaWZmZXJlbnQKKyAgICBmcm9tIHRoZSBhcmd1bWVudC4gRG9lcyBub3QgbWFyayB0aGUgbWVzc2FnZSBhcyBtb2RpZmllZC4KKyAgICAiIiIKKyAgICBvdGhlcl9maWVsZCA9IHNlbGYuX29uZW9mcy5zZXRkZWZhdWx0KGZpZWxkLmNvbnRhaW5pbmdfb25lb2YsIGZpZWxkKQorICAgIGlmIG90aGVyX2ZpZWxkIGlzIG5vdCBmaWVsZDoKKyAgICAgIGRlbCBzZWxmLl9maWVsZHNbb3RoZXJfZmllbGRdCisgICAgICBzZWxmLl9vbmVvZnNbZmllbGQuY29udGFpbmluZ19vbmVvZl0gPSBmaWVsZAorCisgIGNscy5fTW9kaWZpZWQgPSBNb2RpZmllZAorICBjbHMuU2V0SW5QYXJlbnQgPSBNb2RpZmllZAorICBjbHMuX1VwZGF0ZU9uZW9mU3RhdGUgPSBfVXBkYXRlT25lb2ZTdGF0ZQorCisKK2NsYXNzIF9MaXN0ZW5lcihvYmplY3QpOgorCisgICIiIk1lc3NhZ2VMaXN0ZW5lciBpbXBsZW1lbnRhdGlvbiB0aGF0IGEgcGFyZW50IG1lc3NhZ2UgcmVnaXN0ZXJzIHdpdGggaXRzCisgIGNoaWxkIG1lc3NhZ2UuCisKKyAgSW4gb3JkZXIgdG8gc3VwcG9ydCBzZW1hbnRpY3MgbGlrZToKKworICAgIGZvby5iYXIuYmF6LnF1eCA9IDIzCisgICAgYXNzZXJ0IGZvby5IYXNGaWVsZCgnYmFyJykKKworICAuLi5jaGlsZCBvYmplY3RzIG11c3QgaGF2ZSBiYWNrIHJlZmVyZW5jZXMgdG8gdGhlaXIgcGFyZW50cy4KKyAgVGhpcyBoZWxwZXIgY2xhc3MgaXMgYXQgdGhlIGhlYXJ0IG9mIHRoaXMgc3VwcG9ydC4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIHBhcmVudF9tZXNzYWdlKToKKyAgICAiIiJBcmdzOgorICAgICAgcGFyZW50X21lc3NhZ2U6IFRoZSBtZXNzYWdlIHdob3NlIF9Nb2RpZmllZCgpIG1ldGhvZCB3ZSBzaG91bGQgY2FsbCB3aGVuCisgICAgICAgIHdlIHJlY2VpdmUgTW9kaWZpZWQoKSBtZXNzYWdlcy4KKyAgICAiIiIKKyAgICAjIFRoaXMgbGlzdGVuZXIgZXN0YWJsaXNoZXMgYSBiYWNrIHJlZmVyZW5jZSBmcm9tIGEgY2hpbGQgKGNvbnRhaW5lZCkgb2JqZWN0CisgICAgIyB0byBpdHMgcGFyZW50IChjb250YWluaW5nKSBvYmplY3QuICBXZSBtYWtlIHRoaXMgYSB3ZWFrIHJlZmVyZW5jZSB0byBhdm9pZAorICAgICMgY3JlYXRpbmcgY3ljbGljIGdhcmJhZ2Ugd2hlbiB0aGUgY2xpZW50IGZpbmlzaGVzIHdpdGggdGhlICdwYXJlbnQnIG9iamVjdAorICAgICMgaW4gdGhlIHRyZWUuCisgICAgaWYgaXNpbnN0YW5jZShwYXJlbnRfbWVzc2FnZSwgd2Vha3JlZi5Qcm94eVR5cGUpOgorICAgICAgc2VsZi5fcGFyZW50X21lc3NhZ2Vfd2Vha3JlZiA9IHBhcmVudF9tZXNzYWdlCisgICAgZWxzZToKKyAgICAgIHNlbGYuX3BhcmVudF9tZXNzYWdlX3dlYWtyZWYgPSB3ZWFrcmVmLnByb3h5KHBhcmVudF9tZXNzYWdlKQorCisgICAgIyBBcyBhbiBvcHRpbWl6YXRpb24sIHdlIGFsc28gaW5kaWNhdGUgZGlyZWN0bHkgb24gdGhlIGxpc3RlbmVyIHdoZXRoZXIKKyAgICAjIG9yIG5vdCB0aGUgcGFyZW50IG1lc3NhZ2UgaXMgZGlydHkuICBUaGlzIHdheSB3ZSBjYW4gYXZvaWQgdHJhdmVyc2luZworICAgICMgdXAgdGhlIHRyZWUgaW4gdGhlIGNvbW1vbiBjYXNlLgorICAgIHNlbGYuZGlydHkgPSBGYWxzZQorCisgIGRlZiBNb2RpZmllZChzZWxmKToKKyAgICBpZiBzZWxmLmRpcnR5OgorICAgICAgcmV0dXJuCisgICAgdHJ5OgorICAgICAgIyBQcm9wYWdhdGUgdGhlIHNpZ25hbCB0byBvdXIgcGFyZW50cyBpZmYgdGhpcyBpcyB0aGUgZmlyc3QgZmllbGQgc2V0LgorICAgICAgc2VsZi5fcGFyZW50X21lc3NhZ2Vfd2Vha3JlZi5fTW9kaWZpZWQoKQorICAgIGV4Y2VwdCBSZWZlcmVuY2VFcnJvcjoKKyAgICAgICMgV2UgY2FuIGdldCBoZXJlIGlmIGEgY2xpZW50IGhhcyBrZXB0IGEgcmVmZXJlbmNlIHRvIGEgY2hpbGQgb2JqZWN0LAorICAgICAgIyBhbmQgaXMgbm93IHNldHRpbmcgYSBmaWVsZCBvbiBpdCwgYnV0IHRoZSBjaGlsZCdzIHBhcmVudCBoYXMgYmVlbgorICAgICAgIyBnYXJiYWdlLWNvbGxlY3RlZC4gIFRoaXMgaXMgbm90IGFuIGVycm9yLgorICAgICAgcGFzcworCisKK2NsYXNzIF9PbmVvZkxpc3RlbmVyKF9MaXN0ZW5lcik6CisgICIiIlNwZWNpYWwgbGlzdGVuZXIgaW1wbGVtZW50YXRpb24gZm9yIHNldHRpbmcgY29tcG9zaXRlIG9uZW9mIGZpZWxkcy4iIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgcGFyZW50X21lc3NhZ2UsIGZpZWxkKToKKyAgICAiIiJBcmdzOgorICAgICAgcGFyZW50X21lc3NhZ2U6IFRoZSBtZXNzYWdlIHdob3NlIF9Nb2RpZmllZCgpIG1ldGhvZCB3ZSBzaG91bGQgY2FsbCB3aGVuCisgICAgICAgIHdlIHJlY2VpdmUgTW9kaWZpZWQoKSBtZXNzYWdlcy4KKyAgICAgIGZpZWxkOiBUaGUgZGVzY3JpcHRvciBvZiB0aGUgZmllbGQgYmVpbmcgc2V0IGluIHRoZSBwYXJlbnQgbWVzc2FnZS4KKyAgICAiIiIKKyAgICBzdXBlcihfT25lb2ZMaXN0ZW5lciwgc2VsZikuX19pbml0X18ocGFyZW50X21lc3NhZ2UpCisgICAgc2VsZi5fZmllbGQgPSBmaWVsZAorCisgIGRlZiBNb2RpZmllZChzZWxmKToKKyAgICAiIiJBbHNvIHVwZGF0ZXMgdGhlIHN0YXRlIG9mIHRoZSBjb250YWluaW5nIG9uZW9mIGluIHRoZSBwYXJlbnQgbWVzc2FnZS4iIiIKKyAgICB0cnk6CisgICAgICBzZWxmLl9wYXJlbnRfbWVzc2FnZV93ZWFrcmVmLl9VcGRhdGVPbmVvZlN0YXRlKHNlbGYuX2ZpZWxkKQorICAgICAgc3VwZXIoX09uZW9mTGlzdGVuZXIsIHNlbGYpLk1vZGlmaWVkKCkKKyAgICBleGNlcHQgUmVmZXJlbmNlRXJyb3I6CisgICAgICBwYXNzCisKKworIyBUT0RPKHJvYmluc29uKTogTW92ZSBlbHNld2hlcmU/ICBUaGlzIGZpbGUgaXMgZ2V0dGluZyBwcmV0dHkgcmlkaWN1bG91cy4uLgorIyBUT0RPKHJvYmluc29uKTogVW5pZnkgZXJyb3IgaGFuZGxpbmcgb2YgInVua25vd24gZXh0ZW5zaW9uIiBjcmFwLgorIyBUT0RPKHJvYmluc29uKTogU3VwcG9ydCBpdGVyaXRlbXMoKS1zdHlsZSBpdGVyYXRpb24gb3ZlciBhbGwKKyMgZXh0ZW5zaW9ucyB3aXRoIHRoZSAiaGFzIiBiaXRzIHR1cm5lZCBvbj8KK2NsYXNzIF9FeHRlbnNpb25EaWN0KG9iamVjdCk6CisKKyAgIiIiRGljdC1saWtlIGNvbnRhaW5lciBmb3Igc3VwcG9ydGluZyBhbiBpbmRleGFibGUgIkV4dGVuc2lvbnMiCisgIGZpZWxkIG9uIHByb3RvIGluc3RhbmNlcy4KKworICBOb3RlIHRoYXQgaW4gYWxsIGNhc2VzIHdlIGV4cGVjdCBleHRlbnNpb24gaGFuZGxlcyB0byBiZQorICBGaWVsZERlc2NyaXB0b3JzLgorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgZXh0ZW5kZWRfbWVzc2FnZSk6CisgICAgIiIiZXh0ZW5kZWRfbWVzc2FnZTogTWVzc2FnZSBpbnN0YW5jZSBmb3Igd2hpY2ggd2UgYXJlIHRoZSBFeHRlbnNpb25zIGRpY3QuCisgICAgIiIiCisKKyAgICBzZWxmLl9leHRlbmRlZF9tZXNzYWdlID0gZXh0ZW5kZWRfbWVzc2FnZQorCisgIGRlZiBfX2dldGl0ZW1fXyhzZWxmLCBleHRlbnNpb25faGFuZGxlKToKKyAgICAiIiJSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBnaXZlbiBleHRlbnNpb24gaGFuZGxlLiIiIgorCisgICAgX1ZlcmlmeUV4dGVuc2lvbkhhbmRsZShzZWxmLl9leHRlbmRlZF9tZXNzYWdlLCBleHRlbnNpb25faGFuZGxlKQorCisgICAgcmVzdWx0ID0gc2VsZi5fZXh0ZW5kZWRfbWVzc2FnZS5fZmllbGRzLmdldChleHRlbnNpb25faGFuZGxlKQorICAgIGlmIHJlc3VsdCBpcyBub3QgTm9uZToKKyAgICAgIHJldHVybiByZXN1bHQKKworICAgIGlmIGV4dGVuc2lvbl9oYW5kbGUubGFiZWwgPT0gX0ZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICAgIHJlc3VsdCA9IGV4dGVuc2lvbl9oYW5kbGUuX2RlZmF1bHRfY29uc3RydWN0b3Ioc2VsZi5fZXh0ZW5kZWRfbWVzc2FnZSkKKyAgICBlbGlmIGV4dGVuc2lvbl9oYW5kbGUuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgICByZXN1bHQgPSBleHRlbnNpb25faGFuZGxlLm1lc3NhZ2VfdHlwZS5fY29uY3JldGVfY2xhc3MoKQorICAgICAgdHJ5OgorICAgICAgICByZXN1bHQuX1NldExpc3RlbmVyKHNlbGYuX2V4dGVuZGVkX21lc3NhZ2UuX2xpc3RlbmVyX2Zvcl9jaGlsZHJlbikKKyAgICAgIGV4Y2VwdCBSZWZlcmVuY2VFcnJvcjoKKyAgICAgICAgcGFzcworICAgIGVsc2U6CisgICAgICAjIFNpbmd1bGFyIHNjYWxhciAtLSBqdXN0IHJldHVybiB0aGUgZGVmYXVsdCB3aXRob3V0IGluc2VydGluZyBpbnRvIHRoZQorICAgICAgIyBkaWN0LgorICAgICAgcmV0dXJuIGV4dGVuc2lvbl9oYW5kbGUuZGVmYXVsdF92YWx1ZQorCisgICAgIyBBdG9taWNhbGx5IGNoZWNrIGlmIGFub3RoZXIgdGhyZWFkIGhhcyBwcmVlbXB0ZWQgdXMgYW5kLCBpZiBub3QsIHN3YXAKKyAgICAjIGluIHRoZSBuZXcgb2JqZWN0IHdlIGp1c3QgY3JlYXRlZC4gIElmIHNvbWVvbmUgaGFzIHByZWVtcHRlZCB1cywgd2UKKyAgICAjIHRha2UgdGhhdCBvYmplY3QgYW5kIGRpc2NhcmQgb3Vycy4KKyAgICAjIFdBUk5JTkc6ICBXZSBhcmUgcmVseWluZyBvbiBzZXRkZWZhdWx0KCkgYmVpbmcgYXRvbWljLiAgVGhpcyBpcyB0cnVlCisgICAgIyAgIGluIENQeXRob24gYnV0IHdlIGhhdmVuJ3QgaW52ZXN0aWdhdGVkIG90aGVycy4gIFRoaXMgd2FybmluZyBhcHBlYXJzCisgICAgIyAgIGluIHNldmVyYWwgb3RoZXIgbG9jYXRpb25zIGluIHRoaXMgZmlsZS4KKyAgICByZXN1bHQgPSBzZWxmLl9leHRlbmRlZF9tZXNzYWdlLl9maWVsZHMuc2V0ZGVmYXVsdCgKKyAgICAgICAgZXh0ZW5zaW9uX2hhbmRsZSwgcmVzdWx0KQorCisgICAgcmV0dXJuIHJlc3VsdAorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIGlmIG5vdCBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXyk6CisgICAgICByZXR1cm4gRmFsc2UKKworICAgIG15X2ZpZWxkcyA9IHNlbGYuX2V4dGVuZGVkX21lc3NhZ2UuTGlzdEZpZWxkcygpCisgICAgb3RoZXJfZmllbGRzID0gb3RoZXIuX2V4dGVuZGVkX21lc3NhZ2UuTGlzdEZpZWxkcygpCisKKyAgICAjIEdldCByaWQgb2Ygbm9uLWV4dGVuc2lvbiBmaWVsZHMuCisgICAgbXlfZmllbGRzICAgID0gWyBmaWVsZCBmb3IgZmllbGQgaW4gbXlfZmllbGRzICAgIGlmIGZpZWxkLmlzX2V4dGVuc2lvbiBdCisgICAgb3RoZXJfZmllbGRzID0gWyBmaWVsZCBmb3IgZmllbGQgaW4gb3RoZXJfZmllbGRzIGlmIGZpZWxkLmlzX2V4dGVuc2lvbiBdCisKKyAgICByZXR1cm4gbXlfZmllbGRzID09IG90aGVyX2ZpZWxkcworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3Qgc2VsZiA9PSBvdGhlcgorCisgIGRlZiBfX2hhc2hfXyhzZWxmKToKKyAgICByYWlzZSBUeXBlRXJyb3IoJ3VuaGFzaGFibGUgb2JqZWN0JykKKworICAjIE5vdGUgdGhhdCB0aGlzIGlzIG9ubHkgbWVhbmluZ2Z1bCBmb3Igbm9uLXJlcGVhdGVkLCBzY2FsYXIgZXh0ZW5zaW9uCisgICMgZmllbGRzLiAgTm90ZSBhbHNvIHRoYXQgd2UgbWF5IGhhdmUgdG8gY2FsbCBfTW9kaWZpZWQoKSB3aGVuIHdlIGRvCisgICMgc3VjY2Vzc2Z1bGx5IHNldCBhIGZpZWxkIHRoaXMgd2F5LCB0byBzZXQgYW55IG5lY3NzYXJ5ICJoYXMiIGJpdHMgaW4gdGhlCisgICMgYW5jZXN0b3JzIG9mIHRoZSBleHRlbmRlZCBtZXNzYWdlLgorICBkZWYgX19zZXRpdGVtX18oc2VsZiwgZXh0ZW5zaW9uX2hhbmRsZSwgdmFsdWUpOgorICAgICIiIklmIGV4dGVuc2lvbl9oYW5kbGUgc3BlY2lmaWVzIGEgbm9uLXJlcGVhdGVkLCBzY2FsYXIgZXh0ZW5zaW9uCisgICAgZmllbGQsIHNldHMgdGhlIHZhbHVlIG9mIHRoYXQgZmllbGQuCisgICAgIiIiCisKKyAgICBfVmVyaWZ5RXh0ZW5zaW9uSGFuZGxlKHNlbGYuX2V4dGVuZGVkX21lc3NhZ2UsIGV4dGVuc2lvbl9oYW5kbGUpCisKKyAgICBpZiAoZXh0ZW5zaW9uX2hhbmRsZS5sYWJlbCA9PSBfRmllbGREZXNjcmlwdG9yLkxBQkVMX1JFUEVBVEVEIG9yCisgICAgICAgIGV4dGVuc2lvbl9oYW5kbGUuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0UpOgorICAgICAgcmFpc2UgVHlwZUVycm9yKAorICAgICAgICAgICdDYW5ub3QgYXNzaWduIHRvIGV4dGVuc2lvbiAiJXMiIGJlY2F1c2UgaXQgaXMgYSByZXBlYXRlZCBvciAnCisgICAgICAgICAgJ2NvbXBvc2l0ZSB0eXBlLicgJSBleHRlbnNpb25faGFuZGxlLmZ1bGxfbmFtZSkKKworICAgICMgSXQncyBzbGlnaHRseSB3YXN0ZWZ1bCB0byBsb29rdXAgdGhlIHR5cGUgY2hlY2tlciBlYWNoIHRpbWUsCisgICAgIyBidXQgd2UgZXhwZWN0IHRoaXMgdG8gYmUgYSB2YW5pc2hpbmdseSB1bmNvbW1vbiBjYXNlIGFueXdheS4KKyAgICB0eXBlX2NoZWNrZXIgPSB0eXBlX2NoZWNrZXJzLkdldFR5cGVDaGVja2VyKGV4dGVuc2lvbl9oYW5kbGUpCisgICAgIyBweWxpbnQ6IGRpc2FibGU9cHJvdGVjdGVkLWFjY2VzcworICAgIHNlbGYuX2V4dGVuZGVkX21lc3NhZ2UuX2ZpZWxkc1tleHRlbnNpb25faGFuZGxlXSA9ICgKKyAgICAgICAgdHlwZV9jaGVja2VyLkNoZWNrVmFsdWUodmFsdWUpKQorICAgIHNlbGYuX2V4dGVuZGVkX21lc3NhZ2UuX01vZGlmaWVkKCkKKworICBkZWYgX0ZpbmRFeHRlbnNpb25CeU5hbWUoc2VsZiwgbmFtZSk6CisgICAgIiIiVHJpZXMgdG8gZmluZCBhIGtub3duIGV4dGVuc2lvbiB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KKworICAgIEFyZ3M6CisgICAgICBuYW1lOiBFeHRlbnNpb24gZnVsbCBuYW1lLgorCisgICAgUmV0dXJuczoKKyAgICAgIEV4dGVuc2lvbiBmaWVsZCBkZXNjcmlwdG9yLgorICAgICIiIgorICAgIHJldHVybiBzZWxmLl9leHRlbmRlZF9tZXNzYWdlLl9leHRlbnNpb25zX2J5X25hbWUuZ2V0KG5hbWUsIE5vbmUpCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3JlZmxlY3Rpb25fdGVzdC5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvcmVmbGVjdGlvbl90ZXN0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmE2MmQ5ODQKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3JlZmxlY3Rpb25fdGVzdC5weQpAQCAtMCwwICsxLDI5NjYgQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVW5pdHRlc3QgZm9yIHJlZmxlY3Rpb24ucHksIHdoaWNoIGFsc28gaW5kaXJlY3RseSB0ZXN0cyB0aGUgb3V0cHV0IG9mIHRoZQorcHVyZS1QeXRob24gcHJvdG9jb2wgY29tcGlsZXIuCisiIiIKKworaW1wb3J0IGNvcHkKK2ltcG9ydCBnYworaW1wb3J0IG9wZXJhdG9yCitpbXBvcnQgc3RydWN0CisKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X2ltcG9ydF9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9tc2V0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2UKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCByZWZsZWN0aW9uCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdGV4dF9mb3JtYXQKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBhcGlfaW1wbGVtZW50YXRpb24KK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBtb3JlX2V4dGVuc2lvbnNfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgbW9yZV9tZXNzYWdlc19wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCB3aXJlX2Zvcm1hdAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IHRlc3RfdXRpbAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGRlY29kZXIKKworCitjbGFzcyBfTWluaURlY29kZXIob2JqZWN0KToKKyAgIiIiRGVjb2RlcyBhIHN0cmVhbSBvZiB2YWx1ZXMgZnJvbSBhIHN0cmluZy4KKworICBPbmNlIHVwb24gYSB0aW1lIHdlIGFjdHVhbGx5IGhhZCBhIGNsYXNzIGNhbGxlZCBkZWNvZGVyLkRlY29kZXIuICBUaGVuIHdlCisgIGdvdCByaWQgb2YgaXQgZHVyaW5nIGEgcmVkZXNpZ24gdGhhdCBtYWRlIGRlY29kaW5nIG11Y2gsIG11Y2ggZmFzdGVyIG92ZXJhbGwuCisgIEJ1dCBhIGNvdXBsZSB0ZXN0cyBpbiB0aGlzIGZpbGUgdXNlZCBpdCB0byBjaGVjayB0aGF0IHRoZSBzZXJpYWxpemVkIGZvcm0gb2YKKyAgYSBtZXNzYWdlIHdhcyBjb3JyZWN0LiAgU28sIHRoaXMgY2xhc3MgaW1wbGVtZW50cyBqdXN0IHRoZSBtZXRob2RzIHRoYXQgd2VyZQorICB1c2VkIGJ5IHNhaWQgdGVzdHMsIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byByZXdyaXRlIHRoZSB0ZXN0cy4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGJ5dGVzKToKKyAgICBzZWxmLl9ieXRlcyA9IGJ5dGVzCisgICAgc2VsZi5fcG9zID0gMAorCisgIGRlZiBSZWFkVmFyaW50KHNlbGYpOgorICAgIHJlc3VsdCwgc2VsZi5fcG9zID0gZGVjb2Rlci5fRGVjb2RlVmFyaW50KHNlbGYuX2J5dGVzLCBzZWxmLl9wb3MpCisgICAgcmV0dXJuIHJlc3VsdAorCisgIFJlYWRJbnQzMiA9IFJlYWRWYXJpbnQKKyAgUmVhZEludDY0ID0gUmVhZFZhcmludAorICBSZWFkVUludDMyID0gUmVhZFZhcmludAorICBSZWFkVUludDY0ID0gUmVhZFZhcmludAorCisgIGRlZiBSZWFkU0ludDY0KHNlbGYpOgorICAgIHJldHVybiB3aXJlX2Zvcm1hdC5aaWdaYWdEZWNvZGUoc2VsZi5SZWFkVmFyaW50KCkpCisKKyAgUmVhZFNJbnQzMiA9IFJlYWRTSW50NjQKKworICBkZWYgUmVhZEZpZWxkTnVtYmVyQW5kV2lyZVR5cGUoc2VsZik6CisgICAgcmV0dXJuIHdpcmVfZm9ybWF0LlVucGFja1RhZyhzZWxmLlJlYWRWYXJpbnQoKSkKKworICBkZWYgUmVhZEZsb2F0KHNlbGYpOgorICAgIHJlc3VsdCA9IHN0cnVjdC51bnBhY2soIjxmIiwgc2VsZi5fYnl0ZXNbc2VsZi5fcG9zOnNlbGYuX3Bvcys0XSlbMF0KKyAgICBzZWxmLl9wb3MgKz0gNAorICAgIHJldHVybiByZXN1bHQKKworICBkZWYgUmVhZERvdWJsZShzZWxmKToKKyAgICByZXN1bHQgPSBzdHJ1Y3QudW5wYWNrKCI8ZCIsIHNlbGYuX2J5dGVzW3NlbGYuX3BvczpzZWxmLl9wb3MrOF0pWzBdCisgICAgc2VsZi5fcG9zICs9IDgKKyAgICByZXR1cm4gcmVzdWx0CisKKyAgZGVmIEVuZE9mU3RyZWFtKHNlbGYpOgorICAgIHJldHVybiBzZWxmLl9wb3MgPT0gbGVuKHNlbGYuX2J5dGVzKQorCisKK2NsYXNzIFJlZmxlY3Rpb25UZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgYXNzZXJ0TGlzdHNFcXVhbChzZWxmLCB2YWx1ZXMsIG90aGVycyk6CisgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4odmFsdWVzKSwgbGVuKG90aGVycykpCisgICAgZm9yIGkgaW4gcmFuZ2UobGVuKHZhbHVlcykpOgorICAgICAgc2VsZi5hc3NlcnRFcXVhbCh2YWx1ZXNbaV0sIG90aGVyc1tpXSkKKworICBkZWYgdGVzdFNjYWxhckNvbnN0cnVjdG9yKHNlbGYpOgorICAgICMgQ29uc3RydWN0b3Igd2l0aCBvbmx5IHNjYWxhciB0eXBlcyBzaG91bGQgc3VjY2VlZC4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoCisgICAgICAgIG9wdGlvbmFsX2ludDMyPTI0LAorICAgICAgICBvcHRpb25hbF9kb3VibGU9NTQuMzIxLAorICAgICAgICBvcHRpb25hbF9zdHJpbmc9J29wdGlvbmFsX3N0cmluZycpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKDI0LCBwcm90by5vcHRpb25hbF9pbnQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDU0LjMyMSwgcHJvdG8ub3B0aW9uYWxfZG91YmxlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29wdGlvbmFsX3N0cmluZycsIHByb3RvLm9wdGlvbmFsX3N0cmluZykKKworICBkZWYgdGVzdFJlcGVhdGVkU2NhbGFyQ29uc3RydWN0b3Ioc2VsZik6CisgICAgIyBDb25zdHJ1Y3RvciB3aXRoIG9ubHkgcmVwZWF0ZWQgc2NhbGFyIHR5cGVzIHNob3VsZCBzdWNjZWVkLgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygKKyAgICAgICAgcmVwZWF0ZWRfaW50MzI9WzEsIDIsIDMsIDRdLAorICAgICAgICByZXBlYXRlZF9kb3VibGU9WzEuMjMsIDU0LjMyMV0sCisgICAgICAgIHJlcGVhdGVkX2Jvb2w9W1RydWUsIEZhbHNlLCBGYWxzZV0sCisgICAgICAgIHJlcGVhdGVkX3N0cmluZz1bIm9wdGlvbmFsX3N0cmluZyJdKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoWzEsIDIsIDMsIDRdLCBsaXN0KHByb3RvLnJlcGVhdGVkX2ludDMyKSkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhbMS4yMywgNTQuMzIxXSwgbGlzdChwcm90by5yZXBlYXRlZF9kb3VibGUpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKFtUcnVlLCBGYWxzZSwgRmFsc2VdLCBsaXN0KHByb3RvLnJlcGVhdGVkX2Jvb2wpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKFsib3B0aW9uYWxfc3RyaW5nIl0sIGxpc3QocHJvdG8ucmVwZWF0ZWRfc3RyaW5nKSkKKworICBkZWYgdGVzdFJlcGVhdGVkQ29tcG9zaXRlQ29uc3RydWN0b3Ioc2VsZik6CisgICAgIyBDb25zdHJ1Y3RvciB3aXRoIG9ubHkgcmVwZWF0ZWQgY29tcG9zaXRlIHR5cGVzIHNob3VsZCBzdWNjZWVkLgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygKKyAgICAgICAgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2U9WworICAgICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgICAgIGJiPXVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuRk9PKSwKKyAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSgKKyAgICAgICAgICAgICAgICBiYj11bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkJBUildLAorICAgICAgICByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2U9WworICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZvcmVpZ25NZXNzYWdlKGM9LTQzKSwKKyAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduTWVzc2FnZShjPTQ1MzI0KSwKKyAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduTWVzc2FnZShjPTEyKV0sCisgICAgICAgIHJlcGVhdGVkZ3JvdXA9WworICAgICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwKCksCisgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAoYT0xKSwKKyAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cChhPTIpXSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICBbdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgYmI9dW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5GT08pLAorICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgIGJiPXVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuQkFSKV0sCisgICAgICAgIGxpc3QocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICBbdW5pdHRlc3RfcGIyLkZvcmVpZ25NZXNzYWdlKGM9LTQzKSwKKyAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduTWVzc2FnZShjPTQ1MzI0KSwKKyAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduTWVzc2FnZShjPTEyKV0sCisgICAgICAgIGxpc3QocHJvdG8ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgW3VuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCgpLAorICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwKGE9MSksCisgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAoYT0yKV0sCisgICAgICAgIGxpc3QocHJvdG8ucmVwZWF0ZWRncm91cCkpCisKKyAgZGVmIHRlc3RNaXhlZENvbnN0cnVjdG9yKHNlbGYpOgorICAgICMgQ29uc3RydWN0b3Igd2l0aCBvbmx5IG1peGVkIHR5cGVzIHNob3VsZCBzdWNjZWVkLgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygKKyAgICAgICAgb3B0aW9uYWxfaW50MzI9MjQsCisgICAgICAgIG9wdGlvbmFsX3N0cmluZz0nb3B0aW9uYWxfc3RyaW5nJywKKyAgICAgICAgcmVwZWF0ZWRfZG91YmxlPVsxLjIzLCA1NC4zMjFdLAorICAgICAgICByZXBlYXRlZF9ib29sPVtUcnVlLCBGYWxzZSwgRmFsc2VdLAorICAgICAgICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZT1bCisgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgYmI9dW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5GT08pLAorICAgICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgICAgIGJiPXVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuQkFSKV0sCisgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZT1bCisgICAgICAgICAgICB1bml0dGVzdF9wYjIuRm9yZWlnbk1lc3NhZ2UoYz0tNDMpLAorICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZvcmVpZ25NZXNzYWdlKGM9NDUzMjQpLAorICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZvcmVpZ25NZXNzYWdlKGM9MTIpXSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWwoMjQsIHByb3RvLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ29wdGlvbmFsX3N0cmluZycsIHByb3RvLm9wdGlvbmFsX3N0cmluZykKKyAgICBzZWxmLmFzc2VydEVxdWFscyhbMS4yMywgNTQuMzIxXSwgbGlzdChwcm90by5yZXBlYXRlZF9kb3VibGUpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKFtUcnVlLCBGYWxzZSwgRmFsc2VdLCBsaXN0KHByb3RvLnJlcGVhdGVkX2Jvb2wpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICBbdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgYmI9dW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5GT08pLAorICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKAorICAgICAgICAgICAgIGJiPXVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuQkFSKV0sCisgICAgICAgIGxpc3QocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICBbdW5pdHRlc3RfcGIyLkZvcmVpZ25NZXNzYWdlKGM9LTQzKSwKKyAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduTWVzc2FnZShjPTQ1MzI0KSwKKyAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduTWVzc2FnZShjPTEyKV0sCisgICAgICAgIGxpc3QocHJvdG8ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKSkKKworICBkZWYgdGVzdENvbnN0cnVjdG9yVHlwZUVycm9yKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKAorICAgICAgICBUeXBlRXJyb3IsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMsIG9wdGlvbmFsX2ludDMyPSJmb28iKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKAorICAgICAgICBUeXBlRXJyb3IsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMsIG9wdGlvbmFsX3N0cmluZz0xMjM0KQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKAorICAgICAgICBUeXBlRXJyb3IsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMsIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlPTEyMzQpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoCisgICAgICAgIFR5cGVFcnJvciwgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcywgcmVwZWF0ZWRfaW50MzI9MTIzNCkKKyAgICBzZWxmLmFzc2VydFJhaXNlcygKKyAgICAgICAgVHlwZUVycm9yLCB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLCByZXBlYXRlZF9pbnQzMj1bImZvbyJdKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKAorICAgICAgICBUeXBlRXJyb3IsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMsIHJlcGVhdGVkX3N0cmluZz0xMjM0KQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKAorICAgICAgICBUeXBlRXJyb3IsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMsIHJlcGVhdGVkX3N0cmluZz1bMTIzNF0pCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoCisgICAgICAgIFR5cGVFcnJvciwgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcywgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2U9MTIzNCkKKyAgICBzZWxmLmFzc2VydFJhaXNlcygKKyAgICAgICAgVHlwZUVycm9yLCB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLCByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZT1bMTIzNF0pCisKKyAgZGVmIHRlc3RDb25zdHJ1Y3RvckludmFsaWRhdGVzQ2FjaGVkQnl0ZVNpemUoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMob3B0aW9uYWxfaW50MzIgPSAxMikKKyAgICBzZWxmLmFzc2VydEVxdWFscygyLCBtZXNzYWdlLkJ5dGVTaXplKCkpCisKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygKKyAgICAgICAgb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygzLCBtZXNzYWdlLkJ5dGVTaXplKCkpCisKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcyhyZXBlYXRlZF9pbnQzMiA9IFsxMl0pCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoMywgbWVzc2FnZS5CeXRlU2l6ZSgpKQorCisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoCisgICAgICAgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gW3VuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSgpXSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygzLCBtZXNzYWdlLkJ5dGVTaXplKCkpCisKKyAgZGVmIHRlc3RTaW1wbGVIYXNCaXRzKHNlbGYpOgorICAgICMgVGVzdCBhIHNjYWxhci4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX2ludDMyJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBwcm90by5vcHRpb25hbF9pbnQzMikKKyAgICAjIEhhc0ZpZWxkKCkgc2hvdWxkbid0IGJlIHRydWUgaWYgYWxsIHdlJ3ZlIGRvbmUgaXMKKyAgICAjIHJlYWQgdGhlIGRlZmF1bHQgdmFsdWUuCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfaW50MzInKSkKKyAgICBwcm90by5vcHRpb25hbF9pbnQzMiA9IDEKKyAgICAjIFNldHRpbmcgYSB2YWx1ZSBob3dldmVyICpzaG91bGQqIHNldCB0aGUgImhhcyIgYml0LgorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfaW50MzInKSkKKyAgICBwcm90by5DbGVhckZpZWxkKCdvcHRpb25hbF9pbnQzMicpCisgICAgIyBBbmQgY2xlYXJpbmcgdGhhdCB2YWx1ZSBzaG91bGQgdW5zZXQgdGhlICJoYXMiIGJpdC4KKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9pbnQzMicpKQorCisgIGRlZiB0ZXN0SGFzQml0c1dpdGhTaW5nbHlOZXN0ZWRTY2FsYXIoc2VsZik6CisgICAgIyBIZWxwZXIgdXNlZCB0byB0ZXN0IGZvcmVpZ24gbWVzc2FnZXMgYW5kIGdyb3Vwcy4KKyAgICAjCisgICAgIyBjb21wb3NpdGVfZmllbGRfbmFtZSBzaG91bGQgYmUgdGhlIG5hbWUgb2YgYSBub24tcmVwZWF0ZWQKKyAgICAjIGNvbXBvc2l0ZSAoaS5lLiwgZm9yZWlnbiBvciBncm91cCkgZmllbGQgaW4gVGVzdEFsbFR5cGVzLAorICAgICMgYW5kIHNjYWxhcl9maWVsZF9uYW1lIHNob3VsZCBiZSB0aGUgbmFtZSBvZiBhbiBpbnRlZ2VyLXZhbHVlZAorICAgICMgc2NhbGFyIGZpZWxkIHdpdGhpbiB0aGF0IGNvbXBvc2l0ZS4KKyAgICAjCisgICAgIyBJIG5ldmVyIHRob3VnaHQgSSdkIG1pc3MgQysrIG1hY3JvcyBhbmQgdGVtcGxhdGVzIHNvIG11Y2guIDooCisgICAgIyBUaGlzIGhlbHBlciBpcyBzZW1hbnRpY2FsbHkganVzdDoKKyAgICAjCisgICAgIyAgIGFzc2VydCBwcm90by5jb21wb3NpdGVfZmllbGQuc2NhbGFyX2ZpZWxkID09IDAKKyAgICAjICAgYXNzZXJ0IG5vdCBwcm90by5jb21wb3NpdGVfZmllbGQuSGFzRmllbGQoJ3NjYWxhcl9maWVsZCcpCisgICAgIyAgIGFzc2VydCBub3QgcHJvdG8uSGFzRmllbGQoJ2NvbXBvc2l0ZV9maWVsZCcpCisgICAgIworICAgICMgICBwcm90by5jb21wb3NpdGVfZmllbGQuc2NhbGFyX2ZpZWxkID0gMTAKKyAgICAjICAgb2xkX2NvbXBvc2l0ZV9maWVsZCA9IHByb3RvLmNvbXBvc2l0ZV9maWVsZAorICAgICMKKyAgICAjICAgYXNzZXJ0IHByb3RvLmNvbXBvc2l0ZV9maWVsZC5zY2FsYXJfZmllbGQgPT0gMTAKKyAgICAjICAgYXNzZXJ0IHByb3RvLmNvbXBvc2l0ZV9maWVsZC5IYXNGaWVsZCgnc2NhbGFyX2ZpZWxkJykKKyAgICAjICAgYXNzZXJ0IHByb3RvLkhhc0ZpZWxkKCdjb21wb3NpdGVfZmllbGQnKQorICAgICMKKyAgICAjICAgcHJvdG8uQ2xlYXJGaWVsZCgnY29tcG9zaXRlX2ZpZWxkJykKKyAgICAjCisgICAgIyAgIGFzc2VydCBub3QgcHJvdG8uY29tcG9zaXRlX2ZpZWxkLkhhc0ZpZWxkKCdzY2FsYXJfZmllbGQnKQorICAgICMgICBhc3NlcnQgbm90IHByb3RvLkhhc0ZpZWxkKCdjb21wb3NpdGVfZmllbGQnKQorICAgICMgICBhc3NlcnQgcHJvdG8uY29tcG9zaXRlX2ZpZWxkLnNjYWxhcl9maWVsZCA9PSAwCisgICAgIworICAgICMgICAjIE5vdyBlbnN1cmUgdGhhdCBDbGVhckZpZWxkKCdjb21wb3NpdGVfZmllbGQnKSBkaXNjb25uZWN0ZWQKKyAgICAjICAgIyB0aGUgb2xkIGZpZWxkIG9iamVjdCBmcm9tIHRoZSBvYmplY3QgdHJlZS4uLgorICAgICMgICBhc3NlcnQgb2xkX2NvbXBvc2l0ZV9maWVsZCBpcyBub3QgcHJvdG8uY29tcG9zaXRlX2ZpZWxkCisgICAgIyAgIG9sZF9jb21wb3NpdGVfZmllbGQuc2NhbGFyX2ZpZWxkID0gMjAKKyAgICAjICAgYXNzZXJ0IG5vdCBwcm90by5jb21wb3NpdGVfZmllbGQuSGFzRmllbGQoJ3NjYWxhcl9maWVsZCcpCisgICAgIyAgIGFzc2VydCBub3QgcHJvdG8uSGFzRmllbGQoJ2NvbXBvc2l0ZV9maWVsZCcpCisgICAgZGVmIFRlc3RDb21wb3NpdGVIYXNCaXRzKGNvbXBvc2l0ZV9maWVsZF9uYW1lLCBzY2FsYXJfZmllbGRfbmFtZSk6CisgICAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgICAgIyBGaXJzdCwgY2hlY2sgdGhhdCB3ZSBjYW4gZ2V0IHRoZSBzY2FsYXIgdmFsdWUsIGFuZCBzZWUgdGhhdCBpdCdzIHRoZQorICAgICAgIyBkZWZhdWx0ICgwKSwgYnV0IHRoYXQgcHJvdG8uSGFzRmllbGQoJ29tcG9zaXRlJykgYW5kCisgICAgICAjIHByb3RvLmNvbXBvc2l0ZS5IYXNGaWVsZCgnc2NhbGFyJykgd2lsbCBzdGlsbCByZXR1cm4gRmFsc2UuCisgICAgICBjb21wb3NpdGVfZmllbGQgPSBnZXRhdHRyKHByb3RvLCBjb21wb3NpdGVfZmllbGRfbmFtZSkKKyAgICAgIG9yaWdpbmFsX3NjYWxhcl92YWx1ZSA9IGdldGF0dHIoY29tcG9zaXRlX2ZpZWxkLCBzY2FsYXJfZmllbGRfbmFtZSkKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgb3JpZ2luYWxfc2NhbGFyX3ZhbHVlKQorICAgICAgIyBBc3NlcnQgdGhhdCB0aGUgY29tcG9zaXRlIG9iamVjdCBkb2VzIG5vdCAiaGF2ZSIgdGhlIHNjYWxhci4KKyAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgY29tcG9zaXRlX2ZpZWxkLkhhc0ZpZWxkKHNjYWxhcl9maWVsZF9uYW1lKSkKKyAgICAgICMgQXNzZXJ0IHRoYXQgcHJvdG8gZG9lcyBub3QgImhhdmUiIHRoZSBjb21wb3NpdGUgZmllbGQuCisgICAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKGNvbXBvc2l0ZV9maWVsZF9uYW1lKSkKKworICAgICAgIyBOb3cgc2V0IHRoZSBzY2FsYXIgd2l0aGluIHRoZSBjb21wb3NpdGUgZmllbGQuICBFbnN1cmUgdGhhdCB0aGUgc2V0dGluZworICAgICAgIyBpcyByZWZsZWN0ZWQsIGFuZCB0aGF0IHByb3RvLkhhc0ZpZWxkKCdjb21wb3NpdGUnKSBhbmQKKyAgICAgICMgcHJvdG8uY29tcG9zaXRlLkhhc0ZpZWxkKCdzY2FsYXInKSBub3cgYm90aCByZXR1cm4gVHJ1ZS4KKyAgICAgIG5ld192YWwgPSAyMAorICAgICAgc2V0YXR0cihjb21wb3NpdGVfZmllbGQsIHNjYWxhcl9maWVsZF9uYW1lLCBuZXdfdmFsKQorICAgICAgc2VsZi5hc3NlcnRFcXVhbChuZXdfdmFsLCBnZXRhdHRyKGNvbXBvc2l0ZV9maWVsZCwgc2NhbGFyX2ZpZWxkX25hbWUpKQorICAgICAgIyBIb2xkIG9uIHRvIGEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IGNvbXBvc2l0ZV9maWVsZCBvYmplY3QuCisgICAgICBvbGRfY29tcG9zaXRlX2ZpZWxkID0gY29tcG9zaXRlX2ZpZWxkCisgICAgICAjIEFzc2VydCB0aGF0IHRoZSBoYXMgbWV0aG9kcyBub3cgcmV0dXJuIHRydWUuCisgICAgICBzZWxmLmFzc2VydFRydWUoY29tcG9zaXRlX2ZpZWxkLkhhc0ZpZWxkKHNjYWxhcl9maWVsZF9uYW1lKSkKKyAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5IYXNGaWVsZChjb21wb3NpdGVfZmllbGRfbmFtZSkpCisKKyAgICAgICMgTm93IGNhbGwgdGhlIGNsZWFyIG1ldGhvZC4uLgorICAgICAgcHJvdG8uQ2xlYXJGaWVsZChjb21wb3NpdGVfZmllbGRfbmFtZSkKKworICAgICAgIyAuLi5hbmQgZW5zdXJlIHRoYXQgdGhlICJoYXMiIGJpdHMgYXJlIGFsbCBiYWNrIHRvIEZhbHNlLi4uCisgICAgICBjb21wb3NpdGVfZmllbGQgPSBnZXRhdHRyKHByb3RvLCBjb21wb3NpdGVfZmllbGRfbmFtZSkKKyAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgY29tcG9zaXRlX2ZpZWxkLkhhc0ZpZWxkKHNjYWxhcl9maWVsZF9uYW1lKSkKKyAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8uSGFzRmllbGQoY29tcG9zaXRlX2ZpZWxkX25hbWUpKQorICAgICAgIyAuLi5hbmQgZW5zdXJlIHRoYXQgdGhlIHNjYWxhciBmaWVsZCBoYXMgcmV0dXJuZWQgdG8gaXRzIGRlZmF1bHQuCisgICAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGdldGF0dHIoY29tcG9zaXRlX2ZpZWxkLCBzY2FsYXJfZmllbGRfbmFtZSkpCisKKyAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShvbGRfY29tcG9zaXRlX2ZpZWxkIGlzIG5vdCBjb21wb3NpdGVfZmllbGQpCisgICAgICBzZXRhdHRyKG9sZF9jb21wb3NpdGVfZmllbGQsIHNjYWxhcl9maWVsZF9uYW1lLCBuZXdfdmFsKQorICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBjb21wb3NpdGVfZmllbGQuSGFzRmllbGQoc2NhbGFyX2ZpZWxkX25hbWUpKQorICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBwcm90by5IYXNGaWVsZChjb21wb3NpdGVfZmllbGRfbmFtZSkpCisgICAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGdldGF0dHIoY29tcG9zaXRlX2ZpZWxkLCBzY2FsYXJfZmllbGRfbmFtZSkpCisKKyAgICAjIFRlc3Qgc2ltcGxlLCBzaW5nbGUtbGV2ZWwgbmVzdGluZyB3aGVuIHdlIHNldCBhIHNjYWxhci4KKyAgICBUZXN0Q29tcG9zaXRlSGFzQml0cygnb3B0aW9uYWxncm91cCcsICdhJykKKyAgICBUZXN0Q29tcG9zaXRlSGFzQml0cygnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UnLCAnYmInKQorICAgIFRlc3RDb21wb3NpdGVIYXNCaXRzKCdvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UnLCAnYycpCisgICAgVGVzdENvbXBvc2l0ZUhhc0JpdHMoJ29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlJywgJ2QnKQorCisgIGRlZiB0ZXN0UmVmZXJlbmNlc1RvTmVzdGVkTWVzc2FnZShzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIG5lc3RlZCA9IHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlCisgICAgZGVsIHByb3RvCisgICAgIyBBIHByZXZpb3VzIHZlcnNpb24gaGFkIGEgYnVnIHdoZXJlIHRoaXMgd291bGQgcmFpc2UgYW4gZXhjZXB0aW9uIHdoZW4KKyAgICAjIGhpdHRpbmcgYSBub3ctZGVhZCB3ZWFrIHJlZmVyZW5jZS4KKyAgICBuZXN0ZWQuYmIgPSAyMworCisgIGRlZiB0ZXN0RGlzY29ubmVjdGluZ05lc3RlZE1lc3NhZ2VCZWZvcmVTZXR0aW5nRmllbGQoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBuZXN0ZWQgPSBwcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZQorICAgIHByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykgICMgU2hvdWxkIGRpc2Nvbm5lY3QgZnJvbSBwYXJlbnQKKyAgICBzZWxmLmFzc2VydFRydWUobmVzdGVkIGlzIG5vdCBwcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSkKKyAgICBuZXN0ZWQuYmIgPSAyMworICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBwcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYikKKworICBkZWYgdGVzdEdldERlZmF1bHRNZXNzYWdlQWZ0ZXJEaXNjb25uZWN0aW5nRGVmYXVsdE1lc3NhZ2Uoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBuZXN0ZWQgPSBwcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZQorICAgIHByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykKKyAgICBkZWwgcHJvdG8KKyAgICBkZWwgbmVzdGVkCisgICAgIyBGb3JjZSBhIGdhcmJhZ2UgY29sbGVjdCBzbyB0aGF0IHRoZSB1bmRlcmx5aW5nIENNZXNzYWdlcyBhcmUgZnJlZWQgYWxvbmcKKyAgICAjIHdpdGggdGhlIE1lc3NhZ2VzIHRoZXkgcG9pbnQgdG8uIFRoaXMgaXMgdG8gbWFrZSBzdXJlIHdlJ3JlIG5vdCBkZWxldGluZworICAgICMgZGVmYXVsdCBtZXNzYWdlIGluc3RhbmNlcy4KKyAgICBnYy5jb2xsZWN0KCkKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIG5lc3RlZCA9IHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlCisKKyAgZGVmIHRlc3REaXNjb25uZWN0aW5nTmVzdGVkTWVzc2FnZUFmdGVyU2V0dGluZ0ZpZWxkKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgbmVzdGVkID0gcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UKKyAgICBuZXN0ZWQuYmIgPSA1CisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorICAgIHByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykgICMgU2hvdWxkIGRpc2Nvbm5lY3QgZnJvbSBwYXJlbnQKKyAgICBzZWxmLmFzc2VydEVxdWFsKDUsIG5lc3RlZC5iYikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShuZXN0ZWQgaXMgbm90IHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKQorICAgIG5lc3RlZC5iYiA9IDIzCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiKQorCisgIGRlZiB0ZXN0RGlzY29ubmVjdGluZ05lc3RlZE1lc3NhZ2VCZWZvcmVHZXR0aW5nRmllbGQoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorICAgIHByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorCisgIGRlZiB0ZXN0RGlzY29ubmVjdGluZ05lc3RlZE1lc3NhZ2VBZnRlck1lcmdlKHNlbGYpOgorICAgICMgVGhpcyB0ZXN0IGV4ZXJjaXNlcyB0aGUgY29kZSBwYXRoIHRoYXQgZG9lcyBub3QgdXNlIFJlbGVhc2VNZXNzYWdlKCkuCisgICAgIyBUaGUgdW5kZXJseWluZyBmZWFyIGlzIHRoYXQgaWYgd2UgdXNlIFJlbGVhc2VNZXNzYWdlKCkgaW5jb3JyZWN0bHksCisgICAgIyB3ZSB3aWxsIGhhdmUgbWVtb3J5IGxlYWtzLiAgSXQncyBoYXJkIHRvIGNoZWNrIHRoYXQgdGhhdCBkb2Vzbid0IGhhcHBlbiwKKyAgICAjIGJ1dCBhdCBsZWFzdCB3ZSBjYW4gZXhlcmNpc2UgdGhhdCBjb2RlIHBhdGggdG8gbWFrZSBzdXJlIGl0IHdvcmtzLgorICAgIHByb3RvMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMi5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYiA9IDUKKyAgICBwcm90bzEuTWVyZ2VGcm9tKHByb3RvMikKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8xLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorICAgIHByb3RvMS5DbGVhckZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBwcm90bzEuSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisKKyAgZGVmIHRlc3REaXNjb25uZWN0aW5nTGF6eU5lc3RlZE1lc3NhZ2Uoc2VsZik6CisgICAgIyBUaGlzIHRlc3QgZXhlcmNpc2VzIHJlbGVhc2luZyBhIG5lc3RlZCBtZXNzYWdlIHRoYXQgaXMgbGF6eS4gVGhpcyB0ZXN0CisgICAgIyBvbmx5IGV4ZXJjaXNlcyByZWFsIGNvZGUgaW4gdGhlIEMrKyBpbXBsZW1lbnRhdGlvbiBhcyBQeXRob24gZG9lcyBub3QKKyAgICAjIHN1cHBvcnQgbGF6eSBwYXJzaW5nLCBidXQgdGhlIGN1cnJlbnQgQysrIGltcGxlbWVudGF0aW9uIHJlc3VsdHMgaW4KKyAgICAjIG1lbW9yeSBjb3JydXB0aW9uIGFuZCBhIGNyYXNoLgorICAgIGlmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgIT0gJ3B5dGhvbic6CisgICAgICByZXR1cm4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLm9wdGlvbmFsX2xhenlfbWVzc2FnZS5iYiA9IDUKKyAgICBwcm90by5DbGVhckZpZWxkKCdvcHRpb25hbF9sYXp5X21lc3NhZ2UnKQorICAgIGRlbCBwcm90bworICAgIGdjLmNvbGxlY3QoKQorCisgIGRlZiB0ZXN0SGFzQml0c1doZW5Nb2RpZnlpbmdSZXBlYXRlZEZpZWxkcyhzZWxmKToKKyAgICAjIFRlc3QgbmVzdGluZyB3aGVuIHdlIGFkZCBhbiBlbGVtZW50IHRvIGEgcmVwZWF0ZWQgZmllbGQgaW4gYSBzdWJtZXNzYWdlLgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cygpCisgICAgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UubmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9pbnQzMi5hcHBlbmQoNSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBbNV0sIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLm5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorCisgICAgIyBEbyB0aGUgc2FtZSB0ZXN0LCBidXQgd2l0aCBhIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZCB3aXRoaW4gdGhlCisgICAgIyBzdWJtZXNzYWdlLgorICAgIHByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorICAgIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLm5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UuYWRkKCkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisKKyAgZGVmIHRlc3RIYXNCaXRzRm9yTWFueUxldmVsc09mTmVzdGluZyhzZWxmKToKKyAgICAjIFRlc3QgbmVzdGluZyBtYW55IGxldmVscyBkZWVwLgorICAgIHJlY3Vyc2l2ZV9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0TXV0dWFsUmVjdXJzaW9uQSgpCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCByZWN1cnNpdmVfcHJvdG8uSGFzRmllbGQoJ2JiJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCByZWN1cnNpdmVfcHJvdG8uYmIuYS5iYi5hLmJiLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcmVjdXJzaXZlX3Byb3RvLkhhc0ZpZWxkKCdiYicpKQorICAgIHJlY3Vyc2l2ZV9wcm90by5iYi5hLmJiLmEuYmIub3B0aW9uYWxfaW50MzIgPSA1CisgICAgc2VsZi5hc3NlcnRFcXVhbCg1LCByZWN1cnNpdmVfcHJvdG8uYmIuYS5iYi5hLmJiLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWN1cnNpdmVfcHJvdG8uSGFzRmllbGQoJ2JiJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKHJlY3Vyc2l2ZV9wcm90by5iYi5IYXNGaWVsZCgnYScpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWN1cnNpdmVfcHJvdG8uYmIuYS5IYXNGaWVsZCgnYmInKSkKKyAgICBzZWxmLmFzc2VydFRydWUocmVjdXJzaXZlX3Byb3RvLmJiLmEuYmIuSGFzRmllbGQoJ2EnKSkKKyAgICBzZWxmLmFzc2VydFRydWUocmVjdXJzaXZlX3Byb3RvLmJiLmEuYmIuYS5IYXNGaWVsZCgnYmInKSkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHJlY3Vyc2l2ZV9wcm90by5iYi5hLmJiLmEuYmIuSGFzRmllbGQoJ2EnKSkKKyAgICBzZWxmLmFzc2VydFRydWUocmVjdXJzaXZlX3Byb3RvLmJiLmEuYmIuYS5iYi5IYXNGaWVsZCgnb3B0aW9uYWxfaW50MzInKSkKKworICBkZWYgdGVzdFNpbmd1bGFyTGlzdEZpZWxkcyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLm9wdGlvbmFsX2ZpeGVkMzIgPSAxCisgICAgcHJvdG8ub3B0aW9uYWxfaW50MzIgPSA1CisgICAgcHJvdG8ub3B0aW9uYWxfc3RyaW5nID0gJ2ZvbycKKyAgICAjIEFjY2VzcyBzdWItbWVzc2FnZSBidXQgZG9uJ3Qgc2V0IGl0IHlldC4KKyAgICBuZXN0ZWRfbWVzc2FnZSA9IHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgIFsgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ29wdGlvbmFsX2ludDMyJyAgXSwgNSksCisgICAgICAgIChwcm90by5ERVNDUklQVE9SLmZpZWxkc19ieV9uYW1lWydvcHRpb25hbF9maXhlZDMyJ10sIDEpLAorICAgICAgICAocHJvdG8uREVTQ1JJUFRPUi5maWVsZHNfYnlfbmFtZVsnb3B0aW9uYWxfc3RyaW5nJyBdLCAnZm9vJykgXSwKKyAgICAgIHByb3RvLkxpc3RGaWVsZHMoKSkKKworICAgIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiID0gMTIzCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgIFsgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ29wdGlvbmFsX2ludDMyJyAgXSwgNSksCisgICAgICAgIChwcm90by5ERVNDUklQVE9SLmZpZWxkc19ieV9uYW1lWydvcHRpb25hbF9maXhlZDMyJ10sIDEpLAorICAgICAgICAocHJvdG8uREVTQ1JJUFRPUi5maWVsZHNfYnlfbmFtZVsnb3B0aW9uYWxfc3RyaW5nJyBdLCAnZm9vJyksCisgICAgICAgIChwcm90by5ERVNDUklQVE9SLmZpZWxkc19ieV9uYW1lWydvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScgXSwKKyAgICAgICAgICAgICBuZXN0ZWRfbWVzc2FnZSkgXSwKKyAgICAgIHByb3RvLkxpc3RGaWVsZHMoKSkKKworICBkZWYgdGVzdFJlcGVhdGVkTGlzdEZpZWxkcyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLnJlcGVhdGVkX2ZpeGVkMzIuYXBwZW5kKDEpCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDUpCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDExKQorICAgIHByb3RvLnJlcGVhdGVkX3N0cmluZy5leHRlbmQoWydmb28nLCAnYmFyJ10pCisgICAgcHJvdG8ucmVwZWF0ZWRfc3RyaW5nLmV4dGVuZChbXSkKKyAgICBwcm90by5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKCdiYXonKQorICAgIHByb3RvLnJlcGVhdGVkX3N0cmluZy5leHRlbmQoc3RyKHgpIGZvciB4IGluIHhyYW5nZSgyKSkKKyAgICBwcm90by5vcHRpb25hbF9pbnQzMiA9IDIxCisgICAgcHJvdG8ucmVwZWF0ZWRfYm9vbCAgIyBBY2Nlc3MgYnV0IGRvbid0IHNldCBhbnl0aGluZzsgc2hvdWxkIG5vdCBiZSBsaXN0ZWQuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgIFsgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ29wdGlvbmFsX2ludDMyJyAgXSwgMjEpLAorICAgICAgICAocHJvdG8uREVTQ1JJUFRPUi5maWVsZHNfYnlfbmFtZVsncmVwZWF0ZWRfaW50MzInICBdLCBbNSwgMTFdKSwKKyAgICAgICAgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ3JlcGVhdGVkX2ZpeGVkMzInXSwgWzFdKSwKKyAgICAgICAgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ3JlcGVhdGVkX3N0cmluZycgXSwKKyAgICAgICAgICBbJ2ZvbycsICdiYXInLCAnYmF6JywgJzAnLCAnMSddKSBdLAorICAgICAgcHJvdG8uTGlzdEZpZWxkcygpKQorCisgIGRlZiB0ZXN0U2luZ3VsYXJMaXN0RXh0ZW5zaW9ucyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgcHJvdG8uRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIub3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25dID0gMQorICAgIHByb3RvLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgXSA9IDUKKyAgICBwcm90by5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5vcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uIF0gPSAnZm9vJworICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICBbICh1bml0dGVzdF9wYjIub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uICAsIDUpLAorICAgICAgICAodW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uLCAxKSwKKyAgICAgICAgKHVuaXR0ZXN0X3BiMi5vcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uICwgJ2ZvbycpIF0sCisgICAgICBwcm90by5MaXN0RmllbGRzKCkpCisKKyAgZGVmIHRlc3RSZXBlYXRlZExpc3RFeHRlbnNpb25zKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICBwcm90by5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5yZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl0uYXBwZW5kKDEpCisgICAgcHJvdG8uRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIucmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICBdLmFwcGVuZCg1KQorICAgIHByb3RvLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgXS5hcHBlbmQoMTEpCisgICAgcHJvdG8uRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbiBdLmFwcGVuZCgnZm9vJykKKyAgICBwcm90by5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5yZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uIF0uYXBwZW5kKCdiYXInKQorICAgIHByb3RvLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gXS5hcHBlbmQoJ2JheicpCisgICAgcHJvdG8uRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uICBdID0gMjEKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgWyAodW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgLCAyMSksCisgICAgICAgICh1bml0dGVzdF9wYjIucmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAsIFs1LCAxMV0pLAorICAgICAgICAodW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uLCBbMV0pLAorICAgICAgICAodW5pdHRlc3RfcGIyLnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gLCBbJ2ZvbycsICdiYXInLCAnYmF6J10pIF0sCisgICAgICBwcm90by5MaXN0RmllbGRzKCkpCisKKyAgZGVmIHRlc3RMaXN0RmllbGRzQW5kRXh0ZW5zaW9ucyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0RmllbGRPcmRlcmluZ3MoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHNBbmRFeHRlbnNpb25zKHByb3RvKQorICAgIHVuaXR0ZXN0X3BiMi5teV9leHRlbnNpb25faW50CisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgIFsgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ215X2ludCcgICBdLCAxKSwKKyAgICAgICAgKHVuaXR0ZXN0X3BiMi5teV9leHRlbnNpb25faW50ICAgICAgICAgICAgICAgLCAyMyksCisgICAgICAgIChwcm90by5ERVNDUklQVE9SLmZpZWxkc19ieV9uYW1lWydteV9zdHJpbmcnXSwgJ2ZvbycpLAorICAgICAgICAodW5pdHRlc3RfcGIyLm15X2V4dGVuc2lvbl9zdHJpbmcgICAgICAgICAgICAsICdiYXInKSwKKyAgICAgICAgKHByb3RvLkRFU0NSSVBUT1IuZmllbGRzX2J5X25hbWVbJ215X2Zsb2F0JyBdLCAxLjApIF0sCisgICAgICBwcm90by5MaXN0RmllbGRzKCkpCisKKyAgZGVmIHRlc3REZWZhdWx0VmFsdWVzKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBwcm90by5vcHRpb25hbF9pbnQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX2ludDY0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfdWludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfdWludDY0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfc2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfc2ludDY0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfZml4ZWQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX2ZpeGVkNjQpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBwcm90by5vcHRpb25hbF9zZml4ZWQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX3NmaXhlZDY0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMC4wLCBwcm90by5vcHRpb25hbF9mbG9hdCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAuMCwgcHJvdG8ub3B0aW9uYWxfZG91YmxlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoRmFsc2UsIHByb3RvLm9wdGlvbmFsX2Jvb2wpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnJywgcHJvdG8ub3B0aW9uYWxfc3RyaW5nKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoYicnLCBwcm90by5vcHRpb25hbF9ieXRlcykKKworICAgIHNlbGYuYXNzZXJ0RXF1YWwoNDEsIHByb3RvLmRlZmF1bHRfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0MiwgcHJvdG8uZGVmYXVsdF9pbnQ2NCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQzLCBwcm90by5kZWZhdWx0X3VpbnQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQ0LCBwcm90by5kZWZhdWx0X3VpbnQ2NCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKC00NSwgcHJvdG8uZGVmYXVsdF9zaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0NiwgcHJvdG8uZGVmYXVsdF9zaW50NjQpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0NywgcHJvdG8uZGVmYXVsdF9maXhlZDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNDgsIHByb3RvLmRlZmF1bHRfZml4ZWQ2NCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQ5LCBwcm90by5kZWZhdWx0X3NmaXhlZDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoLTUwLCBwcm90by5kZWZhdWx0X3NmaXhlZDY0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNTEuNSwgcHJvdG8uZGVmYXVsdF9mbG9hdCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDUyZTMsIHByb3RvLmRlZmF1bHRfZG91YmxlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoVHJ1ZSwgcHJvdG8uZGVmYXVsdF9ib29sKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ2hlbGxvJywgcHJvdG8uZGVmYXVsdF9zdHJpbmcpCisgICAgc2VsZi5hc3NlcnRFcXVhbChiJ3dvcmxkJywgcHJvdG8uZGVmYXVsdF9ieXRlcykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuQkFSLCBwcm90by5kZWZhdWx0X25lc3RlZF9lbnVtKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLkZPUkVJR05fQkFSLCBwcm90by5kZWZhdWx0X2ZvcmVpZ25fZW51bSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X2ltcG9ydF9wYjIuSU1QT1JUX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgIHByb3RvLmRlZmF1bHRfaW1wb3J0X2VudW0pCisKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodSdcdTEyMzQnLCBwcm90by51dGY4X3N0cmluZykKKworICBkZWYgdGVzdEhhc0ZpZWxkV2l0aFVua25vd25GaWVsZE5hbWUoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBwcm90by5IYXNGaWVsZCwgJ25vbmV4aXN0ZW50X2ZpZWxkJykKKworICBkZWYgdGVzdENsZWFyRmllbGRXaXRoVW5rbm93bkZpZWxkTmFtZShzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHByb3RvLkNsZWFyRmllbGQsICdub25leGlzdGVudF9maWVsZCcpCisKKyAgZGVmIHRlc3RDbGVhclJlbW92ZXNDaGlsZHJlbihzZWxmKToKKyAgICAjIE1ha2Ugc3VyZSB0aGVyZSBhcmVuJ3QgYW55IGltcGxlbWVudGF0aW9uIGJ1Z3MgdGhhdCBhcmUgb25seSBwYXJ0aWFsbHkKKyAgICAjIGNsZWFyaW5nIHRoZSBtZXNzYWdlICh3aGljaCBjYW4gaGFwcGVuIGluIHRoZSBtb3JlIGNvbXBsZXggQysrCisgICAgIyBpbXBsZW1lbnRhdGlvbiB3aGljaCBoYXMgcGFyYWxsZWwgbWVzc2FnZSBsaXN0cykuCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkRm9yZWlnbigpCisgICAgZm9yIGkgaW4gcmFuZ2UoMTApOgorICAgICAgcHJvdG8ucmVwZWF0ZWRfbWVzc2FnZS5hZGQoKQorICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWRGb3JlaWduKCkKKyAgICBwcm90by5Db3B5RnJvbShwcm90bzIpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoSW5kZXhFcnJvciwgbGFtYmRhOiBwcm90by5yZXBlYXRlZF9tZXNzYWdlWzVdKQorCisgIGRlZiB0ZXN0RGlzYWxsb3dlZEFzc2lnbm1lbnRzKHNlbGYpOgorICAgICMgSXQncyBpbGxlZ2FsIHRvIGFzc2lnbiB2YWx1ZXMgZGlyZWN0bHkgdG8gcmVwZWF0ZWQgZmllbGRzCisgICAgIyBvciB0byBub25yZXBlYXRlZCBjb21wb3NpdGUgZmllbGRzLiAgRW5zdXJlIHRoYXQgdGhpcyBmYWlscy4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgICMgUmVwZWF0ZWQgZmllbGRzLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEF0dHJpYnV0ZUVycm9yLCBzZXRhdHRyLCBwcm90bywgJ3JlcGVhdGVkX2ludDMyJywgMTApCisgICAgIyBMaXN0cyBzaG91bGRuJ3Qgd29yaywgZWl0aGVyLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEF0dHJpYnV0ZUVycm9yLCBzZXRhdHRyLCBwcm90bywgJ3JlcGVhdGVkX2ludDMyJywgWzEwXSkKKyAgICAjIENvbXBvc2l0ZSBmaWVsZHMuCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoQXR0cmlidXRlRXJyb3IsIHNldGF0dHIsIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScsIDIzKQorICAgICMgQXNzaWdubWVudCB0byBhIHJlcGVhdGVkIG5lc3RlZCBtZXNzYWdlIGZpZWxkIHdpdGhvdXQgc3BlY2lmeWluZworICAgICMgdGhlIGluZGV4IGluIHRoZSBhcnJheSBvZiBuZXN0ZWQgbWVzc2FnZXMuCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoQXR0cmlidXRlRXJyb3IsIHNldGF0dHIsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICdiYicsIDM0KQorICAgICMgQXNzaWdubWVudCB0byBhbiBhdHRyaWJ1dGUgb2YgYSByZXBlYXRlZCBmaWVsZC4KKyAgICBzZWxmLmFzc2VydFJhaXNlcyhBdHRyaWJ1dGVFcnJvciwgc2V0YXR0ciwgcHJvdG8ucmVwZWF0ZWRfZmxvYXQsCisgICAgICAgICAgICAgICAgICAgICAgJ3NvbWVfYXR0cmlidXRlJywgMzQpCisgICAgIyBwcm90by5ub25leGlzdGVudF9maWVsZCA9IDIzIHNob3VsZCBmYWlsIGFzIHdlbGwuCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoQXR0cmlidXRlRXJyb3IsIHNldGF0dHIsIHByb3RvLCAnbm9uZXhpc3RlbnRfZmllbGQnLCAyMykKKworICBkZWYgdGVzdFNpbmdsZVNjYWxhclR5cGVTYWZldHkoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNldGF0dHIsIHByb3RvLCAnb3B0aW9uYWxfaW50MzInLCAxLjEpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZXRhdHRyLCBwcm90bywgJ29wdGlvbmFsX2ludDMyJywgJ2ZvbycpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZXRhdHRyLCBwcm90bywgJ29wdGlvbmFsX3N0cmluZycsIDEwKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgc2V0YXR0ciwgcHJvdG8sICdvcHRpb25hbF9ieXRlcycsIDEwKQorCisgIGRlZiB0ZXN0SW50ZWdlclR5cGVzKHNlbGYpOgorICAgIGRlZiBUZXN0R2V0QW5kRGVzZXJpYWxpemUoZmllbGRfbmFtZSwgdmFsdWUsIGV4cGVjdGVkX3R5cGUpOgorICAgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICAgIHNldGF0dHIocHJvdG8sIGZpZWxkX25hbWUsIHZhbHVlKQorICAgICAgc2VsZi5hc3NlcnRUcnVlKGlzaW5zdGFuY2UoZ2V0YXR0cihwcm90bywgZmllbGRfbmFtZSksIGV4cGVjdGVkX3R5cGUpKQorICAgICAgcHJvdG8yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgICBwcm90bzIuUGFyc2VGcm9tU3RyaW5nKHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgICBzZWxmLmFzc2VydFRydWUoaXNpbnN0YW5jZShnZXRhdHRyKHByb3RvMiwgZmllbGRfbmFtZSksIGV4cGVjdGVkX3R5cGUpKQorCisgICAgVGVzdEdldEFuZERlc2VyaWFsaXplKCdvcHRpb25hbF9pbnQzMicsIDEsIGludCkKKyAgICBUZXN0R2V0QW5kRGVzZXJpYWxpemUoJ29wdGlvbmFsX2ludDMyJywgMSA8PCAzMCwgaW50KQorICAgIFRlc3RHZXRBbmREZXNlcmlhbGl6ZSgnb3B0aW9uYWxfdWludDMyJywgMSA8PCAzMCwgaW50KQorICAgIGlmIHN0cnVjdC5jYWxjc2l6ZSgnTCcpID09IDQ6CisgICAgICAjIFB5dGhvbiBvbmx5IGhhcyBzaWduZWQgaW50cywgc28gMzItYml0IHB5dGhvbiBjYW4ndCBmaXQgYW4gdWludDMyCisgICAgICAjIGluIGFuIGludC4KKyAgICAgIFRlc3RHZXRBbmREZXNlcmlhbGl6ZSgnb3B0aW9uYWxfdWludDMyJywgMSA8PCAzMSwgbG9uZykKKyAgICBlbHNlOgorICAgICAgIyA2NC1iaXQgcHl0aG9uIGNhbiBmaXQgdWludDMyIGluc2lkZSBhbiBpbnQKKyAgICAgIFRlc3RHZXRBbmREZXNlcmlhbGl6ZSgnb3B0aW9uYWxfdWludDMyJywgMSA8PCAzMSwgaW50KQorICAgIFRlc3RHZXRBbmREZXNlcmlhbGl6ZSgnb3B0aW9uYWxfaW50NjQnLCAxIDw8IDMwLCBsb25nKQorICAgIFRlc3RHZXRBbmREZXNlcmlhbGl6ZSgnb3B0aW9uYWxfaW50NjQnLCAxIDw8IDYwLCBsb25nKQorICAgIFRlc3RHZXRBbmREZXNlcmlhbGl6ZSgnb3B0aW9uYWxfdWludDY0JywgMSA8PCAzMCwgbG9uZykKKyAgICBUZXN0R2V0QW5kRGVzZXJpYWxpemUoJ29wdGlvbmFsX3VpbnQ2NCcsIDEgPDwgNjAsIGxvbmcpCisKKyAgZGVmIHRlc3RTaW5nbGVTY2FsYXJCb3VuZHNDaGVja2luZyhzZWxmKToKKyAgICBkZWYgVGVzdE1pbkFuZE1heEludGVnZXJzKGZpZWxkX25hbWUsIGV4cGVjdGVkX21pbiwgZXhwZWN0ZWRfbWF4KToKKyAgICAgIHBiID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgICBzZXRhdHRyKHBiLCBmaWVsZF9uYW1lLCBleHBlY3RlZF9taW4pCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGV4cGVjdGVkX21pbiwgZ2V0YXR0cihwYiwgZmllbGRfbmFtZSkpCisgICAgICBzZXRhdHRyKHBiLCBmaWVsZF9uYW1lLCBleHBlY3RlZF9tYXgpCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGV4cGVjdGVkX21heCwgZ2V0YXR0cihwYiwgZmllbGRfbmFtZSkpCisgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBzZXRhdHRyLCBwYiwgZmllbGRfbmFtZSwgZXhwZWN0ZWRfbWluIC0gMSkKKyAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHNldGF0dHIsIHBiLCBmaWVsZF9uYW1lLCBleHBlY3RlZF9tYXggKyAxKQorCisgICAgVGVzdE1pbkFuZE1heEludGVnZXJzKCdvcHRpb25hbF9pbnQzMicsIC0oMSA8PCAzMSksICgxIDw8IDMxKSAtIDEpCisgICAgVGVzdE1pbkFuZE1heEludGVnZXJzKCdvcHRpb25hbF91aW50MzInLCAwLCAweGZmZmZmZmZmKQorICAgIFRlc3RNaW5BbmRNYXhJbnRlZ2Vycygnb3B0aW9uYWxfaW50NjQnLCAtKDEgPDwgNjMpLCAoMSA8PCA2MykgLSAxKQorICAgIFRlc3RNaW5BbmRNYXhJbnRlZ2Vycygnb3B0aW9uYWxfdWludDY0JywgMCwgMHhmZmZmZmZmZmZmZmZmZmZmKQorCisgICAgcGIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwYi5vcHRpb25hbF9uZXN0ZWRfZW51bSA9IDEKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHBiLm9wdGlvbmFsX25lc3RlZF9lbnVtKQorCisgIGRlZiB0ZXN0UmVwZWF0ZWRTY2FsYXJUeXBlU2FmZXR5KHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBwcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQsIDEuMSkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHByb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCwgJ2ZvbycpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBwcm90by5yZXBlYXRlZF9zdHJpbmcsIDEwKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgcHJvdG8ucmVwZWF0ZWRfYnl0ZXMsIDEwKQorCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDEwKQorICAgIHByb3RvLnJlcGVhdGVkX2ludDMyWzBdID0gMjMKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhJbmRleEVycm9yLCBwcm90by5yZXBlYXRlZF9pbnQzMi5fX3NldGl0ZW1fXywgNTAwLCAyMykKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHByb3RvLnJlcGVhdGVkX2ludDMyLl9fc2V0aXRlbV9fLCAwLCAnYWJjJykKKworICAgICMgUmVwZWF0ZWQgZW51bXMgdGVzdHMuCisgICAgI3Byb3RvLnJlcGVhdGVkX25lc3RlZF9lbnVtLmFwcGVuZCgwKQorCisgIGRlZiB0ZXN0U2luZ2xlU2NhbGFyR2V0dGVyc0FuZFNldHRlcnMoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX2ludDMyKQorICAgIHByb3RvLm9wdGlvbmFsX2ludDMyID0gMQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgcHJvdG8ub3B0aW9uYWxfaW50MzIpCisKKyAgICBwcm90by5vcHRpb25hbF91aW50NjQgPSAweGZmZmZmZmZmZmZmZgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMHhmZmZmZmZmZmZmZmYsIHByb3RvLm9wdGlvbmFsX3VpbnQ2NCkKKyAgICBwcm90by5vcHRpb25hbF91aW50NjQgPSAweGZmZmZmZmZmZmZmZmZmZmYKKyAgICBzZWxmLmFzc2VydEVxdWFsKDB4ZmZmZmZmZmZmZmZmZmZmZiwgcHJvdG8ub3B0aW9uYWxfdWludDY0KQorICAgICMgVE9ETyhyb2JpbnNvbik6IFRlc3QgYWxsIG90aGVyIHNjYWxhciBmaWVsZCB0eXBlcy4KKworICBkZWYgdGVzdFNpbmdsZVNjYWxhckNsZWFyRmllbGQoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICAjIFNob3VsZCBiZSBhbGxvd2VkIHRvIGNsZWFyIHNvbWV0aGluZyB0aGF0J3Mgbm90IHRoZXJlIChhIG5vLW9wKS4KKyAgICBwcm90by5DbGVhckZpZWxkKCdvcHRpb25hbF9pbnQzMicpCisgICAgcHJvdG8ub3B0aW9uYWxfaW50MzIgPSAxCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9pbnQzMicpKQorICAgIHByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX2ludDMyJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX2ludDMyJykpCisgICAgIyBUT0RPKHJvYmluc29uKTogVGVzdCBhbGwgb3RoZXIgc2NhbGFyIGZpZWxkIHR5cGVzLgorCisgIGRlZiB0ZXN0RW51bXMoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLkZPTykKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuRk9PKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgcHJvdG8uQkFSKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5CQVIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCBwcm90by5CQVopCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkJBWikKKworICBkZWYgdGVzdEVudW1fTmFtZShzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdGT1JFSUdOX0ZPTycsCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuRm9yZWlnbkVudW0uTmFtZSh1bml0dGVzdF9wYjIuRk9SRUlHTl9GT08pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ0ZPUkVJR05fQkFSJywKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduRW51bS5OYW1lKHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0JBUikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnRk9SRUlHTl9CQVonLAorICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZvcmVpZ25FbnVtLk5hbWUodW5pdHRlc3RfcGIyLkZPUkVJR05fQkFaKSkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduRW51bS5OYW1lLCAxMTMxMikKKworICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnRk9PJywKKyAgICAgICAgICAgICAgICAgICAgIHByb3RvLk5lc3RlZEVudW0uTmFtZShwcm90by5GT08pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ0ZPTycsCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uTmFtZShwcm90by5GT08pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ0JBUicsCisgICAgICAgICAgICAgICAgICAgICBwcm90by5OZXN0ZWRFbnVtLk5hbWUocHJvdG8uQkFSKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdCQVInLAorICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLk5hbWUocHJvdG8uQkFSKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdCQVonLAorICAgICAgICAgICAgICAgICAgICAgcHJvdG8uTmVzdGVkRW51bS5OYW1lKHByb3RvLkJBWikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnQkFaJywKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5OYW1lKHByb3RvLkJBWikpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICBwcm90by5OZXN0ZWRFbnVtLk5hbWUsIDExMzEyKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLk5hbWUsIDExMzEyKQorCisgIGRlZiB0ZXN0RW51bV9WYWx1ZShzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0ZPTywKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduRW51bS5WYWx1ZSgnRk9SRUlHTl9GT08nKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduRW51bS5WYWx1ZSgnRk9SRUlHTl9CQVInKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0JBWiwKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduRW51bS5WYWx1ZSgnRk9SRUlHTl9CQVonKSkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5Gb3JlaWduRW51bS5WYWx1ZSwgJ0ZPJykKKworICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcm90by5GT08sCisgICAgICAgICAgICAgICAgICAgICBwcm90by5OZXN0ZWRFbnVtLlZhbHVlKCdGT08nKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHByb3RvLkZPTywKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5WYWx1ZSgnRk9PJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcm90by5CQVIsCisgICAgICAgICAgICAgICAgICAgICBwcm90by5OZXN0ZWRFbnVtLlZhbHVlKCdCQVInKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHByb3RvLkJBUiwKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5WYWx1ZSgnQkFSJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcm90by5CQVosCisgICAgICAgICAgICAgICAgICAgICBwcm90by5OZXN0ZWRFbnVtLlZhbHVlKCdCQVonKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHByb3RvLkJBWiwKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5WYWx1ZSgnQkFaJykpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICBwcm90by5OZXN0ZWRFbnVtLlZhbHVlLCAnRm9vJykKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5WYWx1ZSwgJ0ZvbycpCisKKyAgZGVmIHRlc3RFbnVtX0tleXNBbmRWYWx1ZXMoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbChbJ0ZPUkVJR05fRk9PJywgJ0ZPUkVJR05fQkFSJywgJ0ZPUkVJR05fQkFaJ10sCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuRm9yZWlnbkVudW0ua2V5cygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWzQsIDUsIDZdLAorICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZvcmVpZ25FbnVtLnZhbHVlcygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWygnRk9SRUlHTl9GT08nLCA0KSwgKCdGT1JFSUdOX0JBUicsIDUpLAorICAgICAgICAgICAgICAgICAgICAgICgnRk9SRUlHTl9CQVonLCA2KV0sCisgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuRm9yZWlnbkVudW0uaXRlbXMoKSkKKworICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbJ0ZPTycsICdCQVInLCAnQkFaJywgJ05FRyddLCBwcm90by5OZXN0ZWRFbnVtLmtleXMoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFsxLCAyLCAzLCAtMV0sIHByb3RvLk5lc3RlZEVudW0udmFsdWVzKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbKCdGT08nLCAxKSwgKCdCQVInLCAyKSwgKCdCQVonLCAzKSwgKCdORUcnLCAtMSldLAorICAgICAgICAgICAgICAgICAgICAgcHJvdG8uTmVzdGVkRW51bS5pdGVtcygpKQorCisgIGRlZiB0ZXN0UmVwZWF0ZWRTY2FsYXJzKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLnJlcGVhdGVkX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbGVuKHByb3RvLnJlcGVhdGVkX2ludDMyKSkKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoNSkKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMTApCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDE1KQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5yZXBlYXRlZF9pbnQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMsIGxlbihwcm90by5yZXBlYXRlZF9pbnQzMikpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKFs1LCAxMCwgMTVdLCBwcm90by5yZXBlYXRlZF9pbnQzMikKKworICAgICMgVGVzdCBzaW5nbGUgcmV0cmlldmFsLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNSwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxNSwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbLTFdKQorICAgICMgVGVzdCBvdXQtb2YtYm91bmRzIGluZGljZXMuCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoSW5kZXhFcnJvciwgcHJvdG8ucmVwZWF0ZWRfaW50MzIuX19nZXRpdGVtX18sIDEyMzQpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoSW5kZXhFcnJvciwgcHJvdG8ucmVwZWF0ZWRfaW50MzIuX19nZXRpdGVtX18sIC0xMjM0KQorICAgICMgVGVzdCBpbmNvcnJlY3QgdHlwZXMgcGFzc2VkIHRvIF9fZ2V0aXRlbV9fLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgcHJvdG8ucmVwZWF0ZWRfaW50MzIuX19nZXRpdGVtX18sICdmb28nKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgcHJvdG8ucmVwZWF0ZWRfaW50MzIuX19nZXRpdGVtX18sIE5vbmUpCisKKyAgICAjIFRlc3Qgc2luZ2xlIGFzc2lnbm1lbnQuCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMV0gPSAyMAorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWzUsIDIwLCAxNV0sIHByb3RvLnJlcGVhdGVkX2ludDMyKQorCisgICAgIyBUZXN0IGluc2VydGlvbi4KKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5pbnNlcnQoMSwgMjUpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNSwgMjUsIDIwLCAxNV0sIHByb3RvLnJlcGVhdGVkX2ludDMyKQorCisgICAgIyBUZXN0IHNsaWNlIHJldHJpZXZhbC4KKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMzApCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMjUsIDIwLCAxNV0sIHByb3RvLnJlcGVhdGVkX2ludDMyWzE6NF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNSwgMjUsIDIwLCAxNSwgMzBdLCBwcm90by5yZXBlYXRlZF9pbnQzMls6XSkKKworICAgICMgVGVzdCBzbGljZSBhc3NpZ25tZW50IHdpdGggYW4gaXRlcmF0b3IKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMlsxOjRdID0gKGkgZm9yIGkgaW4geHJhbmdlKDMpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWzUsIDAsIDEsIDIsIDMwXSwgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisKKyAgICAjIFRlc3Qgc2xpY2UgYXNzaWdubWVudC4KKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMlsxOjRdID0gWzM1LCA0MCwgNDVdCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNSwgMzUsIDQwLCA0NSwgMzBdLCBwcm90by5yZXBlYXRlZF9pbnQzMikKKworICAgICMgVGVzdCB0aGF0IHdlIGNhbiB1c2UgdGhlIGZpZWxkIGFzIGFuIGl0ZXJhdG9yLgorICAgIHJlc3VsdCA9IFtdCisgICAgZm9yIGkgaW4gcHJvdG8ucmVwZWF0ZWRfaW50MzI6CisgICAgICByZXN1bHQuYXBwZW5kKGkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNSwgMzUsIDQwLCA0NSwgMzBdLCByZXN1bHQpCisKKyAgICAjIFRlc3Qgc2luZ2xlIGRlbGV0aW9uLgorICAgIGRlbCBwcm90by5yZXBlYXRlZF9pbnQzMlsyXQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWzUsIDM1LCA0NSwgMzBdLCBwcm90by5yZXBlYXRlZF9pbnQzMikKKworICAgICMgVGVzdCBzbGljZSBkZWxldGlvbi4KKyAgICBkZWwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMjpdCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNSwgMzVdLCBwcm90by5yZXBlYXRlZF9pbnQzMikKKworICAgICMgVGVzdCBleHRlbmRpbmcuCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIuZXh0ZW5kKFszLCAxM10pCisgICAgc2VsZi5hc3NlcnRFcXVhbChbNSwgMzUsIDMsIDEzXSwgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisKKyAgICAjIFRlc3QgY2xlYXJpbmcuCisgICAgcHJvdG8uQ2xlYXJGaWVsZCgncmVwZWF0ZWRfaW50MzInKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBsZW4ocHJvdG8ucmVwZWF0ZWRfaW50MzIpKQorCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90by5yZXBlYXRlZF9pbnQzMlstMV0pCisgICAgIyBUZXN0IGFzc2lnbm1lbnQgdG8gYSBuZWdhdGl2ZSBpbmRleC4KKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMlstMV0gPSAyCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBwcm90by5yZXBlYXRlZF9pbnQzMlstMV0pCisKKyAgICAjIFRlc3QgZGVsZXRpb24gYXQgbmVnYXRpdmUgaW5kaWNlcy4KKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMls6XSA9IFswLCAxLCAyLCAzXQorICAgIGRlbCBwcm90by5yZXBlYXRlZF9pbnQzMlstMV0KKyAgICBzZWxmLmFzc2VydEVxdWFsKFswLCAxLCAyXSwgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisKKyAgICBkZWwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbLTJdCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMCwgMl0sIHByb3RvLnJlcGVhdGVkX2ludDMyKQorCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoSW5kZXhFcnJvciwgcHJvdG8ucmVwZWF0ZWRfaW50MzIuX19kZWxpdGVtX18sIC0zKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEluZGV4RXJyb3IsIHByb3RvLnJlcGVhdGVkX2ludDMyLl9fZGVsaXRlbV9fLCAzMDApCisKKyAgICBkZWwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbLTI6LTFdCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMl0sIHByb3RvLnJlcGVhdGVkX2ludDMyKQorCisgICAgZGVsIHByb3RvLnJlcGVhdGVkX2ludDMyWzEwMDoxMDAwMF0KKyAgICBzZWxmLmFzc2VydEVxdWFsKFsyXSwgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisKKyAgZGVmIHRlc3RSZXBlYXRlZFNjYWxhcnNSZW1vdmUoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKworICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBsZW4ocHJvdG8ucmVwZWF0ZWRfaW50MzIpKQorICAgIHByb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCg1KQorICAgIHByb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxMCkKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoNSkKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoNSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWwoNCwgbGVuKHByb3RvLnJlcGVhdGVkX2ludDMyKSkKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5yZW1vdmUoNSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMsIGxlbihwcm90by5yZXBlYXRlZF9pbnQzMikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMCwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCg1LCBwcm90by5yZXBlYXRlZF9pbnQzMlsxXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDUsIHByb3RvLnJlcGVhdGVkX2ludDMyWzJdKQorCisgICAgcHJvdG8ucmVwZWF0ZWRfaW50MzIucmVtb3ZlKDUpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBsZW4ocHJvdG8ucmVwZWF0ZWRfaW50MzIpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTAsIHByb3RvLnJlcGVhdGVkX2ludDMyWzBdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNSwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMV0pCisKKyAgICBwcm90by5yZXBlYXRlZF9pbnQzMi5yZW1vdmUoMTApCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBsZW4ocHJvdG8ucmVwZWF0ZWRfaW50MzIpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNSwgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMF0pCisKKyAgICAjIFJlbW92ZSBhIG5vbi1leGlzdGVudCBlbGVtZW50LgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHByb3RvLnJlcGVhdGVkX2ludDMyLnJlbW92ZSwgMTIzKQorCisgIGRlZiB0ZXN0UmVwZWF0ZWRDb21wb3NpdGVzKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGxlbihwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSkpCisgICAgbTAgPSBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIG0xID0gcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBsZW4ocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpKQorICAgIHNlbGYuYXNzZXJ0TGlzdHNFcXVhbChbbTAsIG0xXSwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRUcnVlKGlzaW5zdGFuY2UobTAsIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkpCisKKyAgICAjIFRlc3Qgb3V0LW9mLWJvdW5kcyBpbmRpY2VzLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEluZGV4RXJyb3IsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLl9fZ2V0aXRlbV9fLAorICAgICAgICAgICAgICAgICAgICAgIDEyMzQpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoSW5kZXhFcnJvciwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuX19nZXRpdGVtX18sCisgICAgICAgICAgICAgICAgICAgICAgLTEyMzQpCisKKyAgICAjIFRlc3QgaW5jb3JyZWN0IHR5cGVzIHBhc3NlZCB0byBfX2dldGl0ZW1fXy4KKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLl9fZ2V0aXRlbV9fLAorICAgICAgICAgICAgICAgICAgICAgICdmb28nKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuX19nZXRpdGVtX18sCisgICAgICAgICAgICAgICAgICAgICAgTm9uZSkKKworICAgICMgVGVzdCBzbGljZSByZXRyaWV2YWwuCisgICAgbTIgPSBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIG0zID0gcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkKKyAgICBtNCA9IHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgc2VsZi5hc3NlcnRMaXN0c0VxdWFsKAorICAgICAgICBbbTEsIG0yLCBtM10sIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzE6NF0pCisgICAgc2VsZi5hc3NlcnRMaXN0c0VxdWFsKAorICAgICAgICBbbTAsIG0xLCBtMiwgbTMsIG00XSwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbOl0pCisgICAgc2VsZi5hc3NlcnRMaXN0c0VxdWFsKAorICAgICAgICBbbTAsIG0xXSwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbOjJdKQorICAgIHNlbGYuYXNzZXJ0TGlzdHNFcXVhbCgKKyAgICAgICAgW20yLCBtMywgbTRdLCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsyOl0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbTAsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdKQorICAgIHNlbGYuYXNzZXJ0TGlzdHNFcXVhbCgKKyAgICAgICAgW20wXSwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbOjFdKQorCisgICAgIyBUZXN0IHRoYXQgd2UgY2FuIHVzZSB0aGUgZmllbGQgYXMgYW4gaXRlcmF0b3IuCisgICAgcmVzdWx0ID0gW10KKyAgICBmb3IgaSBpbiBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZToKKyAgICAgIHJlc3VsdC5hcHBlbmQoaSkKKyAgICBzZWxmLmFzc2VydExpc3RzRXF1YWwoW20wLCBtMSwgbTIsIG0zLCBtNF0sIHJlc3VsdCkKKworICAgICMgVGVzdCBzaW5nbGUgZGVsZXRpb24uCisgICAgZGVsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzJdCisgICAgc2VsZi5hc3NlcnRMaXN0c0VxdWFsKFttMCwgbTEsIG0zLCBtNF0sIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKQorCisgICAgIyBUZXN0IHNsaWNlIGRlbGV0aW9uLgorICAgIGRlbCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsyOl0KKyAgICBzZWxmLmFzc2VydExpc3RzRXF1YWwoW20wLCBtMV0sIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKQorCisgICAgIyBUZXN0IGV4dGVuZGluZy4KKyAgICBuMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZShiYj0xKQorICAgIG4yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKGJiPTIpCisgICAgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuZXh0ZW5kKFtuMSxuMl0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0LCBsZW4ocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobjEsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzJdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobjIsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzNdKQorCisgICAgIyBUZXN0IGNsZWFyaW5nLgorICAgIHByb3RvLkNsZWFyRmllbGQoJ3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlJykKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbGVuKHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKSkKKworICAgICMgVGVzdCBjb25zdHJ1Y3RpbmcgYW4gZWxlbWVudCB3aGlsZSBhZGRpbmcgaXQuCisgICAgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKGJiPTIzKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgbGVuKHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIzLCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVswXS5iYikKKworICBkZWYgdGVzdFJlcGVhdGVkQ29tcG9zaXRlUmVtb3ZlKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGxlbihwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSkpCisgICAgbTAgPSBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgICMgTmVlZCB0byBzZXQgc29tZSBkaWZmZXJlbnRpYXRpbmcgdmFyaWFibGUgc28gbTAgIT0gbTEgIT0gbTI6CisgICAgbTAuYmIgPSBsZW4ocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpCisgICAgbTEgPSBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIG0xLmJiID0gbGVuKHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtMCAhPSBtMSkKKyAgICBtMiA9IHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgbTIuYmIgPSBsZW4ocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRMaXN0c0VxdWFsKFttMCwgbTEsIG0yXSwgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMsIGxlbihwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSkpCisgICAgcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UucmVtb3ZlKG0wKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgbGVuKHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKG0xLCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVswXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKG0yLCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsxXSkKKworICAgICMgUmVtb3ZpbmcgbTAgYWdhaW4gb3IgcmVtb3ZpbmcgTm9uZSBzaG91bGQgcmFpc2UgZXJyb3IKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5yZW1vdmUsIG0wKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLnJlbW92ZSwgTm9uZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIGxlbihwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSkpCisKKyAgICBwcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5yZW1vdmUobTIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBsZW4ocHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobTEsIHByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdKQorCisgIGRlZiB0ZXN0SGFuZFdyaXR0ZW5SZWZsZWN0aW9uKHNlbGYpOgorICAgICMgSGFuZCB3cml0dGVuIGV4dGVuc2lvbnMgYXJlIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZSBwdXJlLVB5dGhvbgorICAgICMgaW1wbGVtZW50YXRpb24gb2YgdGhlIEFQSS4KKyAgICBpZiBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpICE9ICdweXRob24nOgorICAgICAgcmV0dXJuCisKKyAgICBGaWVsZERlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvcgorICAgIGZvb19maWVsZF9kZXNjcmlwdG9yID0gRmllbGREZXNjcmlwdG9yKAorICAgICAgICBuYW1lPSdmb29fZmllbGQnLCBmdWxsX25hbWU9J015UHJvdG8uZm9vX2ZpZWxkJywKKyAgICAgICAgaW5kZXg9MCwgbnVtYmVyPTEsIHR5cGU9RmllbGREZXNjcmlwdG9yLlRZUEVfSU5UNjQsCisgICAgICAgIGNwcF90eXBlPUZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX0lOVDY0LAorICAgICAgICBsYWJlbD1GaWVsZERlc2NyaXB0b3IuTEFCRUxfT1BUSU9OQUwsIGRlZmF1bHRfdmFsdWU9MCwKKyAgICAgICAgY29udGFpbmluZ190eXBlPU5vbmUsIG1lc3NhZ2VfdHlwZT1Ob25lLCBlbnVtX3R5cGU9Tm9uZSwKKyAgICAgICAgaXNfZXh0ZW5zaW9uPUZhbHNlLCBleHRlbnNpb25fc2NvcGU9Tm9uZSwKKyAgICAgICAgb3B0aW9ucz1kZXNjcmlwdG9yX3BiMi5GaWVsZE9wdGlvbnMoKSkKKyAgICBteWRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLkRlc2NyaXB0b3IoCisgICAgICAgIG5hbWU9J015UHJvdG8nLCBmdWxsX25hbWU9J015UHJvdG8nLCBmaWxlbmFtZT0naWdub3JlZCcsCisgICAgICAgIGNvbnRhaW5pbmdfdHlwZT1Ob25lLCBuZXN0ZWRfdHlwZXM9W10sIGVudW1fdHlwZXM9W10sCisgICAgICAgIGZpZWxkcz1bZm9vX2ZpZWxkX2Rlc2NyaXB0b3JdLCBleHRlbnNpb25zPVtdLAorICAgICAgICBvcHRpb25zPWRlc2NyaXB0b3JfcGIyLk1lc3NhZ2VPcHRpb25zKCkpCisgICAgY2xhc3MgTXlQcm90b0NsYXNzKG1lc3NhZ2UuTWVzc2FnZSk6CisgICAgICBERVNDUklQVE9SID0gbXlkZXNjcmlwdG9yCisgICAgICBfX21ldGFjbGFzc19fID0gcmVmbGVjdGlvbi5HZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlCisgICAgbXlwcm90b19pbnN0YW5jZSA9IE15UHJvdG9DbGFzcygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBteXByb3RvX2luc3RhbmNlLmZvb19maWVsZCkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IG15cHJvdG9faW5zdGFuY2UuSGFzRmllbGQoJ2Zvb19maWVsZCcpKQorICAgIG15cHJvdG9faW5zdGFuY2UuZm9vX2ZpZWxkID0gMjMKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIzLCBteXByb3RvX2luc3RhbmNlLmZvb19maWVsZCkKKyAgICBzZWxmLmFzc2VydFRydWUobXlwcm90b19pbnN0YW5jZS5IYXNGaWVsZCgnZm9vX2ZpZWxkJykpCisKKyAgZGVmIHRlc3REZXNjcmlwdG9yUHJvdG9TdXBwb3J0KHNlbGYpOgorICAgICMgSGFuZCB3cml0dGVuIGRlc2NyaXB0b3JzL3JlZmxlY3Rpb24gYXJlIG9ubHkgc3VwcG9ydGVkIGJ5IHRoZSBwdXJlLVB5dGhvbgorICAgICMgaW1wbGVtZW50YXRpb24gb2YgdGhlIEFQSS4KKyAgICBpZiBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpICE9ICdweXRob24nOgorICAgICAgcmV0dXJuCisKKyAgICBkZWYgQWRkRGVzY3JpcHRvckZpZWxkKHByb3RvLCBmaWVsZF9uYW1lLCBmaWVsZF90eXBlKToKKyAgICAgIEFkZERlc2NyaXB0b3JGaWVsZC5maWVsZF9pbmRleCArPSAxCisgICAgICBuZXdfZmllbGQgPSBwcm90by5maWVsZC5hZGQoKQorICAgICAgbmV3X2ZpZWxkLm5hbWUgPSBmaWVsZF9uYW1lCisgICAgICBuZXdfZmllbGQudHlwZSA9IGZpZWxkX3R5cGUKKyAgICAgIG5ld19maWVsZC5udW1iZXIgPSBBZGREZXNjcmlwdG9yRmllbGQuZmllbGRfaW5kZXgKKyAgICAgIG5ld19maWVsZC5sYWJlbCA9IGRlc2NyaXB0b3JfcGIyLkZpZWxkRGVzY3JpcHRvclByb3RvLkxBQkVMX09QVElPTkFMCisKKyAgICBBZGREZXNjcmlwdG9yRmllbGQuZmllbGRfaW5kZXggPSAwCisKKyAgICBkZXNjX3Byb3RvID0gZGVzY3JpcHRvcl9wYjIuRGVzY3JpcHRvclByb3RvKCkKKyAgICBkZXNjX3Byb3RvLm5hbWUgPSAnQ2FyJworICAgIGZkcCA9IGRlc2NyaXB0b3JfcGIyLkZpZWxkRGVzY3JpcHRvclByb3RvCisgICAgQWRkRGVzY3JpcHRvckZpZWxkKGRlc2NfcHJvdG8sICduYW1lJywgZmRwLlRZUEVfU1RSSU5HKQorICAgIEFkZERlc2NyaXB0b3JGaWVsZChkZXNjX3Byb3RvLCAneWVhcicsIGZkcC5UWVBFX0lOVDY0KQorICAgIEFkZERlc2NyaXB0b3JGaWVsZChkZXNjX3Byb3RvLCAnYXV0b21hdGljJywgZmRwLlRZUEVfQk9PTCkKKyAgICBBZGREZXNjcmlwdG9yRmllbGQoZGVzY19wcm90bywgJ3ByaWNlJywgZmRwLlRZUEVfRE9VQkxFKQorICAgICMgQWRkIGEgcmVwZWF0ZWQgZmllbGQKKyAgICBBZGREZXNjcmlwdG9yRmllbGQuZmllbGRfaW5kZXggKz0gMQorICAgIG5ld19maWVsZCA9IGRlc2NfcHJvdG8uZmllbGQuYWRkKCkKKyAgICBuZXdfZmllbGQubmFtZSA9ICdvd25lcnMnCisgICAgbmV3X2ZpZWxkLnR5cGUgPSBmZHAuVFlQRV9TVFJJTkcKKyAgICBuZXdfZmllbGQubnVtYmVyID0gQWRkRGVzY3JpcHRvckZpZWxkLmZpZWxkX2luZGV4CisgICAgbmV3X2ZpZWxkLmxhYmVsID0gZGVzY3JpcHRvcl9wYjIuRmllbGREZXNjcmlwdG9yUHJvdG8uTEFCRUxfUkVQRUFURUQKKworICAgIGRlc2MgPSBkZXNjcmlwdG9yLk1ha2VEZXNjcmlwdG9yKGRlc2NfcHJvdG8pCisgICAgc2VsZi5hc3NlcnRUcnVlKGRlc2MuZmllbGRzX2J5X25hbWUuaGFzX2tleSgnbmFtZScpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShkZXNjLmZpZWxkc19ieV9uYW1lLmhhc19rZXkoJ3llYXInKSkKKyAgICBzZWxmLmFzc2VydFRydWUoZGVzYy5maWVsZHNfYnlfbmFtZS5oYXNfa2V5KCdhdXRvbWF0aWMnKSkKKyAgICBzZWxmLmFzc2VydFRydWUoZGVzYy5maWVsZHNfYnlfbmFtZS5oYXNfa2V5KCdwcmljZScpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShkZXNjLmZpZWxkc19ieV9uYW1lLmhhc19rZXkoJ293bmVycycpKQorCisgICAgY2xhc3MgQ2FyTWVzc2FnZShtZXNzYWdlLk1lc3NhZ2UpOgorICAgICAgX19tZXRhY2xhc3NfXyA9IHJlZmxlY3Rpb24uR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZQorICAgICAgREVTQ1JJUFRPUiA9IGRlc2MKKworICAgIHByaXVzID0gQ2FyTWVzc2FnZSgpCisgICAgcHJpdXMubmFtZSA9ICdwcml1cycKKyAgICBwcml1cy55ZWFyID0gMjAxMAorICAgIHByaXVzLmF1dG9tYXRpYyA9IFRydWUKKyAgICBwcml1cy5wcmljZSA9IDI1MTM0Ljc1CisgICAgcHJpdXMub3duZXJzLmV4dGVuZChbJ2JvYicsICdzdXNhbiddKQorCisgICAgc2VyaWFsaXplZF9wcml1cyA9IHByaXVzLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBuZXdfcHJpdXMgPSByZWZsZWN0aW9uLlBhcnNlTWVzc2FnZShkZXNjLCBzZXJpYWxpemVkX3ByaXVzKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShuZXdfcHJpdXMgaXMgbm90IHByaXVzKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJpdXMsIG5ld19wcml1cykKKworICAgICMgdGhlc2UgYXJlIHVubmVjZXNzYXJ5IGFzc3VtaW5nIG1lc3NhZ2UgZXF1YWxpdHkgd29ya3MgYXMgYWR2ZXJ0aXNlZCBidXQKKyAgICAjIGV4cGxpY2l0bHkgY2hlY2sgdG8gYmUgc2FmZSBzaW5jZSB3ZSdyZSBtdWNraW5nIGFib3V0IGluIG1ldGFjbGFzcyBmb28KKyAgICBzZWxmLmFzc2VydEVxdWFsKHByaXVzLm5hbWUsIG5ld19wcml1cy5uYW1lKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJpdXMueWVhciwgbmV3X3ByaXVzLnllYXIpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcml1cy5hdXRvbWF0aWMsIG5ld19wcml1cy5hdXRvbWF0aWMpCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcml1cy5wcmljZSwgbmV3X3ByaXVzLnByaWNlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJpdXMub3duZXJzLCBuZXdfcHJpdXMub3duZXJzKQorCisgIGRlZiB0ZXN0VG9wTGV2ZWxFeHRlbnNpb25zRm9yT3B0aW9uYWxTY2FsYXIoc2VsZik6CisgICAgZXh0ZW5kZWVfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIGV4dGVuc2lvbiA9IHVuaXR0ZXN0X3BiMi5vcHRpb25hbF9pbnQzMl9leHRlbnNpb24KKyAgICBzZWxmLmFzc2VydFRydWUobm90IGV4dGVuZGVlX3Byb3RvLkhhc0V4dGVuc2lvbihleHRlbnNpb24pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dKQorICAgICMgQXMgd2l0aCBub3JtYWwgc2NhbGFyIGZpZWxkcywganVzdCBkb2luZyBhIHJlYWQgZG9lc24ndCBhY3R1YWxseSBzZXQgdGhlCisgICAgIyAiaGFzIiBiaXQuCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24oZXh0ZW5zaW9uKSkKKyAgICAjIEFjdHVhbGx5IHNldCB0aGUgdGhpbmcuCisgICAgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dID0gMjMKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIzLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0pCisgICAgc2VsZi5hc3NlcnRUcnVlKGV4dGVuZGVlX3Byb3RvLkhhc0V4dGVuc2lvbihleHRlbnNpb24pKQorICAgICMgRW5zdXJlIHRoYXQgY2xlYXJpbmcgd29ya3MgYXMgd2VsbC4KKyAgICBleHRlbmRlZV9wcm90by5DbGVhckV4dGVuc2lvbihleHRlbnNpb24pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0pCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24oZXh0ZW5zaW9uKSkKKworICBkZWYgdGVzdFRvcExldmVsRXh0ZW5zaW9uc0ZvclJlcGVhdGVkU2NhbGFyKHNlbGYpOgorICAgIGV4dGVuZGVlX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICBleHRlbnNpb24gPSB1bml0dGVzdF9wYjIucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbGVuKGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSkpCisgICAgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dLmFwcGVuZCgnZm9vJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKFsnZm9vJ10sIGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSkKKyAgICBzdHJpbmdfbGlzdCA9IGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXQorICAgIGV4dGVuZGVlX3Byb3RvLkNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGxlbihleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0pKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShzdHJpbmdfbGlzdCBpcyBub3QgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dKQorICAgICMgU2hvdWxkbid0IGJlIGFsbG93ZWQgdG8gZG8gRXh0ZW5zaW9uc1tleHRlbnNpb25dID0gJ2EnCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBvcGVyYXRvci5zZXRpdGVtLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zLAorICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiwgJ2EnKQorCisgIGRlZiB0ZXN0VG9wTGV2ZWxFeHRlbnNpb25zRm9yT3B0aW9uYWxNZXNzYWdlKHNlbGYpOgorICAgIGV4dGVuZGVlX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICBleHRlbnNpb24gPSB1bml0dGVzdF9wYjIub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbgorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgZXh0ZW5kZWVfcHJvdG8uSGFzRXh0ZW5zaW9uKGV4dGVuc2lvbikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0uYykKKyAgICAjIEFzIHdpdGggbm9ybWFsIChub24tZXh0ZW5zaW9uKSBmaWVsZHMsIG1lcmVseSByZWFkaW5nIGZyb20gdGhlCisgICAgIyB0aGluZyBzaG91bGRuJ3Qgc2V0IHRoZSAiaGFzIiBiaXQuCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24oZXh0ZW5zaW9uKSkKKyAgICBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0uYyA9IDIzCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyMywgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dLmMpCisgICAgc2VsZi5hc3NlcnRUcnVlKGV4dGVuZGVlX3Byb3RvLkhhc0V4dGVuc2lvbihleHRlbnNpb24pKQorICAgICMgU2F2ZSBhIHJlZmVyZW5jZSBoZXJlLgorICAgIGZvcmVpZ25fbWVzc2FnZSA9IGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXQorICAgIGV4dGVuZGVlX3Byb3RvLkNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbikKKyAgICBzZWxmLmFzc2VydFRydWUoZm9yZWlnbl9tZXNzYWdlIGlzIG5vdCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0pCisgICAgIyBTZXR0aW5nIGEgZmllbGQgb24gZm9yZWlnbl9tZXNzYWdlIG5vdyBzaG91bGRuJ3Qgc2V0CisgICAgIyBhbnkgImhhcyIgYml0cyBvbiBleHRlbmRlZV9wcm90by4KKyAgICBmb3JlaWduX21lc3NhZ2UuYyA9IDQyCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0MiwgZm9yZWlnbl9tZXNzYWdlLmMpCisgICAgc2VsZi5hc3NlcnRUcnVlKGZvcmVpZ25fbWVzc2FnZS5IYXNGaWVsZCgnYycpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgZXh0ZW5kZWVfcHJvdG8uSGFzRXh0ZW5zaW9uKGV4dGVuc2lvbikpCisgICAgIyBTaG91bGRuJ3QgYmUgYWxsb3dlZCB0byBkbyBFeHRlbnNpb25zW2V4dGVuc2lvbl0gPSAnYScKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIG9wZXJhdG9yLnNldGl0ZW0sIGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnMsCisgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLCAnYScpCisKKyAgZGVmIHRlc3RUb3BMZXZlbEV4dGVuc2lvbnNGb3JSZXBlYXRlZE1lc3NhZ2Uoc2VsZik6CisgICAgZXh0ZW5kZWVfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIGV4dGVuc2lvbiA9IHVuaXR0ZXN0X3BiMi5yZXBlYXRlZGdyb3VwX2V4dGVuc2lvbgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbGVuKGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSkpCisgICAgZ3JvdXAgPSBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0uYWRkKCkKKyAgICBncm91cC5hID0gMjMKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIzLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl1bMF0uYSkKKyAgICBncm91cC5hID0gNDIKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQyLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl1bMF0uYSkKKyAgICBncm91cF9saXN0ID0gZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dCisgICAgZXh0ZW5kZWVfcHJvdG8uQ2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbGVuKGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSkpCisgICAgc2VsZi5hc3NlcnRUcnVlKGdyb3VwX2xpc3QgaXMgbm90IGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSkKKyAgICAjIFNob3VsZG4ndCBiZSBhbGxvd2VkIHRvIGRvIEV4dGVuc2lvbnNbZXh0ZW5zaW9uXSA9ICdhJworICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgb3BlcmF0b3Iuc2V0aXRlbSwgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9ucywKKyAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24sICdhJykKKworICBkZWYgdGVzdE5lc3RlZEV4dGVuc2lvbnMoc2VsZik6CisgICAgZXh0ZW5kZWVfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIGV4dGVuc2lvbiA9IHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWQuc2luZ2xlCisKKyAgICAjIFdlIGp1c3QgdGVzdCB0aGUgbm9uLXJlcGVhdGVkIGNhc2UuCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24oZXh0ZW5zaW9uKSkKKyAgICByZXF1aXJlZCA9IGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcmVxdWlyZWQuYSkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IGV4dGVuZGVlX3Byb3RvLkhhc0V4dGVuc2lvbihleHRlbnNpb24pKQorICAgIHJlcXVpcmVkLmEgPSAyMworICAgIHNlbGYuYXNzZXJ0RXF1YWwoMjMsIGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXS5hKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24oZXh0ZW5zaW9uKSkKKyAgICBleHRlbmRlZV9wcm90by5DbGVhckV4dGVuc2lvbihleHRlbnNpb24pCisgICAgc2VsZi5hc3NlcnRUcnVlKHJlcXVpcmVkIGlzIG5vdCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0pCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24oZXh0ZW5zaW9uKSkKKworICBkZWYgdGVzdFJlZ2lzdGVyZWRFeHRlbnNpb25zKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0VHJ1ZSgncHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uJyBpbgorICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMuX2V4dGVuc2lvbnNfYnlfbmFtZSkKKyAgICBzZWxmLmFzc2VydFRydWUoMSBpbiB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMuX2V4dGVuc2lvbnNfYnlfbnVtYmVyKQorICAgICMgTWFrZSBzdXJlIGV4dGVuc2lvbnMgaGF2ZW4ndCBiZWVuIHJlZ2lzdGVyZWQgaW50byB0eXBlcyB0aGF0IHNob3VsZG4ndAorICAgICMgaGF2ZSBhbnkuCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoMCwgbGVuKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuX2V4dGVuc2lvbnNfYnlfbmFtZSkpCisKKyAgIyBJZiBtZXNzYWdlIEEgZGlyZWN0bHkgY29udGFpbnMgbWVzc2FnZSBCLCBhbmQKKyAgIyBhLkhhc0ZpZWxkKCdiJykgaXMgY3VycmVudGx5IEZhbHNlLCB0aGVuIG11dGF0aW5nIGFueQorICAjIGV4dGVuc2lvbiBpbiBCIHNob3VsZCBjaGFuZ2UgYS5IYXNGaWVsZCgnYicpIHRvIFRydWUKKyAgIyAoYW5kIHNvIG9uIHVwIHRoZSBvYmplY3QgdHJlZSkuCisgIGRlZiB0ZXN0SGFzQml0c0ZvckFuY2VzdG9yc09mRXh0ZW5kZWRNZXNzYWdlKHNlbGYpOgorICAgICMgT3B0aW9uYWwgc2NhbGFyIGV4dGVuc2lvbi4KKyAgICB0b3BsZXZlbCA9IG1vcmVfZXh0ZW5zaW9uc19wYjIuVG9wTGV2ZWxNZXNzYWdlKCkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHRvcGxldmVsLkhhc0ZpZWxkKCdzdWJtZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCB0b3BsZXZlbC5zdWJtZXNzYWdlLkV4dGVuc2lvbnNbCisgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIub3B0aW9uYWxfaW50X2V4dGVuc2lvbl0pCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB0b3BsZXZlbC5IYXNGaWVsZCgnc3VibWVzc2FnZScpKQorICAgIHRvcGxldmVsLnN1Ym1lc3NhZ2UuRXh0ZW5zaW9uc1sKKyAgICAgICAgbW9yZV9leHRlbnNpb25zX3BiMi5vcHRpb25hbF9pbnRfZXh0ZW5zaW9uXSA9IDIzCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyMywgdG9wbGV2ZWwuc3VibWVzc2FnZS5FeHRlbnNpb25zWworICAgICAgICBtb3JlX2V4dGVuc2lvbnNfcGIyLm9wdGlvbmFsX2ludF9leHRlbnNpb25dKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0b3BsZXZlbC5IYXNGaWVsZCgnc3VibWVzc2FnZScpKQorCisgICAgIyBSZXBlYXRlZCBzY2FsYXIgZXh0ZW5zaW9uLgorICAgIHRvcGxldmVsID0gbW9yZV9leHRlbnNpb25zX3BiMi5Ub3BMZXZlbE1lc3NhZ2UoKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgdG9wbGV2ZWwuSGFzRmllbGQoJ3N1Ym1lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFtdLCB0b3BsZXZlbC5zdWJtZXNzYWdlLkV4dGVuc2lvbnNbCisgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIucmVwZWF0ZWRfaW50X2V4dGVuc2lvbl0pCisgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB0b3BsZXZlbC5IYXNGaWVsZCgnc3VibWVzc2FnZScpKQorICAgIHRvcGxldmVsLnN1Ym1lc3NhZ2UuRXh0ZW5zaW9uc1sKKyAgICAgICAgbW9yZV9leHRlbnNpb25zX3BiMi5yZXBlYXRlZF9pbnRfZXh0ZW5zaW9uXS5hcHBlbmQoMjMpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMjNdLCB0b3BsZXZlbC5zdWJtZXNzYWdlLkV4dGVuc2lvbnNbCisgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIucmVwZWF0ZWRfaW50X2V4dGVuc2lvbl0pCisgICAgc2VsZi5hc3NlcnRUcnVlKHRvcGxldmVsLkhhc0ZpZWxkKCdzdWJtZXNzYWdlJykpCisKKyAgICAjIE9wdGlvbmFsIG1lc3NhZ2UgZXh0ZW5zaW9uLgorICAgIHRvcGxldmVsID0gbW9yZV9leHRlbnNpb25zX3BiMi5Ub3BMZXZlbE1lc3NhZ2UoKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgdG9wbGV2ZWwuSGFzRmllbGQoJ3N1Ym1lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHRvcGxldmVsLnN1Ym1lc3NhZ2UuRXh0ZW5zaW9uc1sKKyAgICAgICAgbW9yZV9leHRlbnNpb25zX3BiMi5vcHRpb25hbF9tZXNzYWdlX2V4dGVuc2lvbl0uZm9yZWlnbl9tZXNzYWdlX2ludCkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHRvcGxldmVsLkhhc0ZpZWxkKCdzdWJtZXNzYWdlJykpCisgICAgdG9wbGV2ZWwuc3VibWVzc2FnZS5FeHRlbnNpb25zWworICAgICAgICBtb3JlX2V4dGVuc2lvbnNfcGIyLm9wdGlvbmFsX21lc3NhZ2VfZXh0ZW5zaW9uXS5mb3JlaWduX21lc3NhZ2VfaW50ID0gMjMKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIzLCB0b3BsZXZlbC5zdWJtZXNzYWdlLkV4dGVuc2lvbnNbCisgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIub3B0aW9uYWxfbWVzc2FnZV9leHRlbnNpb25dLmZvcmVpZ25fbWVzc2FnZV9pbnQpCisgICAgc2VsZi5hc3NlcnRUcnVlKHRvcGxldmVsLkhhc0ZpZWxkKCdzdWJtZXNzYWdlJykpCisKKyAgICAjIFJlcGVhdGVkIG1lc3NhZ2UgZXh0ZW5zaW9uLgorICAgIHRvcGxldmVsID0gbW9yZV9leHRlbnNpb25zX3BiMi5Ub3BMZXZlbE1lc3NhZ2UoKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgdG9wbGV2ZWwuSGFzRmllbGQoJ3N1Ym1lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGxlbih0b3BsZXZlbC5zdWJtZXNzYWdlLkV4dGVuc2lvbnNbCisgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIucmVwZWF0ZWRfbWVzc2FnZV9leHRlbnNpb25dKSkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHRvcGxldmVsLkhhc0ZpZWxkKCdzdWJtZXNzYWdlJykpCisgICAgZm9yZWlnbiA9IHRvcGxldmVsLnN1Ym1lc3NhZ2UuRXh0ZW5zaW9uc1sKKyAgICAgICAgbW9yZV9leHRlbnNpb25zX3BiMi5yZXBlYXRlZF9tZXNzYWdlX2V4dGVuc2lvbl0uYWRkKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZvcmVpZ24sIHRvcGxldmVsLnN1Ym1lc3NhZ2UuRXh0ZW5zaW9uc1sKKyAgICAgICAgbW9yZV9leHRlbnNpb25zX3BiMi5yZXBlYXRlZF9tZXNzYWdlX2V4dGVuc2lvbl1bMF0pCisgICAgc2VsZi5hc3NlcnRUcnVlKHRvcGxldmVsLkhhc0ZpZWxkKCdzdWJtZXNzYWdlJykpCisKKyAgZGVmIHRlc3REaXNjb25uZWN0aW9uQWZ0ZXJDbGVhcmluZ0VtcHR5TWVzc2FnZShzZWxmKToKKyAgICB0b3BsZXZlbCA9IG1vcmVfZXh0ZW5zaW9uc19wYjIuVG9wTGV2ZWxNZXNzYWdlKCkKKyAgICBleHRlbmRlZV9wcm90byA9IHRvcGxldmVsLnN1Ym1lc3NhZ2UKKyAgICBleHRlbnNpb24gPSBtb3JlX2V4dGVuc2lvbnNfcGIyLm9wdGlvbmFsX21lc3NhZ2VfZXh0ZW5zaW9uCisgICAgZXh0ZW5zaW9uX3Byb3RvID0gZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dCisgICAgZXh0ZW5kZWVfcHJvdG8uQ2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKQorICAgIGV4dGVuc2lvbl9wcm90by5mb3JlaWduX21lc3NhZ2VfaW50ID0gMjMKKworICAgIHNlbGYuYXNzZXJ0VHJ1ZShleHRlbnNpb25fcHJvdG8gaXMgbm90IGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSkKKworICBkZWYgdGVzdEV4dGVuc2lvbkZhaWx1cmVNb2RlcyhzZWxmKToKKyAgICBleHRlbmRlZV9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisKKyAgICAjIFRyeSBub24tZXh0ZW5zaW9uLWhhbmRsZSBhcmd1bWVudHMgdG8gSGFzRXh0ZW5zaW9uLAorICAgICMgQ2xlYXJFeHRlbnNpb24oKSwgYW5kIEV4dGVuc2lvbnNbXS4uLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24sIDEyMzQpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGV4dGVuZGVlX3Byb3RvLkNsZWFyRXh0ZW5zaW9uLCAxMjM0KQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zLl9fZ2V0aXRlbV9fLCAxMjM0KQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBleHRlbmRlZV9wcm90by5FeHRlbnNpb25zLl9fc2V0aXRlbV9fLCAxMjM0LCA1KQorCisgICAgIyBUcnkgc29tZXRoaW5nIHRoYXQgKmlzKiBhbiBleHRlbnNpb24gaGFuZGxlLCBqdXN0IG5vdCBmb3IKKyAgICAjIHRoaXMgbWVzc2FnZS4uLgorICAgIGZvciB1bmtub3duX2hhbmRsZSBpbiAobW9yZV9leHRlbnNpb25zX3BiMi5vcHRpb25hbF9pbnRfZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9yZV9leHRlbnNpb25zX3BiMi5vcHRpb25hbF9tZXNzYWdlX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIucmVwZWF0ZWRfaW50X2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcmVfZXh0ZW5zaW9uc19wYjIucmVwZWF0ZWRfbWVzc2FnZV9leHRlbnNpb24pOgorICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGV4dGVuZGVlX3Byb3RvLkhhc0V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25faGFuZGxlKQorICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGV4dGVuZGVlX3Byb3RvLkNsZWFyRXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgdW5rbm93bl9oYW5kbGUpCisgICAgICBzZWxmLmFzc2VydFJhaXNlcyhLZXlFcnJvciwgZXh0ZW5kZWVfcHJvdG8uRXh0ZW5zaW9ucy5fX2dldGl0ZW1fXywKKyAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25faGFuZGxlKQorICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGV4dGVuZGVlX3Byb3RvLkV4dGVuc2lvbnMuX19zZXRpdGVtX18sCisgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duX2hhbmRsZSwgNSkKKworICAgICMgVHJ5IGNhbGwgSGFzRXh0ZW5zaW9uKCkgd2l0aCBhIHZhbGlkIGhhbmRsZSwgYnV0IGZvciBhCisgICAgIyAqcmVwZWF0ZWQqIGZpZWxkLiAgKEp1c3QgYXMgd2l0aCBub24tZXh0ZW5zaW9uIHJlcGVhdGVkCisgICAgIyBmaWVsZHMsIEhhcyooKSBpc24ndCBzdXBwb3J0ZWQgZm9yIGV4dGVuc2lvbiByZXBlYXRlZCBmaWVsZHMpLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBleHRlbmRlZV9wcm90by5IYXNFeHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pCisKKyAgZGVmIHRlc3RTdGF0aWNQYXJzZUZyb20oc2VsZik6CisgICAgcHJvdG8xID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbEZpZWxkcyhwcm90bzEpCisKKyAgICBzdHJpbmcxID0gcHJvdG8xLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkZyb21TdHJpbmcoc3RyaW5nMSkKKworICAgICMgTWVzc2FnZXMgc2hvdWxkIGJlIGVxdWFsLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJvdG8yLCBwcm90bzEpCisKKyAgZGVmIHRlc3RNZXJnZUZyb21TaW5ndWxhckZpZWxkKHNlbGYpOgorICAgICMgVGVzdCBtZXJnZSB3aXRoIGp1c3QgYSBzaW5ndWxhciBmaWVsZC4KKyAgICBwcm90bzEgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwcm90bzEub3B0aW9uYWxfaW50MzIgPSAxCisKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICAjIFRoaXMgc2hvdWxkbid0IGdldCBvdmVyd3JpdHRlbi4KKyAgICBwcm90bzIub3B0aW9uYWxfc3RyaW5nID0gJ3ZhbHVlJworCisgICAgcHJvdG8yLk1lcmdlRnJvbShwcm90bzEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90bzIub3B0aW9uYWxfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgndmFsdWUnLCBwcm90bzIub3B0aW9uYWxfc3RyaW5nKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tUmVwZWF0ZWRGaWVsZChzZWxmKToKKyAgICAjIFRlc3QgbWVyZ2Ugd2l0aCBqdXN0IGEgcmVwZWF0ZWQgZmllbGQuCisgICAgcHJvdG8xID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgcHJvdG8xLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxKQorICAgIHByb3RvMS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMikKKworICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMi5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMCkKKyAgICBwcm90bzIuTWVyZ2VGcm9tKHByb3RvMSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8yLnJlcGVhdGVkX2ludDMyWzBdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgcHJvdG8yLnJlcGVhdGVkX2ludDMyWzFdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgcHJvdG8yLnJlcGVhdGVkX2ludDMyWzJdKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tT3B0aW9uYWxHcm91cChzZWxmKToKKyAgICAjIFRlc3QgbWVyZ2Ugd2l0aCBhbiBvcHRpb25hbCBncm91cC4KKyAgICBwcm90bzEgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwcm90bzEub3B0aW9uYWxncm91cC5hID0gMTIKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwcm90bzIuTWVyZ2VGcm9tKHByb3RvMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEyLCBwcm90bzIub3B0aW9uYWxncm91cC5hKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKHNlbGYpOgorICAgICMgVGVzdCBtZXJnZSB3aXRoIGEgcmVwZWF0ZWQgbmVzdGVkIG1lc3NhZ2UuCisgICAgcHJvdG8xID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgbSA9IHByb3RvMS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIG0uYmIgPSAxMjMKKyAgICBtID0gcHJvdG8xLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgbS5iYiA9IDMyMQorCisgICAgcHJvdG8yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgbSA9IHByb3RvMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIG0uYmIgPSA5OTkKKyAgICBwcm90bzIuTWVyZ2VGcm9tKHByb3RvMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDk5OSwgcHJvdG8yLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdLmJiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTIzLCBwcm90bzIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbMV0uYmIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzMjEsIHByb3RvMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsyXS5iYikKKworICAgIHByb3RvMyA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMy5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5NZXJnZUZyb20ocHJvdG8yLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoOTk5LCBwcm90bzMucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbMF0uYmIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMjMsIHByb3RvMy5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsxXS5iYikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMyMSwgcHJvdG8zLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzJdLmJiKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tQWxsRmllbGRzKHNlbGYpOgorICAgICMgV2l0aCBhbGwgZmllbGRzIHNldC4KKyAgICBwcm90bzEgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRmllbGRzKHByb3RvMSkKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwcm90bzIuTWVyZ2VGcm9tKHByb3RvMSkKKworICAgICMgTWVzc2FnZXMgc2hvdWxkIGJlIGVxdWFsLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJvdG8yLCBwcm90bzEpCisKKyAgICAjIFNlcmlhbGl6ZWQgc3RyaW5nIHNob3VsZCBiZSBlcXVhbCB0b28uCisgICAgc3RyaW5nMSA9IHByb3RvMS5TZXJpYWxpemVUb1N0cmluZygpCisgICAgc3RyaW5nMiA9IHByb3RvMi5TZXJpYWxpemVUb1N0cmluZygpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzdHJpbmcxLCBzdHJpbmcyKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tRXh0ZW5zaW9uc1Npbmd1bGFyKHNlbGYpOgorICAgIHByb3RvMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgcHJvdG8xLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl0gPSAxCisKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIHByb3RvMi5NZXJnZUZyb20ocHJvdG8xKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIDEsIHByb3RvMi5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5vcHRpb25hbF9pbnQzMl9leHRlbnNpb25dKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tRXh0ZW5zaW9uc1JlcGVhdGVkKHNlbGYpOgorICAgIHByb3RvMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgcHJvdG8xLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl0uYXBwZW5kKDEpCisgICAgcHJvdG8xLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl0uYXBwZW5kKDIpCisKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIHByb3RvMi5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5yZXBlYXRlZF9pbnQzMl9leHRlbnNpb25dLmFwcGVuZCgwKQorICAgIHByb3RvMi5NZXJnZUZyb20ocHJvdG8xKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIDMsIGxlbihwcm90bzIuRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIucmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uXSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgMCwgcHJvdG8yLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl1bMF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgMSwgcHJvdG8yLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl1bMV0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgMiwgcHJvdG8yLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl1bMl0pCisKKyAgZGVmIHRlc3RNZXJnZUZyb21FeHRlbnNpb25zTmVzdGVkTWVzc2FnZShzZWxmKToKKyAgICBwcm90bzEgPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIGV4dDEgPSBwcm90bzEuRXh0ZW5zaW9uc1sKKyAgICAgICAgdW5pdHRlc3RfcGIyLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0KKyAgICBtID0gZXh0MS5hZGQoKQorICAgIG0uYmIgPSAyMjIKKyAgICBtID0gZXh0MS5hZGQoKQorICAgIG0uYmIgPSAzMzMKKworICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgZXh0MiA9IHByb3RvMi5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9wYjIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXQorICAgIG0gPSBleHQyLmFkZCgpCisgICAgbS5iYiA9IDExMQorCisgICAgcHJvdG8yLk1lcmdlRnJvbShwcm90bzEpCisgICAgZXh0MiA9IHByb3RvMi5FeHRlbnNpb25zWworICAgICAgICB1bml0dGVzdF9wYjIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgbGVuKGV4dDIpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTExLCBleHQyWzBdLmJiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMjIyLCBleHQyWzFdLmJiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMzMzLCBleHQyWzJdLmJiKQorCisgIGRlZiB0ZXN0TWVyZ2VGcm9tQnVnKHNlbGYpOgorICAgIG1lc3NhZ2UxID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgbWVzc2FnZTIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKworICAgICMgQ2F1c2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgdG8gYmUgaW5zdGFudGlhdGVkIHdpdGhpbiBtZXNzYWdlMSwgZXZlbgorICAgICMgdGhvdWdoIGl0IGlzIG5vdCBjb25zaWRlcmVkIHRvIGJlICJwcmVzZW50Ii4KKyAgICBtZXNzYWdlMS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZQorICAgIHNlbGYuYXNzZXJ0RmFsc2UobWVzc2FnZTEuSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisKKyAgICAjIE1lcmdlIGludG8gbWVzc2FnZTIuICBUaGlzIHNob3VsZCBub3QgaW5zdGFudGlhdGUgdGhlIGZpZWxkIGlzIG1lc3NhZ2UyLgorICAgIG1lc3NhZ2UyLk1lcmdlRnJvbShtZXNzYWdlMSkKKyAgICBzZWxmLmFzc2VydEZhbHNlKG1lc3NhZ2UyLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorCisgIGRlZiB0ZXN0Q29weUZyb21TaW5ndWxhckZpZWxkKHNlbGYpOgorICAgICMgVGVzdCBjb3B5IHdpdGgganVzdCBhIHNpbmd1bGFyIGZpZWxkLgorICAgIHByb3RvMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMS5vcHRpb25hbF9pbnQzMiA9IDEKKyAgICBwcm90bzEub3B0aW9uYWxfc3RyaW5nID0gJ2ltcG9ydGFudC10ZXh0JworCisgICAgcHJvdG8yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgcHJvdG8yLm9wdGlvbmFsX3N0cmluZyA9ICd2YWx1ZScKKworICAgIHByb3RvMi5Db3B5RnJvbShwcm90bzEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90bzIub3B0aW9uYWxfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnaW1wb3J0YW50LXRleHQnLCBwcm90bzIub3B0aW9uYWxfc3RyaW5nKQorCisgIGRlZiB0ZXN0Q29weUZyb21SZXBlYXRlZEZpZWxkKHNlbGYpOgorICAgICMgVGVzdCBjb3B5IHdpdGggYSByZXBlYXRlZCBmaWVsZC4KKyAgICBwcm90bzEgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwcm90bzEucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDEpCisgICAgcHJvdG8xLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgyKQorCisgICAgcHJvdG8yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgcHJvdG8yLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgwKQorICAgIHByb3RvMi5Db3B5RnJvbShwcm90bzEpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvMi5yZXBlYXRlZF9pbnQzMlswXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHByb3RvMi5yZXBlYXRlZF9pbnQzMlsxXSkKKworICBkZWYgdGVzdENvcHlGcm9tQWxsRmllbGRzKHNlbGYpOgorICAgICMgV2l0aCBhbGwgZmllbGRzIHNldC4KKyAgICBwcm90bzEgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRmllbGRzKHByb3RvMSkKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBwcm90bzIuQ29weUZyb20ocHJvdG8xKQorCisgICAgIyBNZXNzYWdlcyBzaG91bGQgYmUgZXF1YWwuCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcm90bzIsIHByb3RvMSkKKworICAgICMgU2VyaWFsaXplZCBzdHJpbmcgc2hvdWxkIGJlIGVxdWFsIHRvby4KKyAgICBzdHJpbmcxID0gcHJvdG8xLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBzdHJpbmcyID0gcHJvdG8yLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHN0cmluZzEsIHN0cmluZzIpCisKKyAgZGVmIHRlc3RDb3B5RnJvbVNlbGYoc2VsZik6CisgICAgcHJvdG8xID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgcHJvdG8xLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxKQorICAgIHByb3RvMS5vcHRpb25hbF9pbnQzMiA9IDIKKyAgICBwcm90bzEub3B0aW9uYWxfc3RyaW5nID0gJ2ltcG9ydGFudC10ZXh0JworCisgICAgcHJvdG8xLkNvcHlGcm9tKHByb3RvMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvMS5yZXBlYXRlZF9pbnQzMlswXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHByb3RvMS5vcHRpb25hbF9pbnQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdpbXBvcnRhbnQtdGV4dCcsIHByb3RvMS5vcHRpb25hbF9zdHJpbmcpCisKKyAgZGVmIHRlc3RDb3B5RnJvbUJhZFR5cGUoc2VsZik6CisgICAgIyBUaGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcmFpc2UgYW4gZXhjZXB0aW9uIGluIHRoaXMKKyAgICAjIGNhc2UuIEluIHRoZW9yeSBpdCBzaG91bGQuCisgICAgaWYgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSA9PSAncHl0aG9uJzoKKyAgICAgIHJldHVybgorICAgIHByb3RvMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBwcm90bzEuQ29weUZyb20sIHByb3RvMikKKworICBkZWYgdGVzdERlZXBDb3B5KHNlbGYpOgorICAgIHByb3RvMSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvMS5vcHRpb25hbF9pbnQzMiA9IDEKKyAgICBwcm90bzIgPSBjb3B5LmRlZXBjb3B5KHByb3RvMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvMi5vcHRpb25hbF9pbnQzMikKKworICAgIHByb3RvMS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMikKKyAgICBwcm90bzEucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDMpCisgICAgY29udGFpbmVyID0gY29weS5kZWVwY29weShwcm90bzEucmVwZWF0ZWRfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMiwgM10sIGNvbnRhaW5lcikKKworICAgICMgVE9ETyhhbnVyYWFnKTogSW1wbGVtZW50IGRlZXBjb3B5IGZvciByZXBlYXRlZCBjb21wb3NpdGUgLyBleHRlbnNpb24gZGljdAorCisgIGRlZiB0ZXN0Q2xlYXIoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICAjIEMrKyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IGxhenkgZmllbGRzIHJpZ2h0IG5vdyBzbyBsZWF2ZSBpdAorICAgICMgb3V0IGZvciBub3cuCisgICAgaWYgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSA9PSAncHl0aG9uJzoKKyAgICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMocHJvdG8pCisgICAgZWxzZToKKyAgICAgIHRlc3RfdXRpbC5TZXRBbGxOb25MYXp5RmllbGRzKHByb3RvKQorICAgICMgQ2xlYXIgdGhlIG1lc3NhZ2UuCisgICAgcHJvdG8uQ2xlYXIoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKHByb3RvLkJ5dGVTaXplKCksIDApCisgICAgZW1wdHlfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhwcm90bywgZW1wdHlfcHJvdG8pCisKKyAgICAjIFRlc3QgaWYgZXh0ZW5zaW9ucyB3aGljaCB3ZXJlIHNldCBhcmUgY2xlYXJlZC4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgdGVzdF91dGlsLlNldEFsbEV4dGVuc2lvbnMocHJvdG8pCisgICAgIyBDbGVhciB0aGUgbWVzc2FnZS4KKyAgICBwcm90by5DbGVhcigpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMocHJvdG8uQnl0ZVNpemUoKSwgMCkKKyAgICBlbXB0eV9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMocHJvdG8sIGVtcHR5X3Byb3RvKQorCisgIGRlZiB0ZXN0RGlzY29ubmVjdGluZ0JlZm9yZUNsZWFyKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgbmVzdGVkID0gcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UKKyAgICBwcm90by5DbGVhcigpCisgICAgc2VsZi5hc3NlcnRUcnVlKG5lc3RlZCBpcyBub3QgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UpCisgICAgbmVzdGVkLmJiID0gMjMKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIpCisKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIG5lc3RlZCA9IHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlCisgICAgbmVzdGVkLmJiID0gNQorICAgIGZvcmVpZ24gPSBwcm90by5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UKKyAgICBmb3JlaWduLmMgPSA2CisKKyAgICBwcm90by5DbGVhcigpCisgICAgc2VsZi5hc3NlcnRUcnVlKG5lc3RlZCBpcyBub3QgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRUcnVlKGZvcmVpZ24gaXMgbm90IHByb3RvLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDUsIG5lc3RlZC5iYikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDYsIGZvcmVpZ24uYykKKyAgICBuZXN0ZWQuYmIgPSAxNQorICAgIGZvcmVpZ24uYyA9IDE2CisgICAgc2VsZi5hc3NlcnRGYWxzZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZScpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8ub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlLmMpCisKKyAgZGVmIHRlc3RPbmVPZihzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLm9uZW9mX3VpbnQzMiA9IDEwCisgICAgcHJvdG8ub25lb2ZfbmVzdGVkX21lc3NhZ2UuYmIgPSAxMQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTEsIHByb3RvLm9uZW9mX25lc3RlZF9tZXNzYWdlLmJiKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UocHJvdG8uSGFzRmllbGQoJ29uZW9mX3VpbnQzMicpKQorICAgIG5lc3RlZCA9IHByb3RvLm9uZW9mX25lc3RlZF9tZXNzYWdlCisgICAgcHJvdG8ub25lb2Zfc3RyaW5nID0gJ2FiYycKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdhYmMnLCBwcm90by5vbmVvZl9zdHJpbmcpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMSwgbmVzdGVkLmJiKQorICAgIHNlbGYuYXNzZXJ0RmFsc2UocHJvdG8uSGFzRmllbGQoJ29uZW9mX25lc3RlZF9tZXNzYWdlJykpCisKKyAgZGVmIGFzc2VydEluaXRpYWxpemVkKHNlbGYsIHByb3RvKToKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSXNJbml0aWFsaXplZCgpKQorICAgICMgTmVpdGhlciBtZXRob2Qgc2hvdWxkIHJhaXNlIGFuIGV4Y2VwdGlvbi4KKyAgICBwcm90by5TZXJpYWxpemVUb1N0cmluZygpCisgICAgcHJvdG8uU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKCkKKworICBkZWYgYXNzZXJ0Tm90SW5pdGlhbGl6ZWQoc2VsZiwgcHJvdG8pOgorICAgIHNlbGYuYXNzZXJ0RmFsc2UocHJvdG8uSXNJbml0aWFsaXplZCgpKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKG1lc3NhZ2UuRW5jb2RlRXJyb3IsIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKQorICAgICMgIlBhcnRpYWwiIHNlcmlhbGl6YXRpb24gZG9lc24ndCBjYXJlIGlmIG1lc3NhZ2UgaXMgdW5pbml0aWFsaXplZC4KKyAgICBwcm90by5TZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmcoKQorCisgIGRlZiB0ZXN0SXNJbml0aWFsaXplZChzZWxmKToKKyAgICAjIFRyaXZpYWwgY2FzZXMgLSBhbGwgb3B0aW9uYWwgZmllbGRzIGFuZCBleHRlbnNpb25zLgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRJbml0aWFsaXplZChwcm90bykKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgc2VsZi5hc3NlcnRJbml0aWFsaXplZChwcm90bykKKworICAgICMgVGhlIGNhc2Ugb2YgdW5pbml0aWFsaXplZCByZXF1aXJlZCBmaWVsZHMuCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkKCkKKyAgICBzZWxmLmFzc2VydE5vdEluaXRpYWxpemVkKHByb3RvKQorICAgIHByb3RvLmEgPSBwcm90by5iID0gcHJvdG8uYyA9IDIKKyAgICBzZWxmLmFzc2VydEluaXRpYWxpemVkKHByb3RvKQorCisgICAgIyBUaGUgY2FzZSBvZiB1bmluaXRpYWxpemVkIHN1Ym1lc3NhZ2UuCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkRm9yZWlnbigpCisgICAgc2VsZi5hc3NlcnRJbml0aWFsaXplZChwcm90bykKKyAgICBwcm90by5vcHRpb25hbF9tZXNzYWdlLmEgPSAxCisgICAgc2VsZi5hc3NlcnROb3RJbml0aWFsaXplZChwcm90bykKKyAgICBwcm90by5vcHRpb25hbF9tZXNzYWdlLmIgPSAwCisgICAgcHJvdG8ub3B0aW9uYWxfbWVzc2FnZS5jID0gMAorICAgIHNlbGYuYXNzZXJ0SW5pdGlhbGl6ZWQocHJvdG8pCisKKyAgICAjIFVuaW5pdGlhbGl6ZWQgcmVwZWF0ZWQgc3VibWVzc2FnZS4KKyAgICBtZXNzYWdlMSA9IHByb3RvLnJlcGVhdGVkX21lc3NhZ2UuYWRkKCkKKyAgICBzZWxmLmFzc2VydE5vdEluaXRpYWxpemVkKHByb3RvKQorICAgIG1lc3NhZ2UxLmEgPSBtZXNzYWdlMS5iID0gbWVzc2FnZTEuYyA9IDAKKyAgICBzZWxmLmFzc2VydEluaXRpYWxpemVkKHByb3RvKQorCisgICAgIyBVbmluaXRpYWxpemVkIHJlcGVhdGVkIGdyb3VwIGluIGFuIGV4dGVuc2lvbi4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgZXh0ZW5zaW9uID0gdW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZC5tdWx0aQorICAgIG1lc3NhZ2UxID0gcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dLmFkZCgpCisgICAgbWVzc2FnZTIgPSBwcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0uYWRkKCkKKyAgICBzZWxmLmFzc2VydE5vdEluaXRpYWxpemVkKHByb3RvKQorICAgIG1lc3NhZ2UxLmEgPSAxCisgICAgbWVzc2FnZTEuYiA9IDEKKyAgICBtZXNzYWdlMS5jID0gMQorICAgIHNlbGYuYXNzZXJ0Tm90SW5pdGlhbGl6ZWQocHJvdG8pCisgICAgbWVzc2FnZTIuYSA9IDIKKyAgICBtZXNzYWdlMi5iID0gMgorICAgIG1lc3NhZ2UyLmMgPSAyCisgICAgc2VsZi5hc3NlcnRJbml0aWFsaXplZChwcm90bykKKworICAgICMgVW5pbml0aWFsaXplZCBub25yZXBlYXRlZCBtZXNzYWdlIGluIGFuIGV4dGVuc2lvbi4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgZXh0ZW5zaW9uID0gdW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZC5zaW5nbGUKKyAgICBwcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0uYSA9IDEKKyAgICBzZWxmLmFzc2VydE5vdEluaXRpYWxpemVkKHByb3RvKQorICAgIHByb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXS5iID0gMgorICAgIHByb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXS5jID0gMworICAgIHNlbGYuYXNzZXJ0SW5pdGlhbGl6ZWQocHJvdG8pCisKKyAgICAjIFRyeSBwYXNzaW5nIGFuIGVycm9ycyBsaXN0LgorICAgIGVycm9ycyA9IFtdCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkKCkKKyAgICBzZWxmLmFzc2VydEZhbHNlKHByb3RvLklzSW5pdGlhbGl6ZWQoZXJyb3JzKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGVycm9ycywgWydhJywgJ2InLCAnYyddKQorCisgIEBiYXNldGVzdC51bml0dGVzdC5za2lwSWYoCisgICAgICBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpICE9ICdjcHAnIG9yIGFwaV9pbXBsZW1lbnRhdGlvbi5WZXJzaW9uKCkgIT0gMiwKKyAgICAgICdFcnJvcnMgYXJlIG9ubHkgYXZhaWxhYmxlIGZyb20gdGhlIG1vc3QgcmVjZW50IEMrKyBpbXBsZW1lbnRhdGlvbi4nKQorICBkZWYgdGVzdEZpbGVEZXNjcmlwdG9yRXJyb3JzKHNlbGYpOgorICAgIGZpbGVfbmFtZSA9ICd0ZXN0X2ZpbGVfZGVzY3JpcHRvcl9lcnJvcnMucHJvdG8nCisgICAgcGFja2FnZV9uYW1lID0gJ3Rlc3RfZmlsZV9kZXNjcmlwdG9yX2Vycm9ycy5wcm90bycKKyAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8gPSBkZXNjcmlwdG9yX3BiMi5GaWxlRGVzY3JpcHRvclByb3RvKCkKKyAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubmFtZSA9IGZpbGVfbmFtZQorICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by5wYWNrYWdlID0gcGFja2FnZV9uYW1lCisgICAgbTEgPSBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubWVzc2FnZV90eXBlLmFkZCgpCisgICAgbTEubmFtZSA9ICdtc2cxJworICAgICMgQ29tcGlsZXMgdGhlIHByb3RvIGludG8gdGhlIEMrKyBkZXNjcmlwdG9yIHBvb2wKKyAgICBkZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yKAorICAgICAgICBmaWxlX25hbWUsCisgICAgICAgIHBhY2thZ2VfbmFtZSwKKyAgICAgICAgc2VyaWFsaXplZF9wYj1maWxlX2Rlc2NyaXB0b3JfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgICAjIEFkZCBhIEZpbGVEZXNjcmlwdG9yUHJvdG8gdGhhdCBoYXMgZHVwbGljYXRlIHN5bWJvbHMKKyAgICBhbm90aGVyX2ZpbGVfbmFtZSA9ICdhbm90aGVyX3Rlc3RfZmlsZV9kZXNjcmlwdG9yX2Vycm9ycy5wcm90bycKKyAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubmFtZSA9IGFub3RoZXJfZmlsZV9uYW1lCisgICAgbTIgPSBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8ubWVzc2FnZV90eXBlLmFkZCgpCisgICAgbTIubmFtZSA9ICdtc2cyJworICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yKSBhcyBjbToKKyAgICAgIGRlc2NyaXB0b3IuRmlsZURlc2NyaXB0b3IoCisgICAgICAgICAgYW5vdGhlcl9maWxlX25hbWUsCisgICAgICAgICAgcGFja2FnZV9uYW1lLAorICAgICAgICAgIHNlcmlhbGl6ZWRfcGI9ZmlsZV9kZXNjcmlwdG9yX3Byb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgICBzZWxmLmFzc2VydFRydWUoaGFzYXR0cihjbSwgJ2V4Y2VwdGlvbicpLCAnJXMgbm90IHJhaXNlZCcgJQorICAgICAgICAgICAgICAgICAgICAgIGdldGF0dHIoY20uZXhwZWN0ZWQsICdfX25hbWVfXycsIGNtLmV4cGVjdGVkKSkKKyAgICAgIHNlbGYuYXNzZXJ0SW4oJ3Rlc3RfZmlsZV9kZXNjcmlwdG9yX2Vycm9ycy5wcm90bycsIHN0cihjbS5leGNlcHRpb24pKQorICAgICAgIyBFcnJvciBtZXNzYWdlIHdpbGwgc2F5IHNvbWV0aGluZyBhYm91dCB0aGlzIGRlZmluaXRpb24gYmVpbmcgYQorICAgICAgIyBkdXBsaWNhdGUsIHRob3VnaCB3ZSBkb24ndCBjaGVjayB0aGUgbWVzc2FnZSBleGFjdGx5IHRvIGF2b2lkIGEKKyAgICAgICMgZGVwZW5kZW5jeSBvbiB0aGUgQysrIGxvZ2dpbmcgY29kZS4KKyAgICAgIHNlbGYuYXNzZXJ0SW4oJ3Rlc3RfZmlsZV9kZXNjcmlwdG9yX2Vycm9ycy5tc2cxJywgc3RyKGNtLmV4Y2VwdGlvbikpCisKKyAgZGVmIHRlc3RTdHJpbmdVVEY4RW5jb2Rpbmcoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKworICAgICMgQXNzaWdubWVudCBvZiBhIHVuaWNvZGUgb2JqZWN0IHRvIGEgZmllbGQgb2YgdHlwZSAnYnl0ZXMnIGlzIG5vdCBhbGxvd2VkLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICBzZXRhdHRyLCBwcm90bywgJ29wdGlvbmFsX2J5dGVzJywgdSd1bmljb2RlIG9iamVjdCcpCisKKyAgICAjIENoZWNrIHRoYXQgdGhlIGRlZmF1bHQgdmFsdWUgaXMgb2YgcHl0aG9uJ3MgJ3VuaWNvZGUnIHR5cGUuCisgICAgc2VsZi5hc3NlcnRFcXVhbCh0eXBlKHByb3RvLm9wdGlvbmFsX3N0cmluZyksIHVuaWNvZGUpCisKKyAgICBwcm90by5vcHRpb25hbF9zdHJpbmcgPSB1bmljb2RlKCdUZXN0aW5nJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHByb3RvLm9wdGlvbmFsX3N0cmluZywgc3RyKCdUZXN0aW5nJykpCisKKyAgICAjIEFzc2lnbiBhIHZhbHVlIG9mIHR5cGUgJ3N0cicgd2hpY2ggY2FuIGJlIGVuY29kZWQgaW4gVVRGLTguCisgICAgcHJvdG8ub3B0aW9uYWxfc3RyaW5nID0gc3RyKCdUZXN0aW5nJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHByb3RvLm9wdGlvbmFsX3N0cmluZywgdW5pY29kZSgnVGVzdGluZycpKQorCisgICAgIyBUcnkgdG8gYXNzaWduIGEgJ2J5dGVzJyBvYmplY3Qgd2hpY2ggY29udGFpbnMgbm9uLVVURi04LgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgc2V0YXR0ciwgcHJvdG8sICdvcHRpb25hbF9zdHJpbmcnLCBiJ2FceDgwYScpCisgICAgIyBObyBleGNlcHRpb246IEFzc2lnbiBhbHJlYWR5IGVuY29kZWQgVVRGLTggYnl0ZXMgdG8gYSBzdHJpbmcgZmllbGQuCisgICAgdXRmOF9ieXRlcyA9IHUn0KLQtdGB0YInLmVuY29kZSgndXRmLTgnKQorICAgIHByb3RvLm9wdGlvbmFsX3N0cmluZyA9IHV0ZjhfYnl0ZXMKKyAgICAjIE5vIGV4Y2VwdGlvbjogQXNzaWduIHRoZSBhIG5vbi1hc2NpaSB1bmljb2RlIG9iamVjdC4KKyAgICBwcm90by5vcHRpb25hbF9zdHJpbmcgPSB1J9Ci0LXRgdGCJworICAgICMgTm8gZXhjZXB0aW9uIHRocm93biAobm9ybWFsIHN0ciBhc3NpZ25tZW50IGNvbnRhaW5pbmcgQVNDSUkpLgorICAgIHByb3RvLm9wdGlvbmFsX3N0cmluZyA9ICdhYmMnCisKKyAgZGVmIHRlc3RTdHJpbmdVVEY4U2VyaWFsaXphdGlvbihzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0KCkKKyAgICBleHRlbnNpb25fbWVzc2FnZSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMgorICAgIGV4dGVuc2lvbiA9IGV4dGVuc2lvbl9tZXNzYWdlLm1lc3NhZ2Vfc2V0X2V4dGVuc2lvbgorCisgICAgdGVzdF91dGY4ID0gdSfQotC10YHRgicKKyAgICB0ZXN0X3V0ZjhfYnl0ZXMgPSB0ZXN0X3V0ZjguZW5jb2RlKCd1dGYtOCcpCisKKyAgICAjICdUZXN0JyBpbiBhbm90aGVyIGxhbmd1YWdlLCB1c2luZyBVVEYtOCBjaGFyc2V0LgorICAgIHByb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXS5zdHIgPSB0ZXN0X3V0ZjgKKworICAgICMgU2VyaWFsaXplIHVzaW5nIHRoZSBNZXNzYWdlU2V0IHdpcmUgZm9ybWF0ICh0aGlzIGlzIHNwZWNpZmllZCBpbiB0aGUKKyAgICAjIC5wcm90byBmaWxlKS4KKyAgICBzZXJpYWxpemVkID0gcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgIyBDaGVjayBieXRlIHNpemUuCisgICAgc2VsZi5hc3NlcnRFcXVhbChwcm90by5CeXRlU2l6ZSgpLCBsZW4oc2VyaWFsaXplZCkpCisKKyAgICByYXcgPSB1bml0dGVzdF9tc2V0X3BiMi5SYXdNZXNzYWdlU2V0KCkKKyAgICBieXRlc19yZWFkID0gcmF3Lk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHNlcmlhbGl6ZWQpLCBieXRlc19yZWFkKQorCisgICAgbWVzc2FnZTIgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIoKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBsZW4ocmF3Lml0ZW0pKQorICAgICMgQ2hlY2sgdGhhdCB0aGUgdHlwZV9pZCBpcyB0aGUgc2FtZSBhcyB0aGUgdGFnIElEIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgICBzZWxmLmFzc2VydEVxdWFsKHJhdy5pdGVtWzBdLnR5cGVfaWQsIDE1NDc3NjkpCisKKyAgICAjIENoZWNrIHRoZSBhY3R1YWwgYnl0ZXMgb24gdGhlIHdpcmUuCisgICAgc2VsZi5hc3NlcnRUcnVlKAorICAgICAgICByYXcuaXRlbVswXS5tZXNzYWdlLmVuZHN3aXRoKHRlc3RfdXRmOF9ieXRlcykpCisgICAgYnl0ZXNfcmVhZCA9IG1lc3NhZ2UyLk1lcmdlRnJvbVN0cmluZyhyYXcuaXRlbVswXS5tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJhdy5pdGVtWzBdLm1lc3NhZ2UpLCBieXRlc19yZWFkKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbCh0eXBlKG1lc3NhZ2UyLnN0ciksIHVuaWNvZGUpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlMi5zdHIsIHRlc3RfdXRmOCkKKworICAgICMgVGhlIHB1cmUgUHl0aG9uIEFQSSB0aHJvd3MgYW4gZXhjZXB0aW9uIG9uIE1lcmdlRnJvbVN0cmluZygpLAorICAgICMgaWYgYW55IG9mIHRoZSBzdHJpbmcgZmllbGRzIG9mIHRoZSBtZXNzYWdlIGNhbid0IGJlIFVURi04IGRlY29kZWQuCisgICAgIyBUaGUgQysrIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBUEkgaGFzIG5vIHdheSB0byBjaGVjayB0aGF0IG9uCisgICAgIyBNZXJnZUZyb21TdHJpbmcgYW5kIHRodXMgaGFzIG5vIHdheSB0byB0aHJvdyB0aGUgZXhjZXB0aW9uLgorICAgICMKKyAgICAjIFRoZSBwdXJlIFB5dGhvbiBBUEkgYWx3YXlzIHJldHVybnMgb2JqZWN0cyBvZiB0eXBlICd1bmljb2RlJyAoVVRGLTgKKyAgICAjIGVuY29kZWQpLCBvciAnYnl0ZXMnIChpbiA3IGJpdCBBU0NJSSkuCisgICAgYmFkYnl0ZXMgPSByYXcuaXRlbVswXS5tZXNzYWdlLnJlcGxhY2UoCisgICAgICAgIHRlc3RfdXRmOF9ieXRlcywgbGVuKHRlc3RfdXRmOF9ieXRlcykgKiBiJ1x4ZmYnKQorCisgICAgdW5pY29kZV9kZWNvZGVfZmFpbGVkID0gRmFsc2UKKyAgICB0cnk6CisgICAgICBtZXNzYWdlMi5NZXJnZUZyb21TdHJpbmcoYmFkYnl0ZXMpCisgICAgZXhjZXB0IFVuaWNvZGVEZWNvZGVFcnJvcjoKKyAgICAgIHVuaWNvZGVfZGVjb2RlX2ZhaWxlZCA9IFRydWUKKyAgICBzdHJpbmdfZmllbGQgPSBtZXNzYWdlMi5zdHIKKyAgICBzZWxmLmFzc2VydFRydWUodW5pY29kZV9kZWNvZGVfZmFpbGVkIG9yIHR5cGUoc3RyaW5nX2ZpZWxkKSBpcyBieXRlcykKKworICBkZWYgdGVzdEJ5dGVzSW5UZXh0Rm9ybWF0KHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcyhvcHRpb25hbF9ieXRlcz1iJ1x4MDBceDdmXHg4MFx4ZmYnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodSdvcHRpb25hbF9ieXRlczogIlxcMDAwXFwxNzdcXDIwMFxcMzc3IlxuJywKKyAgICAgICAgICAgICAgICAgICAgIHVuaWNvZGUocHJvdG8pKQorCisgIGRlZiB0ZXN0RW1wdHlOZXN0ZWRNZXNzYWdlKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuTWVyZ2VGcm9tKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UoKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLkNvcHlGcm9tKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UoKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIGJ5dGVzX3JlYWQgPSBwcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5NZXJnZUZyb21TdHJpbmcoYicnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgYnl0ZXNfcmVhZCkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhiJycpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorCisgICAgc2VyaWFsaXplZCA9IHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBsZW4oc2VyaWFsaXplZCksCisgICAgICAgIHByb3RvMi5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvMi5IYXNGaWVsZCgnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UnKSkKKworICBkZWYgdGVzdFNldEluUGFyZW50KHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5hc3NlcnRGYWxzZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxncm91cCcpKQorICAgIHByb3RvLm9wdGlvbmFsZ3JvdXAuU2V0SW5QYXJlbnQoKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxncm91cCcpKQorCisgIGRlZiB0ZXN0UGFja2FnZUluaXRpYWxpemF0aW9uSW1wb3J0KHNlbGYpOgorICAgICIiIlRlc3QgdGhhdCB3ZSBjYW4gaW1wb3J0IG5lc3RlZCBtZXNzYWdlcyBmcm9tIHRoZWlyIF9faW5pdF9fLnB5LgorCisgICAgU3VjaCBzZXR1cCBpcyBub3QgdHJpdmlhbCBzaW5jZSBhdCB0aGUgdGltZSBvZiBwcm9jZXNzaW5nIG9mIF9faW5pdF9fLnB5IG9uZQorICAgIGNhbid0IHJlZmVyIHRvIGl0cyBzdWJtb2R1bGVzIGJ5IG5hbWUgaW4gY29kZSwgc28gZXhwcmVzc2lvbnMgbGlrZQorICAgIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC5pbXBvcnRfdGVzdF9wYWNrYWdlLmlubmVyX3BiMgorICAgIGRvbid0IHdvcmsuIFRoZXkgZG8gd29yayBpbiBpbXBvcnRzLCBzbyB3ZSBoYXZlIGFzc2lnbiBhbiBhbGlhcyBhdCBpbXBvcnQKKyAgICBhbmQgdGhlbiB1c2UgdGhhdCBhbGlhcyBpbiBnZW5lcmF0ZWQgY29kZS4KKyAgICAiIiIKKyAgICAjIFdlIGltcG9ydCBoZXJlIHNpbmNlIGl0J3MgdGhlIGltcG9ydCB0aGF0IHVzZWQgdG8gZmFpbCwgYW5kIHdlIHdhbnQKKyAgICAjIHRoZSBmYWlsdXJlIHRvIGhhdmUgdGhlIHJpZ2h0IGNvbnRleHQuCisgICAgIyBweWxpbnQ6IGRpc2FibGU9Zy1pbXBvcnQtbm90LWF0LXRvcAorICAgIGZyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBpbXBvcnRfdGVzdF9wYWNrYWdlCisgICAgIyBweWxpbnQ6IGVuYWJsZT1nLWltcG9ydC1ub3QtYXQtdG9wCisgICAgbXNnID0gaW1wb3J0X3Rlc3RfcGFja2FnZS5teXByb3RvLk91dGVyKCkKKyAgICAjIEp1c3QgY2hlY2sgdGhlIGRlZmF1bHQgdmFsdWUuCisgICAgc2VsZi5hc3NlcnRFcXVhbCg1NywgbXNnLmlubmVyLnZhbHVlKQorCisgIEBiYXNldGVzdC51bml0dGVzdC5za2lwSWYoCisgICAgICBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpICE9ICdjcHAnIG9yIGFwaV9pbXBsZW1lbnRhdGlvbi5WZXJzaW9uKCkgIT0gMiwKKyAgICAgICdDUFB2Mi1zcGVjaWZpYyB0ZXN0JykKKyAgZGVmIHRlc3RCYWRBcmd1bWVudHMoc2VsZik6CisgICAgIyBTb21lIG9mIHRoZXNlIGFzc2VydGlvbnMgdXNlZCB0byBzZWdmYXVsdC4KKyAgICBmcm9tIGdvb2dsZS5wcm90b2J1Zi5weWV4dCBpbXBvcnQgX21lc3NhZ2UKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIF9tZXNzYWdlLk1lc3NhZ2UuX0dldEZpZWxkRGVzY3JpcHRvciwgMykKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIF9tZXNzYWdlLk1lc3NhZ2UuX0dldEV4dGVuc2lvbkRlc2NyaXB0b3IsIDQyKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkuX19nZXRhdHRyaWJ1dGVfXywgNDIpCisKKworIyAgU2luY2Ugd2UgaGFkIHNvIG1hbnkgdGVzdHMgZm9yIHByb3RvY29sIGJ1ZmZlciBlcXVhbGl0eSwgd2UgYnJva2UgdGhlc2Ugb3V0CisjICBpbnRvIHNlcGFyYXRlIFRlc3RDYXNlIGNsYXNzZXMuCisKKworY2xhc3MgVGVzdEFsbFR5cGVzRXF1YWxpdHlUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgc2V0VXAoc2VsZik6CisgICAgc2VsZi5maXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuc2Vjb25kX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisKKyAgZGVmIHRlc3ROb3RIYXNoYWJsZShzZWxmKToKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIGhhc2gsIHNlbGYuZmlyc3RfcHJvdG8pCisKKyAgZGVmIHRlc3RTZWxmRXF1YWxpdHkoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmZpcnN0X3Byb3RvLCBzZWxmLmZpcnN0X3Byb3RvKQorCisgIGRlZiB0ZXN0RW1wdHlQcm90b3NFcXVhbChzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuZmlyc3RfcHJvdG8sIHNlbGYuc2Vjb25kX3Byb3RvKQorCisKK2NsYXNzIEZ1bGxQcm90b3NFcXVhbGl0eVRlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgICIiIkVxdWFsaXR5IHRlc3RzIHVzaW5nIGNvbXBsZXRlbHktZnVsbCBwcm90b3MgYXMgYSBzdGFydGluZyBwb2ludC4iIiIKKworICBkZWYgc2V0VXAoc2VsZik6CisgICAgc2VsZi5maXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuc2Vjb25kX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbEZpZWxkcyhzZWxmLmZpcnN0X3Byb3RvKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMoc2VsZi5zZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3ROb3RIYXNoYWJsZShzZWxmKToKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIGhhc2gsIHNlbGYuZmlyc3RfcHJvdG8pCisKKyAgZGVmIHRlc3ROb25lTm90RXF1YWwoc2VsZik6CisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChzZWxmLmZpcnN0X3Byb3RvLCBOb25lKQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoTm9uZSwgc2VsZi5zZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3ROb3RFcXVhbFRvT3RoZXJNZXNzYWdlKHNlbGYpOgorICAgIHRoaXJkX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZCgpCisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChzZWxmLmZpcnN0X3Byb3RvLCB0aGlyZF9wcm90bykKKyAgICBzZWxmLmFzc2VydE5vdEVxdWFsKHRoaXJkX3Byb3RvLCBzZWxmLnNlY29uZF9wcm90bykKKworICBkZWYgdGVzdEFsbEZpZWxkc0ZpbGxlZEVxdWFsaXR5KHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3ROb25SZXBlYXRlZFNjYWxhcihzZWxmKToKKyAgICAjIE5vbnJlcGVhdGVkIHNjYWxhciBmaWVsZCBjaGFuZ2Ugc2hvdWxkIGNhdXNlIGluZXF1YWxpdHkuCisgICAgc2VsZi5maXJzdF9wcm90by5vcHRpb25hbF9pbnQzMiArPSAxCisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChzZWxmLmZpcnN0X3Byb3RvLCBzZWxmLnNlY29uZF9wcm90bykKKyAgICAjIC4uLmFzIHNob3VsZCBjbGVhcmluZyBhIGZpZWxkLgorICAgIHNlbGYuZmlyc3RfcHJvdG8uQ2xlYXJGaWVsZCgnb3B0aW9uYWxfaW50MzInKQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3ROb25SZXBlYXRlZENvbXBvc2l0ZShzZWxmKToKKyAgICAjIENoYW5nZSBhIG5vbnJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZC4KKyAgICBzZWxmLmZpcnN0X3Byb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiICs9IDEKKyAgICBzZWxmLmFzc2VydE5vdEVxdWFsKHNlbGYuZmlyc3RfcHJvdG8sIHNlbGYuc2Vjb25kX3Byb3RvKQorICAgIHNlbGYuZmlyc3RfcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIgLT0gMQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisgICAgIyBDbGVhciBhIGZpZWxkIGluIHRoZSBuZXN0ZWQgbWVzc2FnZS4KKyAgICBzZWxmLmZpcnN0X3Byb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLkNsZWFyRmllbGQoJ2JiJykKKyAgICBzZWxmLmFzc2VydE5vdEVxdWFsKHNlbGYuZmlyc3RfcHJvdG8sIHNlbGYuc2Vjb25kX3Byb3RvKQorICAgIHNlbGYuZmlyc3RfcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIgPSAoCisgICAgICAgIHNlbGYuc2Vjb25kX3Byb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisgICAgIyBSZW1vdmUgdGhlIG5lc3RlZCBtZXNzYWdlIGVudGlyZWx5LgorICAgIHNlbGYuZmlyc3RfcHJvdG8uQ2xlYXJGaWVsZCgnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UnKQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3RSZXBlYXRlZFNjYWxhcihzZWxmKToKKyAgICAjIENoYW5nZSBhIHJlcGVhdGVkIHNjYWxhciBmaWVsZC4KKyAgICBzZWxmLmZpcnN0X3Byb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCg1KQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisgICAgc2VsZi5maXJzdF9wcm90by5DbGVhckZpZWxkKCdyZXBlYXRlZF9pbnQzMicpCisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChzZWxmLmZpcnN0X3Byb3RvLCBzZWxmLnNlY29uZF9wcm90bykKKworICBkZWYgdGVzdFJlcGVhdGVkQ29tcG9zaXRlKHNlbGYpOgorICAgICMgQ2hhbmdlIHZhbHVlIHdpdGhpbiBhIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZC4KKyAgICBzZWxmLmZpcnN0X3Byb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdLmJiICs9IDEKKyAgICBzZWxmLmFzc2VydE5vdEVxdWFsKHNlbGYuZmlyc3RfcHJvdG8sIHNlbGYuc2Vjb25kX3Byb3RvKQorICAgIHNlbGYuZmlyc3RfcHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VbMF0uYmIgLT0gMQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisgICAgIyBBZGQgYSB2YWx1ZSB0byBhIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZC4KKyAgICBzZWxmLmZpcnN0X3Byb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChzZWxmLmZpcnN0X3Byb3RvLCBzZWxmLnNlY29uZF9wcm90bykKKyAgICBzZWxmLnNlY29uZF9wcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3ROb25SZXBlYXRlZFNjYWxhckhhc0JpdHMoc2VsZik6CisgICAgIyBFbnN1cmUgdGhhdCB3ZSB0ZXN0ICJoYXMiIGJpdHMgYXMgd2VsbCBhcyB2YWx1ZSBmb3IKKyAgICAjIG5vbnJlcGVhdGVkIHNjYWxhciBmaWVsZC4KKyAgICBzZWxmLmZpcnN0X3Byb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX2ludDMyJykKKyAgICBzZWxmLnNlY29uZF9wcm90by5vcHRpb25hbF9pbnQzMiA9IDAKKyAgICBzZWxmLmFzc2VydE5vdEVxdWFsKHNlbGYuZmlyc3RfcHJvdG8sIHNlbGYuc2Vjb25kX3Byb3RvKQorCisgIGRlZiB0ZXN0Tm9uUmVwZWF0ZWRDb21wb3NpdGVIYXNCaXRzKHNlbGYpOgorICAgICMgRW5zdXJlIHRoYXQgd2UgdGVzdCAiaGFzIiBiaXRzIGFzIHdlbGwgYXMgdmFsdWUgZm9yCisgICAgIyBub25yZXBlYXRlZCBjb21wb3NpdGUgZmllbGQuCisgICAgc2VsZi5maXJzdF9wcm90by5DbGVhckZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpCisgICAgc2VsZi5zZWNvbmRfcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuQ2xlYXJGaWVsZCgnYmInKQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoc2VsZi5maXJzdF9wcm90bywgc2VsZi5zZWNvbmRfcHJvdG8pCisgICAgc2VsZi5maXJzdF9wcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYiA9IDAKKyAgICBzZWxmLmZpcnN0X3Byb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLkNsZWFyRmllbGQoJ2JiJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuZmlyc3RfcHJvdG8sIHNlbGYuc2Vjb25kX3Byb3RvKQorCisKK2NsYXNzIEV4dGVuc2lvbkVxdWFsaXR5VGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3RFeHRlbnNpb25FcXVhbGl0eShzZWxmKToKKyAgICBmaXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgc2Vjb25kX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisgICAgdGVzdF91dGlsLlNldEFsbEV4dGVuc2lvbnMoZmlyc3RfcHJvdG8pCisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChmaXJzdF9wcm90bywgc2Vjb25kX3Byb3RvKQorICAgIHRlc3RfdXRpbC5TZXRBbGxFeHRlbnNpb25zKHNlY29uZF9wcm90bykKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisKKyAgICAjIEVuc3VyZSB0aGF0IHdlIGNoZWNrIHZhbHVlIGVxdWFsaXR5LgorICAgIGZpcnN0X3Byb3RvLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl0gKz0gMQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoZmlyc3RfcHJvdG8sIHNlY29uZF9wcm90bykKKyAgICBmaXJzdF9wcm90by5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5vcHRpb25hbF9pbnQzMl9leHRlbnNpb25dIC09IDEKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisKKyAgICAjIEVuc3VyZSB0aGF0IHdlIGFsc28gbG9vayBhdCAiaGFzIiBiaXRzLgorICAgIGZpcnN0X3Byb3RvLkNsZWFyRXh0ZW5zaW9uKHVuaXR0ZXN0X3BiMi5vcHRpb25hbF9pbnQzMl9leHRlbnNpb24pCisgICAgc2Vjb25kX3Byb3RvLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl0gPSAwCisgICAgc2VsZi5hc3NlcnROb3RFcXVhbChmaXJzdF9wcm90bywgc2Vjb25kX3Byb3RvKQorICAgIGZpcnN0X3Byb3RvLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl0gPSAwCisgICAgc2VsZi5hc3NlcnRFcXVhbChmaXJzdF9wcm90bywgc2Vjb25kX3Byb3RvKQorCisgICAgIyBFbnN1cmUgdGhhdCBkaWZmZXJlbmNlcyBpbiBjYWNoZWQgdmFsdWVzCisgICAgIyBkb24ndCBtYXR0ZXIgaWYgImhhcyIgYml0cyBhcmUgYm90aCBmYWxzZS4KKyAgICBmaXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgc2Vjb25kX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICAwLCBmaXJzdF9wcm90by5FeHRlbnNpb25zW3VuaXR0ZXN0X3BiMi5vcHRpb25hbF9pbnQzMl9leHRlbnNpb25dKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmlyc3RfcHJvdG8sIHNlY29uZF9wcm90bykKKworCitjbGFzcyBNdXR1YWxSZWN1cnNpb25FcXVhbGl0eVRlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiB0ZXN0RXF1YWxpdHlXaXRoTXV0dWFsUmVjdXJzaW9uKHNlbGYpOgorICAgIGZpcnN0X3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RNdXR1YWxSZWN1cnNpb25BKCkKKyAgICBzZWNvbmRfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdE11dHVhbFJlY3Vyc2lvbkEoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmlyc3RfcHJvdG8sIHNlY29uZF9wcm90bykKKyAgICBmaXJzdF9wcm90by5iYi5hLmJiLm9wdGlvbmFsX2ludDMyID0gMjMKKyAgICBzZWxmLmFzc2VydE5vdEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisgICAgc2Vjb25kX3Byb3RvLmJiLmEuYmIub3B0aW9uYWxfaW50MzIgPSAyMworICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmlyc3RfcHJvdG8sIHNlY29uZF9wcm90bykKKworCitjbGFzcyBCeXRlU2l6ZVRlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiBzZXRVcChzZWxmKToKKyAgICBzZWxmLnByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2VsZi5leHRlbmRlZF9wcm90byA9IG1vcmVfZXh0ZW5zaW9uc19wYjIuRXh0ZW5kZWRNZXNzYWdlKCkKKyAgICBzZWxmLnBhY2tlZF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkVHlwZXMoKQorICAgIHNlbGYucGFja2VkX2V4dGVuZGVkX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RQYWNrZWRFeHRlbnNpb25zKCkKKworICBkZWYgU2l6ZShzZWxmKToKKyAgICByZXR1cm4gc2VsZi5wcm90by5CeXRlU2l6ZSgpCisKKyAgZGVmIHRlc3RFbXB0eU1lc3NhZ2Uoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBzZWxmLnByb3RvLkJ5dGVTaXplKCkpCisKKyAgZGVmIHRlc3RTaXplZE9uS3dhcmdzKHNlbGYpOgorICAgICMgVXNlIGEgc2VwYXJhdGUgbWVzc2FnZSB0byBlbnN1cmUgdGVzdGluZyByaWdodCBhZnRlciBjcmVhdGlvbi4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgcHJvdG8uQnl0ZVNpemUoKSkKKyAgICBwcm90b19rd2FyZ3MgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKG9wdGlvbmFsX2ludDY0ID0gMSkKKyAgICAjIE9uZSBieXRlIGZvciB0aGUgdGFnLCBvbmUgdG8gZW5jb2RlIHZhcmludCAxLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgcHJvdG9fa3dhcmdzLkJ5dGVTaXplKCkpCisKKyAgZGVmIHRlc3RWYXJpbnRzKHNlbGYpOgorICAgIGRlZiBUZXN0KGksIGV4cGVjdGVkX3ZhcmludF9zaXplKToKKyAgICAgIHNlbGYucHJvdG8uQ2xlYXIoKQorICAgICAgc2VsZi5wcm90by5vcHRpb25hbF9pbnQ2NCA9IGkKKyAgICAgICMgQWRkIG9uZSB0byB0aGUgdmFyaW50IHNpemUgZm9yIHRoZSB0YWcgaW5mbworICAgICAgIyBmb3IgdGFnIDEuCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGV4cGVjdGVkX3ZhcmludF9zaXplICsgMSwgc2VsZi5TaXplKCkpCisgICAgVGVzdCgwLCAxKQorICAgIFRlc3QoMSwgMSkKKyAgICBmb3IgaSwgbnVtX2J5dGVzIGluIHppcChyYW5nZSg3LCA2MywgNyksIHJhbmdlKDEsIDEwMDAwKSk6CisgICAgICBUZXN0KCgxIDw8IGkpIC0gMSwgbnVtX2J5dGVzKQorICAgIFRlc3QoLTEsIDEwKQorICAgIFRlc3QoLTIsIDEwKQorICAgIFRlc3QoLSgxIDw8IDYzKSwgMTApCisKKyAgZGVmIHRlc3RTdHJpbmdzKHNlbGYpOgorICAgIHNlbGYucHJvdG8ub3B0aW9uYWxfc3RyaW5nID0gJycKKyAgICAjIE5lZWQgb25lIGJ5dGUgZm9yIHRhZyBpbmZvICh0YWcgIzE0KSwgYW5kIG9uZSBieXRlIGZvciBsZW5ndGguCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBzZWxmLlNpemUoKSkKKworICAgIHNlbGYucHJvdG8ub3B0aW9uYWxfc3RyaW5nID0gJ2FiYycKKyAgICAjIE5lZWQgb25lIGJ5dGUgZm9yIHRhZyBpbmZvICh0YWcgIzE0KSwgYW5kIG9uZSBieXRlIGZvciBsZW5ndGguCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyICsgbGVuKHNlbGYucHJvdG8ub3B0aW9uYWxfc3RyaW5nKSwgc2VsZi5TaXplKCkpCisKKyAgICBzZWxmLnByb3RvLm9wdGlvbmFsX3N0cmluZyA9ICd4JyAqIDEyOAorICAgICMgTmVlZCBvbmUgYnl0ZSBmb3IgdGFnIGluZm8gKHRhZyAjMTQpLCBhbmQgVFdPIGJ5dGVzIGZvciBsZW5ndGguCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzICsgbGVuKHNlbGYucHJvdG8ub3B0aW9uYWxfc3RyaW5nKSwgc2VsZi5TaXplKCkpCisKKyAgZGVmIHRlc3RPdGhlck51bWVyaWNzKHNlbGYpOgorICAgIHNlbGYucHJvdG8ub3B0aW9uYWxfZml4ZWQzMiA9IDEyMzQKKyAgICAjIE9uZSBieXRlIGZvciB0YWcgYW5kIDQgYnl0ZXMgZm9yIGZpeGVkMzIuCisgICAgc2VsZi5hc3NlcnRFcXVhbCg1LCBzZWxmLlNpemUoKSkKKyAgICBzZWxmLnByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisKKyAgICBzZWxmLnByb3RvLm9wdGlvbmFsX2ZpeGVkNjQgPSAxMjM0CisgICAgIyBPbmUgYnl0ZSBmb3IgdGFnIGFuZCA4IGJ5dGVzIGZvciBmaXhlZDY0LgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoOSwgc2VsZi5TaXplKCkpCisgICAgc2VsZi5wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorCisgICAgc2VsZi5wcm90by5vcHRpb25hbF9mbG9hdCA9IDEuMjM0CisgICAgIyBPbmUgYnl0ZSBmb3IgdGFnIGFuZCA0IGJ5dGVzIGZvciBmbG9hdC4KKyAgICBzZWxmLmFzc2VydEVxdWFsKDUsIHNlbGYuU2l6ZSgpKQorICAgIHNlbGYucHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKworICAgIHNlbGYucHJvdG8ub3B0aW9uYWxfZG91YmxlID0gMS4yMzQKKyAgICAjIE9uZSBieXRlIGZvciB0YWcgYW5kIDggYnl0ZXMgZm9yIGZsb2F0LgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoOSwgc2VsZi5TaXplKCkpCisgICAgc2VsZi5wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorCisgICAgc2VsZi5wcm90by5vcHRpb25hbF9zaW50MzIgPSA2NAorICAgICMgT25lIGJ5dGUgZm9yIHRhZyBhbmQgMiBieXRlcyBmb3IgemlnLXphZy1lbmNvZGVkIDY0LgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgc2VsZi5TaXplKCkpCisgICAgc2VsZi5wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorCisgIGRlZiB0ZXN0Q29tcG9zaXRlcyhzZWxmKToKKyAgICAjIDMgYnl0ZXMuCisgICAgc2VsZi5wcm90by5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYiA9ICgxIDw8IDE0KQorICAgICMgUGx1cyBvbmUgYnl0ZSBmb3IgYmIgdGFnLgorICAgICMgUGx1cyAxIGJ5dGUgZm9yIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHNlcmlhbGl6ZWQgc2l6ZS4KKyAgICAjIFBsdXMgdHdvIGJ5dGVzIGZvciBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSB0YWcuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzICsgMSArIDEgKyAyLCBzZWxmLlNpemUoKSkKKworICBkZWYgdGVzdEdyb3VwcyhzZWxmKToKKyAgICAjIDQgYnl0ZXMuCisgICAgc2VsZi5wcm90by5vcHRpb25hbGdyb3VwLmEgPSAoMSA8PCAyMSkKKyAgICAjIFBsdXMgdHdvIGJ5dGVzIGZvciB8YXwgdGFnLgorICAgICMgUGx1cyAyICogdHdvIGJ5dGVzIGZvciBTVEFSVF9HUk9VUCBhbmQgRU5EX0dST1VQIHRhZ3MuCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0ICsgMiArIDIqMiwgc2VsZi5TaXplKCkpCisKKyAgZGVmIHRlc3RSZXBlYXRlZFNjYWxhcnMoc2VsZik6CisgICAgc2VsZi5wcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMTApICAjIDEgYnl0ZS4KKyAgICBzZWxmLnByb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxMjgpICAjIDIgYnl0ZXMuCisgICAgIyBBbHNvIG5lZWQgMiBieXRlcyBmb3IgZWFjaCBlbnRyeSBmb3IgdGFnLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSArIDIgKyAyKjIsIHNlbGYuU2l6ZSgpKQorCisgIGRlZiB0ZXN0UmVwZWF0ZWRTY2FsYXJzRXh0ZW5kKHNlbGYpOgorICAgIHNlbGYucHJvdG8ucmVwZWF0ZWRfaW50MzIuZXh0ZW5kKFsxMCwgMTI4XSkgICMgMyBieXRlcy4KKyAgICAjIEFsc28gbmVlZCAyIGJ5dGVzIGZvciBlYWNoIGVudHJ5IGZvciB0YWcuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxICsgMiArIDIqMiwgc2VsZi5TaXplKCkpCisKKyAgZGVmIHRlc3RSZXBlYXRlZFNjYWxhcnNSZW1vdmUoc2VsZik6CisgICAgc2VsZi5wcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMTApICAjIDEgYnl0ZS4KKyAgICBzZWxmLnByb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxMjgpICAjIDIgYnl0ZXMuCisgICAgIyBBbHNvIG5lZWQgMiBieXRlcyBmb3IgZWFjaCBlbnRyeSBmb3IgdGFnLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSArIDIgKyAyKjIsIHNlbGYuU2l6ZSgpKQorICAgIHNlbGYucHJvdG8ucmVwZWF0ZWRfaW50MzIucmVtb3ZlKDEyOCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEgKyAyLCBzZWxmLlNpemUoKSkKKworICBkZWYgdGVzdFJlcGVhdGVkQ29tcG9zaXRlcyhzZWxmKToKKyAgICAjIEVtcHR5IG1lc3NhZ2UuICAyIGJ5dGVzIHRhZyBwbHVzIDEgYnl0ZSBsZW5ndGguCisgICAgZm9yZWlnbl9tZXNzYWdlXzAgPSBzZWxmLnByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgIyAyIGJ5dGVzIHRhZyBwbHVzIDEgYnl0ZSBsZW5ndGggcGx1cyAxIGJ5dGUgYmIgdGFnIDEgYnl0ZSBpbnQuCisgICAgZm9yZWlnbl9tZXNzYWdlXzEgPSBzZWxmLnByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlLmFkZCgpCisgICAgZm9yZWlnbl9tZXNzYWdlXzEuYmIgPSA3CisgICAgc2VsZi5hc3NlcnRFcXVhbCgyICsgMSArIDIgKyAxICsgMSArIDEsIHNlbGYuU2l6ZSgpKQorCisgIGRlZiB0ZXN0UmVwZWF0ZWRDb21wb3NpdGVzRGVsZXRlKHNlbGYpOgorICAgICMgRW1wdHkgbWVzc2FnZS4gIDIgYnl0ZXMgdGFnIHBsdXMgMSBieXRlIGxlbmd0aC4KKyAgICBmb3JlaWduX21lc3NhZ2VfMCA9IHNlbGYucHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkKKyAgICAjIDIgYnl0ZXMgdGFnIHBsdXMgMSBieXRlIGxlbmd0aCBwbHVzIDEgYnl0ZSBiYiB0YWcgMSBieXRlIGludC4KKyAgICBmb3JlaWduX21lc3NhZ2VfMSA9IHNlbGYucHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkKKyAgICBmb3JlaWduX21lc3NhZ2VfMS5iYiA9IDkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIgKyAxICsgMiArIDEgKyAxICsgMSwgc2VsZi5TaXplKCkpCisKKyAgICAjIDIgYnl0ZXMgdGFnIHBsdXMgMSBieXRlIGxlbmd0aCBwbHVzIDEgYnl0ZSBiYiB0YWcgMSBieXRlIGludC4KKyAgICBkZWwgc2VsZi5wcm90by5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVswXQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiArIDEgKyAxICsgMSwgc2VsZi5TaXplKCkpCisKKyAgICAjIE5vdyBhZGQgYSBuZXcgbWVzc2FnZS4KKyAgICBmb3JlaWduX21lc3NhZ2VfMiA9IHNlbGYucHJvdG8ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkKKyAgICBmb3JlaWduX21lc3NhZ2VfMi5iYiA9IDEyCisKKyAgICAjIDIgYnl0ZXMgdGFnIHBsdXMgMSBieXRlIGxlbmd0aCBwbHVzIDEgYnl0ZSBiYiB0YWcgMSBieXRlIGludC4KKyAgICAjIDIgYnl0ZXMgdGFnIHBsdXMgMSBieXRlIGxlbmd0aCBwbHVzIDEgYnl0ZSBiYiB0YWcgMSBieXRlIGludC4KKyAgICBzZWxmLmFzc2VydEVxdWFsKDIgKyAxICsgMSArIDEgKyAyICsgMSArIDEgKyAxLCBzZWxmLlNpemUoKSkKKworICAgICMgMiBieXRlcyB0YWcgcGx1cyAxIGJ5dGUgbGVuZ3RoIHBsdXMgMSBieXRlIGJiIHRhZyAxIGJ5dGUgaW50LgorICAgIGRlbCBzZWxmLnByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzFdCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyICsgMSArIDEgKyAxLCBzZWxmLlNpemUoKSkKKworICAgIGRlbCBzZWxmLnByb3RvLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBzZWxmLlNpemUoKSkKKworICBkZWYgdGVzdFJlcGVhdGVkR3JvdXBzKHNlbGYpOgorICAgICMgMi1ieXRlIFNUQVJUX0dST1VQIHBsdXMgMi1ieXRlIEVORF9HUk9VUC4KKyAgICBncm91cF8wID0gc2VsZi5wcm90by5yZXBlYXRlZGdyb3VwLmFkZCgpCisgICAgIyAyLWJ5dGUgU1RBUlRfR1JPVVAgcGx1cyAyLWJ5dGUgfGF8IHRhZyArIDEtYnl0ZSB8YXwKKyAgICAjIHBsdXMgMi1ieXRlIEVORF9HUk9VUC4KKyAgICBncm91cF8xID0gc2VsZi5wcm90by5yZXBlYXRlZGdyb3VwLmFkZCgpCisgICAgZ3JvdXBfMS5hID0gIDcKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIgKyAyICsgMiArIDIgKyAxICsgMiwgc2VsZi5TaXplKCkpCisKKyAgZGVmIHRlc3RFeHRlbnNpb25zKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHByb3RvLkJ5dGVTaXplKCkpCisgICAgZXh0ZW5zaW9uID0gdW5pdHRlc3RfcGIyLm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgIyBGaWVsZCAjMSwgMSBieXRlLgorICAgIHByb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXSA9IDIzCisgICAgIyAxIGJ5dGUgZm9yIHRhZywgMSBieXRlIGZvciB2YWx1ZS4KKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHByb3RvLkJ5dGVTaXplKCkpCisKKyAgZGVmIHRlc3RDYWNoZUludmFsaWRhdGlvbkZvck5vbnJlcGVhdGVkU2NhbGFyKHNlbGYpOgorICAgICMgVGVzdCBub24tZXh0ZW5zaW9uLgorICAgIHNlbGYucHJvdG8ub3B0aW9uYWxfaW50MzIgPSAxCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBzZWxmLnByb3RvLkJ5dGVTaXplKCkpCisgICAgc2VsZi5wcm90by5vcHRpb25hbF9pbnQzMiA9IDEyOAorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgc2VsZi5wcm90by5CeXRlU2l6ZSgpKQorICAgIHNlbGYucHJvdG8uQ2xlYXJGaWVsZCgnb3B0aW9uYWxfaW50MzInKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgc2VsZi5wcm90by5CeXRlU2l6ZSgpKQorCisgICAgIyBUZXN0IHdpdGhpbiBleHRlbnNpb24uCisgICAgZXh0ZW5zaW9uID0gbW9yZV9leHRlbnNpb25zX3BiMi5vcHRpb25hbF9pbnRfZXh0ZW5zaW9uCisgICAgc2VsZi5leHRlbmRlZF9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0gPSAxCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBzZWxmLmV4dGVuZGVkX3Byb3RvLkJ5dGVTaXplKCkpCisgICAgc2VsZi5leHRlbmRlZF9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0gPSAxMjgKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMsIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKyAgICBzZWxmLmV4dGVuZGVkX3Byb3RvLkNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKworICBkZWYgdGVzdENhY2hlSW52YWxpZGF0aW9uRm9yUmVwZWF0ZWRTY2FsYXIoc2VsZik6CisgICAgIyBUZXN0IG5vbi1leHRlbnNpb24uCisgICAgc2VsZi5wcm90by5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDMsIHNlbGYucHJvdG8uQnl0ZVNpemUoKSkKKyAgICBzZWxmLnByb3RvLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNiwgc2VsZi5wcm90by5CeXRlU2l6ZSgpKQorICAgIHNlbGYucHJvdG8ucmVwZWF0ZWRfaW50MzJbMV0gPSAxMjgKKyAgICBzZWxmLmFzc2VydEVxdWFsKDcsIHNlbGYucHJvdG8uQnl0ZVNpemUoKSkKKyAgICBzZWxmLnByb3RvLkNsZWFyRmllbGQoJ3JlcGVhdGVkX2ludDMyJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHNlbGYucHJvdG8uQnl0ZVNpemUoKSkKKworICAgICMgVGVzdCB3aXRoaW4gZXh0ZW5zaW9uLgorICAgIGV4dGVuc2lvbiA9IG1vcmVfZXh0ZW5zaW9uc19wYjIucmVwZWF0ZWRfaW50X2V4dGVuc2lvbgorICAgIHJlcGVhdGVkID0gc2VsZi5leHRlbmRlZF9wcm90by5FeHRlbnNpb25zW2V4dGVuc2lvbl0KKyAgICByZXBlYXRlZC5hcHBlbmQoMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKyAgICByZXBlYXRlZC5hcHBlbmQoMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQsIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKyAgICByZXBlYXRlZFsxXSA9IDEyOAorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNSwgc2VsZi5leHRlbmRlZF9wcm90by5CeXRlU2l6ZSgpKQorICAgIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQ2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgc2VsZi5leHRlbmRlZF9wcm90by5CeXRlU2l6ZSgpKQorCisgIGRlZiB0ZXN0Q2FjaGVJbnZhbGlkYXRpb25Gb3JOb25yZXBlYXRlZE1lc3NhZ2Uoc2VsZik6CisgICAgIyBUZXN0IG5vbi1leHRlbnNpb24uCisgICAgc2VsZi5wcm90by5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UuYyA9IDEKKyAgICBzZWxmLmFzc2VydEVxdWFsKDUsIHNlbGYucHJvdG8uQnl0ZVNpemUoKSkKKyAgICBzZWxmLnByb3RvLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZS5jID0gMTI4CisgICAgc2VsZi5hc3NlcnRFcXVhbCg2LCBzZWxmLnByb3RvLkJ5dGVTaXplKCkpCisgICAgc2VsZi5wcm90by5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UuQ2xlYXJGaWVsZCgnYycpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCBzZWxmLnByb3RvLkJ5dGVTaXplKCkpCisgICAgc2VsZi5wcm90by5DbGVhckZpZWxkKCdvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgc2VsZi5wcm90by5CeXRlU2l6ZSgpKQorCisgICAgaWYgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSA9PSAncHl0aG9uJzoKKyAgICAgICMgVGhpcyBpcyBvbmx5IHBvc3NpYmxlIGluIHB1cmUtUHl0aG9uIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBUEkuCisgICAgICBjaGlsZCA9IHNlbGYucHJvdG8ub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlCisgICAgICBzZWxmLnByb3RvLkNsZWFyRmllbGQoJ29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZScpCisgICAgICBjaGlsZC5jID0gMTI4CisgICAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHNlbGYucHJvdG8uQnl0ZVNpemUoKSkKKworICAgICMgVGVzdCB3aXRoaW4gZXh0ZW5zaW9uLgorICAgIGV4dGVuc2lvbiA9IG1vcmVfZXh0ZW5zaW9uc19wYjIub3B0aW9uYWxfbWVzc2FnZV9leHRlbnNpb24KKyAgICBjaGlsZCA9IHNlbGYuZXh0ZW5kZWRfcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb25dCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBzZWxmLmV4dGVuZGVkX3Byb3RvLkJ5dGVTaXplKCkpCisgICAgY2hpbGQuZm9yZWlnbl9tZXNzYWdlX2ludCA9IDEKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQsIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKyAgICBjaGlsZC5mb3JlaWduX21lc3NhZ2VfaW50ID0gMTI4CisgICAgc2VsZi5hc3NlcnRFcXVhbCg1LCBzZWxmLmV4dGVuZGVkX3Byb3RvLkJ5dGVTaXplKCkpCisgICAgc2VsZi5leHRlbmRlZF9wcm90by5DbGVhckV4dGVuc2lvbihleHRlbnNpb24pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBzZWxmLmV4dGVuZGVkX3Byb3RvLkJ5dGVTaXplKCkpCisKKyAgZGVmIHRlc3RDYWNoZUludmFsaWRhdGlvbkZvclJlcGVhdGVkTWVzc2FnZShzZWxmKToKKyAgICAjIFRlc3Qgbm9uLWV4dGVuc2lvbi4KKyAgICBjaGlsZDAgPSBzZWxmLnByb3RvLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZS5hZGQoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgc2VsZi5wcm90by5CeXRlU2l6ZSgpKQorICAgIHNlbGYucHJvdG8ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlLmFkZCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg2LCBzZWxmLnByb3RvLkJ5dGVTaXplKCkpCisgICAgY2hpbGQwLmMgPSAxCisgICAgc2VsZi5hc3NlcnRFcXVhbCg4LCBzZWxmLnByb3RvLkJ5dGVTaXplKCkpCisgICAgc2VsZi5wcm90by5DbGVhckZpZWxkKCdyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgc2VsZi5wcm90by5CeXRlU2l6ZSgpKQorCisgICAgIyBUZXN0IHdpdGhpbiBleHRlbnNpb24uCisgICAgZXh0ZW5zaW9uID0gbW9yZV9leHRlbnNpb25zX3BiMi5yZXBlYXRlZF9tZXNzYWdlX2V4dGVuc2lvbgorICAgIGNoaWxkX2xpc3QgPSBzZWxmLmV4dGVuZGVkX3Byb3RvLkV4dGVuc2lvbnNbZXh0ZW5zaW9uXQorICAgIGNoaWxkMCA9IGNoaWxkX2xpc3QuYWRkKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKyAgICBjaGlsZF9saXN0LmFkZCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0LCBzZWxmLmV4dGVuZGVkX3Byb3RvLkJ5dGVTaXplKCkpCisgICAgY2hpbGQwLmZvcmVpZ25fbWVzc2FnZV9pbnQgPSAxCisgICAgc2VsZi5hc3NlcnRFcXVhbCg2LCBzZWxmLmV4dGVuZGVkX3Byb3RvLkJ5dGVTaXplKCkpCisgICAgY2hpbGQwLkNsZWFyRmllbGQoJ2ZvcmVpZ25fbWVzc2FnZV9pbnQnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoNCwgc2VsZi5leHRlbmRlZF9wcm90by5CeXRlU2l6ZSgpKQorICAgIHNlbGYuZXh0ZW5kZWRfcHJvdG8uQ2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgc2VsZi5leHRlbmRlZF9wcm90by5CeXRlU2l6ZSgpKQorCisgIGRlZiB0ZXN0UGFja2VkUmVwZWF0ZWRTY2FsYXJzKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgc2VsZi5wYWNrZWRfcHJvdG8uQnl0ZVNpemUoKSkKKworICAgIHNlbGYucGFja2VkX3Byb3RvLnBhY2tlZF9pbnQzMi5hcHBlbmQoMTApICAgIyAxIGJ5dGUuCisgICAgc2VsZi5wYWNrZWRfcHJvdG8ucGFja2VkX2ludDMyLmFwcGVuZCgxMjgpICAjIDIgYnl0ZXMuCisgICAgIyBUaGUgdGFnIGlzIDIgYnl0ZXMgKHRoZSBmaWVsZCBudW1iZXIgaXMgOTApLCBhbmQgdGhlIHZhcmludAorICAgICMgc3RvcmluZyB0aGUgbGVuZ3RoIGlzIDEgYnl0ZS4KKyAgICBpbnRfc2l6ZSA9IDEgKyAyICsgMworICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50X3NpemUsIHNlbGYucGFja2VkX3Byb3RvLkJ5dGVTaXplKCkpCisKKyAgICBzZWxmLnBhY2tlZF9wcm90by5wYWNrZWRfZG91YmxlLmFwcGVuZCg0LjIpICAgIyA4IGJ5dGVzCisgICAgc2VsZi5wYWNrZWRfcHJvdG8ucGFja2VkX2RvdWJsZS5hcHBlbmQoMy4yNSkgICMgOCBieXRlcworICAgICMgMiBtb3JlIHRhZyBieXRlcywgMSBtb3JlIGxlbmd0aCBieXRlLgorICAgIGRvdWJsZV9zaXplID0gOCArIDggKyAzCisgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRfc2l6ZStkb3VibGVfc2l6ZSwgc2VsZi5wYWNrZWRfcHJvdG8uQnl0ZVNpemUoKSkKKworICAgIHNlbGYucGFja2VkX3Byb3RvLkNsZWFyRmllbGQoJ3BhY2tlZF9pbnQzMicpCisgICAgc2VsZi5hc3NlcnRFcXVhbChkb3VibGVfc2l6ZSwgc2VsZi5wYWNrZWRfcHJvdG8uQnl0ZVNpemUoKSkKKworICBkZWYgdGVzdFBhY2tlZEV4dGVuc2lvbnMoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBzZWxmLnBhY2tlZF9leHRlbmRlZF9wcm90by5CeXRlU2l6ZSgpKQorICAgIGV4dGVuc2lvbiA9IHNlbGYucGFja2VkX2V4dGVuZGVkX3Byb3RvLkV4dGVuc2lvbnNbCisgICAgICAgIHVuaXR0ZXN0X3BiMi5wYWNrZWRfZml4ZWQzMl9leHRlbnNpb25dCisgICAgZXh0ZW5zaW9uLmV4dGVuZChbMSwgMiwgMywgNF0pICAgIyAxNiBieXRlcworICAgICMgVGFnIGlzIDMgYnl0ZXMuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxOSwgc2VsZi5wYWNrZWRfZXh0ZW5kZWRfcHJvdG8uQnl0ZVNpemUoKSkKKworCisjIElzc3VlcyB0byBiZSBzdXJlIHRvIGNvdmVyIGluY2x1ZGU6CisjICAgKiBIYW5kbGluZyBvZiB1bnJlY29nbml6ZWQgdGFncyAoInVuaW50ZXJwcmV0ZWRfYnl0ZXMiKS4KKyMgICAqIEhhbmRsaW5nIG9mIE1lc3NhZ2VTZXRzLgorIyAgICogQ29uc2lzdGVudCBvcmRlcmluZyBvZiB0YWdzIGluIHRoZSB3aXJlIGZvcm1hdCwKKyMgICAgIGluY2x1ZGluZyBvcmRlcmluZyBiZXR3ZWVuIGV4dGVuc2lvbnMgYW5kIG5vbi1leHRlbnNpb24KKyMgICAgIGZpZWxkcy4KKyMgICAqIENvbnNpc3RlbnQgc2VyaWFsaXphdGlvbiBvZiBuZWdhdGl2ZSBudW1iZXJzLCBlc3BlY2lhbGx5CisjICAgICBuZWdhdGl2ZSBpbnQzMnMuCisjICAgKiBIYW5kbGluZyBvZiBlbXB0eSBzdWJtZXNzYWdlcyAod2l0aCBhbmQgd2l0aG91dCAiaGFzIgorIyAgICAgYml0cyBzZXQpLgorCitjbGFzcyBTZXJpYWxpemF0aW9uVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3RTZXJpYWxpemVFbXRweU1lc3NhZ2Uoc2VsZik6CisgICAgZmlyc3RfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWNvbmRfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZXJpYWxpemVkID0gZmlyc3RfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmlyc3RfcHJvdG8uQnl0ZVNpemUoKSwgbGVuKHNlcmlhbGl6ZWQpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIGxlbihzZXJpYWxpemVkKSwKKyAgICAgICAgc2Vjb25kX3Byb3RvLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3RTZXJpYWxpemVBbGxGaWVsZHMoc2VsZik6CisgICAgZmlyc3RfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWNvbmRfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRmllbGRzKGZpcnN0X3Byb3RvKQorICAgIHNlcmlhbGl6ZWQgPSBmaXJzdF9wcm90by5TZXJpYWxpemVUb1N0cmluZygpCisgICAgc2VsZi5hc3NlcnRFcXVhbChmaXJzdF9wcm90by5CeXRlU2l6ZSgpLCBsZW4oc2VyaWFsaXplZCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHNlcmlhbGl6ZWQpLAorICAgICAgICBzZWNvbmRfcHJvdG8uTWVyZ2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmlyc3RfcHJvdG8sIHNlY29uZF9wcm90bykKKworICBkZWYgdGVzdFNlcmlhbGl6ZUFsbEV4dGVuc2lvbnMoc2VsZik6CisgICAgZmlyc3RfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIHNlY29uZF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgdGVzdF91dGlsLlNldEFsbEV4dGVuc2lvbnMoZmlyc3RfcHJvdG8pCisgICAgc2VyaWFsaXplZCA9IGZpcnN0X3Byb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBsZW4oc2VyaWFsaXplZCksCisgICAgICAgIHNlY29uZF9wcm90by5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChmaXJzdF9wcm90bywgc2Vjb25kX3Byb3RvKQorCisgIGRlZiB0ZXN0U2VyaWFsaXplV2l0aE9wdGlvbmFsR3JvdXAoc2VsZik6CisgICAgZmlyc3RfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWNvbmRfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBmaXJzdF9wcm90by5vcHRpb25hbGdyb3VwLmEgPSAyNDIKKyAgICBzZXJpYWxpemVkID0gZmlyc3RfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIGxlbihzZXJpYWxpemVkKSwKKyAgICAgICAgc2Vjb25kX3Byb3RvLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3RTZXJpYWxpemVOZWdhdGl2ZVZhbHVlcyhzZWxmKToKKyAgICBmaXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorCisgICAgZmlyc3RfcHJvdG8ub3B0aW9uYWxfaW50MzIgPSAtMQorICAgIGZpcnN0X3Byb3RvLm9wdGlvbmFsX2ludDY0ID0gLSgyIDw8IDQwKQorICAgIGZpcnN0X3Byb3RvLm9wdGlvbmFsX3NpbnQzMiA9IC0zCisgICAgZmlyc3RfcHJvdG8ub3B0aW9uYWxfc2ludDY0ID0gLSg0IDw8IDQwKQorICAgIGZpcnN0X3Byb3RvLm9wdGlvbmFsX3NmaXhlZDMyID0gLTUKKyAgICBmaXJzdF9wcm90by5vcHRpb25hbF9zZml4ZWQ2NCA9IC0oNiA8PCA0MCkKKworICAgIHNlY29uZF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuRnJvbVN0cmluZygKKyAgICAgICAgZmlyc3RfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKSkKKworICAgIHNlbGYuYXNzZXJ0RXF1YWwoZmlyc3RfcHJvdG8sIHNlY29uZF9wcm90bykKKworICBkZWYgdGVzdFBhcnNlVHJ1bmNhdGVkKHNlbGYpOgorICAgICMgVGhpcyB0ZXN0IGlzIG9ubHkgYXBwbGljYWJsZSBmb3IgdGhlIFB5dGhvbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQVBJLgorICAgIGlmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgIT0gJ3B5dGhvbic6CisgICAgICByZXR1cm4KKworICAgIGZpcnN0X3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbEZpZWxkcyhmaXJzdF9wcm90bykKKyAgICBzZXJpYWxpemVkID0gZmlyc3RfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgZm9yIHRydW5jYXRpb25fcG9pbnQgaW4geHJhbmdlKGxlbihzZXJpYWxpemVkKSArIDEpOgorICAgICAgdHJ5OgorICAgICAgICBzZWNvbmRfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICAgICAgdW5rbm93bl9maWVsZHMgPSB1bml0dGVzdF9wYjIuVGVzdEVtcHR5TWVzc2FnZSgpCisgICAgICAgIHBvcyA9IHNlY29uZF9wcm90by5fSW50ZXJuYWxQYXJzZShzZXJpYWxpemVkLCAwLCB0cnVuY2F0aW9uX3BvaW50KQorICAgICAgICAjIElmIHdlIGRpZG4ndCByYWlzZSBhbiBlcnJvciB0aGVuIHdlIHJlYWQgZXhhY3RseSB0aGUgYW1vdW50IGV4cGVjdGVkLgorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRydW5jYXRpb25fcG9pbnQsIHBvcykKKworICAgICAgICAjIFBhcnNpbmcgdG8gdW5rbm93biBmaWVsZHMgc2hvdWxkIG5vdCB0aHJvdyBpZiBwYXJzaW5nIHRvIGtub3duIGZpZWxkcworICAgICAgICAjIGRpZCBub3QuCisgICAgICAgIHRyeToKKyAgICAgICAgICBwb3MyID0gdW5rbm93bl9maWVsZHMuX0ludGVybmFsUGFyc2Uoc2VyaWFsaXplZCwgMCwgdHJ1bmNhdGlvbl9wb2ludCkKKyAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRydW5jYXRpb25fcG9pbnQsIHBvczIpCisgICAgICAgIGV4Y2VwdCBtZXNzYWdlLkRlY29kZUVycm9yOgorICAgICAgICAgIHNlbGYuZmFpbCgnUGFyc2luZyB1bmtub3duIGZpZWxkcyBmYWlsZWQgd2hlbiBwYXJzaW5nIGtub3duIGZpZWxkcyAnCisgICAgICAgICAgICAgICAgICAgICdkaWQgbm90LicpCisgICAgICBleGNlcHQgbWVzc2FnZS5EZWNvZGVFcnJvcjoKKyAgICAgICAgIyBQYXJzaW5nIHVua25vd24gZmllbGRzIHNob3VsZCBhbHNvIGZhaWwuCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKG1lc3NhZ2UuRGVjb2RlRXJyb3IsIHVua25vd25fZmllbGRzLl9JbnRlcm5hbFBhcnNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVkLCAwLCB0cnVuY2F0aW9uX3BvaW50KQorCisgIGRlZiB0ZXN0Q2Fub25pY2FsU2VyaWFsaXphdGlvbk9yZGVyKHNlbGYpOgorICAgIHByb3RvID0gbW9yZV9tZXNzYWdlc19wYjIuT3V0T2ZPcmRlckZpZWxkcygpCisgICAgIyBUaGVzZSBhcmUgYWxzbyB0aGVpciB0YWcgbnVtYmVycy4gIEV2ZW4gdGhvdWdoIHdlJ3JlIHNldHRpbmcgdGhlc2UgaW4KKyAgICAjIHJldmVyc2UtdGFnIG9yZGVyIEFORCB0aGV5J3JlIGxpc3RlZCBpbiByZXZlcnNlIHRhZy1vcmRlciBpbiB0aGUgLnByb3RvCisgICAgIyBmaWxlLCB0aGV5IHNob3VsZCBub25ldGhlbGVzcyBiZSBzZXJpYWxpemVkIGluIHRhZyBvcmRlci4KKyAgICBwcm90by5vcHRpb25hbF9zaW50MzIgPSA1CisgICAgcHJvdG8uRXh0ZW5zaW9uc1ttb3JlX21lc3NhZ2VzX3BiMi5vcHRpb25hbF91aW50NjRdID0gNAorICAgIHByb3RvLm9wdGlvbmFsX3VpbnQzMiA9IDMKKyAgICBwcm90by5FeHRlbnNpb25zW21vcmVfbWVzc2FnZXNfcGIyLm9wdGlvbmFsX2ludDY0XSA9IDIKKyAgICBwcm90by5vcHRpb25hbF9pbnQzMiA9IDEKKyAgICBzZXJpYWxpemVkID0gcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJvdG8uQnl0ZVNpemUoKSwgbGVuKHNlcmlhbGl6ZWQpKQorICAgIGQgPSBfTWluaURlY29kZXIoc2VyaWFsaXplZCkKKyAgICBSZWFkVGFnID0gZC5SZWFkRmllbGROdW1iZXJBbmRXaXJlVHlwZQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoKDEsIHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCksIFJlYWRUYWcoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIGQuUmVhZEludDMyKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgoMiwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5UKSwgUmVhZFRhZygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgZC5SZWFkSW50NjQoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCgzLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQpLCBSZWFkVGFnKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCBkLlJlYWRVSW50MzIoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCg0LCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQpLCBSZWFkVGFnKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0LCBkLlJlYWRVSW50NjQoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCg1LCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQpLCBSZWFkVGFnKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg1LCBkLlJlYWRTSW50MzIoKSkKKworICBkZWYgdGVzdENhbm9uaWNhbFNlcmlhbGl6YXRpb25PcmRlclNhbWVBc0NwcChzZWxmKToKKyAgICAjIENvcHkgb2YgdGhlIHNhbWUgdGVzdCB3ZSB1c2UgZm9yIEMrKy4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0RmllbGRPcmRlcmluZ3MoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHNBbmRFeHRlbnNpb25zKHByb3RvKQorICAgIHNlcmlhbGl6ZWQgPSBwcm90by5TZXJpYWxpemVUb1N0cmluZygpCisgICAgdGVzdF91dGlsLkV4cGVjdEFsbEZpZWxkc0FuZEV4dGVuc2lvbnNJbk9yZGVyKHNlcmlhbGl6ZWQpCisKKyAgZGVmIHRlc3RNZXJnZUZyb21TdHJpbmdXaGVuRmllbGRzQWxyZWFkeVNldChzZWxmKToKKyAgICBmaXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIGZpcnN0X3Byb3RvLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQoJ2Zvb2JhcicpCisgICAgZmlyc3RfcHJvdG8ub3B0aW9uYWxfaW50MzIgPSAyMworICAgIGZpcnN0X3Byb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiID0gNDIKKyAgICBzZXJpYWxpemVkID0gZmlyc3RfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgc2Vjb25kX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgc2Vjb25kX3Byb3RvLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQoJ2JheicpCisgICAgc2Vjb25kX3Byb3RvLm9wdGlvbmFsX2ludDMyID0gMTAwCisgICAgc2Vjb25kX3Byb3RvLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiID0gOTk5CisKKyAgICBieXRlc19wYXJzZWQgPSBzZWNvbmRfcHJvdG8uTWVyZ2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpCisgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oc2VyaWFsaXplZCksIGJ5dGVzX3BhcnNlZCkKKworICAgICMgRW5zdXJlIHRoYXQgd2UgYXBwZW5kIHRvIHJlcGVhdGVkIGZpZWxkcy4KKyAgICBzZWxmLmFzc2VydEVxdWFsKFsnYmF6JywgJ2Zvb2JhciddLCBsaXN0KHNlY29uZF9wcm90by5yZXBlYXRlZF9zdHJpbmcpKQorICAgICMgRW5zdXJlIHRoYXQgd2Ugb3ZlcndyaXRlIG5vbnJlcGVhdGQgc2NhbGFycy4KKyAgICBzZWxmLmFzc2VydEVxdWFsKDIzLCBzZWNvbmRfcHJvdG8ub3B0aW9uYWxfaW50MzIpCisgICAgIyBFbnN1cmUgdGhhdCB3ZSByZWN1cnNpdmVseSBjYWxsIE1lcmdlRnJvbVN0cmluZygpIG9uCisgICAgIyBzdWJtZXNzYWdlcy4KKyAgICBzZWxmLmFzc2VydEVxdWFsKDQyLCBzZWNvbmRfcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIpCisKKyAgZGVmIHRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdChzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0KCkKKyAgICBleHRlbnNpb25fbWVzc2FnZTEgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEKKyAgICBleHRlbnNpb25fbWVzc2FnZTIgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIKKyAgICBleHRlbnNpb24xID0gZXh0ZW5zaW9uX21lc3NhZ2UxLm1lc3NhZ2Vfc2V0X2V4dGVuc2lvbgorICAgIGV4dGVuc2lvbjIgPSBleHRlbnNpb25fbWVzc2FnZTIubWVzc2FnZV9zZXRfZXh0ZW5zaW9uCisgICAgcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb24xXS5pID0gMTIzCisgICAgcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb24yXS5zdHIgPSAnZm9vJworCisgICAgIyBTZXJpYWxpemUgdXNpbmcgdGhlIE1lc3NhZ2VTZXQgd2lyZSBmb3JtYXQgKHRoaXMgaXMgc3BlY2lmaWVkIGluIHRoZQorICAgICMgLnByb3RvIGZpbGUpLgorICAgIHNlcmlhbGl6ZWQgPSBwcm90by5TZXJpYWxpemVUb1N0cmluZygpCisKKyAgICByYXcgPSB1bml0dGVzdF9tc2V0X3BiMi5SYXdNZXNzYWdlU2V0KCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKEZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgcmF3LkRFU0NSSVBUT1IuR2V0T3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIGxlbihzZXJpYWxpemVkKSwKKyAgICAgICAgcmF3Lk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIGxlbihyYXcuaXRlbSkpCisKKyAgICBtZXNzYWdlMSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHJhdy5pdGVtWzBdLm1lc3NhZ2UpLAorICAgICAgICBtZXNzYWdlMS5NZXJnZUZyb21TdHJpbmcocmF3Lml0ZW1bMF0ubWVzc2FnZSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMjMsIG1lc3NhZ2UxLmkpCisKKyAgICBtZXNzYWdlMiA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMigpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHJhdy5pdGVtWzFdLm1lc3NhZ2UpLAorICAgICAgICBtZXNzYWdlMi5NZXJnZUZyb21TdHJpbmcocmF3Lml0ZW1bMV0ubWVzc2FnZSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnZm9vJywgbWVzc2FnZTIuc3RyKQorCisgICAgIyBEZXNlcmlhbGl6ZSB1c2luZyB0aGUgTWVzc2FnZVNldCB3aXJlIGZvcm1hdC4KKyAgICBwcm90bzIgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHNlcmlhbGl6ZWQpLAorICAgICAgICBwcm90bzIuTWVyZ2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTIzLCBwcm90bzIuRXh0ZW5zaW9uc1tleHRlbnNpb24xXS5pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ2ZvbycsIHByb3RvMi5FeHRlbnNpb25zW2V4dGVuc2lvbjJdLnN0cikKKworICAgICMgQ2hlY2sgYnl0ZSBzaXplLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJvdG8yLkJ5dGVTaXplKCksIGxlbihzZXJpYWxpemVkKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHByb3RvLkJ5dGVTaXplKCksIGxlbihzZXJpYWxpemVkKSkKKworICBkZWYgdGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0VW5rbm93bkV4dGVuc2lvbihzZWxmKToKKyAgICAjIENyZWF0ZSBhIG1lc3NhZ2UgdXNpbmcgdGhlIG1lc3NhZ2Ugc2V0IHdpcmUgZm9ybWF0IHdpdGggYW4gdW5rbm93bgorICAgICMgbWVzc2FnZS4KKyAgICByYXcgPSB1bml0dGVzdF9tc2V0X3BiMi5SYXdNZXNzYWdlU2V0KCkKKworICAgICMgQWRkIGFuIGl0ZW0uCisgICAgaXRlbSA9IHJhdy5pdGVtLmFkZCgpCisgICAgaXRlbS50eXBlX2lkID0gMTU0NTAwOAorICAgIGV4dGVuc2lvbl9tZXNzYWdlMSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMQorICAgIG1lc3NhZ2UxID0gdW5pdHRlc3RfbXNldF9wYjIuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xKCkKKyAgICBtZXNzYWdlMS5pID0gMTIzNDUKKyAgICBpdGVtLm1lc3NhZ2UgPSBtZXNzYWdlMS5TZXJpYWxpemVUb1N0cmluZygpCisKKyAgICAjIEFkZCBhIHNlY29uZCwgdW5rbm93biBleHRlbnNpb24uCisgICAgaXRlbSA9IHJhdy5pdGVtLmFkZCgpCisgICAgaXRlbS50eXBlX2lkID0gMTU0NTAwOQorICAgIGV4dGVuc2lvbl9tZXNzYWdlMSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMQorICAgIG1lc3NhZ2UxID0gdW5pdHRlc3RfbXNldF9wYjIuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xKCkKKyAgICBtZXNzYWdlMS5pID0gMTIzNDYKKyAgICBpdGVtLm1lc3NhZ2UgPSBtZXNzYWdlMS5TZXJpYWxpemVUb1N0cmluZygpCisKKyAgICAjIEFkZCBhbm90aGVyIHVua25vd24gZXh0ZW5zaW9uLgorICAgIGl0ZW0gPSByYXcuaXRlbS5hZGQoKQorICAgIGl0ZW0udHlwZV9pZCA9IDE1NDUwMTAKKyAgICBtZXNzYWdlMSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMigpCisgICAgbWVzc2FnZTEuc3RyID0gJ2ZvbycKKyAgICBpdGVtLm1lc3NhZ2UgPSBtZXNzYWdlMS5TZXJpYWxpemVUb1N0cmluZygpCisKKyAgICBzZXJpYWxpemVkID0gcmF3LlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICAgICMgUGFyc2UgbWVzc2FnZSB1c2luZyB0aGUgbWVzc2FnZSBzZXQgd2lyZSBmb3JtYXQuCisgICAgcHJvdG8gPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHNlcmlhbGl6ZWQpLAorICAgICAgICBwcm90by5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpCisKKyAgICAjIENoZWNrIHRoYXQgdGhlIG1lc3NhZ2UgcGFyc2VkIHdlbGwuCisgICAgZXh0ZW5zaW9uX21lc3NhZ2UxID0gdW5pdHRlc3RfbXNldF9wYjIuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xCisgICAgZXh0ZW5zaW9uMSA9IGV4dGVuc2lvbl9tZXNzYWdlMS5tZXNzYWdlX3NldF9leHRlbnNpb24KKyAgICBzZWxmLmFzc2VydEVxdWFscygxMjM0NSwgcHJvdG8uRXh0ZW5zaW9uc1tleHRlbnNpb24xXS5pKQorCisgIGRlZiB0ZXN0VW5rbm93bkZpZWxkcyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMocHJvdG8pCisKKyAgICBzZXJpYWxpemVkID0gcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgIyBUaGUgZW1wdHkgbWVzc2FnZSBzaG91bGQgYmUgcGFyc2FibGUgd2l0aCBhbGwgb2YgdGhlIGZpZWxkcworICAgICMgdW5rbm93bi4KKyAgICBwcm90bzIgPSB1bml0dGVzdF9wYjIuVGVzdEVtcHR5TWVzc2FnZSgpCisKKyAgICAjIFBhcnNpbmcgdGhpcyBtZXNzYWdlIHNob3VsZCBzdWNjZWVkLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIGxlbihzZXJpYWxpemVkKSwKKyAgICAgICAgcHJvdG8yLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKSkKKworICAgICMgTm93IHRlc3Qgd2l0aCBhIGludDY0IGZpZWxkIHNldC4KKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHByb3RvLm9wdGlvbmFsX2ludDY0ID0gMHgwZmZmZmZmZmZmZmZmZmZmCisgICAgc2VyaWFsaXplZCA9IHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICAjIFRoZSBlbXB0eSBtZXNzYWdlIHNob3VsZCBiZSBwYXJzYWJsZSB3aXRoIGFsbCBvZiB0aGUgZmllbGRzCisgICAgIyB1bmtub3duLgorICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlKCkKKyAgICAjIFBhcnNpbmcgdGhpcyBtZXNzYWdlIHNob3VsZCBzdWNjZWVkLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIGxlbihzZXJpYWxpemVkKSwKKyAgICAgICAgcHJvdG8yLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKSkKKworICBkZWYgX0NoZWNrUmFpc2VzKHNlbGYsIGV4Y19jbGFzcywgY2FsbGFibGVfb2JqLCBleGNlcHRpb24pOgorICAgICIiIlRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgZXhjcGV0aW9uIHR5cGUgYW5kIG1lc3NhZ2UgYXJlIGFzIGV4cGVjdGVkLiIiIgorICAgIHRyeToKKyAgICAgIGNhbGxhYmxlX29iaigpCisgICAgZXhjZXB0IGV4Y19jbGFzcyBhcyBleDoKKyAgICAgICMgQ2hlY2sgaWYgdGhlIGV4Y2VwdGlvbiBtZXNzYWdlIGlzIHRoZSByaWdodCBvbmUuCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGV4Y2VwdGlvbiwgc3RyKGV4KSkKKyAgICAgIHJldHVybgorICAgIGVsc2U6CisgICAgICByYWlzZSBzZWxmLmZhaWx1cmVFeGNlcHRpb24oJyVzIG5vdCByYWlzZWQnICUgc3RyKGV4Y19jbGFzcykpCisKKyAgZGVmIHRlc3RTZXJpYWxpemVVbmluaXRpYWxpemVkKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZCgpCisgICAgc2VsZi5fQ2hlY2tSYWlzZXMoCisgICAgICAgIG1lc3NhZ2UuRW5jb2RlRXJyb3IsCisgICAgICAgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nLAorICAgICAgICAnTWVzc2FnZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICcKKyAgICAgICAgJ2EsYixjJykKKyAgICAjIFNob3VsZG4ndCByYWlzZSBleGNlcHRpb25zLgorICAgIHBhcnRpYWwgPSBwcm90by5TZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmcoKQorCisgICAgcHJvdG8yID0gdW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZCgpCisgICAgc2VsZi5hc3NlcnRGYWxzZShwcm90bzIuSGFzRmllbGQoJ2EnKSkKKyAgICAjIHByb3RvMiBQYXJzZUZyb21TdHJpbmcgZG9lcyBub3QgY2hlY2sgdGhhdCByZXF1aXJlZCBmaWVsZHMgYXJlIHNldC4KKyAgICBwcm90bzIuUGFyc2VGcm9tU3RyaW5nKHBhcnRpYWwpCisgICAgc2VsZi5hc3NlcnRGYWxzZShwcm90bzIuSGFzRmllbGQoJ2EnKSkKKworICAgIHByb3RvLmEgPSAxCisgICAgc2VsZi5fQ2hlY2tSYWlzZXMoCisgICAgICAgIG1lc3NhZ2UuRW5jb2RlRXJyb3IsCisgICAgICAgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nLAorICAgICAgICAnTWVzc2FnZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6IGIsYycpCisgICAgIyBTaG91bGRuJ3QgcmFpc2UgZXhjZXB0aW9ucy4KKyAgICBwYXJ0aWFsID0gcHJvdG8uU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKCkKKworICAgIHByb3RvLmIgPSAyCisgICAgc2VsZi5fQ2hlY2tSYWlzZXMoCisgICAgICAgIG1lc3NhZ2UuRW5jb2RlRXJyb3IsCisgICAgICAgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nLAorICAgICAgICAnTWVzc2FnZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6IGMnKQorICAgICMgU2hvdWxkbid0IHJhaXNlIGV4Y2VwdGlvbnMuCisgICAgcGFydGlhbCA9IHByb3RvLlNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZygpCisKKyAgICBwcm90by5jID0gMworICAgIHNlcmlhbGl6ZWQgPSBwcm90by5TZXJpYWxpemVUb1N0cmluZygpCisgICAgIyBTaG91bGRuJ3QgcmFpc2UgZXhjZXB0aW9ucy4KKyAgICBwYXJ0aWFsID0gcHJvdG8uU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKCkKKworICAgIHByb3RvMiA9IHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWQoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICAgIGxlbihzZXJpYWxpemVkKSwKKyAgICAgICAgcHJvdG8yLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvMi5hKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgcHJvdG8yLmIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzLCBwcm90bzIuYykKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBsZW4ocGFydGlhbCksCisgICAgICAgIHByb3RvMi5NZXJnZUZyb21TdHJpbmcocGFydGlhbCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90bzIuYSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHByb3RvMi5iKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgcHJvdG8yLmMpCisKKyAgZGVmIHRlc3RTZXJpYWxpemVVbmluaXRpYWxpemVkU3ViTWVzc2FnZShzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0UmVxdWlyZWRGb3JlaWduKCkKKworICAgICMgU3ViLW1lc3NhZ2UgZG9lc24ndCBleGlzdCB5ZXQsIHNvIHRoaXMgc3VjY2VlZHMuCisgICAgcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgcHJvdG8ub3B0aW9uYWxfbWVzc2FnZS5hID0gMQorICAgIHNlbGYuX0NoZWNrUmFpc2VzKAorICAgICAgICBtZXNzYWdlLkVuY29kZUVycm9yLAorICAgICAgICBwcm90by5TZXJpYWxpemVUb1N0cmluZywKKyAgICAgICAgJ01lc3NhZ2UgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbiAnCisgICAgICAgICdpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogJworICAgICAgICAnb3B0aW9uYWxfbWVzc2FnZS5iLG9wdGlvbmFsX21lc3NhZ2UuYycpCisKKyAgICBwcm90by5vcHRpb25hbF9tZXNzYWdlLmIgPSAyCisgICAgcHJvdG8ub3B0aW9uYWxfbWVzc2FnZS5jID0gMworICAgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICAgIHByb3RvLnJlcGVhdGVkX21lc3NhZ2UuYWRkKCkuYSA9IDEKKyAgICBwcm90by5yZXBlYXRlZF9tZXNzYWdlLmFkZCgpLmIgPSAyCisgICAgc2VsZi5fQ2hlY2tSYWlzZXMoCisgICAgICAgIG1lc3NhZ2UuRW5jb2RlRXJyb3IsCisgICAgICAgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nLAorICAgICAgICAnTWVzc2FnZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWduIGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzOiAnCisgICAgICAgICdyZXBlYXRlZF9tZXNzYWdlWzBdLmIscmVwZWF0ZWRfbWVzc2FnZVswXS5jLCcKKyAgICAgICAgJ3JlcGVhdGVkX21lc3NhZ2VbMV0uYSxyZXBlYXRlZF9tZXNzYWdlWzFdLmMnKQorCisgICAgcHJvdG8ucmVwZWF0ZWRfbWVzc2FnZVswXS5iID0gMgorICAgIHByb3RvLnJlcGVhdGVkX21lc3NhZ2VbMF0uYyA9IDMKKyAgICBwcm90by5yZXBlYXRlZF9tZXNzYWdlWzFdLmEgPSAxCisgICAgcHJvdG8ucmVwZWF0ZWRfbWVzc2FnZVsxXS5jID0gMworICAgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICBkZWYgdGVzdFNlcmlhbGl6ZUFsbFBhY2tlZEZpZWxkcyhzZWxmKToKKyAgICBmaXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkVHlwZXMoKQorICAgIHNlY29uZF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxQYWNrZWRGaWVsZHMoZmlyc3RfcHJvdG8pCisgICAgc2VyaWFsaXplZCA9IGZpcnN0X3Byb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLkJ5dGVTaXplKCksIGxlbihzZXJpYWxpemVkKSkKKyAgICBieXRlc19yZWFkID0gc2Vjb25kX3Byb3RvLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2Vjb25kX3Byb3RvLkJ5dGVTaXplKCksIGJ5dGVzX3JlYWQpCisgICAgc2VsZi5hc3NlcnRFcXVhbChmaXJzdF9wcm90bywgc2Vjb25kX3Byb3RvKQorCisgIGRlZiB0ZXN0U2VyaWFsaXplQWxsUGFja2VkRXh0ZW5zaW9ucyhzZWxmKToKKyAgICBmaXJzdF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkRXh0ZW5zaW9ucygpCisgICAgc2Vjb25kX3Byb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RQYWNrZWRFeHRlbnNpb25zKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsUGFja2VkRXh0ZW5zaW9ucyhmaXJzdF9wcm90bykKKyAgICBzZXJpYWxpemVkID0gZmlyc3RfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIGJ5dGVzX3JlYWQgPSBzZWNvbmRfcHJvdG8uTWVyZ2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWNvbmRfcHJvdG8uQnl0ZVNpemUoKSwgYnl0ZXNfcmVhZCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGZpcnN0X3Byb3RvLCBzZWNvbmRfcHJvdG8pCisKKyAgZGVmIHRlc3RNZXJnZVBhY2tlZEZyb21TdHJpbmdXaGVuU29tZUZpZWxkc0FscmVhZHlTZXQoc2VsZik6CisgICAgZmlyc3RfcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFBhY2tlZFR5cGVzKCkKKyAgICBmaXJzdF9wcm90by5wYWNrZWRfaW50MzIuZXh0ZW5kKFsxLCAyXSkKKyAgICBmaXJzdF9wcm90by5wYWNrZWRfZG91YmxlLmFwcGVuZCgzLjApCisgICAgc2VyaWFsaXplZCA9IGZpcnN0X3Byb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICAgIHNlY29uZF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkVHlwZXMoKQorICAgIHNlY29uZF9wcm90by5wYWNrZWRfaW50MzIuYXBwZW5kKDMpCisgICAgc2Vjb25kX3Byb3RvLnBhY2tlZF9kb3VibGUuZXh0ZW5kKFsxLjAsIDIuMF0pCisgICAgc2Vjb25kX3Byb3RvLnBhY2tlZF9zaW50MzIuYXBwZW5kKDQpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICBsZW4oc2VyaWFsaXplZCksCisgICAgICAgIHNlY29uZF9wcm90by5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMywgMSwgMl0sIHNlY29uZF9wcm90by5wYWNrZWRfaW50MzIpCisgICAgc2VsZi5hc3NlcnRFcXVhbChbMS4wLCAyLjAsIDMuMF0sIHNlY29uZF9wcm90by5wYWNrZWRfZG91YmxlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoWzRdLCBzZWNvbmRfcHJvdG8ucGFja2VkX3NpbnQzMikKKworICBkZWYgdGVzdFBhY2tlZEZpZWxkc1dpcmVGb3JtYXQoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFBhY2tlZFR5cGVzKCkKKyAgICBwcm90by5wYWNrZWRfaW50MzIuZXh0ZW5kKFsxLCAyLCAxNTAsIDNdKSAgIyAxICsgMSArIDIgKyAxIGJ5dGVzCisgICAgcHJvdG8ucGFja2VkX2RvdWJsZS5leHRlbmQoWzEuMCwgMTAwMC4wXSkgICMgOCArIDggYnl0ZXMKKyAgICBwcm90by5wYWNrZWRfZmxvYXQuYXBwZW5kKDIuMCkgICAgICAgICAgICAgIyA0IGJ5dGVzLCB3aWxsIGJlIGJlZm9yZSBkb3VibGUKKyAgICBzZXJpYWxpemVkID0gcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwocHJvdG8uQnl0ZVNpemUoKSwgbGVuKHNlcmlhbGl6ZWQpKQorICAgIGQgPSBfTWluaURlY29kZXIoc2VyaWFsaXplZCkKKyAgICBSZWFkVGFnID0gZC5SZWFkRmllbGROdW1iZXJBbmRXaXJlVHlwZQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoKDkwLCB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKSwgUmVhZFRhZygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSsxKzErMiwgZC5SZWFkSW50MzIoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIGQuUmVhZEludDMyKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBkLlJlYWRJbnQzMigpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTUwLCBkLlJlYWRJbnQzMigpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgZC5SZWFkSW50MzIoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKCgxMDAsIHdpcmVfZm9ybWF0LldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpLCBSZWFkVGFnKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0LCBkLlJlYWRJbnQzMigpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMi4wLCBkLlJlYWRGbG9hdCgpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoKDEwMSwgd2lyZV9mb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCksIFJlYWRUYWcoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDgrOCwgZC5SZWFkSW50MzIoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEuMCwgZC5SZWFkRG91YmxlKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMDAwLjAsIGQuUmVhZERvdWJsZSgpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShkLkVuZE9mU3RyZWFtKCkpCisKKyAgZGVmIHRlc3RQYXJzZVBhY2tlZEZyb21VbnBhY2tlZChzZWxmKToKKyAgICB1bnBhY2tlZCA9IHVuaXR0ZXN0X3BiMi5UZXN0VW5wYWNrZWRUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbFVucGFja2VkRmllbGRzKHVucGFja2VkKQorICAgIHBhY2tlZCA9IHVuaXR0ZXN0X3BiMi5UZXN0UGFja2VkVHlwZXMoKQorICAgIHNlcmlhbGl6ZWQgPSB1bnBhY2tlZC5TZXJpYWxpemVUb1N0cmluZygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHNlcmlhbGl6ZWQpLAorICAgICAgICBwYWNrZWQuTWVyZ2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKQorICAgIGV4cGVjdGVkID0gdW5pdHRlc3RfcGIyLlRlc3RQYWNrZWRUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbFBhY2tlZEZpZWxkcyhleHBlY3RlZCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGV4cGVjdGVkLCBwYWNrZWQpCisKKyAgZGVmIHRlc3RQYXJzZVVucGFja2VkRnJvbVBhY2tlZChzZWxmKToKKyAgICBwYWNrZWQgPSB1bml0dGVzdF9wYjIuVGVzdFBhY2tlZFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsUGFja2VkRmllbGRzKHBhY2tlZCkKKyAgICB1bnBhY2tlZCA9IHVuaXR0ZXN0X3BiMi5UZXN0VW5wYWNrZWRUeXBlcygpCisgICAgc2VyaWFsaXplZCA9IHBhY2tlZC5TZXJpYWxpemVUb1N0cmluZygpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgbGVuKHNlcmlhbGl6ZWQpLAorICAgICAgICB1bnBhY2tlZC5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpCisgICAgZXhwZWN0ZWQgPSB1bml0dGVzdF9wYjIuVGVzdFVucGFja2VkVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxVbnBhY2tlZEZpZWxkcyhleHBlY3RlZCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKGV4cGVjdGVkLCB1bnBhY2tlZCkKKworICBkZWYgdGVzdEZpZWxkTnVtYmVycyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJCX0ZJRUxEX05VTUJFUiwgMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuT1BUSU9OQUxfSU5UMzJfRklFTERfTlVNQkVSLCAxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5PUFRJT05BTEdST1VQX0ZJRUxEX05VTUJFUiwgMTYpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSLCAxOCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5PUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIsIDIxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIsIDMxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SRVBFQVRFREdST1VQX0ZJRUxEX05VTUJFUiwgNDYpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSLCA0OCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIsIDUxKQorCisgIGRlZiB0ZXN0RXh0ZW5zaW9uRmllbGROdW1iZXJzKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZC5zaW5nbGUubnVtYmVyLCAxMDAwKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZC5TSU5HTEVfRklFTERfTlVNQkVSLCAxMDAwKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RSZXF1aXJlZC5tdWx0aS5udW1iZXIsIDEwMDEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkLk1VTFRJX0ZJRUxEX05VTUJFUiwgMTAwMSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5vcHRpb25hbF9pbnQzMl9leHRlbnNpb24ubnVtYmVyLCAxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLk9QVElPTkFMX0lOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIub3B0aW9uYWxncm91cF9leHRlbnNpb24ubnVtYmVyLCAxNikKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5PUFRJT05BTEdST1VQX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDE2KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbi5udW1iZXIsIDE4KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoCisgICAgICB1bml0dGVzdF9wYjIuT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiwgMTgpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIub3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uLm51bWJlciwgMjEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuT1BUSU9OQUxfTkVTVEVEX0VOVU1fRVhURU5TSU9OX0ZJRUxEX05VTUJFUiwKKyAgICAgIDIxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbi5udW1iZXIsIDMxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlJFUEVBVEVEX0lOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDMxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uLm51bWJlciwgNDYpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuUkVQRUFURURHUk9VUF9FWFRFTlNJT05fRklFTERfTlVNQkVSLCA0NikKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24ubnVtYmVyLCA0OCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgdW5pdHRlc3RfcGIyLlJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsIDQ4KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbi5udW1iZXIsIDUxKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlJFUEVBVEVEX05FU1RFRF9FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIsCisgICAgICA1MSkKKworICBkZWYgdGVzdEluaXRLd2FyZ3Moc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKAorICAgICAgICBvcHRpb25hbF9pbnQzMj0xLAorICAgICAgICBvcHRpb25hbF9zdHJpbmc9J2ZvbycsCisgICAgICAgIG9wdGlvbmFsX2Jvb2w9VHJ1ZSwKKyAgICAgICAgb3B0aW9uYWxfYnl0ZXM9YidiYXInLAorICAgICAgICBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZT11bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UoYmI9MSksCisgICAgICAgIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZT11bml0dGVzdF9wYjIuRm9yZWlnbk1lc3NhZ2UoYz0xKSwKKyAgICAgICAgb3B0aW9uYWxfbmVzdGVkX2VudW09dW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5GT08sCisgICAgICAgIG9wdGlvbmFsX2ZvcmVpZ25fZW51bT11bml0dGVzdF9wYjIuRk9SRUlHTl9GT08sCisgICAgICAgIHJlcGVhdGVkX2ludDMyPVsxLCAyLCAzXSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSXNJbml0aWFsaXplZCgpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfaW50MzInKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX3N0cmluZycpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfYm9vbCcpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5IYXNGaWVsZCgnb3B0aW9uYWxfYnl0ZXMnKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9lbnVtJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9mb3JlaWduX2VudW0nKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLm9wdGlvbmFsX2ludDMyKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ2ZvbycsIHByb3RvLm9wdGlvbmFsX3N0cmluZykKKyAgICBzZWxmLmFzc2VydEVxdWFsKFRydWUsIHByb3RvLm9wdGlvbmFsX2Jvb2wpCisgICAgc2VsZi5hc3NlcnRFcXVhbChiJ2JhcicsIHByb3RvLm9wdGlvbmFsX2J5dGVzKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90by5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UuYykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuRk9PLAorICAgICAgICAgICAgICAgICAgICAgcHJvdG8ub3B0aW9uYWxfbmVzdGVkX2VudW0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuRk9SRUlHTl9GT08sIHByb3RvLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFsxLCAyLCAzXSwgcHJvdG8ucmVwZWF0ZWRfaW50MzIpCisKKyAgZGVmIHRlc3RJbml0QXJnc1Vua25vd25GaWVsZE5hbWUoc2VsZik6CisgICAgZGVmIEluaXRhbGl6ZUVtcHR5TWVzc2FnZVdpdGhFeHRyYUtleXdvcmRBcmcoKToKKyAgICAgIHVudXNlZF9wcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlKHVua25vd249J3Vua25vd24nKQorICAgIHNlbGYuX0NoZWNrUmFpc2VzKFZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgSW5pdGFsaXplRW1wdHlNZXNzYWdlV2l0aEV4dHJhS2V5d29yZEFyZywKKyAgICAgICAgICAgICAgICAgICAgICAnUHJvdG9jb2wgbWVzc2FnZSBoYXMgbm8gInVua25vd24iIGZpZWxkLicpCisKKyAgZGVmIHRlc3RJbml0UmVxdWlyZWRLd2FyZ3Moc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkKGE9MSwgYj0xLCBjPTEpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLklzSW5pdGlhbGl6ZWQoKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ2EnKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ2InKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8uSGFzRmllbGQoJ2MnKSkKKyAgICBzZWxmLmFzc2VydFRydWUobm90IHByb3RvLkhhc0ZpZWxkKCdkdW1teTInKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLmEpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90by5iKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgcHJvdG8uYykKKworICBkZWYgdGVzdEluaXRSZXF1aXJlZEZvcmVpZ25Ld2FyZ3Moc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkRm9yZWlnbigKKyAgICAgICAgb3B0aW9uYWxfbWVzc2FnZT11bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkKGE9MSwgYj0xLCBjPTEpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5Jc0luaXRpYWxpemVkKCkpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLkhhc0ZpZWxkKCdvcHRpb25hbF9tZXNzYWdlJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLm9wdGlvbmFsX21lc3NhZ2UuSXNJbml0aWFsaXplZCgpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5vcHRpb25hbF9tZXNzYWdlLkhhc0ZpZWxkKCdhJykpCisgICAgc2VsZi5hc3NlcnRUcnVlKHByb3RvLm9wdGlvbmFsX21lc3NhZ2UuSGFzRmllbGQoJ2InKSkKKyAgICBzZWxmLmFzc2VydFRydWUocHJvdG8ub3B0aW9uYWxfbWVzc2FnZS5IYXNGaWVsZCgnYycpKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcHJvdG8ub3B0aW9uYWxfbWVzc2FnZS5IYXNGaWVsZCgnZHVtbXkyJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuVGVzdFJlcXVpcmVkKGE9MSwgYj0xLCBjPTEpLAorICAgICAgICAgICAgICAgICAgICAgcHJvdG8ub3B0aW9uYWxfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLm9wdGlvbmFsX21lc3NhZ2UuYSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLm9wdGlvbmFsX21lc3NhZ2UuYikKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEsIHByb3RvLm9wdGlvbmFsX21lc3NhZ2UuYykKKworICBkZWYgdGVzdEluaXRSZXBlYXRlZEt3YXJncyhzZWxmKToKKyAgICBwcm90byA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMocmVwZWF0ZWRfaW50MzI9WzEsIDIsIDNdKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm90by5Jc0luaXRpYWxpemVkKCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBwcm90by5yZXBlYXRlZF9pbnQzMlswXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIHByb3RvLnJlcGVhdGVkX2ludDMyWzFdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgcHJvdG8ucmVwZWF0ZWRfaW50MzJbMl0pCisKKworY2xhc3MgT3B0aW9uc1Rlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiB0ZXN0TWVzc2FnZU9wdGlvbnMoc2VsZik6CisgICAgcHJvdG8gPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldCgpCisgICAgc2VsZi5hc3NlcnRFcXVhbChUcnVlLAorICAgICAgICAgICAgICAgICAgICAgcHJvdG8uREVTQ1JJUFRPUi5HZXRPcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQpCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKEZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgcHJvdG8uREVTQ1JJUFRPUi5HZXRPcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQpCisKKyAgZGVmIHRlc3RQYWNrZWRPcHRpb25zKHNlbGYpOgorICAgIHByb3RvID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgcHJvdG8ub3B0aW9uYWxfaW50MzIgPSAxCisgICAgcHJvdG8ub3B0aW9uYWxfZG91YmxlID0gMy4wCisgICAgZm9yIGZpZWxkX2Rlc2NyaXB0b3IsIF8gaW4gcHJvdG8uTGlzdEZpZWxkcygpOgorICAgICAgc2VsZi5hc3NlcnRFcXVhbChGYWxzZSwgZmllbGRfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkucGFja2VkKQorCisgICAgcHJvdG8gPSB1bml0dGVzdF9wYjIuVGVzdFBhY2tlZFR5cGVzKCkKKyAgICBwcm90by5wYWNrZWRfaW50MzIuYXBwZW5kKDEpCisgICAgcHJvdG8ucGFja2VkX2RvdWJsZS5hcHBlbmQoMy4wKQorICAgIGZvciBmaWVsZF9kZXNjcmlwdG9yLCBfIGluIHByb3RvLkxpc3RGaWVsZHMoKToKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoVHJ1ZSwgZmllbGRfZGVzY3JpcHRvci5HZXRPcHRpb25zKCkucGFja2VkKQorICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZWZsZWN0aW9uLl9GaWVsZERlc2NyaXB0b3IuTEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Rlc2NyaXB0b3IubGFiZWwpCisKKworCitjbGFzcyBDbGFzc0FQSVRlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIEBiYXNldGVzdC51bml0dGVzdC5za2lwSWYoCisgICAgICBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpID09ICdjcHAnIGFuZCBhcGlfaW1wbGVtZW50YXRpb24uVmVyc2lvbigpID09IDIsCisgICAgICAnQysrIGltcGxlbWVudGF0aW9uIHJlcXVpcmVzIGEgY2FsbCB0byBNYWtlRGVzY3JpcHRvcigpJykKKyAgZGVmIHRlc3RNYWtlQ2xhc3NXaXRoTmVzdGVkRGVzY3JpcHRvcihzZWxmKToKKyAgICBsZWFmX2Rlc2MgPSBkZXNjcmlwdG9yLkRlc2NyaXB0b3IoJ2xlYWYnLCAncGFja2FnZS5wYXJlbnQuY2hpbGQubGVhZicsICcnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGU9Tm9uZSwgZmllbGRzPVtdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0ZWRfdHlwZXM9W10sIGVudW1fdHlwZXM9W10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM9W10pCisgICAgY2hpbGRfZGVzYyA9IGRlc2NyaXB0b3IuRGVzY3JpcHRvcignY2hpbGQnLCAncGFja2FnZS5wYXJlbnQuY2hpbGQnLCAnJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZT1Ob25lLCBmaWVsZHM9W10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0ZWRfdHlwZXM9W2xlYWZfZGVzY10sIGVudW1fdHlwZXM9W10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zPVtdKQorICAgIHNpYmxpbmdfZGVzYyA9IGRlc2NyaXB0b3IuRGVzY3JpcHRvcignc2libGluZycsICdwYWNrYWdlLnBhcmVudC5zaWJsaW5nJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJycsIGNvbnRhaW5pbmdfdHlwZT1Ob25lLCBmaWVsZHM9W10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RlZF90eXBlcz1bXSwgZW51bV90eXBlcz1bXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucz1bXSkKKyAgICBwYXJlbnRfZGVzYyA9IGRlc2NyaXB0b3IuRGVzY3JpcHRvcigncGFyZW50JywgJ3BhY2thZ2UucGFyZW50JywgJycsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ190eXBlPU5vbmUsIGZpZWxkcz1bXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0ZWRfdHlwZXM9W2NoaWxkX2Rlc2MsIHNpYmxpbmdfZGVzY10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bV90eXBlcz1bXSwgZXh0ZW5zaW9ucz1bXSkKKyAgICBtZXNzYWdlX2NsYXNzID0gcmVmbGVjdGlvbi5NYWtlQ2xhc3MocGFyZW50X2Rlc2MpCisgICAgc2VsZi5hc3NlcnRJbignY2hpbGQnLCBtZXNzYWdlX2NsYXNzLl9fZGljdF9fKQorICAgIHNlbGYuYXNzZXJ0SW4oJ3NpYmxpbmcnLCBtZXNzYWdlX2NsYXNzLl9fZGljdF9fKQorICAgIHNlbGYuYXNzZXJ0SW4oJ2xlYWYnLCBtZXNzYWdlX2NsYXNzLmNoaWxkLl9fZGljdF9fKQorCisgIGRlZiBfR2V0U2VyaWFsaXplZEZpbGVEZXNjcmlwdG9yKHNlbGYsIG5hbWUpOgorICAgICIiIkdldCBhIHNlcmlhbGl6ZWQgcmVwcmVzZW50YXRpb24gb2YgYSB0ZXN0IEZpbGVEZXNjcmlwdG9yUHJvdG8uCisKKyAgICBBcmdzOgorICAgICAgbmFtZTogQWxsIGNhbGxzIHRvIHRoaXMgbXVzdCB1c2UgYSB1bmlxdWUgbWVzc2FnZSBuYW1lLCB0byBhdm9pZAorICAgICAgICAgIGNvbGxpc2lvbnMgaW4gdGhlIGNwcCBkZXNjcmlwdG9yIHBvb2wuCisgICAgUmV0dXJuczoKKyAgICAgIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNlcmlhbGl6ZWQgZm9ybSBvZiBhIHRlc3QgRmlsZURlc2NyaXB0b3JQcm90by4KKyAgICAiIiIKKyAgICBmaWxlX2Rlc2NyaXB0b3Jfc3RyID0gKAorICAgICAgICAnbWVzc2FnZV90eXBlIHsnCisgICAgICAgICcgIG5hbWU6ICInICsgbmFtZSArICciJworICAgICAgICAnICBmaWVsZCB7JworICAgICAgICAnICAgIG5hbWU6ICJmbGF0IicKKyAgICAgICAgJyAgICBudW1iZXI6IDEnCisgICAgICAgICcgICAgbGFiZWw6IExBQkVMX1JFUEVBVEVEJworICAgICAgICAnICAgIHR5cGU6IFRZUEVfVUlOVDMyJworICAgICAgICAnICB9JworICAgICAgICAnICBmaWVsZCB7JworICAgICAgICAnICAgIG5hbWU6ICJiYXIiJworICAgICAgICAnICAgIG51bWJlcjogMicKKyAgICAgICAgJyAgICBsYWJlbDogTEFCRUxfT1BUSU9OQUwnCisgICAgICAgICcgICAgdHlwZTogVFlQRV9NRVNTQUdFJworICAgICAgICAnICAgIHR5cGVfbmFtZTogIkJhciInCisgICAgICAgICcgIH0nCisgICAgICAgICcgIG5lc3RlZF90eXBlIHsnCisgICAgICAgICcgICAgbmFtZTogIkJhciInCisgICAgICAgICcgICAgZmllbGQgeycKKyAgICAgICAgJyAgICAgIG5hbWU6ICJiYXoiJworICAgICAgICAnICAgICAgbnVtYmVyOiAzJworICAgICAgICAnICAgICAgbGFiZWw6IExBQkVMX09QVElPTkFMJworICAgICAgICAnICAgICAgdHlwZTogVFlQRV9NRVNTQUdFJworICAgICAgICAnICAgICAgdHlwZV9uYW1lOiAiQmF6IicKKyAgICAgICAgJyAgICB9JworICAgICAgICAnICAgIG5lc3RlZF90eXBlIHsnCisgICAgICAgICcgICAgICBuYW1lOiAiQmF6IicKKyAgICAgICAgJyAgICAgIGVudW1fdHlwZSB7JworICAgICAgICAnICAgICAgICBuYW1lOiAiZGVlcF9lbnVtIicKKyAgICAgICAgJyAgICAgICAgdmFsdWUgeycKKyAgICAgICAgJyAgICAgICAgICBuYW1lOiAiVkFMVUVfQSInCisgICAgICAgICcgICAgICAgICAgbnVtYmVyOiAwJworICAgICAgICAnICAgICAgICB9JworICAgICAgICAnICAgICAgfScKKyAgICAgICAgJyAgICAgIGZpZWxkIHsnCisgICAgICAgICcgICAgICAgIG5hbWU6ICJkZWVwIicKKyAgICAgICAgJyAgICAgICAgbnVtYmVyOiA0JworICAgICAgICAnICAgICAgICBsYWJlbDogTEFCRUxfT1BUSU9OQUwnCisgICAgICAgICcgICAgICAgIHR5cGU6IFRZUEVfVUlOVDMyJworICAgICAgICAnICAgICAgfScKKyAgICAgICAgJyAgICB9JworICAgICAgICAnICB9JworICAgICAgICAnfScpCisgICAgZmlsZV9kZXNjcmlwdG9yID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90bygpCisgICAgdGV4dF9mb3JtYXQuTWVyZ2UoZmlsZV9kZXNjcmlwdG9yX3N0ciwgZmlsZV9kZXNjcmlwdG9yKQorICAgIHJldHVybiBmaWxlX2Rlc2NyaXB0b3IuU2VyaWFsaXplVG9TdHJpbmcoKQorCisgIGRlZiB0ZXN0UGFyc2luZ0ZsYXRDbGFzc1dpdGhFeHBsaWNpdENsYXNzRGVjbGFyYXRpb24oc2VsZik6CisgICAgIiIiVGVzdCB0aGF0IHRoZSBnZW5lcmF0ZWQgY2xhc3MgY2FuIHBhcnNlIGEgZmxhdCBtZXNzYWdlLiIiIgorICAgIGZpbGVfZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8oKQorICAgIGZpbGVfZGVzY3JpcHRvci5QYXJzZUZyb21TdHJpbmcoc2VsZi5fR2V0U2VyaWFsaXplZEZpbGVEZXNjcmlwdG9yKCdBJykpCisgICAgbXNnX2Rlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLk1ha2VEZXNjcmlwdG9yKAorICAgICAgICBmaWxlX2Rlc2NyaXB0b3IubWVzc2FnZV90eXBlWzBdKQorCisgICAgY2xhc3MgTWVzc2FnZUNsYXNzKG1lc3NhZ2UuTWVzc2FnZSk6CisgICAgICBfX21ldGFjbGFzc19fID0gcmVmbGVjdGlvbi5HZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlCisgICAgICBERVNDUklQVE9SID0gbXNnX2Rlc2NyaXB0b3IKKyAgICBtc2cgPSBNZXNzYWdlQ2xhc3MoKQorICAgIG1zZ19zdHIgPSAoCisgICAgICAgICdmbGF0OiAwICcKKyAgICAgICAgJ2ZsYXQ6IDEgJworICAgICAgICAnZmxhdDogMiAnKQorICAgIHRleHRfZm9ybWF0Lk1lcmdlKG1zZ19zdHIsIG1zZykKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1zZy5mbGF0LCBbMCwgMSwgMl0pCisKKyAgZGVmIHRlc3RQYXJzaW5nRmxhdENsYXNzKHNlbGYpOgorICAgICIiIlRlc3QgdGhhdCB0aGUgZ2VuZXJhdGVkIGNsYXNzIGNhbiBwYXJzZSBhIGZsYXQgbWVzc2FnZS4iIiIKKyAgICBmaWxlX2Rlc2NyaXB0b3IgPSBkZXNjcmlwdG9yX3BiMi5GaWxlRGVzY3JpcHRvclByb3RvKCkKKyAgICBmaWxlX2Rlc2NyaXB0b3IuUGFyc2VGcm9tU3RyaW5nKHNlbGYuX0dldFNlcmlhbGl6ZWRGaWxlRGVzY3JpcHRvcignQicpKQorICAgIG1zZ19kZXNjcmlwdG9yID0gZGVzY3JpcHRvci5NYWtlRGVzY3JpcHRvcigKKyAgICAgICAgZmlsZV9kZXNjcmlwdG9yLm1lc3NhZ2VfdHlwZVswXSkKKyAgICBtc2dfY2xhc3MgPSByZWZsZWN0aW9uLk1ha2VDbGFzcyhtc2dfZGVzY3JpcHRvcikKKyAgICBtc2cgPSBtc2dfY2xhc3MoKQorICAgIG1zZ19zdHIgPSAoCisgICAgICAgICdmbGF0OiAwICcKKyAgICAgICAgJ2ZsYXQ6IDEgJworICAgICAgICAnZmxhdDogMiAnKQorICAgIHRleHRfZm9ybWF0Lk1lcmdlKG1zZ19zdHIsIG1zZykKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1zZy5mbGF0LCBbMCwgMSwgMl0pCisKKyAgZGVmIHRlc3RQYXJzaW5nTmVzdGVkQ2xhc3Moc2VsZik6CisgICAgIiIiVGVzdCB0aGF0IHRoZSBnZW5lcmF0ZWQgY2xhc3MgY2FuIHBhcnNlIGEgbmVzdGVkIG1lc3NhZ2UuIiIiCisgICAgZmlsZV9kZXNjcmlwdG9yID0gZGVzY3JpcHRvcl9wYjIuRmlsZURlc2NyaXB0b3JQcm90bygpCisgICAgZmlsZV9kZXNjcmlwdG9yLlBhcnNlRnJvbVN0cmluZyhzZWxmLl9HZXRTZXJpYWxpemVkRmlsZURlc2NyaXB0b3IoJ0MnKSkKKyAgICBtc2dfZGVzY3JpcHRvciA9IGRlc2NyaXB0b3IuTWFrZURlc2NyaXB0b3IoCisgICAgICAgIGZpbGVfZGVzY3JpcHRvci5tZXNzYWdlX3R5cGVbMF0pCisgICAgbXNnX2NsYXNzID0gcmVmbGVjdGlvbi5NYWtlQ2xhc3MobXNnX2Rlc2NyaXB0b3IpCisgICAgbXNnID0gbXNnX2NsYXNzKCkKKyAgICBtc2dfc3RyID0gKAorICAgICAgICAnYmFyIHsnCisgICAgICAgICcgIGJheiB7JworICAgICAgICAnICAgIGRlZXA6IDQnCisgICAgICAgICcgIH0nCisgICAgICAgICd9JykKKyAgICB0ZXh0X2Zvcm1hdC5NZXJnZShtc2dfc3RyLCBtc2cpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtc2cuYmFyLmJhei5kZWVwLCA0KQorCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvc2VydmljZV9yZWZsZWN0aW9uX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3NlcnZpY2VfcmVmbGVjdGlvbl90ZXN0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmQwNjZhZTcKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3NlcnZpY2VfcmVmbGVjdGlvbl90ZXN0LnB5CkBAIC0wLDAgKzEsMTM2IEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgZm9yIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC5zZXJ2aWNlX3JlZmxlY3Rpb24uIiIiCisKK19fYXV0aG9yX18gPSAncGV0YXJAZ29vZ2xlLmNvbSAoUGV0YXIgUGV0cm92KScKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgc2VydmljZV9yZWZsZWN0aW9uCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgc2VydmljZQorCisKK2NsYXNzIEZvb1VuaXRUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdFNlcnZpY2Uoc2VsZik6CisgICAgY2xhc3MgTW9ja1JwY0NoYW5uZWwoc2VydmljZS5ScGNDaGFubmVsKToKKyAgICAgIGRlZiBDYWxsTWV0aG9kKHNlbGYsIG1ldGhvZCwgY29udHJvbGxlciwgcmVxdWVzdCwgcmVzcG9uc2UsIGNhbGxiYWNrKToKKyAgICAgICAgc2VsZi5tZXRob2QgPSBtZXRob2QKKyAgICAgICAgc2VsZi5jb250cm9sbGVyID0gY29udHJvbGxlcgorICAgICAgICBzZWxmLnJlcXVlc3QgPSByZXF1ZXN0CisgICAgICAgIGNhbGxiYWNrKHJlc3BvbnNlKQorCisgICAgY2xhc3MgTW9ja1JwY0NvbnRyb2xsZXIoc2VydmljZS5ScGNDb250cm9sbGVyKToKKyAgICAgIGRlZiBTZXRGYWlsZWQoc2VsZiwgbXNnKToKKyAgICAgICAgc2VsZi5mYWlsdXJlX21lc3NhZ2UgPSBtc2cKKworICAgIHNlbGYuY2FsbGJhY2tfcmVzcG9uc2UgPSBOb25lCisKKyAgICBjbGFzcyBNeVNlcnZpY2UodW5pdHRlc3RfcGIyLlRlc3RTZXJ2aWNlKToKKyAgICAgIHBhc3MKKworICAgIHNlbGYuY2FsbGJhY2tfcmVzcG9uc2UgPSBOb25lCisKKyAgICBkZWYgTXlDYWxsYmFjayhyZXNwb25zZSk6CisgICAgICBzZWxmLmNhbGxiYWNrX3Jlc3BvbnNlID0gcmVzcG9uc2UKKworICAgIHJwY19jb250cm9sbGVyID0gTW9ja1JwY0NvbnRyb2xsZXIoKQorICAgIGNoYW5uZWwgPSBNb2NrUnBjQ2hhbm5lbCgpCisgICAgc3J2YyA9IE15U2VydmljZSgpCisgICAgc3J2Yy5Gb28ocnBjX2NvbnRyb2xsZXIsIHVuaXR0ZXN0X3BiMi5Gb29SZXF1ZXN0KCksIE15Q2FsbGJhY2spCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnTWV0aG9kIEZvbyBub3QgaW1wbGVtZW50ZWQuJywKKyAgICAgICAgICAgICAgICAgICAgIHJwY19jb250cm9sbGVyLmZhaWx1cmVfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKE5vbmUsIHNlbGYuY2FsbGJhY2tfcmVzcG9uc2UpCisKKyAgICBycGNfY29udHJvbGxlci5mYWlsdXJlX21lc3NhZ2UgPSBOb25lCisKKyAgICBzZXJ2aWNlX2Rlc2NyaXB0b3IgPSB1bml0dGVzdF9wYjIuVGVzdFNlcnZpY2UuR2V0RGVzY3JpcHRvcigpCisgICAgc3J2Yy5DYWxsTWV0aG9kKHNlcnZpY2VfZGVzY3JpcHRvci5tZXRob2RzWzFdLCBycGNfY29udHJvbGxlciwKKyAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkJhclJlcXVlc3QoKSwgTXlDYWxsYmFjaykKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdNZXRob2QgQmFyIG5vdCBpbXBsZW1lbnRlZC4nLAorICAgICAgICAgICAgICAgICAgICAgcnBjX2NvbnRyb2xsZXIuZmFpbHVyZV9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoTm9uZSwgc2VsZi5jYWxsYmFja19yZXNwb25zZSkKKyAgICAKKyAgICBjbGFzcyBNeVNlcnZpY2VJbXBsKHVuaXR0ZXN0X3BiMi5UZXN0U2VydmljZSk6CisgICAgICBkZWYgRm9vKHNlbGYsIHJwY19jb250cm9sbGVyLCByZXF1ZXN0LCBkb25lKToKKyAgICAgICAgc2VsZi5mb29fY2FsbGVkID0gVHJ1ZQorICAgICAgZGVmIEJhcihzZWxmLCBycGNfY29udHJvbGxlciwgcmVxdWVzdCwgZG9uZSk6CisgICAgICAgIHNlbGYuYmFyX2NhbGxlZCA9IFRydWUKKworICAgIHNydmMgPSBNeVNlcnZpY2VJbXBsKCkKKyAgICBycGNfY29udHJvbGxlci5mYWlsdXJlX21lc3NhZ2UgPSBOb25lCisgICAgc3J2Yy5Gb28ocnBjX2NvbnRyb2xsZXIsIHVuaXR0ZXN0X3BiMi5Gb29SZXF1ZXN0KCksIE15Q2FsbGJhY2spCisgICAgc2VsZi5hc3NlcnRFcXVhbChOb25lLCBycGNfY29udHJvbGxlci5mYWlsdXJlX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChUcnVlLCBzcnZjLmZvb19jYWxsZWQpCisKKyAgICBycGNfY29udHJvbGxlci5mYWlsdXJlX21lc3NhZ2UgPSBOb25lCisgICAgc3J2Yy5DYWxsTWV0aG9kKHNlcnZpY2VfZGVzY3JpcHRvci5tZXRob2RzWzFdLCBycGNfY29udHJvbGxlciwKKyAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkJhclJlcXVlc3QoKSwgTXlDYWxsYmFjaykKKyAgICBzZWxmLmFzc2VydEVxdWFsKE5vbmUsIHJwY19jb250cm9sbGVyLmZhaWx1cmVfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFRydWUsIHNydmMuYmFyX2NhbGxlZCkKKworICBkZWYgdGVzdFNlcnZpY2VTdHViKHNlbGYpOgorICAgIGNsYXNzIE1vY2tScGNDaGFubmVsKHNlcnZpY2UuUnBjQ2hhbm5lbCk6CisgICAgICBkZWYgQ2FsbE1ldGhvZChzZWxmLCBtZXRob2QsIGNvbnRyb2xsZXIsIHJlcXVlc3QsCisgICAgICAgICAgICAgICAgICAgICByZXNwb25zZV9jbGFzcywgY2FsbGJhY2spOgorICAgICAgICBzZWxmLm1ldGhvZCA9IG1ldGhvZAorICAgICAgICBzZWxmLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyCisgICAgICAgIHNlbGYucmVxdWVzdCA9IHJlcXVlc3QKKyAgICAgICAgY2FsbGJhY2socmVzcG9uc2VfY2xhc3MoKSkKKworICAgIHNlbGYuY2FsbGJhY2tfcmVzcG9uc2UgPSBOb25lCisKKyAgICBkZWYgTXlDYWxsYmFjayhyZXNwb25zZSk6CisgICAgICBzZWxmLmNhbGxiYWNrX3Jlc3BvbnNlID0gcmVzcG9uc2UKKworICAgIGNoYW5uZWwgPSBNb2NrUnBjQ2hhbm5lbCgpCisgICAgc3R1YiA9IHVuaXR0ZXN0X3BiMi5UZXN0U2VydmljZV9TdHViKGNoYW5uZWwpCisgICAgcnBjX2NvbnRyb2xsZXIgPSAnY29udHJvbGxlcicKKyAgICByZXF1ZXN0ID0gJ3JlcXVlc3QnCisKKyAgICAjIEdldERlc2NyaXB0b3Igbm93IHN0YXRpYywgc3RpbGwgd29ya3MgYXMgaW5zdGFuY2UgbWV0aG9kIGZvciBjb21wYXRpYmlsaXR5CisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuVGVzdFNlcnZpY2VfU3R1Yi5HZXREZXNjcmlwdG9yKCksCisgICAgICAgICAgICAgICAgICAgICBzdHViLkdldERlc2NyaXB0b3IoKSkKKworICAgICMgSW52b2tlIG1ldGhvZC4KKyAgICBzdHViLkZvbyhycGNfY29udHJvbGxlciwgcmVxdWVzdCwgTXlDYWxsYmFjaykKKworICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc2luc3RhbmNlKHNlbGYuY2FsbGJhY2tfcmVzcG9uc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZvb1Jlc3BvbnNlKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3QsIGNoYW5uZWwucmVxdWVzdCkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHJwY19jb250cm9sbGVyLCBjaGFubmVsLmNvbnRyb2xsZXIpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzdHViLkdldERlc2NyaXB0b3IoKS5tZXRob2RzWzBdLCBjaGFubmVsLm1ldGhvZCkKKworCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvc3ltYm9sX2RhdGFiYXNlX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3N5bWJvbF9kYXRhYmFzZV90ZXN0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3NTcyZDUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3N5bWJvbF9kYXRhYmFzZV90ZXN0LnB5CkBAIC0wLDAgKzEsMTIwIEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiVGVzdHMgZm9yIGdvb2dsZS5wcm90b2J1Zi5zeW1ib2xfZGF0YWJhc2UuIiIiCisKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHN5bWJvbF9kYXRhYmFzZQorCisKK2NsYXNzIFN5bWJvbERhdGFiYXNlVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIF9EYXRhYmFzZShzZWxmKToKKyAgICBkYiA9IHN5bWJvbF9kYXRhYmFzZS5TeW1ib2xEYXRhYmFzZSgpCisgICAgIyBSZWdpc3RlciByZXByZXNlbnRhdGl2ZSB0eXBlcyBmcm9tIHVuaXR0ZXN0X3BiMi4KKyAgICBkYi5SZWdpc3RlckZpbGVEZXNjcmlwdG9yKHVuaXR0ZXN0X3BiMi5ERVNDUklQVE9SKQorICAgIGRiLlJlZ2lzdGVyTWVzc2FnZSh1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKQorICAgIGRiLlJlZ2lzdGVyTWVzc2FnZSh1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCisgICAgZGIuUmVnaXN0ZXJNZXNzYWdlKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCkKKyAgICBkYi5SZWdpc3Rlck1lc3NhZ2UodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwKQorICAgIGRiLlJlZ2lzdGVyRW51bURlc2NyaXB0b3IodW5pdHRlc3RfcGIyLkZvcmVpZ25FbnVtLkRFU0NSSVBUT1IpCisgICAgZGIuUmVnaXN0ZXJFbnVtRGVzY3JpcHRvcih1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uREVTQ1JJUFRPUikKKyAgICByZXR1cm4gZGIKKworICBkZWYgdGVzdEdldFByb3RvdHlwZShzZWxmKToKKyAgICBpbnN0YW5jZSA9IHNlbGYuX0RhdGFiYXNlKCkuR2V0UHJvdG90eXBlKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkRFU0NSSVBUT1IpCisgICAgc2VsZi5hc3NlcnRUcnVlKGluc3RhbmNlIGlzIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMpCisKKyAgZGVmIHRlc3RHZXRNZXNzYWdlcyhzZWxmKToKKyAgICBtZXNzYWdlcyA9IHNlbGYuX0RhdGFiYXNlKCkuR2V0TWVzc2FnZXMoCisgICAgICAgIFsnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvJ10pCisgICAgc2VsZi5hc3NlcnRUcnVlKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzIGlzCisgICAgICAgIG1lc3NhZ2VzWydwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMnXSkKKworICBkZWYgdGVzdEdldFN5bWJvbChzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcywgc2VsZi5fRGF0YWJhc2UoKS5HZXRTeW1ib2woCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJykpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgIHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgc2VsZi5fRGF0YWJhc2UoKS5HZXRTeW1ib2woCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UnKSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLCBzZWxmLl9EYXRhYmFzZSgpLkdldFN5bWJvbCgKKyAgICAgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCcpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAsIHNlbGYuX0RhdGFiYXNlKCkuR2V0U3ltYm9sKAorICAgICAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwJykpCisKKyAgZGVmIHRlc3RFbnVtcyhzZWxmKToKKyAgICAjIENoZWNrIHJlZ2lzdHJhdGlvbiBvZiB0eXBlcyBpbiB0aGUgcG9vbC4KKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtJywKKyAgICAgICAgc2VsZi5fRGF0YWJhc2UoKS5wb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgKKyAgICAgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bScpLmZ1bGxfbmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtJywKKyAgICAgICAgc2VsZi5fRGF0YWJhc2UoKS5wb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgKKyAgICAgICAgICAgICdwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bScpLmZ1bGxfbmFtZSkKKworICBkZWYgdGVzdEZpbmRNZXNzYWdlVHlwZUJ5TmFtZShzZWxmKToKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcycsCisgICAgICAgIHNlbGYuX0RhdGFiYXNlKCkucG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJykuZnVsbF9uYW1lKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UnLAorICAgICAgICBzZWxmLl9EYXRhYmFzZSgpLnBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlJykuZnVsbF9uYW1lKQorCisgIGRlZiB0ZXN0RmluZEZpbmRDb250YWluaW5nU3ltYm9sKHNlbGYpOgorICAgICMgTG9va3VwIGJhc2VkIG9uIGVpdGhlciBlbnVtIG9yIG1lc3NhZ2UuCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoCisgICAgICAgICdnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8nLAorICAgICAgICBzZWxmLl9EYXRhYmFzZSgpLnBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgICAgICAgICAgJ3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtJykubmFtZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscygKKyAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bycsCisgICAgICAgIHNlbGYuX0RhdGFiYXNlKCkucG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgICAgICAgICAncHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJykubmFtZSkKKworICBkZWYgdGVzdEZpbmRGaWxlQnlOYW1lKHNlbGYpOgorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKAorICAgICAgICAnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvJywKKyAgICAgICAgc2VsZi5fRGF0YWJhc2UoKS5wb29sLkZpbmRGaWxlQnlOYW1lKAorICAgICAgICAgICAgJ2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bycpLm5hbWUpCisKKworaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKKyAgYmFzZXRlc3QubWFpbigpCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDg2MGVhCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bwpAQCAtMCwwICsxLDUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIHB5X2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOworCittZXNzYWdlIFRlc3RCYWRJZGVudGlmaWVycyB7CisgIGV4dGVuc2lvbnMgMTAwIHRvIG1heDsKK30KKworLy8gTWFrZSBzdXJlIHRoZXNlIHJlYXNvbmFibGUgZXh0ZW5zaW9uIG5hbWVzIGRvbid0IGNvbmZsaWN0IHdpdGggaW50ZXJuYWwKKy8vIHZhcmlhYmxlcy4KK2V4dGVuZCBUZXN0QmFkSWRlbnRpZmllcnMgeworICBvcHRpb25hbCBzdHJpbmcgbWVzc2FnZSA9IDEwMCBbZGVmYXVsdD0iZm9vIl07CisgIG9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTAxIFtkZWZhdWx0PSJiYXIiXTsKKyAgb3B0aW9uYWwgc3RyaW5nIHJlZmxlY3Rpb24gPSAxMDIgW2RlZmF1bHQ9ImJheiJdOworICBvcHRpb25hbCBzdHJpbmcgc2VydmljZSA9IDEwMyBbZGVmYXVsdD0icXV4Il07Cit9CisKK21lc3NhZ2UgQW5vdGhlck1lc3NhZ2Uge30KK3NlcnZpY2UgQW5vdGhlclNlcnZpY2Uge30KZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGVzdF91dGlsLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90ZXN0X3V0aWwucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZDg0ZTM4MwotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGVzdF91dGlsLnB5CkBAIC0wLDAgKzEsNjc4IEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyIiIlV0aWxpdGllcyBmb3IgUHl0aG9uIHByb3RvMiB0ZXN0cy4KKworVGhpcyBpcyBpbnRlbnRpb25hbGx5IG1vZGVsZWQgb24gQysrIGNvZGUgaW4KKy8vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC4qLgorIiIiCisKK19fYXV0aG9yX18gPSAncm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbiknCisKK2ltcG9ydCBvcy5wYXRoCisKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9pbXBvcnRfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9wYjIKKworIyBUZXN0cyB3aGV0aGVyIHRoZSBnaXZlbiBUZXN0QWxsVHlwZXMgbWVzc2FnZSBpcyBwcm90bzIgb3Igbm90LgorIyBUaGlzIGlzIHVzZWQgdG8gZ2F0ZSBzZXZlcmFsIGZpZWxkcy9mZWF0dXJlcyB0aGF0IG9ubHkgZXhpc3QKKyMgZm9yIHRoZSBwcm90bzIgdmVyc2lvbiBvZiB0aGUgbWVzc2FnZS4KK2RlZiBJc1Byb3RvMihtZXNzYWdlKToKKyAgcmV0dXJuIG1lc3NhZ2UuREVTQ1JJUFRPUi5zeW50YXggPT0gInByb3RvMiIKKworZGVmIFNldEFsbE5vbkxhenlGaWVsZHMobWVzc2FnZSk6CisgICIiIlNldHMgZXZlcnkgbm9uLWxhenkgZmllbGQgaW4gdGhlIG1lc3NhZ2UgdG8gYSB1bmlxdWUgdmFsdWUuCisKKyAgQXJnczoKKyAgICBtZXNzYWdlOiBBIFRlc3RBbGxUeXBlcyBpbnN0YW5jZS4KKyAgIiIiCisKKyAgIworICAjIE9wdGlvbmFsIGZpZWxkcy4KKyAgIworCisgIG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIgICAgPSAxMDEKKyAgbWVzc2FnZS5vcHRpb25hbF9pbnQ2NCAgICA9IDEwMgorICBtZXNzYWdlLm9wdGlvbmFsX3VpbnQzMiAgID0gMTAzCisgIG1lc3NhZ2Uub3B0aW9uYWxfdWludDY0ICAgPSAxMDQKKyAgbWVzc2FnZS5vcHRpb25hbF9zaW50MzIgICA9IDEwNQorICBtZXNzYWdlLm9wdGlvbmFsX3NpbnQ2NCAgID0gMTA2CisgIG1lc3NhZ2Uub3B0aW9uYWxfZml4ZWQzMiAgPSAxMDcKKyAgbWVzc2FnZS5vcHRpb25hbF9maXhlZDY0ICA9IDEwOAorICBtZXNzYWdlLm9wdGlvbmFsX3NmaXhlZDMyID0gMTA5CisgIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkNjQgPSAxMTAKKyAgbWVzc2FnZS5vcHRpb25hbF9mbG9hdCAgICA9IDExMQorICBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSAgID0gMTEyCisgIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCAgICAgPSBUcnVlCisgIG1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nICAgPSB1JzExNScKKyAgbWVzc2FnZS5vcHRpb25hbF9ieXRlcyAgICA9IGInMTE2JworCisgIG1lc3NhZ2Uub3B0aW9uYWxncm91cC5hID0gMTE3CisgIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIgPSAxMTgKKyAgbWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UuYyA9IDExOQorICBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlLmQgPSAxMjAKKyAgbWVzc2FnZS5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UuZSA9IDEyNgorCisgIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX2VudW0gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkJBWgorICBtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0JBWgorICBpZiBJc1Byb3RvMihtZXNzYWdlKToKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9lbnVtID0gdW5pdHRlc3RfaW1wb3J0X3BiMi5JTVBPUlRfQkFaCisKKyAgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmdfcGllY2UgPSB1JzEyNCcKKyAgbWVzc2FnZS5vcHRpb25hbF9jb3JkID0gdScxMjUnCisKKyAgIworICAjIFJlcGVhdGVkIGZpZWxkcy4KKyAgIworCisgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDIwMSkKKyAgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NC5hcHBlbmQoMjAyKQorICBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMi5hcHBlbmQoMjAzKQorICBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NC5hcHBlbmQoMjA0KQorICBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMi5hcHBlbmQoMjA1KQorICBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NC5hcHBlbmQoMjA2KQorICBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzIuYXBwZW5kKDIwNykKKyAgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0LmFwcGVuZCgyMDgpCisgIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIuYXBwZW5kKDIwOSkKKyAgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NC5hcHBlbmQoMjEwKQorICBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0LmFwcGVuZCgyMTEpCisgIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlLmFwcGVuZCgyMTIpCisgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbC5hcHBlbmQoVHJ1ZSkKKyAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKHUnMjE1JykKKyAgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcy5hcHBlbmQoYicyMTYnKQorCisgIG1lc3NhZ2UucmVwZWF0ZWRncm91cC5hZGQoKS5hID0gMjE3CisgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UuYWRkKCkuYmIgPSAyMTgKKyAgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UuYWRkKCkuYyA9IDIxOQorICBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlLmFkZCgpLmQgPSAyMjAKKyAgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2UuYWRkKCkuYmIgPSAyMjcKKworICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtLmFwcGVuZCh1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkJBUikKKyAgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0uYXBwZW5kKHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0JBUikKKyAgaWYgSXNQcm90bzIobWVzc2FnZSk6CisgICAgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bS5hcHBlbmQodW5pdHRlc3RfaW1wb3J0X3BiMi5JTVBPUlRfQkFSKQorCisgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlLmFwcGVuZCh1JzIyNCcpCisgIG1lc3NhZ2UucmVwZWF0ZWRfY29yZC5hcHBlbmQodScyMjUnKQorCisgICMgQWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgzMDEpCisgIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQuYXBwZW5kKDMwMikKKyAgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIuYXBwZW5kKDMwMykKKyAgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQuYXBwZW5kKDMwNCkKKyAgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIuYXBwZW5kKDMwNSkKKyAgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQuYXBwZW5kKDMwNikKKyAgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyLmFwcGVuZCgzMDcpCisgIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NC5hcHBlbmQoMzA4KQorICBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyLmFwcGVuZCgzMDkpCisgIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQuYXBwZW5kKDMxMCkKKyAgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdC5hcHBlbmQoMzExKQorICBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZS5hcHBlbmQoMzEyKQorICBtZXNzYWdlLnJlcGVhdGVkX2Jvb2wuYXBwZW5kKEZhbHNlKQorICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQodSczMTUnKQorICBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzLmFwcGVuZChiJzMxNicpCisKKyAgbWVzc2FnZS5yZXBlYXRlZGdyb3VwLmFkZCgpLmEgPSAzMTcKKyAgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKS5iYiA9IDMxOAorICBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZS5hZGQoKS5jID0gMzE5CisgIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UuYWRkKCkuZCA9IDMyMAorICBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZS5hZGQoKS5iYiA9IDMyNworCisgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0uYXBwZW5kKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuQkFaKQorICBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bS5hcHBlbmQodW5pdHRlc3RfcGIyLkZPUkVJR05fQkFaKQorICBpZiBJc1Byb3RvMihtZXNzYWdlKToKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtLmFwcGVuZCh1bml0dGVzdF9pbXBvcnRfcGIyLklNUE9SVF9CQVopCisKKyAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfcGllY2UuYXBwZW5kKHUnMzI0JykKKyAgbWVzc2FnZS5yZXBlYXRlZF9jb3JkLmFwcGVuZCh1JzMyNScpCisKKyAgIworICAjIEZpZWxkcyB0aGF0IGhhdmUgZGVmYXVsdHMuCisgICMKKworICBpZiBJc1Byb3RvMihtZXNzYWdlKToKKyAgICBtZXNzYWdlLmRlZmF1bHRfaW50MzIgPSA0MDEKKyAgICBtZXNzYWdlLmRlZmF1bHRfaW50NjQgPSA0MDIKKyAgICBtZXNzYWdlLmRlZmF1bHRfdWludDMyID0gNDAzCisgICAgbWVzc2FnZS5kZWZhdWx0X3VpbnQ2NCA9IDQwNAorICAgIG1lc3NhZ2UuZGVmYXVsdF9zaW50MzIgPSA0MDUKKyAgICBtZXNzYWdlLmRlZmF1bHRfc2ludDY0ID0gNDA2CisgICAgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkMzIgPSA0MDcKKyAgICBtZXNzYWdlLmRlZmF1bHRfZml4ZWQ2NCA9IDQwOAorICAgIG1lc3NhZ2UuZGVmYXVsdF9zZml4ZWQzMiA9IDQwOQorICAgIG1lc3NhZ2UuZGVmYXVsdF9zZml4ZWQ2NCA9IDQxMAorICAgIG1lc3NhZ2UuZGVmYXVsdF9mbG9hdCA9IDQxMQorICAgIG1lc3NhZ2UuZGVmYXVsdF9kb3VibGUgPSA0MTIKKyAgICBtZXNzYWdlLmRlZmF1bHRfYm9vbCA9IEZhbHNlCisgICAgbWVzc2FnZS5kZWZhdWx0X3N0cmluZyA9ICc0MTUnCisgICAgbWVzc2FnZS5kZWZhdWx0X2J5dGVzID0gYic0MTYnCisKKyAgICBtZXNzYWdlLmRlZmF1bHRfbmVzdGVkX2VudW0gPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkZPTworICAgIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0gPSB1bml0dGVzdF9wYjIuRk9SRUlHTl9GT08KKyAgICBtZXNzYWdlLmRlZmF1bHRfaW1wb3J0X2VudW0gPSB1bml0dGVzdF9pbXBvcnRfcGIyLklNUE9SVF9GT08KKworICAgIG1lc3NhZ2UuZGVmYXVsdF9zdHJpbmdfcGllY2UgPSAnNDI0JworICAgIG1lc3NhZ2UuZGVmYXVsdF9jb3JkID0gJzQyNScKKworICBtZXNzYWdlLm9uZW9mX3VpbnQzMiA9IDYwMQorICBtZXNzYWdlLm9uZW9mX25lc3RlZF9tZXNzYWdlLmJiID0gNjAyCisgIG1lc3NhZ2Uub25lb2Zfc3RyaW5nID0gJzYwMycKKyAgbWVzc2FnZS5vbmVvZl9ieXRlcyA9IGInNjA0JworCisKK2RlZiBTZXRBbGxGaWVsZHMobWVzc2FnZSk6CisgIFNldEFsbE5vbkxhenlGaWVsZHMobWVzc2FnZSkKKyAgbWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UuYmIgPSAxMjcKKworCitkZWYgU2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlKToKKyAgIiIiU2V0cyBldmVyeSBleHRlbnNpb24gaW4gdGhlIG1lc3NhZ2UgdG8gYSB1bmlxdWUgdmFsdWUuCisKKyAgQXJnczoKKyAgICBtZXNzYWdlOiBBIHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucyBpbnN0YW5jZS4KKyAgIiIiCisKKyAgZXh0ZW5zaW9ucyA9IG1lc3NhZ2UuRXh0ZW5zaW9ucworICBwYjIgPSB1bml0dGVzdF9wYjIKKyAgaW1wb3J0X3BiMiA9IHVuaXR0ZXN0X2ltcG9ydF9wYjIKKworICAjCisgICMgT3B0aW9uYWwgZmllbGRzLgorICAjCisKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXSA9IDEwMQorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9pbnQ2NF9leHRlbnNpb25dID0gMTAyCisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb25dID0gMTAzCisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25dID0gMTA0CisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25dID0gMTA1CisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb25dID0gMTA2CisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uXSA9IDEwNworICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbl0gPSAxMDgKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uXSA9IDEwOQorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb25dID0gMTEwCisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl0gPSAxMTEKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbl0gPSAxMTIKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfYm9vbF9leHRlbnNpb25dID0gVHJ1ZQorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uXSA9IHUnMTE1JworICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9ieXRlc19leHRlbnNpb25dID0gYicxMTYnCisKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxncm91cF9leHRlbnNpb25dLmEgPSAxMTcKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXS5iYiA9IDExOAorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uXS5jID0gMTE5CisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl0uZCA9IDEyMAorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXS5lID0gMTI2CisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25dLmJiID0gMTI3CisKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uXSA9IHBiMi5UZXN0QWxsVHlwZXMuQkFaCisgIGV4dGVuc2lvbnNbcGIyLm9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbl0gPSBwYjIuVGVzdEFsbFR5cGVzLkJBWgorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXSA9IHBiMi5GT1JFSUdOX0JBWgorICBleHRlbnNpb25zW3BiMi5vcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb25dID0gaW1wb3J0X3BiMi5JTVBPUlRfQkFaCisKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl0gPSB1JzEyNCcKKyAgZXh0ZW5zaW9uc1twYjIub3B0aW9uYWxfY29yZF9leHRlbnNpb25dID0gdScxMjUnCisKKyAgIworICAjIFJlcGVhdGVkIGZpZWxkcy4KKyAgIworCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl0uYXBwZW5kKDIwMSkKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uXS5hcHBlbmQoMjAyKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uXS5hcHBlbmQoMjAzKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uXS5hcHBlbmQoMjA0KQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uXS5hcHBlbmQoMjA1KQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uXS5hcHBlbmQoMjA2KQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl0uYXBwZW5kKDIwNykKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25dLmFwcGVuZCgyMDgpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl0uYXBwZW5kKDIwOSkKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uXS5hcHBlbmQoMjEwKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9mbG9hdF9leHRlbnNpb25dLmFwcGVuZCgyMTEpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25dLmFwcGVuZCgyMTIpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uXS5hcHBlbmQoVHJ1ZSkKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl0uYXBwZW5kKHUnMjE1JykKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uXS5hcHBlbmQoYicyMTYnKQorCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uXS5hZGQoKS5hID0gMjE3CisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0uYWRkKCkuYmIgPSAyMTgKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl0uYWRkKCkuYyA9IDIxOQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25dLmFkZCgpLmQgPSAyMjAKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl0uYWRkKCkuYmIgPSAyMjcKKworICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25dLmFwcGVuZChwYjIuVGVzdEFsbFR5cGVzLkJBUikKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl0uYXBwZW5kKHBiMi5GT1JFSUdOX0JBUikKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXS5hcHBlbmQoaW1wb3J0X3BiMi5JTVBPUlRfQkFSKQorCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb25dLmFwcGVuZCh1JzIyNCcpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uXS5hcHBlbmQodScyMjUnKQorCisgICMgQXBwZW5kIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9pbnQzMl9leHRlbnNpb25dLmFwcGVuZCgzMDEpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl0uYXBwZW5kKDMwMikKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl0uYXBwZW5kKDMwMykKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl0uYXBwZW5kKDMwNCkKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl0uYXBwZW5kKDMwNSkKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl0uYXBwZW5kKDMwNikKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25dLmFwcGVuZCgzMDcpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uXS5hcHBlbmQoMzA4KQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25dLmFwcGVuZCgzMDkpCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl0uYXBwZW5kKDMxMCkKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uXS5hcHBlbmQoMzExKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uXS5hcHBlbmQoMzEyKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9ib29sX2V4dGVuc2lvbl0uYXBwZW5kKEZhbHNlKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uXS5hcHBlbmQodSczMTUnKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9ieXRlc19leHRlbnNpb25dLmFwcGVuZChiJzMxNicpCisKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRncm91cF9leHRlbnNpb25dLmFkZCgpLmEgPSAzMTcKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXS5hZGQoKS5iYiA9IDMxOAorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uXS5hZGQoKS5jID0gMzE5CisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl0uYWRkKCkuZCA9IDMyMAorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXS5hZGQoKS5iYiA9IDMyNworCisgIGV4dGVuc2lvbnNbcGIyLnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl0uYXBwZW5kKHBiMi5UZXN0QWxsVHlwZXMuQkFaKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXS5hcHBlbmQocGIyLkZPUkVJR05fQkFaKQorICBleHRlbnNpb25zW3BiMi5yZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25dLmFwcGVuZChpbXBvcnRfcGIyLklNUE9SVF9CQVopCisKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl0uYXBwZW5kKHUnMzI0JykKKyAgZXh0ZW5zaW9uc1twYjIucmVwZWF0ZWRfY29yZF9leHRlbnNpb25dLmFwcGVuZCh1JzMyNScpCisKKyAgIworICAjIEZpZWxkcyB3aXRoIGRlZmF1bHRzLgorICAjCisKKyAgZXh0ZW5zaW9uc1twYjIuZGVmYXVsdF9pbnQzMl9leHRlbnNpb25dID0gNDAxCisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uXSA9IDQwMgorICBleHRlbnNpb25zW3BiMi5kZWZhdWx0X3VpbnQzMl9leHRlbnNpb25dID0gNDAzCisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl0gPSA0MDQKKyAgZXh0ZW5zaW9uc1twYjIuZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uXSA9IDQwNQorICBleHRlbnNpb25zW3BiMi5kZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25dID0gNDA2CisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25dID0gNDA3CisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25dID0gNDA4CisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uXSA9IDQwOQorICBleHRlbnNpb25zW3BiMi5kZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbl0gPSA0MTAKKyAgZXh0ZW5zaW9uc1twYjIuZGVmYXVsdF9mbG9hdF9leHRlbnNpb25dID0gNDExCisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbl0gPSA0MTIKKyAgZXh0ZW5zaW9uc1twYjIuZGVmYXVsdF9ib29sX2V4dGVuc2lvbl0gPSBGYWxzZQorICBleHRlbnNpb25zW3BiMi5kZWZhdWx0X3N0cmluZ19leHRlbnNpb25dID0gdSc0MTUnCisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uXSA9IGInNDE2JworCisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uXSA9IHBiMi5UZXN0QWxsVHlwZXMuRk9PCisgIGV4dGVuc2lvbnNbcGIyLmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl0gPSBwYjIuRk9SRUlHTl9GT08KKyAgZXh0ZW5zaW9uc1twYjIuZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25dID0gaW1wb3J0X3BiMi5JTVBPUlRfRk9PCisKKyAgZXh0ZW5zaW9uc1twYjIuZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uXSA9IHUnNDI0JworICBleHRlbnNpb25zW3BiMi5kZWZhdWx0X2NvcmRfZXh0ZW5zaW9uXSA9ICc0MjUnCisKKyAgZXh0ZW5zaW9uc1twYjIub25lb2ZfdWludDMyX2V4dGVuc2lvbl0gPSA2MDEKKyAgZXh0ZW5zaW9uc1twYjIub25lb2ZfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXS5iYiA9IDYwMgorICBleHRlbnNpb25zW3BiMi5vbmVvZl9zdHJpbmdfZXh0ZW5zaW9uXSA9IHUnNjAzJworICBleHRlbnNpb25zW3BiMi5vbmVvZl9ieXRlc19leHRlbnNpb25dID0gYic2MDQnCisKKworZGVmIFNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMobWVzc2FnZSk6CisgICIiIlNldHMgZXZlcnkgZmllbGQgYW5kIGV4dGVuc2lvbiBpbiB0aGUgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKworICBBcmdzOgorICAgIG1lc3NhZ2U6IEEgdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UuCisgICIiIgorICBtZXNzYWdlLm15X2ludCA9IDEKKyAgbWVzc2FnZS5teV9zdHJpbmcgPSAnZm9vJworICBtZXNzYWdlLm15X2Zsb2F0ID0gMS4wCisgIG1lc3NhZ2UuRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIubXlfZXh0ZW5zaW9uX2ludF0gPSAyMworICBtZXNzYWdlLkV4dGVuc2lvbnNbdW5pdHRlc3RfcGIyLm15X2V4dGVuc2lvbl9zdHJpbmddID0gJ2JhcicKKworCitkZWYgRXhwZWN0QWxsRmllbGRzQW5kRXh0ZW5zaW9uc0luT3JkZXIoc2VyaWFsaXplZCk6CisgICIiIkVuc3VyZXMgdGhhdCBzZXJpYWxpemVkIGlzIHRoZSBzZXJpYWxpemF0aW9uIHdlIGV4cGVjdCBmb3IgYSBtZXNzYWdlCisgIGZpbGxlZCB3aXRoIFNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoKS4gIChTcGVjaWZpY2FsbHksIGVuc3VyZXMgdGhhdCB0aGUKKyAgc2VyaWFsaXphdGlvbiBpcyBpbiBjYW5vbmljYWwsIHRhZy1udW1iZXIgb3JkZXIpLgorICAiIiIKKyAgbXlfZXh0ZW5zaW9uX2ludCA9IHVuaXR0ZXN0X3BiMi5teV9leHRlbnNpb25faW50CisgIG15X2V4dGVuc2lvbl9zdHJpbmcgPSB1bml0dGVzdF9wYjIubXlfZXh0ZW5zaW9uX3N0cmluZworICBleHBlY3RlZF9zdHJpbmdzID0gW10KKyAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0RmllbGRPcmRlcmluZ3MoKQorICBtZXNzYWdlLm15X2ludCA9IDEgICMgRmllbGQgMS4KKyAgZXhwZWN0ZWRfc3RyaW5ncy5hcHBlbmQobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICBtZXNzYWdlLkNsZWFyKCkKKyAgbWVzc2FnZS5FeHRlbnNpb25zW215X2V4dGVuc2lvbl9pbnRdID0gMjMgICMgRmllbGQgNS4KKyAgZXhwZWN0ZWRfc3RyaW5ncy5hcHBlbmQobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICBtZXNzYWdlLkNsZWFyKCkKKyAgbWVzc2FnZS5teV9zdHJpbmcgPSAnZm9vJyAgIyBGaWVsZCAxMS4KKyAgZXhwZWN0ZWRfc3RyaW5ncy5hcHBlbmQobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICBtZXNzYWdlLkNsZWFyKCkKKyAgbWVzc2FnZS5FeHRlbnNpb25zW215X2V4dGVuc2lvbl9zdHJpbmddID0gJ2JhcicgICMgRmllbGQgNTAuCisgIGV4cGVjdGVkX3N0cmluZ3MuYXBwZW5kKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKSkKKyAgbWVzc2FnZS5DbGVhcigpCisgIG1lc3NhZ2UubXlfZmxvYXQgPSAxLjAKKyAgZXhwZWN0ZWRfc3RyaW5ncy5hcHBlbmQobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICBtZXNzYWdlLkNsZWFyKCkKKyAgZXhwZWN0ZWQgPSBiJycuam9pbihleHBlY3RlZF9zdHJpbmdzKQorCisgIGlmIGV4cGVjdGVkICE9IHNlcmlhbGl6ZWQ6CisgICAgcmFpc2UgVmFsdWVFcnJvcignRXhwZWN0ZWQgJXIsIGZvdW5kICVyJyAlIChleHBlY3RlZCwgc2VyaWFsaXplZCkpCisKKworZGVmIEV4cGVjdEFsbEZpZWxkc1NldCh0ZXN0X2Nhc2UsIG1lc3NhZ2UpOgorICAiIiJDaGVjayBhbGwgZmllbGRzIGZvciBjb3JyZWN0IHZhbHVlcyBoYXZlIGFmdGVyIFNldCpGaWVsZHMoKSBpcyBjYWxsZWQuIiIiCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX2ludDMyJykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX2ludDY0JykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX3VpbnQzMicpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF91aW50NjQnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfc2ludDMyJykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX3NpbnQ2NCcpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF9maXhlZDMyJykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX2ZpeGVkNjQnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfc2ZpeGVkMzInKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfc2ZpeGVkNjQnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfZmxvYXQnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfZG91YmxlJykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX2Jvb2wnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfc3RyaW5nJykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX2J5dGVzJykpCisKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxncm91cCcpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZScpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UnKSkKKworICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAuSGFzRmllbGQoJ2EnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5IYXNGaWVsZCgnYmInKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UuSGFzRmllbGQoJ2MnKSkKKyAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZS5IYXNGaWVsZCgnZCcpKQorCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX25lc3RlZF9lbnVtJykpCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX2ZvcmVpZ25fZW51bScpKQorICBpZiBJc1Byb3RvMihtZXNzYWdlKToKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF9pbXBvcnRfZW51bScpKQorCisgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsX3N0cmluZ19waWVjZScpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF9jb3JkJykpCisKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDEwMSwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMikKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDEwMiwgbWVzc2FnZS5vcHRpb25hbF9pbnQ2NCkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDEwMywgbWVzc2FnZS5vcHRpb25hbF91aW50MzIpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgxMDQsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDY0KQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTA1LCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMikKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDEwNiwgbWVzc2FnZS5vcHRpb25hbF9zaW50NjQpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgxMDcsIG1lc3NhZ2Uub3B0aW9uYWxfZml4ZWQzMikKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDEwOCwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDY0KQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTA5LCBtZXNzYWdlLm9wdGlvbmFsX3NmaXhlZDMyKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTEwLCBtZXNzYWdlLm9wdGlvbmFsX3NmaXhlZDY0KQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTExLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0KQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTEyLCBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKFRydWUsIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKCcxMTUnLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZykKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKGInMTE2JywgbWVzc2FnZS5vcHRpb25hbF9ieXRlcykKKworICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTE3LCBtZXNzYWdlLm9wdGlvbmFsZ3JvdXAuYSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDExOCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYikKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDExOSwgbWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UuYykKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDEyMCwgbWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZS5kKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTI2LCBtZXNzYWdlLm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZS5lKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMTI3LCBtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZS5iYikKKworICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5CQVosCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9lbnVtKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLkZPUkVJR05fQkFaLAorICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX2VudW0pCisgIGlmIElzUHJvdG8yKG1lc3NhZ2UpOgorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCh1bml0dGVzdF9pbXBvcnRfcGIyLklNUE9SVF9CQVosCisgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X2VudW0pCisKKyAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9pbnQzMikpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCkpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF91aW50MzIpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMiwgbGVuKG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0KSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMikpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9zaW50NjQpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMiwgbGVuKG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMikpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0KSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyKSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0KSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0KSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSkpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9ib29sKSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX3N0cmluZykpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9ieXRlcykpCisKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkZ3JvdXApKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMiwgbGVuKG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMiwgbGVuKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlKSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtKSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSkpCisgIGlmIElzUHJvdG8yKG1lc3NhZ2UpOgorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bSkpCisKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIsIGxlbihtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19waWVjZSkpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyLCBsZW4obWVzc2FnZS5yZXBlYXRlZF9jb3JkKSkKKworICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjAxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyWzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjAyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0WzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjAzLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMlswXSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIwNCwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjRbMF0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMDUsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyWzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjA2LCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NFswXSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDIwNywgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyWzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjA4LCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRbMF0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMDksIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzJbMF0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMTAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjRbMF0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMTEsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXRbMF0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMTIsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlWzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoVHJ1ZSwgbWVzc2FnZS5yZXBlYXRlZF9ib29sWzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoJzIxNScsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzBdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoYicyMTYnLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzWzBdKQorCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cFswXS5hKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlWzBdLmJiKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZVswXS5jKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMjIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlWzBdLmQpCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlWzBdLmJiKQorCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzLkJBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1bMF0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCh1bml0dGVzdF9wYjIuRk9SRUlHTl9CQVIsCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bVswXSkKKyAgaWYgSXNQcm90bzIobWVzc2FnZSk6CisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKHVuaXR0ZXN0X2ltcG9ydF9wYjIuSU1QT1JUX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bVswXSkKKworICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzAxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyWzFdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzAyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0WzFdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzAzLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMlsxXSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDMwNCwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjRbMV0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgzMDUsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyWzFdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzA2LCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NFsxXSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDMwNywgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyWzFdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzA4LCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRbMV0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgzMDksIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzJbMV0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgzMTAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjRbMV0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgzMTEsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXRbMV0pCisgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCgzMTIsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlWzFdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoRmFsc2UsIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbFsxXSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKCczMTUnLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ1sxXSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKGInMzE2JywgbWVzc2FnZS5yZXBlYXRlZF9ieXRlc1sxXSkKKworICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXBbMV0uYSkKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDMxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVsxXS5iYikKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDMxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VbMV0uYykKKyAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDMyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZVsxXS5kKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoMzI3LCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZVsxXS5iYikKKworICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5CQVosCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtWzFdKQorICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwodW5pdHRlc3RfcGIyLkZPUkVJR05fQkFaLAorICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW1bMV0pCisgIGlmIElzUHJvdG8yKG1lc3NhZ2UpOgorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCh1bml0dGVzdF9pbXBvcnRfcGIyLklNUE9SVF9CQVosCisgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW1bMV0pCisKKyAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlmIElzUHJvdG8yKG1lc3NhZ2UpOgorICAgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ2RlZmF1bHRfaW50MzInKSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdkZWZhdWx0X2ludDY0JykpCisgICAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnZGVmYXVsdF91aW50MzInKSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdkZWZhdWx0X3VpbnQ2NCcpKQorICAgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ2RlZmF1bHRfc2ludDMyJykpCisgICAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnZGVmYXVsdF9zaW50NjQnKSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdkZWZhdWx0X2ZpeGVkMzInKSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdkZWZhdWx0X2ZpeGVkNjQnKSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdkZWZhdWx0X3NmaXhlZDMyJykpCisgICAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnZGVmYXVsdF9zZml4ZWQ2NCcpKQorICAgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ2RlZmF1bHRfZmxvYXQnKSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdkZWZhdWx0X2RvdWJsZScpKQorICAgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ2RlZmF1bHRfYm9vbCcpKQorICAgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ2RlZmF1bHRfc3RyaW5nJykpCisgICAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnZGVmYXVsdF9ieXRlcycpKQorCisgICAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnZGVmYXVsdF9uZXN0ZWRfZW51bScpKQorICAgIHRlc3RfY2FzZS5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ2RlZmF1bHRfZm9yZWlnbl9lbnVtJykpCisgICAgdGVzdF9jYXNlLmFzc2VydFRydWUobWVzc2FnZS5IYXNGaWVsZCgnZGVmYXVsdF9pbXBvcnRfZW51bScpKQorCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDQwMSwgbWVzc2FnZS5kZWZhdWx0X2ludDMyKQorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCg0MDIsIG1lc3NhZ2UuZGVmYXVsdF9pbnQ2NCkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoNDAzLCBtZXNzYWdlLmRlZmF1bHRfdWludDMyKQorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCg0MDQsIG1lc3NhZ2UuZGVmYXVsdF91aW50NjQpCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDQwNSwgbWVzc2FnZS5kZWZhdWx0X3NpbnQzMikKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoNDA2LCBtZXNzYWdlLmRlZmF1bHRfc2ludDY0KQorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCg0MDcsIG1lc3NhZ2UuZGVmYXVsdF9maXhlZDMyKQorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCg0MDgsIG1lc3NhZ2UuZGVmYXVsdF9maXhlZDY0KQorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCg0MDksIG1lc3NhZ2UuZGVmYXVsdF9zZml4ZWQzMikKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoNDEwLCBtZXNzYWdlLmRlZmF1bHRfc2ZpeGVkNjQpCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKDQxMSwgbWVzc2FnZS5kZWZhdWx0X2Zsb2F0KQorICAgIHRlc3RfY2FzZS5hc3NlcnRFcXVhbCg0MTIsIG1lc3NhZ2UuZGVmYXVsdF9kb3VibGUpCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKEZhbHNlLCBtZXNzYWdlLmRlZmF1bHRfYm9vbCkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwoJzQxNScsIG1lc3NhZ2UuZGVmYXVsdF9zdHJpbmcpCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKGInNDE2JywgbWVzc2FnZS5kZWZhdWx0X2J5dGVzKQorCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuRk9PLAorICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRlZmF1bHRfbmVzdGVkX2VudW0pCisgICAgdGVzdF9jYXNlLmFzc2VydEVxdWFsKHVuaXR0ZXN0X3BiMi5GT1JFSUdOX0ZPTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kZWZhdWx0X2ZvcmVpZ25fZW51bSkKKyAgICB0ZXN0X2Nhc2UuYXNzZXJ0RXF1YWwodW5pdHRlc3RfaW1wb3J0X3BiMi5JTVBPUlRfRk9PLAorICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRlZmF1bHRfaW1wb3J0X2VudW0pCisKKworZGVmIEdvbGRlbkZpbGUoZmlsZW5hbWUpOgorICAiIiJGaW5kcyB0aGUgZ2l2ZW4gZ29sZGVuIGZpbGUgYW5kIHJldHVybnMgYSBmaWxlIG9iamVjdCByZXByZXNlbnRpbmcgaXQuIiIiCisKKyAgIyBTZWFyY2ggdXAgdGhlIGRpcmVjdG9yeSB0cmVlIGxvb2tpbmcgZm9yIHRoZSBDKysgcHJvdG9idWYgc291cmNlIGNvZGUuCisgIHBhdGggPSAnLicKKyAgd2hpbGUgb3MucGF0aC5leGlzdHMocGF0aCk6CisgICAgaWYgb3MucGF0aC5leGlzdHMob3MucGF0aC5qb2luKHBhdGgsICdzcmMvZ29vZ2xlL3Byb3RvYnVmJykpOgorICAgICAgIyBGb3VuZCBpdC4gIExvYWQgdGhlIGdvbGRlbiBmaWxlIGZyb20gdGhlIHRlc3RkYXRhIGRpcmVjdG9yeS4KKyAgICAgIGZ1bGxfcGF0aCA9IG9zLnBhdGguam9pbihwYXRoLCAnc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YScsIGZpbGVuYW1lKQorICAgICAgcmV0dXJuIG9wZW4oZnVsbF9wYXRoLCAncmInKQorICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ocGF0aCwgJy4uJykKKworICByYWlzZSBSdW50aW1lRXJyb3IoCisgICAgICAnQ291bGQgbm90IGZpbmQgZ29sZGVuIGZpbGVzLiAgVGhpcyB0ZXN0IG11c3QgYmUgcnVuIGZyb20gd2l0aGluIHRoZSAnCisgICAgICAncHJvdG9idWYgc291cmNlIHBhY2thZ2Ugc28gdGhhdCBpdCBjYW4gcmVhZCB0ZXN0IGRhdGEgZmlsZXMgZnJvbSB0aGUgJworICAgICAgJ0MrKyBzb3VyY2UgdHJlZS4nKQorCisKK2RlZiBHb2xkZW5GaWxlRGF0YShmaWxlbmFtZSk6CisgICIiIkZpbmRzIHRoZSBnaXZlbiBnb2xkZW4gZmlsZSBhbmQgcmV0dXJucyBpdHMgY29udGVudHMuIiIiCisgIHdpdGggR29sZGVuRmlsZShmaWxlbmFtZSkgYXMgZjoKKyAgICByZXR1cm4gZi5yZWFkKCkKKworCitkZWYgU2V0QWxsUGFja2VkRmllbGRzKG1lc3NhZ2UpOgorICAiIiJTZXRzIGV2ZXJ5IGZpZWxkIGluIHRoZSBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorCisgIEFyZ3M6CisgICAgbWVzc2FnZTogQSBUZXN0UGFja2VkVHlwZXMgaW5zdGFuY2UuCisgICIiIgorICBtZXNzYWdlLnBhY2tlZF9pbnQzMi5leHRlbmQoWzYwMSwgNzAxXSkKKyAgbWVzc2FnZS5wYWNrZWRfaW50NjQuZXh0ZW5kKFs2MDIsIDcwMl0pCisgIG1lc3NhZ2UucGFja2VkX3VpbnQzMi5leHRlbmQoWzYwMywgNzAzXSkKKyAgbWVzc2FnZS5wYWNrZWRfdWludDY0LmV4dGVuZChbNjA0LCA3MDRdKQorICBtZXNzYWdlLnBhY2tlZF9zaW50MzIuZXh0ZW5kKFs2MDUsIDcwNV0pCisgIG1lc3NhZ2UucGFja2VkX3NpbnQ2NC5leHRlbmQoWzYwNiwgNzA2XSkKKyAgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMi5leHRlbmQoWzYwNywgNzA3XSkKKyAgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NC5leHRlbmQoWzYwOCwgNzA4XSkKKyAgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIuZXh0ZW5kKFs2MDksIDcwOV0pCisgIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0LmV4dGVuZChbNjEwLCA3MTBdKQorICBtZXNzYWdlLnBhY2tlZF9mbG9hdC5leHRlbmQoWzYxMS4wLCA3MTEuMF0pCisgIG1lc3NhZ2UucGFja2VkX2RvdWJsZS5leHRlbmQoWzYxMi4wLCA3MTIuMF0pCisgIG1lc3NhZ2UucGFja2VkX2Jvb2wuZXh0ZW5kKFtUcnVlLCBGYWxzZV0pCisgIG1lc3NhZ2UucGFja2VkX2VudW0uZXh0ZW5kKFt1bml0dGVzdF9wYjIuRk9SRUlHTl9CQVIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuRk9SRUlHTl9CQVpdKQorCisKK2RlZiBTZXRBbGxQYWNrZWRFeHRlbnNpb25zKG1lc3NhZ2UpOgorICAiIiJTZXRzIGV2ZXJ5IGV4dGVuc2lvbiBpbiB0aGUgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKworICBBcmdzOgorICAgIG1lc3NhZ2U6IEEgdW5pdHRlc3RfcGIyLlRlc3RQYWNrZWRFeHRlbnNpb25zIGluc3RhbmNlLgorICAiIiIKKyAgZXh0ZW5zaW9ucyA9IG1lc3NhZ2UuRXh0ZW5zaW9ucworICBwYjIgPSB1bml0dGVzdF9wYjIKKworICBleHRlbnNpb25zW3BiMi5wYWNrZWRfaW50MzJfZXh0ZW5zaW9uXS5leHRlbmQoWzYwMSwgNzAxXSkKKyAgZXh0ZW5zaW9uc1twYjIucGFja2VkX2ludDY0X2V4dGVuc2lvbl0uZXh0ZW5kKFs2MDIsIDcwMl0pCisgIGV4dGVuc2lvbnNbcGIyLnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uXS5leHRlbmQoWzYwMywgNzAzXSkKKyAgZXh0ZW5zaW9uc1twYjIucGFja2VkX3VpbnQ2NF9leHRlbnNpb25dLmV4dGVuZChbNjA0LCA3MDRdKQorICBleHRlbnNpb25zW3BiMi5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbl0uZXh0ZW5kKFs2MDUsIDcwNV0pCisgIGV4dGVuc2lvbnNbcGIyLnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uXS5leHRlbmQoWzYwNiwgNzA2XSkKKyAgZXh0ZW5zaW9uc1twYjIucGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uXS5leHRlbmQoWzYwNywgNzA3XSkKKyAgZXh0ZW5zaW9uc1twYjIucGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uXS5leHRlbmQoWzYwOCwgNzA4XSkKKyAgZXh0ZW5zaW9uc1twYjIucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl0uZXh0ZW5kKFs2MDksIDcwOV0pCisgIGV4dGVuc2lvbnNbcGIyLnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25dLmV4dGVuZChbNjEwLCA3MTBdKQorICBleHRlbnNpb25zW3BiMi5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uXS5leHRlbmQoWzYxMS4wLCA3MTEuMF0pCisgIGV4dGVuc2lvbnNbcGIyLnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uXS5leHRlbmQoWzYxMi4wLCA3MTIuMF0pCisgIGV4dGVuc2lvbnNbcGIyLnBhY2tlZF9ib29sX2V4dGVuc2lvbl0uZXh0ZW5kKFtUcnVlLCBGYWxzZV0pCisgIGV4dGVuc2lvbnNbcGIyLnBhY2tlZF9lbnVtX2V4dGVuc2lvbl0uZXh0ZW5kKFt1bml0dGVzdF9wYjIuRk9SRUlHTl9CQVIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdF9wYjIuRk9SRUlHTl9CQVpdKQorCisKK2RlZiBTZXRBbGxVbnBhY2tlZEZpZWxkcyhtZXNzYWdlKToKKyAgIiIiU2V0cyBldmVyeSBmaWVsZCBpbiB0aGUgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKworICBBcmdzOgorICAgIG1lc3NhZ2U6IEEgdW5pdHRlc3RfcGIyLlRlc3RVbnBhY2tlZFR5cGVzIGluc3RhbmNlLgorICAiIiIKKyAgbWVzc2FnZS51bnBhY2tlZF9pbnQzMi5leHRlbmQoWzYwMSwgNzAxXSkKKyAgbWVzc2FnZS51bnBhY2tlZF9pbnQ2NC5leHRlbmQoWzYwMiwgNzAyXSkKKyAgbWVzc2FnZS51bnBhY2tlZF91aW50MzIuZXh0ZW5kKFs2MDMsIDcwM10pCisgIG1lc3NhZ2UudW5wYWNrZWRfdWludDY0LmV4dGVuZChbNjA0LCA3MDRdKQorICBtZXNzYWdlLnVucGFja2VkX3NpbnQzMi5leHRlbmQoWzYwNSwgNzA1XSkKKyAgbWVzc2FnZS51bnBhY2tlZF9zaW50NjQuZXh0ZW5kKFs2MDYsIDcwNl0pCisgIG1lc3NhZ2UudW5wYWNrZWRfZml4ZWQzMi5leHRlbmQoWzYwNywgNzA3XSkKKyAgbWVzc2FnZS51bnBhY2tlZF9maXhlZDY0LmV4dGVuZChbNjA4LCA3MDhdKQorICBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDMyLmV4dGVuZChbNjA5LCA3MDldKQorICBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDY0LmV4dGVuZChbNjEwLCA3MTBdKQorICBtZXNzYWdlLnVucGFja2VkX2Zsb2F0LmV4dGVuZChbNjExLjAsIDcxMS4wXSkKKyAgbWVzc2FnZS51bnBhY2tlZF9kb3VibGUuZXh0ZW5kKFs2MTIuMCwgNzEyLjBdKQorICBtZXNzYWdlLnVucGFja2VkX2Jvb2wuZXh0ZW5kKFtUcnVlLCBGYWxzZV0pCisgIG1lc3NhZ2UudW5wYWNrZWRfZW51bS5leHRlbmQoW3VuaXR0ZXN0X3BiMi5GT1JFSUdOX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3RfcGIyLkZPUkVJR05fQkFaXSkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGV4dF9lbmNvZGluZ190ZXN0LnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90ZXh0X2VuY29kaW5nX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZGIwMjIyYgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGV4dF9lbmNvZGluZ190ZXN0LnB5CkBAIC0wLDAgKzEsNjggQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJUZXN0cyBmb3IgZ29vZ2xlLnByb3RvYnVmLnRleHRfZW5jb2RpbmcuIiIiCisKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHRleHRfZW5jb2RpbmcKKworVEVTVF9WQUxVRVMgPSBbCisgICAgKCJmb29cXHJiYXJcXG5iYXpcXHQiLAorICAgICAiZm9vXFxyYmFyXFxuYmF6XFx0IiwKKyAgICAgYiJmb29ccmJhclxuYmF6XHQiKSwKKyAgICAoIlxcJ2Z1bGwgb2YgXFxcInNvdW5kXFxcIiBhbmQgXFxcImZ1cnlcXFwiXFwnIiwKKyAgICAgIlxcJ2Z1bGwgb2YgXFxcInNvdW5kXFxcIiBhbmQgXFxcImZ1cnlcXFwiXFwnIiwKKyAgICAgYiInZnVsbCBvZiBcInNvdW5kXCIgYW5kIFwiZnVyeVwiJyIpLAorICAgICgic2lnbmlcXFxcZnlpbmdcXFxcIG5vdGhpbmdcXFxcIiwKKyAgICAgInNpZ25pXFxcXGZ5aW5nXFxcXCBub3RoaW5nXFxcXCIsCisgICAgIGIic2lnbmlcXGZ5aW5nXFwgbm90aGluZ1xcIiksCisgICAgKCJcXDAxMFxcdFxcblxcMDEzXFwwMTRcXHIiLAorICAgICAiXHgwOFxcdFxcblx4MGJceDBjXFxyIiwKKyAgICAgYiJcMDEwXDAxMVwwMTJcMDEzXDAxNFwwMTUiKV0KKworCitjbGFzcyBUZXh0RW5jb2RpbmdUZXN0Q2FzZShiYXNldGVzdC5UZXN0Q2FzZSk6CisgIGRlZiB0ZXN0Q0VzY2FwZShzZWxmKToKKyAgICBmb3IgZXNjYXBlZCwgZXNjYXBlZF91dGY4LCB1bmVzY2FwZWQgaW4gVEVTVF9WQUxVRVM6CisgICAgICBzZWxmLmFzc2VydEVxdWFscyhlc2NhcGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgdGV4dF9lbmNvZGluZy5DRXNjYXBlKHVuZXNjYXBlZCwgYXNfdXRmOD1GYWxzZSkpCisgICAgICBzZWxmLmFzc2VydEVxdWFscyhlc2NhcGVkX3V0ZjgsCisgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0X2VuY29kaW5nLkNFc2NhcGUodW5lc2NhcGVkLCBhc191dGY4PVRydWUpKQorCisgIGRlZiB0ZXN0Q1VuZXNjYXBlKHNlbGYpOgorICAgIGZvciBlc2NhcGVkLCBlc2NhcGVkX3V0ZjgsIHVuZXNjYXBlZCBpbiBURVNUX1ZBTFVFUzoKKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWxzKHVuZXNjYXBlZCwgdGV4dF9lbmNvZGluZy5DVW5lc2NhcGUoZXNjYXBlZCkpCisgICAgICBzZWxmLmFzc2VydEVxdWFscyh1bmVzY2FwZWQsIHRleHRfZW5jb2RpbmcuQ1VuZXNjYXBlKGVzY2FwZWRfdXRmOCkpCisKKworaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKKyAgYmFzZXRlc3QubWFpbigpCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3RleHRfZm9ybWF0X3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3RleHRfZm9ybWF0X3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uN2Q1ODEzZgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGV4dF9mb3JtYXRfdGVzdC5weQpAQCAtMCwwICsxLDc2OSBAQAorIyEgL3Vzci9iaW4vcHl0aG9uCisjCisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyIiIlRlc3QgZm9yIGdvb2dsZS5wcm90b2J1Zi50ZXh0X2Zvcm1hdC4iIiIKKworX19hdXRob3JfXyA9ICdrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKScKKworaW1wb3J0IHJlCisKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IF9wYXJhbWV0ZXJpemVkCisKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9tc2V0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3BiMgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHVuaXR0ZXN0X3Byb3RvM19hcmVuYV9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBhcGlfaW1wbGVtZW50YXRpb24KK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCB0ZXN0X3V0aWwKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB0ZXh0X2Zvcm1hdAorCisjIEJhc2UgY2xhc3Mgd2l0aCBzb21lIGNvbW1vbiBmdW5jdGlvbmFsaXR5LgorY2xhc3MgVGV4dEZvcm1hdEJhc2UoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiBSZWFkR29sZGVuKHNlbGYsIGdvbGRlbl9maWxlbmFtZSk6CisgICAgd2l0aCB0ZXN0X3V0aWwuR29sZGVuRmlsZShnb2xkZW5fZmlsZW5hbWUpIGFzIGY6CisgICAgICByZXR1cm4gKGYucmVhZGxpbmVzKCkgaWYgc3RyIGlzIGJ5dGVzIGVsc2UgICMgUFkzCisgICAgICAgICAgICAgIFtnb2xkZW5fbGluZS5kZWNvZGUoJ3V0Zi04JykgZm9yIGdvbGRlbl9saW5lIGluIGZdKQorCisgIGRlZiBDb21wYXJlVG9Hb2xkZW5GaWxlKHNlbGYsIHRleHQsIGdvbGRlbl9maWxlbmFtZSk6CisgICAgZ29sZGVuX2xpbmVzID0gc2VsZi5SZWFkR29sZGVuKGdvbGRlbl9maWxlbmFtZSkKKyAgICBzZWxmLmFzc2VydE11bHRpTGluZUVxdWFsKHRleHQsICcnLmpvaW4oZ29sZGVuX2xpbmVzKSkKKworICBkZWYgQ29tcGFyZVRvR29sZGVuVGV4dChzZWxmLCB0ZXh0LCBnb2xkZW5fdGV4dCk6CisgICAgc2VsZi5hc3NlcnRNdWx0aUxpbmVFcXVhbCh0ZXh0LCBnb2xkZW5fdGV4dCkKKworICBkZWYgUmVtb3ZlUmVkdW5kYW50WmVyb3Moc2VsZiwgdGV4dCk6CisgICAgIyBTb21lIHBsYXRmb3JtcyBwcmludCAxZSs1IGFzIDFlKzAwNS4gIFRoaXMgaXMgZmluZSwgYnV0IHdlIG5lZWQgdG8gcmVtb3ZlCisgICAgIyB0aGVzZSB6ZXJvcyBpbiBvcmRlciB0byBtYXRjaCB0aGUgZ29sZGVuIGZpbGUuCisgICAgdGV4dCA9IHRleHQucmVwbGFjZSgnZSswJywnZSsnKS5yZXBsYWNlKCdlKzAnLCdlKycpIFwKKyAgICAgICAgICAgICAgIC5yZXBsYWNlKCdlLTAnLCdlLScpLnJlcGxhY2UoJ2UtMCcsJ2UtJykKKyAgICAjIEZsb2F0aW5nIHBvaW50IGZpZWxkcyBhcmUgcHJpbnRlZCB3aXRoIC4wIHN1ZmZpeCBldmVuIGlmIHRoZXkgYXJlCisgICAgIyBhY3R1YWx5IGludGVnZXIgbnVtYmVycy4KKyAgICB0ZXh0ID0gcmUuY29tcGlsZSgnXC4wJCcsIHJlLk1VTFRJTElORSkuc3ViKCcnLCB0ZXh0KQorICAgIHJldHVybiB0ZXh0CisKKworQF9wYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnMoCisgICAgKHVuaXR0ZXN0X3BiMiksCisgICAgKHVuaXR0ZXN0X3Byb3RvM19hcmVuYV9wYjIpKQorY2xhc3MgVGV4dEZvcm1hdFRlc3QoVGV4dEZvcm1hdEJhc2UpOgorCisgIGRlZiB0ZXN0UHJpbnRFeG90aWMoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQuYXBwZW5kKC05MjIzMzcyMDM2ODU0Nzc1ODA4KQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0LmFwcGVuZCgxODQ0Njc0NDA3MzcwOTU1MTYxNSkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZS5hcHBlbmQoMTIzLjQ1NikKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZS5hcHBlbmQoMS4yM2UyMikKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZS5hcHBlbmQoMS4yM2UtMTgpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKCdcMDAwXDAwMVxhXGJcZlxuXHJcdFx2XFxcJyInKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZCh1J1x1MDBmY1x1YTcxZicpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICBzZWxmLlJlbW92ZVJlZHVuZGFudFplcm9zKHRleHRfZm9ybWF0Lk1lc3NhZ2VUb1N0cmluZyhtZXNzYWdlKSksCisgICAgICAgICdyZXBlYXRlZF9pbnQ2NDogLTkyMjMzNzIwMzY4NTQ3NzU4MDhcbicKKyAgICAgICAgJ3JlcGVhdGVkX3VpbnQ2NDogMTg0NDY3NDQwNzM3MDk1NTE2MTVcbicKKyAgICAgICAgJ3JlcGVhdGVkX2RvdWJsZTogMTIzLjQ1NlxuJworICAgICAgICAncmVwZWF0ZWRfZG91YmxlOiAxLjIzZSsyMlxuJworICAgICAgICAncmVwZWF0ZWRfZG91YmxlOiAxLjIzZS0xOFxuJworICAgICAgICAncmVwZWF0ZWRfc3RyaW5nOicKKyAgICAgICAgJyAiXFwwMDBcXDAwMVxcMDA3XFwwMTBcXDAxNFxcblxcclxcdFxcMDEzXFxcXFxcXCdcXCIiXG4nCisgICAgICAgICdyZXBlYXRlZF9zdHJpbmc6ICJcXDMwM1xcMjc0XFwzNTJcXDIzNFxcMjM3IlxuJykKKworICBkZWYgdGVzdFByaW50RXhvdGljVW5pY29kZVN1YmNsYXNzKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBjbGFzcyBVbmljb2RlU3ViKHVuaWNvZGUpOgorICAgICAgcGFzcworICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZChVbmljb2RlU3ViKHUnXHUwMGZjXHVhNzFmJykpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSksCisgICAgICAgICdyZXBlYXRlZF9zdHJpbmc6ICJcXDMwM1xcMjc0XFwzNTJcXDIzNFxcMjM3IlxuJykKKworICBkZWYgdGVzdFByaW50TmVzdGVkTWVzc2FnZUFzT25lTGluZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbXNnID0gbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5hZGQoKQorICAgIG1zZy5iYiA9IDQyCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSwgYXNfb25lX2xpbmU9VHJ1ZSksCisgICAgICAgICdyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiA0MiB9JykKKworICBkZWYgdGVzdFByaW50UmVwZWF0ZWRGaWVsZHNBc09uZUxpbmUoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIuYXBwZW5kKDEpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMi5hcHBlbmQoMSkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDMyLmFwcGVuZCgzKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZCgnR29vZ2xlJykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQoJ1p1cmljaCcpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSwgYXNfb25lX2xpbmU9VHJ1ZSksCisgICAgICAgICdyZXBlYXRlZF9pbnQzMjogMSByZXBlYXRlZF9pbnQzMjogMSByZXBlYXRlZF9pbnQzMjogMyAnCisgICAgICAgICdyZXBlYXRlZF9zdHJpbmc6ICJHb29nbGUiIHJlcGVhdGVkX3N0cmluZzogIlp1cmljaCInKQorCisgIGRlZiB0ZXN0UHJpbnROZXN0ZWROZXdMaW5lSW5TdHJpbmdBc09uZUxpbmUoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nID0gJ2Fcbm5ld1xubGluZScKKyAgICBzZWxmLkNvbXBhcmVUb0dvbGRlblRleHQoCisgICAgICAgIHRleHRfZm9ybWF0Lk1lc3NhZ2VUb1N0cmluZyhtZXNzYWdlLCBhc19vbmVfbGluZT1UcnVlKSwKKyAgICAgICAgJ29wdGlvbmFsX3N0cmluZzogImFcXG5uZXdcXG5saW5lIicpCisKKyAgZGVmIHRlc3RQcmludEV4b3RpY0FzT25lTGluZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NC5hcHBlbmQoLTkyMjMzNzIwMzY4NTQ3NzU4MDgpCisgICAgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQuYXBwZW5kKDE4NDQ2NzQ0MDczNzA5NTUxNjE1KQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlLmFwcGVuZCgxMjMuNDU2KQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlLmFwcGVuZCgxLjIzZTIyKQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlLmFwcGVuZCgxLjIzZS0xOCkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQoJ1wwMDBcMDAxXGFcYlxmXG5cclx0XHZcXFwnIicpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKHUnXHUwMGZjXHVhNzFmJykKKyAgICBzZWxmLkNvbXBhcmVUb0dvbGRlblRleHQoCisgICAgICAgIHNlbGYuUmVtb3ZlUmVkdW5kYW50WmVyb3MoCisgICAgICAgICAgICB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSwgYXNfb25lX2xpbmU9VHJ1ZSkpLAorICAgICAgICAncmVwZWF0ZWRfaW50NjQ6IC05MjIzMzcyMDM2ODU0Nzc1ODA4JworICAgICAgICAnIHJlcGVhdGVkX3VpbnQ2NDogMTg0NDY3NDQwNzM3MDk1NTE2MTUnCisgICAgICAgICcgcmVwZWF0ZWRfZG91YmxlOiAxMjMuNDU2JworICAgICAgICAnIHJlcGVhdGVkX2RvdWJsZTogMS4yM2UrMjInCisgICAgICAgICcgcmVwZWF0ZWRfZG91YmxlOiAxLjIzZS0xOCcKKyAgICAgICAgJyByZXBlYXRlZF9zdHJpbmc6ICcKKyAgICAgICAgJyJcXDAwMFxcMDAxXFwwMDdcXDAxMFxcMDE0XFxuXFxyXFx0XFwwMTNcXFxcXFxcJ1xcIiInCisgICAgICAgICcgcmVwZWF0ZWRfc3RyaW5nOiAiXFwzMDNcXDI3NFxcMzUyXFwyMzRcXDIzNyInKQorCisgIGRlZiB0ZXN0Um91bmRUcmlwRXhvdGljQXNPbmVMaW5lKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX2ludDY0LmFwcGVuZCgtOTIyMzM3MjAzNjg1NDc3NTgwOCkKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NC5hcHBlbmQoMTg0NDY3NDQwNzM3MDk1NTE2MTUpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUuYXBwZW5kKDEyMy40NTYpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUuYXBwZW5kKDEuMjNlMjIpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUuYXBwZW5kKDEuMjNlLTE4KQorICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nLmFwcGVuZCgnXDAwMFwwMDFcYVxiXGZcblxyXHRcdlxcXCciJykKKyAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZy5hcHBlbmQodSdcdTAwZmNcdWE3MWYnKQorCisgICAgIyBUZXN0IGFzX3V0ZjggPSBGYWxzZS4KKyAgICB3aXJlX3RleHQgPSB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcoCisgICAgICAgIG1lc3NhZ2UsIGFzX29uZV9saW5lPVRydWUsIGFzX3V0Zjg9RmFsc2UpCisgICAgcGFyc2VkX21lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHIgPSB0ZXh0X2Zvcm1hdC5QYXJzZSh3aXJlX3RleHQsIHBhcnNlZF9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0SXMociwgcGFyc2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobWVzc2FnZSwgcGFyc2VkX21lc3NhZ2UpCisKKyAgICAjIFRlc3QgYXNfdXRmOCA9IFRydWUuCisgICAgd2lyZV90ZXh0ID0gdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKAorICAgICAgICBtZXNzYWdlLCBhc19vbmVfbGluZT1UcnVlLCBhc191dGY4PVRydWUpCisgICAgcGFyc2VkX21lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHIgPSB0ZXh0X2Zvcm1hdC5QYXJzZSh3aXJlX3RleHQsIHBhcnNlZF9tZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0SXMociwgcGFyc2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobWVzc2FnZSwgcGFyc2VkX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgJ1xuJXMgIT0gJXMnICUgKG1lc3NhZ2UsIHBhcnNlZF9tZXNzYWdlKSkKKworICBkZWYgdGVzdFByaW50UmF3VXRmOFN0cmluZyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcuYXBwZW5kKHUnXHUwMGZjXHVhNzFmJykKKyAgICB0ZXh0ID0gdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG1lc3NhZ2UsIGFzX3V0Zjg9VHJ1ZSkKKyAgICBzZWxmLkNvbXBhcmVUb0dvbGRlblRleHQodGV4dCwgJ3JlcGVhdGVkX3N0cmluZzogIlwzMDNcMjc0XDM1MlwyMzRcMjM3IlxuJykKKyAgICBwYXJzZWRfbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dF9mb3JtYXQuUGFyc2UodGV4dCwgcGFyc2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobWVzc2FnZSwgcGFyc2VkX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgJ1xuJXMgIT0gJXMnICUgKG1lc3NhZ2UsIHBhcnNlZF9tZXNzYWdlKSkKKworICBkZWYgdGVzdFByaW50RmxvYXRGb3JtYXQoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgICMgQ2hlY2sgdGhhdCBmbG9hdF9mb3JtYXQgYXJndW1lbnQgaXMgcGFzc2VkIHRvIHN1Yi1tZXNzYWdlIGZvcm1hdHRpbmcuCisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLk5lc3RlZFRlc3RBbGxUeXBlcygpCisgICAgIyBXZSB1c2UgMS4yNSBhcyBpdCBpcyBhIHJvdW5kIG51bWJlciBpbiBiaW5hcnkuICBUaGUgcHJvdG8gMzItYml0IGZsb2F0CisgICAgIyB3aWxsIG5vdCBnYWluIGFkZGl0aW9uYWwgaW1wcmVjaXNlIGRpZ2l0cyBhcyBhIDY0LWJpdCBQeXRob24gZmxvYXQgYW5kCisgICAgIyBzaG93IHVwIGluIGl0cyBzdHIuICAzMi1iaXQgMS4yIGlzIG5vaXN5IHdoZW4gZXh0ZW5kZWQgdG8gNjQtYml0OgorICAgICMgID4+PiBzdHJ1Y3QudW5wYWNrKCdmJywgc3RydWN0LnBhY2soJ2YnLCAxLjIpKVswXQorICAgICMgIDEuMjAwMDAwMDQ3NjgzNzE1OAorICAgICMgID4+PiBzdHJ1Y3QudW5wYWNrKCdmJywgc3RydWN0LnBhY2soJ2YnLCAxLjI1KSlbMF0KKyAgICAjICAxLjI1CisgICAgbWVzc2FnZS5wYXlsb2FkLm9wdGlvbmFsX2Zsb2F0ID0gMS4yNQorICAgICMgQ2hlY2sgcm91bmRpbmcgYXQgMTUgc2lnbmlmaWNhbnQgZGlnaXRzCisgICAgbWVzc2FnZS5wYXlsb2FkLm9wdGlvbmFsX2RvdWJsZSA9IC0uMDAwMDAzNDU2Nzg5MDEyMzQ1Njc4CisgICAgIyBDaGVjayBubyBkZWNpbWFsIHBvaW50LgorICAgIG1lc3NhZ2UucGF5bG9hZC5yZXBlYXRlZF9mbG9hdC5hcHBlbmQoLTU2NDIpCisgICAgIyBDaGVjayBubyB0cmFpbGluZyB6ZXJvcy4KKyAgICBtZXNzYWdlLnBheWxvYWQucmVwZWF0ZWRfZG91YmxlLmFwcGVuZCguMDAwMDc4OTAwKQorICAgIGZvcm1hdHRlZF9maWVsZHMgPSBbJ29wdGlvbmFsX2Zsb2F0OiAxLjI1JywKKyAgICAgICAgICAgICAgICAgICAgICAgICdvcHRpb25hbF9kb3VibGU6IC0zLjQ1Njc4OTAxMjM0NTY4ZS02JywKKyAgICAgICAgICAgICAgICAgICAgICAgICdyZXBlYXRlZF9mbG9hdDogLTU2NDInLAorICAgICAgICAgICAgICAgICAgICAgICAgJ3JlcGVhdGVkX2RvdWJsZTogNy44OWUtNSddCisgICAgdGV4dF9tZXNzYWdlID0gdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG1lc3NhZ2UsIGZsb2F0X2Zvcm1hdD0nLjE1ZycpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICBzZWxmLlJlbW92ZVJlZHVuZGFudFplcm9zKHRleHRfbWVzc2FnZSksCisgICAgICAgICdwYXlsb2FkIHt7XG4gIHt9XG4gIHt9XG4gIHt9XG4gIHt9XG59fVxuJy5mb3JtYXQoKmZvcm1hdHRlZF9maWVsZHMpKQorICAgICMgYXNfb25lX2xpbmU9VHJ1ZSBpcyBhIHNlcGFyYXRlIGNvZGUgYnJhbmNoIHdoZXJlIGZsb2F0X2Zvcm1hdCBpcyBwYXNzZWQuCisgICAgdGV4dF9tZXNzYWdlID0gdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG1lc3NhZ2UsIGFzX29uZV9saW5lPVRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0X2Zvcm1hdD0nLjE1ZycpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICBzZWxmLlJlbW92ZVJlZHVuZGFudFplcm9zKHRleHRfbWVzc2FnZSksCisgICAgICAgICdwYXlsb2FkIHt7IHt9IHt9IHt9IHt9IH19Jy5mb3JtYXQoKmZvcm1hdHRlZF9maWVsZHMpKQorCisgIGRlZiB0ZXN0TWVzc2FnZVRvU3RyaW5nKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuRm9yZWlnbk1lc3NhZ2UoKQorICAgIG1lc3NhZ2UuYyA9IDEyMworICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ2M6IDEyM1xuJywgc3RyKG1lc3NhZ2UpKQorCisgIGRlZiB0ZXN0UGFyc2VBbGxGaWVsZHMoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMobWVzc2FnZSkKKyAgICBhc2NpaV90ZXh0ID0gdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG1lc3NhZ2UpCisKKyAgICBwYXJzZWRfbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dF9mb3JtYXQuUGFyc2UoYXNjaWlfdGV4dCwgcGFyc2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChtZXNzYWdlLCBwYXJzZWRfbWVzc2FnZSkKKyAgICBpZiBtZXNzYWdlX21vZHVsZSBpcyB1bml0dGVzdF9wYjI6CisgICAgICB0ZXN0X3V0aWwuRXhwZWN0QWxsRmllbGRzU2V0KHNlbGYsIG1lc3NhZ2UpCisKKyAgZGVmIHRlc3RQYXJzZUV4b3RpYyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICgncmVwZWF0ZWRfaW50NjQ6IC05MjIzMzcyMDM2ODU0Nzc1ODA4XG4nCisgICAgICAgICAgICAncmVwZWF0ZWRfdWludDY0OiAxODQ0Njc0NDA3MzcwOTU1MTYxNVxuJworICAgICAgICAgICAgJ3JlcGVhdGVkX2RvdWJsZTogMTIzLjQ1NlxuJworICAgICAgICAgICAgJ3JlcGVhdGVkX2RvdWJsZTogMS4yM2UrMjJcbicKKyAgICAgICAgICAgICdyZXBlYXRlZF9kb3VibGU6IDEuMjNlLTE4XG4nCisgICAgICAgICAgICAncmVwZWF0ZWRfc3RyaW5nOiBcbicKKyAgICAgICAgICAgICciXFwwMDBcXDAwMVxcMDA3XFwwMTBcXDAxNFxcblxcclxcdFxcMDEzXFxcXFxcXCdcXCIiXG4nCisgICAgICAgICAgICAncmVwZWF0ZWRfc3RyaW5nOiAiZm9vIiBcJ2NvcmdlXCcgImdyYXVsdCJcbicKKyAgICAgICAgICAgICdyZXBlYXRlZF9zdHJpbmc6ICJcXDMwM1xcMjc0XFwzNTJcXDIzNFxcMjM3IlxuJworICAgICAgICAgICAgJ3JlcGVhdGVkX3N0cmluZzogIlxceGMzXFx4YmMiXG4nCisgICAgICAgICAgICAncmVwZWF0ZWRfc3RyaW5nOiAiXHhjM1x4YmMiXG4nKQorICAgIHRleHRfZm9ybWF0LlBhcnNlKHRleHQsIG1lc3NhZ2UpCisKKyAgICBzZWxmLmFzc2VydEVxdWFsKC05MjIzMzcyMDM2ODU0Nzc1ODA4LCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0WzBdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTg0NDY3NDQwNzM3MDk1NTE2MTUsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0WzBdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTIzLjQ1NiwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVbMF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLjIzZTIyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZVsxXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDEuMjNlLTE4LCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZVsyXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKAorICAgICAgICAnXDAwMFwwMDFcYVxiXGZcblxyXHRcdlxcXCciJywgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbMF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgnZm9vY29yZ2VncmF1bHQnLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ1sxXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHUnXHUwMGZjXHVhNzFmJywgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbMl0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1J1x1MDBmYycsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzNdKQorCisgIGRlZiB0ZXN0UGFyc2VUcmFpbGluZ0NvbW1hcyhzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICgncmVwZWF0ZWRfaW50NjQ6IDEwMDtcbicKKyAgICAgICAgICAgICdyZXBlYXRlZF9pbnQ2NDogMjAwO1xuJworICAgICAgICAgICAgJ3JlcGVhdGVkX2ludDY0OiAzMDAsXG4nCisgICAgICAgICAgICAncmVwZWF0ZWRfc3RyaW5nOiAib25lIixcbicKKyAgICAgICAgICAgICdyZXBlYXRlZF9zdHJpbmc6ICJ0d28iO1xuJykKKyAgICB0ZXh0X2Zvcm1hdC5QYXJzZSh0ZXh0LCBtZXNzYWdlKQorCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxMDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjRbMF0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyMDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjRbMV0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCgzMDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjRbMl0pCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1J29uZScsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzBdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwodSd0d28nLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ1sxXSkKKworICBkZWYgdGVzdFBhcnNlRW1wdHlUZXh0KHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXh0ID0gJycKKyAgICB0ZXh0X2Zvcm1hdC5QYXJzZSh0ZXh0LCBtZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpLCBtZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VJbnZhbGlkVXRmOChzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICdyZXBlYXRlZF9zdHJpbmc6ICJcXHhjM1xceGMzIicKKyAgICBzZWxmLmFzc2VydFJhaXNlcyh0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLCB0ZXh0X2Zvcm1hdC5QYXJzZSwgdGV4dCwgbWVzc2FnZSkKKworICBkZWYgdGVzdFBhcnNlU2luZ2xlV29yZChzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICdmb28nCisgICAgc2VsZi5hc3NlcnRSYWlzZXNSZWdleHAoCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlRXJyb3IsCisgICAgICAgIChyJzE6MSA6IE1lc3NhZ2UgdHlwZSAiXHcrLlRlc3RBbGxUeXBlcyIgaGFzIG5vIGZpZWxkIG5hbWVkICcKKyAgICAgICAgIHInImZvbyIuJyksCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlLCB0ZXh0LCBtZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VVbmtub3duRmllbGQoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHRleHQgPSAndW5rbm93bl9maWVsZDogOFxuJworICAgIHNlbGYuYXNzZXJ0UmFpc2VzUmVnZXhwKAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLAorICAgICAgICAocicxOjEgOiBNZXNzYWdlIHR5cGUgIlx3Ky5UZXN0QWxsVHlwZXMiIGhhcyBubyBmaWVsZCBuYW1lZCAnCisgICAgICAgICByJyJ1bmtub3duX2ZpZWxkIi4nKSwKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2UsIHRleHQsIG1lc3NhZ2UpCisKKyAgZGVmIHRlc3RQYXJzZUdyb3VwTm90Q2xvc2VkKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXh0ID0gJ1JlcGVhdGVkR3JvdXA6IDwnCisgICAgc2VsZi5hc3NlcnRSYWlzZXNXaXRoTGl0ZXJhbE1hdGNoKAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLCAnMToxNiA6IEV4cGVjdGVkICI+Ii4nLAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZSwgdGV4dCwgbWVzc2FnZSkKKworICAgIHRleHQgPSAnUmVwZWF0ZWRHcm91cDogeycKKyAgICBzZWxmLmFzc2VydFJhaXNlc1dpdGhMaXRlcmFsTWF0Y2goCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlRXJyb3IsICcxOjE2IDogRXhwZWN0ZWQgIn0iLicsCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlLCB0ZXh0LCBtZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VFbXB0eUdyb3VwKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXh0ID0gJ09wdGlvbmFsR3JvdXA6IHt9JworICAgIHRleHRfZm9ybWF0LlBhcnNlKHRleHQsIG1lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRUcnVlKG1lc3NhZ2UuSGFzRmllbGQoJ29wdGlvbmFsZ3JvdXAnKSkKKworICAgIG1lc3NhZ2UuQ2xlYXIoKQorCisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICdPcHRpb25hbEdyb3VwOiA8PicKKyAgICB0ZXh0X2Zvcm1hdC5QYXJzZSh0ZXh0LCBtZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0VHJ1ZShtZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbGdyb3VwJykpCisKKyAgZGVmIHRlc3RQYXJzZUJhZEVudW1WYWx1ZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICdvcHRpb25hbF9uZXN0ZWRfZW51bTogQkFSUicKKyAgICBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4cCgKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2VFcnJvciwKKyAgICAgICAgKHInMToyMyA6IEVudW0gdHlwZSAiXHcrLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIiAnCisgICAgICAgICByJ2hhcyBubyB2YWx1ZSBuYW1lZCBCQVJSLicpLAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZSwgdGV4dCwgbWVzc2FnZSkKKworICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHRleHQgPSAnb3B0aW9uYWxfbmVzdGVkX2VudW06IDEwMCcKKyAgICBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4cCgKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2VFcnJvciwKKyAgICAgICAgKHInMToyMyA6IEVudW0gdHlwZSAiXHcrLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIiAnCisgICAgICAgICByJ2hhcyBubyB2YWx1ZSB3aXRoIG51bWJlciAxMDAuJyksCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlLCB0ZXh0LCBtZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VCYWRJbnRWYWx1ZShzZWxmLCBtZXNzYWdlX21vZHVsZSk6CisgICAgbWVzc2FnZSA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICdvcHRpb25hbF9pbnQzMjogYm9yaycKKyAgICBzZWxmLmFzc2VydFJhaXNlc1dpdGhMaXRlcmFsTWF0Y2goCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlRXJyb3IsCisgICAgICAgICgnMToxNyA6IENvdWxkblwndCBwYXJzZSBpbnRlZ2VyOiBib3JrJyksCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlLCB0ZXh0LCBtZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VTdHJpbmdGaWVsZFVuZXNjYXBlKHNlbGYsIG1lc3NhZ2VfbW9kdWxlKToKKyAgICBtZXNzYWdlID0gbWVzc2FnZV9tb2R1bGUuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXh0ID0gcicnJ3JlcGVhdGVkX3N0cmluZzogIlx4Zlx4NjIiCisgICAgICAgICAgICAgICByZXBlYXRlZF9zdHJpbmc6ICJcXHhmXFx4NjIiCisgICAgICAgICAgICAgICByZXBlYXRlZF9zdHJpbmc6ICJcXFx4ZlxcXHg2MiIKKyAgICAgICAgICAgICAgIHJlcGVhdGVkX3N0cmluZzogIlxcXFx4ZlxcXFx4NjIiCisgICAgICAgICAgICAgICByZXBlYXRlZF9zdHJpbmc6ICJcXFxcXHhmXFxcXFx4NjIiCisgICAgICAgICAgICAgICByZXBlYXRlZF9zdHJpbmc6ICJceDVjeDIwIicnJworICAgIHRleHRfZm9ybWF0LlBhcnNlKHRleHQsIG1lc3NhZ2UpCisKKyAgICBTTEFTSCA9ICdcXCcKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdceDBmYicsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzBdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoU0xBU0ggKyAneGYnICsgU0xBU0ggKyAneDYyJywgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbMV0pCisgICAgc2VsZi5hc3NlcnRFcXVhbChTTEFTSCArICdceDBmJyArIFNMQVNIICsgJ2InLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ1syXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKFNMQVNIICsgU0xBU0ggKyAneGYnICsgU0xBU0ggKyBTTEFTSCArICd4NjInLAorICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbM10pCisgICAgc2VsZi5hc3NlcnRFcXVhbChTTEFTSCArIFNMQVNIICsgJ1x4MGYnICsgU0xBU0ggKyBTTEFTSCArICdiJywKKyAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nWzRdKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoU0xBU0ggKyAneDIwJywgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdbNV0pCisKKyAgZGVmIHRlc3RNZXJnZUR1cGxpY2F0ZVNjYWxhcnMoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHRleHQgPSAoJ29wdGlvbmFsX2ludDMyOiA0MiAnCisgICAgICAgICAgICAnb3B0aW9uYWxfaW50MzI6IDY3JykKKyAgICByID0gdGV4dF9mb3JtYXQuTWVyZ2UodGV4dCwgbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydElzKHIsIG1lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg2NywgbWVzc2FnZS5vcHRpb25hbF9pbnQzMikKKworICBkZWYgdGVzdE1lcmdlRHVwbGljYXRlTmVzdGVkTWVzc2FnZVNjYWxhcnMoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG1lc3NhZ2UgPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIHRleHQgPSAoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsgYmI6IDEgfSAnCisgICAgICAgICAgICAnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeyBiYjogMiB9JykKKyAgICByID0gdGV4dF9mb3JtYXQuTWVyZ2UodGV4dCwgbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydFRydWUociBpcyBtZXNzYWdlKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMiwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYikKKworICBkZWYgdGVzdFBhcnNlT25lb2Yoc2VsZiwgbWVzc2FnZV9tb2R1bGUpOgorICAgIG0gPSBtZXNzYWdlX21vZHVsZS5UZXN0QWxsVHlwZXMoKQorICAgIG0ub25lb2ZfdWludDMyID0gMTEKKyAgICBtMiA9IG1lc3NhZ2VfbW9kdWxlLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dF9mb3JtYXQuUGFyc2UodGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG0pLCBtMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKCdvbmVvZl91aW50MzInLCBtMi5XaGljaE9uZW9mKCdvbmVvZl9maWVsZCcpKQorCisKKyMgVGhlc2UgYXJlIHRlc3RzIHRoYXQgYXJlbid0IGZ1bmRhbWVudGFsbHkgc3BlY2lmaWMgdG8gcHJvdG8yLCBidXQgYXJlIGF0CisjIHRoZSBtb21lbnQgYmVjYXVzZSBvZiBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBwcm90bzIgYW5kIHByb3RvMyB0ZXN0IHNjaGVtYXMuCisjIElkZWFsbHkgdGhlIHNjaGVtYXMgd291bGQgYmUgbWFkZSBtb3JlIHNpbWlsYXIgc28gdGhlc2UgdGVzdHMgY291bGQgcGFzcy4KK2NsYXNzIE9ubHlXb3Jrc1dpdGhQcm90bzJSaWdodE5vd1Rlc3RzKFRleHRGb3JtYXRCYXNlKToKKworICBkZWYgdGVzdFBhcnNlR29sZGVuKHNlbGYpOgorICAgIGdvbGRlbl90ZXh0ID0gJ1xuJy5qb2luKHNlbGYuUmVhZEdvbGRlbigndGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQnKSkKKyAgICBwYXJzZWRfbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHIgPSB0ZXh0X2Zvcm1hdC5QYXJzZShnb2xkZW5fdGV4dCwgcGFyc2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRJcyhyLCBwYXJzZWRfbWVzc2FnZSkKKworICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRmllbGRzKG1lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobWVzc2FnZSwgcGFyc2VkX21lc3NhZ2UpCisKKyAgZGVmIHRlc3RQcmludEFsbEZpZWxkcyhzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbEZpZWxkcyhtZXNzYWdlKQorICAgIHNlbGYuQ29tcGFyZVRvR29sZGVuRmlsZSgKKyAgICAgICAgc2VsZi5SZW1vdmVSZWR1bmRhbnRaZXJvcyh0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSkpLAorICAgICAgICAndGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9vbmVvZl9pbXBsZW1lbnRlZC50eHQnKQorCisgIGRlZiB0ZXN0UHJpbnRBbGxGaWVsZHNQb2ludHkoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMobWVzc2FnZSkKKyAgICBzZWxmLkNvbXBhcmVUb0dvbGRlbkZpbGUoCisgICAgICAgIHNlbGYuUmVtb3ZlUmVkdW5kYW50WmVyb3MoCisgICAgICAgICAgICB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSwgcG9pbnR5X2JyYWNrZXRzPVRydWUpKSwKKyAgICAgICAgJ3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfcG9pbnR5X29uZW9mLnR4dCcpCisKKyAgZGVmIHRlc3RQcmludEluSW5kZXhPcmRlcihzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RGaWVsZE9yZGVyaW5ncygpCisgICAgbWVzc2FnZS5teV9zdHJpbmcgPSAnMTE1JworICAgIG1lc3NhZ2UubXlfaW50ID0gMTAxCisgICAgbWVzc2FnZS5teV9mbG9hdCA9IDExMQorICAgIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2Uub28gPSAwCisgICAgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYiA9IDEKKyAgICBzZWxmLkNvbXBhcmVUb0dvbGRlblRleHQoCisgICAgICAgIHNlbGYuUmVtb3ZlUmVkdW5kYW50WmVyb3ModGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKAorICAgICAgICAgICAgbWVzc2FnZSwgdXNlX2luZGV4X29yZGVyPVRydWUpKSwKKyAgICAgICAgJ215X3N0cmluZzogXCIxMTVcIlxubXlfaW50OiAxMDFcbm15X2Zsb2F0OiAxMTFcbicKKyAgICAgICAgJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHtcbiAgb286IDBcbiAgYmI6IDFcbn1cbicpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5UZXh0KAorICAgICAgICBzZWxmLlJlbW92ZVJlZHVuZGFudFplcm9zKHRleHRfZm9ybWF0Lk1lc3NhZ2VUb1N0cmluZygKKyAgICAgICAgICAgIG1lc3NhZ2UpKSwKKyAgICAgICAgJ215X2ludDogMTAxXG5teV9zdHJpbmc6IFwiMTE1XCJcbm15X2Zsb2F0OiAxMTFcbicKKyAgICAgICAgJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHtcbiAgYmI6IDFcbiAgb286IDBcbn1cbicpCisKKyAgZGVmIHRlc3RNZXJnZUxpbmVzR29sZGVuKHNlbGYpOgorICAgIG9wZW5lZCA9IHNlbGYuUmVhZEdvbGRlbigndGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQnKQorICAgIHBhcnNlZF9tZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgciA9IHRleHRfZm9ybWF0Lk1lcmdlTGluZXMob3BlbmVkLCBwYXJzZWRfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydElzKHIsIHBhcnNlZF9tZXNzYWdlKQorCisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMobWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UsIHBhcnNlZF9tZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VMaW5lc0dvbGRlbihzZWxmKToKKyAgICBvcGVuZWQgPSBzZWxmLlJlYWRHb2xkZW4oJ3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0JykKKyAgICBwYXJzZWRfbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHIgPSB0ZXh0X2Zvcm1hdC5QYXJzZUxpbmVzKG9wZW5lZCwgcGFyc2VkX21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRJcyhyLCBwYXJzZWRfbWVzc2FnZSkKKworICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRmllbGRzKG1lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbHMobWVzc2FnZSwgcGFyc2VkX21lc3NhZ2UpCisKKworIyBUZXN0cyBvZiBwcm90bzItb25seSBmZWF0dXJlcyAoTWVzc2FnZVNldCBhbmQgZXh0ZW5zaW9ucykuCitjbGFzcyBQcm90bzJUZXN0cyhUZXh0Rm9ybWF0QmFzZSk6CisKKyAgZGVmIHRlc3RQcmludE1lc3NhZ2VTZXQoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKCkKKyAgICBleHQxID0gdW5pdHRlc3RfbXNldF9wYjIuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2Vfc2V0X2V4dGVuc2lvbgorICAgIGV4dDIgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIubWVzc2FnZV9zZXRfZXh0ZW5zaW9uCisgICAgbWVzc2FnZS5tZXNzYWdlX3NldC5FeHRlbnNpb25zW2V4dDFdLmkgPSAyMworICAgIG1lc3NhZ2UubWVzc2FnZV9zZXQuRXh0ZW5zaW9uc1tleHQyXS5zdHIgPSAnZm9vJworICAgIHNlbGYuQ29tcGFyZVRvR29sZGVuVGV4dCgKKyAgICAgICAgdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG1lc3NhZ2UpLAorICAgICAgICAnbWVzc2FnZV9zZXQge1xuJworICAgICAgICAnICBbcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xXSB7XG4nCisgICAgICAgICcgICAgaTogMjNcbicKKyAgICAgICAgJyAgfVxuJworICAgICAgICAnICBbcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yXSB7XG4nCisgICAgICAgICcgICAgc3RyOiBcImZvb1wiXG4nCisgICAgICAgICcgIH1cbicKKyAgICAgICAgJ31cbicpCisKKyAgZGVmIHRlc3RQcmludE1lc3NhZ2VTZXRBc09uZUxpbmUoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKCkKKyAgICBleHQxID0gdW5pdHRlc3RfbXNldF9wYjIuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2Vfc2V0X2V4dGVuc2lvbgorICAgIGV4dDIgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIubWVzc2FnZV9zZXRfZXh0ZW5zaW9uCisgICAgbWVzc2FnZS5tZXNzYWdlX3NldC5FeHRlbnNpb25zW2V4dDFdLmkgPSAyMworICAgIG1lc3NhZ2UubWVzc2FnZV9zZXQuRXh0ZW5zaW9uc1tleHQyXS5zdHIgPSAnZm9vJworICAgIHNlbGYuQ29tcGFyZVRvR29sZGVuVGV4dCgKKyAgICAgICAgdGV4dF9mb3JtYXQuTWVzc2FnZVRvU3RyaW5nKG1lc3NhZ2UsIGFzX29uZV9saW5lPVRydWUpLAorICAgICAgICAnbWVzc2FnZV9zZXQgeycKKyAgICAgICAgJyBbcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xXSB7JworICAgICAgICAnIGk6IDIzJworICAgICAgICAnIH0nCisgICAgICAgICcgW3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl0geycKKyAgICAgICAgJyBzdHI6IFwiZm9vXCInCisgICAgICAgICcgfScKKyAgICAgICAgJyB9JykKKworICBkZWYgdGVzdFBhcnNlTWVzc2FnZVNldChzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgdGV4dCA9ICgncmVwZWF0ZWRfdWludDY0OiAxXG4nCisgICAgICAgICAgICAncmVwZWF0ZWRfdWludDY0OiAyXG4nKQorICAgIHRleHRfZm9ybWF0LlBhcnNlKHRleHQsIG1lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NFswXSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDIsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0WzFdKQorCisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKCkKKyAgICB0ZXh0ID0gKCdtZXNzYWdlX3NldCB7XG4nCisgICAgICAgICAgICAnICBbcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xXSB7XG4nCisgICAgICAgICAgICAnICAgIGk6IDIzXG4nCisgICAgICAgICAgICAnICB9XG4nCisgICAgICAgICAgICAnICBbcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yXSB7XG4nCisgICAgICAgICAgICAnICAgIHN0cjogXCJmb29cIlxuJworICAgICAgICAgICAgJyAgfVxuJworICAgICAgICAgICAgJ31cbicpCisgICAgdGV4dF9mb3JtYXQuUGFyc2UodGV4dCwgbWVzc2FnZSkKKyAgICBleHQxID0gdW5pdHRlc3RfbXNldF9wYjIuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm1lc3NhZ2Vfc2V0X2V4dGVuc2lvbgorICAgIGV4dDIgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIubWVzc2FnZV9zZXRfZXh0ZW5zaW9uCisgICAgc2VsZi5hc3NlcnRFcXVhbHMoMjMsIG1lc3NhZ2UubWVzc2FnZV9zZXQuRXh0ZW5zaW9uc1tleHQxXS5pKQorICAgIHNlbGYuYXNzZXJ0RXF1YWxzKCdmb28nLCBtZXNzYWdlLm1lc3NhZ2Vfc2V0LkV4dGVuc2lvbnNbZXh0Ml0uc3RyKQorCisgIGRlZiB0ZXN0UHJpbnRBbGxFeHRlbnNpb25zKHNlbGYpOgorICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEFsbEV4dGVuc2lvbnMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxFeHRlbnNpb25zKG1lc3NhZ2UpCisgICAgc2VsZi5Db21wYXJlVG9Hb2xkZW5GaWxlKAorICAgICAgICBzZWxmLlJlbW92ZVJlZHVuZGFudFplcm9zKHRleHRfZm9ybWF0Lk1lc3NhZ2VUb1N0cmluZyhtZXNzYWdlKSksCisgICAgICAgICd0ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0JykKKworICBkZWYgdGVzdFByaW50QWxsRXh0ZW5zaW9uc1BvaW50eShzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlKQorICAgIHNlbGYuQ29tcGFyZVRvR29sZGVuRmlsZSgKKyAgICAgICAgc2VsZi5SZW1vdmVSZWR1bmRhbnRaZXJvcyh0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcoCisgICAgICAgICAgICBtZXNzYWdlLCBwb2ludHlfYnJhY2tldHM9VHJ1ZSkpLAorICAgICAgICAndGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhX3BvaW50eS50eHQnKQorCisgIGRlZiB0ZXN0UGFyc2VHb2xkZW5FeHRlbnNpb25zKHNlbGYpOgorICAgIGdvbGRlbl90ZXh0ID0gJ1xuJy5qb2luKHNlbGYuUmVhZEdvbGRlbigKKyAgICAgICAgJ3RleHRfZm9ybWF0X3VuaXR0ZXN0X2V4dGVuc2lvbnNfZGF0YS50eHQnKSkKKyAgICBwYXJzZWRfbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgdGV4dF9mb3JtYXQuUGFyc2UoZ29sZGVuX3RleHQsIHBhcnNlZF9tZXNzYWdlKQorCisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgdGVzdF91dGlsLlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFscyhtZXNzYWdlLCBwYXJzZWRfbWVzc2FnZSkKKworICBkZWYgdGVzdFBhcnNlQWxsRXh0ZW5zaW9ucyhzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICB0ZXN0X3V0aWwuU2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlKQorICAgIGFzY2lpX3RleHQgPSB0ZXh0X2Zvcm1hdC5NZXNzYWdlVG9TdHJpbmcobWVzc2FnZSkKKworICAgIHBhcnNlZF9tZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICB0ZXh0X2Zvcm1hdC5QYXJzZShhc2NpaV90ZXh0LCBwYXJzZWRfbWVzc2FnZSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKG1lc3NhZ2UsIHBhcnNlZF9tZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VCYWRFeHRlbnNpb24oc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgdGV4dCA9ICdbdW5rbm93bl9leHRlbnNpb25dOiA4XG4nCisgICAgc2VsZi5hc3NlcnRSYWlzZXNXaXRoTGl0ZXJhbE1hdGNoKAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLAorICAgICAgICAnMToyIDogRXh0ZW5zaW9uICJ1bmtub3duX2V4dGVuc2lvbiIgbm90IHJlZ2lzdGVyZWQuJywKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2UsIHRleHQsIG1lc3NhZ2UpCisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzV2l0aExpdGVyYWxNYXRjaCgKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2VFcnJvciwKKyAgICAgICAgKCcxOjIgOiBNZXNzYWdlIHR5cGUgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyIgZG9lcyBub3QgaGF2ZSAnCisgICAgICAgICAnZXh0ZW5zaW9ucy4nKSwKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2UsIHRleHQsIG1lc3NhZ2UpCisKKyAgZGVmIHRlc3RNZXJnZUR1cGxpY2F0ZUV4dGVuc2lvblNjYWxhcnMoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsRXh0ZW5zaW9ucygpCisgICAgdGV4dCA9ICgnW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl06IDQyICcKKyAgICAgICAgICAgICdbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXTogNjcnKQorICAgIHRleHRfZm9ybWF0Lk1lcmdlKHRleHQsIG1lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgNjcsCisgICAgICAgIG1lc3NhZ2UuRXh0ZW5zaW9uc1t1bml0dGVzdF9wYjIub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXSkKKworICBkZWYgdGVzdFBhcnNlRHVwbGljYXRlRXh0ZW5zaW9uU2NhbGFycyhzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxFeHRlbnNpb25zKCkKKyAgICB0ZXh0ID0gKCdbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXTogNDIgJworICAgICAgICAgICAgJ1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbnQzMl9leHRlbnNpb25dOiA2NycpCisgICAgc2VsZi5hc3NlcnRSYWlzZXNXaXRoTGl0ZXJhbE1hdGNoKAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLAorICAgICAgICAoJzE6OTYgOiBNZXNzYWdlIHR5cGUgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIiAnCisgICAgICAgICAnc2hvdWxkIG5vdCBoYXZlIG11bHRpcGxlICcKKyAgICAgICAgICcicHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uIiBleHRlbnNpb25zLicpLAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZSwgdGV4dCwgbWVzc2FnZSkKKworICBkZWYgdGVzdFBhcnNlRHVwbGljYXRlTmVzdGVkTWVzc2FnZVNjYWxhcnMoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHRleHQgPSAoJ29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsgYmI6IDEgfSAnCisgICAgICAgICAgICAnb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeyBiYjogMiB9JykKKyAgICBzZWxmLmFzc2VydFJhaXNlc1dpdGhMaXRlcmFsTWF0Y2goCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlRXJyb3IsCisgICAgICAgICgnMTo2NSA6IE1lc3NhZ2UgdHlwZSAicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UiICcKKyAgICAgICAgICdzaG91bGQgbm90IGhhdmUgbXVsdGlwbGUgImJiIiBmaWVsZHMuJyksCisgICAgICAgIHRleHRfZm9ybWF0LlBhcnNlLCB0ZXh0LCBtZXNzYWdlKQorCisgIGRlZiB0ZXN0UGFyc2VEdXBsaWNhdGVTY2FsYXJzKHNlbGYpOgorICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEFsbFR5cGVzKCkKKyAgICB0ZXh0ID0gKCdvcHRpb25hbF9pbnQzMjogNDIgJworICAgICAgICAgICAgJ29wdGlvbmFsX2ludDMyOiA2NycpCisgICAgc2VsZi5hc3NlcnRSYWlzZXNXaXRoTGl0ZXJhbE1hdGNoKAorICAgICAgICB0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLAorICAgICAgICAoJzE6MzYgOiBNZXNzYWdlIHR5cGUgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyIgc2hvdWxkIG5vdCAnCisgICAgICAgICAnaGF2ZSBtdWx0aXBsZSAib3B0aW9uYWxfaW50MzIiIGZpZWxkcy4nKSwKKyAgICAgICAgdGV4dF9mb3JtYXQuUGFyc2UsIHRleHQsIG1lc3NhZ2UpCisKKworY2xhc3MgVG9rZW5pemVyVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3RTaW1wbGVUb2tlbkNhc2VzKHNlbGYpOgorICAgIHRleHQgPSAoJ2lkZW50aWZpZXIxOiJzdHJpbmcxIlxuICAgICBcblxuJworICAgICAgICAgICAgJ2lkZW50aWZpZXIyIDogXG4gXG4xMjMgIFxuICBpZGVudGlmaWVyMyA6XCdzdHJpbmdcJ1xuJworICAgICAgICAgICAgJ2lkZW50aWZpRVJfNCA6IDEuMWUrMiBJRDU6LTAuMjMgSUQ2OlwnYWFhYVxcXCdiYmJiXCdcbicKKyAgICAgICAgICAgICdJRDcgOiAiYWFcXCJiYiJcblxuXG5cbiBJRDg6IHtBOmluZiBCOi1pbmYgQzp0cnVlIEQ6ZmFsc2V9XG4nCisgICAgICAgICAgICAnSUQ5OiAyMiBJRDEwOiAtMTExMTExMTExMTExMTExMTExIElEMTE6IC0yMlxuJworICAgICAgICAgICAgJ0lEMTI6IDIyMjIyMjIyMjIyMjIyMjIyMjIgSUQxMzogMS4yMzQ1NmYgSUQxNDogMS4yZSsyZiAnCisgICAgICAgICAgICAnZmFsc2VfYm9vbDogIDAgdHJ1ZV9CT09MOnQgXG4gdHJ1ZV9ib29sMTogIDEgZmFsc2VfQk9PTDE6ZiAnKQorICAgIHRva2VuaXplciA9IHRleHRfZm9ybWF0Ll9Ub2tlbml6ZXIodGV4dC5zcGxpdGxpbmVzKCkpCisgICAgbWV0aG9kcyA9IFsodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAnaWRlbnRpZmllcjEnKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZVN0cmluZywgJ3N0cmluZzEnKSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdpZGVudGlmaWVyMicpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSW50MzIsIDEyMyksCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAnaWRlbnRpZmllcjMnKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZVN0cmluZywgJ3N0cmluZycpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ2lkZW50aWZpRVJfNCcpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lRmxvYXQsIDEuMWUrMiksCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAnSUQ1JyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVGbG9hdCwgLTAuMjMpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ0lENicpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lU3RyaW5nLCAnYWFhYVwnYmJiYicpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ0lENycpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lU3RyaW5nLCAnYWFcImJiJyksCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAnSUQ4JyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAneycsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAnQScpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lRmxvYXQsIGZsb2F0KCdpbmYnKSksCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAnQicpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lRmxvYXQsIC1mbG9hdCgnaW5mJykpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ0MnKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUJvb2wsIFRydWUpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ0QnKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUJvb2wsIEZhbHNlKSwKKyAgICAgICAgICAgICAgICd9JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdJRDknKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZVVpbnQzMiwgMjIpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ0lEMTAnKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUludDY0LCAtMTExMTExMTExMTExMTExMTExKSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdJRDExJyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJbnQzMiwgLTIyKSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdJRDEyJyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVVaW50NjQsIDIyMjIyMjIyMjIyMjIyMjIyMjIpLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lSWRlbnRpZmllciwgJ0lEMTMnKSwKKyAgICAgICAgICAgICAgICc6JywKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUZsb2F0LCAxLjIzNDU2KSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdJRDE0JyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVGbG9hdCwgMS4yZSsyKSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdmYWxzZV9ib29sJyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVCb29sLCBGYWxzZSksCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyLCAndHJ1ZV9CT09MJyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVCb29sLCBUcnVlKSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICd0cnVlX2Jvb2wxJyksCisgICAgICAgICAgICAgICAnOicsCisgICAgICAgICAgICAgICAodG9rZW5pemVyLkNvbnN1bWVCb29sLCBUcnVlKSwKKyAgICAgICAgICAgICAgICh0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIsICdmYWxzZV9CT09MMScpLAorICAgICAgICAgICAgICAgJzonLAorICAgICAgICAgICAgICAgKHRva2VuaXplci5Db25zdW1lQm9vbCwgRmFsc2UpXQorCisgICAgaSA9IDAKKyAgICB3aGlsZSBub3QgdG9rZW5pemVyLkF0RW5kKCk6CisgICAgICBtID0gbWV0aG9kc1tpXQorICAgICAgaWYgdHlwZShtKSA9PSBzdHI6CisgICAgICAgIHRva2VuID0gdG9rZW5pemVyLnRva2VuCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodG9rZW4sIG0pCisgICAgICAgIHRva2VuaXplci5OZXh0VG9rZW4oKQorICAgICAgZWxzZToKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChtWzFdLCBtWzBdKCkpCisgICAgICBpICs9IDEKKworICBkZWYgdGVzdENvbnN1bWVJbnRlZ2VycyhzZWxmKToKKyAgICAjIFRoaXMgdGVzdCBvbmx5IHRlc3RzIHRoZSBmYWlsdXJlcyBpbiB0aGUgaW50ZWdlciBwYXJzaW5nIG1ldGhvZHMgYXMgd2VsbAorICAgICMgYXMgdGhlICcwJyBzcGVjaWFsIGNhc2VzLgorICAgIGludDY0X21heCA9ICgxIDw8IDYzKSAtIDEKKyAgICB1aW50MzJfbWF4ID0gKDEgPDwgMzIpIC0gMQorICAgIHRleHQgPSAnLTEgJWQgJWQnICUgKHVpbnQzMl9tYXggKyAxLCBpbnQ2NF9tYXggKyAxKQorICAgIHRva2VuaXplciA9IHRleHRfZm9ybWF0Ll9Ub2tlbml6ZXIodGV4dC5zcGxpdGxpbmVzKCkpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVVaW50MzIpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVVaW50NjQpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgtMSwgdG9rZW5pemVyLkNvbnN1bWVJbnQzMigpKQorCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVVaW50MzIpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVJbnQzMikKKyAgICBzZWxmLmFzc2VydEVxdWFsKHVpbnQzMl9tYXggKyAxLCB0b2tlbml6ZXIuQ29uc3VtZUludDY0KCkpCisKKyAgICBzZWxmLmFzc2VydFJhaXNlcyh0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLCB0b2tlbml6ZXIuQ29uc3VtZUludDY0KQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50NjRfbWF4ICsgMSwgdG9rZW5pemVyLkNvbnN1bWVVaW50NjQoKSkKKyAgICBzZWxmLmFzc2VydFRydWUodG9rZW5pemVyLkF0RW5kKCkpCisKKyAgICB0ZXh0ID0gJy0wIC0wIDAgMCcKKyAgICB0b2tlbml6ZXIgPSB0ZXh0X2Zvcm1hdC5fVG9rZW5pemVyKHRleHQuc3BsaXRsaW5lcygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgdG9rZW5pemVyLkNvbnN1bWVVaW50MzIoKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIHRva2VuaXplci5Db25zdW1lVWludDY0KCkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCB0b2tlbml6ZXIuQ29uc3VtZVVpbnQzMigpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgdG9rZW5pemVyLkNvbnN1bWVVaW50NjQoKSkKKyAgICBzZWxmLmFzc2VydFRydWUodG9rZW5pemVyLkF0RW5kKCkpCisKKyAgZGVmIHRlc3RDb25zdW1lQnl0ZVN0cmluZyhzZWxmKToKKyAgICB0ZXh0ID0gJyJzdHJpbmcxXCcnCisgICAgdG9rZW5pemVyID0gdGV4dF9mb3JtYXQuX1Rva2VuaXplcih0ZXh0LnNwbGl0bGluZXMoKSkKKyAgICBzZWxmLmFzc2VydFJhaXNlcyh0ZXh0X2Zvcm1hdC5QYXJzZUVycm9yLCB0b2tlbml6ZXIuQ29uc3VtZUJ5dGVTdHJpbmcpCisKKyAgICB0ZXh0ID0gJ3N0cmluZzEiJworICAgIHRva2VuaXplciA9IHRleHRfZm9ybWF0Ll9Ub2tlbml6ZXIodGV4dC5zcGxpdGxpbmVzKCkpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVCeXRlU3RyaW5nKQorCisgICAgdGV4dCA9ICdcbiJcXHh0IicKKyAgICB0b2tlbml6ZXIgPSB0ZXh0X2Zvcm1hdC5fVG9rZW5pemVyKHRleHQuc3BsaXRsaW5lcygpKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRleHRfZm9ybWF0LlBhcnNlRXJyb3IsIHRva2VuaXplci5Db25zdW1lQnl0ZVN0cmluZykKKworICAgIHRleHQgPSAnXG4iXFwiJworICAgIHRva2VuaXplciA9IHRleHRfZm9ybWF0Ll9Ub2tlbml6ZXIodGV4dC5zcGxpdGxpbmVzKCkpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVCeXRlU3RyaW5nKQorCisgICAgdGV4dCA9ICdcbiJcXHgiJworICAgIHRva2VuaXplciA9IHRleHRfZm9ybWF0Ll9Ub2tlbml6ZXIodGV4dC5zcGxpdGxpbmVzKCkpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVCeXRlU3RyaW5nKQorCisgIGRlZiB0ZXN0Q29uc3VtZUJvb2woc2VsZik6CisgICAgdGV4dCA9ICdub3QtYS1ib29sJworICAgIHRva2VuaXplciA9IHRleHRfZm9ybWF0Ll9Ub2tlbml6ZXIodGV4dC5zcGxpdGxpbmVzKCkpCisgICAgc2VsZi5hc3NlcnRSYWlzZXModGV4dF9mb3JtYXQuUGFyc2VFcnJvciwgdG9rZW5pemVyLkNvbnN1bWVCb29sKQorCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIGJhc2V0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90eXBlX2NoZWNrZXJzLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC90eXBlX2NoZWNrZXJzLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjc2YzA1NmMKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3R5cGVfY2hlY2tlcnMucHkKQEAgLTAsMCArMSwzMzMgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI1BZMjUgY29tcGF0aWJsZSBmb3IgR0FFLgorIworIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorCisiIiJQcm92aWRlcyB0eXBlIGNoZWNraW5nIHJvdXRpbmVzLgorCitUaGlzIG1vZHVsZSBkZWZpbmVzIHR5cGUgY2hlY2tpbmcgdXRpbGl0aWVzIGluIHRoZSBmb3JtcyBvZiBkaWN0aW9uYXJpZXM6CisKK1ZBTFVFX0NIRUNLRVJTOiBBIGRpY3Rpb25hcnkgb2YgZmllbGQgdHlwZXMgYW5kIGEgdmFsdWUgdmFsaWRhdGlvbiBvYmplY3QuCitUWVBFX1RPX0JZVEVfU0laRV9GTjogQSBkaWN0aW9uYXJ5IHdpdGggZmllbGQgdHlwZXMgYW5kIGEgc2l6ZSBjb21wdXRpbmcKKyAgZnVuY3Rpb24uCitUWVBFX1RPX1NFUklBTElaRV9NRVRIT0Q6IEEgZGljdGlvbmFyeSB3aXRoIGZpZWxkIHR5cGVzIGFuZCBzZXJpYWxpemF0aW9uCisgIGZ1bmN0aW9uLgorRklFTERfVFlQRV9UT19XSVJFX1RZUEU6IEEgZGljdGlvbmFyeSB3aXRoIGZpZWxkIHR5cGVkIGFuZCB0aGVpcgorICBjb3Jlc3BvbmRpbmcgd2lyZSB0eXBlcy4KK1RZUEVfVE9fREVTRVJJQUxJWkVfTUVUSE9EOiBBIGRpY3Rpb25hcnkgd2l0aCBmaWVsZCB0eXBlcyBhbmQgZGVzZXJpYWxpemF0aW9uCisgIGZ1bmN0aW9uLgorIiIiCisKK19fYXV0aG9yX18gPSAncm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbiknCisKK2ltcG9ydCBzeXMgICMjUFkyNQoraWYgc3lzLnZlcnNpb24gPCAnMi42JzogYnl0ZXMgPSBzdHIgICMjUFkyNQorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGFwaV9pbXBsZW1lbnRhdGlvbgorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IGRlY29kZXIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBlbmNvZGVyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgd2lyZV9mb3JtYXQKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yCisKK19GaWVsZERlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvcgorCitkZWYgU3VwcG9ydHNPcGVuRW51bXMoZmllbGRfZGVzY3JpcHRvcik6CisgIHJldHVybiBmaWVsZF9kZXNjcmlwdG9yLmNvbnRhaW5pbmdfdHlwZS5zeW50YXggPT0gInByb3RvMyIKKworZGVmIEdldFR5cGVDaGVja2VyKGZpZWxkKToKKyAgIiIiUmV0dXJucyBhIHR5cGUgY2hlY2tlciBmb3IgYSBtZXNzYWdlIGZpZWxkIG9mIHRoZSBzcGVjaWZpZWQgdHlwZXMuCisKKyAgQXJnczoKKyAgICBmaWVsZDogRmllbGREZXNjcmlwdG9yIG9iamVjdCBmb3IgdGhpcyBmaWVsZC4KKworICBSZXR1cm5zOgorICAgIEFuIGluc3RhbmNlIG9mIFR5cGVDaGVja2VyIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHZlcmlmeSB0aGUgdHlwZXMKKyAgICBvZiB2YWx1ZXMgYXNzaWduZWQgdG8gYSBmaWVsZCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICIiIgorICBpZiAoZmllbGQuY3BwX3R5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX1NUUklORyBhbmQKKyAgICAgIGZpZWxkLnR5cGUgPT0gX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NUUklORyk6CisgICAgcmV0dXJuIFVuaWNvZGVWYWx1ZUNoZWNrZXIoKQorICBpZiBmaWVsZC5jcHBfdHlwZSA9PSBfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfRU5VTToKKyAgICBpZiBTdXBwb3J0c09wZW5FbnVtcyhmaWVsZCk6CisgICAgICAjIFdoZW4gb3BlbiBlbnVtcyBhcmUgc3VwcG9ydGVkLCBhbnkgaW50MzIgY2FuIGJlIGFzc2lnbmVkLgorICAgICAgcmV0dXJuIF9WQUxVRV9DSEVDS0VSU1tfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfSU5UMzJdCisgICAgZWxzZToKKyAgICAgIHJldHVybiBFbnVtVmFsdWVDaGVja2VyKGZpZWxkLmVudW1fdHlwZSkKKyAgcmV0dXJuIF9WQUxVRV9DSEVDS0VSU1tmaWVsZC5jcHBfdHlwZV0KKworCisjIE5vbmUgb2YgdGhlIHR5cGVjaGVja2VycyBiZWxvdyBtYWtlIGFueSBhdHRlbXB0IHRvIGd1YXJkIGFnYWluc3QgcGVvcGxlCisjIHN1YmNsYXNzaW5nIGJ1aWx0aW4gdHlwZXMgYW5kIGRvaW5nIHdlaXJkIHRoaW5ncy4gIFdlJ3JlIG5vdCB0cnlpbmcgdG8KKyMgcHJvdGVjdCBhZ2FpbnN0IG1hbGljaW91cyBjbGllbnRzIGhlcmUsIGp1c3QgcGVvcGxlIGFjY2lkZW50YWxseSBzaG9vdGluZworIyB0aGVtc2VsdmVzIGluIHRoZSBmb290IGluIG9idmlvdXMgd2F5cy4KKworY2xhc3MgVHlwZUNoZWNrZXIob2JqZWN0KToKKworICAiIiJUeXBlIGNoZWNrZXIgdXNlZCB0byBjYXRjaCB0eXBlIGVycm9ycyBhcyBlYXJseSBhcyBwb3NzaWJsZQorICB3aGVuIHRoZSBjbGllbnQgaXMgc2V0dGluZyBzY2FsYXIgZmllbGRzIGluIHByb3RvY29sIG1lc3NhZ2VzLgorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgKmFjY2VwdGFibGVfdHlwZXMpOgorICAgIHNlbGYuX2FjY2VwdGFibGVfdHlwZXMgPSBhY2NlcHRhYmxlX3R5cGVzCisKKyAgZGVmIENoZWNrVmFsdWUoc2VsZiwgcHJvcG9zZWRfdmFsdWUpOgorICAgICIiIlR5cGUgY2hlY2sgdGhlIHByb3ZpZGVkIHZhbHVlIGFuZCByZXR1cm4gaXQuCisKKyAgICBUaGUgcmV0dXJuZWQgdmFsdWUgbWlnaHQgaGF2ZSBiZWVuIG5vcm1hbGl6ZWQgdG8gYW5vdGhlciB0eXBlLgorICAgICIiIgorICAgIGlmIG5vdCBpc2luc3RhbmNlKHByb3Bvc2VkX3ZhbHVlLCBzZWxmLl9hY2NlcHRhYmxlX3R5cGVzKToKKyAgICAgIG1lc3NhZ2UgPSAoJyUuMTAyNHIgaGFzIHR5cGUgJXMsIGJ1dCBleHBlY3RlZCBvbmUgb2Y6ICVzJyAlCisgICAgICAgICAgICAgICAgIChwcm9wb3NlZF92YWx1ZSwgdHlwZShwcm9wb3NlZF92YWx1ZSksIHNlbGYuX2FjY2VwdGFibGVfdHlwZXMpKQorICAgICAgcmFpc2UgVHlwZUVycm9yKG1lc3NhZ2UpCisgICAgcmV0dXJuIHByb3Bvc2VkX3ZhbHVlCisKKworIyBJbnRWYWx1ZUNoZWNrZXIgYW5kIGl0cyBzdWJjbGFzc2VzIHBlcmZvcm0gaW50ZWdlciB0eXBlLWNoZWNrcworIyBhbmQgYm91bmRzLWNoZWNrcy4KK2NsYXNzIEludFZhbHVlQ2hlY2tlcihvYmplY3QpOgorCisgICIiIkNoZWNrZXIgdXNlZCBmb3IgaW50ZWdlciBmaWVsZHMuICBQZXJmb3JtcyB0eXBlLWNoZWNrIGFuZCByYW5nZSBjaGVjay4iIiIKKworICBkZWYgQ2hlY2tWYWx1ZShzZWxmLCBwcm9wb3NlZF92YWx1ZSk6CisgICAgaWYgbm90IGlzaW5zdGFuY2UocHJvcG9zZWRfdmFsdWUsIChpbnQsIGxvbmcpKToKKyAgICAgIG1lc3NhZ2UgPSAoJyUuMTAyNHIgaGFzIHR5cGUgJXMsIGJ1dCBleHBlY3RlZCBvbmUgb2Y6ICVzJyAlCisgICAgICAgICAgICAgICAgIChwcm9wb3NlZF92YWx1ZSwgdHlwZShwcm9wb3NlZF92YWx1ZSksIChpbnQsIGxvbmcpKSkKKyAgICAgIHJhaXNlIFR5cGVFcnJvcihtZXNzYWdlKQorICAgIGlmIG5vdCBzZWxmLl9NSU4gPD0gcHJvcG9zZWRfdmFsdWUgPD0gc2VsZi5fTUFYOgorICAgICAgcmFpc2UgVmFsdWVFcnJvcignVmFsdWUgb3V0IG9mIHJhbmdlOiAlZCcgJSBwcm9wb3NlZF92YWx1ZSkKKyAgICAjIFdlIGZvcmNlIDMyLWJpdCB2YWx1ZXMgdG8gaW50IGFuZCA2NC1iaXQgdmFsdWVzIHRvIGxvbmcgdG8gbWFrZQorICAgICMgYWx0ZXJuYXRlIGltcGxlbWVudGF0aW9ucyB3aGVyZSB0aGUgZGlzdGluY3Rpb24gaXMgbW9yZSBzaWduaWZpY2FudAorICAgICMgKGUuZy4gdGhlIEMrKyBpbXBsZW1lbnRhdGlvbikgc2ltcGxlci4KKyAgICBwcm9wb3NlZF92YWx1ZSA9IHNlbGYuX1RZUEUocHJvcG9zZWRfdmFsdWUpCisgICAgcmV0dXJuIHByb3Bvc2VkX3ZhbHVlCisKKworY2xhc3MgRW51bVZhbHVlQ2hlY2tlcihvYmplY3QpOgorCisgICIiIkNoZWNrZXIgdXNlZCBmb3IgZW51bSBmaWVsZHMuICBQZXJmb3JtcyB0eXBlLWNoZWNrIGFuZCByYW5nZSBjaGVjay4iIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgZW51bV90eXBlKToKKyAgICBzZWxmLl9lbnVtX3R5cGUgPSBlbnVtX3R5cGUKKworICBkZWYgQ2hlY2tWYWx1ZShzZWxmLCBwcm9wb3NlZF92YWx1ZSk6CisgICAgaWYgbm90IGlzaW5zdGFuY2UocHJvcG9zZWRfdmFsdWUsIChpbnQsIGxvbmcpKToKKyAgICAgIG1lc3NhZ2UgPSAoJyUuMTAyNHIgaGFzIHR5cGUgJXMsIGJ1dCBleHBlY3RlZCBvbmUgb2Y6ICVzJyAlCisgICAgICAgICAgICAgICAgIChwcm9wb3NlZF92YWx1ZSwgdHlwZShwcm9wb3NlZF92YWx1ZSksIChpbnQsIGxvbmcpKSkKKyAgICAgIHJhaXNlIFR5cGVFcnJvcihtZXNzYWdlKQorICAgIGlmIHByb3Bvc2VkX3ZhbHVlIG5vdCBpbiBzZWxmLl9lbnVtX3R5cGUudmFsdWVzX2J5X251bWJlcjoKKyAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ1Vua25vd24gZW51bSB2YWx1ZTogJWQnICUgcHJvcG9zZWRfdmFsdWUpCisgICAgcmV0dXJuIHByb3Bvc2VkX3ZhbHVlCisKKworY2xhc3MgVW5pY29kZVZhbHVlQ2hlY2tlcihvYmplY3QpOgorCisgICIiIkNoZWNrZXIgdXNlZCBmb3Igc3RyaW5nIGZpZWxkcy4KKworICBBbHdheXMgcmV0dXJucyBhIHVuaWNvZGUgdmFsdWUsIGV2ZW4gaWYgdGhlIGlucHV0IGlzIG9mIHR5cGUgc3RyLgorICAiIiIKKworICBkZWYgQ2hlY2tWYWx1ZShzZWxmLCBwcm9wb3NlZF92YWx1ZSk6CisgICAgaWYgbm90IGlzaW5zdGFuY2UocHJvcG9zZWRfdmFsdWUsIChieXRlcywgdW5pY29kZSkpOgorICAgICAgbWVzc2FnZSA9ICgnJS4xMDI0ciBoYXMgdHlwZSAlcywgYnV0IGV4cGVjdGVkIG9uZSBvZjogJXMnICUKKyAgICAgICAgICAgICAgICAgKHByb3Bvc2VkX3ZhbHVlLCB0eXBlKHByb3Bvc2VkX3ZhbHVlKSwgKGJ5dGVzLCB1bmljb2RlKSkpCisgICAgICByYWlzZSBUeXBlRXJyb3IobWVzc2FnZSkKKworICAgICMgSWYgdGhlIHZhbHVlIGlzIG9mIHR5cGUgJ2J5dGVzJyBtYWtlIHN1cmUgdGhhdCBpdCBpcyB2YWxpZCBVVEYtOCBkYXRhLgorICAgIGlmIGlzaW5zdGFuY2UocHJvcG9zZWRfdmFsdWUsIGJ5dGVzKToKKyAgICAgIHRyeToKKyAgICAgICAgcHJvcG9zZWRfdmFsdWUgPSBwcm9wb3NlZF92YWx1ZS5kZWNvZGUoJ3V0Zi04JykKKyAgICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3I6CisgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJyUuMTAyNHIgaGFzIHR5cGUgYnl0ZXMsIGJ1dCBpc25cJ3QgdmFsaWQgVVRGLTggJworICAgICAgICAgICAgICAgICAgICAgICAgICdlbmNvZGluZy4gTm9uLVVURi04IHN0cmluZ3MgbXVzdCBiZSBjb252ZXJ0ZWQgdG8gJworICAgICAgICAgICAgICAgICAgICAgICAgICd1bmljb2RlIG9iamVjdHMgYmVmb3JlIGJlaW5nIGFkZGVkLicgJQorICAgICAgICAgICAgICAgICAgICAgICAgIChwcm9wb3NlZF92YWx1ZSkpCisgICAgcmV0dXJuIHByb3Bvc2VkX3ZhbHVlCisKKworY2xhc3MgSW50MzJWYWx1ZUNoZWNrZXIoSW50VmFsdWVDaGVja2VyKToKKyAgIyBXZSdyZSBzdXJlIHRvIHVzZSBpbnRzIGluc3RlYWQgb2YgbG9uZ3MgaGVyZSBzaW5jZSBjb21wYXJpc29uIG1heSBiZSBtb3JlCisgICMgZWZmaWNpZW50LgorICBfTUlOID0gLTIxNDc0ODM2NDgKKyAgX01BWCA9IDIxNDc0ODM2NDcKKyAgX1RZUEUgPSBpbnQKKworCitjbGFzcyBVaW50MzJWYWx1ZUNoZWNrZXIoSW50VmFsdWVDaGVja2VyKToKKyAgX01JTiA9IDAKKyAgX01BWCA9ICgxIDw8IDMyKSAtIDEKKyAgX1RZUEUgPSBpbnQKKworCitjbGFzcyBJbnQ2NFZhbHVlQ2hlY2tlcihJbnRWYWx1ZUNoZWNrZXIpOgorICBfTUlOID0gLSgxIDw8IDYzKQorICBfTUFYID0gKDEgPDwgNjMpIC0gMQorICBfVFlQRSA9IGxvbmcKKworCitjbGFzcyBVaW50NjRWYWx1ZUNoZWNrZXIoSW50VmFsdWVDaGVja2VyKToKKyAgX01JTiA9IDAKKyAgX01BWCA9ICgxIDw8IDY0KSAtIDEKKyAgX1RZUEUgPSBsb25nCisKKworIyBUeXBlLWNoZWNrZXJzIGZvciBhbGwgc2NhbGFyIENQUFRZUEVzLgorX1ZBTFVFX0NIRUNLRVJTID0geworICAgIF9GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9JTlQzMjogSW50MzJWYWx1ZUNoZWNrZXIoKSwKKyAgICBfRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfSU5UNjQ6IEludDY0VmFsdWVDaGVja2VyKCksCisgICAgX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX1VJTlQzMjogVWludDMyVmFsdWVDaGVja2VyKCksCisgICAgX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX1VJTlQ2NDogVWludDY0VmFsdWVDaGVja2VyKCksCisgICAgX0ZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX0RPVUJMRTogVHlwZUNoZWNrZXIoCisgICAgICAgIGZsb2F0LCBpbnQsIGxvbmcpLAorICAgIF9GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9GTE9BVDogVHlwZUNoZWNrZXIoCisgICAgICAgIGZsb2F0LCBpbnQsIGxvbmcpLAorICAgIF9GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9CT09MOiBUeXBlQ2hlY2tlcihib29sLCBpbnQpLAorICAgIF9GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9TVFJJTkc6IFR5cGVDaGVja2VyKGJ5dGVzKSwKKyAgICB9CisKKworIyBNYXAgZnJvbSBmaWVsZCB0eXBlIHRvIGEgZnVuY3Rpb24gRiwgc3VjaCB0aGF0IEYoZmllbGRfbnVtLCB2YWx1ZSkKKyMgZ2l2ZXMgdGhlIHRvdGFsIGJ5dGUgc2l6ZSBmb3IgYSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gdHlwZS4gIFRoaXMKKyMgYnl0ZSBzaXplIGluY2x1ZGVzIHRhZyBpbmZvcm1hdGlvbiBhbmQgYW55IG90aGVyIGFkZGl0aW9uYWwgc3BhY2UKKyMgYXNzb2NpYXRlZCB3aXRoIHNlcmlhbGl6aW5nICJ2YWx1ZSIuCitUWVBFX1RPX0JZVEVfU0laRV9GTiA9IHsKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRE9VQkxFOiB3aXJlX2Zvcm1hdC5Eb3VibGVCeXRlU2l6ZSwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRkxPQVQ6IHdpcmVfZm9ybWF0LkZsb2F0Qnl0ZVNpemUsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0lOVDY0OiB3aXJlX2Zvcm1hdC5JbnQ2NEJ5dGVTaXplLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9VSU5UNjQ6IHdpcmVfZm9ybWF0LlVJbnQ2NEJ5dGVTaXplLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9JTlQzMjogd2lyZV9mb3JtYXQuSW50MzJCeXRlU2l6ZSwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRklYRUQ2NDogd2lyZV9mb3JtYXQuRml4ZWQ2NEJ5dGVTaXplLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9GSVhFRDMyOiB3aXJlX2Zvcm1hdC5GaXhlZDMyQnl0ZVNpemUsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0JPT0w6IHdpcmVfZm9ybWF0LkJvb2xCeXRlU2l6ZSwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU1RSSU5HOiB3aXJlX2Zvcm1hdC5TdHJpbmdCeXRlU2l6ZSwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfR1JPVVA6IHdpcmVfZm9ybWF0Lkdyb3VwQnl0ZVNpemUsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0U6IHdpcmVfZm9ybWF0Lk1lc3NhZ2VCeXRlU2l6ZSwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfQllURVM6IHdpcmVfZm9ybWF0LkJ5dGVzQnl0ZVNpemUsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1VJTlQzMjogd2lyZV9mb3JtYXQuVUludDMyQnl0ZVNpemUsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU06IHdpcmVfZm9ybWF0LkVudW1CeXRlU2l6ZSwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU0ZJWEVEMzI6IHdpcmVfZm9ybWF0LlNGaXhlZDMyQnl0ZVNpemUsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NGSVhFRDY0OiB3aXJlX2Zvcm1hdC5TRml4ZWQ2NEJ5dGVTaXplLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UMzI6IHdpcmVfZm9ybWF0LlNJbnQzMkJ5dGVTaXplLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UNjQ6IHdpcmVfZm9ybWF0LlNJbnQ2NEJ5dGVTaXplCisgICAgfQorCisKKyMgTWFwcyBmcm9tIGZpZWxkIHR5cGVzIHRvIGVuY29kZXIgY29uc3RydWN0b3JzLgorVFlQRV9UT19FTkNPREVSID0geworICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9ET1VCTEU6IGVuY29kZXIuRG91YmxlRW5jb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRkxPQVQ6IGVuY29kZXIuRmxvYXRFbmNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9JTlQ2NDogZW5jb2Rlci5JbnQ2NEVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1VJTlQ2NDogZW5jb2Rlci5VSW50NjRFbmNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9JTlQzMjogZW5jb2Rlci5JbnQzMkVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0ZJWEVENjQ6IGVuY29kZXIuRml4ZWQ2NEVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0ZJWEVEMzI6IGVuY29kZXIuRml4ZWQzMkVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0JPT0w6IGVuY29kZXIuQm9vbEVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NUUklORzogZW5jb2Rlci5TdHJpbmdFbmNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9HUk9VUDogZW5jb2Rlci5Hcm91cEVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0U6IGVuY29kZXIuTWVzc2FnZUVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0JZVEVTOiBlbmNvZGVyLkJ5dGVzRW5jb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfVUlOVDMyOiBlbmNvZGVyLlVJbnQzMkVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU06IGVuY29kZXIuRW51bUVuY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NGSVhFRDMyOiBlbmNvZGVyLlNGaXhlZDMyRW5jb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU0ZJWEVENjQ6IGVuY29kZXIuU0ZpeGVkNjRFbmNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UMzI6IGVuY29kZXIuU0ludDMyRW5jb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU0lOVDY0OiBlbmNvZGVyLlNJbnQ2NEVuY29kZXIsCisgICAgfQorCisKKyMgTWFwcyBmcm9tIGZpZWxkIHR5cGVzIHRvIHNpemVyIGNvbnN0cnVjdG9ycy4KK1RZUEVfVE9fU0laRVIgPSB7CisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0RPVUJMRTogZW5jb2Rlci5Eb3VibGVTaXplciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRkxPQVQ6IGVuY29kZXIuRmxvYXRTaXplciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfSU5UNjQ6IGVuY29kZXIuSW50NjRTaXplciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfVUlOVDY0OiBlbmNvZGVyLlVJbnQ2NFNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9JTlQzMjogZW5jb2Rlci5JbnQzMlNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9GSVhFRDY0OiBlbmNvZGVyLkZpeGVkNjRTaXplciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRklYRUQzMjogZW5jb2Rlci5GaXhlZDMyU2l6ZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0JPT0w6IGVuY29kZXIuQm9vbFNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TVFJJTkc6IGVuY29kZXIuU3RyaW5nU2l6ZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0dST1VQOiBlbmNvZGVyLkdyb3VwU2l6ZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0U6IGVuY29kZXIuTWVzc2FnZVNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9CWVRFUzogZW5jb2Rlci5CeXRlc1NpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9VSU5UMzI6IGVuY29kZXIuVUludDMyU2l6ZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU06IGVuY29kZXIuRW51bVNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TRklYRUQzMjogZW5jb2Rlci5TRml4ZWQzMlNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TRklYRUQ2NDogZW5jb2Rlci5TRml4ZWQ2NFNpemVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UMzI6IGVuY29kZXIuU0ludDMyU2l6ZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NJTlQ2NDogZW5jb2Rlci5TSW50NjRTaXplciwKKyAgICB9CisKKworIyBNYXBzIGZyb20gZmllbGQgdHlwZSB0byBhIGRlY29kZXIgY29uc3RydWN0b3IuCitUWVBFX1RPX0RFQ09ERVIgPSB7CisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0RPVUJMRTogZGVjb2Rlci5Eb3VibGVEZWNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9GTE9BVDogZGVjb2Rlci5GbG9hdERlY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0lOVDY0OiBkZWNvZGVyLkludDY0RGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfVUlOVDY0OiBkZWNvZGVyLlVJbnQ2NERlY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0lOVDMyOiBkZWNvZGVyLkludDMyRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRklYRUQ2NDogZGVjb2Rlci5GaXhlZDY0RGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRklYRUQzMjogZGVjb2Rlci5GaXhlZDMyRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfQk9PTDogZGVjb2Rlci5Cb29sRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU1RSSU5HOiBkZWNvZGVyLlN0cmluZ0RlY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0dST1VQOiBkZWNvZGVyLkdyb3VwRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfTUVTU0FHRTogZGVjb2Rlci5NZXNzYWdlRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfQllURVM6IGRlY29kZXIuQnl0ZXNEZWNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9VSU5UMzI6IGRlY29kZXIuVUludDMyRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRU5VTTogZGVjb2Rlci5FbnVtRGVjb2RlciwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU0ZJWEVEMzI6IGRlY29kZXIuU0ZpeGVkMzJEZWNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TRklYRUQ2NDogZGVjb2Rlci5TRml4ZWQ2NERlY29kZXIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NJTlQzMjogZGVjb2Rlci5TSW50MzJEZWNvZGVyLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UNjQ6IGRlY29kZXIuU0ludDY0RGVjb2RlciwKKyAgICB9CisKKyMgTWFwcyBmcm9tIGZpZWxkIHR5cGUgdG8gZXhwZWN0ZWQgd2lyZXR5cGUuCitGSUVMRF9UWVBFX1RPX1dJUkVfVFlQRSA9IHsKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRE9VQkxFOiB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9GSVhFRDY0LAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9GTE9BVDogd2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQzMiwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfSU5UNjQ6IHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfVUlOVDY0OiB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0lOVDMyOiB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9WQVJJTlQsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0ZJWEVENjQ6IHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVENjQsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0ZJWEVEMzI6IHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVEMzIsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX0JPT0w6IHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU1RSSU5HOgorICAgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfR1JPVVA6IHdpcmVfZm9ybWF0LldJUkVUWVBFX1NUQVJUX0dST1VQLAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9NRVNTQUdFOgorICAgICAgd2lyZV9mb3JtYXQuV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfQllURVM6CisgICAgICB3aXJlX2Zvcm1hdC5XSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9VSU5UMzI6IHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfRU5VTTogd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5ULAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TRklYRUQzMjogd2lyZV9mb3JtYXQuV0lSRVRZUEVfRklYRUQzMiwKKyAgICBfRmllbGREZXNjcmlwdG9yLlRZUEVfU0ZJWEVENjQ6IHdpcmVfZm9ybWF0LldJUkVUWVBFX0ZJWEVENjQsCisgICAgX0ZpZWxkRGVzY3JpcHRvci5UWVBFX1NJTlQzMjogd2lyZV9mb3JtYXQuV0lSRVRZUEVfVkFSSU5ULAorICAgIF9GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UNjQ6IHdpcmVfZm9ybWF0LldJUkVUWVBFX1ZBUklOVCwKKyAgICB9CmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3Vua25vd25fZmllbGRzX3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3Vua25vd25fZmllbGRzX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNTlmOWFlNAotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdW5rbm93bl9maWVsZHNfdGVzdC5weQpAQCAtMCwwICsxLDI2NCBAQAorIyEgL3Vzci9iaW4vcHl0aG9uCisjIC0qLSBjb2Rpbmc6IHV0Zi04IC0qLQorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJUZXN0IGZvciBwcmVzZXJ2YXRpb24gb2YgdW5rbm93biBmaWVsZHMgaW4gdGhlIHB1cmUgUHl0aG9uIGltcGxlbWVudGF0aW9uLiIiIgorCitfX2F1dGhvcl9fID0gJ2JvaGRhbmtAZ29vZ2xlLmNvbSAoQm9oZGFuIEtvdmFsKScKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgdW5pdHRlc3RfbXNldF9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9wYjIKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCB1bml0dGVzdF9wcm90bzNfYXJlbmFfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgYXBpX2ltcGxlbWVudGF0aW9uCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgZW5jb2RlcgorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IG1pc3NpbmdfZW51bV92YWx1ZXNfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgdGVzdF91dGlsCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgdHlwZV9jaGVja2VycworCisKK2NsYXNzIFVua25vd25GaWVsZHNUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgc2V0VXAoc2VsZik6CisgICAgc2VsZi5kZXNjcmlwdG9yID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcy5ERVNDUklQVE9SCisgICAgc2VsZi5hbGxfZmllbGRzID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgdGVzdF91dGlsLlNldEFsbEZpZWxkcyhzZWxmLmFsbF9maWVsZHMpCisgICAgc2VsZi5hbGxfZmllbGRzX2RhdGEgPSBzZWxmLmFsbF9maWVsZHMuU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIHNlbGYuZW1wdHlfbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlKCkKKyAgICBzZWxmLmVtcHR5X21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlbGYuYWxsX2ZpZWxkc19kYXRhKQorCisgIGRlZiB0ZXN0U2VyaWFsaXplKHNlbGYpOgorICAgIGRhdGEgPSBzZWxmLmVtcHR5X21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgIyBEb24ndCB1c2UgYXNzZXJ0RXF1YWwgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIGR1bXAgcmF3IGJpbmFyeSBkYXRhIHRvCisgICAgIyBzdGRvdXQuCisgICAgc2VsZi5hc3NlcnRUcnVlKGRhdGEgPT0gc2VsZi5hbGxfZmllbGRzX2RhdGEpCisKKyAgZGVmIHRlc3RTZXJpYWxpemVQcm90bzMoc2VsZik6CisgICAgIyBWZXJpZnkgdGhhdCBwcm90bzMgZG9lc24ndCBwcmVzZXJ2ZSB1bmtub3duIGZpZWxkcy4KKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcHJvdG8zX2FyZW5hX3BiMi5UZXN0RW1wdHlNZXNzYWdlKCkKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZWxmLmFsbF9maWVsZHNfZGF0YSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDAsIGxlbihtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpKQorCisgIGRlZiB0ZXN0Qnl0ZVNpemUoc2VsZik6CisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmFsbF9maWVsZHMuQnl0ZVNpemUoKSwgc2VsZi5lbXB0eV9tZXNzYWdlLkJ5dGVTaXplKCkpCisKKyAgZGVmIHRlc3RMaXN0RmllbGRzKHNlbGYpOgorICAgICMgTWFrZSBzdXJlIExpc3RGaWVsZHMgZG9lc24ndCByZXR1cm4gdW5rbm93biBmaWVsZHMuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBsZW4oc2VsZi5lbXB0eV9tZXNzYWdlLkxpc3RGaWVsZHMoKSkpCisKKyAgZGVmIHRlc3RTZXJpYWxpemVNZXNzYWdlU2V0V2lyZUZvcm1hdFVua25vd25FeHRlbnNpb24oc2VsZik6CisgICAgIyBDcmVhdGUgYSBtZXNzYWdlIHVzaW5nIHRoZSBtZXNzYWdlIHNldCB3aXJlIGZvcm1hdCB3aXRoIGFuIHVua25vd24KKyAgICAjIG1lc3NhZ2UuCisgICAgcmF3ID0gdW5pdHRlc3RfbXNldF9wYjIuUmF3TWVzc2FnZVNldCgpCisKKyAgICAjIEFkZCBhbiB1bmtub3duIGV4dGVuc2lvbi4KKyAgICBpdGVtID0gcmF3Lml0ZW0uYWRkKCkKKyAgICBpdGVtLnR5cGVfaWQgPSAxNTQ1MDA5CisgICAgbWVzc2FnZTEgPSB1bml0dGVzdF9tc2V0X3BiMi5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEoKQorICAgIG1lc3NhZ2UxLmkgPSAxMjM0NQorICAgIGl0ZW0ubWVzc2FnZSA9IG1lc3NhZ2UxLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKworICAgIHNlcmlhbGl6ZWQgPSByYXcuU2VyaWFsaXplVG9TdHJpbmcoKQorCisgICAgIyBQYXJzZSBtZXNzYWdlIHVzaW5nIHRoZSBtZXNzYWdlIHNldCB3aXJlIGZvcm1hdC4KKyAgICBwcm90byA9IHVuaXR0ZXN0X21zZXRfcGIyLlRlc3RNZXNzYWdlU2V0KCkKKyAgICBwcm90by5NZXJnZUZyb21TdHJpbmcoc2VyaWFsaXplZCkKKworICAgICMgVmVyaWZ5IHRoYXQgdGhlIHVua25vd24gZXh0ZW5zaW9uIGlzIHNlcmlhbGl6ZWQgdW5jaGFuZ2VkCisgICAgcmVzZXJpYWxpemVkID0gcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIG5ld19yYXcgPSB1bml0dGVzdF9tc2V0X3BiMi5SYXdNZXNzYWdlU2V0KCkKKyAgICBuZXdfcmF3Lk1lcmdlRnJvbVN0cmluZyhyZXNlcmlhbGl6ZWQpCisgICAgc2VsZi5hc3NlcnRFcXVhbChyYXcsIG5ld19yYXcpCisKKyAgIyBDKysgaW1wbGVtZW50YXRpb24gZm9yIHByb3RvMiBkb2VzIG5vdCBjdXJyZW50bHkgdGFrZSBpbnRvIGFjY291bnQgdW5rbm93bgorICAjIGZpZWxkcyB3aGVuIGNoZWNraW5nIGVxdWFsaXR5LgorICAjCisgICMgVE9ETyhoYWJlcm1hbik6IGZpeCB0aGlzLgorICBAYmFzZXRlc3QudW5pdHRlc3Quc2tpcElmKAorICAgICAgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSA9PSAnY3BwJyBhbmQgYXBpX2ltcGxlbWVudGF0aW9uLlZlcnNpb24oKSA9PSAyLAorICAgICAgJ0MrKyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBleHBvc2UgdW5rbm93biBmaWVsZHMgdG8gUHl0aG9uJykKKyAgZGVmIHRlc3RFcXVhbHMoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlKCkKKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZWxmLmFsbF9maWVsZHNfZGF0YSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuZW1wdHlfbWVzc2FnZSwgbWVzc2FnZSkKKworICAgIHNlbGYuYWxsX2ZpZWxkcy5DbGVhckZpZWxkKCdvcHRpb25hbF9zdHJpbmcnKQorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlbGYuYWxsX2ZpZWxkcy5TZXJpYWxpemVUb1N0cmluZygpKQorICAgIHNlbGYuYXNzZXJ0Tm90RXF1YWwoc2VsZi5lbXB0eV9tZXNzYWdlLCBtZXNzYWdlKQorCisKK0BiYXNldGVzdC51bml0dGVzdC5za2lwSWYoCisgICAgYXBpX2ltcGxlbWVudGF0aW9uLlR5cGUoKSA9PSAnY3BwJyBhbmQgYXBpX2ltcGxlbWVudGF0aW9uLlZlcnNpb24oKSA9PSAyLAorICAgICdDKysgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgZXhwb3NlIHVua25vd24gZmllbGRzIHRvIFB5dGhvbicpCitjbGFzcyBVbmtub3duRmllbGRzQWNjZXNzb3JzVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHNldFVwKHNlbGYpOgorICAgIHNlbGYuZGVzY3JpcHRvciA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuREVTQ1JJUFRPUgorICAgIHNlbGYuYWxsX2ZpZWxkcyA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMoKQorICAgIHRlc3RfdXRpbC5TZXRBbGxGaWVsZHMoc2VsZi5hbGxfZmllbGRzKQorICAgIHNlbGYuYWxsX2ZpZWxkc19kYXRhID0gc2VsZi5hbGxfZmllbGRzLlNlcmlhbGl6ZVRvU3RyaW5nKCkKKyAgICBzZWxmLmVtcHR5X21lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEVtcHR5TWVzc2FnZSgpCisgICAgc2VsZi5lbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZWxmLmFsbF9maWVsZHNfZGF0YSkKKyAgICBzZWxmLnVua25vd25fZmllbGRzID0gc2VsZi5lbXB0eV9tZXNzYWdlLl91bmtub3duX2ZpZWxkcworCisgIGRlZiBHZXRGaWVsZChzZWxmLCBuYW1lKToKKyAgICBmaWVsZF9kZXNjcmlwdG9yID0gc2VsZi5kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lW25hbWVdCisgICAgd2lyZV90eXBlID0gdHlwZV9jaGVja2Vycy5GSUVMRF9UWVBFX1RPX1dJUkVfVFlQRVtmaWVsZF9kZXNjcmlwdG9yLnR5cGVdCisgICAgZmllbGRfdGFnID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9kZXNjcmlwdG9yLm51bWJlciwgd2lyZV90eXBlKQorICAgIHJlc3VsdF9kaWN0ID0ge30KKyAgICBmb3IgdGFnX2J5dGVzLCB2YWx1ZSBpbiBzZWxmLnVua25vd25fZmllbGRzOgorICAgICAgaWYgdGFnX2J5dGVzID09IGZpZWxkX3RhZzoKKyAgICAgICAgZGVjb2RlciA9IHVuaXR0ZXN0X3BiMi5UZXN0QWxsVHlwZXMuX2RlY29kZXJzX2J5X3RhZ1t0YWdfYnl0ZXNdWzBdCisgICAgICAgIGRlY29kZXIodmFsdWUsIDAsIGxlbih2YWx1ZSksIHNlbGYuYWxsX2ZpZWxkcywgcmVzdWx0X2RpY3QpCisgICAgcmV0dXJuIHJlc3VsdF9kaWN0W2ZpZWxkX2Rlc2NyaXB0b3JdCisKKyAgZGVmIHRlc3RFbnVtKHNlbGYpOgorICAgIHZhbHVlID0gc2VsZi5HZXRGaWVsZCgnb3B0aW9uYWxfbmVzdGVkX2VudW0nKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5hbGxfZmllbGRzLm9wdGlvbmFsX25lc3RlZF9lbnVtLCB2YWx1ZSkKKworICBkZWYgdGVzdFJlcGVhdGVkRW51bShzZWxmKToKKyAgICB2YWx1ZSA9IHNlbGYuR2V0RmllbGQoJ3JlcGVhdGVkX25lc3RlZF9lbnVtJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuYWxsX2ZpZWxkcy5yZXBlYXRlZF9uZXN0ZWRfZW51bSwgdmFsdWUpCisKKyAgZGVmIHRlc3RWYXJpbnQoc2VsZik6CisgICAgdmFsdWUgPSBzZWxmLkdldEZpZWxkKCdvcHRpb25hbF9pbnQzMicpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmFsbF9maWVsZHMub3B0aW9uYWxfaW50MzIsIHZhbHVlKQorCisgIGRlZiB0ZXN0Rml4ZWQzMihzZWxmKToKKyAgICB2YWx1ZSA9IHNlbGYuR2V0RmllbGQoJ29wdGlvbmFsX2ZpeGVkMzInKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5hbGxfZmllbGRzLm9wdGlvbmFsX2ZpeGVkMzIsIHZhbHVlKQorCisgIGRlZiB0ZXN0Rml4ZWQ2NChzZWxmKToKKyAgICB2YWx1ZSA9IHNlbGYuR2V0RmllbGQoJ29wdGlvbmFsX2ZpeGVkNjQnKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5hbGxfZmllbGRzLm9wdGlvbmFsX2ZpeGVkNjQsIHZhbHVlKQorCisgIGRlZiB0ZXN0TGVuZ3RoRGVsaW1pdGVkKHNlbGYpOgorICAgIHZhbHVlID0gc2VsZi5HZXRGaWVsZCgnb3B0aW9uYWxfc3RyaW5nJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuYWxsX2ZpZWxkcy5vcHRpb25hbF9zdHJpbmcsIHZhbHVlKQorCisgIGRlZiB0ZXN0R3JvdXAoc2VsZik6CisgICAgdmFsdWUgPSBzZWxmLkdldEZpZWxkKCdvcHRpb25hbGdyb3VwJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuYWxsX2ZpZWxkcy5vcHRpb25hbGdyb3VwLCB2YWx1ZSkKKworICBkZWYgdGVzdENvcHlGcm9tKHNlbGYpOgorICAgIG1lc3NhZ2UgPSB1bml0dGVzdF9wYjIuVGVzdEVtcHR5TWVzc2FnZSgpCisgICAgbWVzc2FnZS5Db3B5RnJvbShzZWxmLmVtcHR5X21lc3NhZ2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLnVua25vd25fZmllbGRzLCBtZXNzYWdlLl91bmtub3duX2ZpZWxkcykKKworICBkZWYgdGVzdE1lcmdlRnJvbShzZWxmKToKKyAgICBtZXNzYWdlID0gdW5pdHRlc3RfcGIyLlRlc3RBbGxUeXBlcygpCisgICAgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiA9IDEKKyAgICBtZXNzYWdlLm9wdGlvbmFsX3VpbnQzMiA9IDIKKyAgICBzb3VyY2UgPSB1bml0dGVzdF9wYjIuVGVzdEVtcHR5TWVzc2FnZSgpCisgICAgc291cmNlLlBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisKKyAgICBtZXNzYWdlLkNsZWFyRmllbGQoJ29wdGlvbmFsX2ludDMyJykKKyAgICBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ID0gMworICAgIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyID0gNAorICAgIGRlc3RpbmF0aW9uID0gdW5pdHRlc3RfcGIyLlRlc3RFbXB0eU1lc3NhZ2UoKQorICAgIGRlc3RpbmF0aW9uLlBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCkpCisgICAgdW5rbm93bl9maWVsZHMgPSBkZXN0aW5hdGlvbi5fdW5rbm93bl9maWVsZHNbOl0KKworICAgIGRlc3RpbmF0aW9uLk1lcmdlRnJvbShzb3VyY2UpCisgICAgc2VsZi5hc3NlcnRFcXVhbCh1bmtub3duX2ZpZWxkcyArIHNvdXJjZS5fdW5rbm93bl9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbi5fdW5rbm93bl9maWVsZHMpCisKKyAgZGVmIHRlc3RDbGVhcihzZWxmKToKKyAgICBzZWxmLmVtcHR5X21lc3NhZ2UuQ2xlYXIoKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMCwgbGVuKHNlbGYuZW1wdHlfbWVzc2FnZS5fdW5rbm93bl9maWVsZHMpKQorCisgIGRlZiB0ZXN0VW5rbm93bkV4dGVuc2lvbnMoc2VsZik6CisgICAgbWVzc2FnZSA9IHVuaXR0ZXN0X3BiMi5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMoKQorICAgIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlbGYuYWxsX2ZpZWxkc19kYXRhKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5lbXB0eV9tZXNzYWdlLl91bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuX3Vua25vd25fZmllbGRzKQorCisKKworQGJhc2V0ZXN0LnVuaXR0ZXN0LnNraXBJZigKKyAgICBhcGlfaW1wbGVtZW50YXRpb24uVHlwZSgpID09ICdjcHAnIGFuZCBhcGlfaW1wbGVtZW50YXRpb24uVmVyc2lvbigpID09IDIsCisgICAgJ0MrKyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBleHBvc2UgdW5rbm93biBmaWVsZHMgdG8gUHl0aG9uJykKK2NsYXNzIFVua25vd25FbnVtVmFsdWVzVGVzdChiYXNldGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHNldFVwKHNlbGYpOgorICAgIHNlbGYuZGVzY3JpcHRvciA9IG1pc3NpbmdfZW51bV92YWx1ZXNfcGIyLlRlc3RFbnVtVmFsdWVzLkRFU0NSSVBUT1IKKworICAgIHNlbGYubWVzc2FnZSA9IG1pc3NpbmdfZW51bV92YWx1ZXNfcGIyLlRlc3RFbnVtVmFsdWVzKCkKKyAgICBzZWxmLm1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX2VudW0gPSAoCisgICAgICBtaXNzaW5nX2VudW1fdmFsdWVzX3BiMi5UZXN0RW51bVZhbHVlcy5aRVJPKQorICAgIHNlbGYubWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bS5leHRlbmQoWworICAgICAgbWlzc2luZ19lbnVtX3ZhbHVlc19wYjIuVGVzdEVudW1WYWx1ZXMuWkVSTywKKyAgICAgIG1pc3NpbmdfZW51bV92YWx1ZXNfcGIyLlRlc3RFbnVtVmFsdWVzLk9ORSwKKyAgICAgIF0pCisgICAgc2VsZi5tZXNzYWdlLnBhY2tlZF9uZXN0ZWRfZW51bS5leHRlbmQoWworICAgICAgbWlzc2luZ19lbnVtX3ZhbHVlc19wYjIuVGVzdEVudW1WYWx1ZXMuWkVSTywKKyAgICAgIG1pc3NpbmdfZW51bV92YWx1ZXNfcGIyLlRlc3RFbnVtVmFsdWVzLk9ORSwKKyAgICAgIF0pCisgICAgc2VsZi5tZXNzYWdlX2RhdGEgPSBzZWxmLm1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoKQorICAgIHNlbGYubWlzc2luZ19tZXNzYWdlID0gbWlzc2luZ19lbnVtX3ZhbHVlc19wYjIuVGVzdE1pc3NpbmdFbnVtVmFsdWVzKCkKKyAgICBzZWxmLm1pc3NpbmdfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VsZi5tZXNzYWdlX2RhdGEpCisgICAgc2VsZi51bmtub3duX2ZpZWxkcyA9IHNlbGYubWlzc2luZ19tZXNzYWdlLl91bmtub3duX2ZpZWxkcworCisgIGRlZiBHZXRGaWVsZChzZWxmLCBuYW1lKToKKyAgICBmaWVsZF9kZXNjcmlwdG9yID0gc2VsZi5kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lW25hbWVdCisgICAgd2lyZV90eXBlID0gdHlwZV9jaGVja2Vycy5GSUVMRF9UWVBFX1RPX1dJUkVfVFlQRVtmaWVsZF9kZXNjcmlwdG9yLnR5cGVdCisgICAgZmllbGRfdGFnID0gZW5jb2Rlci5UYWdCeXRlcyhmaWVsZF9kZXNjcmlwdG9yLm51bWJlciwgd2lyZV90eXBlKQorICAgIHJlc3VsdF9kaWN0ID0ge30KKyAgICBmb3IgdGFnX2J5dGVzLCB2YWx1ZSBpbiBzZWxmLnVua25vd25fZmllbGRzOgorICAgICAgaWYgdGFnX2J5dGVzID09IGZpZWxkX3RhZzoKKyAgICAgICAgZGVjb2RlciA9IG1pc3NpbmdfZW51bV92YWx1ZXNfcGIyLlRlc3RFbnVtVmFsdWVzLl9kZWNvZGVyc19ieV90YWdbCisgICAgICAgICAgdGFnX2J5dGVzXVswXQorICAgICAgICBkZWNvZGVyKHZhbHVlLCAwLCBsZW4odmFsdWUpLCBzZWxmLm1lc3NhZ2UsIHJlc3VsdF9kaWN0KQorICAgIHJldHVybiByZXN1bHRfZGljdFtmaWVsZF9kZXNjcmlwdG9yXQorCisgIGRlZiB0ZXN0VW5rbm93bkVudW1WYWx1ZShzZWxmKToKKyAgICBzZWxmLmFzc2VydEZhbHNlKHNlbGYubWlzc2luZ19tZXNzYWdlLkhhc0ZpZWxkKCdvcHRpb25hbF9uZXN0ZWRfZW51bScpKQorICAgIHZhbHVlID0gc2VsZi5HZXRGaWVsZCgnb3B0aW9uYWxfbmVzdGVkX2VudW0nKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5tZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9lbnVtLCB2YWx1ZSkKKworICBkZWYgdGVzdFVua25vd25SZXBlYXRlZEVudW1WYWx1ZShzZWxmKToKKyAgICB2YWx1ZSA9IHNlbGYuR2V0RmllbGQoJ3JlcGVhdGVkX25lc3RlZF9lbnVtJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSwgdmFsdWUpCisKKyAgZGVmIHRlc3RVbmtub3duUGFja2VkRW51bVZhbHVlKHNlbGYpOgorICAgIHZhbHVlID0gc2VsZi5HZXRGaWVsZCgncGFja2VkX25lc3RlZF9lbnVtJykKKyAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYubWVzc2FnZS5wYWNrZWRfbmVzdGVkX2VudW0sIHZhbHVlKQorCisgIGRlZiB0ZXN0Um91bmRUcmlwKHNlbGYpOgorICAgIG5ld19tZXNzYWdlID0gbWlzc2luZ19lbnVtX3ZhbHVlc19wYjIuVGVzdEVudW1WYWx1ZXMoKQorICAgIG5ld19tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZWxmLm1pc3NpbmdfbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5tZXNzYWdlLCBuZXdfbWVzc2FnZSkKKworCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvd2lyZV9mb3JtYXQucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3dpcmVfZm9ybWF0LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjg4M2Y1MjUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3dpcmVfZm9ybWF0LnB5CkBAIC0wLDAgKzEsMjY4IEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyIiIkNvbnN0YW50cyBhbmQgc3RhdGljIGZ1bmN0aW9ucyB0byBzdXBwb3J0IHByb3RvY29sIGJ1ZmZlciB3aXJlIGZvcm1hdC4iIiIKKworX19hdXRob3JfXyA9ICdyb2JpbnNvbkBnb29nbGUuY29tIChXaWxsIFJvYmluc29uKScKKworaW1wb3J0IHN0cnVjdAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3IKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBtZXNzYWdlCisKKworVEFHX1RZUEVfQklUUyA9IDMgICMgTnVtYmVyIG9mIGJpdHMgdXNlZCB0byBob2xkIHR5cGUgaW5mbyBpbiBhIHByb3RvIHRhZy4KK1RBR19UWVBFX01BU0sgPSAoMSA8PCBUQUdfVFlQRV9CSVRTKSAtIDEgICMgMHg3CisKKyMgVGhlc2UgbnVtYmVycyBpZGVudGlmeSB0aGUgd2lyZSB0eXBlIG9mIGEgcHJvdG9jb2wgYnVmZmVyIHZhbHVlLgorIyBXZSB1c2UgdGhlIGxlYXN0LXNpZ25pZmljYW50IFRBR19UWVBFX0JJVFMgYml0cyBvZiB0aGUgdmFyaW50LWVuY29kZWQKKyMgdGFnLWFuZC10eXBlIHRvIHN0b3JlIG9uZSBvZiB0aGVzZSBXSVJFVFlQRV8qIGNvbnN0YW50cy4KKyMgVGhlc2UgdmFsdWVzIG11c3QgbWF0Y2ggV2lyZVR5cGUgZW51bSBpbiBnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaC4KK1dJUkVUWVBFX1ZBUklOVCA9IDAKK1dJUkVUWVBFX0ZJWEVENjQgPSAxCitXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEID0gMgorV0lSRVRZUEVfU1RBUlRfR1JPVVAgPSAzCitXSVJFVFlQRV9FTkRfR1JPVVAgPSA0CitXSVJFVFlQRV9GSVhFRDMyID0gNQorX1dJUkVUWVBFX01BWCA9IDUKKworCisjIEJvdW5kcyBmb3IgdmFyaW91cyBpbnRlZ2VyIHR5cGVzLgorSU5UMzJfTUFYID0gaW50KCgxIDw8IDMxKSAtIDEpCitJTlQzMl9NSU4gPSBpbnQoLSgxIDw8IDMxKSkKK1VJTlQzMl9NQVggPSAoMSA8PCAzMikgLSAxCisKK0lOVDY0X01BWCA9ICgxIDw8IDYzKSAtIDEKK0lOVDY0X01JTiA9IC0oMSA8PCA2MykKK1VJTlQ2NF9NQVggPSAoMSA8PCA2NCkgLSAxCisKKyMgInN0cnVjdCIgZm9ybWF0IHN0cmluZ3MgdGhhdCB3aWxsIGVuY29kZS9kZWNvZGUgdGhlIHNwZWNpZmllZCBmb3JtYXRzLgorRk9STUFUX1VJTlQzMl9MSVRUTEVfRU5ESUFOID0gJzxJJworRk9STUFUX1VJTlQ2NF9MSVRUTEVfRU5ESUFOID0gJzxRJworRk9STUFUX0ZMT0FUX0xJVFRMRV9FTkRJQU4gPSAnPGYnCitGT1JNQVRfRE9VQkxFX0xJVFRMRV9FTkRJQU4gPSAnPGQnCisKKworIyBXZSdsbCBoYXZlIHRvIHByb3ZpZGUgYWx0ZXJuYXRlIGltcGxlbWVudGF0aW9ucyBvZiBBcHBlbmRMaXR0bGVFbmRpYW4qKCkgb24KKyMgYW55IGFyY2hpdGVjdHVyZXMgd2hlcmUgdGhlc2UgY2hlY2tzIGZhaWwuCitpZiBzdHJ1Y3QuY2FsY3NpemUoRk9STUFUX1VJTlQzMl9MSVRUTEVfRU5ESUFOKSAhPSA0OgorICByYWlzZSBBc3NlcnRpb25FcnJvcignRm9ybWF0ICJJIiBpcyBub3QgYSAzMi1iaXQgbnVtYmVyLicpCitpZiBzdHJ1Y3QuY2FsY3NpemUoRk9STUFUX1VJTlQ2NF9MSVRUTEVfRU5ESUFOKSAhPSA4OgorICByYWlzZSBBc3NlcnRpb25FcnJvcignRm9ybWF0ICJRIiBpcyBub3QgYSA2NC1iaXQgbnVtYmVyLicpCisKKworZGVmIFBhY2tUYWcoZmllbGRfbnVtYmVyLCB3aXJlX3R5cGUpOgorICAiIiJSZXR1cm5zIGFuIHVuc2lnbmVkIDMyLWJpdCBpbnRlZ2VyIHRoYXQgZW5jb2RlcyB0aGUgZmllbGQgbnVtYmVyIGFuZAorICB3aXJlIHR5cGUgaW5mb3JtYXRpb24gaW4gc3RhbmRhcmQgcHJvdG9jb2wgbWVzc2FnZSB3aXJlIGZvcm1hdC4KKworICBBcmdzOgorICAgIGZpZWxkX251bWJlcjogRXhwZWN0ZWQgdG8gYmUgYW4gaW50ZWdlciBpbiB0aGUgcmFuZ2UgWzEsIDEgPDwgMjkpCisgICAgd2lyZV90eXBlOiBPbmUgb2YgdGhlIFdJUkVUWVBFXyogY29uc3RhbnRzLgorICAiIiIKKyAgaWYgbm90IDAgPD0gd2lyZV90eXBlIDw9IF9XSVJFVFlQRV9NQVg6CisgICAgcmFpc2UgbWVzc2FnZS5FbmNvZGVFcnJvcignVW5rbm93biB3aXJlIHR5cGU6ICVkJyAlIHdpcmVfdHlwZSkKKyAgcmV0dXJuIChmaWVsZF9udW1iZXIgPDwgVEFHX1RZUEVfQklUUykgfCB3aXJlX3R5cGUKKworCitkZWYgVW5wYWNrVGFnKHRhZyk6CisgICIiIlRoZSBpbnZlcnNlIG9mIFBhY2tUYWcoKS4gIEdpdmVuIGFuIHVuc2lnbmVkIDMyLWJpdCBudW1iZXIsCisgIHJldHVybnMgYSAoZmllbGRfbnVtYmVyLCB3aXJlX3R5cGUpIHR1cGxlLgorICAiIiIKKyAgcmV0dXJuICh0YWcgPj4gVEFHX1RZUEVfQklUUyksICh0YWcgJiBUQUdfVFlQRV9NQVNLKQorCisKK2RlZiBaaWdaYWdFbmNvZGUodmFsdWUpOgorICAiIiJaaWdaYWcgVHJhbnNmb3JtOiAgRW5jb2RlcyBzaWduZWQgaW50ZWdlcnMgc28gdGhhdCB0aGV5IGNhbiBiZQorICBlZmZlY3RpdmVseSB1c2VkIHdpdGggdmFyaW50IGVuY29kaW5nLiAgU2VlIHdpcmVfZm9ybWF0LmggZm9yCisgIG1vcmUgZGV0YWlscy4KKyAgIiIiCisgIGlmIHZhbHVlID49IDA6CisgICAgcmV0dXJuIHZhbHVlIDw8IDEKKyAgcmV0dXJuICh2YWx1ZSA8PCAxKSBeICh+MCkKKworCitkZWYgWmlnWmFnRGVjb2RlKHZhbHVlKToKKyAgIiIiSW52ZXJzZSBvZiBaaWdaYWdFbmNvZGUoKS4iIiIKKyAgaWYgbm90IHZhbHVlICYgMHgxOgorICAgIHJldHVybiB2YWx1ZSA+PiAxCisgIHJldHVybiAodmFsdWUgPj4gMSkgXiAofjApCisKKworCisjIFRoZSAqQnl0ZVNpemUoKSBmdW5jdGlvbnMgYmVsb3cgcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8KKyMgc2VyaWFsaXplICJmaWVsZCBudW1iZXIgKyB0eXBlIiBpbmZvcm1hdGlvbiBhbmQgdGhlbiBzZXJpYWxpemUgdGhlIHZhbHVlLgorCisKK2RlZiBJbnQzMkJ5dGVTaXplKGZpZWxkX251bWJlciwgaW50MzIpOgorICByZXR1cm4gSW50NjRCeXRlU2l6ZShmaWVsZF9udW1iZXIsIGludDMyKQorCisKK2RlZiBJbnQzMkJ5dGVTaXplTm9UYWcoaW50MzIpOgorICByZXR1cm4gX1ZhclVJbnQ2NEJ5dGVTaXplTm9UYWcoMHhmZmZmZmZmZmZmZmZmZmZmICYgaW50MzIpCisKKworZGVmIEludDY0Qnl0ZVNpemUoZmllbGRfbnVtYmVyLCBpbnQ2NCk6CisgICMgSGF2ZSB0byBjb252ZXJ0IHRvIHVpbnQgYmVmb3JlIGNhbGxpbmcgVUludDY0Qnl0ZVNpemUoKS4KKyAgcmV0dXJuIFVJbnQ2NEJ5dGVTaXplKGZpZWxkX251bWJlciwgMHhmZmZmZmZmZmZmZmZmZmZmICYgaW50NjQpCisKKworZGVmIFVJbnQzMkJ5dGVTaXplKGZpZWxkX251bWJlciwgdWludDMyKToKKyAgcmV0dXJuIFVJbnQ2NEJ5dGVTaXplKGZpZWxkX251bWJlciwgdWludDMyKQorCisKK2RlZiBVSW50NjRCeXRlU2l6ZShmaWVsZF9udW1iZXIsIHVpbnQ2NCk6CisgIHJldHVybiBUYWdCeXRlU2l6ZShmaWVsZF9udW1iZXIpICsgX1ZhclVJbnQ2NEJ5dGVTaXplTm9UYWcodWludDY0KQorCisKK2RlZiBTSW50MzJCeXRlU2l6ZShmaWVsZF9udW1iZXIsIGludDMyKToKKyAgcmV0dXJuIFVJbnQzMkJ5dGVTaXplKGZpZWxkX251bWJlciwgWmlnWmFnRW5jb2RlKGludDMyKSkKKworCitkZWYgU0ludDY0Qnl0ZVNpemUoZmllbGRfbnVtYmVyLCBpbnQ2NCk6CisgIHJldHVybiBVSW50NjRCeXRlU2l6ZShmaWVsZF9udW1iZXIsIFppZ1phZ0VuY29kZShpbnQ2NCkpCisKKworZGVmIEZpeGVkMzJCeXRlU2l6ZShmaWVsZF9udW1iZXIsIGZpeGVkMzIpOgorICByZXR1cm4gVGFnQnl0ZVNpemUoZmllbGRfbnVtYmVyKSArIDQKKworCitkZWYgRml4ZWQ2NEJ5dGVTaXplKGZpZWxkX251bWJlciwgZml4ZWQ2NCk6CisgIHJldHVybiBUYWdCeXRlU2l6ZShmaWVsZF9udW1iZXIpICsgOAorCisKK2RlZiBTRml4ZWQzMkJ5dGVTaXplKGZpZWxkX251bWJlciwgc2ZpeGVkMzIpOgorICByZXR1cm4gVGFnQnl0ZVNpemUoZmllbGRfbnVtYmVyKSArIDQKKworCitkZWYgU0ZpeGVkNjRCeXRlU2l6ZShmaWVsZF9udW1iZXIsIHNmaXhlZDY0KToKKyAgcmV0dXJuIFRhZ0J5dGVTaXplKGZpZWxkX251bWJlcikgKyA4CisKKworZGVmIEZsb2F0Qnl0ZVNpemUoZmllbGRfbnVtYmVyLCBmbHQpOgorICByZXR1cm4gVGFnQnl0ZVNpemUoZmllbGRfbnVtYmVyKSArIDQKKworCitkZWYgRG91YmxlQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBkb3VibGUpOgorICByZXR1cm4gVGFnQnl0ZVNpemUoZmllbGRfbnVtYmVyKSArIDgKKworCitkZWYgQm9vbEJ5dGVTaXplKGZpZWxkX251bWJlciwgYik6CisgIHJldHVybiBUYWdCeXRlU2l6ZShmaWVsZF9udW1iZXIpICsgMQorCisKK2RlZiBFbnVtQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBlbnVtKToKKyAgcmV0dXJuIFVJbnQzMkJ5dGVTaXplKGZpZWxkX251bWJlciwgZW51bSkKKworCitkZWYgU3RyaW5nQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBzdHJpbmcpOgorICByZXR1cm4gQnl0ZXNCeXRlU2l6ZShmaWVsZF9udW1iZXIsIHN0cmluZy5lbmNvZGUoJ3V0Zi04JykpCisKKworZGVmIEJ5dGVzQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBiKToKKyAgcmV0dXJuIChUYWdCeXRlU2l6ZShmaWVsZF9udW1iZXIpCisgICAgICAgICAgKyBfVmFyVUludDY0Qnl0ZVNpemVOb1RhZyhsZW4oYikpCisgICAgICAgICAgKyBsZW4oYikpCisKKworZGVmIEdyb3VwQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBtZXNzYWdlKToKKyAgcmV0dXJuICgyICogVGFnQnl0ZVNpemUoZmllbGRfbnVtYmVyKSAgIyBTVEFSVCBhbmQgRU5EIGdyb3VwLgorICAgICAgICAgICsgbWVzc2FnZS5CeXRlU2l6ZSgpKQorCisKK2RlZiBNZXNzYWdlQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBtZXNzYWdlKToKKyAgcmV0dXJuIChUYWdCeXRlU2l6ZShmaWVsZF9udW1iZXIpCisgICAgICAgICAgKyBfVmFyVUludDY0Qnl0ZVNpemVOb1RhZyhtZXNzYWdlLkJ5dGVTaXplKCkpCisgICAgICAgICAgKyBtZXNzYWdlLkJ5dGVTaXplKCkpCisKKworZGVmIE1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoZmllbGRfbnVtYmVyLCBtc2cpOgorICAjIEZpcnN0IGNvbXB1dGUgdGhlIHNpemVzIG9mIHRoZSB0YWdzLgorICAjIFRoZXJlIGFyZSAyIHRhZ3MgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBvZiB0aGUgcmVwZWF0ZWQgZ3JvdXAsIHRoYXQKKyAgIyBpcyBmaWVsZCBudW1iZXIgMSwgb25lIHdpdGggZmllbGQgbnVtYmVyIDIgKHR5cGVfaWQpIGFuZCBvbmUgd2l0aCBmaWVsZAorICAjIG51bWJlciAzIChtZXNzYWdlKS4KKyAgdG90YWxfc2l6ZSA9ICgyICogVGFnQnl0ZVNpemUoMSkgKyBUYWdCeXRlU2l6ZSgyKSArIFRhZ0J5dGVTaXplKDMpKQorCisgICMgQWRkIHRoZSBudW1iZXIgb2YgYnl0ZXMgZm9yIHR5cGVfaWQuCisgIHRvdGFsX3NpemUgKz0gX1ZhclVJbnQ2NEJ5dGVTaXplTm9UYWcoZmllbGRfbnVtYmVyKQorCisgIG1lc3NhZ2Vfc2l6ZSA9IG1zZy5CeXRlU2l6ZSgpCisKKyAgIyBUaGUgbnVtYmVyIG9mIGJ5dGVzIGZvciBlbmNvZGluZyB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlLgorICB0b3RhbF9zaXplICs9IF9WYXJVSW50NjRCeXRlU2l6ZU5vVGFnKG1lc3NhZ2Vfc2l6ZSkKKworICAjIFRoZSBzaXplIG9mIHRoZSBtZXNzYWdlLgorICB0b3RhbF9zaXplICs9IG1lc3NhZ2Vfc2l6ZQorICByZXR1cm4gdG90YWxfc2l6ZQorCisKK2RlZiBUYWdCeXRlU2l6ZShmaWVsZF9udW1iZXIpOgorICAiIiJSZXR1cm5zIHRoZSBieXRlcyByZXF1aXJlZCB0byBzZXJpYWxpemUgYSB0YWcgd2l0aCB0aGlzIGZpZWxkIG51bWJlci4iIiIKKyAgIyBKdXN0IHBhc3MgaW4gdHlwZSAwLCBzaW5jZSB0aGUgdHlwZSB3b24ndCBhZmZlY3QgdGhlIHRhZyt0eXBlIHNpemUuCisgIHJldHVybiBfVmFyVUludDY0Qnl0ZVNpemVOb1RhZyhQYWNrVGFnKGZpZWxkX251bWJlciwgMCkpCisKKworIyBQcml2YXRlIGhlbHBlciBmdW5jdGlvbiBmb3IgdGhlICpCeXRlU2l6ZSgpIGZ1bmN0aW9ucyBhYm92ZS4KKworZGVmIF9WYXJVSW50NjRCeXRlU2l6ZU5vVGFnKHVpbnQ2NCk6CisgICIiIlJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzZXJpYWxpemUgYSBzaW5nbGUgdmFyaW50CisgIHVzaW5nIGJvdW5kYXJ5IHZhbHVlIGNvbXBhcmlzb25zLiAodW5yb2xsZWQgbG9vcCBvcHRpbWl6YXRpb24gLVdQaWVyY2UpCisgIHVpbnQ2NCBtdXN0IGJlIHVuc2lnbmVkLgorICAiIiIKKyAgaWYgdWludDY0IDw9IDB4N2Y6IHJldHVybiAxCisgIGlmIHVpbnQ2NCA8PSAweDNmZmY6IHJldHVybiAyCisgIGlmIHVpbnQ2NCA8PSAweDFmZmZmZjogcmV0dXJuIDMKKyAgaWYgdWludDY0IDw9IDB4ZmZmZmZmZjogcmV0dXJuIDQKKyAgaWYgdWludDY0IDw9IDB4N2ZmZmZmZmZmOiByZXR1cm4gNQorICBpZiB1aW50NjQgPD0gMHgzZmZmZmZmZmZmZjogcmV0dXJuIDYKKyAgaWYgdWludDY0IDw9IDB4MWZmZmZmZmZmZmZmZjogcmV0dXJuIDcKKyAgaWYgdWludDY0IDw9IDB4ZmZmZmZmZmZmZmZmZmY6IHJldHVybiA4CisgIGlmIHVpbnQ2NCA8PSAweDdmZmZmZmZmZmZmZmZmZmY6IHJldHVybiA5CisgIGlmIHVpbnQ2NCA+IFVJTlQ2NF9NQVg6CisgICAgcmFpc2UgbWVzc2FnZS5FbmNvZGVFcnJvcignVmFsdWUgb3V0IG9mIHJhbmdlOiAlZCcgJSB1aW50NjQpCisgIHJldHVybiAxMAorCisKK05PTl9QQUNLQUJMRV9UWVBFUyA9ICgKKyAgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9TVFJJTkcsCisgIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfR1JPVVAsCisgIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfTUVTU0FHRSwKKyAgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9CWVRFUworKQorCisKK2RlZiBJc1R5cGVQYWNrYWJsZShmaWVsZF90eXBlKToKKyAgIiIiUmV0dXJuIHRydWUgaWZmIHBhY2thYmxlID0gdHJ1ZSBpcyB2YWxpZCBmb3IgZmllbGRzIG9mIHRoaXMgdHlwZS4KKworICBBcmdzOgorICAgIGZpZWxkX3R5cGU6IGEgRmllbGREZXNjcmlwdG9yOjpUeXBlIHZhbHVlLgorCisgIFJldHVybnM6CisgICAgVHJ1ZSBpZmYgZmllbGRzIG9mIHRoaXMgdHlwZSBhcmUgcGFja2FibGUuCisgICIiIgorICByZXR1cm4gZmllbGRfdHlwZSBub3QgaW4gTk9OX1BBQ0tBQkxFX1RZUEVTCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3dpcmVfZm9ybWF0X3Rlc3QucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL3dpcmVfZm9ybWF0X3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZjM5MDM1YwotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvd2lyZV9mb3JtYXRfdGVzdC5weQpAQCAtMCwwICsxLDI1MyBAQAorIyEgL3Vzci9iaW4vcHl0aG9uCisjCisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyIiIlRlc3QgZm9yIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC53aXJlX2Zvcm1hdC4iIiIKKworX19hdXRob3JfXyA9ICdyb2JpbnNvbkBnb29nbGUuY29tIChXaWxsIFJvYmluc29uKScKKworZnJvbSBnb29nbGUuYXBwdXRpbHMgaW1wb3J0IGJhc2V0ZXN0Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgbWVzc2FnZQorZnJvbSBnb29nbGUucHJvdG9idWYuaW50ZXJuYWwgaW1wb3J0IHdpcmVfZm9ybWF0CisKKworY2xhc3MgV2lyZUZvcm1hdFRlc3QoYmFzZXRlc3QuVGVzdENhc2UpOgorCisgIGRlZiB0ZXN0UGFja1RhZyhzZWxmKToKKyAgICBmaWVsZF9udW1iZXIgPSAweGFiYworICAgIHRhZ190eXBlID0gMgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoKGZpZWxkX251bWJlciA8PCAzKSB8IHRhZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgd2lyZV9mb3JtYXQuUGFja1RhZyhmaWVsZF9udW1iZXIsIHRhZ190eXBlKSkKKyAgICBQYWNrVGFnID0gd2lyZV9mb3JtYXQuUGFja1RhZworICAgICMgTnVtYmVyIHRvbyBoaWdoLgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKG1lc3NhZ2UuRW5jb2RlRXJyb3IsIFBhY2tUYWcsIGZpZWxkX251bWJlciwgNikKKyAgICAjIE51bWJlciB0b28gbG93LgorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKG1lc3NhZ2UuRW5jb2RlRXJyb3IsIFBhY2tUYWcsIGZpZWxkX251bWJlciwgLTEpCisKKyAgZGVmIHRlc3RVbnBhY2tUYWcoc2VsZik6CisgICAgIyBUZXN0IGZpZWxkIG51bWJlcnMgdGhhdCB3aWxsIHJlcXVpcmUgdmFyaW91cyB2YXJpbnQgc2l6ZXMuCisgICAgZm9yIGV4cGVjdGVkX2ZpZWxkX251bWJlciBpbiAoMSwgMTUsIDE2LCAyMDQ3LCAyMDQ4KToKKyAgICAgIGZvciBleHBlY3RlZF93aXJlX3R5cGUgaW4gcmFuZ2UoNik6ICAjIEhpZ2hlc3QtbnVtYmVyZWQgd2lyZXR5cGUgaXMgNS4KKyAgICAgICAgZmllbGRfbnVtYmVyLCB3aXJlX3R5cGUgPSB3aXJlX2Zvcm1hdC5VbnBhY2tUYWcoCisgICAgICAgICAgICB3aXJlX2Zvcm1hdC5QYWNrVGFnKGV4cGVjdGVkX2ZpZWxkX251bWJlciwgZXhwZWN0ZWRfd2lyZV90eXBlKSkKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChleHBlY3RlZF9maWVsZF9udW1iZXIsIGZpZWxkX251bWJlcikKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChleHBlY3RlZF93aXJlX3R5cGUsIHdpcmVfdHlwZSkKKworICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgd2lyZV9mb3JtYXQuVW5wYWNrVGFnLCBOb25lKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgd2lyZV9mb3JtYXQuVW5wYWNrVGFnLCAnYWJjJykKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHdpcmVfZm9ybWF0LlVucGFja1RhZywgMC4wKQorICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgd2lyZV9mb3JtYXQuVW5wYWNrVGFnLCBvYmplY3QoKSkKKworICBkZWYgdGVzdFppZ1phZ0VuY29kZShzZWxmKToKKyAgICBaID0gd2lyZV9mb3JtYXQuWmlnWmFnRW5jb2RlCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBaKDApKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMSwgWigtMSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBaKDEpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMywgWigtMikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0LCBaKDIpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMHhmZmZmZmZmZSwgWigweDdmZmZmZmZmKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKDB4ZmZmZmZmZmYsIFooLTB4ODAwMDAwMDApKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMHhmZmZmZmZmZmZmZmZmZmZlLCBaKDB4N2ZmZmZmZmZmZmZmZmZmZikpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgweGZmZmZmZmZmZmZmZmZmZmYsIFooLTB4ODAwMDAwMDAwMDAwMDAwMCkpCisKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIFosIE5vbmUpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBaLCAnYWJjZCcpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBaLCAwLjApCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBaLCBvYmplY3QoKSkKKworICBkZWYgdGVzdFppZ1phZ0RlY29kZShzZWxmKToKKyAgICBaID0gd2lyZV9mb3JtYXQuWmlnWmFnRGVjb2RlCisgICAgc2VsZi5hc3NlcnRFcXVhbCgwLCBaKDApKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoLTEsIFooMSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgxLCBaKDIpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoLTIsIFooMykpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyLCBaKDQpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMHg3ZmZmZmZmZiwgWigweGZmZmZmZmZlKSkKKyAgICBzZWxmLmFzc2VydEVxdWFsKC0weDgwMDAwMDAwLCBaKDB4ZmZmZmZmZmYpKQorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMHg3ZmZmZmZmZmZmZmZmZmZmLCBaKDB4ZmZmZmZmZmZmZmZmZmZmZSkpCisgICAgc2VsZi5hc3NlcnRFcXVhbCgtMHg4MDAwMDAwMDAwMDAwMDAwLCBaKDB4ZmZmZmZmZmZmZmZmZmZmZikpCisKKyAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIFosIE5vbmUpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBaLCAnYWJjZCcpCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBaLCAwLjApCisgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBaLCBvYmplY3QoKSkKKworICBkZWYgTnVtZXJpY0J5dGVTaXplVGVzdEhlbHBlcihzZWxmLCBieXRlX3NpemVfZm4sIHZhbHVlLCBleHBlY3RlZF92YWx1ZV9zaXplKToKKyAgICAjIFVzZSBmaWVsZCBudW1iZXJzIHRoYXQgY2F1c2UgdmFyaW91cyBieXRlIHNpemVzIGZvciB0aGUgdGFnIGluZm9ybWF0aW9uLgorICAgIGZvciBmaWVsZF9udW1iZXIsIHRhZ19ieXRlcyBpbiAoKDE1LCAxKSwgKDE2LCAyKSwgKDIwNDcsIDIpLCAoMjA0OCwgMykpOgorICAgICAgZXhwZWN0ZWRfc2l6ZSA9IGV4cGVjdGVkX3ZhbHVlX3NpemUgKyB0YWdfYnl0ZXMKKyAgICAgIGFjdHVhbF9zaXplID0gYnl0ZV9zaXplX2ZuKGZpZWxkX251bWJlciwgdmFsdWUpCisgICAgICBzZWxmLmFzc2VydEVxdWFsKGV4cGVjdGVkX3NpemUsIGFjdHVhbF9zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAnYnl0ZV9zaXplX2ZuOiAlcywgZmllbGRfbnVtYmVyOiAlZCwgdmFsdWU6ICVyXG4nCisgICAgICAgICAgICAgICAgICAgICAgICdFeHBlY3RlZDogJWQsIEFjdHVhbDogJWQnJSAoCisgICAgICAgICAgYnl0ZV9zaXplX2ZuLCBmaWVsZF9udW1iZXIsIHZhbHVlLCBleHBlY3RlZF9zaXplLCBhY3R1YWxfc2l6ZSkpCisKKyAgZGVmIHRlc3RCeXRlU2l6ZUZ1bmN0aW9ucyhzZWxmKToKKyAgICAjIFRlc3QgYWxsIG51bWVyaWMgKkJ5dGVTaXplKCkgZnVuY3Rpb25zLgorICAgIE5VTUVSSUNfQVJHUyA9IFsKKyAgICAgICAgIyBJbnQzMkJ5dGVTaXplKCkuCisgICAgICAgIFt3aXJlX2Zvcm1hdC5JbnQzMkJ5dGVTaXplLCAwLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkludDMyQnl0ZVNpemUsIDEyNywgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5JbnQzMkJ5dGVTaXplLCAxMjgsIDJdLAorICAgICAgICBbd2lyZV9mb3JtYXQuSW50MzJCeXRlU2l6ZSwgLTEsIDEwXSwKKyAgICAgICAgIyBJbnQ2NEJ5dGVTaXplKCkuCisgICAgICAgIFt3aXJlX2Zvcm1hdC5JbnQ2NEJ5dGVTaXplLCAwLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkludDY0Qnl0ZVNpemUsIDEyNywgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5JbnQ2NEJ5dGVTaXplLCAxMjgsIDJdLAorICAgICAgICBbd2lyZV9mb3JtYXQuSW50NjRCeXRlU2l6ZSwgLTEsIDEwXSwKKyAgICAgICAgIyBVSW50MzJCeXRlU2l6ZSgpLgorICAgICAgICBbd2lyZV9mb3JtYXQuVUludDMyQnl0ZVNpemUsIDAsIDFdLAorICAgICAgICBbd2lyZV9mb3JtYXQuVUludDMyQnl0ZVNpemUsIDEyNywgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5VSW50MzJCeXRlU2l6ZSwgMTI4LCAyXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlVJbnQzMkJ5dGVTaXplLCB3aXJlX2Zvcm1hdC5VSU5UMzJfTUFYLCA1XSwKKyAgICAgICAgIyBVSW50NjRCeXRlU2l6ZSgpLgorICAgICAgICBbd2lyZV9mb3JtYXQuVUludDY0Qnl0ZVNpemUsIDAsIDFdLAorICAgICAgICBbd2lyZV9mb3JtYXQuVUludDY0Qnl0ZVNpemUsIDEyNywgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5VSW50NjRCeXRlU2l6ZSwgMTI4LCAyXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlVJbnQ2NEJ5dGVTaXplLCB3aXJlX2Zvcm1hdC5VSU5UNjRfTUFYLCAxMF0sCisgICAgICAgICMgU0ludDMyQnl0ZVNpemUoKS4KKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQzMkJ5dGVTaXplLCAwLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQzMkJ5dGVTaXplLCAtMSwgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TSW50MzJCeXRlU2l6ZSwgMSwgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TSW50MzJCeXRlU2l6ZSwgLTYzLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQzMkJ5dGVTaXplLCA2MywgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TSW50MzJCeXRlU2l6ZSwgLTY0LCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQzMkJ5dGVTaXplLCA2NCwgMl0sCisgICAgICAgICMgU0ludDY0Qnl0ZVNpemUoKS4KKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQ2NEJ5dGVTaXplLCAwLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQ2NEJ5dGVTaXplLCAtMSwgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TSW50NjRCeXRlU2l6ZSwgMSwgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TSW50NjRCeXRlU2l6ZSwgLTYzLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQ2NEJ5dGVTaXplLCA2MywgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TSW50NjRCeXRlU2l6ZSwgLTY0LCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNJbnQ2NEJ5dGVTaXplLCA2NCwgMl0sCisgICAgICAgICMgRml4ZWQzMkJ5dGVTaXplKCkuCisgICAgICAgIFt3aXJlX2Zvcm1hdC5GaXhlZDMyQnl0ZVNpemUsIDAsIDRdLAorICAgICAgICBbd2lyZV9mb3JtYXQuRml4ZWQzMkJ5dGVTaXplLCB3aXJlX2Zvcm1hdC5VSU5UMzJfTUFYLCA0XSwKKyAgICAgICAgIyBGaXhlZDY0Qnl0ZVNpemUoKS4KKyAgICAgICAgW3dpcmVfZm9ybWF0LkZpeGVkNjRCeXRlU2l6ZSwgMCwgOF0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5GaXhlZDY0Qnl0ZVNpemUsIHdpcmVfZm9ybWF0LlVJTlQ2NF9NQVgsIDhdLAorICAgICAgICAjIFNGaXhlZDMyQnl0ZVNpemUoKS4KKyAgICAgICAgW3dpcmVfZm9ybWF0LlNGaXhlZDMyQnl0ZVNpemUsIDAsIDRdLAorICAgICAgICBbd2lyZV9mb3JtYXQuU0ZpeGVkMzJCeXRlU2l6ZSwgd2lyZV9mb3JtYXQuSU5UMzJfTUlOLCA0XSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LlNGaXhlZDMyQnl0ZVNpemUsIHdpcmVfZm9ybWF0LklOVDMyX01BWCwgNF0sCisgICAgICAgICMgU0ZpeGVkNjRCeXRlU2l6ZSgpLgorICAgICAgICBbd2lyZV9mb3JtYXQuU0ZpeGVkNjRCeXRlU2l6ZSwgMCwgOF0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5TRml4ZWQ2NEJ5dGVTaXplLCB3aXJlX2Zvcm1hdC5JTlQ2NF9NSU4sIDhdLAorICAgICAgICBbd2lyZV9mb3JtYXQuU0ZpeGVkNjRCeXRlU2l6ZSwgd2lyZV9mb3JtYXQuSU5UNjRfTUFYLCA4XSwKKyAgICAgICAgIyBGbG9hdEJ5dGVTaXplKCkuCisgICAgICAgIFt3aXJlX2Zvcm1hdC5GbG9hdEJ5dGVTaXplLCAwLjAsIDRdLAorICAgICAgICBbd2lyZV9mb3JtYXQuRmxvYXRCeXRlU2l6ZSwgMTAwMDAwMDAwMC4wLCA0XSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkZsb2F0Qnl0ZVNpemUsIC0xMDAwMDAwMDAwLjAsIDRdLAorICAgICAgICAjIERvdWJsZUJ5dGVTaXplKCkuCisgICAgICAgIFt3aXJlX2Zvcm1hdC5Eb3VibGVCeXRlU2l6ZSwgMC4wLCA4XSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkRvdWJsZUJ5dGVTaXplLCAxMDAwMDAwMDAwLjAsIDhdLAorICAgICAgICBbd2lyZV9mb3JtYXQuRG91YmxlQnl0ZVNpemUsIC0xMDAwMDAwMDAwLjAsIDhdLAorICAgICAgICAjIEJvb2xCeXRlU2l6ZSgpLgorICAgICAgICBbd2lyZV9mb3JtYXQuQm9vbEJ5dGVTaXplLCBGYWxzZSwgMV0sCisgICAgICAgIFt3aXJlX2Zvcm1hdC5Cb29sQnl0ZVNpemUsIFRydWUsIDFdLAorICAgICAgICAjIEVudW1CeXRlU2l6ZSgpLgorICAgICAgICBbd2lyZV9mb3JtYXQuRW51bUJ5dGVTaXplLCAwLCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkVudW1CeXRlU2l6ZSwgMTI3LCAxXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkVudW1CeXRlU2l6ZSwgMTI4LCAyXSwKKyAgICAgICAgW3dpcmVfZm9ybWF0LkVudW1CeXRlU2l6ZSwgd2lyZV9mb3JtYXQuVUlOVDMyX01BWCwgNV0sCisgICAgICAgIF0KKyAgICBmb3IgYXJncyBpbiBOVU1FUklDX0FSR1M6CisgICAgICBzZWxmLk51bWVyaWNCeXRlU2l6ZVRlc3RIZWxwZXIoKmFyZ3MpCisKKyAgICAjIFRlc3Qgc3RyaW5ncyBhbmQgYnl0ZXMuCisgICAgZm9yIGJ5dGVfc2l6ZV9mbiBpbiAod2lyZV9mb3JtYXQuU3RyaW5nQnl0ZVNpemUsIHdpcmVfZm9ybWF0LkJ5dGVzQnl0ZVNpemUpOgorICAgICAgIyAxIGJ5dGUgZm9yIHRhZywgMSBieXRlIGZvciBsZW5ndGgsIDMgYnl0ZXMgZm9yIGNvbnRlbnRzLgorICAgICAgc2VsZi5hc3NlcnRFcXVhbCg1LCBieXRlX3NpemVfZm4oMTAsICdhYmMnKSkKKyAgICAgICMgMiBieXRlcyBmb3IgdGFnLCAxIGJ5dGUgZm9yIGxlbmd0aCwgMyBieXRlcyBmb3IgY29udGVudHMuCisgICAgICBzZWxmLmFzc2VydEVxdWFsKDYsIGJ5dGVfc2l6ZV9mbigxNiwgJ2FiYycpKQorICAgICAgIyAyIGJ5dGVzIGZvciB0YWcsIDIgYnl0ZXMgZm9yIGxlbmd0aCwgMTI4IGJ5dGVzIGZvciBjb250ZW50cy4KKyAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoMTMyLCBieXRlX3NpemVfZm4oMTYsICdhJyAqIDEyOCkpCisKKyAgICAjIFRlc3QgVVRGLTggc3RyaW5nIGJ5dGUgc2l6ZSBjYWxjdWxhdGlvbi4KKyAgICAjIDEgYnl0ZSBmb3IgdGFnLCAxIGJ5dGUgZm9yIGxlbmd0aCwgOCBieXRlcyBmb3IgY29udGVudC4KKyAgICBzZWxmLmFzc2VydEVxdWFsKDEwLCB3aXJlX2Zvcm1hdC5TdHJpbmdCeXRlU2l6ZSgKKyAgICAgICAgNSwgYidceGQwXHhhMlx4ZDBceGI1XHhkMVx4ODFceGQxXHg4MicuZGVjb2RlKCd1dGYtOCcpKSkKKworICAgIGNsYXNzIE1vY2tNZXNzYWdlKG9iamVjdCk6CisgICAgICBkZWYgX19pbml0X18oc2VsZiwgYnl0ZV9zaXplKToKKyAgICAgICAgc2VsZi5ieXRlX3NpemUgPSBieXRlX3NpemUKKyAgICAgIGRlZiBCeXRlU2l6ZShzZWxmKToKKyAgICAgICAgcmV0dXJuIHNlbGYuYnl0ZV9zaXplCisKKyAgICBtZXNzYWdlX2J5dGVfc2l6ZSA9IDEwCisgICAgbW9ja19tZXNzYWdlID0gTW9ja01lc3NhZ2UoYnl0ZV9zaXplPW1lc3NhZ2VfYnl0ZV9zaXplKQorICAgICMgVGVzdCBncm91cHMuCisgICAgIyAoMiAqIDEpIGJ5dGVzIGZvciBiZWdpbiBhbmQgZW5kIHRhZ3MsIHBsdXMgbWVzc2FnZV9ieXRlX3NpemUuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyICsgbWVzc2FnZV9ieXRlX3NpemUsCisgICAgICAgICAgICAgICAgICAgICB3aXJlX2Zvcm1hdC5Hcm91cEJ5dGVTaXplKDEsIG1vY2tfbWVzc2FnZSkpCisgICAgIyAoMiAqIDIpIGJ5dGVzIGZvciBiZWdpbiBhbmQgZW5kIHRhZ3MsIHBsdXMgbWVzc2FnZV9ieXRlX3NpemUuCisgICAgc2VsZi5hc3NlcnRFcXVhbCg0ICsgbWVzc2FnZV9ieXRlX3NpemUsCisgICAgICAgICAgICAgICAgICAgICB3aXJlX2Zvcm1hdC5Hcm91cEJ5dGVTaXplKDE2LCBtb2NrX21lc3NhZ2UpKQorCisgICAgIyBUZXN0IG1lc3NhZ2VzLgorICAgICMgMSBieXRlIGZvciB0YWcsIHBsdXMgMSBieXRlIGZvciBsZW5ndGgsIHBsdXMgY29udGVudHMuCisgICAgc2VsZi5hc3NlcnRFcXVhbCgyICsgbW9ja19tZXNzYWdlLmJ5dGVfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgIHdpcmVfZm9ybWF0Lk1lc3NhZ2VCeXRlU2l6ZSgxLCBtb2NrX21lc3NhZ2UpKQorICAgICMgMiBieXRlcyBmb3IgdGFnLCBwbHVzIDEgYnl0ZSBmb3IgbGVuZ3RoLCBwbHVzIGNvbnRlbnRzLgorICAgIHNlbGYuYXNzZXJ0RXF1YWwoMyArIG1vY2tfbWVzc2FnZS5ieXRlX3NpemUsCisgICAgICAgICAgICAgICAgICAgICB3aXJlX2Zvcm1hdC5NZXNzYWdlQnl0ZVNpemUoMTYsIG1vY2tfbWVzc2FnZSkpCisgICAgIyAyIGJ5dGVzIGZvciB0YWcsIHBsdXMgMiBieXRlcyBmb3IgbGVuZ3RoLCBwbHVzIGNvbnRlbnRzLgorICAgIG1vY2tfbWVzc2FnZS5ieXRlX3NpemUgPSAxMjgKKyAgICBzZWxmLmFzc2VydEVxdWFsKDQgKyBtb2NrX21lc3NhZ2UuYnl0ZV9zaXplLAorICAgICAgICAgICAgICAgICAgICAgd2lyZV9mb3JtYXQuTWVzc2FnZUJ5dGVTaXplKDE2LCBtb2NrX21lc3NhZ2UpKQorCisKKyAgICAjIFRlc3QgbWVzc2FnZSBzZXQgaXRlbSBieXRlIHNpemUuCisgICAgIyA0IGJ5dGVzIGZvciB0YWdzLCBwbHVzIDEgYnl0ZSBmb3IgbGVuZ3RoLCBwbHVzIDEgYnl0ZSBmb3IgdHlwZV9pZCwKKyAgICAjIHBsdXMgY29udGVudHMuCisgICAgbW9ja19tZXNzYWdlLmJ5dGVfc2l6ZSA9IDEwCisgICAgc2VsZi5hc3NlcnRFcXVhbChtb2NrX21lc3NhZ2UuYnl0ZV9zaXplICsgNiwKKyAgICAgICAgICAgICAgICAgICAgIHdpcmVfZm9ybWF0Lk1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoMSwgbW9ja19tZXNzYWdlKSkKKworICAgICMgNCBieXRlcyBmb3IgdGFncywgcGx1cyAyIGJ5dGVzIGZvciBsZW5ndGgsIHBsdXMgMSBieXRlIGZvciB0eXBlX2lkLAorICAgICMgcGx1cyBjb250ZW50cy4KKyAgICBtb2NrX21lc3NhZ2UuYnl0ZV9zaXplID0gMTI4CisgICAgc2VsZi5hc3NlcnRFcXVhbChtb2NrX21lc3NhZ2UuYnl0ZV9zaXplICsgNywKKyAgICAgICAgICAgICAgICAgICAgIHdpcmVfZm9ybWF0Lk1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoMSwgbW9ja19tZXNzYWdlKSkKKworICAgICMgNCBieXRlcyBmb3IgdGFncywgcGx1cyAyIGJ5dGVzIGZvciBsZW5ndGgsIHBsdXMgMiBieXRlIGZvciB0eXBlX2lkLAorICAgICMgcGx1cyBjb250ZW50cy4KKyAgICBzZWxmLmFzc2VydEVxdWFsKG1vY2tfbWVzc2FnZS5ieXRlX3NpemUgKyA4LAorICAgICAgICAgICAgICAgICAgICAgd2lyZV9mb3JtYXQuTWVzc2FnZVNldEl0ZW1CeXRlU2l6ZSgxMjgsIG1vY2tfbWVzc2FnZSkpCisKKyAgICAjIFRvby1sb25nIHZhcmludC4KKyAgICBzZWxmLmFzc2VydFJhaXNlcyhtZXNzYWdlLkVuY29kZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIHdpcmVfZm9ybWF0LlVJbnQ2NEJ5dGVTaXplLCAxLCAxIDw8IDEyOCkKKworCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBiYXNldGVzdC5tYWluKCkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5kZTJmNTY5Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLnB5CkBAIC0wLDAgKzEsMjkyIEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyMgVE9ETyhyb2JpbnNvbik6IFdlIHNob3VsZCBqdXN0IG1ha2UgdGhlc2UgbWV0aG9kcyBhbGwgInB1cmUtdmlydHVhbCIgYW5kIG1vdmUKKyMgYWxsIGltcGxlbWVudGF0aW9uIG91dCwgaW50byByZWZsZWN0aW9uLnB5IGZvciBub3cuCisKKworIiIiQ29udGFpbnMgYW4gYWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgcHJvdG9jb2wgbWVzc2FnZXMuIiIiCisKK19fYXV0aG9yX18gPSAncm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbiknCisKK2NsYXNzIEVycm9yKEV4Y2VwdGlvbik6IHBhc3MKK2NsYXNzIERlY29kZUVycm9yKEVycm9yKTogcGFzcworY2xhc3MgRW5jb2RlRXJyb3IoRXJyb3IpOiBwYXNzCisKKworY2xhc3MgTWVzc2FnZShvYmplY3QpOgorCisgICIiIkFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIHByb3RvY29sIG1lc3NhZ2VzLgorCisgIFByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcyBhcmUgYWxtb3N0IGFsd2F5cyBnZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sCisgIGNvbXBpbGVyLiAgVGhlc2UgZ2VuZXJhdGVkIHR5cGVzIHN1YmNsYXNzIE1lc3NhZ2UgYW5kIGltcGxlbWVudCB0aGUgbWV0aG9kcworICBzaG93biBiZWxvdy4KKworICBUT0RPKHJvYmluc29uKTogTGluayB0byBhbiBIVE1MIGRvY3VtZW50IGhlcmUuCisKKyAgVE9ETyhyb2JpbnNvbik6IERvY3VtZW50IHRoYXQgaW5zdGFuY2VzIG9mIHRoaXMgY2xhc3Mgd2lsbCBhbHNvCisgIGhhdmUgYW4gRXh0ZW5zaW9ucyBhdHRyaWJ1dGUgd2l0aCBfX2dldGl0ZW1fXyBhbmQgX19zZXRpdGVtX18uCisgIEFnYWluLCBub3Qgc3VyZSBob3cgdG8gYmVzdCBjb252ZXkgdGhpcy4KKworICBUT0RPKHJvYmluc29uKTogRG9jdW1lbnQgdGhhdCB0aGUgY2xhc3MgbXVzdCBhbHNvIGhhdmUgYSBzdGF0aWMKKyAgICBSZWdpc3RlckV4dGVuc2lvbihleHRlbnNpb25fZmllbGQpIG1ldGhvZC4KKyAgICBOb3Qgc3VyZSBob3cgdG8gYmVzdCBleHByZXNzIGF0IHRoaXMgcG9pbnQuCisgICIiIgorCisgICMgVE9ETyhyb2JpbnNvbik6IERvY3VtZW50IHRoZXNlIGZpZWxkcyBhbmQgbWV0aG9kcy4KKworICBfX3Nsb3RzX18gPSBbXQorCisgIERFU0NSSVBUT1IgPSBOb25lCisKKyAgZGVmIF9fZGVlcGNvcHlfXyhzZWxmLCBtZW1vPU5vbmUpOgorICAgIGNsb25lID0gdHlwZShzZWxmKSgpCisgICAgY2xvbmUuTWVyZ2VGcm9tKHNlbGYpCisgICAgcmV0dXJuIGNsb25lCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcl9tc2cpOgorICAgICIiIlJlY3Vyc2l2ZWx5IGNvbXBhcmVzIHR3byBtZXNzYWdlcyBieSB2YWx1ZSBhbmQgc3RydWN0dXJlLiIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyX21zZyk6CisgICAgIyBDYW4ndCBqdXN0IHNheSBzZWxmICE9IG90aGVyX21zZywgc2luY2UgdGhhdCB3b3VsZCBpbmZpbml0ZWx5IHJlY3Vyc2UuIDopCisgICAgcmV0dXJuIG5vdCBzZWxmID09IG90aGVyX21zZworCisgIGRlZiBfX2hhc2hfXyhzZWxmKToKKyAgICByYWlzZSBUeXBlRXJyb3IoJ3VuaGFzaGFibGUgb2JqZWN0JykKKworICBkZWYgX19zdHJfXyhzZWxmKToKKyAgICAiIiJPdXRwdXRzIGEgaHVtYW4tcmVhZGFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2UuIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBfX3VuaWNvZGVfXyhzZWxmKToKKyAgICAiIiJPdXRwdXRzIGEgaHVtYW4tcmVhZGFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2UuIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBNZXJnZUZyb20oc2VsZiwgb3RoZXJfbXNnKToKKyAgICAiIiJNZXJnZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBpbnRvIGN1cnJlbnQgbWVzc2FnZS4KKworICAgIFRoaXMgbWV0aG9kIG1lcmdlcyB0aGUgY29udGVudHMgb2YgdGhlIHNwZWNpZmllZCBtZXNzYWdlIGludG8gdGhlIGN1cnJlbnQKKyAgICBtZXNzYWdlLiBTaW5ndWxhciBmaWVsZHMgdGhhdCBhcmUgc2V0IGluIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBvdmVyd3JpdGUKKyAgICB0aGUgY29ycmVzcG9uZGluZyBmaWVsZHMgaW4gdGhlIGN1cnJlbnQgbWVzc2FnZS4gUmVwZWF0ZWQgZmllbGRzIGFyZQorICAgIGFwcGVuZGVkLiBTaW5ndWxhciBzdWItbWVzc2FnZXMgYW5kIGdyb3VwcyBhcmUgcmVjdXJzaXZlbHkgbWVyZ2VkLgorCisgICAgQXJnczoKKyAgICAgIG90aGVyX21zZzogTWVzc2FnZSB0byBtZXJnZSBpbnRvIHRoZSBjdXJyZW50IG1lc3NhZ2UuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBDb3B5RnJvbShzZWxmLCBvdGhlcl9tc2cpOgorICAgICIiIkNvcGllcyB0aGUgY29udGVudCBvZiB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UgaW50byB0aGUgY3VycmVudCBtZXNzYWdlLgorCisgICAgVGhlIG1ldGhvZCBjbGVhcnMgdGhlIGN1cnJlbnQgbWVzc2FnZSBhbmQgdGhlbiBtZXJnZXMgdGhlIHNwZWNpZmllZAorICAgIG1lc3NhZ2UgdXNpbmcgTWVyZ2VGcm9tLgorCisgICAgQXJnczoKKyAgICAgIG90aGVyX21zZzogTWVzc2FnZSB0byBjb3B5IGludG8gdGhlIGN1cnJlbnQgb25lLgorICAgICIiIgorICAgIGlmIHNlbGYgaXMgb3RoZXJfbXNnOgorICAgICAgcmV0dXJuCisgICAgc2VsZi5DbGVhcigpCisgICAgc2VsZi5NZXJnZUZyb20ob3RoZXJfbXNnKQorCisgIGRlZiBDbGVhcihzZWxmKToKKyAgICAiIiJDbGVhcnMgYWxsIGRhdGEgdGhhdCB3YXMgc2V0IGluIHRoZSBtZXNzYWdlLiIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgU2V0SW5QYXJlbnQoc2VsZik6CisgICAgIiIiTWFyayB0aGlzIGFzIHByZXNlbnQgaW4gdGhlIHBhcmVudC4KKworICAgIFRoaXMgbm9ybWFsbHkgaGFwcGVucyBhdXRvbWF0aWNhbGx5IHdoZW4geW91IGFzc2lnbiBhIGZpZWxkIG9mIGEKKyAgICBzdWItbWVzc2FnZSwgYnV0IHNvbWV0aW1lcyB5b3Ugd2FudCB0byBtYWtlIHRoZSBzdWItbWVzc2FnZQorICAgIHByZXNlbnQgd2hpbGUga2VlcGluZyBpdCBlbXB0eS4gIElmIHlvdSBmaW5kIHlvdXJzZWxmIHVzaW5nIHRoaXMsCisgICAgeW91IG1heSB3YW50IHRvIHJlY29uc2lkZXIgeW91ciBkZXNpZ24uIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBJc0luaXRpYWxpemVkKHNlbGYpOgorICAgICIiIkNoZWNrcyBpZiB0aGUgbWVzc2FnZSBpcyBpbml0aWFsaXplZC4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgbWV0aG9kIHJldHVybnMgVHJ1ZSBpZiB0aGUgbWVzc2FnZSBpcyBpbml0aWFsaXplZCAoaS5lLiBhbGwgb2YgaXRzCisgICAgICByZXF1aXJlZCBmaWVsZHMgYXJlIHNldCkuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgICMgVE9ETyhyb2JpbnNvbik6IE1lcmdlRnJvbVN0cmluZygpIHNob3VsZCBwcm9iYWJseSByZXR1cm4gTm9uZSBhbmQgYmUKKyAgIyBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiBhIGhlbHBlciB0aGF0IHJldHVybnMgdGhlICMgb2YgYnl0ZXMgcmVhZC4gIE91cgorICAjIGRlc2VyaWFsaXphdGlvbiByb3V0aW5lcyB3b3VsZCB1c2UgdGhlIGhlbHBlciB3aGVuIHJlY3Vyc2l2ZWx5CisgICMgZGVzZXJpYWxpemluZywgYnV0IHRoZSBlbmQgdXNlciB3b3VsZCBhbG1vc3QgYWx3YXlzIGp1c3Qgd2FudCB0aGUgbm8tcmV0dXJuCisgICMgTWVyZ2VGcm9tU3RyaW5nKCkuCisKKyAgZGVmIE1lcmdlRnJvbVN0cmluZyhzZWxmLCBzZXJpYWxpemVkKToKKyAgICAiIiJNZXJnZXMgc2VyaWFsaXplZCBwcm90b2NvbCBidWZmZXIgZGF0YSBpbnRvIHRoaXMgbWVzc2FnZS4KKworICAgIFdoZW4gd2UgZmluZCBhIGZpZWxkIGluIHxzZXJpYWxpemVkfCB0aGF0IGlzIGFscmVhZHkgcHJlc2VudAorICAgIGluIHRoaXMgbWVzc2FnZToKKyAgICAgIC0gSWYgaXQncyBhICJyZXBlYXRlZCIgZmllbGQsIHdlIGFwcGVuZCB0byB0aGUgZW5kIG9mIG91ciBsaXN0LgorICAgICAgLSBFbHNlLCBpZiBpdCdzIGEgc2NhbGFyLCB3ZSBvdmVyd3JpdGUgb3VyIGZpZWxkLgorICAgICAgLSBFbHNlLCAoaXQncyBhIG5vbnJlcGVhdGVkIGNvbXBvc2l0ZSksIHdlIHJlY3Vyc2l2ZWx5IG1lcmdlCisgICAgICAgIGludG8gdGhlIGV4aXN0aW5nIGNvbXBvc2l0ZS4KKworICAgIFRPRE8ocm9iaW5zb24pOiBEb2N1bWVudCBoYW5kbGluZyBvZiB1bmtub3duIGZpZWxkcy4KKworICAgIEFyZ3M6CisgICAgICBzZXJpYWxpemVkOiBBbnkgb2JqZWN0IHRoYXQgYWxsb3dzIHVzIHRvIGNhbGwgYnVmZmVyKHNlcmlhbGl6ZWQpCisgICAgICAgIHRvIGFjY2VzcyBhIHN0cmluZyBvZiBieXRlcyB1c2luZyB0aGUgYnVmZmVyIGludGVyZmFjZS4KKworICAgIFRPRE8ocm9iaW5zb24pOiBXaGVuIHdlIHN3aXRjaCB0byBhIGhlbHBlciwgdGhpcyB3aWxsIHJldHVybiBOb25lLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBmcm9tIHxzZXJpYWxpemVkfC4KKyAgICAgIEZvciBub24tZ3JvdXAgbWVzc2FnZXMsIHRoaXMgd2lsbCBhbHdheXMgYmUgbGVuKHNlcmlhbGl6ZWQpLAorICAgICAgYnV0IGZvciBtZXNzYWdlcyB3aGljaCBhcmUgYWN0dWFsbHkgZ3JvdXBzLCB0aGlzIHdpbGwKKyAgICAgIGdlbmVyYWxseSBiZSBsZXNzIHRoYW4gbGVuKHNlcmlhbGl6ZWQpLCBzaW5jZSB3ZSBtdXN0CisgICAgICBzdG9wIHdoZW4gd2UgcmVhY2ggYW4gRU5EX0dST1VQIHRhZy4gIE5vdGUgdGhhdCBpZgorICAgICAgd2UgKmRvKiBzdG9wIGJlY2F1c2Ugb2YgYW4gRU5EX0dST1VQIHRhZywgdGhlIG51bWJlcgorICAgICAgb2YgYnl0ZXMgcmV0dXJuZWQgZG9lcyBub3QgaW5jbHVkZSB0aGUgYnl0ZXMKKyAgICAgIGZvciB0aGUgRU5EX0dST1VQIHRhZyBpbmZvcm1hdGlvbi4KKyAgICAiIiIKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKKyAgZGVmIFBhcnNlRnJvbVN0cmluZyhzZWxmLCBzZXJpYWxpemVkKToKKyAgICAiIiJQYXJzZSBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBkYXRhIGludG8gdGhpcyBtZXNzYWdlLgorCisgICAgTGlrZSBNZXJnZUZyb21TdHJpbmcoKSwgZXhjZXB0IHdlIGNsZWFyIHRoZSBvYmplY3QgZmlyc3QgYW5kCisgICAgZG8gbm90IHJldHVybiB0aGUgdmFsdWUgdGhhdCBNZXJnZUZyb21TdHJpbmcgcmV0dXJucy4KKyAgICAiIiIKKyAgICBzZWxmLkNsZWFyKCkKKyAgICBzZWxmLk1lcmdlRnJvbVN0cmluZyhzZXJpYWxpemVkKQorCisgIGRlZiBTZXJpYWxpemVUb1N0cmluZyhzZWxmKToKKyAgICAiIiJTZXJpYWxpemVzIHRoZSBwcm90b2NvbCBtZXNzYWdlIHRvIGEgYmluYXJ5IHN0cmluZy4KKworICAgIFJldHVybnM6CisgICAgICBBIGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2UgaWYgYWxsIG9mIHRoZSByZXF1aXJlZAorICAgICAgZmllbGRzIGluIHRoZSBtZXNzYWdlIGFyZSBzZXQgKGkuZS4gdGhlIG1lc3NhZ2UgaXMgaW5pdGlhbGl6ZWQpLgorCisgICAgUmFpc2VzOgorICAgICAgbWVzc2FnZS5FbmNvZGVFcnJvciBpZiB0aGUgbWVzc2FnZSBpc24ndCBpbml0aWFsaXplZC4KKyAgICAiIiIKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKKyAgZGVmIFNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyhzZWxmKToKKyAgICAiIiJTZXJpYWxpemVzIHRoZSBwcm90b2NvbCBtZXNzYWdlIHRvIGEgYmluYXJ5IHN0cmluZy4KKworICAgIFRoaXMgbWV0aG9kIGlzIHNpbWlsYXIgdG8gU2VyaWFsaXplVG9TdHJpbmcgYnV0IGRvZXNuJ3QgY2hlY2sgaWYgdGhlCisgICAgbWVzc2FnZSBpcyBpbml0aWFsaXplZC4KKworICAgIFJldHVybnM6CisgICAgICBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFydGlhbCBtZXNzYWdlLgorICAgICIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICAjIFRPRE8ocm9iaW5zb24pOiBEZWNpZGUgd2hldGhlciB3ZSBsaWtlIHRoZXNlIGJldHRlcgorICAjIHRoYW4gYXV0by1nZW5lcmF0ZWQgaGFzX2ZvbygpIGFuZCBjbGVhcl9mb28oKSBtZXRob2RzCisgICMgb24gdGhlIGluc3RhbmNlcyB0aGVtc2VsdmVzLiAgVGhpcyB3YXkgaXMgbGVzcyBjb25zaXN0ZW50CisgICMgd2l0aCBDKyssIGJ1dCBpdCBtYWtlcyByZWZsZWN0aW9uLXR5cGUgYWNjZXNzIGVhc2llciBhbmQKKyAgIyByZWR1Y2VzIHRoZSBudW1iZXIgb2YgbWFnaWNhbGx5IGF1dG9nZW5lcmF0ZWQgdGhpbmdzLgorICAjCisgICMgVE9ETyhyb2JpbnNvbik6IEJlIHN1cmUgdG8gZG9jdW1lbnQgKGFuZCB0ZXN0KSBleGFjdGx5CisgICMgd2hpY2ggZmllbGQgbmFtZXMgYXJlIGFjY2VwdGVkIGhlcmUuICBBcmUgd2UgY2FzZS1zZW5zaXRpdmU/CisgICMgV2hhdCBkbyB3ZSBkbyB3aXRoIGZpZWxkcyB0aGF0IHNoYXJlIG5hbWVzIHdpdGggUHl0aG9uIGtleXdvcmRzCisgICMgbGlrZSAnbGFtYmRhJyBhbmQgJ3lpZWxkJz8KKyAgIworICAjIG5ub3J3aXR6IHNheXM6CisgICMgIiIiCisgICMgVHlwaWNhbGx5IChpbiBweXRob24pLCBhbiB1bmRlcnNjb3JlIGlzIGFwcGVuZGVkIHRvIG5hbWVzIHRoYXQgYXJlCisgICMga2V5d29yZHMuIFNvIHRoZXkgd291bGQgYmVjb21lIGxhbWJkYV8gb3IgeWllbGRfLgorICAjICIiIgorICBkZWYgTGlzdEZpZWxkcyhzZWxmKToKKyAgICAiIiJSZXR1cm5zIGEgbGlzdCBvZiAoRmllbGREZXNjcmlwdG9yLCB2YWx1ZSkgdHVwbGVzIGZvciBhbGwKKyAgICBmaWVsZHMgaW4gdGhlIG1lc3NhZ2Ugd2hpY2ggYXJlIG5vdCBlbXB0eS4gIEEgc2luZ3VsYXIgZmllbGQgaXMgbm9uLWVtcHR5CisgICAgaWYgSGFzRmllbGQoKSB3b3VsZCByZXR1cm4gdHJ1ZSwgYW5kIGEgcmVwZWF0ZWQgZmllbGQgaXMgbm9uLWVtcHR5IGlmCisgICAgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIGVsZW1lbnQuICBUaGUgZmllbGRzIGFyZSBvcmRlcmVkIGJ5IGZpZWxkCisgICAgbnVtYmVyIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBIYXNGaWVsZChzZWxmLCBmaWVsZF9uYW1lKToKKyAgICAiIiJDaGVja3MgaWYgYSBjZXJ0YWluIGZpZWxkIGlzIHNldCBmb3IgdGhlIG1lc3NhZ2UsIG9yIGlmIGFueSBmaWVsZCBpbnNpZGUKKyAgICBhIG9uZW9mIGdyb3VwIGlzIHNldC4gIE5vdGUgdGhhdCBpZiB0aGUgZmllbGRfbmFtZSBpcyBub3QgZGVmaW5lZCBpbiB0aGUKKyAgICBtZXNzYWdlIGRlc2NyaXB0b3IsIFZhbHVlRXJyb3Igd2lsbCBiZSByYWlzZWQuIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBDbGVhckZpZWxkKHNlbGYsIGZpZWxkX25hbWUpOgorICAgICIiIkNsZWFycyB0aGUgY29udGVudHMgb2YgYSBnaXZlbiBmaWVsZCwgb3IgdGhlIGZpZWxkIHNldCBpbnNpZGUgYSBvbmVvZgorICAgIGdyb3VwLiAgSWYgdGhlIG5hbWUgbmVpdGhlciByZWZlcnMgdG8gYSBkZWZpbmVkIGZpZWxkIG9yIG9uZW9mIGdyb3VwLAorICAgIFZhbHVlRXJyb3IgaXMgcmFpc2VkLiIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgV2hpY2hPbmVvZihzZWxmLCBvbmVvZl9ncm91cCk6CisgICAgIiIiUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdGhhdCBpcyBzZXQgaW5zaWRlIGEgb25lb2YgZ3JvdXAsIG9yCisgICAgTm9uZSBpZiBubyBmaWVsZCBpcyBzZXQuICBJZiBubyBncm91cCB3aXRoIHRoZSBnaXZlbiBuYW1lIGV4aXN0cywgVmFsdWVFcnJvcgorICAgIHdpbGwgYmUgcmFpc2VkLiIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgSGFzRXh0ZW5zaW9uKHNlbGYsIGV4dGVuc2lvbl9oYW5kbGUpOgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgQ2xlYXJFeHRlbnNpb24oc2VsZiwgZXh0ZW5zaW9uX2hhbmRsZSk6CisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBCeXRlU2l6ZShzZWxmKToKKyAgICAiIiJSZXR1cm5zIHRoZSBzZXJpYWxpemVkIHNpemUgb2YgdGhpcyBtZXNzYWdlLgorICAgIFJlY3Vyc2l2ZWx5IGNhbGxzIEJ5dGVTaXplKCkgb24gYWxsIGNvbnRhaW5lZCBtZXNzYWdlcy4KKyAgICAiIiIKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKKyAgZGVmIF9TZXRMaXN0ZW5lcihzZWxmLCBtZXNzYWdlX2xpc3RlbmVyKToKKyAgICAiIiJJbnRlcm5hbCBtZXRob2QgdXNlZCBieSB0aGUgcHJvdG9jb2wgbWVzc2FnZSBpbXBsZW1lbnRhdGlvbi4KKyAgICBDbGllbnRzIHNob3VsZCBub3QgY2FsbCB0aGlzIGRpcmVjdGx5LgorCisgICAgU2V0cyBhIGxpc3RlbmVyIHRoYXQgdGhpcyBtZXNzYWdlIHdpbGwgY2FsbCBvbiBjZXJ0YWluIHN0YXRlIHRyYW5zaXRpb25zLgorCisgICAgVGhlIHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gcmVnaXN0ZXIgYmFjay1lZGdlcyBmcm9tIGNoaWxkcmVuIHRvCisgICAgcGFyZW50cyBhdCBydW50aW1lLCBmb3IgdGhlIHB1cnBvc2Ugb2Ygc2V0dGluZyAiaGFzIiBiaXRzIGFuZAorICAgIGJ5dGUtc2l6ZS1kaXJ0eSBiaXRzIGluIHRoZSBwYXJlbnQgYW5kIGFuY2VzdG9yIG9iamVjdHMgd2hlbmV2ZXIgYSBjaGlsZCBvcgorICAgIGRlc2NlbmRhbnQgb2JqZWN0IGlzIG1vZGlmaWVkLgorCisgICAgSWYgdGhlIGNsaWVudCB3YW50cyB0byBkaXNjb25uZWN0IHRoaXMgTWVzc2FnZSBmcm9tIHRoZSBvYmplY3QgdHJlZSwgc2hlCisgICAgZXhwbGljaXRseSBzZXRzIGNhbGxiYWNrIHRvIE5vbmUuCisKKyAgICBJZiBtZXNzYWdlX2xpc3RlbmVyIGlzIE5vbmUsIHVucmVnaXN0ZXJzIGFueSBleGlzdGluZyBsaXN0ZW5lci4gIE90aGVyd2lzZSwKKyAgICBtZXNzYWdlX2xpc3RlbmVyIG11c3QgaW1wbGVtZW50IHRoZSBNZXNzYWdlTGlzdGVuZXIgaW50ZXJmYWNlIGluCisgICAgaW50ZXJuYWwvbWVzc2FnZV9saXN0ZW5lci5weSwgYW5kIHdlIGRpc2NhcmQgYW55IGxpc3RlbmVyIHJlZ2lzdGVyZWQKKyAgICB2aWEgYSBwcmV2aW91cyBfU2V0TGlzdGVuZXIoKSBjYWxsLgorICAgICIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgX19nZXRzdGF0ZV9fKHNlbGYpOgorICAgICIiIlN1cHBvcnQgdGhlIHBpY2tsZSBwcm90b2NvbC4iIiIKKyAgICByZXR1cm4gZGljdChzZXJpYWxpemVkPXNlbGYuU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKCkpCisKKyAgZGVmIF9fc2V0c3RhdGVfXyhzZWxmLCBzdGF0ZSk6CisgICAgIiIiU3VwcG9ydCB0aGUgcGlja2xlIHByb3RvY29sLiIiIgorICAgIHNlbGYuX19pbml0X18oKQorICAgIHNlbGYuUGFyc2VGcm9tU3RyaW5nKHN0YXRlWydzZXJpYWxpemVkJ10pCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfZmFjdG9yeS5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV9mYWN0b3J5LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmZDdiZWMKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfZmFjdG9yeS5weQpAQCAtMCwwICsxLDE1NSBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjUFkyNSBjb21wYXRpYmxlIGZvciBHQUUuCisjCisjIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisKKyIiIlByb3ZpZGVzIGEgZmFjdG9yeSBjbGFzcyBmb3IgZ2VuZXJhdGluZyBkeW5hbWljIG1lc3NhZ2VzLgorCitUaGUgZWFzaWVzdCB3YXkgdG8gdXNlIHRoaXMgY2xhc3MgaXMgaWYgeW91IGhhdmUgYWNjZXNzIHRvIHRoZSBGaWxlRGVzY3JpcHRvcgorcHJvdG9zIGNvbnRhaW5pbmcgdGhlIG1lc3NhZ2VzIHlvdSB3YW50IHRvIGNyZWF0ZSB5b3UgY2FuIGp1c3QgZG8gdGhlIGZvbGxvd2luZzoKKworbWVzc2FnZV9jbGFzc2VzID0gbWVzc2FnZV9mYWN0b3J5LkdldE1lc3NhZ2VzKGl0ZXJhYmxlX29mX2ZpbGVfZGVzY3JpcHRvcnMpCitteV9wcm90b19pbnN0YW5jZSA9IG1lc3NhZ2VfY2xhc3Nlc1snc29tZS5wcm90by5wYWNrYWdlLk1lc3NhZ2VOYW1lJ10oKQorIiIiCisKK19fYXV0aG9yX18gPSAnbWF0dGhld3RvaWFAZ29vZ2xlLmNvbSAoTWF0dCBUb2lhKScKKworaW1wb3J0IHN5cyAgIyNQWTI1Citmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcl9kYXRhYmFzZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcG9vbAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2UKK2Zyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCByZWZsZWN0aW9uCisKKworY2xhc3MgTWVzc2FnZUZhY3Rvcnkob2JqZWN0KToKKyAgIiIiRmFjdG9yeSBmb3IgY3JlYXRpbmcgUHJvdG8yIG1lc3NhZ2VzIGZyb20gZGVzY3JpcHRvcnMgaW4gYSBwb29sLiIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBwb29sPU5vbmUpOgorICAgICIiIkluaXRpYWxpemVzIGEgbmV3IGZhY3RvcnkuIiIiCisgICAgc2VsZi5wb29sID0gKHBvb2wgb3IgZGVzY3JpcHRvcl9wb29sLkRlc2NyaXB0b3JQb29sKAorICAgICAgICBkZXNjcmlwdG9yX2RhdGFiYXNlLkRlc2NyaXB0b3JEYXRhYmFzZSgpKSkKKworICAgICMgbG9jYWwgY2FjaGUgb2YgYWxsIGNsYXNzZXMgYnVpbHQgZnJvbSBwcm90b2J1ZiBkZXNjcmlwdG9ycworICAgIHNlbGYuX2NsYXNzZXMgPSB7fQorCisgIGRlZiBHZXRQcm90b3R5cGUoc2VsZiwgZGVzY3JpcHRvcik6CisgICAgIiIiQnVpbGRzIGEgcHJvdG8yIG1lc3NhZ2UgY2xhc3MgYmFzZWQgb24gdGhlIHBhc3NlZCBpbiBkZXNjcmlwdG9yLgorCisgICAgUGFzc2luZyBhIGRlc2NyaXB0b3Igd2l0aCBhIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG1hdGNoaW5nIGEgcHJldmlvdXMKKyAgICBpbnZvY2F0aW9uIHdpbGwgY2F1c2UgdGhlIHNhbWUgY2xhc3MgdG8gYmUgcmV0dXJuZWQuCisKKyAgICBBcmdzOgorICAgICAgZGVzY3JpcHRvcjogVGhlIGRlc2NyaXB0b3IgdG8gYnVpbGQgZnJvbS4KKworICAgIFJldHVybnM6CisgICAgICBBIGNsYXNzIGRlc2NyaWJpbmcgdGhlIHBhc3NlZCBpbiBkZXNjcmlwdG9yLgorICAgICIiIgorICAgIGlmIGRlc2NyaXB0b3IuZnVsbF9uYW1lIG5vdCBpbiBzZWxmLl9jbGFzc2VzOgorICAgICAgZGVzY3JpcHRvcl9uYW1lID0gZGVzY3JpcHRvci5uYW1lCisgICAgICBpZiBzeXMudmVyc2lvbl9pbmZvWzBdIDwgMzogICMjUFkyNQorIyMhUFkyNSAgICAgIGlmIHN0ciBpcyBieXRlczogICMgUFkyCisgICAgICAgIGRlc2NyaXB0b3JfbmFtZSA9IGRlc2NyaXB0b3IubmFtZS5lbmNvZGUoJ2FzY2lpJywgJ2lnbm9yZScpCisgICAgICByZXN1bHRfY2xhc3MgPSByZWZsZWN0aW9uLkdlbmVyYXRlZFByb3RvY29sTWVzc2FnZVR5cGUoCisgICAgICAgICAgZGVzY3JpcHRvcl9uYW1lLAorICAgICAgICAgIChtZXNzYWdlLk1lc3NhZ2UsKSwKKyAgICAgICAgICB7J0RFU0NSSVBUT1InOiBkZXNjcmlwdG9yLCAnX19tb2R1bGVfXyc6IE5vbmV9KQorICAgICAgICAgICMgSWYgbW9kdWxlIG5vdCBzZXQsIGl0IHdyb25nbHkgcG9pbnRzIHRvIHRoZSByZWZsZWN0aW9uLnB5IG1vZHVsZS4KKyAgICAgIHNlbGYuX2NsYXNzZXNbZGVzY3JpcHRvci5mdWxsX25hbWVdID0gcmVzdWx0X2NsYXNzCisgICAgICBmb3IgZmllbGQgaW4gZGVzY3JpcHRvci5maWVsZHM6CisgICAgICAgIGlmIGZpZWxkLm1lc3NhZ2VfdHlwZToKKyAgICAgICAgICBzZWxmLkdldFByb3RvdHlwZShmaWVsZC5tZXNzYWdlX3R5cGUpCisgICAgICBmb3IgZXh0ZW5zaW9uIGluIHJlc3VsdF9jbGFzcy5ERVNDUklQVE9SLmV4dGVuc2lvbnM6CisgICAgICAgIGlmIGV4dGVuc2lvbi5jb250YWluaW5nX3R5cGUuZnVsbF9uYW1lIG5vdCBpbiBzZWxmLl9jbGFzc2VzOgorICAgICAgICAgIHNlbGYuR2V0UHJvdG90eXBlKGV4dGVuc2lvbi5jb250YWluaW5nX3R5cGUpCisgICAgICAgIGV4dGVuZGVkX2NsYXNzID0gc2VsZi5fY2xhc3Nlc1tleHRlbnNpb24uY29udGFpbmluZ190eXBlLmZ1bGxfbmFtZV0KKyAgICAgICAgZXh0ZW5kZWRfY2xhc3MuUmVnaXN0ZXJFeHRlbnNpb24oZXh0ZW5zaW9uKQorICAgIHJldHVybiBzZWxmLl9jbGFzc2VzW2Rlc2NyaXB0b3IuZnVsbF9uYW1lXQorCisgIGRlZiBHZXRNZXNzYWdlcyhzZWxmLCBmaWxlcyk6CisgICAgIiIiR2V0cyBhbGwgdGhlIG1lc3NhZ2VzIGZyb20gYSBzcGVjaWZpZWQgZmlsZS4KKworICAgIFRoaXMgd2lsbCBmaW5kIGFuZCByZXNvbHZlIGRlcGVuZGVuY2llcywgZmFpbGluZyBpZiB0aGUgZGVzY3JpcHRvcgorICAgIHBvb2wgY2Fubm90IHNhdGlzZnkgdGhlbS4KKworICAgIEFyZ3M6CisgICAgICBmaWxlczogVGhlIGZpbGUgbmFtZXMgdG8gZXh0cmFjdCBtZXNzYWdlcyBmcm9tLgorCisgICAgUmV0dXJuczoKKyAgICAgIEEgZGljdGlvbmFyeSBtYXBwaW5nIHByb3RvIG5hbWVzIHRvIHRoZSBtZXNzYWdlIGNsYXNzZXMuIFRoaXMgd2lsbCBpbmNsdWRlCisgICAgICBhbnkgZGVwZW5kZW50IG1lc3NhZ2VzIGFzIHdlbGwgYXMgYW55IG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIHNhbWUgZmlsZSBhcworICAgICAgYSBzcGVjaWZpZWQgbWVzc2FnZS4KKyAgICAiIiIKKyAgICByZXN1bHQgPSB7fQorICAgIGZvciBmaWxlX25hbWUgaW4gZmlsZXM6CisgICAgICBmaWxlX2Rlc2MgPSBzZWxmLnBvb2wuRmluZEZpbGVCeU5hbWUoZmlsZV9uYW1lKQorICAgICAgZm9yIG5hbWUsIG1zZyBpbiBmaWxlX2Rlc2MubWVzc2FnZV90eXBlc19ieV9uYW1lLml0ZXJpdGVtcygpOgorICAgICAgICBpZiBmaWxlX2Rlc2MucGFja2FnZToKKyAgICAgICAgICBmdWxsX25hbWUgPSAnLicuam9pbihbZmlsZV9kZXNjLnBhY2thZ2UsIG5hbWVdKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGZ1bGxfbmFtZSA9IG1zZy5uYW1lCisgICAgICAgIHJlc3VsdFtmdWxsX25hbWVdID0gc2VsZi5HZXRQcm90b3R5cGUoCisgICAgICAgICAgICBzZWxmLnBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKGZ1bGxfbmFtZSkpCisKKyAgICAgICMgV2hpbGUgdGhlIGV4dGVuc2lvbiBGaWVsZERlc2NyaXB0b3JzIGFyZSBjcmVhdGVkIGJ5IHRoZSBkZXNjcmlwdG9yIHBvb2wsCisgICAgICAjIHRoZSBweXRob24gY2xhc3NlcyBjcmVhdGVkIGluIHRoZSBmYWN0b3J5IG5lZWQgdGhlbSB0byBiZSByZWdpc3RlcmVkCisgICAgICAjIGV4cGxpY2l0bHksIHdoaWNoIGlzIGRvbmUgYmVsb3cuCisgICAgICAjCisgICAgICAjIFRoZSBjYWxsIHRvIFJlZ2lzdGVyRXh0ZW5zaW9uIHdpbGwgc3BlY2lmaWNhbGx5IGNoZWNrIGlmIHRoZQorICAgICAgIyBleHRlbnNpb24gd2FzIGFscmVhZHkgcmVnaXN0ZXJlZCBvbiB0aGUgb2JqZWN0IGFuZCBlaXRoZXIKKyAgICAgICMgaWdub3JlIHRoZSByZWdpc3RyYXRpb24gaWYgdGhlIG9yaWdpbmFsIHdhcyB0aGUgc2FtZSwgb3IgcmFpc2UKKyAgICAgICMgYW4gZXJyb3IgaWYgdGhleSB3ZXJlIGRpZmZlcmVudC4KKworICAgICAgZm9yIG5hbWUsIGV4dGVuc2lvbiBpbiBmaWxlX2Rlc2MuZXh0ZW5zaW9uc19ieV9uYW1lLml0ZXJpdGVtcygpOgorICAgICAgICBpZiBleHRlbnNpb24uY29udGFpbmluZ190eXBlLmZ1bGxfbmFtZSBub3QgaW4gc2VsZi5fY2xhc3NlczoKKyAgICAgICAgICBzZWxmLkdldFByb3RvdHlwZShleHRlbnNpb24uY29udGFpbmluZ190eXBlKQorICAgICAgICBleHRlbmRlZF9jbGFzcyA9IHNlbGYuX2NsYXNzZXNbZXh0ZW5zaW9uLmNvbnRhaW5pbmdfdHlwZS5mdWxsX25hbWVdCisgICAgICAgIGV4dGVuZGVkX2NsYXNzLlJlZ2lzdGVyRXh0ZW5zaW9uKGV4dGVuc2lvbikKKyAgICByZXR1cm4gcmVzdWx0CisKKworX0ZBQ1RPUlkgPSBNZXNzYWdlRmFjdG9yeSgpCisKKworZGVmIEdldE1lc3NhZ2VzKGZpbGVfcHJvdG9zKToKKyAgIiIiQnVpbGRzIGEgZGljdGlvbmFyeSBvZiBhbGwgdGhlIG1lc3NhZ2VzIGF2YWlsYWJsZSBpbiBhIHNldCBvZiBmaWxlcy4KKworICBBcmdzOgorICAgIGZpbGVfcHJvdG9zOiBBIHNlcXVlbmNlIG9mIGZpbGUgcHJvdG9zIHRvIGJ1aWxkIG1lc3NhZ2VzIG91dCBvZi4KKworICBSZXR1cm5zOgorICAgIEEgZGljdGlvbmFyeSBtYXBwaW5nIHByb3RvIG5hbWVzIHRvIHRoZSBtZXNzYWdlIGNsYXNzZXMuIFRoaXMgd2lsbCBpbmNsdWRlCisgICAgYW55IGRlcGVuZGVudCBtZXNzYWdlcyBhcyB3ZWxsIGFzIGFueSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSBzYW1lIGZpbGUgYXMKKyAgICBhIHNwZWNpZmllZCBtZXNzYWdlLgorICAiIiIKKyAgZm9yIGZpbGVfcHJvdG8gaW4gZmlsZV9wcm90b3M6CisgICAgX0ZBQ1RPUlkucG9vbC5BZGQoZmlsZV9wcm90bykKKyAgcmV0dXJuIF9GQUNUT1JZLkdldE1lc3NhZ2VzKFtmaWxlX3Byb3RvLm5hbWUgZm9yIGZpbGVfcHJvdG8gaW4gZmlsZV9wcm90b3NdKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9wcm90b19idWlsZGVyLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9wcm90b19idWlsZGVyLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmYTI4ZjEKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3Byb3RvX2J1aWxkZXIucHkKQEAgLTAsMCArMSw5OCBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJEeW5hbWljIFByb3RvYnVmIGNsYXNzIGNyZWF0b3IuIiIiCisKK2ltcG9ydCBoYXNobGliCitpbXBvcnQgb3MKKworZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcGIyCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgbWVzc2FnZV9mYWN0b3J5CisKKworZGVmIF9HZXRNZXNzYWdlRnJvbUZhY3RvcnkoZmFjdG9yeSwgZnVsbF9uYW1lKToKKyAgIiIiR2V0IGEgcHJvdG8gY2xhc3MgZnJvbSB0aGUgTWVzc2FnZUZhY3RvcnkgYnkgbmFtZS4KKworICBBcmdzOgorICAgIGZhY3Rvcnk6IGEgTWVzc2FnZUZhY3RvcnkgaW5zdGFuY2UuCisgICAgZnVsbF9uYW1lOiBzdHIsIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgcHJvdG8gdHlwZS4KKyAgUmV0dXJuczoKKyAgICBhIGNsYXNzLCBmb3IgdGhlIHR5cGUgaWRlbnRpZmllZCBieSBmdWxsX25hbWUuCisgIFJhaXNlczoKKyAgICBLZXlFcnJvciwgaWYgdGhlIHByb3RvIGlzIG5vdCBmb3VuZCBpbiB0aGUgZmFjdG9yeSdzIGRlc2NyaXB0b3IgcG9vbC4KKyAgIiIiCisgIHByb3RvX2Rlc2NyaXB0b3IgPSBmYWN0b3J5LnBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKGZ1bGxfbmFtZSkKKyAgcHJvdG9fY2xzID0gZmFjdG9yeS5HZXRQcm90b3R5cGUocHJvdG9fZGVzY3JpcHRvcikKKyAgcmV0dXJuIHByb3RvX2NscworCisKK2RlZiBNYWtlU2ltcGxlUHJvdG9DbGFzcyhmaWVsZHMsIGZ1bGxfbmFtZSwgcG9vbD1Ob25lKToKKyAgIiIiQ3JlYXRlIGEgUHJvdG9idWYgY2xhc3Mgd2hvc2UgZmllbGRzIGFyZSBiYXNpYyB0eXBlcy4KKworICBOb3RlOiB0aGlzIGRvZXNuJ3QgdmFsaWRhdGUgZmllbGQgbmFtZXMhCisKKyAgQXJnczoKKyAgICBmaWVsZHM6IGRpY3Qgb2Yge25hbWU6IGZpZWxkX3R5cGV9IG1hcHBpbmdzIGZvciBlYWNoIGZpZWxkIGluIHRoZSBwcm90by4KKyAgICBmdWxsX25hbWU6IHN0ciwgdGhlIGZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoZSBwcm90byB0eXBlLgorICAgIHBvb2w6IG9wdGlvbmFsIERlc2NyaXB0b3JQb29sIGluc3RhbmNlLgorICBSZXR1cm5zOgorICAgIGEgY2xhc3MsIHRoZSBuZXcgcHJvdG9idWYgY2xhc3Mgd2l0aCBhIEZpbGVEZXNjcmlwdG9yLgorICAiIiIKKyAgZmFjdG9yeSA9IG1lc3NhZ2VfZmFjdG9yeS5NZXNzYWdlRmFjdG9yeShwb29sPXBvb2wpCisgIHRyeToKKyAgICBwcm90b19jbHMgPSBfR2V0TWVzc2FnZUZyb21GYWN0b3J5KGZhY3RvcnksIGZ1bGxfbmFtZSkKKyAgICByZXR1cm4gcHJvdG9fY2xzCisgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAjIFRoZSBmYWN0b3J5J3MgRGVzY3JpcHRvclBvb2wgZG9lc24ndCBrbm93IGFib3V0IHRoaXMgY2xhc3MgeWV0LgorICAgIHBhc3MKKworICAjIFVzZSBhIGNvbnNpc3RlbnQgZmlsZSBuYW1lIHRoYXQgaXMgdW5saWtlbHkgdG8gY29uZmxpY3Qgd2l0aCBhbnkgaW1wb3J0ZWQKKyAgIyBwcm90byBmaWxlcy4KKyAgZmllbGRzX2hhc2ggPSBoYXNobGliLnNoYTEoKQorICBmb3IgZl9uYW1lLCBmX3R5cGUgaW4gc29ydGVkKGZpZWxkcy5pdGVtcygpKToKKyAgICBmaWVsZHNfaGFzaC51cGRhdGUoZl9uYW1lLmVuY29kZSgndXRmOCcpKQorICAgIGZpZWxkc19oYXNoLnVwZGF0ZShzdHIoZl90eXBlKS5lbmNvZGUoJ3V0ZjgnKSkKKyAgcHJvdG9fZmlsZV9uYW1lID0gZmllbGRzX2hhc2guaGV4ZGlnZXN0KCkgKyAnLnByb3RvJworCisgIHBhY2thZ2UsIG5hbWUgPSBmdWxsX25hbWUucnNwbGl0KCcuJywgMSkKKyAgZmlsZV9wcm90byA9IGRlc2NyaXB0b3JfcGIyLkZpbGVEZXNjcmlwdG9yUHJvdG8oKQorICBmaWxlX3Byb3RvLm5hbWUgPSBvcy5wYXRoLmpvaW4ocGFja2FnZS5yZXBsYWNlKCcuJywgJy8nKSwgcHJvdG9fZmlsZV9uYW1lKQorICBmaWxlX3Byb3RvLnBhY2thZ2UgPSBwYWNrYWdlCisgIGRlc2NfcHJvdG8gPSBmaWxlX3Byb3RvLm1lc3NhZ2VfdHlwZS5hZGQoKQorICBkZXNjX3Byb3RvLm5hbWUgPSBuYW1lCisgIGZvciBmX251bWJlciwgKGZfbmFtZSwgZl90eXBlKSBpbiBlbnVtZXJhdGUoc29ydGVkKGZpZWxkcy5pdGVtcygpKSwgMSk6CisgICAgZmllbGRfcHJvdG8gPSBkZXNjX3Byb3RvLmZpZWxkLmFkZCgpCisgICAgZmllbGRfcHJvdG8ubmFtZSA9IGZfbmFtZQorICAgIGZpZWxkX3Byb3RvLm51bWJlciA9IGZfbnVtYmVyCisgICAgZmllbGRfcHJvdG8ubGFiZWwgPSBkZXNjcmlwdG9yX3BiMi5GaWVsZERlc2NyaXB0b3JQcm90by5MQUJFTF9PUFRJT05BTAorICAgIGZpZWxkX3Byb3RvLnR5cGUgPSBmX3R5cGUKKworICBmYWN0b3J5LnBvb2wuQWRkKGZpbGVfcHJvdG8pCisgIHJldHVybiBfR2V0TWVzc2FnZUZyb21GYWN0b3J5KGZhY3RvcnksIGZ1bGxfbmFtZSkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvUkVBRE1FIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9SRUFETUUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmQ2MWNiNAotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvUkVBRE1FCkBAIC0wLDAgKzEsNiBAQAorVGhpcyBpcyB0aGUgJ3YyJyBDKysgaW1wbGVtZW50YXRpb24gZm9yIHB5dGhvbiBwcm90bzIuCisKK0l0IGlzIGFjdGl2ZSB3aGVuOgorCitQUk9UT0NPTF9CVUZGRVJTX1BZVEhPTl9JTVBMRU1FTlRBVElPTj1jcHAKK1BST1RPQ09MX0JVRkZFUlNfUFlUSE9OX0lNUExFTUVOVEFUSU9OX1ZFUlNJT049MgpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9fX2luaXRfXy5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvX19pbml0X18ucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5ZGUyOQotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvX19pbml0X18ucHkKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvY3BwX21lc3NhZ2UucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2NwcF9tZXNzYWdlLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzN2JiNzIKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2NwcF9tZXNzYWdlLnB5CkBAIC0wLDAgKzEsNTcgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiUHJvdG9jb2wgbWVzc2FnZSBpbXBsZW1lbnRhdGlvbiBob29rcyBmb3IgQysrIGltcGxlbWVudGF0aW9uLgorCitDb250YWlucyBoZWxwZXIgZnVuY3Rpb25zIHVzZWQgdG8gY3JlYXRlIHByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcyBmcm9tCitEZXNjcmlwdG9yIG9iamVjdHMgYXQgcnVudGltZSBiYWNrZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBDKysgQVBJLgorIiIiCisKK19fYXV0aG9yX18gPSAndGliZWxsQGdvb2dsZS5jb20gKEpvaGFuIFRpYmVsbCknCisKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLnB5ZXh0IGltcG9ydCBfbWVzc2FnZQorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2UKKworCitkZWYgTmV3TWVzc2FnZShiYXNlcywgbWVzc2FnZV9kZXNjcmlwdG9yLCBkaWN0aW9uYXJ5KToKKyAgIiIiQ3JlYXRlcyBhIG5ldyBwcm90b2NvbCBtZXNzYWdlICpjbGFzcyouIiIiCisgIG5ld19iYXNlcyA9IFtdCisgIGZvciBiYXNlIGluIGJhc2VzOgorICAgIGlmIGJhc2UgaXMgbWVzc2FnZS5NZXNzYWdlOgorICAgICAgIyBfbWVzc2FnZS5NZXNzYWdlIG11c3QgY29tZSBiZWZvcmUgbWVzc2FnZS5NZXNzYWdlIGFzIGl0CisgICAgICAjIG92ZXJyaWRlcyBtZXRob2RzIGluIHRoYXQgY2xhc3MuCisgICAgICBuZXdfYmFzZXMuYXBwZW5kKF9tZXNzYWdlLk1lc3NhZ2UpCisgICAgbmV3X2Jhc2VzLmFwcGVuZChiYXNlKQorICByZXR1cm4gdHVwbGUobmV3X2Jhc2VzKQorCisKK2RlZiBJbml0TWVzc2FnZShtZXNzYWdlX2Rlc2NyaXB0b3IsIGNscyk6CisgICIiIkZpbmFsaXplcyB0aGUgY3JlYXRpb24gb2YgYSBtZXNzYWdlIGNsYXNzLiIiIgorICBjbHMuQWRkRGVzY3JpcHRvcnMobWVzc2FnZV9kZXNjcmlwdG9yKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yLmNjIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3N2QwYmIKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3IuY2MKQEAgLTAsMCArMSwxNDcxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBwZXRhckBnb29nbGUuY29tIChQZXRhciBQZXRyb3YpCisKKyNpbmNsdWRlIDxQeXRob24uaD4KKyNpbmNsdWRlIDxmcmFtZW9iamVjdC5oPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX2NvbnRhaW5lcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9wb29sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvc2NvcGVkX3B5b2JqZWN0X3B0ci5oPgorCisjZGVmaW5lIEMoc3RyKSBjb25zdF9jYXN0PGNoYXIqPihzdHIpCisKKyNpZiBQWV9NQUpPUl9WRVJTSU9OID49IDMKKyAgI2RlZmluZSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSBQeVVuaWNvZGVfRnJvbVN0cmluZ0FuZFNpemUKKyAgI2RlZmluZSBQeVN0cmluZ19DaGVjayBQeVVuaWNvZGVfQ2hlY2sKKyAgI2RlZmluZSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nIFB5VW5pY29kZV9JbnRlcm5Gcm9tU3RyaW5nCisgICNkZWZpbmUgUHlJbnRfRnJvbUxvbmcgUHlMb25nX0Zyb21Mb25nCisgICNkZWZpbmUgUHlJbnRfRnJvbVNpemVfdCBQeUxvbmdfRnJvbVNpemVfdAorICAjaWYgUFlfVkVSU0lPTl9IRVggPCAweDAzMDMwMDAwCisgICAgI2Vycm9yICJQeXRob24gMy4wIC0gMy4yIGFyZSBub3Qgc3VwcG9ydGVkLiIKKyAgI2VuZGlmCisgICNkZWZpbmUgUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG9iLCBjaGFycHAsIHNpemVwKSBcCisgICAgKFB5VW5pY29kZV9DaGVjayhvYik/IFwKKyAgICAgICAoKCooY2hhcnBwKSA9IFB5VW5pY29kZV9Bc1VURjhBbmRTaXplKG9iLCAoc2l6ZXApKSkgPT0gTlVMTD8gLTE6IDApOiBcCisgICAgICAgUHlCeXRlc19Bc1N0cmluZ0FuZFNpemUob2IsIChjaGFycHApLCAoc2l6ZXApKSkKKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworUHlPYmplY3QqIFB5U3RyaW5nX0Zyb21DcHBTdHJpbmcoY29uc3Qgc3RyaW5nJiBzdHIpIHsKKyAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKHN0ci5jX3N0cigpLCBzdHIuc2l6ZSgpKTsKK30KKworLy8gQ2hlY2sgdGhhdCB0aGUgY2FsbGluZyBQeXRob24gY29kZSBpcyB0aGUgZ2xvYmFsIHNjb3BlIG9mIGEgX3BiMi5weSBtb2R1bGUuCisvLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gc3VwcG9ydCB0aGUgY3VycmVudCBjb2RlIGdlbmVyYXRlZCBieSB0aGUgcHJvdG8KKy8vIGNvbXBpbGVyLCB3aGljaCBjcmVhdGVzIGRlc2NyaXB0b3JzLCB0aGVuIHVwZGF0ZSBzb21lIHByb3BlcnRpZXMuCisvLyBGb3IgZXhhbXBsZToKKy8vICAgbWVzc2FnZV9kZXNjcmlwdG9yID0gRGVzY3JpcHRvcigKKy8vICAgICAgIG5hbWU9J01lc3NhZ2UnLAorLy8gICAgICAgZmllbGRzID0gW0ZpZWxkRGVzY3JpcHRvcihuYW1lPSdmaWVsZCcpXQorLy8gICBtZXNzYWdlX2Rlc2NyaXB0b3IuZmllbGRzWzBdLmNvbnRhaW5pbmdfdHlwZSA9IG1lc3NhZ2VfZGVzY3JpcHRvcgorLy8KKy8vIFRoaXMgY29kZSBpcyBzdGlsbCBleGVjdXRlZCwgYnV0IHRoZSBkZXNjcmlwdG9ycyBub3cgaGF2ZSBubyBvdGhlciBzdG9yYWdlCisvLyB0aGFuIHRoZSAoY29uc3QpIEMrKyBwb2ludGVyLCBhbmQgYXJlIGltbXV0YWJsZS4KKy8vIFNvIHdlIGxldCB0aGlzIGNvZGUgcGFzcywgYnkgc2ltcGx5IGlnbm9yaW5nIHRoZSBuZXcgdmFsdWUuCisvLworLy8gRnJvbSB1c2VyIGNvZGUsIGRlc2NyaXB0b3JzIHN0aWxsIGxvb2sgaW1tdXRhYmxlLgorLy8KKy8vIFRPRE8oYW1hdXJ5ZmEpOiBDaGFuZ2UgdGhlIHByb3RvMiBjb21waWxlciB0byByZW1vdmUgdGhlIGFzc2lnbm1lbnRzLCBhbmQKKy8vIHJlbW92ZSB0aGlzIGhhY2suCitib29sIF9DYWxsZWRGcm9tR2VuZXJhdGVkRmlsZShpbnQgc3RhY2tsZXZlbCkgeworICBQeVRocmVhZFN0YXRlICpzdGF0ZSA9IFB5VGhyZWFkU3RhdGVfR0VUKCk7CisgIGlmIChzdGF0ZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIFB5RnJhbWVPYmplY3QqIGZyYW1lID0gc3RhdGUtPmZyYW1lOworICBpZiAoZnJhbWUgPT0gTlVMTCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICB3aGlsZSAoc3RhY2tsZXZlbC0tID4gMCkgeworICAgIGZyYW1lID0gZnJhbWUtPmZfYmFjazsKKyAgICBpZiAoZnJhbWUgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBpZiAoZnJhbWUtPmZfZ2xvYmFscyAhPSBmcmFtZS0+Zl9sb2NhbHMpIHsKKyAgICAvLyBOb3QgYXQgZ2xvYmFsIG1vZHVsZSBzY29wZQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChmcmFtZS0+Zl9jb2RlLT5jb19maWxlbmFtZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGNoYXIqIGZpbGVuYW1lOworICBQeV9zc2l6ZV90IGZpbGVuYW1lX3NpemU7CisgIGlmIChQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoZnJhbWUtPmZfY29kZS0+Y29fZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZpbGVuYW1lLCAmZmlsZW5hbWVfc2l6ZSkgPCAwKSB7CisgICAgLy8gZmlsZW5hbWUgaXMgbm90IGEgc3RyaW5nLgorICAgIFB5RXJyX0NsZWFyKCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChmaWxlbmFtZV9zaXplIDwgNykgeworICAgIC8vIGZpbGVuYW1lIGlzIHRvbyBzaG9ydC4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKHN0cmNtcCgmZmlsZW5hbWVbZmlsZW5hbWVfc2l6ZSAtIDddLCAiX3BiMi5weSIpICE9IDApIHsKKyAgICAvLyBGaWxlbmFtZSBpcyBub3QgZW5kaW5nIHdpdGggX3BiMi4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIElmIHRoZSBjYWxsaW5nIGNvZGUgaXMgbm90IGEgX3BiMi5weSBmaWxlLCByYWlzZSBBdHRyaWJ1dGVFcnJvci4KKy8vIFRvIGJlIHVzZWQgaW4gYXR0cmlidXRlIHNldHRlcnMuCitzdGF0aWMgaW50IENoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoY29uc3QgY2hhciogYXR0cl9uYW1lKSB7CisgIGlmIChfQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoMCkpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAiYXR0cmlidXRlIGlzIG5vdCB3cml0YWJsZTogJXMiLCBhdHRyX25hbWUpOworICByZXR1cm4gLTE7Cit9CisKKworI2lmbmRlZiBQeVZhck9iamVjdF9IRUFEX0lOSVQKKyNkZWZpbmUgUHlWYXJPYmplY3RfSEVBRF9JTklUKHR5cGUsIHNpemUpIFB5T2JqZWN0X0hFQURfSU5JVCh0eXBlKSBzaXplLAorI2VuZGlmCisjaWZuZGVmIFB5X1RZUEUKKyNkZWZpbmUgUHlfVFlQRShvYikgKCgoUHlPYmplY3QqKShvYikpLT5vYl90eXBlKQorI2VuZGlmCisKKworLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgZGVzY3JpcHRvciBvYmplY3RzLgorCisvLyBDb252ZXJ0cyBvcHRpb25zIGludG8gYSBQeXRob24gcHJvdG9idWYsIGFuZCBjYWNoZSB0aGUgcmVzdWx0LgorLy8KKy8vIFRoaXMgaXMgYSBiaXQgdHJpY2t5IGJlY2F1c2Ugb3B0aW9ucyBjYW4gY29udGFpbiBleHRlbnNpb24gZmllbGRzIGRlZmluZWQgaW4KKy8vIHRoZSBzYW1lIHByb3RvIGZpbGUuIEluIHRoaXMgY2FzZSB0aGUgb3B0aW9ucyBwYXJzZWQgZnJvbSB0aGUgc2VyaWFsaXplZF9wYgorLy8gaGF2ZSB1bmtvd24gZmllbGRzLCBhbmQgd2UgbmVlZCB0byBwYXJzZSB0aGVtIGFnYWluLgorLy8KKy8vIEFsd2F5cyByZXR1cm5zIGEgbmV3IHJlZmVyZW5jZS4KK3RlbXBsYXRlPGNsYXNzIERlc2NyaXB0b3JDbGFzcz4KK3N0YXRpYyBQeU9iamVjdCogR2V0T3JCdWlsZE9wdGlvbnMoY29uc3QgRGVzY3JpcHRvckNsYXNzICpkZXNjcmlwdG9yKSB7CisgIGhhc2hfbWFwPGNvbnN0IHZvaWQqLCBQeU9iamVjdCo+KiBkZXNjcmlwdG9yX29wdGlvbnMgPQorICAgICAgR2V0RGVzY3JpcHRvclBvb2woKS0+ZGVzY3JpcHRvcl9vcHRpb25zOworICAvLyBGaXJzdCBzZWFyY2ggaW4gdGhlIGNhY2hlLgorICBpZiAoZGVzY3JpcHRvcl9vcHRpb25zLT5maW5kKGRlc2NyaXB0b3IpICE9IGRlc2NyaXB0b3Jfb3B0aW9ucy0+ZW5kKCkpIHsKKyAgICBQeU9iamVjdCAqdmFsdWUgPSAoKmRlc2NyaXB0b3Jfb3B0aW9ucylbZGVzY3JpcHRvcl07CisgICAgUHlfSU5DUkVGKHZhbHVlKTsKKyAgICByZXR1cm4gdmFsdWU7CisgIH0KKworICAvLyBCdWlsZCB0aGUgT3B0aW9ucyBvYmplY3Q6IGdldCBpdHMgUHl0aG9uIGNsYXNzLCBhbmQgbWFrZSBhIGNvcHkgb2YgdGhlIEMrKworICAvLyByZWFkLW9ubHkgaW5zdGFuY2UuCisgIGNvbnN0IE1lc3NhZ2UmIG9wdGlvbnMoZGVzY3JpcHRvci0+b3B0aW9ucygpKTsKKyAgY29uc3QgRGVzY3JpcHRvciAqbWVzc2FnZV90eXBlID0gb3B0aW9ucy5HZXREZXNjcmlwdG9yKCk7CisgIFB5T2JqZWN0KiBtZXNzYWdlX2NsYXNzKGNkZXNjcmlwdG9yX3Bvb2w6OkdldE1lc3NhZ2VDbGFzcygKKyAgICAgIEdldERlc2NyaXB0b3JQb29sKCksIG1lc3NhZ2VfdHlwZSkpOworICBpZiAobWVzc2FnZV9jbGFzcyA9PSBOVUxMKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIkNvdWxkIG5vdCByZXRyaWV2ZSBjbGFzcyBmb3IgT3B0aW9uczogJXMiLAorICAgICAgICAgICAgICAgICBtZXNzYWdlX3R5cGUtPmZ1bGxfbmFtZSgpLmNfc3RyKCkpOworICAgIHJldHVybiBOVUxMOworICB9CisgIFNjb3BlZFB5T2JqZWN0UHRyIHZhbHVlKFB5RXZhbF9DYWxsT2JqZWN0KG1lc3NhZ2VfY2xhc3MsIE5VTEwpKTsKKyAgaWYgKHZhbHVlID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBDTWVzc2FnZSogY21zZyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Q01lc3NhZ2UqPih2YWx1ZS5nZXQoKSk7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG9wdGlvbnMuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKHJlZmxlY3Rpb24tPkdldFVua25vd25GaWVsZHMob3B0aW9ucykpOworICBpZiAodW5rbm93bl9maWVsZHMuZW1wdHkoKSkgeworICAgIGNtc2ctPm1lc3NhZ2UtPkNvcHlGcm9tKG9wdGlvbnMpOworICB9IGVsc2UgeworICAgIC8vIFJlcGFyc2Ugb3B0aW9ucyBzdHJpbmchICBYWFggY2FsbCBjbWVzc2FnZTo6TWVyZ2VGcm9tU3RyaW5nCisgICAgc3RyaW5nIHNlcmlhbGl6ZWQ7CisgICAgb3B0aW9ucy5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoCisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihzZXJpYWxpemVkLmNfc3RyKCkpLCBzZXJpYWxpemVkLnNpemUoKSk7CisgICAgaW5wdXQuU2V0RXh0ZW5zaW9uUmVnaXN0cnkoR2V0RGVzY3JpcHRvclBvb2woKS0+cG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbWVzc2FnZTo6R2V0TWVzc2FnZUZhY3RvcnkoKSk7CisgICAgYm9vbCBzdWNjZXNzID0gY21zZy0+bWVzc2FnZS0+TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCk7CisgICAgaWYgKCFzdWNjZXNzKSB7CisgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgIkVycm9yIHBhcnNpbmcgT3B0aW9ucyBtZXNzYWdlIik7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgIH0KKworICAvLyBDYWNoZSB0aGUgcmVzdWx0LgorICBQeV9JTkNSRUYodmFsdWUpOworICAoKkdldERlc2NyaXB0b3JQb29sKCktPmRlc2NyaXB0b3Jfb3B0aW9ucylbZGVzY3JpcHRvcl0gPSB2YWx1ZS5nZXQoKTsKKworICByZXR1cm4gdmFsdWUucmVsZWFzZSgpOworfQorCisvLyBDb3B5IHRoZSBDKysgZGVzY3JpcHRvciB0byBhIFB5dGhvbiBtZXNzYWdlLgorLy8gVGhlIFB5dGhvbiBtZXNzYWdlIGlzIGFuIGluc3RhbmNlIG9mIGRlc2NyaXB0b3JfcGIyLkRlc2NyaXB0b3JQcm90bworLy8gb3Igc2ltaWxhci4KK3RlbXBsYXRlPGNsYXNzIERlc2NyaXB0b3JQcm90b0NsYXNzLCBjbGFzcyBEZXNjcmlwdG9yQ2xhc3M+CitzdGF0aWMgUHlPYmplY3QqIENvcHlUb1B5dGhvblByb3RvKGNvbnN0IERlc2NyaXB0b3JDbGFzcyAqZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnRhcmdldCkgeworICBjb25zdCBEZXNjcmlwdG9yKiBzZWxmX2Rlc2NyaXB0b3IgPQorICAgICAgRGVzY3JpcHRvclByb3RvQ2xhc3M6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXREZXNjcmlwdG9yKCk7CisgIENNZXNzYWdlKiBtZXNzYWdlID0gcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KHRhcmdldCk7CisgIGlmICghUHlPYmplY3RfVHlwZUNoZWNrKHRhcmdldCwgJkNNZXNzYWdlX1R5cGUpIHx8CisgICAgICBtZXNzYWdlLT5tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCkgIT0gc2VsZl9kZXNjcmlwdG9yKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIk5vdCBhICVzIG1lc3NhZ2UiLAorICAgICAgICAgICAgICAgICBzZWxmX2Rlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLmNfc3RyKCkpOworICAgIHJldHVybiBOVUxMOworICB9CisgIGNtZXNzYWdlOjpBc3N1cmVXcml0YWJsZShtZXNzYWdlKTsKKyAgRGVzY3JpcHRvclByb3RvQ2xhc3MqIGRlc2NyaXB0b3JfbWVzc2FnZSA9CisgICAgICBzdGF0aWNfY2FzdDxEZXNjcmlwdG9yUHJvdG9DbGFzcyo+KG1lc3NhZ2UtPm1lc3NhZ2UpOworICBkZXNjcmlwdG9yLT5Db3B5VG8oZGVzY3JpcHRvcl9tZXNzYWdlKTsKKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKKy8vIEFsbCBEZXNjcmlwdG9ycyBjbGFzc2VzIHNoYXJlIHRoZSBzYW1lIG1lbW9yeSBsYXlvdXQuCit0eXBlZGVmIHN0cnVjdCBQeUJhc2VEZXNjcmlwdG9yIHsKKyAgUHlPYmplY3RfSEVBRAorCisgIC8vIFBvaW50ZXIgdG8gdGhlIEMrKyBwcm90bzIgZGVzY3JpcHRvci4KKyAgLy8gTGlrZSBhbGwgZGVzY3JpcHRvcnMsIGl0IGlzIG93bmVkIGJ5IHRoZSBnbG9iYWwgRGVzY3JpcHRvclBvb2wuCisgIGNvbnN0IHZvaWQqIGRlc2NyaXB0b3I7Cit9IFB5QmFzZURlc2NyaXB0b3I7CisKKworLy8gRmlsZURlc2NyaXB0b3Igc3RydWN0dXJlICJpbmhlcml0cyIgZnJvbSB0aGUgYmFzZSBkZXNjcmlwdG9yLgordHlwZWRlZiBzdHJ1Y3QgUHlGaWxlRGVzY3JpcHRvciB7CisgIFB5QmFzZURlc2NyaXB0b3IgYmFzZTsKKworICAvLyBUaGUgY2FjaGVkIHZlcnNpb24gb2Ygc2VyaWFsaXplZCBwYi4gRWl0aGVyIE5VTEwsIG9yIGEgQnl0ZXMgc3RyaW5nLgorICAvLyBXZSBvd24gdGhlIHJlZmVyZW5jZS4KKyAgUHlPYmplY3QgKnNlcmlhbGl6ZWRfcGI7Cit9IFB5RmlsZURlc2NyaXB0b3I7CisKKworbmFtZXNwYWNlIGRlc2NyaXB0b3IgeworCisvLyBDcmVhdGVzIG9yIHJldHJpZXZlIGEgUHl0aG9uIGRlc2NyaXB0b3Igb2YgdGhlIHNwZWNpZmllZCB0eXBlLgorLy8gT2JqZWN0cyBhcmUgaW50ZXJuZWQ6IHRoZSBzYW1lIGRlc2NyaXB0b3Igd2lsbCByZXR1cm4gdGhlIHNhbWUgb2JqZWN0IGlmIGl0CisvLyB3YXMga2VwdCBhbGl2ZS4KKy8vIEFsd2F5cyByZXR1cm4gYSBuZXcgcmVmZXJlbmNlLgorUHlPYmplY3QqIE5ld0ludGVybmVkRGVzY3JpcHRvcihQeVR5cGVPYmplY3QqIHR5cGUsIGNvbnN0IHZvaWQqIGRlc2NyaXB0b3IpIHsKKyAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gU2VlIGlmIHRoZSBvYmplY3QgaXMgaW4gdGhlIG1hcCBvZiBpbnRlcm5lZCBkZXNjcmlwdG9ycworICBoYXNoX21hcDxjb25zdCB2b2lkKiwgUHlPYmplY3QqPjo6aXRlcmF0b3IgaXQgPQorICAgICAgR2V0RGVzY3JpcHRvclBvb2woKS0+aW50ZXJuZWRfZGVzY3JpcHRvcnMtPmZpbmQoZGVzY3JpcHRvcik7CisgIGlmIChpdCAhPSBHZXREZXNjcmlwdG9yUG9vbCgpLT5pbnRlcm5lZF9kZXNjcmlwdG9ycy0+ZW5kKCkpIHsKKyAgICBHT09HTEVfRENIRUNLKFB5X1RZUEUoaXQtPnNlY29uZCkgPT0gdHlwZSk7CisgICAgUHlfSU5DUkVGKGl0LT5zZWNvbmQpOworICAgIHJldHVybiBpdC0+c2Vjb25kOworICB9CisgIC8vIENyZWF0ZSBhIG5ldyBkZXNjcmlwdG9yIG9iamVjdAorICBQeUJhc2VEZXNjcmlwdG9yKiBweV9kZXNjcmlwdG9yID0gUHlPYmplY3RfTmV3KAorICAgICAgUHlCYXNlRGVzY3JpcHRvciwgdHlwZSk7CisgIGlmIChweV9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBweV9kZXNjcmlwdG9yLT5kZXNjcmlwdG9yID0gZGVzY3JpcHRvcjsKKyAgLy8gYW5kIGNhY2hlIGl0LgorICBHZXREZXNjcmlwdG9yUG9vbCgpLT5pbnRlcm5lZF9kZXNjcmlwdG9ycy0+aW5zZXJ0KAorICAgICAgc3RkOjptYWtlX3BhaXIoZGVzY3JpcHRvciwgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHB5X2Rlc2NyaXB0b3IpKSk7CisKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihweV9kZXNjcmlwdG9yKTsKK30KKworc3RhdGljIHZvaWQgRGVhbGxvYyhQeUJhc2VEZXNjcmlwdG9yKiBzZWxmKSB7CisgIC8vIFJlbW92ZSBmcm9tIGludGVybmVkIGRpY3Rpb25hcnkKKyAgR2V0RGVzY3JpcHRvclBvb2woKS0+aW50ZXJuZWRfZGVzY3JpcHRvcnMtPmVyYXNlKHNlbGYtPmRlc2NyaXB0b3IpOworICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiBHZXR0ZXJzW10gPSB7CisgIHtOVUxMfQorfTsKKworUHlUeXBlT2JqZWN0IFB5QmFzZURlc2NyaXB0b3JfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgLy8gS2VlcCB0aGUgZnVsbHkgcXVhbGlmaWVkIF9tZXNzYWdlIHN5bWJvbCBpbiBhIGxpbmUgZm9yIG9wZW5zb3VyY2UuCisgICJnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuX21lc3NhZ2UuIgorICAiRGVzY3JpcHRvckJhc2UiLCAgICAgICAgICAgICAgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5QmFzZURlc2NyaXB0b3IpLCAgICAgICAgICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVtc2l6ZQorICAoZGVzdHJ1Y3RvcilEZWFsbG9jLCAgICAgICAgICAgICAgICAgIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19zZXF1ZW5jZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX21hcHBpbmcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2FsbAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3N0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19idWZmZXIKKyAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICAiRGVzY3JpcHRvcnMgYmFzZSBjbGFzcyIsICAgICAgICAgICAgIC8vIHRwX2RvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3RyYXZlcnNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yaWNoY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3dlYWtsaXN0b2Zmc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXJuZXh0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbWV0aG9kcworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21lbWJlcnMKKyAgR2V0dGVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRzZXQKK307CisKK30gIC8vIG5hbWVzcGFjZSBkZXNjcmlwdG9yCisKK2NvbnN0IHZvaWQqIFB5RGVzY3JpcHRvcl9Bc1ZvaWRQdHIoUHlPYmplY3QqIG9iaikgeworICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhvYmosICZkZXNjcmlwdG9yOjpQeUJhc2VEZXNjcmlwdG9yX1R5cGUpKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIk5vdCBhIEJhc2VEZXNjcmlwdG9yIik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UHlCYXNlRGVzY3JpcHRvcio+KG9iaiktPmRlc2NyaXB0b3I7Cit9CisKK25hbWVzcGFjZSBtZXNzYWdlX2Rlc2NyaXB0b3IgeworCisvLyBVbmNoZWNrZWQgYWNjZXNzb3IgdG8gdGhlIEMrKyBwb2ludGVyLgorc3RhdGljIGNvbnN0IERlc2NyaXB0b3IqIF9HZXREZXNjcmlwdG9yKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYpIHsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgRGVzY3JpcHRvcio+KHNlbGYtPmRlc2NyaXB0b3IpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE5hbWUoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfRnJvbUNwcFN0cmluZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+bmFtZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRGdWxsTmFtZShQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeVN0cmluZ19Gcm9tQ3BwU3RyaW5nKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5mdWxsX25hbWUoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0RmlsZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeUZpbGVEZXNjcmlwdG9yX05ldyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZmlsZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRDb25jcmV0ZUNsYXNzKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgUHlPYmplY3QqIGNvbmNyZXRlX2NsYXNzKGNkZXNjcmlwdG9yX3Bvb2w6OkdldE1lc3NhZ2VDbGFzcygKKyAgICAgIEdldERlc2NyaXB0b3JQb29sKCksIF9HZXREZXNjcmlwdG9yKHNlbGYpKSk7CisgIFB5X1hJTkNSRUYoY29uY3JldGVfY2xhc3MpOworICByZXR1cm4gY29uY3JldGVfY2xhc3M7Cit9CisKK3N0YXRpYyBpbnQgU2V0Q29uY3JldGVDbGFzcyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICAvLyBUaGlzIGF0dHJpYnV0ZSBpcyBhbHNvIHNldCBmcm9tIHJlZmxlY3Rpb24ucHkuIENoZWNrIHRoYXQgaXQncyBhY3R1YWxseSBhCisgIC8vIG5vLW9wLgorICBpZiAodmFsdWUgIT0gY2Rlc2NyaXB0b3JfcG9vbDo6R2V0TWVzc2FnZUNsYXNzKAorICAgICAgICAgIEdldERlc2NyaXB0b3JQb29sKCksIF9HZXREZXNjcmlwdG9yKHNlbGYpKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19BdHRyaWJ1dGVFcnJvciwgIkNhbm5vdCBjaGFuZ2UgX2NvbmNyZXRlX2NsYXNzIik7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0RmllbGRzQnlOYW1lKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld01lc3NhZ2VGaWVsZHNCeU5hbWUoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEZpZWxkc0J5TnVtYmVyKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld01lc3NhZ2VGaWVsZHNCeU51bWJlcihfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0RmllbGRzU2VxKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld01lc3NhZ2VGaWVsZHNTZXEoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE5lc3RlZFR5cGVzQnlOYW1lKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld01lc3NhZ2VOZXN0ZWRUeXBlc0J5TmFtZShfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0TmVzdGVkVHlwZXNTZXEoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gTmV3TWVzc2FnZU5lc3RlZFR5cGVzU2VxKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRFeHRlbnNpb25zQnlOYW1lKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld01lc3NhZ2VFeHRlbnNpb25zQnlOYW1lKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRFeHRlbnNpb25zKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld01lc3NhZ2VFeHRlbnNpb25zU2VxKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRFbnVtc1NlcShQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBOZXdNZXNzYWdlRW51bXNTZXEoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEVudW1UeXBlc0J5TmFtZShQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBOZXdNZXNzYWdlRW51bXNCeU5hbWUoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEVudW1WYWx1ZXNCeU5hbWUoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gTmV3TWVzc2FnZUVudW1WYWx1ZXNCeU5hbWUoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE9uZW9mc0J5TmFtZShQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBOZXdNZXNzYWdlT25lb2ZzQnlOYW1lKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRPbmVvZnNTZXEoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gTmV3TWVzc2FnZU9uZW9mc1NlcShfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogSXNFeHRlbmRhYmxlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgaWYgKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBQeV9SRVRVUk5fVFJVRTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fRkFMU0U7CisgIH0KK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRFeHRlbnNpb25SYW5nZXMoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gX0dldERlc2NyaXB0b3Ioc2VsZik7CisgIFB5T2JqZWN0KiByYW5nZV9saXN0ID0gUHlMaXN0X05ldyhkZXNjcmlwdG9yLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlID0gZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX3JhbmdlKGkpOworICAgIFB5T2JqZWN0KiBzdGFydCA9IFB5SW50X0Zyb21Mb25nKHJhbmdlLT5zdGFydCk7CisgICAgUHlPYmplY3QqIGVuZCA9IFB5SW50X0Zyb21Mb25nKHJhbmdlLT5lbmQpOworICAgIFB5TGlzdF9TZXRJdGVtKHJhbmdlX2xpc3QsIGksIFB5VHVwbGVfUGFjaygyLCBzdGFydCwgZW5kKSk7CisgIH0KKworICByZXR1cm4gcmFuZ2VfbGlzdDsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRDb250YWluaW5nVHlwZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSA9CisgICAgICBfR2V0RGVzY3JpcHRvcihzZWxmKS0+Y29udGFpbmluZ190eXBlKCk7CisgIGlmIChjb250YWluaW5nX3R5cGUpIHsKKyAgICByZXR1cm4gUHlNZXNzYWdlRGVzY3JpcHRvcl9OZXcoY29udGFpbmluZ190eXBlKTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorfQorCitzdGF0aWMgaW50IFNldENvbnRhaW5pbmdUeXBlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgiY29udGFpbmluZ190eXBlIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0SGFzT3B0aW9ucyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBvcHRpb25zKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5vcHRpb25zKCkpOworICBpZiAoJm9wdGlvbnMgIT0gJk1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBQeV9SRVRVUk5fVFJVRTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fRkFMU0U7CisgIH0KK30KK3N0YXRpYyBpbnQgU2V0SGFzT3B0aW9ucyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIENoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoImhhc19vcHRpb25zIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0T3B0aW9ucyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmKSB7CisgIHJldHVybiBHZXRPckJ1aWxkT3B0aW9ucyhfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBpbnQgU2V0T3B0aW9ucyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgiX29wdGlvbnMiKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBDb3B5VG9Qcm90byhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdGFyZ2V0KSB7CisgIHJldHVybiBDb3B5VG9QeXRob25Qcm90bzxEZXNjcmlwdG9yUHJvdG8+KF9HZXREZXNjcmlwdG9yKHNlbGYpLCB0YXJnZXQpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEVudW1WYWx1ZU5hbWUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpIHsKKyAgY29uc3QgY2hhciAqZW51bV9uYW1lOworICBpbnQgbnVtYmVyOworICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInNpIiwgJmVudW1fbmFtZSwgJm51bWJlcikpCisgICAgcmV0dXJuIE5VTEw7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yICplbnVtX3R5cGUgPQorICAgICAgX0dldERlc2NyaXB0b3Ioc2VsZiktPkZpbmRFbnVtVHlwZUJ5TmFtZShlbnVtX25hbWUpOworICBpZiAoZW51bV90eXBlID09IE5VTEwpIHsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfS2V5RXJyb3IsIGVudW1fbmFtZSk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciAqZW51bV92YWx1ZSA9CisgICAgICBlbnVtX3R5cGUtPkZpbmRWYWx1ZUJ5TnVtYmVyKG51bWJlcik7CisgIGlmIChlbnVtX3ZhbHVlID09IE5VTEwpIHsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfS2V5RXJyb3IsICIlZCIsIG51bWJlcik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIFB5U3RyaW5nX0Zyb21DcHBTdHJpbmcoZW51bV92YWx1ZS0+bmFtZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRTeW50YXgoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygKKyAgICAgIEZpbGVEZXNjcmlwdG9yOjpTeW50YXhOYW1lKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5maWxlKCktPnN5bnRheCgpKSk7Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiBHZXR0ZXJzW10gPSB7CisgIHsgQygibmFtZSIpLCAoZ2V0dGVyKUdldE5hbWUsIE5VTEwsICJMYXN0IG5hbWUiLCBOVUxMfSwKKyAgeyBDKCJmdWxsX25hbWUiKSwgKGdldHRlcilHZXRGdWxsTmFtZSwgTlVMTCwgIkZ1bGwgbmFtZSIsIE5VTEx9LAorICB7IEMoIl9jb25jcmV0ZV9jbGFzcyIpLCAoZ2V0dGVyKUdldENvbmNyZXRlQ2xhc3MsIChzZXR0ZXIpU2V0Q29uY3JldGVDbGFzcywgImNvbmNyZXRlIGNsYXNzIiwgTlVMTH0sCisgIHsgQygiZmlsZSIpLCAoZ2V0dGVyKUdldEZpbGUsIE5VTEwsICJGaWxlIGRlc2NyaXB0b3IiLCBOVUxMfSwKKworICB7IEMoImZpZWxkcyIpLCAoZ2V0dGVyKUdldEZpZWxkc1NlcSwgTlVMTCwgIkZpZWxkcyBzZXF1ZW5jZSIsIE5VTEx9LAorICB7IEMoImZpZWxkc19ieV9uYW1lIiksIChnZXR0ZXIpR2V0RmllbGRzQnlOYW1lLCBOVUxMLCAiRmllbGRzIGJ5IG5hbWUiLCBOVUxMfSwKKyAgeyBDKCJmaWVsZHNfYnlfbnVtYmVyIiksIChnZXR0ZXIpR2V0RmllbGRzQnlOdW1iZXIsIE5VTEwsICJGaWVsZHMgYnkgbnVtYmVyIiwgTlVMTH0sCisgIHsgQygibmVzdGVkX3R5cGVzIiksIChnZXR0ZXIpR2V0TmVzdGVkVHlwZXNTZXEsIE5VTEwsICJOZXN0ZWQgdHlwZXMgc2VxdWVuY2UiLCBOVUxMfSwKKyAgeyBDKCJuZXN0ZWRfdHlwZXNfYnlfbmFtZSIpLCAoZ2V0dGVyKUdldE5lc3RlZFR5cGVzQnlOYW1lLCBOVUxMLCAiTmVzdGVkIHR5cGVzIGJ5IG5hbWUiLCBOVUxMfSwKKyAgeyBDKCJleHRlbnNpb25zIiksIChnZXR0ZXIpR2V0RXh0ZW5zaW9ucywgTlVMTCwgIkV4dGVuc2lvbnMgU2VxdWVuY2UiLCBOVUxMfSwKKyAgeyBDKCJleHRlbnNpb25zX2J5X25hbWUiKSwgKGdldHRlcilHZXRFeHRlbnNpb25zQnlOYW1lLCBOVUxMLCAiRXh0ZW5zaW9ucyBieSBuYW1lIiwgTlVMTH0sCisgIHsgQygiZXh0ZW5zaW9uX3JhbmdlcyIpLCAoZ2V0dGVyKUdldEV4dGVuc2lvblJhbmdlcywgTlVMTCwgIkV4dGVuc2lvbiByYW5nZXMiLCBOVUxMfSwKKyAgeyBDKCJlbnVtX3R5cGVzIiksIChnZXR0ZXIpR2V0RW51bXNTZXEsIE5VTEwsICJFbnVtIHNlcXVlbmNlIiwgTlVMTH0sCisgIHsgQygiZW51bV90eXBlc19ieV9uYW1lIiksIChnZXR0ZXIpR2V0RW51bVR5cGVzQnlOYW1lLCBOVUxMLCAiRW51bSB0eXBlcyBieSBuYW1lIiwgTlVMTH0sCisgIHsgQygiZW51bV92YWx1ZXNfYnlfbmFtZSIpLCAoZ2V0dGVyKUdldEVudW1WYWx1ZXNCeU5hbWUsIE5VTEwsICJFbnVtIHZhbHVlcyBieSBuYW1lIiwgTlVMTH0sCisgIHsgQygib25lb2ZzX2J5X25hbWUiKSwgKGdldHRlcilHZXRPbmVvZnNCeU5hbWUsIE5VTEwsICJPbmVvZnMgYnkgbmFtZSIsIE5VTEx9LAorICB7IEMoIm9uZW9mcyIpLCAoZ2V0dGVyKUdldE9uZW9mc1NlcSwgTlVMTCwgIk9uZW9mcyBieSBuYW1lIiwgTlVMTH0sCisgIHsgQygiY29udGFpbmluZ190eXBlIiksIChnZXR0ZXIpR2V0Q29udGFpbmluZ1R5cGUsIChzZXR0ZXIpU2V0Q29udGFpbmluZ1R5cGUsICJDb250YWluaW5nIHR5cGUiLCBOVUxMfSwKKyAgeyBDKCJpc19leHRlbmRhYmxlIiksIChnZXR0ZXIpSXNFeHRlbmRhYmxlLCAoc2V0dGVyKU5VTEwsIE5VTEwsIE5VTEx9LAorICB7IEMoImhhc19vcHRpb25zIiksIChnZXR0ZXIpR2V0SGFzT3B0aW9ucywgKHNldHRlcilTZXRIYXNPcHRpb25zLCAiSGFzIE9wdGlvbnMiLCBOVUxMfSwKKyAgeyBDKCJfb3B0aW9ucyIpLCAoZ2V0dGVyKU5VTEwsIChzZXR0ZXIpU2V0T3B0aW9ucywgIk9wdGlvbnMiLCBOVUxMfSwKKyAgeyBDKCJzeW50YXgiKSwgKGdldHRlcilHZXRTeW50YXgsIChzZXR0ZXIpTlVMTCwgIlN5bnRheCIsIE5VTEx9LAorICB7TlVMTH0KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBNZXRob2RzW10gPSB7CisgIHsgIkdldE9wdGlvbnMiLCAoUHlDRnVuY3Rpb24pR2V0T3B0aW9ucywgTUVUSF9OT0FSR1MsIH0sCisgIHsgIkNvcHlUb1Byb3RvIiwgKFB5Q0Z1bmN0aW9uKUNvcHlUb1Byb3RvLCBNRVRIX08sIH0sCisgIHsgIkVudW1WYWx1ZU5hbWUiLCAoUHlDRnVuY3Rpb24pRW51bVZhbHVlTmFtZSwgTUVUSF9WQVJBUkdTLCB9LAorICB7TlVMTH0KK307CisKK30gIC8vIG5hbWVzcGFjZSBtZXNzYWdlX2Rlc2NyaXB0b3IKKworUHlUeXBlT2JqZWN0IFB5TWVzc2FnZURlc2NyaXB0b3JfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgLy8gS2VlcCB0aGUgZnVsbHkgcXVhbGlmaWVkIF9tZXNzYWdlIHN5bWJvbCBpbiBhIGxpbmUgZm9yIG9wZW5zb3VyY2UuCisgIEMoImdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC5fbWVzc2FnZS4iCisgICAgIk1lc3NhZ2VEZXNjcmlwdG9yIiksICAgICAgLy8gdHBfbmFtZQorICBzaXplb2YoUHlCYXNlRGVzY3JpcHRvciksICAgICAgICAgICAgIC8vIHRwX2Jhc2ljc2l6ZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZW1zaXplCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZGVhbGxvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3ByaW50CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZ2V0YXR0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3NldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9jb21wYXJlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfcmVwcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX251bWJlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX3NlcXVlbmNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfbWFwcGluZworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2hhc2gKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9jYWxsCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc3RyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZ2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX2J1ZmZlcgorICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAgIC8vIHRwX2ZsYWdzCisgIEMoIkEgTWVzc2FnZSBEZXNjcmlwdG9yIiksICAgICAgICAgICAgLy8gdHBfZG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfdHJhdmVyc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9jbGVhcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JpY2hjb21wYXJlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfd2Vha2xpc3RvZmZzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcm5leHQKKyAgbWVzc2FnZV9kZXNjcmlwdG9yOjpNZXRob2RzLCAgICAgICAgICAvLyB0cF9tZXRob2RzCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbWVtYmVycworICBtZXNzYWdlX2Rlc2NyaXB0b3I6OkdldHRlcnMsICAgICAgICAgIC8vIHRwX2dldHNldAorICAmZGVzY3JpcHRvcjo6UHlCYXNlRGVzY3JpcHRvcl9UeXBlLCAgIC8vIHRwX2Jhc2UKK307CisKK1B5T2JqZWN0KiBQeU1lc3NhZ2VEZXNjcmlwdG9yX05ldygKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX2Rlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld0ludGVybmVkRGVzY3JpcHRvcigKKyAgICAgICZQeU1lc3NhZ2VEZXNjcmlwdG9yX1R5cGUsIG1lc3NhZ2VfZGVzY3JpcHRvcik7Cit9CisKK2NvbnN0IERlc2NyaXB0b3IqIFB5TWVzc2FnZURlc2NyaXB0b3JfQXNEZXNjcmlwdG9yKFB5T2JqZWN0KiBvYmopIHsKKyAgaWYgKCFQeU9iamVjdF9UeXBlQ2hlY2sob2JqLCAmUHlNZXNzYWdlRGVzY3JpcHRvcl9UeXBlKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJOb3QgYSBNZXNzYWdlRGVzY3JpcHRvciIpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IERlc2NyaXB0b3IqPigKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UHlCYXNlRGVzY3JpcHRvcio+KG9iaiktPmRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZmllbGRfZGVzY3JpcHRvciB7CisKKy8vIFVuY2hlY2tlZCBhY2Nlc3NvciB0byB0aGUgQysrIHBvaW50ZXIuCitzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yKiBfR2V0RGVzY3JpcHRvcigKKyAgICBQeUJhc2VEZXNjcmlwdG9yICpzZWxmKSB7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KHNlbGYtPmRlc2NyaXB0b3IpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEZ1bGxOYW1lKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5U3RyaW5nX0Zyb21DcHBTdHJpbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPmZ1bGxfbmFtZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXROYW1lKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5U3RyaW5nX0Zyb21DcHBTdHJpbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPm5hbWUoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0VHlwZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeUludF9Gcm9tTG9uZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+dHlwZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRDcHBUeXBlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5jcHBfdHlwZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRMYWJlbChQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeUludF9Gcm9tTG9uZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+bGFiZWwoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0TnVtYmVyKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5udW1iZXIoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0SW5kZXgoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPmluZGV4KCkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldElEKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5TG9uZ19Gcm9tVm9pZFB0cihzZWxmKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBJc0V4dGVuc2lvbihQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPmlzX2V4dGVuc2lvbigpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBIYXNEZWZhdWx0VmFsdWUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXREZWZhdWx0VmFsdWUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICBQeU9iamVjdCAqcmVzdWx0OworCisgIHN3aXRjaCAoX0dldERlc2NyaXB0b3Ioc2VsZiktPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjogeworICAgICAgaW50MzIgdmFsdWUgPSBfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZGVmYXVsdF92YWx1ZV9pbnQzMigpOworICAgICAgcmVzdWx0ID0gUHlJbnRfRnJvbUxvbmcodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OiB7CisgICAgICBpbnQ2NCB2YWx1ZSA9IF9HZXREZXNjcmlwdG9yKHNlbGYpLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCk7CisgICAgICByZXN1bHQgPSBQeUxvbmdfRnJvbUxvbmdMb25nKHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6IHsKKyAgICAgIHVpbnQzMiB2YWx1ZSA9IF9HZXREZXNjcmlwdG9yKHNlbGYpLT5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpOworICAgICAgcmVzdWx0ID0gUHlJbnRfRnJvbVNpemVfdCh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OiB7CisgICAgICB1aW50NjQgdmFsdWUgPSBfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZGVmYXVsdF92YWx1ZV91aW50NjQoKTsKKyAgICAgIHJlc3VsdCA9IFB5TG9uZ19Gcm9tVW5zaWduZWRMb25nTG9uZyh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6IHsKKyAgICAgIGZsb2F0IHZhbHVlID0gX0dldERlc2NyaXB0b3Ioc2VsZiktPmRlZmF1bHRfdmFsdWVfZmxvYXQoKTsKKyAgICAgIHJlc3VsdCA9IFB5RmxvYXRfRnJvbURvdWJsZSh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKTsKKyAgICAgIHJlc3VsdCA9IFB5RmxvYXRfRnJvbURvdWJsZSh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDogeworICAgICAgYm9vbCB2YWx1ZSA9IF9HZXREZXNjcmlwdG9yKHNlbGYpLT5kZWZhdWx0X3ZhbHVlX2Jvb2woKTsKKyAgICAgIHJlc3VsdCA9IFB5Qm9vbF9Gcm9tTG9uZyh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICBzdHJpbmcgdmFsdWUgPSBfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKTsKKyAgICAgIHJlc3VsdCA9IFRvU3RyaW5nT2JqZWN0KF9HZXREZXNjcmlwdG9yKHNlbGYpLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTogeworICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPQorICAgICAgICAgIF9HZXREZXNjcmlwdG9yKHNlbGYpLT5kZWZhdWx0X3ZhbHVlX2VudW0oKTsKKyAgICAgIHJlc3VsdCA9IFB5SW50X0Zyb21Mb25nKHZhbHVlLT5udW1iZXIoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yLCAiZGVmYXVsdCB2YWx1ZSBmb3IgJXMiLAorICAgICAgICAgICAgICAgICAgIF9HZXREZXNjcmlwdG9yKHNlbGYpLT5mdWxsX25hbWUoKS5jX3N0cigpKTsKKyAgICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0Q0Rlc2NyaXB0b3IoUHlPYmplY3QgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgUHlfSU5DUkVGKHNlbGYpOworICByZXR1cm4gc2VsZjsKK30KKworc3RhdGljIFB5T2JqZWN0ICpHZXRFbnVtVHlwZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUgPSBfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZW51bV90eXBlKCk7CisgIGlmIChlbnVtX3R5cGUpIHsKKyAgICByZXR1cm4gUHlFbnVtRGVzY3JpcHRvcl9OZXcoZW51bV90eXBlKTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorfQorCitzdGF0aWMgaW50IFNldEVudW1UeXBlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgiZW51bV90eXBlIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqR2V0TWVzc2FnZVR5cGUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUgPSBfR2V0RGVzY3JpcHRvcihzZWxmKS0+bWVzc2FnZV90eXBlKCk7CisgIGlmIChtZXNzYWdlX3R5cGUpIHsKKyAgICByZXR1cm4gUHlNZXNzYWdlRGVzY3JpcHRvcl9OZXcobWVzc2FnZV90eXBlKTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorfQorCitzdGF0aWMgaW50IFNldE1lc3NhZ2VUeXBlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgibWVzc2FnZV90eXBlIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0Q29udGFpbmluZ1R5cGUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUgPQorICAgICAgX0dldERlc2NyaXB0b3Ioc2VsZiktPmNvbnRhaW5pbmdfdHlwZSgpOworICBpZiAoY29udGFpbmluZ190eXBlKSB7CisgICAgcmV0dXJuIFB5TWVzc2FnZURlc2NyaXB0b3JfTmV3KGNvbnRhaW5pbmdfdHlwZSk7CisgIH0gZWxzZSB7CisgICAgUHlfUkVUVVJOX05PTkU7CisgIH0KK30KKworc3RhdGljIGludCBTZXRDb250YWluaW5nVHlwZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIENoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoImNvbnRhaW5pbmdfdHlwZSIpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEV4dGVuc2lvblNjb3BlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5zaW9uX3Njb3BlID0KKyAgICAgIF9HZXREZXNjcmlwdG9yKHNlbGYpLT5leHRlbnNpb25fc2NvcGUoKTsKKyAgaWYgKGV4dGVuc2lvbl9zY29wZSkgeworICAgIHJldHVybiBQeU1lc3NhZ2VEZXNjcmlwdG9yX05ldyhleHRlbnNpb25fc2NvcGUpOworICB9IGVsc2UgeworICAgIFB5X1JFVFVSTl9OT05FOworICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0Q29udGFpbmluZ09uZW9mKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBjb250YWluaW5nX29uZW9mID0KKyAgICAgIF9HZXREZXNjcmlwdG9yKHNlbGYpLT5jb250YWluaW5nX29uZW9mKCk7CisgIGlmIChjb250YWluaW5nX29uZW9mKSB7CisgICAgcmV0dXJuIFB5T25lb2ZEZXNjcmlwdG9yX05ldyhjb250YWluaW5nX29uZW9mKTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorfQorCitzdGF0aWMgaW50IFNldENvbnRhaW5pbmdPbmVvZihQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBDaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKCJjb250YWluaW5nX29uZW9mIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0SGFzT3B0aW9ucyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IEZpZWxkT3B0aW9ucyYgb3B0aW9ucyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+b3B0aW9ucygpKTsKKyAgaWYgKCZvcHRpb25zICE9ICZGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIFB5X1JFVFVSTl9UUlVFOworICB9IGVsc2UgeworICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgfQorfQorc3RhdGljIGludCBTZXRIYXNPcHRpb25zKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBDaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKCJoYXNfb3B0aW9ucyIpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE9wdGlvbnMoUHlCYXNlRGVzY3JpcHRvciAqc2VsZikgeworICByZXR1cm4gR2V0T3JCdWlsZE9wdGlvbnMoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgaW50IFNldE9wdGlvbnMoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgUHlPYmplY3QgKnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIENoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoIl9vcHRpb25zIik7Cit9CisKKworc3RhdGljIFB5R2V0U2V0RGVmIEdldHRlcnNbXSA9IHsKKyAgeyBDKCJmdWxsX25hbWUiKSwgKGdldHRlcilHZXRGdWxsTmFtZSwgTlVMTCwgIkZ1bGwgbmFtZSIsIE5VTEx9LAorICB7IEMoIm5hbWUiKSwgKGdldHRlcilHZXROYW1lLCBOVUxMLCAiVW5xdWFsaWZpZWQgbmFtZSIsIE5VTEx9LAorICB7IEMoInR5cGUiKSwgKGdldHRlcilHZXRUeXBlLCBOVUxMLCAiQysrIFR5cGUiLCBOVUxMfSwKKyAgeyBDKCJjcHBfdHlwZSIpLCAoZ2V0dGVyKUdldENwcFR5cGUsIE5VTEwsICJDKysgVHlwZSIsIE5VTEx9LAorICB7IEMoImxhYmVsIiksIChnZXR0ZXIpR2V0TGFiZWwsIE5VTEwsICJMYWJlbCIsIE5VTEx9LAorICB7IEMoIm51bWJlciIpLCAoZ2V0dGVyKUdldE51bWJlciwgTlVMTCwgIk51bWJlciIsIE5VTEx9LAorICB7IEMoImluZGV4IiksIChnZXR0ZXIpR2V0SW5kZXgsIE5VTEwsICJJbmRleCIsIE5VTEx9LAorICB7IEMoImRlZmF1bHRfdmFsdWUiKSwgKGdldHRlcilHZXREZWZhdWx0VmFsdWUsIE5VTEwsICJEZWZhdWx0IFZhbHVlIiwgTlVMTH0sCisgIHsgQygiaGFzX2RlZmF1bHRfdmFsdWUiKSwgKGdldHRlcilIYXNEZWZhdWx0VmFsdWUsIE5VTEwsIE5VTEwsIE5VTEx9LAorICB7IEMoImlzX2V4dGVuc2lvbiIpLCAoZ2V0dGVyKUlzRXh0ZW5zaW9uLCBOVUxMLCAiSUQiLCBOVUxMfSwKKyAgeyBDKCJpZCIpLCAoZ2V0dGVyKUdldElELCBOVUxMLCAiSUQiLCBOVUxMfSwKKyAgeyBDKCJfY2Rlc2NyaXB0b3IiKSwgKGdldHRlcilHZXRDRGVzY3JpcHRvciwgTlVMTCwgIkhBQUNLIFJFTU9WRSBNRSIsIE5VTEx9LAorCisgIHsgQygibWVzc2FnZV90eXBlIiksIChnZXR0ZXIpR2V0TWVzc2FnZVR5cGUsIChzZXR0ZXIpU2V0TWVzc2FnZVR5cGUsICJNZXNzYWdlIHR5cGUiLCBOVUxMfSwKKyAgeyBDKCJlbnVtX3R5cGUiKSwgKGdldHRlcilHZXRFbnVtVHlwZSwgKHNldHRlcilTZXRFbnVtVHlwZSwgIkVudW0gdHlwZSIsIE5VTEx9LAorICB7IEMoImNvbnRhaW5pbmdfdHlwZSIpLCAoZ2V0dGVyKUdldENvbnRhaW5pbmdUeXBlLCAoc2V0dGVyKVNldENvbnRhaW5pbmdUeXBlLCAiQ29udGFpbmluZyB0eXBlIiwgTlVMTH0sCisgIHsgQygiZXh0ZW5zaW9uX3Njb3BlIiksIChnZXR0ZXIpR2V0RXh0ZW5zaW9uU2NvcGUsIChzZXR0ZXIpTlVMTCwgIkV4dGVuc2lvbiBzY29wZSIsIE5VTEx9LAorICB7IEMoImNvbnRhaW5pbmdfb25lb2YiKSwgKGdldHRlcilHZXRDb250YWluaW5nT25lb2YsIChzZXR0ZXIpU2V0Q29udGFpbmluZ09uZW9mLCAiQ29udGFpbmluZyBvbmVvZiIsIE5VTEx9LAorICB7IEMoImhhc19vcHRpb25zIiksIChnZXR0ZXIpR2V0SGFzT3B0aW9ucywgKHNldHRlcilTZXRIYXNPcHRpb25zLCAiSGFzIE9wdGlvbnMiLCBOVUxMfSwKKyAgeyBDKCJfb3B0aW9ucyIpLCAoZ2V0dGVyKU5VTEwsIChzZXR0ZXIpU2V0T3B0aW9ucywgIk9wdGlvbnMiLCBOVUxMfSwKKyAge05VTEx9Cit9OworCitzdGF0aWMgUHlNZXRob2REZWYgTWV0aG9kc1tdID0geworICB7ICJHZXRPcHRpb25zIiwgKFB5Q0Z1bmN0aW9uKUdldE9wdGlvbnMsIE1FVEhfTk9BUkdTLCB9LAorICB7TlVMTH0KK307CisKK30gIC8vIG5hbWVzcGFjZSBmaWVsZF9kZXNjcmlwdG9yCisKK1B5VHlwZU9iamVjdCBQeUZpZWxkRGVzY3JpcHRvcl9UeXBlID0geworICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICBDKCJnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuIgorICAgICJfbWVzc2FnZS5GaWVsZERlc2NyaXB0b3IiKSwgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5QmFzZURlc2NyaXB0b3IpLCAgICAgICAgICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVtc2l6ZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19zZXF1ZW5jZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX21hcHBpbmcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2FsbAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3N0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19idWZmZXIKKyAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICBDKCJBIEZpZWxkIERlc2NyaXB0b3IiKSwgICAgICAgICAgICAgIC8vIHRwX2RvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3RyYXZlcnNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yaWNoY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3dlYWtsaXN0b2Zmc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXJuZXh0CisgIGZpZWxkX2Rlc2NyaXB0b3I6Ok1ldGhvZHMsICAgICAgICAgICAgLy8gdHBfbWV0aG9kcworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21lbWJlcnMKKyAgZmllbGRfZGVzY3JpcHRvcjo6R2V0dGVycywgICAgICAgICAgICAvLyB0cF9nZXRzZXQKKyAgJmRlc2NyaXB0b3I6OlB5QmFzZURlc2NyaXB0b3JfVHlwZSwgICAvLyB0cF9iYXNlCit9OworCitQeU9iamVjdCogUHlGaWVsZERlc2NyaXB0b3JfTmV3KAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3SW50ZXJuZWREZXNjcmlwdG9yKAorICAgICAgJlB5RmllbGREZXNjcmlwdG9yX1R5cGUsIGZpZWxkX2Rlc2NyaXB0b3IpOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIFB5RmllbGREZXNjcmlwdG9yX0FzRGVzY3JpcHRvcihQeU9iamVjdCogb2JqKSB7CisgIGlmICghUHlPYmplY3RfVHlwZUNoZWNrKG9iaiwgJlB5RmllbGREZXNjcmlwdG9yX1R5cGUpKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIk5vdCBhIEZpZWxkRGVzY3JpcHRvciIpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KAorICAgICAgcmVpbnRlcnByZXRfY2FzdDxQeUJhc2VEZXNjcmlwdG9yKj4ob2JqKS0+ZGVzY3JpcHRvcik7Cit9CisKK25hbWVzcGFjZSBlbnVtX2Rlc2NyaXB0b3IgeworCisvLyBVbmNoZWNrZWQgYWNjZXNzb3IgdG8gdGhlIEMrKyBwb2ludGVyLgorc3RhdGljIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBfR2V0RGVzY3JpcHRvcigKKyAgICBQeUJhc2VEZXNjcmlwdG9yICpzZWxmKSB7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IEVudW1EZXNjcmlwdG9yKj4oc2VsZi0+ZGVzY3JpcHRvcik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0RnVsbE5hbWUoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfRnJvbUNwcFN0cmluZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+ZnVsbF9uYW1lKCkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE5hbWUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfRnJvbUNwcFN0cmluZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+bmFtZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRGaWxlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5RmlsZURlc2NyaXB0b3JfTmV3KF9HZXREZXNjcmlwdG9yKHNlbGYpLT5maWxlKCkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEVudW12YWx1ZXNCeU5hbWUoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gTmV3RW51bVZhbHVlc0J5TmFtZShfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0RW51bXZhbHVlc0J5TnVtYmVyKFB5QmFzZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld0VudW1WYWx1ZXNCeU51bWJlcihfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0RW51bXZhbHVlc1NlcShQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBOZXdFbnVtVmFsdWVzU2VxKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRDb250YWluaW5nVHlwZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSA9CisgICAgICBfR2V0RGVzY3JpcHRvcihzZWxmKS0+Y29udGFpbmluZ190eXBlKCk7CisgIGlmIChjb250YWluaW5nX3R5cGUpIHsKKyAgICByZXR1cm4gUHlNZXNzYWdlRGVzY3JpcHRvcl9OZXcoY29udGFpbmluZ190eXBlKTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorfQorCitzdGF0aWMgaW50IFNldENvbnRhaW5pbmdUeXBlKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgiY29udGFpbmluZ190eXBlIik7Cit9CisKKworc3RhdGljIFB5T2JqZWN0KiBHZXRIYXNPcHRpb25zKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgY29uc3QgRW51bU9wdGlvbnMmIG9wdGlvbnMoX0dldERlc2NyaXB0b3Ioc2VsZiktPm9wdGlvbnMoKSk7CisgIGlmICgmb3B0aW9ucyAhPSAmRW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIFB5X1JFVFVSTl9UUlVFOworICB9IGVsc2UgeworICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgfQorfQorc3RhdGljIGludCBTZXRIYXNPcHRpb25zKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBDaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKCJoYXNfb3B0aW9ucyIpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE9wdGlvbnMoUHlCYXNlRGVzY3JpcHRvciAqc2VsZikgeworICByZXR1cm4gR2V0T3JCdWlsZE9wdGlvbnMoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgaW50IFNldE9wdGlvbnMoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgUHlPYmplY3QgKnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIENoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoIl9vcHRpb25zIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogQ29weVRvUHJvdG8oUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgUHlPYmplY3QgKnRhcmdldCkgeworICByZXR1cm4gQ29weVRvUHl0aG9uUHJvdG88RW51bURlc2NyaXB0b3JQcm90bz4oX0dldERlc2NyaXB0b3Ioc2VsZiksIHRhcmdldCk7Cit9CisKK3N0YXRpYyBQeU1ldGhvZERlZiBNZXRob2RzW10gPSB7CisgIHsgIkdldE9wdGlvbnMiLCAoUHlDRnVuY3Rpb24pR2V0T3B0aW9ucywgTUVUSF9OT0FSR1MsIH0sCisgIHsgIkNvcHlUb1Byb3RvIiwgKFB5Q0Z1bmN0aW9uKUNvcHlUb1Byb3RvLCBNRVRIX08sIH0sCisgIHtOVUxMfQorfTsKKworc3RhdGljIFB5R2V0U2V0RGVmIEdldHRlcnNbXSA9IHsKKyAgeyBDKCJmdWxsX25hbWUiKSwgKGdldHRlcilHZXRGdWxsTmFtZSwgTlVMTCwgIkZ1bGwgbmFtZSIsIE5VTEx9LAorICB7IEMoIm5hbWUiKSwgKGdldHRlcilHZXROYW1lLCBOVUxMLCAibGFzdCBuYW1lIiwgTlVMTH0sCisgIHsgQygiZmlsZSIpLCAoZ2V0dGVyKUdldEZpbGUsIE5VTEwsICJGaWxlIGRlc2NyaXB0b3IiLCBOVUxMfSwKKyAgeyBDKCJ2YWx1ZXMiKSwgKGdldHRlcilHZXRFbnVtdmFsdWVzU2VxLCBOVUxMLCAidmFsdWVzIiwgTlVMTH0sCisgIHsgQygidmFsdWVzX2J5X25hbWUiKSwgKGdldHRlcilHZXRFbnVtdmFsdWVzQnlOYW1lLCBOVUxMLCAiRW51bXZhbHVlcyBieSBuYW1lIiwgTlVMTH0sCisgIHsgQygidmFsdWVzX2J5X251bWJlciIpLCAoZ2V0dGVyKUdldEVudW12YWx1ZXNCeU51bWJlciwgTlVMTCwgIkVudW12YWx1ZXMgYnkgbnVtYmVyIiwgTlVMTH0sCisKKyAgeyBDKCJjb250YWluaW5nX3R5cGUiKSwgKGdldHRlcilHZXRDb250YWluaW5nVHlwZSwgKHNldHRlcilTZXRDb250YWluaW5nVHlwZSwgIkNvbnRhaW5pbmcgdHlwZSIsIE5VTEx9LAorICB7IEMoImhhc19vcHRpb25zIiksIChnZXR0ZXIpR2V0SGFzT3B0aW9ucywgKHNldHRlcilTZXRIYXNPcHRpb25zLCAiSGFzIE9wdGlvbnMiLCBOVUxMfSwKKyAgeyBDKCJfb3B0aW9ucyIpLCAoZ2V0dGVyKU5VTEwsIChzZXR0ZXIpU2V0T3B0aW9ucywgIk9wdGlvbnMiLCBOVUxMfSwKKyAge05VTEx9Cit9OworCit9ICAvLyBuYW1lc3BhY2UgZW51bV9kZXNjcmlwdG9yCisKK1B5VHlwZU9iamVjdCBQeUVudW1EZXNjcmlwdG9yX1R5cGUgPSB7CisgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgIC8vIEtlZXAgdGhlIGZ1bGx5IHF1YWxpZmllZCBfbWVzc2FnZSBzeW1ib2wgaW4gYSBsaW5lIGZvciBvcGVuc291cmNlLgorICBDKCJnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuX21lc3NhZ2UuIgorICAgICJFbnVtRGVzY3JpcHRvciIpLCAgICAgICAgICAgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5QmFzZURlc2NyaXB0b3IpLCAgICAgICAgICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVtc2l6ZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19zZXF1ZW5jZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX21hcHBpbmcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2FsbAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3N0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19idWZmZXIKKyAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICBDKCJBIEVudW0gRGVzY3JpcHRvciIpLCAgICAgICAgICAgICAgIC8vIHRwX2RvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3RyYXZlcnNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yaWNoY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3dlYWtsaXN0b2Zmc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXJuZXh0CisgIGVudW1fZGVzY3JpcHRvcjo6TWV0aG9kcywgICAgICAgICAgICAgLy8gdHBfZ2V0c2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbWVtYmVycworICBlbnVtX2Rlc2NyaXB0b3I6OkdldHRlcnMsICAgICAgICAgICAgIC8vIHRwX2dldHNldAorICAmZGVzY3JpcHRvcjo6UHlCYXNlRGVzY3JpcHRvcl9UeXBlLCAgIC8vIHRwX2Jhc2UKK307CisKK1B5T2JqZWN0KiBQeUVudW1EZXNjcmlwdG9yX05ldygKKyAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV9kZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdJbnRlcm5lZERlc2NyaXB0b3IoCisgICAgICAmUHlFbnVtRGVzY3JpcHRvcl9UeXBlLCBlbnVtX2Rlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZW51bXZhbHVlX2Rlc2NyaXB0b3IgeworCisvLyBVbmNoZWNrZWQgYWNjZXNzb3IgdG8gdGhlIEMrKyBwb2ludGVyLgorc3RhdGljIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIF9HZXREZXNjcmlwdG9yKAorICAgIFB5QmFzZURlc2NyaXB0b3IgKnNlbGYpIHsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcio+KHNlbGYtPmRlc2NyaXB0b3IpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE5hbWUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfRnJvbUNwcFN0cmluZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+bmFtZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXROdW1iZXIoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPm51bWJlcigpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRJbmRleChQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeUludF9Gcm9tTG9uZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+aW5kZXgoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0VHlwZShQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeUVudW1EZXNjcmlwdG9yX05ldyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+dHlwZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRIYXNPcHRpb25zKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgb3B0aW9ucyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+b3B0aW9ucygpKTsKKyAgaWYgKCZvcHRpb25zICE9ICZFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBQeV9SRVRVUk5fVFJVRTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fRkFMU0U7CisgIH0KK30KK3N0YXRpYyBpbnQgU2V0SGFzT3B0aW9ucyhQeUJhc2VEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgiaGFzX29wdGlvbnMiKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRPcHRpb25zKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYpIHsKKyAgcmV0dXJuIEdldE9yQnVpbGRPcHRpb25zKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIGludCBTZXRPcHRpb25zKFB5QmFzZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBDaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKCJfb3B0aW9ucyIpOworfQorCisKK3N0YXRpYyBQeUdldFNldERlZiBHZXR0ZXJzW10gPSB7CisgIHsgQygibmFtZSIpLCAoZ2V0dGVyKUdldE5hbWUsIE5VTEwsICJuYW1lIiwgTlVMTH0sCisgIHsgQygibnVtYmVyIiksIChnZXR0ZXIpR2V0TnVtYmVyLCBOVUxMLCAibnVtYmVyIiwgTlVMTH0sCisgIHsgQygiaW5kZXgiKSwgKGdldHRlcilHZXRJbmRleCwgTlVMTCwgImluZGV4IiwgTlVMTH0sCisgIHsgQygidHlwZSIpLCAoZ2V0dGVyKUdldFR5cGUsIE5VTEwsICJpbmRleCIsIE5VTEx9LAorCisgIHsgQygiaGFzX29wdGlvbnMiKSwgKGdldHRlcilHZXRIYXNPcHRpb25zLCAoc2V0dGVyKVNldEhhc09wdGlvbnMsICJIYXMgT3B0aW9ucyIsIE5VTEx9LAorICB7IEMoIl9vcHRpb25zIiksIChnZXR0ZXIpTlVMTCwgKHNldHRlcilTZXRPcHRpb25zLCAiT3B0aW9ucyIsIE5VTEx9LAorICB7TlVMTH0KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBNZXRob2RzW10gPSB7CisgIHsgIkdldE9wdGlvbnMiLCAoUHlDRnVuY3Rpb24pR2V0T3B0aW9ucywgTUVUSF9OT0FSR1MsIH0sCisgIHtOVUxMfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGVudW12YWx1ZV9kZXNjcmlwdG9yCisKK1B5VHlwZU9iamVjdCBQeUVudW1WYWx1ZURlc2NyaXB0b3JfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgQygiZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLiIKKyAgICAiX21lc3NhZ2UuRW51bVZhbHVlRGVzY3JpcHRvciIpLCAgICAvLyB0cF9uYW1lCisgIHNpemVvZihQeUJhc2VEZXNjcmlwdG9yKSwgICAgICAgICAgICAgLy8gdHBfYmFzaWNzaXplCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlbXNpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kZWFsbG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfcHJpbnQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yZXByCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfbnVtYmVyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfc2VxdWVuY2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19tYXBwaW5nCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaGFzaAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NhbGwKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zdHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3NldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfYnVmZmVyCisgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgICAgLy8gdHBfZmxhZ3MKKyAgQygiQSBFbnVtVmFsdWUgRGVzY3JpcHRvciIpLCAgICAgICAgICAvLyB0cF9kb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF90cmF2ZXJzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NsZWFyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfcmljaGNvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF93ZWFrbGlzdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVybmV4dAorICBlbnVtdmFsdWVfZGVzY3JpcHRvcjo6TWV0aG9kcywgICAgICAgIC8vIHRwX21ldGhvZHMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9tZW1iZXJzCisgIGVudW12YWx1ZV9kZXNjcmlwdG9yOjpHZXR0ZXJzLCAgICAgICAgLy8gdHBfZ2V0c2V0CisgICZkZXNjcmlwdG9yOjpQeUJhc2VEZXNjcmlwdG9yX1R5cGUsICAgLy8gdHBfYmFzZQorfTsKKworUHlPYmplY3QqIFB5RW51bVZhbHVlRGVzY3JpcHRvcl9OZXcoCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bXZhbHVlX2Rlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld0ludGVybmVkRGVzY3JpcHRvcigKKyAgICAgICZQeUVudW1WYWx1ZURlc2NyaXB0b3JfVHlwZSwgZW51bXZhbHVlX2Rlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZmlsZV9kZXNjcmlwdG9yIHsKKworLy8gVW5jaGVja2VkIGFjY2Vzc29yIHRvIHRoZSBDKysgcG9pbnRlci4KK3N0YXRpYyBjb25zdCBGaWxlRGVzY3JpcHRvciogX0dldERlc2NyaXB0b3IoUHlGaWxlRGVzY3JpcHRvciAqc2VsZikgeworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBGaWxlRGVzY3JpcHRvcio+KHNlbGYtPmJhc2UuZGVzY3JpcHRvcik7Cit9CisKK3N0YXRpYyB2b2lkIERlYWxsb2MoUHlGaWxlRGVzY3JpcHRvciogc2VsZikgeworICBQeV9YREVDUkVGKHNlbGYtPnNlcmlhbGl6ZWRfcGIpOworICBkZXNjcmlwdG9yOjpEZWFsbG9jKCZzZWxmLT5iYXNlKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXROYW1lKFB5RmlsZURlc2NyaXB0b3IgKnNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIFB5U3RyaW5nX0Zyb21DcHBTdHJpbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPm5hbWUoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0UGFja2FnZShQeUZpbGVEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeVN0cmluZ19Gcm9tQ3BwU3RyaW5nKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5wYWNrYWdlKCkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldFNlcmlhbGl6ZWRQYihQeUZpbGVEZXNjcmlwdG9yICpzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIFB5T2JqZWN0ICpzZXJpYWxpemVkX3BiID0gc2VsZi0+c2VyaWFsaXplZF9wYjsKKyAgaWYgKHNlcmlhbGl6ZWRfcGIgIT0gTlVMTCkgeworICAgIFB5X0lOQ1JFRihzZXJpYWxpemVkX3BiKTsKKyAgICByZXR1cm4gc2VyaWFsaXplZF9wYjsKKyAgfQorICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIF9HZXREZXNjcmlwdG9yKHNlbGYpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBzdHJpbmcgY29udGVudHM7CisgIGZpbGVfcHJvdG8uU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKCZjb250ZW50cyk7CisgIHNlbGYtPnNlcmlhbGl6ZWRfcGIgPSBQeUJ5dGVzX0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgY29udGVudHMuY19zdHIoKSwgY29udGVudHMuc2l6ZSgpKTsKKyAgaWYgKHNlbGYtPnNlcmlhbGl6ZWRfcGIgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5X0lOQ1JFRihzZWxmLT5zZXJpYWxpemVkX3BiKTsKKyAgcmV0dXJuIHNlbGYtPnNlcmlhbGl6ZWRfcGI7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0TWVzc2FnZVR5cGVzQnlOYW1lKFB5RmlsZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld0ZpbGVNZXNzYWdlVHlwZXNCeU5hbWUoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEVudW1UeXBlc0J5TmFtZShQeUZpbGVEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBOZXdGaWxlRW51bVR5cGVzQnlOYW1lKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRFeHRlbnNpb25zQnlOYW1lKFB5RmlsZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld0ZpbGVFeHRlbnNpb25zQnlOYW1lKF9HZXREZXNjcmlwdG9yKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXREZXBlbmRlbmNpZXMoUHlGaWxlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gTmV3RmlsZURlcGVuZGVuY2llcyhfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0UHVibGljRGVwZW5kZW5jaWVzKFB5RmlsZURlc2NyaXB0b3IqIHNlbGYsIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIE5ld0ZpbGVQdWJsaWNEZXBlbmRlbmNpZXMoX0dldERlc2NyaXB0b3Ioc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEhhc09wdGlvbnMoUHlGaWxlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCBGaWxlT3B0aW9ucyYgb3B0aW9ucyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+b3B0aW9ucygpKTsKKyAgaWYgKCZvcHRpb25zICE9ICZGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKSB7CisgICAgUHlfUkVUVVJOX1RSVUU7CisgIH0gZWxzZSB7CisgICAgUHlfUkVUVVJOX0ZBTFNFOworICB9Cit9CitzdGF0aWMgaW50IFNldEhhc09wdGlvbnMoUHlGaWxlRGVzY3JpcHRvciAqc2VsZiwgUHlPYmplY3QgKnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgcmV0dXJuIENoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoImhhc19vcHRpb25zIik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0T3B0aW9ucyhQeUZpbGVEZXNjcmlwdG9yICpzZWxmKSB7CisgIHJldHVybiBHZXRPckJ1aWxkT3B0aW9ucyhfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBpbnQgU2V0T3B0aW9ucyhQeUZpbGVEZXNjcmlwdG9yICpzZWxmLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gQ2hlY2tDYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgiX29wdGlvbnMiKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRTeW50YXgoUHlGaWxlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygKKyAgICAgIEZpbGVEZXNjcmlwdG9yOjpTeW50YXhOYW1lKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5zeW50YXgoKSkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIENvcHlUb1Byb3RvKFB5RmlsZURlc2NyaXB0b3IgKnNlbGYsIFB5T2JqZWN0ICp0YXJnZXQpIHsKKyAgcmV0dXJuIENvcHlUb1B5dGhvblByb3RvPEZpbGVEZXNjcmlwdG9yUHJvdG8+KF9HZXREZXNjcmlwdG9yKHNlbGYpLCB0YXJnZXQpOworfQorCitzdGF0aWMgUHlHZXRTZXREZWYgR2V0dGVyc1tdID0geworICB7IEMoIm5hbWUiKSwgKGdldHRlcilHZXROYW1lLCBOVUxMLCAibmFtZSIsIE5VTEx9LAorICB7IEMoInBhY2thZ2UiKSwgKGdldHRlcilHZXRQYWNrYWdlLCBOVUxMLCAicGFja2FnZSIsIE5VTEx9LAorICB7IEMoInNlcmlhbGl6ZWRfcGIiKSwgKGdldHRlcilHZXRTZXJpYWxpemVkUGIsIE5VTEwsIE5VTEwsIE5VTEx9LAorICB7IEMoIm1lc3NhZ2VfdHlwZXNfYnlfbmFtZSIpLCAoZ2V0dGVyKUdldE1lc3NhZ2VUeXBlc0J5TmFtZSwgTlVMTCwgIk1lc3NhZ2VzIGJ5IG5hbWUiLCBOVUxMfSwKKyAgeyBDKCJlbnVtX3R5cGVzX2J5X25hbWUiKSwgKGdldHRlcilHZXRFbnVtVHlwZXNCeU5hbWUsIE5VTEwsICJFbnVtcyBieSBuYW1lIiwgTlVMTH0sCisgIHsgQygiZXh0ZW5zaW9uc19ieV9uYW1lIiksIChnZXR0ZXIpR2V0RXh0ZW5zaW9uc0J5TmFtZSwgTlVMTCwgIkV4dGVuc2lvbnMgYnkgbmFtZSIsIE5VTEx9LAorICB7IEMoImRlcGVuZGVuY2llcyIpLCAoZ2V0dGVyKUdldERlcGVuZGVuY2llcywgTlVMTCwgIkRlcGVuZGVuY2llcyIsIE5VTEx9LAorICB7IEMoInB1YmxpY19kZXBlbmRlbmNpZXMiKSwgKGdldHRlcilHZXRQdWJsaWNEZXBlbmRlbmNpZXMsIE5VTEwsICJEZXBlbmRlbmNpZXMiLCBOVUxMfSwKKworICB7IEMoImhhc19vcHRpb25zIiksIChnZXR0ZXIpR2V0SGFzT3B0aW9ucywgKHNldHRlcilTZXRIYXNPcHRpb25zLCAiSGFzIE9wdGlvbnMiLCBOVUxMfSwKKyAgeyBDKCJfb3B0aW9ucyIpLCAoZ2V0dGVyKU5VTEwsIChzZXR0ZXIpU2V0T3B0aW9ucywgIk9wdGlvbnMiLCBOVUxMfSwKKyAgeyBDKCJzeW50YXgiKSwgKGdldHRlcilHZXRTeW50YXgsIChzZXR0ZXIpTlVMTCwgIlN5bnRheCIsIE5VTEx9LAorICB7TlVMTH0KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBNZXRob2RzW10gPSB7CisgIHsgIkdldE9wdGlvbnMiLCAoUHlDRnVuY3Rpb24pR2V0T3B0aW9ucywgTUVUSF9OT0FSR1MsIH0sCisgIHsgIkNvcHlUb1Byb3RvIiwgKFB5Q0Z1bmN0aW9uKUNvcHlUb1Byb3RvLCBNRVRIX08sIH0sCisgIHtOVUxMfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGZpbGVfZGVzY3JpcHRvcgorCitQeVR5cGVPYmplY3QgUHlGaWxlRGVzY3JpcHRvcl9UeXBlID0geworICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICBDKCJnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuIgorICAgICJfbWVzc2FnZS5GaWxlRGVzY3JpcHRvciIpLCAgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5RmlsZURlc2NyaXB0b3IpLCAgICAgICAgICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVtc2l6ZQorICAoZGVzdHJ1Y3RvcilmaWxlX2Rlc2NyaXB0b3I6OkRlYWxsb2MsIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19zZXF1ZW5jZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX21hcHBpbmcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2FsbAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3N0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19idWZmZXIKKyAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICBDKCJBIEZpbGUgRGVzY3JpcHRvciIpLCAgICAgICAgICAgICAgIC8vIHRwX2RvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3RyYXZlcnNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yaWNoY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3dlYWtsaXN0b2Zmc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXJuZXh0CisgIGZpbGVfZGVzY3JpcHRvcjo6TWV0aG9kcywgICAgICAgICAgICAgLy8gdHBfbWV0aG9kcworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21lbWJlcnMKKyAgZmlsZV9kZXNjcmlwdG9yOjpHZXR0ZXJzLCAgICAgICAgICAgICAvLyB0cF9nZXRzZXQKKyAgJmRlc2NyaXB0b3I6OlB5QmFzZURlc2NyaXB0b3JfVHlwZSwgICAvLyB0cF9iYXNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZGljdAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2Rlc2NyX2dldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2Rlc2NyX3NldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RpY3RvZmZzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pbml0CisgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgICAgLy8gdHBfYWxsb2MKKyAgUHlUeXBlX0dlbmVyaWNOZXcsICAgICAgICAgICAgICAgICAgICAvLyB0cF9uZXcKKyAgUHlPYmplY3RfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9mcmVlCit9OworCitQeU9iamVjdCogUHlGaWxlRGVzY3JpcHRvcl9OZXcoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3SW50ZXJuZWREZXNjcmlwdG9yKAorICAgICAgJlB5RmlsZURlc2NyaXB0b3JfVHlwZSwgZmlsZV9kZXNjcmlwdG9yKTsKK30KKworUHlPYmplY3QqIFB5RmlsZURlc2NyaXB0b3JfTmV3V2l0aFBiKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlX2Rlc2NyaXB0b3IsIFB5T2JqZWN0ICpzZXJpYWxpemVkX3BiKSB7CisgIFB5T2JqZWN0KiBweV9kZXNjcmlwdG9yID0gUHlGaWxlRGVzY3JpcHRvcl9OZXcoZmlsZV9kZXNjcmlwdG9yKTsKKyAgaWYgKHB5X2Rlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChzZXJpYWxpemVkX3BiICE9IE5VTEwpIHsKKyAgICBQeUZpbGVEZXNjcmlwdG9yKiBjZmlsZV9kZXNjcmlwdG9yID0KKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxQeUZpbGVEZXNjcmlwdG9yKj4ocHlfZGVzY3JpcHRvcik7CisgICAgUHlfWElOQ1JFRihzZXJpYWxpemVkX3BiKTsKKyAgICBjZmlsZV9kZXNjcmlwdG9yLT5zZXJpYWxpemVkX3BiID0gc2VyaWFsaXplZF9wYjsKKyAgfQorCisgIHJldHVybiBweV9kZXNjcmlwdG9yOworfQorCituYW1lc3BhY2Ugb25lb2ZfZGVzY3JpcHRvciB7CisKKy8vIFVuY2hlY2tlZCBhY2Nlc3NvciB0byB0aGUgQysrIHBvaW50ZXIuCitzdGF0aWMgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBfR2V0RGVzY3JpcHRvcigKKyAgICBQeUJhc2VEZXNjcmlwdG9yICpzZWxmKSB7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IE9uZW9mRGVzY3JpcHRvcio+KHNlbGYtPmRlc2NyaXB0b3IpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldE5hbWUoUHlCYXNlRGVzY3JpcHRvciogc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlTdHJpbmdfRnJvbUNwcFN0cmluZyhfR2V0RGVzY3JpcHRvcihzZWxmKS0+bmFtZSgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBHZXRGdWxsTmFtZShQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBQeVN0cmluZ19Gcm9tQ3BwU3RyaW5nKF9HZXREZXNjcmlwdG9yKHNlbGYpLT5mdWxsX25hbWUoKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0SW5kZXgoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoX0dldERlc2NyaXB0b3Ioc2VsZiktPmluZGV4KCkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEdldEZpZWxkcyhQeUJhc2VEZXNjcmlwdG9yKiBzZWxmLCB2b2lkICpjbG9zdXJlKSB7CisgIHJldHVybiBOZXdPbmVvZkZpZWxkc1NlcShfR2V0RGVzY3JpcHRvcihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogR2V0Q29udGFpbmluZ1R5cGUoUHlCYXNlRGVzY3JpcHRvciAqc2VsZiwgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUgPQorICAgICAgX0dldERlc2NyaXB0b3Ioc2VsZiktPmNvbnRhaW5pbmdfdHlwZSgpOworICBpZiAoY29udGFpbmluZ190eXBlKSB7CisgICAgcmV0dXJuIFB5TWVzc2FnZURlc2NyaXB0b3JfTmV3KGNvbnRhaW5pbmdfdHlwZSk7CisgIH0gZWxzZSB7CisgICAgUHlfUkVUVVJOX05PTkU7CisgIH0KK30KKworc3RhdGljIFB5R2V0U2V0RGVmIEdldHRlcnNbXSA9IHsKKyAgeyBDKCJuYW1lIiksIChnZXR0ZXIpR2V0TmFtZSwgTlVMTCwgIk5hbWUiLCBOVUxMfSwKKyAgeyBDKCJmdWxsX25hbWUiKSwgKGdldHRlcilHZXRGdWxsTmFtZSwgTlVMTCwgIkZ1bGwgbmFtZSIsIE5VTEx9LAorICB7IEMoImluZGV4IiksIChnZXR0ZXIpR2V0SW5kZXgsIE5VTEwsICJJbmRleCIsIE5VTEx9LAorCisgIHsgQygiY29udGFpbmluZ190eXBlIiksIChnZXR0ZXIpR2V0Q29udGFpbmluZ1R5cGUsIE5VTEwsICJDb250YWluaW5nIHR5cGUiLCBOVUxMfSwKKyAgeyBDKCJmaWVsZHMiKSwgKGdldHRlcilHZXRGaWVsZHMsIE5VTEwsICJGaWVsZHMiLCBOVUxMfSwKKyAge05VTEx9Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugb25lb2ZfZGVzY3JpcHRvcgorCitQeVR5cGVPYmplY3QgUHlPbmVvZkRlc2NyaXB0b3JfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgQygiZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLiIKKyAgICAiX21lc3NhZ2UuT25lb2ZEZXNjcmlwdG9yIiksICAgICAgICAvLyB0cF9uYW1lCisgIHNpemVvZihQeUJhc2VEZXNjcmlwdG9yKSwgICAgICAgICAgICAgLy8gdHBfYmFzaWNzaXplCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlbXNpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kZWFsbG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfcHJpbnQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yZXByCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfbnVtYmVyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfc2VxdWVuY2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19tYXBwaW5nCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaGFzaAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NhbGwKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zdHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3NldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfYnVmZmVyCisgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgICAgLy8gdHBfZmxhZ3MKKyAgQygiQSBPbmVvZiBEZXNjcmlwdG9yIiksICAgICAgICAgICAgICAvLyB0cF9kb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF90cmF2ZXJzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NsZWFyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfcmljaGNvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF93ZWFrbGlzdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVybmV4dAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21ldGhvZHMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9tZW1iZXJzCisgIG9uZW9mX2Rlc2NyaXB0b3I6OkdldHRlcnMsICAgICAgICAgICAgLy8gdHBfZ2V0c2V0CisgICZkZXNjcmlwdG9yOjpQeUJhc2VEZXNjcmlwdG9yX1R5cGUsICAgLy8gdHBfYmFzZQorfTsKKworUHlPYmplY3QqIFB5T25lb2ZEZXNjcmlwdG9yX05ldygKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld0ludGVybmVkRGVzY3JpcHRvcigKKyAgICAgICZQeU9uZW9mRGVzY3JpcHRvcl9UeXBlLCBvbmVvZl9kZXNjcmlwdG9yKTsKK30KKworLy8gQWRkIGEgZW51bSB2YWx1ZXMgdG8gYSB0eXBlIGRpY3Rpb25hcnkuCitzdGF0aWMgYm9vbCBBZGRFbnVtVmFsdWVzKFB5VHlwZU9iamVjdCAqdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fZGVzY3JpcHRvcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1fZGVzY3JpcHRvci0+dmFsdWVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBlbnVtX2Rlc2NyaXB0b3ItPnZhbHVlKGkpOworICAgIFNjb3BlZFB5T2JqZWN0UHRyIG9iaihQeUludF9Gcm9tTG9uZyh2YWx1ZS0+bnVtYmVyKCkpKTsKKyAgICBpZiAob2JqID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKFB5RGljdF9TZXRJdGVtU3RyaW5nKHR5cGUtPnRwX2RpY3QsIHZhbHVlLT5uYW1lKCkuY19zdHIoKSwgb2JqKSA8IDApIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIEFkZEludENvbnN0YW50KFB5VHlwZU9iamVjdCAqdHlwZSwgY29uc3QgY2hhciogbmFtZSwgaW50IHZhbHVlKSB7CisgIFNjb3BlZFB5T2JqZWN0UHRyIG9iaihQeUludF9Gcm9tTG9uZyh2YWx1ZSkpOworICBpZiAoUHlEaWN0X1NldEl0ZW1TdHJpbmcodHlwZS0+dHBfZGljdCwgbmFtZSwgb2JqKSA8IDApIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKworYm9vbCBJbml0RGVzY3JpcHRvcigpIHsKKyAgaWYgKFB5VHlwZV9SZWFkeSgmUHlNZXNzYWdlRGVzY3JpcHRvcl9UeXBlKSA8IDApCisgICAgcmV0dXJuIGZhbHNlOworCisgIGlmIChQeVR5cGVfUmVhZHkoJlB5RmllbGREZXNjcmlwdG9yX1R5cGUpIDwgMCkKKyAgICByZXR1cm4gZmFsc2U7CisKKyAgaWYgKCFBZGRFbnVtVmFsdWVzKCZQeUZpZWxkRGVzY3JpcHRvcl9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsX2Rlc2NyaXB0b3IoKSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKCFBZGRFbnVtVmFsdWVzKCZQeUZpZWxkRGVzY3JpcHRvcl9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGVfZGVzY3JpcHRvcigpKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorI2RlZmluZSBBRERfRklFTERERVNDX0NPTlNUQU5UKE5BTUUpIEFkZEludENvbnN0YW50KCBcCisgICAgJlB5RmllbGREZXNjcmlwdG9yX1R5cGUsICNOQU1FLCBGaWVsZERlc2NyaXB0b3I6Ok5BTUUpCisgIGlmICghQUREX0ZJRUxEREVTQ19DT05TVEFOVChDUFBUWVBFX0lOVDMyKSB8fAorICAgICAgIUFERF9GSUVMRERFU0NfQ09OU1RBTlQoQ1BQVFlQRV9JTlQ2NCkgfHwKKyAgICAgICFBRERfRklFTERERVNDX0NPTlNUQU5UKENQUFRZUEVfVUlOVDMyKSB8fAorICAgICAgIUFERF9GSUVMRERFU0NfQ09OU1RBTlQoQ1BQVFlQRV9VSU5UNjQpIHx8CisgICAgICAhQUREX0ZJRUxEREVTQ19DT05TVEFOVChDUFBUWVBFX0RPVUJMRSkgfHwKKyAgICAgICFBRERfRklFTERERVNDX0NPTlNUQU5UKENQUFRZUEVfRkxPQVQpIHx8CisgICAgICAhQUREX0ZJRUxEREVTQ19DT05TVEFOVChDUFBUWVBFX0JPT0wpIHx8CisgICAgICAhQUREX0ZJRUxEREVTQ19DT05TVEFOVChDUFBUWVBFX0VOVU0pIHx8CisgICAgICAhQUREX0ZJRUxEREVTQ19DT05TVEFOVChDUFBUWVBFX1NUUklORykgfHwKKyAgICAgICFBRERfRklFTERERVNDX0NPTlNUQU5UKENQUFRZUEVfTUVTU0FHRSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyN1bmRlZiBBRERfRklFTERERVNDX0NPTlNUQU5UCisKKyAgaWYgKFB5VHlwZV9SZWFkeSgmUHlFbnVtRGVzY3JpcHRvcl9UeXBlKSA8IDApCisgICAgcmV0dXJuIGZhbHNlOworCisgIGlmIChQeVR5cGVfUmVhZHkoJlB5RW51bVZhbHVlRGVzY3JpcHRvcl9UeXBlKSA8IDApCisgICAgcmV0dXJuIGZhbHNlOworCisgIGlmIChQeVR5cGVfUmVhZHkoJlB5RmlsZURlc2NyaXB0b3JfVHlwZSkgPCAwKQorICAgIHJldHVybiBmYWxzZTsKKworICBpZiAoUHlUeXBlX1JlYWR5KCZQeU9uZW9mRGVzY3JpcHRvcl9UeXBlKSA8IDApCisgICAgcmV0dXJuIGZhbHNlOworCisgIGlmICghSW5pdERlc2NyaXB0b3JNYXBwaW5nVHlwZXMoKSkKKyAgICByZXR1cm4gZmFsc2U7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yLmggYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTZlNzI5Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yLmgKQEAgLTAsMCArMSw5MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogcGV0YXJAZ29vZ2xlLmNvbSAoUGV0YXIgUGV0cm92KQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX0RFU0NSSVBUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX0RFU0NSSVBUT1JfSF9fCisKKyNpbmNsdWRlIDxQeXRob24uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBweXRob24geworCitleHRlcm4gUHlUeXBlT2JqZWN0IFB5TWVzc2FnZURlc2NyaXB0b3JfVHlwZTsKK2V4dGVybiBQeVR5cGVPYmplY3QgUHlGaWVsZERlc2NyaXB0b3JfVHlwZTsKK2V4dGVybiBQeVR5cGVPYmplY3QgUHlFbnVtRGVzY3JpcHRvcl9UeXBlOworZXh0ZXJuIFB5VHlwZU9iamVjdCBQeUVudW1WYWx1ZURlc2NyaXB0b3JfVHlwZTsKK2V4dGVybiBQeVR5cGVPYmplY3QgUHlGaWxlRGVzY3JpcHRvcl9UeXBlOworZXh0ZXJuIFB5VHlwZU9iamVjdCBQeU9uZW9mRGVzY3JpcHRvcl9UeXBlOworCisvLyBSZXR1cm4gYSBuZXcgcmVmZXJlbmNlIHRvIGEgRGVzY3JpcHRvciBvYmplY3QuCisvLyBUaGUgQysrIHBvaW50ZXIgaXMgdXN1YWxseSBib3Jyb3dlZCBmcm9tIHRoZSBnbG9iYWwgRGVzY3JpcHRvclBvb2wuCisvLyBJbiBhbnkgY2FzZSwgaXQgbXVzdCBzdGF5IGFsaXZlIGFzIGxvbmcgYXMgdGhlIFB5dGhvbiBvYmplY3QuCitQeU9iamVjdCogUHlNZXNzYWdlRGVzY3JpcHRvcl9OZXcoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogUHlGaWVsZERlc2NyaXB0b3JfTmV3KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogUHlFbnVtRGVzY3JpcHRvcl9OZXcoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworUHlPYmplY3QqIFB5RW51bVZhbHVlRGVzY3JpcHRvcl9OZXcoY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogUHlPbmVvZkRlc2NyaXB0b3JfTmV3KGNvbnN0IE9uZW9mRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogUHlGaWxlRGVzY3JpcHRvcl9OZXcoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfZGVzY3JpcHRvcik7CisKKy8vIEFsdGVybmF0ZSBjb25zdHJ1Y3RvciBvZiBQeUZpbGVEZXNjcmlwdG9yLCB1c2VkIHdoZW4gd2UgYWxyZWFkeSBoYXZlIGEKKy8vIHNlcmlhbGl6ZWQgRmlsZURlc2NyaXB0b3JQcm90byB0aGF0IGNhbiBiZSBjYWNoZWQuCisvLyBSZXR1cm5zIGEgbmV3IHJlZmVyZW5jZS4KK1B5T2JqZWN0KiBQeUZpbGVEZXNjcmlwdG9yX05ld1dpdGhQYihjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBzZXJpYWxpemVkX3BiKTsKKworLy8gUmV0dXJuIHRoZSBDKysgZGVzY3JpcHRvciBwb2ludGVyLgorLy8gVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhlIHBhcmFtZXRlciB0eXBlOyBvbiBlcnJvciwgcmV0dXJuIE5VTEwgd2l0aCBhIFB5dGhvbgorLy8gZXhjZXB0aW9uIHNldC4KK2NvbnN0IERlc2NyaXB0b3IqIFB5TWVzc2FnZURlc2NyaXB0b3JfQXNEZXNjcmlwdG9yKFB5T2JqZWN0KiBvYmopOworY29uc3QgRmllbGREZXNjcmlwdG9yKiBQeUZpZWxkRGVzY3JpcHRvcl9Bc0Rlc2NyaXB0b3IoUHlPYmplY3QqIG9iaik7CisKKy8vIFJldHVybnMgdGhlIHJhdyBDKysgcG9pbnRlci4KK2NvbnN0IHZvaWQqIFB5RGVzY3JpcHRvcl9Bc1ZvaWRQdHIoUHlPYmplY3QqIG9iaik7CisKKy8vIENoZWNrIHRoYXQgdGhlIGNhbGxpbmcgUHl0aG9uIGNvZGUgaXMgdGhlIGdsb2JhbCBzY29wZSBvZiBhIF9wYjIucHkgbW9kdWxlLgorLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHN1cHBvcnQgdGhlIGN1cnJlbnQgY29kZSBnZW5lcmF0ZWQgYnkgdGhlIHByb3RvCisvLyBjb21waWxlciwgd2hpY2ggaW5zaXN0cyBvbiBtb2RpZnlpbmcgZGVzY3JpcHRvcnMgYWZ0ZXIgdGhleSBoYXZlIGJlZW4KKy8vIGNyZWF0ZWQuCisvLworLy8gc3RhY2tsZXZlbCBpbmRpY2F0ZXMgd2hpY2ggUHl0aG9uIGZyYW1lIHNob3VsZCBiZSB0aGUgX3BiMi5weSBtb2R1bGUuCisvLworLy8gRG9uJ3QgdXNlIHRoaXMgZnVuY3Rpb24gb3V0c2lkZSBkZXNjcmlwdG9yIGNsYXNzZXMuCitib29sIF9DYWxsZWRGcm9tR2VuZXJhdGVkRmlsZShpbnQgc3RhY2tsZXZlbCk7CisKK2Jvb2wgSW5pdERlc2NyaXB0b3IoKTsKKworfSAgLy8gbmFtZXNwYWNlIHB5dGhvbgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1BZVEhPTl9DUFBfREVTQ1JJUFRPUl9IX18KZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9jb250YWluZXJzLmNjIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX2NvbnRhaW5lcnMuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDZlZGViZgotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9jb250YWluZXJzLmNjCkBAIC0wLDAgKzEsMTU2NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIE1hcHBpbmdzIGFuZCBTZXF1ZW5jZXMgb2YgZGVzY3JpcHRvcnMuCisvLyBVc2VkIGJ5IERlc2NyaXB0b3IuZmllbGRzX2J5X25hbWUsIEVudW1EZXNjcmlwdG9yLnZhbHVlcy4uLgorLy8KKy8vIFRoZXkgYXZvaWQgdGhlIGFsbG9jYXRpb24gb2YgYSBmdWxsIGRpY3Rpb25hcnkgb3IgYSBmdWxsIGxpc3Q6IHRoZXkgc2ltcGx5CisvLyBzdG9yZSBhIHBvaW50ZXIgdG8gdGhlIHBhcmVudCBkZXNjcmlwdG9yLCB1c2UgdGhlIEMrKyBEZXNjcmlwdG9yIG1ldGhvZHMgKHNlZQorLy8gZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaCkgdG8gcmV0cmlldmUgb3RoZXIgZGVzY3JpcHRvcnMsIGFuZCBjcmVhdGUKKy8vIFB5dGhvbiBvYmplY3RzIG9uIHRoZSBmbHkuCisvLworLy8gVGhlIGNvbnRhaW5lcnMgZnVsbHkgY29uZm9ybSB0byBhYmMuTWFwcGluZyBhbmQgYWJjLlNlcXVlbmNlLCBhbmQgYmVoYXZlIGp1c3QKKy8vIGxpa2UgcmVhZC1vbmx5IGRpY3Rpb25hcmllcyBhbmQgbGlzdHMuCisvLworLy8gQmVjYXVzZSB0aGUgaW50ZXJmYWNlIG9mIEMrKyBEZXNjcmlwdG9ycyBpcyBxdWl0ZSByZWd1bGFyLCB0aGlzIGZpbGUgYWN0dWFsbHkKKy8vIGRlZmluZXMgb25seSB0aHJlZSB0eXBlcywgdGhlIGV4YWN0IGJlaGF2aW9yIG9mIGEgY29udGFpbmVyIGlzIGNvbnRyb2xsZWQgYnkKKy8vIGEgRGVzY3JpcHRvckNvbnRhaW5lckRlZiBzdHJ1Y3R1cmUsIHdoaWNoIGNvbnRhaW5zIGZ1bmN0aW9ucyB0aGF0IHVzZXMgdGhlCisvLyBwdWJsaWMgRGVzY3JpcHRvciBBUEkuCisvLworLy8gTm90ZTogVGhpcyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIGlzIHNpbWlsYXIgdG8gdGhlICJ2aXJ0dWFsIG1ldGhvZHMgdGFibGUiCisvLyB0aGF0IGEgQysrIGNvbXBpbGVyIGdlbmVyYXRlcyBmb3IgYSBjbGFzcy4gV2UgaGF2ZSB0byBtYWtlIGl0IGV4cGxpY2l0CisvLyBiZWNhdXNlIHRoZSBQeXRob24gQVBJIGlzIGJhc2VkIG9uIEMsIGFuZCBkb2VzIG5vdCBwbGF5IHdlbGwgd2l0aCBDKysKKy8vIGluaGVyaXRhbmNlLgorCisjaW5jbHVkZSA8UHl0aG9uLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX2NvbnRhaW5lcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9wb29sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvc2NvcGVkX3B5b2JqZWN0X3B0ci5oPgorCisjaWYgUFlfTUFKT1JfVkVSU0lPTiA+PSAzCisgICNkZWZpbmUgUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUgUHlVbmljb2RlX0Zyb21TdHJpbmdBbmRTaXplCisgICNkZWZpbmUgUHlTdHJpbmdfRnJvbUZvcm1hdCBQeVVuaWNvZGVfRnJvbUZvcm1hdAorICAjZGVmaW5lIFB5SW50X0Zyb21Mb25nIFB5TG9uZ19Gcm9tTG9uZworICAjaWYgUFlfVkVSU0lPTl9IRVggPCAweDAzMDMwMDAwCisgICAgI2Vycm9yICJQeXRob24gMy4wIC0gMy4yIGFyZSBub3Qgc3VwcG9ydGVkLiIKKyAgI2VuZGlmCisgICNkZWZpbmUgUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG9iLCBjaGFycHAsIHNpemVwKSBcCisgICAgKFB5VW5pY29kZV9DaGVjayhvYik/IFwKKyAgICAgICAoKCooY2hhcnBwKSA9IFB5VW5pY29kZV9Bc1VURjhBbmRTaXplKG9iLCAoc2l6ZXApKSkgPT0gTlVMTD8gLTE6IDApOiBcCisgICAgICAgUHlCeXRlc19Bc1N0cmluZ0FuZFNpemUob2IsIChjaGFycHApLCAoc2l6ZXApKSkKKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworc3RydWN0IFB5Q29udGFpbmVyOworCit0eXBlZGVmIGludCAoKkNvdW50TWV0aG9kKShQeUNvbnRhaW5lciogc2VsZik7Cit0eXBlZGVmIGNvbnN0IHZvaWQqICgqR2V0QnlJbmRleE1ldGhvZCkoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCk7Cit0eXBlZGVmIGNvbnN0IHZvaWQqICgqR2V0QnlOYW1lTWV0aG9kKShQeUNvbnRhaW5lciogc2VsZiwgY29uc3Qgc3RyaW5nJiBuYW1lKTsKK3R5cGVkZWYgY29uc3Qgdm9pZCogKCpHZXRCeU51bWJlck1ldGhvZCkoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCk7Cit0eXBlZGVmIFB5T2JqZWN0KiAoKk5ld09iamVjdEZyb21JdGVtTWV0aG9kKShjb25zdCB2b2lkKiBkZXNjcmlwdG9yKTsKK3R5cGVkZWYgY29uc3Qgc3RyaW5nJiAoKkdldEl0ZW1OYW1lTWV0aG9kKShjb25zdCB2b2lkKiBkZXNjcmlwdG9yKTsKK3R5cGVkZWYgaW50ICgqR2V0SXRlbU51bWJlck1ldGhvZCkoY29uc3Qgdm9pZCogZGVzY3JpcHRvcik7Cit0eXBlZGVmIGludCAoKkdldEl0ZW1JbmRleE1ldGhvZCkoY29uc3Qgdm9pZCogZGVzY3JpcHRvcik7CisKK3N0cnVjdCBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIHsKKyAgY29uc3QgY2hhciogbWFwcGluZ19uYW1lOworICAvLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIGNvbnRhaW5lci4KKyAgQ291bnRNZXRob2QgY291bnRfZm47CisgIC8vIFJldHJpZXZlIGl0ZW0gYnkgaW5kZXggKHVzdWFsbHkgdGhlIG9yZGVyIG9mIGRlY2xhcmF0aW9uIGluIHRoZSBwcm90byBmaWxlKQorICAvLyBVc2VkIGJ5IHNlcXVlbmNlcywgYnV0IGFsc28gaXRlcmF0b3JzLiAwIDw9IGluZGV4IDwgQ291bnQoKS4KKyAgR2V0QnlJbmRleE1ldGhvZCBnZXRfYnlfaW5kZXhfZm47CisgIC8vIFJldHJpZXZlIGl0ZW0gYnkgbmFtZSAodXN1YWxseSBhIGNhbGwgdG8gc29tZSAnRmluZEJ5TmFtZScgbWV0aG9kKS4KKyAgLy8gVXNlZCBieSAiYnlfbmFtZSIgbWFwcGluZ3MuCisgIEdldEJ5TmFtZU1ldGhvZCBnZXRfYnlfbmFtZV9mbjsKKyAgLy8gUmV0cmlldmUgaXRlbSBieSBkZWNsYXJlZCBudW1iZXIgKGZpZWxkIHRhZywgb3IgZW51bSB2YWx1ZSkuCisgIC8vIFVzZWQgYnkgImJ5X251bWJlciIgbWFwcGluZ3MuCisgIEdldEJ5TnVtYmVyTWV0aG9kIGdldF9ieV9udW1iZXJfZm47CisgIC8vIENvbnZlcnRzIGEgaXRlbSBDKysgZGVzY3JpcHRvciB0byBhIFB5dGhvbiBvYmplY3QuIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlLgorICBOZXdPYmplY3RGcm9tSXRlbU1ldGhvZCBuZXdfb2JqZWN0X2Zyb21faXRlbV9mbjsKKyAgLy8gUmV0cmlldmUgdGhlIG5hbWUgb2YgYW4gaXRlbS4gVXNlZCBieSBpdGVyYXRvcnMgb24gImJ5X25hbWUiIG1hcHBpbmdzLgorICBHZXRJdGVtTmFtZU1ldGhvZCBnZXRfaXRlbV9uYW1lX2ZuOworICAvLyBSZXRyaWV2ZSB0aGUgbnVtYmVyIG9mIGFuIGl0ZW0uIFVzZWQgYnkgaXRlcmF0b3JzIG9uICJieV9udW1iZXIiIG1hcHBpbmdzLgorICBHZXRJdGVtTnVtYmVyTWV0aG9kIGdldF9pdGVtX251bWJlcl9mbjsKKyAgLy8gUmV0cmlldmUgdGhlIGluZGV4IG9mIGFuIGl0ZW0gZm9yIHRoZSBjb250YWluZXIgdHlwZS4KKyAgLy8gVXNlZCBieSAiX19jb250YWluc19fIi4KKyAgLy8gSWYgbm90IHNldCwgInggaW4gc2VxdWVuY2UiIHdpbGwgZG8gYSBsaW5lYXIgc2VhcmNoLgorICBHZXRJdGVtSW5kZXhNZXRob2QgZ2V0X2l0ZW1faW5kZXhfZm47Cit9OworCitzdHJ1Y3QgUHlDb250YWluZXIgeworICBQeU9iamVjdF9IRUFECisKKyAgLy8gVGhlIHByb3RvMiBkZXNjcmlwdG9yIHRoaXMgY29udGFpbmVyIGJlbG9uZ3MgdG8gdGhlIGdsb2JhbCBEZXNjcmlwdG9yUG9vbC4KKyAgY29uc3Qgdm9pZCogZGVzY3JpcHRvcjsKKworICAvLyBBIHBvaW50ZXIgdG8gYSBzdGF0aWMgc3RydWN0dXJlIHdpdGggZnVuY3Rpb24gcG9pbnRlcnMgdGhhdCBjb250cm9sIHRoZQorICAvLyBiZWhhdmlvciBvZiB0aGUgY29udGFpbmVyLiBWZXJ5IHNpbWlsYXIgdG8gdGhlIHRhYmxlIG9mIHZpcnR1YWwgZnVuY3Rpb25zCisgIC8vIG9mIGEgQysrIGNsYXNzLgorICBjb25zdCBEZXNjcmlwdG9yQ29udGFpbmVyRGVmKiBjb250YWluZXJfZGVmOworCisgIC8vIFRoZSBraW5kIG9mIGNvbnRhaW5lcjogbGlzdCwgb3IgZGljdCBieSBuYW1lIG9yIHZhbHVlLgorICBlbnVtIENvbnRhaW5lcktpbmQgeworICAgIEtJTkRfU0VRVUVOQ0UsCisgICAgS0lORF9CWU5BTUUsCisgICAgS0lORF9CWU5VTUJFUiwKKyAgfSBraW5kOworfTsKKworc3RydWN0IFB5Q29udGFpbmVySXRlcmF0b3IgeworICBQeU9iamVjdF9IRUFECisKKyAgLy8gVGhlIGNvbnRhaW5lciB3ZSBhcmUgaXRlcmF0aW5nIG92ZXIuIE93biBhIHJlZmVyZW5jZS4KKyAgUHlDb250YWluZXIqIGNvbnRhaW5lcjsKKworICAvLyBUaGUgY3VycmVudCBpbmRleCBpbiB0aGUgaXRlcmF0b3IuCisgIGludCBpbmRleDsKKworICAvLyBUaGUga2luZCBvZiBjb250YWluZXI6IGxpc3QsIG9yIGRpY3QgYnkgbmFtZSBvciB2YWx1ZS4KKyAgZW51bSBJdGVyS2luZCB7CisgICAgS0lORF9JVEVSS0VZLAorICAgIEtJTkRfSVRFUlZBTFVFLAorICAgIEtJTkRfSVRFUklURU0sCisgICAgS0lORF9JVEVSVkFMVUVfUkVWRVJTRUQsICAvLyBGb3Igc2VxdWVuY2VzCisgIH0ga2luZDsKK307CisKK25hbWVzcGFjZSBkZXNjcmlwdG9yIHsKKworLy8gUmV0dXJucyB0aGUgQysrIGl0ZW0gZGVzY3JpcHRvciBmb3IgYSBnaXZlbiBQeXRob24ga2V5LgorLy8gV2hlbiB0aGUgZGVzY3JpcHRvciBpcyBmb3VuZCwgcmV0dXJuIHRydWUgYW5kIHNldCAqaXRlbS4KKy8vIFdoZW4gdGhlIGRlc2NyaXB0b3IgaXMgbm90IGZvdW5kLCByZXR1cm4gdHJ1ZSwgYnV0IHNldCAqaXRlbSB0byBOVUxMLgorLy8gT24gZXJyb3IsIHJldHVybnMgZmFsc2Ugd2l0aCBhbiBleGNlcHRpb24gc2V0Lgorc3RhdGljIGJvb2wgX0dldEl0ZW1CeUtleShQeUNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIGtleSwgY29uc3Qgdm9pZCoqIGl0ZW0pIHsKKyAgc3dpdGNoIChzZWxmLT5raW5kKSB7CisgICAgY2FzZSBQeUNvbnRhaW5lcjo6S0lORF9CWU5BTUU6CisgICAgICB7CisgICAgICAgIGNoYXIqIG5hbWU7CisgICAgICAgIFB5X3NzaXplX3QgbmFtZV9zaXplOworICAgICAgICBpZiAoUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKGtleSwgJm5hbWUsICZuYW1lX3NpemUpIDwgMCkgeworICAgICAgICAgIGlmIChQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX1R5cGVFcnJvcikpIHsKKyAgICAgICAgICAgIC8vIE5vdCBhIHN0cmluZywgY2Fubm90IGJlIGluIHRoZSBjb250YWluZXIuCisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICAgICAgKml0ZW0gPSBOVUxMOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICAqaXRlbSA9IHNlbGYtPmNvbnRhaW5lcl9kZWYtPmdldF9ieV9uYW1lX2ZuKAorICAgICAgICAgICAgc2VsZiwgc3RyaW5nKG5hbWUsIG5hbWVfc2l6ZSkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICBjYXNlIFB5Q29udGFpbmVyOjpLSU5EX0JZTlVNQkVSOgorICAgICAgeworICAgICAgICBQeV9zc2l6ZV90IG51bWJlciA9IFB5TnVtYmVyX0FzU3NpemVfdChrZXksIE5VTEwpOworICAgICAgICBpZiAobnVtYmVyID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKSB7CisgICAgICAgICAgICAvLyBOb3QgYSBudW1iZXIsIGNhbm5vdCBiZSBpbiB0aGUgY29udGFpbmVyLgorICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICppdGVtID0gTlVMTDsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgKml0ZW0gPSBzZWxmLT5jb250YWluZXJfZGVmLT5nZXRfYnlfbnVtYmVyX2ZuKHNlbGYsIG51bWJlcik7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICBQeUVycl9TZXROb25lKFB5RXhjX05vdEltcGxlbWVudGVkRXJyb3IpOworICAgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKy8vIFJldHVybnMgdGhlIGtleSBvZiB0aGUgb2JqZWN0IGF0IHRoZSBnaXZlbiBpbmRleC4KKy8vIFVzZWQgd2hlbiBpdGVyYXRpbmcgb3ZlciBtYXBwaW5ncy4KK3N0YXRpYyBQeU9iamVjdCogX05ld0tleV9CeUluZGV4KFB5Q29udGFpbmVyKiBzZWxmLCBQeV9zc2l6ZV90IGluZGV4KSB7CisgIGNvbnN0IHZvaWQqIGl0ZW0gPSBzZWxmLT5jb250YWluZXJfZGVmLT5nZXRfYnlfaW5kZXhfZm4oc2VsZiwgaW5kZXgpOworICBzd2l0Y2ggKHNlbGYtPmtpbmQpIHsKKyAgICBjYXNlIFB5Q29udGFpbmVyOjpLSU5EX0JZTkFNRToKKyAgICAgIHsKKyAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKHNlbGYtPmNvbnRhaW5lcl9kZWYtPmdldF9pdGVtX25hbWVfZm4oaXRlbSkpOworICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUobmFtZS5jX3N0cigpLCBuYW1lLnNpemUoKSk7CisgICAgICB9CisgICAgY2FzZSBQeUNvbnRhaW5lcjo6S0lORF9CWU5VTUJFUjoKKyAgICAgIHsKKyAgICAgICAgaW50IHZhbHVlID0gc2VsZi0+Y29udGFpbmVyX2RlZi0+Z2V0X2l0ZW1fbnVtYmVyX2ZuKGl0ZW0pOworICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcodmFsdWUpOworICAgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICBQeUVycl9TZXROb25lKFB5RXhjX05vdEltcGxlbWVudGVkRXJyb3IpOworICAgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworLy8gUmV0dXJucyB0aGUgb2JqZWN0IGF0IHRoZSBnaXZlbiBpbmRleC4KKy8vIEFsc28gdXNlZCB3aGVuIGl0ZXJhdGluZyBvdmVyIG1hcHBpbmdzLgorc3RhdGljIFB5T2JqZWN0KiBfTmV3T2JqX0J5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIFB5X3NzaXplX3QgaW5kZXgpIHsKKyAgcmV0dXJuIHNlbGYtPmNvbnRhaW5lcl9kZWYtPm5ld19vYmplY3RfZnJvbV9pdGVtX2ZuKAorICAgICAgc2VsZi0+Y29udGFpbmVyX2RlZi0+Z2V0X2J5X2luZGV4X2ZuKHNlbGYsIGluZGV4KSk7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90IExlbmd0aChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gc2VsZi0+Y29udGFpbmVyX2RlZi0+Y291bnRfZm4oc2VsZik7Cit9CisKKy8vIFRoZSBEZXNjcmlwdG9yTWFwcGluZyB0eXBlLgorCitzdGF0aWMgUHlPYmplY3QqIFN1YnNjcmlwdChQeUNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIGtleSkgeworICBjb25zdCB2b2lkKiBpdGVtID0gTlVMTDsKKyAgaWYgKCFfR2V0SXRlbUJ5S2V5KHNlbGYsIGtleSwgJml0ZW0pKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaWYgKCFpdGVtKSB7CisgICAgUHlFcnJfU2V0T2JqZWN0KFB5RXhjX0tleUVycm9yLCBrZXkpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBzZWxmLT5jb250YWluZXJfZGVmLT5uZXdfb2JqZWN0X2Zyb21faXRlbV9mbihpdGVtKTsKK30KKworc3RhdGljIGludCBBc3NTdWJzY3JpcHQoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBrZXksIFB5T2JqZWN0KiB2YWx1ZSkgeworICBpZiAoX0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKDApKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICInJS4yMDBzJyBvYmplY3QgZG9lcyBub3Qgc3VwcG9ydCBpdGVtIGFzc2lnbm1lbnQiLAorICAgICAgICAgICAgICAgUHlfVFlQRShzZWxmKS0+dHBfbmFtZSk7CisgIHJldHVybiAtMTsKK30KKworc3RhdGljIFB5TWFwcGluZ01ldGhvZHMgTWFwcGluZ01hcHBpbmdNZXRob2RzID0geworICAobGVuZnVuYylMZW5ndGgsICAgICAgICAgICAgICAgLy8gbXBfbGVuZ3RoCisgIChiaW5hcnlmdW5jKVN1YnNjcmlwdCwgICAgICAgICAvLyBtcF9zdWJzY3JpcHQKKyAgKG9iam9iamFyZ3Byb2MpQXNzU3Vic2NyaXB0LCAgIC8vIG1wX2Fzc19zdWJzY3JpcHQKK307CisKK3N0YXRpYyBpbnQgQ29udGFpbnMoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBrZXkpIHsKKyAgY29uc3Qgdm9pZCogaXRlbSA9IE5VTEw7CisgIGlmICghX0dldEl0ZW1CeUtleShzZWxmLCBrZXksICZpdGVtKSkgeworICAgIHJldHVybiAtMTsKKyAgfQorICBpZiAoaXRlbSkgeworICAgIHJldHVybiAxOworICB9IGVsc2UgeworICAgIHJldHVybiAwOworICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCogQ29udGFpbmVyUmVwcihQeUNvbnRhaW5lciogc2VsZikgeworICBjb25zdCBjaGFyKiBraW5kID0gIiI7CisgIHN3aXRjaCAoc2VsZi0+a2luZCkgeworICAgIGNhc2UgUHlDb250YWluZXI6OktJTkRfU0VRVUVOQ0U6CisgICAgICBraW5kID0gInNlcXVlbmNlIjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgUHlDb250YWluZXI6OktJTkRfQllOQU1FOgorICAgICAga2luZCA9ICJtYXBwaW5nIGJ5IG5hbWUiOworICAgICAgYnJlYWs7CisgICAgY2FzZSBQeUNvbnRhaW5lcjo6S0lORF9CWU5VTUJFUjoKKyAgICAgIGtpbmQgPSAibWFwcGluZyBieSBudW1iZXIiOworICAgICAgYnJlYWs7CisgIH0KKyAgcmV0dXJuIFB5U3RyaW5nX0Zyb21Gb3JtYXQoCisgICAgICAiPCVzICVzPiIsIHNlbGYtPmNvbnRhaW5lcl9kZWYtPm1hcHBpbmdfbmFtZSwga2luZCk7Cit9CisKK2V4dGVybiBQeVR5cGVPYmplY3QgRGVzY3JpcHRvck1hcHBpbmdfVHlwZTsKK2V4dGVybiBQeVR5cGVPYmplY3QgRGVzY3JpcHRvclNlcXVlbmNlX1R5cGU7CisKKy8vIEEgc2VxdWVuY2UgY29udGFpbmVyIGNhbiBvbmx5IGJlIGVxdWFsIHRvIGFub3RoZXIgc2VxdWVuY2UgY29udGFpbmVyLCBvciAoZm9yCisvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KSB0byBhIGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSBpdGVtcy4KKy8vIFJldHVybnMgMSBpZiBlcXVhbCwgMCBpZiB1bmVxdWFsLCAtMSBvbiBlcnJvci4KK3N0YXRpYyBpbnQgRGVzY3JpcHRvclNlcXVlbmNlX0VxdWFsKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogb3RoZXIpIHsKKyAgLy8gQ2hlY2sgdGhlIGlkZW50aXR5IG9mIEMrKyBwb2ludGVycy4KKyAgaWYgKFB5T2JqZWN0X1R5cGVDaGVjayhvdGhlciwgJkRlc2NyaXB0b3JTZXF1ZW5jZV9UeXBlKSkgeworICAgIFB5Q29udGFpbmVyKiBvdGhlcl9jb250YWluZXIgPSByZWludGVycHJldF9jYXN0PFB5Q29udGFpbmVyKj4ob3RoZXIpOworICAgIGlmIChzZWxmLT5kZXNjcmlwdG9yID09IG90aGVyX2NvbnRhaW5lci0+ZGVzY3JpcHRvciAmJgorICAgICAgICBzZWxmLT5jb250YWluZXJfZGVmID09IG90aGVyX2NvbnRhaW5lci0+Y29udGFpbmVyX2RlZiAmJgorICAgICAgICBzZWxmLT5raW5kID09IG90aGVyX2NvbnRhaW5lci0+a2luZCkgeworICAgICAgcmV0dXJuIDE7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorCisgIC8vIElmIG90aGVyIGlzIGEgbGlzdAorICBpZiAoUHlMaXN0X0NoZWNrKG90aGVyKSkgeworICAgIC8vIHJldHVybiBsaXN0KHNlbGYpID09IG90aGVyCisgICAgaW50IHNpemUgPSBMZW5ndGgoc2VsZik7CisgICAgaWYgKHNpemUgIT0gUHlMaXN0X1NpemUob3RoZXIpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBzaXplOyBpbmRleCsrKSB7CisgICAgICBTY29wZWRQeU9iamVjdFB0ciB2YWx1ZTEoX05ld09ial9CeUluZGV4KHNlbGYsIGluZGV4KSk7CisgICAgICBpZiAodmFsdWUxID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgUHlPYmplY3QqIHZhbHVlMiA9IFB5TGlzdF9HZXRJdGVtKG90aGVyLCBpbmRleCk7CisgICAgICBpZiAodmFsdWUyID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgaW50IGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbCh2YWx1ZTEsIHZhbHVlMiwgUHlfRVEpOworICAgICAgaWYgKGNtcCAhPSAxKSAgLy8gZXJyb3Igb3Igbm90IGVxdWFsCisgICAgICAgICAgcmV0dXJuIGNtcDsKKyAgICB9CisgICAgLy8gQWxsIGl0ZW1zIHdlcmUgZm91bmQgYW5kIGVxdWFsCisgICAgcmV0dXJuIDE7CisgIH0KKworICAvLyBBbnkgb3RoZXIgb2JqZWN0IGlzIGRpZmZlcmVudC4KKyAgcmV0dXJuIDA7Cit9CisKKy8vIEEgbWFwcGluZyBjb250YWluZXIgY2FuIG9ubHkgYmUgZXF1YWwgdG8gYW5vdGhlciBtYXBwaW5nIGNvbnRhaW5lciwgb3IgKGZvcgorLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSkgdG8gYSBkaWN0IGNvbnRhaW5pbmcgdGhlIHNhbWUgaXRlbXMuCisvLyBSZXR1cm5zIDEgaWYgZXF1YWwsIDAgaWYgdW5lcXVhbCwgLTEgb24gZXJyb3IuCitzdGF0aWMgaW50IERlc2NyaXB0b3JNYXBwaW5nX0VxdWFsKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogb3RoZXIpIHsKKyAgLy8gQ2hlY2sgdGhlIGlkZW50aXR5IG9mIEMrKyBwb2ludGVycy4KKyAgaWYgKFB5T2JqZWN0X1R5cGVDaGVjayhvdGhlciwgJkRlc2NyaXB0b3JNYXBwaW5nX1R5cGUpKSB7CisgICAgUHlDb250YWluZXIqIG90aGVyX2NvbnRhaW5lciA9IHJlaW50ZXJwcmV0X2Nhc3Q8UHlDb250YWluZXIqPihvdGhlcik7CisgICAgaWYgKHNlbGYtPmRlc2NyaXB0b3IgPT0gb3RoZXJfY29udGFpbmVyLT5kZXNjcmlwdG9yICYmCisgICAgICAgIHNlbGYtPmNvbnRhaW5lcl9kZWYgPT0gb3RoZXJfY29udGFpbmVyLT5jb250YWluZXJfZGVmICYmCisgICAgICAgIHNlbGYtPmtpbmQgPT0gb3RoZXJfY29udGFpbmVyLT5raW5kKSB7CisgICAgICByZXR1cm4gMTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisKKyAgLy8gSWYgb3RoZXIgaXMgYSBkaWN0CisgIGlmIChQeURpY3RfQ2hlY2sob3RoZXIpKSB7CisgICAgLy8gZXF1aXZhbGVudCB0byBkaWN0KHNlbGYuaXRlbXMoKSkgPT0gb3RoZXIKKyAgICBpbnQgc2l6ZSA9IExlbmd0aChzZWxmKTsKKyAgICBpZiAoc2l6ZSAhPSBQeURpY3RfU2l6ZShvdGhlcikpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IHNpemU7IGluZGV4KyspIHsKKyAgICAgIFNjb3BlZFB5T2JqZWN0UHRyIGtleShfTmV3S2V5X0J5SW5kZXgoc2VsZiwgaW5kZXgpKTsKKyAgICAgIGlmIChrZXkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgICB9CisgICAgICBTY29wZWRQeU9iamVjdFB0ciB2YWx1ZTEoX05ld09ial9CeUluZGV4KHNlbGYsIGluZGV4KSk7CisgICAgICBpZiAodmFsdWUxID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgUHlPYmplY3QqIHZhbHVlMiA9IFB5RGljdF9HZXRJdGVtKG90aGVyLCBrZXkpOworICAgICAgaWYgKHZhbHVlMiA9PSBOVUxMKSB7CisgICAgICAgIC8vIE5vdCBmb3VuZCBpbiB0aGUgb3RoZXIgZGljdGlvbmFyeQorICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGludCBjbXAgPSBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2wodmFsdWUxLCB2YWx1ZTIsIFB5X0VRKTsKKyAgICAgIGlmIChjbXAgIT0gMSkgIC8vIGVycm9yIG9yIG5vdCBlcXVhbAorICAgICAgICAgIHJldHVybiBjbXA7CisgICAgfQorICAgIC8vIEFsbCBpdGVtcyB3ZXJlIGZvdW5kIGFuZCBlcXVhbAorICAgIHJldHVybiAxOworICB9CisKKyAgLy8gQW55IG90aGVyIG9iamVjdCBpcyBkaWZmZXJlbnQuCisgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QqIFJpY2hDb21wYXJlKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogb3RoZXIsIGludCBvcGlkKSB7CisgIGlmIChvcGlkICE9IFB5X0VRICYmIG9waWQgIT0gUHlfTkUpIHsKKyAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgfQorCisgIGludCByZXN1bHQ7CisKKyAgaWYgKHNlbGYtPmtpbmQgPT0gUHlDb250YWluZXI6OktJTkRfU0VRVUVOQ0UpIHsKKyAgICByZXN1bHQgPSBEZXNjcmlwdG9yU2VxdWVuY2VfRXF1YWwoc2VsZiwgb3RoZXIpOworICB9IGVsc2UgeworICAgIHJlc3VsdCA9IERlc2NyaXB0b3JNYXBwaW5nX0VxdWFsKHNlbGYsIG90aGVyKTsKKyAgfQorICBpZiAocmVzdWx0IDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChyZXN1bHQgXiAob3BpZCA9PSBQeV9ORSkpIHsKKyAgICBQeV9SRVRVUk5fVFJVRTsKKyAgfSBlbHNlIHsKKyAgICBQeV9SRVRVUk5fRkFMU0U7CisgIH0KK30KKworc3RhdGljIFB5U2VxdWVuY2VNZXRob2RzIE1hcHBpbmdTZXF1ZW5jZU1ldGhvZHMgPSB7CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfbGVuZ3RoCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfY29uY2F0CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfcmVwZWF0CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfaXRlbQorICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8vIHNxX3NsaWNlCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfYXNzX2l0ZW0KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvLyBzcV9hc3Nfc2xpY2UKKyAgICAob2Jqb2JqcHJvYylDb250YWlucywgICAvLyBzcV9jb250YWlucworfTsKKworc3RhdGljIFB5T2JqZWN0KiBHZXQoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKSB7CisgIFB5T2JqZWN0KiBrZXk7CisgIFB5T2JqZWN0KiBkZWZhdWx0X3ZhbHVlID0gUHlfTm9uZTsKKyAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCAiZ2V0IiwgMSwgMiwgJmtleSwgJmRlZmF1bHRfdmFsdWUpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBjb25zdCB2b2lkKiBpdGVtOworICBpZiAoIV9HZXRJdGVtQnlLZXkoc2VsZiwga2V5LCAmaXRlbSkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoaXRlbSA9PSBOVUxMKSB7CisgICAgUHlfSU5DUkVGKGRlZmF1bHRfdmFsdWUpOworICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9CisgIHJldHVybiBzZWxmLT5jb250YWluZXJfZGVmLT5uZXdfb2JqZWN0X2Zyb21faXRlbV9mbihpdGVtKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBLZXlzKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICBQeV9zc2l6ZV90IGNvdW50ID0gTGVuZ3RoKHNlbGYpOworICBTY29wZWRQeU9iamVjdFB0ciBsaXN0KFB5TGlzdF9OZXcoY291bnQpKTsKKyAgaWYgKGxpc3QgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGZvciAoUHlfc3NpemVfdCBpbmRleCA9IDA7IGluZGV4IDwgY291bnQ7ICsraW5kZXgpIHsKKyAgICBQeU9iamVjdCoga2V5ID0gX05ld0tleV9CeUluZGV4KHNlbGYsIGluZGV4KTsKKyAgICBpZiAoa2V5ID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeUxpc3RfU0VUX0lURU0obGlzdC5nZXQoKSwgaW5kZXgsIGtleSk7CisgIH0KKyAgcmV0dXJuIGxpc3QucmVsZWFzZSgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIFZhbHVlcyhQeUNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpIHsKKyAgUHlfc3NpemVfdCBjb3VudCA9IExlbmd0aChzZWxmKTsKKyAgU2NvcGVkUHlPYmplY3RQdHIgbGlzdChQeUxpc3RfTmV3KGNvdW50KSk7CisgIGlmIChsaXN0ID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBmb3IgKFB5X3NzaXplX3QgaW5kZXggPSAwOyBpbmRleCA8IGNvdW50OyArK2luZGV4KSB7CisgICAgUHlPYmplY3QqIHZhbHVlID0gX05ld09ial9CeUluZGV4KHNlbGYsIGluZGV4KTsKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5TGlzdF9TRVRfSVRFTShsaXN0LmdldCgpLCBpbmRleCwgdmFsdWUpOworICB9CisgIHJldHVybiBsaXN0LnJlbGVhc2UoKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBJdGVtcyhQeUNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpIHsKKyAgUHlfc3NpemVfdCBjb3VudCA9IExlbmd0aChzZWxmKTsKKyAgU2NvcGVkUHlPYmplY3RQdHIgbGlzdChQeUxpc3RfTmV3KGNvdW50KSk7CisgIGlmIChsaXN0ID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBmb3IgKFB5X3NzaXplX3QgaW5kZXggPSAwOyBpbmRleCA8IGNvdW50OyArK2luZGV4KSB7CisgICAgU2NvcGVkUHlPYmplY3RQdHIgb2JqKFB5VHVwbGVfTmV3KDIpKTsKKyAgICBpZiAob2JqID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeU9iamVjdCoga2V5ID0gX05ld0tleV9CeUluZGV4KHNlbGYsIGluZGV4KTsKKyAgICBpZiAoa2V5ID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeVR1cGxlX1NFVF9JVEVNKG9iai5nZXQoKSwgMCwga2V5KTsKKyAgICBQeU9iamVjdCogdmFsdWUgPSBfTmV3T2JqX0J5SW5kZXgoc2VsZiwgaW5kZXgpOworICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlUdXBsZV9TRVRfSVRFTShvYmouZ2V0KCksIDEsIHZhbHVlKTsKKyAgICBQeUxpc3RfU0VUX0lURU0obGlzdC5nZXQoKSwgaW5kZXgsIG9iai5yZWxlYXNlKCkpOworICB9CisgIHJldHVybiBsaXN0LnJlbGVhc2UoKTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBOZXdDb250YWluZXJJdGVyYXRvcihQeUNvbnRhaW5lciogbWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlDb250YWluZXJJdGVyYXRvcjo6SXRlcktpbmQga2luZCk7CisKK3N0YXRpYyBQeU9iamVjdCogSXRlcihQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gTmV3Q29udGFpbmVySXRlcmF0b3Ioc2VsZiwgUHlDb250YWluZXJJdGVyYXRvcjo6S0lORF9JVEVSS0VZKTsKK30KK3N0YXRpYyBQeU9iamVjdCogSXRlcktleXMoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKSB7CisgIHJldHVybiBOZXdDb250YWluZXJJdGVyYXRvcihzZWxmLCBQeUNvbnRhaW5lckl0ZXJhdG9yOjpLSU5EX0lURVJLRVkpOworfQorc3RhdGljIFB5T2JqZWN0KiBJdGVyVmFsdWVzKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICByZXR1cm4gTmV3Q29udGFpbmVySXRlcmF0b3Ioc2VsZiwgUHlDb250YWluZXJJdGVyYXRvcjo6S0lORF9JVEVSVkFMVUUpOworfQorc3RhdGljIFB5T2JqZWN0KiBJdGVySXRlbXMoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKSB7CisgIHJldHVybiBOZXdDb250YWluZXJJdGVyYXRvcihzZWxmLCBQeUNvbnRhaW5lckl0ZXJhdG9yOjpLSU5EX0lURVJJVEVNKTsKK30KKworc3RhdGljIFB5TWV0aG9kRGVmIE1hcHBpbmdNZXRob2RzW10gPSB7CisgIHsgImdldCIsIChQeUNGdW5jdGlvbilHZXQsIE1FVEhfVkFSQVJHUywgfSwKKyAgeyAia2V5cyIsIChQeUNGdW5jdGlvbilLZXlzLCBNRVRIX05PQVJHUywgfSwKKyAgeyAidmFsdWVzIiwgKFB5Q0Z1bmN0aW9uKVZhbHVlcywgTUVUSF9OT0FSR1MsIH0sCisgIHsgIml0ZW1zIiwgKFB5Q0Z1bmN0aW9uKUl0ZW1zLCBNRVRIX05PQVJHUywgfSwKKyAgeyAiaXRlcmtleXMiLCAoUHlDRnVuY3Rpb24pSXRlcktleXMsIE1FVEhfTk9BUkdTLCB9LAorICB7ICJpdGVydmFsdWVzIiwgKFB5Q0Z1bmN0aW9uKUl0ZXJWYWx1ZXMsIE1FVEhfTk9BUkdTLCB9LAorICB7ICJpdGVyaXRlbXMiLCAoUHlDRnVuY3Rpb24pSXRlckl0ZW1zLCBNRVRIX05PQVJHUywgfSwKKyAge05VTEx9Cit9OworCitQeVR5cGVPYmplY3QgRGVzY3JpcHRvck1hcHBpbmdfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgIkRlc2NyaXB0b3JNYXBwaW5nIiwgICAgICAgICAgICAgICAgICAvLyB0cF9uYW1lCisgIHNpemVvZihQeUNvbnRhaW5lciksICAgICAgICAgICAgICAgICAgLy8gdHBfYmFzaWNzaXplCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlbXNpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kZWFsbG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfcHJpbnQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NvbXBhcmUKKyAgKHJlcHJmdW5jKUNvbnRhaW5lclJlcHIsICAgICAgICAgICAgICAvLyB0cF9yZXByCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfbnVtYmVyCisgICZNYXBwaW5nU2VxdWVuY2VNZXRob2RzLCAgICAgICAgICAgICAgLy8gdHBfYXNfc2VxdWVuY2UKKyAgJk1hcHBpbmdNYXBwaW5nTWV0aG9kcywgICAgICAgICAgICAgICAvLyB0cF9hc19tYXBwaW5nCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaGFzaAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NhbGwKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zdHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3NldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfYnVmZmVyCisgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgICAgLy8gdHBfZmxhZ3MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF90cmF2ZXJzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2NsZWFyCisgIChyaWNoY21wZnVuYylSaWNoQ29tcGFyZSwgICAgICAgICAgICAgLy8gdHBfcmljaGNvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF93ZWFrbGlzdG9mZnNldAorICAoZ2V0aXRlcmZ1bmMpSXRlciwgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVybmV4dAorICBNYXBwaW5nTWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21ldGhvZHMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9tZW1iZXJzCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZ2V0c2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYmFzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RpY3QKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kZXNjcl9nZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kZXNjcl9zZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kaWN0b2Zmc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaW5pdAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FsbG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbmV3CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZnJlZQorfTsKKworLy8gVGhlIERlc2NyaXB0b3JTZXF1ZW5jZSB0eXBlLgorCitzdGF0aWMgUHlPYmplY3QqIEdldEl0ZW0oUHlDb250YWluZXIqIHNlbGYsIFB5X3NzaXplX3QgaW5kZXgpIHsKKyAgaWYgKGluZGV4IDwgMCkgeworICAgIGluZGV4ICs9IExlbmd0aChzZWxmKTsKKyAgfQorICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IExlbmd0aChzZWxmKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAiaW5kZXggb3V0IG9mIHJhbmdlIik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIF9OZXdPYmpfQnlJbmRleChzZWxmLCBpbmRleCk7Cit9CisKKy8vIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIHRoZSBpdGVtIGluIHRoZSBzZXF1ZW5jZSwgb2YgLTEgaWYgbm90IGZvdW5kLgorLy8gVGhpcyBmdW5jdGlvbiBuZXZlciBmYWlscy4KK2ludCBGaW5kKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogaXRlbSkgeworICAvLyBUaGUgaXRlbSBjYW4gb25seSBiZSBpbiBvbmUgcG9zaXRpb246IGl0ZW0uaW5kZXguCisgIC8vIENoZWNrIHRoYXQgc2VsZltpdGVtLmluZGV4XSA9PSBpdGVtLCBpdCdzIGZhc3RlciB0aGFuIGEgbGluZWFyIHNlYXJjaC4KKyAgLy8KKyAgLy8gVGhpcyBhc3N1bWVzIHRoYXQgc2VxdWVuY2VzIGFyZSBvbmx5IGRlZmluZWQgYnkgc3ludGF4IG9mIHRoZSAucHJvdG8gZmlsZToKKyAgLy8gYSBzcGVjaWZpYyBpdGVtIGJlbG9uZ3MgdG8gb25seSBvbmUgc2VxdWVuY2UsIGRlcGVuZGluZyBvbiBpdHMgcG9zaXRpb24gaW4KKyAgLy8gdGhlIC5wcm90byBmaWxlIGRlZmluaXRpb24uCisgIGNvbnN0IHZvaWQqIGRlc2NyaXB0b3JfcHRyID0gUHlEZXNjcmlwdG9yX0FzVm9pZFB0cihpdGVtKTsKKyAgaWYgKGRlc2NyaXB0b3JfcHRyID09IE5VTEwpIHsKKyAgICAvLyBOb3QgYSBkZXNjcmlwdG9yLCBpdCBjYW5ub3QgYmUgaW4gdGhlIGxpc3QuCisgICAgcmV0dXJuIC0xOworICB9CisgIGlmIChzZWxmLT5jb250YWluZXJfZGVmLT5nZXRfaXRlbV9pbmRleF9mbikgeworICAgIGludCBpbmRleCA9IHNlbGYtPmNvbnRhaW5lcl9kZWYtPmdldF9pdGVtX2luZGV4X2ZuKGRlc2NyaXB0b3JfcHRyKTsKKyAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IExlbmd0aChzZWxmKSkgeworICAgICAgLy8gVGhpcyBpbmRleCBpcyBub3QgZnJvbSB0aGlzIGNvbGxlY3Rpb24uCisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChzZWxmLT5jb250YWluZXJfZGVmLT5nZXRfYnlfaW5kZXhfZm4oc2VsZiwgaW5kZXgpICE9IGRlc2NyaXB0b3JfcHRyKSB7CisgICAgICAvLyBUaGUgZGVzY3JpcHRvciBhdCB0aGlzIGluZGV4IGlzIG5vdCB0aGUgc2FtZS4KKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgLy8gc2VsZltpdGVtLmluZGV4XSA9PSBpdGVtLCBzbyByZXR1cm4gdGhlIGluZGV4LgorICAgIHJldHVybiBpbmRleDsKKyAgfSBlbHNlIHsKKyAgICAvLyBGYWxsIGJhY2sgdG8gbGluZWFyIHNlYXJjaC4KKyAgICBpbnQgbGVuZ3RoID0gTGVuZ3RoKHNlbGYpOworICAgIGZvciAoaW50IGluZGV4PTA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CisgICAgICBpZiAoc2VsZi0+Y29udGFpbmVyX2RlZi0+Z2V0X2J5X2luZGV4X2ZuKHNlbGYsIGluZGV4KSA9PSBkZXNjcmlwdG9yX3B0cikgeworICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgICB9CisgICAgfQorICAgIC8vIE5vdCBmb3VuZAorICAgIHJldHVybiAtMTsKKyAgfQorfQorCisvLyBJbXBsZW1lbnRzIGxpc3QuaW5kZXgoKTogdGhlIHBvc2l0aW9uIG9mIHRoZSBpdGVtIGlzIGluIHRoZSBzZXF1ZW5jZS4KK3N0YXRpYyBQeU9iamVjdCogSW5kZXgoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBpdGVtKSB7CisgIGludCBwb3NpdGlvbiA9IEZpbmQoc2VsZiwgaXRlbSk7CisgIGlmIChwb3NpdGlvbiA8IDApIHsKKyAgICAvLyBOb3QgZm91bmQKKyAgICBQeUVycl9TZXROb25lKFB5RXhjX1ZhbHVlRXJyb3IpOworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhwb3NpdGlvbik7CisgIH0KK30KKy8vIEltcGxlbWVudHMgImxpc3QuX19jb250YWluc19fKCkiOiBpcyB0aGUgb2JqZWN0IGluIHRoZSBzZXF1ZW5jZS4KK3N0YXRpYyBpbnQgU2VxQ29udGFpbnMoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBpdGVtKSB7CisgIGludCBwb3NpdGlvbiA9IEZpbmQoc2VsZiwgaXRlbSk7CisgIGlmIChwb3NpdGlvbiA8IDApIHsKKyAgICByZXR1cm4gMDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gMTsKKyAgfQorfQorCisvLyBJbXBsZW1lbnRzIGxpc3QuY291bnQoKTogbnVtYmVyIG9mIG9jY3VycmVuY2VzIG9mIHRoZSBpdGVtIGluIHRoZSBzZXF1ZW5jZS4KKy8vIEFuIGl0ZW0gY2FuIG9ubHkgYXBwZWFyIG9uY2UgaW4gYSBzZXF1ZW5jZS4gSWYgaXQgZXhpc3RzLCByZXR1cm4gMS4KK3N0YXRpYyBQeU9iamVjdCogQ291bnQoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBpdGVtKSB7CisgIGludCBwb3NpdGlvbiA9IEZpbmQoc2VsZiwgaXRlbSk7CisgIGlmIChwb3NpdGlvbiA8IDApIHsKKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoMCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKDEpOworICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCogQXBwZW5kKFB5Q29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICBpZiAoX0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlKDApKSB7CisgICAgUHlfUkVUVVJOX05PTkU7CisgIH0KKyAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICInJS4yMDBzJyBvYmplY3QgaXMgbm90IGEgbXV0YWJsZSBzZXF1ZW5jZSIsCisgICAgICAgICAgICAgICBQeV9UWVBFKHNlbGYpLT50cF9uYW1lKTsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogUmV2ZXJzZWQoUHlDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKSB7CisgIHJldHVybiBOZXdDb250YWluZXJJdGVyYXRvcihzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlDb250YWluZXJJdGVyYXRvcjo6S0lORF9JVEVSVkFMVUVfUkVWRVJTRUQpOworfQorCitzdGF0aWMgUHlNZXRob2REZWYgU2VxTWV0aG9kc1tdID0geworICB7ICJpbmRleCIsIChQeUNGdW5jdGlvbilJbmRleCwgTUVUSF9PLCB9LAorICB7ICJjb3VudCIsIChQeUNGdW5jdGlvbilDb3VudCwgTUVUSF9PLCB9LAorICB7ICJhcHBlbmQiLCAoUHlDRnVuY3Rpb24pQXBwZW5kLCBNRVRIX08sIH0sCisgIHsgIl9fcmV2ZXJzZWRfXyIsIChQeUNGdW5jdGlvbilSZXZlcnNlZCwgTUVUSF9OT0FSR1MsIH0sCisgIHtOVUxMfQorfTsKKworc3RhdGljIFB5U2VxdWVuY2VNZXRob2RzIFNlcVNlcXVlbmNlTWV0aG9kcyA9IHsKKyAgICAobGVuZnVuYylMZW5ndGgsICAgICAgICAgIC8vIHNxX2xlbmd0aAorICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfY29uY2F0CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcV9yZXBlYXQKKyAgICAoc3NpemVhcmdmdW5jKUdldEl0ZW0sICAgIC8vIHNxX2l0ZW0KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNxX3NsaWNlCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcV9hc3NfaXRlbQorICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3FfYXNzX3NsaWNlCisgICAgKG9iam9ianByb2MpU2VxQ29udGFpbnMsICAvLyBzcV9jb250YWlucworfTsKKworUHlUeXBlT2JqZWN0IERlc2NyaXB0b3JTZXF1ZW5jZV9UeXBlID0geworICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAiRGVzY3JpcHRvclNlcXVlbmNlIiwgICAgICAgICAgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5Q29udGFpbmVyKSwgICAgICAgICAgICAgICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVtc2l6ZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY29tcGFyZQorICAocmVwcmZ1bmMpQ29udGFpbmVyUmVwciwgICAgICAgICAgICAgIC8vIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgJlNlcVNlcXVlbmNlTWV0aG9kcywgICAgICAgICAgICAgICAgICAvLyB0cF9hc19zZXF1ZW5jZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX21hcHBpbmcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2FsbAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3N0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19idWZmZXIKKyAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3RyYXZlcnNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgKHJpY2hjbXBmdW5jKVJpY2hDb21wYXJlLCAgICAgICAgICAgICAvLyB0cF9yaWNoY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3dlYWtsaXN0b2Zmc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2l0ZXJuZXh0CisgIFNlcU1ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbWV0aG9kcworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21lbWJlcnMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9iYXNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZGljdAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2Rlc2NyX2dldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2Rlc2NyX3NldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RpY3RvZmZzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pbml0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9uZXcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9mcmVlCit9OworCitzdGF0aWMgUHlPYmplY3QqIE5ld01hcHBpbmdCeU5hbWUoCisgICAgRGVzY3JpcHRvckNvbnRhaW5lckRlZiogY29udGFpbmVyX2RlZiwgY29uc3Qgdm9pZCogZGVzY3JpcHRvcikgeworICBQeUNvbnRhaW5lciogc2VsZiA9IFB5T2JqZWN0X05ldyhQeUNvbnRhaW5lciwgJkRlc2NyaXB0b3JNYXBwaW5nX1R5cGUpOworICBpZiAoc2VsZiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgc2VsZi0+ZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgIHNlbGYtPmNvbnRhaW5lcl9kZWYgPSBjb250YWluZXJfZGVmOworICBzZWxmLT5raW5kID0gUHlDb250YWluZXI6OktJTkRfQllOQU1FOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld01hcHBpbmdCeU51bWJlcigKKyAgICBEZXNjcmlwdG9yQ29udGFpbmVyRGVmKiBjb250YWluZXJfZGVmLCBjb25zdCB2b2lkKiBkZXNjcmlwdG9yKSB7CisgIGlmIChjb250YWluZXJfZGVmLT5nZXRfYnlfbnVtYmVyX2ZuID09IE5VTEwgfHwKKyAgICAgIGNvbnRhaW5lcl9kZWYtPmdldF9pdGVtX251bWJlcl9mbiA9PSBOVUxMKSB7CisgICAgUHlFcnJfU2V0Tm9uZShQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeUNvbnRhaW5lciogc2VsZiA9IFB5T2JqZWN0X05ldyhQeUNvbnRhaW5lciwgJkRlc2NyaXB0b3JNYXBwaW5nX1R5cGUpOworICBpZiAoc2VsZiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgc2VsZi0+ZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgIHNlbGYtPmNvbnRhaW5lcl9kZWYgPSBjb250YWluZXJfZGVmOworICBzZWxmLT5raW5kID0gUHlDb250YWluZXI6OktJTkRfQllOVU1CRVI7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oc2VsZik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogTmV3U2VxdWVuY2UoCisgICAgRGVzY3JpcHRvckNvbnRhaW5lckRlZiogY29udGFpbmVyX2RlZiwgY29uc3Qgdm9pZCogZGVzY3JpcHRvcikgeworICBQeUNvbnRhaW5lciogc2VsZiA9IFB5T2JqZWN0X05ldyhQeUNvbnRhaW5lciwgJkRlc2NyaXB0b3JTZXF1ZW5jZV9UeXBlKTsKKyAgaWYgKHNlbGYgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHNlbGYtPmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yOworICBzZWxmLT5jb250YWluZXJfZGVmID0gY29udGFpbmVyX2RlZjsKKyAgc2VsZi0+a2luZCA9IFB5Q29udGFpbmVyOjpLSU5EX1NFUVVFTkNFOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYpOworfQorCisvLyBJbXBsZW1lbnQgaXRlcmF0b3JzIG92ZXIgUHlDb250YWluZXJzLgorCitzdGF0aWMgdm9pZCBJdGVyYXRvcl9EZWFsbG9jKFB5Q29udGFpbmVySXRlcmF0b3IqIHNlbGYpIHsKKyAgUHlfQ0xFQVIoc2VsZi0+Y29udGFpbmVyKTsKKyAgUHlfVFlQRShzZWxmKS0+dHBfZnJlZShyZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEl0ZXJhdG9yX05leHQoUHlDb250YWluZXJJdGVyYXRvciogc2VsZikgeworICBpbnQgY291bnQgPSBzZWxmLT5jb250YWluZXItPmNvbnRhaW5lcl9kZWYtPmNvdW50X2ZuKHNlbGYtPmNvbnRhaW5lcik7CisgIGlmIChzZWxmLT5pbmRleCA+PSBjb3VudCkgeworICAgIC8vIFJldHVybiBOVUxMIHdpdGggbm8gZXhjZXB0aW9uIHRvIGluZGljYXRlIHRoZSBlbmQuCisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaW50IGluZGV4ID0gc2VsZi0+aW5kZXg7CisgIHNlbGYtPmluZGV4ICs9IDE7CisgIHN3aXRjaCAoc2VsZi0+a2luZCkgeworICAgIGNhc2UgUHlDb250YWluZXJJdGVyYXRvcjo6S0lORF9JVEVSS0VZOgorICAgICAgcmV0dXJuIF9OZXdLZXlfQnlJbmRleChzZWxmLT5jb250YWluZXIsIGluZGV4KTsKKyAgICBjYXNlIFB5Q29udGFpbmVySXRlcmF0b3I6OktJTkRfSVRFUlZBTFVFOgorICAgICAgcmV0dXJuIF9OZXdPYmpfQnlJbmRleChzZWxmLT5jb250YWluZXIsIGluZGV4KTsKKyAgICBjYXNlIFB5Q29udGFpbmVySXRlcmF0b3I6OktJTkRfSVRFUlZBTFVFX1JFVkVSU0VEOgorICAgICAgcmV0dXJuIF9OZXdPYmpfQnlJbmRleChzZWxmLT5jb250YWluZXIsIGNvdW50IC0gaW5kZXggLSAxKTsKKyAgICBjYXNlIFB5Q29udGFpbmVySXRlcmF0b3I6OktJTkRfSVRFUklURU06CisgICAgICB7CisgICAgICAgIFB5T2JqZWN0KiBvYmogPSBQeVR1cGxlX05ldygyKTsKKyAgICAgICAgaWYgKG9iaiA9PSBOVUxMKSB7CisgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgUHlPYmplY3QqIGtleSA9IF9OZXdLZXlfQnlJbmRleChzZWxmLT5jb250YWluZXIsIGluZGV4KTsKKyAgICAgICAgaWYgKGtleSA9PSBOVUxMKSB7CisgICAgICAgICAgUHlfREVDUkVGKG9iaik7CisgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShvYmosIDAsIGtleSk7CisgICAgICAgIFB5T2JqZWN0KiB2YWx1ZSA9IF9OZXdPYmpfQnlJbmRleChzZWxmLT5jb250YWluZXIsIGluZGV4KTsKKyAgICAgICAgaWYgKHZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgICBQeV9ERUNSRUYob2JqKTsKKyAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG9iaiwgMSwgdmFsdWUpOworICAgICAgICByZXR1cm4gb2JqOworICAgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICBQeUVycl9TZXROb25lKFB5RXhjX05vdEltcGxlbWVudGVkRXJyb3IpOworICAgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworc3RhdGljIFB5VHlwZU9iamVjdCBDb250YWluZXJJdGVyYXRvcl9UeXBlID0geworICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAiRGVzY3JpcHRvckNvbnRhaW5lckl0ZXJhdG9yIiwgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5Q29udGFpbmVySXRlcmF0b3IpLCAgICAgICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pdGVtc2l6ZQorICAoZGVzdHJ1Y3RvcilJdGVyYXRvcl9EZWFsbG9jLCAgICAgICAgIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19zZXF1ZW5jZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX21hcHBpbmcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2FsbAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3N0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfc2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19idWZmZXIKKyAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3RyYXZlcnNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yaWNoY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3dlYWtsaXN0b2Zmc2V0CisgIFB5T2JqZWN0X1NlbGZJdGVyLCAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAoaXRlcm5leHRmdW5jKUl0ZXJhdG9yX05leHQsICAgICAgICAgIC8vIHRwX2l0ZXJuZXh0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbWV0aG9kcworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21lbWJlcnMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9iYXNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZGljdAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2Rlc2NyX2dldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2Rlc2NyX3NldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RpY3RvZmZzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9pbml0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9uZXcKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9mcmVlCit9OworCitzdGF0aWMgUHlPYmplY3QqIE5ld0NvbnRhaW5lckl0ZXJhdG9yKFB5Q29udGFpbmVyKiBjb250YWluZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Q29udGFpbmVySXRlcmF0b3I6Okl0ZXJLaW5kIGtpbmQpIHsKKyAgUHlDb250YWluZXJJdGVyYXRvciogc2VsZiA9IFB5T2JqZWN0X05ldyhQeUNvbnRhaW5lckl0ZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDb250YWluZXJJdGVyYXRvcl9UeXBlKTsKKyAgaWYgKHNlbGYgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5X0lOQ1JFRihjb250YWluZXIpOworICBzZWxmLT5jb250YWluZXIgPSBjb250YWluZXI7CisgIHNlbGYtPmtpbmQgPSBraW5kOworICBzZWxmLT5pbmRleCA9IDA7CisKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihzZWxmKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGRlc2NyaXB0b3IKKworLy8gTm93IGRlZmluZSB0aGUgcmVhbCBjb2xsZWN0aW9ucyEKKworbmFtZXNwYWNlIG1lc3NhZ2VfZGVzY3JpcHRvciB7CisKK3R5cGVkZWYgY29uc3QgRGVzY3JpcHRvciogUGFyZW50RGVzY3JpcHRvcjsKKworc3RhdGljIFBhcmVudERlc2NyaXB0b3IgR2V0RGVzY3JpcHRvcihQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQYXJlbnREZXNjcmlwdG9yPihzZWxmLT5kZXNjcmlwdG9yKTsKK30KKworbmFtZXNwYWNlIGZpZWxkcyB7CisKK3R5cGVkZWYgY29uc3QgRmllbGREZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZmllbGRfY291bnQoKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5TmFtZShQeUNvbnRhaW5lciogc2VsZiwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5GaW5kRmllbGRCeU5hbWUobmFtZSk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU51bWJlcihQeUNvbnRhaW5lciogc2VsZiwgaW50IG51bWJlcikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZEZpZWxkQnlOdW1iZXIobnVtYmVyKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZmllbGQoaW5kZXgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5RmllbGREZXNjcmlwdG9yX05ldyhpdGVtKTsKK30KKworc3RhdGljIGNvbnN0IHN0cmluZyYgR2V0SXRlbU5hbWUoSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gaXRlbS0+bmFtZSgpOworfQorCitzdGF0aWMgaW50IEdldEl0ZW1OdW1iZXIoSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gaXRlbS0+bnVtYmVyKCk7Cit9CisKK3N0YXRpYyBpbnQgR2V0SXRlbUluZGV4KEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPmluZGV4KCk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIk1lc3NhZ2VGaWVsZHMiLAorICAoQ291bnRNZXRob2QpQ291bnQsCisgIChHZXRCeUluZGV4TWV0aG9kKUdldEJ5SW5kZXgsCisgIChHZXRCeU5hbWVNZXRob2QpR2V0QnlOYW1lLAorICAoR2V0QnlOdW1iZXJNZXRob2QpR2V0QnlOdW1iZXIsCisgIChOZXdPYmplY3RGcm9tSXRlbU1ldGhvZClOZXdPYmplY3RGcm9tSXRlbSwKKyAgKEdldEl0ZW1OYW1lTWV0aG9kKUdldEl0ZW1OYW1lLAorICAoR2V0SXRlbU51bWJlck1ldGhvZClHZXRJdGVtTnVtYmVyLAorICAoR2V0SXRlbUluZGV4TWV0aG9kKUdldEl0ZW1JbmRleCwKK307CisKK30gIC8vIG5hbWVzcGFjZSBmaWVsZHMKKworUHlPYmplY3QqIE5ld01lc3NhZ2VGaWVsZHNCeU5hbWUoUGFyZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdNYXBwaW5nQnlOYW1lKCZmaWVsZHM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlRmllbGRzQnlOdW1iZXIoUGFyZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdNYXBwaW5nQnlOdW1iZXIoJmZpZWxkczo6Q29udGFpbmVyRGVmLCBkZXNjcmlwdG9yKTsKK30KKworUHlPYmplY3QqIE5ld01lc3NhZ2VGaWVsZHNTZXEoUGFyZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdTZXF1ZW5jZSgmZmllbGRzOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgbmVzdGVkX3R5cGVzIHsKKwordHlwZWRlZiBjb25zdCBEZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+bmVzdGVkX3R5cGVfY291bnQoKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5TmFtZShQeUNvbnRhaW5lciogc2VsZiwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZShuYW1lKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+bmVzdGVkX3R5cGUoaW5kZXgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5TWVzc2FnZURlc2NyaXB0b3JfTmV3KGl0ZW0pOworfQorCitzdGF0aWMgY29uc3Qgc3RyaW5nJiBHZXRJdGVtTmFtZShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBpdGVtLT5uYW1lKCk7Cit9CisKK3N0YXRpYyBpbnQgR2V0SXRlbUluZGV4KEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPmluZGV4KCk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIk1lc3NhZ2VOZXN0ZWRUeXBlcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClHZXRCeU5hbWUsCisgIChHZXRCeU51bWJlck1ldGhvZClOVUxMLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClHZXRJdGVtSW5kZXgsCit9OworCit9ICAvLyBuYW1lc3BhY2UgbmVzdGVkX3R5cGVzCisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlTmVzdGVkVHlwZXNTZXEoUGFyZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdTZXF1ZW5jZSgmbmVzdGVkX3R5cGVzOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCitQeU9iamVjdCogTmV3TWVzc2FnZU5lc3RlZFR5cGVzQnlOYW1lKFBhcmVudERlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3TWFwcGluZ0J5TmFtZSgmbmVzdGVkX3R5cGVzOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZW51bXMgeworCit0eXBlZGVmIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZW51bV90eXBlX2NvdW50KCk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU5hbWUoUHlDb250YWluZXIqIHNlbGYsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZEVudW1UeXBlQnlOYW1lKG5hbWUpOworfQorCitzdGF0aWMgSXRlbURlc2NyaXB0b3IgR2V0QnlJbmRleChQeUNvbnRhaW5lciogc2VsZiwgaW50IGluZGV4KSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5lbnVtX3R5cGUoaW5kZXgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5RW51bURlc2NyaXB0b3JfTmV3KGl0ZW0pOworfQorCitzdGF0aWMgY29uc3Qgc3RyaW5nJiBHZXRJdGVtTmFtZShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBpdGVtLT5uYW1lKCk7Cit9CisKK3N0YXRpYyBpbnQgR2V0SXRlbUluZGV4KEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPmluZGV4KCk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIk1lc3NhZ2VOZXN0ZWRFbnVtcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClHZXRCeU5hbWUsCisgIChHZXRCeU51bWJlck1ldGhvZClOVUxMLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClHZXRJdGVtSW5kZXgsCit9OworCit9ICAvLyBuYW1lc3BhY2UgZW51bXMKKworUHlPYmplY3QqIE5ld01lc3NhZ2VFbnVtc0J5TmFtZShQYXJlbnREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld01hcHBpbmdCeU5hbWUoJmVudW1zOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCitQeU9iamVjdCogTmV3TWVzc2FnZUVudW1zU2VxKFBhcmVudERlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3U2VxdWVuY2UoJmVudW1zOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZW51bXZhbHVlcyB7CisKKy8vIFRoaXMgaXMgdGhlICJlbnVtX3ZhbHVlc19ieV9uYW1lIiBtYXBwaW5nLCB3aGljaCBjb2xsZWN0cyB2YWx1ZXMgZnJvbSBhbGwKKy8vIGVudW0gdHlwZXMgaW4gYSBtZXNzYWdlLgorLy8KKy8vIE5vdGUgdGhhdCB0aGUgYmVoYXZpb3Igb2YgdGhlIEMrKyBkZXNjcmlwdG9yIGlzIGRpZmZlcmVudDogaXQgd2lsbCBzZWFyY2ggYW5kCisvLyByZXR1cm4gdGhlIGZpcnN0IHZhbHVlIHRoYXQgbWF0Y2hlcyB0aGUgbmFtZSwgd2hlcmVhcyB0aGUgUHl0aG9uCisvLyBpbXBsZW1lbnRhdGlvbiByZXRyaWV2ZXMgdGhlIGxhc3Qgb25lLgorCit0eXBlZGVmIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIEl0ZW1EZXNjcmlwdG9yOworCitzdGF0aWMgaW50IENvdW50KFB5Q29udGFpbmVyKiBzZWxmKSB7CisgIGludCBjb3VudCA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgR2V0RGVzY3JpcHRvcihzZWxmKS0+ZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvdW50ICs9IEdldERlc2NyaXB0b3Ioc2VsZiktPmVudW1fdHlwZShpKS0+dmFsdWVfY291bnQoKTsKKyAgfQorICByZXR1cm4gY291bnQ7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU5hbWUoUHlDb250YWluZXIqIHNlbGYsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZEVudW1WYWx1ZUJ5TmFtZShuYW1lKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICAvLyBUaGlzIGlzIG5vdCBvcHRpbWFsLCBidXQgdGhlIG51bWJlciBvZiBlbnVtcyAqdHlwZXMqIGluIGEgZ2l2ZW4gbWVzc2FnZQorICAvLyBpcyBzbWFsbC4gIFRoaXMgZnVuY3Rpb24gaXMgb25seSB1c2VkIHdoZW4gaXRlcmF0aW5nIG92ZXIgdGhlIG1hcHBpbmcuCisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUgPSBOVUxMOworICBpbnQgZW51bV90eXBlX2NvdW50ID0gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZW51bV90eXBlX2NvdW50KCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlX2NvdW50OyArK2kpIHsKKyAgICBlbnVtX3R5cGUgPSBHZXREZXNjcmlwdG9yKHNlbGYpLT5lbnVtX3R5cGUoaSk7CisgICAgaW50IGVudW1fdmFsdWVfY291bnQgPSBlbnVtX3R5cGUtPnZhbHVlX2NvdW50KCk7CisgICAgaWYgKGluZGV4IDwgZW51bV92YWx1ZV9jb3VudCkgeworICAgICAgLy8gRm91bmQgaXQhCisgICAgICBicmVhazsKKyAgICB9CisgICAgaW5kZXggLT0gZW51bV92YWx1ZV9jb3VudDsKKyAgfQorICAvLyBUaGUgbmV4dCBzdGF0ZW1lbnQgY2Fubm90IG92ZXJmbG93LCBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgYnkKKyAgLy8gaW50ZXJuYWwgaXRlcmF0b3JzIHdoaWNoIGVuc3VyZSB0aGF0IDAgPD0gaW5kZXggPCBDb3VudCgpLgorICByZXR1cm4gZW51bV90eXBlLT52YWx1ZShpbmRleCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogTmV3T2JqZWN0RnJvbUl0ZW0oSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gUHlFbnVtVmFsdWVEZXNjcmlwdG9yX05ldyhpdGVtKTsKK30KKworc3RhdGljIGNvbnN0IHN0cmluZyYgR2V0SXRlbU5hbWUoSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gaXRlbS0+bmFtZSgpOworfQorCitzdGF0aWMgRGVzY3JpcHRvckNvbnRhaW5lckRlZiBDb250YWluZXJEZWYgPSB7CisgICJNZXNzYWdlRW51bVZhbHVlcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClHZXRCeU5hbWUsCisgIChHZXRCeU51bWJlck1ldGhvZClOVUxMLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClOVUxMLAorfTsKKworfSAgLy8gbmFtZXNwYWNlIGVudW12YWx1ZXMKKworUHlPYmplY3QqIE5ld01lc3NhZ2VFbnVtVmFsdWVzQnlOYW1lKFBhcmVudERlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3TWFwcGluZ0J5TmFtZSgmZW51bXZhbHVlczo6Q29udGFpbmVyRGVmLCBkZXNjcmlwdG9yKTsKK30KKworbmFtZXNwYWNlIGV4dGVuc2lvbnMgeworCit0eXBlZGVmIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogSXRlbURlc2NyaXB0b3I7CisKK3N0YXRpYyBpbnQgQ291bnQoUHlDb250YWluZXIqIHNlbGYpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPmV4dGVuc2lvbl9jb3VudCgpOworfQorCitzdGF0aWMgSXRlbURlc2NyaXB0b3IgR2V0QnlOYW1lKFB5Q29udGFpbmVyKiBzZWxmLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPkZpbmRFeHRlbnNpb25CeU5hbWUobmFtZSk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeUluZGV4KFB5Q29udGFpbmVyKiBzZWxmLCBpbnQgaW5kZXgpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPmV4dGVuc2lvbihpbmRleCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogTmV3T2JqZWN0RnJvbUl0ZW0oSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gUHlGaWVsZERlc2NyaXB0b3JfTmV3KGl0ZW0pOworfQorCitzdGF0aWMgY29uc3Qgc3RyaW5nJiBHZXRJdGVtTmFtZShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBpdGVtLT5uYW1lKCk7Cit9CisKK3N0YXRpYyBpbnQgR2V0SXRlbUluZGV4KEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPmluZGV4KCk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIk1lc3NhZ2VFeHRlbnNpb25zIiwKKyAgKENvdW50TWV0aG9kKUNvdW50LAorICAoR2V0QnlJbmRleE1ldGhvZClHZXRCeUluZGV4LAorICAoR2V0QnlOYW1lTWV0aG9kKUdldEJ5TmFtZSwKKyAgKEdldEJ5TnVtYmVyTWV0aG9kKU5VTEwsCisgIChOZXdPYmplY3RGcm9tSXRlbU1ldGhvZClOZXdPYmplY3RGcm9tSXRlbSwKKyAgKEdldEl0ZW1OYW1lTWV0aG9kKUdldEl0ZW1OYW1lLAorICAoR2V0SXRlbU51bWJlck1ldGhvZClOVUxMLAorICAoR2V0SXRlbUluZGV4TWV0aG9kKUdldEl0ZW1JbmRleCwKK307CisKK30gIC8vIG5hbWVzcGFjZSBleHRlbnNpb25zCisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlRXh0ZW5zaW9uc0J5TmFtZShQYXJlbnREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld01hcHBpbmdCeU5hbWUoJmV4dGVuc2lvbnM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlRXh0ZW5zaW9uc1NlcShQYXJlbnREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld1NlcXVlbmNlKCZleHRlbnNpb25zOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2Ugb25lb2ZzIHsKKwordHlwZWRlZiBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIEl0ZW1EZXNjcmlwdG9yOworCitzdGF0aWMgaW50IENvdW50KFB5Q29udGFpbmVyKiBzZWxmKSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5vbmVvZl9kZWNsX2NvdW50KCk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU5hbWUoUHlDb250YWluZXIqIHNlbGYsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZE9uZW9mQnlOYW1lKG5hbWUpOworfQorCitzdGF0aWMgSXRlbURlc2NyaXB0b3IgR2V0QnlJbmRleChQeUNvbnRhaW5lciogc2VsZiwgaW50IGluZGV4KSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5vbmVvZl9kZWNsKGluZGV4KTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBOZXdPYmplY3RGcm9tSXRlbShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBQeU9uZW9mRGVzY3JpcHRvcl9OZXcoaXRlbSk7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJpbmcmIEdldEl0ZW1OYW1lKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPm5hbWUoKTsKK30KKworc3RhdGljIGludCBHZXRJdGVtSW5kZXgoSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gaXRlbS0+aW5kZXgoKTsKK30KKworc3RhdGljIERlc2NyaXB0b3JDb250YWluZXJEZWYgQ29udGFpbmVyRGVmID0geworICAiTWVzc2FnZU9uZW9mcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClHZXRCeU5hbWUsCisgIChHZXRCeU51bWJlck1ldGhvZClOVUxMLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClHZXRJdGVtSW5kZXgsCit9OworCit9ICAvLyBuYW1lc3BhY2Ugb25lb2ZzCisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlT25lb2ZzQnlOYW1lKFBhcmVudERlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3TWFwcGluZ0J5TmFtZSgmb25lb2ZzOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCitQeU9iamVjdCogTmV3TWVzc2FnZU9uZW9mc1NlcShQYXJlbnREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld1NlcXVlbmNlKCZvbmVvZnM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBtZXNzYWdlX2Rlc2NyaXB0b3IKKworbmFtZXNwYWNlIGVudW1fZGVzY3JpcHRvciB7CisKK3R5cGVkZWYgY29uc3QgRW51bURlc2NyaXB0b3IqIFBhcmVudERlc2NyaXB0b3I7CisKK3N0YXRpYyBQYXJlbnREZXNjcmlwdG9yIEdldERlc2NyaXB0b3IoUHlDb250YWluZXIqIHNlbGYpIHsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UGFyZW50RGVzY3JpcHRvcj4oc2VsZi0+ZGVzY3JpcHRvcik7Cit9CisKK25hbWVzcGFjZSBlbnVtdmFsdWVzIHsKKwordHlwZWRlZiBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+dmFsdWVfY291bnQoKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+dmFsdWUoaW5kZXgpOworfQorCitzdGF0aWMgSXRlbURlc2NyaXB0b3IgR2V0QnlOYW1lKFB5Q29udGFpbmVyKiBzZWxmLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPkZpbmRWYWx1ZUJ5TmFtZShuYW1lKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5TnVtYmVyKFB5Q29udGFpbmVyKiBzZWxmLCBpbnQgbnVtYmVyKSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5GaW5kVmFsdWVCeU51bWJlcihudW1iZXIpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5RW51bVZhbHVlRGVzY3JpcHRvcl9OZXcoaXRlbSk7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJpbmcmIEdldEl0ZW1OYW1lKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPm5hbWUoKTsKK30KKworc3RhdGljIGludCBHZXRJdGVtTnVtYmVyKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPm51bWJlcigpOworfQorCitzdGF0aWMgaW50IEdldEl0ZW1JbmRleChJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBpdGVtLT5pbmRleCgpOworfQorCitzdGF0aWMgRGVzY3JpcHRvckNvbnRhaW5lckRlZiBDb250YWluZXJEZWYgPSB7CisgICJFbnVtVmFsdWVzIiwKKyAgKENvdW50TWV0aG9kKUNvdW50LAorICAoR2V0QnlJbmRleE1ldGhvZClHZXRCeUluZGV4LAorICAoR2V0QnlOYW1lTWV0aG9kKUdldEJ5TmFtZSwKKyAgKEdldEJ5TnVtYmVyTWV0aG9kKUdldEJ5TnVtYmVyLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpR2V0SXRlbU51bWJlciwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClHZXRJdGVtSW5kZXgsCit9OworCit9ICAvLyBuYW1lc3BhY2UgZW51bXZhbHVlcworCitQeU9iamVjdCogTmV3RW51bVZhbHVlc0J5TmFtZShQYXJlbnREZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld01hcHBpbmdCeU5hbWUoJmVudW12YWx1ZXM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK1B5T2JqZWN0KiBOZXdFbnVtVmFsdWVzQnlOdW1iZXIoUGFyZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdNYXBwaW5nQnlOdW1iZXIoJmVudW12YWx1ZXM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK1B5T2JqZWN0KiBOZXdFbnVtVmFsdWVzU2VxKFBhcmVudERlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvcjo6TmV3U2VxdWVuY2UoJmVudW12YWx1ZXM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBlbnVtX2Rlc2NyaXB0b3IKKworbmFtZXNwYWNlIG9uZW9mX2Rlc2NyaXB0b3IgeworCit0eXBlZGVmIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogUGFyZW50RGVzY3JpcHRvcjsKKworc3RhdGljIFBhcmVudERlc2NyaXB0b3IgR2V0RGVzY3JpcHRvcihQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQYXJlbnREZXNjcmlwdG9yPihzZWxmLT5kZXNjcmlwdG9yKTsKK30KKworbmFtZXNwYWNlIGZpZWxkcyB7CisKK3R5cGVkZWYgY29uc3QgRmllbGREZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZmllbGRfY291bnQoKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZmllbGQoaW5kZXgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5RmllbGREZXNjcmlwdG9yX05ldyhpdGVtKTsKK30KKworc3RhdGljIGludCBHZXRJdGVtSW5kZXgoSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gaXRlbS0+aW5kZXhfaW5fb25lb2YoKTsKK30KKworc3RhdGljIERlc2NyaXB0b3JDb250YWluZXJEZWYgQ29udGFpbmVyRGVmID0geworICAiT25lb2ZGaWVsZHMiLAorICAoQ291bnRNZXRob2QpQ291bnQsCisgIChHZXRCeUluZGV4TWV0aG9kKUdldEJ5SW5kZXgsCisgIChHZXRCeU5hbWVNZXRob2QpTlVMTCwKKyAgKEdldEJ5TnVtYmVyTWV0aG9kKU5VTEwsCisgIChOZXdPYmplY3RGcm9tSXRlbU1ldGhvZClOZXdPYmplY3RGcm9tSXRlbSwKKyAgKEdldEl0ZW1OYW1lTWV0aG9kKU5VTEwsCisgIChHZXRJdGVtTnVtYmVyTWV0aG9kKU5VTEwsCisgIChHZXRJdGVtSW5kZXhNZXRob2QpR2V0SXRlbUluZGV4LAorfTsKKworfSAgLy8gbmFtZXNwYWNlIGZpZWxkcworCitQeU9iamVjdCogTmV3T25lb2ZGaWVsZHNTZXEoUGFyZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdTZXF1ZW5jZSgmZmllbGRzOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCit9ICAvLyBuYW1lc3BhY2Ugb25lb2ZfZGVzY3JpcHRvcgorCituYW1lc3BhY2UgZmlsZV9kZXNjcmlwdG9yIHsKKwordHlwZWRlZiBjb25zdCBGaWxlRGVzY3JpcHRvciogUGFyZW50RGVzY3JpcHRvcjsKKworc3RhdGljIFBhcmVudERlc2NyaXB0b3IgR2V0RGVzY3JpcHRvcihQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQYXJlbnREZXNjcmlwdG9yPihzZWxmLT5kZXNjcmlwdG9yKTsKK30KKworbmFtZXNwYWNlIG1lc3NhZ2VzIHsKKwordHlwZWRlZiBjb25zdCBEZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+bWVzc2FnZV90eXBlX2NvdW50KCk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU5hbWUoUHlDb250YWluZXIqIHNlbGYsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKG5hbWUpOworfQorCitzdGF0aWMgSXRlbURlc2NyaXB0b3IgR2V0QnlJbmRleChQeUNvbnRhaW5lciogc2VsZiwgaW50IGluZGV4KSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5tZXNzYWdlX3R5cGUoaW5kZXgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5TWVzc2FnZURlc2NyaXB0b3JfTmV3KGl0ZW0pOworfQorCitzdGF0aWMgY29uc3Qgc3RyaW5nJiBHZXRJdGVtTmFtZShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBpdGVtLT5uYW1lKCk7Cit9CisKK3N0YXRpYyBpbnQgR2V0SXRlbUluZGV4KEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPmluZGV4KCk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIkZpbGVNZXNzYWdlcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClHZXRCeU5hbWUsCisgIChHZXRCeU51bWJlck1ldGhvZClOVUxMLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClHZXRJdGVtSW5kZXgsCit9OworCit9ICAvLyBuYW1lc3BhY2UgbWVzc2FnZXMKKworUHlPYmplY3QqIE5ld0ZpbGVNZXNzYWdlVHlwZXNCeU5hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld01hcHBpbmdCeU5hbWUoJm1lc3NhZ2VzOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZW51bXMgeworCit0eXBlZGVmIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZW51bV90eXBlX2NvdW50KCk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU5hbWUoUHlDb250YWluZXIqIHNlbGYsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZEVudW1UeXBlQnlOYW1lKG5hbWUpOworfQorCitzdGF0aWMgSXRlbURlc2NyaXB0b3IgR2V0QnlJbmRleChQeUNvbnRhaW5lciogc2VsZiwgaW50IGluZGV4KSB7CisgIHJldHVybiBHZXREZXNjcmlwdG9yKHNlbGYpLT5lbnVtX3R5cGUoaW5kZXgpOworfQorCitzdGF0aWMgUHlPYmplY3QqIE5ld09iamVjdEZyb21JdGVtKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIFB5RW51bURlc2NyaXB0b3JfTmV3KGl0ZW0pOworfQorCitzdGF0aWMgY29uc3Qgc3RyaW5nJiBHZXRJdGVtTmFtZShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBpdGVtLT5uYW1lKCk7Cit9CisKK3N0YXRpYyBpbnQgR2V0SXRlbUluZGV4KEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPmluZGV4KCk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIkZpbGVFbnVtcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClHZXRCeU5hbWUsCisgIChHZXRCeU51bWJlck1ldGhvZClOVUxMLAorICAoTmV3T2JqZWN0RnJvbUl0ZW1NZXRob2QpTmV3T2JqZWN0RnJvbUl0ZW0sCisgIChHZXRJdGVtTmFtZU1ldGhvZClHZXRJdGVtTmFtZSwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClHZXRJdGVtSW5kZXgsCit9OworCit9ICAvLyBuYW1lc3BhY2UgZW51bXMKKworUHlPYmplY3QqIE5ld0ZpbGVFbnVtVHlwZXNCeU5hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld01hcHBpbmdCeU5hbWUoJmVudW1zOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZXh0ZW5zaW9ucyB7CisKK3R5cGVkZWYgY29uc3QgRmllbGREZXNjcmlwdG9yKiBJdGVtRGVzY3JpcHRvcjsKKworc3RhdGljIGludCBDb3VudChQeUNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZXh0ZW5zaW9uX2NvdW50KCk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeU5hbWUoUHlDb250YWluZXIqIHNlbGYsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+RmluZEV4dGVuc2lvbkJ5TmFtZShuYW1lKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZXh0ZW5zaW9uKGluZGV4KTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBOZXdPYmplY3RGcm9tSXRlbShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBQeUZpZWxkRGVzY3JpcHRvcl9OZXcoaXRlbSk7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJpbmcmIEdldEl0ZW1OYW1lKEl0ZW1EZXNjcmlwdG9yIGl0ZW0pIHsKKyAgcmV0dXJuIGl0ZW0tPm5hbWUoKTsKK30KKworc3RhdGljIGludCBHZXRJdGVtSW5kZXgoSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gaXRlbS0+aW5kZXgoKTsKK30KKworc3RhdGljIERlc2NyaXB0b3JDb250YWluZXJEZWYgQ29udGFpbmVyRGVmID0geworICAiRmlsZUV4dGVuc2lvbnMiLAorICAoQ291bnRNZXRob2QpQ291bnQsCisgIChHZXRCeUluZGV4TWV0aG9kKUdldEJ5SW5kZXgsCisgIChHZXRCeU5hbWVNZXRob2QpR2V0QnlOYW1lLAorICAoR2V0QnlOdW1iZXJNZXRob2QpTlVMTCwKKyAgKE5ld09iamVjdEZyb21JdGVtTWV0aG9kKU5ld09iamVjdEZyb21JdGVtLAorICAoR2V0SXRlbU5hbWVNZXRob2QpR2V0SXRlbU5hbWUsCisgIChHZXRJdGVtTnVtYmVyTWV0aG9kKU5VTEwsCisgIChHZXRJdGVtSW5kZXhNZXRob2QpR2V0SXRlbUluZGV4LAorfTsKKworfSAgLy8gbmFtZXNwYWNlIGV4dGVuc2lvbnMKKworUHlPYmplY3QqIE5ld0ZpbGVFeHRlbnNpb25zQnlOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yOjpOZXdNYXBwaW5nQnlOYW1lKCZleHRlbnNpb25zOjpDb250YWluZXJEZWYsIGRlc2NyaXB0b3IpOworfQorCituYW1lc3BhY2UgZGVwZW5kZW5jaWVzIHsKKwordHlwZWRlZiBjb25zdCBGaWxlRGVzY3JpcHRvciogSXRlbURlc2NyaXB0b3I7CisKK3N0YXRpYyBpbnQgQ291bnQoUHlDb250YWluZXIqIHNlbGYpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPmRlcGVuZGVuY3lfY291bnQoKTsKK30KKworc3RhdGljIEl0ZW1EZXNjcmlwdG9yIEdldEJ5SW5kZXgoUHlDb250YWluZXIqIHNlbGYsIGludCBpbmRleCkgeworICByZXR1cm4gR2V0RGVzY3JpcHRvcihzZWxmKS0+ZGVwZW5kZW5jeShpbmRleCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogTmV3T2JqZWN0RnJvbUl0ZW0oSXRlbURlc2NyaXB0b3IgaXRlbSkgeworICByZXR1cm4gUHlGaWxlRGVzY3JpcHRvcl9OZXcoaXRlbSk7Cit9CisKK3N0YXRpYyBEZXNjcmlwdG9yQ29udGFpbmVyRGVmIENvbnRhaW5lckRlZiA9IHsKKyAgIkZpbGVEZXBlbmRlbmNpZXMiLAorICAoQ291bnRNZXRob2QpQ291bnQsCisgIChHZXRCeUluZGV4TWV0aG9kKUdldEJ5SW5kZXgsCisgIChHZXRCeU5hbWVNZXRob2QpTlVMTCwKKyAgKEdldEJ5TnVtYmVyTWV0aG9kKU5VTEwsCisgIChOZXdPYmplY3RGcm9tSXRlbU1ldGhvZClOZXdPYmplY3RGcm9tSXRlbSwKKyAgKEdldEl0ZW1OYW1lTWV0aG9kKU5VTEwsCisgIChHZXRJdGVtTnVtYmVyTWV0aG9kKU5VTEwsCisgIChHZXRJdGVtSW5kZXhNZXRob2QpTlVMTCwKK307CisKK30gIC8vIG5hbWVzcGFjZSBkZXBlbmRlbmNpZXMKKworUHlPYmplY3QqIE5ld0ZpbGVEZXBlbmRlbmNpZXMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld1NlcXVlbmNlKCZkZXBlbmRlbmNpZXM6OkNvbnRhaW5lckRlZiwgZGVzY3JpcHRvcik7Cit9CisKK25hbWVzcGFjZSBwdWJsaWNfZGVwZW5kZW5jaWVzIHsKKwordHlwZWRlZiBjb25zdCBGaWxlRGVzY3JpcHRvciogSXRlbURlc2NyaXB0b3I7CisKK3N0YXRpYyBpbnQgQ291bnQoUHlDb250YWluZXIqIHNlbGYpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7Cit9CisKK3N0YXRpYyBJdGVtRGVzY3JpcHRvciBHZXRCeUluZGV4KFB5Q29udGFpbmVyKiBzZWxmLCBpbnQgaW5kZXgpIHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3Ioc2VsZiktPnB1YmxpY19kZXBlbmRlbmN5KGluZGV4KTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBOZXdPYmplY3RGcm9tSXRlbShJdGVtRGVzY3JpcHRvciBpdGVtKSB7CisgIHJldHVybiBQeUZpbGVEZXNjcmlwdG9yX05ldyhpdGVtKTsKK30KKworc3RhdGljIERlc2NyaXB0b3JDb250YWluZXJEZWYgQ29udGFpbmVyRGVmID0geworICAiRmlsZVB1YmxpY0RlcGVuZGVuY2llcyIsCisgIChDb3VudE1ldGhvZClDb3VudCwKKyAgKEdldEJ5SW5kZXhNZXRob2QpR2V0QnlJbmRleCwKKyAgKEdldEJ5TmFtZU1ldGhvZClOVUxMLAorICAoR2V0QnlOdW1iZXJNZXRob2QpTlVMTCwKKyAgKE5ld09iamVjdEZyb21JdGVtTWV0aG9kKU5ld09iamVjdEZyb21JdGVtLAorICAoR2V0SXRlbU5hbWVNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1OdW1iZXJNZXRob2QpTlVMTCwKKyAgKEdldEl0ZW1JbmRleE1ldGhvZClOVUxMLAorfTsKKworfSAgLy8gbmFtZXNwYWNlIHB1YmxpY19kZXBlbmRlbmNpZXMKKworUHlPYmplY3QqIE5ld0ZpbGVQdWJsaWNEZXBlbmRlbmNpZXMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3I6Ok5ld1NlcXVlbmNlKCZwdWJsaWNfZGVwZW5kZW5jaWVzOjpDb250YWluZXJEZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGZpbGVfZGVzY3JpcHRvcgorCisKKy8vIFJlZ2lzdGVyIGFsbCBpbXBsZW1lbnRhdGlvbnMKKworYm9vbCBJbml0RGVzY3JpcHRvck1hcHBpbmdUeXBlcygpIHsKKyAgaWYgKFB5VHlwZV9SZWFkeSgmZGVzY3JpcHRvcjo6RGVzY3JpcHRvck1hcHBpbmdfVHlwZSkgPCAwKQorICAgIHJldHVybiBmYWxzZTsKKyAgaWYgKFB5VHlwZV9SZWFkeSgmZGVzY3JpcHRvcjo6RGVzY3JpcHRvclNlcXVlbmNlX1R5cGUpIDwgMCkKKyAgICByZXR1cm4gZmFsc2U7CisgIGlmIChQeVR5cGVfUmVhZHkoJmRlc2NyaXB0b3I6OkNvbnRhaW5lckl0ZXJhdG9yX1R5cGUpIDwgMCkKKyAgICByZXR1cm4gZmFsc2U7CisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHl0aG9uCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9jb250YWluZXJzLmggYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfY29udGFpbmVycy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4MTUzN2QKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfY29udGFpbmVycy5oCkBAIC0wLDAgKzEsOTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBNYXBwaW5ncyBhbmQgU2VxdWVuY2VzIG9mIGRlc2NyaXB0b3JzLgorLy8gVGhleSBpbXBsZW1lbnQgY29udGFpbmVycyBsaWtlIGZpZWxkc19ieV9uYW1lLCBFbnVtRGVzY3JpcHRvci52YWx1ZXMuLi4KKy8vIFNlZSBkZXNjcmlwdG9yX2NvbnRhaW5lcnMuY2MgZm9yIG1vcmUgZGVzY3JpcHRpb24uCisjaW5jbHVkZSA8UHl0aG9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRGVzY3JpcHRvcjsKK2NsYXNzIEZpbGVEZXNjcmlwdG9yOworY2xhc3MgRW51bURlc2NyaXB0b3I7CitjbGFzcyBPbmVvZkRlc2NyaXB0b3I7CisKK25hbWVzcGFjZSBweXRob24geworCisvLyBJbml0aWFsaXplIHRoZSB2YXJpb3VzIHR5cGVzIGFuZCBvYmplY3RzLgorYm9vbCBJbml0RGVzY3JpcHRvck1hcHBpbmdUeXBlcygpOworCisvLyBFYWNoIGZ1bmN0aW9uIGJlbG93IHJldHVybnMgYSBNYXBwaW5nLCBvciBhIFNlcXVlbmNlIG9mIGRlc2NyaXB0b3JzLgorLy8gVGhleSBhbGwgcmV0dXJuIGEgbmV3IHJlZmVyZW5jZS4KKworbmFtZXNwYWNlIG1lc3NhZ2VfZGVzY3JpcHRvciB7CitQeU9iamVjdCogTmV3TWVzc2FnZUZpZWxkc0J5TmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKK1B5T2JqZWN0KiBOZXdNZXNzYWdlRmllbGRzQnlOdW1iZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogTmV3TWVzc2FnZUZpZWxkc1NlcShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworUHlPYmplY3QqIE5ld01lc3NhZ2VOZXN0ZWRUeXBlc1NlcShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKK1B5T2JqZWN0KiBOZXdNZXNzYWdlTmVzdGVkVHlwZXNCeU5hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlRW51bXNCeU5hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogTmV3TWVzc2FnZUVudW1zU2VxKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworUHlPYmplY3QqIE5ld01lc3NhZ2VFbnVtVmFsdWVzQnlOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCitQeU9iamVjdCogTmV3TWVzc2FnZUV4dGVuc2lvbnNCeU5hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogTmV3TWVzc2FnZUV4dGVuc2lvbnNTZXEoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKK1B5T2JqZWN0KiBOZXdNZXNzYWdlT25lb2ZzQnlOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworUHlPYmplY3QqIE5ld01lc3NhZ2VPbmVvZnNTZXEoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7Cit9ICAvLyBuYW1lc3BhY2UgbWVzc2FnZV9kZXNjcmlwdG9yCisKK25hbWVzcGFjZSBlbnVtX2Rlc2NyaXB0b3IgeworUHlPYmplY3QqIE5ld0VudW1WYWx1ZXNCeU5hbWUoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworUHlPYmplY3QqIE5ld0VudW1WYWx1ZXNCeU51bWJlcihjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitQeU9iamVjdCogTmV3RW51bVZhbHVlc1NlcShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcik7Cit9ICAvLyBuYW1lc3BhY2UgZW51bV9kZXNjcmlwdG9yCisKK25hbWVzcGFjZSBvbmVvZl9kZXNjcmlwdG9yIHsKK1B5T2JqZWN0KiBOZXdPbmVvZkZpZWxkc1NlcShjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworfSAgLy8gbmFtZXNwYWNlIG9uZW9mX2Rlc2NyaXB0b3IKKworbmFtZXNwYWNlIGZpbGVfZGVzY3JpcHRvciB7CitQeU9iamVjdCogTmV3RmlsZU1lc3NhZ2VUeXBlc0J5TmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKK1B5T2JqZWN0KiBOZXdGaWxlRW51bVR5cGVzQnlOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworUHlPYmplY3QqIE5ld0ZpbGVFeHRlbnNpb25zQnlOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworUHlPYmplY3QqIE5ld0ZpbGVEZXBlbmRlbmNpZXMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworUHlPYmplY3QqIE5ld0ZpbGVQdWJsaWNEZXBlbmRlbmNpZXMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworfSAgLy8gbmFtZXNwYWNlIGZpbGVfZGVzY3JpcHRvcgorCisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuY2MgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfcG9vbC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzMwNzdiCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuY2MKQEAgLTAsMCArMSwzNzAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBJbXBsZW1lbnRzIHRoZSBEZXNjcmlwdG9yUG9vbCwgd2hpY2ggY29sbGVjdHMgYWxsIGRlc2NyaXB0b3JzLgorCisjaW5jbHVkZSA8UHl0aG9uLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9zY29wZWRfcHlvYmplY3RfcHRyLmg+CisKKyNkZWZpbmUgQyhzdHIpIGNvbnN0X2Nhc3Q8Y2hhcio+KHN0cikKKworI2lmIFBZX01BSk9SX1ZFUlNJT04gPj0gMworICAjZGVmaW5lIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplIFB5VW5pY29kZV9Gcm9tU3RyaW5nQW5kU2l6ZQorICAjaWYgUFlfVkVSU0lPTl9IRVggPCAweDAzMDMwMDAwCisgICAgI2Vycm9yICJQeXRob24gMy4wIC0gMy4yIGFyZSBub3Qgc3VwcG9ydGVkLiIKKyAgI2VuZGlmCisgICNkZWZpbmUgUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG9iLCBjaGFycHAsIHNpemVwKSBcCisgICAgKFB5VW5pY29kZV9DaGVjayhvYik/IFwKKyAgICAgICAoKCooY2hhcnBwKSA9IFB5VW5pY29kZV9Bc1VURjhBbmRTaXplKG9iLCAoc2l6ZXApKSkgPT0gTlVMTD8gLTE6IDApOiBcCisgICAgICAgUHlCeXRlc19Bc1N0cmluZ0FuZFNpemUob2IsIChjaGFycHApLCAoc2l6ZXApKSkKKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworbmFtZXNwYWNlIGNkZXNjcmlwdG9yX3Bvb2wgeworCitQeURlc2NyaXB0b3JQb29sKiBOZXdEZXNjcmlwdG9yUG9vbCgpIHsKKyAgUHlEZXNjcmlwdG9yUG9vbCogY2Rlc2NyaXB0b3JfcG9vbCA9IFB5T2JqZWN0X05ldygKKyAgICAgIFB5RGVzY3JpcHRvclBvb2wsICZQeURlc2NyaXB0b3JQb29sX1R5cGUpOworICBpZiAoY2Rlc2NyaXB0b3JfcG9vbCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICAvLyBCdWlsZCBhIERlc2NyaXB0b3JQb29sIGZvciBtZXNzYWdlcyBvbmx5IGRlY2xhcmVkIGluIFB5dGhvbiBsaWJyYXJpZXMuCisgIC8vIGdlbmVyYXRlZF9wb29sKCkgY29udGFpbnMgYWxsIG1lc3NhZ2VzIGxpbmtlZCBpbiBDKysgbGlicmFyaWVzLCBhbmQgaXMgdXNlZAorICAvLyBhcyB1bmRlcmxheS4KKyAgY2Rlc2NyaXB0b3JfcG9vbC0+cG9vbCA9IG5ldyBEZXNjcmlwdG9yUG9vbChEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSk7CisKKyAgLy8gVE9ETyhhbWF1cnlmYSk6IFJld3JpdGUgdGhlIFN5bWJvbERhdGFiYXNlIGluIEMgc28gdGhhdCBpdCB1c2VzIHRoZSBzYW1lCisgIC8vIHN0b3JhZ2UuCisgIGNkZXNjcmlwdG9yX3Bvb2wtPmNsYXNzZXNfYnlfZGVzY3JpcHRvciA9CisgICAgICBuZXcgUHlEZXNjcmlwdG9yUG9vbDo6Q2xhc3Nlc0J5TWVzc2FnZU1hcCgpOworICBjZGVzY3JpcHRvcl9wb29sLT5pbnRlcm5lZF9kZXNjcmlwdG9ycyA9CisgICAgICBuZXcgaGFzaF9tYXA8Y29uc3Qgdm9pZCosIFB5T2JqZWN0ICo+KCk7CisgIGNkZXNjcmlwdG9yX3Bvb2wtPmRlc2NyaXB0b3Jfb3B0aW9ucyA9CisgICAgICBuZXcgaGFzaF9tYXA8Y29uc3Qgdm9pZCosIFB5T2JqZWN0ICo+KCk7CisKKyAgcmV0dXJuIGNkZXNjcmlwdG9yX3Bvb2w7Cit9CisKK3N0YXRpYyB2b2lkIERlYWxsb2MoUHlEZXNjcmlwdG9yUG9vbCogc2VsZikgeworICB0eXBlZGVmIFB5RGVzY3JpcHRvclBvb2w6OkNsYXNzZXNCeU1lc3NhZ2VNYXA6Oml0ZXJhdG9yIGl0ZXJhdG9yOworICBmb3IgKGl0ZXJhdG9yIGl0ID0gc2VsZi0+Y2xhc3Nlc19ieV9kZXNjcmlwdG9yLT5iZWdpbigpOworICAgICAgIGl0ICE9IHNlbGYtPmNsYXNzZXNfYnlfZGVzY3JpcHRvci0+ZW5kKCk7ICsraXQpIHsKKyAgICBQeV9ERUNSRUYoaXQtPnNlY29uZCk7CisgIH0KKyAgZGVsZXRlIHNlbGYtPmNsYXNzZXNfYnlfZGVzY3JpcHRvcjsKKyAgZGVsZXRlIHNlbGYtPmludGVybmVkX2Rlc2NyaXB0b3JzOyAgLy8gaXRzIHJlZmVyZW5jZXMgd2VyZSBib3Jyb3dlZC4KKyAgZm9yIChoYXNoX21hcDxjb25zdCB2b2lkKiwgUHlPYmplY3QqPjo6aXRlcmF0b3IgaXQgPQorICAgICAgICAgICBzZWxmLT5kZXNjcmlwdG9yX29wdGlvbnMtPmJlZ2luKCk7CisgICAgICAgaXQgIT0gc2VsZi0+ZGVzY3JpcHRvcl9vcHRpb25zLT5lbmQoKTsgKytpdCkgeworICAgIFB5X0RFQ1JFRihpdC0+c2Vjb25kKTsKKyAgfQorICBkZWxldGUgc2VsZi0+ZGVzY3JpcHRvcl9vcHRpb25zOworICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihzZWxmKSk7Cit9CisKK1B5T2JqZWN0KiBGaW5kTWVzc2FnZUJ5TmFtZShQeURlc2NyaXB0b3JQb29sKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIFB5X3NzaXplX3QgbmFtZV9zaXplOworICBjaGFyKiBuYW1lOworICBpZiAoUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKGFyZywgJm5hbWUsICZuYW1lX3NpemUpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV9kZXNjcmlwdG9yID0KKyAgICAgIHNlbGYtPnBvb2wtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZShzdHJpbmcobmFtZSwgbmFtZV9zaXplKSk7CisKKyAgaWYgKG1lc3NhZ2VfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIkNvdWxkbid0IGZpbmQgbWVzc2FnZSAlLjIwMHMiLCBuYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIHJldHVybiBQeU1lc3NhZ2VEZXNjcmlwdG9yX05ldyhtZXNzYWdlX2Rlc2NyaXB0b3IpOworfQorCisvLyBBZGQgYSBtZXNzYWdlIGNsYXNzIHRvIG91ciBkYXRhYmFzZS4KK2NvbnN0IERlc2NyaXB0b3IqIFJlZ2lzdGVyTWVzc2FnZUNsYXNzKAorICAgIFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsIFB5T2JqZWN0ICptZXNzYWdlX2NsYXNzLCBQeU9iamVjdCogZGVzY3JpcHRvcikgeworICBTY29wZWRQeU9iamVjdFB0ciBmdWxsX21lc3NhZ2VfbmFtZSgKKyAgICAgIFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoZGVzY3JpcHRvciwgImZ1bGxfbmFtZSIpKTsKKyAgUHlfc3NpemVfdCBuYW1lX3NpemU7CisgIGNoYXIqIG5hbWU7CisgIGlmIChQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoZnVsbF9tZXNzYWdlX25hbWUsICZuYW1lLCAmbmFtZV9zaXplKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBjb25zdCBEZXNjcmlwdG9yICptZXNzYWdlX2Rlc2NyaXB0b3IgPQorICAgICAgc2VsZi0+cG9vbC0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKHN0cmluZyhuYW1lLCBuYW1lX3NpemUpKTsKKyAgaWYgKCFtZXNzYWdlX2Rlc2NyaXB0b3IpIHsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAiQ291bGQgbm90IGZpbmQgQysrIGRlc2NyaXB0b3IgZm9yICclcyciLAorICAgICAgICAgICAgICAgICBuYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeV9JTkNSRUYobWVzc2FnZV9jbGFzcyk7CisgIHR5cGVkZWYgUHlEZXNjcmlwdG9yUG9vbDo6Q2xhc3Nlc0J5TWVzc2FnZU1hcDo6aXRlcmF0b3IgaXRlcmF0b3I7CisgIHN0ZDo6cGFpcjxpdGVyYXRvciwgYm9vbD4gcmV0ID0gc2VsZi0+Y2xhc3Nlc19ieV9kZXNjcmlwdG9yLT5pbnNlcnQoCisgICAgICBzdGQ6Om1ha2VfcGFpcihtZXNzYWdlX2Rlc2NyaXB0b3IsIG1lc3NhZ2VfY2xhc3MpKTsKKyAgaWYgKCFyZXQuc2Vjb25kKSB7CisgICAgLy8gVXBkYXRlIGNhc2U6IERFQ1JFRiB0aGUgcHJldmlvdXMgdmFsdWUuCisgICAgUHlfREVDUkVGKHJldC5maXJzdC0+c2Vjb25kKTsKKyAgICByZXQuZmlyc3QtPnNlY29uZCA9IG1lc3NhZ2VfY2xhc3M7CisgIH0KKyAgcmV0dXJuIG1lc3NhZ2VfZGVzY3JpcHRvcjsKK30KKworLy8gUmV0cmlldmUgdGhlIG1lc3NhZ2UgY2xhc3MgYWRkZWQgdG8gb3VyIGRhdGFiYXNlLgorUHlPYmplY3QgKkdldE1lc3NhZ2VDbGFzcyhQeURlc2NyaXB0b3JQb29sKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yICptZXNzYWdlX2Rlc2NyaXB0b3IpIHsKKyAgdHlwZWRlZiBQeURlc2NyaXB0b3JQb29sOjpDbGFzc2VzQnlNZXNzYWdlTWFwOjppdGVyYXRvciBpdGVyYXRvcjsKKyAgaXRlcmF0b3IgcmV0ID0gc2VsZi0+Y2xhc3Nlc19ieV9kZXNjcmlwdG9yLT5maW5kKG1lc3NhZ2VfZGVzY3JpcHRvcik7CisgIGlmIChyZXQgPT0gc2VsZi0+Y2xhc3Nlc19ieV9kZXNjcmlwdG9yLT5lbmQoKSkgeworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJObyBtZXNzYWdlIGNsYXNzIHJlZ2lzdGVyZWQgZm9yICclcyciLAorICAgICAgICAgICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLmNfc3RyKCkpOworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXQtPnNlY29uZDsKKyAgfQorfQorCitQeU9iamVjdCogRmluZEZpZWxkQnlOYW1lKFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsIFB5T2JqZWN0KiBhcmcpIHsKKyAgUHlfc3NpemVfdCBuYW1lX3NpemU7CisgIGNoYXIqIG5hbWU7CisgIGlmIChQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoYXJnLCAmbmFtZSwgJm5hbWVfc2l6ZSkgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IgPQorICAgICAgc2VsZi0+cG9vbC0+RmluZEZpZWxkQnlOYW1lKHN0cmluZyhuYW1lLCBuYW1lX3NpemUpKTsKKyAgaWYgKGZpZWxkX2Rlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJDb3VsZG4ndCBmaW5kIGZpZWxkICUuMjAwcyIsCisgICAgICAgICAgICAgICAgIG5hbWUpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgcmV0dXJuIFB5RmllbGREZXNjcmlwdG9yX05ldyhmaWVsZF9kZXNjcmlwdG9yKTsKK30KKworUHlPYmplY3QqIEZpbmRFeHRlbnNpb25CeU5hbWUoUHlEZXNjcmlwdG9yUG9vbCogc2VsZiwgUHlPYmplY3QqIGFyZykgeworICBQeV9zc2l6ZV90IG5hbWVfc2l6ZTsKKyAgY2hhciogbmFtZTsKKyAgaWYgKFB5U3RyaW5nX0FzU3RyaW5nQW5kU2l6ZShhcmcsICZuYW1lLCAmbmFtZV9zaXplKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciA9CisgICAgICBzZWxmLT5wb29sLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKHN0cmluZyhuYW1lLCBuYW1lX3NpemUpKTsKKyAgaWYgKGZpZWxkX2Rlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJDb3VsZG4ndCBmaW5kIGZpZWxkICUuMjAwcyIsIG5hbWUpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgcmV0dXJuIFB5RmllbGREZXNjcmlwdG9yX05ldyhmaWVsZF9kZXNjcmlwdG9yKTsKK30KKworUHlPYmplY3QqIEZpbmRFbnVtVHlwZUJ5TmFtZShQeURlc2NyaXB0b3JQb29sKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIFB5X3NzaXplX3QgbmFtZV9zaXplOworICBjaGFyKiBuYW1lOworICBpZiAoUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKGFyZywgJm5hbWUsICZuYW1lX3NpemUpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fZGVzY3JpcHRvciA9CisgICAgICBzZWxmLT5wb29sLT5GaW5kRW51bVR5cGVCeU5hbWUoc3RyaW5nKG5hbWUsIG5hbWVfc2l6ZSkpOworICBpZiAoZW51bV9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAiQ291bGRuJ3QgZmluZCBlbnVtICUuMjAwcyIsIG5hbWUpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgcmV0dXJuIFB5RW51bURlc2NyaXB0b3JfTmV3KGVudW1fZGVzY3JpcHRvcik7Cit9CisKK1B5T2JqZWN0KiBGaW5kT25lb2ZCeU5hbWUoUHlEZXNjcmlwdG9yUG9vbCogc2VsZiwgUHlPYmplY3QqIGFyZykgeworICBQeV9zc2l6ZV90IG5hbWVfc2l6ZTsKKyAgY2hhciogbmFtZTsKKyAgaWYgKFB5U3RyaW5nX0FzU3RyaW5nQW5kU2l6ZShhcmcsICZuYW1lLCAmbmFtZV9zaXplKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvciA9CisgICAgICBzZWxmLT5wb29sLT5GaW5kT25lb2ZCeU5hbWUoc3RyaW5nKG5hbWUsIG5hbWVfc2l6ZSkpOworICBpZiAob25lb2ZfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIkNvdWxkbid0IGZpbmQgb25lb2YgJS4yMDBzIiwgbmFtZSk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICByZXR1cm4gUHlPbmVvZkRlc2NyaXB0b3JfTmV3KG9uZW9mX2Rlc2NyaXB0b3IpOworfQorCitzdGF0aWMgUHlNZXRob2REZWYgTWV0aG9kc1tdID0geworICB7IEMoIkZpbmRGaWVsZEJ5TmFtZSIpLAorICAgIChQeUNGdW5jdGlvbilGaW5kRmllbGRCeU5hbWUsCisgICAgTUVUSF9PLAorICAgIEMoIlNlYXJjaGVzIGZvciBhIGZpZWxkIGRlc2NyaXB0b3IgYnkgZnVsbCBuYW1lLiIpIH0sCisgIHsgQygiRmluZEV4dGVuc2lvbkJ5TmFtZSIpLAorICAgIChQeUNGdW5jdGlvbilGaW5kRXh0ZW5zaW9uQnlOYW1lLAorICAgIE1FVEhfTywKKyAgICBDKCJTZWFyY2hlcyBmb3IgZXh0ZW5zaW9uIGRlc2NyaXB0b3IgYnkgZnVsbCBuYW1lLiIpIH0sCisgIHtOVUxMfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGNkZXNjcmlwdG9yX3Bvb2wKKworUHlUeXBlT2JqZWN0IFB5RGVzY3JpcHRvclBvb2xfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgQygiZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLiIKKyAgICAiX21lc3NhZ2UuRGVzY3JpcHRvclBvb2wiKSwgICAgICAgIC8vIHRwX25hbWUKKyAgc2l6ZW9mKFB5RGVzY3JpcHRvclBvb2wpLCAgICAgICAgICAgIC8vIHRwX2Jhc2ljc2l6ZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlbXNpemUKKyAgKGRlc3RydWN0b3IpY2Rlc2NyaXB0b3JfcG9vbDo6RGVhbGxvYywgIC8vIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3ByaW50CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9nZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9jb21wYXJlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9yZXByCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19udW1iZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FzX3NlcXVlbmNlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9hc19tYXBwaW5nCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9oYXNoCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9jYWxsCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zdHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9zZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYXNfYnVmZmVyCisgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgICAvLyB0cF9mbGFncworICBDKCJBIERlc2NyaXB0b3IgUG9vbCIpLCAgICAgICAgICAgICAgLy8gdHBfZG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF90cmF2ZXJzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfY2xlYXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX3JpY2hjb21wYXJlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF93ZWFrbGlzdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfaXRlcm5leHQKKyAgY2Rlc2NyaXB0b3JfcG9vbDo6TWV0aG9kcywgICAgICAgICAgIC8vIHRwX21ldGhvZHMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX21lbWJlcnMKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2dldHNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfYmFzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZGljdAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfZGVzY3JfZ2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9kZXNjcl9zZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2RpY3RvZmZzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2luaXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2FsbG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cF9uZXcKKyAgUHlPYmplY3RfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRwX2ZyZWUKK307CisKKy8vIFRoZSBjb2RlIGJlbG93IGxvYWRzIG5ldyBEZXNjcmlwdG9ycyBmcm9tIGEgc2VyaWFsaXplZCBGaWxlRGVzY3JpcHRvclByb3RvLgorCisKKy8vIENvbGxlY3RzIGVycm9ycyB0aGF0IG9jY3VyIGR1cmluZyBwcm90byBmaWxlIGJ1aWxkaW5nIHRvIGFsbG93IHRoZW0gdG8gYmUKKy8vIHByb3BhZ2F0ZWQgaW4gdGhlIHB5dGhvbiBleGNlcHRpb24gaW5zdGVhZCBvZiBvbmx5IGxpdmluZyBpbiBFUlJPUiBsb2dzLgorY2xhc3MgQnVpbGRGaWxlRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIEJ1aWxkRmlsZUVycm9yQ29sbGVjdG9yKCkgOiBlcnJvcl9tZXNzYWdlKCIiKSwgaGFkX2Vycm9ycyhmYWxzZSkge30KKworICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGNvbnN0IHN0cmluZyYgZWxlbWVudF9uYW1lLAorICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsIEVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgLy8gUmVwbGljYXRlcyB0aGUgbG9nZ2luZyBiZWhhdmlvciB0aGF0IGhhcHBlbnMgaW4gdGhlIEMrKyBpbXBsZW1lbnRhdGlvbgorICAgIC8vIHdoZW4gYW4gZXJyb3IgY29sbGVjdG9yIGlzIG5vdCBwYXNzZWQgaW4uCisgICAgaWYgKCFoYWRfZXJyb3JzKSB7CisgICAgICBlcnJvcl9tZXNzYWdlICs9CisgICAgICAgICAgKCJJbnZhbGlkIHByb3RvIGRlc2NyaXB0b3IgZm9yIGZpbGUgXCIiICsgZmlsZW5hbWUgKyAiXCI6XG4iKTsKKyAgICB9CisgICAgLy8gQXMgdGhpcyBvbmx5IGhhcHBlbnMgb24gZmFpbHVyZSBhbmQgd2lsbCByZXN1bHQgaW4gdGhlIHByb2dyYW0gbm90CisgICAgLy8gcnVubmluZyBhdCBhbGwsIG5vIGVmZm9ydCBpcyBtYWRlIHRvIG9wdGltaXplIHRoaXMgc3RyaW5nIG1hbmlwdWxhdGlvbi4KKyAgICBlcnJvcl9tZXNzYWdlICs9ICgiICAiICsgZWxlbWVudF9uYW1lICsgIjogIiArIG1lc3NhZ2UgKyAiXG4iKTsKKyAgfQorCisgIHN0cmluZyBlcnJvcl9tZXNzYWdlOworICBib29sIGhhZF9lcnJvcnM7Cit9OworCitQeU9iamVjdCogUHl0aG9uX0J1aWxkRmlsZShQeU9iamVjdCogaWdub3JlZCwgUHlPYmplY3QqIHNlcmlhbGl6ZWRfcGIpIHsKKyAgY2hhciogbWVzc2FnZV90eXBlOworICBQeV9zc2l6ZV90IG1lc3NhZ2VfbGVuOworCisgIGlmIChQeUJ5dGVzX0FzU3RyaW5nQW5kU2l6ZShzZXJpYWxpemVkX3BiLCAmbWVzc2FnZV90eXBlLCAmbWVzc2FnZV9sZW4pIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBpZiAoIWZpbGVfcHJvdG8uUGFyc2VGcm9tQXJyYXkobWVzc2FnZV90eXBlLCBtZXNzYWdlX2xlbikpIHsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiQ291bGRuJ3QgcGFyc2UgZmlsZSBjb250ZW50ISIpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gSWYgdGhlIGZpbGUgd2FzIGFscmVhZHkgcGFydCBvZiBhIEMrKyBsaWJyYXJ5LCBhbGwgaXRzIGRlc2NyaXB0b3JzIGFyZSBpbgorICAvLyB0aGUgdW5kZXJseWluZyBwb29sLiAgTm8gbmVlZCB0byBkbyBhbnl0aGluZyBlbHNlLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZ2VuZXJhdGVkX2ZpbGUgPQorICAgICAgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPkZpbmRGaWxlQnlOYW1lKGZpbGVfcHJvdG8ubmFtZSgpKTsKKyAgaWYgKGdlbmVyYXRlZF9maWxlICE9IE5VTEwpIHsKKyAgICByZXR1cm4gUHlGaWxlRGVzY3JpcHRvcl9OZXdXaXRoUGIoZ2VuZXJhdGVkX2ZpbGUsIHNlcmlhbGl6ZWRfcGIpOworICB9CisKKyAgQnVpbGRGaWxlRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvciA9CisgICAgICBHZXREZXNjcmlwdG9yUG9vbCgpLT5wb29sLT5CdWlsZEZpbGVDb2xsZWN0aW5nRXJyb3JzKGZpbGVfcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZlcnJvcl9jb2xsZWN0b3IpOworICBpZiAoZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgIkNvdWxkbid0IGJ1aWxkIHByb3RvIGZpbGUgaW50byBkZXNjcmlwdG9yIHBvb2whXG4lcyIsCisgICAgICAgICAgICAgICAgIGVycm9yX2NvbGxlY3Rvci5lcnJvcl9tZXNzYWdlLmNfc3RyKCkpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgcmV0dXJuIFB5RmlsZURlc2NyaXB0b3JfTmV3V2l0aFBiKGRlc2NyaXB0b3IsIHNlcmlhbGl6ZWRfcGIpOworfQorCitzdGF0aWMgUHlEZXNjcmlwdG9yUG9vbCogZ2xvYmFsX2NkZXNjcmlwdG9yX3Bvb2wgPSBOVUxMOworCitib29sIEluaXREZXNjcmlwdG9yUG9vbCgpIHsKKyAgaWYgKFB5VHlwZV9SZWFkeSgmUHlEZXNjcmlwdG9yUG9vbF9UeXBlKSA8IDApCisgICAgcmV0dXJuIGZhbHNlOworCisgIGdsb2JhbF9jZGVzY3JpcHRvcl9wb29sID0gY2Rlc2NyaXB0b3JfcG9vbDo6TmV3RGVzY3JpcHRvclBvb2woKTsKKyAgaWYgKGdsb2JhbF9jZGVzY3JpcHRvcl9wb29sID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworUHlEZXNjcmlwdG9yUG9vbCogR2V0RGVzY3JpcHRvclBvb2woKSB7CisgIHJldHVybiBnbG9iYWxfY2Rlc2NyaXB0b3JfcG9vbDsKK30KKworfSAgLy8gbmFtZXNwYWNlIHB5dGhvbgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfcG9vbC5oIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZTQ5NGI4Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuaApAQCAtMCwwICsxLDE1MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1BZVEhPTl9DUFBfREVTQ1JJUFRPUl9QT09MX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUFlUSE9OX0NQUF9ERVNDUklQVE9SX1BPT0xfSF9fCisKKyNpbmNsdWRlIDxQeXRob24uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHB5dGhvbiB7CisKKy8vIFdyYXBzIG9wZXJhdGlvbnMgdG8gdGhlIGdsb2JhbCBEZXNjcmlwdG9yUG9vbCB3aGljaCBjb250YWlucyBpbmZvcm1hdGlvbgorLy8gYWJvdXQgYWxsIG1lc3NhZ2VzIGFuZCBmaWVsZHMuCisvLworLy8gVGhlcmUgaXMgbm9ybWFsbHkgb25lIHBvb2wgcGVyIHByb2Nlc3MuIFdlIG1ha2UgaXQgYSBQeXRob24gb2JqZWN0IG9ubHkKKy8vIGJlY2F1c2UgaXQgY29udGFpbnMgbWFueSBQeXRob24gcmVmZXJlbmNlcy4KKy8vIFRPRE8oYW1hdXJ5ZmEpOiBTZWUgd2hldGhlciBzdWNoIG9iamVjdHMgY2FuIGFwcGVhciBpbiByZWZlcmVuY2UgY3ljbGVzLCBhbmQKKy8vIGNvbnNpZGVyIGFkZGluZyBzdXBwb3J0IGZvciB0aGUgY3ljbGljIEdDLgorLy8KKy8vICJNZXRob2RzIiB0aGF0IGludGVyYWN0cyB3aXRoIHRoaXMgRGVzY3JpcHRvclBvb2wgYXJlIGluIHRoZSBjZGVzY3JpcHRvcl9wb29sCisvLyBuYW1lc3BhY2UuCit0eXBlZGVmIHN0cnVjdCBQeURlc2NyaXB0b3JQb29sIHsKKyAgUHlPYmplY3RfSEVBRAorCisgIERlc2NyaXB0b3JQb29sKiBwb29sOworCisgIC8vIE1ha2Ugb3VyIG93biBtYXBwaW5nIHRvIHJldHJpZXZlIFB5dGhvbiBjbGFzc2VzIGZyb20gQysrIGRlc2NyaXB0b3JzLgorICAvLworICAvLyBEZXNjcmlwdG9yIHBvaW50ZXJzIHN0b3JlZCBoZXJlIGFyZSBvd25lZCBieSB0aGUgRGVzY3JpcHRvclBvb2wgYWJvdmUuCisgIC8vIFB5dGhvbiByZWZlcmVuY2VzIHRvIGNsYXNzZXMgYXJlIG93bmVkIGJ5IHRoaXMgUHlEZXNjcmlwdG9yUG9vbC4KKyAgdHlwZWRlZiBoYXNoX21hcDxjb25zdCBEZXNjcmlwdG9yKiwgUHlPYmplY3QqPiBDbGFzc2VzQnlNZXNzYWdlTWFwOworICBDbGFzc2VzQnlNZXNzYWdlTWFwKiBjbGFzc2VzX2J5X2Rlc2NyaXB0b3I7CisKKyAgLy8gU3RvcmUgaW50ZXJuZWQgZGVzY3JpcHRvcnMsIHNvIHRoYXQgdGhlIHNhbWUgQysrIGRlc2NyaXB0b3IgeWllbGRzIHRoZSBzYW1lCisgIC8vIFB5dGhvbiBvYmplY3QuIE9iamVjdHMgYXJlIG5vdCBpbW1vcnRhbDogdGhpcyBtYXAgZG9lcyBub3Qgb3duIHRoZQorICAvLyByZWZlcmVuY2VzLCBhbmQgaXRlbXMgYXJlIGRlbGV0ZWQgd2hlbiB0aGUgbGFzdCByZWZlcmVuY2UgdG8gdGhlIG9iamVjdCBpcworICAvLyByZWxlYXNlZC4KKyAgLy8gVGhpcyBpcyBlbm91Z2ggdG8gc3VwcG9ydCB0aGUgImlzIiBvcGVyYXRvciBvbiBsaXZlIG9iamVjdHMuCisgIC8vIEFsbCBkZXNjcmlwdG9ycyBhcmUgc3RvcmVkIGhlcmUuCisgIGhhc2hfbWFwPGNvbnN0IHZvaWQqLCBQeU9iamVjdCo+KiBpbnRlcm5lZF9kZXNjcmlwdG9yczsKKworICAvLyBDYWNoZSB0aGUgb3B0aW9ucyBmb3IgYW55IGtpbmQgb2YgZGVzY3JpcHRvci4KKyAgLy8gRGVzY3JpcHRvciBwb2ludGVycyBhcmUgb3duZWQgYnkgdGhlIERlc2NyaXB0b3JQb29sIGFib3ZlLgorICAvLyBQeXRob24gb2JqZWN0cyBhcmUgb3duZWQgYnkgdGhlIG1hcC4KKyAgaGFzaF9tYXA8Y29uc3Qgdm9pZCosIFB5T2JqZWN0Kj4qIGRlc2NyaXB0b3Jfb3B0aW9uczsKK30gUHlEZXNjcmlwdG9yUG9vbDsKKworCitleHRlcm4gUHlUeXBlT2JqZWN0IFB5RGVzY3JpcHRvclBvb2xfVHlwZTsKKworbmFtZXNwYWNlIGNkZXNjcmlwdG9yX3Bvb2wgeworCisvLyBCdWlsZHMgYSBuZXcgRGVzY3JpcHRvclBvb2wuIE5vcm1hbGx5IGNhbGxlZCBvbmx5IG9uY2UgcGVyIHByb2Nlc3MuCitQeURlc2NyaXB0b3JQb29sKiBOZXdEZXNjcmlwdG9yUG9vbCgpOworCisvLyBMb29rcyB1cCBhIG1lc3NhZ2UgYnkgbmFtZS4KKy8vIFJldHVybnMgYSBtZXNzYWdlIERlc2NyaXB0b3IsIG9yIE5VTEwgaWYgbm90IGZvdW5kLgorY29uc3QgRGVzY3JpcHRvciogRmluZE1lc3NhZ2VUeXBlQnlOYW1lKFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworLy8gUmVnaXN0ZXJzIGEgbmV3IFB5dGhvbiBjbGFzcyBmb3IgdGhlIGdpdmVuIG1lc3NhZ2UgZGVzY3JpcHRvci4KKy8vIFJldHVybnMgdGhlIG1lc3NhZ2UgRGVzY3JpcHRvci4KKy8vIE9uIGVycm9yLCByZXR1cm5zIE5VTEwgd2l0aCBhIFB5dGhvbiBleGNlcHRpb24gc2V0LgorY29uc3QgRGVzY3JpcHRvciogUmVnaXN0ZXJNZXNzYWdlQ2xhc3MoCisgICAgUHlEZXNjcmlwdG9yUG9vbCogc2VsZiwgUHlPYmplY3QqIG1lc3NhZ2VfY2xhc3MsIFB5T2JqZWN0KiBkZXNjcmlwdG9yKTsKKworLy8gUmV0cmlldmVzIHRoZSBQeXRob24gY2xhc3MgcmVnaXN0ZXJlZCB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGRlc2NyaXB0b3IuCisvLworLy8gUmV0dXJucyBhICpib3Jyb3dlZCogcmVmZXJlbmNlIGlmIGZvdW5kLCBvdGhlcndpc2UgcmV0dXJucyBOVUxMIHdpdGggYW4KKy8vIGV4Y2VwdGlvbiBzZXQuCitQeU9iamVjdCogR2V0TWVzc2FnZUNsYXNzKFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfZGVzY3JpcHRvcik7CisKKy8vIExvb2tzIHVwIGEgbWVzc2FnZSBieSBuYW1lLiBSZXR1cm5zIGEgUHlNZXNzYWdlRGVzY3JpcHRvciBjb3JyZXNwb25kaW5nIHRvCisvLyB0aGUgZmllbGQgb24gc3VjY2Vzcywgb3IgTlVMTCBvbiBmYWlsdXJlLgorLy8KKy8vIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlLgorUHlPYmplY3QqIEZpbmRNZXNzYWdlQnlOYW1lKFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsIFB5T2JqZWN0KiBuYW1lKTsKKworLy8gTG9va3MgdXAgYSBmaWVsZCBieSBuYW1lLiBSZXR1cm5zIGEgUHlGaWVsZERlc2NyaXB0b3IgY29ycmVzcG9uZGluZyB0bworLy8gdGhlIGZpZWxkIG9uIHN1Y2Nlc3MsIG9yIE5VTEwgb24gZmFpbHVyZS4KKy8vCisvLyBSZXR1cm5zIGEgbmV3IHJlZmVyZW5jZS4KK1B5T2JqZWN0KiBGaW5kRmllbGRCeU5hbWUoUHlEZXNjcmlwdG9yUG9vbCogc2VsZiwgUHlPYmplY3QqIG5hbWUpOworCisvLyBMb29rcyB1cCBhbiBleHRlbnNpb24gYnkgbmFtZS4gUmV0dXJucyBhIFB5RmllbGREZXNjcmlwdG9yIGNvcnJlc3BvbmRpbmcKKy8vIHRvIHRoZSBmaWVsZCBvbiBzdWNjZXNzLCBvciBOVUxMIG9uIGZhaWx1cmUuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogRmluZEV4dGVuc2lvbkJ5TmFtZShQeURlc2NyaXB0b3JQb29sKiBzZWxmLCBQeU9iamVjdCogYXJnKTsKKworLy8gTG9va3MgdXAgYW4gZW51bSB0eXBlIGJ5IG5hbWUuIFJldHVybnMgYSBQeUVudW1EZXNjcmlwdG9yIGNvcnJlc3BvbmRpbmcKKy8vIHRvIHRoZSBmaWVsZCBvbiBzdWNjZXNzLCBvciBOVUxMIG9uIGZhaWx1cmUuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogRmluZEVudW1UeXBlQnlOYW1lKFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsIFB5T2JqZWN0KiBhcmcpOworCisvLyBMb29rcyB1cCBhIG9uZW9mIGJ5IG5hbWUuIFJldHVybnMgYSBDT25lb2ZEZXNjcmlwdG9yIGNvcnJlc3BvbmRpbmcKKy8vIHRvIHRoZSBvbmVvZiBvbiBzdWNjZXNzLCBvciBOVUxMIG9uIGZhaWx1cmUuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogRmluZE9uZW9mQnlOYW1lKFB5RGVzY3JpcHRvclBvb2wqIHNlbGYsIFB5T2JqZWN0KiBhcmcpOworCit9ICAvLyBuYW1lc3BhY2UgY2Rlc2NyaXB0b3JfcG9vbAorCisvLyBJbXBsZW1lbnQgdGhlIFB5dGhvbiAiX0J1aWxkRmlsZSIgbWV0aG9kLCBpdCB0YWtlcyBhIHNlcmlhbGl6ZWQKKy8vIEZpbGVEZXNjcmlwdG9yUHJvdG8sIGFuZCBhZGRzIGl0IHRvIHRoZSBDKysgRGVzY3JpcHRvclBvb2wuCisvLyBJdCByZXR1cm5zIGEgbmV3IEZpbGVEZXNjcmlwdG9yIG9iamVjdCwgb3IgTlVMTCB3aGVuIGFuIGV4Y2VwdGlvbiBpcyByYWlzZWQuCitQeU9iamVjdCogUHl0aG9uX0J1aWxkRmlsZShQeU9iamVjdCogaWdub3JlZCwgUHlPYmplY3QqIGFyZ3MpOworCisvLyBSZXRyaWV2ZSB0aGUgZ2xvYmFsIGRlc2NyaXB0b3IgcG9vbCBvd25lZCBieSB0aGUgX21lc3NhZ2UgbW9kdWxlLgorUHlEZXNjcmlwdG9yUG9vbCogR2V0RGVzY3JpcHRvclBvb2woKTsKKworLy8gSW5pdGlhbGl6ZSBvYmplY3RzIHVzZWQgYnkgdGhpcyBtb2R1bGUuCitib29sIEluaXREZXNjcmlwdG9yUG9vbCgpOworCit9ICAvLyBuYW1lc3BhY2UgcHl0aG9uCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUFlUSE9OX0NQUF9ERVNDUklQVE9SX1BPT0xfSF9fCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2V4dGVuc2lvbl9kaWN0LmNjIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9leHRlbnNpb25fZGljdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTM4ZmM0Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9leHRlbnNpb25fZGljdC5jYwpAQCAtMCwwICsxLDMwOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYW51cmFhZ0Bnb29nbGUuY29tIChBbnVyYWFnIEFncmF3YWwpCisvLyBBdXRob3I6IHRpYmVsbEBnb29nbGUuY29tIChKb2hhbiBUaWJlbGwpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZXh0ZW5zaW9uX2RpY3QuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfcG9vbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9zY29wZWRfcHlvYmplY3RfcHRyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHB5dGhvbiB7CisKK25hbWVzcGFjZSBleHRlbnNpb25fZGljdCB7CisKKy8vIFRPRE8odGliZWxsKTogQWx3YXlzIHVzZSBzZWxmLT5tZXNzYWdlIGZvciBjbGFyaXR5LCBqdXN0IGxpa2UgaW4KKy8vIFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyLgorc3RhdGljIE1lc3NhZ2UqIEdldE1lc3NhZ2UoRXh0ZW5zaW9uRGljdCogc2VsZikgeworICBpZiAoc2VsZi0+cGFyZW50ICE9IE5VTEwpIHsKKyAgICByZXR1cm4gc2VsZi0+cGFyZW50LT5tZXNzYWdlOworICB9IGVsc2UgeworICAgIHJldHVybiBzZWxmLT5tZXNzYWdlOworICB9Cit9CisKK1B5T2JqZWN0KiBsZW4oRXh0ZW5zaW9uRGljdCogc2VsZikgeworI2lmIFBZX01BSk9SX1ZFUlNJT04gPj0gMworICByZXR1cm4gUHlMb25nX0Zyb21Mb25nKFB5RGljdF9TaXplKHNlbGYtPnZhbHVlcykpOworI2Vsc2UKKyAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKFB5RGljdF9TaXplKHNlbGYtPnZhbHVlcykpOworI2VuZGlmCit9CisKKy8vIFRPRE8odGliZWxsKTogVXNlIFZpc2l0Q29tcG9zaXRlRmllbGQuCitpbnQgUmVsZWFzZUV4dGVuc2lvbihFeHRlbnNpb25EaWN0KiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGV4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBpZiAoZGVzY3JpcHRvci0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChyZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyOjpSZWxlYXNlKAorICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKj4oCisgICAgICAgICAgICAgICAgICBleHRlbnNpb24pKSA8IDApIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAocmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lcjo6UmVsZWFzZSgKKyAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFNjYWxhckNvbnRhaW5lcio+KAorICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uKSkgPCAwKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICB9CisgIH0gZWxzZSBpZiAoZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIGlmIChjbWVzc2FnZTo6UmVsZWFzZVN1Yk1lc3NhZ2UoCisgICAgICAgICAgICBHZXRNZXNzYWdlKHNlbGYpLCBkZXNjcmlwdG9yLAorICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KGV4dGVuc2lvbikpIDwgMCkgeworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgfQorCisgIHJldHVybiAwOworfQorCitQeU9iamVjdCogc3Vic2NyaXB0KEV4dGVuc2lvbkRpY3QqIHNlbGYsIFB5T2JqZWN0KiBrZXkpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gY21lc3NhZ2U6OkdldEV4dGVuc2lvbkRlc2NyaXB0b3Ioa2V5KTsKKyAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmICghQ2hlY2tGaWVsZEJlbG9uZ3NUb01lc3NhZ2UoZGVzY3JpcHRvciwgc2VsZi0+cGFyZW50LT5tZXNzYWdlKSkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3ItPmxhYmVsKCkgIT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCAmJgorICAgICAgZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIHJldHVybiBjbWVzc2FnZTo6SW50ZXJuYWxHZXRTY2FsYXIoc2VsZi0+cGFyZW50LCBkZXNjcmlwdG9yKTsKKyAgfQorCisgIFB5T2JqZWN0KiB2YWx1ZSA9IFB5RGljdF9HZXRJdGVtKHNlbGYtPnZhbHVlcywga2V5KTsKKyAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICBQeV9JTkNSRUYodmFsdWUpOworICAgIHJldHVybiB2YWx1ZTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yLT5sYWJlbCgpICE9IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQgJiYKKyAgICAgIGRlc2NyaXB0b3ItPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICBQeU9iamVjdCogc3ViX21lc3NhZ2UgPSBjbWVzc2FnZTo6SW50ZXJuYWxHZXRTdWJNZXNzYWdlKAorICAgICAgICBzZWxmLT5wYXJlbnQsIGRlc2NyaXB0b3IpOworICAgIGlmIChzdWJfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlEaWN0X1NldEl0ZW0oc2VsZi0+dmFsdWVzLCBrZXksIHN1Yl9tZXNzYWdlKTsKKyAgICByZXR1cm4gc3ViX21lc3NhZ2U7CisgIH0KKworICBpZiAoZGVzY3JpcHRvci0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIFB5T2JqZWN0ICptZXNzYWdlX2NsYXNzID0gY2Rlc2NyaXB0b3JfcG9vbDo6R2V0TWVzc2FnZUNsYXNzKAorICAgICAgICAgIEdldERlc2NyaXB0b3JQb29sKCksIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICAgIGlmIChtZXNzYWdlX2NsYXNzID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgICBQeU9iamVjdCogcHlfY29udGFpbmVyID0gcmVwZWF0ZWRfY29tcG9zaXRlX2NvbnRhaW5lcjo6TmV3Q29udGFpbmVyKAorICAgICAgICAgIHNlbGYtPnBhcmVudCwgZGVzY3JpcHRvciwgbWVzc2FnZV9jbGFzcyk7CisgICAgICBpZiAocHlfY29udGFpbmVyID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgICBQeURpY3RfU2V0SXRlbShzZWxmLT52YWx1ZXMsIGtleSwgcHlfY29udGFpbmVyKTsKKyAgICAgIHJldHVybiBweV9jb250YWluZXI7CisgICAgfSBlbHNlIHsKKyAgICAgIFB5T2JqZWN0KiBweV9jb250YWluZXIgPSByZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyOjpOZXdDb250YWluZXIoCisgICAgICAgICAgc2VsZi0+cGFyZW50LCBkZXNjcmlwdG9yKTsKKyAgICAgIGlmIChweV9jb250YWluZXIgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICAgIFB5RGljdF9TZXRJdGVtKHNlbGYtPnZhbHVlcywga2V5LCBweV9jb250YWluZXIpOworICAgICAgcmV0dXJuIHB5X2NvbnRhaW5lcjsKKyAgICB9CisgIH0KKyAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJjb250cm9sIHJlYWNoZWQgdW5leHBlY3RlZCBsaW5lIik7CisgIHJldHVybiBOVUxMOworfQorCitpbnQgYXNzX3N1YnNjcmlwdChFeHRlbnNpb25EaWN0KiBzZWxmLCBQeU9iamVjdCoga2V5LCBQeU9iamVjdCogdmFsdWUpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gY21lc3NhZ2U6OkdldEV4dGVuc2lvbkRlc2NyaXB0b3Ioa2V5KTsKKyAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIHJldHVybiAtMTsKKyAgfQorICBpZiAoIUNoZWNrRmllbGRCZWxvbmdzVG9NZXNzYWdlKGRlc2NyaXB0b3IsIHNlbGYtPnBhcmVudC0+bWVzc2FnZSkpIHsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICBpZiAoZGVzY3JpcHRvci0+bGFiZWwoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMIHx8CisgICAgICBkZXNjcmlwdG9yLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIkV4dGVuc2lvbiBpcyByZXBlYXRlZCBhbmQvb3IgY29tcG9zaXRlICIKKyAgICAgICAgICAgICAgICAgICAgInR5cGUiKTsKKyAgICByZXR1cm4gLTE7CisgIH0KKyAgY21lc3NhZ2U6OkFzc3VyZVdyaXRhYmxlKHNlbGYtPnBhcmVudCk7CisgIGlmIChjbWVzc2FnZTo6SW50ZXJuYWxTZXRTY2FsYXIoc2VsZi0+cGFyZW50LCBkZXNjcmlwdG9yLCB2YWx1ZSkgPCAwKSB7CisgICAgcmV0dXJuIC0xOworICB9CisgIC8vIFRPRE8odGliZWxsKTogV2Ugc2hvdWxkbid0IHdyaXRlIHNjYWxhcnMgdG8gdGhlIGNhY2hlLgorICBQeURpY3RfU2V0SXRlbShzZWxmLT52YWx1ZXMsIGtleSwgdmFsdWUpOworICByZXR1cm4gMDsKK30KKworUHlPYmplY3QqIENsZWFyRXh0ZW5zaW9uKEV4dGVuc2lvbkRpY3QqIHNlbGYsIFB5T2JqZWN0KiBleHRlbnNpb24pIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0KKyAgICAgIGNtZXNzYWdlOjpHZXRFeHRlbnNpb25EZXNjcmlwdG9yKGV4dGVuc2lvbik7CisgIGlmIChkZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeU9iamVjdCogdmFsdWUgPSBQeURpY3RfR2V0SXRlbShzZWxmLT52YWx1ZXMsIGV4dGVuc2lvbik7CisgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgaWYgKFJlbGVhc2VFeHRlbnNpb24oc2VsZiwgdmFsdWUsIGRlc2NyaXB0b3IpIDwgMCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisgIGlmIChjbWVzc2FnZTo6Q2xlYXJGaWVsZEJ5RGVzY3JpcHRvcihzZWxmLT5wYXJlbnQsIGRlc2NyaXB0b3IpID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoUHlEaWN0X0RlbEl0ZW0oc2VsZi0+dmFsdWVzLCBleHRlbnNpb24pIDwgMCkgeworICAgIFB5RXJyX0NsZWFyKCk7CisgIH0KKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKK1B5T2JqZWN0KiBIYXNFeHRlbnNpb24oRXh0ZW5zaW9uRGljdCogc2VsZiwgUHlPYmplY3QqIGV4dGVuc2lvbikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPQorICAgICAgY21lc3NhZ2U6OkdldEV4dGVuc2lvbkRlc2NyaXB0b3IoZXh0ZW5zaW9uKTsKKyAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5T2JqZWN0KiByZXN1bHQgPSBjbWVzc2FnZTo6SGFzRmllbGRCeURlc2NyaXB0b3Ioc2VsZi0+cGFyZW50LCBkZXNjcmlwdG9yKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworUHlPYmplY3QqIF9GaW5kRXh0ZW5zaW9uQnlOYW1lKEV4dGVuc2lvbkRpY3QqIHNlbGYsIFB5T2JqZWN0KiBuYW1lKSB7CisgIFNjb3BlZFB5T2JqZWN0UHRyIGV4dGVuc2lvbnNfYnlfbmFtZShQeU9iamVjdF9HZXRBdHRyU3RyaW5nKAorICAgICAgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYtPnBhcmVudCksICJfZXh0ZW5zaW9uc19ieV9uYW1lIikpOworICBpZiAoZXh0ZW5zaW9uc19ieV9uYW1lID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeU9iamVjdCogcmVzdWx0ID0gUHlEaWN0X0dldEl0ZW0oZXh0ZW5zaW9uc19ieV9uYW1lLCBuYW1lKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgUHlfUkVUVVJOX05PTkU7CisgIH0gZWxzZSB7CisgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCitFeHRlbnNpb25EaWN0KiBOZXdFeHRlbnNpb25EaWN0KENNZXNzYWdlICpwYXJlbnQpIHsKKyAgRXh0ZW5zaW9uRGljdCogc2VsZiA9IHJlaW50ZXJwcmV0X2Nhc3Q8RXh0ZW5zaW9uRGljdCo+KAorICAgICAgUHlUeXBlX0dlbmVyaWNBbGxvYygmRXh0ZW5zaW9uRGljdF9UeXBlLCAwKSk7CisgIGlmIChzZWxmID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIHNlbGYtPnBhcmVudCA9IHBhcmVudDsgIC8vIFN0b3JlIGEgYm9ycm93ZWQgcmVmZXJlbmNlLgorICBzZWxmLT5tZXNzYWdlID0gcGFyZW50LT5tZXNzYWdlOworICBzZWxmLT5vd25lciA9IHBhcmVudC0+b3duZXI7CisgIHNlbGYtPnZhbHVlcyA9IFB5RGljdF9OZXcoKTsKKyAgcmV0dXJuIHNlbGY7Cit9CisKK3ZvaWQgZGVhbGxvYyhFeHRlbnNpb25EaWN0KiBzZWxmKSB7CisgIFB5X0NMRUFSKHNlbGYtPnZhbHVlcyk7CisgIHNlbGYtPm93bmVyLnJlc2V0KCk7CisgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUocmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYpKTsKK30KKworc3RhdGljIFB5TWFwcGluZ01ldGhvZHMgTXBNZXRob2RzID0geworICAobGVuZnVuYylsZW4sICAgICAgICAgICAgICAgLyogbXBfbGVuZ3RoICovCisgIChiaW5hcnlmdW5jKXN1YnNjcmlwdCwgICAgICAvKiBtcF9zdWJzY3JpcHQgKi8KKyAgKG9iam9iamFyZ3Byb2MpYXNzX3N1YnNjcmlwdCwvKiBtcF9hc3Nfc3Vic2NyaXB0ICovCit9OworCisjZGVmaW5lIEVETUVUSE9EKG5hbWUsIGFyZ3MsIGRvYykgeyAjbmFtZSwgKFB5Q0Z1bmN0aW9uKW5hbWUsIGFyZ3MsIGRvYyB9CitzdGF0aWMgUHlNZXRob2REZWYgTWV0aG9kc1tdID0geworICBFRE1FVEhPRChDbGVhckV4dGVuc2lvbiwgTUVUSF9PLCAiQ2xlYXJzIGFuIGV4dGVuc2lvbiBmcm9tIHRoZSBvYmplY3QuIiksCisgIEVETUVUSE9EKEhhc0V4dGVuc2lvbiwgTUVUSF9PLCAiQ2hlY2tzIGlmIHRoZSBvYmplY3QgaGFzIGFuIGV4dGVuc2lvbi4iKSwKKyAgRURNRVRIT0QoX0ZpbmRFeHRlbnNpb25CeU5hbWUsIE1FVEhfTywKKyAgICAgICAgICAgIkZpbmRzIGFuIGV4dGVuc2lvbiBieSBuYW1lLiIpLAorICB7IE5VTEwsIE5VTEwgfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGV4dGVuc2lvbl9kaWN0CisKK1B5VHlwZU9iamVjdCBFeHRlbnNpb25EaWN0X1R5cGUgPSB7CisgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICJnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuIgorICAiY3BwLl9tZXNzYWdlLkV4dGVuc2lvbkRpY3QiLCAgICAgICAgLy8gdHBfbmFtZQorICBzaXplb2YoRXh0ZW5zaW9uRGljdCksICAgICAgICAgICAgICAgLy8gdHBfYmFzaWNzaXplCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfaXRlbXNpemUKKyAgKGRlc3RydWN0b3IpZXh0ZW5zaW9uX2RpY3Q6OmRlYWxsb2MsICAvLyAgdHBfZGVhbGxvYworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX3ByaW50CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZ2V0YXR0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX3NldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jb21wYXJlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfcmVwcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2FzX251bWJlcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2FzX3NlcXVlbmNlCisgICZleHRlbnNpb25fZGljdDo6TXBNZXRob2RzLCAgICAgICAgICAvLyAgdHBfYXNfbWFwcGluZworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2hhc2gKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jYWxsCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfc3RyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZ2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9zZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2FzX2J1ZmZlcgorICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAgLy8gIHRwX2ZsYWdzCisgICJBbiBleHRlbnNpb24gZGljdCIsICAgICAgICAgICAgICAgICAvLyAgdHBfZG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfdHJhdmVyc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jbGVhcgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX3JpY2hjb21wYXJlCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfd2Vha2xpc3RvZmZzZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9pdGVyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfaXRlcm5leHQKKyAgZXh0ZW5zaW9uX2RpY3Q6Ok1ldGhvZHMsICAgICAgICAgICAgIC8vICB0cF9tZXRob2RzCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfbWVtYmVycworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2dldHNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2Jhc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9kaWN0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGVzY3JfZ2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGVzY3Jfc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGljdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2luaXQKK307CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9leHRlbnNpb25fZGljdC5oIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9leHRlbnNpb25fZGljdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlMTA0OWYKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2V4dGVuc2lvbl9kaWN0LmgKQEAgLTAsMCArMSwxMzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGFudXJhYWdAZ29vZ2xlLmNvbSAoQW51cmFhZyBBZ3Jhd2FsKQorLy8gQXV0aG9yOiB0aWJlbGxAZ29vZ2xlLmNvbSAoSm9oYW4gVGliZWxsKQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX0VYVEVOU0lPTl9ESUNUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUFlUSE9OX0NQUF9FWFRFTlNJT05fRElDVF9IX18KKworI2luY2x1ZGUgPFB5dGhvbi5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIE1lc3NhZ2U7CitjbGFzcyBGaWVsZERlc2NyaXB0b3I7CisKK3VzaW5nIGludGVybmFsOjpzaGFyZWRfcHRyOworCituYW1lc3BhY2UgcHl0aG9uIHsKKworc3RydWN0IENNZXNzYWdlOworCit0eXBlZGVmIHN0cnVjdCBFeHRlbnNpb25EaWN0IHsKKyAgUHlPYmplY3RfSEVBRDsKKworICAvLyBUaGlzIGlzIHRoZSB0b3AtbGV2ZWwgQysrIE1lc3NhZ2Ugb2JqZWN0IHRoYXQgb3ducyB0aGUgd2hvbGUKKyAgLy8gcHJvdG8gdHJlZS4gIEV2ZXJ5IFB5dGhvbiBjb250YWluZXIgY2xhc3MgaG9sZHMgYQorICAvLyByZWZlcmVuY2UgdG8gaXQgaW4gb3JkZXIgdG8ga2VlcCBpdCBhbGl2ZSBhcyBsb25nIGFzIHRoZXJlJ3MgYQorICAvLyBQeXRob24gb2JqZWN0IHRoYXQgcmVmZXJlbmNlcyBhbnkgcGFydCBvZiB0aGUgdHJlZS4KKyAgc2hhcmVkX3B0cjxNZXNzYWdlPiBvd25lcjsKKworICAvLyBXZWFrIHJlZmVyZW5jZSB0byBwYXJlbnQgbWVzc2FnZS4gVXNlZCB0byBtYWtlIHN1cmUKKyAgLy8gdGhlIHBhcmVudCBpcyB3cml0YWJsZSB3aGVuIGFuIGV4dGVuc2lvbiBmaWVsZCBpcyBtb2RpZmllZC4KKyAgQ01lc3NhZ2UqIHBhcmVudDsKKworICAvLyBQb2ludGVyIHRvIHRoZSBDKysgTWVzc2FnZSB0aGF0IHRoaXMgRXh0ZW5zaW9uRGljdCBleHRlbmRzLgorICAvLyBOb3Qgb3duZWQgYnkgdXMuCisgIE1lc3NhZ2UqIG1lc3NhZ2U7CisKKyAgLy8gQSBkaWN0IG9mIGNoaWxkIG1lc3NhZ2VzLCBpbmRleGVkIGJ5IEV4dGVuc2lvbiBkZXNjcmlwdG9ycy4KKyAgLy8gU2ltaWxhciB0byBDTWVzc2FnZTo6Y29tcG9zaXRlX2ZpZWxkcy4KKyAgUHlPYmplY3QqIHZhbHVlczsKK30gRXh0ZW5zaW9uRGljdDsKKworZXh0ZXJuIFB5VHlwZU9iamVjdCBFeHRlbnNpb25EaWN0X1R5cGU7CisKK25hbWVzcGFjZSBleHRlbnNpb25fZGljdCB7CisKKy8vIEJ1aWxkcyBhbiBFeHRlbnNpb25zIGRpY3QgZm9yIGEgc3BlY2lmaWMgbWVzc2FnZS4KK0V4dGVuc2lvbkRpY3QqIE5ld0V4dGVuc2lvbkRpY3QoQ01lc3NhZ2UgKnBhcmVudCk7CisKKy8vIEdldHMgdGhlIG51bWJlciBvZiBleHRlbnNpb24gdmFsdWVzIGluIHRoaXMgRXh0ZW5zaW9uRGljdCBhcyBhIHB5dGhvbiBvYmplY3QuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogbGVuKEV4dGVuc2lvbkRpY3QqIHNlbGYpOworCisvLyBSZWxlYXNlcyBleHRlbnNpb25zIHJlZmVyZW5jZWQgb3V0c2lkZSB0aGlzIGRpY3Rpb25hcnkgdG8ga2VlcCBvdXRzaWRlCisvLyByZWZlcmVuY2VzIGFsaXZlLgorLy8KKy8vIFJldHVybnMgMCBvbiBzdWNjZXNzLCAtMSBvbiBmYWlsdXJlLgoraW50IFJlbGVhc2VFeHRlbnNpb24oRXh0ZW5zaW9uRGljdCogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBleHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBHZXRzIGFuIGV4dGVuc2lvbiBmcm9tIHRoZSBkaWN0IGZvciB0aGUgZ2l2ZW4gZXh0ZW5zaW9uIGRlc2NyaXB0b3IuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogc3Vic2NyaXB0KEV4dGVuc2lvbkRpY3QqIHNlbGYsIFB5T2JqZWN0KiBrZXkpOworCisvLyBBc3NpZ25zIGEgdmFsdWUgdG8gYW4gZXh0ZW5zaW9uIGluIHRoZSBkaWN0LiBDYW4gb25seSBiZSB1c2VkIGZvciBzaW5ndWxhcgorLy8gc2ltcGxlIHR5cGVzLgorLy8KKy8vIFJldHVybnMgMCBvbiBzdWNjZXNzLCAtMSBvbiBmYWlsdXJlLgoraW50IGFzc19zdWJzY3JpcHQoRXh0ZW5zaW9uRGljdCogc2VsZiwgUHlPYmplY3QqIGtleSwgUHlPYmplY3QqIHZhbHVlKTsKKworLy8gQ2xlYXJzIGFuIGV4dGVuc2lvbiBmcm9tIHRoZSBkaWN0LiBXaWxsIHJlbGVhc2UgdGhlIGV4dGVuc2lvbiBpZiB0aGVyZQorLy8gaXMgc3RpbGwgYW4gZXh0ZXJuYWwgcmVmZXJlbmNlIGxlZnQgdG8gaXQuCisvLworLy8gUmV0dXJucyBOb25lIG9uIHN1Y2Nlc3MuCitQeU9iamVjdCogQ2xlYXJFeHRlbnNpb24oRXh0ZW5zaW9uRGljdCogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBleHRlbnNpb24pOworCisvLyBDaGVja3MgaWYgdGhlIGRpY3QgaGFzIGFuIGV4dGVuc2lvbi4KKy8vCisvLyBSZXR1cm5zIGEgbmV3IHB5dGhvbiBib29sZWFuIHJlZmVyZW5jZS4KK1B5T2JqZWN0KiBIYXNFeHRlbnNpb24oRXh0ZW5zaW9uRGljdCogc2VsZiwgUHlPYmplY3QqIGV4dGVuc2lvbik7CisKKy8vIEdldHMgYW4gZXh0ZW5zaW9uIGZyb20gdGhlIGRpY3QgZ2l2ZW4gdGhlIGV4dGVuc2lvbiBuYW1lIGFzIG9wcG9zZWQgdG8KKy8vIGRlc2NyaXB0b3IuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogX0ZpbmRFeHRlbnNpb25CeU5hbWUoRXh0ZW5zaW9uRGljdCogc2VsZiwgUHlPYmplY3QqIG5hbWUpOworCit9ICAvLyBuYW1lc3BhY2UgZXh0ZW5zaW9uX2RpY3QKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX0VYVEVOU0lPTl9ESUNUX0hfXwpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9tZXNzYWdlLmNjIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9tZXNzYWdlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyYjM1N2IKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L21lc3NhZ2UuY2MKQEAgLTAsMCArMSwyNTc1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBhbnVyYWFnQGdvb2dsZS5jb20gKEFudXJhYWcgQWdyYXdhbCkKKy8vIEF1dGhvcjogdGliZWxsQGdvb2dsZS5jb20gKEpvaGFuIFRpYmVsbCkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9tZXNzYWdlLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxzdHJ1Y3RtZW1iZXIuaD4gIC8vIEEgUHl0aG9uIGhlYWRlciBmaWxlLgorCisjaWZuZGVmIFB5VmFyT2JqZWN0X0hFQURfSU5JVAorI2RlZmluZSBQeVZhck9iamVjdF9IRUFEX0lOSVQodHlwZSwgc2l6ZSkgUHlPYmplY3RfSEVBRF9JTklUKHR5cGUpIHNpemUsCisjZW5kaWYKKyNpZm5kZWYgUHlfVFlQRQorI2RlZmluZSBQeV9UWVBFKG9iKSAoKChQeU9iamVjdCopKG9iKSktPm9iX3R5cGUpCisjZW5kaWYKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yX3Bvb2wuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvZXh0ZW5zaW9uX2RpY3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfY29tcG9zaXRlX2NvbnRhaW5lci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3Njb3BlZF9weW9iamVjdF9wdHIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCisjaWYgUFlfTUFKT1JfVkVSU0lPTiA+PSAzCisgICNkZWZpbmUgUHlJbnRfQ2hlY2sgUHlMb25nX0NoZWNrCisgICNkZWZpbmUgUHlJbnRfQXNMb25nIFB5TG9uZ19Bc0xvbmcKKyAgI2RlZmluZSBQeUludF9Gcm9tTG9uZyBQeUxvbmdfRnJvbUxvbmcKKyAgI2RlZmluZSBQeUludF9Gcm9tU2l6ZV90IFB5TG9uZ19Gcm9tU2l6ZV90CisgICNkZWZpbmUgUHlTdHJpbmdfQ2hlY2sgUHlVbmljb2RlX0NoZWNrCisgICNkZWZpbmUgUHlTdHJpbmdfRnJvbVN0cmluZyBQeVVuaWNvZGVfRnJvbVN0cmluZworICAjZGVmaW5lIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplIFB5VW5pY29kZV9Gcm9tU3RyaW5nQW5kU2l6ZQorICAjaWYgUFlfVkVSU0lPTl9IRVggPCAweDAzMDMwMDAwCisgICAgI2Vycm9yICJQeXRob24gMy4wIC0gMy4yIGFyZSBub3Qgc3VwcG9ydGVkLiIKKyAgI2Vsc2UKKyAgI2RlZmluZSBQeVN0cmluZ19Bc1N0cmluZyhvYikgXAorICAgIChQeVVuaWNvZGVfQ2hlY2sob2IpPyBQeVVuaWNvZGVfQXNVVEY4KG9iKTogUHlCeXRlc19Bc1N0cmluZyhvYikpCisgICNkZWZpbmUgUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG9iLCBjaGFycHAsIHNpemVwKSBcCisgICAgKFB5VW5pY29kZV9DaGVjayhvYik/IFwKKyAgICAgICAoKCooY2hhcnBwKSA9IFB5VW5pY29kZV9Bc1VURjhBbmRTaXplKG9iLCAoc2l6ZXApKSkgPT0gTlVMTD8gLTE6IDApOiBcCisgICAgICAgUHlCeXRlc19Bc1N0cmluZ0FuZFNpemUob2IsIChjaGFycHApLCAoc2l6ZXApKSkKKyAgI2VuZGlmCisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHB5dGhvbiB7CisKKy8vIEZvcndhcmQgZGVjbGFyYXRpb25zCituYW1lc3BhY2UgY21lc3NhZ2Ugeworc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogR2V0RmllbGREZXNjcmlwdG9yKAorICAgIENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogbmFtZSk7CitzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZURlc2NyaXB0b3IoUHlUeXBlT2JqZWN0KiBjbHMpOworc3RhdGljIHN0cmluZyBHZXRNZXNzYWdlTmFtZShDTWVzc2FnZSogc2VsZik7CitpbnQgSW50ZXJuYWxSZWxlYXNlRmllbGRCeURlc2NyaXB0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yLAorICAgIFB5T2JqZWN0KiBjb21wb3NpdGVfZmllbGQsCisgICAgTWVzc2FnZSogcGFyZW50X21lc3NhZ2UpOworfSAgLy8gbmFtZXNwYWNlIGNtZXNzYWdlCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVmlzaXRpbmcgdGhlIGNvbXBvc2l0ZSBjaGlsZHJlbiBvZiBhIENNZXNzYWdlCisKK3N0cnVjdCBDaGlsZFZpc2l0b3IgeworICAvLyBSZXR1cm5zIDAgb24gc3VjY2VzcywgLTEgb24gZmFpbHVyZS4KKyAgaW50IFZpc2l0UmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIGNvbnRhaW5lcikgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8gUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGZhaWx1cmUuCisgIGludCBWaXNpdFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBjb250YWluZXIpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vIFJldHVybnMgMCBvbiBzdWNjZXNzLCAtMSBvbiBmYWlsdXJlLgorICBpbnQgVmlzaXRDTWVzc2FnZShDTWVzc2FnZSogY21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvcikgeworICAgIHJldHVybiAwOworICB9Cit9OworCisvLyBBcHBseSBhIGZ1bmN0aW9uIHRvIGEgY29tcG9zaXRlIGZpZWxkLiAgRG9lcyBub3RoaW5nIGlmIGNoaWxkIGlzIG9mCisvLyBub24tY29tcG9zaXRlIHR5cGUuCit0ZW1wbGF0ZTxjbGFzcyBWaXNpdG9yPgorc3RhdGljIGludCBWaXNpdENvbXBvc2l0ZUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogY2hpbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmlzaXRvciB2aXNpdG9yKSB7CisgIGlmIChkZXNjcmlwdG9yLT5sYWJlbCgpID09IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQpIHsKKyAgICBpZiAoZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIGNvbnRhaW5lciA9CisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqPihjaGlsZCk7CisgICAgICBpZiAodmlzaXRvci5WaXNpdFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKGNvbnRhaW5lcikgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICB9IGVsc2UgeworICAgICAgUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIGNvbnRhaW5lciA9CisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRTY2FsYXJDb250YWluZXIqPihjaGlsZCk7CisgICAgICBpZiAodmlzaXRvci5WaXNpdFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKGNvbnRhaW5lcikgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0gZWxzZSBpZiAoZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIENNZXNzYWdlKiBjbXNnID0gcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KGNoaWxkKTsKKyAgICBpZiAodmlzaXRvci5WaXNpdENNZXNzYWdlKGNtc2csIGRlc2NyaXB0b3IpID09IC0xKQorICAgICAgcmV0dXJuIC0xOworICB9CisgIC8vIFRoZSBFeHRlbnNpb25EaWN0IG1pZ2h0IGNvbnRhaW4gbm9uLWNvbXBvc2l0ZSBmaWVsZHMsIHdoaWNoIHdlCisgIC8vIHNraXAgaGVyZS4KKyAgcmV0dXJuIDA7Cit9CisKKy8vIFZpc2l0IGVhY2ggY29tcG9zaXRlIGZpZWxkIGFuZCBleHRlbnNpb24gZmllbGQgb2YgdGhpcyBDTWVzc2FnZS4KKy8vIFJldHVybnMgLTEgb24gZXJyb3IgYW5kIDAgb24gc3VjY2Vzcy4KK3RlbXBsYXRlPGNsYXNzIFZpc2l0b3I+CitpbnQgRm9yRWFjaENvbXBvc2l0ZUZpZWxkKENNZXNzYWdlKiBzZWxmLCBWaXNpdG9yIHZpc2l0b3IpIHsKKyAgUHlfc3NpemVfdCBwb3MgPSAwOworICBQeU9iamVjdCoga2V5OworICBQeU9iamVjdCogZmllbGQ7CisKKyAgLy8gVmlzaXQgbm9ybWFsIGZpZWxkcy4KKyAgaWYgKHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMpIHsKKyAgICAvLyBOZXZlciB1c2Ugc2VsZi0+bWVzc2FnZSBpbiB0aGlzIGZ1bmN0aW9uLCBpdCBtYXkgYmUgYWxyZWFkeSBmcmVlZC4KKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX2Rlc2NyaXB0b3IgPQorICAgICAgICBjbWVzc2FnZTo6R2V0TWVzc2FnZURlc2NyaXB0b3IoUHlfVFlQRShzZWxmKSk7CisgICAgd2hpbGUgKFB5RGljdF9OZXh0KHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMsICZwb3MsICZrZXksICZmaWVsZCkpIHsKKyAgICAgIFB5X3NzaXplX3Qga2V5X3N0cl9zaXplOworICAgICAgY2hhciAqa2V5X3N0cl9kYXRhOworICAgICAgaWYgKFB5U3RyaW5nX0FzU3RyaW5nQW5kU2l6ZShrZXksICZrZXlfc3RyX2RhdGEsICZrZXlfc3RyX3NpemUpICE9IDApCisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIGNvbnN0IHN0cmluZyBrZXlfc3RyKGtleV9zdHJfZGF0YSwga2V5X3N0cl9zaXplKTsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9CisgICAgICAgIG1lc3NhZ2VfZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKGtleV9zdHIpOworICAgICAgaWYgKGRlc2NyaXB0b3IgIT0gTlVMTCkgeworICAgICAgICBpZiAoVmlzaXRDb21wb3NpdGVGaWVsZChkZXNjcmlwdG9yLCBmaWVsZCwgdmlzaXRvcikgPT0gLTEpCisgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFZpc2l0IGV4dGVuc2lvbiBmaWVsZHMuCisgIGlmIChzZWxmLT5leHRlbnNpb25zICE9IE5VTEwpIHsKKyAgICBwb3MgPSAwOworICAgIHdoaWxlIChQeURpY3RfTmV4dChzZWxmLT5leHRlbnNpb25zLT52YWx1ZXMsICZwb3MsICZrZXksICZmaWVsZCkpIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IGNtZXNzYWdlOjpHZXRFeHRlbnNpb25EZXNjcmlwdG9yKGtleSk7CisgICAgICBpZiAoZGVzY3JpcHRvciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgICBpZiAoVmlzaXRDb21wb3NpdGVGaWVsZChkZXNjcmlwdG9yLCBmaWVsZCwgdmlzaXRvcikgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0KKworICByZXR1cm4gMDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBEeW5hbWljTWVzc2FnZUZhY3RvcnkqIG1lc3NhZ2VfZmFjdG9yeTsKKworLy8gQ29uc3RhbnRzIHVzZWQgZm9yIGludGVnZXIgdHlwZSByYW5nZSBjaGVja2luZy4KK1B5T2JqZWN0KiBrUHl0aG9uWmVybzsKK1B5T2JqZWN0KiBraW50MzJtaW5fcHk7CitQeU9iamVjdCoga2ludDMybWF4X3B5OworUHlPYmplY3QqIGt1aW50MzJtYXhfcHk7CitQeU9iamVjdCoga2ludDY0bWluX3B5OworUHlPYmplY3QqIGtpbnQ2NG1heF9weTsKK1B5T2JqZWN0KiBrdWludDY0bWF4X3B5OworCitQeU9iamVjdCogRW51bVR5cGVXcmFwcGVyX2NsYXNzOworUHlPYmplY3QqIEVuY29kZUVycm9yX2NsYXNzOworUHlPYmplY3QqIERlY29kZUVycm9yX2NsYXNzOworUHlPYmplY3QqIFBpY2tsZUVycm9yX2NsYXNzOworCisvLyBDb25zdGFudCBQeVN0cmluZyB2YWx1ZXMgdXNlZCBmb3IgR2V0QXR0ci9HZXRJdGVtLgorc3RhdGljIFB5T2JqZWN0KiBrREVTQ1JJUFRPUjsKK3N0YXRpYyBQeU9iamVjdCoga19jZGVzY3JpcHRvcjsKK3N0YXRpYyBQeU9iamVjdCoga2Z1bGxfbmFtZTsKK3N0YXRpYyBQeU9iamVjdCoga19leHRlbnNpb25zX2J5X25hbWU7CitzdGF0aWMgUHlPYmplY3QqIGtfZXh0ZW5zaW9uc19ieV9udW1iZXI7CisKKy8qIElzIDY0Yml0ICovCit2b2lkIEZvcm1hdFR5cGVFcnJvcihQeU9iamVjdCogYXJnLCBjaGFyKiBleHBlY3RlZF90eXBlcykgeworICBQeU9iamVjdCogcmVwciA9IFB5T2JqZWN0X1JlcHIoYXJnKTsKKyAgaWYgKHJlcHIpIHsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAiJS4xMDBzIGhhcyB0eXBlICUuMTAwcywgYnV0IGV4cGVjdGVkIG9uZSBvZjogJXMiLAorICAgICAgICAgICAgICAgICBQeVN0cmluZ19Bc1N0cmluZyhyZXByKSwKKyAgICAgICAgICAgICAgICAgUHlfVFlQRShhcmcpLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICBleHBlY3RlZF90eXBlcyk7CisgICAgUHlfREVDUkVGKHJlcHIpOworICB9Cit9CisKK3RlbXBsYXRlPGNsYXNzIFQ+Citib29sIENoZWNrQW5kR2V0SW50ZWdlcigKKyAgICBQeU9iamVjdCogYXJnLCBUKiB2YWx1ZSwgUHlPYmplY3QqIG1pbiwgUHlPYmplY3QqIG1heCkgeworICBib29sIGlzX2xvbmcgPSBQeUxvbmdfQ2hlY2soYXJnKTsKKyNpZiBQWV9NQUpPUl9WRVJTSU9OIDwgMworICBpZiAoIVB5SW50X0NoZWNrKGFyZykgJiYgIWlzX2xvbmcpIHsKKyAgICBGb3JtYXRUeXBlRXJyb3IoYXJnLCAiaW50LCBsb25nIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChQeU9iamVjdF9Db21wYXJlKG1pbiwgYXJnKSA+IDAgfHwgUHlPYmplY3RfQ29tcGFyZShtYXgsIGFyZykgPCAwKSB7CisjZWxzZQorICBpZiAoIWlzX2xvbmcpIHsKKyAgICBGb3JtYXRUeXBlRXJyb3IoYXJnLCAiaW50Iik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2wobWluLCBhcmcsIFB5X0xFKSAhPSAxIHx8CisgICAgICBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2wobWF4LCBhcmcsIFB5X0dFKSAhPSAxKSB7CisjZW5kaWYKKyAgICBQeU9iamVjdCAqcyA9IFB5T2JqZWN0X1N0cihhcmcpOworICAgIGlmIChzKSB7CisgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAiVmFsdWUgb3V0IG9mIHJhbmdlOiAlcyIsCisgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcocykpOworICAgICAgUHlfREVDUkVGKHMpOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyNpZiBQWV9NQUpPUl9WRVJTSU9OIDwgMworICBpZiAoIWlzX2xvbmcpIHsKKyAgICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxUPihQeUludF9Bc0xvbmcoYXJnKSk7CisgIH0gZWxzZSAgLy8gTk9MSU5UCisjZW5kaWYKKyAgeworICAgIGlmIChtaW4gPT0ga1B5dGhvblplcm8pIHsKKyAgICAgICp2YWx1ZSA9IHN0YXRpY19jYXN0PFQ+KFB5TG9uZ19Bc1Vuc2lnbmVkTG9uZ0xvbmcoYXJnKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICp2YWx1ZSA9IHN0YXRpY19jYXN0PFQ+KFB5TG9uZ19Bc0xvbmdMb25nKGFyZykpOworICAgIH0KKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworLy8gVGhlc2UgYXJlIHJlZmVyZW5jZWQgYnkgcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lciwgYW5kIG11c3QKKy8vIGJlIGV4cGxpY2l0bHkgaW5zdGFudGlhdGVkLgordGVtcGxhdGUgYm9vbCBDaGVja0FuZEdldEludGVnZXI8aW50MzI+KAorICAgIFB5T2JqZWN0KiwgaW50MzIqLCBQeU9iamVjdCosIFB5T2JqZWN0Kik7Cit0ZW1wbGF0ZSBib29sIENoZWNrQW5kR2V0SW50ZWdlcjxpbnQ2ND4oCisgICAgUHlPYmplY3QqLCBpbnQ2NCosIFB5T2JqZWN0KiwgUHlPYmplY3QqKTsKK3RlbXBsYXRlIGJvb2wgQ2hlY2tBbmRHZXRJbnRlZ2VyPHVpbnQzMj4oCisgICAgUHlPYmplY3QqLCB1aW50MzIqLCBQeU9iamVjdCosIFB5T2JqZWN0Kik7Cit0ZW1wbGF0ZSBib29sIENoZWNrQW5kR2V0SW50ZWdlcjx1aW50NjQ+KAorICAgIFB5T2JqZWN0KiwgdWludDY0KiwgUHlPYmplY3QqLCBQeU9iamVjdCopOworCitib29sIENoZWNrQW5kR2V0RG91YmxlKFB5T2JqZWN0KiBhcmcsIGRvdWJsZSogdmFsdWUpIHsKKyAgaWYgKCFQeUludF9DaGVjayhhcmcpICYmICFQeUxvbmdfQ2hlY2soYXJnKSAmJgorICAgICAgIVB5RmxvYXRfQ2hlY2soYXJnKSkgeworICAgIEZvcm1hdFR5cGVFcnJvcihhcmcsICJpbnQsIGxvbmcsIGZsb2F0Iik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgICp2YWx1ZSA9IFB5RmxvYXRfQXNEb3VibGUoYXJnKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQ2hlY2tBbmRHZXRGbG9hdChQeU9iamVjdCogYXJnLCBmbG9hdCogdmFsdWUpIHsKKyAgZG91YmxlIGRvdWJsZV92YWx1ZTsKKyAgaWYgKCFDaGVja0FuZEdldERvdWJsZShhcmcsICZkb3VibGVfdmFsdWUpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PGZsb2F0Pihkb3VibGVfdmFsdWUpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDaGVja0FuZEdldEJvb2woUHlPYmplY3QqIGFyZywgYm9vbCogdmFsdWUpIHsKKyAgaWYgKCFQeUludF9DaGVjayhhcmcpICYmICFQeUJvb2xfQ2hlY2soYXJnKSAmJiAhUHlMb25nX0NoZWNrKGFyZykpIHsKKyAgICBGb3JtYXRUeXBlRXJyb3IoYXJnLCAiaW50LCBsb25nLCBib29sIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PGJvb2w+KFB5SW50X0FzTG9uZyhhcmcpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQ2hlY2tBbmRTZXRTdHJpbmcoCisgICAgUHlPYmplY3QqIGFyZywgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICBib29sIGFwcGVuZCwKKyAgICBpbnQgaW5kZXgpIHsKKyAgR09PR0xFX0RDSEVDSyhkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyB8fAorICAgICAgICAgZGVzY3JpcHRvci0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyk7CisgIGlmIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIGlmICghUHlCeXRlc19DaGVjayhhcmcpICYmICFQeVVuaWNvZGVfQ2hlY2soYXJnKSkgeworICAgICAgRm9ybWF0VHlwZUVycm9yKGFyZywgImJ5dGVzLCB1bmljb2RlIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKFB5Qnl0ZXNfQ2hlY2soYXJnKSkgeworICAgICAgUHlPYmplY3QqIHVuaWNvZGUgPSBQeVVuaWNvZGVfRnJvbUVuY29kZWRPYmplY3QoYXJnLCAidXRmLTgiLCBOVUxMKTsKKyAgICAgIGlmICh1bmljb2RlID09IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QqIHJlcHIgPSBQeU9iamVjdF9SZXByKGFyZyk7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiVzIGhhcyB0eXBlIHN0ciwgYnV0IGlzbid0IHZhbGlkIFVURi04ICIKKyAgICAgICAgICAgICAgICAgICAgICJlbmNvZGluZy4gTm9uLVVURi04IHN0cmluZ3MgbXVzdCBiZSBjb252ZXJ0ZWQgdG8gIgorICAgICAgICAgICAgICAgICAgICAgInVuaWNvZGUgb2JqZWN0cyBiZWZvcmUgYmVpbmcgYWRkZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FzU3RyaW5nKHJlcHIpKTsKKyAgICAgICAgUHlfREVDUkVGKHJlcHIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBQeV9ERUNSRUYodW5pY29kZSk7CisgICAgICB9CisgICAgfQorICB9IGVsc2UgaWYgKCFQeUJ5dGVzX0NoZWNrKGFyZykpIHsKKyAgICBGb3JtYXRUeXBlRXJyb3IoYXJnLCAiYnl0ZXMiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBQeU9iamVjdCogZW5jb2RlZF9zdHJpbmcgPSBOVUxMOworICBpZiAoZGVzY3JpcHRvci0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICBpZiAoUHlCeXRlc19DaGVjayhhcmcpKSB7CisgICAgICAvLyBUaGUgYnl0ZXMgd2VyZSBhbHJlYWR5IHZhbGlkYXRlZCBhcyBjb3JyZWN0bHkgZW5jb2RlZCBVVEYtOCBhYm92ZS4KKyAgICAgIGVuY29kZWRfc3RyaW5nID0gYXJnOyAgLy8gQWxyZWFkeSBlbmNvZGVkLgorICAgICAgUHlfSU5DUkVGKGVuY29kZWRfc3RyaW5nKTsKKyAgICB9IGVsc2UgeworICAgICAgZW5jb2RlZF9zdHJpbmcgPSBQeVVuaWNvZGVfQXNFbmNvZGVkT2JqZWN0KGFyZywgInV0Zi04IiwgTlVMTCk7CisgICAgfQorICB9IGVsc2UgeworICAgIC8vIEluIHRoaXMgY2FzZSBmaWVsZCB0eXBlIGlzICJieXRlcyIuCisgICAgZW5jb2RlZF9zdHJpbmcgPSBhcmc7CisgICAgUHlfSU5DUkVGKGVuY29kZWRfc3RyaW5nKTsKKyAgfQorCisgIGlmIChlbmNvZGVkX3N0cmluZyA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgY2hhciogdmFsdWU7CisgIFB5X3NzaXplX3QgdmFsdWVfbGVuOworICBpZiAoUHlCeXRlc19Bc1N0cmluZ0FuZFNpemUoZW5jb2RlZF9zdHJpbmcsICZ2YWx1ZSwgJnZhbHVlX2xlbikgPCAwKSB7CisgICAgUHlfREVDUkVGKGVuY29kZWRfc3RyaW5nKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBzdHJpbmcgdmFsdWVfc3RyaW5nKHZhbHVlLCB2YWx1ZV9sZW4pOworICBpZiAoYXBwZW5kKSB7CisgICAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIGRlc2NyaXB0b3IsIHZhbHVlX3N0cmluZyk7CisgIH0gZWxzZSBpZiAoaW5kZXggPCAwKSB7CisgICAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIGRlc2NyaXB0b3IsIHZhbHVlX3N0cmluZyk7CisgIH0gZWxzZSB7CisgICAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRTdHJpbmcobWVzc2FnZSwgZGVzY3JpcHRvciwgaW5kZXgsIHZhbHVlX3N0cmluZyk7CisgIH0KKyAgUHlfREVDUkVGKGVuY29kZWRfc3RyaW5nKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK1B5T2JqZWN0KiBUb1N0cmluZ09iamVjdChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIHN0cmluZyB2YWx1ZSkgeworICBpZiAoZGVzY3JpcHRvci0+dHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICByZXR1cm4gUHlCeXRlc19Gcm9tU3RyaW5nQW5kU2l6ZSh2YWx1ZS5jX3N0cigpLCB2YWx1ZS5sZW5ndGgoKSk7CisgIH0KKworICBQeU9iamVjdCogcmVzdWx0ID0gUHlVbmljb2RlX0RlY29kZVVURjgodmFsdWUuY19zdHIoKSwgdmFsdWUubGVuZ3RoKCksIE5VTEwpOworICAvLyBJZiB0aGUgc3RyaW5nIGNhbid0IGJlIGRlY29kZWQgaW4gVVRGLTgsIGp1c3QgcmV0dXJuIGEgc3RyaW5nIG9iamVjdCB0aGF0CisgIC8vIGNvbnRhaW5zIHRoZSByYXcgYnl0ZXMuIFRoaXMgY2FuJ3QgaGFwcGVuIGlmIHRoZSB2YWx1ZSB3YXMgYXNzaWduZWQgdXNpbmcKKyAgLy8gdGhlIG1lbWJlcnMgb2YgdGhlIFB5dGhvbiBtZXNzYWdlIG9iamVjdCwgYnV0IGNhbiBoYXBwZW4gaWYgdGhlIHZhbHVlcyB3ZXJlCisgIC8vIHBhcnNlZCBmcm9tIHRoZSB3aXJlIChiaW5hcnkpLgorICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICBQeUVycl9DbGVhcigpOworICAgIHJlc3VsdCA9IFB5Qnl0ZXNfRnJvbVN0cmluZ0FuZFNpemUodmFsdWUuY19zdHIoKSwgdmFsdWUubGVuZ3RoKCkpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2Jvb2wgQ2hlY2tGaWVsZEJlbG9uZ3NUb01lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGlmIChtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCkgPT0gZmllbGRfZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICBQeUVycl9Gb3JtYXQoUHlFeGNfS2V5RXJyb3IsICJGaWVsZCAnJXMnIGRvZXMgbm90IGJlbG9uZyB0byBtZXNzYWdlICclcyciLAorICAgICAgICAgICAgICAgZmllbGRfZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkuY19zdHIoKSwKKyAgICAgICAgICAgICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkuY19zdHIoKSk7CisgIHJldHVybiBmYWxzZTsKK30KKworbmFtZXNwYWNlIGNtZXNzYWdlIHsKKworRHluYW1pY01lc3NhZ2VGYWN0b3J5KiBHZXRNZXNzYWdlRmFjdG9yeSgpIHsKKyAgcmV0dXJuIG1lc3NhZ2VfZmFjdG9yeTsKK30KKworc3RhdGljIGludCBNYXliZVJlbGVhc2VPdmVybGFwcGluZ09uZW9mRmllbGQoCisgICAgQ01lc3NhZ2UqIGNtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfSEFTX09ORU9GCisgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBjbWVzc2FnZS0+bWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgaWYgKCFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpIHx8CisgICAgICAhcmVmbGVjdGlvbi0+SGFzT25lb2YoKm1lc3NhZ2UsIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHx8CisgICAgICByZWZsZWN0aW9uLT5IYXNGaWVsZCgqbWVzc2FnZSwgZmllbGQpKSB7CisgICAgLy8gTm8gb3RoZXIgZmllbGQgaW4gdGhpcyBvbmVvZiwgbm8gbmVlZCB0byByZWxlYXNlLgorICAgIHJldHVybiAwOworICB9CisKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXhpc3RpbmdfZmllbGQgPQorICAgICAgcmVmbGVjdGlvbi0+R2V0T25lb2ZGaWVsZERlc2NyaXB0b3IoKm1lc3NhZ2UsIG9uZW9mKTsKKyAgaWYgKGV4aXN0aW5nX2ZpZWxkLT5jcHBfdHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgLy8gTm9uLW1lc3NhZ2UgZmllbGRzIGRvbid0IG5lZWQgdG8gYmUgcmVsZWFzZWQuCisgICAgcmV0dXJuIDA7CisgIH0KKyAgY29uc3QgY2hhciogZmllbGRfbmFtZSA9IGV4aXN0aW5nX2ZpZWxkLT5uYW1lKCkuY19zdHIoKTsKKyAgUHlPYmplY3QqIGNoaWxkX21lc3NhZ2UgPSBjbWVzc2FnZS0+Y29tcG9zaXRlX2ZpZWxkcyA/CisgICAgICBQeURpY3RfR2V0SXRlbVN0cmluZyhjbWVzc2FnZS0+Y29tcG9zaXRlX2ZpZWxkcywgZmllbGRfbmFtZSkgOiBOVUxMOworICBpZiAoY2hpbGRfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgLy8gTm8gcHl0aG9uIHJlZmVyZW5jZSB0byB0aGlzIGZpZWxkIHNvIG5vIG5lZWQgdG8gcmVsZWFzZS4KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmIChJbnRlcm5hbFJlbGVhc2VGaWVsZEJ5RGVzY3JpcHRvcigKKyAgICAgICAgICBleGlzdGluZ19maWVsZCwgY2hpbGRfbWVzc2FnZSwgbWVzc2FnZSkgPCAwKSB7CisgICAgcmV0dXJuIC0xOworICB9CisgIHJldHVybiBQeURpY3RfRGVsSXRlbVN0cmluZyhjbWVzc2FnZS0+Y29tcG9zaXRlX2ZpZWxkcywgZmllbGRfbmFtZSk7CisjZWxzZQorICByZXR1cm4gMDsKKyNlbmRpZgorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1ha2luZyBhIG1lc3NhZ2Ugd3JpdGFibGUKKworc3RhdGljIE1lc3NhZ2UqIEdldE11dGFibGVNZXNzYWdlKAorICAgIENNZXNzYWdlKiBwYXJlbnQsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBwYXJlbnRfZmllbGQpIHsKKyAgTWVzc2FnZSogcGFyZW50X21lc3NhZ2UgPSBwYXJlbnQtPm1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBwYXJlbnRfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBpZiAoTWF5YmVSZWxlYXNlT3ZlcmxhcHBpbmdPbmVvZkZpZWxkKHBhcmVudCwgcGFyZW50X2ZpZWxkKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICByZXR1cm4gcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICBwYXJlbnRfbWVzc2FnZSwgcGFyZW50X2ZpZWxkLCBtZXNzYWdlX2ZhY3RvcnkpOworfQorCitzdHJ1Y3QgRml4dXBNZXNzYWdlUmVmZXJlbmNlIDogcHVibGljIENoaWxkVmlzaXRvciB7CisgIC8vIG1lc3NhZ2UgbXVzdCBvdXRsaXZlIHRoaXMgb2JqZWN0LgorICBleHBsaWNpdCBGaXh1cE1lc3NhZ2VSZWZlcmVuY2UoTWVzc2FnZSogbWVzc2FnZSkgOgorICAgICAgbWVzc2FnZV8obWVzc2FnZSkge30KKworICBpbnQgVmlzaXRSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lcihSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogY29udGFpbmVyKSB7CisgICAgY29udGFpbmVyLT5tZXNzYWdlID0gbWVzc2FnZV87CisgICAgcmV0dXJuIDA7CisgIH0KKworICBpbnQgVmlzaXRSZXBlYXRlZFNjYWxhckNvbnRhaW5lcihSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogY29udGFpbmVyKSB7CisgICAgY29udGFpbmVyLT5tZXNzYWdlID0gbWVzc2FnZV87CisgICAgcmV0dXJuIDA7CisgIH0KKworIHByaXZhdGU6CisgIE1lc3NhZ2UqIG1lc3NhZ2VfOworfTsKKworaW50IEFzc3VyZVdyaXRhYmxlKENNZXNzYWdlKiBzZWxmKSB7CisgIGlmIChzZWxmID09IE5VTEwgfHwgIXNlbGYtPnJlYWRfb25seSkgeworICAgIHJldHVybiAwOworICB9CisKKyAgaWYgKHNlbGYtPnBhcmVudCA9PSBOVUxMKSB7CisgICAgLy8gSWYgcGFyZW50IGlzIE5VTEwgYnV0IHdlIGFyZSB0cnlpbmcgdG8gbW9kaWZ5IGEgcmVhZC1vbmx5IG1lc3NhZ2UsIHRoaXMKKyAgICAvLyBpcyBhIHJlZmVyZW5jZSB0byBhIGNvbnN0YW50IGRlZmF1bHQgaW5zdGFuY2UgdGhhdCBuZWVkcyB0byBiZSByZXBsYWNlZAorICAgIC8vIHdpdGggYSBtdXRhYmxlIHRvcC1sZXZlbCBtZXNzYWdlLgorICAgIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZSA9IG1lc3NhZ2VfZmFjdG9yeS0+R2V0UHJvdG90eXBlKAorICAgICAgICBzZWxmLT5tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCkpOworICAgIHNlbGYtPm1lc3NhZ2UgPSBwcm90b3R5cGUtPk5ldygpOworICAgIHNlbGYtPm93bmVyLnJlc2V0KHNlbGYtPm1lc3NhZ2UpOworICB9IGVsc2UgeworICAgIC8vIE90aGVyd2lzZSwgd2UgbmVlZCBhIG11dGFibGUgY2hpbGQgbWVzc2FnZS4KKyAgICBpZiAoQXNzdXJlV3JpdGFibGUoc2VsZi0+cGFyZW50KSA9PSAtMSkKKyAgICAgIHJldHVybiAtMTsKKworICAgIC8vIE1ha2Ugc2VsZi0+bWVzc2FnZSB3cml0YWJsZS4KKyAgICBNZXNzYWdlKiBwYXJlbnRfbWVzc2FnZSA9IHNlbGYtPnBhcmVudC0+bWVzc2FnZTsKKyAgICBNZXNzYWdlKiBtdXRhYmxlX21lc3NhZ2UgPSBHZXRNdXRhYmxlTWVzc2FnZSgKKyAgICAgICAgc2VsZi0+cGFyZW50LAorICAgICAgICBzZWxmLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvcik7CisgICAgaWYgKG11dGFibGVfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHNlbGYtPm1lc3NhZ2UgPSBtdXRhYmxlX21lc3NhZ2U7CisgIH0KKyAgc2VsZi0+cmVhZF9vbmx5ID0gZmFsc2U7CisKKyAgLy8gV2hlbiBhIENNZXNzYWdlIGlzIG1hZGUgd3JpdGFibGUgaXRzIE1lc3NhZ2UgcG9pbnRlciBpcyB1cGRhdGVkCisgIC8vIHRvIHBvaW50IHRvIGEgbmV3IG11dGFibGUgTWVzc2FnZS4gIFdoZW4gdGhhdCBoYXBwZW5zIHdlIG5lZWQgdG8KKyAgLy8gdXBkYXRlIGFueSByZWZlcmVuY2VzIHRvIHRoZSBvbGQsIHJlYWQtb25seSBDTWVzc2FnZS4gIFRoZXJlIGFyZQorICAvLyB0aHJlZSBwbGFjZXMgc3VjaCByZWZlcmVuY2VzIG9jY3VyOiBSZXBlYXRlZFNjYWxhckNvbnRhaW5lciwKKyAgLy8gUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIsIGFuZCBFeHRlbnNpb25EaWN0LgorICBpZiAoc2VsZi0+ZXh0ZW5zaW9ucyAhPSBOVUxMKQorICAgIHNlbGYtPmV4dGVuc2lvbnMtPm1lc3NhZ2UgPSBzZWxmLT5tZXNzYWdlOworICBpZiAoRm9yRWFjaENvbXBvc2l0ZUZpZWxkKHNlbGYsIEZpeHVwTWVzc2FnZVJlZmVyZW5jZShzZWxmLT5tZXNzYWdlKSkgPT0gLTEpCisgICAgcmV0dXJuIC0xOworCisgIHJldHVybiAwOworfQorCisvLyAtLS0gR2xvYmFsczoKKworLy8gUmV0cmlldmUgdGhlIEMrKyBEZXNjcmlwdG9yIG9mIGEgbWVzc2FnZSBjbGFzcy4KKy8vIE9uIGVycm9yLCByZXR1cm5zIE5VTEwgd2l0aCBhbiBleGNlcHRpb24gc2V0Lgorc3RhdGljIGNvbnN0IERlc2NyaXB0b3IqIEdldE1lc3NhZ2VEZXNjcmlwdG9yKFB5VHlwZU9iamVjdCogY2xzKSB7CisgIFNjb3BlZFB5T2JqZWN0UHRyIGRlc2NyaXB0b3IoUHlPYmplY3RfR2V0QXR0cigKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihjbHMpLCBrREVTQ1JJUFRPUikpOworICBpZiAoZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIk1lc3NhZ2UgY2xhc3MgaGFzIG5vIERFU0NSSVBUT1IiKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhkZXNjcmlwdG9yLCAmUHlNZXNzYWdlRGVzY3JpcHRvcl9UeXBlKSkgeworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJFeHBlY3RlZCBhIG1lc3NhZ2UgRGVzY3JpcHRvciwgZ290ICVzIiwKKyAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIFB5TWVzc2FnZURlc2NyaXB0b3JfQXNEZXNjcmlwdG9yKGRlc2NyaXB0b3IpOworfQorCisvLyBSZXRyaWV2ZSBhIEMrKyBGaWVsZERlc2NyaXB0b3IgZm9yIGEgbWVzc2FnZSBhdHRyaWJ1dGUuCisvLyBUaGUgQysrIG1lc3NhZ2UgbXVzdCBiZSB2YWxpZC4KKy8vIFRPRE8oYW1hdXJ5ZmEpOiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBzdGF5IGludGVybmFsLCBiZWNhdXNlIGV4Y2VwdGlvbgorLy8gaGFuZGxpbmcgaXMgbm90IGNvbnNpc3RlbnQuCitzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZXRGaWVsZERlc2NyaXB0b3IoCisgICAgQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBuYW1lKSB7CisgIGNvbnN0IERlc2NyaXB0b3IgKm1lc3NhZ2VfZGVzY3JpcHRvciA9IHNlbGYtPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKyAgY2hhciogZmllbGRfbmFtZTsKKyAgUHlfc3NpemVfdCBzaXplOworICBpZiAoUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG5hbWUsICZmaWVsZF9uYW1lLCAmc2l6ZSkgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZF9kZXNjcmlwdG9yID0KKyAgICAgIG1lc3NhZ2VfZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKHN0cmluZyhmaWVsZF9uYW1lLCBzaXplKSk7CisgIGlmIChmaWVsZF9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICAvLyBOb3RlOiBObyBleGNlcHRpb24gaXMgc2V0IQorICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBmaWVsZF9kZXNjcmlwdG9yOworfQorCisvLyBSZXRyaWV2ZSBhIEMrKyBGaWVsZERlc2NyaXB0b3IgZm9yIGFuIGV4dGVuc2lvbiBoYW5kbGUuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIEdldEV4dGVuc2lvbkRlc2NyaXB0b3IoUHlPYmplY3QqIGV4dGVuc2lvbikgeworICBTY29wZWRQeU9iamVjdFB0ciBjZGVzY3JpcHRvcjsKKyAgaWYgKCFQeU9iamVjdF9UeXBlQ2hlY2soZXh0ZW5zaW9uLCAmUHlGaWVsZERlc2NyaXB0b3JfVHlwZSkpIHsKKyAgICAvLyBNb3N0IGNhbGxlcnMgY29uc2lkZXIgZXh0ZW5zaW9ucyBhcyBhIHBsYWluIGRpY3Rpb25hcnkuICBXZSBzaG91bGQKKyAgICAvLyBhbGxvdyBpbnB1dCB3aGljaCBpcyBub3QgYSBmaWVsZCBkZXNjcmlwdG9yLCBhbmQgc2ltcGx5IHByZXRlbmQgaXQgZG9lcworICAgIC8vIG5vdCBleGlzdC4KKyAgICBQeUVycl9TZXRPYmplY3QoUHlFeGNfS2V5RXJyb3IsIGV4dGVuc2lvbik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIFB5RmllbGREZXNjcmlwdG9yX0FzRGVzY3JpcHRvcihleHRlbnNpb24pOworfQorCisvLyBJZiBjbWVzc2FnZV9saXN0IGlzIG5vdCBOVUxMLCB0aGlzIGZ1bmN0aW9uIHJlbGVhc2VzIHZhbHVlcyBpbnRvIHRoZQorLy8gY29udGFpbmVyIENNZXNzYWdlcyBpbnN0ZWFkIG9mIGp1c3QgcmVtb3ZpbmcuIFJlcGVhdGVkIGNvbXBvc2l0ZSBjb250YWluZXIKKy8vIG5lZWRzIHRvIGRvIHRoaXMgdG8gbWFrZSBzdXJlIENNZXNzYWdlcyBzdGF5IGFsaXZlIGlmIHRoZXkncmUgc3RpbGwKKy8vIHJlZmVyZW5jZWQgYWZ0ZXIgZGVsZXRpb24uIFJlcGVhdGVkIHNjYWxhciBjb250YWluZXIgZG9lc24ndCBuZWVkIHRvIHdvcnJ5LgoraW50IEludGVybmFsRGVsZXRlUmVwZWF0ZWRGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciwKKyAgICBQeU9iamVjdCogc2xpY2UsCisgICAgUHlPYmplY3QqIGNtZXNzYWdlX2xpc3QpIHsKKyAgUHlfc3NpemVfdCBsZW5ndGgsIGZyb20sIHRvLCBzdGVwLCBzbGljZV9sZW5ndGg7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIGludCBtaW4sIG1heDsKKyAgbGVuZ3RoID0gcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKworICBpZiAoUHlJbnRfQ2hlY2soc2xpY2UpIHx8IFB5TG9uZ19DaGVjayhzbGljZSkpIHsKKyAgICBmcm9tID0gdG8gPSBQeUxvbmdfQXNMb25nKHNsaWNlKTsKKyAgICBpZiAoZnJvbSA8IDApIHsKKyAgICAgIGZyb20gPSB0byA9IGxlbmd0aCArIGZyb207CisgICAgfQorICAgIHN0ZXAgPSAxOworICAgIG1pbiA9IG1heCA9IGZyb207CisKKyAgICAvLyBSYW5nZSBjaGVjay4KKyAgICBpZiAoZnJvbSA8IDAgfHwgZnJvbSA+PSBsZW5ndGgpIHsKKyAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19JbmRleEVycm9yLCAibGlzdCBhc3NpZ25tZW50IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgfSBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKHNsaWNlKSkgeworICAgIGZyb20gPSB0byA9IHN0ZXAgPSBzbGljZV9sZW5ndGggPSAwOworICAgIFB5U2xpY2VfR2V0SW5kaWNlc0V4KAorI2lmIFBZX01BSk9SX1ZFUlNJT04gPCAzCisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UHlTbGljZU9iamVjdCo+KHNsaWNlKSwKKyNlbHNlCisgICAgICAgIHNsaWNlLAorI2VuZGlmCisgICAgICAgIGxlbmd0aCwgJmZyb20sICZ0bywgJnN0ZXAsICZzbGljZV9sZW5ndGgpOworICAgIGlmIChmcm9tIDwgdG8pIHsKKyAgICAgIG1pbiA9IGZyb207CisgICAgICBtYXggPSB0byAtIDE7CisgICAgfSBlbHNlIHsKKyAgICAgIG1pbiA9IHRvICsgMTsKKyAgICAgIG1heCA9IGZyb207CisgICAgfQorICB9IGVsc2UgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJsaXN0IGluZGljZXMgbXVzdCBiZSBpbnRlZ2VycyIpOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIFB5X3NzaXplX3QgaSA9IGZyb207CisgIHN0ZDo6dmVjdG9yPGJvb2w+IHRvX2RlbGV0ZShsZW5ndGgsIGZhbHNlKTsKKyAgd2hpbGUgKGkgPj0gbWluICYmIGkgPD0gbWF4KSB7CisgICAgdG9fZGVsZXRlW2ldID0gdHJ1ZTsKKyAgICBpICs9IHN0ZXA7CisgIH0KKworICB0byA9IDA7CisgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgIGlmICghdG9fZGVsZXRlW2ldKSB7CisgICAgICBpZiAoaSAhPSB0bykgeworICAgICAgICByZWZsZWN0aW9uLT5Td2FwRWxlbWVudHMobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaSwgdG8pOworICAgICAgICBpZiAoY21lc3NhZ2VfbGlzdCAhPSBOVUxMKSB7CisgICAgICAgICAgLy8gSWYgYSBsaXN0IG9mIGNtZXNzYWdlcyBpcyBwYXNzZWQgaW4gKGkuZS4gZnJvbSBhIHJlcGVhdGVkCisgICAgICAgICAgLy8gY29tcG9zaXRlIGNvbnRhaW5lciksIHN3YXAgdGhvc2UgYXMgd2VsbCB0byBjb3JyZXNwb25kIHRvIHRoZQorICAgICAgICAgIC8vIHN3YXBzIGluIHRoZSB1bmRlcmx5aW5nIG1lc3NhZ2Ugc28gdGhleSdyZSBpbiB0aGUgcmlnaHQgb3JkZXIKKyAgICAgICAgICAvLyB3aGVuIHdlIHN0YXJ0IHJlbGVhc2luZy4KKyAgICAgICAgICBQeU9iamVjdCogdG1wID0gUHlMaXN0X0dFVF9JVEVNKGNtZXNzYWdlX2xpc3QsIGkpOworICAgICAgICAgIFB5TGlzdF9TRVRfSVRFTShjbWVzc2FnZV9saXN0LCBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQeUxpc3RfR0VUX0lURU0oY21lc3NhZ2VfbGlzdCwgdG8pKTsKKyAgICAgICAgICBQeUxpc3RfU0VUX0lURU0oY21lc3NhZ2VfbGlzdCwgdG8sIHRtcCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgICsrdG87CisgICAgfQorICB9CisKKyAgd2hpbGUgKGkgPiB0bykgeworICAgIGlmIChjbWVzc2FnZV9saXN0ID09IE5VTEwpIHsKKyAgICAgIHJlZmxlY3Rpb24tPlJlbW92ZUxhc3QobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgICAgfSBlbHNlIHsKKyAgICAgIENNZXNzYWdlKiBsYXN0X2NtZXNzYWdlID0gcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KAorICAgICAgICAgIFB5TGlzdF9HRVRfSVRFTShjbWVzc2FnZV9saXN0LCBQeUxpc3RfR0VUX1NJWkUoY21lc3NhZ2VfbGlzdCkgLSAxKSk7CisgICAgICByZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyOjpSZWxlYXNlTGFzdFRvKAorICAgICAgICAgIGZpZWxkX2Rlc2NyaXB0b3IsIG1lc3NhZ2UsIGxhc3RfY21lc3NhZ2UpOworICAgICAgaWYgKFB5U2VxdWVuY2VfRGVsSXRlbShjbWVzc2FnZV9saXN0LCAtMSkgPCAwKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICB9CisgICAgLS1pOworICB9CisKKyAgcmV0dXJuIDA7Cit9CisKKy8vIEluaXRpYWxpemVzIGZpZWxkcyBvZiBhIG1lc3NhZ2UuIFVzZWQgaW4gY29uc3RydWN0b3JzLgoraW50IEluaXRBdHRyaWJ1dGVzKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCoga3dhcmdzKSB7CisgIGlmIChrd2FyZ3MgPT0gTlVMTCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgUHlfc3NpemVfdCBwb3MgPSAwOworICBQeU9iamVjdCogbmFtZTsKKyAgUHlPYmplY3QqIHZhbHVlOworICB3aGlsZSAoUHlEaWN0X05leHQoa3dhcmdzLCAmcG9zLCAmbmFtZSwgJnZhbHVlKSkgeworICAgIGlmICghUHlTdHJpbmdfQ2hlY2sobmFtZSkpIHsKKyAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiRmllbGQgbmFtZSBtdXN0IGJlIGEgc3RyaW5nIik7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEdldEZpZWxkRGVzY3JpcHRvcihzZWxmLCBuYW1lKTsKKyAgICBpZiAoZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgIlByb3RvY29sIG1lc3NhZ2UgaGFzIG5vIFwiJXNcIiBmaWVsZC4iLAorICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FzU3RyaW5nKG5hbWUpKTsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKGRlc2NyaXB0b3ItPmxhYmVsKCkgPT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCkgeworICAgICAgU2NvcGVkUHlPYmplY3RQdHIgY29udGFpbmVyKEdldEF0dHIoc2VsZiwgbmFtZSkpOworICAgICAgaWYgKGNvbnRhaW5lciA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICAgIGlmIChkZXNjcmlwdG9yLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICAgIGlmIChyZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyOjpFeHRlbmQoCisgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lcio+KGNvbnRhaW5lci5nZXQoKSksCisgICAgICAgICAgICAgICAgdmFsdWUpCisgICAgICAgICAgICA9PSBOVUxMKSB7CisgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAocmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lcjo6RXh0ZW5kKAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRTY2FsYXJDb250YWluZXIqPihjb250YWluZXIuZ2V0KCkpLAorICAgICAgICAgICAgICAgIHZhbHVlKSA9PQorICAgICAgICAgICAgTlVMTCkgeworICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZWxzZSBpZiAoZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgU2NvcGVkUHlPYmplY3RQdHIgbWVzc2FnZShHZXRBdHRyKHNlbGYsIG5hbWUpKTsKKyAgICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgaWYgKE1lcmdlRnJvbShyZWludGVycHJldF9jYXN0PENNZXNzYWdlKj4obWVzc2FnZS5nZXQoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKFNldEF0dHIoc2VsZiwgbmFtZSwgdmFsdWUpIDwgMCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiAwOworfQorCisvLyBBbGxvY2F0ZXMgYW4gaW5jb21wbGV0ZSBQeXRob24gTWVzc2FnZTogdGhlIGNhbGxlciBtdXN0IGZpbGwgc2VsZi0+bWVzc2FnZSwKKy8vIHNlbGYtPm93bmVyIGFuZCBldmVudHVhbGx5IHNlbGYtPnBhcmVudC4KK0NNZXNzYWdlKiBOZXdFbXB0eU1lc3NhZ2UoUHlPYmplY3QqIHR5cGUsIGNvbnN0IERlc2NyaXB0b3IgKmRlc2NyaXB0b3IpIHsKKyAgQ01lc3NhZ2UqIHNlbGYgPSByZWludGVycHJldF9jYXN0PENNZXNzYWdlKj4oCisgICAgICBQeVR5cGVfR2VuZXJpY0FsbG9jKHJlaW50ZXJwcmV0X2Nhc3Q8UHlUeXBlT2JqZWN0Kj4odHlwZSksIDApKTsKKyAgaWYgKHNlbGYgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgc2VsZi0+bWVzc2FnZSA9IE5VTEw7CisgIHNlbGYtPnBhcmVudCA9IE5VTEw7CisgIHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yID0gTlVMTDsKKyAgc2VsZi0+cmVhZF9vbmx5ID0gZmFsc2U7CisgIHNlbGYtPmV4dGVuc2lvbnMgPSBOVUxMOworCisgIHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMgPSBOVUxMOworCisgIC8vIElmIHRoZXJlIGFyZSBleHRlbnNpb25fcmFuZ2VzLCB0aGUgbWVzc2FnZSBpcyAiZXh0ZW5kYWJsZSIuIEFsbG9jYXRlIGEKKyAgLy8gZGljdGlvbmFyeSB0byBzdG9yZSB0aGUgZXh0ZW5zaW9uIGZpZWxkcy4KKyAgaWYgKGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIC8vIFRPRE8oYW1hdXJ5ZmEpOiBEZWxheSB0aGUgY29uc3RydWN0aW9uIG9mIHRoaXMgZGljdCB1bnRpbCBleHRlbnNpb25zIGFyZQorICAgIC8vIHJlYWxseSB1c2VkIG9uIHRoZSBvYmplY3QuCisgICAgRXh0ZW5zaW9uRGljdCogZXh0ZW5zaW9uX2RpY3QgPSBleHRlbnNpb25fZGljdDo6TmV3RXh0ZW5zaW9uRGljdChzZWxmKTsKKyAgICBpZiAoZXh0ZW5zaW9uX2RpY3QgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHNlbGYtPmV4dGVuc2lvbnMgPSBleHRlbnNpb25fZGljdDsKKyAgfQorCisgIHJldHVybiBzZWxmOworfQorCisvLyBUaGUgX19uZXdfXyBtZXRob2Qgb2YgTWVzc2FnZSBjbGFzc2VzLgorLy8gQ3JlYXRlcyBhIG5ldyBDKysgbWVzc2FnZSBhbmQgdGFrZXMgb3duZXJzaGlwLgorc3RhdGljIFB5T2JqZWN0KiBOZXcoUHlUeXBlT2JqZWN0KiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIHVudXNlZF9hcmdzLCBQeU9iamVjdCogdW51c2VkX2t3YXJncykgeworICAvLyBSZXRyaWV2ZSB0aGUgbWVzc2FnZSBkZXNjcmlwdG9yIGFuZCB0aGUgZGVmYXVsdCBpbnN0YW5jZSAoPXByb3RvdHlwZSkuCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfZGVzY3JpcHRvciA9IEdldE1lc3NhZ2VEZXNjcmlwdG9yKHR5cGUpOworICBpZiAobWVzc2FnZV9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X21lc3NhZ2UgPQorICAgICAgbWVzc2FnZV9mYWN0b3J5LT5HZXRQcm90b3R5cGUobWVzc2FnZV9kZXNjcmlwdG9yKTsKKyAgaWYgKGRlZmF1bHRfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgbWVzc2FnZV9kZXNjcmlwdG9yLT5mdWxsX25hbWUoKS5jX3N0cigpKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIENNZXNzYWdlKiBzZWxmID0gTmV3RW1wdHlNZXNzYWdlKHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPih0eXBlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yKTsKKyAgaWYgKHNlbGYgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHNlbGYtPm1lc3NhZ2UgPSBkZWZhdWx0X21lc3NhZ2UtPk5ldygpOworICBzZWxmLT5vd25lci5yZXNldChzZWxmLT5tZXNzYWdlKTsKKworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYpOworfQorCisvLyBUaGUgX19pbml0X18gbWV0aG9kIG9mIE1lc3NhZ2UgY2xhc3Nlcy4KKy8vIEl0IGluaXRpYWxpemVzIGZpZWxkcyBmcm9tIGtleXdvcmRzIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IuCitzdGF0aWMgaW50IEluaXQoQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKSB7CisgIGlmIChQeVR1cGxlX1NpemUoYXJncykgIT0gMCkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJObyBwb3NpdGlvbmFsIGFyZ3VtZW50cyBhbGxvd2VkIik7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgcmV0dXJuIEluaXRBdHRyaWJ1dGVzKHNlbGYsIGt3YXJncyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRGVhbGxvY2F0aW5nIGEgQ01lc3NhZ2UKKy8vCisvLyBEZWFsbG9jYXRpbmcgYSBDTWVzc2FnZSByZXF1aXJlcyB0aGF0IHdlIGNsZWFyIGFueSB3ZWFrIHJlZmVyZW5jZXMKKy8vIGZyb20gY2hpbGRyZW4gdG8gdGhlIG1lc3NhZ2UgYmVpbmcgZGVhbGxvY2F0ZWQuCisKKy8vIENsZWFyIHRoZSB3ZWFrIHJlZmVyZW5jZSBmcm9tIHRoZSBjaGlsZCB0byB0aGUgcGFyZW50Lgorc3RydWN0IENsZWFyV2Vha1JlZmVyZW5jZXMgOiBwdWJsaWMgQ2hpbGRWaXNpdG9yIHsKKyAgaW50IFZpc2l0UmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIGNvbnRhaW5lcikgeworICAgIGNvbnRhaW5lci0+cGFyZW50ID0gTlVMTDsKKyAgICAvLyBUaGUgZWxlbWVudHMgaW4gdGhlIGNvbnRhaW5lciBoYXZlIHRoZSBzYW1lIHBhcmVudCBhcyB0aGUKKyAgICAvLyBjb250YWluZXIgaXRzZWxmLCBzbyBOVUxMIG91dCB0aGF0IHBvaW50ZXIgYXMgd2VsbC4KKyAgICBjb25zdCBQeV9zc2l6ZV90IG4gPSBQeUxpc3RfR0VUX1NJWkUoY29udGFpbmVyLT5jaGlsZF9tZXNzYWdlcyk7CisgICAgZm9yIChQeV9zc2l6ZV90IGkgPSAwOyBpIDwgbjsgKytpKSB7CisgICAgICBDTWVzc2FnZSogY2hpbGRfY21lc3NhZ2UgPSByZWludGVycHJldF9jYXN0PENNZXNzYWdlKj4oCisgICAgICAgICAgUHlMaXN0X0dFVF9JVEVNKGNvbnRhaW5lci0+Y2hpbGRfbWVzc2FnZXMsIGkpKTsKKyAgICAgIGNoaWxkX2NtZXNzYWdlLT5wYXJlbnQgPSBOVUxMOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGludCBWaXNpdFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBjb250YWluZXIpIHsKKyAgICBjb250YWluZXItPnBhcmVudCA9IE5VTEw7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBpbnQgVmlzaXRDTWVzc2FnZShDTWVzc2FnZSogY21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvcikgeworICAgIGNtZXNzYWdlLT5wYXJlbnQgPSBOVUxMOworICAgIHJldHVybiAwOworICB9Cit9OworCitzdGF0aWMgdm9pZCBEZWFsbG9jKENNZXNzYWdlKiBzZWxmKSB7CisgIC8vIE51bGwgb3V0IGFsbCB3ZWFrIHJlZmVyZW5jZXMgZnJvbSBjaGlsZHJlbiB0byB0aGlzIG1lc3NhZ2UuCisgIEdPT0dMRV9DSEVDS19FUSgwLCBGb3JFYWNoQ29tcG9zaXRlRmllbGQoc2VsZiwgQ2xlYXJXZWFrUmVmZXJlbmNlcygpKSk7CisKKyAgUHlfQ0xFQVIoc2VsZi0+ZXh0ZW5zaW9ucyk7CisgIFB5X0NMRUFSKHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMpOworICBzZWxmLT5vd25lci5yZXNldCgpOworICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihzZWxmKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisKK1B5T2JqZWN0KiBJc0luaXRpYWxpemVkKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICBQeU9iamVjdCogZXJyb3JzID0gTlVMTDsKKyAgaWYgKFB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxPIiwgJmVycm9ycykgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaWYgKHNlbGYtPm1lc3NhZ2UtPklzSW5pdGlhbGl6ZWQoKSkgeworICAgIFB5X1JFVFVSTl9UUlVFOworICB9CisgIGlmIChlcnJvcnMgIT0gTlVMTCkgeworICAgIFNjb3BlZFB5T2JqZWN0UHRyIGluaXRpYWxpemF0aW9uX2Vycm9ycygKKyAgICAgICAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKHNlbGYpKTsKKyAgICBpZiAoaW5pdGlhbGl6YXRpb25fZXJyb3JzID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRQeU9iamVjdFB0ciBleHRlbmRfbmFtZShQeVN0cmluZ19Gcm9tU3RyaW5nKCJleHRlbmQiKSk7CisgICAgaWYgKGV4dGVuZF9uYW1lID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRQeU9iamVjdFB0ciByZXN1bHQoUHlPYmplY3RfQ2FsbE1ldGhvZE9iakFyZ3MoCisgICAgICAgIGVycm9ycywKKyAgICAgICAgZXh0ZW5kX25hbWUuZ2V0KCksCisgICAgICAgIGluaXRpYWxpemF0aW9uX2Vycm9ycy5nZXQoKSwKKyAgICAgICAgTlVMTCkpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisgIFB5X1JFVFVSTl9GQUxTRTsKK30KKworUHlPYmplY3QqIEhhc0ZpZWxkQnlEZXNjcmlwdG9yKAorICAgIENNZXNzYWdlKiBzZWxmLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IpIHsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIGlmICghQ2hlY2tGaWVsZEJlbG9uZ3NUb01lc3NhZ2UoZmllbGRfZGVzY3JpcHRvciwgbWVzc2FnZSkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoZmllbGRfZGVzY3JpcHRvci0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0tleUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiRmllbGQgaXMgcmVwZWF0ZWQuIEEgc2luZ3VsYXIgbWV0aG9kIGlzIHJlcXVpcmVkLiIpOworICAgIHJldHVybiBOVUxMOworICB9CisgIGJvb2wgaGFzX2ZpZWxkID0KKyAgICAgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IpOworICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKGhhc19maWVsZCA/IDEgOiAwKTsKK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRmllbGRXaXRoT25lb2ZzKAorICAgIGNvbnN0IE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSwgYm9vbCogaW5fb25lb2YpIHsKKyAgKmluX29uZW9mID0gZmFsc2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciA9CisgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoZmllbGRfbmFtZSk7CisgIGlmIChmaWVsZF9kZXNjcmlwdG9yICE9IE5VTEwpIHsKKyAgICByZXR1cm4gZmllbGRfZGVzY3JpcHRvcjsKKyAgfQorICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2MgPQorICAgICAgZGVzY3JpcHRvci0+RmluZE9uZW9mQnlOYW1lKGZpZWxkX25hbWUpOworICBpZiAob25lb2ZfZGVzYyAhPSBOVUxMKSB7CisgICAgKmluX29uZW9mID0gdHJ1ZTsKKyAgICByZXR1cm4gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRPbmVvZkZpZWxkRGVzY3JpcHRvcigqbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVvZl9kZXNjKTsKKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworYm9vbCBDaGVja0hhc1ByZXNlbmNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciwgYm9vbCBpbl9vbmVvZikgeworICBpZiAoZmllbGRfZGVzY3JpcHRvci0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICJQcm90b2NvbCBtZXNzYWdlIGhhcyBubyBzaW5ndWxhciBcIiVzXCIgZmllbGQuIiwKKyAgICAgICAgICAgICAgICAgZmllbGRfZGVzY3JpcHRvci0+bmFtZSgpLmNfc3RyKCkpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChmaWVsZF9kZXNjcmlwdG9yLT5maWxlKCktPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zKSB7CisgICAgLy8gSGFzRmllbGQoKSBmb3IgYSBvbmVvZiAqaXRzZWxmKiBpc24ndCBzdXBwb3J0ZWQuCisgICAgaWYgKGluX29uZW9mKSB7CisgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgdGVzdCBvbmVvZiBmaWVsZCBcIiVzXCIgZm9yIHByZXNlbmNlIGluIHByb3RvMywgdXNlICIKKyAgICAgICAgICAgICAgICAgICAiV2hpY2hPbmVvZiBpbnN0ZWFkLiIsCisgICAgICAgICAgICAgICAgICAgZmllbGRfZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpLT5uYW1lKCkuY19zdHIoKSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gLi4uYnV0IEhhc0ZpZWxkKCkgZm9yIGZpZWxkcyAqaW4qIGEgb25lb2YgaXMgc3VwcG9ydGVkLgorICAgIGlmIChmaWVsZF9kZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIFB5RXJyX0Zvcm1hdCgKKyAgICAgICAgICBQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICJDYW4ndCB0ZXN0IG5vbi1zdWJtZXNzYWdlIGZpZWxkIFwiJXNcIiBmb3IgcHJlc2VuY2UgaW4gcHJvdG8zLiIsCisgICAgICAgICAgZmllbGRfZGVzY3JpcHRvci0+bmFtZSgpLmNfc3RyKCkpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitQeU9iamVjdCogSGFzRmllbGQoQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmcpIHsKKyAgY2hhciogZmllbGRfbmFtZTsKKyAgUHlfc3NpemVfdCBzaXplOworI2lmIFBZX01BSk9SX1ZFUlNJT04gPCAzCisgIGlmIChQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoYXJnLCAmZmllbGRfbmFtZSwgJnNpemUpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisjZWxzZQorICBmaWVsZF9uYW1lID0gUHlVbmljb2RlX0FzVVRGOEFuZFNpemUoYXJnLCAmc2l6ZSk7CisgIGlmICghZmllbGRfbmFtZSkgeworICAgIHJldHVybiBOVUxMOworICB9CisjZW5kaWYKKworICBNZXNzYWdlKiBtZXNzYWdlID0gc2VsZi0+bWVzc2FnZTsKKyAgYm9vbCBpc19pbl9vbmVvZjsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yID0KKyAgICAgIEZpbmRGaWVsZFdpdGhPbmVvZnMobWVzc2FnZSwgc3RyaW5nKGZpZWxkX25hbWUsIHNpemUpLCAmaXNfaW5fb25lb2YpOworICBpZiAoZmllbGRfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgaWYgKCFpc19pbl9vbmVvZikgeworICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsICJVbmtub3duIGZpZWxkICVzLiIsIGZpZWxkX25hbWUpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfSBlbHNlIHsKKyAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgICB9CisgIH0KKworICBpZiAoIUNoZWNrSGFzUHJlc2VuY2UoZmllbGRfZGVzY3JpcHRvciwgaXNfaW5fb25lb2YpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBpZiAobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcikpIHsKKyAgICBQeV9SRVRVUk5fVFJVRTsKKyAgfQorICBpZiAoIW1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpICYmCisgICAgICBmaWVsZF9kZXNjcmlwdG9yLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNKSB7CisgICAgLy8gU3BlY2lhbCBjYXNlOiBQeXRob24gSGFzRmllbGQoKSBkaWZmZXJzIGluIHNlbWFudGljcyBmcm9tIEMrKworICAgIC8vIHNsaWdodGx5OiB3ZSByZXR1cm4gSGFzRmllbGQoJ2VudW1fZmllbGQnKSA9PSB0cnVlIGlmIHRoZXJlIGlzCisgICAgLy8gYW4gdW5rbm93biBlbnVtIHZhbHVlIHByZXNlbnQuIFRvIGltcGxlbWVudCB0aGlzIHdlIGhhdmUgdG8KKyAgICAvLyBsb29rIGluIHRoZSBVbmtub3duRmllbGRTZXQuCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkX3NldCA9CisgICAgICAgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VW5rbm93bkZpZWxkcygqbWVzc2FnZSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkX3NldC5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkX3NldC5maWVsZChpKS5udW1iZXIoKSA9PSBmaWVsZF9kZXNjcmlwdG9yLT5udW1iZXIoKSkgeworICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgUHlfUkVUVVJOX0ZBTFNFOworfQorCitQeU9iamVjdCogQ2xlYXJFeHRlbnNpb24oQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmcpIHsKKyAgaWYgKHNlbGYtPmV4dGVuc2lvbnMgIT0gTlVMTCkgeworICAgIHJldHVybiBleHRlbnNpb25fZGljdDo6Q2xlYXJFeHRlbnNpb24oc2VsZi0+ZXh0ZW5zaW9ucywgYXJnKTsKKyAgfQorICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiTWVzc2FnZSBpcyBub3QgZXh0ZW5kYWJsZSIpOworICByZXR1cm4gTlVMTDsKK30KKworUHlPYmplY3QqIEhhc0V4dGVuc2lvbihDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIGFyZykgeworICBpZiAoc2VsZi0+ZXh0ZW5zaW9ucyAhPSBOVUxMKSB7CisgICAgcmV0dXJuIGV4dGVuc2lvbl9kaWN0OjpIYXNFeHRlbnNpb24oc2VsZi0+ZXh0ZW5zaW9ucywgYXJnKTsKKyAgfQorICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiTWVzc2FnZSBpcyBub3QgZXh0ZW5kYWJsZSIpOworICByZXR1cm4gTlVMTDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBSZWxlYXNpbmcgbWVzc2FnZXMKKy8vCisvLyBUaGUgUHl0aG9uIEFQSSdzIENsZWFyRmllbGQoKSBhbmQgQ2xlYXIoKSBtZXRob2RzIGJlaGF2ZQorLy8gZGlmZmVyZW50bHkgdGhhbiB0aGVpciBDKysgY291bnRlcnBhcnRzLiAgV2hpbGUgdGhlIEMrKyB2ZXJzaW9ucworLy8gY2xlYXJzIHRoZSBjaGlsZHJlbiB0aGUgUHl0aG9uIHZlcnNpb25zIGRldGFjaGVzIHRoZSBjaGlsZHJlbiwKKy8vIHdpdGhvdXQgdG91Y2hpbmcgdGhlaXIgY29udGVudC4gIFRoaXMgaW1wZWRhbmNlIG1pc21hdGNoIGNhdXNlcworLy8gc29tZSBjb21wbGV4aXR5IGluIHRoZSBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgY2FwdHVyZWQgaW4gdGhpcworLy8gc2VjdGlvbi4KKy8vCisvLyBXaGVuIGEgQ01lc3NhZ2UgZmllbGQgaXMgY2xlYXJlZCB3ZSBuZWVkIHRvOgorLy8KKy8vICogUmVsZWFzZSB0aGUgTWVzc2FnZSB1c2VkIGFzIHRoZSBiYWNraW5nIHN0b3JlIGZvciB0aGUgQ01lc3NhZ2UKKy8vICAgZnJvbSBpdHMgcGFyZW50LgorLy8KKy8vICogQ2hhbmdlIHRoZSBvd25lciBmaWVsZCBvZiB0aGUgcmVsZWFzZWQgQ01lc3NhZ2UgYW5kIGFsbCBvZiBpdHMKKy8vICAgY2hpbGRyZW4gdG8gcG9pbnQgdG8gdGhlIG5ld2x5IHJlbGVhc2VkIE1lc3NhZ2UuCisvLworLy8gKiBDbGVhciB0aGUgd2VhayByZWZlcmVuY2VzIGZyb20gdGhlIHJlbGVhc2VkIENNZXNzYWdlIHRvIHRoZQorLy8gICBwYXJlbnQuCisvLworLy8gV2hlbiBhIFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyIGZpZWxkIGlzIGNsZWFyZWQgd2UgbmVlZCB0bzoKKy8vCisvLyAqIFJlbGVhc2UgYWxsIHRoZSBNZXNzYWdlIHVzZWQgYXMgdGhlIGJhY2tpbmcgc3RvcmUgZm9yIHRoZQorLy8gICBDTWVzc2FnZXMgc3RvcmVkIGluIHRoZSBjb250YWluZXIuCisvLworLy8gKiBDaGFuZ2UgdGhlIG93bmVyIGZpZWxkIG9mIGFsbCB0aGUgcmVsZWFzZWQgQ01lc3NhZ2UgYW5kIGFsbCBvZgorLy8gICB0aGVpciBjaGlsZHJlbiB0byBwb2ludCB0byB0aGUgbmV3bHkgcmVsZWFzZWQgTWVzc2FnZXMuCisvLworLy8gKiBDbGVhciB0aGUgd2VhayByZWZlcmVuY2VzIGZyb20gdGhlIHJlbGVhc2VkIGNvbnRhaW5lciB0byB0aGUKKy8vICAgcGFyZW50LgorCitzdHJ1Y3QgU2V0T3duZXJWaXNpdG9yIDogcHVibGljIENoaWxkVmlzaXRvciB7CisgIC8vIG5ld19vd25lciBtdXN0IG91dGxpdmUgdGhpcyBvYmplY3QuCisgIGV4cGxpY2l0IFNldE93bmVyVmlzaXRvcihjb25zdCBzaGFyZWRfcHRyPE1lc3NhZ2U+JiBuZXdfb3duZXIpCisgICAgICA6IG5ld19vd25lcl8obmV3X293bmVyKSB7fQorCisgIGludCBWaXNpdFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBjb250YWluZXIpIHsKKyAgICByZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyOjpTZXRPd25lcihjb250YWluZXIsIG5ld19vd25lcl8pOworICAgIHJldHVybiAwOworICB9CisKKyAgaW50IFZpc2l0UmVwZWF0ZWRTY2FsYXJDb250YWluZXIoUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIGNvbnRhaW5lcikgeworICAgIHJlcGVhdGVkX3NjYWxhcl9jb250YWluZXI6OlNldE93bmVyKGNvbnRhaW5lciwgbmV3X293bmVyXyk7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBpbnQgVmlzaXRDTWVzc2FnZShDTWVzc2FnZSogY21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvcikgeworICAgIHJldHVybiBTZXRPd25lcihjbWVzc2FnZSwgbmV3X293bmVyXyk7CisgIH0KKworIHByaXZhdGU6CisgIGNvbnN0IHNoYXJlZF9wdHI8TWVzc2FnZT4mIG5ld19vd25lcl87Cit9OworCisvLyBDaGFuZ2UgdGhlIG93bmVyIG9mIHRoaXMgQ01lc3NhZ2UgYW5kIGFsbCBpdHMgY2hpbGRyZW4sIHJlY3Vyc2l2ZWx5LgoraW50IFNldE93bmVyKENNZXNzYWdlKiBzZWxmLCBjb25zdCBzaGFyZWRfcHRyPE1lc3NhZ2U+JiBuZXdfb3duZXIpIHsKKyAgc2VsZi0+b3duZXIgPSBuZXdfb3duZXI7CisgIGlmIChGb3JFYWNoQ29tcG9zaXRlRmllbGQoc2VsZiwgU2V0T3duZXJWaXNpdG9yKG5ld19vd25lcikpID09IC0xKQorICAgIHJldHVybiAtMTsKKyAgcmV0dXJuIDA7Cit9CisKKy8vIFJlbGVhc2VzIHRoZSBtZXNzYWdlIHNwZWNpZmllZCBieSAnZmllbGQnIGFuZCByZXR1cm5zIHRoZQorLy8gcG9pbnRlci4gSWYgdGhlIGZpZWxkIGRvZXMgbm90IGV4aXN0IGEgbmV3IG1lc3NhZ2UgaXMgY3JlYXRlZCB1c2luZworLy8gJ2Rlc2NyaXB0b3InLiBUaGUgY2FsbGVyIHRha2VzIG93bmVyc2hpcCBvZiB0aGUgcmV0dXJuZWQgcG9pbnRlci4KK01lc3NhZ2UqIFJlbGVhc2VNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yKSB7CisgIE1lc3NhZ2UqIHJlbGVhc2VkX21lc3NhZ2UgPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VNZXNzYWdlKAorICAgICAgbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgbWVzc2FnZV9mYWN0b3J5KTsKKyAgLy8gUmVsZWFzZU1lc3NhZ2Ugd2lsbCByZXR1cm4gTlVMTCB3aGljaCBkaWZmZXJzIGZyb20KKyAgLy8gY2hpbGRfY21lc3NhZ2UtPm1lc3NhZ2UsIGlmIHRoZSBmaWVsZCBkb2VzIG5vdCBleGlzdC4gIEluIHRoaXMgY2FzZSwKKyAgLy8gdGhlIGxhdHRlciBwb2ludHMgdG8gdGhlIGRlZmF1bHQgaW5zdGFuY2UgdmlhIGEgY29uc3RfY2FzdDw+LCBzbyB3ZQorICAvLyBoYXZlIHRvIHJlc2V0IGl0IHRvIGEgbmV3IG11dGFibGUgb2JqZWN0IHNpbmNlIHdlIGFyZSB0YWtpbmcgb3duZXJzaGlwLgorICBpZiAocmVsZWFzZWRfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgY29uc3QgTWVzc2FnZSogcHJvdG90eXBlID0gbWVzc2FnZV9mYWN0b3J5LT5HZXRQcm90b3R5cGUoZGVzY3JpcHRvcik7CisgICAgR09PR0xFX0RDSEVDSyhwcm90b3R5cGUgIT0gTlVMTCk7CisgICAgcmVsZWFzZWRfbWVzc2FnZSA9IHByb3RvdHlwZS0+TmV3KCk7CisgIH0KKworICByZXR1cm4gcmVsZWFzZWRfbWVzc2FnZTsKK30KKworaW50IFJlbGVhc2VTdWJNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIENNZXNzYWdlKiBjaGlsZF9jbWVzc2FnZSkgeworICAvLyBSZWxlYXNlIHRoZSBNZXNzYWdlCisgIHNoYXJlZF9wdHI8TWVzc2FnZT4gcmVsZWFzZWRfbWVzc2FnZShSZWxlYXNlTWVzc2FnZSgKKyAgICAgIG1lc3NhZ2UsIGNoaWxkX2NtZXNzYWdlLT5tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCksIGZpZWxkX2Rlc2NyaXB0b3IpKTsKKyAgY2hpbGRfY21lc3NhZ2UtPm1lc3NhZ2UgPSByZWxlYXNlZF9tZXNzYWdlLmdldCgpOworICBjaGlsZF9jbWVzc2FnZS0+b3duZXIuc3dhcChyZWxlYXNlZF9tZXNzYWdlKTsKKyAgY2hpbGRfY21lc3NhZ2UtPnBhcmVudCA9IE5VTEw7CisgIGNoaWxkX2NtZXNzYWdlLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvciA9IE5VTEw7CisgIGNoaWxkX2NtZXNzYWdlLT5yZWFkX29ubHkgPSBmYWxzZTsKKyAgcmV0dXJuIEZvckVhY2hDb21wb3NpdGVGaWVsZChjaGlsZF9jbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRPd25lclZpc2l0b3IoY2hpbGRfY21lc3NhZ2UtPm93bmVyKSk7Cit9CisKK3N0cnVjdCBSZWxlYXNlQ2hpbGQgOiBwdWJsaWMgQ2hpbGRWaXNpdG9yIHsKKyAgLy8gbWVzc2FnZSBtdXN0IG91dGxpdmUgdGhpcyBvYmplY3QuCisgIGV4cGxpY2l0IFJlbGVhc2VDaGlsZChNZXNzYWdlKiBwYXJlbnRfbWVzc2FnZSkgOgorICAgICAgcGFyZW50X21lc3NhZ2VfKHBhcmVudF9tZXNzYWdlKSB7fQorCisgIGludCBWaXNpdFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBjb250YWluZXIpIHsKKyAgICByZXR1cm4gcmVwZWF0ZWRfY29tcG9zaXRlX2NvbnRhaW5lcjo6UmVsZWFzZSgKKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lcio+KGNvbnRhaW5lcikpOworICB9CisKKyAgaW50IFZpc2l0UmVwZWF0ZWRTY2FsYXJDb250YWluZXIoUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIGNvbnRhaW5lcikgeworICAgIHJldHVybiByZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyOjpSZWxlYXNlKAorICAgICAgICByZWludGVycHJldF9jYXN0PFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKj4oY29udGFpbmVyKSk7CisgIH0KKworICBpbnQgVmlzaXRDTWVzc2FnZShDTWVzc2FnZSogY21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvcikgeworICAgIHJldHVybiBSZWxlYXNlU3ViTWVzc2FnZShwYXJlbnRfbWVzc2FnZV8sIGZpZWxkX2Rlc2NyaXB0b3IsCisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Q01lc3NhZ2UqPihjbWVzc2FnZSkpOworICB9CisKKyAgTWVzc2FnZSogcGFyZW50X21lc3NhZ2VfOworfTsKKworaW50IEludGVybmFsUmVsZWFzZUZpZWxkQnlEZXNjcmlwdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciwKKyAgICBQeU9iamVjdCogY29tcG9zaXRlX2ZpZWxkLAorICAgIE1lc3NhZ2UqIHBhcmVudF9tZXNzYWdlKSB7CisgIHJldHVybiBWaXNpdENvbXBvc2l0ZUZpZWxkKAorICAgICAgZmllbGRfZGVzY3JpcHRvciwKKyAgICAgIGNvbXBvc2l0ZV9maWVsZCwKKyAgICAgIFJlbGVhc2VDaGlsZChwYXJlbnRfbWVzc2FnZSkpOworfQorCitQeU9iamVjdCogQ2xlYXJGaWVsZEJ5RGVzY3JpcHRvcigKKyAgICBDTWVzc2FnZSogc2VsZiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgaWYgKCFDaGVja0ZpZWxkQmVsb25nc1RvTWVzc2FnZShkZXNjcmlwdG9yLCBzZWxmLT5tZXNzYWdlKSkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIEFzc3VyZVdyaXRhYmxlKHNlbGYpOworICBzZWxmLT5tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkNsZWFyRmllbGQoc2VsZi0+bWVzc2FnZSwgZGVzY3JpcHRvcik7CisgIFB5X1JFVFVSTl9OT05FOworfQorCitQeU9iamVjdCogQ2xlYXJGaWVsZChDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIGFyZykgeworICBpZiAoIVB5U3RyaW5nX0NoZWNrKGFyZykpIHsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiZmllbGQgbmFtZSBtdXN0IGJlIGEgc3RyaW5nIik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyNpZiBQWV9NQUpPUl9WRVJTSU9OIDwgMworICBjb25zdCBjaGFyKiBmaWVsZF9uYW1lID0gUHlTdHJpbmdfQVNfU1RSSU5HKGFyZyk7CisgIFB5X3NzaXplX3Qgc2l6ZSA9IFB5U3RyaW5nX0dFVF9TSVpFKGFyZyk7CisjZWxzZQorICBQeV9zc2l6ZV90IHNpemU7CisgIGNvbnN0IGNoYXIqIGZpZWxkX25hbWUgPSBQeVVuaWNvZGVfQXNVVEY4QW5kU2l6ZShhcmcsICZzaXplKTsKKyNlbmRpZgorICBBc3N1cmVXcml0YWJsZShzZWxmKTsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIFNjb3BlZFB5T2JqZWN0UHRyIGFyZ19pbl9vbmVvZjsKKyAgYm9vbCBpc19pbl9vbmVvZjsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yID0KKyAgICAgIEZpbmRGaWVsZFdpdGhPbmVvZnMobWVzc2FnZSwgc3RyaW5nKGZpZWxkX25hbWUsIHNpemUpLCAmaXNfaW5fb25lb2YpOworICBpZiAoZmllbGRfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgaWYgKCFpc19pbl9vbmVvZikgeworICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgIlByb3RvY29sIG1lc3NhZ2UgaGFzIG5vIFwiJXNcIiBmaWVsZC4iLCBmaWVsZF9uYW1lKTsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0gZWxzZSB7CisgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICB9CisgIH0gZWxzZSBpZiAoaXNfaW5fb25lb2YpIHsKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUgPSBmaWVsZF9kZXNjcmlwdG9yLT5uYW1lKCk7CisgICAgYXJnX2luX29uZW9mLnJlc2V0KFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKG5hbWUuY19zdHIoKSwgbmFtZS5zaXplKCkpKTsKKyAgICBhcmcgPSBhcmdfaW5fb25lb2YuZ2V0KCk7CisgIH0KKworICBQeU9iamVjdCogY29tcG9zaXRlX2ZpZWxkID0gc2VsZi0+Y29tcG9zaXRlX2ZpZWxkcyA/CisgICAgICBQeURpY3RfR2V0SXRlbShzZWxmLT5jb21wb3NpdGVfZmllbGRzLCBhcmcpIDogTlVMTDsKKworICAvLyBPbmx5IHJlbGVhc2UgdGhlIGZpZWxkIGlmIHRoZXJlJ3MgYSBwb3NzaWJpbGl0eSB0aGF0IHRoZXJlIGFyZQorICAvLyByZWZlcmVuY2VzIHRvIGl0LgorICBpZiAoY29tcG9zaXRlX2ZpZWxkICE9IE5VTEwpIHsKKyAgICBpZiAoSW50ZXJuYWxSZWxlYXNlRmllbGRCeURlc2NyaXB0b3IoZmllbGRfZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zaXRlX2ZpZWxkLCBtZXNzYWdlKSA8IDApIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeURpY3RfRGVsSXRlbShzZWxmLT5jb21wb3NpdGVfZmllbGRzLCBhcmcpOworICB9CisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+Q2xlYXJGaWVsZChtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgaWYgKGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gJiYKKyAgICAgICFtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZXMoKSkgeworICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZF9zZXQgPQorICAgICAgICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpOworICAgIHVua25vd25fZmllbGRfc2V0LT5EZWxldGVCeU51bWJlcihmaWVsZF9kZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgIH0KKworICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlPYmplY3QqIENsZWFyKENNZXNzYWdlKiBzZWxmKSB7CisgIEFzc3VyZVdyaXRhYmxlKHNlbGYpOworICBpZiAoRm9yRWFjaENvbXBvc2l0ZUZpZWxkKHNlbGYsIFJlbGVhc2VDaGlsZChzZWxmLT5tZXNzYWdlKSkgPT0gLTEpCisgICAgcmV0dXJuIE5VTEw7CisKKyAgLy8gVGhlIG9sZCBFeHRlbnNpb25EaWN0IHN0aWxsIGFsaWFzZXMgdGhpcyBDTWVzc2FnZSwgYnV0IGFsbCBpdHMKKyAgLy8gZmllbGRzIGhhdmUgYmVlbiByZWxlYXNlZC4KKyAgaWYgKHNlbGYtPmV4dGVuc2lvbnMgIT0gTlVMTCkgeworICAgIFB5X0NMRUFSKHNlbGYtPmV4dGVuc2lvbnMpOworICAgIEV4dGVuc2lvbkRpY3QqIGV4dGVuc2lvbl9kaWN0ID0gZXh0ZW5zaW9uX2RpY3Q6Ok5ld0V4dGVuc2lvbkRpY3Qoc2VsZik7CisgICAgaWYgKGV4dGVuc2lvbl9kaWN0ID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzZWxmLT5leHRlbnNpb25zID0gZXh0ZW5zaW9uX2RpY3Q7CisgIH0KKyAgaWYgKHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMpIHsKKyAgICBQeURpY3RfQ2xlYXIoc2VsZi0+Y29tcG9zaXRlX2ZpZWxkcyk7CisgIH0KKyAgc2VsZi0+bWVzc2FnZS0+Q2xlYXIoKTsKKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgc3RyaW5nIEdldE1lc3NhZ2VOYW1lKENNZXNzYWdlKiBzZWxmKSB7CisgIGlmIChzZWxmLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvciAhPSBOVUxMKSB7CisgICAgcmV0dXJuIHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gc2VsZi0+bWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKTsKKyAgfQorfQorCitzdGF0aWMgUHlPYmplY3QqIFNlcmlhbGl6ZVRvU3RyaW5nKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICBpZiAoIXNlbGYtPm1lc3NhZ2UtPklzSW5pdGlhbGl6ZWQoKSkgeworICAgIFNjb3BlZFB5T2JqZWN0UHRyIGVycm9ycyhGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoc2VsZikpOworICAgIGlmIChlcnJvcnMgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFNjb3BlZFB5T2JqZWN0UHRyIGNvbW1hKFB5U3RyaW5nX0Zyb21TdHJpbmcoIiwiKSk7CisgICAgaWYgKGNvbW1hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRQeU9iamVjdFB0ciBqb2luZWQoCisgICAgICAgIFB5T2JqZWN0X0NhbGxNZXRob2QoY29tbWEuZ2V0KCksICJqb2luIiwgIk8iLCBlcnJvcnMuZ2V0KCkpKTsKKyAgICBpZiAoam9pbmVkID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIFRPRE8oaGFiZXJtYW4pOiB0aGlzIGlzIGEgKGhvcGVmdWxseSB0ZW1wb3JhcnkpIGhhY2suICBUaGUgdW5pdCB0ZXN0aW5nCisgICAgLy8gaW5mcmFzdHJ1Y3R1cmUgcmVsb2FkcyBhbGwgcHVyZS1QeXRob24gbW9kdWxlcyBmb3IgZXZlcnkgdGVzdCwgYnV0IG5vdAorICAgIC8vIEMrKyBtb2R1bGVzIChiZWNhdXNlIHRoYXQncyBnZW5lcmFsbHkgaW1wb3NzaWJsZToKKyAgICAvLyBodHRwOi8vYnVncy5weXRob24ub3JnL2lzc3VlMTE0NDI2MykuICBCdXQgaWYgd2UgY2FjaGUgRW5jb2RlRXJyb3IsIHdlJ2xsCisgICAgLy8gcmV0dXJuIHRoZSBFbmNvZGVFcnJvciBmcm9tIGEgcHJldmlvdXMgbG9hZCBvZiB0aGUgbW9kdWxlLCB3aGljaCB3b24ndAorICAgIC8vIG1hdGNoIGEgdXNlcidzIGF0dGVtcHQgdG8gY2F0Y2ggRW5jb2RlRXJyb3IuICBTbyB3ZSBoYXZlIHRvIGxvb2sgaXQgdXAKKyAgICAvLyBhZ2FpbiBldmVyeSB0aW1lLgorICAgIFNjb3BlZFB5T2JqZWN0UHRyIG1lc3NhZ2VfbW9kdWxlKFB5SW1wb3J0X0ltcG9ydE1vZHVsZSgKKyAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5tZXNzYWdlIikpOworICAgIGlmIChtZXNzYWdlX21vZHVsZS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBTY29wZWRQeU9iamVjdFB0ciBlbmNvZGVfZXJyb3IoCisgICAgICAgIFB5T2JqZWN0X0dldEF0dHJTdHJpbmcobWVzc2FnZV9tb2R1bGUsICJFbmNvZGVFcnJvciIpKTsKKyAgICBpZiAoZW5jb2RlX2Vycm9yLmdldCgpID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeUVycl9Gb3JtYXQoZW5jb2RlX2Vycm9yLmdldCgpLAorICAgICAgICAgICAgICAgICAiTWVzc2FnZSAlcyBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogJXMiLAorICAgICAgICAgICAgICAgICBHZXRNZXNzYWdlTmFtZShzZWxmKS5jX3N0cigpLCBQeVN0cmluZ19Bc1N0cmluZyhqb2luZWQpKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpbnQgc2l6ZSA9IHNlbGYtPm1lc3NhZ2UtPkJ5dGVTaXplKCk7CisgIGlmIChzaXplIDw9IDApIHsKKyAgICByZXR1cm4gUHlCeXRlc19Gcm9tU3RyaW5nKCIiKTsKKyAgfQorICBQeU9iamVjdCogcmVzdWx0ID0gUHlCeXRlc19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBzaXplKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgY2hhciogYnVmZmVyID0gUHlCeXRlc19BU19TVFJJTkcocmVzdWx0KTsKKyAgc2VsZi0+bWVzc2FnZS0+U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihidWZmZXIpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0KiBTZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmcoQ01lc3NhZ2UqIHNlbGYpIHsKKyAgc3RyaW5nIGNvbnRlbnRzOworICBzZWxmLT5tZXNzYWdlLT5TZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmcoJmNvbnRlbnRzKTsKKyAgcmV0dXJuIFB5Qnl0ZXNfRnJvbVN0cmluZ0FuZFNpemUoY29udGVudHMuY19zdHIoKSwgY29udGVudHMuc2l6ZSgpKTsKK30KKworLy8gRm9ybWF0cyBwcm90byBmaWVsZHMgZm9yIGFzY2lpIGR1bXBzIHVzaW5nIHB5dGhvbiBmb3JtYXR0aW5nIGZ1bmN0aW9ucyB3aGVyZQorLy8gYXBwcm9wcmlhdGUuCitjbGFzcyBQeXRob25GaWVsZFZhbHVlUHJpbnRlciA6IHB1YmxpYyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlciB7CisgcHVibGljOgorICBQeXRob25GaWVsZFZhbHVlUHJpbnRlcigpIDogZmxvYXRfaG9sZGVyXyhQeUZsb2F0X0Zyb21Eb3VibGUoMCkpIHt9CisKKyAgLy8gUHl0aG9uIGhhcyBzb21lIGRpZmZlcmVuY2VzIGZyb20gQysrIHdoZW4gcHJpbnRpbmcgZmxvYXRpbmcgcG9pbnQgbnVtYmVycy4KKyAgLy8KKyAgLy8gMSkgVHJhaWxpbmcgLjAgaXMgYWx3YXlzIHByaW50ZWQuCisgIC8vIDIpIE91dHB1dHRlZCBpcyByb3VuZGVkIHRvIDEyIGRpZ2l0cy4KKyAgLy8KKyAgLy8gV2Ugb3ZlcnJpZGUgZmxvYXRpbmcgcG9pbnQgcHJpbnRpbmcgd2l0aCB0aGUgQy1BUEkgZnVuY3Rpb24gZm9yIHByaW50aW5nCisgIC8vIFB5dGhvbiBmbG9hdHMgdG8gZW5zdXJlIGNvbnNpc3RlbmN5LgorICBzdHJpbmcgUHJpbnRGbG9hdChmbG9hdCB2YWx1ZSkgY29uc3QgeyByZXR1cm4gUHJpbnREb3VibGUodmFsdWUpOyB9CisgIHN0cmluZyBQcmludERvdWJsZShkb3VibGUgdmFsdWUpIGNvbnN0IHsKKyAgICByZWludGVycHJldF9jYXN0PFB5RmxvYXRPYmplY3QqPihmbG9hdF9ob2xkZXJfLmdldCgpKS0+b2JfZnZhbCA9IHZhbHVlOworICAgIFNjb3BlZFB5T2JqZWN0UHRyIHMoUHlPYmplY3RfU3RyKGZsb2F0X2hvbGRlcl8uZ2V0KCkpKTsKKyAgICBpZiAocyA9PSBOVUxMKSByZXR1cm4gc3RyaW5nKCk7CisjaWYgUFlfTUFKT1JfVkVSU0lPTiA8IDMKKyAgICBjaGFyICpjc3RyID0gUHlCeXRlc19BU19TVFJJTkcoc3RhdGljX2Nhc3Q8UHlPYmplY3QqPihzKSk7CisjZWxzZQorICAgIGNoYXIgKmNzdHIgPSBQeVVuaWNvZGVfQXNVVEY4KHMpOworI2VuZGlmCisgICAgcmV0dXJuIHN0cmluZyhjc3RyKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgLy8gSG9sZGVyIGZvciBhIHB5dGhvbiBmbG9hdCBvYmplY3Qgd2hpY2ggd2UgdXNlIHRvIGFsbG93IHVzIHRvIHVzZQorICAvLyB0aGUgUHl0aG9uIEFQSSBmb3IgcHJpbnRpbmcgZG91Ymxlcy4gV2UgaW5pdGlhbGl6ZSBvbmNlIGFuZCB0aGVuCisgIC8vIGRpcmVjdGx5IG1vZGlmeSBpdCBmb3IgZXZlcnkgZmxvYXQgcHJpbnRlZCB0byBzYXZlIG9uIGFsbG9jYXRpb25zCisgIC8vIGFuZCByZWZjb3VudGluZy4KKyAgU2NvcGVkUHlPYmplY3RQdHIgZmxvYXRfaG9sZGVyXzsKK307CisKK3N0YXRpYyBQeU9iamVjdCogVG9TdHIoQ01lc3NhZ2UqIHNlbGYpIHsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICAvLyBQYXNzZXMgb3duZXJzaGlwCisgIHByaW50ZXIuU2V0RGVmYXVsdEZpZWxkVmFsdWVQcmludGVyKG5ldyBQeXRob25GaWVsZFZhbHVlUHJpbnRlcigpKTsKKyAgcHJpbnRlci5TZXRIaWRlVW5rbm93bkZpZWxkcyh0cnVlKTsKKyAgc3RyaW5nIG91dHB1dDsKKyAgaWYgKCFwcmludGVyLlByaW50VG9TdHJpbmcoKnNlbGYtPm1lc3NhZ2UsICZvdXRwdXQpKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJVbmFibGUgdG8gY29udmVydCBtZXNzYWdlIHRvIHN0ciIpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKG91dHB1dC5jX3N0cigpKTsKK30KKworUHlPYmplY3QqIE1lcmdlRnJvbShDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIGFyZykgeworICBDTWVzc2FnZSogb3RoZXJfbWVzc2FnZTsKKyAgaWYgKCFQeU9iamVjdF9UeXBlQ2hlY2socmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCAqPihhcmcpLCAmQ01lc3NhZ2VfVHlwZSkpIHsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiTXVzdCBiZSBhIG1lc3NhZ2UiKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIG90aGVyX21lc3NhZ2UgPSByZWludGVycHJldF9jYXN0PENNZXNzYWdlKj4oYXJnKTsKKyAgaWYgKG90aGVyX21lc3NhZ2UtPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKSAhPQorICAgICAgc2VsZi0+bWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgIlRyaWVkIHRvIG1lcmdlIGZyb20gYSBtZXNzYWdlIHdpdGggYSBkaWZmZXJlbnQgdHlwZS4gIgorICAgICAgICAgICAgICAgICAidG86ICVzLCBmcm9tOiAlcyIsCisgICAgICAgICAgICAgICAgIHNlbGYtPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkuY19zdHIoKSwKKyAgICAgICAgICAgICAgICAgb3RoZXJfbWVzc2FnZS0+bWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKS5jX3N0cigpKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBBc3N1cmVXcml0YWJsZShzZWxmKTsKKworICAvLyBUT0RPKHRpYmVsbCk6IE1lc3NhZ2U6Ok1lcmdlRnJvbSBtaWdodCB0dXJuIHNvbWUgY2hpbGQgTWVzc2FnZXMKKyAgLy8gaW50byBtdXRhYmxlIG1lc3NhZ2VzLCBpbnZhbGlkYXRpbmcgdGhlIG1lc3NhZ2UgZmllbGQgaW4gdGhlCisgIC8vIGNvcnJlc3BvbmRpbmcgQ01lc3NhZ2VzLiAgV2Ugc2hvdWxkIHJ1biBhIEZpeHVwTWVzc2FnZVJlZmVyZW5jZXMKKyAgLy8gcGFzcyBoZXJlLgorCisgIHNlbGYtPm1lc3NhZ2UtPk1lcmdlRnJvbSgqb3RoZXJfbWVzc2FnZS0+bWVzc2FnZSk7CisgIFB5X1JFVFVSTl9OT05FOworfQorCitzdGF0aWMgUHlPYmplY3QqIENvcHlGcm9tKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIENNZXNzYWdlKiBvdGhlcl9tZXNzYWdlOworICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhyZWludGVycHJldF9jYXN0PFB5T2JqZWN0ICo+KGFyZyksICZDTWVzc2FnZV9UeXBlKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJNdXN0IGJlIGEgbWVzc2FnZSIpOworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgb3RoZXJfbWVzc2FnZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Q01lc3NhZ2UqPihhcmcpOworCisgIGlmIChzZWxmID09IG90aGVyX21lc3NhZ2UpIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorCisgIGlmIChvdGhlcl9tZXNzYWdlLT5tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCkgIT0KKyAgICAgIHNlbGYtPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKSkgeworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICJUcmllZCB0byBjb3B5IGZyb20gYSBtZXNzYWdlIHdpdGggYSBkaWZmZXJlbnQgdHlwZS4gIgorICAgICAgICAgICAgICAgICAidG86ICVzLCBmcm9tOiAlcyIsCisgICAgICAgICAgICAgICAgIHNlbGYtPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkuY19zdHIoKSwKKyAgICAgICAgICAgICAgICAgb3RoZXJfbWVzc2FnZS0+bWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKS5jX3N0cigpKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIEFzc3VyZVdyaXRhYmxlKHNlbGYpOworCisgIC8vIENvcHlGcm9tIG9uIHRoZSBtZXNzYWdlIHdpbGwgbm90IGNsZWFuIHVwIHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMsCisgIC8vIHdoaWNoIGNhbiBsZWF2ZSB1cyBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUsIHNvIGNsZWFyIGl0IG91dCBoZXJlLgorICBDbGVhcihzZWxmKTsKKworICBzZWxmLT5tZXNzYWdlLT5Db3B5RnJvbSgqb3RoZXJfbWVzc2FnZS0+bWVzc2FnZSk7CisKKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogTWVyZ2VGcm9tU3RyaW5nKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIGNvbnN0IHZvaWQqIGRhdGE7CisgIFB5X3NzaXplX3QgZGF0YV9sZW5ndGg7CisgIGlmIChQeU9iamVjdF9Bc1JlYWRCdWZmZXIoYXJnLCAmZGF0YSwgJmRhdGFfbGVuZ3RoKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIEFzc3VyZVdyaXRhYmxlKHNlbGYpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhKSwgZGF0YV9sZW5ndGgpOworICBpbnB1dC5TZXRFeHRlbnNpb25SZWdpc3RyeShHZXREZXNjcmlwdG9yUG9vbCgpLT5wb29sLCBtZXNzYWdlX2ZhY3RvcnkpOworICBib29sIHN1Y2Nlc3MgPSBzZWxmLT5tZXNzYWdlLT5NZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oJmlucHV0KTsKKyAgaWYgKHN1Y2Nlc3MpIHsKKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoaW5wdXQuQ3VycmVudFBvc2l0aW9uKCkpOworICB9IGVsc2UgeworICAgIFB5RXJyX0Zvcm1hdChEZWNvZGVFcnJvcl9jbGFzcywgIkVycm9yIHBhcnNpbmcgbWVzc2FnZSIpOworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCogUGFyc2VGcm9tU3RyaW5nKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIGlmIChDbGVhcihzZWxmKSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIE1lcmdlRnJvbVN0cmluZyhzZWxmLCBhcmcpOworfQorCitzdGF0aWMgUHlPYmplY3QqIEJ5dGVTaXplKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICByZXR1cm4gUHlMb25nX0Zyb21Mb25nKHNlbGYtPm1lc3NhZ2UtPkJ5dGVTaXplKCkpOworfQorCitzdGF0aWMgUHlPYmplY3QqIFJlZ2lzdGVyRXh0ZW5zaW9uKFB5T2JqZWN0KiBjbHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBleHRlbnNpb25faGFuZGxlKSB7CisgIFNjb3BlZFB5T2JqZWN0UHRyIG1lc3NhZ2VfZGVzY3JpcHRvcihQeU9iamVjdF9HZXRBdHRyKGNscywga0RFU0NSSVBUT1IpKTsKKyAgaWYgKG1lc3NhZ2VfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPQorICAgICAgR2V0RXh0ZW5zaW9uRGVzY3JpcHRvcihleHRlbnNpb25faGFuZGxlKTsKKyAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGNvbnN0IERlc2NyaXB0b3IqIGNtZXNzYWdlX2Rlc2NyaXB0b3IgPSBHZXRNZXNzYWdlRGVzY3JpcHRvcigKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UHlUeXBlT2JqZWN0Kj4oY2xzKSk7CisKKyAgaWYgKGNtZXNzYWdlX2Rlc2NyaXB0b3IgIT0gZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpIHsKKyAgICBpZiAoUHlPYmplY3RfU2V0QXR0clN0cmluZyhleHRlbnNpb25faGFuZGxlLCAiY29udGFpbmluZ190eXBlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IpIDwgMCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisKKyAgU2NvcGVkUHlPYmplY3RQdHIgZXh0ZW5zaW9uc19ieV9uYW1lKAorICAgICAgUHlPYmplY3RfR2V0QXR0cihjbHMsIGtfZXh0ZW5zaW9uc19ieV9uYW1lKSk7CisgIGlmIChleHRlbnNpb25zX2J5X25hbWUgPT0gTlVMTCkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJubyBleHRlbnNpb25zX2J5X25hbWUgb24gY2xhc3MiKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBTY29wZWRQeU9iamVjdFB0ciBmdWxsX25hbWUoUHlPYmplY3RfR2V0QXR0cihleHRlbnNpb25faGFuZGxlLCBrZnVsbF9uYW1lKSk7CisgIGlmIChmdWxsX25hbWUgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gSWYgdGhlIGV4dGVuc2lvbiB3YXMgYWxyZWFkeSByZWdpc3RlcmVkLCBjaGVjayB0aGF0IGl0IGlzIHRoZSBzYW1lLgorICBQeU9iamVjdCogZXhpc3RpbmdfZXh0ZW5zaW9uID0gUHlEaWN0X0dldEl0ZW0oZXh0ZW5zaW9uc19ieV9uYW1lLCBmdWxsX25hbWUpOworICBpZiAoZXhpc3RpbmdfZXh0ZW5zaW9uICE9IE5VTEwpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4aXN0aW5nX2V4dGVuc2lvbl9kZXNjcmlwdG9yID0KKyAgICAgICAgR2V0RXh0ZW5zaW9uRGVzY3JpcHRvcihleGlzdGluZ19leHRlbnNpb24pOworICAgIGlmIChleGlzdGluZ19leHRlbnNpb25fZGVzY3JpcHRvciAhPSBkZXNjcmlwdG9yKSB7CisgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIkRvdWJsZSByZWdpc3RyYXRpb24gb2YgRXh0ZW5zaW9ucyIpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8vIE5vdGhpbmcgZWxzZSB0byBkby4KKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorCisgIGlmIChQeURpY3RfU2V0SXRlbShleHRlbnNpb25zX2J5X25hbWUsIGZ1bGxfbmFtZSwgZXh0ZW5zaW9uX2hhbmRsZSkgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICAvLyBBbHNvIHN0b3JlIGEgbWFwcGluZyBmcm9tIGV4dGVuc2lvbiBudW1iZXIgdG8gaW1wbGVtZW50aW5nIGNsYXNzLgorICBTY29wZWRQeU9iamVjdFB0ciBleHRlbnNpb25zX2J5X251bWJlcigKKyAgICAgIFB5T2JqZWN0X0dldEF0dHIoY2xzLCBrX2V4dGVuc2lvbnNfYnlfbnVtYmVyKSk7CisgIGlmIChleHRlbnNpb25zX2J5X251bWJlciA9PSBOVUxMKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIm5vIGV4dGVuc2lvbnNfYnlfbnVtYmVyIG9uIGNsYXNzIik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgbnVtYmVyKFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoZXh0ZW5zaW9uX2hhbmRsZSwgIm51bWJlciIpKTsKKyAgaWYgKG51bWJlciA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaWYgKFB5RGljdF9TZXRJdGVtKGV4dGVuc2lvbnNfYnlfbnVtYmVyLCBudW1iZXIsIGV4dGVuc2lvbl9oYW5kbGUpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gQ2hlY2sgaWYgaXQncyBhIG1lc3NhZ2Ugc2V0CisgIGlmIChkZXNjcmlwdG9yLT5pc19leHRlbnNpb24oKSAmJgorICAgICAgZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpICYmCisgICAgICBkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgJiYKKyAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpID09IGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9zY29wZSgpICYmCisgICAgICBkZXNjcmlwdG9yLT5sYWJlbCgpID09IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwpIHsKKyAgICBTY29wZWRQeU9iamVjdFB0ciBtZXNzYWdlX25hbWUoUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoCisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5mdWxsX25hbWUoKS5jX3N0cigpLAorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCkuc2l6ZSgpKSk7CisgICAgaWYgKG1lc3NhZ2VfbmFtZSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlEaWN0X1NldEl0ZW0oZXh0ZW5zaW9uc19ieV9uYW1lLCBtZXNzYWdlX25hbWUsIGV4dGVuc2lvbl9oYW5kbGUpOworICB9CisKKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogU2V0SW5QYXJlbnQoQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKSB7CisgIEFzc3VyZVdyaXRhYmxlKHNlbGYpOworICBQeV9SRVRVUk5fTk9ORTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBXaGljaE9uZW9mKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIFB5X3NzaXplX3QgbmFtZV9zaXplOworICBjaGFyICpuYW1lX2RhdGE7CisgIGlmIChQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoYXJnLCAmbmFtZV9kYXRhLCAmbmFtZV9zaXplKSA8IDApCisgICAgcmV0dXJuIE5VTEw7CisgIHN0cmluZyBvbmVvZl9uYW1lID0gc3RyaW5nKG5hbWVfZGF0YSwgbmFtZV9zaXplKTsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjID0KKyAgICAgIHNlbGYtPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZE9uZW9mQnlOYW1lKG9uZW9mX25hbWUpOworICBpZiAob25lb2ZfZGVzYyA9PSBOVUxMKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICJQcm90b2NvbCBtZXNzYWdlIGhhcyBubyBvbmVvZiBcIiVzXCIgZmllbGQuIiwKKyAgICAgICAgICAgICAgICAgb25lb2ZfbmFtZS5jX3N0cigpKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2luX29uZW9mID0KKyAgICAgIHNlbGYtPm1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0T25lb2ZGaWVsZERlc2NyaXB0b3IoCisgICAgICAgICAgKnNlbGYtPm1lc3NhZ2UsIG9uZW9mX2Rlc2MpOworICBpZiAoZmllbGRfaW5fb25lb2YgPT0gTlVMTCkgeworICAgIFB5X1JFVFVSTl9OT05FOworICB9IGVsc2UgeworICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IGZpZWxkX2luX29uZW9mLT5uYW1lKCk7CisgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKG5hbWUuY19zdHIoKSwgbmFtZS5zaXplKCkpOworICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCogTGlzdEZpZWxkcyhDTWVzc2FnZSogc2VsZikgeworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBzZWxmLT5tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkxpc3RGaWVsZHMoKnNlbGYtPm1lc3NhZ2UsICZmaWVsZHMpOworCisgIC8vIE5vcm1hbGx5LCB0aGUgbGlzdCB3aWxsIGJlIGV4YWN0bHkgdGhlIHNpemUgb2YgdGhlIGZpZWxkcy4KKyAgU2NvcGVkUHlPYmplY3RQdHIgYWxsX2ZpZWxkcyhQeUxpc3RfTmV3KGZpZWxkcy5zaXplKCkpKTsKKyAgaWYgKGFsbF9maWVsZHMgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gV2hlbiB0aGVyZSBhcmUgdW5rbm93biBleHRlbnNpb25zLCB0aGUgcHkgbGlzdCB3aWxsICpub3QqIGNvbnRhaW4KKyAgLy8gdGhlIGZpZWxkIGluZm9ybWF0aW9uLiAgVGh1cyB0aGUgYWN0dWFsIHNpemUgb2YgdGhlIHB5IGxpc3Qgd2lsbCBiZQorICAvLyBzbWFsbGVyIHRoYW4gdGhlIHNpemUgb2YgZmllbGRzLiAgU2V0IHRoZSBhY3R1YWwgc2l6ZSBhdCB0aGUgZW5kLgorICBQeV9zc2l6ZV90IGFjdHVhbF9zaXplID0gMDsKKyAgZm9yIChQeV9zc2l6ZV90IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgU2NvcGVkUHlPYmplY3RQdHIgdChQeVR1cGxlX05ldygyKSk7CisgICAgaWYgKHQgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKGZpZWxkc1tpXS0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIFNjb3BlZFB5T2JqZWN0UHRyIGV4dGVuc2lvbl9maWVsZChQeUZpZWxkRGVzY3JpcHRvcl9OZXcoZmllbGRzW2ldKSk7CisgICAgICBpZiAoZXh0ZW5zaW9uX2ZpZWxkID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgICAvLyBXaXRoIEMrKyBkZXNjcmlwdG9ycywgdGhlIGZpZWxkIGNhbiBhbHdheXMgYmUgcmV0cmlldmVkLCBidXQgZm9yCisgICAgICAvLyB1bmtub3duIGV4dGVuc2lvbnMgd2hpY2ggaGF2ZSBub3QgYmVlbiBpbXBvcnRlZCBpbiBQeXRob24gY29kZSwgdGhlcmUKKyAgICAgIC8vIGlzIG5vIG1lc3NhZ2UgY2xhc3MgYW5kIHdlIGNhbm5vdCByZXRyaWV2ZSB0aGUgdmFsdWUuCisgICAgICAvLyBUT0RPKGFtYXVyeWZhKTogY29uc2lkZXIgYnVpbGRpbmcgdGhlIGNsYXNzIG9uIHRoZSBmbHkhCisgICAgICBpZiAoZmllbGRzW2ldLT5tZXNzYWdlX3R5cGUoKSAhPSBOVUxMICYmCisgICAgICAgICAgY2Rlc2NyaXB0b3JfcG9vbDo6R2V0TWVzc2FnZUNsYXNzKAorICAgICAgICAgICAgICBHZXREZXNjcmlwdG9yUG9vbCgpLCBmaWVsZHNbaV0tPm1lc3NhZ2VfdHlwZSgpKSA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgUHlPYmplY3QqIGV4dGVuc2lvbnMgPSByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oc2VsZi0+ZXh0ZW5zaW9ucyk7CisgICAgICBpZiAoZXh0ZW5zaW9ucyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgICAgfQorICAgICAgLy8gJ2V4dGVuc2lvbicgcmVmZXJlbmNlIGxhdGVyIHN0b2xlbiBieSBQeVR1cGxlX1NFVF9JVEVNLgorICAgICAgUHlPYmplY3QqIGV4dGVuc2lvbiA9IFB5T2JqZWN0X0dldEl0ZW0oZXh0ZW5zaW9ucywgZXh0ZW5zaW9uX2ZpZWxkKTsKKyAgICAgIGlmIChleHRlbnNpb24gPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICAgIFB5VHVwbGVfU0VUX0lURU0odC5nZXQoKSwgMCwgZXh0ZW5zaW9uX2ZpZWxkLnJlbGVhc2UoKSk7CisgICAgICAvLyBTdGVhbHMgcmVmZXJlbmNlIHRvICdleHRlbnNpb24nCisgICAgICBQeVR1cGxlX1NFVF9JVEVNKHQuZ2V0KCksIDEsIGV4dGVuc2lvbik7CisgICAgfSBlbHNlIHsKKyAgICAgIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSA9IGZpZWxkc1tpXS0+bmFtZSgpOworICAgICAgU2NvcGVkUHlPYmplY3RQdHIgcHlfZmllbGRfbmFtZShQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgKKyAgICAgICAgICBmaWVsZF9uYW1lLmNfc3RyKCksIGZpZWxkX25hbWUubGVuZ3RoKCkpKTsKKyAgICAgIGlmIChweV9maWVsZF9uYW1lID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJiYWQgc3RyaW5nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgICAgfQorICAgICAgU2NvcGVkUHlPYmplY3RQdHIgZmllbGRfZGVzY3JpcHRvcihQeUZpZWxkRGVzY3JpcHRvcl9OZXcoZmllbGRzW2ldKSk7CisgICAgICBpZiAoZmllbGRfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgICAgfQorCisgICAgICBQeU9iamVjdCogZmllbGRfdmFsdWUgPSBHZXRBdHRyKHNlbGYsIHB5X2ZpZWxkX25hbWUpOworICAgICAgaWYgKGZpZWxkX3ZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0T2JqZWN0KFB5RXhjX1ZhbHVlRXJyb3IsIHB5X2ZpZWxkX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICAgIFB5VHVwbGVfU0VUX0lURU0odC5nZXQoKSwgMCwgZmllbGRfZGVzY3JpcHRvci5yZWxlYXNlKCkpOworICAgICAgUHlUdXBsZV9TRVRfSVRFTSh0LmdldCgpLCAxLCBmaWVsZF92YWx1ZSk7CisgICAgfQorICAgIFB5TGlzdF9TRVRfSVRFTShhbGxfZmllbGRzLmdldCgpLCBhY3R1YWxfc2l6ZSwgdC5yZWxlYXNlKCkpOworICAgICsrYWN0dWFsX3NpemU7CisgIH0KKyAgUHlfU0laRShhbGxfZmllbGRzLmdldCgpKSA9IGFjdHVhbF9zaXplOworICByZXR1cm4gYWxsX2ZpZWxkcy5yZWxlYXNlKCk7Cit9CisKK1B5T2JqZWN0KiBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoQ01lc3NhZ2UqIHNlbGYpIHsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgbWVzc2FnZS0+RmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCZlcnJvcnMpOworCisgIFB5T2JqZWN0KiBlcnJvcl9saXN0ID0gUHlMaXN0X05ldyhlcnJvcnMuc2l6ZSgpKTsKKyAgaWYgKGVycm9yX2xpc3QgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGZvciAoUHlfc3NpemVfdCBpID0gMDsgaSA8IGVycm9ycy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IHN0cmluZyYgZXJyb3IgPSBlcnJvcnNbaV07CisgICAgUHlPYmplY3QqIGVycm9yX3N0cmluZyA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgICBlcnJvci5jX3N0cigpLCBlcnJvci5sZW5ndGgoKSk7CisgICAgaWYgKGVycm9yX3N0cmluZyA9PSBOVUxMKSB7CisgICAgICBQeV9ERUNSRUYoZXJyb3JfbGlzdCk7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlMaXN0X1NFVF9JVEVNKGVycm9yX2xpc3QsIGksIGVycm9yX3N0cmluZyk7CisgIH0KKyAgcmV0dXJuIGVycm9yX2xpc3Q7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogUmljaENvbXBhcmUoQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBvdGhlciwgaW50IG9waWQpIHsKKyAgaWYgKCFQeU9iamVjdF9UeXBlQ2hlY2sob3RoZXIsICZDTWVzc2FnZV9UeXBlKSkgeworICAgIGlmIChvcGlkID09IFB5X0VRKSB7CisgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfSBlbHNlIGlmIChvcGlkID09IFB5X05FKSB7CisgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICB9CisgIH0KKyAgaWYgKG9waWQgPT0gUHlfRVEgfHwgb3BpZCA9PSBQeV9ORSkgeworICAgIFNjb3BlZFB5T2JqZWN0UHRyIHNlbGZfZmllbGRzKExpc3RGaWVsZHMoc2VsZikpOworICAgIGlmICghc2VsZl9maWVsZHMpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRQeU9iamVjdFB0ciBvdGhlcl9maWVsZHMoTGlzdEZpZWxkcygKKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KG90aGVyKSkpOworICAgIGlmICghb3RoZXJfZmllbGRzKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlKHNlbGZfZmllbGRzLCBvdGhlcl9maWVsZHMsIG9waWQpOworICB9IGVsc2UgeworICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICB9Cit9CisKK1B5T2JqZWN0KiBJbnRlcm5hbEdldFNjYWxhcigKKyAgICBDTWVzc2FnZSogc2VsZiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IpIHsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgaWYgKCFDaGVja0ZpZWxkQmVsb25nc1RvTWVzc2FnZShmaWVsZF9kZXNjcmlwdG9yLCBtZXNzYWdlKSkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgUHlPYmplY3QqIHJlc3VsdCA9IE5VTEw7CisgIHN3aXRjaCAoZmllbGRfZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOiB7CisgICAgICBpbnQzMiB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldEludDMyKCptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgICAgIHJlc3VsdCA9IFB5SW50X0Zyb21Mb25nKHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDogeworICAgICAgaW50NjQgdmFsdWUgPSByZWZsZWN0aW9uLT5HZXRJbnQ2NCgqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgICAgICByZXN1bHQgPSBQeUxvbmdfRnJvbUxvbmdMb25nKHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6IHsKKyAgICAgIHVpbnQzMiB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldFVJbnQzMigqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgICAgICByZXN1bHQgPSBQeUludF9Gcm9tU2l6ZV90KHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6IHsKKyAgICAgIHVpbnQ2NCB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldFVJbnQ2NCgqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgICAgICByZXN1bHQgPSBQeUxvbmdfRnJvbVVuc2lnbmVkTG9uZ0xvbmcodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOiB7CisgICAgICBmbG9hdCB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldEZsb2F0KCptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgICAgIHJlc3VsdCA9IFB5RmxvYXRfRnJvbURvdWJsZSh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSByZWZsZWN0aW9uLT5HZXREb3VibGUoKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IpOworICAgICAgcmVzdWx0ID0gUHlGbG9hdF9Gcm9tRG91YmxlKHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOiB7CisgICAgICBib29sIHZhbHVlID0gcmVmbGVjdGlvbi0+R2V0Qm9vbCgqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgICAgICByZXN1bHQgPSBQeUJvb2xfRnJvbUxvbmcodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgc3RyaW5nIHZhbHVlID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nKCptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgICAgIHJlc3VsdCA9IFRvU3RyaW5nT2JqZWN0KGZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOiB7CisgICAgICBpZiAoIW1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpICYmCisgICAgICAgICAgIW1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IpKSB7CisgICAgICAgIC8vIExvb2sgZm9yIHRoZSB2YWx1ZSBpbiB0aGUgdW5rbm93biBmaWVsZHMuCisgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZF9zZXQgPQorICAgICAgICAgICAgbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhtZXNzYWdlKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkX3NldC0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgICAgICAgaWYgKHVua25vd25fZmllbGRfc2V0LT5maWVsZChpKS5udW1iZXIoKSA9PQorICAgICAgICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLT5udW1iZXIoKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gUHlJbnRfRnJvbUxvbmcodW5rbm93bl9maWVsZF9zZXQtPmZpZWxkKGkpLnZhcmludCgpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEVudW0oKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IpOworICAgICAgICByZXN1bHQgPSBQeUludF9Gcm9tTG9uZyhlbnVtX3ZhbHVlLT5udW1iZXIoKSk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIFB5RXJyX0Zvcm1hdCgKKyAgICAgICAgICBQeUV4Y19TeXN0ZW1FcnJvciwgIkdldHRpbmcgYSB2YWx1ZSBmcm9tIGEgZmllbGQgb2YgdW5rbm93biB0eXBlICVkIiwKKyAgICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLT5jcHBfdHlwZSgpKTsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5T2JqZWN0KiBJbnRlcm5hbEdldFN1Yk1lc3NhZ2UoCisgICAgQ01lc3NhZ2UqIHNlbGYsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvcikgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gc2VsZi0+bWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICAqc2VsZi0+bWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgbWVzc2FnZV9mYWN0b3J5KTsKKworICBQeU9iamVjdCAqbWVzc2FnZV9jbGFzcyA9IGNkZXNjcmlwdG9yX3Bvb2w6OkdldE1lc3NhZ2VDbGFzcygKKyAgICAgIEdldERlc2NyaXB0b3JQb29sKCksIGZpZWxkX2Rlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgaWYgKG1lc3NhZ2VfY2xhc3MgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgQ01lc3NhZ2UqIGNtc2cgPSBjbWVzc2FnZTo6TmV3RW1wdHlNZXNzYWdlKG1lc3NhZ2VfY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJfbWVzc2FnZS5HZXREZXNjcmlwdG9yKCkpOworICBpZiAoY21zZyA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBjbXNnLT5vd25lciA9IHNlbGYtPm93bmVyOworICBjbXNnLT5wYXJlbnQgPSBzZWxmOworICBjbXNnLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvciA9IGZpZWxkX2Rlc2NyaXB0b3I7CisgIGNtc2ctPnJlYWRfb25seSA9ICFyZWZsZWN0aW9uLT5IYXNGaWVsZCgqc2VsZi0+bWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgIGNtc2ctPm1lc3NhZ2UgPSBjb25zdF9jYXN0PE1lc3NhZ2UqPigmc3ViX21lc3NhZ2UpOworCisgIHJldHVybiByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oY21zZyk7Cit9CisKK2ludCBJbnRlcm5hbFNldFNjYWxhcigKKyAgICBDTWVzc2FnZSogc2VsZiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IsCisgICAgUHlPYmplY3QqIGFyZykgeworICBNZXNzYWdlKiBtZXNzYWdlID0gc2VsZi0+bWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICBpZiAoIUNoZWNrRmllbGRCZWxvbmdzVG9NZXNzYWdlKGZpZWxkX2Rlc2NyaXB0b3IsIG1lc3NhZ2UpKSB7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgaWYgKE1heWJlUmVsZWFzZU92ZXJsYXBwaW5nT25lb2ZGaWVsZChzZWxmLCBmaWVsZF9kZXNjcmlwdG9yKSA8IDApIHsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICBzd2l0Y2ggKGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9JTlQzMihhcmcsIHZhbHVlLCAtMSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRJbnQzMihtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfSU5UNjQoYXJnLCB2YWx1ZSwgLTEpOworICAgICAgcmVmbGVjdGlvbi0+U2V0SW50NjQobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgdmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9VSU5UMzIoYXJnLCB2YWx1ZSwgLTEpOworICAgICAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfVUlOVDY0KGFyZywgdmFsdWUsIC0xKTsKKyAgICAgIHJlZmxlY3Rpb24tPlNldFVJbnQ2NChtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfRkxPQVQoYXJnLCB2YWx1ZSwgLTEpOworICAgICAgcmVmbGVjdGlvbi0+U2V0RmxvYXQobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgdmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRTogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9ET1VCTEUoYXJnLCB2YWx1ZSwgLTEpOworICAgICAgcmVmbGVjdGlvbi0+U2V0RG91YmxlKG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX0JPT0woYXJnLCB2YWx1ZSwgLTEpOworICAgICAgcmVmbGVjdGlvbi0+U2V0Qm9vbChtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICBpZiAoIUNoZWNrQW5kU2V0U3RyaW5nKAorICAgICAgICAgIGFyZywgbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgcmVmbGVjdGlvbiwgZmFsc2UsIC0xKSkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9JTlQzMihhcmcsIHZhbHVlLCAtMSk7CisgICAgICBpZiAocmVmbGVjdGlvbi0+U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpKSB7CisgICAgICAgIHJlZmxlY3Rpb24tPlNldEVudW1WYWx1ZShtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV9kZXNjcmlwdG9yID0gZmllbGRfZGVzY3JpcHRvci0+ZW51bV90eXBlKCk7CisgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPQorICAgICAgICAgICAgZW51bV9kZXNjcmlwdG9yLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgICAgICAgIGlmIChlbnVtX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICByZWZsZWN0aW9uLT5TZXRFbnVtKG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGVudW1fdmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLCAiVW5rbm93biBlbnVtIHZhbHVlOiAlZCIsIHZhbHVlKTsKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgUHlFcnJfRm9ybWF0KAorICAgICAgICAgIFB5RXhjX1N5c3RlbUVycm9yLCAiU2V0dGluZyB2YWx1ZSB0byBhIGZpZWxkIG9mIHVua25vd24gdHlwZSAlZCIsCisgICAgICAgICAgZmllbGRfZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSk7CisgICAgICByZXR1cm4gLTE7CisgIH0KKworICByZXR1cm4gMDsKK30KKworUHlPYmplY3QqIEZyb21TdHJpbmcoUHlUeXBlT2JqZWN0KiBjbHMsIFB5T2JqZWN0KiBzZXJpYWxpemVkKSB7CisgIFB5T2JqZWN0KiBweV9jbXNnID0gUHlPYmplY3RfQ2FsbE9iamVjdCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihjbHMpLCBOVUxMKTsKKyAgaWYgKHB5X2Ntc2cgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIENNZXNzYWdlKiBjbXNnID0gcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KHB5X2Ntc2cpOworCisgIFNjb3BlZFB5T2JqZWN0UHRyIHB5X2xlbmd0aChNZXJnZUZyb21TdHJpbmcoY21zZywgc2VyaWFsaXplZCkpOworICBpZiAocHlfbGVuZ3RoID09IE5VTEwpIHsKKyAgICBQeV9ERUNSRUYocHlfY21zZyk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICByZXR1cm4gcHlfY21zZzsKK30KKworLy8gQWRkIHRoZSBudW1iZXIgb2YgYSBmaWVsZCBkZXNjcmlwdG9yIHRvIHRoZSBjb250YWluaW5nIG1lc3NhZ2UgY2xhc3MuCisvLyBFcXVpdmFsZW50IHRvOgorLy8gICBfY2xzLjxmaWVsZD5fRklFTERfTlVNQkVSID0gPG51bWJlcj4KK3N0YXRpYyBib29sIEFkZEZpZWxkTnVtYmVyVG9DbGFzcygKKyAgICBQeU9iamVjdCogY2xzLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IpIHsKKyAgc3RyaW5nIGNvbnN0YW50X25hbWUgPSBmaWVsZF9kZXNjcmlwdG9yLT5uYW1lKCkgKyAiX0ZJRUxEX05VTUJFUiI7CisgIFVwcGVyU3RyaW5nKCZjb25zdGFudF9uYW1lKTsKKyAgU2NvcGVkUHlPYmplY3RQdHIgYXR0cl9uYW1lKFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgY29uc3RhbnRfbmFtZS5jX3N0cigpLCBjb25zdGFudF9uYW1lLnNpemUoKSkpOworICBpZiAoYXR0cl9uYW1lID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgbnVtYmVyKFB5SW50X0Zyb21Mb25nKGZpZWxkX2Rlc2NyaXB0b3ItPm51bWJlcigpKSk7CisgIGlmIChudW1iZXIgPT0gTlVMTCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoUHlPYmplY3RfU2V0QXR0cihjbHMsIGF0dHJfbmFtZSwgbnVtYmVyKSA9PSAtMSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworCisvLyBGaW5hbGl6ZSB0aGUgY3JlYXRpb24gb2YgdGhlIE1lc3NhZ2UgY2xhc3MuCisvLyBDYWxsZWQgZnJvbSBpdHMgbWV0YWNsYXNzOiBHZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlLl9faW5pdF9fKCkuCitzdGF0aWMgUHlPYmplY3QqIEFkZERlc2NyaXB0b3JzKFB5T2JqZWN0KiBjbHMsIFB5T2JqZWN0KiBkZXNjcmlwdG9yKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfZGVzY3JpcHRvciA9CisgICAgICBjZGVzY3JpcHRvcl9wb29sOjpSZWdpc3Rlck1lc3NhZ2VDbGFzcygKKyAgICAgICAgICBHZXREZXNjcmlwdG9yUG9vbCgpLCBjbHMsIGRlc2NyaXB0b3IpOworICBpZiAobWVzc2FnZV9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIC8vIElmIHRoZXJlIGFyZSBleHRlbnNpb25fcmFuZ2VzLCB0aGUgbWVzc2FnZSBpcyAiZXh0ZW5kYWJsZSIsIGFuZCBleHRlbnNpb24KKyAgLy8gY2xhc3NlcyB3aWxsIHJlZ2lzdGVyIHRoZW1zZWx2ZXMgaW4gdGhpcyBjbGFzcy4KKyAgaWYgKG1lc3NhZ2VfZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgU2NvcGVkUHlPYmplY3RQdHIgYnlfbmFtZShQeURpY3RfTmV3KCkpOworICAgIGlmIChQeU9iamVjdF9TZXRBdHRyKGNscywga19leHRlbnNpb25zX2J5X25hbWUsIGJ5X25hbWUpIDwgMCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFNjb3BlZFB5T2JqZWN0UHRyIGJ5X251bWJlcihQeURpY3RfTmV3KCkpOworICAgIGlmIChQeU9iamVjdF9TZXRBdHRyKGNscywga19leHRlbnNpb25zX2J5X251bWJlciwgYnlfbnVtYmVyKSA8IDApIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgfQorCisgIC8vIEZvciBlYWNoIGZpZWxkIHNldDogY2xzLjxmaWVsZD5fRklFTERfTlVNQkVSID0gPG51bWJlcj4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlX2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIGlmICghQWRkRmllbGROdW1iZXJUb0NsYXNzKGNscywgbWVzc2FnZV9kZXNjcmlwdG9yLT5maWVsZChpKSkpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgfQorCisgIC8vIEZvciBlYWNoIGVudW0gc2V0IGNscy48ZW51bSBuYW1lPiA9IEVudW1UeXBlV3JhcHBlcig8ZW51bSBkZXNjcmlwdG9yPikuCisgIC8vCisgIC8vIFRoZSBlbnVtIGRlc2NyaXB0b3Igd2UgZ2V0IGZyb20KKyAgLy8gPG1lc3NhZ2VkZXNjcmlwdG9yPi5lbnVtX3R5cGVzX2J5X25hbWVbbmFtZV0KKyAgLy8gd2hpY2ggd2FzIGJ1aWx0IHByZXZpb3VzbHkuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV9kZXNjcmlwdG9yLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fZGVzY3JpcHRvciA9IG1lc3NhZ2VfZGVzY3JpcHRvci0+ZW51bV90eXBlKGkpOworICAgIFNjb3BlZFB5T2JqZWN0UHRyIGVudW1fdHlwZShQeUVudW1EZXNjcmlwdG9yX05ldyhlbnVtX2Rlc2NyaXB0b3IpKTsKKyAgICBpZiAoZW51bV90eXBlID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgICB9CisgICAgLy8gQWRkIHdyYXBwZWQgZW51bSB0eXBlIHRvIG1lc3NhZ2UgY2xhc3MuCisgICAgU2NvcGVkUHlPYmplY3RQdHIgd3JhcHBlZChQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKAorICAgICAgICBFbnVtVHlwZVdyYXBwZXJfY2xhc3MsIGVudW1fdHlwZS5nZXQoKSwgTlVMTCkpOworICAgIGlmICh3cmFwcGVkID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoUHlPYmplY3RfU2V0QXR0clN0cmluZygKKyAgICAgICAgICAgIGNscywgZW51bV9kZXNjcmlwdG9yLT5uYW1lKCkuY19zdHIoKSwgd3JhcHBlZCkgPT0gLTEpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIEZvciBlYWNoIGVudW0gdmFsdWUgYWRkIGNscy48bmFtZT4gPSA8bnVtYmVyPgorICAgIGZvciAoaW50IGogPSAwOyBqIDwgZW51bV9kZXNjcmlwdG9yLT52YWx1ZV9jb3VudCgpOyArK2opIHsKKyAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgICAgZW51bV9kZXNjcmlwdG9yLT52YWx1ZShqKTsKKyAgICAgIFNjb3BlZFB5T2JqZWN0UHRyIHZhbHVlX251bWJlcihQeUludF9Gcm9tTG9uZygKKyAgICAgICAgICBlbnVtX3ZhbHVlX2Rlc2NyaXB0b3ItPm51bWJlcigpKSk7CisgICAgICBpZiAodmFsdWVfbnVtYmVyID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgICBpZiAoUHlPYmplY3RfU2V0QXR0clN0cmluZygKKyAgICAgICAgICAgICAgY2xzLCBlbnVtX3ZhbHVlX2Rlc2NyaXB0b3ItPm5hbWUoKS5jX3N0cigpLCB2YWx1ZV9udW1iZXIpID09IC0xKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIEZvciBlYWNoIGV4dGVuc2lvbiBzZXQgY2xzLjxleHRlbnNpb24gbmFtZT4gPSA8ZXh0ZW5zaW9uIGRlc2NyaXB0b3I+LgorICAvLworICAvLyBFeHRlbnNpb24gZGVzY3JpcHRvcnMgY29tZSBmcm9tCisgIC8vIDxtZXNzYWdlIGRlc2NyaXB0b3I+LmV4dGVuc2lvbnNfYnlfbmFtZVtuYW1lXQorICAvLyB3aGljaCB3YXMgZGVmaW5lZCBwcmV2aW91c2x5LgorICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VfZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBtZXNzYWdlX2Rlc2NyaXB0b3ItPmV4dGVuc2lvbihpKTsKKyAgICBTY29wZWRQeU9iamVjdFB0ciBleHRlbnNpb25fZmllbGQoUHlGaWVsZERlc2NyaXB0b3JfTmV3KGZpZWxkKSk7CisgICAgaWYgKGV4dGVuc2lvbl9maWVsZCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvLyBBZGQgdGhlIGV4dGVuc2lvbiBmaWVsZCB0byB0aGUgbWVzc2FnZSBjbGFzcy4KKyAgICBpZiAoUHlPYmplY3RfU2V0QXR0clN0cmluZygKKyAgICAgICAgICAgIGNscywgZmllbGQtPm5hbWUoKS5jX3N0cigpLCBleHRlbnNpb25fZmllbGQpID09IC0xKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvLyBGb3IgZWFjaCBleHRlbnNpb24gc2V0IGNscy48ZXh0ZW5zaW9uIG5hbWU+X0ZJRUxEX05VTUJFUiA9IDxudW1iZXI+LgorICAgIGlmICghQWRkRmllbGROdW1iZXJUb0NsYXNzKGNscywgZmllbGQpKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgIH0KKworICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlPYmplY3QqIERlZXBDb3B5KENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIFB5T2JqZWN0KiBjbG9uZSA9IFB5T2JqZWN0X0NhbGxPYmplY3QoCisgICAgICByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oUHlfVFlQRShzZWxmKSksIE5VTEwpOworICBpZiAoY2xvbmUgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmICghUHlPYmplY3RfVHlwZUNoZWNrKGNsb25lLCAmQ01lc3NhZ2VfVHlwZSkpIHsKKyAgICBQeV9ERUNSRUYoY2xvbmUpOworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChNZXJnZUZyb20ocmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KGNsb25lKSwKKyAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oc2VsZikpID09IE5VTEwpIHsKKyAgICBQeV9ERUNSRUYoY2xvbmUpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBjbG9uZTsKK30KKworUHlPYmplY3QqIFRvVW5pY29kZShDTWVzc2FnZSogc2VsZikgeworICAvLyBMYXp5IGltcG9ydCB0byBwcmV2ZW50IGNpcmN1bGFyIGRlcGVuZGVuY2llcworICBTY29wZWRQeU9iamVjdFB0ciB0ZXh0X2Zvcm1hdCgKKyAgICAgIFB5SW1wb3J0X0ltcG9ydE1vZHVsZSgiZ29vZ2xlLnByb3RvYnVmLnRleHRfZm9ybWF0IikpOworICBpZiAodGV4dF9mb3JtYXQgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFNjb3BlZFB5T2JqZWN0UHRyIG1ldGhvZF9uYW1lKFB5U3RyaW5nX0Zyb21TdHJpbmcoIk1lc3NhZ2VUb1N0cmluZyIpKTsKKyAgaWYgKG1ldGhvZF9uYW1lID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeV9JTkNSRUYoUHlfVHJ1ZSk7CisgIFNjb3BlZFB5T2JqZWN0UHRyIGVuY29kZWQoUHlPYmplY3RfQ2FsbE1ldGhvZE9iakFyZ3ModGV4dF9mb3JtYXQsIG1ldGhvZF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYsIFB5X1RydWUsIE5VTEwpKTsKKyAgUHlfREVDUkVGKFB5X1RydWUpOworICBpZiAoZW5jb2RlZCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyNpZiBQWV9NQUpPUl9WRVJTSU9OIDwgMworICBQeU9iamVjdCogZGVjb2RlZCA9IFB5U3RyaW5nX0FzRGVjb2RlZE9iamVjdChlbmNvZGVkLCAidXRmLTgiLCBOVUxMKTsKKyNlbHNlCisgIFB5T2JqZWN0KiBkZWNvZGVkID0gUHlVbmljb2RlX0Zyb21FbmNvZGVkT2JqZWN0KGVuY29kZWQsICJ1dGYtOCIsIE5VTEwpOworI2VuZGlmCisgIGlmIChkZWNvZGVkID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICByZXR1cm4gZGVjb2RlZDsKK30KKworUHlPYmplY3QqIFJlZHVjZShDTWVzc2FnZSogc2VsZikgeworICBTY29wZWRQeU9iamVjdFB0ciBjb25zdHJ1Y3RvcihyZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oUHlfVFlQRShzZWxmKSkpOworICBjb25zdHJ1Y3Rvci5pbmMoKTsKKyAgU2NvcGVkUHlPYmplY3RQdHIgYXJncyhQeVR1cGxlX05ldygwKSk7CisgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBTY29wZWRQeU9iamVjdFB0ciBzdGF0ZShQeURpY3RfTmV3KCkpOworICBpZiAoc3RhdGUgPT0gTlVMTCkgeworICAgIHJldHVybiAgTlVMTDsKKyAgfQorICBTY29wZWRQeU9iamVjdFB0ciBzZXJpYWxpemVkKFNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyhzZWxmKSk7CisgIGlmIChzZXJpYWxpemVkID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoUHlEaWN0X1NldEl0ZW1TdHJpbmcoc3RhdGUsICJzZXJpYWxpemVkIiwgc2VyaWFsaXplZCkgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIk9PTyIsIGNvbnN0cnVjdG9yLmdldCgpLCBhcmdzLmdldCgpLCBzdGF0ZS5nZXQoKSk7Cit9CisKK1B5T2JqZWN0KiBTZXRTdGF0ZShDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIHN0YXRlKSB7CisgIGlmICghUHlEaWN0X0NoZWNrKHN0YXRlKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJzdGF0ZSBub3QgYSBkaWN0Iik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgUHlPYmplY3QqIHNlcmlhbGl6ZWQgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhzdGF0ZSwgInNlcmlhbGl6ZWQiKTsKKyAgaWYgKHNlcmlhbGl6ZWQgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChQYXJzZUZyb21TdHJpbmcoc2VsZiwgc2VyaWFsaXplZCkgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5X1JFVFVSTl9OT05FOworfQorCisvLyBDTWVzc2FnZSBzdGF0aWMgbWV0aG9kczoKK1B5T2JqZWN0KiBfR2V0TWVzc2FnZURlc2NyaXB0b3IoUHlPYmplY3QqIHVudXNlZCwgUHlPYmplY3QqIGFyZykgeworICByZXR1cm4gY2Rlc2NyaXB0b3JfcG9vbDo6RmluZE1lc3NhZ2VCeU5hbWUoR2V0RGVzY3JpcHRvclBvb2woKSwgYXJnKTsKK30KKworUHlPYmplY3QqIF9HZXRGaWVsZERlc2NyaXB0b3IoUHlPYmplY3QqIHVudXNlZCwgUHlPYmplY3QqIGFyZykgeworICByZXR1cm4gY2Rlc2NyaXB0b3JfcG9vbDo6RmluZEZpZWxkQnlOYW1lKEdldERlc2NyaXB0b3JQb29sKCksIGFyZyk7Cit9CisKK1B5T2JqZWN0KiBfR2V0RXh0ZW5zaW9uRGVzY3JpcHRvcihQeU9iamVjdCogdW51c2VkLCBQeU9iamVjdCogYXJnKSB7CisgIHJldHVybiBjZGVzY3JpcHRvcl9wb29sOjpGaW5kRXh0ZW5zaW9uQnlOYW1lKEdldERlc2NyaXB0b3JQb29sKCksIGFyZyk7Cit9CisKK1B5T2JqZWN0KiBfR2V0RW51bURlc2NyaXB0b3IoUHlPYmplY3QqIHVudXNlZCwgUHlPYmplY3QqIGFyZykgeworICByZXR1cm4gY2Rlc2NyaXB0b3JfcG9vbDo6RmluZEVudW1UeXBlQnlOYW1lKEdldERlc2NyaXB0b3JQb29sKCksIGFyZyk7Cit9CisKK1B5T2JqZWN0KiBfR2V0T25lb2ZEZXNjcmlwdG9yKFB5T2JqZWN0KiB1bnVzZWQsIFB5T2JqZWN0KiBhcmcpIHsKKyAgcmV0dXJuIGNkZXNjcmlwdG9yX3Bvb2w6OkZpbmRPbmVvZkJ5TmFtZShHZXREZXNjcmlwdG9yUG9vbCgpLCBhcmcpOworfQorCitQeU9iamVjdCogX0NoZWNrQ2FsbGVkRnJvbUdlbmVyYXRlZEZpbGUoUHlPYmplY3QqIHVudXNlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogdW51c2VkX2FyZykgeworICBpZiAoIV9DYWxsZWRGcm9tR2VuZXJhdGVkRmlsZSgxKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJEZXNjcmlwdG9ycyBzaG91bGQgbm90IGJlIGNyZWF0ZWQgZGlyZWN0bHksICIKKyAgICAgICAgICAgICAgICAgICAgImJ1dCBvbmx5IHJldHJpZXZlZCBmcm9tIHRoZWlyIHBhcmVudC4iKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeV9SRVRVUk5fTk9ORTsKK30KKworc3RhdGljIFB5TWVtYmVyRGVmIE1lbWJlcnNbXSA9IHsKKyAgeyJFeHRlbnNpb25zIiwgVF9PQkpFQ1RfRVgsIG9mZnNldG9mKENNZXNzYWdlLCBleHRlbnNpb25zKSwgMCwKKyAgICJFeHRlbnNpb24gZGljdCJ9LAorICB7TlVMTH0KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBNZXRob2RzW10gPSB7CisgIHsgIl9fZGVlcGNvcHlfXyIsIChQeUNGdW5jdGlvbilEZWVwQ29weSwgTUVUSF9WQVJBUkdTLAorICAgICJNYWtlcyBhIGRlZXAgY29weSBvZiB0aGUgY2xhc3MuIiB9LAorICB7ICJfX3JlZHVjZV9fIiwgKFB5Q0Z1bmN0aW9uKVJlZHVjZSwgTUVUSF9OT0FSR1MsCisgICAgIk91dHB1dHMgcGlja2xhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlLiIgfSwKKyAgeyAiX19zZXRzdGF0ZV9fIiwgKFB5Q0Z1bmN0aW9uKVNldFN0YXRlLCBNRVRIX08sCisgICAgIklucHV0cyBwaWNrbGFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2UuIiB9LAorICB7ICJfX3VuaWNvZGVfXyIsIChQeUNGdW5jdGlvbilUb1VuaWNvZGUsIE1FVEhfTk9BUkdTLAorICAgICJPdXRwdXRzIGEgdW5pY29kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZS4iIH0sCisgIHsgIkFkZERlc2NyaXB0b3JzIiwgKFB5Q0Z1bmN0aW9uKUFkZERlc2NyaXB0b3JzLCBNRVRIX08gfCBNRVRIX0NMQVNTLAorICAgICJBZGRzIGZpZWxkIGRlc2NyaXB0b3JzIHRvIHRoZSBjbGFzcyIgfSwKKyAgeyAiQnl0ZVNpemUiLCAoUHlDRnVuY3Rpb24pQnl0ZVNpemUsIE1FVEhfTk9BUkdTLAorICAgICJSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBtZXNzYWdlIGluIGJ5dGVzLiIgfSwKKyAgeyAiQ2xlYXIiLCAoUHlDRnVuY3Rpb24pQ2xlYXIsIE1FVEhfTk9BUkdTLAorICAgICJDbGVhcnMgdGhlIG1lc3NhZ2UuIiB9LAorICB7ICJDbGVhckV4dGVuc2lvbiIsIChQeUNGdW5jdGlvbilDbGVhckV4dGVuc2lvbiwgTUVUSF9PLAorICAgICJDbGVhcnMgYSBtZXNzYWdlIGZpZWxkLiIgfSwKKyAgeyAiQ2xlYXJGaWVsZCIsIChQeUNGdW5jdGlvbilDbGVhckZpZWxkLCBNRVRIX08sCisgICAgIkNsZWFycyBhIG1lc3NhZ2UgZmllbGQuIiB9LAorICB7ICJDb3B5RnJvbSIsIChQeUNGdW5jdGlvbilDb3B5RnJvbSwgTUVUSF9PLAorICAgICJDb3BpZXMgYSBwcm90b2NvbCBtZXNzYWdlIGludG8gdGhlIGN1cnJlbnQgbWVzc2FnZS4iIH0sCisgIHsgIkZpbmRJbml0aWFsaXphdGlvbkVycm9ycyIsIChQeUNGdW5jdGlvbilGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMsCisgICAgTUVUSF9OT0FSR1MsCisgICAgIkZpbmRzIHVuc2V0IHJlcXVpcmVkIGZpZWxkcy4iIH0sCisgIHsgIkZyb21TdHJpbmciLCAoUHlDRnVuY3Rpb24pRnJvbVN0cmluZywgTUVUSF9PIHwgTUVUSF9DTEFTUywKKyAgICAiQ3JlYXRlcyBuZXcgbWV0aG9kIGluc3RhbmNlIGZyb20gZ2l2ZW4gc2VyaWFsaXplZCBkYXRhLiIgfSwKKyAgeyAiSGFzRXh0ZW5zaW9uIiwgKFB5Q0Z1bmN0aW9uKUhhc0V4dGVuc2lvbiwgTUVUSF9PLAorICAgICJDaGVja3MgaWYgYSBtZXNzYWdlIGZpZWxkIGlzIHNldC4iIH0sCisgIHsgIkhhc0ZpZWxkIiwgKFB5Q0Z1bmN0aW9uKUhhc0ZpZWxkLCBNRVRIX08sCisgICAgIkNoZWNrcyBpZiBhIG1lc3NhZ2UgZmllbGQgaXMgc2V0LiIgfSwKKyAgeyAiSXNJbml0aWFsaXplZCIsIChQeUNGdW5jdGlvbilJc0luaXRpYWxpemVkLCBNRVRIX1ZBUkFSR1MsCisgICAgIkNoZWNrcyBpZiBhbGwgcmVxdWlyZWQgZmllbGRzIG9mIGEgcHJvdG9jb2wgbWVzc2FnZSBhcmUgc2V0LiIgfSwKKyAgeyAiTGlzdEZpZWxkcyIsIChQeUNGdW5jdGlvbilMaXN0RmllbGRzLCBNRVRIX05PQVJHUywKKyAgICAiTGlzdHMgYWxsIHNldCBmaWVsZHMgb2YgYSBtZXNzYWdlLiIgfSwKKyAgeyAiTWVyZ2VGcm9tIiwgKFB5Q0Z1bmN0aW9uKU1lcmdlRnJvbSwgTUVUSF9PLAorICAgICJNZXJnZXMgYSBwcm90b2NvbCBtZXNzYWdlIGludG8gdGhlIGN1cnJlbnQgbWVzc2FnZS4iIH0sCisgIHsgIk1lcmdlRnJvbVN0cmluZyIsIChQeUNGdW5jdGlvbilNZXJnZUZyb21TdHJpbmcsIE1FVEhfTywKKyAgICAiTWVyZ2VzIGEgc2VyaWFsaXplZCBtZXNzYWdlIGludG8gdGhlIGN1cnJlbnQgbWVzc2FnZS4iIH0sCisgIHsgIlBhcnNlRnJvbVN0cmluZyIsIChQeUNGdW5jdGlvbilQYXJzZUZyb21TdHJpbmcsIE1FVEhfTywKKyAgICAiUGFyc2VzIGEgc2VyaWFsaXplZCBtZXNzYWdlIGludG8gdGhlIGN1cnJlbnQgbWVzc2FnZS4iIH0sCisgIHsgIlJlZ2lzdGVyRXh0ZW5zaW9uIiwgKFB5Q0Z1bmN0aW9uKVJlZ2lzdGVyRXh0ZW5zaW9uLCBNRVRIX08gfCBNRVRIX0NMQVNTLAorICAgICJSZWdpc3RlcnMgYW4gZXh0ZW5zaW9uIHdpdGggdGhlIGN1cnJlbnQgbWVzc2FnZS4iIH0sCisgIHsgIlNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyIsIChQeUNGdW5jdGlvbilTZXJpYWxpemVQYXJ0aWFsVG9TdHJpbmcsCisgICAgTUVUSF9OT0FSR1MsCisgICAgIlNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgdG8gYSBzdHJpbmcsIGV2ZW4gaWYgaXQgaXNuJ3QgaW5pdGlhbGl6ZWQuIiB9LAorICB7ICJTZXJpYWxpemVUb1N0cmluZyIsIChQeUNGdW5jdGlvbilTZXJpYWxpemVUb1N0cmluZywgTUVUSF9OT0FSR1MsCisgICAgIlNlcmlhbGl6ZXMgdGhlIG1lc3NhZ2UgdG8gYSBzdHJpbmcsIG9ubHkgZm9yIGluaXRpYWxpemVkIG1lc3NhZ2VzLiIgfSwKKyAgeyAiU2V0SW5QYXJlbnQiLCAoUHlDRnVuY3Rpb24pU2V0SW5QYXJlbnQsIE1FVEhfTk9BUkdTLAorICAgICJTZXRzIHRoZSBoYXMgYml0IG9mIHRoZSBnaXZlbiBmaWVsZCBpbiBpdHMgcGFyZW50IG1lc3NhZ2UuIiB9LAorICB7ICJXaGljaE9uZW9mIiwgKFB5Q0Z1bmN0aW9uKVdoaWNoT25lb2YsIE1FVEhfTywKKyAgICAiUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZmllbGQgc2V0IGluc2lkZSBhIG9uZW9mLCAiCisgICAgIm9yIE5vbmUgaWYgbm8gZmllbGQgaXMgc2V0LiIgfSwKKworICAvLyBTdGF0aWMgTWV0aG9kcy4KKyAgeyAiX0J1aWxkRmlsZSIsIChQeUNGdW5jdGlvbilQeXRob25fQnVpbGRGaWxlLCBNRVRIX08gfCBNRVRIX1NUQVRJQywKKyAgICAiUmVnaXN0ZXJzIGEgbmV3IHByb3RvY29sIGJ1ZmZlciBmaWxlIGluIHRoZSBnbG9iYWwgQysrIGRlc2NyaXB0b3IgcG9vbC4iIH0sCisgIHsgIl9HZXRNZXNzYWdlRGVzY3JpcHRvciIsIChQeUNGdW5jdGlvbilfR2V0TWVzc2FnZURlc2NyaXB0b3IsCisgICAgTUVUSF9PIHwgTUVUSF9TVEFUSUMsICJGaW5kcyBhIG1lc3NhZ2UgZGVzY3JpcHRvciBpbiB0aGUgbWVzc2FnZSBwb29sLiIgfSwKKyAgeyAiX0dldEZpZWxkRGVzY3JpcHRvciIsIChQeUNGdW5jdGlvbilfR2V0RmllbGREZXNjcmlwdG9yLAorICAgIE1FVEhfTyB8IE1FVEhfU1RBVElDLCAiRmluZHMgYSBmaWVsZCBkZXNjcmlwdG9yIGluIHRoZSBtZXNzYWdlIHBvb2wuIiB9LAorICB7ICJfR2V0RXh0ZW5zaW9uRGVzY3JpcHRvciIsIChQeUNGdW5jdGlvbilfR2V0RXh0ZW5zaW9uRGVzY3JpcHRvciwKKyAgICBNRVRIX08gfCBNRVRIX1NUQVRJQywKKyAgICAiRmluZHMgYSBleHRlbnNpb24gZGVzY3JpcHRvciBpbiB0aGUgbWVzc2FnZSBwb29sLiIgfSwKKyAgeyAiX0dldEVudW1EZXNjcmlwdG9yIiwgKFB5Q0Z1bmN0aW9uKV9HZXRFbnVtRGVzY3JpcHRvciwKKyAgICBNRVRIX08gfCBNRVRIX1NUQVRJQywKKyAgICAiRmluZHMgYW4gZW51bSBkZXNjcmlwdG9yIGluIHRoZSBtZXNzYWdlIHBvb2wuIiB9LAorICB7ICJfR2V0T25lb2ZEZXNjcmlwdG9yIiwgKFB5Q0Z1bmN0aW9uKV9HZXRPbmVvZkRlc2NyaXB0b3IsCisgICAgTUVUSF9PIHwgTUVUSF9TVEFUSUMsCisgICAgIkZpbmRzIGFuIG9uZW9mIGRlc2NyaXB0b3IgaW4gdGhlIG1lc3NhZ2UgcG9vbC4iIH0sCisgIHsgIl9DaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlIiwgKFB5Q0Z1bmN0aW9uKV9DaGVja0NhbGxlZEZyb21HZW5lcmF0ZWRGaWxlLAorICAgIE1FVEhfTk9BUkdTIHwgTUVUSF9TVEFUSUMsCisgICAgIlJhaXNlcyBUeXBlRXJyb3IgaWYgdGhlIGNhbGxlciBpcyBub3QgaW4gYSBfcGIyLnB5IGZpbGUuIn0sCisgIHsgTlVMTCwgTlVMTH0KK307CisKK3N0YXRpYyBib29sIFNldENvbXBvc2l0ZUZpZWxkKAorICAgIENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogbmFtZSwgUHlPYmplY3QqIHZhbHVlKSB7CisgIGlmIChzZWxmLT5jb21wb3NpdGVfZmllbGRzID09IE5VTEwpIHsKKyAgICBzZWxmLT5jb21wb3NpdGVfZmllbGRzID0gUHlEaWN0X05ldygpOworICAgIGlmIChzZWxmLT5jb21wb3NpdGVfZmllbGRzID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIFB5RGljdF9TZXRJdGVtKHNlbGYtPmNvbXBvc2l0ZV9maWVsZHMsIG5hbWUsIHZhbHVlKSA9PSAwOworfQorCitQeU9iamVjdCogR2V0QXR0cihDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIG5hbWUpIHsKKyAgUHlPYmplY3QqIHZhbHVlID0gc2VsZi0+Y29tcG9zaXRlX2ZpZWxkcyA/CisgICAgICBQeURpY3RfR2V0SXRlbShzZWxmLT5jb21wb3NpdGVfZmllbGRzLCBuYW1lKSA6IE5VTEw7CisgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgUHlfSU5DUkVGKHZhbHVlKTsKKyAgICByZXR1cm4gdmFsdWU7CisgIH0KKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IgPSBHZXRGaWVsZERlc2NyaXB0b3Ioc2VsZiwgbmFtZSk7CisgIGlmIChmaWVsZF9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICByZXR1cm4gQ01lc3NhZ2VfVHlwZS50cF9iYXNlLT50cF9nZXRhdHRybygKKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYpLCBuYW1lKTsKKyAgfQorCisgIGlmIChmaWVsZF9kZXNjcmlwdG9yLT5sYWJlbCgpID09IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQpIHsKKyAgICBQeU9iamVjdCogcHlfY29udGFpbmVyID0gTlVMTDsKKyAgICBpZiAoZmllbGRfZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgUHlPYmplY3QgKm1lc3NhZ2VfY2xhc3MgPSBjZGVzY3JpcHRvcl9wb29sOjpHZXRNZXNzYWdlQ2xhc3MoCisgICAgICAgICAgR2V0RGVzY3JpcHRvclBvb2woKSwgZmllbGRfZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCkpOworICAgICAgaWYgKG1lc3NhZ2VfY2xhc3MgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICAgIHB5X2NvbnRhaW5lciA9IHJlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXI6Ok5ld0NvbnRhaW5lcigKKyAgICAgICAgICBzZWxmLCBmaWVsZF9kZXNjcmlwdG9yLCBtZXNzYWdlX2NsYXNzKTsKKyAgICB9IGVsc2UgeworICAgICAgcHlfY29udGFpbmVyID0gcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lcjo6TmV3Q29udGFpbmVyKAorICAgICAgICAgIHNlbGYsIGZpZWxkX2Rlc2NyaXB0b3IpOworICAgIH0KKyAgICBpZiAocHlfY29udGFpbmVyID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIVNldENvbXBvc2l0ZUZpZWxkKHNlbGYsIG5hbWUsIHB5X2NvbnRhaW5lcikpIHsKKyAgICAgIFB5X0RFQ1JFRihweV9jb250YWluZXIpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBweV9jb250YWluZXI7CisgIH0KKworICBpZiAoZmllbGRfZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIFB5T2JqZWN0KiBzdWJfbWVzc2FnZSA9IEludGVybmFsR2V0U3ViTWVzc2FnZShzZWxmLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgICBpZiAoIVNldENvbXBvc2l0ZUZpZWxkKHNlbGYsIG5hbWUsIHN1Yl9tZXNzYWdlKSkgeworICAgICAgUHlfREVDUkVGKHN1Yl9tZXNzYWdlKTsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gc3ViX21lc3NhZ2U7CisgIH0KKworICByZXR1cm4gSW50ZXJuYWxHZXRTY2FsYXIoc2VsZiwgZmllbGRfZGVzY3JpcHRvcik7Cit9CisKK2ludCBTZXRBdHRyKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogbmFtZSwgUHlPYmplY3QqIHZhbHVlKSB7CisgIGlmIChzZWxmLT5jb21wb3NpdGVfZmllbGRzICYmIFB5RGljdF9Db250YWlucyhzZWxmLT5jb21wb3NpdGVfZmllbGRzLCBuYW1lKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJDYW4ndCBzZXQgY29tcG9zaXRlIGZpZWxkIik7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yID0gR2V0RmllbGREZXNjcmlwdG9yKHNlbGYsIG5hbWUpOworICBpZiAoZmllbGRfZGVzY3JpcHRvciAhPSBOVUxMKSB7CisgICAgQXNzdXJlV3JpdGFibGUoc2VsZik7CisgICAgaWYgKGZpZWxkX2Rlc2NyaXB0b3ItPmxhYmVsKCkgPT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCkgeworICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0F0dHJpYnV0ZUVycm9yLCAiQXNzaWdubWVudCBub3QgYWxsb3dlZCB0byByZXBlYXRlZCAiCisgICAgICAgICAgICAgICAgICAgImZpZWxkIFwiJXNcIiBpbiBwcm90b2NvbCBtZXNzYWdlIG9iamVjdC4iLAorICAgICAgICAgICAgICAgICAgIGZpZWxkX2Rlc2NyaXB0b3ItPm5hbWUoKS5jX3N0cigpKTsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0F0dHJpYnV0ZUVycm9yLCAiQXNzaWdubWVudCBub3QgYWxsb3dlZCB0byAiCisgICAgICAgICAgICAgICAgICAgICAiZmllbGQgXCIlc1wiIGluIHByb3RvY29sIG1lc3NhZ2Ugb2JqZWN0LiIsCisgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLT5uYW1lKCkuY19zdHIoKSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBJbnRlcm5hbFNldFNjYWxhcihzZWxmLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgUHlFcnJfRm9ybWF0KFB5RXhjX0F0dHJpYnV0ZUVycm9yLCAiQXNzaWdubWVudCBub3QgYWxsb3dlZCIpOworICByZXR1cm4gLTE7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjbWVzc2FnZQorCitQeVR5cGVPYmplY3QgQ01lc3NhZ2VfVHlwZSA9IHsKKyAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgLy8gS2VlcCB0aGUgZnVsbHkgcXVhbGlmaWVkIF9tZXNzYWdlIHN5bWJvbCBpbiBhIGxpbmUgZm9yIG9wZW5zb3VyY2UuCisgICJnb29nbGUucHJvdG9idWYucHlleHQuX21lc3NhZ2UuIgorICAiQ01lc3NhZ2UiLCAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHBfbmFtZQorICBzaXplb2YoQ01lc3NhZ2UpLCAgICAgICAgICAgICAgICAgICAgLy8gdHBfYmFzaWNzaXplCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfaXRlbXNpemUKKyAgKGRlc3RydWN0b3IpY21lc3NhZ2U6OkRlYWxsb2MsICAgICAgIC8vICB0cF9kZWFsbG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfcHJpbnQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9nZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfc2V0YXR0cgorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2NvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9yZXByCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfYXNfbnVtYmVyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfYXNfc2VxdWVuY2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9hc19tYXBwaW5nCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfaGFzaAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2NhbGwKKyAgKHJlcHJmdW5jKWNtZXNzYWdlOjpUb1N0ciwgICAgICAgICAgIC8vICB0cF9zdHIKKyAgKGdldGF0dHJvZnVuYyljbWVzc2FnZTo6R2V0QXR0ciwgICAgIC8vICB0cF9nZXRhdHRybworICAoc2V0YXR0cm9mdW5jKWNtZXNzYWdlOjpTZXRBdHRyLCAgICAgLy8gIHRwX3NldGF0dHJvCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfYXNfYnVmZmVyCisgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfQkFTRVRZUEUsICAvLyAgdHBfZmxhZ3MKKyAgIkEgUHJvdG9jb2xNZXNzYWdlIiwgICAgICAgICAgICAgICAgIC8vICB0cF9kb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF90cmF2ZXJzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2NsZWFyCisgIChyaWNoY21wZnVuYyljbWVzc2FnZTo6UmljaENvbXBhcmUsICAvLyAgdHBfcmljaGNvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF93ZWFrbGlzdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2l0ZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9pdGVybmV4dAorICBjbWVzc2FnZTo6TWV0aG9kcywgICAgICAgICAgICAgICAgICAgLy8gIHRwX21ldGhvZHMKKyAgY21lc3NhZ2U6Ok1lbWJlcnMsICAgICAgICAgICAgICAgICAgIC8vICB0cF9tZW1iZXJzCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZ2V0c2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfYmFzZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2RpY3QKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9kZXNjcl9nZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9kZXNjcl9zZXQKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9kaWN0b2Zmc2V0CisgIChpbml0cHJvYyljbWVzc2FnZTo6SW5pdCwgICAgICAgICAgICAvLyAgdHBfaW5pdAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2FsbG9jCisgIGNtZXNzYWdlOjpOZXcsICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfbmV3Cit9OworCisvLyAtLS0gRXhwb3NpbmcgdGhlIEMgcHJvdG8gbGl2aW5nIGluc2lkZSBQeXRob24gcHJvdG8gdG8gQyBjb2RlOgorCitjb25zdCBNZXNzYWdlKiAoKkdldENQcm90b0luc2lkZVB5UHJvdG9QdHIpKFB5T2JqZWN0KiBtc2cpOworTWVzc2FnZSogKCpNdXRhYmxlQ1Byb3RvSW5zaWRlUHlQcm90b1B0cikoUHlPYmplY3QqIG1zZyk7CisKK3N0YXRpYyBjb25zdCBNZXNzYWdlKiBHZXRDUHJvdG9JbnNpZGVQeVByb3RvSW1wbChQeU9iamVjdCogbXNnKSB7CisgIGlmICghUHlPYmplY3RfVHlwZUNoZWNrKG1zZywgJkNNZXNzYWdlX1R5cGUpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgQ01lc3NhZ2UqIGNtc2cgPSByZWludGVycHJldF9jYXN0PENNZXNzYWdlKj4obXNnKTsKKyAgcmV0dXJuIGNtc2ctPm1lc3NhZ2U7Cit9CisKK3N0YXRpYyBNZXNzYWdlKiBNdXRhYmxlQ1Byb3RvSW5zaWRlUHlQcm90b0ltcGwoUHlPYmplY3QqIG1zZykgeworICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhtc2csICZDTWVzc2FnZV9UeXBlKSkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIENNZXNzYWdlKiBjbXNnID0gcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KG1zZyk7CisgIGlmICgoY21zZy0+Y29tcG9zaXRlX2ZpZWxkcyAmJiBQeURpY3RfU2l6ZShjbXNnLT5jb21wb3NpdGVfZmllbGRzKSAhPSAwKSB8fAorICAgICAgKGNtc2ctPmV4dGVuc2lvbnMgIT0gTlVMTCAmJgorICAgICAgIFB5RGljdF9TaXplKGNtc2ctPmV4dGVuc2lvbnMtPnZhbHVlcykgIT0gMCkpIHsKKyAgICAvLyBUaGVyZSBpcyBjdXJyZW50bHkgbm8gd2F5IG9mIGFjY3VyYXRlbHkgc3luY2luZyBhcmJpdHJhcnkgY2hhbmdlcyB0bworICAgIC8vIHRoZSB1bmRlcmx5aW5nIEMrKyBtZXNzYWdlIGJhY2sgdG8gdGhlIENNZXNzYWdlIChlLmcuIHJlbW92ZWQgcmVwZWF0ZWQKKyAgICAvLyBjb21wb3NpdGUgY29udGFpbmVycykuIFdlIG9ubHkgYWxsb3cgZGlyZWN0IG11dGF0aW9uIG9mIHRoZSB1bmRlcmx5aW5nCisgICAgLy8gQysrIG1lc3NhZ2UgaWYgdGhlcmUgaXMgbm8gY2hpbGQgZGF0YSBpbiB0aGUgQ01lc3NhZ2UuCisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgY21lc3NhZ2U6OkFzc3VyZVdyaXRhYmxlKGNtc2cpOworICByZXR1cm4gY21zZy0+bWVzc2FnZTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIgbW9kdWxlX2RvY3N0cmluZ1tdID0KKyJweXRob24tcHJvdG8yIGlzIGEgbW9kdWxlIHRoYXQgY2FuIGJlIHVzZWQgdG8gZW5oYW5jZSBwcm90bzIgUHl0aG9uIEFQSVxuIgorInBlcmZvcm1hbmNlLlxuIgorIlxuIgorIkl0IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgcHJvdG9jb2wgYnVmZmVycyBDKysgcmVmbGVjdGlvbiBBUEkgdGhhdFxuIgorImltcGxlbWVudHMgdGhlIGJhc2ljIHByb3RvY29sIGJ1ZmZlciBmdW5jdGlvbnMuIjsKKwordm9pZCBJbml0R2xvYmFscygpIHsKKyAgLy8gVE9ETyhncHMpOiBDaGVjayBhbGwgcmV0dXJuIHZhbHVlcyBpbiB0aGlzIGZ1bmN0aW9uIGZvciBOVUxMIGFuZCBwcm9wYWdhdGUKKyAgLy8gdGhlIGVycm9yIChNZW1vcnlFcnJvcikgb24gdXAgdG8gcmVzdWx0IGluIGFuIGltcG9ydCBmYWlsdXJlLiAgVGhlc2Ugc2hvdWxkCisgIC8vIGFsc28gYmUgZnJlZWQgYW5kIHJlc2V0IHRvIE5VTEwgZHVyaW5nIGZpbmFsaXphdGlvbi4KKyAga1B5dGhvblplcm8gPSBQeUludF9Gcm9tTG9uZygwKTsKKyAga2ludDMybWluX3B5ID0gUHlJbnRfRnJvbUxvbmcoa2ludDMybWluKTsKKyAga2ludDMybWF4X3B5ID0gUHlJbnRfRnJvbUxvbmcoa2ludDMybWF4KTsKKyAga3VpbnQzMm1heF9weSA9IFB5TG9uZ19Gcm9tTG9uZ0xvbmcoa3VpbnQzMm1heCk7CisgIGtpbnQ2NG1pbl9weSA9IFB5TG9uZ19Gcm9tTG9uZ0xvbmcoa2ludDY0bWluKTsKKyAga2ludDY0bWF4X3B5ID0gUHlMb25nX0Zyb21Mb25nTG9uZyhraW50NjRtYXgpOworICBrdWludDY0bWF4X3B5ID0gUHlMb25nX0Zyb21VbnNpZ25lZExvbmdMb25nKGt1aW50NjRtYXgpOworCisgIGtERVNDUklQVE9SID0gUHlTdHJpbmdfRnJvbVN0cmluZygiREVTQ1JJUFRPUiIpOworICBrX2NkZXNjcmlwdG9yID0gUHlTdHJpbmdfRnJvbVN0cmluZygiX2NkZXNjcmlwdG9yIik7CisgIGtmdWxsX25hbWUgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJmdWxsX25hbWUiKTsKKyAga19leHRlbnNpb25zX2J5X25hbWUgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJfZXh0ZW5zaW9uc19ieV9uYW1lIik7CisgIGtfZXh0ZW5zaW9uc19ieV9udW1iZXIgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJfZXh0ZW5zaW9uc19ieV9udW1iZXIiKTsKKworICBtZXNzYWdlX2ZhY3RvcnkgPSBuZXcgRHluYW1pY01lc3NhZ2VGYWN0b3J5KEdldERlc2NyaXB0b3JQb29sKCktPnBvb2wpOworICBtZXNzYWdlX2ZhY3RvcnktPlNldERlbGVnYXRlVG9HZW5lcmF0ZWRGYWN0b3J5KHRydWUpOworfQorCitib29sIEluaXRQcm90bzJNZXNzYWdlTW9kdWxlKFB5T2JqZWN0ICptKSB7CisgIC8vIEluaXRpYWxpemUgdHlwZXMgYW5kIGdsb2JhbHMgaW4gZGVzY3JpcHRvci5jYworICBpZiAoIUluaXREZXNjcmlwdG9yKCkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBJbml0aWFsaXplIHR5cGVzIGFuZCBnbG9iYWxzIGluIGRlc2NyaXB0b3JfcG9vbC5jYworICBpZiAoIUluaXREZXNjcmlwdG9yUG9vbCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gSW5pdGlhbGl6ZSBjb25zdGFudHMgZGVmaW5lZCBpbiB0aGlzIGZpbGUuCisgIEluaXRHbG9iYWxzKCk7CisKKyAgQ01lc3NhZ2VfVHlwZS50cF9oYXNoID0gUHlPYmplY3RfSGFzaE5vdEltcGxlbWVudGVkOworICBpZiAoUHlUeXBlX1JlYWR5KCZDTWVzc2FnZV9UeXBlKSA8IDApIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBERVNDUklQVE9SIGlzIHNldCBvbiBlYWNoIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlIGNsYXNzIGVsc2V3aGVyZSwgYnV0IHNldAorICAvLyBpdCBoZXJlIGFzIHdlbGwgdG8gZG9jdW1lbnQgdGhhdCBzdWJjbGFzc2VzIG5lZWQgdG8gc2V0IGl0LgorICBQeURpY3RfU2V0SXRlbShDTWVzc2FnZV9UeXBlLnRwX2RpY3QsIGtERVNDUklQVE9SLCBQeV9Ob25lKTsKKyAgLy8gU3ViY2xhc3NlcyB3aXRoIG1lc3NhZ2UgZXh0ZW5zaW9ucyB3aWxsIG92ZXJyaWRlIF9leHRlbnNpb25zX2J5X25hbWUgYW5kCisgIC8vIF9leHRlbnNpb25zX2J5X251bWJlciB3aXRoIGZyZXNoIG11dGFibGUgZGljdGlvbmFyaWVzIGluIEFkZERlc2NyaXB0b3JzLgorICAvLyBBbGwgb3RoZXIgY2xhc3NlcyBjYW4gc2hhcmUgdGhpcyBzYW1lIGltbXV0YWJsZSBtYXBwaW5nLgorICBTY29wZWRQeU9iamVjdFB0ciBlbXB0eV9kaWN0KFB5RGljdF9OZXcoKSk7CisgIGlmIChlbXB0eV9kaWN0ID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgaW1tdXRhYmxlX2RpY3QoUHlEaWN0UHJveHlfTmV3KGVtcHR5X2RpY3QpKTsKKyAgaWYgKGltbXV0YWJsZV9kaWN0ID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKFB5RGljdF9TZXRJdGVtKENNZXNzYWdlX1R5cGUudHBfZGljdCwKKyAgICAgICAgICAgICAgICAgICAgIGtfZXh0ZW5zaW9uc19ieV9uYW1lLCBpbW11dGFibGVfZGljdCkgPCAwKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChQeURpY3RfU2V0SXRlbShDTWVzc2FnZV9UeXBlLnRwX2RpY3QsCisgICAgICAgICAgICAgICAgICAgICBrX2V4dGVuc2lvbnNfYnlfbnVtYmVyLCBpbW11dGFibGVfZGljdCkgPCAwKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJNZXNzYWdlIiwgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KCZDTWVzc2FnZV9UeXBlKSk7CisKKyAgUmVwZWF0ZWRTY2FsYXJDb250YWluZXJfVHlwZS50cF9oYXNoID0KKyAgICAgIFB5T2JqZWN0X0hhc2hOb3RJbXBsZW1lbnRlZDsKKyAgaWYgKFB5VHlwZV9SZWFkeSgmUmVwZWF0ZWRTY2FsYXJDb250YWluZXJfVHlwZSkgPCAwKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJSZXBlYXRlZFNjYWxhckNvbnRhaW5lciIsCisgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oCisgICAgICAgICAgICAgICAgICAgICAgICAgJlJlcGVhdGVkU2NhbGFyQ29udGFpbmVyX1R5cGUpKTsKKworICBSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lcl9UeXBlLnRwX2hhc2ggPSBQeU9iamVjdF9IYXNoTm90SW1wbGVtZW50ZWQ7CisgIGlmIChQeVR5cGVfUmVhZHkoJlJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyX1R5cGUpIDwgMCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIFB5TW9kdWxlX0FkZE9iamVjdCgKKyAgICAgIG0sICJSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciIsCisgICAgICByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oCisgICAgICAgICAgJlJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyX1R5cGUpKTsKKworICBFeHRlbnNpb25EaWN0X1R5cGUudHBfaGFzaCA9IFB5T2JqZWN0X0hhc2hOb3RJbXBsZW1lbnRlZDsKKyAgaWYgKFB5VHlwZV9SZWFkeSgmRXh0ZW5zaW9uRGljdF9UeXBlKSA8IDApIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBQeU1vZHVsZV9BZGRPYmplY3QoCisgICAgICBtLCAiRXh0ZW5zaW9uRGljdCIsCisgICAgICByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oJkV4dGVuc2lvbkRpY3RfVHlwZSkpOworCisgIC8vIFRoaXMgaW1wbGVtZW50YXRpb24gcHJvdmlkZXMgZnVsbCBEZXNjcmlwdG9yIHR5cGVzLCB3ZSBhZHZlcnRpc2UgaXQgc28gdGhhdAorICAvLyBkZXNjcmlwdG9yLnB5IGNhbiB1c2UgdGhlbSBpbiByZXBsYWNlbWVudCBvZiB0aGUgUHl0aG9uIGNsYXNzZXMuCisgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJfVVNFX0NfREVTQ1JJUFRPUlMiLCAxKTsKKworICBQeU1vZHVsZV9BZGRPYmplY3QobSwgIkRlc2NyaXB0b3IiLCByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oCisgICAgICAmUHlNZXNzYWdlRGVzY3JpcHRvcl9UeXBlKSk7CisgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAiRmllbGREZXNjcmlwdG9yIiwgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KAorICAgICAgJlB5RmllbGREZXNjcmlwdG9yX1R5cGUpKTsKKyAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJFbnVtRGVzY3JpcHRvciIsIHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPigKKyAgICAgICZQeUVudW1EZXNjcmlwdG9yX1R5cGUpKTsKKyAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJFbnVtVmFsdWVEZXNjcmlwdG9yIiwgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KAorICAgICAgJlB5RW51bVZhbHVlRGVzY3JpcHRvcl9UeXBlKSk7CisgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAiRmlsZURlc2NyaXB0b3IiLCByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oCisgICAgICAmUHlGaWxlRGVzY3JpcHRvcl9UeXBlKSk7CisgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAiT25lb2ZEZXNjcmlwdG9yIiwgcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KAorICAgICAgJlB5T25lb2ZEZXNjcmlwdG9yX1R5cGUpKTsKKworICBQeU9iamVjdCogZW51bV90eXBlX3dyYXBwZXIgPSBQeUltcG9ydF9JbXBvcnRNb2R1bGUoCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLmVudW1fdHlwZV93cmFwcGVyIik7CisgIGlmIChlbnVtX3R5cGVfd3JhcHBlciA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIEVudW1UeXBlV3JhcHBlcl9jbGFzcyA9CisgICAgICBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGVudW1fdHlwZV93cmFwcGVyLCAiRW51bVR5cGVXcmFwcGVyIik7CisgIFB5X0RFQ1JFRihlbnVtX3R5cGVfd3JhcHBlcik7CisKKyAgUHlPYmplY3QqIG1lc3NhZ2VfbW9kdWxlID0gUHlJbXBvcnRfSW1wb3J0TW9kdWxlKAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5tZXNzYWdlIik7CisgIGlmIChtZXNzYWdlX21vZHVsZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIEVuY29kZUVycm9yX2NsYXNzID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhtZXNzYWdlX21vZHVsZSwgIkVuY29kZUVycm9yIik7CisgIERlY29kZUVycm9yX2NsYXNzID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhtZXNzYWdlX21vZHVsZSwgIkRlY29kZUVycm9yIik7CisgIFB5X0RFQ1JFRihtZXNzYWdlX21vZHVsZSk7CisKKyAgUHlPYmplY3QqIHBpY2tsZV9tb2R1bGUgPSBQeUltcG9ydF9JbXBvcnRNb2R1bGUoInBpY2tsZSIpOworICBpZiAocGlja2xlX21vZHVsZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIFBpY2tsZUVycm9yX2NsYXNzID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhwaWNrbGVfbW9kdWxlLCAiUGlja2xlRXJyb3IiKTsKKyAgUHlfREVDUkVGKHBpY2tsZV9tb2R1bGUpOworCisgIC8vIE92ZXJyaWRlIHtHZXQsTXV0YWJsZX1DUHJvdG9JbnNpZGVQeVByb3RvLgorICBHZXRDUHJvdG9JbnNpZGVQeVByb3RvUHRyID0gR2V0Q1Byb3RvSW5zaWRlUHlQcm90b0ltcGw7CisgIE11dGFibGVDUHJvdG9JbnNpZGVQeVByb3RvUHRyID0gTXV0YWJsZUNQcm90b0luc2lkZVB5UHJvdG9JbXBsOworCisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHl0aG9uCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCisjaWYgUFlfTUFKT1JfVkVSU0lPTiA+PSAzCitzdGF0aWMgc3RydWN0IFB5TW9kdWxlRGVmIF9tb2R1bGUgPSB7CisgIFB5TW9kdWxlRGVmX0hFQURfSU5JVCwKKyAgIl9tZXNzYWdlIiwKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6cHl0aG9uOjptb2R1bGVfZG9jc3RyaW5nLAorICAtMSwKKyAgTlVMTCwKKyAgTlVMTCwKKyAgTlVMTCwKKyAgTlVMTCwKKyAgTlVMTAorfTsKKyNkZWZpbmUgSU5JVEZVTkMgUHlJbml0X19tZXNzYWdlCisjZGVmaW5lIElOSVRGVU5DX0VSUk9SVkFMIE5VTEwKKyNlbHNlICAvLyBQeXRob24gMgorI2RlZmluZSBJTklURlVOQyBpbml0X21lc3NhZ2UKKyNkZWZpbmUgSU5JVEZVTkNfRVJST1JWQUwKKyNlbmRpZgorCitleHRlcm4gIkMiIHsKKyAgUHlNT0RJTklUX0ZVTkMgSU5JVEZVTkModm9pZCkgeworICAgIFB5T2JqZWN0KiBtOworI2lmIFBZX01BSk9SX1ZFUlNJT04gPj0gMworICAgIG0gPSBQeU1vZHVsZV9DcmVhdGUoJl9tb2R1bGUpOworI2Vsc2UKKyAgICBtID0gUHlfSW5pdE1vZHVsZTMoIl9tZXNzYWdlIiwgTlVMTCwgZ29vZ2xlOjpwcm90b2J1Zjo6cHl0aG9uOjptb2R1bGVfZG9jc3RyaW5nKTsKKyNlbmRpZgorICAgIGlmIChtID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBJTklURlVOQ19FUlJPUlZBTDsKKyAgICB9CisKKyAgICBpZiAoIWdvb2dsZTo6cHJvdG9idWY6OnB5dGhvbjo6SW5pdFByb3RvMk1lc3NhZ2VNb2R1bGUobSkpIHsKKyAgICAgIFB5X0RFQ1JFRihtKTsKKyAgICAgIHJldHVybiBJTklURlVOQ19FUlJPUlZBTDsKKyAgICB9CisKKyNpZiBQWV9NQUpPUl9WRVJTSU9OID49IDMKKyAgICByZXR1cm4gbTsKKyNlbmRpZgorICB9Cit9Cit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L21lc3NhZ2UuaCBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvbWVzc2FnZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmMmRhNzkKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L21lc3NhZ2UuaApAQCAtMCwwICsxLDMxMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYW51cmFhZ0Bnb29nbGUuY29tIChBbnVyYWFnIEFncmF3YWwpCisvLyBBdXRob3I6IHRpYmVsbEBnb29nbGUuY29tIChKb2hhbiBUaWJlbGwpCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1BZVEhPTl9DUFBfTUVTU0FHRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1BZVEhPTl9DUFBfTUVTU0FHRV9IX18KKworI2luY2x1ZGUgPFB5dGhvbi5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBNZXNzYWdlOworY2xhc3MgUmVmbGVjdGlvbjsKK2NsYXNzIEZpZWxkRGVzY3JpcHRvcjsKK2NsYXNzIERlc2NyaXB0b3I7CitjbGFzcyBEeW5hbWljTWVzc2FnZUZhY3Rvcnk7CisKK3VzaW5nIGludGVybmFsOjpzaGFyZWRfcHRyOworCituYW1lc3BhY2UgcHl0aG9uIHsKKworc3RydWN0IEV4dGVuc2lvbkRpY3Q7CisKK3R5cGVkZWYgc3RydWN0IENNZXNzYWdlIHsKKyAgUHlPYmplY3RfSEVBRDsKKworICAvLyBUaGlzIGlzIHRoZSB0b3AtbGV2ZWwgQysrIE1lc3NhZ2Ugb2JqZWN0IHRoYXQgb3ducyB0aGUgd2hvbGUKKyAgLy8gcHJvdG8gdHJlZS4gIEV2ZXJ5IFB5dGhvbiBDTWVzc2FnZSBob2xkcyBhIHJlZmVyZW5jZSB0byBpdCBpbgorICAvLyBvcmRlciB0byBrZWVwIGl0IGFsaXZlIGFzIGxvbmcgYXMgdGhlcmUncyBhIFB5dGhvbiBvYmplY3QgdGhhdAorICAvLyByZWZlcmVuY2VzIGFueSBwYXJ0IG9mIHRoZSB0cmVlLgorICBzaGFyZWRfcHRyPE1lc3NhZ2U+IG93bmVyOworCisgIC8vIFdlYWsgcmVmZXJlbmNlIHRvIGEgcGFyZW50IENNZXNzYWdlIG9iamVjdC4gVGhpcyBpcyBOVUxMIGZvciBhbnkgdG9wLWxldmVsCisgIC8vIG1lc3NhZ2UgYW5kIGlzIHNldCBmb3IgYW55IGNoaWxkIG1lc3NhZ2UgKGkuZS4gYSBjaGlsZCBzdWJtZXNzYWdlIG9yIGEKKyAgLy8gcGFydCBvZiBhIHJlcGVhdGVkIGNvbXBvc2l0ZSBmaWVsZCkuCisgIC8vCisgIC8vIFVzZWQgdG8gbWFrZSBzdXJlIGFsbCBhbmNlc3RvcnMgYXJlIGFsc28gbXV0YWJsZSB3aGVuIGZpcnN0IG1vZGlmeWluZworICAvLyBhIGNoaWxkIHN1Ym1lc3NhZ2UgKGluIG90aGVyIHdvcmRzLCB0dXJuaW5nIGEgZGVmYXVsdCBtZXNzYWdlIGluc3RhbmNlCisgIC8vIGludG8gYSBtdXRhYmxlIG9uZSkuCisgIC8vCisgIC8vIElmIGEgc3VibWVzc2FnZSBpcyByZWxlYXNlZCAoYmVjb21lcyBhIG5ldyB0b3AtbGV2ZWwgbWVzc2FnZSksIHRoaXMgZmllbGQKKyAgLy8gTVVTVCBiZSBzZXQgdG8gTlVMTC4gVGhlIHBhcmVudCBtYXkgZ2V0IGRlYWxsb2NhdGVkIGFuZCBmdXJ0aGVyIGF0dGVtcHRzCisgIC8vIHRvIHVzZSB0aGlzIHBvaW50ZXIgd2lsbCByZXN1bHQgaW4gYSBjcmFzaC4KKyAgc3RydWN0IENNZXNzYWdlKiBwYXJlbnQ7CisKKyAgLy8gUG9pbnRlciB0byB0aGUgcGFyZW50J3MgZGVzY3JpcHRvciB0aGF0IGRlc2NyaWJlcyB0aGlzIHN1Ym1lc3NhZ2UuCisgIC8vIFVzZWQgdG9nZXRoZXIgd2l0aCB0aGUgcGFyZW50J3MgbWVzc2FnZSB3aGVuIG1ha2luZyBhIGRlZmF1bHQgbWVzc2FnZQorICAvLyBpbnN0YW5jZSBtdXRhYmxlLgorICAvLyBUaGUgcG9pbnRlciBpcyBvd25lZCBieSB0aGUgZ2xvYmFsIERlc2NyaXB0b3JQb29sLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHBhcmVudF9maWVsZF9kZXNjcmlwdG9yOworCisgIC8vIFBvaW50ZXIgdG8gdGhlIEMrKyBNZXNzYWdlIG9iamVjdCBmb3IgdGhpcyBDTWVzc2FnZS4gIFRoZQorICAvLyBDTWVzc2FnZSBkb2VzIG5vdCBvd24gdGhpcyBwb2ludGVyLgorICBNZXNzYWdlKiBtZXNzYWdlOworCisgIC8vIEluZGljYXRlcyB0aGlzIHN1Ym1lc3NhZ2UgaXMgcG9pbnRpbmcgdG8gYSBkZWZhdWx0IGluc3RhbmNlIG9mIGEgbWVzc2FnZS4KKyAgLy8gU3VibWVzc2FnZXMgYXJlIGFsd2F5cyBmaXJzdCBjcmVhdGVkIGFzIHJlYWQgb25seSBtZXNzYWdlcyBhbmQgYXJlIHRoZW4KKyAgLy8gbWFkZSB3cml0YWJsZSwgYXQgd2hpY2ggcG9pbnQgdGhpcyBmaWVsZCBpcyBzZXQgdG8gZmFsc2UuCisgIGJvb2wgcmVhZF9vbmx5OworCisgIC8vIEEgcmVmZXJlbmNlIHRvIGEgUHl0aG9uIGRpY3Rpb25hcnkgY29udGFpbmluZyBDTWVzc2FnZSwKKyAgLy8gUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIsIGFuZCBSZXBlYXRlZFNjYWxhckNvbnRhaW5lcgorICAvLyBvYmplY3RzLiBVc2VkIGFzIGEgY2FjaGUgdG8gbWFrZSBzdXJlIHdlIGRvbid0IGhhdmUgdG8gbWFrZSBhCisgIC8vIFB5dGhvbiB3cmFwcGVyIGZvciB0aGUgQysrIE1lc3NhZ2Ugb2JqZWN0cyBvbiBldmVyeSBhY2Nlc3MsIG9yCisgIC8vIGRlYWwgd2l0aCB0aGUgc3luY2hyb25pemF0aW9uIG5pZ2h0bWFyZSB0aGF0IGNvdWxkIGNyZWF0ZS4KKyAgUHlPYmplY3QqIGNvbXBvc2l0ZV9maWVsZHM7CisKKyAgLy8gQSByZWZlcmVuY2UgdG8gdGhlIGRpY3Rpb25hcnkgY29udGFpbmluZyB0aGUgbWVzc2FnZSdzIGV4dGVuc2lvbnMuCisgIC8vIFNpbWlsYXIgdG8gY29tcG9zaXRlX2ZpZWxkcywgYWN0aW5nIGFzIGEgY2FjaGUsIGJ1dCBhbHNvIGNvbnRhaW5zIHRoZQorICAvLyByZXF1aXJlZCBleHRlbnNpb24gZGljdCBsb2dpYy4KKyAgRXh0ZW5zaW9uRGljdCogZXh0ZW5zaW9uczsKK30gQ01lc3NhZ2U7CisKK2V4dGVybiBQeVR5cGVPYmplY3QgQ01lc3NhZ2VfVHlwZTsKKworbmFtZXNwYWNlIGNtZXNzYWdlIHsKKworLy8gSW50ZXJuYWwgZnVuY3Rpb24gdG8gY3JlYXRlIGEgbmV3IGVtcHR5IE1lc3NhZ2UgUHl0aG9uIG9iamVjdCwgYnV0IHdpdGggZW1wdHkKKy8vIHBvaW50ZXJzIHRvIHRoZSBDKysgb2JqZWN0cy4KKy8vIFRoZSBjYWxsZXIgbXVzdCBmaWxsIHNlbGYtPm1lc3NhZ2UsIHNlbGYtPm93bmVyIGFuZCBldmVudHVhbGx5IHNlbGYtPnBhcmVudC4KK0NNZXNzYWdlKiBOZXdFbXB0eU1lc3NhZ2UoUHlPYmplY3QqIHR5cGUsIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZWxlYXNlIGEgc3VibWVzc2FnZSBmcm9tIGl0cyBwcm90byB0cmVlLCBtYWtpbmcgaXQgYSBuZXcgdG9wLWxldmVsIG1lc3NnYWUuCisvLyBBIG5ldyBtZXNzYWdlIHdpbGwgYmUgY3JlYXRlZCBpZiB0aGlzIGlzIGEgcmVhZC1vbmx5IGRlZmF1bHQgaW5zdGFuY2UuCisvLworLy8gQ29ycmVzcG9uZHMgdG8gcmVmbGVjdGlvbiBhcGkgbWV0aG9kIFJlbGVhc2VNZXNzYWdlLgoraW50IFJlbGVhc2VTdWJNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIENNZXNzYWdlKiBjaGlsZF9jbWVzc2FnZSk7CisKKy8vIFJldHJpZXZlcyB0aGUgQysrIGRlc2NyaXB0b3Igb2YgYSBQeXRob24gRXh0ZW5zaW9uIGRlc2NyaXB0b3IuCisvLyBPbiBlcnJvciwgcmV0dXJuIE5VTEwgd2l0aCBhbiBleGNlcHRpb24gc2V0LgorY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZXRFeHRlbnNpb25EZXNjcmlwdG9yKFB5T2JqZWN0KiBleHRlbnNpb24pOworCisvLyBJbml0aWFsaXplcyBhIG5ldyBDTWVzc2FnZSBpbnN0YW5jZSBmb3IgYSBzdWJtZXNzYWdlLiBPbmx5IGNhbGxlZCBvbmNlIHBlcgorLy8gc3VibWVzc2FnZSBhcyB0aGUgcmVzdWx0IGlzIGNhY2hlZCBpbiBjb21wb3NpdGVfZmllbGRzLgorLy8KKy8vIENvcnJlc3BvbmRzIHRvIHJlZmxlY3Rpb24gYXBpIG1ldGhvZCBHZXRNZXNzYWdlLgorUHlPYmplY3QqIEludGVybmFsR2V0U3ViTWVzc2FnZSgKKyAgICBDTWVzc2FnZSogc2VsZiwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yKTsKKworLy8gRGVsZXRlcyBhIHJhbmdlIG9mIEMrKyBzdWJtZXNzYWdlcyBpbiBhIHJlcGVhdGVkIGZpZWxkIChmb2xsb3dpbmcgYQorLy8gcmVtb3ZhbCBpbiBhIFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKS4KKy8vCisvLyBSZWxlYXNlcyBtZXNzYWdlcyB0byB0aGUgcHJvdmlkZWQgY21lc3NhZ2VfbGlzdCBpZiBpdCBpcyBub3QgTlVMTCByYXRoZXIKKy8vIHRoYW4ganVzdCByZW1vdmluZyB0aGVtIGZyb20gdGhlIHVuZGVybHlpbmcgcHJvdG8uIFRoaXMgY21lc3NhZ2VfbGlzdCBtdXN0CisvLyBoYXZlIGEgQ01lc3NhZ2UgZm9yIGVhY2ggdW5kZXJseWluZyBzdWJtZXNzYWdlLiBUaGUgQ01lc3NhZ2VzIHJlZmVycmVkIHRvCisvLyBieSBzbGljZSB3aWxsIGJlIHJlbW92ZWQgZnJvbSBjbWVzc2FnZV9saXN0IGJ5IHRoaXMgZnVuY3Rpb24uCisvLworLy8gQ29ycmVzcG9uZHMgdG8gcmVmbGVjdGlvbiBhcGkgbWV0aG9kIFJlbW92ZUxhc3QuCitpbnQgSW50ZXJuYWxEZWxldGVSZXBlYXRlZEZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIHNsaWNlLCBQeU9iamVjdCogY21lc3NhZ2VfbGlzdCk7CisKKy8vIFNldHMgdGhlIHNwZWNpZmllZCBzY2FsYXIgdmFsdWUgdG8gdGhlIG1lc3NhZ2UuCitpbnQgSW50ZXJuYWxTZXRTY2FsYXIoQ01lc3NhZ2UqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiB2YWx1ZSk7CisKKy8vIFJldHJpZXZlcyB0aGUgc3BlY2lmaWVkIHNjYWxhciB2YWx1ZSBmcm9tIHRoZSBtZXNzYWdlLgorLy8KKy8vIFJldHVybnMgYSBuZXcgcHl0aG9uIHJlZmVyZW5jZS4KK1B5T2JqZWN0KiBJbnRlcm5hbEdldFNjYWxhcihDTWVzc2FnZSogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IpOworCisvLyBDbGVhcnMgdGhlIG1lc3NhZ2UsIHJlbW92aW5nIGFsbCBjb250YWluZWQgZGF0YS4gRXh0ZW5zaW9uIGRpY3Rpb25hcnkgYW5kCisvLyBzdWJtZXNzYWdlcyBhcmUgcmVsZWFzZWQgZmlyc3QgaWYgdGhlcmUgYXJlIHJlbWFpbmluZyBleHRlcm5hbCByZWZlcmVuY2VzLgorLy8KKy8vIENvcnJlc3BvbmRzIHRvIG1lc3NhZ2UgYXBpIG1ldGhvZCBDbGVhci4KK1B5T2JqZWN0KiBDbGVhcihDTWVzc2FnZSogc2VsZik7CisKKy8vIENsZWFycyB0aGUgZGF0YSBkZXNjcmliZWQgYnkgdGhlIGdpdmVuIGRlc2NyaXB0b3IuIFVzZWQgdG8gY2xlYXIgZXh0ZW5zaW9ucworLy8gKHdoaWNoIGRvbid0IGhhdmUgbmFtZXMpLiBFeHRlbnNpb24gcmVsZWFzZSBpcyBoYW5kbGVkIGJ5IEV4dGVuc2lvbkRpY3QKKy8vIGNsYXNzLCBub3QgdGhpcyBmdW5jdGlvbi4KKy8vIFRPRE8oYW51cmFhZyk6IFRyeSB0byBtYWtlIHRoaXMgZGlzY3JlcGFuY3kgaW4gcmVsZWFzZSBzZW1hbnRpY3Mgd2l0aAorLy8gICAgICAgICAgICAgICAgQ2xlYXJGaWVsZCBsZXNzIGNvbmZ1c2luZy4KKy8vCisvLyBDb3JyZXNwb25kcyB0byByZWZsZWN0aW9uIGFwaSBtZXRob2QgQ2xlYXJGaWVsZC4KK1B5T2JqZWN0KiBDbGVhckZpZWxkQnlEZXNjcmlwdG9yKAorICAgIENNZXNzYWdlKiBzZWxmLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBDbGVhcnMgdGhlIGRhdGEgZm9yIHRoZSBnaXZlbiBmaWVsZCBuYW1lLiBUaGUgbWVzc2FnZSBpcyByZWxlYXNlZCBpZiB0aGVyZQorLy8gYXJlIGFueSBleHRlcm5hbCByZWZlcmVuY2VzLgorLy8KKy8vIENvcnJlc3BvbmRzIHRvIHJlZmxlY3Rpb24gYXBpIG1ldGhvZCBDbGVhckZpZWxkLgorUHlPYmplY3QqIENsZWFyRmllbGQoQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmcpOworCisvLyBDaGVja3MgaWYgdGhlIG1lc3NhZ2UgaGFzIHRoZSBmaWVsZCBkZXNjcmliZWQgYnkgdGhlIGRlc2NyaXB0b3IuIFVzZWQgZm9yCisvLyBleHRlbnNpb25zICh3aGljaCBoYXZlIG5vIG5hbWUpLgorLy8KKy8vIENvcnJlc3BvbmRzIHRvIHJlZmxlY3Rpb24gYXBpIG1ldGhvZCBIYXNGaWVsZAorUHlPYmplY3QqIEhhc0ZpZWxkQnlEZXNjcmlwdG9yKAorICAgIENNZXNzYWdlKiBzZWxmLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IpOworCisvLyBDaGVja3MgaWYgdGhlIG1lc3NhZ2UgaGFzIHRoZSBuYW1lZCBmaWVsZC4KKy8vCisvLyBDb3JyZXNwb25kcyB0byByZWZsZWN0aW9uIGFwaSBtZXRob2QgSGFzRmllbGQuCitQeU9iamVjdCogSGFzRmllbGQoQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmcpOworCisvLyBJbml0aWFsaXplcyB2YWx1ZXMgb2YgZmllbGRzIG9uIGEgbmV3bHkgY29uc3RydWN0ZWQgbWVzc2FnZS4KK2ludCBJbml0QXR0cmlidXRlcyhDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIGt3YXJncyk7CisKK1B5T2JqZWN0KiBNZXJnZUZyb20oQ01lc3NhZ2UqIHNlbGYsIFB5T2JqZWN0KiBhcmcpOworCisvLyBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5hbWVkICduYW1lJyBmcm9tIENNZXNzYWdlICdzZWxmJy4gUmV0dXJucworLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvbiBzdWNjZXNzLCBvciBOVUxMIG9uIGZhaWx1cmUuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UuCitQeU9iamVjdCogR2V0QXR0cihDTWVzc2FnZSogc2VsZiwgUHlPYmplY3QqIG5hbWUpOworCisvLyBTZXQgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgbmFtZWQgJ25hbWUnLCBmb3IgQ01lc3NhZ2UgJ3NlbGYnLAorLy8gdG8gdGhlIHZhbHVlICd2YWx1ZScuIFJldHVybnMgLTEgb24gZmFpbHVyZS4KK2ludCBTZXRBdHRyKENNZXNzYWdlKiBzZWxmLCBQeU9iamVjdCogbmFtZSwgUHlPYmplY3QqIHZhbHVlKTsKKworUHlPYmplY3QqIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhDTWVzc2FnZSogc2VsZik7CisKKy8vIFNldCB0aGUgb3duZXIgZmllbGQgb2Ygc2VsZiBhbmQgYW55IGNoaWxkcmVuIG9mIHNlbGYsIHJlY3Vyc2l2ZWx5LgorLy8gVXNlZCB3aGVuIHNlbGYgaXMgYmVpbmcgcmVsZWFzZWQgYW5kIHRodXMgaGFzIGEgbmV3IG93bmVyICh0aGUKKy8vIHJlbGVhc2VkIE1lc3NhZ2UuKQoraW50IFNldE93bmVyKENNZXNzYWdlKiBzZWxmLCBjb25zdCBzaGFyZWRfcHRyPE1lc3NhZ2U+JiBuZXdfb3duZXIpOworCitpbnQgQXNzdXJlV3JpdGFibGUoQ01lc3NhZ2UqIHNlbGYpOworCitEeW5hbWljTWVzc2FnZUZhY3RvcnkqIEdldE1lc3NhZ2VGYWN0b3J5KCk7CisKK30gIC8vIG5hbWVzcGFjZSBjbWVzc2FnZQorCisKKy8qIElzIDY0Yml0ICovCisjZGVmaW5lIElTXzY0QklUIChTSVpFT0ZfTE9ORyA9PSA4KQorCisjZGVmaW5lIEZJRUxEX0lTX1JFUEVBVEVEKGZpZWxkX2Rlc2NyaXB0b3IpICAgICAgICAgICAgICAgICBcCisgICAgKChmaWVsZF9kZXNjcmlwdG9yKS0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKQorCisjZGVmaW5lIEdPT0dMRV9DSEVDS19HRVRfSU5UMzIoYXJnLCB2YWx1ZSwgZXJyKSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpbnQzMiB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpZiAoIUNoZWNrQW5kR2V0SW50ZWdlcihhcmcsICZ2YWx1ZSwga2ludDMybWluX3B5LCBraW50MzJtYXhfcHkpKSB7IFwKKyAgICAgIHJldHVybiBlcnI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKworI2RlZmluZSBHT09HTEVfQ0hFQ0tfR0VUX0lOVDY0KGFyZywgdmFsdWUsIGVycikgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaW50NjQgdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKCFDaGVja0FuZEdldEludGVnZXIoYXJnLCAmdmFsdWUsIGtpbnQ2NG1pbl9weSwga2ludDY0bWF4X3B5KSkgeyBcCisgICAgICByZXR1cm4gZXJyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9CisKKyNkZWZpbmUgR09PR0xFX0NIRUNLX0dFVF9VSU5UMzIoYXJnLCB2YWx1ZSwgZXJyKSAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHVpbnQzMiB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmICghQ2hlY2tBbmRHZXRJbnRlZ2VyKGFyZywgJnZhbHVlLCBrUHl0aG9uWmVybywga3VpbnQzMm1heF9weSkpIHsgXAorICAgICAgcmV0dXJuIGVycjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfQorCisjZGVmaW5lIEdPT0dMRV9DSEVDS19HRVRfVUlOVDY0KGFyZywgdmFsdWUsIGVycikgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB1aW50NjQgdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpZiAoIUNoZWNrQW5kR2V0SW50ZWdlcihhcmcsICZ2YWx1ZSwga1B5dGhvblplcm8sIGt1aW50NjRtYXhfcHkpKSB7IFwKKyAgICAgIHJldHVybiBlcnI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKworI2RlZmluZSBHT09HTEVfQ0hFQ0tfR0VUX0ZMT0FUKGFyZywgdmFsdWUsIGVycikgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZmxvYXQgdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKCFDaGVja0FuZEdldEZsb2F0KGFyZywgJnZhbHVlKSkgeyAgICAgICAgICAgICAgICAgICBcCisgICAgICByZXR1cm4gZXJyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKworI2RlZmluZSBHT09HTEVfQ0hFQ0tfR0VUX0RPVUJMRShhcmcsIHZhbHVlLCBlcnIpICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZG91YmxlIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKCFDaGVja0FuZEdldERvdWJsZShhcmcsICZ2YWx1ZSkpIHsgICAgICAgICAgICAgICAgICBcCisgICAgICByZXR1cm4gZXJyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9CisKKyNkZWZpbmUgR09PR0xFX0NIRUNLX0dFVF9CT09MKGFyZywgdmFsdWUsIGVycikgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGJvb2wgdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmICghQ2hlY2tBbmRHZXRCb29sKGFyZywgJnZhbHVlKSkgeyAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIGVycjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfQorCisKK2V4dGVybiBQeU9iamVjdCoga1B5dGhvblplcm87CitleHRlcm4gUHlPYmplY3QqIGtpbnQzMm1pbl9weTsKK2V4dGVybiBQeU9iamVjdCoga2ludDMybWF4X3B5OworZXh0ZXJuIFB5T2JqZWN0KiBrdWludDMybWF4X3B5OworZXh0ZXJuIFB5T2JqZWN0KiBraW50NjRtaW5fcHk7CitleHRlcm4gUHlPYmplY3QqIGtpbnQ2NG1heF9weTsKK2V4dGVybiBQeU9iamVjdCoga3VpbnQ2NG1heF9weTsKKworI2RlZmluZSBDKHN0cikgY29uc3RfY2FzdDxjaGFyKj4oc3RyKQorCit2b2lkIEZvcm1hdFR5cGVFcnJvcihQeU9iamVjdCogYXJnLCBjaGFyKiBleHBlY3RlZF90eXBlcyk7Cit0ZW1wbGF0ZTxjbGFzcyBUPgorYm9vbCBDaGVja0FuZEdldEludGVnZXIoCisgICAgUHlPYmplY3QqIGFyZywgVCogdmFsdWUsIFB5T2JqZWN0KiBtaW4sIFB5T2JqZWN0KiBtYXgpOworYm9vbCBDaGVja0FuZEdldERvdWJsZShQeU9iamVjdCogYXJnLCBkb3VibGUqIHZhbHVlKTsKK2Jvb2wgQ2hlY2tBbmRHZXRGbG9hdChQeU9iamVjdCogYXJnLCBmbG9hdCogdmFsdWUpOworYm9vbCBDaGVja0FuZEdldEJvb2woUHlPYmplY3QqIGFyZywgYm9vbCogdmFsdWUpOworYm9vbCBDaGVja0FuZFNldFN0cmluZygKKyAgICBQeU9iamVjdCogYXJnLCBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgIGJvb2wgYXBwZW5kLAorICAgIGludCBpbmRleCk7CitQeU9iamVjdCogVG9TdHJpbmdPYmplY3QoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBzdHJpbmcgdmFsdWUpOworCisvLyBDaGVjayBpZiB0aGUgcGFzc2VkIGZpZWxkIGRlc2NyaXB0b3IgYmVsb25ncyB0byB0aGUgZ2l2ZW4gbWVzc2FnZS4KKy8vIElmIG5vdCwgcmV0dXJuIGZhbHNlIGFuZCBzZXQgYSBQeXRob24gZXhjZXB0aW9uIChhIEtleUVycm9yKQorYm9vbCBDaGVja0ZpZWxkQmVsb25nc1RvTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIG1lc3NhZ2UpOworCitleHRlcm4gUHlPYmplY3QqIFBpY2tsZUVycm9yX2NsYXNzOworCit9ICAvLyBuYW1lc3BhY2UgcHl0aG9uCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUFlUSE9OX0NQUF9NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9wcm90bzJfYXBpX3Rlc3QucHJvdG8gYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3Byb3RvMl9hcGlfdGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOGFlY2ZiCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9wcm90bzJfYXBpX3Rlc3QucHJvdG8KQEAgLTAsMCArMSw0MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9jcHAvcHJvdG8xX2FwaV90ZXN0LnByb3RvIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYucHl0aG9uLmludGVybmFsOworCittZXNzYWdlIFRlc3ROZXN0ZWRQcm90bzFBUElNZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgYSA9IDE7CisgIG9wdGlvbmFsIFRlc3RNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgYiA9IDI7Cit9CmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3B5dGhvbi5wcm90byBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvcHl0aG9uLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjZTY0NWQKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3B5dGhvbi5wcm90bwpAQCAtMCwwICsxLDY4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB0aWJlbGxAZ29vZ2xlLmNvbSAoSm9oYW4gVGliZWxsKQorLy8KKy8vIFRoZXNlIG1lc3NhZ2UgZGVmaW5pdGlvbnMgYXJlIHVzZWQgdG8gZXhlcmNpc2VzIGtub3duIGNvcm5lciBjYXNlcworLy8gaW4gdGhlIEMrKyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUHl0aG9uIEFQSS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLnB5dGhvbi5pbnRlcm5hbDsKKworLy8gUHJvdG9zIG9wdGltaXplZCBmb3IgU1BFRUQgdXNlIGEgc3RyaWN0IHN1cGVyc2V0IG9mIHRoZSBnZW5lcmF0ZWQgY29kZQorLy8gb2YgZXF1aXZhbGVudCBvbmVzIG9wdGltaXplZCBmb3IgQ09ERV9TSVpFLCBzbyB3ZSBzaG91bGQgb3B0aW1pemUgYWxsIG91cgorLy8gdGVzdHMgZm9yIHNwZWVkIHVubGVzcyBleHBsaWNpdGx5IHRlc3RpbmcgY29kZSBzaXplIG9wdGltaXphdGlvbi4KK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworbWVzc2FnZSBUZXN0QWxsVHlwZXMgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDMyIGJiID0gMTsKKyAgICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSBjYyA9IDI7CisgIH0KKworICByZXBlYXRlZCBOZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMTsKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDI7CisgIG9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMzsKK30KKworbWVzc2FnZSBGb3JlaWduTWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIGMgPSAxOworICByZXBlYXRlZCBpbnQzMiBkID0gMjsKK30KKworbWVzc2FnZSBUZXN0QWxsRXh0ZW5zaW9ucyB7CisgIGV4dGVuc2lvbnMgMSB0byBtYXg7Cit9CisKK2V4dGVuZCBUZXN0QWxsRXh0ZW5zaW9ucyB7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiA9IDE7CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiA9IDI7Cit9CmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3B5dGhvbl9wcm90b2J1Zi5oIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9weXRob25fcHJvdG9idWYuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWI2ZTQ2Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9weXRob25fcHJvdG9idWYuaApAQCAtMCwwICsxLDU3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBxcmN6YWtAZ29vZ2xlLmNvbSAoTWFyY2luIEtvd2FsY3p5aykKKy8vCisvLyBUaGlzIG1vZHVsZSBleHBvc2VzIHRoZSBDIHByb3RvIGluc2lkZSB0aGUgZ2l2ZW4gUHl0aG9uIHByb3RvLCBpbgorLy8gY2FzZSB0aGUgUHl0aG9uIHByb3RvIGlzIGltcGxlbWVudGVkIHdpdGggYSBDIHByb3RvLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fUFlUSE9OX1BST1RPQlVGX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUFlUSE9OX1BZVEhPTl9QUk9UT0JVRl9IX18KKworI2luY2x1ZGUgPFB5dGhvbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIE1lc3NhZ2U7CisKK25hbWVzcGFjZSBweXRob24geworCisvLyBSZXR1cm4gdGhlIHBvaW50ZXIgdG8gdGhlIEMgcHJvdG8gaW5zaWRlIHRoZSBnaXZlbiBQeXRob24gcHJvdG8sCisvLyBvciBOVUxMIHdoZW4gdGhpcyBpcyBub3QgYSBQeXRob24gcHJvdG8gaW1wbGVtZW50ZWQgd2l0aCBhIEMgcHJvdG8uCitjb25zdCBNZXNzYWdlKiBHZXRDUHJvdG9JbnNpZGVQeVByb3RvKFB5T2JqZWN0KiBtc2cpOworTWVzc2FnZSogTXV0YWJsZUNQcm90b0luc2lkZVB5UHJvdG8oUHlPYmplY3QqIG1zZyk7CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fUFlUSE9OX1BST1RPQlVGX0hfXwpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyLmNjIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmZTk4ZTcKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXIuY2MKQEAgLTAsMCArMSw3NzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGFudXJhYWdAZ29vZ2xlLmNvbSAoQW51cmFhZyBBZ3Jhd2FsKQorLy8gQXV0aG9yOiB0aWJlbGxAZ29vZ2xlLmNvbSAoSm9oYW4gVGliZWxsKQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXIuaD4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvc2NvcGVkX3B5b2JqZWN0X3B0ci5oPgorCisjaWYgUFlfTUFKT1JfVkVSU0lPTiA+PSAzCisgICNkZWZpbmUgUHlJbnRfQ2hlY2sgUHlMb25nX0NoZWNrCisgICNkZWZpbmUgUHlJbnRfQXNMb25nIFB5TG9uZ19Bc0xvbmcKKyAgI2RlZmluZSBQeUludF9Gcm9tTG9uZyBQeUxvbmdfRnJvbUxvbmcKKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworbmFtZXNwYWNlIHJlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXIgeworCisvLyBUT0RPKHRpYmVsbCk6IFdlIG1pZ2h0IGFsc28gd2FudCB0byBjaGVjazoKKy8vICAgR09PR0xFX0NIRUNLX05PVE5VTEwoKHNlbGYpLT5vd25lci5nZXQoKSk7CisjZGVmaW5lIEdPT0dMRV9DSEVDS19BVFRBQ0hFRChzZWxmKSAgICAgICAgICAgICBcCisgIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfQ0hFQ0tfTk9UTlVMTCgoc2VsZiktPm1lc3NhZ2UpOyAgICAgIFwKKyAgICBHT09HTEVfQ0hFQ0tfTk9UTlVMTCgoc2VsZiktPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yKTsgXAorICB9IHdoaWxlICgwKTsKKworI2RlZmluZSBHT09HTEVfQ0hFQ0tfUkVMRUFTRUQoc2VsZikgICAgICAgICAgICAgXAorICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgR09PR0xFX0NIRUNLKChzZWxmKS0+b3duZXIuZ2V0KCkgPT0gTlVMTCk7ICBcCisgICAgR09PR0xFX0NIRUNLKChzZWxmKS0+bWVzc2FnZSA9PSBOVUxMKTsgICAgICBcCisgICAgR09PR0xFX0NIRUNLKChzZWxmKS0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IgPT0gTlVMTCk7IFwKKyAgICBHT09HTEVfQ0hFQ0soKHNlbGYpLT5wYXJlbnQgPT0gTlVMTCk7ICAgICAgIFwKKyAgfSB3aGlsZSAoMCk7CisKKy8vIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlLgorc3RhdGljIFB5T2JqZWN0KiBHZXRLZXkoUHlPYmplY3QqIHgpIHsKKyAgLy8gSnVzdCB0aGUgaWRlbnRpdHkgZnVuY3Rpb24uCisgIFB5X0lOQ1JFRih4KTsKKyAgcmV0dXJuIHg7Cit9CisKKyNkZWZpbmUgR0VUX0tFWShrZXlmdW5jLCB2YWx1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgKChrZXlmdW5jKSA9PSBOVUxMID8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgR2V0S2V5KCh2YWx1ZSkpIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncygoa2V5ZnVuYyksICh2YWx1ZSksIE5VTEwpKQorCisvLyBDb252ZXJ0cyBhIGNvbXBhcmlzb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIC0xLCAwLCBvciAxIGludG8gYQorLy8gbGVzcy10aGFuIHByZWRpY2F0ZS4KKy8vCisvLyBSZXR1cm5zIC0xIG9uIGVycm9yLCAxIGlmIHggPCB5LCAwIGlmIHggPj0geS4KK3N0YXRpYyBpbnQgaXNsdChQeU9iamVjdCAqeCwgUHlPYmplY3QgKnksIFB5T2JqZWN0ICpjb21wYXJlKSB7CisgIGlmIChjb21wYXJlID09IE5VTEwpCisgICAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbCh4LCB5LCBQeV9MVCk7CisKKyAgU2NvcGVkUHlPYmplY3RQdHIgcmVzKFB5T2JqZWN0X0NhbGxGdW5jdGlvbk9iakFyZ3MoY29tcGFyZSwgeCwgeSwgTlVMTCkpOworICBpZiAocmVzID09IE5VTEwpCisgICAgcmV0dXJuIC0xOworICBpZiAoIVB5SW50X0NoZWNrKHJlcykpIHsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAiY29tcGFyaXNvbiBmdW5jdGlvbiBtdXN0IHJldHVybiBpbnQsIG5vdCAlLjIwMHMiLAorICAgICAgICAgICAgICAgICBQeV9UWVBFKHJlcyktPnRwX25hbWUpOworICAgIHJldHVybiAtMTsKKyAgfQorICByZXR1cm4gUHlJbnRfQXNMb25nKHJlcykgPCAwOworfQorCisvLyBDb3BpZWQgZnJvbSB1YXJyc29ydC5jIGJ1dCBzd2FwcyBtZW1jcHkgc3dhcHMgd2l0aCBwcm90b2J1Zi9weXRob24gc3dhcHMKKy8vIFRPRE8oYW51cmFhZyk6IElzIHRoZXJlIGEgYmV0dGVyIHdheSB0byBkbyB0aGlzIHRoZW4gcmVpbnZlbnRpbmcgdGhlIHdoZWVsPworc3RhdGljIGludCBJbnRlcm5hbFF1aWNrU29ydChSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBsaW1pdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGNtcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGtleWZ1bmMpIHsKKyAgaWYgKGxpbWl0IC0gc3RhcnQgPD0gMSkKKyAgICByZXR1cm4gMDsgIC8vIE5vdGhpbmcgdG8gc29ydC4KKworICBHT09HTEVfQ0hFQ0tfQVRUQUNIRUQoc2VsZik7CisKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yOworICBQeV9zc2l6ZV90IGxlZnQ7CisgIFB5X3NzaXplX3QgcmlnaHQ7CisKKyAgUHlPYmplY3QqIGNoaWxkcmVuID0gc2VsZi0+Y2hpbGRfbWVzc2FnZXM7CisKKyAgZG8geworICAgIGxlZnQgPSBzdGFydDsKKyAgICByaWdodCA9IGxpbWl0OworICAgIFNjb3BlZFB5T2JqZWN0UHRyIG1pZCgKKyAgICAgICAgR0VUX0tFWShrZXlmdW5jLCBQeUxpc3RfR0VUX0lURU0oY2hpbGRyZW4sIChzdGFydCArIGxpbWl0KSAvIDIpKSk7CisgICAgZG8geworICAgICAgU2NvcGVkUHlPYmplY3RQdHIga2V5KEdFVF9LRVkoa2V5ZnVuYywgUHlMaXN0X0dFVF9JVEVNKGNoaWxkcmVuLCBsZWZ0KSkpOworICAgICAgaW50IGlzX2x0ID0gaXNsdChrZXksIG1pZCwgY21wKTsKKyAgICAgIGlmIChpc19sdCA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgLyogYXJyYXlbbGVmdF08eCAqLworICAgICAgd2hpbGUgKGlzX2x0KSB7CisgICAgICAgICsrbGVmdDsKKyAgICAgICAgU2NvcGVkUHlPYmplY3RQdHIga2V5KEdFVF9LRVkoa2V5ZnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlMaXN0X0dFVF9JVEVNKGNoaWxkcmVuLCBsZWZ0KSkpOworICAgICAgICBpc19sdCA9IGlzbHQoa2V5LCBtaWQsIGNtcCk7CisgICAgICAgIGlmIChpc19sdCA9PSAtMSkKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICB9CisgICAgICBrZXkucmVzZXQoR0VUX0tFWShrZXlmdW5jLCBQeUxpc3RfR0VUX0lURU0oY2hpbGRyZW4sIHJpZ2h0IC0gMSkpKTsKKyAgICAgIGlzX2x0ID0gaXNsdChtaWQsIGtleSwgY21wKTsKKyAgICAgIGlmIChpc19sdCA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgd2hpbGUgKGlzX2x0KSB7CisgICAgICAgIC0tcmlnaHQ7CisgICAgICAgIFNjb3BlZFB5T2JqZWN0UHRyIGtleShHRVRfS0VZKGtleWZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5TGlzdF9HRVRfSVRFTShjaGlsZHJlbiwgcmlnaHQgLSAxKSkpOworICAgICAgICBpc19sdCA9IGlzbHQobWlkLCBrZXksIGNtcCk7CisgICAgICAgIGlmIChpc19sdCA9PSAtMSkKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICB9CisgICAgICBpZiAobGVmdCA8IHJpZ2h0KSB7CisgICAgICAgIC0tcmlnaHQ7CisgICAgICAgIGlmIChsZWZ0IDwgcmlnaHQpIHsKKyAgICAgICAgICByZWZsZWN0aW9uLT5Td2FwRWxlbWVudHMobWVzc2FnZSwgZGVzY3JpcHRvciwgbGVmdCwgcmlnaHQpOworICAgICAgICAgIFB5T2JqZWN0KiB0bXAgPSBQeUxpc3RfR0VUX0lURU0oY2hpbGRyZW4sIGxlZnQpOworICAgICAgICAgIFB5TGlzdF9TRVRfSVRFTShjaGlsZHJlbiwgbGVmdCwgUHlMaXN0X0dFVF9JVEVNKGNoaWxkcmVuLCByaWdodCkpOworICAgICAgICAgIFB5TGlzdF9TRVRfSVRFTShjaGlsZHJlbiwgcmlnaHQsIHRtcCk7CisgICAgICAgIH0KKyAgICAgICAgKytsZWZ0OworICAgICAgfQorICAgIH0gd2hpbGUgKGxlZnQgPCByaWdodCk7CisKKyAgICBpZiAoKHJpZ2h0IC0gc3RhcnQpIDwgKGxpbWl0IC0gbGVmdCkpIHsKKyAgICAgIC8qIHNvcnQgW3N0YXJ0Li5yaWdodFsgKi8KKyAgICAgIGlmIChzdGFydCA8IChyaWdodCAtIDEpKSB7CisgICAgICAgIEludGVybmFsUXVpY2tTb3J0KHNlbGYsIHN0YXJ0LCByaWdodCwgY21wLCBrZXlmdW5jKTsKKyAgICAgIH0KKworICAgICAgLyogc29ydCBbbGVmdC4ubGltaXRbICovCisgICAgICBzdGFydCA9IGxlZnQ7CisgICAgfSBlbHNlIHsKKyAgICAgIC8qIHNvcnQgW2xlZnQuLmxpbWl0WyAqLworICAgICAgaWYgKGxlZnQgPCAobGltaXQgLSAxKSkgeworICAgICAgICBJbnRlcm5hbFF1aWNrU29ydChzZWxmLCBsZWZ0LCBsaW1pdCwgY21wLCBrZXlmdW5jKTsKKyAgICAgIH0KKworICAgICAgLyogc29ydCBbc3RhcnQuLnJpZ2h0WyAqLworICAgICAgbGltaXQgPSByaWdodDsKKyAgICB9CisgIH0gd2hpbGUgKHN0YXJ0IDwgKGxpbWl0IC0gMSkpOworCisgIHJldHVybiAwOworfQorCisjdW5kZWYgR0VUX0tFWQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIGxlbigpCisKK3N0YXRpYyBQeV9zc2l6ZV90IExlbmd0aChSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZikgeworICBNZXNzYWdlKiBtZXNzYWdlID0gc2VsZi0+bWVzc2FnZTsKKyAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkgeworICAgIHJldHVybiBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgqbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IpOworICB9IGVsc2UgeworICAgIC8vIFRoZSBjb250YWluZXIgaGFzIGJlZW4gcmVsZWFzZWQgKGkuZS4gYnkgYSBjYWxsIHRvIENsZWFyKCkgb3IKKyAgICAvLyBDbGVhckZpZWxkKCkgb24gdGhlIHBhcmVudCkgYW5kIHRodXMgdGhlcmUncyBubyBtZXNzYWdlLgorICAgIHJldHVybiBQeUxpc3RfR0VUX1NJWkUoc2VsZi0+Y2hpbGRfbWVzc2FnZXMpOworICB9Cit9CisKKy8vIFJldHVybnMgMCBpZiBzdWNjZXNzZnVsOyByZXR1cm5zIC0xIGFuZCBzZXRzIGFuIGV4Y2VwdGlvbiBpZgorLy8gdW5zdWNjZXNzZnVsLgorc3RhdGljIGludCBVcGRhdGVDaGlsZE1lc3NhZ2VzKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmKSB7CisgIGlmIChzZWxmLT5tZXNzYWdlID09IE5VTEwpCisgICAgcmV0dXJuIDA7CisKKyAgLy8gQSBNZXJnZUZyb20gb24gYSBwYXJlbnQgbWVzc2FnZSBjb3VsZCBoYXZlIGNhdXNlZCBleHRyYSBtZXNzYWdlcyB0byBiZQorICAvLyBhZGRlZCBpbiB0aGUgdW5kZXJseWluZyBwcm90b2J1ZiBzbyBhZGQgdGhlbSB0byBvdXIgbGlzdC4gVGhleSBjYW4gbmV2ZXIKKyAgLy8gYmUgcmVtb3ZlZCBpbiBzdWNoIGEgd2F5IHNvIHRoZXJlJ3Mgbm8gbmVlZCB0byB3b3JyeSBhYm91dCB0aGF0LgorICBQeV9zc2l6ZV90IG1lc3NhZ2VfbGVuZ3RoID0gTGVuZ3RoKHNlbGYpOworICBQeV9zc2l6ZV90IGNoaWxkX2xlbmd0aCA9IFB5TGlzdF9HRVRfU0laRShzZWxmLT5jaGlsZF9tZXNzYWdlcyk7CisgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBzZWxmLT5tZXNzYWdlOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBmb3IgKFB5X3NzaXplX3QgaSA9IGNoaWxkX2xlbmd0aDsgaSA8IG1lc3NhZ2VfbGVuZ3RoOyArK2kpIHsKKyAgICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICAgICAgKihzZWxmLT5tZXNzYWdlKSwgc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IsIGkpOworICAgIENNZXNzYWdlKiBjbXNnID0gY21lc3NhZ2U6Ok5ld0VtcHR5TWVzc2FnZShzZWxmLT5zdWJjbGFzc19pbml0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJfbWVzc2FnZS5HZXREZXNjcmlwdG9yKCkpOworICAgIFNjb3BlZFB5T2JqZWN0UHRyIHB5X2Ntc2cocmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KGNtc2cpKTsKKyAgICBpZiAoY21zZyA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGNtc2ctPm93bmVyID0gc2VsZi0+b3duZXI7CisgICAgY21zZy0+bWVzc2FnZSA9IGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZzdWJfbWVzc2FnZSk7CisgICAgY21zZy0+cGFyZW50ID0gc2VsZi0+cGFyZW50OworICAgIGlmIChQeUxpc3RfQXBwZW5kKHNlbGYtPmNoaWxkX21lc3NhZ2VzLCBweV9jbXNnKSA8IDApIHsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gYWRkKCkKKworc3RhdGljIFB5T2JqZWN0KiBBZGRUb0F0dGFjaGVkKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBhcmdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBrd2FyZ3MpIHsKKyAgR09PR0xFX0NIRUNLX0FUVEFDSEVEKHNlbGYpOworCisgIGlmIChVcGRhdGVDaGlsZE1lc3NhZ2VzKHNlbGYpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChjbWVzc2FnZTo6QXNzdXJlV3JpdGFibGUoc2VsZi0+cGFyZW50KSA9PSAtMSkKKyAgICByZXR1cm4gTlVMTDsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlID0KKyAgICAgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+QWRkTWVzc2FnZShtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yKTsKKyAgQ01lc3NhZ2UqIGNtc2cgPSBjbWVzc2FnZTo6TmV3RW1wdHlNZXNzYWdlKHNlbGYtPnN1YmNsYXNzX2luaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJfbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpKTsKKyAgaWYgKGNtc2cgPT0gTlVMTCkKKyAgICByZXR1cm4gTlVMTDsKKworICBjbXNnLT5vd25lciA9IHNlbGYtPm93bmVyOworICBjbXNnLT5tZXNzYWdlID0gc3ViX21lc3NhZ2U7CisgIGNtc2ctPnBhcmVudCA9IHNlbGYtPnBhcmVudDsKKyAgaWYgKGNtZXNzYWdlOjpJbml0QXR0cmlidXRlcyhjbXNnLCBrd2FyZ3MpIDwgMCkgeworICAgIFB5X0RFQ1JFRihjbXNnKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIFB5T2JqZWN0KiBweV9jbXNnID0gcmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KGNtc2cpOworICBpZiAoUHlMaXN0X0FwcGVuZChzZWxmLT5jaGlsZF9tZXNzYWdlcywgcHlfY21zZykgPCAwKSB7CisgICAgUHlfREVDUkVGKHB5X2Ntc2cpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBweV9jbXNnOworfQorCitzdGF0aWMgUHlPYmplY3QqIEFkZFRvUmVsZWFzZWQoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGt3YXJncykgeworICBHT09HTEVfQ0hFQ0tfUkVMRUFTRUQoc2VsZik7CisKKyAgLy8gQ3JlYXRlIGEgbmV3IE1lc3NhZ2UgZGV0YWNoZWQgZnJvbSB0aGUgcmVzdC4KKyAgUHlPYmplY3QqIHB5X2Ntc2cgPSBQeUV2YWxfQ2FsbE9iamVjdFdpdGhLZXl3b3JkcygKKyAgICAgIHNlbGYtPnN1YmNsYXNzX2luaXQsIE5VTEwsIGt3YXJncyk7CisgIGlmIChweV9jbXNnID09IE5VTEwpCisgICAgcmV0dXJuIE5VTEw7CisKKyAgaWYgKFB5TGlzdF9BcHBlbmQoc2VsZi0+Y2hpbGRfbWVzc2FnZXMsIHB5X2Ntc2cpIDwgMCkgeworICAgIFB5X0RFQ1JFRihweV9jbXNnKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICByZXR1cm4gcHlfY21zZzsKK30KKworUHlPYmplY3QqIEFkZChSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgUHlPYmplY3QqIGFyZ3MsCisgICAgICAgICAgICAgIFB5T2JqZWN0KiBrd2FyZ3MpIHsKKyAgaWYgKHNlbGYtPm1lc3NhZ2UgPT0gTlVMTCkKKyAgICByZXR1cm4gQWRkVG9SZWxlYXNlZChzZWxmLCBhcmdzLCBrd2FyZ3MpOworICBlbHNlCisgICAgcmV0dXJuIEFkZFRvQXR0YWNoZWQoc2VsZiwgYXJncywga3dhcmdzKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBleHRlbmQoKQorCitQeU9iamVjdCogRXh0ZW5kKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogdmFsdWUpIHsKKyAgY21lc3NhZ2U6OkFzc3VyZVdyaXRhYmxlKHNlbGYtPnBhcmVudCk7CisgIGlmIChVcGRhdGVDaGlsZE1lc3NhZ2VzKHNlbGYpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFNjb3BlZFB5T2JqZWN0UHRyIGl0ZXIoUHlPYmplY3RfR2V0SXRlcih2YWx1ZSkpOworICBpZiAoaXRlciA9PSBOVUxMKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIlZhbHVlIG11c3QgYmUgaXRlcmFibGUiKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBTY29wZWRQeU9iamVjdFB0ciBuZXh0OworICB3aGlsZSAoKG5leHQucmVzZXQoUHlJdGVyX05leHQoaXRlcikpKSAhPSBOVUxMKSB7CisgICAgaWYgKCFQeU9iamVjdF9UeXBlQ2hlY2sobmV4dCwgJkNNZXNzYWdlX1R5cGUpKSB7CisgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiTm90IGEgY21lc3NhZ2UiKTsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRQeU9iamVjdFB0ciBuZXdfbWVzc2FnZShBZGQoc2VsZiwgTlVMTCwgTlVMTCkpOworICAgIGlmIChuZXdfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgQ01lc3NhZ2UqIG5ld19jbWVzc2FnZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Q01lc3NhZ2UqPihuZXdfbWVzc2FnZS5nZXQoKSk7CisgICAgaWYgKGNtZXNzYWdlOjpNZXJnZUZyb20obmV3X2NtZXNzYWdlLCBuZXh0KSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgIH0KKyAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlPYmplY3QqIE1lcmdlRnJvbShSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIG90aGVyKSB7CisgIGlmIChVcGRhdGVDaGlsZE1lc3NhZ2VzKHNlbGYpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBFeHRlbmQoc2VsZiwgb3RoZXIpOworfQorCitQeU9iamVjdCogU3Vic2NyaXB0KFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogc2xpY2UpIHsKKyAgaWYgKFVwZGF0ZUNoaWxkTWVzc2FnZXMoc2VsZikgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgLy8gSnVzdCBmb3J3YXJkIHRoZSBjYWxsIHRvIHRoZSBzdWJzY3JpcHQtaGFuZGxpbmcgZnVuY3Rpb24gb2YgdGhlCisgIC8vIGxpc3QgY29udGFpbmluZyB0aGUgY2hpbGQgbWVzc2FnZXMuCisgIHJldHVybiBQeU9iamVjdF9HZXRJdGVtKHNlbGYtPmNoaWxkX21lc3NhZ2VzLCBzbGljZSk7Cit9CisKK2ludCBBc3NpZ25TdWJzY3JpcHQoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBzbGljZSwKKyAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIHZhbHVlKSB7CisgIGlmIChVcGRhdGVDaGlsZE1lc3NhZ2VzKHNlbGYpIDwgMCkgeworICAgIHJldHVybiAtMTsKKyAgfQorICBpZiAodmFsdWUgIT0gTlVMTCkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJkb2VzIG5vdCBzdXBwb3J0IGFzc2lnbm1lbnQiKTsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICAvLyBEZWxldGUgZnJvbSB0aGUgdW5kZXJseWluZyBNZXNzYWdlLCBpZiBhbnkuCisgIGlmIChzZWxmLT5tZXNzYWdlICE9IE5VTEwpIHsKKyAgICBpZiAoY21lc3NhZ2U6OkludGVybmFsRGVsZXRlUmVwZWF0ZWRGaWVsZChzZWxmLT5tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNsaWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoaWxkX21lc3NhZ2VzKSA8IDApIHsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgUHlfc3NpemVfdCBmcm9tOworICAgIFB5X3NzaXplX3QgdG87CisgICAgUHlfc3NpemVfdCBzdGVwOworICAgIFB5X3NzaXplX3QgbGVuZ3RoID0gTGVuZ3RoKHNlbGYpOworICAgIFB5X3NzaXplX3Qgc2xpY2VsZW5ndGg7CisgICAgaWYgKFB5U2xpY2VfQ2hlY2soc2xpY2UpKSB7CisjaWYgUFlfTUFKT1JfVkVSU0lPTiA+PSAzCisgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoc2xpY2UsCisjZWxzZQorICAgICAgaWYgKFB5U2xpY2VfR2V0SW5kaWNlc0V4KHJlaW50ZXJwcmV0X2Nhc3Q8UHlTbGljZU9iamVjdCo+KHNsaWNlKSwKKyNlbmRpZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCwgJmZyb20sICZ0bywgJnN0ZXAsICZzbGljZWxlbmd0aCkgPT0gLTEpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgcmV0dXJuIFB5U2VxdWVuY2VfRGVsU2xpY2Uoc2VsZi0+Y2hpbGRfbWVzc2FnZXMsIGZyb20sIHRvKTsKKyAgICB9IGVsc2UgaWYgKFB5SW50X0NoZWNrKHNsaWNlKSB8fCBQeUxvbmdfQ2hlY2soc2xpY2UpKSB7CisgICAgICBmcm9tID0gdG8gPSBQeUxvbmdfQXNMb25nKHNsaWNlKTsKKyAgICAgIGlmIChmcm9tIDwgMCkgeworICAgICAgICBmcm9tID0gdG8gPSBsZW5ndGggKyBmcm9tOworICAgICAgfQorICAgICAgcmV0dXJuIFB5U2VxdWVuY2VfRGVsSXRlbShzZWxmLT5jaGlsZF9tZXNzYWdlcywgZnJvbSk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogUmVtb3ZlKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogdmFsdWUpIHsKKyAgaWYgKFVwZGF0ZUNoaWxkTWVzc2FnZXMoc2VsZikgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgUHlfc3NpemVfdCBpbmRleCA9IFB5U2VxdWVuY2VfSW5kZXgoc2VsZi0+Y2hpbGRfbWVzc2FnZXMsIHZhbHVlKTsKKyAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgcHlfaW5kZXgoUHlMb25nX0Zyb21Mb25nKGluZGV4KSk7CisgIGlmIChBc3NpZ25TdWJzY3JpcHQoc2VsZiwgcHlfaW5kZXgsIE5VTEwpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5X1JFVFVSTl9OT05FOworfQorCitzdGF0aWMgUHlPYmplY3QqIFJpY2hDb21wYXJlKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogb3RoZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvcGlkKSB7CisgIGlmIChVcGRhdGVDaGlsZE1lc3NhZ2VzKHNlbGYpIDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmICghUHlPYmplY3RfVHlwZUNoZWNrKG90aGVyLCAmUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXJfVHlwZSkpIHsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiQ2FuIG9ubHkgY29tcGFyZSByZXBlYXRlZCBjb21wb3NpdGUgZmllbGRzICIKKyAgICAgICAgICAgICAgICAgICAgImFnYWluc3Qgb3RoZXIgcmVwZWF0ZWQgY29tcG9zaXRlIGZpZWxkcy4iKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAob3BpZCA9PSBQeV9FUSB8fCBvcGlkID09IFB5X05FKSB7CisgICAgLy8gVE9ETyhhbnVyYWFnKTogRG9uJ3QgbWFrZSBuZXcgbGlzdHMganVzdCBmb3IgdGhpcy4uLgorICAgIFNjb3BlZFB5T2JqZWN0UHRyIGZ1bGxfc2xpY2UoUHlTbGljZV9OZXcoTlVMTCwgTlVMTCwgTlVMTCkpOworICAgIGlmIChmdWxsX3NsaWNlID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRQeU9iamVjdFB0ciBsaXN0KFN1YnNjcmlwdChzZWxmLCBmdWxsX3NsaWNlKSk7CisgICAgaWYgKGxpc3QgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFNjb3BlZFB5T2JqZWN0UHRyIG90aGVyX2xpc3QoCisgICAgICAgIFN1YnNjcmlwdCgKKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqPihvdGhlciksIGZ1bGxfc2xpY2UpKTsKKyAgICBpZiAob3RoZXJfbGlzdCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlKGxpc3QsIG90aGVyX2xpc3QsIG9waWQpOworICB9IGVsc2UgeworICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gc29ydCgpCisKK3N0YXRpYyBQeU9iamVjdCogU29ydEF0dGFjaGVkKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCoga3dkcykgeworICAvLyBTb3J0IHRoZSB1bmRlcmx5aW5nIE1lc3NhZ2UgYXJyYXkuCisgIFB5T2JqZWN0ICpjb21wYXJlID0gTlVMTDsKKyAgaW50IHJldmVyc2UgPSAwOworICBQeU9iamVjdCAqa2V5ZnVuYyA9IE5VTEw7CisgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsiY21wIiwgImtleSIsICJyZXZlcnNlIiwgMH07CisKKyAgaWYgKGFyZ3MgIT0gTlVMTCkgeworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJ8T09pOnNvcnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt3bGlzdCwgJmNvbXBhcmUsICZrZXlmdW5jLCAmcmV2ZXJzZSkpCisgICAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoY29tcGFyZSA9PSBQeV9Ob25lKQorICAgIGNvbXBhcmUgPSBOVUxMOworICBpZiAoa2V5ZnVuYyA9PSBQeV9Ob25lKQorICAgIGtleWZ1bmMgPSBOVUxMOworCisgIGNvbnN0IFB5X3NzaXplX3QgbGVuZ3RoID0gTGVuZ3RoKHNlbGYpOworICBpZiAoSW50ZXJuYWxRdWlja1NvcnQoc2VsZiwgMCwgbGVuZ3RoLCBjb21wYXJlLCBrZXlmdW5jKSA8IDApCisgICAgcmV0dXJuIE5VTEw7CisKKyAgLy8gRmluYWxseSByZXZlcnNlIHRoZSByZXN1bHQgaWYgcmVxdWVzdGVkLgorICBpZiAocmV2ZXJzZSkgeworICAgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBzZWxmLT5tZXNzYWdlOworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisKKyAgICAvLyBSZXZlcnNlIHRoZSBNZXNzYWdlIGFycmF5LgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoIC8gMjsgKytpKQorICAgICAgcmVmbGVjdGlvbi0+U3dhcEVsZW1lbnRzKG1lc3NhZ2UsIGRlc2NyaXB0b3IsIGksIGxlbmd0aCAtIGkgLSAxKTsKKworICAgIC8vIFJldmVyc2UgdGhlIFB5dGhvbiBsaXN0LgorICAgIFNjb3BlZFB5T2JqZWN0UHRyIHJlcyhQeU9iamVjdF9DYWxsTWV0aG9kKHNlbGYtPmNoaWxkX21lc3NhZ2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXZlcnNlIiwgTlVMTCkpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgIHJldHVybiBOVUxMOworICB9CisKKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogU29ydFJlbGVhc2VkKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCoga3dkcykgeworICBTY29wZWRQeU9iamVjdFB0ciBtKFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoc2VsZi0+Y2hpbGRfbWVzc2FnZXMsICJzb3J0IikpOworICBpZiAobSA9PSBOVUxMKQorICAgIHJldHVybiBOVUxMOworICBpZiAoUHlPYmplY3RfQ2FsbChtLCBhcmdzLCBrd2RzKSA9PSBOVUxMKQorICAgIHJldHVybiBOVUxMOworICBQeV9SRVRVUk5fTk9ORTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBTb3J0KFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBhcmdzLAorICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBrd2RzKSB7CisgIC8vIFN1cHBvcnQgdGhlIG9sZCBzb3J0X2Z1bmN0aW9uIGFyZ3VtZW50IGZvciBiYWNrd2FyZHMKKyAgLy8gY29tcGF0aWJpbGl0eS4KKyAgaWYgKGt3ZHMgIT0gTlVMTCkgeworICAgIFB5T2JqZWN0KiBzb3J0X2Z1bmMgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhrd2RzLCAic29ydF9mdW5jdGlvbiIpOworICAgIGlmIChzb3J0X2Z1bmMgIT0gTlVMTCkgeworICAgICAgLy8gTXVzdCBzZXQgYmVmb3JlIGRlbGV0aW5nIGFzIHNvcnRfZnVuYyBpcyBhIGJvcnJvd2VkIHJlZmVyZW5jZQorICAgICAgLy8gYW5kIGt3ZHMgbWlnaHQgYmUgdGhlIG9ubHkgdGhpbmcga2VlcGluZyBpdCBhbGl2ZS4KKyAgICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGt3ZHMsICJjbXAiLCBzb3J0X2Z1bmMpOworICAgICAgUHlEaWN0X0RlbEl0ZW1TdHJpbmcoa3dkcywgInNvcnRfZnVuY3Rpb24iKTsKKyAgICB9CisgIH0KKworICBpZiAoVXBkYXRlQ2hpbGRNZXNzYWdlcyhzZWxmKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoc2VsZi0+bWVzc2FnZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIFNvcnRSZWxlYXNlZChzZWxmLCBhcmdzLCBrd2RzKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gU29ydEF0dGFjaGVkKHNlbGYsIGFyZ3MsIGt3ZHMpOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgUHlPYmplY3QqIEl0ZW0oUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsIFB5X3NzaXplX3QgaW5kZXgpIHsKKyAgaWYgKFVwZGF0ZUNoaWxkTWVzc2FnZXMoc2VsZikgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgUHlfc3NpemVfdCBsZW5ndGggPSBMZW5ndGgoc2VsZik7CisgIGlmIChpbmRleCA8IDApIHsKKyAgICBpbmRleCA9IGxlbmd0aCArIGluZGV4OworICB9CisgIFB5T2JqZWN0KiBpdGVtID0gUHlMaXN0X0dldEl0ZW0oc2VsZi0+Y2hpbGRfbWVzc2FnZXMsIGluZGV4KTsKKyAgaWYgKGl0ZW0gPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5X0lOQ1JFRihpdGVtKTsKKyAgcmV0dXJuIGl0ZW07Cit9CisKK3N0YXRpYyBQeU9iamVjdCogUG9wKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIGFyZ3MpIHsKKyAgUHlfc3NpemVfdCBpbmRleCA9IC0xOworICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxuIiwgJmluZGV4KSkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5T2JqZWN0KiBpdGVtID0gSXRlbShzZWxmLCBpbmRleCk7CisgIGlmIChpdGVtID09IE5VTEwpIHsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfSW5kZXhFcnJvciwKKyAgICAgICAgICAgICAgICAgImxpc3QgaW5kZXggKCV6ZCkgb3V0IG9mIHJhbmdlIiwKKyAgICAgICAgICAgICAgICAgaW5kZXgpOworICAgIHJldHVybiBOVUxMOworICB9CisgIFNjb3BlZFB5T2JqZWN0UHRyIHB5X2luZGV4KFB5TG9uZ19Gcm9tU3NpemVfdChpbmRleCkpOworICBpZiAoQXNzaWduU3Vic2NyaXB0KHNlbGYsIHB5X2luZGV4LCBOVUxMKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICByZXR1cm4gaXRlbTsKK30KKworLy8gVGhlIGNhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIE1lc3NhZ2UuCitNZXNzYWdlKiBSZWxlYXNlTGFzdChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgR09PR0xFX0NIRUNLX05PVE5VTEwoZmllbGQpOworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTCh0eXBlKTsKKyAgR09PR0xFX0NIRUNLX05PVE5VTEwobWVzc2FnZSk7CisKKyAgTWVzc2FnZSogcmVsZWFzZWRfbWVzc2FnZSA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgICBtZXNzYWdlLCBmaWVsZCk7CisgIC8vIFRPRE8odGliZWxsKTogRGVhbCB3aXRoIHByb3RvMS4KKworICAvLyBSZWxlYXNlTWVzc2FnZSB3aWxsIHJldHVybiBOVUxMIHdoaWNoIGRpZmZlcnMgZnJvbQorICAvLyBjaGlsZF9jbWVzc2FnZS0+bWVzc2FnZSwgaWYgdGhlIGZpZWxkIGRvZXMgbm90IGV4aXN0LiAgSW4gdGhpcyBjYXNlLAorICAvLyB0aGUgbGF0dGVyIHBvaW50cyB0byB0aGUgZGVmYXVsdCBpbnN0YW5jZSB2aWEgYSBjb25zdF9jYXN0PD4sIHNvIHdlCisgIC8vIGhhdmUgdG8gcmVzZXQgaXQgdG8gYSBuZXcgbXV0YWJsZSBvYmplY3Qgc2luY2Ugd2UgYXJlIHRha2luZyBvd25lcnNoaXAuCisgIGlmIChyZWxlYXNlZF9tZXNzYWdlID09IE5VTEwpIHsKKyAgICBjb25zdCBNZXNzYWdlKiBwcm90b3R5cGUgPQorICAgICAgICBjbWVzc2FnZTo6R2V0TWVzc2FnZUZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKHR5cGUpOworICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKHByb3RvdHlwZSk7CisgICAgcmV0dXJuIHByb3RvdHlwZS0+TmV3KCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHJlbGVhc2VkX21lc3NhZ2U7CisgIH0KK30KKworLy8gUmVsZWFzZSBmaWVsZCBvZiBtZXNzYWdlIGFuZCB0cmFuc2ZlciB0aGUgb3duZXJzaGlwIHRvIGNtZXNzYWdlLgordm9pZCBSZWxlYXNlTGFzdFRvKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBDTWVzc2FnZSogY21lc3NhZ2UpIHsKKyAgR09PR0xFX0NIRUNLX05PVE5VTEwoZmllbGQpOworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChtZXNzYWdlKTsKKyAgR09PR0xFX0NIRUNLX05PVE5VTEwoY21lc3NhZ2UpOworCisgIHNoYXJlZF9wdHI8TWVzc2FnZT4gcmVsZWFzZWRfbWVzc2FnZSgKKyAgICAgIFJlbGVhc2VMYXN0KGZpZWxkLCBjbWVzc2FnZS0+bWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLCBtZXNzYWdlKSk7CisgIGNtZXNzYWdlLT5wYXJlbnQgPSBOVUxMOworICBjbWVzc2FnZS0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IgPSBOVUxMOworICBjbWVzc2FnZS0+bWVzc2FnZSA9IHJlbGVhc2VkX21lc3NhZ2UuZ2V0KCk7CisgIGNtZXNzYWdlLT5yZWFkX29ubHkgPSBmYWxzZTsKKyAgY21lc3NhZ2U6OlNldE93bmVyKGNtZXNzYWdlLCByZWxlYXNlZF9tZXNzYWdlKTsKK30KKworLy8gQ2FsbGVkIHRvIHJlbGVhc2UgYSBjb250YWluZXIgdXNpbmcKKy8vIENsZWFyRmllbGQoJ2NvbnRhaW5lcl9maWVsZF9uYW1lJykgb24gdGhlIHBhcmVudC4KK2ludCBSZWxlYXNlKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmKSB7CisgIGlmIChVcGRhdGVDaGlsZE1lc3NhZ2VzKHNlbGYpIDwgMCkgeworICAgIFB5RXJyX1dyaXRlVW5yYWlzYWJsZShQeUJ5dGVzX0Zyb21TdHJpbmcoIkZhaWxlZCB0byB1cGRhdGUgcmVsZWFzZWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lc3NhZ2VzIikpOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBzZWxmLT5tZXNzYWdlOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisKKyAgLy8gVGhlIHJlZmxlY3Rpb24gQVBJIG9ubHkgbGV0cyB1cyByZWxlYXNlIHRoZSBsYXN0IG1lc3NhZ2UgaW4gYQorICAvLyByZXBlYXRlZCBmaWVsZC4gIFRoZXJlZm9yZSB3ZSBpdGVyYXRlIHRocm91Z2ggdGhlIGNoaWxkcmVuCisgIC8vIHN0YXJ0aW5nIHdpdGggdGhlIGxhc3Qgb25lLgorICBjb25zdCBQeV9zc2l6ZV90IHNpemUgPSBQeUxpc3RfR0VUX1NJWkUoc2VsZi0+Y2hpbGRfbWVzc2FnZXMpOworICBHT09HTEVfRENIRUNLX0VRKHNpemUsIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKCptZXNzYWdlLCBmaWVsZCkpOworICBmb3IgKFB5X3NzaXplX3QgaSA9IHNpemUgLSAxOyBpID49IDA7IC0taSkgeworICAgIENNZXNzYWdlKiBjaGlsZF9jbWVzc2FnZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Q01lc3NhZ2UqPigKKyAgICAgICAgUHlMaXN0X0dFVF9JVEVNKHNlbGYtPmNoaWxkX21lc3NhZ2VzLCBpKSk7CisgICAgUmVsZWFzZUxhc3RUbyhmaWVsZCwgbWVzc2FnZSwgY2hpbGRfY21lc3NhZ2UpOworICB9CisKKyAgLy8gRGV0YWNoIGZyb20gY29udGFpbmluZyBtZXNzYWdlLgorICBzZWxmLT5wYXJlbnQgPSBOVUxMOworICBzZWxmLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvciA9IE5VTEw7CisgIHNlbGYtPm1lc3NhZ2UgPSBOVUxMOworICBzZWxmLT5vd25lci5yZXNldCgpOworCisgIHJldHVybiAwOworfQorCitpbnQgU2V0T3duZXIoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsCisgICAgICAgICAgICAgY29uc3Qgc2hhcmVkX3B0cjxNZXNzYWdlPiYgbmV3X293bmVyKSB7CisgIEdPT0dMRV9DSEVDS19BVFRBQ0hFRChzZWxmKTsKKworICBzZWxmLT5vd25lciA9IG5ld19vd25lcjsKKyAgY29uc3QgUHlfc3NpemVfdCBuID0gUHlMaXN0X0dFVF9TSVpFKHNlbGYtPmNoaWxkX21lc3NhZ2VzKTsKKyAgZm9yIChQeV9zc2l6ZV90IGkgPSAwOyBpIDwgbjsgKytpKSB7CisgICAgUHlPYmplY3QqIG1zZyA9IFB5TGlzdF9HRVRfSVRFTShzZWxmLT5jaGlsZF9tZXNzYWdlcywgaSk7CisgICAgaWYgKGNtZXNzYWdlOjpTZXRPd25lcihyZWludGVycHJldF9jYXN0PENNZXNzYWdlKj4obXNnKSwgbmV3X293bmVyKSA9PSAtMSkgeworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gVGhlIHByaXZhdGUgY29uc3RydWN0b3Igb2YgUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIgb2JqZWN0cy4KK1B5T2JqZWN0ICpOZXdDb250YWluZXIoCisgICAgQ01lc3NhZ2UqIHBhcmVudCwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHBhcmVudF9maWVsZF9kZXNjcmlwdG9yLAorICAgIFB5T2JqZWN0ICpjb25jcmV0ZV9jbGFzcykgeworICBpZiAoIUNoZWNrRmllbGRCZWxvbmdzVG9NZXNzYWdlKHBhcmVudF9maWVsZF9kZXNjcmlwdG9yLCBwYXJlbnQtPm1lc3NhZ2UpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZiA9CisgICAgICByZWludGVycHJldF9jYXN0PFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKj4oCisgICAgICAgICAgUHlUeXBlX0dlbmVyaWNBbGxvYygmUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXJfVHlwZSwgMCkpOworICBpZiAoc2VsZiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBzZWxmLT5tZXNzYWdlID0gcGFyZW50LT5tZXNzYWdlOworICBzZWxmLT5wYXJlbnQgPSBwYXJlbnQ7CisgIHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yID0gcGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisgIHNlbGYtPm93bmVyID0gcGFyZW50LT5vd25lcjsKKyAgUHlfSU5DUkVGKGNvbmNyZXRlX2NsYXNzKTsKKyAgc2VsZi0+c3ViY2xhc3NfaW5pdCA9IGNvbmNyZXRlX2NsYXNzOworICBzZWxmLT5jaGlsZF9tZXNzYWdlcyA9IFB5TGlzdF9OZXcoMCk7CisKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihzZWxmKTsKK30KKworc3RhdGljIHZvaWQgRGVhbGxvYyhSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZikgeworICBQeV9DTEVBUihzZWxmLT5jaGlsZF9tZXNzYWdlcyk7CisgIFB5X0NMRUFSKHNlbGYtPnN1YmNsYXNzX2luaXQpOworICAvLyBUT0RPKHRpYmVsbCk6IERvIHdlIG5lZWQgdG8gY2FsbCBkZWxldGUgb24gdGhlc2Ugb2JqZWN0cyB0byBtYWtlCisgIC8vIHN1cmUgdGhlaXIgZGVzdHJ1Y3RvcnMgYXJlIGNhbGxlZD8KKyAgc2VsZi0+b3duZXIucmVzZXQoKTsKKworICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBTcU1ldGhvZHMgPSB7CisgIChsZW5mdW5jKUxlbmd0aCwgICAgICAgIC8qIHNxX2xlbmd0aCAqLworICAwLCAvKiBzcV9jb25jYXQgKi8KKyAgMCwgLyogc3FfcmVwZWF0ICovCisgIChzc2l6ZWFyZ2Z1bmMpSXRlbSAvKiBzcV9pdGVtICovCit9OworCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyBNcE1ldGhvZHMgPSB7CisgIChsZW5mdW5jKUxlbmd0aCwgICAgICAgICAgICAgICAvKiBtcF9sZW5ndGggKi8KKyAgKGJpbmFyeWZ1bmMpU3Vic2NyaXB0LCAgICAgIC8qIG1wX3N1YnNjcmlwdCAqLworICAob2Jqb2JqYXJncHJvYylBc3NpZ25TdWJzY3JpcHQsLyogbXBfYXNzX3N1YnNjcmlwdCAqLworfTsKKworc3RhdGljIFB5TWV0aG9kRGVmIE1ldGhvZHNbXSA9IHsKKyAgeyAiYWRkIiwgKFB5Q0Z1bmN0aW9uKSBBZGQsIE1FVEhfVkFSQVJHUyB8IE1FVEhfS0VZV09SRFMsCisgICAgIkFkZHMgYW4gb2JqZWN0IHRvIHRoZSByZXBlYXRlZCBjb250YWluZXIuIiB9LAorICB7ICJleHRlbmQiLCAoUHlDRnVuY3Rpb24pIEV4dGVuZCwgTUVUSF9PLAorICAgICJBZGRzIG9iamVjdHMgdG8gdGhlIHJlcGVhdGVkIGNvbnRhaW5lci4iIH0sCisgIHsgInBvcCIsIChQeUNGdW5jdGlvbilQb3AsIE1FVEhfVkFSQVJHUywKKyAgICAiUmVtb3ZlcyBhbiBvYmplY3QgZnJvbSB0aGUgcmVwZWF0ZWQgY29udGFpbmVyIGFuZCByZXR1cm5zIGl0LiIgfSwKKyAgeyAicmVtb3ZlIiwgKFB5Q0Z1bmN0aW9uKSBSZW1vdmUsIE1FVEhfTywKKyAgICAiUmVtb3ZlcyBhbiBvYmplY3QgZnJvbSB0aGUgcmVwZWF0ZWQgY29udGFpbmVyLiIgfSwKKyAgeyAic29ydCIsIChQeUNGdW5jdGlvbikgU29ydCwgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywKKyAgICAiU29ydHMgdGhlIHJlcGVhdGVkIGNvbnRhaW5lci4iIH0sCisgIHsgIk1lcmdlRnJvbSIsIChQeUNGdW5jdGlvbikgTWVyZ2VGcm9tLCBNRVRIX08sCisgICAgIkFkZHMgb2JqZWN0cyB0byB0aGUgcmVwZWF0ZWQgY29udGFpbmVyLiIgfSwKKyAgeyBOVUxMLCBOVUxMIH0KK307CisKK30gIC8vIG5hbWVzcGFjZSByZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyCisKK1B5VHlwZU9iamVjdCBSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lcl9UeXBlID0geworICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAvLyBLZWVwIHRoZSBmdWxseSBxdWFsaWZpZWQgX21lc3NhZ2Ugc3ltYm9sIGluIGEgbGluZSBmb3Igb3BlbnNvdXJjZS4KKyAgImdvb2dsZS5wcm90b2J1Zi5weWV4dC5fbWVzc2FnZS4iCisgICJSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciIsICAgICAgICAvLyB0cF9uYW1lCisgIHNpemVvZihSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciksICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9pdGVtc2l6ZQorICAoZGVzdHJ1Y3RvcilyZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyOjpEZWFsbG9jLCAgLy8gIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9hc19udW1iZXIKKyAgJnJlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXI6OlNxTWV0aG9kcywgICAvLyAgdHBfYXNfc2VxdWVuY2UKKyAgJnJlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXI6Ok1wTWV0aG9kcywgICAvLyAgdHBfYXNfbWFwcGluZworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2hhc2gKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jYWxsCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfc3RyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZ2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9zZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2FzX2J1ZmZlcgorICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAgLy8gIHRwX2ZsYWdzCisgICJBIFJlcGVhdGVkIHNjYWxhciBjb250YWluZXIiLCAgICAgICAvLyAgdHBfZG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfdHJhdmVyc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jbGVhcgorICAocmljaGNtcGZ1bmMpcmVwZWF0ZWRfY29tcG9zaXRlX2NvbnRhaW5lcjo6UmljaENvbXBhcmUsICAvLyAgdHBfcmljaGNvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF93ZWFrbGlzdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2l0ZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9pdGVybmV4dAorICByZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyOjpNZXRob2RzLCAgIC8vICB0cF9tZXRob2RzCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfbWVtYmVycworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2dldHNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2Jhc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9kaWN0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGVzY3JfZ2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGVzY3Jfc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGljdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2luaXQKK307CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyLmggYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTdjZWUwCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyLmgKQEAgLTAsMCArMSwxNzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGFudXJhYWdAZ29vZ2xlLmNvbSAoQW51cmFhZyBBZ3Jhd2FsKQorLy8gQXV0aG9yOiB0aWJlbGxAZ29vZ2xlLmNvbSAoSm9oYW4gVGliZWxsKQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1JFUEVBVEVEX0NPTVBPU0lURV9DT05UQUlORVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1JFUEVBVEVEX0NPTVBPU0lURV9DT05UQUlORVJfSF9fCisKKyNpbmNsdWRlIDxQeXRob24uaD4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIEZpZWxkRGVzY3JpcHRvcjsKK2NsYXNzIE1lc3NhZ2U7CisKK3VzaW5nIGludGVybmFsOjpzaGFyZWRfcHRyOworCituYW1lc3BhY2UgcHl0aG9uIHsKKworc3RydWN0IENNZXNzYWdlOworCisvLyBBIFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyIGNhbiBiZSBpbiBvbmUgb2YgdHdvIHN0YXRlczogYXR0YWNoZWQKKy8vIG9yIHJlbGVhc2VkLgorLy8KKy8vIFdoZW4gaW4gdGhlIGF0dGFjaGVkIHN0YXRlIGFsbCBtb2RpZmljYXRpb25zIHRvIHRoZSBjb250YWluZXIgYXJlCisvLyBkb25lIGJvdGggb24gdGhlICdtZXNzYWdlJyBhbmQgb24gdGhlICdjaGlsZF9tZXNzYWdlcycKKy8vIGxpc3QuICBJbiB0aGlzIHN0YXRlIGFsbCBNZXNzYWdlcyByZWZlcnJlZCB0byBieSB0aGUgY2hpbGRyZW4gaW4KKy8vICdjaGlsZF9tZXNzYWdlcycgYXJlIG93bmVyIGJ5IHRoZSAnb3duZXInLgorLy8KKy8vIFdoZW4gaW4gdGhlIHJlbGVhc2VkIHN0YXRlICdtZXNzYWdlJywgJ293bmVyJywgJ3BhcmVudCcsIGFuZAorLy8gJ3BhcmVudF9maWVsZF9kZXNjcmlwdG9yJyBhcmUgTlVMTC4KK3R5cGVkZWYgc3RydWN0IFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyIHsKKyAgUHlPYmplY3RfSEVBRDsKKworICAvLyBUaGlzIGlzIHRoZSB0b3AtbGV2ZWwgQysrIE1lc3NhZ2Ugb2JqZWN0IHRoYXQgb3ducyB0aGUgd2hvbGUKKyAgLy8gcHJvdG8gdHJlZS4gIEV2ZXJ5IFB5dGhvbiBSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciBob2xkcyBhCisgIC8vIHJlZmVyZW5jZSB0byBpdCBpbiBvcmRlciB0byBrZWVwIGl0IGFsaXZlIGFzIGxvbmcgYXMgdGhlcmUncyBhCisgIC8vIFB5dGhvbiBvYmplY3QgdGhhdCByZWZlcmVuY2VzIGFueSBwYXJ0IG9mIHRoZSB0cmVlLgorICBzaGFyZWRfcHRyPE1lc3NhZ2U+IG93bmVyOworCisgIC8vIFdlYWsgcmVmZXJlbmNlIHRvIHBhcmVudCBvYmplY3QuIE1heSBiZSBOVUxMLiBVc2VkIHRvIG1ha2Ugc3VyZQorICAvLyB0aGUgcGFyZW50IGlzIHdyaXRhYmxlIGJlZm9yZSBtb2RpZnlpbmcgdGhlCisgIC8vIFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyLgorICBDTWVzc2FnZSogcGFyZW50OworCisgIC8vIEEgZGVzY3JpcHRvciB1c2VkIHRvIG1vZGlmeSB0aGUgdW5kZXJseWluZyAnbWVzc2FnZScuCisgIC8vIFRoZSBwb2ludGVyIGlzIG93bmVkIGJ5IHRoZSBnbG9iYWwgRGVzY3JpcHRvclBvb2wuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisKKyAgLy8gUG9pbnRlciB0byB0aGUgQysrIE1lc3NhZ2UgdGhhdCBjb250YWlucyB0aGlzIGNvbnRhaW5lci4gIFRoZQorICAvLyBSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciBkb2VzIG5vdCBvd24gdGhpcyBwb2ludGVyLgorICAvLworICAvLyBJZiBOVUxMLCB0aGlzIG1lc3NhZ2UgaGFzIGJlZW4gcmVsZWFzZWQgZnJvbSBpdHMgcGFyZW50IChieQorICAvLyBjYWxsaW5nIENsZWFyKCkgb3IgQ2xlYXJGaWVsZCgpIG9uIHRoZSBwYXJlbnQuCisgIE1lc3NhZ2UqIG1lc3NhZ2U7CisKKyAgLy8gQSBjYWxsYWJsZSB0aGF0IGlzIHVzZWQgdG8gY3JlYXRlIG5ldyBjaGlsZCBtZXNzYWdlcy4KKyAgUHlPYmplY3QqIHN1YmNsYXNzX2luaXQ7CisKKyAgLy8gQSBsaXN0IG9mIGNoaWxkIG1lc3NhZ2VzLgorICBQeU9iamVjdCogY2hpbGRfbWVzc2FnZXM7Cit9IFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyOworCitleHRlcm4gUHlUeXBlT2JqZWN0IFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyX1R5cGU7CisKK25hbWVzcGFjZSByZXBlYXRlZF9jb21wb3NpdGVfY29udGFpbmVyIHsKKworLy8gQnVpbGRzIGEgUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIgb2JqZWN0LCBmcm9tIGEgcGFyZW50IG1lc3NhZ2UgYW5kIGEKKy8vIGZpZWxkIGRlc2NyaXB0b3IuCitQeU9iamVjdCAqTmV3Q29udGFpbmVyKAorICAgIENNZXNzYWdlKiBwYXJlbnQsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBwYXJlbnRfZmllbGRfZGVzY3JpcHRvciwKKyAgICBQeU9iamVjdCAqY29uY3JldGVfY2xhc3MpOworCisvLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhpcyByZXBlYXRlZCBjb21wb3NpdGUgY29udGFpbmVyLgorc3RhdGljIFB5X3NzaXplX3QgTGVuZ3RoKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmKTsKKworLy8gQXBwZW5kcyBhIG5ldyBDTWVzc2FnZSB0byB0aGUgY29udGFpbmVyIGFuZCByZXR1cm5zIGl0LiAgVGhlCisvLyBDTWVzc2FnZSBpcyBpbml0aWFsaXplZCB1c2luZyB0aGUgY29udGVudCBvZiBrd2FyZ3MuCisvLworLy8gUmV0dXJucyBhIG5ldyByZWZlcmVuY2UgaWYgc3VjY2Vzc2Z1bDsgcmV0dXJucyBOVUxMIGFuZCBzZXRzIGFuCisvLyBleGNlcHRpb24gaWYgdW5zdWNjZXNzZnVsLgorUHlPYmplY3QqIEFkZChSZXBlYXRlZENvbXBvc2l0ZUNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgUHlPYmplY3QqIGFyZ3MsCisgICAgICAgICAgICAgIFB5T2JqZWN0KiBrd2FyZ3MpOworCisvLyBBcHBlbmRzIGFsbCB0aGUgQ01lc3NhZ2VzIGluIHRoZSBpbnB1dCBpdGVyYXRvciB0byB0aGUgY29udGFpbmVyLgorLy8KKy8vIFJldHVybnMgTm9uZSBpZiBzdWNjZXNzZnVsOyByZXR1cm5zIE5VTEwgYW5kIHNldHMgYW4gZXhjZXB0aW9uIGlmCisvLyB1bnN1Y2Nlc3NmdWwuCitQeU9iamVjdCogRXh0ZW5kKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogdmFsdWUpOworCisvLyBBcHBlbmRzIGEgbmV3IG1lc3NhZ2UgdG8gdGhlIGNvbnRhaW5lciBmb3IgZWFjaCBtZXNzYWdlIGluIHRoZQorLy8gaW5wdXQgaXRlcmF0b3IsIG1lcmdpbmcgZWFjaCBkYXRhIGVsZW1lbnQgaW4uIEVxdWl2YWxlbnQgdG8gZXh0ZW5kLgorLy8KKy8vIFJldHVybnMgTm9uZSBpZiBzdWNjZXNzZnVsOyByZXR1cm5zIE5VTEwgYW5kIHNldHMgYW4gZXhjZXB0aW9uIGlmCisvLyB1bnN1Y2Nlc3NmdWwuCitQeU9iamVjdCogTWVyZ2VGcm9tKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogb3RoZXIpOworCisvLyBBY2Nlc3NlcyBtZXNzYWdlcyBpbiB0aGUgY29udGFpbmVyLgorLy8KKy8vIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlIHRvIHRoZSBtZXNzYWdlIGZvciBhbiBpbnRlZ2VyIHBhcmFtZXRlci4KKy8vIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlIHRvIGEgbGlzdCBvZiBtZXNzYWdlcyBmb3IgYSBzbGljZS4KK1B5T2JqZWN0KiBTdWJzY3JpcHQoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBzbGljZSk7CisKKy8vIERlbGV0ZXMgaXRlbXMgZnJvbSB0aGUgY29udGFpbmVyIChjYW5ub3QgYmUgdXNlZCBmb3IgYXNzaWdubWVudCkuCisvLworLy8gUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGZhaWx1cmUuCitpbnQgQXNzaWduU3Vic2NyaXB0KFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmLAorICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogc2xpY2UsCisgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiB2YWx1ZSk7CisKKy8vIFJlbGVhc2VzIHRoZSBtZXNzYWdlcyBpbiB0aGUgY29udGFpbmVyIHRvIHRoZSBnaXZlbiBtZXNzYWdlLgorLy8KKy8vIFJldHVybnMgMCBvbiBzdWNjZXNzLCAtMSBvbiBmYWlsdXJlLgoraW50IFJlbGVhc2VUb01lc3NhZ2UoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsIE1lc3NhZ2UqIG5ld19tZXNzYWdlKTsKKworLy8gUmVsZWFzZXMgdGhlIG1lc3NhZ2VzIGluIHRoZSBjb250YWluZXIgdG8gYSBuZXcgbWVzc2FnZS4KKy8vCisvLyBSZXR1cm5zIDAgb24gc3VjY2VzcywgLTEgb24gZmFpbHVyZS4KK2ludCBSZWxlYXNlKFJlcGVhdGVkQ29tcG9zaXRlQ29udGFpbmVyKiBzZWxmKTsKKworLy8gUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGZhaWx1cmUuCitpbnQgU2V0T3duZXIoUmVwZWF0ZWRDb21wb3NpdGVDb250YWluZXIqIHNlbGYsCisgICAgICAgICAgICAgY29uc3Qgc2hhcmVkX3B0cjxNZXNzYWdlPiYgbmV3X293bmVyKTsKKworLy8gUmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50IG9mIHRoZSByZXBlYXRlZCBtZXNzYWdlIGZpZWxkICdmaWVsZCcgb24KKy8vIHRoZSBNZXNzYWdlICdtZXNzYWdlJywgYW5kIHRyYW5zZmVycyB0aGUgb3duZXJzaGlwIG9mIHRoZSByZWxlYXNlZAorLy8gTWVzc2FnZSB0byAnY21lc3NhZ2UnLgorLy8KKy8vIENvcnJlc3BvbmRzIHRvIHJlZmxlY3Rpb24gYXBpIG1ldGhvZCBSZWxlYXNlTWVzc2FnZS4KK3ZvaWQgUmVsZWFzZUxhc3RUbyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgQ01lc3NhZ2UqIGNtZXNzYWdlKTsKKworfSAgLy8gbmFtZXNwYWNlIHJlcGVhdGVkX2NvbXBvc2l0ZV9jb250YWluZXIKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1JFUEVBVEVEX0NPTVBPU0lURV9DT05UQUlORVJfSF9fCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX3NjYWxhcl9jb250YWluZXIuY2MgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX3NjYWxhcl9jb250YWluZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTEwYTRjOAotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lci5jYwpAQCAtMCwwICsxLDgxMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYW51cmFhZ0Bnb29nbGUuY29tIChBbnVyYWFnIEFncmF3YWwpCisvLyBBdXRob3I6IHRpYmVsbEBnb29nbGUuY29tIChKb2hhbiBUaWJlbGwpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lci5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcHlleHQvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9weWV4dC9zY29wZWRfcHlvYmplY3RfcHRyLmg+CisKKyNpZiBQWV9NQUpPUl9WRVJTSU9OID49IDMKKyAgI2RlZmluZSBQeUludF9Gcm9tTG9uZyBQeUxvbmdfRnJvbUxvbmcKKyAgI2lmIFBZX1ZFUlNJT05fSEVYIDwgMHgwMzAzMDAwMAorICAgICNlcnJvciAiUHl0aG9uIDMuMCAtIDMuMiBhcmUgbm90IHN1cHBvcnRlZC4iCisgICNlbHNlCisgICNkZWZpbmUgUHlTdHJpbmdfQXNTdHJpbmcob2IpIFwKKyAgICAoUHlVbmljb2RlX0NoZWNrKG9iKT8gUHlVbmljb2RlX0FzVVRGOChvYik6IFB5Qnl0ZXNfQXNTdHJpbmcob2IpKQorICAjZW5kaWYKKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworbmFtZXNwYWNlIHJlcGVhdGVkX3NjYWxhcl9jb250YWluZXIgeworCitzdGF0aWMgaW50IEludGVybmFsQXNzaWduUmVwZWF0ZWRGaWVsZCgKKyAgICBSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIGxpc3QpIHsKKyAgc2VsZi0+bWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5DbGVhckZpZWxkKHNlbGYtPm1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvcik7CisgIGZvciAoUHlfc3NpemVfdCBpID0gMDsgaSA8IFB5TGlzdF9HRVRfU0laRShsaXN0KTsgKytpKSB7CisgICAgUHlPYmplY3QqIHZhbHVlID0gUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGkpOworICAgIGlmIChBcHBlbmQoc2VsZiwgdmFsdWUpID09IE5VTEwpIHsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90IExlbihSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZikgeworICBNZXNzYWdlKiBtZXNzYWdlID0gc2VsZi0+bWVzc2FnZTsKKyAgcmV0dXJuIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKCptZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IpOworfQorCitzdGF0aWMgaW50IEFzc2lnbkl0ZW0oUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogYXJnKSB7CisgIGNtZXNzYWdlOjpBc3N1cmVXcml0YWJsZShzZWxmLT5wYXJlbnQpOworICBNZXNzYWdlKiBtZXNzYWdlID0gc2VsZi0+bWVzc2FnZTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yID0gc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgaW50IGZpZWxkX3NpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IpOworICBpZiAoaW5kZXggPCAwKSB7CisgICAgaW5kZXggPSBmaWVsZF9zaXplICsgaW5kZXg7CisgIH0KKyAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmaWVsZF9zaXplKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0luZGV4RXJyb3IsCisgICAgICAgICAgICAgICAgICJsaXN0IGFzc2lnbm1lbnQgaW5kZXggKCVkKSBvdXQgb2YgcmFuZ2UiLAorICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KGluZGV4KSk7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgaWYgKGFyZyA9PSBOVUxMKSB7CisgICAgU2NvcGVkUHlPYmplY3RQdHIgcHlfaW5kZXgoUHlMb25nX0Zyb21Mb25nKGluZGV4KSk7CisgICAgcmV0dXJuIGNtZXNzYWdlOjpJbnRlcm5hbERlbGV0ZVJlcGVhdGVkRmllbGQobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBweV9pbmRleCwgTlVMTCk7CisgIH0KKworICBpZiAoUHlTZXF1ZW5jZV9DaGVjayhhcmcpICYmICEoUHlCeXRlc19DaGVjayhhcmcpIHx8IFB5VW5pY29kZV9DaGVjayhhcmcpKSkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJWYWx1ZSBtdXN0IGJlIHNjYWxhciIpOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIHN3aXRjaCAoZmllbGRfZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX0lOVDMyKGFyZywgdmFsdWUsIC0xKTsKKyAgICAgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaW5kZXgsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9JTlQ2NChhcmcsIHZhbHVlLCAtMSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEludDY0KG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4LCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX1VJTlQzMihhcmcsIHZhbHVlLCAtMSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFVJbnQzMihtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCBpbmRleCwgdmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9VSU5UNjQoYXJnLCB2YWx1ZSwgLTEpOworICAgICAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaW5kZXgsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9GTE9BVChhcmcsIHZhbHVlLCAtMSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEZsb2F0KG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4LCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX0RPVUJMRShhcmcsIHZhbHVlLCAtMSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZERvdWJsZShtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCBpbmRleCwgdmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfQk9PTChhcmcsIHZhbHVlLCAtMSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEJvb2wobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaW5kZXgsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6IHsKKyAgICAgIGlmICghQ2hlY2tBbmRTZXRTdHJpbmcoCisgICAgICAgICAgYXJnLCBtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCByZWZsZWN0aW9uLCBmYWxzZSwgaW5kZXgpKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX0lOVDMyKGFyZywgdmFsdWUsIC0xKTsKKyAgICAgIGlmIChyZWZsZWN0aW9uLT5TdXBwb3J0c1Vua25vd25FbnVtVmFsdWVzKCkpIHsKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3IgPSBmaWVsZF9kZXNjcmlwdG9yLT5lbnVtX3R5cGUoKTsKKyAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICBlbnVtX2Rlc2NyaXB0b3ItPkZpbmRWYWx1ZUJ5TnVtYmVyKHZhbHVlKTsKKyAgICAgICAgaWYgKGVudW1fdmFsdWUgIT0gTlVMTCkgeworICAgICAgICAgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRW51bShtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bV92YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgU2NvcGVkUHlPYmplY3RQdHIgcyhQeU9iamVjdF9TdHIoYXJnKSk7CisgICAgICAgICAgaWYgKHMgIT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsICJVbmtub3duIGVudW0gdmFsdWU6ICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19Bc1N0cmluZyhzKSk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICBQeUVycl9Gb3JtYXQoCisgICAgICAgICAgUHlFeGNfU3lzdGVtRXJyb3IsICJBZGRpbmcgdmFsdWUgdG8gYSBmaWVsZCBvZiB1bmtub3duIHR5cGUgJWQiLAorICAgICAgICAgIGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkpOworICAgICAgcmV0dXJuIC0xOworICB9CisgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QqIEl0ZW0oUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIHNlbGYsIFB5X3NzaXplX3QgaW5kZXgpIHsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHNlbGYtPm1lc3NhZ2U7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZGVzY3JpcHRvciA9IHNlbGYtPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIGludCBmaWVsZF9zaXplID0gcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgaWYgKGluZGV4IDwgMCkgeworICAgIGluZGV4ID0gZmllbGRfc2l6ZSArIGluZGV4OworICB9CisgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZmllbGRfc2l6ZSkgeworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19JbmRleEVycm9yLAorICAgICAgICAgICAgICAgICAibGlzdCBpbmRleCAoJXpkKSBvdXQgb2YgcmFuZ2UiLAorICAgICAgICAgICAgICAgICBpbmRleCk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBQeU9iamVjdCogcmVzdWx0ID0gTlVMTDsKKyAgc3dpdGNoIChmaWVsZF9kZXNjcmlwdG9yLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6IHsKKyAgICAgIGludDMyIHZhbHVlID0gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMigKKyAgICAgICAgICAqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaW5kZXgpOworICAgICAgcmVzdWx0ID0gUHlJbnRfRnJvbUxvbmcodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OiB7CisgICAgICBpbnQ2NCB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQoCisgICAgICAgICAgKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4KTsKKyAgICAgIHJlc3VsdCA9IFB5TG9uZ19Gcm9tTG9uZ0xvbmcodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjogeworICAgICAgdWludDMyIHZhbHVlID0gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIoCisgICAgICAgICAgKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4KTsKKyAgICAgIHJlc3VsdCA9IFB5TG9uZ19Gcm9tTG9uZ0xvbmcodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDogeworICAgICAgdWludDY0IHZhbHVlID0gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQoCisgICAgICAgICAgKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4KTsKKyAgICAgIHJlc3VsdCA9IFB5TG9uZ19Gcm9tVW5zaWduZWRMb25nTG9uZyh2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6IHsKKyAgICAgIGZsb2F0IHZhbHVlID0gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRGbG9hdCgKKyAgICAgICAgICAqbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgaW5kZXgpOworICAgICAgcmVzdWx0ID0gUHlGbG9hdF9Gcm9tRG91YmxlKHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6IHsKKyAgICAgIGRvdWJsZSB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRG91YmxlKAorICAgICAgICAgICptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCBpbmRleCk7CisgICAgICByZXN1bHQgPSBQeUZsb2F0X0Zyb21Eb3VibGUodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6IHsKKyAgICAgIGJvb2wgdmFsdWUgPSByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEJvb2woCisgICAgICAgICAgKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4KTsKKyAgICAgIHJlc3VsdCA9IFB5Qm9vbF9Gcm9tTG9uZyh2YWx1ZSA/IDEgOiAwKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOiB7CisgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlID0KKyAgICAgICAgICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkRW51bSgKKyAgICAgICAgICAgICAgKm1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIGluZGV4KTsKKyAgICAgIHJlc3VsdCA9IFB5SW50X0Zyb21Mb25nKGVudW1fdmFsdWUtPm51bWJlcigpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6IHsKKyAgICAgIHN0cmluZyB2YWx1ZSA9IHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKAorICAgICAgICAgICptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCBpbmRleCk7CisgICAgICByZXN1bHQgPSBUb1N0cmluZ09iamVjdChmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgUHlPYmplY3QqIHB5X2Ntc2cgPSBQeU9iamVjdF9DYWxsT2JqZWN0KHJlaW50ZXJwcmV0X2Nhc3Q8UHlPYmplY3QqPigKKyAgICAgICAgICAmQ01lc3NhZ2VfVHlwZSksIE5VTEwpOworICAgICAgaWYgKHB5X2Ntc2cgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICAgIENNZXNzYWdlKiBjbXNnID0gcmVpbnRlcnByZXRfY2FzdDxDTWVzc2FnZSo+KHB5X2Ntc2cpOworICAgICAgY29uc3QgTWVzc2FnZSYgbXNnID0gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgICAgICAgICptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCBpbmRleCk7CisgICAgICBjbXNnLT5vd25lciA9IHNlbGYtPm93bmVyOworICAgICAgY21zZy0+cGFyZW50ID0gc2VsZi0+cGFyZW50OworICAgICAgY21zZy0+bWVzc2FnZSA9IGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZtc2cpOworICAgICAgY21zZy0+cmVhZF9vbmx5ID0gZmFsc2U7CisgICAgICByZXN1bHQgPSByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4ocHlfY21zZyk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIFB5RXJyX0Zvcm1hdCgKKyAgICAgICAgICBQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAiR2V0dGluZyB2YWx1ZSBmcm9tIGEgcmVwZWF0ZWQgZmllbGQgb2YgdW5rbm93biB0eXBlICVkIiwKKyAgICAgICAgICBmaWVsZF9kZXNjcmlwdG9yLT5jcHBfdHlwZSgpKTsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogU3Vic2NyaXB0KFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogc2xpY2UpIHsKKyAgUHlfc3NpemVfdCBmcm9tOworICBQeV9zc2l6ZV90IHRvOworICBQeV9zc2l6ZV90IHN0ZXA7CisgIFB5X3NzaXplX3QgbGVuZ3RoOworICBQeV9zc2l6ZV90IHNsaWNlbGVuZ3RoOworICBib29sIHJldHVybl9saXN0ID0gZmFsc2U7CisjaWYgUFlfTUFKT1JfVkVSU0lPTiA8IDMKKyAgaWYgKFB5SW50X0NoZWNrKHNsaWNlKSkgeworICAgIGZyb20gPSB0byA9IFB5SW50X0FzTG9uZyhzbGljZSk7CisgIH0gZWxzZSAgLy8gTk9MSU5UCisjZW5kaWYKKyAgaWYgKFB5TG9uZ19DaGVjayhzbGljZSkpIHsKKyAgICBmcm9tID0gdG8gPSBQeUxvbmdfQXNMb25nKHNsaWNlKTsKKyAgfSBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKHNsaWNlKSkgeworICAgIGxlbmd0aCA9IExlbihzZWxmKTsKKyNpZiBQWV9NQUpPUl9WRVJTSU9OID49IDMKKyAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoc2xpY2UsCisjZWxzZQorICAgIGlmIChQeVNsaWNlX0dldEluZGljZXNFeChyZWludGVycHJldF9jYXN0PFB5U2xpY2VPYmplY3QqPihzbGljZSksCisjZW5kaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLCAmZnJvbSwgJnRvLCAmc3RlcCwgJnNsaWNlbGVuZ3RoKSA9PSAtMSkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybl9saXN0ID0gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAibGlzdCBpbmRpY2VzIG11c3QgYmUgaW50ZWdlcnMiKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIGlmICghcmV0dXJuX2xpc3QpIHsKKyAgICByZXR1cm4gSXRlbShzZWxmLCBmcm9tKTsKKyAgfQorCisgIFB5T2JqZWN0KiBsaXN0ID0gUHlMaXN0X05ldygwKTsKKyAgaWYgKGxpc3QgPT0gTlVMTCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChmcm9tIDw9IHRvKSB7CisgICAgaWYgKHN0ZXAgPCAwKSB7CisgICAgICByZXR1cm4gbGlzdDsKKyAgICB9CisgICAgZm9yIChQeV9zc2l6ZV90IGluZGV4ID0gZnJvbTsgaW5kZXggPCB0bzsgaW5kZXggKz0gc3RlcCkgeworICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBsZW5ndGgpIHsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBTY29wZWRQeU9iamVjdFB0ciBzKEl0ZW0oc2VsZiwgaW5kZXgpKTsKKyAgICAgIFB5TGlzdF9BcHBlbmQobGlzdCwgcyk7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChzdGVwID4gMCkgeworICAgICAgcmV0dXJuIGxpc3Q7CisgICAgfQorICAgIGZvciAoUHlfc3NpemVfdCBpbmRleCA9IGZyb207IGluZGV4ID4gdG87IGluZGV4ICs9IHN0ZXApIHsKKyAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gbGVuZ3RoKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgU2NvcGVkUHlPYmplY3RQdHIgcyhJdGVtKHNlbGYsIGluZGV4KSk7CisgICAgICBQeUxpc3RfQXBwZW5kKGxpc3QsIHMpOworICAgIH0KKyAgfQorICByZXR1cm4gbGlzdDsKK30KKworUHlPYmplY3QqIEFwcGVuZChSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwgUHlPYmplY3QqIGl0ZW0pIHsKKyAgY21lc3NhZ2U6OkFzc3VyZVdyaXRhYmxlKHNlbGYtPnBhcmVudCk7CisgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBzZWxmLT5tZXNzYWdlOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IgPSBzZWxmLT5wYXJlbnRfZmllbGRfZGVzY3JpcHRvcjsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBzd2l0Y2ggKGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9JTlQzMihpdGVtLCB2YWx1ZSwgTlVMTCk7CisgICAgICByZWZsZWN0aW9uLT5BZGRJbnQzMihtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfSU5UNjQoaXRlbSwgdmFsdWUsIE5VTEwpOworICAgICAgcmVmbGVjdGlvbi0+QWRkSW50NjQobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgdmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9VSU5UMzIoaXRlbSwgdmFsdWUsIE5VTEwpOworICAgICAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfVUlOVDY0KGl0ZW0sIHZhbHVlLCBOVUxMKTsKKyAgICAgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6IHsKKyAgICAgIEdPT0dMRV9DSEVDS19HRVRfRkxPQVQoaXRlbSwgdmFsdWUsIE5VTEwpOworICAgICAgcmVmbGVjdGlvbi0+QWRkRmxvYXQobWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgdmFsdWUpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRTogeworICAgICAgR09PR0xFX0NIRUNLX0dFVF9ET1VCTEUoaXRlbSwgdmFsdWUsIE5VTEwpOworICAgICAgcmVmbGVjdGlvbi0+QWRkRG91YmxlKG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX0JPT0woaXRlbSwgdmFsdWUsIE5VTEwpOworICAgICAgcmVmbGVjdGlvbi0+QWRkQm9vbChtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICBpZiAoIUNoZWNrQW5kU2V0U3RyaW5nKAorICAgICAgICAgIGl0ZW0sIG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIHJlZmxlY3Rpb24sIHRydWUsIC0xKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOiB7CisgICAgICBHT09HTEVfQ0hFQ0tfR0VUX0lOVDMyKGl0ZW0sIHZhbHVlLCBOVUxMKTsKKyAgICAgIGlmIChyZWZsZWN0aW9uLT5TdXBwb3J0c1Vua25vd25FbnVtVmFsdWVzKCkpIHsKKyAgICAgICAgcmVmbGVjdGlvbi0+QWRkRW51bVZhbHVlKG1lc3NhZ2UsIGZpZWxkX2Rlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3IgPSBmaWVsZF9kZXNjcmlwdG9yLT5lbnVtX3R5cGUoKTsKKyAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICBlbnVtX2Rlc2NyaXB0b3ItPkZpbmRWYWx1ZUJ5TnVtYmVyKHZhbHVlKTsKKyAgICAgICAgaWYgKGVudW1fdmFsdWUgIT0gTlVMTCkgeworICAgICAgICAgIHJlZmxlY3Rpb24tPkFkZEVudW0obWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgZW51bV92YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgU2NvcGVkUHlPYmplY3RQdHIgcyhQeU9iamVjdF9TdHIoaXRlbSkpOworICAgICAgICAgIGlmIChzICE9IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLCAiVW5rbm93biBlbnVtIHZhbHVlOiAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcocykpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICBQeUVycl9Gb3JtYXQoCisgICAgICAgICAgUHlFeGNfU3lzdGVtRXJyb3IsICJBZGRpbmcgdmFsdWUgdG8gYSBmaWVsZCBvZiB1bmtub3duIHR5cGUgJWQiLAorICAgICAgICAgIGZpZWxkX2Rlc2NyaXB0b3ItPmNwcF90eXBlKCkpOworICAgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBQeV9SRVRVUk5fTk9ORTsKK30KKworc3RhdGljIGludCBBc3NTdWJzY3JpcHQoUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogc2xpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogdmFsdWUpIHsKKyAgUHlfc3NpemVfdCBmcm9tOworICBQeV9zc2l6ZV90IHRvOworICBQeV9zc2l6ZV90IHN0ZXA7CisgIFB5X3NzaXplX3QgbGVuZ3RoOworICBQeV9zc2l6ZV90IHNsaWNlbGVuZ3RoOworICBib29sIGNyZWF0ZV9saXN0ID0gZmFsc2U7CisKKyAgY21lc3NhZ2U6OkFzc3VyZVdyaXRhYmxlKHNlbGYtPnBhcmVudCk7CisgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBzZWxmLT5tZXNzYWdlOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IgPQorICAgICAgc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisKKyNpZiBQWV9NQUpPUl9WRVJTSU9OIDwgMworICBpZiAoUHlJbnRfQ2hlY2soc2xpY2UpKSB7CisgICAgZnJvbSA9IHRvID0gUHlJbnRfQXNMb25nKHNsaWNlKTsKKyAgfSBlbHNlCisjZW5kaWYKKyAgaWYgKFB5TG9uZ19DaGVjayhzbGljZSkpIHsKKyAgICBmcm9tID0gdG8gPSBQeUxvbmdfQXNMb25nKHNsaWNlKTsKKyAgfSBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKHNsaWNlKSkgeworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgbGVuZ3RoID0gcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyNpZiBQWV9NQUpPUl9WRVJTSU9OID49IDMKKyAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoc2xpY2UsCisjZWxzZQorICAgIGlmIChQeVNsaWNlX0dldEluZGljZXNFeChyZWludGVycHJldF9jYXN0PFB5U2xpY2VPYmplY3QqPihzbGljZSksCisjZW5kaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLCAmZnJvbSwgJnRvLCAmc3RlcCwgJnNsaWNlbGVuZ3RoKSA9PSAtMSkgeworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBjcmVhdGVfbGlzdCA9IHRydWU7CisgIH0gZWxzZSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgImxpc3QgaW5kaWNlcyBtdXN0IGJlIGludGVnZXJzIik7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgaWYgKHZhbHVlID09IE5VTEwpIHsKKyAgICByZXR1cm4gY21lc3NhZ2U6OkludGVybmFsRGVsZXRlUmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvciwgc2xpY2UsIE5VTEwpOworICB9CisKKyAgaWYgKCFjcmVhdGVfbGlzdCkgeworICAgIHJldHVybiBBc3NpZ25JdGVtKHNlbGYsIGZyb20sIHZhbHVlKTsKKyAgfQorCisgIFNjb3BlZFB5T2JqZWN0UHRyIGZ1bGxfc2xpY2UoUHlTbGljZV9OZXcoTlVMTCwgTlVMTCwgTlVMTCkpOworICBpZiAoZnVsbF9zbGljZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIC0xOworICB9CisgIFNjb3BlZFB5T2JqZWN0UHRyIG5ld19saXN0KFN1YnNjcmlwdChzZWxmLCBmdWxsX3NsaWNlKSk7CisgIGlmIChuZXdfbGlzdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIC0xOworICB9CisgIGlmIChQeVNlcXVlbmNlX1NldFNsaWNlKG5ld19saXN0LCBmcm9tLCB0bywgdmFsdWUpIDwgMCkgeworICAgIHJldHVybiAtMTsKKyAgfQorCisgIHJldHVybiBJbnRlcm5hbEFzc2lnblJlcGVhdGVkRmllbGQoc2VsZiwgbmV3X2xpc3QpOworfQorCitQeU9iamVjdCogRXh0ZW5kKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogdmFsdWUpIHsKKyAgY21lc3NhZ2U6OkFzc3VyZVdyaXRhYmxlKHNlbGYtPnBhcmVudCk7CisKKyAgLy8gVE9ETyhwdHVja2VyKTogRGVwcmVjYXRlIHRoaXMgYmVoYXZpb3IuIGIvMTg0MTM4NjIKKyAgaWYgKHZhbHVlID09IFB5X05vbmUpIHsKKyAgICBQeV9SRVRVUk5fTk9ORTsKKyAgfQorICBpZiAoKFB5X1RZUEUodmFsdWUpLT50cF9hc19zZXF1ZW5jZSA9PSBOVUxMKSAmJiBQeU9iamVjdF9Ob3QodmFsdWUpKSB7CisgICAgUHlfUkVUVVJOX05PTkU7CisgIH0KKworICBTY29wZWRQeU9iamVjdFB0ciBpdGVyKFB5T2JqZWN0X0dldEl0ZXIodmFsdWUpKTsKKyAgaWYgKGl0ZXIgPT0gTlVMTCkgeworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJWYWx1ZSBtdXN0IGJlIGl0ZXJhYmxlIik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgbmV4dDsKKyAgd2hpbGUgKChuZXh0LnJlc2V0KFB5SXRlcl9OZXh0KGl0ZXIpKSkgIT0gTlVMTCkgeworICAgIGlmIChBcHBlbmQoc2VsZiwgbmV4dCkgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogSW5zZXJ0KFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogYXJncykgeworICBQeV9zc2l6ZV90IGluZGV4OworICBQeU9iamVjdCogdmFsdWU7CisgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibE8iLCAmaW5kZXgsICZ2YWx1ZSkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBTY29wZWRQeU9iamVjdFB0ciBmdWxsX3NsaWNlKFB5U2xpY2VfTmV3KE5VTEwsIE5VTEwsIE5VTEwpKTsKKyAgU2NvcGVkUHlPYmplY3RQdHIgbmV3X2xpc3QoU3Vic2NyaXB0KHNlbGYsIGZ1bGxfc2xpY2UpKTsKKyAgaWYgKFB5TGlzdF9JbnNlcnQobmV3X2xpc3QsIGluZGV4LCB2YWx1ZSkgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaW50IHJldCA9IEludGVybmFsQXNzaWduUmVwZWF0ZWRGaWVsZChzZWxmLCBuZXdfbGlzdCk7CisgIGlmIChyZXQgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogUmVtb3ZlKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogdmFsdWUpIHsKKyAgUHlfc3NpemVfdCBtYXRjaF9pbmRleCA9IC0xOworICBmb3IgKFB5X3NzaXplX3QgaSA9IDA7IGkgPCBMZW4oc2VsZik7ICsraSkgeworICAgIFNjb3BlZFB5T2JqZWN0UHRyIGVsZW0oSXRlbShzZWxmLCBpKSk7CisgICAgaWYgKFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChlbGVtLCB2YWx1ZSwgUHlfRVEpKSB7CisgICAgICBtYXRjaF9pbmRleCA9IGk7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgaWYgKG1hdGNoX2luZGV4ID09IC0xKSB7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJyZW1vdmUoeCk6IHggbm90IGluIGNvbnRhaW5lciIpOworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChBc3NpZ25JdGVtKHNlbGYsIG1hdGNoX2luZGV4LCBOVUxMKSA8IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeV9SRVRVUk5fTk9ORTsKK30KKworc3RhdGljIFB5T2JqZWN0KiBSaWNoQ29tcGFyZShSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QqIG90aGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb3BpZCkgeworICBpZiAob3BpZCAhPSBQeV9FUSAmJiBvcGlkICE9IFB5X05FKSB7CisgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgIH0KKworICAvLyBDb3B5IHRoZSBjb250ZW50cyBvZiB0aGlzIHJlcGVhdGVkIHNjYWxhciBjb250YWluZXIsIGFuZCBvdGhlciBpZiBpdCBpcworICAvLyBhbHNvIGEgcmVwZWF0ZWQgc2NhbGFyIGNvbnRhaW5lciwgaW50byBQeXRob24gbGlzdHMgc28gd2UgY2FuIGRlbGVnYXRlCisgIC8vIHRvIHRoZSBsaXN0J3MgY29tcGFyZSBtZXRob2QuCisKKyAgU2NvcGVkUHlPYmplY3RQdHIgZnVsbF9zbGljZShQeVNsaWNlX05ldyhOVUxMLCBOVUxMLCBOVUxMKSk7CisgIGlmIChmdWxsX3NsaWNlID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIFNjb3BlZFB5T2JqZWN0UHRyIG90aGVyX2xpc3RfZGVsZXRlcjsKKyAgaWYgKFB5T2JqZWN0X1R5cGVDaGVjayhvdGhlciwgJlJlcGVhdGVkU2NhbGFyQ29udGFpbmVyX1R5cGUpKSB7CisgICAgb3RoZXJfbGlzdF9kZWxldGVyLnJlc2V0KFN1YnNjcmlwdCgKKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFNjYWxhckNvbnRhaW5lcio+KG90aGVyKSwgZnVsbF9zbGljZSkpOworICAgIG90aGVyID0gb3RoZXJfbGlzdF9kZWxldGVyLmdldCgpOworICB9CisKKyAgU2NvcGVkUHlPYmplY3RQdHIgbGlzdChTdWJzY3JpcHQoc2VsZiwgZnVsbF9zbGljZSkpOworICBpZiAobGlzdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlKGxpc3QsIG90aGVyLCBvcGlkKTsKK30KKworUHlPYmplY3QqIFJlZHVjZShSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogdW51c2VkX3NlbGYpIHsKKyAgUHlFcnJfRm9ybWF0KAorICAgICAgUGlja2xlRXJyb3JfY2xhc3MsCisgICAgICAiY2FuJ3QgcGlja2xlIHJlcGVhdGVkIG1lc3NhZ2UgZmllbGRzLCBjb252ZXJ0IHRvIGxpc3QgZmlyc3QiKTsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCogU29ydChSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCogYXJncywKKyAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCoga3dkcykgeworICAvLyBTdXBwb3J0IHRoZSBvbGQgc29ydF9mdW5jdGlvbiBhcmd1bWVudCBmb3IgYmFja3dhcmRzCisgIC8vIGNvbXBhdGliaWxpdHkuCisgIGlmIChrd2RzICE9IE5VTEwpIHsKKyAgICBQeU9iamVjdCogc29ydF9mdW5jID0gUHlEaWN0X0dldEl0ZW1TdHJpbmcoa3dkcywgInNvcnRfZnVuY3Rpb24iKTsKKyAgICBpZiAoc29ydF9mdW5jICE9IE5VTEwpIHsKKyAgICAgIC8vIE11c3Qgc2V0IGJlZm9yZSBkZWxldGluZyBhcyBzb3J0X2Z1bmMgaXMgYSBib3Jyb3dlZCByZWZlcmVuY2UKKyAgICAgIC8vIGFuZCBrd2RzIG1pZ2h0IGJlIHRoZSBvbmx5IHRoaW5nIGtlZXBpbmcgaXQgYWxpdmUuCisgICAgICBpZiAoUHlEaWN0X1NldEl0ZW1TdHJpbmcoa3dkcywgImNtcCIsIHNvcnRfZnVuYykgPT0gLTEpCisgICAgICAgIHJldHVybiBOVUxMOworICAgICAgaWYgKFB5RGljdF9EZWxJdGVtU3RyaW5nKGt3ZHMsICJzb3J0X2Z1bmN0aW9uIikgPT0gLTEpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgfQorCisgIFNjb3BlZFB5T2JqZWN0UHRyIGZ1bGxfc2xpY2UoUHlTbGljZV9OZXcoTlVMTCwgTlVMTCwgTlVMTCkpOworICBpZiAoZnVsbF9zbGljZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgbGlzdChTdWJzY3JpcHQoc2VsZiwgZnVsbF9zbGljZSkpOworICBpZiAobGlzdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgbShQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGxpc3QsICJzb3J0IikpOworICBpZiAobSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgU2NvcGVkUHlPYmplY3RQdHIgcmVzKFB5T2JqZWN0X0NhbGwobSwgYXJncywga3dkcykpOworICBpZiAocmVzID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpbnQgcmV0ID0gSW50ZXJuYWxBc3NpZ25SZXBlYXRlZEZpZWxkKHNlbGYsIGxpc3QpOworICBpZiAocmV0IDwgMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIFB5X1JFVFVSTl9OT05FOworfQorCitzdGF0aWMgUHlPYmplY3QqIFBvcChSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBhcmdzKSB7CisgIFB5X3NzaXplX3QgaW5kZXggPSAtMTsKKyAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8biIsICZpbmRleCkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBQeU9iamVjdCogaXRlbSA9IEl0ZW0oc2VsZiwgaW5kZXgpOworICBpZiAoaXRlbSA9PSBOVUxMKSB7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0luZGV4RXJyb3IsCisgICAgICAgICAgICAgICAgICJsaXN0IGluZGV4ICglemQpIG91dCBvZiByYW5nZSIsCisgICAgICAgICAgICAgICAgIGluZGV4KTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoQXNzaWduSXRlbShzZWxmLCBpbmRleCwgTlVMTCkgPCAwKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgcmV0dXJuIGl0ZW07Cit9CisKKy8vIFRoZSBwcml2YXRlIGNvbnN0cnVjdG9yIG9mIFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyIG9iamVjdHMuCitQeU9iamVjdCAqTmV3Q29udGFpbmVyKAorICAgIENNZXNzYWdlKiBwYXJlbnQsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IpIHsKKyAgaWYgKCFDaGVja0ZpZWxkQmVsb25nc1RvTWVzc2FnZShwYXJlbnRfZmllbGRfZGVzY3JpcHRvciwgcGFyZW50LT5tZXNzYWdlKSkgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIHNlbGYgPSByZWludGVycHJldF9jYXN0PFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKj4oCisgICAgICBQeVR5cGVfR2VuZXJpY0FsbG9jKCZSZXBlYXRlZFNjYWxhckNvbnRhaW5lcl9UeXBlLCAwKSk7CisgIGlmIChzZWxmID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIHNlbGYtPm1lc3NhZ2UgPSBwYXJlbnQtPm1lc3NhZ2U7CisgIHNlbGYtPnBhcmVudCA9IHBhcmVudDsKKyAgc2VsZi0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IgPSBwYXJlbnRfZmllbGRfZGVzY3JpcHRvcjsKKyAgc2VsZi0+b3duZXIgPSBwYXJlbnQtPm93bmVyOworCisgIHJldHVybiByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oc2VsZik7Cit9CisKKy8vIEluaXRpYWxpemVzIHRoZSB1bmRlcmx5aW5nIE1lc3NhZ2Ugb2JqZWN0IG9mICJ0byIgc28gaXQgYmVjb21lcyBhIG5ldyBwYXJlbnQKKy8vIHJlcGVhdGVkIHNjYWxhciwgYW5kIGNvcGllcyBhbGwgdGhlIHZhbHVlcyBmcm9tICJmcm9tIiB0byBpdC4gQSBjaGlsZCBzY2FsYXIKKy8vIGNvbnRhaW5lciBjYW4gYmUgcmVsZWFzZWQgYnkgcGFzc2luZyBpdCBhcyBib3RoIGZyb20gYW5kIHRvIChlLmcuIG1ha2luZyBpdAorLy8gdGhlIHJlY2lwaWVudCBvZiB0aGUgbmV3IHBhcmVudCBtZXNzYWdlIGFuZCBjb3B5aW5nIHRoZSB2YWx1ZXMgZnJvbSBpdHNlbGYpLgorc3RhdGljIGludCBJbml0aWFsaXplQW5kQ29weVRvUGFyZW50Q29udGFpbmVyKAorICAgIFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBmcm9tLAorICAgIFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiB0bykgeworICBTY29wZWRQeU9iamVjdFB0ciBmdWxsX3NsaWNlKFB5U2xpY2VfTmV3KE5VTEwsIE5VTEwsIE5VTEwpKTsKKyAgaWYgKGZ1bGxfc2xpY2UgPT0gTlVMTCkgeworICAgIHJldHVybiAtMTsKKyAgfQorICBTY29wZWRQeU9iamVjdFB0ciB2YWx1ZXMoU3Vic2NyaXB0KGZyb20sIGZ1bGxfc2xpY2UpKTsKKyAgaWYgKHZhbHVlcyA9PSBOVUxMKSB7CisgICAgcmV0dXJuIC0xOworICB9CisgIE1lc3NhZ2UqIG5ld19tZXNzYWdlID0gY21lc3NhZ2U6OkdldE1lc3NhZ2VGYWN0b3J5KCktPkdldFByb3RvdHlwZSgKKyAgICAgIGZyb20tPm1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKSktPk5ldygpOworICB0by0+cGFyZW50ID0gTlVMTDsKKyAgdG8tPnBhcmVudF9maWVsZF9kZXNjcmlwdG9yID0gZnJvbS0+cGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3I7CisgIHRvLT5tZXNzYWdlID0gbmV3X21lc3NhZ2U7CisgIHRvLT5vd25lci5yZXNldChuZXdfbWVzc2FnZSk7CisgIGlmIChJbnRlcm5hbEFzc2lnblJlcGVhdGVkRmllbGQodG8sIHZhbHVlcykgPCAwKSB7CisgICAgcmV0dXJuIC0xOworICB9CisgIHJldHVybiAwOworfQorCitpbnQgUmVsZWFzZShSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZikgeworICByZXR1cm4gSW5pdGlhbGl6ZUFuZENvcHlUb1BhcmVudENvbnRhaW5lcihzZWxmLCBzZWxmKTsKK30KKworUHlPYmplY3QqIERlZXBDb3B5KFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogYXJnKSB7CisgIFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBjbG9uZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRTY2FsYXJDb250YWluZXIqPigKKyAgICAgIFB5VHlwZV9HZW5lcmljQWxsb2MoJlJlcGVhdGVkU2NhbGFyQ29udGFpbmVyX1R5cGUsIDApKTsKKyAgaWYgKGNsb25lID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIGlmIChJbml0aWFsaXplQW5kQ29weVRvUGFyZW50Q29udGFpbmVyKHNlbGYsIGNsb25lKSA8IDApIHsKKyAgICBQeV9ERUNSRUYoY2xvbmUpOworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiByZWludGVycHJldF9jYXN0PFB5T2JqZWN0Kj4oY2xvbmUpOworfQorCitzdGF0aWMgdm9pZCBEZWFsbG9jKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmKSB7CisgIHNlbGYtPm93bmVyLnJlc2V0KCk7CisgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUocmVpbnRlcnByZXRfY2FzdDxQeU9iamVjdCo+KHNlbGYpKTsKK30KKwordm9pZCBTZXRPd25lcihSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgY29uc3Qgc2hhcmVkX3B0cjxNZXNzYWdlPiYgbmV3X293bmVyKSB7CisgIHNlbGYtPm93bmVyID0gbmV3X293bmVyOworfQorCitzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgU3FNZXRob2RzID0geworICAobGVuZnVuYylMZW4sICAgICAgICAgICAvKiBzcV9sZW5ndGggKi8KKyAgMCwgLyogc3FfY29uY2F0ICovCisgIDAsIC8qIHNxX3JlcGVhdCAqLworICAoc3NpemVhcmdmdW5jKUl0ZW0sIC8qIHNxX2l0ZW0gKi8KKyAgMCwgLyogc3Ffc2xpY2UgKi8KKyAgKHNzaXplb2JqYXJncHJvYylBc3NpZ25JdGVtIC8qIHNxX2Fzc19pdGVtICovCit9OworCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyBNcE1ldGhvZHMgPSB7CisgIChsZW5mdW5jKUxlbiwgICAgICAgICAgICAgICAvKiBtcF9sZW5ndGggKi8KKyAgKGJpbmFyeWZ1bmMpU3Vic2NyaXB0LCAgICAgIC8qIG1wX3N1YnNjcmlwdCAqLworICAob2Jqb2JqYXJncHJvYylBc3NTdWJzY3JpcHQsIC8qIG1wX2Fzc19zdWJzY3JpcHQgKi8KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBNZXRob2RzW10gPSB7CisgIHsgIl9fZGVlcGNvcHlfXyIsIChQeUNGdW5jdGlvbilEZWVwQ29weSwgTUVUSF9WQVJBUkdTLAorICAgICJNYWtlcyBhIGRlZXAgY29weSBvZiB0aGUgY2xhc3MuIiB9LAorICB7ICJfX3JlZHVjZV9fIiwgKFB5Q0Z1bmN0aW9uKVJlZHVjZSwgTUVUSF9OT0FSR1MsCisgICAgIk91dHB1dHMgcGlja2xhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZXBlYXRlZCBmaWVsZC4iIH0sCisgIHsgImFwcGVuZCIsIChQeUNGdW5jdGlvbilBcHBlbmQsIE1FVEhfTywKKyAgICAiQXBwZW5kcyBhbiBvYmplY3QgdG8gdGhlIHJlcGVhdGVkIGNvbnRhaW5lci4iIH0sCisgIHsgImV4dGVuZCIsIChQeUNGdW5jdGlvbilFeHRlbmQsIE1FVEhfTywKKyAgICAiQXBwZW5kcyBvYmplY3RzIHRvIHRoZSByZXBlYXRlZCBjb250YWluZXIuIiB9LAorICB7ICJpbnNlcnQiLCAoUHlDRnVuY3Rpb24pSW5zZXJ0LCBNRVRIX1ZBUkFSR1MsCisgICAgIkFwcGVuZHMgb2JqZWN0cyB0byB0aGUgcmVwZWF0ZWQgY29udGFpbmVyLiIgfSwKKyAgeyAicG9wIiwgKFB5Q0Z1bmN0aW9uKVBvcCwgTUVUSF9WQVJBUkdTLAorICAgICJSZW1vdmVzIGFuIG9iamVjdCBmcm9tIHRoZSByZXBlYXRlZCBjb250YWluZXIgYW5kIHJldHVybnMgaXQuIiB9LAorICB7ICJyZW1vdmUiLCAoUHlDRnVuY3Rpb24pUmVtb3ZlLCBNRVRIX08sCisgICAgIlJlbW92ZXMgYW4gb2JqZWN0IGZyb20gdGhlIHJlcGVhdGVkIGNvbnRhaW5lci4iIH0sCisgIHsgInNvcnQiLCAoUHlDRnVuY3Rpb24pU29ydCwgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywKKyAgICAiU29ydHMgdGhlIHJlcGVhdGVkIGNvbnRhaW5lci4ifSwKKyAgeyBOVUxMLCBOVUxMIH0KK307CisKK30gIC8vIG5hbWVzcGFjZSByZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyCisKK1B5VHlwZU9iamVjdCBSZXBlYXRlZFNjYWxhckNvbnRhaW5lcl9UeXBlID0geworICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAvLyBLZWVwIHRoZSBmdWxseSBxdWFsaWZpZWQgX21lc3NhZ2Ugc3ltYm9sIGluIGEgbGluZSBmb3Igb3BlbnNvdXJjZS4KKyAgImdvb2dsZS5wcm90b2J1Zi5weWV4dC5fbWVzc2FnZS4iCisgICJSZXBlYXRlZFNjYWxhckNvbnRhaW5lciIsICAgICAgICAgICAvLyB0cF9uYW1lCisgIHNpemVvZihSZXBlYXRlZFNjYWxhckNvbnRhaW5lciksICAgICAvLyB0cF9iYXNpY3NpemUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9pdGVtc2l6ZQorICAoZGVzdHJ1Y3RvcilyZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyOjpEZWFsbG9jLCAgLy8gIHRwX2RlYWxsb2MKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9wcmludAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2dldGF0dHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9zZXRhdHRyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfY29tcGFyZQorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX3JlcHIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9hc19udW1iZXIKKyAgJnJlcGVhdGVkX3NjYWxhcl9jb250YWluZXI6OlNxTWV0aG9kcywgICAvLyAgdHBfYXNfc2VxdWVuY2UKKyAgJnJlcGVhdGVkX3NjYWxhcl9jb250YWluZXI6Ok1wTWV0aG9kcywgICAvLyAgdHBfYXNfbWFwcGluZworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2hhc2gKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jYWxsCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfc3RyCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZ2V0YXR0cm8KKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9zZXRhdHRybworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2FzX2J1ZmZlcgorICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAgLy8gIHRwX2ZsYWdzCisgICJBIFJlcGVhdGVkIHNjYWxhciBjb250YWluZXIiLCAgICAgICAvLyAgdHBfZG9jCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfdHJhdmVyc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9jbGVhcgorICAocmljaGNtcGZ1bmMpcmVwZWF0ZWRfc2NhbGFyX2NvbnRhaW5lcjo6UmljaENvbXBhcmUsICAvLyAgdHBfcmljaGNvbXBhcmUKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF93ZWFrbGlzdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2l0ZXIKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9pdGVybmV4dAorICByZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyOjpNZXRob2RzLCAgICAgIC8vICB0cF9tZXRob2RzCisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfbWVtYmVycworICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2dldHNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2Jhc2UKKyAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cF9kaWN0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGVzY3JfZ2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGVzY3Jfc2V0CisgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgdHBfZGljdG9mZnNldAorICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRwX2luaXQKK307CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyLmggYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX3NjYWxhcl9jb250YWluZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZGZhMjFlCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9weWV4dC9yZXBlYXRlZF9zY2FsYXJfY29udGFpbmVyLmgKQEAgLTAsMCArMSwxMTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGFudXJhYWdAZ29vZ2xlLmNvbSAoQW51cmFhZyBBZ3Jhd2FsKQorLy8gQXV0aG9yOiB0aWJlbGxAZ29vZ2xlLmNvbSAoSm9oYW4gVGliZWxsKQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1JFUEVBVEVEX1NDQUxBUl9DT05UQUlORVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1JFUEVBVEVEX1NDQUxBUl9DT05UQUlORVJfSF9fCisKKyNpbmNsdWRlIDxQeXRob24uaD4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgTWVzc2FnZTsKKwordXNpbmcgaW50ZXJuYWw6OnNoYXJlZF9wdHI7CisKK25hbWVzcGFjZSBweXRob24geworCitzdHJ1Y3QgQ01lc3NhZ2U7CisKK3R5cGVkZWYgc3RydWN0IFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyIHsKKyAgUHlPYmplY3RfSEVBRDsKKworICAvLyBUaGlzIGlzIHRoZSB0b3AtbGV2ZWwgQysrIE1lc3NhZ2Ugb2JqZWN0IHRoYXQgb3ducyB0aGUgd2hvbGUKKyAgLy8gcHJvdG8gdHJlZS4gIEV2ZXJ5IFB5dGhvbiBSZXBlYXRlZFNjYWxhckNvbnRhaW5lciBob2xkcyBhCisgIC8vIHJlZmVyZW5jZSB0byBpdCBpbiBvcmRlciB0byBrZWVwIGl0IGFsaXZlIGFzIGxvbmcgYXMgdGhlcmUncyBhCisgIC8vIFB5dGhvbiBvYmplY3QgdGhhdCByZWZlcmVuY2VzIGFueSBwYXJ0IG9mIHRoZSB0cmVlLgorICBzaGFyZWRfcHRyPE1lc3NhZ2U+IG93bmVyOworCisgIC8vIFBvaW50ZXIgdG8gdGhlIEMrKyBNZXNzYWdlIHRoYXQgY29udGFpbnMgdGhpcyBjb250YWluZXIuICBUaGUKKyAgLy8gUmVwZWF0ZWRTY2FsYXJDb250YWluZXIgZG9lcyBub3Qgb3duIHRoaXMgcG9pbnRlci4KKyAgTWVzc2FnZSogbWVzc2FnZTsKKworICAvLyBXZWFrIHJlZmVyZW5jZSB0byBhIHBhcmVudCBDTWVzc2FnZSBvYmplY3QgKGkuZS4gbWF5IGJlIE5VTEwuKQorICAvLworICAvLyBVc2VkIHRvIG1ha2Ugc3VyZSBhbGwgYW5jZXN0b3JzIGFyZSBhbHNvIG11dGFibGUgd2hlbiBmaXJzdAorICAvLyBtb2RpZnlpbmcgdGhlIGNvbnRhaW5lci4KKyAgQ01lc3NhZ2UqIHBhcmVudDsKKworICAvLyBQb2ludGVyIHRvIHRoZSBwYXJlbnQncyBkZXNjcmlwdG9yIHRoYXQgZGVzY3JpYmVzIHRoaXMKKyAgLy8gZmllbGQuICBVc2VkIHRvZ2V0aGVyIHdpdGggdGhlIHBhcmVudCdzIG1lc3NhZ2Ugd2hlbiBtYWtpbmcgYQorICAvLyBkZWZhdWx0IG1lc3NhZ2UgaW5zdGFuY2UgbXV0YWJsZS4KKyAgLy8gVGhlIHBvaW50ZXIgaXMgb3duZWQgYnkgdGhlIGdsb2JhbCBEZXNjcmlwdG9yUG9vbC4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBwYXJlbnRfZmllbGRfZGVzY3JpcHRvcjsKK30gUmVwZWF0ZWRTY2FsYXJDb250YWluZXI7CisKK2V4dGVybiBQeVR5cGVPYmplY3QgUmVwZWF0ZWRTY2FsYXJDb250YWluZXJfVHlwZTsKKworbmFtZXNwYWNlIHJlcGVhdGVkX3NjYWxhcl9jb250YWluZXIgeworCisvLyBCdWlsZHMgYSBSZXBlYXRlZFNjYWxhckNvbnRhaW5lciBvYmplY3QsIGZyb20gYSBwYXJlbnQgbWVzc2FnZSBhbmQgYQorLy8gZmllbGQgZGVzY3JpcHRvci4KK2V4dGVybiBQeU9iamVjdCAqTmV3Q29udGFpbmVyKAorICAgIENNZXNzYWdlKiBwYXJlbnQsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcGFyZW50X2ZpZWxkX2Rlc2NyaXB0b3IpOworCisvLyBBcHBlbmRzIHRoZSBzY2FsYXIgJ2l0ZW0nIHRvIHRoZSBlbmQgb2YgdGhlIGNvbnRhaW5lciAnc2VsZicuCisvLworLy8gUmV0dXJucyBOb25lIGlmIHN1Y2Nlc3NmdWw7IHJldHVybnMgTlVMTCBhbmQgc2V0cyBhbiBleGNlcHRpb24gaWYKKy8vIHVuc3VjY2Vzc2Z1bC4KK1B5T2JqZWN0KiBBcHBlbmQoUmVwZWF0ZWRTY2FsYXJDb250YWluZXIqIHNlbGYsIFB5T2JqZWN0KiBpdGVtKTsKKworLy8gUmVsZWFzZXMgdGhlIG1lc3NhZ2VzIGluIHRoZSBjb250YWluZXIgdG8gYSBuZXcgbWVzc2FnZS4KKy8vCisvLyBSZXR1cm5zIDAgb24gc3VjY2VzcywgLTEgb24gZmFpbHVyZS4KK2ludCBSZWxlYXNlKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmKTsKKworLy8gQXBwZW5kcyBhbGwgdGhlIGVsZW1lbnRzIGluIHRoZSBpbnB1dCBpdGVyYXRvciB0byB0aGUgY29udGFpbmVyLgorLy8KKy8vIFJldHVybnMgTm9uZSBpZiBzdWNjZXNzZnVsOyByZXR1cm5zIE5VTEwgYW5kIHNldHMgYW4gZXhjZXB0aW9uIGlmCisvLyB1bnN1Y2Nlc3NmdWwuCitQeU9iamVjdCogRXh0ZW5kKFJlcGVhdGVkU2NhbGFyQ29udGFpbmVyKiBzZWxmLCBQeU9iamVjdCogdmFsdWUpOworCisvLyBTZXQgdGhlIG93bmVyIGZpZWxkIG9mIHNlbGYgYW5kIGFueSBjaGlsZHJlbiBvZiBzZWxmLgordm9pZCBTZXRPd25lcihSZXBlYXRlZFNjYWxhckNvbnRhaW5lciogc2VsZiwKKyAgICAgICAgICAgICAgY29uc3Qgc2hhcmVkX3B0cjxNZXNzYWdlPiYgbmV3X293bmVyKTsKKworfSAgLy8gbmFtZXNwYWNlIHJlcGVhdGVkX3NjYWxhcl9jb250YWluZXIKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1JFUEVBVEVEX1NDQUxBUl9DT05UQUlORVJfSF9fCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3Njb3BlZF9weW9iamVjdF9wdHIuaCBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcHlleHQvc2NvcGVkX3B5b2JqZWN0X3B0ci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4ZGRkNWMKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3Njb3BlZF9weW9iamVjdF9wdHIuaApAQCAtMCwwICsxLDk3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB0aWJlbGxAZ29vZ2xlLmNvbSAoSm9oYW4gVGliZWxsKQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1NDT1BFRF9QWU9CSkVDVF9QVFJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1NDT1BFRF9QWU9CSkVDVF9QVFJfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpbmNsdWRlIDxQeXRob24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CitjbGFzcyBTY29wZWRQeU9iamVjdFB0ciB7CisgcHVibGljOgorICAvLyBDb25zdHJ1Y3Rvci4gIERlZmF1bHRzIHRvIGluaXRpYWxpemluZyB3aXRoIE5VTEwuCisgIC8vIFRoZXJlIGlzIG5vIHdheSB0byBjcmVhdGUgYW4gdW5pbml0aWFsaXplZCBTY29wZWRQeU9iamVjdFB0ci4KKyAgZXhwbGljaXQgU2NvcGVkUHlPYmplY3RQdHIoUHlPYmplY3QqIHAgPSBOVUxMKSA6IHB0cl8ocCkgeyB9CisKKyAgLy8gRGVzdHJ1Y3Rvci4gIElmIHRoZXJlIGlzIGEgUHlPYmplY3Qgb2JqZWN0LCBkZWxldGUgaXQuCisgIH5TY29wZWRQeU9iamVjdFB0cigpIHsKKyAgICBQeV9YREVDUkVGKHB0cl8pOworICB9CisKKyAgLy8gUmVzZXQuICBEZWxldGVzIHRoZSBjdXJyZW50IG93bmVkIG9iamVjdCwgaWYgYW55LgorICAvLyBUaGVuIHRha2VzIG93bmVyc2hpcCBvZiBhIG5ldyBvYmplY3QsIGlmIGdpdmVuLgorICAvLyB0aGlzLT5yZXNldCh0aGlzLT5nZXQoKSkgd29ya3MuCisgIFB5T2JqZWN0KiByZXNldChQeU9iamVjdCogcCA9IE5VTEwpIHsKKyAgICBpZiAocCAhPSBwdHJfKSB7CisgICAgICBQeV9YREVDUkVGKHB0cl8pOworICAgICAgcHRyXyA9IHA7CisgICAgfQorICAgIHJldHVybiBwdHJfOworICB9CisKKyAgLy8gUmVsZWFzZXMgb3duZXJzaGlwIG9mIHRoZSBvYmplY3QuCisgIFB5T2JqZWN0KiByZWxlYXNlKCkgeworICAgIFB5T2JqZWN0KiBwID0gcHRyXzsKKyAgICBwdHJfID0gTlVMTDsKKyAgICByZXR1cm4gcDsKKyAgfQorCisgIG9wZXJhdG9yIFB5T2JqZWN0KigpIHsgcmV0dXJuIHB0cl87IH0KKworICBQeU9iamVjdCogb3BlcmF0b3ItPigpIGNvbnN0ICB7CisgICAgYXNzZXJ0KHB0cl8gIT0gTlVMTCk7CisgICAgcmV0dXJuIHB0cl87CisgIH0KKworICBQeU9iamVjdCogZ2V0KCkgY29uc3QgeyByZXR1cm4gcHRyXzsgfQorCisgIFB5X3NzaXplX3QgcmVmY250KCkgY29uc3QgeyByZXR1cm4gUHlfUkVGQ05UKHB0cl8pOyB9CisKKyAgdm9pZCBpbmMoKSBjb25zdCB7IFB5X0lOQ1JFRihwdHJfKTsgfQorCisgIC8vIENvbXBhcmlzb24gb3BlcmF0b3JzLgorICAvLyBUaGVzZSByZXR1cm4gd2hldGhlciBhIFNjb3BlZFB5T2JqZWN0UHRyIGFuZCBhIHJhdyBwb2ludGVyCisgIC8vIHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdCwgbm90IGp1c3QgdG8gdHdvIGRpZmZlcmVudCBidXQgZXF1YWwKKyAgLy8gb2JqZWN0cy4KKyAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFB5T2JqZWN0KiBwKSBjb25zdCB7IHJldHVybiBwdHJfID09IHA7IH0KKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IFB5T2JqZWN0KiBwKSBjb25zdCB7IHJldHVybiBwdHJfICE9IHA7IH0KKworIHByaXZhdGU6CisgIFB5T2JqZWN0KiBwdHJfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTY29wZWRQeU9iamVjdFB0cik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QWVRIT05fQ1BQX1NDT1BFRF9QWU9CSkVDVF9QVFJfSF9fCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24ucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24ucHkKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNTVlNjUzYQotLS0gL2Rldi9udWxsCisrKyBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5weQpAQCAtMCwwICsxLDE5OSBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjIFRoaXMgY29kZSBpcyBtZWFudCB0byB3b3JrIG9uIFB5dGhvbiAyLjQgYW5kIGFib3ZlIG9ubHkuCisKKyIiIkNvbnRhaW5zIGEgbWV0YWNsYXNzIGFuZCBoZWxwZXIgZnVuY3Rpb25zIHVzZWQgdG8gY3JlYXRlCitwcm90b2NvbCBtZXNzYWdlIGNsYXNzZXMgZnJvbSBEZXNjcmlwdG9yIG9iamVjdHMgYXQgcnVudGltZS4KKworUmVjYWxsIHRoYXQgYSBtZXRhY2xhc3MgaXMgdGhlICJ0eXBlIiBvZiBhIGNsYXNzLgorKEEgY2xhc3MgaXMgdG8gYSBtZXRhY2xhc3Mgd2hhdCBhbiBpbnN0YW5jZSBpcyB0byBhIGNsYXNzLikKKworSW4gdGhpcyBjYXNlLCB3ZSB1c2UgdGhlIEdlbmVyYXRlZFByb3RvY29sTWVzc2FnZVR5cGUgbWV0YWNsYXNzCit0byBpbmplY3QgYWxsIHRoZSB1c2VmdWwgZnVuY3Rpb25hbGl0eSBpbnRvIHRoZSBjbGFzc2VzCitvdXRwdXQgYnkgdGhlIHByb3RvY29sIGNvbXBpbGVyIGF0IGNvbXBpbGUtdGltZS4KKworVGhlIHVwc2hvdCBvZiBhbGwgdGhpcyBpcyB0aGF0IHRoZSByZWFsIGltcGxlbWVudGF0aW9uCitkZXRhaWxzIGZvciBBTEwgcHVyZS1QeXRob24gcHJvdG9jb2wgYnVmZmVycyBhcmUgKmhlcmUgaW4KK3RoaXMgZmlsZSouCisiIiIKKworX19hdXRob3JfXyA9ICdyb2JpbnNvbkBnb29nbGUuY29tIChXaWxsIFJvYmluc29uKScKKworCitmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgYXBpX2ltcGxlbWVudGF0aW9uCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvciBhcyBkZXNjcmlwdG9yX21vZAorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2UKKworX0ZpZWxkRGVzY3JpcHRvciA9IGRlc2NyaXB0b3JfbW9kLkZpZWxkRGVzY3JpcHRvcgorCisKK2lmIGFwaV9pbXBsZW1lbnRhdGlvbi5UeXBlKCkgPT0gJ2NwcCc6CisgIGZyb20gZ29vZ2xlLnByb3RvYnVmLnB5ZXh0IGltcG9ydCBjcHBfbWVzc2FnZSBhcyBtZXNzYWdlX2ltcGwKK2Vsc2U6CisgIGZyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBweXRob25fbWVzc2FnZSBhcyBtZXNzYWdlX2ltcGwKKworX05ld01lc3NhZ2UgPSBtZXNzYWdlX2ltcGwuTmV3TWVzc2FnZQorX0luaXRNZXNzYWdlID0gbWVzc2FnZV9pbXBsLkluaXRNZXNzYWdlCisKKworY2xhc3MgR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZSh0eXBlKToKKworICAiIiJNZXRhY2xhc3MgZm9yIHByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcyBjcmVhdGVkIGF0IHJ1bnRpbWUgZnJvbSBEZXNjcmlwdG9ycy4KKworICBXZSBhZGQgaW1wbGVtZW50YXRpb25zIGZvciBhbGwgbWV0aG9kcyBkZXNjcmliZWQgaW4gdGhlIE1lc3NhZ2UgY2xhc3MuICBXZQorICBhbHNvIGNyZWF0ZSBwcm9wZXJ0aWVzIHRvIGFsbG93IGdldHRpbmcvc2V0dGluZyBhbGwgZmllbGRzIGluIHRoZSBwcm90b2NvbAorICBtZXNzYWdlLiAgRmluYWxseSwgd2UgY3JlYXRlIHNsb3RzIHRvIHByZXZlbnQgdXNlcnMgZnJvbSBhY2NpZGVudGFsbHkKKyAgInNldHRpbmciIG5vbmV4aXN0ZW50IGZpZWxkcyBpbiB0aGUgcHJvdG9jb2wgbWVzc2FnZSwgd2hpY2ggdGhlbiB3b3VsZG4ndCBnZXQKKyAgc2VyaWFsaXplZCAvIGRlc2VyaWFsaXplZCBwcm9wZXJseS4KKworICBUaGUgcHJvdG9jb2wgY29tcGlsZXIgY3VycmVudGx5IHVzZXMgdGhpcyBtZXRhY2xhc3MgdG8gY3JlYXRlIHByb3RvY29sCisgIG1lc3NhZ2UgY2xhc3NlcyBhdCBydW50aW1lLiAgQ2xpZW50cyBjYW4gYWxzbyBtYW51YWxseSBjcmVhdGUgdGhlaXIgb3duCisgIGNsYXNzZXMgYXQgcnVudGltZSwgYXMgaW4gdGhpcyBleGFtcGxlOgorCisgIG15ZGVzY3JpcHRvciA9IERlc2NyaXB0b3IoLi4uLi4pCisgIGNsYXNzIE15UHJvdG9DbGFzcyhNZXNzYWdlKToKKyAgICBfX21ldGFjbGFzc19fID0gR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZQorICAgIERFU0NSSVBUT1IgPSBteWRlc2NyaXB0b3IKKyAgbXlwcm90b19pbnN0YW5jZSA9IE15UHJvdG9DbGFzcygpCisgIG15cHJvdG8uZm9vX2ZpZWxkID0gMjMKKyAgLi4uCisKKyAgVGhlIGFib3ZlIGV4YW1wbGUgd2lsbCBub3Qgd29yayBmb3IgbmVzdGVkIHR5cGVzLiBJZiB5b3Ugd2lzaCB0byBpbmNsdWRlIHRoZW0sCisgIHVzZSByZWZsZWN0aW9uLk1ha2VDbGFzcygpIGluc3RlYWQgb2YgbWFudWFsbHkgaW5zdGFudGlhdGluZyB0aGUgY2xhc3MgaW4KKyAgb3JkZXIgdG8gY3JlYXRlIHRoZSBhcHByb3ByaWF0ZSBjbGFzcyBzdHJ1Y3R1cmUuCisgICIiIgorCisgICMgTXVzdCBiZSBjb25zaXN0ZW50IHdpdGggdGhlIHByb3RvY29sLWNvbXBpbGVyIGNvZGUgaW4KKyAgIyBwcm90bzIvY29tcGlsZXIvaW50ZXJuYWwvZ2VuZXJhdG9yLiouCisgIF9ERVNDUklQVE9SX0tFWSA9ICdERVNDUklQVE9SJworCisgIGRlZiBfX25ld19fKGNscywgbmFtZSwgYmFzZXMsIGRpY3Rpb25hcnkpOgorICAgICIiIkN1c3RvbSBhbGxvY2F0aW9uIGZvciBydW50aW1lLWdlbmVyYXRlZCBjbGFzcyB0eXBlcy4KKworICAgIFdlIG92ZXJyaWRlIF9fbmV3X18gYmVjYXVzZSB0aGlzIGlzIGFwcGFyZW50bHkgdGhlIG9ubHkgcGxhY2UKKyAgICB3aGVyZSB3ZSBjYW4gbWVhbmluZ2Z1bGx5IHNldCBfX3Nsb3RzX18gb24gdGhlIGNsYXNzIHdlJ3JlIGNyZWF0aW5nKD8pLgorICAgIChUaGUgaW50ZXJwbGF5IGJldHdlZW4gbWV0YWNsYXNzZXMgYW5kIHNsb3RzIGlzIG5vdCB2ZXJ5IHdlbGwtZG9jdW1lbnRlZCkuCisKKyAgICBBcmdzOgorICAgICAgbmFtZTogTmFtZSBvZiB0aGUgY2xhc3MgKGlnbm9yZWQsIGJ1dCByZXF1aXJlZCBieSB0aGUKKyAgICAgICAgbWV0YWNsYXNzIHByb3RvY29sKS4KKyAgICAgIGJhc2VzOiBCYXNlIGNsYXNzZXMgb2YgdGhlIGNsYXNzIHdlJ3JlIGNvbnN0cnVjdGluZy4KKyAgICAgICAgKFNob3VsZCBiZSBtZXNzYWdlLk1lc3NhZ2UpLiAgV2UgaWdub3JlIHRoaXMgZmllbGQsIGJ1dAorICAgICAgICBpdCdzIHJlcXVpcmVkIGJ5IHRoZSBtZXRhY2xhc3MgcHJvdG9jb2wKKyAgICAgIGRpY3Rpb25hcnk6IFRoZSBjbGFzcyBkaWN0aW9uYXJ5IG9mIHRoZSBjbGFzcyB3ZSdyZQorICAgICAgICBjb25zdHJ1Y3RpbmcuICBkaWN0aW9uYXJ5W19ERVNDUklQVE9SX0tFWV0gbXVzdCBjb250YWluCisgICAgICAgIGEgRGVzY3JpcHRvciBvYmplY3QgZGVzY3JpYmluZyB0aGlzIHByb3RvY29sIG1lc3NhZ2UKKyAgICAgICAgdHlwZS4KKworICAgIFJldHVybnM6CisgICAgICBOZXdseS1hbGxvY2F0ZWQgY2xhc3MuCisgICAgIiIiCisgICAgZGVzY3JpcHRvciA9IGRpY3Rpb25hcnlbR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZS5fREVTQ1JJUFRPUl9LRVldCisgICAgYmFzZXMgPSBfTmV3TWVzc2FnZShiYXNlcywgZGVzY3JpcHRvciwgZGljdGlvbmFyeSkKKyAgICBzdXBlcmNsYXNzID0gc3VwZXIoR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZSwgY2xzKQorCisgICAgbmV3X2NsYXNzID0gc3VwZXJjbGFzcy5fX25ld19fKGNscywgbmFtZSwgYmFzZXMsIGRpY3Rpb25hcnkpCisgICAgcmV0dXJuIG5ld19jbGFzcworCisgIGRlZiBfX2luaXRfXyhjbHMsIG5hbWUsIGJhc2VzLCBkaWN0aW9uYXJ5KToKKyAgICAiIiJIZXJlIHdlIHBlcmZvcm0gdGhlIG1ham9yaXR5IG9mIG91ciB3b3JrIG9uIHRoZSBjbGFzcy4KKyAgICBXZSBhZGQgZW51bSBnZXR0ZXJzLCBhbiBfX2luaXRfXyBtZXRob2QsIGltcGxlbWVudGF0aW9ucworICAgIG9mIGFsbCBNZXNzYWdlIG1ldGhvZHMsIGFuZCBwcm9wZXJ0aWVzIGZvciBhbGwgZmllbGRzCisgICAgaW4gdGhlIHByb3RvY29sIHR5cGUuCisKKyAgICBBcmdzOgorICAgICAgbmFtZTogTmFtZSBvZiB0aGUgY2xhc3MgKGlnbm9yZWQsIGJ1dCByZXF1aXJlZCBieSB0aGUKKyAgICAgICAgbWV0YWNsYXNzIHByb3RvY29sKS4KKyAgICAgIGJhc2VzOiBCYXNlIGNsYXNzZXMgb2YgdGhlIGNsYXNzIHdlJ3JlIGNvbnN0cnVjdGluZy4KKyAgICAgICAgKFNob3VsZCBiZSBtZXNzYWdlLk1lc3NhZ2UpLiAgV2UgaWdub3JlIHRoaXMgZmllbGQsIGJ1dAorICAgICAgICBpdCdzIHJlcXVpcmVkIGJ5IHRoZSBtZXRhY2xhc3MgcHJvdG9jb2wKKyAgICAgIGRpY3Rpb25hcnk6IFRoZSBjbGFzcyBkaWN0aW9uYXJ5IG9mIHRoZSBjbGFzcyB3ZSdyZQorICAgICAgICBjb25zdHJ1Y3RpbmcuICBkaWN0aW9uYXJ5W19ERVNDUklQVE9SX0tFWV0gbXVzdCBjb250YWluCisgICAgICAgIGEgRGVzY3JpcHRvciBvYmplY3QgZGVzY3JpYmluZyB0aGlzIHByb3RvY29sIG1lc3NhZ2UKKyAgICAgICAgdHlwZS4KKyAgICAiIiIKKyAgICBkZXNjcmlwdG9yID0gZGljdGlvbmFyeVtHZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlLl9ERVNDUklQVE9SX0tFWV0KKyAgICBfSW5pdE1lc3NhZ2UoZGVzY3JpcHRvciwgY2xzKQorICAgIHN1cGVyY2xhc3MgPSBzdXBlcihHZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlLCBjbHMpCisgICAgc3VwZXJjbGFzcy5fX2luaXRfXyhuYW1lLCBiYXNlcywgZGljdGlvbmFyeSkKKyAgICBzZXRhdHRyKGRlc2NyaXB0b3IsICdfY29uY3JldGVfY2xhc3MnLCBjbHMpCisKKworZGVmIFBhcnNlTWVzc2FnZShkZXNjcmlwdG9yLCBieXRlX3N0cik6CisgICIiIkdlbmVyYXRlIGEgbmV3IE1lc3NhZ2UgaW5zdGFuY2UgZnJvbSB0aGlzIERlc2NyaXB0b3IgYW5kIGEgYnl0ZSBzdHJpbmcuCisKKyAgQXJnczoKKyAgICBkZXNjcmlwdG9yOiBQcm90b2J1ZiBEZXNjcmlwdG9yIG9iamVjdAorICAgIGJ5dGVfc3RyOiBTZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBieXRlIHN0cmluZworCisgIFJldHVybnM6CisgICAgTmV3bHkgY3JlYXRlZCBwcm90b2J1ZiBNZXNzYWdlIG9iamVjdC4KKyAgIiIiCisgIHJlc3VsdF9jbGFzcyA9IE1ha2VDbGFzcyhkZXNjcmlwdG9yKQorICBuZXdfbXNnID0gcmVzdWx0X2NsYXNzKCkKKyAgbmV3X21zZy5QYXJzZUZyb21TdHJpbmcoYnl0ZV9zdHIpCisgIHJldHVybiBuZXdfbXNnCisKKworZGVmIE1ha2VDbGFzcyhkZXNjcmlwdG9yKToKKyAgIiIiQ29uc3RydWN0IGEgY2xhc3Mgb2JqZWN0IGZvciBhIHByb3RvYnVmIGRlc2NyaWJlZCBieSBkZXNjcmlwdG9yLgorCisgIENvbXBvc2l0ZSBkZXNjcmlwdG9ycyBhcmUgaGFuZGxlZCBieSBkZWZpbmluZyB0aGUgbmV3IGNsYXNzIGFzIGEgbWVtYmVyIG9mIHRoZQorICBwYXJlbnQgY2xhc3MsIHJlY3Vyc2luZyBhcyBkZWVwIGFzIG5lY2Vzc2FyeS4KKyAgVGhpcyBpcyB0aGUgZHluYW1pYyBlcXVpdmFsZW50IHRvOgorCisgIGNsYXNzIFBhcmVudChtZXNzYWdlLk1lc3NhZ2UpOgorICAgIF9fbWV0YWNsYXNzX18gPSBHZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlCisgICAgREVTQ1JJUFRPUiA9IGRlc2NyaXB0b3IKKyAgICBjbGFzcyBDaGlsZChtZXNzYWdlLk1lc3NhZ2UpOgorICAgICAgX19tZXRhY2xhc3NfXyA9IEdlbmVyYXRlZFByb3RvY29sTWVzc2FnZVR5cGUKKyAgICAgIERFU0NSSVBUT1IgPSBkZXNjcmlwdG9yLm5lc3RlZF90eXBlc1swXQorCisgIFNhbXBsZSB1c2FnZToKKyAgICBmaWxlX2Rlc2NyaXB0b3IgPSBkZXNjcmlwdG9yX3BiMi5GaWxlRGVzY3JpcHRvclByb3RvKCkKKyAgICBmaWxlX2Rlc2NyaXB0b3IuUGFyc2VGcm9tU3RyaW5nKHByb3RvMl9zdHJpbmcpCisgICAgbXNnX2Rlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLk1ha2VEZXNjcmlwdG9yKGZpbGVfZGVzY3JpcHRvci5tZXNzYWdlX3R5cGVbMF0pCisgICAgbXNnX2NsYXNzID0gcmVmbGVjdGlvbi5NYWtlQ2xhc3MobXNnX2Rlc2NyaXB0b3IpCisgICAgbXNnID0gbXNnX2NsYXNzKCkKKworICBBcmdzOgorICAgIGRlc2NyaXB0b3I6IEEgZGVzY3JpcHRvci5EZXNjcmlwdG9yIG9iamVjdCBkZXNjcmliaW5nIHRoZSBwcm90b2J1Zi4KKyAgUmV0dXJuczoKKyAgICBUaGUgTWVzc2FnZSBjbGFzcyBvYmplY3QgZGVzY3JpYmVkIGJ5IHRoZSBkZXNjcmlwdG9yLgorICAiIiIKKyAgYXR0cmlidXRlcyA9IHt9CisgIGZvciBuYW1lLCBuZXN0ZWRfdHlwZSBpbiBkZXNjcmlwdG9yLm5lc3RlZF90eXBlc19ieV9uYW1lLml0ZW1zKCk6CisgICAgYXR0cmlidXRlc1tuYW1lXSA9IE1ha2VDbGFzcyhuZXN0ZWRfdHlwZSkKKworICBhdHRyaWJ1dGVzW0dlbmVyYXRlZFByb3RvY29sTWVzc2FnZVR5cGUuX0RFU0NSSVBUT1JfS0VZXSA9IGRlc2NyaXB0b3IKKworICByZXR1cm4gR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZShzdHIoZGVzY3JpcHRvci5uYW1lKSwgKG1lc3NhZ2UuTWVzc2FnZSwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjllMDBkZTcKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UucHkKQEAgLTAsMCArMSwyMjYgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiREVQUkVDQVRFRDogIERlY2xhcmVzIHRoZSBSUEMgc2VydmljZSBpbnRlcmZhY2VzLgorCitUaGlzIG1vZHVsZSBkZWNsYXJlcyB0aGUgYWJzdHJhY3QgaW50ZXJmYWNlcyB1bmRlcmx5aW5nIHByb3RvMiBSUEMKK3NlcnZpY2VzLiAgVGhlc2UgYXJlIGludGVuZGVkIHRvIGJlIGluZGVwZW5kZW50IG9mIGFueSBwYXJ0aWN1bGFyIFJQQworaW1wbGVtZW50YXRpb24sIHNvIHRoYXQgcHJvdG8yIHNlcnZpY2VzIGNhbiBiZSB1c2VkIG9uIHRvcCBvZiBhIHZhcmlldHkKK29mIGltcGxlbWVudGF0aW9ucy4gIFN0YXJ0aW5nIHdpdGggdmVyc2lvbiAyLjMuMCwgUlBDIGltcGxlbWVudGF0aW9ucyBzaG91bGQKK25vdCB0cnkgdG8gYnVpbGQgb24gdGhlc2UsIGJ1dCBzaG91bGQgaW5zdGVhZCBwcm92aWRlIGNvZGUgZ2VuZXJhdG9yIHBsdWdpbnMKK3doaWNoIGdlbmVyYXRlIGNvZGUgc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIgUlBDIGltcGxlbWVudGF0aW9uLiAgVGhpcyB3YXkKK3RoZSBnZW5lcmF0ZWQgY29kZSBjYW4gYmUgbW9yZSBhcHByb3ByaWF0ZSBmb3IgdGhlIGltcGxlbWVudGF0aW9uIGluIHVzZQorYW5kIGNhbiBhdm9pZCB1bm5lY2Vzc2FyeSBsYXllcnMgb2YgaW5kaXJlY3Rpb24uCisiIiIKKworX19hdXRob3JfXyA9ICdwZXRhckBnb29nbGUuY29tIChQZXRhciBQZXRyb3YpJworCisKK2NsYXNzIFJwY0V4Y2VwdGlvbihFeGNlcHRpb24pOgorICAiIiJFeGNlcHRpb24gcmFpc2VkIG9uIGZhaWxlZCBibG9ja2luZyBSUEMgbWV0aG9kIGNhbGwuIiIiCisgIHBhc3MKKworCitjbGFzcyBTZXJ2aWNlKG9iamVjdCk6CisKKyAgIiIiQWJzdHJhY3QgYmFzZSBpbnRlcmZhY2UgZm9yIHByb3RvY29sLWJ1ZmZlci1iYXNlZCBSUEMgc2VydmljZXMuCisKKyAgU2VydmljZXMgdGhlbXNlbHZlcyBhcmUgYWJzdHJhY3QgY2xhc3NlcyAoaW1wbGVtZW50ZWQgZWl0aGVyIGJ5IHNlcnZlcnMgb3IgYXMKKyAgc3R1YnMpLCBidXQgdGhleSBzdWJjbGFzcyB0aGlzIGJhc2UgaW50ZXJmYWNlLiBUaGUgbWV0aG9kcyBvZiB0aGlzCisgIGludGVyZmFjZSBjYW4gYmUgdXNlZCB0byBjYWxsIHRoZSBtZXRob2RzIG9mIHRoZSBzZXJ2aWNlIHdpdGhvdXQga25vd2luZworICBpdHMgZXhhY3QgdHlwZSBhdCBjb21waWxlIHRpbWUgKGFuYWxvZ291cyB0byB0aGUgTWVzc2FnZSBpbnRlcmZhY2UpLgorICAiIiIKKworICBkZWYgR2V0RGVzY3JpcHRvcigpOgorICAgICIiIlJldHJpZXZlcyB0aGlzIHNlcnZpY2UncyBkZXNjcmlwdG9yLiIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgQ2FsbE1ldGhvZChzZWxmLCBtZXRob2RfZGVzY3JpcHRvciwgcnBjX2NvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgIHJlcXVlc3QsIGRvbmUpOgorICAgICIiIkNhbGxzIGEgbWV0aG9kIG9mIHRoZSBzZXJ2aWNlIHNwZWNpZmllZCBieSBtZXRob2RfZGVzY3JpcHRvci4KKworICAgIElmICJkb25lIiBpcyBOb25lIHRoZW4gdGhlIGNhbGwgaXMgYmxvY2tpbmcgYW5kIHRoZSByZXNwb25zZQorICAgIG1lc3NhZ2Ugd2lsbCBiZSByZXR1cm5lZCBkaXJlY3RseS4gIE90aGVyd2lzZSB0aGUgY2FsbCBpcyBhc3luY2hyb25vdXMKKyAgICBhbmQgImRvbmUiIHdpbGwgbGF0ZXIgYmUgY2FsbGVkIHdpdGggdGhlIHJlc3BvbnNlIHZhbHVlLgorCisgICAgSW4gdGhlIGJsb2NraW5nIGNhc2UsIFJwY0V4Y2VwdGlvbiB3aWxsIGJlIHJhaXNlZCBvbiBlcnJvci4KKworICAgIFByZWNvbmRpdGlvbnM6CisgICAgKiBtZXRob2RfZGVzY3JpcHRvci5zZXJ2aWNlID09IEdldERlc2NyaXB0b3IKKyAgICAqIHJlcXVlc3QgaXMgb2YgdGhlIGV4YWN0IHNhbWUgY2xhc3NlcyBhcyByZXR1cm5lZCBieQorICAgICAgR2V0UmVxdWVzdENsYXNzKG1ldGhvZCkuCisgICAgKiBBZnRlciB0aGUgY2FsbCBoYXMgc3RhcnRlZCwgdGhlIHJlcXVlc3QgbXVzdCBub3QgYmUgbW9kaWZpZWQuCisgICAgKiAicnBjX2NvbnRyb2xsZXIiIGlzIG9mIHRoZSBjb3JyZWN0IHR5cGUgZm9yIHRoZSBSUEMgaW1wbGVtZW50YXRpb24gYmVpbmcKKyAgICAgIHVzZWQgYnkgdGhpcyBTZXJ2aWNlLiAgRm9yIHN0dWJzLCB0aGUgImNvcnJlY3QgdHlwZSIgZGVwZW5kcyBvbiB0aGUKKyAgICAgIFJwY0NoYW5uZWwgd2hpY2ggdGhlIHN0dWIgaXMgdXNpbmcuCisKKyAgICBQb3N0Y29uZGl0aW9uczoKKyAgICAqICJkb25lIiB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBtZXRob2QgaXMgY29tcGxldGUuICBUaGlzIG1heSBiZQorICAgICAgYmVmb3JlIENhbGxNZXRob2QoKSByZXR1cm5zIG9yIGl0IG1heSBiZSBhdCBzb21lIHBvaW50IGluIHRoZSBmdXR1cmUuCisgICAgKiBJZiB0aGUgUlBDIGZhaWxlZCwgdGhlIHJlc3BvbnNlIHZhbHVlIHBhc3NlZCB0byAiZG9uZSIgd2lsbCBiZSBOb25lLgorICAgICAgRnVydGhlciBkZXRhaWxzIGFib3V0IHRoZSBmYWlsdXJlIGNhbiBiZSBmb3VuZCBieSBxdWVyeWluZyB0aGUKKyAgICAgIFJwY0NvbnRyb2xsZXIuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBHZXRSZXF1ZXN0Q2xhc3Moc2VsZiwgbWV0aG9kX2Rlc2NyaXB0b3IpOgorICAgICIiIlJldHVybnMgdGhlIGNsYXNzIG9mIHRoZSByZXF1ZXN0IG1lc3NhZ2UgZm9yIHRoZSBzcGVjaWZpZWQgbWV0aG9kLgorCisgICAgQ2FsbE1ldGhvZCgpIHJlcXVpcmVzIHRoYXQgdGhlIHJlcXVlc3QgaXMgb2YgYSBwYXJ0aWN1bGFyIHN1YmNsYXNzIG9mCisgICAgTWVzc2FnZS4gR2V0UmVxdWVzdENsYXNzKCkgZ2V0cyB0aGUgZGVmYXVsdCBpbnN0YW5jZSBvZiB0aGlzIHJlcXVpcmVkCisgICAgdHlwZS4KKworICAgIEV4YW1wbGU6CisgICAgICBtZXRob2QgPSBzZXJ2aWNlLkdldERlc2NyaXB0b3IoKS5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKQorICAgICAgcmVxdWVzdCA9IHN0dWIuR2V0UmVxdWVzdENsYXNzKG1ldGhvZCkoKQorICAgICAgcmVxdWVzdC5QYXJzZUZyb21TdHJpbmcoaW5wdXQpCisgICAgICBzZXJ2aWNlLkNhbGxNZXRob2QobWV0aG9kLCByZXF1ZXN0LCBjYWxsYmFjaykKKyAgICAiIiIKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKKyAgZGVmIEdldFJlc3BvbnNlQ2xhc3Moc2VsZiwgbWV0aG9kX2Rlc2NyaXB0b3IpOgorICAgICIiIlJldHVybnMgdGhlIGNsYXNzIG9mIHRoZSByZXNwb25zZSBtZXNzYWdlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGhvZC4KKworICAgIFRoaXMgbWV0aG9kIGlzbid0IHJlYWxseSBuZWVkZWQsIGFzIHRoZSBScGNDaGFubmVsJ3MgQ2FsbE1ldGhvZCBjb25zdHJ1Y3RzCisgICAgdGhlIHJlc3BvbnNlIHByb3RvY29sIG1lc3NhZ2UuIEl0J3MgcHJvdmlkZWQgYW55d2F5IGluIGNhc2UgaXQgaXMgdXNlZnVsCisgICAgZm9yIHRoZSBjYWxsZXIgdG8ga25vdyB0aGUgcmVzcG9uc2UgdHlwZSBpbiBhZHZhbmNlLgorICAgICIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworCitjbGFzcyBScGNDb250cm9sbGVyKG9iamVjdCk6CisKKyAgIiIiQW4gUnBjQ29udHJvbGxlciBtZWRpYXRlcyBhIHNpbmdsZSBtZXRob2QgY2FsbC4KKworICBUaGUgcHJpbWFyeSBwdXJwb3NlIG9mIHRoZSBjb250cm9sbGVyIGlzIHRvIHByb3ZpZGUgYSB3YXkgdG8gbWFuaXB1bGF0ZQorICBzZXR0aW5ncyBzcGVjaWZpYyB0byB0aGUgUlBDIGltcGxlbWVudGF0aW9uIGFuZCB0byBmaW5kIG91dCBhYm91dCBSUEMtbGV2ZWwKKyAgZXJyb3JzLiBUaGUgbWV0aG9kcyBwcm92aWRlZCBieSB0aGUgUnBjQ29udHJvbGxlciBpbnRlcmZhY2UgYXJlIGludGVuZGVkCisgIHRvIGJlIGEgImxlYXN0IGNvbW1vbiBkZW5vbWluYXRvciIgc2V0IG9mIGZlYXR1cmVzIHdoaWNoIHdlIGV4cGVjdCBhbGwKKyAgaW1wbGVtZW50YXRpb25zIHRvIHN1cHBvcnQuICBTcGVjaWZpYyBpbXBsZW1lbnRhdGlvbnMgbWF5IHByb3ZpZGUgbW9yZQorICBhZHZhbmNlZCBmZWF0dXJlcyAoZS5nLiBkZWFkbGluZSBwcm9wYWdhdGlvbikuCisgICIiIgorCisgICMgQ2xpZW50LXNpZGUgbWV0aG9kcyBiZWxvdworCisgIGRlZiBSZXNldChzZWxmKToKKyAgICAiIiJSZXNldHMgdGhlIFJwY0NvbnRyb2xsZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuCisKKyAgICBBZnRlciB0aGUgUnBjQ29udHJvbGxlciBoYXMgYmVlbiByZXNldCwgaXQgbWF5IGJlIHJldXNlZCBpbgorICAgIGEgbmV3IGNhbGwuIE11c3Qgbm90IGJlIGNhbGxlZCB3aGlsZSBhbiBSUEMgaXMgaW4gcHJvZ3Jlc3MuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBGYWlsZWQoc2VsZik6CisgICAgIiIiUmV0dXJucyB0cnVlIGlmIHRoZSBjYWxsIGZhaWxlZC4KKworICAgIEFmdGVyIGEgY2FsbCBoYXMgZmluaXNoZWQsIHJldHVybnMgdHJ1ZSBpZiB0aGUgY2FsbCBmYWlsZWQuICBUaGUgcG9zc2libGUKKyAgICByZWFzb25zIGZvciBmYWlsdXJlIGRlcGVuZCBvbiB0aGUgUlBDIGltcGxlbWVudGF0aW9uLiAgRmFpbGVkKCkgbXVzdCBub3QKKyAgICBiZSBjYWxsZWQgYmVmb3JlIGEgY2FsbCBoYXMgZmluaXNoZWQuICBJZiBGYWlsZWQoKSByZXR1cm5zIHRydWUsIHRoZQorICAgIGNvbnRlbnRzIG9mIHRoZSByZXNwb25zZSBtZXNzYWdlIGFyZSB1bmRlZmluZWQuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBFcnJvclRleHQoc2VsZik6CisgICAgIiIiSWYgRmFpbGVkIGlzIHRydWUsIHJldHVybnMgYSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgZXJyb3IuIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBTdGFydENhbmNlbChzZWxmKToKKyAgICAiIiJJbml0aWF0ZSBjYW5jZWxsYXRpb24uCisKKyAgICBBZHZpc2VzIHRoZSBSUEMgc3lzdGVtIHRoYXQgdGhlIGNhbGxlciBkZXNpcmVzIHRoYXQgdGhlIFJQQyBjYWxsIGJlCisgICAgY2FuY2VsZWQuICBUaGUgUlBDIHN5c3RlbSBtYXkgY2FuY2VsIGl0IGltbWVkaWF0ZWx5LCBtYXkgd2FpdCBhd2hpbGUgYW5kCisgICAgdGhlbiBjYW5jZWwgaXQsIG9yIG1heSBub3QgZXZlbiBjYW5jZWwgdGhlIGNhbGwgYXQgYWxsLiAgSWYgdGhlIGNhbGwgaXMKKyAgICBjYW5jZWxlZCwgdGhlICJkb25lIiBjYWxsYmFjayB3aWxsIHN0aWxsIGJlIGNhbGxlZCBhbmQgdGhlIFJwY0NvbnRyb2xsZXIKKyAgICB3aWxsIGluZGljYXRlIHRoYXQgdGhlIGNhbGwgZmFpbGVkIGF0IHRoYXQgdGltZS4KKyAgICAiIiIKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKKyAgIyBTZXJ2ZXItc2lkZSBtZXRob2RzIGJlbG93CisKKyAgZGVmIFNldEZhaWxlZChzZWxmLCByZWFzb24pOgorICAgICIiIlNldHMgYSBmYWlsdXJlIHJlYXNvbi4KKworICAgIENhdXNlcyBGYWlsZWQoKSB0byByZXR1cm4gdHJ1ZSBvbiB0aGUgY2xpZW50IHNpZGUuICAicmVhc29uIiB3aWxsIGJlCisgICAgaW5jb3Jwb3JhdGVkIGludG8gdGhlIG1lc3NhZ2UgcmV0dXJuZWQgYnkgRXJyb3JUZXh0KCkuICBJZiB5b3UgZmluZAorICAgIHlvdSBuZWVkIHRvIHJldHVybiBtYWNoaW5lLXJlYWRhYmxlIGluZm9ybWF0aW9uIGFib3V0IGZhaWx1cmVzLCB5b3UKKyAgICBzaG91bGQgaW5jb3Jwb3JhdGUgaXQgaW50byB5b3VyIHJlc3BvbnNlIHByb3RvY29sIGJ1ZmZlciBhbmQgc2hvdWxkCisgICAgTk9UIGNhbGwgU2V0RmFpbGVkKCkuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBJc0NhbmNlbGVkKHNlbGYpOgorICAgICIiIkNoZWNrcyBpZiB0aGUgY2xpZW50IGNhbmNlbGxlZCB0aGUgUlBDLgorCisgICAgSWYgdHJ1ZSwgaW5kaWNhdGVzIHRoYXQgdGhlIGNsaWVudCBjYW5jZWxlZCB0aGUgUlBDLCBzbyB0aGUgc2VydmVyIG1heQorICAgIGFzIHdlbGwgZ2l2ZSB1cCBvbiByZXBseWluZyB0byBpdC4gIFRoZSBzZXJ2ZXIgc2hvdWxkIHN0aWxsIGNhbGwgdGhlCisgICAgZmluYWwgImRvbmUiIGNhbGxiYWNrLgorICAgICIiIgorICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKKworICBkZWYgTm90aWZ5T25DYW5jZWwoc2VsZiwgY2FsbGJhY2spOgorICAgICIiIlNldHMgYSBjYWxsYmFjayB0byBpbnZva2Ugb24gY2FuY2VsLgorCisgICAgQXNrcyB0aGF0IHRoZSBnaXZlbiBjYWxsYmFjayBiZSBjYWxsZWQgd2hlbiB0aGUgUlBDIGlzIGNhbmNlbGVkLiAgVGhlCisgICAgY2FsbGJhY2sgd2lsbCBhbHdheXMgYmUgY2FsbGVkIGV4YWN0bHkgb25jZS4gIElmIHRoZSBSUEMgY29tcGxldGVzIHdpdGhvdXQKKyAgICBiZWluZyBjYW5jZWxlZCwgdGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGNvbXBsZXRpb24uICBJZiB0aGUgUlBDCisgICAgaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZCB3aGVuIE5vdGlmeU9uQ2FuY2VsKCkgaXMgY2FsbGVkLCB0aGUgY2FsbGJhY2sKKyAgICB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseS4KKworICAgIE5vdGlmeU9uQ2FuY2VsKCkgbXVzdCBiZSBjYWxsZWQgbm8gbW9yZSB0aGFuIG9uY2UgcGVyIHJlcXVlc3QuCisgICAgIiIiCisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisKK2NsYXNzIFJwY0NoYW5uZWwob2JqZWN0KToKKworICAiIiJBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIGFuIFJQQyBjaGFubmVsLgorCisgIEFuIFJwY0NoYW5uZWwgcmVwcmVzZW50cyBhIGNvbW11bmljYXRpb24gbGluZSB0byBhIHNlcnZpY2Ugd2hpY2ggY2FuIGJlIHVzZWQKKyAgdG8gY2FsbCB0aGF0IHNlcnZpY2UncyBtZXRob2RzLiAgVGhlIHNlcnZpY2UgbWF5IGJlIHJ1bm5pbmcgb24gYW5vdGhlcgorICBtYWNoaW5lLiBOb3JtYWxseSwgeW91IHNob3VsZCBub3QgdXNlIGFuIFJwY0NoYW5uZWwgZGlyZWN0bHksIGJ1dCBpbnN0ZWFkCisgIGNvbnN0cnVjdCBhIHN0dWIge0BsaW5rIFNlcnZpY2V9IHdyYXBwaW5nIGl0LiAgRXhhbXBsZToKKworICBFeGFtcGxlOgorICAgIFJwY0NoYW5uZWwgY2hhbm5lbCA9IHJwY0ltcGwuQ2hhbm5lbCgicmVtb3RlaG9zdC5leGFtcGxlLmNvbToxMjM0IikKKyAgICBScGNDb250cm9sbGVyIGNvbnRyb2xsZXIgPSBycGNJbXBsLkNvbnRyb2xsZXIoKQorICAgIE15U2VydmljZSBzZXJ2aWNlID0gTXlTZXJ2aWNlX1N0dWIoY2hhbm5lbCkKKyAgICBzZXJ2aWNlLk15TWV0aG9kKGNvbnRyb2xsZXIsIHJlcXVlc3QsIGNhbGxiYWNrKQorICAiIiIKKworICBkZWYgQ2FsbE1ldGhvZChzZWxmLCBtZXRob2RfZGVzY3JpcHRvciwgcnBjX2NvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgIHJlcXVlc3QsIHJlc3BvbnNlX2NsYXNzLCBkb25lKToKKyAgICAiIiJDYWxscyB0aGUgbWV0aG9kIGlkZW50aWZpZWQgYnkgdGhlIGRlc2NyaXB0b3IuCisKKyAgICBDYWxsIHRoZSBnaXZlbiBtZXRob2Qgb2YgdGhlIHJlbW90ZSBzZXJ2aWNlLiAgVGhlIHNpZ25hdHVyZSBvZiB0aGlzCisgICAgcHJvY2VkdXJlIGxvb2tzIHRoZSBzYW1lIGFzIFNlcnZpY2UuQ2FsbE1ldGhvZCgpLCBidXQgdGhlIHJlcXVpcmVtZW50cworICAgIGFyZSBsZXNzIHN0cmljdCBpbiBvbmUgaW1wb3J0YW50IHdheTogIHRoZSByZXF1ZXN0IG9iamVjdCBkb2Vzbid0IGhhdmUgdG8KKyAgICBiZSBvZiBhbnkgc3BlY2lmaWMgY2xhc3MgYXMgbG9uZyBhcyBpdHMgZGVzY3JpcHRvciBpcyBtZXRob2QuaW5wdXRfdHlwZS4KKyAgICAiIiIKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2VfcmVmbGVjdGlvbi5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvc2VydmljZV9yZWZsZWN0aW9uLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjFjMzYzNmEKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2VfcmVmbGVjdGlvbi5weQpAQCAtMCwwICsxLDI4NCBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisiIiJDb250YWlucyBtZXRhY2xhc3NlcyB1c2VkIHRvIGNyZWF0ZSBwcm90b2NvbCBzZXJ2aWNlIGFuZCBzZXJ2aWNlIHN0dWIKK2NsYXNzZXMgZnJvbSBTZXJ2aWNlRGVzY3JpcHRvciBvYmplY3RzIGF0IHJ1bnRpbWUuCisKK1RoZSBHZW5lcmF0ZWRTZXJ2aWNlVHlwZSBhbmQgR2VuZXJhdGVkU2VydmljZVN0dWJUeXBlIG1ldGFjbGFzc2VzIGFyZSB1c2VkIHRvCitpbmplY3QgYWxsIHVzZWZ1bCBmdW5jdGlvbmFsaXR5IGludG8gdGhlIGNsYXNzZXMgb3V0cHV0IGJ5IHRoZSBwcm90b2NvbAorY29tcGlsZXIgYXQgY29tcGlsZS10aW1lLgorIiIiCisKK19fYXV0aG9yX18gPSAncGV0YXJAZ29vZ2xlLmNvbSAoUGV0YXIgUGV0cm92KScKKworCitjbGFzcyBHZW5lcmF0ZWRTZXJ2aWNlVHlwZSh0eXBlKToKKworICAiIiJNZXRhY2xhc3MgZm9yIHNlcnZpY2UgY2xhc3NlcyBjcmVhdGVkIGF0IHJ1bnRpbWUgZnJvbSBTZXJ2aWNlRGVzY3JpcHRvcnMuCisKKyAgSW1wbGVtZW50YXRpb25zIGZvciBhbGwgbWV0aG9kcyBkZXNjcmliZWQgaW4gdGhlIFNlcnZpY2UgY2xhc3MgYXJlIGFkZGVkIGhlcmUKKyAgYnkgdGhpcyBjbGFzcy4gV2UgYWxzbyBjcmVhdGUgcHJvcGVydGllcyB0byBhbGxvdyBnZXR0aW5nL3NldHRpbmcgYWxsIGZpZWxkcworICBpbiB0aGUgcHJvdG9jb2wgbWVzc2FnZS4KKworICBUaGUgcHJvdG9jb2wgY29tcGlsZXIgY3VycmVudGx5IHVzZXMgdGhpcyBtZXRhY2xhc3MgdG8gY3JlYXRlIHByb3RvY29sIHNlcnZpY2UKKyAgY2xhc3NlcyBhdCBydW50aW1lLiBDbGllbnRzIGNhbiBhbHNvIG1hbnVhbGx5IGNyZWF0ZSB0aGVpciBvd24gY2xhc3NlcyBhdAorICBydW50aW1lLCBhcyBpbiB0aGlzIGV4YW1wbGU6CisKKyAgbXlkZXNjcmlwdG9yID0gU2VydmljZURlc2NyaXB0b3IoLi4uLi4pCisgIGNsYXNzIE15UHJvdG9TZXJ2aWNlKHNlcnZpY2UuU2VydmljZSk6CisgICAgX19tZXRhY2xhc3NfXyA9IEdlbmVyYXRlZFNlcnZpY2VUeXBlCisgICAgREVTQ1JJUFRPUiA9IG15ZGVzY3JpcHRvcgorICBteXNlcnZpY2VfaW5zdGFuY2UgPSBNeVByb3RvU2VydmljZSgpCisgIC4uLgorICAiIiIKKworICBfREVTQ1JJUFRPUl9LRVkgPSAnREVTQ1JJUFRPUicKKworICBkZWYgX19pbml0X18oY2xzLCBuYW1lLCBiYXNlcywgZGljdGlvbmFyeSk6CisgICAgIiIiQ3JlYXRlcyBhIG1lc3NhZ2Ugc2VydmljZSBjbGFzcy4KKworICAgIEFyZ3M6CisgICAgICBuYW1lOiBOYW1lIG9mIHRoZSBjbGFzcyAoaWdub3JlZCwgYnV0IHJlcXVpcmVkIGJ5IHRoZSBtZXRhY2xhc3MKKyAgICAgICAgcHJvdG9jb2wpLgorICAgICAgYmFzZXM6IEJhc2UgY2xhc3NlcyBvZiB0aGUgY2xhc3MgYmVpbmcgY29uc3RydWN0ZWQuCisgICAgICBkaWN0aW9uYXJ5OiBUaGUgY2xhc3MgZGljdGlvbmFyeSBvZiB0aGUgY2xhc3MgYmVpbmcgY29uc3RydWN0ZWQuCisgICAgICAgIGRpY3Rpb25hcnlbX0RFU0NSSVBUT1JfS0VZXSBtdXN0IGNvbnRhaW4gYSBTZXJ2aWNlRGVzY3JpcHRvciBvYmplY3QKKyAgICAgICAgZGVzY3JpYmluZyB0aGlzIHByb3RvY29sIHNlcnZpY2UgdHlwZS4KKyAgICAiIiIKKyAgICAjIERvbid0IGRvIGFueXRoaW5nIGlmIHRoaXMgY2xhc3MgZG9lc24ndCBoYXZlIGEgZGVzY3JpcHRvci4gVGhpcyBoYXBwZW5zCisgICAgIyB3aGVuIGEgc2VydmljZSBjbGFzcyBpcyBzdWJjbGFzc2VkLgorICAgIGlmIEdlbmVyYXRlZFNlcnZpY2VUeXBlLl9ERVNDUklQVE9SX0tFWSBub3QgaW4gZGljdGlvbmFyeToKKyAgICAgIHJldHVybgorICAgIGRlc2NyaXB0b3IgPSBkaWN0aW9uYXJ5W0dlbmVyYXRlZFNlcnZpY2VUeXBlLl9ERVNDUklQVE9SX0tFWV0KKyAgICBzZXJ2aWNlX2J1aWxkZXIgPSBfU2VydmljZUJ1aWxkZXIoZGVzY3JpcHRvcikKKyAgICBzZXJ2aWNlX2J1aWxkZXIuQnVpbGRTZXJ2aWNlKGNscykKKworCitjbGFzcyBHZW5lcmF0ZWRTZXJ2aWNlU3R1YlR5cGUoR2VuZXJhdGVkU2VydmljZVR5cGUpOgorCisgICIiIk1ldGFjbGFzcyBmb3Igc2VydmljZSBzdHVicyBjcmVhdGVkIGF0IHJ1bnRpbWUgZnJvbSBTZXJ2aWNlRGVzY3JpcHRvcnMuCisKKyAgVGhpcyBjbGFzcyBoYXMgc2ltaWxhciByZXNwb25zaWJpbGl0aWVzIGFzIEdlbmVyYXRlZFNlcnZpY2VUeXBlLCBleGNlcHQgdGhhdAorICBpdCBjcmVhdGVzIHRoZSBzZXJ2aWNlIHN0dWIgY2xhc3Nlcy4KKyAgIiIiCisKKyAgX0RFU0NSSVBUT1JfS0VZID0gJ0RFU0NSSVBUT1InCisKKyAgZGVmIF9faW5pdF9fKGNscywgbmFtZSwgYmFzZXMsIGRpY3Rpb25hcnkpOgorICAgICIiIkNyZWF0ZXMgYSBtZXNzYWdlIHNlcnZpY2Ugc3R1YiBjbGFzcy4KKworICAgIEFyZ3M6CisgICAgICBuYW1lOiBOYW1lIG9mIHRoZSBjbGFzcyAoaWdub3JlZCwgaGVyZSkuCisgICAgICBiYXNlczogQmFzZSBjbGFzc2VzIG9mIHRoZSBjbGFzcyBiZWluZyBjb25zdHJ1Y3RlZC4KKyAgICAgIGRpY3Rpb25hcnk6IFRoZSBjbGFzcyBkaWN0aW9uYXJ5IG9mIHRoZSBjbGFzcyBiZWluZyBjb25zdHJ1Y3RlZC4KKyAgICAgICAgZGljdGlvbmFyeVtfREVTQ1JJUFRPUl9LRVldIG11c3QgY29udGFpbiBhIFNlcnZpY2VEZXNjcmlwdG9yIG9iamVjdAorICAgICAgICBkZXNjcmliaW5nIHRoaXMgcHJvdG9jb2wgc2VydmljZSB0eXBlLgorICAgICIiIgorICAgIHN1cGVyKEdlbmVyYXRlZFNlcnZpY2VTdHViVHlwZSwgY2xzKS5fX2luaXRfXyhuYW1lLCBiYXNlcywgZGljdGlvbmFyeSkKKyAgICAjIERvbid0IGRvIGFueXRoaW5nIGlmIHRoaXMgY2xhc3MgZG9lc24ndCBoYXZlIGEgZGVzY3JpcHRvci4gVGhpcyBoYXBwZW5zCisgICAgIyB3aGVuIGEgc2VydmljZSBzdHViIGlzIHN1YmNsYXNzZWQuCisgICAgaWYgR2VuZXJhdGVkU2VydmljZVN0dWJUeXBlLl9ERVNDUklQVE9SX0tFWSBub3QgaW4gZGljdGlvbmFyeToKKyAgICAgIHJldHVybgorICAgIGRlc2NyaXB0b3IgPSBkaWN0aW9uYXJ5W0dlbmVyYXRlZFNlcnZpY2VTdHViVHlwZS5fREVTQ1JJUFRPUl9LRVldCisgICAgc2VydmljZV9zdHViX2J1aWxkZXIgPSBfU2VydmljZVN0dWJCdWlsZGVyKGRlc2NyaXB0b3IpCisgICAgc2VydmljZV9zdHViX2J1aWxkZXIuQnVpbGRTZXJ2aWNlU3R1YihjbHMpCisKKworY2xhc3MgX1NlcnZpY2VCdWlsZGVyKG9iamVjdCk6CisKKyAgIiIiVGhpcyBjbGFzcyBjb25zdHJ1Y3RzIGEgcHJvdG9jb2wgc2VydmljZSBjbGFzcyB1c2luZyBhIHNlcnZpY2UgZGVzY3JpcHRvci4KKworICBHaXZlbiBhIHNlcnZpY2UgZGVzY3JpcHRvciwgdGhpcyBjbGFzcyBjb25zdHJ1Y3RzIGEgY2xhc3MgdGhhdCByZXByZXNlbnRzCisgIHRoZSBzcGVjaWZpZWQgc2VydmljZSBkZXNjcmlwdG9yLiBPbmUgc2VydmljZSBidWlsZGVyIGluc3RhbmNlIGNvbnN0cnVjdHMKKyAgZXhhY3RseSBvbmUgc2VydmljZSBjbGFzcy4gVGhhdCBtZWFucyBhbGwgaW5zdGFuY2VzIG9mIHRoYXQgY2xhc3Mgc2hhcmUgdGhlCisgIHNhbWUgYnVpbGRlci4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIHNlcnZpY2VfZGVzY3JpcHRvcik6CisgICAgIiIiSW5pdGlhbGl6ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIHNlcnZpY2UgY2xhc3MgYnVpbGRlci4KKworICAgIEFyZ3M6CisgICAgICBzZXJ2aWNlX2Rlc2NyaXB0b3I6IFNlcnZpY2VEZXNjcmlwdG9yIHRvIHVzZSB3aGVuIGNvbnN0cnVjdGluZyB0aGUKKyAgICAgICAgc2VydmljZSBjbGFzcy4KKyAgICAiIiIKKyAgICBzZWxmLmRlc2NyaXB0b3IgPSBzZXJ2aWNlX2Rlc2NyaXB0b3IKKworICBkZWYgQnVpbGRTZXJ2aWNlKHNlbGYsIGNscyk6CisgICAgIiIiQ29uc3RydWN0cyB0aGUgc2VydmljZSBjbGFzcy4KKworICAgIEFyZ3M6CisgICAgICBjbHM6IFRoZSBjbGFzcyB0aGF0IHdpbGwgYmUgY29uc3RydWN0ZWQuCisgICAgIiIiCisKKyAgICAjIENhbGxNZXRob2QgbmVlZHMgdG8gb3BlcmF0ZSB3aXRoIGFuIGluc3RhbmNlIG9mIHRoZSBTZXJ2aWNlIGNsYXNzLiBUaGlzCisgICAgIyBpbnRlcm5hbCB3cmFwcGVyIGZ1bmN0aW9uIGV4aXN0cyBvbmx5IHRvIGJlIGFibGUgdG8gcGFzcyB0aGUgc2VydmljZQorICAgICMgaW5zdGFuY2UgdG8gdGhlIG1ldGhvZCB0aGF0IGRvZXMgdGhlIHJlYWwgQ2FsbE1ldGhvZCB3b3JrLgorICAgIGRlZiBfV3JhcENhbGxNZXRob2Qoc3J2YywgbWV0aG9kX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICBycGNfY29udHJvbGxlciwgcmVxdWVzdCwgY2FsbGJhY2spOgorICAgICAgcmV0dXJuIHNlbGYuX0NhbGxNZXRob2Qoc3J2YywgbWV0aG9kX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgIHJwY19jb250cm9sbGVyLCByZXF1ZXN0LCBjYWxsYmFjaykKKyAgICBzZWxmLmNscyA9IGNscworICAgIGNscy5DYWxsTWV0aG9kID0gX1dyYXBDYWxsTWV0aG9kCisgICAgY2xzLkdldERlc2NyaXB0b3IgPSBzdGF0aWNtZXRob2QobGFtYmRhOiBzZWxmLmRlc2NyaXB0b3IpCisgICAgY2xzLkdldERlc2NyaXB0b3IuX19kb2NfXyA9ICJSZXR1cm5zIHRoZSBzZXJ2aWNlIGRlc2NyaXB0b3IuIgorICAgIGNscy5HZXRSZXF1ZXN0Q2xhc3MgPSBzZWxmLl9HZXRSZXF1ZXN0Q2xhc3MKKyAgICBjbHMuR2V0UmVzcG9uc2VDbGFzcyA9IHNlbGYuX0dldFJlc3BvbnNlQ2xhc3MKKyAgICBmb3IgbWV0aG9kIGluIHNlbGYuZGVzY3JpcHRvci5tZXRob2RzOgorICAgICAgc2V0YXR0cihjbHMsIG1ldGhvZC5uYW1lLCBzZWxmLl9HZW5lcmF0ZU5vbkltcGxlbWVudGVkTWV0aG9kKG1ldGhvZCkpCisKKyAgZGVmIF9DYWxsTWV0aG9kKHNlbGYsIHNydmMsIG1ldGhvZF9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgcnBjX2NvbnRyb2xsZXIsIHJlcXVlc3QsIGNhbGxiYWNrKToKKyAgICAiIiJDYWxscyB0aGUgbWV0aG9kIGRlc2NyaWJlZCBieSBhIGdpdmVuIG1ldGhvZCBkZXNjcmlwdG9yLgorCisgICAgQXJnczoKKyAgICAgIHNydmM6IEluc3RhbmNlIG9mIHRoZSBzZXJ2aWNlIGZvciB3aGljaCB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICBtZXRob2RfZGVzY3JpcHRvcjogRGVzY3JpcHRvciB0aGF0IHJlcHJlc2VudCB0aGUgbWV0aG9kIHRvIGNhbGwuCisgICAgICBycGNfY29udHJvbGxlcjogUlBDIGNvbnRyb2xsZXIgdG8gdXNlIGZvciB0aGlzIG1ldGhvZCdzIGV4ZWN1dGlvbi4KKyAgICAgIHJlcXVlc3Q6IFJlcXVlc3QgcHJvdG9jb2wgbWVzc2FnZS4KKyAgICAgIGNhbGxiYWNrOiBBIGNhbGxiYWNrIHRvIGludm9rZSBhZnRlciB0aGUgbWV0aG9kIGhhcyBjb21wbGV0ZWQuCisgICAgIiIiCisgICAgaWYgbWV0aG9kX2Rlc2NyaXB0b3IuY29udGFpbmluZ19zZXJ2aWNlICE9IHNlbGYuZGVzY3JpcHRvcjoKKyAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKKyAgICAgICAgICAnQ2FsbE1ldGhvZCgpIGdpdmVuIG1ldGhvZCBkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuJykKKyAgICBtZXRob2QgPSBnZXRhdHRyKHNydmMsIG1ldGhvZF9kZXNjcmlwdG9yLm5hbWUpCisgICAgcmV0dXJuIG1ldGhvZChycGNfY29udHJvbGxlciwgcmVxdWVzdCwgY2FsbGJhY2spCisKKyAgZGVmIF9HZXRSZXF1ZXN0Q2xhc3Moc2VsZiwgbWV0aG9kX2Rlc2NyaXB0b3IpOgorICAgICIiIlJldHVybnMgdGhlIGNsYXNzIG9mIHRoZSByZXF1ZXN0IHByb3RvY29sIG1lc3NhZ2UuCisKKyAgICBBcmdzOgorICAgICAgbWV0aG9kX2Rlc2NyaXB0b3I6IERlc2NyaXB0b3Igb2YgdGhlIG1ldGhvZCBmb3Igd2hpY2ggdG8gcmV0dXJuIHRoZQorICAgICAgICByZXF1ZXN0IHByb3RvY29sIG1lc3NhZ2UgY2xhc3MuCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBjbGFzcyB0aGF0IHJlcHJlc2VudHMgdGhlIGlucHV0IHByb3RvY29sIG1lc3NhZ2Ugb2YgdGhlIHNwZWNpZmllZAorICAgICAgbWV0aG9kLgorICAgICIiIgorICAgIGlmIG1ldGhvZF9kZXNjcmlwdG9yLmNvbnRhaW5pbmdfc2VydmljZSAhPSBzZWxmLmRlc2NyaXB0b3I6CisgICAgICByYWlzZSBSdW50aW1lRXJyb3IoCisgICAgICAgICAgJ0dldFJlcXVlc3RDbGFzcygpIGdpdmVuIG1ldGhvZCBkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuJykKKyAgICByZXR1cm4gbWV0aG9kX2Rlc2NyaXB0b3IuaW5wdXRfdHlwZS5fY29uY3JldGVfY2xhc3MKKworICBkZWYgX0dldFJlc3BvbnNlQ2xhc3Moc2VsZiwgbWV0aG9kX2Rlc2NyaXB0b3IpOgorICAgICIiIlJldHVybnMgdGhlIGNsYXNzIG9mIHRoZSByZXNwb25zZSBwcm90b2NvbCBtZXNzYWdlLgorCisgICAgQXJnczoKKyAgICAgIG1ldGhvZF9kZXNjcmlwdG9yOiBEZXNjcmlwdG9yIG9mIHRoZSBtZXRob2QgZm9yIHdoaWNoIHRvIHJldHVybiB0aGUKKyAgICAgICAgcmVzcG9uc2UgcHJvdG9jb2wgbWVzc2FnZSBjbGFzcy4KKworICAgIFJldHVybnM6CisgICAgICBBIGNsYXNzIHRoYXQgcmVwcmVzZW50cyB0aGUgb3V0cHV0IHByb3RvY29sIG1lc3NhZ2Ugb2YgdGhlIHNwZWNpZmllZAorICAgICAgbWV0aG9kLgorICAgICIiIgorICAgIGlmIG1ldGhvZF9kZXNjcmlwdG9yLmNvbnRhaW5pbmdfc2VydmljZSAhPSBzZWxmLmRlc2NyaXB0b3I6CisgICAgICByYWlzZSBSdW50aW1lRXJyb3IoCisgICAgICAgICAgJ0dldFJlc3BvbnNlQ2xhc3MoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLicpCisgICAgcmV0dXJuIG1ldGhvZF9kZXNjcmlwdG9yLm91dHB1dF90eXBlLl9jb25jcmV0ZV9jbGFzcworCisgIGRlZiBfR2VuZXJhdGVOb25JbXBsZW1lbnRlZE1ldGhvZChzZWxmLCBtZXRob2QpOgorICAgICIiIkdlbmVyYXRlcyBhbmQgcmV0dXJucyBhIG1ldGhvZCB0aGF0IGNhbiBiZSBzZXQgZm9yIGEgc2VydmljZSBtZXRob2RzLgorCisgICAgQXJnczoKKyAgICAgIG1ldGhvZDogRGVzY3JpcHRvciBvZiB0aGUgc2VydmljZSBtZXRob2QgZm9yIHdoaWNoIGEgbWV0aG9kIGlzIHRvIGJlCisgICAgICAgIGdlbmVyYXRlZC4KKworICAgIFJldHVybnM6CisgICAgICBBIG1ldGhvZCB0aGF0IGNhbiBiZSBhZGRlZCB0byB0aGUgc2VydmljZSBjbGFzcy4KKyAgICAiIiIKKyAgICByZXR1cm4gbGFtYmRhIGluc3QsIHJwY19jb250cm9sbGVyLCByZXF1ZXN0LCBjYWxsYmFjazogKAorICAgICAgICBzZWxmLl9Ob25JbXBsZW1lbnRlZE1ldGhvZChtZXRob2QubmFtZSwgcnBjX2NvbnRyb2xsZXIsIGNhbGxiYWNrKSkKKworICBkZWYgX05vbkltcGxlbWVudGVkTWV0aG9kKHNlbGYsIG1ldGhvZF9uYW1lLCBycGNfY29udHJvbGxlciwgY2FsbGJhY2spOgorICAgICIiIlRoZSBib2R5IG9mIGFsbCBtZXRob2RzIGluIHRoZSBnZW5lcmF0ZWQgc2VydmljZSBjbGFzcy4KKworICAgIEFyZ3M6CisgICAgICBtZXRob2RfbmFtZTogTmFtZSBvZiB0aGUgbWV0aG9kIGJlaW5nIGV4ZWN1dGVkLgorICAgICAgcnBjX2NvbnRyb2xsZXI6IFJQQyBjb250cm9sbGVyIHVzZWQgdG8gZXhlY3V0ZSB0aGlzIG1ldGhvZC4KKyAgICAgIGNhbGxiYWNrOiBBIGNhbGxiYWNrIHdoaWNoIHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSBtZXRob2QgZmluaXNoZXMuCisgICAgIiIiCisgICAgcnBjX2NvbnRyb2xsZXIuU2V0RmFpbGVkKCdNZXRob2QgJXMgbm90IGltcGxlbWVudGVkLicgJSBtZXRob2RfbmFtZSkKKyAgICBjYWxsYmFjayhOb25lKQorCisKK2NsYXNzIF9TZXJ2aWNlU3R1YkJ1aWxkZXIob2JqZWN0KToKKworICAiIiJDb25zdHJ1Y3RzIGEgcHJvdG9jb2wgc2VydmljZSBzdHViIGNsYXNzIHVzaW5nIGEgc2VydmljZSBkZXNjcmlwdG9yLgorCisgIEdpdmVuIGEgc2VydmljZSBkZXNjcmlwdG9yLCB0aGlzIGNsYXNzIGNvbnN0cnVjdHMgYSBzdWl0YWJsZSBzdHViIGNsYXNzLgorICBBIHN0dWIgaXMganVzdCBhIHR5cGUtc2FmZSB3cmFwcGVyIGFyb3VuZCBhbiBScGNDaGFubmVsIHdoaWNoIGVtdWxhdGVzIGEKKyAgbG9jYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UuCisKKyAgT25lIHNlcnZpY2Ugc3R1YiBidWlsZGVyIGluc3RhbmNlIGNvbnN0cnVjdHMgZXhhY3RseSBvbmUgY2xhc3MuIEl0IG1lYW5zIGFsbAorICBpbnN0YW5jZXMgb2YgdGhhdCBjbGFzcyBzaGFyZSB0aGUgc2FtZSBzZXJ2aWNlIHN0dWIgYnVpbGRlci4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIHNlcnZpY2VfZGVzY3JpcHRvcik6CisgICAgIiIiSW5pdGlhbGl6ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIHNlcnZpY2Ugc3R1YiBjbGFzcyBidWlsZGVyLgorCisgICAgQXJnczoKKyAgICAgIHNlcnZpY2VfZGVzY3JpcHRvcjogU2VydmljZURlc2NyaXB0b3IgdG8gdXNlIHdoZW4gY29uc3RydWN0aW5nIHRoZQorICAgICAgICBzdHViIGNsYXNzLgorICAgICIiIgorICAgIHNlbGYuZGVzY3JpcHRvciA9IHNlcnZpY2VfZGVzY3JpcHRvcgorCisgIGRlZiBCdWlsZFNlcnZpY2VTdHViKHNlbGYsIGNscyk6CisgICAgIiIiQ29uc3RydWN0cyB0aGUgc3R1YiBjbGFzcy4KKworICAgIEFyZ3M6CisgICAgICBjbHM6IFRoZSBjbGFzcyB0aGF0IHdpbGwgYmUgY29uc3RydWN0ZWQuCisgICAgIiIiCisKKyAgICBkZWYgX1NlcnZpY2VTdHViSW5pdChzdHViLCBycGNfY2hhbm5lbCk6CisgICAgICBzdHViLnJwY19jaGFubmVsID0gcnBjX2NoYW5uZWwKKyAgICBzZWxmLmNscyA9IGNscworICAgIGNscy5fX2luaXRfXyA9IF9TZXJ2aWNlU3R1YkluaXQKKyAgICBmb3IgbWV0aG9kIGluIHNlbGYuZGVzY3JpcHRvci5tZXRob2RzOgorICAgICAgc2V0YXR0cihjbHMsIG1ldGhvZC5uYW1lLCBzZWxmLl9HZW5lcmF0ZVN0dWJNZXRob2QobWV0aG9kKSkKKworICBkZWYgX0dlbmVyYXRlU3R1Yk1ldGhvZChzZWxmLCBtZXRob2QpOgorICAgIHJldHVybiAobGFtYmRhIGluc3QsIHJwY19jb250cm9sbGVyLCByZXF1ZXN0LCBjYWxsYmFjaz1Ob25lOgorICAgICAgICBzZWxmLl9TdHViTWV0aG9kKGluc3QsIG1ldGhvZCwgcnBjX2NvbnRyb2xsZXIsIHJlcXVlc3QsIGNhbGxiYWNrKSkKKworICBkZWYgX1N0dWJNZXRob2Qoc2VsZiwgc3R1YiwgbWV0aG9kX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICBycGNfY29udHJvbGxlciwgcmVxdWVzdCwgY2FsbGJhY2spOgorICAgICIiIlRoZSBib2R5IG9mIGFsbCBzZXJ2aWNlIG1ldGhvZHMgaW4gdGhlIGdlbmVyYXRlZCBzdHViIGNsYXNzLgorCisgICAgQXJnczoKKyAgICAgIHN0dWI6IFN0dWIgaW5zdGFuY2UuCisgICAgICBtZXRob2RfZGVzY3JpcHRvcjogRGVzY3JpcHRvciBvZiB0aGUgaW52b2tlZCBtZXRob2QuCisgICAgICBycGNfY29udHJvbGxlcjogUnBjIGNvbnRyb2xsZXIgdG8gZXhlY3V0ZSB0aGUgbWV0aG9kLgorICAgICAgcmVxdWVzdDogUmVxdWVzdCBwcm90b2NvbCBtZXNzYWdlLgorICAgICAgY2FsbGJhY2s6IEEgY2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHRoZSBtZXRob2QgZmluaXNoZXMuCisgICAgUmV0dXJuczoKKyAgICAgIFJlc3BvbnNlIG1lc3NhZ2UgKGluIGNhc2Ugb2YgYmxvY2tpbmcgY2FsbCkuCisgICAgIiIiCisgICAgcmV0dXJuIHN0dWIucnBjX2NoYW5uZWwuQ2FsbE1ldGhvZCgKKyAgICAgICAgbWV0aG9kX2Rlc2NyaXB0b3IsIHJwY19jb250cm9sbGVyLCByZXF1ZXN0LAorICAgICAgICBtZXRob2RfZGVzY3JpcHRvci5vdXRwdXRfdHlwZS5fY29uY3JldGVfY2xhc3MsIGNhbGxiYWNrKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9zeW1ib2xfZGF0YWJhc2UucHkgYi9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3N5bWJvbF9kYXRhYmFzZS5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzcwYjM5Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi9zeW1ib2xfZGF0YWJhc2UucHkKQEAgLTAsMCArMSwxODUgQEAKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiQSBkYXRhYmFzZSBvZiBQeXRob24gcHJvdG9jb2wgYnVmZmVyIGdlbmVyYXRlZCBzeW1ib2xzLgorCitTeW1ib2xEYXRhYmFzZSBtYWtlcyBpdCBlYXN5IHRvIGNyZWF0ZSBuZXcgaW5zdGFuY2VzIG9mIGEgcmVnaXN0ZXJlZCB0eXBlLCBnaXZlbgorb25seSB0aGUgdHlwZSdzIHByb3RvY29sIGJ1ZmZlciBzeW1ib2wgbmFtZS4gT25jZSBhbGwgc3ltYm9scyBhcmUgcmVnaXN0ZXJlZCwKK3RoZXkgY2FuIGJlIGFjY2Vzc2VkIHVzaW5nIGVpdGhlciB0aGUgTWVzc2FnZUZhY3RvcnkgaW50ZXJmYWNlIHdoaWNoCitTeW1ib2xEYXRhYmFzZSBleHBvc2VzLCBvciB0aGUgRGVzY3JpcHRvclBvb2wgaW50ZXJmYWNlIG9mIHRoZSB1bmRlcmx5aW5nCitwb29sLgorCitFeGFtcGxlIHVzYWdlOgorCisgIGRiID0gc3ltYm9sX2RhdGFiYXNlLlN5bWJvbERhdGFiYXNlKCkKKworICAjIFJlZ2lzdGVyIHN5bWJvbHMgb2YgaW50ZXJlc3QsIGZyb20gb25lIG9yIG11bHRpcGxlIGZpbGVzLgorICBkYi5SZWdpc3RlckZpbGVEZXNjcmlwdG9yKG15X3Byb3RvX3BiMi5ERVNDUklQVE9SKQorICBkYi5SZWdpc3Rlck1lc3NhZ2UobXlfcHJvdG9fcGIyLk15TWVzc2FnZSkKKyAgZGIuUmVnaXN0ZXJFbnVtRGVzY3JpcHRvcihteV9wcm90b19wYjIuTXlFbnVtLkRFU0NSSVBUT1IpCisKKyAgIyBUaGUgZGF0YWJhc2UgY2FuIGJlIHVzZWQgYXMgYSBNZXNzYWdlRmFjdG9yeSwgdG8gZ2VuZXJhdGUgdHlwZXMgYmFzZWQgb24KKyAgIyB0aGVpciBuYW1lOgorICB0eXBlcyA9IGRiLkdldE1lc3NhZ2VzKFsnbXlfcHJvdG8ucHJvdG8nXSkKKyAgbXlfbWVzc2FnZV9pbnN0YW5jZSA9IHR5cGVzWydNeU1lc3NhZ2UnXSgpCisKKyAgIyBUaGUgZGF0YWJhc2UncyB1bmRlcmx5aW5nIGRlc2NyaXB0b3IgcG9vbCBjYW4gYmUgcXVlcmllZCwgc28gaXQncyBub3QKKyAgIyBuZWNlc3NhcnkgdG8ga25vdyBhIHR5cGUncyBmaWxlbmFtZSB0byBiZSBhYmxlIHRvIGdlbmVyYXRlIGl0OgorICBmaWxlbmFtZSA9IGRiLnBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCdNeU1lc3NhZ2UnKQorICBteV9tZXNzYWdlX2luc3RhbmNlID0gZGIuR2V0TWVzc2FnZXMoW2ZpbGVuYW1lXSlbJ015TWVzc2FnZSddKCkKKworICAjIFRoaXMgZnVuY3Rpb25hbGl0eSBpcyBhbHNvIHByb3ZpZGVkIGRpcmVjdGx5IHZpYSBhIGNvbnZlbmllbmNlIG1ldGhvZDoKKyAgbXlfbWVzc2FnZV9pbnN0YW5jZSA9IGRiLkdldFN5bWJvbCgnTXlNZXNzYWdlJykoKQorIiIiCisKKworZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcG9vbAorCisKK2NsYXNzIFN5bWJvbERhdGFiYXNlKG9iamVjdCk6CisgICIiIkEgZGF0YWJhc2Ugb2YgUHl0aG9uIGdlbmVyYXRlZCBzeW1ib2xzLgorCisgIFN5bWJvbERhdGFiYXNlIGFsc28gbW9kZWxzIG1lc3NhZ2VfZmFjdG9yeS5NZXNzYWdlRmFjdG9yeS4KKworICBUaGUgc3ltYm9sIGRhdGFiYXNlIGNhbiBiZSB1c2VkIHRvIGtlZXAgYSBnbG9iYWwgcmVnaXN0cnkgb2YgYWxsIHByb3RvY29sCisgIGJ1ZmZlciB0eXBlcyB1c2VkIHdpdGhpbiBhIHByb2dyYW0uCisgICIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmKToKKyAgICAiIiJDb25zdHJ1Y3Rvci4iIiIKKworICAgIHNlbGYuX3N5bWJvbHMgPSB7fQorICAgIHNlbGYuX3N5bWJvbHNfYnlfZmlsZSA9IHt9CisgICAgc2VsZi5wb29sID0gZGVzY3JpcHRvcl9wb29sLkRlc2NyaXB0b3JQb29sKCkKKworICBkZWYgUmVnaXN0ZXJNZXNzYWdlKHNlbGYsIG1lc3NhZ2UpOgorICAgICIiIlJlZ2lzdGVycyB0aGUgZ2l2ZW4gbWVzc2FnZSB0eXBlIGluIHRoZSBsb2NhbCBkYXRhYmFzZS4KKworICAgIEFyZ3M6CisgICAgICBtZXNzYWdlOiBhIG1lc3NhZ2UuTWVzc2FnZSwgdG8gYmUgcmVnaXN0ZXJlZC4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgcHJvdmlkZWQgbWVzc2FnZS4KKyAgICAiIiIKKworICAgIGRlc2MgPSBtZXNzYWdlLkRFU0NSSVBUT1IKKyAgICBzZWxmLl9zeW1ib2xzW2Rlc2MuZnVsbF9uYW1lXSA9IG1lc3NhZ2UKKyAgICBpZiBkZXNjLmZpbGUubmFtZSBub3QgaW4gc2VsZi5fc3ltYm9sc19ieV9maWxlOgorICAgICAgc2VsZi5fc3ltYm9sc19ieV9maWxlW2Rlc2MuZmlsZS5uYW1lXSA9IHt9CisgICAgc2VsZi5fc3ltYm9sc19ieV9maWxlW2Rlc2MuZmlsZS5uYW1lXVtkZXNjLmZ1bGxfbmFtZV0gPSBtZXNzYWdlCisgICAgc2VsZi5wb29sLkFkZERlc2NyaXB0b3IoZGVzYykKKyAgICByZXR1cm4gbWVzc2FnZQorCisgIGRlZiBSZWdpc3RlckVudW1EZXNjcmlwdG9yKHNlbGYsIGVudW1fZGVzY3JpcHRvcik6CisgICAgIiIiUmVnaXN0ZXJzIHRoZSBnaXZlbiBlbnVtIGRlc2NyaXB0b3IgaW4gdGhlIGxvY2FsIGRhdGFiYXNlLgorCisgICAgQXJnczoKKyAgICAgIGVudW1fZGVzY3JpcHRvcjogYSBkZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBwcm92aWRlZCBkZXNjcmlwdG9yLgorICAgICIiIgorICAgIHNlbGYucG9vbC5BZGRFbnVtRGVzY3JpcHRvcihlbnVtX2Rlc2NyaXB0b3IpCisgICAgcmV0dXJuIGVudW1fZGVzY3JpcHRvcgorCisgIGRlZiBSZWdpc3RlckZpbGVEZXNjcmlwdG9yKHNlbGYsIGZpbGVfZGVzY3JpcHRvcik6CisgICAgIiIiUmVnaXN0ZXJzIHRoZSBnaXZlbiBmaWxlIGRlc2NyaXB0b3IgaW4gdGhlIGxvY2FsIGRhdGFiYXNlLgorCisgICAgQXJnczoKKyAgICAgIGZpbGVfZGVzY3JpcHRvcjogYSBkZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBwcm92aWRlZCBkZXNjcmlwdG9yLgorICAgICIiIgorICAgIHNlbGYucG9vbC5BZGRGaWxlRGVzY3JpcHRvcihmaWxlX2Rlc2NyaXB0b3IpCisKKyAgZGVmIEdldFN5bWJvbChzZWxmLCBzeW1ib2wpOgorICAgICIiIlRyaWVzIHRvIGZpbmQgYSBzeW1ib2wgaW4gdGhlIGxvY2FsIGRhdGFiYXNlLgorCisgICAgQ3VycmVudGx5LCB0aGlzIG1ldGhvZCBvbmx5IHJldHVybnMgbWVzc2FnZS5NZXNzYWdlIGluc3RhbmNlcywgaG93ZXZlciwgaWYKKyAgICBtYXkgYmUgZXh0ZW5kZWQgaW4gZnV0dXJlIHRvIHN1cHBvcnQgb3RoZXIgc3ltYm9sIHR5cGVzLgorCisgICAgQXJnczoKKyAgICAgIHN5bWJvbDogQSBzdHIsIGEgcHJvdG9jb2wgYnVmZmVyIHN5bWJvbC4KKworICAgIFJldHVybnM6CisgICAgICBBIFB5dGhvbiBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBzeW1ib2wuCisKKyAgICBSYWlzZXM6CisgICAgICBLZXlFcnJvcjogaWYgdGhlIHN5bWJvbCBjb3VsZCBub3QgYmUgZm91bmQuCisgICAgIiIiCisKKyAgICByZXR1cm4gc2VsZi5fc3ltYm9sc1tzeW1ib2xdCisKKyAgZGVmIEdldFByb3RvdHlwZShzZWxmLCBkZXNjcmlwdG9yKToKKyAgICAiIiJCdWlsZHMgYSBwcm90bzIgbWVzc2FnZSBjbGFzcyBiYXNlZCBvbiB0aGUgcGFzc2VkIGluIGRlc2NyaXB0b3IuCisKKyAgICBQYXNzaW5nIGEgZGVzY3JpcHRvciB3aXRoIGEgZnVsbHkgcXVhbGlmaWVkIG5hbWUgbWF0Y2hpbmcgYSBwcmV2aW91cworICAgIGludm9jYXRpb24gd2lsbCBjYXVzZSB0aGUgc2FtZSBjbGFzcyB0byBiZSByZXR1cm5lZC4KKworICAgIEFyZ3M6CisgICAgICBkZXNjcmlwdG9yOiBUaGUgZGVzY3JpcHRvciB0byBidWlsZCBmcm9tLgorCisgICAgUmV0dXJuczoKKyAgICAgIEEgY2xhc3MgZGVzY3JpYmluZyB0aGUgcGFzc2VkIGluIGRlc2NyaXB0b3IuCisgICAgIiIiCisKKyAgICByZXR1cm4gc2VsZi5HZXRTeW1ib2woZGVzY3JpcHRvci5mdWxsX25hbWUpCisKKyAgZGVmIEdldE1lc3NhZ2VzKHNlbGYsIGZpbGVzKToKKyAgICAiIiJHZXRzIGFsbCB0aGUgbWVzc2FnZXMgZnJvbSBhIHNwZWNpZmllZCBmaWxlLgorCisgICAgVGhpcyB3aWxsIGZpbmQgYW5kIHJlc29sdmUgZGVwZW5kZW5jaWVzLCBmYWlsaW5nIGlmIHRoZXkgYXJlIG5vdCByZWdpc3RlcmVkCisgICAgaW4gdGhlIHN5bWJvbCBkYXRhYmFzZS4KKworCisgICAgQXJnczoKKyAgICAgIGZpbGVzOiBUaGUgZmlsZSBuYW1lcyB0byBleHRyYWN0IG1lc3NhZ2VzIGZyb20uCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBkaWN0aW9uYXJ5IG1hcHBpbmcgcHJvdG8gbmFtZXMgdG8gdGhlIG1lc3NhZ2UgY2xhc3Nlcy4gVGhpcyB3aWxsIGluY2x1ZGUKKyAgICAgIGFueSBkZXBlbmRlbnQgbWVzc2FnZXMgYXMgd2VsbCBhcyBhbnkgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgc2FtZSBmaWxlIGFzCisgICAgICBhIHNwZWNpZmllZCBtZXNzYWdlLgorCisgICAgUmFpc2VzOgorICAgICAgS2V5RXJyb3I6IGlmIGEgZmlsZSBjb3VsZCBub3QgYmUgZm91bmQuCisgICAgIiIiCisKKyAgICByZXN1bHQgPSB7fQorICAgIGZvciBmIGluIGZpbGVzOgorICAgICAgcmVzdWx0LnVwZGF0ZShzZWxmLl9zeW1ib2xzX2J5X2ZpbGVbZl0pCisgICAgcmV0dXJuIHJlc3VsdAorCitfREVGQVVMVCA9IFN5bWJvbERhdGFiYXNlKCkKKworCitkZWYgRGVmYXVsdCgpOgorICAiIiJSZXR1cm5zIHRoZSBkZWZhdWx0IFN5bWJvbERhdGFiYXNlLiIiIgorICByZXR1cm4gX0RFRkFVTFQKZGlmZiAtLWdpdCBhL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvdGV4dF9lbmNvZGluZy5weSBiL3B5dGhvbi9nb29nbGUvcHJvdG9idWYvdGV4dF9lbmNvZGluZy5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDg2YTY3Ci0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2VuY29kaW5nLnB5CkBAIC0wLDAgKzEsMTEwIEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNQWTI1IGNvbXBhdGlibGUgZm9yIEdBRS4KKyMKKyIiIkVuY29kaW5nIHJlbGF0ZWQgdXRpbGl0aWVzLiIiIgorCitpbXBvcnQgcmUKK2ltcG9ydCBzeXMgICMjUFkyNQorCisjIExvb2t1cCB0YWJsZSBmb3IgdXRmOAorX2Nlc2NhcGVfdXRmOF90b19zdHIgPSBbY2hyKGkpIGZvciBpIGluIHhyYW5nZSgwLCAyNTYpXQorX2Nlc2NhcGVfdXRmOF90b19zdHJbOV0gPSByJ1x0JyAgIyBvcHRpb25hbCBlc2NhcGUKK19jZXNjYXBlX3V0ZjhfdG9fc3RyWzEwXSA9IHInXG4nICAjIG9wdGlvbmFsIGVzY2FwZQorX2Nlc2NhcGVfdXRmOF90b19zdHJbMTNdID0gcidccicgICMgb3B0aW9uYWwgZXNjYXBlCitfY2VzY2FwZV91dGY4X3RvX3N0clszOV0gPSByIlwnIiAgIyBvcHRpb25hbCBlc2NhcGUKKworX2Nlc2NhcGVfdXRmOF90b19zdHJbMzRdID0gcidcIicgICMgbmVjZXNzYXJ5IGVzY2FwZQorX2Nlc2NhcGVfdXRmOF90b19zdHJbOTJdID0gcidcXCcgICMgbmVjZXNzYXJ5IGVzY2FwZQorCisjIExvb2t1cCB0YWJsZSBmb3Igbm9uLXV0ZjgsIHdpdGggbmVjZXNzYXJ5IGVzY2FwZXMgYXQgKG8gPj0gMTI3IG9yIG8gPCAzMikKK19jZXNjYXBlX2J5dGVfdG9fc3RyID0gKFtyJ1wlMDNvJyAlIGkgZm9yIGkgaW4geHJhbmdlKDAsIDMyKV0gKworICAgICAgICAgICAgICAgICAgICAgICAgW2NocihpKSBmb3IgaSBpbiB4cmFuZ2UoMzIsIDEyNyldICsKKyAgICAgICAgICAgICAgICAgICAgICAgIFtyJ1wlMDNvJyAlIGkgZm9yIGkgaW4geHJhbmdlKDEyNywgMjU2KV0pCitfY2VzY2FwZV9ieXRlX3RvX3N0cls5XSA9IHInXHQnICAjIG9wdGlvbmFsIGVzY2FwZQorX2Nlc2NhcGVfYnl0ZV90b19zdHJbMTBdID0gcidcbicgICMgb3B0aW9uYWwgZXNjYXBlCitfY2VzY2FwZV9ieXRlX3RvX3N0clsxM10gPSByJ1xyJyAgIyBvcHRpb25hbCBlc2NhcGUKK19jZXNjYXBlX2J5dGVfdG9fc3RyWzM5XSA9IHIiXCciICAjIG9wdGlvbmFsIGVzY2FwZQorCitfY2VzY2FwZV9ieXRlX3RvX3N0clszNF0gPSByJ1wiJyAgIyBuZWNlc3NhcnkgZXNjYXBlCitfY2VzY2FwZV9ieXRlX3RvX3N0cls5Ml0gPSByJ1xcJyAgIyBuZWNlc3NhcnkgZXNjYXBlCisKKworZGVmIENFc2NhcGUodGV4dCwgYXNfdXRmOCk6CisgICIiIkVzY2FwZSBhIGJ5dGVzIHN0cmluZyBmb3IgdXNlIGluIGFuIGFzY2lpIHByb3RvY29sIGJ1ZmZlci4KKworICB0ZXh0LmVuY29kZSgnc3RyaW5nX2VzY2FwZScpIGRvZXMgbm90IHNlZW0gdG8gc2F0aXNmeSBvdXIgbmVlZHMgYXMgaXQKKyAgZW5jb2RlcyB1bnByaW50YWJsZSBjaGFyYWN0ZXJzIHVzaW5nIHR3by1kaWdpdCBoZXggZXNjYXBlcyB3aGVyZWFzIG91cgorICBDKysgdW5lc2NhcGluZyBmdW5jdGlvbiBhbGxvd3MgaGV4IGVzY2FwZXMgdG8gYmUgYW55IGxlbmd0aC4gIFNvLAorICAiXDAwMTEiLmVuY29kZSgnc3RyaW5nX2VzY2FwZScpIGVuZHMgdXAgYmVpbmcgIlxceDAxMSIsIHdoaWNoIHdpbGwgYmUKKyAgZGVjb2RlZCBpbiBDKysgYXMgYSBzaW5nbGUtY2hhcmFjdGVyIHN0cmluZyB3aXRoIGNoYXIgY29kZSAweDExLgorCisgIEFyZ3M6CisgICAgdGV4dDogQSBieXRlIHN0cmluZyB0byBiZSBlc2NhcGVkCisgICAgYXNfdXRmODogU3BlY2lmaWVzIGlmIHJlc3VsdCBzaG91bGQgYmUgcmV0dXJuZWQgaW4gVVRGLTggZW5jb2RpbmcKKyAgUmV0dXJuczoKKyAgICBFc2NhcGVkIHN0cmluZworICAiIiIKKyAgIyBQWTMgaGFjazogbWFrZSBPcmQgd29yayBmb3Igc3RyIGFuZCBieXRlczoKKyAgIyAvL3BsYXRmb3Jtcy9uZXR3b3JraW5nL2RhdGEgdXNlcyB1bmljb2RlIGhlcmUsIGhlbmNlIGJhc2VzdHJpbmcuCisgIE9yZCA9IG9yZCBpZiBpc2luc3RhbmNlKHRleHQsIGJhc2VzdHJpbmcpIGVsc2UgbGFtYmRhIHg6IHgKKyAgaWYgYXNfdXRmODoKKyAgICByZXR1cm4gJycuam9pbihfY2VzY2FwZV91dGY4X3RvX3N0cltPcmQoYyldIGZvciBjIGluIHRleHQpCisgIHJldHVybiAnJy5qb2luKF9jZXNjYXBlX2J5dGVfdG9fc3RyW09yZChjKV0gZm9yIGMgaW4gdGV4dCkKKworCitfQ1VORVNDQVBFX0hFWCA9IHJlLmNvbXBpbGUocicoXFwrKXgoWzAtOWEtZkEtRl0pKD8hWzAtOWEtZkEtRl0pJykKK19jZXNjYXBlX2hpZ2hiaXRfdG9fc3RyID0gKFtjaHIoaSkgZm9yIGkgaW4gcmFuZ2UoMCwgMTI3KV0gKworICAgICAgICAgICAgICAgICAgICAgICAgICAgW3InXCUwM28nICUgaSBmb3IgaSBpbiByYW5nZSgxMjcsIDI1NildKQorCisKK2RlZiBDVW5lc2NhcGUodGV4dCk6CisgICIiIlVuZXNjYXBlIGEgdGV4dCBzdHJpbmcgd2l0aCBDLXN0eWxlIGVzY2FwZSBzZXF1ZW5jZXMgdG8gVVRGLTggYnl0ZXMuIiIiCisKKyAgZGVmIFJlcGxhY2VIZXgobSk6CisgICAgIyBPbmx5IHJlcGxhY2UgdGhlIG1hdGNoIGlmIHRoZSBudW1iZXIgb2YgbGVhZGluZyBiYWNrIHNsYXNoZXMgaXMgb2RkLiBpLmUuCisgICAgIyB0aGUgc2xhc2ggaXRzZWxmIGlzIG5vdCBlc2NhcGVkLgorICAgIGlmIGxlbihtLmdyb3VwKDEpKSAmIDE6CisgICAgICByZXR1cm4gbS5ncm91cCgxKSArICd4MCcgKyBtLmdyb3VwKDIpCisgICAgcmV0dXJuIG0uZ3JvdXAoMCkKKworICAjIFRoaXMgaXMgcmVxdWlyZWQgYmVjYXVzZSB0aGUgJ3N0cmluZ19lc2NhcGUnIGVuY29kaW5nIGRvZXNuJ3QKKyAgIyBhbGxvdyBzaW5nbGUtZGlnaXQgaGV4IGVzY2FwZXMgKGxpa2UgJ1x4ZicpLgorICByZXN1bHQgPSBfQ1VORVNDQVBFX0hFWC5zdWIoUmVwbGFjZUhleCwgdGV4dCkKKworICBpZiBzeXMudmVyc2lvbl9pbmZvWzBdIDwgMzogICMjUFkyNQorIyMhUFkyNSAgaWYgc3RyIGlzIGJ5dGVzOiAgIyBQWTIKKyAgICByZXR1cm4gcmVzdWx0LmRlY29kZSgnc3RyaW5nX2VzY2FwZScpCisgIHJlc3VsdCA9ICcnLmpvaW4oX2Nlc2NhcGVfaGlnaGJpdF90b19zdHJbb3JkKGMpXSBmb3IgYyBpbiByZXN1bHQpCisgIHJldHVybiAocmVzdWx0LmVuY29kZSgnYXNjaWknKSAgIyBNYWtlIGl0IGJ5dGVzIHRvIGFsbG93IGRlY29kZS4KKyAgICAgICAgICAuZGVjb2RlKCd1bmljb2RlX2VzY2FwZScpCisgICAgICAgICAgIyBNYWtlIGl0IGJ5dGVzIGFnYWluIHRvIHJldHVybiB0aGUgcHJvcGVyIHR5cGUuCisgICAgICAgICAgLmVuY29kZSgncmF3X3VuaWNvZGVfZXNjYXBlJykpCmRpZmYgLS1naXQgYS9weXRob24vZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LnB5IGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5hNDdjZTNlCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5weQpAQCAtMCwwICsxLDg4NCBAQAorIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjUFkyNSBjb21wYXRpYmxlIGZvciBHQUUuCisjCisjIENvcHlyaWdodCAyMDA3IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisKKyIiIkNvbnRhaW5zIHJvdXRpbmVzIGZvciBwcmludGluZyBwcm90b2NvbCBtZXNzYWdlcyBpbiB0ZXh0IGZvcm1hdC4iIiIKKworX19hdXRob3JfXyA9ICdrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKScKKworaW1wb3J0IGNTdHJpbmdJTworaW1wb3J0IHJlCisKK2Zyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCB0eXBlX2NoZWNrZXJzCitmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgZGVzY3JpcHRvcgorZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHRleHRfZW5jb2RpbmcKKworX19hbGxfXyA9IFsnTWVzc2FnZVRvU3RyaW5nJywgJ1ByaW50TWVzc2FnZScsICdQcmludEZpZWxkJywKKyAgICAgICAgICAgJ1ByaW50RmllbGRWYWx1ZScsICdNZXJnZSddCisKKworX0lOVEVHRVJfQ0hFQ0tFUlMgPSAodHlwZV9jaGVja2Vycy5VaW50MzJWYWx1ZUNoZWNrZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGVfY2hlY2tlcnMuSW50MzJWYWx1ZUNoZWNrZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGVfY2hlY2tlcnMuVWludDY0VmFsdWVDaGVja2VyKCksCisgICAgICAgICAgICAgICAgICAgICB0eXBlX2NoZWNrZXJzLkludDY0VmFsdWVDaGVja2VyKCkpCitfRkxPQVRfSU5GSU5JVFkgPSByZS5jb21waWxlKCctP2luZig/OmluaXR5KT9mPycsIHJlLklHTk9SRUNBU0UpCitfRkxPQVRfTkFOID0gcmUuY29tcGlsZSgnbmFuZj8nLCByZS5JR05PUkVDQVNFKQorX0ZMT0FUX1RZUEVTID0gZnJvemVuc2V0KFtkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX0ZMT0FULAorICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX0RPVUJMRV0pCisKKworY2xhc3MgRXJyb3IoRXhjZXB0aW9uKToKKyAgIiIiVG9wLWxldmVsIG1vZHVsZSBlcnJvciBmb3IgdGV4dF9mb3JtYXQuIiIiCisKKworY2xhc3MgUGFyc2VFcnJvcihFcnJvcik6CisgICIiIlRocm93biBpbiBjYXNlIG9mIEFTQ0lJIHBhcnNpbmcgZXJyb3IuIiIiCisKKworZGVmIE1lc3NhZ2VUb1N0cmluZyhtZXNzYWdlLCBhc191dGY4PUZhbHNlLCBhc19vbmVfbGluZT1GYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgcG9pbnR5X2JyYWNrZXRzPUZhbHNlLCB1c2VfaW5kZXhfb3JkZXI9RmFsc2UsCisgICAgICAgICAgICAgICAgICAgIGZsb2F0X2Zvcm1hdD1Ob25lKToKKyAgIiIiQ29udmVydCBwcm90b2J1ZiBtZXNzYWdlIHRvIHRleHQgZm9ybWF0LgorCisgIEZsb2F0aW5nIHBvaW50IHZhbHVlcyBjYW4gYmUgZm9ybWF0dGVkIGNvbXBhY3RseSB3aXRoIDE1IGRpZ2l0cyBvZgorICBwcmVjaXNpb24gKHdoaWNoIGlzIHRoZSBtb3N0IHRoYXQgSUVFRSA3NTQgImRvdWJsZSIgY2FuIGd1YXJhbnRlZSkKKyAgdXNpbmcgZmxvYXRfZm9ybWF0PScuMTVnJy4KKworICBBcmdzOgorICAgIG1lc3NhZ2U6IFRoZSBwcm90b2NvbCBidWZmZXJzIG1lc3NhZ2UuCisgICAgYXNfdXRmODogUHJvZHVjZSB0ZXh0IG91dHB1dCBpbiBVVEY4IGZvcm1hdC4KKyAgICBhc19vbmVfbGluZTogRG9uJ3QgaW50cm9kdWNlIG5ld2xpbmVzIGJldHdlZW4gZmllbGRzLgorICAgIHBvaW50eV9icmFja2V0czogSWYgVHJ1ZSwgdXNlIGFuZ2xlIGJyYWNrZXRzIGluc3RlYWQgb2YgY3VybHkgYnJhY2VzIGZvcgorICAgICAgbmVzdGluZy4KKyAgICB1c2VfaW5kZXhfb3JkZXI6IElmIFRydWUsIHByaW50IGZpZWxkcyBvZiBhIHByb3RvIG1lc3NhZ2UgdXNpbmcgdGhlIG9yZGVyCisgICAgICBkZWZpbmVkIGluIHNvdXJjZSBjb2RlIGluc3RlYWQgb2YgdGhlIGZpZWxkIG51bWJlci4gQnkgZGVmYXVsdCwgdXNlIHRoZQorICAgICAgZmllbGQgbnVtYmVyIG9yZGVyLgorICAgIGZsb2F0X2Zvcm1hdDogSWYgc2V0LCB1c2UgdGhpcyB0byBzcGVjaWZ5IGZsb2F0aW5nIHBvaW50IG51bWJlciBmb3JtYXR0aW5nCisgICAgICAocGVyIHRoZSAiRm9ybWF0IFNwZWNpZmljYXRpb24gTWluaS1MYW5ndWFnZSIpOyBvdGhlcndpc2UsIHN0cigpIGlzIHVzZWQuCisKKyAgUmV0dXJuczoKKyAgICBBIHN0cmluZyBvZiB0aGUgdGV4dCBmb3JtYXR0ZWQgcHJvdG9jb2wgYnVmZmVyIG1lc3NhZ2UuCisgICIiIgorICBvdXQgPSBjU3RyaW5nSU8uU3RyaW5nSU8oKQorICBQcmludE1lc3NhZ2UobWVzc2FnZSwgb3V0LCBhc191dGY4PWFzX3V0ZjgsIGFzX29uZV9saW5lPWFzX29uZV9saW5lLAorICAgICAgICAgICAgICAgcG9pbnR5X2JyYWNrZXRzPXBvaW50eV9icmFja2V0cywKKyAgICAgICAgICAgICAgIHVzZV9pbmRleF9vcmRlcj11c2VfaW5kZXhfb3JkZXIsCisgICAgICAgICAgICAgICBmbG9hdF9mb3JtYXQ9ZmxvYXRfZm9ybWF0KQorICByZXN1bHQgPSBvdXQuZ2V0dmFsdWUoKQorICBvdXQuY2xvc2UoKQorICBpZiBhc19vbmVfbGluZToKKyAgICByZXR1cm4gcmVzdWx0LnJzdHJpcCgpCisgIHJldHVybiByZXN1bHQKKworCitkZWYgUHJpbnRNZXNzYWdlKG1lc3NhZ2UsIG91dCwgaW5kZW50PTAsIGFzX3V0Zjg9RmFsc2UsIGFzX29uZV9saW5lPUZhbHNlLAorICAgICAgICAgICAgICAgICBwb2ludHlfYnJhY2tldHM9RmFsc2UsIHVzZV9pbmRleF9vcmRlcj1GYWxzZSwKKyAgICAgICAgICAgICAgICAgZmxvYXRfZm9ybWF0PU5vbmUpOgorICBmaWVsZHMgPSBtZXNzYWdlLkxpc3RGaWVsZHMoKQorICBpZiB1c2VfaW5kZXhfb3JkZXI6CisgICAgZmllbGRzLnNvcnQoa2V5PWxhbWJkYSB4OiB4WzBdLmluZGV4KQorICBmb3IgZmllbGQsIHZhbHVlIGluIGZpZWxkczoKKyAgICBpZiBmaWVsZC5sYWJlbCA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICAgIGZvciBlbGVtZW50IGluIHZhbHVlOgorICAgICAgICBQcmludEZpZWxkKGZpZWxkLCBlbGVtZW50LCBvdXQsIGluZGVudCwgYXNfdXRmOCwgYXNfb25lX2xpbmUsCisgICAgICAgICAgICAgICAgICAgcG9pbnR5X2JyYWNrZXRzPXBvaW50eV9icmFja2V0cywKKyAgICAgICAgICAgICAgICAgICB1c2VfaW5kZXhfb3JkZXI9dXNlX2luZGV4X29yZGVyLAorICAgICAgICAgICAgICAgICAgIGZsb2F0X2Zvcm1hdD1mbG9hdF9mb3JtYXQpCisgICAgZWxzZToKKyAgICAgIFByaW50RmllbGQoZmllbGQsIHZhbHVlLCBvdXQsIGluZGVudCwgYXNfdXRmOCwgYXNfb25lX2xpbmUsCisgICAgICAgICAgICAgICAgIHBvaW50eV9icmFja2V0cz1wb2ludHlfYnJhY2tldHMsCisgICAgICAgICAgICAgICAgIHVzZV9pbmRleF9vcmRlcj11c2VfaW5kZXhfb3JkZXIsCisgICAgICAgICAgICAgICAgIGZsb2F0X2Zvcm1hdD1mbG9hdF9mb3JtYXQpCisKKworZGVmIFByaW50RmllbGQoZmllbGQsIHZhbHVlLCBvdXQsIGluZGVudD0wLCBhc191dGY4PUZhbHNlLCBhc19vbmVfbGluZT1GYWxzZSwKKyAgICAgICAgICAgICAgIHBvaW50eV9icmFja2V0cz1GYWxzZSwgdXNlX2luZGV4X29yZGVyPUZhbHNlLCBmbG9hdF9mb3JtYXQ9Tm9uZSk6CisgICIiIlByaW50IGEgc2luZ2xlIGZpZWxkIG5hbWUvdmFsdWUgcGFpci4gIEZvciByZXBlYXRlZCBmaWVsZHMsIHRoZSB2YWx1ZQorICBzaG91bGQgYmUgYSBzaW5nbGUgZWxlbWVudC4iIiIKKworICBvdXQud3JpdGUoJyAnICogaW5kZW50KQorICBpZiBmaWVsZC5pc19leHRlbnNpb246CisgICAgb3V0LndyaXRlKCdbJykKKyAgICBpZiAoZmllbGQuY29udGFpbmluZ190eXBlLkdldE9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCBhbmQKKyAgICAgICAgZmllbGQudHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX01FU1NBR0UgYW5kCisgICAgICAgIGZpZWxkLm1lc3NhZ2VfdHlwZSA9PSBmaWVsZC5leHRlbnNpb25fc2NvcGUgYW5kCisgICAgICAgIGZpZWxkLmxhYmVsID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkxBQkVMX09QVElPTkFMKToKKyAgICAgIG91dC53cml0ZShmaWVsZC5tZXNzYWdlX3R5cGUuZnVsbF9uYW1lKQorICAgIGVsc2U6CisgICAgICBvdXQud3JpdGUoZmllbGQuZnVsbF9uYW1lKQorICAgIG91dC53cml0ZSgnXScpCisgIGVsaWYgZmllbGQudHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0dST1VQOgorICAgICMgRm9yIGdyb3VwcywgdXNlIHRoZSBjYXBpdGFsaXplZCBuYW1lLgorICAgIG91dC53cml0ZShmaWVsZC5tZXNzYWdlX3R5cGUubmFtZSkKKyAgZWxzZToKKyAgICBvdXQud3JpdGUoZmllbGQubmFtZSkKKworICBpZiBmaWVsZC5jcHBfdHlwZSAhPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgIyBUaGUgY29sb24gaXMgb3B0aW9uYWwgaW4gdGhpcyBjYXNlLCBidXQgb3VyIGNyb3NzLWxhbmd1YWdlIGdvbGRlbiBmaWxlcworICAgICMgZG9uJ3QgaW5jbHVkZSBpdC4KKyAgICBvdXQud3JpdGUoJzogJykKKworICBQcmludEZpZWxkVmFsdWUoZmllbGQsIHZhbHVlLCBvdXQsIGluZGVudCwgYXNfdXRmOCwgYXNfb25lX2xpbmUsCisgICAgICAgICAgICAgICAgICBwb2ludHlfYnJhY2tldHM9cG9pbnR5X2JyYWNrZXRzLAorICAgICAgICAgICAgICAgICAgdXNlX2luZGV4X29yZGVyPXVzZV9pbmRleF9vcmRlciwKKyAgICAgICAgICAgICAgICAgIGZsb2F0X2Zvcm1hdD1mbG9hdF9mb3JtYXQpCisgIGlmIGFzX29uZV9saW5lOgorICAgIG91dC53cml0ZSgnICcpCisgIGVsc2U6CisgICAgb3V0LndyaXRlKCdcbicpCisKKworZGVmIFByaW50RmllbGRWYWx1ZShmaWVsZCwgdmFsdWUsIG91dCwgaW5kZW50PTAsIGFzX3V0Zjg9RmFsc2UsCisgICAgICAgICAgICAgICAgICAgIGFzX29uZV9saW5lPUZhbHNlLCBwb2ludHlfYnJhY2tldHM9RmFsc2UsCisgICAgICAgICAgICAgICAgICAgIHVzZV9pbmRleF9vcmRlcj1GYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgZmxvYXRfZm9ybWF0PU5vbmUpOgorICAiIiJQcmludCBhIHNpbmdsZSBmaWVsZCB2YWx1ZSAobm90IGluY2x1ZGluZyBuYW1lKS4gIEZvciByZXBlYXRlZCBmaWVsZHMsCisgIHRoZSB2YWx1ZSBzaG91bGQgYmUgYSBzaW5nbGUgZWxlbWVudC4iIiIKKworICBpZiBwb2ludHlfYnJhY2tldHM6CisgICAgb3BlbmIgPSAnPCcKKyAgICBjbG9zZWIgPSAnPicKKyAgZWxzZToKKyAgICBvcGVuYiA9ICd7JworICAgIGNsb3NlYiA9ICd9JworCisgIGlmIGZpZWxkLmNwcF90eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfTUVTU0FHRToKKyAgICBpZiBhc19vbmVfbGluZToKKyAgICAgIG91dC53cml0ZSgnICVzICcgJSBvcGVuYikKKyAgICAgIFByaW50TWVzc2FnZSh2YWx1ZSwgb3V0LCBpbmRlbnQsIGFzX3V0ZjgsIGFzX29uZV9saW5lLAorICAgICAgICAgICAgICAgICAgIHBvaW50eV9icmFja2V0cz1wb2ludHlfYnJhY2tldHMsCisgICAgICAgICAgICAgICAgICAgdXNlX2luZGV4X29yZGVyPXVzZV9pbmRleF9vcmRlciwKKyAgICAgICAgICAgICAgICAgICBmbG9hdF9mb3JtYXQ9ZmxvYXRfZm9ybWF0KQorICAgICAgb3V0LndyaXRlKGNsb3NlYikKKyAgICBlbHNlOgorICAgICAgb3V0LndyaXRlKCcgJXNcbicgJSBvcGVuYikKKyAgICAgIFByaW50TWVzc2FnZSh2YWx1ZSwgb3V0LCBpbmRlbnQgKyAyLCBhc191dGY4LCBhc19vbmVfbGluZSwKKyAgICAgICAgICAgICAgICAgICBwb2ludHlfYnJhY2tldHM9cG9pbnR5X2JyYWNrZXRzLAorICAgICAgICAgICAgICAgICAgIHVzZV9pbmRleF9vcmRlcj11c2VfaW5kZXhfb3JkZXIsCisgICAgICAgICAgICAgICAgICAgZmxvYXRfZm9ybWF0PWZsb2F0X2Zvcm1hdCkKKyAgICAgIG91dC53cml0ZSgnICcgKiBpbmRlbnQgKyBjbG9zZWIpCisgIGVsaWYgZmllbGQuY3BwX3R5cGUgPT0gZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuQ1BQVFlQRV9FTlVNOgorICAgIGVudW1fdmFsdWUgPSBmaWVsZC5lbnVtX3R5cGUudmFsdWVzX2J5X251bWJlci5nZXQodmFsdWUsIE5vbmUpCisgICAgaWYgZW51bV92YWx1ZSBpcyBub3QgTm9uZToKKyAgICAgIG91dC53cml0ZShlbnVtX3ZhbHVlLm5hbWUpCisgICAgZWxzZToKKyAgICAgIG91dC53cml0ZShzdHIodmFsdWUpKQorICBlbGlmIGZpZWxkLmNwcF90eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfU1RSSU5HOgorICAgIG91dC53cml0ZSgnXCInKQorICAgIGlmIGlzaW5zdGFuY2UodmFsdWUsIHVuaWNvZGUpOgorICAgICAgb3V0X3ZhbHVlID0gdmFsdWUuZW5jb2RlKCd1dGYtOCcpCisgICAgZWxzZToKKyAgICAgIG91dF92YWx1ZSA9IHZhbHVlCisgICAgaWYgZmllbGQudHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0JZVEVTOgorICAgICAgIyBXZSBuZWVkIHRvIGVzY2FwZSBub24tVVRGOCBjaGFycyBpbiBUWVBFX0JZVEVTIGZpZWxkLgorICAgICAgb3V0X2FzX3V0ZjggPSBGYWxzZQorICAgIGVsc2U6CisgICAgICBvdXRfYXNfdXRmOCA9IGFzX3V0ZjgKKyAgICBvdXQud3JpdGUodGV4dF9lbmNvZGluZy5DRXNjYXBlKG91dF92YWx1ZSwgb3V0X2FzX3V0ZjgpKQorICAgIG91dC53cml0ZSgnXCInKQorICBlbGlmIGZpZWxkLmNwcF90eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkNQUFRZUEVfQk9PTDoKKyAgICBpZiB2YWx1ZToKKyAgICAgIG91dC53cml0ZSgndHJ1ZScpCisgICAgZWxzZToKKyAgICAgIG91dC53cml0ZSgnZmFsc2UnKQorICBlbGlmIGZpZWxkLmNwcF90eXBlIGluIF9GTE9BVF9UWVBFUyBhbmQgZmxvYXRfZm9ybWF0IGlzIG5vdCBOb25lOgorICAgIG91dC53cml0ZSgnezE6ezB9fScuZm9ybWF0KGZsb2F0X2Zvcm1hdCwgdmFsdWUpKQorICBlbHNlOgorICAgIG91dC53cml0ZShzdHIodmFsdWUpKQorCisKK2RlZiBQYXJzZSh0ZXh0LCBtZXNzYWdlKToKKyAgIiIiUGFyc2VzIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uIG9mIGEgcHJvdG9jb2wgbWVzc2FnZSBpbnRvIGEgbWVzc2FnZS4KKworICBBcmdzOgorICAgIHRleHQ6IE1lc3NhZ2UgQVNDSUkgcmVwcmVzZW50YXRpb24uCisgICAgbWVzc2FnZTogQSBwcm90b2NvbCBidWZmZXIgbWVzc2FnZSB0byBtZXJnZSBpbnRvLgorCisgIFJldHVybnM6CisgICAgVGhlIHNhbWUgbWVzc2FnZSBwYXNzZWQgYXMgYXJndW1lbnQuCisKKyAgUmFpc2VzOgorICAgIFBhcnNlRXJyb3I6IE9uIEFTQ0lJIHBhcnNpbmcgcHJvYmxlbXMuCisgICIiIgorICBpZiBub3QgaXNpbnN0YW5jZSh0ZXh0LCBzdHIpOiB0ZXh0ID0gdGV4dC5kZWNvZGUoJ3V0Zi04JykKKyAgcmV0dXJuIFBhcnNlTGluZXModGV4dC5zcGxpdCgnXG4nKSwgbWVzc2FnZSkKKworCitkZWYgTWVyZ2UodGV4dCwgbWVzc2FnZSk6CisgICIiIlBhcnNlcyBhbiBBU0NJSSByZXByZXNlbnRhdGlvbiBvZiBhIHByb3RvY29sIG1lc3NhZ2UgaW50byBhIG1lc3NhZ2UuCisKKyAgTGlrZSBQYXJzZSgpLCBidXQgYWxsb3dzIHJlcGVhdGVkIHZhbHVlcyBmb3IgYSBub24tcmVwZWF0ZWQgZmllbGQsIGFuZCB1c2VzCisgIHRoZSBsYXN0IG9uZS4KKworICBBcmdzOgorICAgIHRleHQ6IE1lc3NhZ2UgQVNDSUkgcmVwcmVzZW50YXRpb24uCisgICAgbWVzc2FnZTogQSBwcm90b2NvbCBidWZmZXIgbWVzc2FnZSB0byBtZXJnZSBpbnRvLgorCisgIFJldHVybnM6CisgICAgVGhlIHNhbWUgbWVzc2FnZSBwYXNzZWQgYXMgYXJndW1lbnQuCisKKyAgUmFpc2VzOgorICAgIFBhcnNlRXJyb3I6IE9uIEFTQ0lJIHBhcnNpbmcgcHJvYmxlbXMuCisgICIiIgorICByZXR1cm4gTWVyZ2VMaW5lcyh0ZXh0LnNwbGl0KCdcbicpLCBtZXNzYWdlKQorCisKK2RlZiBQYXJzZUxpbmVzKGxpbmVzLCBtZXNzYWdlKToKKyAgIiIiUGFyc2VzIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uIG9mIGEgcHJvdG9jb2wgbWVzc2FnZSBpbnRvIGEgbWVzc2FnZS4KKworICBBcmdzOgorICAgIGxpbmVzOiBBbiBpdGVyYWJsZSBvZiBsaW5lcyBvZiBhIG1lc3NhZ2UncyBBU0NJSSByZXByZXNlbnRhdGlvbi4KKyAgICBtZXNzYWdlOiBBIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlIHRvIG1lcmdlIGludG8uCisKKyAgUmV0dXJuczoKKyAgICBUaGUgc2FtZSBtZXNzYWdlIHBhc3NlZCBhcyBhcmd1bWVudC4KKworICBSYWlzZXM6CisgICAgUGFyc2VFcnJvcjogT24gQVNDSUkgcGFyc2luZyBwcm9ibGVtcy4KKyAgIiIiCisgIF9QYXJzZU9yTWVyZ2UobGluZXMsIG1lc3NhZ2UsIEZhbHNlKQorICByZXR1cm4gbWVzc2FnZQorCisKK2RlZiBNZXJnZUxpbmVzKGxpbmVzLCBtZXNzYWdlKToKKyAgIiIiUGFyc2VzIGFuIEFTQ0lJIHJlcHJlc2VudGF0aW9uIG9mIGEgcHJvdG9jb2wgbWVzc2FnZSBpbnRvIGEgbWVzc2FnZS4KKworICBBcmdzOgorICAgIGxpbmVzOiBBbiBpdGVyYWJsZSBvZiBsaW5lcyBvZiBhIG1lc3NhZ2UncyBBU0NJSSByZXByZXNlbnRhdGlvbi4KKyAgICBtZXNzYWdlOiBBIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlIHRvIG1lcmdlIGludG8uCisKKyAgUmV0dXJuczoKKyAgICBUaGUgc2FtZSBtZXNzYWdlIHBhc3NlZCBhcyBhcmd1bWVudC4KKworICBSYWlzZXM6CisgICAgUGFyc2VFcnJvcjogT24gQVNDSUkgcGFyc2luZyBwcm9ibGVtcy4KKyAgIiIiCisgIF9QYXJzZU9yTWVyZ2UobGluZXMsIG1lc3NhZ2UsIFRydWUpCisgIHJldHVybiBtZXNzYWdlCisKKworZGVmIF9QYXJzZU9yTWVyZ2UobGluZXMsIG1lc3NhZ2UsIGFsbG93X211bHRpcGxlX3NjYWxhcnMpOgorICAiIiJDb252ZXJ0cyBhbiBBU0NJSSByZXByZXNlbnRhdGlvbiBvZiBhIHByb3RvY29sIG1lc3NhZ2UgaW50byBhIG1lc3NhZ2UuCisKKyAgQXJnczoKKyAgICBsaW5lczogTGluZXMgb2YgYSBtZXNzYWdlJ3MgQVNDSUkgcmVwcmVzZW50YXRpb24uCisgICAgbWVzc2FnZTogQSBwcm90b2NvbCBidWZmZXIgbWVzc2FnZSB0byBtZXJnZSBpbnRvLgorICAgIGFsbG93X211bHRpcGxlX3NjYWxhcnM6IERldGVybWluZXMgaWYgcmVwZWF0ZWQgdmFsdWVzIGZvciBhIG5vbi1yZXBlYXRlZAorICAgICAgZmllbGQgYXJlIHBlcm1pdHRlZCwgZS5nLiwgdGhlIHN0cmluZyAiZm9vOiAxIGZvbzogMiIgZm9yIGEKKyAgICAgIHJlcXVpcmVkL29wdGlvbmFsIGZpZWxkIG5hbWVkICJmb28iLgorCisgIFJhaXNlczoKKyAgICBQYXJzZUVycm9yOiBPbiBBU0NJSSBwYXJzaW5nIHByb2JsZW1zLgorICAiIiIKKyAgdG9rZW5pemVyID0gX1Rva2VuaXplcihsaW5lcykKKyAgd2hpbGUgbm90IHRva2VuaXplci5BdEVuZCgpOgorICAgIF9NZXJnZUZpZWxkKHRva2VuaXplciwgbWVzc2FnZSwgYWxsb3dfbXVsdGlwbGVfc2NhbGFycykKKworCitkZWYgX01lcmdlRmllbGQodG9rZW5pemVyLCBtZXNzYWdlLCBhbGxvd19tdWx0aXBsZV9zY2FsYXJzKToKKyAgIiIiTWVyZ2VzIGEgc2luZ2xlIHByb3RvY29sIG1lc3NhZ2UgZmllbGQgaW50byBhIG1lc3NhZ2UuCisKKyAgQXJnczoKKyAgICB0b2tlbml6ZXI6IEEgdG9rZW5pemVyIHRvIHBhcnNlIHRoZSBmaWVsZCBuYW1lIGFuZCB2YWx1ZXMuCisgICAgbWVzc2FnZTogQSBwcm90b2NvbCBtZXNzYWdlIHRvIHJlY29yZCB0aGUgZGF0YS4KKyAgICBhbGxvd19tdWx0aXBsZV9zY2FsYXJzOiBEZXRlcm1pbmVzIGlmIHJlcGVhdGVkIHZhbHVlcyBmb3IgYSBub24tcmVwZWF0ZWQKKyAgICAgIGZpZWxkIGFyZSBwZXJtaXR0ZWQsIGUuZy4sIHRoZSBzdHJpbmcgImZvbzogMSBmb286IDIiIGZvciBhCisgICAgICByZXF1aXJlZC9vcHRpb25hbCBmaWVsZCBuYW1lZCAiZm9vIi4KKworICBSYWlzZXM6CisgICAgUGFyc2VFcnJvcjogSW4gY2FzZSBvZiBBU0NJSSBwYXJzaW5nIHByb2JsZW1zLgorICAiIiIKKyAgbWVzc2FnZV9kZXNjcmlwdG9yID0gbWVzc2FnZS5ERVNDUklQVE9SCisgIGlmIChoYXNhdHRyKG1lc3NhZ2VfZGVzY3JpcHRvciwgJ3N5bnRheCcpIGFuZAorICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yLnN5bnRheCA9PSAncHJvdG8zJyk6CisgICAgIyBQcm90bzMgZG9lc24ndCByZXByZXNlbnQgcHJlc2VuY2Ugc28gd2UgY2FuJ3QgdGVzdCBpZiBtdWx0aXBsZQorICAgICMgc2NhbGFycyBoYXZlIG9jY3VycmVkLiAgV2UgaGF2ZSB0byBhbGxvdyB0aGVtLgorICAgIGFsbG93X211bHRpcGxlX3NjYWxhcnMgPSBUcnVlCisgIGlmIHRva2VuaXplci5UcnlDb25zdW1lKCdbJyk6CisgICAgbmFtZSA9IFt0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIoKV0KKyAgICB3aGlsZSB0b2tlbml6ZXIuVHJ5Q29uc3VtZSgnLicpOgorICAgICAgbmFtZS5hcHBlbmQodG9rZW5pemVyLkNvbnN1bWVJZGVudGlmaWVyKCkpCisgICAgbmFtZSA9ICcuJy5qb2luKG5hbWUpCisKKyAgICBpZiBub3QgbWVzc2FnZV9kZXNjcmlwdG9yLmlzX2V4dGVuZGFibGU6CisgICAgICByYWlzZSB0b2tlbml6ZXIuUGFyc2VFcnJvclByZXZpb3VzVG9rZW4oCisgICAgICAgICAgJ01lc3NhZ2UgdHlwZSAiJXMiIGRvZXMgbm90IGhhdmUgZXh0ZW5zaW9ucy4nICUKKyAgICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IuZnVsbF9uYW1lKQorICAgICMgcHlsaW50OiBkaXNhYmxlPXByb3RlY3RlZC1hY2Nlc3MKKyAgICBmaWVsZCA9IG1lc3NhZ2UuRXh0ZW5zaW9ucy5fRmluZEV4dGVuc2lvbkJ5TmFtZShuYW1lKQorICAgICMgcHlsaW50OiBlbmFibGU9cHJvdGVjdGVkLWFjY2VzcworICAgIGlmIG5vdCBmaWVsZDoKKyAgICAgIHJhaXNlIHRva2VuaXplci5QYXJzZUVycm9yUHJldmlvdXNUb2tlbigKKyAgICAgICAgICAnRXh0ZW5zaW9uICIlcyIgbm90IHJlZ2lzdGVyZWQuJyAlIG5hbWUpCisgICAgZWxpZiBtZXNzYWdlX2Rlc2NyaXB0b3IgIT0gZmllbGQuY29udGFpbmluZ190eXBlOgorICAgICAgcmFpc2UgdG9rZW5pemVyLlBhcnNlRXJyb3JQcmV2aW91c1Rva2VuKAorICAgICAgICAgICdFeHRlbnNpb24gIiVzIiBkb2VzIG5vdCBleHRlbmQgbWVzc2FnZSB0eXBlICIlcyIuJyAlICgKKyAgICAgICAgICAgICAgbmFtZSwgbWVzc2FnZV9kZXNjcmlwdG9yLmZ1bGxfbmFtZSkpCisgICAgdG9rZW5pemVyLkNvbnN1bWUoJ10nKQorICBlbHNlOgorICAgIG5hbWUgPSB0b2tlbml6ZXIuQ29uc3VtZUlkZW50aWZpZXIoKQorICAgIGZpZWxkID0gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lLmdldChuYW1lLCBOb25lKQorCisgICAgIyBHcm91cCBuYW1lcyBhcmUgZXhwZWN0ZWQgdG8gYmUgY2FwaXRhbGl6ZWQgYXMgdGhleSBhcHBlYXIgaW4gdGhlCisgICAgIyAucHJvdG8gZmlsZSwgd2hpY2ggYWN0dWFsbHkgbWF0Y2hlcyB0aGVpciB0eXBlIG5hbWVzLCBub3QgdGhlaXIgZmllbGQKKyAgICAjIG5hbWVzLgorICAgIGlmIG5vdCBmaWVsZDoKKyAgICAgIGZpZWxkID0gbWVzc2FnZV9kZXNjcmlwdG9yLmZpZWxkc19ieV9uYW1lLmdldChuYW1lLmxvd2VyKCksIE5vbmUpCisgICAgICBpZiBmaWVsZCBhbmQgZmllbGQudHlwZSAhPSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0dST1VQOgorICAgICAgICBmaWVsZCA9IE5vbmUKKworICAgIGlmIChmaWVsZCBhbmQgZmllbGQudHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0dST1VQIGFuZAorICAgICAgICBmaWVsZC5tZXNzYWdlX3R5cGUubmFtZSAhPSBuYW1lKToKKyAgICAgIGZpZWxkID0gTm9uZQorCisgICAgaWYgbm90IGZpZWxkOgorICAgICAgcmFpc2UgdG9rZW5pemVyLlBhcnNlRXJyb3JQcmV2aW91c1Rva2VuKAorICAgICAgICAgICdNZXNzYWdlIHR5cGUgIiVzIiBoYXMgbm8gZmllbGQgbmFtZWQgIiVzIi4nICUgKAorICAgICAgICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IuZnVsbF9uYW1lLCBuYW1lKSkKKworICBpZiBmaWVsZC5jcHBfdHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5DUFBUWVBFX01FU1NBR0U6CisgICAgdG9rZW5pemVyLlRyeUNvbnN1bWUoJzonKQorCisgICAgaWYgdG9rZW5pemVyLlRyeUNvbnN1bWUoJzwnKToKKyAgICAgIGVuZF90b2tlbiA9ICc+JworICAgIGVsc2U6CisgICAgICB0b2tlbml6ZXIuQ29uc3VtZSgneycpCisgICAgICBlbmRfdG9rZW4gPSAnfScKKworICAgIGlmIGZpZWxkLmxhYmVsID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLkxBQkVMX1JFUEVBVEVEOgorICAgICAgaWYgZmllbGQuaXNfZXh0ZW5zaW9uOgorICAgICAgICBzdWJfbWVzc2FnZSA9IG1lc3NhZ2UuRXh0ZW5zaW9uc1tmaWVsZF0uYWRkKCkKKyAgICAgIGVsc2U6CisgICAgICAgIHN1Yl9tZXNzYWdlID0gZ2V0YXR0cihtZXNzYWdlLCBmaWVsZC5uYW1lKS5hZGQoKQorICAgIGVsc2U6CisgICAgICBpZiBmaWVsZC5pc19leHRlbnNpb246CisgICAgICAgIHN1Yl9tZXNzYWdlID0gbWVzc2FnZS5FeHRlbnNpb25zW2ZpZWxkXQorICAgICAgZWxzZToKKyAgICAgICAgc3ViX21lc3NhZ2UgPSBnZXRhdHRyKG1lc3NhZ2UsIGZpZWxkLm5hbWUpCisgICAgICBzdWJfbWVzc2FnZS5TZXRJblBhcmVudCgpCisKKyAgICB3aGlsZSBub3QgdG9rZW5pemVyLlRyeUNvbnN1bWUoZW5kX3Rva2VuKToKKyAgICAgIGlmIHRva2VuaXplci5BdEVuZCgpOgorICAgICAgICByYWlzZSB0b2tlbml6ZXIuUGFyc2VFcnJvclByZXZpb3VzVG9rZW4oJ0V4cGVjdGVkICIlcyIuJyAlIChlbmRfdG9rZW4pKQorICAgICAgX01lcmdlRmllbGQodG9rZW5pemVyLCBzdWJfbWVzc2FnZSwgYWxsb3dfbXVsdGlwbGVfc2NhbGFycykKKyAgZWxzZToKKyAgICBfTWVyZ2VTY2FsYXJGaWVsZCh0b2tlbml6ZXIsIG1lc3NhZ2UsIGZpZWxkLCBhbGxvd19tdWx0aXBsZV9zY2FsYXJzKQorCisgICMgRm9yIGhpc3RvcmljYWwgcmVhc29ucywgZmllbGRzIG1heSBvcHRpb25hbGx5IGJlIHNlcGFyYXRlZCBieSBjb21tYXMgb3IKKyAgIyBzZW1pY29sb25zLgorICBpZiBub3QgdG9rZW5pemVyLlRyeUNvbnN1bWUoJywnKToKKyAgICB0b2tlbml6ZXIuVHJ5Q29uc3VtZSgnOycpCisKKworZGVmIF9NZXJnZVNjYWxhckZpZWxkKHRva2VuaXplciwgbWVzc2FnZSwgZmllbGQsIGFsbG93X211bHRpcGxlX3NjYWxhcnMpOgorICAiIiJNZXJnZXMgYSBzaW5nbGUgcHJvdG9jb2wgbWVzc2FnZSBzY2FsYXIgZmllbGQgaW50byBhIG1lc3NhZ2UuCisKKyAgQXJnczoKKyAgICB0b2tlbml6ZXI6IEEgdG9rZW5pemVyIHRvIHBhcnNlIHRoZSBmaWVsZCB2YWx1ZS4KKyAgICBtZXNzYWdlOiBBIHByb3RvY29sIG1lc3NhZ2UgdG8gcmVjb3JkIHRoZSBkYXRhLgorICAgIGZpZWxkOiBUaGUgZGVzY3JpcHRvciBvZiB0aGUgZmllbGQgdG8gYmUgbWVyZ2VkLgorICAgIGFsbG93X211bHRpcGxlX3NjYWxhcnM6IERldGVybWluZXMgaWYgcmVwZWF0ZWQgdmFsdWVzIGZvciBhIG5vbi1yZXBlYXRlZAorICAgICAgZmllbGQgYXJlIHBlcm1pdHRlZCwgZS5nLiwgdGhlIHN0cmluZyAiZm9vOiAxIGZvbzogMiIgZm9yIGEKKyAgICAgIHJlcXVpcmVkL29wdGlvbmFsIGZpZWxkIG5hbWVkICJmb28iLgorCisgIFJhaXNlczoKKyAgICBQYXJzZUVycm9yOiBJbiBjYXNlIG9mIEFTQ0lJIHBhcnNpbmcgcHJvYmxlbXMuCisgICAgUnVudGltZUVycm9yOiBPbiBydW50aW1lIGVycm9ycy4KKyAgIiIiCisgIHRva2VuaXplci5Db25zdW1lKCc6JykKKyAgdmFsdWUgPSBOb25lCisKKyAgaWYgZmllbGQudHlwZSBpbiAoZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9JTlQzMiwKKyAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9TSU5UMzIsCisgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfU0ZJWEVEMzIpOgorICAgIHZhbHVlID0gdG9rZW5pemVyLkNvbnN1bWVJbnQzMigpCisgIGVsaWYgZmllbGQudHlwZSBpbiAoZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9JTlQ2NCwKKyAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX1NJTlQ2NCwKKyAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX1NGSVhFRDY0KToKKyAgICB2YWx1ZSA9IHRva2VuaXplci5Db25zdW1lSW50NjQoKQorICBlbGlmIGZpZWxkLnR5cGUgaW4gKGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfVUlOVDMyLAorICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfRklYRUQzMik6CisgICAgdmFsdWUgPSB0b2tlbml6ZXIuQ29uc3VtZVVpbnQzMigpCisgIGVsaWYgZmllbGQudHlwZSBpbiAoZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9VSU5UNjQsCisgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9GSVhFRDY0KToKKyAgICB2YWx1ZSA9IHRva2VuaXplci5Db25zdW1lVWludDY0KCkKKyAgZWxpZiBmaWVsZC50eXBlIGluIChkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0ZMT0FULAorICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfRE9VQkxFKToKKyAgICB2YWx1ZSA9IHRva2VuaXplci5Db25zdW1lRmxvYXQoKQorICBlbGlmIGZpZWxkLnR5cGUgPT0gZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9CT09MOgorICAgIHZhbHVlID0gdG9rZW5pemVyLkNvbnN1bWVCb29sKCkKKyAgZWxpZiBmaWVsZC50eXBlID09IGRlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yLlRZUEVfU1RSSU5HOgorICAgIHZhbHVlID0gdG9rZW5pemVyLkNvbnN1bWVTdHJpbmcoKQorICBlbGlmIGZpZWxkLnR5cGUgPT0gZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IuVFlQRV9CWVRFUzoKKyAgICB2YWx1ZSA9IHRva2VuaXplci5Db25zdW1lQnl0ZVN0cmluZygpCisgIGVsaWYgZmllbGQudHlwZSA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5UWVBFX0VOVU06CisgICAgdmFsdWUgPSB0b2tlbml6ZXIuQ29uc3VtZUVudW0oZmllbGQpCisgIGVsc2U6CisgICAgcmFpc2UgUnVudGltZUVycm9yKCdVbmtub3duIGZpZWxkIHR5cGUgJWQnICUgZmllbGQudHlwZSkKKworICBpZiBmaWVsZC5sYWJlbCA9PSBkZXNjcmlwdG9yLkZpZWxkRGVzY3JpcHRvci5MQUJFTF9SRVBFQVRFRDoKKyAgICBpZiBmaWVsZC5pc19leHRlbnNpb246CisgICAgICBtZXNzYWdlLkV4dGVuc2lvbnNbZmllbGRdLmFwcGVuZCh2YWx1ZSkKKyAgICBlbHNlOgorICAgICAgZ2V0YXR0cihtZXNzYWdlLCBmaWVsZC5uYW1lKS5hcHBlbmQodmFsdWUpCisgIGVsc2U6CisgICAgaWYgZmllbGQuaXNfZXh0ZW5zaW9uOgorICAgICAgaWYgbm90IGFsbG93X211bHRpcGxlX3NjYWxhcnMgYW5kIG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKGZpZWxkKToKKyAgICAgICAgcmFpc2UgdG9rZW5pemVyLlBhcnNlRXJyb3JQcmV2aW91c1Rva2VuKAorICAgICAgICAgICAgJ01lc3NhZ2UgdHlwZSAiJXMiIHNob3VsZCBub3QgaGF2ZSBtdWx0aXBsZSAiJXMiIGV4dGVuc2lvbnMuJyAlCisgICAgICAgICAgICAobWVzc2FnZS5ERVNDUklQVE9SLmZ1bGxfbmFtZSwgZmllbGQuZnVsbF9uYW1lKSkKKyAgICAgIGVsc2U6CisgICAgICAgIG1lc3NhZ2UuRXh0ZW5zaW9uc1tmaWVsZF0gPSB2YWx1ZQorICAgIGVsc2U6CisgICAgICBpZiBub3QgYWxsb3dfbXVsdGlwbGVfc2NhbGFycyBhbmQgbWVzc2FnZS5IYXNGaWVsZChmaWVsZC5uYW1lKToKKyAgICAgICAgcmFpc2UgdG9rZW5pemVyLlBhcnNlRXJyb3JQcmV2aW91c1Rva2VuKAorICAgICAgICAgICAgJ01lc3NhZ2UgdHlwZSAiJXMiIHNob3VsZCBub3QgaGF2ZSBtdWx0aXBsZSAiJXMiIGZpZWxkcy4nICUKKyAgICAgICAgICAgIChtZXNzYWdlLkRFU0NSSVBUT1IuZnVsbF9uYW1lLCBmaWVsZC5uYW1lKSkKKyAgICAgIGVsc2U6CisgICAgICAgIHNldGF0dHIobWVzc2FnZSwgZmllbGQubmFtZSwgdmFsdWUpCisKKworY2xhc3MgX1Rva2VuaXplcihvYmplY3QpOgorICAiIiJQcm90b2NvbCBidWZmZXIgQVNDSUkgcmVwcmVzZW50YXRpb24gdG9rZW5pemVyLgorCisgIFRoaXMgY2xhc3MgaGFuZGxlcyB0aGUgbG93ZXIgbGV2ZWwgc3RyaW5nIHBhcnNpbmcgYnkgc3BsaXR0aW5nIGl0IGludG8KKyAgbWVhbmluZ2Z1bCB0b2tlbnMuCisKKyAgSXQgd2FzIGRpcmVjdGx5IHBvcnRlZCBmcm9tIHRoZSBKYXZhIHByb3RvY29sIGJ1ZmZlciBBUEkuCisgICIiIgorCisgIF9XSElURVNQQUNFID0gcmUuY29tcGlsZSgnKFxcc3woIy4qJCkpKycsIHJlLk1VTFRJTElORSkKKyAgX1RPS0VOID0gcmUuY29tcGlsZSgKKyAgICAgICdbYS16QS1aX11bMC05YS16QS1aXystXSp8JyAgICAgICAgICAgIyBhbiBpZGVudGlmaWVyCisgICAgICAnWzAtOSstXVswLTlhLXpBLVpfListXSp8JyAgICAgICAgICAgICMgYSBudW1iZXIKKyAgICAgICdcIihbXlwiXG5cXFxcXXxcXFxcLikqKFwifFxcXFw/JCl8JyAgIyBhIGRvdWJsZS1xdW90ZWQgc3RyaW5nCisgICAgICAnXCcoW15cJ1xuXFxcXF18XFxcXC4pKihcJ3xcXFxcPyQpJykgICMgYSBzaW5nbGUtcXVvdGVkIHN0cmluZworICBfSURFTlRJRklFUiA9IHJlLmNvbXBpbGUocidcdysnKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBsaW5lcyk6CisgICAgc2VsZi5fcG9zaXRpb24gPSAwCisgICAgc2VsZi5fbGluZSA9IC0xCisgICAgc2VsZi5fY29sdW1uID0gMAorICAgIHNlbGYuX3Rva2VuX3N0YXJ0ID0gTm9uZQorICAgIHNlbGYudG9rZW4gPSAnJworICAgIHNlbGYuX2xpbmVzID0gaXRlcihsaW5lcykKKyAgICBzZWxmLl9jdXJyZW50X2xpbmUgPSAnJworICAgIHNlbGYuX3ByZXZpb3VzX2xpbmUgPSAwCisgICAgc2VsZi5fcHJldmlvdXNfY29sdW1uID0gMAorICAgIHNlbGYuX21vcmVfbGluZXMgPSBUcnVlCisgICAgc2VsZi5fU2tpcFdoaXRlc3BhY2UoKQorICAgIHNlbGYuTmV4dFRva2VuKCkKKworICBkZWYgQXRFbmQoc2VsZik6CisgICAgIiIiQ2hlY2tzIHRoZSBlbmQgb2YgdGhlIHRleHQgd2FzIHJlYWNoZWQuCisKKyAgICBSZXR1cm5zOgorICAgICAgVHJ1ZSBpZmYgdGhlIGVuZCB3YXMgcmVhY2hlZC4KKyAgICAiIiIKKyAgICByZXR1cm4gbm90IHNlbGYudG9rZW4KKworICBkZWYgX1BvcExpbmUoc2VsZik6CisgICAgd2hpbGUgbGVuKHNlbGYuX2N1cnJlbnRfbGluZSkgPD0gc2VsZi5fY29sdW1uOgorICAgICAgdHJ5OgorICAgICAgICBzZWxmLl9jdXJyZW50X2xpbmUgPSBzZWxmLl9saW5lcy5uZXh0KCkKKyAgICAgIGV4Y2VwdCBTdG9wSXRlcmF0aW9uOgorICAgICAgICBzZWxmLl9jdXJyZW50X2xpbmUgPSAnJworICAgICAgICBzZWxmLl9tb3JlX2xpbmVzID0gRmFsc2UKKyAgICAgICAgcmV0dXJuCisgICAgICBlbHNlOgorICAgICAgICBzZWxmLl9saW5lICs9IDEKKyAgICAgICAgc2VsZi5fY29sdW1uID0gMAorCisgIGRlZiBfU2tpcFdoaXRlc3BhY2Uoc2VsZik6CisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIHNlbGYuX1BvcExpbmUoKQorICAgICAgbWF0Y2ggPSBzZWxmLl9XSElURVNQQUNFLm1hdGNoKHNlbGYuX2N1cnJlbnRfbGluZSwgc2VsZi5fY29sdW1uKQorICAgICAgaWYgbm90IG1hdGNoOgorICAgICAgICBicmVhaworICAgICAgbGVuZ3RoID0gbGVuKG1hdGNoLmdyb3VwKDApKQorICAgICAgc2VsZi5fY29sdW1uICs9IGxlbmd0aAorCisgIGRlZiBUcnlDb25zdW1lKHNlbGYsIHRva2VuKToKKyAgICAiIiJUcmllcyB0byBjb25zdW1lIGEgZ2l2ZW4gcGllY2Ugb2YgdGV4dC4KKworICAgIEFyZ3M6CisgICAgICB0b2tlbjogVGV4dCB0byBjb25zdW1lLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRydWUgaWZmIHRoZSB0ZXh0IHdhcyBjb25zdW1lZC4KKyAgICAiIiIKKyAgICBpZiBzZWxmLnRva2VuID09IHRva2VuOgorICAgICAgc2VsZi5OZXh0VG9rZW4oKQorICAgICAgcmV0dXJuIFRydWUKKyAgICByZXR1cm4gRmFsc2UKKworICBkZWYgQ29uc3VtZShzZWxmLCB0b2tlbik6CisgICAgIiIiQ29uc3VtZXMgYSBwaWVjZSBvZiB0ZXh0LgorCisgICAgQXJnczoKKyAgICAgIHRva2VuOiBUZXh0IHRvIGNvbnN1bWUuCisKKyAgICBSYWlzZXM6CisgICAgICBQYXJzZUVycm9yOiBJZiB0aGUgdGV4dCBjb3VsZG4ndCBiZSBjb25zdW1lZC4KKyAgICAiIiIKKyAgICBpZiBub3Qgc2VsZi5UcnlDb25zdW1lKHRva2VuKToKKyAgICAgIHJhaXNlIHNlbGYuX1BhcnNlRXJyb3IoJ0V4cGVjdGVkICIlcyIuJyAlIHRva2VuKQorCisgIGRlZiBDb25zdW1lSWRlbnRpZmllcihzZWxmKToKKyAgICAiIiJDb25zdW1lcyBwcm90b2NvbCBtZXNzYWdlIGZpZWxkIGlkZW50aWZpZXIuCisKKyAgICBSZXR1cm5zOgorICAgICAgSWRlbnRpZmllciBzdHJpbmcuCisKKyAgICBSYWlzZXM6CisgICAgICBQYXJzZUVycm9yOiBJZiBhbiBpZGVudGlmaWVyIGNvdWxkbid0IGJlIGNvbnN1bWVkLgorICAgICIiIgorICAgIHJlc3VsdCA9IHNlbGYudG9rZW4KKyAgICBpZiBub3Qgc2VsZi5fSURFTlRJRklFUi5tYXRjaChyZXN1bHQpOgorICAgICAgcmFpc2Ugc2VsZi5fUGFyc2VFcnJvcignRXhwZWN0ZWQgaWRlbnRpZmllci4nKQorICAgIHNlbGYuTmV4dFRva2VuKCkKKyAgICByZXR1cm4gcmVzdWx0CisKKyAgZGVmIENvbnN1bWVJbnQzMihzZWxmKToKKyAgICAiIiJDb25zdW1lcyBhIHNpZ25lZCAzMmJpdCBpbnRlZ2VyIG51bWJlci4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgaW50ZWdlciBwYXJzZWQuCisKKyAgICBSYWlzZXM6CisgICAgICBQYXJzZUVycm9yOiBJZiBhIHNpZ25lZCAzMmJpdCBpbnRlZ2VyIGNvdWxkbid0IGJlIGNvbnN1bWVkLgorICAgICIiIgorICAgIHRyeToKKyAgICAgIHJlc3VsdCA9IFBhcnNlSW50ZWdlcihzZWxmLnRva2VuLCBpc19zaWduZWQ9VHJ1ZSwgaXNfbG9uZz1GYWxzZSkKKyAgICBleGNlcHQgVmFsdWVFcnJvciwgZToKKyAgICAgIHJhaXNlIHNlbGYuX1BhcnNlRXJyb3Ioc3RyKGUpKQorICAgIHNlbGYuTmV4dFRva2VuKCkKKyAgICByZXR1cm4gcmVzdWx0CisKKyAgZGVmIENvbnN1bWVVaW50MzIoc2VsZik6CisgICAgIiIiQ29uc3VtZXMgYW4gdW5zaWduZWQgMzJiaXQgaW50ZWdlciBudW1iZXIuCisKKyAgICBSZXR1cm5zOgorICAgICAgVGhlIGludGVnZXIgcGFyc2VkLgorCisgICAgUmFpc2VzOgorICAgICAgUGFyc2VFcnJvcjogSWYgYW4gdW5zaWduZWQgMzJiaXQgaW50ZWdlciBjb3VsZG4ndCBiZSBjb25zdW1lZC4KKyAgICAiIiIKKyAgICB0cnk6CisgICAgICByZXN1bHQgPSBQYXJzZUludGVnZXIoc2VsZi50b2tlbiwgaXNfc2lnbmVkPUZhbHNlLCBpc19sb25nPUZhbHNlKQorICAgIGV4Y2VwdCBWYWx1ZUVycm9yLCBlOgorICAgICAgcmFpc2Ugc2VsZi5fUGFyc2VFcnJvcihzdHIoZSkpCisgICAgc2VsZi5OZXh0VG9rZW4oKQorICAgIHJldHVybiByZXN1bHQKKworICBkZWYgQ29uc3VtZUludDY0KHNlbGYpOgorICAgICIiIkNvbnN1bWVzIGEgc2lnbmVkIDY0Yml0IGludGVnZXIgbnVtYmVyLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBpbnRlZ2VyIHBhcnNlZC4KKworICAgIFJhaXNlczoKKyAgICAgIFBhcnNlRXJyb3I6IElmIGEgc2lnbmVkIDY0Yml0IGludGVnZXIgY291bGRuJ3QgYmUgY29uc3VtZWQuCisgICAgIiIiCisgICAgdHJ5OgorICAgICAgcmVzdWx0ID0gUGFyc2VJbnRlZ2VyKHNlbGYudG9rZW4sIGlzX3NpZ25lZD1UcnVlLCBpc19sb25nPVRydWUpCisgICAgZXhjZXB0IFZhbHVlRXJyb3IsIGU6CisgICAgICByYWlzZSBzZWxmLl9QYXJzZUVycm9yKHN0cihlKSkKKyAgICBzZWxmLk5leHRUb2tlbigpCisgICAgcmV0dXJuIHJlc3VsdAorCisgIGRlZiBDb25zdW1lVWludDY0KHNlbGYpOgorICAgICIiIkNvbnN1bWVzIGFuIHVuc2lnbmVkIDY0Yml0IGludGVnZXIgbnVtYmVyLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBpbnRlZ2VyIHBhcnNlZC4KKworICAgIFJhaXNlczoKKyAgICAgIFBhcnNlRXJyb3I6IElmIGFuIHVuc2lnbmVkIDY0Yml0IGludGVnZXIgY291bGRuJ3QgYmUgY29uc3VtZWQuCisgICAgIiIiCisgICAgdHJ5OgorICAgICAgcmVzdWx0ID0gUGFyc2VJbnRlZ2VyKHNlbGYudG9rZW4sIGlzX3NpZ25lZD1GYWxzZSwgaXNfbG9uZz1UcnVlKQorICAgIGV4Y2VwdCBWYWx1ZUVycm9yLCBlOgorICAgICAgcmFpc2Ugc2VsZi5fUGFyc2VFcnJvcihzdHIoZSkpCisgICAgc2VsZi5OZXh0VG9rZW4oKQorICAgIHJldHVybiByZXN1bHQKKworICBkZWYgQ29uc3VtZUZsb2F0KHNlbGYpOgorICAgICIiIkNvbnN1bWVzIGFuIGZsb2F0aW5nIHBvaW50IG51bWJlci4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgbnVtYmVyIHBhcnNlZC4KKworICAgIFJhaXNlczoKKyAgICAgIFBhcnNlRXJyb3I6IElmIGEgZmxvYXRpbmcgcG9pbnQgbnVtYmVyIGNvdWxkbid0IGJlIGNvbnN1bWVkLgorICAgICIiIgorICAgIHRyeToKKyAgICAgIHJlc3VsdCA9IFBhcnNlRmxvYXQoc2VsZi50b2tlbikKKyAgICBleGNlcHQgVmFsdWVFcnJvciwgZToKKyAgICAgIHJhaXNlIHNlbGYuX1BhcnNlRXJyb3Ioc3RyKGUpKQorICAgIHNlbGYuTmV4dFRva2VuKCkKKyAgICByZXR1cm4gcmVzdWx0CisKKyAgZGVmIENvbnN1bWVCb29sKHNlbGYpOgorICAgICIiIkNvbnN1bWVzIGEgYm9vbGVhbiB2YWx1ZS4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgYm9vbCBwYXJzZWQuCisKKyAgICBSYWlzZXM6CisgICAgICBQYXJzZUVycm9yOiBJZiBhIGJvb2xlYW4gdmFsdWUgY291bGRuJ3QgYmUgY29uc3VtZWQuCisgICAgIiIiCisgICAgdHJ5OgorICAgICAgcmVzdWx0ID0gUGFyc2VCb29sKHNlbGYudG9rZW4pCisgICAgZXhjZXB0IFZhbHVlRXJyb3IsIGU6CisgICAgICByYWlzZSBzZWxmLl9QYXJzZUVycm9yKHN0cihlKSkKKyAgICBzZWxmLk5leHRUb2tlbigpCisgICAgcmV0dXJuIHJlc3VsdAorCisgIGRlZiBDb25zdW1lU3RyaW5nKHNlbGYpOgorICAgICIiIkNvbnN1bWVzIGEgc3RyaW5nIHZhbHVlLgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBzdHJpbmcgcGFyc2VkLgorCisgICAgUmFpc2VzOgorICAgICAgUGFyc2VFcnJvcjogSWYgYSBzdHJpbmcgdmFsdWUgY291bGRuJ3QgYmUgY29uc3VtZWQuCisgICAgIiIiCisgICAgdGhlX2J5dGVzID0gc2VsZi5Db25zdW1lQnl0ZVN0cmluZygpCisgICAgdHJ5OgorICAgICAgcmV0dXJuIHVuaWNvZGUodGhlX2J5dGVzLCAndXRmLTgnKQorICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3IsIGU6CisgICAgICByYWlzZSBzZWxmLl9TdHJpbmdQYXJzZUVycm9yKGUpCisKKyAgZGVmIENvbnN1bWVCeXRlU3RyaW5nKHNlbGYpOgorICAgICIiIkNvbnN1bWVzIGEgYnl0ZSBhcnJheSB2YWx1ZS4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgYXJyYXkgcGFyc2VkIChhcyBhIHN0cmluZykuCisKKyAgICBSYWlzZXM6CisgICAgICBQYXJzZUVycm9yOiBJZiBhIGJ5dGUgYXJyYXkgdmFsdWUgY291bGRuJ3QgYmUgY29uc3VtZWQuCisgICAgIiIiCisgICAgdGhlX2xpc3QgPSBbc2VsZi5fQ29uc3VtZVNpbmdsZUJ5dGVTdHJpbmcoKV0KKyAgICB3aGlsZSBzZWxmLnRva2VuIGFuZCBzZWxmLnRva2VuWzBdIGluICgnXCcnLCAnIicpOgorICAgICAgdGhlX2xpc3QuYXBwZW5kKHNlbGYuX0NvbnN1bWVTaW5nbGVCeXRlU3RyaW5nKCkpCisgICAgcmV0dXJuICcnLmVuY29kZSgnbGF0aW4xJykuam9pbih0aGVfbGlzdCkgICMjUFkyNQorIyMhUFkyNSAgICByZXR1cm4gYicnLmpvaW4odGhlX2xpc3QpCisKKyAgZGVmIF9Db25zdW1lU2luZ2xlQnl0ZVN0cmluZyhzZWxmKToKKyAgICAiIiJDb25zdW1lIG9uZSB0b2tlbiBvZiBhIHN0cmluZyBsaXRlcmFsLgorCisgICAgU3RyaW5nIGxpdGVyYWxzICh3aGV0aGVyIGJ5dGVzIG9yIHRleHQpIGNhbiBjb21lIGluIG11bHRpcGxlIGFkamFjZW50CisgICAgdG9rZW5zIHdoaWNoIGFyZSBhdXRvbWF0aWNhbGx5IGNvbmNhdGVuYXRlZCwgbGlrZSBpbiBDIG9yIFB5dGhvbi4gIFRoaXMKKyAgICBtZXRob2Qgb25seSBjb25zdW1lcyBvbmUgdG9rZW4uCisgICAgIiIiCisgICAgdGV4dCA9IHNlbGYudG9rZW4KKyAgICBpZiBsZW4odGV4dCkgPCAxIG9yIHRleHRbMF0gbm90IGluICgnXCcnLCAnIicpOgorICAgICAgcmFpc2Ugc2VsZi5fUGFyc2VFcnJvcignRXhwZWN0ZWQgc3RyaW5nIGJ1dCBmb3VuZDogIiVyIicgJSB0ZXh0KQorCisgICAgaWYgbGVuKHRleHQpIDwgMiBvciB0ZXh0Wy0xXSAhPSB0ZXh0WzBdOgorICAgICAgcmFpc2Ugc2VsZi5fUGFyc2VFcnJvcignU3RyaW5nIG1pc3NpbmcgZW5kaW5nIHF1b3RlLicpCisKKyAgICB0cnk6CisgICAgICByZXN1bHQgPSB0ZXh0X2VuY29kaW5nLkNVbmVzY2FwZSh0ZXh0WzE6LTFdKQorICAgIGV4Y2VwdCBWYWx1ZUVycm9yLCBlOgorICAgICAgcmFpc2Ugc2VsZi5fUGFyc2VFcnJvcihzdHIoZSkpCisgICAgc2VsZi5OZXh0VG9rZW4oKQorICAgIHJldHVybiByZXN1bHQKKworICBkZWYgQ29uc3VtZUVudW0oc2VsZiwgZmllbGQpOgorICAgIHRyeToKKyAgICAgIHJlc3VsdCA9IFBhcnNlRW51bShmaWVsZCwgc2VsZi50b2tlbikKKyAgICBleGNlcHQgVmFsdWVFcnJvciwgZToKKyAgICAgIHJhaXNlIHNlbGYuX1BhcnNlRXJyb3Ioc3RyKGUpKQorICAgIHNlbGYuTmV4dFRva2VuKCkKKyAgICByZXR1cm4gcmVzdWx0CisKKyAgZGVmIFBhcnNlRXJyb3JQcmV2aW91c1Rva2VuKHNlbGYsIG1lc3NhZ2UpOgorICAgICIiIkNyZWF0ZXMgYW5kICpyZXR1cm5zKiBhIFBhcnNlRXJyb3IgZm9yIHRoZSBwcmV2aW91c2x5IHJlYWQgdG9rZW4uCisKKyAgICBBcmdzOgorICAgICAgbWVzc2FnZTogQSBtZXNzYWdlIHRvIHNldCBmb3IgdGhlIGV4Y2VwdGlvbi4KKworICAgIFJldHVybnM6CisgICAgICBBIFBhcnNlRXJyb3IgaW5zdGFuY2UuCisgICAgIiIiCisgICAgcmV0dXJuIFBhcnNlRXJyb3IoJyVkOiVkIDogJXMnICUgKAorICAgICAgICBzZWxmLl9wcmV2aW91c19saW5lICsgMSwgc2VsZi5fcHJldmlvdXNfY29sdW1uICsgMSwgbWVzc2FnZSkpCisKKyAgZGVmIF9QYXJzZUVycm9yKHNlbGYsIG1lc3NhZ2UpOgorICAgICIiIkNyZWF0ZXMgYW5kICpyZXR1cm5zKiBhIFBhcnNlRXJyb3IgZm9yIHRoZSBjdXJyZW50IHRva2VuLiIiIgorICAgIHJldHVybiBQYXJzZUVycm9yKCclZDolZCA6ICVzJyAlICgKKyAgICAgICAgc2VsZi5fbGluZSArIDEsIHNlbGYuX2NvbHVtbiArIDEsIG1lc3NhZ2UpKQorCisgIGRlZiBfU3RyaW5nUGFyc2VFcnJvcihzZWxmLCBlKToKKyAgICByZXR1cm4gc2VsZi5fUGFyc2VFcnJvcignQ291bGRuXCd0IHBhcnNlIHN0cmluZzogJyArIHN0cihlKSkKKworICBkZWYgTmV4dFRva2VuKHNlbGYpOgorICAgICIiIlJlYWRzIHRoZSBuZXh0IG1lYW5pbmdmdWwgdG9rZW4uIiIiCisgICAgc2VsZi5fcHJldmlvdXNfbGluZSA9IHNlbGYuX2xpbmUKKyAgICBzZWxmLl9wcmV2aW91c19jb2x1bW4gPSBzZWxmLl9jb2x1bW4KKworICAgIHNlbGYuX2NvbHVtbiArPSBsZW4oc2VsZi50b2tlbikKKyAgICBzZWxmLl9Ta2lwV2hpdGVzcGFjZSgpCisKKyAgICBpZiBub3Qgc2VsZi5fbW9yZV9saW5lczoKKyAgICAgIHNlbGYudG9rZW4gPSAnJworICAgICAgcmV0dXJuCisKKyAgICBtYXRjaCA9IHNlbGYuX1RPS0VOLm1hdGNoKHNlbGYuX2N1cnJlbnRfbGluZSwgc2VsZi5fY29sdW1uKQorICAgIGlmIG1hdGNoOgorICAgICAgdG9rZW4gPSBtYXRjaC5ncm91cCgwKQorICAgICAgc2VsZi50b2tlbiA9IHRva2VuCisgICAgZWxzZToKKyAgICAgIHNlbGYudG9rZW4gPSBzZWxmLl9jdXJyZW50X2xpbmVbc2VsZi5fY29sdW1uXQorCisKK2RlZiBQYXJzZUludGVnZXIodGV4dCwgaXNfc2lnbmVkPUZhbHNlLCBpc19sb25nPUZhbHNlKToKKyAgIiIiUGFyc2VzIGFuIGludGVnZXIuCisKKyAgQXJnczoKKyAgICB0ZXh0OiBUaGUgdGV4dCB0byBwYXJzZS4KKyAgICBpc19zaWduZWQ6IFRydWUgaWYgYSBzaWduZWQgaW50ZWdlciBtdXN0IGJlIHBhcnNlZC4KKyAgICBpc19sb25nOiBUcnVlIGlmIGEgbG9uZyBpbnRlZ2VyIG11c3QgYmUgcGFyc2VkLgorCisgIFJldHVybnM6CisgICAgVGhlIGludGVnZXIgdmFsdWUuCisKKyAgUmFpc2VzOgorICAgIFZhbHVlRXJyb3I6IFRocm93biBJZmYgdGhlIHRleHQgaXMgbm90IGEgdmFsaWQgaW50ZWdlci4KKyAgIiIiCisgICMgRG8gdGhlIGFjdHVhbCBwYXJzaW5nLiBFeGNlcHRpb24gaGFuZGxpbmcgaXMgcHJvcGFnYXRlZCB0byBjYWxsZXIuCisgIHRyeToKKyAgICAjIFdlIGZvcmNlIDMyLWJpdCB2YWx1ZXMgdG8gaW50IGFuZCA2NC1iaXQgdmFsdWVzIHRvIGxvbmcgdG8gbWFrZQorICAgICMgYWx0ZXJuYXRlIGltcGxlbWVudGF0aW9ucyB3aGVyZSB0aGUgZGlzdGluY3Rpb24gaXMgbW9yZSBzaWduaWZpY2FudAorICAgICMgKGUuZy4gdGhlIEMrKyBpbXBsZW1lbnRhdGlvbikgc2ltcGxlci4KKyAgICBpZiBpc19sb25nOgorICAgICAgcmVzdWx0ID0gbG9uZyh0ZXh0LCAwKQorICAgIGVsc2U6CisgICAgICByZXN1bHQgPSBpbnQodGV4dCwgMCkKKyAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgcmFpc2UgVmFsdWVFcnJvcignQ291bGRuXCd0IHBhcnNlIGludGVnZXI6ICVzJyAlIHRleHQpCisKKyAgIyBDaGVjayBpZiB0aGUgaW50ZWdlciBpcyBzYW5lLiBFeGNlcHRpb25zIGhhbmRsZWQgYnkgY2FsbGVycy4KKyAgY2hlY2tlciA9IF9JTlRFR0VSX0NIRUNLRVJTWzIgKiBpbnQoaXNfbG9uZykgKyBpbnQoaXNfc2lnbmVkKV0KKyAgY2hlY2tlci5DaGVja1ZhbHVlKHJlc3VsdCkKKyAgcmV0dXJuIHJlc3VsdAorCisKK2RlZiBQYXJzZUZsb2F0KHRleHQpOgorICAiIiJQYXJzZSBhIGZsb2F0aW5nIHBvaW50IG51bWJlci4KKworICBBcmdzOgorICAgIHRleHQ6IFRleHQgdG8gcGFyc2UuCisKKyAgUmV0dXJuczoKKyAgICBUaGUgbnVtYmVyIHBhcnNlZC4KKworICBSYWlzZXM6CisgICAgVmFsdWVFcnJvcjogSWYgYSBmbG9hdGluZyBwb2ludCBudW1iZXIgY291bGRuJ3QgYmUgcGFyc2VkLgorICAiIiIKKyAgdHJ5OgorICAgICMgQXNzdW1lIFB5dGhvbiBjb21wYXRpYmxlIHN5bnRheC4KKyAgICByZXR1cm4gZmxvYXQodGV4dCkKKyAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgIyBDaGVjayBhbHRlcm5hdGl2ZSBzcGVsbGluZ3MuCisgICAgaWYgX0ZMT0FUX0lORklOSVRZLm1hdGNoKHRleHQpOgorICAgICAgaWYgdGV4dFswXSA9PSAnLSc6CisgICAgICAgIHJldHVybiBmbG9hdCgnLWluZicpCisgICAgICBlbHNlOgorICAgICAgICByZXR1cm4gZmxvYXQoJ2luZicpCisgICAgZWxpZiBfRkxPQVRfTkFOLm1hdGNoKHRleHQpOgorICAgICAgcmV0dXJuIGZsb2F0KCduYW4nKQorICAgIGVsc2U6CisgICAgICAjIGFzc3VtZSAnMS4wZicgZm9ybWF0CisgICAgICB0cnk6CisgICAgICAgIHJldHVybiBmbG9hdCh0ZXh0LnJzdHJpcCgnZicpKQorICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ0NvdWxkblwndCBwYXJzZSBmbG9hdDogJXMnICUgdGV4dCkKKworCitkZWYgUGFyc2VCb29sKHRleHQpOgorICAiIiJQYXJzZSBhIGJvb2xlYW4gdmFsdWUuCisKKyAgQXJnczoKKyAgICB0ZXh0OiBUZXh0IHRvIHBhcnNlLgorCisgIFJldHVybnM6CisgICAgQm9vbGVhbiB2YWx1ZXMgcGFyc2VkCisKKyAgUmFpc2VzOgorICAgIFZhbHVlRXJyb3I6IElmIHRleHQgaXMgbm90IGEgdmFsaWQgYm9vbGVhbi4KKyAgIiIiCisgIGlmIHRleHQgaW4gKCd0cnVlJywgJ3QnLCAnMScpOgorICAgIHJldHVybiBUcnVlCisgIGVsaWYgdGV4dCBpbiAoJ2ZhbHNlJywgJ2YnLCAnMCcpOgorICAgIHJldHVybiBGYWxzZQorICBlbHNlOgorICAgIHJhaXNlIFZhbHVlRXJyb3IoJ0V4cGVjdGVkICJ0cnVlIiBvciAiZmFsc2UiLicpCisKKworZGVmIFBhcnNlRW51bShmaWVsZCwgdmFsdWUpOgorICAiIiJQYXJzZSBhbiBlbnVtIHZhbHVlLgorCisgIFRoZSB2YWx1ZSBjYW4gYmUgc3BlY2lmaWVkIGJ5IGEgbnVtYmVyICh0aGUgZW51bSB2YWx1ZSksIG9yIGJ5CisgIGEgc3RyaW5nIGxpdGVyYWwgKHRoZSBlbnVtIG5hbWUpLgorCisgIEFyZ3M6CisgICAgZmllbGQ6IEVudW0gZmllbGQgZGVzY3JpcHRvci4KKyAgICB2YWx1ZTogU3RyaW5nIHZhbHVlLgorCisgIFJldHVybnM6CisgICAgRW51bSB2YWx1ZSBudW1iZXIuCisKKyAgUmFpc2VzOgorICAgIFZhbHVlRXJyb3I6IElmIHRoZSBlbnVtIHZhbHVlIGNvdWxkIG5vdCBiZSBwYXJzZWQuCisgICIiIgorICBlbnVtX2Rlc2NyaXB0b3IgPSBmaWVsZC5lbnVtX3R5cGUKKyAgdHJ5OgorICAgIG51bWJlciA9IGludCh2YWx1ZSwgMCkKKyAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgIyBJZGVudGlmaWVyLgorICAgIGVudW1fdmFsdWUgPSBlbnVtX2Rlc2NyaXB0b3IudmFsdWVzX2J5X25hbWUuZ2V0KHZhbHVlLCBOb25lKQorICAgIGlmIGVudW1fdmFsdWUgaXMgTm9uZToKKyAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCisgICAgICAgICAgJ0VudW0gdHlwZSAiJXMiIGhhcyBubyB2YWx1ZSBuYW1lZCAlcy4nICUgKAorICAgICAgICAgICAgICBlbnVtX2Rlc2NyaXB0b3IuZnVsbF9uYW1lLCB2YWx1ZSkpCisgIGVsc2U6CisgICAgIyBOdW1lcmljIHZhbHVlLgorICAgIGVudW1fdmFsdWUgPSBlbnVtX2Rlc2NyaXB0b3IudmFsdWVzX2J5X251bWJlci5nZXQobnVtYmVyLCBOb25lKQorICAgIGlmIGVudW1fdmFsdWUgaXMgTm9uZToKKyAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCisgICAgICAgICAgJ0VudW0gdHlwZSAiJXMiIGhhcyBubyB2YWx1ZSB3aXRoIG51bWJlciAlZC4nICUgKAorICAgICAgICAgICAgICBlbnVtX2Rlc2NyaXB0b3IuZnVsbF9uYW1lLCBudW1iZXIpKQorICByZXR1cm4gZW51bV92YWx1ZS5udW1iZXIKZGlmZiAtLWdpdCBhL3B5dGhvbi9tb3gucHkgYi9weXRob24vbW94LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjI1NzQ2OGUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vbW94LnB5CkBAIC0wLDAgKzEsMTQwMSBAQAorIyEvdXNyL2Jpbi9weXRob24yLjQKKyMKKyMgQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4KKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKyMgVGhpcyBmaWxlIGlzIHVzZWQgZm9yIHRlc3RpbmcuICBUaGUgb3JpZ2luYWwgaXMgYXQ6CisjICAgaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3B5bW94LworCisiIiJNb3gsIGFuIG9iamVjdC1tb2NraW5nIGZyYW1ld29yayBmb3IgUHl0aG9uLgorCitNb3ggd29ya3MgaW4gdGhlIHJlY29yZC1yZXBsYXktdmVyaWZ5IHBhcmFkaWdtLiAgV2hlbiB5b3UgZmlyc3QgY3JlYXRlCithIG1vY2sgb2JqZWN0LCBpdCBpcyBpbiByZWNvcmQgbW9kZS4gIFlvdSB0aGVuIHByb2dyYW1tYXRpY2FsbHkgc2V0Cit0aGUgZXhwZWN0ZWQgYmVoYXZpb3Igb2YgdGhlIG1vY2sgb2JqZWN0ICh3aGF0IG1ldGhvZHMgYXJlIHRvIGJlCitjYWxsZWQgb24gaXQsIHdpdGggd2hhdCBwYXJhbWV0ZXJzLCB3aGF0IHRoZXkgc2hvdWxkIHJldHVybiwgYW5kIGluCit3aGF0IG9yZGVyKS4KKworT25jZSB5b3UgaGF2ZSBzZXQgdXAgdGhlIGV4cGVjdGVkIG1vY2sgYmVoYXZpb3IsIHlvdSBwdXQgaXQgaW4gcmVwbGF5Cittb2RlLiAgTm93IHRoZSBtb2NrIHJlc3BvbmRzIHRvIG1ldGhvZCBjYWxscyBqdXN0IGFzIHlvdSB0b2xkIGl0IHRvLgorSWYgYW4gdW5leHBlY3RlZCBtZXRob2QgKG9yIGFuIGV4cGVjdGVkIG1ldGhvZCB3aXRoIHVuZXhwZWN0ZWQKK3BhcmFtZXRlcnMpIGlzIGNhbGxlZCwgdGhlbiBhbiBleGNlcHRpb24gd2lsbCBiZSByYWlzZWQuCisKK09uY2UgeW91IGFyZSBkb25lIGludGVyYWN0aW5nIHdpdGggdGhlIG1vY2ssIHlvdSBuZWVkIHRvIHZlcmlmeSB0aGF0CithbGwgdGhlIGV4cGVjdGVkIGludGVyYWN0aW9ucyBvY2N1cnJlZC4gIChNYXliZSB5b3VyIGNvZGUgZXhpdGVkCitwcmVtYXR1cmVseSB3aXRob3V0IGNhbGxpbmcgc29tZSBjbGVhbnVwIG1ldGhvZCEpICBUaGUgdmVyaWZ5IHBoYXNlCitlbnN1cmVzIHRoYXQgZXZlcnkgZXhwZWN0ZWQgbWV0aG9kIHdhcyBjYWxsZWQ7IG90aGVyd2lzZSwgYW4gZXhjZXB0aW9uCit3aWxsIGJlIHJhaXNlZC4KKworU3VnZ2VzdGVkIHVzYWdlIC8gd29ya2Zsb3c6CisKKyAgIyBDcmVhdGUgTW94IGZhY3RvcnkKKyAgbXlfbW94ID0gTW94KCkKKworICAjIENyZWF0ZSBhIG1vY2sgZGF0YSBhY2Nlc3Mgb2JqZWN0CisgIG1vY2tfZGFvID0gbXlfbW94LkNyZWF0ZU1vY2soREFPQ2xhc3MpCisKKyAgIyBTZXQgdXAgZXhwZWN0ZWQgYmVoYXZpb3IKKyAgbW9ja19kYW8uUmV0cmlldmVQZXJzb25XaXRoSWRlbnRpZmllcignMScpLkFuZFJldHVybihwZXJzb24pCisgIG1vY2tfZGFvLkRlbGV0ZVBlcnNvbihwZXJzb24pCisKKyAgIyBQdXQgbW9ja3MgaW4gcmVwbGF5IG1vZGUKKyAgbXlfbW94LlJlcGxheUFsbCgpCisKKyAgIyBJbmplY3QgbW9jayBvYmplY3QgYW5kIHJ1biB0ZXN0CisgIGNvbnRyb2xsZXIuU2V0RGFvKG1vY2tfZGFvKQorICBjb250cm9sbGVyLkRlbGV0ZVBlcnNvbkJ5SWQoJzEnKQorCisgICMgVmVyaWZ5IGFsbCBtZXRob2RzIHdlcmUgY2FsbGVkIGFzIGV4cGVjdGVkCisgIG15X21veC5WZXJpZnlBbGwoKQorIiIiCisKK2Zyb20gY29sbGVjdGlvbnMgaW1wb3J0IGRlcXVlCitpbXBvcnQgcmUKK2ltcG9ydCB0eXBlcworaW1wb3J0IHVuaXR0ZXN0CisKK2ltcG9ydCBzdHVib3V0CisKK2NsYXNzIEVycm9yKEFzc2VydGlvbkVycm9yKToKKyAgIiIiQmFzZSBleGNlcHRpb24gZm9yIHRoaXMgbW9kdWxlLiIiIgorCisgIHBhc3MKKworCitjbGFzcyBFeHBlY3RlZE1ldGhvZENhbGxzRXJyb3IoRXJyb3IpOgorICAiIiJSYWlzZWQgd2hlbiBWZXJpZnkoKSBpcyBjYWxsZWQgYmVmb3JlIGFsbCBleHBlY3RlZCBtZXRob2RzIGhhdmUgYmVlbiBjYWxsZWQKKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGV4cGVjdGVkX21ldGhvZHMpOgorICAgICIiIkluaXQgZXhjZXB0aW9uLgorCisgICAgQXJnczoKKyAgICAgICMgZXhwZWN0ZWRfbWV0aG9kczogQSBzZXF1ZW5jZSBvZiBNb2NrTWV0aG9kIG9iamVjdHMgdGhhdCBzaG91bGQgaGF2ZSBiZWVuCisgICAgICAjICAgY2FsbGVkLgorICAgICAgZXhwZWN0ZWRfbWV0aG9kczogW01vY2tNZXRob2RdCisKKyAgICBSYWlzZXM6CisgICAgICBWYWx1ZUVycm9yOiBpZiBleHBlY3RlZF9tZXRob2RzIGNvbnRhaW5zIG5vIG1ldGhvZHMuCisgICAgIiIiCisKKyAgICBpZiBub3QgZXhwZWN0ZWRfbWV0aG9kczoKKyAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIlRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIGV4cGVjdGVkIG1ldGhvZCIpCisgICAgRXJyb3IuX19pbml0X18oc2VsZikKKyAgICBzZWxmLl9leHBlY3RlZF9tZXRob2RzID0gZXhwZWN0ZWRfbWV0aG9kcworCisgIGRlZiBfX3N0cl9fKHNlbGYpOgorICAgIGNhbGxzID0gIlxuIi5qb2luKFsiJTNkLiAgJXMiICUgKGksIG0pCisgICAgICAgICAgICAgICAgICAgICAgIGZvciBpLCBtIGluIGVudW1lcmF0ZShzZWxmLl9leHBlY3RlZF9tZXRob2RzKV0pCisgICAgcmV0dXJuICJWZXJpZnk6IEV4cGVjdGVkIG1ldGhvZHMgbmV2ZXIgY2FsbGVkOlxuJXMiICUgKGNhbGxzLCkKKworCitjbGFzcyBVbmV4cGVjdGVkTWV0aG9kQ2FsbEVycm9yKEVycm9yKToKKyAgIiIiUmFpc2VkIHdoZW4gYW4gdW5leHBlY3RlZCBtZXRob2QgaXMgY2FsbGVkLgorCisgIFRoaXMgY2FuIG9jY3VyIGlmIGEgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGluY29ycmVjdCBwYXJhbWV0ZXJzLCBvciBvdXQgb2YgdGhlCisgIHNwZWNpZmllZCBvcmRlci4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIHVuZXhwZWN0ZWRfbWV0aG9kLCBleHBlY3RlZCk6CisgICAgIiIiSW5pdCBleGNlcHRpb24uCisKKyAgICBBcmdzOgorICAgICAgIyB1bmV4cGVjdGVkX21ldGhvZDogTW9ja01ldGhvZCB0aGF0IHdhcyBjYWxsZWQgYnV0IHdhcyBub3QgYXQgdGhlIGhlYWQgb2YKKyAgICAgICMgICB0aGUgZXhwZWN0ZWRfbWV0aG9kIHF1ZXVlLgorICAgICAgIyBleHBlY3RlZDogTW9ja01ldGhvZCBvciBVbm9yZGVyZWRHcm91cCB0aGUgbWV0aG9kIHNob3VsZCBoYXZlCisgICAgICAjICAgYmVlbiBpbi4KKyAgICAgIHVuZXhwZWN0ZWRfbWV0aG9kOiBNb2NrTWV0aG9kCisgICAgICBleHBlY3RlZDogTW9ja01ldGhvZCBvciBVbm9yZGVyZWRHcm91cAorICAgICIiIgorCisgICAgRXJyb3IuX19pbml0X18oc2VsZikKKyAgICBzZWxmLl91bmV4cGVjdGVkX21ldGhvZCA9IHVuZXhwZWN0ZWRfbWV0aG9kCisgICAgc2VsZi5fZXhwZWN0ZWQgPSBleHBlY3RlZAorCisgIGRlZiBfX3N0cl9fKHNlbGYpOgorICAgIHJldHVybiAiVW5leHBlY3RlZCBtZXRob2QgY2FsbDogJXMuICBFeHBlY3Rpbmc6ICVzIiAlIFwKKyAgICAgIChzZWxmLl91bmV4cGVjdGVkX21ldGhvZCwgc2VsZi5fZXhwZWN0ZWQpCisKKworY2xhc3MgVW5rbm93bk1ldGhvZENhbGxFcnJvcihFcnJvcik6CisgICIiIlJhaXNlZCBpZiBhbiB1bmtub3duIG1ldGhvZCBpcyByZXF1ZXN0ZWQgb2YgdGhlIG1vY2sgb2JqZWN0LiIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCB1bmtub3duX21ldGhvZF9uYW1lKToKKyAgICAiIiJJbml0IGV4Y2VwdGlvbi4KKworICAgIEFyZ3M6CisgICAgICAjIHVua25vd25fbWV0aG9kX25hbWU6IE1ldGhvZCBjYWxsIHRoYXQgaXMgbm90IHBhcnQgb2YgdGhlIG1vY2tlZCBjbGFzcydzCisgICAgICAjICAgcHVibGljIGludGVyZmFjZS4KKyAgICAgIHVua25vd25fbWV0aG9kX25hbWU6IHN0cgorICAgICIiIgorCisgICAgRXJyb3IuX19pbml0X18oc2VsZikKKyAgICBzZWxmLl91bmtub3duX21ldGhvZF9uYW1lID0gdW5rbm93bl9tZXRob2RfbmFtZQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOgorICAgIHJldHVybiAiTWV0aG9kIGNhbGxlZCBpcyBub3QgYSBtZW1iZXIgb2YgdGhlIG9iamVjdDogJXMiICUgXAorICAgICAgc2VsZi5fdW5rbm93bl9tZXRob2RfbmFtZQorCisKK2NsYXNzIE1veChvYmplY3QpOgorICAiIiJNb3g6IGEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgbW9jayBvYmplY3RzLiIiIgorCisgICMgQSBsaXN0IG9mIHR5cGVzIHRoYXQgc2hvdWxkIGJlIHN0dWJiZWQgb3V0IHdpdGggTW9ja09iamVjdHMgKGFzCisgICMgb3Bwb3NlZCB0byBNb2NrQW55dGhpbmdzKS4KKyAgX1VTRV9NT0NLX09CSkVDVCA9IFt0eXBlcy5DbGFzc1R5cGUsIHR5cGVzLkluc3RhbmNlVHlwZSwgdHlwZXMuTW9kdWxlVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5PYmplY3RUeXBlLCB0eXBlcy5UeXBlVHlwZV0KKworICBkZWYgX19pbml0X18oc2VsZik6CisgICAgIiIiSW5pdGlhbGl6ZSBhIG5ldyBNb3guIiIiCisKKyAgICBzZWxmLl9tb2NrX29iamVjdHMgPSBbXQorICAgIHNlbGYuc3R1YnMgPSBzdHVib3V0LlN0dWJPdXRGb3JUZXN0aW5nKCkKKworICBkZWYgQ3JlYXRlTW9jayhzZWxmLCBjbGFzc190b19tb2NrKToKKyAgICAiIiJDcmVhdGUgYSBuZXcgbW9jayBvYmplY3QuCisKKyAgICBBcmdzOgorICAgICAgIyBjbGFzc190b19tb2NrOiB0aGUgY2xhc3MgdG8gYmUgbW9ja2VkCisgICAgICBjbGFzc190b19tb2NrOiBjbGFzcworCisgICAgUmV0dXJuczoKKyAgICAgIE1vY2tPYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBhcyB0aGUgY2xhc3NfdG9fbW9jayB3b3VsZCBiZS4KKyAgICAiIiIKKworICAgIG5ld19tb2NrID0gTW9ja09iamVjdChjbGFzc190b19tb2NrKQorICAgIHNlbGYuX21vY2tfb2JqZWN0cy5hcHBlbmQobmV3X21vY2spCisgICAgcmV0dXJuIG5ld19tb2NrCisKKyAgZGVmIENyZWF0ZU1vY2tBbnl0aGluZyhzZWxmKToKKyAgICAiIiJDcmVhdGUgYSBtb2NrIHRoYXQgd2lsbCBhY2NlcHQgYW55IG1ldGhvZCBjYWxscy4KKworICAgIFRoaXMgZG9lcyBub3QgZW5mb3JjZSBhbiBpbnRlcmZhY2UuCisgICAgIiIiCisKKyAgICBuZXdfbW9jayA9IE1vY2tBbnl0aGluZygpCisgICAgc2VsZi5fbW9ja19vYmplY3RzLmFwcGVuZChuZXdfbW9jaykKKyAgICByZXR1cm4gbmV3X21vY2sKKworICBkZWYgUmVwbGF5QWxsKHNlbGYpOgorICAgICIiIlNldCBhbGwgbW9jayBvYmplY3RzIHRvIHJlcGxheSBtb2RlLiIiIgorCisgICAgZm9yIG1vY2tfb2JqIGluIHNlbGYuX21vY2tfb2JqZWN0czoKKyAgICAgIG1vY2tfb2JqLl9SZXBsYXkoKQorCisKKyAgZGVmIFZlcmlmeUFsbChzZWxmKToKKyAgICAiIiJDYWxsIHZlcmlmeSBvbiBhbGwgbW9jayBvYmplY3RzIGNyZWF0ZWQuIiIiCisKKyAgICBmb3IgbW9ja19vYmogaW4gc2VsZi5fbW9ja19vYmplY3RzOgorICAgICAgbW9ja19vYmouX1ZlcmlmeSgpCisKKyAgZGVmIFJlc2V0QWxsKHNlbGYpOgorICAgICIiIkNhbGwgcmVzZXQgb24gYWxsIG1vY2sgb2JqZWN0cy4gIFRoaXMgZG9lcyBub3QgdW5zZXQgc3R1YnMuIiIiCisKKyAgICBmb3IgbW9ja19vYmogaW4gc2VsZi5fbW9ja19vYmplY3RzOgorICAgICAgbW9ja19vYmouX1Jlc2V0KCkKKworICBkZWYgU3R1Yk91dFdpdGhNb2NrKHNlbGYsIG9iaiwgYXR0cl9uYW1lLCB1c2VfbW9ja19hbnl0aGluZz1GYWxzZSk6CisgICAgIiIiUmVwbGFjZSBhIG1ldGhvZCwgYXR0cmlidXRlLCBldGMuIHdpdGggYSBNb2NrLgorCisgICAgVGhpcyB3aWxsIHJlcGxhY2UgYSBjbGFzcyBvciBtb2R1bGUgd2l0aCBhIE1vY2tPYmplY3QsIGFuZCBldmVyeXRoaW5nIGVsc2UKKyAgICAobWV0aG9kLCBmdW5jdGlvbiwgZXRjKSB3aXRoIGEgTW9ja0FueXRoaW5nLiAgVGhpcyBjYW4gYmUgb3ZlcnJpZGRlbiB0bworICAgIGFsd2F5cyB1c2UgYSBNb2NrQW55dGhpbmcgYnkgc2V0dGluZyB1c2VfbW9ja19hbnl0aGluZyB0byBUcnVlLgorCisgICAgQXJnczoKKyAgICAgIG9iajogQSBQeXRob24gb2JqZWN0IChjbGFzcywgbW9kdWxlLCBpbnN0YW5jZSwgY2FsbGFibGUpLgorICAgICAgYXR0cl9uYW1lOiBzdHIuICBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHJlcGxhY2Ugd2l0aCBhIG1vY2suCisgICAgICB1c2VfbW9ja19hbnl0aGluZzogYm9vbC4gVHJ1ZSBpZiBhIE1vY2tBbnl0aGluZyBzaG91bGQgYmUgdXNlZCByZWdhcmRsZXNzCisgICAgICAgIG9mIHRoZSB0eXBlIG9mIGF0dHJpYnV0ZS4KKyAgICAiIiIKKworICAgIGF0dHJfdG9fcmVwbGFjZSA9IGdldGF0dHIob2JqLCBhdHRyX25hbWUpCisgICAgaWYgdHlwZShhdHRyX3RvX3JlcGxhY2UpIGluIHNlbGYuX1VTRV9NT0NLX09CSkVDVCBhbmQgbm90IHVzZV9tb2NrX2FueXRoaW5nOgorICAgICAgc3R1YiA9IHNlbGYuQ3JlYXRlTW9jayhhdHRyX3RvX3JlcGxhY2UpCisgICAgZWxzZToKKyAgICAgIHN0dWIgPSBzZWxmLkNyZWF0ZU1vY2tBbnl0aGluZygpCisKKyAgICBzZWxmLnN0dWJzLlNldChvYmosIGF0dHJfbmFtZSwgc3R1YikKKworICBkZWYgVW5zZXRTdHVicyhzZWxmKToKKyAgICAiIiJSZXN0b3JlIHN0dWJzIHRvIHRoZWlyIG9yaWdpbmFsIHN0YXRlLiIiIgorCisgICAgc2VsZi5zdHVicy5VbnNldEFsbCgpCisKK2RlZiBSZXBsYXkoKmFyZ3MpOgorICAiIiJQdXQgbW9ja3MgaW50byBSZXBsYXkgbW9kZS4KKworICBBcmdzOgorICAgICMgYXJncyBpcyBhbnkgbnVtYmVyIG9mIG1vY2tzIHRvIHB1dCBpbnRvIHJlcGxheSBtb2RlLgorICAiIiIKKworICBmb3IgbW9jayBpbiBhcmdzOgorICAgIG1vY2suX1JlcGxheSgpCisKKworZGVmIFZlcmlmeSgqYXJncyk6CisgICIiIlZlcmlmeSBtb2Nrcy4KKworICBBcmdzOgorICAgICMgYXJncyBpcyBhbnkgbnVtYmVyIG9mIG1vY2tzIHRvIGJlIHZlcmlmaWVkLgorICAiIiIKKworICBmb3IgbW9jayBpbiBhcmdzOgorICAgIG1vY2suX1ZlcmlmeSgpCisKKworZGVmIFJlc2V0KCphcmdzKToKKyAgIiIiUmVzZXQgbW9ja3MuCisKKyAgQXJnczoKKyAgICAjIGFyZ3MgaXMgYW55IG51bWJlciBvZiBtb2NrcyB0byBiZSByZXNldC4KKyAgIiIiCisKKyAgZm9yIG1vY2sgaW4gYXJnczoKKyAgICBtb2NrLl9SZXNldCgpCisKKworY2xhc3MgTW9ja0FueXRoaW5nOgorICAiIiJBIG1vY2sgdGhhdCBjYW4gYmUgdXNlZCB0byBtb2NrIGFueXRoaW5nLgorCisgIFRoaXMgaXMgaGVscGZ1bCBmb3IgbW9ja2luZyBjbGFzc2VzIHRoYXQgZG8gbm90IHByb3ZpZGUgYSBwdWJsaWMgaW50ZXJmYWNlLgorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZik6CisgICAgIiIiICIiIgorICAgIHNlbGYuX1Jlc2V0KCkKKworICBkZWYgX19nZXRhdHRyX18oc2VsZiwgbWV0aG9kX25hbWUpOgorICAgICIiIkludGVyY2VwdCBtZXRob2QgY2FsbHMgb24gdGhpcyBvYmplY3QuCisKKyAgICAgQSBuZXcgTW9ja01ldGhvZCBpcyByZXR1cm5lZCB0aGF0IGlzIGF3YXJlIG9mIHRoZSBNb2NrQW55dGhpbmcncworICAgICBzdGF0ZSAocmVjb3JkIG9yIHJlcGxheSkuICBUaGUgY2FsbCB3aWxsIGJlIHJlY29yZGVkIG9yIHJlcGxheWVkCisgICAgIGJ5IHRoZSBNb2NrTWV0aG9kJ3MgX19jYWxsX18uCisKKyAgICBBcmdzOgorICAgICAgIyBtZXRob2QgbmFtZTogdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCBiZWluZyBjYWxsZWQuCisgICAgICBtZXRob2RfbmFtZTogc3RyCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBuZXcgTW9ja01ldGhvZCBhd2FyZSBvZiBNb2NrQW55dGhpbmcncyBzdGF0ZSAocmVjb3JkIG9yIHJlcGxheSkuCisgICAgIiIiCisKKyAgICByZXR1cm4gc2VsZi5fQ3JlYXRlTW9ja01ldGhvZChtZXRob2RfbmFtZSkKKworICBkZWYgX0NyZWF0ZU1vY2tNZXRob2Qoc2VsZiwgbWV0aG9kX25hbWUpOgorICAgICIiIkNyZWF0ZSBhIG5ldyBtb2NrIG1ldGhvZCBjYWxsIGFuZCByZXR1cm4gaXQuCisKKyAgICBBcmdzOgorICAgICAgIyBtZXRob2QgbmFtZTogdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCBiZWluZyBjYWxsZWQuCisgICAgICBtZXRob2RfbmFtZTogc3RyCisKKyAgICBSZXR1cm5zOgorICAgICAgQSBuZXcgTW9ja01ldGhvZCBhd2FyZSBvZiBNb2NrQW55dGhpbmcncyBzdGF0ZSAocmVjb3JkIG9yIHJlcGxheSkuCisgICAgIiIiCisKKyAgICByZXR1cm4gTW9ja01ldGhvZChtZXRob2RfbmFtZSwgc2VsZi5fZXhwZWN0ZWRfY2FsbHNfcXVldWUsCisgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwbGF5X21vZGUpCisKKyAgZGVmIF9fbm9uemVyb19fKHNlbGYpOgorICAgICIiIlJldHVybiAxIGZvciBub256ZXJvIHNvIHRoZSBtb2NrIGNhbiBiZSB1c2VkIGFzIGEgY29uZGl0aW9uYWwuIiIiCisKKyAgICByZXR1cm4gMQorCisgIGRlZiBfX2VxX18oc2VsZiwgcmhzKToKKyAgICAiIiJQcm92aWRlIGN1c3RvbSBsb2dpYyB0byBjb21wYXJlIG9iamVjdHMuIiIiCisKKyAgICByZXR1cm4gKGlzaW5zdGFuY2UocmhzLCBNb2NrQW55dGhpbmcpIGFuZAorICAgICAgICAgICAgc2VsZi5fcmVwbGF5X21vZGUgPT0gcmhzLl9yZXBsYXlfbW9kZSBhbmQKKyAgICAgICAgICAgIHNlbGYuX2V4cGVjdGVkX2NhbGxzX3F1ZXVlID09IHJocy5fZXhwZWN0ZWRfY2FsbHNfcXVldWUpCisKKyAgZGVmIF9fbmVfXyhzZWxmLCByaHMpOgorICAgICIiIlByb3ZpZGUgY3VzdG9tIGxvZ2ljIHRvIGNvbXBhcmUgb2JqZWN0cy4iIiIKKworICAgIHJldHVybiBub3Qgc2VsZiA9PSByaHMKKworICBkZWYgX1JlcGxheShzZWxmKToKKyAgICAiIiJTdGFydCByZXBsYXlpbmcgZXhwZWN0ZWQgbWV0aG9kIGNhbGxzLiIiIgorCisgICAgc2VsZi5fcmVwbGF5X21vZGUgPSBUcnVlCisKKyAgZGVmIF9WZXJpZnkoc2VsZik6CisgICAgIiIiVmVyaWZ5IHRoYXQgYWxsIG9mIHRoZSBleHBlY3RlZCBjYWxscyBoYXZlIGJlZW4gbWFkZS4KKworICAgIFJhaXNlczoKKyAgICAgIEV4cGVjdGVkTWV0aG9kQ2FsbHNFcnJvcjogaWYgdGhlcmUgYXJlIHN0aWxsIG1vcmUgbWV0aG9kIGNhbGxzIGluIHRoZQorICAgICAgICBleHBlY3RlZCBxdWV1ZS4KKyAgICAiIiIKKworICAgICMgSWYgdGhlIGxpc3Qgb2YgZXhwZWN0ZWQgY2FsbHMgaXMgbm90IGVtcHR5LCByYWlzZSBhbiBleGNlcHRpb24KKyAgICBpZiBzZWxmLl9leHBlY3RlZF9jYWxsc19xdWV1ZToKKyAgICAgICMgVGhlIGxhc3QgTXVsdGlwbGVUaW1lc0dyb3VwIGlzIG5vdCBwb3BwZWQgZnJvbSB0aGUgcXVldWUuCisgICAgICBpZiAobGVuKHNlbGYuX2V4cGVjdGVkX2NhbGxzX3F1ZXVlKSA9PSAxIGFuZAorICAgICAgICAgIGlzaW5zdGFuY2Uoc2VsZi5fZXhwZWN0ZWRfY2FsbHNfcXVldWVbMF0sIE11bHRpcGxlVGltZXNHcm91cCkgYW5kCisgICAgICAgICAgc2VsZi5fZXhwZWN0ZWRfY2FsbHNfcXVldWVbMF0uSXNTYXRpc2ZpZWQoKSk6CisgICAgICAgIHBhc3MKKyAgICAgIGVsc2U6CisgICAgICAgIHJhaXNlIEV4cGVjdGVkTWV0aG9kQ2FsbHNFcnJvcihzZWxmLl9leHBlY3RlZF9jYWxsc19xdWV1ZSkKKworICBkZWYgX1Jlc2V0KHNlbGYpOgorICAgICIiIlJlc2V0IHRoZSBzdGF0ZSBvZiB0aGlzIG1vY2sgdG8gcmVjb3JkIG1vZGUgd2l0aCBhbiBlbXB0eSBxdWV1ZS4iIiIKKworICAgICMgTWFpbnRhaW4gYSBsaXN0IG9mIG1ldGhvZCBjYWxscyB3ZSBhcmUgZXhwZWN0aW5nCisgICAgc2VsZi5fZXhwZWN0ZWRfY2FsbHNfcXVldWUgPSBkZXF1ZSgpCisKKyAgICAjIE1ha2Ugc3VyZSB3ZSBhcmUgaW4gc2V0dXAgbW9kZSwgbm90IHJlcGxheSBtb2RlCisgICAgc2VsZi5fcmVwbGF5X21vZGUgPSBGYWxzZQorCisKK2NsYXNzIE1vY2tPYmplY3QoTW9ja0FueXRoaW5nLCBvYmplY3QpOgorICAiIiJBIG1vY2sgb2JqZWN0IHRoYXQgc2ltdWxhdGVzIHRoZSBwdWJsaWMvcHJvdGVjdGVkIGludGVyZmFjZSBvZiBhIGNsYXNzLiIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBjbGFzc190b19tb2NrKToKKyAgICAiIiJJbml0aWFsaXplIGEgbW9jayBvYmplY3QuCisKKyAgICBUaGlzIGRldGVybWluZXMgdGhlIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMgb2YgdGhlIGNsYXNzIGFuZCBzdG9yZXMgdGhlbS4KKworICAgIEFyZ3M6CisgICAgICAjIGNsYXNzX3RvX21vY2s6IGNsYXNzIHRvIGJlIG1vY2tlZAorICAgICAgY2xhc3NfdG9fbW9jazogY2xhc3MKKyAgICAiIiIKKworICAgICMgVGhpcyBpcyB1c2VkIHRvIGhhY2sgYXJvdW5kIHRoZSBtaXhpbi9pbmhlcml0YW5jZSBvZiBNb2NrQW55dGhpbmcsIHdoaWNoCisgICAgIyBpcyBub3QgYSBwcm9wZXIgb2JqZWN0IChpdCBjYW4gYmUgYW55dGhpbmcuIDotKQorICAgIE1vY2tBbnl0aGluZy5fX2RpY3RfX1snX19pbml0X18nXShzZWxmKQorCisgICAgIyBHZXQgYSBsaXN0IG9mIGFsbCB0aGUgcHVibGljIGFuZCBzcGVjaWFsIG1ldGhvZHMgd2Ugc2hvdWxkIG1vY2suCisgICAgc2VsZi5fa25vd25fbWV0aG9kcyA9IHNldCgpCisgICAgc2VsZi5fa25vd25fdmFycyA9IHNldCgpCisgICAgc2VsZi5fY2xhc3NfdG9fbW9jayA9IGNsYXNzX3RvX21vY2sKKyAgICBmb3IgbWV0aG9kIGluIGRpcihjbGFzc190b19tb2NrKToKKyAgICAgIGlmIGNhbGxhYmxlKGdldGF0dHIoY2xhc3NfdG9fbW9jaywgbWV0aG9kKSk6CisgICAgICAgIHNlbGYuX2tub3duX21ldGhvZHMuYWRkKG1ldGhvZCkKKyAgICAgIGVsc2U6CisgICAgICAgIHNlbGYuX2tub3duX3ZhcnMuYWRkKG1ldGhvZCkKKworICBkZWYgX19nZXRhdHRyX18oc2VsZiwgbmFtZSk6CisgICAgIiIiSW50ZXJjZXB0IGF0dHJpYnV0ZSByZXF1ZXN0IG9uIHRoaXMgb2JqZWN0LgorCisgICAgSWYgdGhlIGF0dHJpYnV0ZSBpcyBhIHB1YmxpYyBjbGFzcyB2YXJpYWJsZSwgaXQgd2lsbCBiZSByZXR1cm5lZCBhbmQgbm90CisgICAgcmVjb3JkZWQgYXMgYSBjYWxsLgorCisgICAgSWYgdGhlIGF0dHJpYnV0ZSBpcyBub3QgYSB2YXJpYWJsZSwgaXQgaXMgaGFuZGxlZCBsaWtlIGEgbWV0aG9kCisgICAgY2FsbC4gVGhlIG1ldGhvZCBuYW1lIGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgc2V0IG9mIG1vY2thYmxlCisgICAgbWV0aG9kcywgYW5kIGEgbmV3IE1vY2tNZXRob2QgaXMgcmV0dXJuZWQgdGhhdCBpcyBhd2FyZSBvZiB0aGUKKyAgICBNb2NrT2JqZWN0J3Mgc3RhdGUgKHJlY29yZCBvciByZXBsYXkpLiAgVGhlIGNhbGwgd2lsbCBiZSByZWNvcmRlZAorICAgIG9yIHJlcGxheWVkIGJ5IHRoZSBNb2NrTWV0aG9kJ3MgX19jYWxsX18uCisKKyAgICBBcmdzOgorICAgICAgIyBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGJlaW5nIHJlcXVlc3RlZC4KKyAgICAgIG5hbWU6IHN0cgorCisgICAgUmV0dXJuczoKKyAgICAgIEVpdGhlciBhIGNsYXNzIHZhcmlhYmxlIG9yIGEgbmV3IE1vY2tNZXRob2QgdGhhdCBpcyBhd2FyZSBvZiB0aGUgc3RhdGUKKyAgICAgIG9mIHRoZSBtb2NrIChyZWNvcmQgb3IgcmVwbGF5KS4KKworICAgIFJhaXNlczoKKyAgICAgIFVua25vd25NZXRob2RDYWxsRXJyb3IgaWYgdGhlIE1vY2tPYmplY3QgZG9lcyBub3QgbW9jayB0aGUgcmVxdWVzdGVkCisgICAgICAgICAgbWV0aG9kLgorICAgICIiIgorCisgICAgaWYgbmFtZSBpbiBzZWxmLl9rbm93bl92YXJzOgorICAgICAgcmV0dXJuIGdldGF0dHIoc2VsZi5fY2xhc3NfdG9fbW9jaywgbmFtZSkKKworICAgIGlmIG5hbWUgaW4gc2VsZi5fa25vd25fbWV0aG9kczoKKyAgICAgIHJldHVybiBzZWxmLl9DcmVhdGVNb2NrTWV0aG9kKG5hbWUpCisKKyAgICByYWlzZSBVbmtub3duTWV0aG9kQ2FsbEVycm9yKG5hbWUpCisKKyAgZGVmIF9fZXFfXyhzZWxmLCByaHMpOgorICAgICIiIlByb3ZpZGUgY3VzdG9tIGxvZ2ljIHRvIGNvbXBhcmUgb2JqZWN0cy4iIiIKKworICAgIHJldHVybiAoaXNpbnN0YW5jZShyaHMsIE1vY2tPYmplY3QpIGFuZAorICAgICAgICAgICAgc2VsZi5fY2xhc3NfdG9fbW9jayA9PSByaHMuX2NsYXNzX3RvX21vY2sgYW5kCisgICAgICAgICAgICBzZWxmLl9yZXBsYXlfbW9kZSA9PSByaHMuX3JlcGxheV9tb2RlIGFuZAorICAgICAgICAgICAgc2VsZi5fZXhwZWN0ZWRfY2FsbHNfcXVldWUgPT0gcmhzLl9leHBlY3RlZF9jYWxsc19xdWV1ZSkKKworICBkZWYgX19zZXRpdGVtX18oc2VsZiwga2V5LCB2YWx1ZSk6CisgICAgIiIiUHJvdmlkZSBjdXN0b20gbG9naWMgZm9yIG1vY2tpbmcgY2xhc3NlcyB0aGF0IHN1cHBvcnQgaXRlbSBhc3NpZ25tZW50LgorCisgICAgQXJnczoKKyAgICAgIGtleTogS2V5IHRvIHNldCB0aGUgdmFsdWUgZm9yLgorICAgICAgdmFsdWU6IFZhbHVlIHRvIHNldC4KKworICAgIFJldHVybnM6CisgICAgICBFeHBlY3RlZCByZXR1cm4gdmFsdWUgaW4gcmVwbGF5IG1vZGUuICBBIE1vY2tNZXRob2Qgb2JqZWN0IGZvciB0aGUKKyAgICAgIF9fc2V0aXRlbV9fIG1ldGhvZCB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIGlmIG5vdCBpbiByZXBsYXkgbW9kZS4KKworICAgIFJhaXNlczoKKyAgICAgIFR5cGVFcnJvciBpZiB0aGUgdW5kZXJseWluZyBjbGFzcyBkb2VzIG5vdCBzdXBwb3J0IGl0ZW0gYXNzaWdubWVudC4KKyAgICAgIFVuZXhwZWN0ZWRNZXRob2RDYWxsRXJyb3IgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBleHBlY3QgdGhlIGNhbGwgdG8KKyAgICAgICAgX19zZXRpdGVtX18uCisKKyAgICAiIiIKKyAgICBzZXRpdGVtID0gc2VsZi5fY2xhc3NfdG9fbW9jay5fX2RpY3RfXy5nZXQoJ19fc2V0aXRlbV9fJywgTm9uZSkKKworICAgICMgVmVyaWZ5IHRoZSBjbGFzcyBzdXBwb3J0cyBpdGVtIGFzc2lnbm1lbnQuCisgICAgaWYgc2V0aXRlbSBpcyBOb25lOgorICAgICAgcmFpc2UgVHlwZUVycm9yKCdvYmplY3QgZG9lcyBub3Qgc3VwcG9ydCBpdGVtIGFzc2lnbm1lbnQnKQorCisgICAgIyBJZiB3ZSBhcmUgaW4gcmVwbGF5IG1vZGUgdGhlbiBzaW1wbHkgY2FsbCB0aGUgbW9jayBfX3NldGl0ZW1fXyBtZXRob2QuCisgICAgaWYgc2VsZi5fcmVwbGF5X21vZGU6CisgICAgICByZXR1cm4gTW9ja01ldGhvZCgnX19zZXRpdGVtX18nLCBzZWxmLl9leHBlY3RlZF9jYWxsc19xdWV1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3JlcGxheV9tb2RlKShrZXksIHZhbHVlKQorCisKKyAgICAjIE90aGVyd2lzZSwgY3JlYXRlIGEgbW9jayBtZXRob2QgX19zZXRpdGVtX18uCisgICAgcmV0dXJuIHNlbGYuX0NyZWF0ZU1vY2tNZXRob2QoJ19fc2V0aXRlbV9fJykoa2V5LCB2YWx1ZSkKKworICBkZWYgX19nZXRpdGVtX18oc2VsZiwga2V5KToKKyAgICAiIiJQcm92aWRlIGN1c3RvbSBsb2dpYyBmb3IgbW9ja2luZyBjbGFzc2VzIHRoYXQgYXJlIHN1YnNjcmlwdGFibGUuCisKKyAgICBBcmdzOgorICAgICAga2V5OiBLZXkgdG8gcmV0dXJuIHRoZSB2YWx1ZSBmb3IuCisKKyAgICBSZXR1cm5zOgorICAgICAgRXhwZWN0ZWQgcmV0dXJuIHZhbHVlIGluIHJlcGxheSBtb2RlLiAgQSBNb2NrTWV0aG9kIG9iamVjdCBmb3IgdGhlCisgICAgICBfX2dldGl0ZW1fXyBtZXRob2QgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCBpZiBub3QgaW4gcmVwbGF5IG1vZGUuCisKKyAgICBSYWlzZXM6CisgICAgICBUeXBlRXJyb3IgaWYgdGhlIHVuZGVybHlpbmcgY2xhc3MgaXMgbm90IHN1YnNjcmlwdGFibGUuCisgICAgICBVbmV4cGVjdGVkTWV0aG9kQ2FsbEVycm9yIGlmIHRoZSBvYmplY3QgZG9lcyBub3QgZXhwZWN0IHRoZSBjYWxsIHRvCisgICAgICAgIF9fc2V0aXRlbV9fLgorCisgICAgIiIiCisgICAgZ2V0aXRlbSA9IHNlbGYuX2NsYXNzX3RvX21vY2suX19kaWN0X18uZ2V0KCdfX2dldGl0ZW1fXycsIE5vbmUpCisKKyAgICAjIFZlcmlmeSB0aGUgY2xhc3Mgc3VwcG9ydHMgaXRlbSBhc3NpZ25tZW50LgorICAgIGlmIGdldGl0ZW0gaXMgTm9uZToKKyAgICAgIHJhaXNlIFR5cGVFcnJvcigndW5zdWJzY3JpcHRhYmxlIG9iamVjdCcpCisKKyAgICAjIElmIHdlIGFyZSBpbiByZXBsYXkgbW9kZSB0aGVuIHNpbXBseSBjYWxsIHRoZSBtb2NrIF9fZ2V0aXRlbV9fIG1ldGhvZC4KKyAgICBpZiBzZWxmLl9yZXBsYXlfbW9kZToKKyAgICAgIHJldHVybiBNb2NrTWV0aG9kKCdfX2dldGl0ZW1fXycsIHNlbGYuX2V4cGVjdGVkX2NhbGxzX3F1ZXVlLAorICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwbGF5X21vZGUpKGtleSkKKworCisgICAgIyBPdGhlcndpc2UsIGNyZWF0ZSBhIG1vY2sgbWV0aG9kIF9fZ2V0aXRlbV9fLgorICAgIHJldHVybiBzZWxmLl9DcmVhdGVNb2NrTWV0aG9kKCdfX2dldGl0ZW1fXycpKGtleSkKKworICBkZWYgX19jYWxsX18oc2VsZiwgKnBhcmFtcywgKipuYW1lZF9wYXJhbXMpOgorICAgICIiIlByb3ZpZGUgY3VzdG9tIGxvZ2ljIGZvciBtb2NraW5nIGNsYXNzZXMgdGhhdCBhcmUgY2FsbGFibGUuIiIiCisKKyAgICAjIFZlcmlmeSB0aGUgY2xhc3Mgd2UgYXJlIG1vY2tpbmcgaXMgY2FsbGFibGUKKyAgICBjYWxsYWJsZSA9IHNlbGYuX2NsYXNzX3RvX21vY2suX19kaWN0X18uZ2V0KCdfX2NhbGxfXycsIE5vbmUpCisgICAgaWYgY2FsbGFibGUgaXMgTm9uZToKKyAgICAgIHJhaXNlIFR5cGVFcnJvcignTm90IGNhbGxhYmxlJykKKworICAgICMgQmVjYXVzZSB0aGUgY2FsbCBpcyBoYXBwZW5pbmcgZGlyZWN0bHkgb24gdGhpcyBvYmplY3QgaW5zdGVhZCBvZiBhIG1ldGhvZCwKKyAgICAjIHRoZSBjYWxsIG9uIHRoZSBtb2NrIG1ldGhvZCBpcyBtYWRlIHJpZ2h0IGhlcmUKKyAgICBtb2NrX21ldGhvZCA9IHNlbGYuX0NyZWF0ZU1vY2tNZXRob2QoJ19fY2FsbF9fJykKKyAgICByZXR1cm4gbW9ja19tZXRob2QoKnBhcmFtcywgKipuYW1lZF9wYXJhbXMpCisKKyAgQHByb3BlcnR5CisgIGRlZiBfX2NsYXNzX18oc2VsZik6CisgICAgIiIiUmV0dXJuIHRoZSBjbGFzcyB0aGF0IGlzIGJlaW5nIG1vY2tlZC4iIiIKKworICAgIHJldHVybiBzZWxmLl9jbGFzc190b19tb2NrCisKKworY2xhc3MgTW9ja01ldGhvZChvYmplY3QpOgorICAiIiJDYWxsYWJsZSBtb2NrIG1ldGhvZC4KKworICBBIE1vY2tNZXRob2Qgc2hvdWxkIGFjdCBleGFjdGx5IGxpa2UgdGhlIG1ldGhvZCBpdCBtb2NrcywgYWNjZXB0aW5nIHBhcmFtZXRlcnMKKyAgYW5kIHJldHVybmluZyBhIHZhbHVlLCBvciB0aHJvd2luZyBhbiBleGNlcHRpb24gKGFzIHNwZWNpZmllZCkuICBXaGVuIHRoaXMKKyAgbWV0aG9kIGlzIGNhbGxlZCwgaXQgY2FuIG9wdGlvbmFsbHkgdmVyaWZ5IHdoZXRoZXIgdGhlIGNhbGxlZCBtZXRob2QgKG5hbWUgYW5kCisgIHNpZ25hdHVyZSkgbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgbWV0aG9kLgorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgbWV0aG9kX25hbWUsIGNhbGxfcXVldWUsIHJlcGxheV9tb2RlKToKKyAgICAiIiJDb25zdHJ1Y3QgYSBuZXcgbW9jayBtZXRob2QuCisKKyAgICBBcmdzOgorICAgICAgIyBtZXRob2RfbmFtZTogdGhlIG5hbWUgb2YgdGhlIG1ldGhvZAorICAgICAgIyBjYWxsX3F1ZXVlOiBkZXF1ZSBvZiBjYWxscywgdmVyaWZ5IHRoaXMgY2FsbCBhZ2FpbnN0IHRoZSBoZWFkLCBvciBhZGQKKyAgICAgICMgICAgIHRoaXMgY2FsbCB0byB0aGUgcXVldWUuCisgICAgICAjIHJlcGxheV9tb2RlOiBGYWxzZSBpZiB3ZSBhcmUgcmVjb3JkaW5nLCBUcnVlIGlmIHdlIGFyZSB2ZXJpZnlpbmcgY2FsbHMKKyAgICAgICMgICAgIGFnYWluc3QgdGhlIGNhbGwgcXVldWUuCisgICAgICBtZXRob2RfbmFtZTogc3RyCisgICAgICBjYWxsX3F1ZXVlOiBsaXN0IG9yIGRlcXVlCisgICAgICByZXBsYXlfbW9kZTogYm9vbAorICAgICIiIgorCisgICAgc2VsZi5fbmFtZSA9IG1ldGhvZF9uYW1lCisgICAgc2VsZi5fY2FsbF9xdWV1ZSA9IGNhbGxfcXVldWUKKyAgICBpZiBub3QgaXNpbnN0YW5jZShjYWxsX3F1ZXVlLCBkZXF1ZSk6CisgICAgICBzZWxmLl9jYWxsX3F1ZXVlID0gZGVxdWUoc2VsZi5fY2FsbF9xdWV1ZSkKKyAgICBzZWxmLl9yZXBsYXlfbW9kZSA9IHJlcGxheV9tb2RlCisKKyAgICBzZWxmLl9wYXJhbXMgPSBOb25lCisgICAgc2VsZi5fbmFtZWRfcGFyYW1zID0gTm9uZQorICAgIHNlbGYuX3JldHVybl92YWx1ZSA9IE5vbmUKKyAgICBzZWxmLl9leGNlcHRpb24gPSBOb25lCisgICAgc2VsZi5fc2lkZV9lZmZlY3RzID0gTm9uZQorCisgIGRlZiBfX2NhbGxfXyhzZWxmLCAqcGFyYW1zLCAqKm5hbWVkX3BhcmFtcyk6CisgICAgIiIiTG9nIHBhcmFtZXRlcnMgYW5kIHJldHVybiB0aGUgc3BlY2lmaWVkIHJldHVybiB2YWx1ZS4KKworICAgIElmIHRoZSBNb2NrKEFueXRoaW5nL09iamVjdCkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY2FsbCBpcyBpbiByZWNvcmQgbW9kZSwKKyAgICB0aGlzIE1vY2tNZXRob2Qgd2lsbCBiZSBwdXNoZWQgb250byB0aGUgZXhwZWN0ZWQgY2FsbCBxdWV1ZS4gIElmIHRoZSBtb2NrCisgICAgaXMgaW4gcmVwbGF5IG1vZGUsIHRoaXMgd2lsbCBwb3AgYSBNb2NrTWV0aG9kIG9mZiB0aGUgdG9wIG9mIHRoZSBxdWV1ZSBhbmQKKyAgICB2ZXJpZnkgdGhpcyBjYWxsIGlzIGVxdWFsIHRvIHRoZSBleHBlY3RlZCBjYWxsLgorCisgICAgUmFpc2VzOgorICAgICAgVW5leHBlY3RlZE1ldGhvZENhbGwgaWYgdGhpcyBjYWxsIGlzIHN1cHBvc2VkIHRvIG1hdGNoIGFuIGV4cGVjdGVkIG1ldGhvZAorICAgICAgICBjYWxsIGFuZCBpdCBkb2VzIG5vdC4KKyAgICAiIiIKKworICAgIHNlbGYuX3BhcmFtcyA9IHBhcmFtcworICAgIHNlbGYuX25hbWVkX3BhcmFtcyA9IG5hbWVkX3BhcmFtcworCisgICAgaWYgbm90IHNlbGYuX3JlcGxheV9tb2RlOgorICAgICAgc2VsZi5fY2FsbF9xdWV1ZS5hcHBlbmQoc2VsZikKKyAgICAgIHJldHVybiBzZWxmCisKKyAgICBleHBlY3RlZF9tZXRob2QgPSBzZWxmLl9WZXJpZnlNZXRob2RDYWxsKCkKKworICAgIGlmIGV4cGVjdGVkX21ldGhvZC5fc2lkZV9lZmZlY3RzOgorICAgICAgZXhwZWN0ZWRfbWV0aG9kLl9zaWRlX2VmZmVjdHMoKnBhcmFtcywgKipuYW1lZF9wYXJhbXMpCisKKyAgICBpZiBleHBlY3RlZF9tZXRob2QuX2V4Y2VwdGlvbjoKKyAgICAgIHJhaXNlIGV4cGVjdGVkX21ldGhvZC5fZXhjZXB0aW9uCisKKyAgICByZXR1cm4gZXhwZWN0ZWRfbWV0aG9kLl9yZXR1cm5fdmFsdWUKKworICBkZWYgX19nZXRhdHRyX18oc2VsZiwgbmFtZSk6CisgICAgIiIiUmFpc2UgYW4gQXR0cmlidXRlRXJyb3Igd2l0aCBhIGhlbHBmdWwgbWVzc2FnZS4iIiIKKworICAgIHJhaXNlIEF0dHJpYnV0ZUVycm9yKCdNb2NrTWV0aG9kIGhhcyBubyBhdHRyaWJ1dGUgIiVzIi4gJworICAgICAgICAnRGlkIHlvdSByZW1lbWJlciB0byBwdXQgeW91ciBtb2NrcyBpbiByZXBsYXkgbW9kZT8nICUgbmFtZSkKKworICBkZWYgX1BvcE5leHRNZXRob2Qoc2VsZik6CisgICAgIiIiUG9wIHRoZSBuZXh0IG1ldGhvZCBmcm9tIG91ciBjYWxsIHF1ZXVlLiIiIgorICAgIHRyeToKKyAgICAgIHJldHVybiBzZWxmLl9jYWxsX3F1ZXVlLnBvcGxlZnQoKQorICAgIGV4Y2VwdCBJbmRleEVycm9yOgorICAgICAgcmFpc2UgVW5leHBlY3RlZE1ldGhvZENhbGxFcnJvcihzZWxmLCBOb25lKQorCisgIGRlZiBfVmVyaWZ5TWV0aG9kQ2FsbChzZWxmKToKKyAgICAiIiJWZXJpZnkgdGhlIGNhbGxlZCBtZXRob2QgaXMgZXhwZWN0ZWQuCisKKyAgICBUaGlzIGNhbiBiZSBhbiBvcmRlcmVkIG1ldGhvZCwgb3IgcGFydCBvZiBhbiB1bm9yZGVyZWQgc2V0LgorCisgICAgUmV0dXJuczoKKyAgICAgIFRoZSBleHBlY3RlZCBtb2NrIG1ldGhvZC4KKworICAgIFJhaXNlczoKKyAgICAgIFVuZXhwZWN0ZWRNZXRob2RDYWxsIGlmIHRoZSBtZXRob2QgY2FsbGVkIHdhcyBub3QgZXhwZWN0ZWQuCisgICAgIiIiCisKKyAgICBleHBlY3RlZCA9IHNlbGYuX1BvcE5leHRNZXRob2QoKQorCisgICAgIyBMb29wIGhlcmUsIGJlY2F1c2Ugd2UgbWlnaHQgaGF2ZSBhIE1ldGhvZEdyb3VwIGZvbGxvd2VkIGJ5IGFub3RoZXIKKyAgICAjIGdyb3VwLgorICAgIHdoaWxlIGlzaW5zdGFuY2UoZXhwZWN0ZWQsIE1ldGhvZEdyb3VwKToKKyAgICAgIGV4cGVjdGVkLCBtZXRob2QgPSBleHBlY3RlZC5NZXRob2RDYWxsZWQoc2VsZikKKyAgICAgIGlmIG1ldGhvZCBpcyBub3QgTm9uZToKKyAgICAgICAgcmV0dXJuIG1ldGhvZAorCisgICAgIyBUaGlzIGlzIGEgbW9jayBtZXRob2QsIHNvIGp1c3QgY2hlY2sgZXF1YWxpdHkuCisgICAgaWYgZXhwZWN0ZWQgIT0gc2VsZjoKKyAgICAgIHJhaXNlIFVuZXhwZWN0ZWRNZXRob2RDYWxsRXJyb3Ioc2VsZiwgZXhwZWN0ZWQpCisKKyAgICByZXR1cm4gZXhwZWN0ZWQKKworICBkZWYgX19zdHJfXyhzZWxmKToKKyAgICBwYXJhbXMgPSAnLCAnLmpvaW4oCisgICAgICAgIFtyZXByKHApIGZvciBwIGluIHNlbGYuX3BhcmFtcyBvciBbXV0gKworICAgICAgICBbJyVzPSVyJyAlIHggZm9yIHggaW4gc29ydGVkKChzZWxmLl9uYW1lZF9wYXJhbXMgb3Ige30pLml0ZW1zKCkpXSkKKyAgICBkZXNjID0gIiVzKCVzKSAtPiAlciIgJSAoc2VsZi5fbmFtZSwgcGFyYW1zLCBzZWxmLl9yZXR1cm5fdmFsdWUpCisgICAgcmV0dXJuIGRlc2MKKworICBkZWYgX19lcV9fKHNlbGYsIHJocyk6CisgICAgIiIiVGVzdCB3aGV0aGVyIHRoaXMgTW9ja01ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGFub3RoZXIgTW9ja01ldGhvZC4KKworICAgIEFyZ3M6CisgICAgICAjIHJoczogdGhlIHJpZ2h0IGhhbmQgc2lkZSBvZiB0aGUgdGVzdAorICAgICAgcmhzOiBNb2NrTWV0aG9kCisgICAgIiIiCisKKyAgICByZXR1cm4gKGlzaW5zdGFuY2UocmhzLCBNb2NrTWV0aG9kKSBhbmQKKyAgICAgICAgICAgIHNlbGYuX25hbWUgPT0gcmhzLl9uYW1lIGFuZAorICAgICAgICAgICAgc2VsZi5fcGFyYW1zID09IHJocy5fcGFyYW1zIGFuZAorICAgICAgICAgICAgc2VsZi5fbmFtZWRfcGFyYW1zID09IHJocy5fbmFtZWRfcGFyYW1zKQorCisgIGRlZiBfX25lX18oc2VsZiwgcmhzKToKKyAgICAiIiJUZXN0IHdoZXRoZXIgdGhpcyBNb2NrTWV0aG9kIGlzIG5vdCBlcXVpdmFsZW50IHRvIGFub3RoZXIgTW9ja01ldGhvZC4KKworICAgIEFyZ3M6CisgICAgICAjIHJoczogdGhlIHJpZ2h0IGhhbmQgc2lkZSBvZiB0aGUgdGVzdAorICAgICAgcmhzOiBNb2NrTWV0aG9kCisgICAgIiIiCisKKyAgICByZXR1cm4gbm90IHNlbGYgPT0gcmhzCisKKyAgZGVmIEdldFBvc3NpYmxlR3JvdXAoc2VsZik6CisgICAgIiIiUmV0dXJucyBhIHBvc3NpYmxlIGdyb3VwIGZyb20gdGhlIGVuZCBvZiB0aGUgY2FsbCBxdWV1ZSBvciBOb25lIGlmIG5vCisgICAgb3RoZXIgbWV0aG9kcyBhcmUgb24gdGhlIHN0YWNrLgorICAgICIiIgorCisgICAgIyBSZW1vdmUgdGhpcyBtZXRob2QgZnJvbSB0aGUgdGFpbCBvZiB0aGUgcXVldWUgc28gd2UgY2FuIGFkZCBpdCB0byBhIGdyb3VwLgorICAgIHRoaXNfbWV0aG9kID0gc2VsZi5fY2FsbF9xdWV1ZS5wb3AoKQorICAgIGFzc2VydCB0aGlzX21ldGhvZCA9PSBzZWxmCisKKyAgICAjIERldGVybWluZSBpZiB0aGUgdGFpbCBvZiB0aGUgcXVldWUgaXMgYSBncm91cCwgb3IganVzdCBhIHJlZ3VsYXIgb3JkZXJlZAorICAgICMgbW9jayBtZXRob2QuCisgICAgZ3JvdXAgPSBOb25lCisgICAgdHJ5OgorICAgICAgZ3JvdXAgPSBzZWxmLl9jYWxsX3F1ZXVlWy0xXQorICAgIGV4Y2VwdCBJbmRleEVycm9yOgorICAgICAgcGFzcworCisgICAgcmV0dXJuIGdyb3VwCisKKyAgZGVmIF9DaGVja0FuZENyZWF0ZU5ld0dyb3VwKHNlbGYsIGdyb3VwX25hbWUsIGdyb3VwX2NsYXNzKToKKyAgICAiIiJDaGVja3MgaWYgdGhlIGxhc3QgbWV0aG9kIChhIHBvc3NpYmxlIGdyb3VwKSBpcyBhbiBpbnN0YW5jZSBvZiBvdXIKKyAgICBncm91cF9jbGFzcy4gQWRkcyB0aGUgY3VycmVudCBtZXRob2QgdG8gdGhpcyBncm91cCBvciBjcmVhdGVzIGEgbmV3IG9uZS4KKworICAgIEFyZ3M6CisKKyAgICAgIGdyb3VwX25hbWU6IHRoZSBuYW1lIG9mIHRoZSBncm91cC4KKyAgICAgIGdyb3VwX2NsYXNzOiB0aGUgY2xhc3MgdXNlZCB0byBjcmVhdGUgaW5zdGFuY2Ugb2YgdGhpcyBuZXcgZ3JvdXAKKyAgICAiIiIKKyAgICBncm91cCA9IHNlbGYuR2V0UG9zc2libGVHcm91cCgpCisKKyAgICAjIElmIHRoaXMgaXMgYSBncm91cCwgYW5kIGl0IGlzIHRoZSBjb3JyZWN0IGdyb3VwLCBhZGQgdGhlIG1ldGhvZC4KKyAgICBpZiBpc2luc3RhbmNlKGdyb3VwLCBncm91cF9jbGFzcykgYW5kIGdyb3VwLmdyb3VwX25hbWUoKSA9PSBncm91cF9uYW1lOgorICAgICAgZ3JvdXAuQWRkTWV0aG9kKHNlbGYpCisgICAgICByZXR1cm4gc2VsZgorCisgICAgIyBDcmVhdGUgYSBuZXcgZ3JvdXAgYW5kIGFkZCB0aGUgbWV0aG9kLgorICAgIG5ld19ncm91cCA9IGdyb3VwX2NsYXNzKGdyb3VwX25hbWUpCisgICAgbmV3X2dyb3VwLkFkZE1ldGhvZChzZWxmKQorICAgIHNlbGYuX2NhbGxfcXVldWUuYXBwZW5kKG5ld19ncm91cCkKKyAgICByZXR1cm4gc2VsZgorCisgIGRlZiBJbkFueU9yZGVyKHNlbGYsIGdyb3VwX25hbWU9ImRlZmF1bHQiKToKKyAgICAiIiJNb3ZlIHRoaXMgbWV0aG9kIGludG8gYSBncm91cCBvZiB1bm9yZGVyZWQgY2FsbHMuCisKKyAgICBBIGdyb3VwIG9mIHVub3JkZXJlZCBjYWxscyBtdXN0IGJlIGRlZmluZWQgdG9nZXRoZXIsIGFuZCBtdXN0IGJlIGV4ZWN1dGVkCisgICAgaW4gZnVsbCBiZWZvcmUgdGhlIG5leHQgZXhwZWN0ZWQgbWV0aG9kIGNhbiBiZSBjYWxsZWQuICBUaGVyZSBjYW4gYmUKKyAgICBtdWx0aXBsZSBncm91cHMgdGhhdCBhcmUgZXhwZWN0ZWQgc2VyaWFsbHksIGlmIHRoZXkgYXJlIGdpdmVuCisgICAgZGlmZmVyZW50IGdyb3VwIG5hbWVzLiAgVGhlIHNhbWUgZ3JvdXAgbmFtZSBjYW4gYmUgcmV1c2VkIGlmIHRoZXJlIGlzIGEKKyAgICBzdGFuZGFyZCBtZXRob2QgY2FsbCwgb3IgYSBncm91cCB3aXRoIGEgZGlmZmVyZW50IG5hbWUsIHNwbGljZWQgYmV0d2VlbgorICAgIHVzYWdlcy4KKworICAgIEFyZ3M6CisgICAgICBncm91cF9uYW1lOiB0aGUgbmFtZSBvZiB0aGUgdW5vcmRlcmVkIGdyb3VwLgorCisgICAgUmV0dXJuczoKKyAgICAgIHNlbGYKKyAgICAiIiIKKyAgICByZXR1cm4gc2VsZi5fQ2hlY2tBbmRDcmVhdGVOZXdHcm91cChncm91cF9uYW1lLCBVbm9yZGVyZWRHcm91cCkKKworICBkZWYgTXVsdGlwbGVUaW1lcyhzZWxmLCBncm91cF9uYW1lPSJkZWZhdWx0Iik6CisgICAgIiIiTW92ZSB0aGlzIG1ldGhvZCBpbnRvIGdyb3VwIG9mIGNhbGxzIHdoaWNoIG1heSBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMuCisKKyAgICBBIGdyb3VwIG9mIHJlcGVhdGluZyBjYWxscyBtdXN0IGJlIGRlZmluZWQgdG9nZXRoZXIsIGFuZCBtdXN0IGJlIGV4ZWN1dGVkIGluCisgICAgZnVsbCBiZWZvcmUgdGhlIG5leHQgZXhwZWN0ZWQgbWVodG9kIGNhbiBiZSBjYWxsZWQuCisKKyAgICBBcmdzOgorICAgICAgZ3JvdXBfbmFtZTogdGhlIG5hbWUgb2YgdGhlIHVub3JkZXJlZCBncm91cC4KKworICAgIFJldHVybnM6CisgICAgICBzZWxmCisgICAgIiIiCisgICAgcmV0dXJuIHNlbGYuX0NoZWNrQW5kQ3JlYXRlTmV3R3JvdXAoZ3JvdXBfbmFtZSwgTXVsdGlwbGVUaW1lc0dyb3VwKQorCisgIGRlZiBBbmRSZXR1cm4oc2VsZiwgcmV0dXJuX3ZhbHVlKToKKyAgICAiIiJTZXQgdGhlIHZhbHVlIHRvIHJldHVybiB3aGVuIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KKworICAgIEFyZ3M6CisgICAgICAjIHJldHVybl92YWx1ZSBjYW4gYmUgYW55dGhpbmcuCisgICAgIiIiCisKKyAgICBzZWxmLl9yZXR1cm5fdmFsdWUgPSByZXR1cm5fdmFsdWUKKyAgICByZXR1cm4gcmV0dXJuX3ZhbHVlCisKKyAgZGVmIEFuZFJhaXNlKHNlbGYsIGV4Y2VwdGlvbik6CisgICAgIiIiU2V0IHRoZSBleGNlcHRpb24gdG8gcmFpc2Ugd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisKKyAgICBBcmdzOgorICAgICAgIyBleGNlcHRpb246IHRoZSBleGNlcHRpb24gdG8gcmFpc2Ugd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICBleGNlcHRpb246IEV4Y2VwdGlvbgorICAgICIiIgorCisgICAgc2VsZi5fZXhjZXB0aW9uID0gZXhjZXB0aW9uCisKKyAgZGVmIFdpdGhTaWRlRWZmZWN0cyhzZWxmLCBzaWRlX2VmZmVjdHMpOgorICAgICIiIlNldCB0aGUgc2lkZSBlZmZlY3RzIHRoYXQgYXJlIHNpbXVsYXRlZCB3aGVuIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KKworICAgIEFyZ3M6CisgICAgICBzaWRlX2VmZmVjdHM6IEEgY2FsbGFibGUgd2hpY2ggbW9kaWZpZXMgdGhlIHBhcmFtZXRlcnMgb3Igb3RoZXIgcmVsZXZhbnQKKyAgICAgICAgc3RhdGUgd2hpY2ggYSBnaXZlbiB0ZXN0IGNhc2UgZGVwZW5kcyBvbi4KKworICAgIFJldHVybnM6CisgICAgICBTZWxmIGZvciBjaGFpbmluZyB3aXRoIEFuZFJldHVybiBhbmQgQW5kUmFpc2UuCisgICAgIiIiCisgICAgc2VsZi5fc2lkZV9lZmZlY3RzID0gc2lkZV9lZmZlY3RzCisgICAgcmV0dXJuIHNlbGYKKworY2xhc3MgQ29tcGFyYXRvcjoKKyAgIiIiQmFzZSBjbGFzcyBmb3IgYWxsIE1veCBjb21wYXJhdG9ycy4KKworICBBIENvbXBhcmF0b3IgY2FuIGJlIHVzZWQgYXMgYSBwYXJhbWV0ZXIgdG8gYSBtb2NrZWQgbWV0aG9kIHdoZW4gdGhlIGV4YWN0CisgIHZhbHVlIGlzIG5vdCBrbm93bi4gIEZvciBleGFtcGxlLCB0aGUgY29kZSB5b3UgYXJlIHRlc3RpbmcgbWlnaHQgYnVpbGQgdXAgYQorICBsb25nIFNRTCBzdHJpbmcgdGhhdCBpcyBwYXNzZWQgdG8geW91ciBtb2NrIERBTy4gWW91J3JlIG9ubHkgaW50ZXJlc3RlZCB0aGF0CisgIHRoZSBJTiBjbGF1c2UgY29udGFpbnMgdGhlIHByb3BlciBwcmltYXJ5IGtleXMsIHNvIHlvdSBjYW4gc2V0IHlvdXIgbW9jaworICB1cCBhcyBmb2xsb3dzOgorCisgIG1vY2tfZGFvLlJ1blF1ZXJ5KFN0ckNvbnRhaW5zKCdJTiAoMSwgMiwgNCwgNSknKSkuQW5kUmV0dXJuKG1vY2tfcmVzdWx0KQorCisgIE5vdyB3aGF0ZXZlciBxdWVyeSBpcyBwYXNzZWQgaW4gbXVzdCBjb250YWluIHRoZSBzdHJpbmcgJ0lOICgxLCAyLCA0LCA1KScuCisKKyAgQSBDb21wYXJhdG9yIG1heSByZXBsYWNlIG9uZSBvciBtb3JlIHBhcmFtZXRlcnMsIGZvciBleGFtcGxlOgorICAjIHJldHVybiBhdCBtb3N0IDEwIHJvd3MKKyAgbW9ja19kYW8uUnVuUXVlcnkoU3RyQ29udGFpbnMoJ1NFTEVDVCcpLCAxMCkKKworICBvcgorCisgICMgUmV0dXJuIHNvbWUgbm9uLWRldGVybWluaXN0aWMgbnVtYmVyIG9mIHJvd3MKKyAgbW9ja19kYW8uUnVuUXVlcnkoU3RyQ29udGFpbnMoJ1NFTEVDVCcpLCBJc0EoaW50KSkKKyAgIiIiCisKKyAgZGVmIGVxdWFscyhzZWxmLCByaHMpOgorICAgICIiIlNwZWNpYWwgZXF1YWxzIG1ldGhvZCB0aGF0IGFsbCBjb21wYXJhdG9ycyBtdXN0IGltcGxlbWVudC4KKworICAgIEFyZ3M6CisgICAgICByaHM6IGFueSBweXRob24gb2JqZWN0CisgICAgIiIiCisKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yLCAnbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgYSBzdWJjbGFzcy4nCisKKyAgZGVmIF9fZXFfXyhzZWxmLCByaHMpOgorICAgIHJldHVybiBzZWxmLmVxdWFscyhyaHMpCisKKyAgZGVmIF9fbmVfXyhzZWxmLCByaHMpOgorICAgIHJldHVybiBub3Qgc2VsZi5lcXVhbHMocmhzKQorCisKK2NsYXNzIElzQShDb21wYXJhdG9yKToKKyAgIiIiVGhpcyBjbGFzcyB3cmFwcyBhIGJhc2ljIFB5dGhvbiB0eXBlIG9yIGNsYXNzLiAgSXQgaXMgdXNlZCB0byB2ZXJpZnkKKyAgdGhhdCBhIHBhcmFtZXRlciBpcyBvZiB0aGUgZ2l2ZW4gdHlwZSBvciBjbGFzcy4KKworICBFeGFtcGxlOgorICBtb2NrX2Rhby5Db25uZWN0KElzQShEYkNvbm5lY3RJbmZvKSkKKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGNsYXNzX25hbWUpOgorICAgICIiIkluaXRpYWxpemUgSXNBCisKKyAgICBBcmdzOgorICAgICAgY2xhc3NfbmFtZTogYmFzaWMgcHl0aG9uIHR5cGUgb3IgYSBjbGFzcworICAgICIiIgorCisgICAgc2VsZi5fY2xhc3NfbmFtZSA9IGNsYXNzX25hbWUKKworICBkZWYgZXF1YWxzKHNlbGYsIHJocyk6CisgICAgIiIiQ2hlY2sgdG8gc2VlIGlmIHRoZSBSSFMgaXMgYW4gaW5zdGFuY2Ugb2YgY2xhc3NfbmFtZS4KKworICAgIEFyZ3M6CisgICAgICAjIHJoczogdGhlIHJpZ2h0IGhhbmQgc2lkZSBvZiB0aGUgdGVzdAorICAgICAgcmhzOiBvYmplY3QKKworICAgIFJldHVybnM6CisgICAgICBib29sCisgICAgIiIiCisKKyAgICB0cnk6CisgICAgICByZXR1cm4gaXNpbnN0YW5jZShyaHMsIHNlbGYuX2NsYXNzX25hbWUpCisgICAgZXhjZXB0IFR5cGVFcnJvcjoKKyAgICAgICMgQ2hlY2sgcmF3IHR5cGVzIGlmIHRoZXJlIHdhcyBhIHR5cGUgZXJyb3IuICBUaGlzIGlzIGhlbHBmdWwgZm9yCisgICAgICAjIHRoaW5ncyBsaWtlIGNTdHJpbmdJTy5TdHJpbmdJTy4KKyAgICAgIHJldHVybiB0eXBlKHJocykgPT0gdHlwZShzZWxmLl9jbGFzc19uYW1lKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKToKKyAgICByZXR1cm4gc3RyKHNlbGYuX2NsYXNzX25hbWUpCisKK2NsYXNzIElzQWxtb3N0KENvbXBhcmF0b3IpOgorICAiIiJDb21wYXJpc29uIGNsYXNzIHVzZWQgdG8gY2hlY2sgd2hldGhlciBhIHBhcmFtZXRlciBpcyBuZWFybHkgZXF1YWwKKyAgdG8gYSBnaXZlbiB2YWx1ZS4gIEdlbmVyYWxseSB1c2VmdWwgZm9yIGZsb2F0aW5nIHBvaW50IG51bWJlcnMuCisKKyAgRXhhbXBsZSBtb2NrX2Rhby5TZXRUaW1lb3V0KChJc0FsbW9zdCgzLjkpKSkKKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGZsb2F0X3ZhbHVlLCBwbGFjZXM9Nyk6CisgICAgIiIiSW5pdGlhbGl6ZSBJc0FsbW9zdC4KKworICAgIEFyZ3M6CisgICAgICBmbG9hdF92YWx1ZTogVGhlIHZhbHVlIGZvciBtYWtpbmcgdGhlIGNvbXBhcmlzb24uCisgICAgICBwbGFjZXM6IFRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcm91bmQgdG8uCisgICAgIiIiCisKKyAgICBzZWxmLl9mbG9hdF92YWx1ZSA9IGZsb2F0X3ZhbHVlCisgICAgc2VsZi5fcGxhY2VzID0gcGxhY2VzCisKKyAgZGVmIGVxdWFscyhzZWxmLCByaHMpOgorICAgICIiIkNoZWNrIHRvIHNlZSBpZiBSSFMgaXMgYWxtb3N0IGVxdWFsIHRvIGZsb2F0X3ZhbHVlCisKKyAgICBBcmdzOgorICAgICAgcmhzOiB0aGUgdmFsdWUgdG8gY29tcGFyZSB0byBmbG9hdF92YWx1ZQorCisgICAgUmV0dXJuczoKKyAgICAgIGJvb2wKKyAgICAiIiIKKworICAgIHRyeToKKyAgICAgIHJldHVybiByb3VuZChyaHMtc2VsZi5fZmxvYXRfdmFsdWUsIHNlbGYuX3BsYWNlcykgPT0gMAorICAgIGV4Y2VwdCBUeXBlRXJyb3I6CisgICAgICAjIFRoaXMgaXMgcHJvYmFibHkgYmVjYXVzZSBlaXRoZXIgZmxvYXRfdmFsdWUgb3IgcmhzIGlzIG5vdCBhIG51bWJlci4KKyAgICAgIHJldHVybiBGYWxzZQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKToKKyAgICByZXR1cm4gc3RyKHNlbGYuX2Zsb2F0X3ZhbHVlKQorCitjbGFzcyBTdHJDb250YWlucyhDb21wYXJhdG9yKToKKyAgIiIiQ29tcGFyaXNvbiBjbGFzcyB1c2VkIHRvIGNoZWNrIHdoZXRoZXIgYSBzdWJzdHJpbmcgZXhpc3RzIGluIGEKKyAgc3RyaW5nIHBhcmFtZXRlci4gIFRoaXMgY2FuIGJlIHVzZWZ1bCBpbiBtb2NraW5nIGEgZGF0YWJhc2Ugd2l0aCBTUUwKKyAgcGFzc2VkIGluIGFzIGEgc3RyaW5nIHBhcmFtZXRlciwgZm9yIGV4YW1wbGUuCisKKyAgRXhhbXBsZToKKyAgbW9ja19kYW8uUnVuUXVlcnkoU3RyQ29udGFpbnMoJ0lOICgxLCAyLCA0LCA1KScpKS5BbmRSZXR1cm4obW9ja19yZXN1bHQpCisgICIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBzZWFyY2hfc3RyaW5nKToKKyAgICAiIiJJbml0aWFsaXplLgorCisgICAgQXJnczoKKyAgICAgICMgc2VhcmNoX3N0cmluZzogdGhlIHN0cmluZyB5b3UgYXJlIHNlYXJjaGluZyBmb3IKKyAgICAgIHNlYXJjaF9zdHJpbmc6IHN0cgorICAgICIiIgorCisgICAgc2VsZi5fc2VhcmNoX3N0cmluZyA9IHNlYXJjaF9zdHJpbmcKKworICBkZWYgZXF1YWxzKHNlbGYsIHJocyk6CisgICAgIiIiQ2hlY2sgdG8gc2VlIGlmIHRoZSBzZWFyY2hfc3RyaW5nIGlzIGNvbnRhaW5lZCBpbiB0aGUgcmhzIHN0cmluZy4KKworICAgIEFyZ3M6CisgICAgICAjIHJoczogdGhlIHJpZ2h0IGhhbmQgc2lkZSBvZiB0aGUgdGVzdAorICAgICAgcmhzOiBvYmplY3QKKworICAgIFJldHVybnM6CisgICAgICBib29sCisgICAgIiIiCisKKyAgICB0cnk6CisgICAgICByZXR1cm4gcmhzLmZpbmQoc2VsZi5fc2VhcmNoX3N0cmluZykgPiAtMQorICAgIGV4Y2VwdCBFeGNlcHRpb246CisgICAgICByZXR1cm4gRmFsc2UKKworICBkZWYgX19yZXByX18oc2VsZik6CisgICAgcmV0dXJuICc8c3RyIGNvbnRhaW5pbmcgXCclc1wnPicgJSBzZWxmLl9zZWFyY2hfc3RyaW5nCisKKworY2xhc3MgUmVnZXgoQ29tcGFyYXRvcik6CisgICIiIkNoZWNrcyBpZiBhIHN0cmluZyBtYXRjaGVzIGEgcmVndWxhciBleHByZXNzaW9uLgorCisgIFRoaXMgdXNlcyBhIGdpdmVuIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBkZXRlcm1pbmUgZXF1YWxpdHkuCisgICIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXR0ZXJuLCBmbGFncz0wKToKKyAgICAiIiJJbml0aWFsaXplLgorCisgICAgQXJnczoKKyAgICAgICMgcGF0dGVybiBpcyB0aGUgcmVndWxhciBleHByZXNzaW9uIHRvIHNlYXJjaCBmb3IKKyAgICAgIHBhdHRlcm46IHN0cgorICAgICAgIyBmbGFncyBwYXNzZWQgdG8gcmUuY29tcGlsZSBmdW5jdGlvbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50CisgICAgICBmbGFnczogaW50CisgICAgIiIiCisKKyAgICBzZWxmLnJlZ2V4ID0gcmUuY29tcGlsZShwYXR0ZXJuLCBmbGFncz1mbGFncykKKworICBkZWYgZXF1YWxzKHNlbGYsIHJocyk6CisgICAgIiIiQ2hlY2sgdG8gc2VlIGlmIHJocyBtYXRjaGVzIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuLgorCisgICAgUmV0dXJuczoKKyAgICAgIGJvb2wKKyAgICAiIiIKKworICAgIHJldHVybiBzZWxmLnJlZ2V4LnNlYXJjaChyaHMpIGlzIG5vdCBOb25lCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHMgPSAnPHJlZ3VsYXIgZXhwcmVzc2lvbiBcJyVzXCcnICUgc2VsZi5yZWdleC5wYXR0ZXJuCisgICAgaWYgc2VsZi5yZWdleC5mbGFnczoKKyAgICAgIHMgKz0gJywgZmxhZ3M9JWQnICUgc2VsZi5yZWdleC5mbGFncworICAgIHMgKz0gJz4nCisgICAgcmV0dXJuIHMKKworCitjbGFzcyBJbihDb21wYXJhdG9yKToKKyAgIiIiQ2hlY2tzIHdoZXRoZXIgYW4gaXRlbSAob3Iga2V5KSBpcyBpbiBhIGxpc3QgKG9yIGRpY3QpIHBhcmFtZXRlci4KKworICBFeGFtcGxlOgorICBtb2NrX2Rhby5HZXRVc2Vyc0luZm8oSW4oJ2V4cGVjdGVkVXNlck5hbWUnKSkuQW5kUmV0dXJuKG1vY2tfcmVzdWx0KQorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZiwga2V5KToKKyAgICAiIiJJbml0aWFsaXplLgorCisgICAgQXJnczoKKyAgICAgICMga2V5IGlzIGFueSB0aGluZyB0aGF0IGNvdWxkIGJlIGluIGEgbGlzdCBvciBhIGtleSBpbiBhIGRpY3QKKyAgICAiIiIKKworICAgIHNlbGYuX2tleSA9IGtleQorCisgIGRlZiBlcXVhbHMoc2VsZiwgcmhzKToKKyAgICAiIiJDaGVjayB0byBzZWUgd2hldGhlciBrZXkgaXMgaW4gcmhzLgorCisgICAgQXJnczoKKyAgICAgIHJoczogZGljdAorCisgICAgUmV0dXJuczoKKyAgICAgIGJvb2wKKyAgICAiIiIKKworICAgIHJldHVybiBzZWxmLl9rZXkgaW4gcmhzCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiAnPHNlcXVlbmNlIG9yIG1hcCBjb250YWluaW5nIFwnJXNcJz4nICUgc2VsZi5fa2V5CisKKworY2xhc3MgQ29udGFpbnNLZXlWYWx1ZShDb21wYXJhdG9yKToKKyAgIiIiQ2hlY2tzIHdoZXRoZXIgYSBrZXkvdmFsdWUgcGFpciBpcyBpbiBhIGRpY3QgcGFyYW1ldGVyLgorCisgIEV4YW1wbGU6CisgIG1vY2tfZGFvLlVwZGF0ZVVzZXJzKENvbnRhaW5zS2V5VmFsdWUoJ3N0ZXZlcG0nLCBzdGV2ZXBtX3VzZXJfaW5mbykpCisgICIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBrZXksIHZhbHVlKToKKyAgICAiIiJJbml0aWFsaXplLgorCisgICAgQXJnczoKKyAgICAgICMga2V5OiBhIGtleSBpbiBhIGRpY3QKKyAgICAgICMgdmFsdWU6IHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlCisgICAgIiIiCisKKyAgICBzZWxmLl9rZXkgPSBrZXkKKyAgICBzZWxmLl92YWx1ZSA9IHZhbHVlCisKKyAgZGVmIGVxdWFscyhzZWxmLCByaHMpOgorICAgICIiIkNoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIGtleS92YWx1ZSBwYWlyIGlzIGluIHRoZSByaHMgZGljdC4KKworICAgIFJldHVybnM6CisgICAgICBib29sCisgICAgIiIiCisKKyAgICB0cnk6CisgICAgICByZXR1cm4gcmhzW3NlbGYuX2tleV0gPT0gc2VsZi5fdmFsdWUKKyAgICBleGNlcHQgRXhjZXB0aW9uOgorICAgICAgcmV0dXJuIEZhbHNlCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiAnPG1hcCBjb250YWluaW5nIHRoZSBlbnRyeSBcJyVzOiAlc1wnPicgJSAoc2VsZi5fa2V5LCBzZWxmLl92YWx1ZSkKKworCitjbGFzcyBTYW1lRWxlbWVudHNBcyhDb21wYXJhdG9yKToKKyAgIiIiQ2hlY2tzIHdoZXRoZXIgaXRlcmFibGVzIGNvbnRhaW4gdGhlIHNhbWUgZWxlbWVudHMgKGlnbm9yaW5nIG9yZGVyKS4KKworICBFeGFtcGxlOgorICBtb2NrX2Rhby5Qcm9jZXNzVXNlcnMoU2FtZUVsZW1lbnRzQXMoJ3N0ZXZlcG0nLCAnc2Fsb21ha2knKSkKKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGV4cGVjdGVkX3NlcSk6CisgICAgIiIiSW5pdGlhbGl6ZS4KKworICAgIEFyZ3M6CisgICAgICBleHBlY3RlZF9zZXE6IGEgc2VxdWVuY2UKKyAgICAiIiIKKworICAgIHNlbGYuX2V4cGVjdGVkX3NlcSA9IGV4cGVjdGVkX3NlcQorCisgIGRlZiBlcXVhbHMoc2VsZiwgYWN0dWFsX3NlcSk6CisgICAgIiIiQ2hlY2sgdG8gc2VlIHdoZXRoZXIgYWN0dWFsX3NlcSBoYXMgc2FtZSBlbGVtZW50cyBhcyBleHBlY3RlZF9zZXEuCisKKyAgICBBcmdzOgorICAgICAgYWN0dWFsX3NlcTogc2VxdWVuY2UKKworICAgIFJldHVybnM6CisgICAgICBib29sCisgICAgIiIiCisKKyAgICB0cnk6CisgICAgICBleHBlY3RlZCA9IGRpY3QoWyhlbGVtZW50LCBOb25lKSBmb3IgZWxlbWVudCBpbiBzZWxmLl9leHBlY3RlZF9zZXFdKQorICAgICAgYWN0dWFsID0gZGljdChbKGVsZW1lbnQsIE5vbmUpIGZvciBlbGVtZW50IGluIGFjdHVhbF9zZXFdKQorICAgIGV4Y2VwdCBUeXBlRXJyb3I6CisgICAgICAjIEZhbGwgYmFjayB0byBzbG93ZXIgbGlzdC1jb21wYXJlIGlmIGFueSBvZiB0aGUgb2JqZWN0cyBhcmUgdW5oYXNoYWJsZS4KKyAgICAgIGV4cGVjdGVkID0gbGlzdChzZWxmLl9leHBlY3RlZF9zZXEpCisgICAgICBhY3R1YWwgPSBsaXN0KGFjdHVhbF9zZXEpCisgICAgICBleHBlY3RlZC5zb3J0KCkKKyAgICAgIGFjdHVhbC5zb3J0KCkKKyAgICByZXR1cm4gZXhwZWN0ZWQgPT0gYWN0dWFsCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiAnPHNlcXVlbmNlIHdpdGggc2FtZSBlbGVtZW50cyBhcyBcJyVzXCc+JyAlIHNlbGYuX2V4cGVjdGVkX3NlcQorCisKK2NsYXNzIEFuZChDb21wYXJhdG9yKToKKyAgIiIiRXZhbHVhdGVzIG9uZSBvciBtb3JlIENvbXBhcmF0b3JzIG9uIFJIUyBhbmQgcmV0dXJucyBhbiBBTkQgb2YgdGhlIHJlc3VsdHMuCisgICIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCAqYXJncyk6CisgICAgIiIiSW5pdGlhbGl6ZS4KKworICAgIEFyZ3M6CisgICAgICAqYXJnczogT25lIG9yIG1vcmUgQ29tcGFyYXRvcgorICAgICIiIgorCisgICAgc2VsZi5fY29tcGFyYXRvcnMgPSBhcmdzCisKKyAgZGVmIGVxdWFscyhzZWxmLCByaHMpOgorICAgICIiIkNoZWNrcyB3aGV0aGVyIGFsbCBDb21wYXJhdG9ycyBhcmUgZXF1YWwgdG8gcmhzLgorCisgICAgQXJnczoKKyAgICAgICMgcmhzOiBjYW4gYmUgYW55dGhpbmcKKworICAgIFJldHVybnM6CisgICAgICBib29sCisgICAgIiIiCisKKyAgICBmb3IgY29tcGFyYXRvciBpbiBzZWxmLl9jb21wYXJhdG9yczoKKyAgICAgIGlmIG5vdCBjb21wYXJhdG9yLmVxdWFscyhyaHMpOgorICAgICAgICByZXR1cm4gRmFsc2UKKworICAgIHJldHVybiBUcnVlCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiAnPEFORCAlcz4nICUgc3RyKHNlbGYuX2NvbXBhcmF0b3JzKQorCisKK2NsYXNzIE9yKENvbXBhcmF0b3IpOgorICAiIiJFdmFsdWF0ZXMgb25lIG9yIG1vcmUgQ29tcGFyYXRvcnMgb24gUkhTIGFuZCByZXR1cm5zIGFuIE9SIG9mIHRoZSByZXN1bHRzLgorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgKmFyZ3MpOgorICAgICIiIkluaXRpYWxpemUuCisKKyAgICBBcmdzOgorICAgICAgKmFyZ3M6IE9uZSBvciBtb3JlIE1veCBjb21wYXJhdG9ycworICAgICIiIgorCisgICAgc2VsZi5fY29tcGFyYXRvcnMgPSBhcmdzCisKKyAgZGVmIGVxdWFscyhzZWxmLCByaHMpOgorICAgICIiIkNoZWNrcyB3aGV0aGVyIGFueSBDb21wYXJhdG9yIGlzIGVxdWFsIHRvIHJocy4KKworICAgIEFyZ3M6CisgICAgICAjIHJoczogY2FuIGJlIGFueXRoaW5nCisKKyAgICBSZXR1cm5zOgorICAgICAgYm9vbAorICAgICIiIgorCisgICAgZm9yIGNvbXBhcmF0b3IgaW4gc2VsZi5fY29tcGFyYXRvcnM6CisgICAgICBpZiBjb21wYXJhdG9yLmVxdWFscyhyaHMpOgorICAgICAgICByZXR1cm4gVHJ1ZQorCisgICAgcmV0dXJuIEZhbHNlCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiAnPE9SICVzPicgJSBzdHIoc2VsZi5fY29tcGFyYXRvcnMpCisKKworY2xhc3MgRnVuYyhDb21wYXJhdG9yKToKKyAgIiIiQ2FsbCBhIGZ1bmN0aW9uIHRoYXQgc2hvdWxkIHZlcmlmeSB0aGUgcGFyYW1ldGVyIHBhc3NlZCBpbiBpcyBjb3JyZWN0LgorCisgIFlvdSBtYXkgbmVlZCB0aGUgYWJpbGl0eSB0byBwZXJmb3JtIG1vcmUgYWR2YW5jZWQgb3BlcmF0aW9ucyBvbiB0aGUgcGFyYW1ldGVyCisgIGluIG9yZGVyIHRvIHZhbGlkYXRlIGl0LiAgWW91IGNhbiB1c2UgdGhpcyB0byBoYXZlIGEgY2FsbGFibGUgdmFsaWRhdGUgYW55CisgIHBhcmFtZXRlci4gVGhlIGNhbGxhYmxlIHNob3VsZCByZXR1cm4gZWl0aGVyIFRydWUgb3IgRmFsc2UuCisKKworICBFeGFtcGxlOgorCisgIGRlZiBteVBhcmFtVmFsaWRhdG9yKHBhcmFtKToKKyAgICAjIEFkdmFuY2VkIGxvZ2ljIGhlcmUKKyAgICByZXR1cm4gVHJ1ZQorCisgIG1vY2tfZGFvLkRvU29tZXRoaW5nKEZ1bmMobXlQYXJhbVZhbGlkYXRvciksIHRydWUpCisgICIiIgorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBmdW5jKToKKyAgICAiIiJJbml0aWFsaXplLgorCisgICAgQXJnczoKKyAgICAgIGZ1bmM6IGNhbGxhYmxlIHRoYXQgdGFrZXMgb25lIHBhcmFtZXRlciBhbmQgcmV0dXJucyBhIGJvb2wKKyAgICAiIiIKKworICAgIHNlbGYuX2Z1bmMgPSBmdW5jCisKKyAgZGVmIGVxdWFscyhzZWxmLCByaHMpOgorICAgICIiIlRlc3Qgd2hldGhlciByaHMgcGFzc2VzIHRoZSBmdW5jdGlvbiB0ZXN0LgorCisgICAgcmhzIGlzIHBhc3NlZCBpbnRvIGZ1bmMuCisKKyAgICBBcmdzOgorICAgICAgcmhzOiBhbnkgcHl0aG9uIG9iamVjdAorCisgICAgUmV0dXJuczoKKyAgICAgIHRoZSByZXN1bHQgb2YgZnVuYyhyaHMpCisgICAgIiIiCisKKyAgICByZXR1cm4gc2VsZi5fZnVuYyhyaHMpCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiBzdHIoc2VsZi5fZnVuYykKKworCitjbGFzcyBJZ25vcmVBcmcoQ29tcGFyYXRvcik6CisgICIiIklnbm9yZSBhbiBhcmd1bWVudC4KKworICBUaGlzIGNhbiBiZSB1c2VkIHdoZW4gd2UgZG9uJ3QgY2FyZSBhYm91dCBhbiBhcmd1bWVudCBvZiBhIG1ldGhvZCBjYWxsLgorCisgIEV4YW1wbGU6CisgICMgQ2hlY2sgaWYgQ2FzdE1hZ2ljIGlzIGNhbGxlZCB3aXRoIDMgYXMgZmlyc3QgYXJnIGFuZCAnZGlzYXBwZWFyJyBhcyB0aGlyZC4KKyAgbXltb2NrLkNhc3RNYWdpYygzLCBJZ25vcmVBcmcoKSwgJ2Rpc2FwcGVhcicpCisgICIiIgorCisgIGRlZiBlcXVhbHMoc2VsZiwgdW51c2VkX3Jocyk6CisgICAgIiIiSWdub3JlcyBhcmd1bWVudHMgYW5kIHJldHVybnMgVHJ1ZS4KKworICAgIEFyZ3M6CisgICAgICB1bnVzZWRfcmhzOiBhbnkgcHl0aG9uIG9iamVjdAorCisgICAgUmV0dXJuczoKKyAgICAgIGFsd2F5cyByZXR1cm5zIFRydWUKKyAgICAiIiIKKworICAgIHJldHVybiBUcnVlCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOgorICAgIHJldHVybiAnPElnbm9yZUFyZz4nCisKKworY2xhc3MgTWV0aG9kR3JvdXAob2JqZWN0KToKKyAgIiIiQmFzZSBjbGFzcyBjb250YWluaW5nIGNvbW1vbiBiZWhhdmlvdXIgZm9yIE1ldGhvZEdyb3Vwcy4iIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgZ3JvdXBfbmFtZSk6CisgICAgc2VsZi5fZ3JvdXBfbmFtZSA9IGdyb3VwX25hbWUKKworICBkZWYgZ3JvdXBfbmFtZShzZWxmKToKKyAgICByZXR1cm4gc2VsZi5fZ3JvdXBfbmFtZQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOgorICAgIHJldHVybiAnPCVzICIlcyI+JyAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXywgc2VsZi5fZ3JvdXBfbmFtZSkKKworICBkZWYgQWRkTWV0aG9kKHNlbGYsIG1vY2tfbWV0aG9kKToKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKKyAgZGVmIE1ldGhvZENhbGxlZChzZWxmLCBtb2NrX21ldGhvZCk6CisgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisgIGRlZiBJc1NhdGlzZmllZChzZWxmKToKKyAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yCisKK2NsYXNzIFVub3JkZXJlZEdyb3VwKE1ldGhvZEdyb3VwKToKKyAgIiIiVW5vcmRlcmVkR3JvdXAgaG9sZHMgYSBzZXQgb2YgbWV0aG9kIGNhbGxzIHRoYXQgbWF5IG9jY3VyIGluIGFueSBvcmRlci4KKworICBUaGlzIGNvbnN0cnVjdCBpcyBoZWxwZnVsIGZvciBub24tZGV0ZXJtaW5pc3RpYyBldmVudHMsIHN1Y2ggYXMgaXRlcmF0aW5nCisgIG92ZXIgdGhlIGtleXMgb2YgYSBkaWN0LgorICAiIiIKKworICBkZWYgX19pbml0X18oc2VsZiwgZ3JvdXBfbmFtZSk6CisgICAgc3VwZXIoVW5vcmRlcmVkR3JvdXAsIHNlbGYpLl9faW5pdF9fKGdyb3VwX25hbWUpCisgICAgc2VsZi5fbWV0aG9kcyA9IFtdCisKKyAgZGVmIEFkZE1ldGhvZChzZWxmLCBtb2NrX21ldGhvZCk6CisgICAgIiIiQWRkIGEgbWV0aG9kIHRvIHRoaXMgZ3JvdXAuCisKKyAgICBBcmdzOgorICAgICAgbW9ja19tZXRob2Q6IEEgbW9jayBtZXRob2QgdG8gYmUgYWRkZWQgdG8gdGhpcyBncm91cC4KKyAgICAiIiIKKworICAgIHNlbGYuX21ldGhvZHMuYXBwZW5kKG1vY2tfbWV0aG9kKQorCisgIGRlZiBNZXRob2RDYWxsZWQoc2VsZiwgbW9ja19tZXRob2QpOgorICAgICIiIlJlbW92ZSBhIG1ldGhvZCBjYWxsIGZyb20gdGhlIGdyb3VwLgorCisgICAgSWYgdGhlIG1ldGhvZCBpcyBub3QgaW4gdGhlIHNldCwgYW4gVW5leHBlY3RlZE1ldGhvZENhbGxFcnJvciB3aWxsIGJlCisgICAgcmFpc2VkLgorCisgICAgQXJnczoKKyAgICAgIG1vY2tfbWV0aG9kOiBhIG1vY2sgbWV0aG9kIHRoYXQgc2hvdWxkIGJlIGVxdWFsIHRvIGEgbWV0aG9kIGluIHRoZSBncm91cC4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgbW9jayBtZXRob2QgZnJvbSB0aGUgZ3JvdXAKKworICAgIFJhaXNlczoKKyAgICAgIFVuZXhwZWN0ZWRNZXRob2RDYWxsRXJyb3IgaWYgdGhlIG1vY2tfbWV0aG9kIHdhcyBub3QgaW4gdGhlIGdyb3VwLgorICAgICIiIgorCisgICAgIyBDaGVjayB0byBzZWUgaWYgdGhpcyBtZXRob2QgZXhpc3RzLCBhbmQgaWYgc28sIHJlbW92ZSBpdCBmcm9tIHRoZSBzZXQKKyAgICAjIGFuZCByZXR1cm4gaXQuCisgICAgZm9yIG1ldGhvZCBpbiBzZWxmLl9tZXRob2RzOgorICAgICAgaWYgbWV0aG9kID09IG1vY2tfbWV0aG9kOgorICAgICAgICAjIFJlbW92ZSB0aGUgY2FsbGVkIG1vY2tfbWV0aG9kIGluc3RlYWQgb2YgdGhlIG1ldGhvZCBpbiB0aGUgZ3JvdXAuCisgICAgICAgICMgVGhlIGNhbGxlZCBtZXRob2Qgd2lsbCBtYXRjaCBhbnkgY29tcGFyYXRvcnMgd2hlbiBlcXVhbGl0eSBpcyBjaGVja2VkCisgICAgICAgICMgZHVyaW5nIHJlbW92YWwuICBUaGUgbWV0aG9kIGluIHRoZSBncm91cCBjb3VsZCBwYXNzIGEgY29tcGFyYXRvciB0bworICAgICAgICAjIGFub3RoZXIgY29tcGFyYXRvciBkdXJpbmcgdGhlIGVxdWFsaXR5IGNoZWNrLgorICAgICAgICBzZWxmLl9tZXRob2RzLnJlbW92ZShtb2NrX21ldGhvZCkKKworICAgICAgICAjIElmIHRoaXMgZ3JvdXAgaXMgbm90IGVtcHR5LCBwdXQgaXQgYmFjayBhdCB0aGUgaGVhZCBvZiB0aGUgcXVldWUuCisgICAgICAgIGlmIG5vdCBzZWxmLklzU2F0aXNmaWVkKCk6CisgICAgICAgICAgbW9ja19tZXRob2QuX2NhbGxfcXVldWUuYXBwZW5kbGVmdChzZWxmKQorCisgICAgICAgIHJldHVybiBzZWxmLCBtZXRob2QKKworICAgIHJhaXNlIFVuZXhwZWN0ZWRNZXRob2RDYWxsRXJyb3IobW9ja19tZXRob2QsIHNlbGYpCisKKyAgZGVmIElzU2F0aXNmaWVkKHNlbGYpOgorICAgICIiIlJldHVybiBUcnVlIGlmIHRoZXJlIGFyZSBub3QgYW55IG1ldGhvZHMgaW4gdGhpcyBncm91cC4iIiIKKworICAgIHJldHVybiBsZW4oc2VsZi5fbWV0aG9kcykgPT0gMAorCisKK2NsYXNzIE11bHRpcGxlVGltZXNHcm91cChNZXRob2RHcm91cCk6CisgICIiIk11bHRpcGxlVGltZXNHcm91cCBob2xkcyBtZXRob2RzIHRoYXQgbWF5IGJlIGNhbGxlZCBhbnkgbnVtYmVyIG9mIHRpbWVzLgorCisgIE5vdGU6IEVhY2ggbWV0aG9kIG11c3QgYmUgY2FsbGVkIGF0IGxlYXN0IG9uY2UuCisKKyAgVGhpcyBpcyBoZWxwZnVsLCBpZiB5b3UgZG9uJ3Qga25vdyBvciBjYXJlIGhvdyBtYW55IHRpbWVzIGEgbWV0aG9kIGlzIGNhbGxlZC4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGdyb3VwX25hbWUpOgorICAgIHN1cGVyKE11bHRpcGxlVGltZXNHcm91cCwgc2VsZikuX19pbml0X18oZ3JvdXBfbmFtZSkKKyAgICBzZWxmLl9tZXRob2RzID0gc2V0KCkKKyAgICBzZWxmLl9tZXRob2RzX2NhbGxlZCA9IHNldCgpCisKKyAgZGVmIEFkZE1ldGhvZChzZWxmLCBtb2NrX21ldGhvZCk6CisgICAgIiIiQWRkIGEgbWV0aG9kIHRvIHRoaXMgZ3JvdXAuCisKKyAgICBBcmdzOgorICAgICAgbW9ja19tZXRob2Q6IEEgbW9jayBtZXRob2QgdG8gYmUgYWRkZWQgdG8gdGhpcyBncm91cC4KKyAgICAiIiIKKworICAgIHNlbGYuX21ldGhvZHMuYWRkKG1vY2tfbWV0aG9kKQorCisgIGRlZiBNZXRob2RDYWxsZWQoc2VsZiwgbW9ja19tZXRob2QpOgorICAgICIiIlJlbW92ZSBhIG1ldGhvZCBjYWxsIGZyb20gdGhlIGdyb3VwLgorCisgICAgSWYgdGhlIG1ldGhvZCBpcyBub3QgaW4gdGhlIHNldCwgYW4gVW5leHBlY3RlZE1ldGhvZENhbGxFcnJvciB3aWxsIGJlCisgICAgcmFpc2VkLgorCisgICAgQXJnczoKKyAgICAgIG1vY2tfbWV0aG9kOiBhIG1vY2sgbWV0aG9kIHRoYXQgc2hvdWxkIGJlIGVxdWFsIHRvIGEgbWV0aG9kIGluIHRoZSBncm91cC4KKworICAgIFJldHVybnM6CisgICAgICBUaGUgbW9jayBtZXRob2QgZnJvbSB0aGUgZ3JvdXAKKworICAgIFJhaXNlczoKKyAgICAgIFVuZXhwZWN0ZWRNZXRob2RDYWxsRXJyb3IgaWYgdGhlIG1vY2tfbWV0aG9kIHdhcyBub3QgaW4gdGhlIGdyb3VwLgorICAgICIiIgorCisgICAgIyBDaGVjayB0byBzZWUgaWYgdGhpcyBtZXRob2QgZXhpc3RzLCBhbmQgaWYgc28gYWRkIGl0IHRvIHRoZSBzZXQgb2YKKyAgICAjIGNhbGxlZCBtZXRob2RzLgorCisgICAgZm9yIG1ldGhvZCBpbiBzZWxmLl9tZXRob2RzOgorICAgICAgaWYgbWV0aG9kID09IG1vY2tfbWV0aG9kOgorICAgICAgICBzZWxmLl9tZXRob2RzX2NhbGxlZC5hZGQobW9ja19tZXRob2QpCisgICAgICAgICMgQWx3YXlzIHB1dCB0aGlzIGdyb3VwIGJhY2sgb24gdG9wIG9mIHRoZSBxdWV1ZSwgYmVjYXVzZSB3ZSBkb24ndCBrbm93CisgICAgICAgICMgd2hlbiB3ZSBhcmUgZG9uZS4KKyAgICAgICAgbW9ja19tZXRob2QuX2NhbGxfcXVldWUuYXBwZW5kbGVmdChzZWxmKQorICAgICAgICByZXR1cm4gc2VsZiwgbWV0aG9kCisKKyAgICBpZiBzZWxmLklzU2F0aXNmaWVkKCk6CisgICAgICBuZXh0X21ldGhvZCA9IG1vY2tfbWV0aG9kLl9Qb3BOZXh0TWV0aG9kKCk7CisgICAgICByZXR1cm4gbmV4dF9tZXRob2QsIE5vbmUKKyAgICBlbHNlOgorICAgICAgcmFpc2UgVW5leHBlY3RlZE1ldGhvZENhbGxFcnJvcihtb2NrX21ldGhvZCwgc2VsZikKKworICBkZWYgSXNTYXRpc2ZpZWQoc2VsZik6CisgICAgIiIiUmV0dXJuIFRydWUgaWYgYWxsIG1ldGhvZHMgaW4gdGhpcyBncm91cCBhcmUgY2FsbGVkIGF0IGxlYXN0IG9uY2UuIiIiCisgICAgIyBOT1RFKHBzeWNobyk6IFdlIGNhbid0IHVzZSB0aGUgc2ltcGxlIHNldCBkaWZmZXJlbmNlIGhlcmUgYmVjYXVzZSB3ZSB3YW50CisgICAgIyB0byBtYXRjaCBkaWZmZXJlbnQgcGFyYW1ldGVycyB3aGljaCBhcmUgY29uc2lkZXJlZCB0aGUgc2FtZSBlLmcuIElzQShzdHIpCisgICAgIyBhbmQgc29tZSBzdHJpbmcuIFRoaXMgc29sdXRpb24gaXMgTyhuXjIpIGJ1dCBuIHNob3VsZCBiZSBzbWFsbC4KKyAgICB0bXAgPSBzZWxmLl9tZXRob2RzLmNvcHkoKQorICAgIGZvciBjYWxsZWQgaW4gc2VsZi5fbWV0aG9kc19jYWxsZWQ6CisgICAgICBmb3IgZXhwZWN0ZWQgaW4gdG1wOgorICAgICAgICBpZiBjYWxsZWQgPT0gZXhwZWN0ZWQ6CisgICAgICAgICAgdG1wLnJlbW92ZShleHBlY3RlZCkKKyAgICAgICAgICBpZiBub3QgdG1wOgorICAgICAgICAgICAgcmV0dXJuIFRydWUKKyAgICAgICAgICBicmVhaworICAgIHJldHVybiBGYWxzZQorCisKK2NsYXNzIE1veE1ldGFUZXN0QmFzZSh0eXBlKToKKyAgIiIiTWV0YWNsYXNzIHRvIGFkZCBtb3ggY2xlYW51cCBhbmQgdmVyaWZpY2F0aW9uIHRvIGV2ZXJ5IHRlc3QuCisKKyAgQXMgdGhlIG1veCB1bml0IHRlc3RpbmcgY2xhc3MgaXMgYmVpbmcgY29uc3RydWN0ZWQgKE1veFRlc3RCYXNlIG9yIGEKKyAgc3ViY2xhc3MpLCB0aGlzIG1ldGFjbGFzcyB3aWxsIG1vZGlmeSBhbGwgdGVzdCBmdW5jdGlvbnMgdG8gY2FsbCB0aGUKKyAgQ2xlYW5VcE1veCBtZXRob2Qgb2YgdGhlIHRlc3QgY2xhc3MgYWZ0ZXIgdGhleSBmaW5pc2guIFRoaXMgbWVhbnMgdGhhdAorICB1bnN0dWJiaW5nIGFuZCB2ZXJpZnlpbmcgd2lsbCBoYXBwZW4gZm9yIGV2ZXJ5IHRlc3Qgd2l0aCBubyBhZGRpdGlvbmFsIGNvZGUsCisgIGFuZCBhbnkgZmFpbHVyZXMgd2lsbCByZXN1bHQgaW4gdGVzdCBmYWlsdXJlcyBhcyBvcHBvc2VkIHRvIGVycm9ycy4KKyAgIiIiCisKKyAgZGVmIF9faW5pdF9fKGNscywgbmFtZSwgYmFzZXMsIGQpOgorICAgIHR5cGUuX19pbml0X18oY2xzLCBuYW1lLCBiYXNlcywgZCkKKworICAgICMgYWxzbyBnZXQgYWxsIHRoZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGJhc2UgY2xhc3NlcyB0byBhY2NvdW50CisgICAgIyBmb3IgYSBjYXNlIHdoZW4gdGVzdCBjbGFzcyBpcyBub3QgdGhlIGltbWVkaWF0ZSBjaGlsZCBvZiBNb3hUZXN0QmFzZQorICAgIGZvciBiYXNlIGluIGJhc2VzOgorICAgICAgZm9yIGF0dHJfbmFtZSBpbiBkaXIoYmFzZSk6CisgICAgICAgIGRbYXR0cl9uYW1lXSA9IGdldGF0dHIoYmFzZSwgYXR0cl9uYW1lKQorCisgICAgZm9yIGZ1bmNfbmFtZSwgZnVuYyBpbiBkLml0ZW1zKCk6CisgICAgICBpZiBmdW5jX25hbWUuc3RhcnRzd2l0aCgndGVzdCcpIGFuZCBjYWxsYWJsZShmdW5jKToKKyAgICAgICAgc2V0YXR0cihjbHMsIGZ1bmNfbmFtZSwgTW94TWV0YVRlc3RCYXNlLkNsZWFuVXBUZXN0KGNscywgZnVuYykpCisKKyAgQHN0YXRpY21ldGhvZAorICBkZWYgQ2xlYW5VcFRlc3QoY2xzLCBmdW5jKToKKyAgICAiIiJBZGRzIE1veCBjbGVhbnVwIGNvZGUgdG8gYW55IE1veFRlc3RCYXNlIG1ldGhvZC4KKworICAgIEFsd2F5cyB1bnNldHMgc3R1YnMgYWZ0ZXIgYSB0ZXN0LiBXaWxsIHZlcmlmeSBhbGwgbW9ja3MgZm9yIHRlc3RzIHRoYXQKKyAgICBvdGhlcndpc2UgcGFzcy4KKworICAgIEFyZ3M6CisgICAgICBjbHM6IE1veFRlc3RCYXNlIG9yIHN1YmNsYXNzOyB0aGUgY2xhc3Mgd2hvc2UgdGVzdCBtZXRob2Qgd2UgYXJlIGFsdGVyaW5nLgorICAgICAgZnVuYzogbWV0aG9kOyB0aGUgbWV0aG9kIG9mIHRoZSBNb3hUZXN0QmFzZSB0ZXN0IGNsYXNzIHdlIHdpc2ggdG8gYWx0ZXIuCisKKyAgICBSZXR1cm5zOgorICAgICAgVGhlIG1vZGlmaWVkIG1ldGhvZC4KKyAgICAiIiIKKyAgICBkZWYgbmV3X21ldGhvZChzZWxmLCAqYXJncywgKiprd2FyZ3MpOgorICAgICAgbW94X29iaiA9IGdldGF0dHIoc2VsZiwgJ21veCcsIE5vbmUpCisgICAgICBjbGVhbnVwX21veCA9IEZhbHNlCisgICAgICBpZiBtb3hfb2JqIGFuZCBpc2luc3RhbmNlKG1veF9vYmosIE1veCk6CisgICAgICAgIGNsZWFudXBfbW94ID0gVHJ1ZQorICAgICAgdHJ5OgorICAgICAgICBmdW5jKHNlbGYsICphcmdzLCAqKmt3YXJncykKKyAgICAgIGZpbmFsbHk6CisgICAgICAgIGlmIGNsZWFudXBfbW94OgorICAgICAgICAgIG1veF9vYmouVW5zZXRTdHVicygpCisgICAgICBpZiBjbGVhbnVwX21veDoKKyAgICAgICAgbW94X29iai5WZXJpZnlBbGwoKQorICAgIG5ld19tZXRob2QuX19uYW1lX18gPSBmdW5jLl9fbmFtZV9fCisgICAgbmV3X21ldGhvZC5fX2RvY19fID0gZnVuYy5fX2RvY19fCisgICAgbmV3X21ldGhvZC5fX21vZHVsZV9fID0gZnVuYy5fX21vZHVsZV9fCisgICAgcmV0dXJuIG5ld19tZXRob2QKKworCitjbGFzcyBNb3hUZXN0QmFzZSh1bml0dGVzdC5UZXN0Q2FzZSk6CisgICIiIkNvbnZlbmllbmNlIHRlc3QgY2xhc3MgdG8gbWFrZSBzdHViYmluZyBlYXNpZXIuCisKKyAgU2V0cyB1cCBhICJtb3giIGF0dHJpYnV0ZSB3aGljaCBpcyBhbiBpbnN0YW5jZSBvZiBNb3ggLSBhbnkgbW94IHRlc3RzIHdpbGwKKyAgd2FudCB0aGlzLiBBbHNvIGF1dG9tYXRpY2FsbHkgdW5zZXRzIGFueSBzdHVicyBhbmQgdmVyaWZpZXMgdGhhdCBhbGwgbW9jaworICBtZXRob2RzIGhhdmUgYmVlbiBjYWxsZWQgYXQgdGhlIGVuZCBvZiBlYWNoIHRlc3QsIGVsaW1pbmF0aW5nIGJvaWxlcnBsYXRlCisgIGNvZGUuCisgICIiIgorCisgIF9fbWV0YWNsYXNzX18gPSBNb3hNZXRhVGVzdEJhc2UKKworICBkZWYgc2V0VXAoc2VsZik6CisgICAgc2VsZi5tb3ggPSBNb3goKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL3NldHVwLnB5IGIvcHl0aG9uL3NldHVwLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmMxODgxOGUKLS0tIC9kZXYvbnVsbAorKysgYi9weXRob24vc2V0dXAucHkKQEAgLTAsMCArMSwyMTEgQEAKKyMhIC91c3IvYmluL3B5dGhvbgorIworIyBTZWUgUkVBRE1FIGZvciB1c2FnZSBpbnN0cnVjdGlvbnMuCitpbXBvcnQgc3lzCitpbXBvcnQgb3MKK2ltcG9ydCBzdWJwcm9jZXNzCisKKyMgV2UgbXVzdCB1c2Ugc2V0dXB0b29scywgbm90IGRpc3R1dGlscywgYmVjYXVzZSB3ZSBuZWVkIHRvIHVzZSB0aGUKKyMgbmFtZXNwYWNlX3BhY2thZ2VzIG9wdGlvbiBmb3IgdGhlICJnb29nbGUiIHBhY2thZ2UuCit0cnk6CisgIGZyb20gc2V0dXB0b29scyBpbXBvcnQgc2V0dXAsIEV4dGVuc2lvbgorZXhjZXB0IEltcG9ydEVycm9yOgorICB0cnk6CisgICAgZnJvbSBlel9zZXR1cCBpbXBvcnQgdXNlX3NldHVwdG9vbHMKKyAgICB1c2Vfc2V0dXB0b29scygpCisgICAgZnJvbSBzZXR1cHRvb2xzIGltcG9ydCBzZXR1cCwgRXh0ZW5zaW9uCisgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgICBzeXMuc3RkZXJyLndyaXRlKAorICAgICAgICAiQ291bGQgbm90IGltcG9ydCBzZXR1cHRvb2xzOyBtYWtlIHN1cmUgeW91IGhhdmUgc2V0dXB0b29scyBvciAiCisgICAgICAgICJlel9zZXR1cCBpbnN0YWxsZWQuXG4iKQorICAgIHJhaXNlCitmcm9tIGRpc3R1dGlscy5jb21tYW5kLmNsZWFuIGltcG9ydCBjbGVhbiBhcyBfY2xlYW4KK2lmIHN5cy52ZXJzaW9uX2luZm9bMF0gPj0gMzoKKyAgICAjIFB5dGhvbiAzCisgICAgZnJvbSBkaXN0dXRpbHMuY29tbWFuZC5idWlsZF9weSBpbXBvcnQgYnVpbGRfcHlfMnRvMyBhcyBfYnVpbGRfcHkKK2Vsc2U6CisgICAgIyBQeXRob24gMgorICAgIGZyb20gZGlzdHV0aWxzLmNvbW1hbmQuYnVpbGRfcHkgaW1wb3J0IGJ1aWxkX3B5IGFzIF9idWlsZF9weQorZnJvbSBkaXN0dXRpbHMuc3Bhd24gaW1wb3J0IGZpbmRfZXhlY3V0YWJsZQorCittYWludGFpbmVyX2VtYWlsID0gInByb3RvYnVmQGdvb2dsZWdyb3Vwcy5jb20iCisKKyMgRmluZCB0aGUgUHJvdG9jb2wgQ29tcGlsZXIuCitpZiAnUFJPVE9DJyBpbiBvcy5lbnZpcm9uIGFuZCBvcy5wYXRoLmV4aXN0cyhvcy5lbnZpcm9uWydQUk9UT0MnXSk6CisgIHByb3RvYyA9IG9zLmVudmlyb25bJ1BST1RPQyddCitlbGlmIG9zLnBhdGguZXhpc3RzKCIuLi9zcmMvcHJvdG9jIik6CisgIHByb3RvYyA9ICIuLi9zcmMvcHJvdG9jIgorZWxpZiBvcy5wYXRoLmV4aXN0cygiLi4vc3JjL3Byb3RvYy5leGUiKToKKyAgcHJvdG9jID0gIi4uL3NyYy9wcm90b2MuZXhlIgorZWxpZiBvcy5wYXRoLmV4aXN0cygiLi4vdnNwcm9qZWN0cy9EZWJ1Zy9wcm90b2MuZXhlIik6CisgIHByb3RvYyA9ICIuLi92c3Byb2plY3RzL0RlYnVnL3Byb3RvYy5leGUiCitlbGlmIG9zLnBhdGguZXhpc3RzKCIuLi92c3Byb2plY3RzL1JlbGVhc2UvcHJvdG9jLmV4ZSIpOgorICBwcm90b2MgPSAiLi4vdnNwcm9qZWN0cy9SZWxlYXNlL3Byb3RvYy5leGUiCitlbHNlOgorICBwcm90b2MgPSBmaW5kX2V4ZWN1dGFibGUoInByb3RvYyIpCisKK2RlZiBHZXRWZXJzaW9uKCk6CisgICIiIkdldHMgdGhlIHZlcnNpb24gZnJvbSBnb29nbGUvcHJvdG9idWYvX19pbml0X18ucHkKKworICBEbyBub3QgaW1wb3J0IGdvb2dsZS5wcm90b2J1Zi5fX2luaXRfXyBkaXJlY3RseSwgYmVjYXVzZSBhbiBpbnN0YWxsZWQgcHJvdG9idWYKKyAgbGlicmFyeSBtYXkgYmUgbG9hZGVkIGluc3RlYWQuCisKKyAgIiIiCisgIHdpdGggb3Blbihvcy5wYXRoLmpvaW4oJ2dvb2dsZScsICdwcm90b2J1ZicsICdfX2luaXRfXy5weScpKSBhcyB2ZXJzaW9uX2ZpbGU6CisgICAgZXhlYyh2ZXJzaW9uX2ZpbGUucmVhZCgpKQorICAgIHJldHVybiBfX3ZlcnNpb25fXworCisKK2RlZiBnZW5lcmF0ZV9wcm90byhzb3VyY2UpOgorICAiIiJJbnZva2VzIHRoZSBQcm90b2NvbCBDb21waWxlciB0byBnZW5lcmF0ZSBhIF9wYjIucHkgZnJvbSB0aGUgZ2l2ZW4KKyAgLnByb3RvIGZpbGUuICBEb2VzIG5vdGhpbmcgaWYgdGhlIG91dHB1dCBhbHJlYWR5IGV4aXN0cyBhbmQgaXMgbmV3ZXIgdGhhbgorICB0aGUgaW5wdXQuIiIiCisKKyAgb3V0cHV0ID0gc291cmNlLnJlcGxhY2UoIi5wcm90byIsICJfcGIyLnB5IikucmVwbGFjZSgiLi4vc3JjLyIsICIiKQorCisgIGlmIChub3Qgb3MucGF0aC5leGlzdHMob3V0cHV0KSBvcgorICAgICAgKG9zLnBhdGguZXhpc3RzKHNvdXJjZSkgYW5kCisgICAgICAgb3MucGF0aC5nZXRtdGltZShzb3VyY2UpID4gb3MucGF0aC5nZXRtdGltZShvdXRwdXQpKSk6CisgICAgcHJpbnQgKCJHZW5lcmF0aW5nICVzLi4uIiAlIG91dHB1dCkKKworICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhzb3VyY2UpOgorICAgICAgc3lzLnN0ZGVyci53cml0ZSgiQ2FuJ3QgZmluZCByZXF1aXJlZCBmaWxlOiAlc1xuIiAlIHNvdXJjZSkKKyAgICAgIHN5cy5leGl0KC0xKQorCisgICAgaWYgcHJvdG9jID09IE5vbmU6CisgICAgICBzeXMuc3RkZXJyLndyaXRlKAorICAgICAgICAgICJwcm90b2MgaXMgbm90IGluc3RhbGxlZCBub3IgZm91bmQgaW4gLi4vc3JjLiAgUGxlYXNlIGNvbXBpbGUgaXQgIgorICAgICAgICAgICJvciBpbnN0YWxsIHRoZSBiaW5hcnkgcGFja2FnZS5cbiIpCisgICAgICBzeXMuZXhpdCgtMSkKKworICAgIHByb3RvY19jb21tYW5kID0gWyBwcm90b2MsICItSS4uL3NyYyIsICItSS4iLCAiLS1weXRob25fb3V0PS4iLCBzb3VyY2UgXQorICAgIGlmIHN1YnByb2Nlc3MuY2FsbChwcm90b2NfY29tbWFuZCkgIT0gMDoKKyAgICAgIHN5cy5leGl0KC0xKQorCitkZWYgR2VuZXJhdGVVbml0dGVzdFByb3RvcygpOgorICBnZW5lcmF0ZV9wcm90bygiLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byIpCisgIGdlbmVyYXRlX3Byb3RvKCIuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIikKKyAgZ2VuZXJhdGVfcHJvdG8oIi4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvIikKKyAgZ2VuZXJhdGVfcHJvdG8oIi4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90byIpCisgIGdlbmVyYXRlX3Byb3RvKCIuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvIikKKyAgZ2VuZXJhdGVfcHJvdG8oIi4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvIikKKyAgZ2VuZXJhdGVfcHJvdG8oImdvb2dsZS9wcm90b2J1Zi9pbnRlcm5hbC9kZXNjcmlwdG9yX3Bvb2xfdGVzdDEucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2Rlc2NyaXB0b3JfcG9vbF90ZXN0Mi5wcm90byIpCisgIGdlbmVyYXRlX3Byb3RvKCJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21pc3NpbmdfZW51bV92YWx1ZXMucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfZXh0ZW5zaW9ucy5wcm90byIpCisgIGdlbmVyYXRlX3Byb3RvKCJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwvbW9yZV9leHRlbnNpb25zX2R5bmFtaWMucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL21vcmVfbWVzc2FnZXMucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ZhY3RvcnlfdGVzdDEucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ZhY3RvcnlfdGVzdDIucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ltcG9ydF90ZXN0X3BhY2thZ2UvaW5uZXIucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL2ludGVybmFsL2ltcG9ydF90ZXN0X3BhY2thZ2Uvb3V0ZXIucHJvdG8iKQorICBnZW5lcmF0ZV9wcm90bygiZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3B5dGhvbi5wcm90byIpCisKK2NsYXNzIGNsZWFuKF9jbGVhbik6CisgIGRlZiBydW4oc2VsZik6CisgICAgIyBEZWxldGUgZ2VuZXJhdGVkIGZpbGVzIGluIHRoZSBjb2RlIHRyZWUuCisgICAgZm9yIChkaXJwYXRoLCBkaXJuYW1lcywgZmlsZW5hbWVzKSBpbiBvcy53YWxrKCIuIik6CisgICAgICBmb3IgZmlsZW5hbWUgaW4gZmlsZW5hbWVzOgorICAgICAgICBmaWxlcGF0aCA9IG9zLnBhdGguam9pbihkaXJwYXRoLCBmaWxlbmFtZSkKKyAgICAgICAgaWYgZmlsZXBhdGguZW5kc3dpdGgoIl9wYjIucHkiKSBvciBmaWxlcGF0aC5lbmRzd2l0aCgiLnB5YyIpIG9yIFwKKyAgICAgICAgICBmaWxlcGF0aC5lbmRzd2l0aCgiLnNvIikgb3IgZmlsZXBhdGguZW5kc3dpdGgoIi5vIikgb3IgXAorICAgICAgICAgIGZpbGVwYXRoLmVuZHN3aXRoKCdnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvX19pbml0X18ucHknKToKKyAgICAgICAgICBvcy5yZW1vdmUoZmlsZXBhdGgpCisgICAgIyBfY2xlYW4gaXMgYW4gb2xkLXN0eWxlIGNsYXNzLCBzbyBzdXBlcigpIGRvZXNuJ3Qgd29yay4KKyAgICBfY2xlYW4ucnVuKHNlbGYpCisKK2NsYXNzIGJ1aWxkX3B5KF9idWlsZF9weSk6CisgIGRlZiBydW4oc2VsZik6CisgICAgIyBHZW5lcmF0ZSBuZWNlc3NhcnkgLnByb3RvIGZpbGUgaWYgaXQgZG9lc24ndCBleGlzdC4KKyAgICBnZW5lcmF0ZV9wcm90bygiLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIikKKyAgICBnZW5lcmF0ZV9wcm90bygiLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8iKQorICAgIEdlbmVyYXRlVW5pdHRlc3RQcm90b3MoKQorCisgICAgIyBNYWtlIHN1cmUgZ29vZ2xlLnByb3RvYnVmLyoqIGFyZSB2YWxpZCBwYWNrYWdlcy4KKyAgICBmb3IgcGF0aCBpbiBbJycsICdpbnRlcm5hbC8nLCAnY29tcGlsZXIvJywgJ3B5ZXh0LyddOgorICAgICAgdHJ5OgorICAgICAgICBvcGVuKCdnb29nbGUvcHJvdG9idWYvJXNfX2luaXRfXy5weScgJSBwYXRoLCAnYScpLmNsb3NlKCkKKyAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yOgorICAgICAgICBwYXNzCisgICAgIyBfYnVpbGRfcHkgaXMgYW4gb2xkLXN0eWxlIGNsYXNzLCBzbyBzdXBlcigpIGRvZXNuJ3Qgd29yay4KKyAgICBfYnVpbGRfcHkucnVuKHNlbGYpCisgICMgVE9ETyhtcm92bmVyKTogU3ViY2xhc3MgdG8gcnVuIDJ0bzMgb24gc29tZSBmaWxlcyBvbmx5LgorICAjIFRyYWNpbmcgd2hhdCBodHRwczovL3dpa2kucHl0aG9uLm9yZy9tb2luL1BvcnRpbmdQeXRob25Ub1B5M2sncyAiQXBwcm9hY2ggMiIKKyAgIyBzZWN0aW9uIG9uIGhvdyB0byBnZXQgMnRvMyB0byBydW4gb24gc291cmNlIGZpbGVzIGR1cmluZyBpbnN0YWxsIHVuZGVyCisgICMgUHl0aG9uIDMuICBUaGlzIGNsYXNzIHNlZW1zIGxpa2UgYSBnb29kIHBsYWNlIHRvIHB1dCBsb2dpYyB0aGF0IGNhbGxzCisgICMgcHl0aG9uMydzIGRpc3R1dGlscy51dGlsLnJ1bl8ydG8zIG9uIHRoZSBzdWJzZXQgb2YgdGhlIGZpbGVzIHdlIGhhdmUgaW4gb3VyCisgICMgcmVsZWFzZSB0aGF0IGFyZSBzdWJqZWN0IHRvIGNvbnZlcnNpb24uCisgICMgU2VlIGNvZGUgcmVmZXJlbmNlIGluIHByZXZpb3VzIGNvZGUgcmV2aWV3LgorCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBleHRfbW9kdWxlX2xpc3QgPSBbXQorICBjcHBfaW1wbCA9ICctLWNwcF9pbXBsZW1lbnRhdGlvbicKKyAgaWYgY3BwX2ltcGwgaW4gc3lzLmFyZ3Y6CisgICAgc3lzLmFyZ3YucmVtb3ZlKGNwcF9pbXBsKQorICAgICMgQysrIGltcGxlbWVudGF0aW9uIGV4dGVuc2lvbgorICAgIGV4dF9tb2R1bGVfbGlzdC5hcHBlbmQoRXh0ZW5zaW9uKAorICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLnB5ZXh0Ll9tZXNzYWdlIiwKKyAgICAgICAgWyAiZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3IuY2MiLAorICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvcHlleHQvZGVzY3JpcHRvcl9jb250YWluZXJzLmNjIiwKKyAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2Rlc2NyaXB0b3JfcG9vbC5jYyIsCisgICAgICAgICAgImdvb2dsZS9wcm90b2J1Zi9weWV4dC9tZXNzYWdlLmNjIiwKKyAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L2V4dGVuc2lvbl9kaWN0LmNjIiwKKyAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL3B5ZXh0L3JlcGVhdGVkX3NjYWxhcl9jb250YWluZXIuY2MiLAorICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvcHlleHQvcmVwZWF0ZWRfY29tcG9zaXRlX2NvbnRhaW5lci5jYyIgXSwKKyAgICAgICAgZGVmaW5lX21hY3Jvcz1bKCdHT09HTEVfUFJPVE9CVUZfSEFTX09ORU9GJywgJzEnKV0sCisgICAgICAgIGluY2x1ZGVfZGlycyA9IFsgIi4iLCAiLi4iLCAiLi4vc3JjIl0sCisgICAgICAgIGxpYnJhcmllcyA9IFsgInByb3RvYnVmIiBdLAorICAgICAgICBsaWJyYXJ5X2RpcnMgPSBbICcuLi9zcmMvLmxpYnMnIF0sCisgICAgICAgICkpCisgICAgb3MuZW52aXJvblsnUFJPVE9DT0xfQlVGRkVSU19QWVRIT05fSU1QTEVNRU5UQVRJT04nXSA9ICdjcHAnCisKKyAgc2V0dXAobmFtZSA9ICdwcm90b2J1ZicsCisgICAgICAgIHZlcnNpb24gPSBHZXRWZXJzaW9uKCksCisgICAgICAgIHBhY2thZ2VzID0gWyAnZ29vZ2xlJyBdLAorICAgICAgICBuYW1lc3BhY2VfcGFja2FnZXMgPSBbICdnb29nbGUnIF0sCisgICAgICAgIGdvb2dsZV90ZXN0X2RpciA9ICJnb29nbGUvcHJvdG9idWYvaW50ZXJuYWwiLAorICAgICAgICAjIE11c3QgbGlzdCBtb2R1bGVzIGV4cGxpY2l0bHkgc28gdGhhdCB3ZSBkb24ndCBpbnN0YWxsIHRlc3RzLgorICAgICAgICBweV9tb2R1bGVzID0gWworICAgICAgICAgICdnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuYXBpX2ltcGxlbWVudGF0aW9uJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLmNvbnRhaW5lcnMnLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuY3BwX21lc3NhZ2UnLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYuaW50ZXJuYWwuZGVjb2RlcicsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC5lbmNvZGVyJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLmVudW1fdHlwZV93cmFwcGVyJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLmludGVybmFsLm1lc3NhZ2VfbGlzdGVuZXInLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYuaW50ZXJuYWwucHl0aG9uX21lc3NhZ2UnLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYuaW50ZXJuYWwudHlwZV9jaGVja2VycycsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbC53aXJlX2Zvcm1hdCcsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5kZXNjcmlwdG9yJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLmRlc2NyaXB0b3JfcGIyJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLnBsdWdpbl9wYjInLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYubWVzc2FnZScsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5kZXNjcmlwdG9yX2RhdGFiYXNlJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLmRlc2NyaXB0b3JfcG9vbCcsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5tZXNzYWdlX2ZhY3RvcnknLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYucHJvdG9fYnVpbGRlcicsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5weWV4dC5jcHBfbWVzc2FnZScsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi5yZWZsZWN0aW9uJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnNlcnZpY2UnLAorICAgICAgICAgICdnb29nbGUucHJvdG9idWYuc2VydmljZV9yZWZsZWN0aW9uJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnN5bWJvbF9kYXRhYmFzZScsCisgICAgICAgICAgJ2dvb2dsZS5wcm90b2J1Zi50ZXh0X2VuY29kaW5nJywKKyAgICAgICAgICAnZ29vZ2xlLnByb3RvYnVmLnRleHRfZm9ybWF0J10sCisgICAgICAgIGNtZGNsYXNzID0geyAnY2xlYW4nOiBjbGVhbiwgJ2J1aWxkX3B5JzogYnVpbGRfcHkgfSwKKyAgICAgICAgaW5zdGFsbF9yZXF1aXJlcyA9IFsnc2V0dXB0b29scyddLAorICAgICAgICAjIFRPRE86IFJlc3RvcmUgZGVwZW5kZW5jeSBvbmNlIGEgUHl0aG9uIDMgY29tcGF0aWJsZSBnb29nbGUtYXBwdXRpbHMKKyAgICAgICAgIyBpcyByZWxlYXNlZC4KKyAgICAgICAgc2V0dXBfcmVxdWlyZXMgPSAoWydnb29nbGUtYXBwdXRpbHMnXQorICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBzeXMudmVyc2lvbl9pbmZvWzBdIDwgMyBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICAgIFtdKSwKKyAgICAgICAgZXh0X21vZHVsZXMgPSBleHRfbW9kdWxlX2xpc3QsCisgICAgICAgIHVybCA9ICdodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLycsCisgICAgICAgIG1haW50YWluZXIgPSBtYWludGFpbmVyX2VtYWlsLAorICAgICAgICBtYWludGFpbmVyX2VtYWlsID0gJ3Byb3RvYnVmQGdvb2dsZWdyb3Vwcy5jb20nLAorICAgICAgICBsaWNlbnNlID0gJ05ldyBCU0QgTGljZW5zZScsCisgICAgICAgIGRlc2NyaXB0aW9uID0gJ1Byb3RvY29sIEJ1ZmZlcnMnLAorICAgICAgICBsb25nX2Rlc2NyaXB0aW9uID0KKyAgICAgICAgICAiUHJvdG9jb2wgQnVmZmVycyBhcmUgR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQuIiwKKyAgICAgICAgKQpkaWZmIC0tZ2l0IGEvcHl0aG9uL3N0dWJvdXQucHkgYi9weXRob24vc3R1Ym91dC5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5hZWU0ZjJkCi0tLSAvZGV2L251bGwKKysrIGIvcHl0aG9uL3N0dWJvdXQucHkKQEAgLTAsMCArMSwxNDAgQEAKKyMhL3Vzci9iaW4vcHl0aG9uMi40CisjCisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisjIFRoaXMgZmlsZSBpcyB1c2VkIGZvciB0ZXN0aW5nLiAgVGhlIG9yaWdpbmFsIGlzIGF0OgorIyAgIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9weW1veC8KKworY2xhc3MgU3R1Yk91dEZvclRlc3Rpbmc6CisgICIiIlNhbXBsZSBVc2FnZToKKyAgICAgWW91IHdhbnQgb3MucGF0aC5leGlzdHMoKSB0byBhbHdheXMgcmV0dXJuIHRydWUgZHVyaW5nIHRlc3RpbmcuCisKKyAgICAgc3R1YnMgPSBTdHViT3V0Rm9yVGVzdGluZygpCisgICAgIHN0dWJzLlNldChvcy5wYXRoLCAnZXhpc3RzJywgbGFtYmRhIHg6IDEpCisgICAgICAgLi4uCisgICAgIHN0dWJzLlVuc2V0QWxsKCkKKworICAgICBUaGUgYWJvdmUgY2hhbmdlcyBvcy5wYXRoLmV4aXN0cyBpbnRvIGEgbGFtYmRhIHRoYXQgcmV0dXJucyAxLiAgT25jZQorICAgICB0aGUgLi4uIHBhcnQgb2YgdGhlIGNvZGUgZmluaXNoZXMsIHRoZSBVbnNldEFsbCgpIGxvb2tzIHVwIHRoZSBvbGQgdmFsdWUKKyAgICAgb2Ygb3MucGF0aC5leGlzdHMgYW5kIHJlc3RvcmVzIGl0LgorCisgICIiIgorICBkZWYgX19pbml0X18oc2VsZik6CisgICAgc2VsZi5jYWNoZSA9IFtdCisgICAgc2VsZi5zdHVicyA9IFtdCisKKyAgZGVmIF9fZGVsX18oc2VsZik6CisgICAgc2VsZi5TbWFydFVuc2V0QWxsKCkKKyAgICBzZWxmLlVuc2V0QWxsKCkKKworICBkZWYgU21hcnRTZXQoc2VsZiwgb2JqLCBhdHRyX25hbWUsIG5ld19hdHRyKToKKyAgICAiIiJSZXBsYWNlIG9iai5hdHRyX25hbWUgd2l0aCBuZXdfYXR0ci4gVGhpcyBtZXRob2QgaXMgc21hcnQgYW5kIHdvcmtzCisgICAgICAgYXQgdGhlIG1vZHVsZSwgY2xhc3MsIGFuZCBpbnN0YW5jZSBsZXZlbCB3aGlsZSBwcmVzZXJ2aW5nIHByb3BlcgorICAgICAgIGluaGVyaXRhbmNlLiBJdCB3aWxsIG5vdCBzdHViIG91dCBDIHR5cGVzIGhvd2V2ZXIgdW5sZXNzIHRoYXQgaGFzIGJlZW4KKyAgICAgICBleHBsaWNpdGx5IGFsbG93ZWQgYnkgdGhlIHR5cGUuCisKKyAgICAgICBUaGlzIG1ldGhvZCBzdXBwb3J0cyB0aGUgY2FzZSB3aGVyZSBhdHRyX25hbWUgaXMgYSBzdGF0aWNtZXRob2Qgb3IgYQorICAgICAgIGNsYXNzbWV0aG9kIG9mIG9iai4KKworICAgICAgIE5vdGVzOgorICAgICAgLSBJZiBvYmogaXMgYW4gaW5zdGFuY2UsIHRoZW4gaXQgaXMgaXRzIGNsYXNzIHRoYXQgd2lsbCBhY3R1YWxseSBiZQorICAgICAgICBzdHViYmVkLiBOb3RlIHRoYXQgdGhlIG1ldGhvZCBTZXQoKSBkb2VzIG5vdCBkbyB0aGF0OiBpZiBvYmogaXMKKyAgICAgICAgYW4gaW5zdGFuY2UsIGl0IChhbmQgbm90IGl0cyBjbGFzcykgd2lsbCBiZSBzdHViYmVkLgorICAgICAgLSBUaGUgc3R1YmJpbmcgaXMgdXNpbmcgdGhlIGJ1aWx0aW4gZ2V0YXR0ciBhbmQgc2V0YXR0ci4gU28sIHRoZSBfX2dldF9fCisgICAgICAgIGFuZCBfX3NldF9fIHdpbGwgYmUgY2FsbGVkIHdoZW4gc3R1YmJpbmcgKFRPRE86IEEgYmV0dGVyIGlkZWEgd291bGQKKyAgICAgICAgcHJvYmFibHkgYmUgdG8gbWFuaXB1bGF0ZSBvYmouX19kaWN0X18gaW5zdGVhZCBvZiBnZXRhdHRyKCkgYW5kCisgICAgICAgIHNldGF0dHIoKSkuCisKKyAgICAgICBSYWlzZXMgQXR0cmlidXRlRXJyb3IgaWYgdGhlIGF0dHJpYnV0ZSBjYW5ub3QgYmUgZm91bmQuCisgICAgIiIiCisgICAgaWYgKGluc3BlY3QuaXNtb2R1bGUob2JqKSBvcgorICAgICAgICAobm90IGluc3BlY3QuaXNjbGFzcyhvYmopIGFuZCBvYmouX19kaWN0X18uaGFzX2tleShhdHRyX25hbWUpKSk6CisgICAgICBvcmlnX29iaiA9IG9iagorICAgICAgb3JpZ19hdHRyID0gZ2V0YXR0cihvYmosIGF0dHJfbmFtZSkKKworICAgIGVsc2U6CisgICAgICBpZiBub3QgaW5zcGVjdC5pc2NsYXNzKG9iaik6CisgICAgICAgIG1ybyA9IGxpc3QoaW5zcGVjdC5nZXRtcm8ob2JqLl9fY2xhc3NfXykpCisgICAgICBlbHNlOgorICAgICAgICBtcm8gPSBsaXN0KGluc3BlY3QuZ2V0bXJvKG9iaikpCisKKyAgICAgIG1yby5yZXZlcnNlKCkKKworICAgICAgb3JpZ19hdHRyID0gTm9uZQorCisgICAgICBmb3IgY2xzIGluIG1ybzoKKyAgICAgICAgdHJ5OgorICAgICAgICAgIG9yaWdfb2JqID0gY2xzCisgICAgICAgICAgb3JpZ19hdHRyID0gZ2V0YXR0cihvYmosIGF0dHJfbmFtZSkKKyAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgorICAgICAgICAgIGNvbnRpbnVlCisKKyAgICBpZiBvcmlnX2F0dHIgaXMgTm9uZToKKyAgICAgIHJhaXNlIEF0dHJpYnV0ZUVycm9yKCJBdHRyaWJ1dGUgbm90IGZvdW5kLiIpCisKKyAgICAjIENhbGxpbmcgZ2V0YXR0cigpIG9uIGEgc3RhdGljbWV0aG9kIHRyYW5zZm9ybXMgaXQgdG8gYSAnbm9ybWFsJyBmdW5jdGlvbi4KKyAgICAjIFdlIG5lZWQgdG8gZW5zdXJlIHRoYXQgd2UgcHV0IGl0IGJhY2sgYXMgYSBzdGF0aWNtZXRob2QuCisgICAgb2xkX2F0dHJpYnV0ZSA9IG9iai5fX2RpY3RfXy5nZXQoYXR0cl9uYW1lKQorICAgIGlmIG9sZF9hdHRyaWJ1dGUgaXMgbm90IE5vbmUgYW5kIGlzaW5zdGFuY2Uob2xkX2F0dHJpYnV0ZSwgc3RhdGljbWV0aG9kKToKKyAgICAgIG9yaWdfYXR0ciA9IHN0YXRpY21ldGhvZChvcmlnX2F0dHIpCisKKyAgICBzZWxmLnN0dWJzLmFwcGVuZCgob3JpZ19vYmosIGF0dHJfbmFtZSwgb3JpZ19hdHRyKSkKKyAgICBzZXRhdHRyKG9yaWdfb2JqLCBhdHRyX25hbWUsIG5ld19hdHRyKQorCisgIGRlZiBTbWFydFVuc2V0QWxsKHNlbGYpOgorICAgICIiIlJldmVyc2VzIGFsbCB0aGUgU21hcnRTZXQoKSBjYWxscywgcmVzdG9yaW5nIHRoaW5ncyB0byB0aGVpciBvcmlnaW5hbAorICAgIGRlZmluaXRpb24uICBJdHMgb2theSB0byBjYWxsIFNtYXJ0VW5zZXRBbGwoKSByZXBlYXRlZGx5LCBhcyBsYXRlciBjYWxscworICAgIGhhdmUgbm8gZWZmZWN0IGlmIG5vIFNtYXJ0U2V0KCkgY2FsbHMgaGF2ZSBiZWVuIG1hZGUuCisKKyAgICAiIiIKKyAgICBzZWxmLnN0dWJzLnJldmVyc2UoKQorCisgICAgZm9yIGFyZ3MgaW4gc2VsZi5zdHViczoKKyAgICAgIHNldGF0dHIoKmFyZ3MpCisKKyAgICBzZWxmLnN0dWJzID0gW10KKworICBkZWYgU2V0KHNlbGYsIHBhcmVudCwgY2hpbGRfbmFtZSwgbmV3X2NoaWxkKToKKyAgICAiIiJSZXBsYWNlIGNoaWxkX25hbWUncyBvbGQgZGVmaW5pdGlvbiB3aXRoIG5ld19jaGlsZCwgaW4gdGhlIGNvbnRleHQKKyAgICBvZiB0aGUgZ2l2ZW4gcGFyZW50LiAgVGhlIHBhcmVudCBjb3VsZCBiZSBhIG1vZHVsZSB3aGVuIHRoZSBjaGlsZCBpcyBhCisgICAgZnVuY3Rpb24gYXQgbW9kdWxlIHNjb3BlLiAgT3IgdGhlIHBhcmVudCBjb3VsZCBiZSBhIGNsYXNzIHdoZW4gYSBjbGFzcycKKyAgICBtZXRob2QgaXMgYmVpbmcgcmVwbGFjZWQuICBUaGUgbmFtZWQgY2hpbGQgaXMgc2V0IHRvIG5ld19jaGlsZCwgd2hpbGUKKyAgICB0aGUgcHJpb3IgZGVmaW5pdGlvbiBpcyBzYXZlZCBhd2F5IGZvciBsYXRlciwgd2hlbiBVbnNldEFsbCgpIGlzIGNhbGxlZC4KKworICAgIFRoaXMgbWV0aG9kIHN1cHBvcnRzIHRoZSBjYXNlIHdoZXJlIGNoaWxkX25hbWUgaXMgYSBzdGF0aWNtZXRob2Qgb3IgYQorICAgIGNsYXNzbWV0aG9kIG9mIHBhcmVudC4KKyAgICAiIiIKKyAgICBvbGRfY2hpbGQgPSBnZXRhdHRyKHBhcmVudCwgY2hpbGRfbmFtZSkKKworICAgIG9sZF9hdHRyaWJ1dGUgPSBwYXJlbnQuX19kaWN0X18uZ2V0KGNoaWxkX25hbWUpCisgICAgaWYgb2xkX2F0dHJpYnV0ZSBpcyBub3QgTm9uZSBhbmQgaXNpbnN0YW5jZShvbGRfYXR0cmlidXRlLCBzdGF0aWNtZXRob2QpOgorICAgICAgb2xkX2NoaWxkID0gc3RhdGljbWV0aG9kKG9sZF9jaGlsZCkKKworICAgIHNlbGYuY2FjaGUuYXBwZW5kKChwYXJlbnQsIG9sZF9jaGlsZCwgY2hpbGRfbmFtZSkpCisgICAgc2V0YXR0cihwYXJlbnQsIGNoaWxkX25hbWUsIG5ld19jaGlsZCkKKworICBkZWYgVW5zZXRBbGwoc2VsZik6CisgICAgIiIiUmV2ZXJzZXMgYWxsIHRoZSBTZXQoKSBjYWxscywgcmVzdG9yaW5nIHRoaW5ncyB0byB0aGVpciBvcmlnaW5hbAorICAgIGRlZmluaXRpb24uICBJdHMgb2theSB0byBjYWxsIFVuc2V0QWxsKCkgcmVwZWF0ZWRseSwgYXMgbGF0ZXIgY2FsbHMgaGF2ZQorICAgIG5vIGVmZmVjdCBpZiBubyBTZXQoKSBjYWxscyBoYXZlIGJlZW4gbWFkZS4KKworICAgICIiIgorICAgICMgVW5kbyBjYWxscyB0byBTZXQoKSBpbiByZXZlcnNlIG9yZGVyLCBpbiBjYXNlIFNldCgpIHdhcyBjYWxsZWQgb24gdGhlCisgICAgIyBzYW1lIGFyZ3VtZW50cyByZXBlYXRlZGx5ICh3YW50IHRoZSBvcmlnaW5hbCBjYWxsIHRvIGJlIGxhc3Qgb25lIHVuZG9uZSkKKyAgICBzZWxmLmNhY2hlLnJldmVyc2UoKQorCisgICAgZm9yIChwYXJlbnQsIG9sZF9jaGlsZCwgY2hpbGRfbmFtZSkgaW4gc2VsZi5jYWNoZToKKyAgICAgIHNldGF0dHIocGFyZW50LCBjaGlsZF9uYW1lLCBvbGRfY2hpbGQpCisgICAgc2VsZi5jYWNoZSA9IFtdCmRpZmYgLS1naXQgYS9ydWJ5Ly5naXRpZ25vcmUgYi9ydWJ5Ly5naXRpZ25vcmUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBjOTc4ZgotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvLmdpdGlnbm9yZQpAQCAtMCwwICsxLDYgQEAKKyouYnVuZGxlCit0YWdzCisuaWRlYS8KK2xpYi9nb29nbGUvcHJvdG9idWZfamF2YS5qYXIKK3Byb3RvYnVmLWpydWJ5LmltbAordGFyZ2V0LwpkaWZmIC0tZ2l0IGEvcnVieS9HZW1maWxlIGIvcnVieS9HZW1maWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhNzVkZjEKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L0dlbWZpbGUKQEAgLTAsMCArMSwzIEBACitzb3VyY2UgJ2h0dHBzOi8vcnVieWdlbXMub3JnJworCitnZW1zcGVjCmRpZmYgLS1naXQgYS9ydWJ5L0dlbWZpbGUubG9jayBiL3J1YnkvR2VtZmlsZS5sb2NrCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5ZGViNDcKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L0dlbWZpbGUubG9jawpAQCAtMCwwICsxLDI1IEBACitQQVRICisgIHJlbW90ZTogLgorICBzcGVjczoKKyAgICBnb29nbGUtcHJvdG9idWYgKDMuMC4wLmFscGhhLjIpCisKK0dFTQorICByZW1vdGU6IGh0dHBzOi8vcnVieWdlbXMub3JnLworICBzcGVjczoKKyAgICBwb3dlcl9hc3NlcnQgKDAuMi4yKQorICAgIHJha2UgKDEwLjQuMikKKyAgICByYWtlLWNvbXBpbGVyICgwLjkuNSkKKyAgICAgIHJha2UKKyAgICBydWJ5Z2Vtcy10YXNrcyAoMC4yLjQpCisgICAgdGVzdC11bml0ICgzLjAuOSkKKyAgICAgIHBvd2VyX2Fzc2VydAorCitQTEFURk9STVMKKyAgamF2YQorICBydWJ5CisKK0RFUEVOREVOQ0lFUworICBnb29nbGUtcHJvdG9idWYhCisgIHJha2UtY29tcGlsZXIKKyAgcnVieWdlbXMtdGFza3MKKyAgdGVzdC11bml0CmRpZmYgLS1naXQgYS9ydWJ5L1JFQURNRS5tZCBiL3J1YnkvUkVBRE1FLm1kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyZmE3NmEKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L1JFQURNRS5tZApAQCAtMCwwICsxLDExMSBAQAorVGhpcyBkaXJlY3RvcnkgY29udGFpbnMgdGhlIFJ1YnkgZXh0ZW5zaW9uIHRoYXQgaW1wbGVtZW50cyBQcm90b2NvbCBCdWZmZXJzCitmdW5jdGlvbmFsaXR5IGluIFJ1YnkuCisKK1RoZSBSdWJ5IGV4dGVuc2lvbiBtYWtlcyB1c2Ugb2YgZ2VuZXJhdGVkIFJ1YnkgY29kZSB0aGF0IGRlZmluZXMgbWVzc2FnZSBhbmQKK2VudW0gdHlwZXMgaW4gYSBSdWJ5IERTTC4gWW91IG1heSB3cml0ZSBkZWZpbml0aW9ucyBpbiB0aGlzIERTTCBkaXJlY3RseSwgYnV0Cit3ZSByZWNvbW1lbmQgdXNpbmcgcHJvdG9jJ3MgUnVieSBnZW5lcmF0aW9uIHN1cHBvcnQgd2l0aCAucHJvdG8gZmlsZXMuIFRoZQorYnVpbGQgcHJvY2VzcyBpbiB0aGlzIGRpcmVjdG9yeSBvbmx5IGluc3RhbGxzIHRoZSBleHRlbnNpb247IHlvdSBuZWVkIHRvCitpbnN0YWxsIHByb3RvYyBhcyB3ZWxsIHRvIGhhdmUgUnVieSBjb2RlIGdlbmVyYXRpb24gZnVuY3Rpb25hbGl0eS4KKworSW5zdGFsbGF0aW9uIGZyb20gR2VtCistLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworV2hlbiB3ZSByZWxlYXNlIGEgdmVyc2lvbiBvZiBQcm90b2NvbCBCdWZmZXJzLCB3ZSB3aWxsIHVwbG9hZCBhIEdlbSB0bworW1J1YnlHZW1zXShodHRwczovL3d3dy5ydWJ5Z2Vtcy5vcmcvKS4gVG8gdXNlIHRoaXMgcHJlLXBhY2thZ2VkIGdlbSwgc2ltcGx5CitpbnN0YWxsIGl0IGFzIHlvdSB3b3VsZCBhbnkgb3RoZXIgZ2VtOgorCisgICAgJCBnZW0gaW5zdGFsbCBbLS1wcmVyZWxlYXNlXSBnb29nbGUtcHJvdG9idWYKKworVGhlIGAtLXByZWAgZmxhZyBpcyBuZWNlc3NhcnkgaWYgd2UgaGF2ZSBub3QgeWV0IG1hZGUgYSBub24tYWxwaGEvYmV0YSByZWxlYXNlCitvZiB0aGUgUnVieSBleHRlbnNpb247IGl0IGFsbG93cyBgZ2VtYCB0byBjb25zaWRlciB0aGVzZSAicHJlLXJlbGVhc2UiCithbHBoYS9iZXRhIHZlcnNpb25zLgorCitPbmNlIHRoZSBnZW0gaXMgaW5zdGFsbGVkLCB5b3UgbWF5IG9yIG1heSBub3QgbmVlZCBgcHJvdG9jYC4gSWYgeW91IHdyaXRlIHlvdXIKK21lc3NhZ2UgdHlwZSBkZXNjcmlwdGlvbnMgZGlyZWN0bHkgaW4gdGhlIFJ1YnkgRFNMLCB5b3UgZG8gbm90IG5lZWQgaXQuCitIb3dldmVyLCBpZiB5b3Ugd2lzaCB0byBnZW5lcmF0ZSB0aGUgUnVieSBEU0wgZnJvbSBhIGAucHJvdG9gIGZpbGUsIHlvdSB3aWxsCithbHNvIHdhbnQgdG8gaW5zdGFsbCBQcm90b2NvbCBCdWZmZXJzIGl0c2VsZiwgYXMgZGVzY3JpYmVkIGluIHRoaXMgcmVwb3NpdG9yeSdzCittYWluIGBSRUFETUVgIGZpbGUuIFRoZSB2ZXJzaW9uIG9mIGBwcm90b2NgIGluY2x1ZGVkIGluIHRoZSBsYXRlc3QgcmVsZWFzZQorc3VwcG9ydHMgdGhlIGAtLXJ1Ynlfb3V0YCBvcHRpb24gdG8gZ2VuZXJhdGUgUnVieSBjb2RlLgorCitBIHNpbXBsZSBleGFtcGxlIG9mIHVzaW5nIHRoZSBSdWJ5IGV4dGVuc2lvbiBmb2xsb3dzLiBNb3JlIGV4dGVuc2l2ZQorZG9jdW1lbnRhdGlvbiBtYXkgYmUgZm91bmQgaW4gdGhlIFJ1YnlEb2MgY29tbWVudHMgKGBjYWxsLXNlcWAgdGFncykgaW4gdGhlCitzb3VyY2UsIGFuZCB3ZSBwbGFuIHRvIHJlbGVhc2Ugc2VwYXJhdGUsIG1vcmUgZGV0YWlsZWQsIGRvY3VtZW50YXRpb24gYXQgYQorbGF0ZXIgZGF0ZS4KKworICAgIHJlcXVpcmUgJ2dvb2dsZS9wcm90b2J1ZicKKworICAgICMgZ2VuZXJhdGVkIGZyb20gbXlfcHJvdG9fdHlwZXMucHJvdG8gd2l0aCBwcm90b2M6CisgICAgIyAgJCBwcm90b2MgLS1ydWJ5X291dD0uIG15X3Byb3RvX3R5cGVzLnByb3RvCisgICAgcmVxdWlyZSAnbXlfcHJvdG9fdHlwZXMnCisKKyAgICBteW1lc3NhZ2UgPSBNeVRlc3RNZXNzYWdlLm5ldyg6ZmllbGQxID0+IDQyLCA6ZmllbGQyID0+IFsiYSIsICJiIiwgImMiXSkKKyAgICBteW1lc3NhZ2UuZmllbGQxID0gNDMKKyAgICBteW1lc3NhZ2UuZmllbGQyLnB1c2goImQiKQorICAgIG15bWVzc2FnZS5maWVsZDMgPSBTdWJNZXNzYWdlLm5ldyg6Zm9vID0+IDEwMCkKKworICAgIGVuY29kZWRfZGF0YSA9IE15VGVzdE1lc3NhZ2UuZW5jb2RlKG15bWVzc2FnZSkKKyAgICBkZWNvZGVkID0gTXlUZXN0TWVzc2FnZS5kZWNvZGUoZW5jb2RlZF9kYXRhKQorICAgIGFzc2VydCBkZWNvZGVkID09IG15bWVzc2FnZQorCisgICAgcHV0cyAiSlNPTjoiCisgICAgcHV0cyBNeVRlc3RNZXNzYWdlLmVuY29kZV9qc29uKG15bWVzc2FnZSkKKworSW5zdGFsbGF0aW9uIGZyb20gU291cmNlIChCdWlsZGluZyBHZW0pCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVG8gYnVpbGQgdGhpcyBSdWJ5IGV4dGVuc2lvbiwgeW91IHdpbGwgbmVlZDoKKworKiBSYWtlCisqIEJ1bmRsZXIKKyogUnVieSBkZXZlbG9wbWVudCBoZWFkZXJzCisqIGEgQyBjb21waWxlcgorCitUbyBCdWlsZCB0aGUgSlJ1YnkgZXh0ZW5zaW9uLCB5b3Ugd2lsbCBuZWVkOgorCisqIE1hdmVuCisqIFRoZSBsYXRlc3QgdmVyc2lvbiBvZiB0aGUgcHJvdG9idWYgamF2YSBsaWJyYXJ5CisqIEluc3RhbGwgSlJ1YnkgdmlhIHJiZW52IG9yIFJWTQorCitGaXJzdCBzd2l0Y2ggdG8gdGhlIGRlc2lyZWQgcGxhdGZvcm0gd2l0aCByYmVudiBvciBSVk0uCisKK1RoZW4gaW5zdGFsbCB0aGUgcmVxdWlyZWQgUnVieSBnZW1zOgorCisgICAgJCBnZW0gaW5zdGFsbCBidW5kbGVyCisgICAgJCBidW5kbGUKKworVGhlbiBidWlsZCB0aGUgR2VtOgorCisgICAgJCByYWtlIGdlbQorICAgICQgZ2VtIGluc3RhbGwgcGtnL3Byb3RvYnVmLSRWRVJTSU9OLmdlbQorCitUbyBydW4gdGhlIHNwZWNzOgorCisgICAgJCByYWtlIHRlc3QKKworVGhpcyBnZW0gaW5jbHVkZXMgdGhlIHVwYiBwYXJzaW5nIGFuZCBzZXJpYWxpemF0aW9uIGxpYnJhcnkgYXMgYSBzaW5nbGUtZmlsZQorYW1hbGdhbWF0aW9uLiBJdCBpcyB1cC10by1kYXRlIHdpdGggdXBiIGdpdCBjb21taXQKK2A1MzViYzJmZTJmMmI0NjdmNTkzNDdmZmM5NDQ5ZTExZTQ3NzkxMjU3YC4KKworVmVyc2lvbiBOdW1iZXIgU2NoZW1lCistLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworV2UgYXJlIHVzaW5nIGEgdmVyc2lvbiBudW1iZXIgc2NoZW1lIHRoYXQgaXMgYSBoeWJyaWQgb2YgUHJvdG9jb2wgQnVmZmVycycKK292ZXJhbGwgdmVyc2lvbiBudW1iZXIgYW5kIHNvbWUgUnVieS1zcGVjaWZpYyBydWxlcy4gR2VtIGRvZXMgbm90IGFsbG93CityZS11cGxvYWRzIG9mIGEgZ2VtIHdpdGggdGhlIHNhbWUgdmVyc2lvbiBudW1iZXIsIHNvIHdlIGFkZCBhIHNlcXVlbmNlIG51bWJlcgorKCJ1cGxvYWQgdmVyc2lvbiIpIHRvIHRoZSB2ZXJzaW9uLiBXZSBhbHNvIGZvcm1hdCBhbHBoYWJldGljYWwgdGFncyAoYWxwaGEsCitwcmUsIC4uLikgc2xpZ2h0bHkgZGlmZmVyZW50bHksIGFuZCB3ZSBhdm9pZCBoeXBoZW5zLiBJbiBtb3JlIGRldGFpbDoKKworKiBGaXJzdCwgd2UgZGV0ZXJtaW5lIHRoZSBwcmVmaXg6IGEgUHJvdG9jb2wgQnVmZmVycyB2ZXJzaW9uICIzLjAuMC1hbHBoYS0yIgorICBiZWNvbWVzICIzLjAuMC5hbHBoYS4yIi4gV2hlbiB3ZSByZWxlYXNlIDMuMC4wLCB0aGlzIHByZWZpeCB3aWxsIGJlIHNpbXBseQorICAiMy4wLjAiLgorKiBXZSB0aGVuIGFwcGVuZCB0aGUgdXBsb2FkIHZlcnNpb246ICIzLjAuMC5hbHBoYS4yLjAiIG9yICIzLjAuMC4wIi4gSWYgd2UgbmVlZAorICB0byB1cGxvYWQgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZ2VtIHRvIGZpeCBhbiBpc3N1ZSwgdGhlIHZlcnNpb24gYmVjb21lcworICAiMy4wLjAuYWxwaGEuMi4xIiBvciAiMy4wLjAuMSIuCisqIElmIHdlIGFyZSB3b3JraW5nIG9uIGEgcHJlcmVsZWFzZSB2ZXJzaW9uLCB3ZSBhcHBlbmQgYSBwcmVyZWxlYXNlIHRhZzoKKyAgIjMuMC4wLmFscGhhLjMuMC5wcmUiLiBUaGUgcHJlcmVsZWFzZSB0YWcgY29tZXMgYXQgdGhlIGVuZCBzbyB0aGF0IHdoZW4KKyAgdmVyc2lvbiBudW1iZXJzIGFyZSBzb3J0ZWQsIGFueSBwcmVyZWxlYXNlIGJ1aWxkcyBhcmUgb3JkZXJlZCBiZXR3ZWVuIHRoZQorICBwcmlvciB2ZXJzaW9uIGFuZCBjdXJyZW50IHZlcnNpb24uCisKK1RoZXNlIHJ1bGVzIGFyZSBkZXNpZ25lZCB0byB3b3JrIHdpdGggdGhlIHNvcnRpbmcgcnVsZXMgZm9yCitbR2VtOjpWZXJzaW9uXShodHRwOi8vcnVieS1kb2Mub3JnL3N0ZGxpYi0yLjAvbGliZG9jL3J1YnlnZW1zL3Jkb2MvR2VtL1ZlcnNpb24uaHRtbCk6CityZWxlYXNlIG51bWJlcnMgc2hvdWxkIHNvcnQgaW4gYWN0dWFsIHJlbGVhc2Ugb3JkZXIuCmRpZmYgLS1naXQgYS9ydWJ5L1Jha2VmaWxlIGIvcnVieS9SYWtlZmlsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YzFkODQ5Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS9SYWtlZmlsZQpAQCAtMCwwICsxLDMzIEBACityZXF1aXJlICJydWJ5Z2VtcyIKK3JlcXVpcmUgInJ1YnlnZW1zL3BhY2thZ2VfdGFzayIKK3JlcXVpcmUgInJha2UvZXh0ZW5zaW9udGFzayIgdW5sZXNzIFJVQllfUExBVEZPUk0gPT0gImphdmEiCityZXF1aXJlICJyYWtlL3Rlc3R0YXNrIgorCitzcGVjID0gR2VtOjpTcGVjaWZpY2F0aW9uLmxvYWQoImdvb2dsZS1wcm90b2J1Zi5nZW1zcGVjIikKKworaWYgUlVCWV9QTEFURk9STSA9PSAiamF2YSIKKyAgdGFzayA6Y2xlYW4gZG8KKyAgICBzeXN0ZW0oIm12biBjbGVhbiIpCisgIGVuZAorCisgIHRhc2sgOmNvbXBpbGUgZG8KKyAgICBzeXN0ZW0oIm12biBwYWNrYWdlIikKKyAgZW5kCitlbHNlCisgIFJha2U6OkV4dGVuc2lvblRhc2submV3KCJwcm90b2J1Zl9jIiwgc3BlYykgZG8gfGV4dHwKKyAgICBleHQuZXh0X2RpciA9ICJleHQvZ29vZ2xlL3Byb3RvYnVmX2MiCisgICAgZXh0LmxpYl9kaXIgPSAibGliL2dvb2dsZSIKKyAgZW5kCitlbmQKKworR2VtOjpQYWNrYWdlVGFzay5uZXcoc3BlYykgZG8gfHBrZ3wKK2VuZAorCitSYWtlOjpUZXN0VGFzay5uZXcoOnRlc3QgPT4gOmJ1aWxkKSBkbyB8dHwKKyAgdC50ZXN0X2ZpbGVzID0gRmlsZUxpc3RbInRlc3RzLyoucmIiXQorZW5kCisKK3Rhc2sgOmJ1aWxkID0+IFs6Y2xlYW4sIDpjb21waWxlXQordGFzayA6ZGVmYXVsdCA9PiBbOmJ1aWxkXQorCisjIHZpbTpzdz0yOmV0CmRpZmYgLS1naXQgYS9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9kZWZzLmMgYi9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9kZWZzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM5YzI3ZgotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL2RlZnMuYwpAQCAtMCwwICsxLDE2NzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSAicHJvdG9idWYuaCIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIENvbW1vbiB1dGlsaXRpZXMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCBjaGFyKiBrRGVzY3JpcHRvckluc3RhbmNlVmFyID0gImRlc2NyaXB0b3IiOworCitzdGF0aWMgY29uc3QgY2hhciogZ2V0X3N0cihWQUxVRSBzdHIpIHsKKyAgQ2hlY2tfVHlwZShzdHIsIFRfU1RSSU5HKTsKKyAgcmV0dXJuIFJTVFJJTkdfUFRSKHN0cik7Cit9CisKK3N0YXRpYyBWQUxVRSByYl9zdHJfbWF5YmVfbnVsbChjb25zdCBjaGFyKiBzKSB7CisgIGlmIChzID09IE5VTEwpIHsKKyAgICBzID0gIiI7CisgIH0KKyAgcmV0dXJuIHJiX3N0cl9uZXcyKHMpOworfQorCitzdGF0aWMgdXBiX2RlZiogY2hlY2tfbm90ZnJvemVuKGNvbnN0IHVwYl9kZWYqIGRlZikgeworICBpZiAodXBiX2RlZl9pc2Zyb3plbihkZWYpKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAiQXR0ZW1wdCB0byBtb2RpZnkgYSBmcm96ZW4gZGVzY3JpcHRvci4gT25jZSBkZXNjcmlwdG9ycyBhcmUgIgorICAgICAgICAgICAgICJhZGRlZCB0byB0aGUgZGVzY3JpcHRvciBwb29sLCB0aGV5IG1heSBub3QgYmUgbW9kaWZpZWQuIik7CisgIH0KKyAgcmV0dXJuICh1cGJfZGVmKilkZWY7Cit9CisKK3N0YXRpYyB1cGJfbXNnZGVmKiBjaGVja19tc2dfbm90ZnJvemVuKGNvbnN0IHVwYl9tc2dkZWYqIGRlZikgeworICByZXR1cm4gdXBiX2Rvd25jYXN0X21zZ2RlZl9tdXRhYmxlKGNoZWNrX25vdGZyb3plbigoY29uc3QgdXBiX2RlZiopZGVmKSk7Cit9CisKK3N0YXRpYyB1cGJfZmllbGRkZWYqIGNoZWNrX2ZpZWxkX25vdGZyb3plbihjb25zdCB1cGJfZmllbGRkZWYqIGRlZikgeworICByZXR1cm4gdXBiX2Rvd25jYXN0X2ZpZWxkZGVmX211dGFibGUoY2hlY2tfbm90ZnJvemVuKChjb25zdCB1cGJfZGVmKilkZWYpKTsKK30KKworc3RhdGljIHVwYl9vbmVvZmRlZiogY2hlY2tfb25lb2Zfbm90ZnJvemVuKGNvbnN0IHVwYl9vbmVvZmRlZiogZGVmKSB7CisgIHJldHVybiAodXBiX29uZW9mZGVmKiljaGVja19ub3Rmcm96ZW4oKGNvbnN0IHVwYl9kZWYqKWRlZik7Cit9CisKK3N0YXRpYyB1cGJfZW51bWRlZiogY2hlY2tfZW51bV9ub3Rmcm96ZW4oY29uc3QgdXBiX2VudW1kZWYqIGRlZikgeworICByZXR1cm4gKHVwYl9lbnVtZGVmKiljaGVja19ub3Rmcm96ZW4oKGNvbnN0IHVwYl9kZWYqKWRlZik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBEZXNjcmlwdG9yUG9vbC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgREVGSU5FX0NMQVNTKG5hbWUsIHN0cmluZ19uYW1lKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFZBTFVFIGMgIyMgbmFtZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY29uc3QgcmJfZGF0YV90eXBlX3QgXyAjIyBuYW1lICMjIF90eXBlID0geyAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHN0cmluZ19uYW1lLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgeyBuYW1lICMjIF9tYXJrLCBuYW1lICMjIF9mcmVlLCBOVUxMIH0sICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBuYW1lKiBydWJ5X3RvXyAjIyBuYW1lKFZBTFVFIHZhbCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgbmFtZSogcmV0OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBUeXBlZERhdGFfR2V0X1N0cnVjdCh2YWwsIG5hbWUsICZfICMjIG5hbWUgIyMgX3R5cGUsIHJldCk7ICAgIFwKKyAgICAgIHJldHVybiByZXQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisKKyNkZWZpbmUgREVGSU5FX1NFTEYodHlwZSwgdmFyLCByYl92YXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHR5cGUqIHZhciA9IHJ1YnlfdG9fICMjIHR5cGUocmJfdmFyKTsKKworLy8gR2xvYmFsIHNpbmdsZXRvbiBEZXNjcmlwdG9yUG9vbC4gVGhlIHVzZXIgaXMgZnJlZSB0byBjcmVhdGUgb3RoZXJzLCBidXQgdGhpcworLy8gaXMgdXNlZCBieSBnZW5lcmF0ZWQgY29kZS4KK1ZBTFVFIGdlbmVyYXRlZF9wb29sOworCitERUZJTkVfQ0xBU1MoRGVzY3JpcHRvclBvb2wsICJHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbCIpOworCit2b2lkIERlc2NyaXB0b3JQb29sX21hcmsodm9pZCogX3NlbGYpIHsKK30KKwordm9pZCBEZXNjcmlwdG9yUG9vbF9mcmVlKHZvaWQqIF9zZWxmKSB7CisgIERlc2NyaXB0b3JQb29sKiBzZWxmID0gX3NlbGY7CisgIHVwYl9zeW10YWJfdW5yZWYoc2VsZi0+c3ltdGFiLCAmc2VsZi0+c3ltdGFiKTsKKyAgeGZyZWUoc2VsZik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBEZXNjcmlwdG9yUG9vbC5uZXcgPT4gcG9vbAorICoKKyAqIENyZWF0ZXMgYSBuZXcsIGVtcHR5LCBkZXNjcmlwdG9yIHBvb2wuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JQb29sX2FsbG9jKFZBTFVFIGtsYXNzKSB7CisgIERlc2NyaXB0b3JQb29sKiBzZWxmID0gQUxMT0MoRGVzY3JpcHRvclBvb2wpOworICBzZWxmLT5zeW10YWIgPSB1cGJfc3ltdGFiX25ldygmc2VsZi0+c3ltdGFiKTsKKyAgcmV0dXJuIFR5cGVkRGF0YV9XcmFwX1N0cnVjdChrbGFzcywgJl9EZXNjcmlwdG9yUG9vbF90eXBlLCBzZWxmKTsKK30KKwordm9pZCBEZXNjcmlwdG9yUG9vbF9yZWdpc3RlcihWQUxVRSBtb2R1bGUpIHsKKyAgVkFMVUUga2xhc3MgPSByYl9kZWZpbmVfY2xhc3NfdW5kZXIoCisgICAgICBtb2R1bGUsICJEZXNjcmlwdG9yUG9vbCIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgRGVzY3JpcHRvclBvb2xfYWxsb2MpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiYWRkIiwgRGVzY3JpcHRvclBvb2xfYWRkLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImJ1aWxkIiwgRGVzY3JpcHRvclBvb2xfYnVpbGQsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibG9va3VwIiwgRGVzY3JpcHRvclBvb2xfbG9va3VwLCAxKTsKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2Qoa2xhc3MsICJnZW5lcmF0ZWRfcG9vbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sX2dlbmVyYXRlZF9wb29sLCAwKTsKKyAgY0Rlc2NyaXB0b3JQb29sID0ga2xhc3M7CisgIHJiX2djX3JlZ2lzdGVyX2FkZHJlc3MoJmNEZXNjcmlwdG9yUG9vbCk7CisKKyAgZ2VuZXJhdGVkX3Bvb2wgPSByYl9jbGFzc19uZXdfaW5zdGFuY2UoMCwgTlVMTCwga2xhc3MpOworICByYl9nY19yZWdpc3Rlcl9hZGRyZXNzKCZnZW5lcmF0ZWRfcG9vbCk7Cit9CisKK3N0YXRpYyB2b2lkIGFkZF9kZXNjcmlwdG9yX3RvX3Bvb2woRGVzY3JpcHRvclBvb2wqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgQ0hFQ0tfVVBCKAorICAgICAgdXBiX3N5bXRhYl9hZGQoc2VsZi0+c3ltdGFiLCAodXBiX2RlZioqKSZkZXNjcmlwdG9yLT5tc2dkZWYsIDEsCisgICAgICAgICAgICAgICAgICAgICBOVUxMLCAmc3RhdHVzKSwKKyAgICAgICJBZGRpbmcgRGVzY3JpcHRvciB0byBEZXNjcmlwdG9yUG9vbCBmYWlsZWQiKTsKK30KKworc3RhdGljIHZvaWQgYWRkX2VudW1kZXNjX3RvX3Bvb2woRGVzY3JpcHRvclBvb2wqIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtRGVzY3JpcHRvciogZW51bWRlc2MpIHsKKyAgQ0hFQ0tfVVBCKAorICAgICAgdXBiX3N5bXRhYl9hZGQoc2VsZi0+c3ltdGFiLCAodXBiX2RlZioqKSZlbnVtZGVzYy0+ZW51bWRlZiwgMSwKKyAgICAgICAgICAgICAgICAgICAgIE5VTEwsICZzdGF0dXMpLAorICAgICAgIkFkZGluZyBFbnVtRGVzY3JpcHRvciB0byBEZXNjcmlwdG9yUG9vbCBmYWlsZWQiKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIERlc2NyaXB0b3JQb29sLmFkZChkZXNjcmlwdG9yKQorICoKKyAqIEFkZHMgdGhlIGdpdmVuIERlc2NyaXB0b3Igb3IgRW51bURlc2NyaXB0b3IgdG8gdGhpcyBwb29sLiBBbGwgcmVmZXJlbmNlcyB0bworICogb3RoZXIgdHlwZXMgaW4gYSBEZXNjcmlwdG9yJ3MgZmllbGRzIG11c3QgYmUgcmVzb2x2YWJsZSB3aXRoaW4gdGhpcyBwb29sIG9yCisgKiBhbiBleGNlcHRpb24gd2lsbCBiZSByYWlzZWQuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JQb29sX2FkZChWQUxVRSBfc2VsZiwgVkFMVUUgZGVmKSB7CisgIERFRklORV9TRUxGKERlc2NyaXB0b3JQb29sLCBzZWxmLCBfc2VsZik7CisgIFZBTFVFIGRlZl9rbGFzcyA9IHJiX29ial9jbGFzcyhkZWYpOworICBpZiAoZGVmX2tsYXNzID09IGNEZXNjcmlwdG9yKSB7CisgICAgYWRkX2Rlc2NyaXB0b3JfdG9fcG9vbChzZWxmLCBydWJ5X3RvX0Rlc2NyaXB0b3IoZGVmKSk7CisgIH0gZWxzZSBpZiAoZGVmX2tsYXNzID09IGNFbnVtRGVzY3JpcHRvcikgeworICAgIGFkZF9lbnVtZGVzY190b19wb29sKHNlbGYsIHJ1YnlfdG9fRW51bURlc2NyaXB0b3IoZGVmKSk7CisgIH0gZWxzZSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLAorICAgICAgICAgICAgICJTZWNvbmQgYXJndW1lbnQgbXVzdCBiZSBhIERlc2NyaXB0b3Igb3IgRW51bURlc2NyaXB0b3IuIik7CisgIH0KKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBEZXNjcmlwdG9yUG9vbC5idWlsZCgmYmxvY2spCisgKgorICogSW52b2tlcyB0aGUgYmxvY2sgd2l0aCBhIEJ1aWxkZXIgaW5zdGFuY2UgYXMgc2VsZi4gQWxsIG1lc3NhZ2UgYW5kIGVudW0gdHlwZXMKKyAqIGFkZGVkIHdpdGhpbiB0aGUgYmxvY2sgYXJlIGNvbW1pdHRlZCB0byB0aGUgcG9vbCBhdG9taWNhbGx5LCBhbmQgbWF5IHJlZmVyCisgKiAoY28pcmVjdXJzaXZlbHkgdG8gZWFjaCBvdGhlci4gVGhlIHVzZXIgc2hvdWxkIGNhbGwgQnVpbGRlciNhZGRfbWVzc2FnZSBhbmQKKyAqIEJ1aWxkZXIjYWRkX2VudW0gd2l0aGluIHRoZSBibG9jayBhcyBhcHByb3ByaWF0ZS4gIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkLAorICogaWRpb21hdGljIHdheSB0byBkZWZpbmUgbmV3IG1lc3NhZ2UgYW5kIGVudW0gdHlwZXMuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JQb29sX2J1aWxkKFZBTFVFIF9zZWxmKSB7CisgIFZBTFVFIGN0eCA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBjQnVpbGRlcik7CisgIFZBTFVFIGJsb2NrID0gcmJfYmxvY2tfcHJvYygpOworICByYl9mdW5jYWxsX3dpdGhfYmxvY2soY3R4LCByYl9pbnRlcm4oImluc3RhbmNlX2V2YWwiKSwgMCwgTlVMTCwgYmxvY2spOworICByYl9mdW5jYWxsKGN0eCwgcmJfaW50ZXJuKCJmaW5hbGl6ZV90b19wb29sIiksIDEsIF9zZWxmKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBEZXNjcmlwdG9yUG9vbC5sb29rdXAobmFtZSkgPT4gZGVzY3JpcHRvcgorICoKKyAqIEZpbmRzIGEgRGVzY3JpcHRvciBvciBFbnVtRGVzY3JpcHRvciBieSBuYW1lIGFuZCByZXR1cm5zIGl0LCBvciBuaWwgaWYgbm9uZQorICogZXhpc3RzIHdpdGggdGhlIGdpdmVuIG5hbWUuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JQb29sX2xvb2t1cChWQUxVRSBfc2VsZiwgVkFMVUUgbmFtZSkgeworICBERUZJTkVfU0VMRihEZXNjcmlwdG9yUG9vbCwgc2VsZiwgX3NlbGYpOworICBjb25zdCBjaGFyKiBuYW1lX3N0ciA9IGdldF9zdHIobmFtZSk7CisgIGNvbnN0IHVwYl9kZWYqIGRlZiA9IHVwYl9zeW10YWJfbG9va3VwKHNlbGYtPnN5bXRhYiwgbmFtZV9zdHIpOworICBpZiAoIWRlZikgeworICAgIHJldHVybiBRbmlsOworICB9CisgIHJldHVybiBnZXRfZGVmX29iaihkZWYpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wgPT4gZGVzY3JpcHRvcl9wb29sCisgKgorICogQ2xhc3MgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgZ2xvYmFsIERlc2NyaXB0b3JQb29sLiBUaGlzIGlzIGEgc2luZ2xldG9uIGludG8KKyAqIHdoaWNoIGdlbmVyYXRlZC1jb2RlIG1lc3NhZ2UgYW5kIGVudW0gdHlwZXMgYXJlIHJlZ2lzdGVyZWQuIFRoZSB1c2VyIG1heSBhbHNvCisgKiByZWdpc3RlciB0eXBlcyBpbiB0aGlzIHBvb2wgZm9yIGNvbnZlbmllbmNlIHNvIHRoYXQgdGhleSBkbyBub3QgaGF2ZSB0byBob2xkCisgKiBhIHJlZmVyZW5jZSB0byBhIHByaXZhdGUgcG9vbCBpbnN0YW5jZS4KKyAqLworVkFMVUUgRGVzY3JpcHRvclBvb2xfZ2VuZXJhdGVkX3Bvb2woVkFMVUUgX3NlbGYpIHsKKyAgcmV0dXJuIGdlbmVyYXRlZF9wb29sOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRGVzY3JpcHRvci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0RFRklORV9DTEFTUyhEZXNjcmlwdG9yLCAiR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvciIpOworCit2b2lkIERlc2NyaXB0b3JfbWFyayh2b2lkKiBfc2VsZikgeworICBEZXNjcmlwdG9yKiBzZWxmID0gX3NlbGY7CisgIHJiX2djX21hcmsoc2VsZi0+a2xhc3MpOworICByYl9nY19tYXJrKHNlbGYtPnR5cGVjbGFzc19yZWZlcmVuY2VzKTsKK30KKwordm9pZCBEZXNjcmlwdG9yX2ZyZWUodm9pZCogX3NlbGYpIHsKKyAgRGVzY3JpcHRvciogc2VsZiA9IF9zZWxmOworICB1cGJfbXNnZGVmX3VucmVmKHNlbGYtPm1zZ2RlZiwgJnNlbGYtPm1zZ2RlZik7CisgIGlmIChzZWxmLT5sYXlvdXQpIHsKKyAgICBmcmVlX2xheW91dChzZWxmLT5sYXlvdXQpOworICB9CisgIGlmIChzZWxmLT5maWxsX2hhbmRsZXJzKSB7CisgICAgdXBiX2hhbmRsZXJzX3VucmVmKHNlbGYtPmZpbGxfaGFuZGxlcnMsICZzZWxmLT5maWxsX2hhbmRsZXJzKTsKKyAgfQorICBpZiAoc2VsZi0+ZmlsbF9tZXRob2QpIHsKKyAgICB1cGJfcGJkZWNvZGVybWV0aG9kX3VucmVmKHNlbGYtPmZpbGxfbWV0aG9kLCAmc2VsZi0+ZmlsbF9tZXRob2QpOworICB9CisgIGlmIChzZWxmLT5wYl9zZXJpYWxpemVfaGFuZGxlcnMpIHsKKyAgICB1cGJfaGFuZGxlcnNfdW5yZWYoc2VsZi0+cGJfc2VyaWFsaXplX2hhbmRsZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cGJfc2VyaWFsaXplX2hhbmRsZXJzKTsKKyAgfQorICBpZiAoc2VsZi0+anNvbl9zZXJpYWxpemVfaGFuZGxlcnMpIHsKKyAgICB1cGJfaGFuZGxlcnNfdW5yZWYoc2VsZi0+cGJfc2VyaWFsaXplX2hhbmRsZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+anNvbl9zZXJpYWxpemVfaGFuZGxlcnMpOworICB9CisgIHhmcmVlKHNlbGYpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRGVzY3JpcHRvci5uZXcgPT4gZGVzY3JpcHRvcgorICoKKyAqIENyZWF0ZXMgYSBuZXcsIGVtcHR5LCBtZXNzYWdlIHR5cGUgZGVzY3JpcHRvci4gQXQgYSBtaW5pbXVtLCBpdHMgbmFtZSBtdXN0IGJlCisgKiBzZXQgYmVmb3JlIGl0IGlzIGFkZGVkIHRvIGEgcG9vbC4gSXQgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIG1lc3NhZ2VzIHVudGlsCisgKiBpdCBpcyBhZGRlZCB0byBhIHBvb2wsIGFmdGVyIHdoaWNoIGl0IGJlY29tZXMgaW1tdXRhYmxlIChhcyBwYXJ0IG9mIGEKKyAqIGZpbmFsaXphdGlvbiBwcm9jZXNzKS4KKyAqLworVkFMVUUgRGVzY3JpcHRvcl9hbGxvYyhWQUxVRSBrbGFzcykgeworICBEZXNjcmlwdG9yKiBzZWxmID0gQUxMT0MoRGVzY3JpcHRvcik7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdChrbGFzcywgJl9EZXNjcmlwdG9yX3R5cGUsIHNlbGYpOworICBzZWxmLT5tc2dkZWYgPSB1cGJfbXNnZGVmX25ldygmc2VsZi0+bXNnZGVmKTsKKyAgc2VsZi0+a2xhc3MgPSBRbmlsOworICBzZWxmLT5sYXlvdXQgPSBOVUxMOworICBzZWxmLT5maWxsX2hhbmRsZXJzID0gTlVMTDsKKyAgc2VsZi0+ZmlsbF9tZXRob2QgPSBOVUxMOworICBzZWxmLT5wYl9zZXJpYWxpemVfaGFuZGxlcnMgPSBOVUxMOworICBzZWxmLT5qc29uX3NlcmlhbGl6ZV9oYW5kbGVycyA9IE5VTEw7CisgIHNlbGYtPnR5cGVjbGFzc19yZWZlcmVuY2VzID0gcmJfYXJ5X25ldygpOworICByZXR1cm4gcmV0OworfQorCit2b2lkIERlc2NyaXB0b3JfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKSB7CisgIFZBTFVFIGtsYXNzID0gcmJfZGVmaW5lX2NsYXNzX3VuZGVyKAorICAgICAgbW9kdWxlLCAiRGVzY3JpcHRvciIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgRGVzY3JpcHRvcl9hbGxvYyk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJlYWNoIiwgRGVzY3JpcHRvcl9lYWNoLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImxvb2t1cCIsIERlc2NyaXB0b3JfbG9va3VwLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImFkZF9maWVsZCIsIERlc2NyaXB0b3JfYWRkX2ZpZWxkLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImFkZF9vbmVvZiIsIERlc2NyaXB0b3JfYWRkX29uZW9mLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImVhY2hfb25lb2YiLCBEZXNjcmlwdG9yX2VhY2hfb25lb2YsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibG9va3VwX29uZW9mIiwgRGVzY3JpcHRvcl9sb29rdXBfb25lb2YsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibXNnY2xhc3MiLCBEZXNjcmlwdG9yX21zZ2NsYXNzLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm5hbWUiLCBEZXNjcmlwdG9yX25hbWUsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibmFtZT0iLCBEZXNjcmlwdG9yX25hbWVfc2V0LCAxKTsKKyAgcmJfaW5jbHVkZV9tb2R1bGUoa2xhc3MsIHJiX21FbnVtZXJhYmxlKTsKKyAgY0Rlc2NyaXB0b3IgPSBrbGFzczsKKyAgcmJfZ2NfcmVnaXN0ZXJfYWRkcmVzcygmY0Rlc2NyaXB0b3IpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRGVzY3JpcHRvci5uYW1lID0+IG5hbWUKKyAqCisgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgbWVzc2FnZSB0eXBlIGFzIGEgZnVsbHktcXVhbGZpZWQgc3RyaW5nIChlLmcuLAorICogTXkuUGFja2FnZS5NZXNzYWdlVHlwZSkuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JfbmFtZShWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihEZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHJldHVybiByYl9zdHJfbWF5YmVfbnVsbCh1cGJfbXNnZGVmX2Z1bGxuYW1lKHNlbGYtPm1zZ2RlZikpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICBEZXNjcmlwdG9yLm5hbWUgPSBuYW1lCisgKgorICogQXNzaWducyBhIG5hbWUgdG8gdGhpcyBtZXNzYWdlIHR5cGUuIFRoZSBkZXNjcmlwdG9yIG11c3Qgbm90IGhhdmUgYmVlbiBhZGRlZAorICogdG8gYSBwb29sIHlldC4KKyAqLworVkFMVUUgRGVzY3JpcHRvcl9uYW1lX3NldChWQUxVRSBfc2VsZiwgVkFMVUUgc3RyKSB7CisgIERFRklORV9TRUxGKERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgdXBiX21zZ2RlZiogbXV0X2RlZiA9IGNoZWNrX21zZ19ub3Rmcm96ZW4oc2VsZi0+bXNnZGVmKTsKKyAgY29uc3QgY2hhciogbmFtZSA9IGdldF9zdHIoc3RyKTsKKyAgQ0hFQ0tfVVBCKAorICAgICAgdXBiX21zZ2RlZl9zZXRmdWxsbmFtZShtdXRfZGVmLCBuYW1lLCAmc3RhdHVzKSwKKyAgICAgICJFcnJvciBzZXR0aW5nIERlc2NyaXB0b3IgbmFtZSIpOworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIERlc2NyaXB0b3IuZWFjaCgmYmxvY2spCisgKgorICogSXRlcmF0ZXMgb3ZlciBmaWVsZHMgaW4gdGhpcyBtZXNzYWdlIHR5cGUsIHlpZWxkaW5nIHRvIHRoZSBibG9jayBvbiBlYWNoIG9uZS4KKyAqLworVkFMVUUgRGVzY3JpcHRvcl9lYWNoKFZBTFVFIF9zZWxmKSB7CisgIERFRklORV9TRUxGKERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaXQ7CisgIGZvciAodXBiX21zZ19maWVsZF9iZWdpbigmaXQsIHNlbGYtPm1zZ2RlZik7CisgICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaXQpOworICAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaXQpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaXQpOworICAgIFZBTFVFIG9iaiA9IGdldF9kZWZfb2JqKGZpZWxkKTsKKyAgICByYl95aWVsZChvYmopOworICB9CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRGVzY3JpcHRvci5sb29rdXAobmFtZSkgPT4gRmllbGREZXNjcmlwdG9yCisgKgorICogUmV0dXJucyB0aGUgZmllbGQgZGVzY3JpcHRvciBmb3IgdGhlIGZpZWxkIHdpdGggdGhlIGdpdmVuIG5hbWUsIGlmIHByZXNlbnQsCisgKiBvciBuaWwgaWYgbm9uZS4KKyAqLworVkFMVUUgRGVzY3JpcHRvcl9sb29rdXAoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpIHsKKyAgREVGSU5FX1NFTEYoRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICBjb25zdCBjaGFyKiBzID0gZ2V0X3N0cihuYW1lKTsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9IHVwYl9tc2dkZWZfbnRvZnooc2VsZi0+bXNnZGVmLCBzKTsKKyAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICByZXR1cm4gUW5pbDsKKyAgfQorICByZXR1cm4gZ2V0X2RlZl9vYmooZmllbGQpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRGVzY3JpcHRvci5hZGRfZmllbGQoZmllbGQpID0+IG5pbAorICoKKyAqIEFkZHMgdGhlIGdpdmVuIEZpZWxkRGVzY3JpcHRvciB0byB0aGlzIG1lc3NhZ2UgdHlwZS4gVGhpcyBkZXNjcmlwdG9yIG11c3Qgbm90CisgKiBoYXZlIGJlZW4gYWRkZWQgdG8gYSBwb29sIHlldC4gUmFpc2VzIGFuIGV4Y2VwdGlvbiBpZiBhIGZpZWxkIHdpdGggdGhlIHNhbWUKKyAqIG5hbWUgb3IgbnVtYmVyIGFscmVhZHkgZXhpc3RzLiBTdWItdHlwZSByZWZlcmVuY2VzIChlLmcuIGZvciBmaWVsZHMgb2YgdHlwZQorICogbWVzc2FnZSkgYXJlIG5vdCByZXNvbHZlZCBhdCB0aGlzIHBvaW50LgorICovCitWQUxVRSBEZXNjcmlwdG9yX2FkZF9maWVsZChWQUxVRSBfc2VsZiwgVkFMVUUgb2JqKSB7CisgIERFRklORV9TRUxGKERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgdXBiX21zZ2RlZiogbXV0X2RlZiA9IGNoZWNrX21zZ19ub3Rmcm96ZW4oc2VsZi0+bXNnZGVmKTsKKyAgRmllbGREZXNjcmlwdG9yKiBkZWYgPSBydWJ5X3RvX0ZpZWxkRGVzY3JpcHRvcihvYmopOworICB1cGJfZmllbGRkZWYqIG11dF9maWVsZF9kZWYgPSBjaGVja19maWVsZF9ub3Rmcm96ZW4oZGVmLT5maWVsZGRlZik7CisgIENIRUNLX1VQQigKKyAgICAgIHVwYl9tc2dkZWZfYWRkZmllbGQobXV0X2RlZiwgbXV0X2ZpZWxkX2RlZiwgTlVMTCwgJnN0YXR1cyksCisgICAgICAiQWRkaW5nIGZpZWxkIHRvIERlc2NyaXB0b3IgZmFpbGVkIik7CisgIGFkZF9kZWZfb2JqKGRlZi0+ZmllbGRkZWYsIG9iaik7CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRGVzY3JpcHRvci5hZGRfb25lb2Yob25lb2YpID0+IG5pbAorICoKKyAqIEFkZHMgdGhlIGdpdmVuIE9uZW9mRGVzY3JpcHRvciB0byB0aGlzIG1lc3NhZ2UgdHlwZS4gVGhpcyBkZXNjcmlwdG9yIG11c3Qgbm90CisgKiBoYXZlIGJlZW4gYWRkZWQgdG8gYSBwb29sIHlldC4gUmFpc2VzIGFuIGV4Y2VwdGlvbiBpZiBhIG9uZW9mIHdpdGggdGhlIHNhbWUKKyAqIG5hbWUgYWxyZWFkeSBleGlzdHMsIG9yIGlmIGFueSBvZiB0aGUgb25lb2YncyBmaWVsZHMnIG5hbWVzIG9yIG51bWJlcnMKKyAqIGNvbmZsaWN0IHdpdGggYW4gZXhpc3RpbmcgZmllbGQgaW4gdGhpcyBtZXNzYWdlIHR5cGUuIEFsbCBmaWVsZHMgaW4gdGhlIG9uZW9mCisgKiBhcmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UgZGVzY3JpcHRvci4gU3ViLXR5cGUgcmVmZXJlbmNlcyAoZS5nLiBmb3IgZmllbGRzIG9mCisgKiB0eXBlIG1lc3NhZ2UpIGFyZSBub3QgcmVzb2x2ZWQgYXQgdGhpcyBwb2ludC4KKyAqLworVkFMVUUgRGVzY3JpcHRvcl9hZGRfb25lb2YoVkFMVUUgX3NlbGYsIFZBTFVFIG9iaikgeworICBERUZJTkVfU0VMRihEZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHVwYl9tc2dkZWYqIG11dF9kZWYgPSBjaGVja19tc2dfbm90ZnJvemVuKHNlbGYtPm1zZ2RlZik7CisgIE9uZW9mRGVzY3JpcHRvciogZGVmID0gcnVieV90b19PbmVvZkRlc2NyaXB0b3Iob2JqKTsKKyAgdXBiX29uZW9mZGVmKiBtdXRfb25lb2ZfZGVmID0gY2hlY2tfb25lb2Zfbm90ZnJvemVuKGRlZi0+b25lb2ZkZWYpOworICBDSEVDS19VUEIoCisgICAgICB1cGJfbXNnZGVmX2FkZG9uZW9mKG11dF9kZWYsIG11dF9vbmVvZl9kZWYsIE5VTEwsICZzdGF0dXMpLAorICAgICAgIkFkZGluZyBvbmVvZiB0byBEZXNjcmlwdG9yIGZhaWxlZCIpOworICBhZGRfZGVmX29iaihkZWYtPm9uZW9mZGVmLCBvYmopOworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIERlc2NyaXB0b3IuZWFjaF9vbmVvZigmYmxvY2spID0+IG5pbAorICoKKyAqIEludm9rZXMgdGhlIGdpdmVuIGJsb2NrIGZvciBlYWNoIG9uZW9mIGluIHRoaXMgbWVzc2FnZSB0eXBlLCBwYXNzaW5nIHRoZQorICogY29ycmVzcG9uZGluZyBPbmVvZkRlc2NyaXB0b3IuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JfZWFjaF9vbmVvZihWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihEZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisKKyAgdXBiX21zZ19vbmVvZl9pdGVyIGl0OworICBmb3IgKHVwYl9tc2dfb25lb2ZfYmVnaW4oJml0LCBzZWxmLT5tc2dkZWYpOworICAgICAgICF1cGJfbXNnX29uZW9mX2RvbmUoJml0KTsKKyAgICAgICB1cGJfbXNnX29uZW9mX25leHQoJml0KSkgeworICAgIGNvbnN0IHVwYl9vbmVvZmRlZiogb25lb2YgPSB1cGJfbXNnX2l0ZXJfb25lb2YoJml0KTsKKyAgICBWQUxVRSBvYmogPSBnZXRfZGVmX29iaihvbmVvZik7CisgICAgcmJfeWllbGQob2JqKTsKKyAgfQorICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIERlc2NyaXB0b3IubG9va3VwX29uZW9mKG5hbWUpID0+IE9uZW9mRGVzY3JpcHRvcgorICoKKyAqIFJldHVybnMgdGhlIG9uZW9mIGRlc2NyaXB0b3IgZm9yIHRoZSBvbmVvZiB3aXRoIHRoZSBnaXZlbiBuYW1lLCBpZiBwcmVzZW50LAorICogb3IgbmlsIGlmIG5vbmUuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JfbG9va3VwX29uZW9mKFZBTFVFIF9zZWxmLCBWQUxVRSBuYW1lKSB7CisgIERFRklORV9TRUxGKERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgY29uc3QgY2hhciogcyA9IGdldF9zdHIobmFtZSk7CisgIGNvbnN0IHVwYl9vbmVvZmRlZiogb25lb2YgPSB1cGJfbXNnZGVmX250b296KHNlbGYtPm1zZ2RlZiwgcyk7CisgIGlmIChvbmVvZiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIFFuaWw7CisgIH0KKyAgcmV0dXJuIGdldF9kZWZfb2JqKG9uZW9mKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIERlc2NyaXB0b3IubXNnY2xhc3MgPT4gbWVzc2FnZV9rbGFzcworICoKKyAqIFJldHVybnMgdGhlIFJ1YnkgY2xhc3MgY3JlYXRlZCBmb3IgdGhpcyBtZXNzYWdlIHR5cGUuIFZhbGlkIG9ubHkgb25jZSB0aGUKKyAqIG1lc3NhZ2UgdHlwZSBoYXMgYmVlbiBhZGRlZCB0byBhIHBvb2wuCisgKi8KK1ZBTFVFIERlc2NyaXB0b3JfbXNnY2xhc3MoVkFMVUUgX3NlbGYpIHsKKyAgREVGSU5FX1NFTEYoRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICBpZiAoIXVwYl9kZWZfaXNmcm96ZW4oKGNvbnN0IHVwYl9kZWYqKXNlbGYtPm1zZ2RlZikpIHsKKyAgICByYl9yYWlzZShyYl9lUnVudGltZUVycm9yLAorICAgICAgICAgICAgICJDYW5ub3QgZmV0Y2ggbWVzc2FnZSBjbGFzcyBmcm9tIGEgRGVzY3JpcHRvciBub3QgeWV0IGluIGEgcG9vbC4iKTsKKyAgfQorICBpZiAoc2VsZi0+a2xhc3MgPT0gUW5pbCkgeworICAgIHNlbGYtPmtsYXNzID0gYnVpbGRfY2xhc3NfZnJvbV9kZXNjcmlwdG9yKHNlbGYpOworICB9CisgIHJldHVybiBzZWxmLT5rbGFzczsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEZpZWxkRGVzY3JpcHRvci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0RFRklORV9DTEFTUyhGaWVsZERlc2NyaXB0b3IsICJHb29nbGU6OlByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IiKTsKKwordm9pZCBGaWVsZERlc2NyaXB0b3JfbWFyayh2b2lkKiBfc2VsZikgeworfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvcl9mcmVlKHZvaWQqIF9zZWxmKSB7CisgIEZpZWxkRGVzY3JpcHRvciogc2VsZiA9IF9zZWxmOworICB1cGJfZmllbGRkZWZfdW5yZWYoc2VsZi0+ZmllbGRkZWYsICZzZWxmLT5maWVsZGRlZik7CisgIHhmcmVlKHNlbGYpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRmllbGREZXNjcmlwdG9yLm5ldyA9PiBmaWVsZAorICoKKyAqIFJldHVybnMgYSBuZXcgZmllbGQgZGVzY3JpcHRvci4gSXRzIG5hbWUsIHR5cGUsIGV0Yy4gbXVzdCBiZSBzZXQgYmVmb3JlIGl0IGlzCisgKiBhZGRlZCB0byBhIG1lc3NhZ2UgdHlwZS4KKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX2FsbG9jKFZBTFVFIGtsYXNzKSB7CisgIEZpZWxkRGVzY3JpcHRvciogc2VsZiA9IEFMTE9DKEZpZWxkRGVzY3JpcHRvcik7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdChrbGFzcywgJl9GaWVsZERlc2NyaXB0b3JfdHlwZSwgc2VsZik7CisgIHVwYl9maWVsZGRlZiogZmllbGRkZWYgPSB1cGJfZmllbGRkZWZfbmV3KCZzZWxmLT5maWVsZGRlZik7CisgIHVwYl9maWVsZGRlZl9zZXRwYWNrZWQoZmllbGRkZWYsIGZhbHNlKTsKKyAgc2VsZi0+ZmllbGRkZWYgPSBmaWVsZGRlZjsKKyAgcmV0dXJuIHJldDsKK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3JfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKSB7CisgIFZBTFVFIGtsYXNzID0gcmJfZGVmaW5lX2NsYXNzX3VuZGVyKAorICAgICAgbW9kdWxlLCAiRmllbGREZXNjcmlwdG9yIiwgcmJfY09iamVjdCk7CisgIHJiX2RlZmluZV9hbGxvY19mdW5jKGtsYXNzLCBGaWVsZERlc2NyaXB0b3JfYWxsb2MpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibmFtZSIsIEZpZWxkRGVzY3JpcHRvcl9uYW1lLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm5hbWU9IiwgRmllbGREZXNjcmlwdG9yX25hbWVfc2V0LCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgInR5cGUiLCBGaWVsZERlc2NyaXB0b3JfdHlwZSwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJ0eXBlPSIsIEZpZWxkRGVzY3JpcHRvcl90eXBlX3NldCwgMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJsYWJlbCIsIEZpZWxkRGVzY3JpcHRvcl9sYWJlbCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJsYWJlbD0iLCBGaWVsZERlc2NyaXB0b3JfbGFiZWxfc2V0LCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm51bWJlciIsIEZpZWxkRGVzY3JpcHRvcl9udW1iZXIsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibnVtYmVyPSIsIEZpZWxkRGVzY3JpcHRvcl9udW1iZXJfc2V0LCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgInN1Ym1zZ19uYW1lIiwgRmllbGREZXNjcmlwdG9yX3N1Ym1zZ19uYW1lLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgInN1Ym1zZ19uYW1lPSIsIEZpZWxkRGVzY3JpcHRvcl9zdWJtc2dfbmFtZV9zZXQsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAic3VidHlwZSIsIEZpZWxkRGVzY3JpcHRvcl9zdWJ0eXBlLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImdldCIsIEZpZWxkRGVzY3JpcHRvcl9nZXQsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAic2V0IiwgRmllbGREZXNjcmlwdG9yX3NldCwgMik7CisgIGNGaWVsZERlc2NyaXB0b3IgPSBrbGFzczsKKyAgcmJfZ2NfcmVnaXN0ZXJfYWRkcmVzcygmY0ZpZWxkRGVzY3JpcHRvcik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBGaWVsZERlc2NyaXB0b3IubmFtZSA9PiBuYW1lCisgKgorICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGZpZWxkLgorICovCitWQUxVRSBGaWVsZERlc2NyaXB0b3JfbmFtZShWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihGaWVsZERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgcmV0dXJuIHJiX3N0cl9tYXliZV9udWxsKHVwYl9maWVsZGRlZl9uYW1lKHNlbGYtPmZpZWxkZGVmKSk7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBGaWVsZERlc2NyaXB0b3IubmFtZSA9IG5hbWUKKyAqCisgKiBTZXRzIHRoZSBuYW1lIG9mIHRoaXMgZmllbGQuIENhbm5vdCBiZSBjYWxsZWQgb25jZSB0aGUgY29udGFpbmluZyBtZXNzYWdlCisgKiB0eXBlLCBpZiBhbnksIGlzIGFkZGVkIHRvIGEgcG9vbC4KKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX25hbWVfc2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBzdHIpIHsKKyAgREVGSU5FX1NFTEYoRmllbGREZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHVwYl9maWVsZGRlZiogbXV0X2RlZiA9IGNoZWNrX2ZpZWxkX25vdGZyb3plbihzZWxmLT5maWVsZGRlZik7CisgIGNvbnN0IGNoYXIqIG5hbWUgPSBnZXRfc3RyKHN0cik7CisgIENIRUNLX1VQQih1cGJfZmllbGRkZWZfc2V0bmFtZShtdXRfZGVmLCBuYW1lLCAmc3RhdHVzKSwKKyAgICAgICAgICAgICJFcnJvciBzZXR0aW5nIEZpZWxkRGVzY3JpcHRvciBuYW1lIik7CisgIHJldHVybiBRbmlsOworfQorCit1cGJfZmllbGR0eXBlX3QgcnVieV90b19maWVsZHR5cGUoVkFMVUUgdHlwZSkgeworICBpZiAoVFlQRSh0eXBlKSAhPSBUX1NZTUJPTCkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIHN5bWJvbCBmb3IgZmllbGQgdHlwZS4iKTsKKyAgfQorCisgIHVwYl9maWVsZHR5cGVfdCB1cGJfdHlwZSA9IC0xOworCisjZGVmaW5lIENPTlZFUlQodXBiLCBydWJ5KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlmIChTWU0ySUQodHlwZSkgPT0gcmJfaW50ZXJuKCAjIHJ1YnkgKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdXBiX3R5cGUgPSBVUEJfVFlQRV8gIyMgdXBiOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKworICBDT05WRVJUKEZMT0FULCBmbG9hdCk7CisgIENPTlZFUlQoRE9VQkxFLCBkb3VibGUpOworICBDT05WRVJUKEJPT0wsIGJvb2wpOworICBDT05WRVJUKFNUUklORywgc3RyaW5nKTsKKyAgQ09OVkVSVChCWVRFUywgYnl0ZXMpOworICBDT05WRVJUKE1FU1NBR0UsIG1lc3NhZ2UpOworICBDT05WRVJUKEVOVU0sIGVudW0pOworICBDT05WRVJUKElOVDMyLCBpbnQzMik7CisgIENPTlZFUlQoSU5UNjQsIGludDY0KTsKKyAgQ09OVkVSVChVSU5UMzIsIHVpbnQzMik7CisgIENPTlZFUlQoVUlOVDY0LCB1aW50NjQpOworCisjdW5kZWYgQ09OVkVSVAorCisgIGlmICh1cGJfdHlwZSA9PSAtMSkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIlVua25vd24gZmllbGQgdHlwZS4iKTsKKyAgfQorCisgIHJldHVybiB1cGJfdHlwZTsKK30KKworVkFMVUUgZmllbGR0eXBlX3RvX3J1YnkodXBiX2ZpZWxkdHlwZV90IHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisjZGVmaW5lIENPTlZFUlQodXBiLCBydWJ5KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2FzZSBVUEJfVFlQRV8gIyMgdXBiIDogcmV0dXJuIElEMlNZTShyYl9pbnRlcm4oICMgcnVieSApKTsKKyAgICBDT05WRVJUKEZMT0FULCBmbG9hdCk7CisgICAgQ09OVkVSVChET1VCTEUsIGRvdWJsZSk7CisgICAgQ09OVkVSVChCT09MLCBib29sKTsKKyAgICBDT05WRVJUKFNUUklORywgc3RyaW5nKTsKKyAgICBDT05WRVJUKEJZVEVTLCBieXRlcyk7CisgICAgQ09OVkVSVChNRVNTQUdFLCBtZXNzYWdlKTsKKyAgICBDT05WRVJUKEVOVU0sIGVudW0pOworICAgIENPTlZFUlQoSU5UMzIsIGludDMyKTsKKyAgICBDT05WRVJUKElOVDY0LCBpbnQ2NCk7CisgICAgQ09OVkVSVChVSU5UMzIsIHVpbnQzMik7CisgICAgQ09OVkVSVChVSU5UNjQsIHVpbnQ2NCk7CisjdW5kZWYgQ09OVkVSVAorICB9CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRmllbGREZXNjcmlwdG9yLnR5cGUgPT4gdHlwZQorICoKKyAqIFJldHVybnMgdGhpcyBmaWVsZCdzIHR5cGUsIGFzIGEgUnVieSBzeW1ib2wsIG9yIG5pbCBpZiBub3QgeWV0IHNldC4KKyAqCisgKiBWYWxpZCBmaWVsZCB0eXBlcyBhcmU6CisgKiAgICAgOmludDMyLCA6aW50NjQsIDp1aW50MzIsIDp1aW50NjQsIDpmbG9hdCwgOmRvdWJsZSwgOmJvb2wsIDpzdHJpbmcsCisgKiAgICAgOmJ5dGVzLCA6bWVzc2FnZS4KKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX3R5cGUoVkFMVUUgX3NlbGYpIHsKKyAgREVGSU5FX1NFTEYoRmllbGREZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIGlmICghdXBiX2ZpZWxkZGVmX3R5cGVpc3NldChzZWxmLT5maWVsZGRlZikpIHsKKyAgICByZXR1cm4gUW5pbDsKKyAgfQorICByZXR1cm4gZmllbGR0eXBlX3RvX3J1YnkodXBiX2ZpZWxkZGVmX3R5cGUoc2VsZi0+ZmllbGRkZWYpKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEZpZWxkRGVzY3JpcHRvci50eXBlID0gdHlwZQorICoKKyAqIFNldHMgdGhpcyBmaWVsZCdzIHR5cGUuIENhbm5vdCBiZSBjYWxsZWQgaWYgZmllbGQgaXMgcGFydCBvZiBhIG1lc3NhZ2UgdHlwZQorICogYWxyZWFkeSBpbiBhIHBvb2wuCisgKi8KK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl90eXBlX3NldChWQUxVRSBfc2VsZiwgVkFMVUUgdHlwZSkgeworICBERUZJTkVfU0VMRihGaWVsZERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgdXBiX2ZpZWxkZGVmKiBtdXRfZGVmID0gY2hlY2tfZmllbGRfbm90ZnJvemVuKHNlbGYtPmZpZWxkZGVmKTsKKyAgdXBiX2ZpZWxkZGVmX3NldHR5cGUobXV0X2RlZiwgcnVieV90b19maWVsZHR5cGUodHlwZSkpOworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEZpZWxkRGVzY3JpcHRvci5sYWJlbCA9PiBsYWJlbAorICoKKyAqIFJldHVybnMgdGhpcyBmaWVsZCdzIGxhYmVsIChpLmUuLCBwbHVyYWxpdHkpLCBhcyBhIFJ1Ynkgc3ltYm9sLgorICoKKyAqIFZhbGlkIGZpZWxkIGxhYmVscyBhcmU6CisgKiAgICAgOm9wdGlvbmFsLCA6cmVwZWF0ZWQKKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX2xhYmVsKFZBTFVFIF9zZWxmKSB7CisgIERFRklORV9TRUxGKEZpZWxkRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICBzd2l0Y2ggKHVwYl9maWVsZGRlZl9sYWJlbChzZWxmLT5maWVsZGRlZikpIHsKKyNkZWZpbmUgQ09OVkVSVCh1cGIsIHJ1YnkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjYXNlIFVQQl9MQUJFTF8gIyMgdXBiIDogcmV0dXJuIElEMlNZTShyYl9pbnRlcm4oICMgcnVieSApKTsKKworICAgIENPTlZFUlQoT1BUSU9OQUwsIG9wdGlvbmFsKTsKKyAgICBDT05WRVJUKFJFUVVJUkVELCByZXF1aXJlZCk7CisgICAgQ09OVkVSVChSRVBFQVRFRCwgcmVwZWF0ZWQpOworCisjdW5kZWYgQ09OVkVSVAorICB9CisKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBGaWVsZERlc2NyaXB0b3IubGFiZWwgPSBsYWJlbAorICoKKyAqIFNldHMgdGhlIGxhYmVsIG9uIHRoaXMgZmllbGQuIENhbm5vdCBiZSBjYWxsZWQgaWYgZmllbGQgaXMgcGFydCBvZiBhIG1lc3NhZ2UKKyAqIHR5cGUgYWxyZWFkeSBpbiBhIHBvb2wuCisgKi8KK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9sYWJlbF9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIGxhYmVsKSB7CisgIERFRklORV9TRUxGKEZpZWxkRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICB1cGJfZmllbGRkZWYqIG11dF9kZWYgPSBjaGVja19maWVsZF9ub3Rmcm96ZW4oc2VsZi0+ZmllbGRkZWYpOworICBpZiAoVFlQRShsYWJlbCkgIT0gVF9TWU1CT0wpIHsKKyAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsICJFeHBlY3RlZCBzeW1ib2wgZm9yIGZpZWxkIGxhYmVsLiIpOworICB9CisKKyAgdXBiX2xhYmVsX3QgdXBiX2xhYmVsID0gLTE7CisKKyNkZWZpbmUgQ09OVkVSVCh1cGIsIHJ1YnkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaWYgKFNZTTJJRChsYWJlbCkgPT0gcmJfaW50ZXJuKCAjIHJ1YnkgKSkgeyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB1cGJfbGFiZWwgPSBVUEJfTEFCRUxfICMjIHVwYjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCisgIENPTlZFUlQoT1BUSU9OQUwsIG9wdGlvbmFsKTsKKyAgQ09OVkVSVChSRVFVSVJFRCwgcmVxdWlyZWQpOworICBDT05WRVJUKFJFUEVBVEVELCByZXBlYXRlZCk7CisKKyN1bmRlZiBDT05WRVJUCisKKyAgaWYgKHVwYl9sYWJlbCA9PSAtMSkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIlVua25vd24gZmllbGQgbGFiZWwuIik7CisgIH0KKworICB1cGJfZmllbGRkZWZfc2V0bGFiZWwobXV0X2RlZiwgdXBiX2xhYmVsKTsKKworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEZpZWxkRGVzY3JpcHRvci5udW1iZXIgPT4gbnVtYmVyCisgKgorICogUmV0dXJucyB0aGUgdGFnIG51bWJlciBmb3IgdGhpcyBmaWVsZC4KKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX251bWJlcihWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihGaWVsZERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgcmV0dXJuIElOVDJOVU0odXBiX2ZpZWxkZGVmX251bWJlcihzZWxmLT5maWVsZGRlZikpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRmllbGREZXNjcmlwdG9yLm51bWJlciA9IG51bWJlcgorICoKKyAqIFNldHMgdGhlIHRhZyBudW1iZXIgZm9yIHRoaXMgZmllbGQuIENhbm5vdCBiZSBjYWxsZWQgaWYgZmllbGQgaXMgcGFydCBvZiBhCisgKiBtZXNzYWdlIHR5cGUgYWxyZWFkeSBpbiBhIHBvb2wuCisgKi8KK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9udW1iZXJfc2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBudW1iZXIpIHsKKyAgREVGSU5FX1NFTEYoRmllbGREZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHVwYl9maWVsZGRlZiogbXV0X2RlZiA9IGNoZWNrX2ZpZWxkX25vdGZyb3plbihzZWxmLT5maWVsZGRlZik7CisgIENIRUNLX1VQQih1cGJfZmllbGRkZWZfc2V0bnVtYmVyKG11dF9kZWYsIE5VTTJJTlQobnVtYmVyKSwgJnN0YXR1cyksCisgICAgICAgICAgICAiRXJyb3Igc2V0dGluZyBmaWVsZCBudW1iZXIiKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBGaWVsZERlc2NyaXB0b3Iuc3VibXNnX25hbWUgPT4gc3VibXNnX25hbWUKKyAqCisgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIG9yIGVudW0gdHlwZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZmllbGQsIGlmCisgKiBpdCBpcyBhIG1lc3NhZ2Ugb3IgZW51bSBmaWVsZCAocmVzcGVjdGl2ZWx5KSwgb3IgbmlsIG90aGVyd2lzZS4gVGhpcyB0eXBlCisgKiBuYW1lIHdpbGwgYmUgcmVzb2x2ZWQgd2l0aGluIHRoZSBjb250ZXh0IG9mIHRoZSBwb29sIHRvIHdoaWNoIHRoZSBjb250YWluaW5nCisgKiBtZXNzYWdlIHR5cGUgaXMgYWRkZWQuCisgKi8KK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9zdWJtc2dfbmFtZShWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihGaWVsZERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgaWYgKCF1cGJfZmllbGRkZWZfaGFzc3ViZGVmKHNlbGYtPmZpZWxkZGVmKSkgeworICAgIHJldHVybiBRbmlsOworICB9CisgIHJldHVybiByYl9zdHJfbWF5YmVfbnVsbCh1cGJfZmllbGRkZWZfc3ViZGVmbmFtZShzZWxmLT5maWVsZGRlZikpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRmllbGREZXNjcmlwdG9yLnN1Ym1zZ19uYW1lID0gc3VibXNnX25hbWUKKyAqCisgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIG9yIGVudW0gdHlwZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZmllbGQsIGlmIGl0CisgKiBpcyBhIG1lc3NhZ2Ugb3IgZW51bSBmaWVsZCAocmVzcGVjdGl2ZWx5KS4gVGhpcyB0eXBlIG5hbWUgd2lsbCBiZSByZXNvbHZlZAorICogd2l0aGluIHRoZSBjb250ZXh0IG9mIHRoZSBwb29sIHRvIHdoaWNoIHRoZSBjb250YWluaW5nIG1lc3NhZ2UgdHlwZSBpcyBhZGRlZC4KKyAqIENhbm5vdCBiZSBjYWxsZWQgb24gZmllbGQgdGhhdCBhcmUgbm90IG9mIG1lc3NhZ2Ugb3IgZW51bSB0eXBlLCBvciBvbiBmaWVsZHMKKyAqIHRoYXQgYXJlIHBhcnQgb2YgYSBtZXNzYWdlIHR5cGUgYWxyZWFkeSBhZGRlZCB0byBhIHBvb2wuCisgKi8KK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9zdWJtc2dfbmFtZV9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIHZhbHVlKSB7CisgIERFRklORV9TRUxGKEZpZWxkRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICB1cGJfZmllbGRkZWYqIG11dF9kZWYgPSBjaGVja19maWVsZF9ub3Rmcm96ZW4oc2VsZi0+ZmllbGRkZWYpOworICBpZiAoIXVwYl9maWVsZGRlZl9oYXNzdWJkZWYoc2VsZi0+ZmllbGRkZWYpKSB7CisgICAgcmJfcmFpc2UocmJfZVR5cGVFcnJvciwgIkZpZWxkRGVzY3JpcHRvciBkb2VzIG5vdCBoYXZlIHN1YmRlZi4iKTsKKyAgfQorICBjb25zdCBjaGFyKiBzdHIgPSBnZXRfc3RyKHZhbHVlKTsKKyAgQ0hFQ0tfVVBCKHVwYl9maWVsZGRlZl9zZXRzdWJkZWZuYW1lKG11dF9kZWYsIHN0ciwgJnN0YXR1cyksCisgICAgICAgICAgICAiRXJyb3Igc2V0dGluZyBzdWJtZXNzYWdlIG5hbWUiKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBGaWVsZERlc2NyaXB0b3Iuc3VidHlwZSA9PiBtZXNzYWdlX29yX2VudW1fZGVzY3JpcHRvcgorICoKKyAqIFJldHVybnMgdGhlIG1lc3NhZ2Ugb3IgZW51bSBkZXNjcmlwdG9yIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBmaWVsZCdzIHR5cGUgaWYKKyAqIGl0IGlzIGEgbWVzc2FnZSBvciBlbnVtIGZpZWxkLCByZXNwZWN0aXZlbHksIG9yIG5pbCBvdGhlcndpc2UuIENhbm5vdCBiZQorICogY2FsbGVkICp1bnRpbCogdGhlIGNvbnRhaW5pbmcgbWVzc2FnZSB0eXBlIGlzIGFkZGVkIHRvIGEgcG9vbCAoYW5kIHRodXMKKyAqIHJlc29sdmVkKS4KKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX3N1YnR5cGUoVkFMVUUgX3NlbGYpIHsKKyAgREVGSU5FX1NFTEYoRmllbGREZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIGlmICghdXBiX2ZpZWxkZGVmX2hhc3N1YmRlZihzZWxmLT5maWVsZGRlZikpIHsKKyAgICByZXR1cm4gUW5pbDsKKyAgfQorICBjb25zdCB1cGJfZGVmKiBkZWYgPSB1cGJfZmllbGRkZWZfc3ViZGVmKHNlbGYtPmZpZWxkZGVmKTsKKyAgaWYgKGRlZiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIFFuaWw7CisgIH0KKyAgcmV0dXJuIGdldF9kZWZfb2JqKGRlZik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBGaWVsZERlc2NyaXB0b3IuZ2V0KG1lc3NhZ2UpID0+IHZhbHVlCisgKgorICogUmV0dXJucyB0aGUgdmFsdWUgc2V0IGZvciB0aGlzIGZpZWxkIG9uIHRoZSBnaXZlbiBtZXNzYWdlLiBSYWlzZXMgYW4KKyAqIGV4Y2VwdGlvbiBpZiBtZXNzYWdlIGlzIG9mIHRoZSB3cm9uZyB0eXBlLgorICovCitWQUxVRSBGaWVsZERlc2NyaXB0b3JfZ2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBtc2dfcmIpIHsKKyAgREVGSU5FX1NFTEYoRmllbGREZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIE1lc3NhZ2VIZWFkZXIqIG1zZzsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QobXNnX3JiLCBNZXNzYWdlSGVhZGVyLCAmTWVzc2FnZV90eXBlLCBtc2cpOworICBpZiAobXNnLT5kZXNjcmlwdG9yLT5tc2dkZWYgIT0gdXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlKHNlbGYtPmZpZWxkZGVmKSkgeworICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsICJnZXQgbWV0aG9kIGNhbGxlZCBvbiB3cm9uZyBtZXNzYWdlIHR5cGUiKTsKKyAgfQorICByZXR1cm4gbGF5b3V0X2dldChtc2ctPmRlc2NyaXB0b3ItPmxheW91dCwgTWVzc2FnZV9kYXRhKG1zZyksIHNlbGYtPmZpZWxkZGVmKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEZpZWxkRGVzY3JpcHRvci5zZXQobWVzc2FnZSwgdmFsdWUpCisgKgorICogU2V0cyB0aGUgdmFsdWUgY29ycmVzcG9uZGluZyB0byB0aGlzIGZpZWxkIHRvIHRoZSBnaXZlbiB2YWx1ZSBvbiB0aGUgZ2l2ZW4KKyAqIG1lc3NhZ2UuIFJhaXNlcyBhbiBleGNlcHRpb24gaWYgbWVzc2FnZSBpcyBvZiB0aGUgd3JvbmcgdHlwZS4gUGVyZm9ybXMgdGhlCisgKiBvcmRpbmFyeSB0eXBlLWNoZWNrcyBmb3IgZmllbGQgc2V0dGluZy4KKyAqLworVkFMVUUgRmllbGREZXNjcmlwdG9yX3NldChWQUxVRSBfc2VsZiwgVkFMVUUgbXNnX3JiLCBWQUxVRSB2YWx1ZSkgeworICBERUZJTkVfU0VMRihGaWVsZERlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgTWVzc2FnZUhlYWRlciogbXNnOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChtc2dfcmIsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIG1zZyk7CisgIGlmIChtc2ctPmRlc2NyaXB0b3ItPm1zZ2RlZiAhPSB1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGUoc2VsZi0+ZmllbGRkZWYpKSB7CisgICAgcmJfcmFpc2UocmJfZVR5cGVFcnJvciwgInNldCBtZXRob2QgY2FsbGVkIG9uIHdyb25nIG1lc3NhZ2UgdHlwZSIpOworICB9CisgIGxheW91dF9zZXQobXNnLT5kZXNjcmlwdG9yLT5sYXlvdXQsIE1lc3NhZ2VfZGF0YShtc2cpLCBzZWxmLT5maWVsZGRlZiwgdmFsdWUpOworICByZXR1cm4gUW5pbDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE9uZW9mRGVzY3JpcHRvci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0RFRklORV9DTEFTUyhPbmVvZkRlc2NyaXB0b3IsICJHb29nbGU6OlByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3IiKTsKKwordm9pZCBPbmVvZkRlc2NyaXB0b3JfbWFyayh2b2lkKiBfc2VsZikgeworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvcl9mcmVlKHZvaWQqIF9zZWxmKSB7CisgIE9uZW9mRGVzY3JpcHRvciogc2VsZiA9IF9zZWxmOworICB1cGJfb25lb2ZkZWZfdW5yZWYoc2VsZi0+b25lb2ZkZWYsICZzZWxmLT5vbmVvZmRlZik7CisgIHhmcmVlKHNlbGYpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgT25lb2ZEZXNjcmlwdG9yLm5ldyA9PiBvbmVvZl9kZXNjcmlwdG9yCisgKgorICogQ3JlYXRlcyBhIG5ldywgZW1wdHksIG9uZW9mIGRlc2NyaXB0b3IuIFRoZSBvbmVvZiBtYXkgb25seSBiZSBtb2RpZmllZCBwcmlvcgorICogdG8gYmVpbmcgYWRkZWQgdG8gYSBtZXNzYWdlIGRlc2NyaXB0b3Igd2hpY2ggaXMgc3Vic2VxdWVudGx5IGFkZGVkIHRvIGEgcG9vbC4KKyAqLworVkFMVUUgT25lb2ZEZXNjcmlwdG9yX2FsbG9jKFZBTFVFIGtsYXNzKSB7CisgIE9uZW9mRGVzY3JpcHRvciogc2VsZiA9IEFMTE9DKE9uZW9mRGVzY3JpcHRvcik7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdChrbGFzcywgJl9PbmVvZkRlc2NyaXB0b3JfdHlwZSwgc2VsZik7CisgIHNlbGYtPm9uZW9mZGVmID0gdXBiX29uZW9mZGVmX25ldygmc2VsZi0+b25lb2ZkZWYpOworICByZXR1cm4gcmV0OworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvcl9yZWdpc3RlcihWQUxVRSBtb2R1bGUpIHsKKyAgVkFMVUUga2xhc3MgPSByYl9kZWZpbmVfY2xhc3NfdW5kZXIoCisgICAgICBtb2R1bGUsICJPbmVvZkRlc2NyaXB0b3IiLCByYl9jT2JqZWN0KTsKKyAgcmJfZGVmaW5lX2FsbG9jX2Z1bmMoa2xhc3MsIE9uZW9mRGVzY3JpcHRvcl9hbGxvYyk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJuYW1lIiwgT25lb2ZEZXNjcmlwdG9yX25hbWUsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibmFtZT0iLCBPbmVvZkRlc2NyaXB0b3JfbmFtZV9zZXQsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiYWRkX2ZpZWxkIiwgT25lb2ZEZXNjcmlwdG9yX2FkZF9maWVsZCwgMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJlYWNoIiwgT25lb2ZEZXNjcmlwdG9yX2VhY2gsIDApOworICByYl9pbmNsdWRlX21vZHVsZShrbGFzcywgcmJfbUVudW1lcmFibGUpOworICBjT25lb2ZEZXNjcmlwdG9yID0ga2xhc3M7CisgIHJiX2djX3JlZ2lzdGVyX2FkZHJlc3MoJmNPbmVvZkRlc2NyaXB0b3IpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgT25lb2ZEZXNjcmlwdG9yLm5hbWUgPT4gbmFtZQorICoKKyAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBvbmVvZi4KKyAqLworVkFMVUUgT25lb2ZEZXNjcmlwdG9yX25hbWUoVkFMVUUgX3NlbGYpIHsKKyAgREVGSU5FX1NFTEYoT25lb2ZEZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHJldHVybiByYl9zdHJfbWF5YmVfbnVsbCh1cGJfb25lb2ZkZWZfbmFtZShzZWxmLT5vbmVvZmRlZikpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgT25lb2ZEZXNjcmlwdG9yLm5hbWUgPSBuYW1lCisgKgorICogU2V0cyBhIG5ldyBuYW1lIGZvciB0aGlzIG9uZW9mLiBUaGUgb25lb2YgbXVzdCBub3QgaGF2ZSBiZWVuIGFkZGVkIHRvIGEKKyAqIG1lc3NhZ2UgZGVzY3JpcHRvciB5ZXQuCisgKi8KK1ZBTFVFIE9uZW9mRGVzY3JpcHRvcl9uYW1lX3NldChWQUxVRSBfc2VsZiwgVkFMVUUgdmFsdWUpIHsKKyAgREVGSU5FX1NFTEYoT25lb2ZEZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHVwYl9vbmVvZmRlZiogbXV0X2RlZiA9IGNoZWNrX29uZW9mX25vdGZyb3plbihzZWxmLT5vbmVvZmRlZik7CisgIGNvbnN0IGNoYXIqIHN0ciA9IGdldF9zdHIodmFsdWUpOworICBDSEVDS19VUEIodXBiX29uZW9mZGVmX3NldG5hbWUobXV0X2RlZiwgc3RyLCAmc3RhdHVzKSwKKyAgICAgICAgICAgICJFcnJvciBzZXR0aW5nIG9uZW9mIG5hbWUiKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBPbmVvZkRlc2NyaXB0b3IuYWRkX2ZpZWxkKGZpZWxkKSA9PiBuaWwKKyAqCisgKiBBZGRzIGEgZmllbGQgdG8gdGhpcyBvbmVvZi4gVGhlIGZpZWxkIG1heSBoYXZlIGJlZW4gYWRkZWQgdG8gdGhpcyBvbmVvZiBpbgorICogdGhlIHBhc3QsIG9yIHRoZSBtZXNzYWdlIHRvIHdoaWNoIHRoaXMgb25lb2YgYmVsb25ncyAoaWYgYW55KSwgYnV0IG1heSBub3QKKyAqIGhhdmUgYWxyZWFkeSBiZWVuIGFkZGVkIHRvIGFueSBvdGhlciBvbmVvZiBvciBtZXNzYWdlLiBPdGhlcndpc2UsIGFuCisgKiBleGNlcHRpb24gaXMgcmFpc2VkLgorICoKKyAqIEFsbCBmaWVsZHMgYWRkZWQgdG8gdGhlIG9uZW9mIHZpYSB0aGlzIG1ldGhvZCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgYWRkZWQgdG8KKyAqIHRoZSBtZXNzYWdlIHRvIHdoaWNoIHRoaXMgb25lb2YgYmVsb25ncywgaWYgaXQgYmVsb25ncyB0byBvbmUgY3VycmVudGx5LCBvcgorICogZWxzZSB3aWxsIGJlIGFkZGVkIHRvIGFueSBtZXNzYWdlIHRvIHdoaWNoIHRoZSBvbmVvZiBpcyBsYXRlciBhZGRlZCBhdCB0aGUKKyAqIHRpbWUgdGhhdCBpdCBpcyBhZGRlZC4KKyAqLworVkFMVUUgT25lb2ZEZXNjcmlwdG9yX2FkZF9maWVsZChWQUxVRSBfc2VsZiwgVkFMVUUgb2JqKSB7CisgIERFRklORV9TRUxGKE9uZW9mRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICB1cGJfb25lb2ZkZWYqIG11dF9kZWYgPSBjaGVja19vbmVvZl9ub3Rmcm96ZW4oc2VsZi0+b25lb2ZkZWYpOworICBGaWVsZERlc2NyaXB0b3IqIGRlZiA9IHJ1YnlfdG9fRmllbGREZXNjcmlwdG9yKG9iaik7CisgIHVwYl9maWVsZGRlZiogbXV0X2ZpZWxkX2RlZiA9IGNoZWNrX2ZpZWxkX25vdGZyb3plbihkZWYtPmZpZWxkZGVmKTsKKyAgQ0hFQ0tfVVBCKAorICAgICAgdXBiX29uZW9mZGVmX2FkZGZpZWxkKG11dF9kZWYsIG11dF9maWVsZF9kZWYsIE5VTEwsICZzdGF0dXMpLAorICAgICAgIkFkZGluZyBmaWVsZCB0byBPbmVvZkRlc2NyaXB0b3IgZmFpbGVkIik7CisgIGFkZF9kZWZfb2JqKGRlZi0+ZmllbGRkZWYsIG9iaik7CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgT25lb2ZEZXNjcmlwdG9yLmVhY2goJmJsb2NrKSA9PiBuaWwKKyAqCisgKiBJdGVyYXRlcyB0aHJvdWdoIGZpZWxkcyBpbiB0aGlzIG9uZW9mLCB5aWVsZGluZyB0byB0aGUgYmxvY2sgb24gZWFjaCBvbmUuCisgKi8KK1ZBTFVFIE9uZW9mRGVzY3JpcHRvcl9lYWNoKFZBTFVFIF9zZWxmLCBWQUxVRSBmaWVsZCkgeworICBERUZJTkVfU0VMRihPbmVvZkRlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgdXBiX29uZW9mX2l0ZXIgaXQ7CisgIGZvciAodXBiX29uZW9mX2JlZ2luKCZpdCwgc2VsZi0+b25lb2ZkZWYpOworICAgICAgICF1cGJfb25lb2ZfZG9uZSgmaXQpOworICAgICAgIHVwYl9vbmVvZl9uZXh0KCZpdCkpIHsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYqIGYgPSB1cGJfb25lb2ZfaXRlcl9maWVsZCgmaXQpOworICAgIFZBTFVFIG9iaiA9IGdldF9kZWZfb2JqKGYpOworICAgIHJiX3lpZWxkKG9iaik7CisgIH0KKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBFbnVtRGVzY3JpcHRvci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0RFRklORV9DTEFTUyhFbnVtRGVzY3JpcHRvciwgIkdvb2dsZTo6UHJvdG9idWY6OkVudW1EZXNjcmlwdG9yIik7CisKK3ZvaWQgRW51bURlc2NyaXB0b3JfbWFyayh2b2lkKiBfc2VsZikgeworICBFbnVtRGVzY3JpcHRvciogc2VsZiA9IF9zZWxmOworICByYl9nY19tYXJrKHNlbGYtPm1vZHVsZSk7Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JfZnJlZSh2b2lkKiBfc2VsZikgeworICBFbnVtRGVzY3JpcHRvciogc2VsZiA9IF9zZWxmOworICB1cGJfZW51bWRlZl91bnJlZihzZWxmLT5lbnVtZGVmLCAmc2VsZi0+ZW51bWRlZik7CisgIHhmcmVlKHNlbGYpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgRW51bURlc2NyaXB0b3IubmV3ID0+IGVudW1fZGVzY3JpcHRvcgorICoKKyAqIENyZWF0ZXMgYSBuZXcsIGVtcHR5LCBlbnVtIGRlc2NyaXB0b3IuIE11c3QgYmUgYWRkZWQgdG8gYSBwb29sIGJlZm9yZSB0aGUKKyAqIGVudW0gdHlwZSBjYW4gYmUgdXNlZC4gVGhlIGVudW0gdHlwZSBtYXkgb25seSBiZSBtb2RpZmllZCBwcmlvciB0byBhZGRpbmcgdG8KKyAqIGEgcG9vbC4KKyAqLworVkFMVUUgRW51bURlc2NyaXB0b3JfYWxsb2MoVkFMVUUga2xhc3MpIHsKKyAgRW51bURlc2NyaXB0b3IqIHNlbGYgPSBBTExPQyhFbnVtRGVzY3JpcHRvcik7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdChrbGFzcywgJl9FbnVtRGVzY3JpcHRvcl90eXBlLCBzZWxmKTsKKyAgc2VsZi0+ZW51bWRlZiA9IHVwYl9lbnVtZGVmX25ldygmc2VsZi0+ZW51bWRlZik7CisgIHNlbGYtPm1vZHVsZSA9IFFuaWw7CisgIHJldHVybiByZXQ7Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKSB7CisgIFZBTFVFIGtsYXNzID0gcmJfZGVmaW5lX2NsYXNzX3VuZGVyKAorICAgICAgbW9kdWxlLCAiRW51bURlc2NyaXB0b3IiLCByYl9jT2JqZWN0KTsKKyAgcmJfZGVmaW5lX2FsbG9jX2Z1bmMoa2xhc3MsIEVudW1EZXNjcmlwdG9yX2FsbG9jKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm5hbWUiLCBFbnVtRGVzY3JpcHRvcl9uYW1lLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm5hbWU9IiwgRW51bURlc2NyaXB0b3JfbmFtZV9zZXQsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiYWRkX3ZhbHVlIiwgRW51bURlc2NyaXB0b3JfYWRkX3ZhbHVlLCAyKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImxvb2t1cF9uYW1lIiwgRW51bURlc2NyaXB0b3JfbG9va3VwX25hbWUsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibG9va3VwX3ZhbHVlIiwgRW51bURlc2NyaXB0b3JfbG9va3VwX3ZhbHVlLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImVhY2giLCBFbnVtRGVzY3JpcHRvcl9lYWNoLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImVudW1tb2R1bGUiLCBFbnVtRGVzY3JpcHRvcl9lbnVtbW9kdWxlLCAwKTsKKyAgcmJfaW5jbHVkZV9tb2R1bGUoa2xhc3MsIHJiX21FbnVtZXJhYmxlKTsKKyAgY0VudW1EZXNjcmlwdG9yID0ga2xhc3M7CisgIHJiX2djX3JlZ2lzdGVyX2FkZHJlc3MoJmNFbnVtRGVzY3JpcHRvcik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtRGVzY3JpcHRvci5uYW1lID0+IG5hbWUKKyAqCisgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgZW51bSB0eXBlLgorICovCitWQUxVRSBFbnVtRGVzY3JpcHRvcl9uYW1lKFZBTFVFIF9zZWxmKSB7CisgIERFRklORV9TRUxGKEVudW1EZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIHJldHVybiByYl9zdHJfbWF5YmVfbnVsbCh1cGJfZW51bWRlZl9mdWxsbmFtZShzZWxmLT5lbnVtZGVmKSk7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtRGVzY3JpcHRvci5uYW1lID0gbmFtZQorICoKKyAqIFNldHMgdGhlIG5hbWUgb2YgdGhpcyBlbnVtIHR5cGUuIENhbm5vdCBiZSBjYWxsZWQgaWYgdGhlIGVudW0gdHlwZSBoYXMKKyAqIGFscmVhZHkgYmVlbiBhZGRlZCB0byBhIHBvb2wuCisgKi8KK1ZBTFVFIEVudW1EZXNjcmlwdG9yX25hbWVfc2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBzdHIpIHsKKyAgREVGSU5FX1NFTEYoRW51bURlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKyAgdXBiX2VudW1kZWYqIG11dF9kZWYgPSBjaGVja19lbnVtX25vdGZyb3plbihzZWxmLT5lbnVtZGVmKTsKKyAgY29uc3QgY2hhciogbmFtZSA9IGdldF9zdHIoc3RyKTsKKyAgQ0hFQ0tfVVBCKHVwYl9lbnVtZGVmX3NldGZ1bGxuYW1lKG11dF9kZWYsIG5hbWUsICZzdGF0dXMpLAorICAgICAgICAgICAgIkVycm9yIHNldHRpbmcgRW51bURlc2NyaXB0b3IgbmFtZSIpOworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEVudW1EZXNjcmlwdG9yLmFkZF92YWx1ZShrZXksIHZhbHVlKQorICoKKyAqIEFkZHMgYSBuZXcga2V5ID0+IHZhbHVlIG1hcHBpbmcgdG8gdGhpcyBlbnVtIHR5cGUuIEtleSBtdXN0IGJlIGdpdmVuIGFzIGEKKyAqIFJ1Ynkgc3ltYm9sLiBDYW5ub3QgYmUgY2FsbGVkIGlmIHRoZSBlbnVtIHR5cGUgaGFzIGFscmVhZHkgYmVlbiBhZGRlZCB0byBhCisgKiBwb29sLiBXaWxsIHJhaXNlIGFuIGV4Y2VwdGlvbiBpZiB0aGUga2V5IG9yIHZhbHVlIGlzIGFscmVhZHkgaW4gdXNlLgorICovCitWQUxVRSBFbnVtRGVzY3JpcHRvcl9hZGRfdmFsdWUoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUsIFZBTFVFIG51bWJlcikgeworICBERUZJTkVfU0VMRihFbnVtRGVzY3JpcHRvciwgc2VsZiwgX3NlbGYpOworICB1cGJfZW51bWRlZiogbXV0X2RlZiA9IGNoZWNrX2VudW1fbm90ZnJvemVuKHNlbGYtPmVudW1kZWYpOworICBjb25zdCBjaGFyKiBuYW1lX3N0ciA9IHJiX2lkMm5hbWUoU1lNMklEKG5hbWUpKTsKKyAgaW50MzJfdCB2YWwgPSBOVU0ySU5UKG51bWJlcik7CisgIENIRUNLX1VQQih1cGJfZW51bWRlZl9hZGR2YWwobXV0X2RlZiwgbmFtZV9zdHIsIHZhbCwgJnN0YXR1cyksCisgICAgICAgICAgICAiRXJyb3IgYWRkaW5nIHZhbHVlIHRvIGVudW0iKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtRGVzY3JpcHRvci5sb29rdXBfbmFtZShuYW1lKSA9PiB2YWx1ZQorICoKKyAqIFJldHVybnMgdGhlIG51bWVyaWMgdmFsdWUgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4ga2V5IG5hbWUgKGFzIGEgUnVieQorICogc3ltYm9sKSwgb3IgbmlsIGlmIG5vbmUuCisgKi8KK1ZBTFVFIEVudW1EZXNjcmlwdG9yX2xvb2t1cF9uYW1lKFZBTFVFIF9zZWxmLCBWQUxVRSBuYW1lKSB7CisgIERFRklORV9TRUxGKEVudW1EZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIGNvbnN0IGNoYXIqIG5hbWVfc3RyPSByYl9pZDJuYW1lKFNZTTJJRChuYW1lKSk7CisgIGludDMyX3QgdmFsID0gMDsKKyAgaWYgKHVwYl9lbnVtZGVmX250b2l6KHNlbGYtPmVudW1kZWYsIG5hbWVfc3RyLCAmdmFsKSkgeworICAgIHJldHVybiBJTlQyTlVNKHZhbCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFFuaWw7CisgIH0KK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEVudW1EZXNjcmlwdG9yLmxvb2t1cF92YWx1ZShuYW1lKSA9PiB2YWx1ZQorICoKKyAqIFJldHVybnMgdGhlIGtleSBuYW1lIChhcyBhIFJ1Ynkgc3ltYm9sKSBjb3JyZXNwb25kaW5nIHRvIHRoZSBpbnRlZ2VyIHZhbHVlLAorICogb3IgbmlsIGlmIG5vbmUuCisgKi8KK1ZBTFVFIEVudW1EZXNjcmlwdG9yX2xvb2t1cF92YWx1ZShWQUxVRSBfc2VsZiwgVkFMVUUgbnVtYmVyKSB7CisgIERFRklORV9TRUxGKEVudW1EZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIGludDMyX3QgdmFsID0gTlVNMklOVChudW1iZXIpOworICBjb25zdCBjaGFyKiBuYW1lID0gdXBiX2VudW1kZWZfaXRvbihzZWxmLT5lbnVtZGVmLCB2YWwpOworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgcmV0dXJuIElEMlNZTShyYl9pbnRlcm4obmFtZSkpOworICB9IGVsc2UgeworICAgIHJldHVybiBRbmlsOworICB9Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtRGVzY3JpcHRvci5lYWNoKCZibG9jaykKKyAqCisgKiBJdGVyYXRlcyBvdmVyIGtleSA9PiB2YWx1ZSBtYXBwaW5ncyBpbiB0aGlzIGVudW0ncyBkZWZpbml0aW9uLCB5aWVsZGluZyB0bworICogdGhlIGJsb2NrIHdpdGggKGtleSwgdmFsdWUpIGFyZ3VtZW50cyBmb3IgZWFjaCBvbmUuCisgKi8KK1ZBTFVFIEVudW1EZXNjcmlwdG9yX2VhY2goVkFMVUUgX3NlbGYpIHsKKyAgREVGSU5FX1NFTEYoRW51bURlc2NyaXB0b3IsIHNlbGYsIF9zZWxmKTsKKworICB1cGJfZW51bV9pdGVyIGl0OworICBmb3IgKHVwYl9lbnVtX2JlZ2luKCZpdCwgc2VsZi0+ZW51bWRlZik7CisgICAgICAgIXVwYl9lbnVtX2RvbmUoJml0KTsKKyAgICAgICB1cGJfZW51bV9uZXh0KCZpdCkpIHsKKyAgICBWQUxVRSBrZXkgPSBJRDJTWU0ocmJfaW50ZXJuKHVwYl9lbnVtX2l0ZXJfbmFtZSgmaXQpKSk7CisgICAgVkFMVUUgbnVtYmVyID0gSU5UMk5VTSh1cGJfZW51bV9pdGVyX251bWJlcigmaXQpKTsKKyAgICByYl95aWVsZF92YWx1ZXMoMiwga2V5LCBudW1iZXIpOworICB9CisKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtRGVzY3JpcHRvci5lbnVtbW9kdWxlID0+IG1vZHVsZQorICoKKyAqIFJldHVybnMgdGhlIFJ1YnkgbW9kdWxlIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBlbnVtIHR5cGUuIENhbm5vdCBiZSBjYWxsZWQKKyAqIHVudGlsIHRoZSBlbnVtIGRlc2NyaXB0b3IgaGFzIGJlZW4gYWRkZWQgdG8gYSBwb29sLgorICovCitWQUxVRSBFbnVtRGVzY3JpcHRvcl9lbnVtbW9kdWxlKFZBTFVFIF9zZWxmKSB7CisgIERFRklORV9TRUxGKEVudW1EZXNjcmlwdG9yLCBzZWxmLCBfc2VsZik7CisgIGlmICghdXBiX2RlZl9pc2Zyb3plbigoY29uc3QgdXBiX2RlZiopc2VsZi0+ZW51bWRlZikpIHsKKyAgICByYl9yYWlzZShyYl9lUnVudGltZUVycm9yLAorICAgICAgICAgICAgICJDYW5ub3QgZmV0Y2ggZW51bSBtb2R1bGUgZnJvbSBhbiBFbnVtRGVzY3JpcHRvciBub3QgeWV0ICIKKyAgICAgICAgICAgICAiaW4gYSBwb29sLiIpOworICB9CisgIGlmIChzZWxmLT5tb2R1bGUgPT0gUW5pbCkgeworICAgIHNlbGYtPm1vZHVsZSA9IGJ1aWxkX21vZHVsZV9mcm9tX2VudW1kZXNjKHNlbGYpOworICB9CisgIHJldHVybiBzZWxmLT5tb2R1bGU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNZXNzYWdlQnVpbGRlckNvbnRleHQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitERUZJTkVfQ0xBU1MoTWVzc2FnZUJ1aWxkZXJDb250ZXh0LAorICAgICJHb29nbGU6OlByb3RvYnVmOjpJbnRlcm5hbDo6TWVzc2FnZUJ1aWxkZXJDb250ZXh0Iik7CisKK3ZvaWQgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X21hcmsodm9pZCogX3NlbGYpIHsKKyAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0KiBzZWxmID0gX3NlbGY7CisgIHJiX2djX21hcmsoc2VsZi0+ZGVzY3JpcHRvcik7CisgIHJiX2djX21hcmsoc2VsZi0+YnVpbGRlcik7Cit9CisKK3ZvaWQgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X2ZyZWUodm9pZCogX3NlbGYpIHsKKyAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0KiBzZWxmID0gX3NlbGY7CisgIHhmcmVlKHNlbGYpOworfQorCitWQUxVRSBNZXNzYWdlQnVpbGRlckNvbnRleHRfYWxsb2MoVkFMVUUga2xhc3MpIHsKKyAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0KiBzZWxmID0gQUxMT0MoTWVzc2FnZUJ1aWxkZXJDb250ZXh0KTsKKyAgVkFMVUUgcmV0ID0gVHlwZWREYXRhX1dyYXBfU3RydWN0KAorICAgICAga2xhc3MsICZfTWVzc2FnZUJ1aWxkZXJDb250ZXh0X3R5cGUsIHNlbGYpOworICBzZWxmLT5kZXNjcmlwdG9yID0gUW5pbDsKKyAgc2VsZi0+YnVpbGRlciA9IFFuaWw7CisgIHJldHVybiByZXQ7Cit9CisKK3ZvaWQgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X3JlZ2lzdGVyKFZBTFVFIG1vZHVsZSkgeworICBWQUxVRSBrbGFzcyA9IHJiX2RlZmluZV9jbGFzc191bmRlcigKKyAgICAgIG1vZHVsZSwgIk1lc3NhZ2VCdWlsZGVyQ29udGV4dCIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X2FsbG9jKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImluaXRpYWxpemUiLAorICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9pbml0aWFsaXplLCAyKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm9wdGlvbmFsIiwgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X29wdGlvbmFsLCAtMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJyZXF1aXJlZCIsIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9yZXF1aXJlZCwgLTEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAicmVwZWF0ZWQiLCBNZXNzYWdlQnVpbGRlckNvbnRleHRfcmVwZWF0ZWQsIC0xKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm1hcCIsIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9tYXAsIC0xKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIm9uZW9mIiwgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X29uZW9mLCAxKTsKKyAgY01lc3NhZ2VCdWlsZGVyQ29udGV4dCA9IGtsYXNzOworICByYl9nY19yZWdpc3Rlcl9hZGRyZXNzKCZjTWVzc2FnZUJ1aWxkZXJDb250ZXh0KTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dC5uZXcoZGVzYywgYnVpbGRlcikgPT4gY29udGV4dAorICoKKyAqIENyZWF0ZSBhIG5ldyBtZXNzYWdlIGJ1aWxkZXIgY29udGV4dCBhcm91bmQgdGhlIGdpdmVuIG1lc3NhZ2UgZGVzY3JpcHRvciBhbmQKKyAqIGJ1aWxkZXIgY29udGV4dC4gVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBzZXJ2ZSBhcyBhIERTTCBjb250ZXh0IHRvIGJlIHVzZWQKKyAqIHdpdGggI2luc3RhbmNlX2V2YWwuCisgKi8KK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9pbml0aWFsaXplKFZBTFVFIF9zZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgbXNnZGVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgYnVpbGRlcikgeworICBERUZJTkVfU0VMRihNZXNzYWdlQnVpbGRlckNvbnRleHQsIHNlbGYsIF9zZWxmKTsKKyAgc2VsZi0+ZGVzY3JpcHRvciA9IG1zZ2RlZjsKKyAgc2VsZi0+YnVpbGRlciA9IGJ1aWxkZXI7CisgIHJldHVybiBRbmlsOworfQorCitzdGF0aWMgVkFMVUUgbXNnZGVmX2FkZF9maWVsZChWQUxVRSBtc2dkZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBsYWJlbCwgVkFMVUUgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTFVFIHR5cGUsIFZBTFVFIG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTFVFIHR5cGVfY2xhc3MpIHsKKyAgVkFMVUUgZmllbGRkZWYgPSByYl9jbGFzc19uZXdfaW5zdGFuY2UoMCwgTlVMTCwgY0ZpZWxkRGVzY3JpcHRvcik7CisgIFZBTFVFIG5hbWVfc3RyID0gcmJfc3RyX25ldzIocmJfaWQybmFtZShTWU0ySUQobmFtZSkpKTsKKworICByYl9mdW5jYWxsKGZpZWxkZGVmLCByYl9pbnRlcm4oImxhYmVsPSIpLCAxLCBJRDJTWU0ocmJfaW50ZXJuKGxhYmVsKSkpOworICByYl9mdW5jYWxsKGZpZWxkZGVmLCByYl9pbnRlcm4oIm5hbWU9IiksIDEsIG5hbWVfc3RyKTsKKyAgcmJfZnVuY2FsbChmaWVsZGRlZiwgcmJfaW50ZXJuKCJ0eXBlPSIpLCAxLCB0eXBlKTsKKyAgcmJfZnVuY2FsbChmaWVsZGRlZiwgcmJfaW50ZXJuKCJudW1iZXI9IiksIDEsIG51bWJlcik7CisKKyAgaWYgKHR5cGVfY2xhc3MgIT0gUW5pbCkgeworICAgIGlmIChUWVBFKHR5cGVfY2xhc3MpICE9IFRfU1RSSU5HKSB7CisgICAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsICJFeHBlY3RlZCBzdHJpbmcgZm9yIHR5cGUgY2xhc3MiKTsKKyAgICB9CisgICAgLy8gTWFrZSBpdCBhbiBhYnNvbHV0ZSB0eXBlIG5hbWUgYnkgcHJlcGVuZGluZyBhIGRvdC4KKyAgICB0eXBlX2NsYXNzID0gcmJfc3RyX2FwcGVuZChyYl9zdHJfbmV3MigiLiIpLCB0eXBlX2NsYXNzKTsKKyAgICByYl9mdW5jYWxsKGZpZWxkZGVmLCByYl9pbnRlcm4oInN1Ym1zZ19uYW1lPSIpLCAxLCB0eXBlX2NsYXNzKTsKKyAgfQorCisgIHJiX2Z1bmNhbGwobXNnZGVmLCByYl9pbnRlcm4oImFkZF9maWVsZCIpLCAxLCBmaWVsZGRlZik7CisgIHJldHVybiBmaWVsZGRlZjsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dC5vcHRpb25hbChuYW1lLCB0eXBlLCBudW1iZXIsIHR5cGVfY2xhc3MgPSBuaWwpCisgKgorICogRGVmaW5lcyBhIG5ldyBvcHRpb25hbCBmaWVsZCBvbiB0aGlzIG1lc3NhZ2UgdHlwZSB3aXRoIHRoZSBnaXZlbiB0eXBlLCB0YWcKKyAqIG51bWJlciwgYW5kIHR5cGUgY2xhc3MgKGZvciBtZXNzYWdlIGFuZCBlbnVtIGZpZWxkcykuIFRoZSB0eXBlIG11c3QgYmUgYSBSdWJ5CisgKiBzeW1ib2wgKGFzIGFjY2VwdGVkIGJ5IEZpZWxkRGVzY3JpcHRvciN0eXBlPSkgYW5kIHRoZSB0eXBlX2NsYXNzIG11c3QgYmUgYQorICogc3RyaW5nLCBpZiBwcmVzZW50IChhcyBhY2NlcHRlZCBieSBGaWVsZERlc2NyaXB0b3Ijc3VibXNnX25hbWU9KS4KKyAqLworVkFMVUUgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X29wdGlvbmFsKGludCBhcmdjLCBWQUxVRSogYXJndiwgVkFMVUUgX3NlbGYpIHsKKyAgREVGSU5FX1NFTEYoTWVzc2FnZUJ1aWxkZXJDb250ZXh0LCBzZWxmLCBfc2VsZik7CisKKyAgaWYgKGFyZ2MgPCAzKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiRXhwZWN0ZWQgYXQgbGVhc3QgMyBhcmd1bWVudHMuIik7CisgIH0KKyAgVkFMVUUgbmFtZSA9IGFyZ3ZbMF07CisgIFZBTFVFIHR5cGUgPSBhcmd2WzFdOworICBWQUxVRSBudW1iZXIgPSBhcmd2WzJdOworICBWQUxVRSB0eXBlX2NsYXNzID0gKGFyZ2MgPiAzKSA/IGFyZ3ZbM10gOiBRbmlsOworCisgIHJldHVybiBtc2dkZWZfYWRkX2ZpZWxkKHNlbGYtPmRlc2NyaXB0b3IsICJvcHRpb25hbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZV9jbGFzcyk7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBNZXNzYWdlQnVpbGRlckNvbnRleHQucmVxdWlyZWQobmFtZSwgdHlwZSwgbnVtYmVyLCB0eXBlX2NsYXNzID0gbmlsKQorICoKKyAqIERlZmluZXMgYSBuZXcgcmVxdWlyZWQgZmllbGQgb24gdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gdHlwZSwgdGFnCisgKiBudW1iZXIsIGFuZCB0eXBlIGNsYXNzIChmb3IgbWVzc2FnZSBhbmQgZW51bSBmaWVsZHMpLiBUaGUgdHlwZSBtdXN0IGJlIGEgUnVieQorICogc3ltYm9sIChhcyBhY2NlcHRlZCBieSBGaWVsZERlc2NyaXB0b3IjdHlwZT0pIGFuZCB0aGUgdHlwZV9jbGFzcyBtdXN0IGJlIGEKKyAqIHN0cmluZywgaWYgcHJlc2VudCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3N1Ym1zZ19uYW1lPSkuCisgKgorICogUHJvdG8zIGRvZXMgbm90IGhhdmUgcmVxdWlyZWQgZmllbGRzLCBidXQgdGhpcyBtZXRob2QgZXhpc3RzIGZvcgorICogY29tcGxldGVuZXNzLiBBbnkgYXR0ZW1wdCB0byBhZGQgYSBtZXNzYWdlIHR5cGUgd2l0aCByZXF1aXJlZCBmaWVsZHMgdG8gYQorICogcG9vbCB3aWxsIGN1cnJlbnRseSByZXN1bHQgaW4gYW4gZXJyb3IuCisgKi8KK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9yZXF1aXJlZChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKSB7CisgIERFRklORV9TRUxGKE1lc3NhZ2VCdWlsZGVyQ29udGV4dCwgc2VsZiwgX3NlbGYpOworCisgIGlmIChhcmdjIDwgMykgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIGF0IGxlYXN0IDMgYXJndW1lbnRzLiIpOworICB9CisgIFZBTFVFIG5hbWUgPSBhcmd2WzBdOworICBWQUxVRSB0eXBlID0gYXJndlsxXTsKKyAgVkFMVUUgbnVtYmVyID0gYXJndlsyXTsKKyAgVkFMVUUgdHlwZV9jbGFzcyA9IChhcmdjID4gMykgPyBhcmd2WzNdIDogUW5pbDsKKworICByZXR1cm4gbXNnZGVmX2FkZF9maWVsZChzZWxmLT5kZXNjcmlwdG9yLCAicmVxdWlyZWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlLCBudW1iZXIsIHR5cGVfY2xhc3MpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0LnJlcGVhdGVkKG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZV9jbGFzcyA9IG5pbCkKKyAqCisgKiBEZWZpbmVzIGEgbmV3IHJlcGVhdGVkIGZpZWxkIG9uIHRoaXMgbWVzc2FnZSB0eXBlIHdpdGggdGhlIGdpdmVuIHR5cGUsIHRhZworICogbnVtYmVyLCBhbmQgdHlwZSBjbGFzcyAoZm9yIG1lc3NhZ2UgYW5kIGVudW0gZmllbGRzKS4gVGhlIHR5cGUgbXVzdCBiZSBhIFJ1YnkKKyAqIHN5bWJvbCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3R5cGU9KSBhbmQgdGhlIHR5cGVfY2xhc3MgbXVzdCBiZSBhCisgKiBzdHJpbmcsIGlmIHByZXNlbnQgKGFzIGFjY2VwdGVkIGJ5IEZpZWxkRGVzY3JpcHRvciNzdWJtc2dfbmFtZT0pLgorICovCitWQUxVRSBNZXNzYWdlQnVpbGRlckNvbnRleHRfcmVwZWF0ZWQoaW50IGFyZ2MsIFZBTFVFKiBhcmd2LCBWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihNZXNzYWdlQnVpbGRlckNvbnRleHQsIHNlbGYsIF9zZWxmKTsKKworICBpZiAoYXJnYyA8IDMpIHsKKyAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsICJFeHBlY3RlZCBhdCBsZWFzdCAzIGFyZ3VtZW50cy4iKTsKKyAgfQorICBWQUxVRSBuYW1lID0gYXJndlswXTsKKyAgVkFMVUUgdHlwZSA9IGFyZ3ZbMV07CisgIFZBTFVFIG51bWJlciA9IGFyZ3ZbMl07CisgIFZBTFVFIHR5cGVfY2xhc3MgPSAoYXJnYyA+IDMpID8gYXJndlszXSA6IFFuaWw7CisKKyAgcmV0dXJuIG1zZ2RlZl9hZGRfZmllbGQoc2VsZi0+ZGVzY3JpcHRvciwgInJlcGVhdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgdHlwZSwgbnVtYmVyLCB0eXBlX2NsYXNzKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dC5tYXAobmFtZSwga2V5X3R5cGUsIHZhbHVlX3R5cGUsIG51bWJlciwKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX3R5cGVfY2xhc3MgPSBuaWwpCisgKgorICogRGVmaW5lcyBhIG5ldyBtYXAgZmllbGQgb24gdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4ga2V5IGFuZCB2YWx1ZQorICogdHlwZXMsIHRhZyBudW1iZXIsIGFuZCB0eXBlIGNsYXNzIChmb3IgbWVzc2FnZSBhbmQgZW51bSB2YWx1ZSB0eXBlcykuIFRoZSBrZXkKKyAqIHR5cGUgbXVzdCBiZSA6aW50MzIvOnVpbnQzMi86aW50NjQvOnVpbnQ2NCwgOmJvb2wsIG9yIDpzdHJpbmcuIFRoZSB2YWx1ZSB0eXBlCisgKiB0eXBlIG11c3QgYmUgYSBSdWJ5IHN5bWJvbCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3R5cGU9KSBhbmQgdGhlCisgKiB0eXBlX2NsYXNzIG11c3QgYmUgYSBzdHJpbmcsIGlmIHByZXNlbnQgKGFzIGFjY2VwdGVkIGJ5CisgKiBGaWVsZERlc2NyaXB0b3Ijc3VibXNnX25hbWU9KS4KKyAqLworVkFMVUUgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X21hcChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKSB7CisgIERFRklORV9TRUxGKE1lc3NhZ2VCdWlsZGVyQ29udGV4dCwgc2VsZiwgX3NlbGYpOworCisgIGlmIChhcmdjIDwgNCkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIGF0IGxlYXN0IDQgYXJndW1lbnRzLiIpOworICB9CisgIFZBTFVFIG5hbWUgPSBhcmd2WzBdOworICBWQUxVRSBrZXlfdHlwZSA9IGFyZ3ZbMV07CisgIFZBTFVFIHZhbHVlX3R5cGUgPSBhcmd2WzJdOworICBWQUxVRSBudW1iZXIgPSBhcmd2WzNdOworICBWQUxVRSB0eXBlX2NsYXNzID0gKGFyZ2MgPiA0KSA/IGFyZ3ZbNF0gOiBRbmlsOworCisgIC8vIFZhbGlkYXRlIHRoZSBrZXkgdHlwZS4gV2UgY2FuJ3QgYWNjZXB0IGVudW1zLCBtZXNzYWdlcywgb3IgZmxvYXRzL2RvdWJsZXMKKyAgLy8gYXMgbWFwIGtleXMuIChXZSBleGNsdWRlIHRoZXNlIGV4cGxpY2l0bHksIGFuZCB0aGUgZmllbGQtZGVzY3JpcHRvciBzZXR0ZXIKKyAgLy8gYmVsb3cgdGhlbiBlbnN1cmVzIHRoYXQgdGhlIHR5cGUgaXMgb25lIG9mIHRoZSByZW1haW5pbmcgdmFsaWQgb3B0aW9ucy4pCisgIGlmIChTWU0ySUQoa2V5X3R5cGUpID09IHJiX2ludGVybigiZmxvYXQiKSB8fAorICAgICAgU1lNMklEKGtleV90eXBlKSA9PSByYl9pbnRlcm4oImRvdWJsZSIpIHx8CisgICAgICBTWU0ySUQoa2V5X3R5cGUpID09IHJiX2ludGVybigiZW51bSIpIHx8CisgICAgICBTWU0ySUQoa2V5X3R5cGUpID09IHJiX2ludGVybigibWVzc2FnZSIpKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLAorICAgICAgICAgICAgICJDYW5ub3QgYWRkIGEgbWFwIGZpZWxkIHdpdGggYSBmbG9hdCwgZG91YmxlLCBlbnVtLCBvciBtZXNzYWdlICIKKyAgICAgICAgICAgICAidHlwZS4iKTsKKyAgfQorCisgIC8vIENyZWF0ZSBhIG5ldyBtZXNzYWdlIGRlc2NyaXB0b3IgZm9yIHRoZSBtYXAgZW50cnkgbWVzc2FnZSwgYW5kIGNyZWF0ZSBhCisgIC8vIHJlcGVhdGVkIHN1Ym1lc3NhZ2UgZmllbGQgaGVyZSB3aXRoIHRoYXQgdHlwZS4KKyAgVkFMVUUgbWFwZW50cnlfZGVzYyA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBjRGVzY3JpcHRvcik7CisgIFZBTFVFIG1hcGVudHJ5X2Rlc2NfbmFtZSA9IHJiX2Z1bmNhbGwoc2VsZi0+ZGVzY3JpcHRvciwgcmJfaW50ZXJuKCJuYW1lIiksIDApOworICBtYXBlbnRyeV9kZXNjX25hbWUgPSByYl9zdHJfY2F0MihtYXBlbnRyeV9kZXNjX25hbWUsICJfTWFwRW50cnlfIik7CisgIG1hcGVudHJ5X2Rlc2NfbmFtZSA9IHJiX3N0cl9jYXQyKG1hcGVudHJ5X2Rlc2NfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmJfaWQybmFtZShTWU0ySUQobmFtZSkpKTsKKyAgRGVzY3JpcHRvcl9uYW1lX3NldChtYXBlbnRyeV9kZXNjLCBtYXBlbnRyeV9kZXNjX25hbWUpOworCisgIC8vIFRoZSAnbWFwZW50cnknIGF0dHJpYnV0ZSBoYXMgbm8gUnVieSBzZXR0ZXIgYmVjYXVzZSB3ZSBkbyBub3Qgd2FudCB0aGUgdXNlcgorICAvLyBhdHRlbXB0aW5nIHRvIERJWSB0aGUgc2V0dXAgYmVsb3c7IHdlIHdhbnQgdG8gZW5zdXJlIHRoYXQgdGhlIGZpZWxkcyBhcmUKKyAgLy8gY29ycmVjdC4gU28gd2UgcmVhY2ggaW50byB0aGUgbXNnZGVmIGhlcmUgdG8gc2V0IHRoZSBiaXQgbWFudWFsbHkuCisgIERlc2NyaXB0b3IqIG1hcGVudHJ5X2Rlc2Nfc2VsZiA9IHJ1YnlfdG9fRGVzY3JpcHRvcihtYXBlbnRyeV9kZXNjKTsKKyAgdXBiX21zZ2RlZl9zZXRtYXBlbnRyeSgodXBiX21zZ2RlZiopbWFwZW50cnlfZGVzY19zZWxmLT5tc2dkZWYsIHRydWUpOworCisgIC8vIG9wdGlvbmFsIDx0eXBlPiBrZXkgPSAxOworICBWQUxVRSBrZXlfZmllbGQgPSByYl9jbGFzc19uZXdfaW5zdGFuY2UoMCwgTlVMTCwgY0ZpZWxkRGVzY3JpcHRvcik7CisgIEZpZWxkRGVzY3JpcHRvcl9uYW1lX3NldChrZXlfZmllbGQsIHJiX3N0cl9uZXcyKCJrZXkiKSk7CisgIEZpZWxkRGVzY3JpcHRvcl9sYWJlbF9zZXQoa2V5X2ZpZWxkLCBJRDJTWU0ocmJfaW50ZXJuKCJvcHRpb25hbCIpKSk7CisgIEZpZWxkRGVzY3JpcHRvcl9udW1iZXJfc2V0KGtleV9maWVsZCwgSU5UMk5VTSgxKSk7CisgIEZpZWxkRGVzY3JpcHRvcl90eXBlX3NldChrZXlfZmllbGQsIGtleV90eXBlKTsKKyAgRGVzY3JpcHRvcl9hZGRfZmllbGQobWFwZW50cnlfZGVzYywga2V5X2ZpZWxkKTsKKworICAvLyBvcHRpb25hbCA8dHlwZT4gdmFsdWUgPSAyOworICBWQUxVRSB2YWx1ZV9maWVsZCA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBjRmllbGREZXNjcmlwdG9yKTsKKyAgRmllbGREZXNjcmlwdG9yX25hbWVfc2V0KHZhbHVlX2ZpZWxkLCByYl9zdHJfbmV3MigidmFsdWUiKSk7CisgIEZpZWxkRGVzY3JpcHRvcl9sYWJlbF9zZXQodmFsdWVfZmllbGQsIElEMlNZTShyYl9pbnRlcm4oIm9wdGlvbmFsIikpKTsKKyAgRmllbGREZXNjcmlwdG9yX251bWJlcl9zZXQodmFsdWVfZmllbGQsIElOVDJOVU0oMikpOworICBGaWVsZERlc2NyaXB0b3JfdHlwZV9zZXQodmFsdWVfZmllbGQsIHZhbHVlX3R5cGUpOworICBpZiAodHlwZV9jbGFzcyAhPSBRbmlsKSB7CisgICAgVkFMVUUgc3VibXNnX25hbWUgPSByYl9zdHJfbmV3MigiLiIpOyAvLyBwcmVwZW5kICcuJyB0byBtYWtlIG5hbWUgYWJzb2x1dGUuCisgICAgc3VibXNnX25hbWUgPSByYl9zdHJfYXBwZW5kKHN1Ym1zZ19uYW1lLCB0eXBlX2NsYXNzKTsKKyAgICBGaWVsZERlc2NyaXB0b3Jfc3VibXNnX25hbWVfc2V0KHZhbHVlX2ZpZWxkLCBzdWJtc2dfbmFtZSk7CisgIH0KKyAgRGVzY3JpcHRvcl9hZGRfZmllbGQobWFwZW50cnlfZGVzYywgdmFsdWVfZmllbGQpOworCisgIC8vIEFkZCB0aGUgbWFwLWVudHJ5IG1lc3NhZ2UgdHlwZSB0byB0aGUgY3VycmVudCBidWlsZGVyLCBhbmQgdXNlIHRoZSB0eXBlIHRvCisgIC8vIGNyZWF0ZSB0aGUgbWFwIGZpZWxkIGl0c2VsZi4KKyAgQnVpbGRlciogYnVpbGRlcl9zZWxmID0gcnVieV90b19CdWlsZGVyKHNlbGYtPmJ1aWxkZXIpOworICByYl9hcnlfcHVzaChidWlsZGVyX3NlbGYtPnBlbmRpbmdfbGlzdCwgbWFwZW50cnlfZGVzYyk7CisKKyAgVkFMVUUgbWFwX2ZpZWxkID0gcmJfY2xhc3NfbmV3X2luc3RhbmNlKDAsIE5VTEwsIGNGaWVsZERlc2NyaXB0b3IpOworICBWQUxVRSBuYW1lX3N0ciA9IHJiX3N0cl9uZXcyKHJiX2lkMm5hbWUoU1lNMklEKG5hbWUpKSk7CisgIEZpZWxkRGVzY3JpcHRvcl9uYW1lX3NldChtYXBfZmllbGQsIG5hbWVfc3RyKTsKKyAgRmllbGREZXNjcmlwdG9yX251bWJlcl9zZXQobWFwX2ZpZWxkLCBudW1iZXIpOworICBGaWVsZERlc2NyaXB0b3JfbGFiZWxfc2V0KG1hcF9maWVsZCwgSUQyU1lNKHJiX2ludGVybigicmVwZWF0ZWQiKSkpOworICBGaWVsZERlc2NyaXB0b3JfdHlwZV9zZXQobWFwX2ZpZWxkLCBJRDJTWU0ocmJfaW50ZXJuKCJtZXNzYWdlIikpKTsKKyAgVkFMVUUgc3VibXNnX25hbWUgPSByYl9zdHJfbmV3MigiLiIpOyAvLyBwcmVwZW5kICcuJyB0byBtYWtlIG5hbWUgYWJzb2x1dGUuCisgIHN1Ym1zZ19uYW1lID0gcmJfc3RyX2FwcGVuZChzdWJtc2dfbmFtZSwgbWFwZW50cnlfZGVzY19uYW1lKTsKKyAgRmllbGREZXNjcmlwdG9yX3N1Ym1zZ19uYW1lX3NldChtYXBfZmllbGQsIHN1Ym1zZ19uYW1lKTsKKyAgRGVzY3JpcHRvcl9hZGRfZmllbGQoc2VsZi0+ZGVzY3JpcHRvciwgbWFwX2ZpZWxkKTsKKworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dC5vbmVvZihuYW1lLCAmYmxvY2spID0+IG5pbAorICoKKyAqIENyZWF0ZXMgYSBuZXcgT25lb2ZEZXNjcmlwdG9yIHdpdGggdGhlIGdpdmVuIG5hbWUsIGNyZWF0ZXMgYQorICogT25lb2ZCdWlsZGVyQ29udGV4dCBhdHRhY2hlZCB0byB0aGF0IE9uZW9mRGVzY3JpcHRvciwgZXZhbHVhdGVzIHRoZSBnaXZlbgorICogYmxvY2sgaW4gdGhlIGNvbnRleHQgb2YgdGhhdCBPbmVvZkJ1aWxkZXJDb250ZXh0IHdpdGggI2luc3RhbmNlX2V2YWwsIGFuZAorICogdGhlbiBhZGRzIHRoZSBvbmVvZiB0byB0aGUgbWVzc2FnZS4KKyAqCisgKiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCwgaWRpb21hdGljIHdheSB0byBidWlsZCBvbmVvZiBkZWZpbml0aW9ucy4KKyAqLworVkFMVUUgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X29uZW9mKFZBTFVFIF9zZWxmLCBWQUxVRSBuYW1lKSB7CisgIERFRklORV9TRUxGKE1lc3NhZ2VCdWlsZGVyQ29udGV4dCwgc2VsZiwgX3NlbGYpOworICBWQUxVRSBvbmVvZmRlZiA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBjT25lb2ZEZXNjcmlwdG9yKTsKKyAgVkFMVUUgYXJnc1syXSA9IHsgb25lb2ZkZWYsIHNlbGYtPmJ1aWxkZXIgfTsKKyAgVkFMVUUgY3R4ID0gcmJfY2xhc3NfbmV3X2luc3RhbmNlKDIsIGFyZ3MsIGNPbmVvZkJ1aWxkZXJDb250ZXh0KTsKKyAgVkFMVUUgYmxvY2sgPSByYl9ibG9ja19wcm9jKCk7CisgIFZBTFVFIG5hbWVfc3RyID0gcmJfc3RyX25ldzIocmJfaWQybmFtZShTWU0ySUQobmFtZSkpKTsKKyAgcmJfZnVuY2FsbChvbmVvZmRlZiwgcmJfaW50ZXJuKCJuYW1lPSIpLCAxLCBuYW1lX3N0cik7CisgIHJiX2Z1bmNhbGxfd2l0aF9ibG9jayhjdHgsIHJiX2ludGVybigiaW5zdGFuY2VfZXZhbCIpLCAwLCBOVUxMLCBibG9jayk7CisgIERlc2NyaXB0b3JfYWRkX29uZW9mKHNlbGYtPmRlc2NyaXB0b3IsIG9uZW9mZGVmKTsKKworICByZXR1cm4gUW5pbDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE9uZW9mQnVpbGRlckNvbnRleHQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitERUZJTkVfQ0xBU1MoT25lb2ZCdWlsZGVyQ29udGV4dCwKKyAgICAiR29vZ2xlOjpQcm90b2J1Zjo6SW50ZXJuYWw6Ok9uZW9mQnVpbGRlckNvbnRleHQiKTsKKwordm9pZCBPbmVvZkJ1aWxkZXJDb250ZXh0X21hcmsodm9pZCogX3NlbGYpIHsKKyAgT25lb2ZCdWlsZGVyQ29udGV4dCogc2VsZiA9IF9zZWxmOworICByYl9nY19tYXJrKHNlbGYtPmRlc2NyaXB0b3IpOworICByYl9nY19tYXJrKHNlbGYtPmJ1aWxkZXIpOworfQorCit2b2lkIE9uZW9mQnVpbGRlckNvbnRleHRfZnJlZSh2b2lkKiBfc2VsZikgeworICBPbmVvZkJ1aWxkZXJDb250ZXh0KiBzZWxmID0gX3NlbGY7CisgIHhmcmVlKHNlbGYpOworfQorCitWQUxVRSBPbmVvZkJ1aWxkZXJDb250ZXh0X2FsbG9jKFZBTFVFIGtsYXNzKSB7CisgIE9uZW9mQnVpbGRlckNvbnRleHQqIHNlbGYgPSBBTExPQyhPbmVvZkJ1aWxkZXJDb250ZXh0KTsKKyAgVkFMVUUgcmV0ID0gVHlwZWREYXRhX1dyYXBfU3RydWN0KAorICAgICAga2xhc3MsICZfT25lb2ZCdWlsZGVyQ29udGV4dF90eXBlLCBzZWxmKTsKKyAgc2VsZi0+ZGVzY3JpcHRvciA9IFFuaWw7CisgIHNlbGYtPmJ1aWxkZXIgPSBRbmlsOworICByZXR1cm4gcmV0OworfQorCit2b2lkIE9uZW9mQnVpbGRlckNvbnRleHRfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKSB7CisgIFZBTFVFIGtsYXNzID0gcmJfZGVmaW5lX2NsYXNzX3VuZGVyKAorICAgICAgbW9kdWxlLCAiT25lb2ZCdWlsZGVyQ29udGV4dCIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgT25lb2ZCdWlsZGVyQ29udGV4dF9hbGxvYyk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJpbml0aWFsaXplIiwKKyAgICAgICAgICAgICAgICAgICBPbmVvZkJ1aWxkZXJDb250ZXh0X2luaXRpYWxpemUsIDIpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAib3B0aW9uYWwiLCBPbmVvZkJ1aWxkZXJDb250ZXh0X29wdGlvbmFsLCAtMSk7CisgIGNPbmVvZkJ1aWxkZXJDb250ZXh0ID0ga2xhc3M7CisgIHJiX2djX3JlZ2lzdGVyX2FkZHJlc3MoJmNPbmVvZkJ1aWxkZXJDb250ZXh0KTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE9uZW9mQnVpbGRlckNvbnRleHQubmV3KGRlc2MsIGJ1aWxkZXIpID0+IGNvbnRleHQKKyAqCisgKiBDcmVhdGUgYSBuZXcgb25lb2YgYnVpbGRlciBjb250ZXh0IGFyb3VuZCB0aGUgZ2l2ZW4gb25lb2YgZGVzY3JpcHRvciBhbmQKKyAqIGJ1aWxkZXIgY29udGV4dC4gVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBzZXJ2ZSBhcyBhIERTTCBjb250ZXh0IHRvIGJlIHVzZWQKKyAqIHdpdGggI2luc3RhbmNlX2V2YWwuCisgKi8KK1ZBTFVFIE9uZW9mQnVpbGRlckNvbnRleHRfaW5pdGlhbGl6ZShWQUxVRSBfc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxVRSBvbmVvZmRlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxVRSBidWlsZGVyKSB7CisgIERFRklORV9TRUxGKE9uZW9mQnVpbGRlckNvbnRleHQsIHNlbGYsIF9zZWxmKTsKKyAgc2VsZi0+ZGVzY3JpcHRvciA9IG9uZW9mZGVmOworICBzZWxmLT5idWlsZGVyID0gYnVpbGRlcjsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBPbmVvZkJ1aWxkZXJDb250ZXh0Lm9wdGlvbmFsKG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZV9jbGFzcyA9IG5pbCkKKyAqCisgKiBEZWZpbmVzIGEgbmV3IG9wdGlvbmFsIGZpZWxkIGluIHRoaXMgb25lb2Ygd2l0aCB0aGUgZ2l2ZW4gdHlwZSwgdGFnIG51bWJlciwKKyAqIGFuZCB0eXBlIGNsYXNzIChmb3IgbWVzc2FnZSBhbmQgZW51bSBmaWVsZHMpLiBUaGUgdHlwZSBtdXN0IGJlIGEgUnVieSBzeW1ib2wKKyAqIChhcyBhY2NlcHRlZCBieSBGaWVsZERlc2NyaXB0b3IjdHlwZT0pIGFuZCB0aGUgdHlwZV9jbGFzcyBtdXN0IGJlIGEgc3RyaW5nLAorICogaWYgcHJlc2VudCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3N1Ym1zZ19uYW1lPSkuCisgKi8KK1ZBTFVFIE9uZW9mQnVpbGRlckNvbnRleHRfb3B0aW9uYWwoaW50IGFyZ2MsIFZBTFVFKiBhcmd2LCBWQUxVRSBfc2VsZikgeworICBERUZJTkVfU0VMRihPbmVvZkJ1aWxkZXJDb250ZXh0LCBzZWxmLCBfc2VsZik7CisKKyAgaWYgKGFyZ2MgPCAzKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiRXhwZWN0ZWQgYXQgbGVhc3QgMyBhcmd1bWVudHMuIik7CisgIH0KKyAgVkFMVUUgbmFtZSA9IGFyZ3ZbMF07CisgIFZBTFVFIHR5cGUgPSBhcmd2WzFdOworICBWQUxVRSBudW1iZXIgPSBhcmd2WzJdOworICBWQUxVRSB0eXBlX2NsYXNzID0gKGFyZ2MgPiAzKSA/IGFyZ3ZbM10gOiBRbmlsOworCisgIHJldHVybiBtc2dkZWZfYWRkX2ZpZWxkKHNlbGYtPmRlc2NyaXB0b3IsICJvcHRpb25hbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZV9jbGFzcyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBFbnVtQnVpbGRlckNvbnRleHQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitERUZJTkVfQ0xBU1MoRW51bUJ1aWxkZXJDb250ZXh0LAorICAgICJHb29nbGU6OlByb3RvYnVmOjpJbnRlcm5hbDo6RW51bUJ1aWxkZXJDb250ZXh0Iik7CisKK3ZvaWQgRW51bUJ1aWxkZXJDb250ZXh0X21hcmsodm9pZCogX3NlbGYpIHsKKyAgRW51bUJ1aWxkZXJDb250ZXh0KiBzZWxmID0gX3NlbGY7CisgIHJiX2djX21hcmsoc2VsZi0+ZW51bWRlc2MpOworfQorCit2b2lkIEVudW1CdWlsZGVyQ29udGV4dF9mcmVlKHZvaWQqIF9zZWxmKSB7CisgIEVudW1CdWlsZGVyQ29udGV4dCogc2VsZiA9IF9zZWxmOworICB4ZnJlZShzZWxmKTsKK30KKworVkFMVUUgRW51bUJ1aWxkZXJDb250ZXh0X2FsbG9jKFZBTFVFIGtsYXNzKSB7CisgIEVudW1CdWlsZGVyQ29udGV4dCogc2VsZiA9IEFMTE9DKEVudW1CdWlsZGVyQ29udGV4dCk7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdCgKKyAgICAgIGtsYXNzLCAmX0VudW1CdWlsZGVyQ29udGV4dF90eXBlLCBzZWxmKTsKKyAgc2VsZi0+ZW51bWRlc2MgPSBRbmlsOworICByZXR1cm4gcmV0OworfQorCit2b2lkIEVudW1CdWlsZGVyQ29udGV4dF9yZWdpc3RlcihWQUxVRSBtb2R1bGUpIHsKKyAgVkFMVUUga2xhc3MgPSByYl9kZWZpbmVfY2xhc3NfdW5kZXIoCisgICAgICBtb2R1bGUsICJFbnVtQnVpbGRlckNvbnRleHQiLCByYl9jT2JqZWN0KTsKKyAgcmJfZGVmaW5lX2FsbG9jX2Z1bmMoa2xhc3MsIEVudW1CdWlsZGVyQ29udGV4dF9hbGxvYyk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJpbml0aWFsaXplIiwKKyAgICAgICAgICAgICAgICAgICBFbnVtQnVpbGRlckNvbnRleHRfaW5pdGlhbGl6ZSwgMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJ2YWx1ZSIsIEVudW1CdWlsZGVyQ29udGV4dF92YWx1ZSwgMik7CisgIGNFbnVtQnVpbGRlckNvbnRleHQgPSBrbGFzczsKKyAgcmJfZ2NfcmVnaXN0ZXJfYWRkcmVzcygmY0VudW1CdWlsZGVyQ29udGV4dCk7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtQnVpbGRlckNvbnRleHQubmV3KGVudW1kZXNjKSA9PiBjb250ZXh0CisgKgorICogQ3JlYXRlIGEgbmV3IGJ1aWxkZXIgY29udGV4dCBhcm91bmQgdGhlIGdpdmVuIGVudW0gZGVzY3JpcHRvci4gVGhpcyBjbGFzcyBpcworICogaW50ZW5kZWQgdG8gc2VydmUgYXMgYSBEU0wgY29udGV4dCB0byBiZSB1c2VkIHdpdGggI2luc3RhbmNlX2V2YWwuCisgKi8KK1ZBTFVFIEVudW1CdWlsZGVyQ29udGV4dF9pbml0aWFsaXplKFZBTFVFIF9zZWxmLCBWQUxVRSBlbnVtZGVmKSB7CisgIERFRklORV9TRUxGKEVudW1CdWlsZGVyQ29udGV4dCwgc2VsZiwgX3NlbGYpOworICBzZWxmLT5lbnVtZGVzYyA9IGVudW1kZWY7CisgIHJldHVybiBRbmlsOworfQorCitzdGF0aWMgVkFMVUUgZW51bWRlZl9hZGRfdmFsdWUoVkFMVUUgZW51bWRlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxVRSBuYW1lLCBWQUxVRSBudW1iZXIpIHsKKyAgcmJfZnVuY2FsbChlbnVtZGVmLCByYl9pbnRlcm4oImFkZF92YWx1ZSIpLCAyLCBuYW1lLCBudW1iZXIpOworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEVudW1CdWlsZGVyLmFkZF92YWx1ZShuYW1lLCBudW1iZXIpCisgKgorICogQWRkcyB0aGUgZ2l2ZW4gbmFtZSA9PiBudW1iZXIgbWFwcGluZyB0byB0aGUgZW51bSB0eXBlLiBOYW1lIG11c3QgYmUgYSBSdWJ5CisgKiBzeW1ib2wuCisgKi8KK1ZBTFVFIEVudW1CdWlsZGVyQ29udGV4dF92YWx1ZShWQUxVRSBfc2VsZiwgVkFMVUUgbmFtZSwgVkFMVUUgbnVtYmVyKSB7CisgIERFRklORV9TRUxGKEVudW1CdWlsZGVyQ29udGV4dCwgc2VsZiwgX3NlbGYpOworICByZXR1cm4gZW51bWRlZl9hZGRfdmFsdWUoc2VsZi0+ZW51bWRlc2MsIG5hbWUsIG51bWJlcik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBCdWlsZGVyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworREVGSU5FX0NMQVNTKEJ1aWxkZXIsICJHb29nbGU6OlByb3RvYnVmOjpJbnRlcm5hbDo6QnVpbGRlciIpOworCit2b2lkIEJ1aWxkZXJfbWFyayh2b2lkKiBfc2VsZikgeworICBCdWlsZGVyKiBzZWxmID0gX3NlbGY7CisgIHJiX2djX21hcmsoc2VsZi0+cGVuZGluZ19saXN0KTsKK30KKwordm9pZCBCdWlsZGVyX2ZyZWUodm9pZCogX3NlbGYpIHsKKyAgQnVpbGRlciogc2VsZiA9IF9zZWxmOworICB4ZnJlZShzZWxmLT5kZWZzKTsKKyAgeGZyZWUoc2VsZik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBCdWlsZGVyLm5ldyA9PiBidWlsZGVyCisgKgorICogQ3JlYXRlcyBhIG5ldyBCdWlsZGVyLiBBIEJ1aWxkZXIgY2FuIGFjY3VtdWxhdGUgYSBzZXQgb2YgbmV3IG1lc3NhZ2UgYW5kIGVudW0KKyAqIGRlc2NyaXB0b3JzIGFuZCBhdG9taWNhbGx5IHJlZ2lzdGVyIHRoZW0gaW50byBhIHBvb2wgaW4gYSB3YXkgdGhhdCBhbGxvd3MgZm9yCisgKiAoY28pcmVjdXJzaXZlIHR5cGUgcmVmZXJlbmNlcy4KKyAqLworVkFMVUUgQnVpbGRlcl9hbGxvYyhWQUxVRSBrbGFzcykgeworICBCdWlsZGVyKiBzZWxmID0gQUxMT0MoQnVpbGRlcik7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdCgKKyAgICAgIGtsYXNzLCAmX0J1aWxkZXJfdHlwZSwgc2VsZik7CisgIHNlbGYtPnBlbmRpbmdfbGlzdCA9IHJiX2FyeV9uZXcoKTsKKyAgc2VsZi0+ZGVmcyA9IE5VTEw7CisgIHJldHVybiByZXQ7Cit9CisKK3ZvaWQgQnVpbGRlcl9yZWdpc3RlcihWQUxVRSBtb2R1bGUpIHsKKyAgVkFMVUUga2xhc3MgPSByYl9kZWZpbmVfY2xhc3NfdW5kZXIobW9kdWxlLCAiQnVpbGRlciIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgQnVpbGRlcl9hbGxvYyk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJhZGRfbWVzc2FnZSIsIEJ1aWxkZXJfYWRkX21lc3NhZ2UsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiYWRkX2VudW0iLCBCdWlsZGVyX2FkZF9lbnVtLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImZpbmFsaXplX3RvX3Bvb2wiLCBCdWlsZGVyX2ZpbmFsaXplX3RvX3Bvb2wsIDEpOworICBjQnVpbGRlciA9IGtsYXNzOworICByYl9nY19yZWdpc3Rlcl9hZGRyZXNzKCZjQnVpbGRlcik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBCdWlsZGVyLmFkZF9tZXNzYWdlKG5hbWUsICZibG9jaykKKyAqCisgKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSBkZXNjcmlwdG9yIHdpdGggdGhlIGdpdmVuIG5hbWUsIGFuZCBpbnZva2VzIHRoZSBibG9jayBpbgorICogdGhlIGNvbnRleHQgb2YgYSBNZXNzYWdlQnVpbGRlckNvbnRleHQgb24gdGhhdCBkZXNjcmlwdG9yLiBUaGUgYmxvY2sgY2FuIHRoZW4KKyAqIGNhbGwsIGUuZy4sIE1lc3NhZ2VCdWlsZGVyQ29udGV4dCNvcHRpb25hbCBhbmQgTWVzc2FnZUJ1aWxkZXJDb250ZXh0I3JlcGVhdGVkCisgKiBtZXRob2RzIHRvIGRlZmluZSB0aGUgbWVzc2FnZSBmaWVsZHMuCisgKgorICogVGhpcyBpcyB0aGUgcmVjb21tZW5kZWQsIGlkaW9tYXRpYyB3YXkgdG8gYnVpbGQgbWVzc2FnZSBkZWZpbml0aW9ucy4KKyAqLworVkFMVUUgQnVpbGRlcl9hZGRfbWVzc2FnZShWQUxVRSBfc2VsZiwgVkFMVUUgbmFtZSkgeworICBERUZJTkVfU0VMRihCdWlsZGVyLCBzZWxmLCBfc2VsZik7CisgIFZBTFVFIG1zZ2RlZiA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBjRGVzY3JpcHRvcik7CisgIFZBTFVFIGFyZ3NbMl0gPSB7IG1zZ2RlZiwgX3NlbGYgfTsKKyAgVkFMVUUgY3R4ID0gcmJfY2xhc3NfbmV3X2luc3RhbmNlKDIsIGFyZ3MsIGNNZXNzYWdlQnVpbGRlckNvbnRleHQpOworICBWQUxVRSBibG9jayA9IHJiX2Jsb2NrX3Byb2MoKTsKKyAgcmJfZnVuY2FsbChtc2dkZWYsIHJiX2ludGVybigibmFtZT0iKSwgMSwgbmFtZSk7CisgIHJiX2Z1bmNhbGxfd2l0aF9ibG9jayhjdHgsIHJiX2ludGVybigiaW5zdGFuY2VfZXZhbCIpLCAwLCBOVUxMLCBibG9jayk7CisgIHJiX2FyeV9wdXNoKHNlbGYtPnBlbmRpbmdfbGlzdCwgbXNnZGVmKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBCdWlsZGVyLmFkZF9lbnVtKG5hbWUsICZibG9jaykKKyAqCisgKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSBlbnVtIGRlc2NyaXB0b3Igd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgYW5kIGludm9rZXMgdGhlIGJsb2NrIGluCisgKiB0aGUgY29udGV4dCBvZiBhbiBFbnVtQnVpbGRlckNvbnRleHQgb24gdGhhdCBkZXNjcmlwdG9yLiBUaGUgYmxvY2sgY2FuIHRoZW4KKyAqIGNhbGwgRW51bUJ1aWxkZXJDb250ZXh0I2FkZF92YWx1ZSB0byBkZWZpbmUgdGhlIGVudW0gdmFsdWVzLgorICoKKyAqIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkLCBpZGlvbWF0aWMgd2F5IHRvIGJ1aWxkIGVudW0gZGVmaW5pdGlvbnMuCisgKi8KK1ZBTFVFIEJ1aWxkZXJfYWRkX2VudW0oVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpIHsKKyAgREVGSU5FX1NFTEYoQnVpbGRlciwgc2VsZiwgX3NlbGYpOworICBWQUxVRSBlbnVtZGVmID0gcmJfY2xhc3NfbmV3X2luc3RhbmNlKDAsIE5VTEwsIGNFbnVtRGVzY3JpcHRvcik7CisgIFZBTFVFIGN0eCA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgxLCAmZW51bWRlZiwgY0VudW1CdWlsZGVyQ29udGV4dCk7CisgIFZBTFVFIGJsb2NrID0gcmJfYmxvY2tfcHJvYygpOworICByYl9mdW5jYWxsKGVudW1kZWYsIHJiX2ludGVybigibmFtZT0iKSwgMSwgbmFtZSk7CisgIHJiX2Z1bmNhbGxfd2l0aF9ibG9jayhjdHgsIHJiX2ludGVybigiaW5zdGFuY2VfZXZhbCIpLCAwLCBOVUxMLCBibG9jayk7CisgIHJiX2FyeV9wdXNoKHNlbGYtPnBlbmRpbmdfbGlzdCwgZW51bWRlZik7CisgIHJldHVybiBRbmlsOworfQorCitzdGF0aWMgdm9pZCB2YWxpZGF0ZV9tc2dkZWYoY29uc3QgdXBiX21zZ2RlZiogbXNnZGVmKSB7CisgIC8vIFZlcmlmeSB0aGF0IG5vIHJlcXVpcmVkIGZpZWxkcyBleGlzdC4gcHJvdG8zIGRvZXMgbm90IHN1cHBvcnQgdGhlc2UuCisgIHVwYl9tc2dfZmllbGRfaXRlciBpdDsKKyAgZm9yICh1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpdCwgbXNnZGVmKTsKKyAgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpdCk7CisgICAgICAgdXBiX21zZ19maWVsZF9uZXh0KCZpdCkpIHsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpdCk7CisgICAgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUVVJUkVEKSB7CisgICAgICByYl9yYWlzZShyYl9lVHlwZUVycm9yLCAiUmVxdWlyZWQgZmllbGRzIGFyZSB1bnN1cHBvcnRlZCBpbiBwcm90bzMuIik7CisgICAgfQorICB9Cit9CisKK3N0YXRpYyB2b2lkIHZhbGlkYXRlX2VudW1kZWYoY29uc3QgdXBiX2VudW1kZWYqIGVudW1kZWYpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgYW4gZW50cnkgZXhpc3RzIHdpdGggaW50ZWdlciB2YWx1ZSAwLiAoVGhpcyBpcyB0aGUgZGVmYXVsdAorICAvLyB2YWx1ZS4pCisgIGNvbnN0IGNoYXIqIGxvb2t1cCA9IHVwYl9lbnVtZGVmX2l0b24oZW51bWRlZiwgMCk7CisgIGlmIChsb29rdXAgPT0gTlVMTCkgeworICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsCisgICAgICAgICAgICAgIkVudW0gZGVmaW5pdGlvbiBkb2VzIG5vdCBjb250YWluIGEgdmFsdWUgZm9yICcwJy4iKTsKKyAgfQorfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgQnVpbGRlci5maW5hbGl6ZV90b19wb29sKHBvb2wpCisgKgorICogQWRkcyBhbGwgYWNjdW11bGF0ZWQgbWVzc2FnZSBhbmQgZW51bSBkZXNjcmlwdG9ycyBjcmVhdGVkIGluIHRoaXMgYnVpbGRlcgorICogY29udGV4dCB0byB0aGUgZ2l2ZW4gcG9vbC4gVGhlIG9wZXJhdGlvbiBvY2N1cnMgYXRvbWljYWxseSwgYW5kIGFsbAorICogZGVzY3JpcHRvcnMgY2FuIHJlZmVyIHRvIGVhY2ggb3RoZXIgKGluY2x1ZGluZyBpbiBjeWNsZXMpLiBUaGlzIGlzIHRoZSBvbmx5CisgKiB3YXkgdG8gYnVpbGQgKGNvKXJlY3Vyc2l2ZSBtZXNzYWdlIGRlZmluaXRpb25zLgorICoKKyAqIFRoaXMgbWV0aG9kIGlzIHVzdWFsbHkgY2FsbGVkIGF1dG9tYXRpY2FsbHkgYnkgRGVzY3JpcHRvclBvb2wjYnVpbGQgYWZ0ZXIgaXQKKyAqIGludm9rZXMgdGhlIGdpdmVuIHVzZXIgYmxvY2sgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGJ1aWxkZXIuIFRoZSB1c2VyIHNob3VsZAorICogbm90IG5vcm1hbGx5IG5lZWQgdG8gY2FsbCB0aGlzIG1hbnVhbGx5IGJlY2F1c2UgYSBCdWlsZGVyIGlzIG5vdCBub3JtYWxseQorICogY3JlYXRlZCBtYW51YWxseS4KKyAqLworVkFMVUUgQnVpbGRlcl9maW5hbGl6ZV90b19wb29sKFZBTFVFIF9zZWxmLCBWQUxVRSBwb29sX3JiKSB7CisgIERFRklORV9TRUxGKEJ1aWxkZXIsIHNlbGYsIF9zZWxmKTsKKworICBEZXNjcmlwdG9yUG9vbCogcG9vbCA9IHJ1YnlfdG9fRGVzY3JpcHRvclBvb2wocG9vbF9yYik7CisKKyAgUkVBTExPQ19OKHNlbGYtPmRlZnMsIHVwYl9kZWYqLCBSQVJSQVlfTEVOKHNlbGYtPnBlbmRpbmdfbGlzdCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgUkFSUkFZX0xFTihzZWxmLT5wZW5kaW5nX2xpc3QpOyBpKyspIHsKKyAgICBWQUxVRSBkZWZfcmIgPSByYl9hcnlfZW50cnkoc2VsZi0+cGVuZGluZ19saXN0LCBpKTsKKyAgICBpZiAoQ0xBU1NfT0YoZGVmX3JiKSA9PSBjRGVzY3JpcHRvcikgeworICAgICAgc2VsZi0+ZGVmc1tpXSA9ICh1cGJfZGVmKilydWJ5X3RvX0Rlc2NyaXB0b3IoZGVmX3JiKS0+bXNnZGVmOworICAgICAgdmFsaWRhdGVfbXNnZGVmKChjb25zdCB1cGJfbXNnZGVmKilzZWxmLT5kZWZzW2ldKTsKKyAgICB9IGVsc2UgaWYgKENMQVNTX09GKGRlZl9yYikgPT0gY0VudW1EZXNjcmlwdG9yKSB7CisgICAgICBzZWxmLT5kZWZzW2ldID0gKHVwYl9kZWYqKXJ1YnlfdG9fRW51bURlc2NyaXB0b3IoZGVmX3JiKS0+ZW51bWRlZjsKKyAgICAgIHZhbGlkYXRlX2VudW1kZWYoKGNvbnN0IHVwYl9lbnVtZGVmKilzZWxmLT5kZWZzW2ldKTsKKyAgICB9CisgIH0KKworICBDSEVDS19VUEIodXBiX3N5bXRhYl9hZGQocG9vbC0+c3ltdGFiLCAodXBiX2RlZioqKXNlbGYtPmRlZnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBSQVJSQVlfTEVOKHNlbGYtPnBlbmRpbmdfbGlzdCksIE5VTEwsICZzdGF0dXMpLAorICAgICAgICAgICAgIlVuYWJsZSB0byBhZGQgZGVmcyB0byBEZXNjcmlwdG9yUG9vbCIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgUkFSUkFZX0xFTihzZWxmLT5wZW5kaW5nX2xpc3QpOyBpKyspIHsKKyAgICBWQUxVRSBkZWZfcmIgPSByYl9hcnlfZW50cnkoc2VsZi0+cGVuZGluZ19saXN0LCBpKTsKKyAgICBhZGRfZGVmX29iaihzZWxmLT5kZWZzW2ldLCBkZWZfcmIpOworICB9CisKKyAgc2VsZi0+cGVuZGluZ19saXN0ID0gcmJfYXJ5X25ldygpOworICByZXR1cm4gUW5pbDsKK30KZGlmZiAtLWdpdCBhL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL2VuY29kZV9kZWNvZGUuYyBiL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL2VuY29kZV9kZWNvZGUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzMwNTA0Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvZW5jb2RlX2RlY29kZS5jCkBAIC0wLDAgKzEsMTE2NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlICJwcm90b2J1Zi5oIgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUGFyc2luZy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgREVSRUYobXNnLCBvZnMsIHR5cGUpICoodHlwZSopKCgodWludDhfdCAqKW1zZykgKyBvZnMpCisKKy8vIENyZWF0ZXMgYSBoYW5kbGVyZGF0YSB0aGF0IHNpbXBseSBjb250YWlucyB0aGUgb2Zmc2V0IGZvciB0aGlzIGZpZWxkLgorc3RhdGljIGNvbnN0IHZvaWQqIG5ld2hhbmRsZXJkYXRhKHVwYl9oYW5kbGVycyogaCwgdWludDMyX3Qgb2ZzKSB7CisgIHNpemVfdCogaGRfb2ZzID0gQUxMT0Moc2l6ZV90KTsKKyAgKmhkX29mcyA9IG9mczsKKyAgdXBiX2hhbmRsZXJzX2FkZGNsZWFudXAoaCwgaGRfb2ZzLCBmcmVlKTsKKyAgcmV0dXJuIGhkX29mczsKK30KKwordHlwZWRlZiBzdHJ1Y3QgeworICBzaXplX3Qgb2ZzOworICBjb25zdCB1cGJfbXNnZGVmICptZDsKK30gc3VibXNnX2hhbmRsZXJkYXRhX3Q7CisKKy8vIENyZWF0ZXMgYSBoYW5kbGVyZGF0YSB0aGF0IGNvbnRhaW5zIG9mZnNldCBhbmQgc3VibWVzc2FnZSB0eXBlIGluZm9ybWF0aW9uLgorc3RhdGljIGNvbnN0IHZvaWQgKm5ld3N1Ym1zZ2hhbmRsZXJkYXRhKHVwYl9oYW5kbGVycyogaCwgdWludDMyX3Qgb2ZzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiogZikgeworICBzdWJtc2dfaGFuZGxlcmRhdGFfdCAqaGQgPSBBTExPQyhzdWJtc2dfaGFuZGxlcmRhdGFfdCk7CisgIGhkLT5vZnMgPSBvZnM7CisgIGhkLT5tZCA9IHVwYl9maWVsZGRlZl9tc2dzdWJkZWYoZik7CisgIHVwYl9oYW5kbGVyc19hZGRjbGVhbnVwKGgsIGhkLCBmcmVlKTsKKyAgcmV0dXJuIGhkOworfQorCit0eXBlZGVmIHN0cnVjdCB7CisgIHNpemVfdCBvZnM7ICAgICAgICAgICAgICAvLyB1bmlvbiBkYXRhIHNsb3QKKyAgc2l6ZV90IGNhc2Vfb2ZzOyAgICAgICAgIC8vIG9uZW9mX2Nhc2UgZmllbGQKKyAgdWludDMyX3Qgb25lb2ZfY2FzZV9udW07IC8vIG9uZW9mLWNhc2UgbnVtYmVyIHRvIHBsYWNlIGluIG9uZW9mX2Nhc2UgZmllbGQKKyAgY29uc3QgdXBiX21zZ2RlZiAqbWQ7ICAgIC8vIG1zZ2RlZiwgZm9yIG9uZW9mIHN1Ym1lc3NhZ2UgaGFuZGxlcgorfSBvbmVvZl9oYW5kbGVyZGF0YV90OworCitzdGF0aWMgY29uc3Qgdm9pZCAqbmV3b25lb2ZoYW5kbGVyZGF0YSh1cGJfaGFuZGxlcnMgKmgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBvZnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBjYXNlX29mcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBvbmVvZl9oYW5kbGVyZGF0YV90ICpoZCA9IEFMTE9DKG9uZW9mX2hhbmRsZXJkYXRhX3QpOworICBoZC0+b2ZzID0gb2ZzOworICBoZC0+Y2FzZV9vZnMgPSBjYXNlX29mczsKKyAgLy8gV2UgcmV1c2UgdGhlIGZpZWxkIHRhZyBudW1iZXIgYXMgYSBvbmVvZiB1bmlvbiBkaXNjcmltaW5hbnQgdGFnLiBOb3RlIHRoYXQKKyAgLy8gd2UgZG9uJ3QgZXhwb3NlIHRoZXNlIG51bWJlcnMgdG8gdGhlIHVzZXIsIHNvIHRoZSBvbmx5IHJlcXVpcmVtZW50IGlzIHRoYXQKKyAgLy8gd2UgaGF2ZSBzb21lIHVuaXF1ZSBJRCBmb3IgZWFjaCB1bmlvbiBjYXNlL3Bvc3NpYmlsaXR5LiBUaGUgZmllbGQgdGFnCisgIC8vIG51bWJlcnMgYXJlIGFscmVhZHkgcHJlc2VudCBhbmQgYXJlIGVhc3kgdG8gdXNlIHNvIHRoZXJlJ3Mgbm8gcmVhc29uIHRvCisgIC8vIGNyZWF0ZSBhIHNlcGFyYXRlIElEIHNwYWNlLiBJbiBhZGRpdGlvbiwgdXNpbmcgdGhlIGZpZWxkIHRhZyBudW1iZXIgaGVyZQorICAvLyBsZXRzIHVzIGVhc2lseSBsb29rIHVwIHRoZSBmaWVsZCBpbiB0aGUgb25lb2YgYWNjZXNzb3IuCisgIGhkLT5vbmVvZl9jYXNlX251bSA9IHVwYl9maWVsZGRlZl9udW1iZXIoZik7CisgIGlmICh1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9NRVNTQUdFKSB7CisgICAgaGQtPm1kID0gdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihmKTsKKyAgfSBlbHNlIHsKKyAgICBoZC0+bWQgPSBOVUxMOworICB9CisgIHVwYl9oYW5kbGVyc19hZGRjbGVhbnVwKGgsIGhkLCBmcmVlKTsKKyAgcmV0dXJuIGhkOworfQorCisvLyBBIGhhbmRsZXIgdGhhdCBzdGFydHMgYSByZXBlYXRlZCBmaWVsZC4gIEdldHMgdGhlIFJlcGVhdGVkKkZpZWxkIGluc3RhbmNlIGZvcgorLy8gdGhpcyBmaWVsZCAoc3VjaCBhbiBpbnN0YW5jZSBhbHdheXMgZXhpc3RzIGV2ZW4gaW4gYW4gZW1wdHkgbWVzc2FnZSkuCitzdGF0aWMgdm9pZCAqc3RhcnRzZXFfaGFuZGxlcih2b2lkKiBjbG9zdXJlLCBjb25zdCB2b2lkKiBoZCkgeworICBNZXNzYWdlSGVhZGVyKiBtc2cgPSBjbG9zdXJlOworICBjb25zdCBzaXplX3QgKm9mcyA9IGhkOworICByZXR1cm4gKHZvaWQqKURFUkVGKG1zZywgKm9mcywgVkFMVUUpOworfQorCisvLyBIYW5kbGVycyB0aGF0IGFwcGVuZCBwcmltaXRpdmUgdmFsdWVzIHRvIGEgcmVwZWF0ZWQgZmllbGQuCisjZGVmaW5lIERFRklORV9BUFBFTkRfSEFORExFUih0eXBlLCBjdHlwZSkgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgYXBwZW5kIyN0eXBlIyNfaGFuZGxlcih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eXBlIHZhbCkgeyAgICAgICAgICAgICAgICAgICBcCisgICAgVkFMVUUgYXJ5ID0gKFZBTFVFKWNsb3N1cmU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBSZXBlYXRlZEZpZWxkX3B1c2hfbmF0aXZlKGFyeSwgJnZhbCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKworREVGSU5FX0FQUEVORF9IQU5ETEVSKGJvb2wsICAgYm9vbCkKK0RFRklORV9BUFBFTkRfSEFORExFUihpbnQzMiwgIGludDMyX3QpCitERUZJTkVfQVBQRU5EX0hBTkRMRVIodWludDMyLCB1aW50MzJfdCkKK0RFRklORV9BUFBFTkRfSEFORExFUihmbG9hdCwgIGZsb2F0KQorREVGSU5FX0FQUEVORF9IQU5ETEVSKGludDY0LCAgaW50NjRfdCkKK0RFRklORV9BUFBFTkRfSEFORExFUih1aW50NjQsIHVpbnQ2NF90KQorREVGSU5FX0FQUEVORF9IQU5ETEVSKGRvdWJsZSwgZG91YmxlKQorCisvLyBBcHBlbmRzIGEgc3RyaW5nIHRvIGEgcmVwZWF0ZWQgZmllbGQuCitzdGF0aWMgdm9pZCogYXBwZW5kc3RyX2hhbmRsZXIodm9pZCAqY2xvc3VyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpoZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZV9oaW50KSB7CisgIFZBTFVFIGFyeSA9IChWQUxVRSljbG9zdXJlOworICBWQUxVRSBzdHIgPSByYl9zdHJfbmV3MigiIik7CisgIHJiX2VuY19hc3NvY2lhdGUoc3RyLCBrUnVieVN0cmluZ1V0ZjhFbmNvZGluZyk7CisgIFJlcGVhdGVkRmllbGRfcHVzaChhcnksIHN0cik7CisgIHJldHVybiAodm9pZCopc3RyOworfQorCisvLyBBcHBlbmRzIGEgJ2J5dGVzJyBzdHJpbmcgdG8gYSByZXBlYXRlZCBmaWVsZC4KK3N0YXRpYyB2b2lkKiBhcHBlbmRieXRlc19oYW5kbGVyKHZvaWQgKmNsb3N1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpoZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplX2hpbnQpIHsKKyAgVkFMVUUgYXJ5ID0gKFZBTFVFKWNsb3N1cmU7CisgIFZBTFVFIHN0ciA9IHJiX3N0cl9uZXcyKCIiKTsKKyAgcmJfZW5jX2Fzc29jaWF0ZShzdHIsIGtSdWJ5U3RyaW5nOGJpdEVuY29kaW5nKTsKKyAgUmVwZWF0ZWRGaWVsZF9wdXNoKGFyeSwgc3RyKTsKKyAgcmV0dXJuICh2b2lkKilzdHI7Cit9CisKKy8vIFNldHMgYSBub24tcmVwZWF0ZWQgc3RyaW5nIGZpZWxkIGluIGEgbWVzc2FnZS4KK3N0YXRpYyB2b2lkKiBzdHJfaGFuZGxlcih2b2lkICpjbG9zdXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmhkLAorICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplX2hpbnQpIHsKKyAgTWVzc2FnZUhlYWRlciogbXNnID0gY2xvc3VyZTsKKyAgY29uc3Qgc2l6ZV90ICpvZnMgPSBoZDsKKyAgVkFMVUUgc3RyID0gcmJfc3RyX25ldzIoIiIpOworICByYl9lbmNfYXNzb2NpYXRlKHN0ciwga1J1YnlTdHJpbmdVdGY4RW5jb2RpbmcpOworICBERVJFRihtc2csICpvZnMsIFZBTFVFKSA9IHN0cjsKKyAgcmV0dXJuICh2b2lkKilzdHI7Cit9CisKKy8vIFNldHMgYSBub24tcmVwZWF0ZWQgJ2J5dGVzJyBmaWVsZCBpbiBhIG1lc3NhZ2UuCitzdGF0aWMgdm9pZCogYnl0ZXNfaGFuZGxlcih2b2lkICpjbG9zdXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqaGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZV9oaW50KSB7CisgIE1lc3NhZ2VIZWFkZXIqIG1zZyA9IGNsb3N1cmU7CisgIGNvbnN0IHNpemVfdCAqb2ZzID0gaGQ7CisgIFZBTFVFIHN0ciA9IHJiX3N0cl9uZXcyKCIiKTsKKyAgcmJfZW5jX2Fzc29jaWF0ZShzdHIsIGtSdWJ5U3RyaW5nOGJpdEVuY29kaW5nKTsKKyAgREVSRUYobXNnLCAqb2ZzLCBWQUxVRSkgPSBzdHI7CisgIHJldHVybiAodm9pZCopc3RyOworfQorCitzdGF0aWMgc2l6ZV90IHN0cmluZ2RhdGFfaGFuZGxlcih2b2lkKiBjbG9zdXJlLCBjb25zdCB2b2lkKiBoZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHN0ciwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9idWZoYW5kbGUqIGhhbmRsZSkgeworICBWQUxVRSByYl9zdHIgPSAoVkFMVUUpY2xvc3VyZTsKKyAgcmJfc3RyX2NhdChyYl9zdHIsIHN0ciwgbGVuKTsKKyAgcmV0dXJuIGxlbjsKK30KKworLy8gQXBwZW5kcyBhIHN1Ym1lc3NhZ2UgdG8gYSByZXBlYXRlZCBmaWVsZCAoYSByZWd1bGFyIFJ1YnkgYXJyYXkgZm9yIG5vdykuCitzdGF0aWMgdm9pZCAqYXBwZW5kc3VibXNnX2hhbmRsZXIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQpIHsKKyAgVkFMVUUgYXJ5ID0gKFZBTFVFKWNsb3N1cmU7CisgIGNvbnN0IHN1Ym1zZ19oYW5kbGVyZGF0YV90ICpzdWJtc2dkYXRhID0gaGQ7CisgIFZBTFVFIHN1YmRlc2MgPQorICAgICAgZ2V0X2RlZl9vYmooKHZvaWQqKXN1Ym1zZ2RhdGEtPm1kKTsKKyAgVkFMVUUgc3Via2xhc3MgPSBEZXNjcmlwdG9yX21zZ2NsYXNzKHN1YmRlc2MpOworCisgIFZBTFVFIHN1Ym1zZ19yYiA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBzdWJrbGFzcyk7CisgIFJlcGVhdGVkRmllbGRfcHVzaChhcnksIHN1Ym1zZ19yYik7CisKKyAgTWVzc2FnZUhlYWRlciogc3VibXNnOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChzdWJtc2dfcmIsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIHN1Ym1zZyk7CisgIHJldHVybiBzdWJtc2c7Cit9CisKKy8vIFNldHMgYSBub24tcmVwZWF0ZWQgc3VibWVzc2FnZSBmaWVsZCBpbiBhIG1lc3NhZ2UuCitzdGF0aWMgdm9pZCAqc3VibXNnX2hhbmRsZXIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQpIHsKKyAgTWVzc2FnZUhlYWRlciogbXNnID0gY2xvc3VyZTsKKyAgY29uc3Qgc3VibXNnX2hhbmRsZXJkYXRhX3QqIHN1Ym1zZ2RhdGEgPSBoZDsKKyAgVkFMVUUgc3ViZGVzYyA9CisgICAgICBnZXRfZGVmX29iaigodm9pZCopc3VibXNnZGF0YS0+bWQpOworICBWQUxVRSBzdWJrbGFzcyA9IERlc2NyaXB0b3JfbXNnY2xhc3Moc3ViZGVzYyk7CisKKyAgaWYgKERFUkVGKG1zZywgc3VibXNnZGF0YS0+b2ZzLCBWQUxVRSkgPT0gUW5pbCkgeworICAgIERFUkVGKG1zZywgc3VibXNnZGF0YS0+b2ZzLCBWQUxVRSkgPQorICAgICAgICByYl9jbGFzc19uZXdfaW5zdGFuY2UoMCwgTlVMTCwgc3Via2xhc3MpOworICB9CisKKyAgVkFMVUUgc3VibXNnX3JiID0gREVSRUYobXNnLCBzdWJtc2dkYXRhLT5vZnMsIFZBTFVFKTsKKyAgTWVzc2FnZUhlYWRlciogc3VibXNnOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChzdWJtc2dfcmIsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIHN1Ym1zZyk7CisgIHJldHVybiBzdWJtc2c7Cit9CisKKy8vIEhhbmRsZXIgZGF0YSBmb3Igc3RhcnRtYXAvZW5kbWFwIGhhbmRsZXJzLgordHlwZWRlZiBzdHJ1Y3QgeworICBzaXplX3Qgb2ZzOworICB1cGJfZmllbGR0eXBlX3Qga2V5X2ZpZWxkX3R5cGU7CisgIHVwYl9maWVsZHR5cGVfdCB2YWx1ZV9maWVsZF90eXBlOworCisgIC8vIFdlIGtub3cgdGhhdCB3ZSBjYW4gaG9sZCB0aGlzIHJlZmVyZW5jZSBiZWNhdXNlIHRoZSBoYW5kbGVyZGF0YSBoYXMgdGhlCisgIC8vIHNhbWUgbGlmZXRpbWUgYXMgdGhlIHVwYl9oYW5kbGVycyBzdHJ1Y3QsIGFuZCB0aGUgdXBiX2hhbmRsZXJzIHN0cnVjdCBob2xkcworICAvLyBhIHJlZmVyZW5jZSB0byB0aGUgdXBiX21zZ2RlZiwgd2hpY2ggaW4gdHVybiBoYXMgcmVmZXJlbmNlcyB0byBpdHMgc3ViZGVmcy4KKyAgY29uc3QgdXBiX2RlZiogdmFsdWVfZmllbGRfc3ViZGVmOworfSBtYXBfaGFuZGxlcmRhdGFfdDsKKworLy8gVGVtcG9yYXJ5IGZyYW1lIGZvciBtYXAgcGFyc2luZzogYXQgdGhlIGJlZ2lubmluZyBvZiBhIG1hcCBlbnRyeSBtZXNzYWdlLCBhCisvLyBzdWJtc2cgaGFuZGxlciBhbGxvY2F0ZXMgYSBmcmFtZSB0byBob2xkIChpKSBhIHJlZmVyZW5jZSB0byB0aGUgTWFwIG9iamVjdAorLy8gaW50byB3aGljaCB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBpbnNlcnRlZCBhbmQgKGlpKSBzdG9yYWdlIHNsb3RzIHRvCisvLyB0ZW1wb3JhcmlseSBob2xkIHRoZSBrZXkgYW5kIHZhbHVlIGZvciB0aGlzIG1hcCBlbnRyeSB1bnRpbCB0aGUgZW5kIG9mIHRoZQorLy8gc3VibWVzc2FnZS4gV2hlbiB0aGUgc3VibWVzc2FnZSBlbmRzLCBhbm90aGVyIGhhbmRsZXIgaXMgY2FsbGVkIHRvIGluc2VydCB0aGUKKy8vIHZhbHVlIGludG8gdGhlIG1hcC4KK3R5cGVkZWYgc3RydWN0IHsKKyAgVkFMVUUgbWFwOworICBjaGFyIGtleV9zdG9yYWdlW05BVElWRV9TTE9UX01BWF9TSVpFXTsKKyAgY2hhciB2YWx1ZV9zdG9yYWdlW05BVElWRV9TTE9UX01BWF9TSVpFXTsKK30gbWFwX3BhcnNlX2ZyYW1lX3Q7CisKKy8vIEhhbmRsZXIgdG8gYmVnaW4gYSBtYXAgZW50cnk6IGFsbG9jYXRlcyBhIHRlbXBvcmFyeSBmcmFtZS4gVGhpcyBpcyB0aGUKKy8vICdzdGFydHN1Ym1zZycgaGFuZGxlciBvbiB0aGUgbXNnZGVmIHRoYXQgY29udGFpbnMgdGhlIG1hcCBmaWVsZC4KK3N0YXRpYyB2b2lkICpzdGFydG1hcGVudHJ5X2hhbmRsZXIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQpIHsKKyAgTWVzc2FnZUhlYWRlciogbXNnID0gY2xvc3VyZTsKKyAgY29uc3QgbWFwX2hhbmRsZXJkYXRhX3QqIG1hcGRhdGEgPSBoZDsKKyAgVkFMVUUgbWFwX3JiID0gREVSRUYobXNnLCBtYXBkYXRhLT5vZnMsIFZBTFVFKTsKKworICBtYXBfcGFyc2VfZnJhbWVfdCogZnJhbWUgPSBBTExPQyhtYXBfcGFyc2VfZnJhbWVfdCk7CisgIGZyYW1lLT5tYXAgPSBtYXBfcmI7CisKKyAgbmF0aXZlX3Nsb3RfaW5pdChtYXBkYXRhLT5rZXlfZmllbGRfdHlwZSwgJmZyYW1lLT5rZXlfc3RvcmFnZSk7CisgIG5hdGl2ZV9zbG90X2luaXQobWFwZGF0YS0+dmFsdWVfZmllbGRfdHlwZSwgJmZyYW1lLT52YWx1ZV9zdG9yYWdlKTsKKworICByZXR1cm4gZnJhbWU7Cit9CisKKy8vIEhhbmRsZXIgdG8gZW5kIGEgbWFwIGVudHJ5OiBpbnNlcnRzIHRoZSB2YWx1ZSBkZWZpbmVkIGR1cmluZyB0aGUgbWVzc2FnZSBpbnRvCisvLyB0aGUgbWFwLiBUaGlzIGlzIHRoZSAnZW5kbXNnJyBoYW5kbGVyIG9uIHRoZSBtYXAgZW50cnkgbXNnZGVmLgorc3RhdGljIGJvb2wgZW5kbWFwX2hhbmRsZXIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIHVwYl9zdGF0dXMqIHMpIHsKKyAgbWFwX3BhcnNlX2ZyYW1lX3QqIGZyYW1lID0gY2xvc3VyZTsKKyAgY29uc3QgbWFwX2hhbmRsZXJkYXRhX3QqIG1hcGRhdGEgPSBoZDsKKworICBWQUxVRSBrZXkgPSBuYXRpdmVfc2xvdF9nZXQoCisgICAgICBtYXBkYXRhLT5rZXlfZmllbGRfdHlwZSwgUW5pbCwKKyAgICAgICZmcmFtZS0+a2V5X3N0b3JhZ2UpOworCisgIFZBTFVFIHZhbHVlX2ZpZWxkX3R5cGVjbGFzcyA9IFFuaWw7CisgIGlmIChtYXBkYXRhLT52YWx1ZV9maWVsZF90eXBlID09IFVQQl9UWVBFX01FU1NBR0UgfHwKKyAgICAgIG1hcGRhdGEtPnZhbHVlX2ZpZWxkX3R5cGUgPT0gVVBCX1RZUEVfRU5VTSkgeworICAgIHZhbHVlX2ZpZWxkX3R5cGVjbGFzcyA9IGdldF9kZWZfb2JqKG1hcGRhdGEtPnZhbHVlX2ZpZWxkX3N1YmRlZik7CisgIH0KKworICBWQUxVRSB2YWx1ZSA9IG5hdGl2ZV9zbG90X2dldCgKKyAgICAgIG1hcGRhdGEtPnZhbHVlX2ZpZWxkX3R5cGUsIHZhbHVlX2ZpZWxkX3R5cGVjbGFzcywKKyAgICAgICZmcmFtZS0+dmFsdWVfc3RvcmFnZSk7CisKKyAgTWFwX2luZGV4X3NldChmcmFtZS0+bWFwLCBrZXksIHZhbHVlKTsKKyAgZnJlZShmcmFtZSk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIEFsbG9jYXRlcyBhIG5ldyBtYXBfaGFuZGxlcmRhdGFfdCBnaXZlbiB0aGUgbWFwIGVudHJ5IG1lc3NhZ2UgZGVmaW5pdGlvbi4gSWYKKy8vIHRoZSBvZmZzZXQgb2YgdGhlIGZpZWxkIHdpdGhpbiB0aGUgcGFyZW50IG1lc3NhZ2UgaXMgYWxzbyBnaXZlbiwgdGhhdCBpcworLy8gYWRkZWQgdG8gdGhlIGhhbmRsZXIgZGF0YSBhcyB3ZWxsLiBOb3RlIHRoYXQgdGhpcyBpcyBjYWxsZWQgKnR3aWNlKiBwZXIgbWFwCisvLyBmaWVsZDogb25jZSBpbiB0aGUgcGFyZW50IG1lc3NhZ2UgaGFuZGxlciBzZXR1cCB3aGVuIHNldHRpbmcgdGhlIHN0YXJ0c3VibXNnCisvLyBoYW5kbGVyIGFuZCBvbmNlIGluIHRoZSBtYXAgZW50cnkgbWVzc2FnZSBoYW5kbGVyIHNldHVwIHdoZW4gc2V0dGluZyB0aGUKKy8vIGtleS92YWx1ZSBhbmQgZW5kbXNnIGhhbmRsZXJzLiBUaGUgcmVhc29uIGlzIHRoYXQgdGhlcmUgaXMgbm8gZWFzeSB3YXkgdG8KKy8vIHBhc3MgdGhlIGhhbmRsZXJkYXRhIGRvd24gdG8gdGhlIHN1Yi1tZXNzYWdlIGhhbmRsZXIgc2V0dXAuCitzdGF0aWMgbWFwX2hhbmRsZXJkYXRhX3QqIG5ld19tYXBfaGFuZGxlcmRhdGEoCisgICAgc2l6ZV90IG9mcywKKyAgICBjb25zdCB1cGJfbXNnZGVmKiBtYXBlbnRyeV9kZWYsCisgICAgRGVzY3JpcHRvciogZGVzYykgeworCisgIG1hcF9oYW5kbGVyZGF0YV90KiBoZCA9IEFMTE9DKG1hcF9oYW5kbGVyZGF0YV90KTsKKyAgaGQtPm9mcyA9IG9mczsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBrZXlfZmllbGQgPSB1cGJfbXNnZGVmX2l0b2YobWFwZW50cnlfZGVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVBfS0VZX0ZJRUxEKTsKKyAgYXNzZXJ0KGtleV9maWVsZCAhPSBOVUxMKTsKKyAgaGQtPmtleV9maWVsZF90eXBlID0gdXBiX2ZpZWxkZGVmX3R5cGUoa2V5X2ZpZWxkKTsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiB2YWx1ZV9maWVsZCA9IHVwYl9tc2dkZWZfaXRvZihtYXBlbnRyeV9kZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFQX1ZBTFVFX0ZJRUxEKTsKKyAgYXNzZXJ0KHZhbHVlX2ZpZWxkICE9IE5VTEwpOworICBoZC0+dmFsdWVfZmllbGRfdHlwZSA9IHVwYl9maWVsZGRlZl90eXBlKHZhbHVlX2ZpZWxkKTsKKyAgaGQtPnZhbHVlX2ZpZWxkX3N1YmRlZiA9IHVwYl9maWVsZGRlZl9zdWJkZWYodmFsdWVfZmllbGQpOworCisgIHJldHVybiBoZDsKK30KKworLy8gSGFuZGxlcnMgdGhhdCBzZXQgcHJpbWl0aXZlIHZhbHVlcyBpbiBvbmVvZnMuCisjZGVmaW5lIERFRklORV9PTkVPRl9IQU5ETEVSKHR5cGUsIGN0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgb25lb2YjI3R5cGUjI19oYW5kbGVyKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkLCAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eXBlIHZhbCkgeyAgICAgICAgICAgICAgICAgICBcCisgICAgY29uc3Qgb25lb2ZfaGFuZGxlcmRhdGFfdCAqb25lb2ZkYXRhID0gaGQ7ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBERVJFRihjbG9zdXJlLCBvbmVvZmRhdGEtPmNhc2Vfb2ZzLCB1aW50MzJfdCkgPSAgICAgICAgICAgICAgICAgXAorICAgICAgICBvbmVvZmRhdGEtPm9uZW9mX2Nhc2VfbnVtOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgREVSRUYoY2xvc3VyZSwgb25lb2ZkYXRhLT5vZnMsIGN0eXBlKSA9IHZhbDsgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0RFRklORV9PTkVPRl9IQU5ETEVSKGJvb2wsICAgYm9vbCkKK0RFRklORV9PTkVPRl9IQU5ETEVSKGludDMyLCAgaW50MzJfdCkKK0RFRklORV9PTkVPRl9IQU5ETEVSKHVpbnQzMiwgdWludDMyX3QpCitERUZJTkVfT05FT0ZfSEFORExFUihmbG9hdCwgIGZsb2F0KQorREVGSU5FX09ORU9GX0hBTkRMRVIoaW50NjQsICBpbnQ2NF90KQorREVGSU5FX09ORU9GX0hBTkRMRVIodWludDY0LCB1aW50NjRfdCkKK0RFRklORV9PTkVPRl9IQU5ETEVSKGRvdWJsZSwgZG91YmxlKQorCisjdW5kZWYgREVGSU5FX09ORU9GX0hBTkRMRVIKKworLy8gSGFuZGxlcnMgZm9yIHN0cmluZ3MgaW4gYSBvbmVvZi4KK3N0YXRpYyB2b2lkICpvbmVvZnN0cl9oYW5kbGVyKHZvaWQgKmNsb3N1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpoZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplX2hpbnQpIHsKKyAgTWVzc2FnZUhlYWRlciogbXNnID0gY2xvc3VyZTsKKyAgY29uc3Qgb25lb2ZfaGFuZGxlcmRhdGFfdCAqb25lb2ZkYXRhID0gaGQ7CisgIFZBTFVFIHN0ciA9IHJiX3N0cl9uZXcyKCIiKTsKKyAgcmJfZW5jX2Fzc29jaWF0ZShzdHIsIGtSdWJ5U3RyaW5nVXRmOEVuY29kaW5nKTsKKyAgREVSRUYobXNnLCBvbmVvZmRhdGEtPmNhc2Vfb2ZzLCB1aW50MzJfdCkgPQorICAgICAgb25lb2ZkYXRhLT5vbmVvZl9jYXNlX251bTsKKyAgREVSRUYobXNnLCBvbmVvZmRhdGEtPm9mcywgVkFMVUUpID0gc3RyOworICByZXR1cm4gKHZvaWQqKXN0cjsKK30KKworc3RhdGljIHZvaWQgKm9uZW9mYnl0ZXNfaGFuZGxlcih2b2lkICpjbG9zdXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpoZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemVfaGludCkgeworICBNZXNzYWdlSGVhZGVyKiBtc2cgPSBjbG9zdXJlOworICBjb25zdCBvbmVvZl9oYW5kbGVyZGF0YV90ICpvbmVvZmRhdGEgPSBoZDsKKyAgVkFMVUUgc3RyID0gcmJfc3RyX25ldzIoIiIpOworICByYl9lbmNfYXNzb2NpYXRlKHN0ciwga1J1YnlTdHJpbmc4Yml0RW5jb2RpbmcpOworICBERVJFRihtc2csIG9uZW9mZGF0YS0+Y2FzZV9vZnMsIHVpbnQzMl90KSA9CisgICAgICBvbmVvZmRhdGEtPm9uZW9mX2Nhc2VfbnVtOworICBERVJFRihtc2csIG9uZW9mZGF0YS0+b2ZzLCBWQUxVRSkgPSBzdHI7CisgIHJldHVybiAodm9pZCopc3RyOworfQorCisvLyBIYW5kbGVyIGZvciBhIHN1Ym1lc3NhZ2UgZmllbGQgaW4gYSBvbmVvZi4KK3N0YXRpYyB2b2lkICpvbmVvZnN1Ym1zZ19oYW5kbGVyKHZvaWQgKmNsb3N1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpoZCkgeworICBNZXNzYWdlSGVhZGVyKiBtc2cgPSBjbG9zdXJlOworICBjb25zdCBvbmVvZl9oYW5kbGVyZGF0YV90ICpvbmVvZmRhdGEgPSBoZDsKKyAgdWludDMyX3Qgb2xkY2FzZSA9IERFUkVGKG1zZywgb25lb2ZkYXRhLT5jYXNlX29mcywgdWludDMyX3QpOworCisgIFZBTFVFIHN1YmRlc2MgPQorICAgICAgZ2V0X2RlZl9vYmooKHZvaWQqKW9uZW9mZGF0YS0+bWQpOworICBWQUxVRSBzdWJrbGFzcyA9IERlc2NyaXB0b3JfbXNnY2xhc3Moc3ViZGVzYyk7CisKKyAgaWYgKG9sZGNhc2UgIT0gb25lb2ZkYXRhLT5vbmVvZl9jYXNlX251bSB8fAorICAgICAgREVSRUYobXNnLCBvbmVvZmRhdGEtPm9mcywgVkFMVUUpID09IFFuaWwpIHsKKyAgICBERVJFRihtc2csIG9uZW9mZGF0YS0+b2ZzLCBWQUxVRSkgPQorICAgICAgICByYl9jbGFzc19uZXdfaW5zdGFuY2UoMCwgTlVMTCwgc3Via2xhc3MpOworICB9CisgIC8vIFNldCB0aGUgb25lb2YgY2FzZSAqYWZ0ZXIqIGFsbG9jYXRpbmcgdGhlIG5ldyBjbGFzcyBpbnN0YW5jZSAtLSBvdGhlcndpc2UsCisgIC8vIGlmIHRoZSBSdWJ5IEdDIGlzIGludm9rZWQgYXMgcGFydCBvZiBhIGNhbGwgaW50byB0aGUgVk0sIGl0IG1pZ2h0IGludm9rZQorICAvLyBvdXIgbWFyayByb3V0aW5lcywgYW5kIG91ciBtYXJrIHJvdXRpbmVzIG1pZ2h0IHNlZSB0aGUgY2FzZSB2YWx1ZQorICAvLyBpbmRpY2F0aW5nIGEgVkFMVUUgaXMgcHJlc2VudCBhbmQgZXhwZWN0IGEgdmFsaWQgVkFMVUUuIFNlZSBjb21tZW50IGluCisgIC8vIGxheW91dF9zZXQoKSBmb3IgbW9yZSBkZXRhaWw6IGJhc2ljYWxseSwgdGhlIGNoYW5nZSB0byB0aGUgdmFsdWUgYW5kIHRoZQorICAvLyBjYXNlIG11c3QgYmUgYXRvbWljIHcuci50LiB0aGUgUnVieSBWTS4KKyAgREVSRUYobXNnLCBvbmVvZmRhdGEtPmNhc2Vfb2ZzLCB1aW50MzJfdCkgPQorICAgICAgb25lb2ZkYXRhLT5vbmVvZl9jYXNlX251bTsKKworICBWQUxVRSBzdWJtc2dfcmIgPSBERVJFRihtc2csIG9uZW9mZGF0YS0+b2ZzLCBWQUxVRSk7CisgIE1lc3NhZ2VIZWFkZXIqIHN1Ym1zZzsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3Qoc3VibXNnX3JiLCBNZXNzYWdlSGVhZGVyLCAmTWVzc2FnZV90eXBlLCBzdWJtc2cpOworICByZXR1cm4gc3VibXNnOworfQorCisvLyBTZXQgdXAgaGFuZGxlcnMgZm9yIGEgcmVwZWF0ZWQgZmllbGQuCitzdGF0aWMgdm9pZCBhZGRfaGFuZGxlcnNfZm9yX3JlcGVhdGVkX2ZpZWxkKHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgb2Zmc2V0KSB7CisgIHVwYl9oYW5kbGVyYXR0ciBhdHRyID0gVVBCX0hBTkRMRVJBVFRSX0lOSVRJQUxJWkVSOworICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoJmF0dHIsIG5ld2hhbmRsZXJkYXRhKGgsIG9mZnNldCkpOworICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzZXEoaCwgZiwgc3RhcnRzZXFfaGFuZGxlciwgJmF0dHIpOworICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZhdHRyKTsKKworICBzd2l0Y2ggKHVwYl9maWVsZGRlZl90eXBlKGYpKSB7CisKKyNkZWZpbmUgU0VUX0hBTkRMRVIodXR5cGUsIGx0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2FzZSB1dHlwZTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB1cGJfaGFuZGxlcnNfc2V0IyNsdHlwZShoLCBmLCBhcHBlbmQjI2x0eXBlIyNfaGFuZGxlciwgTlVMTCk7IFwKKyAgICBicmVhazsKKworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX0JPT0wsICAgYm9vbCk7CisgICAgU0VUX0hBTkRMRVIoVVBCX1RZUEVfSU5UMzIsICBpbnQzMik7CisgICAgU0VUX0hBTkRMRVIoVVBCX1RZUEVfVUlOVDMyLCB1aW50MzIpOworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX0VOVU0sICAgaW50MzIpOworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX0ZMT0FULCAgZmxvYXQpOworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX0lOVDY0LCAgaW50NjQpOworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX1VJTlQ2NCwgdWludDY0KTsKKyAgICBTRVRfSEFORExFUihVUEJfVFlQRV9ET1VCTEUsIGRvdWJsZSk7CisKKyN1bmRlZiBTRVRfSEFORExFUgorCisgICAgY2FzZSBVUEJfVFlQRV9TVFJJTkc6CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzogeworICAgICAgYm9vbCBpc19ieXRlcyA9IHVwYl9maWVsZGRlZl90eXBlKGYpID09IFVQQl9UWVBFX0JZVEVTOworICAgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c3RyKGgsIGYsIGlzX2J5dGVzID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRieXRlc19oYW5kbGVyIDogYXBwZW5kc3RyX2hhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKGgsIGYsIHN0cmluZ2RhdGFfaGFuZGxlciwgTlVMTCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9NRVNTQUdFOiB7CisgICAgICB1cGJfaGFuZGxlcmF0dHIgYXR0ciA9IFVQQl9IQU5ETEVSQVRUUl9JTklUSUFMSVpFUjsKKyAgICAgIHVwYl9oYW5kbGVyYXR0cl9zZXRoYW5kbGVyZGF0YSgmYXR0ciwgbmV3c3VibXNnaGFuZGxlcmRhdGEoaCwgMCwgZikpOworICAgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c3VibXNnKGgsIGYsIGFwcGVuZHN1Ym1zZ19oYW5kbGVyLCAmYXR0cik7CisgICAgICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZhdHRyKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCisvLyBTZXQgdXAgaGFuZGxlcnMgZm9yIGEgc2luZ3VsYXIgZmllbGQuCitzdGF0aWMgdm9pZCBhZGRfaGFuZGxlcnNfZm9yX3Npbmd1bGFyX2ZpZWxkKHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgb2Zmc2V0KSB7CisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUoZikpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0JPT0w6CisgICAgY2FzZSBVUEJfVFlQRV9JTlQzMjoKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjoKKyAgICBjYXNlIFVQQl9UWVBFX0VOVU06CisgICAgY2FzZSBVUEJfVFlQRV9GTE9BVDoKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDY0OgorICAgIGNhc2UgVVBCX1RZUEVfVUlOVDY0OgorICAgIGNhc2UgVVBCX1RZUEVfRE9VQkxFOgorICAgICAgdXBiX3NoaW1fc2V0KGgsIGYsIG9mZnNldCwgLTEpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9TVFJJTkc6CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzogeworICAgICAgYm9vbCBpc19ieXRlcyA9IHVwYl9maWVsZGRlZl90eXBlKGYpID09IFVQQl9UWVBFX0JZVEVTOworICAgICAgdXBiX2hhbmRsZXJhdHRyIGF0dHIgPSBVUEJfSEFORExFUkFUVFJfSU5JVElBTElaRVI7CisgICAgICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoJmF0dHIsIG5ld2hhbmRsZXJkYXRhKGgsIG9mZnNldCkpOworICAgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c3RyKGgsIGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfYnl0ZXMgPyBieXRlc19oYW5kbGVyIDogc3RyX2hhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dHIpOworICAgICAgdXBiX2hhbmRsZXJzX3NldHN0cmluZyhoLCBmLCBzdHJpbmdkYXRhX2hhbmRsZXIsICZhdHRyKTsKKyAgICAgIHVwYl9oYW5kbGVyYXR0cl91bmluaXQoJmF0dHIpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRTogeworICAgICAgdXBiX2hhbmRsZXJhdHRyIGF0dHIgPSBVUEJfSEFORExFUkFUVFJfSU5JVElBTElaRVI7CisgICAgICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoJmF0dHIsIG5ld3N1Ym1zZ2hhbmRsZXJkYXRhKGgsIG9mZnNldCwgZikpOworICAgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c3VibXNnKGgsIGYsIHN1Ym1zZ19oYW5kbGVyLCAmYXR0cik7CisgICAgICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZhdHRyKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCisvLyBBZGRzIGhhbmRsZXJzIHRvIGEgbWFwIGZpZWxkLgorc3RhdGljIHZvaWQgYWRkX2hhbmRsZXJzX2Zvcl9tYXBmaWVsZCh1cGJfaGFuZGxlcnMqIGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGRkZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgY29uc3QgdXBiX21zZ2RlZiogbWFwX21zZ2RlZiA9IHVwYl9maWVsZGRlZl9tc2dzdWJkZWYoZmllbGRkZWYpOworICBtYXBfaGFuZGxlcmRhdGFfdCogaGQgPSBuZXdfbWFwX2hhbmRsZXJkYXRhKG9mZnNldCwgbWFwX21zZ2RlZiwgZGVzYyk7CisgIHVwYl9oYW5kbGVyc19hZGRjbGVhbnVwKGgsIGhkLCBmcmVlKTsKKyAgdXBiX2hhbmRsZXJhdHRyIGF0dHIgPSBVUEJfSEFORExFUkFUVFJfSU5JVElBTElaRVI7CisgIHVwYl9oYW5kbGVyYXR0cl9zZXRoYW5kbGVyZGF0YSgmYXR0ciwgaGQpOworICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdWJtc2coaCwgZmllbGRkZWYsIHN0YXJ0bWFwZW50cnlfaGFuZGxlciwgJmF0dHIpOworICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZhdHRyKTsKK30KKworLy8gQWRkcyBoYW5kbGVycyB0byBhIG1hcC1lbnRyeSBtc2dkZWYuCitzdGF0aWMgdm9pZCBhZGRfaGFuZGxlcnNfZm9yX21hcGVudHJ5KGNvbnN0IHVwYl9tc2dkZWYqIG1zZ2RlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJzKiBoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yKiBkZXNjKSB7CisgIGNvbnN0IHVwYl9maWVsZGRlZioga2V5X2ZpZWxkID0gbWFwX2VudHJ5X2tleShtc2dkZWYpOworICBjb25zdCB1cGJfZmllbGRkZWYqIHZhbHVlX2ZpZWxkID0gbWFwX2VudHJ5X3ZhbHVlKG1zZ2RlZik7CisgIG1hcF9oYW5kbGVyZGF0YV90KiBoZCA9IG5ld19tYXBfaGFuZGxlcmRhdGEoMCwgbXNnZGVmLCBkZXNjKTsKKyAgdXBiX2hhbmRsZXJzX2FkZGNsZWFudXAoaCwgaGQsIGZyZWUpOworICB1cGJfaGFuZGxlcmF0dHIgYXR0ciA9IFVQQl9IQU5ETEVSQVRUUl9JTklUSUFMSVpFUjsKKyAgdXBiX2hhbmRsZXJhdHRyX3NldGhhbmRsZXJkYXRhKCZhdHRyLCBoZCk7CisgIHVwYl9oYW5kbGVyc19zZXRlbmRtc2coaCwgZW5kbWFwX2hhbmRsZXIsICZhdHRyKTsKKworICBhZGRfaGFuZGxlcnNfZm9yX3Npbmd1bGFyX2ZpZWxkKAorICAgICAgaCwga2V5X2ZpZWxkLAorICAgICAgb2Zmc2V0b2YobWFwX3BhcnNlX2ZyYW1lX3QsIGtleV9zdG9yYWdlKSk7CisgIGFkZF9oYW5kbGVyc19mb3Jfc2luZ3VsYXJfZmllbGQoCisgICAgICBoLCB2YWx1ZV9maWVsZCwKKyAgICAgIG9mZnNldG9mKG1hcF9wYXJzZV9mcmFtZV90LCB2YWx1ZV9zdG9yYWdlKSk7Cit9CisKKy8vIFNldCB1cCBoYW5kbGVycyBmb3IgYSBvbmVvZiBmaWVsZC4KK3N0YXRpYyB2b2lkIGFkZF9oYW5kbGVyc19mb3Jfb25lb2ZfZmllbGQodXBiX2hhbmRsZXJzICpoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBvbmVvZl9jYXNlX29mZnNldCkgeworCisgIHVwYl9oYW5kbGVyYXR0ciBhdHRyID0gVVBCX0hBTkRMRVJBVFRSX0lOSVRJQUxJWkVSOworICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoCisgICAgICAmYXR0ciwgbmV3b25lb2ZoYW5kbGVyZGF0YShoLCBvZmZzZXQsIG9uZW9mX2Nhc2Vfb2Zmc2V0LCBmKSk7CisKKyAgc3dpdGNoICh1cGJfZmllbGRkZWZfdHlwZShmKSkgeworCisjZGVmaW5lIFNFVF9IQU5ETEVSKHV0eXBlLCBsdHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNhc2UgdXR5cGU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdXBiX2hhbmRsZXJzX3NldCMjbHR5cGUoaCwgZiwgb25lb2YjI2x0eXBlIyNfaGFuZGxlciwgJmF0dHIpOyBcCisgICAgYnJlYWs7CisKKyAgICBTRVRfSEFORExFUihVUEJfVFlQRV9CT09MLCAgIGJvb2wpOworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX0lOVDMyLCAgaW50MzIpOworICAgIFNFVF9IQU5ETEVSKFVQQl9UWVBFX1VJTlQzMiwgdWludDMyKTsKKyAgICBTRVRfSEFORExFUihVUEJfVFlQRV9FTlVNLCAgIGludDMyKTsKKyAgICBTRVRfSEFORExFUihVUEJfVFlQRV9GTE9BVCwgIGZsb2F0KTsKKyAgICBTRVRfSEFORExFUihVUEJfVFlQRV9JTlQ2NCwgIGludDY0KTsKKyAgICBTRVRfSEFORExFUihVUEJfVFlQRV9VSU5UNjQsIHVpbnQ2NCk7CisgICAgU0VUX0hBTkRMRVIoVVBCX1RZUEVfRE9VQkxFLCBkb3VibGUpOworCisjdW5kZWYgU0VUX0hBTkRMRVIKKworICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOgorICAgIGNhc2UgVVBCX1RZUEVfQllURVM6IHsKKyAgICAgIGJvb2wgaXNfYnl0ZXMgPSB1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9CWVRFUzsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHN0cihoLCBmLCBpc19ieXRlcyA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lb2ZieXRlc19oYW5kbGVyIDogb25lb2ZzdHJfaGFuZGxlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0cik7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKGgsIGYsIHN0cmluZ2RhdGFfaGFuZGxlciwgTlVMTCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9NRVNTQUdFOiB7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdWJtc2coaCwgZiwgb25lb2ZzdWJtc2dfaGFuZGxlciwgJmF0dHIpOworICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgdXBiX2hhbmRsZXJhdHRyX3VuaW5pdCgmYXR0cik7Cit9CisKKworc3RhdGljIHZvaWQgYWRkX2hhbmRsZXJzX2Zvcl9tZXNzYWdlKGNvbnN0IHZvaWQgKmNsb3N1cmUsIHVwYl9oYW5kbGVycyAqaCkgeworICBjb25zdCB1cGJfbXNnZGVmKiBtc2dkZWYgPSB1cGJfaGFuZGxlcnNfbXNnZGVmKGgpOworICBEZXNjcmlwdG9yKiBkZXNjID0gcnVieV90b19EZXNjcmlwdG9yKGdldF9kZWZfb2JqKCh2b2lkKiltc2dkZWYpKTsKKworICAvLyBJZiB0aGlzIGlzIGEgbWFwZW50cnkgbWVzc2FnZSB0eXBlLCBzZXQgdXAgYSBzcGVjaWFsIHNldCBvZiBoYW5kbGVycyBhbmQKKyAgLy8gYmFpbCBvdXQgb2YgdGhlIG5vcm1hbCAodXNlci1kZWZpbmVkKSBtZXNzYWdlIHR5cGUgaGFuZGxpbmcuCisgIGlmICh1cGJfbXNnZGVmX21hcGVudHJ5KG1zZ2RlZikpIHsKKyAgICBhZGRfaGFuZGxlcnNfZm9yX21hcGVudHJ5KG1zZ2RlZiwgaCwgZGVzYyk7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gRW5zdXJlIGxheW91dCBleGlzdHMuIFdlIG1heSBiZSBpbnZva2VkIHRvIGNyZWF0ZSBoYW5kbGVycyBmb3IgYSBnaXZlbgorICAvLyBtZXNzYWdlIGlmIHdlIGFyZSBpbmNsdWRlZCBhcyBhIHN1Ym1zZyBvZiBhbm90aGVyIG1lc3NhZ2UgdHlwZSBiZWZvcmUgb3VyCisgIC8vIGNsYXNzIGlzIGFjdHVhbGx5IGJ1aWx0LCBzbyB0byB3b3JrIGFyb3VuZCB0aGlzLCB3ZSBqdXN0IGNyZWF0ZSB0aGUgbGF5b3V0CisgIC8vIChhbmQgaGFuZGxlcnMsIGluIHRoZSBjbGFzcy1idWlsZGluZyBmdW5jdGlvbikgb24tZGVtYW5kLgorICBpZiAoZGVzYy0+bGF5b3V0ID09IE5VTEwpIHsKKyAgICBkZXNjLT5sYXlvdXQgPSBjcmVhdGVfbGF5b3V0KGRlc2MtPm1zZ2RlZik7CisgIH0KKworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgZm9yICh1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpLCBkZXNjLT5tc2dkZWYpOworICAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmkpOworICAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaSkpIHsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJmkpOworICAgIHNpemVfdCBvZmZzZXQgPSBkZXNjLT5sYXlvdXQtPmZpZWxkc1t1cGJfZmllbGRkZWZfaW5kZXgoZildLm9mZnNldCArCisgICAgICAgIHNpemVvZihNZXNzYWdlSGVhZGVyKTsKKworICAgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGYpKSB7CisgICAgICBzaXplX3Qgb25lb2ZfY2FzZV9vZmZzZXQgPQorICAgICAgICAgIGRlc2MtPmxheW91dC0+ZmllbGRzW3VwYl9maWVsZGRlZl9pbmRleChmKV0uY2FzZV9vZmZzZXQgKworICAgICAgICAgIHNpemVvZihNZXNzYWdlSGVhZGVyKTsKKyAgICAgIGFkZF9oYW5kbGVyc19mb3Jfb25lb2ZfZmllbGQoaCwgZiwgb2Zmc2V0LCBvbmVvZl9jYXNlX29mZnNldCk7CisgICAgfSBlbHNlIGlmIChpc19tYXBfZmllbGQoZikpIHsKKyAgICAgIGFkZF9oYW5kbGVyc19mb3JfbWFwZmllbGQoaCwgZiwgb2Zmc2V0LCBkZXNjKTsKKyAgICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSkgeworICAgICAgYWRkX2hhbmRsZXJzX2Zvcl9yZXBlYXRlZF9maWVsZChoLCBmLCBvZmZzZXQpOworICAgIH0gZWxzZSB7CisgICAgICBhZGRfaGFuZGxlcnNfZm9yX3Npbmd1bGFyX2ZpZWxkKGgsIGYsIG9mZnNldCk7CisgICAgfQorICB9Cit9CisKKy8vIENyZWF0ZXMgdXBiIGhhbmRsZXJzIGZvciBwb3B1bGF0aW5nIGEgbWVzc2FnZS4KK3N0YXRpYyBjb25zdCB1cGJfaGFuZGxlcnMgKm5ld19maWxsX2hhbmRsZXJzKERlc2NyaXB0b3IqIGRlc2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBvd25lcikgeworICAvLyBUT0RPKGNmYWxsaW4sIGhhYmVybWFuKTogb25jZSB1cGIgZ2V0cyBhIGNhY2hpbmcvbWVtb2l6YXRpb24gbGF5ZXIgZm9yCisgIC8vIGhhbmRsZXJzLCByZXVzZSBzdWJkZWYgaGFuZGxlcnMgc28gdGhhdCBlLmcuIGlmIHdlIGFscmVhZHkgcGFyc2UKKyAgLy8gQi13aXRoLWZpZWxkLW9mLXR5cGUtQywgd2UgZG9uJ3QgaGF2ZSB0byByZWJ1aWxkIHRoZSB3aG9sZSBoaWVyYXJjaHkgdG8KKyAgLy8gcGFyc2UgQS13aXRoLWZpZWxkLW9mLXR5cGUtQi13aXRoLWZpZWxkLW9mLXR5cGUtQy4KKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19uZXdmcm96ZW4oZGVzYy0+bXNnZGVmLCBvd25lciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX2hhbmRsZXJzX2Zvcl9tZXNzYWdlLCBOVUxMKTsKK30KKworLy8gQ29uc3RydWN0cyB0aGUgaGFuZGxlcnMgZm9yIGZpbGxpbmcgYSBtZXNzYWdlJ3MgZGF0YSBpbnRvIGFuIGluLW1lbW9yeQorLy8gb2JqZWN0LgorY29uc3QgdXBiX2hhbmRsZXJzKiBnZXRfZmlsbF9oYW5kbGVycyhEZXNjcmlwdG9yKiBkZXNjKSB7CisgIGlmICghZGVzYy0+ZmlsbF9oYW5kbGVycykgeworICAgIGRlc2MtPmZpbGxfaGFuZGxlcnMgPQorICAgICAgICBuZXdfZmlsbF9oYW5kbGVycyhkZXNjLCAmZGVzYy0+ZmlsbF9oYW5kbGVycyk7CisgIH0KKyAgcmV0dXJuIGRlc2MtPmZpbGxfaGFuZGxlcnM7Cit9CisKKy8vIENvbnN0cnVjdHMgdGhlIHVwYiBkZWNvZGVyIG1ldGhvZCBmb3IgcGFyc2luZyBtZXNzYWdlcyBvZiB0aGlzIHR5cGUuCisvLyBUaGlzIGlzIGNhbGxlZCBmcm9tIHRoZSBtZXNzYWdlIGNsYXNzIGNyZWF0aW9uIGNvZGUuCitjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICpuZXdfZmlsbG1zZ19kZWNvZGVybWV0aG9kKERlc2NyaXB0b3IqIGRlc2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIG93bmVyKSB7CisgIGNvbnN0IHVwYl9oYW5kbGVycyogaGFuZGxlcnMgPSBnZXRfZmlsbF9oYW5kbGVycyhkZXNjKTsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHMgb3B0czsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfaW5pdCgmb3B0cywgaGFuZGxlcnMpOworCisgIGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKnJldCA9IHVwYl9wYmRlY29kZXJtZXRob2RfbmV3KCZvcHRzLCBvd25lcik7CisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptc2dkZWZfZGVjb2Rlcm1ldGhvZChEZXNjcmlwdG9yKiBkZXNjKSB7CisgIGlmIChkZXNjLT5maWxsX21ldGhvZCA9PSBOVUxMKSB7CisgICAgZGVzYy0+ZmlsbF9tZXRob2QgPSBuZXdfZmlsbG1zZ19kZWNvZGVybWV0aG9kKAorICAgICAgICBkZXNjLCAmZGVzYy0+ZmlsbF9tZXRob2QpOworICB9CisgIHJldHVybiBkZXNjLT5maWxsX21ldGhvZDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2VDbGFzcy5kZWNvZGUoZGF0YSkgPT4gbWVzc2FnZQorICoKKyAqIERlY29kZXMgdGhlIGdpdmVuIGRhdGEgKGFzIGEgc3RyaW5nIGNvbnRhaW5pbmcgYnl0ZXMgaW4gcHJvdG9jb2wgYnVmZmVycyB3aXJlCisgKiBmb3JtYXQpIHVuZGVyIHRoZSBpbnRlcnByZXRyYXRpb24gZ2l2ZW4gYnkgdGhpcyBtZXNzYWdlIGNsYXNzJ3MgZGVmaW5pdGlvbgorICogYW5kIHJldHVybnMgYSBtZXNzYWdlIG9iamVjdCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIHZhbHVlcy4KKyAqLworVkFMVUUgTWVzc2FnZV9kZWNvZGUoVkFMVUUga2xhc3MsIFZBTFVFIGRhdGEpIHsKKyAgVkFMVUUgZGVzY3JpcHRvciA9IHJiX2l2X2dldChrbGFzcywga0Rlc2NyaXB0b3JJbnN0YW5jZVZhcik7CisgIERlc2NyaXB0b3IqIGRlc2MgPSBydWJ5X3RvX0Rlc2NyaXB0b3IoZGVzY3JpcHRvcik7CisgIFZBTFVFIG1zZ2tsYXNzID0gRGVzY3JpcHRvcl9tc2djbGFzcyhkZXNjcmlwdG9yKTsKKworICBpZiAoVFlQRShkYXRhKSAhPSBUX1NUUklORykgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIHN0cmluZyBmb3IgYmluYXJ5IHByb3RvYnVmIGRhdGEuIik7CisgIH0KKworICBWQUxVRSBtc2dfcmIgPSByYl9jbGFzc19uZXdfaW5zdGFuY2UoMCwgTlVMTCwgbXNna2xhc3MpOworICBNZXNzYWdlSGVhZGVyKiBtc2c7CisgIFR5cGVkRGF0YV9HZXRfU3RydWN0KG1zZ19yYiwgTWVzc2FnZUhlYWRlciwgJk1lc3NhZ2VfdHlwZSwgbXNnKTsKKworICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kKiBtZXRob2QgPSBtc2dkZWZfZGVjb2Rlcm1ldGhvZChkZXNjKTsKKyAgY29uc3QgdXBiX2hhbmRsZXJzKiBoID0gdXBiX3BiZGVjb2Rlcm1ldGhvZF9kZXN0aGFuZGxlcnMobWV0aG9kKTsKKyAgdXBiX3BiZGVjb2RlciBkZWNvZGVyOworICB1cGJfc2luayBzaW5rOworICB1cGJfc3RhdHVzIHN0YXR1cyA9IFVQQl9TVEFUVVNfSU5JVDsKKworICB1cGJfcGJkZWNvZGVyX2luaXQoJmRlY29kZXIsIG1ldGhvZCwgJnN0YXR1cyk7CisgIHVwYl9zaW5rX3Jlc2V0KCZzaW5rLCBoLCBtc2cpOworICB1cGJfcGJkZWNvZGVyX3Jlc2V0b3V0cHV0KCZkZWNvZGVyLCAmc2luayk7CisgIHVwYl9idWZzcmNfcHV0YnVmKFJTVFJJTkdfUFRSKGRhdGEpLCBSU1RSSU5HX0xFTihkYXRhKSwKKyAgICAgICAgICAgICAgICAgICAgdXBiX3BiZGVjb2Rlcl9pbnB1dCgmZGVjb2RlcikpOworCisgIHVwYl9wYmRlY29kZXJfdW5pbml0KCZkZWNvZGVyKTsKKyAgaWYgKCF1cGJfb2soJnN0YXR1cykpIHsKKyAgICByYl9yYWlzZShyYl9lUnVudGltZUVycm9yLCAiRXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmc6ICVzLiIsCisgICAgICAgICAgICAgdXBiX3N0YXR1c19lcnJtc2coJnN0YXR1cykpOworICB9CisKKyAgcmV0dXJuIG1zZ19yYjsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2VDbGFzcy5kZWNvZGVfanNvbihkYXRhKSA9PiBtZXNzYWdlCisgKgorICogRGVjb2RlcyB0aGUgZ2l2ZW4gZGF0YSAoYXMgYSBzdHJpbmcgY29udGFpbmluZyBieXRlcyBpbiBwcm90b2NvbCBidWZmZXJzIHdpcmUKKyAqIGZvcm1hdCkgdW5kZXIgdGhlIGludGVycHJldHJhdGlvbiBnaXZlbiBieSB0aGlzIG1lc3NhZ2UgY2xhc3MncyBkZWZpbml0aW9uCisgKiBhbmQgcmV0dXJucyBhIG1lc3NhZ2Ugb2JqZWN0IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgdmFsdWVzLgorICovCitWQUxVRSBNZXNzYWdlX2RlY29kZV9qc29uKFZBTFVFIGtsYXNzLCBWQUxVRSBkYXRhKSB7CisgIFZBTFVFIGRlc2NyaXB0b3IgPSByYl9pdl9nZXQoa2xhc3MsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIpOworICBEZXNjcmlwdG9yKiBkZXNjID0gcnVieV90b19EZXNjcmlwdG9yKGRlc2NyaXB0b3IpOworICBWQUxVRSBtc2drbGFzcyA9IERlc2NyaXB0b3JfbXNnY2xhc3MoZGVzY3JpcHRvcik7CisKKyAgaWYgKFRZUEUoZGF0YSkgIT0gVF9TVFJJTkcpIHsKKyAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsICJFeHBlY3RlZCBzdHJpbmcgZm9yIEpTT04gZGF0YS4iKTsKKyAgfQorICAvLyBUT0RPKGNmYWxsaW4pOiBDaGVjayBhbmQgcmVzcGVjdCBzdHJpbmcgZW5jb2RpbmcuIElmIG5vdCBVVEYtOCwgd2UgbmVlZCB0bworICAvLyBjb252ZXJ0LCBiZWNhdXNlIHN0cmluZyBoYW5kbGVycyBwYXNzIGRhdGEgZGlyZWN0bHkgdG8gbWVzc2FnZSBzdHJpbmcKKyAgLy8gZmllbGRzLgorCisgIFZBTFVFIG1zZ19yYiA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBtc2drbGFzcyk7CisgIE1lc3NhZ2VIZWFkZXIqIG1zZzsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QobXNnX3JiLCBNZXNzYWdlSGVhZGVyLCAmTWVzc2FnZV90eXBlLCBtc2cpOworCisgIHVwYl9zdGF0dXMgc3RhdHVzID0gVVBCX1NUQVRVU19JTklUOworICB1cGJfanNvbl9wYXJzZXIgcGFyc2VyOworICB1cGJfanNvbl9wYXJzZXJfaW5pdCgmcGFyc2VyLCAmc3RhdHVzKTsKKworICB1cGJfc2luayBzaW5rOworICB1cGJfc2lua19yZXNldCgmc2luaywgZ2V0X2ZpbGxfaGFuZGxlcnMoZGVzYyksIG1zZyk7CisgIHVwYl9qc29uX3BhcnNlcl9yZXNldG91dHB1dCgmcGFyc2VyLCAmc2luayk7CisgIHVwYl9idWZzcmNfcHV0YnVmKFJTVFJJTkdfUFRSKGRhdGEpLCBSU1RSSU5HX0xFTihkYXRhKSwKKyAgICAgICAgICAgICAgICAgICAgdXBiX2pzb25fcGFyc2VyX2lucHV0KCZwYXJzZXIpKTsKKworICB1cGJfanNvbl9wYXJzZXJfdW5pbml0KCZwYXJzZXIpOworICBpZiAoIXVwYl9vaygmc3RhdHVzKSkgeworICAgIHJiX3JhaXNlKHJiX2VSdW50aW1lRXJyb3IsICJFcnJvciBvY2N1cnJlZCBkdXJpbmcgcGFyc2luZzogJXMuIiwKKyAgICAgICAgICAgICB1cGJfc3RhdHVzX2Vycm1zZygmc3RhdHVzKSk7CisgIH0KKworICByZXR1cm4gbXNnX3JiOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU2VyaWFsaXppbmcuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vIFRoZSBjb2RlIGJlbG93IGFsc28gY29tZXMgZnJvbSB1cGIncyBwcm90b3R5cGUgUnVieSBiaW5kaW5nLCBkZXZlbG9wZWQgYnkKKy8vIGhhYmVybWFuQC4KKworLyogc3RyaW5nc2luayAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gVGhpcyBzaG91bGQgcHJvYmFibHkgYmUgZmFjdG9yZWQgaW50byBhIGNvbW1vbiB1cGIgY29tcG9uZW50LgorCit0eXBlZGVmIHN0cnVjdCB7CisgIHVwYl9ieXRlc2hhbmRsZXIgaGFuZGxlcjsKKyAgdXBiX2J5dGVzc2luayBzaW5rOworICBjaGFyICpwdHI7CisgIHNpemVfdCBsZW4sIHNpemU7Cit9IHN0cmluZ3Npbms7CisKK3N0YXRpYyB2b2lkICpzdHJpbmdzaW5rX3N0YXJ0KHZvaWQgKl9zaW5rLCBjb25zdCB2b2lkICpoZCwgc2l6ZV90IHNpemVfaGludCkgeworICBzdHJpbmdzaW5rICpzaW5rID0gX3Npbms7CisgIHNpbmstPmxlbiA9IDA7CisgIHJldHVybiBzaW5rOworfQorCitzdGF0aWMgc2l6ZV90IHN0cmluZ3Npbmtfc3RyaW5nKHZvaWQgKl9zaW5rLCBjb25zdCB2b2lkICpoZCwgY29uc3QgY2hhciAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuLCBjb25zdCB1cGJfYnVmaGFuZGxlICpoYW5kbGUpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIFVQQl9VTlVTRUQoaGFuZGxlKTsKKworICBzdHJpbmdzaW5rICpzaW5rID0gX3Npbms7CisgIHNpemVfdCBuZXdfc2l6ZSA9IHNpbmstPnNpemU7CisKKyAgd2hpbGUgKHNpbmstPmxlbiArIGxlbiA+IG5ld19zaXplKSB7CisgICAgbmV3X3NpemUgKj0gMjsKKyAgfQorCisgIGlmIChuZXdfc2l6ZSAhPSBzaW5rLT5zaXplKSB7CisgICAgc2luay0+cHRyID0gcmVhbGxvYyhzaW5rLT5wdHIsIG5ld19zaXplKTsKKyAgICBzaW5rLT5zaXplID0gbmV3X3NpemU7CisgIH0KKworICBtZW1jcHkoc2luay0+cHRyICsgc2luay0+bGVuLCBwdHIsIGxlbik7CisgIHNpbmstPmxlbiArPSBsZW47CisKKyAgcmV0dXJuIGxlbjsKK30KKwordm9pZCBzdHJpbmdzaW5rX2luaXQoc3RyaW5nc2luayAqc2luaykgeworICB1cGJfYnl0ZXNoYW5kbGVyX2luaXQoJnNpbmstPmhhbmRsZXIpOworICB1cGJfYnl0ZXNoYW5kbGVyX3NldHN0YXJ0c3RyKCZzaW5rLT5oYW5kbGVyLCBzdHJpbmdzaW5rX3N0YXJ0LCBOVUxMKTsKKyAgdXBiX2J5dGVzaGFuZGxlcl9zZXRzdHJpbmcoJnNpbmstPmhhbmRsZXIsIHN0cmluZ3Npbmtfc3RyaW5nLCBOVUxMKTsKKworICB1cGJfYnl0ZXNzaW5rX3Jlc2V0KCZzaW5rLT5zaW5rLCAmc2luay0+aGFuZGxlciwgc2luayk7CisKKyAgc2luay0+c2l6ZSA9IDMyOworICBzaW5rLT5wdHIgPSBtYWxsb2Moc2luay0+c2l6ZSk7CisgIHNpbmstPmxlbiA9IDA7Cit9CisKK3ZvaWQgc3RyaW5nc2lua191bmluaXQoc3RyaW5nc2luayAqc2luaykgeworICBmcmVlKHNpbmstPnB0cik7Cit9CisKKy8qIG1zZ3Zpc2l0b3IgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIFRPRE86IElmL3doZW4gd2Ugc3VwcG9ydCBwcm90bzIgc2VtYW50aWNzIGluIGFkZGl0aW9uIHRvIHRoZSBjdXJyZW50IHByb3RvMworLy8gc2VtYW50aWNzLCB3aGljaCBtZWFucyB0aGF0IHdlIGhhdmUgdHJ1ZSBmaWVsZCBwcmVzZW5jZSwgd2Ugd2lsbCB3YW50IHRvCisvLyBtb2RpZnkgbXNndmlzaXRvciBzbyB0aGF0IGl0IGVtaXRzIGFsbCBwcmVzZW50IGZpZWxkcyByYXRoZXIgdGhhbiBhbGwKKy8vIG5vbi1kZWZhdWx0LXZhbHVlIGZpZWxkcy4KKy8vCisvLyBMaWtld2lzZSwgd2hlbiBpbXBsZW1lbnRpbmcgSlNPTiBzZXJpYWxpemF0aW9uLCB3ZSBtYXkgbmVlZCB0byBoYXZlIGEKKy8vICd2ZXJib3NlJyBtb2RlIHRoYXQgb3V0cHV0cyBhbGwgZmllbGRzIGFuZCBhICdjb25jaXNlJyBtb2RlIHRoYXQgb3V0cHV0cyBvbmx5CisvLyB0aG9zZSB3aXRoIG5vbi1kZWZhdWx0IHZhbHVlcy4KKworc3RhdGljIHZvaWQgcHV0bXNnKFZBTFVFIG1zZywgY29uc3QgRGVzY3JpcHRvciogZGVzYywKKyAgICAgICAgICAgICAgICAgICB1cGJfc2luayAqc2luaywgaW50IGRlcHRoKTsKKworc3RhdGljIHVwYl9zZWxlY3Rvcl90IGdldHNlbChjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9oYW5kbGVydHlwZV90IHR5cGUpIHsKKyAgdXBiX3NlbGVjdG9yX3QgcmV0OworICBib29sIG9rID0gdXBiX2hhbmRsZXJzX2dldHNlbGVjdG9yKGYsIHR5cGUsICZyZXQpOworICBVUEJfQVNTRVJUX1ZBUihvaywgb2spOworICByZXR1cm4gcmV0OworfQorCitzdGF0aWMgdm9pZCBwdXRzdHIoVkFMVUUgc3RyLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9zaW5rICpzaW5rKSB7CisgIGlmIChzdHIgPT0gUW5pbCkgcmV0dXJuOworCisgIGFzc2VydChCVUlMVElOX1RZUEUoc3RyKSA9PSBSVUJZX1RfU1RSSU5HKTsKKyAgdXBiX3Npbmsgc3Vic2luazsKKworICAvLyBFbnN1cmUgdGhhdCB0aGUgc3RyaW5nIGhhcyB0aGUgY29ycmVjdCBlbmNvZGluZy4gV2UgYWxzbyBjaGVjayBhdCBmaWVsZC1zZXQKKyAgLy8gdGltZSwgYnV0IHRoZSB1c2VyIG1heSBoYXZlIG11dGF0ZWQgdGhlIHN0cmluZyBvYmplY3Qgc2luY2UgdGhlbi4KKyAgbmF0aXZlX3Nsb3RfdmFsaWRhdGVfc3RyaW5nX2VuY29kaW5nKHVwYl9maWVsZGRlZl90eXBlKGYpLCBzdHIpOworCisgIHVwYl9zaW5rX3N0YXJ0c3RyKHNpbmssIGdldHNlbChmLCBVUEJfSEFORExFUl9TVEFSVFNUUiksIFJTVFJJTkdfTEVOKHN0ciksCisgICAgICAgICAgICAgICAgICAgICZzdWJzaW5rKTsKKyAgdXBiX3NpbmtfcHV0c3RyaW5nKCZzdWJzaW5rLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfU1RSSU5HKSwgUlNUUklOR19QVFIoc3RyKSwKKyAgICAgICAgICAgICAgICAgICAgIFJTVFJJTkdfTEVOKHN0ciksIE5VTEwpOworICB1cGJfc2lua19lbmRzdHIoc2luaywgZ2V0c2VsKGYsIFVQQl9IQU5ETEVSX0VORFNUUikpOworfQorCitzdGF0aWMgdm9pZCBwdXRzdWJtc2coVkFMVUUgc3VibXNnLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9zaW5rICpzaW5rLAorICAgICAgICAgICAgICAgICAgICAgIGludCBkZXB0aCkgeworICBpZiAoc3VibXNnID09IFFuaWwpIHJldHVybjsKKworICB1cGJfc2luayBzdWJzaW5rOworICBWQUxVRSBkZXNjcmlwdG9yID0gcmJfaXZfZ2V0KHN1Ym1zZywga0Rlc2NyaXB0b3JJbnN0YW5jZVZhcik7CisgIERlc2NyaXB0b3IqIHN1YmRlc2MgPSBydWJ5X3RvX0Rlc2NyaXB0b3IoZGVzY3JpcHRvcik7CisKKyAgdXBiX3Npbmtfc3RhcnRzdWJtc2coc2luaywgZ2V0c2VsKGYsIFVQQl9IQU5ETEVSX1NUQVJUU1VCTVNHKSwgJnN1YnNpbmspOworICBwdXRtc2coc3VibXNnLCBzdWJkZXNjLCAmc3Vic2luaywgZGVwdGggKyAxKTsKKyAgdXBiX3NpbmtfZW5kc3VibXNnKHNpbmssIGdldHNlbChmLCBVUEJfSEFORExFUl9FTkRTVUJNU0cpKTsKK30KKworc3RhdGljIHZvaWQgcHV0YXJ5KFZBTFVFIGFyeSwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLCB1cGJfc2luayAqc2luaywKKyAgICAgICAgICAgICAgICAgICBpbnQgZGVwdGgpIHsKKyAgaWYgKGFyeSA9PSBRbmlsKSByZXR1cm47CisKKyAgdXBiX3Npbmsgc3Vic2luazsKKworICB1cGJfc2lua19zdGFydHNlcShzaW5rLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfU1RBUlRTRVEpLCAmc3Vic2luayk7CisKKyAgdXBiX2ZpZWxkdHlwZV90IHR5cGUgPSB1cGJfZmllbGRkZWZfdHlwZShmKTsKKyAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gMDsKKyAgaWYgKHVwYl9maWVsZGRlZl9pc3ByaW1pdGl2ZShmKSkgeworICAgIHNlbCA9IGdldHNlbChmLCB1cGJfaGFuZGxlcnNfZ2V0cHJpbWl0aXZlaGFuZGxlcnR5cGUoZikpOworICB9CisKKyAgaW50IHNpemUgPSBOVU0ySU5UKFJlcGVhdGVkRmllbGRfbGVuZ3RoKGFyeSkpOworICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgIHZvaWQqIG1lbW9yeSA9IFJlcGVhdGVkRmllbGRfaW5kZXhfbmF0aXZlKGFyeSwgaSk7CisgICAgc3dpdGNoICh0eXBlKSB7CisjZGVmaW5lIFQodXBidHlwZWNvbnN0LCB1cGJ0eXBlLCBjdHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYXNlIHVwYnR5cGVjb25zdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB1cGJfc2lua19wdXQjI3VwYnR5cGUoJnN1YnNpbmssIHNlbCwgKigoY3R5cGUgKiltZW1vcnkpKTsgICBcCisgICAgYnJlYWs7CisKKyAgICAgIFQoVVBCX1RZUEVfRkxPQVQsICBmbG9hdCwgIGZsb2F0KQorICAgICAgVChVUEJfVFlQRV9ET1VCTEUsIGRvdWJsZSwgZG91YmxlKQorICAgICAgVChVUEJfVFlQRV9CT09MLCAgIGJvb2wsICAgaW50OF90KQorICAgICAgY2FzZSBVUEJfVFlQRV9FTlVNOgorICAgICAgVChVUEJfVFlQRV9JTlQzMiwgIGludDMyLCAgaW50MzJfdCkKKyAgICAgIFQoVVBCX1RZUEVfVUlOVDMyLCB1aW50MzIsIHVpbnQzMl90KQorICAgICAgVChVUEJfVFlQRV9JTlQ2NCwgIGludDY0LCAgaW50NjRfdCkKKyAgICAgIFQoVVBCX1RZUEVfVUlOVDY0LCB1aW50NjQsIHVpbnQ2NF90KQorCisgICAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICAgIGNhc2UgVVBCX1RZUEVfQllURVM6CisgICAgICAgIHB1dHN0cigqKChWQUxVRSAqKW1lbW9yeSksIGYsICZzdWJzaW5rKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX01FU1NBR0U6CisgICAgICAgIHB1dHN1Ym1zZygqKChWQUxVRSAqKW1lbW9yeSksIGYsICZzdWJzaW5rLCBkZXB0aCk7CisgICAgICAgIGJyZWFrOworCisjdW5kZWYgVAorCisgICAgfQorICB9CisgIHVwYl9zaW5rX2VuZHNlcShzaW5rLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfRU5EU0VRKSk7Cit9CisKK3N0YXRpYyB2b2lkIHB1dF9ydWJ5X3ZhbHVlKFZBTFVFIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgdHlwZV9jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZXB0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zaW5rICpzaW5rKSB7CisgIHVwYl9zZWxlY3Rvcl90IHNlbCA9IDA7CisgIGlmICh1cGJfZmllbGRkZWZfaXNwcmltaXRpdmUoZikpIHsKKyAgICBzZWwgPSBnZXRzZWwoZiwgdXBiX2hhbmRsZXJzX2dldHByaW1pdGl2ZWhhbmRsZXJ0eXBlKGYpKTsKKyAgfQorCisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUoZikpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgICAgdXBiX3NpbmtfcHV0aW50MzIoc2luaywgc2VsLCBOVU0ySU5UKHZhbHVlKSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDY0OgorICAgICAgdXBiX3NpbmtfcHV0aW50NjQoc2luaywgc2VsLCBOVU0yTEwodmFsdWUpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDMyOgorICAgICAgdXBiX3NpbmtfcHV0dWludDMyKHNpbmssIHNlbCwgTlVNMlVJTlQodmFsdWUpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDY0OgorICAgICAgdXBiX3NpbmtfcHV0dWludDY0KHNpbmssIHNlbCwgTlVNMlVMTCh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9GTE9BVDoKKyAgICAgIHVwYl9zaW5rX3B1dGZsb2F0KHNpbmssIHNlbCwgTlVNMkRCTCh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9ET1VCTEU6CisgICAgICB1cGJfc2lua19wdXRkb3VibGUoc2luaywgc2VsLCBOVU0yREJMKHZhbHVlKSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0VOVU06IHsKKyAgICAgIGlmIChUWVBFKHZhbHVlKSA9PSBUX1NZTUJPTCkgeworICAgICAgICB2YWx1ZSA9IHJiX2Z1bmNhbGwodHlwZV9jbGFzcywgcmJfaW50ZXJuKCJyZXNvbHZlIiksIDEsIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIHVwYl9zaW5rX3B1dGludDMyKHNpbmssIHNlbCwgTlVNMklOVCh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfQk9PTDoKKyAgICAgIHVwYl9zaW5rX3B1dGJvb2woc2luaywgc2VsLCB2YWx1ZSA9PSBRdHJ1ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOgorICAgICAgcHV0c3RyKHZhbHVlLCBmLCBzaW5rKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRToKKyAgICAgIHB1dHN1Ym1zZyh2YWx1ZSwgZiwgc2luaywgZGVwdGgpOworICB9Cit9CisKK3N0YXRpYyB2b2lkIHB1dG1hcChWQUxVRSBtYXAsIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgdXBiX3NpbmsgKnNpbmssCisgICAgICAgICAgICAgICAgICAgaW50IGRlcHRoKSB7CisgIGlmIChtYXAgPT0gUW5pbCkgcmV0dXJuOworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChtYXApOworCisgIHVwYl9zaW5rIHN1YnNpbms7CisKKyAgdXBiX3Npbmtfc3RhcnRzZXEoc2luaywgZ2V0c2VsKGYsIFVQQl9IQU5ETEVSX1NUQVJUU0VRKSwgJnN1YnNpbmspOworCisgIGFzc2VydCh1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9NRVNTQUdFKTsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBrZXlfZmllbGQgPSBtYXBfZmllbGRfa2V5KGYpOworICBjb25zdCB1cGJfZmllbGRkZWYqIHZhbHVlX2ZpZWxkID0gbWFwX2ZpZWxkX3ZhbHVlKGYpOworCisgIE1hcF9pdGVyIGl0OworICBmb3IgKE1hcF9iZWdpbihtYXAsICZpdCk7ICFNYXBfZG9uZSgmaXQpOyBNYXBfbmV4dCgmaXQpKSB7CisgICAgVkFMVUUga2V5ID0gTWFwX2l0ZXJfa2V5KCZpdCk7CisgICAgVkFMVUUgdmFsdWUgPSBNYXBfaXRlcl92YWx1ZSgmaXQpOworCisgICAgdXBiX3NpbmsgZW50cnlfc2luazsKKyAgICB1cGJfc2lua19zdGFydHN1Ym1zZygmc3Vic2luaywgZ2V0c2VsKGYsIFVQQl9IQU5ETEVSX1NUQVJUU1VCTVNHKSwgJmVudHJ5X3NpbmspOworICAgIHVwYl9zaW5rX3N0YXJ0bXNnKCZlbnRyeV9zaW5rKTsKKworICAgIHB1dF9ydWJ5X3ZhbHVlKGtleSwga2V5X2ZpZWxkLCBRbmlsLCBkZXB0aCArIDEsICZlbnRyeV9zaW5rKTsKKyAgICBwdXRfcnVieV92YWx1ZSh2YWx1ZSwgdmFsdWVfZmllbGQsIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MsIGRlcHRoICsgMSwKKyAgICAgICAgICAgICAgICAgICAmZW50cnlfc2luayk7CisKKyAgICB1cGJfc3RhdHVzIHN0YXR1czsKKyAgICB1cGJfc2lua19lbmRtc2coJmVudHJ5X3NpbmssICZzdGF0dXMpOworICAgIHVwYl9zaW5rX2VuZHN1Ym1zZygmc3Vic2luaywgZ2V0c2VsKGYsIFVQQl9IQU5ETEVSX0VORFNVQk1TRykpOworICB9CisKKyAgdXBiX3NpbmtfZW5kc2VxKHNpbmssIGdldHNlbChmLCBVUEJfSEFORExFUl9FTkRTRVEpKTsKK30KKworc3RhdGljIHZvaWQgcHV0bXNnKFZBTFVFIG1zZ19yYiwgY29uc3QgRGVzY3JpcHRvciogZGVzYywKKyAgICAgICAgICAgICAgICAgICB1cGJfc2luayAqc2luaywgaW50IGRlcHRoKSB7CisgIHVwYl9zaW5rX3N0YXJ0bXNnKHNpbmspOworCisgIC8vIFByb3RlY3QgYWdhaW5zdCBjeWNsZXMgKHBvc3NpYmxlIGJlY2F1c2UgdXNlcnMgbWF5IGZyZWVseSByZWFzc2lnbiBtZXNzYWdlCisgIC8vIGFuZCByZXBlYXRlZCBmaWVsZHMpIGJ5IGltcG9zaW5nIGEgbWF4aW11bSByZWN1cnNpb24gZGVwdGguCisgIGlmIChkZXB0aCA+IFVQQl9TSU5LX01BWF9ORVNUSU5HKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAiTWF4aW11bSByZWN1cnNpb24gZGVwdGggZXhjZWVkZWQgZHVyaW5nIGVuY29kaW5nLiIpOworICB9CisKKyAgTWVzc2FnZUhlYWRlciogbXNnOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChtc2dfcmIsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIG1zZyk7CisKKyAgdXBiX21zZ19maWVsZF9pdGVyIGk7CisgIGZvciAodXBiX21zZ19maWVsZF9iZWdpbigmaSwgZGVzYy0+bXNnZGVmKTsKKyAgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpKTsKKyAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpKTsKKyAgICB1aW50MzJfdCBvZmZzZXQgPQorICAgICAgICBkZXNjLT5sYXlvdXQtPmZpZWxkc1t1cGJfZmllbGRkZWZfaW5kZXgoZildLm9mZnNldCArCisgICAgICAgIHNpemVvZihNZXNzYWdlSGVhZGVyKTsKKworICAgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGYpKSB7CisgICAgICB1aW50MzJfdCBvbmVvZl9jYXNlX29mZnNldCA9CisgICAgICAgICAgZGVzYy0+bGF5b3V0LT5maWVsZHNbdXBiX2ZpZWxkZGVmX2luZGV4KGYpXS5jYXNlX29mZnNldCArCisgICAgICAgICAgc2l6ZW9mKE1lc3NhZ2VIZWFkZXIpOworICAgICAgLy8gRm9yIGEgb25lb2YsIGNoZWNrIHRoYXQgdGhpcyBmaWVsZCBpcyBhY3R1YWxseSBwcmVzZW50IC0tIHNraXAgYWxsIHRoZQorICAgICAgLy8gYmVsb3cgaWYgbm90LgorICAgICAgaWYgKERFUkVGKG1zZywgb25lb2ZfY2FzZV9vZmZzZXQsIHVpbnQzMl90KSAhPQorICAgICAgICAgIHVwYl9maWVsZGRlZl9udW1iZXIoZikpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICAvLyBPdGhlcndpc2UsIGZhbGwgdGhyb3VnaCB0byB0aGUgYXBwcm9wcmlhdGUgc2luZ3VsYXItZmllbGQgaGFuZGxlcgorICAgICAgLy8gYmVsb3cuCisgICAgfQorCisgICAgaWYgKGlzX21hcF9maWVsZChmKSkgeworICAgICAgVkFMVUUgbWFwID0gREVSRUYobXNnLCBvZmZzZXQsIFZBTFVFKTsKKyAgICAgIGlmIChtYXAgIT0gUW5pbCkgeworICAgICAgICBwdXRtYXAobWFwLCBmLCBzaW5rLCBkZXB0aCk7CisgICAgICB9CisgICAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsKKyAgICAgIFZBTFVFIGFyeSA9IERFUkVGKG1zZywgb2Zmc2V0LCBWQUxVRSk7CisgICAgICBpZiAoYXJ5ICE9IFFuaWwpIHsKKyAgICAgICAgcHV0YXJ5KGFyeSwgZiwgc2luaywgZGVwdGgpOworICAgICAgfQorICAgIH0gZWxzZSBpZiAodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGYpKSB7CisgICAgICBWQUxVRSBzdHIgPSBERVJFRihtc2csIG9mZnNldCwgVkFMVUUpOworICAgICAgaWYgKFJTVFJJTkdfTEVOKHN0cikgPiAwKSB7CisgICAgICAgIHB1dHN0cihzdHIsIGYsIHNpbmspOworICAgICAgfQorICAgIH0gZWxzZSBpZiAodXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpKSB7CisgICAgICBwdXRzdWJtc2coREVSRUYobXNnLCBvZmZzZXQsIFZBTFVFKSwgZiwgc2luaywgZGVwdGgpOworICAgIH0gZWxzZSB7CisgICAgICB1cGJfc2VsZWN0b3JfdCBzZWwgPSBnZXRzZWwoZiwgdXBiX2hhbmRsZXJzX2dldHByaW1pdGl2ZWhhbmRsZXJ0eXBlKGYpKTsKKworI2RlZmluZSBUKHVwYnR5cGVjb25zdCwgdXBidHlwZSwgY3R5cGUsIGRlZmF1bHRfdmFsdWUpICAgICAgICAgICAgICAgIFwKKyAgY2FzZSB1cGJ0eXBlY29uc3Q6IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjdHlwZSB2YWx1ZSA9IERFUkVGKG1zZywgb2Zmc2V0LCBjdHlwZSk7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgaWYgKHZhbHVlICE9IGRlZmF1bHRfdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgdXBiX3NpbmtfcHV0IyN1cGJ0eXBlKHNpbmssIHNlbCwgdmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBicmVhazsKKworICAgICAgc3dpdGNoICh1cGJfZmllbGRkZWZfdHlwZShmKSkgeworICAgICAgICBUKFVQQl9UWVBFX0ZMT0FULCAgZmxvYXQsICBmbG9hdCwgMC4wKQorICAgICAgICBUKFVQQl9UWVBFX0RPVUJMRSwgZG91YmxlLCBkb3VibGUsIDAuMCkKKyAgICAgICAgVChVUEJfVFlQRV9CT09MLCAgIGJvb2wsICAgdWludDhfdCwgMCkKKyAgICAgICAgY2FzZSBVUEJfVFlQRV9FTlVNOgorICAgICAgICBUKFVQQl9UWVBFX0lOVDMyLCAgaW50MzIsICBpbnQzMl90LCAwKQorICAgICAgICBUKFVQQl9UWVBFX1VJTlQzMiwgdWludDMyLCB1aW50MzJfdCwgMCkKKyAgICAgICAgVChVUEJfVFlQRV9JTlQ2NCwgIGludDY0LCAgaW50NjRfdCwgMCkKKyAgICAgICAgVChVUEJfVFlQRV9VSU5UNjQsIHVpbnQ2NCwgdWludDY0X3QsIDApCisKKyAgICAgICAgY2FzZSBVUEJfVFlQRV9TVFJJTkc6CisgICAgICAgIGNhc2UgVVBCX1RZUEVfQllURVM6CisgICAgICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRTogcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIkludGVybmFsIGVycm9yLiIpOworICAgICAgfQorCisjdW5kZWYgVAorCisgICAgfQorICB9CisKKyAgdXBiX3N0YXR1cyBzdGF0dXM7CisgIHVwYl9zaW5rX2VuZG1zZyhzaW5rLCAmc3RhdHVzKTsKK30KKworc3RhdGljIGNvbnN0IHVwYl9oYW5kbGVycyogbXNnZGVmX3BiX3NlcmlhbGl6ZV9oYW5kbGVycyhEZXNjcmlwdG9yKiBkZXNjKSB7CisgIGlmIChkZXNjLT5wYl9zZXJpYWxpemVfaGFuZGxlcnMgPT0gTlVMTCkgeworICAgIGRlc2MtPnBiX3NlcmlhbGl6ZV9oYW5kbGVycyA9CisgICAgICAgIHVwYl9wYl9lbmNvZGVyX25ld2hhbmRsZXJzKGRlc2MtPm1zZ2RlZiwgJmRlc2MtPnBiX3NlcmlhbGl6ZV9oYW5kbGVycyk7CisgIH0KKyAgcmV0dXJuIGRlc2MtPnBiX3NlcmlhbGl6ZV9oYW5kbGVyczsKK30KKworc3RhdGljIGNvbnN0IHVwYl9oYW5kbGVycyogbXNnZGVmX2pzb25fc2VyaWFsaXplX2hhbmRsZXJzKERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgaWYgKGRlc2MtPmpzb25fc2VyaWFsaXplX2hhbmRsZXJzID09IE5VTEwpIHsKKyAgICBkZXNjLT5qc29uX3NlcmlhbGl6ZV9oYW5kbGVycyA9CisgICAgICAgIHVwYl9qc29uX3ByaW50ZXJfbmV3aGFuZGxlcnMoCisgICAgICAgICAgICBkZXNjLT5tc2dkZWYsICZkZXNjLT5qc29uX3NlcmlhbGl6ZV9oYW5kbGVycyk7CisgIH0KKyAgcmV0dXJuIGRlc2MtPmpzb25fc2VyaWFsaXplX2hhbmRsZXJzOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZUNsYXNzLmVuY29kZShtc2cpID0+IGJ5dGVzCisgKgorICogRW5jb2RlcyB0aGUgZ2l2ZW4gbWVzc2FnZSBvYmplY3QgdG8gaXRzIHNlcmlhbGl6ZWQgZm9ybSBpbiBwcm90b2NvbCBidWZmZXJzCisgKiB3aXJlIGZvcm1hdC4KKyAqLworVkFMVUUgTWVzc2FnZV9lbmNvZGUoVkFMVUUga2xhc3MsIFZBTFVFIG1zZ19yYikgeworICBWQUxVRSBkZXNjcmlwdG9yID0gcmJfaXZfZ2V0KGtsYXNzLCBrRGVzY3JpcHRvckluc3RhbmNlVmFyKTsKKyAgRGVzY3JpcHRvciogZGVzYyA9IHJ1YnlfdG9fRGVzY3JpcHRvcihkZXNjcmlwdG9yKTsKKworICBzdHJpbmdzaW5rIHNpbms7CisgIHN0cmluZ3NpbmtfaW5pdCgmc2luayk7CisKKyAgY29uc3QgdXBiX2hhbmRsZXJzKiBzZXJpYWxpemVfaGFuZGxlcnMgPQorICAgICAgbXNnZGVmX3BiX3NlcmlhbGl6ZV9oYW5kbGVycyhkZXNjKTsKKworICB1cGJfcGJfZW5jb2RlciBlbmNvZGVyOworICB1cGJfcGJfZW5jb2Rlcl9pbml0KCZlbmNvZGVyLCBzZXJpYWxpemVfaGFuZGxlcnMpOworICB1cGJfcGJfZW5jb2Rlcl9yZXNldG91dHB1dCgmZW5jb2RlciwgJnNpbmsuc2luayk7CisKKyAgcHV0bXNnKG1zZ19yYiwgZGVzYywgdXBiX3BiX2VuY29kZXJfaW5wdXQoJmVuY29kZXIpLCAwKTsKKworICBWQUxVRSByZXQgPSByYl9zdHJfbmV3KHNpbmsucHRyLCBzaW5rLmxlbik7CisKKyAgdXBiX3BiX2VuY29kZXJfdW5pbml0KCZlbmNvZGVyKTsKKyAgc3RyaW5nc2lua191bmluaXQoJnNpbmspOworCisgIHJldHVybiByZXQ7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBNZXNzYWdlQ2xhc3MuZW5jb2RlX2pzb24obXNnKSA9PiBqc29uX3N0cmluZworICoKKyAqIEVuY29kZXMgdGhlIGdpdmVuIG1lc3NhZ2Ugb2JqZWN0IGludG8gaXRzIHNlcmlhbGl6ZWQgSlNPTiByZXByZXNlbnRhdGlvbi4KKyAqLworVkFMVUUgTWVzc2FnZV9lbmNvZGVfanNvbihWQUxVRSBrbGFzcywgVkFMVUUgbXNnX3JiKSB7CisgIFZBTFVFIGRlc2NyaXB0b3IgPSByYl9pdl9nZXQoa2xhc3MsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIpOworICBEZXNjcmlwdG9yKiBkZXNjID0gcnVieV90b19EZXNjcmlwdG9yKGRlc2NyaXB0b3IpOworCisgIHN0cmluZ3Npbmsgc2luazsKKyAgc3RyaW5nc2lua19pbml0KCZzaW5rKTsKKworICBjb25zdCB1cGJfaGFuZGxlcnMqIHNlcmlhbGl6ZV9oYW5kbGVycyA9CisgICAgICBtc2dkZWZfanNvbl9zZXJpYWxpemVfaGFuZGxlcnMoZGVzYyk7CisKKyAgdXBiX2pzb25fcHJpbnRlciBwcmludGVyOworICB1cGJfanNvbl9wcmludGVyX2luaXQoJnByaW50ZXIsIHNlcmlhbGl6ZV9oYW5kbGVycyk7CisgIHVwYl9qc29uX3ByaW50ZXJfcmVzZXRvdXRwdXQoJnByaW50ZXIsICZzaW5rLnNpbmspOworCisgIHB1dG1zZyhtc2dfcmIsIGRlc2MsIHVwYl9qc29uX3ByaW50ZXJfaW5wdXQoJnByaW50ZXIpLCAwKTsKKworICBWQUxVRSByZXQgPSByYl9zdHJfbmV3KHNpbmsucHRyLCBzaW5rLmxlbik7CisKKyAgdXBiX2pzb25fcHJpbnRlcl91bmluaXQoJnByaW50ZXIpOworICBzdHJpbmdzaW5rX3VuaW5pdCgmc2luayk7CisKKyAgcmV0dXJuIHJldDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEdvb2dsZTo6UHJvdG9idWYuZW5jb2RlKG1zZykgPT4gYnl0ZXMKKyAqCisgKiBFbmNvZGVzIHRoZSBnaXZlbiBtZXNzYWdlIG9iamVjdCB0byBwcm90b2NvbCBidWZmZXJzIHdpcmUgZm9ybWF0LiBUaGlzIGlzIGFuCisgKiBhbHRlcm5hdGl2ZSB0byB0aGUgI2VuY29kZSBtZXRob2Qgb24gbXNnJ3MgY2xhc3MuCisgKi8KK1ZBTFVFIEdvb2dsZV9Qcm90b2J1Zl9lbmNvZGUoVkFMVUUgc2VsZiwgVkFMVUUgbXNnX3JiKSB7CisgIFZBTFVFIGtsYXNzID0gQ0xBU1NfT0YobXNnX3JiKTsKKyAgcmV0dXJuIE1lc3NhZ2VfZW5jb2RlKGtsYXNzLCBtc2dfcmIpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgR29vZ2xlOjpQcm90b2J1Zi5lbmNvZGVfanNvbihtc2cpID0+IGpzb25fc3RyaW5nCisgKgorICogRW5jb2RlcyB0aGUgZ2l2ZW4gbWVzc2FnZSBvYmplY3QgdG8gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uIFRoaXMgaXMgYW4KKyAqIGFsdGVybmF0aXZlIHRvIHRoZSAjZW5jb2RlX2pzb24gbWV0aG9kIG9uIG1zZydzIGNsYXNzLgorICovCitWQUxVRSBHb29nbGVfUHJvdG9idWZfZW5jb2RlX2pzb24oVkFMVUUgc2VsZiwgVkFMVUUgbXNnX3JiKSB7CisgIFZBTFVFIGtsYXNzID0gQ0xBU1NfT0YobXNnX3JiKTsKKyAgcmV0dXJuIE1lc3NhZ2VfZW5jb2RlX2pzb24oa2xhc3MsIG1zZ19yYik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBHb29nbGU6OlByb3RvYnVmLmRlY29kZShjbGFzcywgYnl0ZXMpID0+IG1zZworICoKKyAqIERlY29kZXMgdGhlIGdpdmVuIGJ5dGVzIGFzIHByb3RvY29sIGJ1ZmZlcnMgd2lyZSBmb3JtYXQgdW5kZXIgdGhlCisgKiBpbnRlcnByZXRhdGlvbiBnaXZlbiBieSB0aGUgZ2l2ZW4gY2xhc3MncyBtZXNzYWdlIGRlZmluaXRpb24uIFRoaXMgaXMgYW4KKyAqIGFsdGVybmF0aXZlIHRvIHRoZSAjZGVjb2RlIG1ldGhvZCBvbiB0aGUgZ2l2ZW4gY2xhc3MuCisgKi8KK1ZBTFVFIEdvb2dsZV9Qcm90b2J1Zl9kZWNvZGUoVkFMVUUgc2VsZiwgVkFMVUUga2xhc3MsIFZBTFVFIG1zZ19yYikgeworICByZXR1cm4gTWVzc2FnZV9kZWNvZGUoa2xhc3MsIG1zZ19yYik7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBHb29nbGU6OlByb3RvYnVmLmRlY29kZV9qc29uKGNsYXNzLCBqc29uX3N0cmluZykgPT4gbXNnCisgKgorICogRGVjb2RlcyB0aGUgZ2l2ZW4gSlNPTiBzdHJpbmcgdW5kZXIgdGhlIGludGVycHJldGF0aW9uIGdpdmVuIGJ5IHRoZSBnaXZlbgorICogY2xhc3MncyBtZXNzYWdlIGRlZmluaXRpb24uIFRoaXMgaXMgYW4gYWx0ZXJuYXRpdmUgdG8gdGhlICNkZWNvZGVfanNvbiBtZXRob2QKKyAqIG9uIHRoZSBnaXZlbiBjbGFzcy4KKyAqLworVkFMVUUgR29vZ2xlX1Byb3RvYnVmX2RlY29kZV9qc29uKFZBTFVFIHNlbGYsIFZBTFVFIGtsYXNzLCBWQUxVRSBtc2dfcmIpIHsKKyAgcmV0dXJuIE1lc3NhZ2VfZGVjb2RlX2pzb24oa2xhc3MsIG1zZ19yYik7Cit9CmRpZmYgLS1naXQgYS9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9leHRjb25mLnJiIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvZXh0Y29uZi5yYgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDYwMzkyCi0tLSAvZGV2L251bGwKKysrIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvZXh0Y29uZi5yYgpAQCAtMCwwICsxLDEwIEBACisjIS91c3IvYmluL3J1YnkKKworcmVxdWlyZSAnbWttZicKKworJENGTEFHUyArPSAiIC1PMyAtc3RkPWM5OSAtV25vLXVudXNlZC1mdW5jdGlvbiAtRE5ERUJVRyAiCisKKyRvYmpzID0gWyJwcm90b2J1Zi5vIiwgImRlZnMubyIsICJzdG9yYWdlLm8iLCAibWVzc2FnZS5vIiwKKyAgICAgICAgICJyZXBlYXRlZF9maWVsZC5vIiwgIm1hcC5vIiwgImVuY29kZV9kZWNvZGUubyIsICJ1cGIubyJdCisKK2NyZWF0ZV9tYWtlZmlsZSgiZ29vZ2xlL3Byb3RvYnVmX2MiKQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvbWFwLmMgYi9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9tYXAuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMmU3YTlkCi0tLSAvZGV2L251bGwKKysrIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvbWFwLmMKQEAgLTAsMCArMSw4MDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSAicHJvdG9idWYuaCIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEJhc2ljIG1hcCBvcGVyYXRpb25zIG9uIHRvcCBvZiB1cGIncyBzdHJ0YWJsZS4KKy8vCisvLyBOb3RlIHRoYXQgd2Ugcm9sbCBvdXIgb3duIGBNYXBgIGNvbnRhaW5lciBoZXJlIGJlY2F1c2UsIGFzIGZvcgorLy8gYFJlcGVhdGVkRmllbGRgLCB3ZSB3YW50IGEgc3Ryb25nbHktdHlwZWQgY29udGFpbmVyLiBUaGlzIGlzIHNvIHRoYXQgYW55IHVzZXIKKy8vIGVycm9ycyBkdWUgdG8gaW5jb3JyZWN0IG1hcCBrZXkgb3IgdmFsdWUgdHlwZXMgYXJlIHJhaXNlZCBhcyBjbG9zZSBhcworLy8gcG9zc2libGUgdG8gdGhlIGVycm9yIHNpdGUsIHJhdGhlciB0aGFuIGF0IHNvbWUgZGVmZXJyZWQgcG9pbnQgKGUuZy4sCisvLyBzZXJpYWxpemF0aW9uKS4KKy8vCisvLyBXZSBidWlsZCBvdXIgYE1hcGAgb24gdG9wIG9mIHVwYl9zdHJ0YWJsZSBzbyB0aGF0IHdlJ3JlIGFibGUgdG8gdGFrZQorLy8gYWR2YW50YWdlIG9mIHRoZSBuYXRpdmVfc2xvdCBzdG9yYWdlIGFic3RyYWN0aW9uLCBhcyBSZXBlYXRlZEZpZWxkIGRvZXMuCisvLyAoVGhpcyBpcyBub3QgcXVpdGUgYSBwZXJmZWN0IG1hcHBpbmcgLS0gc2VlIHRoZSBrZXkgY29udmVyc2lvbnMgYmVsb3cgLS0gYnV0CisvLyBnaXZlcyB1cyBmdWxsIHN1cHBvcnQgYW5kIGVycm9yLWNoZWNraW5nIGZvciBhbGwgdmFsdWUgdHlwZXMgZm9yIGZyZWUuKQorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gTWFwIHZhbHVlcyBhcmUgc3RvcmVkIHVzaW5nIHRoZSBuYXRpdmVfc2xvdCBhYnN0cmFjdGlvbiAoYXMgd2l0aCByZXBlYXRlZAorLy8gZmllbGQgdmFsdWVzKSwgYnV0IGtleXMgYXJlIGEgYml0IHNwZWNpYWwuIFNpbmNlIHdlIHVzZSBhIHN0cnRhYmxlLCB3ZSBuZWVkCisvLyB0byBzdG9yZSBrZXlzIGFzIHNlcXVlbmNlcyBvZiBieXRlcyBzdWNoIHRoYXQgZXF1YWxpdHkgb2YgdGhvc2UgYnl0ZXMgbWFwcworLy8gb25lLXRvLW9uZSB0byBlcXVhbGl0eSBvZiBrZXlzLiBXZSBzdG9yZSBzdHJpbmdzIGRpcmVjdGx5IChpLmUuLCB0aGV5IG1hcCB0bworLy8gdGhlaXIgb3duIGJ5dGVzKSBhbmQgaW50ZWdlcnMgYXMgbmF0aXZlIGludGVnZXJzICh1c2luZyB0aGUgbmF0aXZlX3Nsb3QKKy8vIGFic3RyYWN0aW9uKS4KKworLy8gTm90ZSB0aGF0IHRoZXJlIGlzIGFub3RoZXIgdHJhZGVvZmYgaGVyZSBpbiBrZWVwaW5nIHN0cmluZyBrZXlzIGFzIG5hdGl2ZQorLy8gc3RyaW5ncyByYXRoZXIgdGhhbiBSdWJ5IHN0cmluZ3M6IHRyYXZlcnNpbmcgdGhlIE1hcCByZXF1aXJlcyBjb252ZXJzaW9uIHRvCisvLyBSdWJ5IHN0cmluZyB2YWx1ZXMgb24gZXZlcnkgdHJhdmVyc2FsLCBwb3RlbnRpYWxseSBjcmVhdGluZyBtb3JlIGdhcmJhZ2UuIFdlCisvLyBzaG91bGQgY29uc2lkZXIgd2F5cyB0byBjYWNoZSBhIFJ1YnkgdmVyc2lvbiBvZiB0aGUga2V5IGlmIHRoaXMgYmVjb21lcyBhbgorLy8gaXNzdWUgbGF0ZXIuCisKKy8vIEZvcm1zIGEga2V5IHRvIHVzZSB3aXRoIHRoZSB1bmRlcmx5aW5nIHN0cnRhYmxlIGZyb20gYSBSdWJ5IGtleSB2YWx1ZS4gfGJ1ZnwKKy8vIG11c3QgcG9pbnQgdG8gVEFCTEVfS0VZX0JVRl9MRU5HVEggYnl0ZXMgb2YgdGVtcG9yYXJ5IHNwYWNlLCB1c2VkIHRvCisvLyBjb25zdHJ1Y3QgYSBrZXkgYnl0ZSBzZXF1ZW5jZSBpZiBuZWVkZWQuIHxvdXRfa2V5fCBhbmQgfG91dF9sZW5ndGh8IHByb3ZpZGUKKy8vIHRoZSByZXN1bHRpbmcga2V5IGRhdGEvbGVuZ3RoLgorI2RlZmluZSBUQUJMRV9LRVlfQlVGX0xFTkdUSCA4ICAvLyBzaXplb2YodWludDY0X3QpCitzdGF0aWMgdm9pZCB0YWJsZV9rZXkoTWFwKiBzZWxmLCBWQUxVRSBrZXksCisgICAgICAgICAgICAgICAgICAgICAgY2hhciogYnVmLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqKiBvdXRfa2V5LAorICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCogb3V0X2xlbmd0aCkgeworICBzd2l0Y2ggKHNlbGYtPmtleV90eXBlKSB7CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzoKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICAgIC8vIFN0cmluZ3M6IHVzZSBzdHJpbmcgY29udGVudCBkaXJlY3RseS4KKyAgICAgIENoZWNrX1R5cGUoa2V5LCBUX1NUUklORyk7CisgICAgICBuYXRpdmVfc2xvdF92YWxpZGF0ZV9zdHJpbmdfZW5jb2Rpbmcoc2VsZi0+a2V5X3R5cGUsIGtleSk7CisgICAgICAqb3V0X2tleSA9IFJTVFJJTkdfUFRSKGtleSk7CisgICAgICAqb3V0X2xlbmd0aCA9IFJTVFJJTkdfTEVOKGtleSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgVVBCX1RZUEVfQk9PTDoKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgIGNhc2UgVVBCX1RZUEVfSU5UNjQ6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UNjQ6CisgICAgICBuYXRpdmVfc2xvdF9zZXQoc2VsZi0+a2V5X3R5cGUsIFFuaWwsIGJ1Ziwga2V5KTsKKyAgICAgICpvdXRfa2V5ID0gYnVmOworICAgICAgKm91dF9sZW5ndGggPSBuYXRpdmVfc2xvdF9zaXplKHNlbGYtPmtleV90eXBlKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIC8vIE1hcCBjb25zdHJ1Y3RvciBzaG91bGQgbm90IGFsbG93IGEgTWFwIHdpdGggYW5vdGhlciBrZXkgdHlwZSB0byBiZQorICAgICAgLy8gY29uc3RydWN0ZWQuCisgICAgICBhc3NlcnQoZmFsc2UpOworICAgICAgYnJlYWs7CisgIH0KK30KKworc3RhdGljIFZBTFVFIHRhYmxlX2tleV90b19ydWJ5KE1hcCogc2VsZiwgY29uc3QgY2hhciogYnVmLCBzaXplX3QgbGVuZ3RoKSB7CisgIHN3aXRjaCAoc2VsZi0+a2V5X3R5cGUpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOgorICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOiB7CisgICAgICBWQUxVRSByZXQgPSByYl9zdHJfbmV3KGJ1ZiwgbGVuZ3RoKTsKKyAgICAgIHJiX2VuY19hc3NvY2lhdGUocmV0LAorICAgICAgICAgICAgICAgICAgICAgICAoc2VsZi0+a2V5X3R5cGUgPT0gVVBCX1RZUEVfQllURVMpID8KKyAgICAgICAgICAgICAgICAgICAgICAga1J1YnlTdHJpbmc4Yml0RW5jb2RpbmcgOiBrUnVieVN0cmluZ1V0ZjhFbmNvZGluZyk7CisgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIGNhc2UgVVBCX1RZUEVfQk9PTDoKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgIGNhc2UgVVBCX1RZUEVfSU5UNjQ6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gbmF0aXZlX3Nsb3RfZ2V0KHNlbGYtPmtleV90eXBlLCBRbmlsLCBidWYpOworCisgICAgZGVmYXVsdDoKKyAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICByZXR1cm4gUW5pbDsKKyAgfQorfQorCitzdGF0aWMgdm9pZCogdmFsdWVfbWVtb3J5KHVwYl92YWx1ZSogdikgeworICByZXR1cm4gKHZvaWQqKSgmdi0+dmFsLnVpbnQ2NCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNYXAgY29udGFpbmVyIHR5cGUuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCByYl9kYXRhX3R5cGVfdCBNYXBfdHlwZSA9IHsKKyAgIkdvb2dsZTo6UHJvdG9idWY6Ok1hcCIsCisgIHsgTWFwX21hcmssIE1hcF9mcmVlLCBOVUxMIH0sCit9OworCitWQUxVRSBjTWFwOworCitNYXAqIHJ1YnlfdG9fTWFwKFZBTFVFIF9zZWxmKSB7CisgIE1hcCogc2VsZjsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QoX3NlbGYsIE1hcCwgJk1hcF90eXBlLCBzZWxmKTsKKyAgcmV0dXJuIHNlbGY7Cit9CisKK3ZvaWQgTWFwX21hcmsodm9pZCogX3NlbGYpIHsKKyAgTWFwKiBzZWxmID0gX3NlbGY7CisKKyAgcmJfZ2NfbWFyayhzZWxmLT52YWx1ZV90eXBlX2NsYXNzKTsKKworICBpZiAoc2VsZi0+dmFsdWVfdHlwZSA9PSBVUEJfVFlQRV9TVFJJTkcgfHwKKyAgICAgIHNlbGYtPnZhbHVlX3R5cGUgPT0gVVBCX1RZUEVfQllURVMgfHwKKyAgICAgIHNlbGYtPnZhbHVlX3R5cGUgPT0gVVBCX1RZUEVfTUVTU0FHRSkgeworICAgIHVwYl9zdHJ0YWJsZV9pdGVyIGl0OworICAgIGZvciAodXBiX3N0cnRhYmxlX2JlZ2luKCZpdCwgJnNlbGYtPnRhYmxlKTsKKyAgICAgICAgICF1cGJfc3RydGFibGVfZG9uZSgmaXQpOworICAgICAgICAgdXBiX3N0cnRhYmxlX25leHQoJml0KSkgeworICAgICAgdXBiX3ZhbHVlIHYgPSB1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaXQpOworICAgICAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgICAgIG5hdGl2ZV9zbG90X21hcmsoc2VsZi0+dmFsdWVfdHlwZSwgbWVtKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBNYXBfZnJlZSh2b2lkKiBfc2VsZikgeworICBNYXAqIHNlbGYgPSBfc2VsZjsKKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmc2VsZi0+dGFibGUpOworICB4ZnJlZShzZWxmKTsKK30KKworVkFMVUUgTWFwX2FsbG9jKFZBTFVFIGtsYXNzKSB7CisgIE1hcCogc2VsZiA9IEFMTE9DKE1hcCk7CisgIG1lbXNldChzZWxmLCAwLCBzaXplb2YoTWFwKSk7CisgIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MgPSBRbmlsOworICBWQUxVRSByZXQgPSBUeXBlZERhdGFfV3JhcF9TdHJ1Y3Qoa2xhc3MsICZNYXBfdHlwZSwgc2VsZik7CisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBib29sIG5lZWRzX3R5cGVjbGFzcyh1cGJfZmllbGR0eXBlX3QgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIFVQQl9UWVBFX01FU1NBR0U6CisgICAgY2FzZSBVUEJfVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIHRydWU7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLm5ldyhrZXlfdHlwZSwgdmFsdWVfdHlwZSwgdmFsdWVfdHlwZWNsYXNzID0gbmlsLCBpbml0X2hhc2htYXAgPSB7fSkKKyAqICAgICA9PiBuZXcgbWFwCisgKgorICogQWxsb2NhdGVzIGEgbmV3IE1hcCBjb250YWluZXIuIFRoaXMgY29uc3RydWN0b3IgbWF5IGJlIGNhbGxlZCB3aXRoIDIsIDMsIG9yIDQKKyAqIGFyZ3VtZW50cy4gVGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIGFsd2F5cyBwcmVzZW50IGFuZCBhcmUgc3ltYm9scyAodGFraW5nCisgKiBvbiB0aGUgc2FtZSB2YWx1ZXMgYXMgZmllbGQtdHlwZSBzeW1ib2xzIGluIG1lc3NhZ2UgZGVzY3JpcHRvcnMpIHRoYXQKKyAqIGluZGljYXRlIHRoZSB0eXBlIG9mIHRoZSBtYXAga2V5IGFuZCB2YWx1ZSBmaWVsZHMuCisgKgorICogVGhlIHN1cHBvcnRlZCBrZXkgdHlwZXMgYXJlOiA6aW50MzIsIDppbnQ2NCwgOnVpbnQzMiwgOnVpbnQ2NCwgOmJvb2wsCisgKiA6c3RyaW5nLCA6Ynl0ZXMuCisgKgorICogVGhlIHN1cHBvcnRlZCB2YWx1ZSB0eXBlcyBhcmU6IDppbnQzMiwgOmludDY0LCA6dWludDMyLCA6dWludDY0LCA6Ym9vbCwKKyAqIDpzdHJpbmcsIDpieXRlcywgOmVudW0sIDptZXNzYWdlLgorICoKKyAqIFRoZSB0aGlyZCBhcmd1bWVudCwgdmFsdWVfdHlwZWNsYXNzLCBtdXN0IGJlIHByZXNlbnQgaWYgdmFsdWVfdHlwZSBpcyA6ZW51bQorICogb3IgOm1lc3NhZ2UuIEFzIGluIFJlcGVhdGVkRmllbGQjbmV3LCB0aGlzIGFyZ3VtZW50IG11c3QgYmUgYSBtZXNzYWdlIGNsYXNzCisgKiAoZm9yIDptZXNzYWdlKSBvciBlbnVtIG1vZHVsZSAoZm9yIDplbnVtKS4KKyAqCisgKiBUaGUgbGFzdCBhcmd1bWVudCwgaWYgcHJlc2VudCwgcHJvdmlkZXMgaW5pdGlhbCBjb250ZW50IGZvciBtYXAuIE5vdGUgdGhhdAorICogdGhpcyBtYXkgYmUgYW4gb3JkaW5hcnkgUnVieSBoYXNobWFwIG9yIGFub3RoZXIgTWFwIGluc3RhbmNlIHdpdGggaWRlbnRpY2FsCisgKiBrZXkgYW5kIHZhbHVlIHR5cGVzLiBBbHNvIG5vdGUgdGhhdCB0aGlzIGFyZ3VtZW50IG1heSBiZSBwcmVzZW50IHdoZXRoZXIgb3IKKyAqIG5vdCB2YWx1ZV90eXBlY2xhc3MgaXMgcHJlc2VudCAoYW5kIGl0IGlzIHVuYW1iaWd1b3VzbHkgc2VwYXJhdGUgZnJvbQorICogdmFsdWVfdHlwZWNsYXNzIGJlY2F1c2UgdmFsdWVfdHlwZWNsYXNzJ3MgcHJlc2VuY2UgaXMgc3RyaWN0bHkgZGV0ZXJtaW5lZCBieQorICogdmFsdWVfdHlwZSkuIFRoZSBjb250ZW50cyBvZiB0aGlzIGluaXRpYWwgaGFzaG1hcCBvciBNYXAgaW5zdGFuY2UgYXJlCisgKiBzaGFsbG93LWNvcGllZCBpbnRvIHRoZSBuZXcgTWFwOiB0aGUgb3JpZ2luYWwgbWFwIGlzIHVubW9kaWZpZWQsIGJ1dAorICogcmVmZXJlbmNlcyB0byB1bmRlcmx5aW5nIG9iamVjdHMgd2lsbCBiZSBzaGFyZWQgaWYgdGhlIHZhbHVlIHR5cGUgaXMgYQorICogbWVzc2FnZSB0eXBlLgorICovCitWQUxVRSBNYXBfaW5pdChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKSB7CisgIE1hcCogc2VsZiA9IHJ1YnlfdG9fTWFwKF9zZWxmKTsKKworICAvLyBXZSB0YWtlIGVpdGhlciB0d28gYXJncyAoOmtleV90eXBlLCA6dmFsdWVfdHlwZSksIHRocmVlIGFyZ3MgKDprZXlfdHlwZSwKKyAgLy8gOnZhbHVlX3R5cGUsICJWYWx1ZU1lc3NhZ2VUeXBlIiksIG9yIGZvdXIgYXJncyAodGhlIGFib3ZlIHBsdXMgYW4gaW5pdGlhbAorICAvLyBoYXNobWFwKS4KKyAgaWYgKGFyZ2MgPCAyIHx8IGFyZ2MgPiA0KSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiTWFwIGNvbnN0cnVjdG9yIGV4cGVjdHMgMiwgMyBvciA0IGFyZ3VtZW50cy4iKTsKKyAgfQorCisgIHNlbGYtPmtleV90eXBlID0gcnVieV90b19maWVsZHR5cGUoYXJndlswXSk7CisgIHNlbGYtPnZhbHVlX3R5cGUgPSBydWJ5X3RvX2ZpZWxkdHlwZShhcmd2WzFdKTsKKworICAvLyBDaGVjayB0aGF0IHRoZSBrZXkgdHlwZSBpcyBhbiBhbGxvd2VkIHR5cGUuCisgIHN3aXRjaCAoc2VsZi0+a2V5X3R5cGUpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgIGNhc2UgVVBCX1RZUEVfSU5UNjQ6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UNjQ6CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOgorICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOgorICAgIGNhc2UgVVBCX1RZUEVfQllURVM6CisgICAgICAvLyBUaGVzZSBhcmUgT0suCisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiSW52YWxpZCBrZXkgdHlwZSBmb3IgbWFwLiIpOworICB9CisKKyAgaW50IGluaXRfdmFsdWVfYXJnID0gMjsKKyAgaWYgKG5lZWRzX3R5cGVjbGFzcyhzZWxmLT52YWx1ZV90eXBlKSAmJiBhcmdjID4gMikgeworICAgIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MgPSBhcmd2WzJdOworICAgIHZhbGlkYXRlX3R5cGVfY2xhc3Moc2VsZi0+dmFsdWVfdHlwZSwgc2VsZi0+dmFsdWVfdHlwZV9jbGFzcyk7CisgICAgaW5pdF92YWx1ZV9hcmcgPSAzOworICB9CisKKyAgLy8gVGFibGUgdmFsdWUgdHlwZSBpcyBhbHdheXMgVUlOVDY0OiB0aGlzIGVuc3VyZXMgZW5vdWdoIHNwYWNlIHRvIHN0b3JlIHRoZQorICAvLyBuYXRpdmVfc2xvdCB2YWx1ZS4KKyAgaWYgKCF1cGJfc3RydGFibGVfaW5pdCgmc2VsZi0+dGFibGUsIFVQQl9DVFlQRV9VSU5UNjQpKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIkNvdWxkIG5vdCBhbGxvY2F0ZSB0YWJsZS4iKTsKKyAgfQorCisgIGlmIChhcmdjID4gaW5pdF92YWx1ZV9hcmcpIHsKKyAgICBNYXBfbWVyZ2VfaW50b19zZWxmKF9zZWxmLCBhcmd2W2luaXRfdmFsdWVfYXJnXSk7CisgIH0KKworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1hcC5lYWNoKCZibG9jaykKKyAqCisgKiBJbnZva2VzICZibG9jayBvbiBlYWNoIHxrZXksIHZhbHVlfCBwYWlyIGluIHRoZSBtYXAsIGluIHVuc3BlY2lmaWVkIG9yZGVyLgorICogTm90ZSB0aGF0IE1hcCBhbHNvIGluY2x1ZGVzIEVudW1lcmFibGU7IG1hcCB0aHVzIGFjdHMgbGlrZSBhIG5vcm1hbCBSdWJ5CisgKiBzZXF1ZW5jZS4KKyAqLworVkFMVUUgTWFwX2VhY2goVkFMVUUgX3NlbGYpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworCisgIHVwYl9zdHJ0YWJsZV9pdGVyIGl0OworICBmb3IgKHVwYl9zdHJ0YWJsZV9iZWdpbigmaXQsICZzZWxmLT50YWJsZSk7CisgICAgICAgIXVwYl9zdHJ0YWJsZV9kb25lKCZpdCk7CisgICAgICAgdXBiX3N0cnRhYmxlX25leHQoJml0KSkgeworCisgICAgVkFMVUUga2V5ID0gdGFibGVfa2V5X3RvX3J1YnkoCisgICAgICAgIHNlbGYsIHVwYl9zdHJ0YWJsZV9pdGVyX2tleSgmaXQpLCB1cGJfc3RydGFibGVfaXRlcl9rZXlsZW5ndGgoJml0KSk7CisKKyAgICB1cGJfdmFsdWUgdiA9IHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKCZpdCk7CisgICAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgICBWQUxVRSB2YWx1ZSA9IG5hdGl2ZV9zbG90X2dldChzZWxmLT52YWx1ZV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtKTsKKworICAgIHJiX3lpZWxkX3ZhbHVlcygyLCBrZXksIHZhbHVlKTsKKyAgfQorCisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLmtleXMgPT4gW2xpc3Rfb2Zfa2V5c10KKyAqCisgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGtleXMgY29udGFpbmVkIGluIHRoZSBtYXAsIGluIHVuc3BlY2lmaWVkIG9yZGVyLgorICovCitWQUxVRSBNYXBfa2V5cyhWQUxVRSBfc2VsZikgeworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChfc2VsZik7CisKKyAgVkFMVUUgcmV0ID0gcmJfYXJ5X25ldygpOworICB1cGJfc3RydGFibGVfaXRlciBpdDsKKyAgZm9yICh1cGJfc3RydGFibGVfYmVnaW4oJml0LCAmc2VsZi0+dGFibGUpOworICAgICAgICF1cGJfc3RydGFibGVfZG9uZSgmaXQpOworICAgICAgIHVwYl9zdHJ0YWJsZV9uZXh0KCZpdCkpIHsKKworICAgIFZBTFVFIGtleSA9IHRhYmxlX2tleV90b19ydWJ5KAorICAgICAgICBzZWxmLCB1cGJfc3RydGFibGVfaXRlcl9rZXkoJml0KSwgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5bGVuZ3RoKCZpdCkpOworCisgICAgcmJfYXJ5X3B1c2gocmV0LCBrZXkpOworICB9CisKKyAgcmV0dXJuIHJldDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1hcC52YWx1ZXMgPT4gW2xpc3Rfb2ZfdmFsdWVzXQorICoKKyAqIFJldHVybnMgdGhlIGxpc3Qgb2YgdmFsdWVzIGNvbnRhaW5lZCBpbiB0aGUgbWFwLCBpbiB1bnNwZWNpZmllZCBvcmRlci4KKyAqLworVkFMVUUgTWFwX3ZhbHVlcyhWQUxVRSBfc2VsZikgeworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChfc2VsZik7CisKKyAgVkFMVUUgcmV0ID0gcmJfYXJ5X25ldygpOworICB1cGJfc3RydGFibGVfaXRlciBpdDsKKyAgZm9yICh1cGJfc3RydGFibGVfYmVnaW4oJml0LCAmc2VsZi0+dGFibGUpOworICAgICAgICF1cGJfc3RydGFibGVfZG9uZSgmaXQpOworICAgICAgIHVwYl9zdHJ0YWJsZV9uZXh0KCZpdCkpIHsKKworICAgIHVwYl92YWx1ZSB2ID0gdXBiX3N0cnRhYmxlX2l0ZXJfdmFsdWUoJml0KTsKKyAgICB2b2lkKiBtZW0gPSB2YWx1ZV9tZW1vcnkoJnYpOworICAgIFZBTFVFIHZhbHVlID0gbmF0aXZlX3Nsb3RfZ2V0KHNlbGYtPnZhbHVlX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+dmFsdWVfdHlwZV9jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW0pOworCisgICAgcmJfYXJ5X3B1c2gocmV0LCB2YWx1ZSk7CisgIH0KKworICByZXR1cm4gcmV0OworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLltdKGtleSkgPT4gdmFsdWUKKyAqCisgKiBBY2Nlc3NlcyB0aGUgZWxlbWVudCBhdCB0aGUgZ2l2ZW4ga2V5LiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSBrZXkgdHlwZSBpcworICogaW5jb3JyZWN0LiBSZXR1cm5zIG5pbCB3aGVuIHRoZSBrZXkgaXMgbm90IHByZXNlbnQgaW4gdGhlIG1hcC4KKyAqLworVkFMVUUgTWFwX2luZGV4KFZBTFVFIF9zZWxmLCBWQUxVRSBrZXkpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworCisgIGNoYXIga2V5YnVmW1RBQkxFX0tFWV9CVUZfTEVOR1RIXTsKKyAgY29uc3QgY2hhcioga2V5dmFsID0gTlVMTDsKKyAgc2l6ZV90IGxlbmd0aCA9IDA7CisgIHRhYmxlX2tleShzZWxmLCBrZXksIGtleWJ1ZiwgJmtleXZhbCwgJmxlbmd0aCk7CisKKyAgdXBiX3ZhbHVlIHY7CisgIGlmICh1cGJfc3RydGFibGVfbG9va3VwMigmc2VsZi0+dGFibGUsIGtleXZhbCwgbGVuZ3RoLCAmdikpIHsKKyAgICB2b2lkKiBtZW0gPSB2YWx1ZV9tZW1vcnkoJnYpOworICAgIHJldHVybiBuYXRpdmVfc2xvdF9nZXQoc2VsZi0+dmFsdWVfdHlwZSwgc2VsZi0+dmFsdWVfdHlwZV9jbGFzcywgbWVtKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gUW5pbDsKKyAgfQorfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLltdPShrZXksIHZhbHVlKSA9PiB2YWx1ZQorICoKKyAqIEluc2VydHMgb3Igb3ZlcndyaXRlcyB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGtleSB3aXRoIHRoZSBnaXZlbiBuZXcgdmFsdWUuCisgKiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSBrZXkgdHlwZSBpcyBpbmNvcnJlY3QuIFJldHVybnMgdGhlIG5ldyB2YWx1ZSB0aGF0CisgKiB3YXMganVzdCBpbnNlcnRlZC4KKyAqLworVkFMVUUgTWFwX2luZGV4X3NldChWQUxVRSBfc2VsZiwgVkFMVUUga2V5LCBWQUxVRSB2YWx1ZSkgeworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChfc2VsZik7CisKKyAgY2hhciBrZXlidWZbVEFCTEVfS0VZX0JVRl9MRU5HVEhdOworICBjb25zdCBjaGFyKiBrZXl2YWwgPSBOVUxMOworICBzaXplX3QgbGVuZ3RoID0gMDsKKyAgdGFibGVfa2V5KHNlbGYsIGtleSwga2V5YnVmLCAma2V5dmFsLCAmbGVuZ3RoKTsKKworICB1cGJfdmFsdWUgdjsKKyAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgbmF0aXZlX3Nsb3Rfc2V0KHNlbGYtPnZhbHVlX3R5cGUsIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MsIG1lbSwgdmFsdWUpOworCisgIC8vIFJlcGxhY2UgYW55IGV4aXN0aW5nIHZhbHVlIGJ5IGlzc3VpbmcgYSAncmVtb3ZlJyBvcGVyYXRpb24gZmlyc3QuCisgIHVwYl9zdHJ0YWJsZV9yZW1vdmUyKCZzZWxmLT50YWJsZSwga2V5dmFsLCBsZW5ndGgsIE5VTEwpOworICBpZiAoIXVwYl9zdHJ0YWJsZV9pbnNlcnQyKCZzZWxmLT50YWJsZSwga2V5dmFsLCBsZW5ndGgsIHYpKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIkNvdWxkIG5vdCBpbnNlcnQgaW50byB0YWJsZSIpOworICB9CisKKyAgLy8gUnVieSBoYXNobWFwJ3MgOltdPSBtZXRob2QgYWxzbyByZXR1cm5zIHRoZSBpbnNlcnRlZCB2YWx1ZS4KKyAgcmV0dXJuIHZhbHVlOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLmhhc19rZXk/KGtleSkgPT4gYm9vbAorICoKKyAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4ga2V5IGlzIHByZXNlbnQgaW4gdGhlIG1hcC4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZgorICogdGhlIGtleSBoYXMgdGhlIHdyb25nIHR5cGUuCisgKi8KK1ZBTFVFIE1hcF9oYXNfa2V5KFZBTFVFIF9zZWxmLCBWQUxVRSBrZXkpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworCisgIGNoYXIga2V5YnVmW1RBQkxFX0tFWV9CVUZfTEVOR1RIXTsKKyAgY29uc3QgY2hhcioga2V5dmFsID0gTlVMTDsKKyAgc2l6ZV90IGxlbmd0aCA9IDA7CisgIHRhYmxlX2tleShzZWxmLCBrZXksIGtleWJ1ZiwgJmtleXZhbCwgJmxlbmd0aCk7CisKKyAgaWYgKHVwYl9zdHJ0YWJsZV9sb29rdXAyKCZzZWxmLT50YWJsZSwga2V5dmFsLCBsZW5ndGgsIE5VTEwpKSB7CisgICAgcmV0dXJuIFF0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBRZmFsc2U7CisgIH0KK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1hcC5kZWxldGUoa2V5KSA9PiBvbGRfdmFsdWUKKyAqCisgKiBEZWxldGVzIHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4ga2V5LCBpZiBhbnksIHJldHVybmluZyBlaXRoZXIgdGhlIG9sZCB2YWx1ZSBvcgorICogbmlsIGlmIG5vbmUgd2FzIHByZXNlbnQuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIGtleSBpcyBvZiB0aGUgd3JvbmcgdHlwZS4KKyAqLworVkFMVUUgTWFwX2RlbGV0ZShWQUxVRSBfc2VsZiwgVkFMVUUga2V5KSB7CisgIE1hcCogc2VsZiA9IHJ1YnlfdG9fTWFwKF9zZWxmKTsKKworICBjaGFyIGtleWJ1ZltUQUJMRV9LRVlfQlVGX0xFTkdUSF07CisgIGNvbnN0IGNoYXIqIGtleXZhbCA9IE5VTEw7CisgIHNpemVfdCBsZW5ndGggPSAwOworICB0YWJsZV9rZXkoc2VsZiwga2V5LCBrZXlidWYsICZrZXl2YWwsICZsZW5ndGgpOworCisgIHVwYl92YWx1ZSB2OworICBpZiAodXBiX3N0cnRhYmxlX3JlbW92ZTIoJnNlbGYtPnRhYmxlLCBrZXl2YWwsIGxlbmd0aCwgJnYpKSB7CisgICAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgICByZXR1cm4gbmF0aXZlX3Nsb3RfZ2V0KHNlbGYtPnZhbHVlX3R5cGUsIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MsIG1lbSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFFuaWw7CisgIH0KK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1hcC5jbGVhcgorICoKKyAqIFJlbW92ZXMgYWxsIGVudHJpZXMgZnJvbSB0aGUgbWFwLgorICovCitWQUxVRSBNYXBfY2xlYXIoVkFMVUUgX3NlbGYpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworCisgIC8vIFVuaW5pdCBhbmQgcmVpbml0IHRoZSB0YWJsZSAtLSB0aGlzIGlzIGZhc3RlciB0aGFuIGl0ZXJhdGluZyBhbmQgZG9pbmcgYQorICAvLyBkZWxldGUtbG9va3VwIG9uIGVhY2gga2V5LgorICB1cGJfc3RydGFibGVfdW5pbml0KCZzZWxmLT50YWJsZSk7CisgIGlmICghdXBiX3N0cnRhYmxlX2luaXQoJnNlbGYtPnRhYmxlLCBVUEJfQ1RZUEVfSU5UNjQpKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIlVuYWJsZSB0byByZS1pbml0aWFsaXplIHRhYmxlIik7CisgIH0KKyAgcmV0dXJuIFFuaWw7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBNYXAubGVuZ3RoCisgKgorICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVudHJpZXMgKGtleS12YWx1ZSBwYWlycykgaW4gdGhlIG1hcC4KKyAqLworVkFMVUUgTWFwX2xlbmd0aChWQUxVRSBfc2VsZikgeworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChfc2VsZik7CisgIHJldHVybiBVTEwyTlVNKHVwYl9zdHJ0YWJsZV9jb3VudCgmc2VsZi0+dGFibGUpKTsKK30KKworc3RhdGljIFZBTFVFIE1hcF9uZXdfdGhpc190eXBlKFZBTFVFIF9zZWxmKSB7CisgIE1hcCogc2VsZiA9IHJ1YnlfdG9fTWFwKF9zZWxmKTsKKyAgVkFMVUUgbmV3X21hcCA9IFFuaWw7CisgIFZBTFVFIGtleV90eXBlID0gZmllbGR0eXBlX3RvX3J1Ynkoc2VsZi0+a2V5X3R5cGUpOworICBWQUxVRSB2YWx1ZV90eXBlID0gZmllbGR0eXBlX3RvX3J1Ynkoc2VsZi0+dmFsdWVfdHlwZSk7CisgIGlmIChzZWxmLT52YWx1ZV90eXBlX2NsYXNzICE9IFFuaWwpIHsKKyAgICBuZXdfbWFwID0gcmJfZnVuY2FsbChDTEFTU19PRihfc2VsZiksIHJiX2ludGVybigibmV3IiksIDMsCisgICAgICAgICAgICAgICAgICAgICAgICAga2V5X3R5cGUsIHZhbHVlX3R5cGUsIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MpOworICB9IGVsc2UgeworICAgIG5ld19tYXAgPSByYl9mdW5jYWxsKENMQVNTX09GKF9zZWxmKSwgcmJfaW50ZXJuKCJuZXciKSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfdHlwZSwgdmFsdWVfdHlwZSk7CisgIH0KKyAgcmV0dXJuIG5ld19tYXA7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBNYXAuZHVwID0+IG5ld19tYXAKKyAqCisgKiBEdXBsaWNhdGVzIHRoaXMgbWFwIHdpdGggYSBzaGFsbG93IGNvcHkuIFJlZmVyZW5jZXMgdG8gYWxsIG5vbi1wcmltaXRpdmUKKyAqIGVsZW1lbnQgb2JqZWN0cyAoZS5nLiwgc3VibWVzc2FnZXMpIGFyZSBzaGFyZWQuCisgKi8KK1ZBTFVFIE1hcF9kdXAoVkFMVUUgX3NlbGYpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworICBWQUxVRSBuZXdfbWFwID0gTWFwX25ld190aGlzX3R5cGUoX3NlbGYpOworICBNYXAqIG5ld19zZWxmID0gcnVieV90b19NYXAobmV3X21hcCk7CisKKyAgdXBiX3N0cnRhYmxlX2l0ZXIgaXQ7CisgIGZvciAodXBiX3N0cnRhYmxlX2JlZ2luKCZpdCwgJnNlbGYtPnRhYmxlKTsKKyAgICAgICAhdXBiX3N0cnRhYmxlX2RvbmUoJml0KTsKKyAgICAgICB1cGJfc3RydGFibGVfbmV4dCgmaXQpKSB7CisKKyAgICB1cGJfdmFsdWUgdiA9IHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKCZpdCk7CisgICAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgICB1cGJfdmFsdWUgZHVwOworICAgIHZvaWQqIGR1cF9tZW0gPSB2YWx1ZV9tZW1vcnkoJmR1cCk7CisgICAgbmF0aXZlX3Nsb3RfZHVwKHNlbGYtPnZhbHVlX3R5cGUsIGR1cF9tZW0sIG1lbSk7CisKKyAgICBpZiAoIXVwYl9zdHJ0YWJsZV9pbnNlcnQyKCZuZXdfc2VsZi0+dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RydGFibGVfaXRlcl9rZXkoJml0KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX2tleWxlbmd0aCgmaXQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwKSkgeworICAgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIkVycm9yIGluc2VydGluZyB2YWx1ZSBpbnRvIG5ldyB0YWJsZSIpOworICAgIH0KKyAgfQorCisgIHJldHVybiBuZXdfbWFwOworfQorCisvLyBVc2VkIGJ5IEdvb2dsZTo6UHJvdG9idWYuZGVlcF9jb3B5IGJ1dCBub3QgZXhwb3NlZCBkaXJlY3RseS4KK1ZBTFVFIE1hcF9kZWVwX2NvcHkoVkFMVUUgX3NlbGYpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworICBWQUxVRSBuZXdfbWFwID0gTWFwX25ld190aGlzX3R5cGUoX3NlbGYpOworICBNYXAqIG5ld19zZWxmID0gcnVieV90b19NYXAobmV3X21hcCk7CisKKyAgdXBiX3N0cnRhYmxlX2l0ZXIgaXQ7CisgIGZvciAodXBiX3N0cnRhYmxlX2JlZ2luKCZpdCwgJnNlbGYtPnRhYmxlKTsKKyAgICAgICAhdXBiX3N0cnRhYmxlX2RvbmUoJml0KTsKKyAgICAgICB1cGJfc3RydGFibGVfbmV4dCgmaXQpKSB7CisKKyAgICB1cGJfdmFsdWUgdiA9IHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKCZpdCk7CisgICAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgICB1cGJfdmFsdWUgZHVwOworICAgIHZvaWQqIGR1cF9tZW0gPSB2YWx1ZV9tZW1vcnkoJmR1cCk7CisgICAgbmF0aXZlX3Nsb3RfZGVlcF9jb3B5KHNlbGYtPnZhbHVlX3R5cGUsIGR1cF9tZW0sIG1lbSk7CisKKyAgICBpZiAoIXVwYl9zdHJ0YWJsZV9pbnNlcnQyKCZuZXdfc2VsZi0+dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RydGFibGVfaXRlcl9rZXkoJml0KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX2tleWxlbmd0aCgmaXQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwKSkgeworICAgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIkVycm9yIGluc2VydGluZyB2YWx1ZSBpbnRvIG5ldyB0YWJsZSIpOworICAgIH0KKyAgfQorCisgIHJldHVybiBuZXdfbWFwOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLj09KG90aGVyKSA9PiBib29sZWFuCisgKgorICogQ29tcGFyZXMgdGhpcyBtYXAgdG8gYW5vdGhlci4gTWFwcyBhcmUgZXF1YWwgaWYgdGhleSBoYXZlIGlkZW50aWNhbCBrZXkgc2V0cywKKyAqIGFuZCBmb3IgZWFjaCBrZXksIHRoZSB2YWx1ZXMgaW4gYm90aCBtYXBzIGNvbXBhcmUgZXF1YWwuIEVsZW1lbnRzIGFyZQorICogY29tcGFyZWQgYXMgcGVyIG5vcm1hbCBSdWJ5IHNlbWFudGljcywgYnkgY2FsbGluZyB0aGVpciA6PT0gbWV0aG9kcyAob3IKKyAqIHBlcmZvcm1pbmcgYSBtb3JlIGVmZmljaWVudCBjb21wYXJpc29uIGZvciBwcmltaXRpdmUgdHlwZXMpLgorICoKKyAqIE1hcHMgd2l0aCBkaXNzaW1pbGFyIGtleSB0eXBlcyBvciB2YWx1ZSB0eXBlcy90eXBlY2xhc3NlcyBhcmUgbmV2ZXIgZXF1YWwsCisgKiBldmVuIGlmIHZhbHVlIGNvbXBhcmlzb24gKGZvciBleGFtcGxlLCBiZXR3ZWVuIGludGVnZXJzIGFuZCBmbG9hdHMpIHdvdWxkCisgKiBoYXZlIG90aGVyd2lzZSBpbmRpY2F0ZWQgdGhhdCBldmVyeSBlbGVtZW50IGhhcyBlcXVhbCB2YWx1ZS4KKyAqLworVkFMVUUgTWFwX2VxKFZBTFVFIF9zZWxmLCBWQUxVRSBfb3RoZXIpIHsKKyAgTWFwKiBzZWxmID0gcnVieV90b19NYXAoX3NlbGYpOworCisgIC8vIEFsbG93IGNvbXBhcmlzb25zIHRvIFJ1YnkgaGFzaG1hcHMgYnkgY29udmVydGluZyB0byBhIHRlbXBvcmFyeSBNYXAKKyAgLy8gaW5zdGFuY2UuIFNsb3csIGJ1dCB3b3JrYWJsZS4KKyAgaWYgKFRZUEUoX290aGVyKSA9PSBUX0hBU0gpIHsKKyAgICBWQUxVRSBvdGhlcl9tYXAgPSBNYXBfbmV3X3RoaXNfdHlwZShfc2VsZik7CisgICAgTWFwX21lcmdlX2ludG9fc2VsZihvdGhlcl9tYXAsIF9vdGhlcik7CisgICAgX290aGVyID0gb3RoZXJfbWFwOworICB9CisKKyAgTWFwKiBvdGhlciA9IHJ1YnlfdG9fTWFwKF9vdGhlcik7CisKKyAgaWYgKHNlbGYgPT0gb3RoZXIpIHsKKyAgICByZXR1cm4gUXRydWU7CisgIH0KKyAgaWYgKHNlbGYtPmtleV90eXBlICE9IG90aGVyLT5rZXlfdHlwZSB8fAorICAgICAgc2VsZi0+dmFsdWVfdHlwZSAhPSBvdGhlci0+dmFsdWVfdHlwZSB8fAorICAgICAgc2VsZi0+dmFsdWVfdHlwZV9jbGFzcyAhPSBvdGhlci0+dmFsdWVfdHlwZV9jbGFzcykgeworICAgIHJldHVybiBRZmFsc2U7CisgIH0KKyAgaWYgKHVwYl9zdHJ0YWJsZV9jb3VudCgmc2VsZi0+dGFibGUpICE9IHVwYl9zdHJ0YWJsZV9jb3VudCgmb3RoZXItPnRhYmxlKSkgeworICAgIHJldHVybiBRZmFsc2U7CisgIH0KKworICAvLyBGb3IgZWFjaCBtZW1iZXIgb2Ygc2VsZiwgY2hlY2sgdGhhdCBhbiBlcXVhbCBtZW1iZXIgZXhpc3RzIGF0IHRoZSBzYW1lIGtleQorICAvLyBpbiBvdGhlci4KKyAgdXBiX3N0cnRhYmxlX2l0ZXIgaXQ7CisgIGZvciAodXBiX3N0cnRhYmxlX2JlZ2luKCZpdCwgJnNlbGYtPnRhYmxlKTsKKyAgICAgICAhdXBiX3N0cnRhYmxlX2RvbmUoJml0KTsKKyAgICAgICB1cGJfc3RydGFibGVfbmV4dCgmaXQpKSB7CisKKyAgICB1cGJfdmFsdWUgdiA9IHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKCZpdCk7CisgICAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgICB1cGJfdmFsdWUgb3RoZXJfdjsKKyAgICB2b2lkKiBvdGhlcl9tZW0gPSB2YWx1ZV9tZW1vcnkoJm90aGVyX3YpOworCisgICAgaWYgKCF1cGJfc3RydGFibGVfbG9va3VwMigmb3RoZXItPnRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5KCZpdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RydGFibGVfaXRlcl9rZXlsZW5ndGgoJml0KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvdGhlcl92KSkgeworICAgICAgLy8gTm90IHByZXNlbnQgaW4gb3RoZXIgbWFwLgorICAgICAgcmV0dXJuIFFmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIW5hdGl2ZV9zbG90X2VxKHNlbGYtPnZhbHVlX3R5cGUsIG1lbSwgb3RoZXJfbWVtKSkgeworICAgICAgLy8gUHJlc2VudCwgYnV0IHZhbHVlIG5vdCBlcXVhbC4KKyAgICAgIHJldHVybiBRZmFsc2U7CisgICAgfQorICB9CisKKyAgcmV0dXJuIFF0cnVlOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWFwLmhhc2ggPT4gaGFzaF92YWx1ZQorICoKKyAqIFJldHVybnMgYSBoYXNoIHZhbHVlIGJhc2VkIG9uIHRoaXMgbWFwJ3MgY29udGVudHMuCisgKi8KK1ZBTFVFIE1hcF9oYXNoKFZBTFVFIF9zZWxmKSB7CisgIE1hcCogc2VsZiA9IHJ1YnlfdG9fTWFwKF9zZWxmKTsKKworICBzdF9pbmRleF90IGggPSByYl9oYXNoX3N0YXJ0KDApOworICBWQUxVRSBoYXNoX3N5bSA9IHJiX2ludGVybigiaGFzaCIpOworCisgIHVwYl9zdHJ0YWJsZV9pdGVyIGl0OworICBmb3IgKHVwYl9zdHJ0YWJsZV9iZWdpbigmaXQsICZzZWxmLT50YWJsZSk7CisgICAgICAgIXVwYl9zdHJ0YWJsZV9kb25lKCZpdCk7CisgICAgICAgdXBiX3N0cnRhYmxlX25leHQoJml0KSkgeworICAgIFZBTFVFIGtleSA9IHRhYmxlX2tleV90b19ydWJ5KAorICAgICAgICBzZWxmLCB1cGJfc3RydGFibGVfaXRlcl9rZXkoJml0KSwgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5bGVuZ3RoKCZpdCkpOworCisgICAgdXBiX3ZhbHVlIHYgPSB1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaXQpOworICAgIHZvaWQqIG1lbSA9IHZhbHVlX21lbW9yeSgmdik7CisgICAgVkFMVUUgdmFsdWUgPSBuYXRpdmVfc2xvdF9nZXQoc2VsZi0+dmFsdWVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT52YWx1ZV90eXBlX2NsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbSk7CisKKyAgICBoID0gcmJfaGFzaF91aW50KGgsIE5VTTJMT05HKHJiX2Z1bmNhbGwoa2V5LCBoYXNoX3N5bSwgMCkpKTsKKyAgICBoID0gcmJfaGFzaF91aW50KGgsIE5VTTJMT05HKHJiX2Z1bmNhbGwodmFsdWUsIGhhc2hfc3ltLCAwKSkpOworICB9CisKKyAgcmV0dXJuIElOVDJGSVgoaCk7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBNYXAuaW5zcGVjdCA9PiBzdHJpbmcKKyAqCisgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGlzIG1hcCdzIGVsZW1lbnRzLiBJdCB3aWxsIGJlIGZvcm1hdHRlZCBhcworICogIntrZXkgPT4gdmFsdWUsIGtleSA9PiB2YWx1ZSwgLi4ufSIsIHdpdGggZWFjaCBrZXkgYW5kIHZhbHVlIHN0cmluZworICogcmVwcmVzZW50YXRpb24gY29tcHV0ZWQgYnkgaXRzIG93biAjaW5zcGVjdCBtZXRob2QuCisgKi8KK1ZBTFVFIE1hcF9pbnNwZWN0KFZBTFVFIF9zZWxmKSB7CisgIE1hcCogc2VsZiA9IHJ1YnlfdG9fTWFwKF9zZWxmKTsKKworICBWQUxVRSBzdHIgPSByYl9zdHJfbmV3MigieyIpOworCisgIGJvb2wgZmlyc3QgPSB0cnVlOworICBWQUxVRSBpbnNwZWN0X3N5bSA9IHJiX2ludGVybigiaW5zcGVjdCIpOworCisgIHVwYl9zdHJ0YWJsZV9pdGVyIGl0OworICBmb3IgKHVwYl9zdHJ0YWJsZV9iZWdpbigmaXQsICZzZWxmLT50YWJsZSk7CisgICAgICAgIXVwYl9zdHJ0YWJsZV9kb25lKCZpdCk7CisgICAgICAgdXBiX3N0cnRhYmxlX25leHQoJml0KSkgeworICAgIFZBTFVFIGtleSA9IHRhYmxlX2tleV90b19ydWJ5KAorICAgICAgICBzZWxmLCB1cGJfc3RydGFibGVfaXRlcl9rZXkoJml0KSwgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5bGVuZ3RoKCZpdCkpOworCisgICAgdXBiX3ZhbHVlIHYgPSB1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaXQpOworICAgIHZvaWQqIG1lbSA9IHZhbHVlX21lbW9yeSgmdik7CisgICAgVkFMVUUgdmFsdWUgPSBuYXRpdmVfc2xvdF9nZXQoc2VsZi0+dmFsdWVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT52YWx1ZV90eXBlX2NsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbSk7CisKKyAgICBpZiAoIWZpcnN0KSB7CisgICAgICBzdHIgPSByYl9zdHJfY2F0MihzdHIsICIsICIpOworICAgIH0gZWxzZSB7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgIH0KKyAgICBzdHIgPSByYl9zdHJfYXBwZW5kKHN0ciwgcmJfZnVuY2FsbChrZXksIGluc3BlY3Rfc3ltLCAwKSk7CisgICAgc3RyID0gcmJfc3RyX2NhdDIoc3RyLCAiPT4iKTsKKyAgICBzdHIgPSByYl9zdHJfYXBwZW5kKHN0ciwgcmJfZnVuY2FsbCh2YWx1ZSwgaW5zcGVjdF9zeW0sIDApKTsKKyAgfQorCisgIHN0ciA9IHJiX3N0cl9jYXQyKHN0ciwgIn0iKTsKKyAgcmV0dXJuIHN0cjsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1hcC5tZXJnZShvdGhlcl9tYXApID0+IG1hcAorICoKKyAqIENvcGllcyBrZXkvdmFsdWUgcGFpcnMgZnJvbSBvdGhlcl9tYXAgaW50byBhIGNvcHkgb2YgdGhpcyBtYXAuIElmIGEga2V5IGlzCisgKiBzZXQgaW4gb3RoZXJfbWFwIGFuZCB0aGlzIG1hcCwgdGhlIHZhbHVlIGZyb20gb3RoZXJfbWFwIG92ZXJ3cml0ZXMgdGhlIHZhbHVlCisgKiBpbiB0aGUgbmV3IGNvcHkgb2YgdGhpcyBtYXAuIFJldHVybnMgdGhlIG5ldyBjb3B5IG9mIHRoaXMgbWFwIHdpdGggbWVyZ2VkCisgKiBjb250ZW50cy4KKyAqLworVkFMVUUgTWFwX21lcmdlKFZBTFVFIF9zZWxmLCBWQUxVRSBoYXNobWFwKSB7CisgIFZBTFVFIGR1cHBlZCA9IE1hcF9kdXAoX3NlbGYpOworICByZXR1cm4gTWFwX21lcmdlX2ludG9fc2VsZihkdXBwZWQsIGhhc2htYXApOworfQorCitzdGF0aWMgaW50IG1lcmdlX2ludG9fc2VsZl9jYWxsYmFjayhWQUxVRSBrZXksIFZBTFVFIHZhbHVlLCBWQUxVRSBzZWxmKSB7CisgIE1hcF9pbmRleF9zZXQoc2VsZiwga2V5LCB2YWx1ZSk7CisgIHJldHVybiBTVF9DT05USU5VRTsKK30KKworLy8gVXNlZCBvbmx5IGludGVybmFsbHkgLS0gc2hhcmVkIGJ5ICNtZXJnZSBhbmQgI2luaXRpYWxpemUuCitWQUxVRSBNYXBfbWVyZ2VfaW50b19zZWxmKFZBTFVFIF9zZWxmLCBWQUxVRSBoYXNobWFwKSB7CisgIGlmIChUWVBFKGhhc2htYXApID09IFRfSEFTSCkgeworICAgIHJiX2hhc2hfZm9yZWFjaChoYXNobWFwLCBtZXJnZV9pbnRvX3NlbGZfY2FsbGJhY2ssIF9zZWxmKTsKKyAgfSBlbHNlIGlmIChSQl9UWVBFX1AoaGFzaG1hcCwgVF9EQVRBKSAmJiBSVFlQRUREQVRBX1AoaGFzaG1hcCkgJiYKKyAgICAgICAgICAgICBSVFlQRUREQVRBX1RZUEUoaGFzaG1hcCkgPT0gJk1hcF90eXBlKSB7CisKKyAgICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChfc2VsZik7CisgICAgTWFwKiBvdGhlciA9IHJ1YnlfdG9fTWFwKGhhc2htYXApOworCisgICAgaWYgKHNlbGYtPmtleV90eXBlICE9IG90aGVyLT5rZXlfdHlwZSB8fAorICAgICAgICBzZWxmLT52YWx1ZV90eXBlICE9IG90aGVyLT52YWx1ZV90eXBlIHx8CisgICAgICAgIHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MgIT0gb3RoZXItPnZhbHVlX3R5cGVfY2xhc3MpIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkF0dGVtcHQgdG8gbWVyZ2UgTWFwIHdpdGggbWlzbWF0Y2hpbmcgdHlwZXMiKTsKKyAgICB9CisKKyAgICB1cGJfc3RydGFibGVfaXRlciBpdDsKKyAgICBmb3IgKHVwYl9zdHJ0YWJsZV9iZWdpbigmaXQsICZvdGhlci0+dGFibGUpOworICAgICAgICAgIXVwYl9zdHJ0YWJsZV9kb25lKCZpdCk7CisgICAgICAgICB1cGJfc3RydGFibGVfbmV4dCgmaXQpKSB7CisKKyAgICAgIC8vIFJlcGxhY2UgYW55IGV4aXN0aW5nIHZhbHVlIGJ5IGlzc3VpbmcgYSAncmVtb3ZlJyBvcGVyYXRpb24gZmlyc3QuCisgICAgICB1cGJfdmFsdWUgb2xkdjsKKyAgICAgIHVwYl9zdHJ0YWJsZV9yZW1vdmUyKCZzZWxmLT50YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX2tleSgmaXQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5bGVuZ3RoKCZpdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2xkdik7CisKKyAgICAgIHVwYl92YWx1ZSB2ID0gdXBiX3N0cnRhYmxlX2l0ZXJfdmFsdWUoJml0KTsKKyAgICAgIHVwYl9zdHJ0YWJsZV9pbnNlcnQyKCZzZWxmLT50YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX2tleSgmaXQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5bGVuZ3RoKCZpdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICB2KTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiVW5rbm93biB0eXBlIG1lcmdpbmcgaW50byBNYXAiKTsKKyAgfQorICByZXR1cm4gX3NlbGY7Cit9CisKKy8vIEludGVybmFsIG1ldGhvZDogbWFwIGl0ZXJhdG9yIGluaXRpYWxpemF0aW9uICh1c2VkIGZvciBzZXJpYWxpemF0aW9uKS4KK3ZvaWQgTWFwX2JlZ2luKFZBTFVFIF9zZWxmLCBNYXBfaXRlciogaXRlcikgeworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcChfc2VsZik7CisgIGl0ZXItPnNlbGYgPSBzZWxmOworICB1cGJfc3RydGFibGVfYmVnaW4oJml0ZXItPml0LCAmc2VsZi0+dGFibGUpOworfQorCit2b2lkIE1hcF9uZXh0KE1hcF9pdGVyKiBpdGVyKSB7CisgIHVwYl9zdHJ0YWJsZV9uZXh0KCZpdGVyLT5pdCk7Cit9CisKK2Jvb2wgTWFwX2RvbmUoTWFwX2l0ZXIqIGl0ZXIpIHsKKyAgcmV0dXJuIHVwYl9zdHJ0YWJsZV9kb25lKCZpdGVyLT5pdCk7Cit9CisKK1ZBTFVFIE1hcF9pdGVyX2tleShNYXBfaXRlciogaXRlcikgeworICByZXR1cm4gdGFibGVfa2V5X3RvX3J1YnkoCisgICAgICBpdGVyLT5zZWxmLAorICAgICAgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5KCZpdGVyLT5pdCksCisgICAgICB1cGJfc3RydGFibGVfaXRlcl9rZXlsZW5ndGgoJml0ZXItPml0KSk7Cit9CisKK1ZBTFVFIE1hcF9pdGVyX3ZhbHVlKE1hcF9pdGVyKiBpdGVyKSB7CisgIHVwYl92YWx1ZSB2ID0gdXBiX3N0cnRhYmxlX2l0ZXJfdmFsdWUoJml0ZXItPml0KTsKKyAgdm9pZCogbWVtID0gdmFsdWVfbWVtb3J5KCZ2KTsKKyAgcmV0dXJuIG5hdGl2ZV9zbG90X2dldChpdGVyLT5zZWxmLT52YWx1ZV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXItPnNlbGYtPnZhbHVlX3R5cGVfY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgbWVtKTsKK30KKwordm9pZCBNYXBfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKSB7CisgIFZBTFVFIGtsYXNzID0gcmJfZGVmaW5lX2NsYXNzX3VuZGVyKG1vZHVsZSwgIk1hcCIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgTWFwX2FsbG9jKTsKKyAgY01hcCA9IGtsYXNzOworICByYl9nY19yZWdpc3Rlcl9hZGRyZXNzKCZjTWFwKTsKKworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiaW5pdGlhbGl6ZSIsIE1hcF9pbml0LCAtMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJlYWNoIiwgTWFwX2VhY2gsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAia2V5cyIsIE1hcF9rZXlzLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgInZhbHVlcyIsIE1hcF92YWx1ZXMsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiW10iLCBNYXBfaW5kZXgsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiW109IiwgTWFwX2luZGV4X3NldCwgMik7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJoYXNfa2V5PyIsIE1hcF9oYXNfa2V5LCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImRlbGV0ZSIsIE1hcF9kZWxldGUsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiY2xlYXIiLCBNYXBfY2xlYXIsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibGVuZ3RoIiwgTWFwX2xlbmd0aCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJkdXAiLCBNYXBfZHVwLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIj09IiwgTWFwX2VxLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImhhc2giLCBNYXBfaGFzaCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJpbnNwZWN0IiwgTWFwX2luc3BlY3QsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAibWVyZ2UiLCBNYXBfbWVyZ2UsIDEpOworICByYl9pbmNsdWRlX21vZHVsZShrbGFzcywgcmJfbUVudW1lcmFibGUpOworfQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvbWVzc2FnZS5jIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvbWVzc2FnZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlNThhNjEKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9tZXNzYWdlLmMKQEAgLTAsMCArMSw1MTYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSAicHJvdG9idWYuaCIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIENsYXNzL21vZHVsZSBjcmVhdGlvbiBmcm9tIG1zZ2RlZnMgYW5kIGVudW1kZWZzLCByZXNwZWN0aXZlbHkuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkKiBNZXNzYWdlX2RhdGEodm9pZCogbXNnKSB7CisgIHJldHVybiAoKHVpbnQ4X3QgKiltc2cpICsgc2l6ZW9mKE1lc3NhZ2VIZWFkZXIpOworfQorCit2b2lkIE1lc3NhZ2VfbWFyayh2b2lkKiBfc2VsZikgeworICBNZXNzYWdlSGVhZGVyKiBzZWxmID0gKE1lc3NhZ2VIZWFkZXIgKilfc2VsZjsKKyAgbGF5b3V0X21hcmsoc2VsZi0+ZGVzY3JpcHRvci0+bGF5b3V0LCBNZXNzYWdlX2RhdGEoc2VsZikpOworfQorCit2b2lkIE1lc3NhZ2VfZnJlZSh2b2lkKiBzZWxmKSB7CisgIHhmcmVlKHNlbGYpOworfQorCityYl9kYXRhX3R5cGVfdCBNZXNzYWdlX3R5cGUgPSB7CisgICJNZXNzYWdlIiwKKyAgeyBNZXNzYWdlX21hcmssIE1lc3NhZ2VfZnJlZSwgTlVMTCB9LAorfTsKKworVkFMVUUgTWVzc2FnZV9hbGxvYyhWQUxVRSBrbGFzcykgeworICBWQUxVRSBkZXNjcmlwdG9yID0gcmJfaXZfZ2V0KGtsYXNzLCBrRGVzY3JpcHRvckluc3RhbmNlVmFyKTsKKyAgRGVzY3JpcHRvciogZGVzYyA9IHJ1YnlfdG9fRGVzY3JpcHRvcihkZXNjcmlwdG9yKTsKKyAgTWVzc2FnZUhlYWRlciogbXNnID0gKE1lc3NhZ2VIZWFkZXIqKUFMTE9DX04oCisgICAgICB1aW50OF90LCBzaXplb2YoTWVzc2FnZUhlYWRlcikgKyBkZXNjLT5sYXlvdXQtPnNpemUpOworICBtZW1zZXQoTWVzc2FnZV9kYXRhKG1zZyksIDAsIGRlc2MtPmxheW91dC0+c2l6ZSk7CisKKyAgLy8gV2Ugd3JhcCBmaXJzdCBzbyB0aGF0IGV2ZXJ5dGhpbmcgaW4gdGhlIG1lc3NhZ2Ugb2JqZWN0IGlzIEdDLXJvb3RlZCBpbiBjYXNlCisgIC8vIGEgY29sbGVjdGlvbiBoYXBwZW5zIGR1cmluZyBvYmplY3QgY3JlYXRpb24gaW4gbGF5b3V0X2luaXQoKS4KKyAgVkFMVUUgcmV0ID0gVHlwZWREYXRhX1dyYXBfU3RydWN0KGtsYXNzLCAmTWVzc2FnZV90eXBlLCBtc2cpOworICBtc2ctPmRlc2NyaXB0b3IgPSBkZXNjOworICByYl9pdl9zZXQocmV0LCBrRGVzY3JpcHRvckluc3RhbmNlVmFyLCBkZXNjcmlwdG9yKTsKKworICBsYXlvdXRfaW5pdChkZXNjLT5sYXlvdXQsIE1lc3NhZ2VfZGF0YShtc2cpKTsKKworICByZXR1cm4gcmV0OworfQorCitzdGF0aWMgVkFMVUUgd2hpY2hfb25lb2ZfZmllbGQoTWVzc2FnZUhlYWRlciogc2VsZiwgY29uc3QgdXBiX29uZW9mZGVmKiBvKSB7CisgIC8vIElmIG5vIGZpZWxkcyBpbiB0aGUgb25lb2YsIGFsd2F5cyBuaWwuCisgIGlmICh1cGJfb25lb2ZkZWZfbnVtZmllbGRzKG8pID09IDApIHsKKyAgICByZXR1cm4gUW5pbDsKKyAgfQorICAvLyBHcmFiIHRoZSBmaXJzdCBmaWVsZCBpbiB0aGUgb25lb2Ygc28gd2UgY2FuIGdldCBpdHMgbGF5b3V0IGluZm8gdG8gZmluZCB0aGUKKyAgLy8gb25lb2ZfY2FzZSBmaWVsZC4KKyAgdXBiX29uZW9mX2l0ZXIgaXQ7CisgIHVwYl9vbmVvZl9iZWdpbigmaXQsIG8pOworICBhc3NlcnQoIXVwYl9vbmVvZl9kb25lKCZpdCkpOworICBjb25zdCB1cGJfZmllbGRkZWYqIGZpcnN0X2ZpZWxkID0gdXBiX29uZW9mX2l0ZXJfZmllbGQoJml0KTsKKyAgYXNzZXJ0KHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZmlyc3RfZmllbGQpICE9IE5VTEwpOworCisgIHNpemVfdCBjYXNlX29mcyA9CisgICAgICBzZWxmLT5kZXNjcmlwdG9yLT5sYXlvdXQtPgorICAgICAgZmllbGRzW3VwYl9maWVsZGRlZl9pbmRleChmaXJzdF9maWVsZCldLmNhc2Vfb2Zmc2V0OworICB1aW50MzJfdCBvbmVvZl9jYXNlID0gKigodWludDMyX3QqKShNZXNzYWdlX2RhdGEoc2VsZikgKyBjYXNlX29mcykpOworCisgIGlmIChvbmVvZl9jYXNlID09IE9ORU9GX0NBU0VfTk9ORSkgeworICAgIHJldHVybiBRbmlsOworICB9CisKKyAgLy8gb25lb2ZfY2FzZSBpcyBhIGZpZWxkIGluZGV4LCBzbyBmaW5kIHRoYXQgZmllbGQuCisgIGNvbnN0IHVwYl9maWVsZGRlZiogZiA9IHVwYl9vbmVvZmRlZl9pdG9mKG8sIG9uZW9mX2Nhc2UpOworICBhc3NlcnQoZiAhPSBOVUxMKTsKKworICByZXR1cm4gSUQyU1lNKHJiX2ludGVybih1cGJfZmllbGRkZWZfbmFtZShmKSkpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS5tZXRob2RfbWlzc2luZygqYXJncykKKyAqCisgKiBQcm92aWRlcyBhY2Nlc3NvcnMgYW5kIHNldHRlcnMgZm9yIG1lc3NhZ2UgZmllbGRzIGFjY29yZGluZyB0byB0aGVpciBmaWVsZAorICogbmFtZXMuIEZvciBhbnkgZmllbGQgd2hvc2UgbmFtZSBkb2VzIG5vdCBjb25mbGljdCB3aXRoIGEgYnVpbHQtaW4gbWV0aG9kLCBhbgorICogYWNjZXNzb3IgaXMgcHJvdmlkZWQgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBmaWVsZCwgYW5kIGEgc2V0dGVyIGlzCisgKiBwcm92aWRlZCB3aXRoIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCBwbHVzIHRoZSAnPScgc3VmZml4LiBUaHVzLCBnaXZlbiBhCisgKiBtZXNzYWdlIGluc3RhbmNlICdtc2cnIHdpdGggZmllbGQgJ2ZvbycsIHRoZSBmb2xsb3dpbmcgY29kZSBpcyB2YWxpZDoKKyAqCisgKiAgICAgbXNnLmZvbyA9IDQyCisgKiAgICAgcHV0cyBtc2cuZm9vCisgKgorICogVGhpcyBtZXRob2QgYWxzbyBwcm92aWRlcyByZWFkLW9ubHkgYWNjZXNzb3JzIGZvciBvbmVvZnMuIElmIGEgb25lb2YgZXhpc3RzCisgKiB3aXRoIG5hbWUgJ215X29uZW9mJywgdGhlbiBtc2cubXlfb25lb2Ygd2lsbCByZXR1cm4gYSBSdWJ5IHN5bWJvbCBlcXVhbCB0bworICogdGhlIG5hbWUgb2YgdGhlIGZpZWxkIGluIHRoYXQgb25lb2YgdGhhdCBpcyBjdXJyZW50bHkgc2V0LCBvciBuaWwgaWYgbm9uZS4KKyAqLworVkFMVUUgTWVzc2FnZV9tZXRob2RfbWlzc2luZyhpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKSB7CisgIE1lc3NhZ2VIZWFkZXIqIHNlbGY7CisgIFR5cGVkRGF0YV9HZXRfU3RydWN0KF9zZWxmLCBNZXNzYWdlSGVhZGVyLCAmTWVzc2FnZV90eXBlLCBzZWxmKTsKKyAgaWYgKGFyZ2MgPCAxKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiRXhwZWN0ZWQgbWV0aG9kIG5hbWUgYXMgZmlyc3QgYXJndW1lbnQuIik7CisgIH0KKyAgVkFMVUUgbWV0aG9kX25hbWUgPSBhcmd2WzBdOworICBpZiAoIVNZTUJPTF9QKG1ldGhvZF9uYW1lKSkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIHN5bWJvbCBhcyBtZXRob2QgbmFtZS4iKTsKKyAgfQorICBWQUxVRSBtZXRob2Rfc3RyID0gcmJfaWQyc3RyKFNZTTJJRChtZXRob2RfbmFtZSkpOworICBjaGFyKiBuYW1lID0gUlNUUklOR19QVFIobWV0aG9kX3N0cik7CisgIHNpemVfdCBuYW1lX2xlbiA9IFJTVFJJTkdfTEVOKG1ldGhvZF9zdHIpOworICBib29sIHNldHRlciA9IGZhbHNlOworCisgIC8vIFNldHRlcnMgaGF2ZSBuYW1lcyB0aGF0IGVuZCBpbiAnPScuCisgIGlmIChuYW1lW25hbWVfbGVuIC0gMV0gPT0gJz0nKSB7CisgICAgc2V0dGVyID0gdHJ1ZTsKKyAgICBuYW1lX2xlbi0tOworICB9CisKKyAgLy8gQ2hlY2sgZm9yIGEgb25lb2YgbmFtZSBmaXJzdC4KKyAgY29uc3QgdXBiX29uZW9mZGVmKiBvID0gdXBiX21zZ2RlZl9udG9vKHNlbGYtPmRlc2NyaXB0b3ItPm1zZ2RlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIG5hbWVfbGVuKTsKKyAgaWYgKG8gIT0gTlVMTCkgeworICAgIGlmIChzZXR0ZXIpIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VSdW50aW1lRXJyb3IsICJPbmVvZiBhY2Nlc3NvcnMgYXJlIHJlYWQtb25seS4iKTsKKyAgICB9CisgICAgcmV0dXJuIHdoaWNoX29uZW9mX2ZpZWxkKHNlbGYsIG8pOworICB9CisKKyAgLy8gT3RoZXJ3aXNlLCBjaGVjayBmb3IgYSBmaWVsZCB3aXRoIHRoYXQgbmFtZS4KKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmID0gdXBiX21zZ2RlZl9udG9mKHNlbGYtPmRlc2NyaXB0b3ItPm1zZ2RlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIG5hbWVfbGVuKTsKKworICBpZiAoZiA9PSBOVUxMKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiVW5rbm93biBmaWVsZCIpOworICB9CisKKyAgaWYgKHNldHRlcikgeworICAgIGlmIChhcmdjIDwgMikgeworICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiTm8gdmFsdWUgcHJvdmlkZWQgdG8gc2V0dGVyLiIpOworICAgIH0KKyAgICBsYXlvdXRfc2V0KHNlbGYtPmRlc2NyaXB0b3ItPmxheW91dCwgTWVzc2FnZV9kYXRhKHNlbGYpLCBmLCBhcmd2WzFdKTsKKyAgICByZXR1cm4gUW5pbDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gbGF5b3V0X2dldChzZWxmLT5kZXNjcmlwdG9yLT5sYXlvdXQsIE1lc3NhZ2VfZGF0YShzZWxmKSwgZik7CisgIH0KK30KKworaW50IE1lc3NhZ2VfaW5pdGlhbGl6ZV9rd2FyZyhWQUxVRSBrZXksIFZBTFVFIHZhbCwgVkFMVUUgX3NlbGYpIHsKKyAgTWVzc2FnZUhlYWRlciogc2VsZjsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QoX3NlbGYsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIHNlbGYpOworCisgIGlmICghU1lNQk9MX1Aoa2V5KSkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwKKyAgICAgICAgICAgICAiRXhwZWN0ZWQgc3ltYm9scyBhcyBoYXNoIGtleXMgaW4gaW5pdGlhbGl6YXRpb24gbWFwLiIpOworICB9CisKKyAgVkFMVUUgbWV0aG9kX3N0ciA9IHJiX2lkMnN0cihTWU0ySUQoa2V5KSk7CisgIGNoYXIqIG5hbWUgPSBSU1RSSU5HX1BUUihtZXRob2Rfc3RyKTsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmID0gdXBiX21zZ2RlZl9udG9meihzZWxmLT5kZXNjcmlwdG9yLT5tc2dkZWYsIG5hbWUpOworICBpZiAoZiA9PSBOVUxMKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLAorICAgICAgICAgICAgICJVbmtub3duIGZpZWxkIG5hbWUgaW4gaW5pdGlhbGl6YXRpb24gbWFwIGVudHJ5LiIpOworICB9CisKKyAgaWYgKGlzX21hcF9maWVsZChmKSkgeworICAgIGlmIChUWVBFKHZhbCkgIT0gVF9IQVNIKSB7CisgICAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsCisgICAgICAgICAgICAgICAiRXhwZWN0ZWQgSGFzaCBvYmplY3QgYXMgaW5pdGlhbGl6ZXIgdmFsdWUgZm9yIG1hcCBmaWVsZC4iKTsKKyAgICB9CisgICAgVkFMVUUgbWFwID0gbGF5b3V0X2dldChzZWxmLT5kZXNjcmlwdG9yLT5sYXlvdXQsIE1lc3NhZ2VfZGF0YShzZWxmKSwgZik7CisgICAgTWFwX21lcmdlX2ludG9fc2VsZihtYXAsIHZhbCk7CisgIH0gZWxzZSBpZiAodXBiX2ZpZWxkZGVmX2xhYmVsKGYpID09IFVQQl9MQUJFTF9SRVBFQVRFRCkgeworICAgIGlmIChUWVBFKHZhbCkgIT0gVF9BUlJBWSkgeworICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLAorICAgICAgICAgICAgICAgIkV4cGVjdGVkIGFycmF5IGFzIGluaXRpYWxpemVyIHZhbHVlIGZvciByZXBlYXRlZCBmaWVsZC4iKTsKKyAgICB9CisgICAgVkFMVUUgYXJ5ID0gbGF5b3V0X2dldChzZWxmLT5kZXNjcmlwdG9yLT5sYXlvdXQsIE1lc3NhZ2VfZGF0YShzZWxmKSwgZik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSQVJSQVlfTEVOKHZhbCk7IGkrKykgeworICAgICAgUmVwZWF0ZWRGaWVsZF9wdXNoKGFyeSwgcmJfYXJ5X2VudHJ5KHZhbCwgaSkpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBsYXlvdXRfc2V0KHNlbGYtPmRlc2NyaXB0b3ItPmxheW91dCwgTWVzc2FnZV9kYXRhKHNlbGYpLCBmLCB2YWwpOworICB9CisgIHJldHVybiAwOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS5uZXcoa3dhcmdzKSA9PiBuZXdfbWVzc2FnZQorICoKKyAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG1lc3NhZ2UgY2xhc3MuIEtleXdvcmQgYXJndW1lbnRzIG1heSBiZQorICogcHJvdmlkZWQgd2l0aCBrZXl3b3JkcyBjb3JyZXNwb25kaW5nIHRvIGZpZWxkIG5hbWVzLgorICoKKyAqIE5vdGUgdGhhdCBubyBsaXRlcmFsIE1lc3NhZ2UgY2xhc3MgZXhpc3RzLiBPbmx5IGNvbmNyZXRlIGNsYXNzZXMgcGVyIG1lc3NhZ2UKKyAqIHR5cGUgZXhpc3QsIGFzIHByb3ZpZGVkIGJ5IHRoZSAjbXNnY2xhc3MgbWV0aG9kIG9uIERlc2NyaXB0b3JzIGFmdGVyIHRoZXkKKyAqIGhhdmUgYmVlbiBhZGRlZCB0byBhIHBvb2wuIFRoZSBtZXRob2QgZGVmaW5pdGlvbnMgZGVzY3JpYmVkIGhlcmUgb24gdGhlCisgKiBNZXNzYWdlIGNsYXNzIGFyZSBwcm92aWRlZCBvbiBlYWNoIGNvbmNyZXRlIG1lc3NhZ2UgY2xhc3MuCisgKi8KK1ZBTFVFIE1lc3NhZ2VfaW5pdGlhbGl6ZShpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKSB7CisgIGlmIChhcmdjID09IDApIHsKKyAgICByZXR1cm4gUW5pbDsKKyAgfQorICBpZiAoYXJnYyAhPSAxKSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiRXhwZWN0ZWQgMCBvciAxIGFyZ3VtZW50cy4iKTsKKyAgfQorICBWQUxVRSBoYXNoX2FyZ3MgPSBhcmd2WzBdOworICBpZiAoVFlQRShoYXNoX2FyZ3MpICE9IFRfSEFTSCkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIGhhc2ggYXJndW1lbnRzLiIpOworICB9CisKKyAgcmJfaGFzaF9mb3JlYWNoKGhhc2hfYXJncywgTWVzc2FnZV9pbml0aWFsaXplX2t3YXJnLCBfc2VsZik7CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS5kdXAgPT4gbmV3X21lc3NhZ2UKKyAqCisgKiBQZXJmb3JtcyBhIHNoYWxsb3cgY29weSBvZiB0aGlzIG1lc3NhZ2UgYW5kIHJldHVybnMgdGhlIG5ldyBjb3B5LgorICovCitWQUxVRSBNZXNzYWdlX2R1cChWQUxVRSBfc2VsZikgeworICBNZXNzYWdlSGVhZGVyKiBzZWxmOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChfc2VsZiwgTWVzc2FnZUhlYWRlciwgJk1lc3NhZ2VfdHlwZSwgc2VsZik7CisKKyAgVkFMVUUgbmV3X21zZyA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgwLCBOVUxMLCBDTEFTU19PRihfc2VsZikpOworICBNZXNzYWdlSGVhZGVyKiBuZXdfbXNnX3NlbGY7CisgIFR5cGVkRGF0YV9HZXRfU3RydWN0KG5ld19tc2csIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIG5ld19tc2dfc2VsZik7CisKKyAgbGF5b3V0X2R1cChzZWxmLT5kZXNjcmlwdG9yLT5sYXlvdXQsCisgICAgICAgICAgICAgTWVzc2FnZV9kYXRhKG5ld19tc2dfc2VsZiksCisgICAgICAgICAgICAgTWVzc2FnZV9kYXRhKHNlbGYpKTsKKworICByZXR1cm4gbmV3X21zZzsKK30KKworLy8gSW50ZXJuYWwgb25seTsgdXNlZCBieSBHb29nbGU6OlByb3RvYnVmLmRlZXBfY29weS4KK1ZBTFVFIE1lc3NhZ2VfZGVlcF9jb3B5KFZBTFVFIF9zZWxmKSB7CisgIE1lc3NhZ2VIZWFkZXIqIHNlbGY7CisgIFR5cGVkRGF0YV9HZXRfU3RydWN0KF9zZWxmLCBNZXNzYWdlSGVhZGVyLCAmTWVzc2FnZV90eXBlLCBzZWxmKTsKKworICBWQUxVRSBuZXdfbXNnID0gcmJfY2xhc3NfbmV3X2luc3RhbmNlKDAsIE5VTEwsIENMQVNTX09GKF9zZWxmKSk7CisgIE1lc3NhZ2VIZWFkZXIqIG5ld19tc2dfc2VsZjsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QobmV3X21zZywgTWVzc2FnZUhlYWRlciwgJk1lc3NhZ2VfdHlwZSwgbmV3X21zZ19zZWxmKTsKKworICBsYXlvdXRfZGVlcF9jb3B5KHNlbGYtPmRlc2NyaXB0b3ItPmxheW91dCwKKyAgICAgICAgICAgICAgICAgICBNZXNzYWdlX2RhdGEobmV3X21zZ19zZWxmKSwKKyAgICAgICAgICAgICAgICAgICBNZXNzYWdlX2RhdGEoc2VsZikpOworCisgIHJldHVybiBuZXdfbXNnOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS49PShvdGhlcikgPT4gYm9vbGVhbgorICoKKyAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIG9mIHRoaXMgbWVzc2FnZSB3aXRoIGFub3RoZXIuIE1lc3NhZ2VzIGFyZSBlcXVhbAorICogaWYgdGhleSBoYXZlIHRoZSBzYW1lIHR5cGUgYW5kIGlmIGVhY2ggZmllbGQgaXMgZXF1YWwgYWNjb3JkaW5nIHRvIHRoZSA6PT0KKyAqIG1ldGhvZCdzIHNlbWFudGljcyAoYSBtb3JlIGVmZmljaWVudCBjb21wYXJpc29uIG1heSBhY3R1YWxseSBiZSBkb25lIGlmIHRoZQorICogZmllbGQgaXMgb2YgYSBwcmltaXRpdmUgdHlwZSkuCisgKi8KK1ZBTFVFIE1lc3NhZ2VfZXEoVkFMVUUgX3NlbGYsIFZBTFVFIF9vdGhlcikgeworICBNZXNzYWdlSGVhZGVyKiBzZWxmOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChfc2VsZiwgTWVzc2FnZUhlYWRlciwgJk1lc3NhZ2VfdHlwZSwgc2VsZik7CisKKyAgTWVzc2FnZUhlYWRlciogb3RoZXI7CisgIFR5cGVkRGF0YV9HZXRfU3RydWN0KF9vdGhlciwgTWVzc2FnZUhlYWRlciwgJk1lc3NhZ2VfdHlwZSwgb3RoZXIpOworCisgIGlmIChzZWxmLT5kZXNjcmlwdG9yICE9IG90aGVyLT5kZXNjcmlwdG9yKSB7CisgICAgcmV0dXJuIFFmYWxzZTsKKyAgfQorCisgIHJldHVybiBsYXlvdXRfZXEoc2VsZi0+ZGVzY3JpcHRvci0+bGF5b3V0LAorICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VfZGF0YShzZWxmKSwKKyAgICAgICAgICAgICAgICAgICBNZXNzYWdlX2RhdGEob3RoZXIpKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2UuaGFzaCA9PiBoYXNoX3ZhbHVlCisgKgorICogUmV0dXJucyBhIGhhc2ggdmFsdWUgdGhhdCByZXByZXNlbnRzIHRoaXMgbWVzc2FnZSdzIGZpZWxkIHZhbHVlcy4KKyAqLworVkFMVUUgTWVzc2FnZV9oYXNoKFZBTFVFIF9zZWxmKSB7CisgIE1lc3NhZ2VIZWFkZXIqIHNlbGY7CisgIFR5cGVkRGF0YV9HZXRfU3RydWN0KF9zZWxmLCBNZXNzYWdlSGVhZGVyLCAmTWVzc2FnZV90eXBlLCBzZWxmKTsKKworICByZXR1cm4gbGF5b3V0X2hhc2goc2VsZi0+ZGVzY3JpcHRvci0+bGF5b3V0LCBNZXNzYWdlX2RhdGEoc2VsZikpOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS5pbnNwZWN0ID0+IHN0cmluZworICoKKyAqIFJldHVybnMgYSBodW1hbi1yZWFkYWJsZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoaXMgbWVzc2FnZS4gSXQgd2lsbCBiZQorICogZm9ybWF0dGVkIGFzICI8TWVzc2FnZVR5cGU6IGZpZWxkMTogdmFsdWUxLCBmaWVsZDI6IHZhbHVlMiwgLi4uPiIuIEVhY2gKKyAqIGZpZWxkJ3MgdmFsdWUgaXMgcmVwcmVzZW50ZWQgYWNjb3JkaW5nIHRvIGl0cyBvd24gI2luc3BlY3QgbWV0aG9kLgorICovCitWQUxVRSBNZXNzYWdlX2luc3BlY3QoVkFMVUUgX3NlbGYpIHsKKyAgTWVzc2FnZUhlYWRlciogc2VsZjsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QoX3NlbGYsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIHNlbGYpOworCisgIFZBTFVFIHN0ciA9IHJiX3N0cl9uZXcyKCI8Iik7CisgIHN0ciA9IHJiX3N0cl9hcHBlbmQoc3RyLCByYl9zdHJfbmV3MihyYl9jbGFzczJuYW1lKENMQVNTX09GKF9zZWxmKSkpKTsKKyAgc3RyID0gcmJfc3RyX2NhdDIoc3RyLCAiOiAiKTsKKyAgc3RyID0gcmJfc3RyX2FwcGVuZChzdHIsIGxheW91dF9pbnNwZWN0KAorICAgICAgc2VsZi0+ZGVzY3JpcHRvci0+bGF5b3V0LCBNZXNzYWdlX2RhdGEoc2VsZikpKTsKKyAgc3RyID0gcmJfc3RyX2NhdDIoc3RyLCAiPiIpOworICByZXR1cm4gc3RyOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS5bXShpbmRleCkgPT4gdmFsdWUKKyAqCisgKiBBY2Nlc3NlcyBhIGZpZWxkJ3MgdmFsdWUgYnkgZmllbGQgbmFtZS4gVGhlIHByb3ZpZGVkIGZpZWxkIG5hbWUgc2hvdWxkIGJlIGEKKyAqIHN0cmluZy4KKyAqLworVkFMVUUgTWVzc2FnZV9pbmRleChWQUxVRSBfc2VsZiwgVkFMVUUgZmllbGRfbmFtZSkgeworICBNZXNzYWdlSGVhZGVyKiBzZWxmOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChfc2VsZiwgTWVzc2FnZUhlYWRlciwgJk1lc3NhZ2VfdHlwZSwgc2VsZik7CisgIENoZWNrX1R5cGUoZmllbGRfbmFtZSwgVF9TVFJJTkcpOworICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkID0KKyAgICAgIHVwYl9tc2dkZWZfbnRvZnooc2VsZi0+ZGVzY3JpcHRvci0+bXNnZGVmLCBSU1RSSU5HX1BUUihmaWVsZF9uYW1lKSk7CisgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIFFuaWw7CisgIH0KKyAgcmV0dXJuIGxheW91dF9nZXQoc2VsZi0+ZGVzY3JpcHRvci0+bGF5b3V0LCBNZXNzYWdlX2RhdGEoc2VsZiksIGZpZWxkKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIE1lc3NhZ2UuW109KGluZGV4LCB2YWx1ZSkKKyAqCisgKiBTZXRzIGEgZmllbGQncyB2YWx1ZSBieSBmaWVsZCBuYW1lLiBUaGUgcHJvdmlkZWQgZmllbGQgbmFtZSBzaG91bGQgYmUgYQorICogc3RyaW5nLgorICovCitWQUxVRSBNZXNzYWdlX2luZGV4X3NldChWQUxVRSBfc2VsZiwgVkFMVUUgZmllbGRfbmFtZSwgVkFMVUUgdmFsdWUpIHsKKyAgTWVzc2FnZUhlYWRlciogc2VsZjsKKyAgVHlwZWREYXRhX0dldF9TdHJ1Y3QoX3NlbGYsIE1lc3NhZ2VIZWFkZXIsICZNZXNzYWdlX3R5cGUsIHNlbGYpOworICBDaGVja19UeXBlKGZpZWxkX25hbWUsIFRfU1RSSU5HKTsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9CisgICAgICB1cGJfbXNnZGVmX250b2Z6KHNlbGYtPmRlc2NyaXB0b3ItPm1zZ2RlZiwgUlNUUklOR19QVFIoZmllbGRfbmFtZSkpOworICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIlVua25vd24gZmllbGQ6ICVzIiwgUlNUUklOR19QVFIoZmllbGRfbmFtZSkpOworICB9CisgIGxheW91dF9zZXQoc2VsZi0+ZGVzY3JpcHRvci0+bGF5b3V0LCBNZXNzYWdlX2RhdGEoc2VsZiksIGZpZWxkLCB2YWx1ZSk7CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgTWVzc2FnZS5kZXNjcmlwdG9yID0+IGRlc2NyaXB0b3IKKyAqCisgKiBDbGFzcyBtZXRob2QgdGhhdCByZXR1cm5zIHRoZSBEZXNjcmlwdG9yIGluc3RhbmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhpcworICogbWVzc2FnZSBjbGFzcydzIHR5cGUuCisgKi8KK1ZBTFVFIE1lc3NhZ2VfZGVzY3JpcHRvcihWQUxVRSBrbGFzcykgeworICByZXR1cm4gcmJfaXZfZ2V0KGtsYXNzLCBrRGVzY3JpcHRvckluc3RhbmNlVmFyKTsKK30KKworVkFMVUUgYnVpbGRfY2xhc3NfZnJvbV9kZXNjcmlwdG9yKERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgaWYgKGRlc2MtPmxheW91dCA9PSBOVUxMKSB7CisgICAgZGVzYy0+bGF5b3V0ID0gY3JlYXRlX2xheW91dChkZXNjLT5tc2dkZWYpOworICB9CisgIGlmIChkZXNjLT5maWxsX21ldGhvZCA9PSBOVUxMKSB7CisgICAgZGVzYy0+ZmlsbF9tZXRob2QgPSBuZXdfZmlsbG1zZ19kZWNvZGVybWV0aG9kKGRlc2MsICZkZXNjLT5maWxsX21ldGhvZCk7CisgIH0KKworICBjb25zdCBjaGFyKiBuYW1lID0gdXBiX21zZ2RlZl9mdWxsbmFtZShkZXNjLT5tc2dkZWYpOworICBpZiAobmFtZSA9PSBOVUxMKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIkRlc2NyaXB0b3IgZG9lcyBub3QgaGF2ZSBhc3NpZ25lZCBuYW1lLiIpOworICB9CisKKyAgVkFMVUUga2xhc3MgPSByYl9kZWZpbmVfY2xhc3NfaWQoCisgICAgICAvLyBEb2NzIHNheSB0aGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkLiBVc2VyIHdpbGwgYXNzaWduIHJldHVybiB2YWx1ZSB0bworICAgICAgLy8gdGhlaXIgb3duIHRvcGxldmVsIGNvbnN0YW50IGNsYXNzIG5hbWUuCisgICAgICByYl9pbnRlcm4oIk1lc3NhZ2UiKSwKKyAgICAgIHJiX2NPYmplY3QpOworICByYl9pdl9zZXQoa2xhc3MsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIsIGdldF9kZWZfb2JqKGRlc2MtPm1zZ2RlZikpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgTWVzc2FnZV9hbGxvYyk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJtZXRob2RfbWlzc2luZyIsCisgICAgICAgICAgICAgICAgICAgTWVzc2FnZV9tZXRob2RfbWlzc2luZywgLTEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiaW5pdGlhbGl6ZSIsIE1lc3NhZ2VfaW5pdGlhbGl6ZSwgLTEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiZHVwIiwgTWVzc2FnZV9kdXAsIDApOworICAvLyBBbHNvIGRlZmluZSAjY2xvbmUgc28gdGhhdCB3ZSBkb24ndCBpbmhlcml0IE9iamVjdCNjbG9uZS4KKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImNsb25lIiwgTWVzc2FnZV9kdXAsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiPT0iLCBNZXNzYWdlX2VxLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImhhc2giLCBNZXNzYWdlX2hhc2gsIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiaW5zcGVjdCIsIE1lc3NhZ2VfaW5zcGVjdCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJbXSIsIE1lc3NhZ2VfaW5kZXgsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiW109IiwgTWVzc2FnZV9pbmRleF9zZXQsIDIpOworICByYl9kZWZpbmVfc2luZ2xldG9uX21ldGhvZChrbGFzcywgImRlY29kZSIsIE1lc3NhZ2VfZGVjb2RlLCAxKTsKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2Qoa2xhc3MsICJlbmNvZGUiLCBNZXNzYWdlX2VuY29kZSwgMSk7CisgIHJiX2RlZmluZV9zaW5nbGV0b25fbWV0aG9kKGtsYXNzLCAiZGVjb2RlX2pzb24iLCBNZXNzYWdlX2RlY29kZV9qc29uLCAxKTsKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2Qoa2xhc3MsICJlbmNvZGVfanNvbiIsIE1lc3NhZ2VfZW5jb2RlX2pzb24sIDEpOworICByYl9kZWZpbmVfc2luZ2xldG9uX21ldGhvZChrbGFzcywgImRlc2NyaXB0b3IiLCBNZXNzYWdlX2Rlc2NyaXB0b3IsIDApOworICByZXR1cm4ga2xhc3M7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtLmxvb2t1cChudW1iZXIpID0+IG5hbWUKKyAqCisgKiBUaGlzIG1vZHVsZSBtZXRob2QsIHByb3ZpZGVkIG9uIGVhY2ggZ2VuZXJhdGVkIGVudW0gbW9kdWxlLCBsb29rcyB1cCBhbiBlbnVtCisgKiB2YWx1ZSBieSBudW1iZXIgYW5kIHJldHVybnMgaXRzIG5hbWUgYXMgYSBSdWJ5IHN5bWJvbCwgb3IgbmlsIGlmIG5vdCBmb3VuZC4KKyAqLworVkFMVUUgZW51bV9sb29rdXAoVkFMVUUgc2VsZiwgVkFMVUUgbnVtYmVyKSB7CisgIGludDMyX3QgbnVtID0gTlVNMklOVChudW1iZXIpOworICBWQUxVRSBkZXNjID0gcmJfaXZfZ2V0KHNlbGYsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIpOworICBFbnVtRGVzY3JpcHRvciogZW51bWRlc2MgPSBydWJ5X3RvX0VudW1EZXNjcmlwdG9yKGRlc2MpOworCisgIGNvbnN0IGNoYXIqIG5hbWUgPSB1cGJfZW51bWRlZl9pdG9uKGVudW1kZXNjLT5lbnVtZGVmLCBudW0pOworICBpZiAobmFtZSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIFFuaWw7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIElEMlNZTShyYl9pbnRlcm4obmFtZSkpOworICB9Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBFbnVtLnJlc29sdmUobmFtZSkgPT4gbnVtYmVyCisgKgorICogVGhpcyBtb2R1bGUgbWV0aG9kLCBwcm92aWRlZCBvbiBlYWNoIGdlbmVyYXRlZCBlbnVtIG1vZHVsZSwgbG9va3MgdXAgYW4gZW51bQorICogdmFsdWUgYnkgbmFtZSAoYXMgYSBSdWJ5IHN5bWJvbCkgYW5kIHJldHVybnMgaXRzIG5hbWUsIG9yIG5pbCBpZiBub3QgZm91bmQuCisgKi8KK1ZBTFVFIGVudW1fcmVzb2x2ZShWQUxVRSBzZWxmLCBWQUxVRSBzeW0pIHsKKyAgY29uc3QgY2hhciogbmFtZSA9IHJiX2lkMm5hbWUoU1lNMklEKHN5bSkpOworICBWQUxVRSBkZXNjID0gcmJfaXZfZ2V0KHNlbGYsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIpOworICBFbnVtRGVzY3JpcHRvciogZW51bWRlc2MgPSBydWJ5X3RvX0VudW1EZXNjcmlwdG9yKGRlc2MpOworCisgIGludDMyX3QgbnVtID0gMDsKKyAgYm9vbCBmb3VuZCA9IHVwYl9lbnVtZGVmX250b2l6KGVudW1kZXNjLT5lbnVtZGVmLCBuYW1lLCAmbnVtKTsKKyAgaWYgKCFmb3VuZCkgeworICAgIHJldHVybiBRbmlsOworICB9IGVsc2UgeworICAgIHJldHVybiBJTlQyTlVNKG51bSk7CisgIH0KK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEVudW0uZGVzY3JpcHRvcgorICoKKyAqIFRoaXMgbW9kdWxlIG1ldGhvZCwgcHJvdmlkZWQgb24gZWFjaCBnZW5lcmF0ZWQgZW51bSBtb2R1bGUsIHJldHVybnMgdGhlCisgKiBFbnVtRGVzY3JpcHRvciBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZW51bSB0eXBlLgorICovCitWQUxVRSBlbnVtX2Rlc2NyaXB0b3IoVkFMVUUgc2VsZikgeworICByZXR1cm4gcmJfaXZfZ2V0KHNlbGYsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIpOworfQorCitWQUxVRSBidWlsZF9tb2R1bGVfZnJvbV9lbnVtZGVzYyhFbnVtRGVzY3JpcHRvciogZW51bWRlc2MpIHsKKyAgVkFMVUUgbW9kID0gcmJfZGVmaW5lX21vZHVsZV9pZCgKKyAgICAgIHJiX2ludGVybih1cGJfZW51bWRlZl9mdWxsbmFtZShlbnVtZGVzYy0+ZW51bWRlZikpKTsKKworICB1cGJfZW51bV9pdGVyIGl0OworICBmb3IgKHVwYl9lbnVtX2JlZ2luKCZpdCwgZW51bWRlc2MtPmVudW1kZWYpOworICAgICAgICF1cGJfZW51bV9kb25lKCZpdCk7CisgICAgICAgdXBiX2VudW1fbmV4dCgmaXQpKSB7CisgICAgY29uc3QgY2hhciogbmFtZSA9IHVwYl9lbnVtX2l0ZXJfbmFtZSgmaXQpOworICAgIGludDMyX3QgdmFsdWUgPSB1cGJfZW51bV9pdGVyX251bWJlcigmaXQpOworICAgIGlmIChuYW1lWzBdIDwgJ0EnIHx8IG5hbWVbMF0gPiAnWicpIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsCisgICAgICAgICAgICAgICAiRW51bSB2YWx1ZSAnJXMnIGRvZXMgbm90IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGxldHRlciAiCisgICAgICAgICAgICAgICAiYXMgaXMgcmVxdWlyZWQgZm9yIFJ1YnkgY29uc3RhbnRzLiIsCisgICAgICAgICAgICAgICBuYW1lKTsKKyAgICB9CisgICAgcmJfZGVmaW5lX2NvbnN0KG1vZCwgbmFtZSwgSU5UMk5VTSh2YWx1ZSkpOworICB9CisKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2QobW9kLCAibG9va3VwIiwgZW51bV9sb29rdXAsIDEpOworICByYl9kZWZpbmVfc2luZ2xldG9uX21ldGhvZChtb2QsICJyZXNvbHZlIiwgZW51bV9yZXNvbHZlLCAxKTsKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2QobW9kLCAiZGVzY3JpcHRvciIsIGVudW1fZGVzY3JpcHRvciwgMCk7CisgIHJiX2l2X3NldChtb2QsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIsIGdldF9kZWZfb2JqKGVudW1kZXNjLT5lbnVtZGVmKSk7CisKKyAgcmV0dXJuIG1vZDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIEdvb2dsZTo6UHJvdG9idWYuZGVlcF9jb3B5KG9iaikgPT4gY29weV9vZl9vYmoKKyAqCisgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvZiBhIFJlcGVhdGVkRmllbGQgaW5zdGFuY2UsIGEgTWFwIGluc3RhbmNlLCBvciBhCisgKiBtZXNzYWdlIG9iamVjdCwgcmVjdXJzaXZlbHkgY29weWluZyBpdHMgbWVtYmVycy4KKyAqLworVkFMVUUgR29vZ2xlX1Byb3RvYnVmX2RlZXBfY29weShWQUxVRSBzZWxmLCBWQUxVRSBvYmopIHsKKyAgVkFMVUUga2xhc3MgPSBDTEFTU19PRihvYmopOworICBpZiAoa2xhc3MgPT0gY1JlcGVhdGVkRmllbGQpIHsKKyAgICByZXR1cm4gUmVwZWF0ZWRGaWVsZF9kZWVwX2NvcHkob2JqKTsKKyAgfSBlbHNlIGlmIChrbGFzcyA9PSBjTWFwKSB7CisgICAgcmV0dXJuIE1hcF9kZWVwX2NvcHkob2JqKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTWVzc2FnZV9kZWVwX2NvcHkob2JqKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvcHJvdG9idWYuYyBiL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL3Byb3RvYnVmLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDJkMzUwMwotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL3Byb3RvYnVmLmMKQEAgLTAsMCArMSwxMDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSAicHJvdG9idWYuaCIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEdsb2JhbCBtYXAgZnJvbSB1cGIge21zZyxlbnVtfWRlZnMgdG8gd3JhcHBlciBEZXNjcmlwdG9yL0VudW1EZXNjcmlwdG9yCisvLyBpbnN0YW5jZXMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBUaGlzIGlzIGEgaGFzaCB0YWJsZSBmcm9tIGRlZiBvYmplY3RzIChlbmNvZGVkIGJ5IGNvbnZlcnRpbmcgcG9pbnRlcnMgdG8KKy8vIFJ1YnkgaW50ZWdlcnMpIHRvIE1lc3NhZ2VEZWYvRW51bURlZiBpbnN0YW5jZXMgKGFzIFJ1YnkgdmFsdWVzKS4KK1ZBTFVFIHVwYl9kZWZfdG9fcnVieV9vYmpfbWFwOworCit2b2lkIGFkZF9kZWZfb2JqKGNvbnN0IHZvaWQqIGRlZiwgVkFMVUUgdmFsdWUpIHsKKyAgcmJfaGFzaF9hc2V0KHVwYl9kZWZfdG9fcnVieV9vYmpfbWFwLCBVTEwyTlVNKChpbnRwdHJfdClkZWYpLCB2YWx1ZSk7Cit9CisKK1ZBTFVFIGdldF9kZWZfb2JqKGNvbnN0IHZvaWQqIGRlZikgeworICByZXR1cm4gcmJfaGFzaF9hcmVmKHVwYl9kZWZfdG9fcnVieV9vYmpfbWFwLCBVTEwyTlVNKChpbnRwdHJfdClkZWYpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFV0aWxpdGllcy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFJhaXNlcyBhIFJ1YnkgZXJyb3IgaWYgfHN0YXR1c3wgaXMgbm90IE9LLCB1c2luZyBpdHMgZXJyb3IgbWVzc2FnZS4KK3ZvaWQgY2hlY2tfdXBiX3N0YXR1cyhjb25zdCB1cGJfc3RhdHVzKiBzdGF0dXMsIGNvbnN0IGNoYXIqIG1zZykgeworICBpZiAoIXVwYl9vayhzdGF0dXMpKSB7CisgICAgcmJfcmFpc2UocmJfZVJ1bnRpbWVFcnJvciwgIiVzOiAlc1xuIiwgbXNnLCB1cGJfc3RhdHVzX2Vycm1zZyhzdGF0dXMpKTsKKyAgfQorfQorCisvLyBTdHJpbmcgZW5jb2RpbmdzOiB3ZSBsb29rIHRoZXNlIHVwIG9uY2UsIGF0IGxvYWQgdGltZSwgYW5kIHRoZW4gY2FjaGUgdGhlbQorLy8gaGVyZS4KK3JiX2VuY29kaW5nKiBrUnVieVN0cmluZ1V0ZjhFbmNvZGluZzsKK3JiX2VuY29kaW5nKiBrUnVieVN0cmluZ0FTQ0lJRW5jb2Rpbmc7CityYl9lbmNvZGluZyoga1J1YnlTdHJpbmc4Yml0RW5jb2Rpbmc7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBJbml0aWFsaXphdGlvbi9lbnRyeSBwb2ludC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFRoaXMgbXVzdCBiZSBuYW1lZCAiSW5pdF9wcm90b2J1Zl9jIiBiZWNhdXNlIHRoZSBSdWJ5IG1vZHVsZSBpcyBuYW1lZAorLy8gInByb3RvYnVmX2MiIC0tIHRoZSBWTSBsb29rcyBmb3IgdGhpcyBzeW1ib2wgaW4gb3VyIC5zby4KK3ZvaWQgSW5pdF9wcm90b2J1Zl9jKCkgeworICBWQUxVRSBnb29nbGUgPSByYl9kZWZpbmVfbW9kdWxlKCJHb29nbGUiKTsKKyAgVkFMVUUgcHJvdG9idWYgPSByYl9kZWZpbmVfbW9kdWxlX3VuZGVyKGdvb2dsZSwgIlByb3RvYnVmIik7CisgIFZBTFVFIGludGVybmFsID0gcmJfZGVmaW5lX21vZHVsZV91bmRlcihwcm90b2J1ZiwgIkludGVybmFsIik7CisgIERlc2NyaXB0b3JQb29sX3JlZ2lzdGVyKHByb3RvYnVmKTsKKyAgRGVzY3JpcHRvcl9yZWdpc3Rlcihwcm90b2J1Zik7CisgIEZpZWxkRGVzY3JpcHRvcl9yZWdpc3Rlcihwcm90b2J1Zik7CisgIE9uZW9mRGVzY3JpcHRvcl9yZWdpc3Rlcihwcm90b2J1Zik7CisgIEVudW1EZXNjcmlwdG9yX3JlZ2lzdGVyKHByb3RvYnVmKTsKKyAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0X3JlZ2lzdGVyKGludGVybmFsKTsKKyAgT25lb2ZCdWlsZGVyQ29udGV4dF9yZWdpc3RlcihpbnRlcm5hbCk7CisgIEVudW1CdWlsZGVyQ29udGV4dF9yZWdpc3RlcihpbnRlcm5hbCk7CisgIEJ1aWxkZXJfcmVnaXN0ZXIoaW50ZXJuYWwpOworICBSZXBlYXRlZEZpZWxkX3JlZ2lzdGVyKHByb3RvYnVmKTsKKyAgTWFwX3JlZ2lzdGVyKHByb3RvYnVmKTsKKworICByYl9kZWZpbmVfc2luZ2xldG9uX21ldGhvZChwcm90b2J1ZiwgImVuY29kZSIsIEdvb2dsZV9Qcm90b2J1Zl9lbmNvZGUsIDEpOworICByYl9kZWZpbmVfc2luZ2xldG9uX21ldGhvZChwcm90b2J1ZiwgImRlY29kZSIsIEdvb2dsZV9Qcm90b2J1Zl9kZWNvZGUsIDIpOworICByYl9kZWZpbmVfc2luZ2xldG9uX21ldGhvZChwcm90b2J1ZiwgImVuY29kZV9qc29uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR29vZ2xlX1Byb3RvYnVmX2VuY29kZV9qc29uLCAxKTsKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2QocHJvdG9idWYsICJkZWNvZGVfanNvbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdvb2dsZV9Qcm90b2J1Zl9kZWNvZGVfanNvbiwgMik7CisKKyAgcmJfZGVmaW5lX3NpbmdsZXRvbl9tZXRob2QocHJvdG9idWYsICJkZWVwX2NvcHkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHb29nbGVfUHJvdG9idWZfZGVlcF9jb3B5LCAxKTsKKworICBrUnVieVN0cmluZ1V0ZjhFbmNvZGluZyA9IHJiX3V0ZjhfZW5jb2RpbmcoKTsKKyAga1J1YnlTdHJpbmdBU0NJSUVuY29kaW5nID0gcmJfdXNhc2NpaV9lbmNvZGluZygpOworICBrUnVieVN0cmluZzhiaXRFbmNvZGluZyA9IHJiX2FzY2lpOGJpdF9lbmNvZGluZygpOworCisgIHVwYl9kZWZfdG9fcnVieV9vYmpfbWFwID0gcmJfaGFzaF9uZXcoKTsKKyAgcmJfZ2NfcmVnaXN0ZXJfYWRkcmVzcygmdXBiX2RlZl90b19ydWJ5X29ial9tYXApOworfQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvcHJvdG9idWYuaCBiL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL3Byb3RvYnVmLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDhhMzI3YQotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvZXh0L2dvb2dsZS9wcm90b2J1Zl9jL3Byb3RvYnVmLmgKQEAgLTAsMCArMSw1MzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIF9fR09PR0xFX1BST1RPQlVGX1JVQllfUFJPVE9CVUZfSF9fCisjZGVmaW5lIF9fR09PR0xFX1BST1RPQlVGX1JVQllfUFJPVE9CVUZfSF9fCisKKyNpbmNsdWRlIDxydWJ5L3J1YnkuaD4KKyNpbmNsdWRlIDxydWJ5L3ZtLmg+CisjaW5jbHVkZSA8cnVieS9lbmNvZGluZy5oPgorCisjaW5jbHVkZSAidXBiLmgiCisKKy8vIEZvcndhcmQgZGVjbHMuCitzdHJ1Y3QgRGVzY3JpcHRvclBvb2w7CitzdHJ1Y3QgRGVzY3JpcHRvcjsKK3N0cnVjdCBGaWVsZERlc2NyaXB0b3I7CitzdHJ1Y3QgRW51bURlc2NyaXB0b3I7CitzdHJ1Y3QgTWVzc2FnZUxheW91dDsKK3N0cnVjdCBNZXNzYWdlRmllbGQ7CitzdHJ1Y3QgTWVzc2FnZUhlYWRlcjsKK3N0cnVjdCBNZXNzYWdlQnVpbGRlckNvbnRleHQ7CitzdHJ1Y3QgRW51bUJ1aWxkZXJDb250ZXh0Oworc3RydWN0IEJ1aWxkZXI7CisKK3R5cGVkZWYgc3RydWN0IERlc2NyaXB0b3JQb29sIERlc2NyaXB0b3JQb29sOwordHlwZWRlZiBzdHJ1Y3QgRGVzY3JpcHRvciBEZXNjcmlwdG9yOwordHlwZWRlZiBzdHJ1Y3QgRmllbGREZXNjcmlwdG9yIEZpZWxkRGVzY3JpcHRvcjsKK3R5cGVkZWYgc3RydWN0IE9uZW9mRGVzY3JpcHRvciBPbmVvZkRlc2NyaXB0b3I7Cit0eXBlZGVmIHN0cnVjdCBFbnVtRGVzY3JpcHRvciBFbnVtRGVzY3JpcHRvcjsKK3R5cGVkZWYgc3RydWN0IE1lc3NhZ2VMYXlvdXQgTWVzc2FnZUxheW91dDsKK3R5cGVkZWYgc3RydWN0IE1lc3NhZ2VGaWVsZCBNZXNzYWdlRmllbGQ7Cit0eXBlZGVmIHN0cnVjdCBNZXNzYWdlSGVhZGVyIE1lc3NhZ2VIZWFkZXI7Cit0eXBlZGVmIHN0cnVjdCBNZXNzYWdlQnVpbGRlckNvbnRleHQgTWVzc2FnZUJ1aWxkZXJDb250ZXh0OwordHlwZWRlZiBzdHJ1Y3QgT25lb2ZCdWlsZGVyQ29udGV4dCBPbmVvZkJ1aWxkZXJDb250ZXh0OwordHlwZWRlZiBzdHJ1Y3QgRW51bUJ1aWxkZXJDb250ZXh0IEVudW1CdWlsZGVyQ29udGV4dDsKK3R5cGVkZWYgc3RydWN0IEJ1aWxkZXIgQnVpbGRlcjsKKworLyoKKyBJdCBjYW4gYmUgYSBiaXQgY29uZnVzaW5nIGhvdyB0aGUgQyBzdHJ1Y3RzIGRlZmluZWQgYmVsb3cgYW5kIHRoZSBSdWJ5Cisgb2JqZWN0cyBpbnRlcmFjdCBhbmQgaG9sZCByZWZlcmVuY2VzIHRvIGVhY2ggb3RoZXIuIEZpcnN0LCBhIGZldyBwcmluY2lwbGVzOgorCisgLSBSdWJ5J3MgIlR5cGVkRGF0YSIgYWJzdHJhY3Rpb24gbGV0cyBhIFJ1YnkgVkFMVUUgaG9sZCBhIHBvaW50ZXIgdG8gYSBDCisgICBzdHJ1Y3QgKG9yIGFyYml0cmFyeSBtZW1vcnkgY2h1bmspLCBvd24gaXQsIGFuZCBmcmVlIGl0IHdoZW4gY29sbGVjdGVkLgorICAgVGh1cywgZWFjaCBzdHJ1Y3QgYmVsb3cgd2lsbCBoYXZlIGEgY29ycmVzcG9uZGluZyBSdWJ5IG9iamVjdAorICAgd3JhcHBpbmcvb3duaW5nIGl0LgorCisgLSBUbyBnZXQgYmFjayBmcm9tIGFuIHVuZGVybHlpbmcgdXBiIHttc2csZW51bX1kZWYgdG8gdGhlIFJ1Ynkgb2JqZWN0LCB3ZQorICAga2VlcCBhIGdsb2JhbCBoYXNobWFwLCBhY2Nlc3NlZCBieSBnZXRfZGVmX29iai9hZGRfZGVmX29iaiBiZWxvdy4KKworIFRoZSBpbi1tZW1vcnkgc3RydWN0dXJlIGlzIHRoZW4gc29tZXRoaW5nIGxpa2U6CisKKyAgIFJ1YnkgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgdXBiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorICAgRGVzY3JpcHRvclBvb2wgIC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLT4gdXBiX3N5bXRhYl9fX19fX19fX19fX19fX19fX19fCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8IChtZXNzYWdlIHR5cGVzKSAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB2ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgRGVzY3JpcHRvciAgIC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLT4gdXBiX21zZ2RlZiAgICAgICAgIChlbnVtIHR5cGVzKXwKKyAgICB8LS0+IG1zZ2NsYXNzICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgIHwgICBeICAgICAgICAgICAgICAgICAgICAgICB8CisgICAgfCAgICAoZHluYW1pY2FsbHkgYnVpbHQpICAgfCAgICAgICAgICAgICAgICB8ICAgfCAoc3VibXNnIGZpZWxkcykgICAgICAgfAorICAgIHwtLT4gTWVzc2FnZUxheW91dCAgICAgICAgIHwgICAgICAgICAgICAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgIC8KKyAgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18PiBkZWNvZGVyIG1ldGhvZHwgICB8ICAgICAgICAgICAgICAgICAgICAgIC8KKyAgICBcLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18PiBzZXJpYWxpemUgICAgIHwgICB8ICAgICAgICAgICAgICAgICAgICAgLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIGhhbmRsZXJzICAgICAgdiAgIHwgICAgICAgICAgICAgICAgICAgIC8KKyAgIEZpZWxkRGVzY3JpcHRvciAgLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0+IHVwYl9maWVsZGRlZiAgICAgICAgICAgICAgIC8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgIHYgKGVudW0gZmllbGRzKSAgIC8KKyAgIEVudW1EZXNjcmlwdG9yICAtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0+IHVwYl9lbnVtZGVmICA8LS0tLS0tLS0tLScKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorICAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICBcX19fLworICAgICAgICAgICAgICAgYC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLScgICAgKGdldF9kZWZfb2JqIG1hcCkKKyAqLworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUnVieSBjbGFzcyBzdHJ1Y3R1cmUgZGVmaW5pdGlvbnMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3QgRGVzY3JpcHRvclBvb2wgeworICB1cGJfc3ltdGFiKiBzeW10YWI7Cit9OworCitzdHJ1Y3QgRGVzY3JpcHRvciB7CisgIGNvbnN0IHVwYl9tc2dkZWYqIG1zZ2RlZjsKKyAgTWVzc2FnZUxheW91dCogbGF5b3V0OworICBWQUxVRSBrbGFzczsgIC8vIGJlZ2lucyBhcyBuaWwKKyAgY29uc3QgdXBiX2hhbmRsZXJzKiBmaWxsX2hhbmRsZXJzOworICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kKiBmaWxsX21ldGhvZDsKKyAgY29uc3QgdXBiX2hhbmRsZXJzKiBwYl9zZXJpYWxpemVfaGFuZGxlcnM7CisgIGNvbnN0IHVwYl9oYW5kbGVycyoganNvbl9zZXJpYWxpemVfaGFuZGxlcnM7CisgIC8vIEhhbmRsZXJzIGhvbGQgdHlwZSBjbGFzcyByZWZlcmVuY2VzIGZvciBzdWItbWVzc2FnZSBmaWVsZHMgZGlyZWN0bHkgaW4gc29tZQorICAvLyBjYXNlcy4gV2UgbmVlZCB0byBrZWVwIHRoZXNlIHJvb3RlZCBiZWNhdXNlIHRoZXkgbWlnaHQgb3RoZXJ3aXNlIGJlCisgIC8vIGNvbGxlY3RlZC4KKyAgVkFMVUUgdHlwZWNsYXNzX3JlZmVyZW5jZXM7Cit9OworCitzdHJ1Y3QgRmllbGREZXNjcmlwdG9yIHsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZGRlZjsKK307CisKK3N0cnVjdCBPbmVvZkRlc2NyaXB0b3IgeworICBjb25zdCB1cGJfb25lb2ZkZWYqIG9uZW9mZGVmOworfTsKKworc3RydWN0IEVudW1EZXNjcmlwdG9yIHsKKyAgY29uc3QgdXBiX2VudW1kZWYqIGVudW1kZWY7CisgIFZBTFVFIG1vZHVsZTsgIC8vIGJlZ2lucyBhcyBuaWwKK307CisKK3N0cnVjdCBNZXNzYWdlQnVpbGRlckNvbnRleHQgeworICBWQUxVRSBkZXNjcmlwdG9yOworICBWQUxVRSBidWlsZGVyOworfTsKKworc3RydWN0IE9uZW9mQnVpbGRlckNvbnRleHQgeworICBWQUxVRSBkZXNjcmlwdG9yOworICBWQUxVRSBidWlsZGVyOworfTsKKworc3RydWN0IEVudW1CdWlsZGVyQ29udGV4dCB7CisgIFZBTFVFIGVudW1kZXNjOworfTsKKworc3RydWN0IEJ1aWxkZXIgeworICBWQUxVRSBwZW5kaW5nX2xpc3Q7CisgIHVwYl9kZWYqKiBkZWZzOyAgLy8gdXNlZCBvbmx5IHdoaWxlIGZpbmFsaXppbmcKK307CisKK2V4dGVybiBWQUxVRSBjRGVzY3JpcHRvclBvb2w7CitleHRlcm4gVkFMVUUgY0Rlc2NyaXB0b3I7CitleHRlcm4gVkFMVUUgY0ZpZWxkRGVzY3JpcHRvcjsKK2V4dGVybiBWQUxVRSBjRW51bURlc2NyaXB0b3I7CitleHRlcm4gVkFMVUUgY01lc3NhZ2VCdWlsZGVyQ29udGV4dDsKK2V4dGVybiBWQUxVRSBjT25lb2ZCdWlsZGVyQ29udGV4dDsKK2V4dGVybiBWQUxVRSBjRW51bUJ1aWxkZXJDb250ZXh0OworZXh0ZXJuIFZBTFVFIGNCdWlsZGVyOworCitleHRlcm4gY29uc3QgY2hhcioga0Rlc2NyaXB0b3JJbnN0YW5jZVZhcjsKKworLy8gV2UgZm9yd2FyZC1kZWNsYXJlIGFsbCBvZiB0aGUgUnVieSBtZXRob2QgaW1wbGVtZW50YXRpb25zIGhlcmUgYmVjYXVzZSB3ZQorLy8gc29tZXRpbWVzIGNhbGwgdGhlIG1ldGhvZHMgZGlyZWN0bHkgYWNyb3NzIC5jIGZpbGVzLCByYXRoZXIgdGhhbiBnb2luZworLy8gdGhyb3VnaCBSdWJ5J3MgbWV0aG9kIGRpc3BhdGNoaW5nIChlLmcuIGR1cmluZyBtZXNzYWdlIHBhcnNlKS4gSXQncyBjbGVhbmVyCisvLyB0byBrZWVwIHRoZSBsaXN0IG9mIG9iamVjdCBtZXRob2RzIHRvZ2V0aGVyIHRoYW4gdG8gc3BsaXQgdGhlbSBiZXR3ZWVuCisvLyBzdGF0aWMtaW4tZmlsZSBkZWZpbml0aW9ucyBhbmQgaGVhZGVyIGRlY2xhcmF0aW9ucy4KKwordm9pZCBEZXNjcmlwdG9yUG9vbF9tYXJrKHZvaWQqIF9zZWxmKTsKK3ZvaWQgRGVzY3JpcHRvclBvb2xfZnJlZSh2b2lkKiBfc2VsZik7CitWQUxVRSBEZXNjcmlwdG9yUG9vbF9hbGxvYyhWQUxVRSBrbGFzcyk7Cit2b2lkIERlc2NyaXB0b3JQb29sX3JlZ2lzdGVyKFZBTFVFIG1vZHVsZSk7CitEZXNjcmlwdG9yUG9vbCogcnVieV90b19EZXNjcmlwdG9yUG9vbChWQUxVRSB2YWx1ZSk7CitWQUxVRSBEZXNjcmlwdG9yUG9vbF9hZGQoVkFMVUUgX3NlbGYsIFZBTFVFIGRlZik7CitWQUxVRSBEZXNjcmlwdG9yUG9vbF9idWlsZChWQUxVRSBfc2VsZik7CitWQUxVRSBEZXNjcmlwdG9yUG9vbF9sb29rdXAoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpOworVkFMVUUgRGVzY3JpcHRvclBvb2xfZ2VuZXJhdGVkX3Bvb2woVkFMVUUgX3NlbGYpOworCit2b2lkIERlc2NyaXB0b3JfbWFyayh2b2lkKiBfc2VsZik7Cit2b2lkIERlc2NyaXB0b3JfZnJlZSh2b2lkKiBfc2VsZik7CitWQUxVRSBEZXNjcmlwdG9yX2FsbG9jKFZBTFVFIGtsYXNzKTsKK3ZvaWQgRGVzY3JpcHRvcl9yZWdpc3RlcihWQUxVRSBtb2R1bGUpOworRGVzY3JpcHRvciogcnVieV90b19EZXNjcmlwdG9yKFZBTFVFIHZhbHVlKTsKK1ZBTFVFIERlc2NyaXB0b3JfbmFtZShWQUxVRSBfc2VsZik7CitWQUxVRSBEZXNjcmlwdG9yX25hbWVfc2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBzdHIpOworVkFMVUUgRGVzY3JpcHRvcl9lYWNoKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIERlc2NyaXB0b3JfbG9va3VwKFZBTFVFIF9zZWxmLCBWQUxVRSBuYW1lKTsKK1ZBTFVFIERlc2NyaXB0b3JfYWRkX2ZpZWxkKFZBTFVFIF9zZWxmLCBWQUxVRSBvYmopOworVkFMVUUgRGVzY3JpcHRvcl9hZGRfb25lb2YoVkFMVUUgX3NlbGYsIFZBTFVFIG9iaik7CitWQUxVRSBEZXNjcmlwdG9yX2VhY2hfb25lb2YoVkFMVUUgX3NlbGYpOworVkFMVUUgRGVzY3JpcHRvcl9sb29rdXBfb25lb2YoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpOworVkFMVUUgRGVzY3JpcHRvcl9tc2djbGFzcyhWQUxVRSBfc2VsZik7CitleHRlcm4gY29uc3QgcmJfZGF0YV90eXBlX3QgX0Rlc2NyaXB0b3JfdHlwZTsKKwordm9pZCBGaWVsZERlc2NyaXB0b3JfbWFyayh2b2lkKiBfc2VsZik7Cit2b2lkIEZpZWxkRGVzY3JpcHRvcl9mcmVlKHZvaWQqIF9zZWxmKTsKK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9hbGxvYyhWQUxVRSBrbGFzcyk7Cit2b2lkIEZpZWxkRGVzY3JpcHRvcl9yZWdpc3RlcihWQUxVRSBtb2R1bGUpOworRmllbGREZXNjcmlwdG9yKiBydWJ5X3RvX0ZpZWxkRGVzY3JpcHRvcihWQUxVRSB2YWx1ZSk7CitWQUxVRSBGaWVsZERlc2NyaXB0b3JfbmFtZShWQUxVRSBfc2VsZik7CitWQUxVRSBGaWVsZERlc2NyaXB0b3JfbmFtZV9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIHN0cik7CitWQUxVRSBGaWVsZERlc2NyaXB0b3JfdHlwZShWQUxVRSBfc2VsZik7CitWQUxVRSBGaWVsZERlc2NyaXB0b3JfdHlwZV9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIHR5cGUpOworVkFMVUUgRmllbGREZXNjcmlwdG9yX2xhYmVsKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9sYWJlbF9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIGxhYmVsKTsKK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9udW1iZXIoVkFMVUUgX3NlbGYpOworVkFMVUUgRmllbGREZXNjcmlwdG9yX251bWJlcl9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIG51bWJlcik7CitWQUxVRSBGaWVsZERlc2NyaXB0b3Jfc3VibXNnX25hbWUoVkFMVUUgX3NlbGYpOworVkFMVUUgRmllbGREZXNjcmlwdG9yX3N1Ym1zZ19uYW1lX3NldChWQUxVRSBfc2VsZiwgVkFMVUUgdmFsdWUpOworVkFMVUUgRmllbGREZXNjcmlwdG9yX3N1YnR5cGUoVkFMVUUgX3NlbGYpOworVkFMVUUgRmllbGREZXNjcmlwdG9yX2dldChWQUxVRSBfc2VsZiwgVkFMVUUgbXNnX3JiKTsKK1ZBTFVFIEZpZWxkRGVzY3JpcHRvcl9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIG1zZ19yYiwgVkFMVUUgdmFsdWUpOwordXBiX2ZpZWxkdHlwZV90IHJ1YnlfdG9fZmllbGR0eXBlKFZBTFVFIHR5cGUpOworVkFMVUUgZmllbGR0eXBlX3RvX3J1YnkodXBiX2ZpZWxkdHlwZV90IHR5cGUpOworCit2b2lkIE9uZW9mRGVzY3JpcHRvcl9tYXJrKHZvaWQqIF9zZWxmKTsKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yX2ZyZWUodm9pZCogX3NlbGYpOworVkFMVUUgT25lb2ZEZXNjcmlwdG9yX2FsbG9jKFZBTFVFIGtsYXNzKTsKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yX3JlZ2lzdGVyKFZBTFVFIG1vZHVsZSk7CitPbmVvZkRlc2NyaXB0b3IqIHJ1YnlfdG9fT25lb2ZEZXNjcmlwdG9yKFZBTFVFIHZhbHVlKTsKK1ZBTFVFIE9uZW9mRGVzY3JpcHRvcl9uYW1lKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE9uZW9mRGVzY3JpcHRvcl9uYW1lX3NldChWQUxVRSBfc2VsZiwgVkFMVUUgdmFsdWUpOworVkFMVUUgT25lb2ZEZXNjcmlwdG9yX2FkZF9maWVsZChWQUxVRSBfc2VsZiwgVkFMVUUgZmllbGQpOworVkFMVUUgT25lb2ZEZXNjcmlwdG9yX2VhY2goVkFMVUUgX3NlbGYsIFZBTFVFIGZpZWxkKTsKKwordm9pZCBFbnVtRGVzY3JpcHRvcl9tYXJrKHZvaWQqIF9zZWxmKTsKK3ZvaWQgRW51bURlc2NyaXB0b3JfZnJlZSh2b2lkKiBfc2VsZik7CitWQUxVRSBFbnVtRGVzY3JpcHRvcl9hbGxvYyhWQUxVRSBrbGFzcyk7Cit2b2lkIEVudW1EZXNjcmlwdG9yX3JlZ2lzdGVyKFZBTFVFIG1vZHVsZSk7CitFbnVtRGVzY3JpcHRvciogcnVieV90b19FbnVtRGVzY3JpcHRvcihWQUxVRSB2YWx1ZSk7CitWQUxVRSBFbnVtRGVzY3JpcHRvcl9uYW1lKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIEVudW1EZXNjcmlwdG9yX25hbWVfc2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBzdHIpOworVkFMVUUgRW51bURlc2NyaXB0b3JfYWRkX3ZhbHVlKFZBTFVFIF9zZWxmLCBWQUxVRSBuYW1lLCBWQUxVRSBudW1iZXIpOworVkFMVUUgRW51bURlc2NyaXB0b3JfbG9va3VwX25hbWUoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpOworVkFMVUUgRW51bURlc2NyaXB0b3JfbG9va3VwX3ZhbHVlKFZBTFVFIF9zZWxmLCBWQUxVRSBudW1iZXIpOworVkFMVUUgRW51bURlc2NyaXB0b3JfZWFjaChWQUxVRSBfc2VsZik7CitWQUxVRSBFbnVtRGVzY3JpcHRvcl9lbnVtbW9kdWxlKFZBTFVFIF9zZWxmKTsKK2V4dGVybiBjb25zdCByYl9kYXRhX3R5cGVfdCBfRW51bURlc2NyaXB0b3JfdHlwZTsKKwordm9pZCBNZXNzYWdlQnVpbGRlckNvbnRleHRfbWFyayh2b2lkKiBfc2VsZik7Cit2b2lkIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9mcmVlKHZvaWQqIF9zZWxmKTsKK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9hbGxvYyhWQUxVRSBrbGFzcyk7Cit2b2lkIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9yZWdpc3RlcihWQUxVRSBtb2R1bGUpOworTWVzc2FnZUJ1aWxkZXJDb250ZXh0KiBydWJ5X3RvX01lc3NhZ2VCdWlsZGVyQ29udGV4dChWQUxVRSB2YWx1ZSk7CitWQUxVRSBNZXNzYWdlQnVpbGRlckNvbnRleHRfaW5pdGlhbGl6ZShWQUxVRSBfc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTFVFIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxVRSBidWlsZGVyKTsKK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9vcHRpb25hbChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9yZXF1aXJlZChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9yZXBlYXRlZChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1lc3NhZ2VCdWlsZGVyQ29udGV4dF9tYXAoaW50IGFyZ2MsIFZBTFVFKiBhcmd2LCBWQUxVRSBfc2VsZik7CitWQUxVRSBNZXNzYWdlQnVpbGRlckNvbnRleHRfb25lb2YoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpOworCit2b2lkIE9uZW9mQnVpbGRlckNvbnRleHRfbWFyayh2b2lkKiBfc2VsZik7Cit2b2lkIE9uZW9mQnVpbGRlckNvbnRleHRfZnJlZSh2b2lkKiBfc2VsZik7CitWQUxVRSBPbmVvZkJ1aWxkZXJDb250ZXh0X2FsbG9jKFZBTFVFIGtsYXNzKTsKK3ZvaWQgT25lb2ZCdWlsZGVyQ29udGV4dF9yZWdpc3RlcihWQUxVRSBtb2R1bGUpOworT25lb2ZCdWlsZGVyQ29udGV4dCogcnVieV90b19PbmVvZkJ1aWxkZXJDb250ZXh0KFZBTFVFIHZhbHVlKTsKK1ZBTFVFIE9uZW9mQnVpbGRlckNvbnRleHRfaW5pdGlhbGl6ZShWQUxVRSBfc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxVRSBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTFVFIGJ1aWxkZXIpOworVkFMVUUgT25lb2ZCdWlsZGVyQ29udGV4dF9vcHRpb25hbChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIF9zZWxmKTsKKwordm9pZCBFbnVtQnVpbGRlckNvbnRleHRfbWFyayh2b2lkKiBfc2VsZik7Cit2b2lkIEVudW1CdWlsZGVyQ29udGV4dF9mcmVlKHZvaWQqIF9zZWxmKTsKK1ZBTFVFIEVudW1CdWlsZGVyQ29udGV4dF9hbGxvYyhWQUxVRSBrbGFzcyk7Cit2b2lkIEVudW1CdWlsZGVyQ29udGV4dF9yZWdpc3RlcihWQUxVRSBtb2R1bGUpOworRW51bUJ1aWxkZXJDb250ZXh0KiBydWJ5X3RvX0VudW1CdWlsZGVyQ29udGV4dChWQUxVRSB2YWx1ZSk7CitWQUxVRSBFbnVtQnVpbGRlckNvbnRleHRfaW5pdGlhbGl6ZShWQUxVRSBfc2VsZiwgVkFMVUUgZW51bWRlc2MpOworVkFMVUUgRW51bUJ1aWxkZXJDb250ZXh0X3ZhbHVlKFZBTFVFIF9zZWxmLCBWQUxVRSBuYW1lLCBWQUxVRSBudW1iZXIpOworCit2b2lkIEJ1aWxkZXJfbWFyayh2b2lkKiBfc2VsZik7Cit2b2lkIEJ1aWxkZXJfZnJlZSh2b2lkKiBfc2VsZik7CitWQUxVRSBCdWlsZGVyX2FsbG9jKFZBTFVFIGtsYXNzKTsKK3ZvaWQgQnVpbGRlcl9yZWdpc3RlcihWQUxVRSBtb2R1bGUpOworQnVpbGRlciogcnVieV90b19CdWlsZGVyKFZBTFVFIHZhbHVlKTsKK1ZBTFVFIEJ1aWxkZXJfYWRkX21lc3NhZ2UoVkFMVUUgX3NlbGYsIFZBTFVFIG5hbWUpOworVkFMVUUgQnVpbGRlcl9hZGRfZW51bShWQUxVRSBfc2VsZiwgVkFMVUUgbmFtZSk7CitWQUxVRSBCdWlsZGVyX2ZpbmFsaXplX3RvX3Bvb2woVkFMVUUgX3NlbGYsIFZBTFVFIHBvb2xfcmIpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTmF0aXZlIHNsb3Qgc3RvcmFnZSBhYnN0cmFjdGlvbi4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgTkFUSVZFX1NMT1RfTUFYX1NJWkUgc2l6ZW9mKHVpbnQ2NF90KQorCitzaXplX3QgbmF0aXZlX3Nsb3Rfc2l6ZSh1cGJfZmllbGR0eXBlX3QgdHlwZSk7Cit2b2lkIG5hdGl2ZV9zbG90X3NldCh1cGJfZmllbGR0eXBlX3QgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgIFZBTFVFIHR5cGVfY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICB2b2lkKiBtZW1vcnksCisgICAgICAgICAgICAgICAgICAgICBWQUxVRSB2YWx1ZSk7CisvLyBBdG9taWNhbGx5ICh3aXRoIHJlc3BlY3QgdG8gUnVieSBWTSBjYWxscykgZWl0aGVyIHVwZGF0ZSB0aGUgdmFsdWUgYW5kIHNldCBhCisvLyBvbmVvZiBjYXNlLCBvciBkbyBuZWl0aGVyLiBJZiB8Y2FzZV9tZW1vcnl8IGlzIG51bGwsIHRoZW4gbm8gY2FzZSB2YWx1ZSBpcworLy8gc2V0Lgordm9pZCBuYXRpdmVfc2xvdF9zZXRfdmFsdWVfYW5kX2Nhc2UodXBiX2ZpZWxkdHlwZV90IHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxVRSB0eXBlX2NsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogbWVtb3J5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCogY2FzZV9tZW1vcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBjYXNlX251bWJlcik7CitWQUxVRSBuYXRpdmVfc2xvdF9nZXQodXBiX2ZpZWxkdHlwZV90IHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgdHlwZV9jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBtZW1vcnkpOwordm9pZCBuYXRpdmVfc2xvdF9pbml0KHVwYl9maWVsZHR5cGVfdCB0eXBlLCB2b2lkKiBtZW1vcnkpOwordm9pZCBuYXRpdmVfc2xvdF9tYXJrKHVwYl9maWVsZHR5cGVfdCB0eXBlLCB2b2lkKiBtZW1vcnkpOwordm9pZCBuYXRpdmVfc2xvdF9kdXAodXBiX2ZpZWxkdHlwZV90IHR5cGUsIHZvaWQqIHRvLCB2b2lkKiBmcm9tKTsKK3ZvaWQgbmF0aXZlX3Nsb3RfZGVlcF9jb3B5KHVwYl9maWVsZHR5cGVfdCB0eXBlLCB2b2lkKiB0bywgdm9pZCogZnJvbSk7Citib29sIG5hdGl2ZV9zbG90X2VxKHVwYl9maWVsZHR5cGVfdCB0eXBlLCB2b2lkKiBtZW0xLCB2b2lkKiBtZW0yKTsKKwordm9pZCBuYXRpdmVfc2xvdF92YWxpZGF0ZV9zdHJpbmdfZW5jb2RpbmcodXBiX2ZpZWxkdHlwZV90IHR5cGUsIFZBTFVFIHZhbHVlKTsKK3ZvaWQgbmF0aXZlX3Nsb3RfY2hlY2tfaW50X3JhbmdlX3ByZWNpc2lvbih1cGJfZmllbGR0eXBlX3QgdHlwZSwgVkFMVUUgdmFsdWUpOworCitleHRlcm4gcmJfZW5jb2RpbmcqIGtSdWJ5U3RyaW5nVXRmOEVuY29kaW5nOworZXh0ZXJuIHJiX2VuY29kaW5nKiBrUnVieVN0cmluZ0FTQ0lJRW5jb2Rpbmc7CitleHRlcm4gcmJfZW5jb2RpbmcqIGtSdWJ5U3RyaW5nOGJpdEVuY29kaW5nOworCitWQUxVRSBmaWVsZF90eXBlX2NsYXNzKGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpOworCisjZGVmaW5lIE1BUF9LRVlfRklFTEQgMQorI2RlZmluZSBNQVBfVkFMVUVfRklFTEQgMgorCisvLyBPbmVvZiBjYXNlIHNsb3QgdmFsdWUgdG8gaW5kaWNhdGUgdGhhdCBubyBvbmVvZiBjYXNlIGlzIHNldC4gVGhlIHZhbHVlIGAwYCBpcworLy8gc2FmZSBiZWNhdXNlIGZpZWxkIG51bWJlcnMgYXJlIHVzZWQgYXMgY2FzZSBpZGVudGlmaWVycywgYW5kIG5vIGZpZWxkIGNhbgorLy8gaGF2ZSBhIG51bWJlciBvZiAwLgorI2RlZmluZSBPTkVPRl9DQVNFX05PTkUgMAorCisvLyBUaGVzZSBvcGVyYXRlIG9uIGEgbWFwIGZpZWxkIChpLmUuLCBhIHJlcGVhdGVkIGZpZWxkIG9mIHN1Ym1lc3NhZ2VzIHdob3NlCisvLyBzdWJtZXNzYWdlIHR5cGUgaXMgYSBtYXAtZW50cnkgbXNnZGVmKS4KK2Jvb2wgaXNfbWFwX2ZpZWxkKGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpOworY29uc3QgdXBiX2ZpZWxkZGVmKiBtYXBfZmllbGRfa2V5KGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpOworY29uc3QgdXBiX2ZpZWxkZGVmKiBtYXBfZmllbGRfdmFsdWUoY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCk7CisKKy8vIFRoZXNlIG9wZXJhdGUgb24gYSBtYXAtZW50cnkgbXNnZGVmLgorY29uc3QgdXBiX2ZpZWxkZGVmKiBtYXBfZW50cnlfa2V5KGNvbnN0IHVwYl9tc2dkZWYqIG1zZ2RlZik7Citjb25zdCB1cGJfZmllbGRkZWYqIG1hcF9lbnRyeV92YWx1ZShjb25zdCB1cGJfbXNnZGVmKiBtc2dkZWYpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUmVwZWF0ZWQgZmllbGQgY29udGFpbmVyIHR5cGUuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0eXBlZGVmIHN0cnVjdCB7CisgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlOworICBWQUxVRSBmaWVsZF90eXBlX2NsYXNzOworICB2b2lkKiBlbGVtZW50czsKKyAgaW50IHNpemU7CisgIGludCBjYXBhY2l0eTsKK30gUmVwZWF0ZWRGaWVsZDsKKwordm9pZCBSZXBlYXRlZEZpZWxkX21hcmsodm9pZCogc2VsZik7Cit2b2lkIFJlcGVhdGVkRmllbGRfZnJlZSh2b2lkKiBzZWxmKTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfYWxsb2MoVkFMVUUga2xhc3MpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9pbml0KGludCBhcmdjLCBWQUxVRSogYXJndiwgVkFMVUUgc2VsZik7Cit2b2lkIFJlcGVhdGVkRmllbGRfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKTsKKworZXh0ZXJuIGNvbnN0IHJiX2RhdGFfdHlwZV90IFJlcGVhdGVkRmllbGRfdHlwZTsKK2V4dGVybiBWQUxVRSBjUmVwZWF0ZWRGaWVsZDsKKworUmVwZWF0ZWRGaWVsZCogcnVieV90b19SZXBlYXRlZEZpZWxkKFZBTFVFIHZhbHVlKTsKKworVkFMVUUgUmVwZWF0ZWRGaWVsZF9lYWNoKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfaW5kZXgoVkFMVUUgX3NlbGYsIFZBTFVFIF9pbmRleCk7Cit2b2lkKiBSZXBlYXRlZEZpZWxkX2luZGV4X25hdGl2ZShWQUxVRSBfc2VsZiwgaW50IGluZGV4KTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfaW5kZXhfc2V0KFZBTFVFIF9zZWxmLCBWQUxVRSBfaW5kZXgsIFZBTFVFIHZhbCk7Cit2b2lkIFJlcGVhdGVkRmllbGRfcmVzZXJ2ZShSZXBlYXRlZEZpZWxkKiBzZWxmLCBpbnQgbmV3X3NpemUpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9wdXNoKFZBTFVFIF9zZWxmLCBWQUxVRSB2YWwpOwordm9pZCBSZXBlYXRlZEZpZWxkX3B1c2hfbmF0aXZlKFZBTFVFIF9zZWxmLCB2b2lkKiBkYXRhKTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfcG9wKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfaW5zZXJ0KGludCBhcmdjLCBWQUxVRSogYXJndiwgVkFMVUUgX3NlbGYpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9yZXBsYWNlKFZBTFVFIF9zZWxmLCBWQUxVRSBsaXN0KTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfY2xlYXIoVkFMVUUgX3NlbGYpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9sZW5ndGgoVkFMVUUgX3NlbGYpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9kdXAoVkFMVUUgX3NlbGYpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9kZWVwX2NvcHkoVkFMVUUgX3NlbGYpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9lcShWQUxVRSBfc2VsZiwgVkFMVUUgX290aGVyKTsKK1ZBTFVFIFJlcGVhdGVkRmllbGRfaGFzaChWQUxVRSBfc2VsZik7CitWQUxVRSBSZXBlYXRlZEZpZWxkX2luc3BlY3QoVkFMVUUgX3NlbGYpOworVkFMVUUgUmVwZWF0ZWRGaWVsZF9wbHVzKFZBTFVFIF9zZWxmLCBWQUxVRSBsaXN0KTsKKworLy8gRGVmaW5lZCBpbiByZXBlYXRlZF9maWVsZC5jOyBhbHNvIHVzZWQgYnkgTWFwLgordm9pZCB2YWxpZGF0ZV90eXBlX2NsYXNzKHVwYl9maWVsZHR5cGVfdCB0eXBlLCBWQUxVRSBrbGFzcyk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNYXAgY29udGFpbmVyIHR5cGUuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0eXBlZGVmIHN0cnVjdCB7CisgIHVwYl9maWVsZHR5cGVfdCBrZXlfdHlwZTsKKyAgdXBiX2ZpZWxkdHlwZV90IHZhbHVlX3R5cGU7CisgIFZBTFVFIHZhbHVlX3R5cGVfY2xhc3M7CisgIHVwYl9zdHJ0YWJsZSB0YWJsZTsKK30gTWFwOworCit2b2lkIE1hcF9tYXJrKHZvaWQqIHNlbGYpOwordm9pZCBNYXBfZnJlZSh2b2lkKiBzZWxmKTsKK1ZBTFVFIE1hcF9hbGxvYyhWQUxVRSBrbGFzcyk7CitWQUxVRSBNYXBfaW5pdChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIHNlbGYpOwordm9pZCBNYXBfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKTsKKworZXh0ZXJuIGNvbnN0IHJiX2RhdGFfdHlwZV90IE1hcF90eXBlOworZXh0ZXJuIFZBTFVFIGNNYXA7CisKK01hcCogcnVieV90b19NYXAoVkFMVUUgdmFsdWUpOworCitWQUxVRSBNYXBfZWFjaChWQUxVRSBfc2VsZik7CitWQUxVRSBNYXBfa2V5cyhWQUxVRSBfc2VsZik7CitWQUxVRSBNYXBfdmFsdWVzKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1hcF9pbmRleChWQUxVRSBfc2VsZiwgVkFMVUUga2V5KTsKK1ZBTFVFIE1hcF9pbmRleF9zZXQoVkFMVUUgX3NlbGYsIFZBTFVFIGtleSwgVkFMVUUgdmFsdWUpOworVkFMVUUgTWFwX2hhc19rZXkoVkFMVUUgX3NlbGYsIFZBTFVFIGtleSk7CitWQUxVRSBNYXBfZGVsZXRlKFZBTFVFIF9zZWxmLCBWQUxVRSBrZXkpOworVkFMVUUgTWFwX2NsZWFyKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1hcF9sZW5ndGgoVkFMVUUgX3NlbGYpOworVkFMVUUgTWFwX2R1cChWQUxVRSBfc2VsZik7CitWQUxVRSBNYXBfZGVlcF9jb3B5KFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1hcF9lcShWQUxVRSBfc2VsZiwgVkFMVUUgX290aGVyKTsKK1ZBTFVFIE1hcF9oYXNoKFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1hcF9pbnNwZWN0KFZBTFVFIF9zZWxmKTsKK1ZBTFVFIE1hcF9tZXJnZShWQUxVRSBfc2VsZiwgVkFMVUUgaGFzaG1hcCk7CitWQUxVRSBNYXBfbWVyZ2VfaW50b19zZWxmKFZBTFVFIF9zZWxmLCBWQUxVRSBoYXNobWFwKTsKKwordHlwZWRlZiBzdHJ1Y3QgeworICBNYXAqIHNlbGY7CisgIHVwYl9zdHJ0YWJsZV9pdGVyIGl0OworfSBNYXBfaXRlcjsKKwordm9pZCBNYXBfYmVnaW4oVkFMVUUgX3NlbGYsIE1hcF9pdGVyKiBpdGVyKTsKK3ZvaWQgTWFwX25leHQoTWFwX2l0ZXIqIGl0ZXIpOworYm9vbCBNYXBfZG9uZShNYXBfaXRlciogaXRlcik7CitWQUxVRSBNYXBfaXRlcl9rZXkoTWFwX2l0ZXIqIGl0ZXIpOworVkFMVUUgTWFwX2l0ZXJfdmFsdWUoTWFwX2l0ZXIqIGl0ZXIpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTWVzc2FnZSBsYXlvdXQgLyBzdG9yYWdlLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBNRVNTQUdFX0ZJRUxEX05PX0NBU0UgKChzaXplX3QpLTEpCisKK3N0cnVjdCBNZXNzYWdlRmllbGQgeworICBzaXplX3Qgb2Zmc2V0OworICBzaXplX3QgY2FzZV9vZmZzZXQ7ICAvLyBmb3Igb25lb2ZzLCBhIHVpbnQzMi4gRWxzZSwgTUVTU0FHRV9GSUVMRF9OT19DQVNFLgorfTsKKworc3RydWN0IE1lc3NhZ2VMYXlvdXQgeworICBjb25zdCB1cGJfbXNnZGVmKiBtc2dkZWY7CisgIE1lc3NhZ2VGaWVsZCogZmllbGRzOworICBzaXplX3Qgc2l6ZTsKK307CisKK01lc3NhZ2VMYXlvdXQqIGNyZWF0ZV9sYXlvdXQoY29uc3QgdXBiX21zZ2RlZiogbXNnZGVmKTsKK3ZvaWQgZnJlZV9sYXlvdXQoTWVzc2FnZUxheW91dCogbGF5b3V0KTsKK1ZBTFVFIGxheW91dF9nZXQoTWVzc2FnZUxheW91dCogbGF5b3V0LAorICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBzdG9yYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkKTsKK3ZvaWQgbGF5b3V0X3NldChNZXNzYWdlTGF5b3V0KiBsYXlvdXQsCisgICAgICAgICAgICAgICAgdm9pZCogc3RvcmFnZSwKKyAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkLAorICAgICAgICAgICAgICAgIFZBTFVFIHZhbCk7Cit2b2lkIGxheW91dF9pbml0KE1lc3NhZ2VMYXlvdXQqIGxheW91dCwgdm9pZCogc3RvcmFnZSk7Cit2b2lkIGxheW91dF9tYXJrKE1lc3NhZ2VMYXlvdXQqIGxheW91dCwgdm9pZCogc3RvcmFnZSk7Cit2b2lkIGxheW91dF9kdXAoTWVzc2FnZUxheW91dCogbGF5b3V0LCB2b2lkKiB0bywgdm9pZCogZnJvbSk7Cit2b2lkIGxheW91dF9kZWVwX2NvcHkoTWVzc2FnZUxheW91dCogbGF5b3V0LCB2b2lkKiB0bywgdm9pZCogZnJvbSk7CitWQUxVRSBsYXlvdXRfZXEoTWVzc2FnZUxheW91dCogbGF5b3V0LCB2b2lkKiBtc2cxLCB2b2lkKiBtc2cyKTsKK1ZBTFVFIGxheW91dF9oYXNoKE1lc3NhZ2VMYXlvdXQqIGxheW91dCwgdm9pZCogc3RvcmFnZSk7CitWQUxVRSBsYXlvdXRfaW5zcGVjdChNZXNzYWdlTGF5b3V0KiBsYXlvdXQsIHZvaWQqIHN0b3JhZ2UpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTWVzc2FnZSBjbGFzcyBjcmVhdGlvbi4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCBNZXNzYWdlSGVhZGVyIHsKKyAgRGVzY3JpcHRvciogZGVzY3JpcHRvcjsgIC8vIGtlcHQgYWxpdmUgYnkgc2VsZi5jbGFzcy5kZXNjcmlwdG9yIHJlZmVyZW5jZS4KKyAgLy8gRGF0YSBjb21lcyBhZnRlciB0aGlzLgorfTsKKworZXh0ZXJuIHJiX2RhdGFfdHlwZV90IE1lc3NhZ2VfdHlwZTsKKworVkFMVUUgYnVpbGRfY2xhc3NfZnJvbV9kZXNjcmlwdG9yKERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOwordm9pZCogTWVzc2FnZV9kYXRhKHZvaWQqIG1zZyk7Cit2b2lkIE1lc3NhZ2VfbWFyayh2b2lkKiBzZWxmKTsKK3ZvaWQgTWVzc2FnZV9mcmVlKHZvaWQqIHNlbGYpOworVkFMVUUgTWVzc2FnZV9hbGxvYyhWQUxVRSBrbGFzcyk7CitWQUxVRSBNZXNzYWdlX21ldGhvZF9taXNzaW5nKGludCBhcmdjLCBWQUxVRSogYXJndiwgVkFMVUUgX3NlbGYpOworVkFMVUUgTWVzc2FnZV9pbml0aWFsaXplKGludCBhcmdjLCBWQUxVRSogYXJndiwgVkFMVUUgX3NlbGYpOworVkFMVUUgTWVzc2FnZV9kdXAoVkFMVUUgX3NlbGYpOworVkFMVUUgTWVzc2FnZV9kZWVwX2NvcHkoVkFMVUUgX3NlbGYpOworVkFMVUUgTWVzc2FnZV9lcShWQUxVRSBfc2VsZiwgVkFMVUUgX290aGVyKTsKK1ZBTFVFIE1lc3NhZ2VfaGFzaChWQUxVRSBfc2VsZik7CitWQUxVRSBNZXNzYWdlX2luc3BlY3QoVkFMVUUgX3NlbGYpOworVkFMVUUgTWVzc2FnZV9pbmRleChWQUxVRSBfc2VsZiwgVkFMVUUgZmllbGRfbmFtZSk7CitWQUxVRSBNZXNzYWdlX2luZGV4X3NldChWQUxVRSBfc2VsZiwgVkFMVUUgZmllbGRfbmFtZSwgVkFMVUUgdmFsdWUpOworVkFMVUUgTWVzc2FnZV9kZXNjcmlwdG9yKFZBTFVFIGtsYXNzKTsKK1ZBTFVFIE1lc3NhZ2VfZGVjb2RlKFZBTFVFIGtsYXNzLCBWQUxVRSBkYXRhKTsKK1ZBTFVFIE1lc3NhZ2VfZW5jb2RlKFZBTFVFIGtsYXNzLCBWQUxVRSBtc2dfcmIpOworVkFMVUUgTWVzc2FnZV9kZWNvZGVfanNvbihWQUxVRSBrbGFzcywgVkFMVUUgZGF0YSk7CitWQUxVRSBNZXNzYWdlX2VuY29kZV9qc29uKFZBTFVFIGtsYXNzLCBWQUxVRSBtc2dfcmIpOworCitWQUxVRSBHb29nbGVfUHJvdG9idWZfZW5jb2RlKFZBTFVFIHNlbGYsIFZBTFVFIG1zZ19yYik7CitWQUxVRSBHb29nbGVfUHJvdG9idWZfZGVjb2RlKFZBTFVFIHNlbGYsIFZBTFVFIGtsYXNzLCBWQUxVRSBtc2dfcmIpOworVkFMVUUgR29vZ2xlX1Byb3RvYnVmX2VuY29kZV9qc29uKFZBTFVFIHNlbGYsIFZBTFVFIG1zZ19yYik7CitWQUxVRSBHb29nbGVfUHJvdG9idWZfZGVjb2RlX2pzb24oVkFMVUUgc2VsZiwgVkFMVUUga2xhc3MsIFZBTFVFIG1zZ19yYik7CisKK1ZBTFVFIEdvb2dsZV9Qcm90b2J1Zl9kZWVwX2NvcHkoVkFMVUUgc2VsZiwgVkFMVUUgb2JqKTsKKworVkFMVUUgYnVpbGRfbW9kdWxlX2Zyb21fZW51bWRlc2MoRW51bURlc2NyaXB0b3IqIGVudW1kZWYpOworVkFMVUUgZW51bV9sb29rdXAoVkFMVUUgc2VsZiwgVkFMVUUgbnVtYmVyKTsKK1ZBTFVFIGVudW1fcmVzb2x2ZShWQUxVRSBzZWxmLCBWQUxVRSBzeW0pOworCitjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICpuZXdfZmlsbG1zZ19kZWNvZGVybWV0aG9kKAorICAgIERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IHZvaWQgKm93bmVyKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEdsb2JhbCBtYXAgZnJvbSB1cGIge21zZyxlbnVtfWRlZnMgdG8gd3JhcHBlciBEZXNjcmlwdG9yL0VudW1EZXNjcmlwdG9yCisvLyBpbnN0YW5jZXMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQordm9pZCBhZGRfZGVmX29iaihjb25zdCB2b2lkKiBkZWYsIFZBTFVFIHZhbHVlKTsKK1ZBTFVFIGdldF9kZWZfb2JqKGNvbnN0IHZvaWQqIGRlZik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBVdGlsaXRpZXMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIGNoZWNrX3VwYl9zdGF0dXMoY29uc3QgdXBiX3N0YXR1cyogc3RhdHVzLCBjb25zdCBjaGFyKiBtc2cpOworCisjZGVmaW5lIENIRUNLX1VQQihjb2RlLCBtc2cpIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdXBiX3N0YXR1cyBzdGF0dXMgPSBVUEJfU1RBVFVTX0lOSVQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY29kZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2hlY2tfdXBiX3N0YXR1cygmc3RhdHVzLCBtc2cpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9IHdoaWxlICgwKQorCisjZW5kaWYgIC8vIF9fR09PR0xFX1BST1RPQlVGX1JVQllfUFJPVE9CVUZfSF9fCmRpZmYgLS1naXQgYS9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9yZXBlYXRlZF9maWVsZC5jIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvcmVwZWF0ZWRfZmllbGQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Y2YyZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvcmVwZWF0ZWRfZmllbGQuYwpAQCAtMCwwICsxLDU5OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlICJwcm90b2J1Zi5oIgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUmVwZWF0ZWQgZmllbGQgY29udGFpbmVyIHR5cGUuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCByYl9kYXRhX3R5cGVfdCBSZXBlYXRlZEZpZWxkX3R5cGUgPSB7CisgICJHb29nbGU6OlByb3RvYnVmOjpSZXBlYXRlZEZpZWxkIiwKKyAgeyBSZXBlYXRlZEZpZWxkX21hcmssIFJlcGVhdGVkRmllbGRfZnJlZSwgTlVMTCB9LAorfTsKKworVkFMVUUgY1JlcGVhdGVkRmllbGQ7CisKK1JlcGVhdGVkRmllbGQqIHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChWQUxVRSBfc2VsZikgeworICBSZXBlYXRlZEZpZWxkKiBzZWxmOworICBUeXBlZERhdGFfR2V0X1N0cnVjdChfc2VsZiwgUmVwZWF0ZWRGaWVsZCwgJlJlcGVhdGVkRmllbGRfdHlwZSwgc2VsZik7CisgIHJldHVybiBzZWxmOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC5lYWNoKCZibG9jaykKKyAqCisgKiBJbnZva2VzIHRoZSBibG9jayBvbmNlIGZvciBlYWNoIGVsZW1lbnQgb2YgdGhlIHJlcGVhdGVkIGZpZWxkLiBSZXBlYXRlZEZpZWxkCisgKiBhbHNvIGluY2x1ZGVzIEVudW1lcmFibGU7IGNvbWJpbmVkIHdpdGggdGhpcyBtZXRob2QsIHRoZSByZXBlYXRlZCBmaWVsZCB0aHVzCisgKiBhY3RzIGxpa2UgYW4gb3JkaW5hcnkgUnVieSBzZXF1ZW5jZS4KKyAqLworVkFMVUUgUmVwZWF0ZWRGaWVsZF9lYWNoKFZBTFVFIF9zZWxmKSB7CisgIFJlcGVhdGVkRmllbGQqIHNlbGYgPSBydWJ5X3RvX1JlcGVhdGVkRmllbGQoX3NlbGYpOworICB1cGJfZmllbGR0eXBlX3QgZmllbGRfdHlwZSA9IHNlbGYtPmZpZWxkX3R5cGU7CisgIFZBTFVFIGZpZWxkX3R5cGVfY2xhc3MgPSBzZWxmLT5maWVsZF90eXBlX2NsYXNzOworICBpbnQgZWxlbWVudF9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKworICBzaXplX3Qgb2ZmID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWxmLT5zaXplOyBpKyssIG9mZiArPSBlbGVtZW50X3NpemUpIHsKKyAgICB2b2lkKiBtZW1vcnkgPSAodm9pZCAqKSAoKCh1aW50OF90ICopc2VsZi0+ZWxlbWVudHMpICsgb2ZmKTsKKyAgICBWQUxVRSB2YWwgPSBuYXRpdmVfc2xvdF9nZXQoZmllbGRfdHlwZSwgZmllbGRfdHlwZV9jbGFzcywgbWVtb3J5KTsKKyAgICByYl95aWVsZCh2YWwpOworICB9CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC5bXShpbmRleCkgPT4gdmFsdWUKKyAqCisgKiBBY2Nlc3NlcyB0aGUgZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kZXguIFRocm93cyBhbiBleGNlcHRpb24gb24gb3V0LW9mLWJvdW5kcworICogZXJyb3JzLgorICovCitWQUxVRSBSZXBlYXRlZEZpZWxkX2luZGV4KFZBTFVFIF9zZWxmLCBWQUxVRSBfaW5kZXgpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIGludCBlbGVtZW50X3NpemUgPSBuYXRpdmVfc2xvdF9zaXplKHNlbGYtPmZpZWxkX3R5cGUpOworICB1cGJfZmllbGR0eXBlX3QgZmllbGRfdHlwZSA9IHNlbGYtPmZpZWxkX3R5cGU7CisgIFZBTFVFIGZpZWxkX3R5cGVfY2xhc3MgPSBzZWxmLT5maWVsZF90eXBlX2NsYXNzOworCisgIGludCBpbmRleCA9IE5VTTJJTlQoX2luZGV4KTsKKyAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBzZWxmLT5zaXplKSB7CisgICAgcmJfcmFpc2UocmJfZVJhbmdlRXJyb3IsICJJbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgfQorCisgIHZvaWQqIG1lbW9yeSA9ICh2b2lkICopICgoKHVpbnQ4X3QgKilzZWxmLT5lbGVtZW50cykgKyBpbmRleCAqIGVsZW1lbnRfc2l6ZSk7CisgIHJldHVybiBuYXRpdmVfc2xvdF9nZXQoZmllbGRfdHlwZSwgZmllbGRfdHlwZV9jbGFzcywgbWVtb3J5KTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIFJlcGVhdGVkRmllbGQuW109KGluZGV4LCB2YWx1ZSkKKyAqCisgKiBTZXRzIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleC4gT24gb3V0LW9mLWJvdW5kcyBhc3NpZ25tZW50cywgZXh0ZW5kcworICogdGhlIGFycmF5IGFuZCBmaWxscyB0aGUgaG9sZSAoaWYgYW55KSB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICovCitWQUxVRSBSZXBlYXRlZEZpZWxkX2luZGV4X3NldChWQUxVRSBfc2VsZiwgVkFMVUUgX2luZGV4LCBWQUxVRSB2YWwpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlID0gc2VsZi0+ZmllbGRfdHlwZTsKKyAgVkFMVUUgZmllbGRfdHlwZV9jbGFzcyA9IHNlbGYtPmZpZWxkX3R5cGVfY2xhc3M7CisgIGludCBlbGVtZW50X3NpemUgPSBuYXRpdmVfc2xvdF9zaXplKGZpZWxkX3R5cGUpOworCisgIGludCBpbmRleCA9IE5VTTJJTlQoX2luZGV4KTsKKyAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSAoSU5UX01BWCAtIDEpKSB7CisgICAgcmJfcmFpc2UocmJfZVJhbmdlRXJyb3IsICJJbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgfQorICBpZiAoaW5kZXggPj0gc2VsZi0+c2l6ZSkgeworICAgIFJlcGVhdGVkRmllbGRfcmVzZXJ2ZShzZWxmLCBpbmRleCArIDEpOworICAgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlID0gc2VsZi0+ZmllbGRfdHlwZTsKKyAgICBpbnQgZWxlbWVudF9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKyAgICBmb3IgKGludCBpID0gc2VsZi0+c2l6ZTsgaSA8PSBpbmRleDsgaSsrKSB7CisgICAgICB2b2lkKiBlbGVtID0gKHZvaWQgKikoKCh1aW50OF90ICopc2VsZi0+ZWxlbWVudHMpICsgaSAqIGVsZW1lbnRfc2l6ZSk7CisgICAgICBuYXRpdmVfc2xvdF9pbml0KGZpZWxkX3R5cGUsIGVsZW0pOworICAgIH0KKyAgICBzZWxmLT5zaXplID0gaW5kZXggKyAxOworICB9CisKKyAgdm9pZCogbWVtb3J5ID0gKHZvaWQgKikgKCgodWludDhfdCAqKXNlbGYtPmVsZW1lbnRzKSArIGluZGV4ICogZWxlbWVudF9zaXplKTsKKyAgbmF0aXZlX3Nsb3Rfc2V0KGZpZWxkX3R5cGUsIGZpZWxkX3R5cGVfY2xhc3MsIG1lbW9yeSwgdmFsKTsKKyAgcmV0dXJuIFFuaWw7Cit9CisKK3N0YXRpYyBpbnQga0luaXRpYWxTaXplID0gODsKKwordm9pZCBSZXBlYXRlZEZpZWxkX3Jlc2VydmUoUmVwZWF0ZWRGaWVsZCogc2VsZiwgaW50IG5ld19zaXplKSB7CisgIGlmIChuZXdfc2l6ZSA8PSBzZWxmLT5jYXBhY2l0eSkgeworICAgIHJldHVybjsKKyAgfQorICBpZiAoc2VsZi0+Y2FwYWNpdHkgPT0gMCkgeworICAgIHNlbGYtPmNhcGFjaXR5ID0ga0luaXRpYWxTaXplOworICB9CisgIHdoaWxlIChzZWxmLT5jYXBhY2l0eSA8IG5ld19zaXplKSB7CisgICAgc2VsZi0+Y2FwYWNpdHkgKj0gMjsKKyAgfQorICB2b2lkKiBvbGRfZWxlbXMgPSBzZWxmLT5lbGVtZW50czsKKyAgaW50IGVsZW1fc2l6ZSA9IG5hdGl2ZV9zbG90X3NpemUoc2VsZi0+ZmllbGRfdHlwZSk7CisgIHNlbGYtPmVsZW1lbnRzID0gQUxMT0NfTih1aW50OF90LCBlbGVtX3NpemUgKiBzZWxmLT5jYXBhY2l0eSk7CisgIGlmIChvbGRfZWxlbXMgIT0gTlVMTCkgeworICAgIG1lbWNweShzZWxmLT5lbGVtZW50cywgb2xkX2VsZW1zLCBzZWxmLT5zaXplICogZWxlbV9zaXplKTsKKyAgICB4ZnJlZShvbGRfZWxlbXMpOworICB9Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBSZXBlYXRlZEZpZWxkLnB1c2godmFsdWUpCisgKgorICogQWRkcyBhIG5ldyBlbGVtZW50IHRvIHRoZSByZXBlYXRlZCBmaWVsZC4KKyAqLworVkFMVUUgUmVwZWF0ZWRGaWVsZF9wdXNoKFZBTFVFIF9zZWxmLCBWQUxVRSB2YWwpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlID0gc2VsZi0+ZmllbGRfdHlwZTsKKyAgaW50IGVsZW1lbnRfc2l6ZSA9IG5hdGl2ZV9zbG90X3NpemUoZmllbGRfdHlwZSk7CisgIFJlcGVhdGVkRmllbGRfcmVzZXJ2ZShzZWxmLCBzZWxmLT5zaXplICsgMSk7CisgIGludCBpbmRleCA9IHNlbGYtPnNpemU7CisgIHZvaWQqIG1lbW9yeSA9ICh2b2lkICopICgoKHVpbnQ4X3QgKilzZWxmLT5lbGVtZW50cykgKyBpbmRleCAqIGVsZW1lbnRfc2l6ZSk7CisgIG5hdGl2ZV9zbG90X3NldChmaWVsZF90eXBlLCBzZWxmLT5maWVsZF90eXBlX2NsYXNzLCBtZW1vcnksIHZhbCk7CisgIC8vIG5hdGl2ZV9zbG90X3NldCBtYXkgcmFpc2UgYW4gZXJyb3I7IGJ1bXAgaW5kZXggb25seSBhZnRlciBzZXQuCisgIHNlbGYtPnNpemUrKzsKKyAgcmV0dXJuIF9zZWxmOworfQorCisvLyBVc2VkIGJ5IHBhcnNpbmcgaGFuZGxlcnMuCit2b2lkIFJlcGVhdGVkRmllbGRfcHVzaF9uYXRpdmUoVkFMVUUgX3NlbGYsIHZvaWQqIGRhdGEpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlID0gc2VsZi0+ZmllbGRfdHlwZTsKKyAgaW50IGVsZW1lbnRfc2l6ZSA9IG5hdGl2ZV9zbG90X3NpemUoZmllbGRfdHlwZSk7CisgIFJlcGVhdGVkRmllbGRfcmVzZXJ2ZShzZWxmLCBzZWxmLT5zaXplICsgMSk7CisgIGludCBpbmRleCA9IHNlbGYtPnNpemU7CisgIHZvaWQqIG1lbW9yeSA9ICh2b2lkICopICgoKHVpbnQ4X3QgKilzZWxmLT5lbGVtZW50cykgKyBpbmRleCAqIGVsZW1lbnRfc2l6ZSk7CisgIG1lbWNweShtZW1vcnksIGRhdGEsIGVsZW1lbnRfc2l6ZSk7CisgIHNlbGYtPnNpemUrKzsKK30KKwordm9pZCogUmVwZWF0ZWRGaWVsZF9pbmRleF9uYXRpdmUoVkFMVUUgX3NlbGYsIGludCBpbmRleCkgeworICBSZXBlYXRlZEZpZWxkKiBzZWxmID0gcnVieV90b19SZXBlYXRlZEZpZWxkKF9zZWxmKTsKKyAgdXBiX2ZpZWxkdHlwZV90IGZpZWxkX3R5cGUgPSBzZWxmLT5maWVsZF90eXBlOworICBpbnQgZWxlbWVudF9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKyAgcmV0dXJuICgodWludDhfdCAqKXNlbGYtPmVsZW1lbnRzKSArIGluZGV4ICogZWxlbWVudF9zaXplOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC5wb3AgPT4gdmFsdWUKKyAqCisgKiBSZW1vdmVzIHRoZSBsYXN0IGVsZW1lbnQgYW5kIHJldHVybnMgaXQuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIHJlcGVhdGVkCisgKiBmaWVsZCBpcyBlbXB0eS4KKyAqLworVkFMVUUgUmVwZWF0ZWRGaWVsZF9wb3AoVkFMVUUgX3NlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlID0gc2VsZi0+ZmllbGRfdHlwZTsKKyAgVkFMVUUgZmllbGRfdHlwZV9jbGFzcyA9IHNlbGYtPmZpZWxkX3R5cGVfY2xhc3M7CisgIGludCBlbGVtZW50X3NpemUgPSBuYXRpdmVfc2xvdF9zaXplKGZpZWxkX3R5cGUpOworICBpZiAoc2VsZi0+c2l6ZSA9PSAwKSB7CisgICAgcmJfcmFpc2UocmJfZVJhbmdlRXJyb3IsICJQb3AgZnJvbSBlbXB0eSByZXBlYXRlZCBmaWVsZCBpcyBub3QgYWxsb3dlZC4iKTsKKyAgfQorICBpbnQgaW5kZXggPSBzZWxmLT5zaXplIC0gMTsKKyAgdm9pZCogbWVtb3J5ID0gKHZvaWQgKikgKCgodWludDhfdCAqKXNlbGYtPmVsZW1lbnRzKSArIGluZGV4ICogZWxlbWVudF9zaXplKTsKKyAgVkFMVUUgcmV0ID0gbmF0aXZlX3Nsb3RfZ2V0KGZpZWxkX3R5cGUsIGZpZWxkX3R5cGVfY2xhc3MsIG1lbW9yeSk7CisgIHNlbGYtPnNpemUtLTsKKyAgcmV0dXJuIHJldDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIFJlcGVhdGVkRmllbGQuaW5zZXJ0KCphcmdzKQorICoKKyAqIFB1c2hlcyBlYWNoIGFyZyBpbiB0dXJuIG9udG8gdGhlIGVuZCBvZiB0aGUgcmVwZWF0ZWQgZmllbGQuCisgKi8KK1ZBTFVFIFJlcGVhdGVkRmllbGRfaW5zZXJ0KGludCBhcmdjLCBWQUxVRSogYXJndiwgVkFMVUUgX3NlbGYpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdjOyBpKyspIHsKKyAgICBSZXBlYXRlZEZpZWxkX3B1c2goX3NlbGYsIGFyZ3ZbaV0pOworICB9CisgIHJldHVybiBRbmlsOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC5yZXBsYWNlKGxpc3QpCisgKgorICogUmVwbGFjZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSByZXBlYXRlZCBmaWVsZCB3aXRoIHRoZSBnaXZlbiBsaXN0IG9mIGVsZW1lbnRzLgorICovCitWQUxVRSBSZXBlYXRlZEZpZWxkX3JlcGxhY2UoVkFMVUUgX3NlbGYsIFZBTFVFIGxpc3QpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIENoZWNrX1R5cGUobGlzdCwgVF9BUlJBWSk7CisgIHNlbGYtPnNpemUgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IFJBUlJBWV9MRU4obGlzdCk7IGkrKykgeworICAgIFJlcGVhdGVkRmllbGRfcHVzaChfc2VsZiwgcmJfYXJ5X2VudHJ5KGxpc3QsIGkpKTsKKyAgfQorICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIFJlcGVhdGVkRmllbGQuY2xlYXIKKyAqCisgKiBDbGVhcnMgKHJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20pIHRoaXMgcmVwZWF0ZWQgZmllbGQuCisgKi8KK1ZBTFVFIFJlcGVhdGVkRmllbGRfY2xlYXIoVkFMVUUgX3NlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIHNlbGYtPnNpemUgPSAwOworICByZXR1cm4gUW5pbDsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIFJlcGVhdGVkRmllbGQubGVuZ3RoCisgKgorICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoaXMgcmVwZWF0ZWQgZmllbGQuCisgKi8KK1ZBTFVFIFJlcGVhdGVkRmllbGRfbGVuZ3RoKFZBTFVFIF9zZWxmKSB7CisgIFJlcGVhdGVkRmllbGQqIHNlbGYgPSBydWJ5X3RvX1JlcGVhdGVkRmllbGQoX3NlbGYpOworICByZXR1cm4gSU5UMk5VTShzZWxmLT5zaXplKTsKK30KKworc3RhdGljIFZBTFVFIFJlcGVhdGVkRmllbGRfbmV3X3RoaXNfdHlwZShWQUxVRSBfc2VsZikgeworICBSZXBlYXRlZEZpZWxkKiBzZWxmID0gcnVieV90b19SZXBlYXRlZEZpZWxkKF9zZWxmKTsKKyAgVkFMVUUgbmV3X3JwdGZpZWxkID0gUW5pbDsKKyAgVkFMVUUgZWxlbWVudF90eXBlID0gZmllbGR0eXBlX3RvX3J1Ynkoc2VsZi0+ZmllbGRfdHlwZSk7CisgIGlmIChzZWxmLT5maWVsZF90eXBlX2NsYXNzICE9IFFuaWwpIHsKKyAgICBuZXdfcnB0ZmllbGQgPSByYl9mdW5jYWxsKENMQVNTX09GKF9zZWxmKSwgcmJfaW50ZXJuKCJuZXciKSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRfdHlwZSwgc2VsZi0+ZmllbGRfdHlwZV9jbGFzcyk7CisgIH0gZWxzZSB7CisgICAgbmV3X3JwdGZpZWxkID0gcmJfZnVuY2FsbChDTEFTU19PRihfc2VsZiksIHJiX2ludGVybigibmV3IiksIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50X3R5cGUpOworICB9CisgIHJldHVybiBuZXdfcnB0ZmllbGQ7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBSZXBlYXRlZEZpZWxkLmR1cCA9PiByZXBlYXRlZF9maWVsZAorICoKKyAqIER1cGxpY2F0ZXMgdGhpcyByZXBlYXRlZCBmaWVsZCB3aXRoIGEgc2hhbGxvdyBjb3B5LiBSZWZlcmVuY2VzIHRvIGFsbAorICogbm9uLXByaW1pdGl2ZSBlbGVtZW50IG9iamVjdHMgKGUuZy4sIHN1Ym1lc3NhZ2VzKSBhcmUgc2hhcmVkLgorICovCitWQUxVRSBSZXBlYXRlZEZpZWxkX2R1cChWQUxVRSBfc2VsZikgeworICBSZXBlYXRlZEZpZWxkKiBzZWxmID0gcnVieV90b19SZXBlYXRlZEZpZWxkKF9zZWxmKTsKKyAgVkFMVUUgbmV3X3JwdGZpZWxkID0gUmVwZWF0ZWRGaWVsZF9uZXdfdGhpc190eXBlKF9zZWxmKTsKKyAgUmVwZWF0ZWRGaWVsZCogbmV3X3JwdGZpZWxkX3NlbGYgPSBydWJ5X3RvX1JlcGVhdGVkRmllbGQobmV3X3JwdGZpZWxkKTsKKyAgUmVwZWF0ZWRGaWVsZF9yZXNlcnZlKG5ld19ycHRmaWVsZF9zZWxmLCBzZWxmLT5zaXplKTsKKyAgdXBiX2ZpZWxkdHlwZV90IGZpZWxkX3R5cGUgPSBzZWxmLT5maWVsZF90eXBlOworICBzaXplX3QgZWxlbV9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKyAgc2l6ZV90IG9mZiA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VsZi0+c2l6ZTsgaSsrLCBvZmYgKz0gZWxlbV9zaXplKSB7CisgICAgdm9pZCogdG9fbWVtID0gKHVpbnQ4X3QgKiluZXdfcnB0ZmllbGRfc2VsZi0+ZWxlbWVudHMgKyBvZmY7CisgICAgdm9pZCogZnJvbV9tZW0gPSAodWludDhfdCAqKXNlbGYtPmVsZW1lbnRzICsgb2ZmOworICAgIG5hdGl2ZV9zbG90X2R1cChmaWVsZF90eXBlLCB0b19tZW0sIGZyb21fbWVtKTsKKyAgICBuZXdfcnB0ZmllbGRfc2VsZi0+c2l6ZSsrOworICB9CisKKyAgcmV0dXJuIG5ld19ycHRmaWVsZDsKK30KKworLy8gSW50ZXJuYWwgb25seTogdXNlZCBieSBHb29nbGU6OlByb3RvYnVmLmRlZXBfY29weS4KK1ZBTFVFIFJlcGVhdGVkRmllbGRfZGVlcF9jb3B5KFZBTFVFIF9zZWxmKSB7CisgIFJlcGVhdGVkRmllbGQqIHNlbGYgPSBydWJ5X3RvX1JlcGVhdGVkRmllbGQoX3NlbGYpOworICBWQUxVRSBuZXdfcnB0ZmllbGQgPSBSZXBlYXRlZEZpZWxkX25ld190aGlzX3R5cGUoX3NlbGYpOworICBSZXBlYXRlZEZpZWxkKiBuZXdfcnB0ZmllbGRfc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChuZXdfcnB0ZmllbGQpOworICBSZXBlYXRlZEZpZWxkX3Jlc2VydmUobmV3X3JwdGZpZWxkX3NlbGYsIHNlbGYtPnNpemUpOworICB1cGJfZmllbGR0eXBlX3QgZmllbGRfdHlwZSA9IHNlbGYtPmZpZWxkX3R5cGU7CisgIHNpemVfdCBlbGVtX3NpemUgPSBuYXRpdmVfc2xvdF9zaXplKGZpZWxkX3R5cGUpOworICBzaXplX3Qgb2ZmID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWxmLT5zaXplOyBpKyssIG9mZiArPSBlbGVtX3NpemUpIHsKKyAgICB2b2lkKiB0b19tZW0gPSAodWludDhfdCAqKW5ld19ycHRmaWVsZF9zZWxmLT5lbGVtZW50cyArIG9mZjsKKyAgICB2b2lkKiBmcm9tX21lbSA9ICh1aW50OF90ICopc2VsZi0+ZWxlbWVudHMgKyBvZmY7CisgICAgbmF0aXZlX3Nsb3RfZGVlcF9jb3B5KGZpZWxkX3R5cGUsIHRvX21lbSwgZnJvbV9tZW0pOworICAgIG5ld19ycHRmaWVsZF9zZWxmLT5zaXplKys7CisgIH0KKworICByZXR1cm4gbmV3X3JwdGZpZWxkOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC50b19hcnkgPT4gYXJyYXkKKyAqCisgKiBVc2VkIHdoZW4gY29udmVydGVkIGltcGxpY2l0bHkgaW50byBhcnJheSwgZS5nLiBjb21wYXJlZCB0byBhbiBBcnJheS4KKyAqIEFsc28gY2FsbGVkIGFzIGEgZmFsbGJhY2sgb2YgT2JqZWN0I3RvX2EKKyAqLworVkFMVUUgUmVwZWF0ZWRGaWVsZF90b19hcnkoVkFMVUUgX3NlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIHVwYl9maWVsZHR5cGVfdCBmaWVsZF90eXBlID0gc2VsZi0+ZmllbGRfdHlwZTsKKworICBzaXplX3QgZWxlbV9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKyAgc2l6ZV90IG9mZiA9IDA7CisgIFZBTFVFIGFyeSA9IHJiX2FyeV9uZXcyKHNlbGYtPnNpemUpOworICBmb3IgKGludCBpID0gMDsgaSA8IHNlbGYtPnNpemU7IGkrKywgb2ZmICs9IGVsZW1fc2l6ZSkgeworICAgIHZvaWQqIG1lbSA9ICgodWludDhfdCAqKXNlbGYtPmVsZW1lbnRzKSArIG9mZjsKKyAgICBWQUxVRSBlbGVtID0gbmF0aXZlX3Nsb3RfZ2V0KGZpZWxkX3R5cGUsIHNlbGYtPmZpZWxkX3R5cGVfY2xhc3MsIG1lbSk7CisKKyAgICByYl9hcnlfcHVzaChhcnksIGVsZW0pOworICB9CisgIHJldHVybiBhcnk7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBSZXBlYXRlZEZpZWxkLj09KG90aGVyKSA9PiBib29sZWFuCisgKgorICogQ29tcGFyZXMgdGhpcyByZXBlYXRlZCBmaWVsZCB0byBhbm90aGVyLiBSZXBlYXRlZCBmaWVsZHMgYXJlIGVxdWFsIGlmIHRoZWlyCisgKiBlbGVtZW50IHR5cGVzIGFyZSBlcXVhbCwgdGhlaXIgbGVuZ3RocyBhcmUgZXF1YWwsIGFuZCBlYWNoIGVsZW1lbnQgaXMgZXF1YWwuCisgKiBFbGVtZW50cyBhcmUgY29tcGFyZWQgYXMgcGVyIG5vcm1hbCBSdWJ5IHNlbWFudGljcywgYnkgY2FsbGluZyB0aGVpciA6PT0KKyAqIG1ldGhvZHMgKG9yIHBlcmZvcm1pbmcgYSBtb3JlIGVmZmljaWVudCBjb21wYXJpc29uIGZvciBwcmltaXRpdmUgdHlwZXMpLgorICoKKyAqIFJlcGVhdGVkIGZpZWxkcyB3aXRoIGRpc3NpbWlsYXIgZWxlbWVudCB0eXBlcyBhcmUgbmV2ZXIgZXF1YWwsIGV2ZW4gaWYgdmFsdWUKKyAqIGNvbXBhcmlzb24gKGZvciBleGFtcGxlLCBiZXR3ZWVuIGludGVnZXJzIGFuZCBmbG9hdHMpIHdvdWxkIGhhdmUgb3RoZXJ3aXNlCisgKiBpbmRpY2F0ZWQgdGhhdCBldmVyeSBlbGVtZW50IGhhcyBlcXVhbCB2YWx1ZS4KKyAqLworVkFMVUUgUmVwZWF0ZWRGaWVsZF9lcShWQUxVRSBfc2VsZiwgVkFMVUUgX290aGVyKSB7CisgIGlmIChfc2VsZiA9PSBfb3RoZXIpIHsKKyAgICByZXR1cm4gUXRydWU7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisKKyAgaWYgKFRZUEUoX290aGVyKSA9PSBUX0FSUkFZKSB7CisgICAgVkFMVUUgc2VsZl9hcnkgPSBSZXBlYXRlZEZpZWxkX3RvX2FyeShfc2VsZik7CisgICAgcmV0dXJuIHJiX2VxdWFsKHNlbGZfYXJ5LCBfb3RoZXIpOworICB9CisKKyAgUmVwZWF0ZWRGaWVsZCogb3RoZXIgPSBydWJ5X3RvX1JlcGVhdGVkRmllbGQoX290aGVyKTsKKyAgaWYgKHNlbGYtPmZpZWxkX3R5cGUgIT0gb3RoZXItPmZpZWxkX3R5cGUgfHwKKyAgICAgIHNlbGYtPmZpZWxkX3R5cGVfY2xhc3MgIT0gb3RoZXItPmZpZWxkX3R5cGVfY2xhc3MgfHwKKyAgICAgIHNlbGYtPnNpemUgIT0gb3RoZXItPnNpemUpIHsKKyAgICByZXR1cm4gUWZhbHNlOworICB9CisKKyAgdXBiX2ZpZWxkdHlwZV90IGZpZWxkX3R5cGUgPSBzZWxmLT5maWVsZF90eXBlOworICBzaXplX3QgZWxlbV9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKyAgc2l6ZV90IG9mZiA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VsZi0+c2l6ZTsgaSsrLCBvZmYgKz0gZWxlbV9zaXplKSB7CisgICAgdm9pZCogc2VsZl9tZW0gPSAoKHVpbnQ4X3QgKilzZWxmLT5lbGVtZW50cykgKyBvZmY7CisgICAgdm9pZCogb3RoZXJfbWVtID0gKCh1aW50OF90ICopb3RoZXItPmVsZW1lbnRzKSArIG9mZjsKKyAgICBpZiAoIW5hdGl2ZV9zbG90X2VxKGZpZWxkX3R5cGUsIHNlbGZfbWVtLCBvdGhlcl9tZW0pKSB7CisgICAgICByZXR1cm4gUWZhbHNlOworICAgIH0KKyAgfQorICByZXR1cm4gUXRydWU7Cit9CisKKy8qCisgKiBjYWxsLXNlcToKKyAqICAgICBSZXBlYXRlZEZpZWxkLmhhc2ggPT4gaGFzaF92YWx1ZQorICoKKyAqIFJldHVybnMgYSBoYXNoIHZhbHVlIGNvbXB1dGVkIGZyb20gdGhpcyByZXBlYXRlZCBmaWVsZCdzIGVsZW1lbnRzLgorICovCitWQUxVRSBSZXBlYXRlZEZpZWxkX2hhc2goVkFMVUUgX3NlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisKKyAgVkFMVUUgaGFzaCA9IExMMk5VTSgwKTsKKworICB1cGJfZmllbGR0eXBlX3QgZmllbGRfdHlwZSA9IHNlbGYtPmZpZWxkX3R5cGU7CisgIFZBTFVFIGZpZWxkX3R5cGVfY2xhc3MgPSBzZWxmLT5maWVsZF90eXBlX2NsYXNzOworICBzaXplX3QgZWxlbV9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZShmaWVsZF90eXBlKTsKKyAgc2l6ZV90IG9mZiA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VsZi0+c2l6ZTsgaSsrLCBvZmYgKz0gZWxlbV9zaXplKSB7CisgICAgdm9pZCogbWVtID0gKCh1aW50OF90ICopc2VsZi0+ZWxlbWVudHMpICsgb2ZmOworICAgIFZBTFVFIGVsZW0gPSBuYXRpdmVfc2xvdF9nZXQoZmllbGRfdHlwZSwgZmllbGRfdHlwZV9jbGFzcywgbWVtKTsKKyAgICBoYXNoID0gcmJfZnVuY2FsbChoYXNoLCByYl9pbnRlcm4oIjw8IiksIDEsIElOVDJOVU0oMikpOworICAgIGhhc2ggPSByYl9mdW5jYWxsKGhhc2gsIHJiX2ludGVybigiXiIpLCAxLAorICAgICAgICAgICAgICAgICAgICAgIHJiX2Z1bmNhbGwoZWxlbSwgcmJfaW50ZXJuKCJoYXNoIiksIDApKTsKKyAgfQorCisgIHJldHVybiBoYXNoOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC5pbnNwZWN0ID0+IHN0cmluZworICoKKyAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoaXMgcmVwZWF0ZWQgZmllbGQncyBlbGVtZW50cy4gSXQgd2lsbCBiZQorICogZm9ybWF0ZWQgYXMgIls8ZWxlbWVudD4sIDxlbGVtZW50PiwgLi4uXSIsIHdpdGggZWFjaCBlbGVtZW50J3Mgc3RyaW5nCisgKiByZXByZXNlbnRhdGlvbiBjb21wdXRlZCBieSBpdHMgb3duICNpbnNwZWN0IG1ldGhvZC4KKyAqLworVkFMVUUgUmVwZWF0ZWRGaWVsZF9pbnNwZWN0KFZBTFVFIF9zZWxmKSB7CisgIFZBTFVFIHNlbGZfYXJ5ID0gUmVwZWF0ZWRGaWVsZF90b19hcnkoX3NlbGYpOworICByZXR1cm4gcmJfZnVuY2FsbChzZWxmX2FyeSwgcmJfaW50ZXJuKCJpbnNwZWN0IiksIDApOworfQorCisvKgorICogY2FsbC1zZXE6CisgKiAgICAgUmVwZWF0ZWRGaWVsZC4rKG90aGVyKSA9PiByZXBlYXRlZCBmaWVsZAorICoKKyAqIFJldHVybnMgYSBuZXcgcmVwZWF0ZWQgZmllbGQgdGhhdCBjb250YWlucyB0aGUgY29uY2F0ZW5hdGVkIGxpc3Qgb2YgdGhpcworICogcmVwZWF0ZWQgZmllbGQncyBlbGVtZW50cyBhbmQgb3RoZXIncyBlbGVtZW50cy4gVGhlIG90aGVyIChzZWNvbmQpIGxpc3QgbWF5CisgKiBiZSBlaXRoZXIgYW5vdGhlciByZXBlYXRlZCBmaWVsZCBvciBhIFJ1YnkgYXJyYXkuCisgKi8KK1ZBTFVFIFJlcGVhdGVkRmllbGRfcGx1cyhWQUxVRSBfc2VsZiwgVkFMVUUgbGlzdCkgeworICBWQUxVRSBkdXBwZWQgPSBSZXBlYXRlZEZpZWxkX2R1cChfc2VsZik7CisKKyAgaWYgKFRZUEUobGlzdCkgPT0gVF9BUlJBWSkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkFSUkFZX0xFTihsaXN0KTsgaSsrKSB7CisgICAgICBWQUxVRSBlbGVtID0gcmJfYXJ5X2VudHJ5KGxpc3QsIGkpOworICAgICAgUmVwZWF0ZWRGaWVsZF9wdXNoKGR1cHBlZCwgZWxlbSk7CisgICAgfQorICB9IGVsc2UgaWYgKFJCX1RZUEVfUChsaXN0LCBUX0RBVEEpICYmIFJUWVBFRERBVEFfUChsaXN0KSAmJgorICAgICAgICAgICAgIFJUWVBFRERBVEFfVFlQRShsaXN0KSA9PSAmUmVwZWF0ZWRGaWVsZF90eXBlKSB7CisgICAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgICAgUmVwZWF0ZWRGaWVsZCogbGlzdF9ycHRmaWVsZCA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChsaXN0KTsKKyAgICBpZiAoc2VsZi0+ZmllbGRfdHlwZSAhPSBsaXN0X3JwdGZpZWxkLT5maWVsZF90eXBlIHx8CisgICAgICAgIHNlbGYtPmZpZWxkX3R5cGVfY2xhc3MgIT0gbGlzdF9ycHRmaWVsZC0+ZmllbGRfdHlwZV9jbGFzcykgeworICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLAorICAgICAgICAgICAgICAgIkF0dGVtcHQgdG8gYXBwZW5kIFJlcGVhdGVkRmllbGQgd2l0aCBkaWZmZXJlbnQgZWxlbWVudCB0eXBlLiIpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3RfcnB0ZmllbGQtPnNpemU7IGkrKykgeworICAgICAgdm9pZCogbWVtID0gUmVwZWF0ZWRGaWVsZF9pbmRleF9uYXRpdmUobGlzdCwgaSk7CisgICAgICBSZXBlYXRlZEZpZWxkX3B1c2hfbmF0aXZlKGR1cHBlZCwgbWVtKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiVW5rbm93biB0eXBlIGFwcGVuZGluZyB0byBSZXBlYXRlZEZpZWxkIik7CisgIH0KKworICByZXR1cm4gZHVwcGVkOworfQorCit2b2lkIHZhbGlkYXRlX3R5cGVfY2xhc3ModXBiX2ZpZWxkdHlwZV90IHR5cGUsIFZBTFVFIGtsYXNzKSB7CisgIGlmIChyYl9pdl9nZXQoa2xhc3MsIGtEZXNjcmlwdG9ySW5zdGFuY2VWYXIpID09IFFuaWwpIHsKKyAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsCisgICAgICAgICAgICAgIlR5cGUgY2xhc3MgaGFzIG5vIGRlc2NyaXB0b3IuIFBsZWFzZSBwYXNzIGEgIgorICAgICAgICAgICAgICJjbGFzcyBvciBlbnVtIGFzIHJldHVybmVkIGJ5IHRoZSBEZXNjcmlwdG9yUG9vbC4iKTsKKyAgfQorICBpZiAodHlwZSA9PSBVUEJfVFlQRV9NRVNTQUdFKSB7CisgICAgVkFMVUUgZGVzYyA9IHJiX2l2X2dldChrbGFzcywga0Rlc2NyaXB0b3JJbnN0YW5jZVZhcik7CisgICAgaWYgKCFSQl9UWVBFX1AoZGVzYywgVF9EQVRBKSB8fCAhUlRZUEVEREFUQV9QKGRlc2MpIHx8CisgICAgICAgIFJUWVBFRERBVEFfVFlQRShkZXNjKSAhPSAmX0Rlc2NyaXB0b3JfdHlwZSkgeworICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiRGVzY3JpcHRvciBoYXMgYW4gaW5jb3JyZWN0IHR5cGUuIik7CisgICAgfQorICAgIGlmIChyYl9nZXRfYWxsb2NfZnVuYyhrbGFzcykgIT0gJk1lc3NhZ2VfYWxsb2MpIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwKKyAgICAgICAgICAgICAgICJNZXNzYWdlIGNsYXNzIHdhcyBub3QgcmV0dXJuZWQgYnkgdGhlIERlc2NyaXB0b3JQb29sLiIpOworICAgIH0KKyAgfSBlbHNlIGlmICh0eXBlID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICBWQUxVRSBlbnVtZGVzYyA9IHJiX2l2X2dldChrbGFzcywga0Rlc2NyaXB0b3JJbnN0YW5jZVZhcik7CisgICAgaWYgKCFSQl9UWVBFX1AoZW51bWRlc2MsIFRfREFUQSkgfHwgIVJUWVBFRERBVEFfUChlbnVtZGVzYykgfHwKKyAgICAgICAgUlRZUEVEREFUQV9UWVBFKGVudW1kZXNjKSAhPSAmX0VudW1EZXNjcmlwdG9yX3R5cGUpIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkRlc2NyaXB0b3IgaGFzIGFuIGluY29ycmVjdCB0eXBlLiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIFJlcGVhdGVkRmllbGRfaW5pdF9hcmdzKGludCBhcmdjLCBWQUxVRSogYXJndiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgX3NlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IHJ1YnlfdG9fUmVwZWF0ZWRGaWVsZChfc2VsZik7CisgIFZBTFVFIGFyeSA9IFFuaWw7CisgIGlmIChhcmdjIDwgMSkgeworICAgIHJiX3JhaXNlKHJiX2VBcmdFcnJvciwgIkV4cGVjdGVkIGF0IGxlYXN0IDEgYXJndW1lbnQuIik7CisgIH0KKyAgc2VsZi0+ZmllbGRfdHlwZSA9IHJ1YnlfdG9fZmllbGR0eXBlKGFyZ3ZbMF0pOworCisgIGlmIChzZWxmLT5maWVsZF90eXBlID09IFVQQl9UWVBFX01FU1NBR0UgfHwKKyAgICAgIHNlbGYtPmZpZWxkX3R5cGUgPT0gVVBCX1RZUEVfRU5VTSkgeworICAgIGlmIChhcmdjIDwgMikgeworICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiRXhwZWN0ZWQgYXQgbGVhc3QgMiBhcmd1bWVudHMgZm9yIG1lc3NhZ2UvZW51bS4iKTsKKyAgICB9CisgICAgc2VsZi0+ZmllbGRfdHlwZV9jbGFzcyA9IGFyZ3ZbMV07CisgICAgaWYgKGFyZ2MgPiAyKSB7CisgICAgICBhcnkgPSBhcmd2WzJdOworICAgIH0KKyAgICB2YWxpZGF0ZV90eXBlX2NsYXNzKHNlbGYtPmZpZWxkX3R5cGUsIHNlbGYtPmZpZWxkX3R5cGVfY2xhc3MpOworICB9IGVsc2UgeworICAgIGlmIChhcmdjID4gMikgeworICAgICAgcmJfcmFpc2UocmJfZUFyZ0Vycm9yLCAiVG9vIG1hbnkgYXJndW1lbnRzOiBleHBlY3RlZCAxIG9yIDIuIik7CisgICAgfQorICAgIGlmIChhcmdjID4gMSkgeworICAgICAgYXJ5ID0gYXJndlsxXTsKKyAgICB9CisgIH0KKworICBpZiAoYXJ5ICE9IFFuaWwpIHsKKyAgICBpZiAoIVJCX1RZUEVfUChhcnksIFRfQVJSQVkpKSB7CisgICAgICByYl9yYWlzZShyYl9lQXJnRXJyb3IsICJFeHBlY3RlZCBhcnJheSBhcyBpbml0aWFsaXplIGFyZ3VtZW50Iik7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkFSUkFZX0xFTihhcnkpOyBpKyspIHsKKyAgICAgIFJlcGVhdGVkRmllbGRfcHVzaChfc2VsZiwgcmJfYXJ5X2VudHJ5KGFyeSwgaSkpOworICAgIH0KKyAgfQorfQorCisvLyBNYXJrLCBmcmVlLCBhbGxvYywgaW5pdCBhbmQgY2xhc3Mgc2V0dXAgZnVuY3Rpb25zLgorCit2b2lkIFJlcGVhdGVkRmllbGRfbWFyayh2b2lkKiBfc2VsZikgeworICBSZXBlYXRlZEZpZWxkKiBzZWxmID0gKFJlcGVhdGVkRmllbGQqKV9zZWxmOworICByYl9nY19tYXJrKHNlbGYtPmZpZWxkX3R5cGVfY2xhc3MpOworICB1cGJfZmllbGR0eXBlX3QgZmllbGRfdHlwZSA9IHNlbGYtPmZpZWxkX3R5cGU7CisgIGludCBlbGVtZW50X3NpemUgPSBuYXRpdmVfc2xvdF9zaXplKGZpZWxkX3R5cGUpOworICBmb3IgKGludCBpID0gMDsgaSA8IHNlbGYtPnNpemU7IGkrKykgeworICAgIHZvaWQqIG1lbW9yeSA9ICgoKHVpbnQ4X3QgKilzZWxmLT5lbGVtZW50cykgKyBpICogZWxlbWVudF9zaXplKTsKKyAgICBuYXRpdmVfc2xvdF9tYXJrKHNlbGYtPmZpZWxkX3R5cGUsIG1lbW9yeSk7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEZpZWxkX2ZyZWUodm9pZCogX3NlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IChSZXBlYXRlZEZpZWxkKilfc2VsZjsKKyAgeGZyZWUoc2VsZi0+ZWxlbWVudHMpOworICB4ZnJlZShzZWxmKTsKK30KKworLyoKKyAqIGNhbGwtc2VxOgorICogICAgIFJlcGVhdGVkRmllbGQubmV3KHR5cGUsIHR5cGVfY2xhc3MgPSBuaWwsIGluaXRpYWxfZWxlbXMgPSBbXSkKKyAqCisgKiBDcmVhdGVzIGEgbmV3IHJlcGVhdGVkIGZpZWxkLiBUaGUgcHJvdmlkZWQgdHlwZSBtdXN0IGJlIGEgUnVieSBzeW1ib2wsIGFuZAorICogY2FuIHRha2Ugb24gdGhlIHNhbWUgdmFsdWVzIGFzIHRob3NlIGFjY2VwdGVkIGJ5IEZpZWxkRGVzY3JpcHRvciN0eXBlPS4gSWYKKyAqIHRoZSB0eXBlIGlzIDptZXNzYWdlIG9yIDplbnVtLCB0eXBlX2NsYXNzIG11c3QgYmUgbm9uLW5pbCwgYW5kIG11c3QgYmUgdGhlCisgKiBSdWJ5IGNsYXNzIG9yIG1vZHVsZSByZXR1cm5lZCBieSBEZXNjcmlwdG9yI21zZ2NsYXNzIG9yCisgKiBFbnVtRGVzY3JpcHRvciNlbnVtbW9kdWxlLCByZXNwZWN0aXZlbHkuIEFuIGluaXRpYWwgbGlzdCBvZiBlbGVtZW50cyBtYXkgYWxzbworICogYmUgcHJvdmlkZWQuCisgKi8KK1ZBTFVFIFJlcGVhdGVkRmllbGRfYWxsb2MoVkFMVUUga2xhc3MpIHsKKyAgUmVwZWF0ZWRGaWVsZCogc2VsZiA9IEFMTE9DKFJlcGVhdGVkRmllbGQpOworICBzZWxmLT5lbGVtZW50cyA9IE5VTEw7CisgIHNlbGYtPnNpemUgPSAwOworICBzZWxmLT5jYXBhY2l0eSA9IDA7CisgIHNlbGYtPmZpZWxkX3R5cGUgPSAtMTsKKyAgc2VsZi0+ZmllbGRfdHlwZV9jbGFzcyA9IFFuaWw7CisgIFZBTFVFIHJldCA9IFR5cGVkRGF0YV9XcmFwX1N0cnVjdChrbGFzcywgJlJlcGVhdGVkRmllbGRfdHlwZSwgc2VsZik7CisgIHJldHVybiByZXQ7Cit9CisKK1ZBTFVFIFJlcGVhdGVkRmllbGRfaW5pdChpbnQgYXJnYywgVkFMVUUqIGFyZ3YsIFZBTFVFIHNlbGYpIHsKKyAgUmVwZWF0ZWRGaWVsZF9pbml0X2FyZ3MoYXJnYywgYXJndiwgc2VsZik7CisgIHJldHVybiBRbmlsOworfQorCit2b2lkIFJlcGVhdGVkRmllbGRfcmVnaXN0ZXIoVkFMVUUgbW9kdWxlKSB7CisgIFZBTFVFIGtsYXNzID0gcmJfZGVmaW5lX2NsYXNzX3VuZGVyKAorICAgICAgbW9kdWxlLCAiUmVwZWF0ZWRGaWVsZCIsIHJiX2NPYmplY3QpOworICByYl9kZWZpbmVfYWxsb2NfZnVuYyhrbGFzcywgUmVwZWF0ZWRGaWVsZF9hbGxvYyk7CisgIGNSZXBlYXRlZEZpZWxkID0ga2xhc3M7CisgIHJiX2djX3JlZ2lzdGVyX2FkZHJlc3MoJmNSZXBlYXRlZEZpZWxkKTsKKworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiaW5pdGlhbGl6ZSIsCisgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZF9pbml0LCAtMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJlYWNoIiwgUmVwZWF0ZWRGaWVsZF9lYWNoLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIltdIiwgUmVwZWF0ZWRGaWVsZF9pbmRleCwgMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJbXT0iLCBSZXBlYXRlZEZpZWxkX2luZGV4X3NldCwgMik7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJwdXNoIiwgUmVwZWF0ZWRGaWVsZF9wdXNoLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIjw8IiwgUmVwZWF0ZWRGaWVsZF9wdXNoLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgInBvcCIsIFJlcGVhdGVkRmllbGRfcG9wLCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImluc2VydCIsIFJlcGVhdGVkRmllbGRfaW5zZXJ0LCAtMSk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJyZXBsYWNlIiwgUmVwZWF0ZWRGaWVsZF9yZXBsYWNlLCAxKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgImNsZWFyIiwgUmVwZWF0ZWRGaWVsZF9jbGVhciwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJsZW5ndGgiLCBSZXBlYXRlZEZpZWxkX2xlbmd0aCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJkdXAiLCBSZXBlYXRlZEZpZWxkX2R1cCwgMCk7CisgIC8vIEFsc28gZGVmaW5lICNjbG9uZSBzbyB0aGF0IHdlIGRvbid0IGluaGVyaXQgT2JqZWN0I2Nsb25lLgorICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiY2xvbmUiLCBSZXBlYXRlZEZpZWxkX2R1cCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICI9PSIsIFJlcGVhdGVkRmllbGRfZXEsIDEpOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAidG9fYXJ5IiwgUmVwZWF0ZWRGaWVsZF90b19hcnksIDApOworICByYl9kZWZpbmVfbWV0aG9kKGtsYXNzLCAiaGFzaCIsIFJlcGVhdGVkRmllbGRfaGFzaCwgMCk7CisgIHJiX2RlZmluZV9tZXRob2Qoa2xhc3MsICJpbnNwZWN0IiwgUmVwZWF0ZWRGaWVsZF9pbnNwZWN0LCAwKTsKKyAgcmJfZGVmaW5lX21ldGhvZChrbGFzcywgIisiLCBSZXBlYXRlZEZpZWxkX3BsdXMsIDEpOworICByYl9pbmNsdWRlX21vZHVsZShrbGFzcywgcmJfbUVudW1lcmFibGUpOworfQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2Mvc3RvcmFnZS5jIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2Mvc3RvcmFnZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViMTU0OWQKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy9zdG9yYWdlLmMKQEAgLTAsMCArMSw4NDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSAicHJvdG9idWYuaCIKKworI2luY2x1ZGUgPG1hdGguaD4KKworI2luY2x1ZGUgPHJ1YnkvZW5jb2RpbmcuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFJ1YnkgPC0+IG5hdGl2ZSBzbG90IG1hbmFnZW1lbnQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIERFUkVGKG1lbW9yeSwgdHlwZSkgKih0eXBlKikobWVtb3J5KQorCitzaXplX3QgbmF0aXZlX3Nsb3Rfc2l6ZSh1cGJfZmllbGR0eXBlX3QgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0ZMT0FUOiAgIHJldHVybiA0OworICAgIGNhc2UgVVBCX1RZUEVfRE9VQkxFOiAgcmV0dXJuIDg7CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOiAgICByZXR1cm4gMTsKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzogIHJldHVybiBzaXplb2YoVkFMVUUpOworICAgIGNhc2UgVVBCX1RZUEVfQllURVM6ICAgcmV0dXJuIHNpemVvZihWQUxVRSk7CisgICAgY2FzZSBVUEJfVFlQRV9NRVNTQUdFOiByZXR1cm4gc2l6ZW9mKFZBTFVFKTsKKyAgICBjYXNlIFVQQl9UWVBFX0VOVU06ICAgIHJldHVybiA0OworICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6ICAgcmV0dXJuIDQ7CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDogICByZXR1cm4gODsKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjogIHJldHVybiA0OworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDY0OiAgcmV0dXJuIDg7CisgICAgZGVmYXVsdDogcmV0dXJuIDA7CisgIH0KK30KKworc3RhdGljIGJvb2wgaXNfcnVieV9udW0oVkFMVUUgdmFsdWUpIHsKKyAgcmV0dXJuIChUWVBFKHZhbHVlKSA9PSBUX0ZMT0FUIHx8CisgICAgICAgICAgVFlQRSh2YWx1ZSkgPT0gVF9GSVhOVU0gfHwKKyAgICAgICAgICBUWVBFKHZhbHVlKSA9PSBUX0JJR05VTSk7Cit9CisKK3ZvaWQgbmF0aXZlX3Nsb3RfY2hlY2tfaW50X3JhbmdlX3ByZWNpc2lvbih1cGJfZmllbGR0eXBlX3QgdHlwZSwgVkFMVUUgdmFsKSB7CisgIGlmICghaXNfcnVieV9udW0odmFsKSkgeworICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsICJFeHBlY3RlZCBudW1iZXIgdHlwZSBmb3IgaW50ZWdyYWwgZmllbGQuIik7CisgIH0KKworICAvLyBOVU0ye0lOVCxVSU5ULExMLFVMTH0gbWFjcm9zIGRvIHRoZSBhcHByb3ByaWF0ZSByYW5nZSBjaGVja3Mgb24gdXBwZXIKKyAgLy8gYm91bmQ7IHdlIGp1c3QgbmVlZCB0byBkbyBwcmVjaXNpb24gY2hlY2tzIChpLmUuLCBkaXNhbGxvdyByb3VuZGluZykgYW5kCisgIC8vIGNoZWNrIGZvciA8IDAgb24gdW5zaWduZWQgdHlwZXMuCisgIGlmIChUWVBFKHZhbCkgPT0gVF9GTE9BVCkgeworICAgIGRvdWJsZSBkYmxfdmFsID0gTlVNMkRCTCh2YWwpOworICAgIGlmIChmbG9vcihkYmxfdmFsKSAhPSBkYmxfdmFsKSB7CisgICAgICByYl9yYWlzZShyYl9lUmFuZ2VFcnJvciwKKyAgICAgICAgICAgICAgICJOb24taW50ZWdyYWwgZmxvYXRpbmcgcG9pbnQgdmFsdWUgYXNzaWduZWQgdG8gaW50ZWdlciBmaWVsZC4iKTsKKyAgICB9CisgIH0KKyAgaWYgKHR5cGUgPT0gVVBCX1RZUEVfVUlOVDMyIHx8IHR5cGUgPT0gVVBCX1RZUEVfVUlOVDY0KSB7CisgICAgaWYgKE5VTTJEQkwodmFsKSA8IDApIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VSYW5nZUVycm9yLAorICAgICAgICAgICAgICAgIkFzc2lnbmluZyBuZWdhdGl2ZSB2YWx1ZSB0byB1bnNpZ25lZCBpbnRlZ2VyIGZpZWxkLiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIG5hdGl2ZV9zbG90X3ZhbGlkYXRlX3N0cmluZ19lbmNvZGluZyh1cGJfZmllbGR0eXBlX3QgdHlwZSwgVkFMVUUgdmFsdWUpIHsKKyAgYm9vbCBiYWRfZW5jb2RpbmcgPSBmYWxzZTsKKyAgcmJfZW5jb2RpbmcqIHN0cmluZ19lbmNvZGluZyA9IHJiX2VuY19mcm9tX2luZGV4KEVOQ09ESU5HX0dFVCh2YWx1ZSkpOworICBpZiAodHlwZSA9PSBVUEJfVFlQRV9TVFJJTkcpIHsKKyAgICBiYWRfZW5jb2RpbmcgPQorICAgICAgICBzdHJpbmdfZW5jb2RpbmcgIT0ga1J1YnlTdHJpbmdVdGY4RW5jb2RpbmcgJiYKKyAgICAgICAgc3RyaW5nX2VuY29kaW5nICE9IGtSdWJ5U3RyaW5nQVNDSUlFbmNvZGluZzsKKyAgfSBlbHNlIHsKKyAgICBiYWRfZW5jb2RpbmcgPQorICAgICAgICBzdHJpbmdfZW5jb2RpbmcgIT0ga1J1YnlTdHJpbmc4Yml0RW5jb2Rpbmc7CisgIH0KKyAgLy8gQ2hlY2sgdGhhdCBlbmNvZGluZyBpcyBVVEYtOCBvciBBU0NJSSAoZm9yIHN0cmluZyBmaWVsZHMpIG9yIEFTQ0lJLThCSVQKKyAgLy8gKGZvciBieXRlcyBmaWVsZHMpLgorICBpZiAoYmFkX2VuY29kaW5nKSB7CisgICAgcmJfcmFpc2UocmJfZVR5cGVFcnJvciwgIkVuY29kaW5nIGZvciAnJXMnIGZpZWxkcyBtdXN0IGJlICVzICh3YXMgJXMpIiwKKyAgICAgICAgICAgICAodHlwZSA9PSBVUEJfVFlQRV9TVFJJTkcpID8gInN0cmluZyIgOiAiYnl0ZXMiLAorICAgICAgICAgICAgICh0eXBlID09IFVQQl9UWVBFX1NUUklORykgPyAiVVRGLTggb3IgQVNDSUkiIDogIkFTQ0lJLThCSVQiLAorICAgICAgICAgICAgIHJiX2VuY19uYW1lKHN0cmluZ19lbmNvZGluZykpOworICB9Cit9CisKK3ZvaWQgbmF0aXZlX3Nsb3Rfc2V0KHVwYl9maWVsZHR5cGVfdCB0eXBlLCBWQUxVRSB0eXBlX2NsYXNzLAorICAgICAgICAgICAgICAgICAgICAgdm9pZCogbWVtb3J5LCBWQUxVRSB2YWx1ZSkgeworICBuYXRpdmVfc2xvdF9zZXRfdmFsdWVfYW5kX2Nhc2UodHlwZSwgdHlwZV9jbGFzcywgbWVtb3J5LCB2YWx1ZSwgTlVMTCwgMCk7Cit9CisKK3ZvaWQgbmF0aXZlX3Nsb3Rfc2V0X3ZhbHVlX2FuZF9jYXNlKHVwYl9maWVsZHR5cGVfdCB0eXBlLCBWQUxVRSB0eXBlX2NsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogbWVtb3J5LCBWQUxVRSB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90KiBjYXNlX21lbW9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGNhc2VfbnVtYmVyKSB7CisgIC8vIE5vdGUgdGhhdCBpbiBvcmRlciB0byBhdG9taWNhbGx5IGNoYW5nZSB0aGUgdmFsdWUgaW4gbWVtb3J5IGFuZCB0aGUgY2FzZQorICAvLyB2YWx1ZSAody5yLnQuIFJ1YnkgVk0gY2FsbHMpLCB3ZSBtdXN0IHNldCB0aGUgdmFsdWUgYXQgfG1lbW9yeXwgb25seSBhZnRlcgorICAvLyBhbGwgUnVieSBWTSBjYWxscyBhcmUgY29tcGxldGUuIFRoZSBjYXNlIGlzIHRoZW4gc2V0IGF0IHRoZSBib3R0b20gb2YgdGhpcworICAvLyBmdW5jdGlvbi4KKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBVUEJfVFlQRV9GTE9BVDoKKyAgICAgIGlmICghaXNfcnVieV9udW0odmFsdWUpKSB7CisgICAgICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsICJFeHBlY3RlZCBudW1iZXIgdHlwZSBmb3IgZmxvYXQgZmllbGQuIik7CisgICAgICB9CisgICAgICBERVJFRihtZW1vcnksIGZsb2F0KSA9IE5VTTJEQkwodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9ET1VCTEU6CisgICAgICBpZiAoIWlzX3J1YnlfbnVtKHZhbHVlKSkgeworICAgICAgICByYl9yYWlzZShyYl9lVHlwZUVycm9yLCAiRXhwZWN0ZWQgbnVtYmVyIHR5cGUgZm9yIGRvdWJsZSBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIERFUkVGKG1lbW9yeSwgZG91YmxlKSA9IE5VTTJEQkwodmFsdWUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOiB7CisgICAgICBpbnQ4X3QgdmFsID0gLTE7CisgICAgICBpZiAodmFsdWUgPT0gUXRydWUpIHsKKyAgICAgICAgdmFsID0gMTsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gUWZhbHNlKSB7CisgICAgICAgIHZhbCA9IDA7CisgICAgICB9IGVsc2UgeworICAgICAgICByYl9yYWlzZShyYl9lVHlwZUVycm9yLCAiSW52YWxpZCBhcmd1bWVudCBmb3IgYm9vbGVhbiBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIERFUkVGKG1lbW9yeSwgaW50OF90KSA9IHZhbDsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOiB7CisgICAgICBpZiAoQ0xBU1NfT0YodmFsdWUpICE9IHJiX2NTdHJpbmcpIHsKKyAgICAgICAgcmJfcmFpc2UocmJfZVR5cGVFcnJvciwgIkludmFsaWQgYXJndW1lbnQgZm9yIHN0cmluZyBmaWVsZC4iKTsKKyAgICAgIH0KKyAgICAgIG5hdGl2ZV9zbG90X3ZhbGlkYXRlX3N0cmluZ19lbmNvZGluZyh0eXBlLCB2YWx1ZSk7CisgICAgICBERVJFRihtZW1vcnksIFZBTFVFKSA9IHZhbHVlOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRTogeworICAgICAgaWYgKENMQVNTX09GKHZhbHVlKSAhPSB0eXBlX2NsYXNzKSB7CisgICAgICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICJJbnZhbGlkIHR5cGUgJXMgdG8gYXNzaWduIHRvIHN1Ym1lc3NhZ2UgZmllbGQuIiwKKyAgICAgICAgICAgICAgICAgcmJfY2xhc3MybmFtZShDTEFTU19PRih2YWx1ZSkpKTsKKyAgICAgIH0KKyAgICAgIERFUkVGKG1lbW9yeSwgVkFMVUUpID0gdmFsdWU7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9FTlVNOiB7CisgICAgICBpZiAoIWlzX3J1YnlfbnVtKHZhbHVlKSAmJiBUWVBFKHZhbHVlKSAhPSBUX1NZTUJPTCkgeworICAgICAgICByYl9yYWlzZShyYl9lVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgbnVtYmVyIG9yIHN5bWJvbCB0eXBlIGZvciBlbnVtIGZpZWxkLiIpOworICAgICAgfQorICAgICAgaW50MzJfdCBpbnRfdmFsID0gMDsKKyAgICAgIGlmIChUWVBFKHZhbHVlKSA9PSBUX1NZTUJPTCkgeworICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgZ2l2ZW4gc3ltYm9sIGV4aXN0cyBpbiB0aGUgZW51bSBtb2R1bGUuCisgICAgICAgIFZBTFVFIGxvb2t1cCA9IHJiX2Z1bmNhbGwodHlwZV9jbGFzcywgcmJfaW50ZXJuKCJyZXNvbHZlIiksIDEsIHZhbHVlKTsKKyAgICAgICAgaWYgKGxvb2t1cCA9PSBRbmlsKSB7CisgICAgICAgICAgcmJfcmFpc2UocmJfZVJhbmdlRXJyb3IsICJVbmtub3duIHN5bWJvbCB2YWx1ZSBmb3IgZW51bSBmaWVsZC4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpbnRfdmFsID0gTlVNMklOVChsb29rdXApOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBuYXRpdmVfc2xvdF9jaGVja19pbnRfcmFuZ2VfcHJlY2lzaW9uKFVQQl9UWVBFX0lOVDMyLCB2YWx1ZSk7CisgICAgICAgIGludF92YWwgPSBOVU0ySU5UKHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIERFUkVGKG1lbW9yeSwgaW50MzJfdCkgPSBpbnRfdmFsOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDoKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjoKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDoKKyAgICAgIG5hdGl2ZV9zbG90X2NoZWNrX2ludF9yYW5nZV9wcmVjaXNpb24odHlwZSwgdmFsdWUpOworICAgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgICAgICBERVJFRihtZW1vcnksIGludDMyX3QpID0gTlVNMklOVCh2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDoKKyAgICAgICAgREVSRUYobWVtb3J5LCBpbnQ2NF90KSA9IE5VTTJMTCh2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVUEJfVFlQRV9VSU5UMzI6CisgICAgICAgIERFUkVGKG1lbW9yeSwgdWludDMyX3QpID0gTlVNMlVJTlQodmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVVBCX1RZUEVfVUlOVDY0OgorICAgICAgICBERVJFRihtZW1vcnksIHVpbnQ2NF90KSA9IE5VTTJVTEwodmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9CisKKyAgaWYgKGNhc2VfbWVtb3J5ICE9IE5VTEwpIHsKKyAgICAqY2FzZV9tZW1vcnkgPSBjYXNlX251bWJlcjsKKyAgfQorfQorCitWQUxVRSBuYXRpdmVfc2xvdF9nZXQodXBiX2ZpZWxkdHlwZV90IHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgdHlwZV9jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBtZW1vcnkpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBVUEJfVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBEQkwyTlVNKERFUkVGKG1lbW9yeSwgZmxvYXQpKTsKKyAgICBjYXNlIFVQQl9UWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiBEQkwyTlVNKERFUkVGKG1lbW9yeSwgZG91YmxlKSk7CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOgorICAgICAgcmV0dXJuIERFUkVGKG1lbW9yeSwgaW50OF90KSA/IFF0cnVlIDogUWZhbHNlOworICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOgorICAgIGNhc2UgVVBCX1RZUEVfQllURVM6CisgICAgY2FzZSBVUEJfVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIERFUkVGKG1lbW9yeSwgVkFMVUUpOworICAgIGNhc2UgVVBCX1RZUEVfRU5VTTogeworICAgICAgaW50MzJfdCB2YWwgPSBERVJFRihtZW1vcnksIGludDMyX3QpOworICAgICAgVkFMVUUgc3ltYm9sID0gZW51bV9sb29rdXAodHlwZV9jbGFzcywgSU5UMk5VTSh2YWwpKTsKKyAgICAgIGlmIChzeW1ib2wgPT0gUW5pbCkgeworICAgICAgICByZXR1cm4gSU5UMk5VTSh2YWwpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHN5bWJvbDsKKyAgICAgIH0KKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiBJTlQyTlVNKERFUkVGKG1lbW9yeSwgaW50MzJfdCkpOworICAgIGNhc2UgVVBCX1RZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gTEwyTlVNKERFUkVGKG1lbW9yeSwgaW50NjRfdCkpOworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuIFVJTlQyTlVNKERFUkVGKG1lbW9yeSwgdWludDMyX3QpKTsKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiBVTEwyTlVNKERFUkVGKG1lbW9yeSwgdWludDY0X3QpKTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIFFuaWw7CisgIH0KK30KKwordm9pZCBuYXRpdmVfc2xvdF9pbml0KHVwYl9maWVsZHR5cGVfdCB0eXBlLCB2b2lkKiBtZW1vcnkpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBVUEJfVFlQRV9GTE9BVDoKKyAgICAgIERFUkVGKG1lbW9yeSwgZmxvYXQpID0gMC4wOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9ET1VCTEU6CisgICAgICBERVJFRihtZW1vcnksIGRvdWJsZSkgPSAwLjA7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0JPT0w6CisgICAgICBERVJFRihtZW1vcnksIGludDhfdCkgPSAwOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9TVFJJTkc6CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzoKKyAgICAgIERFUkVGKG1lbW9yeSwgVkFMVUUpID0gcmJfc3RyX25ldzIoIiIpOworICAgICAgcmJfZW5jX2Fzc29jaWF0ZShERVJFRihtZW1vcnksIFZBTFVFKSwgKHR5cGUgPT0gVVBCX1RZUEVfQllURVMpID8KKyAgICAgICAgICAgICAgICAgICAgICAga1J1YnlTdHJpbmc4Yml0RW5jb2RpbmcgOiBrUnVieVN0cmluZ1V0ZjhFbmNvZGluZyk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX01FU1NBR0U6CisgICAgICBERVJFRihtZW1vcnksIFZBTFVFKSA9IFFuaWw7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0VOVU06CisgICAgY2FzZSBVUEJfVFlQRV9JTlQzMjoKKyAgICAgIERFUkVGKG1lbW9yeSwgaW50MzJfdCkgPSAwOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDoKKyAgICAgIERFUkVGKG1lbW9yeSwgaW50NjRfdCkgPSAwOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UMzI6CisgICAgICBERVJFRihtZW1vcnksIHVpbnQzMl90KSA9IDA7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDoKKyAgICAgIERFUkVGKG1lbW9yeSwgdWludDY0X3QpID0gMDsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBicmVhazsKKyAgfQorfQorCit2b2lkIG5hdGl2ZV9zbG90X21hcmsodXBiX2ZpZWxkdHlwZV90IHR5cGUsIHZvaWQqIG1lbW9yeSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOgorICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRToKKyAgICAgIHJiX2djX21hcmsoREVSRUYobWVtb3J5LCBWQUxVRSkpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgbmF0aXZlX3Nsb3RfZHVwKHVwYl9maWVsZHR5cGVfdCB0eXBlLCB2b2lkKiB0bywgdm9pZCogZnJvbSkgeworICBtZW1jcHkodG8sIGZyb20sIG5hdGl2ZV9zbG90X3NpemUodHlwZSkpOworfQorCit2b2lkIG5hdGl2ZV9zbG90X2RlZXBfY29weSh1cGJfZmllbGR0eXBlX3QgdHlwZSwgdm9pZCogdG8sIHZvaWQqIGZyb20pIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBVUEJfVFlQRV9TVFJJTkc6CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzogeworICAgICAgVkFMVUUgZnJvbV92YWwgPSBERVJFRihmcm9tLCBWQUxVRSk7CisgICAgICBERVJFRih0bywgVkFMVUUpID0gKGZyb21fdmFsICE9IFFuaWwpID8KKyAgICAgICAgICByYl9mdW5jYWxsKGZyb21fdmFsLCByYl9pbnRlcm4oImR1cCIpLCAwKSA6IFFuaWw7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9NRVNTQUdFOiB7CisgICAgICBWQUxVRSBmcm9tX3ZhbCA9IERFUkVGKGZyb20sIFZBTFVFKTsKKyAgICAgIERFUkVGKHRvLCBWQUxVRSkgPSAoZnJvbV92YWwgIT0gUW5pbCkgPworICAgICAgICAgIE1lc3NhZ2VfZGVlcF9jb3B5KGZyb21fdmFsKSA6IFFuaWw7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIG1lbWNweSh0bywgZnJvbSwgbmF0aXZlX3Nsb3Rfc2l6ZSh0eXBlKSk7CisgIH0KK30KKworYm9vbCBuYXRpdmVfc2xvdF9lcSh1cGJfZmllbGR0eXBlX3QgdHlwZSwgdm9pZCogbWVtMSwgdm9pZCogbWVtMikgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOgorICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRTogeworICAgICAgVkFMVUUgdmFsMSA9IERFUkVGKG1lbTEsIFZBTFVFKTsKKyAgICAgIFZBTFVFIHZhbDIgPSBERVJFRihtZW0yLCBWQUxVRSk7CisgICAgICBWQUxVRSByZXQgPSByYl9mdW5jYWxsKHZhbDEsIHJiX2ludGVybigiPT0iKSwgMSwgdmFsMik7CisgICAgICByZXR1cm4gcmV0ID09IFF0cnVlOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuICFtZW1jbXAobWVtMSwgbWVtMiwgbmF0aXZlX3Nsb3Rfc2l6ZSh0eXBlKSk7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1hcCBmaWVsZCB1dGlsaXRpZXMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitib29sIGlzX21hcF9maWVsZChjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkKSB7CisgIGlmICh1cGJfZmllbGRkZWZfbGFiZWwoZmllbGQpICE9IFVQQl9MQUJFTF9SRVBFQVRFRCB8fAorICAgICAgdXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpICE9IFVQQl9UWVBFX01FU1NBR0UpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgY29uc3QgdXBiX21zZ2RlZiogc3ViZGVmID0gdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihmaWVsZCk7CisgIHJldHVybiB1cGJfbXNnZGVmX21hcGVudHJ5KHN1YmRlZik7Cit9CisKK2NvbnN0IHVwYl9maWVsZGRlZiogbWFwX2ZpZWxkX2tleShjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkKSB7CisgIGFzc2VydChpc19tYXBfZmllbGQoZmllbGQpKTsKKyAgY29uc3QgdXBiX21zZ2RlZiogc3ViZGVmID0gdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihmaWVsZCk7CisgIHJldHVybiBtYXBfZW50cnlfa2V5KHN1YmRlZik7Cit9CisKK2NvbnN0IHVwYl9maWVsZGRlZiogbWFwX2ZpZWxkX3ZhbHVlKGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpIHsKKyAgYXNzZXJ0KGlzX21hcF9maWVsZChmaWVsZCkpOworICBjb25zdCB1cGJfbXNnZGVmKiBzdWJkZWYgPSB1cGJfZmllbGRkZWZfbXNnc3ViZGVmKGZpZWxkKTsKKyAgcmV0dXJuIG1hcF9lbnRyeV92YWx1ZShzdWJkZWYpOworfQorCitjb25zdCB1cGJfZmllbGRkZWYqIG1hcF9lbnRyeV9rZXkoY29uc3QgdXBiX21zZ2RlZiogbXNnZGVmKSB7CisgIGNvbnN0IHVwYl9maWVsZGRlZioga2V5X2ZpZWxkID0gdXBiX21zZ2RlZl9pdG9mKG1zZ2RlZiwgTUFQX0tFWV9GSUVMRCk7CisgIGFzc2VydChrZXlfZmllbGQgIT0gTlVMTCk7CisgIHJldHVybiBrZXlfZmllbGQ7Cit9CisKK2NvbnN0IHVwYl9maWVsZGRlZiogbWFwX2VudHJ5X3ZhbHVlKGNvbnN0IHVwYl9tc2dkZWYqIG1zZ2RlZikgeworICBjb25zdCB1cGJfZmllbGRkZWYqIHZhbHVlX2ZpZWxkID0gdXBiX21zZ2RlZl9pdG9mKG1zZ2RlZiwgTUFQX1ZBTFVFX0ZJRUxEKTsKKyAgYXNzZXJ0KHZhbHVlX2ZpZWxkICE9IE5VTEwpOworICByZXR1cm4gdmFsdWVfZmllbGQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNZW1vcnkgbGF5b3V0IG1hbmFnZW1lbnQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgc2l6ZV90IGFsaWduX3VwX3RvKHNpemVfdCBvZmZzZXQsIHNpemVfdCBncmFudWxhcml0eSkgeworICAvLyBHcmFudWxhcml0eSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvLgorICByZXR1cm4gKG9mZnNldCArIGdyYW51bGFyaXR5IC0gMSkgJiB+KGdyYW51bGFyaXR5IC0gMSk7Cit9CisKK01lc3NhZ2VMYXlvdXQqIGNyZWF0ZV9sYXlvdXQoY29uc3QgdXBiX21zZ2RlZiogbXNnZGVmKSB7CisgIE1lc3NhZ2VMYXlvdXQqIGxheW91dCA9IEFMTE9DKE1lc3NhZ2VMYXlvdXQpOworICBpbnQgbmZpZWxkcyA9IHVwYl9tc2dkZWZfbnVtZmllbGRzKG1zZ2RlZik7CisgIGxheW91dC0+ZmllbGRzID0gQUxMT0NfTihNZXNzYWdlRmllbGQsIG5maWVsZHMpOworCisgIHVwYl9tc2dfZmllbGRfaXRlciBpdDsKKyAgc2l6ZV90IG9mZiA9IDA7CisgIGZvciAodXBiX21zZ19maWVsZF9iZWdpbigmaXQsIG1zZ2RlZik7CisgICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaXQpOworICAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaXQpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaXQpOworCisgICAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZmllbGQpKSB7CisgICAgICAvLyBPbmVvZnMgYXJlIGhhbmRsZWQgc2VwYXJhdGVseSBiZWxvdy4KKyAgICAgIGNvbnRpbnVlOworICAgIH0KKworICAgIC8vIEFsbG9jYXRlIHxmaWVsZF9zaXplfCBieXRlcyBmb3IgdGhpcyBmaWVsZCBpbiB0aGUgbGF5b3V0LgorICAgIHNpemVfdCBmaWVsZF9zaXplID0gMDsKKyAgICBpZiAodXBiX2ZpZWxkZGVmX2xhYmVsKGZpZWxkKSA9PSBVUEJfTEFCRUxfUkVQRUFURUQpIHsKKyAgICAgIGZpZWxkX3NpemUgPSBzaXplb2YoVkFMVUUpOworICAgIH0gZWxzZSB7CisgICAgICBmaWVsZF9zaXplID0gbmF0aXZlX3Nsb3Rfc2l6ZSh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCkpOworICAgIH0KKyAgICAvLyBBbGlnbiBjdXJyZW50IG9mZnNldCB1cCB0byB8c2l6ZXwgZ3JhbnVsYXJpdHkuCisgICAgb2ZmID0gYWxpZ25fdXBfdG8ob2ZmLCBmaWVsZF9zaXplKTsKKyAgICBsYXlvdXQtPmZpZWxkc1t1cGJfZmllbGRkZWZfaW5kZXgoZmllbGQpXS5vZmZzZXQgPSBvZmY7CisgICAgbGF5b3V0LT5maWVsZHNbdXBiX2ZpZWxkZGVmX2luZGV4KGZpZWxkKV0uY2FzZV9vZmZzZXQgPSBNRVNTQUdFX0ZJRUxEX05PX0NBU0U7CisgICAgb2ZmICs9IGZpZWxkX3NpemU7CisgIH0KKworICAvLyBIYW5kbGUgb25lb2ZzIG5vdyAtLSB3ZSBpdGVyYXRlIG92ZXIgb25lb2ZzIHNwZWNpZmljYWxseSBhbmQgYWxsb2NhdGUgb25seQorICAvLyBvbmUgc2xvdCBwZXIgb25lb2YuCisgIC8vCisgIC8vIFdlIGFzc2lnbiBhbGwgdmFsdWUgc2xvdHMgZmlyc3QsIHRoZW4gcGFjayB0aGUgJ2Nhc2UnIGZpZWxkcyBhdCB0aGUgZW5kLAorICAvLyBzaW5jZSBpbiB0aGUgY29tbW9uIGNhc2UgKG1vZGVybiA2NC1iaXQgcGxhdGZvcm0pIHRoZXNlIGFyZSA4IGJ5dGVzIGFuZCA0CisgIC8vIGJ5dGVzIHJlc3BlY3RpdmVseSBhbmQgd2Ugd2FudCB0byBhdm9pZCBhbGlnbm1lbnQgb3ZlcmhlYWQuCisgIC8vCisgIC8vIE5vdGUgdGhhdCB3ZSByZXNlcnZlIDQgYnl0ZXMgKGEgdWludDMyKSBwZXIgJ2Nhc2UnIHNsb3QgYmVjYXVzZSB0aGUgdmFsdWUKKyAgLy8gc3BhY2UgZm9yIG9uZW9mIGNhc2VzIGlzIGNvbmNlcHR1YWxseSBhcyB3aWRlIGFzIGZpZWxkIHRhZyBudW1iZXJzLiBJbgorICAvLyBwcmFjdGljZSwgaXQncyB1bmxpa2VseSB0aGF0IGEgb25lb2Ygd291bGQgaGF2ZSBtb3JlIHRoYW4gZS5nLiAyNTYgb3IgNjRLCisgIC8vIG1lbWJlcnMgKDggb3IgMTYgYml0cyByZXNwZWN0aXZlbHkpLCBzbyBjb25jZWl2YWJseSB3ZSBjb3VsZCBhc3NpZ24KKyAgLy8gY29uc2VjdXRpdmUgY2FzZSBudW1iZXJzIGFuZCB0aGVuIHBpY2sgYSBzbWFsbGVyIG9uZW9mIGNhc2Ugc2xvdCBzaXplLCBidXQKKyAgLy8gdGhlIGNvbXBsZXhpdHkgdG8gaW1wbGVtZW50IHRoaXMgaW5kaXJlY3Rpb24gaXMgcHJvYmFibHkgbm90IHdvcnRod2hpbGUuCisgIHVwYl9tc2dfb25lb2ZfaXRlciBvaXQ7CisgIGZvciAodXBiX21zZ19vbmVvZl9iZWdpbigmb2l0LCBtc2dkZWYpOworICAgICAgICF1cGJfbXNnX29uZW9mX2RvbmUoJm9pdCk7CisgICAgICAgdXBiX21zZ19vbmVvZl9uZXh0KCZvaXQpKSB7CisgICAgY29uc3QgdXBiX29uZW9mZGVmKiBvbmVvZiA9IHVwYl9tc2dfaXRlcl9vbmVvZigmb2l0KTsKKworICAgIC8vIEFsd2F5cyBhbGxvY2F0ZSBOQVRJVkVfU0xPVF9NQVhfU0laRSBieXRlcywgYnV0IHNoYXJlIHRoZSBzbG90IGJldHdlZW4KKyAgICAvLyBhbGwgZmllbGRzLgorICAgIHNpemVfdCBmaWVsZF9zaXplID0gTkFUSVZFX1NMT1RfTUFYX1NJWkU7CisgICAgLy8gQWxpZ24gdGhlIG9mZnNldC4KKyAgICBvZmYgPSBhbGlnbl91cF90byhvZmYsIGZpZWxkX3NpemUpOworICAgIC8vIEFzc2lnbiBhbGwgZmllbGRzIGluIHRoZSBvbmVvZiB0aGlzIHNhbWUgb2Zmc2V0LgorICAgIHVwYl9vbmVvZl9pdGVyIGZpdDsKKyAgICBmb3IgKHVwYl9vbmVvZl9iZWdpbigmZml0LCBvbmVvZik7CisgICAgICAgICAhdXBiX29uZW9mX2RvbmUoJmZpdCk7CisgICAgICAgICB1cGJfb25lb2ZfbmV4dCgmZml0KSkgeworICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9IHVwYl9vbmVvZl9pdGVyX2ZpZWxkKCZmaXQpOworICAgICAgbGF5b3V0LT5maWVsZHNbdXBiX2ZpZWxkZGVmX2luZGV4KGZpZWxkKV0ub2Zmc2V0ID0gb2ZmOworICAgIH0KKyAgICBvZmYgKz0gZmllbGRfc2l6ZTsKKyAgfQorCisgIC8vIE5vdyB0aGUgY2FzZSBmaWVsZHMuCisgIGZvciAodXBiX21zZ19vbmVvZl9iZWdpbigmb2l0LCBtc2dkZWYpOworICAgICAgICF1cGJfbXNnX29uZW9mX2RvbmUoJm9pdCk7CisgICAgICAgdXBiX21zZ19vbmVvZl9uZXh0KCZvaXQpKSB7CisgICAgY29uc3QgdXBiX29uZW9mZGVmKiBvbmVvZiA9IHVwYl9tc2dfaXRlcl9vbmVvZigmb2l0KTsKKworICAgIHNpemVfdCBmaWVsZF9zaXplID0gc2l6ZW9mKHVpbnQzMl90KTsKKyAgICAvLyBBbGlnbiB0aGUgb2Zmc2V0LgorICAgIG9mZiA9IChvZmYgKyBmaWVsZF9zaXplIC0gMSkgJiB+KGZpZWxkX3NpemUgLSAxKTsKKyAgICAvLyBBc3NpZ24gYWxsIGZpZWxkcyBpbiB0aGUgb25lb2YgdGhpcyBzYW1lIG9mZnNldC4KKyAgICB1cGJfb25lb2ZfaXRlciBmaXQ7CisgICAgZm9yICh1cGJfb25lb2ZfYmVnaW4oJmZpdCwgb25lb2YpOworICAgICAgICAgIXVwYl9vbmVvZl9kb25lKCZmaXQpOworICAgICAgICAgdXBiX29uZW9mX25leHQoJmZpdCkpIHsKKyAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQgPSB1cGJfb25lb2ZfaXRlcl9maWVsZCgmZml0KTsKKyAgICAgIGxheW91dC0+ZmllbGRzW3VwYl9maWVsZGRlZl9pbmRleChmaWVsZCldLmNhc2Vfb2Zmc2V0ID0gb2ZmOworICAgIH0KKyAgICBvZmYgKz0gZmllbGRfc2l6ZTsKKyAgfQorCisgIGxheW91dC0+c2l6ZSA9IG9mZjsKKworICBsYXlvdXQtPm1zZ2RlZiA9IG1zZ2RlZjsKKyAgdXBiX21zZ2RlZl9yZWYobGF5b3V0LT5tc2dkZWYsICZsYXlvdXQtPm1zZ2RlZik7CisKKyAgcmV0dXJuIGxheW91dDsKK30KKwordm9pZCBmcmVlX2xheW91dChNZXNzYWdlTGF5b3V0KiBsYXlvdXQpIHsKKyAgeGZyZWUobGF5b3V0LT5maWVsZHMpOworICB1cGJfbXNnZGVmX3VucmVmKGxheW91dC0+bXNnZGVmLCAmbGF5b3V0LT5tc2dkZWYpOworICB4ZnJlZShsYXlvdXQpOworfQorCitWQUxVRSBmaWVsZF90eXBlX2NsYXNzKGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpIHsKKyAgVkFMVUUgdHlwZV9jbGFzcyA9IFFuaWw7CisgIGlmICh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCkgPT0gVVBCX1RZUEVfTUVTU0FHRSkgeworICAgIFZBTFVFIHN1Ym1zZ2Rlc2MgPQorICAgICAgICBnZXRfZGVmX29iaih1cGJfZmllbGRkZWZfc3ViZGVmKGZpZWxkKSk7CisgICAgdHlwZV9jbGFzcyA9IERlc2NyaXB0b3JfbXNnY2xhc3Moc3VibXNnZGVzYyk7CisgIH0gZWxzZSBpZiAodXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICBWQUxVRSBzdWJlbnVtZGVzYyA9CisgICAgICAgIGdldF9kZWZfb2JqKHVwYl9maWVsZGRlZl9zdWJkZWYoZmllbGQpKTsKKyAgICB0eXBlX2NsYXNzID0gRW51bURlc2NyaXB0b3JfZW51bW1vZHVsZShzdWJlbnVtZGVzYyk7CisgIH0KKyAgcmV0dXJuIHR5cGVfY2xhc3M7Cit9CisKK3N0YXRpYyB2b2lkKiBzbG90X21lbW9yeShNZXNzYWdlTGF5b3V0KiBsYXlvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogc3RvcmFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkKSB7CisgIHJldHVybiAoKHVpbnQ4X3QgKilzdG9yYWdlKSArCisgICAgICBsYXlvdXQtPmZpZWxkc1t1cGJfZmllbGRkZWZfaW5kZXgoZmllbGQpXS5vZmZzZXQ7Cit9CisKK3N0YXRpYyB1aW50MzJfdCogc2xvdF9vbmVvZl9jYXNlKE1lc3NhZ2VMYXlvdXQqIGxheW91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIHN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkKSB7CisgIHJldHVybiAodWludDMyX3QgKikoKCh1aW50OF90ICopc3RvcmFnZSkgKworICAgICAgbGF5b3V0LT5maWVsZHNbdXBiX2ZpZWxkZGVmX2luZGV4KGZpZWxkKV0uY2FzZV9vZmZzZXQpOworfQorCisKK1ZBTFVFIGxheW91dF9nZXQoTWVzc2FnZUxheW91dCogbGF5b3V0LAorICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBzdG9yYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkKSB7CisgIHZvaWQqIG1lbW9yeSA9IHNsb3RfbWVtb3J5KGxheW91dCwgc3RvcmFnZSwgZmllbGQpOworICB1aW50MzJfdCogb25lb2ZfY2FzZSA9IHNsb3Rfb25lb2ZfY2FzZShsYXlvdXQsIHN0b3JhZ2UsIGZpZWxkKTsKKworICBpZiAodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmdvbmVvZihmaWVsZCkpIHsKKyAgICBpZiAoKm9uZW9mX2Nhc2UgIT0gdXBiX2ZpZWxkZGVmX251bWJlcihmaWVsZCkpIHsKKyAgICAgIHJldHVybiBRbmlsOworICAgIH0KKyAgICByZXR1cm4gbmF0aXZlX3Nsb3RfZ2V0KHVwYl9maWVsZGRlZl90eXBlKGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX3R5cGVfY2xhc3MoZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtb3J5KTsKKyAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfbGFiZWwoZmllbGQpID09IFVQQl9MQUJFTF9SRVBFQVRFRCkgeworICAgIHJldHVybiAqKChWQUxVRSAqKW1lbW9yeSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIG5hdGl2ZV9zbG90X2dldCh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF90eXBlX2NsYXNzKGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbW9yeSk7CisgIH0KK30KKworc3RhdGljIHZvaWQgY2hlY2tfcmVwZWF0ZWRfZmllbGRfdHlwZShWQUxVRSB2YWwsIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpIHsKKyAgYXNzZXJ0KHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUEVBVEVEKTsKKworICBpZiAoIVJCX1RZUEVfUCh2YWwsIFRfREFUQSkgfHwgIVJUWVBFRERBVEFfUCh2YWwpIHx8CisgICAgICBSVFlQRUREQVRBX1RZUEUodmFsKSAhPSAmUmVwZWF0ZWRGaWVsZF90eXBlKSB7CisgICAgcmJfcmFpc2UocmJfZVR5cGVFcnJvciwgIkV4cGVjdGVkIHJlcGVhdGVkIGZpZWxkIGFycmF5Iik7CisgIH0KKworICBSZXBlYXRlZEZpZWxkKiBzZWxmID0gcnVieV90b19SZXBlYXRlZEZpZWxkKHZhbCk7CisgIGlmIChzZWxmLT5maWVsZF90eXBlICE9IHVwYl9maWVsZGRlZl90eXBlKGZpZWxkKSkgeworICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsICJSZXBlYXRlZCBmaWVsZCBhcnJheSBoYXMgd3JvbmcgZWxlbWVudCB0eXBlIik7CisgIH0KKworICBpZiAoc2VsZi0+ZmllbGRfdHlwZSA9PSBVUEJfVFlQRV9NRVNTQUdFIHx8CisgICAgICBzZWxmLT5maWVsZF90eXBlID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICBpZiAoc2VsZi0+ZmllbGRfdHlwZV9jbGFzcyAhPQorICAgICAgICBnZXRfZGVmX29iaih1cGJfZmllbGRkZWZfc3ViZGVmKGZpZWxkKSkpIHsKKyAgICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsCisgICAgICAgICAgICAgICAiUmVwZWF0ZWQgZmllbGQgYXJyYXkgaGFzIHdyb25nIG1lc3NhZ2UvZW51bSBjbGFzcyIpOworICAgIH0KKyAgfQorfQorCitzdGF0aWMgdm9pZCBjaGVja19tYXBfZmllbGRfdHlwZShWQUxVRSB2YWwsIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQpIHsKKyAgYXNzZXJ0KGlzX21hcF9maWVsZChmaWVsZCkpOworICBjb25zdCB1cGJfZmllbGRkZWYqIGtleV9maWVsZCA9IG1hcF9maWVsZF9rZXkoZmllbGQpOworICBjb25zdCB1cGJfZmllbGRkZWYqIHZhbHVlX2ZpZWxkID0gbWFwX2ZpZWxkX3ZhbHVlKGZpZWxkKTsKKworICBpZiAoIVJCX1RZUEVfUCh2YWwsIFRfREFUQSkgfHwgIVJUWVBFRERBVEFfUCh2YWwpIHx8CisgICAgICBSVFlQRUREQVRBX1RZUEUodmFsKSAhPSAmTWFwX3R5cGUpIHsKKyAgICByYl9yYWlzZShyYl9lVHlwZUVycm9yLCAiRXhwZWN0ZWQgTWFwIGluc3RhbmNlIik7CisgIH0KKworICBNYXAqIHNlbGYgPSBydWJ5X3RvX01hcCh2YWwpOworICBpZiAoc2VsZi0+a2V5X3R5cGUgIT0gdXBiX2ZpZWxkZGVmX3R5cGUoa2V5X2ZpZWxkKSkgeworICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsICJNYXAga2V5IHR5cGUgZG9lcyBub3QgbWF0Y2ggZmllbGQncyBrZXkgdHlwZSIpOworICB9CisgIGlmIChzZWxmLT52YWx1ZV90eXBlICE9IHVwYl9maWVsZGRlZl90eXBlKHZhbHVlX2ZpZWxkKSkgeworICAgIHJiX3JhaXNlKHJiX2VUeXBlRXJyb3IsICJNYXAgdmFsdWUgdHlwZSBkb2VzIG5vdCBtYXRjaCBmaWVsZCdzIHZhbHVlIHR5cGUiKTsKKyAgfQorICBpZiAodXBiX2ZpZWxkZGVmX3R5cGUodmFsdWVfZmllbGQpID09IFVQQl9UWVBFX01FU1NBR0UgfHwKKyAgICAgIHVwYl9maWVsZGRlZl90eXBlKHZhbHVlX2ZpZWxkKSA9PSBVUEJfVFlQRV9FTlVNKSB7CisgICAgaWYgKHNlbGYtPnZhbHVlX3R5cGVfY2xhc3MgIT0KKyAgICAgICAgZ2V0X2RlZl9vYmoodXBiX2ZpZWxkZGVmX3N1YmRlZih2YWx1ZV9maWVsZCkpKSB7CisgICAgICByYl9yYWlzZShyYl9lVHlwZUVycm9yLAorICAgICAgICAgICAgICAgIk1hcCB2YWx1ZSB0eXBlIGhhcyB3cm9uZyBtZXNzYWdlL2VudW0gY2xhc3MiKTsKKyAgICB9CisgIH0KK30KKworCit2b2lkIGxheW91dF9zZXQoTWVzc2FnZUxheW91dCogbGF5b3V0LAorICAgICAgICAgICAgICAgIHZvaWQqIHN0b3JhZ2UsCisgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCwKKyAgICAgICAgICAgICAgICBWQUxVRSB2YWwpIHsKKyAgdm9pZCogbWVtb3J5ID0gc2xvdF9tZW1vcnkobGF5b3V0LCBzdG9yYWdlLCBmaWVsZCk7CisgIHVpbnQzMl90KiBvbmVvZl9jYXNlID0gc2xvdF9vbmVvZl9jYXNlKGxheW91dCwgc3RvcmFnZSwgZmllbGQpOworCisgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGZpZWxkKSkgeworICAgIGlmICh2YWwgPT0gUW5pbCkgeworICAgICAgLy8gQXNzaWduaW5nIG5pbCB0byBhIG9uZW9mIGZpZWxkIGNsZWFycyB0aGUgb25lb2YgY29tcGxldGVseS4KKyAgICAgICpvbmVvZl9jYXNlID0gT05FT0ZfQ0FTRV9OT05FOworICAgICAgbWVtc2V0KG1lbW9yeSwgMCwgTkFUSVZFX1NMT1RfTUFYX1NJWkUpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBUaGUgdHJhbnNpdGlvbiBiZXR3ZWVuIGZpZWxkIHR5cGVzIGZvciBhIHNpbmdsZSBvbmVvZiAodW5pb24pIHNsb3QgaXMKKyAgICAgIC8vIHNvbWV3aGF0IGNvbXBsZXggYmVjYXVzZSB3ZSBuZWVkIHRvIGVuc3VyZSB0aGF0IGEgR0MgdHJpZ2dlcmVkIGF0IGFueQorICAgICAgLy8gcG9pbnQgYnkgYSBjYWxsIGludG8gdGhlIFJ1YnkgVk0gc2VlcyBhIHZhbGlkIHN0YXRlIGZvciB0aGlzIGZpZWxkIGFuZAorICAgICAgLy8gZG9lcyBub3QgZWl0aGVyIGdvIG9mZiBpbnRvIHRoZSB3ZWVkcyAoZm9sbG93aW5nIHdoYXQgaXQgdGhpbmtzIGlzIGEKKyAgICAgIC8vIFZBTFVFIGJ1dCBpcyBhY3R1YWxseSBhIGRpZmZlcmVudCBmaWVsZCB0eXBlKSBvciBtaXNzIGFuIG9iamVjdCAoc2VlaW5nCisgICAgICAvLyB3aGF0IGl0IHRoaW5rcyBpcyBhIHByaW1pdGl2ZSBmaWVsZCBidXQgaXMgYWN0dWFsbHkgYSBWQUxVRSBmb3IgdGhlIG5ldworICAgICAgLy8gZmllbGQgdHlwZSkuCisgICAgICAvLworICAgICAgLy8gSW4gb3JkZXIgZm9yIHRoZSB0cmFuc2l0aW9uIHRvIGJlIHNhZmUsIHRoZSBvbmVvZiBjYXNlIHNsb3QgbXVzdCBiZSBpbgorICAgICAgLy8gc3luYyB3aXRoIHRoZSB2YWx1ZSBzbG90IHdoZW5ldmVyIHRoZSBSdWJ5IFZNIGhhcyBiZWVuIGNhbGxlZC4gVGh1cywgd2UKKyAgICAgIC8vIHVzZSBuYXRpdmVfc2xvdF9zZXRfdmFsdWVfYW5kX2Nhc2UoKSwgd2hpY2ggZW5zdXJlcyB0aGF0IGJvdGggdGhlIHZhbHVlCisgICAgICAvLyBhbmQgY2FzZSBudW1iZXIgYXJlIGFsdGVyZWQgYXRvbWljYWxseSAody5yLnQuIHRoZSBSdWJ5IFZNKS4KKyAgICAgIG5hdGl2ZV9zbG90X3NldF92YWx1ZV9hbmRfY2FzZSgKKyAgICAgICAgICB1cGJfZmllbGRkZWZfdHlwZShmaWVsZCksIGZpZWxkX3R5cGVfY2xhc3MoZmllbGQpLAorICAgICAgICAgIG1lbW9yeSwgdmFsLAorICAgICAgICAgIG9uZW9mX2Nhc2UsIHVwYl9maWVsZGRlZl9udW1iZXIoZmllbGQpKTsKKyAgICB9CisgIH0gZWxzZSBpZiAoaXNfbWFwX2ZpZWxkKGZpZWxkKSkgeworICAgIGNoZWNrX21hcF9maWVsZF90eXBlKHZhbCwgZmllbGQpOworICAgIERFUkVGKG1lbW9yeSwgVkFMVUUpID0gdmFsOworICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUEVBVEVEKSB7CisgICAgY2hlY2tfcmVwZWF0ZWRfZmllbGRfdHlwZSh2YWwsIGZpZWxkKTsKKyAgICBERVJFRihtZW1vcnksIFZBTFVFKSA9IHZhbDsKKyAgfSBlbHNlIHsKKyAgICBuYXRpdmVfc2xvdF9zZXQodXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpLCBmaWVsZF90eXBlX2NsYXNzKGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgbWVtb3J5LCB2YWwpOworICB9Cit9CisKK3ZvaWQgbGF5b3V0X2luaXQoTWVzc2FnZUxheW91dCogbGF5b3V0LAorICAgICAgICAgICAgICAgICB2b2lkKiBzdG9yYWdlKSB7CisgIHVwYl9tc2dfZmllbGRfaXRlciBpdDsKKyAgZm9yICh1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpdCwgbGF5b3V0LT5tc2dkZWYpOworICAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJml0KTsKKyAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJml0KSkgeworICAgIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJml0KTsKKyAgICB2b2lkKiBtZW1vcnkgPSBzbG90X21lbW9yeShsYXlvdXQsIHN0b3JhZ2UsIGZpZWxkKTsKKyAgICB1aW50MzJfdCogb25lb2ZfY2FzZSA9IHNsb3Rfb25lb2ZfY2FzZShsYXlvdXQsIHN0b3JhZ2UsIGZpZWxkKTsKKworICAgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGZpZWxkKSkgeworICAgICAgbWVtc2V0KG1lbW9yeSwgMCwgTkFUSVZFX1NMT1RfTUFYX1NJWkUpOworICAgICAgKm9uZW9mX2Nhc2UgPSBPTkVPRl9DQVNFX05PTkU7CisgICAgfSBlbHNlIGlmIChpc19tYXBfZmllbGQoZmllbGQpKSB7CisgICAgICBWQUxVRSBtYXAgPSBRbmlsOworCisgICAgICBjb25zdCB1cGJfZmllbGRkZWYqIGtleV9maWVsZCA9IG1hcF9maWVsZF9rZXkoZmllbGQpOworICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiB2YWx1ZV9maWVsZCA9IG1hcF9maWVsZF92YWx1ZShmaWVsZCk7CisgICAgICBWQUxVRSB0eXBlX2NsYXNzID0gZmllbGRfdHlwZV9jbGFzcyh2YWx1ZV9maWVsZCk7CisKKyAgICAgIGlmICh0eXBlX2NsYXNzICE9IFFuaWwpIHsKKyAgICAgICAgVkFMVUUgYXJnc1szXSA9IHsKKyAgICAgICAgICBmaWVsZHR5cGVfdG9fcnVieSh1cGJfZmllbGRkZWZfdHlwZShrZXlfZmllbGQpKSwKKyAgICAgICAgICBmaWVsZHR5cGVfdG9fcnVieSh1cGJfZmllbGRkZWZfdHlwZSh2YWx1ZV9maWVsZCkpLAorICAgICAgICAgIHR5cGVfY2xhc3MsCisgICAgICAgIH07CisgICAgICAgIG1hcCA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgzLCBhcmdzLCBjTWFwKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIFZBTFVFIGFyZ3NbMl0gPSB7CisgICAgICAgICAgZmllbGR0eXBlX3RvX3J1YnkodXBiX2ZpZWxkZGVmX3R5cGUoa2V5X2ZpZWxkKSksCisgICAgICAgICAgZmllbGR0eXBlX3RvX3J1YnkodXBiX2ZpZWxkZGVmX3R5cGUodmFsdWVfZmllbGQpKSwKKyAgICAgICAgfTsKKyAgICAgICAgbWFwID0gcmJfY2xhc3NfbmV3X2luc3RhbmNlKDIsIGFyZ3MsIGNNYXApOworICAgICAgfQorCisgICAgICBERVJFRihtZW1vcnksIFZBTFVFKSA9IG1hcDsKKyAgICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUEVBVEVEKSB7CisgICAgICBWQUxVRSBhcnkgPSBRbmlsOworCisgICAgICBWQUxVRSB0eXBlX2NsYXNzID0gZmllbGRfdHlwZV9jbGFzcyhmaWVsZCk7CisKKyAgICAgIGlmICh0eXBlX2NsYXNzICE9IFFuaWwpIHsKKyAgICAgICAgVkFMVUUgYXJnc1syXSA9IHsKKyAgICAgICAgICBmaWVsZHR5cGVfdG9fcnVieSh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCkpLAorICAgICAgICAgIHR5cGVfY2xhc3MsCisgICAgICAgIH07CisgICAgICAgIGFyeSA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgyLCBhcmdzLCBjUmVwZWF0ZWRGaWVsZCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBWQUxVRSBhcmdzWzFdID0geyBmaWVsZHR5cGVfdG9fcnVieSh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCkpIH07CisgICAgICAgIGFyeSA9IHJiX2NsYXNzX25ld19pbnN0YW5jZSgxLCBhcmdzLCBjUmVwZWF0ZWRGaWVsZCk7CisgICAgICB9CisKKyAgICAgIERFUkVGKG1lbW9yeSwgVkFMVUUpID0gYXJ5OworICAgIH0gZWxzZSB7CisgICAgICBuYXRpdmVfc2xvdF9pbml0KHVwYl9maWVsZGRlZl90eXBlKGZpZWxkKSwgbWVtb3J5KTsKKyAgICB9CisgIH0KK30KKwordm9pZCBsYXlvdXRfbWFyayhNZXNzYWdlTGF5b3V0KiBsYXlvdXQsIHZvaWQqIHN0b3JhZ2UpIHsKKyAgdXBiX21zZ19maWVsZF9pdGVyIGl0OworICBmb3IgKHVwYl9tc2dfZmllbGRfYmVnaW4oJml0LCBsYXlvdXQtPm1zZ2RlZik7CisgICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaXQpOworICAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaXQpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaXQpOworICAgIHZvaWQqIG1lbW9yeSA9IHNsb3RfbWVtb3J5KGxheW91dCwgc3RvcmFnZSwgZmllbGQpOworICAgIHVpbnQzMl90KiBvbmVvZl9jYXNlID0gc2xvdF9vbmVvZl9jYXNlKGxheW91dCwgc3RvcmFnZSwgZmllbGQpOworCisgICAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZmllbGQpKSB7CisgICAgICBpZiAoKm9uZW9mX2Nhc2UgPT0gdXBiX2ZpZWxkZGVmX251bWJlcihmaWVsZCkpIHsKKyAgICAgICAgbmF0aXZlX3Nsb3RfbWFyayh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCksIG1lbW9yeSk7CisgICAgICB9CisgICAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfbGFiZWwoZmllbGQpID09IFVQQl9MQUJFTF9SRVBFQVRFRCkgeworICAgICAgcmJfZ2NfbWFyayhERVJFRihtZW1vcnksIFZBTFVFKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIG5hdGl2ZV9zbG90X21hcmsodXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpLCBtZW1vcnkpOworICAgIH0KKyAgfQorfQorCit2b2lkIGxheW91dF9kdXAoTWVzc2FnZUxheW91dCogbGF5b3V0LCB2b2lkKiB0bywgdm9pZCogZnJvbSkgeworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaXQ7CisgIGZvciAodXBiX21zZ19maWVsZF9iZWdpbigmaXQsIGxheW91dC0+bXNnZGVmKTsKKyAgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpdCk7CisgICAgICAgdXBiX21zZ19maWVsZF9uZXh0KCZpdCkpIHsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpdCk7CisKKyAgICB2b2lkKiB0b19tZW1vcnkgPSBzbG90X21lbW9yeShsYXlvdXQsIHRvLCBmaWVsZCk7CisgICAgdWludDMyX3QqIHRvX29uZW9mX2Nhc2UgPSBzbG90X29uZW9mX2Nhc2UobGF5b3V0LCB0bywgZmllbGQpOworICAgIHZvaWQqIGZyb21fbWVtb3J5ID0gc2xvdF9tZW1vcnkobGF5b3V0LCBmcm9tLCBmaWVsZCk7CisgICAgdWludDMyX3QqIGZyb21fb25lb2ZfY2FzZSA9IHNsb3Rfb25lb2ZfY2FzZShsYXlvdXQsIGZyb20sIGZpZWxkKTsKKworICAgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGZpZWxkKSkgeworICAgICAgaWYgKCpmcm9tX29uZW9mX2Nhc2UgPT0gdXBiX2ZpZWxkZGVmX251bWJlcihmaWVsZCkpIHsKKyAgICAgICAgKnRvX29uZW9mX2Nhc2UgPSAqZnJvbV9vbmVvZl9jYXNlOworICAgICAgICBuYXRpdmVfc2xvdF9kdXAodXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpLCB0b19tZW1vcnksIGZyb21fbWVtb3J5KTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGlzX21hcF9maWVsZChmaWVsZCkpIHsKKyAgICAgIERFUkVGKHRvX21lbW9yeSwgVkFMVUUpID0gTWFwX2R1cChERVJFRihmcm9tX21lbW9yeSwgVkFMVUUpKTsKKyAgICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUEVBVEVEKSB7CisgICAgICBERVJFRih0b19tZW1vcnksIFZBTFVFKSA9IFJlcGVhdGVkRmllbGRfZHVwKERFUkVGKGZyb21fbWVtb3J5LCBWQUxVRSkpOworICAgIH0gZWxzZSB7CisgICAgICBuYXRpdmVfc2xvdF9kdXAodXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpLCB0b19tZW1vcnksIGZyb21fbWVtb3J5KTsKKyAgICB9CisgIH0KK30KKwordm9pZCBsYXlvdXRfZGVlcF9jb3B5KE1lc3NhZ2VMYXlvdXQqIGxheW91dCwgdm9pZCogdG8sIHZvaWQqIGZyb20pIHsKKyAgdXBiX21zZ19maWVsZF9pdGVyIGl0OworICBmb3IgKHVwYl9tc2dfZmllbGRfYmVnaW4oJml0LCBsYXlvdXQtPm1zZ2RlZik7CisgICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaXQpOworICAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaXQpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmKiBmaWVsZCA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaXQpOworCisgICAgdm9pZCogdG9fbWVtb3J5ID0gc2xvdF9tZW1vcnkobGF5b3V0LCB0bywgZmllbGQpOworICAgIHVpbnQzMl90KiB0b19vbmVvZl9jYXNlID0gc2xvdF9vbmVvZl9jYXNlKGxheW91dCwgdG8sIGZpZWxkKTsKKyAgICB2b2lkKiBmcm9tX21lbW9yeSA9IHNsb3RfbWVtb3J5KGxheW91dCwgZnJvbSwgZmllbGQpOworICAgIHVpbnQzMl90KiBmcm9tX29uZW9mX2Nhc2UgPSBzbG90X29uZW9mX2Nhc2UobGF5b3V0LCBmcm9tLCBmaWVsZCk7CisKKyAgICBpZiAodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmdvbmVvZihmaWVsZCkpIHsKKyAgICAgIGlmICgqZnJvbV9vbmVvZl9jYXNlID09IHVwYl9maWVsZGRlZl9udW1iZXIoZmllbGQpKSB7CisgICAgICAgICp0b19vbmVvZl9jYXNlID0gKmZyb21fb25lb2ZfY2FzZTsKKyAgICAgICAgbmF0aXZlX3Nsb3RfZGVlcF9jb3B5KHVwYl9maWVsZGRlZl90eXBlKGZpZWxkKSwgdG9fbWVtb3J5LCBmcm9tX21lbW9yeSk7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChpc19tYXBfZmllbGQoZmllbGQpKSB7CisgICAgICBERVJFRih0b19tZW1vcnksIFZBTFVFKSA9CisgICAgICAgICAgTWFwX2RlZXBfY29weShERVJFRihmcm9tX21lbW9yeSwgVkFMVUUpKTsKKyAgICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUEVBVEVEKSB7CisgICAgICBERVJFRih0b19tZW1vcnksIFZBTFVFKSA9CisgICAgICAgICAgUmVwZWF0ZWRGaWVsZF9kZWVwX2NvcHkoREVSRUYoZnJvbV9tZW1vcnksIFZBTFVFKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIG5hdGl2ZV9zbG90X2RlZXBfY29weSh1cGJfZmllbGRkZWZfdHlwZShmaWVsZCksIHRvX21lbW9yeSwgZnJvbV9tZW1vcnkpOworICAgIH0KKyAgfQorfQorCitWQUxVRSBsYXlvdXRfZXEoTWVzc2FnZUxheW91dCogbGF5b3V0LCB2b2lkKiBtc2cxLCB2b2lkKiBtc2cyKSB7CisgIHVwYl9tc2dfZmllbGRfaXRlciBpdDsKKyAgZm9yICh1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpdCwgbGF5b3V0LT5tc2dkZWYpOworICAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJml0KTsKKyAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJml0KSkgeworICAgIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJml0KTsKKworICAgIHZvaWQqIG1zZzFfbWVtb3J5ID0gc2xvdF9tZW1vcnkobGF5b3V0LCBtc2cxLCBmaWVsZCk7CisgICAgdWludDMyX3QqIG1zZzFfb25lb2ZfY2FzZSA9IHNsb3Rfb25lb2ZfY2FzZShsYXlvdXQsIG1zZzEsIGZpZWxkKTsKKyAgICB2b2lkKiBtc2cyX21lbW9yeSA9IHNsb3RfbWVtb3J5KGxheW91dCwgbXNnMiwgZmllbGQpOworICAgIHVpbnQzMl90KiBtc2cyX29uZW9mX2Nhc2UgPSBzbG90X29uZW9mX2Nhc2UobGF5b3V0LCBtc2cyLCBmaWVsZCk7CisKKyAgICBpZiAodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmdvbmVvZihmaWVsZCkpIHsKKyAgICAgIGlmICgqbXNnMV9vbmVvZl9jYXNlICE9ICptc2cyX29uZW9mX2Nhc2UgfHwKKyAgICAgICAgICAoKm1zZzFfb25lb2ZfY2FzZSA9PSB1cGJfZmllbGRkZWZfbnVtYmVyKGZpZWxkKSAmJgorICAgICAgICAgICAhbmF0aXZlX3Nsb3RfZXEodXBiX2ZpZWxkZGVmX3R5cGUoZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnMV9tZW1vcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cyX21lbW9yeSkpKSB7CisgICAgICAgIHJldHVybiBRZmFsc2U7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChpc19tYXBfZmllbGQoZmllbGQpKSB7CisgICAgICBpZiAoIU1hcF9lcShERVJFRihtc2cxX21lbW9yeSwgVkFMVUUpLAorICAgICAgICAgICAgICAgICAgREVSRUYobXNnMl9tZW1vcnksIFZBTFVFKSkpIHsKKyAgICAgICAgcmV0dXJuIFFmYWxzZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmaWVsZCkgPT0gVVBCX0xBQkVMX1JFUEVBVEVEKSB7CisgICAgICBpZiAoIVJlcGVhdGVkRmllbGRfZXEoREVSRUYobXNnMV9tZW1vcnksIFZBTFVFKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBERVJFRihtc2cyX21lbW9yeSwgVkFMVUUpKSkgeworICAgICAgICByZXR1cm4gUWZhbHNlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoIW5hdGl2ZV9zbG90X2VxKHVwYl9maWVsZGRlZl90eXBlKGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnMV9tZW1vcnksIG1zZzJfbWVtb3J5KSkgeworICAgICAgICByZXR1cm4gUWZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gUXRydWU7Cit9CisKK1ZBTFVFIGxheW91dF9oYXNoKE1lc3NhZ2VMYXlvdXQqIGxheW91dCwgdm9pZCogc3RvcmFnZSkgeworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaXQ7CisgIHN0X2luZGV4X3QgaCA9IHJiX2hhc2hfc3RhcnQoMCk7CisgIFZBTFVFIGhhc2hfc3ltID0gcmJfaW50ZXJuKCJoYXNoIik7CisgIGZvciAodXBiX21zZ19maWVsZF9iZWdpbigmaXQsIGxheW91dC0+bXNnZGVmKTsKKyAgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpdCk7CisgICAgICAgdXBiX21zZ19maWVsZF9uZXh0KCZpdCkpIHsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYqIGZpZWxkID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpdCk7CisgICAgVkFMVUUgZmllbGRfdmFsID0gbGF5b3V0X2dldChsYXlvdXQsIHN0b3JhZ2UsIGZpZWxkKTsKKyAgICBoID0gcmJfaGFzaF91aW50KGgsIE5VTTJMT05HKHJiX2Z1bmNhbGwoZmllbGRfdmFsLCBoYXNoX3N5bSwgMCkpKTsKKyAgfQorICBoID0gcmJfaGFzaF9lbmQoaCk7CisKKyAgcmV0dXJuIElOVDJGSVgoaCk7Cit9CisKK1ZBTFVFIGxheW91dF9pbnNwZWN0KE1lc3NhZ2VMYXlvdXQqIGxheW91dCwgdm9pZCogc3RvcmFnZSkgeworICBWQUxVRSBzdHIgPSByYl9zdHJfbmV3MigiIik7CisKKyAgdXBiX21zZ19maWVsZF9pdGVyIGl0OworICBib29sIGZpcnN0ID0gdHJ1ZTsKKyAgZm9yICh1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpdCwgbGF5b3V0LT5tc2dkZWYpOworICAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJml0KTsKKyAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJml0KSkgeworICAgIGNvbnN0IHVwYl9maWVsZGRlZiogZmllbGQgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJml0KTsKKyAgICBWQUxVRSBmaWVsZF92YWwgPSBsYXlvdXRfZ2V0KGxheW91dCwgc3RvcmFnZSwgZmllbGQpOworCisgICAgaWYgKCFmaXJzdCkgeworICAgICAgc3RyID0gcmJfc3RyX2NhdDIoc3RyLCAiLCAiKTsKKyAgICB9IGVsc2UgeworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICB9CisgICAgc3RyID0gcmJfc3RyX2NhdDIoc3RyLCB1cGJfZmllbGRkZWZfbmFtZShmaWVsZCkpOworICAgIHN0ciA9IHJiX3N0cl9jYXQyKHN0ciwgIjogIik7CisKKyAgICBzdHIgPSByYl9zdHJfYXBwZW5kKHN0ciwgcmJfZnVuY2FsbChmaWVsZF92YWwsIHJiX2ludGVybigiaW5zcGVjdCIpLCAwKSk7CisgIH0KKworICByZXR1cm4gc3RyOworfQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvdXBiLmMgYi9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy91cGIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMGJkNzZiCi0tLSAvZGV2L251bGwKKysrIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvdXBiLmMKQEAgLTAsMCArMSwxMTIyMCBAQAorLy8gQW1hbGdhbWF0ZWQgc291cmNlIGZpbGUKKyNpbmNsdWRlICJ1cGIuaCIKKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMDgtMjAxMiBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKi8KKworCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKK3R5cGVkZWYgc3RydWN0IHsKKyAgc2l6ZV90IGxlbjsKKyAgY2hhciBzdHJbMV07ICAvLyBOdWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGRhdGEgZm9sbG93cy4KK30gc3RyX3Q7CisKK3N0YXRpYyBzdHJfdCAqbmV3c3RyKGNvbnN0IGNoYXIgKmRhdGEsIHNpemVfdCBsZW4pIHsKKyAgc3RyX3QgKnJldCA9IG1hbGxvYyhzaXplb2YoKnJldCkgKyBsZW4pOworICBpZiAoIXJldCkgcmV0dXJuIE5VTEw7CisgIHJldC0+bGVuID0gbGVuOworICBtZW1jcHkocmV0LT5zdHIsIGRhdGEsIGxlbik7CisgIHJldC0+c3RyW2xlbl0gPSAnXDAnOworICByZXR1cm4gcmV0OworfQorCitzdGF0aWMgdm9pZCBmcmVlc3RyKHN0cl90ICpzKSB7IGZyZWUocyk7IH0KKworLy8gaXNhbHBoYSgpIGV0Yy4gZnJvbSA8Y3R5cGUuaD4gYXJlIGxvY2FsZS1kZXBlbmRlbnQsIHdoaWNoIHdlIGRvbid0IHdhbnQuCitzdGF0aWMgYm9vbCB1cGJfaXNiZXR3ZWVuKGNoYXIgYywgY2hhciBsb3csIGNoYXIgaGlnaCkgeworICByZXR1cm4gYyA+PSBsb3cgJiYgYyA8PSBoaWdoOworfQorCitzdGF0aWMgYm9vbCB1cGJfaXNsZXR0ZXIoY2hhciBjKSB7CisgIHJldHVybiB1cGJfaXNiZXR3ZWVuKGMsICdBJywgJ1onKSB8fCB1cGJfaXNiZXR3ZWVuKGMsICdhJywgJ3onKSB8fCBjID09ICdfJzsKK30KKworc3RhdGljIGJvb2wgdXBiX2lzYWxwaGFudW0oY2hhciBjKSB7CisgIHJldHVybiB1cGJfaXNsZXR0ZXIoYykgfHwgdXBiX2lzYmV0d2VlbihjLCAnMCcsICc5Jyk7Cit9CisKK3N0YXRpYyBib29sIHVwYl9pc2lkZW50KGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IGxlbiwgYm9vbCBmdWxsLCB1cGJfc3RhdHVzICpzKSB7CisgIGJvb2wgc3RhcnQgPSB0cnVlOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgY2hhciBjID0gc3RyW2ldOworICAgIGlmIChjID09ICcuJykgeworICAgICAgaWYgKHN0YXJ0IHx8ICFmdWxsKSB7CisgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihzLCAiaW52YWxpZCBuYW1lOiB1bmV4cGVjdGVkICcuJyAoJXMpIiwgc3RyKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgc3RhcnQgPSB0cnVlOworICAgIH0gZWxzZSBpZiAoc3RhcnQpIHsKKyAgICAgIGlmICghdXBiX2lzbGV0dGVyKGMpKSB7CisgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZigKKyAgICAgICAgICAgIHMsICJpbnZhbGlkIG5hbWU6IHBhdGggY29tcG9uZW50cyBtdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIgKCVzKSIsCisgICAgICAgICAgICBzdHIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBzdGFydCA9IGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICBpZiAoIXVwYl9pc2FscGhhbnVtKGMpKSB7CisgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihzLCAiaW52YWxpZCBuYW1lOiBub24tYWxwaGFudW1lcmljIGNoYXJhY3RlciAoJXMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuICFzdGFydDsKK30KKworCisvKiB1cGJfZGVmICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit1cGJfZGVmdHlwZV90IHVwYl9kZWZfdHlwZShjb25zdCB1cGJfZGVmICpkKSB7IHJldHVybiBkLT50eXBlOyB9CisKK2NvbnN0IGNoYXIgKnVwYl9kZWZfZnVsbG5hbWUoY29uc3QgdXBiX2RlZiAqZCkgeyByZXR1cm4gZC0+ZnVsbG5hbWU7IH0KKworYm9vbCB1cGJfZGVmX3NldGZ1bGxuYW1lKHVwYl9kZWYgKmRlZiwgY29uc3QgY2hhciAqZnVsbG5hbWUsIHVwYl9zdGF0dXMgKnMpIHsKKyAgYXNzZXJ0KCF1cGJfZGVmX2lzZnJvemVuKGRlZikpOworICBpZiAoIXVwYl9pc2lkZW50KGZ1bGxuYW1lLCBzdHJsZW4oZnVsbG5hbWUpLCB0cnVlLCBzKSkgcmV0dXJuIGZhbHNlOworICBmcmVlKCh2b2lkKilkZWYtPmZ1bGxuYW1lKTsKKyAgZGVmLT5mdWxsbmFtZSA9IHVwYl9zdHJkdXAoZnVsbG5hbWUpOworICByZXR1cm4gdHJ1ZTsKK30KKwordXBiX2RlZiAqdXBiX2RlZl9kdXAoY29uc3QgdXBiX2RlZiAqZGVmLCBjb25zdCB2b2lkICpvKSB7CisgIHN3aXRjaCAoZGVmLT50eXBlKSB7CisgICAgY2FzZSBVUEJfREVGX01TRzoKKyAgICAgIHJldHVybiBVUEJfVVBDQVNUKHVwYl9tc2dkZWZfZHVwKHVwYl9kb3duY2FzdF9tc2dkZWYoZGVmKSwgbykpOworICAgIGNhc2UgVVBCX0RFRl9GSUVMRDoKKyAgICAgIHJldHVybiBVUEJfVVBDQVNUKHVwYl9maWVsZGRlZl9kdXAodXBiX2Rvd25jYXN0X2ZpZWxkZGVmKGRlZiksIG8pKTsKKyAgICBjYXNlIFVQQl9ERUZfRU5VTToKKyAgICAgIHJldHVybiBVUEJfVVBDQVNUKHVwYl9lbnVtZGVmX2R1cCh1cGJfZG93bmNhc3RfZW51bWRlZihkZWYpLCBvKSk7CisgICAgZGVmYXVsdDogYXNzZXJ0KGZhbHNlKTsgcmV0dXJuIE5VTEw7CisgIH0KK30KKworYm9vbCB1cGJfZGVmX2lzZnJvemVuKGNvbnN0IHVwYl9kZWYgKmRlZikgeworICByZXR1cm4gdXBiX3JlZmNvdW50ZWRfaXNmcm96ZW4oVVBCX1VQQ0FTVChkZWYpKTsKK30KKwordm9pZCB1cGJfZGVmX3JlZihjb25zdCB1cGJfZGVmICpkZWYsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9yZWZjb3VudGVkX3JlZihVUEJfVVBDQVNUKGRlZiksIG93bmVyKTsKK30KKwordm9pZCB1cGJfZGVmX3VucmVmKGNvbnN0IHVwYl9kZWYgKmRlZiwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX3JlZmNvdW50ZWRfdW5yZWYoVVBCX1VQQ0FTVChkZWYpLCBvd25lcik7Cit9CisKK3ZvaWQgdXBiX2RlZl9kb25hdGVyZWYoY29uc3QgdXBiX2RlZiAqZGVmLCBjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0bykgeworICB1cGJfcmVmY291bnRlZF9kb25hdGVyZWYoVVBCX1VQQ0FTVChkZWYpLCBmcm9tLCB0byk7Cit9CisKK3ZvaWQgdXBiX2RlZl9jaGVja3JlZihjb25zdCB1cGJfZGVmICpkZWYsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9yZWZjb3VudGVkX2NoZWNrcmVmKFVQQl9VUENBU1QoZGVmKSwgb3duZXIpOworfQorCitzdGF0aWMgYm9vbCB1cGJfZGVmX2luaXQodXBiX2RlZiAqZGVmLCB1cGJfZGVmdHlwZV90IHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IHVwYl9yZWZjb3VudGVkX3Z0YmwgKnZ0YmwsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgaWYgKCF1cGJfcmVmY291bnRlZF9pbml0KFVQQl9VUENBU1QoZGVmKSwgdnRibCwgb3duZXIpKSByZXR1cm4gZmFsc2U7CisgIGRlZi0+dHlwZSA9IHR5cGU7CisgIGRlZi0+ZnVsbG5hbWUgPSBOVUxMOworICBkZWYtPmNhbWVfZnJvbV91c2VyID0gZmFsc2U7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgdm9pZCB1cGJfZGVmX3VuaW5pdCh1cGJfZGVmICpkZWYpIHsKKyAgZnJlZSgodm9pZCopZGVmLT5mdWxsbmFtZSk7Cit9CisKK3N0YXRpYyBjb25zdCBjaGFyICptc2dkZWZfbmFtZShjb25zdCB1cGJfbXNnZGVmICptKSB7CisgIGNvbnN0IGNoYXIgKm5hbWUgPSB1cGJfZGVmX2Z1bGxuYW1lKFVQQl9VUENBU1QobSkpOworICByZXR1cm4gbmFtZSA/IG5hbWUgOiAiKGFub255bW91cykiOworfQorCitzdGF0aWMgYm9vbCB1cGJfdmFsaWRhdGVfZmllbGQodXBiX2ZpZWxkZGVmICpmLCB1cGJfc3RhdHVzICpzKSB7CisgIGlmICh1cGJfZmllbGRkZWZfbmFtZShmKSA9PSBOVUxMIHx8IHVwYl9maWVsZGRlZl9udW1iZXIoZikgPT0gMCkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJmaWVsZGRlZiBtdXN0IGhhdmUgbmFtZSBhbmQgbnVtYmVyIHNldCIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmICghZi0+dHlwZV9pc19zZXRfKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgImZpZWxkZGVmIHR5cGUgd2FzIG5vdCBpbml0aWFsaXplZCIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmICh1cGJfZmllbGRkZWZfbGF6eShmKSAmJgorICAgICAgdXBiX2ZpZWxkZGVmX2Rlc2NyaXB0b3J0eXBlKGYpICE9IFVQQl9ERVNDUklQVE9SX1RZUEVfTUVTU0FHRSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIm9ubHkgbGVuZ3RoLWRlbGltaXRlZCBzdWJtZXNzYWdlIGZpZWxkcyBtYXkgYmUgbGF6eSIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmICh1cGJfZmllbGRkZWZfaGFzc3ViZGVmKGYpKSB7CisgICAgaWYgKGYtPnN1YmRlZl9pc19zeW1ib2xpYykgeworICAgICAgdXBiX3N0YXR1c19zZXRlcnJmKHMsICJmaWVsZCAnJXMuJXMnIGhhcyBub3QgYmVlbiByZXNvbHZlZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgbXNnZGVmX25hbWUoZi0+bXNnLmRlZiksIHVwYl9maWVsZGRlZl9uYW1lKGYpKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBjb25zdCB1cGJfZGVmICpzdWJkZWYgPSB1cGJfZmllbGRkZWZfc3ViZGVmKGYpOworICAgIGlmIChzdWJkZWYgPT0gTlVMTCkgeworICAgICAgdXBiX3N0YXR1c19zZXRlcnJmKHMsICJmaWVsZCAlcy4lcyBpcyBtaXNzaW5nIHJlcXVpcmVkIHN1YmRlZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgbXNnZGVmX25hbWUoZi0+bXNnLmRlZiksIHVwYl9maWVsZGRlZl9uYW1lKGYpKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIXVwYl9kZWZfaXNmcm96ZW4oc3ViZGVmKSAmJiAhc3ViZGVmLT5jYW1lX2Zyb21fdXNlcikgeworICAgICAgdXBiX3N0YXR1c19zZXRlcnJmKHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgInN1YmRlZiBvZiBmaWVsZCAlcy4lcyBpcyBub3QgZnJvemVuIG9yIGJlaW5nIGZyb3plbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgbXNnZGVmX25hbWUoZi0+bXNnLmRlZiksIHVwYl9maWVsZGRlZl9uYW1lKGYpKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICBpZiAodXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfRU5VTSkgeworICAgIGJvb2wgaGFzX2RlZmF1bHRfbmFtZSA9IHVwYl9maWVsZGRlZl9lbnVtaGFzZGVmYXVsdHN0cihmKTsKKyAgICBib29sIGhhc19kZWZhdWx0X251bWJlciA9IHVwYl9maWVsZGRlZl9lbnVtaGFzZGVmYXVsdGludDMyKGYpOworCisgICAgLy8gUHJldmlvdXNseSB2ZXJpZmllZCBieSB1cGJfdmFsaWRhdGVfZW51bWRlZigpLgorICAgIGFzc2VydCh1cGJfZW51bWRlZl9udW12YWxzKHVwYl9maWVsZGRlZl9lbnVtc3ViZGVmKGYpKSA+IDApOworCisgICAgLy8gV2UndmUgYWxyZWFkeSB2YWxpZGF0ZWQgdGhhdCB3ZSBoYXZlIGFuIGFzc29jaWF0ZWQgZW51bWRlZiBhbmQgdGhhdCBpdAorICAgIC8vIGhhcyBhdCBsZWFzdCBvbmUgbWVtYmVyLCBzbyBhdCBsZWFzdCBvbmUgb2YgdGhlc2Ugc2hvdWxkIGJlIHRydWUuCisgICAgLy8gQmVjYXVzZSBpZiB0aGUgdXNlciBkaWRuJ3Qgc2V0IGFueXRoaW5nLCB3ZSdsbCBwaWNrIHVwIHRoZSBlbnVtJ3MKKyAgICAvLyBkZWZhdWx0LCBidXQgaWYgdGhlIHVzZXIgKmRpZCogc2V0IHNvbWV0aGluZyB3ZSBzaG91bGQgYXQgbGVhc3QgcGljayB1cAorICAgIC8vIHRoZSBvbmUgdGhleSBzZXQgKGludDMyIG9yIHN0cmluZykuCisgICAgYXNzZXJ0KGhhc19kZWZhdWx0X25hbWUgfHwgaGFzX2RlZmF1bHRfbnVtYmVyKTsKKworICAgIGlmICghaGFzX2RlZmF1bHRfbmFtZSkgeworICAgICAgdXBiX3N0YXR1c19zZXRlcnJmKHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgImVudW0gZGVmYXVsdCBmb3IgZmllbGQgJXMuJXMgKCVkKSBpcyBub3QgaW4gdGhlIGVudW0iLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1zZ2RlZl9uYW1lKGYtPm1zZy5kZWYpLCB1cGJfZmllbGRkZWZfbmFtZShmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfZGVmYXVsdGludDMyKGYpKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIWhhc19kZWZhdWx0X251bWJlcikgeworICAgICAgdXBiX3N0YXR1c19zZXRlcnJmKHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgImVudW0gZGVmYXVsdCBmb3IgZmllbGQgJXMuJXMgKCVzKSBpcyBub3QgaW4gdGhlIGVudW0iLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1zZ2RlZl9uYW1lKGYtPm1zZy5kZWYpLCB1cGJfZmllbGRkZWZfbmFtZShmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfZGVmYXVsdHN0cihmLCBOVUxMKSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gTGlmdCB0aGUgZWZmZWN0aXZlIG51bWVyaWMgZGVmYXVsdCBpbnRvIHRoZSBmaWVsZCdzIGRlZmF1bHQgc2xvdCwgaW4gY2FzZQorICAgIC8vIHdlIHdlcmUgb25seSBnZXR0aW5nIGl0ICJieSByZWZlcmVuY2UiIGZyb20gdGhlIGVudW1kZWYuCisgICAgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRpbnQzMihmLCB1cGJfZmllbGRkZWZfZGVmYXVsdGludDMyKGYpKTsKKyAgfQorCisgIC8vIEVuc3VyZSB0aGF0IE1hcEVudHJ5IHN1Ym1lc3NhZ2VzIG9ubHkgYXBwZWFyIGFzIHJlcGVhdGVkIGZpZWxkcywgbm90CisgIC8vIG9wdGlvbmFsL3JlcXVpcmVkIChzaW5ndWxhcikgZmllbGRzLgorICBpZiAodXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfTUVTU0FHRSAmJgorICAgICAgdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihmKSAhPSBOVUxMKSB7CisgICAgY29uc3QgdXBiX21zZ2RlZiAqc3ViZGVmID0gdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihmKTsKKyAgICBpZiAodXBiX21zZ2RlZl9tYXBlbnRyeShzdWJkZWYpICYmICF1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihzLAorICAgICAgICAgICAgICAgICAgICAgICAgICJGaWVsZCAlcyByZWZlcnMgdG8gbWFwZW50cnkgbWVzc2FnZSBidXQgaXMgbm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiYSByZXBlYXRlZCBmaWVsZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2ZpZWxkZGVmX25hbWUoZikgPyB1cGJfZmllbGRkZWZfbmFtZShmKSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgIih1bm5hbWVkKSIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCB1cGJfdmFsaWRhdGVfZW51bWRlZihjb25zdCB1cGJfZW51bWRlZiAqZSwgdXBiX3N0YXR1cyAqcykgeworICBpZiAodXBiX2VudW1kZWZfbnVtdmFscyhlKSA9PSAwKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJmKHMsICJlbnVtICVzIGhhcyBubyBtZW1iZXJzIChtdXN0IGhhdmUgYXQgbGVhc3Qgb25lKSIsCisgICAgICAgICAgICAgICAgICAgICAgIHVwYl9lbnVtZGVmX2Z1bGxuYW1lKGUpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gQWxsIHN1Ym1lc3NhZ2UgZmllbGRzIGFyZSBsb3dlciB0aGFuIGFsbCBvdGhlciBmaWVsZHMuCisvLyBTZWNvbmRseSwgZmllbGRzIGFyZSBpbmNyZWFzaW5nIGluIG9yZGVyLgordWludDMyX3QgZmllbGRfcmFuayhjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgdWludDMyX3QgcmV0ID0gdXBiX2ZpZWxkZGVmX251bWJlcihmKTsKKyAgY29uc3QgdWludDMyX3QgaGlnaF9iaXQgPSAxIDw8IDMwOworICBhc3NlcnQocmV0IDwgaGlnaF9iaXQpOworICBpZiAoIXVwYl9maWVsZGRlZl9pc3N1Ym1zZyhmKSkKKyAgICByZXQgfD0gaGlnaF9iaXQ7CisgIHJldHVybiByZXQ7Cit9CisKK2ludCBjbXBfZmllbGRzKGNvbnN0IHZvaWQgKnAxLCBjb25zdCB2b2lkICpwMikgeworICBjb25zdCB1cGJfZmllbGRkZWYgKmYxID0gKih1cGJfZmllbGRkZWYqY29uc3QqKXAxOworICBjb25zdCB1cGJfZmllbGRkZWYgKmYyID0gKih1cGJfZmllbGRkZWYqY29uc3QqKXAyOworICByZXR1cm4gZmllbGRfcmFuayhmMSkgLSBmaWVsZF9yYW5rKGYyKTsKK30KKworc3RhdGljIGJvb2wgYXNzaWduX21zZ19pbmRpY2VzKHVwYl9tc2dkZWYgKm0sIHVwYl9zdGF0dXMgKnMpIHsKKyAgLy8gU29ydCBmaWVsZHMuICB1cGIgaW50ZXJuYWxseSByZWxpZXMgb24gVVBCX1RZUEVfTUVTU0FHRSBmaWVsZHMgaGF2aW5nIHRoZQorICAvLyBsb3dlc3QgaW5kZXhlcywgYnV0IHdlIGRvIG5vdCBwdWJsaWNseSBndWFyYW50ZWUgdGhpcy4KKyAgaW50IG4gPSB1cGJfbXNnZGVmX251bWZpZWxkcyhtKTsKKyAgdXBiX2ZpZWxkZGVmICoqZmllbGRzID0gbWFsbG9jKG4gKiBzaXplb2YoKmZpZWxkcykpOworICBpZiAoIWZpZWxkcykgcmV0dXJuIGZhbHNlOworCisgIHVwYl9tc2dfZmllbGRfaXRlciBqOworICBpbnQgaTsKKyAgbS0+c3VibXNnX2ZpZWxkX2NvdW50ID0gMDsKKyAgZm9yKGkgPSAwLCB1cGJfbXNnX2ZpZWxkX2JlZ2luKCZqLCBtKTsKKyAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmopOworICAgICAgdXBiX21zZ19maWVsZF9uZXh0KCZqKSwgaSsrKSB7CisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZqKTsKKyAgICBhc3NlcnQoZi0+bXNnLmRlZiA9PSBtKTsKKyAgICBpZiAoIXVwYl92YWxpZGF0ZV9maWVsZChmLCBzKSkgeworICAgICAgZnJlZShmaWVsZHMpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpKSB7CisgICAgICBtLT5zdWJtc2dfZmllbGRfY291bnQrKzsKKyAgICB9CisgICAgZmllbGRzW2ldID0gZjsKKyAgfQorCisgIHFzb3J0KGZpZWxkcywgbiwgc2l6ZW9mKCpmaWVsZHMpLCBjbXBfZmllbGRzKTsKKworICB1aW50MzJfdCBzZWxlY3RvciA9IFVQQl9TVEFUSUNfU0VMRUNUT1JfQ09VTlQgKyBtLT5zdWJtc2dfZmllbGRfY291bnQ7CisgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICB1cGJfZmllbGRkZWYgKmYgPSBmaWVsZHNbaV07CisgICAgZi0+aW5kZXhfID0gaTsKKyAgICBmLT5zZWxlY3Rvcl9iYXNlID0gc2VsZWN0b3IgKyB1cGJfaGFuZGxlcnNfc2VsZWN0b3JiYXNlb2Zmc2V0KGYpOworICAgIHNlbGVjdG9yICs9IHVwYl9oYW5kbGVyc19zZWxlY3RvcmNvdW50KGYpOworICB9CisgIG0tPnNlbGVjdG9yX2NvdW50ID0gc2VsZWN0b3I7CisKKyNpZm5kZWYgTkRFQlVHCisgIC8vIFZlcmlmeSB0aGF0IGFsbCBzZWxlY3RvcnMgZm9yIHRoZSBtZXNzYWdlIGFyZSBkaXN0aW5jdC4KKyAgLy8KKyNkZWZpbmUgVFJZKHR5cGUpIFwKKyAgaWYgKHVwYl9oYW5kbGVyc19nZXRzZWxlY3RvcihmLCB0eXBlLCAmc2VsKSkgdXBiX2ludHRhYmxlX2luc2VydCgmdCwgc2VsLCB2KTsKKworICB1cGJfaW50dGFibGUgdDsKKyAgdXBiX2ludHRhYmxlX2luaXQoJnQsIFVQQl9DVFlQRV9CT09MKTsKKyAgdXBiX3ZhbHVlIHYgPSB1cGJfdmFsdWVfYm9vbCh0cnVlKTsKKyAgdXBiX3NlbGVjdG9yX3Qgc2VsOworICB1cGJfaW50dGFibGVfaW5zZXJ0KCZ0LCBVUEJfU1RBUlRNU0dfU0VMRUNUT1IsIHYpOworICB1cGJfaW50dGFibGVfaW5zZXJ0KCZ0LCBVUEJfRU5ETVNHX1NFTEVDVE9SLCB2KTsKKyAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmosIG0pOworICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaik7CisgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmopKSB7CisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZqKTsKKyAgICAvLyBUaGVzZSBjYWxscyB3aWxsIGFzc2VydC1mYWlsIGluIHVwYl90YWJsZSBpZiB0aGUgdmFsdWUgYWxyZWFkeSBleGlzdHMuCisgICAgVFJZKFVQQl9IQU5ETEVSX0lOVDMyKTsKKyAgICBUUlkoVVBCX0hBTkRMRVJfSU5UNjQpCisgICAgVFJZKFVQQl9IQU5ETEVSX1VJTlQzMikKKyAgICBUUlkoVVBCX0hBTkRMRVJfVUlOVDY0KQorICAgIFRSWShVUEJfSEFORExFUl9GTE9BVCkKKyAgICBUUlkoVVBCX0hBTkRMRVJfRE9VQkxFKQorICAgIFRSWShVUEJfSEFORExFUl9CT09MKQorICAgIFRSWShVUEJfSEFORExFUl9TVEFSVFNUUikKKyAgICBUUlkoVVBCX0hBTkRMRVJfU1RSSU5HKQorICAgIFRSWShVUEJfSEFORExFUl9FTkRTVFIpCisgICAgVFJZKFVQQl9IQU5ETEVSX1NUQVJUU1VCTVNHKQorICAgIFRSWShVUEJfSEFORExFUl9FTkRTVUJNU0cpCisgICAgVFJZKFVQQl9IQU5ETEVSX1NUQVJUU0VRKQorICAgIFRSWShVUEJfSEFORExFUl9FTkRTRVEpCisgIH0KKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmdCk7CisjdW5kZWYgVFJZCisjZW5kaWYKKworICBmcmVlKGZpZWxkcyk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9kZWZfZnJlZXplKHVwYl9kZWYgKmNvbnN0KiBkZWZzLCBpbnQgbiwgdXBiX3N0YXR1cyAqcykgeworICB1cGJfc3RhdHVzX2NsZWFyKHMpOworCisgIC8vIEZpcnN0IHBlcmZvcm0gdmFsaWRhdGlvbiwgaW4gdHdvIHBhc3NlcyBzbyB3ZSBjYW4gY2hlY2sgdGhhdCB3ZSBoYXZlIGEKKyAgLy8gdHJhbnNpdGl2ZSBjbG9zdXJlIHdpdGhvdXQgbmVlZGluZyB0byBzZWFyY2guCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgdXBiX2RlZiAqZGVmID0gZGVmc1tpXTsKKyAgICBpZiAodXBiX2RlZl9pc2Zyb3plbihkZWYpKSB7CisgICAgICAvLyBDb3VsZCByZWxheCB0aGlzIHJlcXVpcmVtZW50IGlmIGl0J3MgYW5ub3lpbmcuCisgICAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiZGVmIGlzIGFscmVhZHkgZnJvemVuIik7CisgICAgICBnb3RvIGVycjsKKyAgICB9IGVsc2UgaWYgKGRlZi0+dHlwZSA9PSBVUEJfREVGX0ZJRUxEKSB7CisgICAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAic3RhbmRhbG9uZSBmaWVsZGRlZnMgY2FuIG5vdCBiZSBmcm96ZW4iKTsKKyAgICAgIGdvdG8gZXJyOworICAgIH0gZWxzZSBpZiAoZGVmLT50eXBlID09IFVQQl9ERUZfRU5VTSkgeworICAgICAgaWYgKCF1cGJfdmFsaWRhdGVfZW51bWRlZih1cGJfZHluY2FzdF9lbnVtZGVmKGRlZiksIHMpKSB7CisgICAgICAgIGdvdG8gZXJyOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBTZXQgbm93IHRvIGRldGVjdCB0cmFuc2l0aXZlIGNsb3N1cmUgaW4gdGhlIHNlY29uZCBwYXNzLgorICAgICAgZGVmLT5jYW1lX2Zyb21fdXNlciA9IHRydWU7CisgICAgfQorICB9CisKKyAgLy8gU2Vjb25kIHBhc3Mgb2YgdmFsaWRhdGlvbi4gIEFsc28gYXNzaWduIHNlbGVjdG9yIGJhc2VzIGFuZCBpbmRleGVzLCBhbmQKKyAgLy8gY29tcGFjdCB0YWJsZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgdXBiX21zZ2RlZiAqbSA9IHVwYl9keW5jYXN0X21zZ2RlZl9tdXRhYmxlKGRlZnNbaV0pOworICAgIHVwYl9lbnVtZGVmICplID0gdXBiX2R5bmNhc3RfZW51bWRlZl9tdXRhYmxlKGRlZnNbaV0pOworICAgIGlmIChtKSB7CisgICAgICB1cGJfaW50dGFibGVfY29tcGFjdCgmbS0+aXRvZik7CisgICAgICBpZiAoIWFzc2lnbl9tc2dfaW5kaWNlcyhtLCBzKSkgeworICAgICAgICBnb3RvIGVycjsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGUpIHsKKyAgICAgIHVwYl9pbnR0YWJsZV9jb21wYWN0KCZlLT5pdG9uKTsKKyAgICB9CisgIH0KKworICAvLyBEZWYgZ3JhcGggY29udGFpbnMgRmllbGREZWZzIGJldHdlZW4gZWFjaCBNZXNzYWdlRGVmLCBzbyBkb3VibGUgdGhlIGxpbWl0LgorICBpbnQgbWF4ZGVwdGggPSBVUEJfTUFYX01FU1NBR0VfREVQVEggKiAyOworCisgIC8vIFZhbGlkYXRpb24gYWxsIHBhc3NlZDsgZnJlZXplIHRoZSBkZWZzLgorICBib29sIHJldCA9CisgICAgICB1cGJfcmVmY291bnRlZF9mcmVlemUoKHVwYl9yZWZjb3VudGVkICogY29uc3QgKilkZWZzLCBuLCBzLCBtYXhkZXB0aCk7CisgIGFzc2VydCghKHMgJiYgcmV0ICE9IHVwYl9vayhzKSkpOworICByZXR1cm4gcmV0OworCitlcnI6CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgZGVmc1tpXS0+Y2FtZV9mcm9tX3VzZXIgPSBmYWxzZTsKKyAgfQorICBhc3NlcnQoIShzICYmIHVwYl9vayhzKSkpOworICByZXR1cm4gZmFsc2U7Cit9CisKKworLyogdXBiX2VudW1kZWYgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIHZvaWQgdXBiX2VudW1kZWZfZnJlZSh1cGJfcmVmY291bnRlZCAqcikgeworICB1cGJfZW51bWRlZiAqZSA9ICh1cGJfZW51bWRlZiopcjsKKyAgdXBiX2ludHRhYmxlX2l0ZXIgaTsKKyAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCAmZS0+aXRvbik7CisgIGZvciggOyAhdXBiX2ludHRhYmxlX2RvbmUoJmkpOyB1cGJfaW50dGFibGVfbmV4dCgmaSkpIHsKKyAgICAvLyBUbyBjbGVhbiB1cCB0aGUgdXBiX3N0cmR1cCgpIGZyb20gdXBiX2VudW1kZWZfYWRkdmFsKCkuCisgICAgZnJlZSh1cGJfdmFsdWVfZ2V0Y3N0cih1cGJfaW50dGFibGVfaXRlcl92YWx1ZSgmaSkpKTsKKyAgfQorICB1cGJfc3RydGFibGVfdW5pbml0KCZlLT5udG9pKTsKKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmZS0+aXRvbik7CisgIHVwYl9kZWZfdW5pbml0KFVQQl9VUENBU1QoZSkpOworICBmcmVlKGUpOworfQorCit1cGJfZW51bWRlZiAqdXBiX2VudW1kZWZfbmV3KGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgdXBiX3JlZmNvdW50ZWRfdnRibCB2dGJsID0ge05VTEwsICZ1cGJfZW51bWRlZl9mcmVlfTsKKyAgdXBiX2VudW1kZWYgKmUgPSBtYWxsb2Moc2l6ZW9mKCplKSk7CisgIGlmICghZSkgcmV0dXJuIE5VTEw7CisgIGlmICghdXBiX2RlZl9pbml0KFVQQl9VUENBU1QoZSksIFVQQl9ERUZfRU5VTSwgJnZ0YmwsIG93bmVyKSkgZ290byBlcnIyOworICBpZiAoIXVwYl9zdHJ0YWJsZV9pbml0KCZlLT5udG9pLCBVUEJfQ1RZUEVfSU5UMzIpKSBnb3RvIGVycjI7CisgIGlmICghdXBiX2ludHRhYmxlX2luaXQoJmUtPml0b24sIFVQQl9DVFlQRV9DU1RSKSkgZ290byBlcnIxOworICByZXR1cm4gZTsKKworZXJyMToKKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmZS0+bnRvaSk7CitlcnIyOgorICBmcmVlKGUpOworICByZXR1cm4gTlVMTDsKK30KKwordXBiX2VudW1kZWYgKnVwYl9lbnVtZGVmX2R1cChjb25zdCB1cGJfZW51bWRlZiAqZSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2VudW1kZWYgKm5ld19lID0gdXBiX2VudW1kZWZfbmV3KG93bmVyKTsKKyAgaWYgKCFuZXdfZSkgcmV0dXJuIE5VTEw7CisgIHVwYl9lbnVtX2l0ZXIgaTsKKyAgZm9yKHVwYl9lbnVtX2JlZ2luKCZpLCBlKTsgIXVwYl9lbnVtX2RvbmUoJmkpOyB1cGJfZW51bV9uZXh0KCZpKSkgeworICAgIGJvb2wgc3VjY2VzcyA9IHVwYl9lbnVtZGVmX2FkZHZhbCgKKyAgICAgICAgbmV3X2UsIHVwYl9lbnVtX2l0ZXJfbmFtZSgmaSksdXBiX2VudW1faXRlcl9udW1iZXIoJmkpLCBOVUxMKTsKKyAgICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICAgIHVwYl9lbnVtZGVmX3VucmVmKG5ld19lLCBvd25lcik7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIG5ld19lOworfQorCitib29sIHVwYl9lbnVtZGVmX2lzZnJvemVuKGNvbnN0IHVwYl9lbnVtZGVmICplKSB7CisgIHJldHVybiB1cGJfZGVmX2lzZnJvemVuKFVQQl9VUENBU1QoZSkpOworfQorCit2b2lkIHVwYl9lbnVtZGVmX3JlZihjb25zdCB1cGJfZW51bWRlZiAqZSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl9yZWYoVVBCX1VQQ0FTVChlKSwgb3duZXIpOworfQorCit2b2lkIHVwYl9lbnVtZGVmX3VucmVmKGNvbnN0IHVwYl9lbnVtZGVmICplLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfZGVmX3VucmVmKFVQQl9VUENBU1QoZSksIG93bmVyKTsKK30KKwordm9pZCB1cGJfZW51bWRlZl9kb25hdGVyZWYoCisgICAgY29uc3QgdXBiX2VudW1kZWYgKmUsIGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKSB7CisgIHVwYl9kZWZfZG9uYXRlcmVmKFVQQl9VUENBU1QoZSksIGZyb20sIHRvKTsKK30KKwordm9pZCB1cGJfZW51bWRlZl9jaGVja3JlZihjb25zdCB1cGJfZW51bWRlZiAqZSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl9jaGVja3JlZihVUEJfVVBDQVNUKGUpLCBvd25lcik7Cit9CisKK2Jvb2wgdXBiX2VudW1kZWZfZnJlZXplKHVwYl9lbnVtZGVmICplLCB1cGJfc3RhdHVzICpzdGF0dXMpIHsKKyAgdXBiX2RlZiAqZCA9IFVQQl9VUENBU1QoZSk7CisgIHJldHVybiB1cGJfZGVmX2ZyZWV6ZSgmZCwgMSwgc3RhdHVzKTsKK30KKworY29uc3QgY2hhciAqdXBiX2VudW1kZWZfZnVsbG5hbWUoY29uc3QgdXBiX2VudW1kZWYgKmUpIHsKKyAgcmV0dXJuIHVwYl9kZWZfZnVsbG5hbWUoVVBCX1VQQ0FTVChlKSk7Cit9CisKK2Jvb2wgdXBiX2VudW1kZWZfc2V0ZnVsbG5hbWUodXBiX2VudW1kZWYgKmUsIGNvbnN0IGNoYXIgKmZ1bGxuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKSB7CisgIHJldHVybiB1cGJfZGVmX3NldGZ1bGxuYW1lKFVQQl9VUENBU1QoZSksIGZ1bGxuYW1lLCBzKTsKK30KKworYm9vbCB1cGJfZW51bWRlZl9hZGR2YWwodXBiX2VudW1kZWYgKmUsIGNvbnN0IGNoYXIgKm5hbWUsIGludDMyX3QgbnVtLAorICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIGlmICghdXBiX2lzaWRlbnQobmFtZSwgc3RybGVuKG5hbWUpLCBmYWxzZSwgc3RhdHVzKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAodXBiX2VudW1kZWZfbnRvaXooZSwgbmFtZSwgTlVMTCkpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycmYoc3RhdHVzLCAibmFtZSAnJXMnIGlzIGFscmVhZHkgZGVmaW5lZCIsIG5hbWUpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoIXVwYl9zdHJ0YWJsZV9pbnNlcnQoJmUtPm50b2ksIG5hbWUsIHVwYl92YWx1ZV9pbnQzMihudW0pKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgIm91dCBvZiBtZW1vcnkiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKCF1cGJfaW50dGFibGVfbG9va3VwKCZlLT5pdG9uLCBudW0sIE5VTEwpICYmCisgICAgICAhdXBiX2ludHRhYmxlX2luc2VydCgmZS0+aXRvbiwgbnVtLCB1cGJfdmFsdWVfY3N0cih1cGJfc3RyZHVwKG5hbWUpKSkpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzdGF0dXMsICJvdXQgb2YgbWVtb3J5Iik7CisgICAgdXBiX3N0cnRhYmxlX3JlbW92ZSgmZS0+bnRvaSwgbmFtZSwgTlVMTCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmICh1cGJfZW51bWRlZl9udW12YWxzKGUpID09IDEpIHsKKyAgICBib29sIG9rID0gdXBiX2VudW1kZWZfc2V0ZGVmYXVsdChlLCBudW0sIE5VTEwpOworICAgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2ludDMyX3QgdXBiX2VudW1kZWZfZGVmYXVsdChjb25zdCB1cGJfZW51bWRlZiAqZSkgeworICBhc3NlcnQodXBiX2VudW1kZWZfaXRvbihlLCBlLT5kZWZhdWx0dmFsKSk7CisgIHJldHVybiBlLT5kZWZhdWx0dmFsOworfQorCitib29sIHVwYl9lbnVtZGVmX3NldGRlZmF1bHQodXBiX2VudW1kZWYgKmUsIGludDMyX3QgdmFsLCB1cGJfc3RhdHVzICpzKSB7CisgIGFzc2VydCghdXBiX2VudW1kZWZfaXNmcm96ZW4oZSkpOworICBpZiAoIXVwYl9lbnVtZGVmX2l0b24oZSwgdmFsKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihzLCAibnVtYmVyICclZCcgaXMgbm90IGluIHRoZSBlbnVtLiIsIHZhbCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGUtPmRlZmF1bHR2YWwgPSB2YWw7CisgIHJldHVybiB0cnVlOworfQorCitpbnQgdXBiX2VudW1kZWZfbnVtdmFscyhjb25zdCB1cGJfZW51bWRlZiAqZSkgeworICByZXR1cm4gdXBiX3N0cnRhYmxlX2NvdW50KCZlLT5udG9pKTsKK30KKwordm9pZCB1cGJfZW51bV9iZWdpbih1cGJfZW51bV9pdGVyICppLCBjb25zdCB1cGJfZW51bWRlZiAqZSkgeworICAvLyBXZSBpdGVyYXRlIG92ZXIgdGhlIG50b2kgdGFibGUsIHRvIGFjY291bnQgZm9yIGR1cGxpY2F0ZSBudW1iZXJzLgorICB1cGJfc3RydGFibGVfYmVnaW4oaSwgJmUtPm50b2kpOworfQorCit2b2lkIHVwYl9lbnVtX25leHQodXBiX2VudW1faXRlciAqaXRlcikgeyB1cGJfc3RydGFibGVfbmV4dChpdGVyKTsgfQorYm9vbCB1cGJfZW51bV9kb25lKHVwYl9lbnVtX2l0ZXIgKml0ZXIpIHsgcmV0dXJuIHVwYl9zdHJ0YWJsZV9kb25lKGl0ZXIpOyB9CisKK2Jvb2wgdXBiX2VudW1kZWZfbnRvaShjb25zdCB1cGJfZW51bWRlZiAqZGVmLCBjb25zdCBjaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4sIGludDMyX3QgKm51bSkgeworICB1cGJfdmFsdWUgdjsKKyAgaWYgKCF1cGJfc3RydGFibGVfbG9va3VwMigmZGVmLT5udG9pLCBuYW1lLCBsZW4sICZ2KSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAobnVtKSAqbnVtID0gdXBiX3ZhbHVlX2dldGludDMyKHYpOworICByZXR1cm4gdHJ1ZTsKK30KKworY29uc3QgY2hhciAqdXBiX2VudW1kZWZfaXRvbihjb25zdCB1cGJfZW51bWRlZiAqZGVmLCBpbnQzMl90IG51bSkgeworICB1cGJfdmFsdWUgdjsKKyAgcmV0dXJuIHVwYl9pbnR0YWJsZV9sb29rdXAzMigmZGVmLT5pdG9uLCBudW0sICZ2KSA/CisgICAgICB1cGJfdmFsdWVfZ2V0Y3N0cih2KSA6IE5VTEw7Cit9CisKK2NvbnN0IGNoYXIgKnVwYl9lbnVtX2l0ZXJfbmFtZSh1cGJfZW51bV9pdGVyICppdGVyKSB7CisgIHJldHVybiB1cGJfc3RydGFibGVfaXRlcl9rZXkoaXRlcik7Cit9CisKK2ludDMyX3QgdXBiX2VudW1faXRlcl9udW1iZXIodXBiX2VudW1faXRlciAqaXRlcikgeworICByZXR1cm4gdXBiX3ZhbHVlX2dldGludDMyKHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKGl0ZXIpKTsKK30KKworCisvKiB1cGJfZmllbGRkZWYgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgdm9pZCB1cGJfZmllbGRkZWZfaW5pdF9kZWZhdWx0KHVwYl9maWVsZGRlZiAqZik7CisKK3N0YXRpYyB2b2lkIHVwYl9maWVsZGRlZl91bmluaXRfZGVmYXVsdCh1cGJfZmllbGRkZWYgKmYpIHsKKyAgaWYgKGYtPnR5cGVfaXNfc2V0XyAmJiBmLT5kZWZhdWx0X2lzX3N0cmluZyAmJiBmLT5kZWZhdWx0dmFsLmJ5dGVzKQorICAgIGZyZWVzdHIoZi0+ZGVmYXVsdHZhbC5ieXRlcyk7Cit9CisKK3N0YXRpYyB2b2lkIHZpc2l0ZmllbGQoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIHVwYl9yZWZjb3VudGVkX3Zpc2l0ICp2aXNpdCwKKyAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSAoY29uc3QgdXBiX2ZpZWxkZGVmKilyOworICBpZiAodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlKGYpKSB7CisgICAgdmlzaXQociwgVVBCX1VQQ0FTVDIodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlKGYpKSwgY2xvc3VyZSk7CisgIH0KKyAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZikpIHsKKyAgICB2aXNpdChyLCBVUEJfVVBDQVNUMih1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGYpKSwgY2xvc3VyZSk7CisgIH0KKyAgaWYgKHVwYl9maWVsZGRlZl9zdWJkZWYoZikpIHsKKyAgICB2aXNpdChyLCBVUEJfVVBDQVNUKHVwYl9maWVsZGRlZl9zdWJkZWYoZikpLCBjbG9zdXJlKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBmcmVlZmllbGQodXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgdXBiX2ZpZWxkZGVmICpmID0gKHVwYl9maWVsZGRlZiopcjsKKyAgdXBiX2ZpZWxkZGVmX3VuaW5pdF9kZWZhdWx0KGYpOworICBpZiAoZi0+c3ViZGVmX2lzX3N5bWJvbGljKQorICAgIGZyZWUoZi0+c3ViLm5hbWUpOworICB1cGJfZGVmX3VuaW5pdChVUEJfVVBDQVNUKGYpKTsKKyAgZnJlZShmKTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIgKmVudW1kZWZhdWx0c3RyKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBhc3NlcnQoZi0+dHlwZV9pc19zZXRfICYmIGYtPnR5cGVfID09IFVQQl9UWVBFX0VOVU0pOworICBjb25zdCB1cGJfZW51bWRlZiAqZSA9IHVwYl9maWVsZGRlZl9lbnVtc3ViZGVmKGYpOworICBpZiAoZi0+ZGVmYXVsdF9pc19zdHJpbmcgJiYgZi0+ZGVmYXVsdHZhbC5ieXRlcykgeworICAgIC8vIERlZmF1bHQgd2FzIGV4cGxpY2l0bHkgc2V0IGFzIGEgc3RyaW5nLgorICAgIHN0cl90ICpzID0gZi0+ZGVmYXVsdHZhbC5ieXRlczsKKyAgICByZXR1cm4gcy0+c3RyOworICB9IGVsc2UgaWYgKGUpIHsKKyAgICBpZiAoIWYtPmRlZmF1bHRfaXNfc3RyaW5nKSB7CisgICAgICAvLyBEZWZhdWx0IHdhcyBleHBsaWNpdGx5IHNldCBhcyBhbiBpbnRlZ2VyOyBsb29rIGl0IHVwIGluIGVudW1kZWYuCisgICAgICBjb25zdCBjaGFyICpuYW1lID0gdXBiX2VudW1kZWZfaXRvbihlLCBmLT5kZWZhdWx0dmFsLnNpbnQpOworICAgICAgaWYgKG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIERlZmF1bHQgaXMgY29tcGxldGVseSB1bnNldDsgcHVsbCBlbnVtZGVmIGRlZmF1bHQuCisgICAgICBpZiAodXBiX2VudW1kZWZfbnVtdmFscyhlKSA+IDApIHsKKyAgICAgICAgY29uc3QgY2hhciAqbmFtZSA9IHVwYl9lbnVtZGVmX2l0b24oZSwgdXBiX2VudW1kZWZfZGVmYXVsdChlKSk7CisgICAgICAgIGFzc2VydChuYW1lKTsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgYm9vbCBlbnVtZGVmYXVsdGludDMyKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgaW50MzJfdCAqdmFsKSB7CisgIGFzc2VydChmLT50eXBlX2lzX3NldF8gJiYgZi0+dHlwZV8gPT0gVVBCX1RZUEVfRU5VTSk7CisgIGNvbnN0IHVwYl9lbnVtZGVmICplID0gdXBiX2ZpZWxkZGVmX2VudW1zdWJkZWYoZik7CisgIGlmICghZi0+ZGVmYXVsdF9pc19zdHJpbmcpIHsKKyAgICAvLyBEZWZhdWx0IHdhcyBleHBsaWNpdGx5IHNldCBhcyBhbiBpbnRlZ2VyLgorICAgICp2YWwgPSBmLT5kZWZhdWx0dmFsLnNpbnQ7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoZSkgeworICAgIGlmIChmLT5kZWZhdWx0dmFsLmJ5dGVzKSB7CisgICAgICAvLyBEZWZhdWx0IHdhcyBleHBsaWNpdGx5IHNldCBhcyBhIHN0cjsgdHJ5IHRvIGxvb2t1cCBjb3JyZXNwb25kaW5nIGludC4KKyAgICAgIHN0cl90ICpzID0gZi0+ZGVmYXVsdHZhbC5ieXRlczsKKyAgICAgIGlmICh1cGJfZW51bWRlZl9udG9peihlLCBzLT5zdHIsIHZhbCkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIERlZmF1bHQgaXMgdW5zZXQ7IHRyeSB0byBwdWxsIGluIGVudW1kZWYgZGVmYXVsdC4KKyAgICAgIGlmICh1cGJfZW51bWRlZl9udW12YWxzKGUpID4gMCkgeworICAgICAgICAqdmFsID0gdXBiX2VudW1kZWZfZGVmYXVsdChlKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKwordXBiX2ZpZWxkZGVmICp1cGJfZmllbGRkZWZfbmV3KGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgdXBiX3JlZmNvdW50ZWRfdnRibCB2dGJsID0ge3Zpc2l0ZmllbGQsIGZyZWVmaWVsZH07CisgIHVwYl9maWVsZGRlZiAqZiA9IG1hbGxvYyhzaXplb2YoKmYpKTsKKyAgaWYgKCFmKSByZXR1cm4gTlVMTDsKKyAgaWYgKCF1cGJfZGVmX2luaXQoVVBCX1VQQ0FTVChmKSwgVVBCX0RFRl9GSUVMRCwgJnZ0YmwsIG93bmVyKSkgeworICAgIGZyZWUoZik7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgZi0+bXNnLmRlZiA9IE5VTEw7CisgIGYtPnN1Yi5kZWYgPSBOVUxMOworICBmLT5vbmVvZiA9IE5VTEw7CisgIGYtPnN1YmRlZl9pc19zeW1ib2xpYyA9IGZhbHNlOworICBmLT5tc2dfaXNfc3ltYm9saWMgPSBmYWxzZTsKKyAgZi0+bGFiZWxfID0gVVBCX0xBQkVMX09QVElPTkFMOworICBmLT50eXBlXyA9IFVQQl9UWVBFX0lOVDMyOworICBmLT5udW1iZXJfID0gMDsKKyAgZi0+dHlwZV9pc19zZXRfID0gZmFsc2U7CisgIGYtPnRhZ2RlbGltID0gZmFsc2U7CisgIGYtPmlzX2V4dGVuc2lvbl8gPSBmYWxzZTsKKyAgZi0+bGF6eV8gPSBmYWxzZTsKKyAgZi0+cGFja2VkXyA9IHRydWU7CisKKyAgLy8gRm9yIHRoZSBtb21lbnQgd2UgZGVmYXVsdCB0aGlzIHRvIFVQQl9JTlRGTVRfVkFSSUFCTEUsIHNpbmNlIGl0IHdpbGwgd29yaworICAvLyB3aXRoIGFsbCBpbnRlZ2VyIHR5cGVzIGFuZCBpcyBpbiBzb21lIHNpbmNlIG1vcmUgImRlZmF1bHQiIHNpbmNlIHRoZSBtb3N0CisgIC8vIG5vcm1hbC1sb29raW5nIHByb3RvMiB0eXBlcyBpbnQzMi9pbnQ2NC91aW50MzIvdWludDY0IHVzZSB2YXJpYWJsZS4KKyAgLy8KKyAgLy8gT3RoZXIgb3B0aW9ucyB0byBjb25zaWRlcjoKKyAgLy8gLSB0aGVyZSBpcyBubyBkZWZhdWx0OyB1c2VycyBtdXN0IHNldCB0aGlzIG1hbnVhbGx5IChsaWtlIHR5cGUpLgorICAvLyAtIGRlZmF1bHQgc2lnbmVkIGludGVnZXJzIHRvIFVQQl9JTlRGTVRfWklHWkFHLCBzaW5jZSBpdCdzIG1vcmUgbGlrZWx5IHRvCisgIC8vICAgYmUgYW4gb3B0aW1hbCBkZWZhdWx0IGZvciBzaWduZWQgaW50ZWdlcnMuCisgIGYtPmludGZtdCA9IFVQQl9JTlRGTVRfVkFSSUFCTEU7CisgIHJldHVybiBmOworfQorCit1cGJfZmllbGRkZWYgKnVwYl9maWVsZGRlZl9kdXAoY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfZmllbGRkZWYgKm5ld2YgPSB1cGJfZmllbGRkZWZfbmV3KG93bmVyKTsKKyAgaWYgKCFuZXdmKSByZXR1cm4gTlVMTDsKKyAgdXBiX2ZpZWxkZGVmX3NldHR5cGUobmV3ZiwgdXBiX2ZpZWxkZGVmX3R5cGUoZikpOworICB1cGJfZmllbGRkZWZfc2V0bGFiZWwobmV3ZiwgdXBiX2ZpZWxkZGVmX2xhYmVsKGYpKTsKKyAgdXBiX2ZpZWxkZGVmX3NldG51bWJlcihuZXdmLCB1cGJfZmllbGRkZWZfbnVtYmVyKGYpLCBOVUxMKTsKKyAgdXBiX2ZpZWxkZGVmX3NldG5hbWUobmV3ZiwgdXBiX2ZpZWxkZGVmX25hbWUoZiksIE5VTEwpOworICBpZiAoZi0+ZGVmYXVsdF9pc19zdHJpbmcgJiYgZi0+ZGVmYXVsdHZhbC5ieXRlcykgeworICAgIHN0cl90ICpzID0gZi0+ZGVmYXVsdHZhbC5ieXRlczsKKyAgICB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdHN0cihuZXdmLCBzLT5zdHIsIHMtPmxlbiwgTlVMTCk7CisgIH0gZWxzZSB7CisgICAgbmV3Zi0+ZGVmYXVsdF9pc19zdHJpbmcgPSBmLT5kZWZhdWx0X2lzX3N0cmluZzsKKyAgICBuZXdmLT5kZWZhdWx0dmFsID0gZi0+ZGVmYXVsdHZhbDsKKyAgfQorCisgIGNvbnN0IGNoYXIgKnNyY25hbWU7CisgIGlmIChmLT5zdWJkZWZfaXNfc3ltYm9saWMpIHsKKyAgICBzcmNuYW1lID0gZi0+c3ViLm5hbWU7ICAvLyBNaWdodCBiZSBOVUxMLgorICB9IGVsc2UgeworICAgIHNyY25hbWUgPSBmLT5zdWIuZGVmID8gdXBiX2RlZl9mdWxsbmFtZShmLT5zdWIuZGVmKSA6IE5VTEw7CisgIH0KKyAgaWYgKHNyY25hbWUpIHsKKyAgICBjaGFyICpuZXduYW1lID0gbWFsbG9jKHN0cmxlbihmLT5zdWIuZGVmLT5mdWxsbmFtZSkgKyAyKTsKKyAgICBpZiAoIW5ld25hbWUpIHsKKyAgICAgIHVwYl9maWVsZGRlZl91bnJlZihuZXdmLCBvd25lcik7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc3RyY3B5KG5ld25hbWUsICIuIik7CisgICAgc3RyY2F0KG5ld25hbWUsIGYtPnN1Yi5kZWYtPmZ1bGxuYW1lKTsKKyAgICB1cGJfZmllbGRkZWZfc2V0c3ViZGVmbmFtZShuZXdmLCBuZXduYW1lLCBOVUxMKTsKKyAgICBmcmVlKG5ld25hbWUpOworICB9CisKKyAgcmV0dXJuIG5ld2Y7Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX2lzZnJvemVuKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICByZXR1cm4gdXBiX2RlZl9pc2Zyb3plbihVUEJfVVBDQVNUKGYpKTsKK30KKwordm9pZCB1cGJfZmllbGRkZWZfcmVmKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl9yZWYoVVBCX1VQQ0FTVChmKSwgb3duZXIpOworfQorCit2b2lkIHVwYl9maWVsZGRlZl91bnJlZihjb25zdCB1cGJfZmllbGRkZWYgKmYsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9kZWZfdW5yZWYoVVBCX1VQQ0FTVChmKSwgb3duZXIpOworfQorCit2b2lkIHVwYl9maWVsZGRlZl9kb25hdGVyZWYoCisgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0bykgeworICB1cGJfZGVmX2RvbmF0ZXJlZihVUEJfVVBDQVNUKGYpLCBmcm9tLCB0byk7Cit9CisKK3ZvaWQgdXBiX2ZpZWxkZGVmX2NoZWNrcmVmKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl9jaGVja3JlZihVUEJfVVBDQVNUKGYpLCBvd25lcik7Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX3R5cGVpc3NldChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIGYtPnR5cGVfaXNfc2V0XzsKK30KKwordXBiX2ZpZWxkdHlwZV90IHVwYl9maWVsZGRlZl90eXBlKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBhc3NlcnQoZi0+dHlwZV9pc19zZXRfKTsKKyAgcmV0dXJuIGYtPnR5cGVfOworfQorCit1aW50MzJfdCB1cGJfZmllbGRkZWZfaW5kZXgoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiBmLT5pbmRleF87Cit9CisKK3VwYl9sYWJlbF90IHVwYl9maWVsZGRlZl9sYWJlbChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIGYtPmxhYmVsXzsKK30KKwordXBiX2ludGZtdF90IHVwYl9maWVsZGRlZl9pbnRmbXQoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiBmLT5pbnRmbXQ7Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX2lzdGFnZGVsaW0oY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiBmLT50YWdkZWxpbTsKK30KKwordWludDMyX3QgdXBiX2ZpZWxkZGVmX251bWJlcihjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIGYtPm51bWJlcl87Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX2lzZXh0ZW5zaW9uKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICByZXR1cm4gZi0+aXNfZXh0ZW5zaW9uXzsKK30KKworYm9vbCB1cGJfZmllbGRkZWZfbGF6eShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIGYtPmxhenlfOworfQorCitib29sIHVwYl9maWVsZGRlZl9wYWNrZWQoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiBmLT5wYWNrZWRfOworfQorCitjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfbmFtZShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIHVwYl9kZWZfZnVsbG5hbWUoVVBCX1VQQ0FTVChmKSk7Cit9CisKK2NvbnN0IHVwYl9tc2dkZWYgKnVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIGYtPm1zZ19pc19zeW1ib2xpYyA/IE5VTEwgOiBmLT5tc2cuZGVmOworfQorCitjb25zdCB1cGJfb25lb2ZkZWYgKnVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiBmLT5vbmVvZjsKK30KKwordXBiX21zZ2RlZiAqdXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlX211dGFibGUodXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiAodXBiX21zZ2RlZiopdXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlKGYpOworfQorCitjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGVuYW1lKHVwYl9maWVsZGRlZiAqZikgeworICByZXR1cm4gZi0+bXNnX2lzX3N5bWJvbGljID8gZi0+bXNnLm5hbWUgOiBOVUxMOworfQorCitzdGF0aWMgdm9pZCByZWxlYXNlX2NvbnRhaW5pbmd0eXBlKHVwYl9maWVsZGRlZiAqZikgeworICBpZiAoZi0+bXNnX2lzX3N5bWJvbGljKSBmcmVlKGYtPm1zZy5uYW1lKTsKK30KKworYm9vbCB1cGJfZmllbGRkZWZfc2V0Y29udGFpbmluZ3R5cGVuYW1lKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgY2hhciAqbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKSB7CisgIGFzc2VydCghdXBiX2ZpZWxkZGVmX2lzZnJvemVuKGYpKTsKKyAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShmKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJmaWVsZCBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkIHRvIGEgbWVzc2FnZS4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgLy8gVE9ETzogdmFsaWRhdGUgbmFtZSAodXBiX2lzaWRlbnQoKSBkb2Vzbid0IHF1aXRlIHdvcmsgYXRtIGJlY2F1c2UgdGhpcyBuYW1lCisgIC8vIG1heSBoYXZlIGEgbGVhZGluZyAiLiIpLgorICByZWxlYXNlX2NvbnRhaW5pbmd0eXBlKGYpOworICBmLT5tc2cubmFtZSA9IHVwYl9zdHJkdXAobmFtZSk7CisgIGYtPm1zZ19pc19zeW1ib2xpYyA9IHRydWU7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9maWVsZGRlZl9zZXRuYW1lKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgY2hhciAqbmFtZSwgdXBiX3N0YXR1cyAqcykgeworICBpZiAodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlKGYpIHx8IHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZikpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiQWxyZWFkeSBhZGRlZCB0byBtZXNzYWdlIG9yIG9uZW9mIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB1cGJfZGVmX3NldGZ1bGxuYW1lKFVQQl9VUENBU1QoZiksIG5hbWUsIHMpOworfQorCitzdGF0aWMgdm9pZCBjaGtkZWZhdWx0dHlwZShjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9maWVsZHR5cGVfdCB0eXBlKSB7CisgIFVQQl9VTlVTRUQoZik7CisgIFVQQl9VTlVTRUQodHlwZSk7CisgIGFzc2VydChmLT50eXBlX2lzX3NldF8gJiYgdXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gdHlwZSk7Cit9CisKK2ludDY0X3QgdXBiX2ZpZWxkZGVmX2RlZmF1bHRpbnQ2NChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgY2hrZGVmYXVsdHR5cGUoZiwgVVBCX1RZUEVfSU5UNjQpOworICByZXR1cm4gZi0+ZGVmYXVsdHZhbC5zaW50OworfQorCitpbnQzMl90IHVwYl9maWVsZGRlZl9kZWZhdWx0aW50MzIoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIGlmIChmLT50eXBlX2lzX3NldF8gJiYgdXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfRU5VTSkgeworICAgIGludDMyX3QgdmFsOworICAgIGJvb2wgb2sgPSBlbnVtZGVmYXVsdGludDMyKGYsICZ2YWwpOworICAgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7CisgICAgcmV0dXJuIHZhbDsKKyAgfSBlbHNlIHsKKyAgICBjaGtkZWZhdWx0dHlwZShmLCBVUEJfVFlQRV9JTlQzMik7CisgICAgcmV0dXJuIGYtPmRlZmF1bHR2YWwuc2ludDsKKyAgfQorfQorCit1aW50NjRfdCB1cGJfZmllbGRkZWZfZGVmYXVsdHVpbnQ2NChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgY2hrZGVmYXVsdHR5cGUoZiwgVVBCX1RZUEVfVUlOVDY0KTsKKyAgcmV0dXJuIGYtPmRlZmF1bHR2YWwudWludDsKK30KKwordWludDMyX3QgdXBiX2ZpZWxkZGVmX2RlZmF1bHR1aW50MzIoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIGNoa2RlZmF1bHR0eXBlKGYsIFVQQl9UWVBFX1VJTlQzMik7CisgIHJldHVybiBmLT5kZWZhdWx0dmFsLnVpbnQ7Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX2RlZmF1bHRib29sKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBjaGtkZWZhdWx0dHlwZShmLCBVUEJfVFlQRV9CT09MKTsKKyAgcmV0dXJuIGYtPmRlZmF1bHR2YWwudWludDsKK30KKworZmxvYXQgdXBiX2ZpZWxkZGVmX2RlZmF1bHRmbG9hdChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgY2hrZGVmYXVsdHR5cGUoZiwgVVBCX1RZUEVfRkxPQVQpOworICByZXR1cm4gZi0+ZGVmYXVsdHZhbC5mbHQ7Cit9CisKK2RvdWJsZSB1cGJfZmllbGRkZWZfZGVmYXVsdGRvdWJsZShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgY2hrZGVmYXVsdHR5cGUoZiwgVVBCX1RZUEVfRE9VQkxFKTsKKyAgcmV0dXJuIGYtPmRlZmF1bHR2YWwuZGJsOworfQorCitjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfZGVmYXVsdHN0cihjb25zdCB1cGJfZmllbGRkZWYgKmYsIHNpemVfdCAqbGVuKSB7CisgIGFzc2VydChmLT50eXBlX2lzX3NldF8pOworICBhc3NlcnQodXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfU1RSSU5HIHx8CisgICAgICAgICB1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9CWVRFUyB8fAorICAgICAgICAgdXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfRU5VTSk7CisKKyAgaWYgKHVwYl9maWVsZGRlZl90eXBlKGYpID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICBjb25zdCBjaGFyICpyZXQgPSBlbnVtZGVmYXVsdHN0cihmKTsKKyAgICBhc3NlcnQocmV0KTsKKyAgICAvLyBFbnVtIGRlZmF1bHRzIGNhbid0IGhhdmUgZW1iZWRkZWQgTlVMTHMuCisgICAgaWYgKGxlbikgKmxlbiA9IHN0cmxlbihyZXQpOworICAgIHJldHVybiByZXQ7CisgIH0KKworICBpZiAoZi0+ZGVmYXVsdF9pc19zdHJpbmcpIHsKKyAgICBzdHJfdCAqc3RyID0gZi0+ZGVmYXVsdHZhbC5ieXRlczsKKyAgICBpZiAobGVuKSAqbGVuID0gc3RyLT5sZW47CisgICAgcmV0dXJuIHN0ci0+c3RyOworICB9CisKKyAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyB2b2lkIHVwYl9maWVsZGRlZl9pbml0X2RlZmF1bHQodXBiX2ZpZWxkZGVmICpmKSB7CisgIGYtPmRlZmF1bHRfaXNfc3RyaW5nID0gZmFsc2U7CisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUoZikpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0RPVUJMRTogZi0+ZGVmYXVsdHZhbC5kYmwgPSAwOyBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0ZMT0FUOiBmLT5kZWZhdWx0dmFsLmZsdCA9IDA7IGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDogZi0+ZGVmYXVsdHZhbC5zaW50ID0gMDsgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UNjQ6CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOiBmLT5kZWZhdWx0dmFsLnVpbnQgPSAwOyBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOgorICAgICAgZi0+ZGVmYXVsdHZhbC5ieXRlcyA9IG5ld3N0cigiIiwgMCk7CisgICAgICBmLT5kZWZhdWx0X2lzX3N0cmluZyA9IHRydWU7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX01FU1NBR0U6IGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfRU5VTToKKyAgICAgIC8vIFRoaXMgaXMgb3VyIHNwZWNpYWwgc2VudGluZWwgdGhhdCBpbmRpY2F0ZXMgIm5vdCBzZXQiIGZvciBhbiBlbnVtLgorICAgICAgZi0+ZGVmYXVsdF9pc19zdHJpbmcgPSB0cnVlOworICAgICAgZi0+ZGVmYXVsdHZhbC5ieXRlcyA9IE5VTEw7CisgICAgICBicmVhazsKKyAgfQorfQorCitjb25zdCB1cGJfZGVmICp1cGJfZmllbGRkZWZfc3ViZGVmKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICByZXR1cm4gZi0+c3ViZGVmX2lzX3N5bWJvbGljID8gTlVMTCA6IGYtPnN1Yi5kZWY7Cit9CisKK2NvbnN0IHVwYl9tc2dkZWYgKnVwYl9maWVsZGRlZl9tc2dzdWJkZWYoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIGNvbnN0IHVwYl9kZWYgKmRlZiA9IHVwYl9maWVsZGRlZl9zdWJkZWYoZik7CisgIHJldHVybiBkZWYgPyB1cGJfZHluY2FzdF9tc2dkZWYoZGVmKSA6IE5VTEw7Cit9CisKK2NvbnN0IHVwYl9lbnVtZGVmICp1cGJfZmllbGRkZWZfZW51bXN1YmRlZihjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgY29uc3QgdXBiX2RlZiAqZGVmID0gdXBiX2ZpZWxkZGVmX3N1YmRlZihmKTsKKyAgcmV0dXJuIGRlZiA/IHVwYl9keW5jYXN0X2VudW1kZWYoZGVmKSA6IE5VTEw7Cit9CisKK3VwYl9kZWYgKnVwYl9maWVsZGRlZl9zdWJkZWZfbXV0YWJsZSh1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuICh1cGJfZGVmKil1cGJfZmllbGRkZWZfc3ViZGVmKGYpOworfQorCitjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfc3ViZGVmbmFtZShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgaWYgKGYtPnN1YmRlZl9pc19zeW1ib2xpYykgeworICAgIHJldHVybiBmLT5zdWIubmFtZTsKKyAgfSBlbHNlIGlmIChmLT5zdWIuZGVmKSB7CisgICAgcmV0dXJuIHVwYl9kZWZfZnVsbG5hbWUoZi0+c3ViLmRlZik7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworYm9vbCB1cGJfZmllbGRkZWZfc2V0bnVtYmVyKHVwYl9maWVsZGRlZiAqZiwgdWludDMyX3QgbnVtYmVyLCB1cGJfc3RhdHVzICpzKSB7CisgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGUoZikpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZygKKyAgICAgICAgcywgImNhbm5vdCBjaGFuZ2UgZmllbGQgbnVtYmVyIGFmdGVyIGFkZGluZyB0byBhIG1lc3NhZ2UiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKG51bWJlciA9PSAwIHx8IG51bWJlciA+IFVQQl9NQVhfRklFTEROVU1CRVIpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycmYocywgImludmFsaWQgZmllbGQgbnVtYmVyICgldSkiLCBudW1iZXIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBmLT5udW1iZXJfID0gbnVtYmVyOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCB1cGJfZmllbGRkZWZfc2V0dHlwZSh1cGJfZmllbGRkZWYgKmYsIHVwYl9maWVsZHR5cGVfdCB0eXBlKSB7CisgIGFzc2VydCghdXBiX2ZpZWxkZGVmX2lzZnJvemVuKGYpKTsKKyAgYXNzZXJ0KHVwYl9maWVsZGRlZl9jaGVja3R5cGUodHlwZSkpOworICB1cGJfZmllbGRkZWZfdW5pbml0X2RlZmF1bHQoZik7CisgIGYtPnR5cGVfID0gdHlwZTsKKyAgZi0+dHlwZV9pc19zZXRfID0gdHJ1ZTsKKyAgdXBiX2ZpZWxkZGVmX2luaXRfZGVmYXVsdChmKTsKK30KKwordm9pZCB1cGJfZmllbGRkZWZfc2V0ZGVzY3JpcHRvcnR5cGUodXBiX2ZpZWxkZGVmICpmLCBpbnQgdHlwZSkgeworICBhc3NlcnQoIXVwYl9maWVsZGRlZl9pc2Zyb3plbihmKSk7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9ET1VCTEU6CisgICAgICB1cGJfZmllbGRkZWZfc2V0dHlwZShmLCBVUEJfVFlQRV9ET1VCTEUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfREVTQ1JJUFRPUl9UWVBFX0ZMT0FUOgorICAgICAgdXBiX2ZpZWxkZGVmX3NldHR5cGUoZiwgVVBCX1RZUEVfRkxPQVQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfREVTQ1JJUFRPUl9UWVBFX0lOVDY0OgorICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9TRklYRUQ2NDoKKyAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfU0lOVDY0OgorICAgICAgdXBiX2ZpZWxkZGVmX3NldHR5cGUoZiwgVVBCX1RZUEVfSU5UNjQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfREVTQ1JJUFRPUl9UWVBFX1VJTlQ2NDoKKyAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfRklYRUQ2NDoKKyAgICAgIHVwYl9maWVsZGRlZl9zZXR0eXBlKGYsIFVQQl9UWVBFX1VJTlQ2NCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfSU5UMzI6CisgICAgY2FzZSBVUEJfREVTQ1JJUFRPUl9UWVBFX1NGSVhFRDMyOgorICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9TSU5UMzI6CisgICAgICB1cGJfZmllbGRkZWZfc2V0dHlwZShmLCBVUEJfVFlQRV9JTlQzMik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfVUlOVDMyOgorICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9GSVhFRDMyOgorICAgICAgdXBiX2ZpZWxkZGVmX3NldHR5cGUoZiwgVVBCX1RZUEVfVUlOVDMyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9CT09MOgorICAgICAgdXBiX2ZpZWxkZGVmX3NldHR5cGUoZiwgVVBCX1RZUEVfQk9PTCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfU1RSSU5HOgorICAgICAgdXBiX2ZpZWxkZGVmX3NldHR5cGUoZiwgVVBCX1RZUEVfU1RSSU5HKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9CWVRFUzoKKyAgICAgIHVwYl9maWVsZGRlZl9zZXR0eXBlKGYsIFVQQl9UWVBFX0JZVEVTKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9HUk9VUDoKKyAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfTUVTU0FHRToKKyAgICAgIHVwYl9maWVsZGRlZl9zZXR0eXBlKGYsIFVQQl9UWVBFX01FU1NBR0UpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfREVTQ1JJUFRPUl9UWVBFX0VOVU06CisgICAgICB1cGJfZmllbGRkZWZfc2V0dHlwZShmLCBVUEJfVFlQRV9FTlVNKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6IGFzc2VydChmYWxzZSk7CisgIH0KKworICBpZiAodHlwZSA9PSBVUEJfREVTQ1JJUFRPUl9UWVBFX0ZJWEVENjQgfHwKKyAgICAgIHR5cGUgPT0gVVBCX0RFU0NSSVBUT1JfVFlQRV9GSVhFRDMyIHx8CisgICAgICB0eXBlID09IFVQQl9ERVNDUklQVE9SX1RZUEVfU0ZJWEVENjQgfHwKKyAgICAgIHR5cGUgPT0gVVBCX0RFU0NSSVBUT1JfVFlQRV9TRklYRUQzMikgeworICAgIHVwYl9maWVsZGRlZl9zZXRpbnRmbXQoZiwgVVBCX0lOVEZNVF9GSVhFRCk7CisgIH0gZWxzZSBpZiAodHlwZSA9PSBVUEJfREVTQ1JJUFRPUl9UWVBFX1NJTlQ2NCB8fAorICAgICAgICAgICAgIHR5cGUgPT0gVVBCX0RFU0NSSVBUT1JfVFlQRV9TSU5UMzIpIHsKKyAgICB1cGJfZmllbGRkZWZfc2V0aW50Zm10KGYsIFVQQl9JTlRGTVRfWklHWkFHKTsKKyAgfSBlbHNlIHsKKyAgICB1cGJfZmllbGRkZWZfc2V0aW50Zm10KGYsIFVQQl9JTlRGTVRfVkFSSUFCTEUpOworICB9CisKKyAgdXBiX2ZpZWxkZGVmX3NldHRhZ2RlbGltKGYsIHR5cGUgPT0gVVBCX0RFU0NSSVBUT1JfVFlQRV9HUk9VUCk7Cit9CisKK3VwYl9kZXNjcmlwdG9ydHlwZV90IHVwYl9maWVsZGRlZl9kZXNjcmlwdG9ydHlwZShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgc3dpdGNoICh1cGJfZmllbGRkZWZfdHlwZShmKSkgeworICAgIGNhc2UgVVBCX1RZUEVfRkxPQVQ6ICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9GTE9BVDsKKyAgICBjYXNlIFVQQl9UWVBFX0RPVUJMRTogcmV0dXJuIFVQQl9ERVNDUklQVE9SX1RZUEVfRE9VQkxFOworICAgIGNhc2UgVVBCX1RZUEVfQk9PTDogICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9CT09MOworICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOiByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9TVFJJTkc7CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzogIHJldHVybiBVUEJfREVTQ1JJUFRPUl9UWVBFX0JZVEVTOworICAgIGNhc2UgVVBCX1RZUEVfRU5VTTogICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9FTlVNOworICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6CisgICAgICBzd2l0Y2ggKHVwYl9maWVsZGRlZl9pbnRmbXQoZikpIHsKKyAgICAgICAgY2FzZSBVUEJfSU5URk1UX1ZBUklBQkxFOiByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9JTlQzMjsKKyAgICAgICAgY2FzZSBVUEJfSU5URk1UX0ZJWEVEOiAgICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9TRklYRUQzMjsKKyAgICAgICAgY2FzZSBVUEJfSU5URk1UX1pJR1pBRzogICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9TSU5UMzI7CisgICAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDoKKyAgICAgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX2ludGZtdChmKSkgeworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfVkFSSUFCTEU6IHJldHVybiBVUEJfREVTQ1JJUFRPUl9UWVBFX0lOVDY0OworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfRklYRUQ6ICAgIHJldHVybiBVUEJfREVTQ1JJUFRPUl9UWVBFX1NGSVhFRDY0OworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfWklHWkFHOiAgIHJldHVybiBVUEJfREVTQ1JJUFRPUl9UWVBFX1NJTlQ2NDsKKyAgICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjoKKyAgICAgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX2ludGZtdChmKSkgeworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfVkFSSUFCTEU6IHJldHVybiBVUEJfREVTQ1JJUFRPUl9UWVBFX1VJTlQzMjsKKyAgICAgICAgY2FzZSBVUEJfSU5URk1UX0ZJWEVEOiAgICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9GSVhFRDMyOworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfWklHWkFHOiAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDoKKyAgICAgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX2ludGZtdChmKSkgeworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfVkFSSUFCTEU6IHJldHVybiBVUEJfREVTQ1JJUFRPUl9UWVBFX1VJTlQ2NDsKKyAgICAgICAgY2FzZSBVUEJfSU5URk1UX0ZJWEVEOiAgICByZXR1cm4gVVBCX0RFU0NSSVBUT1JfVFlQRV9GSVhFRDY0OworICAgICAgICBjYXNlIFVQQl9JTlRGTVRfWklHWkFHOiAgIHJldHVybiAtMTsKKyAgICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gdXBiX2ZpZWxkZGVmX2lzdGFnZGVsaW0oZikgPworICAgICAgICAgIFVQQl9ERVNDUklQVE9SX1RZUEVfR1JPVVAgOiBVUEJfREVTQ1JJUFRPUl9UWVBFX01FU1NBR0U7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldGlzZXh0ZW5zaW9uKHVwYl9maWVsZGRlZiAqZiwgYm9vbCBpc19leHRlbnNpb24pIHsKKyAgYXNzZXJ0KCF1cGJfZmllbGRkZWZfaXNmcm96ZW4oZikpOworICBmLT5pc19leHRlbnNpb25fID0gaXNfZXh0ZW5zaW9uOworfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRsYXp5KHVwYl9maWVsZGRlZiAqZiwgYm9vbCBsYXp5KSB7CisgIGFzc2VydCghdXBiX2ZpZWxkZGVmX2lzZnJvemVuKGYpKTsKKyAgZi0+bGF6eV8gPSBsYXp5OworfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRwYWNrZWQodXBiX2ZpZWxkZGVmICpmLCBib29sIHBhY2tlZCkgeworICBhc3NlcnQoIXVwYl9maWVsZGRlZl9pc2Zyb3plbihmKSk7CisgIGYtPnBhY2tlZF8gPSBwYWNrZWQ7Cit9CisKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldGxhYmVsKHVwYl9maWVsZGRlZiAqZiwgdXBiX2xhYmVsX3QgbGFiZWwpIHsKKyAgYXNzZXJ0KCF1cGJfZmllbGRkZWZfaXNmcm96ZW4oZikpOworICBhc3NlcnQodXBiX2ZpZWxkZGVmX2NoZWNrbGFiZWwobGFiZWwpKTsKKyAgZi0+bGFiZWxfID0gbGFiZWw7Cit9CisKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldGludGZtdCh1cGJfZmllbGRkZWYgKmYsIHVwYl9pbnRmbXRfdCBmbXQpIHsKKyAgYXNzZXJ0KCF1cGJfZmllbGRkZWZfaXNmcm96ZW4oZikpOworICBhc3NlcnQodXBiX2ZpZWxkZGVmX2NoZWNraW50Zm10KGZtdCkpOworICBmLT5pbnRmbXQgPSBmbXQ7Cit9CisKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldHRhZ2RlbGltKHVwYl9maWVsZGRlZiAqZiwgYm9vbCB0YWdfZGVsaW0pIHsKKyAgYXNzZXJ0KCF1cGJfZmllbGRkZWZfaXNmcm96ZW4oZikpOworICBmLT50YWdkZWxpbSA9IHRhZ19kZWxpbTsKKyAgZi0+dGFnZGVsaW0gPSB0YWdfZGVsaW07Cit9CisKK3N0YXRpYyBib29sIGNoZWNrc2V0ZGVmYXVsdCh1cGJfZmllbGRkZWYgKmYsIHVwYl9maWVsZHR5cGVfdCB0eXBlKSB7CisgIGlmICghZi0+dHlwZV9pc19zZXRfIHx8IHVwYl9maWVsZGRlZl9pc2Zyb3plbihmKSB8fAorICAgICAgdXBiX2ZpZWxkZGVmX3R5cGUoZikgIT0gdHlwZSkgeworICAgIGFzc2VydChmYWxzZSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChmLT5kZWZhdWx0X2lzX3N0cmluZykgeworICAgIHN0cl90ICpzID0gZi0+ZGVmYXVsdHZhbC5ieXRlczsKKyAgICBhc3NlcnQocyB8fCB0eXBlID09IFVQQl9UWVBFX0VOVU0pOworICAgIGlmIChzKSBmcmVlc3RyKHMpOworICB9CisgIGYtPmRlZmF1bHRfaXNfc3RyaW5nID0gZmFsc2U7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0aW50NjQodXBiX2ZpZWxkZGVmICpmLCBpbnQ2NF90IHZhbHVlKSB7CisgIGlmIChjaGVja3NldGRlZmF1bHQoZiwgVVBCX1RZUEVfSU5UNjQpKQorICAgIGYtPmRlZmF1bHR2YWwuc2ludCA9IHZhbHVlOworfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0aW50MzIodXBiX2ZpZWxkZGVmICpmLCBpbnQzMl90IHZhbHVlKSB7CisgIGlmICgodXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfRU5VTSAmJgorICAgICAgIGNoZWNrc2V0ZGVmYXVsdChmLCBVUEJfVFlQRV9FTlVNKSkgfHwKKyAgICAgIGNoZWNrc2V0ZGVmYXVsdChmLCBVUEJfVFlQRV9JTlQzMikpIHsKKyAgICBmLT5kZWZhdWx0dmFsLnNpbnQgPSB2YWx1ZTsKKyAgfQorfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0dWludDY0KHVwYl9maWVsZGRlZiAqZiwgdWludDY0X3QgdmFsdWUpIHsKKyAgaWYgKGNoZWNrc2V0ZGVmYXVsdChmLCBVUEJfVFlQRV9VSU5UNjQpKQorICAgIGYtPmRlZmF1bHR2YWwudWludCA9IHZhbHVlOworfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0dWludDMyKHVwYl9maWVsZGRlZiAqZiwgdWludDMyX3QgdmFsdWUpIHsKKyAgaWYgKGNoZWNrc2V0ZGVmYXVsdChmLCBVUEJfVFlQRV9VSU5UMzIpKQorICAgIGYtPmRlZmF1bHR2YWwudWludCA9IHZhbHVlOworfQorCit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0Ym9vbCh1cGJfZmllbGRkZWYgKmYsIGJvb2wgdmFsdWUpIHsKKyAgaWYgKGNoZWNrc2V0ZGVmYXVsdChmLCBVUEJfVFlQRV9CT09MKSkKKyAgICBmLT5kZWZhdWx0dmFsLnVpbnQgPSB2YWx1ZTsKK30KKwordm9pZCB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdGZsb2F0KHVwYl9maWVsZGRlZiAqZiwgZmxvYXQgdmFsdWUpIHsKKyAgaWYgKGNoZWNrc2V0ZGVmYXVsdChmLCBVUEJfVFlQRV9GTE9BVCkpCisgICAgZi0+ZGVmYXVsdHZhbC5mbHQgPSB2YWx1ZTsKK30KKwordm9pZCB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdGRvdWJsZSh1cGJfZmllbGRkZWYgKmYsIGRvdWJsZSB2YWx1ZSkgeworICBpZiAoY2hlY2tzZXRkZWZhdWx0KGYsIFVQQl9UWVBFX0RPVUJMRSkpCisgICAgZi0+ZGVmYXVsdHZhbC5kYmwgPSB2YWx1ZTsKK30KKworYm9vbCB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdHN0cih1cGJfZmllbGRkZWYgKmYsIGNvbnN0IHZvaWQgKnN0ciwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcykgeworICBhc3NlcnQodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGYpIHx8IGYtPnR5cGVfID09IFVQQl9UWVBFX0VOVU0pOworICBpZiAoZi0+dHlwZV8gPT0gVVBCX1RZUEVfRU5VTSAmJiAhdXBiX2lzaWRlbnQoc3RyLCBsZW4sIGZhbHNlLCBzKSkKKyAgICByZXR1cm4gZmFsc2U7CisKKyAgaWYgKGYtPmRlZmF1bHRfaXNfc3RyaW5nKSB7CisgICAgc3RyX3QgKnMgPSBmLT5kZWZhdWx0dmFsLmJ5dGVzOworICAgIGFzc2VydChzIHx8IGYtPnR5cGVfID09IFVQQl9UWVBFX0VOVU0pOworICAgIGlmIChzKSBmcmVlc3RyKHMpOworICB9IGVsc2UgeworICAgIGFzc2VydChmLT50eXBlXyA9PSBVUEJfVFlQRV9FTlVNKTsKKyAgfQorCisgIHN0cl90ICpzdHIyID0gbmV3c3RyKHN0ciwgbGVuKTsKKyAgZi0+ZGVmYXVsdHZhbC5ieXRlcyA9IHN0cjI7CisgIGYtPmRlZmF1bHRfaXNfc3RyaW5nID0gdHJ1ZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRjc3RyKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgY2hhciAqc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcykgeworICBhc3NlcnQoZi0+dHlwZV9pc19zZXRfKTsKKyAgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRzdHIoZiwgc3RyLCBzdHIgPyBzdHJsZW4oc3RyKSA6IDAsIHMpOworfQorCitib29sIHVwYl9maWVsZGRlZl9lbnVtaGFzZGVmYXVsdGludDMyKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBhc3NlcnQoZi0+dHlwZV9pc19zZXRfICYmIGYtPnR5cGVfID09IFVQQl9UWVBFX0VOVU0pOworICBpbnQzMl90IHZhbDsKKyAgcmV0dXJuIGVudW1kZWZhdWx0aW50MzIoZiwgJnZhbCk7Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX2VudW1oYXNkZWZhdWx0c3RyKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBhc3NlcnQoZi0+dHlwZV9pc19zZXRfICYmIGYtPnR5cGVfID09IFVQQl9UWVBFX0VOVU0pOworICByZXR1cm4gZW51bWRlZmF1bHRzdHIoZikgIT0gTlVMTDsKK30KKworc3RhdGljIGJvb2wgdXBiX3N1YmRlZl90eXBlY2hlY2sodXBiX2ZpZWxkZGVmICpmLCBjb25zdCB1cGJfZGVmICpzdWJkZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKSB7CisgIGlmIChmLT50eXBlXyA9PSBVUEJfVFlQRV9NRVNTQUdFKSB7CisgICAgaWYgKHVwYl9keW5jYXN0X21zZ2RlZihzdWJkZWYpKSByZXR1cm4gdHJ1ZTsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiaW52YWxpZCBzdWJkZWYgdHlwZSBmb3IgdGhpcyBzdWJtZXNzYWdlIGZpZWxkIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgaWYgKGYtPnR5cGVfID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICBpZiAodXBiX2R5bmNhc3RfZW51bWRlZihzdWJkZWYpKSByZXR1cm4gdHJ1ZTsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiaW52YWxpZCBzdWJkZWYgdHlwZSBmb3IgdGhpcyBlbnVtIGZpZWxkIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJvbmx5IG1lc3NhZ2UgYW5kIGVudW0gZmllbGRzIGNhbiBoYXZlIGEgc3ViZGVmIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK3N0YXRpYyB2b2lkIHJlbGVhc2Vfc3ViZGVmKHVwYl9maWVsZGRlZiAqZikgeworICBpZiAoZi0+c3ViZGVmX2lzX3N5bWJvbGljKSB7CisgICAgZnJlZShmLT5zdWIubmFtZSk7CisgIH0gZWxzZSBpZiAoZi0+c3ViLmRlZikgeworICAgIHVwYl91bnJlZjIoZi0+c3ViLmRlZiwgZik7CisgIH0KK30KKworYm9vbCB1cGJfZmllbGRkZWZfc2V0c3ViZGVmKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgdXBiX2RlZiAqc3ViZGVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpIHsKKyAgYXNzZXJ0KCF1cGJfZmllbGRkZWZfaXNmcm96ZW4oZikpOworICBhc3NlcnQodXBiX2ZpZWxkZGVmX2hhc3N1YmRlZihmKSk7CisgIGlmIChzdWJkZWYgJiYgIXVwYl9zdWJkZWZfdHlwZWNoZWNrKGYsIHN1YmRlZiwgcykpIHJldHVybiBmYWxzZTsKKyAgcmVsZWFzZV9zdWJkZWYoZik7CisgIGYtPnN1Yi5kZWYgPSBzdWJkZWY7CisgIGYtPnN1YmRlZl9pc19zeW1ib2xpYyA9IGZhbHNlOworICBpZiAoZi0+c3ViLmRlZikgdXBiX3JlZjIoZi0+c3ViLmRlZiwgZik7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9maWVsZGRlZl9zZXRtc2dzdWJkZWYodXBiX2ZpZWxkZGVmICpmLCBjb25zdCB1cGJfbXNnZGVmICpzdWJkZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldHN1YmRlZihmLCBVUEJfVVBDQVNUKHN1YmRlZiksIHMpOworfQorCitib29sIHVwYl9maWVsZGRlZl9zZXRlbnVtc3ViZGVmKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgdXBiX2VudW1kZWYgKnN1YmRlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldHN1YmRlZihmLCBVUEJfVVBDQVNUKHN1YmRlZiksIHMpOworfQorCitib29sIHVwYl9maWVsZGRlZl9zZXRzdWJkZWZuYW1lKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgY2hhciAqbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcykgeworICBhc3NlcnQoIXVwYl9maWVsZGRlZl9pc2Zyb3plbihmKSk7CisgIGlmICghdXBiX2ZpZWxkZGVmX2hhc3N1YmRlZihmKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJmaWVsZCB0eXBlIGRvZXMgbm90IGFjY2VwdCBhIHN1YmRlZiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAvLyBUT0RPOiB2YWxpZGF0ZSBuYW1lICh1cGJfaXNpZGVudCgpIGRvZXNuJ3QgcXVpdGUgd29yayBhdG0gYmVjYXVzZSB0aGlzIG5hbWUKKyAgLy8gbWF5IGhhdmUgYSBsZWFkaW5nICIuIikuCisgIHJlbGVhc2Vfc3ViZGVmKGYpOworICBmLT5zdWIubmFtZSA9IHVwYl9zdHJkdXAobmFtZSk7CisgIGYtPnN1YmRlZl9pc19zeW1ib2xpYyA9IHRydWU7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9maWVsZGRlZl9pc3N1Ym1zZyhjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl90eXBlKGYpID09IFVQQl9UWVBFX01FU1NBR0U7Cit9CisKK2Jvb2wgdXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfU1RSSU5HIHx8CisgICAgICAgICB1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9CWVRFUzsKK30KKworYm9vbCB1cGJfZmllbGRkZWZfaXNzZXEoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfbGFiZWwoZikgPT0gVVBCX0xBQkVMX1JFUEVBVEVEOworfQorCitib29sIHVwYl9maWVsZGRlZl9pc3ByaW1pdGl2ZShjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuICF1cGJfZmllbGRkZWZfaXNzdHJpbmcoZikgJiYgIXVwYl9maWVsZGRlZl9pc3N1Ym1zZyhmKTsKK30KKworYm9vbCB1cGJfZmllbGRkZWZfaXNtYXAoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfaXNzZXEoZikgJiYgdXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpICYmCisgICAgICAgICB1cGJfbXNnZGVmX21hcGVudHJ5KHVwYl9maWVsZGRlZl9tc2dzdWJkZWYoZikpOworfQorCitib29sIHVwYl9maWVsZGRlZl9oYXNzdWJkZWYoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfaXNzdWJtc2coZikgfHwgdXBiX2ZpZWxkZGVmX3R5cGUoZikgPT0gVVBCX1RZUEVfRU5VTTsKK30KKworc3RhdGljIGJvb2wgYmV0d2VlbihpbnQzMl90IHgsIGludDMyX3QgbG93LCBpbnQzMl90IGhpZ2gpIHsKKyAgcmV0dXJuIHggPj0gbG93ICYmIHggPD0gaGlnaDsKK30KKworYm9vbCB1cGJfZmllbGRkZWZfY2hlY2tsYWJlbChpbnQzMl90IGxhYmVsKSB7IHJldHVybiBiZXR3ZWVuKGxhYmVsLCAxLCAzKTsgfQorYm9vbCB1cGJfZmllbGRkZWZfY2hlY2t0eXBlKGludDMyX3QgdHlwZSkgeyByZXR1cm4gYmV0d2Vlbih0eXBlLCAxLCAxMSk7IH0KK2Jvb2wgdXBiX2ZpZWxkZGVmX2NoZWNraW50Zm10KGludDMyX3QgZm10KSB7IHJldHVybiBiZXR3ZWVuKGZtdCwgMSwgMyk7IH0KKworYm9vbCB1cGJfZmllbGRkZWZfY2hlY2tkZXNjcmlwdG9ydHlwZShpbnQzMl90IHR5cGUpIHsKKyAgcmV0dXJuIGJldHdlZW4odHlwZSwgMSwgMTgpOworfQorCisvKiB1cGJfbXNnZGVmICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgdm9pZCB2aXNpdG1zZyhjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWRfdmlzaXQgKnZpc2l0LAorICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gKGNvbnN0IHVwYl9tc2dkZWYqKXI7CisgIHVwYl9tc2dfZmllbGRfaXRlciBpOworICBmb3IodXBiX21zZ19maWVsZF9iZWdpbigmaSwgbSk7CisgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpKTsKKyAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaSkpIHsKKyAgICB1cGJfZmllbGRkZWYgKmYgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJmkpOworICAgIHZpc2l0KHIsIFVQQl9VUENBU1QyKGYpLCBjbG9zdXJlKTsKKyAgfQorICB1cGJfbXNnX29uZW9mX2l0ZXIgbzsKKyAgZm9yKHVwYl9tc2dfb25lb2ZfYmVnaW4oJm8sIG0pOworICAgICAgIXVwYl9tc2dfb25lb2ZfZG9uZSgmbyk7CisgICAgICB1cGJfbXNnX29uZW9mX25leHQoJm8pKSB7CisgICAgdXBiX29uZW9mZGVmICpmID0gdXBiX21zZ19pdGVyX29uZW9mKCZvKTsKKyAgICB2aXNpdChyLCBVUEJfVVBDQVNUMihmKSwgY2xvc3VyZSk7CisgIH0KK30KKworc3RhdGljIHZvaWQgZnJlZW1zZyh1cGJfcmVmY291bnRlZCAqcikgeworICB1cGJfbXNnZGVmICptID0gKHVwYl9tc2dkZWYqKXI7CisgIHVwYl9zdHJ0YWJsZV91bmluaXQoJm0tPm50b28pOworICB1cGJfc3RydGFibGVfdW5pbml0KCZtLT5udG9mKTsKKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmbS0+aXRvZik7CisgIHVwYl9kZWZfdW5pbml0KFVQQl9VUENBU1QobSkpOworICBmcmVlKG0pOworfQorCit1cGJfbXNnZGVmICp1cGJfbXNnZGVmX25ldyhjb25zdCB2b2lkICpvd25lcikgeworICBzdGF0aWMgY29uc3Qgc3RydWN0IHVwYl9yZWZjb3VudGVkX3Z0YmwgdnRibCA9IHt2aXNpdG1zZywgZnJlZW1zZ307CisgIHVwYl9tc2dkZWYgKm0gPSBtYWxsb2Moc2l6ZW9mKCptKSk7CisgIGlmICghbSkgcmV0dXJuIE5VTEw7CisgIGlmICghdXBiX2RlZl9pbml0KFVQQl9VUENBU1QobSksIFVQQl9ERUZfTVNHLCAmdnRibCwgb3duZXIpKSBnb3RvIGVycjI7CisgIGlmICghdXBiX2ludHRhYmxlX2luaXQoJm0tPml0b2YsIFVQQl9DVFlQRV9QVFIpKSBnb3RvIGVycjM7CisgIGlmICghdXBiX3N0cnRhYmxlX2luaXQoJm0tPm50b2YsIFVQQl9DVFlQRV9QVFIpKSBnb3RvIGVycjI7CisgIGlmICghdXBiX3N0cnRhYmxlX2luaXQoJm0tPm50b28sIFVQQl9DVFlQRV9QVFIpKSBnb3RvIGVycjE7CisgIG0tPm1hcF9lbnRyeSA9IGZhbHNlOworICByZXR1cm4gbTsKKworZXJyMToKKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmbS0+bnRvZik7CitlcnIyOgorICB1cGJfaW50dGFibGVfdW5pbml0KCZtLT5pdG9mKTsKK2VycjM6CisgIGZyZWUobSk7CisgIHJldHVybiBOVUxMOworfQorCit1cGJfbXNnZGVmICp1cGJfbXNnZGVmX2R1cChjb25zdCB1cGJfbXNnZGVmICptLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfbXNnZGVmICpuZXdtID0gdXBiX21zZ2RlZl9uZXcob3duZXIpOworICBpZiAoIW5ld20pIHJldHVybiBOVUxMOworICBib29sIG9rID0gdXBiX2RlZl9zZXRmdWxsbmFtZShVUEJfVVBDQVNUKG5ld20pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfZGVmX2Z1bGxuYW1lKFVQQl9VUENBU1QobSkpLCBOVUxMKTsKKyAgbmV3bS0+bWFwX2VudHJ5ID0gbS0+bWFwX2VudHJ5OworICBVUEJfQVNTRVJUX1ZBUihvaywgb2spOworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmksIG0pOworICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaSk7CisgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX2ZpZWxkZGVmX2R1cCh1cGJfbXNnX2l0ZXJfZmllbGQoJmkpLCAmZik7CisgICAgLy8gRmllbGRzIGluIG9uZW9mcyBhcmUgZHVwJ2QgYmVsb3cuCisgICAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZikpIGNvbnRpbnVlOworICAgIGlmICghZiB8fCAhdXBiX21zZ2RlZl9hZGRmaWVsZChuZXdtLCBmLCAmZiwgTlVMTCkpIHsKKyAgICAgIHVwYl9tc2dkZWZfdW5yZWYobmV3bSwgb3duZXIpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisgIHVwYl9tc2dfb25lb2ZfaXRlciBvOworICBmb3IodXBiX21zZ19vbmVvZl9iZWdpbigmbywgbSk7CisgICAgICAhdXBiX21zZ19vbmVvZl9kb25lKCZvKTsKKyAgICAgIHVwYl9tc2dfb25lb2ZfbmV4dCgmbykpIHsKKyAgICB1cGJfb25lb2ZkZWYgKmYgPSB1cGJfb25lb2ZkZWZfZHVwKHVwYl9tc2dfaXRlcl9vbmVvZigmbyksICZmKTsKKyAgICBpZiAoIWYgfHwgIXVwYl9tc2dkZWZfYWRkb25lb2YobmV3bSwgZiwgJmYsIE5VTEwpKSB7CisgICAgICB1cGJfbXNnZGVmX3VucmVmKG5ld20sIG93bmVyKTsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgfQorICByZXR1cm4gbmV3bTsKK30KKworYm9vbCB1cGJfbXNnZGVmX2lzZnJvemVuKGNvbnN0IHVwYl9tc2dkZWYgKm0pIHsKKyAgcmV0dXJuIHVwYl9kZWZfaXNmcm96ZW4oVVBCX1VQQ0FTVChtKSk7Cit9CisKK3ZvaWQgdXBiX21zZ2RlZl9yZWYoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl9yZWYoVVBCX1VQQ0FTVChtKSwgb3duZXIpOworfQorCit2b2lkIHVwYl9tc2dkZWZfdW5yZWYoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl91bnJlZihVUEJfVVBDQVNUKG0pLCBvd25lcik7Cit9CisKK3ZvaWQgdXBiX21zZ2RlZl9kb25hdGVyZWYoCisgICAgY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqZnJvbSwgY29uc3Qgdm9pZCAqdG8pIHsKKyAgdXBiX2RlZl9kb25hdGVyZWYoVVBCX1VQQ0FTVChtKSwgZnJvbSwgdG8pOworfQorCit2b2lkIHVwYl9tc2dkZWZfY2hlY2tyZWYoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX2RlZl9jaGVja3JlZihVUEJfVVBDQVNUKG0pLCBvd25lcik7Cit9CisKK2Jvb2wgdXBiX21zZ2RlZl9mcmVlemUodXBiX21zZ2RlZiAqbSwgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIHVwYl9kZWYgKmQgPSBVUEJfVVBDQVNUKG0pOworICByZXR1cm4gdXBiX2RlZl9mcmVlemUoJmQsIDEsIHN0YXR1cyk7Cit9CisKK2NvbnN0IGNoYXIgKnVwYl9tc2dkZWZfZnVsbG5hbWUoY29uc3QgdXBiX21zZ2RlZiAqbSkgeworICByZXR1cm4gdXBiX2RlZl9mdWxsbmFtZShVUEJfVVBDQVNUKG0pKTsKK30KKworYm9vbCB1cGJfbXNnZGVmX3NldGZ1bGxuYW1lKHVwYl9tc2dkZWYgKm0sIGNvbnN0IGNoYXIgKmZ1bGxuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpIHsKKyAgcmV0dXJuIHVwYl9kZWZfc2V0ZnVsbG5hbWUoVVBCX1VQQ0FTVChtKSwgZnVsbG5hbWUsIHMpOworfQorCisvLyBIZWxwZXI6IGNoZWNrIHRoYXQgdGhlIGZpZWxkIHxmfCBpcyBzYWZlIHRvIGFkZCB0byBtc2dkZWYgfG18LiBTZXQgYW4gZXJyb3IKKy8vIG9uIHN0YXR1cyB8c3wgYW5kIHJldHVybiBmYWxzZSBpZiBub3QuCitzdGF0aWMgYm9vbCBjaGVja19maWVsZF9hZGQoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpIHsKKyAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShmKSAhPSBOVUxMKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgImZpZWxkZGVmIGFscmVhZHkgYmVsb25ncyB0byBhIG1lc3NhZ2UiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSBpZiAodXBiX2ZpZWxkZGVmX25hbWUoZikgPT0gTlVMTCB8fCB1cGJfZmllbGRkZWZfbnVtYmVyKGYpID09IDApIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiZmllbGQgbmFtZSBvciBudW1iZXIgd2VyZSBub3Qgc2V0Iik7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgaWYgKHVwYl9tc2dkZWZfbnRvZnoobSwgdXBiX2ZpZWxkZGVmX25hbWUoZikpIHx8CisgICAgICAgICAgICAgdXBiX21zZ2RlZl9pdG9mKG0sIHVwYl9maWVsZGRlZl9udW1iZXIoZikpKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgImR1cGxpY2F0ZSBmaWVsZCBuYW1lIG9yIG51bWJlciBmb3IgZmllbGQiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB2b2lkIGFkZF9maWVsZCh1cGJfbXNnZGVmICptLCB1cGJfZmllbGRkZWYgKmYsIGNvbnN0IHZvaWQgKnJlZl9kb25vcikgeworICByZWxlYXNlX2NvbnRhaW5pbmd0eXBlKGYpOworICBmLT5tc2cuZGVmID0gbTsKKyAgZi0+bXNnX2lzX3N5bWJvbGljID0gZmFsc2U7CisgIHVwYl9pbnR0YWJsZV9pbnNlcnQoJm0tPml0b2YsIHVwYl9maWVsZGRlZl9udW1iZXIoZiksIHVwYl92YWx1ZV9wdHIoZikpOworICB1cGJfc3RydGFibGVfaW5zZXJ0KCZtLT5udG9mLCB1cGJfZmllbGRkZWZfbmFtZShmKSwgdXBiX3ZhbHVlX3B0cihmKSk7CisgIHVwYl9yZWYyKGYsIG0pOworICB1cGJfcmVmMihtLCBmKTsKKyAgaWYgKHJlZl9kb25vcikgdXBiX2ZpZWxkZGVmX3VucmVmKGYsIHJlZl9kb25vcik7Cit9CisKK2Jvb2wgdXBiX21zZ2RlZl9hZGRmaWVsZCh1cGJfbXNnZGVmICptLCB1cGJfZmllbGRkZWYgKmYsIGNvbnN0IHZvaWQgKnJlZl9kb25vciwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKSB7CisgIC8vIFRPRE86IGV4dGVuc2lvbnMgbmVlZCB0byBoYXZlIGEgc2VwYXJhdGUgbmFtZXNwYWNlLCBiZWNhdXNlIHByb3RvMiBhbGxvd3MgYQorICAvLyB0b3AtbGV2ZWwgZXh0ZW5zaW9uIChpZS4gb25lIG5vdCBpbiBhbnkgcGFja2FnZSkgdG8gaGF2ZSB0aGUgc2FtZSBuYW1lIGFzIGEKKyAgLy8gZmllbGQgZnJvbSB0aGUgbWVzc2FnZS4KKyAgLy8KKyAgLy8gVGhpcyBhbHNvIGltcGxpZXMgdGhhdCB0aGVyZSBuZWVkcyB0byBiZSBhIHNlcGFyYXRlIGxvb2t1cC1ieS1uYW1lIG1ldGhvZAorICAvLyBmb3IgZXh0ZW5zaW9ucy4gIEl0IHNlZW1zIGRlc2lyYWJsZSBmb3IgaXRlcmF0aW9uIHRvIHJldHVybiBib3RoIGV4dGVuc2lvbnMKKyAgLy8gYW5kIG5vbi1leHRlbnNpb25zIHRob3VnaC4KKyAgLy8KKyAgLy8gV2UgYWxzbyBuZWVkIHRvIHZhbGlkYXRlIHRoYXQgdGhlIGZpZWxkIG51bWJlciBpcyBpbiBhbiBleHRlbnNpb24gcmFuZ2UgaWZmCisgIC8vIGl0IGlzIGFuIGV4dGVuc2lvbi4KKworICAvLyBUaGlzIG1ldGhvZCBpcyBpZGVtcG90ZW50LiBDaGVjayBpZiB8ZnwgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgbXNnZGVmIGFuZAorICAvLyByZXR1cm4gaW1tZWRpYXRlbHkgaWYgc28uCisgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGUoZikgPT0gbSkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gQ2hlY2sgY29uc3RyYWludHMgZm9yIGFsbCBmaWVsZHMgYmVmb3JlIHBlcmZvcm1pbmcgYW55IGFjdGlvbi4KKyAgaWYgKCFjaGVja19maWVsZF9hZGQobSwgZiwgcykpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSBpZiAodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmdvbmVvZihmKSAhPSBOVUxMKSB7CisgICAgLy8gRmllbGRzIGluIGEgb25lb2YgY2FuIG9ubHkgYmUgYWRkZWQgYnkgYWRkaW5nIHRoZSBvbmVvZiB0byB0aGUgbXNnZGVmLgorICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJmaWVsZGRlZiBpcyBwYXJ0IG9mIGEgb25lb2YiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBDb25zdHJhaW50IGNoZWNrcyBvaywgcGVyZm9ybSB0aGUgYWN0aW9uLgorICBhZGRfZmllbGQobSwgZiwgcmVmX2Rvbm9yKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgdXBiX21zZ2RlZl9hZGRvbmVvZih1cGJfbXNnZGVmICptLCB1cGJfb25lb2ZkZWYgKm8sIGNvbnN0IHZvaWQgKnJlZl9kb25vciwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKSB7CisgIC8vIENoZWNrIHZhcmlvdXMgY29uZGl0aW9ucyB0aGF0IHdvdWxkIHByZXZlbnQgdGhpcyBvbmVvZiBmcm9tIGJlaW5nIGFkZGVkLgorICBpZiAodXBiX29uZW9mZGVmX2NvbnRhaW5pbmd0eXBlKG8pKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgIm9uZW9mZGVmIGFscmVhZHkgYmVsb25ncyB0byBhIG1lc3NhZ2UiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSBpZiAodXBiX29uZW9mZGVmX25hbWUobykgPT0gTlVMTCkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJvbmVvZmRlZiBuYW1lIHdhcyBub3Qgc2V0Iik7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgaWYgKHVwYl9tc2dkZWZfbnRvb3oobSwgdXBiX29uZW9mZGVmX25hbWUobykpKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgImR1cGxpY2F0ZSBvbmVvZiBuYW1lIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgb2YgdGhlIG9uZW9mJ3MgZmllbGRzIGRvIG5vdCBjb25mbGljdCB3aXRoIG5hbWVzIG9yIG51bWJlcnMKKyAgLy8gb2YgZmllbGRzIGFscmVhZHkgaW4gdGhlIG1lc3NhZ2UuCisgIHVwYl9vbmVvZl9pdGVyIGl0OworICBmb3IgKHVwYl9vbmVvZl9iZWdpbigmaXQsIG8pOyAhdXBiX29uZW9mX2RvbmUoJml0KTsgdXBiX29uZW9mX25leHQoJml0KSkgeworICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZiA9IHVwYl9vbmVvZl9pdGVyX2ZpZWxkKCZpdCk7CisgICAgaWYgKCFjaGVja19maWVsZF9hZGQobSwgZiwgcykpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICAvLyBFdmVyeXRoaW5nIGNoZWNrcyBvdXQgLS0gY29tbWl0IG5vdy4KKworICAvLyBBZGQgb25lb2YgaXRzZWxmIGZpcnN0LgorICBvLT5wYXJlbnQgPSBtOworICB1cGJfc3RydGFibGVfaW5zZXJ0KCZtLT5udG9vLCB1cGJfb25lb2ZkZWZfbmFtZShvKSwgdXBiX3ZhbHVlX3B0cihvKSk7CisgIHVwYl9yZWYyKG8sIG0pOworICB1cGJfcmVmMihtLCBvKTsKKworICAvLyBBZGQgZWFjaCBmaWVsZCBvZiB0aGUgb25lb2YgZGlyZWN0bHkgdG8gdGhlIG1zZ2RlZi4KKyAgZm9yICh1cGJfb25lb2ZfYmVnaW4oJml0LCBvKTsgIXVwYl9vbmVvZl9kb25lKCZpdCk7IHVwYl9vbmVvZl9uZXh0KCZpdCkpIHsKKyAgICB1cGJfZmllbGRkZWYgKmYgPSB1cGJfb25lb2ZfaXRlcl9maWVsZCgmaXQpOworICAgIGFkZF9maWVsZChtLCBmLCBOVUxMKTsKKyAgfQorCisgIGlmIChyZWZfZG9ub3IpIHVwYl9vbmVvZmRlZl91bnJlZihvLCByZWZfZG9ub3IpOworCisgIHJldHVybiB0cnVlOworfQorCitjb25zdCB1cGJfZmllbGRkZWYgKnVwYl9tc2dkZWZfaXRvZihjb25zdCB1cGJfbXNnZGVmICptLCB1aW50MzJfdCBpKSB7CisgIHVwYl92YWx1ZSB2YWw7CisgIHJldHVybiB1cGJfaW50dGFibGVfbG9va3VwMzIoJm0tPml0b2YsIGksICZ2YWwpID8KKyAgICAgIHVwYl92YWx1ZV9nZXRwdHIodmFsKSA6IE5VTEw7Cit9CisKK2NvbnN0IHVwYl9maWVsZGRlZiAqdXBiX21zZ2RlZl9udG9mKGNvbnN0IHVwYl9tc2dkZWYgKm0sIGNvbnN0IGNoYXIgKm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuKSB7CisgIHVwYl92YWx1ZSB2YWw7CisgIHJldHVybiB1cGJfc3RydGFibGVfbG9va3VwMigmbS0+bnRvZiwgbmFtZSwgbGVuLCAmdmFsKSA/CisgICAgICB1cGJfdmFsdWVfZ2V0cHRyKHZhbCkgOiBOVUxMOworfQorCitjb25zdCB1cGJfb25lb2ZkZWYgKnVwYl9tc2dkZWZfbnRvbyhjb25zdCB1cGJfbXNnZGVmICptLCBjb25zdCBjaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbikgeworICB1cGJfdmFsdWUgdmFsOworICByZXR1cm4gdXBiX3N0cnRhYmxlX2xvb2t1cDIoJm0tPm50b28sIG5hbWUsIGxlbiwgJnZhbCkgPworICAgICAgdXBiX3ZhbHVlX2dldHB0cih2YWwpIDogTlVMTDsKK30KKworaW50IHVwYl9tc2dkZWZfbnVtZmllbGRzKGNvbnN0IHVwYl9tc2dkZWYgKm0pIHsKKyAgcmV0dXJuIHVwYl9zdHJ0YWJsZV9jb3VudCgmbS0+bnRvZik7Cit9CisKK2ludCB1cGJfbXNnZGVmX251bW9uZW9mcyhjb25zdCB1cGJfbXNnZGVmICptKSB7CisgIHJldHVybiB1cGJfc3RydGFibGVfY291bnQoJm0tPm50b28pOworfQorCit2b2lkIHVwYl9tc2dkZWZfc2V0bWFwZW50cnkodXBiX21zZ2RlZiAqbSwgYm9vbCBtYXBfZW50cnkpIHsKKyAgYXNzZXJ0KCF1cGJfbXNnZGVmX2lzZnJvemVuKG0pKTsKKyAgbS0+bWFwX2VudHJ5ID0gbWFwX2VudHJ5OworfQorCitib29sIHVwYl9tc2dkZWZfbWFwZW50cnkoY29uc3QgdXBiX21zZ2RlZiAqbSkgeworICByZXR1cm4gbS0+bWFwX2VudHJ5OworfQorCit2b2lkIHVwYl9tc2dfZmllbGRfYmVnaW4odXBiX21zZ19maWVsZF9pdGVyICppdGVyLCBjb25zdCB1cGJfbXNnZGVmICptKSB7CisgIHVwYl9pbnR0YWJsZV9iZWdpbihpdGVyLCAmbS0+aXRvZik7Cit9CisKK3ZvaWQgdXBiX21zZ19maWVsZF9uZXh0KHVwYl9tc2dfZmllbGRfaXRlciAqaXRlcikgeyB1cGJfaW50dGFibGVfbmV4dChpdGVyKTsgfQorCitib29sIHVwYl9tc2dfZmllbGRfZG9uZShjb25zdCB1cGJfbXNnX2ZpZWxkX2l0ZXIgKml0ZXIpIHsKKyAgcmV0dXJuIHVwYl9pbnR0YWJsZV9kb25lKGl0ZXIpOworfQorCit1cGJfZmllbGRkZWYgKnVwYl9tc2dfaXRlcl9maWVsZChjb25zdCB1cGJfbXNnX2ZpZWxkX2l0ZXIgKml0ZXIpIHsKKyAgcmV0dXJuICh1cGJfZmllbGRkZWYqKXVwYl92YWx1ZV9nZXRwdHIodXBiX2ludHRhYmxlX2l0ZXJfdmFsdWUoaXRlcikpOworfQorCit2b2lkIHVwYl9tc2dfZmllbGRfaXRlcl9zZXRkb25lKHVwYl9tc2dfZmllbGRfaXRlciAqaXRlcikgeworICB1cGJfaW50dGFibGVfaXRlcl9zZXRkb25lKGl0ZXIpOworfQorCit2b2lkIHVwYl9tc2dfb25lb2ZfYmVnaW4odXBiX21zZ19vbmVvZl9pdGVyICppdGVyLCBjb25zdCB1cGJfbXNnZGVmICptKSB7CisgIHVwYl9zdHJ0YWJsZV9iZWdpbihpdGVyLCAmbS0+bnRvbyk7Cit9CisKK3ZvaWQgdXBiX21zZ19vbmVvZl9uZXh0KHVwYl9tc2dfb25lb2ZfaXRlciAqaXRlcikgeyB1cGJfc3RydGFibGVfbmV4dChpdGVyKTsgfQorCitib29sIHVwYl9tc2dfb25lb2ZfZG9uZShjb25zdCB1cGJfbXNnX29uZW9mX2l0ZXIgKml0ZXIpIHsKKyAgcmV0dXJuIHVwYl9zdHJ0YWJsZV9kb25lKGl0ZXIpOworfQorCit1cGJfb25lb2ZkZWYgKnVwYl9tc2dfaXRlcl9vbmVvZihjb25zdCB1cGJfbXNnX29uZW9mX2l0ZXIgKml0ZXIpIHsKKyAgcmV0dXJuICh1cGJfb25lb2ZkZWYqKXVwYl92YWx1ZV9nZXRwdHIodXBiX3N0cnRhYmxlX2l0ZXJfdmFsdWUoaXRlcikpOworfQorCit2b2lkIHVwYl9tc2dfb25lb2ZfaXRlcl9zZXRkb25lKHVwYl9tc2dfb25lb2ZfaXRlciAqaXRlcikgeworICB1cGJfc3RydGFibGVfaXRlcl9zZXRkb25lKGl0ZXIpOworfQorCisvKiB1cGJfb25lb2ZkZWYgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgdm9pZCB2aXNpdG9uZW9mKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCB1cGJfcmVmY291bnRlZF92aXNpdCAqdmlzaXQsCisgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgY29uc3QgdXBiX29uZW9mZGVmICpvID0gKGNvbnN0IHVwYl9vbmVvZmRlZiopcjsKKyAgdXBiX29uZW9mX2l0ZXIgaTsKKyAgZm9yICh1cGJfb25lb2ZfYmVnaW4oJmksIG8pOyAhdXBiX29uZW9mX2RvbmUoJmkpOyB1cGJfb25lb2ZfbmV4dCgmaSkpIHsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSB1cGJfb25lb2ZfaXRlcl9maWVsZCgmaSk7CisgICAgdmlzaXQociwgVVBCX1VQQ0FTVDIoZiksIGNsb3N1cmUpOworICB9CisgIGlmIChvLT5wYXJlbnQpIHsKKyAgICB2aXNpdChyLCBVUEJfVVBDQVNUMihvLT5wYXJlbnQpLCBjbG9zdXJlKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBmcmVlb25lb2YodXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgdXBiX29uZW9mZGVmICpvID0gKHVwYl9vbmVvZmRlZiopcjsKKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmby0+bnRvZik7CisgIHVwYl9pbnR0YWJsZV91bmluaXQoJm8tPml0b2YpOworICB1cGJfZGVmX3VuaW5pdChVUEJfVVBDQVNUKG8pKTsKKyAgZnJlZShvKTsKK30KKwordXBiX29uZW9mZGVmICp1cGJfb25lb2ZkZWZfbmV3KGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgdXBiX3JlZmNvdW50ZWRfdnRibCB2dGJsID0ge3Zpc2l0b25lb2YsIGZyZWVvbmVvZn07CisgIHVwYl9vbmVvZmRlZiAqbyA9IG1hbGxvYyhzaXplb2YoKm8pKTsKKyAgby0+cGFyZW50ID0gTlVMTDsKKyAgaWYgKCFvKSByZXR1cm4gTlVMTDsKKyAgaWYgKCF1cGJfZGVmX2luaXQoVVBCX1VQQ0FTVChvKSwgVVBCX0RFRl9PTkVPRiwgJnZ0YmwsIG93bmVyKSkgZ290byBlcnIyOworICBpZiAoIXVwYl9pbnR0YWJsZV9pbml0KCZvLT5pdG9mLCBVUEJfQ1RZUEVfUFRSKSkgZ290byBlcnIyOworICBpZiAoIXVwYl9zdHJ0YWJsZV9pbml0KCZvLT5udG9mLCBVUEJfQ1RZUEVfUFRSKSkgZ290byBlcnIxOworICByZXR1cm4gbzsKKworZXJyMToKKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmby0+aXRvZik7CitlcnIyOgorICBmcmVlKG8pOworICByZXR1cm4gTlVMTDsKK30KKwordXBiX29uZW9mZGVmICp1cGJfb25lb2ZkZWZfZHVwKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX29uZW9mZGVmICpuZXdvID0gdXBiX29uZW9mZGVmX25ldyhvd25lcik7CisgIGlmICghbmV3bykgcmV0dXJuIE5VTEw7CisgIGJvb2wgb2sgPSB1cGJfZGVmX3NldGZ1bGxuYW1lKFVQQl9VUENBU1QobmV3byksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9kZWZfZnVsbG5hbWUoVVBCX1VQQ0FTVChvKSksIE5VTEwpOworICBVUEJfQVNTRVJUX1ZBUihvaywgb2spOworICB1cGJfb25lb2ZfaXRlciBpOworICBmb3IgKHVwYl9vbmVvZl9iZWdpbigmaSwgbyk7ICF1cGJfb25lb2ZfZG9uZSgmaSk7IHVwYl9vbmVvZl9uZXh0KCZpKSkgeworICAgIHVwYl9maWVsZGRlZiAqZiA9IHVwYl9maWVsZGRlZl9kdXAodXBiX29uZW9mX2l0ZXJfZmllbGQoJmkpLCAmZik7CisgICAgaWYgKCFmIHx8ICF1cGJfb25lb2ZkZWZfYWRkZmllbGQobmV3bywgZiwgJmYsIE5VTEwpKSB7CisgICAgICB1cGJfb25lb2ZkZWZfdW5yZWYobmV3bywgb3duZXIpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisgIHJldHVybiBuZXdvOworfQorCitib29sIHVwYl9vbmVvZmRlZl9pc2Zyb3plbihjb25zdCB1cGJfb25lb2ZkZWYgKm8pIHsKKyAgcmV0dXJuIHVwYl9kZWZfaXNmcm96ZW4oVVBCX1VQQ0FTVChvKSk7Cit9CisKK3ZvaWQgdXBiX29uZW9mZGVmX3JlZihjb25zdCB1cGJfb25lb2ZkZWYgKm8sIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9kZWZfcmVmKFVQQl9VUENBU1QobyksIG93bmVyKTsKK30KKwordm9pZCB1cGJfb25lb2ZkZWZfdW5yZWYoY29uc3QgdXBiX29uZW9mZGVmICpvLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfZGVmX3VucmVmKFVQQl9VUENBU1QobyksIG93bmVyKTsKK30KKwordm9pZCB1cGJfb25lb2ZkZWZfZG9uYXRlcmVmKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywgY29uc3Qgdm9pZCAqZnJvbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnRvKSB7CisgIHVwYl9kZWZfZG9uYXRlcmVmKFVQQl9VUENBU1QobyksIGZyb20sIHRvKTsKK30KKwordm9pZCB1cGJfb25lb2ZkZWZfY2hlY2tyZWYoY29uc3QgdXBiX29uZW9mZGVmICpvLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfZGVmX2NoZWNrcmVmKFVQQl9VUENBU1QobyksIG93bmVyKTsKK30KKworY29uc3QgY2hhciAqdXBiX29uZW9mZGVmX25hbWUoY29uc3QgdXBiX29uZW9mZGVmICpvKSB7CisgIHJldHVybiB1cGJfZGVmX2Z1bGxuYW1lKFVQQl9VUENBU1QobykpOworfQorCitib29sIHVwYl9vbmVvZmRlZl9zZXRuYW1lKHVwYl9vbmVvZmRlZiAqbywgY29uc3QgY2hhciAqZnVsbG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpIHsKKyAgaWYgKHVwYl9vbmVvZmRlZl9jb250YWluaW5ndHlwZShvKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJvbmVvZiBhbHJlYWR5IGFkZGVkIHRvIGEgbWVzc2FnZSIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdXBiX2RlZl9zZXRmdWxsbmFtZShVUEJfVVBDQVNUKG8pLCBmdWxsbmFtZSwgcyk7Cit9CisKK2NvbnN0IHVwYl9tc2dkZWYgKnVwYl9vbmVvZmRlZl9jb250YWluaW5ndHlwZShjb25zdCB1cGJfb25lb2ZkZWYgKm8pIHsKKyAgcmV0dXJuIG8tPnBhcmVudDsKK30KKworaW50IHVwYl9vbmVvZmRlZl9udW1maWVsZHMoY29uc3QgdXBiX29uZW9mZGVmICpvKSB7CisgIHJldHVybiB1cGJfc3RydGFibGVfY291bnQoJm8tPm50b2YpOworfQorCitib29sIHVwYl9vbmVvZmRlZl9hZGRmaWVsZCh1cGJfb25lb2ZkZWYgKm8sIHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnJlZl9kb25vciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpIHsKKyAgYXNzZXJ0KCF1cGJfb25lb2ZkZWZfaXNmcm96ZW4obykpOworICBhc3NlcnQoIW8tPnBhcmVudCB8fCAhdXBiX21zZ2RlZl9pc2Zyb3plbihvLT5wYXJlbnQpKTsKKworICAvLyBUaGlzIG1ldGhvZCBpcyBpZGVtcG90ZW50LiBDaGVjayBpZiB8ZnwgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgb25lb2ZkZWYKKyAgLy8gYW5kIHJldHVybiBpbW1lZGlhdGVseSBpZiBzby4KKyAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoZikgPT0gbykgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gVGhlIGZpZWxkIG11c3QgaGF2ZSBhbiBPUFRJT05BTCBsYWJlbC4KKyAgaWYgKHVwYl9maWVsZGRlZl9sYWJlbChmKSAhPSBVUEJfTEFCRUxfT1BUSU9OQUwpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiZmllbGRzIGluIG9uZW9mIG11c3QgaGF2ZSBPUFRJT05BTCBsYWJlbCIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIENoZWNrIHRoYXQgbm8gZmllbGQgd2l0aCB0aGlzIG5hbWUgb3IgbnVtYmVyIGV4aXN0cyBhbHJlYWR5IGluIHRoZSBvbmVvZi4KKyAgLy8gQWxzbyBjaGVjayB0aGF0IHRoZSBmaWVsZCBpcyBub3QgYWxyZWFkeSBwYXJ0IG9mIGEgb25lb2YuCisgIGlmICh1cGJfZmllbGRkZWZfbmFtZShmKSA9PSBOVUxMIHx8IHVwYl9maWVsZGRlZl9udW1iZXIoZikgPT0gMCkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJmaWVsZCBuYW1lIG9yIG51bWJlciB3ZXJlIG5vdCBzZXQiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSBpZiAodXBiX29uZW9mZGVmX2l0b2YobywgdXBiX2ZpZWxkZGVmX251bWJlcihmKSkgfHwKKyAgICAgICAgICAgICB1cGJfb25lb2ZkZWZfbnRvZnoobywgdXBiX2ZpZWxkZGVmX25hbWUoZikpKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgImR1cGxpY2F0ZSBmaWVsZCBuYW1lIG9yIG51bWJlciIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKGYpICE9IE5VTEwpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzLCAiZmllbGRkZWYgYWxyZWFkeSBiZWxvbmdzIHRvIGEgb25lb2YiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBXZSBhbGxvdyBhZGRpbmcgYSBmaWVsZCB0byB0aGUgb25lb2YgZWl0aGVyIGlmIHRoZSBmaWVsZCBpcyBub3QgcGFydCBvZiBhCisgIC8vIG1zZ2RlZiwgb3IgaWYgaXQgaXMgYW5kIHdlIGFyZSBhbHNvIHBhcnQgb2YgdGhlIHNhbWUgbXNnZGVmLgorICBpZiAoby0+cGFyZW50ID09IE5VTEwpIHsKKyAgICAvLyBJZiB3ZSdyZSBub3QgaW4gYSBtc2dkZWYsIHRoZSBmaWVsZCBjYW5ub3QgYmUgZWl0aGVyLiBPdGhlcndpc2Ugd2Ugd291bGQKKyAgICAvLyBuZWVkIHRvIG1hZ2ljYWxseSBhZGQgdGhpcyBvbmVvZiB0byBhIG1zZ2RlZiB0byByZW1haW4gY29uc2lzdGVudCwgd2hpY2gKKyAgICAvLyBpcyBzdXJwcmlzaW5nIGJlaGF2aW9yLgorICAgIGlmICh1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGUoZikgIT0gTlVMTCkgeworICAgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocywgImZpZWxkZGVmIGFscmVhZHkgYmVsb25ncyB0byBhIG1lc3NhZ2UsIGJ1dCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib25lb2YgZG9lcyBub3QiKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gSWYgd2UncmUgaW4gYSBtc2dkZWYsIHRoZSB1c2VyIGNhbiBhZGQgZmllbGRzIHRoYXQgZWl0aGVyIGFyZW4ndCBpbiBhbnkKKyAgICAvLyBtc2dkZWYgKGluIHdoaWNoIGNhc2UgdGhleSdyZSBhZGRlZCB0byBvdXIgbXNnZGVmKSBvciBhbHJlYWR5IGEgcGFydCBvZgorICAgIC8vIG91ciBtc2dkZWYuCisgICAgaWYgKHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShmKSAhPSBOVUxMICYmCisgICAgICAgIHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShmKSAhPSBvLT5wYXJlbnQpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJmaWVsZGRlZiBiZWxvbmdzIHRvIGEgZGlmZmVyZW50IG1lc3NhZ2UgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRoYW4gb25lb2YiKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICAvLyBDb21taXQgcGhhc2UuIEZpcnN0IGFkZCB0aGUgZmllbGQgdG8gb3VyIHBhcmVudCBtc2dkZWYsIGlmIGFueSwgYmVjYXVzZQorICAvLyB0aGF0IG1heSBmYWlsOyB0aGVuIGFkZCB0aGUgZmllbGQgdG8gb3VyIG93biB0YWJsZXMuCisKKyAgaWYgKG8tPnBhcmVudCAhPSBOVUxMICYmIHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShmKSA9PSBOVUxMKSB7CisgICAgaWYgKCF1cGJfbXNnZGVmX2FkZGZpZWxkKCh1cGJfbXNnZGVmKilvLT5wYXJlbnQsIGYsIE5VTEwsIHMpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgcmVsZWFzZV9jb250YWluaW5ndHlwZShmKTsKKyAgZi0+b25lb2YgPSBvOworICB1cGJfaW50dGFibGVfaW5zZXJ0KCZvLT5pdG9mLCB1cGJfZmllbGRkZWZfbnVtYmVyKGYpLCB1cGJfdmFsdWVfcHRyKGYpKTsKKyAgdXBiX3N0cnRhYmxlX2luc2VydCgmby0+bnRvZiwgdXBiX2ZpZWxkZGVmX25hbWUoZiksIHVwYl92YWx1ZV9wdHIoZikpOworICB1cGJfcmVmMihmLCBvKTsKKyAgdXBiX3JlZjIobywgZik7CisgIGlmIChyZWZfZG9ub3IpIHVwYl9maWVsZGRlZl91bnJlZihmLCByZWZfZG9ub3IpOworCisgIHJldHVybiB0cnVlOworfQorCitjb25zdCB1cGJfZmllbGRkZWYgKnVwYl9vbmVvZmRlZl9udG9mKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IGxlbmd0aCkgeworICB1cGJfdmFsdWUgdmFsOworICByZXR1cm4gdXBiX3N0cnRhYmxlX2xvb2t1cDIoJm8tPm50b2YsIG5hbWUsIGxlbmd0aCwgJnZhbCkgPworICAgICAgdXBiX3ZhbHVlX2dldHB0cih2YWwpIDogTlVMTDsKK30KKworY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJfb25lb2ZkZWZfaXRvZihjb25zdCB1cGJfb25lb2ZkZWYgKm8sIHVpbnQzMl90IG51bSkgeworICB1cGJfdmFsdWUgdmFsOworICByZXR1cm4gdXBiX2ludHRhYmxlX2xvb2t1cDMyKCZvLT5pdG9mLCBudW0sICZ2YWwpID8KKyAgICAgIHVwYl92YWx1ZV9nZXRwdHIodmFsKSA6IE5VTEw7Cit9CisKK3ZvaWQgdXBiX29uZW9mX2JlZ2luKHVwYl9vbmVvZl9pdGVyICppdGVyLCBjb25zdCB1cGJfb25lb2ZkZWYgKm8pIHsKKyAgdXBiX2ludHRhYmxlX2JlZ2luKGl0ZXIsICZvLT5pdG9mKTsKK30KKwordm9pZCB1cGJfb25lb2ZfbmV4dCh1cGJfb25lb2ZfaXRlciAqaXRlcikgeworICB1cGJfaW50dGFibGVfbmV4dChpdGVyKTsKK30KKworYm9vbCB1cGJfb25lb2ZfZG9uZSh1cGJfb25lb2ZfaXRlciAqaXRlcikgeworICByZXR1cm4gdXBiX2ludHRhYmxlX2RvbmUoaXRlcik7Cit9CisKK3VwYl9maWVsZGRlZiAqdXBiX29uZW9mX2l0ZXJfZmllbGQoY29uc3QgdXBiX29uZW9mX2l0ZXIgKml0ZXIpIHsKKyAgcmV0dXJuICh1cGJfZmllbGRkZWYqKXVwYl92YWx1ZV9nZXRwdHIodXBiX2ludHRhYmxlX2l0ZXJfdmFsdWUoaXRlcikpOworfQorCit2b2lkIHVwYl9vbmVvZl9pdGVyX3NldGRvbmUodXBiX29uZW9mX2l0ZXIgKml0ZXIpIHsKKyAgdXBiX2ludHRhYmxlX2l0ZXJfc2V0ZG9uZShpdGVyKTsKK30KKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTEtMjAxMiBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogVE9ETyhoYWJlcm1hbik6IGl0J3MgdW5jbGVhciB3aGV0aGVyIGEgbG90IG9mIHRoZSBjb25zaXN0ZW5jeSBjaGVja3Mgc2hvdWxkCisgKiBhc3NlcnQoKSBvciByZXR1cm4gZmFsc2UuCisgKi8KKworCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKworLy8gRGVmaW5lZCBmb3IgdGhlIHNvbGUgcHVycG9zZSBvZiBoYXZpbmcgYSB1bmlxdWUgcG9pbnRlciB2YWx1ZSBmb3IKKy8vIFVQQl9OT19DTE9TVVJFLgorY2hhciBfdXBiX25vY2xvc3VyZTsKKworc3RhdGljIHZvaWQgZnJlZWhhbmRsZXJzKHVwYl9yZWZjb3VudGVkICpyKSB7CisgIHVwYl9oYW5kbGVycyAqaCA9ICh1cGJfaGFuZGxlcnMqKXI7CisKKyAgdXBiX2ludHRhYmxlX2l0ZXIgaTsKKyAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCAmaC0+Y2xlYW51cF8pOworICBmb3IoOyAhdXBiX2ludHRhYmxlX2RvbmUoJmkpOyB1cGJfaW50dGFibGVfbmV4dCgmaSkpIHsKKyAgICB2b2lkICp2YWwgPSAodm9pZCopdXBiX2ludHRhYmxlX2l0ZXJfa2V5KCZpKTsKKyAgICB1cGJfdmFsdWUgZnVuY192YWwgPSB1cGJfaW50dGFibGVfaXRlcl92YWx1ZSgmaSk7CisgICAgdXBiX2hhbmRsZXJmcmVlICpmdW5jID0gdXBiX3ZhbHVlX2dldGZwdHIoZnVuY192YWwpOworICAgIGZ1bmModmFsKTsKKyAgfQorCisgIHVwYl9pbnR0YWJsZV91bmluaXQoJmgtPmNsZWFudXBfKTsKKyAgdXBiX21zZ2RlZl91bnJlZihoLT5tc2csIGgpOworICBmcmVlKGgtPnN1Yik7CisgIGZyZWUoaCk7Cit9CisKK3N0YXRpYyB2b2lkIHZpc2l0aGFuZGxlcnMoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIHVwYl9yZWZjb3VudGVkX3Zpc2l0ICp2aXNpdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCB1cGJfaGFuZGxlcnMgKmggPSAoY29uc3QgdXBiX2hhbmRsZXJzKilyOworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmksIGgtPm1zZyk7CisgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpKTsKKyAgICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaSkpIHsKKyAgICB1cGJfZmllbGRkZWYgKmYgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJmkpOworICAgIGlmICghdXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpKSBjb250aW51ZTsKKyAgICBjb25zdCB1cGJfaGFuZGxlcnMgKnN1YiA9IHVwYl9oYW5kbGVyc19nZXRzdWJoYW5kbGVycyhoLCBmKTsKKyAgICBpZiAoc3ViKSB2aXNpdChyLCBVUEJfVVBDQVNUKHN1YiksIGNsb3N1cmUpOworICB9Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdXBiX3JlZmNvdW50ZWRfdnRibCB2dGJsID0ge3Zpc2l0aGFuZGxlcnMsIGZyZWVoYW5kbGVyc307CisKK3R5cGVkZWYgc3RydWN0IHsKKyAgdXBiX2ludHRhYmxlIHRhYjsgIC8vIG1hcHMgdXBiX21zZ2RlZiogLT4gdXBiX2hhbmRsZXJzKi4KKyAgdXBiX2hhbmRsZXJzX2NhbGxiYWNrICpjYWxsYmFjazsKKyAgY29uc3Qgdm9pZCAqY2xvc3VyZTsKK30gZGZzX3N0YXRlOworCisvLyBUT0RPKGhhYmVybWFuKTogZGlzY2FyZCB1cGJfaGFuZGxlcnMqIG9iamVjdHMgdGhhdCBkbyBub3QgYWN0dWFsbHkgaGF2ZSBhbnkKKy8vIGhhbmRsZXJzIHNldCBhbmQgY2Fubm90IHJlYWNoIGFueSB1cGJfaGFuZGxlcnMqIG9iamVjdCB0aGF0IGRvZXMuICBUaGlzIGlzCisvLyBzbGlnaHRseSB0cmlja3kgdG8gZG8gY29ycmVjdGx5Lgorc3RhdGljIHVwYl9oYW5kbGVycyAqbmV3Zm9ybXNnKGNvbnN0IHVwYl9tc2dkZWYgKm0sIGNvbnN0IHZvaWQgKm93bmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmc19zdGF0ZSAqcykgeworICB1cGJfaGFuZGxlcnMgKmggPSB1cGJfaGFuZGxlcnNfbmV3KG0sIG93bmVyKTsKKyAgaWYgKCFoKSByZXR1cm4gTlVMTDsKKyAgaWYgKCF1cGJfaW50dGFibGVfaW5zZXJ0cHRyKCZzLT50YWIsIG0sIHVwYl92YWx1ZV9wdHIoaCkpKSBnb3RvIG9vbTsKKworICBzLT5jYWxsYmFjayhzLT5jbG9zdXJlLCBoKTsKKworICAvLyBGb3IgZWFjaCBzdWJtZXNzYWdlIGZpZWxkLCBnZXQgb3IgY3JlYXRlIGEgaGFuZGxlcnMgb2JqZWN0IGFuZCBzZXQgaXQgYXMKKyAgLy8gdGhlIHN1YmhhbmRsZXJzLgorICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmksIG0pOworICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaSk7CisgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpKTsKKyAgICBpZiAoIXVwYl9maWVsZGRlZl9pc3N1Ym1zZyhmKSkgY29udGludWU7CisKKyAgICBjb25zdCB1cGJfbXNnZGVmICpzdWJkZWYgPSB1cGJfZG93bmNhc3RfbXNnZGVmKHVwYl9maWVsZGRlZl9zdWJkZWYoZikpOworICAgIHVwYl92YWx1ZSBzdWJtX2VudDsKKyAgICBpZiAodXBiX2ludHRhYmxlX2xvb2t1cHB0cigmcy0+dGFiLCBzdWJkZWYsICZzdWJtX2VudCkpIHsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdWJoYW5kbGVycyhoLCBmLCB1cGJfdmFsdWVfZ2V0cHRyKHN1Ym1fZW50KSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHVwYl9oYW5kbGVycyAqc3ViX21oID0gbmV3Zm9ybXNnKHN1YmRlZiwgJnN1Yl9taCwgcyk7CisgICAgICBpZiAoIXN1Yl9taCkgZ290byBvb207CisgICAgICB1cGJfaGFuZGxlcnNfc2V0c3ViaGFuZGxlcnMoaCwgZiwgc3ViX21oKTsKKyAgICAgIHVwYl9oYW5kbGVyc191bnJlZihzdWJfbWgsICZzdWJfbWgpOworICAgIH0KKyAgfQorICByZXR1cm4gaDsKKworb29tOgorICB1cGJfaGFuZGxlcnNfdW5yZWYoaCwgb3duZXIpOworICByZXR1cm4gTlVMTDsKK30KKworLy8gR2l2ZW4gYSBzZWxlY3RvciBmb3IgYSBTVEFSVFNVQk1TRyBoYW5kbGVyLCByZXNvbHZlcyB0byBhIHBvaW50ZXIgdG8gdGhlCisvLyBzdWJoYW5kbGVycyBmb3IgdGhpcyBzdWJtZXNzYWdlIGZpZWxkLgorI2RlZmluZSBTVUJIKGgsIHNlbGVjdG9yKSAoaC0+c3ViW3NlbGVjdG9yXSkKKworLy8gVGhlIHNlbGVjdG9yIGZvciBhIHN1Ym1lc3NhZ2UgZmllbGQgaXMgdGhlIGZpZWxkIGluZGV4LgorI2RlZmluZSBTVUJIX0YoaCwgZikgU1VCSChoLCBmLT5pbmRleF8pCisKK3N0YXRpYyBpbnQzMl90IHRyeWdldHNlbCh1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcnR5cGVfdCB0eXBlKSB7CisgIHVwYl9zZWxlY3Rvcl90IHNlbDsKKyAgYXNzZXJ0KCF1cGJfaGFuZGxlcnNfaXNmcm96ZW4oaCkpOworICBpZiAodXBiX2hhbmRsZXJzX21zZ2RlZihoKSAhPSB1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGUoZikpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycmYoCisgICAgICAgICZoLT5zdGF0dXNfLCAidHlwZSBtaXNtYXRjaDogZmllbGQgJXMgZG9lcyBub3QgYmVsb25nIHRvIG1lc3NhZ2UgJXMiLAorICAgICAgICB1cGJfZmllbGRkZWZfbmFtZShmKSwgdXBiX21zZ2RlZl9mdWxsbmFtZSh1cGJfaGFuZGxlcnNfbXNnZGVmKGgpKSk7CisgICAgcmV0dXJuIC0xOworICB9CisgIGlmICghdXBiX2hhbmRsZXJzX2dldHNlbGVjdG9yKGYsIHR5cGUsICZzZWwpKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJmKAorICAgICAgICAmaC0+c3RhdHVzXywKKyAgICAgICAgInR5cGUgbWlzbWF0Y2g6IGNhbm5vdCByZWdpc3RlciBoYW5kbGVyIHR5cGUgJWQgZm9yIGZpZWxkICVzIiwKKyAgICAgICAgdHlwZSwgdXBiX2ZpZWxkZGVmX25hbWUoZikpOworICAgIHJldHVybiAtMTsKKyAgfQorICByZXR1cm4gc2VsOworfQorCitzdGF0aWMgdXBiX3NlbGVjdG9yX3QgaGFuZGxlcnNfZ2V0c2VsKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcnR5cGVfdCB0eXBlKSB7CisgIGludDMyX3Qgc2VsID0gdHJ5Z2V0c2VsKGgsIGYsIHR5cGUpOworICBhc3NlcnQoc2VsID49IDApOworICByZXR1cm4gc2VsOworfQorCitzdGF0aWMgY29uc3Qgdm9pZCAqKnJldHVybnR5cGUodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJ0eXBlX3QgdHlwZSkgeworICByZXR1cm4gJmgtPnRhYmxlW2hhbmRsZXJzX2dldHNlbChoLCBmLCB0eXBlKV0uYXR0ci5yZXR1cm5fY2xvc3VyZV90eXBlXzsKK30KKworc3RhdGljIGJvb2wgZG9zZXQodXBiX2hhbmRsZXJzICpoLCBpbnQzMl90IHNlbCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJ0eXBlX3QgdHlwZSwgdXBiX2Z1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsKKyAgYXNzZXJ0KCF1cGJfaGFuZGxlcnNfaXNmcm96ZW4oaCkpOworCisgIGlmIChzZWwgPCAwKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2coJmgtPnN0YXR1c18sCisgICAgICAgICAgICAgICAgICAgICAgICAgImluY29ycmVjdCBoYW5kbGVyIHR5cGUgZm9yIHRoaXMgZmllbGQuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaWYgKGgtPnRhYmxlW3NlbF0uZnVuYykgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKCZoLT5zdGF0dXNfLAorICAgICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgY2hhbmdlIGhhbmRsZXIgb25jZSBpdCBoYXMgYmVlbiBzZXQuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdXBiX2hhbmRsZXJhdHRyIHNldF9hdHRyID0gVVBCX0hBTkRMRVJBVFRSX0lOSVRJQUxJWkVSOworICBpZiAoYXR0cikgeworICAgIHNldF9hdHRyID0gKmF0dHI7CisgIH0KKworICAvLyBDaGVjayB0aGF0IHRoZSBnaXZlbiBjbG9zdXJlIHR5cGUgbWF0Y2hlcyB0aGUgY2xvc3VyZSB0eXBlIHRoYXQgaGFzIGJlZW4KKyAgLy8gZXN0YWJsaXNoZWQgZm9yIHRoaXMgY29udGV4dCAoaWYgYW55KS4KKyAgY29uc3Qgdm9pZCAqY2xvc3VyZV90eXBlID0gdXBiX2hhbmRsZXJhdHRyX2Nsb3N1cmV0eXBlKCZzZXRfYXR0cik7CisgIGNvbnN0IHZvaWQgKipjb250ZXh0X2Nsb3N1cmVfdHlwZTsKKworICBpZiAodHlwZSA9PSBVUEJfSEFORExFUl9TVFJJTkcpIHsKKyAgICBjb250ZXh0X2Nsb3N1cmVfdHlwZSA9IHJldHVybnR5cGUoaCwgZiwgVVBCX0hBTkRMRVJfU1RBUlRTVFIpOworICB9IGVsc2UgaWYgKGYgJiYgdXBiX2ZpZWxkZGVmX2lzc2VxKGYpICYmCisgICAgICAgICAgICAgdHlwZSAhPSBVUEJfSEFORExFUl9TVEFSVFNFUSAmJgorICAgICAgICAgICAgIHR5cGUgIT0gVVBCX0hBTkRMRVJfRU5EU0VRKSB7CisgICAgY29udGV4dF9jbG9zdXJlX3R5cGUgPSByZXR1cm50eXBlKGgsIGYsIFVQQl9IQU5ETEVSX1NUQVJUU0VRKTsKKyAgfSBlbHNlIHsKKyAgICBjb250ZXh0X2Nsb3N1cmVfdHlwZSA9ICZoLT50b3BfY2xvc3VyZV90eXBlOworICB9CisKKyAgaWYgKGNsb3N1cmVfdHlwZSAmJiAqY29udGV4dF9jbG9zdXJlX3R5cGUgJiYKKyAgICAgIGNsb3N1cmVfdHlwZSAhPSAqY29udGV4dF9jbG9zdXJlX3R5cGUpIHsKKyAgICAvLyBUT0RPKGhhYmVybWFuKTogYmV0dGVyIG1lc3NhZ2UgZm9yIGRlYnVnZ2luZy4KKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZygmaC0+c3RhdHVzXywgImNsb3N1cmUgdHlwZSBkb2VzIG5vdCBtYXRjaCIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChjbG9zdXJlX3R5cGUpCisgICAgKmNvbnRleHRfY2xvc3VyZV90eXBlID0gY2xvc3VyZV90eXBlOworCisgIC8vIElmIHRoaXMgaXMgYSBTVEFSVFNFUSBvciBTVEFSVFNUUiBoYW5kbGVyLCBjaGVjayB0aGF0IHRoZSByZXR1cm5lZCBwb2ludGVyCisgIC8vIG1hdGNoZXMgYW55IHByZS1leGlzdGluZyBleHBlY3RhdGlvbnMgYWJvdXQgd2hhdCB0eXBlIGlzIGV4cGVjdGVkLgorICBpZiAodHlwZSA9PSBVUEJfSEFORExFUl9TVEFSVFNFUSB8fCB0eXBlID09IFVQQl9IQU5ETEVSX1NUQVJUU1RSKSB7CisgICAgY29uc3Qgdm9pZCAqcmV0dXJuX3R5cGUgPSB1cGJfaGFuZGxlcmF0dHJfcmV0dXJuY2xvc3VyZXR5cGUoJnNldF9hdHRyKTsKKyAgICBjb25zdCB2b2lkICp0YWJsZV9yZXR1cm5fdHlwZSA9CisgICAgICAgIHVwYl9oYW5kbGVyYXR0cl9yZXR1cm5jbG9zdXJldHlwZSgmaC0+dGFibGVbc2VsXS5hdHRyKTsKKyAgICBpZiAocmV0dXJuX3R5cGUgJiYgdGFibGVfcmV0dXJuX3R5cGUgJiYgcmV0dXJuX3R5cGUgIT0gdGFibGVfcmV0dXJuX3R5cGUpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKCZoLT5zdGF0dXNfLCAiY2xvc3VyZSByZXR1cm4gdHlwZSBkb2VzIG5vdCBtYXRjaCIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICh0YWJsZV9yZXR1cm5fdHlwZSAmJiAhcmV0dXJuX3R5cGUpCisgICAgICB1cGJfaGFuZGxlcmF0dHJfc2V0cmV0dXJuY2xvc3VyZXR5cGUoJnNldF9hdHRyLCB0YWJsZV9yZXR1cm5fdHlwZSk7CisgIH0KKworICBoLT50YWJsZVtzZWxdLmZ1bmMgPSAodXBiX2Z1bmMqKWZ1bmM7CisgIGgtPnRhYmxlW3NlbF0uYXR0ciA9IHNldF9hdHRyOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gUmV0dXJucyB0aGUgZWZmZWN0aXZlIGNsb3N1cmUgdHlwZSBmb3IgdGhpcyBoYW5kbGVyICh3aGljaCB3aWxsIHByb3BhZ2F0ZQorLy8gZnJvbSBvdXRlciBmcmFtZXMgaWYgdGhpcyBmcmFtZSBoYXMgbm8gU1RBUlQqIGhhbmRsZXIpLiAgTm90IGltcGxlbWVudGVkIGZvcgorLy8gVVBCX0hBTkRMRVJfU1RSSU5HIGF0IHRoZSBtb21lbnQgc2luY2UgdGhpcyBpcyBub3QgbmVlZGVkLiAgUmV0dXJucyBOVUxMIGlzCisvLyB0aGUgZWZmZWN0aXZlIGNsb3N1cmUgdHlwZSBpcyB1bnNwZWNpZmllZCAoZWl0aGVyIG5vIGhhbmRsZXIgd2FzIHJlZ2lzdGVyZWQKKy8vIHRvIHNwZWNpZnkgaXQgb3IgdGhlIGhhbmRsZXIgdGhhdCB3YXMgcmVnaXN0ZXJlZCBkaWQgbm90IHNwZWNpZnkgdGhlIGNsb3N1cmUKKy8vIHR5cGUpLgorY29uc3Qgdm9pZCAqZWZmZWN0aXZlX2Nsb3N1cmVfdHlwZSh1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJ0eXBlX3QgdHlwZSkgeworICBhc3NlcnQodHlwZSAhPSBVUEJfSEFORExFUl9TVFJJTkcpOworICBjb25zdCB2b2lkICpyZXQgPSBoLT50b3BfY2xvc3VyZV90eXBlOworICB1cGJfc2VsZWN0b3JfdCBzZWw7CisgIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikgJiYKKyAgICAgIHR5cGUgIT0gVVBCX0hBTkRMRVJfU1RBUlRTRVEgJiYKKyAgICAgIHR5cGUgIT0gVVBCX0hBTkRMRVJfRU5EU0VRICYmCisgICAgICBoLT50YWJsZVtzZWwgPSBoYW5kbGVyc19nZXRzZWwoaCwgZiwgVVBCX0hBTkRMRVJfU1RBUlRTRVEpXS5mdW5jKSB7CisgICAgcmV0ID0gdXBiX2hhbmRsZXJhdHRyX3JldHVybmNsb3N1cmV0eXBlKCZoLT50YWJsZVtzZWxdLmF0dHIpOworICB9CisKKyAgaWYgKHR5cGUgPT0gVVBCX0hBTkRMRVJfU1RSSU5HICYmCisgICAgICBoLT50YWJsZVtzZWwgPSBoYW5kbGVyc19nZXRzZWwoaCwgZiwgVVBCX0hBTkRMRVJfU1RBUlRTVFIpXS5mdW5jKSB7CisgICAgcmV0ID0gdXBiX2hhbmRsZXJhdHRyX3JldHVybmNsb3N1cmV0eXBlKCZoLT50YWJsZVtzZWxdLmF0dHIpOworICB9CisKKyAgLy8gVGhlIGVmZmVjdGl2ZSB0eXBlIG9mIHRoZSBzdWJtZXNzYWdlOyBub3QgdXNlZCB5ZXQuCisgIC8vIGlmICh0eXBlID09IFNVQk1FU1NBR0UgJiYKKyAgLy8gICAgIGgtPnRhYmxlW3NlbCA9IGhhbmRsZXJzX2dldHNlbChoLCBmLCBVUEJfSEFORExFUl9TVEFSVFNVQk1TRyldLmZ1bmMpIHsKKyAgLy8gICByZXQgPSB1cGJfaGFuZGxlcmF0dHJfcmV0dXJuY2xvc3VyZXR5cGUoJmgtPnRhYmxlW3NlbF0uYXR0cik7CisgIC8vIH0KKworICByZXR1cm4gcmV0OworfQorCisvLyBDaGVja3Mgd2hldGhlciB0aGUgU1RBUlQqIGhhbmRsZXIgc3BlY2lmaWVkIGJ5IGYgJiB0eXBlIGlzIG1pc3NpbmcgZXZlbgorLy8gdGhvdWdoIGl0IGlzIHJlcXVpcmVkIHRvIGNvbnZlcnQgdGhlIGVzdGFibGlzaGVkIHR5cGUgb2YgYW4gb3V0ZXIgZnJhbWUKKy8vICgiY2xvc3VyZV90eXBlIikgaW50byB0aGUgZXN0YWJsaXNoZWQgdHlwZSBvZiBhbiBpbm5lciBmcmFtZSAocmVwcmVzZW50ZWQgaW4KKy8vIHRoZSByZXR1cm4gY2xvc3VyZSB0eXBlIG9mIHRoaXMgaGFuZGxlcidzIGF0dHIuCitib29sIGNoZWNrc3RhcnQodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9oYW5kbGVydHlwZV90IHR5cGUsCisgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIHVwYl9zZWxlY3Rvcl90IHNlbCA9IGhhbmRsZXJzX2dldHNlbChoLCBmLCB0eXBlKTsKKyAgaWYgKGgtPnRhYmxlW3NlbF0uZnVuYykgcmV0dXJuIHRydWU7CisgIGNvbnN0IHZvaWQgKmNsb3N1cmVfdHlwZSA9IGVmZmVjdGl2ZV9jbG9zdXJlX3R5cGUoaCwgZiwgdHlwZSk7CisgIGNvbnN0IHVwYl9oYW5kbGVyYXR0ciAqYXR0ciA9ICZoLT50YWJsZVtzZWxdLmF0dHI7CisgIGNvbnN0IHZvaWQgKnJldHVybl9jbG9zdXJlX3R5cGUgPSB1cGJfaGFuZGxlcmF0dHJfcmV0dXJuY2xvc3VyZXR5cGUoYXR0cik7CisgIGlmIChjbG9zdXJlX3R5cGUgJiYgcmV0dXJuX2Nsb3N1cmVfdHlwZSAmJgorICAgICAgY2xvc3VyZV90eXBlICE9IHJldHVybl9jbG9zdXJlX3R5cGUpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycmYoc3RhdHVzLAorICAgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgc3RhcnQgaGFuZGxlciB0byByZXR1cm4gc3ViIHR5cGUgZm9yIGZpZWxkICVmIiwKKyAgICAgICAgICAgICAgICAgICAgICAgdXBiX2ZpZWxkZGVmX25hbWUoZikpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworLyogUHVibGljIGludGVyZmFjZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworYm9vbCB1cGJfaGFuZGxlcnNfaXNmcm96ZW4oY29uc3QgdXBiX2hhbmRsZXJzICpoKSB7CisgIHJldHVybiB1cGJfcmVmY291bnRlZF9pc2Zyb3plbihVUEJfVVBDQVNUKGgpKTsKK30KKwordm9pZCB1cGJfaGFuZGxlcnNfcmVmKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX3JlZmNvdW50ZWRfcmVmKFVQQl9VUENBU1QoaCksIG93bmVyKTsKK30KKwordm9pZCB1cGJfaGFuZGxlcnNfdW5yZWYoY29uc3QgdXBiX2hhbmRsZXJzICpoLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfcmVmY291bnRlZF91bnJlZihVUEJfVVBDQVNUKGgpLCBvd25lcik7Cit9CisKK3ZvaWQgdXBiX2hhbmRsZXJzX2RvbmF0ZXJlZigKKyAgICBjb25zdCB1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKSB7CisgIHVwYl9yZWZjb3VudGVkX2RvbmF0ZXJlZihVUEJfVVBDQVNUKGgpLCBmcm9tLCB0byk7Cit9CisKK3ZvaWQgdXBiX2hhbmRsZXJzX2NoZWNrcmVmKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX3JlZmNvdW50ZWRfY2hlY2tyZWYoVVBCX1VQQ0FTVChoKSwgb3duZXIpOworfQorCit1cGJfaGFuZGxlcnMgKnVwYl9oYW5kbGVyc19uZXcoY29uc3QgdXBiX21zZ2RlZiAqbWQsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIGFzc2VydCh1cGJfbXNnZGVmX2lzZnJvemVuKG1kKSk7CisKKyAgaW50IGV4dHJhID0gc2l6ZW9mKHVwYl9oYW5kbGVyc190YWJlbnQpICogKG1kLT5zZWxlY3Rvcl9jb3VudCAtIDEpOworICB1cGJfaGFuZGxlcnMgKmggPSBjYWxsb2Moc2l6ZW9mKCpoKSArIGV4dHJhLCAxKTsKKyAgaWYgKCFoKSByZXR1cm4gTlVMTDsKKworICBoLT5tc2cgPSBtZDsKKyAgdXBiX21zZ2RlZl9yZWYoaC0+bXNnLCBoKTsKKyAgdXBiX3N0YXR1c19jbGVhcigmaC0+c3RhdHVzXyk7CisgIGgtPnN1YiA9IGNhbGxvYyhtZC0+c3VibXNnX2ZpZWxkX2NvdW50LCBzaXplb2YoKmgtPnN1YikpOworICBpZiAoIWgtPnN1YikgZ290byBvb207CisgIGlmICghdXBiX3JlZmNvdW50ZWRfaW5pdChVUEJfVVBDQVNUKGgpLCAmdnRibCwgb3duZXIpKSBnb3RvIG9vbTsKKyAgaWYgKCF1cGJfaW50dGFibGVfaW5pdCgmaC0+Y2xlYW51cF8sIFVQQl9DVFlQRV9GUFRSKSkgZ290byBvb207CisKKyAgLy8gY2FsbG9jKCkgYWJvdmUgaW5pdGlhbGl6ZWQgYWxsIGhhbmRsZXJzIHRvIE5VTEwuCisgIHJldHVybiBoOworCitvb206CisgIGZyZWVoYW5kbGVycyhVUEJfVVBDQVNUKGgpKTsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX2hhbmRsZXJzX25ld2Zyb3plbihjb25zdCB1cGJfbXNnZGVmICptLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKm93bmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyc19jYWxsYmFjayAqY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqY2xvc3VyZSkgeworICBkZnNfc3RhdGUgc3RhdGU7CisgIHN0YXRlLmNhbGxiYWNrID0gY2FsbGJhY2s7CisgIHN0YXRlLmNsb3N1cmUgPSBjbG9zdXJlOworICBpZiAoIXVwYl9pbnR0YWJsZV9pbml0KCZzdGF0ZS50YWIsIFVQQl9DVFlQRV9QVFIpKSByZXR1cm4gTlVMTDsKKworICB1cGJfaGFuZGxlcnMgKnJldCA9IG5ld2Zvcm1zZyhtLCBvd25lciwgJnN0YXRlKTsKKworICB1cGJfaW50dGFibGVfdW5pbml0KCZzdGF0ZS50YWIpOworICBpZiAoIXJldCkgcmV0dXJuIE5VTEw7CisKKyAgdXBiX3JlZmNvdW50ZWQgKnIgPSBVUEJfVVBDQVNUKHJldCk7CisgIGJvb2wgb2sgPSB1cGJfcmVmY291bnRlZF9mcmVlemUoJnIsIDEsIE5VTEwsIFVQQl9NQVhfSEFORExFUl9ERVBUSCk7CisgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7CisKKyAgcmV0dXJuIHJldDsKK30KKworY29uc3QgdXBiX3N0YXR1cyAqdXBiX2hhbmRsZXJzX3N0YXR1cyh1cGJfaGFuZGxlcnMgKmgpIHsKKyAgYXNzZXJ0KCF1cGJfaGFuZGxlcnNfaXNmcm96ZW4oaCkpOworICByZXR1cm4gJmgtPnN0YXR1c187Cit9CisKK3ZvaWQgdXBiX2hhbmRsZXJzX2NsZWFyZXJyKHVwYl9oYW5kbGVycyAqaCkgeworICBhc3NlcnQoIXVwYl9oYW5kbGVyc19pc2Zyb3plbihoKSk7CisgIHVwYl9zdGF0dXNfY2xlYXIoJmgtPnN0YXR1c18pOworfQorCisjZGVmaW5lIFNFVFRFUihuYW1lLCBoYW5kbGVyY3R5cGUsIGhhbmRsZXJ0eXBlKSBcCisgIGJvb2wgdXBiX2hhbmRsZXJzX3NldCAjIyBuYW1lKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJjdHlwZSBmdW5jLCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsgXAorICAgIGludDMyX3Qgc2VsID0gdHJ5Z2V0c2VsKGgsIGYsIGhhbmRsZXJ0eXBlKTsgXAorICAgIHJldHVybiBkb3NldChoLCBzZWwsIGYsIGhhbmRsZXJ0eXBlLCAodXBiX2Z1bmMqKWZ1bmMsIGF0dHIpOyBcCisgIH0KKworU0VUVEVSKGludDMyLCAgICAgICB1cGJfaW50MzJfaGFuZGxlcmZ1bmMqLCAgICAgICBVUEJfSEFORExFUl9JTlQzMik7CitTRVRURVIoaW50NjQsICAgICAgIHVwYl9pbnQ2NF9oYW5kbGVyZnVuYyosICAgICAgIFVQQl9IQU5ETEVSX0lOVDY0KTsKK1NFVFRFUih1aW50MzIsICAgICAgdXBiX3VpbnQzMl9oYW5kbGVyZnVuYyosICAgICAgVVBCX0hBTkRMRVJfVUlOVDMyKTsKK1NFVFRFUih1aW50NjQsICAgICAgdXBiX3VpbnQ2NF9oYW5kbGVyZnVuYyosICAgICAgVVBCX0hBTkRMRVJfVUlOVDY0KTsKK1NFVFRFUihmbG9hdCwgICAgICAgdXBiX2Zsb2F0X2hhbmRsZXJmdW5jKiwgICAgICAgVVBCX0hBTkRMRVJfRkxPQVQpOworU0VUVEVSKGRvdWJsZSwgICAgICB1cGJfZG91YmxlX2hhbmRsZXJmdW5jKiwgICAgICBVUEJfSEFORExFUl9ET1VCTEUpOworU0VUVEVSKGJvb2wsICAgICAgICB1cGJfYm9vbF9oYW5kbGVyZnVuYyosICAgICAgICBVUEJfSEFORExFUl9CT09MKTsKK1NFVFRFUihzdGFydHN0ciwgICAgdXBiX3N0YXJ0c3RyX2hhbmRsZXJmdW5jKiwgICAgVVBCX0hBTkRMRVJfU1RBUlRTVFIpOworU0VUVEVSKHN0cmluZywgICAgICB1cGJfc3RyaW5nX2hhbmRsZXJmdW5jKiwgICAgICBVUEJfSEFORExFUl9TVFJJTkcpOworU0VUVEVSKGVuZHN0ciwgICAgICB1cGJfZW5kZmllbGRfaGFuZGxlcmZ1bmMqLCAgICBVUEJfSEFORExFUl9FTkRTVFIpOworU0VUVEVSKHN0YXJ0c2VxLCAgICB1cGJfc3RhcnRmaWVsZF9oYW5kbGVyZnVuYyosICBVUEJfSEFORExFUl9TVEFSVFNFUSk7CitTRVRURVIoc3RhcnRzdWJtc2csIHVwYl9zdGFydGZpZWxkX2hhbmRsZXJmdW5jKiwgIFVQQl9IQU5ETEVSX1NUQVJUU1VCTVNHKTsKK1NFVFRFUihlbmRzdWJtc2csICAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jKiwgICAgVVBCX0hBTkRMRVJfRU5EU1VCTVNHKTsKK1NFVFRFUihlbmRzZXEsICAgICAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jKiwgICAgVVBCX0hBTkRMRVJfRU5EU0VRKTsKKworI3VuZGVmIFNFVFRFUgorCitib29sIHVwYl9oYW5kbGVyc19zZXRzdGFydG1zZyh1cGJfaGFuZGxlcnMgKmgsIHVwYl9zdGFydG1zZ19oYW5kbGVyZnVuYyAqZnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyYXR0ciAqYXR0cikgeworICByZXR1cm4gZG9zZXQoaCwgVVBCX1NUQVJUTVNHX1NFTEVDVE9SLCBOVUxMLCBVUEJfSEFORExFUl9JTlQzMiwKKyAgICAgICAgICAgICAgICh1cGJfZnVuYyAqKWZ1bmMsIGF0dHIpOworfQorCitib29sIHVwYl9oYW5kbGVyc19zZXRlbmRtc2codXBiX2hhbmRsZXJzICpoLCB1cGJfZW5kbXNnX2hhbmRsZXJmdW5jICpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyYXR0ciAqYXR0cikgeworICBhc3NlcnQoIXVwYl9oYW5kbGVyc19pc2Zyb3plbihoKSk7CisgIHJldHVybiBkb3NldChoLCBVUEJfRU5ETVNHX1NFTEVDVE9SLCBOVUxMLCBVUEJfSEFORExFUl9JTlQzMiwKKyAgICAgICAgICAgICAgICh1cGJfZnVuYyAqKWZ1bmMsIGF0dHIpOworfQorCitib29sIHVwYl9oYW5kbGVyc19zZXRzdWJoYW5kbGVycyh1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9oYW5kbGVycyAqc3ViKSB7CisgIGFzc2VydChzdWIpOworICBhc3NlcnQoIXVwYl9oYW5kbGVyc19pc2Zyb3plbihoKSk7CisgIGFzc2VydCh1cGJfZmllbGRkZWZfaXNzdWJtc2coZikpOworICBpZiAoU1VCSF9GKGgsIGYpKSByZXR1cm4gZmFsc2U7ICAvLyBDYW4ndCByZXNldC4KKyAgaWYgKFVQQl9VUENBU1QodXBiX2hhbmRsZXJzX21zZ2RlZihzdWIpKSAhPSB1cGJfZmllbGRkZWZfc3ViZGVmKGYpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIFNVQkhfRihoLCBmKSA9IHN1YjsKKyAgdXBiX3JlZjIoc3ViLCBoKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX2hhbmRsZXJzX2dldHN1YmhhbmRsZXJzKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBhc3NlcnQodXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpKTsKKyAgcmV0dXJuIFNVQkhfRihoLCBmKTsKK30KKworYm9vbCB1cGJfaGFuZGxlcnNfZ2V0YXR0cihjb25zdCB1cGJfaGFuZGxlcnMgKmgsIHVwYl9zZWxlY3Rvcl90IHNlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKSB7CisgIGlmICghdXBiX2hhbmRsZXJzX2dldGhhbmRsZXIoaCwgc2VsKSkKKyAgICByZXR1cm4gZmFsc2U7CisgICphdHRyID0gaC0+dGFibGVbc2VsXS5hdHRyOworICByZXR1cm4gdHJ1ZTsKK30KKworY29uc3QgdXBiX2hhbmRsZXJzICp1cGJfaGFuZGxlcnNfZ2V0c3ViaGFuZGxlcnNfc2VsKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc2VsZWN0b3JfdCBzZWwpIHsKKyAgLy8gU1RBUlRTVUJNU0cgc2VsZWN0b3IgaW4gc2VsIGlzIHRoZSBmaWVsZCdzIHNlbGVjdG9yIGJhc2UuCisgIHJldHVybiBTVUJIKGgsIHNlbCAtIFVQQl9TVEFUSUNfU0VMRUNUT1JfQ09VTlQpOworfQorCitjb25zdCB1cGJfbXNnZGVmICp1cGJfaGFuZGxlcnNfbXNnZGVmKGNvbnN0IHVwYl9oYW5kbGVycyAqaCkgeyByZXR1cm4gaC0+bXNnOyB9CisKK2Jvb2wgdXBiX2hhbmRsZXJzX2FkZGNsZWFudXAodXBiX2hhbmRsZXJzICpoLCB2b2lkICpwLCB1cGJfaGFuZGxlcmZyZWUgKmZ1bmMpIHsKKyAgaWYgKHVwYl9pbnR0YWJsZV9sb29rdXBwdHIoJmgtPmNsZWFudXBfLCBwLCBOVUxMKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIG9rID0gdXBiX2ludHRhYmxlX2luc2VydHB0cigmaC0+Y2xlYW51cF8sIHAsIHVwYl92YWx1ZV9mcHRyKGZ1bmMpKTsKKyAgVVBCX0FTU0VSVF9WQVIob2ssIG9rKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKworLyogIlN0YXRpYyIgbWV0aG9kcyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworYm9vbCB1cGJfaGFuZGxlcnNfZnJlZXplKHVwYl9oYW5kbGVycyAqY29uc3QqaGFuZGxlcnMsIGludCBuLCB1cGJfc3RhdHVzICpzKSB7CisgIC8vIFRPRE86IHZlcmlmeSB3ZSBoYXZlIGEgdHJhbnNpdGl2ZSBjbG9zdXJlLgorICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgeworICAgIHVwYl9oYW5kbGVycyAqaCA9IGhhbmRsZXJzW2ldOworCisgICAgaWYgKCF1cGJfb2soJmgtPnN0YXR1c18pKSB7CisgICAgICB1cGJfc3RhdHVzX3NldGVycmYocywgImhhbmRsZXJzIGZvciBtZXNzYWdlICVzIGhhZCBlcnJvciBzdGF0dXM6ICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfbXNnZGVmX2Z1bGxuYW1lKHVwYl9oYW5kbGVyc19tc2dkZWYoaCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXNfZXJybXNnKCZoLT5zdGF0dXNfKSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gQ2hlY2sgdGhhdCB0aGVyZSBhcmUgbm8gY2xvc3VyZSBtaXNtYXRjaGVzIGR1ZSB0byBtaXNzaW5nIFN0YXJ0KiBoYW5kbGVycworICAgIC8vIG9yIHN1YmhhbmRsZXJzIHdpdGggZGlmZmVyZW50IHR5cGUtbGV2ZWwgdHlwZXMuCisgICAgdXBiX21zZ19maWVsZF9pdGVyIGo7CisgICAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmosIGgtPm1zZyk7CisgICAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmopOworICAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmopKSB7CisKKyAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZiA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaik7CisgICAgICBpZiAodXBiX2ZpZWxkZGVmX2lzc2VxKGYpKSB7CisgICAgICAgIGlmICghY2hlY2tzdGFydChoLCBmLCBVUEJfSEFORExFUl9TVEFSVFNFUSwgcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBpZiAodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGYpKSB7CisgICAgICAgIGlmICghY2hlY2tzdGFydChoLCBmLCBVUEJfSEFORExFUl9TVEFSVFNUUiwgcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBpZiAodXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpKSB7CisgICAgICAgIGJvb2wgaGFzaGFuZGxlciA9IGZhbHNlOworICAgICAgICBpZiAodXBiX2hhbmRsZXJzX2dldGhhbmRsZXIoCisgICAgICAgICAgICAgICAgaCwgaGFuZGxlcnNfZ2V0c2VsKGgsIGYsIFVQQl9IQU5ETEVSX1NUQVJUU1VCTVNHKSkgfHwKKyAgICAgICAgICAgIHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKAorICAgICAgICAgICAgICAgIGgsIGhhbmRsZXJzX2dldHNlbChoLCBmLCBVUEJfSEFORExFUl9FTkRTVUJNU0cpKSkgeworICAgICAgICAgIGhhc2hhbmRsZXIgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSAmJgorICAgICAgICAgICAgKHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKAorICAgICAgICAgICAgICAgICBoLCBoYW5kbGVyc19nZXRzZWwoaCwgZiwgVVBCX0hBTkRMRVJfU1RBUlRTRVEpKSB8fAorICAgICAgICAgICAgIHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKAorICAgICAgICAgICAgICAgICBoLCBoYW5kbGVyc19nZXRzZWwoaCwgZiwgVVBCX0hBTkRMRVJfRU5EU0VRKSkpKSB7CisgICAgICAgICAgaGFzaGFuZGxlciA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaGFzaGFuZGxlciAmJiAhdXBiX2hhbmRsZXJzX2dldHN1YmhhbmRsZXJzKGgsIGYpKSB7CisgICAgICAgICAgLy8gRm9yIG5vdyB3ZSBhZGQgYW4gZW1wdHkgc3ViaGFuZGxlcnMgaW4gdGhpcyBjYXNlLiAgSXQgbWFrZXMgdGhlCisgICAgICAgICAgLy8gZGVjb2RlciBjb2RlIGdlbmVyYXRvciBzaW1wbGVyLCBiZWNhdXNlIGl0IG9ubHkgaGFzIHRvIGhhbmRsZSB0d28KKyAgICAgICAgICAvLyBjYXNlcyAoc3VibWVzc2FnZSBoYXMgaGFuZGxlcnMgb3Igbm90KSBhcyBvcHBvc2VkIHRvIHRocmVlCisgICAgICAgICAgLy8gKHN1Ym1lc3NhZ2UgaGFzIGhhbmRsZXJzIGluIGVuY2xvc2luZyBtZXNzYWdlIGJ1dCBubyBzdWJoYW5kbGVycykuCisgICAgICAgICAgLy8KKyAgICAgICAgICAvLyBUaGlzIG1ha2VzIHBhcnNpbmcgbGVzcyBlZmZpY2llbnQgaW4gdGhlIGNhc2UgdGhhdCB3ZSB3YW50IHRvCisgICAgICAgICAgLy8gbm90aWNlIGEgc3VibWVzc2FnZSBidXQgc2tpcCBpdHMgY29udGVudHMgKGxpa2UgaWYgd2UncmUgdGVzdGluZworICAgICAgICAgIC8vIGZvciBzdWJtZXNzYWdlIHByZXNlbmNlIG9yIGNvdW50aW5nIHRoZSBudW1iZXIgb2YgcmVwZWF0ZWQKKyAgICAgICAgICAvLyBzdWJtZXNzYWdlcykuICBJbiB0aGlzIGNhc2Ugd2Ugd2lsbCBlbmQgdXAgcGFyc2luZyB0aGUgc3VibWVzc2FnZQorICAgICAgICAgIC8vIGZpZWxkIGJ5IGZpZWxkIGFuZCB0aHJvd2luZyBhd2F5IHRoZSByZXN1bHRzIGZvciBlYWNoLCBpbnN0ZWFkIG9mCisgICAgICAgICAgLy8gc2tpcHBpbmcgdGhlIHdob2xlIGRlbGltaXRlZCB0aGluZyBhdCBvbmNlLiAgSWYgdGhpcyBpcyBhbiBpc3N1ZSB3ZQorICAgICAgICAgIC8vIGNhbiByZXZpc2l0IGl0LCBidXQgZG8gcmVtZW1iZXIgdGhhdCB0aGlzIG9ubHkgYXJpc2VzIHdoZW4geW91IGhhdmUKKyAgICAgICAgICAvLyBoYW5kbGVycyAoc3RhcnRzZXEvc3RhcnRzdWJtc2cvZW5kc3VibXNnL2VuZHNlcSkgc2V0IGZvciB0aGUKKyAgICAgICAgICAvLyBzdWJtZXNzYWdlIGJ1dCBubyBzdWJoYW5kbGVycy4gIFRoZSB1c2VzIGNhc2VzIGZvciB0aGlzIGFyZQorICAgICAgICAgIC8vIGxpbWl0ZWQuCisgICAgICAgICAgdXBiX2hhbmRsZXJzICpzdWIgPSB1cGJfaGFuZGxlcnNfbmV3KHVwYl9maWVsZGRlZl9tc2dzdWJkZWYoZiksICZzdWIpOworICAgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdWJoYW5kbGVycyhoLCBmLCBzdWIpOworICAgICAgICAgIHVwYl9oYW5kbGVyc191bnJlZihzdWIsICZzdWIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVE9ETyhoYWJlcm1hbik6IGNoZWNrIHR5cGUgb2Ygc3VibWVzc2FnZS4KKyAgICAgICAgLy8gVGhpcyBpcyBzbGlnaHRseSB0cmlja3k7IGFsc28gY29uc2lkZXIgd2hldGhlciB3ZSBzaG91bGQgY2hlY2sgdGhhdAorICAgICAgICAvLyB0aGV5IG1hdGNoIGF0IHNldHN1YmhhbmRsZXJzIHRpbWUuCisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKCF1cGJfcmVmY291bnRlZF9mcmVlemUoKHVwYl9yZWZjb3VudGVkKmNvbnN0KiloYW5kbGVycywgbiwgcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVBCX01BWF9IQU5ETEVSX0RFUFRIKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit1cGJfaGFuZGxlcnR5cGVfdCB1cGJfaGFuZGxlcnNfZ2V0cHJpbWl0aXZlaGFuZGxlcnR5cGUoY29uc3QgdXBiX2ZpZWxkZGVmICpmKSB7CisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUoZikpIHsKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgIGNhc2UgVVBCX1RZUEVfRU5VTTogcmV0dXJuIFVQQl9IQU5ETEVSX0lOVDMyOworICAgIGNhc2UgVVBCX1RZUEVfSU5UNjQ6IHJldHVybiBVUEJfSEFORExFUl9JTlQ2NDsKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjogcmV0dXJuIFVQQl9IQU5ETEVSX1VJTlQzMjsKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDogcmV0dXJuIFVQQl9IQU5ETEVSX1VJTlQ2NDsKKyAgICBjYXNlIFVQQl9UWVBFX0ZMT0FUOiByZXR1cm4gVVBCX0hBTkRMRVJfRkxPQVQ7CisgICAgY2FzZSBVUEJfVFlQRV9ET1VCTEU6IHJldHVybiBVUEJfSEFORExFUl9ET1VCTEU7CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOiByZXR1cm4gVVBCX0hBTkRMRVJfQk9PTDsKKyAgICBkZWZhdWx0OiBhc3NlcnQoZmFsc2UpOyByZXR1cm4gLTE7ICAvLyBJbnZhbGlkIGlucHV0LgorICB9Cit9CisKK2Jvb2wgdXBiX2hhbmRsZXJzX2dldHNlbGVjdG9yKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgdXBiX2hhbmRsZXJ0eXBlX3QgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zZWxlY3Rvcl90ICpzKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgVVBCX0hBTkRMRVJfSU5UMzI6CisgICAgY2FzZSBVUEJfSEFORExFUl9JTlQ2NDoKKyAgICBjYXNlIFVQQl9IQU5ETEVSX1VJTlQzMjoKKyAgICBjYXNlIFVQQl9IQU5ETEVSX1VJTlQ2NDoKKyAgICBjYXNlIFVQQl9IQU5ETEVSX0ZMT0FUOgorICAgIGNhc2UgVVBCX0hBTkRMRVJfRE9VQkxFOgorICAgIGNhc2UgVVBCX0hBTkRMRVJfQk9PTDoKKyAgICAgIGlmICghdXBiX2ZpZWxkZGVmX2lzcHJpbWl0aXZlKGYpIHx8CisgICAgICAgICAgdXBiX2hhbmRsZXJzX2dldHByaW1pdGl2ZWhhbmRsZXJ0eXBlKGYpICE9IHR5cGUpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICpzID0gZi0+c2VsZWN0b3JfYmFzZTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX0hBTkRMRVJfU1RSSU5HOgorICAgICAgaWYgKHVwYl9maWVsZGRlZl9pc3N0cmluZyhmKSkgeworICAgICAgICAqcyA9IGYtPnNlbGVjdG9yX2Jhc2U7CisgICAgICB9IGVsc2UgaWYgKHVwYl9maWVsZGRlZl9sYXp5KGYpKSB7CisgICAgICAgICpzID0gZi0+c2VsZWN0b3JfYmFzZSArIDM7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9IQU5ETEVSX1NUQVJUU1RSOgorICAgICAgaWYgKHVwYl9maWVsZGRlZl9pc3N0cmluZyhmKSB8fCB1cGJfZmllbGRkZWZfbGF6eShmKSkgeworICAgICAgICAqcyA9IGYtPnNlbGVjdG9yX2Jhc2UgKyAxOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfSEFORExFUl9FTkRTVFI6CisgICAgICBpZiAodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGYpIHx8IHVwYl9maWVsZGRlZl9sYXp5KGYpKSB7CisgICAgICAgICpzID0gZi0+c2VsZWN0b3JfYmFzZSArIDI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9IQU5ETEVSX1NUQVJUU0VROgorICAgICAgaWYgKCF1cGJfZmllbGRkZWZfaXNzZXEoZikpIHJldHVybiBmYWxzZTsKKyAgICAgICpzID0gZi0+c2VsZWN0b3JfYmFzZSAtIDI7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9IQU5ETEVSX0VORFNFUToKKyAgICAgIGlmICghdXBiX2ZpZWxkZGVmX2lzc2VxKGYpKSByZXR1cm4gZmFsc2U7CisgICAgICAqcyA9IGYtPnNlbGVjdG9yX2Jhc2UgLSAxOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfSEFORExFUl9TVEFSVFNVQk1TRzoKKyAgICAgIGlmICghdXBiX2ZpZWxkZGVmX2lzc3VibXNnKGYpKSByZXR1cm4gZmFsc2U7CisgICAgICAvLyBTZWxlY3RvcnMgZm9yIFNUQVJUU1VCTVNHIGFyZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0YWJsZSBzbyB0aGF0IHRoZQorICAgICAgLy8gc2VsZWN0b3IgY2FuIGFsc28gYmUgdXNlZCBhcyBhbiBpbmRleCBpbnRvIHRoZSAic3ViIiBhcnJheSBvZgorICAgICAgLy8gc3ViaGFuZGxlcnMuICBUaGUgaW5kZXhlcyBmb3IgdGhlIHR3byBpbnRvIHRoZXNlIHR3byB0YWJsZXMgYXJlIHRoZQorICAgICAgLy8gc2FtZSwgZXhjZXB0IHRoYXQgaW4gdGhlIGhhbmRsZXIgdGFibGUgdGhlIHN0YXRpYyBzZWxlY3RvcnMgY29tZSBmaXJzdC4KKyAgICAgICpzID0gZi0+aW5kZXhfICsgVVBCX1NUQVRJQ19TRUxFQ1RPUl9DT1VOVDsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX0hBTkRMRVJfRU5EU1VCTVNHOgorICAgICAgaWYgKCF1cGJfZmllbGRkZWZfaXNzdWJtc2coZikpIHJldHVybiBmYWxzZTsKKyAgICAgICpzID0gZi0+c2VsZWN0b3JfYmFzZTsKKyAgICAgIGJyZWFrOworICB9CisgIGFzc2VydCgqcyA8IHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZShmKS0+c2VsZWN0b3JfY291bnQpOworICByZXR1cm4gdHJ1ZTsKK30KKwordWludDMyX3QgdXBiX2hhbmRsZXJzX3NlbGVjdG9yYmFzZW9mZnNldChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9pc3NlcShmKSA/IDIgOiAwOworfQorCit1aW50MzJfdCB1cGJfaGFuZGxlcnNfc2VsZWN0b3Jjb3VudChjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgdWludDMyX3QgcmV0ID0gMTsKKyAgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSkgcmV0ICs9IDI7ICAgIC8vIFNUQVJUU0VRL0VORFNFUQorICBpZiAodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGYpKSByZXQgKz0gMjsgLy8gW1NUUklOR10vU1RBUlRTVFIvRU5EU1RSCisgIGlmICh1cGJfZmllbGRkZWZfaXNzdWJtc2coZikpIHsKKyAgICAvLyBFTkRTVUJNU0cgKFNUQVJUU1VCTVNHIGlzIGF0IHRhYmxlIGJlZ2lubmluZykKKyAgICByZXQgKz0gMDsKKyAgICBpZiAodXBiX2ZpZWxkZGVmX2xhenkoZikpIHsKKyAgICAgIC8vIFNUQVJUU1RSL0VORFNUUi9TVFJJTkcgKGZvciBsYXp5KQorICAgICAgcmV0ICs9IDM7CisgICAgfQorICB9CisgIHJldHVybiByZXQ7Cit9CisKKworLyogdXBiX2hhbmRsZXJhdHRyICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordm9pZCB1cGJfaGFuZGxlcmF0dHJfaW5pdCh1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsKKyAgdXBiX2hhbmRsZXJhdHRyIGZyb20gPSBVUEJfSEFORExFUkFUVFJfSU5JVElBTElaRVI7CisgIG1lbWNweShhdHRyLCAmZnJvbSwgc2l6ZW9mKCphdHRyKSk7Cit9CisKK3ZvaWQgdXBiX2hhbmRsZXJhdHRyX3VuaW5pdCh1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsKKyAgVVBCX1VOVVNFRChhdHRyKTsKK30KKworYm9vbCB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEodXBiX2hhbmRsZXJhdHRyICphdHRyLCBjb25zdCB2b2lkICpoZCkgeworICBhdHRyLT5oYW5kbGVyX2RhdGFfID0gaGQ7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9oYW5kbGVyYXR0cl9zZXRjbG9zdXJldHlwZSh1cGJfaGFuZGxlcmF0dHIgKmF0dHIsIGNvbnN0IHZvaWQgKnR5cGUpIHsKKyAgYXR0ci0+Y2xvc3VyZV90eXBlXyA9IHR5cGU7CisgIHJldHVybiB0cnVlOworfQorCitjb25zdCB2b2lkICp1cGJfaGFuZGxlcmF0dHJfY2xvc3VyZXR5cGUoY29uc3QgdXBiX2hhbmRsZXJhdHRyICphdHRyKSB7CisgIHJldHVybiBhdHRyLT5jbG9zdXJlX3R5cGVfOworfQorCitib29sIHVwYl9oYW5kbGVyYXR0cl9zZXRyZXR1cm5jbG9zdXJldHlwZSh1cGJfaGFuZGxlcmF0dHIgKmF0dHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICp0eXBlKSB7CisgIGF0dHItPnJldHVybl9jbG9zdXJlX3R5cGVfID0gdHlwZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NvbnN0IHZvaWQgKnVwYl9oYW5kbGVyYXR0cl9yZXR1cm5jbG9zdXJldHlwZShjb25zdCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsKKyAgcmV0dXJuIGF0dHItPnJldHVybl9jbG9zdXJlX3R5cGVfOworfQorCitib29sIHVwYl9oYW5kbGVyYXR0cl9zZXRhbHdheXNvayh1cGJfaGFuZGxlcmF0dHIgKmF0dHIsIGJvb2wgYWx3YXlzb2spIHsKKyAgYXR0ci0+YWx3YXlzb2tfID0gYWx3YXlzb2s7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9oYW5kbGVyYXR0cl9hbHdheXNvayhjb25zdCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsKKyAgcmV0dXJuIGF0dHItPmFsd2F5c29rXzsKK30KKworLyogdXBiX2J1ZmhhbmRsZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc2l6ZV90IHVwYl9idWZoYW5kbGVfb2Jqb2ZzKGNvbnN0IHVwYl9idWZoYW5kbGUgKmgpIHsKKyAgcmV0dXJuIGgtPm9iam9mc187Cit9CisKKy8qIHVwYl9ieXRlc2hhbmRsZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3ZvaWQgdXBiX2J5dGVzaGFuZGxlcl9pbml0KHVwYl9ieXRlc2hhbmRsZXIqIGgpIHsKKyAgbWVtc2V0KGgsIDAsIHNpemVvZigqaCkpOworfQorCisvLyBGb3Igd2hlbiB3ZSBzdXBwb3J0IGhhbmRsZXJmcmVlIGNhbGxiYWNrcy4KK3ZvaWQgdXBiX2J5dGVzaGFuZGxlcl91bmluaXQodXBiX2J5dGVzaGFuZGxlciogaCkgeworICBVUEJfVU5VU0VEKGgpOworfQorCitib29sIHVwYl9ieXRlc2hhbmRsZXJfc2V0c3RhcnRzdHIodXBiX2J5dGVzaGFuZGxlciAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMgKmZ1bmMsIHZvaWQgKmQpIHsKKyAgaC0+dGFibGVbVVBCX1NUQVJUU1RSX1NFTEVDVE9SXS5mdW5jID0gKHVwYl9mdW5jKilmdW5jOworICBoLT50YWJsZVtVUEJfU1RBUlRTVFJfU0VMRUNUT1JdLmF0dHIuaGFuZGxlcl9kYXRhXyA9IGQ7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9ieXRlc2hhbmRsZXJfc2V0c3RyaW5nKHVwYl9ieXRlc2hhbmRsZXIgKmgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdHJpbmdfaGFuZGxlcmZ1bmMgKmZ1bmMsIHZvaWQgKmQpIHsKKyAgaC0+dGFibGVbVVBCX1NUUklOR19TRUxFQ1RPUl0uZnVuYyA9ICh1cGJfZnVuYyopZnVuYzsKKyAgaC0+dGFibGVbVVBCX1NUUklOR19TRUxFQ1RPUl0uYXR0ci5oYW5kbGVyX2RhdGFfID0gZDsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgdXBiX2J5dGVzaGFuZGxlcl9zZXRlbmRzdHIodXBiX2J5dGVzaGFuZGxlciAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jICpmdW5jLCB2b2lkICpkKSB7CisgIGgtPnRhYmxlW1VQQl9FTkRTVFJfU0VMRUNUT1JdLmZ1bmMgPSAodXBiX2Z1bmMqKWZ1bmM7CisgIGgtPnRhYmxlW1VQQl9FTkRTVFJfU0VMRUNUT1JdLmF0dHIuaGFuZGxlcl9kYXRhXyA9IGQ7CisgIHJldHVybiB0cnVlOworfQorLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAxMiBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogT3VyIGtleSBpbnZhcmlhbnRzIGFyZToKKyAqIDEuIHJlZmVyZW5jZSBjeWNsZXMgbmV2ZXIgc3BhbiBncm91cHMKKyAqIDIuIGZvciByZWYyKHRvLCBmcm9tKSwgd2UgaW5jcmVtZW50IHRvJ3MgY291bnQgaWZmIGdyb3VwKGZyb20pICE9IGdyb3VwKHRvKQorICoKKyAqIFRoZSBwcmV2aW91cyB0d28gYXJlIGhvdyB3ZSBhdm9pZCBsZWFraW5nIGN5Y2xlcy4gIE90aGVyIGltcG9ydGFudAorICogaW52YXJpYW50cyBhcmU6CisgKiAzLiBmb3IgbXV0YWJsZSBvYmplY3RzICJmcm9tIiBhbmQgInRvIiwgaWYgdGhlcmUgZXhpc3RzIGEgcmVmMih0bywgZnJvbSkKKyAqICAgIHRoaXMgaW1wbGllcyBncm91cChmcm9tKSA9PSBncm91cCh0bykuICAoSW4gcHJhY3RpY2UsIHdoYXQgd2UgaW1wbGVtZW50CisgKiAgICBpcyBldmVuIHN0cm9uZ2VyOyAiZnJvbSIgYW5kICJ0byIgd2lsbCBzaGFyZSBhIGdyb3VwIGlmIHRoZXJlIGhhcyAqZXZlcioKKyAqICAgIGJlZW4gYSByZWYyKHRvLCBmcm9tKSwgYnV0IGFsbCB0aGF0IGlzIG5lY2Vzc2FyeSBmb3IgY29ycmVjdG5lc3MgaXMgdGhlCisgKiAgICB3ZWFrZXIgb25lKS4KKyAqIDQuIG11dGFibGUgYW5kIGltbXV0YWJsZSBvYmplY3RzIGFyZSBuZXZlciBpbiB0aGUgc2FtZSBncm91cC4KKyAqLworCisKKyNpbmNsdWRlIDxzZXRqbXAuaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworc3RhdGljIHZvaWQgZnJlZW9iaih1cGJfcmVmY291bnRlZCAqbyk7CisKK2NvbnN0IGNoYXIgdW50cmFja2VkX3ZhbDsKK2NvbnN0IHZvaWQgKlVQQl9VTlRSQUNLRURfUkVGID0gJnVudHJhY2tlZF92YWw7CisKKy8qIGFyY2gtc3BlY2lmaWMgYXRvbWljIHByaW1pdGl2ZXMgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNpZmRlZiBVUEJfVEhSRUFEX1VOU0FGRSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKK3N0YXRpYyB2b2lkIGF0b21pY19pbmModWludDMyX3QgKmEpIHsgKCphKSsrOyB9CitzdGF0aWMgYm9vbCBhdG9taWNfZGVjKHVpbnQzMl90ICphKSB7IHJldHVybiAtLSgqYSkgPT0gMDsgfQorCisjZWxpZiBkZWZpbmVkKF9fR05VQ19fKSB8fCBkZWZpbmVkKF9fY2xhbmdfXykgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCitzdGF0aWMgdm9pZCBhdG9taWNfaW5jKHVpbnQzMl90ICphKSB7IF9fc3luY19mZXRjaF9hbmRfYWRkKGEsIDEpOyB9CitzdGF0aWMgYm9vbCBhdG9taWNfZGVjKHVpbnQzMl90ICphKSB7IHJldHVybiBfX3N5bmNfc3ViX2FuZF9mZXRjaChhLCAxKSA9PSAwOyB9CisKKyNlbGlmIGRlZmluZWQoV0lOMzIpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyNpbmNsdWRlIDxXaW5kb3dzLmg+CisKK3N0YXRpYyB2b2lkIGF0b21pY19pbmModXBiX2F0b21pY190ICphKSB7IEludGVybG9ja2VkSW5jcmVtZW50KCZhLT52YWwpOyB9CitzdGF0aWMgYm9vbCBhdG9taWNfZGVjKHVwYl9hdG9taWNfdCAqYSkgeworICByZXR1cm4gSW50ZXJsb2NrZWREZWNyZW1lbnQoJmEtPnZhbCkgPT0gMDsKK30KKworI2Vsc2UKKyNlcnJvciBBdG9taWMgcHJpbWl0aXZlcyBub3QgZGVmaW5lZCBmb3IgeW91ciBwbGF0Zm9ybS9DUFUuICBcCisgICAgICAgSW1wbGVtZW50IHRoZW0gb3IgY29tcGlsZSB3aXRoIFVQQl9USFJFQURfVU5TQUZFLgorI2VuZGlmCisKKy8vIEFsbCBzdGF0aWMgb2JqZWN0cyBwb2ludCB0byB0aGlzIHJlZmNvdW50LgorLy8gSXQgaXMgc3BlY2lhbC1jYXNlZCBpbiByZWYvdW5yZWYgYmVsb3cuCit1aW50MzJfdCBzdGF0aWNfcmVmY291bnQgPSAtMTsKKworLy8gV2UgY2FuIGF2b2lkIGF0b21pYyBvcHMgZm9yIHN0YXRpY2FsbHktZGVjbGFyZWQgb2JqZWN0cy4KKy8vIFRoaXMgaXMgYSBtaW5vciBvcHRpbWl6YXRpb24gYnV0IG5pY2Ugc2luY2Ugd2UgY2FuIGF2b2lkIGRlZ3JhZGluZyB1bmRlcgorLy8gY29udGVudGlvbiBpbiB0aGlzIGNhc2UuCisKK3N0YXRpYyB2b2lkIHJlZmdyb3VwKHVpbnQzMl90ICpncm91cCkgeworICBpZiAoZ3JvdXAgIT0gJnN0YXRpY19yZWZjb3VudCkKKyAgICBhdG9taWNfaW5jKGdyb3VwKTsKK30KKworc3RhdGljIGJvb2wgdW5yZWZncm91cCh1aW50MzJfdCAqZ3JvdXApIHsKKyAgaWYgKGdyb3VwID09ICZzdGF0aWNfcmVmY291bnQpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGF0b21pY19kZWMoZ3JvdXApOworICB9Cit9CisKKworLyogUmVmZXJlbmNlIHRyYWNraW5nIChkZWJ1ZyBvbmx5KSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2lmZGVmIFVQQl9ERUJVR19SRUZTCisKKyNpZmRlZiBVUEJfVEhSRUFEX1VOU0FGRQorCitzdGF0aWMgdm9pZCB1cGJfbG9jaygpIHt9CitzdGF0aWMgdm9pZCB1cGJfdW5sb2NrKCkge30KKworI2Vsc2UKKworLy8gVXNlciBtdXN0IGRlZmluZSBmdW5jdGlvbnMgdGhhdCBsb2NrL3VubG9jayBhIGdsb2JhbCBtdXRleCBhbmQgbGluayB0aGlzCisvLyBmaWxlIGFnYWluc3QgdGhlbS4KK3ZvaWQgdXBiX2xvY2soKTsKK3ZvaWQgdXBiX3VubG9jaygpOworCisjZW5kaWYKKworLy8gVVBCX0RFQlVHX1JFRlMgbW9kZSBjb3VudHMgb24gYmVpbmcgYWJsZSB0byBtYWxsb2MoKSBtZW1vcnkgaW4gc29tZQorLy8gY29kZS1wYXRocyB0aGF0IGNhbiBub3JtYWxseSBuZXZlciBmYWlsLCBsaWtlIHVwYl9yZWZjb3VudGVkX3JlZigpLiAgU2luY2UKKy8vIHdlIGhhdmUgbm8gd2F5IHRvIHByb3BhZ2FnZSBvdXQtb2YtbWVtb3J5IGVycm9ycyBiYWNrIHRvIHRoZSB1c2VyLCBhbmQgc2luY2UKKy8vIHRoZXNlIGVycm9ycyBjYW4gb25seSBvY2N1ciBpbiBVUEJfREVCVUdfUkVGUyBtb2RlLCB3ZSBpbW1lZGlhdGVseSBmYWlsLgorI2RlZmluZSBDSEVDS19PT00ocHJlZGljYXRlKSBpZiAoIShwcmVkaWNhdGUpKSB7IGFzc2VydChwcmVkaWNhdGUpOyBleGl0KDEpOyB9CisKK3R5cGVkZWYgc3RydWN0IHsKKyAgaW50IGNvdW50OyAgLy8gSG93IG1hbnkgcmVmcyB0aGVyZSBhcmUgKGR1cGxpY2F0ZXMgb25seSBhbGxvd2VkIGZvciByZWYyKS4KKyAgYm9vbCBpc19yZWYyOworfSB0cmFja2VkcmVmOworCitzdGF0aWMgdHJhY2tlZHJlZiAqdHJhY2tlZHJlZl9uZXcoYm9vbCBpc19yZWYyKSB7CisgIHRyYWNrZWRyZWYgKnJldCA9IG1hbGxvYyhzaXplb2YoKnJldCkpOworICBDSEVDS19PT00ocmV0KTsKKyAgcmV0LT5jb3VudCA9IDE7CisgIHJldC0+aXNfcmVmMiA9IGlzX3JlZjI7CisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyB2b2lkIHRyYWNrKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCBjb25zdCB2b2lkICpvd25lciwgYm9vbCByZWYyKSB7CisgIGFzc2VydChvd25lcik7CisgIGlmIChvd25lciA9PSBVUEJfVU5UUkFDS0VEX1JFRikgcmV0dXJuOworCisgIHVwYl9sb2NrKCk7CisgIHVwYl92YWx1ZSB2OworICBpZiAodXBiX2ludHRhYmxlX2xvb2t1cHB0cihyLT5yZWZzLCBvd25lciwgJnYpKSB7CisgICAgdHJhY2tlZHJlZiAqcmVmID0gdXBiX3ZhbHVlX2dldHB0cih2KTsKKyAgICAvLyBTaW5jZSB3ZSBhbGxvdyBtdWx0aXBsZSByZWYyJ3MgZm9yIHRoZSBzYW1lIHRvL2Zyb20gcGFpciB3aXRob3V0CisgICAgLy8gYWxsb2NhdGluZyBzZXBhcmF0ZSBtZW1vcnkgZm9yIGVhY2ggb25lLCB3ZSBsb3NlIHRoZSBmaW5lLWdyYWluZWQKKyAgICAvLyB0cmFja2luZyBiZWhhdmlvciB3ZSBnZXQgd2l0aCByZWd1bGFyIHJlZnMuICBTaW5jZSByZWYycyBvbmx5IGhhcHBlbgorICAgIC8vIGluc2lkZSB1cGIsIHdlJ2xsIGFjY2VwdCB0aGlzIGxpbWl0YXRpb24gdW50aWwvdW5sZXNzIHRoZXJlIGlzIGEgcmVhbGx5CisgICAgLy8gZGlmZmljdWx0IHVwYi1pbnRlcm5hbCBidWcgdGhhdCBjYW4ndCBiZSBmaWd1cmVkIG91dCB3aXRob3V0IGl0LgorICAgIGFzc2VydChyZWYyKTsKKyAgICBhc3NlcnQocmVmLT5pc19yZWYyKTsKKyAgICByZWYtPmNvdW50Kys7CisgIH0gZWxzZSB7CisgICAgdHJhY2tlZHJlZiAqcmVmID0gdHJhY2tlZHJlZl9uZXcocmVmMik7CisgICAgYm9vbCBvayA9IHVwYl9pbnR0YWJsZV9pbnNlcnRwdHIoci0+cmVmcywgb3duZXIsIHVwYl92YWx1ZV9wdHIocmVmKSk7CisgICAgQ0hFQ0tfT09NKG9rKTsKKyAgICBpZiAocmVmMikgeworICAgICAgLy8gV2Uga25vdyB0aGlzIGNhc3QgaXMgc2FmZSB3aGVuIGl0IGlzIGEgcmVmMiwgYmVjYXVzZSBpdCdzIGNvbWluZyBmcm9tCisgICAgICAvLyBhbm90aGVyIHJlZmNvdW50ZWQgb2JqZWN0LgorICAgICAgY29uc3QgdXBiX3JlZmNvdW50ZWQgKmZyb20gPSBvd25lcjsKKyAgICAgIGFzc2VydCghdXBiX2ludHRhYmxlX2xvb2t1cHB0cihmcm9tLT5yZWYycywgciwgTlVMTCkpOworICAgICAgb2sgPSB1cGJfaW50dGFibGVfaW5zZXJ0cHRyKGZyb20tPnJlZjJzLCByLCB1cGJfdmFsdWVfcHRyKE5VTEwpKTsKKyAgICAgIENIRUNLX09PTShvayk7CisgICAgfQorICB9CisgIHVwYl91bmxvY2soKTsKK30KKworc3RhdGljIHZvaWQgdW50cmFjayhjb25zdCB1cGJfcmVmY291bnRlZCAqciwgY29uc3Qgdm9pZCAqb3duZXIsIGJvb2wgcmVmMikgeworICBhc3NlcnQob3duZXIpOworICBpZiAob3duZXIgPT0gVVBCX1VOVFJBQ0tFRF9SRUYpIHJldHVybjsKKworICB1cGJfbG9jaygpOworICB1cGJfdmFsdWUgdjsKKyAgYm9vbCBmb3VuZCA9IHVwYl9pbnR0YWJsZV9sb29rdXBwdHIoci0+cmVmcywgb3duZXIsICZ2KTsKKyAgLy8gVGhpcyBhc3NlcnQgd2lsbCBmYWlsIGlmIGFuIG93bmVyIGF0dGVtcHRzIHRvIHJlbGVhc2UgYSByZWYgaXQgZGlkbid0IGhhdmUuCisgIFVQQl9BU1NFUlRfVkFSKGZvdW5kLCBmb3VuZCk7CisgIHRyYWNrZWRyZWYgKnJlZiA9IHVwYl92YWx1ZV9nZXRwdHIodik7CisgIGFzc2VydChyZWYtPmlzX3JlZjIgPT0gcmVmMik7CisgIGlmICgtLXJlZi0+Y291bnQgPT0gMCkgeworICAgIGZyZWUocmVmKTsKKyAgICB1cGJfaW50dGFibGVfcmVtb3ZlcHRyKHItPnJlZnMsIG93bmVyLCBOVUxMKTsKKyAgICBpZiAocmVmMikgeworICAgICAgLy8gV2Uga25vdyB0aGlzIGNhc3QgaXMgc2FmZSB3aGVuIGl0IGlzIGEgcmVmMiwgYmVjYXVzZSBpdCdzIGNvbWluZyBmcm9tCisgICAgICAvLyBhbm90aGVyIHJlZmNvdW50ZWQgb2JqZWN0LgorICAgICAgY29uc3QgdXBiX3JlZmNvdW50ZWQgKmZyb20gPSBvd25lcjsKKyAgICAgIGJvb2wgcmVtb3ZlZCA9IHVwYl9pbnR0YWJsZV9yZW1vdmVwdHIoZnJvbS0+cmVmMnMsIHIsIE5VTEwpOworICAgICAgYXNzZXJ0KHJlbW92ZWQpOworICAgIH0KKyAgfQorICB1cGJfdW5sb2NrKCk7Cit9CisKK3N0YXRpYyB2b2lkIGNoZWNrcmVmKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCBjb25zdCB2b2lkICpvd25lciwgYm9vbCByZWYyKSB7CisgIHVwYl9sb2NrKCk7CisgIHVwYl92YWx1ZSB2OworICBib29sIGZvdW5kID0gdXBiX2ludHRhYmxlX2xvb2t1cHB0cihyLT5yZWZzLCBvd25lciwgJnYpOworICBVUEJfQVNTRVJUX1ZBUihmb3VuZCwgZm91bmQpOworICB0cmFja2VkcmVmICpyZWYgPSB1cGJfdmFsdWVfZ2V0cHRyKHYpOworICBhc3NlcnQocmVmLT5pc19yZWYyID09IHJlZjIpOworICB1cGJfdW5sb2NrKCk7Cit9CisKKy8vIFBvcHVsYXRlcyB0aGUgZ2l2ZW4gVVBCX0NUWVBFX0lOVDMyIGludHRhYmxlIHdpdGggY291bnRzIG9mIHJlZjIncyB0aGF0CisvLyBvcmlnaW5hdGUgZnJvbSB0aGUgZ2l2ZW4gb3duZXIuCitzdGF0aWMgdm9pZCBnZXRyZWYycyhjb25zdCB1cGJfcmVmY291bnRlZCAqb3duZXIsIHVwYl9pbnR0YWJsZSAqdGFiKSB7CisgIHVwYl9sb2NrKCk7CisgIHVwYl9pbnR0YWJsZV9pdGVyIGk7CisgIHVwYl9pbnR0YWJsZV9iZWdpbigmaSwgb3duZXItPnJlZjJzKTsKKyAgZm9yKDsgIXVwYl9pbnR0YWJsZV9kb25lKCZpKTsgdXBiX2ludHRhYmxlX25leHQoJmkpKSB7CisgICAgdXBiX3JlZmNvdW50ZWQgKnRvID0gKHVwYl9yZWZjb3VudGVkKil1cGJfaW50dGFibGVfaXRlcl9rZXkoJmkpOworCisgICAgLy8gVG8gZ2V0IHRoZSBjb3VudCB3ZSBuZWVkIHRvIGxvb2sgaW4gdGhlIHRhcmdldCdzIHRhYmxlLgorICAgIHVwYl92YWx1ZSB2OworICAgIGJvb2wgZm91bmQgPSB1cGJfaW50dGFibGVfbG9va3VwcHRyKHRvLT5yZWZzLCBvd25lciwgJnYpOworICAgIGFzc2VydChmb3VuZCk7CisgICAgdHJhY2tlZHJlZiAqcmVmID0gdXBiX3ZhbHVlX2dldHB0cih2KTsKKyAgICB1cGJfdmFsdWUgY291bnQgPSB1cGJfdmFsdWVfaW50MzIocmVmLT5jb3VudCk7CisKKyAgICBib29sIG9rID0gdXBiX2ludHRhYmxlX2luc2VydHB0cih0YWIsIHRvLCBjb3VudCk7CisgICAgQ0hFQ0tfT09NKG9rKTsKKyAgfQorICB1cGJfdW5sb2NrKCk7Cit9CisKK3R5cGVkZWYgc3RydWN0IHsKKyAgdXBiX2ludHRhYmxlIHJlZjI7CisgIGNvbnN0IHVwYl9yZWZjb3VudGVkICpvYmo7Cit9IGNoZWNrX3N0YXRlOworCitzdGF0aWMgdm9pZCB2aXNpdF9jaGVjayhjb25zdCB1cGJfcmVmY291bnRlZCAqb2JqLCBjb25zdCB1cGJfcmVmY291bnRlZCAqc3Vib2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICBjaGVja19zdGF0ZSAqcyA9IGNsb3N1cmU7CisgIGFzc2VydChvYmogPT0gcy0+b2JqKTsKKyAgYXNzZXJ0KHN1Ym9iaik7CisgIHVwYl9pbnR0YWJsZSAqcmVmMiA9ICZzLT5yZWYyOworICB1cGJfdmFsdWUgdjsKKyAgYm9vbCByZW1vdmVkID0gdXBiX2ludHRhYmxlX3JlbW92ZXB0cihyZWYyLCBzdWJvYmosICZ2KTsKKyAgLy8gVGhlIGZvbGxvd2luZyBhc3NlcnRpb24gd2lsbCBmYWlsIGlmIHRoZSB2aXNpdCgpIGZ1bmN0aW9uIHZpc2l0cyBhIHN1Ym9iagorICAvLyB0aGF0IGl0IGRpZCBub3QgaGF2ZSBhIHJlZjIgb24sIG9yIHZpc2l0cyB0aGUgc2FtZSBzdWJvYmogdG9vIG1hbnkgdGltZXMuCisgIGFzc2VydChyZW1vdmVkKTsKKyAgaW50MzJfdCBuZXdjb3VudCA9IHVwYl92YWx1ZV9nZXRpbnQzMih2KSAtIDE7CisgIGlmIChuZXdjb3VudCA+IDApIHsKKyAgICB1cGJfaW50dGFibGVfaW5zZXJ0KHJlZjIsICh1aW50cHRyX3Qpc3Vib2JqLCB1cGJfdmFsdWVfaW50MzIobmV3Y291bnQpKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCB2aXNpdChjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWRfdmlzaXQgKnYsCisgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKSB7CisgIC8vIEluIERFQlVHX1JFRlMgbW9kZSB3ZSBrbm93IHdoYXQgZXhpc3RpbmcgcmVmMiByZWZzIHRoZXJlIGFyZSwgc28gd2Uga25vdworICAvLyBleGFjdGx5IHRoZSBzZXQgb2Ygbm9kZXMgdGhhdCB2aXNpdCgpIHNob3VsZCB2aXNpdC4gIFNvIHdlIHZlcmlmeSB2aXNpdCgpJ3MKKyAgLy8gY29ycmVjdG5lc3MgaGVyZS4KKyAgY2hlY2tfc3RhdGUgc3RhdGU7CisgIHN0YXRlLm9iaiA9IHI7CisgIGJvb2wgb2sgPSB1cGJfaW50dGFibGVfaW5pdCgmc3RhdGUucmVmMiwgVVBCX0NUWVBFX0lOVDMyKTsKKyAgQ0hFQ0tfT09NKG9rKTsKKyAgZ2V0cmVmMnMociwgJnN0YXRlLnJlZjIpOworCisgIC8vIFRoaXMgc2hvdWxkIHZpc2l0IGFueSBjaGlsZHJlbiBpbiB0aGUgcmVmMiB0YWJsZS4KKyAgaWYgKHItPnZ0YmwtPnZpc2l0KSByLT52dGJsLT52aXNpdChyLCB2aXNpdF9jaGVjaywgJnN0YXRlKTsKKworICAvLyBUaGlzIGFzc2VydGlvbiB3aWxsIGZhaWwgaWYgdGhlIHZpc2l0KCkgZnVuY3Rpb24gbWlzc2VkIGFueSBjaGlsZHJlbi4KKyAgYXNzZXJ0KHVwYl9pbnR0YWJsZV9jb3VudCgmc3RhdGUucmVmMikgPT0gMCk7CisgIHVwYl9pbnR0YWJsZV91bmluaXQoJnN0YXRlLnJlZjIpOworICBpZiAoci0+dnRibC0+dmlzaXQpIHItPnZ0YmwtPnZpc2l0KHIsIHYsIGNsb3N1cmUpOworfQorCitzdGF0aWMgYm9vbCB0cmFja2luaXQodXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgci0+cmVmcyA9IG1hbGxvYyhzaXplb2YoKnItPnJlZnMpKTsKKyAgci0+cmVmMnMgPSBtYWxsb2Moc2l6ZW9mKCpyLT5yZWYycykpOworICBpZiAoIXItPnJlZnMgfHwgIXItPnJlZjJzKSBnb3RvIGVycjE7CisKKyAgaWYgKCF1cGJfaW50dGFibGVfaW5pdChyLT5yZWZzLCBVUEJfQ1RZUEVfUFRSKSkgZ290byBlcnIxOworICBpZiAoIXVwYl9pbnR0YWJsZV9pbml0KHItPnJlZjJzLCBVUEJfQ1RZUEVfUFRSKSkgZ290byBlcnIyOworICByZXR1cm4gdHJ1ZTsKKworZXJyMjoKKyAgdXBiX2ludHRhYmxlX3VuaW5pdChyLT5yZWZzKTsKK2VycjE6CisgIGZyZWUoci0+cmVmcyk7CisgIGZyZWUoci0+cmVmMnMpOworICByZXR1cm4gZmFsc2U7Cit9CisKK3N0YXRpYyB2b2lkIHRyYWNrZnJlZShjb25zdCB1cGJfcmVmY291bnRlZCAqcikgeworICB1cGJfaW50dGFibGVfdW5pbml0KHItPnJlZnMpOworICB1cGJfaW50dGFibGVfdW5pbml0KHItPnJlZjJzKTsKKyAgZnJlZShyLT5yZWZzKTsKKyAgZnJlZShyLT5yZWYycyk7Cit9CisKKyNlbHNlCisKK3N0YXRpYyB2b2lkIHRyYWNrKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCBjb25zdCB2b2lkICpvd25lciwgYm9vbCByZWYyKSB7CisgIFVQQl9VTlVTRUQocik7CisgIFVQQl9VTlVTRUQob3duZXIpOworICBVUEJfVU5VU0VEKHJlZjIpOworfQorCitzdGF0aWMgdm9pZCB1bnRyYWNrKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCBjb25zdCB2b2lkICpvd25lciwgYm9vbCByZWYyKSB7CisgIFVQQl9VTlVTRUQocik7CisgIFVQQl9VTlVTRUQob3duZXIpOworICBVUEJfVU5VU0VEKHJlZjIpOworfQorCitzdGF0aWMgdm9pZCBjaGVja3JlZihjb25zdCB1cGJfcmVmY291bnRlZCAqciwgY29uc3Qgdm9pZCAqb3duZXIsIGJvb2wgcmVmMikgeworICBVUEJfVU5VU0VEKHIpOworICBVUEJfVU5VU0VEKG93bmVyKTsKKyAgVVBCX1VOVVNFRChyZWYyKTsKK30KKworc3RhdGljIGJvb2wgdHJhY2tpbml0KHVwYl9yZWZjb3VudGVkICpyKSB7CisgIFVQQl9VTlVTRUQocik7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgdm9pZCB0cmFja2ZyZWUoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgVVBCX1VOVVNFRChyKTsKK30KKworc3RhdGljIHZvaWQgdmlzaXQoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIHVwYl9yZWZjb3VudGVkX3Zpc2l0ICp2LAorICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICBpZiAoci0+dnRibC0+dmlzaXQpIHItPnZ0YmwtPnZpc2l0KHIsIHYsIGNsb3N1cmUpOworfQorCisjZW5kaWYgIC8vIFVQQl9ERUJVR19SRUZTCisKKworLyogZnJlZXplKCkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gVGhlIGZyZWV6ZSgpIG9wZXJhdGlvbiBpcyBieSBmYXIgdGhlIG1vc3QgY29tcGxpY2F0ZWQgcGFydCBvZiB0aGlzIHNjaGVtZS4KKy8vIFdlIGNvbXB1dGUgc3Ryb25nbHktY29ubmVjdGVkIGNvbXBvbmVudHMgYW5kIHRoZW4gbXV0YXRlIHRoZSBncmFwaCBzdWNoIHRoYXQKKy8vIHdlIHByZXNlcnZlIHRoZSBpbnZhcmlhbnRzIGRvY3VtZW50ZWQgYXQgdGhlIHRvcCBvZiB0aGlzIGZpbGUuICBBbmQgd2UgbXVzdAorLy8gaGFuZGxlIG91dC1vZi1tZW1vcnkgZXJyb3JzIGdyYWNlZnVsbHkgKHdpdGhvdXQgbGVhdmluZyB0aGUgZ3JhcGgKKy8vIGluY29uc2lzdGVudCksIHdoaWNoIGFkZHMgdG8gdGhlIGZ1bi4KKworLy8gVGhlIHN0YXRlIHVzZWQgYnkgdGhlIGZyZWV6ZSBvcGVyYXRpb24gKHNoYXJlZCBhY3Jvc3MgbWFueSBmdW5jdGlvbnMpLgordHlwZWRlZiBzdHJ1Y3QgeworICBpbnQgZGVwdGg7CisgIGludCBtYXhkZXB0aDsKKyAgdWludDY0X3QgaW5kZXg7CisgIC8vIE1hcHMgdXBiX3JlZmNvdW50ZWQqIC0+IGF0dHJpYnV0ZXMgKGNvbG9yLCBldGMpLiAgYXR0ciBsYXlvdXQgdmFyaWVzIGJ5CisgIC8vIGNvbG9yLgorICB1cGJfaW50dGFibGUgb2JqYXR0cjsKKyAgdXBiX2ludHRhYmxlIHN0YWNrOyAgIC8vIHN0YWNrIG9mIHVwYl9yZWZjb3VudGVkKiBmb3IgVGFyamFuJ3MgYWxnb3JpdGhtLgorICB1cGJfaW50dGFibGUgZ3JvdXBzOyAgLy8gYXJyYXkgb2YgdWludDMyX3QqLCBtYWxsb2MnZCByZWZjb3VudHMgZm9yIG5ldyBncm91cHMKKyAgdXBiX3N0YXR1cyAqc3RhdHVzOworICBqbXBfYnVmIGVycjsKK30gdGFyamFuOworCitzdGF0aWMgdm9pZCByZWxlYXNlX3JlZjIoY29uc3QgdXBiX3JlZmNvdW50ZWQgKm9iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfcmVmY291bnRlZCAqc3Vib2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpOworCisvLyBOb2RlIGF0dHJpYnV0ZXMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisvLyBBZnRlciBvdXIgYW5hbHlzaXMgcGhhc2UgYWxsIG5vZGVzIHdpbGwgYmUgZWl0aGVyIEdSQVkgb3IgV0hJVEUuCisKK3R5cGVkZWYgZW51bSB7CisgIEJMQUNLID0gMCwgIC8vIE9iamVjdCBoYXMgbm90IGJlZW4gc2Vlbi4KKyAgR1JBWSwgICAvLyBPYmplY3QgaGFzIGJlZW4gZm91bmQgdmlhIGEgcmVmZ3JvdXAgYnV0IG1heSBub3QgYmUgcmVhY2hhYmxlLgorICBHUkVFTiwgIC8vIE9iamVjdCBpcyByZWFjaGFibGUgYW5kIGlzIGN1cnJlbnRseSBvbiB0aGUgVGFyamFuIHN0YWNrLgorICBXSElURSwgIC8vIE9iamVjdCBpcyByZWFjaGFibGUgYW5kIGhhcyBiZWVuIGFzc2lnbmVkIGEgZ3JvdXAgKFNDQykuCit9IGNvbG9yX3Q7CisKK1VQQl9OT1JFVFVSTiBzdGF0aWMgdm9pZCBlcnIodGFyamFuICp0KSB7IGxvbmdqbXAodC0+ZXJyLCAxKTsgfQorVVBCX05PUkVUVVJOIHN0YXRpYyB2b2lkIG9vbSh0YXJqYW4gKnQpIHsKKyAgdXBiX3N0YXR1c19zZXRlcnJtc2codC0+c3RhdHVzLCAib3V0IG9mIG1lbW9yeSIpOworICBlcnIodCk7Cit9CisKK3N0YXRpYyB1aW50NjRfdCB0cnlnZXRhdHRyKGNvbnN0IHRhcmphbiAqdCwgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgdXBiX3ZhbHVlIHY7CisgIHJldHVybiB1cGJfaW50dGFibGVfbG9va3VwcHRyKCZ0LT5vYmphdHRyLCByLCAmdikgPworICAgICAgdXBiX3ZhbHVlX2dldHVpbnQ2NCh2KSA6IDA7Cit9CisKK3N0YXRpYyB1aW50NjRfdCBnZXRhdHRyKGNvbnN0IHRhcmphbiAqdCwgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgdXBiX3ZhbHVlIHY7CisgIGJvb2wgZm91bmQgPSB1cGJfaW50dGFibGVfbG9va3VwcHRyKCZ0LT5vYmphdHRyLCByLCAmdik7CisgIFVQQl9BU1NFUlRfVkFSKGZvdW5kLCBmb3VuZCk7CisgIHJldHVybiB1cGJfdmFsdWVfZ2V0dWludDY0KHYpOworfQorCitzdGF0aWMgdm9pZCBzZXRhdHRyKHRhcmphbiAqdCwgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIHVpbnQ2NF90IGF0dHIpIHsKKyAgdXBiX2ludHRhYmxlX3JlbW92ZXB0cigmdC0+b2JqYXR0ciwgciwgTlVMTCk7CisgIHVwYl9pbnR0YWJsZV9pbnNlcnRwdHIoJnQtPm9iamF0dHIsIHIsIHVwYl92YWx1ZV91aW50NjQoYXR0cikpOworfQorCitzdGF0aWMgY29sb3JfdCBjb2xvcih0YXJqYW4gKnQsIGNvbnN0IHVwYl9yZWZjb3VudGVkICpyKSB7CisgIHJldHVybiB0cnlnZXRhdHRyKHQsIHIpICYgMHgzOyAgLy8gQ29sb3IgaXMgYWx3YXlzIHN0b3JlZCBpbiB0aGUgbG93IDIgYml0cy4KK30KKworc3RhdGljIHZvaWQgc2V0X2dyYXkodGFyamFuICp0LCBjb25zdCB1cGJfcmVmY291bnRlZCAqcikgeworICBhc3NlcnQoY29sb3IodCwgcikgPT0gQkxBQ0spOworICBzZXRhdHRyKHQsIHIsIEdSQVkpOworfQorCisvLyBQdXNoZXMgYW4gb2JqIG9udG8gdGhlIFRhcmphbiBzdGFjayBhbmQgc2V0cyBpdCB0byBHUkVFTi4KK3N0YXRpYyB2b2lkIHB1c2godGFyamFuICp0LCBjb25zdCB1cGJfcmVmY291bnRlZCAqcikgeworICBhc3NlcnQoY29sb3IodCwgcikgPT0gQkxBQ0sgfHwgY29sb3IodCwgcikgPT0gR1JBWSk7CisgIC8vIFRoaXMgZGVmaW5lcyB0aGUgYXR0ciBsYXlvdXQgZm9yIHRoZSBHUkVFTiBzdGF0ZS4gICJpbmRleCIgYW5kICJsb3dsaW5rIgorICAvLyBnZXQgMzEgYml0cywgd2hpY2ggaXMgcGxlbnR5IChsaW1pdCBvZiAyQiBvYmplY3RzIGZyb3plbiBhdCBhIHRpbWUpLgorICBzZXRhdHRyKHQsIHIsIEdSRUVOIHwgKHQtPmluZGV4IDw8IDIpIHwgKHQtPmluZGV4IDw8IDMzKSk7CisgIGlmICgrK3QtPmluZGV4ID09IDB4ODAwMDAwMDApIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyh0LT5zdGF0dXMsICJ0b28gbWFueSBvYmplY3RzIHRvIGZyZWV6ZSIpOworICAgIGVycih0KTsKKyAgfQorICB1cGJfaW50dGFibGVfcHVzaCgmdC0+c3RhY2ssIHVwYl92YWx1ZV9wdHIoKHZvaWQqKXIpKTsKK30KKworLy8gUG9wcyBhbiBvYmogZnJvbSB0aGUgVGFyamFuIHN0YWNrIGFuZCBzZXRzIGl0IHRvIFdISVRFLCB3aXRoIGEgcHRyIHRvIGl0cworLy8gU0NDIGdyb3VwLgorc3RhdGljIHVwYl9yZWZjb3VudGVkICpwb3AodGFyamFuICp0KSB7CisgIHVwYl9yZWZjb3VudGVkICpyID0gdXBiX3ZhbHVlX2dldHB0cih1cGJfaW50dGFibGVfcG9wKCZ0LT5zdGFjaykpOworICBhc3NlcnQoY29sb3IodCwgcikgPT0gR1JFRU4pOworICAvLyBUaGlzIGRlZmluZXMgdGhlIGF0dHIgbGF5b3V0IGZvciBub2RlcyBpbiB0aGUgV0hJVEUgc3RhdGUuCisgIC8vIFRvcCBvZiBncm91cCBzdGFjayBpcyBbZ3JvdXAsIE5VTExdOyB3ZSBwb2ludCBhdCBncm91cC4KKyAgc2V0YXR0cih0LCByLCBXSElURSB8ICh1cGJfaW50dGFibGVfY291bnQoJnQtPmdyb3VwcykgLSAyKSA8PCA4KTsKKyAgcmV0dXJuIHI7Cit9CisKK3N0YXRpYyB2b2lkIHRhcmphbl9uZXdncm91cCh0YXJqYW4gKnQpIHsKKyAgdWludDMyX3QgKmdyb3VwID0gbWFsbG9jKHNpemVvZigqZ3JvdXApKTsKKyAgaWYgKCFncm91cCkgb29tKHQpOworICAvLyBQdXNoIGdyb3VwIGFuZCBlbXB0eSBncm91cCBsZWFkZXIgKHdlJ2xsIGZpbGwgaW4gbGVhZGVyIGxhdGVyKS4KKyAgaWYgKCF1cGJfaW50dGFibGVfcHVzaCgmdC0+Z3JvdXBzLCB1cGJfdmFsdWVfcHRyKGdyb3VwKSkgfHwKKyAgICAgICF1cGJfaW50dGFibGVfcHVzaCgmdC0+Z3JvdXBzLCB1cGJfdmFsdWVfcHRyKE5VTEwpKSkgeworICAgIGZyZWUoZ3JvdXApOworICAgIG9vbSh0KTsKKyAgfQorICAqZ3JvdXAgPSAwOworfQorCitzdGF0aWMgdWludDMyX3QgaWR4KHRhcmphbiAqdCwgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgYXNzZXJ0KGNvbG9yKHQsIHIpID09IEdSRUVOKTsKKyAgcmV0dXJuIChnZXRhdHRyKHQsIHIpID4+IDIpICYgMHg3RkZGRkZGRjsKK30KKworc3RhdGljIHVpbnQzMl90IGxvd2xpbmsodGFyamFuICp0LCBjb25zdCB1cGJfcmVmY291bnRlZCAqcikgeworICBpZiAoY29sb3IodCwgcikgPT0gR1JFRU4pIHsKKyAgICByZXR1cm4gZ2V0YXR0cih0LCByKSA+PiAzMzsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gVUlOVDMyX01BWDsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBzZXRfbG93bGluayh0YXJqYW4gKnQsIGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCB1aW50MzJfdCBsb3dsaW5rKSB7CisgIGFzc2VydChjb2xvcih0LCByKSA9PSBHUkVFTik7CisgIHNldGF0dHIodCwgciwgKCh1aW50NjRfdClsb3dsaW5rIDw8IDMzKSB8IChnZXRhdHRyKHQsIHIpICYgMHgxRkZGRkZGRkYpKTsKK30KKworc3RhdGljIHVpbnQzMl90ICpncm91cCh0YXJqYW4gKnQsIHVwYl9yZWZjb3VudGVkICpyKSB7CisgIGFzc2VydChjb2xvcih0LCByKSA9PSBXSElURSk7CisgIHVpbnQ2NF90IGdyb3VwbnVtID0gZ2V0YXR0cih0LCByKSA+PiA4OworICB1cGJfdmFsdWUgdjsKKyAgYm9vbCBmb3VuZCA9IHVwYl9pbnR0YWJsZV9sb29rdXAoJnQtPmdyb3VwcywgZ3JvdXBudW0sICZ2KTsKKyAgVVBCX0FTU0VSVF9WQVIoZm91bmQsIGZvdW5kKTsKKyAgcmV0dXJuIHVwYl92YWx1ZV9nZXRwdHIodik7Cit9CisKKy8vIElmIHRoZSBncm91cCBsZWFkZXIgZm9yIHRoaXMgb2JqZWN0J3MgZ3JvdXAgaGFzIG5vdCBwcmV2aW91c2x5IGJlZW4gc2V0LAorLy8gdGhlIGdpdmVuIG9iamVjdCBpcyBhc3NpZ25lZCB0byBiZSBpdHMgbGVhZGVyLgorc3RhdGljIHVwYl9yZWZjb3VudGVkICpncm91cGxlYWRlcih0YXJqYW4gKnQsIHVwYl9yZWZjb3VudGVkICpyKSB7CisgIGFzc2VydChjb2xvcih0LCByKSA9PSBXSElURSk7CisgIHVpbnQ2NF90IGxlYWRlcl9zbG90ID0gKGdldGF0dHIodCwgcikgPj4gOCkgKyAxOworICB1cGJfdmFsdWUgdjsKKyAgYm9vbCBmb3VuZCA9IHVwYl9pbnR0YWJsZV9sb29rdXAoJnQtPmdyb3VwcywgbGVhZGVyX3Nsb3QsICZ2KTsKKyAgVVBCX0FTU0VSVF9WQVIoZm91bmQsIGZvdW5kKTsKKyAgaWYgKHVwYl92YWx1ZV9nZXRwdHIodikpIHsKKyAgICByZXR1cm4gdXBiX3ZhbHVlX2dldHB0cih2KTsKKyAgfSBlbHNlIHsKKyAgICB1cGJfaW50dGFibGVfcmVtb3ZlKCZ0LT5ncm91cHMsIGxlYWRlcl9zbG90LCBOVUxMKTsKKyAgICB1cGJfaW50dGFibGVfaW5zZXJ0KCZ0LT5ncm91cHMsIGxlYWRlcl9zbG90LCB1cGJfdmFsdWVfcHRyKHIpKTsKKyAgICByZXR1cm4gcjsKKyAgfQorfQorCisKKy8vIFRhcmphbidzIGFsZ29yaXRobSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKy8vIFNlZToKKy8vICAgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9UYXJqYW4lMjdzX3N0cm9uZ2x5X2Nvbm5lY3RlZF9jb21wb25lbnRzX2FsZ29yaXRobQorc3RhdGljIHZvaWQgZG9fdGFyamFuKGNvbnN0IHVwYl9yZWZjb3VudGVkICpvYmosIHRhcmphbiAqdCk7CisKK3N0YXRpYyB2b2lkIHRhcmphbl92aXNpdChjb25zdCB1cGJfcmVmY291bnRlZCAqb2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9yZWZjb3VudGVkICpzdWJvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICB0YXJqYW4gKnQgPSBjbG9zdXJlOworICBpZiAoKyt0LT5kZXB0aCA+IHQtPm1heGRlcHRoKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJmKHQtPnN0YXR1cywgImdyYXBoIHRvbyBkZWVwIHRvIGZyZWV6ZSAoJWQpIiwgdC0+bWF4ZGVwdGgpOworICAgIGVycih0KTsKKyAgfSBlbHNlIGlmIChzdWJvYmotPmlzX2Zyb3plbiB8fCBjb2xvcih0LCBzdWJvYmopID09IFdISVRFKSB7CisgICAgLy8gRG8gbm90aGluZzogd2UgZG9uJ3Qgd2FudCB0byB2aXNpdCBvciBjb2xvciBhbHJlYWR5LWZyb3plbiBub2RlcywKKyAgICAvLyBhbmQgV0hJVEUgbm9kZXMgaGF2ZSBhbHJlYWR5IGJlZW4gYXNzaWduZWQgYSBTQ0MuCisgIH0gZWxzZSBpZiAoY29sb3IodCwgc3Vib2JqKSA8IEdSRUVOKSB7CisgICAgLy8gU3ViZGVmIGhhcyBub3QgeWV0IGJlZW4gdmlzaXRlZDsgcmVjdXJzZSBvbiBpdC4KKyAgICBkb190YXJqYW4oc3Vib2JqLCB0KTsKKyAgICBzZXRfbG93bGluayh0LCBvYmosIFVQQl9NSU4obG93bGluayh0LCBvYmopLCBsb3dsaW5rKHQsIHN1Ym9iaikpKTsKKyAgfSBlbHNlIGlmIChjb2xvcih0LCBzdWJvYmopID09IEdSRUVOKSB7CisgICAgLy8gU3ViZGVmIGlzIGluIHRoZSBzdGFjayBhbmQgaGVuY2UgaW4gdGhlIGN1cnJlbnQgU0NDLgorICAgIHNldF9sb3dsaW5rKHQsIG9iaiwgVVBCX01JTihsb3dsaW5rKHQsIG9iaiksIGlkeCh0LCBzdWJvYmopKSk7CisgIH0KKyAgLS10LT5kZXB0aDsKK30KKworc3RhdGljIHZvaWQgZG9fdGFyamFuKGNvbnN0IHVwYl9yZWZjb3VudGVkICpvYmosIHRhcmphbiAqdCkgeworICBpZiAoY29sb3IodCwgb2JqKSA9PSBCTEFDSykgeworICAgIC8vIFdlIGhhdmVuJ3Qgc2VlbiB0aGlzIG9iamVjdCdzIGdyb3VwOyBtYXJrIHRoZSB3aG9sZSBncm91cCBHUkFZLgorICAgIGNvbnN0IHVwYl9yZWZjb3VudGVkICpvID0gb2JqOworICAgIGRvIHsgc2V0X2dyYXkodCwgbyk7IH0gd2hpbGUgKChvID0gby0+bmV4dCkgIT0gb2JqKTsKKyAgfQorCisgIHB1c2godCwgb2JqKTsKKyAgdmlzaXQob2JqLCB0YXJqYW5fdmlzaXQsIHQpOworICBpZiAobG93bGluayh0LCBvYmopID09IGlkeCh0LCBvYmopKSB7CisgICAgdGFyamFuX25ld2dyb3VwKHQpOworICAgIHdoaWxlIChwb3AodCkgIT0gb2JqKQorICAgICAgOworICB9Cit9CisKKworLy8gZnJlZXplKCkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworc3RhdGljIHZvaWQgY3Jvc3NyZWYoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIGNvbnN0IHVwYl9yZWZjb3VudGVkICpzdWJvYmosCisgICAgICAgICAgICAgICAgICAgICB2b2lkICpfdCkgeworICB0YXJqYW4gKnQgPSBfdDsKKyAgYXNzZXJ0KGNvbG9yKHQsIHIpID4gQkxBQ0spOworICBpZiAoY29sb3IodCwgc3Vib2JqKSA+IEJMQUNLICYmIHItPmdyb3VwICE9IHN1Ym9iai0+Z3JvdXApIHsKKyAgICAvLyBQcmV2aW91c2x5IHRoaXMgcmVmIHdhcyBub3QgcmVmbGVjdGVkIGluIHN1Ym9iai0+Z3JvdXAgYmVjYXVzZSB0aGV5CisgICAgLy8gd2VyZSBpbiB0aGUgc2FtZSBncm91cDsgbm93IHRoYXQgdGhleSBhcmUgc3BsaXQgYSByZWYgbXVzdCBiZSB0YWtlbi4KKyAgICByZWZncm91cChzdWJvYmotPmdyb3VwKTsKKyAgfQorfQorCitzdGF0aWMgYm9vbCBmcmVlemUodXBiX3JlZmNvdW50ZWQgKmNvbnN0KnJvb3RzLCBpbnQgbiwgdXBiX3N0YXR1cyAqcywKKyAgICAgICAgICAgICAgICAgICBpbnQgbWF4ZGVwdGgpIHsKKyAgdm9sYXRpbGUgYm9vbCByZXQgPSBmYWxzZTsKKworICAvLyBXZSBydW4gaW4gdHdvIHBhc3NlcyBzbyB0aGF0IHdlIGNhbiBhbGxvY2F0ZSBhbGwgbWVtb3J5IGJlZm9yZSBwZXJmb3JtaW5nCisgIC8vIGFueSBtdXRhdGlvbiBvZiB0aGUgaW5wdXQgLS0gdGhpcyBhbGxvd3MgdXMgdG8gbGVhdmUgdGhlIGlucHV0IHVuY2hhbmdlZAorICAvLyBpbiB0aGUgY2FzZSBvZiBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlLgorICB0YXJqYW4gdDsKKyAgdC5pbmRleCA9IDA7CisgIHQuZGVwdGggPSAwOworICB0Lm1heGRlcHRoID0gbWF4ZGVwdGg7CisgIHQuc3RhdHVzID0gczsKKyAgaWYgKCF1cGJfaW50dGFibGVfaW5pdCgmdC5vYmphdHRyLCBVUEJfQ1RZUEVfVUlOVDY0KSkgZ290byBlcnIxOworICBpZiAoIXVwYl9pbnR0YWJsZV9pbml0KCZ0LnN0YWNrLCBVUEJfQ1RZUEVfUFRSKSkgZ290byBlcnIyOworICBpZiAoIXVwYl9pbnR0YWJsZV9pbml0KCZ0Lmdyb3VwcywgVVBCX0NUWVBFX1BUUikpIGdvdG8gZXJyMzsKKyAgaWYgKHNldGptcCh0LmVycikgIT0gMCkgZ290byBlcnI0OworCisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICBpZiAoY29sb3IoJnQsIHJvb3RzW2ldKSA8IEdSRUVOKSB7CisgICAgICBkb190YXJqYW4ocm9vdHNbaV0sICZ0KTsKKyAgICB9CisgIH0KKworICAvLyBJZiB3ZSd2ZSBtYWRlIGl0IHRoaXMgZmFyLCBubyBmdXJ0aGVyIGVycm9ycyBhcmUgcG9zc2libGUgc28gaXQncyBzYWZlIHRvCisgIC8vIG11dGF0ZSB0aGUgb2JqZWN0cyB3aXRob3V0IHJpc2sgb2YgbGVhdmluZyB0aGVtIGluIGFuIGluY29uc2lzdGVudCBzdGF0ZS4KKyAgcmV0ID0gdHJ1ZTsKKworICAvLyBUaGUgdHJhbnNmb3JtYXRpb24gdGhhdCBmb2xsb3dzIHJlcXVpcmVzIGNhcmUuICBUaGUgcHJlY29uZGl0aW9ucyBhcmU6CisgIC8vIC0gYWxsIG9iamVjdHMgaW4gYXR0ciBtYXAgYXJlIFdISVRFIG9yIEdSQVksIGFuZCBhcmUgaW4gbXV0YWJsZSBncm91cHMKKyAgLy8gICAoZ3JvdXBzIG9mIGFsbCBtdXRhYmxlIG9ianMpCisgIC8vIC0gbm8gcmVmMih0bywgZnJvbSkgcmVmcyBoYXZlIGluY3JlbWVudGVkIGNvdW50KHRvKSBpZiBib3RoICJ0byIgYW5kCisgIC8vICAgImZyb20iIGFyZSBpbiBvdXIgYXR0ciBtYXAgKHRoaXMgZm9sbG93cyBmcm9tIGludmFyaWFudHMgKDIpIGFuZCAoMykpCisKKyAgLy8gUGFzcyAxOiB3ZSByZW1vdmUgV0hJVEUgb2JqZWN0cyBmcm9tIHRoZWlyIG11dGFibGUgZ3JvdXBzLCBhbmQgYWRkIHRoZW0gdG8KKyAgLy8gbmV3IGdyb3VwcyAgYWNjb3JkaW5nIHRvIHRoZSBTQ0MncyB3ZSBjb21wdXRlZC4gIFRoZXNlIG5ldyBncm91cHMgd2lsbAorICAvLyBjb25zaXN0IG9mIG9ubHkgZnJvemVuIG9iamVjdHMuICBOb25lIHdpbGwgYmUgaW1tZWRpYXRlbHkgY29sbGVjdGlibGUsCisgIC8vIGJlY2F1c2UgV0hJVEUgb2JqZWN0cyBhcmUgYnkgZGVmaW5pdGlvbiByZWFjaGFibGUgZnJvbSBvbmUgb2YgInJvb3RzIiwKKyAgLy8gd2hpY2ggdGhlIGNhbGxlciBtdXN0IG93biByZWZzIG9uLgorICB1cGJfaW50dGFibGVfaXRlciBpOworICB1cGJfaW50dGFibGVfYmVnaW4oJmksICZ0Lm9iamF0dHIpOworICBmb3IoOyAhdXBiX2ludHRhYmxlX2RvbmUoJmkpOyB1cGJfaW50dGFibGVfbmV4dCgmaSkpIHsKKyAgICB1cGJfcmVmY291bnRlZCAqb2JqID0gKHVwYl9yZWZjb3VudGVkKil1cGJfaW50dGFibGVfaXRlcl9rZXkoJmkpOworICAgIC8vIFNpbmNlIHJlbW92YWwgZnJvbSBhIHNpbmdseS1saW5rZWQgbGlzdCByZXF1aXJlcyBhY2Nlc3MgdG8gdGhlIG9iamVjdCdzCisgICAgLy8gcHJlZGVjZXNzb3IsIHdlIGNvbnNpZGVyIG9iai0+bmV4dCBpbnN0ZWFkIG9mIG9iaiBmb3IgbW92aW5nLiAgV2l0aCB0aGUKKyAgICAvLyB3aGlsZSgpIGxvb3Agd2UgZ3VhcmFudGVlIHRoYXQgd2Ugd2lsbCB2aXNpdCBldmVyeSBub2RlJ3MgcHJlZGVjZXNzb3IuCisgICAgLy8gUHJvb2Y6CisgICAgLy8gIDEuIGV2ZXJ5IG5vZGUncyBwcmVkZWNlc3NvciBpcyBpbiBvdXIgYXR0ciBtYXAuCisgICAgLy8gIDIuIHRob3VnaCB0aGUgbG9vcCBib2R5IG1heSBjaGFuZ2UgYSBub2RlJ3MgcHJlZGVjZXNzb3IsIGl0IHdpbGwgb25seQorICAgIC8vICAgICBjaGFuZ2UgaXQgdG8gYmUgdGhlIG5vZGUgd2UgYXJlIGN1cnJlbnRseSBvcGVyYXRpbmcgb24sIHNvIHdpdGggYQorICAgIC8vICAgICB3aGlsZSgpIGxvb3Agd2UgZ3VhcmFudGVlIG91cnNlbHZlcyB0aGUgY2hhbmNlIHRvIHJlbW92ZSBlYWNoIG5vZGUuCisgICAgd2hpbGUgKGNvbG9yKCZ0LCBvYmotPm5leHQpID09IFdISVRFICYmCisgICAgICAgICAgIGdyb3VwKCZ0LCBvYmotPm5leHQpICE9IG9iai0+bmV4dC0+Z3JvdXApIHsKKyAgICAgIC8vIFJlbW92ZSBmcm9tIG9sZCBncm91cC4KKyAgICAgIHVwYl9yZWZjb3VudGVkICptb3ZlID0gb2JqLT5uZXh0OworICAgICAgaWYgKG9iaiA9PSBtb3ZlKSB7CisgICAgICAgIC8vIFJlbW92aW5nIHRoZSBsYXN0IG9iamVjdCBmcm9tIGEgZ3JvdXAuCisgICAgICAgIGFzc2VydCgqb2JqLT5ncm91cCA9PSBvYmotPmluZGl2aWR1YWxfY291bnQpOworICAgICAgICBmcmVlKG9iai0+Z3JvdXApOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgb2JqLT5uZXh0ID0gbW92ZS0+bmV4dDsKKyAgICAgICAgLy8gVGhpcyBtYXkgZGVjcmVhc2UgdG8gemVybzsgd2UnbGwgY29sbGVjdCBHUkFZIG9iamVjdHMgKGlmIGFueSkgdGhhdAorICAgICAgICAvLyByZW1haW4gaW4gdGhlIGdyb3VwIGluIHRoZSB0aGlyZCBwYXNzLgorICAgICAgICBhc3NlcnQoKm1vdmUtPmdyb3VwID49IG1vdmUtPmluZGl2aWR1YWxfY291bnQpOworICAgICAgICAqbW92ZS0+Z3JvdXAgLT0gbW92ZS0+aW5kaXZpZHVhbF9jb3VudDsKKyAgICAgIH0KKworICAgICAgLy8gQWRkIHRvIG5ldyBncm91cC4KKyAgICAgIHVwYl9yZWZjb3VudGVkICpsZWFkZXIgPSBncm91cGxlYWRlcigmdCwgbW92ZSk7CisgICAgICBpZiAobW92ZSA9PSBsZWFkZXIpIHsKKyAgICAgICAgLy8gRmlyc3Qgb2JqZWN0IGFkZGVkIHRvIG5ldyBncm91cCBpcyBpdHMgbGVhZGVyLgorICAgICAgICBtb3ZlLT5ncm91cCA9IGdyb3VwKCZ0LCBtb3ZlKTsKKyAgICAgICAgbW92ZS0+bmV4dCA9IG1vdmU7CisgICAgICAgICptb3ZlLT5ncm91cCA9IG1vdmUtPmluZGl2aWR1YWxfY291bnQ7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBHcm91cCBhbHJlYWR5IGhhcyBhdCBsZWFzdCBvbmUgb2JqZWN0IGluIGl0LgorICAgICAgICBhc3NlcnQobGVhZGVyLT5ncm91cCA9PSBncm91cCgmdCwgbW92ZSkpOworICAgICAgICBtb3ZlLT5ncm91cCA9IGdyb3VwKCZ0LCBtb3ZlKTsKKyAgICAgICAgbW92ZS0+bmV4dCA9IGxlYWRlci0+bmV4dDsKKyAgICAgICAgbGVhZGVyLT5uZXh0ID0gbW92ZTsKKyAgICAgICAgKm1vdmUtPmdyb3VwICs9IG1vdmUtPmluZGl2aWR1YWxfY291bnQ7CisgICAgICB9CisKKyAgICAgIG1vdmUtPmlzX2Zyb3plbiA9IHRydWU7CisgICAgfQorICB9CisKKyAgLy8gUGFzcyAyOiBHUkFZIGFuZCBXSElURSBvYmplY3RzICJvYmoiIHdpdGggcmVmMih0bywgb2JqKSByZWZlcmVuY2VzIG11c3QKKyAgLy8gaW5jcmVtZW50IGNvdW50KHRvKSBpZiBncm91cChvYmopICE9IGdyb3VwKHRvKSAod2hpY2ggY291bGQgbm93IGJlIHRoZQorICAvLyBjYXNlIGlmICJ0byIgd2FzIGp1c3QgZnJvemVuKS4KKyAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCAmdC5vYmphdHRyKTsKKyAgZm9yKDsgIXVwYl9pbnR0YWJsZV9kb25lKCZpKTsgdXBiX2ludHRhYmxlX25leHQoJmkpKSB7CisgICAgdXBiX3JlZmNvdW50ZWQgKm9iaiA9ICh1cGJfcmVmY291bnRlZCopdXBiX2ludHRhYmxlX2l0ZXJfa2V5KCZpKTsKKyAgICB2aXNpdChvYmosIGNyb3NzcmVmLCAmdCk7CisgIH0KKworICAvLyBQYXNzIDM6IEdSQVkgb2JqZWN0cyBhcmUgY29sbGVjdGVkIGlmIHRoZWlyIGdyb3VwJ3MgcmVmY291bnQgZHJvcHBlZCB0bworICAvLyB6ZXJvIHdoZW4gd2UgcmVtb3ZlZCBpdHMgd2hpdGUgbm9kZXMuICBUaGlzIGNhbiBoYXBwZW4gaWYgdGhleSBoYWQgb25seQorICAvLyBiZWVuIGtlcHQgYWxpdmUgYnkgdmlydHVlIG9mIHNoYXJpbmcgYSBncm91cCB3aXRoIGFuIG9iamVjdCB0aGF0IHdhcyBqdXN0CisgIC8vIGZyb3plbi4KKyAgLy8KKyAgLy8gSXQgaXMgaW1wb3J0YW50IHRoYXQgd2UgZG8gdGhpcyBsYXN0LCBzaW5jZSB0aGUgR1JBWSBvYmplY3QncyBmcmVlKCkKKyAgLy8gZnVuY3Rpb24gY291bGQgY2FsbCB1bnJlZjIoKSBvbiBqdXN0LWZyb3plbiBvYmplY3RzLCB3aGljaCB3aWxsIGRlY3JlbWVudAorICAvLyByZWZzIHRoYXQgd2VyZSBhZGRlZCBpbiBwYXNzIDIuCisgIHVwYl9pbnR0YWJsZV9iZWdpbigmaSwgJnQub2JqYXR0cik7CisgIGZvcig7ICF1cGJfaW50dGFibGVfZG9uZSgmaSk7IHVwYl9pbnR0YWJsZV9uZXh0KCZpKSkgeworICAgIHVwYl9yZWZjb3VudGVkICpvYmogPSAodXBiX3JlZmNvdW50ZWQqKXVwYl9pbnR0YWJsZV9pdGVyX2tleSgmaSk7CisgICAgaWYgKG9iai0+Z3JvdXAgPT0gTlVMTCB8fCAqb2JqLT5ncm91cCA9PSAwKSB7CisgICAgICBpZiAob2JqLT5ncm91cCkgeworICAgICAgICAvLyBXZSBlYWdlcmx5IGZyZWUoKSB0aGUgZ3JvdXAncyBjb3VudCAoc2luY2Ugd2UgY2FuJ3QgZWFzaWx5IGRldGVybWluZQorICAgICAgICAvLyB0aGUgZ3JvdXAncyByZW1haW5pbmcgc2l6ZSBpdCdzIHRoZSBlYXNpZXN0IHdheSB0byBlbnN1cmUgaXQgZ2V0cworICAgICAgICAvLyBkb25lKS4KKyAgICAgICAgZnJlZShvYmotPmdyb3VwKTsKKworICAgICAgICAvLyBWaXNpdCB0byByZWxlYXNlIHJlZjIncyAoZG9uZSBpbiBhIHNlcGFyYXRlIHBhc3Mgc2luY2UgcmVsZWFzZV9yZWYyCisgICAgICAgIC8vIGRlcGVuZHMgb24gby0+Z3JvdXAgYmVpbmcgdW5tb2RpZmllZCBzbyBpdCBjYW4gdGVzdCBtZXJnZWQoKSkuCisgICAgICAgIHVwYl9yZWZjb3VudGVkICpvID0gb2JqOworICAgICAgICBkbyB7IHZpc2l0KG8sIHJlbGVhc2VfcmVmMiwgTlVMTCk7IH0gd2hpbGUgKChvID0gby0+bmV4dCkgIT0gb2JqKTsKKworICAgICAgICAvLyBNYXJrICJncm91cCIgZmllbGRzIGFzIE5VTEwgc28gd2Uga25vdyB0byBmcmVlIHRoZSBvYmplY3RzIGxhdGVyIGluCisgICAgICAgIC8vIHRoaXMgbG9vcCwgYnV0IGFsc28gZG9uJ3QgdHJ5IHRvIGRlbGV0ZSB0aGUgZ3JvdXAgdHdpY2UuCisgICAgICAgIG8gPSBvYmo7CisgICAgICAgIGRvIHsgby0+Z3JvdXAgPSBOVUxMOyB9IHdoaWxlICgobyA9IG8tPm5leHQpICE9IG9iaik7CisgICAgICB9CisgICAgICBmcmVlb2JqKG9iaik7CisgICAgfQorICB9CisKK2VycjQ6CisgIGlmICghcmV0KSB7CisgICAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCAmdC5ncm91cHMpOworICAgIGZvcig7ICF1cGJfaW50dGFibGVfZG9uZSgmaSk7IHVwYl9pbnR0YWJsZV9uZXh0KCZpKSkKKyAgICAgIGZyZWUodXBiX3ZhbHVlX2dldHB0cih1cGJfaW50dGFibGVfaXRlcl92YWx1ZSgmaSkpKTsKKyAgfQorICB1cGJfaW50dGFibGVfdW5pbml0KCZ0Lmdyb3Vwcyk7CitlcnIzOgorICB1cGJfaW50dGFibGVfdW5pbml0KCZ0LnN0YWNrKTsKK2VycjI6CisgIHVwYl9pbnR0YWJsZV91bmluaXQoJnQub2JqYXR0cik7CitlcnIxOgorICByZXR1cm4gcmV0OworfQorCisKKy8qIE1pc2MgaW50ZXJuYWwgZnVuY3Rpb25zICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3N0YXRpYyBib29sIG1lcmdlZChjb25zdCB1cGJfcmVmY291bnRlZCAqciwgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIyKSB7CisgIHJldHVybiByLT5ncm91cCA9PSByMi0+Z3JvdXA7Cit9CisKK3N0YXRpYyB2b2lkIG1lcmdlKHVwYl9yZWZjb3VudGVkICpyLCB1cGJfcmVmY291bnRlZCAqZnJvbSkgeworICBpZiAobWVyZ2VkKHIsIGZyb20pKSByZXR1cm47CisgICpyLT5ncm91cCArPSAqZnJvbS0+Z3JvdXA7CisgIGZyZWUoZnJvbS0+Z3JvdXApOworICB1cGJfcmVmY291bnRlZCAqYmFzZSA9IGZyb207CisKKyAgLy8gU2V0IGFsbCByZWZjb3VudCBwb2ludGVycyBpbiB0aGUgImZyb20iIGNoYWluIHRvIHRoZSBtZXJnZWQgcmVmY291bnQuCisgIC8vCisgIC8vIFRPRE8oaGFiZXJtYW4pOiB0aGlzIGxpbmVhciBhbGdvcml0aG0gY2FuIHJlc3VsdCBpbiBhbiBvdmVyYWxsIE8obl4yKSBib3VuZAorICAvLyBpZiB0aGUgdXNlciBjb250aW51b3VzbHkgZXh0ZW5kcyBhIGdyb3VwIGJ5IG9uZSBvYmplY3QuICBQcmV2ZW50IHRoaXMgYnkKKyAgLy8gdXNpbmcgb25lIG9mIHRoZSB0ZWNobmlxdWVzIGluIHRoaXMgcGFwZXI6CisgIC8vICAgICBmdHA6Ly93d3cubmNlZGMub3JnL291dGdvaW5nL2dlb21vcnBoL2Rpbm8vb3JhbHMvcDI0NS10YXJqYW4ucGRmCisgIGRvIHsgZnJvbS0+Z3JvdXAgPSByLT5ncm91cDsgfSB3aGlsZSAoKGZyb20gPSBmcm9tLT5uZXh0KSAhPSBiYXNlKTsKKworICAvLyBNZXJnZSB0aGUgdHdvIGNpcmN1bGFybHkgbGlua2VkIGxpc3RzIGJ5IHN3YXBwaW5nIHRoZWlyIG5leHQgcG9pbnRlcnMuCisgIHVwYl9yZWZjb3VudGVkICp0bXAgPSByLT5uZXh0OworICByLT5uZXh0ID0gYmFzZS0+bmV4dDsKKyAgYmFzZS0+bmV4dCA9IHRtcDsKK30KKworc3RhdGljIHZvaWQgdW5yZWYoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIpOworCitzdGF0aWMgdm9pZCByZWxlYXNlX3JlZjIoY29uc3QgdXBiX3JlZmNvdW50ZWQgKm9iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfcmVmY291bnRlZCAqc3Vib2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgVVBCX1VOVVNFRChjbG9zdXJlKTsKKyAgdW50cmFjayhzdWJvYmosIG9iaiwgdHJ1ZSk7CisgIGlmICghbWVyZ2VkKG9iaiwgc3Vib2JqKSkgeworICAgIGFzc2VydChzdWJvYmotPmlzX2Zyb3plbik7CisgICAgdW5yZWYoc3Vib2JqKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCB1bnJlZihjb25zdCB1cGJfcmVmY291bnRlZCAqcikgeworICBpZiAodW5yZWZncm91cChyLT5ncm91cCkpIHsKKyAgICBmcmVlKHItPmdyb3VwKTsKKworICAgIC8vIEluIHR3byBwYXNzZXMsIHNpbmNlIHJlbGVhc2VfcmVmMiBuZWVkcyBhIGd1YXJhbnRlZSB0aGF0IGFueSBzdWJvYmpzCisgICAgLy8gYXJlIGFsaXZlLgorICAgIGNvbnN0IHVwYl9yZWZjb3VudGVkICpvID0gcjsKKyAgICBkbyB7IHZpc2l0KG8sIHJlbGVhc2VfcmVmMiwgTlVMTCk7IH0gd2hpbGUoKG8gPSBvLT5uZXh0KSAhPSByKTsKKworICAgIG8gPSByOworICAgIGRvIHsKKyAgICAgIGNvbnN0IHVwYl9yZWZjb3VudGVkICpuZXh0ID0gby0+bmV4dDsKKyAgICAgIGFzc2VydChvLT5pc19mcm96ZW4gfHwgby0+aW5kaXZpZHVhbF9jb3VudCA9PSAwKTsKKyAgICAgIGZyZWVvYmooKHVwYl9yZWZjb3VudGVkKilvKTsKKyAgICAgIG8gPSBuZXh0OworICAgIH0gd2hpbGUobyAhPSByKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBmcmVlb2JqKHVwYl9yZWZjb3VudGVkICpvKSB7CisgIHRyYWNrZnJlZShvKTsKKyAgby0+dnRibC0+ZnJlZSgodXBiX3JlZmNvdW50ZWQqKW8pOworfQorCisKKy8qIFB1YmxpYyBpbnRlcmZhY2UgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK2Jvb2wgdXBiX3JlZmNvdW50ZWRfaW5pdCh1cGJfcmVmY291bnRlZCAqciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3QgdXBiX3JlZmNvdW50ZWRfdnRibCAqdnRibCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpvd25lcikgeworICByLT5uZXh0ID0gcjsKKyAgci0+dnRibCA9IHZ0Ymw7CisgIHItPmluZGl2aWR1YWxfY291bnQgPSAwOworICByLT5pc19mcm96ZW4gPSBmYWxzZTsKKyAgci0+Z3JvdXAgPSBtYWxsb2Moc2l6ZW9mKCpyLT5ncm91cCkpOworICBpZiAoIXItPmdyb3VwKSByZXR1cm4gZmFsc2U7CisgICpyLT5ncm91cCA9IDA7CisgIGlmICghdHJhY2tpbml0KHIpKSB7CisgICAgZnJlZShyLT5ncm91cCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHVwYl9yZWZjb3VudGVkX3JlZihyLCBvd25lcik7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9yZWZjb3VudGVkX2lzZnJvemVuKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyKSB7CisgIHJldHVybiByLT5pc19mcm96ZW47Cit9CisKK3ZvaWQgdXBiX3JlZmNvdW50ZWRfcmVmKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCBjb25zdCB2b2lkICpvd25lcikgeworICB0cmFjayhyLCBvd25lciwgZmFsc2UpOworICBpZiAoIXItPmlzX2Zyb3plbikKKyAgICAoKHVwYl9yZWZjb3VudGVkKilyKS0+aW5kaXZpZHVhbF9jb3VudCsrOworICByZWZncm91cChyLT5ncm91cCk7Cit9CisKK3ZvaWQgdXBiX3JlZmNvdW50ZWRfdW5yZWYoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVudHJhY2sociwgb3duZXIsIGZhbHNlKTsKKyAgaWYgKCFyLT5pc19mcm96ZW4pCisgICAgKCh1cGJfcmVmY291bnRlZCopciktPmluZGl2aWR1YWxfY291bnQtLTsKKyAgdW5yZWYocik7Cit9CisKK3ZvaWQgdXBiX3JlZmNvdW50ZWRfcmVmMihjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWQgKmZyb20pIHsKKyAgYXNzZXJ0KCFmcm9tLT5pc19mcm96ZW4pOyAgLy8gTm9uLWNvbnN0IHBvaW50ZXIgaW1wbGllcyB0aGlzLgorICB0cmFjayhyLCBmcm9tLCB0cnVlKTsKKyAgaWYgKHItPmlzX2Zyb3plbikgeworICAgIHJlZmdyb3VwKHItPmdyb3VwKTsKKyAgfSBlbHNlIHsKKyAgICBtZXJnZSgodXBiX3JlZmNvdW50ZWQqKXIsIGZyb20pOworICB9Cit9CisKK3ZvaWQgdXBiX3JlZmNvdW50ZWRfdW5yZWYyKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCB1cGJfcmVmY291bnRlZCAqZnJvbSkgeworICBhc3NlcnQoIWZyb20tPmlzX2Zyb3plbik7ICAvLyBOb24tY29uc3QgcG9pbnRlciBpbXBsaWVzIHRoaXMuCisgIHVudHJhY2sociwgZnJvbSwgdHJ1ZSk7CisgIGlmIChyLT5pc19mcm96ZW4pIHsKKyAgICB1bnJlZihyKTsKKyAgfSBlbHNlIHsKKyAgICBhc3NlcnQobWVyZ2VkKHIsIGZyb20pKTsKKyAgfQorfQorCit2b2lkIHVwYl9yZWZjb3VudGVkX2RvbmF0ZXJlZigKKyAgICBjb25zdCB1cGJfcmVmY291bnRlZCAqciwgY29uc3Qgdm9pZCAqZnJvbSwgY29uc3Qgdm9pZCAqdG8pIHsKKyAgYXNzZXJ0KGZyb20gIT0gdG8pOworICBpZiAodG8gIT0gTlVMTCkKKyAgICB1cGJfcmVmY291bnRlZF9yZWYociwgdG8pOworICBpZiAoZnJvbSAhPSBOVUxMKQorICAgIHVwYl9yZWZjb3VudGVkX3VucmVmKHIsIGZyb20pOworfQorCit2b2lkIHVwYl9yZWZjb3VudGVkX2NoZWNrcmVmKGNvbnN0IHVwYl9yZWZjb3VudGVkICpyLCBjb25zdCB2b2lkICpvd25lcikgeworICBjaGVja3JlZihyLCBvd25lciwgZmFsc2UpOworfQorCitib29sIHVwYl9yZWZjb3VudGVkX2ZyZWV6ZSh1cGJfcmVmY291bnRlZCAqY29uc3Qqcm9vdHMsIGludCBuLCB1cGJfc3RhdHVzICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heGRlcHRoKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgYXNzZXJ0KCFyb290c1tpXS0+aXNfZnJvemVuKTsKKyAgfQorICByZXR1cm4gZnJlZXplKHJvb3RzLCBuLCBzLCBtYXhkZXB0aCk7Cit9CisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDEzIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqLworCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworLy8gRmFsbGJhY2sgaW1wbGVtZW50YXRpb24gaWYgdGhlIHNoaW0gaXMgbm90IHNwZWNpYWxpemVkIGJ5IHRoZSBKSVQuCisjZGVmaW5lIFNISU1fV1JJVEVSKHR5cGUsIGN0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGJvb2wgdXBiX3NoaW1fc2V0ICMjIHR5cGUgKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkLCBjdHlwZSB2YWwpIHsgICAgICAgICAgICBcCisgICAgdWludDhfdCAqbSA9IGM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY29uc3QgdXBiX3NoaW1fZGF0YSAqZCA9IGhkOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKGQtPmhhc2JpdCA+IDApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAqKHVpbnQ4X3QqKSZtW2QtPmhhc2JpdCAvIDhdIHw9IDEgPDwgKGQtPmhhc2JpdCAlIDgpOyAgICAgICAgICAgICAgICAgICBcCisgICAgKihjdHlwZSopJm1bZC0+b2Zmc2V0XSA9IHZhbDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisKK1NISU1fV1JJVEVSKGRvdWJsZSwgZG91YmxlKQorU0hJTV9XUklURVIoZmxvYXQsICBmbG9hdCkKK1NISU1fV1JJVEVSKGludDMyLCAgaW50MzJfdCkKK1NISU1fV1JJVEVSKGludDY0LCAgaW50NjRfdCkKK1NISU1fV1JJVEVSKHVpbnQzMiwgdWludDMyX3QpCitTSElNX1dSSVRFUih1aW50NjQsIHVpbnQ2NF90KQorU0hJTV9XUklURVIoYm9vbCwgICBib29sKQorI3VuZGVmIFNISU1fV1JJVEVSCisKK2Jvb2wgdXBiX3NoaW1fc2V0KHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBzaXplX3Qgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgaW50MzJfdCBoYXNiaXQpIHsKKyAgdXBiX3NoaW1fZGF0YSAqZCA9IG1hbGxvYyhzaXplb2YoKmQpKTsKKyAgaWYgKCFkKSByZXR1cm4gZmFsc2U7CisgIGQtPm9mZnNldCA9IG9mZnNldDsKKyAgZC0+aGFzYml0ID0gaGFzYml0OworCisgIHVwYl9oYW5kbGVyYXR0ciBhdHRyID0gVVBCX0hBTkRMRVJBVFRSX0lOSVRJQUxJWkVSOworICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoJmF0dHIsIGQpOworICB1cGJfaGFuZGxlcmF0dHJfc2V0YWx3YXlzb2soJmF0dHIsIHRydWUpOworICB1cGJfaGFuZGxlcnNfYWRkY2xlYW51cChoLCBkLCBmcmVlKTsKKworI2RlZmluZSBUWVBFKHUsIGwpIFwKKyAgY2FzZSBVUEJfVFlQRV8jI3U6IFwKKyAgICBvayA9IHVwYl9oYW5kbGVyc19zZXQjI2woaCwgZiwgdXBiX3NoaW1fc2V0IyNsLCAmYXR0cik7IGJyZWFrOworCisgIGJvb2wgb2sgPSBmYWxzZTsKKworICBzd2l0Y2ggKHVwYl9maWVsZGRlZl90eXBlKGYpKSB7CisgICAgVFlQRShJTlQ2NCwgIGludDY0KTsKKyAgICBUWVBFKElOVDMyLCAgaW50MzIpOworICAgIFRZUEUoRU5VTSwgICBpbnQzMik7CisgICAgVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgVFlQRShET1VCTEUsIGRvdWJsZSk7CisgICAgVFlQRShGTE9BVCwgIGZsb2F0KTsKKyAgICBUWVBFKEJPT0wsICAgYm9vbCk7CisgICAgZGVmYXVsdDogYXNzZXJ0KGZhbHNlKTsgYnJlYWs7CisgIH0KKyN1bmRlZiBUWVBFCisKKyAgdXBiX2hhbmRsZXJhdHRyX3VuaW5pdCgmYXR0cik7CisgIHJldHVybiBvazsKK30KKworY29uc3QgdXBiX3NoaW1fZGF0YSAqdXBiX3NoaW1fZ2V0ZGF0YShjb25zdCB1cGJfaGFuZGxlcnMgKmgsIHVwYl9zZWxlY3Rvcl90IHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9maWVsZHR5cGVfdCAqdHlwZSkgeworICB1cGJfZnVuYyAqZiA9IHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKGgsIHMpOworCisgIGlmICgodXBiX2ludDY0X2hhbmRsZXJmdW5jKilmID09IHVwYl9zaGltX3NldGludDY0KSB7CisgICAgKnR5cGUgPSBVUEJfVFlQRV9JTlQ2NDsKKyAgfSBlbHNlIGlmICgodXBiX2ludDMyX2hhbmRsZXJmdW5jKilmID09IHVwYl9zaGltX3NldGludDMyKSB7CisgICAgKnR5cGUgPSBVUEJfVFlQRV9JTlQzMjsKKyAgfSBlbHNlIGlmICgodXBiX3VpbnQ2NF9oYW5kbGVyZnVuYyopZiA9PSB1cGJfc2hpbV9zZXR1aW50NjQpIHsKKyAgICAqdHlwZSA9IFVQQl9UWVBFX1VJTlQ2NDsKKyAgfSBlbHNlIGlmICgodXBiX3VpbnQzMl9oYW5kbGVyZnVuYyopZiA9PSB1cGJfc2hpbV9zZXR1aW50MzIpIHsKKyAgICAqdHlwZSA9IFVQQl9UWVBFX1VJTlQzMjsKKyAgfSBlbHNlIGlmICgodXBiX2RvdWJsZV9oYW5kbGVyZnVuYyopZiA9PSB1cGJfc2hpbV9zZXRkb3VibGUpIHsKKyAgICAqdHlwZSA9IFVQQl9UWVBFX0RPVUJMRTsKKyAgfSBlbHNlIGlmICgodXBiX2Zsb2F0X2hhbmRsZXJmdW5jKilmID09IHVwYl9zaGltX3NldGZsb2F0KSB7CisgICAgKnR5cGUgPSBVUEJfVFlQRV9GTE9BVDsKKyAgfSBlbHNlIGlmICgodXBiX2Jvb2xfaGFuZGxlcmZ1bmMqKWYgPT0gdXBiX3NoaW1fc2V0Ym9vbCkgeworICAgICp0eXBlID0gVVBCX1RZUEVfQk9PTDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIHJldHVybiAoY29uc3QgdXBiX3NoaW1fZGF0YSopdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKGgsIHMpOworfQorLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAwOC0yMDEyIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqLworCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworYm9vbCB1cGJfc3ltdGFiX2lzZnJvemVuKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsKKyAgcmV0dXJuIHVwYl9yZWZjb3VudGVkX2lzZnJvemVuKFVQQl9VUENBU1QocykpOworfQorCit2b2lkIHVwYl9zeW10YWJfcmVmKGNvbnN0IHVwYl9zeW10YWIgKnMsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9yZWZjb3VudGVkX3JlZihVUEJfVVBDQVNUKHMpLCBvd25lcik7Cit9CisKK3ZvaWQgdXBiX3N5bXRhYl91bnJlZihjb25zdCB1cGJfc3ltdGFiICpzLCBjb25zdCB2b2lkICpvd25lcikgeworICB1cGJfcmVmY291bnRlZF91bnJlZihVUEJfVVBDQVNUKHMpLCBvd25lcik7Cit9CisKK3ZvaWQgdXBiX3N5bXRhYl9kb25hdGVyZWYoCisgICAgY29uc3QgdXBiX3N5bXRhYiAqcywgY29uc3Qgdm9pZCAqZnJvbSwgY29uc3Qgdm9pZCAqdG8pIHsKKyAgdXBiX3JlZmNvdW50ZWRfZG9uYXRlcmVmKFVQQl9VUENBU1QocyksIGZyb20sIHRvKTsKK30KKwordm9pZCB1cGJfc3ltdGFiX2NoZWNrcmVmKGNvbnN0IHVwYl9zeW10YWIgKnMsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9yZWZjb3VudGVkX2NoZWNrcmVmKFVQQl9VUENBU1QocyksIG93bmVyKTsKK30KKworc3RhdGljIHZvaWQgdXBiX3N5bXRhYl9mcmVlKHVwYl9yZWZjb3VudGVkICpyKSB7CisgIHVwYl9zeW10YWIgKnMgPSAodXBiX3N5bXRhYiopcjsKKyAgdXBiX3N0cnRhYmxlX2l0ZXIgaTsKKyAgdXBiX3N0cnRhYmxlX2JlZ2luKCZpLCAmcy0+c3ltdGFiKTsKKyAgZm9yICg7ICF1cGJfc3RydGFibGVfZG9uZSgmaSk7IHVwYl9zdHJ0YWJsZV9uZXh0KCZpKSkgeworICAgIGNvbnN0IHVwYl9kZWYgKmRlZiA9IHVwYl92YWx1ZV9nZXRwdHIodXBiX3N0cnRhYmxlX2l0ZXJfdmFsdWUoJmkpKTsKKyAgICB1cGJfZGVmX3VucmVmKGRlZiwgcyk7CisgIH0KKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmcy0+c3ltdGFiKTsKKyAgZnJlZShzKTsKK30KKworCit1cGJfc3ltdGFiICp1cGJfc3ltdGFiX25ldyhjb25zdCB2b2lkICpvd25lcikgeworICBzdGF0aWMgY29uc3Qgc3RydWN0IHVwYl9yZWZjb3VudGVkX3Z0YmwgdnRibCA9IHtOVUxMLCAmdXBiX3N5bXRhYl9mcmVlfTsKKyAgdXBiX3N5bXRhYiAqcyA9IG1hbGxvYyhzaXplb2YoKnMpKTsKKyAgdXBiX3JlZmNvdW50ZWRfaW5pdChVUEJfVVBDQVNUKHMpLCAmdnRibCwgb3duZXIpOworICB1cGJfc3RydGFibGVfaW5pdCgmcy0+c3ltdGFiLCBVUEJfQ1RZUEVfUFRSKTsKKyAgcmV0dXJuIHM7Cit9CisKK3ZvaWQgdXBiX3N5bXRhYl9mcmVlemUodXBiX3N5bXRhYiAqcykgeworICBhc3NlcnQoIXVwYl9zeW10YWJfaXNmcm96ZW4ocykpOworICB1cGJfcmVmY291bnRlZCAqciA9IFVQQl9VUENBU1Qocyk7CisgIC8vIFRoZSBzeW10YWIgZG9lcyBub3QgdGFrZSByZWYyJ3MgKHNlZSByZWZjb3VudGVkLmgpIG9uIHRoZSBkZWZzLCBiZWNhdXNlCisgIC8vIGRlZnMgY2Fubm90IHJlZmVyIGJhY2sgdG8gdGhlIHRhYmxlIGFuZCB0aGVyZWZvcmUgY2Fubm90IGNyZWF0ZSBjeWNsZXMuICBTbworICAvLyAwIHdpbGwgc3VmZmljZSBmb3IgbWF4ZGVwdGggaGVyZS4KKyAgYm9vbCBvayA9IHVwYl9yZWZjb3VudGVkX2ZyZWV6ZSgmciwgMSwgTlVMTCwgMCk7CisgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7Cit9CisKK2NvbnN0IHVwYl9kZWYgKnVwYl9zeW10YWJfbG9va3VwKGNvbnN0IHVwYl9zeW10YWIgKnMsIGNvbnN0IGNoYXIgKnN5bSkgeworICB1cGJfdmFsdWUgdjsKKyAgdXBiX2RlZiAqcmV0ID0gdXBiX3N0cnRhYmxlX2xvb2t1cCgmcy0+c3ltdGFiLCBzeW0sICZ2KSA/CisgICAgICB1cGJfdmFsdWVfZ2V0cHRyKHYpIDogTlVMTDsKKyAgcmV0dXJuIHJldDsKK30KKworY29uc3QgdXBiX21zZ2RlZiAqdXBiX3N5bXRhYl9sb29rdXBtc2coY29uc3QgdXBiX3N5bXRhYiAqcywgY29uc3QgY2hhciAqc3ltKSB7CisgIHVwYl92YWx1ZSB2OworICB1cGJfZGVmICpkZWYgPSB1cGJfc3RydGFibGVfbG9va3VwKCZzLT5zeW10YWIsIHN5bSwgJnYpID8KKyAgICAgIHVwYl92YWx1ZV9nZXRwdHIodikgOiBOVUxMOworICByZXR1cm4gZGVmID8gdXBiX2R5bmNhc3RfbXNnZGVmKGRlZikgOiBOVUxMOworfQorCitjb25zdCB1cGJfZW51bWRlZiAqdXBiX3N5bXRhYl9sb29rdXBlbnVtKGNvbnN0IHVwYl9zeW10YWIgKnMsIGNvbnN0IGNoYXIgKnN5bSkgeworICB1cGJfdmFsdWUgdjsKKyAgdXBiX2RlZiAqZGVmID0gdXBiX3N0cnRhYmxlX2xvb2t1cCgmcy0+c3ltdGFiLCBzeW0sICZ2KSA/CisgICAgICB1cGJfdmFsdWVfZ2V0cHRyKHYpIDogTlVMTDsKKyAgcmV0dXJuIGRlZiA/IHVwYl9keW5jYXN0X2VudW1kZWYoZGVmKSA6IE5VTEw7Cit9CisKKy8vIEdpdmVuIGEgc3ltYm9sIGFuZCB0aGUgYmFzZSBzeW1ib2wgaW5zaWRlIHdoaWNoIGl0IGlzIGRlZmluZWQsIGZpbmQgdGhlCisvLyBzeW1ib2wncyBkZWZpbml0aW9uIGluIHQuCitzdGF0aWMgdXBiX2RlZiAqdXBiX3Jlc29sdmVuYW1lKGNvbnN0IHVwYl9zdHJ0YWJsZSAqdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYmFzZSwgY29uc3QgY2hhciAqc3ltKSB7CisgIGlmKHN0cmxlbihzeW0pID09IDApIHJldHVybiBOVUxMOworICBpZihzeW1bMF0gPT0gJy4nKSB7CisgICAgLy8gU3ltYm9scyBzdGFydGluZyB3aXRoICcuJyBhcmUgYWJzb2x1dGUsIHNvIHdlIGRvIGEgc2luZ2xlIGxvb2t1cC4KKyAgICAvLyBTbGljZSB0byBvbWl0IHRoZSBsZWFkaW5nICcuJworICAgIHVwYl92YWx1ZSB2OworICAgIHJldHVybiB1cGJfc3RydGFibGVfbG9va3VwKHQsIHN5bSArIDEsICZ2KSA/IHVwYl92YWx1ZV9nZXRwdHIodikgOiBOVUxMOworICB9IGVsc2UgeworICAgIC8vIFJlbW92ZSBjb21wb25lbnRzIGZyb20gYmFzZSB1bnRpbCB3ZSBmaW5kIGFuIGVudHJ5IG9yIHJ1biBvdXQuCisgICAgLy8gVE9ETzogVGhpcyBicmFuY2ggaXMgdG90YWxseSBicm9rZW4sIGJ1dCBjdXJyZW50bHkgbm90IHVzZWQuCisgICAgKHZvaWQpYmFzZTsKKyAgICBhc3NlcnQoZmFsc2UpOworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IHVwYl9kZWYgKnVwYl9zeW10YWJfcmVzb2x2ZShjb25zdCB1cGJfc3ltdGFiICpzLCBjb25zdCBjaGFyICpiYXNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN5bSkgeworICB1cGJfZGVmICpyZXQgPSB1cGJfcmVzb2x2ZW5hbWUoJnMtPnN5bXRhYiwgYmFzZSwgc3ltKTsKKyAgcmV0dXJuIHJldDsKK30KKworLy8gU2VhcmNoZXMgZGVmIGFuZCBpdHMgY2hpbGRyZW4gdG8gZmluZCBkZWZzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFzIGFueQorLy8gZGVmIGluICJhZGR0YWIuIiAgUmV0dXJucyB0cnVlIGlmIGFueSB3aGVyZSBmb3VuZCwgYW5kIGFzIGEgc2lkZS1lZmZlY3QgYWRkcworLy8gZHVwbGljYXRlcyBvZiB0aGVzZSBkZWZzIGludG8gYWRkdGFiLgorLy8KKy8vIFdlIHVzZSBhIG1vZGlmaWVkIGRlcHRoLWZpcnN0IHRyYXZlcnNhbCB0aGF0IHRyYXZlcnNlcyBlYWNoIFNDQyAod2hpY2ggd2UKKy8vIGFscmVhZHkgY29tcHV0ZWQpIGFzIGlmIGl0IHdlcmUgYSBzaW5nbGUgbm9kZS4gIFRoaXMgYWxsb3dzIHVzIHRvIHRyYXZlcnNlCisvLyB0aGUgcG9zc2libHktY3ljbGljIGdyYXBoIGFzIGlmIGl0IHdlcmUgYSBEQUcgYW5kIHRvIGR1cCB0aGUgY29ycmVjdCBzZXQgb2YKKy8vIG5vZGVzIHdpdGggTyhuKSB0aW1lLgorc3RhdGljIGJvb2wgdXBiX3Jlc29sdmVfZGZzKGNvbnN0IHVwYl9kZWYgKmRlZiwgdXBiX3N0cnRhYmxlICphZGR0YWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqbmV3X293bmVyLCB1cGJfaW50dGFibGUgKnNlZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcykgeworICAvLyBNZW1vaXplIHJlc3VsdHMgb2YgdGhpcyBmdW5jdGlvbiBmb3IgZWZmaWNpZW5jeSAoc2luY2Ugd2UncmUgdHJhdmVyc2luZyBhCisgIC8vIERBRyB0aGlzIGlzIG5vdCBuZWVkZWQgdG8gbGltaXQgdGhlIGRlcHRoIG9mIHRoZSBzZWFyY2gpLgorICB1cGJfdmFsdWUgdjsKKyAgaWYgKHVwYl9pbnR0YWJsZV9sb29rdXAoc2VlbiwgKHVpbnRwdHJfdClkZWYsICZ2KSkKKyAgICByZXR1cm4gdXBiX3ZhbHVlX2dldGJvb2wodik7CisKKyAgLy8gVmlzaXQgc3VibWVzc2FnZXMgZm9yIGFsbCBtZXNzYWdlcyBpbiB0aGUgU0NDLgorICBib29sIG5lZWRfZHVwID0gZmFsc2U7CisgIGNvbnN0IHVwYl9kZWYgKmJhc2UgPSBkZWY7CisgIGRvIHsKKyAgICBhc3NlcnQodXBiX2RlZl9pc2Zyb3plbihkZWYpKTsKKyAgICBpZiAoZGVmLT50eXBlID09IFVQQl9ERUZfRklFTEQpIGNvbnRpbnVlOworICAgIHVwYl92YWx1ZSB2OworICAgIGlmICh1cGJfc3RydGFibGVfbG9va3VwKGFkZHRhYiwgdXBiX2RlZl9mdWxsbmFtZShkZWYpLCAmdikpIHsKKyAgICAgIG5lZWRfZHVwID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvLyBGb3IgbWVzc2FnZXMsIGNvbnRpbnVlIHRoZSByZWN1cnNpb24gYnkgdmlzaXRpbmcgYWxsIHN1YmRlZnMuCisgICAgY29uc3QgdXBiX21zZ2RlZiAqbSA9IHVwYl9keW5jYXN0X21zZ2RlZihkZWYpOworICAgIGlmIChtKSB7CisgICAgICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgICAgIGZvcih1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpLCBtKTsKKyAgICAgICAgICAhdXBiX21zZ19maWVsZF9kb25lKCZpKTsKKyAgICAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgICAgIHVwYl9maWVsZGRlZiAqZiA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaSk7CisgICAgICAgIGlmICghdXBiX2ZpZWxkZGVmX2hhc3N1YmRlZihmKSkgY29udGludWU7CisgICAgICAgIC8vIHw9IHRvIGF2b2lkIHNob3J0LWNpcmN1aXQ7IHdlIG5lZWQgaXRzIHNpZGUtZWZmZWN0cy4KKyAgICAgICAgbmVlZF9kdXAgfD0gdXBiX3Jlc29sdmVfZGZzKAorICAgICAgICAgICAgdXBiX2ZpZWxkZGVmX3N1YmRlZihmKSwgYWRkdGFiLCBuZXdfb3duZXIsIHNlZW4sIHMpOworICAgICAgICBpZiAoIXVwYl9vayhzKSkgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfSB3aGlsZSAoKGRlZiA9ICh1cGJfZGVmKilkZWYtPmJhc2UubmV4dCkgIT0gYmFzZSk7CisKKyAgaWYgKG5lZWRfZHVwKSB7CisgICAgLy8gRHVwIGFueSBkZWZzIHRoYXQgZG9uJ3QgYWxyZWFkeSBoYXZlIGVudHJpZXMgaW4gYWRkdGFiLgorICAgIGRlZiA9IGJhc2U7CisgICAgZG8geworICAgICAgaWYgKGRlZi0+dHlwZSA9PSBVUEJfREVGX0ZJRUxEKSBjb250aW51ZTsKKyAgICAgIGNvbnN0IGNoYXIgKm5hbWUgPSB1cGJfZGVmX2Z1bGxuYW1lKGRlZik7CisgICAgICBpZiAoIXVwYl9zdHJ0YWJsZV9sb29rdXAoYWRkdGFiLCBuYW1lLCBOVUxMKSkgeworICAgICAgICB1cGJfZGVmICpuZXdkZWYgPSB1cGJfZGVmX2R1cChkZWYsIG5ld19vd25lcik7CisgICAgICAgIGlmICghbmV3ZGVmKSBnb3RvIG9vbTsKKyAgICAgICAgbmV3ZGVmLT5jYW1lX2Zyb21fdXNlciA9IGZhbHNlOworICAgICAgICBpZiAoIXVwYl9zdHJ0YWJsZV9pbnNlcnQoYWRkdGFiLCBuYW1lLCB1cGJfdmFsdWVfcHRyKG5ld2RlZikpKQorICAgICAgICAgIGdvdG8gb29tOworICAgICAgfQorICAgIH0gd2hpbGUgKChkZWYgPSAodXBiX2RlZiopZGVmLT5iYXNlLm5leHQpICE9IGJhc2UpOworICB9CisKKyAgdXBiX2ludHRhYmxlX2luc2VydChzZWVuLCAodWludHB0cl90KWRlZiwgdXBiX3ZhbHVlX2Jvb2wobmVlZF9kdXApKTsKKyAgcmV0dXJuIG5lZWRfZHVwOworCitvb206CisgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHMsICJvdXQgb2YgbWVtb3J5Iik7CisgIHJldHVybiBmYWxzZTsKK30KKworLy8gVE9ETyhoYWJlcm1hbik6IHdlIG5lZWQgYSBsb3QgbW9yZSB0ZXN0aW5nIG9mIGVycm9yIGNvbmRpdGlvbnMuCisvLyBUaGUgY2FtZV9mcm9tX3VzZXIgc3R1ZmYgaW4gcGFydGljdWxhciBpcyBub3QgdGVzdGVkLgorYm9vbCB1cGJfc3ltdGFiX2FkZCh1cGJfc3ltdGFiICpzLCB1cGJfZGVmICpjb25zdCpkZWZzLCBpbnQgbiwgdm9pZCAqcmVmX2Rvbm9yLAorICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzdGF0dXMpIHsKKyAgYXNzZXJ0KCF1cGJfc3ltdGFiX2lzZnJvemVuKHMpKTsKKyAgdXBiX2RlZiAqKmFkZF9kZWZzID0gTlVMTDsKKyAgdXBiX3N0cnRhYmxlIGFkZHRhYjsKKyAgaWYgKCF1cGJfc3RydGFibGVfaW5pdCgmYWRkdGFiLCBVUEJfQ1RZUEVfUFRSKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgIm91dCBvZiBtZW1vcnkiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBBZGQgbmV3IGRlZnMgdG8gb3VyICJhZGQiIHNldC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICB1cGJfZGVmICpkZWYgPSBkZWZzW2ldOworICAgIGlmICh1cGJfZGVmX2lzZnJvemVuKGRlZikpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgImFkZGVkIGRlZnMgbXVzdCBiZSBtdXRhYmxlIik7CisgICAgICBnb3RvIGVycjsKKyAgICB9CisgICAgYXNzZXJ0KCF1cGJfZGVmX2lzZnJvemVuKGRlZikpOworICAgIGNvbnN0IGNoYXIgKmZ1bGxuYW1lID0gdXBiX2RlZl9mdWxsbmFtZShkZWYpOworICAgIGlmICghZnVsbG5hbWUpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKAorICAgICAgICAgIHN0YXR1cywgIkFub255bW91cyBkZWZzIGNhbm5vdCBiZSBhZGRlZCB0byBhIHN5bXRhYiIpOworICAgICAgZ290byBlcnI7CisgICAgfQorCisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX2R5bmNhc3RfZmllbGRkZWZfbXV0YWJsZShkZWYpOworCisgICAgaWYgKGYpIHsKKyAgICAgIGlmICghdXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlbmFtZShmKSkgeworICAgICAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGFuZGFsb25lIGZpZWxkZGVmcyBtdXN0IGhhdmUgYSBjb250YWluaW5nIHR5cGUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKGV4dGVuZGVlKSBuYW1lIHNldCIpOworICAgICAgICBnb3RvIGVycjsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKHVwYl9zdHJ0YWJsZV9sb29rdXAoJmFkZHRhYiwgZnVsbG5hbWUsIE5VTEwpKSB7CisgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihzdGF0dXMsICJDb25mbGljdGluZyBkZWZzIG5hbWVkICclcyciLCBmdWxsbmFtZSk7CisgICAgICAgIGdvdG8gZXJyOworICAgICAgfQorICAgICAgLy8gV2UgbmVlZCB0aGlzIHRvIGJhY2sgb3V0IHByb3Blcmx5LCBiZWNhdXNlIGlmIHRoZXJlIGlzIGEgZmFpbHVyZSB3ZQorICAgICAgLy8gbmVlZCB0byBkb25hdGUgdGhlIHJlZiBiYWNrIHRvIHRoZSBjYWxsZXIuCisgICAgICBkZWYtPmNhbWVfZnJvbV91c2VyID0gdHJ1ZTsKKyAgICAgIHVwYl9kZWZfZG9uYXRlcmVmKGRlZiwgcmVmX2Rvbm9yLCBzKTsKKyAgICAgIGlmICghdXBiX3N0cnRhYmxlX2luc2VydCgmYWRkdGFiLCBmdWxsbmFtZSwgdXBiX3ZhbHVlX3B0cihkZWYpKSkKKyAgICAgICAgZ290byBvb21fZXJyOworICAgIH0KKyAgfQorCisgIC8vIEFkZCBzdGFuZGFsb25lIGZpZWxkZGVmcyAoaWUuIGV4dGVuc2lvbnMpIHRvIHRoZSBhcHByb3ByaWF0ZSBtZXNzYWdlcy4KKyAgLy8gSWYgdGhlIGFwcHJvcHJpYXRlIG1lc3NhZ2Ugb25seSBleGlzdHMgaW4gdGhlIGV4aXN0aW5nIHN5bXRhYiwgZHVwbGljYXRlCisgIC8vIGl0IHNvIHdlIGhhdmUgYSBtdXRhYmxlIGNvcHkgd2UgY2FuIGFkZCB0aGUgZmllbGRzIHRvLgorICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgeworICAgIHVwYl9kZWYgKmRlZiA9IGRlZnNbaV07CisgICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX2R5bmNhc3RfZmllbGRkZWZfbXV0YWJsZShkZWYpOworICAgIGlmICghZikgY29udGludWU7CisgICAgY29uc3QgY2hhciAqbXNnbmFtZSA9IHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZW5hbWUoZik7CisgICAgLy8gV2UgdmFsaWRhdGVkIHRoaXMgZWFybGllciBpbiB0aGlzIGZ1bmN0aW9uLgorICAgIGFzc2VydChtc2duYW1lKTsKKworICAgIC8vIElmIHRoZSBleHRlbmRlZSBuYW1lIGlzIGFic29sdXRlbHkgcXVhbGlmaWVkLCBtb3ZlIHBhc3QgdGhlIGluaXRpYWwgIi4iLgorICAgIC8vIFRPRE8oaGFiZXJtYW4pOiBpdCBpcyBub3Qgb2J2aW91cyB3aGF0IGl0IHdvdWxkIG1lYW4gaWYgdGhpcyB3YXMgbm90CisgICAgLy8gYWJzb2x1dGVseSBxdWFsaWZpZWQuCisgICAgaWYgKG1zZ25hbWVbMF0gPT0gJy4nKSB7CisgICAgICBtc2duYW1lKys7CisgICAgfQorCisgICAgdXBiX3ZhbHVlIHY7CisgICAgdXBiX21zZ2RlZiAqbTsKKyAgICBpZiAodXBiX3N0cnRhYmxlX2xvb2t1cCgmYWRkdGFiLCBtc2duYW1lLCAmdikpIHsKKyAgICAgIC8vIEV4dGVuZGVlIGlzIGluIHRoZSBzZXQgb2YgZGVmcyB0aGUgdXNlciBhc2tlZCB1cyB0byBhZGQuCisgICAgICBtID0gdXBiX3ZhbHVlX2dldHB0cih2KTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTmVlZCB0byBmaW5kIGFuZCBkdXAgdGhlIGV4dGVuZGVlIGZyb20gdGhlIGV4aXN0aW5nIHN5bXRhYi4KKyAgICAgIGNvbnN0IHVwYl9tc2dkZWYgKmZyb3plbl9tID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgbXNnbmFtZSk7CisgICAgICBpZiAoIWZyb3plbl9tKSB7CisgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihzdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJpZWQgdG8gZXh0ZW5kIG1lc3NhZ2UgJXMgdGhhdCBkb2VzIG5vdCBleGlzdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gdGhpcyBTeW1ib2xUYWJsZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnbmFtZSk7CisgICAgICAgIGdvdG8gZXJyOworICAgICAgfQorICAgICAgbSA9IHVwYl9tc2dkZWZfZHVwKGZyb3plbl9tLCBzKTsKKyAgICAgIGlmICghbSkgZ290byBvb21fZXJyOworICAgICAgaWYgKCF1cGJfc3RydGFibGVfaW5zZXJ0KCZhZGR0YWIsIG1zZ25hbWUsIHVwYl92YWx1ZV9wdHIobSkpKSB7CisgICAgICAgIHVwYl9tc2dkZWZfdW5yZWYobSwgcyk7CisgICAgICAgIGdvdG8gb29tX2VycjsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoIXVwYl9tc2dkZWZfYWRkZmllbGQobSwgZiwgcmVmX2Rvbm9yLCBzdGF0dXMpKSB7CisgICAgICBnb3RvIGVycjsKKyAgICB9CisgIH0KKworICAvLyBBZGQgZHVwcyBvZiBhbnkgZXhpc3RpbmcgZGVmIHRoYXQgY2FuIHJlYWNoIGEgZGVmIHdpdGggdGhlIHNhbWUgbmFtZSBhcworICAvLyBhbnl0aGluZyBpbiBvdXIgImFkZCIgc2V0LgorICB1cGJfaW50dGFibGUgc2VlbjsKKyAgaWYgKCF1cGJfaW50dGFibGVfaW5pdCgmc2VlbiwgVVBCX0NUWVBFX0JPT0wpKSBnb3RvIG9vbV9lcnI7CisgIHVwYl9zdHJ0YWJsZV9pdGVyIGk7CisgIHVwYl9zdHJ0YWJsZV9iZWdpbigmaSwgJnMtPnN5bXRhYik7CisgIGZvciAoOyAhdXBiX3N0cnRhYmxlX2RvbmUoJmkpOyB1cGJfc3RydGFibGVfbmV4dCgmaSkpIHsKKyAgICB1cGJfZGVmICpkZWYgPSB1cGJfdmFsdWVfZ2V0cHRyKHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKCZpKSk7CisgICAgdXBiX3Jlc29sdmVfZGZzKGRlZiwgJmFkZHRhYiwgcywgJnNlZW4sIHN0YXR1cyk7CisgICAgaWYgKCF1cGJfb2soc3RhdHVzKSkgZ290byBlcnI7CisgIH0KKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmc2Vlbik7CisKKyAgLy8gTm93IHVzaW5nIHRoZSB0YWJsZSwgcmVzb2x2ZSBzeW1ib2xpYyByZWZlcmVuY2VzIGZvciBzdWJkZWZzLgorICB1cGJfc3RydGFibGVfYmVnaW4oJmksICZhZGR0YWIpOworICBmb3IgKDsgIXVwYl9zdHJ0YWJsZV9kb25lKCZpKTsgdXBiX3N0cnRhYmxlX25leHQoJmkpKSB7CisgICAgdXBiX2RlZiAqZGVmID0gdXBiX3ZhbHVlX2dldHB0cih1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaSkpOworICAgIHVwYl9tc2dkZWYgKm0gPSB1cGJfZHluY2FzdF9tc2dkZWZfbXV0YWJsZShkZWYpOworICAgIGlmICghbSkgY29udGludWU7CisgICAgLy8gVHlwZSBuYW1lcyBhcmUgcmVzb2x2ZWQgcmVsYXRpdmUgdG8gdGhlIG1lc3NhZ2UgaW4gd2hpY2ggdGhleSBhcHBlYXIuCisgICAgY29uc3QgY2hhciAqYmFzZSA9IHVwYl9tc2dkZWZfZnVsbG5hbWUobSk7CisKKyAgICB1cGJfbXNnX2ZpZWxkX2l0ZXIgajsKKyAgICBmb3IodXBiX21zZ19maWVsZF9iZWdpbigmaiwgbSk7CisgICAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmopOworICAgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmopKSB7CisgICAgICB1cGJfZmllbGRkZWYgKmYgPSB1cGJfbXNnX2l0ZXJfZmllbGQoJmopOworICAgICAgY29uc3QgY2hhciAqbmFtZSA9IHVwYl9maWVsZGRlZl9zdWJkZWZuYW1lKGYpOworICAgICAgaWYgKG5hbWUgJiYgIXVwYl9maWVsZGRlZl9zdWJkZWYoZikpIHsKKyAgICAgICAgLy8gVHJ5IHRoZSBsb29rdXAgaW4gdGhlIGN1cnJlbnQgc2V0IG9mIHRvLWJlLWFkZGVkIGRlZnMgZmlyc3QuIElmIG5vdAorICAgICAgICAvLyB0aGVyZSwgdHJ5IGV4aXN0aW5nIGRlZnMuCisgICAgICAgIHVwYl9kZWYgKnN1YmRlZiA9IHVwYl9yZXNvbHZlbmFtZSgmYWRkdGFiLCBiYXNlLCBuYW1lKTsKKyAgICAgICAgaWYgKHN1YmRlZiA9PSBOVUxMKSB7CisgICAgICAgICAgc3ViZGVmID0gdXBiX3Jlc29sdmVuYW1lKCZzLT5zeW10YWIsIGJhc2UsIG5hbWUpOworICAgICAgICB9CisgICAgICAgIGlmIChzdWJkZWYgPT0gTlVMTCkgeworICAgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZigKKyAgICAgICAgICAgICAgc3RhdHVzLCAiY291bGRuJ3QgcmVzb2x2ZSBuYW1lICclcycgaW4gbWVzc2FnZSAnJXMnIiwgbmFtZSwgYmFzZSk7CisgICAgICAgICAgZ290byBlcnI7CisgICAgICAgIH0gZWxzZSBpZiAoIXVwYl9maWVsZGRlZl9zZXRzdWJkZWYoZiwgc3ViZGVmLCBzdGF0dXMpKSB7CisgICAgICAgICAgZ290byBlcnI7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBXZSBuZWVkIGFuIGFycmF5IG9mIHRoZSBkZWZzIGluIGFkZHRhYiwgZm9yIHBhc3NpbmcgdG8gdXBiX2RlZl9mcmVlemUuCisgIGFkZF9kZWZzID0gbWFsbG9jKHNpemVvZih2b2lkKikgKiB1cGJfc3RydGFibGVfY291bnQoJmFkZHRhYikpOworICBpZiAoYWRkX2RlZnMgPT0gTlVMTCkgZ290byBvb21fZXJyOworICB1cGJfc3RydGFibGVfYmVnaW4oJmksICZhZGR0YWIpOworICBmb3IgKG4gPSAwOyAhdXBiX3N0cnRhYmxlX2RvbmUoJmkpOyB1cGJfc3RydGFibGVfbmV4dCgmaSkpIHsKKyAgICBhZGRfZGVmc1tuKytdID0gdXBiX3ZhbHVlX2dldHB0cih1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaSkpOworICB9CisKKyAgaWYgKCF1cGJfZGVmX2ZyZWV6ZShhZGRfZGVmcywgbiwgc3RhdHVzKSkgZ290byBlcnI7CisKKyAgLy8gVGhpcyBtdXN0IGJlIGRlbGF5ZWQgdW50aWwgYWxsIGVycm9ycyBoYXZlIGJlZW4gZGV0ZWN0ZWQsIHNpbmNlIGVycm9yCisgIC8vIHJlY292ZXJ5IGNvZGUgdXNlcyB0aGlzIHRhYmxlIHRvIGNsZWFudXAgZGVmcy4KKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmYWRkdGFiKTsKKworICAvLyBUT0RPKGhhYmVybWFuKSB3ZSBkb24ndCBwcm9wZXJseSBoYW5kbGUgZXJyb3JzIGFmdGVyIHRoaXMgcG9pbnQgKGxpa2UKKyAgLy8gT09NIGluIHVwYl9zdHJ0YWJsZV9pbnNlcnQoKSBiZWxvdykuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgdXBiX2RlZiAqZGVmID0gYWRkX2RlZnNbaV07CisgICAgY29uc3QgY2hhciAqbmFtZSA9IHVwYl9kZWZfZnVsbG5hbWUoZGVmKTsKKyAgICB1cGJfdmFsdWUgdjsKKyAgICBpZiAodXBiX3N0cnRhYmxlX3JlbW92ZSgmcy0+c3ltdGFiLCBuYW1lLCAmdikpIHsKKyAgICAgIGNvbnN0IHVwYl9kZWYgKmRlZiA9IHVwYl92YWx1ZV9nZXRwdHIodik7CisgICAgICB1cGJfZGVmX3VucmVmKGRlZiwgcyk7CisgICAgfQorICAgIGJvb2wgc3VjY2VzcyA9IHVwYl9zdHJ0YWJsZV9pbnNlcnQoJnMtPnN5bXRhYiwgbmFtZSwgdXBiX3ZhbHVlX3B0cihkZWYpKTsKKyAgICBVUEJfQVNTRVJUX1ZBUihzdWNjZXNzLCBzdWNjZXNzID09IHRydWUpOworICB9CisgIGZyZWUoYWRkX2RlZnMpOworICByZXR1cm4gdHJ1ZTsKKworb29tX2VycjoKKyAgdXBiX3N0YXR1c19zZXRlcnJtc2coc3RhdHVzLCAib3V0IG9mIG1lbW9yeSIpOworZXJyOiB7CisgICAgLy8gRm9yIGRlZnMgdGhlIHVzZXIgcGFzc2VkIGluLCB3ZSBuZWVkIHRvIGRvbmF0ZSB0aGUgcmVmcyBiYWNrLiAgRm9yIGRlZnMKKyAgICAvLyB3ZSBkdXAnZCwgd2UgbmVlZCB0byBqdXN0IHVucmVmIHRoZW0uCisgICAgdXBiX3N0cnRhYmxlX2l0ZXIgaTsKKyAgICB1cGJfc3RydGFibGVfYmVnaW4oJmksICZhZGR0YWIpOworICAgIGZvciAoOyAhdXBiX3N0cnRhYmxlX2RvbmUoJmkpOyB1cGJfc3RydGFibGVfbmV4dCgmaSkpIHsKKyAgICAgIHVwYl9kZWYgKmRlZiA9IHVwYl92YWx1ZV9nZXRwdHIodXBiX3N0cnRhYmxlX2l0ZXJfdmFsdWUoJmkpKTsKKyAgICAgIGJvb2wgY2FtZV9mcm9tX3VzZXIgPSBkZWYtPmNhbWVfZnJvbV91c2VyOworICAgICAgZGVmLT5jYW1lX2Zyb21fdXNlciA9IGZhbHNlOworICAgICAgaWYgKGNhbWVfZnJvbV91c2VyKSB7CisgICAgICAgIHVwYl9kZWZfZG9uYXRlcmVmKGRlZiwgcywgcmVmX2Rvbm9yKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHVwYl9kZWZfdW5yZWYoZGVmLCBzKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCgmYWRkdGFiKTsKKyAgZnJlZShhZGRfZGVmcyk7CisgIGFzc2VydCghdXBiX29rKHN0YXR1cykpOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIEl0ZXJhdGlvbi4KKworc3RhdGljIHZvaWQgYWR2YW5jZV90b19tYXRjaGluZyh1cGJfc3ltdGFiX2l0ZXIgKml0ZXIpIHsKKyAgaWYgKGl0ZXItPnR5cGUgPT0gVVBCX0RFRl9BTlkpCisgICAgcmV0dXJuOworCisgIHdoaWxlICghdXBiX3N0cnRhYmxlX2RvbmUoJml0ZXItPml0ZXIpICYmCisgICAgICAgICBpdGVyLT50eXBlICE9IHVwYl9zeW10YWJfaXRlcl9kZWYoaXRlciktPnR5cGUpIHsKKyAgICB1cGJfc3RydGFibGVfbmV4dCgmaXRlci0+aXRlcik7CisgIH0KK30KKwordm9pZCB1cGJfc3ltdGFiX2JlZ2luKHVwYl9zeW10YWJfaXRlciAqaXRlciwgY29uc3QgdXBiX3N5bXRhYiAqcywKKyAgICAgICAgICAgICAgICAgICAgICB1cGJfZGVmdHlwZV90IHR5cGUpIHsKKyAgdXBiX3N0cnRhYmxlX2JlZ2luKCZpdGVyLT5pdGVyLCAmcy0+c3ltdGFiKTsKKyAgaXRlci0+dHlwZSA9IHR5cGU7CisgIGFkdmFuY2VfdG9fbWF0Y2hpbmcoaXRlcik7Cit9CisKK3ZvaWQgdXBiX3N5bXRhYl9uZXh0KHVwYl9zeW10YWJfaXRlciAqaXRlcikgeworICB1cGJfc3RydGFibGVfbmV4dCgmaXRlci0+aXRlcik7CisgIGFkdmFuY2VfdG9fbWF0Y2hpbmcoaXRlcik7Cit9CisKK2Jvb2wgdXBiX3N5bXRhYl9kb25lKGNvbnN0IHVwYl9zeW10YWJfaXRlciAqaXRlcikgeworICByZXR1cm4gdXBiX3N0cnRhYmxlX2RvbmUoJml0ZXItPml0ZXIpOworfQorCitjb25zdCB1cGJfZGVmICp1cGJfc3ltdGFiX2l0ZXJfZGVmKGNvbnN0IHVwYl9zeW10YWJfaXRlciAqaXRlcikgeworICByZXR1cm4gdXBiX3ZhbHVlX2dldHB0cih1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaXRlci0+aXRlcikpOworfQorLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAwOSBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogSW1wbGVtZW50YXRpb24gaXMgaGVhdmlseSBpbnNwaXJlZCBieSBMdWEncyBsdGFibGUuYy4KKyAqLworCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2RlZmluZSBVUEJfTUFYQVJSU0laRSAxNiAgLy8gNjRrLgorCisvLyBGcm9tIENocm9taXVtLgorI2RlZmluZSBBUlJBWV9TSVpFKHgpIFwKKyAgICAoKHNpemVvZih4KS9zaXplb2YoMFt4XSkpIC8gKChzaXplX3QpKCEoc2l6ZW9mKHgpICUgc2l6ZW9mKDBbeF0pKSkpKQorCitzdGF0aWMgY29uc3QgZG91YmxlIE1BWF9MT0FEID0gMC44NTsKKworLy8gVGhlIG1pbmltdW0gdXRpbGl6YXRpb24gb2YgdGhlIGFycmF5IHBhcnQgb2YgYSBtaXhlZCBoYXNoL2FycmF5IHRhYmxlLiAgVGhpcworLy8gaXMgYSBzcGVlZC9tZW1vcnktdXNhZ2UgdHJhZGVvZmYgKHRob3VnaCBpdCdzIG5vdCBzdHJhaWdodGZvcndhcmQgYmVjYXVzZSBvZgorLy8gY2FjaGUgZWZmZWN0cykuICBUaGUgbG93ZXIgdGhpcyBpcywgdGhlIG1vcmUgbWVtb3J5IHdlJ2xsIHVzZS4KK3N0YXRpYyBjb25zdCBkb3VibGUgTUlOX0RFTlNJVFkgPSAwLjE7CisKK2Jvb2wgaXNfcG93Mih1aW50NjRfdCB2KSB7IHJldHVybiB2ID09IDAgfHwgKHYgJiAodiAtIDEpKSA9PSAwOyB9CisKK2ludCBsb2cyY2VpbCh1aW50NjRfdCB2KSB7CisgIGludCByZXQgPSAwOworICBib29sIHBvdzIgPSBpc19wb3cyKHYpOworICB3aGlsZSAodiA+Pj0gMSkgcmV0Kys7CisgIHJldCA9IHBvdzIgPyByZXQgOiByZXQgKyAxOyAgLy8gQ2VpbGluZy4KKyAgcmV0dXJuIFVQQl9NSU4oVVBCX01BWEFSUlNJWkUsIHJldCk7Cit9CisKK2NoYXIgKnVwYl9zdHJkdXAoY29uc3QgY2hhciAqcykgeworICByZXR1cm4gdXBiX3N0cmR1cDIocywgc3RybGVuKHMpKTsKK30KKworY2hhciAqdXBiX3N0cmR1cDIoY29uc3QgY2hhciAqcywgc2l6ZV90IGxlbikgeworICAvLyBQcmV2ZW50IG92ZXJmbG93IGVycm9ycy4KKyAgaWYgKGxlbiA9PSBTSVpFX01BWCkgcmV0dXJuIE5VTEw7CisgIC8vIEFsd2F5cyBudWxsLXRlcm1pbmF0ZSwgZXZlbiBpZiBiaW5hcnkgZGF0YTsgYnV0IGRvbid0IHJlbHkgb24gdGhlIGlucHV0IHRvCisgIC8vIGhhdmUgYSBudWxsLXRlcm1pbmF0aW5nIGJ5dGUgc2luY2UgaXQgbWF5IGJlIGEgcmF3IGJpbmFyeSBidWZmZXIuCisgIHNpemVfdCBuID0gbGVuICsgMTsKKyAgY2hhciAqcCA9IG1hbGxvYyhuKTsKKyAgaWYgKHApIHsKKyAgICBtZW1jcHkocCwgcywgbGVuKTsKKyAgICBwW2xlbl0gPSAwOworICB9CisgIHJldHVybiBwOworfQorCisvLyBBIHR5cGUgdG8gcmVwcmVzZW50IHRoZSBsb29rdXAga2V5IG9mIGVpdGhlciBhIHN0cnRhYmxlIG9yIGFuIGludHRhYmxlLgordHlwZWRlZiBzdHJ1Y3QgeworICB1cGJfdGFia2V5IGtleTsKK30gbG9va3Vwa2V5X3Q7CisKK3N0YXRpYyBsb29rdXBrZXlfdCBzdHJrZXkyKGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IGxlbikgeworICBsb29rdXBrZXlfdCBrOworICBrLmtleS5zLnN0ciA9IChjaGFyKilzdHI7CisgIGsua2V5LnMubGVuZ3RoID0gbGVuOworICByZXR1cm4gazsKK30KKworc3RhdGljIGxvb2t1cGtleV90IGludGtleSh1aW50cHRyX3Qga2V5KSB7CisgIGxvb2t1cGtleV90IGs7CisgIGsua2V5ID0gdXBiX2ludGtleShrZXkpOworICByZXR1cm4gazsKK30KKwordHlwZWRlZiB1aW50MzJfdCBoYXNoZnVuY190KHVwYl90YWJrZXkga2V5KTsKK3R5cGVkZWYgYm9vbCBlcWxmdW5jX3QodXBiX3RhYmtleSBrMSwgbG9va3Vwa2V5X3QgazIpOworCisvKiBCYXNlIHRhYmxlIChzaGFyZWQgY29kZSkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvLyBGb3Igd2hlbiB3ZSBuZWVkIHRvIGNhc3QgYXdheSBjb25zdC4KK3N0YXRpYyB1cGJfdGFiZW50ICptdXRhYmxlX2VudHJpZXModXBiX3RhYmxlICp0KSB7CisgIHJldHVybiAodXBiX3RhYmVudCopdC0+ZW50cmllczsKK30KKworc3RhdGljIGJvb2wgaXNmdWxsKHVwYl90YWJsZSAqdCkgeworICByZXR1cm4gKGRvdWJsZSkodC0+Y291bnQgKyAxKSAvIHVwYl90YWJsZV9zaXplKHQpID4gTUFYX0xPQUQ7Cit9CisKK3N0YXRpYyBib29sIGluaXQodXBiX3RhYmxlICp0LCB1cGJfY3R5cGVfdCBjdHlwZSwgdWludDhfdCBzaXplX2xnMikgeworICB0LT5jb3VudCA9IDA7CisgIHQtPmN0eXBlID0gY3R5cGU7CisgIHQtPnNpemVfbGcyID0gc2l6ZV9sZzI7CisgIHQtPm1hc2sgPSB1cGJfdGFibGVfc2l6ZSh0KSA/IHVwYl90YWJsZV9zaXplKHQpIC0gMSA6IDA7CisgIHNpemVfdCBieXRlcyA9IHVwYl90YWJsZV9zaXplKHQpICogc2l6ZW9mKHVwYl90YWJlbnQpOworICBpZiAoYnl0ZXMgPiAwKSB7CisgICAgdC0+ZW50cmllcyA9IG1hbGxvYyhieXRlcyk7CisgICAgaWYgKCF0LT5lbnRyaWVzKSByZXR1cm4gZmFsc2U7CisgICAgbWVtc2V0KG11dGFibGVfZW50cmllcyh0KSwgMCwgYnl0ZXMpOworICB9IGVsc2UgeworICAgIHQtPmVudHJpZXMgPSBOVUxMOworICB9CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgdm9pZCB1bmluaXQodXBiX3RhYmxlICp0KSB7IGZyZWUobXV0YWJsZV9lbnRyaWVzKHQpKTsgfQorCitzdGF0aWMgdXBiX3RhYmVudCAqZW1wdHllbnQodXBiX3RhYmxlICp0KSB7CisgIHVwYl90YWJlbnQgKmUgPSBtdXRhYmxlX2VudHJpZXModCkgKyB1cGJfdGFibGVfc2l6ZSh0KTsKKyAgd2hpbGUgKDEpIHsgaWYgKHVwYl90YWJlbnRfaXNlbXB0eSgtLWUpKSByZXR1cm4gZTsgYXNzZXJ0KGUgPiB0LT5lbnRyaWVzKTsgfQorfQorCitzdGF0aWMgdXBiX3RhYmVudCAqZ2V0ZW50cnlfbXV0YWJsZSh1cGJfdGFibGUgKnQsIHVpbnQzMl90IGhhc2gpIHsKKyAgcmV0dXJuICh1cGJfdGFiZW50Kil1cGJfZ2V0ZW50cnkodCwgaGFzaCk7Cit9CisKK3N0YXRpYyBjb25zdCB1cGJfdGFiZW50ICpmaW5kZW50cnkoY29uc3QgdXBiX3RhYmxlICp0LCBsb29rdXBrZXlfdCBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGhhc2gsIGVxbGZ1bmNfdCAqZXFsKSB7CisgIGlmICh0LT5zaXplX2xnMiA9PSAwKSByZXR1cm4gTlVMTDsKKyAgY29uc3QgdXBiX3RhYmVudCAqZSA9IHVwYl9nZXRlbnRyeSh0LCBoYXNoKTsKKyAgaWYgKHVwYl90YWJlbnRfaXNlbXB0eShlKSkgcmV0dXJuIE5VTEw7CisgIHdoaWxlICgxKSB7CisgICAgaWYgKGVxbChlLT5rZXksIGtleSkpIHJldHVybiBlOworICAgIGlmICgoZSA9IGUtPm5leHQpID09IE5VTEwpIHJldHVybiBOVUxMOworICB9Cit9CisKK3N0YXRpYyB1cGJfdGFiZW50ICpmaW5kZW50cnlfbXV0YWJsZSh1cGJfdGFibGUgKnQsIGxvb2t1cGtleV90IGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBoYXNoLCBlcWxmdW5jX3QgKmVxbCkgeworICByZXR1cm4gKHVwYl90YWJlbnQqKWZpbmRlbnRyeSh0LCBrZXksIGhhc2gsIGVxbCk7Cit9CisKK3N0YXRpYyBib29sIGxvb2t1cChjb25zdCB1cGJfdGFibGUgKnQsIGxvb2t1cGtleV90IGtleSwgdXBiX3ZhbHVlICp2LAorICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGhhc2gsIGVxbGZ1bmNfdCAqZXFsKSB7CisgIGNvbnN0IHVwYl90YWJlbnQgKmUgPSBmaW5kZW50cnkodCwga2V5LCBoYXNoLCBlcWwpOworICBpZiAoZSkgeworICAgIGlmICh2KSB7CisgICAgICBfdXBiX3ZhbHVlX3NldHZhbCh2LCBlLT52YWwsIHQtPmN0eXBlKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKy8vIFRoZSBnaXZlbiBrZXkgbXVzdCBub3QgYWxyZWFkeSBleGlzdCBpbiB0aGUgdGFibGUuCitzdGF0aWMgdm9pZCBpbnNlcnQodXBiX3RhYmxlICp0LCBsb29rdXBrZXlfdCBrZXksIHVwYl92YWx1ZSB2YWwsCisgICAgICAgICAgICAgICAgICAgdWludDMyX3QgaGFzaCwgaGFzaGZ1bmNfdCAqaGFzaGZ1bmMsIGVxbGZ1bmNfdCAqZXFsKSB7CisgIFVQQl9VTlVTRUQoZXFsKTsKKyAgYXNzZXJ0KGZpbmRlbnRyeSh0LCBrZXksIGhhc2gsIGVxbCkgPT0gTlVMTCk7CisgIGFzc2VydCh2YWwuY3R5cGUgPT0gdC0+Y3R5cGUpOworICB0LT5jb3VudCsrOworICB1cGJfdGFiZW50ICptYWlucG9zX2UgPSBnZXRlbnRyeV9tdXRhYmxlKHQsIGhhc2gpOworICB1cGJfdGFiZW50ICpvdXJfZSA9IG1haW5wb3NfZTsKKyAgaWYgKHVwYl90YWJlbnRfaXNlbXB0eShtYWlucG9zX2UpKSB7CisgICAgLy8gT3VyIG1haW4gcG9zaXRpb24gaXMgZW1wdHk7IHVzZSBpdC4KKyAgICBvdXJfZS0+bmV4dCA9IE5VTEw7CisgIH0gZWxzZSB7CisgICAgLy8gQ29sbGlzaW9uLgorICAgIHVwYl90YWJlbnQgKm5ld19lID0gZW1wdHllbnQodCk7CisgICAgLy8gSGVhZCBvZiBjb2xsaWRlcidzIGNoYWluLgorICAgIHVwYl90YWJlbnQgKmNoYWluID0gZ2V0ZW50cnlfbXV0YWJsZSh0LCBoYXNoZnVuYyhtYWlucG9zX2UtPmtleSkpOworICAgIGlmIChjaGFpbiA9PSBtYWlucG9zX2UpIHsKKyAgICAgIC8vIEV4aXN0aW5nIGVudCBpcyBpbiBpdHMgbWFpbiBwb3Npc2l0b24gKGl0IGhhcyB0aGUgc2FtZSBoYXNoIGFzIHVzLCBhbmQKKyAgICAgIC8vIGlzIHRoZSBoZWFkIG9mIG91ciBjaGFpbikuICBJbnNlcnQgdG8gbmV3IGVudCBhbmQgYXBwZW5kIHRvIHRoaXMgY2hhaW4uCisgICAgICBuZXdfZS0+bmV4dCA9IG1haW5wb3NfZS0+bmV4dDsKKyAgICAgIG1haW5wb3NfZS0+bmV4dCA9IG5ld19lOworICAgICAgb3VyX2UgPSBuZXdfZTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gRXhpc3RpbmcgZW50IGlzIG5vdCBpbiBpdHMgbWFpbiBwb3NpdGlvbiAoaXQgaXMgYSBub2RlIGluIHNvbWUgb3RoZXIKKyAgICAgIC8vIGNoYWluKS4gIFRoaXMgaW1wbGllcyB0aGF0IG5vIGV4aXN0aW5nIGVudCBpbiB0aGUgdGFibGUgaGFzIG91ciBoYXNoLgorICAgICAgLy8gRXZpY3QgaXQgKHVwZGF0aW5nIGl0cyBjaGFpbikgYW5kIHVzZSBpdHMgZW50IGZvciBoZWFkIG9mIG91ciBjaGFpbi4KKyAgICAgICpuZXdfZSA9ICptYWlucG9zX2U7ICAvLyBjb3BpZXMgbmV4dC4KKyAgICAgIHdoaWxlIChjaGFpbi0+bmV4dCAhPSBtYWlucG9zX2UpIHsKKyAgICAgICAgY2hhaW4gPSAodXBiX3RhYmVudCopY2hhaW4tPm5leHQ7CisgICAgICAgIGFzc2VydChjaGFpbik7CisgICAgICB9CisgICAgICBjaGFpbi0+bmV4dCA9IG5ld19lOworICAgICAgb3VyX2UgPSBtYWlucG9zX2U7CisgICAgICBvdXJfZS0+bmV4dCA9IE5VTEw7CisgICAgfQorICB9CisgIG91cl9lLT5rZXkgPSBrZXkua2V5OworICBvdXJfZS0+dmFsID0gdmFsLnZhbDsKKyAgYXNzZXJ0KGZpbmRlbnRyeSh0LCBrZXksIGhhc2gsIGVxbCkgPT0gb3VyX2UpOworfQorCitzdGF0aWMgYm9vbCBybSh1cGJfdGFibGUgKnQsIGxvb2t1cGtleV90IGtleSwgdXBiX3ZhbHVlICp2YWwsCisgICAgICAgICAgICAgICB1cGJfdGFia2V5ICpyZW1vdmVkLCB1aW50MzJfdCBoYXNoLCBlcWxmdW5jX3QgKmVxbCkgeworICB1cGJfdGFiZW50ICpjaGFpbiA9IGdldGVudHJ5X211dGFibGUodCwgaGFzaCk7CisgIGlmICh1cGJfdGFiZW50X2lzZW1wdHkoY2hhaW4pKSByZXR1cm4gZmFsc2U7CisgIGlmIChlcWwoY2hhaW4tPmtleSwga2V5KSkgeworICAgIC8vIEVsZW1lbnQgdG8gcmVtb3ZlIGlzIGF0IHRoZSBoZWFkIG9mIGl0cyBjaGFpbi4KKyAgICB0LT5jb3VudC0tOworICAgIGlmICh2YWwpIHsKKyAgICAgIF91cGJfdmFsdWVfc2V0dmFsKHZhbCwgY2hhaW4tPnZhbCwgdC0+Y3R5cGUpOworICAgIH0KKyAgICBpZiAoY2hhaW4tPm5leHQpIHsKKyAgICAgIHVwYl90YWJlbnQgKm1vdmUgPSAodXBiX3RhYmVudCopY2hhaW4tPm5leHQ7CisgICAgICAqY2hhaW4gPSAqbW92ZTsKKyAgICAgIGlmIChyZW1vdmVkKSAqcmVtb3ZlZCA9IG1vdmUtPmtleTsKKyAgICAgIG1vdmUtPmtleS5udW0gPSAwOyAgLy8gTWFrZSB0aGUgc2xvdCBlbXB0eS4KKyAgICB9IGVsc2UgeworICAgICAgaWYgKHJlbW92ZWQpICpyZW1vdmVkID0gY2hhaW4tPmtleTsKKyAgICAgIGNoYWluLT5rZXkubnVtID0gMDsgIC8vIE1ha2UgdGhlIHNsb3QgZW1wdHkuCisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIC8vIEVsZW1lbnQgdG8gcmVtb3ZlIGlzIGVpdGhlciBpbiBhIG5vbi1oZWFkIHBvc2l0aW9uIG9yIG5vdCBpbiB0aGUgdGFibGUuCisgICAgd2hpbGUgKGNoYWluLT5uZXh0ICYmICFlcWwoY2hhaW4tPm5leHQtPmtleSwga2V5KSkKKyAgICAgIGNoYWluID0gKHVwYl90YWJlbnQqKWNoYWluLT5uZXh0OworICAgIGlmIChjaGFpbi0+bmV4dCkgeworICAgICAgLy8gRm91bmQgZWxlbWVudCB0byByZW1vdmUuCisgICAgICBpZiAodmFsKSB7CisgICAgICAgIF91cGJfdmFsdWVfc2V0dmFsKHZhbCwgY2hhaW4tPm5leHQtPnZhbCwgdC0+Y3R5cGUpOworICAgICAgfQorICAgICAgdXBiX3RhYmVudCAqcm0gPSAodXBiX3RhYmVudCopY2hhaW4tPm5leHQ7CisgICAgICBpZiAocmVtb3ZlZCkgKnJlbW92ZWQgPSBybS0+a2V5OworICAgICAgcm0tPmtleS5udW0gPSAwOworICAgICAgY2hhaW4tPm5leHQgPSBybS0+bmV4dDsKKyAgICAgIHQtPmNvdW50LS07CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorfQorCitzdGF0aWMgc2l6ZV90IG5leHQoY29uc3QgdXBiX3RhYmxlICp0LCBzaXplX3QgaSkgeworICBkbyB7CisgICAgaWYgKCsraSA+PSB1cGJfdGFibGVfc2l6ZSh0KSkKKyAgICAgIHJldHVybiBTSVpFX01BWDsKKyAgfSB3aGlsZSh1cGJfdGFiZW50X2lzZW1wdHkoJnQtPmVudHJpZXNbaV0pKTsKKworICByZXR1cm4gaTsKK30KKworc3RhdGljIHNpemVfdCBiZWdpbihjb25zdCB1cGJfdGFibGUgKnQpIHsKKyAgcmV0dXJuIG5leHQodCwgLTEpOworfQorCisKKy8qIHVwYl9zdHJ0YWJsZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIEEgc2ltcGxlICJzdWJjbGFzcyIgb2YgdXBiX3RhYmxlIHRoYXQgb25seSBhZGRzIGEgaGFzaCBmdW5jdGlvbiBmb3Igc3RyaW5ncy4KKworc3RhdGljIHVpbnQzMl90IHN0cmhhc2godXBiX3RhYmtleSBrZXkpIHsKKyAgcmV0dXJuIE11cm11ckhhc2gyKGtleS5zLnN0ciwga2V5LnMubGVuZ3RoLCAwKTsKK30KKworc3RhdGljIGJvb2wgc3RyZXFsKHVwYl90YWJrZXkgazEsIGxvb2t1cGtleV90IGsyKSB7CisgIHJldHVybiBrMS5zLmxlbmd0aCA9PSBrMi5rZXkucy5sZW5ndGggJiYKKyAgICAgICAgIG1lbWNtcChrMS5zLnN0ciwgazIua2V5LnMuc3RyLCBrMS5zLmxlbmd0aCkgPT0gMDsKK30KKworYm9vbCB1cGJfc3RydGFibGVfaW5pdCh1cGJfc3RydGFibGUgKnQsIHVwYl9jdHlwZV90IGN0eXBlKSB7CisgIHJldHVybiBpbml0KCZ0LT50LCBjdHlwZSwgMik7Cit9CisKK3ZvaWQgdXBiX3N0cnRhYmxlX3VuaW5pdCh1cGJfc3RydGFibGUgKnQpIHsKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCB1cGJfdGFibGVfc2l6ZSgmdC0+dCk7IGkrKykKKyAgICBmcmVlKCh2b2lkKil0LT50LmVudHJpZXNbaV0ua2V5LnMuc3RyKTsKKyAgdW5pbml0KCZ0LT50KTsKK30KKworYm9vbCB1cGJfc3RydGFibGVfcmVzaXplKHVwYl9zdHJ0YWJsZSAqdCwgc2l6ZV90IHNpemVfbGcyKSB7CisgIHVwYl9zdHJ0YWJsZSBuZXdfdGFibGU7CisgIGlmICghaW5pdCgmbmV3X3RhYmxlLnQsIHQtPnQuY3R5cGUsIHNpemVfbGcyKSkKKyAgICByZXR1cm4gZmFsc2U7CisgIHVwYl9zdHJ0YWJsZV9pdGVyIGk7CisgIHVwYl9zdHJ0YWJsZV9iZWdpbigmaSwgdCk7CisgIGZvciAoIDsgIXVwYl9zdHJ0YWJsZV9kb25lKCZpKTsgdXBiX3N0cnRhYmxlX25leHQoJmkpKSB7CisgICAgdXBiX3N0cnRhYmxlX2luc2VydDIoCisgICAgICAgICZuZXdfdGFibGUsCisgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX2tleSgmaSksCisgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX2tleWxlbmd0aCgmaSksCisgICAgICAgIHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKCZpKSk7CisgIH0KKyAgdXBiX3N0cnRhYmxlX3VuaW5pdCh0KTsKKyAgKnQgPSBuZXdfdGFibGU7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9zdHJ0YWJsZV9pbnNlcnQyKHVwYl9zdHJ0YWJsZSAqdCwgY29uc3QgY2hhciAqaywgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3ZhbHVlIHYpIHsKKyAgaWYgKGlzZnVsbCgmdC0+dCkpIHsKKyAgICAvLyBOZWVkIHRvIHJlc2l6ZS4gIE5ldyB0YWJsZSBvZiBkb3VibGUgdGhlIHNpemUsIGFkZCBvbGQgZWxlbWVudHMgdG8gaXQuCisgICAgaWYgKCF1cGJfc3RydGFibGVfcmVzaXplKHQsIHQtPnQuc2l6ZV9sZzIgKyAxKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBpZiAoKGsgPSB1cGJfc3RyZHVwMihrLCBsZW4pKSA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgbG9va3Vwa2V5X3Qga2V5ID0gc3Rya2V5MihrLCBsZW4pOworICB1aW50MzJfdCBoYXNoID0gTXVybXVySGFzaDIoa2V5LmtleS5zLnN0ciwga2V5LmtleS5zLmxlbmd0aCwgMCk7CisgIGluc2VydCgmdC0+dCwga2V5LCB2LCBoYXNoLCAmc3RyaGFzaCwgJnN0cmVxbCk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9zdHJ0YWJsZV9sb29rdXAyKGNvbnN0IHVwYl9zdHJ0YWJsZSAqdCwgY29uc3QgY2hhciAqa2V5LCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfdmFsdWUgKnYpIHsKKyAgdWludDMyX3QgaGFzaCA9IE11cm11ckhhc2gyKGtleSwgbGVuLCAwKTsKKyAgcmV0dXJuIGxvb2t1cCgmdC0+dCwgc3Rya2V5MihrZXksIGxlbiksIHYsIGhhc2gsICZzdHJlcWwpOworfQorCitib29sIHVwYl9zdHJ0YWJsZV9yZW1vdmUyKHVwYl9zdHJ0YWJsZSAqdCwgY29uc3QgY2hhciAqa2V5LCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl92YWx1ZSAqdmFsKSB7CisgIHVpbnQzMl90IGhhc2ggPSBNdXJtdXJIYXNoMihrZXksIHN0cmxlbihrZXkpLCAwKTsKKyAgdXBiX3RhYmtleSB0YWJrZXk7CisgIGlmIChybSgmdC0+dCwgc3Rya2V5MihrZXksIGxlbiksIHZhbCwgJnRhYmtleSwgaGFzaCwgJnN0cmVxbCkpIHsKKyAgICBmcmVlKCh2b2lkKil0YWJrZXkucy5zdHIpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisvLyBJdGVyYXRpb24KKworc3RhdGljIGNvbnN0IHVwYl90YWJlbnQgKnN0cl90YWJlbnQoY29uc3QgdXBiX3N0cnRhYmxlX2l0ZXIgKmkpIHsKKyAgcmV0dXJuICZpLT50LT50LmVudHJpZXNbaS0+aW5kZXhdOworfQorCit2b2lkIHVwYl9zdHJ0YWJsZV9iZWdpbih1cGJfc3RydGFibGVfaXRlciAqaSwgY29uc3QgdXBiX3N0cnRhYmxlICp0KSB7CisgIGktPnQgPSB0OworICBpLT5pbmRleCA9IGJlZ2luKCZ0LT50KTsKK30KKwordm9pZCB1cGJfc3RydGFibGVfbmV4dCh1cGJfc3RydGFibGVfaXRlciAqaSkgeworICBpLT5pbmRleCA9IG5leHQoJmktPnQtPnQsIGktPmluZGV4KTsKK30KKworYm9vbCB1cGJfc3RydGFibGVfZG9uZShjb25zdCB1cGJfc3RydGFibGVfaXRlciAqaSkgeworICByZXR1cm4gaS0+aW5kZXggPj0gdXBiX3RhYmxlX3NpemUoJmktPnQtPnQpIHx8CisgICAgICAgICB1cGJfdGFiZW50X2lzZW1wdHkoc3RyX3RhYmVudChpKSk7Cit9CisKK2NvbnN0IGNoYXIgKnVwYl9zdHJ0YWJsZV9pdGVyX2tleSh1cGJfc3RydGFibGVfaXRlciAqaSkgeworICBhc3NlcnQoIXVwYl9zdHJ0YWJsZV9kb25lKGkpKTsKKyAgcmV0dXJuIHN0cl90YWJlbnQoaSktPmtleS5zLnN0cjsKK30KKworc2l6ZV90IHVwYl9zdHJ0YWJsZV9pdGVyX2tleWxlbmd0aCh1cGJfc3RydGFibGVfaXRlciAqaSkgeworICBhc3NlcnQoIXVwYl9zdHJ0YWJsZV9kb25lKGkpKTsKKyAgcmV0dXJuIHN0cl90YWJlbnQoaSktPmtleS5zLmxlbmd0aDsKK30KKwordXBiX3ZhbHVlIHVwYl9zdHJ0YWJsZV9pdGVyX3ZhbHVlKGNvbnN0IHVwYl9zdHJ0YWJsZV9pdGVyICppKSB7CisgIGFzc2VydCghdXBiX3N0cnRhYmxlX2RvbmUoaSkpOworICByZXR1cm4gX3VwYl92YWx1ZV92YWwoc3RyX3RhYmVudChpKS0+dmFsLCBpLT50LT50LmN0eXBlKTsKK30KKwordm9pZCB1cGJfc3RydGFibGVfaXRlcl9zZXRkb25lKHVwYl9zdHJ0YWJsZV9pdGVyICppKSB7CisgIGktPmluZGV4ID0gU0laRV9NQVg7Cit9CisKK2Jvb2wgdXBiX3N0cnRhYmxlX2l0ZXJfaXNlcXVhbChjb25zdCB1cGJfc3RydGFibGVfaXRlciAqaTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX3N0cnRhYmxlX2l0ZXIgKmkyKSB7CisgIGlmICh1cGJfc3RydGFibGVfZG9uZShpMSkgJiYgdXBiX3N0cnRhYmxlX2RvbmUoaTIpKQorICAgIHJldHVybiB0cnVlOworICByZXR1cm4gaTEtPnQgPT0gaTItPnQgJiYgaTEtPmluZGV4ID09IGkyLT5pbmRleDsKK30KKworCisvKiB1cGJfaW50dGFibGUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvLyBGb3IgaW50dGFibGVzIHdlIHVzZSBhIGh5YnJpZCBzdHJ1Y3R1cmUgd2hlcmUgc21hbGwga2V5cyBhcmUga2VwdCBpbiBhbgorLy8gYXJyYXkgYW5kIGxhcmdlIGtleXMgYXJlIHB1dCBpbiB0aGUgaGFzaCB0YWJsZS4KKworc3RhdGljIHVpbnQzMl90IGludGhhc2godXBiX3RhYmtleSBrZXkpIHsgcmV0dXJuIHVwYl9pbnRoYXNoKGtleS5udW0pOyB9CisKK3N0YXRpYyBib29sIGludGVxbCh1cGJfdGFia2V5IGsxLCBsb29rdXBrZXlfdCBrMikgeworICByZXR1cm4gazEubnVtID09IGsyLmtleS5udW07Cit9CisKK3N0YXRpYyBfdXBiX3ZhbHVlICptdXRhYmxlX2FycmF5KHVwYl9pbnR0YWJsZSAqdCkgeworICByZXR1cm4gKF91cGJfdmFsdWUqKXQtPmFycmF5OworfQorCitzdGF0aWMgX3VwYl92YWx1ZSAqaW50dGFibGVfdmFsKHVwYl9pbnR0YWJsZSAqdCwgdWludHB0cl90IGtleSkgeworICBpZiAoa2V5IDwgdC0+YXJyYXlfc2l6ZSkgeworICAgIHJldHVybiB1cGJfYXJyaGFzKHQtPmFycmF5W2tleV0pID8gJihtdXRhYmxlX2FycmF5KHQpW2tleV0pIDogTlVMTDsKKyAgfSBlbHNlIHsKKyAgICB1cGJfdGFiZW50ICplID0KKyAgICAgICAgZmluZGVudHJ5X211dGFibGUoJnQtPnQsIGludGtleShrZXkpLCB1cGJfaW50aGFzaChrZXkpLCAmaW50ZXFsKTsKKyAgICByZXR1cm4gZSA/ICZlLT52YWwgOiBOVUxMOworICB9Cit9CisKK3N0YXRpYyBjb25zdCBfdXBiX3ZhbHVlICppbnR0YWJsZV92YWxfY29uc3QoY29uc3QgdXBiX2ludHRhYmxlICp0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50cHRyX3Qga2V5KSB7CisgIHJldHVybiBpbnR0YWJsZV92YWwoKHVwYl9pbnR0YWJsZSopdCwga2V5KTsKK30KKworc2l6ZV90IHVwYl9pbnR0YWJsZV9jb3VudChjb25zdCB1cGJfaW50dGFibGUgKnQpIHsKKyAgcmV0dXJuIHQtPnQuY291bnQgKyB0LT5hcnJheV9jb3VudDsKK30KKworc3RhdGljIHZvaWQgY2hlY2sodXBiX2ludHRhYmxlICp0KSB7CisgIFVQQl9VTlVTRUQodCk7CisjaWYgZGVmaW5lZChVUEJfREVCVUdfVEFCTEUpICYmICFkZWZpbmVkKE5ERUJVRykKKyAgLy8gVGhpcyBjaGVjayBpcyB2ZXJ5IGV4cGVuc2l2ZSAobWFrZXMgaW5zZXJ0cy9kZWxldGVzIE8oTikpLgorICBzaXplX3QgY291bnQgPSAwOworICB1cGJfaW50dGFibGVfaXRlciBpOworICB1cGJfaW50dGFibGVfYmVnaW4oJmksIHQpOworICBmb3IoOyAhdXBiX2ludHRhYmxlX2RvbmUoJmkpOyB1cGJfaW50dGFibGVfbmV4dCgmaSksIGNvdW50KyspIHsKKyAgICBhc3NlcnQodXBiX2ludHRhYmxlX2xvb2t1cCh0LCB1cGJfaW50dGFibGVfaXRlcl9rZXkoJmkpLCBOVUxMKSk7CisgIH0KKyAgYXNzZXJ0KGNvdW50ID09IHVwYl9pbnR0YWJsZV9jb3VudCh0KSk7CisjZW5kaWYKK30KKworYm9vbCB1cGJfaW50dGFibGVfc2l6ZWRpbml0KHVwYl9pbnR0YWJsZSAqdCwgdXBiX2N0eXBlX3QgY3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGFzaXplLCBpbnQgaHNpemVfbGcyKSB7CisgIGlmICghaW5pdCgmdC0+dCwgY3R5cGUsIGhzaXplX2xnMikpIHJldHVybiBmYWxzZTsKKyAgLy8gQWx3YXlzIG1ha2UgdGhlIGFycmF5IHBhcnQgYXQgbGVhc3QgMSBsb25nLCBzbyB0aGF0IHdlIGtub3cga2V5IDAKKyAgLy8gd29uJ3QgYmUgaW4gdGhlIGhhc2ggcGFydCwgd2hpY2ggc2ltcGxpZmllcyB0aGluZ3MuCisgIHQtPmFycmF5X3NpemUgPSBVUEJfTUFYKDEsIGFzaXplKTsKKyAgdC0+YXJyYXlfY291bnQgPSAwOworICBzaXplX3QgYXJyYXlfYnl0ZXMgPSB0LT5hcnJheV9zaXplICogc2l6ZW9mKHVwYl92YWx1ZSk7CisgIHQtPmFycmF5ID0gbWFsbG9jKGFycmF5X2J5dGVzKTsKKyAgaWYgKCF0LT5hcnJheSkgeworICAgIHVuaW5pdCgmdC0+dCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIG1lbXNldChtdXRhYmxlX2FycmF5KHQpLCAweGZmLCBhcnJheV9ieXRlcyk7CisgIGNoZWNrKHQpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCB1cGJfaW50dGFibGVfaW5pdCh1cGJfaW50dGFibGUgKnQsIHVwYl9jdHlwZV90IGN0eXBlKSB7CisgIHJldHVybiB1cGJfaW50dGFibGVfc2l6ZWRpbml0KHQsIGN0eXBlLCAwLCA0KTsKK30KKwordm9pZCB1cGJfaW50dGFibGVfdW5pbml0KHVwYl9pbnR0YWJsZSAqdCkgeworICB1bmluaXQoJnQtPnQpOworICBmcmVlKG11dGFibGVfYXJyYXkodCkpOworfQorCitib29sIHVwYl9pbnR0YWJsZV9pbnNlcnQodXBiX2ludHRhYmxlICp0LCB1aW50cHRyX3Qga2V5LCB1cGJfdmFsdWUgdmFsKSB7CisgIGFzc2VydCh1cGJfYXJyaGFzKHZhbC52YWwpKTsKKyAgaWYgKGtleSA8IHQtPmFycmF5X3NpemUpIHsKKyAgICBhc3NlcnQoIXVwYl9hcnJoYXModC0+YXJyYXlba2V5XSkpOworICAgIHQtPmFycmF5X2NvdW50Kys7CisgICAgbXV0YWJsZV9hcnJheSh0KVtrZXldID0gdmFsLnZhbDsKKyAgfSBlbHNlIHsKKyAgICBpZiAoaXNmdWxsKCZ0LT50KSkgeworICAgICAgLy8gTmVlZCB0byByZXNpemUgdGhlIGhhc2ggcGFydCwgYnV0IHdlIHJlLXVzZSB0aGUgYXJyYXkgcGFydC4KKyAgICAgIHVwYl90YWJsZSBuZXdfdGFibGU7CisgICAgICBpZiAoIWluaXQoJm5ld190YWJsZSwgdC0+dC5jdHlwZSwgdC0+dC5zaXplX2xnMiArIDEpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBzaXplX3QgaTsKKyAgICAgIGZvciAoaSA9IGJlZ2luKCZ0LT50KTsgaSA8IHVwYl90YWJsZV9zaXplKCZ0LT50KTsgaSA9IG5leHQoJnQtPnQsIGkpKSB7CisgICAgICAgIGNvbnN0IHVwYl90YWJlbnQgKmUgPSAmdC0+dC5lbnRyaWVzW2ldOworICAgICAgICB1cGJfdmFsdWUgdjsKKyAgICAgICAgX3VwYl92YWx1ZV9zZXR2YWwoJnYsIGUtPnZhbCwgdC0+dC5jdHlwZSk7CisgICAgICAgIHVpbnQzMl90IGhhc2ggPSB1cGJfaW50aGFzaChlLT5rZXkubnVtKTsKKyAgICAgICAgaW5zZXJ0KCZuZXdfdGFibGUsIGludGtleShlLT5rZXkubnVtKSwgdiwgaGFzaCwgJmludGhhc2gsICZpbnRlcWwpOworICAgICAgfQorCisgICAgICBhc3NlcnQodC0+dC5jb3VudCA9PSBuZXdfdGFibGUuY291bnQpOworCisgICAgICB1bmluaXQoJnQtPnQpOworICAgICAgdC0+dCA9IG5ld190YWJsZTsKKyAgICB9CisgICAgaW5zZXJ0KCZ0LT50LCBpbnRrZXkoa2V5KSwgdmFsLCB1cGJfaW50aGFzaChrZXkpLCAmaW50aGFzaCwgJmludGVxbCk7CisgIH0KKyAgY2hlY2sodCk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHVwYl9pbnR0YWJsZV9sb29rdXAoY29uc3QgdXBiX2ludHRhYmxlICp0LCB1aW50cHRyX3Qga2V5LCB1cGJfdmFsdWUgKnYpIHsKKyAgY29uc3QgX3VwYl92YWx1ZSAqdGFibGVfdiA9IGludHRhYmxlX3ZhbF9jb25zdCh0LCBrZXkpOworICBpZiAoIXRhYmxlX3YpIHJldHVybiBmYWxzZTsKKyAgaWYgKHYpIF91cGJfdmFsdWVfc2V0dmFsKHYsICp0YWJsZV92LCB0LT50LmN0eXBlKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgdXBiX2ludHRhYmxlX3JlcGxhY2UodXBiX2ludHRhYmxlICp0LCB1aW50cHRyX3Qga2V5LCB1cGJfdmFsdWUgdmFsKSB7CisgIF91cGJfdmFsdWUgKnRhYmxlX3YgPSBpbnR0YWJsZV92YWwodCwga2V5KTsKKyAgaWYgKCF0YWJsZV92KSByZXR1cm4gZmFsc2U7CisgICp0YWJsZV92ID0gdmFsLnZhbDsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgdXBiX2ludHRhYmxlX3JlbW92ZSh1cGJfaW50dGFibGUgKnQsIHVpbnRwdHJfdCBrZXksIHVwYl92YWx1ZSAqdmFsKSB7CisgIGJvb2wgc3VjY2VzczsKKyAgaWYgKGtleSA8IHQtPmFycmF5X3NpemUpIHsKKyAgICBpZiAodXBiX2Fycmhhcyh0LT5hcnJheVtrZXldKSkgeworICAgICAgdC0+YXJyYXlfY291bnQtLTsKKyAgICAgIGlmICh2YWwpIHsKKyAgICAgICAgX3VwYl92YWx1ZV9zZXR2YWwodmFsLCB0LT5hcnJheVtrZXldLCB0LT50LmN0eXBlKTsKKyAgICAgIH0KKyAgICAgIF91cGJfdmFsdWUgZW1wdHkgPSBVUEJfQVJSQVlfRU1QVFlFTlQ7CisgICAgICBtdXRhYmxlX2FycmF5KHQpW2tleV0gPSBlbXB0eTsKKyAgICAgIHN1Y2Nlc3MgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBzdWNjZXNzID0gZmFsc2U7CisgICAgfQorICB9IGVsc2UgeworICAgIHVwYl90YWJrZXkgcmVtb3ZlZDsKKyAgICB1aW50MzJfdCBoYXNoID0gdXBiX2ludGhhc2goa2V5KTsKKyAgICBzdWNjZXNzID0gcm0oJnQtPnQsIGludGtleShrZXkpLCB2YWwsICZyZW1vdmVkLCBoYXNoLCAmaW50ZXFsKTsKKyAgfQorICBjaGVjayh0KTsKKyAgcmV0dXJuIHN1Y2Nlc3M7Cit9CisKK2Jvb2wgdXBiX2ludHRhYmxlX3B1c2godXBiX2ludHRhYmxlICp0LCB1cGJfdmFsdWUgdmFsKSB7CisgIHJldHVybiB1cGJfaW50dGFibGVfaW5zZXJ0KHQsIHVwYl9pbnR0YWJsZV9jb3VudCh0KSwgdmFsKTsKK30KKwordXBiX3ZhbHVlIHVwYl9pbnR0YWJsZV9wb3AodXBiX2ludHRhYmxlICp0KSB7CisgIHVwYl92YWx1ZSB2YWw7CisgIGJvb2wgb2sgPSB1cGJfaW50dGFibGVfcmVtb3ZlKHQsIHVwYl9pbnR0YWJsZV9jb3VudCh0KSAtIDEsICZ2YWwpOworICBVUEJfQVNTRVJUX1ZBUihvaywgb2spOworICByZXR1cm4gdmFsOworfQorCitib29sIHVwYl9pbnR0YWJsZV9pbnNlcnRwdHIodXBiX2ludHRhYmxlICp0LCBjb25zdCB2b2lkICprZXksIHVwYl92YWx1ZSB2YWwpIHsKKyAgcmV0dXJuIHVwYl9pbnR0YWJsZV9pbnNlcnQodCwgKHVpbnRwdHJfdClrZXksIHZhbCk7Cit9CisKK2Jvb2wgdXBiX2ludHRhYmxlX2xvb2t1cHB0cihjb25zdCB1cGJfaW50dGFibGUgKnQsIGNvbnN0IHZvaWQgKmtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfdmFsdWUgKnYpIHsKKyAgcmV0dXJuIHVwYl9pbnR0YWJsZV9sb29rdXAodCwgKHVpbnRwdHJfdClrZXksIHYpOworfQorCitib29sIHVwYl9pbnR0YWJsZV9yZW1vdmVwdHIodXBiX2ludHRhYmxlICp0LCBjb25zdCB2b2lkICprZXksIHVwYl92YWx1ZSAqdmFsKSB7CisgIHJldHVybiB1cGJfaW50dGFibGVfcmVtb3ZlKHQsICh1aW50cHRyX3Qpa2V5LCB2YWwpOworfQorCit2b2lkIHVwYl9pbnR0YWJsZV9jb21wYWN0KHVwYl9pbnR0YWJsZSAqdCkgeworICAvLyBDcmVhdGUgYSBwb3dlci1vZi10d28gaGlzdG9ncmFtIG9mIHRoZSB0YWJsZSBrZXlzLgorICBpbnQgY291bnRzW1VQQl9NQVhBUlJTSVpFICsgMV0gPSB7MH07CisgIHVpbnRwdHJfdCBtYXhfa2V5ID0gMDsKKyAgdXBiX2ludHRhYmxlX2l0ZXIgaTsKKyAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCB0KTsKKyAgZm9yICg7ICF1cGJfaW50dGFibGVfZG9uZSgmaSk7IHVwYl9pbnR0YWJsZV9uZXh0KCZpKSkgeworICAgIHVpbnRwdHJfdCBrZXkgPSB1cGJfaW50dGFibGVfaXRlcl9rZXkoJmkpOworICAgIGlmIChrZXkgPiBtYXhfa2V5KSB7CisgICAgICBtYXhfa2V5ID0ga2V5OworICAgIH0KKyAgICBjb3VudHNbbG9nMmNlaWwoa2V5KV0rKzsKKyAgfQorCisgIGludCBhcnJfc2l6ZTsKKyAgaW50IGFycl9jb3VudCA9IHVwYl9pbnR0YWJsZV9jb3VudCh0KTsKKworICBpZiAodXBiX2ludHRhYmxlX2NvdW50KHQpID49IG1heF9rZXkgKiBNSU5fREVOU0lUWSkgeworICAgIC8vIFdlIGNhbiBwdXQgMTAwJSBvZiB0aGUgZW50cmllcyBpbiB0aGUgYXJyYXkgcGFydC4KKyAgICBhcnJfc2l6ZSA9IG1heF9rZXkgKyAxOworICB9IGVsc2UgeworICAgIC8vIEZpbmQgdGhlIGxhcmdlc3QgcG93ZXIgb2YgdHdvIHRoYXQgc2F0aXNmaWVzIHRoZSBNSU5fREVOU0lUWSBkZWZpbml0aW9uLgorICAgIGZvciAoaW50IHNpemVfbGcyID0gQVJSQVlfU0laRShjb3VudHMpIC0gMTsgc2l6ZV9sZzIgPiAxOyBzaXplX2xnMi0tKSB7CisgICAgICBhcnJfc2l6ZSA9IDEgPDwgc2l6ZV9sZzI7CisgICAgICBhcnJfY291bnQgLT0gY291bnRzW3NpemVfbGcyXTsKKyAgICAgIGlmIChhcnJfY291bnQgPj0gYXJyX3NpemUgKiBNSU5fREVOU0lUWSkgeworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBBcnJheSBwYXJ0IG11c3QgYWx3YXlzIGJlIGF0IGxlYXN0IDEgZW50cnkgbGFyZ2UgdG8gY2F0Y2ggbG9va3VwcyBvZiBrZXkKKyAgLy8gMC4gIEtleSAwIG11c3QgYWx3YXlzIGJlIGluIHRoZSBhcnJheSBwYXJ0IGJlY2F1c2UgIjAiIGluIHRoZSBoYXNoIHBhcnQKKyAgLy8gZGVub3RlcyBhbiBlbXB0eSBlbnRyeS4KKyAgYXJyX3NpemUgPSBVUEJfTUFYKGFycl9zaXplLCAxKTsKKworICAvLyBJbnNlcnQgYWxsIGVsZW1lbnRzIGludG8gbmV3LCBwZXJmZWN0bHktc2l6ZWQgdGFibGUuCisgIGludCBoYXNoX2NvdW50ID0gdXBiX2ludHRhYmxlX2NvdW50KHQpIC0gYXJyX2NvdW50OworICBpbnQgaGFzaF9zaXplID0gaGFzaF9jb3VudCA/IChoYXNoX2NvdW50IC8gTUFYX0xPQUQpICsgMSA6IDA7CisgIGludCBoYXNoc2l6ZV9sZzIgPSBsb2cyY2VpbChoYXNoX3NpemUpOworICBhc3NlcnQoaGFzaF9jb3VudCA+PSAwKTsKKworICB1cGJfaW50dGFibGUgbmV3X3Q7CisgIHVwYl9pbnR0YWJsZV9zaXplZGluaXQoJm5ld190LCB0LT50LmN0eXBlLCBhcnJfc2l6ZSwgaGFzaHNpemVfbGcyKTsKKyAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCB0KTsKKyAgZm9yICg7ICF1cGJfaW50dGFibGVfZG9uZSgmaSk7IHVwYl9pbnR0YWJsZV9uZXh0KCZpKSkgeworICAgIHVpbnRwdHJfdCBrID0gdXBiX2ludHRhYmxlX2l0ZXJfa2V5KCZpKTsKKyAgICB1cGJfaW50dGFibGVfaW5zZXJ0KCZuZXdfdCwgaywgdXBiX2ludHRhYmxlX2l0ZXJfdmFsdWUoJmkpKTsKKyAgfQorICBhc3NlcnQobmV3X3QuYXJyYXlfc2l6ZSA9PSBhcnJfc2l6ZSk7CisgIGFzc2VydChuZXdfdC50LnNpemVfbGcyID09IGhhc2hzaXplX2xnMik7CisgIHVwYl9pbnR0YWJsZV91bmluaXQodCk7CisgICp0ID0gbmV3X3Q7Cit9CisKKy8vIEl0ZXJhdGlvbi4KKworc3RhdGljIGNvbnN0IHVwYl90YWJlbnQgKmludF90YWJlbnQoY29uc3QgdXBiX2ludHRhYmxlX2l0ZXIgKmkpIHsKKyAgYXNzZXJ0KCFpLT5hcnJheV9wYXJ0KTsKKyAgcmV0dXJuICZpLT50LT50LmVudHJpZXNbaS0+aW5kZXhdOworfQorCitzdGF0aWMgX3VwYl92YWx1ZSBpbnRfYXJyZW50KGNvbnN0IHVwYl9pbnR0YWJsZV9pdGVyICppKSB7CisgIGFzc2VydChpLT5hcnJheV9wYXJ0KTsKKyAgcmV0dXJuIGktPnQtPmFycmF5W2ktPmluZGV4XTsKK30KKwordm9pZCB1cGJfaW50dGFibGVfYmVnaW4odXBiX2ludHRhYmxlX2l0ZXIgKmksIGNvbnN0IHVwYl9pbnR0YWJsZSAqdCkgeworICBpLT50ID0gdDsKKyAgaS0+aW5kZXggPSAtMTsKKyAgaS0+YXJyYXlfcGFydCA9IHRydWU7CisgIHVwYl9pbnR0YWJsZV9uZXh0KGkpOworfQorCit2b2lkIHVwYl9pbnR0YWJsZV9uZXh0KHVwYl9pbnR0YWJsZV9pdGVyICppdGVyKSB7CisgIGNvbnN0IHVwYl9pbnR0YWJsZSAqdCA9IGl0ZXItPnQ7CisgIGlmIChpdGVyLT5hcnJheV9wYXJ0KSB7CisgICAgd2hpbGUgKCsraXRlci0+aW5kZXggPCB0LT5hcnJheV9zaXplKSB7CisgICAgICBpZiAodXBiX2FycmhhcyhpbnRfYXJyZW50KGl0ZXIpKSkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgfQorICAgIGl0ZXItPmFycmF5X3BhcnQgPSBmYWxzZTsKKyAgICBpdGVyLT5pbmRleCA9IGJlZ2luKCZ0LT50KTsKKyAgfSBlbHNlIHsKKyAgICBpdGVyLT5pbmRleCA9IG5leHQoJnQtPnQsIGl0ZXItPmluZGV4KTsKKyAgfQorfQorCitib29sIHVwYl9pbnR0YWJsZV9kb25lKGNvbnN0IHVwYl9pbnR0YWJsZV9pdGVyICppKSB7CisgIGlmIChpLT5hcnJheV9wYXJ0KSB7CisgICAgcmV0dXJuIGktPmluZGV4ID49IGktPnQtPmFycmF5X3NpemUgfHwKKyAgICAgICAgICAgIXVwYl9hcnJoYXMoaW50X2FycmVudChpKSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGktPmluZGV4ID49IHVwYl90YWJsZV9zaXplKCZpLT50LT50KSB8fAorICAgICAgICAgICB1cGJfdGFiZW50X2lzZW1wdHkoaW50X3RhYmVudChpKSk7CisgIH0KK30KKwordWludHB0cl90IHVwYl9pbnR0YWJsZV9pdGVyX2tleShjb25zdCB1cGJfaW50dGFibGVfaXRlciAqaSkgeworICBhc3NlcnQoIXVwYl9pbnR0YWJsZV9kb25lKGkpKTsKKyAgcmV0dXJuIGktPmFycmF5X3BhcnQgPyBpLT5pbmRleCA6IGludF90YWJlbnQoaSktPmtleS5udW07Cit9CisKK3VwYl92YWx1ZSB1cGJfaW50dGFibGVfaXRlcl92YWx1ZShjb25zdCB1cGJfaW50dGFibGVfaXRlciAqaSkgeworICBhc3NlcnQoIXVwYl9pbnR0YWJsZV9kb25lKGkpKTsKKyAgcmV0dXJuIF91cGJfdmFsdWVfdmFsKAorICAgICAgaS0+YXJyYXlfcGFydCA/IGktPnQtPmFycmF5W2ktPmluZGV4XSA6IGludF90YWJlbnQoaSktPnZhbCwKKyAgICAgIGktPnQtPnQuY3R5cGUpOworfQorCit2b2lkIHVwYl9pbnR0YWJsZV9pdGVyX3NldGRvbmUodXBiX2ludHRhYmxlX2l0ZXIgKmkpIHsKKyAgaS0+aW5kZXggPSBTSVpFX01BWDsKKyAgaS0+YXJyYXlfcGFydCA9IGZhbHNlOworfQorCitib29sIHVwYl9pbnR0YWJsZV9pdGVyX2lzZXF1YWwoY29uc3QgdXBiX2ludHRhYmxlX2l0ZXIgKmkxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ludHRhYmxlX2l0ZXIgKmkyKSB7CisgIGlmICh1cGJfaW50dGFibGVfZG9uZShpMSkgJiYgdXBiX2ludHRhYmxlX2RvbmUoaTIpKQorICAgIHJldHVybiB0cnVlOworICByZXR1cm4gaTEtPnQgPT0gaTItPnQgJiYgaTEtPmluZGV4ID09IGkyLT5pbmRleCAmJgorICAgICAgICAgaTEtPmFycmF5X3BhcnQgPT0gaTItPmFycmF5X3BhcnQ7Cit9CisKKyNpZmRlZiBVUEJfVU5BTElHTkVEX1JFQURTX09LCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNdXJtdXJIYXNoMiwgYnkgQXVzdGluIEFwcGxlYnkgKHJlbGVhc2VkIGFzIHB1YmxpYyBkb21haW4pLgorLy8gUmVmb3JtYXR0ZWQgYW5kIEM5OS1pZmllZCBieSBKb3NodWEgSGFiZXJtYW4uCisvLyBOb3RlIC0gVGhpcyBjb2RlIG1ha2VzIGEgZmV3IGFzc3VtcHRpb25zIGFib3V0IGhvdyB5b3VyIG1hY2hpbmUgYmVoYXZlcyAtCisvLyAgIDEuIFdlIGNhbiByZWFkIGEgNC1ieXRlIHZhbHVlIGZyb20gYW55IGFkZHJlc3Mgd2l0aG91dCBjcmFzaGluZworLy8gICAyLiBzaXplb2YoaW50KSA9PSA0IChpbiB1cGIgdGhpcyBsaW1pdGF0aW9uIGlzIHJlbW92ZWQgYnkgdXNpbmcgdWludDMyX3QKKy8vIEFuZCBpdCBoYXMgYSBmZXcgbGltaXRhdGlvbnMgLQorLy8gICAxLiBJdCB3aWxsIG5vdCB3b3JrIGluY3JlbWVudGFsbHkuCisvLyAgIDIuIEl0IHdpbGwgbm90IHByb2R1Y2UgdGhlIHNhbWUgcmVzdWx0cyBvbiBsaXR0bGUtZW5kaWFuIGFuZCBiaWctZW5kaWFuCisvLyAgICAgIG1hY2hpbmVzLgordWludDMyX3QgTXVybXVySGFzaDIoY29uc3Qgdm9pZCAqa2V5LCBzaXplX3QgbGVuLCB1aW50MzJfdCBzZWVkKSB7CisgIC8vICdtJyBhbmQgJ3InIGFyZSBtaXhpbmcgY29uc3RhbnRzIGdlbmVyYXRlZCBvZmZsaW5lLgorICAvLyBUaGV5J3JlIG5vdCByZWFsbHkgJ21hZ2ljJywgdGhleSBqdXN0IGhhcHBlbiB0byB3b3JrIHdlbGwuCisgIGNvbnN0IHVpbnQzMl90IG0gPSAweDViZDFlOTk1OworICBjb25zdCBpbnQzMl90IHIgPSAyNDsKKworICAvLyBJbml0aWFsaXplIHRoZSBoYXNoIHRvIGEgJ3JhbmRvbScgdmFsdWUKKyAgdWludDMyX3QgaCA9IHNlZWQgXiBsZW47CisKKyAgLy8gTWl4IDQgYnl0ZXMgYXQgYSB0aW1lIGludG8gdGhlIGhhc2gKKyAgY29uc3QgdWludDhfdCAqIGRhdGEgPSAoY29uc3QgdWludDhfdCAqKWtleTsKKyAgd2hpbGUobGVuID49IDQpIHsKKyAgICB1aW50MzJfdCBrID0gKih1aW50MzJfdCAqKWRhdGE7CisKKyAgICBrICo9IG07CisgICAgayBePSBrID4+IHI7CisgICAgayAqPSBtOworCisgICAgaCAqPSBtOworICAgIGggXj0gazsKKworICAgIGRhdGEgKz0gNDsKKyAgICBsZW4gLT0gNDsKKyAgfQorCisgIC8vIEhhbmRsZSB0aGUgbGFzdCBmZXcgYnl0ZXMgb2YgdGhlIGlucHV0IGFycmF5CisgIHN3aXRjaChsZW4pIHsKKyAgICBjYXNlIDM6IGggXj0gZGF0YVsyXSA8PCAxNjsKKyAgICBjYXNlIDI6IGggXj0gZGF0YVsxXSA8PCA4OworICAgIGNhc2UgMTogaCBePSBkYXRhWzBdOyBoICo9IG07CisgIH07CisKKyAgLy8gRG8gYSBmZXcgZmluYWwgbWl4ZXMgb2YgdGhlIGhhc2ggdG8gZW5zdXJlIHRoZSBsYXN0IGZldworICAvLyBieXRlcyBhcmUgd2VsbC1pbmNvcnBvcmF0ZWQuCisgIGggXj0gaCA+PiAxMzsKKyAgaCAqPSBtOworICBoIF49IGggPj4gMTU7CisKKyAgcmV0dXJuIGg7Cit9CisKKyNlbHNlIC8vICFVUEJfVU5BTElHTkVEX1JFQURTX09LCisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE11cm11ckhhc2hBbGlnbmVkMiwgYnkgQXVzdGluIEFwcGxlYnkKKy8vIFNhbWUgYWxnb3JpdGhtIGFzIE11cm11ckhhc2gyLCBidXQgb25seSBkb2VzIGFsaWduZWQgcmVhZHMgLSBzaG91bGQgYmUgc2FmZXIKKy8vIG9uIGNlcnRhaW4gcGxhdGZvcm1zLgorLy8gUGVyZm9ybWFuY2Ugd2lsbCBiZSBsb3dlciB0aGFuIE11cm11ckhhc2gyCisKKyNkZWZpbmUgTUlYKGgsayxtKSB7IGsgKj0gbTsgayBePSBrID4+IHI7IGsgKj0gbTsgaCAqPSBtOyBoIF49IGs7IH0KKwordWludDMyX3QgTXVybXVySGFzaDIoY29uc3Qgdm9pZCAqIGtleSwgc2l6ZV90IGxlbiwgdWludDMyX3Qgc2VlZCkgeworICBjb25zdCB1aW50MzJfdCBtID0gMHg1YmQxZTk5NTsKKyAgY29uc3QgaW50MzJfdCByID0gMjQ7CisgIGNvbnN0IHVpbnQ4X3QgKiBkYXRhID0gKGNvbnN0IHVpbnQ4X3QgKilrZXk7CisgIHVpbnQzMl90IGggPSBzZWVkIF4gbGVuOworICB1aW50OF90IGFsaWduID0gKHVpbnRwdHJfdClkYXRhICYgMzsKKworICBpZihhbGlnbiAmJiAobGVuID49IDQpKSB7CisgICAgLy8gUHJlLWxvYWQgdGhlIHRlbXAgcmVnaXN0ZXJzCisgICAgdWludDMyX3QgdCA9IDAsIGQgPSAwOworCisgICAgc3dpdGNoKGFsaWduKSB7CisgICAgICBjYXNlIDE6IHQgfD0gZGF0YVsyXSA8PCAxNjsKKyAgICAgIGNhc2UgMjogdCB8PSBkYXRhWzFdIDw8IDg7CisgICAgICBjYXNlIDM6IHQgfD0gZGF0YVswXTsKKyAgICB9CisKKyAgICB0IDw8PSAoOCAqIGFsaWduKTsKKworICAgIGRhdGEgKz0gNC1hbGlnbjsKKyAgICBsZW4gLT0gNC1hbGlnbjsKKworICAgIGludDMyX3Qgc2wgPSA4ICogKDQtYWxpZ24pOworICAgIGludDMyX3Qgc3IgPSA4ICogYWxpZ247CisKKyAgICAvLyBNaXgKKworICAgIHdoaWxlKGxlbiA+PSA0KSB7CisgICAgICBkID0gKih1aW50MzJfdCAqKWRhdGE7CisgICAgICB0ID0gKHQgPj4gc3IpIHwgKGQgPDwgc2wpOworCisgICAgICB1aW50MzJfdCBrID0gdDsKKworICAgICAgTUlYKGgsayxtKTsKKworICAgICAgdCA9IGQ7CisKKyAgICAgIGRhdGEgKz0gNDsKKyAgICAgIGxlbiAtPSA0OworICAgIH0KKworICAgIC8vIEhhbmRsZSBsZWZ0b3ZlciBkYXRhIGluIHRlbXAgcmVnaXN0ZXJzCisKKyAgICBkID0gMDsKKworICAgIGlmKGxlbiA+PSBhbGlnbikgeworICAgICAgc3dpdGNoKGFsaWduKSB7CisgICAgICAgIGNhc2UgMzogZCB8PSBkYXRhWzJdIDw8IDE2OworICAgICAgICBjYXNlIDI6IGQgfD0gZGF0YVsxXSA8PCA4OworICAgICAgICBjYXNlIDE6IGQgfD0gZGF0YVswXTsKKyAgICAgIH0KKworICAgICAgdWludDMyX3QgayA9ICh0ID4+IHNyKSB8IChkIDw8IHNsKTsKKyAgICAgIE1JWChoLGssbSk7CisKKyAgICAgIGRhdGEgKz0gYWxpZ247CisgICAgICBsZW4gLT0gYWxpZ247CisKKyAgICAgIC8vLS0tLS0tLS0tLQorICAgICAgLy8gSGFuZGxlIHRhaWwgYnl0ZXMKKworICAgICAgc3dpdGNoKGxlbikgeworICAgICAgICBjYXNlIDM6IGggXj0gZGF0YVsyXSA8PCAxNjsKKyAgICAgICAgY2FzZSAyOiBoIF49IGRhdGFbMV0gPDwgODsKKyAgICAgICAgY2FzZSAxOiBoIF49IGRhdGFbMF07IGggKj0gbTsKKyAgICAgIH07CisgICAgfSBlbHNlIHsKKyAgICAgIHN3aXRjaChsZW4pIHsKKyAgICAgICAgY2FzZSAzOiBkIHw9IGRhdGFbMl0gPDwgMTY7CisgICAgICAgIGNhc2UgMjogZCB8PSBkYXRhWzFdIDw8IDg7CisgICAgICAgIGNhc2UgMTogZCB8PSBkYXRhWzBdOworICAgICAgICBjYXNlIDA6IGggXj0gKHQgPj4gc3IpIHwgKGQgPDwgc2wpOyBoICo9IG07CisgICAgICB9CisgICAgfQorCisgICAgaCBePSBoID4+IDEzOworICAgIGggKj0gbTsKKyAgICBoIF49IGggPj4gMTU7CisKKyAgICByZXR1cm4gaDsKKyAgfSBlbHNlIHsKKyAgICB3aGlsZShsZW4gPj0gNCkgeworICAgICAgdWludDMyX3QgayA9ICoodWludDMyX3QgKilkYXRhOworCisgICAgICBNSVgoaCxrLG0pOworCisgICAgICBkYXRhICs9IDQ7CisgICAgICBsZW4gLT0gNDsKKyAgICB9CisKKyAgICAvLy0tLS0tLS0tLS0KKyAgICAvLyBIYW5kbGUgdGFpbCBieXRlcworCisgICAgc3dpdGNoKGxlbikgeworICAgICAgY2FzZSAzOiBoIF49IGRhdGFbMl0gPDwgMTY7CisgICAgICBjYXNlIDI6IGggXj0gZGF0YVsxXSA8PCA4OworICAgICAgY2FzZSAxOiBoIF49IGRhdGFbMF07IGggKj0gbTsKKyAgICB9OworCisgICAgaCBePSBoID4+IDEzOworICAgIGggKj0gbTsKKyAgICBoIF49IGggPj4gMTU7CisKKyAgICByZXR1cm4gaDsKKyAgfQorfQorI3VuZGVmIE1JWAorCisjZW5kaWYgLy8gVVBCX1VOQUxJR05FRF9SRUFEU19PSworLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAwOS0yMDEyIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqLworCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdGRhcmcuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCitib29sIHVwYl9kdW1wdG9zdGRlcnIodm9pZCAqY2xvc3VyZSwgY29uc3QgdXBiX3N0YXR1cyogc3RhdHVzKSB7CisgIFVQQl9VTlVTRUQoY2xvc3VyZSk7CisgIGZwcmludGYoc3RkZXJyLCAiJXNcbiIsIHVwYl9zdGF0dXNfZXJybXNnKHN0YXR1cykpOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIEd1YXJhbnRlZSBudWxsLXRlcm1pbmF0aW9uIGFuZCBwcm92aWRlIGVsbGlwc2lzIHRydW5jYXRpb24uCisvLyBJdCBtYXkgYmUgdGVtcHRpbmcgdG8gIm9wdGltaXplIiB0aGlzIGJ5IGluaXRpYWxpemluZyB0aGVzZSBmaW5hbAorLy8gZm91ciBieXRlcyB1cC1mcm9udCBhbmQgdGhlbiBiZWluZyBjYXJlZnVsIG5ldmVyIHRvIG92ZXJ3cml0ZSB0aGVtLAorLy8gdGhpcyBpcyBzYWZlciBhbmQgc2ltcGxlci4KK3N0YXRpYyB2b2lkIG51bGx6KHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBjb25zdCBjaGFyICplbGxpcHNpcyA9ICIuLi4iOworICBzaXplX3QgbGVuID0gc3RybGVuKGVsbGlwc2lzKTsKKyAgYXNzZXJ0KHNpemVvZihzdGF0dXMtPm1zZykgPiBsZW4pOworICBtZW1jcHkoc3RhdHVzLT5tc2cgKyBzaXplb2Yoc3RhdHVzLT5tc2cpIC0gbGVuLCBlbGxpcHNpcywgbGVuKTsKK30KKwordm9pZCB1cGJfc3RhdHVzX2NsZWFyKHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBpZiAoIXN0YXR1cykgcmV0dXJuOworICBzdGF0dXMtPm9rXyA9IHRydWU7CisgIHN0YXR1cy0+Y29kZV8gPSAwOworICBzdGF0dXMtPm1zZ1swXSA9ICdcMCc7Cit9CisKK2Jvb2wgdXBiX29rKGNvbnN0IHVwYl9zdGF0dXMgKnN0YXR1cykgeyByZXR1cm4gc3RhdHVzLT5va187IH0KKwordXBiX2Vycm9yc3BhY2UgKnVwYl9zdGF0dXNfZXJyc3BhY2UoY29uc3QgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIHJldHVybiBzdGF0dXMtPmVycm9yX3NwYWNlXzsKK30KKworaW50IHVwYl9zdGF0dXNfZXJyY29kZShjb25zdCB1cGJfc3RhdHVzICpzdGF0dXMpIHsgcmV0dXJuIHN0YXR1cy0+Y29kZV87IH0KKworY29uc3QgY2hhciAqdXBiX3N0YXR1c19lcnJtc2coY29uc3QgdXBiX3N0YXR1cyAqc3RhdHVzKSB7IHJldHVybiBzdGF0dXMtPm1zZzsgfQorCit2b2lkIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHVwYl9zdGF0dXMgKnN0YXR1cywgY29uc3QgY2hhciAqbXNnKSB7CisgIGlmICghc3RhdHVzKSByZXR1cm47CisgIHN0YXR1cy0+b2tfID0gZmFsc2U7CisgIHN0cm5jcHkoc3RhdHVzLT5tc2csIG1zZywgc2l6ZW9mKHN0YXR1cy0+bXNnKSk7CisgIG51bGx6KHN0YXR1cyk7Cit9CisKK3ZvaWQgdXBiX3N0YXR1c19zZXRlcnJmKHVwYl9zdGF0dXMgKnN0YXR1cywgY29uc3QgY2hhciAqZm10LCAuLi4pIHsKKyAgdmFfbGlzdCBhcmdzOworICB2YV9zdGFydChhcmdzLCBmbXQpOworICB1cGJfc3RhdHVzX3ZzZXRlcnJmKHN0YXR1cywgZm10LCBhcmdzKTsKKyAgdmFfZW5kKGFyZ3MpOworfQorCit2b2lkIHVwYl9zdGF0dXNfdnNldGVycmYodXBiX3N0YXR1cyAqc3RhdHVzLCBjb25zdCBjaGFyICpmbXQsIHZhX2xpc3QgYXJncykgeworICBpZiAoIXN0YXR1cykgcmV0dXJuOworICBzdGF0dXMtPm9rXyA9IGZhbHNlOworICB2c25wcmludGYoc3RhdHVzLT5tc2csIHNpemVvZihzdGF0dXMtPm1zZyksIGZtdCwgYXJncyk7CisgIG51bGx6KHN0YXR1cyk7Cit9CisKK3ZvaWQgdXBiX3N0YXR1c19zZXRlcnJjb2RlKHVwYl9zdGF0dXMgKnN0YXR1cywgdXBiX2Vycm9yc3BhY2UgKnNwYWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvZGUpIHsKKyAgaWYgKCFzdGF0dXMpIHJldHVybjsKKyAgc3RhdHVzLT5va18gPSBmYWxzZTsKKyAgc3RhdHVzLT5lcnJvcl9zcGFjZV8gPSBzcGFjZTsKKyAgc3RhdHVzLT5jb2RlXyA9IGNvZGU7CisgIHNwYWNlLT5zZXRfbWVzc2FnZShzdGF0dXMsIGNvZGUpOworfQorCit2b2lkIHVwYl9zdGF0dXNfY29weSh1cGJfc3RhdHVzICp0bywgY29uc3QgdXBiX3N0YXR1cyAqZnJvbSkgeworICBpZiAoIXRvKSByZXR1cm47CisgICp0byA9ICpmcm9tOworfQorLy8gVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdXBiYyAodGhlIHVwYiBjb21waWxlcikuCisvLyBEbyBub3QgZWRpdCAtLSB5b3VyIGNoYW5nZXMgd2lsbCBiZSBkaXNjYXJkZWQgd2hlbiB0aGUgZmlsZSBpcworLy8gcmVnZW5lcmF0ZWQuCisKKworc3RhdGljIGNvbnN0IHVwYl9tc2dkZWYgbXNnc1syMF07CitzdGF0aWMgY29uc3QgdXBiX2ZpZWxkZGVmIGZpZWxkc1s4MV07CitzdGF0aWMgY29uc3QgdXBiX2VudW1kZWYgZW51bXNbNF07CitzdGF0aWMgY29uc3QgdXBiX3RhYmVudCBzdHJlbnRyaWVzWzIzNl07CitzdGF0aWMgY29uc3QgdXBiX3RhYmVudCBpbnRlbnRyaWVzWzE0XTsKK3N0YXRpYyBjb25zdCBfdXBiX3ZhbHVlIGFycmF5c1syMzJdOworCisjaWZkZWYgVVBCX0RFQlVHX1JFRlMKK3N0YXRpYyB1cGJfaW50dGFibGUgcmVmdGFibGVzWzIxMl07CisjZW5kaWYKKworc3RhdGljIGNvbnN0IHVwYl9tc2dkZWYgbXNnc1syMF0gPSB7CisgIFVQQl9NU0dERUZfSU5JVCgiZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byIsIDI3LCA2LCBVUEJfSU5UVEFCTEVfSU5JVCgwLCAwLCBVUEJfQ1RZUEVfUFRSLCAwLCBOVUxMLCAmYXJyYXlzWzBdLCA4LCA3KSwgVVBCX1NUUlRBQkxFX0lOSVQoNywgMTUsIFVQQl9DVFlQRV9QVFIsIDQsICZzdHJlbnRyaWVzWzBdKSwmcmVmdGFibGVzWzBdLCAmcmVmdGFibGVzWzFdKSwKKyAgVVBCX01TR0RFRl9JTklUKCJnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlIiwgNCwgMCwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX1BUUiwgMCwgTlVMTCwgJmFycmF5c1s4XSwgMywgMiksIFVQQl9TVFJUQUJMRV9JTklUKDIsIDMsIFVQQl9DVFlQRV9QVFIsIDIsICZzdHJlbnRyaWVzWzE2XSksJnJlZnRhYmxlc1syXSwgJnJlZnRhYmxlc1szXSksCisgIFVQQl9NU0dERUZfSU5JVCgiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8iLCAxMSwgMiwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX1BUUiwgMCwgTlVMTCwgJmFycmF5c1sxMV0sIDQsIDMpLCBVUEJfU1RSVEFCTEVfSU5JVCgzLCAzLCBVUEJfQ1RZUEVfUFRSLCAyLCAmc3RyZW50cmllc1syMF0pLCZyZWZ0YWJsZXNbNF0sICZyZWZ0YWJsZXNbNV0pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyIsIDcsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDEsIDEsIFVQQl9DVFlQRV9QVFIsIDEsICZpbnRlbnRyaWVzWzBdLCAmYXJyYXlzWzE1XSwgOCwgMSksIFVQQl9TVFJUQUJMRV9JTklUKDIsIDMsIFVQQl9DVFlQRV9QVFIsIDIsICZzdHJlbnRyaWVzWzI0XSksJnJlZnRhYmxlc1s2XSwgJnJlZnRhYmxlc1s3XSksCisgIFVQQl9NU0dERUZfSU5JVCgiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byIsIDgsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDAsIDAsIFVQQl9DVFlQRV9QVFIsIDAsIE5VTEwsICZhcnJheXNbMjNdLCA0LCAzKSwgVVBCX1NUUlRBQkxFX0lOSVQoMywgMywgVVBCX0NUWVBFX1BUUiwgMiwgJnN0cmVudHJpZXNbMjhdKSwmcmVmdGFibGVzWzhdLCAmcmVmdGFibGVzWzldKSwKKyAgVVBCX01TR0RFRl9JTklUKCJnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyIsIDYsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDEsIDEsIFVQQl9DVFlQRV9QVFIsIDEsICZpbnRlbnRyaWVzWzJdLCAmYXJyYXlzWzI3XSwgNCwgMCksIFVQQl9TVFJUQUJMRV9JTklUKDEsIDMsIFVQQl9DVFlQRV9QVFIsIDIsICZzdHJlbnRyaWVzWzMyXSksJnJlZnRhYmxlc1sxMF0sICZyZWZ0YWJsZXNbMTFdKSwKKyAgVVBCX01TR0RFRl9JTklUKCJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8iLCAxOSwgMSwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX1BUUiwgMCwgTlVMTCwgJmFycmF5c1szMV0sIDksIDgpLCBVUEJfU1RSVEFCTEVfSU5JVCg4LCAxNSwgVVBCX0NUWVBFX1BUUiwgNCwgJnN0cmVudHJpZXNbMzZdKSwmcmVmdGFibGVzWzEyXSwgJnJlZnRhYmxlc1sxM10pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMiLCAxNCwgMSwgVVBCX0lOVFRBQkxFX0lOSVQoMSwgMSwgVVBCX0NUWVBFX1BUUiwgMSwgJmludGVudHJpZXNbNF0sICZhcnJheXNbNDBdLCAzMiwgNiksIFVQQl9TVFJUQUJMRV9JTklUKDcsIDE1LCBVUEJfQ1RZUEVfUFRSLCA0LCAmc3RyZW50cmllc1s1Ml0pLCZyZWZ0YWJsZXNbMTRdLCAmcmVmdGFibGVzWzE1XSksCisgIFVQQl9NU0dERUZfSU5JVCgiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8iLCAzOSwgNiwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX1BUUiwgMCwgTlVMTCwgJmFycmF5c1s3Ml0sIDEyLCAxMSksIFVQQl9TVFJUQUJMRV9JTklUKDExLCAxNSwgVVBCX0NUWVBFX1BUUiwgNCwgJnN0cmVudHJpZXNbNjhdKSwmcmVmdGFibGVzWzE2XSwgJnJlZnRhYmxlc1sxN10pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCIsIDYsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDAsIDAsIFVQQl9DVFlQRV9QVFIsIDAsIE5VTEwsICZhcnJheXNbODRdLCAyLCAxKSwgVVBCX1NUUlRBQkxFX0lOSVQoMSwgMywgVVBCX0NUWVBFX1BUUiwgMiwgJnN0cmVudHJpZXNbODRdKSwmcmVmdGFibGVzWzE4XSwgJnJlZnRhYmxlc1sxOV0pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyIsIDIxLCAxLCBVUEJfSU5UVEFCTEVfSU5JVCgxLCAxLCBVUEJfQ1RZUEVfUFRSLCAxLCAmaW50ZW50cmllc1s2XSwgJmFycmF5c1s4Nl0sIDY0LCA5KSwgVVBCX1NUUlRBQkxFX0lOSVQoMTAsIDE1LCBVUEJfQ1RZUEVfUFRSLCA0LCAmc3RyZW50cmllc1s4OF0pLCZyZWZ0YWJsZXNbMjBdLCAmcmVmdGFibGVzWzIxXSksCisgIFVQQl9NU0dERUZfSU5JVCgiZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIiwgOCwgMSwgVVBCX0lOVFRBQkxFX0lOSVQoMSwgMSwgVVBCX0NUWVBFX1BUUiwgMSwgJmludGVudHJpZXNbOF0sICZhcnJheXNbMTUwXSwgMTYsIDIpLCBVUEJfU1RSVEFCTEVfSU5JVCgzLCAzLCBVUEJfQ1RZUEVfUFRSLCAyLCAmc3RyZW50cmllc1sxMDRdKSwmcmVmdGFibGVzWzIyXSwgJnJlZnRhYmxlc1syM10pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8iLCAxMywgMSwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX1BUUiwgMCwgTlVMTCwgJmFycmF5c1sxNjZdLCA1LCA0KSwgVVBCX1NUUlRBQkxFX0lOSVQoNCwgNywgVVBCX0NUWVBFX1BUUiwgMywgJnN0cmVudHJpZXNbMTA4XSksJnJlZnRhYmxlc1syNF0sICZyZWZ0YWJsZXNbMjVdKSwKKyAgVVBCX01TR0RFRl9JTklUKCJnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyIsIDYsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDEsIDEsIFVQQl9DVFlQRV9QVFIsIDEsICZpbnRlbnRyaWVzWzEwXSwgJmFycmF5c1sxNzFdLCA0LCAwKSwgVVBCX1NUUlRBQkxFX0lOSVQoMSwgMywgVVBCX0NUWVBFX1BUUiwgMiwgJnN0cmVudHJpZXNbMTE2XSksJnJlZnRhYmxlc1syNl0sICZyZWZ0YWJsZXNbMjddKSwKKyAgVVBCX01TR0RFRl9JTklUKCJnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byIsIDExLCAyLCBVUEJfSU5UVEFCTEVfSU5JVCgwLCAwLCBVUEJfQ1RZUEVfUFRSLCAwLCBOVUxMLCAmYXJyYXlzWzE3NV0sIDQsIDMpLCBVUEJfU1RSVEFCTEVfSU5JVCgzLCAzLCBVUEJfQ1RZUEVfUFRSLCAyLCAmc3RyZW50cmllc1sxMjBdKSwmcmVmdGFibGVzWzI4XSwgJnJlZnRhYmxlc1syOV0pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyIsIDYsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDEsIDEsIFVQQl9DVFlQRV9QVFIsIDEsICZpbnRlbnRyaWVzWzEyXSwgJmFycmF5c1sxNzldLCA0LCAwKSwgVVBCX1NUUlRBQkxFX0lOSVQoMSwgMywgVVBCX0NUWVBFX1BUUiwgMiwgJnN0cmVudHJpZXNbMTI0XSksJnJlZnRhYmxlc1szMF0sICZyZWZ0YWJsZXNbMzFdKSwKKyAgVVBCX01TR0RFRl9JTklUKCJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8iLCA2LCAxLCBVUEJfSU5UVEFCTEVfSU5JVCgwLCAwLCBVUEJfQ1RZUEVfUFRSLCAwLCBOVUxMLCAmYXJyYXlzWzE4M10sIDIsIDEpLCBVUEJfU1RSVEFCTEVfSU5JVCgxLCAzLCBVUEJfQ1RZUEVfUFRSLCAyLCAmc3RyZW50cmllc1sxMjhdKSwmcmVmdGFibGVzWzMyXSwgJnJlZnRhYmxlc1szM10pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiIsIDE0LCAwLCBVUEJfSU5UVEFCTEVfSU5JVCgwLCAwLCBVUEJfQ1RZUEVfUFRSLCAwLCBOVUxMLCAmYXJyYXlzWzE4NV0sIDUsIDQpLCBVUEJfU1RSVEFCTEVfSU5JVCg0LCA3LCBVUEJfQ1RZUEVfUFRSLCAzLCAmc3RyZW50cmllc1sxMzJdKSwmcmVmdGFibGVzWzM0XSwgJnJlZnRhYmxlc1szNV0pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIiwgMTgsIDEsIFVQQl9JTlRUQUJMRV9JTklUKDAsIDAsIFVQQl9DVFlQRV9QVFIsIDAsIE5VTEwsICZhcnJheXNbMTkwXSwgOSwgNyksIFVQQl9TVFJUQUJMRV9JTklUKDcsIDE1LCBVUEJfQ1RZUEVfUFRSLCA0LCAmc3RyZW50cmllc1sxNDBdKSwmcmVmdGFibGVzWzM2XSwgJnJlZnRhYmxlc1szN10pLAorICBVUEJfTVNHREVGX0lOSVQoImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0IiwgNiwgMCwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX1BUUiwgMCwgTlVMTCwgJmFycmF5c1sxOTldLCAzLCAyKSwgVVBCX1NUUlRBQkxFX0lOSVQoMiwgMywgVVBCX0NUWVBFX1BUUiwgMiwgJnN0cmVudHJpZXNbMTU2XSksJnJlZnRhYmxlc1szOF0sICZyZWZ0YWJsZXNbMzldKSwKK307CisKK3N0YXRpYyBjb25zdCB1cGJfZmllbGRkZWYgZmllbGRzWzgxXSA9IHsKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9TVFJJTkcsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAiYWdncmVnYXRlX3ZhbHVlIiwgOCwgJm1zZ3NbMThdLCBOVUxMLCAxNSwgNiwgezB9LCZyZWZ0YWJsZXNbNDBdLCAmcmVmdGFibGVzWzQxXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJhbGxvd19hbGlhcyIsIDIsICZtc2dzWzNdLCBOVUxMLCA2LCAxLCB7MH0sJnJlZnRhYmxlc1s0Ml0sICZyZWZ0YWJsZXNbNDNdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9CT09MLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImNjX2dlbmVyaWNfc2VydmljZXMiLCAxNiwgJm1zZ3NbMTBdLCBOVUxMLCAxNywgNiwgezB9LCZyZWZ0YWJsZXNbNDRdLCAmcmVmdGFibGVzWzQ1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfRU5VTSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJjdHlwZSIsIDEsICZtc2dzWzddLCBVUEJfVVBDQVNUKCZlbnVtc1syXSksIDYsIDEsIHswfSwmcmVmdGFibGVzWzQ2XSwgJnJlZnRhYmxlc1s0N10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJkZWZhdWx0X3ZhbHVlIiwgNywgJm1zZ3NbNl0sIE5VTEwsIDE2LCA3LCB7MH0sJnJlZnRhYmxlc1s0OF0sICZyZWZ0YWJsZXNbNDldKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9TVFJJTkcsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAiZGVwZW5kZW5jeSIsIDMsICZtc2dzWzhdLCBOVUxMLCAzMCwgOCwgezB9LCZyZWZ0YWJsZXNbNTBdLCAmcmVmdGFibGVzWzUxXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJkZXByZWNhdGVkIiwgMywgJm1zZ3NbN10sIE5VTEwsIDgsIDMsIHswfSwmcmVmdGFibGVzWzUyXSwgJnJlZnRhYmxlc1s1M10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX0RPVUJMRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJkb3VibGVfdmFsdWUiLCA2LCAmbXNnc1sxOF0sIE5VTEwsIDExLCA0LCB7MH0sJnJlZnRhYmxlc1s1NF0sICZyZWZ0YWJsZXNbNTVdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9JTlQzMiwgVVBCX0lOVEZNVF9WQVJJQUJMRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJlbmQiLCAyLCAmbXNnc1sxXSwgTlVMTCwgMywgMSwgezB9LCZyZWZ0YWJsZXNbNTZdLCAmcmVmdGFibGVzWzU3XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVBFQVRFRCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJlbnVtX3R5cGUiLCA0LCAmbXNnc1swXSwgVVBCX1VQQ0FTVCgmbXNnc1syXSksIDE2LCAyLCB7MH0sJnJlZnRhYmxlc1s1OF0sICZyZWZ0YWJsZXNbNTldKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImVudW1fdHlwZSIsIDUsICZtc2dzWzhdLCBVUEJfVVBDQVNUKCZtc2dzWzJdKSwgMTMsIDEsIHswfSwmcmVmdGFibGVzWzYwXSwgJnJlZnRhYmxlc1s2MV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJleHBlcmltZW50YWxfbWFwX2tleSIsIDksICZtc2dzWzddLCBOVUxMLCAxMCwgNSwgezB9LCZyZWZ0YWJsZXNbNjJdLCAmcmVmdGFibGVzWzYzXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImV4dGVuZGVlIiwgMiwgJm1zZ3NbNl0sIE5VTEwsIDcsIDIsIHswfSwmcmVmdGFibGVzWzY0XSwgJnJlZnRhYmxlc1s2NV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAiZXh0ZW5zaW9uIiwgNywgJm1zZ3NbOF0sIFVQQl9VUENBU1QoJm1zZ3NbNl0pLCAxOSwgMywgezB9LCZyZWZ0YWJsZXNbNjZdLCAmcmVmdGFibGVzWzY3XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVBFQVRFRCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJleHRlbnNpb24iLCA2LCAmbXNnc1swXSwgVVBCX1VQQ0FTVCgmbXNnc1s2XSksIDIyLCA0LCB7MH0sJnJlZnRhYmxlc1s2OF0sICZyZWZ0YWJsZXNbNjldKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImV4dGVuc2lvbl9yYW5nZSIsIDUsICZtc2dzWzBdLCBVUEJfVVBDQVNUKCZtc2dzWzFdKSwgMTksIDMsIHswfSwmcmVmdGFibGVzWzcwXSwgJnJlZnRhYmxlc1s3MV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAiZmllbGQiLCAyLCAmbXNnc1swXSwgVVBCX1VQQ0FTVCgmbXNnc1s2XSksIDEwLCAwLCB7MH0sJnJlZnRhYmxlc1s3Ml0sICZyZWZ0YWJsZXNbNzNdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImZpbGUiLCAxLCAmbXNnc1s5XSwgVVBCX1VQQ0FTVCgmbXNnc1s4XSksIDUsIDAsIHswfSwmcmVmdGFibGVzWzc0XSwgJnJlZnRhYmxlc1s3NV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJnb19wYWNrYWdlIiwgMTEsICZtc2dzWzEwXSwgTlVMTCwgMTQsIDUsIHswfSwmcmVmdGFibGVzWzc2XSwgJnJlZnRhYmxlc1s3N10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJpZGVudGlmaWVyX3ZhbHVlIiwgMywgJm1zZ3NbMThdLCBOVUxMLCA2LCAxLCB7MH0sJnJlZnRhYmxlc1s3OF0sICZyZWZ0YWJsZXNbNzldKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9TVFJJTkcsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAiaW5wdXRfdHlwZSIsIDIsICZtc2dzWzEyXSwgTlVMTCwgNywgMiwgezB9LCZyZWZ0YWJsZXNbODBdLCAmcmVmdGFibGVzWzgxXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVFVSVJFRCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJpc19leHRlbnNpb24iLCAyLCAmbXNnc1sxOV0sIE5VTEwsIDUsIDEsIHswfSwmcmVmdGFibGVzWzgyXSwgJnJlZnRhYmxlc1s4M10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX0JPT0wsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAiamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2giLCAyMCwgJm1zZ3NbMTBdLCBOVUxMLCAyMCwgOSwgezB9LCZyZWZ0YWJsZXNbODRdLCAmcmVmdGFibGVzWzg1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJqYXZhX2dlbmVyaWNfc2VydmljZXMiLCAxNywgJm1zZ3NbMTBdLCBOVUxMLCAxOCwgNywgezB9LCZyZWZ0YWJsZXNbODZdLCAmcmVmdGFibGVzWzg3XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJqYXZhX211bHRpcGxlX2ZpbGVzIiwgMTAsICZtc2dzWzEwXSwgTlVMTCwgMTMsIDQsIHswfSwmcmVmdGFibGVzWzg4XSwgJnJlZnRhYmxlc1s4OV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJqYXZhX291dGVyX2NsYXNzbmFtZSIsIDgsICZtc2dzWzEwXSwgTlVMTCwgOSwgMiwgezB9LCZyZWZ0YWJsZXNbOTBdLCAmcmVmdGFibGVzWzkxXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImphdmFfcGFja2FnZSIsIDEsICZtc2dzWzEwXSwgTlVMTCwgNiwgMSwgezB9LCZyZWZ0YWJsZXNbOTJdLCAmcmVmdGFibGVzWzkzXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfRU5VTSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJsYWJlbCIsIDQsICZtc2dzWzZdLCBVUEJfVVBDQVNUKCZlbnVtc1swXSksIDExLCA0LCB7MH0sJnJlZnRhYmxlc1s5NF0sICZyZWZ0YWJsZXNbOTVdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9CT09MLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImxhenkiLCA1LCAmbXNnc1s3XSwgTlVMTCwgOSwgNCwgezB9LCZyZWZ0YWJsZXNbOTZdLCAmcmVmdGFibGVzWzk3XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgImxlYWRpbmdfY29tbWVudHMiLCAzLCAmbXNnc1sxN10sIE5VTEwsIDgsIDIsIHswfSwmcmVmdGFibGVzWzk4XSwgJnJlZnRhYmxlc1s5OV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAibG9jYXRpb24iLCAxLCAmbXNnc1sxNl0sIFVQQl9VUENBU1QoJm1zZ3NbMTddKSwgNSwgMCwgezB9LCZyZWZ0YWJsZXNbMTAwXSwgJnJlZnRhYmxlc1sxMDFdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9CT09MLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0IiwgMSwgJm1zZ3NbMTFdLCBOVUxMLCA2LCAxLCB7MH0sJnJlZnRhYmxlc1sxMDJdLCAmcmVmdGFibGVzWzEwM10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAibWVzc2FnZV90eXBlIiwgNCwgJm1zZ3NbOF0sIFVQQl9VUENBU1QoJm1zZ3NbMF0pLCAxMCwgMCwgezB9LCZyZWZ0YWJsZXNbMTA0XSwgJnJlZnRhYmxlc1sxMDVdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm1ldGhvZCIsIDIsICZtc2dzWzE0XSwgVVBCX1VQQ0FTVCgmbXNnc1sxMl0pLCA2LCAwLCB7MH0sJnJlZnRhYmxlc1sxMDZdLCAmcmVmdGFibGVzWzEwN10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJuYW1lIiwgMSwgJm1zZ3NbOF0sIE5VTEwsIDIyLCA2LCB7MH0sJnJlZnRhYmxlc1sxMDhdLCAmcmVmdGFibGVzWzEwOV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJuYW1lIiwgMSwgJm1zZ3NbMTRdLCBOVUxMLCA4LCAyLCB7MH0sJnJlZnRhYmxlc1sxMTBdLCAmcmVmdGFibGVzWzExMV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAibmFtZSIsIDIsICZtc2dzWzE4XSwgVVBCX1VQQ0FTVCgmbXNnc1sxOV0pLCA1LCAwLCB7MH0sJnJlZnRhYmxlc1sxMTJdLCAmcmVmdGFibGVzWzExM10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJuYW1lIiwgMSwgJm1zZ3NbNF0sIE5VTEwsIDQsIDEsIHswfSwmcmVmdGFibGVzWzExNF0sICZyZWZ0YWJsZXNbMTE1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm5hbWUiLCAxLCAmbXNnc1swXSwgTlVMTCwgMjQsIDYsIHswfSwmcmVmdGFibGVzWzExNl0sICZyZWZ0YWJsZXNbMTE3XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm5hbWUiLCAxLCAmbXNnc1sxMl0sIE5VTEwsIDQsIDEsIHswfSwmcmVmdGFibGVzWzExOF0sICZyZWZ0YWJsZXNbMTE5XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm5hbWUiLCAxLCAmbXNnc1syXSwgTlVMTCwgOCwgMiwgezB9LCZyZWZ0YWJsZXNbMTIwXSwgJnJlZnRhYmxlc1sxMjFdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9TVFJJTkcsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAibmFtZSIsIDEsICZtc2dzWzZdLCBOVUxMLCA0LCAxLCB7MH0sJnJlZnRhYmxlc1sxMjJdLCAmcmVmdGFibGVzWzEyM10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVRVUlSRUQsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJuYW1lX3BhcnQiLCAxLCAmbXNnc1sxOV0sIE5VTEwsIDIsIDAsIHswfSwmcmVmdGFibGVzWzEyNF0sICZyZWZ0YWJsZXNbMTI1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfSU5UNjQsIFVQQl9JTlRGTVRfVkFSSUFCTEUsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAibmVnYXRpdmVfaW50X3ZhbHVlIiwgNSwgJm1zZ3NbMThdLCBOVUxMLCAxMCwgMywgezB9LCZyZWZ0YWJsZXNbMTI2XSwgJnJlZnRhYmxlc1sxMjddKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm5lc3RlZF90eXBlIiwgMywgJm1zZ3NbMF0sIFVQQl9VUENBU1QoJm1zZ3NbMF0pLCAxMywgMSwgezB9LCZyZWZ0YWJsZXNbMTI4XSwgJnJlZnRhYmxlc1sxMjldKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9CT09MLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IiLCAyLCAmbXNnc1sxMV0sIE5VTEwsIDcsIDIsIHswfSwmcmVmdGFibGVzWzEzMF0sICZyZWZ0YWJsZXNbMTMxXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfSU5UMzIsIFVQQl9JTlRGTVRfVkFSSUFCTEUsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAibnVtYmVyIiwgMywgJm1zZ3NbNl0sIE5VTEwsIDEwLCAzLCB7MH0sJnJlZnRhYmxlc1sxMzJdLCAmcmVmdGFibGVzWzEzM10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX0lOVDMyLCBVUEJfSU5URk1UX1ZBUklBQkxFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm51bWJlciIsIDIsICZtc2dzWzRdLCBOVUxMLCA3LCAyLCB7MH0sJnJlZnRhYmxlc1sxMzRdLCAmcmVmdGFibGVzWzEzNV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX0VOVU0sIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAib3B0aW1pemVfZm9yIiwgOSwgJm1zZ3NbMTBdLCBVUEJfVVBDQVNUKCZlbnVtc1szXSksIDEyLCAzLCB7MH0sJnJlZnRhYmxlc1sxMzZdLCAmcmVmdGFibGVzWzEzN10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAib3B0aW9ucyIsIDcsICZtc2dzWzBdLCBVUEJfVVBDQVNUKCZtc2dzWzExXSksIDIzLCA1LCB7MH0sJnJlZnRhYmxlc1sxMzhdLCAmcmVmdGFibGVzWzEzOV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAib3B0aW9ucyIsIDMsICZtc2dzWzJdLCBVUEJfVVBDQVNUKCZtc2dzWzNdKSwgNywgMSwgezB9LCZyZWZ0YWJsZXNbMTQwXSwgJnJlZnRhYmxlc1sxNDFdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIm9wdGlvbnMiLCA4LCAmbXNnc1s2XSwgVVBCX1VQQ0FTVCgmbXNnc1s3XSksIDMsIDAsIHswfSwmcmVmdGFibGVzWzE0Ml0sICZyZWZ0YWJsZXNbMTQzXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJvcHRpb25zIiwgMywgJm1zZ3NbNF0sIFVQQl9VUENBU1QoJm1zZ3NbNV0pLCAzLCAwLCB7MH0sJnJlZnRhYmxlc1sxNDRdLCAmcmVmdGFibGVzWzE0NV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAib3B0aW9ucyIsIDgsICZtc2dzWzhdLCBVUEJfVVBDQVNUKCZtc2dzWzEwXSksIDIwLCA0LCB7MH0sJnJlZnRhYmxlc1sxNDZdLCAmcmVmdGFibGVzWzE0N10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAib3B0aW9ucyIsIDMsICZtc2dzWzE0XSwgVVBCX1VQQ0FTVCgmbXNnc1sxNV0pLCA3LCAxLCB7MH0sJnJlZnRhYmxlc1sxNDhdLCAmcmVmdGFibGVzWzE0OV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAib3B0aW9ucyIsIDQsICZtc2dzWzEyXSwgVVBCX1VQQ0FTVCgmbXNnc1sxM10pLCAzLCAwLCB7MH0sJnJlZnRhYmxlc1sxNTBdLCAmcmVmdGFibGVzWzE1MV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJvdXRwdXRfdHlwZSIsIDMsICZtc2dzWzEyXSwgTlVMTCwgMTAsIDMsIHswfSwmcmVmdGFibGVzWzE1Ml0sICZyZWZ0YWJsZXNbMTUzXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgInBhY2thZ2UiLCAyLCAmbXNnc1s4XSwgTlVMTCwgMjUsIDcsIHswfSwmcmVmdGFibGVzWzE1NF0sICZyZWZ0YWJsZXNbMTU1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJwYWNrZWQiLCAyLCAmbXNnc1s3XSwgTlVMTCwgNywgMiwgezB9LCZyZWZ0YWJsZXNbMTU2XSwgJnJlZnRhYmxlc1sxNTddKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9JTlQzMiwgVVBCX0lOVEZNVF9WQVJJQUJMRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgInBhdGgiLCAxLCAmbXNnc1sxN10sIE5VTEwsIDQsIDAsIHswfSwmcmVmdGFibGVzWzE1OF0sICZyZWZ0YWJsZXNbMTU5XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfVUlOVDY0LCBVUEJfSU5URk1UX1ZBUklBQkxFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgInBvc2l0aXZlX2ludF92YWx1ZSIsIDQsICZtc2dzWzE4XSwgTlVMTCwgOSwgMiwgezB9LCZyZWZ0YWJsZXNbMTYwXSwgJnJlZnRhYmxlc1sxNjFdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9JTlQzMiwgVVBCX0lOVEZNVF9WQVJJQUJMRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJwdWJsaWNfZGVwZW5kZW5jeSIsIDEwLCAmbXNnc1s4XSwgTlVMTCwgMzUsIDksIHswfSwmcmVmdGFibGVzWzE2Ml0sICZyZWZ0YWJsZXNbMTYzXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQk9PTCwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJweV9nZW5lcmljX3NlcnZpY2VzIiwgMTgsICZtc2dzWzEwXSwgTlVMTCwgMTksIDgsIHswfSwmcmVmdGFibGVzWzE2NF0sICZyZWZ0YWJsZXNbMTY1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVBFQVRFRCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJzZXJ2aWNlIiwgNiwgJm1zZ3NbOF0sIFVQQl9VUENBU1QoJm1zZ3NbMTRdKSwgMTYsIDIsIHswfSwmcmVmdGFibGVzWzE2Nl0sICZyZWZ0YWJsZXNbMTY3XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJzb3VyY2VfY29kZV9pbmZvIiwgOSwgJm1zZ3NbOF0sIFVQQl9VUENBU1QoJm1zZ3NbMTZdKSwgMjEsIDUsIHswfSwmcmVmdGFibGVzWzE2OF0sICZyZWZ0YWJsZXNbMTY5XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVBFQVRFRCwgVVBCX1RZUEVfSU5UMzIsIFVQQl9JTlRGTVRfVkFSSUFCTEUsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsICJzcGFuIiwgMiwgJm1zZ3NbMTddLCBOVUxMLCA3LCAxLCB7MH0sJnJlZnRhYmxlc1sxNzBdLCAmcmVmdGFibGVzWzE3MV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX0lOVDMyLCBVUEJfSU5URk1UX1ZBUklBQkxFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgInN0YXJ0IiwgMSwgJm1zZ3NbMV0sIE5VTEwsIDIsIDAsIHswfSwmcmVmdGFibGVzWzE3Ml0sICZyZWZ0YWJsZXNbMTczXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9PUFRJT05BTCwgVVBCX1RZUEVfQllURVMsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAic3RyaW5nX3ZhbHVlIiwgNywgJm1zZ3NbMThdLCBOVUxMLCAxMiwgNSwgezB9LCZyZWZ0YWJsZXNbMTc0XSwgJnJlZnRhYmxlc1sxNzVdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9TVFJJTkcsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAidHJhaWxpbmdfY29tbWVudHMiLCA0LCAmbXNnc1sxN10sIE5VTEwsIDExLCAzLCB7MH0sJnJlZnRhYmxlc1sxNzZdLCAmcmVmdGFibGVzWzE3N10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX0VOVU0sIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAidHlwZSIsIDUsICZtc2dzWzZdLCBVUEJfVVBDQVNUKCZlbnVtc1sxXSksIDEyLCA1LCB7MH0sJnJlZnRhYmxlc1sxNzhdLCAmcmVmdGFibGVzWzE3OV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfT1BUSU9OQUwsIFVQQl9UWVBFX1NUUklORywgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJ0eXBlX25hbWUiLCA2LCAmbXNnc1s2XSwgTlVMTCwgMTMsIDYsIHswfSwmcmVmdGFibGVzWzE4MF0sICZyZWZ0YWJsZXNbMTgxXSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVBFQVRFRCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJ1bmludGVycHJldGVkX29wdGlvbiIsIDk5OSwgJm1zZ3NbNV0sIFVQQl9VUENBU1QoJm1zZ3NbMThdKSwgNSwgMCwgezB9LCZyZWZ0YWJsZXNbMTgyXSwgJnJlZnRhYmxlc1sxODNdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgInVuaW50ZXJwcmV0ZWRfb3B0aW9uIiwgOTk5LCAmbXNnc1sxNV0sIFVQQl9VUENBU1QoJm1zZ3NbMThdKSwgNSwgMCwgezB9LCZyZWZ0YWJsZXNbMTg0XSwgJnJlZnRhYmxlc1sxODVdKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX1JFUEVBVEVELCBVUEJfVFlQRV9NRVNTQUdFLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgInVuaW50ZXJwcmV0ZWRfb3B0aW9uIiwgOTk5LCAmbXNnc1szXSwgVVBCX1VQQ0FTVCgmbXNnc1sxOF0pLCA1LCAwLCB7MH0sJnJlZnRhYmxlc1sxODZdLCAmcmVmdGFibGVzWzE4N10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAidW5pbnRlcnByZXRlZF9vcHRpb24iLCA5OTksICZtc2dzWzEzXSwgVVBCX1VQQ0FTVCgmbXNnc1sxOF0pLCA1LCAwLCB7MH0sJnJlZnRhYmxlc1sxODhdLCAmcmVmdGFibGVzWzE4OV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAidW5pbnRlcnByZXRlZF9vcHRpb24iLCA5OTksICZtc2dzWzEwXSwgVVBCX1VQQ0FTVCgmbXNnc1sxOF0pLCA1LCAwLCB7MH0sJnJlZnRhYmxlc1sxOTBdLCAmcmVmdGFibGVzWzE5MV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAidW5pbnRlcnByZXRlZF9vcHRpb24iLCA5OTksICZtc2dzWzExXSwgVVBCX1VQQ0FTVCgmbXNnc1sxOF0pLCA1LCAwLCB7MH0sJnJlZnRhYmxlc1sxOTJdLCAmcmVmdGFibGVzWzE5M10pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX01FU1NBR0UsIDAsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAidW5pbnRlcnByZXRlZF9vcHRpb24iLCA5OTksICZtc2dzWzddLCBVUEJfVVBDQVNUKCZtc2dzWzE4XSksIDUsIDAsIHswfSwmcmVmdGFibGVzWzE5NF0sICZyZWZ0YWJsZXNbMTk1XSksCisgIFVQQl9GSUVMRERFRl9JTklUKFVQQl9MQUJFTF9SRVBFQVRFRCwgVVBCX1RZUEVfTUVTU0FHRSwgMCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsICJ2YWx1ZSIsIDIsICZtc2dzWzJdLCBVUEJfVVBDQVNUKCZtc2dzWzRdKSwgNiwgMCwgezB9LCZyZWZ0YWJsZXNbMTk2XSwgJnJlZnRhYmxlc1sxOTddKSwKKyAgVVBCX0ZJRUxEREVGX0lOSVQoVVBCX0xBQkVMX09QVElPTkFMLCBVUEJfVFlQRV9CT09MLCAwLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIndlYWsiLCAxMCwgJm1zZ3NbN10sIE5VTEwsIDEzLCA2LCB7MH0sJnJlZnRhYmxlc1sxOThdLCAmcmVmdGFibGVzWzE5OV0pLAorICBVUEJfRklFTERERUZfSU5JVChVUEJfTEFCRUxfUkVQRUFURUQsIFVQQl9UWVBFX0lOVDMyLCBVUEJfSU5URk1UX1ZBUklBQkxFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgIndlYWtfZGVwZW5kZW5jeSIsIDExLCAmbXNnc1s4XSwgTlVMTCwgMzgsIDEwLCB7MH0sJnJlZnRhYmxlc1syMDBdLCAmcmVmdGFibGVzWzIwMV0pLAorfTsKKworc3RhdGljIGNvbnN0IHVwYl9lbnVtZGVmIGVudW1zWzRdID0geworICBVUEJfRU5VTURFRl9JTklUKCJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwiLCBVUEJfU1RSVEFCTEVfSU5JVCgzLCAzLCBVUEJfQ1RZUEVfSU5UMzIsIDIsICZzdHJlbnRyaWVzWzE2MF0pLCBVUEJfSU5UVEFCTEVfSU5JVCgwLCAwLCBVUEJfQ1RZUEVfQ1NUUiwgMCwgTlVMTCwgJmFycmF5c1syMDJdLCA0LCAzKSwgMCwgJnJlZnRhYmxlc1syMDJdLCAmcmVmdGFibGVzWzIwM10pLAorICBVUEJfRU5VTURFRl9JTklUKCJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSIsIFVQQl9TVFJUQUJMRV9JTklUKDE4LCAzMSwgVVBCX0NUWVBFX0lOVDMyLCA1LCAmc3RyZW50cmllc1sxNjRdKSwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX0NTVFIsIDAsIE5VTEwsICZhcnJheXNbMjA2XSwgMTksIDE4KSwgMCwgJnJlZnRhYmxlc1syMDRdLCAmcmVmdGFibGVzWzIwNV0pLAorICBVUEJfRU5VTURFRl9JTklUKCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlIiwgVVBCX1NUUlRBQkxFX0lOSVQoMywgMywgVVBCX0NUWVBFX0lOVDMyLCAyLCAmc3RyZW50cmllc1sxOTZdKSwgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgVVBCX0NUWVBFX0NTVFIsIDAsIE5VTEwsICZhcnJheXNbMjI1XSwgMywgMyksIDAsICZyZWZ0YWJsZXNbMjA2XSwgJnJlZnRhYmxlc1syMDddKSwKKyAgVVBCX0VOVU1ERUZfSU5JVCgiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSIsIFVQQl9TVFJUQUJMRV9JTklUKDMsIDMsIFVQQl9DVFlQRV9JTlQzMiwgMiwgJnN0cmVudHJpZXNbMjAwXSksIFVQQl9JTlRUQUJMRV9JTklUKDAsIDAsIFVQQl9DVFlQRV9DU1RSLCAwLCBOVUxMLCAmYXJyYXlzWzIyOF0sIDQsIDMpLCAwLCAmcmVmdGFibGVzWzIwOF0sICZyZWZ0YWJsZXNbMjA5XSksCit9OworCitzdGF0aWMgY29uc3QgdXBiX3RhYmVudCBzdHJlbnRyaWVzWzIzNl0gPSB7CisgIHtVUEJfVEFCS0VZX1NUUigiZXh0ZW5zaW9uIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMTRdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm5hbWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szOF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJmaWVsZCIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzE2XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImV4dGVuc2lvbl9yYW5nZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzE1XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigibmVzdGVkX3R5cGUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0NF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJvcHRpb25zIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDldKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZW51bV90eXBlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbOV0pLCAmc3RyZW50cmllc1sxNF19LAorICB7VVBCX1RBQktFWV9TVFIoInN0YXJ0IiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjZdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZW5kIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbOF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ2YWx1ZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzc4XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1MF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJuYW1lIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDBdKSwgJnN0cmVudHJpZXNbMjJdfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ1bmludGVycHJldGVkX29wdGlvbiIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzczXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiYWxsb3dfYWxpYXMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigibnVtYmVyIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDddKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJvcHRpb25zIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNTJdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigibmFtZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzM3XSksICZzdHJlbnRyaWVzWzMwXX0sCisgIHtVUEJfVEFCS0VZX1NUUigidW5pbnRlcnByZXRlZF9vcHRpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3MV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImxhYmVsIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjddKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJuYW1lIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDFdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJudW1iZXIiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0Nl0pLCAmc3RyZW50cmllc1s0OV19LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ0eXBlX25hbWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3MF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJleHRlbmRlZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzEyXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoInR5cGUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s2OV0pLCAmc3RyZW50cmllc1s0OF19LAorICB7VVBCX1RBQktFWV9TVFIoImRlZmF1bHRfdmFsdWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1MV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJleHBlcmltZW50YWxfbWFwX2tleSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzExXSksICZzdHJlbnRyaWVzWzY3XX0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ3ZWFrIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNzldKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJwYWNrZWQiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1OF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJsYXp5IiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjhdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJjdHlwZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzNdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImRlcHJlY2F0ZWQiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s2XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigidW5pbnRlcnByZXRlZF9vcHRpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3N10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJleHRlbnNpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxM10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ3ZWFrX2RlcGVuZGVuY3kiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s4MF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm5hbWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szNF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJzZXJ2aWNlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjNdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJzb3VyY2VfY29kZV9pbmZvIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjRdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZGVwZW5kZW5jeSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzVdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigibWVzc2FnZV90eXBlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMzJdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigicGFja2FnZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzU3XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1M10pLCAmc3RyZW50cmllc1s4Ml19LAorICB7VVBCX1RBQktFWV9TVFIoImVudW1fdHlwZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzEwXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoInB1YmxpY19kZXBlbmRlbmN5IiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjFdKSwgJnN0cmVudHJpZXNbODFdfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImZpbGUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxN10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigidW5pbnRlcnByZXRlZF9vcHRpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3NV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImNjX2dlbmVyaWNfc2VydmljZXMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1syXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiamF2YV9tdWx0aXBsZV9maWxlcyIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzI0XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiamF2YV9nZW5lcmljX3NlcnZpY2VzIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjNdKSwgJnN0cmVudHJpZXNbMTAyXX0sCisgIHtVUEJfVEFCS0VZX1NUUigiamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2giKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1syMl0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb19wYWNrYWdlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMThdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiamF2YV9wYWNrYWdlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjZdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigib3B0aW1pemVfZm9yIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDhdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigicHlfZ2VuZXJpY19zZXJ2aWNlcyIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzYyXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImphdmFfb3V0ZXJfY2xhc3NuYW1lIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjVdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigibWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szMV0pLCAmc3RyZW50cmllc1sxMDZdfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoInVuaW50ZXJwcmV0ZWRfb3B0aW9uIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNzZdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigibm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzQ1XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm5hbWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szOV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJpbnB1dF90eXBlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjBdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJvdXRwdXRfdHlwZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzU2XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1NV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ1bmludGVycHJldGVkX29wdGlvbiIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzc0XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigib3B0aW9ucyIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzU0XSksICZzdHJlbnRyaWVzWzEyMl19LAorICB7VVBCX1RBQktFWV9TVFIoIm1ldGhvZCIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzMzXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm5hbWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szNV0pLCAmc3RyZW50cmllc1sxMjFdfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJ1bmludGVycHJldGVkX29wdGlvbiIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzcyXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJsb2NhdGlvbiIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzMwXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigic3BhbiIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzY1XSksICZzdHJlbnRyaWVzWzEzOV19LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigidHJhaWxpbmdfY29tbWVudHMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s2OF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJsZWFkaW5nX2NvbW1lbnRzIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjldKSwgJnN0cmVudHJpZXNbMTM3XX0sCisgIHtVUEJfVEFCS0VZX1NUUigicGF0aCIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzU5XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImRvdWJsZV92YWx1ZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzddKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIm5hbWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szNl0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJuZWdhdGl2ZV9pbnRfdmFsdWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0M10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJhZ2dyZWdhdGVfdmFsdWUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1swXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigicG9zaXRpdmVfaW50X3ZhbHVlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjBdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiaWRlbnRpZmllcl92YWx1ZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzE5XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoInN0cmluZ192YWx1ZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzY3XSksICZzdHJlbnRyaWVzWzE1NF19LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJpc19leHRlbnNpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1syMV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJuYW1lX3BhcnQiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0Ml0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJMQUJFTF9SRVFVSVJFRCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigyKSwgJnN0cmVudHJpZXNbMTYyXX0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJMQUJFTF9SRVBFQVRFRCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigzKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiTEFCRUxfT1BUSU9OQUwiKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIlRZUEVfRklYRUQ2NCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMig2KSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJUWVBFX1NUUklORyIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMig5KSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9GTE9BVCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigyKSwgJnN0cmVudHJpZXNbMTkzXX0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9ET1VCTEUiKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9JTlQzMiIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMig1KSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9TRklYRUQzMiIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigxNSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIlRZUEVfRklYRUQzMiIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMig3KSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJUWVBFX01FU1NBR0UiKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMTEpLCAmc3RyZW50cmllc1sxOTRdfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9JTlQ2NCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigzKSwgJnN0cmVudHJpZXNbMTkxXX0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJUWVBFX0VOVU0iKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMTQpLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJUWVBFX1VJTlQzMiIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigxMyksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9VSU5UNjQiKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoNCksICZzdHJlbnRyaWVzWzE5MF19LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9TRklYRUQ2NCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigxNiksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIlRZUEVfQllURVMiKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMTIpLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJUWVBFX1NJTlQ2NCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigxOCksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIlRZUEVfQk9PTCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMig4KSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiVFlQRV9HUk9VUCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigxMCksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoIlRZUEVfU0lOVDMyIiksIFVQQl9WQUxVRV9JTklUX0lOVDMyKDE3KSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJDT1JEIiksIFVQQl9WQUxVRV9JTklUX0lOVDMyKDEpLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJTVFJJTkciKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMCksICZzdHJlbnRyaWVzWzE5N119LAorICB7VVBCX1RBQktFWV9TVFIoIlNUUklOR19QSUVDRSIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigyKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiQ09ERV9TSVpFIiksIFVQQl9WQUxVRV9JTklUX0lOVDMyKDIpLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJTUEVFRCIpLCBVUEJfVkFMVUVfSU5JVF9JTlQzMigxKSwgJnN0cmVudHJpZXNbMjAzXX0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJMSVRFX1JVTlRJTUUiKSwgVVBCX1ZBTFVFX0lOSVRfSU5UMzIoMyksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTddKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMThdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbOF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZtc2dzWzEyXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbNV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZtc2dzWzBdKSwgJnN0cmVudHJpZXNbMjI4XX0sCisgIHtVUEJfVEFCS0VZX05PTkUsIFVQQl9fVkFMVUVfSU5JVF9OT05FLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTZdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmVudW1zWzFdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmbXNnc1sxXSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9OT05FLCBVUEJfX1ZBTFVFX0lOSVRfTk9ORSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmbXNnc1s0XSksIE5VTEx9LAorICB7VVBCX1RBQktFWV9TVFIoImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbN10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTBdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMl0pLCAmc3RyZW50cmllc1syMzNdfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmVudW1zWzBdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTRdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZSIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZW51bXNbMl0pLCAmc3RyZW50cmllc1syMjldfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbOV0pLCAmc3RyZW50cmllc1syMzVdfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbM10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8iKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbNl0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIiksIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZlbnVtc1szXSksICZzdHJlbnRyaWVzWzIyMV19LAorICB7VVBCX1RBQktFWV9TVFIoImdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyIpLCBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmbXNnc1sxNV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfU1RSKCJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTFdKSwgTlVMTH0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTNdKSwgJnN0cmVudHJpZXNbMjI2XX0sCisgIHtVUEJfVEFCS0VZX1NUUigiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQiKSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJm1zZ3NbMTldKSwgTlVMTH0sCit9OworCitzdGF0aWMgY29uc3QgdXBiX3RhYmVudCBpbnRlbnRyaWVzWzE0XSA9IHsKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3M10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3MV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3N10pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3NV0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3Nl0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3NF0pLCBOVUxMfSwKKyAge1VQQl9UQUJLRVlfTk9ORSwgVVBCX19WQUxVRV9JTklUX05PTkUsIE5VTEx9LAorICB7VVBCX1RBQktFWV9OVU0oOTk5KSwgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3Ml0pLCBOVUxMfSwKK307CisKK3N0YXRpYyBjb25zdCBfdXBiX3ZhbHVlIGFycmF5c1syMzJdID0geworICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMzhdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxNl0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzQ0XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbOV0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzE1XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMTRdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0OV0pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjZdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s4XSksCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0MF0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzc4XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNTBdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMV0pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzM3XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDddKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1Ml0pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0MV0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzEyXSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDZdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1syN10pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzY5XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNzBdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNTFdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzNdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1OF0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzZdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzI4XSksCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMTFdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s3OV0pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMzRdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1N10pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzVdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szMl0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzEwXSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjNdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxM10pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzUzXSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjRdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s2MV0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzgwXSksCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxN10pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjZdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1syNV0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzQ4XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjRdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1sxOF0pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMl0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzIzXSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjJdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzIyXSksCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzMxXSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNDVdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMzldKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1syMF0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzU2XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNTVdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMzVdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szM10pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzU0XSksCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzMwXSksCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s1OV0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzY1XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjldKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s2OF0pLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9BUlJBWV9FTVBUWUVOVCwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1szNl0pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzE5XSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbNjBdKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s0M10pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzddKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoJmZpZWxkc1s2N10pLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzBdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigmZmllbGRzWzQyXSksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCZmaWVsZHNbMjFdKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiTEFCRUxfT1BUSU9OQUwiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIkxBQkVMX1JFUVVJUkVEIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJMQUJFTF9SRVBFQVRFRCIpLAorICBVUEJfQVJSQVlfRU1QVFlFTlQsCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJUWVBFX0RPVUJMRSIpLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiVFlQRV9GTE9BVCIpLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiVFlQRV9JTlQ2NCIpLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiVFlQRV9VSU5UNjQiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfSU5UMzIiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfRklYRUQ2NCIpLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiVFlQRV9GSVhFRDMyIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJUWVBFX0JPT0wiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfU1RSSU5HIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJUWVBFX0dST1VQIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJUWVBFX01FU1NBR0UiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfQllURVMiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfVUlOVDMyIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJUWVBFX0VOVU0iKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfU0ZJWEVEMzIiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfU0ZJWEVENjQiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIlRZUEVfU0lOVDMyIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJUWVBFX1NJTlQ2NCIpLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiU1RSSU5HIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJDT1JEIiksCisgIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKCJTVFJJTkdfUElFQ0UiKSwKKyAgVVBCX0FSUkFZX0VNUFRZRU5ULAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiU1BFRUQiKSwKKyAgVVBCX1ZBTFVFX0lOSVRfQ09OU1RQVFIoIkNPREVfU0laRSIpLAorICBVUEJfVkFMVUVfSU5JVF9DT05TVFBUUigiTElURV9SVU5USU1FIiksCit9OworCitzdGF0aWMgY29uc3QgdXBiX3N5bXRhYiBzeW10YWIgPSBVUEJfU1lNVEFCX0lOSVQoVVBCX1NUUlRBQkxFX0lOSVQoMjQsIDMxLCBVUEJfQ1RZUEVfUFRSLCA1LCAmc3RyZW50cmllc1syMDRdKSwgJnJlZnRhYmxlc1syMTBdLCAmcmVmdGFibGVzWzIxMV0pOworCitjb25zdCB1cGJfc3ltdGFiICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9kZXNjcmlwdG9yKGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9zeW10YWJfcmVmKCZzeW10YWIsIG93bmVyKTsKKyAgcmV0dXJuICZzeW10YWI7Cit9CisKKyNpZmRlZiBVUEJfREVCVUdfUkVGUworc3RhdGljIHVwYl9pbnR0YWJsZSByZWZ0YWJsZXNbMjEyXSA9IHsKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorICBVUEJfRU1QVFlfSU5UVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwKKyAgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoVVBCX0NUWVBFX1BUUiksCisgIFVQQl9FTVBUWV9JTlRUQUJMRV9JTklUKFVQQl9DVFlQRV9QVFIpLAorfTsKKyNlbmRpZgorCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA4LTIwMDkgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIFhYWDogVGhlIHJvdXRpbmVzIGluIHRoaXMgZmlsZSB0aGF0IGNvbnN1bWUgYSBzdHJpbmcgZG8gbm90IGN1cnJlbnRseQorICogc3VwcG9ydCBoYXZpbmcgdGhlIHN0cmluZyBzcGFuIGJ1ZmZlcnMuICBJbiB0aGUgZnV0dXJlLCBhcyB1cGJfc2luayBhbmQKKyAqIGl0cyBidWZmZXJpbmcvc2hhcmluZyBmdW5jdGlvbmFsaXR5IGV2b2x2ZSB0aGVyZSBzaG91bGQgYmUgYW4gZWFzeSBhbmQKKyAqIGlkaW9tYXRpYyB3YXkgb2YgY29ycmVjdGx5IGhhbmRsaW5nIHRoaXMgY2FzZS4gIEZvciBub3csIHdlIGFjY2VwdCB0aGlzCisgKiBsaW1pdGF0aW9uIHNpbmNlIHdlIGN1cnJlbnRseSBvbmx5IHBhcnNlIGRlc2NyaXB0b3JzIGZyb20gc2luZ2xlIHN0cmluZ3MuCisgKi8KKworCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworc3RhdGljIGNoYXIgKnVwYl9zdHJuZHVwKGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IG4pIHsKKyAgY2hhciAqcmV0ID0gbWFsbG9jKG4gKyAxKTsKKyAgaWYgKCFyZXQpIHJldHVybiBOVUxMOworICBtZW1jcHkocmV0LCBidWYsIG4pOworICByZXRbbl0gPSAnXDAnOworICByZXR1cm4gcmV0OworfQorCisvLyBSZXR1cm5zIGEgbmV3bHkgYWxsb2NhdGVkIHN0cmluZyB0aGF0IGpvaW5zIGlucHV0IHN0cmluZ3MgdG9nZXRoZXIsIGZvcgorLy8gZXhhbXBsZToKKy8vICAgam9pbigiRm9vLkJhciIsICJCYXoiKSAtPiAiRm9vLkJhci5CYXoiCisvLyAgIGpvaW4oIiIsICJCYXoiKSAtPiAiQmF6IgorLy8gQ2FsbGVyIG93bnMgYSByZWYgb24gdGhlIHJldHVybmVkIHN0cmluZy4KK3N0YXRpYyBjaGFyICp1cGJfam9pbihjb25zdCBjaGFyICpiYXNlLCBjb25zdCBjaGFyICpuYW1lKSB7CisgIGlmICghYmFzZSB8fCBzdHJsZW4oYmFzZSkgPT0gMCkgeworICAgIHJldHVybiB1cGJfc3RyZHVwKG5hbWUpOworICB9IGVsc2UgeworICAgIGNoYXIgKnJldCA9IG1hbGxvYyhzdHJsZW4oYmFzZSkgKyBzdHJsZW4obmFtZSkgKyAyKTsKKyAgICByZXRbMF0gPSAnXDAnOworICAgIHN0cmNhdChyZXQsIGJhc2UpOworICAgIHN0cmNhdChyZXQsICIuIik7CisgICAgc3RyY2F0KHJldCwgbmFtZSk7CisgICAgcmV0dXJuIHJldDsKKyAgfQorfQorCisKKy8qIHVwYl9kZWZsaXN0ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3ZvaWQgdXBiX2RlZmxpc3RfaW5pdCh1cGJfZGVmbGlzdCAqbCkgeworICBsLT5zaXplID0gMDsKKyAgbC0+ZGVmcyA9IE5VTEw7CisgIGwtPmxlbiA9IDA7CisgIGwtPm93bmVkID0gdHJ1ZTsKK30KKwordm9pZCB1cGJfZGVmbGlzdF91bmluaXQodXBiX2RlZmxpc3QgKmwpIHsKKyAgaWYgKGwtPm93bmVkKQorICAgIGZvcihzaXplX3QgaSA9IDA7IGkgPCBsLT5sZW47IGkrKykKKyAgICAgIHVwYl9kZWZfdW5yZWYobC0+ZGVmc1tpXSwgbCk7CisgIGZyZWUobC0+ZGVmcyk7Cit9CisKK2Jvb2wgdXBiX2RlZmxpc3RfcHVzaCh1cGJfZGVmbGlzdCAqbCwgdXBiX2RlZiAqZCkgeworICBpZigrK2wtPmxlbiA+PSBsLT5zaXplKSB7CisgICAgc2l6ZV90IG5ld19zaXplID0gVVBCX01BWChsLT5zaXplLCA0KTsKKyAgICBuZXdfc2l6ZSAqPSAyOworICAgIGwtPmRlZnMgPSByZWFsbG9jKGwtPmRlZnMsIG5ld19zaXplICogc2l6ZW9mKHZvaWQgKikpOworICAgIGlmICghbC0+ZGVmcykgcmV0dXJuIGZhbHNlOworICAgIGwtPnNpemUgPSBuZXdfc2l6ZTsKKyAgfQorICBsLT5kZWZzW2wtPmxlbiAtIDFdID0gZDsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgdXBiX2RlZmxpc3RfZG9uYXRlcmVmcyh1cGJfZGVmbGlzdCAqbCwgdm9pZCAqb3duZXIpIHsKKyAgYXNzZXJ0KGwtPm93bmVkKTsKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsLT5sZW47IGkrKykKKyAgICB1cGJfZGVmX2RvbmF0ZXJlZihsLT5kZWZzW2ldLCBsLCBvd25lcik7CisgIGwtPm93bmVkID0gZmFsc2U7Cit9CisKK3N0YXRpYyB1cGJfZGVmICp1cGJfZGVmbGlzdF9sYXN0KHVwYl9kZWZsaXN0ICpsKSB7CisgIHJldHVybiBsLT5kZWZzW2wtPmxlbi0xXTsKK30KKworLy8gUXVhbGlmeSB0aGUgZGVmbmFtZSBmb3IgYWxsIGRlZnMgc3RhcnRpbmcgd2l0aCBvZmZzZXQgInN0YXJ0IiB3aXRoICJzdHIiLgorc3RhdGljIHZvaWQgdXBiX2RlZmxpc3RfcXVhbGlmeSh1cGJfZGVmbGlzdCAqbCwgY2hhciAqc3RyLCBpbnQzMl90IHN0YXJ0KSB7CisgIGZvciAodWludDMyX3QgaSA9IHN0YXJ0OyBpIDwgbC0+bGVuOyBpKyspIHsKKyAgICB1cGJfZGVmICpkZWYgPSBsLT5kZWZzW2ldOworICAgIGNoYXIgKm5hbWUgPSB1cGJfam9pbihzdHIsIHVwYl9kZWZfZnVsbG5hbWUoZGVmKSk7CisgICAgdXBiX2RlZl9zZXRmdWxsbmFtZShkZWYsIG5hbWUsIE5VTEwpOworICAgIGZyZWUobmFtZSk7CisgIH0KK30KKworCisvKiB1cGJfZGVzY3JlYWRlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit2b2lkIHVwYl9kZXNjcmVhZGVyX2luaXQodXBiX2Rlc2NyZWFkZXIgKnIsIGNvbnN0IHVwYl9oYW5kbGVycyAqaGFuZGxlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIFVQQl9VTlVTRUQoc3RhdHVzKTsKKyAgdXBiX2RlZmxpc3RfaW5pdCgmci0+ZGVmcyk7CisgIHVwYl9zaW5rX3Jlc2V0KHVwYl9kZXNjcmVhZGVyX2lucHV0KHIpLCBoYW5kbGVycywgcik7CisgIHItPnN0YWNrX2xlbiA9IDA7CisgIHItPm5hbWUgPSBOVUxMOworICByLT5kZWZhdWx0X3N0cmluZyA9IE5VTEw7Cit9CisKK3ZvaWQgdXBiX2Rlc2NyZWFkZXJfdW5pbml0KHVwYl9kZXNjcmVhZGVyICpyKSB7CisgIGZyZWUoci0+bmFtZSk7CisgIHVwYl9kZWZsaXN0X3VuaW5pdCgmci0+ZGVmcyk7CisgIGZyZWUoci0+ZGVmYXVsdF9zdHJpbmcpOworICB3aGlsZSAoci0+c3RhY2tfbGVuID4gMCkgeworICAgIHVwYl9kZXNjcmVhZGVyX2ZyYW1lICpmID0gJnItPnN0YWNrWy0tci0+c3RhY2tfbGVuXTsKKyAgICBmcmVlKGYtPm5hbWUpOworICB9Cit9CisKK3VwYl9kZWYgKip1cGJfZGVzY3JlYWRlcl9nZXRkZWZzKHVwYl9kZXNjcmVhZGVyICpyLCB2b2lkICpvd25lciwgaW50ICpuKSB7CisgICpuID0gci0+ZGVmcy5sZW47CisgIHVwYl9kZWZsaXN0X2RvbmF0ZXJlZnMoJnItPmRlZnMsIG93bmVyKTsKKyAgcmV0dXJuIHItPmRlZnMuZGVmczsKK30KKwordXBiX3NpbmsgKnVwYl9kZXNjcmVhZGVyX2lucHV0KHVwYl9kZXNjcmVhZGVyICpyKSB7CisgIHJldHVybiAmci0+c2luazsKK30KKworc3RhdGljIHVwYl9tc2dkZWYgKnVwYl9kZXNjcmVhZGVyX3RvcCh1cGJfZGVzY3JlYWRlciAqcikgeworICBhc3NlcnQoci0+c3RhY2tfbGVuID4gMSk7CisgIGludCBpbmRleCA9IHItPnN0YWNrW3ItPnN0YWNrX2xlbi0xXS5zdGFydCAtIDE7CisgIGFzc2VydChpbmRleCA+PSAwKTsKKyAgcmV0dXJuIHVwYl9kb3duY2FzdF9tc2dkZWZfbXV0YWJsZShyLT5kZWZzLmRlZnNbaW5kZXhdKTsKK30KKworc3RhdGljIHVwYl9kZWYgKnVwYl9kZXNjcmVhZGVyX2xhc3QodXBiX2Rlc2NyZWFkZXIgKnIpIHsKKyAgcmV0dXJuIHVwYl9kZWZsaXN0X2xhc3QoJnItPmRlZnMpOworfQorCisvLyBTdGFydC9lbmQgaGFuZGxlcnMgZm9yIEZpbGVEZXNjcmlwdG9yUHJvdG8gYW5kIERlc2NyaXB0b3JQcm90byAodGhlIHR3bworLy8gZW50aXRpZXMgdGhhdCBoYXZlIG5hbWVzIGFuZCBjYW4gY29udGFpbiBzdWItZGVmaW5pdGlvbnMuCit2b2lkIHVwYl9kZXNjcmVhZGVyX3N0YXJ0Y29udGFpbmVyKHVwYl9kZXNjcmVhZGVyICpyKSB7CisgIHVwYl9kZXNjcmVhZGVyX2ZyYW1lICpmID0gJnItPnN0YWNrW3ItPnN0YWNrX2xlbisrXTsKKyAgZi0+c3RhcnQgPSByLT5kZWZzLmxlbjsKKyAgZi0+bmFtZSA9IE5VTEw7Cit9CisKK3ZvaWQgdXBiX2Rlc2NyZWFkZXJfZW5kY29udGFpbmVyKHVwYl9kZXNjcmVhZGVyICpyKSB7CisgIHVwYl9kZXNjcmVhZGVyX2ZyYW1lICpmID0gJnItPnN0YWNrWy0tci0+c3RhY2tfbGVuXTsKKyAgdXBiX2RlZmxpc3RfcXVhbGlmeSgmci0+ZGVmcywgZi0+bmFtZSwgZi0+c3RhcnQpOworICBmcmVlKGYtPm5hbWUpOworICBmLT5uYW1lID0gTlVMTDsKK30KKwordm9pZCB1cGJfZGVzY3JlYWRlcl9zZXRzY29wZW5hbWUodXBiX2Rlc2NyZWFkZXIgKnIsIGNoYXIgKnN0cikgeworICB1cGJfZGVzY3JlYWRlcl9mcmFtZSAqZiA9ICZyLT5zdGFja1tyLT5zdGFja19sZW4tMV07CisgIGZyZWUoZi0+bmFtZSk7CisgIGYtPm5hbWUgPSBzdHI7Cit9CisKKy8vIEhhbmRsZXJzIGZvciBnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by4KK3N0YXRpYyBib29sIGZpbGVfc3RhcnRtc2codm9pZCAqciwgY29uc3Qgdm9pZCAqaGQpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHVwYl9kZXNjcmVhZGVyX3N0YXJ0Y29udGFpbmVyKHIpOworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgZmlsZV9lbmRtc2codm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgVVBCX1VOVVNFRChzdGF0dXMpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIHVwYl9kZXNjcmVhZGVyX2VuZGNvbnRhaW5lcihyKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBzaXplX3QgZmlsZV9vbnBhY2thZ2Uodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG4sIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgVVBCX1VOVVNFRChoYW5kbGUpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIC8vIFhYWDogc2VlIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZS4KKyAgdXBiX2Rlc2NyZWFkZXJfc2V0c2NvcGVuYW1lKHIsIHVwYl9zdHJuZHVwKGJ1ZiwgbikpOworICByZXR1cm4gbjsKK30KKworLy8gSGFuZGxlcnMgZm9yIGdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8uCitzdGF0aWMgYm9vbCBlbnVtdmFsX3N0YXJ0bXNnKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIHItPnNhd19udW1iZXIgPSBmYWxzZTsKKyAgci0+c2F3X25hbWUgPSBmYWxzZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBzaXplX3QgZW51bXZhbF9vbm5hbWUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG4sIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgVVBCX1VOVVNFRChoYW5kbGUpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIC8vIFhYWDogc2VlIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZS4KKyAgZnJlZShyLT5uYW1lKTsKKyAgci0+bmFtZSA9IHVwYl9zdHJuZHVwKGJ1Ziwgbik7CisgIHItPnNhd19uYW1lID0gdHJ1ZTsKKyAgcmV0dXJuIG47Cit9CisKK3N0YXRpYyBib29sIGVudW12YWxfb25udW1iZXIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGludDMyX3QgdmFsKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIHItPm51bWJlciA9IHZhbDsKKyAgci0+c2F3X251bWJlciA9IHRydWU7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCBlbnVtdmFsX2VuZG1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIGlmKCFyLT5zYXdfbnVtYmVyIHx8ICFyLT5zYXdfbmFtZSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgIkVudW0gdmFsdWUgbWlzc2luZyBuYW1lIG9yIG51bWJlci4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgdXBiX2VudW1kZWYgKmUgPSB1cGJfZG93bmNhc3RfZW51bWRlZl9tdXRhYmxlKHVwYl9kZXNjcmVhZGVyX2xhc3QocikpOworICB1cGJfZW51bWRlZl9hZGR2YWwoZSwgci0+bmFtZSwgci0+bnVtYmVyLCBzdGF0dXMpOworICBmcmVlKHItPm5hbWUpOworICByLT5uYW1lID0gTlVMTDsKKyAgcmV0dXJuIHRydWU7Cit9CisKKworLy8gSGFuZGxlcnMgZm9yIGdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLgorc3RhdGljIGJvb2wgZW51bV9zdGFydG1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX2Rlc2NyZWFkZXIgKnIgPSBjbG9zdXJlOworICB1cGJfZGVmbGlzdF9wdXNoKCZyLT5kZWZzLCBVUEJfVVBDQVNUKHVwYl9lbnVtZGVmX25ldygmci0+ZGVmcykpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIGVudW1fZW5kbXNnKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkLCB1cGJfc3RhdHVzICpzdGF0dXMpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgdXBiX2VudW1kZWYgKmUgPSB1cGJfZG93bmNhc3RfZW51bWRlZl9tdXRhYmxlKHVwYl9kZXNjcmVhZGVyX2xhc3QocikpOworICBpZiAodXBiX2RlZl9mdWxsbmFtZSh1cGJfZGVzY3JlYWRlcl9sYXN0KHIpKSA9PSBOVUxMKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2coc3RhdHVzLCAiRW51bSBoYWQgbm8gbmFtZS4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKHVwYl9lbnVtZGVmX251bXZhbHMoZSkgPT0gMCkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgIkVudW0gaGFkIG5vIHZhbHVlcy4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBzaXplX3QgZW51bV9vbm5hbWUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG4sIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgVVBCX1VOVVNFRChoYW5kbGUpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIC8vIFhYWDogc2VlIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZS4KKyAgY2hhciAqZnVsbG5hbWUgPSB1cGJfc3RybmR1cChidWYsIG4pOworICB1cGJfZGVmX3NldGZ1bGxuYW1lKHVwYl9kZXNjcmVhZGVyX2xhc3QociksIGZ1bGxuYW1lLCBOVUxMKTsKKyAgZnJlZShmdWxsbmFtZSk7CisgIHJldHVybiBuOworfQorCisvLyBIYW5kbGVycyBmb3IgZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvCitzdGF0aWMgYm9vbCBmaWVsZF9zdGFydG1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX2Rlc2NyZWFkZXIgKnIgPSBjbG9zdXJlOworICByLT5mID0gdXBiX2ZpZWxkZGVmX25ldygmci0+ZGVmcyk7CisgIGZyZWUoci0+ZGVmYXVsdF9zdHJpbmcpOworICByLT5kZWZhdWx0X3N0cmluZyA9IE5VTEw7CisKKyAgLy8gZmllbGRkZWZzIGRlZmF1bHQgdG8gcGFja2VkLCBidXQgZGVzY3JpcHRvcnMgZGVmYXVsdCB0byBub24tcGFja2VkLgorICB1cGJfZmllbGRkZWZfc2V0cGFja2VkKHItPmYsIGZhbHNlKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIENvbnZlcnRzIHRoZSBkZWZhdWx0IHZhbHVlIGluIHN0cmluZyAic3RyIiBpbnRvICJkIi4gIFBhc3NlcyBhIHJlZiBvbiBzdHIuCisvLyBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcy4KK3N0YXRpYyBib29sIHBhcnNlX2RlZmF1bHQoY2hhciAqc3RyLCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgYm9vbCBzdWNjZXNzID0gdHJ1ZTsKKyAgY2hhciAqZW5kOworICBzd2l0Y2ggKHVwYl9maWVsZGRlZl90eXBlKGYpKSB7CisgICAgY2FzZSBVUEJfVFlQRV9JTlQzMjogeworICAgICAgbG9uZyB2YWwgPSBzdHJ0b2woc3RyLCAmZW5kLCAwKTsKKyAgICAgIGlmICh2YWwgPiBJTlQzMl9NQVggfHwgdmFsIDwgSU5UMzJfTUlOIHx8IGVycm5vID09IEVSQU5HRSB8fCAqZW5kKQorICAgICAgICBzdWNjZXNzID0gZmFsc2U7CisgICAgICBlbHNlCisgICAgICAgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0aW50MzIoZiwgdmFsKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX0lOVDY0OiB7CisgICAgICBsb25nIGxvbmcgdmFsID0gc3RydG9sbChzdHIsICZlbmQsIDApOworICAgICAgaWYgKHZhbCA+IElOVDY0X01BWCB8fCB2YWwgPCBJTlQ2NF9NSU4gfHwgZXJybm8gPT0gRVJBTkdFIHx8ICplbmQpCisgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgIGVsc2UKKyAgICAgICAgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRpbnQ2NChmLCB2YWwpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfVUlOVDMyOiB7CisgICAgICBsb25nIHZhbCA9IHN0cnRvdWwoc3RyLCAmZW5kLCAwKTsKKyAgICAgIGlmICh2YWwgPiBVSU5UMzJfTUFYIHx8IGVycm5vID09IEVSQU5HRSB8fCAqZW5kKQorICAgICAgICBzdWNjZXNzID0gZmFsc2U7CisgICAgICBlbHNlCisgICAgICAgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0dWludDMyKGYsIHZhbCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9VSU5UNjQ6IHsKKyAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyB2YWwgPSBzdHJ0b3VsbChzdHIsICZlbmQsIDApOworICAgICAgaWYgKHZhbCA+IFVJTlQ2NF9NQVggfHwgZXJybm8gPT0gRVJBTkdFIHx8ICplbmQpCisgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgIGVsc2UKKyAgICAgICAgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHR1aW50NjQoZiwgdmFsKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX0RPVUJMRTogeworICAgICAgZG91YmxlIHZhbCA9IHN0cnRvZChzdHIsICZlbmQpOworICAgICAgaWYgKGVycm5vID09IEVSQU5HRSB8fCAqZW5kKQorICAgICAgICBzdWNjZXNzID0gZmFsc2U7CisgICAgICBlbHNlCisgICAgICAgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0ZG91YmxlKGYsIHZhbCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBVUEJfVFlQRV9GTE9BVDogeworICAgICAgZmxvYXQgdmFsID0gc3RydG9mKHN0ciwgJmVuZCk7CisgICAgICBpZiAoZXJybm8gPT0gRVJBTkdFIHx8ICplbmQpCisgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgIGVsc2UKKyAgICAgICAgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRmbG9hdChmLCB2YWwpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfQk9PTDogeworICAgICAgaWYgKHN0cmNtcChzdHIsICJmYWxzZSIpID09IDApCisgICAgICAgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0Ym9vbChmLCBmYWxzZSk7CisgICAgICBlbHNlIGlmIChzdHJjbXAoc3RyLCAidHJ1ZSIpID09IDApCisgICAgICAgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0Ym9vbChmLCB0cnVlKTsKKyAgICAgIGVsc2UKKyAgICAgICAgc3VjY2VzcyA9IGZhbHNlOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGRlZmF1bHQ6IGFib3J0KCk7CisgIH0KKyAgcmV0dXJuIHN1Y2Nlc3M7Cit9CisKK3N0YXRpYyBib29sIGZpZWxkX2VuZG1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgdXBiX3N0YXR1cyAqc3RhdHVzKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIHVwYl9maWVsZGRlZiAqZiA9IHItPmY7CisgIC8vIFRPRE86IHZlcmlmeSB0aGF0IGFsbCByZXF1aXJlZCBmaWVsZHMgd2VyZSBwcmVzZW50LgorICBhc3NlcnQodXBiX2ZpZWxkZGVmX251bWJlcihmKSAhPSAwKTsKKyAgYXNzZXJ0KHVwYl9maWVsZGRlZl9uYW1lKGYpICE9IE5VTEwpOworICBhc3NlcnQoKHVwYl9maWVsZGRlZl9zdWJkZWZuYW1lKGYpICE9IE5VTEwpID09IHVwYl9maWVsZGRlZl9oYXNzdWJkZWYoZikpOworCisgIGlmIChyLT5kZWZhdWx0X3N0cmluZykgeworICAgIGlmICh1cGJfZmllbGRkZWZfaXNzdWJtc2coZikpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgIlN1Ym1lc3NhZ2VzIGNhbm5vdCBoYXZlIGRlZmF1bHRzLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKGYpIHx8IHVwYl9maWVsZGRlZl90eXBlKGYpID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICAgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0Y3N0cihmLCByLT5kZWZhdWx0X3N0cmluZywgTlVMTCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChyLT5kZWZhdWx0X3N0cmluZyAmJiAhcGFyc2VfZGVmYXVsdChyLT5kZWZhdWx0X3N0cmluZywgZikpIHsKKyAgICAgICAgLy8gV2UgZG9uJ3Qgd29ycnkgdG9vIG11Y2ggYWJvdXQgZ2l2aW5nIGEgZ3JlYXQgZXJyb3IgbWVzc2FnZSBzaW5jZSB0aGUKKyAgICAgICAgLy8gY29tcGlsZXIgc2hvdWxkIGhhdmUgZW5zdXJlZCB0aGlzIHdhcyBjb3JyZWN0LgorICAgICAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhzdGF0dXMsICJFcnJvciBjb252ZXJ0aW5nIGRlZmF1bHQgdmFsdWUuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIGZpZWxkX29ubGF6eSh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgYm9vbCB2YWwpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgdXBiX2ZpZWxkZGVmX3NldGxhenkoci0+ZiwgdmFsKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIGZpZWxkX29ucGFja2VkKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkLCBib29sIHZhbCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX2Rlc2NyZWFkZXIgKnIgPSBjbG9zdXJlOworICB1cGJfZmllbGRkZWZfc2V0cGFja2VkKHItPmYsIHZhbCk7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCBmaWVsZF9vbnR5cGUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGludDMyX3QgdmFsKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICB1cGJfZGVzY3JlYWRlciAqciA9IGNsb3N1cmU7CisgIHVwYl9maWVsZGRlZl9zZXRkZXNjcmlwdG9ydHlwZShyLT5mLCB2YWwpOworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgZmllbGRfb25sYWJlbCh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgaW50MzJfdCB2YWwpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgdXBiX2ZpZWxkZGVmX3NldGxhYmVsKHItPmYsIHZhbCk7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCBmaWVsZF9vbm51bWJlcih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgaW50MzJfdCB2YWwpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgYm9vbCBvayA9IHVwYl9maWVsZGRlZl9zZXRudW1iZXIoci0+ZiwgdmFsLCBOVUxMKTsKKyAgVVBCX0FTU0VSVF9WQVIob2ssIG9rKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBzaXplX3QgZmllbGRfb25uYW1lKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkLCBjb25zdCBjaGFyICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbiwgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgLy8gWFhYOiBzZWUgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlLgorICBjaGFyICpuYW1lID0gdXBiX3N0cm5kdXAoYnVmLCBuKTsKKyAgdXBiX2ZpZWxkZGVmX3NldG5hbWUoci0+ZiwgbmFtZSwgTlVMTCk7CisgIGZyZWUobmFtZSk7CisgIHJldHVybiBuOworfQorCitzdGF0aWMgc2l6ZV90IGZpZWxkX29udHlwZW5hbWUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbiwgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgLy8gWFhYOiBzZWUgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlLgorICBjaGFyICpuYW1lID0gdXBiX3N0cm5kdXAoYnVmLCBuKTsKKyAgdXBiX2ZpZWxkZGVmX3NldHN1YmRlZm5hbWUoci0+ZiwgbmFtZSwgTlVMTCk7CisgIGZyZWUobmFtZSk7CisgIHJldHVybiBuOworfQorCitzdGF0aWMgc2l6ZV90IGZpZWxkX29uZXh0ZW5kZWUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbiwgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgLy8gWFhYOiBzZWUgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlLgorICBjaGFyICpuYW1lID0gdXBiX3N0cm5kdXAoYnVmLCBuKTsKKyAgdXBiX2ZpZWxkZGVmX3NldGNvbnRhaW5pbmd0eXBlbmFtZShyLT5mLCBuYW1lLCBOVUxMKTsKKyAgZnJlZShuYW1lKTsKKyAgcmV0dXJuIG47Cit9CisKK3N0YXRpYyBzaXplX3QgZmllbGRfb25kZWZhdWx0dmFsKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkLCBjb25zdCBjaGFyICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbiwgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgLy8gSGF2ZSB0byBjb252ZXJ0IGZyb20gc3RyaW5nIHRvIHRoZSBjb3JyZWN0IHR5cGUsIGJ1dCB3ZSBtaWdodCBub3Qga25vdyB0aGUKKyAgLy8gdHlwZSB5ZXQsIHNvIHdlIHNhdmUgaXQgYXMgYSBzdHJpbmcgdW50aWwgdGhlIGVuZCBvZiB0aGUgZmllbGQuCisgIC8vIFhYWDogc2VlIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZS4KKyAgZnJlZShyLT5kZWZhdWx0X3N0cmluZyk7CisgIHItPmRlZmF1bHRfc3RyaW5nID0gdXBiX3N0cm5kdXAoYnVmLCBuKTsKKyAgcmV0dXJuIG47Cit9CisKKy8vIEhhbmRsZXJzIGZvciBnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIChyZXByZXNlbnRpbmcgYSBtZXNzYWdlKS4KK3N0YXRpYyBib29sIG1zZ19zdGFydG1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX2Rlc2NyZWFkZXIgKnIgPSBjbG9zdXJlOworICB1cGJfZGVmbGlzdF9wdXNoKCZyLT5kZWZzLCBVUEJfVVBDQVNUKHVwYl9tc2dkZWZfbmV3KCZyLT5kZWZzKSkpOworICB1cGJfZGVzY3JlYWRlcl9zdGFydGNvbnRhaW5lcihyKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIG1zZ19lbmRtc2codm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX2Rlc2NyZWFkZXIgKnIgPSBjbG9zdXJlOworICB1cGJfbXNnZGVmICptID0gdXBiX2Rlc2NyZWFkZXJfdG9wKHIpOworICBpZighdXBiX2RlZl9mdWxsbmFtZShVUEJfVVBDQVNUKG0pKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHN0YXR1cywgIkVuY291bnRlcmVkIG1lc3NhZ2Ugd2l0aCBubyBuYW1lLiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICB1cGJfZGVzY3JlYWRlcl9lbmRjb250YWluZXIocik7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgc2l6ZV90IG1zZ19vbm5hbWUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbiwgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgdXBiX21zZ2RlZiAqbSA9IHVwYl9kZXNjcmVhZGVyX3RvcChyKTsKKyAgLy8gWFhYOiBzZWUgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlLgorICBjaGFyICpuYW1lID0gdXBiX3N0cm5kdXAoYnVmLCBuKTsKKyAgdXBiX2RlZl9zZXRmdWxsbmFtZShVUEJfVVBDQVNUKG0pLCBuYW1lLCBOVUxMKTsKKyAgdXBiX2Rlc2NyZWFkZXJfc2V0c2NvcGVuYW1lKHIsIG5hbWUpOyAgLy8gUGFzc2VzIG93bmVyc2hpcCBvZiBuYW1lLgorICByZXR1cm4gbjsKK30KKworc3RhdGljIGJvb2wgbXNnX29uZW5kZmllbGQodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHVwYl9kZXNjcmVhZGVyICpyID0gY2xvc3VyZTsKKyAgdXBiX21zZ2RlZiAqbSA9IHVwYl9kZXNjcmVhZGVyX3RvcChyKTsKKyAgdXBiX21zZ2RlZl9hZGRmaWVsZChtLCByLT5mLCAmci0+ZGVmcywgTlVMTCk7CisgIHItPmYgPSBOVUxMOworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgcHVzaGV4dGVuc2lvbih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX2Rlc2NyZWFkZXIgKnIgPSBjbG9zdXJlOworICBhc3NlcnQodXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlbmFtZShyLT5mKSk7CisgIHVwYl9maWVsZGRlZl9zZXRpc2V4dGVuc2lvbihyLT5mLCB0cnVlKTsKKyAgdXBiX2RlZmxpc3RfcHVzaCgmci0+ZGVmcywgVVBCX1VQQ0FTVChyLT5mKSk7CisgIHItPmYgPSBOVUxMOworICByZXR1cm4gdHJ1ZTsKK30KKworI2RlZmluZSBEKG5hbWUpIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmXyAjIyBuYW1lKHMpCisKK3N0YXRpYyB2b2lkIHJlZ2hhbmRsZXJzKGNvbnN0IHZvaWQgKmNsb3N1cmUsIHVwYl9oYW5kbGVycyAqaCkgeworICBjb25zdCB1cGJfc3ltdGFiICpzID0gY2xvc3VyZTsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbSA9IHVwYl9oYW5kbGVyc19tc2dkZWYoaCk7CisKKyAgaWYgKG0gPT0gRChEZXNjcmlwdG9yUHJvdG8pKSB7CisgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0bXNnKGgsICZtc2dfc3RhcnRtc2csIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRlbmRtc2coaCwgJm1zZ19lbmRtc2csIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgRChEZXNjcmlwdG9yUHJvdG9fbmFtZSksICZtc2dfb25uYW1lLCBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc3VibXNnKGgsIEQoRGVzY3JpcHRvclByb3RvX2ZpZWxkKSwgJm1zZ19vbmVuZGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CisgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN1Ym1zZyhoLCBEKERlc2NyaXB0b3JQcm90b19leHRlbnNpb24pLCAmcHVzaGV4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICB9IGVsc2UgaWYgKG0gPT0gRChGaWxlRGVzY3JpcHRvclByb3RvKSkgeworICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydG1zZyhoLCAmZmlsZV9zdGFydG1zZywgTlVMTCk7CisgICAgdXBiX2hhbmRsZXJzX3NldGVuZG1zZyhoLCAmZmlsZV9lbmRtc2csIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgRChGaWxlRGVzY3JpcHRvclByb3RvX3BhY2thZ2UpLCAmZmlsZV9vbnBhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc3VibXNnKGgsIEQoRmlsZURlc2NyaXB0b3JQcm90b19leHRlbnNpb24pLCAmcHVzaGV4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICB9IGVsc2UgaWYgKG0gPT0gRChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pKSB7CisgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0bXNnKGgsICZlbnVtdmFsX3N0YXJ0bXNnLCBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kbXNnKGgsICZlbnVtdmFsX2VuZG1zZywgTlVMTCk7CisgICAgdXBiX2hhbmRsZXJzX3NldHN0cmluZyhoLCBEKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19uYW1lKSwgJmVudW12YWxfb25uYW1lLCBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwgRChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fbnVtYmVyKSwgJmVudW12YWxfb25udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICB9IGVsc2UgaWYgKG0gPT0gRChFbnVtRGVzY3JpcHRvclByb3RvKSkgeworICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydG1zZyhoLCAmZW51bV9zdGFydG1zZywgTlVMTCk7CisgICAgdXBiX2hhbmRsZXJzX3NldGVuZG1zZyhoLCAmZW51bV9lbmRtc2csIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgRChFbnVtRGVzY3JpcHRvclByb3RvX25hbWUpLCAmZW51bV9vbm5hbWUsIE5VTEwpOworICB9IGVsc2UgaWYgKG0gPT0gRChGaWVsZERlc2NyaXB0b3JQcm90bykpIHsKKyAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRtc2coaCwgJmZpZWxkX3N0YXJ0bXNnLCBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kbXNnKGgsICZmaWVsZF9lbmRtc2csIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRpbnQzMihoLCBEKEZpZWxkRGVzY3JpcHRvclByb3RvX3R5cGUpLCAmZmllbGRfb250eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwgRChGaWVsZERlc2NyaXB0b3JQcm90b19sYWJlbCksICZmaWVsZF9vbmxhYmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwgRChGaWVsZERlc2NyaXB0b3JQcm90b19udW1iZXIpLCAmZmllbGRfb25udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgRChGaWVsZERlc2NyaXB0b3JQcm90b19uYW1lKSwgJmZpZWxkX29ubmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgRChGaWVsZERlc2NyaXB0b3JQcm90b190eXBlX25hbWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZpZWxkX29udHlwZW5hbWUsIE5VTEwpOworICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgRChGaWVsZERlc2NyaXB0b3JQcm90b19leHRlbmRlZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAmZmllbGRfb25leHRlbmRlZSwgTlVMTCk7CisgICAgdXBiX2hhbmRsZXJzX3NldHN0cmluZyhoLCBEKEZpZWxkRGVzY3JpcHRvclByb3RvX2RlZmF1bHRfdmFsdWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZpZWxkX29uZGVmYXVsdHZhbCwgTlVMTCk7CisgIH0gZWxzZSBpZiAobSA9PSBEKEZpZWxkT3B0aW9ucykpIHsKKyAgICB1cGJfaGFuZGxlcnNfc2V0Ym9vbChoLCBEKEZpZWxkT3B0aW9uc19sYXp5KSwgJmZpZWxkX29ubGF6eSwgTlVMTCk7CisgICAgdXBiX2hhbmRsZXJzX3NldGJvb2woaCwgRChGaWVsZE9wdGlvbnNfcGFja2VkKSwgJmZpZWxkX29ucGFja2VkLCBOVUxMKTsKKyAgfQorfQorCisjdW5kZWYgRAorCitjb25zdCB1cGJfaGFuZGxlcnMgKnVwYl9kZXNjcmVhZGVyX25ld2hhbmRsZXJzKGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIGNvbnN0IHVwYl9zeW10YWIgKnMgPSB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9kZXNjcmlwdG9yKCZzKTsKKyAgY29uc3QgdXBiX2hhbmRsZXJzICpoID0gdXBiX2hhbmRsZXJzX25ld2Zyb3plbigKKyAgICAgIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yU2V0KHMpLCBvd25lciwgcmVnaGFuZGxlcnMsIHMpOworICB1cGJfc3ltdGFiX3VucmVmKHMsICZzKTsKKyAgcmV0dXJuIGg7Cit9CisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDEzIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBDb2RlIHRvIGNvbXBpbGUgYSB1cGI6OkhhbmRsZXJzIGludG8gYnl0ZWNvZGUgZm9yIGRlY29kaW5nIGEgcHJvdG9idWYKKyAqIGFjY29yZGluZyB0byB0aGF0IHNwZWNpZmljIHNjaGVtYSBhbmQgZGVzdGluYXRpb24gaGFuZGxlcnMuCisgKgorICogQ29tcGlsaW5nIHRvIGJ5dGVjb2RlIGlzIGFsd2F5cyB0aGUgZmlyc3Qgc3RlcC4gIElmIHdlIGFyZSB1c2luZyB0aGUKKyAqIGludGVycHJldGVkIGRlY29kZXIgd2UgbGVhdmUgaXQgYXMgYnl0ZWNvZGUgYW5kIGludGVycHJldCB0aGF0LiAgSWYgd2UgYXJlCisgKiB1c2luZyBhIEpJVCBkZWNvZGVyIHdlIHVzZSBhIGNvZGUgZ2VuZXJhdG9yIHRvIHR1cm4gdGhlIGJ5dGVjb2RlIGludG8gbmF0aXZlCisgKiBjb2RlLCBMTFZNIElSLCBldGMuCisgKgorICogQnl0ZWNvZGUgZGVmaW5pdGlvbiBpcyBpbiBkZWNvZGVyLmludC5oLgorICovCisKKyNpbmNsdWRlIDxzdGRhcmcuaD4KKworI2lmZGVmIFVQQl9EVU1QX0JZVEVDT0RFCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNlbmRpZgorCisjZGVmaW5lIE1BWExBQkVMIDUKKyNkZWZpbmUgRU1QVFlMQUJFTCAtMQorCisvKiBtZ3JvdXAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgdm9pZCBmcmVlZ3JvdXAodXBiX3JlZmNvdW50ZWQgKnIpIHsKKyAgbWdyb3VwICpnID0gKG1ncm91cCopcjsKKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmZy0+bWV0aG9kcyk7CisjaWZkZWYgVVBCX1VTRV9KSVRfWDY0CisgIHVwYl9wYmRlY29kZXJfZnJlZWppdChnKTsKKyNlbmRpZgorICBmcmVlKGctPmJ5dGVjb2RlKTsKKyAgZnJlZShnKTsKK30KKworc3RhdGljIHZvaWQgdmlzaXRncm91cChjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWRfdmlzaXQgKnZpc2l0LAorICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IG1ncm91cCAqZyA9IChjb25zdCBtZ3JvdXAqKXI7CisgIHVwYl9pbnR0YWJsZV9pdGVyIGk7CisgIHVwYl9pbnR0YWJsZV9iZWdpbigmaSwgJmctPm1ldGhvZHMpOworICBmb3IoOyAhdXBiX2ludHRhYmxlX2RvbmUoJmkpOyB1cGJfaW50dGFibGVfbmV4dCgmaSkpIHsKKyAgICB1cGJfcGJkZWNvZGVybWV0aG9kICptZXRob2QgPSB1cGJfdmFsdWVfZ2V0cHRyKHVwYl9pbnR0YWJsZV9pdGVyX3ZhbHVlKCZpKSk7CisgICAgdmlzaXQociwgVVBCX1VQQ0FTVChtZXRob2QpLCBjbG9zdXJlKTsKKyAgfQorfQorCittZ3JvdXAgKm5ld2dyb3VwKGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIG1ncm91cCAqZyA9IG1hbGxvYyhzaXplb2YoKmcpKTsKKyAgc3RhdGljIGNvbnN0IHN0cnVjdCB1cGJfcmVmY291bnRlZF92dGJsIHZ0YmwgPSB7dmlzaXRncm91cCwgZnJlZWdyb3VwfTsKKyAgdXBiX3JlZmNvdW50ZWRfaW5pdChVUEJfVVBDQVNUKGcpLCAmdnRibCwgb3duZXIpOworICB1cGJfaW50dGFibGVfaW5pdCgmZy0+bWV0aG9kcywgVVBCX0NUWVBFX1BUUik7CisgIGctPmJ5dGVjb2RlID0gTlVMTDsKKyAgZy0+Ynl0ZWNvZGVfZW5kID0gTlVMTDsKKyAgcmV0dXJuIGc7Cit9CisKKworLyogdXBiX3BiZGVjb2Rlcm1ldGhvZCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIHZvaWQgZnJlZW1ldGhvZCh1cGJfcmVmY291bnRlZCAqcikgeworICB1cGJfcGJkZWNvZGVybWV0aG9kICptZXRob2QgPSAodXBiX3BiZGVjb2Rlcm1ldGhvZCopcjsKKyAgdXBiX2J5dGVzaGFuZGxlcl91bmluaXQoJm1ldGhvZC0+aW5wdXRfaGFuZGxlcl8pOworCisgIGlmIChtZXRob2QtPmRlc3RfaGFuZGxlcnNfKSB7CisgICAgdXBiX2hhbmRsZXJzX3VucmVmKG1ldGhvZC0+ZGVzdF9oYW5kbGVyc18sIG1ldGhvZCk7CisgIH0KKworICB1cGJfaW50dGFibGVfdW5pbml0KCZtZXRob2QtPmRpc3BhdGNoKTsKKyAgZnJlZShtZXRob2QpOworfQorCitzdGF0aWMgdm9pZCB2aXNpdG1ldGhvZChjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWRfdmlzaXQgKnZpc2l0LAorICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xvc3VyZSkgeworICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptID0gKGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QqKXI7CisgIHZpc2l0KHIsIG0tPmdyb3VwLCBjbG9zdXJlKTsKK30KKworc3RhdGljIHVwYl9wYmRlY29kZXJtZXRob2QgKm5ld21ldGhvZChjb25zdCB1cGJfaGFuZGxlcnMgKmRlc3RfaGFuZGxlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ncm91cCAqZ3JvdXApIHsKKyAgc3RhdGljIGNvbnN0IHN0cnVjdCB1cGJfcmVmY291bnRlZF92dGJsIHZ0YmwgPSB7dmlzaXRtZXRob2QsIGZyZWVtZXRob2R9OworICB1cGJfcGJkZWNvZGVybWV0aG9kICpyZXQgPSBtYWxsb2Moc2l6ZW9mKCpyZXQpKTsKKyAgdXBiX3JlZmNvdW50ZWRfaW5pdChVUEJfVVBDQVNUKHJldCksICZ2dGJsLCAmcmV0KTsKKyAgdXBiX2J5dGVzaGFuZGxlcl9pbml0KCZyZXQtPmlucHV0X2hhbmRsZXJfKTsKKworICAvLyBUaGUgbWV0aG9kIHJlZmVyZW5jZXMgdGhlIGdyb3VwIGFuZCB2aWNlLXZlcnNhLCBpbiBhIGNpcmN1bGFyIHJlZmVyZW5jZS4KKyAgdXBiX3JlZjIocmV0LCBncm91cCk7CisgIHVwYl9yZWYyKGdyb3VwLCByZXQpOworICB1cGJfaW50dGFibGVfaW5zZXJ0cHRyKCZncm91cC0+bWV0aG9kcywgZGVzdF9oYW5kbGVycywgdXBiX3ZhbHVlX3B0cihyZXQpKTsKKyAgdXBiX3JlZmNvdW50ZWRfdW5yZWYoVVBCX1VQQ0FTVChyZXQpLCAmcmV0KTsKKworICByZXQtPmdyb3VwID0gVVBCX1VQQ0FTVChncm91cCk7CisgIHJldC0+ZGVzdF9oYW5kbGVyc18gPSBkZXN0X2hhbmRsZXJzOworICByZXQtPmlzX25hdGl2ZV8gPSBmYWxzZTsgIC8vIElmIHdlIEpJVCwgaXQgd2lsbCB1cGRhdGUgdGhpcyBsYXRlci4KKyAgdXBiX2ludHRhYmxlX2luaXQoJnJldC0+ZGlzcGF0Y2gsIFVQQl9DVFlQRV9VSU5UNjQpOworCisgIGlmIChyZXQtPmRlc3RfaGFuZGxlcnNfKSB7CisgICAgdXBiX2hhbmRsZXJzX3JlZihyZXQtPmRlc3RfaGFuZGxlcnNfLCByZXQpOworICB9CisgIHJldHVybiByZXQ7Cit9CisKK3ZvaWQgdXBiX3BiZGVjb2Rlcm1ldGhvZF9yZWYoY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSwgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX3JlZmNvdW50ZWRfcmVmKFVQQl9VUENBU1QobSksIG93bmVyKTsKK30KKwordm9pZCB1cGJfcGJkZWNvZGVybWV0aG9kX3VucmVmKGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgdXBiX3JlZmNvdW50ZWRfdW5yZWYoVVBCX1VQQ0FTVChtKSwgb3duZXIpOworfQorCit2b2lkIHVwYl9wYmRlY29kZXJtZXRob2RfZG9uYXRlcmVmKGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKSB7CisgIHVwYl9yZWZjb3VudGVkX2RvbmF0ZXJlZihVUEJfVVBDQVNUKG0pLCBmcm9tLCB0byk7Cit9CisKK3ZvaWQgdXBiX3BiZGVjb2Rlcm1ldGhvZF9jaGVja3JlZihjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9yZWZjb3VudGVkX2NoZWNrcmVmKFVQQl9VUENBU1QobSksIG93bmVyKTsKK30KKworY29uc3QgdXBiX2hhbmRsZXJzICp1cGJfcGJkZWNvZGVybWV0aG9kX2Rlc3RoYW5kbGVycygKKyAgICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptKSB7CisgIHJldHVybiBtLT5kZXN0X2hhbmRsZXJzXzsKK30KKworY29uc3QgdXBiX2J5dGVzaGFuZGxlciAqdXBiX3BiZGVjb2Rlcm1ldGhvZF9pbnB1dGhhbmRsZXIoCisgICAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSkgeworICByZXR1cm4gJm0tPmlucHV0X2hhbmRsZXJfOworfQorCitib29sIHVwYl9wYmRlY29kZXJtZXRob2RfaXNuYXRpdmUoY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSkgeworICByZXR1cm4gbS0+aXNfbmF0aXZlXzsKK30KKworY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqdXBiX3BiZGVjb2Rlcm1ldGhvZF9uZXcoCisgICAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHMgKm9wdHMsIGNvbnN0IHZvaWQgKm93bmVyKSB7CisgIHVwYl9wYmNvZGVjYWNoZSBjYWNoZTsKKyAgdXBiX3BiY29kZWNhY2hlX2luaXQoJmNhY2hlKTsKKyAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqcmV0ID0KKyAgICAgIHVwYl9wYmNvZGVjYWNoZV9nZXRkZWNvZGVybWV0aG9kKCZjYWNoZSwgb3B0cyk7CisgIHVwYl9wYmRlY29kZXJtZXRob2RfcmVmKHJldCwgb3duZXIpOworICB1cGJfcGJjb2RlY2FjaGVfdW5pbml0KCZjYWNoZSk7CisgIHJldHVybiByZXQ7Cit9CisKKworLyogYnl0ZWNvZGUgY29tcGlsZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gRGF0YSB1c2VkIG9ubHkgYXQgY29tcGlsYXRpb24gdGltZS4KK3R5cGVkZWYgc3RydWN0IHsKKyAgbWdyb3VwICpncm91cDsKKworICB1aW50MzJfdCAqcGM7CisgIGludCBmd2RfbGFiZWxzW01BWExBQkVMXTsKKyAgaW50IGJhY2tfbGFiZWxzW01BWExBQkVMXTsKKworICAvLyBGb3IgZmllbGRzIG1hcmtlZCAibGF6eSIsIHBhcnNlIHRoZW0gbGF6aWx5IG9yIGVhZ2VybHk/CisgIGJvb2wgbGF6eTsKK30gY29tcGlsZXI7CisKK3N0YXRpYyBjb21waWxlciAqbmV3Y29tcGlsZXIobWdyb3VwICpncm91cCwgYm9vbCBsYXp5KSB7CisgIGNvbXBpbGVyICpyZXQgPSBtYWxsb2Moc2l6ZW9mKCpyZXQpKTsKKyAgcmV0LT5ncm91cCA9IGdyb3VwOworICByZXQtPmxhenkgPSBsYXp5OworICBmb3IgKGludCBpID0gMDsgaSA8IE1BWExBQkVMOyBpKyspIHsKKyAgICByZXQtPmZ3ZF9sYWJlbHNbaV0gPSBFTVBUWUxBQkVMOworICAgIHJldC0+YmFja19sYWJlbHNbaV0gPSBFTVBUWUxBQkVMOworICB9CisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyB2b2lkIGZyZWVjb21waWxlcihjb21waWxlciAqYykgeworICBmcmVlKGMpOworfQorCitjb25zdCBzaXplX3QgcHRyX3dvcmRzID0gc2l6ZW9mKHZvaWQqKSAvIHNpemVvZih1aW50MzJfdCk7CisKKy8vIEhvdyBtYW55IHdvcmRzIGFuIGluc3RydWN0aW9uIGlzLgorc3RhdGljIGludCBpbnN0cnVjdGlvbl9sZW4odWludDMyX3QgaW5zdHIpIHsKKyAgc3dpdGNoIChnZXRvcChpbnN0cikpIHsKKyAgICBjYXNlIE9QX1NFVERJU1BBVENIOiByZXR1cm4gMSArIHB0cl93b3JkczsKKyAgICBjYXNlIE9QX1RBR046IHJldHVybiAzOworICAgIGNhc2UgT1BfU0VUQklHR1JPVVBOVU06IHJldHVybiAyOworICAgIGRlZmF1bHQ6IHJldHVybiAxOworICB9Cit9CisKK2Jvb2wgb3BfaGFzX2xvbmdvZnMoaW50MzJfdCBpbnN0cnVjdGlvbikgeworICBzd2l0Y2ggKGdldG9wKGluc3RydWN0aW9uKSkgeworICAgIGNhc2UgT1BfQ0FMTDoKKyAgICBjYXNlIE9QX0JSQU5DSDoKKyAgICBjYXNlIE9QX0NIRUNLREVMSU06CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAvLyBUaGUgInRhZyIgaW5zdHJ1Y3Rpb25zIG9ubHkgaGF2ZSA4IGJ5dGVzIGF2YWlsYWJsZSBmb3IgdGhlIGp1bXAgdGFyZ2V0LAorICAgIC8vIGJ1dCB0aGF0IGlzIG9rIGJlY2F1c2UgdGhlc2Ugb3Bjb2RlcyBvbmx5IHJlcXVpcmUgc2hvcnQganVtcHMuCisgICAgY2FzZSBPUF9UQUcxOgorICAgIGNhc2UgT1BfVEFHMjoKKyAgICBjYXNlIE9QX1RBR046CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgZGVmYXVsdDoKKyAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworc3RhdGljIGludDMyX3QgZ2V0b2ZzKHVpbnQzMl90IGluc3RydWN0aW9uKSB7CisgIGlmIChvcF9oYXNfbG9uZ29mcyhpbnN0cnVjdGlvbikpIHsKKyAgICByZXR1cm4gKGludDMyX3QpaW5zdHJ1Y3Rpb24gPj4gODsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gKGludDhfdCkoaW5zdHJ1Y3Rpb24gPj4gOCk7CisgIH0KK30KKworc3RhdGljIHZvaWQgc2V0b2ZzKHVpbnQzMl90ICppbnN0cnVjdGlvbiwgaW50MzJfdCBvZnMpIHsKKyAgaWYgKG9wX2hhc19sb25nb2ZzKCppbnN0cnVjdGlvbikpIHsKKyAgICAqaW5zdHJ1Y3Rpb24gPSBnZXRvcCgqaW5zdHJ1Y3Rpb24pIHwgb2ZzIDw8IDg7CisgIH0gZWxzZSB7CisgICAgKmluc3RydWN0aW9uID0gKCppbnN0cnVjdGlvbiAmIH4weGZmMDApIHwgKChvZnMgJiAweGZmKSA8PCA4KTsKKyAgfQorICBhc3NlcnQoZ2V0b2ZzKCppbnN0cnVjdGlvbikgPT0gb2ZzKTsgIC8vIFdvdWxkIGZhaWwgaW4gY2FzZXMgb2Ygb3ZlcmZsb3cuCit9CisKK3N0YXRpYyB1aW50MzJfdCBwY29mcyhjb21waWxlciAqYykgeyByZXR1cm4gYy0+cGMgLSBjLT5ncm91cC0+Ynl0ZWNvZGU7IH0KKworLy8gRGVmaW5lcyBhIGxvY2FsIGxhYmVsIGF0IHRoZSBjdXJyZW50IFBDIGxvY2F0aW9uLiAgQWxsIHByZXZpb3VzIGZvcndhcmQKKy8vIHJlZmVyZW5jZXMgYXJlIHVwZGF0ZWQgdG8gcG9pbnQgdG8gdGhpcyBsb2NhdGlvbi4gIFRoZSBsb2NhdGlvbiBpcyBub3RlZAorLy8gZm9yIGFueSBmdXR1cmUgYmFja3dhcmQgcmVmZXJlbmNlcy4KK3N0YXRpYyB2b2lkIGxhYmVsKGNvbXBpbGVyICpjLCB1bnNpZ25lZCBpbnQgbGFiZWwpIHsKKyAgYXNzZXJ0KGxhYmVsIDwgTUFYTEFCRUwpOworICBpbnQgdmFsID0gYy0+ZndkX2xhYmVsc1tsYWJlbF07CisgIHVpbnQzMl90ICpjb2RlcCA9ICh2YWwgPT0gRU1QVFlMQUJFTCkgPyBOVUxMIDogYy0+Z3JvdXAtPmJ5dGVjb2RlICsgdmFsOworICB3aGlsZSAoY29kZXApIHsKKyAgICBpbnQgb2ZzID0gZ2V0b2ZzKCpjb2RlcCk7CisgICAgc2V0b2ZzKGNvZGVwLCBjLT5wYyAtIGNvZGVwIC0gaW5zdHJ1Y3Rpb25fbGVuKCpjb2RlcCkpOworICAgIGNvZGVwID0gb2ZzID8gY29kZXAgKyBvZnMgOiBOVUxMOworICB9CisgIGMtPmZ3ZF9sYWJlbHNbbGFiZWxdID0gRU1QVFlMQUJFTDsKKyAgYy0+YmFja19sYWJlbHNbbGFiZWxdID0gcGNvZnMoYyk7Cit9CisKKy8vIENyZWF0ZXMgYSByZWZlcmVuY2UgdG8gYSBudW1iZXJlZCBsYWJlbDsgZWl0aGVyIGEgZm9yd2FyZCByZWZlcmVuY2UKKy8vIChwb3NpdGl2ZSBhcmcpIG9yIGJhY2t3YXJkIHJlZmVyZW5jZSAobmVnYXRpdmUgYXJnKS4gIEZvciBmb3J3YXJkIHJlZmVyZW5jZXMKKy8vIHRoZSB2YWx1ZSByZXR1cm5lZCBub3cgaXMgYWN0dWFsbHkgYSAibmV4dCIgcG9pbnRlciBpbnRvIGEgbGlua2VkIGxpc3Qgb2YgYWxsCisvLyBpbnN0cnVjdGlvbnMgdGhhdCB1c2UgdGhpcyBsYWJlbCBhbmQgd2lsbCBiZSBwYXRjaGVkIGxhdGVyIHdoZW4gdGhlIGxhYmVsIGlzCisvLyBkZWZpbmVkIHdpdGggbGFiZWwoKS4KKy8vCisvLyBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgdGhlIG9mZnNldCB0aGF0IHNob3VsZCBiZSB3cml0dGVuIGludG8gdGhlIGluc3RydWN0aW9uLgorc3RhdGljIGludDMyX3QgbGFiZWxyZWYoY29tcGlsZXIgKmMsIGludCBsYWJlbCkgeworICBhc3NlcnQobGFiZWwgPCBNQVhMQUJFTCk7CisgIGlmIChsYWJlbCA9PSBMQUJFTF9ESVNQQVRDSCkgeworICAgIC8vIE5vIHJlc29sdmluZyByZXF1aXJlZC4KKyAgICByZXR1cm4gMDsKKyAgfSBlbHNlIGlmIChsYWJlbCA8IDApIHsKKyAgICAvLyBCYWNrd2FyZCBsb2NhbCBsYWJlbC4gIFJlbGF0aXZlIHRvIHRoZSBuZXh0IGluc3RydWN0aW9uLgorICAgIHVpbnQzMl90IGZyb20gPSAoYy0+cGMgKyAxKSAtIGMtPmdyb3VwLT5ieXRlY29kZTsKKyAgICByZXR1cm4gYy0+YmFja19sYWJlbHNbLWxhYmVsXSAtIGZyb207CisgIH0gZWxzZSB7CisgICAgLy8gRm9yd2FyZCBsb2NhbCBsYWJlbDogcHJlcGVuZCB0byAocG9zc2libHktZW1wdHkpIGxpbmtlZCBsaXN0LgorICAgIGludCAqbHB0ciA9ICZjLT5md2RfbGFiZWxzW2xhYmVsXTsKKyAgICBpbnQzMl90IHJldCA9ICgqbHB0ciA9PSBFTVBUWUxBQkVMKSA/IDAgOiAqbHB0ciAtIHBjb2ZzKGMpOworICAgICpscHRyID0gcGNvZnMoYyk7CisgICAgcmV0dXJuIHJldDsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBwdXQzMihjb21waWxlciAqYywgdWludDMyX3QgdikgeworICBtZ3JvdXAgKmcgPSBjLT5ncm91cDsKKyAgaWYgKGMtPnBjID09IGctPmJ5dGVjb2RlX2VuZCkgeworICAgIGludCBvZnMgPSBwY29mcyhjKTsKKyAgICBzaXplX3Qgb2xkc2l6ZSA9IGctPmJ5dGVjb2RlX2VuZCAtIGctPmJ5dGVjb2RlOworICAgIHNpemVfdCBuZXdzaXplID0gVVBCX01BWChvbGRzaXplICogMiwgNjQpOworICAgIC8vIFRPRE8oaGFiZXJtYW4pOiBoYW5kbGUgT09NLgorICAgIGctPmJ5dGVjb2RlID0gcmVhbGxvYyhnLT5ieXRlY29kZSwgbmV3c2l6ZSAqIHNpemVvZih1aW50MzJfdCkpOworICAgIGctPmJ5dGVjb2RlX2VuZCA9IGctPmJ5dGVjb2RlICsgbmV3c2l6ZTsKKyAgICBjLT5wYyA9IGctPmJ5dGVjb2RlICsgb2ZzOworICB9CisgICpjLT5wYysrID0gdjsKK30KKworc3RhdGljIHZvaWQgcHV0b3AoY29tcGlsZXIgKmMsIG9wY29kZSBvcCwgLi4uKSB7CisgIHZhX2xpc3QgYXA7CisgIHZhX3N0YXJ0KGFwLCBvcCk7CisKKyAgc3dpdGNoIChvcCkgeworICAgIGNhc2UgT1BfU0VURElTUEFUQ0g6IHsKKyAgICAgIHVpbnRwdHJfdCBwdHIgPSAodWludHB0cl90KXZhX2FyZyhhcCwgdm9pZCopOworICAgICAgcHV0MzIoYywgT1BfU0VURElTUEFUQ0gpOworICAgICAgcHV0MzIoYywgcHRyKTsKKyAgICAgIGlmIChzaXplb2YodWludHB0cl90KSA+IHNpemVvZih1aW50MzJfdCkpCisgICAgICAgIHB1dDMyKGMsICh1aW50NjRfdClwdHIgPj4gMzIpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgT1BfU1RBUlRNU0c6CisgICAgY2FzZSBPUF9FTkRNU0c6CisgICAgY2FzZSBPUF9QVVNITEVOREVMSU06CisgICAgY2FzZSBPUF9QT1A6CisgICAgY2FzZSBPUF9TRVRERUxJTToKKyAgICBjYXNlIE9QX0hBTFQ6CisgICAgY2FzZSBPUF9SRVQ6CisgICAgY2FzZSBPUF9ESVNQQVRDSDoKKyAgICAgIHB1dDMyKGMsIG9wKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgT1BfUEFSU0VfRE9VQkxFOgorICAgIGNhc2UgT1BfUEFSU0VfRkxPQVQ6CisgICAgY2FzZSBPUF9QQVJTRV9JTlQ2NDoKKyAgICBjYXNlIE9QX1BBUlNFX1VJTlQ2NDoKKyAgICBjYXNlIE9QX1BBUlNFX0lOVDMyOgorICAgIGNhc2UgT1BfUEFSU0VfRklYRUQ2NDoKKyAgICBjYXNlIE9QX1BBUlNFX0ZJWEVEMzI6CisgICAgY2FzZSBPUF9QQVJTRV9CT09MOgorICAgIGNhc2UgT1BfUEFSU0VfVUlOVDMyOgorICAgIGNhc2UgT1BfUEFSU0VfU0ZJWEVEMzI6CisgICAgY2FzZSBPUF9QQVJTRV9TRklYRUQ2NDoKKyAgICBjYXNlIE9QX1BBUlNFX1NJTlQzMjoKKyAgICBjYXNlIE9QX1BBUlNFX1NJTlQ2NDoKKyAgICBjYXNlIE9QX1NUQVJUU0VROgorICAgIGNhc2UgT1BfRU5EU0VROgorICAgIGNhc2UgT1BfU1RBUlRTVUJNU0c6CisgICAgY2FzZSBPUF9FTkRTVUJNU0c6CisgICAgY2FzZSBPUF9TVEFSVFNUUjoKKyAgICBjYXNlIE9QX1NUUklORzoKKyAgICBjYXNlIE9QX0VORFNUUjoKKyAgICBjYXNlIE9QX1BVU0hUQUdERUxJTToKKyAgICAgIHB1dDMyKGMsIG9wIHwgdmFfYXJnKGFwLCB1cGJfc2VsZWN0b3JfdCkgPDwgOCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIE9QX1NFVEJJR0dST1VQTlVNOgorICAgICAgcHV0MzIoYywgb3ApOworICAgICAgcHV0MzIoYywgdmFfYXJnKGFwLCBpbnQpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgT1BfQ0FMTDogeworICAgICAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbWV0aG9kID0gdmFfYXJnKGFwLCB1cGJfcGJkZWNvZGVybWV0aG9kICopOworICAgICAgcHV0MzIoYywgb3AgfCAobWV0aG9kLT5jb2RlX2Jhc2Uub2ZzIC0gKHBjb2ZzKGMpICsgMSkpIDw8IDgpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgT1BfQ0hFQ0tERUxJTToKKyAgICBjYXNlIE9QX0JSQU5DSDogeworICAgICAgdWludDMyX3QgaW5zdHJ1Y3Rpb24gPSBvcDsKKyAgICAgIGludCBsYWJlbCA9IHZhX2FyZyhhcCwgaW50KTsKKyAgICAgIHNldG9mcygmaW5zdHJ1Y3Rpb24sIGxhYmVscmVmKGMsIGxhYmVsKSk7CisgICAgICBwdXQzMihjLCBpbnN0cnVjdGlvbik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBPUF9UQUcxOgorICAgIGNhc2UgT1BfVEFHMjogeworICAgICAgaW50IGxhYmVsID0gdmFfYXJnKGFwLCBpbnQpOworICAgICAgdWludDY0X3QgdGFnID0gdmFfYXJnKGFwLCB1aW50NjRfdCk7CisgICAgICB1aW50MzJfdCBpbnN0cnVjdGlvbiA9IG9wIHwgKHRhZyA8PCAxNik7CisgICAgICBhc3NlcnQodGFnIDw9IDB4ZmZmZik7CisgICAgICBzZXRvZnMoJmluc3RydWN0aW9uLCBsYWJlbHJlZihjLCBsYWJlbCkpOworICAgICAgcHV0MzIoYywgaW5zdHJ1Y3Rpb24pOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgT1BfVEFHTjogeworICAgICAgaW50IGxhYmVsID0gdmFfYXJnKGFwLCBpbnQpOworICAgICAgdWludDY0X3QgdGFnID0gdmFfYXJnKGFwLCB1aW50NjRfdCk7CisgICAgICB1aW50MzJfdCBpbnN0cnVjdGlvbiA9IG9wIHwgKHVwYl92YWx1ZV9zaXplKHRhZykgPDwgMTYpOworICAgICAgc2V0b2ZzKCZpbnN0cnVjdGlvbiwgbGFiZWxyZWYoYywgbGFiZWwpKTsKKyAgICAgIHB1dDMyKGMsIGluc3RydWN0aW9uKTsKKyAgICAgIHB1dDMyKGMsIHRhZyk7CisgICAgICBwdXQzMihjLCB0YWcgPj4gMzIpOworICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgdmFfZW5kKGFwKTsKK30KKworI2lmIGRlZmluZWQoVVBCX1VTRV9KSVRfWDY0KSB8fCBkZWZpbmVkKFVQQl9EVU1QX0JZVEVDT0RFKQorCitjb25zdCBjaGFyICp1cGJfcGJkZWNvZGVyX2dldG9wbmFtZSh1bnNpZ25lZCBpbnQgb3ApIHsKKyNkZWZpbmUgT1Aob3ApIFtPUF8gIyMgb3BdID0gIk9QXyIgI29wCisjZGVmaW5lIFQob3ApIE9QKFBBUlNFXyMjb3ApCisgIHN0YXRpYyBjb25zdCBjaGFyICpuYW1lc1tdID0geworICAgICI8bm8gb3Bjb2RlPiIsCisgICAgVChET1VCTEUpLCBUKEZMT0FUKSwgVChJTlQ2NCksIFQoVUlOVDY0KSwgVChJTlQzMiksIFQoRklYRUQ2NCksIFQoRklYRUQzMiksCisgICAgVChCT09MKSwgVChVSU5UMzIpLCBUKFNGSVhFRDMyKSwgVChTRklYRUQ2NCksIFQoU0lOVDMyKSwgVChTSU5UNjQpLAorICAgIE9QKFNUQVJUTVNHKSwgT1AoRU5ETVNHKSwgT1AoU1RBUlRTRVEpLCBPUChFTkRTRVEpLCBPUChTVEFSVFNVQk1TRyksCisgICAgT1AoRU5EU1VCTVNHKSwgT1AoU1RBUlRTVFIpLCBPUChTVFJJTkcpLCBPUChFTkRTVFIpLCBPUChDQUxMKSwgT1AoUkVUKSwKKyAgICBPUChQVVNITEVOREVMSU0pLCBPUChQVVNIVEFHREVMSU0pLCBPUChTRVRERUxJTSksIE9QKENIRUNLREVMSU0pLAorICAgIE9QKEJSQU5DSCksIE9QKFRBRzEpLCBPUChUQUcyKSwgT1AoVEFHTiksIE9QKFNFVERJU1BBVENIKSwgT1AoUE9QKSwKKyAgICBPUChTRVRCSUdHUk9VUE5VTSksIE9QKERJU1BBVENIKSwgT1AoSEFMVCksCisgIH07CisgIHJldHVybiBvcCA+IE9QX0hBTFQgPyBuYW1lc1swXSA6IG5hbWVzW29wXTsKKyN1bmRlZiBPUAorI3VuZGVmIFQKK30KKworI2VuZGlmCisKKyNpZmRlZiBVUEJfRFVNUF9CWVRFQ09ERQorCitzdGF0aWMgdm9pZCBkdW1wYmModWludDMyX3QgKnAsIHVpbnQzMl90ICplbmQsIEZJTEUgKmYpIHsKKworICB1aW50MzJfdCAqYmVnaW4gPSBwOworCisgIHdoaWxlIChwIDwgZW5kKSB7CisgICAgZnByaW50ZihmLCAiJXAgICU4dHgiLCBwLCBwIC0gYmVnaW4pOworICAgIHVpbnQzMl90IGluc3RyID0gKnArKzsKKyAgICB1aW50OF90IG9wID0gZ2V0b3AoaW5zdHIpOworICAgIGZwcmludGYoZiwgIiAlcyIsIHVwYl9wYmRlY29kZXJfZ2V0b3BuYW1lKG9wKSk7CisgICAgc3dpdGNoICgob3Bjb2RlKW9wKSB7CisgICAgICBjYXNlIE9QX1NFVERJU1BBVENIOiB7CisgICAgICAgIGNvbnN0IHVwYl9pbnR0YWJsZSAqZGlzcGF0Y2g7CisgICAgICAgIG1lbWNweSgmZGlzcGF0Y2gsIHAsIHNpemVvZih2b2lkKikpOworICAgICAgICBwICs9IHB0cl93b3JkczsKKyAgICAgICAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbWV0aG9kID0KKyAgICAgICAgICAgICh2b2lkICopKChjaGFyICopZGlzcGF0Y2ggLQorICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0b2YodXBiX3BiZGVjb2Rlcm1ldGhvZCwgZGlzcGF0Y2gpKTsKKyAgICAgICAgZnByaW50ZihmLCAiICVzIiwgdXBiX21zZ2RlZl9mdWxsbmFtZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyc19tc2dkZWYobWV0aG9kLT5kZXN0X2hhbmRsZXJzXykpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjYXNlIE9QX0RJU1BBVENIOgorICAgICAgY2FzZSBPUF9TVEFSVE1TRzoKKyAgICAgIGNhc2UgT1BfRU5ETVNHOgorICAgICAgY2FzZSBPUF9QVVNITEVOREVMSU06CisgICAgICBjYXNlIE9QX1BPUDoKKyAgICAgIGNhc2UgT1BfU0VUREVMSU06CisgICAgICBjYXNlIE9QX0hBTFQ6CisgICAgICBjYXNlIE9QX1JFVDoKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE9QX1BBUlNFX0RPVUJMRToKKyAgICAgIGNhc2UgT1BfUEFSU0VfRkxPQVQ6CisgICAgICBjYXNlIE9QX1BBUlNFX0lOVDY0OgorICAgICAgY2FzZSBPUF9QQVJTRV9VSU5UNjQ6CisgICAgICBjYXNlIE9QX1BBUlNFX0lOVDMyOgorICAgICAgY2FzZSBPUF9QQVJTRV9GSVhFRDY0OgorICAgICAgY2FzZSBPUF9QQVJTRV9GSVhFRDMyOgorICAgICAgY2FzZSBPUF9QQVJTRV9CT09MOgorICAgICAgY2FzZSBPUF9QQVJTRV9VSU5UMzI6CisgICAgICBjYXNlIE9QX1BBUlNFX1NGSVhFRDMyOgorICAgICAgY2FzZSBPUF9QQVJTRV9TRklYRUQ2NDoKKyAgICAgIGNhc2UgT1BfUEFSU0VfU0lOVDMyOgorICAgICAgY2FzZSBPUF9QQVJTRV9TSU5UNjQ6CisgICAgICBjYXNlIE9QX1NUQVJUU0VROgorICAgICAgY2FzZSBPUF9FTkRTRVE6CisgICAgICBjYXNlIE9QX1NUQVJUU1VCTVNHOgorICAgICAgY2FzZSBPUF9FTkRTVUJNU0c6CisgICAgICBjYXNlIE9QX1NUQVJUU1RSOgorICAgICAgY2FzZSBPUF9TVFJJTkc6CisgICAgICBjYXNlIE9QX0VORFNUUjoKKyAgICAgIGNhc2UgT1BfUFVTSFRBR0RFTElNOgorICAgICAgICBmcHJpbnRmKGYsICIgJWQiLCBpbnN0ciA+PiA4KTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE9QX1NFVEJJR0dST1VQTlVNOgorICAgICAgICBmcHJpbnRmKGYsICIgJWQiLCAqcCsrKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE9QX0NIRUNLREVMSU06CisgICAgICBjYXNlIE9QX0NBTEw6CisgICAgICBjYXNlIE9QX0JSQU5DSDoKKyAgICAgICAgZnByaW50ZihmLCAiID0+MHgldHgiLCBwICsgZ2V0b2ZzKGluc3RyKSAtIGJlZ2luKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE9QX1RBRzE6CisgICAgICBjYXNlIE9QX1RBRzI6IHsKKyAgICAgICAgZnByaW50ZihmLCAiIHRhZzoweCV4IiwgaW5zdHIgPj4gMTYpOworICAgICAgICBpZiAoZ2V0b2ZzKGluc3RyKSkgeworICAgICAgICAgIGZwcmludGYoZiwgIiA9PjB4JXR4IiwgcCArIGdldG9mcyhpbnN0cikgLSBiZWdpbik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjYXNlIE9QX1RBR046IHsKKyAgICAgICAgdWludDY0X3QgdGFnID0gKnArKzsKKyAgICAgICAgdGFnIHw9ICh1aW50NjRfdCkqcCsrIDw8IDMyOworICAgICAgICBmcHJpbnRmKGYsICIgdGFnOjB4JWxseCIsIChsb25nIGxvbmcpdGFnKTsKKyAgICAgICAgZnByaW50ZihmLCAiIG46JWQiLCBpbnN0ciA+PiAxNik7CisgICAgICAgIGlmIChnZXRvZnMoaW5zdHIpKSB7CisgICAgICAgICAgZnByaW50ZihmLCAiID0+MHgldHgiLCBwICsgZ2V0b2ZzKGluc3RyKSAtIGJlZ2luKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgICAgZnB1dHMoIlxuIiwgZik7CisgIH0KK30KKworI2VuZGlmCisKK3N0YXRpYyB1aW50NjRfdCBnZXRfZW5jb2RlZF90YWcoY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBpbnQgd2lyZV90eXBlKSB7CisgIHVpbnQzMl90IHRhZyA9ICh1cGJfZmllbGRkZWZfbnVtYmVyKGYpIDw8IDMpIHwgd2lyZV90eXBlOworICB1aW50NjRfdCBlbmNvZGVkX3RhZyA9IHVwYl92ZW5jb2RlMzIodGFnKTsKKyAgLy8gTm8gdGFnIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gNSBieXRlcy4KKyAgYXNzZXJ0KGVuY29kZWRfdGFnIDw9IDB4ZmZmZmZmZmZmZik7CisgIHJldHVybiBlbmNvZGVkX3RhZzsKK30KKworc3RhdGljIHZvaWQgcHV0Y2hlY2t0YWcoY29tcGlsZXIgKmMsIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCB3aXJlX3R5cGUsIGludCBkZXN0KSB7CisgIHVpbnQ2NF90IHRhZyA9IGdldF9lbmNvZGVkX3RhZyhmLCB3aXJlX3R5cGUpOworICBzd2l0Y2ggKHVwYl92YWx1ZV9zaXplKHRhZykpIHsKKyAgICBjYXNlIDE6CisgICAgICBwdXRvcChjLCBPUF9UQUcxLCBkZXN0LCB0YWcpOworICAgICAgYnJlYWs7CisgICAgY2FzZSAyOgorICAgICAgcHV0b3AoYywgT1BfVEFHMiwgZGVzdCwgdGFnKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBwdXRvcChjLCBPUF9UQUdOLCBkZXN0LCB0YWcpOworICAgICAgYnJlYWs7CisgIH0KK30KKworc3RhdGljIHVwYl9zZWxlY3Rvcl90IGdldHNlbChjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9oYW5kbGVydHlwZV90IHR5cGUpIHsKKyAgdXBiX3NlbGVjdG9yX3Qgc2VsZWN0b3I7CisgIGJvb2wgb2sgPSB1cGJfaGFuZGxlcnNfZ2V0c2VsZWN0b3IoZiwgdHlwZSwgJnNlbGVjdG9yKTsKKyAgVVBCX0FTU0VSVF9WQVIob2ssIG9rKTsKKyAgcmV0dXJuIHNlbGVjdG9yOworfQorCisvLyBUYWtlcyBhbiBleGlzdGluZywgcHJpbWFyeSBkaXNwYXRjaCB0YWJsZSBlbnRyeSBhbmQgcmVwYWNrcyBpdCB3aXRoIGEKKy8vIGRpZmZlcmVudCBhbHRlcm5hdGUgd2lyZSB0eXBlLiAgQ2FsbGVkIHdoZW4gd2UgYXJlIGluc2VydGluZyBhIHNlY29uZGFyeQorLy8gZGlzcGF0Y2ggdGFibGUgZW50cnkgZm9yIGFuIGFsdGVybmF0ZSB3aXJlIHR5cGUuCitzdGF0aWMgdWludDY0X3QgcmVwYWNrKHVpbnQ2NF90IGRpc3BhdGNoLCBpbnQgbmV3X3d0MikgeworICB1aW50NjRfdCBvZnM7CisgIHVpbnQ4X3Qgd3QxOworICB1aW50OF90IG9sZF93dDI7CisgIHVwYl9wYmRlY29kZXJfdW5wYWNrZGlzcGF0Y2goZGlzcGF0Y2gsICZvZnMsICZ3dDEsICZvbGRfd3QyKTsKKyAgYXNzZXJ0KG9sZF93dDIgPT0gTk9fV0lSRV9UWVBFKTsgIC8vIHd0MiBzaG91bGQgbm90IGJlIHNldCB5ZXQuCisgIHJldHVybiB1cGJfcGJkZWNvZGVyX3BhY2tkaXNwYXRjaChvZnMsIHd0MSwgbmV3X3d0Mik7Cit9CisKKy8vIE1hcmtzIHRoZSBjdXJyZW50IGJ5dGVjb2RlIHBvc2l0aW9uIGFzIHRoZSBkaXNwYXRjaCB0YXJnZXQgZm9yIHRoaXMgbWVzc2FnZSwKKy8vIGZpZWxkLCBhbmQgd2lyZSB0eXBlLgorc3RhdGljIHZvaWQgZGlzcGF0Y2h0YXJnZXQoY29tcGlsZXIgKmMsIHVwYl9wYmRlY29kZXJtZXRob2QgKm1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgaW50IHdpcmVfdHlwZSkgeworICAvLyBPZmZzZXQgaXMgcmVsYXRpdmUgdG8gbXNnIGJhc2UuCisgIHVpbnQ2NF90IG9mcyA9IHBjb2ZzKGMpIC0gbWV0aG9kLT5jb2RlX2Jhc2Uub2ZzOworICB1aW50MzJfdCBmbiA9IHVwYl9maWVsZGRlZl9udW1iZXIoZik7CisgIHVwYl9pbnR0YWJsZSAqZCA9ICZtZXRob2QtPmRpc3BhdGNoOworICB1cGJfdmFsdWUgdjsKKyAgaWYgKHVwYl9pbnR0YWJsZV9yZW1vdmUoZCwgZm4sICZ2KSkgeworICAgIC8vIFRPRE86IHByaW9yaXRpemUgYmFzZWQgb24gcGFja2VkIHNldHRpbmcgaW4gLnByb3RvIGZpbGUuCisgICAgdWludDY0X3QgcmVwYWNrZWQgPSByZXBhY2sodXBiX3ZhbHVlX2dldHVpbnQ2NCh2KSwgd2lyZV90eXBlKTsKKyAgICB1cGJfaW50dGFibGVfaW5zZXJ0KGQsIGZuLCB1cGJfdmFsdWVfdWludDY0KHJlcGFja2VkKSk7CisgICAgdXBiX2ludHRhYmxlX2luc2VydChkLCBmbiArIFVQQl9NQVhfRklFTEROVU1CRVIsIHVwYl92YWx1ZV91aW50NjQob2ZzKSk7CisgIH0gZWxzZSB7CisgICAgdWludDY0X3QgdmFsID0gdXBiX3BiZGVjb2Rlcl9wYWNrZGlzcGF0Y2gob2ZzLCB3aXJlX3R5cGUsIE5PX1dJUkVfVFlQRSk7CisgICAgdXBiX2ludHRhYmxlX2luc2VydChkLCBmbiwgdXBiX3ZhbHVlX3VpbnQ2NCh2YWwpKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBwdXRwdXNoKGNvbXBpbGVyICpjLCBjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgaWYgKHVwYl9maWVsZGRlZl9kZXNjcmlwdG9ydHlwZShmKSA9PSBVUEJfREVTQ1JJUFRPUl9UWVBFX01FU1NBR0UpIHsKKyAgICBwdXRvcChjLCBPUF9QVVNITEVOREVMSU0pOworICB9IGVsc2UgeworICAgIHVpbnQzMl90IGZuID0gdXBiX2ZpZWxkZGVmX251bWJlcihmKTsKKyAgICBpZiAoZm4gPj0gMSA8PCAyNCkgeworICAgICAgcHV0b3AoYywgT1BfUFVTSFRBR0RFTElNLCAwKTsKKyAgICAgIHB1dG9wKGMsIE9QX1NFVEJJR0dST1VQTlVNLCBmbik7CisgICAgfSBlbHNlIHsKKyAgICAgIHB1dG9wKGMsIE9QX1BVU0hUQUdERUxJTSwgZm4pOworICAgIH0KKyAgfQorfQorCitzdGF0aWMgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqZmluZF9zdWJtZXRob2QoY29uc3QgY29tcGlsZXIgKmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBjb25zdCB1cGJfaGFuZGxlcnMgKnN1YiA9CisgICAgICB1cGJfaGFuZGxlcnNfZ2V0c3ViaGFuZGxlcnMobWV0aG9kLT5kZXN0X2hhbmRsZXJzXywgZik7CisgIHVwYl92YWx1ZSB2OworICByZXR1cm4gdXBiX2ludHRhYmxlX2xvb2t1cHB0cigmYy0+Z3JvdXAtPm1ldGhvZHMsIHN1YiwgJnYpCisgICAgICAgICAgICAgPyB1cGJfdmFsdWVfZ2V0cHRyKHYpCisgICAgICAgICAgICAgOiBOVUxMOworfQorCitzdGF0aWMgdm9pZCBwdXRzZWwoY29tcGlsZXIgKmMsIG9wY29kZSBvcCwgdXBiX3NlbGVjdG9yX3Qgc2VsLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9oYW5kbGVycyAqaCkgeworICBpZiAodXBiX2hhbmRsZXJzX2dldGhhbmRsZXIoaCwgc2VsKSkgeworICAgIHB1dG9wKGMsIG9wLCBzZWwpOworICB9Cit9CisKKy8vIFB1dHMgYW4gb3Bjb2RlIHRvIGNhbGwgYSBjYWxsYmFjaywgYnV0IG9ubHkgaWYgYSBjYWxsYmFjayBhY3R1YWxseSBleGlzdHMgZm9yCisvLyB0aGlzIGZpZWxkIGFuZCBoYW5kbGVyIHR5cGUuCitzdGF0aWMgdm9pZCBtYXliZXB1dChjb21waWxlciAqYywgb3Bjb2RlIG9wLCBjb25zdCB1cGJfaGFuZGxlcnMgKmgsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfZmllbGRkZWYgKmYsIHVwYl9oYW5kbGVydHlwZV90IHR5cGUpIHsKKyAgcHV0c2VsKGMsIG9wLCBnZXRzZWwoZiwgdHlwZSksIGgpOworfQorCitzdGF0aWMgYm9vbCBoYXNsYXp5aGFuZGxlcnMoY29uc3QgdXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYpIHsKKyAgaWYgKCF1cGJfZmllbGRkZWZfbGF6eShmKSkKKyAgICByZXR1cm4gZmFsc2U7CisKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKGgsIGdldHNlbChmLCBVUEJfSEFORExFUl9TVEFSVFNUUikpIHx8CisgICAgICAgICB1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihoLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfU1RSSU5HKSkgfHwKKyAgICAgICAgIHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKGgsIGdldHNlbChmLCBVUEJfSEFORExFUl9FTkRTVFIpKTsKK30KKworCisvKiBieXRlY29kZSBjb21waWxlciBjb2RlIGdlbmVyYXRpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvLyBTeW1ib2xpYyBuYW1lcyBmb3Igb3VyIGxvY2FsIGxhYmVscy4KKyNkZWZpbmUgTEFCRUxfTE9PUFNUQVJUIDEgIC8vIFRvcCBvZiBhIHJlcGVhdGVkIGZpZWxkIGxvb3AuCisjZGVmaW5lIExBQkVMX0xPT1BCUkVBSyAyICAvLyBUbyBqdW1wIG91dCBvZiBhIHJlcGVhdGVkIGxvb3AKKyNkZWZpbmUgTEFCRUxfRklFTEQgICAgIDMgIC8vIEp1bXAgYmFja3dhcmQgdG8gZmluZCB0aGUgbW9zdCByZWNlbnQgZmllbGQuCisjZGVmaW5lIExBQkVMX0VORE1TRyAgICA0ICAvLyBUbyByZWFjaCB0aGUgT1BfRU5ETVNHIGluc3RyIGZvciB0aGlzIG1zZy4KKworLy8gR2VuZXJhdGVzIGJ5dGVjb2RlIHRvIHBhcnNlIGEgc2luZ2xlIG5vbi1sYXp5IG1lc3NhZ2UgZmllbGQuCitzdGF0aWMgdm9pZCBnZW5lcmF0ZV9tc2dmaWVsZChjb21waWxlciAqYywgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbWV0aG9kKSB7CisgIGNvbnN0IHVwYl9oYW5kbGVycyAqaCA9IHVwYl9wYmRlY29kZXJtZXRob2RfZGVzdGhhbmRsZXJzKG1ldGhvZCk7CisgIGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKnN1Yl9tID0gZmluZF9zdWJtZXRob2QoYywgbWV0aG9kLCBmKTsKKworICBpZiAoIXN1Yl9tKSB7CisgICAgLy8gRG9uJ3QgZW1pdCBhbnkgY29kZSBmb3IgdGhpcyBmaWVsZCBhdCBhbGw7IGl0IHdpbGwgYmUgcGFyc2VkIGFzIGFuCisgICAgLy8gdW5rbm93biBmaWVsZC4KKyAgICByZXR1cm47CisgIH0KKworICBsYWJlbChjLCBMQUJFTF9GSUVMRCk7CisKKyAgaW50IHdpcmVfdHlwZSA9CisgICAgICAodXBiX2ZpZWxkZGVmX2Rlc2NyaXB0b3J0eXBlKGYpID09IFVQQl9ERVNDUklQVE9SX1RZUEVfTUVTU0FHRSkKKyAgICAgICAgICA/IFVQQl9XSVJFX1RZUEVfREVMSU1JVEVECisgICAgICAgICAgOiBVUEJfV0lSRV9UWVBFX1NUQVJUX0dST1VQOworCisgIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsKKyAgICBwdXRvcChjLCBPUF9DSEVDS0RFTElNLCBMQUJFTF9FTkRNU0cpOworICAgIHB1dGNoZWNrdGFnKGMsIGYsIHdpcmVfdHlwZSwgTEFCRUxfRElTUEFUQ0gpOworICAgZGlzcGF0Y2h0YXJnZXQoYywgbWV0aG9kLCBmLCB3aXJlX3R5cGUpOworICAgIHB1dG9wKGMsIE9QX1BVU0hUQUdERUxJTSwgMCk7CisgICAgcHV0b3AoYywgT1BfU1RBUlRTRVEsIGdldHNlbChmLCBVUEJfSEFORExFUl9TVEFSVFNFUSkpOworICAgbGFiZWwoYywgTEFCRUxfTE9PUFNUQVJUKTsKKyAgICBwdXRwdXNoKGMsIGYpOworICAgIHB1dG9wKGMsIE9QX1NUQVJUU1VCTVNHLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfU1RBUlRTVUJNU0cpKTsKKyAgICBwdXRvcChjLCBPUF9DQUxMLCBzdWJfbSk7CisgICAgcHV0b3AoYywgT1BfUE9QKTsKKyAgICBtYXliZXB1dChjLCBPUF9FTkRTVUJNU0csIGgsIGYsIFVQQl9IQU5ETEVSX0VORFNVQk1TRyk7CisgICAgaWYgKHdpcmVfdHlwZSA9PSBVUEJfV0lSRV9UWVBFX0RFTElNSVRFRCkgeworICAgICAgcHV0b3AoYywgT1BfU0VUREVMSU0pOworICAgIH0KKyAgICBwdXRvcChjLCBPUF9DSEVDS0RFTElNLCBMQUJFTF9MT09QQlJFQUspOworICAgIHB1dGNoZWNrdGFnKGMsIGYsIHdpcmVfdHlwZSwgTEFCRUxfTE9PUEJSRUFLKTsKKyAgICBwdXRvcChjLCBPUF9CUkFOQ0gsIC1MQUJFTF9MT09QU1RBUlQpOworICAgbGFiZWwoYywgTEFCRUxfTE9PUEJSRUFLKTsKKyAgICBwdXRvcChjLCBPUF9QT1ApOworICAgIG1heWJlcHV0KGMsIE9QX0VORFNFUSwgaCwgZiwgVVBCX0hBTkRMRVJfRU5EU0VRKTsKKyAgfSBlbHNlIHsKKyAgICBwdXRvcChjLCBPUF9DSEVDS0RFTElNLCBMQUJFTF9FTkRNU0cpOworICAgIHB1dGNoZWNrdGFnKGMsIGYsIHdpcmVfdHlwZSwgTEFCRUxfRElTUEFUQ0gpOworICAgZGlzcGF0Y2h0YXJnZXQoYywgbWV0aG9kLCBmLCB3aXJlX3R5cGUpOworICAgIHB1dHB1c2goYywgZik7CisgICAgcHV0b3AoYywgT1BfU1RBUlRTVUJNU0csIGdldHNlbChmLCBVUEJfSEFORExFUl9TVEFSVFNVQk1TRykpOworICAgIHB1dG9wKGMsIE9QX0NBTEwsIHN1Yl9tKTsKKyAgICBwdXRvcChjLCBPUF9QT1ApOworICAgIG1heWJlcHV0KGMsIE9QX0VORFNVQk1TRywgaCwgZiwgVVBCX0hBTkRMRVJfRU5EU1VCTVNHKTsKKyAgICBpZiAod2lyZV90eXBlID09IFVQQl9XSVJFX1RZUEVfREVMSU1JVEVEKSB7CisgICAgICBwdXRvcChjLCBPUF9TRVRERUxJTSk7CisgICAgfQorICB9Cit9CisKKy8vIEdlbmVyYXRlcyBieXRlY29kZSB0byBwYXJzZSBhIHNpbmdsZSBzdHJpbmcgb3IgbGF6eSBzdWJtZXNzYWdlIGZpZWxkLgorc3RhdGljIHZvaWQgZ2VuZXJhdGVfZGVsaW1maWVsZChjb21waWxlciAqYywgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfcGJkZWNvZGVybWV0aG9kICptZXRob2QpIHsKKyAgY29uc3QgdXBiX2hhbmRsZXJzICpoID0gdXBiX3BiZGVjb2Rlcm1ldGhvZF9kZXN0aGFuZGxlcnMobWV0aG9kKTsKKworICBsYWJlbChjLCBMQUJFTF9GSUVMRCk7CisgIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsKKyAgICBwdXRvcChjLCBPUF9DSEVDS0RFTElNLCBMQUJFTF9FTkRNU0cpOworICAgIHB1dGNoZWNrdGFnKGMsIGYsIFVQQl9XSVJFX1RZUEVfREVMSU1JVEVELCBMQUJFTF9ESVNQQVRDSCk7CisgICBkaXNwYXRjaHRhcmdldChjLCBtZXRob2QsIGYsIFVQQl9XSVJFX1RZUEVfREVMSU1JVEVEKTsKKyAgICBwdXRvcChjLCBPUF9QVVNIVEFHREVMSU0sIDApOworICAgIHB1dG9wKGMsIE9QX1NUQVJUU0VRLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfU1RBUlRTRVEpKTsKKyAgIGxhYmVsKGMsIExBQkVMX0xPT1BTVEFSVCk7CisgICAgcHV0b3AoYywgT1BfUFVTSExFTkRFTElNKTsKKyAgICBwdXRvcChjLCBPUF9TVEFSVFNUUiwgZ2V0c2VsKGYsIFVQQl9IQU5ETEVSX1NUQVJUU1RSKSk7CisgICAgLy8gTmVlZCB0byBlbWl0IGV2ZW4gaWYgbm8gaGFuZGxlciB0byBza2lwIHBhc3QgdGhlIHN0cmluZy4KKyAgICBwdXRvcChjLCBPUF9TVFJJTkcsIGdldHNlbChmLCBVUEJfSEFORExFUl9TVFJJTkcpKTsKKyAgICBwdXRvcChjLCBPUF9QT1ApOworICAgIG1heWJlcHV0KGMsIE9QX0VORFNUUiwgaCwgZiwgVVBCX0hBTkRMRVJfRU5EU1RSKTsKKyAgICBwdXRvcChjLCBPUF9TRVRERUxJTSk7CisgICAgcHV0b3AoYywgT1BfQ0hFQ0tERUxJTSwgTEFCRUxfTE9PUEJSRUFLKTsKKyAgICBwdXRjaGVja3RhZyhjLCBmLCBVUEJfV0lSRV9UWVBFX0RFTElNSVRFRCwgTEFCRUxfTE9PUEJSRUFLKTsKKyAgICBwdXRvcChjLCBPUF9CUkFOQ0gsIC1MQUJFTF9MT09QU1RBUlQpOworICAgbGFiZWwoYywgTEFCRUxfTE9PUEJSRUFLKTsKKyAgICBwdXRvcChjLCBPUF9QT1ApOworICAgIG1heWJlcHV0KGMsIE9QX0VORFNFUSwgaCwgZiwgVVBCX0hBTkRMRVJfRU5EU0VRKTsKKyAgfSBlbHNlIHsKKyAgICBwdXRvcChjLCBPUF9DSEVDS0RFTElNLCBMQUJFTF9FTkRNU0cpOworICAgIHB1dGNoZWNrdGFnKGMsIGYsIFVQQl9XSVJFX1RZUEVfREVMSU1JVEVELCBMQUJFTF9ESVNQQVRDSCk7CisgICBkaXNwYXRjaHRhcmdldChjLCBtZXRob2QsIGYsIFVQQl9XSVJFX1RZUEVfREVMSU1JVEVEKTsKKyAgICBwdXRvcChjLCBPUF9QVVNITEVOREVMSU0pOworICAgIHB1dG9wKGMsIE9QX1NUQVJUU1RSLCBnZXRzZWwoZiwgVVBCX0hBTkRMRVJfU1RBUlRTVFIpKTsKKyAgICBwdXRvcChjLCBPUF9TVFJJTkcsIGdldHNlbChmLCBVUEJfSEFORExFUl9TVFJJTkcpKTsKKyAgICBwdXRvcChjLCBPUF9QT1ApOworICAgIG1heWJlcHV0KGMsIE9QX0VORFNUUiwgaCwgZiwgVVBCX0hBTkRMRVJfRU5EU1RSKTsKKyAgICBwdXRvcChjLCBPUF9TRVRERUxJTSk7CisgIH0KK30KKworLy8gR2VuZXJhdGVzIGJ5dGVjb2RlIHRvIHBhcnNlIGEgc2luZ2xlIHByaW1pdGl2ZSBmaWVsZC4KK3N0YXRpYyB2b2lkIGdlbmVyYXRlX3ByaW1pdGl2ZWZpZWxkKGNvbXBpbGVyICpjLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfcGJkZWNvZGVybWV0aG9kICptZXRob2QpIHsKKyAgbGFiZWwoYywgTEFCRUxfRklFTEQpOworCisgIGNvbnN0IHVwYl9oYW5kbGVycyAqaCA9IHVwYl9wYmRlY29kZXJtZXRob2RfZGVzdGhhbmRsZXJzKG1ldGhvZCk7CisgIHVwYl9kZXNjcmlwdG9ydHlwZV90IGRlc2NyaXB0b3JfdHlwZSA9IHVwYl9maWVsZGRlZl9kZXNjcmlwdG9ydHlwZShmKTsKKworICAvLyBGcm9tIGEgZGVjb2RpbmcgcGVyc3BlY3RpdmUsIEVOVU0gaXMgdGhlIHNhbWUgYXMgSU5UMzIuCisgIGlmIChkZXNjcmlwdG9yX3R5cGUgPT0gVVBCX0RFU0NSSVBUT1JfVFlQRV9FTlVNKQorICAgIGRlc2NyaXB0b3JfdHlwZSA9IFVQQl9ERVNDUklQVE9SX1RZUEVfSU5UMzI7CisKKyAgb3Bjb2RlIHBhcnNlX3R5cGUgPSAob3Bjb2RlKWRlc2NyaXB0b3JfdHlwZTsKKworICAvLyBUT0RPKGhhYmVybWFuKTogZ2VuZXJhdGUgcGFja2VkIG9yIG5vbi1wYWNrZWQgZmlyc3QgZGVwZW5kaW5nIG9uICJwYWNrZWQiCisgIC8vIHNldHRpbmcgaW4gdGhlIGZpZWxkZGVmLiAgVGhpcyB3aWxsIGZhdm9yIChpbiBzcGVlZCkgd2hpY2hldmVyIHdhcworICAvLyBzcGVjaWZpZWQuCisKKyAgYXNzZXJ0KChpbnQpcGFyc2VfdHlwZSA+PSAwICYmIHBhcnNlX3R5cGUgPD0gT1BfTUFYKTsKKyAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gZ2V0c2VsKGYsIHVwYl9oYW5kbGVyc19nZXRwcmltaXRpdmVoYW5kbGVydHlwZShmKSk7CisgIGludCB3aXJlX3R5cGUgPSB1cGJfcGJfbmF0aXZlX3dpcmVfdHlwZXNbdXBiX2ZpZWxkZGVmX2Rlc2NyaXB0b3J0eXBlKGYpXTsKKyAgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSkgeworICAgIHB1dG9wKGMsIE9QX0NIRUNLREVMSU0sIExBQkVMX0VORE1TRyk7CisgICAgcHV0Y2hlY2t0YWcoYywgZiwgVVBCX1dJUkVfVFlQRV9ERUxJTUlURUQsIExBQkVMX0RJU1BBVENIKTsKKyAgIGRpc3BhdGNodGFyZ2V0KGMsIG1ldGhvZCwgZiwgVVBCX1dJUkVfVFlQRV9ERUxJTUlURUQpOworICAgIHB1dG9wKGMsIE9QX1BVU0hMRU5ERUxJTSk7CisgICAgcHV0b3AoYywgT1BfU1RBUlRTRVEsIGdldHNlbChmLCBVUEJfSEFORExFUl9TVEFSVFNFUSkpOyAgLy8gUGFja2VkCisgICBsYWJlbChjLCBMQUJFTF9MT09QU1RBUlQpOworICAgIHB1dG9wKGMsIHBhcnNlX3R5cGUsIHNlbCk7CisgICAgcHV0b3AoYywgT1BfQ0hFQ0tERUxJTSwgTEFCRUxfTE9PUEJSRUFLKTsKKyAgICBwdXRvcChjLCBPUF9CUkFOQ0gsIC1MQUJFTF9MT09QU1RBUlQpOworICAgZGlzcGF0Y2h0YXJnZXQoYywgbWV0aG9kLCBmLCB3aXJlX3R5cGUpOworICAgIHB1dG9wKGMsIE9QX1BVU0hUQUdERUxJTSwgMCk7CisgICAgcHV0b3AoYywgT1BfU1RBUlRTRVEsIGdldHNlbChmLCBVUEJfSEFORExFUl9TVEFSVFNFUSkpOyAgLy8gTm9uLXBhY2tlZAorICAgbGFiZWwoYywgTEFCRUxfTE9PUFNUQVJUKTsKKyAgICBwdXRvcChjLCBwYXJzZV90eXBlLCBzZWwpOworICAgIHB1dG9wKGMsIE9QX0NIRUNLREVMSU0sIExBQkVMX0xPT1BCUkVBSyk7CisgICAgcHV0Y2hlY2t0YWcoYywgZiwgd2lyZV90eXBlLCBMQUJFTF9MT09QQlJFQUspOworICAgIHB1dG9wKGMsIE9QX0JSQU5DSCwgLUxBQkVMX0xPT1BTVEFSVCk7CisgICBsYWJlbChjLCBMQUJFTF9MT09QQlJFQUspOworICAgIHB1dG9wKGMsIE9QX1BPUCk7ICAvLyBQYWNrZWQgYW5kIG5vbi1wYWNrZWQgam9pbi4KKyAgICBtYXliZXB1dChjLCBPUF9FTkRTRVEsIGgsIGYsIFVQQl9IQU5ETEVSX0VORFNFUSk7CisgICAgcHV0b3AoYywgT1BfU0VUREVMSU0pOyAgLy8gQ291bGQgcmVtb3ZlIGZvciBub24tcGFja2VkIGJ5IGR1cCBFTkRTRVEuCisgIH0gZWxzZSB7CisgICAgcHV0b3AoYywgT1BfQ0hFQ0tERUxJTSwgTEFCRUxfRU5ETVNHKTsKKyAgICBwdXRjaGVja3RhZyhjLCBmLCB3aXJlX3R5cGUsIExBQkVMX0RJU1BBVENIKTsKKyAgIGRpc3BhdGNodGFyZ2V0KGMsIG1ldGhvZCwgZiwgd2lyZV90eXBlKTsKKyAgICBwdXRvcChjLCBwYXJzZV90eXBlLCBzZWwpOworICB9Cit9CisKKy8vIEFkZHMgYnl0ZWNvZGUgZm9yIHBhcnNpbmcgdGhlIGdpdmVuIG1lc3NhZ2UgdG8gdGhlIGdpdmVuIGRlY29kZXJwbGFuLAorLy8gd2hpbGUgYWRkaW5nIGFsbCBkaXNwYXRjaCB0YXJnZXRzIHRvIHRoaXMgbWVzc2FnZSdzIGRpc3BhdGNoIHRhYmxlLgorc3RhdGljIHZvaWQgY29tcGlsZV9tZXRob2QoY29tcGlsZXIgKmMsIHVwYl9wYmRlY29kZXJtZXRob2QgKm1ldGhvZCkgeworICBhc3NlcnQobWV0aG9kKTsKKworICAvLyBDbGVhciBhbGwgZW50cmllcyBpbiB0aGUgZGlzcGF0Y2ggdGFibGUuCisgIHVwYl9pbnR0YWJsZV91bmluaXQoJm1ldGhvZC0+ZGlzcGF0Y2gpOworICB1cGJfaW50dGFibGVfaW5pdCgmbWV0aG9kLT5kaXNwYXRjaCwgVVBCX0NUWVBFX1VJTlQ2NCk7CisKKyAgY29uc3QgdXBiX2hhbmRsZXJzICpoID0gdXBiX3BiZGVjb2Rlcm1ldGhvZF9kZXN0aGFuZGxlcnMobWV0aG9kKTsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbWQgPSB1cGJfaGFuZGxlcnNfbXNnZGVmKGgpOworCisgbWV0aG9kLT5jb2RlX2Jhc2Uub2ZzID0gcGNvZnMoYyk7CisgIHB1dG9wKGMsIE9QX1NFVERJU1BBVENILCAmbWV0aG9kLT5kaXNwYXRjaCk7CisgIHB1dHNlbChjLCBPUF9TVEFSVE1TRywgVVBCX1NUQVJUTVNHX1NFTEVDVE9SLCBoKTsKKyBsYWJlbChjLCBMQUJFTF9GSUVMRCk7CisgIHVpbnQzMl90KiBzdGFydF9wYyA9IGMtPnBjOworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmksIG1kKTsKKyAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmkpOworICAgICAgdXBiX21zZ19maWVsZF9uZXh0KCZpKSkgeworICAgIGNvbnN0IHVwYl9maWVsZGRlZiAqZiA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaSk7CisgICAgdXBiX2ZpZWxkdHlwZV90IHR5cGUgPSB1cGJfZmllbGRkZWZfdHlwZShmKTsKKworICAgIGlmICh0eXBlID09IFVQQl9UWVBFX01FU1NBR0UgJiYgIShoYXNsYXp5aGFuZGxlcnMoaCwgZikgJiYgYy0+bGF6eSkpIHsKKyAgICAgIGdlbmVyYXRlX21zZ2ZpZWxkKGMsIGYsIG1ldGhvZCk7CisgICAgfSBlbHNlIGlmICh0eXBlID09IFVQQl9UWVBFX1NUUklORyB8fCB0eXBlID09IFVQQl9UWVBFX0JZVEVTIHx8CisgICAgICAgICAgICAgICB0eXBlID09IFVQQl9UWVBFX01FU1NBR0UpIHsKKyAgICAgIGdlbmVyYXRlX2RlbGltZmllbGQoYywgZiwgbWV0aG9kKTsKKyAgICB9IGVsc2UgeworICAgICAgZ2VuZXJhdGVfcHJpbWl0aXZlZmllbGQoYywgZiwgbWV0aG9kKTsKKyAgICB9CisgIH0KKworICAvLyBJZiB0aGVyZSB3ZXJlIG5vIGZpZWxkcywgb3IgaWYgbm8gaGFuZGxlcnMgd2VyZSBkZWZpbmVkLCB3ZSBuZWVkIHRvCisgIC8vIGdlbmVyYXRlIGEgbm9uLWVtcHR5IGxvb3AgYm9keSBzbyB0aGF0IHdlIGNhbiBhdCBsZWFzdCBkaXNwYXRjaCBmb3IgdW5rbm93bgorICAvLyBmaWVsZHMgYW5kIGNoZWNrIGZvciB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLgorICBpZiAoYy0+cGMgPT0gc3RhcnRfcGMpIHsKKyAgICAvLyBDaGVjayBmb3IgZW5kLW9mLW1lc3NhZ2UuCisgICAgcHV0b3AoYywgT1BfQ0hFQ0tERUxJTSwgTEFCRUxfRU5ETVNHKTsKKyAgICAvLyBVbmNvbmRpdGlvbmFsbHkgZGlzcGF0Y2guCisgICAgcHV0b3AoYywgT1BfRElTUEFUQ0gsIDApOworICB9CisKKyAgLy8gRm9yIG5vdyB3ZSBqdXN0IGxvb3AgYmFjayB0byB0aGUgbGFzdCBmaWVsZCBvZiB0aGUgbWVzc2FnZSAob3IgaWYgbm9uZSwKKyAgLy8gdGhlIERJU1BBVENIIG9wY29kZSBmb3IgdGhlIG1lc3NhZ2UpLgorICBwdXRvcChjLCBPUF9CUkFOQ0gsIC1MQUJFTF9GSUVMRCk7CisKKyAgLy8gSW5zZXJ0IGJvdGggYSBsYWJlbCBhbmQgYSBkaXNwYXRjaCB0YWJsZSBlbnRyeSBmb3IgdGhpcyBlbmQtb2YtbXNnLgorIGxhYmVsKGMsIExBQkVMX0VORE1TRyk7CisgIHVwYl92YWx1ZSB2YWwgPSB1cGJfdmFsdWVfdWludDY0KHBjb2ZzKGMpIC0gbWV0aG9kLT5jb2RlX2Jhc2Uub2ZzKTsKKyAgdXBiX2ludHRhYmxlX2luc2VydCgmbWV0aG9kLT5kaXNwYXRjaCwgRElTUEFUQ0hfRU5ETVNHLCB2YWwpOworCisgIHB1dHNlbChjLCBPUF9FTkRNU0csIFVQQl9FTkRNU0dfU0VMRUNUT1IsIGgpOworICBwdXRvcChjLCBPUF9SRVQpOworCisgIHVwYl9pbnR0YWJsZV9jb21wYWN0KCZtZXRob2QtPmRpc3BhdGNoKTsKK30KKworLy8gUG9wdWxhdGUgIm1ldGhvZHMiIHdpdGggbmV3IHVwYl9wYmRlY29kZXJtZXRob2Qgb2JqZWN0cyByZWFjaGFibGUgZnJvbSAiaCIuCisvLyBSZXR1cm5zIHRoZSBtZXRob2QgZm9yIHRoZXNlIGhhbmRsZXJzLgorLy8KKy8vIEdlbmVyYXRlcyBhIG5ldyBtZXRob2QgZm9yIGV2ZXJ5IGRlc3RpbmF0aW9uIGhhbmRsZXJzIHJlYWNoYWJsZSBmcm9tICJoIi4KK3N0YXRpYyB2b2lkIGZpbmRfbWV0aG9kcyhjb21waWxlciAqYywgY29uc3QgdXBiX2hhbmRsZXJzICpoKSB7CisgIHVwYl92YWx1ZSB2OworICBpZiAodXBiX2ludHRhYmxlX2xvb2t1cHB0cigmYy0+Z3JvdXAtPm1ldGhvZHMsIGgsICZ2KSkKKyAgICByZXR1cm47CisgIG5ld21ldGhvZChoLCBjLT5ncm91cCk7CisKKyAgLy8gRmluZCBzdWJtZXRob2RzLgorICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbWQgPSB1cGJfaGFuZGxlcnNfbXNnZGVmKGgpOworICBmb3IodXBiX21zZ19maWVsZF9iZWdpbigmaSwgbWQpOworICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaSk7CisgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpKTsKKyAgICBjb25zdCB1cGJfaGFuZGxlcnMgKnN1Yl9oOworICAgIGlmICh1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9NRVNTQUdFICYmCisgICAgICAgIChzdWJfaCA9IHVwYl9oYW5kbGVyc19nZXRzdWJoYW5kbGVycyhoLCBmKSkgIT0gTlVMTCkgeworICAgICAgLy8gV2Ugb25seSBnZW5lcmF0ZSBhIGRlY29kZXIgbWV0aG9kIGZvciBzdWJtZXNzYWdlcyB3aXRoIGhhbmRsZXJzLgorICAgICAgLy8gT3RoZXJzIHdpbGwgYmUgcGFyc2VkIGFzIHVua25vd24gZmllbGRzLgorICAgICAgZmluZF9tZXRob2RzKGMsIHN1Yl9oKTsKKyAgICB9CisgIH0KK30KKworLy8gKFJlLSljb21waWxlIGJ5dGVjb2RlIGZvciBhbGwgbWVzc2FnZXMgaW4gIm1zZ3MuIgorLy8gT3ZlcndyaXRlcyBhbnkgZXhpc3RpbmcgYnl0ZWNvZGUgaW4gImMiLgorc3RhdGljIHZvaWQgY29tcGlsZV9tZXRob2RzKGNvbXBpbGVyICpjKSB7CisgIC8vIFN0YXJ0IG92ZXIgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYnl0ZWNvZGUuCisgIGMtPnBjID0gYy0+Z3JvdXAtPmJ5dGVjb2RlOworCisgIHVwYl9pbnR0YWJsZV9pdGVyIGk7CisgIHVwYl9pbnR0YWJsZV9iZWdpbigmaSwgJmMtPmdyb3VwLT5tZXRob2RzKTsKKyAgZm9yKDsgIXVwYl9pbnR0YWJsZV9kb25lKCZpKTsgdXBiX2ludHRhYmxlX25leHQoJmkpKSB7CisgICAgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbWV0aG9kID0gdXBiX3ZhbHVlX2dldHB0cih1cGJfaW50dGFibGVfaXRlcl92YWx1ZSgmaSkpOworICAgIGNvbXBpbGVfbWV0aG9kKGMsIG1ldGhvZCk7CisgIH0KK30KKworc3RhdGljIHZvaWQgc2V0X2J5dGVjb2RlX2hhbmRsZXJzKG1ncm91cCAqZykgeworICB1cGJfaW50dGFibGVfaXRlciBpOworICB1cGJfaW50dGFibGVfYmVnaW4oJmksICZnLT5tZXRob2RzKTsKKyAgZm9yKDsgIXVwYl9pbnR0YWJsZV9kb25lKCZpKTsgdXBiX2ludHRhYmxlX25leHQoJmkpKSB7CisgICAgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSA9IHVwYl92YWx1ZV9nZXRwdHIodXBiX2ludHRhYmxlX2l0ZXJfdmFsdWUoJmkpKTsKKworICAgIG0tPmNvZGVfYmFzZS5wdHIgPSBnLT5ieXRlY29kZSArIG0tPmNvZGVfYmFzZS5vZnM7CisKKyAgICB1cGJfYnl0ZXNoYW5kbGVyICpoID0gJm0tPmlucHV0X2hhbmRsZXJfOworICAgIHVwYl9ieXRlc2hhbmRsZXJfc2V0c3RhcnRzdHIoaCwgdXBiX3BiZGVjb2Rlcl9zdGFydGJjLCBtLT5jb2RlX2Jhc2UucHRyKTsKKyAgICB1cGJfYnl0ZXNoYW5kbGVyX3NldHN0cmluZyhoLCB1cGJfcGJkZWNvZGVyX2RlY29kZSwgZyk7CisgICAgdXBiX2J5dGVzaGFuZGxlcl9zZXRlbmRzdHIoaCwgdXBiX3BiZGVjb2Rlcl9lbmQsIG0pOworICB9Cit9CisKKworLyogSklUIHNldHVwLiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2lmZGVmIFVQQl9VU0VfSklUX1g2NAorCitzdGF0aWMgdm9pZCBzZXRoYW5kbGVycyhtZ3JvdXAgKmcsIGJvb2wgYWxsb3dqaXQpIHsKKyAgZy0+aml0X2NvZGUgPSBOVUxMOworICBpZiAoYWxsb3dqaXQpIHsKKyAgICAvLyBDb21waWxlIGJ5dGUtY29kZSBpbnRvIG1hY2hpbmUgY29kZSwgY3JlYXRlIGhhbmRsZXJzLgorICAgIHVwYl9wYmRlY29kZXJfaml0KGcpOworICB9IGVsc2UgeworICAgIHNldF9ieXRlY29kZV9oYW5kbGVycyhnKTsKKyAgfQorfQorCisjZWxzZSAgLy8gVVBCX1VTRV9KSVRfWDY0CisKK3N0YXRpYyB2b2lkIHNldGhhbmRsZXJzKG1ncm91cCAqZywgYm9vbCBhbGxvd2ppdCkgeworICAvLyBObyBKSVQgY29tcGlsZWQgaW47IHVzZSBieXRlY29kZSBoYW5kbGVycyB1bmNvbmRpdGlvbmFsbHkuCisgIFVQQl9VTlVTRUQoYWxsb3dqaXQpOworICBzZXRfYnl0ZWNvZGVfaGFuZGxlcnMoZyk7Cit9CisKKyNlbmRpZiAgLy8gVVBCX1VTRV9KSVRfWDY0CisKKworLy8gVE9ETyhoYWJlcm1hbik6IGFsbG93IHRoaXMgdG8gYmUgY29uc3RydWN0ZWQgZm9yIGFuIGFyYml0cmFyeSBzZXQgb2YgZGVzdAorLy8gaGFuZGxlcnMgYW5kIG90aGVyIG1ncm91cHMgKGJ1dCB2ZXJpZnkgd2UgaGF2ZSBhIHRyYW5zaXRpdmUgY2xvc3VyZSkuCitjb25zdCBtZ3JvdXAgKm1ncm91cF9uZXcoY29uc3QgdXBiX2hhbmRsZXJzICpkZXN0LCBib29sIGFsbG93aml0LCBib29sIGxhenksCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgVVBCX1VOVVNFRChhbGxvd2ppdCk7CisgIGFzc2VydCh1cGJfaGFuZGxlcnNfaXNmcm96ZW4oZGVzdCkpOworCisgIG1ncm91cCAqZyA9IG5ld2dyb3VwKG93bmVyKTsKKyAgY29tcGlsZXIgKmMgPSBuZXdjb21waWxlcihnLCBsYXp5KTsKKyAgZmluZF9tZXRob2RzKGMsIGRlc3QpOworCisgIC8vIFdlIGNvbXBpbGUgaW4gdHdvIHBhc3NlczoKKyAgLy8gMS4gYWxsIG1lc3NhZ2VzIGFyZSBhc3NpZ25lZCByZWxhdGl2ZSBvZmZzZXRzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUKKyAgLy8gICAgYnl0ZWNvZGUgKHNhdmVkIGluIG1ldGhvZC0+Y29kZV9iYXNlKS4KKyAgLy8gMi4gZm9yd2FyZHMgT1BfQ0FMTCBpbnN0cnVjdGlvbnMgY2FuIGJlIGNvcnJlY3RseSBsaW5rZWQgc2luY2UgbWVzc2FnZQorICAvLyAgICBvZmZzZXRzIGhhdmUgYmVlbiBwcmV2aW91c2x5IGFzc2lnbmVkLgorICAvLworICAvLyBDb3VsZCBhdm9pZCB0aGUgc2Vjb25kIHBhc3MgYnkgbGlua2luZyBPUF9DQUxMIGluc3RydWN0aW9ucyBzb21laG93LgorICBjb21waWxlX21ldGhvZHMoYyk7CisgIGNvbXBpbGVfbWV0aG9kcyhjKTsKKyAgZy0+Ynl0ZWNvZGVfZW5kID0gYy0+cGM7CisgIGZyZWVjb21waWxlcihjKTsKKworI2lmZGVmIFVQQl9EVU1QX0JZVEVDT0RFCisgIEZJTEUgKmYgPSBmb3BlbigiL3RtcC91cGItYnl0ZWNvZGUiLCAid2IiKTsKKyAgYXNzZXJ0KGYpOworICBkdW1wYmMoZy0+Ynl0ZWNvZGUsIGctPmJ5dGVjb2RlX2VuZCwgc3RkZXJyKTsKKyAgZHVtcGJjKGctPmJ5dGVjb2RlLCBnLT5ieXRlY29kZV9lbmQsIGYpOworICBmY2xvc2UoZik7CisjZW5kaWYKKworICBzZXRoYW5kbGVycyhnLCBhbGxvd2ppdCk7CisgIHJldHVybiBnOworfQorCisKKy8qIHVwYl9wYmNvZGVjYWNoZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3ZvaWQgdXBiX3BiY29kZWNhY2hlX2luaXQodXBiX3BiY29kZWNhY2hlICpjKSB7CisgIHVwYl9pbnR0YWJsZV9pbml0KCZjLT5ncm91cHMsIFVQQl9DVFlQRV9DT05TVFBUUik7CisgIGMtPmFsbG93X2ppdF8gPSB0cnVlOworfQorCit2b2lkIHVwYl9wYmNvZGVjYWNoZV91bmluaXQodXBiX3BiY29kZWNhY2hlICpjKSB7CisgIHVwYl9pbnR0YWJsZV9pdGVyIGk7CisgIHVwYl9pbnR0YWJsZV9iZWdpbigmaSwgJmMtPmdyb3Vwcyk7CisgIGZvcig7ICF1cGJfaW50dGFibGVfZG9uZSgmaSk7IHVwYl9pbnR0YWJsZV9uZXh0KCZpKSkgeworICAgIGNvbnN0IG1ncm91cCAqZ3JvdXAgPSB1cGJfdmFsdWVfZ2V0Y29uc3RwdHIodXBiX2ludHRhYmxlX2l0ZXJfdmFsdWUoJmkpKTsKKyAgICB1cGJfcmVmY291bnRlZF91bnJlZihVUEJfVVBDQVNUKGdyb3VwKSwgYyk7CisgIH0KKyAgdXBiX2ludHRhYmxlX3VuaW5pdCgmYy0+Z3JvdXBzKTsKK30KKworYm9vbCB1cGJfcGJjb2RlY2FjaGVfYWxsb3dqaXQoY29uc3QgdXBiX3BiY29kZWNhY2hlICpjKSB7CisgIHJldHVybiBjLT5hbGxvd19qaXRfOworfQorCitib29sIHVwYl9wYmNvZGVjYWNoZV9zZXRhbGxvd2ppdCh1cGJfcGJjb2RlY2FjaGUgKmMsIGJvb2wgYWxsb3cpIHsKKyAgaWYgKHVwYl9pbnR0YWJsZV9jb3VudCgmYy0+Z3JvdXBzKSA+IDApCisgICAgcmV0dXJuIGZhbHNlOworICBjLT5hbGxvd19qaXRfID0gYWxsb3c7CisgIHJldHVybiB0cnVlOworfQorCitjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICp1cGJfcGJjb2RlY2FjaGVfZ2V0ZGVjb2Rlcm1ldGhvZCgKKyAgICB1cGJfcGJjb2RlY2FjaGUgKmMsIGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2RvcHRzICpvcHRzKSB7CisgIC8vIFJpZ2h0IG5vdyB3ZSBidWlsZCBhIG5ldyBEZWNvZGVyTWV0aG9kIGV2ZXJ5IHRpbWUuCisgIC8vIFRPRE8oaGFiZXJtYW4pOiBwcm9wZXJseSBjYWNoZSBtZXRob2RzIGJ5IHRoZWlyIHRydWUga2V5LgorICBjb25zdCBtZ3JvdXAgKmcgPSBtZ3JvdXBfbmV3KG9wdHMtPmhhbmRsZXJzLCBjLT5hbGxvd19qaXRfLCBvcHRzLT5sYXp5LCBjKTsKKyAgdXBiX2ludHRhYmxlX3B1c2goJmMtPmdyb3VwcywgdXBiX3ZhbHVlX2NvbnN0cHRyKGcpKTsKKworICB1cGJfdmFsdWUgdjsKKyAgYm9vbCBvayA9IHVwYl9pbnR0YWJsZV9sb29rdXBwdHIoJmctPm1ldGhvZHMsIG9wdHMtPmhhbmRsZXJzLCAmdik7CisgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7CisgIHJldHVybiB1cGJfdmFsdWVfZ2V0cHRyKHYpOworfQorCisKKy8qIHVwYl9wYmRlY29kZXJtZXRob2RvcHRzICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3ZvaWQgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfaW5pdCh1cGJfcGJkZWNvZGVybWV0aG9kb3B0cyAqb3B0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfaGFuZGxlcnMgKmgpIHsKKyAgb3B0cy0+aGFuZGxlcnMgPSBoOworICBvcHRzLT5sYXp5ID0gZmFsc2U7Cit9CisKK3ZvaWQgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfc2V0bGF6eSh1cGJfcGJkZWNvZGVybWV0aG9kb3B0cyAqb3B0cywgYm9vbCBsYXp5KSB7CisgIG9wdHMtPmxhenkgPSBsYXp5OworfQorLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAwOC0yMDEzIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBUaGlzIGZpbGUgaW1wbGVtZW50cyBhIFZNIGZvciB0aGUgaW50ZXJwcmV0ZWQgKGJ5dGVjb2RlKSBkZWNvZGVyLgorICoKKyAqIEJ5dGVjb2RlIG11c3QgcHJldmlvdXNseSBoYXZlIGJlZW4gZ2VuZXJhdGVkIHVzaW5nIHRoZSBieXRlY29kZSBjb21waWxlciBpbgorICogY29tcGlsZV9kZWNvZGVyLmMuICBUaGlzIGRlY29kZXIgdGhlbiB3YWxrcyB0aHJvdWdoIHRoZSBieXRlY29kZSBvcC1ieS1vcCB0bworICogcGFyc2UgdGhlIGlucHV0LgorICoKKyAqIERlY29kaW5nIGlzIGZ1bGx5IHJlc3VtYWJsZTsgd2UganVzdCBrZWVwIGEgcG9pbnRlciB0byB0aGUgY3VycmVudCBieXRlY29kZQorICogaW5zdHJ1Y3Rpb24gYW5kIHJlc3VtZSBmcm9tIHRoZXJlLiAgQSBmYWlyIGFtb3VudCBvZiB0aGUgbG9naWMgaGVyZSBpcyB0bworICogaGFuZGxlIHRoZSBmYWN0IHRoYXQgdmFsdWVzIGNhbiBzcGFuIGJ1ZmZlciBzZWFtcyBhbmQgd2UgaGF2ZSB0byBiZSBhYmxlIHRvCisgKiBiZSBjYXBhYmxlIG9mIHN1c3BlbmRpbmcvcmVzdW1pbmcgZnJvbSBhbnkgYnl0ZSBpbiB0aGUgc3RyZWFtLiAgVGhpcworICogc29tZXRpbWVzIHJlcXVpcmVzIGtlZXBpbmcgYSBmZXcgdHJhaWxpbmcgYnl0ZXMgZnJvbSB0aGUgbGFzdCBidWZmZXIgYXJvdW5kCisgKiBpbiB0aGUgInJlc2lkdWFsIiBidWZmZXIuCisgKi8KKworI2luY2x1ZGUgPGludHR5cGVzLmg+CisjaW5jbHVkZSA8c2V0am1wLmg+CisjaW5jbHVkZSA8c3RkYXJnLmg+CisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisKKyNpZmRlZiBVUEJfRFVNUF9CWVRFQ09ERQorI2luY2x1ZGUgPHN0ZGlvLmg+CisjZW5kaWYKKworI2RlZmluZSBDSEVDS19TVVNQRU5EKHgpIGlmICghKHgpKSByZXR1cm4gdXBiX3BiZGVjb2Rlcl9zdXNwZW5kKGQpOworCisvLyBFcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBzaGFyZWQgYmV0d2VlbiB0aGUgYnl0ZWNvZGUgYW5kIEpJVCBkZWNvZGVycy4KK2NvbnN0IGNoYXIgKmtQYkRlY29kZXJTdGFja092ZXJmbG93ID0gIk5lc3RpbmcgdG9vIGRlZXAuIjsKKworLy8gRXJyb3IgbWVzc2FnZXMgc2hhcmVkIHdpdGhpbiB0aGlzIGZpbGUuCitzdGF0aWMgY29uc3QgY2hhciAqa1VudGVybWluYXRlZFZhcmludCA9ICJVbnRlcm1pbmF0ZWQgdmFyaW50LiI7CisKKy8qIHVwYl9wYmRlY29kZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3N0YXRpYyBvcGNvZGUgaGFsdCA9IE9QX0hBTFQ7CisKKy8vIFdoZXRoZXIgYW4gb3AgY29uc3VtZXMgYW55IG9mIHRoZSBpbnB1dCBidWZmZXIuCitzdGF0aWMgYm9vbCBjb25zdW1lc19pbnB1dChvcGNvZGUgb3ApIHsKKyAgc3dpdGNoIChvcCkgeworICAgIGNhc2UgT1BfU0VURElTUEFUQ0g6CisgICAgY2FzZSBPUF9TVEFSVE1TRzoKKyAgICBjYXNlIE9QX0VORE1TRzoKKyAgICBjYXNlIE9QX1NUQVJUU0VROgorICAgIGNhc2UgT1BfRU5EU0VROgorICAgIGNhc2UgT1BfU1RBUlRTVUJNU0c6CisgICAgY2FzZSBPUF9FTkRTVUJNU0c6CisgICAgY2FzZSBPUF9TVEFSVFNUUjoKKyAgICBjYXNlIE9QX0VORFNUUjoKKyAgICBjYXNlIE9QX1BVU0hUQUdERUxJTToKKyAgICBjYXNlIE9QX1BPUDoKKyAgICBjYXNlIE9QX1NFVERFTElNOgorICAgIGNhc2UgT1BfU0VUQklHR1JPVVBOVU06CisgICAgY2FzZSBPUF9DSEVDS0RFTElNOgorICAgIGNhc2UgT1BfQ0FMTDoKKyAgICBjYXNlIE9QX1JFVDoKKyAgICBjYXNlIE9QX0JSQU5DSDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKworc3RhdGljIGJvb2wgaW5fcmVzaWR1YWxfYnVmKGNvbnN0IHVwYl9wYmRlY29kZXIgKmQsIGNvbnN0IGNoYXIgKnApOworCisvLyBJdCdzIHVuZm9ydHVuYXRlIHRoYXQgd2UgaGF2ZSB0byBtaWNyby1tYW5hZ2UgdGhlIGNvbXBpbGVyIHRoaXMgd2F5LAorLy8gZXNwZWNpYWxseSBzaW5jZSB0aGlzIHR1bmluZyBpcyBuZWNlc3NhcmlseSBzcGVjaWZpYyB0byBvbmUgaGFyZHdhcmUKKy8vIGNvbmZpZ3VyYXRpb24uICBCdXQgZW1wZXJpY2FsbHkgb24gYSBDb3JlIGk3LCBwZXJmb3JtYW5jZSBpbmNyZWFzZXMgMzAtNTAlCisvLyB3aXRoIHRoZXNlIGFubm90YXRpb25zLiAgRXZlcnkgaW5zdGFuY2Ugd2hlcmUgdGhlc2UgYXBwZWFyLCBnY2MgNC4yLjEgbWFkZQorLy8gdGhlIHdyb25nIGRlY2lzaW9uIGFuZCBkZWdyYWRlZCBwZXJmb3JtYW5jZSBpbiBiZW5jaG1hcmtzLgorI2RlZmluZSBGT1JDRUlOTElORSBzdGF0aWMgaW5saW5lIF9fYXR0cmlidXRlX18oKGFsd2F5c19pbmxpbmUpKQorI2RlZmluZSBOT0lOTElORSBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCisKK3N0YXRpYyB2b2lkIHNldGVycih1cGJfcGJkZWNvZGVyICpkLCBjb25zdCBjaGFyICptc2cpIHsKKyAgLy8gVE9ETyhoYWJlcm1hbik6IGVuY2Fwc3VsYXRlIHRoaXMgYWNjZXNzIHRvIHBpcGVsaW5lLT5zdGF0dXMsIGJ1dCBub3Qgc3VyZQorICAvLyBleGFjdGx5IHdoYXQgdGhhdCBpbnRlcmZhY2Ugc2hvdWxkIGxvb2sgbGlrZS4KKyAgdXBiX3N0YXR1c19zZXRlcnJtc2coZC0+c3RhdHVzLCBtc2cpOworfQorCit2b2lkIHVwYl9wYmRlY29kZXJfc2V0ZXJyKHVwYl9wYmRlY29kZXIgKmQsIGNvbnN0IGNoYXIgKm1zZykgeworICBzZXRlcnIoZCwgbXNnKTsKK30KKworCisvKiBCdWZmZXJpbmcgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvLyBXZSBvcGVyYXRlIG9uIG9uZSBidWZmZXIgYXQgYSB0aW1lLCB3aGljaCBpcyBlaXRoZXIgdGhlIHVzZXIncyBidWZmZXIgcGFzc2VkCisvLyB0byBvdXIgImRlY29kZSIgY2FsbGJhY2sgb3Igc29tZSByZXNpZHVhbCBieXRlcyBmcm9tIHRoZSBwcmV2aW91cyBidWZmZXIuCisKKy8vIEhvdyBtYW55IGJ5dGVzIGNhbiBiZSBzYWZlbHkgcmVhZCBmcm9tIGQtPnB0ciB3aXRob3V0IHJlYWRpbmcgcGFzdCBlbmQtb2YtYnVmCisvLyBvciBwYXN0IHRoZSBjdXJyZW50IGRlbGltaXRlZCBlbmQuCitzdGF0aWMgc2l6ZV90IGN1cmJ1ZmxlZnQoY29uc3QgdXBiX3BiZGVjb2RlciAqZCkgeworICBhc3NlcnQoZC0+ZGF0YV9lbmQgPj0gZC0+cHRyKTsKKyAgcmV0dXJuIGQtPmRhdGFfZW5kIC0gZC0+cHRyOworfQorCisvLyBPdmVyYWxsIHN0cmVhbSBvZmZzZXQgb2YgZC0+cHRyLgordWludDY0X3Qgb2Zmc2V0KGNvbnN0IHVwYl9wYmRlY29kZXIgKmQpIHsKKyAgcmV0dXJuIGQtPmJ1ZnN0YXJ0X29mcyArIChkLT5wdHIgLSBkLT5idWYpOworfQorCisvLyBBZHZhbmNlcyBkLT5wdHIuCitzdGF0aWMgdm9pZCBhZHZhbmNlKHVwYl9wYmRlY29kZXIgKmQsIHNpemVfdCBsZW4pIHsKKyAgYXNzZXJ0KGN1cmJ1ZmxlZnQoZCkgPj0gbGVuKTsKKyAgZC0+cHRyICs9IGxlbjsKK30KKworc3RhdGljIGJvb2wgaW5fYnVmKGNvbnN0IGNoYXIgKnAsIGNvbnN0IGNoYXIgKmJ1ZiwgY29uc3QgY2hhciAqZW5kKSB7CisgIHJldHVybiBwID49IGJ1ZiAmJiBwIDw9IGVuZDsKK30KKworc3RhdGljIGJvb2wgaW5fcmVzaWR1YWxfYnVmKGNvbnN0IHVwYl9wYmRlY29kZXIgKmQsIGNvbnN0IGNoYXIgKnApIHsKKyAgcmV0dXJuIGluX2J1ZihwLCBkLT5yZXNpZHVhbCwgZC0+cmVzaWR1YWxfZW5kKTsKK30KKworLy8gQ2FsY3VsYXRlcyB0aGUgZGVsaW1fZW5kIHZhbHVlLCB3aGljaCBpcyBhZmZlY3RlZCBieSBib3RoIHRoZSBjdXJyZW50IGJ1ZmZlcgorLy8gYW5kIHRoZSBwYXJzaW5nIHN0YWNrLCBzbyBtdXN0IGJlIGNhbGxlZCB3aGVuZXZlciBlaXRoZXIgaXMgdXBkYXRlZC4KK3N0YXRpYyB2b2lkIHNldF9kZWxpbV9lbmQodXBiX3BiZGVjb2RlciAqZCkgeworICBzaXplX3QgZGVsaW1fb2ZzID0gZC0+dG9wLT5lbmRfb2ZzIC0gZC0+YnVmc3RhcnRfb2ZzOworICBpZiAoZGVsaW1fb2ZzIDw9IChkLT5lbmQgLSBkLT5idWYpKSB7CisgICAgZC0+ZGVsaW1fZW5kID0gZC0+YnVmICsgZGVsaW1fb2ZzOworICAgIGQtPmRhdGFfZW5kID0gZC0+ZGVsaW1fZW5kOworICB9IGVsc2UgeworICAgIGQtPmRhdGFfZW5kID0gZC0+ZW5kOworICAgIGQtPmRlbGltX2VuZCA9IE5VTEw7CisgIH0KK30KKworc3RhdGljIHZvaWQgc3dpdGNodG9idWYodXBiX3BiZGVjb2RlciAqZCwgY29uc3QgY2hhciAqYnVmLCBjb25zdCBjaGFyICplbmQpIHsKKyAgZC0+cHRyID0gYnVmOworICBkLT5idWYgPSBidWY7CisgIGQtPmVuZCA9IGVuZDsKKyAgc2V0X2RlbGltX2VuZChkKTsKK30KKworc3RhdGljIHZvaWQgYWR2YW5jZXRvYnVmKHVwYl9wYmRlY29kZXIgKmQsIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IGxlbikgeworICBhc3NlcnQoY3VyYnVmbGVmdChkKSA9PSAwKTsKKyAgZC0+YnVmc3RhcnRfb2ZzICs9IChkLT5lbmQgLSBkLT5idWYpOworICBzd2l0Y2h0b2J1ZihkLCBidWYsIGJ1ZiArIGxlbik7Cit9CisKK3N0YXRpYyB2b2lkIGNoZWNrcG9pbnQodXBiX3BiZGVjb2RlciAqZCkgeworICAvLyBUaGUgYXNzZXJ0aW9uIGhlcmUgaXMgaW4gdGhlIGludGVyZXN0cyBvZiBlZmZpY2llbmN5LCBub3QgY29ycmVjdG5lc3MuCisgIC8vIFdlIGFyZSB0cnlpbmcgdG8gZW5zdXJlIHRoYXQgd2UgZG9uJ3QgY2hlY2twb2ludCgpIG1vcmUgb2Z0ZW4gdGhhbgorICAvLyBuZWNlc3NhcnkuCisgIGFzc2VydChkLT5jaGVja3BvaW50ICE9IGQtPnB0cik7CisgIGQtPmNoZWNrcG9pbnQgPSBkLT5wdHI7Cit9CisKKy8vIFJlc3VtZXMgdGhlIGRlY29kZXIgZnJvbSBhbiBpbml0aWFsIHN0YXRlIG9yIGZyb20gYSBwcmV2aW91cyBzdXNwZW5kLgoraW50MzJfdCB1cGJfcGJkZWNvZGVyX3Jlc3VtZSh1cGJfcGJkZWNvZGVyICpkLCB2b2lkICpwLCBjb25zdCBjaGFyICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplLCBjb25zdCB1cGJfYnVmaGFuZGxlICpoYW5kbGUpIHsKKyAgVVBCX1VOVVNFRChwKTsgIC8vIFVzZWxlc3M7IGp1c3QgZm9yIHRoZSBiZW5lZml0IG9mIHRoZSBKSVQuCisgIGQtPmJ1Zl9wYXJhbSA9IGJ1ZjsKKyAgZC0+c2l6ZV9wYXJhbSA9IHNpemU7CisgIGQtPmhhbmRsZSA9IGhhbmRsZTsKKyAgaWYgKGQtPnJlc2lkdWFsX2VuZCA+IGQtPnJlc2lkdWFsKSB7CisgICAgLy8gV2UgaGF2ZSByZXNpZHVhbCBieXRlcyBmcm9tIHRoZSBsYXN0IGJ1ZmZlci4KKyAgICBhc3NlcnQoZC0+cHRyID09IGQtPnJlc2lkdWFsKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2h0b2J1ZihkLCBidWYsIGJ1ZiArIHNpemUpOworICB9CisgIGQtPmNoZWNrcG9pbnQgPSBkLT5wdHI7CisgIGlmIChkLT50b3AtPmdyb3VwbnVtIDwgMCkgeworICAgIENIRUNLX1JFVFVSTih1cGJfcGJkZWNvZGVyX3NraXB1bmtub3duKGQsIC0xLCAwKSk7CisgICAgZC0+Y2hlY2twb2ludCA9IGQtPnB0cjsKKyAgfQorICByZXR1cm4gREVDT0RFX09LOworfQorCisvLyBTdXNwZW5kcyB0aGUgZGVjb2RlciBhdCB0aGUgbGFzdCBjaGVja3BvaW50LCB3aXRob3V0IHNhdmluZyBhbnkgcmVzaWR1YWwKKy8vIGJ5dGVzLiAgSWYgdGhlcmUgYXJlIGFueSB1bmNvbnN1bWVkIGJ5dGVzLCByZXR1cm5zIGEgc2hvcnQgYnl0ZSBjb3VudC4KK3NpemVfdCB1cGJfcGJkZWNvZGVyX3N1c3BlbmQodXBiX3BiZGVjb2RlciAqZCkgeworICBkLT5wYyA9IGQtPmxhc3Q7CisgIGlmIChkLT5jaGVja3BvaW50ID09IGQtPnJlc2lkdWFsKSB7CisgICAgLy8gQ2hlY2twb2ludCB3YXMgaW4gcmVzaWR1YWwgYnVmOyBubyB1c2VyIGJ5dGVzIHdlcmUgY29uc3VtZWQuCisgICAgZC0+cHRyID0gZC0+cmVzaWR1YWw7CisgICAgcmV0dXJuIDA7CisgIH0gZWxzZSB7CisgICAgYXNzZXJ0KCFpbl9yZXNpZHVhbF9idWYoZCwgZC0+Y2hlY2twb2ludCkpOworICAgIGFzc2VydChkLT5idWYgPT0gZC0+YnVmX3BhcmFtKTsKKyAgICBzaXplX3QgY29uc3VtZWQgPSBkLT5jaGVja3BvaW50IC0gZC0+YnVmOworICAgIGQtPmJ1ZnN0YXJ0X29mcyArPSBjb25zdW1lZDsKKyAgICBkLT5yZXNpZHVhbF9lbmQgPSBkLT5yZXNpZHVhbDsKKyAgICBzd2l0Y2h0b2J1ZihkLCBkLT5yZXNpZHVhbCwgZC0+cmVzaWR1YWxfZW5kKTsKKyAgICByZXR1cm4gY29uc3VtZWQ7CisgIH0KK30KKworLy8gU3VzcGVuZHMgdGhlIGRlY29kZXIgYXQgdGhlIGxhc3QgY2hlY2twb2ludCwgYW5kIHNhdmVzIGFueSB1bmNvbnN1bWVkCisvLyBieXRlcyBpbiBvdXIgcmVzaWR1YWwgYnVmZmVyLiAgVGhpcyBpcyBuZWNlc3NhcnkgaWYgd2UgbmVlZCBtb3JlIHVzZXIKKy8vIGJ5dGVzIHRvIGZvcm0gYSBjb21wbGV0ZSB2YWx1ZSwgd2hpY2ggbWlnaHQgbm90IGJlIGNvbnRpZ3VvdXMgaW4gdGhlCisvLyB1c2VyJ3MgYnVmZmVycy4gIEFsd2F5cyBjb25zdW1lcyBhbGwgdXNlciBieXRlcy4KK3N0YXRpYyBzaXplX3Qgc3VzcGVuZF9zYXZlKHVwYl9wYmRlY29kZXIgKmQpIHsKKyAgLy8gV2UgaGl0IGVuZC1vZi1idWZmZXIgYmVmb3JlIHdlIGNvdWxkIHBhcnNlIGEgZnVsbCB2YWx1ZS4KKyAgLy8gU2F2ZSBhbnkgdW5jb25zdW1lZCBieXRlcyAoaWYgYW55KSB0byB0aGUgcmVzaWR1YWwgYnVmZmVyLgorICBkLT5wYyA9IGQtPmxhc3Q7CisKKyAgaWYgKGQtPmNoZWNrcG9pbnQgPT0gZC0+cmVzaWR1YWwpIHsKKyAgICAvLyBDaGVja3BvaW50IHdhcyBpbiByZXNpZHVhbCBidWY7IGFwcGVuZCB1c2VyIGJ5dGUocykgdG8gcmVzaWR1YWwgYnVmLgorICAgIGFzc2VydCgoZC0+cmVzaWR1YWxfZW5kIC0gZC0+cmVzaWR1YWwpICsgZC0+c2l6ZV9wYXJhbSA8PQorICAgICAgICAgICBzaXplb2YoZC0+cmVzaWR1YWwpKTsKKyAgICBpZiAoIWluX3Jlc2lkdWFsX2J1ZihkLCBkLT5wdHIpKSB7CisgICAgICBkLT5idWZzdGFydF9vZnMgLT0gKGQtPnJlc2lkdWFsX2VuZCAtIGQtPnJlc2lkdWFsKTsKKyAgICB9CisgICAgbWVtY3B5KGQtPnJlc2lkdWFsX2VuZCwgZC0+YnVmX3BhcmFtLCBkLT5zaXplX3BhcmFtKTsKKyAgICBkLT5yZXNpZHVhbF9lbmQgKz0gZC0+c2l6ZV9wYXJhbTsKKyAgfSBlbHNlIHsKKyAgICAvLyBDaGVja3BvaW50IHdhcyBpbiB1c2VyIGJ1Zjsgb2xkIHJlc2lkdWFsIGJ5dGVzIG5vdCBuZWVkZWQuCisgICAgYXNzZXJ0KCFpbl9yZXNpZHVhbF9idWYoZCwgZC0+Y2hlY2twb2ludCkpOworICAgIGQtPnB0ciA9IGQtPmNoZWNrcG9pbnQ7CisgICAgc2l6ZV90IHNhdmUgPSBjdXJidWZsZWZ0KGQpOworICAgIGFzc2VydChzYXZlIDw9IHNpemVvZihkLT5yZXNpZHVhbCkpOworICAgIG1lbWNweShkLT5yZXNpZHVhbCwgZC0+cHRyLCBzYXZlKTsKKyAgICBkLT5yZXNpZHVhbF9lbmQgPSBkLT5yZXNpZHVhbCArIHNhdmU7CisgICAgZC0+YnVmc3RhcnRfb2ZzID0gb2Zmc2V0KGQpOworICB9CisKKyAgc3dpdGNodG9idWYoZCwgZC0+cmVzaWR1YWwsIGQtPnJlc2lkdWFsX2VuZCk7CisgIHJldHVybiBkLT5zaXplX3BhcmFtOworfQorCisvLyBTa2lwcyAiYnl0ZXMiIGJ5dGVzIGluIHRoZSBzdHJlYW0sIHdoaWNoIG1heSBiZSBtb3JlIHRoYW4gYXZhaWxhYmxlLiAgSWYgd2UKKy8vIHNraXAgbW9yZSBieXRlcyB0aGFuIGFyZSBhdmFpbGFibGUsIHdlIHJldHVybiBhIGxvbmcgcmVhZCBjb3VudCB0byB0aGUgY2FsbGVyCisvLyBpbmRpY2F0aW5nIGhvdyBtYW55IGJ5dGVzIHRoZSBjYWxsZXIgc2hvdWxkIHNraXAgYmVmb3JlIHBhc3NpbmcgYSBuZXcgYnVmZmVyLgorc3RhdGljIGludDMyX3Qgc2tpcCh1cGJfcGJkZWNvZGVyICpkLCBzaXplX3QgYnl0ZXMpIHsKKyAgYXNzZXJ0KCFpbl9yZXNpZHVhbF9idWYoZCwgZC0+cHRyKSB8fCBkLT5zaXplX3BhcmFtID09IDApOworICBpZiAoY3VyYnVmbGVmdChkKSA+PSBieXRlcykgeworICAgIC8vIFNraXBwZWQgZGF0YSBpcyBhbGwgaW4gY3VycmVudCBidWZmZXIuCisgICAgYWR2YW5jZShkLCBieXRlcyk7CisgICAgcmV0dXJuIERFQ09ERV9PSzsKKyAgfSBlbHNlIHsKKyAgICAvLyBTa2lwcGVkIGRhdGEgZXh0ZW5kcyBiZXlvbmQgY3VycmVudGx5IGF2YWlsYWJsZSBidWZmZXJzLgorICAgIGQtPnBjID0gZC0+bGFzdDsKKyAgICBzaXplX3Qgc2tpcCA9IGJ5dGVzIC0gY3VyYnVmbGVmdChkKTsKKyAgICBkLT5idWZzdGFydF9vZnMgKz0gKGQtPmVuZCAtIGQtPmJ1ZikgKyBza2lwOworICAgIGQtPnJlc2lkdWFsX2VuZCA9IGQtPnJlc2lkdWFsOworICAgIHN3aXRjaHRvYnVmKGQsIGQtPnJlc2lkdWFsLCBkLT5yZXNpZHVhbF9lbmQpOworICAgIHJldHVybiBkLT5zaXplX3BhcmFtICsgc2tpcDsKKyAgfQorfQorCisvLyBDb3BpZXMgdGhlIG5leHQgImJ5dGVzIiBieXRlcyBpbnRvICJidWYiIGFuZCBhZHZhbmNlcyB0aGUgc3RyZWFtLgorLy8gUmVxdWlyZXMgdGhhdCB0aGlzIG1hbnkgYnl0ZXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBidWZmZXIuCitGT1JDRUlOTElORSB2b2lkIGNvbnN1bWVieXRlcyh1cGJfcGJkZWNvZGVyICpkLCB2b2lkICpidWYsIHNpemVfdCBieXRlcykgeworICBhc3NlcnQoYnl0ZXMgPD0gY3VyYnVmbGVmdChkKSk7CisgIG1lbWNweShidWYsIGQtPnB0ciwgYnl0ZXMpOworICBhZHZhbmNlKGQsIGJ5dGVzKTsKK30KKworLy8gU2xvdyBwYXRoIGZvciBnZXR0aW5nIHRoZSBuZXh0ICJieXRlcyIgYnl0ZXMsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGV5IGFyZQorLy8gYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGJ1ZmZlciBvciBub3QuICBSZXR1cm5zIGEgc3RhdHVzIGNvZGUgYXMgZGVzY3JpYmVkCisvLyBpbiBkZWNvZGVyLmludC5oLgorc3RhdGljIE5PSU5MSU5FIGludDMyX3QgZ2V0Ynl0ZXNfc2xvdyh1cGJfcGJkZWNvZGVyICpkLCB2b2lkICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBieXRlcykgeworICBjb25zdCBzaXplX3QgYXZhaWwgPSBjdXJidWZsZWZ0KGQpOworICBjb25zdW1lYnl0ZXMoZCwgYnVmLCBhdmFpbCk7CisgIGJ5dGVzIC09IGF2YWlsOworICBhc3NlcnQoYnl0ZXMgPiAwKTsKKyAgaWYgKGluX3Jlc2lkdWFsX2J1ZihkLCBkLT5wdHIpKSB7CisgICAgYWR2YW5jZXRvYnVmKGQsIGQtPmJ1Zl9wYXJhbSwgZC0+c2l6ZV9wYXJhbSk7CisgIH0KKyAgaWYgKGN1cmJ1ZmxlZnQoZCkgPj0gYnl0ZXMpIHsKKyAgICBjb25zdW1lYnl0ZXMoZCwgYnVmICsgYXZhaWwsIGJ5dGVzKTsKKyAgICByZXR1cm4gREVDT0RFX09LOworICB9IGVsc2UgaWYgKGQtPmRhdGFfZW5kID09IGQtPmRlbGltX2VuZCkgeworICAgIHNldGVycihkLCAiU3VibWVzc2FnZSBlbmRlZCBpbiB0aGUgbWlkZGxlIG9mIGEgdmFsdWUgb3IgZ3JvdXAiKTsKKyAgICByZXR1cm4gdXBiX3BiZGVjb2Rlcl9zdXNwZW5kKGQpOworICB9IGVsc2UgeworICAgIHJldHVybiBzdXNwZW5kX3NhdmUoZCk7CisgIH0KK30KKworLy8gR2V0cyB0aGUgbmV4dCAiYnl0ZXMiIGJ5dGVzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhleSBhcmUgYXZhaWxhYmxlIGluIHRoZQorLy8gY3VycmVudCBidWZmZXIgb3Igbm90LiAgUmV0dXJucyBhIHN0YXR1cyBjb2RlIGFzIGRlc2NyaWJlZCBpbiBkZWNvZGVyLmludC5oLgorRk9SQ0VJTkxJTkUgaW50MzJfdCBnZXRieXRlcyh1cGJfcGJkZWNvZGVyICpkLCB2b2lkICpidWYsIHNpemVfdCBieXRlcykgeworICBpZiAoY3VyYnVmbGVmdChkKSA+PSBieXRlcykgeworICAgIC8vIEJ1ZmZlciBoYXMgZW5vdWdoIGRhdGEgdG8gc2F0aXNmeS4KKyAgICBjb25zdW1lYnl0ZXMoZCwgYnVmLCBieXRlcyk7CisgICAgcmV0dXJuIERFQ09ERV9PSzsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZ2V0Ynl0ZXNfc2xvdyhkLCBidWYsIGJ5dGVzKTsKKyAgfQorfQorCitzdGF0aWMgTk9JTkxJTkUgc2l6ZV90IHBlZWtieXRlc19zbG93KHVwYl9wYmRlY29kZXIgKmQsIHZvaWQgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGJ5dGVzKSB7CisgIHNpemVfdCByZXQgPSBjdXJidWZsZWZ0KGQpOworICBtZW1jcHkoYnVmLCBkLT5wdHIsIHJldCk7CisgIGlmIChpbl9yZXNpZHVhbF9idWYoZCwgZC0+cHRyKSkgeworICAgIHNpemVfdCBjb3B5ID0gVVBCX01JTihieXRlcyAtIHJldCwgZC0+c2l6ZV9wYXJhbSk7CisgICAgbWVtY3B5KGJ1ZiArIHJldCwgZC0+YnVmX3BhcmFtLCBjb3B5KTsKKyAgICByZXQgKz0gY29weTsKKyAgfQorICByZXR1cm4gcmV0OworfQorCitGT1JDRUlOTElORSBzaXplX3QgcGVla2J5dGVzKHVwYl9wYmRlY29kZXIgKmQsIHZvaWQgKmJ1Ziwgc2l6ZV90IGJ5dGVzKSB7CisgIGlmIChjdXJidWZsZWZ0KGQpID49IGJ5dGVzKSB7CisgICAgbWVtY3B5KGJ1ZiwgZC0+cHRyLCBieXRlcyk7CisgICAgcmV0dXJuIGJ5dGVzOworICB9IGVsc2UgeworICAgIHJldHVybiBwZWVrYnl0ZXNfc2xvdyhkLCBidWYsIGJ5dGVzKTsKKyAgfQorfQorCisKKy8qIERlY29kaW5nIG9mIHdpcmUgdHlwZXMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIFNsb3cgcGF0aCBmb3IgZGVjb2RpbmcgYSB2YXJpbnQgZnJvbSB0aGUgY3VycmVudCBidWZmZXIgcG9zaXRpb24uCisvLyBSZXR1cm5zIGEgc3RhdHVzIGNvZGUgYXMgZGVzY3JpYmVkIGluIGRlY29kZXIuaW50LmguCitOT0lOTElORSBpbnQzMl90IHVwYl9wYmRlY29kZXJfZGVjb2RlX3ZhcmludF9zbG93KHVwYl9wYmRlY29kZXIgKmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NF90ICp1NjQpIHsKKyAgKnU2NCA9IDA7CisgIHVpbnQ4X3QgYnl0ZSA9IDB4ODA7CisgIGludCBiaXRwb3M7CisgIGZvcihiaXRwb3MgPSAwOyBiaXRwb3MgPCA3MCAmJiAoYnl0ZSAmIDB4ODApOyBiaXRwb3MgKz0gNykgeworICAgIGludDMyX3QgcmV0ID0gZ2V0Ynl0ZXMoZCwgJmJ5dGUsIDEpOworICAgIGlmIChyZXQgPj0gMCkgcmV0dXJuIHJldDsKKyAgICAqdTY0IHw9ICh1aW50NjRfdCkoYnl0ZSAmIDB4N0YpIDw8IGJpdHBvczsKKyAgfQorICBpZihiaXRwb3MgPT0gNzAgJiYgKGJ5dGUgJiAweDgwKSkgeworICAgIHNldGVycihkLCBrVW50ZXJtaW5hdGVkVmFyaW50KTsKKyAgICByZXR1cm4gdXBiX3BiZGVjb2Rlcl9zdXNwZW5kKGQpOworICB9CisgIHJldHVybiBERUNPREVfT0s7Cit9CisKKy8vIERlY29kZXMgYSB2YXJpbnQgZnJvbSB0aGUgY3VycmVudCBidWZmZXIgcG9zaXRpb24uCisvLyBSZXR1cm5zIGEgc3RhdHVzIGNvZGUgYXMgZGVzY3JpYmVkIGluIGRlY29kZXIuaW50LmguCitGT1JDRUlOTElORSBpbnQzMl90IGRlY29kZV92YXJpbnQodXBiX3BiZGVjb2RlciAqZCwgdWludDY0X3QgKnU2NCkgeworICBpZiAoY3VyYnVmbGVmdChkKSA+IDAgJiYgISgqZC0+cHRyICYgMHg4MCkpIHsKKyAgICAqdTY0ID0gKmQtPnB0cjsKKyAgICBhZHZhbmNlKGQsIDEpOworICAgIHJldHVybiBERUNPREVfT0s7CisgIH0gZWxzZSBpZiAoY3VyYnVmbGVmdChkKSA+PSAxMCkgeworICAgIC8vIEZhc3QgY2FzZS4KKyAgICB1cGJfZGVjb2RlcmV0IHIgPSB1cGJfdmRlY29kZV9mYXN0KGQtPnB0cik7CisgICAgaWYgKHIucCA9PSBOVUxMKSB7CisgICAgICBzZXRlcnIoZCwga1VudGVybWluYXRlZFZhcmludCk7CisgICAgICByZXR1cm4gdXBiX3BiZGVjb2Rlcl9zdXNwZW5kKGQpOworICAgIH0KKyAgICBhZHZhbmNlKGQsIHIucCAtIGQtPnB0cik7CisgICAgKnU2NCA9IHIudmFsOworICAgIHJldHVybiBERUNPREVfT0s7CisgIH0gZWxzZSB7CisgICAgLy8gU2xvdyBjYXNlIC0tIHZhcmludCBzcGFucyBidWZmZXIgc2VhbS4KKyAgICByZXR1cm4gdXBiX3BiZGVjb2Rlcl9kZWNvZGVfdmFyaW50X3Nsb3coZCwgdTY0KTsKKyAgfQorfQorCisvLyBEZWNvZGVzIGEgMzItYml0IHZhcmludCBmcm9tIHRoZSBjdXJyZW50IGJ1ZmZlciBwb3NpdGlvbi4KKy8vIFJldHVybnMgYSBzdGF0dXMgY29kZSBhcyBkZXNjcmliZWQgaW4gZGVjb2Rlci5pbnQuaC4KK0ZPUkNFSU5MSU5FIGludDMyX3QgZGVjb2RlX3YzMih1cGJfcGJkZWNvZGVyICpkLCB1aW50MzJfdCAqdTMyKSB7CisgIHVpbnQ2NF90IHU2NDsKKyAgaW50MzJfdCByZXQgPSBkZWNvZGVfdmFyaW50KGQsICZ1NjQpOworICBpZiAocmV0ID49IDApIHJldHVybiByZXQ7CisgIGlmICh1NjQgPiBVSU5UMzJfTUFYKSB7CisgICAgc2V0ZXJyKGQsICJVbnRlcm1pbmF0ZWQgMzItYml0IHZhcmludCIpOworICAgIC8vIFRPRE8oaGFiZXJtYW4pIGd1YXJhbnRlZSB0aGF0IHRoaXMgZnVuY3Rpb24gcmV0dXJuIGlzID49IDAgc29tZWhvdywKKyAgICAvLyBzbyB3ZSBrbm93IHRoaXMgcGF0aCB3aWxsIGFsd2F5cyBiZSB0cmVhdGVkIGFzIGVycm9yIGJ5IG91ciBjYWxsZXIuCisgICAgLy8gUmlnaHQgbm93IHRoZSBzaXplX3QgLT4gaW50MzJfdCBjYW4gb3ZlcmZsb3cgYW5kIHByb2R1Y2UgbmVnYXRpdmUgdmFsdWVzLgorICAgICp1MzIgPSAwOworICAgIHJldHVybiB1cGJfcGJkZWNvZGVyX3N1c3BlbmQoZCk7CisgIH0KKyAgKnUzMiA9IHU2NDsKKyAgcmV0dXJuIERFQ09ERV9PSzsKK30KKworLy8gRGVjb2RlcyBhIGZpeGVkMzIgZnJvbSB0aGUgY3VycmVudCBidWZmZXIgcG9zaXRpb24uCisvLyBSZXR1cm5zIGEgc3RhdHVzIGNvZGUgYXMgZGVzY3JpYmVkIGluIGRlY29kZXIuaW50LmguCisvLyBUT0RPOiBwcm9wZXIgYnl0ZSBzd2FwcGluZyBmb3IgYmlnLWVuZGlhbiBtYWNoaW5lcy4KK0ZPUkNFSU5MSU5FIGludDMyX3QgZGVjb2RlX2ZpeGVkMzIodXBiX3BiZGVjb2RlciAqZCwgdWludDMyX3QgKnUzMikgeworICByZXR1cm4gZ2V0Ynl0ZXMoZCwgdTMyLCA0KTsKK30KKworLy8gRGVjb2RlcyBhIGZpeGVkNjQgZnJvbSB0aGUgY3VycmVudCBidWZmZXIgcG9zaXRpb24uCisvLyBSZXR1cm5zIGEgc3RhdHVzIGNvZGUgYXMgZGVzY3JpYmVkIGluIGRlY29kZXIuaW50LmguCisvLyBUT0RPOiBwcm9wZXIgYnl0ZSBzd2FwcGluZyBmb3IgYmlnLWVuZGlhbiBtYWNoaW5lcy4KK0ZPUkNFSU5MSU5FIGludDMyX3QgZGVjb2RlX2ZpeGVkNjQodXBiX3BiZGVjb2RlciAqZCwgdWludDY0X3QgKnU2NCkgeworICByZXR1cm4gZ2V0Ynl0ZXMoZCwgdTY0LCA4KTsKK30KKworLy8gTm9uLXN0YXRpYyB2ZXJzaW9ucyBvZiB0aGUgYWJvdmUgZnVuY3Rpb25zLgorLy8gVGhlc2UgYXJlIGNhbGxlZCBieSB0aGUgSklUIGZvciBmYWxsYmFjayBwYXRocy4KK2ludDMyX3QgdXBiX3BiZGVjb2Rlcl9kZWNvZGVfZjMyKHVwYl9wYmRlY29kZXIgKmQsIHVpbnQzMl90ICp1MzIpIHsKKyAgcmV0dXJuIGRlY29kZV9maXhlZDMyKGQsIHUzMik7Cit9CisKK2ludDMyX3QgdXBiX3BiZGVjb2Rlcl9kZWNvZGVfZjY0KHVwYl9wYmRlY29kZXIgKmQsIHVpbnQ2NF90ICp1NjQpIHsKKyAgcmV0dXJuIGRlY29kZV9maXhlZDY0KGQsIHU2NCk7Cit9CisKK3N0YXRpYyBkb3VibGUgYXNfZG91YmxlKHVpbnQ2NF90IG4pIHsgZG91YmxlIGQ7IG1lbWNweSgmZCwgJm4sIDgpOyByZXR1cm4gZDsgfQorc3RhdGljIGZsb2F0ICBhc19mbG9hdCh1aW50MzJfdCBuKSAgeyBmbG9hdCAgZjsgbWVtY3B5KCZmLCAmbiwgNCk7IHJldHVybiBmOyB9CisKKy8vIFB1c2hlcyBhIGZyYW1lIG9udG8gdGhlIGRlY29kZXIgc3RhY2suCitzdGF0aWMgYm9vbCBkZWNvZGVyX3B1c2godXBiX3BiZGVjb2RlciAqZCwgdWludDY0X3QgZW5kKSB7CisgIHVwYl9wYmRlY29kZXJfZnJhbWUgKmZyID0gZC0+dG9wOworCisgIGlmIChlbmQgPiBmci0+ZW5kX29mcykgeworICAgIHNldGVycihkLCAiU3VibWVzc2FnZSBlbmQgZXh0ZW5kcyBwYXN0IGVuY2xvc2luZyBzdWJtZXNzYWdlLiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfSBlbHNlIGlmICgoZnIgKyAxKSA9PSBkLT5saW1pdCkgeworICAgIHNldGVycihkLCBrUGJEZWNvZGVyU3RhY2tPdmVyZmxvdyk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZnIrKzsKKyAgZnItPmVuZF9vZnMgPSBlbmQ7CisgIGZyLT5kaXNwYXRjaCA9IE5VTEw7CisgIGZyLT5ncm91cG51bSA9IDA7CisgIGQtPnRvcCA9IGZyOworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgcHVzaHRhZ2RlbGltKHVwYl9wYmRlY29kZXIgKmQsIHVpbnQzMl90IGFyZykgeworICAvLyBXaGlsZSB3ZSBleHBlY3QgdG8gc2VlIGFuICJlbmQiIHRhZyAoZWl0aGVyIEVOREdST1VQIG9yIGEgbm9uLXNlcXVlbmNlCisgIC8vIGZpZWxkIG51bWJlcikgcHJpb3IgdG8gaGl0dGluZyBhbnkgZW5jbG9zaW5nIHN1Ym1lc3NhZ2UgZW5kLCBwdXNoaW5nIG91cgorICAvLyBleGlzdGluZyBkZWxpbSBlbmQgcHJldmVudHMgdXMgZnJvbSBjb250aW51aW5nIHRvIHBhcnNlIHZhbHVlcyBmcm9tIGEKKyAgLy8gY29ycnVwdCBwcm90byB0aGF0IGRvZXNuJ3QgZ2l2ZSB1cyBhbiBFTkQgdGFnIGluIHRpbWUuCisgIGlmICghZGVjb2Rlcl9wdXNoKGQsIGQtPnRvcC0+ZW5kX29mcykpCisgICAgcmV0dXJuIGZhbHNlOworICBkLT50b3AtPmdyb3VwbnVtID0gYXJnOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gUG9wcyBhIGZyYW1lIGZyb20gdGhlIGRlY29kZXIgc3RhY2suCitzdGF0aWMgdm9pZCBkZWNvZGVyX3BvcCh1cGJfcGJkZWNvZGVyICpkKSB7IGQtPnRvcC0tOyB9CisKK05PSU5MSU5FIGludDMyX3QgdXBiX3BiZGVjb2Rlcl9jaGVja3RhZ19zbG93KHVwYl9wYmRlY29kZXIgKmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50NjRfdCBleHBlY3RlZCkgeworICB1aW50NjRfdCBkYXRhID0gMDsKKyAgc2l6ZV90IGJ5dGVzID0gdXBiX3ZhbHVlX3NpemUoZXhwZWN0ZWQpOworICBzaXplX3QgcmVhZCA9IHBlZWtieXRlcyhkLCAmZGF0YSwgYnl0ZXMpOworICBpZiAocmVhZCA9PSBieXRlcyAmJiBkYXRhID09IGV4cGVjdGVkKSB7CisgICAgLy8gQWR2YW5jZSBwYXN0IG1hdGNoZWQgYnl0ZXMuCisgICAgaW50MzJfdCBvayA9IGdldGJ5dGVzKGQsICZkYXRhLCByZWFkKTsKKyAgICBVUEJfQVNTRVJUX1ZBUihvaywgb2sgPCAwKTsKKyAgICByZXR1cm4gREVDT0RFX09LOworICB9IGVsc2UgaWYgKHJlYWQgPCBieXRlcyAmJiBtZW1jbXAoJmRhdGEsICZleHBlY3RlZCwgcmVhZCkgPT0gMCkgeworICAgIHJldHVybiBzdXNwZW5kX3NhdmUoZCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIERFQ09ERV9NSVNNQVRDSDsKKyAgfQorfQorCitpbnQzMl90IHVwYl9wYmRlY29kZXJfc2tpcHVua25vd24odXBiX3BiZGVjb2RlciAqZCwgaW50MzJfdCBmaWVsZG51bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90IHdpcmVfdHlwZSkgeworICBpZiAoZmllbGRudW0gPj0gMCkKKyAgICBnb3RvIGhhdmVfdGFnOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgdWludDMyX3QgdGFnOworICAgIENIRUNLX1JFVFVSTihkZWNvZGVfdjMyKGQsICZ0YWcpKTsKKyAgICB3aXJlX3R5cGUgPSB0YWcgJiAweDc7CisgICAgZmllbGRudW0gPSB0YWcgPj4gMzsKKworaGF2ZV90YWc6CisgICAgaWYgKGZpZWxkbnVtID09IDApIHsKKyAgICAgIHNldGVycihkLCAiU2F3IGludmFsaWQgZmllbGQgbnVtYmVyICgwKSIpOworICAgICAgcmV0dXJuIHVwYl9wYmRlY29kZXJfc3VzcGVuZChkKTsKKyAgICB9CisKKyAgICAvLyBUT0RPOiBkZWxpdmVyIHRvIHVua25vd24gZmllbGQgY2FsbGJhY2suCisgICAgc3dpdGNoICh3aXJlX3R5cGUpIHsKKyAgICAgIGNhc2UgVVBCX1dJUkVfVFlQRV8zMkJJVDoKKyAgICAgICAgQ0hFQ0tfUkVUVVJOKHNraXAoZCwgNCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVVBCX1dJUkVfVFlQRV82NEJJVDoKKyAgICAgICAgQ0hFQ0tfUkVUVVJOKHNraXAoZCwgOCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVVBCX1dJUkVfVFlQRV9WQVJJTlQ6IHsKKyAgICAgICAgdWludDY0X3QgdTY0OworICAgICAgICBDSEVDS19SRVRVUk4oZGVjb2RlX3ZhcmludChkLCAmdTY0KSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBVUEJfV0lSRV9UWVBFX0RFTElNSVRFRDogeworICAgICAgICB1aW50MzJfdCBsZW47CisgICAgICAgIENIRUNLX1JFVFVSTihkZWNvZGVfdjMyKGQsICZsZW4pKTsKKyAgICAgICAgQ0hFQ0tfUkVUVVJOKHNraXAoZCwgbGVuKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBVUEJfV0lSRV9UWVBFX1NUQVJUX0dST1VQOgorICAgICAgICBDSEVDS19TVVNQRU5EKHB1c2h0YWdkZWxpbShkLCAtZmllbGRudW0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9XSVJFX1RZUEVfRU5EX0dST1VQOgorICAgICAgICBpZiAoZmllbGRudW0gPT0gLWQtPnRvcC0+Z3JvdXBudW0pIHsKKyAgICAgICAgICBkZWNvZGVyX3BvcChkKTsKKyAgICAgICAgfSBlbHNlIGlmIChmaWVsZG51bSA9PSBkLT50b3AtPmdyb3VwbnVtKSB7CisgICAgICAgICAgcmV0dXJuIERFQ09ERV9FTkRHUk9VUDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRlcnIoZCwgIlVubWF0Y2hlZCBFTkRHUk9VUCB0YWcuIik7CisgICAgICAgICAgcmV0dXJuIHVwYl9wYmRlY29kZXJfc3VzcGVuZChkKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHNldGVycihkLCAiSW52YWxpZCB3aXJlIHR5cGUiKTsKKyAgICAgICAgcmV0dXJuIHVwYl9wYmRlY29kZXJfc3VzcGVuZChkKTsKKyAgICB9CisKKyAgICBpZiAoZC0+dG9wLT5ncm91cG51bSA+PSAwKSB7CisgICAgICByZXR1cm4gREVDT0RFX09LOworICAgIH0KKworICAgIGlmIChkLT5wdHIgPT0gZC0+ZGVsaW1fZW5kKSB7CisgICAgICBzZXRlcnIoZCwgIkVuY2xvc2luZyBzdWJtZXNzYWdlIGVuZGVkIGluIHRoZSBtaWRkbGUgb2YgdmFsdWUgb3IgZ3JvdXAiKTsKKyAgICAgIC8vIFVubGlrZSBtb3N0IGVycm9ycyB3ZSBub3RpY2UgZHVyaW5nIHBhcnNpbmcsIHJpZ2h0IG5vdyB3ZSBoYXZlIGNvbnN1bWVkCisgICAgICAvLyBhbGwgb2YgdGhlIHVzZXIncyBpbnB1dC4KKyAgICAgIC8vCisgICAgICAvLyBUaGVyZSBhcmUgdGhyZWUgZGlmZmVyZW50IG9wdGlvbnMgZm9yIGhvdyB0byBoYW5kbGUgdGhpcyBjYXNlOgorICAgICAgLy8KKyAgICAgIC8vICAgMS4gZGVjb2RlKCkgPSBzaG9ydCBjb3VudCwgZXJyb3IgPSBzZXQKKyAgICAgIC8vICAgMi4gZGVjb2RlKCkgPSBmdWxsIGNvdW50LCBlcnJvciA9IHNldAorICAgICAgLy8gICAzLiBkZWNvZGUoKSA9IGZ1bGwgY291bnQsIGVycm9yIE5PVCBzZXQsIHNob3J0IGNvdW50IGFuZCBlcnJvciB3aWxsCisgICAgICAvLyAgICAgIGJlIHJlcG9ydGVkIG9uIG5leHQgY2FsbCB0byBkZWNvZGUoKSAob3IgZW5kKCkpCisgICAgICAvLworICAgICAgLy8gKDEpIGFuZCAoMykgaGF2ZSB0aGUgYWR2YW50YWdlIHRoYXQgdGhleSBwcmVzZXJ2ZSB0aGUgaW52YXJpYW50IHRoYXQgYW4KKyAgICAgIC8vIGVycm9yIG9jY3VycyBpZmYgZGVjb2RlKCkgcmV0dXJucyBhIHNob3J0IGNvdW50LgorICAgICAgLy8KKyAgICAgIC8vICgyKSBhbmQgKDMpIGhhdmUgdGhlIGFkdmFudGFnZSBvZiByZWZsZWN0aW5nIHRoZSBmYWN0IHRoYXQgYWxsIG9mIHRoZQorICAgICAgLy8gYnl0ZXMgd2VyZSBpbiBmYWN0IHBhcnNlZCAoYW5kIHBvc3NpYmx5IGRlbGl2ZXJlZCB0byB0aGUgdW5rbm93biBmaWVsZAorICAgICAgLy8gaGFuZGxlciwgaW4gdGhlIGZ1dHVyZSB3aGVuIHRoYXQgaXMgc3VwcG9ydGVkKS4KKyAgICAgIC8vCisgICAgICAvLyAoMykgcmVxdWlyZXMgZXh0cmEgc3RhdGUgaW4gdGhlIGRlY29kZSAoYSBwbGFjZSB0byBzdG9yZSB0aGUgInBlcm1hbmVudAorICAgICAgLy8gZXJyb3IiIHRoYXQgd2Ugc2hvdWxkIHJldHVybiBmb3IgYWxsIHN1YnNlcXVlbnQgYXR0ZW1wdHMgdG8gZGVjb2RlKS4KKyAgICAgIC8vIEJ1dCB3ZSBsaWtlbHkgd2FudCB0aGlzIGFueXdheS4KKyAgICAgIC8vCisgICAgICAvLyBSaWdodCBub3cgd2UgZG8gKDEpLCB0aGFua3MgdG8gdGhlIGZhY3QgdGhhdCB3ZSBjaGVja3BvaW50ICphZnRlciogdGhpcworICAgICAgLy8gY2hlY2suICAoMykgbWF5IGJlIGEgYmV0dGVyIGNob2ljZSBsb25nIHRlcm07IHVuY2xlYXIgYXQgdGhlIG1vbWVudC4KKyAgICAgIHJldHVybiB1cGJfcGJkZWNvZGVyX3N1c3BlbmQoZCk7CisgICAgfQorCisgICAgY2hlY2twb2ludChkKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBnb3RvX2VuZG1zZyh1cGJfcGJkZWNvZGVyICpkKSB7CisgIHVwYl92YWx1ZSB2OworICBib29sIGZvdW5kID0gdXBiX2ludHRhYmxlX2xvb2t1cDMyKGQtPnRvcC0+ZGlzcGF0Y2gsIERJU1BBVENIX0VORE1TRywgJnYpOworICBVUEJfQVNTRVJUX1ZBUihmb3VuZCwgZm91bmQpOworICBkLT5wYyA9IGQtPnRvcC0+YmFzZSArIHVwYl92YWx1ZV9nZXR1aW50NjQodik7Cit9CisKKy8vIFBhcnNlcyBhIHRhZyBhbmQganVtcHMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYnl0ZWNvZGUgaW5zdHJ1Y3Rpb24gZm9yIHRoaXMKKy8vIGZpZWxkLgorLy8KKy8vIElmIHRoZSB0YWcgaXMgdW5rbm93biAob3IgdGhlIHdpcmUgdHlwZSBkb2Vzbid0IG1hdGNoKSwgcGFyc2VzIHRoZSBmaWVsZCBhcworLy8gdW5rbm93bi4gIElmIHRoZSB0YWcgaXMgYSB2YWxpZCBFTkRHUk9VUCB0YWcsIGp1bXBzIHRvIHRoZSBieXRlY29kZQorLy8gaW5zdHJ1Y3Rpb24gZm9yIHRoZSBlbmQgb2YgbWVzc2FnZS4KK3N0YXRpYyBpbnQzMl90IGRpc3BhdGNoKHVwYl9wYmRlY29kZXIgKmQpIHsKKyAgdXBiX2ludHRhYmxlICpkaXNwYXRjaCA9IGQtPnRvcC0+ZGlzcGF0Y2g7CisKKyAgLy8gRGVjb2RlIHRhZy4KKyAgdWludDMyX3QgdGFnOworICBDSEVDS19SRVRVUk4oZGVjb2RlX3YzMihkLCAmdGFnKSk7CisgIHVpbnQ4X3Qgd2lyZV90eXBlID0gdGFnICYgMHg3OworICB1aW50MzJfdCBmaWVsZG51bSA9IHRhZyA+PiAzOworCisgIC8vIExvb2t1cCB0YWcuICBCZWNhdXNlIG9mIHBhY2tlZC9ub24tcGFja2VkIGNvbXBhdGliaWxpdHksIHdlIGhhdmUgdG8KKyAgLy8gY2hlY2sgdGhlIHdpcmUgdHlwZSBhZ2FpbnN0IHR3byBwb3NzaWJpbGl0aWVzLgorICB1cGJfdmFsdWUgdmFsOworICBpZiAoZmllbGRudW0gIT0gRElTUEFUQ0hfRU5ETVNHICYmCisgICAgICB1cGJfaW50dGFibGVfbG9va3VwMzIoZGlzcGF0Y2gsIGZpZWxkbnVtLCAmdmFsKSkgeworICAgIHVpbnQ2NF90IHYgPSB1cGJfdmFsdWVfZ2V0dWludDY0KHZhbCk7CisgICAgaWYgKHdpcmVfdHlwZSA9PSAodiAmIDB4ZmYpKSB7CisgICAgICBkLT5wYyA9IGQtPnRvcC0+YmFzZSArICh2ID4+IDE2KTsKKyAgICAgIHJldHVybiBERUNPREVfT0s7CisgICAgfSBlbHNlIGlmICh3aXJlX3R5cGUgPT0gKCh2ID4+IDgpICYgMHhmZikpIHsKKyAgICAgIGJvb2wgZm91bmQgPQorICAgICAgICAgIHVwYl9pbnR0YWJsZV9sb29rdXAoZGlzcGF0Y2gsIGZpZWxkbnVtICsgVVBCX01BWF9GSUVMRE5VTUJFUiwgJnZhbCk7CisgICAgICBVUEJfQVNTRVJUX1ZBUihmb3VuZCwgZm91bmQpOworICAgICAgZC0+cGMgPSBkLT50b3AtPmJhc2UgKyB1cGJfdmFsdWVfZ2V0dWludDY0KHZhbCk7CisgICAgICByZXR1cm4gREVDT0RFX09LOworICAgIH0KKyAgfQorCisgIC8vIFVua25vd24gZmllbGQgb3IgRU5ER1JPVVAuCisgIGludDMyX3QgcmV0ID0gdXBiX3BiZGVjb2Rlcl9za2lwdW5rbm93bihkLCBmaWVsZG51bSwgd2lyZV90eXBlKTsKKworICBpZiAocmV0ID09IERFQ09ERV9FTkRHUk9VUCkgeworICAgIGdvdG9fZW5kbXNnKGQpOworICAgIHJldHVybiBERUNPREVfT0s7CisgIH0gZWxzZSB7CisgICAgZC0+cGMgPSBkLT5sYXN0IC0gMTsgIC8vIFJld2luZCB0byBDSEVDS0RFTElNLgorICAgIHJldHVybiByZXQ7CisgIH0KK30KKworLy8gQ2FsbGVycyBrbm93IHRoYXQgdGhlIHN0YWNrIGlzIG1vcmUgdGhhbiBvbmUgZGVlcCBiZWNhdXNlIHRoZSBvcGNvZGVzIHRoYXQKKy8vIGNhbGwgdGhpcyBvbmx5IG9jY3VyIGFmdGVyIFBVU0ggb3BlcmF0aW9ucy4KK3VwYl9wYmRlY29kZXJfZnJhbWUgKm91dGVyX2ZyYW1lKHVwYl9wYmRlY29kZXIgKmQpIHsKKyAgYXNzZXJ0KGQtPnRvcCAhPSBkLT5zdGFjayk7CisgIHJldHVybiBkLT50b3AgLSAxOworfQorCisKKy8qIFRoZSBtYWluIGRlY29kaW5nIGxvb3AgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIFRoZSBtYWluIGRlY29kZXIgVk0gZnVuY3Rpb24uICBVc2VzIHRyYWRpdGlvbmFsIGJ5dGVjb2RlIGRpc3BhdGNoIGxvb3Agd2l0aCBhCisvLyBzd2l0Y2goKSBzdGF0ZW1lbnQuCitzaXplX3QgdXBiX3BiZGVjb2Rlcl9kZWNvZGUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZSwgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIHVwYl9wYmRlY29kZXIgKmQgPSBjbG9zdXJlOworICBjb25zdCBtZ3JvdXAgKmdyb3VwID0gaGQ7CisgIGFzc2VydChidWYpOworICBpbnQzMl90IHJlc3VsdCA9IHVwYl9wYmRlY29kZXJfcmVzdW1lKGQsIE5VTEwsIGJ1Ziwgc2l6ZSwgaGFuZGxlKTsKKyAgaWYgKHJlc3VsdCA9PSBERUNPREVfRU5ER1JPVVApIHsKKyAgICBnb3RvX2VuZG1zZyhkKTsKKyAgfQorICBDSEVDS19SRVRVUk4ocmVzdWx0KTsKKyAgVVBCX1VOVVNFRChncm91cCk7CisKKyNkZWZpbmUgVk1DQVNFKG9wLCBjb2RlKSBcCisgIGNhc2Ugb3A6IHsgY29kZTsgaWYgKGNvbnN1bWVzX2lucHV0KG9wKSkgY2hlY2twb2ludChkKTsgYnJlYWs7IH0KKyNkZWZpbmUgUFJJTUlUSVZFX09QKHR5cGUsIHd0LCBuYW1lLCBjb252ZnVuYywgY3R5cGUpIFwKKyAgVk1DQVNFKE9QX1BBUlNFXyAjIyB0eXBlLCB7IFwKKyAgICBjdHlwZSB2YWw7IFwKKyAgICBDSEVDS19SRVRVUk4oZGVjb2RlXyAjIyB3dChkLCAmdmFsKSk7IFwKKyAgICB1cGJfc2lua19wdXQgIyMgbmFtZSgmZC0+dG9wLT5zaW5rLCBhcmcsIChjb252ZnVuYykodmFsKSk7IFwKKyAgfSkKKworICB3aGlsZSgxKSB7CisgICAgZC0+bGFzdCA9IGQtPnBjOworICAgIGludDMyX3QgaW5zdHJ1Y3Rpb24gPSAqZC0+cGMrKzsKKyAgICBvcGNvZGUgb3AgPSBnZXRvcChpbnN0cnVjdGlvbik7CisgICAgdWludDMyX3QgYXJnID0gaW5zdHJ1Y3Rpb24gPj4gODsKKyAgICBpbnQzMl90IGxvbmdvZnMgPSBhcmc7CisgICAgYXNzZXJ0KGQtPnB0ciAhPSBkLT5yZXNpZHVhbF9lbmQpOworI2lmZGVmIFVQQl9EVU1QX0JZVEVDT0RFCisgICAgZnByaW50ZihzdGRlcnIsICJzX29mcz0lZCBidWZfb2ZzPSVkIGRhdGFfcmVtPSVkIGJ1Zl9yZW09JWQgZGVsaW1fcmVtPSVkICIKKyAgICAgICAgICAgICAgICAgICAgIiV4ICVzICglZClcbiIsCisgICAgICAgICAgICAoaW50KW9mZnNldChkKSwKKyAgICAgICAgICAgIChpbnQpKGQtPnB0ciAtIGQtPmJ1ZiksCisgICAgICAgICAgICAoaW50KShkLT5kYXRhX2VuZCAtIGQtPnB0ciksCisgICAgICAgICAgICAoaW50KShkLT5lbmQgLSBkLT5wdHIpLAorICAgICAgICAgICAgKGludCkoKGQtPnRvcC0+ZW5kX29mcyAtIGQtPmJ1ZnN0YXJ0X29mcykgLSAoZC0+cHRyIC0gZC0+YnVmKSksCisgICAgICAgICAgICAoaW50KShkLT5wYyAtIDEgLSBncm91cC0+Ynl0ZWNvZGUpLAorICAgICAgICAgICAgdXBiX3BiZGVjb2Rlcl9nZXRvcG5hbWUob3ApLAorICAgICAgICAgICAgYXJnKTsKKyNlbmRpZgorICAgIHN3aXRjaCAob3ApIHsKKyAgICAgIC8vIFRlY2huaWNhbGx5LCB3ZSBhcmUgbG9zaW5nIGRhdGEgaWYgd2Ugc2VlIGEgMzItYml0IHZhcmludCB0aGF0IGlzIG5vdAorICAgICAgLy8gcHJvcGVybHkgc2lnbi1leHRlbmRlZC4gIFdlIGNvdWxkIGRldGVjdCB0aGlzIGFuZCBlcnJvciBhYm91dCB0aGUgZGF0YQorICAgICAgLy8gbG9zcywgYnV0IHByb3RvMiBkb2VzIG5vdCBkbyB0aGlzLCBzbyB3ZSBwYXNzLgorICAgICAgUFJJTUlUSVZFX09QKElOVDMyLCAgICB2YXJpbnQsICBpbnQzMiwgIGludDMyX3QsICAgICAgdWludDY0X3QpCisgICAgICBQUklNSVRJVkVfT1AoSU5UNjQsICAgIHZhcmludCwgIGludDY0LCAgaW50NjRfdCwgICAgICB1aW50NjRfdCkKKyAgICAgIFBSSU1JVElWRV9PUChVSU5UMzIsICAgdmFyaW50LCAgdWludDMyLCB1aW50MzJfdCwgICAgIHVpbnQ2NF90KQorICAgICAgUFJJTUlUSVZFX09QKFVJTlQ2NCwgICB2YXJpbnQsICB1aW50NjQsIHVpbnQ2NF90LCAgICAgdWludDY0X3QpCisgICAgICBQUklNSVRJVkVfT1AoRklYRUQzMiwgIGZpeGVkMzIsIHVpbnQzMiwgdWludDMyX3QsICAgICB1aW50MzJfdCkKKyAgICAgIFBSSU1JVElWRV9PUChGSVhFRDY0LCAgZml4ZWQ2NCwgdWludDY0LCB1aW50NjRfdCwgICAgIHVpbnQ2NF90KQorICAgICAgUFJJTUlUSVZFX09QKFNGSVhFRDMyLCBmaXhlZDMyLCBpbnQzMiwgIGludDMyX3QsICAgICAgdWludDMyX3QpCisgICAgICBQUklNSVRJVkVfT1AoU0ZJWEVENjQsIGZpeGVkNjQsIGludDY0LCAgaW50NjRfdCwgICAgICB1aW50NjRfdCkKKyAgICAgIFBSSU1JVElWRV9PUChCT09MLCAgICAgdmFyaW50LCAgYm9vbCwgICBib29sLCAgICAgICAgIHVpbnQ2NF90KQorICAgICAgUFJJTUlUSVZFX09QKERPVUJMRSwgICBmaXhlZDY0LCBkb3VibGUsIGFzX2RvdWJsZSwgICAgdWludDY0X3QpCisgICAgICBQUklNSVRJVkVfT1AoRkxPQVQsICAgIGZpeGVkMzIsIGZsb2F0LCAgYXNfZmxvYXQsICAgICB1aW50MzJfdCkKKyAgICAgIFBSSU1JVElWRV9PUChTSU5UMzIsICAgdmFyaW50LCAgaW50MzIsICB1cGJfenpkZWNfMzIsIHVpbnQ2NF90KQorICAgICAgUFJJTUlUSVZFX09QKFNJTlQ2NCwgICB2YXJpbnQsICBpbnQ2NCwgIHVwYl96emRlY182NCwgdWludDY0X3QpCisKKyAgICAgIFZNQ0FTRShPUF9TRVRESVNQQVRDSCwKKyAgICAgICAgZC0+dG9wLT5iYXNlID0gZC0+cGMgLSAxOworICAgICAgICBtZW1jcHkoJmQtPnRvcC0+ZGlzcGF0Y2gsIGQtPnBjLCBzaXplb2Yodm9pZCopKTsKKyAgICAgICAgZC0+cGMgKz0gc2l6ZW9mKHZvaWQqKSAvIHNpemVvZih1aW50MzJfdCk7CisgICAgICApCisgICAgICBWTUNBU0UoT1BfU1RBUlRNU0csCisgICAgICAgIENIRUNLX1NVU1BFTkQodXBiX3Npbmtfc3RhcnRtc2coJmQtPnRvcC0+c2luaykpOworICAgICAgKQorICAgICAgVk1DQVNFKE9QX0VORE1TRywKKyAgICAgICAgQ0hFQ0tfU1VTUEVORCh1cGJfc2lua19lbmRtc2coJmQtPnRvcC0+c2luaywgZC0+c3RhdHVzKSk7CisgICAgICApCisgICAgICBWTUNBU0UoT1BfU1RBUlRTRVEsCisgICAgICAgIHVwYl9wYmRlY29kZXJfZnJhbWUgKm91dGVyID0gb3V0ZXJfZnJhbWUoZCk7CisgICAgICAgIENIRUNLX1NVU1BFTkQodXBiX3Npbmtfc3RhcnRzZXEoJm91dGVyLT5zaW5rLCBhcmcsICZkLT50b3AtPnNpbmspKTsKKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9FTkRTRVEsCisgICAgICAgIENIRUNLX1NVU1BFTkQodXBiX3NpbmtfZW5kc2VxKCZkLT50b3AtPnNpbmssIGFyZykpOworICAgICAgKQorICAgICAgVk1DQVNFKE9QX1NUQVJUU1VCTVNHLAorICAgICAgICB1cGJfcGJkZWNvZGVyX2ZyYW1lICpvdXRlciA9IG91dGVyX2ZyYW1lKGQpOworICAgICAgICBDSEVDS19TVVNQRU5EKHVwYl9zaW5rX3N0YXJ0c3VibXNnKCZvdXRlci0+c2luaywgYXJnLCAmZC0+dG9wLT5zaW5rKSk7CisgICAgICApCisgICAgICBWTUNBU0UoT1BfRU5EU1VCTVNHLAorICAgICAgICBDSEVDS19TVVNQRU5EKHVwYl9zaW5rX2VuZHN1Ym1zZygmZC0+dG9wLT5zaW5rLCBhcmcpKTsKKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9TVEFSVFNUUiwKKyAgICAgICAgdWludDMyX3QgbGVuID0gZC0+dG9wLT5lbmRfb2ZzIC0gb2Zmc2V0KGQpOworICAgICAgICB1cGJfcGJkZWNvZGVyX2ZyYW1lICpvdXRlciA9IG91dGVyX2ZyYW1lKGQpOworICAgICAgICBDSEVDS19TVVNQRU5EKHVwYl9zaW5rX3N0YXJ0c3RyKCZvdXRlci0+c2luaywgYXJnLCBsZW4sICZkLT50b3AtPnNpbmspKTsKKyAgICAgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgICAgZC0+cGMrKzsgIC8vIFNraXAgT1BfU1RSSU5HLgorICAgICAgICB9CisgICAgICApCisgICAgICBWTUNBU0UoT1BfU1RSSU5HLAorICAgICAgICB1aW50MzJfdCBsZW4gPSBjdXJidWZsZWZ0KGQpOworICAgICAgICBzaXplX3QgbiA9IHVwYl9zaW5rX3B1dHN0cmluZygmZC0+dG9wLT5zaW5rLCBhcmcsIGQtPnB0ciwgbGVuLCBoYW5kbGUpOworICAgICAgICBpZiAobiA+IGxlbikgeworICAgICAgICAgIGlmIChuID4gZC0+dG9wLT5lbmRfb2ZzIC0gb2Zmc2V0KGQpKSB7CisgICAgICAgICAgICBzZXRlcnIoZCwgIlRyaWVkIHRvIHNraXAgcGFzdCBlbmQgb2Ygc3RyaW5nLiIpOworICAgICAgICAgICAgcmV0dXJuIHVwYl9wYmRlY29kZXJfc3VzcGVuZChkKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50MzJfdCByZXQgPSBza2lwKGQsIG4pOworICAgICAgICAgICAgLy8gVGhpcyBzaG91bGRuJ3QgcmV0dXJuIERFQ09ERV9PSywgYmVjYXVzZSBuID4gbGVuLgorICAgICAgICAgICAgYXNzZXJ0KHJldCA+PSAwKTsKKyAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFkdmFuY2UoZCwgbik7CisgICAgICAgIGlmIChuIDwgbGVuIHx8IGQtPmRlbGltX2VuZCA9PSBOVUxMKSB7CisgICAgICAgICAgLy8gV2UgYXJlbid0IGZpbmlzaGVkIHdpdGggdGhpcyBzdHJpbmcgeWV0LgorICAgICAgICAgIGQtPnBjLS07ICAvLyBSZXBlYXQgT1BfU1RSSU5HLgorICAgICAgICAgIGlmIChuID4gMCkgY2hlY2twb2ludChkKTsKKyAgICAgICAgICByZXR1cm4gdXBiX3BiZGVjb2Rlcl9zdXNwZW5kKGQpOworICAgICAgICB9CisgICAgICApCisgICAgICBWTUNBU0UoT1BfRU5EU1RSLAorICAgICAgICBDSEVDS19TVVNQRU5EKHVwYl9zaW5rX2VuZHN0cigmZC0+dG9wLT5zaW5rLCBhcmcpKTsKKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9QVVNIVEFHREVMSU0sCisgICAgICAgIENIRUNLX1NVU1BFTkQocHVzaHRhZ2RlbGltKGQsIGFyZykpOworICAgICAgKQorICAgICAgVk1DQVNFKE9QX1NFVEJJR0dST1VQTlVNLAorICAgICAgICBkLT50b3AtPmdyb3VwbnVtID0gKmQtPnBjKys7CisgICAgICApCisgICAgICBWTUNBU0UoT1BfUE9QLAorICAgICAgICBhc3NlcnQoZC0+dG9wID4gZC0+c3RhY2spOworICAgICAgICBkZWNvZGVyX3BvcChkKTsKKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9QVVNITEVOREVMSU0sCisgICAgICAgIHVpbnQzMl90IGxlbjsKKyAgICAgICAgQ0hFQ0tfUkVUVVJOKGRlY29kZV92MzIoZCwgJmxlbikpOworICAgICAgICBDSEVDS19TVVNQRU5EKGRlY29kZXJfcHVzaChkLCBvZmZzZXQoZCkgKyBsZW4pKTsKKyAgICAgICAgc2V0X2RlbGltX2VuZChkKTsKKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9TRVRERUxJTSwKKyAgICAgICAgc2V0X2RlbGltX2VuZChkKTsKKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9DSEVDS0RFTElNLAorICAgICAgICAvLyBXZSBhcmUgZ3VhcmFudGVlZCBvZiB0aGlzIGFzc2VydCBiZWNhdXNlIHdlIG5ldmVyIGFsbG93IG91cnNlbHZlcyB0bworICAgICAgICAvLyBjb25zdW1lIGJ5dGVzIGJleW9uZCBkYXRhX2VuZCwgd2hpY2ggY292ZXJzIGRlbGltX2VuZCB3aGVuIG5vbi1OVUxMLgorICAgICAgICBhc3NlcnQoIShkLT5kZWxpbV9lbmQgJiYgZC0+cHRyID4gZC0+ZGVsaW1fZW5kKSk7CisgICAgICAgIGlmIChkLT5wdHIgPT0gZC0+ZGVsaW1fZW5kKQorICAgICAgICAgIGQtPnBjICs9IGxvbmdvZnM7CisgICAgICApCisgICAgICBWTUNBU0UoT1BfQ0FMTCwKKyAgICAgICAgZC0+Y2FsbHN0YWNrW2QtPmNhbGxfbGVuKytdID0gZC0+cGM7CisgICAgICAgIGQtPnBjICs9IGxvbmdvZnM7CisgICAgICApCisgICAgICBWTUNBU0UoT1BfUkVULAorICAgICAgICBhc3NlcnQoZC0+Y2FsbF9sZW4gPiAwKTsKKyAgICAgICAgZC0+cGMgPSBkLT5jYWxsc3RhY2tbLS1kLT5jYWxsX2xlbl07CisgICAgICApCisgICAgICBWTUNBU0UoT1BfQlJBTkNILAorICAgICAgICBkLT5wYyArPSBsb25nb2ZzOworICAgICAgKQorICAgICAgVk1DQVNFKE9QX1RBRzEsCisgICAgICAgIENIRUNLX1NVU1BFTkQoY3VyYnVmbGVmdChkKSA+IDApOworICAgICAgICB1aW50OF90IGV4cGVjdGVkID0gKGFyZyA+PiA4KSAmIDB4ZmY7CisgICAgICAgIGlmICgqZC0+cHRyID09IGV4cGVjdGVkKSB7CisgICAgICAgICAgYWR2YW5jZShkLCAxKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpbnQ4X3Qgc2hvcnRvZnM7CisgICAgICAgICBiYWR0YWc6CisgICAgICAgICAgc2hvcnRvZnMgPSBhcmc7CisgICAgICAgICAgaWYgKHNob3J0b2ZzID09IExBQkVMX0RJU1BBVENIKSB7CisgICAgICAgICAgICBDSEVDS19SRVRVUk4oZGlzcGF0Y2goZCkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkLT5wYyArPSBzaG9ydG9mczsKKyAgICAgICAgICAgIGJyZWFrOyAvLyBBdm9pZCBjaGVja3BvaW50KCkuCisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICApCisgICAgICBWTUNBU0UoT1BfVEFHMiwKKyAgICAgICAgQ0hFQ0tfU1VTUEVORChjdXJidWZsZWZ0KGQpID4gMCk7CisgICAgICAgIHVpbnQxNl90IGV4cGVjdGVkID0gKGFyZyA+PiA4KSAmIDB4ZmZmZjsKKyAgICAgICAgaWYgKGN1cmJ1ZmxlZnQoZCkgPj0gMikgeworICAgICAgICAgIHVpbnQxNl90IGFjdHVhbDsKKyAgICAgICAgICBtZW1jcHkoJmFjdHVhbCwgZC0+cHRyLCAyKTsKKyAgICAgICAgICBpZiAoZXhwZWN0ZWQgPT0gYWN0dWFsKSB7CisgICAgICAgICAgICBhZHZhbmNlKGQsIDIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnb3RvIGJhZHRhZzsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaW50MzJfdCByZXN1bHQgPSB1cGJfcGJkZWNvZGVyX2NoZWNrdGFnX3Nsb3coZCwgZXhwZWN0ZWQpOworICAgICAgICAgIGlmIChyZXN1bHQgPT0gREVDT0RFX01JU01BVENIKSBnb3RvIGJhZHRhZzsKKyAgICAgICAgICBpZiAocmVzdWx0ID49IDApIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgICkKKyAgICAgIFZNQ0FTRShPUF9UQUdOLCB7CisgICAgICAgIHVpbnQ2NF90IGV4cGVjdGVkOworICAgICAgICBtZW1jcHkoJmV4cGVjdGVkLCBkLT5wYywgOCk7CisgICAgICAgIGQtPnBjICs9IDI7CisgICAgICAgIGludDMyX3QgcmVzdWx0ID0gdXBiX3BiZGVjb2Rlcl9jaGVja3RhZ19zbG93KGQsIGV4cGVjdGVkKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBERUNPREVfTUlTTUFUQ0gpIGdvdG8gYmFkdGFnOworICAgICAgICBpZiAocmVzdWx0ID49IDApIHJldHVybiByZXN1bHQ7CisgICAgICB9KQorICAgICAgVk1DQVNFKE9QX0RJU1BBVENILCB7CisgICAgICAgIENIRUNLX1JFVFVSTihkaXNwYXRjaChkKSk7CisgICAgICB9KQorICAgICAgVk1DQVNFKE9QX0hBTFQsIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICB9KQorICAgIH0KKyAgfQorfQorCit2b2lkICp1cGJfcGJkZWNvZGVyX3N0YXJ0YmModm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqcGMsIHNpemVfdCBzaXplX2hpbnQpIHsKKyAgdXBiX3BiZGVjb2RlciAqZCA9IGNsb3N1cmU7CisgIFVQQl9VTlVTRUQoc2l6ZV9oaW50KTsKKyAgZC0+Y2FsbF9sZW4gPSAxOworICBkLT5wYyA9IHBjOworICByZXR1cm4gZDsKK30KKwordm9pZCAqdXBiX3BiZGVjb2Rlcl9zdGFydGppdCh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoZCwgc2l6ZV90IHNpemVfaGludCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgVVBCX1VOVVNFRChzaXplX2hpbnQpOworICB1cGJfcGJkZWNvZGVyICpkID0gY2xvc3VyZTsKKyAgZC0+Y2FsbF9sZW4gPSAwOworICByZXR1cm4gZDsKK30KKworYm9vbCB1cGJfcGJkZWNvZGVyX2VuZCh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgdXBiX3BiZGVjb2RlciAqZCA9IGNsb3N1cmU7CisgIGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKm1ldGhvZCA9IGhhbmRsZXJfZGF0YTsKKworICBpZiAoZC0+cmVzaWR1YWxfZW5kID4gZC0+cmVzaWR1YWwpIHsKKyAgICBzZXRlcnIoZCwgIlVuZXhwZWN0ZWQgRU9GIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaWYgKGQtPnRvcC0+ZW5kX29mcyAhPSBVSU5UNjRfTUFYKSB7CisgICAgc2V0ZXJyKGQsICJVbmV4cGVjdGVkIEVPRiBpbnNpZGUgZGVsaW1pdGVkIHN0cmluZyIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIE1lc3NhZ2UgZW5kcyBoZXJlLgorICB1aW50NjRfdCBlbmQgPSBvZmZzZXQoZCk7CisgIGQtPnRvcC0+ZW5kX29mcyA9IGVuZDsKKworICBjaGFyIGR1bW15OworI2lmZGVmIFVQQl9VU0VfSklUX1g2NAorICBjb25zdCBtZ3JvdXAgKmdyb3VwID0gKGNvbnN0IG1ncm91cCopbWV0aG9kLT5ncm91cDsKKyAgaWYgKGdyb3VwLT5qaXRfY29kZSkgeworICAgIGlmIChkLT50b3AgIT0gZC0+c3RhY2spCisgICAgICBkLT5zdGFjay0+ZW5kX29mcyA9IDA7CisgICAgZ3JvdXAtPmppdF9jb2RlKGNsb3N1cmUsIG1ldGhvZC0+Y29kZV9iYXNlLnB0ciwgJmR1bW15LCAwLCBOVUxMKTsKKyAgfSBlbHNlIHsKKyNlbmRpZgorICAgIGQtPnN0YWNrLT5lbmRfb2ZzID0gZW5kOworICAgIGNvbnN0IHVpbnQzMl90ICpwID0gZC0+cGM7CisgICAgLy8gQ2hlY2sgdGhlIHByZXZpb3VzIGJ5dGVjb2RlLCBidXQgZ3VhcmQgYWdhaW5zdCBiZWdpbm5pbmcuCisgICAgaWYgKHAgIT0gbWV0aG9kLT5jb2RlX2Jhc2UucHRyKSBwLS07CisgICAgaWYgKGdldG9wKCpwKSA9PSBPUF9DSEVDS0RFTElNKSB7CisgICAgICAvLyBSZXdpbmQgZnJvbSBPUF9UQUcqIHRvIE9QX0NIRUNLREVMSU0uCisgICAgICBhc3NlcnQoZ2V0b3AoKmQtPnBjKSA9PSBPUF9UQUcxIHx8CisgICAgICAgICAgICAgZ2V0b3AoKmQtPnBjKSA9PSBPUF9UQUcyIHx8CisgICAgICAgICAgICAgZ2V0b3AoKmQtPnBjKSA9PSBPUF9UQUdOIHx8CisgICAgICAgICAgICAgZ2V0b3AoKmQtPnBjID09IE9QX0RJU1BBVENIKSk7CisgICAgICBkLT5wYyA9IHA7CisgICAgfQorICAgIHVwYl9wYmRlY29kZXJfZGVjb2RlKGNsb3N1cmUsIGhhbmRsZXJfZGF0YSwgJmR1bW15LCAwLCBOVUxMKTsKKyNpZmRlZiBVUEJfVVNFX0pJVF9YNjQKKyAgfQorI2VuZGlmCisKKyAgaWYgKGQtPmNhbGxfbGVuICE9IDApIHsKKyAgICBzZXRlcnIoZCwgIlVuZXhwZWN0ZWQgRU9GIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgdXBiX3BiZGVjb2Rlcl9pbml0KHVwYl9wYmRlY29kZXIgKmQsIGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKSB7CisgIGQtPmxpbWl0ID0gJmQtPnN0YWNrW1VQQl9ERUNPREVSX01BWF9ORVNUSU5HXTsKKyAgdXBiX2J5dGVzc2lua19yZXNldCgmZC0+aW5wdXRfLCAmbS0+aW5wdXRfaGFuZGxlcl8sIGQpOworICBkLT5tZXRob2RfID0gbTsKKyAgZC0+Y2FsbHN0YWNrWzBdID0gJmhhbHQ7CisgIGQtPnN0YXR1cyA9IHM7CisgIHVwYl9wYmRlY29kZXJfcmVzZXQoZCk7Cit9CisKK3ZvaWQgdXBiX3BiZGVjb2Rlcl9yZXNldCh1cGJfcGJkZWNvZGVyICpkKSB7CisgIGQtPnRvcCA9IGQtPnN0YWNrOworICBkLT50b3AtPmVuZF9vZnMgPSBVSU5UNjRfTUFYOworICBkLT50b3AtPmdyb3VwbnVtID0gMDsKKyAgZC0+YnVmc3RhcnRfb2ZzID0gMDsKKyAgZC0+cHRyID0gZC0+cmVzaWR1YWw7CisgIGQtPmJ1ZiA9IGQtPnJlc2lkdWFsOworICBkLT5lbmQgPSBkLT5yZXNpZHVhbDsKKyAgZC0+cmVzaWR1YWxfZW5kID0gZC0+cmVzaWR1YWw7CisgIGQtPmNhbGxfbGVuID0gMTsKK30KKwordWludDY0X3QgdXBiX3BiZGVjb2Rlcl9ieXRlc3BhcnNlZChjb25zdCB1cGJfcGJkZWNvZGVyICpkKSB7CisgIHJldHVybiBvZmZzZXQoZCk7Cit9CisKKy8vIE5vdCBjdXJyZW50bHkgcmVxdWlyZWQsIGJ1dCB0byBzdXBwb3J0IG91dGdyb3dpbmcgdGhlIHN0YXRpYyBzdGFjayB3ZSBuZWVkCisvLyB0aGlzLgordm9pZCB1cGJfcGJkZWNvZGVyX3VuaW5pdCh1cGJfcGJkZWNvZGVyICpkKSB7CisgIFVQQl9VTlVTRUQoZCk7Cit9CisKK2NvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKnVwYl9wYmRlY29kZXJfbWV0aG9kKGNvbnN0IHVwYl9wYmRlY29kZXIgKmQpIHsKKyAgcmV0dXJuIGQtPm1ldGhvZF87Cit9CisKK2Jvb2wgdXBiX3BiZGVjb2Rlcl9yZXNldG91dHB1dCh1cGJfcGJkZWNvZGVyICpkLCB1cGJfc2luayogc2luaykgeworICAvLyBUT0RPKGhhYmVybWFuKTogZG8gd2UgbmVlZCB0byB0ZXN0IHdoZXRoZXIgdGhlIGRlY29kZXIgaXMgYWxyZWFkeSBvbiB0aGUKKyAgLy8gc3RhY2sgKGxpa2UgY2FsbGluZyB0aGlzIGZyb20gd2l0aGluIGEgY2FsbGJhY2spPyAgU2hvdWxkIHdlIHN1cHBvcnQKKyAgLy8gcmViaW5kaW5nIHRoZSBvdXRwdXQgYXQgYWxsPworICBhc3NlcnQoc2luayk7CisgIGlmIChkLT5tZXRob2RfLT5kZXN0X2hhbmRsZXJzXykgeworICAgIGlmIChzaW5rLT5oYW5kbGVycyAhPSBkLT5tZXRob2RfLT5kZXN0X2hhbmRsZXJzXykKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorICB1cGJfc2lua19yZXNldCgmZC0+dG9wLT5zaW5rLCBzaW5rLT5oYW5kbGVycywgc2luay0+Y2xvc3VyZSk7CisgIHJldHVybiB0cnVlOworfQorCit1cGJfYnl0ZXNzaW5rICp1cGJfcGJkZWNvZGVyX2lucHV0KHVwYl9wYmRlY29kZXIgKmQpIHsKKyAgcmV0dXJuICZkLT5pbnB1dF87Cit9CisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDE0IEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBTaW5jZSB3ZSBhcmUgaW1wbGVtZW50aW5nIHB1cmUgaGFuZGxlcnMgKGllLiB3aXRob3V0IGFueSBvdXQtb2YtYmFuZCBhY2Nlc3MKKyAqIHRvIHByZS1jb21wdXRlZCBsZW5ndGhzKSwgd2UgaGF2ZSB0byBidWZmZXIgYWxsIHN1Ym1lc3NhZ2VzIGJlZm9yZSB3ZSBjYW4KKyAqIGVtaXQgZXZlbiB0aGVpciBmaXJzdCBieXRlLgorICoKKyAqIE5vdCBrbm93aW5nIHRoZSBzaXplIG9mIHN1Ym1lc3NhZ2VzIGFsc28gbWVhbnMgd2UgY2FuJ3Qgd3JpdGUgYSBwZXJmZWN0CisgKiB6ZXJvLWNvcHkgaW1wbGVtZW50YXRpb24sIGV2ZW4gd2l0aCBidWZmZXJpbmcuICBMZW5ndGhzIGFyZSBzdG9yZWQgYXMKKyAqIHZhcmludHMsIHdoaWNoIG1lYW5zIHRoYXQgd2UgZG9uJ3Qga25vdyBob3cgbWFueSBieXRlcyB0byByZXNlcnZlIGZvciB0aGUKKyAqIGxlbmd0aCB1bnRpbCB3ZSBrbm93IHdoYXQgdGhlIGxlbmd0aCBpcy4KKyAqCisgKiBUaGlzIGxlYXZlcyB1cyB3aXRoIHRocmVlIG1haW4gY2hvaWNlczoKKyAqCisgKiAxLiBidWZmZXIgYWxsIHN1Ym1lc3NhZ2UgZGF0YSBpbiBhIHRlbXBvcmFyeSBidWZmZXIsIHRoZW4gY29weSBpdCBleGFjdGx5CisgKiAgICBvbmNlIGludG8gdGhlIG91dHB1dCBidWZmZXIuCisgKgorICogMi4gYXR0ZW1wdCB0byBidWZmZXIgZGF0YSBkaXJlY3RseSBpbnRvIHRoZSBvdXRwdXQgYnVmZmVyLCBlc3RpbWF0aW5nIGhvdworICogICAgbWFueSBieXRlcyBlYWNoIGxlbmd0aCB3aWxsIHRha2UuICBXaGVuIG91ciBndWVzc2VzIGFyZSB3cm9uZywgdXNlCisgKiAgICBtZW1tb3ZlKCkgdG8gZ3JvdyBvciBzaHJpbmsgdGhlIGFsbG90dGVkIHNwYWNlLgorICoKKyAqIDMuIGJ1ZmZlciBkaXJlY3RseSBpbnRvIHRoZSBvdXRwdXQgYnVmZmVyLCBhbGxvY2F0aW5nIGEgbWF4IGxlbmd0aAorICogICAgYWhlYWQtb2YtdGltZSBmb3IgZWFjaCBzdWJtZXNzYWdlIGxlbmd0aC4gIElmIHdlIG92ZXJhbGxvY2F0ZWQsIHdlIHdhc3RlCisgKiAgICBzcGFjZSwgYnV0IG5vIG1lbWNweSgpIG9yIG1lbW1vdmUoKSBpcyByZXF1aXJlZC4gIFRoaXMgYXBwcm9hY2ggcmVxdWlyZXMKKyAqICAgIGRlZmluaW5nIGEgbWF4aW11bSBzaXplIGZvciBzdWJtZXNzYWdlcyBhbmQgcmVqZWN0aW5nIHN1Ym1lc3NhZ2VzIHRoYXQKKyAqICAgIGV4Y2VlZCB0aGF0IHNpemUuCisgKgorICogKDIpIGFuZCAoMykgaGF2ZSB0aGUgcG90ZW50aWFsIHRvIGhhdmUgYmV0dGVyIHBlcmZvcm1hbmNlLCBidXQgdGhleSBhcmUgbW9yZQorICogY29tcGxpY2F0ZWQgYW5kIHN1YnRsZSB0byBpbXBsZW1lbnQ6CisgKgorICogICAoMykgcmVxdWlyZXMgbWFraW5nIGFuIGFyYml0cmFyeSBjaG9pY2Ugb2YgdGhlIG1heGltdW0gbWVzc2FnZSBzaXplOyBpdAorICogICAgICAgd2FzdGVzIHNwYWNlIHdoZW4gc3VibWVzc2FnZXMgYXJlIHNob3J0ZXIgdGhhbiB0aGlzIGFuZCBmYWlscworICogICAgICAgY29tcGxldGVseSB3aGVuIHRoZXkgYXJlIGxvbmdlci4gIFRoaXMgbWFrZXMgaXQgbW9yZSBmaW5pY2t5IGFuZAorICogICAgICAgcmVxdWlyZXMgY29uZmlndXJhdGlvbiBiYXNlZCBvbiB0aGUgaW5wdXQuICBJdCBhbHNvIG1ha2VzIGl0IGltcG9zc2libGUKKyAqICAgICAgIHRvIHBlcmZlY3RseSBtYXRjaCB0aGUgb3V0cHV0IG9mIHJlZmVyZW5jZSBlbmNvZGVycyB0aGF0IGFsd2F5cyB1c2UgdGhlCisgKiAgICAgICBvcHRpbWFsIGFtb3VudCBvZiBzcGFjZSBmb3IgZWFjaCBsZW5ndGguCisgKgorICogICAoMikgcmVxdWlyZXMgZ3Vlc3NpbmcgdGhlIHRoZSBzaXplIHVwZnJvbnQsIGFuZCBpZiBtdWx0aXBsZSBsZW5ndGhzIGFyZQorICogICAgICAgZ3Vlc3NlZCB3cm9uZyB0aGUgbWluaW11bSByZXF1aXJlZCBudW1iZXIgb2YgbWVtbW92ZSgpIG9wZXJhdGlvbnMgbWF5CisgKiAgICAgICBiZSBjb21wbGljYXRlZCB0byBjb21wdXRlIGNvcnJlY3RseS4gIEltcGxlbWVudGVkIHByb3Blcmx5LCBpdCBtYXkgaGF2ZQorICogICAgICAgYSB1c2VmdWwgYW1vcnRpemVkIG9yIGF2ZXJhZ2UgY29zdCwgYnV0IG1vcmUgaW52ZXN0aWdhdGlvbiBpcyByZXF1aXJlZAorICogICAgICAgdG8gZGV0ZXJtaW5lIHRoaXMgYW5kIHdoYXQgdGhlIG9wdGltYWwgYWxnb3JpdGhtIGlzIHRvIGFjaGlldmUgaXQuCisgKgorICogICAoMSkgbWFrZXMgeW91IGFsd2F5cyBwYXkgZm9yIGV4YWN0bHkgb25lIGNvcHksIGJ1dCBpdHMgaW1wbGVtZW50YXRpb24gaXMKKyAqICAgICAgIHRoZSBzaW1wbGVzdCBhbmQgaXRzIHBlcmZvcm1hbmNlIGlzIHByZWRpY3RhYmxlLgorICoKKyAqIFNvIGZvciBub3csIHdlIGltcGxlbWVudCAoMSkgb25seS4gIElmIHdlIHdpc2ggdG8gb3B0aW1pemUgbGF0ZXIsIHdlIHNob3VsZAorICogYmUgYWJsZSB0byBkbyBpdCB3aXRob3V0IGFmZmVjdGluZyB1c2Vycy4KKyAqCisgKiBUaGUgc3RyYXRlZ3kgaXMgdG8gYnVmZmVyIHRoZSBzZWdtZW50cyBvZiBkYXRhIHRoYXQgZG8gKm5vdCogZGVwZW5kIG9uCisgKiB1bmtub3duIGxlbmd0aHMgaW4gb25lIGJ1ZmZlciwgYW5kIGtlZXAgYSBzZXBhcmF0ZSBidWZmZXIgb2Ygc2VnbWVudCBwb2ludGVycworICogYW5kIGxlbmd0aHMuICBXaGVuIHRoZSB0b3AtbGV2ZWwgc3VibWVzc2FnZSBlbmRzLCB3ZSBjYW4gZ28gYmVnaW5uaW5nIHRvIGVuZCwKKyAqIGFsdGVybmF0aW5nIHRoZSB3cml0aW5nIG9mIGxlbmd0aHMgd2l0aCBtZW1jcHkoKSBvZiB0aGUgcmVzdCBvZiB0aGUgZGF0YS4KKyAqIEF0IHRoZSB0b3AgbGV2ZWwgdGhvdWdoLCBubyBidWZmZXJpbmcgaXMgcmVxdWlyZWQuCisgKi8KKworCisjaW5jbHVkZSA8c3RkbGliLmg+CisKKy8qIGxvdy1sZXZlbCBidWZmZXJpbmcgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIExvdy1sZXZlbCBmdW5jdGlvbnMgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIG91dHB1dCBidWZmZXIuCisKKy8vIFRPRE8oaGFiZXJtYW4pOiBoYW5kbGUgcHVzaGJhY2sKK3N0YXRpYyB2b2lkIHB1dGJ1Zih1cGJfcGJfZW5jb2RlciAqZSwgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbGVuKSB7CisgIHNpemVfdCBuID0gdXBiX2J5dGVzc2lua19wdXRidWYoZS0+b3V0cHV0XywgZS0+c3ViYywgYnVmLCBsZW4sIE5VTEwpOworICBVUEJfQVNTRVJUX1ZBUihuLCBuID09IGxlbik7Cit9CisKK3N0YXRpYyB1cGJfcGJfZW5jb2Rlcl9zZWdtZW50ICp0b3AodXBiX3BiX2VuY29kZXIgKmUpIHsKKyAgcmV0dXJuICZlLT5zZWdidWZbKmUtPnRvcF07Cit9CisKKy8vIENhbGwgdG8gZW5zdXJlIHRoYXQgYXQgbGVhc3QgImJ5dGVzIiBieXRlcyBhcmUgYXZhaWxhYmxlIGZvciB3cml0aW5nIGF0CisvLyBlLT5wdHIuICBSZXR1cm5zIGZhbHNlIGlmIHRoZSBieXRlcyBjb3VsZCBub3QgYmUgYWxsb2NhdGVkLgorc3RhdGljIGJvb2wgcmVzZXJ2ZSh1cGJfcGJfZW5jb2RlciAqZSwgc2l6ZV90IGJ5dGVzKSB7CisgIGlmICgoZS0+bGltaXQgLSBlLT5wdHIpIDwgYnl0ZXMpIHsKKyAgICBzaXplX3QgbmVlZGVkID0gYnl0ZXMgKyAoZS0+cHRyIC0gZS0+YnVmKTsKKyAgICBzaXplX3Qgb2xkX3NpemUgPSBlLT5saW1pdCAtIGUtPmJ1ZjsKKyAgICBzaXplX3QgbmV3X3NpemUgPSBvbGRfc2l6ZTsKKyAgICB3aGlsZSAobmV3X3NpemUgPCBuZWVkZWQpIHsKKyAgICAgIG5ld19zaXplICo9IDI7CisgICAgfQorCisgICAgY2hhciAqcmVhbGxvY19mcm9tID0gKGUtPmJ1ZiA9PSBlLT5pbml0YnVmKSA/IE5VTEwgOiBlLT5idWY7CisgICAgY2hhciAqbmV3X2J1ZiA9IHJlYWxsb2MocmVhbGxvY19mcm9tLCBuZXdfc2l6ZSk7CisKKyAgICBpZiAobmV3X2J1ZiA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKHJlYWxsb2NfZnJvbSA9PSBOVUxMKSB7CisgICAgICBtZW1jcHkobmV3X2J1ZiwgZS0+aW5pdGJ1Ziwgb2xkX3NpemUpOworICAgIH0KKworICAgIGUtPnB0ciA9IG5ld19idWYgKyAoZS0+cHRyIC0gZS0+YnVmKTsKKyAgICBlLT5ydW5iZWdpbiA9IG5ld19idWYgKyAoZS0+cnVuYmVnaW4gLSBlLT5idWYpOworICAgIGUtPmxpbWl0ID0gbmV3X2J1ZiArIG5ld19zaXplOworICAgIGUtPmJ1ZiA9IG5ld19idWY7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gQ2FsbCB3aGVuICJieXRlcyIgYnl0ZXMgaGF2ZSBiZWVuIHdyaXR0ZSBhdCBlLT5wdHIuICBUaGUgY2FsbGVyICptdXN0KiBoYXZlCisvLyBwcmV2aW91c2x5IGNhbGxlZCByZXNlcnZlKCkgd2l0aCBhdCBsZWFzdCB0aGlzIG1hbnkgYnl0ZXMuCitzdGF0aWMgdm9pZCBlbmNvZGVyX2FkdmFuY2UodXBiX3BiX2VuY29kZXIgKmUsIHNpemVfdCBieXRlcykgeworICBhc3NlcnQoKGUtPmxpbWl0IC0gZS0+cHRyKSA+PSBieXRlcyk7CisgIGUtPnB0ciArPSBieXRlczsKK30KKworLy8gQ2FsbCB3aGVuIGFsbCBvZiB0aGUgYnl0ZXMgZm9yIGEgaGFuZGxlciBoYXZlIGJlZW4gd3JpdHRlbi4gIEZsdXNoZXMgdGhlCisvLyBieXRlcyBpZiBwb3NzaWJsZSBhbmQgbmVjZXNzYXJ5LCByZXR1cm5pbmcgZmFsc2UgaWYgdGhpcyBmYWlsZWQuCitzdGF0aWMgYm9vbCBjb21taXQodXBiX3BiX2VuY29kZXIgKmUpIHsKKyAgaWYgKCFlLT50b3ApIHsKKyAgICAvLyBXZSBhcmVuJ3QgaW5zaWRlIGEgZGVsaW1pdGVkIHJlZ2lvbi4gIEZsdXNoIG91ciBhY2N1bXVsYXRlZCBieXRlcyB0bworICAgIC8vIHRoZSBvdXRwdXQuCisgICAgLy8KKyAgICAvLyBUT0RPKGhhYmVybWFuKTogaW4gdGhlIGZ1dHVyZSB3ZSBtYXkgd2FudCB0byBkZWxheSBmbHVzaGluZyBmb3IKKyAgICAvLyBlZmZpY2llbmN5IHJlYXNvbnMuCisgICAgcHV0YnVmKGUsIGUtPmJ1ZiwgZS0+cHRyIC0gZS0+YnVmKTsKKyAgICBlLT5wdHIgPSBlLT5idWY7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gV3JpdGVzIHRoZSBnaXZlbiBieXRlcyB0byB0aGUgYnVmZmVyLCBoYW5kbGluZyByZXNlcnZlL2FkdmFuY2UuCitzdGF0aWMgYm9vbCBlbmNvZGVfYnl0ZXModXBiX3BiX2VuY29kZXIgKmUsIGNvbnN0IHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pIHsKKyAgaWYgKCFyZXNlcnZlKGUsIGxlbikpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBtZW1jcHkoZS0+cHRyLCBkYXRhLCBsZW4pOworICBlbmNvZGVyX2FkdmFuY2UoZSwgbGVuKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIEZpbmlzaCB0aGUgY3VycmVudCBydW4gYnkgYWRkaW5nIHRoZSBydW4gdG90YWxzIHRvIHRoZSBzZWdtZW50IGFuZCBtZXNzYWdlCisvLyBsZW5ndGguCitzdGF0aWMgdm9pZCBhY2N1bXVsYXRlKHVwYl9wYl9lbmNvZGVyICplKSB7CisgIGFzc2VydChlLT5wdHIgPj0gZS0+cnVuYmVnaW4pOworICBzaXplX3QgcnVuX2xlbiA9IGUtPnB0ciAtIGUtPnJ1bmJlZ2luOworICBlLT5zZWdwdHItPnNlZ2xlbiArPSBydW5fbGVuOworICB0b3AoZSktPm1zZ2xlbiArPSBydW5fbGVuOworICBlLT5ydW5iZWdpbiA9IGUtPnB0cjsKK30KKworLy8gQ2FsbCB0byBpbmRpY2F0ZSB0aGUgc3RhcnQgb2YgZGVsaW1pdGVkIHJlZ2lvbiBmb3Igd2hpY2ggdGhlIGZ1bGwgbGVuZ3RoIGlzCisvLyBub3QgeWV0IGtub3duLiAgQWxsIGRhdGEgd2lsbCBiZSBidWZmZXJlZCB1bnRpbCB0aGUgbGVuZ3RoIGlzIGtub3duLgorLy8gRGVsaW1pdGVkIHJlZ2lvbnMgbWF5IGJlIG5lc3RlZDsgdGhlaXIgbGVuZ3RocyB3aWxsIGFsbCBiZSB0cmFja2VkIHByb3Blcmx5Lgorc3RhdGljIGJvb2wgc3RhcnRfZGVsaW0odXBiX3BiX2VuY29kZXIgKmUpIHsKKyAgaWYgKGUtPnRvcCkgeworICAgIC8vIFdlIGFyZSBhbHJlYWR5IGJ1ZmZlcmluZywgYWR2YW5jZSB0byB0aGUgbmV4dCBzZWdtZW50IGFuZCBwdXNoIGl0IG9uIHRoZQorICAgIC8vIHN0YWNrLgorICAgIGFjY3VtdWxhdGUoZSk7CisKKyAgICBpZiAoKytlLT50b3AgPT0gZS0+c3RhY2tsaW1pdCkgeworICAgICAgLy8gVE9ETyhoYWJlcm1hbik6IGdyb3cgc3RhY2s/CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKCsrZS0+c2VncHRyID09IGUtPnNlZ2xpbWl0KSB7CisgICAgICB1cGJfcGJfZW5jb2Rlcl9zZWdtZW50ICpyZWFsbG9jX2Zyb20gPQorICAgICAgICAgIChlLT5zZWdidWYgPT0gZS0+c2VnaW5pdGJ1ZikgPyBOVUxMIDogZS0+c2VnYnVmOworICAgICAgc2l6ZV90IG9sZF9zaXplID0KKyAgICAgICAgICAoZS0+c2VnbGltaXQgLSBlLT5zZWdidWYpICogc2l6ZW9mKHVwYl9wYl9lbmNvZGVyX3NlZ21lbnQpOworICAgICAgc2l6ZV90IG5ld19zaXplID0gb2xkX3NpemUgKiAyOworICAgICAgdXBiX3BiX2VuY29kZXJfc2VnbWVudCAqbmV3X2J1ZiA9IHJlYWxsb2MocmVhbGxvY19mcm9tLCBuZXdfc2l6ZSk7CisKKyAgICAgIGlmIChuZXdfYnVmID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBpZiAocmVhbGxvY19mcm9tID09IE5VTEwpIHsKKyAgICAgICAgbWVtY3B5KG5ld19idWYsIGUtPnNlZ2luaXRidWYsIG9sZF9zaXplKTsKKyAgICAgIH0KKworICAgICAgZS0+c2VncHRyID0gbmV3X2J1ZiArIChlLT5zZWdwdHIgLSBlLT5zZWdidWYpOworICAgICAgZS0+c2VnbGltaXQgPSBuZXdfYnVmICsgKG5ld19zaXplIC8gc2l6ZW9mKHVwYl9wYl9lbmNvZGVyX3NlZ21lbnQpKTsKKyAgICAgIGUtPnNlZ2J1ZiA9IG5ld19idWY7CisgICAgfQorICB9IGVsc2UgeworICAgIC8vIFdlIHdlcmUgcHJldmlvdXNseSBhdCB0aGUgdG9wIGxldmVsLCBzdGFydCBidWZmZXJpbmcuCisgICAgZS0+c2VncHRyID0gZS0+c2VnYnVmOworICAgIGUtPnRvcCA9IGUtPnN0YWNrOworICAgIGUtPnJ1bmJlZ2luID0gZS0+cHRyOworICB9CisKKyAgKmUtPnRvcCA9IGUtPnNlZ3B0ciAtIGUtPnNlZ2J1ZjsKKyAgZS0+c2VncHRyLT5zZWdsZW4gPSAwOworICBlLT5zZWdwdHItPm1zZ2xlbiA9IDA7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIENhbGwgdG8gaW5kaWNhdGUgdGhlIGVuZCBvZiBhIGRlbGltaXRlZCByZWdpb24uICBXZSBub3cga25vdyB0aGUgbGVuZ3RoIG9mCisvLyB0aGUgZGVsaW1pdGVkIHJlZ2lvbi4gIElmIHdlIGFyZSBub3QgbmVzdGVkIGluc2lkZSBhbnkgb3RoZXIgZGVsaW1pdGVkCisvLyByZWdpb25zLCB3ZSBjYW4gbm93IGVtaXQgYWxsIG9mIHRoZSBidWZmZXJlZCBkYXRhIHdlIGFjY3VtdWxhdGVkLgorc3RhdGljIGJvb2wgZW5kX2RlbGltKHVwYl9wYl9lbmNvZGVyICplKSB7CisgIGFjY3VtdWxhdGUoZSk7CisgIHNpemVfdCBtc2dsZW4gPSB0b3AoZSktPm1zZ2xlbjsKKworICBpZiAoZS0+dG9wID09IGUtPnN0YWNrKSB7CisgICAgLy8gQWxsIGxlbmd0aHMgYXJlIG5vdyBhdmFpbGFibGUsIGVtaXQgYWxsIGJ1ZmZlcmVkIGRhdGEuCisgICAgY2hhciBidWZbVVBCX1BCX1ZBUklOVF9NQVhfTEVOXTsKKyAgICB1cGJfcGJfZW5jb2Rlcl9zZWdtZW50ICpzOworICAgIGNvbnN0IGNoYXIgKnB0ciA9IGUtPmJ1ZjsKKyAgICBmb3IgKHMgPSBlLT5zZWdidWY7IHMgPD0gZS0+c2VncHRyOyBzKyspIHsKKyAgICAgIHNpemVfdCBsZW5ieXRlcyA9IHVwYl92ZW5jb2RlNjQocy0+bXNnbGVuLCBidWYpOworICAgICAgcHV0YnVmKGUsIGJ1ZiwgbGVuYnl0ZXMpOworICAgICAgcHV0YnVmKGUsIHB0ciwgcy0+c2VnbGVuKTsKKyAgICAgIHB0ciArPSBzLT5zZWdsZW47CisgICAgfQorCisgICAgZS0+cHRyID0gZS0+YnVmOworICAgIGUtPnRvcCA9IE5VTEw7CisgIH0gZWxzZSB7CisgICAgLy8gTmVlZCB0byBrZWVwIGJ1ZmZlcmluZzsgcHJvcGFnYXRlIGxlbmd0aCBpbmZvIGludG8gZW5jbG9zaW5nIHN1Ym1lc3NhZ2VzLgorICAgIC0tZS0+dG9wOworICAgIHRvcChlKS0+bXNnbGVuICs9IG1zZ2xlbiArIHVwYl92YXJpbnRfc2l6ZShtc2dsZW4pOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKworLyogdGFnX3QgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gQSBwcmVjb21wdXRlZCAocHJlLWVuY29kZWQpIHRhZyBhbmQgbGVuZ3RoLgorCit0eXBlZGVmIHN0cnVjdCB7CisgIHVpbnQ4X3QgYnl0ZXM7CisgIGNoYXIgdGFnWzddOworfSB0YWdfdDsKKworLy8gQWxsb2NhdGVzIGEgbmV3IHRhZyBmb3IgdGhpcyBmaWVsZCwgYW5kIHNldHMgaXQgaW4gdGhlc2UgaGFuZGxlcmF0dHIuCitzdGF0aWMgdm9pZCBuZXdfdGFnKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLCB1cGJfd2lyZXR5cGVfdCB3dCwKKyAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKSB7CisgIHVpbnQzMl90IG4gPSB1cGJfZmllbGRkZWZfbnVtYmVyKGYpOworCisgIHRhZ190ICp0YWcgPSBtYWxsb2Moc2l6ZW9mKHRhZ190KSk7CisgIHRhZy0+Ynl0ZXMgPSB1cGJfdmVuY29kZTY0KChuIDw8IDMpIHwgd3QsIHRhZy0+dGFnKTsKKworICB1cGJfaGFuZGxlcmF0dHJfaW5pdChhdHRyKTsKKyAgdXBiX2hhbmRsZXJhdHRyX3NldGhhbmRsZXJkYXRhKGF0dHIsIHRhZyk7CisgIHVwYl9oYW5kbGVyc19hZGRjbGVhbnVwKGgsIHRhZywgZnJlZSk7Cit9CisKK3N0YXRpYyBib29sIGVuY29kZV90YWcodXBiX3BiX2VuY29kZXIgKmUsIGNvbnN0IHRhZ190ICp0YWcpIHsKKyAgcmV0dXJuIGVuY29kZV9ieXRlcyhlLCB0YWctPnRhZywgdGFnLT5ieXRlcyk7Cit9CisKKworLyogZW5jb2Rpbmcgb2Ygd2lyZSB0eXBlcyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIGJvb2wgZW5jb2RlX2ZpeGVkNjQodXBiX3BiX2VuY29kZXIgKmUsIHVpbnQ2NF90IHZhbCkgeworICAvLyBUT0RPKGhhYmVybWFuKTogYnl0ZS1zd2FwIGZvciBiaWcgZW5kaWFuLgorICByZXR1cm4gZW5jb2RlX2J5dGVzKGUsICZ2YWwsIHNpemVvZih1aW50NjRfdCkpOworfQorCitzdGF0aWMgYm9vbCBlbmNvZGVfZml4ZWQzMih1cGJfcGJfZW5jb2RlciAqZSwgdWludDMyX3QgdmFsKSB7CisgIC8vIFRPRE8oaGFiZXJtYW4pOiBieXRlLXN3YXAgZm9yIGJpZyBlbmRpYW4uCisgIHJldHVybiBlbmNvZGVfYnl0ZXMoZSwgJnZhbCwgc2l6ZW9mKHVpbnQzMl90KSk7Cit9CisKK3N0YXRpYyBib29sIGVuY29kZV92YXJpbnQodXBiX3BiX2VuY29kZXIgKmUsIHVpbnQ2NF90IHZhbCkgeworICBpZiAoIXJlc2VydmUoZSwgVVBCX1BCX1ZBUklOVF9NQVhfTEVOKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGVuY29kZXJfYWR2YW5jZShlLCB1cGJfdmVuY29kZTY0KHZhbCwgZS0+cHRyKSk7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgdWludDY0X3QgZGJsMnVpbnQ2NChkb3VibGUgZCkgeworICB1aW50NjRfdCByZXQ7CisgIG1lbWNweSgmcmV0LCAmZCwgc2l6ZW9mKHVpbnQ2NF90KSk7CisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyB1aW50MzJfdCBmbHQydWludDMyKGZsb2F0IGQpIHsKKyAgdWludDMyX3QgcmV0OworICBtZW1jcHkoJnJldCwgJmQsIHNpemVvZih1aW50MzJfdCkpOworICByZXR1cm4gcmV0OworfQorCisKKy8qIGVuY29kaW5nIG9mIHByb3RvIHR5cGVzICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3N0YXRpYyBib29sIHN0YXJ0bXNnKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkKSB7CisgIHVwYl9wYl9lbmNvZGVyICplID0gYzsKKyAgVVBCX1VOVVNFRChoZCk7CisgIGlmIChlLT5kZXB0aCsrID09IDApIHsKKyAgICB1cGJfYnl0ZXNzaW5rX3N0YXJ0KGUtPm91dHB1dF8sIDAsICZlLT5zdWJjKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgZW5kbXNnKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkLCB1cGJfc3RhdHVzICpzdGF0dXMpIHsKKyAgdXBiX3BiX2VuY29kZXIgKmUgPSBjOworICBVUEJfVU5VU0VEKGhkKTsKKyAgVVBCX1VOVVNFRChzdGF0dXMpOworICBpZiAoLS1lLT5kZXB0aCA9PSAwKSB7CisgICAgdXBiX2J5dGVzc2lua19lbmQoZS0+b3V0cHV0Xyk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB2b2lkICplbmNvZGVfc3RhcnRkZWxpbWZpZWxkKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkKSB7CisgIGJvb2wgb2sgPSBlbmNvZGVfdGFnKGMsIGhkKSAmJiBjb21taXQoYykgJiYgc3RhcnRfZGVsaW0oYyk7CisgIHJldHVybiBvayA/IGMgOiBVUEJfQlJFQUs7Cit9CisKK3N0YXRpYyBib29sIGVuY29kZV9lbmRkZWxpbWZpZWxkKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICByZXR1cm4gZW5kX2RlbGltKGMpOworfQorCitzdGF0aWMgdm9pZCAqZW5jb2RlX3N0YXJ0Z3JvdXAodm9pZCAqYywgY29uc3Qgdm9pZCAqaGQpIHsKKyAgcmV0dXJuIChlbmNvZGVfdGFnKGMsIGhkKSAmJiBjb21taXQoYykpID8gYyA6IFVQQl9CUkVBSzsKK30KKworc3RhdGljIGJvb2wgZW5jb2RlX2VuZGdyb3VwKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkKSB7CisgIHJldHVybiBlbmNvZGVfdGFnKGMsIGhkKSAmJiBjb21taXQoYyk7Cit9CisKK3N0YXRpYyB2b2lkICplbmNvZGVfc3RhcnRzdHIodm9pZCAqYywgY29uc3Qgdm9pZCAqaGQsIHNpemVfdCBzaXplX2hpbnQpIHsKKyAgVVBCX1VOVVNFRChzaXplX2hpbnQpOworICByZXR1cm4gZW5jb2RlX3N0YXJ0ZGVsaW1maWVsZChjLCBoZCk7Cit9CisKK3N0YXRpYyBzaXplX3QgZW5jb2RlX3N0cmJ1Zih2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgY29uc3QgY2hhciAqYnVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4sIGNvbnN0IHVwYl9idWZoYW5kbGUgKmgpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIFVQQl9VTlVTRUQoaCk7CisgIHJldHVybiBlbmNvZGVfYnl0ZXMoYywgYnVmLCBsZW4pID8gbGVuIDogMDsKK30KKworI2RlZmluZSBUKHR5cGUsIGN0eXBlLCBjb252ZXJ0LCBlbmNvZGUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgZW5jb2RlX3NjYWxhcl8jI3R5cGUodm9pZCAqZSwgY29uc3Qgdm9pZCAqaGQsIGN0eXBlIHZhbCkgeyBcCisgICAgcmV0dXJuIGVuY29kZV90YWcoZSwgaGQpICYmIGVuY29kZShlLCAoY29udmVydCkodmFsKSkgJiYgY29tbWl0KGUpOyAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgZW5jb2RlX3BhY2tlZF8jI3R5cGUodm9pZCAqZSwgY29uc3Qgdm9pZCAqaGQsIGN0eXBlIHZhbCkgeyBcCisgICAgVVBCX1VOVVNFRChoZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBlbmNvZGUoZSwgKGNvbnZlcnQpKHZhbCkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCitUKGRvdWJsZSwgICBkb3VibGUsICAgZGJsMnVpbnQ2NCwgICBlbmNvZGVfZml4ZWQ2NCkKK1QoZmxvYXQsICAgIGZsb2F0LCAgICBmbHQydWludDMyLCAgIGVuY29kZV9maXhlZDMyKTsKK1QoaW50NjQsICAgIGludDY0X3QsICB1aW50NjRfdCwgICAgIGVuY29kZV92YXJpbnQpOworVChpbnQzMiwgICAgaW50MzJfdCwgIHVpbnQzMl90LCAgICAgZW5jb2RlX3ZhcmludCk7CitUKGZpeGVkNjQsICB1aW50NjRfdCwgdWludDY0X3QsICAgICBlbmNvZGVfZml4ZWQ2NCk7CitUKGZpeGVkMzIsICB1aW50MzJfdCwgdWludDMyX3QsICAgICBlbmNvZGVfZml4ZWQzMik7CitUKGJvb2wsICAgICBib29sLCAgICAgYm9vbCwgICAgICAgICBlbmNvZGVfdmFyaW50KTsKK1QodWludDMyLCAgIHVpbnQzMl90LCB1aW50MzJfdCwgICAgIGVuY29kZV92YXJpbnQpOworVCh1aW50NjQsICAgdWludDY0X3QsIHVpbnQ2NF90LCAgICAgZW5jb2RlX3ZhcmludCk7CitUKGVudW0sICAgICBpbnQzMl90LCAgdWludDMyX3QsICAgICBlbmNvZGVfdmFyaW50KTsKK1Qoc2ZpeGVkMzIsIGludDMyX3QsICB1aW50MzJfdCwgICAgIGVuY29kZV9maXhlZDMyKTsKK1Qoc2ZpeGVkNjQsIGludDY0X3QsICB1aW50NjRfdCwgICAgIGVuY29kZV9maXhlZDY0KTsKK1Qoc2ludDMyLCAgIGludDMyX3QsICB1cGJfenplbmNfMzIsIGVuY29kZV92YXJpbnQpOworVChzaW50NjQsICAgaW50NjRfdCwgIHVwYl96emVuY182NCwgZW5jb2RlX3ZhcmludCk7CisKKyN1bmRlZiBUCisKKworLyogY29kZSB0byBidWlsZCB0aGUgaGFuZGxlcnMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIHZvaWQgbmV3aGFuZGxlcnNfY2FsbGJhY2soY29uc3Qgdm9pZCAqY2xvc3VyZSwgdXBiX2hhbmRsZXJzICpoKSB7CisgIFVQQl9VTlVTRUQoY2xvc3VyZSk7CisKKyAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0bXNnKGgsIHN0YXJ0bXNnLCBOVUxMKTsKKyAgdXBiX2hhbmRsZXJzX3NldGVuZG1zZyhoLCBlbmRtc2csIE5VTEwpOworCisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfaGFuZGxlcnNfbXNnZGVmKGgpOworICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaTsKKyAgZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmksIG0pOworICAgICAgIXVwYl9tc2dfZmllbGRfZG9uZSgmaSk7CisgICAgICB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpKTsKKyAgICBib29sIHBhY2tlZCA9IHVwYl9maWVsZGRlZl9pc3NlcShmKSAmJiB1cGJfZmllbGRkZWZfaXNwcmltaXRpdmUoZikgJiYKKyAgICAgICAgICAgICAgICAgIHVwYl9maWVsZGRlZl9wYWNrZWQoZik7CisgICAgdXBiX2hhbmRsZXJhdHRyIGF0dHI7CisgICAgdXBiX3dpcmV0eXBlX3Qgd3QgPQorICAgICAgICBwYWNrZWQgPyBVUEJfV0lSRV9UWVBFX0RFTElNSVRFRAorICAgICAgICAgICAgICAgOiB1cGJfcGJfbmF0aXZlX3dpcmVfdHlwZXNbdXBiX2ZpZWxkZGVmX2Rlc2NyaXB0b3J0eXBlKGYpXTsKKworICAgIC8vIFByZS1lbmNvZGUgdGhlIHRhZyBmb3IgdGhpcyBmaWVsZC4KKyAgICBuZXdfdGFnKGgsIGYsIHd0LCAmYXR0cik7CisKKyAgICBpZiAocGFja2VkKSB7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzZXEoaCwgZiwgZW5jb2RlX3N0YXJ0ZGVsaW1maWVsZCwgJmF0dHIpOworICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHNlcShoLCBmLCBlbmNvZGVfZW5kZGVsaW1maWVsZCwgJmF0dHIpOworICAgIH0KKworI2RlZmluZSBUKHVwcGVyLCBsb3dlciwgdXBidHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfIyN1cHBlcjogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmIChwYWNrZWQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgdXBiX2hhbmRsZXJzX3NldCMjdXBidHlwZShoLCBmLCBlbmNvZGVfcGFja2VkXyMjbG93ZXIsICZhdHRyKTsgXAorICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgdXBiX2hhbmRsZXJzX3NldCMjdXBidHlwZShoLCBmLCBlbmNvZGVfc2NhbGFyXyMjbG93ZXIsICZhdHRyKTsgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGJyZWFrOworCisgICAgc3dpdGNoICh1cGJfZmllbGRkZWZfZGVzY3JpcHRvcnR5cGUoZikpIHsKKyAgICAgIFQoRE9VQkxFLCAgIGRvdWJsZSwgICBkb3VibGUpOworICAgICAgVChGTE9BVCwgICAgZmxvYXQsICAgIGZsb2F0KTsKKyAgICAgIFQoSU5UNjQsICAgIGludDY0LCAgICBpbnQ2NCk7CisgICAgICBUKElOVDMyLCAgICBpbnQzMiwgICAgaW50MzIpOworICAgICAgVChGSVhFRDY0LCAgZml4ZWQ2NCwgIHVpbnQ2NCk7CisgICAgICBUKEZJWEVEMzIsICBmaXhlZDMyLCAgdWludDMyKTsKKyAgICAgIFQoQk9PTCwgICAgIGJvb2wsICAgICBib29sKTsKKyAgICAgIFQoVUlOVDMyLCAgIHVpbnQzMiwgICB1aW50MzIpOworICAgICAgVChVSU5UNjQsICAgdWludDY0LCAgIHVpbnQ2NCk7CisgICAgICBUKEVOVU0sICAgICBlbnVtLCAgICAgaW50MzIpOworICAgICAgVChTRklYRUQzMiwgc2ZpeGVkMzIsIGludDMyKTsKKyAgICAgIFQoU0ZJWEVENjQsIHNmaXhlZDY0LCBpbnQ2NCk7CisgICAgICBUKFNJTlQzMiwgICBzaW50MzIsICAgaW50MzIpOworICAgICAgVChTSU5UNjQsICAgc2ludDY0LCAgIGludDY0KTsKKyAgICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9TVFJJTkc6CisgICAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfQllURVM6CisgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHN0cihoLCBmLCBlbmNvZGVfc3RhcnRzdHIsICZhdHRyKTsKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN0cihoLCBmLCBlbmNvZGVfZW5kZGVsaW1maWVsZCwgJmF0dHIpOworICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKGgsIGYsIGVuY29kZV9zdHJidWYsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9ERVNDUklQVE9SX1RZUEVfTUVTU0FHRToKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c3VibXNnKGgsIGYsIGVuY29kZV9zdGFydGRlbGltZmllbGQsICZhdHRyKTsKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN1Ym1zZyhoLCBmLCBlbmNvZGVfZW5kZGVsaW1maWVsZCwgJmF0dHIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVVBCX0RFU0NSSVBUT1JfVFlQRV9HUk9VUDogeworICAgICAgICAvLyBFbmRncm91cCB0YWtlcyBhIGRpZmZlcmVudCB0YWcgKHdpcmVfdHlwZSA9IEVORF9HUk9VUCkuCisgICAgICAgIHVwYl9oYW5kbGVyYXR0ciBhdHRyMjsKKyAgICAgICAgbmV3X3RhZyhoLCBmLCBVUEJfV0lSRV9UWVBFX0VORF9HUk9VUCwgJmF0dHIyKTsKKworICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdWJtc2coaCwgZiwgZW5jb2RlX3N0YXJ0Z3JvdXAsICZhdHRyKTsKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN1Ym1zZyhoLCBmLCBlbmNvZGVfZW5kZ3JvdXAsICZhdHRyMik7CisKKyAgICAgICAgdXBiX2hhbmRsZXJhdHRyX3VuaW5pdCgmYXR0cjIpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisKKyN1bmRlZiBUCisKKyAgICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZhdHRyKTsKKyAgfQorfQorCisKKy8qIHB1YmxpYyBBUEkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX3BiX2VuY29kZXJfbmV3aGFuZGxlcnMoY29uc3QgdXBiX21zZ2RlZiAqbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19uZXdmcm96ZW4obSwgb3duZXIsIG5ld2hhbmRsZXJzX2NhbGxiYWNrLCBOVUxMKTsKK30KKworI2RlZmluZSBBUlJBWVNJWkUoeCkgKHNpemVvZih4KSAvIHNpemVvZih4WzBdKSkKKwordm9pZCB1cGJfcGJfZW5jb2Rlcl9pbml0KHVwYl9wYl9lbmNvZGVyICplLCBjb25zdCB1cGJfaGFuZGxlcnMgKmgpIHsKKyAgZS0+b3V0cHV0XyA9IE5VTEw7CisgIGUtPnN1YmMgPSBOVUxMOworICBlLT5idWYgPSBlLT5pbml0YnVmOworICBlLT5wdHIgPSBlLT5idWY7CisgIGUtPmxpbWl0ID0gZS0+YnVmICsgQVJSQVlTSVpFKGUtPmluaXRidWYpOworICBlLT5zZWdidWYgPSBlLT5zZWdpbml0YnVmOworICBlLT5zZWdsaW1pdCA9IGUtPnNlZ2J1ZiArIEFSUkFZU0laRShlLT5zZWdpbml0YnVmKTsKKyAgZS0+c3RhY2tsaW1pdCA9IGUtPnN0YWNrICsgQVJSQVlTSVpFKGUtPnN0YWNrKTsKKyAgdXBiX3NpbmtfcmVzZXQoJmUtPmlucHV0XywgaCwgZSk7Cit9CisKK3ZvaWQgdXBiX3BiX2VuY29kZXJfdW5pbml0KHVwYl9wYl9lbmNvZGVyICplKSB7CisgIGlmIChlLT5idWYgIT0gZS0+aW5pdGJ1ZikgeworICAgIGZyZWUoZS0+YnVmKTsKKyAgfQorCisgIGlmIChlLT5zZWdidWYgIT0gZS0+c2VnaW5pdGJ1ZikgeworICAgIGZyZWUoZS0+c2VnYnVmKTsKKyAgfQorfQorCit2b2lkIHVwYl9wYl9lbmNvZGVyX3Jlc2V0b3V0cHV0KHVwYl9wYl9lbmNvZGVyICplLCB1cGJfYnl0ZXNzaW5rICpvdXRwdXQpIHsKKyAgdXBiX3BiX2VuY29kZXJfcmVzZXQoZSk7CisgIGUtPm91dHB1dF8gPSBvdXRwdXQ7CisgIGUtPnN1YmMgPSBvdXRwdXQtPmNsb3N1cmU7Cit9CisKK3ZvaWQgdXBiX3BiX2VuY29kZXJfcmVzZXQodXBiX3BiX2VuY29kZXIgKmUpIHsKKyAgZS0+c2VncHRyID0gTlVMTDsKKyAgZS0+dG9wID0gTlVMTDsKKyAgZS0+ZGVwdGggPSAwOworfQorCit1cGJfc2luayAqdXBiX3BiX2VuY29kZXJfaW5wdXQodXBiX3BiX2VuY29kZXIgKmUpIHsgcmV0dXJuICZlLT5pbnB1dF87IH0KKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKi8KKworCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKwordXBiX2RlZiAqKnVwYl9sb2FkX2RlZnNfZnJvbV9kZXNjcmlwdG9yKGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IGxlbiwgaW50ICpuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKm93bmVyLCB1cGJfc3RhdHVzICpzdGF0dXMpIHsKKyAgLy8gQ3JlYXRlIGhhbmRsZXJzLgorICBjb25zdCB1cGJfaGFuZGxlcnMgKnJlYWRlcl9oID0gdXBiX2Rlc2NyZWFkZXJfbmV3aGFuZGxlcnMoJnJlYWRlcl9oKTsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHMgb3B0czsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfaW5pdCgmb3B0cywgcmVhZGVyX2gpOworICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICpkZWNvZGVyX20gPQorICAgICAgdXBiX3BiZGVjb2Rlcm1ldGhvZF9uZXcoJm9wdHMsICZkZWNvZGVyX20pOworCisgIHVwYl9wYmRlY29kZXIgZGVjb2RlcjsKKyAgdXBiX2Rlc2NyZWFkZXIgcmVhZGVyOworCisgIHVwYl9wYmRlY29kZXJfaW5pdCgmZGVjb2RlciwgZGVjb2Rlcl9tLCBzdGF0dXMpOworICB1cGJfZGVzY3JlYWRlcl9pbml0KCZyZWFkZXIsIHJlYWRlcl9oLCBzdGF0dXMpOworICB1cGJfcGJkZWNvZGVyX3Jlc2V0b3V0cHV0KCZkZWNvZGVyLCB1cGJfZGVzY3JlYWRlcl9pbnB1dCgmcmVhZGVyKSk7CisKKyAgLy8gUHVzaCBpbnB1dCBkYXRhLgorICBib29sIG9rID0gdXBiX2J1ZnNyY19wdXRidWYoc3RyLCBsZW4sIHVwYl9wYmRlY29kZXJfaW5wdXQoJmRlY29kZXIpKTsKKworICB1cGJfZGVmICoqcmV0ID0gTlVMTDsKKworICBpZiAoIW9rKSBnb3RvIGNsZWFudXA7CisgIHVwYl9kZWYgKipkZWZzID0gdXBiX2Rlc2NyZWFkZXJfZ2V0ZGVmcygmcmVhZGVyLCBvd25lciwgbik7CisgIHJldCA9IG1hbGxvYyhzaXplb2YodXBiX2RlZiopICogKCpuKSk7CisgIG1lbWNweShyZXQsIGRlZnMsIHNpemVvZih1cGJfZGVmKikgKiAoKm4pKTsKKworY2xlYW51cDoKKyAgdXBiX3BiZGVjb2Rlcl91bmluaXQoJmRlY29kZXIpOworICB1cGJfZGVzY3JlYWRlcl91bmluaXQoJnJlYWRlcik7CisgIHVwYl9oYW5kbGVyc191bnJlZihyZWFkZXJfaCwgJnJlYWRlcl9oKTsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZF91bnJlZihkZWNvZGVyX20sICZkZWNvZGVyX20pOworICByZXR1cm4gcmV0OworfQorCitib29sIHVwYl9sb2FkX2Rlc2NyaXB0b3JfaW50b19zeW10YWIodXBiX3N5bXRhYiAqcywgY29uc3QgY2hhciAqc3RyLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBpbnQgbjsKKyAgdXBiX2RlZiAqKmRlZnMgPSB1cGJfbG9hZF9kZWZzX2Zyb21fZGVzY3JpcHRvcihzdHIsIGxlbiwgJm4sICZkZWZzLCBzdGF0dXMpOworICBpZiAoIWRlZnMpIHJldHVybiBmYWxzZTsKKyAgYm9vbCBzdWNjZXNzID0gdXBiX3N5bXRhYl9hZGQocywgZGVmcywgbiwgJmRlZnMsIHN0YXR1cyk7CisgIGZyZWUoZGVmcyk7CisgIHJldHVybiBzdWNjZXNzOworfQorCitjaGFyICp1cGJfcmVhZGZpbGUoY29uc3QgY2hhciAqZmlsZW5hbWUsIHNpemVfdCAqbGVuKSB7CisgIEZJTEUgKmYgPSBmb3BlbihmaWxlbmFtZSwgInJiIik7CisgIGlmKCFmKSByZXR1cm4gTlVMTDsKKyAgaWYoZnNlZWsoZiwgMCwgU0VFS19FTkQpICE9IDApIGdvdG8gZXJyb3I7CisgIGxvbmcgc2l6ZSA9IGZ0ZWxsKGYpOworICBpZihzaXplIDwgMCkgZ290byBlcnJvcjsKKyAgaWYoZnNlZWsoZiwgMCwgU0VFS19TRVQpICE9IDApIGdvdG8gZXJyb3I7CisgIGNoYXIgKmJ1ZiA9IG1hbGxvYyhzaXplICsgMSk7CisgIGlmKHNpemUgJiYgZnJlYWQoYnVmLCBzaXplLCAxLCBmKSAhPSAxKSBnb3RvIGVycm9yOworICBmY2xvc2UoZik7CisgIGlmIChsZW4pICpsZW4gPSBzaXplOworICByZXR1cm4gYnVmOworCitlcnJvcjoKKyAgZmNsb3NlKGYpOworICByZXR1cm4gTlVMTDsKK30KKworYm9vbCB1cGJfbG9hZF9kZXNjcmlwdG9yX2ZpbGVfaW50b19zeW10YWIodXBiX3N5bXRhYiAqc3ltdGFiLCBjb25zdCBjaGFyICpmbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBzaXplX3QgbGVuOworICBjaGFyICpkYXRhID0gdXBiX3JlYWRmaWxlKGZuYW1lLCAmbGVuKTsKKyAgaWYgKCFkYXRhKSB7CisgICAgaWYgKHN0YXR1cykgdXBiX3N0YXR1c19zZXRlcnJmKHN0YXR1cywgIkNvdWxkbid0IHJlYWQgZmlsZTogJXMiLCBmbmFtZSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGJvb2wgc3VjY2VzcyA9IHVwYl9sb2FkX2Rlc2NyaXB0b3JfaW50b19zeW10YWIoc3ltdGFiLCBkYXRhLCBsZW4sIHN0YXR1cyk7CisgIGZyZWUoZGF0YSk7CisgIHJldHVybiBzdWNjZXNzOworfQorLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAwOSBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogT1BUOiBUaGlzIGlzIG5vdCBvcHRpbWl6ZWQgYXQgYWxsLiAgSXQgdXNlcyBwcmludGYoKSB3aGljaCBwYXJzZXMgdGhlIGZvcm1hdAorICogc3RyaW5nIGV2ZXJ5IHRpbWUsIGFuZCBpdCBhbGxvY2F0ZXMgbWVtb3J5IGZvciBldmVyeSBwdXQuCisgKi8KKworCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNpbmNsdWRlIDxmbG9hdC5oPgorI2luY2x1ZGUgPGludHR5cGVzLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworCisjZGVmaW5lIENIRUNLKHgpIGlmICgoeCkgPCAwKSBnb3RvIGVycjsKKworc3RhdGljIGNvbnN0IGNoYXIgKnNob3J0bmFtZShjb25zdCBjaGFyICpsb25nbmFtZSkgeworICBjb25zdCBjaGFyICpsYXN0ID0gc3RycmNocihsb25nbmFtZSwgJy4nKTsKKyAgcmV0dXJuIGxhc3QgPyBsYXN0ICsgMSA6IGxvbmduYW1lOworfQorCitzdGF0aWMgaW50IGluZGVudCh1cGJfdGV4dHByaW50ZXIgKnApIHsKKyAgaW50IGk7CisgIGlmICghcC0+c2luZ2xlX2xpbmVfKQorICAgIGZvciAoaSA9IDA7IGkgPCBwLT5pbmRlbnRfZGVwdGhfOyBpKyspCisgICAgICB1cGJfYnl0ZXNzaW5rX3B1dGJ1ZihwLT5vdXRwdXRfLCBwLT5zdWJjLCAiICAiLCAyLCBOVUxMKTsKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgZW5kZmllbGQodXBiX3RleHRwcmludGVyICpwKSB7CisgIGNvbnN0IGNoYXIgY2ggPSAocC0+c2luZ2xlX2xpbmVfID8gJyAnIDogJ1xuJyk7CisgIHVwYl9ieXRlc3NpbmtfcHV0YnVmKHAtPm91dHB1dF8sIHAtPnN1YmMsICZjaCwgMSwgTlVMTCk7CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IHB1dGVzY2FwZWQodXBiX3RleHRwcmludGVyICpwLCBjb25zdCBjaGFyICpidWYsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgYm9vbCBwcmVzZXJ2ZV91dGY4KSB7CisgIC8vIEJhc2VkIG9uIENFc2NhcGVJbnRlcm5hbCgpIGZyb20gR29vZ2xlJ3MgcHJvdG9idWYgcmVsZWFzZS4KKyAgY2hhciBkc3RidWZbNDA5Nl0sICpkc3QgPSBkc3RidWYsICpkc3RlbmQgPSBkc3RidWYgKyBzaXplb2YoZHN0YnVmKTsKKyAgY29uc3QgY2hhciAqZW5kID0gYnVmICsgbGVuOworCisgIC8vIEkgdGhpbmsgaGV4IGlzIHByZXR0aWVyIGFuZCBtb3JlIHVzZWZ1bCwgYnV0IHByb3RvMiB1c2VzIG9jdGFsOyBzaG91bGQKKyAgLy8gaW52ZXN0aWdhdGUgd2hldGhlciBpdCBjYW4gcGFyc2UgaGV4IGFsc28uCisgIGNvbnN0IGJvb2wgdXNlX2hleCA9IGZhbHNlOworICBib29sIGxhc3RfaGV4X2VzY2FwZSA9IGZhbHNlOyAvLyB0cnVlIGlmIGxhc3Qgb3V0cHV0IGNoYXIgd2FzIFx4Tk4KKworICBmb3IgKDsgYnVmIDwgZW5kOyBidWYrKykgeworICAgIGlmIChkc3RlbmQgLSBkc3QgPCA0KSB7CisgICAgICB1cGJfYnl0ZXNzaW5rX3B1dGJ1ZihwLT5vdXRwdXRfLCBwLT5zdWJjLCBkc3RidWYsIGRzdCAtIGRzdGJ1ZiwgTlVMTCk7CisgICAgICBkc3QgPSBkc3RidWY7CisgICAgfQorCisgICAgYm9vbCBpc19oZXhfZXNjYXBlID0gZmFsc2U7CisgICAgc3dpdGNoICgqYnVmKSB7CisgICAgICBjYXNlICdcbic6ICooZHN0KyspID0gJ1xcJzsgKihkc3QrKykgPSAnbic7ICBicmVhazsKKyAgICAgIGNhc2UgJ1xyJzogKihkc3QrKykgPSAnXFwnOyAqKGRzdCsrKSA9ICdyJzsgIGJyZWFrOworICAgICAgY2FzZSAnXHQnOiAqKGRzdCsrKSA9ICdcXCc7ICooZHN0KyspID0gJ3QnOyAgYnJlYWs7CisgICAgICBjYXNlICdcIic6ICooZHN0KyspID0gJ1xcJzsgKihkc3QrKykgPSAnXCInOyBicmVhazsKKyAgICAgIGNhc2UgJ1wnJzogKihkc3QrKykgPSAnXFwnOyAqKGRzdCsrKSA9ICdcJyc7IGJyZWFrOworICAgICAgY2FzZSAnXFwnOiAqKGRzdCsrKSA9ICdcXCc7ICooZHN0KyspID0gJ1xcJzsgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICAvLyBOb3RlIHRoYXQgaWYgd2UgZW1pdCBceE5OIGFuZCB0aGUgYnVmIGNoYXJhY3RlciBhZnRlciB0aGF0IGlzIGEgaGV4CisgICAgICAgIC8vIGRpZ2l0IHRoZW4gdGhhdCBkaWdpdCBtdXN0IGJlIGVzY2FwZWQgdG9vIHRvIHByZXZlbnQgaXQgYmVpbmcKKyAgICAgICAgLy8gaW50ZXJwcmV0ZWQgYXMgcGFydCBvZiB0aGUgY2hhcmFjdGVyIGNvZGUgYnkgQy4KKyAgICAgICAgaWYgKCghcHJlc2VydmVfdXRmOCB8fCAodWludDhfdCkqYnVmIDwgMHg4MCkgJiYKKyAgICAgICAgICAgICghaXNwcmludCgqYnVmKSB8fCAobGFzdF9oZXhfZXNjYXBlICYmIGlzeGRpZ2l0KCpidWYpKSkpIHsKKyAgICAgICAgICBzcHJpbnRmKGRzdCwgKHVzZV9oZXggPyAiXFx4JTAyeCIgOiAiXFwlMDNvIiksICh1aW50OF90KSpidWYpOworICAgICAgICAgIGlzX2hleF9lc2NhcGUgPSB1c2VfaGV4OworICAgICAgICAgIGRzdCArPSA0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICooZHN0KyspID0gKmJ1ZjsgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgbGFzdF9oZXhfZXNjYXBlID0gaXNfaGV4X2VzY2FwZTsKKyAgfQorICAvLyBGbHVzaCByZW1haW5pbmcgZGF0YS4KKyAgdXBiX2J5dGVzc2lua19wdXRidWYocC0+b3V0cHV0XywgcC0+c3ViYywgZHN0YnVmLCBkc3QgLSBkc3RidWYsIE5VTEwpOworICByZXR1cm4gMDsKK30KKworYm9vbCBwdXRmKHVwYl90ZXh0cHJpbnRlciAqcCwgY29uc3QgY2hhciAqZm10LCAuLi4pIHsKKyAgdmFfbGlzdCBhcmdzOworICB2YV9zdGFydChhcmdzLCBmbXQpOworCisgIC8vIFJ1biBvbmNlIHRvIGdldCB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcuCisgIHZhX2xpc3QgYXJnc19jb3B5OworICB2YV9jb3B5KGFyZ3NfY29weSwgYXJncyk7CisgIGludCBsZW4gPSB2c25wcmludGYoTlVMTCwgMCwgZm10LCBhcmdzX2NvcHkpOworICB2YV9lbmQoYXJnc19jb3B5KTsKKworICAvLyArIDEgZm9yIE5VTEwgdGVybWluYXRvciAodnNucHJpbnRmKCkgcmVxdWlyZXMgaXQgZXZlbiBpZiB3ZSBkb24ndCkuCisgIGNoYXIgKnN0ciA9IG1hbGxvYyhsZW4gKyAxKTsKKyAgaWYgKCFzdHIpIHJldHVybiBmYWxzZTsKKyAgaW50IHdyaXR0ZW4gPSB2c25wcmludGYoc3RyLCBsZW4gKyAxLCBmbXQsIGFyZ3MpOworICB2YV9lbmQoYXJncyk7CisgIFVQQl9BU1NFUlRfVkFSKHdyaXR0ZW4sIHdyaXR0ZW4gPT0gbGVuKTsKKworICBib29sIG9rID0gdXBiX2J5dGVzc2lua19wdXRidWYocC0+b3V0cHV0XywgcC0+c3ViYywgc3RyLCBsZW4sIE5VTEwpOworICBmcmVlKHN0cik7CisgIHJldHVybiBvazsKK30KKworCisvKiBoYW5kbGVycyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgYm9vbCB0ZXh0cHJpbnRlcl9zdGFydG1zZyh2b2lkICpjLCBjb25zdCB2b2lkICpoZCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgdXBiX3RleHRwcmludGVyICpwID0gYzsKKyAgaWYgKHAtPmluZGVudF9kZXB0aF8gPT0gMCkgeworICAgIHVwYl9ieXRlc3Npbmtfc3RhcnQocC0+b3V0cHV0XywgMCwgJnAtPnN1YmMpOworICB9CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCB0ZXh0cHJpbnRlcl9lbmRtc2codm9pZCAqYywgY29uc3Qgdm9pZCAqaGQsIHVwYl9zdGF0dXMgKnMpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIFVQQl9VTlVTRUQocyk7CisgIHVwYl90ZXh0cHJpbnRlciAqcCA9IGM7CisgIGlmIChwLT5pbmRlbnRfZGVwdGhfID09IDApIHsKKyAgICB1cGJfYnl0ZXNzaW5rX2VuZChwLT5vdXRwdXRfKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworI2RlZmluZSBUWVBFKG5hbWUsIGN0eXBlLCBmbXQpIFwKKyAgc3RhdGljIGJvb2wgdGV4dHByaW50ZXJfcHV0ICMjIG5hbWUodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLCBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eXBlIHZhbCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHVwYl90ZXh0cHJpbnRlciAqcCA9IGNsb3N1cmU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSBoYW5kbGVyX2RhdGE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgQ0hFQ0soaW5kZW50KHApKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHB1dGYocCwgIiVzOiAiIGZtdCwgdXBiX2ZpZWxkZGVmX25hbWUoZiksIHZhbCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBDSEVDSyhlbmRmaWVsZChwKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBlcnI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gZmFsc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9CisKK3N0YXRpYyBib29sIHRleHRwcmludGVyX3B1dGJvb2wodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHZhbCkgeworICB1cGJfdGV4dHByaW50ZXIgKnAgPSBjbG9zdXJlOworICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSBoYW5kbGVyX2RhdGE7CisgIENIRUNLKGluZGVudChwKSk7CisgIHB1dGYocCwgIiVzOiAlcyIsIHVwYl9maWVsZGRlZl9uYW1lKGYpLCB2YWwgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKKyAgQ0hFQ0soZW5kZmllbGQocCkpOworICByZXR1cm4gdHJ1ZTsKK2VycjoKKyAgcmV0dXJuIGZhbHNlOworfQorCisjZGVmaW5lIFNUUklOR0lGWV9IRUxQRVIoeCkgI3gKKyNkZWZpbmUgU1RSSU5HSUZZX01BQ1JPVkFMKHgpIFNUUklOR0lGWV9IRUxQRVIoeCkKKworVFlQRShpbnQzMiwgIGludDMyX3QsICAiJSIgUFJJZDMyKQorVFlQRShpbnQ2NCwgIGludDY0X3QsICAiJSIgUFJJZDY0KQorVFlQRSh1aW50MzIsIHVpbnQzMl90LCAiJSIgUFJJdTMyKTsKK1RZUEUodWludDY0LCB1aW50NjRfdCwgIiUiIFBSSXU2NCkKK1RZUEUoZmxvYXQsICBmbG9hdCwgICAgIiUuIiBTVFJJTkdJRllfTUFDUk9WQUwoRkxUX0RJRykgImciKQorVFlQRShkb3VibGUsIGRvdWJsZSwgICAiJS4iIFNUUklOR0lGWV9NQUNST1ZBTChEQkxfRElHKSAiZyIpCisKKyN1bmRlZiBUWVBFCisKKy8vIE91dHB1dCBhIHN5bWJvbGljIHZhbHVlIGZyb20gdGhlIGVudW0gaWYgZm91bmQsIGVsc2UganVzdCBwcmludCBhcyBpbnQzMi4KK3N0YXRpYyBib29sIHRleHRwcmludGVyX3B1dGVudW0odm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHZhbCkgeworICB1cGJfdGV4dHByaW50ZXIgKnAgPSBjbG9zdXJlOworICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSBoYW5kbGVyX2RhdGE7CisgIGNvbnN0IHVwYl9lbnVtZGVmICplbnVtX2RlZiA9IHVwYl9kb3duY2FzdF9lbnVtZGVmKHVwYl9maWVsZGRlZl9zdWJkZWYoZikpOworICBjb25zdCBjaGFyICpsYWJlbCA9IHVwYl9lbnVtZGVmX2l0b24oZW51bV9kZWYsIHZhbCk7CisgIGlmIChsYWJlbCkgeworICAgIGluZGVudChwKTsKKyAgICBwdXRmKHAsICIlczogJXMiLCB1cGJfZmllbGRkZWZfbmFtZShmKSwgbGFiZWwpOworICAgIGVuZGZpZWxkKHApOworICB9IGVsc2UgeworICAgIGlmICghdGV4dHByaW50ZXJfcHV0aW50MzIoY2xvc3VyZSwgaGFuZGxlcl9kYXRhLCB2YWwpKQorICAgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgdm9pZCAqdGV4dHByaW50ZXJfc3RhcnRzdHIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplX2hpbnQpIHsKKyAgY29uc3QgdXBiX2ZpZWxkZGVmICpmID0gaGFuZGxlcl9kYXRhOworICBVUEJfVU5VU0VEKHNpemVfaGludCk7CisgIHVwYl90ZXh0cHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIGluZGVudChwKTsKKyAgcHV0ZihwLCAiJXM6IFwiIiwgdXBiX2ZpZWxkZGVmX25hbWUoZikpOworICByZXR1cm4gcDsKK30KKworc3RhdGljIGJvb2wgdGV4dHByaW50ZXJfZW5kc3RyKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSkgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIHVwYl90ZXh0cHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIHB1dGYocCwgIlwiIik7CisgIGVuZGZpZWxkKHApOworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIHNpemVfdCB0ZXh0cHJpbnRlcl9wdXRzdHIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4sIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl90ZXh0cHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIGNvbnN0IHVwYl9maWVsZGRlZiAqZiA9IGhkOworICBDSEVDSyhwdXRlc2NhcGVkKHAsIGJ1ZiwgbGVuLCB1cGJfZmllbGRkZWZfdHlwZShmKSA9PSBVUEJfVFlQRV9TVFJJTkcpKTsKKyAgcmV0dXJuIGxlbjsKK2VycjoKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkICp0ZXh0cHJpbnRlcl9zdGFydHN1Ym1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgdXBiX3RleHRwcmludGVyICpwID0gY2xvc3VyZTsKKyAgY29uc3QgY2hhciAqbmFtZSA9IGhhbmRsZXJfZGF0YTsKKyAgQ0hFQ0soaW5kZW50KHApKTsKKyAgcHV0ZihwLCAiJXMgeyVjIiwgbmFtZSwgcC0+c2luZ2xlX2xpbmVfID8gJyAnIDogJ1xuJyk7CisgIHAtPmluZGVudF9kZXB0aF8rKzsKKyAgcmV0dXJuIHA7CitlcnI6CisgIHJldHVybiBVUEJfQlJFQUs7Cit9CisKK3N0YXRpYyBib29sIHRleHRwcmludGVyX2VuZHN1Ym1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICB1cGJfdGV4dHByaW50ZXIgKnAgPSBjbG9zdXJlOworICBwLT5pbmRlbnRfZGVwdGhfLS07CisgIENIRUNLKGluZGVudChwKSk7CisgIHVwYl9ieXRlc3NpbmtfcHV0YnVmKHAtPm91dHB1dF8sIHAtPnN1YmMsICJ9IiwgMSwgTlVMTCk7CisgIENIRUNLKGVuZGZpZWxkKHApKTsKKyAgcmV0dXJuIHRydWU7CitlcnI6CisgIHJldHVybiBmYWxzZTsKK30KKworCisvKiBQdWJsaWMgQVBJICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit2b2lkIHVwYl90ZXh0cHJpbnRlcl9pbml0KHVwYl90ZXh0cHJpbnRlciAqcCwgY29uc3QgdXBiX2hhbmRsZXJzICpoKSB7CisgIHAtPnNpbmdsZV9saW5lXyA9IGZhbHNlOworICBwLT5pbmRlbnRfZGVwdGhfID0gMDsKKyAgdXBiX3NpbmtfcmVzZXQoJnAtPmlucHV0XywgaCwgcCk7Cit9CisKK3ZvaWQgdXBiX3RleHRwcmludGVyX3VuaW5pdCh1cGJfdGV4dHByaW50ZXIgKnApIHsKKyAgVVBCX1VOVVNFRChwKTsKK30KKwordm9pZCB1cGJfdGV4dHByaW50ZXJfcmVzZXQodXBiX3RleHRwcmludGVyICpwLCBib29sIHNpbmdsZV9saW5lKSB7CisgIHAtPnNpbmdsZV9saW5lXyA9IHNpbmdsZV9saW5lOworICBwLT5pbmRlbnRfZGVwdGhfID0gMDsKK30KKworc3RhdGljIHZvaWQgb25tcmVnKGNvbnN0IHZvaWQgKmMsIHVwYl9oYW5kbGVycyAqaCkgeworICBVUEJfVU5VU0VEKGMpOworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX2hhbmRsZXJzX21zZ2RlZihoKTsKKworICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRtc2coaCwgdGV4dHByaW50ZXJfc3RhcnRtc2csIE5VTEwpOworICB1cGJfaGFuZGxlcnNfc2V0ZW5kbXNnKGgsIHRleHRwcmludGVyX2VuZG1zZywgTlVMTCk7CisKKyAgdXBiX21zZ19maWVsZF9pdGVyIGk7CisgIGZvcih1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpLCBtKTsKKyAgICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmkpOworICAgICAgdXBiX21zZ19maWVsZF9uZXh0KCZpKSkgeworICAgIHVwYl9maWVsZGRlZiAqZiA9IHVwYl9tc2dfaXRlcl9maWVsZCgmaSk7CisgICAgdXBiX2hhbmRsZXJhdHRyIGF0dHIgPSBVUEJfSEFORExFUkFUVFJfSU5JVElBTElaRVI7CisgICAgdXBiX2hhbmRsZXJhdHRyX3NldGhhbmRsZXJkYXRhKCZhdHRyLCBmKTsKKyAgICBzd2l0Y2ggKHVwYl9maWVsZGRlZl90eXBlKGYpKSB7CisgICAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOgorICAgICAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwgZiwgdGV4dHByaW50ZXJfcHV0aW50MzIsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX0lOVDY0OgorICAgICAgICB1cGJfaGFuZGxlcnNfc2V0aW50NjQoaCwgZiwgdGV4dHByaW50ZXJfcHV0aW50NjQsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjoKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldHVpbnQzMihoLCBmLCB0ZXh0cHJpbnRlcl9wdXR1aW50MzIsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDoKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldHVpbnQ2NChoLCBmLCB0ZXh0cHJpbnRlcl9wdXR1aW50NjQsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX0ZMT0FUOgorICAgICAgICB1cGJfaGFuZGxlcnNfc2V0ZmxvYXQoaCwgZiwgdGV4dHByaW50ZXJfcHV0ZmxvYXQsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX0RPVUJMRToKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldGRvdWJsZShoLCBmLCB0ZXh0cHJpbnRlcl9wdXRkb3VibGUsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX0JPT0w6CisgICAgICAgIHVwYl9oYW5kbGVyc19zZXRib29sKGgsIGYsIHRleHRwcmludGVyX3B1dGJvb2wsICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICAgIGNhc2UgVVBCX1RZUEVfQllURVM6CisgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHN0cihoLCBmLCB0ZXh0cHJpbnRlcl9zdGFydHN0ciwgJmF0dHIpOworICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKGgsIGYsIHRleHRwcmludGVyX3B1dHN0ciwgJmF0dHIpOworICAgICAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc3RyKGgsIGYsIHRleHRwcmludGVyX2VuZHN0ciwgJmF0dHIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRTogeworICAgICAgICBjb25zdCBjaGFyICpuYW1lID0KKyAgICAgICAgICAgIHVwYl9maWVsZGRlZl9pc3RhZ2RlbGltKGYpCisgICAgICAgICAgICAgICAgPyBzaG9ydG5hbWUodXBiX21zZ2RlZl9mdWxsbmFtZSh1cGJfZmllbGRkZWZfbXNnc3ViZGVmKGYpKSkKKyAgICAgICAgICAgICAgICA6IHVwYl9maWVsZGRlZl9uYW1lKGYpOworICAgICAgICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoJmF0dHIsIG5hbWUpOworICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdWJtc2coaCwgZiwgdGV4dHByaW50ZXJfc3RhcnRzdWJtc2csICZhdHRyKTsKKyAgICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN1Ym1zZyhoLCBmLCB0ZXh0cHJpbnRlcl9lbmRzdWJtc2csICZhdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjYXNlIFVQQl9UWVBFX0VOVU06CisgICAgICAgIHVwYl9oYW5kbGVyc19zZXRpbnQzMihoLCBmLCB0ZXh0cHJpbnRlcl9wdXRlbnVtLCAmYXR0cik7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCitjb25zdCB1cGJfaGFuZGxlcnMgKnVwYl90ZXh0cHJpbnRlcl9uZXdoYW5kbGVycyhjb25zdCB1cGJfbXNnZGVmICptLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19uZXdmcm96ZW4obSwgb3duZXIsICZvbm1yZWcsIE5VTEwpOworfQorCit1cGJfc2luayAqdXBiX3RleHRwcmludGVyX2lucHV0KHVwYl90ZXh0cHJpbnRlciAqcCkgeyByZXR1cm4gJnAtPmlucHV0XzsgfQorCitib29sIHVwYl90ZXh0cHJpbnRlcl9yZXNldG91dHB1dCh1cGJfdGV4dHByaW50ZXIgKnAsIHVwYl9ieXRlc3NpbmsgKm91dHB1dCkgeworICBwLT5vdXRwdXRfID0gb3V0cHV0OworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCB1cGJfdGV4dHByaW50ZXJfc2V0c2luZ2xlbGluZSh1cGJfdGV4dHByaW50ZXIgKnAsIGJvb2wgc2luZ2xlX2xpbmUpIHsKKyAgcC0+c2luZ2xlX2xpbmVfID0gc2luZ2xlX2xpbmU7Cit9CisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDExIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqLworCisKKy8vIEluZGV4IGlzIGRlc2NyaXB0b3IgdHlwZS4KK2NvbnN0IHVpbnQ4X3QgdXBiX3BiX25hdGl2ZV93aXJlX3R5cGVzW10gPSB7CisgIFVQQl9XSVJFX1RZUEVfRU5EX0dST1VQLCAgICAgLy8gRU5ER1JPVVAKKyAgVVBCX1dJUkVfVFlQRV82NEJJVCwgICAgICAgICAvLyBET1VCTEUKKyAgVVBCX1dJUkVfVFlQRV8zMkJJVCwgICAgICAgICAvLyBGTE9BVAorICBVUEJfV0lSRV9UWVBFX1ZBUklOVCwgICAgICAgIC8vIElOVDY0CisgIFVQQl9XSVJFX1RZUEVfVkFSSU5ULCAgICAgICAgLy8gVUlOVDY0CisgIFVQQl9XSVJFX1RZUEVfVkFSSU5ULCAgICAgICAgLy8gSU5UMzIKKyAgVVBCX1dJUkVfVFlQRV82NEJJVCwgICAgICAgICAvLyBGSVhFRDY0CisgIFVQQl9XSVJFX1RZUEVfMzJCSVQsICAgICAgICAgLy8gRklYRUQzMgorICBVUEJfV0lSRV9UWVBFX1ZBUklOVCwgICAgICAgIC8vIEJPT0wKKyAgVVBCX1dJUkVfVFlQRV9ERUxJTUlURUQsICAgICAvLyBTVFJJTkcKKyAgVVBCX1dJUkVfVFlQRV9TVEFSVF9HUk9VUCwgICAvLyBHUk9VUAorICBVUEJfV0lSRV9UWVBFX0RFTElNSVRFRCwgICAgIC8vIE1FU1NBR0UKKyAgVVBCX1dJUkVfVFlQRV9ERUxJTUlURUQsICAgICAvLyBCWVRFUworICBVUEJfV0lSRV9UWVBFX1ZBUklOVCwgICAgICAgIC8vIFVJTlQzMgorICBVUEJfV0lSRV9UWVBFX1ZBUklOVCwgICAgICAgIC8vIEVOVU0KKyAgVVBCX1dJUkVfVFlQRV8zMkJJVCwgICAgICAgICAvLyBTRklYRUQzMgorICBVUEJfV0lSRV9UWVBFXzY0QklULCAgICAgICAgIC8vIFNGSVhFRDY0CisgIFVQQl9XSVJFX1RZUEVfVkFSSU5ULCAgICAgICAgLy8gU0lOVDMyCisgIFVQQl9XSVJFX1RZUEVfVkFSSU5ULCAgICAgICAgLy8gU0lOVDY0Cit9OworCisvLyBBIGJhc2ljIGJyYW5jaC1iYXNlZCBkZWNvZGVyLCB1c2VzIDMyLWJpdCB2YWx1ZXMgdG8gZ2V0IGdvb2QgcGVyZm9ybWFuY2UKKy8vIG9uIDMyLWJpdCBhcmNoaXRlY3R1cmVzIChidXQgcGVyZm9ybXMgd2VsbCBvbiA2NC1iaXRzIGFsc28pLgorLy8gVGhpcyBzY2hlbWUgY29tZXMgZnJvbSB0aGUgb3JpZ2luYWwgR29vZ2xlIFByb3RvYnVmIGltcGxlbWVudGF0aW9uIChwcm90bzIpLgordXBiX2RlY29kZXJldCB1cGJfdmRlY29kZV9tYXg4X2JyYW5jaDMyKHVwYl9kZWNvZGVyZXQgcikgeworICB1cGJfZGVjb2RlcmV0IGVyciA9IHtOVUxMLCAwfTsKKyAgY29uc3QgY2hhciAqcCA9IHIucDsKKyAgdWludDMyX3QgbG93ID0gKHVpbnQzMl90KXIudmFsOworICB1aW50MzJfdCBoaWdoID0gMDsKKyAgdWludDMyX3QgYjsKKyAgYiA9ICoocCsrKTsgbG93ICB8PSAoYiAmIDB4N2ZVKSA8PCAxNDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgIGIgPSAqKHArKyk7IGxvdyAgfD0gKGIgJiAweDdmVSkgPDwgMjE7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyBsb3cgIHw9IChiICYgMHg3ZlUpIDw8IDI4OworICAgICAgICAgICAgICBoaWdoICA9IChiICYgMHg3ZlUpID4+ICA0OyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgYiA9ICoocCsrKTsgaGlnaCB8PSAoYiAmIDB4N2ZVKSA8PCAgMzsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgIGIgPSAqKHArKyk7IGhpZ2ggfD0gKGIgJiAweDdmVSkgPDwgMTA7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyBoaWdoIHw9IChiICYgMHg3ZlUpIDw8IDE3OyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgYiA9ICoocCsrKTsgaGlnaCB8PSAoYiAmIDB4N2ZVKSA8PCAyNDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgIGIgPSAqKHArKyk7IGhpZ2ggfD0gKGIgJiAweDdmVSkgPDwgMzE7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICByZXR1cm4gZXJyOworCitkb25lOgorICByLnZhbCA9ICgodWludDY0X3QpaGlnaCA8PCAzMikgfCBsb3c7CisgIHIucCA9IHA7CisgIHJldHVybiByOworfQorCisvLyBMaWtlIHRoZSBwcmV2aW91cywgYnV0IHVzZXMgNjQtYml0IHZhbHVlcy4KK3VwYl9kZWNvZGVyZXQgdXBiX3ZkZWNvZGVfbWF4OF9icmFuY2g2NCh1cGJfZGVjb2RlcmV0IHIpIHsKKyAgY29uc3QgY2hhciAqcCA9IHIucDsKKyAgdWludDY0X3QgdmFsID0gci52YWw7CisgIHVpbnQ2NF90IGI7CisgIHVwYl9kZWNvZGVyZXQgZXJyID0ge05VTEwsIDB9OworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgMTQ7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgMjE7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgMjg7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgMzU7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgNDI7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgNDk7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgNTY7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICBiID0gKihwKyspOyB2YWwgfD0gKGIgJiAweDdmVSkgPDwgNjM7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICByZXR1cm4gZXJyOworCitkb25lOgorICByLnZhbCA9IHZhbDsKKyAgci5wID0gcDsKKyAgcmV0dXJuIHI7Cit9CisKKy8vIEdpdmVuIGFuIGVuY29kZWQgdmFyaW50IHYsIHJldHVybnMgYW4gaW50ZWdlciB3aXRoIGEgc2luZ2xlIGJpdCBzZXQgdGhhdAorLy8gaW5kaWNhdGVzIHRoZSBlbmQgb2YgdGhlIHZhcmludC4gIFN1YnRyYWN0aW5nIG9uZSBmcm9tIHRoaXMgdmFsdWUgd2lsbAorLy8geWllbGQgYSBtYXNrIHRoYXQgbGVhdmVzIG9ubHkgYml0cyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSB2YXJpbnQuICBSZXR1cm5zCisvLyAwIGlmIHRoZSB2YXJpbnQgaXMgdW50ZXJtaW5hdGVkLgorc3RhdGljIHVpbnQ2NF90IHVwYl9nZXRfdnN0b3BiaXQodWludDY0X3QgdikgeworICB1aW50NjRfdCBjYml0cyA9IHYgfCAweDdmN2Y3ZjdmN2Y3ZjdmN2ZVTEw7CisgIHJldHVybiB+Y2JpdHMgJiAoY2JpdHMrMSk7Cit9CisKKy8vIEEgYnJhbmNobGVzcyBkZWNvZGVyLiAgQ3JlZGl0IHRvIFBhc2NhbCBNYXNzaW1pbm8gZm9yIHRoZSBiaXQtdHdpZGRsaW5nLgordXBiX2RlY29kZXJldCB1cGJfdmRlY29kZV9tYXg4X21hc3NpbWlubyh1cGJfZGVjb2RlcmV0IHIpIHsKKyAgdWludDY0X3QgYjsKKyAgbWVtY3B5KCZiLCByLnAsIHNpemVvZihiKSk7CisgIHVpbnQ2NF90IHN0b3BfYml0ID0gdXBiX2dldF92c3RvcGJpdChiKTsKKyAgYiA9ICAoYiAmIDB4N2Y3ZjdmN2Y3ZjdmN2Y3ZlVMTCkgJiAoc3RvcF9iaXQgLSAxKTsKKyAgYiArPSAgICAgICBiICYgMHgwMDdmMDA3ZjAwN2YwMDdmVUxMOworICBiICs9ICAzICogKGIgJiAweDAwMDBmZmZmMDAwMGZmZmZVTEwpOworICBiICs9IDE1ICogKGIgJiAweDAwMDAwMDAwZmZmZmZmZmZVTEwpOworICBpZiAoc3RvcF9iaXQgPT0gMCkgeworICAgIC8vIEVycm9yOiB1bnRlcm1pbmF0ZWQgdmFyaW50LgorICAgIHVwYl9kZWNvZGVyZXQgZXJyX3IgPSB7KHZvaWQqKTAsIDB9OworICAgIHJldHVybiBlcnJfcjsKKyAgfQorICB1cGJfZGVjb2RlcmV0IG15X3IgPSB7ci5wICsgKChfX2J1aWx0aW5fY3R6bGwoc3RvcF9iaXQpICsgMSkgLyA4KSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHIudmFsIHwgKGIgPDwgNyl9OworICByZXR1cm4gbXlfcjsKK30KKworLy8gQSBicmFuY2hsZXNzIGRlY29kZXIuICBDcmVkaXQgdG8gRGFuaWVsIFdyaWdodCBmb3IgdGhlIGJpdC10d2lkZGxpbmcuCit1cGJfZGVjb2RlcmV0IHVwYl92ZGVjb2RlX21heDhfd3JpZ2h0KHVwYl9kZWNvZGVyZXQgcikgeworICB1aW50NjRfdCBiOworICBtZW1jcHkoJmIsIHIucCwgc2l6ZW9mKGIpKTsKKyAgdWludDY0X3Qgc3RvcF9iaXQgPSB1cGJfZ2V0X3ZzdG9wYml0KGIpOworICBiICY9IChzdG9wX2JpdCAtIDEpOworICBiID0gKChiICYgMHg3ZjAwN2YwMDdmMDA3ZjAwVUxMKSA+PiAxKSB8IChiICYgMHgwMDdmMDA3ZjAwN2YwMDdmVUxMKTsKKyAgYiA9ICgoYiAmIDB4ZmZmZjAwMDBmZmZmMDAwMFVMTCkgPj4gMikgfCAoYiAmIDB4MDAwMGZmZmYwMDAwZmZmZlVMTCk7CisgIGIgPSAoKGIgJiAweGZmZmZmZmZmMDAwMDAwMDBVTEwpID4+IDQpIHwgKGIgJiAweDAwMDAwMDAwZmZmZmZmZmZVTEwpOworICBpZiAoc3RvcF9iaXQgPT0gMCkgeworICAgIC8vIEVycm9yOiB1bnRlcm1pbmF0ZWQgdmFyaW50LgorICAgIHVwYl9kZWNvZGVyZXQgZXJyX3IgPSB7KHZvaWQqKTAsIDB9OworICAgIHJldHVybiBlcnJfcjsKKyAgfQorICB1cGJfZGVjb2RlcmV0IG15X3IgPSB7ci5wICsgKChfX2J1aWx0aW5fY3R6bGwoc3RvcF9iaXQpICsgMSkgLyA4KSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHIudmFsIHwgKGIgPDwgMTQpfTsKKyAgcmV0dXJuIG15X3I7Cit9CisKKyNsaW5lIDEgInVwYi9qc29uL3BhcnNlci5ybCIKKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTQgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIEEgcGFyc2VyIHRoYXQgdXNlcyB0aGUgUmFnZWwgU3RhdGUgTWFjaGluZSBDb21waWxlciB0byBnZW5lcmF0ZQorICogdGhlIGZpbml0ZSBhdXRvbWF0YS4KKyAqCisgKiBSYWdlbCBvbmx5IG5hdGl2ZWx5IGhhbmRsZXMgcmVndWxhciBsYW5ndWFnZXMsIGJ1dCB3ZSBjYW4gbWFudWFsbHkKKyAqIHByb2dyYW0gaXQgYSBiaXQgdG8gaGFuZGxlIGNvbnRleHQtZnJlZSBsYW5ndWFnZXMgbGlrZSBKU09OLCBieSB1c2luZworICogdGhlICJmY2FsbCIgYW5kICJmcmV0IiBjb25zdHJ1Y3RzLgorICoKKyAqIFRoaXMgcGFyc2VyIGNhbiBoYW5kbGUgdGhlIGJhc2ljcywgYnV0IG5lZWRzIHNldmVyYWwgdGhpbmdzIHRvIGJlIGZsZXNoZWQKKyAqIG91dDoKKyAqCisgKiAtIGhhbmRsaW5nIG9mIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlcyAoaW5jbHVkaW5nIGhpZ2ggc3Vycm9nYXRlIHBhaXJzKS4KKyAqIC0gcHJvcGVybHkgY2hlY2sgYW5kIHJlcG9ydCBlcnJvcnMgZm9yIHVua25vd24gZmllbGRzLCBzdGFjayBvdmVyZmxvdywKKyAqICAgaW1wcm9wZXIgYXJyYXkgbmVzdGluZyAob3IgbGFjayBvZiBuZXN0aW5nKS4KKyAqIC0gaGFuZGxpbmcgb2YgYmFzZTY0IHNlcXVlbmNlcyB3aXRoIHBhZGRpbmcgY2hhcmFjdGVycy4KKyAqIC0gaGFuZGxpbmcgb2YgcHVzaC1iYWNrIChub24tc3VjY2VzcyByZXR1cm5zIGZyb20gc2luayBmdW5jdGlvbnMpLgorICogLSBoYW5kbGluZyBvZiBrZXlzL2VzY2FwZS1zZXF1ZW5jZXMvZXRjIHRoYXQgc3BhbiBpbnB1dCBidWZmZXJzLgorICovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisKKworI2RlZmluZSBQQVJTRVJfQ0hFQ0tfUkVUVVJOKHgpIGlmICghKHgpKSByZXR1cm4gZmFsc2UKKworLy8gVXNlZCB0byBzaWduYWwgdGhhdCBhIGNhcHR1cmUgaGFzIGJlZW4gc3VzcGVuZGVkLgorc3RhdGljIGNoYXIgc3VzcGVuZF9jYXB0dXJlOworCitzdGF0aWMgdXBiX3NlbGVjdG9yX3QgZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZSh1cGJfanNvbl9wYXJzZXIgKnAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcnR5cGVfdCB0eXBlKSB7CisgIHVwYl9zZWxlY3Rvcl90IHNlbDsKKyAgYm9vbCBvayA9IHVwYl9oYW5kbGVyc19nZXRzZWxlY3RvcihwLT50b3AtPmYsIHR5cGUsICZzZWwpOworICBVUEJfQVNTRVJUX1ZBUihvaywgb2spOworICByZXR1cm4gc2VsOworfQorCitzdGF0aWMgdXBiX3NlbGVjdG9yX3QgcGFyc2VyX2dldHNlbCh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgcmV0dXJuIGdldHNlbF9mb3JfaGFuZGxlcnR5cGUoCisgICAgICBwLCB1cGJfaGFuZGxlcnNfZ2V0cHJpbWl0aXZlaGFuZGxlcnR5cGUocC0+dG9wLT5mKSk7Cit9CisKK3N0YXRpYyBib29sIGNoZWNrX3N0YWNrKHVwYl9qc29uX3BhcnNlciAqcCkgeworICBpZiAoKHAtPnRvcCArIDEpID09IHAtPmxpbWl0KSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocC0+c3RhdHVzLCAiTmVzdGluZyB0b28gZGVlcCIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCisvLyBUaGVyZSBhcmUgR0NDL0NsYW5nIGJ1aWx0LWlucyBmb3Igb3ZlcmZsb3cgY2hlY2tpbmcgd2hpY2ggd2UgY291bGQgc3RhcnQKKy8vIHVzaW5nIGlmIHRoZXJlIHdhcyBhbnkgcGVyZm9ybWFuY2UgYmVuZWZpdCB0byBpdC4KKworc3RhdGljIGJvb2wgY2hlY2tlZF9hZGQoc2l6ZV90IGEsIHNpemVfdCBiLCBzaXplX3QgKmMpIHsKKyAgaWYgKFNJWkVfTUFYIC0gYSA8IGIpIHJldHVybiBmYWxzZTsKKyAgKmMgPSBhICsgYjsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBzaXplX3Qgc2F0dXJhdGluZ19tdWx0aXBseShzaXplX3QgYSwgc2l6ZV90IGIpIHsKKyAgLy8gc2l6ZV90IGlzIHVuc2lnbmVkLCBzbyB0aGlzIGlzIGRlZmluZWQgYmVoYXZpb3IgZXZlbiBvbiBvdmVyZmxvdy4KKyAgc2l6ZV90IHJldCA9IGEgKiBiOworICBpZiAoYiAhPSAwICYmIHJldCAvIGIgIT0gYSkgeworICAgIHJldCA9IFNJWkVfTUFYOworICB9CisgIHJldHVybiByZXQ7Cit9CisKKworLyogQmFzZTY0IGRlY29kaW5nICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gVE9ETyhoYWJlcm1hbik6IG1ha2UgdGhpcyBzdHJlYW1pbmcuCisKK3N0YXRpYyBjb25zdCBzaWduZWQgY2hhciBiNjR0YWJsZVtdID0geworICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIDYyLyorKi8sIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIDYzLyovICovLAorICA1Mi8qMCovLCA1My8qMSovLCA1NC8qMiovLCA1NS8qMyovLCA1Ni8qNCovLCA1Ny8qNSovLCA1OC8qNiovLCA1OS8qNyovLAorICA2MC8qOCovLCA2MS8qOSovLCAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgIDAvKkEqLywgIDEvKkIqLywgIDIvKkMqLywgIDMvKkQqLywgIDQvKkUqLywgIDUvKkYqLywgIDYvKkcqLywKKyAgMDcvKkgqLywgIDgvKkkqLywgIDkvKkoqLywgMTAvKksqLywgMTEvKkwqLywgMTIvKk0qLywgMTMvKk4qLywgMTQvKk8qLywKKyAgMTUvKlAqLywgMTYvKlEqLywgMTcvKlIqLywgMTgvKlMqLywgMTkvKlQqLywgMjAvKlUqLywgMjEvKlYqLywgMjIvKlcqLywKKyAgMjMvKlgqLywgMjQvKlkqLywgMjUvKloqLywgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIDI2LyphKi8sIDI3LypiKi8sIDI4LypjKi8sIDI5LypkKi8sIDMwLyplKi8sIDMxLypmKi8sIDMyLypnKi8sCisgIDMzLypoKi8sIDM0LyppKi8sIDM1LypqKi8sIDM2LyprKi8sIDM3LypsKi8sIDM4LyptKi8sIDM5LypuKi8sIDQwLypvKi8sCisgIDQxLypwKi8sIDQyLypxKi8sIDQzLypyKi8sIDQ0LypzKi8sIDQ1Lyp0Ki8sIDQ2Lyp1Ki8sIDQ3Lyp2Ki8sIDQ4Lyp3Ki8sCisgIDQ5Lyp4Ki8sIDUwLyp5Ki8sIDUxLyp6Ki8sIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMQorfTsKKworLy8gUmV0dXJucyB0aGUgdGFibGUgdmFsdWUgc2lnbi1leHRlbmRlZCB0byAzMiBiaXRzLiAgS25vd2luZyB0aGF0IHRoZSB1cHBlcgorLy8gYml0cyB3aWxsIGJlIDEgZm9yIHVucmVjb2duaXplZCBjaGFyYWN0ZXJzIG1ha2VzIGl0IGVhc2llciB0byBjaGVjayBmb3IKKy8vIHRoaXMgZXJyb3IgY29uZGl0aW9uIGxhdGVyIChzZWUgYmVsb3cpLgoraW50MzJfdCBiNjRsb29rdXAodW5zaWduZWQgY2hhciBjaCkgeyByZXR1cm4gYjY0dGFibGVbY2hdOyB9CisKKy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIG5vdCBhIHZhbGlkIGJhc2U2NCBjaGFyYWN0ZXIgb3IKKy8vIHBhZGRpbmcuCitib29sIG5vbmJhc2U2NCh1bnNpZ25lZCBjaGFyIGNoKSB7IHJldHVybiBiNjRsb29rdXAoY2gpID09IC0xICYmIGNoICE9ICc9JzsgfQorCitzdGF0aWMgYm9vbCBiYXNlNjRfcHVzaCh1cGJfanNvbl9wYXJzZXIgKnAsIHVwYl9zZWxlY3Rvcl90IHNlbCwgY29uc3QgY2hhciAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbikgeworICBjb25zdCBjaGFyICpsaW1pdCA9IHB0ciArIGxlbjsKKyAgZm9yICg7IHB0ciA8IGxpbWl0OyBwdHIgKz0gNCkgeworICAgIGlmIChsaW1pdCAtIHB0ciA8IDQpIHsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihwLT5zdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIkJhc2U2NCBpbnB1dCBmb3IgYnl0ZXMgZmllbGQgbm90IGEgbXVsdGlwbGUgb2YgNDogJXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9maWVsZGRlZl9uYW1lKHAtPnRvcC0+ZikpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHVpbnQzMl90IHZhbCA9IGI2NGxvb2t1cChwdHJbMF0pIDw8IDE4IHwKKyAgICAgICAgICAgICAgICAgICBiNjRsb29rdXAocHRyWzFdKSA8PCAxMiB8CisgICAgICAgICAgICAgICAgICAgYjY0bG9va3VwKHB0clsyXSkgPDwgNiAgfAorICAgICAgICAgICAgICAgICAgIGI2NGxvb2t1cChwdHJbM10pOworCisgICAgLy8gVGVzdCB0aGUgdXBwZXIgYml0OyByZXR1cm5zIHRydWUgaWYgYW55IG9mIHRoZSBjaGFyYWN0ZXJzIHJldHVybmVkIC0xLgorICAgIGlmICh2YWwgJiAweDgwMDAwMDAwKSB7CisgICAgICBnb3RvIG90aGVyY2hhcjsKKyAgICB9CisKKyAgICBjaGFyIG91dHB1dFszXTsKKyAgICBvdXRwdXRbMF0gPSB2YWwgPj4gMTY7CisgICAgb3V0cHV0WzFdID0gKHZhbCA+PiA4KSAmIDB4ZmY7CisgICAgb3V0cHV0WzJdID0gdmFsICYgMHhmZjsKKyAgICB1cGJfc2lua19wdXRzdHJpbmcoJnAtPnRvcC0+c2luaywgc2VsLCBvdXRwdXQsIDMsIE5VTEwpOworICB9CisgIHJldHVybiB0cnVlOworCitvdGhlcmNoYXI6CisgIGlmIChub25iYXNlNjQocHRyWzBdKSB8fCBub25iYXNlNjQocHRyWzFdKSB8fCBub25iYXNlNjQocHRyWzJdKSB8fAorICAgICAgbm9uYmFzZTY0KHB0clszXSkgKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJmKHAtPnN0YXR1cywKKyAgICAgICAgICAgICAgICAgICAgICAgIk5vbi1iYXNlNjQgY2hhcmFjdGVycyBpbiBieXRlcyBmaWVsZDogJXMiLAorICAgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfbmFtZShwLT50b3AtPmYpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gaWYgKHB0clsyXSA9PSAnPScpIHsKKyAgICAvLyBMYXN0IGdyb3VwIGNvbnRhaW5zIG9ubHkgdHdvIGlucHV0IGJ5dGVzLCBvbmUgb3V0cHV0IGJ5dGUuCisgICAgaWYgKHB0clswXSA9PSAnPScgfHwgcHRyWzFdID09ICc9JyB8fCBwdHJbM10gIT0gJz0nKSB7CisgICAgICBnb3RvIGJhZHBhZGRpbmc7CisgICAgfQorCisgICAgdWludDMyX3QgdmFsID0gYjY0bG9va3VwKHB0clswXSkgPDwgMTggfAorICAgICAgICAgICAgICAgICAgIGI2NGxvb2t1cChwdHJbMV0pIDw8IDEyOworCisgICAgYXNzZXJ0KCEodmFsICYgMHg4MDAwMDAwMCkpOworICAgIGNoYXIgb3V0cHV0ID0gdmFsID4+IDE2OworICAgIHVwYl9zaW5rX3B1dHN0cmluZygmcC0+dG9wLT5zaW5rLCBzZWwsICZvdXRwdXQsIDEsIE5VTEwpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIC8vIExhc3QgZ3JvdXAgY29udGFpbnMgb25seSB0aHJlZSBpbnB1dCBieXRlcywgdHdvIG91dHB1dCBieXRlcy4KKyAgICBpZiAocHRyWzBdID09ICc9JyB8fCBwdHJbMV0gPT0gJz0nIHx8IHB0clsyXSA9PSAnPScpIHsKKyAgICAgIGdvdG8gYmFkcGFkZGluZzsKKyAgICB9CisKKyAgICB1aW50MzJfdCB2YWwgPSBiNjRsb29rdXAocHRyWzBdKSA8PCAxOCB8CisgICAgICAgICAgICAgICAgICAgYjY0bG9va3VwKHB0clsxXSkgPDwgMTIgfAorICAgICAgICAgICAgICAgICAgIGI2NGxvb2t1cChwdHJbMl0pIDw8IDY7CisKKyAgICBjaGFyIG91dHB1dFsyXTsKKyAgICBvdXRwdXRbMF0gPSB2YWwgPj4gMTY7CisgICAgb3V0cHV0WzFdID0gKHZhbCA+PiA4KSAmIDB4ZmY7CisgICAgdXBiX3NpbmtfcHV0c3RyaW5nKCZwLT50b3AtPnNpbmssIHNlbCwgb3V0cHV0LCAyLCBOVUxMKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCitiYWRwYWRkaW5nOgorICB1cGJfc3RhdHVzX3NldGVycmYocC0+c3RhdHVzLAorICAgICAgICAgICAgICAgICAgICAgIkluY29ycmVjdCBiYXNlNjQgcGFkZGluZyBmb3IgZmllbGQ6ICVzICglLipzKSIsCisgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfbmFtZShwLT50b3AtPmYpLAorICAgICAgICAgICAgICAgICAgICAgNCwgcHRyKTsKKyAgcmV0dXJuIGZhbHNlOworfQorCisKKy8qIEFjY3VtdWxhdGUgYnVmZmVyICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIEZ1bmN0aW9uYWxpdHkgZm9yIGFjY3VtdWxhdGluZyBhIGJ1ZmZlci4KKy8vCisvLyBTb21lIHBhcnRzIG9mIHRoZSBwYXJzZXIgbmVlZCBhbiBlbnRpcmUgdmFsdWUgYXMgYSBjb250aWd1b3VzIHN0cmluZy4gIEZvcgorLy8gZXhhbXBsZSwgdG8gbG9vayB1cCBhIG1lbWJlciBuYW1lIGluIGEgaGFzaCB0YWJsZSwgb3IgdG8gdHVybiBhIHN0cmluZyBpbnRvCisvLyBhIG51bWJlciwgdGhlIHJlbGV2YW50IGxpYnJhcnkgcm91dGluZXMgbmVlZCB0aGUgaW5wdXQgc3RyaW5nIHRvIGJlIGluCisvLyBjb250aWd1b3VzIG1lbW9yeSwgZXZlbiBpZiB0aGUgdmFsdWUgc3Bhbm5lZCB0d28gb3IgbW9yZSBidWZmZXJzIGluIHRoZQorLy8gaW5wdXQuICBUaGVzZSByb3V0aW5lcyBoYW5kbGUgdGhhdC4KKy8vCisvLyBJbiB0aGUgY29tbW9uIGNhc2Ugd2UgY2FuIGp1c3QgcG9pbnQgdG8gdGhlIGlucHV0IGJ1ZmZlciB0byBnZXQgdGhpcworLy8gY29udGlndW91cyBzdHJpbmcgYW5kIGF2b2lkIGFueSBhY3R1YWwgY29weS4gIFNvIHdlIG9wdGltaXN0aWNhbGx5IGJlZ2luCisvLyB0aGlzIHdheS4gIEJ1dCB0aGVyZSBhcmUgYSBmZXcgY2FzZXMgd2hlcmUgd2UgbXVzdCBpbnN0ZWFkIGNvcHkgaW50byBhCisvLyBzZXBhcmF0ZSBidWZmZXI6CisvLworLy8gICAxLiBUaGUgc3RyaW5nIHdhcyBub3QgY29udGlndW91cyBpbiB0aGUgaW5wdXQgKGl0IHNwYW5uZWQgYnVmZmVycykuCisvLworLy8gICAyLiBUaGUgc3RyaW5nIGluY2x1ZGVkIGVzY2FwZSBzZXF1ZW5jZXMgdGhhdCBuZWVkIHRvIGJlIGludGVycHJldGVkIHRvIGdldAorLy8gICAgICB0aGUgdHJ1ZSB2YWx1ZSBpbiBhIGNvbnRpZ3VvdXMgYnVmZmVyLgorCitzdGF0aWMgdm9pZCBhc3NlcnRfYWNjdW11bGF0ZV9lbXB0eSh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgVVBCX1VOVVNFRChwKTsKKyAgYXNzZXJ0KHAtPmFjY3VtdWxhdGVkID09IE5VTEwpOworICBhc3NlcnQocC0+YWNjdW11bGF0ZWRfbGVuID09IDApOworfQorCitzdGF0aWMgdm9pZCBhY2N1bXVsYXRlX2NsZWFyKHVwYl9qc29uX3BhcnNlciAqcCkgeworICBwLT5hY2N1bXVsYXRlZCA9IE5VTEw7CisgIHAtPmFjY3VtdWxhdGVkX2xlbiA9IDA7Cit9CisKKy8vIFVzZWQgaW50ZXJuYWxseSBieSBhY2N1bXVsYXRlX2FwcGVuZCgpLgorc3RhdGljIGJvb2wgYWNjdW11bGF0ZV9yZWFsbG9jKHVwYl9qc29uX3BhcnNlciAqcCwgc2l6ZV90IG5lZWQpIHsKKyAgc2l6ZV90IG5ld19zaXplID0gVVBCX01BWChwLT5hY2N1bXVsYXRlX2J1Zl9zaXplLCAxMjgpOworICB3aGlsZSAobmV3X3NpemUgPCBuZWVkKSB7CisgICAgbmV3X3NpemUgPSBzYXR1cmF0aW5nX211bHRpcGx5KG5ld19zaXplLCAyKTsKKyAgfQorCisgIHZvaWQgKm1lbSA9IHJlYWxsb2MocC0+YWNjdW11bGF0ZV9idWYsIG5ld19zaXplKTsKKyAgaWYgKCFtZW0pIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhwLT5zdGF0dXMsICJPdXQgb2YgbWVtb3J5IGFsbG9jYXRpbmcgYnVmZmVyLiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHAtPmFjY3VtdWxhdGVfYnVmID0gbWVtOworICBwLT5hY2N1bXVsYXRlX2J1Zl9zaXplID0gbmV3X3NpemU7CisgIHJldHVybiB0cnVlOworfQorCisvLyBMb2dpY2FsbHkgYXBwZW5kcyB0aGUgZ2l2ZW4gZGF0YSB0byB0aGUgYXBwZW5kIGJ1ZmZlci4KKy8vIElmICJjYW5fYWxpYXMiIGlzIHRydWUsIHdlIHdpbGwgdHJ5IHRvIGF2b2lkIGFjdHVhbGx5IGNvcHlpbmcsIGJ1dCB0aGUgYnVmZmVyCisvLyBtdXN0IGJlIHZhbGlkIHVudGlsIHRoZSBuZXh0IGFjY3VtdWxhdGVfYXBwZW5kKCkgY2FsbCAoaWYgYW55KS4KK3N0YXRpYyBib29sIGFjY3VtdWxhdGVfYXBwZW5kKHVwYl9qc29uX3BhcnNlciAqcCwgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBjYW5fYWxpYXMpIHsKKyAgaWYgKCFwLT5hY2N1bXVsYXRlZCAmJiBjYW5fYWxpYXMpIHsKKyAgICBwLT5hY2N1bXVsYXRlZCA9IGJ1ZjsKKyAgICBwLT5hY2N1bXVsYXRlZF9sZW4gPSBsZW47CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBzaXplX3QgbmVlZDsKKyAgaWYgKCFjaGVja2VkX2FkZChwLT5hY2N1bXVsYXRlZF9sZW4sIGxlbiwgJm5lZWQpKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocC0+c3RhdHVzLCAiSW50ZWdlciBvdmVyZmxvdy4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAobmVlZCA+IHAtPmFjY3VtdWxhdGVfYnVmX3NpemUgJiYgIWFjY3VtdWxhdGVfcmVhbGxvYyhwLCBuZWVkKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChwLT5hY2N1bXVsYXRlZCAhPSBwLT5hY2N1bXVsYXRlX2J1ZikgeworICAgIG1lbWNweShwLT5hY2N1bXVsYXRlX2J1ZiwgcC0+YWNjdW11bGF0ZWQsIHAtPmFjY3VtdWxhdGVkX2xlbik7CisgICAgcC0+YWNjdW11bGF0ZWQgPSBwLT5hY2N1bXVsYXRlX2J1ZjsKKyAgfQorCisgIG1lbWNweShwLT5hY2N1bXVsYXRlX2J1ZiArIHAtPmFjY3VtdWxhdGVkX2xlbiwgYnVmLCBsZW4pOworICBwLT5hY2N1bXVsYXRlZF9sZW4gKz0gbGVuOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGRhdGEgYWNjdW11bGF0ZWQgc2luY2UgdGhlIGxhc3QgYWNjdW11bGF0ZV9jbGVhcigpCisvLyBjYWxsLCBhbmQgd3JpdGVzIHRoZSBsZW5ndGggdG8gKmxlbi4gIFRoaXMgd2l0aCBwb2ludCBlaXRoZXIgdG8gdGhlIGlucHV0CisvLyBidWZmZXIgb3IgYSB0ZW1wb3JhcnkgYWNjdW11bGF0ZSBidWZmZXIuCitzdGF0aWMgY29uc3QgY2hhciAqYWNjdW11bGF0ZV9nZXRwdHIodXBiX2pzb25fcGFyc2VyICpwLCBzaXplX3QgKmxlbikgeworICBhc3NlcnQocC0+YWNjdW11bGF0ZWQpOworICAqbGVuID0gcC0+YWNjdW11bGF0ZWRfbGVuOworICByZXR1cm4gcC0+YWNjdW11bGF0ZWQ7Cit9CisKKworLyogTXVsdC1wYXJ0IHRleHQgZGF0YSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gV2hlbiB3ZSBoYXZlIHRleHQgZGF0YSBpbiB0aGUgaW5wdXQsIGl0IGNhbiBvZnRlbiBjb21lIGluIG11bHRpcGxlIHNlZ21lbnRzLgorLy8gRm9yIGV4YW1wbGUsIHRoZXJlIG1heSBiZSBzb21lIHJhdyBzdHJpbmcgZGF0YSBmb2xsb3dlZCBieSBhbiBlc2NhcGUKKy8vIHNlcXVlbmNlLiAgVGhlIHR3byBzZWdtZW50cyBhcmUgcHJvY2Vzc2VkIHdpdGggZGlmZmVyZW50IGxvZ2ljLiAgQWxzbyBidWZmZXIKKy8vIHNlYW1zIGluIHRoZSBpbnB1dCBjYW4gY2F1c2UgbXVsdGlwbGUgc2VnbWVudHMuCisvLworLy8gQXMgd2Ugc2VlIHNlZ21lbnRzLCB0aGVyZSBhcmUgdHdvIG1haW4gY2FzZXMgZm9yIGhvdyB3ZSB3YW50IHRvIHByb2Nlc3MgdGhlbToKKy8vCisvLyAgMS4gd2Ugd2FudCB0byBwdXNoIHRoZSBjYXB0dXJlZCBpbnB1dCBkaXJlY3RseSB0byBzdHJpbmcgaGFuZGxlcnMuCisvLworLy8gIDIuIHdlIG5lZWQgdG8gYWNjdW11bGF0ZSBhbGwgdGhlIHBhcnRzIGludG8gYSBjb250aWd1b3VzIGJ1ZmZlciBmb3IgZnVydGhlcgorLy8gICAgIHByb2Nlc3NpbmcgKGZpZWxkIG5hbWUgbG9va3VwLCBzdHJpbmctPm51bWJlciBjb252ZXJzaW9uLCBldGMpLgorCisvLyBUaGlzIGlzIHRoZSBzZXQgb2Ygc3RhdGVzIGZvciBwLT5tdWx0aXBhcnRfc3RhdGUuCitlbnVtIHsKKyAgLy8gV2UgYXJlIG5vdCBjdXJyZW50bHkgcHJvY2Vzc2luZyBtdWx0aXBhcnQgZGF0YS4KKyAgTVVMVElQQVJUX0lOQUNUSVZFID0gMCwKKworICAvLyBXZSBhcmUgcHJvY2Vzc2luZyBtdWx0aXBhcnQgZGF0YSBieSBhY2N1bXVsYXRpbmcgaXQgaW50byBhIGNvbnRpZ3VvdXMKKyAgLy8gYnVmZmVyLgorICBNVUxUSVBBUlRfQUNDVU1VTEFURSA9IDEsCisKKyAgLy8gV2UgYXJlIHByb2Nlc3NpbmcgbXVsdGlwYXJ0IGRhdGEgYnkgcHVzaGluZyBlYWNoIHBhcnQgZGlyZWN0bHkgdG8gdGhlCisgIC8vIGN1cnJlbnQgc3RyaW5nIGhhbmRsZXJzLgorICBNVUxUSVBBUlRfUFVTSEVBR0VSTFkgPSAyCit9OworCisvLyBTdGFydCBhIG11bHRpLXBhcnQgdGV4dCB2YWx1ZSB3aGVyZSB3ZSBhY2N1bXVsYXRlIHRoZSBkYXRhIGZvciBwcm9jZXNzaW5nIGF0CisvLyB0aGUgZW5kLgorc3RhdGljIHZvaWQgbXVsdGlwYXJ0X3N0YXJ0YWNjdW0odXBiX2pzb25fcGFyc2VyICpwKSB7CisgIGFzc2VydF9hY2N1bXVsYXRlX2VtcHR5KHApOworICBhc3NlcnQocC0+bXVsdGlwYXJ0X3N0YXRlID09IE1VTFRJUEFSVF9JTkFDVElWRSk7CisgIHAtPm11bHRpcGFydF9zdGF0ZSA9IE1VTFRJUEFSVF9BQ0NVTVVMQVRFOworfQorCisvLyBTdGFydCBhIG11bHRpLXBhcnQgdGV4dCB2YWx1ZSB3aGVyZSB3ZSBpbW1lZGlhdGVseSBwdXNoIHRleHQgZGF0YSB0byBhIHN0cmluZworLy8gdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gc2VsZWN0b3IuCitzdGF0aWMgdm9pZCBtdWx0aXBhcnRfc3RhcnQodXBiX2pzb25fcGFyc2VyICpwLCB1cGJfc2VsZWN0b3JfdCBzZWwpIHsKKyAgYXNzZXJ0X2FjY3VtdWxhdGVfZW1wdHkocCk7CisgIGFzc2VydChwLT5tdWx0aXBhcnRfc3RhdGUgPT0gTVVMVElQQVJUX0lOQUNUSVZFKTsKKyAgcC0+bXVsdGlwYXJ0X3N0YXRlID0gTVVMVElQQVJUX1BVU0hFQUdFUkxZOworICBwLT5zdHJpbmdfc2VsZWN0b3IgPSBzZWw7Cit9CisKK3N0YXRpYyBib29sIG11bHRpcGFydF90ZXh0KHVwYl9qc29uX3BhcnNlciAqcCwgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBjYW5fYWxpYXMpIHsKKyAgc3dpdGNoIChwLT5tdWx0aXBhcnRfc3RhdGUpIHsKKyAgICBjYXNlIE1VTFRJUEFSVF9JTkFDVElWRToKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKAorICAgICAgICAgIHAtPnN0YXR1cywgIkludGVybmFsIGVycm9yOiB1bmV4cGVjdGVkIHN0YXRlIE1VTFRJUEFSVF9JTkFDVElWRSIpOworICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgY2FzZSBNVUxUSVBBUlRfQUNDVU1VTEFURToKKyAgICAgIGlmICghYWNjdW11bGF0ZV9hcHBlbmQocCwgYnVmLCBsZW4sIGNhbl9hbGlhcykpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIE1VTFRJUEFSVF9QVVNIRUFHRVJMWTogeworICAgICAgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlID0gY2FuX2FsaWFzID8gcC0+aGFuZGxlIDogTlVMTDsKKyAgICAgIHVwYl9zaW5rX3B1dHN0cmluZygmcC0+dG9wLT5zaW5rLCBwLT5zdHJpbmdfc2VsZWN0b3IsIGJ1ZiwgbGVuLCBoYW5kbGUpOworICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIE5vdGU6IHRoaXMgaW52YWxpZGF0ZXMgdGhlIGFjY3VtdWxhdGUgYnVmZmVyISAgQ2FsbCBvbmx5IGFmdGVyIHJlYWRpbmcgaXRzCisvLyBjb250ZW50cy4KK3N0YXRpYyB2b2lkIG11bHRpcGFydF9lbmQodXBiX2pzb25fcGFyc2VyICpwKSB7CisgIGFzc2VydChwLT5tdWx0aXBhcnRfc3RhdGUgIT0gTVVMVElQQVJUX0lOQUNUSVZFKTsKKyAgcC0+bXVsdGlwYXJ0X3N0YXRlID0gTVVMVElQQVJUX0lOQUNUSVZFOworICBhY2N1bXVsYXRlX2NsZWFyKHApOworfQorCisKKy8qIElucHV0IGNhcHR1cmUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIEZ1bmN0aW9uYWxpdHkgZm9yIGNhcHR1cmluZyBhIHJlZ2lvbiBvZiB0aGUgaW5wdXQgYXMgdGV4dC4gIEdyYWNlZnVsbHkKKy8vIGhhbmRsZXMgdGhlIGNhc2Ugd2hlcmUgYSBidWZmZXIgc2VhbSBvY2N1cnMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgY2FwdHVyZWQKKy8vIHJlZ2lvbi4KKworc3RhdGljIHZvaWQgY2FwdHVyZV9iZWdpbih1cGJfanNvbl9wYXJzZXIgKnAsIGNvbnN0IGNoYXIgKnB0cikgeworICBhc3NlcnQocC0+bXVsdGlwYXJ0X3N0YXRlICE9IE1VTFRJUEFSVF9JTkFDVElWRSk7CisgIGFzc2VydChwLT5jYXB0dXJlID09IE5VTEwpOworICBwLT5jYXB0dXJlID0gcHRyOworfQorCitzdGF0aWMgYm9vbCBjYXB0dXJlX2VuZCh1cGJfanNvbl9wYXJzZXIgKnAsIGNvbnN0IGNoYXIgKnB0cikgeworICBhc3NlcnQocC0+Y2FwdHVyZSk7CisgIGlmIChtdWx0aXBhcnRfdGV4dChwLCBwLT5jYXB0dXJlLCBwdHIgLSBwLT5jYXB0dXJlLCB0cnVlKSkgeworICAgIHAtPmNhcHR1cmUgPSBOVUxMOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisvLyBUaGlzIGlzIGNhbGxlZCBhdCB0aGUgZW5kIG9mIGVhY2ggaW5wdXQgYnVmZmVyIChpZS4gd2hlbiB3ZSBoYXZlIGhpdCBhCisvLyBidWZmZXIgc2VhbSkuICBJZiB3ZSBhcmUgaW4gdGhlIG1pZGRsZSBvZiBjYXB0dXJpbmcgdGhlIGlucHV0LCB0aGlzCisvLyBwcm9jZXNzZXMgdGhlIHVucHJvY2Vzc2VkIGNhcHR1cmUgcmVnaW9uLgorc3RhdGljIHZvaWQgY2FwdHVyZV9zdXNwZW5kKHVwYl9qc29uX3BhcnNlciAqcCwgY29uc3QgY2hhciAqKnB0cikgeworICBpZiAoIXAtPmNhcHR1cmUpIHJldHVybjsKKworICBpZiAobXVsdGlwYXJ0X3RleHQocCwgcC0+Y2FwdHVyZSwgKnB0ciAtIHAtPmNhcHR1cmUsIGZhbHNlKSkgeworICAgIC8vIFdlIHVzZSB0aGlzIGFzIGEgc2lnbmFsIHRoYXQgd2Ugd2VyZSBpbiB0aGUgbWlkZGxlIG9mIGNhcHR1cmluZywgYW5kCisgICAgLy8gdGhhdCBjYXB0dXJpbmcgc2hvdWxkIHJlc3VtZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBuZXh0IGJ1ZmZlci4KKyAgICAvLworICAgIC8vIFdlIGNhbid0IHVzZSAqcHRyIGhlcmUsIGJlY2F1c2Ugd2UgaGF2ZSBubyBndWFyYW50ZWUgdGhhdCB0aGlzIHBvaW50ZXIKKyAgICAvLyB3aWxsIGJlIHZhbGlkIHdoZW4gd2UgcmVzdW1lIChpZiB0aGUgdW5kZXJseWluZyBtZW1vcnkgaXMgZnJlZWQsIHRoZW4KKyAgICAvLyB1c2luZyB0aGUgcG9pbnRlciBhdCBhbGwsIGV2ZW4gdG8gY29tcGFyZSB0byBOVUxMLCBpcyBsaWtlbHkgdW5kZWZpbmVkCisgICAgLy8gYmVoYXZpb3IpLgorICAgIHAtPmNhcHR1cmUgPSAmc3VzcGVuZF9jYXB0dXJlOworICB9IGVsc2UgeworICAgIC8vIE5lZWQgdG8gYmFjayB1cCB0aGUgcG9pbnRlciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBjYXB0dXJlLCBzaW5jZQorICAgIC8vIHdlIHdlcmUgbm90IGFibGUgdG8gYWN0dWFsbHkgcHJlc2VydmUgaXQuCisgICAgKnB0ciA9IHAtPmNhcHR1cmU7CisgIH0KK30KKworc3RhdGljIHZvaWQgY2FwdHVyZV9yZXN1bWUodXBiX2pzb25fcGFyc2VyICpwLCBjb25zdCBjaGFyICpwdHIpIHsKKyAgaWYgKHAtPmNhcHR1cmUpIHsKKyAgICBhc3NlcnQocC0+Y2FwdHVyZSA9PSAmc3VzcGVuZF9jYXB0dXJlKTsKKyAgICBwLT5jYXB0dXJlID0gcHRyOworICB9Cit9CisKKworLyogQ2FsbGJhY2tzIGZyb20gdGhlIHBhcnNlciAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gVGhlc2UgYXJlIHRoZSBmdW5jdGlvbnMgY2FsbGVkIGRpcmVjdGx5IGZyb20gdGhlIHBhcnNlciBpdHNlbGYuCisvLyBXZSBkZWZpbmUgdGhlc2UgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlaXIgZGVjbGFyYXRpb25zIGluIHRoZSBwYXJzZXIuCisKK3N0YXRpYyBjaGFyIGVzY2FwZV9jaGFyKGNoYXIgaW4pIHsKKyAgc3dpdGNoIChpbikgeworICAgIGNhc2UgJ3InOiByZXR1cm4gJ1xyJzsKKyAgICBjYXNlICd0JzogcmV0dXJuICdcdCc7CisgICAgY2FzZSAnbic6IHJldHVybiAnXG4nOworICAgIGNhc2UgJ2YnOiByZXR1cm4gJ1xmJzsKKyAgICBjYXNlICdiJzogcmV0dXJuICdcYic7CisgICAgY2FzZSAnLyc6IHJldHVybiAnLyc7CisgICAgY2FzZSAnIic6IHJldHVybiAnIic7CisgICAgY2FzZSAnXFwnOiByZXR1cm4gJ1xcJzsKKyAgICBkZWZhdWx0OgorICAgICAgYXNzZXJ0KDApOworICAgICAgcmV0dXJuICd4JzsKKyAgfQorfQorCitzdGF0aWMgYm9vbCBlc2NhcGUodXBiX2pzb25fcGFyc2VyICpwLCBjb25zdCBjaGFyICpwdHIpIHsKKyAgY2hhciBjaCA9IGVzY2FwZV9jaGFyKCpwdHIpOworICByZXR1cm4gbXVsdGlwYXJ0X3RleHQocCwgJmNoLCAxLCBmYWxzZSk7Cit9CisKK3N0YXRpYyB2b2lkIHN0YXJ0X2hleCh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgcC0+ZGlnaXQgPSAwOworfQorCitzdGF0aWMgdm9pZCBoZXhkaWdpdCh1cGJfanNvbl9wYXJzZXIgKnAsIGNvbnN0IGNoYXIgKnB0cikgeworICBjaGFyIGNoID0gKnB0cjsKKworICBwLT5kaWdpdCA8PD0gNDsKKworICBpZiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgeworICAgIHAtPmRpZ2l0ICs9IChjaCAtICcwJyk7CisgIH0gZWxzZSBpZiAoY2ggPj0gJ2EnICYmIGNoIDw9ICdmJykgeworICAgIHAtPmRpZ2l0ICs9ICgoY2ggLSAnYScpICsgMTApOworICB9IGVsc2UgeworICAgIGFzc2VydChjaCA+PSAnQScgJiYgY2ggPD0gJ0YnKTsKKyAgICBwLT5kaWdpdCArPSAoKGNoIC0gJ0EnKSArIDEwKTsKKyAgfQorfQorCitzdGF0aWMgYm9vbCBlbmRfaGV4KHVwYl9qc29uX3BhcnNlciAqcCkgeworICB1aW50MzJfdCBjb2RlcG9pbnQgPSBwLT5kaWdpdDsKKworICAvLyBlbWl0IHRoZSBjb2RlcG9pbnQgYXMgVVRGLTguCisgIGNoYXIgdXRmOFszXTsgLy8gc3VwcG9ydCBcdTAwMDAgLS0gXHVGRkZGIC0tIG5lZWQgb25seSB0aHJlZSBieXRlcy4KKyAgaW50IGxlbmd0aCA9IDA7CisgIGlmIChjb2RlcG9pbnQgPD0gMHg3RikgeworICAgIHV0ZjhbMF0gPSBjb2RlcG9pbnQ7CisgICAgbGVuZ3RoID0gMTsKKyAgfSBlbHNlIGlmIChjb2RlcG9pbnQgPD0gMHgwN0ZGKSB7CisgICAgdXRmOFsxXSA9IChjb2RlcG9pbnQgJiAweDNGKSB8IDB4ODA7CisgICAgY29kZXBvaW50ID4+PSA2OworICAgIHV0ZjhbMF0gPSAoY29kZXBvaW50ICYgMHgxRikgfCAweEMwOworICAgIGxlbmd0aCA9IDI7CisgIH0gZWxzZSAvKiBjb2RlcG9pbnQgPD0gMHhGRkZGICovIHsKKyAgICB1dGY4WzJdID0gKGNvZGVwb2ludCAmIDB4M0YpIHwgMHg4MDsKKyAgICBjb2RlcG9pbnQgPj49IDY7CisgICAgdXRmOFsxXSA9IChjb2RlcG9pbnQgJiAweDNGKSB8IDB4ODA7CisgICAgY29kZXBvaW50ID4+PSA2OworICAgIHV0ZjhbMF0gPSAoY29kZXBvaW50ICYgMHgwRikgfCAweEUwOworICAgIGxlbmd0aCA9IDM7CisgIH0KKyAgLy8gVE9ETyhoYWJlcm1hbik6IEhhbmRsZSBoaWdoIHN1cnJvZ2F0ZXM6IGlmIGNvZGVwb2ludCBpcyBhIGhpZ2ggc3Vycm9nYXRlCisgIC8vIHdlIGhhdmUgdG8gd2FpdCBmb3IgdGhlIG5leHQgZXNjYXBlIHRvIGdldCB0aGUgZnVsbCBjb2RlIHBvaW50KS4KKworICByZXR1cm4gbXVsdGlwYXJ0X3RleHQocCwgdXRmOCwgbGVuZ3RoLCBmYWxzZSk7Cit9CisKK3N0YXRpYyB2b2lkIHN0YXJ0X3RleHQodXBiX2pzb25fcGFyc2VyICpwLCBjb25zdCBjaGFyICpwdHIpIHsKKyAgY2FwdHVyZV9iZWdpbihwLCBwdHIpOworfQorCitzdGF0aWMgYm9vbCBlbmRfdGV4dCh1cGJfanNvbl9wYXJzZXIgKnAsIGNvbnN0IGNoYXIgKnB0cikgeworICByZXR1cm4gY2FwdHVyZV9lbmQocCwgcHRyKTsKK30KKworc3RhdGljIHZvaWQgc3RhcnRfbnVtYmVyKHVwYl9qc29uX3BhcnNlciAqcCwgY29uc3QgY2hhciAqcHRyKSB7CisgIG11bHRpcGFydF9zdGFydGFjY3VtKHApOworICBjYXB0dXJlX2JlZ2luKHAsIHB0cik7Cit9CisKK3N0YXRpYyBib29sIHBhcnNlX251bWJlcih1cGJfanNvbl9wYXJzZXIgKnApOworCitzdGF0aWMgYm9vbCBlbmRfbnVtYmVyKHVwYl9qc29uX3BhcnNlciAqcCwgY29uc3QgY2hhciAqcHRyKSB7CisgIGlmICghY2FwdHVyZV9lbmQocCwgcHRyKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiBwYXJzZV9udW1iZXIocCk7Cit9CisKK3N0YXRpYyBib29sIHBhcnNlX251bWJlcih1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgLy8gc3RydG9sKCkgYW5kIGZyaWVuZHMgdW5mb3J0dW5hdGVseSBkbyBub3Qgc3VwcG9ydCBzcGVjaWZ5aW5nIHRoZSBsZW5ndGggb2YKKyAgLy8gdGhlIGlucHV0IHN0cmluZywgc28gd2UgbmVlZCB0byBmb3JjZSBhIGNvcHkgaW50byBhIE5VTEwtdGVybWluYXRlZCBidWZmZXIuCisgIGlmICghbXVsdGlwYXJ0X3RleHQocCwgIlwwIiwgMSwgZmFsc2UpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgc2l6ZV90IGxlbjsKKyAgY29uc3QgY2hhciAqYnVmID0gYWNjdW11bGF0ZV9nZXRwdHIocCwgJmxlbik7CisgIGNvbnN0IGNoYXIgKm15ZW5kID0gYnVmICsgbGVuIC0gMTsgIC8vIE9uZSBmb3IgTlVMTC4KKworICBjaGFyICplbmQ7CisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUocC0+dG9wLT5mKSkgeworICAgIGNhc2UgVVBCX1RZUEVfRU5VTToKKyAgICBjYXNlIFVQQl9UWVBFX0lOVDMyOiB7CisgICAgICBsb25nIHZhbCA9IHN0cnRvbChwLT5hY2N1bXVsYXRlZCwgJmVuZCwgMCk7CisgICAgICBpZiAodmFsID4gSU5UMzJfTUFYIHx8IHZhbCA8IElOVDMyX01JTiB8fCBlcnJubyA9PSBFUkFOR0UgfHwgZW5kICE9IG15ZW5kKQorICAgICAgICBnb3RvIGVycjsKKyAgICAgIGVsc2UKKyAgICAgICAgdXBiX3NpbmtfcHV0aW50MzIoJnAtPnRvcC0+c2luaywgcGFyc2VyX2dldHNlbChwKSwgdmFsKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX0lOVDY0OiB7CisgICAgICBsb25nIGxvbmcgdmFsID0gc3RydG9sbChwLT5hY2N1bXVsYXRlZCwgJmVuZCwgMCk7CisgICAgICBpZiAodmFsID4gSU5UNjRfTUFYIHx8IHZhbCA8IElOVDY0X01JTiB8fCBlcnJubyA9PSBFUkFOR0UgfHwgZW5kICE9IG15ZW5kKQorICAgICAgICBnb3RvIGVycjsKKyAgICAgIGVsc2UKKyAgICAgICAgdXBiX3NpbmtfcHV0aW50NjQoJnAtPnRvcC0+c2luaywgcGFyc2VyX2dldHNlbChwKSwgdmFsKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjogeworICAgICAgdW5zaWduZWQgbG9uZyB2YWwgPSBzdHJ0b3VsKHAtPmFjY3VtdWxhdGVkLCAmZW5kLCAwKTsKKyAgICAgIGlmICh2YWwgPiBVSU5UMzJfTUFYIHx8IGVycm5vID09IEVSQU5HRSB8fCBlbmQgIT0gbXllbmQpCisgICAgICAgIGdvdG8gZXJyOworICAgICAgZWxzZQorICAgICAgICB1cGJfc2lua19wdXR1aW50MzIoJnAtPnRvcC0+c2luaywgcGFyc2VyX2dldHNlbChwKSwgdmFsKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDogeworICAgICAgdW5zaWduZWQgbG9uZyBsb25nIHZhbCA9IHN0cnRvdWxsKHAtPmFjY3VtdWxhdGVkLCAmZW5kLCAwKTsKKyAgICAgIGlmICh2YWwgPiBVSU5UNjRfTUFYIHx8IGVycm5vID09IEVSQU5HRSB8fCBlbmQgIT0gbXllbmQpCisgICAgICAgIGdvdG8gZXJyOworICAgICAgZWxzZQorICAgICAgICB1cGJfc2lua19wdXR1aW50NjQoJnAtPnRvcC0+c2luaywgcGFyc2VyX2dldHNlbChwKSwgdmFsKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIFVQQl9UWVBFX0RPVUJMRTogeworICAgICAgZG91YmxlIHZhbCA9IHN0cnRvZChwLT5hY2N1bXVsYXRlZCwgJmVuZCk7CisgICAgICBpZiAoZXJybm8gPT0gRVJBTkdFIHx8IGVuZCAhPSBteWVuZCkKKyAgICAgICAgZ290byBlcnI7CisgICAgICBlbHNlCisgICAgICAgIHVwYl9zaW5rX3B1dGRvdWJsZSgmcC0+dG9wLT5zaW5rLCBwYXJzZXJfZ2V0c2VsKHApLCB2YWwpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfRkxPQVQ6IHsKKyAgICAgIGZsb2F0IHZhbCA9IHN0cnRvZihwLT5hY2N1bXVsYXRlZCwgJmVuZCk7CisgICAgICBpZiAoZXJybm8gPT0gRVJBTkdFIHx8IGVuZCAhPSBteWVuZCkKKyAgICAgICAgZ290byBlcnI7CisgICAgICBlbHNlCisgICAgICAgIHVwYl9zaW5rX3B1dGZsb2F0KCZwLT50b3AtPnNpbmssIHBhcnNlcl9nZXRzZWwocCksIHZhbCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGFzc2VydChmYWxzZSk7CisgIH0KKworICBtdWx0aXBhcnRfZW5kKHApOworCisgIHJldHVybiB0cnVlOworCitlcnI6CisgIHVwYl9zdGF0dXNfc2V0ZXJyZihwLT5zdGF0dXMsICJlcnJvciBwYXJzaW5nIG51bWJlcjogJXMiLCBidWYpOworICBtdWx0aXBhcnRfZW5kKHApOworICByZXR1cm4gZmFsc2U7Cit9CisKK3N0YXRpYyBib29sIHBhcnNlcl9wdXRib29sKHVwYl9qc29uX3BhcnNlciAqcCwgYm9vbCB2YWwpIHsKKyAgaWYgKHVwYl9maWVsZGRlZl90eXBlKHAtPnRvcC0+ZikgIT0gVVBCX1RZUEVfQk9PTCkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihwLT5zdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICJCb29sZWFuIHZhbHVlIHNwZWNpZmllZCBmb3Igbm9uLWJvb2wgZmllbGQ6ICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgdXBiX2ZpZWxkZGVmX25hbWUocC0+dG9wLT5mKSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgYm9vbCBvayA9IHVwYl9zaW5rX3B1dGJvb2woJnAtPnRvcC0+c2luaywgcGFyc2VyX2dldHNlbChwKSwgdmFsKTsKKyAgVVBCX0FTU0VSVF9WQVIob2ssIG9rKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgc3RhcnRfc3RyaW5ndmFsKHVwYl9qc29uX3BhcnNlciAqcCkgeworICBhc3NlcnQocC0+dG9wLT5mKTsKKworICBpZiAodXBiX2ZpZWxkZGVmX2lzc3RyaW5nKHAtPnRvcC0+ZikpIHsKKyAgICBpZiAoIWNoZWNrX3N0YWNrKHApKSByZXR1cm4gZmFsc2U7CisKKyAgICAvLyBTdGFydCBhIG5ldyBwYXJzZXIgZnJhbWU6IHBhcnNlciBmcmFtZXMgY29ycmVzcG9uZCBvbmUtdG8tb25lIHdpdGgKKyAgICAvLyBoYW5kbGVyIGZyYW1lcywgYW5kIHN0cmluZyBldmVudHMgb2NjdXIgaW4gYSBzdWItZnJhbWUuCisgICAgdXBiX2pzb25wYXJzZXJfZnJhbWUgKmlubmVyID0gcC0+dG9wICsgMTsKKyAgICB1cGJfc2VsZWN0b3JfdCBzZWwgPSBnZXRzZWxfZm9yX2hhbmRsZXJ0eXBlKHAsIFVQQl9IQU5ETEVSX1NUQVJUU1RSKTsKKyAgICB1cGJfc2lua19zdGFydHN0cigmcC0+dG9wLT5zaW5rLCBzZWwsIDAsICZpbm5lci0+c2luayk7CisgICAgaW5uZXItPm0gPSBwLT50b3AtPm07CisgICAgaW5uZXItPmYgPSBwLT50b3AtPmY7CisgICAgaW5uZXItPmlzX21hcCA9IGZhbHNlOworICAgIGlubmVyLT5pc19tYXBlbnRyeSA9IGZhbHNlOworICAgIHAtPnRvcCA9IGlubmVyOworCisgICAgaWYgKHVwYl9maWVsZGRlZl90eXBlKHAtPnRvcC0+ZikgPT0gVVBCX1RZUEVfU1RSSU5HKSB7CisgICAgICAvLyBGb3IgU1RSSU5HIGZpZWxkcyB3ZSBwdXNoIGRhdGEgZGlyZWN0bHkgdG8gdGhlIGhhbmRsZXJzIGFzIGl0IGlzCisgICAgICAvLyBwYXJzZWQuICBXZSBkb24ndCBkbyB0aGlzIHlldCBmb3IgQllURVMgZmllbGRzLCBiZWNhdXNlIG91ciBiYXNlNjQKKyAgICAgIC8vIGRlY29kZXIgaXMgbm90IHN0cmVhbWluZy4KKyAgICAgIC8vCisgICAgICAvLyBUT0RPKGhhYmVybWFuKTogbWFrZSBiYXNlNjQgZGVjb2Rpbmcgc3RyZWFtaW5nIGFsc28uCisgICAgICBtdWx0aXBhcnRfc3RhcnQocCwgZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9TVFJJTkcpKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBtdWx0aXBhcnRfc3RhcnRhY2N1bShwKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfdHlwZShwLT50b3AtPmYpID09IFVQQl9UWVBFX0VOVU0pIHsKKyAgICAvLyBObyBuZWVkIHRvIHB1c2ggYSBmcmFtZSAtLSBzeW1ib2xpYyBlbnVtIG5hbWVzIGluIHF1b3RlcyByZW1haW4gaW4gdGhlCisgICAgLy8gY3VycmVudCBwYXJzZXIgZnJhbWUuCisgICAgLy8KKyAgICAvLyBFbnVtIHN0cmluZyB2YWx1ZXMgbXVzdCBhY2N1bXVsYXRlIHNvIHdlIGNhbiBsb29rIHVwIHRoZSB2YWx1ZSBpbiBhIHRhYmxlCisgICAgLy8gb25jZSBpdCBpcyBjb21wbGV0ZS4KKyAgICBtdWx0aXBhcnRfc3RhcnRhY2N1bShwKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycmYocC0+c3RhdHVzLAorICAgICAgICAgICAgICAgICAgICAgICAiU3RyaW5nIHNwZWNpZmllZCBmb3Igbm9uLXN0cmluZy9ub24tZW51bSBmaWVsZDogJXMiLAorICAgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfbmFtZShwLT50b3AtPmYpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworc3RhdGljIGJvb2wgZW5kX3N0cmluZ3ZhbCh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgYm9vbCBvayA9IHRydWU7CisKKyAgc3dpdGNoICh1cGJfZmllbGRkZWZfdHlwZShwLT50b3AtPmYpKSB7CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzoKKyAgICAgIGlmICghYmFzZTY0X3B1c2gocCwgZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9TVFJJTkcpLAorICAgICAgICAgICAgICAgICAgICAgICBwLT5hY2N1bXVsYXRlZCwgcC0+YWNjdW11bGF0ZWRfbGVuKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBGYWxsIHRocm91Z2guCisKKyAgICBjYXNlIFVQQl9UWVBFX1NUUklORzogeworICAgICAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9FTkRTVFIpOworICAgICAgdXBiX3NpbmtfZW5kc3RyKCZwLT50b3AtPnNpbmssIHNlbCk7CisgICAgICBwLT50b3AtLTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgVVBCX1RZUEVfRU5VTTogeworICAgICAgLy8gUmVzb2x2ZSBlbnVtIHN5bWJvbGljIG5hbWUgdG8gaW50ZWdlciB2YWx1ZS4KKyAgICAgIGNvbnN0IHVwYl9lbnVtZGVmICplbnVtZGVmID0KKyAgICAgICAgICAoY29uc3QgdXBiX2VudW1kZWYqKXVwYl9maWVsZGRlZl9zdWJkZWYocC0+dG9wLT5mKTsKKworICAgICAgc2l6ZV90IGxlbjsKKyAgICAgIGNvbnN0IGNoYXIgKmJ1ZiA9IGFjY3VtdWxhdGVfZ2V0cHRyKHAsICZsZW4pOworCisgICAgICBpbnQzMl90IGludF92YWwgPSAwOworICAgICAgb2sgPSB1cGJfZW51bWRlZl9udG9pKGVudW1kZWYsIGJ1ZiwgbGVuLCAmaW50X3ZhbCk7CisKKyAgICAgIGlmIChvaykgeworICAgICAgICB1cGJfc2VsZWN0b3JfdCBzZWwgPSBwYXJzZXJfZ2V0c2VsKHApOworICAgICAgICB1cGJfc2lua19wdXRpbnQzMigmcC0+dG9wLT5zaW5rLCBzZWwsIGludF92YWwpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdXBiX3N0YXR1c19zZXRlcnJmKHAtPnN0YXR1cywgIkVudW0gdmFsdWUgdW5rbm93bjogJyUuKnMnIiwgbGVuLCBidWYpOworICAgICAgfQorCisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBkZWZhdWx0OgorICAgICAgYXNzZXJ0KGZhbHNlKTsKKyAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHAtPnN0YXR1cywgIkludGVybmFsIGVycm9yIGluIEpTT04gZGVjb2RlciIpOworICAgICAgb2sgPSBmYWxzZTsKKyAgICAgIGJyZWFrOworICB9CisKKyAgbXVsdGlwYXJ0X2VuZChwKTsKKworICByZXR1cm4gb2s7Cit9CisKK3N0YXRpYyB2b2lkIHN0YXJ0X21lbWJlcih1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgYXNzZXJ0KCFwLT50b3AtPmYpOworICBtdWx0aXBhcnRfc3RhcnRhY2N1bShwKTsKK30KKworLy8gSGVscGVyOiBpbnZva2VkIGR1cmluZyBwYXJzZV9tYXBlbnRyeSgpIHRvIGVtaXQgdGhlIG1hcGVudHJ5IG1lc3NhZ2UncyBrZXkKKy8vIGZpZWxkIGJhc2VkIG9uIHRoZSBjdXJyZW50IGNvbnRlbnRzIG9mIHRoZSBhY2N1bXVsYXRlIGJ1ZmZlci4KK3N0YXRpYyBib29sIHBhcnNlX21hcGVudHJ5X2tleSh1cGJfanNvbl9wYXJzZXIgKnApIHsKKworICBzaXplX3QgbGVuOworICBjb25zdCBjaGFyICpidWYgPSBhY2N1bXVsYXRlX2dldHB0cihwLCAmbGVuKTsKKworICAvLyBFbWl0IHRoZSBrZXkgZmllbGQuIFdlIGRvIGEgYml0IG9mIGFkLWhvYyBwYXJzaW5nIGhlcmUgYmVjYXVzZSB0aGUKKyAgLy8gcGFyc2VyIHN0YXRlIG1hY2hpbmUgaGFzIGFscmVhZHkgZGVjaWRlZCB0aGF0IHRoaXMgaXMgYSBzdHJpbmcgZmllbGQKKyAgLy8gbmFtZSwgYW5kIHdlIGFyZSByZWludGVycHJldGluZyBpdCBhcyBzb21lIGFyYml0cmFyeSBrZXkgdHlwZS4gSW4KKyAgLy8gcGFydGljdWxhciwgaW50ZWdlciBhbmQgYm9vbCBrZXlzIGFyZSBxdW90ZWQsIHNvIHdlIG5lZWQgdG8gcGFyc2UgdGhlCisgIC8vIHF1b3RlZCBzdHJpbmcgY29udGVudHMgaGVyZS4KKworICBwLT50b3AtPmYgPSB1cGJfbXNnZGVmX2l0b2YocC0+dG9wLT5tLCBVUEJfTUFQRU5UUllfS0VZKTsKKyAgaWYgKHAtPnRvcC0+ZiA9PSBOVUxMKSB7CisgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocC0+c3RhdHVzLCAibWFwZW50cnkgbWVzc2FnZSBoYXMgbm8ga2V5Iik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUocC0+dG9wLT5mKSkgeworICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDoKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjoKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQ2NDoKKyAgICAgIC8vIEludm9rZSBlbmRfbnVtYmVyLiBUaGUgYWNjdW0gYnVmZmVyIGhhcyB0aGUgbnVtYmVyJ3MgdGV4dCBhbHJlYWR5LgorICAgICAgaWYgKCFwYXJzZV9udW1iZXIocCkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOgorICAgICAgaWYgKGxlbiA9PSA0ICYmICFzdHJuY21wKGJ1ZiwgInRydWUiLCA0KSkgeworICAgICAgICBpZiAoIXBhcnNlcl9wdXRib29sKHAsIHRydWUpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKGxlbiA9PSA1ICYmICFzdHJuY21wKGJ1ZiwgImZhbHNlIiwgNSkpIHsKKyAgICAgICAgaWYgKCFwYXJzZXJfcHV0Ym9vbChwLCBmYWxzZSkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHAtPnN0YXR1cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hcCBib29sIGtleSBub3QgJ3RydWUnIG9yICdmYWxzZSciKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgbXVsdGlwYXJ0X2VuZChwKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOgorICAgIGNhc2UgVVBCX1RZUEVfQllURVM6IHsKKyAgICAgIHVwYl9zaW5rIHN1YnNpbms7CisgICAgICB1cGJfc2VsZWN0b3JfdCBzZWwgPSBnZXRzZWxfZm9yX2hhbmRsZXJ0eXBlKHAsIFVQQl9IQU5ETEVSX1NUQVJUU1RSKTsKKyAgICAgIHVwYl9zaW5rX3N0YXJ0c3RyKCZwLT50b3AtPnNpbmssIHNlbCwgbGVuLCAmc3Vic2luayk7CisgICAgICBzZWwgPSBnZXRzZWxfZm9yX2hhbmRsZXJ0eXBlKHAsIFVQQl9IQU5ETEVSX1NUUklORyk7CisgICAgICB1cGJfc2lua19wdXRzdHJpbmcoJnN1YnNpbmssIHNlbCwgYnVmLCBsZW4sIE5VTEwpOworICAgICAgc2VsID0gZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9FTkRTVFIpOworICAgICAgdXBiX3NpbmtfZW5kc3RyKCZzdWJzaW5rLCBzZWwpOworICAgICAgbXVsdGlwYXJ0X2VuZChwKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgdXBiX3N0YXR1c19zZXRlcnJtc2cocC0+c3RhdHVzLCAiSW52YWxpZCBmaWVsZCB0eXBlIGZvciBtYXAga2V5Iik7CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gSGVscGVyOiBlbWl0IG9uZSBtYXAgZW50cnkgKGFzIGEgc3VibWVzc2FnZSBpbiB0aGUgbWFwIGZpZWxkIHNlcXVlbmNlKS4gVGhpcworLy8gaXMgaW52b2tlZCBmcm9tIGVuZF9tZW1iZXJuYW1lKCksIGF0IHRoZSBlbmQgb2YgdGhlIG1hcCBlbnRyeSdzIGtleSBzdHJpbmcsCisvLyB3aXRoIHRoZSBtYXAga2V5IGluIHRoZSBhY2N1bXVsYXRlIGJ1ZmZlci4gSXQgcGFyc2VzIHRoZSBrZXkgZnJvbSB0aGF0CisvLyBidWZmZXIsIGVtaXRzIHRoZSBoYW5kbGVyIGNhbGxzIHRvIHN0YXJ0IHRoZSBtYXBlbnRyeSBzdWJtZXNzYWdlIChzZXR0aW5nIHVwCisvLyBpdHMgc3ViZnJhbWUgaW4gdGhlIHByb2Nlc3MpLCBhbmQgc2V0cyB1cCBzdGF0ZSBpbiB0aGUgc3ViZnJhbWUgc28gdGhhdCB0aGUKKy8vIHZhbHVlIHBhcnNlciAoaW52b2tlZCBuZXh0KSB3aWxsIGVtaXQgdGhlIG1hcGVudHJ5J3MgdmFsdWUgZmllbGQgYW5kIHRoZW4KKy8vIGVuZCB0aGUgbWFwZW50cnkgbWVzc2FnZS4KKworc3RhdGljIGJvb2wgaGFuZGxlX21hcGVudHJ5KHVwYl9qc29uX3BhcnNlciAqcCkgeworICAvLyBNYXAgZW50cnk6IHAtPnRvcC0+c2luayBpcyB0aGUgc2VxIGZyYW1lLCBzbyB3ZSBuZWVkIHRvIHN0YXJ0IGEgZnJhbWUKKyAgLy8gZm9yIHRoZSBtYXBlbnRyeSBpdHNlbGYsIGFuZCB0aGVuIHNldCB8ZnwgaW4gdGhhdCBmcmFtZSBzbyB0aGF0IHRoZSBtYXAKKyAgLy8gdmFsdWUgZmllbGQgaXMgcGFyc2VkLCBhbmQgYWxzbyBzZXQgYSBmbGFnIHRvIGVuZCB0aGUgZnJhbWUgYWZ0ZXIgdGhlCisgIC8vIG1hcC1lbnRyeSB2YWx1ZSBpcyBwYXJzZWQuCisgIGlmICghY2hlY2tfc3RhY2socCkpIHJldHVybiBmYWxzZTsKKworICBjb25zdCB1cGJfZmllbGRkZWYgKm1hcGZpZWxkID0gcC0+dG9wLT5tYXBmaWVsZDsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbWFwZW50cnltc2cgPSB1cGJfZmllbGRkZWZfbXNnc3ViZGVmKG1hcGZpZWxkKTsKKworICB1cGJfanNvbnBhcnNlcl9mcmFtZSAqaW5uZXIgPSBwLT50b3AgKyAxOworICBwLT50b3AtPmYgPSBtYXBmaWVsZDsKKyAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9TVEFSVFNVQk1TRyk7CisgIHVwYl9zaW5rX3N0YXJ0c3VibXNnKCZwLT50b3AtPnNpbmssIHNlbCwgJmlubmVyLT5zaW5rKTsKKyAgaW5uZXItPm0gPSBtYXBlbnRyeW1zZzsKKyAgaW5uZXItPm1hcGZpZWxkID0gbWFwZmllbGQ7CisgIGlubmVyLT5pc19tYXAgPSBmYWxzZTsKKworICAvLyBEb24ndCBzZXQgdGhpcyB0byB0cnVlICp5ZXQqIC0tIHdlIHJldXNlIHBhcnNpbmcgaGFuZGxlcnMgYmVsb3cgdG8gcHVzaAorICAvLyB0aGUga2V5IGZpZWxkIHZhbHVlIHRvIHRoZSBzaW5rLCBhbmQgdGhlc2UgaGFuZGxlcnMgd2lsbCBwb3AgdGhlIGZyYW1lCisgIC8vIGlmIHRoZXkgc2VlIGlzX21hcGVudHJ5ICh3aGVuIGludm9rZWQgYnkgdGhlIHBhcnNlciBzdGF0ZSBtYWNoaW5lLCB0aGV5CisgIC8vIHdvdWxkIGhhdmUganVzdCBzZWVuIHRoZSBtYXAtZW50cnkgdmFsdWUsIG5vdCBrZXkpLgorICBpbm5lci0+aXNfbWFwZW50cnkgPSBmYWxzZTsKKyAgcC0+dG9wID0gaW5uZXI7CisKKyAgLy8gc2VuZCBTVEFSVE1TRyBpbiBzdWJtc2cgZnJhbWUuCisgIHVwYl9zaW5rX3N0YXJ0bXNnKCZwLT50b3AtPnNpbmspOworCisgIHBhcnNlX21hcGVudHJ5X2tleShwKTsKKworICAvLyBTZXQgdXAgdGhlIHZhbHVlIGZpZWxkIHRvIHJlY2VpdmUgdGhlIG1hcC1lbnRyeSB2YWx1ZS4KKyAgcC0+dG9wLT5mID0gdXBiX21zZ2RlZl9pdG9mKHAtPnRvcC0+bSwgVVBCX01BUEVOVFJZX1ZBTFVFKTsKKyAgcC0+dG9wLT5pc19tYXBlbnRyeSA9IHRydWU7ICAvLyBzZXQgdXAgdG8gcG9wIGZyYW1lIGFmdGVyIHZhbHVlIGlzIHBhcnNlZC4KKyAgcC0+dG9wLT5tYXBmaWVsZCA9IG1hcGZpZWxkOworICBpZiAocC0+dG9wLT5mID09IE5VTEwpIHsKKyAgICB1cGJfc3RhdHVzX3NldGVycm1zZyhwLT5zdGF0dXMsICJtYXBlbnRyeSBtZXNzYWdlIGhhcyBubyB2YWx1ZSIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCBlbmRfbWVtYmVybmFtZSh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgYXNzZXJ0KCFwLT50b3AtPmYpOworCisgIGlmIChwLT50b3AtPmlzX21hcCkgeworICAgIHJldHVybiBoYW5kbGVfbWFwZW50cnkocCk7CisgIH0gZWxzZSB7CisgICAgc2l6ZV90IGxlbjsKKyAgICBjb25zdCBjaGFyICpidWYgPSBhY2N1bXVsYXRlX2dldHB0cihwLCAmbGVuKTsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYgKmYgPSB1cGJfbXNnZGVmX250b2YocC0+dG9wLT5tLCBidWYsIGxlbik7CisKKyAgICBpZiAoIWYpIHsKKyAgICAgIC8vIFRPRE8oaGFiZXJtYW4pOiBJZ25vcmUgdW5rbm93biBmaWVsZHMgaWYgcmVxdWVzdGVkL2NvbmZpZ3VyZWQgdG8gZG8gc28uCisgICAgICB1cGJfc3RhdHVzX3NldGVycmYocC0+c3RhdHVzLCAiTm8gc3VjaCBmaWVsZDogJS4qc1xuIiwgKGludClsZW4sIGJ1Zik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcC0+dG9wLT5mID0gZjsKKyAgICBtdWx0aXBhcnRfZW5kKHApOworCisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKworc3RhdGljIHZvaWQgZW5kX21lbWJlcih1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgLy8gSWYgd2UganVzdCBwYXJzZWQgYSBtYXAtZW50cnkgdmFsdWUsIGVuZCB0aGF0IGZyYW1lIHRvby4KKyAgaWYgKHAtPnRvcC0+aXNfbWFwZW50cnkpIHsKKyAgICBhc3NlcnQocC0+dG9wID4gcC0+c3RhY2spOworICAgIC8vIHNlbmQgRU5ETVNHIG9uIHN1Ym1zZy4KKyAgICB1cGJfc3RhdHVzIHMgPSBVUEJfU1RBVFVTX0lOSVQ7CisgICAgdXBiX3NpbmtfZW5kbXNnKCZwLT50b3AtPnNpbmssICZzKTsKKyAgICBjb25zdCB1cGJfZmllbGRkZWYqIG1hcGZpZWxkID0gcC0+dG9wLT5tYXBmaWVsZDsKKworICAgIC8vIHNlbmQgRU5EU1VCTVNHIGluIHJlcGVhdGVkLWZpZWxkLW9mLW1hcGVudHJpZXMgZnJhbWUuCisgICAgcC0+dG9wLS07CisgICAgdXBiX3NlbGVjdG9yX3Qgc2VsOworICAgIGJvb2wgb2sgPSB1cGJfaGFuZGxlcnNfZ2V0c2VsZWN0b3IobWFwZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUEJfSEFORExFUl9FTkRTVUJNU0csICZzZWwpOworICAgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7CisgICAgdXBiX3NpbmtfZW5kc3VibXNnKCZwLT50b3AtPnNpbmssIHNlbCk7CisgIH0KKworICBwLT50b3AtPmYgPSBOVUxMOworfQorCitzdGF0aWMgYm9vbCBzdGFydF9zdWJvYmplY3QodXBiX2pzb25fcGFyc2VyICpwKSB7CisgIGFzc2VydChwLT50b3AtPmYpOworCisgIGlmICh1cGJfZmllbGRkZWZfaXNtYXAocC0+dG9wLT5mKSkgeworICAgIC8vIEJlZ2lubmluZyBvZiBhIG1hcC4gU3RhcnQgYSBuZXcgcGFyc2VyIGZyYW1lIGluIGEgcmVwZWF0ZWQtZmllbGQKKyAgICAvLyBjb250ZXh0LgorICAgIGlmICghY2hlY2tfc3RhY2socCkpIHJldHVybiBmYWxzZTsKKworICAgIHVwYl9qc29ucGFyc2VyX2ZyYW1lICppbm5lciA9IHAtPnRvcCArIDE7CisgICAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9TVEFSVFNFUSk7CisgICAgdXBiX3Npbmtfc3RhcnRzZXEoJnAtPnRvcC0+c2luaywgc2VsLCAmaW5uZXItPnNpbmspOworICAgIGlubmVyLT5tID0gdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihwLT50b3AtPmYpOworICAgIGlubmVyLT5tYXBmaWVsZCA9IHAtPnRvcC0+ZjsKKyAgICBpbm5lci0+ZiA9IE5VTEw7CisgICAgaW5uZXItPmlzX21hcCA9IHRydWU7CisgICAgaW5uZXItPmlzX21hcGVudHJ5ID0gZmFsc2U7CisgICAgcC0+dG9wID0gaW5uZXI7CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfaXNzdWJtc2cocC0+dG9wLT5mKSkgeworICAgIC8vIEJlZ2lubmluZyBvZiBhIHN1Ym9iamVjdC4gU3RhcnQgYSBuZXcgcGFyc2VyIGZyYW1lIGluIHRoZSBzdWJtc2cKKyAgICAvLyBjb250ZXh0LgorICAgIGlmICghY2hlY2tfc3RhY2socCkpIHJldHVybiBmYWxzZTsKKworICAgIHVwYl9qc29ucGFyc2VyX2ZyYW1lICppbm5lciA9IHAtPnRvcCArIDE7CisKKyAgICB1cGJfc2VsZWN0b3JfdCBzZWwgPSBnZXRzZWxfZm9yX2hhbmRsZXJ0eXBlKHAsIFVQQl9IQU5ETEVSX1NUQVJUU1VCTVNHKTsKKyAgICB1cGJfc2lua19zdGFydHN1Ym1zZygmcC0+dG9wLT5zaW5rLCBzZWwsICZpbm5lci0+c2luayk7CisgICAgaW5uZXItPm0gPSB1cGJfZmllbGRkZWZfbXNnc3ViZGVmKHAtPnRvcC0+Zik7CisgICAgaW5uZXItPmYgPSBOVUxMOworICAgIGlubmVyLT5pc19tYXAgPSBmYWxzZTsKKyAgICBpbm5lci0+aXNfbWFwZW50cnkgPSBmYWxzZTsKKyAgICBwLT50b3AgPSBpbm5lcjsKKworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihwLT5zdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICJPYmplY3Qgc3BlY2lmaWVkIGZvciBub24tbWVzc2FnZS9ncm91cCBmaWVsZDogJXMiLAorICAgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfbmFtZShwLT50b3AtPmYpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworc3RhdGljIHZvaWQgZW5kX3N1Ym9iamVjdCh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgaWYgKHAtPnRvcC0+aXNfbWFwKSB7CisgICAgcC0+dG9wLS07CisgICAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9FTkRTRVEpOworICAgIHVwYl9zaW5rX2VuZHNlcSgmcC0+dG9wLT5zaW5rLCBzZWwpOworICB9IGVsc2UgeworICAgIHAtPnRvcC0tOworICAgIHVwYl9zZWxlY3Rvcl90IHNlbCA9IGdldHNlbF9mb3JfaGFuZGxlcnR5cGUocCwgVVBCX0hBTkRMRVJfRU5EU1VCTVNHKTsKKyAgICB1cGJfc2lua19lbmRzdWJtc2coJnAtPnRvcC0+c2luaywgc2VsKTsKKyAgfQorfQorCitzdGF0aWMgYm9vbCBzdGFydF9hcnJheSh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgYXNzZXJ0KHAtPnRvcC0+Zik7CisKKyAgaWYgKCF1cGJfZmllbGRkZWZfaXNzZXEocC0+dG9wLT5mKSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihwLT5zdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICJBcnJheSBzcGVjaWZpZWQgZm9yIG5vbi1yZXBlYXRlZCBmaWVsZDogJXMiLAorICAgICAgICAgICAgICAgICAgICAgICB1cGJfZmllbGRkZWZfbmFtZShwLT50b3AtPmYpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIWNoZWNrX3N0YWNrKHApKSByZXR1cm4gZmFsc2U7CisKKyAgdXBiX2pzb25wYXJzZXJfZnJhbWUgKmlubmVyID0gcC0+dG9wICsgMTsKKyAgdXBiX3NlbGVjdG9yX3Qgc2VsID0gZ2V0c2VsX2Zvcl9oYW5kbGVydHlwZShwLCBVUEJfSEFORExFUl9TVEFSVFNFUSk7CisgIHVwYl9zaW5rX3N0YXJ0c2VxKCZwLT50b3AtPnNpbmssIHNlbCwgJmlubmVyLT5zaW5rKTsKKyAgaW5uZXItPm0gPSBwLT50b3AtPm07CisgIGlubmVyLT5mID0gcC0+dG9wLT5mOworICBpbm5lci0+aXNfbWFwID0gZmFsc2U7CisgIGlubmVyLT5pc19tYXBlbnRyeSA9IGZhbHNlOworICBwLT50b3AgPSBpbm5lcjsKKworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIHZvaWQgZW5kX2FycmF5KHVwYl9qc29uX3BhcnNlciAqcCkgeworICBhc3NlcnQocC0+dG9wID4gcC0+c3RhY2spOworCisgIHAtPnRvcC0tOworICB1cGJfc2VsZWN0b3JfdCBzZWwgPSBnZXRzZWxfZm9yX2hhbmRsZXJ0eXBlKHAsIFVQQl9IQU5ETEVSX0VORFNFUSk7CisgIHVwYl9zaW5rX2VuZHNlcSgmcC0+dG9wLT5zaW5rLCBzZWwpOworfQorCitzdGF0aWMgdm9pZCBzdGFydF9vYmplY3QodXBiX2pzb25fcGFyc2VyICpwKSB7CisgIGlmICghcC0+dG9wLT5pc19tYXApIHsKKyAgICB1cGJfc2lua19zdGFydG1zZygmcC0+dG9wLT5zaW5rKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBlbmRfb2JqZWN0KHVwYl9qc29uX3BhcnNlciAqcCkgeworICBpZiAoIXAtPnRvcC0+aXNfbWFwKSB7CisgICAgdXBiX3N0YXR1cyBzdGF0dXM7CisgICAgdXBiX3NpbmtfZW5kbXNnKCZwLT50b3AtPnNpbmssICZzdGF0dXMpOworICB9Cit9CisKKworI2RlZmluZSBDSEVDS19SRVRVUk5fVE9QKHgpIGlmICghKHgpKSBnb3RvIGVycm9yCisKKworLyogVGhlIGFjdHVhbCBwYXJzZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gV2hhdCBmb2xsb3dzIGlzIHRoZSBSYWdlbCBwYXJzZXIgaXRzZWxmLiAgVGhlIGxhbmd1YWdlIGlzIHNwZWNpZmllZCBpbiBSYWdlbAorLy8gYW5kIHRoZSBhY3Rpb25zIGNhbGwgb3VyIEMgZnVuY3Rpb25zIGFib3ZlLgorLy8KKy8vIFJhZ2VsIGhhcyBhbiBleHRlbnNpdmUgc2V0IG9mIGZ1bmN0aW9uYWxpdHksIGFuZCB3ZSB1c2Ugb25seSBhIHNtYWxsIHBhcnQgb2YKKy8vIGl0LiAgVGhlcmUgYXJlIG1hbnkgYWN0aW9uIHR5cGVzIGJ1dCB3ZSBvbmx5IHVzZSBhIGZldzoKKy8vCisvLyAgICI+IiAtLSB0cmFuc2l0aW9uIGludG8gYSBtYWNoaW5lCisvLyAgICIlIiAtLSB0cmFuc2l0aW9uIG91dCBvZiBhIG1hY2hpbmUKKy8vICAgIkAiIC0tIHRyYW5zaXRpb24gaW50byBhIGZpbmFsIHN0YXRlIG9mIGEgbWFjaGluZS4KKy8vCisvLyAiQCIgdHJhbnNpdGlvbnMgYXJlIHRyaWNreSBiZWNhdXNlIGEgbWFjaGluZSBjYW4gdHJhbnNpdGlvbiBpbnRvIGEgZmluYWwKKy8vIHN0YXRlIHJlcGVhdGVkbHkuICBCdXQgaW4gc29tZSBjYXNlcyB3ZSBrbm93IHRoaXMgY2FuJ3QgaGFwcGVuLCBmb3IgZXhhbXBsZQorLy8gYSBzdHJpbmcgd2hpY2ggaXMgZGVsaW1pdGVkIGJ5IGEgZmluYWwgJyInIGNhbiBvbmx5IHRyYW5zaXRpb24gaW50byBpdHMKKy8vIGZpbmFsIHN0YXRlIG9uY2UsIHdoZW4gdGhlIGNsb3NpbmcgJyInIGlzIHNlZW4uCisKKworI2xpbmUgMTA4NSAidXBiL2pzb24vcGFyc2VyLnJsIgorCisKKworI2xpbmUgOTk3ICJ1cGIvanNvbi9wYXJzZXIuYyIKK3N0YXRpYyBjb25zdCBjaGFyIF9qc29uX2FjdGlvbnNbXSA9IHsKKwkwLCAxLCAwLCAxLCAyLCAxLCAzLCAxLCAKKwk1LCAxLCA2LCAxLCA3LCAxLCA4LCAxLCAKKwkxMCwgMSwgMTIsIDEsIDEzLCAxLCAxNCwgMSwgCisJMTUsIDEsIDE2LCAxLCAxNywgMSwgMjEsIDEsIAorCTI1LCAxLCAyNywgMiwgMywgOCwgMiwgNCwgCisJNSwgMiwgNiwgMiwgMiwgNiwgOCwgMiwgCisJMTEsIDksIDIsIDEzLCAxNSwgMiwgMTQsIDE1LCAKKwkyLCAxOCwgMSwgMiwgMTksIDI3LCAyLCAyMCwgCisJOSwgMiwgMjIsIDI3LCAyLCAyMywgMjcsIDIsIAorCTI0LCAyNywgMiwgMjYsIDI3LCAzLCAxNCwgMTEsIAorCTkKK307CisKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIF9qc29uX2tleV9vZmZzZXRzW10gPSB7CisJMCwgMCwgNCwgOSwgMTQsIDE1LCAxOSwgMjQsIAorCTI5LCAzNCwgMzgsIDQyLCA0NSwgNDgsIDUwLCA1NCwgCisJNTgsIDYwLCA2MiwgNjcsIDY5LCA3MSwgODAsIDg2LCAKKwk5MiwgOTgsIDEwNCwgMTA2LCAxMTUsIDExNiwgMTE2LCAxMTYsIAorCTEyMSwgMTI2LCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM1LCAKKwkxMzYsIDEzNywgMTM4LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MSwgCisJMTQ2LCAxNTEsIDE1MiwgMTU2LCAxNjEsIDE2NiwgMTcxLCAxNzUsIAorCTE3NSwgMTc4LCAxNzgsIDE3OAorfTsKKworc3RhdGljIGNvbnN0IGNoYXIgX2pzb25fdHJhbnNfa2V5c1tdID0geworCTMyLCAxMjMsIDksIDEzLCAzMiwgMzQsIDEyNSwgOSwgCisJMTMsIDMyLCAzNCwgMTI1LCA5LCAxMywgMzQsIDMyLCAKKwk1OCwgOSwgMTMsIDMyLCA5MywgMTI1LCA5LCAxMywgCisJMzIsIDQ0LCAxMjUsIDksIDEzLCAzMiwgNDQsIDEyNSwgCisJOSwgMTMsIDMyLCAzNCwgOSwgMTMsIDQ1LCA0OCwgCisJNDksIDU3LCA0OCwgNDksIDU3LCA0NiwgNjksIDEwMSwgCisJNDgsIDU3LCA2OSwgMTAxLCA0OCwgNTcsIDQzLCA0NSwgCisJNDgsIDU3LCA0OCwgNTcsIDQ4LCA1NywgNDYsIDY5LCAKKwkxMDEsIDQ4LCA1NywgMzQsIDkyLCAzNCwgOTIsIDM0LCAKKwk0NywgOTIsIDk4LCAxMDIsIDExMCwgMTE0LCAxMTYsIDExNywgCisJNDgsIDU3LCA2NSwgNzAsIDk3LCAxMDIsIDQ4LCA1NywgCisJNjUsIDcwLCA5NywgMTAyLCA0OCwgNTcsIDY1LCA3MCwgCisJOTcsIDEwMiwgNDgsIDU3LCA2NSwgNzAsIDk3LCAxMDIsIAorCTM0LCA5MiwgMzQsIDQ1LCA5MSwgMTAyLCAxMTAsIDExNiwgCisJMTIzLCA0OCwgNTcsIDM0LCAzMiwgOTMsIDEyNSwgOSwgCisJMTMsIDMyLCA0NCwgOTMsIDksIDEzLCAzMiwgOTMsIAorCTEyNSwgOSwgMTMsIDk3LCAxMDgsIDExNSwgMTAxLCAxMTcsIAorCTEwOCwgMTA4LCAxMTQsIDExNywgMTAxLCAzMiwgMzQsIDEyNSwgCisJOSwgMTMsIDMyLCAzNCwgMTI1LCA5LCAxMywgMzQsIAorCTMyLCA1OCwgOSwgMTMsIDMyLCA5MywgMTI1LCA5LCAKKwkxMywgMzIsIDQ0LCAxMjUsIDksIDEzLCAzMiwgNDQsIAorCTEyNSwgOSwgMTMsIDMyLCAzNCwgOSwgMTMsIDMyLCAKKwk5LCAxMywgMAorfTsKKworc3RhdGljIGNvbnN0IGNoYXIgX2pzb25fc2luZ2xlX2xlbmd0aHNbXSA9IHsKKwkwLCAyLCAzLCAzLCAxLCAyLCAzLCAzLCAKKwkzLCAyLCAyLCAxLCAzLCAwLCAyLCAyLCAKKwkwLCAwLCAzLCAyLCAyLCA5LCAwLCAwLCAKKwkwLCAwLCAyLCA3LCAxLCAwLCAwLCAzLCAKKwkzLCAzLCAxLCAxLCAxLCAxLCAwLCAxLCAKKwkxLCAxLCAwLCAxLCAxLCAxLCAwLCAzLCAKKwkzLCAxLCAyLCAzLCAzLCAzLCAyLCAwLCAKKwkxLCAwLCAwLCAwCit9OworCitzdGF0aWMgY29uc3QgY2hhciBfanNvbl9yYW5nZV9sZW5ndGhzW10gPSB7CisJMCwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgCisJMSwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgCisJMSwgMSwgMSwgMCwgMCwgMCwgMywgMywgCisJMywgMywgMCwgMSwgMCwgMCwgMCwgMSwgCisJMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgCisJMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgCisJMSwgMCwgMSwgMSwgMSwgMSwgMSwgMCwgCisJMSwgMCwgMCwgMAorfTsKKworc3RhdGljIGNvbnN0IHNob3J0IF9qc29uX2luZGV4X29mZnNldHNbXSA9IHsKKwkwLCAwLCA0LCA5LCAxNCwgMTYsIDIwLCAyNSwgCisJMzAsIDM1LCAzOSwgNDMsIDQ2LCA1MCwgNTIsIDU2LCAKKwk2MCwgNjIsIDY0LCA2OSwgNzIsIDc1LCA4NSwgODksIAorCTkzLCA5NywgMTAxLCAxMDQsIDExMywgMTE1LCAxMTYsIDExNywgCisJMTIyLCAxMjcsIDEzMiwgMTM0LCAxMzYsIDEzOCwgMTQwLCAxNDEsIAorCTE0MywgMTQ1LCAxNDcsIDE0OCwgMTUwLCAxNTIsIDE1NCwgMTU1LCAKKwkxNjAsIDE2NSwgMTY3LCAxNzEsIDE3NiwgMTgxLCAxODYsIDE5MCwgCisJMTkxLCAxOTQsIDE5NSwgMTk2Cit9OworCitzdGF0aWMgY29uc3QgY2hhciBfanNvbl9pbmRpY2llc1tdID0geworCTAsIDIsIDAsIDEsIDMsIDQsIDUsIDMsIAorCTEsIDYsIDcsIDgsIDYsIDEsIDksIDEsIAorCTEwLCAxMSwgMTAsIDEsIDExLCAxLCAxLCAxMSwgCisJMTIsIDEzLCAxNCwgMTUsIDEzLCAxLCAxNiwgMTcsIAorCTgsIDE2LCAxLCAxNywgNywgMTcsIDEsIDE4LCAKKwkxOSwgMjAsIDEsIDE5LCAyMCwgMSwgMjIsIDIzLCAKKwkyMywgMjEsIDI0LCAxLCAyMywgMjMsIDI0LCAyMSwgCisJMjUsIDI1LCAyNiwgMSwgMjYsIDEsIDI2LCAyMSwgCisJMjIsIDIzLCAyMywgMjAsIDIxLCAyOCwgMjksIDI3LCAKKwkzMSwgMzIsIDMwLCAzMywgMzMsIDMzLCAzMywgMzMsIAorCTMzLCAzMywgMzMsIDM0LCAxLCAzNSwgMzUsIDM1LCAKKwkxLCAzNiwgMzYsIDM2LCAxLCAzNywgMzcsIDM3LCAKKwkxLCAzOCwgMzgsIDM4LCAxLCA0MCwgNDEsIDM5LCAKKwk0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LCA0OCwgNDMsIAorCTEsIDQ5LCAxLCA1MCwgNTEsIDUzLCA1NCwgMSwgCisJNTMsIDUyLCA1NSwgNTYsIDU0LCA1NSwgMSwgNTYsIAorCTEsIDEsIDU2LCA1MiwgNTcsIDEsIDU4LCAxLCAKKwk1OSwgMSwgNjAsIDEsIDYxLCA2MiwgMSwgNjMsIAorCTEsIDY0LCAxLCA2NSwgNjYsIDEsIDY3LCAxLCAKKwk2OCwgMSwgNjksIDcwLCA3MSwgNzIsIDcwLCAxLCAKKwk3MywgNzQsIDc1LCA3MywgMSwgNzYsIDEsIDc3LCAKKwk3OCwgNzcsIDEsIDc4LCAxLCAxLCA3OCwgNzksIAorCTgwLCA4MSwgODIsIDgwLCAxLCA4MywgODQsIDc1LCAKKwk4MywgMSwgODQsIDc0LCA4NCwgMSwgODUsIDg2LCAKKwk4NiwgMSwgMSwgMSwgMSwgMAorfTsKKworc3RhdGljIGNvbnN0IGNoYXIgX2pzb25fdHJhbnNfdGFyZ3NbXSA9IHsKKwkxLCAwLCAyLCAzLCA0LCA1NiwgMywgNCwgCisJNTYsIDUsIDUsIDYsIDcsIDgsIDksIDU2LCAKKwk4LCA5LCAxMSwgMTIsIDE4LCA1NywgMTMsIDE1LCAKKwkxNCwgMTYsIDE3LCAyMCwgNTgsIDIxLCAyMCwgNTgsIAorCTIxLCAxOSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyMCwgCisJNTgsIDIxLCAyOCwgMzAsIDMxLCAzNCwgMzksIDQzLCAKKwk0NywgMjksIDU5LCA1OSwgMzIsIDMxLCAyOSwgMzIsIAorCTMzLCAzNSwgMzYsIDM3LCAzOCwgNTksIDQwLCA0MSwgCisJNDIsIDU5LCA0NCwgNDUsIDQ2LCA1OSwgNDgsIDQ5LCAKKwk1NSwgNDgsIDQ5LCA1NSwgNTAsIDUwLCA1MSwgNTIsIAorCTUzLCA1NCwgNTUsIDUzLCA1NCwgNTksIDU2Cit9OworCitzdGF0aWMgY29uc3QgY2hhciBfanNvbl90cmFuc19hY3Rpb25zW10gPSB7CisJMCwgMCwgMCwgMjEsIDc3LCA1MywgMCwgNDcsIAorCTIzLCAxNywgMCwgMCwgMTUsIDE5LCAxOSwgNTAsIAorCTAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIAorCTAsIDAsIDAsIDMsIDEzLCAwLCAwLCAzNSwgCisJNSwgMTEsIDAsIDM4LCA3LCA3LCA3LCA0MSwgCisJNDQsIDksIDYyLCA1NiwgMjUsIDAsIDAsIDAsIAorCTMxLCAyOSwgMzMsIDU5LCAxNSwgMCwgMjcsIDAsIAorCTAsIDAsIDAsIDAsIDAsIDY4LCAwLCAwLCAKKwkwLCA3MSwgMCwgMCwgMCwgNjUsIDIxLCA3NywgCisJNTMsIDAsIDQ3LCAyMywgMTcsIDAsIDAsIDE1LCAKKwkxOSwgMTksIDUwLCAwLCAwLCA3NCwgMAorfTsKKworc3RhdGljIGNvbnN0IGludCBqc29uX3N0YXJ0ID0gMTsKK3N0YXRpYyBjb25zdCBpbnQganNvbl9maXJzdF9maW5hbCA9IDU2Oworc3RhdGljIGNvbnN0IGludCBqc29uX2Vycm9yID0gMDsKKworc3RhdGljIGNvbnN0IGludCBqc29uX2VuX251bWJlcl9tYWNoaW5lID0gMTA7CitzdGF0aWMgY29uc3QgaW50IGpzb25fZW5fc3RyaW5nX21hY2hpbmUgPSAxOTsKK3N0YXRpYyBjb25zdCBpbnQganNvbl9lbl92YWx1ZV9tYWNoaW5lID0gMjc7CitzdGF0aWMgY29uc3QgaW50IGpzb25fZW5fbWFpbiA9IDE7CisKKworI2xpbmUgMTA4OCAidXBiL2pzb24vcGFyc2VyLnJsIgorCitzaXplX3QgcGFyc2Uodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9qc29uX3BhcnNlciAqcGFyc2VyID0gY2xvc3VyZTsKKyAgcGFyc2VyLT5oYW5kbGUgPSBoYW5kbGU7CisKKyAgLy8gVmFyaWFibGVzIHVzZWQgYnkgUmFnZWwncyBnZW5lcmF0ZWQgY29kZS4KKyAgaW50IGNzID0gcGFyc2VyLT5jdXJyZW50X3N0YXRlOworICBpbnQgKnN0YWNrID0gcGFyc2VyLT5wYXJzZXJfc3RhY2s7CisgIGludCB0b3AgPSBwYXJzZXItPnBhcnNlcl90b3A7CisKKyAgY29uc3QgY2hhciAqcCA9IGJ1ZjsKKyAgY29uc3QgY2hhciAqcGUgPSBidWYgKyBzaXplOworCisgIGNhcHR1cmVfcmVzdW1lKHBhcnNlciwgYnVmKTsKKworICAKKyNsaW5lIDExNjggInVwYi9qc29uL3BhcnNlci5jIgorCXsKKwlpbnQgX2tsZW47CisJdW5zaWduZWQgaW50IF90cmFuczsKKwljb25zdCBjaGFyICpfYWN0czsKKwl1bnNpZ25lZCBpbnQgX25hY3RzOworCWNvbnN0IGNoYXIgKl9rZXlzOworCisJaWYgKCBwID09IHBlICkKKwkJZ290byBfdGVzdF9lb2Y7CisJaWYgKCBjcyA9PSAwICkKKwkJZ290byBfb3V0OworX3Jlc3VtZToKKwlfa2V5cyA9IF9qc29uX3RyYW5zX2tleXMgKyBfanNvbl9rZXlfb2Zmc2V0c1tjc107CisJX3RyYW5zID0gX2pzb25faW5kZXhfb2Zmc2V0c1tjc107CisKKwlfa2xlbiA9IF9qc29uX3NpbmdsZV9sZW5ndGhzW2NzXTsKKwlpZiAoIF9rbGVuID4gMCApIHsKKwkJY29uc3QgY2hhciAqX2xvd2VyID0gX2tleXM7CisJCWNvbnN0IGNoYXIgKl9taWQ7CisJCWNvbnN0IGNoYXIgKl91cHBlciA9IF9rZXlzICsgX2tsZW4gLSAxOworCQl3aGlsZSAoMSkgeworCQkJaWYgKCBfdXBwZXIgPCBfbG93ZXIgKQorCQkJCWJyZWFrOworCisJCQlfbWlkID0gX2xvd2VyICsgKChfdXBwZXItX2xvd2VyKSA+PiAxKTsKKwkJCWlmICggKCpwKSA8ICpfbWlkICkKKwkJCQlfdXBwZXIgPSBfbWlkIC0gMTsKKwkJCWVsc2UgaWYgKCAoKnApID4gKl9taWQgKQorCQkJCV9sb3dlciA9IF9taWQgKyAxOworCQkJZWxzZSB7CisJCQkJX3RyYW5zICs9ICh1bnNpZ25lZCBpbnQpKF9taWQgLSBfa2V5cyk7CisJCQkJZ290byBfbWF0Y2g7CisJCQl9CisJCX0KKwkJX2tleXMgKz0gX2tsZW47CisJCV90cmFucyArPSBfa2xlbjsKKwl9CisKKwlfa2xlbiA9IF9qc29uX3JhbmdlX2xlbmd0aHNbY3NdOworCWlmICggX2tsZW4gPiAwICkgeworCQljb25zdCBjaGFyICpfbG93ZXIgPSBfa2V5czsKKwkJY29uc3QgY2hhciAqX21pZDsKKwkJY29uc3QgY2hhciAqX3VwcGVyID0gX2tleXMgKyAoX2tsZW48PDEpIC0gMjsKKwkJd2hpbGUgKDEpIHsKKwkJCWlmICggX3VwcGVyIDwgX2xvd2VyICkKKwkJCQlicmVhazsKKworCQkJX21pZCA9IF9sb3dlciArICgoKF91cHBlci1fbG93ZXIpID4+IDEpICYgfjEpOworCQkJaWYgKCAoKnApIDwgX21pZFswXSApCisJCQkJX3VwcGVyID0gX21pZCAtIDI7CisJCQllbHNlIGlmICggKCpwKSA+IF9taWRbMV0gKQorCQkJCV9sb3dlciA9IF9taWQgKyAyOworCQkJZWxzZSB7CisJCQkJX3RyYW5zICs9ICh1bnNpZ25lZCBpbnQpKChfbWlkIC0gX2tleXMpPj4xKTsKKwkJCQlnb3RvIF9tYXRjaDsKKwkJCX0KKwkJfQorCQlfdHJhbnMgKz0gX2tsZW47CisJfQorCitfbWF0Y2g6CisJX3RyYW5zID0gX2pzb25faW5kaWNpZXNbX3RyYW5zXTsKKwljcyA9IF9qc29uX3RyYW5zX3RhcmdzW190cmFuc107CisKKwlpZiAoIF9qc29uX3RyYW5zX2FjdGlvbnNbX3RyYW5zXSA9PSAwICkKKwkJZ290byBfYWdhaW47CisKKwlfYWN0cyA9IF9qc29uX2FjdGlvbnMgKyBfanNvbl90cmFuc19hY3Rpb25zW190cmFuc107CisJX25hY3RzID0gKHVuc2lnbmVkIGludCkgKl9hY3RzKys7CisJd2hpbGUgKCBfbmFjdHMtLSA+IDAgKQorCXsKKwkJc3dpdGNoICggKl9hY3RzKysgKQorCQl7CisJY2FzZSAwOgorI2xpbmUgMTAwMCAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgcC0tOyB7Y3MgPSBzdGFja1stLXRvcF07IGdvdG8gX2FnYWluO30gfQorCWJyZWFrOworCWNhc2UgMToKKyNsaW5lIDEwMDEgInVwYi9qc29uL3BhcnNlci5ybCIKKwl7IHAtLTsge3N0YWNrW3RvcCsrXSA9IGNzOyBjcyA9IDEwOyBnb3RvIF9hZ2Fpbjt9IH0KKwlicmVhazsKKwljYXNlIDI6CisjbGluZSAxMDA1ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBzdGFydF90ZXh0KHBhcnNlciwgcCk7IH0KKwlicmVhazsKKwljYXNlIDM6CisjbGluZSAxMDA2ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBDSEVDS19SRVRVUk5fVE9QKGVuZF90ZXh0KHBhcnNlciwgcCkpOyB9CisJYnJlYWs7CisJY2FzZSA0OgorI2xpbmUgMTAxMiAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgc3RhcnRfaGV4KHBhcnNlcik7IH0KKwlicmVhazsKKwljYXNlIDU6CisjbGluZSAxMDEzICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBoZXhkaWdpdChwYXJzZXIsIHApOyB9CisJYnJlYWs7CisJY2FzZSA2OgorI2xpbmUgMTAxNCAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgQ0hFQ0tfUkVUVVJOX1RPUChlbmRfaGV4KHBhcnNlcikpOyB9CisJYnJlYWs7CisJY2FzZSA3OgorI2xpbmUgMTAyMCAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgQ0hFQ0tfUkVUVVJOX1RPUChlc2NhcGUocGFyc2VyLCBwKSk7IH0KKwlicmVhazsKKwljYXNlIDg6CisjbGluZSAxMDI2ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBwLS07IHtjcyA9IHN0YWNrWy0tdG9wXTsgZ290byBfYWdhaW47fSB9CisJYnJlYWs7CisJY2FzZSA5OgorI2xpbmUgMTAyOSAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsge3N0YWNrW3RvcCsrXSA9IGNzOyBjcyA9IDE5OyBnb3RvIF9hZ2Fpbjt9IH0KKwlicmVhazsKKwljYXNlIDEwOgorI2xpbmUgMTAzMSAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgcC0tOyB7c3RhY2tbdG9wKytdID0gY3M7IGNzID0gMjc7IGdvdG8gX2FnYWluO30gfQorCWJyZWFrOworCWNhc2UgMTE6CisjbGluZSAxMDM2ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBzdGFydF9tZW1iZXIocGFyc2VyKTsgfQorCWJyZWFrOworCWNhc2UgMTI6CisjbGluZSAxMDM3ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBDSEVDS19SRVRVUk5fVE9QKGVuZF9tZW1iZXJuYW1lKHBhcnNlcikpOyB9CisJYnJlYWs7CisJY2FzZSAxMzoKKyNsaW5lIDEwNDAgInVwYi9qc29uL3BhcnNlci5ybCIKKwl7IGVuZF9tZW1iZXIocGFyc2VyKTsgfQorCWJyZWFrOworCWNhc2UgMTQ6CisjbGluZSAxMDQ2ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBzdGFydF9vYmplY3QocGFyc2VyKTsgfQorCWJyZWFrOworCWNhc2UgMTU6CisjbGluZSAxMDQ5ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBlbmRfb2JqZWN0KHBhcnNlcik7IH0KKwlicmVhazsKKwljYXNlIDE2OgorI2xpbmUgMTA1NSAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgQ0hFQ0tfUkVUVVJOX1RPUChzdGFydF9hcnJheShwYXJzZXIpKTsgfQorCWJyZWFrOworCWNhc2UgMTc6CisjbGluZSAxMDU5ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBlbmRfYXJyYXkocGFyc2VyKTsgfQorCWJyZWFrOworCWNhc2UgMTg6CisjbGluZSAxMDY0ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBzdGFydF9udW1iZXIocGFyc2VyLCBwKTsgfQorCWJyZWFrOworCWNhc2UgMTk6CisjbGluZSAxMDY1ICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBDSEVDS19SRVRVUk5fVE9QKGVuZF9udW1iZXIocGFyc2VyLCBwKSk7IH0KKwlicmVhazsKKwljYXNlIDIwOgorI2xpbmUgMTA2NyAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgQ0hFQ0tfUkVUVVJOX1RPUChzdGFydF9zdHJpbmd2YWwocGFyc2VyKSk7IH0KKwlicmVhazsKKwljYXNlIDIxOgorI2xpbmUgMTA2OCAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgQ0hFQ0tfUkVUVVJOX1RPUChlbmRfc3RyaW5ndmFsKHBhcnNlcikpOyB9CisJYnJlYWs7CisJY2FzZSAyMjoKKyNsaW5lIDEwNzAgInVwYi9qc29uL3BhcnNlci5ybCIKKwl7IENIRUNLX1JFVFVSTl9UT1AocGFyc2VyX3B1dGJvb2wocGFyc2VyLCB0cnVlKSk7IH0KKwlicmVhazsKKwljYXNlIDIzOgorI2xpbmUgMTA3MiAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgQ0hFQ0tfUkVUVVJOX1RPUChwYXJzZXJfcHV0Ym9vbChwYXJzZXIsIGZhbHNlKSk7IH0KKwlicmVhazsKKwljYXNlIDI0OgorI2xpbmUgMTA3NCAidXBiL2pzb24vcGFyc2VyLnJsIgorCXsgLyogbnVsbCB2YWx1ZSAqLyB9CisJYnJlYWs7CisJY2FzZSAyNToKKyNsaW5lIDEwNzYgInVwYi9qc29uL3BhcnNlci5ybCIKKwl7IENIRUNLX1JFVFVSTl9UT1Aoc3RhcnRfc3Vib2JqZWN0KHBhcnNlcikpOyB9CisJYnJlYWs7CisJY2FzZSAyNjoKKyNsaW5lIDEwNzcgInVwYi9qc29uL3BhcnNlci5ybCIKKwl7IGVuZF9zdWJvYmplY3QocGFyc2VyKTsgfQorCWJyZWFrOworCWNhc2UgMjc6CisjbGluZSAxMDgyICJ1cGIvanNvbi9wYXJzZXIucmwiCisJeyBwLS07IHtjcyA9IHN0YWNrWy0tdG9wXTsgZ290byBfYWdhaW47fSB9CisJYnJlYWs7CisjbGluZSAxMzU0ICJ1cGIvanNvbi9wYXJzZXIuYyIKKwkJfQorCX0KKworX2FnYWluOgorCWlmICggY3MgPT0gMCApCisJCWdvdG8gX291dDsKKwlpZiAoICsrcCAhPSBwZSApCisJCWdvdG8gX3Jlc3VtZTsKKwlfdGVzdF9lb2Y6IHt9CisJX291dDoge30KKwl9CisKKyNsaW5lIDExMDcgInVwYi9qc29uL3BhcnNlci5ybCIKKworICBpZiAocCAhPSBwZSkgeworICAgIHVwYl9zdGF0dXNfc2V0ZXJyZihwYXJzZXItPnN0YXR1cywgIlBhcnNlIGVycm9yIGF0ICVzXG4iLCBwKTsKKyAgfSBlbHNlIHsKKyAgICBjYXB0dXJlX3N1c3BlbmQocGFyc2VyLCAmcCk7CisgIH0KKworZXJyb3I6CisgIC8vIFNhdmUgcGFyc2luZyBzdGF0ZSBiYWNrIHRvIHBhcnNlci4KKyAgcGFyc2VyLT5jdXJyZW50X3N0YXRlID0gY3M7CisgIHBhcnNlci0+cGFyc2VyX3RvcCA9IHRvcDsKKworICByZXR1cm4gcCAtIGJ1ZjsKK30KKworYm9vbCBlbmQodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQpIHsKKyAgVVBCX1VOVVNFRChjbG9zdXJlKTsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHJldHVybiB0cnVlOworfQorCisKKy8qIFB1YmxpYyBBUEkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3ZvaWQgdXBiX2pzb25fcGFyc2VyX2luaXQodXBiX2pzb25fcGFyc2VyICpwLCB1cGJfc3RhdHVzICpzdGF0dXMpIHsKKyAgcC0+bGltaXQgPSBwLT5zdGFjayArIFVQQl9KU09OX01BWF9ERVBUSDsKKyAgcC0+YWNjdW11bGF0ZV9idWYgPSBOVUxMOworICBwLT5hY2N1bXVsYXRlX2J1Zl9zaXplID0gMDsKKyAgdXBiX2J5dGVzaGFuZGxlcl9pbml0KCZwLT5pbnB1dF9oYW5kbGVyXyk7CisgIHVwYl9ieXRlc2hhbmRsZXJfc2V0c3RyaW5nKCZwLT5pbnB1dF9oYW5kbGVyXywgcGFyc2UsIE5VTEwpOworICB1cGJfYnl0ZXNoYW5kbGVyX3NldGVuZHN0cigmcC0+aW5wdXRfaGFuZGxlcl8sIGVuZCwgTlVMTCk7CisgIHVwYl9ieXRlc3NpbmtfcmVzZXQoJnAtPmlucHV0XywgJnAtPmlucHV0X2hhbmRsZXJfLCBwKTsKKyAgcC0+c3RhdHVzID0gc3RhdHVzOworfQorCit2b2lkIHVwYl9qc29uX3BhcnNlcl91bmluaXQodXBiX2pzb25fcGFyc2VyICpwKSB7CisgIHVwYl9ieXRlc2hhbmRsZXJfdW5pbml0KCZwLT5pbnB1dF9oYW5kbGVyXyk7CisgIGZyZWUocC0+YWNjdW11bGF0ZV9idWYpOworfQorCit2b2lkIHVwYl9qc29uX3BhcnNlcl9yZXNldCh1cGJfanNvbl9wYXJzZXIgKnApIHsKKyAgcC0+dG9wID0gcC0+c3RhY2s7CisgIHAtPnRvcC0+ZiA9IE5VTEw7CisgIHAtPnRvcC0+aXNfbWFwID0gZmFsc2U7CisgIHAtPnRvcC0+aXNfbWFwZW50cnkgPSBmYWxzZTsKKworICBpbnQgY3M7CisgIGludCB0b3A7CisgIC8vIEVtaXQgUmFnZWwgaW5pdGlhbGl6YXRpb24gb2YgdGhlIHBhcnNlci4KKyAgCisjbGluZSAxNDE4ICJ1cGIvanNvbi9wYXJzZXIuYyIKKwl7CisJY3MgPSBqc29uX3N0YXJ0OworCXRvcCA9IDA7CisJfQorCisjbGluZSAxMTU3ICJ1cGIvanNvbi9wYXJzZXIucmwiCisgIHAtPmN1cnJlbnRfc3RhdGUgPSBjczsKKyAgcC0+cGFyc2VyX3RvcCA9IHRvcDsKKyAgYWNjdW11bGF0ZV9jbGVhcihwKTsKKyAgcC0+bXVsdGlwYXJ0X3N0YXRlID0gTVVMVElQQVJUX0lOQUNUSVZFOworICBwLT5jYXB0dXJlID0gTlVMTDsKK30KKwordm9pZCB1cGJfanNvbl9wYXJzZXJfcmVzZXRvdXRwdXQodXBiX2pzb25fcGFyc2VyICpwLCB1cGJfc2luayAqc2luaykgeworICB1cGJfanNvbl9wYXJzZXJfcmVzZXQocCk7CisgIHVwYl9zaW5rX3Jlc2V0KCZwLT50b3AtPnNpbmssIHNpbmstPmhhbmRsZXJzLCBzaW5rLT5jbG9zdXJlKTsKKyAgcC0+dG9wLT5tID0gdXBiX2hhbmRsZXJzX21zZ2RlZihzaW5rLT5oYW5kbGVycyk7CisgIHAtPmFjY3VtdWxhdGVkID0gTlVMTDsKK30KKwordXBiX2J5dGVzc2luayAqdXBiX2pzb25fcGFyc2VyX2lucHV0KHVwYl9qc29uX3BhcnNlciAqcCkgeworICByZXR1cm4gJnAtPmlucHV0XzsKK30KKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTQgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIFRoaXMgY3VycmVudGx5IHVzZXMgc25wcmludGYoKSB0byBmb3JtYXQgcHJpbWl0aXZlcywgYW5kIGNvdWxkIGJlIG9wdGltaXplZAorICogZnVydGhlci4KKyAqLworCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorCisvLyBTdHJpbmdQaWVjZTsgYSBwb2ludGVyIHBsdXMgYSBsZW5ndGguCit0eXBlZGVmIHN0cnVjdCB7CisgIGNvbnN0IGNoYXIgKnB0cjsKKyAgc2l6ZV90IGxlbjsKK30gc3RycGM7CisKK3N0cnBjICpuZXdzdHJwYyh1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHVwYl9maWVsZGRlZiAqZikgeworICBzdHJwYyAqcmV0ID0gbWFsbG9jKHNpemVvZigqcmV0KSk7CisgIHJldC0+cHRyID0gdXBiX2ZpZWxkZGVmX25hbWUoZik7CisgIHJldC0+bGVuID0gc3RybGVuKHJldC0+cHRyKTsKKyAgdXBiX2hhbmRsZXJzX2FkZGNsZWFudXAoaCwgcmV0LCBmcmVlKTsKKyAgcmV0dXJuIHJldDsKK30KKworLy8gLS0tLS0tLS0tLS0tIEpTT04gc3RyaW5nIHByaW50aW5nOiB2YWx1ZXMsIG1hcHMsIGFycmF5cyAtLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9pZCBwcmludF9kYXRhKAorICAgIHVwYl9qc29uX3ByaW50ZXIgKnAsIGNvbnN0IGNoYXIgKmJ1ZiwgdW5zaWduZWQgaW50IGxlbikgeworICAvLyBUT0RPOiBXaWxsIG5lZWQgdG8gY2hhbmdlIGlmIHdlIHN1cHBvcnQgcHVzaGJhY2sgZnJvbSB0aGUgc2luay4KKyAgc2l6ZV90IG4gPSB1cGJfYnl0ZXNzaW5rX3B1dGJ1ZihwLT5vdXRwdXRfLCBwLT5zdWJjXywgYnVmLCBsZW4sIE5VTEwpOworICBVUEJfQVNTRVJUX1ZBUihuLCBuID09IGxlbik7Cit9CisKK3N0YXRpYyB2b2lkIHByaW50X2NvbW1hKHVwYl9qc29uX3ByaW50ZXIgKnApIHsKKyAgaWYgKCFwLT5maXJzdF9lbGVtX1twLT5kZXB0aF9dKSB7CisgICAgcHJpbnRfZGF0YShwLCAiLCIsIDEpOworICB9CisgIHAtPmZpcnN0X2VsZW1fW3AtPmRlcHRoX10gPSBmYWxzZTsKK30KKworLy8gSGVscGVycyB0aGF0IHByaW50IHByb3Blcmx5IGZvcm1hdHRlZCBlbGVtZW50cyB0byB0aGUgSlNPTiBvdXRwdXQgc3RyZWFtLgorCisvLyBVc2VkIGZvciBlc2NhcGluZyBjb250cm9sIGNoYXJzIGluIHN0cmluZ3MuCitzdGF0aWMgY29uc3QgY2hhciBrQ29udHJvbENoYXJMaW1pdCA9IDB4MjA7CisKK3N0YXRpYyBpbmxpbmUgYm9vbCBpc19qc29uX2VzY2FwZWQoY2hhciBjKSB7CisgIC8vIFNlZSBSRkMgNDYyNy4KKyAgdW5zaWduZWQgY2hhciB1YyA9ICh1bnNpZ25lZCBjaGFyKWM7CisgIHJldHVybiB1YyA8IGtDb250cm9sQ2hhckxpbWl0IHx8IHVjID09ICciJyB8fCB1YyA9PSAnXFwnOworfQorCitzdGF0aWMgaW5saW5lIGNoYXIqIGpzb25fbmljZV9lc2NhcGUoY2hhciBjKSB7CisgIHN3aXRjaCAoYykgeworICAgIGNhc2UgJyInOiAgcmV0dXJuICJcXFwiIjsKKyAgICBjYXNlICdcXCc6IHJldHVybiAiXFxcXCI7CisgICAgY2FzZSAnXGInOiByZXR1cm4gIlxcYiI7CisgICAgY2FzZSAnXGYnOiByZXR1cm4gIlxcZiI7CisgICAgY2FzZSAnXG4nOiByZXR1cm4gIlxcbiI7CisgICAgY2FzZSAnXHInOiByZXR1cm4gIlxcciI7CisgICAgY2FzZSAnXHQnOiByZXR1cm4gIlxcdCI7CisgICAgZGVmYXVsdDogICByZXR1cm4gTlVMTDsKKyAgfQorfQorCisvLyBXcml0ZSBhIHByb3Blcmx5IGVzY2FwZWQgc3RyaW5nIGNodW5rLiBUaGUgc3Vycm91bmRpbmcgcXVvdGVzIGFyZSAqbm90KgorLy8gcHJpbnRlZDsgdGhpcyBpcyBzbyB0aGF0IHRoZSBjYWxsZXIgaGFzIHRoZSBvcHRpb24gb2YgZW1pdHRpbmcgdGhlIHN0cmluZworLy8gY29udGVudCBpbiBjaHVua3MuCitzdGF0aWMgdm9pZCBwdXRzdHJpbmcodXBiX2pzb25fcHJpbnRlciAqcCwgY29uc3QgY2hhciAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKSB7CisgIGNvbnN0IGNoYXIqIHVuZXNjYXBlZF9ydW4gPSBOVUxMOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgY2hhciBjID0gYnVmW2ldOworICAgIC8vIEhhbmRsZSBlc2NhcGluZy4KKyAgICBpZiAoaXNfanNvbl9lc2NhcGVkKGMpKSB7CisgICAgICAvLyBVc2UgYSAibmljZSIgZXNjYXBlLCBsaWtlIFxuLCBpZiBvbmUgZXhpc3RzIGZvciB0aGlzIGNoYXJhY3Rlci4KKyAgICAgIGNvbnN0IGNoYXIqIGVzY2FwZSA9IGpzb25fbmljZV9lc2NhcGUoYyk7CisgICAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGEgc3BlY2lmaWMgJ25pY2UnIGVzY2FwZSBjb2RlLCB1c2UgYSBcdVhYWFgtc3R5bGUKKyAgICAgIC8vIGVzY2FwZS4KKyAgICAgIGNoYXIgZXNjYXBlX2J1Zls4XTsKKyAgICAgIGlmICghZXNjYXBlKSB7CisgICAgICAgIHVuc2lnbmVkIGNoYXIgYnl0ZSA9ICh1bnNpZ25lZCBjaGFyKWM7CisgICAgICAgIHNucHJpbnRmKGVzY2FwZV9idWYsIHNpemVvZihlc2NhcGVfYnVmKSwgIlxcdSUwNHgiLCAoaW50KWJ5dGUpOworICAgICAgICBlc2NhcGUgPSBlc2NhcGVfYnVmOworICAgICAgfQorCisgICAgICAvLyBOLkIuIHRoYXQgd2UgYXNzdW1lIHRoYXQgdGhlIGlucHV0IGVuY29kaW5nIGlzIGVxdWFsIHRvIHRoZSBvdXRwdXQKKyAgICAgIC8vIGVuY29kaW5nIChib3RoIFVURi04IGZvciAgbm93KSwgc28gZm9yIGNoYXJzID49IDB4MjAgYW5kICE9IFwsICIsIHdlCisgICAgICAvLyBjYW4gc2ltcGx5IHBhc3MgdGhlIGJ5dGVzIHRocm91Z2guCisKKyAgICAgIC8vIElmIHRoZXJlJ3MgYSBjdXJyZW50IHJ1biBvZiB1bmVzY2FwZWQgY2hhcnMsIHByaW50IHRoYXQgcnVuIGZpcnN0LgorICAgICAgaWYgKHVuZXNjYXBlZF9ydW4pIHsKKyAgICAgICAgcHJpbnRfZGF0YShwLCB1bmVzY2FwZWRfcnVuLCAmYnVmW2ldIC0gdW5lc2NhcGVkX3J1bik7CisgICAgICAgIHVuZXNjYXBlZF9ydW4gPSBOVUxMOworICAgICAgfQorICAgICAgLy8gVGhlbiBwcmludCB0aGUgZXNjYXBlIGNvZGUuCisgICAgICBwcmludF9kYXRhKHAsIGVzY2FwZSwgc3RybGVuKGVzY2FwZSkpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBBZGQgdG8gdGhlIGN1cnJlbnQgdW5lc2NhcGVkIHJ1biBvZiBjaGFyYWN0ZXJzLgorICAgICAgaWYgKHVuZXNjYXBlZF9ydW4gPT0gTlVMTCkgeworICAgICAgICB1bmVzY2FwZWRfcnVuID0gJmJ1ZltpXTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBJZiB0aGUgc3RyaW5nIGVuZGVkIGluIGEgcnVuIG9mIHVuZXNjYXBlZCBjaGFyYWN0ZXJzLCBwcmludCB0aGF0IGxhc3QgcnVuLgorICBpZiAodW5lc2NhcGVkX3J1bikgeworICAgIHByaW50X2RhdGEocCwgdW5lc2NhcGVkX3J1biwgJmJ1ZltsZW5dIC0gdW5lc2NhcGVkX3J1bik7CisgIH0KK30KKworI2RlZmluZSBDSEtMRU5HVEgoeCkgaWYgKCEoeCkpIHJldHVybiAtMTsKKworLy8gSGVscGVycyB0aGF0IGZvcm1hdCBmbG9hdGluZyBwb2ludCB2YWx1ZXMgYWNjb3JkaW5nIHRvIG91ciBjdXN0b20gZm9ybWF0cy4KKy8vIFJpZ2h0IG5vdyB3ZSB1c2UgJS44ZyBhbmQgJS4xN2cgZm9yIGZsb2F0L2RvdWJsZSwgcmVzcGVjdGl2ZWx5LCB0byBtYXRjaAorLy8gcHJvdG8yOjp1dGlsOjpKc29uRm9ybWF0J3MgZGVmYXVsdHMuICBNYXkgd2FudCB0byBjaGFuZ2UgdGhpcyBsYXRlci4KKworc3RhdGljIHNpemVfdCBmbXRfZG91YmxlKGRvdWJsZSB2YWwsIGNoYXIqIGJ1Ziwgc2l6ZV90IGxlbmd0aCkgeworICBzaXplX3QgbiA9IHNucHJpbnRmKGJ1ZiwgbGVuZ3RoLCAiJS4xN2ciLCB2YWwpOworICBDSEtMRU5HVEgobiA+IDAgJiYgbiA8IGxlbmd0aCk7CisgIHJldHVybiBuOworfQorCitzdGF0aWMgc2l6ZV90IGZtdF9mbG9hdChmbG9hdCB2YWwsIGNoYXIqIGJ1Ziwgc2l6ZV90IGxlbmd0aCkgeworICBzaXplX3QgbiA9IHNucHJpbnRmKGJ1ZiwgbGVuZ3RoLCAiJS44ZyIsIHZhbCk7CisgIENIS0xFTkdUSChuID4gMCAmJiBuIDwgbGVuZ3RoKTsKKyAgcmV0dXJuIG47Cit9CisKK3N0YXRpYyBzaXplX3QgZm10X2Jvb2woYm9vbCB2YWwsIGNoYXIqIGJ1Ziwgc2l6ZV90IGxlbmd0aCkgeworICBzaXplX3QgbiA9IHNucHJpbnRmKGJ1ZiwgbGVuZ3RoLCAiJXMiLCAodmFsID8gInRydWUiIDogImZhbHNlIikpOworICBDSEtMRU5HVEgobiA+IDAgJiYgbiA8IGxlbmd0aCk7CisgIHJldHVybiBuOworfQorCitzdGF0aWMgc2l6ZV90IGZtdF9pbnQ2NChsb25nIHZhbCwgY2hhciogYnVmLCBzaXplX3QgbGVuZ3RoKSB7CisgIHNpemVfdCBuID0gc25wcmludGYoYnVmLCBsZW5ndGgsICIlbGQiLCB2YWwpOworICBDSEtMRU5HVEgobiA+IDAgJiYgbiA8IGxlbmd0aCk7CisgIHJldHVybiBuOworfQorCitzdGF0aWMgc2l6ZV90IGZtdF91aW50NjQodW5zaWduZWQgbG9uZyBsb25nIHZhbCwgY2hhciogYnVmLCBzaXplX3QgbGVuZ3RoKSB7CisgIHNpemVfdCBuID0gc25wcmludGYoYnVmLCBsZW5ndGgsICIlbGx1IiwgdmFsKTsKKyAgQ0hLTEVOR1RIKG4gPiAwICYmIG4gPCBsZW5ndGgpOworICByZXR1cm4gbjsKK30KKworLy8gUHJpbnQgYSBtYXAga2V5IGdpdmVuIGEgZmllbGQgbmFtZS4gQ2FsbGVkIGJ5IHNjYWxhciBmaWVsZCBoYW5kbGVycyBhbmQgYnkKKy8vIHN0YXJ0c2VxIGZvciByZXBlYXRlZCBmaWVsZHMuCitzdGF0aWMgYm9vbCBwdXRrZXkodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhKSB7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBjb25zdCBzdHJwYyAqa2V5ID0gaGFuZGxlcl9kYXRhOworICBwcmludF9jb21tYShwKTsKKyAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgcHV0c3RyaW5nKHAsIGtleS0+cHRyLCBrZXktPmxlbik7CisgIHByaW50X2RhdGEocCwgIlwiOiIsIDIpOworICByZXR1cm4gdHJ1ZTsKK30KKworI2RlZmluZSBDSEtGTVQodmFsKSBpZiAoKHZhbCkgPT0gLTEpIHJldHVybiBmYWxzZTsKKyNkZWZpbmUgQ0hLKHZhbCkgICAgaWYgKCEodmFsKSkgcmV0dXJuIGZhbHNlOworCisjZGVmaW5lIFRZUEVfSEFORExFUlModHlwZSwgZm10X2Z1bmMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgcHV0IyN0eXBlKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwgdHlwZSB2YWwpIHsgXAorICAgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjaGFyIGRhdGFbNjRdOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHNpemVfdCBsZW5ndGggPSBmbXRfZnVuYyh2YWwsIGRhdGEsIHNpemVvZihkYXRhKSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgQ0hLRk1UKGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBwcmludF9kYXRhKHAsIGRhdGEsIGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgc2NhbGFyXyMjdHlwZSh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgdmFsKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgQ0hLKHB1dGtleShjbG9zdXJlLCBoYW5kbGVyX2RhdGEpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBDSEsocHV0IyN0eXBlKGNsb3N1cmUsIGhhbmRsZXJfZGF0YSwgdmFsKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgcmVwZWF0ZWRfIyN0eXBlKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSB2YWwpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBwcmludF9jb21tYShwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIENISyhwdXQjI3R5cGUoY2xvc3VyZSwgaGFuZGxlcl9kYXRhLCB2YWwpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCisjZGVmaW5lIFRZUEVfSEFORExFUlNfTUFQS0VZKHR5cGUsIGZtdF9mdW5jKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgc3RhdGljIGJvb2wgcHV0bWFwa2V5XyMjdHlwZSh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEsICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgdmFsKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBwcmludF9kYXRhKHAsICJcIiIsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIENISyhwdXQjI3R5cGUoY2xvc3VyZSwgaGFuZGxlcl9kYXRhLCB2YWwpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcHJpbnRfZGF0YShwLCAiXCI6IiwgMik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK1RZUEVfSEFORExFUlMoZG91YmxlLCAgIGZtdF9kb3VibGUpOworVFlQRV9IQU5ETEVSUyhmbG9hdCwgICAgZm10X2Zsb2F0KTsKK1RZUEVfSEFORExFUlMoYm9vbCwgICAgIGZtdF9ib29sKTsKK1RZUEVfSEFORExFUlMoaW50MzJfdCwgIGZtdF9pbnQ2NCk7CitUWVBFX0hBTkRMRVJTKHVpbnQzMl90LCBmbXRfaW50NjQpOworVFlQRV9IQU5ETEVSUyhpbnQ2NF90LCAgZm10X2ludDY0KTsKK1RZUEVfSEFORExFUlModWludDY0X3QsIGZtdF91aW50NjQpOworCisvLyBkb3VibGUgYW5kIGZsb2F0IGFyZSBub3QgYWxsb3dlZCB0byBiZSBtYXAga2V5cy4KK1RZUEVfSEFORExFUlNfTUFQS0VZKGJvb2wsICAgICBmbXRfYm9vbCk7CitUWVBFX0hBTkRMRVJTX01BUEtFWShpbnQzMl90LCAgZm10X2ludDY0KTsKK1RZUEVfSEFORExFUlNfTUFQS0VZKHVpbnQzMl90LCBmbXRfaW50NjQpOworVFlQRV9IQU5ETEVSU19NQVBLRVkoaW50NjRfdCwgIGZtdF9pbnQ2NCk7CitUWVBFX0hBTkRMRVJTX01BUEtFWSh1aW50NjRfdCwgZm10X3VpbnQ2NCk7CisKKyN1bmRlZiBUWVBFX0hBTkRMRVJTCisjdW5kZWYgVFlQRV9IQU5ETEVSU19NQVBLRVkKKwordHlwZWRlZiBzdHJ1Y3QgeworICB2b2lkICprZXluYW1lOworICBjb25zdCB1cGJfZW51bWRlZiAqZW51bWRlZjsKK30gRW51bUhhbmRsZXJEYXRhOworCitzdGF0aWMgYm9vbCBzY2FsYXJfZW51bSh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHZhbCkgeworICBjb25zdCBFbnVtSGFuZGxlckRhdGEgKmhkID0gaGFuZGxlcl9kYXRhOworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgQ0hLKHB1dGtleShjbG9zdXJlLCBoZC0+a2V5bmFtZSkpOworCisgIGNvbnN0IGNoYXIgKnN5bWJvbGljX25hbWUgPSB1cGJfZW51bWRlZl9pdG9uKGhkLT5lbnVtZGVmLCB2YWwpOworICBpZiAoc3ltYm9saWNfbmFtZSkgeworICAgIHByaW50X2RhdGEocCwgIlwiIiwgMSk7CisgICAgcHV0c3RyaW5nKHAsIHN5bWJvbGljX25hbWUsIHN0cmxlbihzeW1ib2xpY19uYW1lKSk7CisgICAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgfSBlbHNlIHsKKyAgICBwdXRpbnQzMl90KGNsb3N1cmUsIE5VTEwsIHZhbCk7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIHZvaWQgcHJpbnRfZW51bV9zeW1ib2xpY19uYW1lKHVwYl9qc29uX3ByaW50ZXIgKnAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2VudW1kZWYgKmRlZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHZhbCkgeworICBjb25zdCBjaGFyICpzeW1ib2xpY19uYW1lID0gdXBiX2VudW1kZWZfaXRvbihkZWYsIHZhbCk7CisgIGlmIChzeW1ib2xpY19uYW1lKSB7CisgICAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgICBwdXRzdHJpbmcocCwgc3ltYm9saWNfbmFtZSwgc3RybGVuKHN5bWJvbGljX25hbWUpKTsKKyAgICBwcmludF9kYXRhKHAsICJcIiIsIDEpOworICB9IGVsc2UgeworICAgIHB1dGludDMyX3QocCwgTlVMTCwgdmFsKTsKKyAgfQorfQorCitzdGF0aWMgYm9vbCByZXBlYXRlZF9lbnVtKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB2YWwpIHsKKyAgY29uc3QgRW51bUhhbmRsZXJEYXRhICpoZCA9IGhhbmRsZXJfZGF0YTsKKyAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIHByaW50X2NvbW1hKHApOworCisgIHByaW50X2VudW1fc3ltYm9saWNfbmFtZShwLCBoZC0+ZW51bWRlZiwgdmFsKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wgbWFwdmFsdWVfZW51bSh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdmFsKSB7CisgIGNvbnN0IEVudW1IYW5kbGVyRGF0YSAqaGQgPSBoYW5kbGVyX2RhdGE7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworCisgIHByaW50X2VudW1fc3ltYm9saWNfbmFtZShwLCBoZC0+ZW51bWRlZiwgdmFsKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIHZvaWQgKnNjYWxhcl9zdGFydHN1Ym1zZyh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgcmV0dXJuIHB1dGtleShjbG9zdXJlLCBoYW5kbGVyX2RhdGEpID8gY2xvc3VyZSA6IFVQQl9CUkVBSzsKK30KKworc3RhdGljIHZvaWQgKnJlcGVhdGVkX3N0YXJ0c3VibXNnKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSkgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBwcmludF9jb21tYShwKTsKKyAgcmV0dXJuIGNsb3N1cmU7Cit9CisKK3N0YXRpYyB2b2lkIHN0YXJ0X2ZyYW1lKHVwYl9qc29uX3ByaW50ZXIgKnApIHsKKyAgcC0+ZGVwdGhfKys7CisgIHAtPmZpcnN0X2VsZW1fW3AtPmRlcHRoX10gPSB0cnVlOworICBwcmludF9kYXRhKHAsICJ7IiwgMSk7Cit9CisKK3N0YXRpYyB2b2lkIGVuZF9mcmFtZSh1cGJfanNvbl9wcmludGVyICpwKSB7CisgIHByaW50X2RhdGEocCwgIn0iLCAxKTsKKyAgcC0+ZGVwdGhfLS07Cit9CisKK3N0YXRpYyBib29sIHByaW50ZXJfc3RhcnRtc2codm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhKSB7CisgIFVQQl9VTlVTRUQoaGFuZGxlcl9kYXRhKTsKKyAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIGlmIChwLT5kZXB0aF8gPT0gMCkgeworICAgIHVwYl9ieXRlc3Npbmtfc3RhcnQocC0+b3V0cHV0XywgMCwgJnAtPnN1YmNfKTsKKyAgfQorICBzdGFydF9mcmFtZShwKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIHByaW50ZXJfZW5kbXNnKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwgdXBiX3N0YXR1cyAqcykgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIFVQQl9VTlVTRUQocyk7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBlbmRfZnJhbWUocCk7CisgIGlmIChwLT5kZXB0aF8gPT0gMCkgeworICAgIHVwYl9ieXRlc3NpbmtfZW5kKHAtPm91dHB1dF8pOworICB9CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgdm9pZCAqc3RhcnRzZXEodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhKSB7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBDSEsocHV0a2V5KGNsb3N1cmUsIGhhbmRsZXJfZGF0YSkpOworICBwLT5kZXB0aF8rKzsKKyAgcC0+Zmlyc3RfZWxlbV9bcC0+ZGVwdGhfXSA9IHRydWU7CisgIHByaW50X2RhdGEocCwgIlsiLCAxKTsKKyAgcmV0dXJuIGNsb3N1cmU7Cit9CisKK3N0YXRpYyBib29sIGVuZHNlcSh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgcHJpbnRfZGF0YShwLCAiXSIsIDEpOworICBwLT5kZXB0aF8tLTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB2b2lkICpzdGFydG1hcCh2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIENISyhwdXRrZXkoY2xvc3VyZSwgaGFuZGxlcl9kYXRhKSk7CisgIHAtPmRlcHRoXysrOworICBwLT5maXJzdF9lbGVtX1twLT5kZXB0aF9dID0gdHJ1ZTsKKyAgcHJpbnRfZGF0YShwLCAieyIsIDEpOworICByZXR1cm4gY2xvc3VyZTsKK30KKworc3RhdGljIGJvb2wgZW5kbWFwKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSkgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBwcmludF9kYXRhKHAsICJ9IiwgMSk7CisgIHAtPmRlcHRoXy0tOworICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIHNpemVfdCBwdXRzdHIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLCBjb25zdCBjaGFyICpzdHIsCisgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuLCBjb25zdCB1cGJfYnVmaGFuZGxlICpoYW5kbGUpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBwdXRzdHJpbmcocCwgc3RyLCBsZW4pOworICByZXR1cm4gbGVuOworfQorCisvLyBUaGlzIGhhcyB0byBCYXNlNjQgZW5jb2RlIHRoZSBieXRlcywgYmVjYXVzZSBKU09OIGhhcyBubyAiYnl0ZXMiIHR5cGUuCitzdGF0aWMgc2l6ZV90IHB1dGJ5dGVzKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwgY29uc3QgY2hhciAqc3RyLAorICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuLCBjb25zdCB1cGJfYnVmaGFuZGxlICpoYW5kbGUpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICBVUEJfVU5VU0VEKGhhbmRsZSk7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworCisgIC8vIFRoaXMgaXMgdGhlIHJlZ3VsYXIgYmFzZTY0LCBub3QgdGhlICJ3ZWItc2FmZSIgdmVyc2lvbi4KKyAgc3RhdGljIGNvbnN0IGNoYXIgYmFzZTY0W10gPQorICAgICAgIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8iOworCisgIC8vIEJhc2U2NC1lbmNvZGUuCisgIGNoYXIgZGF0YVsxNjAwMF07CisgIGNvbnN0IGNoYXIgKmxpbWl0ID0gZGF0YSArIHNpemVvZihkYXRhKTsKKyAgY29uc3QgdW5zaWduZWQgY2hhciAqZnJvbSA9IChjb25zdCB1bnNpZ25lZCBjaGFyKilzdHI7CisgIGNoYXIgKnRvID0gZGF0YTsKKyAgc2l6ZV90IHJlbWFpbmluZyA9IGxlbjsKKyAgd2hpbGUgKHJlbWFpbmluZyA+IDIpIHsKKyAgICAvLyBUT0RPKGhhYmVybWFuKTogaGFuZGxlIGVuY29kZWQgbGVuZ3RocyA+IHNpemVvZihkYXRhKQorICAgIFVQQl9BU1NFUlRfVkFSKGxpbWl0LCAobGltaXQgLSB0bykgPj0gNCk7CisKKyAgICB0b1swXSA9IGJhc2U2NFtmcm9tWzBdID4+IDJdOworICAgIHRvWzFdID0gYmFzZTY0WygoZnJvbVswXSAmIDB4MykgPDwgNCkgfCAoZnJvbVsxXSA+PiA0KV07CisgICAgdG9bMl0gPSBiYXNlNjRbKChmcm9tWzFdICYgMHhmKSA8PCAyKSB8IChmcm9tWzJdID4+IDYpXTsKKyAgICB0b1szXSA9IGJhc2U2NFtmcm9tWzJdICYgMHgzZl07CisKKyAgICByZW1haW5pbmcgLT0gMzsKKyAgICB0byArPSA0OworICAgIGZyb20gKz0gMzsKKyAgfQorCisgIHN3aXRjaCAocmVtYWluaW5nKSB7CisgICAgY2FzZSAyOgorICAgICAgdG9bMF0gPSBiYXNlNjRbZnJvbVswXSA+PiAyXTsKKyAgICAgIHRvWzFdID0gYmFzZTY0WygoZnJvbVswXSAmIDB4MykgPDwgNCkgfCAoZnJvbVsxXSA+PiA0KV07CisgICAgICB0b1syXSA9IGJhc2U2NFsoZnJvbVsxXSAmIDB4ZikgPDwgMl07CisgICAgICB0b1szXSA9ICc9JzsKKyAgICAgIHRvICs9IDQ7CisgICAgICBmcm9tICs9IDI7CisgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICB0b1swXSA9IGJhc2U2NFtmcm9tWzBdID4+IDJdOworICAgICAgdG9bMV0gPSBiYXNlNjRbKChmcm9tWzBdICYgMHgzKSA8PCA0KV07CisgICAgICB0b1syXSA9ICc9JzsKKyAgICAgIHRvWzNdID0gJz0nOworICAgICAgdG8gKz0gNDsKKyAgICAgIGZyb20gKz0gMTsKKyAgICAgIGJyZWFrOworICB9CisKKyAgc2l6ZV90IGJ5dGVzID0gdG8gLSBkYXRhOworICBwcmludF9kYXRhKHAsICJcIiIsIDEpOworICBwdXRzdHJpbmcocCwgZGF0YSwgYnl0ZXMpOworICBwcmludF9kYXRhKHAsICJcIiIsIDEpOworICByZXR1cm4gbGVuOworfQorCitzdGF0aWMgdm9pZCAqc2NhbGFyX3N0YXJ0c3RyKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemVfaGludCkgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIFVQQl9VTlVTRUQoc2l6ZV9oaW50KTsKKyAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIENISyhwdXRrZXkoY2xvc3VyZSwgaGFuZGxlcl9kYXRhKSk7CisgIHByaW50X2RhdGEocCwgIlwiIiwgMSk7CisgIHJldHVybiBwOworfQorCitzdGF0aWMgc2l6ZV90IHNjYWxhcl9zdHIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfYnVmaGFuZGxlICpoYW5kbGUpIHsKKyAgQ0hLKHB1dHN0cihjbG9zdXJlLCBoYW5kbGVyX2RhdGEsIHN0ciwgbGVuLCBoYW5kbGUpKTsKKyAgcmV0dXJuIGxlbjsKK30KKworc3RhdGljIGJvb2wgc2NhbGFyX2VuZHN0cih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB2b2lkICpyZXBlYXRlZF9zdGFydHN0cih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemVfaGludCkgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIFVQQl9VTlVTRUQoc2l6ZV9oaW50KTsKKyAgdXBiX2pzb25fcHJpbnRlciAqcCA9IGNsb3N1cmU7CisgIHByaW50X2NvbW1hKHApOworICBwcmludF9kYXRhKHAsICJcIiIsIDEpOworICByZXR1cm4gcDsKK30KKworc3RhdGljIHNpemVfdCByZXBlYXRlZF9zdHIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqc3RyLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIENISyhwdXRzdHIoY2xvc3VyZSwgaGFuZGxlcl9kYXRhLCBzdHIsIGxlbiwgaGFuZGxlKSk7CisgIHJldHVybiBsZW47Cit9CisKK3N0YXRpYyBib29sIHJlcGVhdGVkX2VuZHN0cih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB2b2lkICptYXBrZXl2YWxfc3RhcnRzdHIodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZV9oaW50KSB7CisgIFVQQl9VTlVTRUQoaGFuZGxlcl9kYXRhKTsKKyAgVVBCX1VOVVNFRChzaXplX2hpbnQpOworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgcmV0dXJuIHA7Cit9CisKK3N0YXRpYyBzaXplX3QgbWFwa2V5X3N0cih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqc3RyLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICBDSEsocHV0c3RyKGNsb3N1cmUsIGhhbmRsZXJfZGF0YSwgc3RyLCBsZW4sIGhhbmRsZSkpOworICByZXR1cm4gbGVuOworfQorCitzdGF0aWMgYm9vbCBtYXBrZXlfZW5kc3RyKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSkgeworICBVUEJfVU5VU0VEKGhhbmRsZXJfZGF0YSk7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBwcmludF9kYXRhKHAsICJcIjoiLCAyKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIG1hcHZhbHVlX2VuZHN0cih2b2lkICpjbG9zdXJlLCBjb25zdCB2b2lkICpoYW5kbGVyX2RhdGEpIHsKKyAgVVBCX1VOVVNFRChoYW5kbGVyX2RhdGEpOworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgcHJpbnRfZGF0YShwLCAiXCIiLCAxKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBzaXplX3Qgc2NhbGFyX2J5dGVzKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICBDSEsocHV0a2V5KGNsb3N1cmUsIGhhbmRsZXJfZGF0YSkpOworICBDSEsocHV0Ynl0ZXMoY2xvc3VyZSwgaGFuZGxlcl9kYXRhLCBzdHIsIGxlbiwgaGFuZGxlKSk7CisgIHJldHVybiBsZW47Cit9CisKK3N0YXRpYyBzaXplX3QgcmVwZWF0ZWRfYnl0ZXModm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpzdHIsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSkgeworICB1cGJfanNvbl9wcmludGVyICpwID0gY2xvc3VyZTsKKyAgcHJpbnRfY29tbWEocCk7CisgIENISyhwdXRieXRlcyhjbG9zdXJlLCBoYW5kbGVyX2RhdGEsIHN0ciwgbGVuLCBoYW5kbGUpKTsKKyAgcmV0dXJuIGxlbjsKK30KKworc3RhdGljIHNpemVfdCBtYXBrZXlfYnl0ZXModm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqc3RyLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlKSB7CisgIHVwYl9qc29uX3ByaW50ZXIgKnAgPSBjbG9zdXJlOworICBDSEsocHV0Ynl0ZXMoY2xvc3VyZSwgaGFuZGxlcl9kYXRhLCBzdHIsIGxlbiwgaGFuZGxlKSk7CisgIHByaW50X2RhdGEocCwgIjoiLCAxKTsKKyAgcmV0dXJuIGxlbjsKK30KKworc3RhdGljIHZvaWQgc2V0X2VudW1faGQodXBiX2hhbmRsZXJzICpoLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKSB7CisgIEVudW1IYW5kbGVyRGF0YSAqaGQgPSBtYWxsb2Moc2l6ZW9mKEVudW1IYW5kbGVyRGF0YSkpOworICBoZC0+ZW51bWRlZiA9IChjb25zdCB1cGJfZW51bWRlZiAqKXVwYl9maWVsZGRlZl9zdWJkZWYoZik7CisgIGhkLT5rZXluYW1lID0gbmV3c3RycGMoaCwgZik7CisgIHVwYl9oYW5kbGVyc19hZGRjbGVhbnVwKGgsIGhkLCBmcmVlKTsKKyAgdXBiX2hhbmRsZXJhdHRyX3NldGhhbmRsZXJkYXRhKGF0dHIsIGhkKTsKK30KKworLy8gU2V0IHVwIGhhbmRsZXJzIGZvciBhIG1hcGVudHJ5IHN1Ym1lc3NhZ2UgKGkuZS4sIGFuIGluZGl2aWR1YWwga2V5L3ZhbHVlIHBhaXIKKy8vIGluIGEgbWFwKS4KKy8vCisvLyBUT0RPOiBIYW5kbGUgbWlzc2luZyBrZXksIG1pc3NpbmcgdmFsdWUsIG91dC1vZi1vcmRlciBrZXkvdmFsdWUsIG9yIHJlcGVhdGVkCisvLyBrZXkgb3IgdmFsdWUgY2FzZXMgcHJvcGVybHkuIFRoZSByaWdodCB3YXkgdG8gZG8gdGhpcyBpcyB0byBhbGxvY2F0ZSBhCisvLyB0ZW1wb3Jhcnkgc3RydWN0dXJlIGF0IHRoZSBzdGFydCBvZiBhIG1hcGVudHJ5IHN1Ym1lc3NhZ2UsIHN0b3JlIGtleSBhbmQKKy8vIHZhbHVlIGRhdGEgaW4gaXQgYXMga2V5IGFuZCB2YWx1ZSBoYW5kbGVycyBhcmUgY2FsbGVkLCBhbmQgdGhlbiBwcmludCB0aGUKKy8vIGtleS92YWx1ZSBwYWlyIG9uY2UgYXQgdGhlIGVuZCBvZiB0aGUgc3VibWVzc2FnZS4gSWYgd2UgZG9uJ3QgZG8gdGhpcywgd2UKKy8vIHNob3VsZCBhdCBsZWFzdCBkZXRlY3QgdGhlIGNhc2UgYW5kIHRocm93IGFuIGVycm9yLiBIb3dldmVyLCBzbyBmYXIgYWxsIG9mCisvLyBvdXIgc291cmNlcyB0aGF0IGVtaXQgbWFwZW50cnkgbWVzc2FnZXMgZG8gc28gY2Fub25pY2FsbHkgKHdpdGggb25lIGtleQorLy8gZmllbGQsIGFuZCB0aGVuIG9uZSB2YWx1ZSBmaWVsZCksIHNvIHRoaXMgaXMgbm90IGEgcHJlc3NpbmcgY29uY2VybiBhdCB0aGUKKy8vIG1vbWVudC4KK3ZvaWQgcHJpbnRlcl9zZXRoYW5kbGVyc19tYXBlbnRyeShjb25zdCB2b2lkICpjbG9zdXJlLCB1cGJfaGFuZGxlcnMgKmgpIHsKKyAgVVBCX1VOVVNFRChjbG9zdXJlKTsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbWQgPSB1cGJfaGFuZGxlcnNfbXNnZGVmKGgpOworCisgIC8vIEEgbWFwZW50cnkgbWVzc2FnZSBpcyBwcmludGVkIHNpbXBseSBhcyAnImtleSI6IHZhbHVlJy4gUmF0aGVyIHRoYW4KKyAgLy8gc3BlY2lhbC1jYXNlIGtleSBhbmQgdmFsdWUgZm9yIGV2ZXJ5IHR5cGUgYmVsb3csIHdlIGp1c3QgaGFuZGxlIGJvdGgKKyAgLy8gZmllbGRzIGV4cGxpY2l0bHkgaGVyZS4KKyAgY29uc3QgdXBiX2ZpZWxkZGVmKiBrZXlfZmllbGQgPSB1cGJfbXNnZGVmX2l0b2YobWQsIFVQQl9NQVBFTlRSWV9LRVkpOworICBjb25zdCB1cGJfZmllbGRkZWYqIHZhbHVlX2ZpZWxkID0gdXBiX21zZ2RlZl9pdG9mKG1kLCBVUEJfTUFQRU5UUllfVkFMVUUpOworCisgIHVwYl9oYW5kbGVyYXR0ciBlbXB0eV9hdHRyID0gVVBCX0hBTkRMRVJBVFRSX0lOSVRJQUxJWkVSOworCisgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUoa2V5X2ZpZWxkKSkgeworICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6CisgICAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwga2V5X2ZpZWxkLCBwdXRtYXBrZXlfaW50MzJfdCwgJmVtcHR5X2F0dHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9JTlQ2NDoKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRpbnQ2NChoLCBrZXlfZmllbGQsIHB1dG1hcGtleV9pbnQ2NF90LCAmZW1wdHlfYXR0cik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX1VJTlQzMjoKKyAgICAgIHVwYl9oYW5kbGVyc19zZXR1aW50MzIoaCwga2V5X2ZpZWxkLCBwdXRtYXBrZXlfdWludDMyX3QsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDY0OgorICAgICAgdXBiX2hhbmRsZXJzX3NldHVpbnQ2NChoLCBrZXlfZmllbGQsIHB1dG1hcGtleV91aW50NjRfdCwgJmVtcHR5X2F0dHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9CT09MOgorICAgICAgdXBiX2hhbmRsZXJzX3NldGJvb2woaCwga2V5X2ZpZWxkLCBwdXRtYXBrZXlfYm9vbCwgJmVtcHR5X2F0dHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9TVFJJTkc6CisgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdHIoaCwga2V5X2ZpZWxkLCBtYXBrZXl2YWxfc3RhcnRzdHIsICZlbXB0eV9hdHRyKTsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwga2V5X2ZpZWxkLCBtYXBrZXlfc3RyLCAmZW1wdHlfYXR0cik7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc3RyKGgsIGtleV9maWVsZCwgbWFwa2V5X2VuZHN0ciwgJmVtcHR5X2F0dHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9CWVRFUzoKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwga2V5X2ZpZWxkLCBtYXBrZXlfYnl0ZXMsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBhc3NlcnQoZmFsc2UpOworICAgICAgYnJlYWs7CisgIH0KKworICBzd2l0Y2ggKHVwYl9maWVsZGRlZl90eXBlKHZhbHVlX2ZpZWxkKSkgeworICAgIGNhc2UgVVBCX1RZUEVfSU5UMzI6CisgICAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwgdmFsdWVfZmllbGQsIHB1dGludDMyX3QsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfSU5UNjQ6CisgICAgICB1cGJfaGFuZGxlcnNfc2V0aW50NjQoaCwgdmFsdWVfZmllbGQsIHB1dGludDY0X3QsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDMyOgorICAgICAgdXBiX2hhbmRsZXJzX3NldHVpbnQzMihoLCB2YWx1ZV9maWVsZCwgcHV0dWludDMyX3QsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfVUlOVDY0OgorICAgICAgdXBiX2hhbmRsZXJzX3NldHVpbnQ2NChoLCB2YWx1ZV9maWVsZCwgcHV0dWludDY0X3QsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfQk9PTDoKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRib29sKGgsIHZhbHVlX2ZpZWxkLCBwdXRib29sLCAmZW1wdHlfYXR0cik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0ZMT0FUOgorICAgICAgdXBiX2hhbmRsZXJzX3NldGZsb2F0KGgsIHZhbHVlX2ZpZWxkLCBwdXRmbG9hdCwgJmVtcHR5X2F0dHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVUEJfVFlQRV9ET1VCTEU6CisgICAgICB1cGJfaGFuZGxlcnNfc2V0ZG91YmxlKGgsIHZhbHVlX2ZpZWxkLCBwdXRkb3VibGUsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfU1RSSU5HOgorICAgICAgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c3RyKGgsIHZhbHVlX2ZpZWxkLCBtYXBrZXl2YWxfc3RhcnRzdHIsICZlbXB0eV9hdHRyKTsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgdmFsdWVfZmllbGQsIHB1dHN0ciwgJmVtcHR5X2F0dHIpOworICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN0cihoLCB2YWx1ZV9maWVsZCwgbWFwdmFsdWVfZW5kc3RyLCAmZW1wdHlfYXR0cik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVQQl9UWVBFX0JZVEVTOgorICAgICAgdXBiX2hhbmRsZXJzX3NldHN0cmluZyhoLCB2YWx1ZV9maWVsZCwgcHV0Ynl0ZXMsICZlbXB0eV9hdHRyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVVBCX1RZUEVfRU5VTTogeworICAgICAgdXBiX2hhbmRsZXJhdHRyIGVudW1fYXR0ciA9IFVQQl9IQU5ETEVSQVRUUl9JTklUSUFMSVpFUjsKKyAgICAgIHNldF9lbnVtX2hkKGgsIHZhbHVlX2ZpZWxkLCAmZW51bV9hdHRyKTsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRpbnQzMihoLCB2YWx1ZV9maWVsZCwgbWFwdmFsdWVfZW51bSwgJmVudW1fYXR0cik7CisgICAgICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZlbnVtX2F0dHIpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgVVBCX1RZUEVfTUVTU0FHRToKKyAgICAgIC8vIE5vIGhhbmRsZXIgbmVjZXNzYXJ5IC0tIHRoZSBzdWJtc2cgaGFuZGxlcnMgd2lsbCBwcmludCB0aGUgbWVzc2FnZQorICAgICAgLy8gYXMgYXBwcm9wcmlhdGUuCisgICAgICBicmVhazsKKyAgfQorCisgIHVwYl9oYW5kbGVyYXR0cl91bmluaXQoJmVtcHR5X2F0dHIpOworfQorCit2b2lkIHByaW50ZXJfc2V0aGFuZGxlcnMoY29uc3Qgdm9pZCAqY2xvc3VyZSwgdXBiX2hhbmRsZXJzICpoKSB7CisgIFVQQl9VTlVTRUQoY2xvc3VyZSk7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm1kID0gdXBiX2hhbmRsZXJzX21zZ2RlZihoKTsKKyAgYm9vbCBpc19tYXBlbnRyeSA9IHVwYl9tc2dkZWZfbWFwZW50cnkobWQpOworICB1cGJfaGFuZGxlcmF0dHIgZW1wdHlfYXR0ciA9IFVQQl9IQU5ETEVSQVRUUl9JTklUSUFMSVpFUjsKKworICBpZiAoaXNfbWFwZW50cnkpIHsKKyAgICAvLyBtYXBlbnRyeSBtZXNzYWdlcyBhcmUgc3VmZmljaWVudGx5IGRpZmZlcmVudCB0aGF0IHdlIGhhbmRsZSB0aGVtCisgICAgLy8gc2VwYXJhdGVseS4KKyAgICBwcmludGVyX3NldGhhbmRsZXJzX21hcGVudHJ5KGNsb3N1cmUsIGgpOworICAgIHJldHVybjsKKyAgfQorCisgIHVwYl9oYW5kbGVyc19zZXRzdGFydG1zZyhoLCBwcmludGVyX3N0YXJ0bXNnLCAmZW1wdHlfYXR0cik7CisgIHVwYl9oYW5kbGVyc19zZXRlbmRtc2coaCwgcHJpbnRlcl9lbmRtc2csICZlbXB0eV9hdHRyKTsKKworI2RlZmluZSBUWVBFKHR5cGUsIG5hbWUsIGN0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYXNlIHR5cGU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgdXBiX2hhbmRsZXJzX3NldCMjbmFtZShoLCBmLCByZXBlYXRlZF8jI2N0eXBlLCAmZW1wdHlfYXR0cik7ICAgICAgICAgICAgXAorICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgdXBiX2hhbmRsZXJzX3NldCMjbmFtZShoLCBmLCBzY2FsYXJfIyNjdHlwZSwgJm5hbWVfYXR0cik7ICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGJyZWFrOworCisgIHVwYl9tc2dfZmllbGRfaXRlciBpOworICB1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpLCBtZCk7CisgIGZvcig7ICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmkpOyB1cGJfbXNnX2ZpZWxkX25leHQoJmkpKSB7CisgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpKTsKKworICAgIHVwYl9oYW5kbGVyYXR0ciBuYW1lX2F0dHIgPSBVUEJfSEFORExFUkFUVFJfSU5JVElBTElaRVI7CisgICAgdXBiX2hhbmRsZXJhdHRyX3NldGhhbmRsZXJkYXRhKCZuYW1lX2F0dHIsIG5ld3N0cnBjKGgsIGYpKTsKKworICAgIGlmICh1cGJfZmllbGRkZWZfaXNtYXAoZikpIHsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHNlcShoLCBmLCBzdGFydG1hcCwgJm5hbWVfYXR0cik7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc2VxKGgsIGYsIGVuZG1hcCwgJm5hbWVfYXR0cik7CisgICAgfSBlbHNlIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsKKyAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHNlcShoLCBmLCBzdGFydHNlcSwgJm5hbWVfYXR0cik7CisgICAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc2VxKGgsIGYsIGVuZHNlcSwgJmVtcHR5X2F0dHIpOworICAgIH0KKworICAgIHN3aXRjaCAodXBiX2ZpZWxkZGVmX3R5cGUoZikpIHsKKyAgICAgIFRZUEUoVVBCX1RZUEVfRkxPQVQsICBmbG9hdCwgIGZsb2F0KTsKKyAgICAgIFRZUEUoVVBCX1RZUEVfRE9VQkxFLCBkb3VibGUsIGRvdWJsZSk7CisgICAgICBUWVBFKFVQQl9UWVBFX0JPT0wsICAgYm9vbCwgICBib29sKTsKKyAgICAgIFRZUEUoVVBCX1RZUEVfSU5UMzIsICBpbnQzMiwgIGludDMyX3QpOworICAgICAgVFlQRShVUEJfVFlQRV9VSU5UMzIsIHVpbnQzMiwgdWludDMyX3QpOworICAgICAgVFlQRShVUEJfVFlQRV9JTlQ2NCwgIGludDY0LCAgaW50NjRfdCk7CisgICAgICBUWVBFKFVQQl9UWVBFX1VJTlQ2NCwgdWludDY0LCB1aW50NjRfdCk7CisgICAgICBjYXNlIFVQQl9UWVBFX0VOVU06IHsKKyAgICAgICAgLy8gRm9yIG5vdywgd2UgYWx3YXlzIGVtaXQgc3ltYm9saWMgbmFtZXMgZm9yIGVudW1zLiBXZSBtYXkgd2FudCBhbgorICAgICAgICAvLyBvcHRpb24gbGF0ZXIgdG8gY29udHJvbCB0aGlzIGJlaGF2aW9yLCBidXQgd2Ugd2lsbCB3YWl0IGZvciBhIHJlYWwKKyAgICAgICAgLy8gbmVlZCBmaXJzdC4KKyAgICAgICAgdXBiX2hhbmRsZXJhdHRyIGVudW1fYXR0ciA9IFVQQl9IQU5ETEVSQVRUUl9JTklUSUFMSVpFUjsKKyAgICAgICAgc2V0X2VudW1faGQoaCwgZiwgJmVudW1fYXR0cik7CisKKyAgICAgICAgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSkgeworICAgICAgICAgIHVwYl9oYW5kbGVyc19zZXRpbnQzMihoLCBmLCByZXBlYXRlZF9lbnVtLCAmZW51bV9hdHRyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB1cGJfaGFuZGxlcnNfc2V0aW50MzIoaCwgZiwgc2NhbGFyX2VudW0sICZlbnVtX2F0dHIpOworICAgICAgICB9CisKKyAgICAgICAgdXBiX2hhbmRsZXJhdHRyX3VuaW5pdCgmZW51bV9hdHRyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjYXNlIFVQQl9UWVBFX1NUUklORzoKKyAgICAgICAgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSkgeworICAgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHN0cihoLCBmLCByZXBlYXRlZF9zdGFydHN0ciwgJmVtcHR5X2F0dHIpOworICAgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgZiwgcmVwZWF0ZWRfc3RyLCAmZW1wdHlfYXR0cik7CisgICAgICAgICAgdXBiX2hhbmRsZXJzX3NldGVuZHN0cihoLCBmLCByZXBlYXRlZF9lbmRzdHIsICZlbXB0eV9hdHRyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdHIoaCwgZiwgc2NhbGFyX3N0YXJ0c3RyLCAmbmFtZV9hdHRyKTsKKyAgICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKGgsIGYsIHNjYWxhcl9zdHIsICZlbXB0eV9hdHRyKTsKKyAgICAgICAgICB1cGJfaGFuZGxlcnNfc2V0ZW5kc3RyKGgsIGYsIHNjYWxhcl9lbmRzdHIsICZlbXB0eV9hdHRyKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVVBCX1RZUEVfQllURVM6CisgICAgICAgIC8vIFhYWDogdGhpcyBkb2Vzbid0IHN1cHBvcnQgc3RyaW5ncyB0aGF0IHNwYW4gYnVmZmVycyB5ZXQuIFRoZSBiYXNlNjQKKyAgICAgICAgLy8gZW5jb2RlciB3aWxsIG5lZWQgdG8gYmUgbWFkZSByZXN1bWFibGUgZm9yIHRoaXMgdG8gd29yayBwcm9wZXJseS4KKyAgICAgICAgaWYgKHVwYl9maWVsZGRlZl9pc3NlcShmKSkgeworICAgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdHJpbmcoaCwgZiwgcmVwZWF0ZWRfYnl0ZXMsICZlbXB0eV9hdHRyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKGgsIGYsIHNjYWxhcl9ieXRlcywgJm5hbWVfYXR0cik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVQQl9UWVBFX01FU1NBR0U6CisgICAgICAgIGlmICh1cGJfZmllbGRkZWZfaXNzZXEoZikpIHsKKyAgICAgICAgICB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdWJtc2coaCwgZiwgcmVwZWF0ZWRfc3RhcnRzdWJtc2csICZuYW1lX2F0dHIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHVwYl9oYW5kbGVyc19zZXRzdGFydHN1Ym1zZyhoLCBmLCBzY2FsYXJfc3RhcnRzdWJtc2csICZuYW1lX2F0dHIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIHVwYl9oYW5kbGVyYXR0cl91bmluaXQoJm5hbWVfYXR0cik7CisgIH0KKworICB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KCZlbXB0eV9hdHRyKTsKKyN1bmRlZiBUWVBFCit9CisKKy8qIFB1YmxpYyBBUEkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3ZvaWQgdXBiX2pzb25fcHJpbnRlcl9pbml0KHVwYl9qc29uX3ByaW50ZXIgKnAsIGNvbnN0IHVwYl9oYW5kbGVycyAqaCkgeworICBwLT5vdXRwdXRfID0gTlVMTDsKKyAgcC0+ZGVwdGhfID0gMDsKKyAgdXBiX3NpbmtfcmVzZXQoJnAtPmlucHV0XywgaCwgcCk7Cit9CisKK3ZvaWQgdXBiX2pzb25fcHJpbnRlcl91bmluaXQodXBiX2pzb25fcHJpbnRlciAqcCkgeworICBVUEJfVU5VU0VEKHApOworfQorCit2b2lkIHVwYl9qc29uX3ByaW50ZXJfcmVzZXQodXBiX2pzb25fcHJpbnRlciAqcCkgeworICBwLT5kZXB0aF8gPSAwOworfQorCit2b2lkIHVwYl9qc29uX3ByaW50ZXJfcmVzZXRvdXRwdXQodXBiX2pzb25fcHJpbnRlciAqcCwgdXBiX2J5dGVzc2luayAqb3V0cHV0KSB7CisgIHVwYl9qc29uX3ByaW50ZXJfcmVzZXQocCk7CisgIHAtPm91dHB1dF8gPSBvdXRwdXQ7Cit9CisKK3VwYl9zaW5rICp1cGJfanNvbl9wcmludGVyX2lucHV0KHVwYl9qc29uX3ByaW50ZXIgKnApIHsKKyAgcmV0dXJuICZwLT5pbnB1dF87Cit9CisKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX2pzb25fcHJpbnRlcl9uZXdoYW5kbGVycyhjb25zdCB1cGJfbXNnZGVmICptZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpvd25lcikgeworICByZXR1cm4gdXBiX2hhbmRsZXJzX25ld2Zyb3plbihtZCwgb3duZXIsIHByaW50ZXJfc2V0aGFuZGxlcnMsIE5VTEwpOworfQpkaWZmIC0tZ2l0IGEvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvdXBiLmggYi9ydWJ5L2V4dC9nb29nbGUvcHJvdG9idWZfYy91cGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZjZkMzY0Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS9leHQvZ29vZ2xlL3Byb3RvYnVmX2MvdXBiLmgKQEAgLTAsMCArMSw4MDUwIEBACisvLyBBbWFsZ2FtYXRlZCBzb3VyY2UgZmlsZQorLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAwOS0yMDEyIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBEZWZzIGFyZSB1cGIncyBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29uc3RydWN0cyB0aGF0IGNhbiBhcHBlYXIKKyAqIGluIGEgLnByb3RvIGZpbGU6CisgKgorICogLSB1cGJfbXNnZGVmOiBkZXNjcmliZXMgYSAibWVzc2FnZSIgY29uc3RydWN0LgorICogLSB1cGJfZmllbGRkZWY6IGRlc2NyaWJlcyBhIG1lc3NhZ2UgZmllbGQuCisgKiAtIHVwYl9lbnVtZGVmOiBkZXNjcmliZXMgYW4gZW51bS4KKyAqIChUT0RPOiBkZWZpbml0aW9ucyBvZiBzZXJ2aWNlcykuCisgKgorICogTGlrZSB1cGJfcmVmY291bnRlZCBvYmplY3RzLCBkZWZzIGFyZSBtdXRhYmxlIG9ubHkgdW50aWwgZnJvemVuLCBhbmQgYXJlCisgKiBvbmx5IHRocmVhZC1zYWZlIG9uY2UgZnJvemVuLgorICoKKyAqIFRoaXMgaXMgYSBtaXhlZCBDL0MrKyBpbnRlcmZhY2UgdGhhdCBvZmZlcnMgYSBmdWxsIEFQSSB0byBib3RoIGxhbmd1YWdlcy4KKyAqIFNlZSB0aGUgdG9wLWxldmVsIFJFQURNRSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAqLworCisjaWZuZGVmIFVQQl9ERUZfSF8KKyNkZWZpbmUgVVBCX0RFRl9IXworCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTIgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIEEgcmVmY291bnRpbmcgc2NoZW1lIHRoYXQgc3VwcG9ydHMgY2lyY3VsYXIgcmVmcy4gIEl0IGFjY29tcGxpc2hlcyB0aGlzIGJ5CisgKiBwYXJ0aXRpb25pbmcgdGhlIHNldCBvZiBvYmplY3RzIGludG8gZ3JvdXBzIHN1Y2ggdGhhdCBubyBjeWNsZSBzcGFucyBncm91cHM7CisgKiB3ZSBjYW4gdGhlbiByZWZlcmVuY2UtY291bnQgdGhlIGdyb3VwIGFzIGEgd2hvbGUgYW5kIGlnbm9yZSByZWZzIHdpdGhpbiB0aGUKKyAqIGdyb3VwLiAgV2hlbiBvYmplY3RzIGFyZSBtdXRhYmxlLCB0aGVzZSBncm91cHMgYXJlIGNvbXB1dGVkIHZlcnkKKyAqIGNvbnNlcnZhdGl2ZWx5OyB3ZSBncm91cCBhbnkgb2JqZWN0cyB0aGF0IGhhdmUgZXZlciBoYWQgYSBsaW5rIGJldHdlZW4gdGhlbS4KKyAqIFdoZW4gb2JqZWN0cyBhcmUgZnJvemVuLCB3ZSBjb21wdXRlIHN0cm9uZ2x5LWNvbm5lY3RlZCBjb21wb25lbnRzIHdoaWNoCisgKiBhbGxvd3MgdXMgdG8gYmUgcHJlY2lzZSBhbmQgb25seSBncm91cCBvYmplY3RzIHRoYXQgYXJlIGFjdHVhbGx5IGN5Y2xpYy4KKyAqCisgKiBUaGlzIGlzIGEgbWl4ZWQgQy9DKysgaW50ZXJmYWNlIHRoYXQgb2ZmZXJzIGEgZnVsbCBBUEkgdG8gYm90aCBsYW5ndWFnZXMuCisgKiBTZWUgdGhlIHRvcC1sZXZlbCBSRUFETUUgZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgKi8KKworI2lmbmRlZiBVUEJfUkVGQ09VTlRFRF9IXworI2RlZmluZSBVUEJfUkVGQ09VTlRFRF9IXworCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA5IEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBUaGlzIGhlYWRlciBpcyBJTlRFUk5BTC1PTkxZISAgSXRzIGludGVyZmFjZXMgYXJlIG5vdCBwdWJsaWMgb3Igc3RhYmxlIQorICogVGhpcyBmaWxlIGRlZmluZXMgdmVyeSBmYXN0IGludC0+dXBiX3ZhbHVlIChpbnR0YWJsZSkgYW5kIHN0cmluZy0+dXBiX3ZhbHVlCisgKiAoc3RydGFibGUpIGhhc2ggdGFibGVzLgorICoKKyAqIFRoZSB0YWJsZSB1c2VzIGNoYWluZWQgc2NhdHRlciB3aXRoIEJyZW50J3MgdmFyaWF0aW9uIChpbnNwaXJlZCBieSB0aGUgTHVhCisgKiBpbXBsZW1lbnRhdGlvbiBvZiBoYXNoIHRhYmxlcykuICBUaGUgaGFzaCBmdW5jdGlvbiBmb3Igc3RyaW5ncyBpcyBBdXN0aW4KKyAqIEFwcGxlYnkncyAiTXVybXVySGFzaC4iCisgKgorICogVGhlIGludHRhYmxlIHVzZXMgdWludHB0cl90IGFzIGl0cyBrZXksIHdoaWNoIGd1YXJhbnRlZXMgaXQgY2FuIGJlIHVzZWQgdG8KKyAqIHN0b3JlIHBvaW50ZXJzIG9yIGludGVnZXJzIG9mIGF0IGxlYXN0IDMyIGJpdHMgKHVwYiBpc24ndCByZWFsbHkgdXNlZnVsIG9uCisgKiBzeXN0ZW1zIHdoZXJlIHNpemVvZih2b2lkKikgPCA0KS4KKyAqCisgKiBUaGUgdGFibGUgbXVzdCBiZSBob21vZ2Vub3VzIChhbGwgdmFsdWVzIG9mIHRoZSBzYW1lIHR5cGUpLiAgSW4gZGVidWcKKyAqIG1vZGUsIHdlIGNoZWNrIHRoaXMgb24gaW5zZXJ0IGFuZCBsb29rdXAuCisgKi8KKworI2lmbmRlZiBVUEJfVEFCTEVfSF8KKyNkZWZpbmUgVVBCX1RBQkxFX0hfCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMDkgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIFRoaXMgZmlsZSBjb250YWlucyBzaGFyZWQgZGVmaW5pdGlvbnMgdGhhdCBhcmUgd2lkZWx5IHVzZWQgYWNyb3NzIHVwYi4KKyAqCisgKiBUaGlzIGlzIGEgbWl4ZWQgQy9DKysgaW50ZXJmYWNlIHRoYXQgb2ZmZXJzIGEgZnVsbCBBUEkgdG8gYm90aCBsYW5ndWFnZXMuCisgKiBTZWUgdGhlIHRvcC1sZXZlbCBSRUFETUUgZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgKi8KKworI2lmbmRlZiBVUEJfSF8KKyNkZWZpbmUgVVBCX0hfCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRhcmcuaD4KKyNpbmNsdWRlIDxzdGRib29sLmg+CisjaW5jbHVkZSA8c3RkZGVmLmg+CisKKy8vIGlubGluZSBpZiBwb3NzaWJsZSwgZW1pdCBzdGFuZGFsb25lIGNvZGUgaWYgcmVxdWlyZWQuCisjaWZkZWYgX19jcGx1c3BsdXMKKyNkZWZpbmUgVVBCX0lOTElORSBpbmxpbmUKKyNlbHNlCisjZGVmaW5lIFVQQl9JTkxJTkUgc3RhdGljIGlubGluZQorI2VuZGlmCisKKyNpZiBfX1NURENfVkVSU0lPTl9fID49IDE5OTkwMUwKKyNkZWZpbmUgVVBCX0M5OQorI2VuZGlmCisKKyNpZiAoKGRlZmluZWQoX19jcGx1c3BsdXMpICYmIF9fY3BsdXNwbHVzID49IDIwMTEwM0wpIHx8IFwKKyAgICAgIGRlZmluZWQoX19HWFhfRVhQRVJJTUVOVEFMX0NYWDBYX18pKSAmJiAhZGVmaW5lZChVUEJfTk9fQ1hYMTEpCisjZGVmaW5lIFVQQl9DWFgxMQorI2VuZGlmCisKKyNpZmRlZiBVUEJfQ1hYMTEKKyNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KKyNkZWZpbmUgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihjbGFzc19uYW1lKSBcCisgIGNsYXNzX25hbWUoY29uc3QgY2xhc3NfbmFtZSYpID0gZGVsZXRlOyBcCisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IGNsYXNzX25hbWUmKSA9IGRlbGV0ZTsKKyNkZWZpbmUgVVBCX0RJU0FMTE9XX1BPRF9PUFMoY2xhc3NfbmFtZSwgZnVsbF9jbGFzc19uYW1lKSBcCisgIGNsYXNzX25hbWUoKSA9IGRlbGV0ZTsgXAorICB+Y2xhc3NfbmFtZSgpID0gZGVsZXRlOyBcCisgIC8qIEZyaWVuZCBQb2ludGVyPFQ+IHNvIGl0IGNhbiBhY2Nlc3MgYmFzZSBjbGFzcy4gKi8gXAorICBmcmllbmQgY2xhc3MgUG9pbnRlcjxmdWxsX2NsYXNzX25hbWU+OyBcCisgIGZyaWVuZCBjbGFzcyBQb2ludGVyPGNvbnN0IGZ1bGxfY2xhc3NfbmFtZT47IFwKKyAgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihjbGFzc19uYW1lKQorI2RlZmluZSBVUEJfQVNTRVJUX1NURExBWU9VVCh0eXBlKSBcCisgIHN0YXRpY19hc3NlcnQoc3RkOjppc19zdGFuZGFyZF9sYXlvdXQ8dHlwZT46OnZhbHVlLCBcCisgICAgICAgICAgICAgICAgI3R5cGUgIiBtdXN0IGJlIHN0YW5kYXJkIGxheW91dCIpOworI2Vsc2UgIC8vICFkZWZpbmVkKFVQQl9DWFgxMSkKKyNkZWZpbmUgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihjbGFzc19uYW1lKSBcCisgIGNsYXNzX25hbWUoY29uc3QgY2xhc3NfbmFtZSYpOyBcCisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IGNsYXNzX25hbWUmKTsKKyNkZWZpbmUgVVBCX0RJU0FMTE9XX1BPRF9PUFMoY2xhc3NfbmFtZSwgZnVsbF9jbGFzc19uYW1lKSBcCisgIGNsYXNzX25hbWUoKTsgXAorICB+Y2xhc3NfbmFtZSgpOyBcCisgIC8qIEZyaWVuZCBQb2ludGVyPFQ+IHNvIGl0IGNhbiBhY2Nlc3MgYmFzZSBjbGFzcy4gKi8gXAorICBmcmllbmQgY2xhc3MgUG9pbnRlcjxmdWxsX2NsYXNzX25hbWU+OyBcCisgIGZyaWVuZCBjbGFzcyBQb2ludGVyPGNvbnN0IGZ1bGxfY2xhc3NfbmFtZT47IFwKKyAgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihjbGFzc19uYW1lKQorI2RlZmluZSBVUEJfQVNTRVJUX1NURExBWU9VVCh0eXBlKQorI2VuZGlmCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCisKKyNkZWZpbmUgVVBCX1BSSVZBVEVfRk9SX0NQUCBwcml2YXRlOgorI2RlZmluZSBVUEJfREVDTEFSRV9UWVBFKGNwcG5hbWUsIGNuYW1lKSB0eXBlZGVmIGNwcG5hbWUgY25hbWU7CisjZGVmaW5lIFVQQl9CRUdJTl9FWFRFUk5fQyBleHRlcm4gIkMiIHsKKyNkZWZpbmUgVVBCX0VORF9FWFRFUk5fQyB9CisjZGVmaW5lIFVQQl9ERUZJTkVfU1RSVUNUMChjbmFtZSwgbWVtYmVycykgbWVtYmVyczsKKyNkZWZpbmUgVVBCX0RFRklORV9TVFJVQ1QoY25hbWUsIGNiYXNlLCBtZW1iZXJzKSBcCisgcHVibGljOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYmFzZSogYmFzZSgpIHsgcmV0dXJuICZiYXNlXzsgfSAgICAgICAgICAgICAgIFwKKyAgY29uc3QgY2Jhc2UqIGJhc2UoKSBjb25zdCB7IHJldHVybiAmYmFzZV87IH0gICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorIHByaXZhdGU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2Jhc2UgYmFzZV87ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIG1lbWJlcnM7CisjZGVmaW5lIFVQQl9ERUZJTkVfQ0xBU1MwKGNwcG5hbWUsIGNwcG1ldGhvZHMsIG1lbWJlcnMpIFwKKyAgY2xhc3MgY3BwbmFtZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY3BwbWV0aG9kcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIG1lbWJlcnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFVQQl9BU1NFUlRfU1RETEFZT1VUKGNwcG5hbWUpOworI2RlZmluZSBVUEJfREVGSU5FX0NMQVNTMShjcHBuYW1lLCBjcHBiYXNlLCBjcHBtZXRob2RzLCBtZW1iZXJzKSAgIFwKKyAgVVBCX0RFRklORV9DTEFTUzAoY3BwbmFtZSwgY3BwbWV0aG9kcywgbWVtYmVycykgICAgICAgICAgICAgICAgICBcCisgIG5hbWVzcGFjZSB1cGIgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIFBvaW50ZXI8Y3BwbmFtZT4gOiBwdWJsaWMgUG9pbnRlckJhc2U8Y3BwbmFtZSwgY3BwYmFzZT4geyBcCisgICBwdWJsaWM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZXhwbGljaXQgUG9pbnRlcihjcHBuYW1lKiBwdHIpIDogUG9pbnRlckJhc2UocHRyKSB7fSAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIFBvaW50ZXI8Y29uc3QgY3BwbmFtZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICA6IHB1YmxpYyBQb2ludGVyQmFzZTxjb25zdCBjcHBuYW1lLCBjb25zdCBjcHBiYXNlPiB7ICAgICAgICBcCisgICBwdWJsaWM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZXhwbGljaXQgUG9pbnRlcihjb25zdCBjcHBuYW1lKiBwdHIpIDogUG9pbnRlckJhc2UocHRyKSB7fSAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKyNkZWZpbmUgVVBCX0RFRklORV9DTEFTUzIoY3BwbmFtZSwgY3BwYmFzZSwgY3BwYmFzZTIsIGNwcG1ldGhvZHMsIG1lbWJlcnMpICAgIFwKKyAgVVBCX0RFRklORV9DTEFTUzAoY3BwbmFtZSwgVVBCX1FVT1RFKGNwcG1ldGhvZHMpLCBtZW1iZXJzKSAgICAgICAgICAgICAgICAgIFwKKyAgbmFtZXNwYWNlIHVwYiB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIFBvaW50ZXI8Y3BwbmFtZT4gOiBwdWJsaWMgUG9pbnRlckJhc2UyPGNwcG5hbWUsIGNwcGJhc2UsIGNwcGJhc2UyPiB7IFwKKyAgIHB1YmxpYzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGV4cGxpY2l0IFBvaW50ZXIoY3BwbmFtZSogcHRyKSA6IFBvaW50ZXJCYXNlMihwdHIpIHt9ICAgICAgICAgICAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjbGFzcyBQb2ludGVyPGNvbnN0IGNwcG5hbWU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICA6IHB1YmxpYyBQb2ludGVyQmFzZTI8Y29uc3QgY3BwbmFtZSwgY29uc3QgY3BwYmFzZSwgY29uc3QgY3BwYmFzZTI+IHsgIFwKKyAgIHB1YmxpYzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGV4cGxpY2l0IFBvaW50ZXIoY29uc3QgY3BwbmFtZSogcHRyKSA6IFBvaW50ZXJCYXNlMihwdHIpIHt9ICAgICAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCisjZWxzZSAgLy8gIWRlZmluZWQoX19jcGx1c3BsdXMpCisKKyNkZWZpbmUgVVBCX1BSSVZBVEVfRk9SX0NQUAorI2RlZmluZSBVUEJfREVDTEFSRV9UWVBFKGNwcG5hbWUsIGNuYW1lKSBcCisgIHN0cnVjdCBjbmFtZTsgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdHlwZWRlZiBzdHJ1Y3QgY25hbWUgY25hbWU7CisjZGVmaW5lIFVQQl9CRUdJTl9FWFRFUk5fQworI2RlZmluZSBVUEJfRU5EX0VYVEVSTl9DCisjZGVmaW5lIFVQQl9ERUZJTkVfU1RSVUNUMChjbmFtZSwgbWVtYmVycykgXAorICBzdHJ1Y3QgY25hbWUgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBtZW1iZXJzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH07CisjZGVmaW5lIFVQQl9ERUZJTkVfU1RSVUNUKGNuYW1lLCBjYmFzZSwgbWVtYmVycykgXAorICBzdHJ1Y3QgY25hbWUgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjYmFzZSBiYXNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgbWVtYmVyczsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9OworI2RlZmluZSBVUEJfREVGSU5FX0NMQVNTMChjcHBuYW1lLCBjcHBtZXRob2RzLCBtZW1iZXJzKSBtZW1iZXJzCisjZGVmaW5lIFVQQl9ERUZJTkVfQ0xBU1MxKGNwcG5hbWUsIGNwcGJhc2UsIGNwcG1ldGhvZHMsIG1lbWJlcnMpIG1lbWJlcnMKKyNkZWZpbmUgVVBCX0RFRklORV9DTEFTUzIoY3BwbmFtZSwgY3BwYmFzZSwgY3BwYmFzZTIsIGNwcG1ldGhvZHMsIG1lbWJlcnMpIFwKKyAgbWVtYmVycworCisjZW5kaWYgIC8vIGRlZmluZWQoX19jcGx1c3BsdXMpCisKKyNpZmRlZiBfX0dOVUNfXworI2RlZmluZSBVUEJfTk9SRVRVUk4gX19hdHRyaWJ1dGVfXygoX19ub3JldHVybl9fKSkKKyNlbHNlCisjZGVmaW5lIFVQQl9OT1JFVFVSTgorI2VuZGlmCisKKyNkZWZpbmUgVVBCX01BWCh4LCB5KSAoKHgpID4gKHkpID8gKHgpIDogKHkpKQorI2RlZmluZSBVUEJfTUlOKHgsIHkpICgoeCkgPCAoeSkgPyAoeCkgOiAoeSkpCisKKyNkZWZpbmUgVVBCX1VOVVNFRCh2YXIpICh2b2lkKXZhcgorCisvLyBDb2RlIHdpdGggY29tbWFzIGNvbmZ1c2VzIHRoZSBwcmVwcm9jZXNzb3Igd2hlbiBwYXNzZWQgYXMgYXJndW1lbnRzLCB3aGV0aGVyCisvLyBDKysgdHlwZSBuYW1lcyB3aXRoIGNvbW1hcyAoZWcuIEZvbzxpbnQsIGludD4pIG9yIGNvZGUgYmxvY2tzIHRoYXQgZGVjbGFyZQorLy8gdmFyaWFibGVzIChpZS4gaW50IGZvbywgYmFyKS4KKyNkZWZpbmUgVVBCX1FVT1RFKC4uLikgX19WQV9BUkdTX18KKworLy8gRm9yIGFzc2VydGluZyBzb21ldGhpbmcgYWJvdXQgYSB2YXJpYWJsZSB3aGVuIHRoZSB2YXJpYWJsZSBpcyBub3QgdXNlZCBmb3IKKy8vIGFueXRoaW5nIGVsc2UuICBUaGlzIHByZXZlbnRzICJ1bnVzZWQgdmFyaWFibGUiIHdhcm5pbmdzIHdoZW4gY29tcGlsaW5nIGluCisvLyBkZWJ1ZyBtb2RlLgorI2RlZmluZSBVUEJfQVNTRVJUX1ZBUih2YXIsIHByZWRpY2F0ZSkgVVBCX1VOVVNFRCh2YXIpOyBhc3NlcnQocHJlZGljYXRlKQorCisvLyBHZW5lcmljIGZ1bmN0aW9uIHR5cGUuCit0eXBlZGVmIHZvaWQgdXBiX2Z1bmMoKTsKKworLyogQ2FzdHMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gVXBjYXN0cyBmb3IgQy4gIEZvciBkb3duY2FzdHMgc2VlIHRoZSBkZWZpbml0aW9ucyBvZiB0aGUgc3VidHlwZXMuCisjZGVmaW5lIFVQQl9VUENBU1Qob2JqKSAoJihvYmopLT5iYXNlKQorI2RlZmluZSBVUEJfVVBDQVNUMihvYmopIFVQQl9VUENBU1QoVVBCX1VQQ0FTVChvYmopKQorCisjaWZkZWYgX19jcGx1c3BsdXMKKworLy8gRG93bmNhc3RzIGZvciBDKysuICBXZSBjYW4ndCB1c2UgQysrIGluaGVyaXRhbmNlIGRpcmVjdGx5IGFuZCBtYWludGFpbgorLy8gY29tcGF0aWJpbGl0eSB3aXRoIEMuICBTbyBvdXIgaW5oZXJpdGFuY2UgaXMgdW5kZWNsYXJlZCBpbiBDKysuCisvLyBTcGVjaWFsaXphdGlvbnMgb2YgdGhlc2UgY2FzdGluZyBmdW5jdGlvbnMgYXJlIGRlZmluZWQgZm9yIGFwcHJvcHJpYXRlIHR5cGUKKy8vIHBhaXJzLCBhbmQgcGVyZm9ybSB0aGUgbmVjZXNzYXJ5IGNoZWNrcy4KKy8vCisvLyBFeGFtcGxlOgorLy8gICB1cGI6OkRlZiogZGVmID0gPC4uLj47CisvLyAgIHVwYjo6TWVzc2FnZURlZiogPSB1cGI6OmR5bl9jYXN0PHVwYjo6TWVzc2FnZURlZio+KGRlZik7CisKK25hbWVzcGFjZSB1cGIgeworCisvLyBDYXN0cyB0byBhIGRpcmVjdCBzdWJjbGFzcy4gIFRoZSBjYWxsZXIgbXVzdCBrbm93IHRoYXQgY2FzdCBpcyBjb3JyZWN0OyBhbgorLy8gaW5jb3JyZWN0IGNhc3Qgd2lsbCB0aHJvdyBhbiBhc3NlcnRpb24gZmFpbHVyZSBpbiBkZWJ1ZyBtb2RlLgordGVtcGxhdGU8Y2xhc3MgVG8sIGNsYXNzIEZyb20+IFRvIGRvd25fY2FzdChGcm9tKiBmKTsKKworLy8gQ2FzdHMgdG8gYSBkaXJlY3Qgc3ViY2xhc3MuICBJZiB0aGUgY2xhc3MgZG9lcyBub3QgYWN0dWFsbHkgbWF0Y2ggdGhlIGdpdmVuCisvLyBzdWJ0eXBlLCByZXR1cm5zIE5VTEwuCit0ZW1wbGF0ZTxjbGFzcyBUbywgY2xhc3MgRnJvbT4gVG8gZHluX2Nhc3QoRnJvbSogZik7CisKKy8vIFBvaW50ZXI8VD4gaXMgYSBzaW1wbGUgd3JhcHBlciBhcm91bmQgYSBUKi4gIEl0IGlzIG9ubHkgY29uc3RydWN0ZWQgZm9yCisvLyB1cGNhc3QoKSBiZWxvdywgYW5kIGl0cyBzb2xlIHB1cnBvc2UgaXMgdG8gYmUgaW1wbGljaXRseSBjb252ZXJ0YWJsZSB0byBUKiBvcgorLy8gcG9pbnRlcnMgdG8gYmFzZSBjbGFzc2VzLCBqdXN0IGFzIGEgcG9pbnRlciB3b3VsZCBiZSBpbiByZWd1bGFyIEMrKyBpZiB0aGUKKy8vIGluaGVyaXRhbmNlIHdlcmUgZGlyZWN0bHkgZXhwcmVzc2VkIGFzIEMrKyBpbmhlcml0YW5jZS4KK3RlbXBsYXRlIDxjbGFzcyBUPiBjbGFzcyBQb2ludGVyOworCisvLyBDYXN0cyB0byBhbnkgYmFzZSBjbGFzcywgb3IgdGhlIHR5cGUgaXRzZWxmIChpZS4gY2FuIGJlIGEgbm8tb3ApLgordGVtcGxhdGUgPGNsYXNzIFQ+IGlubGluZSBQb2ludGVyPFQ+IHVwY2FzdChUICpmKSB7IHJldHVybiBQb2ludGVyPFQ+KGYpOyB9CisKK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBCYXNlPgorY2xhc3MgUG9pbnRlckJhc2UgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUG9pbnRlckJhc2UoVCogcHRyKSA6IHB0cl8ocHRyKSB7fQorICBvcGVyYXRvciBUKigpIHsgcmV0dXJuIHB0cl87IH0KKyAgb3BlcmF0b3IgQmFzZSooKSB7IHJldHVybiBwdHJfLT5iYXNlKCk7IH0KKworIHByaXZhdGU6CisgIFQqIHB0cl87Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgQmFzZSwgY2xhc3MgQmFzZTI+CitjbGFzcyBQb2ludGVyQmFzZTIgOiBwdWJsaWMgUG9pbnRlckJhc2U8VCwgQmFzZT4geworIHB1YmxpYzoKKyAgZXhwbGljaXQgUG9pbnRlckJhc2UyKFQqIHB0cikgOiBQb2ludGVyQmFzZTxULCBCYXNlPihwdHIpIHt9CisgIG9wZXJhdG9yIEJhc2UyKigpIHsgcmV0dXJuIFBvaW50ZXI8QmFzZT4oKnRoaXMpOyB9Cit9OworCit9CisKKyNlbmRpZgorCisKKy8qIHVwYjo6cmVmZmVkX3B0ciAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNpZmRlZiBfX2NwbHVzcGx1cworCisjaW5jbHVkZSA8YWxnb3JpdGhtPiAgLy8gRm9yIHN0ZDo6c3dhcCgpLgorCituYW1lc3BhY2UgdXBiIHsKKworLy8gUHJvdmlkZXMgUkFJSSBzZW1hbnRpY3MgZm9yIHVwYiByZWZjb3VudGVkIG9iamVjdHMuICBFYWNoIHJlZmZlZF9wdHIgb3ducyBhCisvLyByZWYgb24gd2hhdGV2ZXIgb2JqZWN0IGl0IHBvaW50cyB0byAoaWYgYW55KS4KK3RlbXBsYXRlIDxjbGFzcyBUPiBjbGFzcyByZWZmZWRfcHRyIHsKKyBwdWJsaWM6CisgIHJlZmZlZF9wdHIoKSA6IHB0cl8oTlVMTCkge30KKworICAvLyBJZiByZWZfZG9ub3IgaXMgTlVMTCwgdGFrZXMgYSBuZXcgcmVmLCBvdGhlcndpc2UgYWRvcHRzIGZyb20gcmVmX2Rvbm9yLgorICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KKyAgcmVmZmVkX3B0cihVKiB2YWwsIGNvbnN0IHZvaWQqIHJlZl9kb25vciA9IE5VTEwpCisgICAgICA6IHB0cl8odXBiOjp1cGNhc3QodmFsKSkgeworICAgIGlmIChyZWZfZG9ub3IpIHsKKyAgICAgIGFzc2VydChwdHJfKTsKKyAgICAgIHB0cl8tPkRvbmF0ZVJlZihyZWZfZG9ub3IsIHRoaXMpOworICAgIH0gZWxzZSBpZiAocHRyXykgeworICAgICAgcHRyXy0+UmVmKHRoaXMpOworICAgIH0KKyAgfQorCisgIHRlbXBsYXRlIDxjbGFzcyBVPgorICByZWZmZWRfcHRyKGNvbnN0IHJlZmZlZF9wdHI8VT4mIG90aGVyKQorICAgICAgOiBwdHJfKHVwYjo6dXBjYXN0KG90aGVyLmdldCgpKSkgeworICAgIGlmIChwdHJfKSBwdHJfLT5SZWYodGhpcyk7CisgIH0KKworICB+cmVmZmVkX3B0cigpIHsgaWYgKHB0cl8pIHB0cl8tPlVucmVmKHRoaXMpOyB9CisKKyAgdGVtcGxhdGUgPGNsYXNzIFU+CisgIHJlZmZlZF9wdHImIG9wZXJhdG9yPShjb25zdCByZWZmZWRfcHRyPFU+JiBvdGhlcikgeworICAgIHJlc2V0KG90aGVyLmdldCgpKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICByZWZmZWRfcHRyJiBvcGVyYXRvcj0oY29uc3QgcmVmZmVkX3B0ciYgb3RoZXIpIHsKKyAgICByZXNldChvdGhlci5nZXQoKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgLy8gVE9ETyhoYWJlcm1hbik6IGFkZCBDKysxMSBtb3ZlIGNvbnN0cnVjdGlvbi9hc3NpZ25tZW50IGZvciBncmVhdGVyCisgIC8vIGVmZmljaWVuY3kuCisKKyAgdm9pZCBzd2FwKHJlZmZlZF9wdHImIG90aGVyKSB7CisgICAgaWYgKHB0cl8gPT0gb3RoZXIucHRyXykgeworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChwdHJfKSBwdHJfLT5Eb25hdGVSZWYodGhpcywgJm90aGVyKTsKKyAgICBpZiAob3RoZXIucHRyXykgb3RoZXIucHRyXy0+RG9uYXRlUmVmKCZvdGhlciwgdGhpcyk7CisgICAgc3RkOjpzd2FwKHB0cl8sIG90aGVyLnB0cl8pOworICB9CisKKyAgVCYgb3BlcmF0b3IqKCkgY29uc3QgeworICAgIGFzc2VydChwdHJfKTsKKyAgICByZXR1cm4gKnB0cl87CisgIH0KKworICBUKiBvcGVyYXRvci0+KCkgY29uc3QgeworICAgIGFzc2VydChwdHJfKTsKKyAgICByZXR1cm4gcHRyXzsKKyAgfQorCisgIFQqIGdldCgpIGNvbnN0IHsgcmV0dXJuIHB0cl87IH0KKworICAvLyBJZiByZWZfZG9ub3IgaXMgTlVMTCwgdGFrZXMgYSBuZXcgcmVmLCBvdGhlcndpc2UgYWRvcHRzIGZyb20gcmVmX2Rvbm9yLgorICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KKyAgdm9pZCByZXNldChVKiBwdHIgPSBOVUxMLCBjb25zdCB2b2lkKiByZWZfZG9ub3IgPSBOVUxMKSB7CisgICAgcmVmZmVkX3B0cihwdHIsIHJlZl9kb25vcikuc3dhcCgqdGhpcyk7CisgIH0KKworICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KKyAgcmVmZmVkX3B0cjxVPiBkb3duX2Nhc3QoKSB7CisgICAgcmV0dXJuIHJlZmZlZF9wdHI8VT4odXBiOjpkb3duX2Nhc3Q8VSo+KGdldCgpKSk7CisgIH0KKworICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KKyAgcmVmZmVkX3B0cjxVPiBkeW5fY2FzdCgpIHsKKyAgICByZXR1cm4gcmVmZmVkX3B0cjxVPih1cGI6OmR5bl9jYXN0PFUqPihnZXQoKSkpOworICB9CisKKyAgLy8gUGxhaW4gcmVsZWFzZSgpIGlzIHVuc2FmZTsgaWYgd2Ugd2VyZSB0aGUgb25seSBvd25lciwgaXQgd291bGQgbGVhayB0aGUKKyAgLy8gb2JqZWN0LiAgSW5zdGVhZCB3ZSBwcm92aWRlIHRoaXM6CisgIFQqIFJlbGVhc2VUbyhjb25zdCB2b2lkKiBuZXdfb3duZXIpIHsKKyAgICBUKiByZXQgPSBOVUxMOworICAgIHB0cl8tPkRvbmF0ZVJlZih0aGlzLCBuZXdfb3duZXIpOworICAgIHN0ZDo6c3dhcChyZXQsIHB0cl8pOworICAgIHJldHVybiByZXQ7CisgIH0KKworIHByaXZhdGU6CisgIFQqIHB0cl87Cit9OworCit9ICAvLyBuYW1lc3BhY2UgdXBiCisKKyNlbmRpZiAgLy8gX19jcGx1c3BsdXMKKworCisvKiB1cGI6OlN0YXR1cyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjaWZkZWYgX19jcGx1c3BsdXMKK25hbWVzcGFjZSB1cGIgeworY2xhc3MgRXJyb3JTcGFjZTsKK2NsYXNzIFN0YXR1czsKK30KKyNlbmRpZgorCitVUEJfREVDTEFSRV9UWVBFKHVwYjo6RXJyb3JTcGFjZSwgdXBiX2Vycm9yc3BhY2UpOworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OlN0YXR1cywgdXBiX3N0YXR1cyk7CisKKy8vIFRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbiBlcnJvciBtZXNzYWdlIGJlZm9yZSBpdCB3aWxsIGdldCB0cnVuY2F0ZWQuCisjZGVmaW5lIFVQQl9TVEFUVVNfTUFYX01FU1NBR0UgMTI4CisKKy8vIEFuIGVycm9yIGNhbGxiYWNrIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcmVwb3J0IGVycm9ycyBmcm9tIHNvbWUgY29tcG9uZW50LgorLy8gVGhlIGZ1bmN0aW9uIGNhbiByZXR1cm4gInRydWUiIHRvIGluZGljYXRlIHRoYXQgdGhlIGNvbXBvbmVudCBzaG91bGQgdHJ5CisvLyB0byByZWNvdmVyIGFuZCBwcm9jZWVkLCBidXQgdGhpcyBpcyBub3QgYWx3YXlzIHBvc3NpYmxlLgordHlwZWRlZiBib29sIHVwYl9lcnJjYl90KHZvaWQgKmNsb3N1cmUsIGNvbnN0IHVwYl9zdGF0dXMqIHN0YXR1cyk7CisKK1VQQl9ERUZJTkVfQ0xBU1MwKHVwYjo6RXJyb3JTcGFjZSwKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfZXJyb3JzcGFjZSwKKyAgY29uc3QgY2hhciAqbmFtZTsKKyAgLy8gU2hvdWxkIHRoZSBlcnJvciBtZXNzYWdlIGluIHRoZSBzdGF0dXMgb2JqZWN0IGFjY29yZGluZyB0byB0aGlzIGNvZGUuCisgIHZvaWQgKCpzZXRfbWVzc2FnZSkodXBiX3N0YXR1cyogc3RhdHVzLCBpbnQgY29kZSk7CispKTsKKworLy8gT2JqZWN0IHJlcHJlc2VudGluZyBhIHN1Y2Nlc3Mgb3IgZmFpbHVyZSBzdGF0dXMuCisvLyBJdCBvd25zIG5vIHJlc291cmNlcyBhbmQgYWxsb2NhdGVzIG5vIG1lbW9yeSwgc28gaXQgc2hvdWxkIHdvcmsKKy8vIGV2ZW4gaW4gT09NIHNpdHVhdGlvbnMuCitVUEJfREVGSU5FX0NMQVNTMCh1cGI6OlN0YXR1cywKKyBwdWJsaWM6CisgIFN0YXR1cygpOworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBpcyBubyBlcnJvci4KKyAgYm9vbCBvaygpIGNvbnN0OworCisgIC8vIE9wdGlvbmFsIGVycm9yIHNwYWNlIGFuZCBjb2RlLCB1c2VmdWwgaWYgdGhlIGNhbGxlciB3YW50cyB0bworICAvLyBwcm9ncmFtbWF0aWNhbGx5IGNoZWNrIHRoZSBzcGVjaWZpYyBraW5kIG9mIGVycm9yLgorICBFcnJvclNwYWNlKiBlcnJvcl9zcGFjZSgpOworICBpbnQgY29kZSgpIGNvbnN0OworCisgIGNvbnN0IGNoYXIgKmVycm9yX21lc3NhZ2UoKSBjb25zdDsKKworICAvLyBUaGUgZXJyb3IgbWVzc2FnZSB3aWxsIGJlIHRydW5jYXRlZCBpZiBpdCBpcyBsb25nZXIgdGhhbgorICAvLyBVUEJfU1RBVFVTX01BWF9NRVNTQUdFLTQuCisgIHZvaWQgU2V0RXJyb3JNZXNzYWdlKGNvbnN0IGNoYXIqIG1zZyk7CisgIHZvaWQgU2V0Rm9ybWF0dGVkRXJyb3JNZXNzYWdlKGNvbnN0IGNoYXIqIGZtdCwgLi4uKTsKKworICAvLyBJZiB0aGVyZSBpcyBubyBlcnJvciBtZXNzYWdlIGFscmVhZHksIHRoaXMgd2lsbCB1c2UgdGhlIEVycm9yU3BhY2UgdG8KKyAgLy8gcG9wdWxhdGUgdGhlIGVycm9yIG1lc3NhZ2UgZm9yIHRoaXMgY29kZS4gIFRoZSBjYWxsZXIgY2FuIHN0aWxsIGNhbGwKKyAgLy8gU2V0RXJyb3JNZXNzYWdlKCkgdG8gZ2l2ZSBhIG1vcmUgc3BlY2lmaWMgbWVzc2FnZS4KKyAgdm9pZCBTZXRFcnJvckNvZGUoRXJyb3JTcGFjZSogc3BhY2UsIGludCBjb2RlKTsKKworICAvLyBSZXNldHMgdGhlIHN0YXR1cyB0byBhIHN1Y2Nlc3NmdWwgc3RhdGUgd2l0aCBubyBtZXNzYWdlLgorICB2b2lkIENsZWFyKCk7CisKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBTdGF0dXMmIG90aGVyKTsKKworIHByaXZhdGU6CisgIFVQQl9ESVNBTExPV19DT1BZX0FORF9BU1NJR04oU3RhdHVzKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfc3RhdHVzLAorICBib29sIG9rXzsKKworICAvLyBTcGVjaWZpYyBzdGF0dXMgY29kZSBkZWZpbmVkIGJ5IHNvbWUgZXJyb3Igc3BhY2UgKG9wdGlvbmFsKS4KKyAgaW50IGNvZGVfOworICB1cGJfZXJyb3JzcGFjZSAqZXJyb3Jfc3BhY2VfOworCisgIC8vIEVycm9yIG1lc3NhZ2U7IE5VTEwtdGVybWluYXRlZC4KKyAgY2hhciBtc2dbVVBCX1NUQVRVU19NQVhfTUVTU0FHRV07CispKTsKKworI2RlZmluZSBVUEJfU1RBVFVTX0lOSVQge3RydWUsIDAsIE5VTEwsIHswfX0KKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvLyBUaGUgcmV0dXJuZWQgc3RyaW5nIGlzIGludmFsaWRhdGVkIGJ5IGFueSBvdGhlciBjYWxsIGludG8gdGhlIHN0YXR1cy4KK2NvbnN0IGNoYXIgKnVwYl9zdGF0dXNfZXJybXNnKGNvbnN0IHVwYl9zdGF0dXMgKnN0YXR1cyk7Citib29sIHVwYl9vayhjb25zdCB1cGJfc3RhdHVzICpzdGF0dXMpOwordXBiX2Vycm9yc3BhY2UgKnVwYl9zdGF0dXNfZXJyc3BhY2UoY29uc3QgdXBiX3N0YXR1cyAqc3RhdHVzKTsKK2ludCB1cGJfc3RhdHVzX2VycmNvZGUoY29uc3QgdXBiX3N0YXR1cyAqc3RhdHVzKTsKKworLy8gQW55IG9mIHRoZSBmdW5jdGlvbnMgdGhhdCB3cml0ZSB0byBhIHN0YXR1cyBvYmplY3QgYWxsb3cgc3RhdHVzIHRvIGJlIE5VTEwsCisvLyB0byBzdXBwb3J0IHVzZSBjYXNlcyB3aGVyZSB0aGUgZnVuY3Rpb24ncyBjYWxsZXIgZG9lcyBub3QgY2FyZSBhYm91dCB0aGUKKy8vIHN0YXR1cyBtZXNzYWdlLgordm9pZCB1cGJfc3RhdHVzX2NsZWFyKHVwYl9zdGF0dXMgKnN0YXR1cyk7Cit2b2lkIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHVwYl9zdGF0dXMgKnN0YXR1cywgY29uc3QgY2hhciAqbXNnKTsKK3ZvaWQgdXBiX3N0YXR1c19zZXRlcnJmKHVwYl9zdGF0dXMgKnN0YXR1cywgY29uc3QgY2hhciAqZm10LCAuLi4pOwordm9pZCB1cGJfc3RhdHVzX3ZzZXRlcnJmKHVwYl9zdGF0dXMgKnN0YXR1cywgY29uc3QgY2hhciAqZm10LCB2YV9saXN0IGFyZ3MpOwordm9pZCB1cGJfc3RhdHVzX3NldGVycmNvZGUodXBiX3N0YXR1cyAqc3RhdHVzLCB1cGJfZXJyb3JzcGFjZSAqc3BhY2UsIGludCBjb2RlKTsKK3ZvaWQgdXBiX3N0YXR1c19jb3B5KHVwYl9zdGF0dXMgKnRvLCBjb25zdCB1cGJfc3RhdHVzICpmcm9tKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9ICAvLyBleHRlcm4gIkMiCisKK25hbWVzcGFjZSB1cGIgeworCisvLyBDKysgV3JhcHBlcnMKK2lubGluZSBTdGF0dXM6OlN0YXR1cygpIHsgQ2xlYXIoKTsgfQoraW5saW5lIGJvb2wgU3RhdHVzOjpvaygpIGNvbnN0IHsgcmV0dXJuIHVwYl9vayh0aGlzKTsgfQoraW5saW5lIGNvbnN0IGNoYXIqIFN0YXR1czo6ZXJyb3JfbWVzc2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9zdGF0dXNfZXJybXNnKHRoaXMpOworfQoraW5saW5lIHZvaWQgU3RhdHVzOjpTZXRFcnJvck1lc3NhZ2UoY29uc3QgY2hhciogbXNnKSB7CisgIHVwYl9zdGF0dXNfc2V0ZXJybXNnKHRoaXMsIG1zZyk7Cit9CitpbmxpbmUgdm9pZCBTdGF0dXM6OlNldEZvcm1hdHRlZEVycm9yTWVzc2FnZShjb25zdCBjaGFyKiBmbXQsIC4uLikgeworICB2YV9saXN0IGFyZ3M7CisgIHZhX3N0YXJ0KGFyZ3MsIGZtdCk7CisgIHVwYl9zdGF0dXNfdnNldGVycmYodGhpcywgZm10LCBhcmdzKTsKKyAgdmFfZW5kKGFyZ3MpOworfQoraW5saW5lIHZvaWQgU3RhdHVzOjpTZXRFcnJvckNvZGUoRXJyb3JTcGFjZSogc3BhY2UsIGludCBjb2RlKSB7CisgIHVwYl9zdGF0dXNfc2V0ZXJyY29kZSh0aGlzLCBzcGFjZSwgY29kZSk7Cit9CitpbmxpbmUgdm9pZCBTdGF0dXM6OkNsZWFyKCkgeyB1cGJfc3RhdHVzX2NsZWFyKHRoaXMpOyB9CitpbmxpbmUgdm9pZCBTdGF0dXM6OkNvcHlGcm9tKGNvbnN0IFN0YXR1cyYgb3RoZXIpIHsKKyAgdXBiX3N0YXR1c19jb3B5KHRoaXMsICZvdGhlcik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSB1cGIKKworI2VuZGlmCisKKyNlbmRpZiAgLyogVVBCX0hfICovCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworCisvKiB1cGJfdmFsdWUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvLyBBIHRhZ2dlZCB1bmlvbiAoc3RvcmVkIHVudGFnZ2VkIGluc2lkZSB0aGUgdGFibGUpIHNvIHRoYXQgd2UgY2FuIGNoZWNrIHRoYXQKKy8vIGNsaWVudHMgY2FsbGluZyB0YWJsZSBhY2Nlc3NvcnMgYXJlIGNvcnJlY3RseSB0eXBlZCB3aXRob3V0IGhhdmluZyB0byBoYXZlCisvLyBhbiBleHBsb3Npb24gb2YgYWNjZXNzb3JzLgordHlwZWRlZiBlbnVtIHsKKyAgVVBCX0NUWVBFX0lOVDMyICAgID0gMSwKKyAgVVBCX0NUWVBFX0lOVDY0ICAgID0gMiwKKyAgVVBCX0NUWVBFX1VJTlQzMiAgID0gMywKKyAgVVBCX0NUWVBFX1VJTlQ2NCAgID0gNCwKKyAgVVBCX0NUWVBFX0JPT0wgICAgID0gNSwKKyAgVVBCX0NUWVBFX0NTVFIgICAgID0gNiwKKyAgVVBCX0NUWVBFX1BUUiAgICAgID0gNywKKyAgVVBCX0NUWVBFX0NPTlNUUFRSID0gOCwKKyAgVVBCX0NUWVBFX0ZQVFIgICAgID0gOSwKK30gdXBiX2N0eXBlX3Q7CisKK3R5cGVkZWYgdW5pb24geworICBpbnQzMl90ICBpbnQzMjsKKyAgaW50NjRfdCAgaW50NjQ7CisgIHVpbnQ2NF90IHVpbnQ2NDsKKyAgdWludDMyX3QgdWludDMyOworICBib29sICAgICBfYm9vbDsKKyAgY2hhciAgICAgKmNzdHI7CisgIHZvaWQgICAgICpwdHI7CisgIGNvbnN0IHZvaWQgKmNvbnN0cHRyOworICB1cGJfZnVuYyAqZnB0cjsKK30gX3VwYl92YWx1ZTsKKwordHlwZWRlZiBzdHJ1Y3QgeworICBfdXBiX3ZhbHVlIHZhbDsKKyNpZm5kZWYgTkRFQlVHCisgIC8vIEluIGRlYnVnIG1vZGUgd2UgY2FycnkgdGhlIHZhbHVlIHR5cGUgYXJvdW5kIGFsc28gc28gd2UgY2FuIGNoZWNrIGFjY2Vzc2VzCisgIC8vIHRvIGJlIHN1cmUgdGhlIHJpZ2h0IG1lbWJlciBpcyBiZWluZyByZWFkLgorICB1cGJfY3R5cGVfdCBjdHlwZTsKKyNlbmRpZgorfSB1cGJfdmFsdWU7CisKKyNpZmRlZiBVUEJfQzk5CisjZGVmaW5lIFVQQl9WQUxVRV9JTklUKHYsIG1lbWJlcikgey5tZW1iZXIgPSB2fQorI2VuZGlmCisjZGVmaW5lIFVQQl9fVkFMVUVfSU5JVF9OT05FICAgICAgVVBCX1ZBTFVFX0lOSVQoTlVMTCwgcHRyKQorCisjaWZkZWYgTkRFQlVHCisjZGVmaW5lIFNFVF9UWVBFKGRlc3QsIHZhbCkgICAgICBVUEJfVU5VU0VEKHZhbCkKKyNkZWZpbmUgVVBCX1ZBTFVFX0lOSVRfTk9ORSAgICAgIHtVUEJfX1ZBTFVFX0lOSVRfTk9ORX0KKyNlbHNlCisjZGVmaW5lIFNFVF9UWVBFKGRlc3QsIHZhbCkgZGVzdCA9IHZhbAorLy8gTm9uLWV4aXN0ZW50IHR5cGUsIGFsbCByZWFkcyB3aWxsIGZhaWwuCisjZGVmaW5lIFVQQl9WQUxVRV9JTklUX05PTkUgICAgICB7VVBCX19WQUxVRV9JTklUX05PTkUsIC0xfQorI2VuZGlmCisKKyNkZWZpbmUgVVBCX1ZBTFVFX0lOSVRfSU5UMzIodikgIFVQQl9WQUxVRV9JTklUKHYsIGludDMyKQorI2RlZmluZSBVUEJfVkFMVUVfSU5JVF9JTlQ2NCh2KSAgVVBCX1ZBTFVFX0lOSVQodiwgaW50NjQpCisjZGVmaW5lIFVQQl9WQUxVRV9JTklUX1VJTlQzMih2KSBVUEJfVkFMVUVfSU5JVCh2LCB1aW50MzIpCisjZGVmaW5lIFVQQl9WQUxVRV9JTklUX1VJTlQ2NCh2KSBVUEJfVkFMVUVfSU5JVCh2LCB1aW50NjQpCisjZGVmaW5lIFVQQl9WQUxVRV9JTklUX0JPT0wodikgICBVUEJfVkFMVUVfSU5JVCh2LCBfYm9vbCkKKyNkZWZpbmUgVVBCX1ZBTFVFX0lOSVRfQ1NUUih2KSAgIFVQQl9WQUxVRV9JTklUKHYsIGNzdHIpCisjZGVmaW5lIFVQQl9WQUxVRV9JTklUX1BUUih2KSAgICBVUEJfVkFMVUVfSU5JVCh2LCBwdHIpCisjZGVmaW5lIFVQQl9WQUxVRV9JTklUX0NPTlNUUFRSKHYpIFVQQl9WQUxVRV9JTklUKHYsIGNvbnN0cHRyKQorI2RlZmluZSBVUEJfVkFMVUVfSU5JVF9GUFRSKHYpICAgVVBCX1ZBTFVFX0lOSVQodiwgZnB0cikKKworLy8gTGlrZSBzdHJkdXAoKSwgd2hpY2ggaXNuJ3QgYWx3YXlzIGF2YWlsYWJsZSBzaW5jZSBpdCdzIG5vdCBBTlNJIEMuCitjaGFyICp1cGJfc3RyZHVwKGNvbnN0IGNoYXIgKnMpOworLy8gVmFyaWFudCB0aGF0IHdvcmtzIHdpdGggYSBsZW5ndGgtZGVsaW1pdGVkIHJhdGhlciB0aGFuIE5VTEwtZGVsaW1pdGVkIHN0cmluZywKKy8vIGFzIHN1cHBvcnRlZCBieSBzdHJ0YWJsZS4KK2NoYXIgKnVwYl9zdHJkdXAyKGNvbnN0IGNoYXIgKnMsIHNpemVfdCBsZW4pOworCitVUEJfSU5MSU5FIHZvaWQgX3VwYl92YWx1ZV9zZXR2YWwodXBiX3ZhbHVlICp2LCBfdXBiX3ZhbHVlIHZhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfY3R5cGVfdCBjdHlwZSkgeworICB2LT52YWwgPSB2YWw7CisgIFNFVF9UWVBFKHYtPmN0eXBlLCBjdHlwZSk7Cit9CisKK1VQQl9JTkxJTkUgdXBiX3ZhbHVlIF91cGJfdmFsdWVfdmFsKF91cGJfdmFsdWUgdmFsLCB1cGJfY3R5cGVfdCBjdHlwZSkgeworICB1cGJfdmFsdWUgcmV0OworICBfdXBiX3ZhbHVlX3NldHZhbCgmcmV0LCB2YWwsIGN0eXBlKTsKKyAgcmV0dXJuIHJldDsKK30KKworLy8gRm9yIGVhY2ggdmFsdWUgY3R5cGUsIGRlZmluZSB0aGUgZm9sbG93aW5nIHNldCBvZiBmdW5jdGlvbnM6CisvLworLy8gLy8gR2V0L3NldCBhbiBpbnQzMiBmcm9tIGEgdXBiX3ZhbHVlLgorLy8gaW50MzJfdCB1cGJfdmFsdWVfZ2V0aW50MzIodXBiX3ZhbHVlIHZhbCk7CisvLyB2b2lkIHVwYl92YWx1ZV9zZXRpbnQzMih1cGJfdmFsdWUgKnZhbCwgaW50MzJfdCBjdmFsKTsKKy8vCisvLyAvLyBDb25zdHJ1Y3QgYSBuZXcgdXBiX3ZhbHVlIGZyb20gYW4gaW50MzIuCisvLyB1cGJfdmFsdWUgdXBiX3ZhbHVlX2ludDMyKGludDMyX3QgdmFsKTsKKyNkZWZpbmUgRlVOQ1MobmFtZSwgbWVtYmVybmFtZSwgdHlwZV90LCBwcm90b190eXBlKSBcCisgIFVQQl9JTkxJTkUgdm9pZCB1cGJfdmFsdWVfc2V0ICMjIG5hbWUodXBiX3ZhbHVlICp2YWwsIHR5cGVfdCBjdmFsKSB7IFwKKyAgICB2YWwtPnZhbC51aW50NjQgPSAwOyBcCisgICAgU0VUX1RZUEUodmFsLT5jdHlwZSwgcHJvdG9fdHlwZSk7IFwKKyAgICB2YWwtPnZhbC5tZW1iZXJuYW1lID0gY3ZhbDsgXAorICB9IFwKKyAgVVBCX0lOTElORSB1cGJfdmFsdWUgdXBiX3ZhbHVlXyAjIyBuYW1lKHR5cGVfdCB2YWwpIHsgXAorICAgIHVwYl92YWx1ZSByZXQ7IFwKKyAgICB1cGJfdmFsdWVfc2V0ICMjIG5hbWUoJnJldCwgdmFsKTsgXAorICAgIHJldHVybiByZXQ7IFwKKyAgfSBcCisgIFVQQl9JTkxJTkUgdHlwZV90IHVwYl92YWx1ZV9nZXQgIyMgbmFtZSh1cGJfdmFsdWUgdmFsKSB7IFwKKyAgICBhc3NlcnQodmFsLmN0eXBlID09IHByb3RvX3R5cGUpOyBcCisgICAgcmV0dXJuIHZhbC52YWwubWVtYmVybmFtZTsgXAorICB9CisKK0ZVTkNTKGludDMyLCAgICBpbnQzMiwgICAgICAgIGludDMyX3QsICAgICAgVVBCX0NUWVBFX0lOVDMyKTsKK0ZVTkNTKGludDY0LCAgICBpbnQ2NCwgICAgICAgIGludDY0X3QsICAgICAgVVBCX0NUWVBFX0lOVDY0KTsKK0ZVTkNTKHVpbnQzMiwgICB1aW50MzIsICAgICAgIHVpbnQzMl90LCAgICAgVVBCX0NUWVBFX1VJTlQzMik7CitGVU5DUyh1aW50NjQsICAgdWludDY0LCAgICAgICB1aW50NjRfdCwgICAgIFVQQl9DVFlQRV9VSU5UNjQpOworRlVOQ1MoYm9vbCwgICAgIF9ib29sLCAgICAgICAgYm9vbCwgICAgICAgICBVUEJfQ1RZUEVfQk9PTCk7CitGVU5DUyhjc3RyLCAgICAgY3N0ciwgICAgICAgICBjaGFyKiwgICAgICAgIFVQQl9DVFlQRV9DU1RSKTsKK0ZVTkNTKHB0ciwgICAgICBwdHIsICAgICAgICAgIHZvaWQqLCAgICAgICAgVVBCX0NUWVBFX1BUUik7CitGVU5DUyhjb25zdHB0ciwgY29uc3RwdHIsICAgICBjb25zdCB2b2lkKiwgIFVQQl9DVFlQRV9DT05TVFBUUik7CitGVU5DUyhmcHRyLCAgICAgZnB0ciwgICAgICAgICB1cGJfZnVuYyosICAgIFVQQl9DVFlQRV9GUFRSKTsKKworI3VuZGVmIEZVTkNTCisKKworLyogdXBiX3RhYmxlICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiB1bmlvbiB7CisgIHVpbnRwdHJfdCBudW07CisgIHN0cnVjdCB7CisgICAgLy8gV2Ugb3duIHRoaXMuIE5VTEwtdGVybWluYXRlZCBidXQgbWF5IGFsc28gY29udGFpbiBiaW5hcnkgZGF0YTsgc2VlCisgICAgLy8gZXhwbGljaXQgbGVuZ3RoIGJlbG93LgorICAgIC8vIFRPRE86IG1vdmUgdGhlIGxlbmd0aCB0byB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZyBpbiBvcmRlciB0byByZWR1Y2UKKyAgICAvLyB0YWJrZXkncyBzaXplICh0byBvbmUgbWFjaGluZSB3b3JkKSBpbiBhIHdheSB0aGF0IHN1cHBvcnRzIHN0YXRpYworICAgIC8vIGluaXRpYWxpemF0aW9uLgorICAgIGNvbnN0IGNoYXIgKnN0cjsKKyAgICBzaXplX3QgbGVuZ3RoOworICB9IHM7Cit9IHVwYl90YWJrZXk7CisKKyNkZWZpbmUgVVBCX1RBQktFWV9OVU0obikge259CisjaWZkZWYgVVBCX0M5OQorLy8gR2l2ZW4gdGhhdCB8c3wgaXMgYSBzdHJpbmcgbGl0ZXJhbCwgc2l6ZW9mKHMpIGdpdmVzIHVzIGEKKy8vIGNvbXBpbGUtdGltZS1jb25zdGFudCBzdHJsZW4oKS4gV2UgbXVzdCBlbnN1cmUgdGhhdCB0aGlzIHdvcmtzIGZvciBzdGF0aWMKKy8vIGRhdGEgaW5pdGlhbGl6ZXJzLgorI2RlZmluZSBVUEJfVEFCS0VZX1NUUihzdHJ2YWwpIHsgLnMgPSB7IC5zdHIgPSBzdHJ2YWwsICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmxlbmd0aCA9IHNpemVvZihzdHJ2YWwpIC0gMSB9IH0KKyNlbmRpZgorLy8gVE9ETyhoYWJlcm1hbik6IEMrKworI2RlZmluZSBVUEJfVEFCS0VZX05PTkUgezB9CisKK3R5cGVkZWYgc3RydWN0IF91cGJfdGFiZW50IHsKKyAgdXBiX3RhYmtleSBrZXk7CisgIF91cGJfdmFsdWUgdmFsOworICAvLyBJbnRlcm5hbCBjaGFpbmluZy4gIFRoaXMgaXMgY29uc3Qgc28gd2UgY2FuIGNyZWF0ZSBzdGF0aWMgaW5pdGlhbGl6ZXJzIGZvcgorICAvLyB0YWJsZXMuICBXZSBjYXN0IGF3YXkgY29uc3Qgc29tZXRpbWVzLCBidXQgKm9ubHkqIHdoZW4gdGhlIGNvbnRhaW5pbmcKKyAgLy8gdXBiX3RhYmxlIGlzIGtub3duIHRvIGJlIG5vbi1jb25zdC4gIFRoaXMgcmVxdWlyZXMgYSBiaXQgb2YgY2FyZSwgYnV0CisgIC8vIHRoZSBzdWJ0bGV0eSBpcyBjb25maW5lZCB0byB0YWJsZS5jLgorICBjb25zdCBzdHJ1Y3QgX3VwYl90YWJlbnQgKm5leHQ7Cit9IHVwYl90YWJlbnQ7CisKK3R5cGVkZWYgc3RydWN0IHsKKyAgc2l6ZV90IGNvdW50OyAgICAgICAgICAvLyBOdW1iZXIgb2YgZW50cmllcyBpbiB0aGUgaGFzaCBwYXJ0LgorICBzaXplX3QgbWFzazsgICAgICAgICAgIC8vIE1hc2sgdG8gdHVybiBoYXNoIHZhbHVlIC0+IGJ1Y2tldC4KKyAgdXBiX2N0eXBlX3QgY3R5cGU7ICAgICAvLyBUeXBlIG9mIGFsbCB2YWx1ZXMuCisgIHVpbnQ4X3Qgc2l6ZV9sZzI7ICAgICAgLy8gU2l6ZSBvZiB0aGUgaGFzaCB0YWJsZSBwYXJ0IGlzIDJec2l6ZV9sZzIgZW50cmllcy4KKworICAvLyBIYXNoIHRhYmxlIGVudHJpZXMuCisgIC8vIE1ha2luZyB0aGlzIGNvbnN0IGlzbid0IGVudGlyZWx5IGFjY3VyYXRlOyB3aGF0IHdlIHJlYWxseSB3YW50IGlzIGZvciBpdCB0bworICAvLyBoYXZlIHRoZSBzYW1lIGNvbnN0LW5lc3MgYXMgdGhlIHRhYmxlIGl0J3MgaW5zaWRlLiAgQnV0IHRoZXJlJ3Mgbm8gd2F5IHRvCisgIC8vIGRlY2xhcmUgdGhhdCBpbiBDLiAgU28gd2UgaGF2ZSB0byBtYWtlIGl0IGNvbnN0IHNvIHRoYXQgd2UgY2FuIHN0YXRpY2FsbHkKKyAgLy8gaW5pdGlhbGl6ZSBjb25zdCBoYXNoIHRhYmxlcy4gIFRoZW4gd2UgY2FzdCBhd2F5IGNvbnN0IHdoZW4gd2UgaGF2ZSB0by4KKyAgY29uc3QgdXBiX3RhYmVudCAqZW50cmllczsKK30gdXBiX3RhYmxlOworCit0eXBlZGVmIHN0cnVjdCB7CisgIHVwYl90YWJsZSB0OworfSB1cGJfc3RydGFibGU7CisKKyNkZWZpbmUgVVBCX1NUUlRBQkxFX0lOSVQoY291bnQsIG1hc2ssIGN0eXBlLCBzaXplX2xnMiwgZW50cmllcykgXAorICB7e2NvdW50LCBtYXNrLCBjdHlwZSwgc2l6ZV9sZzIsIGVudHJpZXN9fQorCisjZGVmaW5lIFVQQl9FTVBUWV9TVFJUQUJMRV9JTklUKGN0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVVBCX1NUUlRBQkxFX0lOSVQoMCwgMCwgY3R5cGUsIDAsIE5VTEwpCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgdXBiX3RhYmxlIHQ7ICAgICAgICAgICAgICAvLyBGb3IgZW50cmllcyB0aGF0IGRvbid0IGZpdCBpbiB0aGUgYXJyYXkgcGFydC4KKyAgY29uc3QgX3VwYl92YWx1ZSAqYXJyYXk7ICAvLyBBcnJheSBwYXJ0IG9mIHRoZSB0YWJsZS4gIFNlZSBjb25zdCBub3RlIGFib3ZlLgorICBzaXplX3QgYXJyYXlfc2l6ZTsgICAgICAgIC8vIEFycmF5IHBhcnQgc2l6ZS4KKyAgc2l6ZV90IGFycmF5X2NvdW50OyAgICAgICAvLyBBcnJheSBwYXJ0IG51bWJlciBvZiBlbGVtZW50cy4KK30gdXBiX2ludHRhYmxlOworCisjZGVmaW5lIFVQQl9JTlRUQUJMRV9JTklUKGNvdW50LCBtYXNrLCBjdHlwZSwgc2l6ZV9sZzIsIGVudCwgYSwgYXNpemUsIGFjb3VudCkgXAorICB7e2NvdW50LCBtYXNrLCBjdHlwZSwgc2l6ZV9sZzIsIGVudH0sIGEsIGFzaXplLCBhY291bnR9CisKKyNkZWZpbmUgVVBCX0VNUFRZX0lOVFRBQkxFX0lOSVQoY3R5cGUpIFwKKyAgVVBCX0lOVFRBQkxFX0lOSVQoMCwgMCwgY3R5cGUsIDAsIE5VTEwsIE5VTEwsIDAsIDApCisKKyNkZWZpbmUgVVBCX0FSUkFZX0VNUFRZVkFMIC0xCisjZGVmaW5lIFVQQl9BUlJBWV9FTVBUWUVOVCBVUEJfVkFMVUVfSU5JVF9JTlQ2NChVUEJfQVJSQVlfRU1QVFlWQUwpCisKK1VQQl9JTkxJTkUgc2l6ZV90IHVwYl90YWJsZV9zaXplKGNvbnN0IHVwYl90YWJsZSAqdCkgeworICBpZiAodC0+c2l6ZV9sZzIgPT0gMCkKKyAgICByZXR1cm4gMDsKKyAgZWxzZQorICAgIHJldHVybiAxIDw8IHQtPnNpemVfbGcyOworfQorCisvLyBJbnRlcm5hbC1vbmx5IGZ1bmN0aW9ucywgaW4gLmggZmlsZSBvbmx5IG91dCBvZiBuZWNlc3NpdHkuCitVUEJfSU5MSU5FIGJvb2wgdXBiX3RhYmVudF9pc2VtcHR5KGNvbnN0IHVwYl90YWJlbnQgKmUpIHsKKyAgcmV0dXJuIGUtPmtleS5udW0gPT0gMDsKK30KKworLy8gVXNlZCBieSBzb21lIG9mIHRoZSB1bml0IHRlc3RzIGZvciBnZW5lcmljIGhhc2hpbmcgZnVuY3Rpb25hbGl0eS4KK3VpbnQzMl90IE11cm11ckhhc2gyKGNvbnN0IHZvaWQgKiBrZXksIHNpemVfdCBsZW4sIHVpbnQzMl90IHNlZWQpOworCitVUEJfSU5MSU5FIHVwYl90YWJrZXkgdXBiX2ludGtleSh1aW50cHRyX3Qga2V5KSB7CisgIHVwYl90YWJrZXkgazsKKyAgay5udW0gPSBrZXk7CisgIHJldHVybiBrOworfQorCitVUEJfSU5MSU5FIHVpbnQzMl90IHVwYl9pbnRoYXNoKHVpbnRwdHJfdCBrZXkpIHsKKyAgcmV0dXJuICh1aW50MzJfdClrZXk7Cit9CisKK3N0YXRpYyBjb25zdCB1cGJfdGFiZW50ICp1cGJfZ2V0ZW50cnkoY29uc3QgdXBiX3RhYmxlICp0LCB1aW50MzJfdCBoYXNoKSB7CisgIHJldHVybiB0LT5lbnRyaWVzICsgKGhhc2ggJiB0LT5tYXNrKTsKK30KKworVVBCX0lOTElORSBib29sIHVwYl9hcnJoYXMoX3VwYl92YWx1ZSB2KSB7CisgIHJldHVybiB2LnVpbnQ2NCAhPSAodWludDY0X3QpVVBCX0FSUkFZX0VNUFRZVkFMOworfQorCisvLyBJbml0aWFsaXplIGFuZCB1bmluaXRpYWxpemUgYSB0YWJsZSwgcmVzcGVjdGl2ZWx5LiAgSWYgbWVtb3J5IGFsbG9jYXRpb24KKy8vIGZhaWxlZCwgZmFsc2UgaXMgcmV0dXJuZWQgdGhhdCB0aGUgdGFibGUgaXMgdW5pbml0aWFsaXplZC4KK2Jvb2wgdXBiX2ludHRhYmxlX2luaXQodXBiX2ludHRhYmxlICp0YWJsZSwgdXBiX2N0eXBlX3QgY3R5cGUpOworYm9vbCB1cGJfc3RydGFibGVfaW5pdCh1cGJfc3RydGFibGUgKnRhYmxlLCB1cGJfY3R5cGVfdCBjdHlwZSk7Cit2b2lkIHVwYl9pbnR0YWJsZV91bmluaXQodXBiX2ludHRhYmxlICp0YWJsZSk7Cit2b2lkIHVwYl9zdHJ0YWJsZV91bmluaXQodXBiX3N0cnRhYmxlICp0YWJsZSk7CisKKy8vIFJldHVybnMgdGhlIG51bWJlciBvZiB2YWx1ZXMgaW4gdGhlIHRhYmxlLgorc2l6ZV90IHVwYl9pbnR0YWJsZV9jb3VudChjb25zdCB1cGJfaW50dGFibGUgKnQpOworVVBCX0lOTElORSBzaXplX3QgdXBiX3N0cnRhYmxlX2NvdW50KGNvbnN0IHVwYl9zdHJ0YWJsZSAqdCkgeworICByZXR1cm4gdC0+dC5jb3VudDsKK30KKworLy8gSW5zZXJ0cyB0aGUgZ2l2ZW4ga2V5IGludG8gdGhlIGhhc2h0YWJsZSB3aXRoIHRoZSBnaXZlbiB2YWx1ZS4gIFRoZSBrZXkgbXVzdAorLy8gbm90IGFscmVhZHkgZXhpc3QgaW4gdGhlIGhhc2ggdGFibGUuICBGb3Igc3RyaW5nIHRhYmxlcywgdGhlIGtleSBtdXN0IGJlCisvLyBOVUxMLXRlcm1pbmF0ZWQsIGFuZCB0aGUgdGFibGUgd2lsbCBtYWtlIGFuIGludGVybmFsIGNvcHkgb2YgdGhlIGtleS4KKy8vIEludHRhYmxlcyBtdXN0IG5vdCBpbnNlcnQgYSB2YWx1ZSBvZiBVSU5UUFRSX01BWC4KKy8vCisvLyBJZiBhIHRhYmxlIHJlc2l6ZSB3YXMgcmVxdWlyZWQgYnV0IG1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCwgZmFsc2UgaXMKKy8vIHJldHVybmVkIGFuZCB0aGUgdGFibGUgaXMgdW5jaGFuZ2VkLgorYm9vbCB1cGJfaW50dGFibGVfaW5zZXJ0KHVwYl9pbnR0YWJsZSAqdCwgdWludHB0cl90IGtleSwgdXBiX3ZhbHVlIHZhbCk7Citib29sIHVwYl9zdHJ0YWJsZV9pbnNlcnQyKHVwYl9zdHJ0YWJsZSAqdCwgY29uc3QgY2hhciAqa2V5LCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfdmFsdWUgdmFsKTsKKworLy8gRm9yIE5VTEwtdGVybWluYXRlZCBzdHJpbmdzLgorVVBCX0lOTElORSBib29sIHVwYl9zdHJ0YWJsZV9pbnNlcnQodXBiX3N0cnRhYmxlICp0LCBjb25zdCBjaGFyICprZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfdmFsdWUgdmFsKSB7CisgIHJldHVybiB1cGJfc3RydGFibGVfaW5zZXJ0Mih0LCBrZXksIHN0cmxlbihrZXkpLCB2YWwpOworfQorCisvLyBMb29rcyB1cCBrZXkgaW4gdGhpcyB0YWJsZSwgcmV0dXJuaW5nICJ0cnVlIiBpZiB0aGUga2V5IHdhcyBmb3VuZC4KKy8vIElmIHYgaXMgbm9uLU5VTEwsIGNvcGllcyB0aGUgdmFsdWUgZm9yIHRoaXMga2V5IGludG8gKnYuCitib29sIHVwYl9pbnR0YWJsZV9sb29rdXAoY29uc3QgdXBiX2ludHRhYmxlICp0LCB1aW50cHRyX3Qga2V5LCB1cGJfdmFsdWUgKnYpOworYm9vbCB1cGJfc3RydGFibGVfbG9va3VwMihjb25zdCB1cGJfc3RydGFibGUgKnQsIGNvbnN0IGNoYXIgKmtleSwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3ZhbHVlICp2KTsKKworLy8gRm9yIE5VTEwtdGVybWluYXRlZCBzdHJpbmdzLgorVVBCX0lOTElORSBib29sIHVwYl9zdHJ0YWJsZV9sb29rdXAoY29uc3QgdXBiX3N0cnRhYmxlICp0LCBjb25zdCBjaGFyICprZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfdmFsdWUgKnYpIHsKKyAgcmV0dXJuIHVwYl9zdHJ0YWJsZV9sb29rdXAyKHQsIGtleSwgc3RybGVuKGtleSksIHYpOworfQorCisvLyBSZW1vdmVzIGFuIGl0ZW0gZnJvbSB0aGUgdGFibGUuICBSZXR1cm5zIHRydWUgaWYgdGhlIHJlbW92ZSB3YXMgc3VjY2Vzc2Z1bCwKKy8vIGFuZCBzdG9yZXMgdGhlIHJlbW92ZWQgaXRlbSBpbiAqdmFsIGlmIG5vbi1OVUxMLgorYm9vbCB1cGJfaW50dGFibGVfcmVtb3ZlKHVwYl9pbnR0YWJsZSAqdCwgdWludHB0cl90IGtleSwgdXBiX3ZhbHVlICp2YWwpOworYm9vbCB1cGJfc3RydGFibGVfcmVtb3ZlMih1cGJfc3RydGFibGUgKnQsIGNvbnN0IGNoYXIgKmtleSwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3ZhbHVlICp2YWwpOworCisvLyBGb3IgTlVMTC10ZXJtaW5hdGVkIHN0cmluZ3MuCitVUEJfSU5MSU5FIGJvb2wgdXBiX3N0cnRhYmxlX3JlbW92ZSh1cGJfc3RydGFibGUgKnQsIGNvbnN0IGNoYXIgKmtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl92YWx1ZSAqdikgeworICByZXR1cm4gdXBiX3N0cnRhYmxlX3JlbW92ZTIodCwga2V5LCBzdHJsZW4oa2V5KSwgdik7Cit9CisKKy8vIFVwZGF0ZXMgYW4gZXhpc3RpbmcgZW50cnkgaW4gYW4gaW50dGFibGUuICBJZiB0aGUgZW50cnkgZG9lcyBub3QgZXhpc3QsCisvLyByZXR1cm5zIGZhbHNlIGFuZCBkb2VzIG5vdGhpbmcuICBVbmxpa2UgaW5zZXJ0L3JlbW92ZSwgdGhpcyBkb2VzIG5vdAorLy8gaW52YWxpZGF0ZSBpdGVyYXRvcnMuCitib29sIHVwYl9pbnR0YWJsZV9yZXBsYWNlKHVwYl9pbnR0YWJsZSAqdCwgdWludHB0cl90IGtleSwgdXBiX3ZhbHVlIHZhbCk7CisKKy8vIEhhbmR5IHJvdXRpbmVzIGZvciB0cmVhdGluZyBhbiBpbnR0YWJsZSBsaWtlIGEgc3RhY2suICBNYXkgbm90IGJlIG1peGVkIHdpdGgKKy8vIG90aGVyIGluc2VydC9yZW1vdmUgY2FsbHMuCitib29sIHVwYl9pbnR0YWJsZV9wdXNoKHVwYl9pbnR0YWJsZSAqdCwgdXBiX3ZhbHVlIHZhbCk7Cit1cGJfdmFsdWUgdXBiX2ludHRhYmxlX3BvcCh1cGJfaW50dGFibGUgKnQpOworCisvLyBDb252ZW5pZW5jZSByb3V0aW5lcyBmb3IgaW50dGFibGVzIHdpdGggcG9pbnRlciBrZXlzLgorYm9vbCB1cGJfaW50dGFibGVfaW5zZXJ0cHRyKHVwYl9pbnR0YWJsZSAqdCwgY29uc3Qgdm9pZCAqa2V5LCB1cGJfdmFsdWUgdmFsKTsKK2Jvb2wgdXBiX2ludHRhYmxlX3JlbW92ZXB0cih1cGJfaW50dGFibGUgKnQsIGNvbnN0IHZvaWQgKmtleSwgdXBiX3ZhbHVlICp2YWwpOworYm9vbCB1cGJfaW50dGFibGVfbG9va3VwcHRyKAorICAgIGNvbnN0IHVwYl9pbnR0YWJsZSAqdCwgY29uc3Qgdm9pZCAqa2V5LCB1cGJfdmFsdWUgKnZhbCk7CisKKy8vIE9wdGltaXplcyB0aGUgdGFibGUgZm9yIHRoZSBjdXJyZW50IHNldCBvZiBlbnRyaWVzLCBmb3IgYm90aCBtZW1vcnkgdXNlIGFuZAorLy8gbG9va3VwIHRpbWUuICBDbGllbnQgc2hvdWxkIGNhbGwgdGhpcyBhZnRlciBhbGwgZW50cmllcyBoYXZlIGJlZW4gaW5zZXJ0ZWQ7CisvLyBpbnNlcnRpbmcgbW9yZSBlbnRyaWVzIGlzIGxlZ2FsLCBidXQgd2lsbCBsaWtlbHkgcmVxdWlyZSBhIHRhYmxlIHJlc2l6ZS4KK3ZvaWQgdXBiX2ludHRhYmxlX2NvbXBhY3QodXBiX2ludHRhYmxlICp0KTsKKworLy8gQSBzcGVjaWFsLWNhc2UgaW5saW5hYmxlIHZlcnNpb24gb2YgdGhlIGxvb2t1cCByb3V0aW5lIGZvciAzMi1iaXQgaW50ZWdlcnMuCitVUEJfSU5MSU5FIGJvb2wgdXBiX2ludHRhYmxlX2xvb2t1cDMyKGNvbnN0IHVwYl9pbnR0YWJsZSAqdCwgdWludDMyX3Qga2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfdmFsdWUgKnYpIHsKKyAgKnYgPSB1cGJfdmFsdWVfaW50MzIoMCk7ICAvLyBTaWxlbmNlIGNvbXBpbGVyIHdhcm5pbmdzLgorICBpZiAoa2V5IDwgdC0+YXJyYXlfc2l6ZSkgeworICAgIF91cGJfdmFsdWUgYXJydmFsID0gdC0+YXJyYXlba2V5XTsKKyAgICBpZiAodXBiX2FycmhhcyhhcnJ2YWwpKSB7CisgICAgICBfdXBiX3ZhbHVlX3NldHZhbCh2LCBhcnJ2YWwsIHQtPnQuY3R5cGUpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgY29uc3QgdXBiX3RhYmVudCAqZTsKKyAgICBpZiAodC0+dC5lbnRyaWVzID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgICBmb3IgKGUgPSB1cGJfZ2V0ZW50cnkoJnQtPnQsIHVwYl9pbnRoYXNoKGtleSkpOyB0cnVlOyBlID0gZS0+bmV4dCkgeworICAgICAgaWYgKCh1aW50MzJfdCllLT5rZXkubnVtID09IGtleSkgeworICAgICAgICBfdXBiX3ZhbHVlX3NldHZhbCh2LCBlLT52YWwsIHQtPnQuY3R5cGUpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGlmIChlLT5uZXh0ID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KK30KKworLy8gRXhwb3NlZCBmb3IgdGVzdGluZyBvbmx5LgorYm9vbCB1cGJfc3RydGFibGVfcmVzaXplKHVwYl9zdHJ0YWJsZSAqdCwgc2l6ZV90IHNpemVfbGcyKTsKKworLyogSXRlcmF0b3JzICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gSXRlcmF0b3JzIGZvciBpbnQgYW5kIHN0cmluZyB0YWJsZXMuICBXZSBhcmUgc3ViamVjdCB0byBzb21lIGtpbmQgb2YgdW51c3VhbAorLy8gZGVzaWduIGNvbnN0cmFpbnRzOgorLy8KKy8vIEZvciBoaWdoLWxldmVsIGxhbmd1YWdlczoKKy8vICAtIHdlIG11c3QgYmUgYWJsZSB0byBndWFyYW50ZWUgdGhhdCB3ZSBkb24ndCBjcmFzaCBvciBjb3JydXB0IG1lbW9yeSBldmVuIGlmCisvLyAgICB0aGUgcHJvZ3JhbSBhY2Nlc3NlcyBhbiBpbnZhbGlkYXRlZCBpdGVyYXRvci4KKy8vCisvLyBGb3IgQysrMTEgcmFuZ2UtYmFzZWQgZm9yOgorLy8gIC0gaXRlcmF0b3JzIG11c3QgYmUgY29weWFibGUKKy8vICAtIGl0ZXJhdG9ycyBtdXN0IGJlIGNvbXBhcmFibGUKKy8vICAtIGl0IG11c3QgYmUgcG9zc2libGUgdG8gY29uc3RydWN0IGFuICJlbmQiIHZhbHVlLgorLy8KKy8vIEl0ZXJhdGlvbiBvcmRlciBpcyB1bmRlZmluZWQuCisvLworLy8gTW9kaWZ5aW5nIHRoZSB0YWJsZSBpbnZhbGlkYXRlcyBpdGVyYXRvcnMuICB1cGJfe3N0cixpbnR9dGFibGVfZG9uZSgpIGlzCisvLyBndWFyYW50ZWVkIHRvIHdvcmsgZXZlbiBvbiBhbiBpbnZhbGlkYXRlZCBpdGVyYXRvciwgYXMgbG9uZyBhcyB0aGUgdGFibGUgaXQKKy8vIGlzIGl0ZXJhdGluZyBvdmVyIGhhcyBub3QgYmVlbiBmcmVlZC4gIENhbGxpbmcgbmV4dCgpIG9yIGFjY2Vzc2luZyBkYXRhIGZyb20KKy8vIGFuIGludmFsaWRhdGVkIGl0ZXJhdG9yIHlpZWxkcyB1bnNwZWNpZmllZCBlbGVtZW50cyBmcm9tIHRoZSB0YWJsZSwgYnV0IGl0IGlzCisvLyBndWFyYW50ZWVkIG5vdCB0byBjcmFzaCBhbmQgdG8gcmV0dXJuIHJlYWwgdGFibGUgZWxlbWVudHMgKGV4Y2VwdCB3aGVuIGRvbmUoKQorLy8gaXMgdHJ1ZSkuCisKKworLyogdXBiX3N0cnRhYmxlX2l0ZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gICB1cGJfc3RydGFibGVfaXRlciBpOworLy8gICB1cGJfc3RydGFibGVfYmVnaW4oJmksIHQpOworLy8gICBmb3IoOyAhdXBiX3N0cnRhYmxlX2RvbmUoJmkpOyB1cGJfc3RydGFibGVfbmV4dCgmaSkpIHsKKy8vICAgICBjb25zdCBjaGFyICprZXkgPSB1cGJfc3RydGFibGVfaXRlcl9rZXkoJmkpOworLy8gICAgIGNvbnN0IHVwYl92YWx1ZSB2YWwgPSB1cGJfc3RydGFibGVfaXRlcl92YWx1ZSgmaSk7CisvLyAgICAgLy8gLi4uCisvLyAgIH0KKwordHlwZWRlZiBzdHJ1Y3QgeworICBjb25zdCB1cGJfc3RydGFibGUgKnQ7CisgIHNpemVfdCBpbmRleDsKK30gdXBiX3N0cnRhYmxlX2l0ZXI7CisKK3ZvaWQgdXBiX3N0cnRhYmxlX2JlZ2luKHVwYl9zdHJ0YWJsZV9pdGVyICppLCBjb25zdCB1cGJfc3RydGFibGUgKnQpOwordm9pZCB1cGJfc3RydGFibGVfbmV4dCh1cGJfc3RydGFibGVfaXRlciAqaSk7Citib29sIHVwYl9zdHJ0YWJsZV9kb25lKGNvbnN0IHVwYl9zdHJ0YWJsZV9pdGVyICppKTsKK2NvbnN0IGNoYXIgKnVwYl9zdHJ0YWJsZV9pdGVyX2tleSh1cGJfc3RydGFibGVfaXRlciAqaSk7CitzaXplX3QgdXBiX3N0cnRhYmxlX2l0ZXJfa2V5bGVuZ3RoKHVwYl9zdHJ0YWJsZV9pdGVyICppKTsKK3VwYl92YWx1ZSB1cGJfc3RydGFibGVfaXRlcl92YWx1ZShjb25zdCB1cGJfc3RydGFibGVfaXRlciAqaSk7Cit2b2lkIHVwYl9zdHJ0YWJsZV9pdGVyX3NldGRvbmUodXBiX3N0cnRhYmxlX2l0ZXIgKmkpOworYm9vbCB1cGJfc3RydGFibGVfaXRlcl9pc2VxdWFsKGNvbnN0IHVwYl9zdHJ0YWJsZV9pdGVyICppMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfc3RydGFibGVfaXRlciAqaTIpOworCisKKy8qIHVwYl9pbnR0YWJsZV9pdGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vICAgdXBiX2ludHRhYmxlX2l0ZXIgaTsKKy8vICAgdXBiX2ludHRhYmxlX2JlZ2luKCZpLCB0KTsKKy8vICAgZm9yKDsgIXVwYl9pbnR0YWJsZV9kb25lKCZpKTsgdXBiX2ludHRhYmxlX25leHQoJmkpKSB7CisvLyAgICAgdWludHB0cl90IGtleSA9IHVwYl9pbnR0YWJsZV9pdGVyX2tleSgmaSk7CisvLyAgICAgdXBiX3ZhbHVlIHZhbCA9IHVwYl9pbnR0YWJsZV9pdGVyX3ZhbHVlKCZpKTsKKy8vICAgICAvLyAuLi4KKy8vICAgfQorCit0eXBlZGVmIHN0cnVjdCB7CisgIGNvbnN0IHVwYl9pbnR0YWJsZSAqdDsKKyAgc2l6ZV90IGluZGV4OworICBib29sIGFycmF5X3BhcnQ7Cit9IHVwYl9pbnR0YWJsZV9pdGVyOworCit2b2lkIHVwYl9pbnR0YWJsZV9iZWdpbih1cGJfaW50dGFibGVfaXRlciAqaSwgY29uc3QgdXBiX2ludHRhYmxlICp0KTsKK3ZvaWQgdXBiX2ludHRhYmxlX25leHQodXBiX2ludHRhYmxlX2l0ZXIgKmkpOworYm9vbCB1cGJfaW50dGFibGVfZG9uZShjb25zdCB1cGJfaW50dGFibGVfaXRlciAqaSk7Cit1aW50cHRyX3QgdXBiX2ludHRhYmxlX2l0ZXJfa2V5KGNvbnN0IHVwYl9pbnR0YWJsZV9pdGVyICppKTsKK3VwYl92YWx1ZSB1cGJfaW50dGFibGVfaXRlcl92YWx1ZShjb25zdCB1cGJfaW50dGFibGVfaXRlciAqaSk7Cit2b2lkIHVwYl9pbnR0YWJsZV9pdGVyX3NldGRvbmUodXBiX2ludHRhYmxlX2l0ZXIgKmkpOworYm9vbCB1cGJfaW50dGFibGVfaXRlcl9pc2VxdWFsKGNvbnN0IHVwYl9pbnR0YWJsZV9pdGVyICppMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfaW50dGFibGVfaXRlciAqaTIpOworCisKKyNpZmRlZiBfX2NwbHVzcGx1cworfSAgLyogZXh0ZXJuICJDIiAqLworI2VuZGlmCisKKyNlbmRpZiAgLyogVVBCX1RBQkxFX0hfICovCisKKy8vIFJlZmVyZW5jZSB0cmFja2luZyB3aWxsIGNoZWNrIHJlZigpL3VucmVmKCkgb3BlcmF0aW9ucyB0byBtYWtlIHN1cmUgdGhlCisvLyByZWYgb3duZXJzaGlwIGlzIGNvcnJlY3QuICBXaGVyZSBwb3NzaWJsZSBpdCB3aWxsIGFsc28gbWFrZSB0b29scyBsaWtlCisvLyBWYWxncmluZCBhdHRyaWJ1dGUgcmVmIGxlYWtzIHRvIHRoZSBjb2RlIHRoYXQgdG9vayB0aGUgbGVha2VkIHJlZiwgbm90CisvLyB0aGUgY29kZSB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGUgb2JqZWN0LgorLy8KKy8vIEVuYWJsaW5nIHRoaXMgcmVxdWlyZXMgdGhlIGFwcGxpY2F0aW9uIHRvIGRlZmluZSB1cGJfbG9jaygpL3VwYl91bmxvY2soKQorLy8gZnVuY3Rpb25zIHRoYXQgYWNxdWlyZS9yZWxlYXNlIGEgZ2xvYmFsIG11dGV4IChvciAjZGVmaW5lIFVQQl9USFJFQURfVU5TQUZFKS4KKyNpZm5kZWYgTkRFQlVHCisjZGVmaW5lIFVQQl9ERUJVR19SRUZTCisjZW5kaWYKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsgY2xhc3MgUmVmQ291bnRlZDsgfQorI2VuZGlmCisKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpSZWZDb3VudGVkLCB1cGJfcmVmY291bnRlZCk7CisKK3N0cnVjdCB1cGJfcmVmY291bnRlZF92dGJsOworCitVUEJfREVGSU5FX0NMQVNTMCh1cGI6OlJlZkNvdW50ZWQsCisgcHVibGljOgorICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIG9iamVjdCBpcyBmcm96ZW4uCisgIGJvb2wgSXNGcm96ZW4oKSBjb25zdDsKKworICAvLyBJbmNyZWFzZXMgdGhlIHJlZiBjb3VudCwgdGhlIG5ldyByZWYgaXMgb3duZWQgYnkgIm93bmVyIiB3aGljaCBtdXN0IG5vdAorICAvLyBhbHJlYWR5IG93biBhIHJlZiAoYW5kIHNob3VsZCBub3QgaXRzZWxmIGJlIGEgcmVmY291bnRlZCBvYmplY3QgaWYgdGhlIHJlZgorICAvLyBjb3VsZCBwb3NzaWJseSBiZSBjaXJjdWxhcjsgc2VlIGJlbG93KS4KKyAgLy8gVGhyZWFkLXNhZmUgaWZmICJ0aGlzIiBpcyBmcm96ZW4uCisgIHZvaWQgUmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdDsKKworICAvLyBSZWxlYXNlIGEgcmVmIHRoYXQgd2FzIGFjcXVpcmVkIGZyb20gdXBiX3JlZmNvdW50ZWRfcmVmKCkgYW5kIGNvbGxlY3RzIGFueQorICAvLyBvYmplY3RzIGl0IGNhbi4KKyAgdm9pZCBVbnJlZihjb25zdCB2b2lkICpvd25lcikgY29uc3Q7CisKKyAgLy8gTW92ZXMgYW4gZXhpc3RpbmcgcmVmIGZyb20gImZyb20iIHRvICJ0byIsIHdpdGhvdXQgY2hhbmdpbmcgdGhlIG92ZXJhbGwKKyAgLy8gcmVmIGNvdW50LiAgRG9uYXRlUmVmKGZvbywgTlVMTCwgb3duZXIpIGlzIHRoZSBzYW1lIGFzIFJlZihmb28sIG93bmVyKSwKKyAgLy8gYnV0ICJ0byIgbWF5IG5vdCBiZSBOVUxMLgorICB2b2lkIERvbmF0ZVJlZihjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0bykgY29uc3Q7CisKKyAgLy8gVmVyaWZpZXMgdGhhdCBhIHJlZiB0byB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGN1cnJlbnRseSBoZWxkIGJ5IHRoZSBnaXZlbgorICAvLyBvd25lci4gIE9ubHkgZWZmZWN0aXZlIGluIFVQQl9ERUJVR19SRUZTIGJ1aWxkcy4KKyAgdm9pZCBDaGVja1JlZihjb25zdCB2b2lkICpvd25lcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBVUEJfRElTQUxMT1dfUE9EX09QUyhSZWZDb3VudGVkLCB1cGI6OlJlZkNvdW50ZWQpOworLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9yZWZjb3VudGVkLAorICAvLyBBIHNpbmdsZSByZWZlcmVuY2UgY291bnQgc2hhcmVkIGJ5IGFsbCBvYmplY3RzIGluIHRoZSBncm91cC4KKyAgdWludDMyX3QgKmdyb3VwOworCisgIC8vIEEgc2luZ2x5LWxpbmtlZCBsaXN0IG9mIGFsbCBvYmplY3RzIGluIHRoZSBncm91cC4KKyAgdXBiX3JlZmNvdW50ZWQgKm5leHQ7CisKKyAgLy8gVGFibGUgb2YgZnVuY3Rpb24gcG9pbnRlcnMgZm9yIHRoaXMgdHlwZS4KKyAgY29uc3Qgc3RydWN0IHVwYl9yZWZjb3VudGVkX3Z0YmwgKnZ0Ymw7CisKKyAgLy8gTWFpbnRhaW5lZCBvbmx5IHdoZW4gbXV0YWJsZSwgdGhpcyB0cmFja3MgdGhlIG51bWJlciBvZiByZWZzIChidXQgbm90CisgIC8vIHJlZjIncykgdG8gdGhpcyBvYmplY3QuICAqZ3JvdXAgc2hvdWxkIGJlIHRoZSBzdW0gb2YgYWxsIGluZGl2aWR1YWxfY291bnQKKyAgLy8gaW4gdGhlIGdyb3VwLgorICB1aW50MzJfdCBpbmRpdmlkdWFsX2NvdW50OworCisgIGJvb2wgaXNfZnJvemVuOworCisjaWZkZWYgVVBCX0RFQlVHX1JFRlMKKyAgdXBiX2ludHRhYmxlICpyZWZzOyAgLy8gTWFwcyBvd25lciAtPiB0cmFja2VkcmVmIGZvciBpbmNvbWluZyByZWZzLgorICB1cGJfaW50dGFibGUgKnJlZjJzOyAvLyBTZXQgb2YgdGFyZ2V0cyBmb3Igb3V0Z29pbmcgcmVmMnMuCisjZW5kaWYKKykpOworCitVUEJfQkVHSU5fRVhURVJOX0MgIC8vIHsKKworLy8gSXQgaXMgYmV0dGVyIHRvIHVzZSB0cmFja2VkIHJlZnMgd2hlbiBwb3NzaWJsZSwgZm9yIHRoZSBleHRyYSBkZWJ1Z2dpbmcKKy8vIGNhcGFiaWxpdHkuICBCdXQgaWYgdGhpcyBpcyBub3QgcG9zc2libGUgKGJlY2F1c2UgeW91IGRvbid0IGhhdmUgZWFzeSBhY2Nlc3MKKy8vIHRvIGEgc3RhYmxlIHBvaW50ZXIgdmFsdWUgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZiksIHlvdSBjYW4gcGFzcworLy8gVVBCX1VOVFJBQ0tFRF9SRUYgaW5zdGVhZC4KK2V4dGVybiBjb25zdCB2b2lkICpVUEJfVU5UUkFDS0VEX1JFRjsKKworLy8gTmF0aXZlIEMgQVBJLgorYm9vbCB1cGJfcmVmY291bnRlZF9pc2Zyb3plbihjb25zdCB1cGJfcmVmY291bnRlZCAqcik7Cit2b2lkIHVwYl9yZWZjb3VudGVkX3JlZihjb25zdCB1cGJfcmVmY291bnRlZCAqciwgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfcmVmY291bnRlZF91bnJlZihjb25zdCB1cGJfcmVmY291bnRlZCAqciwgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfcmVmY291bnRlZF9kb25hdGVyZWYoCisgICAgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKTsKK3ZvaWQgdXBiX3JlZmNvdW50ZWRfY2hlY2tyZWYoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIGNvbnN0IHZvaWQgKm93bmVyKTsKKworCisvLyBJbnRlcm5hbC10by11cGIgSW50ZXJmYWNlIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCit0eXBlZGVmIHZvaWQgdXBiX3JlZmNvdW50ZWRfdmlzaXQoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX3JlZmNvdW50ZWQgKnN1Ym9iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbG9zdXJlKTsKKworc3RydWN0IHVwYl9yZWZjb3VudGVkX3Z0YmwgeworICAvLyBNdXN0IHZpc2l0IGFsbCBzdWJvYmplY3RzIHRoYXQgYXJlIGN1cnJlbnRseSByZWYnZCB2aWEgdXBiX3JlZmNvdW50ZWRfcmVmMi4KKyAgLy8gTXVzdCBiZSBsb25nam1wKCktc2FmZS4KKyAgdm9pZCAoKnZpc2l0KShjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWRfdmlzaXQgKnZpc2l0LCB2b2lkICpjKTsKKworICAvLyBNdXN0IGZyZWUgdGhlIG9iamVjdCBhbmQgcmVsZWFzZSBhbGwgcmVmZXJlbmNlcyB0byBvdGhlciBvYmplY3RzLgorICB2b2lkICgqZnJlZSkodXBiX3JlZmNvdW50ZWQgKnIpOworfTsKKworLy8gSW5pdGlhbGl6ZXMgdGhlIHJlZmNvdW50ZWQgd2l0aCBhIHNpbmdsZSByZWYgZm9yIHRoZSBnaXZlbiBvd25lci4gIFJldHVybnMKKy8vIGZhbHNlIGlmIG1lbW9yeSBjb3VsZCBub3QgYmUgYWxsb2NhdGVkLgorYm9vbCB1cGJfcmVmY291bnRlZF9pbml0KHVwYl9yZWZjb3VudGVkICpyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCB1cGJfcmVmY291bnRlZF92dGJsICp2dGJsLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKm93bmVyKTsKKworLy8gQWRkcyBhIHJlZiBmcm9tIG9uZSByZWZjb3VudGVkIG9iamVjdCB0byBhbm90aGVyICgiZnJvbSIgbXVzdCBub3QgYWxyZWFkeQorLy8gb3duIGEgcmVmKS4gIFRoZXNlIHJlZnMgbWF5IGJlIGNpcmN1bGFyOyBjeWNsZXMgd2lsbCBiZSBjb2xsZWN0ZWQgY29ycmVjdGx5CisvLyAoaWYgY29uc2VydmF0aXZlbHkpLiAgVGhlc2UgcmVmcyBkbyBub3QgbmVlZCB0byBiZSBmcmVlZCBpbiBmcm9tJ3MgZnJlZSgpCisvLyBmdW5jdGlvbi4KK3ZvaWQgdXBiX3JlZmNvdW50ZWRfcmVmMihjb25zdCB1cGJfcmVmY291bnRlZCAqciwgdXBiX3JlZmNvdW50ZWQgKmZyb20pOworCisvLyBSZW1vdmVzIGEgcmVmIHRoYXQgd2FzIGFjcXVpcmVkIGZyb20gdXBiX3JlZmNvdW50ZWRfcmVmMigpLCBhbmQgY29sbGVjdHMgYW55CisvLyBvYmplY3QgaXQgY2FuLiAgVGhpcyBpcyBvbmx5IG5lY2Vzc2FyeSB3aGVuICJmcm9tIiBubyBsb25nZXIgcG9pbnRzIHRvICJyIiwKKy8vIGFuZCBub3QgZnJvbSBmcm9tJ3MgImZyZWUiIGZ1bmN0aW9uLgordm9pZCB1cGJfcmVmY291bnRlZF91bnJlZjIoY29uc3QgdXBiX3JlZmNvdW50ZWQgKnIsIHVwYl9yZWZjb3VudGVkICpmcm9tKTsKKworI2RlZmluZSB1cGJfcmVmMihyLCBmcm9tKSBcCisgICAgdXBiX3JlZmNvdW50ZWRfcmVmMigoY29uc3QgdXBiX3JlZmNvdW50ZWQqKXIsICh1cGJfcmVmY291bnRlZCopZnJvbSkKKyNkZWZpbmUgdXBiX3VucmVmMihyLCBmcm9tKSBcCisgICAgdXBiX3JlZmNvdW50ZWRfdW5yZWYyKChjb25zdCB1cGJfcmVmY291bnRlZCopciwgKHVwYl9yZWZjb3VudGVkKilmcm9tKQorCisvLyBGcmVlemVzIGFsbCBtdXRhYmxlIG9iamVjdCByZWFjaGFibGUgYnkgcmVmMigpIHJlZnMgZnJvbSB0aGUgZ2l2ZW4gcm9vdHMuCisvLyBUaGlzIHdpbGwgc3BsaXQgcmVmY291bnRpbmcgZ3JvdXBzIGludG8gcHJlY2lzZSBTQ0MgZ3JvdXBzLCBzbyB0aGF0CisvLyByZWZjb3VudGluZyBvZiBmcm96ZW4gb2JqZWN0cyBjYW4gYmUgbW9yZSBhZ2dyZXNzaXZlLiAgSWYgbWVtb3J5IGFsbG9jYXRpb24KKy8vIGZhaWxzLCBvciBpZiBtb3JlIHRoYW4gMioqMzEgbXV0YWJsZSBvYmplY3RzIGFyZSByZWFjaGFibGUgZnJvbSAicm9vdHMiLCBvcgorLy8gaWYgdGhlIG1heGltdW0gZGVwdGggb2YgdGhlIGdyYXBoIGV4Y2VlZHMgIm1heGRlcHRoIiwgZmFsc2UgaXMgcmV0dXJuZWQgYW5kCisvLyB0aGUgb2JqZWN0cyBhcmUgdW5jaGFuZ2VkLgorLy8KKy8vIEFmdGVyIHRoaXMgb3BlcmF0aW9uIHN1Y2NlZWRzLCB0aGUgb2JqZWN0cyBhcmUgZnJvemVuL2NvbnN0LCBhbmQgbWF5IG5vdCBiZQorLy8gdXNlZCB0aHJvdWdoIG5vbi1jb25zdCBwb2ludGVycy4gIEluIHBhcnRpY3VsYXIsIHRoZXkgbWF5IG5vdCBiZSBwYXNzZWQgYXMKKy8vIHRoZSBzZWNvbmQgcGFyYW1ldGVyIG9mIHVwYl9yZWZjb3VudGVkX3tyZWYsdW5yZWZ9MigpLiAgT24gdGhlIHVwc2lkZSwgYWxsCisvLyBvcGVyYXRpb25zIG9uIGZyb3plbiByZWZjb3VudGVkcyBhcmUgdGhyZWFkc2FmZSwgYW5kIG9iamVjdHMgd2lsbCBiZSBmcmVlZAorLy8gYXQgdGhlIHByZWNpc2UgbW9tZW50IHRoYXQgdGhleSBiZWNvbWUgdW5yZWFjaGFibGUuCisvLworLy8gQ2FsbGVyIG11c3Qgb3duIHJlZnMgb24gZWFjaCBvYmplY3QgaW4gdGhlICJyb290cyIgbGlzdC4KK2Jvb2wgdXBiX3JlZmNvdW50ZWRfZnJlZXplKHVwYl9yZWZjb3VudGVkICpjb25zdCpyb290cywgaW50IG4sIHVwYl9zdGF0dXMgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWF4ZGVwdGgpOworCisvLyBTaGFyZWQgYnkgYWxsIGNvbXBpbGVkLWluIHJlZmNvdW50ZWQgb2JqZWN0cy4KK2V4dGVybiB1aW50MzJfdCBzdGF0aWNfcmVmY291bnQ7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworI2lmZGVmIFVQQl9ERUJVR19SRUZTCisjZGVmaW5lIFVQQl9SRUZDT1VOVF9JTklUKHJlZnMsIHJlZjJzKSBcCisgICAgeyZzdGF0aWNfcmVmY291bnQsIE5VTEwsIE5VTEwsIDAsIHRydWUsIHJlZnMsIHJlZjJzfQorI2Vsc2UKKyNkZWZpbmUgVVBCX1JFRkNPVU5UX0lOSVQocmVmcywgcmVmMnMpIHsmc3RhdGljX3JlZmNvdW50LCBOVUxMLCBOVUxMLCAwLCB0cnVlfQorI2VuZGlmCisKKyNpZmRlZiBfX2NwbHVzcGx1cworLy8gQysrIFdyYXBwZXJzLgorbmFtZXNwYWNlIHVwYiB7CitpbmxpbmUgYm9vbCBSZWZDb3VudGVkOjpJc0Zyb3plbigpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9yZWZjb3VudGVkX2lzZnJvemVuKHRoaXMpOworfQoraW5saW5lIHZvaWQgUmVmQ291bnRlZDo6UmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdCB7CisgIHVwYl9yZWZjb3VudGVkX3JlZih0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgdm9pZCBSZWZDb3VudGVkOjpVbnJlZihjb25zdCB2b2lkICpvd25lcikgY29uc3QgeworICB1cGJfcmVmY291bnRlZF91bnJlZih0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgdm9pZCBSZWZDb3VudGVkOjpEb25hdGVSZWYoY29uc3Qgdm9pZCAqZnJvbSwgY29uc3Qgdm9pZCAqdG8pIGNvbnN0IHsKKyAgdXBiX3JlZmNvdW50ZWRfZG9uYXRlcmVmKHRoaXMsIGZyb20sIHRvKTsKK30KK2lubGluZSB2b2lkIFJlZkNvdW50ZWQ6OkNoZWNrUmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdCB7CisgIHVwYl9yZWZjb3VudGVkX2NoZWNrcmVmKHRoaXMsIG93bmVyKTsKK30KK30gIC8vIG5hbWVzcGFjZSB1cGIKKyNlbmRpZgorCisjZW5kaWYgIC8vIFVQQl9SRUZDT1VOVF9IXworCisjaWZkZWYgX19jcGx1c3BsdXMKKyNpbmNsdWRlIDxjc3RyaW5nPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSB1cGIgeworY2xhc3MgRGVmOworY2xhc3MgRW51bURlZjsKK2NsYXNzIEZpZWxkRGVmOworY2xhc3MgTWVzc2FnZURlZjsKK2NsYXNzIE9uZW9mRGVmOworfQorI2VuZGlmCisKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpEZWYsIHVwYl9kZWYpOworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OkVudW1EZWYsIHVwYl9lbnVtZGVmKTsKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpGaWVsZERlZiwgdXBiX2ZpZWxkZGVmKTsKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpNZXNzYWdlRGVmLCB1cGJfbXNnZGVmKTsKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpPbmVvZkRlZiwgdXBiX29uZW9mZGVmKTsKKworLy8gTWF4aW11bSBmaWVsZCBudW1iZXIgYWxsb3dlZCBmb3IgRmllbGREZWZzLiAgVGhpcyBpcyBhbiBpbmhlcmVudCBsaW1pdCBvZiB0aGUKKy8vIHByb3RvYnVmIHdpcmUgZm9ybWF0LgorI2RlZmluZSBVUEJfTUFYX0ZJRUxETlVNQkVSICgoMSA8PCAyOSkgLSAxKQorCisvLyBUaGUgbWF4aW11bSBtZXNzYWdlIGRlcHRoIHRoYXQgdGhlIHR5cGUgZ3JhcGggY2FuIGhhdmUuICBUaGlzIGlzIGEgcmVzb3VyY2UKKy8vIGxpbWl0IGZvciB0aGUgQyBzdGFjayBzaW5jZSB3ZSBzb21ldGltZXMgbmVlZCB0byByZWN1cnNpdmVseSB0cmF2ZXJzZSB0aGUKKy8vIGdyYXBoLiAgQ3ljbGVzIGFyZSBvazsgdGhlIHRyYXZlcnNhbCB3aWxsIHN0b3Agd2hlbiBpdCBkZXRlY3RzIGEgY3ljbGUsIGJ1dAorLy8gd2UgbXVzdCBoaXQgdGhlIGN5Y2xlIGJlZm9yZSB0aGUgbWF4aW11bSBkZXB0aCBpcyByZWFjaGVkLgorLy8KKy8vIElmIGhhdmluZyBhIHNpbmdsZSBzdGF0aWMgbGltaXQgaXMgdG9vIGluZmxleGlibGUsIHdlIGNhbiBhZGQgYW5vdGhlciB2YXJpYW50CisvLyBvZiBEZWY6OkZyZWV6ZSB0aGF0IGFsbG93cyBzcGVjaWZ5aW5nIHRoaXMgYXMgYSBwYXJhbWV0ZXIuCisjZGVmaW5lIFVQQl9NQVhfTUVTU0FHRV9ERVBUSCA2NAorCisKKy8qIHVwYjo6RGVmOiBiYXNlIGNsYXNzIGZvciBkZWZzICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIEFsbCB0aGUgZGlmZmVyZW50IGtpbmQgb2YgZGVmcyB3ZSBzdXBwb3J0LiAgVGhlc2UgY29ycmVzcG9uZCAxOjEgd2l0aAorLy8gZGVjbGFyYXRpb25zIGluIGEgLnByb3RvIGZpbGUuCit0eXBlZGVmIGVudW0geworICBVUEJfREVGX01TRywKKyAgVVBCX0RFRl9GSUVMRCwKKyAgVVBCX0RFRl9FTlVNLAorICBVUEJfREVGX09ORU9GLAorICBVUEJfREVGX1NFUlZJQ0UsICAgLy8gTm90IHlldCBpbXBsZW1lbnRlZC4KKyAgVVBCX0RFRl9BTlkgPSAtMSwgIC8vIFdpbGRjYXJkIGZvciB1cGJfc3ltdGFiX2dldCooKQorfSB1cGJfZGVmdHlwZV90OworCisvLyBUaGUgYmFzZSBjbGFzcyBvZiBhbGwgZGVmcy4gIEl0cyBiYXNlIGlzIHVwYjo6UmVmQ291bnRlZCAodXNlIHVwYjo6dXBjYXN0KCkKKy8vIHRvIGNvbnZlcnQpLgorVVBCX0RFRklORV9DTEFTUzEodXBiOjpEZWYsIHVwYjo6UmVmQ291bnRlZCwKKyBwdWJsaWM6CisgIHR5cGVkZWYgdXBiX2RlZnR5cGVfdCBUeXBlOworCisgIERlZiogRHVwKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdDsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpSZWZDb3VudGVkLgorICBib29sIElzRnJvemVuKCkgY29uc3Q7CisgIHZvaWQgUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBVbnJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisgIHZvaWQgRG9uYXRlUmVmKGNvbnN0IHZvaWQqIGZyb20sIGNvbnN0IHZvaWQqIHRvKSBjb25zdDsKKyAgdm9pZCBDaGVja1JlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisKKyAgVHlwZSBkZWZfdHlwZSgpIGNvbnN0OworCisgIC8vICJmdWxsbmFtZSIgaXMgdGhlIGRlZidzIGZ1bGx5LXF1YWxpZmllZCBuYW1lIChlZy4gZm9vLmJhci5NZXNzYWdlKS4KKyAgY29uc3QgY2hhciAqZnVsbF9uYW1lKCkgY29uc3Q7CisKKyAgLy8gVGhlIGRlZiBtdXN0IGJlIG11dGFibGUuICBDYWxsZXIgcmV0YWlucyBvd25lcnNoaXAgb2YgZnVsbG5hbWUuICBEZWZzIGFyZQorICAvLyBub3QgcmVxdWlyZWQgdG8gaGF2ZSBhIG5hbWU7IGlmIGEgZGVmIGhhcyBubyBuYW1lIHdoZW4gaXQgaXMgZnJvemVuLCBpdAorICAvLyB3aWxsIHJlbWFpbiBhbiBhbm9ueW1vdXMgZGVmLiAgT24gZmFpbHVyZSwgcmV0dXJucyBmYWxzZSBhbmQgZGV0YWlscyBpbiAicyIKKyAgLy8gaWYgbm9uLU5VTEwuCisgIGJvb2wgc2V0X2Z1bGxfbmFtZShjb25zdCBjaGFyKiBmdWxsbmFtZSwgdXBiOjpTdGF0dXMqIHMpOworICBib29sIHNldF9mdWxsX25hbWUoY29uc3Qgc3RkOjpzdHJpbmcgJmZ1bGxuYW1lLCB1cGI6OlN0YXR1cyogcyk7CisKKyAgLy8gRnJlZXplcyB0aGUgZ2l2ZW4gZGVmczsgdGhpcyB2YWxpZGF0ZXMgYWxsIGNvbnN0cmFpbnRzIGFuZCBtYXJrcyB0aGUgZGVmcworICAvLyBhcyBmcm96ZW4gKHJlYWQtb25seSkuICAiZGVmcyIgbWF5IG5vdCBjb250YWluIGFueSBmaWVsZGRlZnMsIGJ1dCBmaWVsZHMKKyAgLy8gb2YgYW55IG1zZ2RlZnMgd2lsbCBiZSBmcm96ZW4uCisgIC8vCisgIC8vIFN5bWJvbGljIHJlZmVyZW5jZXMgdG8gc3ViLXR5cGVzIGFuZCBlbnVtIGRlZmF1bHRzIG11c3QgaGF2ZSBhbHJlYWR5IGJlZW4KKyAgLy8gcmVzb2x2ZWQuICBBbnkgbXV0YWJsZSBkZWZzIHJlYWNoYWJsZSBmcm9tIGFueSBvZiAiZGVmcyIgbXVzdCBhbHNvIGJlIGluCisgIC8vIHRoZSBsaXN0OyBtb3JlIGZvcm1hbGx5LCAiZGVmcyIgbXVzdCBiZSBhIHRyYW5zaXRpdmUgY2xvc3VyZSBvZiBtdXRhYmxlCisgIC8vIGRlZnMuCisgIC8vCisgIC8vIEFmdGVyIHRoaXMgb3BlcmF0aW9uIHN1Y2NlZWRzLCB0aGUgZmluYWxpemVkIGRlZnMgbXVzdCBvbmx5IGJlIGFjY2Vzc2VkCisgIC8vIHRocm91Z2ggYSBjb25zdCBwb2ludGVyIQorICBzdGF0aWMgYm9vbCBGcmVlemUoRGVmKiBjb25zdCogZGVmcywgaW50IG4sIFN0YXR1cyogc3RhdHVzKTsKKyAgc3RhdGljIGJvb2wgRnJlZXplKGNvbnN0IHN0ZDo6dmVjdG9yPERlZio+JiBkZWZzLCBTdGF0dXMqIHN0YXR1cyk7CisKKyBwcml2YXRlOgorICBVUEJfRElTQUxMT1dfUE9EX09QUyhEZWYsIHVwYjo6RGVmKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUKHVwYl9kZWYsIHVwYl9yZWZjb3VudGVkLAorICBjb25zdCBjaGFyICpmdWxsbmFtZTsKKyAgdXBiX2RlZnR5cGVfdCB0eXBlIDogODsKKyAgLy8gVXNlZCBhcyBhIGZsYWcgZHVyaW5nIHRoZSBkZWYncyBtdXRhYmxlIHN0YWdlLiAgTXVzdCBiZSBmYWxzZSB1bmxlc3MKKyAgLy8gaXQgaXMgY3VycmVudGx5IGJlaW5nIHVzZWQgYnkgYSBmdW5jdGlvbiBvbiB0aGUgc3RhY2suICBUaGlzIGFsbG93cworICAvLyB1cyB0byBlYXNpbHkgZGV0ZXJtaW5lIHdoaWNoIGRlZnMgd2VyZSBwYXNzZWQgaW50byB0aGUgZnVuY3Rpb24ncworICAvLyBjdXJyZW50IGludm9jYXRpb24uCisgIGJvb2wgY2FtZV9mcm9tX3VzZXI7CispKTsKKworI2RlZmluZSBVUEJfREVGX0lOSVQobmFtZSwgdHlwZSwgcmVmcywgcmVmMnMpIFwKKyAgICB7IFVQQl9SRUZDT1VOVF9JTklUKHJlZnMsIHJlZjJzKSwgbmFtZSwgdHlwZSwgZmFsc2UgfQorCitVUEJfQkVHSU5fRVhURVJOX0MgIC8vIHsKKworLy8gTmF0aXZlIEMgQVBJLgordXBiX2RlZiAqdXBiX2RlZl9kdXAoY29uc3QgdXBiX2RlZiAqZGVmLCBjb25zdCB2b2lkICpvd25lcik7CisKKy8vIEZyb20gdXBiX3JlZmNvdW50ZWQuCitib29sIHVwYl9kZWZfaXNmcm96ZW4oY29uc3QgdXBiX2RlZiAqZGVmKTsKK3ZvaWQgdXBiX2RlZl9yZWYoY29uc3QgdXBiX2RlZiAqZGVmLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9kZWZfdW5yZWYoY29uc3QgdXBiX2RlZiAqZGVmLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9kZWZfZG9uYXRlcmVmKGNvbnN0IHVwYl9kZWYgKmRlZiwgY29uc3Qgdm9pZCAqZnJvbSwgY29uc3Qgdm9pZCAqdG8pOwordm9pZCB1cGJfZGVmX2NoZWNrcmVmKGNvbnN0IHVwYl9kZWYgKmRlZiwgY29uc3Qgdm9pZCAqb3duZXIpOworCit1cGJfZGVmdHlwZV90IHVwYl9kZWZfdHlwZShjb25zdCB1cGJfZGVmICpkKTsKK2NvbnN0IGNoYXIgKnVwYl9kZWZfZnVsbG5hbWUoY29uc3QgdXBiX2RlZiAqZCk7Citib29sIHVwYl9kZWZfc2V0ZnVsbG5hbWUodXBiX2RlZiAqZGVmLCBjb25zdCBjaGFyICpmdWxsbmFtZSwgdXBiX3N0YXR1cyAqcyk7Citib29sIHVwYl9kZWZfZnJlZXplKHVwYl9kZWYgKmNvbnN0ICpkZWZzLCBpbnQgbiwgdXBiX3N0YXR1cyAqcyk7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworCisvKiB1cGI6OkRlZiBjYXN0cyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjaWZkZWYgX19jcGx1c3BsdXMKKyNkZWZpbmUgVVBCX0NQUF9DQVNUUyhjbmFtZSwgY3BwdHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIG5hbWVzcGFjZSB1cGIgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGNwcHR5cGUgKmRvd25fY2FzdDxjcHB0eXBlICosIERlZj4oRGVmICogZGVmKSB7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHVwYl9kb3duY2FzdF8jI2NuYW1lIyNfbXV0YWJsZShkZWYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBjcHB0eXBlICpkeW5fY2FzdDxjcHB0eXBlICosIERlZj4oRGVmICogZGVmKSB7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiB1cGJfZHluY2FzdF8jI2NuYW1lIyNfbXV0YWJsZShkZWYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgY29uc3QgY3BwdHlwZSAqZG93bl9jYXN0PGNvbnN0IGNwcHR5cGUgKiwgY29uc3QgRGVmPiggICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IERlZiAqZGVmKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHVwYl9kb3duY2FzdF8jI2NuYW1lKGRlZik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBjb25zdCBjcHB0eXBlICpkeW5fY2FzdDxjb25zdCBjcHB0eXBlICosIGNvbnN0IERlZj4oY29uc3QgRGVmICpkZWYpIHsgXAorICAgIHJldHVybiB1cGJfZHluY2FzdF8jI2NuYW1lKGRlZik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgY29uc3QgY3BwdHlwZSAqZG93bl9jYXN0PGNvbnN0IGNwcHR5cGUgKiwgRGVmPihEZWYgKiBkZWYpIHsgICAgICAgICAgIFwKKyAgICByZXR1cm4gdXBiX2Rvd25jYXN0XyMjY25hbWUoZGVmKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGNvbnN0IGNwcHR5cGUgKmR5bl9jYXN0PGNvbnN0IGNwcHR5cGUgKiwgRGVmPihEZWYgKiBkZWYpIHsgICAgICAgICAgICBcCisgICAgcmV0dXJuIHVwYl9keW5jYXN0XyMjY25hbWUoZGVmKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgLy8gbmFtZXNwYWNlIHVwYgorI2Vsc2UKKyNkZWZpbmUgVVBCX0NQUF9DQVNUUyhjbmFtZSwgY3BwdHlwZSkKKyNlbmRpZgorCisvLyBEeW5hbWljIGNhc3RzLCBmb3IgZGV0ZXJtaW5pbmcgaWYgYSBkZWYgaXMgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgYXQgcnVudGltZS4KKy8vIERvd25jYXN0cywgZm9yIHdoZW4gc29tZSB3YW50cyB0byBhc3NlcnQgdGhhdCBhIGRlZiBpcyBvZiBhIHBhcnRpY3VsYXIgdHlwZS4KKy8vIFRoZXNlIGFyZSBvbmx5IGNoZWNrZWQgaWYgd2UgYXJlIGJ1aWxkaW5nIGRlYnVnLgorI2RlZmluZSBVUEJfREVGX0NBU1RTKGxvd2VyLCB1cHBlciwgY3BwdHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVUEJfSU5MSU5FIGNvbnN0IHVwYl8jI2xvd2VyICp1cGJfZHluY2FzdF8jI2xvd2VyKGNvbnN0IHVwYl9kZWYgKmRlZikgeyAgXAorICAgIGlmICh1cGJfZGVmX3R5cGUoZGVmKSAhPSBVUEJfREVGXyMjdXBwZXIpIHJldHVybiBOVUxMOyAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiAodXBiXyMjbG93ZXIgKilkZWY7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVUEJfSU5MSU5FIGNvbnN0IHVwYl8jI2xvd2VyICp1cGJfZG93bmNhc3RfIyNsb3dlcihjb25zdCB1cGJfZGVmICpkZWYpIHsgXAorICAgIGFzc2VydCh1cGJfZGVmX3R5cGUoZGVmKSA9PSBVUEJfREVGXyMjdXBwZXIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiAoY29uc3QgdXBiXyMjbG93ZXIgKilkZWY7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVUEJfSU5MSU5FIHVwYl8jI2xvd2VyICp1cGJfZHluY2FzdF8jI2xvd2VyIyNfbXV0YWJsZSh1cGJfZGVmICpkZWYpIHsgICAgXAorICAgIHJldHVybiAodXBiXyMjbG93ZXIgKil1cGJfZHluY2FzdF8jI2xvd2VyKGRlZik7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVUEJfSU5MSU5FIHVwYl8jI2xvd2VyICp1cGJfZG93bmNhc3RfIyNsb3dlciMjX211dGFibGUodXBiX2RlZiAqZGVmKSB7ICAgXAorICAgIHJldHVybiAodXBiXyMjbG93ZXIgKil1cGJfZG93bmNhc3RfIyNsb3dlcihkZWYpOyAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVUEJfQ1BQX0NBU1RTKGxvd2VyLCBjcHB0eXBlKQorCisjZGVmaW5lIFVQQl9ERUZJTkVfREVGKGNwcG5hbWUsIGxvd2VyLCB1cHBlciwgY3BwbWV0aG9kcywgbWVtYmVycykgICAgICAgICAgICAgXAorICBVUEJfREVGSU5FX0NMQVNTMihjcHBuYW1lLCB1cGI6OkRlZiwgdXBiOjpSZWZDb3VudGVkLCBVUEJfUVVPVEUoY3BwbWV0aG9kcyksIFwKKyAgICAgICAgICAgICAgICAgICBtZW1iZXJzKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFVQQl9ERUZfQ0FTVFMobG93ZXIsIHVwcGVyLCBjcHBuYW1lKQorCisKKy8qIHVwYjo6RmllbGREZWYgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8vIFRoZSB0eXBlcyBhIGZpZWxkIGNhbiBoYXZlLiAgTm90ZSB0aGF0IHRoaXMgbGlzdCBpcyBub3QgaWRlbnRpY2FsIHRvIHRoZQorLy8gdHlwZXMgZGVmaW5lZCBpbiBkZXNjcmlwdG9yLnByb3RvLCB3aGljaCBnaXZlcyBJTlQzMiBhbmQgU0lOVDMyIHNlcGFyYXRlCisvLyB0eXBlcyAod2UgZGlzdGluZ3Vpc2ggdGhlIHR3byB3aXRoIHRoZSAiaW50ZWdlciBlbmNvZGluZyIgZW51bSBiZWxvdykuCit0eXBlZGVmIGVudW0geworICBVUEJfVFlQRV9GTE9BVCAgICA9IDEsCisgIFVQQl9UWVBFX0RPVUJMRSAgID0gMiwKKyAgVVBCX1RZUEVfQk9PTCAgICAgPSAzLAorICBVUEJfVFlQRV9TVFJJTkcgICA9IDQsCisgIFVQQl9UWVBFX0JZVEVTICAgID0gNSwKKyAgVVBCX1RZUEVfTUVTU0FHRSAgPSA2LAorICBVUEJfVFlQRV9FTlVNICAgICA9IDcsICAvLyBFbnVtIHZhbHVlcyBhcmUgaW50MzIuCisgIFVQQl9UWVBFX0lOVDMyICAgID0gOCwKKyAgVVBCX1RZUEVfVUlOVDMyICAgPSA5LAorICBVUEJfVFlQRV9JTlQ2NCAgICA9IDEwLAorICBVUEJfVFlQRV9VSU5UNjQgICA9IDExLAorfSB1cGJfZmllbGR0eXBlX3Q7CisKKy8vIFRoZSByZXBlYXRlZC1uZXNzIG9mIGVhY2ggZmllbGQ7IHRoaXMgbWF0Y2hlcyBkZXNjcmlwdG9yLnByb3RvLgordHlwZWRlZiBlbnVtIHsKKyAgVVBCX0xBQkVMX09QVElPTkFMID0gMSwKKyAgVVBCX0xBQkVMX1JFUVVJUkVEID0gMiwKKyAgVVBCX0xBQkVMX1JFUEVBVEVEID0gMywKK30gdXBiX2xhYmVsX3Q7CisKKy8vIEhvdyBpbnRlZ2VycyBzaG91bGQgYmUgZW5jb2RlZCBpbiBzZXJpYWxpemF0aW9ucyB0aGF0IG9mZmVyIG11bHRpcGxlCisvLyBpbnRlZ2VyIGVuY29kaW5nIG1ldGhvZHMuCit0eXBlZGVmIGVudW0geworICBVUEJfSU5URk1UX1ZBUklBQkxFID0gMSwKKyAgVVBCX0lOVEZNVF9GSVhFRCA9IDIsCisgIFVQQl9JTlRGTVRfWklHWkFHID0gMywgIC8vIE9ubHkgZm9yIHNpZ25lZCB0eXBlcyAoSU5UMzIvSU5UNjQpLgorfSB1cGJfaW50Zm10X3Q7CisKKy8vIERlc2NyaXB0b3IgdHlwZXMsIGFzIGRlZmluZWQgaW4gZGVzY3JpcHRvci5wcm90by4KK3R5cGVkZWYgZW51bSB7CisgIFVQQl9ERVNDUklQVE9SX1RZUEVfRE9VQkxFICAgPSAxLAorICBVUEJfREVTQ1JJUFRPUl9UWVBFX0ZMT0FUICAgID0gMiwKKyAgVVBCX0RFU0NSSVBUT1JfVFlQRV9JTlQ2NCAgICA9IDMsCisgIFVQQl9ERVNDUklQVE9SX1RZUEVfVUlOVDY0ICAgPSA0LAorICBVUEJfREVTQ1JJUFRPUl9UWVBFX0lOVDMyICAgID0gNSwKKyAgVVBCX0RFU0NSSVBUT1JfVFlQRV9GSVhFRDY0ICA9IDYsCisgIFVQQl9ERVNDUklQVE9SX1RZUEVfRklYRUQzMiAgPSA3LAorICBVUEJfREVTQ1JJUFRPUl9UWVBFX0JPT0wgICAgID0gOCwKKyAgVVBCX0RFU0NSSVBUT1JfVFlQRV9TVFJJTkcgICA9IDksCisgIFVQQl9ERVNDUklQVE9SX1RZUEVfR1JPVVAgICAgPSAxMCwKKyAgVVBCX0RFU0NSSVBUT1JfVFlQRV9NRVNTQUdFICA9IDExLAorICBVUEJfREVTQ1JJUFRPUl9UWVBFX0JZVEVTICAgID0gMTIsCisgIFVQQl9ERVNDUklQVE9SX1RZUEVfVUlOVDMyICAgPSAxMywKKyAgVVBCX0RFU0NSSVBUT1JfVFlQRV9FTlVNICAgICA9IDE0LAorICBVUEJfREVTQ1JJUFRPUl9UWVBFX1NGSVhFRDMyID0gMTUsCisgIFVQQl9ERVNDUklQVE9SX1RZUEVfU0ZJWEVENjQgPSAxNiwKKyAgVVBCX0RFU0NSSVBUT1JfVFlQRV9TSU5UMzIgICA9IDE3LAorICBVUEJfREVTQ1JJUFRPUl9UWVBFX1NJTlQ2NCAgID0gMTgsCit9IHVwYl9kZXNjcmlwdG9ydHlwZV90OworCisKKy8vIEEgdXBiX2ZpZWxkZGVmIGRlc2NyaWJlcyBhIHNpbmdsZSBmaWVsZCBpbiBhIG1lc3NhZ2UuICBJdCBpcyBtb3N0IG9mdGVuCisvLyBmb3VuZCBhcyBhIHBhcnQgb2YgYSB1cGJfbXNnZGVmLCBidXQgY2FuIGFsc28gc3RhbmQgYWxvbmUgdG8gcmVwcmVzZW50CisvLyBhbiBleHRlbnNpb24uCisvLworLy8gSXRzIGJhc2UgY2xhc3MgaXMgdXBiOjpEZWYgKHVzZSB1cGI6OnVwY2FzdCgpIHRvIGNvbnZlcnQpLgorVVBCX0RFRklORV9ERUYodXBiOjpGaWVsZERlZiwgZmllbGRkZWYsIEZJRUxELAorIHB1YmxpYzoKKyAgdHlwZWRlZiB1cGJfZmllbGR0eXBlX3QgVHlwZTsKKyAgdHlwZWRlZiB1cGJfbGFiZWxfdCBMYWJlbDsKKyAgdHlwZWRlZiB1cGJfaW50Zm10X3QgSW50ZWdlckZvcm1hdDsKKyAgdHlwZWRlZiB1cGJfZGVzY3JpcHRvcnR5cGVfdCBEZXNjcmlwdG9yVHlwZTsKKworICAvLyBUaGVzZSByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgYSB2YWxpZCBtZW1iZXIgb2YgdGhlIGVudW1lcmF0aW9uLgorICBzdGF0aWMgYm9vbCBDaGVja1R5cGUoaW50MzJfdCB2YWwpOworICBzdGF0aWMgYm9vbCBDaGVja0xhYmVsKGludDMyX3QgdmFsKTsKKyAgc3RhdGljIGJvb2wgQ2hlY2tEZXNjcmlwdG9yVHlwZShpbnQzMl90IHZhbCk7CisgIHN0YXRpYyBib29sIENoZWNrSW50ZWdlckZvcm1hdChpbnQzMl90IHZhbCk7CisKKyAgLy8gVGhlc2UgY29udmVydCB0byB0aGUgZ2l2ZW4gZW51bWVyYXRpb247IHRoZXkgcmVxdWlyZSB0aGF0IHRoZSB2YWx1ZSBpcworICAvLyB2YWxpZC4KKyAgc3RhdGljIFR5cGUgQ29udmVydFR5cGUoaW50MzJfdCB2YWwpOworICBzdGF0aWMgTGFiZWwgQ29udmVydExhYmVsKGludDMyX3QgdmFsKTsKKyAgc3RhdGljIERlc2NyaXB0b3JUeXBlIENvbnZlcnREZXNjcmlwdG9yVHlwZShpbnQzMl90IHZhbCk7CisgIHN0YXRpYyBJbnRlZ2VyRm9ybWF0IENvbnZlcnRJbnRlZ2VyRm9ybWF0KGludDMyX3QgdmFsKTsKKworICAvLyBSZXR1cm5zIE5VTEwgaWYgbWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkLgorICBzdGF0aWMgcmVmZmVkX3B0cjxGaWVsZERlZj4gTmV3KCk7CisKKyAgLy8gRHVwbGljYXRlcyB0aGUgZ2l2ZW4gZmllbGQsIHJldHVybmluZyBOVUxMIGlmIG1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZC4KKyAgLy8gV2hlbiBhIGZpZWxkZGVmIGlzIGR1cGxpY2F0ZWQsIHRoZSBzdWJkZWYgKGlmIGFueSkgaXMgbWFkZSBzeW1ib2xpYyBpZiBpdAorICAvLyB3YXNuJ3QgYWxyZWFkeS4gIElmIHRoZSBzdWJkZWYgaXMgc2V0IGJ1dCBoYXMgbm8gbmFtZSAod2hpY2ggaXMgcG9zc2libGUKKyAgLy8gc2luY2UgbXNnZGVmcyBhcmUgbm90IHJlcXVpcmVkIHRvIGhhdmUgYSBuYW1lKSB0aGUgbmV3IGZpZWxkZGVmJ3Mgc3ViZGVmCisgIC8vIHdpbGwgYmUgdW5zZXQuCisgIEZpZWxkRGVmKiBEdXAoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworCisgIC8vIEZ1bmN0aW9uYWxpdHkgZnJvbSB1cGI6OlJlZkNvdW50ZWQuCisgIGJvb2wgSXNGcm96ZW4oKSBjb25zdDsKKyAgdm9pZCBSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworICB2b2lkIFVucmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBEb25hdGVSZWYoY29uc3Qgdm9pZCogZnJvbSwgY29uc3Qgdm9pZCogdG8pIGNvbnN0OworICB2b2lkIENoZWNrUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpEZWYuCisgIGNvbnN0IGNoYXIqIGZ1bGxfbmFtZSgpIGNvbnN0OworCisgIGJvb2wgdHlwZV9pc19zZXQoKSBjb25zdDsgIC8vIFdoZXRoZXIgc2V0X1tkZXNjcmlwdG9yX110eXBlKCkgaGFzIGJlZW4gY2FsbGVkLgorICBUeXBlIHR5cGUoKSBjb25zdDsgICAgICAgICAvLyBSZXF1aXJlcyB0aGF0IHR5cGVfaXNfc2V0KCkgPT0gdHJ1ZS4KKyAgTGFiZWwgbGFiZWwoKSBjb25zdDsgICAgICAgLy8gRGVmYXVsdHMgdG8gVVBCX0xBQkVMX09QVElPTkFMLgorICBjb25zdCBjaGFyKiBuYW1lKCkgY29uc3Q7ICAvLyBOVUxMIGlmIHVuaW5pdGlhbGl6ZWQuCisgIHVpbnQzMl90IG51bWJlcigpIGNvbnN0OyAgIC8vIFJldHVybnMgMCBpZiB1bmluaXRpYWxpemVkLgorICBib29sIGlzX2V4dGVuc2lvbigpIGNvbnN0OworCisgIC8vIEZvciBVUEJfVFlQRV9NRVNTQUdFIGZpZWxkcyBvbmx5IHdoZXJlIGlzX3RhZ19kZWxpbWl0ZWQoKSA9PSBmYWxzZSwKKyAgLy8gaW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBmaWVsZCBzaG91bGQgaGF2ZSBsYXp5IHBhcnNpbmcgaGFuZGxlcnMgdGhhdCB5aWVsZAorICAvLyB0aGUgdW5wYXJzZWQgc3RyaW5nIGZvciB0aGUgc3VibWVzc2FnZS4KKyAgLy8KKyAgLy8gVE9ETyhoYWJlcm1hbik6IEkgdGhpbmsgd2Ugd2FudCB0byBtb3ZlIHRoaXMgaW50byBhIEZpZWxkT3B0aW9ucyBjb250YWluZXIKKyAgLy8gd2hlbiB3ZSBhZGQgc3VwcG9ydCBmb3IgY3VzdG9tIG9wdGlvbnMgKHRoZSBGaWVsZE9wdGlvbnMgc3RydWN0IHdpbGwKKyAgLy8gY29udGFpbiBib3RoIHJlZ3VsYXIgRmllbGRPcHRpb25zIGxpa2UgImxhenkiICphbmQqIGN1c3RvbSBvcHRpb25zKS4KKyAgYm9vbCBsYXp5KCkgY29uc3Q7CisKKyAgLy8gRm9yIG5vbi1zdHJpbmcsIG5vbi1zdWJtZXNzYWdlIGZpZWxkcywgdGhpcyBpbmRpY2F0ZXMgd2hldGhlciBiaW5hcnkKKyAgLy8gcHJvdG9idWZzIGFyZSBlbmNvZGVkIGluIHBhY2tlZCBvciBub24tcGFja2VkIGZvcm1hdC4KKyAgLy8KKyAgLy8gVE9ETyhoYWJlcm1hbik6IHNlZSBub3RlIGFib3ZlIGFib3V0IHB1dHRpbmcgb3B0aW9ucyBsaWtlIHRoaXMgaW50byBhCisgIC8vIEZpZWxkT3B0aW9ucyBjb250YWluZXIuCisgIGJvb2wgcGFja2VkKCkgY29uc3Q7CisKKyAgLy8gQW4gaW50ZWdlciB0aGF0IGNhbiBiZSB1c2VkIGFzIGFuIGluZGV4IGludG8gYW4gYXJyYXkgb2YgZmllbGRzIGZvcgorICAvLyB3aGF0ZXZlciBtZXNzYWdlIHRoaXMgZmllbGQgYmVsb25ncyB0by4gIEd1YXJhbnRlZWQgdG8gYmUgbGVzcyB0aGFuCisgIC8vIGYtPmNvbnRhaW5pbmdfdHlwZSgpLT5maWVsZF9jb3VudCgpLiAgTWF5IG9ubHkgYmUgYWNjZXNzZWQgb25jZSB0aGUgZGVmIGhhcworICAvLyBiZWVuIGZpbmFsaXplZC4KKyAgaW50IGluZGV4KCkgY29uc3Q7CisKKyAgLy8gVGhlIE1lc3NhZ2VEZWYgdG8gd2hpY2ggdGhpcyBmaWVsZCBiZWxvbmdzLgorICAvLworICAvLyBJZiB0aGlzIGZpZWxkIGhhcyBiZWVuIGFkZGVkIHRvIGEgTWVzc2FnZURlZiwgdGhhdCBtZXNzYWdlIGNhbiBiZSByZXRyaWV2ZWQKKyAgLy8gZGlyZWN0bHkgKHRoaXMgaXMgYWx3YXlzIHRoZSBjYXNlIGZvciBmcm96ZW4gRmllbGREZWZzKS4KKyAgLy8KKyAgLy8gSWYgdGhlIGZpZWxkIGhhcyBub3QgeWV0IGJlZW4gYWRkZWQgdG8gYSBNZXNzYWdlRGVmLCB5b3UgY2FuIHNldCB0aGUgbmFtZQorICAvLyBvZiB0aGUgY29udGFpbmluZyB0eXBlIHN5bWJvbGljYWxseSBpbnN0ZWFkLiAgVGhpcyBpcyBtb3N0bHkgdXNlZnVsIGZvcgorICAvLyBleHRlbnNpb25zLCB3aGVyZSB0aGUgZXh0ZW5zaW9uIGlzIGRlY2xhcmVkIHNlcGFyYXRlbHkgZnJvbSB0aGUgbWVzc2FnZS4KKyAgY29uc3QgTWVzc2FnZURlZiogY29udGFpbmluZ190eXBlKCkgY29uc3Q7CisgIGNvbnN0IGNoYXIqIGNvbnRhaW5pbmdfdHlwZV9uYW1lKCk7CisKKyAgLy8gVGhlIE9uZW9mRGVmIHRvIHdoaWNoIHRoaXMgZmllbGQgYmVsb25ncywgb3IgTlVMTCBpZiB0aGlzIGZpZWxkIGlzIG5vdCBwYXJ0CisgIC8vIG9mIGEgb25lb2YuCisgIGNvbnN0IE9uZW9mRGVmKiBjb250YWluaW5nX29uZW9mKCkgY29uc3Q7CisKKyAgLy8gVGhlIGZpZWxkJ3MgdHlwZSBhY2NvcmRpbmcgdG8gdGhlIGVudW0gaW4gZGVzY3JpcHRvci5wcm90by4gIFRoaXMgaXMgbm90CisgIC8vIHRoZSBzYW1lIGFzIFVQQl9UWVBFXyosIGJlY2F1c2UgaXQgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIChmb3IgZXhhbXBsZSkKKyAgLy8gSU5UMzIgYW5kIFNJTlQzMiwgd2hlcmVhcyBvdXIgInR5cGUiIGVudW0gZG9lcyBub3QuICBUaGlzIHJldHVybiBvZgorICAvLyBkZXNjcmlwdG9yX3R5cGUoKSBpcyBhIGZ1bmN0aW9uIG9mIHR5cGUoKSwgaW50ZWdlcl9mb3JtYXQoKSwgYW5kCisgIC8vIGlzX3RhZ19kZWxpbWl0ZWQoKS4gIExpa2V3aXNlIHNldF9kZXNjcmlwdG9yX3R5cGUoKSBzZXRzIGFsbCB0aHJlZQorICAvLyBhcHByb3ByaWF0ZWx5LgorICBEZXNjcmlwdG9yVHlwZSBkZXNjcmlwdG9yX3R5cGUoKSBjb25zdDsKKworICAvLyBDb252ZW5pZW50IGZpZWxkIHR5cGUgdGVzdHMuCisgIGJvb2wgSXNTdWJNZXNzYWdlKCkgY29uc3Q7CisgIGJvb2wgSXNTdHJpbmcoKSBjb25zdDsKKyAgYm9vbCBJc1NlcXVlbmNlKCkgY29uc3Q7CisgIGJvb2wgSXNQcmltaXRpdmUoKSBjb25zdDsKKyAgYm9vbCBJc01hcCgpIGNvbnN0OworCisgIC8vIEhvdyBpbnRlZ2VycyBhcmUgZW5jb2RlZC4gIE9ubHkgbWVhbmluZ2Z1bCBmb3IgaW50ZWdlciB0eXBlcy4KKyAgLy8gRGVmYXVsdHMgdG8gVVBCX0lOVEZNVF9WQVJJQUJMRSwgYW5kIGlzIHJlc2V0IHdoZW4gInR5cGUiIGNoYW5nZXMuCisgIEludGVnZXJGb3JtYXQgaW50ZWdlcl9mb3JtYXQoKSBjb25zdDsKKworICAvLyBXaGV0aGVyIGEgc3VibWVzc2FnZSBmaWVsZCBpcyB0YWctZGVsaW1pdGVkIG9yIG5vdCAoaWYgZmFsc2UsIHRoZW4KKyAgLy8gbGVuZ3RoLWRlbGltaXRlZCkuICBNYXkgb25seSBiZSBzZXQgd2hlbiB0eXBlKCkgPT0gVVBCX1RZUEVfTUVTU0FHRS4KKyAgYm9vbCBpc190YWdfZGVsaW1pdGVkKCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0aGUgbm9uLXN0cmluZyBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIGZpZWxkZGVmLCB3aGljaCBtYXkgZWl0aGVyCisgIC8vIGJlIHNvbWV0aGluZyB0aGUgY2xpZW50IHNldCBleHBsaWNpdGx5IG9yIHRoZSAiZGVmYXVsdCBkZWZhdWx0IiAoMCBmb3IKKyAgLy8gbnVtYmVycywgZW1wdHkgZm9yIHN0cmluZ3MpLiAgVGhlIGZpZWxkJ3MgdHlwZSBpbmRpY2F0ZXMgdGhlIHR5cGUgb2YgdGhlCisgIC8vIHJldHVybmVkIHZhbHVlLCBleGNlcHQgZm9yIGVudW0gZmllbGRzIHRoYXQgYXJlIHN0aWxsIG11dGFibGUuCisgIC8vCisgIC8vIFJlcXVpcmVzIHRoYXQgdGhlIGdpdmVuIGZ1bmN0aW9uIG1hdGNoZXMgdGhlIGZpZWxkJ3MgY3VycmVudCB0eXBlLgorICBpbnQ2NF90IGRlZmF1bHRfaW50NjQoKSBjb25zdDsKKyAgaW50MzJfdCBkZWZhdWx0X2ludDMyKCkgY29uc3Q7CisgIHVpbnQ2NF90IGRlZmF1bHRfdWludDY0KCkgY29uc3Q7CisgIHVpbnQzMl90IGRlZmF1bHRfdWludDMyKCkgY29uc3Q7CisgIGJvb2wgZGVmYXVsdF9ib29sKCkgY29uc3Q7CisgIGZsb2F0IGRlZmF1bHRfZmxvYXQoKSBjb25zdDsKKyAgZG91YmxlIGRlZmF1bHRfZG91YmxlKCkgY29uc3Q7CisKKyAgLy8gVGhlIHJlc3VsdGluZyBzdHJpbmcgaXMgYWx3YXlzIE5VTEwtdGVybWluYXRlZC4gIElmIG5vbi1OVUxMLCB0aGUgbGVuZ3RoCisgIC8vIHdpbGwgYmUgc3RvcmVkIGluICpsZW4uCisgIGNvbnN0IGNoYXIgKmRlZmF1bHRfc3RyaW5nKHNpemVfdCogbGVuKSBjb25zdDsKKworICAvLyBGb3IgZnJvemVuIFVQQl9UWVBFX0VOVU0gZmllbGRzLCBlbnVtIGRlZmF1bHRzIGNhbiBhbHdheXMgYmUgcmVhZCBhcyBlaXRoZXIKKyAgLy8gc3RyaW5nIG9yIGludDMyLCBhbmQgYm90aCBvZiB0aGVzZSBtZXRob2RzIHdpbGwgYWx3YXlzIHJldHVybiB0cnVlLgorICAvLworICAvLyBGb3IgbXV0YWJsZSBVUEJfVFlQRV9FTlVNIGZpZWxkcywgdGhlIHN0b3J5IGlzIGEgYml0IG1vcmUgY29tcGxpY2F0ZWQuCisgIC8vIEVudW0gZGVmYXVsdHMgYXJlIHVudXN1YWwuIFRoZXkgY2FuIGJlIHNwZWNpZmllZCBlaXRoZXIgYXMgc3RyaW5nIG9yIGludDMyLAorICAvLyBidXQgdG8gYmUgdmFsaWQgdGhlIGVudW0gbXVzdCBoYXZlIHRoYXQgdmFsdWUgYXMgYSBtZW1iZXIuICBBbmQgaWYgbm8KKyAgLy8gZGVmYXVsdCBpcyBzcGVjaWZpZWQsIHRoZSAiZGVmYXVsdCBkZWZhdWx0IiBjb21lcyBmcm9tIHRoZSBFbnVtRGVmLgorICAvLworICAvLyBXZSBhbGxvdyByZWFkaW5nIHRoZSBkZWZhdWx0IGFzIGVpdGhlciBhbiBpbnQzMiBvciBhIHN0cmluZywgYnV0IG9ubHkgaWYKKyAgLy8gd2UgaGF2ZSBhIG1lYW5pbmdmdWwgdmFsdWUgdG8gcmVwb3J0LiAgV2UgaGF2ZSBhIG1lYW5pbmdmdWwgdmFsdWUgaWYgaXQgd2FzCisgIC8vIHNldCBleHBsaWNpdGx5LCBvciBpZiB3ZSBjb3VsZCBnZXQgdGhlICJkZWZhdWx0IGRlZmF1bHQiIGZyb20gdGhlIEVudW1EZWYuCisgIC8vIEFsc28gaWYgeW91IGV4cGxpY2l0bHkgc2V0IHRoZSBuYW1lIGFuZCB3ZSBmaW5kIHRoZSBudW1iZXIgaW4gdGhlIEVudW1EZWYKKyAgYm9vbCBFbnVtSGFzU3RyaW5nRGVmYXVsdCgpIGNvbnN0OworICBib29sIEVudW1IYXNJbnQzMkRlZmF1bHQoKSBjb25zdDsKKworICAvLyBTdWJtZXNzYWdlIGFuZCBlbnVtIGZpZWxkcyBtdXN0IHJlZmVyZW5jZSBhICJzdWJkZWYiLCB3aGljaCBpcyB0aGUKKyAgLy8gdXBiOjpNZXNzYWdlRGVmIG9yIHVwYjo6RW51bURlZiB0aGF0IGRlZmluZXMgdGhlaXIgdHlwZS4gIE5vdGUgdGhhdCB3aGVuCisgIC8vIHRoZSBGaWVsZERlZiBpcyBtdXRhYmxlIGl0IG1heSBub3QgaGF2ZSBhIHN1YmRlZiAqeWV0KiwgYnV0IHRoaXMgZnVuY3Rpb24KKyAgLy8gc3RpbGwgcmV0dXJucyB0cnVlIHRvIGluZGljYXRlIHRoYXQgdGhlIGZpZWxkJ3MgdHlwZSByZXF1aXJlcyBhIHN1YmRlZi4KKyAgYm9vbCBIYXNTdWJEZWYoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRoZSBlbnVtIG9yIHN1Ym1lc3NhZ2UgZGVmIGZvciB0aGlzIGZpZWxkLCBpZiBhbnkuICBUaGUgZmllbGQncworICAvLyB0eXBlIG11c3QgbWF0Y2ggKGllLiB5b3UgbWF5IG9ubHkgY2FsbCBlbnVtX3N1YmRlZigpIGZvciBmaWVsZHMgd2hlcmUKKyAgLy8gdHlwZSgpID09IFVQQl9UWVBFX0VOVU0pLiAgUmV0dXJucyBOVUxMIGlmIHRoZSBzdWJkZWYgaGFzIG5vdCBiZWVuIHNldCBvcgorICAvLyBpcyBjdXJyZW50bHkgc2V0IHN5bWJvbGljYWxseS4KKyAgY29uc3QgRW51bURlZiogZW51bV9zdWJkZWYoKSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZURlZiogbWVzc2FnZV9zdWJkZWYoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRoZSBnZW5lcmljIHN1YmRlZiBmb3IgdGhpcyBmaWVsZC4gIFJlcXVpcmVzIHRoYXQgSGFzU3ViRGVmKCkgKGllLgorICAvLyBvbmx5IHdvcmtzIGZvciBVUEJfVFlQRV9FTlVNIGFuZCBVUEJfVFlQRV9NRVNTQUdFIGZpZWxkcykuCisgIGNvbnN0IERlZiogc3ViZGVmKCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0aGUgc3ltYm9saWMgbmFtZSBvZiB0aGUgc3ViZGVmLiAgSWYgdGhlIHN1YmRlZiBpcyBjdXJyZW50bHkgc2V0CisgIC8vIHVucmVzb2x2ZWQgKGllLiBzZXQgc3ltYm9saWNhbGx5KSByZXR1cm5zIHRoZSBzeW1ib2xpYyBuYW1lLiAgSWYgaXQgaGFzCisgIC8vIGJlZW4gcmVzb2x2ZWQgdG8gYSBzcGVjaWZpYyBzdWJkZWYsIHJldHVybnMgdGhlIG5hbWUgZnJvbSB0aGF0IHN1YmRlZi4KKyAgY29uc3QgY2hhciogc3ViZGVmX25hbWUoKSBjb25zdDsKKworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgLy8gU2V0dGVycyAobm9uLWNvbnN0IG1ldGhvZHMpLCBvbmx5IHZhbGlkIGZvciBtdXRhYmxlIEZpZWxkRGVmcyEKKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgYm9vbCBzZXRfZnVsbF9uYW1lKGNvbnN0IGNoYXIqIGZ1bGxuYW1lLCB1cGI6OlN0YXR1cyogcyk7CisgIGJvb2wgc2V0X2Z1bGxfbmFtZShjb25zdCBzdGQ6OnN0cmluZyYgZnVsbG5hbWUsIHVwYjo6U3RhdHVzKiBzKTsKKworICAvLyBUaGlzIG1heSBvbmx5IGJlIGNhbGxlZCBpZiBjb250YWluaW5nX3R5cGUoKSA9PSBOVUxMIChpZS4gdGhlIGZpZWxkIGhhcyBub3QKKyAgLy8gYmVlbiBhZGRlZCB0byBhIG1lc3NhZ2UgeWV0KS4KKyAgYm9vbCBzZXRfY29udGFpbmluZ190eXBlX25hbWUoY29uc3QgY2hhciAqbmFtZSwgU3RhdHVzKiBzdGF0dXMpOworICBib29sIHNldF9jb250YWluaW5nX3R5cGVfbmFtZShjb25zdCBzdGQ6OnN0cmluZyYgbmFtZSwgU3RhdHVzKiBzdGF0dXMpOworCisgIC8vIERlZmF1bHRzIHRvIGZhbHNlLiAgV2hlbiB3ZSBmcmVlemUsIHdlIGVuc3VyZSB0aGF0IHRoaXMgY2FuIG9ubHkgYmUgdHJ1ZQorICAvLyBmb3IgbGVuZ3RoLWRlbGltaXRlZCBtZXNzYWdlIGZpZWxkcy4gIFByaW9yIHRvIGZyZWV6aW5nIHRoaXMgY2FuIGJlIHRydWUgb3IKKyAgLy8gZmFsc2Ugd2l0aCBubyByZXN0cmljdGlvbnMuCisgIHZvaWQgc2V0X2xhenkoYm9vbCBsYXp5KTsKKworICAvLyBEZWZhdWx0cyB0byB0cnVlLiAgU2V0cyB3aGV0aGVyIHRoaXMgZmllbGQgaXMgZW5jb2RlZCBpbiBwYWNrZWQgZm9ybWF0LgorICB2b2lkIHNldF9wYWNrZWQoYm9vbCBwYWNrZWQpOworCisgIC8vICJ0eXBlIiBvciAiZGVzY3JpcHRvcl90eXBlIiBNVVNUIGJlIHNldCBleHBsaWNpdGx5IGJlZm9yZSB0aGUgZmllbGRkZWYgaXMKKyAgLy8gZmluYWxpemVkLiAgVGhlc2Ugc2V0dGVycyByZXF1aXJlIHRoYXQgdGhlIGVudW0gdmFsdWUgaXMgdmFsaWQ7IGlmIHRoZQorICAvLyB2YWx1ZSBkaWQgbm90IGNvbWUgZGlyZWN0bHkgZnJvbSBhbiBlbnVtIGNvbnN0YW50LCB0aGUgY2FsbGVyIHNob3VsZAorICAvLyB2YWxpZGF0ZSBpdCBmaXJzdCB3aXRoIHRoZSBmdW5jdGlvbnMgYWJvdmUgKENoZWNrRmllbGRUeXBlKCksIGV0YykuCisgIHZvaWQgc2V0X3R5cGUoVHlwZSB0eXBlKTsKKyAgdm9pZCBzZXRfbGFiZWwoTGFiZWwgbGFiZWwpOworICB2b2lkIHNldF9kZXNjcmlwdG9yX3R5cGUoRGVzY3JpcHRvclR5cGUgdHlwZSk7CisgIHZvaWQgc2V0X2lzX2V4dGVuc2lvbihib29sIGlzX2V4dGVuc2lvbik7CisKKyAgLy8gIm51bWJlciIgYW5kICJuYW1lIiBtdXN0IGJlIHNldCBiZWZvcmUgdGhlIEZpZWxkRGVmIGlzIGFkZGVkIHRvIGEKKyAgLy8gTWVzc2FnZURlZiwgYW5kIG1heSBub3QgYmUgc2V0IGFmdGVyIHRoYXQuCisgIC8vCisgIC8vICJuYW1lIiBpcyB0aGUgc2FtZSBhcyBmdWxsX25hbWUoKS9zZXRfZnVsbF9uYW1lKCksIGJ1dCBzaW5jZSBmaWVsZGRlZnMKKyAgLy8gbW9zdCBvZnRlbiB1c2Ugc2ltcGxlLCBub24tcXVhbGlmaWVkIG5hbWVzLCB3ZSBwcm92aWRlIHRoaXMgYWNjZXNzb3IKKyAgLy8gYWxzby4gIEdlbmVyYWxseSBvbmx5IGV4dGVuc2lvbnMgd2lsbCB3YW50IHRvIHRoaW5rIG9mIHRoaXMgbmFtZSBhcworICAvLyBmdWxseS1xdWFsaWZpZWQuCisgIGJvb2wgc2V0X251bWJlcih1aW50MzJfdCBudW1iZXIsIHVwYjo6U3RhdHVzKiBzKTsKKyAgYm9vbCBzZXRfbmFtZShjb25zdCBjaGFyKiBuYW1lLCB1cGI6OlN0YXR1cyogcyk7CisgIGJvb2wgc2V0X25hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUsIHVwYjo6U3RhdHVzKiBzKTsKKworICB2b2lkIHNldF9pbnRlZ2VyX2Zvcm1hdChJbnRlZ2VyRm9ybWF0IGZvcm1hdCk7CisgIGJvb2wgc2V0X3RhZ19kZWxpbWl0ZWQoYm9vbCB0YWdfZGVsaW1pdGVkLCB1cGI6OlN0YXR1cyogcyk7CisKKyAgLy8gU2V0cyBkZWZhdWx0IHZhbHVlIGZvciB0aGUgZmllbGQuICBUaGUgY2FsbCBtdXN0IGV4YWN0bHkgbWF0Y2ggdGhlIHR5cGUKKyAgLy8gb2YgdGhlIGZpZWxkLiAgRW51bSBmaWVsZHMgbWF5IHVzZSBlaXRoZXIgc2V0aW50MzIgb3Igc2V0c3RyaW5nIHRvIHNldAorICAvLyB0aGUgZGVmYXVsdCBudW1lcmljYWxseSBvciBzeW1ib2xpY2FsbHksIHJlc3BlY3RpdmVseSwgYnV0IHN5bWJvbGljCisgIC8vIGRlZmF1bHRzIG11c3QgYmUgcmVzb2x2ZWQgYmVmb3JlIGZpbmFsaXppbmcgKHNlZSBSZXNvbHZlRW51bURlZmF1bHQoKSkuCisgIC8vCisgIC8vIENoYW5naW5nIHRoZSB0eXBlIG9mIGEgZmllbGQgd2lsbCByZXNldCBpdHMgZGVmYXVsdC4KKyAgdm9pZCBzZXRfZGVmYXVsdF9pbnQ2NChpbnQ2NF90IHZhbCk7CisgIHZvaWQgc2V0X2RlZmF1bHRfaW50MzIoaW50MzJfdCB2YWwpOworICB2b2lkIHNldF9kZWZhdWx0X3VpbnQ2NCh1aW50NjRfdCB2YWwpOworICB2b2lkIHNldF9kZWZhdWx0X3VpbnQzMih1aW50MzJfdCB2YWwpOworICB2b2lkIHNldF9kZWZhdWx0X2Jvb2woYm9vbCB2YWwpOworICB2b2lkIHNldF9kZWZhdWx0X2Zsb2F0KGZsb2F0IHZhbCk7CisgIHZvaWQgc2V0X2RlZmF1bHRfZG91YmxlKGRvdWJsZSB2YWwpOworICBib29sIHNldF9kZWZhdWx0X3N0cmluZyhjb25zdCB2b2lkICpzdHIsIHNpemVfdCBsZW4sIFN0YXR1cyAqcyk7CisgIGJvb2wgc2V0X2RlZmF1bHRfc3RyaW5nKGNvbnN0IHN0ZDo6c3RyaW5nICZzdHIsIFN0YXR1cyAqcyk7CisgIHZvaWQgc2V0X2RlZmF1bHRfY3N0cihjb25zdCBjaGFyICpzdHIsIFN0YXR1cyAqcyk7CisKKyAgLy8gQmVmb3JlIGEgZmllbGRkZWYgaXMgZnJvemVuLCBpdHMgc3ViZGVmIG1heSBiZSBzZXQgZWl0aGVyIGRpcmVjdGx5ICh3aXRoIGEKKyAgLy8gdXBiOjpEZWYqKSBvciBzeW1ib2xpY2FsbHkuICBTeW1ib2xpYyByZWZzIG11c3QgYmUgcmVzb2x2ZWQgYmVmb3JlIHRoZQorICAvLyBjb250YWluaW5nIG1zZ2RlZiBjYW4gYmUgZnJvemVuIChzZWUgdXBiX3Jlc29sdmUoKSBhYm92ZSkuICB1cGIgYWx3YXlzCisgIC8vIGd1YXJhbnRlZXMgdGhhdCBhbnkgZGVmIHJlYWNoYWJsZSBmcm9tIGEgbGl2ZSBkZWYgd2lsbCBhbHNvIGJlIGtlcHQgYWxpdmUuCisgIC8vCisgIC8vIEJvdGggbWV0aG9kcyByZXF1aXJlIHRoYXQgdXBiX2hhc3N1YmRlZihmKSAoc28gdGhlIHR5cGUgbXVzdCBiZSBzZXQgcHJpb3IKKyAgLy8gdG8gY2FsbGluZyB0aGVzZSBtZXRob2RzKS4gIFJldHVybnMgZmFsc2UgaWYgdGhpcyBpcyBub3QgdGhlIGNhc2UsIG9yIGlmCisgIC8vIHRoZSBnaXZlbiBzdWJkZWYgaXMgbm90IG9mIHRoZSBjb3JyZWN0IHR5cGUuICBUaGUgc3ViZGVmIGlzIHJlc2V0IGlmIHRoZQorICAvLyBmaWVsZCdzIHR5cGUgaXMgY2hhbmdlZC4gIFRoZSBzdWJkZWYgY2FuIGJlIHNldCB0byBOVUxMIHRvIGNsZWFyIGl0LgorICBib29sIHNldF9zdWJkZWYoY29uc3QgRGVmKiBzdWJkZWYsIFN0YXR1cyogcyk7CisgIGJvb2wgc2V0X2VudW1fc3ViZGVmKGNvbnN0IEVudW1EZWYqIHN1YmRlZiwgU3RhdHVzKiBzKTsKKyAgYm9vbCBzZXRfbWVzc2FnZV9zdWJkZWYoY29uc3QgTWVzc2FnZURlZiogc3ViZGVmLCBTdGF0dXMqIHMpOworICBib29sIHNldF9zdWJkZWZfbmFtZShjb25zdCBjaGFyKiBuYW1lLCBTdGF0dXMqIHMpOworICBib29sIHNldF9zdWJkZWZfbmFtZShjb25zdCBzdGQ6OnN0cmluZyAmbmFtZSwgU3RhdHVzKiBzKTsKKworIHByaXZhdGU6CisgIFVQQl9ESVNBTExPV19QT0RfT1BTKEZpZWxkRGVmLCB1cGI6OkZpZWxkRGVmKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUKHVwYl9maWVsZGRlZiwgdXBiX2RlZiwKKyAgdW5pb24geworICAgIGludDY0X3Qgc2ludDsKKyAgICB1aW50NjRfdCB1aW50OworICAgIGRvdWJsZSBkYmw7CisgICAgZmxvYXQgZmx0OworICAgIHZvaWQgKmJ5dGVzOworICB9IGRlZmF1bHR2YWw7CisgIHVuaW9uIHsKKyAgICBjb25zdCB1cGJfbXNnZGVmICpkZWY7ICAvLyBJZiAhbXNnX2lzX3N5bWJvbGljLgorICAgIGNoYXIgKm5hbWU7ICAgICAgICAgICAgIC8vIElmIG1zZ19pc19zeW1ib2xpYy4KKyAgfSBtc2c7CisgIHVuaW9uIHsKKyAgICBjb25zdCB1cGJfZGVmICpkZWY7ICAvLyBJZiAhc3ViZGVmX2lzX3N5bWJvbGljLgorICAgIGNoYXIgKm5hbWU7ICAgICAgICAgIC8vIElmIHN1YmRlZl9pc19zeW1ib2xpYy4KKyAgfSBzdWI7ICAvLyBUaGUgbXNnZGVmIG9yIGVudW1kZWYgZm9yIHRoaXMgZmllbGQsIGlmIHVwYl9oYXNzdWJkZWYoZikuCisgIGJvb2wgc3ViZGVmX2lzX3N5bWJvbGljOworICBib29sIG1zZ19pc19zeW1ib2xpYzsKKyAgY29uc3QgdXBiX29uZW9mZGVmICpvbmVvZjsKKyAgYm9vbCBkZWZhdWx0X2lzX3N0cmluZzsKKyAgYm9vbCB0eXBlX2lzX3NldF87ICAgICAvLyBGYWxzZSB1bnRpbCB0eXBlIGlzIGV4cGxpY2l0bHkgc2V0LgorICBib29sIGlzX2V4dGVuc2lvbl87CisgIGJvb2wgbGF6eV87CisgIGJvb2wgcGFja2VkXzsKKyAgdXBiX2ludGZtdF90IGludGZtdDsKKyAgYm9vbCB0YWdkZWxpbTsKKyAgdXBiX2ZpZWxkdHlwZV90IHR5cGVfOworICB1cGJfbGFiZWxfdCBsYWJlbF87CisgIHVpbnQzMl90IG51bWJlcl87CisgIHVpbnQzMl90IHNlbGVjdG9yX2Jhc2U7ICAvLyBVc2VkIHRvIGluZGV4IGludG8gYSB1cGI6OkhhbmRsZXJzIHRhYmxlLgorICB1aW50MzJfdCBpbmRleF87CispKTsKKworI2RlZmluZSBVUEJfRklFTERERUZfSU5JVChsYWJlbCwgdHlwZSwgaW50Zm10LCB0YWdkZWxpbSwgaXNfZXh0ZW5zaW9uLCBsYXp5LCAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2VkLCBuYW1lLCBudW0sIG1zZ2RlZiwgc3ViZGVmLCBzZWxlY3Rvcl9iYXNlLCAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4LCBkZWZhdWx0dmFsLCByZWZzLCByZWYycykgICAgICAgICAgICAgICAgICAgICAgXAorICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBVUEJfREVGX0lOSVQobmFtZSwgVVBCX0RFRl9GSUVMRCwgcmVmcywgcmVmMnMpLCBkZWZhdWx0dmFsLCB7bXNnZGVmfSwgICAgICBcCisgICAgICAgIHtzdWJkZWZ9LCBOVUxMLCBmYWxzZSwgZmFsc2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICB0eXBlID09IFVQQl9UWVBFX1NUUklORyB8fCB0eXBlID09IFVQQl9UWVBFX0JZVEVTLCB0cnVlLCBpc19leHRlbnNpb24sIFwKKyAgICAgICAgbGF6eSwgcGFja2VkLCBpbnRmbXQsIHRhZ2RlbGltLCB0eXBlLCBsYWJlbCwgbnVtLCBzZWxlY3Rvcl9iYXNlLCBpbmRleCBcCisgIH0KKworVVBCX0JFR0lOX0VYVEVSTl9DICAvLyB7CisKKy8vIE5hdGl2ZSBDIEFQSS4KK3VwYl9maWVsZGRlZiAqdXBiX2ZpZWxkZGVmX25ldyhjb25zdCB2b2lkICpvd25lcik7Cit1cGJfZmllbGRkZWYgKnVwYl9maWVsZGRlZl9kdXAoY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBjb25zdCB2b2lkICpvd25lcik7CisKKy8vIEZyb20gdXBiX3JlZmNvdW50ZWQuCitib29sIHVwYl9maWVsZGRlZl9pc2Zyb3plbihjb25zdCB1cGJfZmllbGRkZWYgKmYpOwordm9pZCB1cGJfZmllbGRkZWZfcmVmKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfZmllbGRkZWZfdW5yZWYoY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9maWVsZGRlZl9kb25hdGVyZWYoY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBjb25zdCB2b2lkICpmcm9tLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnRvKTsKK3ZvaWQgdXBiX2ZpZWxkZGVmX2NoZWNrcmVmKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgY29uc3Qgdm9pZCAqb3duZXIpOworCisvLyBGcm9tIHVwYl9kZWYuCitjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfZnVsbG5hbWUoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX3NldGZ1bGxuYW1lKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgY2hhciAqZnVsbG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKTsKKworYm9vbCB1cGJfZmllbGRkZWZfdHlwZWlzc2V0KGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Cit1cGJfZmllbGR0eXBlX3QgdXBiX2ZpZWxkZGVmX3R5cGUoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK3VwYl9kZXNjcmlwdG9ydHlwZV90IHVwYl9maWVsZGRlZl9kZXNjcmlwdG9ydHlwZShjb25zdCB1cGJfZmllbGRkZWYgKmYpOwordXBiX2xhYmVsX3QgdXBiX2ZpZWxkZGVmX2xhYmVsKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Cit1aW50MzJfdCB1cGJfZmllbGRkZWZfbnVtYmVyKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfbmFtZShjb25zdCB1cGJfZmllbGRkZWYgKmYpOworYm9vbCB1cGJfZmllbGRkZWZfaXNleHRlbnNpb24oY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX2xhenkoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX3BhY2tlZChjb25zdCB1cGJfZmllbGRkZWYgKmYpOworY29uc3QgdXBiX21zZ2RlZiAqdXBiX2ZpZWxkZGVmX2NvbnRhaW5pbmd0eXBlKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citjb25zdCB1cGJfb25lb2ZkZWYgKnVwYl9maWVsZGRlZl9jb250YWluaW5nb25lb2YoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK3VwYl9tc2dkZWYgKnVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZV9tdXRhYmxlKHVwYl9maWVsZGRlZiAqZik7Citjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfY29udGFpbmluZ3R5cGVuYW1lKHVwYl9maWVsZGRlZiAqZik7Cit1cGJfaW50Zm10X3QgdXBiX2ZpZWxkZGVmX2ludGZtdChjb25zdCB1cGJfZmllbGRkZWYgKmYpOwordWludDMyX3QgdXBiX2ZpZWxkZGVmX2luZGV4KGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citib29sIHVwYl9maWVsZGRlZl9pc3RhZ2RlbGltKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citib29sIHVwYl9maWVsZGRlZl9pc3N1Ym1zZyhjb25zdCB1cGJfZmllbGRkZWYgKmYpOworYm9vbCB1cGJfZmllbGRkZWZfaXNzdHJpbmcoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX2lzc2VxKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citib29sIHVwYl9maWVsZGRlZl9pc3ByaW1pdGl2ZShjb25zdCB1cGJfZmllbGRkZWYgKmYpOworYm9vbCB1cGJfZmllbGRkZWZfaXNtYXAoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2ludDY0X3QgdXBiX2ZpZWxkZGVmX2RlZmF1bHRpbnQ2NChjb25zdCB1cGJfZmllbGRkZWYgKmYpOworaW50MzJfdCB1cGJfZmllbGRkZWZfZGVmYXVsdGludDMyKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Cit1aW50NjRfdCB1cGJfZmllbGRkZWZfZGVmYXVsdHVpbnQ2NChjb25zdCB1cGJfZmllbGRkZWYgKmYpOwordWludDMyX3QgdXBiX2ZpZWxkZGVmX2RlZmF1bHR1aW50MzIoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX2RlZmF1bHRib29sKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7CitmbG9hdCB1cGJfZmllbGRkZWZfZGVmYXVsdGZsb2F0KGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citkb3VibGUgdXBiX2ZpZWxkZGVmX2RlZmF1bHRkb3VibGUoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2NvbnN0IGNoYXIgKnVwYl9maWVsZGRlZl9kZWZhdWx0c3RyKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgc2l6ZV90ICpsZW4pOworYm9vbCB1cGJfZmllbGRkZWZfZW51bWhhc2RlZmF1bHRpbnQzMihjb25zdCB1cGJfZmllbGRkZWYgKmYpOworYm9vbCB1cGJfZmllbGRkZWZfZW51bWhhc2RlZmF1bHRzdHIoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX2hhc3N1YmRlZihjb25zdCB1cGJfZmllbGRkZWYgKmYpOworY29uc3QgdXBiX2RlZiAqdXBiX2ZpZWxkZGVmX3N1YmRlZihjb25zdCB1cGJfZmllbGRkZWYgKmYpOworY29uc3QgdXBiX21zZ2RlZiAqdXBiX2ZpZWxkZGVmX21zZ3N1YmRlZihjb25zdCB1cGJfZmllbGRkZWYgKmYpOworY29uc3QgdXBiX2VudW1kZWYgKnVwYl9maWVsZGRlZl9lbnVtc3ViZGVmKGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Citjb25zdCBjaGFyICp1cGJfZmllbGRkZWZfc3ViZGVmbmFtZShjb25zdCB1cGJfZmllbGRkZWYgKmYpOworCit2b2lkIHVwYl9maWVsZGRlZl9zZXR0eXBlKHVwYl9maWVsZGRlZiAqZiwgdXBiX2ZpZWxkdHlwZV90IHR5cGUpOwordm9pZCB1cGJfZmllbGRkZWZfc2V0ZGVzY3JpcHRvcnR5cGUodXBiX2ZpZWxkZGVmICpmLCBpbnQgdHlwZSk7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRsYWJlbCh1cGJfZmllbGRkZWYgKmYsIHVwYl9sYWJlbF90IGxhYmVsKTsKK2Jvb2wgdXBiX2ZpZWxkZGVmX3NldG51bWJlcih1cGJfZmllbGRkZWYgKmYsIHVpbnQzMl90IG51bWJlciwgdXBiX3N0YXR1cyAqcyk7Citib29sIHVwYl9maWVsZGRlZl9zZXRuYW1lKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgY2hhciAqbmFtZSwgdXBiX3N0YXR1cyAqcyk7Citib29sIHVwYl9maWVsZGRlZl9zZXRjb250YWluaW5ndHlwZW5hbWUodXBiX2ZpZWxkZGVmICpmLCBjb25zdCBjaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOwordm9pZCB1cGJfZmllbGRkZWZfc2V0aXNleHRlbnNpb24odXBiX2ZpZWxkZGVmICpmLCBib29sIGlzX2V4dGVuc2lvbik7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRsYXp5KHVwYl9maWVsZGRlZiAqZiwgYm9vbCBsYXp5KTsKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldHBhY2tlZCh1cGJfZmllbGRkZWYgKmYsIGJvb2wgcGFja2VkKTsKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldGludGZtdCh1cGJfZmllbGRkZWYgKmYsIHVwYl9pbnRmbXRfdCBmbXQpOwordm9pZCB1cGJfZmllbGRkZWZfc2V0dGFnZGVsaW0odXBiX2ZpZWxkZGVmICpmLCBib29sIHRhZ19kZWxpbSk7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0aW50NjQodXBiX2ZpZWxkZGVmICpmLCBpbnQ2NF90IHZhbCk7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0aW50MzIodXBiX2ZpZWxkZGVmICpmLCBpbnQzMl90IHZhbCk7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0dWludDY0KHVwYl9maWVsZGRlZiAqZiwgdWludDY0X3QgdmFsKTsKK3ZvaWQgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHR1aW50MzIodXBiX2ZpZWxkZGVmICpmLCB1aW50MzJfdCB2YWwpOwordm9pZCB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdGJvb2wodXBiX2ZpZWxkZGVmICpmLCBib29sIHZhbCk7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0ZmxvYXQodXBiX2ZpZWxkZGVmICpmLCBmbG9hdCB2YWwpOwordm9pZCB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdGRvdWJsZSh1cGJfZmllbGRkZWYgKmYsIGRvdWJsZSB2YWwpOworYm9vbCB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdHN0cih1cGJfZmllbGRkZWYgKmYsIGNvbnN0IHZvaWQgKnN0ciwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqcyk7Cit2b2lkIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0Y3N0cih1cGJfZmllbGRkZWYgKmYsIGNvbnN0IGNoYXIgKnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworYm9vbCB1cGJfZmllbGRkZWZfc2V0c3ViZGVmKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgdXBiX2RlZiAqc3ViZGVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworYm9vbCB1cGJfZmllbGRkZWZfc2V0bXNnc3ViZGVmKHVwYl9maWVsZGRlZiAqZiwgY29uc3QgdXBiX21zZ2RlZiAqc3ViZGVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworYm9vbCB1cGJfZmllbGRkZWZfc2V0ZW51bXN1YmRlZih1cGJfZmllbGRkZWYgKmYsIGNvbnN0IHVwYl9lbnVtZGVmICpzdWJkZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworYm9vbCB1cGJfZmllbGRkZWZfc2V0c3ViZGVmbmFtZSh1cGJfZmllbGRkZWYgKmYsIGNvbnN0IGNoYXIgKm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworCitib29sIHVwYl9maWVsZGRlZl9jaGVja2xhYmVsKGludDMyX3QgbGFiZWwpOworYm9vbCB1cGJfZmllbGRkZWZfY2hlY2t0eXBlKGludDMyX3QgdHlwZSk7Citib29sIHVwYl9maWVsZGRlZl9jaGVja2Rlc2NyaXB0b3J0eXBlKGludDMyX3QgdHlwZSk7Citib29sIHVwYl9maWVsZGRlZl9jaGVja2ludGZtdChpbnQzMl90IGZtdCk7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworCisvKiB1cGI6Ok1lc3NhZ2VEZWYgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHVwYl9pbnR0YWJsZV9pdGVyIHVwYl9tc2dfZmllbGRfaXRlcjsKK3R5cGVkZWYgdXBiX3N0cnRhYmxlX2l0ZXIgdXBiX21zZ19vbmVvZl9pdGVyOworCisvLyBTdHJ1Y3R1cmUgdGhhdCBkZXNjcmliZXMgYSBzaW5nbGUgLnByb3RvIG1lc3NhZ2UgdHlwZS4KKy8vCisvLyBJdHMgYmFzZSBjbGFzcyBpcyB1cGI6OkRlZiAodXNlIHVwYjo6dXBjYXN0KCkgdG8gY29udmVydCkuCitVUEJfREVGSU5FX0RFRih1cGI6Ok1lc3NhZ2VEZWYsIG1zZ2RlZiwgTVNHLCBVUEJfUVVPVEUoCisgcHVibGljOgorICAvLyBSZXR1cm5zIE5VTEwgaWYgbWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkLgorICBzdGF0aWMgcmVmZmVkX3B0cjxNZXNzYWdlRGVmPiBOZXcoKTsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpSZWZDb3VudGVkLgorICBib29sIElzRnJvemVuKCkgY29uc3Q7CisgIHZvaWQgUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBVbnJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisgIHZvaWQgRG9uYXRlUmVmKGNvbnN0IHZvaWQqIGZyb20sIGNvbnN0IHZvaWQqIHRvKSBjb25zdDsKKyAgdm9pZCBDaGVja1JlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisKKyAgLy8gRnVuY3Rpb25hbGl0eSBmcm9tIHVwYjo6RGVmLgorICBjb25zdCBjaGFyKiBmdWxsX25hbWUoKSBjb25zdDsKKyAgYm9vbCBzZXRfZnVsbF9uYW1lKGNvbnN0IGNoYXIqIGZ1bGxuYW1lLCBTdGF0dXMqIHMpOworICBib29sIHNldF9mdWxsX25hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIGZ1bGxuYW1lLCBTdGF0dXMqIHMpOworCisgIC8vIENhbGwgdG8gZnJlZXplIHRoaXMgTWVzc2FnZURlZi4KKyAgLy8gV0FSTklORzogdGhpcyB3aWxsIGZhaWwgaWYgdGhpcyBtZXNzYWdlIGhhcyBhbnkgdW5mcm96ZW4gc3VibWVzc2FnZXMhCisgIC8vIE1lc3NhZ2VzIHdpdGggY3ljbGVzIG11c3QgYmUgZnJvemVuIGFzIGEgYmF0Y2ggdXNpbmcgdXBiOjpEZWY6OkZyZWV6ZSgpLgorICBib29sIEZyZWV6ZShTdGF0dXMqIHMpOworCisgIC8vIFRoZSBudW1iZXIgb2YgZmllbGRzIHRoYXQgYmVsb25nIHRvIHRoZSBNZXNzYWdlRGVmLgorICBpbnQgZmllbGRfY291bnQoKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIG9uZW9mcyB0aGF0IGJlbG9uZyB0byB0aGUgTWVzc2FnZURlZi4KKyAgaW50IG9uZW9mX2NvdW50KCkgY29uc3Q7CisKKyAgLy8gQWRkcyBhIGZpZWxkICh1cGJfZmllbGRkZWYgb2JqZWN0KSB0byBhIG1zZ2RlZi4gIFJlcXVpcmVzIHRoYXQgdGhlIG1zZ2RlZgorICAvLyBhbmQgdGhlIGZpZWxkZGVmcyBhcmUgbXV0YWJsZS4gIFRoZSBmaWVsZGRlZidzIG5hbWUgYW5kIG51bWJlciBtdXN0IGJlCisgIC8vIHNldCwgYW5kIHRoZSBtZXNzYWdlIG1heSBub3QgYWxyZWFkeSBjb250YWluIGFueSBmaWVsZCB3aXRoIHRoaXMgbmFtZSBvcgorICAvLyBudW1iZXIsIGFuZCB0aGlzIGZpZWxkZGVmIG1heSBub3QgYmUgcGFydCBvZiBhbm90aGVyIG1lc3NhZ2UuICBJbiBlcnJvcgorICAvLyBjYXNlcyBmYWxzZSBpcyByZXR1cm5lZCBhbmQgdGhlIG1zZ2RlZiBpcyB1bmNoYW5nZWQuCisgIC8vCisgIC8vIElmIHRoZSBnaXZlbiBmaWVsZCBpcyBwYXJ0IG9mIGEgb25lb2YsIHRoaXMgY2FsbCBzdWNjZWVkcyBpZiBhbmQgb25seSBpZgorICAvLyB0aGF0IG9uZW9mIGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIG1zZ2RlZi4gKE5vdGUgdGhhdCBhZGRpbmcgYSBvbmVvZiB0byBhCisgIC8vIG1zZ2RlZiBhdXRvbWF0aWNhbGx5IGFkZHMgYWxsIG9mIGl0cyBmaWVsZHMgdG8gdGhlIG1zZ2RlZiBhdCB0aGUgdGltZSB0aGF0CisgIC8vIHRoZSBvbmVvZiBpcyBhZGRlZCwgc28gaXQgaXMgdXN1YWxseSBtb3JlIGlkaW9tYXRpYyB0byBhZGQgdGhlIG9uZW9mJ3MKKyAgLy8gZmllbGRzIGZpcnN0IHRoZW4gYWRkIHRoZSBvbmVvZiB0byB0aGUgbXNnZGVmLiBUaGlzIGNhc2UgaXMgc3VwcG9ydGVkIGZvcgorICAvLyBjb252ZW5pZW5jZS4pCisgIC8vCisgIC8vIElmIHxmfCBpcyBhbHJlYWR5IHBhcnQgb2YgdGhpcyBNZXNzYWdlRGVmLCB0aGlzIG1ldGhvZCBwZXJmb3JtcyBubyBhY3Rpb24KKyAgLy8gYW5kIHJldHVybnMgdHJ1ZSAoc3VjY2VzcykuIFRodXMsIHRoaXMgbWV0aG9kIGlzIGlkZW1wb3RlbnQuCisgIGJvb2wgQWRkRmllbGQoRmllbGREZWYqIGYsIFN0YXR1cyogcyk7CisgIGJvb2wgQWRkRmllbGQoY29uc3QgcmVmZmVkX3B0cjxGaWVsZERlZj4mIGYsIFN0YXR1cyogcyk7CisKKyAgLy8gQWRkcyBhIG9uZW9mICh1cGJfb25lb2ZkZWYgb2JqZWN0KSB0byBhIG1zZ2RlZi4gUmVxdWlyZXMgdGhhdCB0aGUgbXNnZGVmLAorICAvLyBvbmVvZiwgYW5kIGFueSBmaWVsZGRlZnMgYXJlIG11dGFibGUsIHRoYXQgdGhlIGZpZWxkZGVmcyBjb250YWluZWQgaW4gdGhlCisgIC8vIG9uZW9mIGRvIG5vdCBoYXZlIGFueSBuYW1lIG9yIG51bWJlciBjb25mbGljdHMgd2l0aCBleGlzdGluZyBmaWVsZHMgaW4gdGhlCisgIC8vIG1zZ2RlZiwgYW5kIHRoYXQgdGhlIG9uZW9mJ3MgbmFtZSBpcyB1bmlxdWUgYW1vbmcgYWxsIG9uZW9mcyBpbiB0aGUgbXNnZGVmLgorICAvLyBJZiB0aGUgb25lb2YgaXMgYWRkZWQgc3VjY2Vzc2Z1bGx5LCBhbGwgb2YgaXRzIGZpZWxkcyB3aWxsIGJlIGFkZGVkCisgIC8vIGRpcmVjdGx5IHRvIHRoZSBtc2dkZWYgYXMgd2VsbC4gSW4gZXJyb3IgY2FzZXMsIGZhbHNlIGlzIHJldHVybmVkIGFuZCB0aGUKKyAgLy8gbXNnZGVmIGlzIHVuY2hhbmdlZC4KKyAgYm9vbCBBZGRPbmVvZihPbmVvZkRlZiogbywgU3RhdHVzKiBzKTsKKyAgYm9vbCBBZGRPbmVvZihjb25zdCByZWZmZWRfcHRyPE9uZW9mRGVmPiYgbywgU3RhdHVzKiBzKTsKKworICAvLyBUaGVzZSByZXR1cm4gTlVMTCBpZiB0aGUgZmllbGQgaXMgbm90IGZvdW5kLgorICBGaWVsZERlZiogRmluZEZpZWxkQnlOdW1iZXIodWludDMyX3QgbnVtYmVyKTsKKyAgRmllbGREZWYqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbGVuKTsKKyAgY29uc3QgRmllbGREZWYqIEZpbmRGaWVsZEJ5TnVtYmVyKHVpbnQzMl90IG51bWJlcikgY29uc3Q7CisgIGNvbnN0IEZpZWxkRGVmKiBGaW5kRmllbGRCeU5hbWUoY29uc3QgY2hhciogbmFtZSwgc2l6ZV90IGxlbikgY29uc3Q7CisKKworICBGaWVsZERlZiogRmluZEZpZWxkQnlOYW1lKGNvbnN0IGNoYXIgKm5hbWUpIHsKKyAgICByZXR1cm4gRmluZEZpZWxkQnlOYW1lKG5hbWUsIHN0cmxlbihuYW1lKSk7CisgIH0KKyAgY29uc3QgRmllbGREZWYqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBjaGFyICpuYW1lKSBjb25zdCB7CisgICAgcmV0dXJuIEZpbmRGaWVsZEJ5TmFtZShuYW1lLCBzdHJsZW4obmFtZSkpOworICB9CisKKyAgdGVtcGxhdGUgPGNsYXNzIFQ+CisgIEZpZWxkRGVmKiBGaW5kRmllbGRCeU5hbWUoY29uc3QgVCYgc3RyKSB7CisgICAgcmV0dXJuIEZpbmRGaWVsZEJ5TmFtZShzdHIuY19zdHIoKSwgc3RyLnNpemUoKSk7CisgIH0KKyAgdGVtcGxhdGUgPGNsYXNzIFQ+CisgIGNvbnN0IEZpZWxkRGVmKiBGaW5kRmllbGRCeU5hbWUoY29uc3QgVCYgc3RyKSBjb25zdCB7CisgICAgcmV0dXJuIEZpbmRGaWVsZEJ5TmFtZShzdHIuY19zdHIoKSwgc3RyLnNpemUoKSk7CisgIH0KKworICBPbmVvZkRlZiogRmluZE9uZW9mQnlOYW1lKGNvbnN0IGNoYXIqIG5hbWUsIHNpemVfdCBsZW4pOworICBjb25zdCBPbmVvZkRlZiogRmluZE9uZW9mQnlOYW1lKGNvbnN0IGNoYXIqIG5hbWUsIHNpemVfdCBsZW4pIGNvbnN0OworCisgIE9uZW9mRGVmKiBGaW5kT25lb2ZCeU5hbWUoY29uc3QgY2hhciogbmFtZSkgeworICAgIHJldHVybiBGaW5kT25lb2ZCeU5hbWUobmFtZSwgc3RybGVuKG5hbWUpKTsKKyAgfQorICBjb25zdCBPbmVvZkRlZiogRmluZE9uZW9mQnlOYW1lKGNvbnN0IGNoYXIqIG5hbWUpIGNvbnN0IHsKKyAgICByZXR1cm4gRmluZE9uZW9mQnlOYW1lKG5hbWUsIHN0cmxlbihuYW1lKSk7CisgIH0KKworICB0ZW1wbGF0ZTxjbGFzcyBUPgorICBPbmVvZkRlZiogRmluZE9uZW9mQnlOYW1lKGNvbnN0IFQmIHN0cikgeworICAgIHJldHVybiBGaW5kT25lb2ZCeU5hbWUoc3RyLmNfc3RyKCksIHN0ci5zaXplKCkpOworICB9CisgIHRlbXBsYXRlPGNsYXNzIFQ+CisgIGNvbnN0IE9uZW9mRGVmKiBGaW5kT25lb2ZCeU5hbWUoY29uc3QgVCYgc3RyKSBjb25zdCB7CisgICAgcmV0dXJuIEZpbmRPbmVvZkJ5TmFtZShzdHIuY19zdHIoKSwgc3RyLnNpemUoKSk7CisgIH0KKworICAvLyBSZXR1cm5zIGEgbmV3IG1zZ2RlZiB0aGF0IGlzIGEgY29weSBvZiB0aGUgZ2l2ZW4gbXNnZGVmIChhbmQgYSBjb3B5IG9mIGFsbAorICAvLyB0aGUgZmllbGRzKSBidXQgd2l0aCBhbnkgcmVmZXJlbmNlcyB0byBzdWJtZXNzYWdlcyBicm9rZW4gYW5kIHJlcGxhY2VkCisgIC8vIHdpdGgganVzdCB0aGUgbmFtZSBvZiB0aGUgc3VibWVzc2FnZS4gIFJldHVybnMgTlVMTCBpZiBtZW1vcnkgYWxsb2NhdGlvbgorICAvLyBmYWlsZWQuCisgIC8vCisgIC8vIFRPRE8oaGFiZXJtYW4pOiB3aGljaCBpcyBtb3JlIHVzZWZ1bCwga2VlcGluZyBmaWVsZHMgcmVzb2x2ZWQgb3IKKyAgLy8gdW5yZXNvbHZpbmcgdGhlbT8gIElmIHRoZXJlJ3Mgbm8gb2J2aW91cyBhbnN3ZXIsIFNob3VsZCB0aGlzIGZ1bmN0aW9uYWxpdHkKKyAgLy8ganVzdCBiZSBtb3ZlZCBpbnRvIHN5bXRhYi5jPworICBNZXNzYWdlRGVmKiBEdXAoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworCisgIC8vIElzIHRoaXMgbWVzc2FnZSBhIG1hcCBlbnRyeT8KKyAgdm9pZCBzZXRtYXBlbnRyeShib29sIG1hcF9lbnRyeSk7CisgIGJvb2wgbWFwZW50cnkoKSBjb25zdDsKKworICAvLyBJdGVyYXRpb24gb3ZlciBmaWVsZHMuICBUaGUgb3JkZXIgaXMgdW5kZWZpbmVkLgorICBjbGFzcyBmaWVsZF9pdGVyYXRvcgorICAgICAgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjxzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLCBGaWVsZERlZio+IHsKKyAgIHB1YmxpYzoKKyAgICBleHBsaWNpdCBmaWVsZF9pdGVyYXRvcihNZXNzYWdlRGVmKiBtZCk7CisgICAgc3RhdGljIGZpZWxkX2l0ZXJhdG9yIGVuZChNZXNzYWdlRGVmKiBtZCk7CisKKyAgICB2b2lkIG9wZXJhdG9yKysoKTsKKyAgICBGaWVsZERlZiogb3BlcmF0b3IqKCkgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGZpZWxkX2l0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGZpZWxkX2l0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisKKyAgIHByaXZhdGU6CisgICAgdXBiX21zZ19maWVsZF9pdGVyIGl0ZXJfOworICB9OworCisgIGNsYXNzIGNvbnN0X2ZpZWxkX2l0ZXJhdG9yCisgICAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIGNvbnN0IEZpZWxkRGVmKj4geworICAgcHVibGljOgorICAgIGV4cGxpY2l0IGNvbnN0X2ZpZWxkX2l0ZXJhdG9yKGNvbnN0IE1lc3NhZ2VEZWYqIG1kKTsKKyAgICBzdGF0aWMgY29uc3RfZmllbGRfaXRlcmF0b3IgZW5kKGNvbnN0IE1lc3NhZ2VEZWYqIG1kKTsKKworICAgIHZvaWQgb3BlcmF0b3IrKygpOworICAgIGNvbnN0IEZpZWxkRGVmKiBvcGVyYXRvciooKSBjb25zdDsKKyAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgY29uc3RfZmllbGRfaXRlcmF0b3ImIG90aGVyKSBjb25zdDsKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgY29uc3RfZmllbGRfaXRlcmF0b3ImIG90aGVyKSBjb25zdDsKKworICAgcHJpdmF0ZToKKyAgICB1cGJfbXNnX2ZpZWxkX2l0ZXIgaXRlcl87CisgIH07CisKKyAgLy8gSXRlcmF0aW9uIG92ZXIgb25lb2ZzLiBUaGUgb3JkZXIgaXMgdW5kZWZpbmVkLgorICBjbGFzcyBvbmVvZl9pdGVyYXRvcgorICAgICAgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjxzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLCBGaWVsZERlZio+IHsKKyAgIHB1YmxpYzoKKyAgICBleHBsaWNpdCBvbmVvZl9pdGVyYXRvcihNZXNzYWdlRGVmKiBtZCk7CisgICAgc3RhdGljIG9uZW9mX2l0ZXJhdG9yIGVuZChNZXNzYWdlRGVmKiBtZCk7CisKKyAgICB2b2lkIG9wZXJhdG9yKysoKTsKKyAgICBPbmVvZkRlZiogb3BlcmF0b3IqKCkgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IG9uZW9mX2l0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IG9uZW9mX2l0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisKKyAgIHByaXZhdGU6CisgICAgdXBiX21zZ19vbmVvZl9pdGVyIGl0ZXJfOworICB9OworCisgIGNsYXNzIGNvbnN0X29uZW9mX2l0ZXJhdG9yCisgICAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIGNvbnN0IEZpZWxkRGVmKj4geworICAgcHVibGljOgorICAgIGV4cGxpY2l0IGNvbnN0X29uZW9mX2l0ZXJhdG9yKGNvbnN0IE1lc3NhZ2VEZWYqIG1kKTsKKyAgICBzdGF0aWMgY29uc3Rfb25lb2ZfaXRlcmF0b3IgZW5kKGNvbnN0IE1lc3NhZ2VEZWYqIG1kKTsKKworICAgIHZvaWQgb3BlcmF0b3IrKygpOworICAgIGNvbnN0IE9uZW9mRGVmKiBvcGVyYXRvciooKSBjb25zdDsKKyAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgY29uc3Rfb25lb2ZfaXRlcmF0b3ImIG90aGVyKSBjb25zdDsKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgY29uc3Rfb25lb2ZfaXRlcmF0b3ImIG90aGVyKSBjb25zdDsKKworICAgcHJpdmF0ZToKKyAgICB1cGJfbXNnX29uZW9mX2l0ZXIgaXRlcl87CisgIH07CisKKyAgY2xhc3MgRmllbGRBY2Nlc3NvciB7CisgICBwdWJsaWM6CisgICAgZXhwbGljaXQgRmllbGRBY2Nlc3NvcihNZXNzYWdlRGVmKiBtc2cpIDogbXNnXyhtc2cpIHt9CisgICAgZmllbGRfaXRlcmF0b3IgYmVnaW4oKSB7IHJldHVybiBtc2dfLT5maWVsZF9iZWdpbigpOyB9CisgICAgZmllbGRfaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gbXNnXy0+ZmllbGRfZW5kKCk7IH0KKyAgIHByaXZhdGU6CisgICAgTWVzc2FnZURlZiogbXNnXzsKKyAgfTsKKworICBjbGFzcyBDb25zdEZpZWxkQWNjZXNzb3IgeworICAgcHVibGljOgorICAgIGV4cGxpY2l0IENvbnN0RmllbGRBY2Nlc3Nvcihjb25zdCBNZXNzYWdlRGVmKiBtc2cpIDogbXNnXyhtc2cpIHt9CisgICAgY29uc3RfZmllbGRfaXRlcmF0b3IgYmVnaW4oKSB7IHJldHVybiBtc2dfLT5maWVsZF9iZWdpbigpOyB9CisgICAgY29uc3RfZmllbGRfaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gbXNnXy0+ZmllbGRfZW5kKCk7IH0KKyAgIHByaXZhdGU6CisgICAgY29uc3QgTWVzc2FnZURlZiogbXNnXzsKKyAgfTsKKworICBjbGFzcyBPbmVvZkFjY2Vzc29yIHsKKyAgIHB1YmxpYzoKKyAgICBleHBsaWNpdCBPbmVvZkFjY2Vzc29yKE1lc3NhZ2VEZWYqIG1zZykgOiBtc2dfKG1zZykge30KKyAgICBvbmVvZl9pdGVyYXRvciBiZWdpbigpIHsgcmV0dXJuIG1zZ18tPm9uZW9mX2JlZ2luKCk7IH0KKyAgICBvbmVvZl9pdGVyYXRvciBlbmQoKSB7IHJldHVybiBtc2dfLT5vbmVvZl9lbmQoKTsgfQorICAgcHJpdmF0ZToKKyAgICBNZXNzYWdlRGVmKiBtc2dfOworICB9OworCisgIGNsYXNzIENvbnN0T25lb2ZBY2Nlc3NvciB7CisgICBwdWJsaWM6CisgICAgZXhwbGljaXQgQ29uc3RPbmVvZkFjY2Vzc29yKGNvbnN0IE1lc3NhZ2VEZWYqIG1zZykgOiBtc2dfKG1zZykge30KKyAgICBjb25zdF9vbmVvZl9pdGVyYXRvciBiZWdpbigpIHsgcmV0dXJuIG1zZ18tPm9uZW9mX2JlZ2luKCk7IH0KKyAgICBjb25zdF9vbmVvZl9pdGVyYXRvciBlbmQoKSB7IHJldHVybiBtc2dfLT5vbmVvZl9lbmQoKTsgfQorICAgcHJpdmF0ZToKKyAgICBjb25zdCBNZXNzYWdlRGVmKiBtc2dfOworICB9OworCisgIGZpZWxkX2l0ZXJhdG9yIGZpZWxkX2JlZ2luKCk7CisgIGZpZWxkX2l0ZXJhdG9yIGZpZWxkX2VuZCgpOworICBjb25zdF9maWVsZF9pdGVyYXRvciBmaWVsZF9iZWdpbigpIGNvbnN0OworICBjb25zdF9maWVsZF9pdGVyYXRvciBmaWVsZF9lbmQoKSBjb25zdDsKKworICBvbmVvZl9pdGVyYXRvciBvbmVvZl9iZWdpbigpOworICBvbmVvZl9pdGVyYXRvciBvbmVvZl9lbmQoKTsKKyAgY29uc3Rfb25lb2ZfaXRlcmF0b3Igb25lb2ZfYmVnaW4oKSBjb25zdDsKKyAgY29uc3Rfb25lb2ZfaXRlcmF0b3Igb25lb2ZfZW5kKCkgY29uc3Q7CisKKyAgRmllbGRBY2Nlc3NvciBmaWVsZHMoKSB7IHJldHVybiBGaWVsZEFjY2Vzc29yKHRoaXMpOyB9CisgIENvbnN0RmllbGRBY2Nlc3NvciBmaWVsZHMoKSBjb25zdCB7IHJldHVybiBDb25zdEZpZWxkQWNjZXNzb3IodGhpcyk7IH0KKyAgT25lb2ZBY2Nlc3NvciBvbmVvZnMoKSB7IHJldHVybiBPbmVvZkFjY2Vzc29yKHRoaXMpOyB9CisgIENvbnN0T25lb2ZBY2Nlc3NvciBvbmVvZnMoKSBjb25zdCB7IHJldHVybiBDb25zdE9uZW9mQWNjZXNzb3IodGhpcyk7IH0KKworIHByaXZhdGU6CisgIFVQQl9ESVNBTExPV19QT0RfT1BTKE1lc3NhZ2VEZWYsIHVwYjo6TWVzc2FnZURlZik7CispLAorVVBCX0RFRklORV9TVFJVQ1QodXBiX21zZ2RlZiwgdXBiX2RlZiwKKyAgc2l6ZV90IHNlbGVjdG9yX2NvdW50OworICB1aW50MzJfdCBzdWJtc2dfZmllbGRfY291bnQ7CisKKyAgLy8gVGFibGVzIGZvciBsb29raW5nIHVwIGZpZWxkcyBieSBudW1iZXIgYW5kIG5hbWUuCisgIHVwYl9pbnR0YWJsZSBpdG9mOyAgLy8gaW50IHRvIGZpZWxkCisgIHVwYl9zdHJ0YWJsZSBudG9mOyAgLy8gbmFtZSB0byBmaWVsZAorCisgIC8vIFRhYmxlcyBmb3IgbG9va2luZyB1cCBvbmVvZnMgYnkgbmFtZS4KKyAgdXBiX3N0cnRhYmxlIG50b287ICAvLyBuYW1lIHRvIG9uZW9mCisKKyAgLy8gSXMgdGhpcyBhIG1hcC1lbnRyeSBtZXNzYWdlPworICAvLyBUT0RPOiBzZXQgdGhpcyBmbGFnIHByb3Blcmx5IGZvciBzdGF0aWMgZGVzY3JpcHRvcnM7IHJlZ2VuZXJhdGUKKyAgLy8gZGVzY3JpcHRvci51cGIuYy4KKyAgYm9vbCBtYXBfZW50cnk7CisKKyAgLy8gVE9ETyhoYWJlcm1hbik6IHByb3BlciBleHRlbnNpb24gcmFuZ2VzICh0aGVyZSBjYW4gYmUgbXVsdGlwbGUpLgorKSk7CisKKy8vIFRPRE86IGFsc28gc3VwcG9ydCBzdGF0aWMgaW5pdGlhbGl6YXRpb24gb2YgdGhlIG9uZW9mcyB0YWJsZS4gVGhpcyB3aWxsIGJlCisvLyBuZWVkZWQgaWYgd2UgY29tcGlsZSBpbiBkZXNjcmlwdG9ycyB0aGF0IGNvbnRhaW4gb25lb2ZzLgorI2RlZmluZSBVUEJfTVNHREVGX0lOSVQobmFtZSwgc2VsZWN0b3JfY291bnQsIHN1Ym1zZ19maWVsZF9jb3VudCwgaXRvZiwgbnRvZiwgXAorICAgICAgICAgICAgICAgICAgICAgICAgcmVmcywgcmVmMnMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVQQl9ERUZfSU5JVChuYW1lLCBVUEJfREVGX01TRywgcmVmcywgcmVmMnMpLCBzZWxlY3Rvcl9jb3VudCwgICAgICAgICAgICAgXAorICAgICAgICBzdWJtc2dfZmllbGRfY291bnQsIGl0b2YsIG50b2YsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBVUEJfRU1QVFlfU1RSVEFCTEVfSU5JVChVUEJfQ1RZUEVfUFRSKSwgZmFsc2UgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCisvLyBSZXR1cm5zIE5VTEwgaWYgbWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkLgordXBiX21zZ2RlZiAqdXBiX21zZ2RlZl9uZXcoY29uc3Qgdm9pZCAqb3duZXIpOworCisvLyBGcm9tIHVwYl9yZWZjb3VudGVkLgorYm9vbCB1cGJfbXNnZGVmX2lzZnJvemVuKGNvbnN0IHVwYl9tc2dkZWYgKm0pOwordm9pZCB1cGJfbXNnZGVmX3JlZihjb25zdCB1cGJfbXNnZGVmICptLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9tc2dkZWZfdW5yZWYoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfbXNnZGVmX2RvbmF0ZXJlZihjb25zdCB1cGJfbXNnZGVmICptLCBjb25zdCB2b2lkICpmcm9tLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICp0byk7Cit2b2lkIHVwYl9tc2dkZWZfY2hlY2tyZWYoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqb3duZXIpOworYm9vbCB1cGJfbXNnZGVmX2ZyZWV6ZSh1cGJfbXNnZGVmICptLCB1cGJfc3RhdHVzICpzdGF0dXMpOworCisvLyBGcm9tIHVwYl9kZWYuCitjb25zdCBjaGFyICp1cGJfbXNnZGVmX2Z1bGxuYW1lKGNvbnN0IHVwYl9tc2dkZWYgKm0pOworYm9vbCB1cGJfbXNnZGVmX3NldGZ1bGxuYW1lKHVwYl9tc2dkZWYgKm0sIGNvbnN0IGNoYXIgKmZ1bGxuYW1lLCB1cGJfc3RhdHVzICpzKTsKKwordXBiX21zZ2RlZiAqdXBiX21zZ2RlZl9kdXAoY29uc3QgdXBiX21zZ2RlZiAqbSwgY29uc3Qgdm9pZCAqb3duZXIpOworYm9vbCB1cGJfbXNnZGVmX2FkZGZpZWxkKHVwYl9tc2dkZWYgKm0sIHVwYl9maWVsZGRlZiAqZiwgY29uc3Qgdm9pZCAqcmVmX2Rvbm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworYm9vbCB1cGJfbXNnZGVmX2FkZG9uZW9mKHVwYl9tc2dkZWYgKm0sIHVwYl9vbmVvZmRlZiAqbywgY29uc3Qgdm9pZCAqcmVmX2Rvbm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworCisvLyBGaWVsZCBsb29rdXAgaW4gYSBjb3VwbGUgb2YgZGlmZmVyZW50IHZhcmlhdGlvbnM6CisvLyAgIC0gaXRvZiA9IGludCB0byBmaWVsZAorLy8gICAtIG50b2YgPSBuYW1lIHRvIGZpZWxkCisvLyAgIC0gbnRvZnogPSBuYW1lIHRvIGZpZWxkLCBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nLgorY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJfbXNnZGVmX2l0b2YoY29uc3QgdXBiX21zZ2RlZiAqbSwgdWludDMyX3QgaSk7Citjb25zdCB1cGJfZmllbGRkZWYgKnVwYl9tc2dkZWZfbnRvZihjb25zdCB1cGJfbXNnZGVmICptLCBjb25zdCBjaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbik7CitpbnQgdXBiX21zZ2RlZl9udW1maWVsZHMoY29uc3QgdXBiX21zZ2RlZiAqbSk7CisKK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJfbXNnZGVmX250b2Z6KGNvbnN0IHVwYl9tc2dkZWYgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKSB7CisgIHJldHVybiB1cGJfbXNnZGVmX250b2YobSwgbmFtZSwgc3RybGVuKG5hbWUpKTsKK30KKworVVBCX0lOTElORSB1cGJfZmllbGRkZWYgKnVwYl9tc2dkZWZfaXRvZl9tdXRhYmxlKHVwYl9tc2dkZWYgKm0sIHVpbnQzMl90IGkpIHsKKyAgcmV0dXJuICh1cGJfZmllbGRkZWYqKXVwYl9tc2dkZWZfaXRvZihtLCBpKTsKK30KKworVVBCX0lOTElORSB1cGJfZmllbGRkZWYgKnVwYl9tc2dkZWZfbnRvZl9tdXRhYmxlKHVwYl9tc2dkZWYgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IGxlbikgeworICByZXR1cm4gKHVwYl9maWVsZGRlZiAqKXVwYl9tc2dkZWZfbnRvZihtLCBuYW1lLCBsZW4pOworfQorCisvLyBPbmVvZiBsb29rdXA6CisvLyAgIC0gbnRvbyA9IG5hbWUgdG8gb25lb2YKKy8vICAgLSBudG9veiA9IG5hbWUgdG8gb25lb2YsIG51bGwtdGVybWluYXRlZCBzdHJpbmcuCitjb25zdCB1cGJfb25lb2ZkZWYgKnVwYl9tc2dkZWZfbnRvbyhjb25zdCB1cGJfbXNnZGVmICptLCBjb25zdCBjaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbik7CitpbnQgdXBiX21zZ2RlZl9udW1vbmVvZnMoY29uc3QgdXBiX21zZ2RlZiAqbSk7CisKK1VQQl9JTkxJTkUgY29uc3QgdXBiX29uZW9mZGVmICp1cGJfbXNnZGVmX250b296KGNvbnN0IHVwYl9tc2dkZWYgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpIHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfbnRvbyhtLCBuYW1lLCBzdHJsZW4obmFtZSkpOworfQorCitVUEJfSU5MSU5FIHVwYl9vbmVvZmRlZiAqdXBiX21zZ2RlZl9udG9vX211dGFibGUodXBiX21zZ2RlZiAqbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbGVuKSB7CisgIHJldHVybiAodXBiX29uZW9mZGVmICopdXBiX21zZ2RlZl9udG9vKG0sIG5hbWUsIGxlbik7Cit9CisKK3ZvaWQgdXBiX21zZ2RlZl9zZXRtYXBlbnRyeSh1cGJfbXNnZGVmICptLCBib29sIG1hcF9lbnRyeSk7Citib29sIHVwYl9tc2dkZWZfbWFwZW50cnkoY29uc3QgdXBiX21zZ2RlZiAqbSk7CisKKy8vIFdlbGwta25vd24gZmllbGQgdGFnIG51bWJlcnMgZm9yIG1hcC1lbnRyeSBtZXNzYWdlcy4KKyNkZWZpbmUgVVBCX01BUEVOVFJZX0tFWSAgIDEKKyNkZWZpbmUgVVBCX01BUEVOVFJZX1ZBTFVFIDIKKworY29uc3QgdXBiX29uZW9mZGVmICp1cGJfbXNnZGVmX2ZpbmRvbmVvZihjb25zdCB1cGJfbXNnZGVmICptLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSk7CitpbnQgdXBiX21zZ2RlZl9udW1vbmVvZnMoY29uc3QgdXBiX21zZ2RlZiAqbSk7CisKKy8vIHVwYl9tc2dfZmllbGRfaXRlciBpOworLy8gZm9yKHVwYl9tc2dfZmllbGRfYmVnaW4oJmksIG0pOworLy8gICAgICF1cGJfbXNnX2ZpZWxkX2RvbmUoJmkpOworLy8gICAgIHVwYl9tc2dfZmllbGRfbmV4dCgmaSkpIHsKKy8vICAgdXBiX2ZpZWxkZGVmICpmID0gdXBiX21zZ19pdGVyX2ZpZWxkKCZpKTsKKy8vICAgLy8gLi4uCisvLyB9CisvLworLy8gRm9yIEMgd2UgZG9uJ3QgaGF2ZSBzZXBhcmF0ZSBpdGVyYXRvcnMgZm9yIGNvbnN0IGFuZCBub24tY29uc3QuCisvLyBJdCBpcyB0aGUgY2FsbGVyJ3MgcmVzcG9uc2liaWxpdHkgdG8gY2FzdCB0aGUgdXBiX2ZpZWxkZGVmKiB0bworLy8gY29uc3QgaWYgdGhlIHVwYl9tc2dkZWYqIGlzIGNvbnN0Lgordm9pZCB1cGJfbXNnX2ZpZWxkX2JlZ2luKHVwYl9tc2dfZmllbGRfaXRlciAqaXRlciwgY29uc3QgdXBiX21zZ2RlZiAqbSk7Cit2b2lkIHVwYl9tc2dfZmllbGRfbmV4dCh1cGJfbXNnX2ZpZWxkX2l0ZXIgKml0ZXIpOworYm9vbCB1cGJfbXNnX2ZpZWxkX2RvbmUoY29uc3QgdXBiX21zZ19maWVsZF9pdGVyICppdGVyKTsKK3VwYl9maWVsZGRlZiAqdXBiX21zZ19pdGVyX2ZpZWxkKGNvbnN0IHVwYl9tc2dfZmllbGRfaXRlciAqaXRlcik7Cit2b2lkIHVwYl9tc2dfZmllbGRfaXRlcl9zZXRkb25lKHVwYl9tc2dfZmllbGRfaXRlciAqaXRlcik7CisKKy8vIFNpbWlsYXIgdG8gYWJvdmUsIHdlIGFsc28gc3VwcG9ydCBpdGVyYXRpbmcgdGhyb3VnaCB0aGUgb25lb2ZzIGluIGEgbXNnZGVmLgordm9pZCB1cGJfbXNnX29uZW9mX2JlZ2luKHVwYl9tc2dfb25lb2ZfaXRlciAqaXRlciwgY29uc3QgdXBiX21zZ2RlZiAqbSk7Cit2b2lkIHVwYl9tc2dfb25lb2ZfbmV4dCh1cGJfbXNnX29uZW9mX2l0ZXIgKml0ZXIpOworYm9vbCB1cGJfbXNnX29uZW9mX2RvbmUoY29uc3QgdXBiX21zZ19vbmVvZl9pdGVyICppdGVyKTsKK3VwYl9vbmVvZmRlZiAqdXBiX21zZ19pdGVyX29uZW9mKGNvbnN0IHVwYl9tc2dfb25lb2ZfaXRlciAqaXRlcik7Cit2b2lkIHVwYl9tc2dfb25lb2ZfaXRlcl9zZXRkb25lKHVwYl9tc2dfb25lb2ZfaXRlciAqaXRlcik7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworCisvKiB1cGI6OkVudW1EZWYgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHVwYl9zdHJ0YWJsZV9pdGVyIHVwYl9lbnVtX2l0ZXI7CisKKy8vIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBlbnVtLiAgSXRzIGJhc2UgY2xhc3MgaXMgdXBiOjpEZWYgKGNvbnZlcnQgd2l0aAorLy8gdXBiOjp1cGNhc3QoKSkuCitVUEJfREVGSU5FX0RFRih1cGI6OkVudW1EZWYsIGVudW1kZWYsIEVOVU0sCisgcHVibGljOgorICAvLyBSZXR1cm5zIE5VTEwgaWYgbWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkLgorICBzdGF0aWMgcmVmZmVkX3B0cjxFbnVtRGVmPiBOZXcoKTsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpSZWZDb3VudGVkLgorICBib29sIElzRnJvemVuKCkgY29uc3Q7CisgIHZvaWQgUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBVbnJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisgIHZvaWQgRG9uYXRlUmVmKGNvbnN0IHZvaWQqIGZyb20sIGNvbnN0IHZvaWQqIHRvKSBjb25zdDsKKyAgdm9pZCBDaGVja1JlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisKKyAgLy8gRnVuY3Rpb25hbGl0eSBmcm9tIHVwYjo6RGVmLgorICBjb25zdCBjaGFyKiBmdWxsX25hbWUoKSBjb25zdDsKKyAgYm9vbCBzZXRfZnVsbF9uYW1lKGNvbnN0IGNoYXIqIGZ1bGxuYW1lLCBTdGF0dXMqIHMpOworICBib29sIHNldF9mdWxsX25hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIGZ1bGxuYW1lLCBTdGF0dXMqIHMpOworCisgIC8vIENhbGwgdG8gZnJlZXplIHRoaXMgRW51bURlZi4KKyAgYm9vbCBGcmVlemUoU3RhdHVzKiBzKTsKKworICAvLyBUaGUgdmFsdWUgdGhhdCBpcyB1c2VkIGFzIHRoZSBkZWZhdWx0IHdoZW4gbm8gZmllbGQgZGVmYXVsdCBpcyBzcGVjaWZpZWQuCisgIC8vIElmIG5vdCBzZXQgZXhwbGljaXRseSwgdGhlIGZpcnN0IHZhbHVlIHRoYXQgd2FzIGFkZGVkIHdpbGwgYmUgdXNlZC4KKyAgLy8gVGhlIGRlZmF1bHQgdmFsdWUgbXVzdCBiZSBhIG1lbWJlciBvZiB0aGUgZW51bS4KKyAgLy8gUmVxdWlyZXMgdGhhdCB2YWx1ZV9jb3VudCgpID4gMC4KKyAgaW50MzJfdCBkZWZhdWx0X3ZhbHVlKCkgY29uc3Q7CisKKyAgLy8gU2V0cyB0aGUgZGVmYXVsdCB2YWx1ZS4gIElmIHRoaXMgdmFsdWUgaXMgbm90IHZhbGlkLCByZXR1cm5zIGZhbHNlIGFuZCBhbgorICAvLyBlcnJvciBtZXNzYWdlIGluIHN0YXR1cy4KKyAgYm9vbCBzZXRfZGVmYXVsdF92YWx1ZShpbnQzMl90IHZhbCwgU3RhdHVzKiBzdGF0dXMpOworCisgIC8vIFJldHVybnMgdGhlIG51bWJlciBvZiB2YWx1ZXMgY3VycmVudGx5IGRlZmluZWQgaW4gdGhlIGVudW0uICBOb3RlIHRoYXQKKyAgLy8gbXVsdGlwbGUgbmFtZXMgY2FuIHJlZmVyIHRvIHRoZSBzYW1lIG51bWJlciwgc28gdGhpcyBtYXkgYmUgZ3JlYXRlciB0aGFuCisgIC8vIHRoZSB0b3RhbCBudW1iZXIgb2YgdW5pcXVlIG51bWJlcnMuCisgIGludCB2YWx1ZV9jb3VudCgpIGNvbnN0OworCisgIC8vIEFkZHMgYSBzaW5nbGUgbmFtZS9udW1iZXIgcGFpciB0byB0aGUgZW51bS4gIEZhaWxzIGlmIHRoaXMgbmFtZSBoYXMKKyAgLy8gYWxyZWFkeSBiZWVuIHVzZWQgYnkgYW5vdGhlciB2YWx1ZS4KKyAgYm9vbCBBZGRWYWx1ZShjb25zdCBjaGFyKiBuYW1lLCBpbnQzMl90IG51bSwgU3RhdHVzKiBzdGF0dXMpOworICBib29sIEFkZFZhbHVlKGNvbnN0IHN0ZDo6c3RyaW5nJiBuYW1lLCBpbnQzMl90IG51bSwgU3RhdHVzKiBzdGF0dXMpOworCisgIC8vIExvb2t1cHMgZnJvbSBuYW1lIHRvIGludGVnZXIsIHJldHVybmluZyB0cnVlIGlmIGZvdW5kLgorICBib29sIEZpbmRWYWx1ZUJ5TmFtZShjb25zdCBjaGFyKiBuYW1lLCBpbnQzMl90KiBudW0pIGNvbnN0OworCisgIC8vIEZpbmRzIHRoZSBuYW1lIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIG51bWJlciwgb3IgTlVMTCBpZiBub25lIHdhcworICAvLyBmb3VuZC4gIElmIG1vcmUgdGhhbiBvbmUgbmFtZSBjb3JyZXNwb25kcyB0byB0aGlzIG51bWJlciwgcmV0dXJucyB0aGUKKyAgLy8gZmlyc3Qgb25lIHRoYXQgd2FzIGFkZGVkLgorICBjb25zdCBjaGFyKiBGaW5kVmFsdWVCeU51bWJlcihpbnQzMl90IG51bSkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyBhIG5ldyBFbnVtRGVmIHdpdGggYWxsIHRoZSBzYW1lIHZhbHVlcy4gIFRoZSBuZXcgRW51bURlZiB3aWxsIGJlCisgIC8vIG93bmVkIGJ5IHRoZSBnaXZlbiBvd25lci4KKyAgRW51bURlZiogRHVwKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKworICAvLyBJdGVyYXRpb24gb3ZlciBuYW1lL3ZhbHVlIHBhaXJzLiAgVGhlIG9yZGVyIGlzIHVuZGVmaW5lZC4KKyAgLy8gQWRkaW5nIGFuIGVudW0gdmFsIGludmFsaWRhdGVzIGFueSBpdGVyYXRvcnMuCisgIC8vCisgIC8vIFRPRE86IG1ha2UgY29tcGF0aWJsZSB3aXRoIHJhbmdlLWZvciwgd2l0aCBlbGVtZW50cyBhcyBwYWlycz8KKyAgY2xhc3MgSXRlcmF0b3IgeworICAgcHVibGljOgorICAgIGV4cGxpY2l0IEl0ZXJhdG9yKGNvbnN0IEVudW1EZWYqKTsKKworICAgIGludDMyX3QgbnVtYmVyKCk7CisgICAgY29uc3QgY2hhciAqbmFtZSgpOworICAgIGJvb2wgRG9uZSgpOworICAgIHZvaWQgTmV4dCgpOworCisgICBwcml2YXRlOgorICAgIHVwYl9lbnVtX2l0ZXIgaXRlcl87CisgIH07CisKKyBwcml2YXRlOgorICBVUEJfRElTQUxMT1dfUE9EX09QUyhFbnVtRGVmLCB1cGI6OkVudW1EZWYpOworLAorVVBCX0RFRklORV9TVFJVQ1QodXBiX2VudW1kZWYsIHVwYl9kZWYsCisgIHVwYl9zdHJ0YWJsZSBudG9pOworICB1cGJfaW50dGFibGUgaXRvbjsKKyAgaW50MzJfdCBkZWZhdWx0dmFsOworKSk7CisKKyNkZWZpbmUgVVBCX0VOVU1ERUZfSU5JVChuYW1lLCBudG9pLCBpdG9uLCBkZWZhdWx0dmFsLCByZWZzLCByZWYycykgXAorICB7IFVQQl9ERUZfSU5JVChuYW1lLCBVUEJfREVGX0VOVU0sIHJlZnMsIHJlZjJzKSwgbnRvaSwgaXRvbiwgZGVmYXVsdHZhbCB9CisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCisvLyBOYXRpdmUgQyBBUEkuCit1cGJfZW51bWRlZiAqdXBiX2VudW1kZWZfbmV3KGNvbnN0IHZvaWQgKm93bmVyKTsKK3VwYl9lbnVtZGVmICp1cGJfZW51bWRlZl9kdXAoY29uc3QgdXBiX2VudW1kZWYgKmUsIGNvbnN0IHZvaWQgKm93bmVyKTsKKworLy8gRnJvbSB1cGJfcmVmY291bnRlZC4KK3ZvaWQgdXBiX2VudW1kZWZfdW5yZWYoY29uc3QgdXBiX2VudW1kZWYgKmUsIGNvbnN0IHZvaWQgKm93bmVyKTsKK2Jvb2wgdXBiX2VudW1kZWZfaXNmcm96ZW4oY29uc3QgdXBiX2VudW1kZWYgKmUpOwordm9pZCB1cGJfZW51bWRlZl9yZWYoY29uc3QgdXBiX2VudW1kZWYgKmUsIGNvbnN0IHZvaWQgKm93bmVyKTsKK3ZvaWQgdXBiX2VudW1kZWZfZG9uYXRlcmVmKGNvbnN0IHVwYl9lbnVtZGVmICptLCBjb25zdCB2b2lkICpmcm9tLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqdG8pOwordm9pZCB1cGJfZW51bWRlZl9jaGVja3JlZihjb25zdCB1cGJfZW51bWRlZiAqZSwgY29uc3Qgdm9pZCAqb3duZXIpOworYm9vbCB1cGJfZW51bWRlZl9mcmVlemUodXBiX2VudW1kZWYgKmUsIHVwYl9zdGF0dXMgKnN0YXR1cyk7CisKKy8vIEZyb20gdXBiX2RlZi4KK2NvbnN0IGNoYXIgKnVwYl9lbnVtZGVmX2Z1bGxuYW1lKGNvbnN0IHVwYl9lbnVtZGVmICplKTsKK2Jvb2wgdXBiX2VudW1kZWZfc2V0ZnVsbG5hbWUodXBiX2VudW1kZWYgKmUsIGNvbnN0IGNoYXIgKmZ1bGxuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzKTsKKworaW50MzJfdCB1cGJfZW51bWRlZl9kZWZhdWx0KGNvbnN0IHVwYl9lbnVtZGVmICplKTsKK2Jvb2wgdXBiX2VudW1kZWZfc2V0ZGVmYXVsdCh1cGJfZW51bWRlZiAqZSwgaW50MzJfdCB2YWwsIHVwYl9zdGF0dXMgKnMpOworaW50IHVwYl9lbnVtZGVmX251bXZhbHMoY29uc3QgdXBiX2VudW1kZWYgKmUpOworYm9vbCB1cGJfZW51bWRlZl9hZGR2YWwodXBiX2VudW1kZWYgKmUsIGNvbnN0IGNoYXIgKm5hbWUsIGludDMyX3QgbnVtLAorICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqc3RhdHVzKTsKKworLy8gRW51bSBsb29rdXBzOgorLy8gLSBudG9pOiAgbG9vayB1cCBhIG5hbWUgd2l0aCBzcGVjaWZpZWQgbGVuZ3RoLgorLy8gLSBudG9pejogbG9vayB1cCBhIG5hbWUgcHJvdmlkZWQgYXMgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nLgorLy8gLSBpdG9uOiAgbG9vayB1cCBhbiBpbnRlZ2VyLCByZXR1cm5pbmcgdGhlIG5hbWUgYXMgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nLgorYm9vbCB1cGJfZW51bWRlZl9udG9pKGNvbnN0IHVwYl9lbnVtZGVmICplLCBjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgKm51bSk7CitVUEJfSU5MSU5FIGJvb2wgdXBiX2VudW1kZWZfbnRvaXooY29uc3QgdXBiX2VudW1kZWYgKmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgaW50MzJfdCAqbnVtKSB7CisgIHJldHVybiB1cGJfZW51bWRlZl9udG9pKGUsIG5hbWUsIHN0cmxlbihuYW1lKSwgbnVtKTsKK30KK2NvbnN0IGNoYXIgKnVwYl9lbnVtZGVmX2l0b24oY29uc3QgdXBiX2VudW1kZWYgKmUsIGludDMyX3QgbnVtKTsKKworLy8gIHVwYl9lbnVtX2l0ZXIgaTsKKy8vICBmb3IodXBiX2VudW1fYmVnaW4oJmksIGUpOyAhdXBiX2VudW1fZG9uZSgmaSk7IHVwYl9lbnVtX25leHQoJmkpKSB7CisvLyAgICAvLyAuLi4KKy8vICB9Cit2b2lkIHVwYl9lbnVtX2JlZ2luKHVwYl9lbnVtX2l0ZXIgKml0ZXIsIGNvbnN0IHVwYl9lbnVtZGVmICplKTsKK3ZvaWQgdXBiX2VudW1fbmV4dCh1cGJfZW51bV9pdGVyICppdGVyKTsKK2Jvb2wgdXBiX2VudW1fZG9uZSh1cGJfZW51bV9pdGVyICppdGVyKTsKK2NvbnN0IGNoYXIgKnVwYl9lbnVtX2l0ZXJfbmFtZSh1cGJfZW51bV9pdGVyICppdGVyKTsKK2ludDMyX3QgdXBiX2VudW1faXRlcl9udW1iZXIodXBiX2VudW1faXRlciAqaXRlcik7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworLyogdXBiOjpPbmVvZkRlZiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiB1cGJfaW50dGFibGVfaXRlciB1cGJfb25lb2ZfaXRlcjsKKworLy8gQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgb25lb2YuICBJdHMgYmFzZSBjbGFzcyBpcyB1cGI6OkRlZiAoY29udmVydCB3aXRoCisvLyB1cGI6OnVwY2FzdCgpKS4KK1VQQl9ERUZJTkVfREVGKHVwYjo6T25lb2ZEZWYsIG9uZW9mZGVmLCBPTkVPRiwgVVBCX1FVT1RFKAorIHB1YmxpYzoKKyAgLy8gUmV0dXJucyBOVUxMIGlmIG1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZC4KKyAgc3RhdGljIHJlZmZlZF9wdHI8T25lb2ZEZWY+IE5ldygpOworCisgIC8vIEZ1bmN0aW9uYWxpdHkgZnJvbSB1cGI6OlJlZkNvdW50ZWQuCisgIGJvb2wgSXNGcm96ZW4oKSBjb25zdDsKKyAgdm9pZCBSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworICB2b2lkIFVucmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBEb25hdGVSZWYoY29uc3Qgdm9pZCogZnJvbSwgY29uc3Qgdm9pZCogdG8pIGNvbnN0OworICB2b2lkIENoZWNrUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpEZWYuCisgIGNvbnN0IGNoYXIqIGZ1bGxfbmFtZSgpIGNvbnN0OworCisgIC8vIFJldHVybnMgdGhlIE1lc3NhZ2VEZWYgdGhhdCBvd25zIHRoaXMgT25lb2ZEZWYuCisgIGNvbnN0IE1lc3NhZ2VEZWYqIGNvbnRhaW5pbmdfdHlwZSgpIGNvbnN0OworCisgIC8vIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBvbmVvZi4gVGhpcyBpcyB0aGUgbmFtZSB1c2VkIHRvIGxvb2sgdXAgdGhlIG9uZW9mCisgIC8vIGJ5IG5hbWUgb25jZSBhZGRlZCB0byBhIG1lc3NhZ2UgZGVmLgorICBjb25zdCBjaGFyKiBuYW1lKCkgY29uc3Q7CisgIGJvb2wgc2V0X25hbWUoY29uc3QgY2hhciogbmFtZSwgU3RhdHVzKiBzKTsKKworICAvLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZmllbGRzIGN1cnJlbnRseSBkZWZpbmVkIGluIHRoZSBvbmVvZi4KKyAgaW50IGZpZWxkX2NvdW50KCkgY29uc3Q7CisKKyAgLy8gQWRkcyBhIGZpZWxkIHRvIHRoZSBvbmVvZi4gVGhlIGZpZWxkIG11c3Qgbm90IGhhdmUgYmVlbiBhZGRlZCB0byBhbnkgb3RoZXIKKyAgLy8gb25lb2Ygb3IgbXNnZGVmLiBJZiB0aGUgb25lb2YgaXMgbm90IHlldCBwYXJ0IG9mIGEgbXNnZGVmLCB0aGVuIHdoZW4gdGhlCisgIC8vIG9uZW9mIGlzIGV2ZW50dWFsbHkgYWRkZWQgdG8gYSBtc2dkZWYsIGFsbCBmaWVsZHMgYWRkZWQgdG8gdGhlIG9uZW9mIHdpbGwKKyAgLy8gYWxzbyBiZSBhZGRlZCB0byB0aGUgbXNnZGVmIGF0IHRoYXQgdGltZS4gSWYgdGhlIG9uZW9mIGlzIGFscmVhZHkgcGFydCBvZiBhCisgIC8vIG1zZ2RlZiwgdGhlIGZpZWxkIG11c3QgZWl0aGVyIGJlIGEgcGFydCBvZiB0aGF0IG1zZ2RlZiBhbHJlYWR5LCBvciBtdXN0IG5vdAorICAvLyBiZSBhIHBhcnQgb2YgYW55IG1zZ2RlZjsgaW4gdGhlIGxhdHRlciBjYXNlLCB0aGUgZmllbGQgaXMgYWRkZWQgdG8gdGhlCisgIC8vIG1zZ2RlZiBhcyBhIHBhcnQgb2YgdGhpcyBvcGVyYXRpb24uCisgIC8vCisgIC8vIFRoZSBmaWVsZCBtYXkgb25seSBoYXZlIGFuIE9QVElPTkFMIGxhYmVsLCBuZXZlciBSRVFVSVJFRCBvciBSRVBFQVRFRC4KKyAgLy8KKyAgLy8gSWYgfGZ8IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIE1lc3NhZ2VEZWYsIHRoaXMgbWV0aG9kIHBlcmZvcm1zIG5vIGFjdGlvbgorICAvLyBhbmQgcmV0dXJucyB0cnVlIChzdWNjZXNzKS4gVGh1cywgdGhpcyBtZXRob2QgaXMgaWRlbXBvdGVudC4KKyAgYm9vbCBBZGRGaWVsZChGaWVsZERlZiogZmllbGQsIFN0YXR1cyogcyk7CisgIGJvb2wgQWRkRmllbGQoY29uc3QgcmVmZmVkX3B0cjxGaWVsZERlZj4mIGZpZWxkLCBTdGF0dXMqIHMpOworCisgIC8vIExvb2tzIHVwIGJ5IG5hbWUuCisgIGNvbnN0IEZpZWxkRGVmKiBGaW5kRmllbGRCeU5hbWUoY29uc3QgY2hhciogbmFtZSwgc2l6ZV90IGxlbikgY29uc3Q7CisgIEZpZWxkRGVmKiBGaW5kRmllbGRCeU5hbWUoY29uc3QgY2hhciogbmFtZSwgc2l6ZV90IGxlbik7CisgIGNvbnN0IEZpZWxkRGVmKiBGaW5kRmllbGRCeU5hbWUoY29uc3QgY2hhciogbmFtZSkgY29uc3QgeworICAgIHJldHVybiBGaW5kRmllbGRCeU5hbWUobmFtZSwgc3RybGVuKG5hbWUpKTsKKyAgfQorICBGaWVsZERlZiogRmluZEZpZWxkQnlOYW1lKGNvbnN0IGNoYXIqIG5hbWUpIHsKKyAgICByZXR1cm4gRmluZEZpZWxkQnlOYW1lKG5hbWUsIHN0cmxlbihuYW1lKSk7CisgIH0KKworICB0ZW1wbGF0ZSA8Y2xhc3MgVD4KKyAgRmllbGREZWYqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBUJiBzdHIpIHsKKyAgICByZXR1cm4gRmluZEZpZWxkQnlOYW1lKHN0ci5jX3N0cigpLCBzdHIuc2l6ZSgpKTsKKyAgfQorICB0ZW1wbGF0ZSA8Y2xhc3MgVD4KKyAgY29uc3QgRmllbGREZWYqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBUJiBzdHIpIGNvbnN0IHsKKyAgICByZXR1cm4gRmluZEZpZWxkQnlOYW1lKHN0ci5jX3N0cigpLCBzdHIuc2l6ZSgpKTsKKyAgfQorCisgIC8vIExvb2tzIHVwIGJ5IHRhZyBudW1iZXIuCisgIGNvbnN0IEZpZWxkRGVmKiBGaW5kRmllbGRCeU51bWJlcih1aW50MzJfdCBudW0pIGNvbnN0OworCisgIC8vIFJldHVybnMgYSBuZXcgT25lb2ZEZWYgd2l0aCBhbGwgdGhlIHNhbWUgZmllbGRzLiBUaGUgT25lb2ZEZWYgd2lsbCBiZSBvd25lZAorICAvLyBieSB0aGUgZ2l2ZW4gb3duZXIuCisgIE9uZW9mRGVmKiBEdXAoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworCisgIC8vIEl0ZXJhdGlvbiBvdmVyIGZpZWxkcy4gIFRoZSBvcmRlciBpcyB1bmRlZmluZWQuCisgIGNsYXNzIGl0ZXJhdG9yIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywgRmllbGREZWYqPiB7CisgICBwdWJsaWM6CisgICAgZXhwbGljaXQgaXRlcmF0b3IoT25lb2ZEZWYqIG1kKTsKKyAgICBzdGF0aWMgaXRlcmF0b3IgZW5kKE9uZW9mRGVmKiBtZCk7CisKKyAgICB2b2lkIG9wZXJhdG9yKysoKTsKKyAgICBGaWVsZERlZiogb3BlcmF0b3IqKCkgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisKKyAgIHByaXZhdGU6CisgICAgdXBiX29uZW9mX2l0ZXIgaXRlcl87CisgIH07CisKKyAgY2xhc3MgY29uc3RfaXRlcmF0b3IKKyAgICAgIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywgY29uc3QgRmllbGREZWYqPiB7CisgICBwdWJsaWM6CisgICAgZXhwbGljaXQgY29uc3RfaXRlcmF0b3IoY29uc3QgT25lb2ZEZWYqIG1kKTsKKyAgICBzdGF0aWMgY29uc3RfaXRlcmF0b3IgZW5kKGNvbnN0IE9uZW9mRGVmKiBtZCk7CisKKyAgICB2b2lkIG9wZXJhdG9yKysoKTsKKyAgICBjb25zdCBGaWVsZERlZiogb3BlcmF0b3IqKCkgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGNvbnN0X2l0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGNvbnN0X2l0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CisKKyAgIHByaXZhdGU6CisgICAgdXBiX29uZW9mX2l0ZXIgaXRlcl87CisgIH07CisKKyAgaXRlcmF0b3IgYmVnaW4oKTsKKyAgaXRlcmF0b3IgZW5kKCk7CisgIGNvbnN0X2l0ZXJhdG9yIGJlZ2luKCkgY29uc3Q7CisgIGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgVVBCX0RJU0FMTE9XX1BPRF9PUFMoT25lb2ZEZWYsIHVwYjo6T25lb2ZEZWYpOworKSwKK1VQQl9ERUZJTkVfU1RSVUNUKHVwYl9vbmVvZmRlZiwgdXBiX2RlZiwKKyAgdXBiX3N0cnRhYmxlIG50b2Y7CisgIHVwYl9pbnR0YWJsZSBpdG9mOworICBjb25zdCB1cGJfbXNnZGVmICpwYXJlbnQ7CispKTsKKworI2RlZmluZSBVUEJfT05FT0ZERUZfSU5JVChuYW1lLCBudG9mLCBpdG9mLCByZWZzLCByZWYycykgXAorICB7IFVQQl9ERUZfSU5JVChuYW1lLCBVUEJfREVGX0VOVU0sIHJlZnMsIHJlZjJzKSwgbnRvZiwgaXRvZiB9CisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCisvLyBOYXRpdmUgQyBBUEkuCit1cGJfb25lb2ZkZWYgKnVwYl9vbmVvZmRlZl9uZXcoY29uc3Qgdm9pZCAqb3duZXIpOwordXBiX29uZW9mZGVmICp1cGJfb25lb2ZkZWZfZHVwKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywgY29uc3Qgdm9pZCAqb3duZXIpOworCisvLyBGcm9tIHVwYl9yZWZjb3VudGVkLgordm9pZCB1cGJfb25lb2ZkZWZfdW5yZWYoY29uc3QgdXBiX29uZW9mZGVmICpvLCBjb25zdCB2b2lkICpvd25lcik7Citib29sIHVwYl9vbmVvZmRlZl9pc2Zyb3plbihjb25zdCB1cGJfb25lb2ZkZWYgKmUpOwordm9pZCB1cGJfb25lb2ZkZWZfcmVmKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfb25lb2ZkZWZfZG9uYXRlcmVmKGNvbnN0IHVwYl9vbmVvZmRlZiAqbSwgY29uc3Qgdm9pZCAqZnJvbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnRvKTsKK3ZvaWQgdXBiX29uZW9mZGVmX2NoZWNrcmVmKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywgY29uc3Qgdm9pZCAqb3duZXIpOworCitjb25zdCBjaGFyICp1cGJfb25lb2ZkZWZfbmFtZShjb25zdCB1cGJfb25lb2ZkZWYgKm8pOworYm9vbCB1cGJfb25lb2ZkZWZfc2V0bmFtZSh1cGJfb25lb2ZkZWYgKm8sIGNvbnN0IGNoYXIgKm5hbWUsIHVwYl9zdGF0dXMgKnMpOworCitjb25zdCB1cGJfbXNnZGVmICp1cGJfb25lb2ZkZWZfY29udGFpbmluZ3R5cGUoY29uc3QgdXBiX29uZW9mZGVmICpvKTsKK2ludCB1cGJfb25lb2ZkZWZfbnVtZmllbGRzKGNvbnN0IHVwYl9vbmVvZmRlZiAqbyk7Citib29sIHVwYl9vbmVvZmRlZl9hZGRmaWVsZCh1cGJfb25lb2ZkZWYgKm8sIHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnJlZl9kb25vciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdGF0dXMgKnMpOworCisvLyBPbmVvZiBsb29rdXBzOgorLy8gLSBudG9mOiAgbG9vayB1cCBhIGZpZWxkIGJ5IG5hbWUuCisvLyAtIG50b2Z6OiBsb29rIHVwIGEgZmllbGQgYnkgbmFtZSAoYXMgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nKS4KKy8vIC0gaXRvZjogIGxvb2sgdXAgYSBmaWVsZCBieSBudW1iZXIuCitjb25zdCB1cGJfZmllbGRkZWYgKnVwYl9vbmVvZmRlZl9udG9mKGNvbnN0IHVwYl9vbmVvZmRlZiAqbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IGxlbmd0aCk7CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiX29uZW9mZGVmX250b2Z6KGNvbnN0IHVwYl9vbmVvZmRlZiAqbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkgeworICByZXR1cm4gdXBiX29uZW9mZGVmX250b2YobywgbmFtZSwgc3RybGVuKG5hbWUpKTsKK30KK2NvbnN0IHVwYl9maWVsZGRlZiAqdXBiX29uZW9mZGVmX2l0b2YoY29uc3QgdXBiX29uZW9mZGVmICpvLCB1aW50MzJfdCBudW0pOworCisvLyAgdXBiX29uZW9mX2l0ZXIgaTsKKy8vICBmb3IodXBiX29uZW9mX2JlZ2luKCZpLCBlKTsgIXVwYl9vbmVvZl9kb25lKCZpKTsgdXBiX29uZW9mX25leHQoJmkpKSB7CisvLyAgICAvLyAuLi4KKy8vICB9Cit2b2lkIHVwYl9vbmVvZl9iZWdpbih1cGJfb25lb2ZfaXRlciAqaXRlciwgY29uc3QgdXBiX29uZW9mZGVmICpvKTsKK3ZvaWQgdXBiX29uZW9mX25leHQodXBiX29uZW9mX2l0ZXIgKml0ZXIpOworYm9vbCB1cGJfb25lb2ZfZG9uZSh1cGJfb25lb2ZfaXRlciAqaXRlcik7Cit1cGJfZmllbGRkZWYgKnVwYl9vbmVvZl9pdGVyX2ZpZWxkKGNvbnN0IHVwYl9vbmVvZl9pdGVyICppdGVyKTsKK3ZvaWQgdXBiX29uZW9mX2l0ZXJfc2V0ZG9uZSh1cGJfb25lb2ZfaXRlciAqaXRlcik7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworI2lmZGVmIF9fY3BsdXNwbHVzCisKK1VQQl9JTkxJTkUgY29uc3QgY2hhciogdXBiX3NhZmVjc3RyKGNvbnN0IHN0ZDo6c3RyaW5nJiBzdHIpIHsKKyAgYXNzZXJ0KHN0ci5zaXplKCkgPT0gc3RkOjpzdHJsZW4oc3RyLmNfc3RyKCkpKTsKKyAgcmV0dXJuIHN0ci5jX3N0cigpOworfQorCisvLyBJbmxpbmUgQysrIHdyYXBwZXJzLgorbmFtZXNwYWNlIHVwYiB7CisKK2lubGluZSBEZWYqIERlZjo6RHVwKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdCB7CisgIHJldHVybiB1cGJfZGVmX2R1cCh0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgYm9vbCBEZWY6OklzRnJvemVuKCkgY29uc3QgeyByZXR1cm4gdXBiX2RlZl9pc2Zyb3plbih0aGlzKTsgfQoraW5saW5lIHZvaWQgRGVmOjpSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsgdXBiX2RlZl9yZWYodGhpcywgb3duZXIpOyB9CitpbmxpbmUgdm9pZCBEZWY6OlVucmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdCB7IHVwYl9kZWZfdW5yZWYodGhpcywgb3duZXIpOyB9CitpbmxpbmUgdm9pZCBEZWY6OkRvbmF0ZVJlZihjb25zdCB2b2lkKiBmcm9tLCBjb25zdCB2b2lkKiB0bykgY29uc3QgeworICB1cGJfZGVmX2RvbmF0ZXJlZih0aGlzLCBmcm9tLCB0byk7Cit9CitpbmxpbmUgdm9pZCBEZWY6OkNoZWNrUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdCB7CisgIHVwYl9kZWZfY2hlY2tyZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIERlZjo6VHlwZSBEZWY6OmRlZl90eXBlKCkgY29uc3QgeyByZXR1cm4gdXBiX2RlZl90eXBlKHRoaXMpOyB9CitpbmxpbmUgY29uc3QgY2hhciogRGVmOjpmdWxsX25hbWUoKSBjb25zdCB7IHJldHVybiB1cGJfZGVmX2Z1bGxuYW1lKHRoaXMpOyB9CitpbmxpbmUgYm9vbCBEZWY6OnNldF9mdWxsX25hbWUoY29uc3QgY2hhciogZnVsbG5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2RlZl9zZXRmdWxsbmFtZSh0aGlzLCBmdWxsbmFtZSwgcyk7Cit9CitpbmxpbmUgYm9vbCBEZWY6OnNldF9mdWxsX25hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIGZ1bGxuYW1lLCBTdGF0dXMqIHMpIHsKKyAgcmV0dXJuIHVwYl9kZWZfc2V0ZnVsbG5hbWUodGhpcywgdXBiX3NhZmVjc3RyKGZ1bGxuYW1lKSwgcyk7Cit9CitpbmxpbmUgYm9vbCBEZWY6OkZyZWV6ZShEZWYqIGNvbnN0KiBkZWZzLCBpbnQgbiwgU3RhdHVzKiBzdGF0dXMpIHsKKyAgcmV0dXJuIHVwYl9kZWZfZnJlZXplKGRlZnMsIG4sIHN0YXR1cyk7Cit9CitpbmxpbmUgYm9vbCBEZWY6OkZyZWV6ZShjb25zdCBzdGQ6OnZlY3RvcjxEZWYqPiYgZGVmcywgU3RhdHVzKiBzdGF0dXMpIHsKKyAgcmV0dXJuIHVwYl9kZWZfZnJlZXplKChEZWYqIGNvbnN0KikmZGVmc1swXSwgZGVmcy5zaXplKCksIHN0YXR1cyk7Cit9CisKK2lubGluZSBib29sIEZpZWxkRGVmOjpDaGVja1R5cGUoaW50MzJfdCB2YWwpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9jaGVja3R5cGUodmFsKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpDaGVja0xhYmVsKGludDMyX3QgdmFsKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfY2hlY2tsYWJlbCh2YWwpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OkNoZWNrRGVzY3JpcHRvclR5cGUoaW50MzJfdCB2YWwpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9jaGVja2Rlc2NyaXB0b3J0eXBlKHZhbCk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6Q2hlY2tJbnRlZ2VyRm9ybWF0KGludDMyX3QgdmFsKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfY2hlY2tpbnRmbXQodmFsKTsKK30KK2lubGluZSBGaWVsZERlZjo6VHlwZSBGaWVsZERlZjo6Q29udmVydFR5cGUoaW50MzJfdCB2YWwpIHsKKyAgYXNzZXJ0KENoZWNrVHlwZSh2YWwpKTsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PEZpZWxkRGVmOjpUeXBlPih2YWwpOworfQoraW5saW5lIEZpZWxkRGVmOjpMYWJlbCBGaWVsZERlZjo6Q29udmVydExhYmVsKGludDMyX3QgdmFsKSB7CisgIGFzc2VydChDaGVja0xhYmVsKHZhbCkpOworICByZXR1cm4gc3RhdGljX2Nhc3Q8RmllbGREZWY6OkxhYmVsPih2YWwpOworfQoraW5saW5lIEZpZWxkRGVmOjpEZXNjcmlwdG9yVHlwZSBGaWVsZERlZjo6Q29udmVydERlc2NyaXB0b3JUeXBlKGludDMyX3QgdmFsKSB7CisgIGFzc2VydChDaGVja0Rlc2NyaXB0b3JUeXBlKHZhbCkpOworICByZXR1cm4gc3RhdGljX2Nhc3Q8RmllbGREZWY6OkRlc2NyaXB0b3JUeXBlPih2YWwpOworfQoraW5saW5lIEZpZWxkRGVmOjpJbnRlZ2VyRm9ybWF0IEZpZWxkRGVmOjpDb252ZXJ0SW50ZWdlckZvcm1hdChpbnQzMl90IHZhbCkgeworICBhc3NlcnQoQ2hlY2tJbnRlZ2VyRm9ybWF0KHZhbCkpOworICByZXR1cm4gc3RhdGljX2Nhc3Q8RmllbGREZWY6OkludGVnZXJGb3JtYXQ+KHZhbCk7Cit9CisKK2lubGluZSByZWZmZWRfcHRyPEZpZWxkRGVmPiBGaWVsZERlZjo6TmV3KCkgeworICB1cGJfZmllbGRkZWYgKmYgPSB1cGJfZmllbGRkZWZfbmV3KCZmKTsKKyAgcmV0dXJuIHJlZmZlZF9wdHI8RmllbGREZWY+KGYsICZmKTsKK30KK2lubGluZSBGaWVsZERlZiogRmllbGREZWY6OkR1cChjb25zdCB2b2lkKiBvd25lcikgY29uc3QgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX2R1cCh0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6SXNGcm96ZW4oKSBjb25zdCB7IHJldHVybiB1cGJfZmllbGRkZWZfaXNmcm96ZW4odGhpcyk7IH0KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgdXBiX2ZpZWxkZGVmX3JlZih0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6VW5yZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgdXBiX2ZpZWxkZGVmX3VucmVmKHRoaXMsIG93bmVyKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpEb25hdGVSZWYoY29uc3Qgdm9pZCogZnJvbSwgY29uc3Qgdm9pZCogdG8pIGNvbnN0IHsKKyAgdXBiX2ZpZWxkZGVmX2RvbmF0ZXJlZih0aGlzLCBmcm9tLCB0byk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6Q2hlY2tSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgdXBiX2ZpZWxkZGVmX2NoZWNrcmVmKHRoaXMsIG93bmVyKTsKK30KK2lubGluZSBjb25zdCBjaGFyKiBGaWVsZERlZjo6ZnVsbF9uYW1lKCkgY29uc3QgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX2Z1bGxuYW1lKHRoaXMpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OnNldF9mdWxsX25hbWUoY29uc3QgY2hhciogZnVsbG5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldGZ1bGxuYW1lKHRoaXMsIGZ1bGxuYW1lLCBzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfZnVsbF9uYW1lKGNvbnN0IHN0ZDo6c3RyaW5nJiBmdWxsbmFtZSwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfc2V0ZnVsbG5hbWUodGhpcywgdXBiX3NhZmVjc3RyKGZ1bGxuYW1lKSwgcyk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6dHlwZV9pc19zZXQoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfdHlwZWlzc2V0KHRoaXMpOworfQoraW5saW5lIEZpZWxkRGVmOjpUeXBlIEZpZWxkRGVmOjp0eXBlKCkgY29uc3QgeyByZXR1cm4gdXBiX2ZpZWxkZGVmX3R5cGUodGhpcyk7IH0KK2lubGluZSBGaWVsZERlZjo6RGVzY3JpcHRvclR5cGUgRmllbGREZWY6OmRlc2NyaXB0b3JfdHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9kZXNjcmlwdG9ydHlwZSh0aGlzKTsKK30KK2lubGluZSBGaWVsZERlZjo6TGFiZWwgRmllbGREZWY6OmxhYmVsKCkgY29uc3QgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX2xhYmVsKHRoaXMpOworfQoraW5saW5lIHVpbnQzMl90IEZpZWxkRGVmOjpudW1iZXIoKSBjb25zdCB7IHJldHVybiB1cGJfZmllbGRkZWZfbnVtYmVyKHRoaXMpOyB9CitpbmxpbmUgY29uc3QgY2hhciogRmllbGREZWY6Om5hbWUoKSBjb25zdCB7IHJldHVybiB1cGJfZmllbGRkZWZfbmFtZSh0aGlzKTsgfQoraW5saW5lIGJvb2wgRmllbGREZWY6OmlzX2V4dGVuc2lvbigpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9pc2V4dGVuc2lvbih0aGlzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpsYXp5KCkgY29uc3QgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX2xhenkodGhpcyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X2xhenkoYm9vbCBsYXp5KSB7CisgIHVwYl9maWVsZGRlZl9zZXRsYXp5KHRoaXMsIGxhenkpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OnBhY2tlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9wYWNrZWQodGhpcyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X3BhY2tlZChib29sIHBhY2tlZCkgeworICB1cGJfZmllbGRkZWZfc2V0cGFja2VkKHRoaXMsIHBhY2tlZCk7Cit9CitpbmxpbmUgY29uc3QgTWVzc2FnZURlZiogRmllbGREZWY6OmNvbnRhaW5pbmdfdHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZSh0aGlzKTsKK30KK2lubGluZSBjb25zdCBPbmVvZkRlZiogRmllbGREZWY6OmNvbnRhaW5pbmdfb25lb2YoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfY29udGFpbmluZ29uZW9mKHRoaXMpOworfQoraW5saW5lIGNvbnN0IGNoYXIqIEZpZWxkRGVmOjpjb250YWluaW5nX3R5cGVfbmFtZSgpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9jb250YWluaW5ndHlwZW5hbWUodGhpcyk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6c2V0X251bWJlcih1aW50MzJfdCBudW1iZXIsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldG51bWJlcih0aGlzLCBudW1iZXIsIHMpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OnNldF9uYW1lKGNvbnN0IGNoYXIgKm5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldG5hbWUodGhpcywgbmFtZSwgcyk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6c2V0X25hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldG5hbWUodGhpcywgdXBiX3NhZmVjc3RyKG5hbWUpLCBzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfY29udGFpbmluZ190eXBlX25hbWUoY29uc3QgY2hhciAqbmFtZSwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfc2V0Y29udGFpbmluZ3R5cGVuYW1lKHRoaXMsIG5hbWUsIHMpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OnNldF9jb250YWluaW5nX3R5cGVfbmFtZShjb25zdCBzdGQ6OnN0cmluZyAmbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzICpzKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfc2V0Y29udGFpbmluZ3R5cGVuYW1lKHRoaXMsIHVwYl9zYWZlY3N0cihuYW1lKSwgcyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X3R5cGUodXBiX2ZpZWxkdHlwZV90IHR5cGUpIHsKKyAgdXBiX2ZpZWxkZGVmX3NldHR5cGUodGhpcywgdHlwZSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X2lzX2V4dGVuc2lvbihib29sIGlzX2V4dGVuc2lvbikgeworICB1cGJfZmllbGRkZWZfc2V0aXNleHRlbnNpb24odGhpcywgaXNfZXh0ZW5zaW9uKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpzZXRfZGVzY3JpcHRvcl90eXBlKEZpZWxkRGVmOjpEZXNjcmlwdG9yVHlwZSB0eXBlKSB7CisgIHVwYl9maWVsZGRlZl9zZXRkZXNjcmlwdG9ydHlwZSh0aGlzLCB0eXBlKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpzZXRfbGFiZWwodXBiX2xhYmVsX3QgbGFiZWwpIHsKKyAgdXBiX2ZpZWxkZGVmX3NldGxhYmVsKHRoaXMsIGxhYmVsKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpJc1N1Yk1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfaXNzdWJtc2codGhpcyk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6SXNTdHJpbmcoKSBjb25zdCB7IHJldHVybiB1cGJfZmllbGRkZWZfaXNzdHJpbmcodGhpcyk7IH0KK2lubGluZSBib29sIEZpZWxkRGVmOjpJc1NlcXVlbmNlKCkgY29uc3QgeyByZXR1cm4gdXBiX2ZpZWxkZGVmX2lzc2VxKHRoaXMpOyB9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6SXNNYXAoKSBjb25zdCB7IHJldHVybiB1cGJfZmllbGRkZWZfaXNtYXAodGhpcyk7IH0KK2lubGluZSBpbnQ2NF90IEZpZWxkRGVmOjpkZWZhdWx0X2ludDY0KCkgY29uc3QgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX2RlZmF1bHRpbnQ2NCh0aGlzKTsKK30KK2lubGluZSBpbnQzMl90IEZpZWxkRGVmOjpkZWZhdWx0X2ludDMyKCkgY29uc3QgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX2RlZmF1bHRpbnQzMih0aGlzKTsKK30KK2lubGluZSB1aW50NjRfdCBGaWVsZERlZjo6ZGVmYXVsdF91aW50NjQoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfZGVmYXVsdHVpbnQ2NCh0aGlzKTsKK30KK2lubGluZSB1aW50MzJfdCBGaWVsZERlZjo6ZGVmYXVsdF91aW50MzIoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfZGVmYXVsdHVpbnQzMih0aGlzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpkZWZhdWx0X2Jvb2woKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfZGVmYXVsdGJvb2wodGhpcyk7Cit9CitpbmxpbmUgZmxvYXQgRmllbGREZWY6OmRlZmF1bHRfZmxvYXQoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfZGVmYXVsdGZsb2F0KHRoaXMpOworfQoraW5saW5lIGRvdWJsZSBGaWVsZERlZjo6ZGVmYXVsdF9kb3VibGUoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfZGVmYXVsdGRvdWJsZSh0aGlzKTsKK30KK2lubGluZSBjb25zdCBjaGFyKiBGaWVsZERlZjo6ZGVmYXVsdF9zdHJpbmcoc2l6ZV90KiBsZW4pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9kZWZhdWx0c3RyKHRoaXMsIGxlbik7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X2RlZmF1bHRfaW50NjQoaW50NjRfdCB2YWx1ZSkgeworICB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdGludDY0KHRoaXMsIHZhbHVlKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpzZXRfZGVmYXVsdF9pbnQzMihpbnQzMl90IHZhbHVlKSB7CisgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0aW50MzIodGhpcywgdmFsdWUpOworfQoraW5saW5lIHZvaWQgRmllbGREZWY6OnNldF9kZWZhdWx0X3VpbnQ2NCh1aW50NjRfdCB2YWx1ZSkgeworICB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdHVpbnQ2NCh0aGlzLCB2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X2RlZmF1bHRfdWludDMyKHVpbnQzMl90IHZhbHVlKSB7CisgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0dWludDMyKHRoaXMsIHZhbHVlKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpzZXRfZGVmYXVsdF9ib29sKGJvb2wgdmFsdWUpIHsKKyAgdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRib29sKHRoaXMsIHZhbHVlKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpzZXRfZGVmYXVsdF9mbG9hdChmbG9hdCB2YWx1ZSkgeworICB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdGZsb2F0KHRoaXMsIHZhbHVlKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVmOjpzZXRfZGVmYXVsdF9kb3VibGUoZG91YmxlIHZhbHVlKSB7CisgIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0ZG91YmxlKHRoaXMsIHZhbHVlKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfZGVmYXVsdF9zdHJpbmcoY29uc3Qgdm9pZCAqc3RyLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgKnMpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9zZXRkZWZhdWx0c3RyKHRoaXMsIHN0ciwgbGVuLCBzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfZGVmYXVsdF9zdHJpbmcoY29uc3Qgc3RkOjpzdHJpbmcmIHN0ciwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfc2V0ZGVmYXVsdHN0cih0aGlzLCBzdHIuY19zdHIoKSwgc3RyLnNpemUoKSwgcyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlZjo6c2V0X2RlZmF1bHRfY3N0cihjb25zdCBjaGFyKiBzdHIsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldGRlZmF1bHRjc3RyKHRoaXMsIHN0ciwgcyk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlZjo6SGFzU3ViRGVmKCkgY29uc3QgeyByZXR1cm4gdXBiX2ZpZWxkZGVmX2hhc3N1YmRlZih0aGlzKTsgfQoraW5saW5lIGNvbnN0IERlZiogRmllbGREZWY6OnN1YmRlZigpIGNvbnN0IHsgcmV0dXJuIHVwYl9maWVsZGRlZl9zdWJkZWYodGhpcyk7IH0KK2lubGluZSBjb25zdCBNZXNzYWdlRGVmICpGaWVsZERlZjo6bWVzc2FnZV9zdWJkZWYoKSBjb25zdCB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfbXNnc3ViZGVmKHRoaXMpOworfQoraW5saW5lIGNvbnN0IEVudW1EZWYgKkZpZWxkRGVmOjplbnVtX3N1YmRlZigpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9lbnVtc3ViZGVmKHRoaXMpOworfQoraW5saW5lIGNvbnN0IGNoYXIqIEZpZWxkRGVmOjpzdWJkZWZfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9zdWJkZWZuYW1lKHRoaXMpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OnNldF9zdWJkZWYoY29uc3QgRGVmKiBzdWJkZWYsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldHN1YmRlZih0aGlzLCBzdWJkZWYsIHMpOworfQoraW5saW5lIGJvb2wgRmllbGREZWY6OnNldF9lbnVtX3N1YmRlZihjb25zdCBFbnVtRGVmKiBzdWJkZWYsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldGVudW1zdWJkZWYodGhpcywgc3ViZGVmLCBzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfbWVzc2FnZV9zdWJkZWYoY29uc3QgTWVzc2FnZURlZiogc3ViZGVmLCBTdGF0dXMqIHMpIHsKKyAgcmV0dXJuIHVwYl9maWVsZGRlZl9zZXRtc2dzdWJkZWYodGhpcywgc3ViZGVmLCBzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfc3ViZGVmX25hbWUoY29uc3QgY2hhciogbmFtZSwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfZmllbGRkZWZfc2V0c3ViZGVmbmFtZSh0aGlzLCBuYW1lLCBzKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVmOjpzZXRfc3ViZGVmX25hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX2ZpZWxkZGVmX3NldHN1YmRlZm5hbWUodGhpcywgdXBiX3NhZmVjc3RyKG5hbWUpLCBzKTsKK30KKworaW5saW5lIHJlZmZlZF9wdHI8TWVzc2FnZURlZj4gTWVzc2FnZURlZjo6TmV3KCkgeworICB1cGJfbXNnZGVmICptID0gdXBiX21zZ2RlZl9uZXcoJm0pOworICByZXR1cm4gcmVmZmVkX3B0cjxNZXNzYWdlRGVmPihtLCAmbSk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpJc0Zyb3plbigpIGNvbnN0IHsgcmV0dXJuIHVwYl9tc2dkZWZfaXNmcm96ZW4odGhpcyk7IH0KK2lubGluZSB2b2lkIE1lc3NhZ2VEZWY6OlJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3QgeworICByZXR1cm4gdXBiX21zZ2RlZl9yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgTWVzc2FnZURlZjo6VW5yZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfdW5yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgTWVzc2FnZURlZjo6RG9uYXRlUmVmKGNvbnN0IHZvaWQqIGZyb20sIGNvbnN0IHZvaWQqIHRvKSBjb25zdCB7CisgIHJldHVybiB1cGJfbXNnZGVmX2RvbmF0ZXJlZih0aGlzLCBmcm9tLCB0byk7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlRGVmOjpDaGVja1JlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3QgeworICByZXR1cm4gdXBiX21zZ2RlZl9jaGVja3JlZih0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgY29uc3QgY2hhciAqTWVzc2FnZURlZjo6ZnVsbF9uYW1lKCkgY29uc3QgeworICByZXR1cm4gdXBiX21zZ2RlZl9mdWxsbmFtZSh0aGlzKTsKK30KK2lubGluZSBib29sIE1lc3NhZ2VEZWY6OnNldF9mdWxsX25hbWUoY29uc3QgY2hhciogZnVsbG5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX21zZ2RlZl9zZXRmdWxsbmFtZSh0aGlzLCBmdWxsbmFtZSwgcyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpzZXRfZnVsbF9uYW1lKGNvbnN0IHN0ZDo6c3RyaW5nJiBmdWxsbmFtZSwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfbXNnZGVmX3NldGZ1bGxuYW1lKHRoaXMsIHVwYl9zYWZlY3N0cihmdWxsbmFtZSksIHMpOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6RnJlZXplKFN0YXR1cyogc3RhdHVzKSB7CisgIHJldHVybiB1cGJfbXNnZGVmX2ZyZWV6ZSh0aGlzLCBzdGF0dXMpOworfQoraW5saW5lIGludCBNZXNzYWdlRGVmOjpmaWVsZF9jb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfbnVtZmllbGRzKHRoaXMpOworfQoraW5saW5lIGludCBNZXNzYWdlRGVmOjpvbmVvZl9jb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfbnVtb25lb2ZzKHRoaXMpOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6QWRkRmllbGQodXBiX2ZpZWxkZGVmKiBmLCBTdGF0dXMqIHMpIHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfYWRkZmllbGQodGhpcywgZiwgTlVMTCwgcyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpBZGRGaWVsZChjb25zdCByZWZmZWRfcHRyPEZpZWxkRGVmPiYgZiwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfbXNnZGVmX2FkZGZpZWxkKHRoaXMsIGYuZ2V0KCksIE5VTEwsIHMpOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6QWRkT25lb2YodXBiX29uZW9mZGVmKiBvLCBTdGF0dXMqIHMpIHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfYWRkb25lb2YodGhpcywgbywgTlVMTCwgcyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpBZGRPbmVvZihjb25zdCByZWZmZWRfcHRyPE9uZW9mRGVmPiYgbywgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfbXNnZGVmX2FkZG9uZW9mKHRoaXMsIG8uZ2V0KCksIE5VTEwsIHMpOworfQoraW5saW5lIEZpZWxkRGVmKiBNZXNzYWdlRGVmOjpGaW5kRmllbGRCeU51bWJlcih1aW50MzJfdCBudW1iZXIpIHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZl9tdXRhYmxlKHRoaXMsIG51bWJlcik7Cit9CitpbmxpbmUgRmllbGREZWYqIE1lc3NhZ2VEZWY6OkZpbmRGaWVsZEJ5TmFtZShjb25zdCBjaGFyKiBuYW1lLCBzaXplX3QgbGVuKSB7CisgIHJldHVybiB1cGJfbXNnZGVmX250b2ZfbXV0YWJsZSh0aGlzLCBuYW1lLCBsZW4pOworfQoraW5saW5lIGNvbnN0IEZpZWxkRGVmKiBNZXNzYWdlRGVmOjpGaW5kRmllbGRCeU51bWJlcih1aW50MzJfdCBudW1iZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih0aGlzLCBudW1iZXIpOworfQoraW5saW5lIGNvbnN0IEZpZWxkRGVmICpNZXNzYWdlRGVmOjpGaW5kRmllbGRCeU5hbWUoY29uc3QgY2hhciAqbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfbnRvZih0aGlzLCBuYW1lLCBsZW4pOworfQoraW5saW5lIE9uZW9mRGVmKiBNZXNzYWdlRGVmOjpGaW5kT25lb2ZCeU5hbWUoY29uc3QgY2hhciogbmFtZSwgc2l6ZV90IGxlbikgeworICByZXR1cm4gdXBiX21zZ2RlZl9udG9vX211dGFibGUodGhpcywgbmFtZSwgbGVuKTsKK30KK2lubGluZSBjb25zdCBPbmVvZkRlZiogTWVzc2FnZURlZjo6RmluZE9uZW9mQnlOYW1lKGNvbnN0IGNoYXIqIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuKSBjb25zdCB7CisgIHJldHVybiB1cGJfbXNnZGVmX250b28odGhpcywgbmFtZSwgbGVuKTsKK30KK2lubGluZSBNZXNzYWdlRGVmKiBNZXNzYWdlRGVmOjpEdXAoY29uc3Qgdm9pZCAqb3duZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9tc2dkZWZfZHVwKHRoaXMsIG93bmVyKTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VEZWY6OnNldG1hcGVudHJ5KGJvb2wgbWFwX2VudHJ5KSB7CisgIHVwYl9tc2dkZWZfc2V0bWFwZW50cnkodGhpcywgbWFwX2VudHJ5KTsKK30KK2lubGluZSBib29sIE1lc3NhZ2VEZWY6Om1hcGVudHJ5KCkgY29uc3QgeworICByZXR1cm4gdXBiX21zZ2RlZl9tYXBlbnRyeSh0aGlzKTsKK30KK2lubGluZSBNZXNzYWdlRGVmOjpmaWVsZF9pdGVyYXRvciBNZXNzYWdlRGVmOjpmaWVsZF9iZWdpbigpIHsKKyAgcmV0dXJuIGZpZWxkX2l0ZXJhdG9yKHRoaXMpOworfQoraW5saW5lIE1lc3NhZ2VEZWY6OmZpZWxkX2l0ZXJhdG9yIE1lc3NhZ2VEZWY6OmZpZWxkX2VuZCgpIHsKKyAgcmV0dXJuIGZpZWxkX2l0ZXJhdG9yOjplbmQodGhpcyk7Cit9CitpbmxpbmUgTWVzc2FnZURlZjo6Y29uc3RfZmllbGRfaXRlcmF0b3IgTWVzc2FnZURlZjo6ZmllbGRfYmVnaW4oKSBjb25zdCB7CisgIHJldHVybiBjb25zdF9maWVsZF9pdGVyYXRvcih0aGlzKTsKK30KK2lubGluZSBNZXNzYWdlRGVmOjpjb25zdF9maWVsZF9pdGVyYXRvciBNZXNzYWdlRGVmOjpmaWVsZF9lbmQoKSBjb25zdCB7CisgIHJldHVybiBjb25zdF9maWVsZF9pdGVyYXRvcjo6ZW5kKHRoaXMpOworfQorCitpbmxpbmUgTWVzc2FnZURlZjo6b25lb2ZfaXRlcmF0b3IgTWVzc2FnZURlZjo6b25lb2ZfYmVnaW4oKSB7CisgIHJldHVybiBvbmVvZl9pdGVyYXRvcih0aGlzKTsKK30KK2lubGluZSBNZXNzYWdlRGVmOjpvbmVvZl9pdGVyYXRvciBNZXNzYWdlRGVmOjpvbmVvZl9lbmQoKSB7CisgIHJldHVybiBvbmVvZl9pdGVyYXRvcjo6ZW5kKHRoaXMpOworfQoraW5saW5lIE1lc3NhZ2VEZWY6OmNvbnN0X29uZW9mX2l0ZXJhdG9yIE1lc3NhZ2VEZWY6Om9uZW9mX2JlZ2luKCkgY29uc3QgeworICByZXR1cm4gY29uc3Rfb25lb2ZfaXRlcmF0b3IodGhpcyk7Cit9CitpbmxpbmUgTWVzc2FnZURlZjo6Y29uc3Rfb25lb2ZfaXRlcmF0b3IgTWVzc2FnZURlZjo6b25lb2ZfZW5kKCkgY29uc3QgeworICByZXR1cm4gY29uc3Rfb25lb2ZfaXRlcmF0b3I6OmVuZCh0aGlzKTsKK30KKworaW5saW5lIE1lc3NhZ2VEZWY6OmZpZWxkX2l0ZXJhdG9yOjpmaWVsZF9pdGVyYXRvcihNZXNzYWdlRGVmKiBtZCkgeworICB1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpdGVyXywgbWQpOworfQoraW5saW5lIE1lc3NhZ2VEZWY6OmZpZWxkX2l0ZXJhdG9yIE1lc3NhZ2VEZWY6OmZpZWxkX2l0ZXJhdG9yOjplbmQoCisgICAgTWVzc2FnZURlZiogbWQpIHsKKyAgTWVzc2FnZURlZjo6ZmllbGRfaXRlcmF0b3IgaXRlcihtZCk7CisgIHVwYl9tc2dfZmllbGRfaXRlcl9zZXRkb25lKCZpdGVyLml0ZXJfKTsKKyAgcmV0dXJuIGl0ZXI7Cit9CitpbmxpbmUgRmllbGREZWYqIE1lc3NhZ2VEZWY6OmZpZWxkX2l0ZXJhdG9yOjpvcGVyYXRvciooKSBjb25zdCB7CisgIHJldHVybiB1cGJfbXNnX2l0ZXJfZmllbGQoJml0ZXJfKTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VEZWY6OmZpZWxkX2l0ZXJhdG9yOjpvcGVyYXRvcisrKCkgeworICByZXR1cm4gdXBiX21zZ19maWVsZF9uZXh0KCZpdGVyXyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpmaWVsZF9pdGVyYXRvcjo6b3BlcmF0b3I9PSgKKyAgICBjb25zdCBmaWVsZF9pdGVyYXRvciAmb3RoZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9pbnR0YWJsZV9pdGVyX2lzZXF1YWwoJml0ZXJfLCAmb3RoZXIuaXRlcl8pOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6ZmllbGRfaXRlcmF0b3I6Om9wZXJhdG9yIT0oCisgICAgY29uc3QgZmllbGRfaXRlcmF0b3IgJm90aGVyKSBjb25zdCB7CisgIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKK30KKworaW5saW5lIE1lc3NhZ2VEZWY6OmNvbnN0X2ZpZWxkX2l0ZXJhdG9yOjpjb25zdF9maWVsZF9pdGVyYXRvcigKKyAgICBjb25zdCBNZXNzYWdlRGVmKiBtZCkgeworICB1cGJfbXNnX2ZpZWxkX2JlZ2luKCZpdGVyXywgbWQpOworfQoraW5saW5lIE1lc3NhZ2VEZWY6OmNvbnN0X2ZpZWxkX2l0ZXJhdG9yIE1lc3NhZ2VEZWY6OmNvbnN0X2ZpZWxkX2l0ZXJhdG9yOjplbmQoCisgICAgY29uc3QgTWVzc2FnZURlZiAqbWQpIHsKKyAgTWVzc2FnZURlZjo6Y29uc3RfZmllbGRfaXRlcmF0b3IgaXRlcihtZCk7CisgIHVwYl9tc2dfZmllbGRfaXRlcl9zZXRkb25lKCZpdGVyLml0ZXJfKTsKKyAgcmV0dXJuIGl0ZXI7Cit9CitpbmxpbmUgY29uc3QgRmllbGREZWYqIE1lc3NhZ2VEZWY6OmNvbnN0X2ZpZWxkX2l0ZXJhdG9yOjpvcGVyYXRvciooKSBjb25zdCB7CisgIHJldHVybiB1cGJfbXNnX2l0ZXJfZmllbGQoJml0ZXJfKTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VEZWY6OmNvbnN0X2ZpZWxkX2l0ZXJhdG9yOjpvcGVyYXRvcisrKCkgeworICByZXR1cm4gdXBiX21zZ19maWVsZF9uZXh0KCZpdGVyXyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpjb25zdF9maWVsZF9pdGVyYXRvcjo6b3BlcmF0b3I9PSgKKyAgICBjb25zdCBjb25zdF9maWVsZF9pdGVyYXRvciAmb3RoZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9pbnR0YWJsZV9pdGVyX2lzZXF1YWwoJml0ZXJfLCAmb3RoZXIuaXRlcl8pOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6Y29uc3RfZmllbGRfaXRlcmF0b3I6Om9wZXJhdG9yIT0oCisgICAgY29uc3QgY29uc3RfZmllbGRfaXRlcmF0b3IgJm90aGVyKSBjb25zdCB7CisgIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKK30KKworaW5saW5lIE1lc3NhZ2VEZWY6Om9uZW9mX2l0ZXJhdG9yOjpvbmVvZl9pdGVyYXRvcihNZXNzYWdlRGVmKiBtZCkgeworICB1cGJfbXNnX29uZW9mX2JlZ2luKCZpdGVyXywgbWQpOworfQoraW5saW5lIE1lc3NhZ2VEZWY6Om9uZW9mX2l0ZXJhdG9yIE1lc3NhZ2VEZWY6Om9uZW9mX2l0ZXJhdG9yOjplbmQoCisgICAgTWVzc2FnZURlZiogbWQpIHsKKyAgTWVzc2FnZURlZjo6b25lb2ZfaXRlcmF0b3IgaXRlcihtZCk7CisgIHVwYl9tc2dfb25lb2ZfaXRlcl9zZXRkb25lKCZpdGVyLml0ZXJfKTsKKyAgcmV0dXJuIGl0ZXI7Cit9CitpbmxpbmUgT25lb2ZEZWYqIE1lc3NhZ2VEZWY6Om9uZW9mX2l0ZXJhdG9yOjpvcGVyYXRvciooKSBjb25zdCB7CisgIHJldHVybiB1cGJfbXNnX2l0ZXJfb25lb2YoJml0ZXJfKTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VEZWY6Om9uZW9mX2l0ZXJhdG9yOjpvcGVyYXRvcisrKCkgeworICByZXR1cm4gdXBiX21zZ19vbmVvZl9uZXh0KCZpdGVyXyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpvbmVvZl9pdGVyYXRvcjo6b3BlcmF0b3I9PSgKKyAgICBjb25zdCBvbmVvZl9pdGVyYXRvciAmb3RoZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9zdHJ0YWJsZV9pdGVyX2lzZXF1YWwoJml0ZXJfLCAmb3RoZXIuaXRlcl8pOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6b25lb2ZfaXRlcmF0b3I6Om9wZXJhdG9yIT0oCisgICAgY29uc3Qgb25lb2ZfaXRlcmF0b3IgJm90aGVyKSBjb25zdCB7CisgIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKK30KKworaW5saW5lIE1lc3NhZ2VEZWY6OmNvbnN0X29uZW9mX2l0ZXJhdG9yOjpjb25zdF9vbmVvZl9pdGVyYXRvcigKKyAgICBjb25zdCBNZXNzYWdlRGVmKiBtZCkgeworICB1cGJfbXNnX29uZW9mX2JlZ2luKCZpdGVyXywgbWQpOworfQoraW5saW5lIE1lc3NhZ2VEZWY6OmNvbnN0X29uZW9mX2l0ZXJhdG9yIE1lc3NhZ2VEZWY6OmNvbnN0X29uZW9mX2l0ZXJhdG9yOjplbmQoCisgICAgY29uc3QgTWVzc2FnZURlZiAqbWQpIHsKKyAgTWVzc2FnZURlZjo6Y29uc3Rfb25lb2ZfaXRlcmF0b3IgaXRlcihtZCk7CisgIHVwYl9tc2dfb25lb2ZfaXRlcl9zZXRkb25lKCZpdGVyLml0ZXJfKTsKKyAgcmV0dXJuIGl0ZXI7Cit9CitpbmxpbmUgY29uc3QgT25lb2ZEZWYqIE1lc3NhZ2VEZWY6OmNvbnN0X29uZW9mX2l0ZXJhdG9yOjpvcGVyYXRvciooKSBjb25zdCB7CisgIHJldHVybiB1cGJfbXNnX2l0ZXJfb25lb2YoJml0ZXJfKTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VEZWY6OmNvbnN0X29uZW9mX2l0ZXJhdG9yOjpvcGVyYXRvcisrKCkgeworICByZXR1cm4gdXBiX21zZ19vbmVvZl9uZXh0KCZpdGVyXyk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlRGVmOjpjb25zdF9vbmVvZl9pdGVyYXRvcjo6b3BlcmF0b3I9PSgKKyAgICBjb25zdCBjb25zdF9vbmVvZl9pdGVyYXRvciAmb3RoZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9zdHJ0YWJsZV9pdGVyX2lzZXF1YWwoJml0ZXJfLCAmb3RoZXIuaXRlcl8pOworfQoraW5saW5lIGJvb2wgTWVzc2FnZURlZjo6Y29uc3Rfb25lb2ZfaXRlcmF0b3I6Om9wZXJhdG9yIT0oCisgICAgY29uc3QgY29uc3Rfb25lb2ZfaXRlcmF0b3IgJm90aGVyKSBjb25zdCB7CisgIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKK30KKworaW5saW5lIHJlZmZlZF9wdHI8RW51bURlZj4gRW51bURlZjo6TmV3KCkgeworICB1cGJfZW51bWRlZiAqZSA9IHVwYl9lbnVtZGVmX25ldygmZSk7CisgIHJldHVybiByZWZmZWRfcHRyPEVudW1EZWY+KGUsICZlKTsKK30KK2lubGluZSBib29sIEVudW1EZWY6OklzRnJvemVuKCkgY29uc3QgeyByZXR1cm4gdXBiX2VudW1kZWZfaXNmcm96ZW4odGhpcyk7IH0KK2lubGluZSB2b2lkIEVudW1EZWY6OlJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3QgeworICByZXR1cm4gdXBiX2VudW1kZWZfcmVmKHRoaXMsIG93bmVyKTsKK30KK2lubGluZSB2b2lkIEVudW1EZWY6OlVucmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdCB7CisgIHJldHVybiB1cGJfZW51bWRlZl91bnJlZih0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVmOjpEb25hdGVSZWYoY29uc3Qgdm9pZCogZnJvbSwgY29uc3Qgdm9pZCogdG8pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9lbnVtZGVmX2RvbmF0ZXJlZih0aGlzLCBmcm9tLCB0byk7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVmOjpDaGVja1JlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3QgeworICByZXR1cm4gdXBiX2VudW1kZWZfY2hlY2tyZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIGNvbnN0IGNoYXIqIEVudW1EZWY6OmZ1bGxfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9lbnVtZGVmX2Z1bGxuYW1lKHRoaXMpOworfQoraW5saW5lIGJvb2wgRW51bURlZjo6c2V0X2Z1bGxfbmFtZShjb25zdCBjaGFyKiBmdWxsbmFtZSwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfZW51bWRlZl9zZXRmdWxsbmFtZSh0aGlzLCBmdWxsbmFtZSwgcyk7Cit9CitpbmxpbmUgYm9vbCBFbnVtRGVmOjpzZXRfZnVsbF9uYW1lKGNvbnN0IHN0ZDo6c3RyaW5nJiBmdWxsbmFtZSwgU3RhdHVzKiBzKSB7CisgIHJldHVybiB1cGJfZW51bWRlZl9zZXRmdWxsbmFtZSh0aGlzLCB1cGJfc2FmZWNzdHIoZnVsbG5hbWUpLCBzKTsKK30KK2lubGluZSBib29sIEVudW1EZWY6OkZyZWV6ZShTdGF0dXMqIHN0YXR1cykgeworICByZXR1cm4gdXBiX2VudW1kZWZfZnJlZXplKHRoaXMsIHN0YXR1cyk7Cit9CitpbmxpbmUgaW50MzJfdCBFbnVtRGVmOjpkZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gdXBiX2VudW1kZWZfZGVmYXVsdCh0aGlzKTsKK30KK2lubGluZSBib29sIEVudW1EZWY6OnNldF9kZWZhdWx0X3ZhbHVlKGludDMyX3QgdmFsLCBTdGF0dXMqIHN0YXR1cykgeworICByZXR1cm4gdXBiX2VudW1kZWZfc2V0ZGVmYXVsdCh0aGlzLCB2YWwsIHN0YXR1cyk7Cit9CitpbmxpbmUgaW50IEVudW1EZWY6OnZhbHVlX2NvdW50KCkgY29uc3QgeyByZXR1cm4gdXBiX2VudW1kZWZfbnVtdmFscyh0aGlzKTsgfQoraW5saW5lIGJvb2wgRW51bURlZjo6QWRkVmFsdWUoY29uc3QgY2hhciogbmFtZSwgaW50MzJfdCBudW0sIFN0YXR1cyogc3RhdHVzKSB7CisgIHJldHVybiB1cGJfZW51bWRlZl9hZGR2YWwodGhpcywgbmFtZSwgbnVtLCBzdGF0dXMpOworfQoraW5saW5lIGJvb2wgRW51bURlZjo6QWRkVmFsdWUoY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUsIGludDMyX3QgbnVtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzKiBzdGF0dXMpIHsKKyAgcmV0dXJuIHVwYl9lbnVtZGVmX2FkZHZhbCh0aGlzLCB1cGJfc2FmZWNzdHIobmFtZSksIG51bSwgc3RhdHVzKTsKK30KK2lubGluZSBib29sIEVudW1EZWY6OkZpbmRWYWx1ZUJ5TmFtZShjb25zdCBjaGFyKiBuYW1lLCBpbnQzMl90ICpudW0pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9lbnVtZGVmX250b2l6KHRoaXMsIG5hbWUsIG51bSk7Cit9CitpbmxpbmUgY29uc3QgY2hhciogRW51bURlZjo6RmluZFZhbHVlQnlOdW1iZXIoaW50MzJfdCBudW0pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9lbnVtZGVmX2l0b24odGhpcywgbnVtKTsKK30KK2lubGluZSBFbnVtRGVmKiBFbnVtRGVmOjpEdXAoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9lbnVtZGVmX2R1cCh0aGlzLCBvd25lcik7Cit9CisKK2lubGluZSBFbnVtRGVmOjpJdGVyYXRvcjo6SXRlcmF0b3IoY29uc3QgRW51bURlZiogZSkgeworICB1cGJfZW51bV9iZWdpbigmaXRlcl8sIGUpOworfQoraW5saW5lIGludDMyX3QgRW51bURlZjo6SXRlcmF0b3I6Om51bWJlcigpIHsKKyAgcmV0dXJuIHVwYl9lbnVtX2l0ZXJfbnVtYmVyKCZpdGVyXyk7Cit9CitpbmxpbmUgY29uc3QgY2hhciogRW51bURlZjo6SXRlcmF0b3I6Om5hbWUoKSB7CisgIHJldHVybiB1cGJfZW51bV9pdGVyX25hbWUoJml0ZXJfKTsKK30KK2lubGluZSBib29sIEVudW1EZWY6Okl0ZXJhdG9yOjpEb25lKCkgeyByZXR1cm4gdXBiX2VudW1fZG9uZSgmaXRlcl8pOyB9CitpbmxpbmUgdm9pZCBFbnVtRGVmOjpJdGVyYXRvcjo6TmV4dCgpIHsgcmV0dXJuIHVwYl9lbnVtX25leHQoJml0ZXJfKTsgfQorCitpbmxpbmUgcmVmZmVkX3B0cjxPbmVvZkRlZj4gT25lb2ZEZWY6Ok5ldygpIHsKKyAgdXBiX29uZW9mZGVmICpvID0gdXBiX29uZW9mZGVmX25ldygmbyk7CisgIHJldHVybiByZWZmZWRfcHRyPE9uZW9mRGVmPihvLCAmbyk7Cit9CitpbmxpbmUgYm9vbCBPbmVvZkRlZjo6SXNGcm96ZW4oKSBjb25zdCB7IHJldHVybiB1cGJfb25lb2ZkZWZfaXNmcm96ZW4odGhpcyk7IH0KK2lubGluZSB2b2lkIE9uZW9mRGVmOjpSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgT25lb2ZEZWY6OlVucmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdCB7CisgIHJldHVybiB1cGJfb25lb2ZkZWZfdW5yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgT25lb2ZEZWY6OkRvbmF0ZVJlZihjb25zdCB2b2lkKiBmcm9tLCBjb25zdCB2b2lkKiB0bykgY29uc3QgeworICByZXR1cm4gdXBiX29uZW9mZGVmX2RvbmF0ZXJlZih0aGlzLCBmcm9tLCB0byk7Cit9CitpbmxpbmUgdm9pZCBPbmVvZkRlZjo6Q2hlY2tSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9jaGVja3JlZih0aGlzLCBvd25lcik7Cit9CitpbmxpbmUgY29uc3QgY2hhciogT25lb2ZEZWY6OmZ1bGxfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9uYW1lKHRoaXMpOworfQorCitpbmxpbmUgY29uc3QgTWVzc2FnZURlZiogT25lb2ZEZWY6OmNvbnRhaW5pbmdfdHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9jb250YWluaW5ndHlwZSh0aGlzKTsKK30KK2lubGluZSBjb25zdCBjaGFyKiBPbmVvZkRlZjo6bmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9uYW1lKHRoaXMpOworfQoraW5saW5lIGJvb2wgT25lb2ZEZWY6OnNldF9uYW1lKGNvbnN0IGNoYXIqIG5hbWUsIFN0YXR1cyogcykgeworICByZXR1cm4gdXBiX29uZW9mZGVmX3NldG5hbWUodGhpcywgbmFtZSwgcyk7Cit9CitpbmxpbmUgaW50IE9uZW9mRGVmOjpmaWVsZF9jb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9udW1maWVsZHModGhpcyk7Cit9CitpbmxpbmUgYm9vbCBPbmVvZkRlZjo6QWRkRmllbGQoRmllbGREZWYqIGZpZWxkLCBTdGF0dXMqIHMpIHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9hZGRmaWVsZCh0aGlzLCBmaWVsZCwgTlVMTCwgcyk7Cit9CitpbmxpbmUgYm9vbCBPbmVvZkRlZjo6QWRkRmllbGQoY29uc3QgcmVmZmVkX3B0cjxGaWVsZERlZj4mIGZpZWxkLCBTdGF0dXMqIHMpIHsKKyAgcmV0dXJuIHVwYl9vbmVvZmRlZl9hZGRmaWVsZCh0aGlzLCBmaWVsZC5nZXQoKSwgTlVMTCwgcyk7Cit9CitpbmxpbmUgY29uc3QgRmllbGREZWYqIE9uZW9mRGVmOjpGaW5kRmllbGRCeU5hbWUoY29uc3QgY2hhciogbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuKSBjb25zdCB7CisgIHJldHVybiB1cGJfb25lb2ZkZWZfbnRvZih0aGlzLCBuYW1lLCBsZW4pOworfQoraW5saW5lIGNvbnN0IEZpZWxkRGVmKiBPbmVvZkRlZjo6RmluZEZpZWxkQnlOdW1iZXIodWludDMyX3QgbnVtKSBjb25zdCB7CisgIHJldHVybiB1cGJfb25lb2ZkZWZfaXRvZih0aGlzLCBudW0pOworfQoraW5saW5lIE9uZW9mRGVmOjppdGVyYXRvciBPbmVvZkRlZjo6YmVnaW4oKSB7IHJldHVybiBpdGVyYXRvcih0aGlzKTsgfQoraW5saW5lIE9uZW9mRGVmOjppdGVyYXRvciBPbmVvZkRlZjo6ZW5kKCkgeyByZXR1cm4gaXRlcmF0b3I6OmVuZCh0aGlzKTsgfQoraW5saW5lIE9uZW9mRGVmOjpjb25zdF9pdGVyYXRvciBPbmVvZkRlZjo6YmVnaW4oKSBjb25zdCB7CisgIHJldHVybiBjb25zdF9pdGVyYXRvcih0aGlzKTsKK30KK2lubGluZSBPbmVvZkRlZjo6Y29uc3RfaXRlcmF0b3IgT25lb2ZEZWY6OmVuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIGNvbnN0X2l0ZXJhdG9yOjplbmQodGhpcyk7Cit9CisKK2lubGluZSBPbmVvZkRlZjo6aXRlcmF0b3I6Oml0ZXJhdG9yKE9uZW9mRGVmKiBvKSB7CisgIHVwYl9vbmVvZl9iZWdpbigmaXRlcl8sIG8pOworfQoraW5saW5lIE9uZW9mRGVmOjppdGVyYXRvciBPbmVvZkRlZjo6aXRlcmF0b3I6OmVuZChPbmVvZkRlZiogbykgeworICBPbmVvZkRlZjo6aXRlcmF0b3IgaXRlcihvKTsKKyAgdXBiX29uZW9mX2l0ZXJfc2V0ZG9uZSgmaXRlci5pdGVyXyk7CisgIHJldHVybiBpdGVyOworfQoraW5saW5lIEZpZWxkRGVmKiBPbmVvZkRlZjo6aXRlcmF0b3I6Om9wZXJhdG9yKigpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9vbmVvZl9pdGVyX2ZpZWxkKCZpdGVyXyk7Cit9CitpbmxpbmUgdm9pZCBPbmVvZkRlZjo6aXRlcmF0b3I6Om9wZXJhdG9yKysoKSB7IHJldHVybiB1cGJfb25lb2ZfbmV4dCgmaXRlcl8pOyB9CitpbmxpbmUgYm9vbCBPbmVvZkRlZjo6aXRlcmF0b3I6Om9wZXJhdG9yPT0oY29uc3QgaXRlcmF0b3IgJm90aGVyKSBjb25zdCB7CisgIHJldHVybiB1cGJfaW50dGFibGVfaXRlcl9pc2VxdWFsKCZpdGVyXywgJm90aGVyLml0ZXJfKTsKK30KK2lubGluZSBib29sIE9uZW9mRGVmOjppdGVyYXRvcjo6b3BlcmF0b3IhPShjb25zdCBpdGVyYXRvciAmb3RoZXIpIGNvbnN0IHsKKyAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOworfQorCitpbmxpbmUgT25lb2ZEZWY6OmNvbnN0X2l0ZXJhdG9yOjpjb25zdF9pdGVyYXRvcihjb25zdCBPbmVvZkRlZiogbWQpIHsKKyAgdXBiX29uZW9mX2JlZ2luKCZpdGVyXywgbWQpOworfQoraW5saW5lIE9uZW9mRGVmOjpjb25zdF9pdGVyYXRvciBPbmVvZkRlZjo6Y29uc3RfaXRlcmF0b3I6OmVuZCgKKyAgICBjb25zdCBPbmVvZkRlZiAqbWQpIHsKKyAgT25lb2ZEZWY6OmNvbnN0X2l0ZXJhdG9yIGl0ZXIobWQpOworICB1cGJfb25lb2ZfaXRlcl9zZXRkb25lKCZpdGVyLml0ZXJfKTsKKyAgcmV0dXJuIGl0ZXI7Cit9CitpbmxpbmUgY29uc3QgRmllbGREZWYqIE9uZW9mRGVmOjpjb25zdF9pdGVyYXRvcjo6b3BlcmF0b3IqKCkgY29uc3QgeworICByZXR1cm4gdXBiX21zZ19pdGVyX2ZpZWxkKCZpdGVyXyk7Cit9CitpbmxpbmUgdm9pZCBPbmVvZkRlZjo6Y29uc3RfaXRlcmF0b3I6Om9wZXJhdG9yKysoKSB7CisgIHJldHVybiB1cGJfb25lb2ZfbmV4dCgmaXRlcl8pOworfQoraW5saW5lIGJvb2wgT25lb2ZEZWY6OmNvbnN0X2l0ZXJhdG9yOjpvcGVyYXRvcj09KAorICAgIGNvbnN0IGNvbnN0X2l0ZXJhdG9yICZvdGhlcikgY29uc3QgeworICByZXR1cm4gdXBiX2ludHRhYmxlX2l0ZXJfaXNlcXVhbCgmaXRlcl8sICZvdGhlci5pdGVyXyk7Cit9CitpbmxpbmUgYm9vbCBPbmVvZkRlZjo6Y29uc3RfaXRlcmF0b3I6Om9wZXJhdG9yIT0oCisgICAgY29uc3QgY29uc3RfaXRlcmF0b3IgJm90aGVyKSBjb25zdCB7CisgIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHVwYgorI2VuZGlmCisKKyN1bmRlZiBVUEJfREVGSU5FX0RFRgorI3VuZGVmIFVQQl9ERUZfQ0FTVFMKKyN1bmRlZiBVUEJfQ1BQX0NBU1RTCisKKyNlbmRpZiAvKiBVUEJfREVGX0hfICovCisvLyBUaGlzIGZpbGUgY29udGFpbnMgYWNjZXNzb3JzIGZvciBhIHNldCBvZiBjb21waWxlZC1pbiBkZWZzLgorLy8gTm90ZSB0aGF0IHVubGlrZSBHb29nbGUncyBwcm90b2J1ZiwgaXQgZG9lcyAqbm90KiBkZWZpbmUKKy8vIGdlbmVyYXRlZCBjbGFzc2VzIG9yIGFueSBvdGhlciBraW5kIG9mIGRhdGEgc3RydWN0dXJlIGZvcgorLy8gYWN0dWFsbHkgc3RvcmluZyBwcm90b2J1ZnMuICBJdCBvbmx5IGNvbnRhaW5zICpkZWZzKiB3aGljaAorLy8gbGV0IHlvdSByZWZsZWN0IG92ZXIgYSBwcm90b2J1ZiAqc2NoZW1hKi4KKy8vCisvLyBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB1cGJjICh0aGUgdXBiIGNvbXBpbGVyKS4KKy8vIERvIG5vdCBlZGl0IC0tIHlvdXIgY2hhbmdlcyB3aWxsIGJlIGRpc2NhcmRlZCB3aGVuIHRoZSBmaWxlIGlzCisvLyByZWdlbmVyYXRlZC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUl9VUEJfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JfVVBCX0hfCisKKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMDktMjAxMiBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogQSBzeW10YWIgKHN5bWJvbCB0YWJsZSkgc3RvcmVzIGEgbmFtZS0+ZGVmIG1hcCBvZiB1cGJfZGVmcy4gIENsaWVudHMgY291bGQKKyAqIGFsd2F5cyBjcmVhdGUgc3VjaCB0YWJsZXMgdGhlbXNlbHZlcywgYnV0IHVwYl9zeW10YWIgaGFzIGxvZ2ljIGZvciByZXNvbHZpbmcKKyAqIHN5bWJvbGljIHJlZmVyZW5jZXMsIGFuZCBpbiBwYXJ0aWN1bGFyLCBmb3Iga2VlcGluZyBhIHdob2xlIHNldCBvZiBjb25zaXN0ZW50CisgKiBkZWZzIHdoZW4gcmVwbGFjaW5nIHNvbWUgc3Vic2V0IG9mIHRob3NlIGRlZnMuICBUaGlzIGxvZ2ljIGlzIG5vbnRyaXZpYWwuCisgKgorICogVGhpcyBpcyBhIG1peGVkIEMvQysrIGludGVyZmFjZSB0aGF0IG9mZmVycyBhIGZ1bGwgQVBJIHRvIGJvdGggbGFuZ3VhZ2VzLgorICogU2VlIHRoZSB0b3AtbGV2ZWwgUkVBRE1FIGZvciBtb3JlIGluZm9ybWF0aW9uLgorICovCisKKyNpZm5kZWYgVVBCX1NZTVRBQl9IXworI2RlZmluZSBVUEJfU1lNVEFCX0hfCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCisjaW5jbHVkZSA8dmVjdG9yPgorbmFtZXNwYWNlIHVwYiB7IGNsYXNzIFN5bWJvbFRhYmxlOyB9CisjZW5kaWYKKworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OlN5bWJvbFRhYmxlLCB1cGJfc3ltdGFiKTsKKwordHlwZWRlZiBzdHJ1Y3QgeworIFVQQl9QUklWQVRFX0ZPUl9DUFAKKyAgdXBiX3N0cnRhYmxlX2l0ZXIgaXRlcjsKKyAgdXBiX2RlZnR5cGVfdCB0eXBlOworfSB1cGJfc3ltdGFiX2l0ZXI7CisKKy8vIE5vbi1jb25zdCBtZXRob2RzIGluIHVwYjo6U3ltYm9sVGFibGUgYXJlIE5PVCB0aHJlYWQtc2FmZS4KK1VQQl9ERUZJTkVfQ0xBU1MxKHVwYjo6U3ltYm9sVGFibGUsIHVwYjo6UmVmQ291bnRlZCwKKyBwdWJsaWM6CisgIC8vIFJldHVybnMgYSBuZXcgc3ltYm9sIHRhYmxlIHdpdGggYSBzaW5nbGUgcmVmIG93bmVkIGJ5ICJvd25lci4iCisgIC8vIFJldHVybnMgTlVMTCBpZiBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQuCisgIHN0YXRpYyByZWZmZWRfcHRyPFN5bWJvbFRhYmxlPiBOZXcoKTsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpSZWZDb3VudGVkLgorICBib29sIElzRnJvemVuKCkgY29uc3Q7CisgIHZvaWQgUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBVbnJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisgIHZvaWQgRG9uYXRlUmVmKGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKSBjb25zdDsKKyAgdm9pZCBDaGVja1JlZihjb25zdCB2b2lkICpvd25lcikgY29uc3Q7CisKKyAgLy8gRm9yIGFsbCBsb29rdXAgZnVuY3Rpb25zLCB0aGUgcmV0dXJuZWQgcG9pbnRlciBpcyBub3Qgb3duZWQgYnkgdGhlCisgIC8vIGNhbGxlcjsgaXQgbWF5IGJlIGludmFsaWRhdGVkIGJ5IGFueSBub24tY29uc3QgY2FsbCBvciB1bnJlZiBvZiB0aGUKKyAgLy8gU3ltYm9sVGFibGUhICBUbyBwcm90ZWN0IGFnYWluc3QgdGhpcywgdGFrZSBhIHJlZiBpZiBkZXNpcmVkLgorCisgIC8vIEZyZWV6ZXMgdGhlIHN5bWJvbCB0YWJsZTogcHJldmVudHMgZnVydGhlciBtb2RpZmljYXRpb24gb2YgaXQuCisgIC8vIEFmdGVyIHRoZSBGcmVlemUoKSBvcGVyYXRpb24gaXMgc3VjY2Vzc2Z1bCwgdGhlIFN5bWJvbFRhYmxlIG11c3Qgb25seSBiZQorICAvLyBhY2Nlc3NlZCB2aWEgYSBjb25zdCBwb2ludGVyLgorICAvLworICAvLyBVbmxpa2Ugd2l0aCB1cGI6Ok1lc3NhZ2VEZWYvdXBiOjpFbnVtRGVmL2V0YywgZnJlZXppbmcgYSBTeW1ib2xUYWJsZSBpcyBub3QKKyAgLy8gYSBuZWNlc3Nhcnkgc3RlcCBpbiB1c2luZyBhIFN5bWJvbFRhYmxlLiAgSWYgeW91IGhhdmUgbm8gbmVlZCBmb3IgaXQgdG8gYmUKKyAgLy8gaW1tdXRhYmxlLCB0aGVyZSBpcyBubyBuZWVkIHRvIGZyZWV6ZSBpdCBldmVyLiAgSG93ZXZlciBzb21ldGltZXMgaXQgaXMKKyAgLy8gdXNlZnVsLCBhbmQgU3ltYm9sVGFibGVzIHRoYXQgYXJlIHN0YXRpY2FsbHkgY29tcGlsZWQgaW50byB0aGUgYmluYXJ5IGFyZQorICAvLyBhbHdheXMgZnJvemVuIGJ5IG5hdHVyZS4KKyAgdm9pZCBGcmVlemUoKTsKKworICAvLyBSZXNvbHZlcyB0aGUgZ2l2ZW4gc3ltYm9sIHVzaW5nIHRoZSBydWxlcyBkZXNjcmliZWQgaW4gZGVzY3JpcHRvci5wcm90bywKKyAgLy8gbmFtZWx5OgorICAvLworICAvLyAgICBJZiB0aGUgbmFtZSBzdGFydHMgd2l0aCBhICcuJywgaXQgaXMgZnVsbHktcXVhbGlmaWVkLiAgT3RoZXJ3aXNlLAorICAvLyAgICBDKystbGlrZSBzY29waW5nIHJ1bGVzIGFyZSB1c2VkIHRvIGZpbmQgdGhlIHR5cGUgKGkuZS4gZmlyc3QgdGhlIG5lc3RlZAorICAvLyAgICB0eXBlcyB3aXRoaW4gdGhpcyBtZXNzYWdlIGFyZSBzZWFyY2hlZCwgdGhlbiB3aXRoaW4gdGhlIHBhcmVudCwgb24gdXAKKyAgLy8gICAgdG8gdGhlIHJvb3QgbmFtZXNwYWNlKS4KKyAgLy8KKyAgLy8gSWYgbm90IGZvdW5kLCByZXR1cm5zIE5VTEwuCisgIGNvbnN0IERlZiogUmVzb2x2ZShjb25zdCBjaGFyKiBiYXNlLCBjb25zdCBjaGFyKiBzeW0pIGNvbnN0OworCisgIC8vIEZpbmRzIGFuIGVudHJ5IGluIHRoZSBzeW1ib2wgdGFibGUgd2l0aCB0aGlzIGV4YWN0IG5hbWUuICBJZiBub3QgZm91bmQsCisgIC8vIHJldHVybnMgTlVMTC4KKyAgY29uc3QgRGVmKiBMb29rdXAoY29uc3QgY2hhciAqc3ltKSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZURlZiogTG9va3VwTWVzc2FnZShjb25zdCBjaGFyICpzeW0pIGNvbnN0OworICBjb25zdCBFbnVtRGVmKiBMb29rdXBFbnVtKGNvbnN0IGNoYXIgKnN5bSkgY29uc3Q7CisKKyAgLy8gVE9ETzogaW50cm9kdWNlIGEgQysrIGl0ZXJhdG9yLCBidXQgbWFrZSBpdCBuaWNlIGFuZCB0ZW1wbGF0ZWQgc28gdGhhdCBpZgorICAvLyB5b3UgYXNrIGZvciBhbiBpdGVyYXRvciBvZiBNZXNzYWdlRGVmIHRoZSBpdGVyYXRlZCBlbGVtZW50cyBhcmUgc3Ryb25nbHkKKyAgLy8gdHlwZWQgYXMgTWVzc2FnZURlZiouCisKKyAgLy8gQWRkcyB0aGUgZ2l2ZW4gbXV0YWJsZSBkZWZzIHRvIHRoZSBzeW10YWIsIHJlc29sdmluZyBhbGwgc3ltYm9scworICAvLyAoaW5jbHVkaW5nIGVudW0gZGVmYXVsdCB2YWx1ZXMpIGFuZCBmaW5hbGl6aW5nIHRoZSBkZWZzLiAgT25seSBvbmUgZGVmIHBlcgorICAvLyBuYW1lIG1heSBiZSBpbiB0aGUgbGlzdCwgYnV0IGRlZnMgY2FuIHJlcGxhY2UgZXhpc3RpbmcgZGVmcyBpbiB0aGUgc3ltdGFiLgorICAvLyBBbGwgZGVmcyBtdXN0IGhhdmUgYSBuYW1lIC0tIGFub255bW91cyBkZWZzIGFyZSBub3QgYWxsb3dlZC4gIEFub255bW91cworICAvLyBkZWZzIGNhbiBzdGlsbCBiZSBmcm96ZW4gYnkgY2FsbGluZyB1cGJfZGVmX2ZyZWV6ZSgpIGRpcmVjdGx5LgorICAvLworICAvLyBBbnkgZXhpc3RpbmcgZGVmcyB0aGF0IGNhbiByZWFjaCBkZWZzIHRoYXQgYXJlIGJlaW5nIHJlcGxhY2VkIHdpbGwKKyAgLy8gdGhlbXNlbHZlcyBiZSByZXBsYWNlZCBhbHNvLCBzbyB0aGF0IHRoZSByZXN1bHRpbmcgc2V0IG9mIGRlZnMgaXMgZnVsbHkKKyAgLy8gY29uc2lzdGVudC4KKyAgLy8KKyAgLy8gVGhpcyBsb2dpYyBpbXBsZW1lbnRlZCBpbiB0aGlzIG1ldGhvZCBpcyBhIGNvbnZlbmllbmNlOyB1bHRpbWF0ZWx5IGl0CisgIC8vIGNhbGxzIHNvbWUgY29tYmluYXRpb24gb2YgdXBiX2ZpZWxkZGVmX3NldHN1YmRlZigpLCB1cGJfZGVmX2R1cCgpLCBhbmQKKyAgLy8gdXBiX2ZyZWV6ZSgpLCBhbnkgb2Ygd2hpY2ggdGhlIGNsaWVudCBjb3VsZCBjYWxsIHRoZW1zZWxmLiAgSG93ZXZlciwgc2luY2UKKyAgLy8gdGhlIGxvZ2ljIGZvciBkb2luZyBzbyBpcyBub250cml2aWFsLCB3ZSBwcm92aWRlIGl0IGhlcmUuCisgIC8vCisgIC8vIFRoZSBlbnRpcmUgb3BlcmF0aW9uIGVpdGhlciBzdWNjZWVkcyBvciBmYWlscy4gIElmIHRoZSBvcGVyYXRpb24gZmFpbHMsCisgIC8vIHRoZSBzeW10YWIgaXMgdW5jaGFuZ2VkLCBmYWxzZSBpcyByZXR1cm5lZCwgYW5kIHN0YXR1cyBpbmRpY2F0ZXMgdGhlCisgIC8vIGVycm9yLiAgVGhlIGNhbGxlciBwYXNzZXMgYSByZWYgb24gYWxsIGRlZnMgdG8gdGhlIHN5bXRhYiAoZXZlbiBpZiB0aGUKKyAgLy8gb3BlcmF0aW9uIGZhaWxzKS4KKyAgLy8KKyAgLy8gVE9ETyhoYWJlcm1hbik6IGN1cnJlbnRseSBmYWlsdXJlIHdpbGwgbGVhdmUgdGhlIHN5bXRhYiB1bmNoYW5nZWQsIGJ1dCBtYXkKKyAgLy8gbGVhdmUgdGhlIGRlZnMgdGhlbXNlbHZlcyBwYXJ0aWFsbHkgcmVzb2x2ZWQuICBEb2VzIHRoaXMgbWF0dGVyPyAgSWYgc28gd2UKKyAgLy8gY291bGQgZG8gYSBwcmVwYXNzIHRoYXQgZW5zdXJlcyB0aGF0IGFsbCBzeW1ib2xzIGFyZSByZXNvbHZhYmxlIGFuZCBiYWlsCisgIC8vIGlmIG5vdCwgc28gd2UgZG9uJ3QgbXV0YXRlIGFueXRoaW5nIHVudGlsIHdlIGtub3cgdGhlIG9wZXJhdGlvbiB3aWxsCisgIC8vIHN1Y2NlZWQuCisgIC8vCisgIC8vIFRPRE8oaGFiZXJtYW4pOiBzaW5jZSB0aGUgZGVmcyBtdXN0IGJlIG11dGFibGUsIHJlZmluaW5nIGEgZnJvemVuIGRlZgorICAvLyByZXF1aXJlcyBtYWtpbmcgbXV0YWJsZSBjb3BpZXMgb2YgdGhlIGVudGlyZSB0cmVlLiAgVGhpcyBpcyB3YXN0ZWZ1bCBpZgorICAvLyBvbmx5IGEgZmV3IG1lc3NhZ2VzIGFyZSBjaGFuZ2luZy4gIFdlIG1heSB3YW50IHRvIGFkZCBhIHdheSBvZiBhZGRpbmcgYQorICAvLyB0cmVlIG9mIGZyb3plbiBkZWZzIHRvIHRoZSBzeW10YWIgKHBlcmhhcHMgYW4gYWx0ZXJuYXRlIGNvbnN0cnVjdG9yIHdoZXJlCisgIC8vIHlvdSBwYXNzIHRoZSByb290IG9mIHRoZSB0cmVlPykKKyAgYm9vbCBBZGQoRGVmKmNvbnN0KiBkZWZzLCBpbnQgbiwgdm9pZCogcmVmX2Rvbm9yLCB1cGJfc3RhdHVzKiBzdGF0dXMpOworCisgIGJvb2wgQWRkKGNvbnN0IHN0ZDo6dmVjdG9yPERlZio+JiBkZWZzLCB2b2lkICpvd25lciwgU3RhdHVzKiBzdGF0dXMpIHsKKyAgICByZXR1cm4gQWRkKChEZWYqY29uc3QqKSZkZWZzWzBdLCBkZWZzLnNpemUoKSwgb3duZXIsIHN0YXR1cyk7CisgIH0KKworIHByaXZhdGU6CisgIFVQQl9ESVNBTExPV19QT0RfT1BTKFN5bWJvbFRhYmxlLCB1cGI6OlN5bWJvbFRhYmxlKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUKHVwYl9zeW10YWIsIHVwYl9yZWZjb3VudGVkLAorICB1cGJfc3RydGFibGUgc3ltdGFiOworKSk7CisKKyNkZWZpbmUgVVBCX1NZTVRBQl9JTklUKHN5bXRhYiwgcmVmcywgcmVmMnMpIFwKKyAgeyBVUEJfUkVGQ09VTlRfSU5JVChyZWZzLCByZWYycyksIHN5bXRhYiB9CisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCisvLyBOYXRpdmUgQyBBUEkuCisvLyBGcm9tIHVwYl9yZWZjb3VudGVkLgorYm9vbCB1cGJfc3ltdGFiX2lzZnJvemVuKGNvbnN0IHVwYl9zeW10YWIgKnMpOwordm9pZCB1cGJfc3ltdGFiX3JlZihjb25zdCB1cGJfc3ltdGFiICpzLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9zeW10YWJfdW5yZWYoY29uc3QgdXBiX3N5bXRhYiAqcywgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfc3ltdGFiX2RvbmF0ZXJlZigKKyAgICBjb25zdCB1cGJfc3ltdGFiICpzLCBjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0byk7Cit2b2lkIHVwYl9zeW10YWJfY2hlY2tyZWYoY29uc3QgdXBiX3N5bXRhYiAqcywgY29uc3Qgdm9pZCAqb3duZXIpOworCit1cGJfc3ltdGFiICp1cGJfc3ltdGFiX25ldyhjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9zeW10YWJfZnJlZXplKHVwYl9zeW10YWIgKnMpOworY29uc3QgdXBiX2RlZiAqdXBiX3N5bXRhYl9yZXNvbHZlKGNvbnN0IHVwYl9zeW10YWIgKnMsIGNvbnN0IGNoYXIgKmJhc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqc3ltKTsKK2NvbnN0IHVwYl9kZWYgKnVwYl9zeW10YWJfbG9va3VwKGNvbnN0IHVwYl9zeW10YWIgKnMsIGNvbnN0IGNoYXIgKnN5bSk7Citjb25zdCB1cGJfbXNnZGVmICp1cGJfc3ltdGFiX2xvb2t1cG1zZyhjb25zdCB1cGJfc3ltdGFiICpzLCBjb25zdCBjaGFyICpzeW0pOworY29uc3QgdXBiX2VudW1kZWYgKnVwYl9zeW10YWJfbG9va3VwZW51bShjb25zdCB1cGJfc3ltdGFiICpzLCBjb25zdCBjaGFyICpzeW0pOworYm9vbCB1cGJfc3ltdGFiX2FkZCh1cGJfc3ltdGFiICpzLCB1cGJfZGVmICpjb25zdCpkZWZzLCBpbnQgbiwgdm9pZCAqcmVmX2Rvbm9yLAorICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzdGF0dXMpOworCisvLyB1cGJfc3ltdGFiX2l0ZXIgaTsKKy8vIGZvcih1cGJfc3ltdGFiX2JlZ2luKCZpLCBzLCB0eXBlKTsgIXVwYl9zeW10YWJfZG9uZSgmaSk7CisvLyAgICAgdXBiX3N5bXRhYl9uZXh0KCZpKSkgeworLy8gICBjb25zdCB1cGJfZGVmICpkZWYgPSB1cGJfc3ltdGFiX2l0ZXJfZGVmKCZpKTsKKy8vICAgLy8gLi4uCisvLyB9CisvLworLy8gRm9yIEMgd2UgZG9uJ3QgaGF2ZSBzZXBhcmF0ZSBpdGVyYXRvcnMgZm9yIGNvbnN0IGFuZCBub24tY29uc3QuCisvLyBJdCBpcyB0aGUgY2FsbGVyJ3MgcmVzcG9uc2liaWxpdHkgdG8gY2FzdCB0aGUgdXBiX2ZpZWxkZGVmKiB0bworLy8gY29uc3QgaWYgdGhlIHVwYl9tc2dkZWYqIGlzIGNvbnN0Lgordm9pZCB1cGJfc3ltdGFiX2JlZ2luKHVwYl9zeW10YWJfaXRlciAqaXRlciwgY29uc3QgdXBiX3N5bXRhYiAqcywKKyAgICAgICAgICAgICAgICAgICAgICB1cGJfZGVmdHlwZV90IHR5cGUpOwordm9pZCB1cGJfc3ltdGFiX25leHQodXBiX3N5bXRhYl9pdGVyICppdGVyKTsKK2Jvb2wgdXBiX3N5bXRhYl9kb25lKGNvbnN0IHVwYl9zeW10YWJfaXRlciAqaXRlcik7Citjb25zdCB1cGJfZGVmICp1cGJfc3ltdGFiX2l0ZXJfZGVmKGNvbnN0IHVwYl9zeW10YWJfaXRlciAqaXRlcik7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworI2lmZGVmIF9fY3BsdXNwbHVzCisvLyBDKysgaW5saW5lIHdyYXBwZXJzLgorbmFtZXNwYWNlIHVwYiB7CitpbmxpbmUgcmVmZmVkX3B0cjxTeW1ib2xUYWJsZT4gU3ltYm9sVGFibGU6Ok5ldygpIHsKKyAgdXBiX3N5bXRhYiAqcyA9IHVwYl9zeW10YWJfbmV3KCZzKTsKKyAgcmV0dXJuIHJlZmZlZF9wdHI8U3ltYm9sVGFibGU+KHMsICZzKTsKK30KKworaW5saW5lIGJvb2wgU3ltYm9sVGFibGU6OklzRnJvemVuKCkgY29uc3QgeworICByZXR1cm4gdXBiX3N5bXRhYl9pc2Zyb3plbih0aGlzKTsKK30KK2lubGluZSB2b2lkIFN5bWJvbFRhYmxlOjpSZWYoY29uc3Qgdm9pZCAqb3duZXIpIGNvbnN0IHsKKyAgdXBiX3N5bXRhYl9yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgU3ltYm9sVGFibGU6OlVucmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdCB7CisgIHVwYl9zeW10YWJfdW5yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgU3ltYm9sVGFibGU6OkRvbmF0ZVJlZihjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0bykgY29uc3QgeworICB1cGJfc3ltdGFiX2RvbmF0ZXJlZih0aGlzLCBmcm9tLCB0byk7Cit9CitpbmxpbmUgdm9pZCBTeW1ib2xUYWJsZTo6Q2hlY2tSZWYoY29uc3Qgdm9pZCAqb3duZXIpIGNvbnN0IHsKKyAgdXBiX3N5bXRhYl9jaGVja3JlZih0aGlzLCBvd25lcik7Cit9CisKK2lubGluZSB2b2lkIFN5bWJvbFRhYmxlOjpGcmVlemUoKSB7CisgIHJldHVybiB1cGJfc3ltdGFiX2ZyZWV6ZSh0aGlzKTsKK30KK2lubGluZSBjb25zdCBEZWYgKlN5bWJvbFRhYmxlOjpSZXNvbHZlKGNvbnN0IGNoYXIgKmJhc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpzeW0pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9zeW10YWJfcmVzb2x2ZSh0aGlzLCBiYXNlLCBzeW0pOworfQoraW5saW5lIGNvbnN0IERlZiogU3ltYm9sVGFibGU6Okxvb2t1cChjb25zdCBjaGFyICpzeW0pIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9zeW10YWJfbG9va3VwKHRoaXMsIHN5bSk7Cit9CitpbmxpbmUgY29uc3QgTWVzc2FnZURlZiAqU3ltYm9sVGFibGU6Okxvb2t1cE1lc3NhZ2UoY29uc3QgY2hhciAqc3ltKSBjb25zdCB7CisgIHJldHVybiB1cGJfc3ltdGFiX2xvb2t1cG1zZyh0aGlzLCBzeW0pOworfQoraW5saW5lIGJvb2wgU3ltYm9sVGFibGU6OkFkZCgKKyAgICBEZWYqY29uc3QqIGRlZnMsIGludCBuLCB2b2lkKiByZWZfZG9ub3IsIHVwYl9zdGF0dXMqIHN0YXR1cykgeworICByZXR1cm4gdXBiX3N5bXRhYl9hZGQodGhpcywgKHVwYl9kZWYqY29uc3QqKWRlZnMsIG4sIHJlZl9kb25vciwgc3RhdHVzKTsKK30KK30gIC8vIG5hbWVzcGFjZSB1cGIKKyNlbmRpZgorCisjZW5kaWYgIC8qIFVQQl9TWU1UQUJfSF8gKi8KKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvLyBFbnVtcworCit0eXBlZGVmIGVudW0geworICBHT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fTEFCRUxfT1BUSU9OQUwgPSAxLAorICBHT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fTEFCRUxfUkVRVUlSRUQgPSAyLAorICBHT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fTEFCRUxfUkVQRUFURUQgPSAzLAorfSBnb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWw7CisKK3R5cGVkZWYgZW51bSB7CisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX0RPVUJMRSA9IDEsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX0ZMT0FUID0gMiwKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfSU5UNjQgPSAzLAorICBHT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fVFlQRV9VSU5UNjQgPSA0LAorICBHT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fVFlQRV9JTlQzMiA9IDUsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX0ZJWEVENjQgPSA2LAorICBHT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fVFlQRV9GSVhFRDMyID0gNywKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfQk9PTCA9IDgsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX1NUUklORyA9IDksCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX0dST1VQID0gMTAsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX01FU1NBR0UgPSAxMSwKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfQllURVMgPSAxMiwKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfVUlOVDMyID0gMTMsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX0VOVU0gPSAxNCwKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfU0ZJWEVEMzIgPSAxNSwKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfU0ZJWEVENjQgPSAxNiwKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfU0lOVDMyID0gMTcsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX1NJTlQ2NCA9IDE4LAorfSBnb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZTsKKwordHlwZWRlZiBlbnVtIHsKKyAgR09PR0xFX1BST1RPQlVGX0ZJRUxET1BUSU9OU19TVFJJTkcgPSAwLAorICBHT09HTEVfUFJPVE9CVUZfRklFTERPUFRJT05TX0NPUkQgPSAxLAorICBHT09HTEVfUFJPVE9CVUZfRklFTERPUFRJT05TX1NUUklOR19QSUVDRSA9IDIsCit9IGdvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnNfQ1R5cGU7CisKK3R5cGVkZWYgZW51bSB7CisgIEdPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19TUEVFRCA9IDEsCisgIEdPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19DT0RFX1NJWkUgPSAyLAorICBHT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfTElURV9SVU5USU1FID0gMywKK30gZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX09wdGltaXplTW9kZTsKKworLy8gU2VsZWN0b3JzCisKKy8vIGdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8KKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SUFJPVE9fRklFTERfU1RBUlRTVUJNU0cgMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19ORVNURURfVFlQRV9TVEFSVFNVQk1TRyAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VOVU1fVFlQRV9TVEFSVFNVQk1TRyA0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VYVEVOU0lPTl9SQU5HRV9TVEFSVFNVQk1TRyA1CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VYVEVOU0lPTl9TVEFSVFNVQk1TRyA2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX09QVElPTlNfU1RBUlRTVUJNU0cgNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19GSUVMRF9TVEFSVFNFUSA4CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0ZJRUxEX0VORFNFUSA5CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0ZJRUxEX0VORFNVQk1TRyAxMAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19ORVNURURfVFlQRV9TVEFSVFNFUSAxMQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19ORVNURURfVFlQRV9FTkRTRVEgMTIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SUFJPVE9fTkVTVEVEX1RZUEVfRU5EU1VCTVNHIDEzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VOVU1fVFlQRV9TVEFSVFNFUSAxNAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19FTlVNX1RZUEVfRU5EU0VRIDE1CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VOVU1fVFlQRV9FTkRTVUJNU0cgMTYKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SUFJPVE9fRVhURU5TSU9OX1JBTkdFX1NUQVJUU0VRIDE3CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VYVEVOU0lPTl9SQU5HRV9FTkRTRVEgMTgKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SUFJPVE9fRVhURU5TSU9OX1JBTkdFX0VORFNVQk1TRyAxOQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19FWFRFTlNJT05fU1RBUlRTRVEgMjAKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SUFJPVE9fRVhURU5TSU9OX0VORFNFUSAyMQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19FWFRFTlNJT05fRU5EU1VCTVNHIDIyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX09QVElPTlNfRU5EU1VCTVNHIDIzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX05BTUVfU1RSSU5HIDI0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX05BTUVfU1RBUlRTVFIgMjUKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SUFJPVE9fTkFNRV9FTkRTVFIgMjYKKworLy8gZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JQUk9UT19FWFRFTlNJT05SQU5HRV9TVEFSVF9JTlQzMiAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUlBST1RPX0VYVEVOU0lPTlJBTkdFX0VORF9JTlQzMiAzCisKKy8vIGdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTURFU0NSSVBUT1JQUk9UT19WQUxVRV9TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTURFU0NSSVBUT1JQUk9UT19PUFRJT05TX1NUQVJUU1VCTVNHIDMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9FTlVNREVTQ1JJUFRPUlBST1RPX1ZBTFVFX1NUQVJUU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9FTlVNREVTQ1JJUFRPUlBST1RPX1ZBTFVFX0VORFNFUSA1CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTURFU0NSSVBUT1JQUk9UT19WQUxVRV9FTkRTVUJNU0cgNgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1ERVNDUklQVE9SUFJPVE9fT1BUSU9OU19FTkRTVUJNU0cgNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1ERVNDUklQVE9SUFJPVE9fTkFNRV9TVFJJTkcgOAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1ERVNDUklQVE9SUFJPVE9fTkFNRV9TVEFSVFNUUiA5CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTURFU0NSSVBUT1JQUk9UT19OQU1FX0VORFNUUiAxMAorCisvLyBnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9FTlVNT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTU9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fU1RBUlRTRVEgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1PUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX0VORFNFUSA0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTU9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fRU5EU1VCTVNHIDUKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9FTlVNT1BUSU9OU19BTExPV19BTElBU19CT09MIDYKKworLy8gZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1WQUxVRURFU0NSSVBUT1JQUk9UT19PUFRJT05TX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9FTlVNVkFMVUVERVNDUklQVE9SUFJPVE9fT1BUSU9OU19FTkRTVUJNU0cgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1WQUxVRURFU0NSSVBUT1JQUk9UT19OQU1FX1NUUklORyA0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTVZBTFVFREVTQ1JJUFRPUlBST1RPX05BTUVfU1RBUlRTVFIgNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1WQUxVRURFU0NSSVBUT1JQUk9UT19OQU1FX0VORFNUUiA2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTVZBTFVFREVTQ1JJUFRPUlBST1RPX05VTUJFUl9JTlQzMiA3CisKKy8vIGdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTVZBTFVFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTVZBTFVFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNFUSAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRU5VTVZBTFVFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9FTkRTRVEgNAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0VOVU1WQUxVRU9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fRU5EU1VCTVNHIDUKKworLy8gZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fT1BUSU9OU19TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fT1BUSU9OU19FTkRTVUJNU0cgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX05BTUVfU1RSSU5HIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19OQU1FX1NUQVJUU1RSIDUKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19OQU1FX0VORFNUUiA2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fRVhURU5ERUVfU1RSSU5HIDcKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19FWFRFTkRFRV9TVEFSVFNUUiA4CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fRVhURU5ERUVfRU5EU1RSIDkKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19OVU1CRVJfSU5UMzIgMTAKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19MQUJFTF9JTlQzMiAxMQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX1RZUEVfSU5UMzIgMTIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRERFU0NSSVBUT1JQUk9UT19UWVBFX05BTUVfU1RSSU5HIDEzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fVFlQRV9OQU1FX1NUQVJUU1RSIDE0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fVFlQRV9OQU1FX0VORFNUUiAxNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX0RFRkFVTFRfVkFMVUVfU1RSSU5HIDE2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERERVNDUklQVE9SUFJPVE9fREVGQVVMVF9WQUxVRV9TVEFSVFNUUiAxNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxEREVTQ1JJUFRPUlBST1RPX0RFRkFVTFRfVkFMVUVfRU5EU1RSIDE4CisKKy8vIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRE9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fU1RBUlRTVUJNU0cgMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxET1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNFUSAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX0VORFNFUSA0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX0VORFNVQk1TRyA1CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERPUFRJT05TX0NUWVBFX0lOVDMyIDYKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRE9QVElPTlNfUEFDS0VEX0JPT0wgNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxET1BUSU9OU19ERVBSRUNBVEVEX0JPT0wgOAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxET1BUSU9OU19MQVpZX0JPT0wgOQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJRUxET1BUSU9OU19FWFBFUklNRU5UQUxfTUFQX0tFWV9TVFJJTkcgMTAKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRE9QVElPTlNfRVhQRVJJTUVOVEFMX01BUF9LRVlfU1RBUlRTVFIgMTEKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUVMRE9QVElPTlNfRVhQRVJJTUVOVEFMX01BUF9LRVlfRU5EU1RSIDEyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklFTERPUFRJT05TX1dFQUtfQk9PTCAxMworCisvLyBnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fTUVTU0FHRV9UWVBFX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX0VOVU1fVFlQRV9TVEFSVFNVQk1TRyAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19TRVJWSUNFX1NUQVJUU1VCTVNHIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX0VYVEVOU0lPTl9TVEFSVFNVQk1TRyA1CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19PUFRJT05TX1NUQVJUU1VCTVNHIDYKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX1NPVVJDRV9DT0RFX0lORk9fU1RBUlRTVUJNU0cgNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fTUVTU0FHRV9UWVBFX1NUQVJUU0VRIDgKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX01FU1NBR0VfVFlQRV9FTkRTRVEgOQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fTUVTU0FHRV9UWVBFX0VORFNVQk1TRyAxMAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fRU5VTV9UWVBFX1NUQVJUU0VRIDExCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19FTlVNX1RZUEVfRU5EU0VRIDEyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19FTlVNX1RZUEVfRU5EU1VCTVNHIDEzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19TRVJWSUNFX1NUQVJUU0VRIDE0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19TRVJWSUNFX0VORFNFUSAxNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fU0VSVklDRV9FTkRTVUJNU0cgMTYKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX0VYVEVOU0lPTl9TVEFSVFNFUSAxNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fRVhURU5TSU9OX0VORFNFUSAxOAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fRVhURU5TSU9OX0VORFNVQk1TRyAxOQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fT1BUSU9OU19FTkRTVUJNU0cgMjAKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX1NPVVJDRV9DT0RFX0lORk9fRU5EU1VCTVNHIDIxCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19OQU1FX1NUUklORyAyMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fTkFNRV9TVEFSVFNUUiAyMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fTkFNRV9FTkRTVFIgMjQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX1BBQ0tBR0VfU1RSSU5HIDI1CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19QQUNLQUdFX1NUQVJUU1RSIDI2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19QQUNLQUdFX0VORFNUUiAyNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fREVQRU5ERU5DWV9TVEFSVFNFUSAyOAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fREVQRU5ERU5DWV9FTkRTRVEgMjkKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX0RFUEVOREVOQ1lfU1RSSU5HIDMwCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19ERVBFTkRFTkNZX1NUQVJUU1RSIDMxCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRURFU0NSSVBUT1JQUk9UT19ERVBFTkRFTkNZX0VORFNUUiAzMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fUFVCTElDX0RFUEVOREVOQ1lfU1RBUlRTRVEgMzMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX1BVQkxJQ19ERVBFTkRFTkNZX0VORFNFUSAzNAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fUFVCTElDX0RFUEVOREVOQ1lfSU5UMzIgMzUKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlBST1RPX1dFQUtfREVQRU5ERU5DWV9TVEFSVFNFUSAzNgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fV0VBS19ERVBFTkRFTkNZX0VORFNFUSAzNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SUFJPVE9fV0VBS19ERVBFTkRFTkNZX0lOVDMyIDM4CisKKy8vIGdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SU0VUX0ZJTEVfU1RBUlRTVUJNU0cgMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SU0VUX0ZJTEVfU1RBUlRTRVEgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVERVNDUklQVE9SU0VUX0ZJTEVfRU5EU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFREVTQ1JJUFRPUlNFVF9GSUxFX0VORFNVQk1TRyA1CisKKy8vIGdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNFUSAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fRU5EU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9FTkRTVUJNU0cgNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX0pBVkFfUEFDS0FHRV9TVFJJTkcgNgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX0pBVkFfUEFDS0FHRV9TVEFSVFNUUiA3CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfSkFWQV9QQUNLQUdFX0VORFNUUiA4CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfSkFWQV9PVVRFUl9DTEFTU05BTUVfU1RSSU5HIDkKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19KQVZBX09VVEVSX0NMQVNTTkFNRV9TVEFSVFNUUiAxMAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX0pBVkFfT1VURVJfQ0xBU1NOQU1FX0VORFNUUiAxMQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX09QVElNSVpFX0ZPUl9JTlQzMiAxMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX0pBVkFfTVVMVElQTEVfRklMRVNfQk9PTCAxMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX0dPX1BBQ0tBR0VfU1RSSU5HIDE0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfR09fUEFDS0FHRV9TVEFSVFNUUiAxNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX0ZJTEVPUFRJT05TX0dPX1BBQ0tBR0VfRU5EU1RSIDE2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfQ0NfR0VORVJJQ19TRVJWSUNFU19CT09MIDE3CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfRklMRU9QVElPTlNfSkFWQV9HRU5FUklDX1NFUlZJQ0VTX0JPT0wgMTgKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19QWV9HRU5FUklDX1NFUlZJQ0VTX0JPT0wgMTkKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9GSUxFT1BUSU9OU19KQVZBX0dFTkVSQVRFX0VRVUFMU19BTkRfSEFTSF9CT09MIDIwCisKKy8vIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FU1NBR0VPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVNTQUdFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNFUSAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfTUVTU0FHRU9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fRU5EU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVNTQUdFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9FTkRTVUJNU0cgNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FU1NBR0VPUFRJT05TX01FU1NBR0VfU0VUX1dJUkVfRk9STUFUX0JPT0wgNgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FU1NBR0VPUFRJT05TX05PX1NUQU5EQVJEX0RFU0NSSVBUT1JfQUNDRVNTT1JfQk9PTCA3CisKKy8vIGdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8KKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVRIT0RERVNDUklQVE9SUFJPVE9fT1BUSU9OU19TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfTUVUSE9EREVTQ1JJUFRPUlBST1RPX09QVElPTlNfRU5EU1VCTVNHIDMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVRIT0RERVNDUklQVE9SUFJPVE9fTkFNRV9TVFJJTkcgNAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FVEhPRERFU0NSSVBUT1JQUk9UT19OQU1FX1NUQVJUU1RSIDUKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVRIT0RERVNDUklQVE9SUFJPVE9fTkFNRV9FTkRTVFIgNgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FVEhPRERFU0NSSVBUT1JQUk9UT19JTlBVVF9UWVBFX1NUUklORyA3CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfTUVUSE9EREVTQ1JJUFRPUlBST1RPX0lOUFVUX1RZUEVfU1RBUlRTVFIgOAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FVEhPRERFU0NSSVBUT1JQUk9UT19JTlBVVF9UWVBFX0VORFNUUiA5CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfTUVUSE9EREVTQ1JJUFRPUlBST1RPX09VVFBVVF9UWVBFX1NUUklORyAxMAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FVEhPRERFU0NSSVBUT1JQUk9UT19PVVRQVVRfVFlQRV9TVEFSVFNUUiAxMQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX01FVEhPRERFU0NSSVBUT1JQUk9UT19PVVRQVVRfVFlQRV9FTkRTVFIgMTIKKworLy8gZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVRIT0RPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVRIT0RPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX1NUQVJUU0VRIDMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9NRVRIT0RPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX0VORFNFUSA0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfTUVUSE9ET1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9FTkRTVUJNU0cgNQorCisvLyBnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NFUlZJQ0VERVNDUklQVE9SUFJPVE9fTUVUSE9EX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TRVJWSUNFREVTQ1JJUFRPUlBST1RPX09QVElPTlNfU1RBUlRTVUJNU0cgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NFUlZJQ0VERVNDUklQVE9SUFJPVE9fTUVUSE9EX1NUQVJUU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TRVJWSUNFREVTQ1JJUFRPUlBST1RPX01FVEhPRF9FTkRTRVEgNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NFUlZJQ0VERVNDUklQVE9SUFJPVE9fTUVUSE9EX0VORFNVQk1TRyA2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU0VSVklDRURFU0NSSVBUT1JQUk9UT19PUFRJT05TX0VORFNVQk1TRyA3CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU0VSVklDRURFU0NSSVBUT1JQUk9UT19OQU1FX1NUUklORyA4CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU0VSVklDRURFU0NSSVBUT1JQUk9UT19OQU1FX1NUQVJUU1RSIDkKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TRVJWSUNFREVTQ1JJUFRPUlBST1RPX05BTUVfRU5EU1RSIDEwCisKKy8vIGdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NFUlZJQ0VPUFRJT05TX1VOSU5URVJQUkVURURfT1BUSU9OX1NUQVJUU1VCTVNHIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TRVJWSUNFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9TVEFSVFNFUSAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU0VSVklDRU9QVElPTlNfVU5JTlRFUlBSRVRFRF9PUFRJT05fRU5EU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TRVJWSUNFT1BUSU9OU19VTklOVEVSUFJFVEVEX09QVElPTl9FTkRTVUJNU0cgNQorCisvLyBnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8KKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TT1VSQ0VDT0RFSU5GT19MT0NBVElPTl9TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU09VUkNFQ09ERUlORk9fTE9DQVRJT05fU1RBUlRTRVEgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NPVVJDRUNPREVJTkZPX0xPQ0FUSU9OX0VORFNFUSA0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU09VUkNFQ09ERUlORk9fTE9DQVRJT05fRU5EU1VCTVNHIDUKKworLy8gZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU09VUkNFQ09ERUlORk9fTE9DQVRJT05fUEFUSF9TVEFSVFNFUSAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU09VUkNFQ09ERUlORk9fTE9DQVRJT05fUEFUSF9FTkRTRVEgMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NPVVJDRUNPREVJTkZPX0xPQ0FUSU9OX1BBVEhfSU5UMzIgNAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NPVVJDRUNPREVJTkZPX0xPQ0FUSU9OX1NQQU5fU1RBUlRTRVEgNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NPVVJDRUNPREVJTkZPX0xPQ0FUSU9OX1NQQU5fRU5EU0VRIDYKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TT1VSQ0VDT0RFSU5GT19MT0NBVElPTl9TUEFOX0lOVDMyIDcKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TT1VSQ0VDT0RFSU5GT19MT0NBVElPTl9MRUFESU5HX0NPTU1FTlRTX1NUUklORyA4CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU09VUkNFQ09ERUlORk9fTE9DQVRJT05fTEVBRElOR19DT01NRU5UU19TVEFSVFNUUiA5CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfU09VUkNFQ09ERUlORk9fTE9DQVRJT05fTEVBRElOR19DT01NRU5UU19FTkRTVFIgMTAKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TT1VSQ0VDT0RFSU5GT19MT0NBVElPTl9UUkFJTElOR19DT01NRU5UU19TVFJJTkcgMTEKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9TT1VSQ0VDT0RFSU5GT19MT0NBVElPTl9UUkFJTElOR19DT01NRU5UU19TVEFSVFNUUiAxMgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1NPVVJDRUNPREVJTkZPX0xPQ0FUSU9OX1RSQUlMSU5HX0NPTU1FTlRTX0VORFNUUiAxMworCisvLyBnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbgorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1VOSU5URVJQUkVURURPUFRJT05fTkFNRV9TVEFSVFNVQk1TRyAyCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfVU5JTlRFUlBSRVRFRE9QVElPTl9OQU1FX1NUQVJUU0VRIDMKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX05BTUVfRU5EU0VRIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX05BTUVfRU5EU1VCTVNHIDUKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX0lERU5USUZJRVJfVkFMVUVfU1RSSU5HIDYKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX0lERU5USUZJRVJfVkFMVUVfU1RBUlRTVFIgNworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1VOSU5URVJQUkVURURPUFRJT05fSURFTlRJRklFUl9WQUxVRV9FTkRTVFIgOAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1VOSU5URVJQUkVURURPUFRJT05fUE9TSVRJVkVfSU5UX1ZBTFVFX1VJTlQ2NCA5CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfVU5JTlRFUlBSRVRFRE9QVElPTl9ORUdBVElWRV9JTlRfVkFMVUVfSU5UNjQgMTAKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX0RPVUJMRV9WQUxVRV9ET1VCTEUgMTEKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX1NUUklOR19WQUxVRV9TVFJJTkcgMTIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX1NUUklOR19WQUxVRV9TVEFSVFNUUiAxMworI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1VOSU5URVJQUkVURURPUFRJT05fU1RSSU5HX1ZBTFVFX0VORFNUUiAxNAorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1VOSU5URVJQUkVURURPUFRJT05fQUdHUkVHQVRFX1ZBTFVFX1NUUklORyAxNQorI2RlZmluZSBTRUxfR09PR0xFX1BST1RPQlVGX1VOSU5URVJQUkVURURPUFRJT05fQUdHUkVHQVRFX1ZBTFVFX1NUQVJUU1RSIDE2CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfVU5JTlRFUlBSRVRFRE9QVElPTl9BR0dSRUdBVEVfVkFMVUVfRU5EU1RSIDE3CisKKy8vIGdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0CisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfVU5JTlRFUlBSRVRFRE9QVElPTl9OQU1FUEFSVF9OQU1FX1BBUlRfU1RSSU5HIDIKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX05BTUVQQVJUX05BTUVfUEFSVF9TVEFSVFNUUiAzCisjZGVmaW5lIFNFTF9HT09HTEVfUFJPVE9CVUZfVU5JTlRFUlBSRVRFRE9QVElPTl9OQU1FUEFSVF9OQU1FX1BBUlRfRU5EU1RSIDQKKyNkZWZpbmUgU0VMX0dPT0dMRV9QUk9UT0JVRl9VTklOVEVSUFJFVEVET1BUSU9OX05BTUVQQVJUX0lTX0VYVEVOU0lPTl9CT09MIDUKKworY29uc3QgdXBiX3N5bXRhYiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfZGVzY3JpcHRvcihjb25zdCB2b2lkICpvd25lcik7CisKKy8vIE1lc3NhZ2VEZWZzCitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90byhjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfc3ltdGFiX2xvb2t1cG1zZyhzLCAiZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byIpOworICBhc3NlcnQobSk7CisgIHJldHVybiBtOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfbXNnZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UoY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UiKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bURlc2NyaXB0b3JQcm90byhjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfc3ltdGFiX2xvb2t1cG1zZyhzLCAiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8iKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bU9wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyIpOworICBhc3NlcnQobSk7CisgIHJldHVybiBtOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfbXNnZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8oY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8iKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bVZhbHVlT3B0aW9ucyhjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfc3ltdGFiX2xvb2t1cG1zZyhzLCAiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMiKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG8oY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byIpOworICBhc3NlcnQobSk7CisgIHJldHVybiBtOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfbXNnZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMiKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90byhjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfc3ltdGFiX2xvb2t1cG1zZyhzLCAiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8iKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JTZXQoY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCIpOworICBhc3NlcnQobSk7CisgIHJldHVybiBtOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfbXNnZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucyhjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfc3ltdGFiX2xvb2t1cG1zZyhzLCAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01lc3NhZ2VPcHRpb25zKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbSA9IHVwYl9zeW10YWJfbG9va3VwbXNnKHMsICJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMiKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWV0aG9kRGVzY3JpcHRvclByb3RvKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbSA9IHVwYl9zeW10YWJfbG9va3VwbXNnKHMsICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvIik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZE9wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VEZXNjcmlwdG9yUHJvdG8oY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VPcHRpb25zKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsKKyAgY29uc3QgdXBiX21zZ2RlZiAqbSA9IHVwYl9zeW10YWJfbG9va3VwbXNnKHMsICJnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMiKTsKKyAgYXNzZXJ0KG0pOworICByZXR1cm4gbTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX21zZ2RlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU291cmNlQ29kZUluZm8oY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbyIpOworICBhc3NlcnQobSk7CisgIHJldHVybiBtOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfbXNnZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9tc2dkZWYgKm0gPSB1cGJfc3ltdGFiX2xvb2t1cG1zZyhzLCAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb24oY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9tc2dkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoY29uc3QgdXBiX3N5bXRhYiAqcykgeworICBjb25zdCB1cGJfbXNnZGVmICptID0gdXBiX3N5bXRhYl9sb29rdXBtc2cocywgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Iik7CisgIGFzc2VydChtKTsKKyAgcmV0dXJuIG07Cit9CisKKworLy8gRW51bURlZnMKK1VQQl9JTkxJTkUgY29uc3QgdXBiX2VudW1kZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsKKyAgY29uc3QgdXBiX2VudW1kZWYgKmUgPSB1cGJfc3ltdGFiX2xvb2t1cGVudW0ocywgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbCIpOworICBhc3NlcnQoZSk7CisgIHJldHVybiBlOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfZW51bWRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZShjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9lbnVtZGVmICplID0gdXBiX3N5bXRhYl9sb29rdXBlbnVtKHMsICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSIpOworICBhc3NlcnQoZSk7CisgIHJldHVybiBlOworfQorVVBCX0lOTElORSBjb25zdCB1cGJfZW51bWRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGRPcHRpb25zX0NUeXBlKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsKKyAgY29uc3QgdXBiX2VudW1kZWYgKmUgPSB1cGJfc3ltdGFiX2xvb2t1cGVudW0ocywgImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUiKTsKKyAgYXNzZXJ0KGUpOworICByZXR1cm4gZTsKK30KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2VudW1kZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX09wdGltaXplTW9kZShjb25zdCB1cGJfc3ltdGFiICpzKSB7CisgIGNvbnN0IHVwYl9lbnVtZGVmICplID0gdXBiX3N5bXRhYl9sb29rdXBlbnVtKHMsICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIik7CisgIGFzc2VydChlKTsKKyAgcmV0dXJuIGU7Cit9CisKK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZW5kKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UocyksIDIpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX3N0YXJ0KGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UocyksIDEpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvX2VudW1fdHlwZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvKHMpLCA0KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90b19leHRlbnNpb24oY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90byhzKSwgNik7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fZXh0ZW5zaW9uX3JhbmdlKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG8ocyksIDUpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvX2ZpZWxkKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG8ocyksIDIpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvX25hbWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90byhzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fbmVzdGVkX3R5cGUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90byhzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fb3B0aW9ucyhjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvKHMpLCA3KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1EZXNjcmlwdG9yUHJvdG9fbmFtZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bURlc2NyaXB0b3JQcm90byhzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtRGVzY3JpcHRvclByb3RvX29wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1EZXNjcmlwdG9yUHJvdG8ocyksIDMpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bURlc2NyaXB0b3JQcm90b192YWx1ZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bURlc2NyaXB0b3JQcm90byhzKSwgMik7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtT3B0aW9uc19hbGxvd19hbGlhcyhjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bU9wdGlvbnMocyksIDIpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bU9wdGlvbnNfdW5pbnRlcnByZXRlZF9vcHRpb24oY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1PcHRpb25zKHMpLCA5OTkpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX25hbWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1WYWx1ZURlc2NyaXB0b3JQcm90byhzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fbnVtYmVyKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ocyksIDIpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX29wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1WYWx1ZURlc2NyaXB0b3JQcm90byhzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtVmFsdWVPcHRpb25zX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtVmFsdWVPcHRpb25zKHMpLCA5OTkpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fZGVmYXVsdF92YWx1ZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG8ocyksIDcpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fZXh0ZW5kZWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvKHMpLCAyKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvX2xhYmVsKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90byhzKSwgNCk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19uYW1lKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90byhzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19udW1iZXIoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvKHMpLCAzKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvX29wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvKHMpLCA4KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvX3R5cGUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvKHMpLCA1KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvX3R5cGVfbmFtZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG8ocyksIDYpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGRPcHRpb25zX2N0eXBlKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnMocyksIDEpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGRPcHRpb25zX2RlcHJlY2F0ZWQoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9ucyhzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnNfZXhwZXJpbWVudGFsX21hcF9rZXkoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9ucyhzKSwgOSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnNfbGF6eShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGRPcHRpb25zKHMpLCA1KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc19wYWNrZWQoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9ucyhzKSwgMik7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnNfdW5pbnRlcnByZXRlZF9vcHRpb24oY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9ucyhzKSwgOTk5KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc193ZWFrKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnMocyksIDEwKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG9fZGVwZW5kZW5jeShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90byhzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX2VudW1fdHlwZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90byhzKSwgNSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX2V4dGVuc2lvbihjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90byhzKSwgNyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX21lc3NhZ2VfdHlwZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90byhzKSwgNCk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX25hbWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG8ocyksIDEpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90b19vcHRpb25zKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvKHMpLCA4KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG9fcGFja2FnZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90byhzKSwgMik7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX3B1YmxpY19kZXBlbmRlbmN5KGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvKHMpLCAxMCk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX3NlcnZpY2UoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG8ocyksIDYpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90b19zb3VyY2VfY29kZV9pbmZvKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvKHMpLCA5KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG9fd2Vha19kZXBlbmRlbmN5KGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvKHMpLCAxMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclNldF9maWxlKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclNldChzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19jY19nZW5lcmljX3NlcnZpY2VzKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucyhzKSwgMTYpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnNfZ29fcGFja2FnZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnMocyksIDExKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucyhzKSwgMjApOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnNfamF2YV9nZW5lcmljX3NlcnZpY2VzKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucyhzKSwgMTcpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnNfamF2YV9tdWx0aXBsZV9maWxlcyhjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnMocyksIDEwKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucyhzKSwgOCk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19qYXZhX3BhY2thZ2UoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zKHMpLCAxKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX29wdGltaXplX2Zvcihjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnMocyksIDkpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnNfcHlfZ2VuZXJpY19zZXJ2aWNlcyhjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnMocyksIDE4KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucyhzKSwgOTk5KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01lc3NhZ2VPcHRpb25zX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXNzYWdlT3B0aW9ucyhzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXNzYWdlT3B0aW9uc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXNzYWdlT3B0aW9ucyhzKSwgMik7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXNzYWdlT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbihjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWVzc2FnZU9wdGlvbnMocyksIDk5OSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2REZXNjcmlwdG9yUHJvdG9faW5wdXRfdHlwZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWV0aG9kRGVzY3JpcHRvclByb3RvKHMpLCAyKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZERlc2NyaXB0b3JQcm90b19uYW1lKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2REZXNjcmlwdG9yUHJvdG8ocyksIDEpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWV0aG9kRGVzY3JpcHRvclByb3RvX29wdGlvbnMoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZERlc2NyaXB0b3JQcm90byhzKSwgNCk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2REZXNjcmlwdG9yUHJvdG9fb3V0cHV0X3R5cGUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZERlc2NyaXB0b3JQcm90byhzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2RPcHRpb25zX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2RPcHRpb25zKHMpLCA5OTkpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU2VydmljZURlc2NyaXB0b3JQcm90b19tZXRob2QoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VEZXNjcmlwdG9yUHJvdG8ocyksIDIpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU2VydmljZURlc2NyaXB0b3JQcm90b19uYW1lKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9TZXJ2aWNlRGVzY3JpcHRvclByb3RvKHMpLCAxKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VEZXNjcmlwdG9yUHJvdG9fb3B0aW9ucyhjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfU2VydmljZURlc2NyaXB0b3JQcm90byhzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9TZXJ2aWNlT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbihjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfU2VydmljZU9wdGlvbnMocyksIDk5OSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9sZWFkaW5nX2NvbW1lbnRzKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9wYXRoKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihzKSwgMSk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9zcGFuKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihzKSwgMik7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl90cmFpbGluZ19jb21tZW50cyhjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfU291cmNlQ29kZUluZm9fTG9jYXRpb24ocyksIDQpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU291cmNlQ29kZUluZm9fbG9jYXRpb24oY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NvdXJjZUNvZGVJbmZvKHMpLCAxKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnRfaXNfZXh0ZW5zaW9uKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KHMpLCAyKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnRfbmFtZV9wYXJ0KGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KHMpLCAxKTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fYWdncmVnYXRlX3ZhbHVlKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uKHMpLCA4KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fZG91YmxlX3ZhbHVlKGNvbnN0IHVwYl9zeW10YWIgKnMpIHsgcmV0dXJuIHVwYl9tc2dkZWZfaXRvZih1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uKHMpLCA2KTsgfQorVVBCX0lOTElORSBjb25zdCB1cGJfZmllbGRkZWYgKnVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25faWRlbnRpZmllcl92YWx1ZShjb25zdCB1cGJfc3ltdGFiICpzKSB7IHJldHVybiB1cGJfbXNnZGVmX2l0b2YodXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbihzKSwgMyk7IH0KK1VQQl9JTkxJTkUgY29uc3QgdXBiX2ZpZWxkZGVmICp1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uX25hbWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb24ocyksIDIpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9uZWdhdGl2ZV9pbnRfdmFsdWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb24ocyksIDUpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9wb3NpdGl2ZV9pbnRfdmFsdWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb24ocyksIDQpOyB9CitVUEJfSU5MSU5FIGNvbnN0IHVwYl9maWVsZGRlZiAqdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9zdHJpbmdfdmFsdWUoY29uc3QgdXBiX3N5bXRhYiAqcykgeyByZXR1cm4gdXBiX21zZ2RlZl9pdG9mKHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb24ocyksIDcpOyB9CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfTsgIC8vIGV4dGVybiAiQyIKKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKKworbmFtZXNwYWNlIHVwYmRlZnMgeworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGRlc2NyaXB0b3IgeworaW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OlN5bWJvbFRhYmxlPiBTeW1ib2xUYWJsZSgpIHsKKyAgY29uc3QgdXBiOjpTeW1ib2xUYWJsZSogcyA9IHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX2Rlc2NyaXB0b3IoJnMpOworICByZXR1cm4gdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6U3ltYm9sVGFibGU+KHMsICZzKTsKK30KK30gIC8vIG5hbWVzcGFjZSBkZXNjcmlwdG9yCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2RlZmluZSBSRVRVUk5fUkVGRkVEKHR5cGUsIGZ1bmMpIFwKKyAgICBjb25zdCB0eXBlKiBvYmogPSBmdW5jKHVwYmRlZnM6Omdvb2dsZTo6cHJvdG9idWY6OmRlc2NyaXB0b3I6OlN5bWJvbFRhYmxlKCkuZ2V0KCkpOyBcCisgICAgcmV0dXJuIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB0eXBlPihvYmopOworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRGVzY3JpcHRvclByb3RvIHsKK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpNZXNzYWdlRGVmPiBNZXNzYWdlRGVmKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6TWVzc2FnZURlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGVudW1fdHlwZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fZW51bV90eXBlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGV4dGVuc2lvbigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fZXh0ZW5zaW9uKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGV4dGVuc2lvbl9yYW5nZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fZXh0ZW5zaW9uX3JhbmdlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGZpZWxkKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90b19maWVsZCkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBuYW1lKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90b19uYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5lc3RlZF90eXBlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90b19uZXN0ZWRfdHlwZSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBvcHRpb25zKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90b19vcHRpb25zKSB9Cit9ICAvLyBuYW1lc3BhY2UgRGVzY3JpcHRvclByb3RvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIERlc2NyaXB0b3JQcm90byB7CituYW1lc3BhY2UgRXh0ZW5zaW9uUmFuZ2UgeworaW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6Ok1lc3NhZ2VEZWY+IE1lc3NhZ2VEZWYoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpNZXNzYWdlRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZW5kKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0Rlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9lbmQpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gc3RhcnQoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX3N0YXJ0KSB9Cit9ICAvLyBuYW1lc3BhY2UgRXh0ZW5zaW9uUmFuZ2UKK30gIC8vIG5hbWVzcGFjZSBEZXNjcmlwdG9yUHJvdG8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRW51bURlc2NyaXB0b3JQcm90byB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1EZXNjcmlwdG9yUHJvdG8pIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gbmFtZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtRGVzY3JpcHRvclByb3RvX25hbWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gb3B0aW9ucygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtRGVzY3JpcHRvclByb3RvX29wdGlvbnMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gdmFsdWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bURlc2NyaXB0b3JQcm90b192YWx1ZSkgfQorfSAgLy8gbmFtZXNwYWNlIEVudW1EZXNjcmlwdG9yUHJvdG8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRW51bU9wdGlvbnMgeworaW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6Ok1lc3NhZ2VEZWY+IE1lc3NhZ2VEZWYoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpNZXNzYWdlRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtT3B0aW9ucykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBhbGxvd19hbGlhcygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtT3B0aW9uc19hbGxvd19hbGlhcykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiB1bmludGVycHJldGVkX29wdGlvbigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbikgfQorfSAgLy8gbmFtZXNwYWNlIEVudW1PcHRpb25zCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1WYWx1ZURlc2NyaXB0b3JQcm90bykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBuYW1lKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1WYWx1ZURlc2NyaXB0b3JQcm90b19uYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG51bWJlcigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fbnVtYmVyKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG9wdGlvbnMoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX29wdGlvbnMpIH0KK30gIC8vIG5hbWVzcGFjZSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRW51bVZhbHVlT3B0aW9ucyB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0VudW1WYWx1ZU9wdGlvbnMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRW51bVZhbHVlT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbikgfQorfSAgLy8gbmFtZXNwYWNlIEVudW1WYWx1ZU9wdGlvbnMKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRmllbGREZXNjcmlwdG9yUHJvdG8geworaW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6Ok1lc3NhZ2VEZWY+IE1lc3NhZ2VEZWYoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpNZXNzYWdlRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90bykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBkZWZhdWx0X3ZhbHVlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkRGVzY3JpcHRvclByb3RvX2RlZmF1bHRfdmFsdWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZXh0ZW5kZWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fZXh0ZW5kZWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gbGFiZWwoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fbGFiZWwpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gbmFtZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19uYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG51bWJlcigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19udW1iZXIpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gb3B0aW9ucygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19vcHRpb25zKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IHR5cGUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fdHlwZSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiB0eXBlX25hbWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGREZXNjcmlwdG9yUHJvdG9fdHlwZV9uYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RW51bURlZj4gTGFiZWwoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpFbnVtRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkVudW1EZWY+IFR5cGUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpFbnVtRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZERlc2NyaXB0b3JQcm90b19UeXBlKSB9Cit9ICAvLyBuYW1lc3BhY2UgRmllbGREZXNjcmlwdG9yUHJvdG8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRmllbGRPcHRpb25zIHsKK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpNZXNzYWdlRGVmPiBNZXNzYWdlRGVmKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6TWVzc2FnZURlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmllbGRPcHRpb25zKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGN0eXBlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc19jdHlwZSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBkZXByZWNhdGVkKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc19kZXByZWNhdGVkKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGV4cGVyaW1lbnRhbF9tYXBfa2V5KCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc19leHBlcmltZW50YWxfbWFwX2tleSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBsYXp5KCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc19sYXp5KSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IHBhY2tlZCgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnNfcGFja2VkKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbikgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiB3ZWFrKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpZWxkT3B0aW9uc193ZWFrKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RW51bURlZj4gQ1R5cGUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpFbnVtRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWVsZE9wdGlvbnNfQ1R5cGUpIH0KK30gIC8vIG5hbWVzcGFjZSBGaWVsZE9wdGlvbnMKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRmlsZURlc2NyaXB0b3JQcm90byB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG8pIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZGVwZW5kZW5jeSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX2RlcGVuZGVuY3kpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZW51bV90eXBlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG9fZW51bV90eXBlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGV4dGVuc2lvbigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX2V4dGVuc2lvbikgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBtZXNzYWdlX3R5cGUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90b19tZXNzYWdlX3R5cGUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gbmFtZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX25hbWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gb3B0aW9ucygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX29wdGlvbnMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gcGFja2FnZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclByb3RvX3BhY2thZ2UpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gcHVibGljX2RlcGVuZGVuY3koKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90b19wdWJsaWNfZGVwZW5kZW5jeSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBzZXJ2aWNlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG9fc2VydmljZSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBzb3VyY2VfY29kZV9pbmZvKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVEZXNjcmlwdG9yUHJvdG9fc291cmNlX2NvZGVfaW5mbykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiB3ZWFrX2RlcGVuZGVuY3koKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JQcm90b193ZWFrX2RlcGVuZGVuY3kpIH0KK30gIC8vIG5hbWVzcGFjZSBGaWxlRGVzY3JpcHRvclByb3RvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIEZpbGVEZXNjcmlwdG9yU2V0IHsKK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpNZXNzYWdlRGVmPiBNZXNzYWdlRGVmKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6TWVzc2FnZURlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZURlc2NyaXB0b3JTZXQpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZmlsZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlRGVzY3JpcHRvclNldF9maWxlKSB9Cit9ICAvLyBuYW1lc3BhY2UgRmlsZURlc2NyaXB0b3JTZXQKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgRmlsZU9wdGlvbnMgeworaW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6Ok1lc3NhZ2VEZWY+IE1lc3NhZ2VEZWYoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpNZXNzYWdlRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9ucykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBjY19nZW5lcmljX3NlcnZpY2VzKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX2NjX2dlbmVyaWNfc2VydmljZXMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZ29fcGFja2FnZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19nb19wYWNrYWdlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGphdmFfZ2VuZXJpY19zZXJ2aWNlcygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19qYXZhX2dlbmVyaWNfc2VydmljZXMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gamF2YV9tdWx0aXBsZV9maWxlcygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19qYXZhX211bHRpcGxlX2ZpbGVzKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGphdmFfb3V0ZXJfY2xhc3NuYW1lKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX2phdmFfb3V0ZXJfY2xhc3NuYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGphdmFfcGFja2FnZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19qYXZhX3BhY2thZ2UpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gb3B0aW1pemVfZm9yKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX29wdGltaXplX2ZvcikgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBweV9nZW5lcmljX3NlcnZpY2VzKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX0ZpbGVPcHRpb25zX3B5X2dlbmVyaWNfc2VydmljZXMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfRmlsZU9wdGlvbnNfdW5pbnRlcnByZXRlZF9vcHRpb24pIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpFbnVtRGVmPiBPcHRpbWl6ZU1vZGUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpFbnVtRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9GaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUpIH0KK30gIC8vIG5hbWVzcGFjZSBGaWxlT3B0aW9ucworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBNZXNzYWdlT3B0aW9ucyB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01lc3NhZ2VPcHRpb25zKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01lc3NhZ2VPcHRpb25zX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWVzc2FnZU9wdGlvbnNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcikgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiB1bmludGVycHJldGVkX29wdGlvbigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXNzYWdlT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbikgfQorfSAgLy8gbmFtZXNwYWNlIE1lc3NhZ2VPcHRpb25zCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIE1ldGhvZERlc2NyaXB0b3JQcm90byB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZERlc2NyaXB0b3JQcm90bykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBpbnB1dF90eXBlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZERlc2NyaXB0b3JQcm90b19pbnB1dF90eXBlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5hbWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWV0aG9kRGVzY3JpcHRvclByb3RvX25hbWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gb3B0aW9ucygpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2REZXNjcmlwdG9yUHJvdG9fb3B0aW9ucykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBvdXRwdXRfdHlwZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9NZXRob2REZXNjcmlwdG9yUHJvdG9fb3V0cHV0X3R5cGUpIH0KK30gIC8vIG5hbWVzcGFjZSBNZXRob2REZXNjcmlwdG9yUHJvdG8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgTWV0aG9kT3B0aW9ucyB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX01ldGhvZE9wdGlvbnMpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfTWV0aG9kT3B0aW9uc191bmludGVycHJldGVkX29wdGlvbikgfQorfSAgLy8gbmFtZXNwYWNlIE1ldGhvZE9wdGlvbnMKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgU2VydmljZURlc2NyaXB0b3JQcm90byB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VEZXNjcmlwdG9yUHJvdG8pIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gbWV0aG9kKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VEZXNjcmlwdG9yUHJvdG9fbWV0aG9kKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5hbWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU2VydmljZURlc2NyaXB0b3JQcm90b19uYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG9wdGlvbnMoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU2VydmljZURlc2NyaXB0b3JQcm90b19vcHRpb25zKSB9Cit9ICAvLyBuYW1lc3BhY2UgU2VydmljZURlc2NyaXB0b3JQcm90bworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBTZXJ2aWNlT3B0aW9ucyB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VPcHRpb25zKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NlcnZpY2VPcHRpb25zX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKSB9Cit9ICAvLyBuYW1lc3BhY2UgU2VydmljZU9wdGlvbnMKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgU291cmNlQ29kZUluZm8geworaW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6Ok1lc3NhZ2VEZWY+IE1lc3NhZ2VEZWYoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpNZXNzYWdlRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mbykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBsb2NhdGlvbigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19sb2NhdGlvbikgfQorfSAgLy8gbmFtZXNwYWNlIFNvdXJjZUNvZGVJbmZvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIFNvdXJjZUNvZGVJbmZvIHsKK25hbWVzcGFjZSBMb2NhdGlvbiB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGxlYWRpbmdfY29tbWVudHMoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfU291cmNlQ29kZUluZm9fTG9jYXRpb25fbGVhZGluZ19jb21tZW50cykgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBwYXRoKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX3BhdGgpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gc3BhbigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9zcGFuKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IHRyYWlsaW5nX2NvbW1lbnRzKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX3RyYWlsaW5nX2NvbW1lbnRzKSB9Cit9ICAvLyBuYW1lc3BhY2UgTG9jYXRpb24KK30gIC8vIG5hbWVzcGFjZSBTb3VyY2VDb2RlSW5mbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBVbmludGVycHJldGVkT3B0aW9uIHsKK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpNZXNzYWdlRGVmPiBNZXNzYWdlRGVmKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6TWVzc2FnZURlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbikgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBhZ2dyZWdhdGVfdmFsdWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9hZ2dyZWdhdGVfdmFsdWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gZG91YmxlX3ZhbHVlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fZG91YmxlX3ZhbHVlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IGlkZW50aWZpZXJfdmFsdWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9pZGVudGlmaWVyX3ZhbHVlKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5hbWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9uYW1lKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5lZ2F0aXZlX2ludF92YWx1ZSgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uX25lZ2F0aXZlX2ludF92YWx1ZSkgfQoraW5saW5lIHVwYjo6cmVmZmVkX3B0cjxjb25zdCB1cGI6OkZpZWxkRGVmPiBwb3NpdGl2ZV9pbnRfdmFsdWUoKSB7IFJFVFVSTl9SRUZGRUQodXBiOjpGaWVsZERlZiwgdXBiZGVmc19nb29nbGVfcHJvdG9idWZfVW5pbnRlcnByZXRlZE9wdGlvbl9wb3NpdGl2ZV9pbnRfdmFsdWUpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gc3RyaW5nX3ZhbHVlKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fc3RyaW5nX3ZhbHVlKSB9Cit9ICAvLyBuYW1lc3BhY2UgVW5pbnRlcnByZXRlZE9wdGlvbgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBVbmludGVycHJldGVkT3B0aW9uIHsKK25hbWVzcGFjZSBOYW1lUGFydCB7CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6TWVzc2FnZURlZj4gTWVzc2FnZURlZigpIHsgUkVUVVJOX1JFRkZFRCh1cGI6Ok1lc3NhZ2VEZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQpIH0KK2lubGluZSB1cGI6OnJlZmZlZF9wdHI8Y29uc3QgdXBiOjpGaWVsZERlZj4gaXNfZXh0ZW5zaW9uKCkgeyBSRVRVUk5fUkVGRkVEKHVwYjo6RmllbGREZWYsIHVwYmRlZnNfZ29vZ2xlX3Byb3RvYnVmX1VuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnRfaXNfZXh0ZW5zaW9uKSB9CitpbmxpbmUgdXBiOjpyZWZmZWRfcHRyPGNvbnN0IHVwYjo6RmllbGREZWY+IG5hbWVfcGFydCgpIHsgUkVUVVJOX1JFRkZFRCh1cGI6OkZpZWxkRGVmLCB1cGJkZWZzX2dvb2dsZV9wcm90b2J1Zl9VbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X25hbWVfcGFydCkgfQorfSAgLy8gbmFtZXNwYWNlIE5hbWVQYXJ0Cit9ICAvLyBuYW1lc3BhY2UgVW5pbnRlcnByZXRlZE9wdGlvbgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKK30gIC8vIG5hbWVzcGFjZSB1cGJkZWZzCisKKworI3VuZGVmIFJFVFVSTl9SRUZGRUQKKyNlbmRpZiAvLyBfX2NwbHVzcGx1cworCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SX1VQQl9IXworLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEyIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBBIHVwYl9oYW5kbGVycyBpcyBsaWtlIGEgdmlydHVhbCB0YWJsZSBmb3IgYSB1cGJfbXNnZGVmLiAgRWFjaCBmaWVsZCBvZiB0aGUKKyAqIG1lc3NhZ2UgY2FuIGhhdmUgYXNzb2NpYXRlZCBmdW5jdGlvbnMgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHdlIGFyZQorICogcGFyc2luZyBvciB2aXNpdGluZyBhIHN0cmVhbSBvZiBkYXRhLiAgVGhpcyBpcyBzaW1pbGFyIHRvIGhvdyBoYW5kbGVycyB3b3JrCisgKiBpbiBTQVggKHRoZSBTaW1wbGUgQVBJIGZvciBYTUwpLgorICoKKyAqIFRoZSBoYW5kbGVycyBoYXZlIG5vIGlkZWEgd2hlcmUgdGhlIGRhdGEgaXMgY29taW5nIGZyb20sIHNvIGEgc2luZ2xlIHNldCBvZgorICogaGFuZGxlcnMgY291bGQgYmUgdXNlZCB3aXRoIHR3byBjb21wbGV0ZWx5IGRpZmZlcmVudCBkYXRhIHNvdXJjZXMgKGZvcgorICogZXhhbXBsZSwgYSBwYXJzZXIgYW5kIGEgdmlzaXRvciBvdmVyIGluLW1lbW9yeSBvYmplY3RzKS4gIFRoaXMgZGVjb3VwbGluZyBpcworICogdGhlIG1vc3QgaW1wb3J0YW50IGZlYXR1cmUgb2YgdXBiLCBiZWNhdXNlIGl0IGFsbG93cyBwYXJzZXJzIGFuZCBzZXJpYWxpemVycworICogdG8gYmUgaGlnaGx5IHJldXNhYmxlLgorICoKKyAqIFRoaXMgaXMgYSBtaXhlZCBDL0MrKyBpbnRlcmZhY2UgdGhhdCBvZmZlcnMgYSBmdWxsIEFQSSB0byBib3RoIGxhbmd1YWdlcy4KKyAqIFNlZSB0aGUgdG9wLWxldmVsIFJFQURNRSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAqLworCisjaWZuZGVmIFVQQl9IQU5ETEVSU19ICisjZGVmaW5lIFVQQl9IQU5ETEVSU19ICisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK2NsYXNzIEJ1ZmZlckhhbmRsZTsKK2NsYXNzIEJ5dGVzSGFuZGxlcjsKK2NsYXNzIEhhbmRsZXJBdHRyaWJ1dGVzOworY2xhc3MgSGFuZGxlcnM7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gY2xhc3MgSGFuZGxlcjsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgQ2Fub25pY2FsVHlwZTsKK30gIC8vIG5hbWVzcGFjZSB1cGIKKyNlbmRpZgorCitVUEJfREVDTEFSRV9UWVBFKHVwYjo6QnVmZmVySGFuZGxlLCB1cGJfYnVmaGFuZGxlKTsKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpCeXRlc0hhbmRsZXIsIHVwYl9ieXRlc2hhbmRsZXIpOworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OkhhbmRsZXJBdHRyaWJ1dGVzLCB1cGJfaGFuZGxlcmF0dHIpOworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OkhhbmRsZXJzLCB1cGJfaGFuZGxlcnMpOworCisvLyBUaGUgbWF4aW11bSBkZXB0aCB0aGF0IHRoZSBoYW5kbGVyIGdyYXBoIGNhbiBoYXZlLiAgVGhpcyBpcyBhIHJlc291cmNlIGxpbWl0CisvLyBmb3IgdGhlIEMgc3RhY2sgc2luY2Ugd2Ugc29tZXRpbWVzIG5lZWQgdG8gcmVjdXJzaXZlbHkgdHJhdmVyc2UgdGhlIGdyYXBoLgorLy8gQ3ljbGVzIGFyZSBvazsgdGhlIHRyYXZlcnNhbCB3aWxsIHN0b3Agd2hlbiBpdCBkZXRlY3RzIGEgY3ljbGUsIGJ1dCB3ZSBtdXN0CisvLyBoaXQgdGhlIGN5Y2xlIGJlZm9yZSB0aGUgbWF4aW11bSBkZXB0aCBpcyByZWFjaGVkLgorLy8KKy8vIElmIGhhdmluZyBhIHNpbmdsZSBzdGF0aWMgbGltaXQgaXMgdG9vIGluZmxleGlibGUsIHdlIGNhbiBhZGQgYW5vdGhlciB2YXJpYW50CisvLyBvZiBIYW5kbGVyczo6RnJlZXplIHRoYXQgYWxsb3dzIHNwZWNpZnlpbmcgdGhpcyBhcyBhIHBhcmFtZXRlci4KKyNkZWZpbmUgVVBCX01BWF9IQU5ETEVSX0RFUFRIIDY0CisKKy8vIEFsbCB0aGUgZGlmZmVyZW50IHR5cGVzIG9mIGhhbmRsZXJzIHRoYXQgY2FuIGJlIHJlZ2lzdGVyZWQuCisvLyBPbmx5IG5lZWRlZCBmb3IgdGhlIGFkdmFuY2VkIGZ1bmN0aW9ucyBpbiB1cGI6OkhhbmRsZXJzLgordHlwZWRlZiBlbnVtIHsKKyAgVVBCX0hBTkRMRVJfSU5UMzIsCisgIFVQQl9IQU5ETEVSX0lOVDY0LAorICBVUEJfSEFORExFUl9VSU5UMzIsCisgIFVQQl9IQU5ETEVSX1VJTlQ2NCwKKyAgVVBCX0hBTkRMRVJfRkxPQVQsCisgIFVQQl9IQU5ETEVSX0RPVUJMRSwKKyAgVVBCX0hBTkRMRVJfQk9PTCwKKyAgVVBCX0hBTkRMRVJfU1RBUlRTVFIsCisgIFVQQl9IQU5ETEVSX1NUUklORywKKyAgVVBCX0hBTkRMRVJfRU5EU1RSLAorICBVUEJfSEFORExFUl9TVEFSVFNVQk1TRywKKyAgVVBCX0hBTkRMRVJfRU5EU1VCTVNHLAorICBVUEJfSEFORExFUl9TVEFSVFNFUSwKKyAgVVBCX0hBTkRMRVJfRU5EU0VRLAorfSB1cGJfaGFuZGxlcnR5cGVfdDsKKworI2RlZmluZSBVUEJfSEFORExFUl9NQVggKFVQQl9IQU5ETEVSX0VORFNFUSsxKQorCisjZGVmaW5lIFVQQl9CUkVBSyBOVUxMCisKKy8vIEEgY29udmVuaWVudCBkZWZpbml0aW9uIGZvciB3aGVuIG5vIGNsb3N1cmUgaXMgbmVlZGVkLgorZXh0ZXJuIGNoYXIgX3VwYl9ub2Nsb3N1cmU7CisjZGVmaW5lIFVQQl9OT19DTE9TVVJFICZfdXBiX25vY2xvc3VyZQorCisvLyBBIHNlbGVjdG9yIHJlZmVycyB0byBhIHNwZWNpZmljIGZpZWxkIGhhbmRsZXIgaW4gdGhlIEhhbmRsZXJzIG9iamVjdAorLy8gKGZvciBleGFtcGxlOiB0aGUgU1RBUlRTVUJNU0cgaGFuZGxlciBmb3IgZmllbGQgImZpZWxkMTUiKS4KK3R5cGVkZWYgaW50MzJfdCB1cGJfc2VsZWN0b3JfdDsKKworVVBCX0JFR0lOX0VYVEVSTl9DCisKKy8vIEZvcndhcmQtZGVjbGFyZXMgZm9yIEMgaW5saW5lIGFjY2Vzc29ycy4gIFdlIG5lZWQgdG8gZGVjbGFyZSB0aGVzZSBoZXJlCisvLyBzbyB3ZSBjYW4gImZyaWVuZCIgdGhlbSBpbiB0aGUgY2xhc3MgZGVjbGFyYXRpb25zIGluIEMrKy4KK1VQQl9JTkxJTkUgdXBiX2Z1bmMgKnVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zZWxlY3Rvcl90IHMpOworVVBCX0lOTElORSBjb25zdCB2b2lkICp1cGJfaGFuZGxlcmF0dHJfaGFuZGxlcmRhdGEoY29uc3QgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK1VQQl9JTkxJTkUgY29uc3Qgdm9pZCAqdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zZWxlY3Rvcl90IHMpOworCitVUEJfSU5MSU5FIHZvaWQgdXBiX2J1ZmhhbmRsZV9pbml0KHVwYl9idWZoYW5kbGUgKmgpOworVVBCX0lOTElORSB2b2lkIHVwYl9idWZoYW5kbGVfc2V0b2JqKHVwYl9idWZoYW5kbGUgKmgsIGNvbnN0IHZvaWQgKm9iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICp0eXBlKTsKK1VQQl9JTkxJTkUgdm9pZCB1cGJfYnVmaGFuZGxlX3NldGJ1Zih1cGJfYnVmaGFuZGxlICpoLCBjb25zdCBjaGFyICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG9mcyk7CitVUEJfSU5MSU5FIGNvbnN0IHZvaWQgKnVwYl9idWZoYW5kbGVfb2JqKGNvbnN0IHVwYl9idWZoYW5kbGUgKmgpOworVVBCX0lOTElORSBjb25zdCB2b2lkICp1cGJfYnVmaGFuZGxlX29ianR5cGUoY29uc3QgdXBiX2J1ZmhhbmRsZSAqaCk7CitVUEJfSU5MSU5FIGNvbnN0IGNoYXIgKnVwYl9idWZoYW5kbGVfYnVmKGNvbnN0IHVwYl9idWZoYW5kbGUgKmgpOworCitVUEJfRU5EX0VYVEVSTl9DCisKKworLy8gU3RhdGljIHNlbGVjdG9ycyBmb3IgdXBiOjpIYW5kbGVycy4KKyNkZWZpbmUgVVBCX1NUQVJUTVNHX1NFTEVDVE9SIDAKKyNkZWZpbmUgVVBCX0VORE1TR19TRUxFQ1RPUiAxCisjZGVmaW5lIFVQQl9TVEFUSUNfU0VMRUNUT1JfQ09VTlQgMgorCisvLyBTdGF0aWMgc2VsZWN0b3JzIGZvciB1cGI6OkJ5dGVzSGFuZGxlci4KKyNkZWZpbmUgVVBCX1NUQVJUU1RSX1NFTEVDVE9SIDAKKyNkZWZpbmUgVVBCX1NUUklOR19TRUxFQ1RPUiAxCisjZGVmaW5lIFVQQl9FTkRTVFJfU0VMRUNUT1IgMgorCit0eXBlZGVmIHZvaWQgdXBiX2hhbmRsZXJmcmVlKHZvaWQgKmQpOworCisvLyBBIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgYWNjb21wYW5pZXMgYSBoYW5kbGVyJ3MgZnVuY3Rpb24gcG9pbnRlci4KK1VQQl9ERUZJTkVfQ0xBU1MwKHVwYjo6SGFuZGxlckF0dHJpYnV0ZXMsCisgcHVibGljOgorICBIYW5kbGVyQXR0cmlidXRlcygpOworICB+SGFuZGxlckF0dHJpYnV0ZXMoKTsKKworICAvLyBTZXRzIHRoZSBoYW5kbGVyIGRhdGEgdGhhdCB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgc2Vjb25kIHBhcmFtZXRlciBvZiB0aGUKKyAgLy8gaGFuZGxlci4gIFRvIGZyZWUgdGhpcyBwb2ludGVyIHdoZW4gdGhlIGhhbmRsZXJzIGFyZSBmcmVlZCwgY2FsbAorICAvLyBIYW5kbGVyczo6QWRkQ2xlYW51cCgpLgorICBib29sIFNldEhhbmRsZXJEYXRhKGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSk7CisgIGNvbnN0IHZvaWQqIGhhbmRsZXJfZGF0YSgpIGNvbnN0OworCisgIC8vIFVzZSB0aGlzIHRvIHNwZWNpZnkgdGhlIHR5cGUgb2YgdGhlIGNsb3N1cmUuICBUaGlzIHdpbGwgYmUgY2hlY2tlZCBhZ2FpbnN0CisgIC8vIGFsbCBvdGhlciBjbG9zdXJlIHR5cGVzIGZvciBoYW5kbGVyIHRoYXQgdXNlIHRoZSBzYW1lIGNsb3N1cmUuCisgIC8vIFJlZ2lzdHJhdGlvbiB3aWxsIGZhaWwgaWYgdGhpcyBkb2VzIG5vdCBtYXRjaCBhbGwgb3RoZXIgbm9uLU5VTEwgY2xvc3VyZQorICAvLyB0eXBlcy4KKyAgYm9vbCBTZXRDbG9zdXJlVHlwZShjb25zdCB2b2lkICpjbG9zdXJlX3R5cGUpOworICBjb25zdCB2b2lkKiBjbG9zdXJlX3R5cGUoKSBjb25zdDsKKworICAvLyBVc2UgdGhpcyB0byBzcGVjaWZ5IHRoZSB0eXBlIG9mIHRoZSByZXR1cm5lZCBjbG9zdXJlLiAgT25seSB1c2VkIGZvcgorICAvLyBTdGFydCp7U3RyaW5nLFN1Yk1lc3NhZ2UsU2VxdWVuY2V9IGhhbmRsZXJzLiAgVGhpcyBtdXN0IG1hdGNoIHRoZSBjbG9zdXJlCisgIC8vIHR5cGUgb2YgYW55IGhhbmRsZXJzIHRoYXQgdXNlIGl0IChmb3IgZXhhbXBsZSwgdGhlIFN0cmluZ0J1ZiBoYW5kbGVyIG11c3QKKyAgLy8gbWF0Y2ggdGhlIGNsb3N1cmUgcmV0dXJuZWQgZnJvbSBTdGFydFN0cmluZykuCisgIGJvb2wgU2V0UmV0dXJuQ2xvc3VyZVR5cGUoY29uc3Qgdm9pZCAqcmV0dXJuX2Nsb3N1cmVfdHlwZSk7CisgIGNvbnN0IHZvaWQqIHJldHVybl9jbG9zdXJlX3R5cGUoKSBjb25zdDsKKworICAvLyBTZXQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgaGFuZGxlciBhbHdheXMgcmV0dXJucyAib2siIChlaXRoZXIgInRydWUiIG9yIGEKKyAgLy8gbm9uLU5VTEwgY2xvc3VyZSkuICBUaGlzIGlzIGEgaGludCB0aGF0IGNhbiBhbGxvdyBjb2RlIGdlbmVyYXRvcnMgdG8KKyAgLy8gZ2VuZXJhdGUgbW9yZSBlZmZpY2llbnQgY29kZS4KKyAgYm9vbCBTZXRBbHdheXNPayhib29sIGFsd2F5c19vayk7CisgIGJvb2wgYWx3YXlzX29rKCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBmcmllbmQgVVBCX0lOTElORSBjb25zdCB2b2lkICogOjp1cGJfaGFuZGxlcmF0dHJfaGFuZGxlcmRhdGEoCisgICAgICBjb25zdCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9oYW5kbGVyYXR0ciwKKyAgY29uc3Qgdm9pZCAqaGFuZGxlcl9kYXRhXzsKKyAgY29uc3Qgdm9pZCAqY2xvc3VyZV90eXBlXzsKKyAgY29uc3Qgdm9pZCAqcmV0dXJuX2Nsb3N1cmVfdHlwZV87CisgIGJvb2wgYWx3YXlzb2tfOworKSk7CisKKyNkZWZpbmUgVVBCX0hBTkRMRVJBVFRSX0lOSVRJQUxJWkVSIHtOVUxMLCBOVUxMLCBOVUxMLCBmYWxzZX0KKwordHlwZWRlZiBzdHJ1Y3QgeworICB1cGJfZnVuYyAqZnVuYzsKKyAgLy8gSXQgaXMgd2FzdGVmdWwgdG8gaW5jbHVkZSB0aGUgZW50aXJlIGF0dHJpYnV0ZXMgaGVyZToKKyAgLy8KKyAgLy8gKiBTb21lIG9mIHRoZSBpbmZvcm1hdGlvbiBpcyByZWR1bmRhbnQgKGxpa2Ugc3RvcmluZyB0aGUgY2xvc3VyZSB0eXBlCisgIC8vICAgc2VwYXJhdGVseSBmb3IgZWFjaCBoYW5kbGVyIHRoYXQgbXVzdCBtYXRjaCkuCisgIC8vICogU29tZSBvZiB0aGUgaW5mbyBpcyBvbmx5IG5lZWRlZCBwcmlvciB0byBmcmVlemUoKSAobGlrZSBjbG9zdXJlIHR5cGVzKS4KKyAgLy8gKiBhbGlnbm1lbnQgcGFkZGluZyB3YXN0ZXMgYSBsb3Qgb2Ygc3BhY2UgZm9yIGFsd2F5c29rXy4KKyAgLy8KKyAgLy8gSWYvd2hlbiB0aGUgc2l6ZSBhbmQgbG9jYWxpdHkgb2YgaGFuZGxlcnMgaXMgYW4gaXNzdWUsIHdlIGNhbiBvcHRpbWl6ZSB0aGlzCisgIC8vIG5vdCB0byBzdG9yZSB0aGUgZW50aXJlIGF0dHIgbGlrZSB0aGlzLiAgV2UgZG8gbm90IGV4cG9zZSB0aGUgdGFibGUncworICAvLyBsYXlvdXQgdG8gYWxsb3cgdGhpcyBvcHRpbWl6YXRpb24gaW4gdGhlIGZ1dHVyZS4KKyAgdXBiX2hhbmRsZXJhdHRyIGF0dHI7Cit9IHVwYl9oYW5kbGVyc190YWJlbnQ7CisKKy8vIEV4dHJhIGluZm9ybWF0aW9uIGFib3V0IGEgYnVmZmVyIHRoYXQgaXMgcGFzc2VkIHRvIGEgU3RyaW5nQnVmIGhhbmRsZXIuCisvLyBUT0RPKGhhYmVybWFuKTogYWxsb3cgdGhlIGhhbmRsZSB0byBiZSBwaW5uZWQgc28gdGhhdCBpdCB3aWxsIG91dGxpdmUKKy8vIHRoZSBoYW5kbGVyIGludm9jYXRpb24uCitVUEJfREVGSU5FX0NMQVNTMCh1cGI6OkJ1ZmZlckhhbmRsZSwKKyBwdWJsaWM6CisgIEJ1ZmZlckhhbmRsZSgpOworICB+QnVmZmVySGFuZGxlKCk7CisKKyAgLy8gVGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyLiAgVGhpcyBtYXkgYmUgZGlmZmVyZW50IHRoYW4gdGhlIHBvaW50ZXIKKyAgLy8gcGFzc2VkIHRvIGEgU3RyaW5nQnVmIGhhbmRsZXIgYmVjYXVzZSB0aGUgaGFuZGxlciBtYXkgcmVjZWl2ZSBkYXRhCisgIC8vIHRoYXQgaXMgZnJvbSB0aGUgbWlkZGxlIG9yIGVuZCBvZiBhIGxhcmdlciBidWZmZXIuCisgIGNvbnN0IGNoYXIqIGJ1ZmZlcigpIGNvbnN0OworCisgIC8vIFRoZSBvZmZzZXQgd2l0aGluIHRoZSBhdHRhY2hlZCBvYmplY3Qgd2hlcmUgdGhpcyBidWZmZXIgYmVnaW5zLiAgT25seQorICAvLyBtZWFuaW5nZnVsIGlmIHRoZXJlIGlzIGFuIGF0dGFjaGVkIG9iamVjdC4KKyAgc2l6ZV90IG9iamVjdF9vZmZzZXQoKSBjb25zdDsKKworICAvLyBOb3RlIHRoYXQgb2JqZWN0X29mZnNldCBpcyB0aGUgb2Zmc2V0IG9mICJidWYiIHdpdGhpbiB0aGUgYXR0YWNoZWQgb2JqZWN0LgorICB2b2lkIFNldEJ1ZmZlcihjb25zdCBjaGFyKiBidWYsIHNpemVfdCBvYmplY3Rfb2Zmc2V0KTsKKworICAvLyBUaGUgQnVmZmVySGFuZGxlIGNhbiBoYXZlIGFuICJhdHRhY2hlZCBvYmplY3QiLCB3aGljaCBjYW4gYmUgdXNlZCB0bworICAvLyB0dW5uZWwgdGhyb3VnaCBhIHBvaW50ZXIgdG8gdGhlIGJ1ZmZlcidzIHVuZGVybHlpbmcgcmVwcmVzZW50YXRpb24uCisgIHRlbXBsYXRlIDxjbGFzcyBUPgorICB2b2lkIFNldEF0dGFjaGVkT2JqZWN0KGNvbnN0IFQqIG9iaik7CisKKyAgLy8gUmV0dXJucyBOVUxMIGlmIHRoZSBhdHRhY2hlZCBvYmplY3QgaXMgbm90IG9mIHRoaXMgdHlwZS4KKyAgdGVtcGxhdGUgPGNsYXNzIFQ+CisgIGNvbnN0IFQqIEdldEF0dGFjaGVkT2JqZWN0KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBmcmllbmQgVVBCX0lOTElORSB2b2lkIDo6dXBiX2J1ZmhhbmRsZV9pbml0KHVwYl9idWZoYW5kbGUgKmgpOworICBmcmllbmQgVVBCX0lOTElORSB2b2lkIDo6dXBiX2J1ZmhhbmRsZV9zZXRvYmoodXBiX2J1ZmhhbmRsZSAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKm9iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnR5cGUpOworICBmcmllbmQgVVBCX0lOTElORSB2b2lkIDo6dXBiX2J1ZmhhbmRsZV9zZXRidWYodXBiX2J1ZmhhbmRsZSAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IG9mcyk7CisgIGZyaWVuZCBVUEJfSU5MSU5FIGNvbnN0IHZvaWQqIDo6dXBiX2J1ZmhhbmRsZV9vYmooY29uc3QgdXBiX2J1ZmhhbmRsZSAqaCk7CisgIGZyaWVuZCBVUEJfSU5MSU5FIGNvbnN0IHZvaWQqIDo6dXBiX2J1ZmhhbmRsZV9vYmp0eXBlKAorICAgICAgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaCk7CisgIGZyaWVuZCBVUEJfSU5MSU5FIGNvbnN0IGNoYXIqIDo6dXBiX2J1ZmhhbmRsZV9idWYoY29uc3QgdXBiX2J1ZmhhbmRsZSAqaCk7CissCitVUEJfREVGSU5FX1NUUlVDVDAodXBiX2J1ZmhhbmRsZSwKKyAgY29uc3QgY2hhciAqYnVmXzsKKyAgY29uc3Qgdm9pZCAqb2JqXzsKKyAgY29uc3Qgdm9pZCAqb2JqdHlwZV87CisgIHNpemVfdCBvYmpvZnNfOworKSk7CisKKy8vIEEgdXBiOjpIYW5kbGVycyBvYmplY3QgcmVwcmVzZW50cyB0aGUgc2V0IG9mIGhhbmRsZXJzIGFzc29jaWF0ZWQgd2l0aCBhCisvLyBtZXNzYWdlIGluIHRoZSBncmFwaCBvZiBtZXNzYWdlcy4gIFlvdSBjYW4gdGhpbmsgb2YgaXQgYXMgYSBiaWcgdmlydHVhbAorLy8gdGFibGUgd2l0aCBmdW5jdGlvbnMgY29ycmVzcG9uZGluZyB0byBhbGwgdGhlIGV2ZW50cyB0aGF0IGNhbiBmaXJlIHdoaWxlCisvLyBwYXJzaW5nIG9yIHZpc2l0aW5nIGEgbWVzc2FnZSBvZiBhIHNwZWNpZmljIHR5cGUuCisvLworLy8gQW55IGhhbmRsZXJzIHRoYXQgYXJlIG5vdCBzZXQgYmVoYXZlIGFzIGlmIHRoZXkgaGFkIHN1Y2Nlc3NmdWxseSBjb25zdW1lZAorLy8gdGhlIHZhbHVlLiAgQW55IHVuc2V0IFN0YXJ0KiBoYW5kbGVycyB3aWxsIHByb3BhZ2F0ZSB0aGVpciBjbG9zdXJlIHRvIHRoZQorLy8gaW5uZXIgZnJhbWUuCisvLworLy8gVGhlIGVhc2llc3Qgd2F5IHRvIGNyZWF0ZSB0aGUgKkhhbmRsZXIgb2JqZWN0cyBuZWVkZWQgYnkgdGhlIFNldCogbWV0aG9kcyBpcworLy8gd2l0aCB0aGUgVXBiQmluZCgpIGFuZCBVcGJNYWtlSGFuZGxlcigpIG1hY3Jvczsgc2VlIGJlbG93LgorVVBCX0RFRklORV9DTEFTUzEodXBiOjpIYW5kbGVycywgdXBiOjpSZWZDb3VudGVkLAorIHB1YmxpYzoKKyAgdHlwZWRlZiB1cGJfc2VsZWN0b3JfdCBTZWxlY3RvcjsKKyAgdHlwZWRlZiB1cGJfaGFuZGxlcnR5cGVfdCBUeXBlOworCisgIHR5cGVkZWYgSGFuZGxlcjx2b2lkICooKikodm9pZCAqLCBjb25zdCB2b2lkICopPiBTdGFydEZpZWxkSGFuZGxlcjsKKyAgdHlwZWRlZiBIYW5kbGVyPGJvb2wgKCopKHZvaWQgKiwgY29uc3Qgdm9pZCAqKT4gRW5kRmllbGRIYW5kbGVyOworICB0eXBlZGVmIEhhbmRsZXI8Ym9vbCAoKikodm9pZCAqLCBjb25zdCB2b2lkICopPiBTdGFydE1lc3NhZ2VIYW5kbGVyOworICB0eXBlZGVmIEhhbmRsZXI8Ym9vbCAoKikodm9pZCAqLCBjb25zdCB2b2lkICosIFN0YXR1cyopPiBFbmRNZXNzYWdlSGFuZGxlcjsKKyAgdHlwZWRlZiBIYW5kbGVyPHZvaWQgKigqKSh2b2lkICosIGNvbnN0IHZvaWQgKiwgc2l6ZV90KT4gU3RhcnRTdHJpbmdIYW5kbGVyOworICB0eXBlZGVmIEhhbmRsZXI8c2l6ZV90ICgqKSh2b2lkICosIGNvbnN0IHZvaWQgKiwgY29uc3QgY2hhciAqLCBzaXplX3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEJ1ZmZlckhhbmRsZSAqKT4gU3RyaW5nSGFuZGxlcjsKKworICB0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IFZhbHVlSGFuZGxlciB7CisgICAgdHlwZWRlZiBIYW5kbGVyPGJvb2woKikodm9pZCAqLCBjb25zdCB2b2lkICosIFQpPiBIOworICB9OworCisgIHR5cGVkZWYgVmFsdWVIYW5kbGVyPGludDMyX3Q+OjpIICAgICBJbnQzMkhhbmRsZXI7CisgIHR5cGVkZWYgVmFsdWVIYW5kbGVyPGludDY0X3Q+OjpIICAgICBJbnQ2NEhhbmRsZXI7CisgIHR5cGVkZWYgVmFsdWVIYW5kbGVyPHVpbnQzMl90Pjo6SCAgICBVSW50MzJIYW5kbGVyOworICB0eXBlZGVmIFZhbHVlSGFuZGxlcjx1aW50NjRfdD46OkggICAgVUludDY0SGFuZGxlcjsKKyAgdHlwZWRlZiBWYWx1ZUhhbmRsZXI8ZmxvYXQ+OjpIICAgICAgIEZsb2F0SGFuZGxlcjsKKyAgdHlwZWRlZiBWYWx1ZUhhbmRsZXI8ZG91YmxlPjo6SCAgICAgIERvdWJsZUhhbmRsZXI7CisgIHR5cGVkZWYgVmFsdWVIYW5kbGVyPGJvb2w+OjpIICAgICAgICBCb29sSGFuZGxlcjsKKworICAvLyBBbnkgZnVuY3Rpb24gcG9pbnRlciBjYW4gYmUgY29udmVydGVkIHRvIHRoaXMgYW5kIGNvbnZlcnRlZCBiYWNrIHRvIGl0cworICAvLyBjb3JyZWN0IHR5cGUuCisgIHR5cGVkZWYgdm9pZCBHZW5lcmljRnVuY3Rpb24oKTsKKworICB0eXBlZGVmIHZvaWQgSGFuZGxlcnNDYWxsYmFjayhjb25zdCB2b2lkICpjbG9zdXJlLCB1cGJfaGFuZGxlcnMgKmgpOworCisgIC8vIFJldHVybnMgYSBuZXcgaGFuZGxlcnMgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gZnJvemVuIG1zZ2RlZi4KKyAgLy8gUmV0dXJucyBOVUxMIGlmIG1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZC4KKyAgc3RhdGljIHJlZmZlZF9wdHI8SGFuZGxlcnM+IE5ldyhjb25zdCBNZXNzYWdlRGVmICptKTsKKworICAvLyBDb252ZW5pZW5jZSBmdW5jdGlvbiBmb3IgcmVnaXN0ZXJpbmcgYSBncmFwaCBvZiBoYW5kbGVycyB0aGF0IG1pcnJvcnMgdGhlCisgIC8vIGdyYXBoIG9mIG1zZ2RlZnMgZm9yIHNvbWUgbWVzc2FnZS4gIEZvciAibSIgYW5kIGFsbCBpdHMgY2hpbGRyZW4gYSBuZXcgc2V0CisgIC8vIG9mIGhhbmRsZXJzIHdpbGwgYmUgY3JlYXRlZCBhbmQgdGhlIGdpdmVuIGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZCwKKyAgLy8gYWxsb3dpbmcgdGhlIGNsaWVudCB0byByZWdpc3RlciBoYW5kbGVycyBmb3IgdGhpcyBtZXNzYWdlLiAgTm90ZSB0aGF0IGFueQorICAvLyBzdWJoYW5kbGVycyBzZXQgYnkgdGhlIGNhbGxiYWNrIHdpbGwgYmUgb3ZlcndyaXR0ZW4uCisgIHN0YXRpYyByZWZmZWRfcHRyPGNvbnN0IEhhbmRsZXJzPiBOZXdGcm96ZW4oY29uc3QgTWVzc2FnZURlZiAqbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIYW5kbGVyc0NhbGxiYWNrICpjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpjbG9zdXJlKTsKKworICAvLyBGdW5jdGlvbmFsaXR5IGZyb20gdXBiOjpSZWZDb3VudGVkLgorICBib29sIElzRnJvemVuKCkgY29uc3Q7CisgIHZvaWQgUmVmKGNvbnN0IHZvaWQqIG93bmVyKSBjb25zdDsKKyAgdm9pZCBVbnJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisgIHZvaWQgRG9uYXRlUmVmKGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKSBjb25zdDsKKyAgdm9pZCBDaGVja1JlZihjb25zdCB2b2lkICpvd25lcikgY29uc3Q7CisKKyAgLy8gQWxsIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGZ1bmN0aW9ucyByZXR1cm4gYm9vbCB0byBpbmRpY2F0ZSBzdWNjZXNzIG9yCisgIC8vIGZhaWx1cmU7IGRldGFpbHMgYWJvdXQgZmFpbHVyZXMgYXJlIHN0b3JlZCBpbiB0aGlzIHN0YXR1cyBvYmplY3QuICBJZiBhCisgIC8vIGZhaWx1cmUgZG9lcyBvY2N1ciwgaXQgbXVzdCBiZSBjbGVhcmVkIGJlZm9yZSB0aGUgSGFuZGxlcnMgYXJlIGZyb3plbiwKKyAgLy8gb3RoZXJ3aXNlIHRoZSBmcmVlemUoKSBvcGVyYXRpb24gd2lsbCBmYWlsLiAgVGhlIGZ1bmN0aW9ucyBtYXkgKm9ubHkqIGJlCisgIC8vIHVzZWQgd2hpbGUgdGhlIEhhbmRsZXJzIGFyZSBtdXRhYmxlLgorICBjb25zdCBTdGF0dXMqIHN0YXR1cygpOworICB2b2lkIENsZWFyRXJyb3IoKTsKKworICAvLyBDYWxsIHRvIGZyZWV6ZSB0aGVzZSBIYW5kbGVycy4gIFJlcXVpcmVzIHRoYXQgYW55IFN1YkhhbmRsZXJzIGFyZSBhbHJlYWR5CisgIC8vIGZyb3plbi4gIEZvciBjeWNsZXMsIHlvdSBtdXN0IHVzZSB0aGUgc3RhdGljIHZlcnNpb24gYmVsb3cgYW5kIGZyZWV6ZSB0aGUKKyAgLy8gd2hvbGUgZ3JhcGggYXQgb25jZS4KKyAgYm9vbCBGcmVlemUoU3RhdHVzKiBzKTsKKworICAvLyBGcmVlemVzIHRoZSBnaXZlbiBzZXQgb2YgaGFuZGxlcnMuICBZb3UgbWF5IG5vdCBmcmVlemUgYSBoYW5kbGVyIHdpdGhvdXQKKyAgLy8gYWxzbyBmcmVlemluZyBhbnkgaGFuZGxlcnMgdGhleSBwb2ludCB0by4KKyAgc3RhdGljIGJvb2wgRnJlZXplKEhhbmRsZXJzKmNvbnN0KiBoYW5kbGVycywgaW50IG4sIFN0YXR1cyogcyk7CisgIHN0YXRpYyBib29sIEZyZWV6ZShjb25zdCBzdGQ6OnZlY3RvcjxIYW5kbGVycyo+JiBoYW5kbGVycywgU3RhdHVzKiBzKTsKKworICAvLyBSZXR1cm5zIHRoZSBtc2dkZWYgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGFuZGxlcnMgb2JqZWN0LgorICBjb25zdCBNZXNzYWdlRGVmKiBtZXNzYWdlX2RlZigpIGNvbnN0OworCisgIC8vIEFkZHMgdGhlIGdpdmVuIHBvaW50ZXIgYW5kIGZ1bmN0aW9uIHRvIHRoZSBsaXN0IG9mIGNsZWFudXAgZnVuY3Rpb25zIHRoYXQKKyAgLy8gd2lsbCBiZSBydW4gd2hlbiB0aGVzZSBoYW5kbGVycyBhcmUgZnJlZWQuICBJZiB0aGlzIHBvaW50ZXIgaGFzIHByZXZpb3VzbHkKKyAgLy8gYmVlbiByZWdpc3RlcmVkLCB0aGUgZnVuY3Rpb24gcmV0dXJucyBmYWxzZSBhbmQgZG9lcyBub3RoaW5nLgorICBib29sIEFkZENsZWFudXAodm9pZCAqcHRyLCB1cGJfaGFuZGxlcmZyZWUgKmNsZWFudXApOworCisgIC8vIFNldHMgdGhlIHN0YXJ0bXNnIGhhbmRsZXIgZm9yIHRoZSBtZXNzYWdlLCB3aGljaCBpcyBkZWZpbmVkIGFzIGZvbGxvd3M6CisgIC8vCisgIC8vICAgYm9vbCBzdGFydG1zZyhNeVR5cGUqIGNsb3N1cmUpIHsKKyAgLy8gICAgIC8vIENhbGxlZCB3aGVuIHRoZSBtZXNzYWdlIGJlZ2lucy4gIFJldHVybnMgdHJ1ZSBpZiBwcm9jZXNzaW5nIHNob3VsZAorICAvLyAgICAgLy8gY29udGludWUuCisgIC8vICAgICByZXR1cm4gdHJ1ZTsKKyAgLy8gICB9CisgIGJvb2wgU2V0U3RhcnRNZXNzYWdlSGFuZGxlcihjb25zdCBTdGFydE1lc3NhZ2VIYW5kbGVyJiBoYW5kbGVyKTsKKworICAvLyBTZXRzIHRoZSBlbmRtc2cgaGFuZGxlciBmb3IgdGhlIG1lc3NhZ2UsIHdoaWNoIGlzIGRlZmluZWQgYXMgZm9sbG93czoKKyAgLy8KKyAgLy8gICBib29sIGVuZG1zZyhNeVR5cGUqIGNsb3N1cmUsIHVwYl9zdGF0dXMgKnN0YXR1cykgeworICAvLyAgICAgLy8gQ2FsbGVkIHdoZW4gcHJvY2Vzc2luZyBvZiB0aGlzIG1lc3NhZ2UgZW5kcywgd2hldGhlciBpbiBzdWNjZXNzIG9yCisgIC8vICAgICAvLyBmYWlsdXJlLiAgInN0YXR1cyIgaW5kaWNhdGVzIHRoZSBmaW5hbCBzdGF0dXMgb2YgcHJvY2Vzc2luZywgYW5kCisgIC8vICAgICAvLyBjYW4gYWxzbyBiZSBtb2RpZmllZCBpbi1wbGFjZSB0byB1cGRhdGUgdGhlIGZpbmFsIHN0YXR1cy4KKyAgLy8gICB9CisgIGJvb2wgU2V0RW5kTWVzc2FnZUhhbmRsZXIoY29uc3QgRW5kTWVzc2FnZUhhbmRsZXImIGhhbmRsZXIpOworCisgIC8vIFNldHMgdGhlIHZhbHVlIGhhbmRsZXIgZm9yIHRoZSBnaXZlbiBmaWVsZCwgd2hpY2ggaXMgZGVmaW5lZCBhcyBmb2xsb3dzCisgIC8vICh0aGlzIGlzIGZvciBhbiBpbnQzMiBmaWVsZDsgb3RoZXIgZmllbGQgdHlwZXMgd2lsbCBwYXNzIHRoZWlyIG5hdGl2ZQorICAvLyBDL0MrKyB0eXBlIGZvciAidmFsIik6CisgIC8vCisgIC8vICAgYm9vbCBPblZhbHVlKE15Q2xvc3VyZSogYywgY29uc3QgTXlIYW5kbGVyRGF0YSogZCwgaW50MzJfdCB2YWwpIHsKKyAgLy8gICAgIC8vIENhbGxlZCB3aGVuIHRoZSBmaWVsZCdzIHZhbHVlIGlzIGVuY291bnRlcmVkLiAgImQiIGNvbnRhaW5zCisgIC8vICAgICAvLyB3aGF0ZXZlciBkYXRhIHdhcyBib3VuZCB0byB0aGlzIGZpZWxkIHdoZW4gaXQgd2FzIHJlZ2lzdGVyZWQuCisgIC8vICAgICAvLyBSZXR1cm5zIHRydWUgaWYgcHJvY2Vzc2luZyBzaG91bGQgY29udGludWUuCisgIC8vICAgICByZXR1cm4gdHJ1ZTsKKyAgLy8gICB9CisgIC8vCisgIC8vICAgaGFuZGVycy0+U2V0SW50MzJIYW5kbGVyKGYsIFVwYkJpbmQoT25WYWx1ZSwgbmV3IE15SGFuZGxlckRhdGEoLi4uKSkpOworICAvLworICAvLyBUaGUgdmFsdWUgdHlwZSBtdXN0IGV4YWN0bHkgbWF0Y2ggZi0+dHlwZSgpLgorICAvLyBGb3IgZXhhbXBsZSwgYSBoYW5kbGVyIHRoYXQgdGFrZXMgYW4gaW50MzJfdCBwYXJhbWV0ZXIgbWF5IG9ubHkgYmUgdXNlZCBmb3IKKyAgLy8gZmllbGRzIG9mIHR5cGUgVVBCX1RZUEVfSU5UMzIgYW5kIFVQQl9UWVBFX0VOVU0uCisgIC8vCisgIC8vIFJldHVybnMgZmFsc2UgaWYgdGhlIGhhbmRsZXIgZmFpbGVkIHRvIHJlZ2lzdGVyOyBpbiB0aGlzIGNhc2UgdGhlIGNsZWFudXAKKyAgLy8gaGFuZGxlciAoaWYgYW55KSB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseS4KKyAgYm9vbCBTZXRJbnQzMkhhbmRsZXIgKGNvbnN0IEZpZWxkRGVmKiBmLCAgY29uc3QgSW50MzJIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRJbnQ2NEhhbmRsZXIgKGNvbnN0IEZpZWxkRGVmKiBmLCAgY29uc3QgSW50NjRIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRVSW50MzJIYW5kbGVyKGNvbnN0IEZpZWxkRGVmKiBmLCBjb25zdCBVSW50MzJIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRVSW50NjRIYW5kbGVyKGNvbnN0IEZpZWxkRGVmKiBmLCBjb25zdCBVSW50NjRIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRGbG9hdEhhbmRsZXIgKGNvbnN0IEZpZWxkRGVmKiBmLCAgY29uc3QgRmxvYXRIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXREb3VibGVIYW5kbGVyKGNvbnN0IEZpZWxkRGVmKiBmLCBjb25zdCBEb3VibGVIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRCb29sSGFuZGxlciAgKGNvbnN0IEZpZWxkRGVmKiBmLCAgIGNvbnN0IEJvb2xIYW5kbGVyJiBoKTsKKworICAvLyBMaWtlIHRoZSBwcmV2aW91cywgYnV0IHRlbXBsYXRlZCBvbiB0aGUgdHlwZSBvbiB0aGUgdmFsdWUgKGllLiBpbnQzMikuCisgIC8vIFRoaXMgaXMgbW9zdGx5IHVzZWZ1bCB0byBjYWxsIGZyb20gb3RoZXIgdGVtcGxhdGVzLiAgVG8gY2FsbCB0aGlzIHlvdSBtdXN0CisgIC8vIHNwZWNpZnkgdGhlIHRlbXBsYXRlIHBhcmFtZXRlciBleHBsaWNpdGx5LCBpZToKKyAgLy8gICBoLT5TZXRWYWx1ZUhhbmRsZXI8VD4oZiwgVXBiQmluZChNeUhhbmRsZXI8VD4sIE15RGF0YSkpOworICB0ZW1wbGF0ZSA8Y2xhc3MgVD4KKyAgYm9vbCBTZXRWYWx1ZUhhbmRsZXIoCisgICAgICBjb25zdCBGaWVsZERlZiAqZiwKKyAgICAgIGNvbnN0IHR5cGVuYW1lIFZhbHVlSGFuZGxlcjx0eXBlbmFtZSBDYW5vbmljYWxUeXBlPFQ+OjpUeXBlPjo6SCYgaGFuZGxlcik7CisKKyAgLy8gU2V0cyBoYW5kbGVycyBmb3IgYSBzdHJpbmcgZmllbGQsIHdoaWNoIGFyZSBkZWZpbmVkIGFzIGZvbGxvd3M6CisgIC8vCisgIC8vICAgTXlTdWJDbG9zdXJlKiBzdGFydHN0cihNeUNsb3N1cmUqIGMsIGNvbnN0IE15SGFuZGxlckRhdGEqIGQsCisgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZV9oaW50KSB7CisgIC8vICAgICAvLyBDYWxsZWQgd2hlbiBhIHN0cmluZyB2YWx1ZSBiZWdpbnMuICBUaGUgcmV0dXJuIHZhbHVlIGluZGljYXRlcyB0aGUKKyAgLy8gICAgIC8vIGNsb3N1cmUgZm9yIHRoZSBzdHJpbmcuICAic2l6ZV9oaW50IiBpbmRpY2F0ZXMgdGhlIHNpemUgb2YgdGhlCisgIC8vICAgICAvLyBzdHJpbmcgaWYgaXQgaXMga25vd24sIGhvd2V2ZXIgaWYgdGhlIHN0cmluZyBpcyBsZW5ndGgtZGVsaW1pdGVkCisgIC8vICAgICAvLyBhbmQgdGhlIGVuZC1vZi1zdHJpbmcgaXMgbm90IGF2YWlsYWJsZSBzaXplX2hpbnQgd2lsbCBiZSB6ZXJvLgorICAvLyAgICAgLy8gVGhpcyBjYXNlIGlzIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gdGhlIGNhc2Ugd2hlcmUgdGhlIHNpemUgaXMKKyAgLy8gICAgIC8vIGtub3duIHRvIGJlIHplcm8uCisgIC8vICAgICAvLworICAvLyAgICAgLy8gVE9ETyhoYWJlcm1hbik6IGlzIGl0IGltcG9ydGFudCB0byBkaXN0aW5ndWlzaCB0aGVzZSBjYXNlcz8KKyAgLy8gICAgIC8vIElmIHdlIGhhZCBzc2l6ZV90IGFzIGEgdHlwZSB3ZSBjb3VsZCBtYWtlIC0xICJ1bmtub3duIiwgYnV0CisgIC8vICAgICAvLyBzc2l6ZV90IGlzIFBPU0lYIChub3QgQU5TSSkgYW5kIHRoZXJlZm9yZSBsZXNzIHBvcnRhYmxlLgorICAvLyAgICAgLy8gSW4gcHJhY3RpY2UgSSBzdXNwZWN0IGl0IHdvbid0IGJlIGltcG9ydGFudCB0byBkaXN0aW5ndWlzaC4KKyAgLy8gICAgIHJldHVybiBjbG9zdXJlOworICAvLyAgIH0KKyAgLy8KKyAgLy8gICBzaXplX3Qgc3RyKE15Q2xvc3VyZSogY2xvc3VyZSwgY29uc3QgTXlIYW5kbGVyRGF0YSogZCwKKyAgLy8gICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IGxlbikgeworICAvLyAgICAgLy8gQ2FsbGVkIGZvciBlYWNoIGJ1ZmZlciBvZiBzdHJpbmcgZGF0YTsgdGhlIG11bHRpcGxlIHBoeXNpY2FsIGJ1ZmZlcnMKKyAgLy8gICAgIC8vIGFyZSBhbGwgcGFydCBvZiB0aGUgc2FtZSBsb2dpY2FsIHN0cmluZy4gIFRoZSByZXR1cm4gdmFsdWUgaW5kaWNhdGVzCisgIC8vICAgICAvLyBob3cgbWFueSBieXRlcyB3ZXJlIGNvbnN1bWVkLiAgSWYgdGhpcyBudW1iZXIgaXMgbGVzcyB0aGFuICJsZW4iLAorICAvLyAgICAgLy8gdGhpcyB3aWxsIGFsc28gaW5kaWNhdGUgdGhhdCBwcm9jZXNzaW5nIHNob3VsZCBiZSBoYWx0ZWQgZm9yIG5vdywKKyAgLy8gICAgIC8vIGxpa2UgcmV0dXJuaW5nIGZhbHNlIG9yIFVQQl9CUkVBSyBmcm9tIGFueSBvdGhlciBjYWxsYmFjay4gIElmCisgIC8vICAgICAvLyBudW1iZXIgaXMgZ3JlYXRlciB0aGFuICJsZW4iLCB0aGUgZXhjZXNzIGJ5dGVzIHdpbGwgYmUgc2tpcHBlZCBvdmVyCisgIC8vICAgICAvLyBhbmQgbm90IHBhc3NlZCB0byB0aGUgY2FsbGJhY2suCisgIC8vICAgICByZXR1cm4gbGVuOworICAvLyAgIH0KKyAgLy8KKyAgLy8gICBib29sIGVuZHN0cihNeUNsb3N1cmUqIGMsIGNvbnN0IE15SGFuZGxlckRhdGEqIGQpIHsKKyAgLy8gICAgIC8vIENhbGxlZCB3aGVuIGEgc3RyaW5nIHZhbHVlIGVuZHMuICBSZXR1cm4gdmFsdWUgaW5kaWNhdGVzIHdoZXRoZXIKKyAgLy8gICAgIC8vIHByb2Nlc3Npbmcgc2hvdWxkIGNvbnRpbnVlLgorICAvLyAgICAgcmV0dXJuIHRydWU7CisgIC8vICAgfQorICBib29sIFNldFN0YXJ0U3RyaW5nSGFuZGxlcihjb25zdCBGaWVsZERlZiogZiwgY29uc3QgU3RhcnRTdHJpbmdIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRTdHJpbmdIYW5kbGVyKGNvbnN0IEZpZWxkRGVmKiBmLCBjb25zdCBTdHJpbmdIYW5kbGVyJiBoKTsKKyAgYm9vbCBTZXRFbmRTdHJpbmdIYW5kbGVyKGNvbnN0IEZpZWxkRGVmKiBmLCBjb25zdCBFbmRGaWVsZEhhbmRsZXImIGgpOworCisgIC8vIFNldHMgdGhlIHN0YXJ0c2VxIGhhbmRsZXIsIHdoaWNoIGlzIGRlZmluZWQgYXMgZm9sbG93czoKKyAgLy8KKyAgLy8gICBNeVN1YkNsb3N1cmUgKnN0YXJ0c2VxKE15Q2xvc3VyZSogYywgY29uc3QgTXlIYW5kbGVyRGF0YSogZCkgeworICAvLyAgICAgLy8gQ2FsbGVkIHdoZW4gYSBzZXF1ZW5jZSAocmVwZWF0ZWQgZmllbGQpIGJlZ2lucy4gIFRoZSByZXR1cm5lZAorICAvLyAgICAgLy8gcG9pbnRlciBpbmRpY2F0ZXMgdGhlIGNsb3N1cmUgZm9yIHRoZSBzZXF1ZW5jZSAob3IgVVBCX0JSRUFLCisgIC8vICAgICAvLyB0byBpbnRlcnJ1cHQgcHJvY2Vzc2luZykuCisgIC8vICAgICByZXR1cm4gY2xvc3VyZTsKKyAgLy8gICB9CisgIC8vCisgIC8vICAgaC0+U2V0U3RhcnRTZXF1ZW5jZUhhbmRsZXIoZiwgVXBiQmluZChzdGFydHNlcSwgbmV3IE15SGFuZGxlckRhdGEoLi4uKSkpOworICAvLworICAvLyBSZXR1cm5zICJmYWxzZSIgaWYgImYiIGRvZXMgbm90IGJlbG9uZyB0byB0aGlzIG1lc3NhZ2Ugb3IgaXMgbm90IGEKKyAgLy8gcmVwZWF0ZWQgZmllbGQuCisgIGJvb2wgU2V0U3RhcnRTZXF1ZW5jZUhhbmRsZXIoY29uc3QgRmllbGREZWYqIGYsIGNvbnN0IFN0YXJ0RmllbGRIYW5kbGVyJiBoKTsKKworICAvLyBTZXRzIHRoZSBzdGFydHN1Ym1zZyBoYW5kbGVyIGZvciB0aGUgZ2l2ZW4gZmllbGQsIHdoaWNoIGlzIGRlZmluZWQgYXMKKyAgLy8gZm9sbG93czoKKyAgLy8KKyAgLy8gICBNeVN1YkNsb3N1cmUqIHN0YXJ0c3VibXNnKE15Q2xvc3VyZSogYywgY29uc3QgTXlIYW5kbGVyRGF0YSogZCkgeworICAvLyAgICAgLy8gQ2FsbGVkIHdoZW4gYSBzdWJtZXNzYWdlIGJlZ2lucy4gIFRoZSByZXR1cm5lZCBwb2ludGVyIGluZGljYXRlcyB0aGUKKyAgLy8gICAgIC8vIGNsb3N1cmUgZm9yIHRoZSBzZXF1ZW5jZSAob3IgVVBCX0JSRUFLIHRvIGludGVycnVwdCBwcm9jZXNzaW5nKS4KKyAgLy8gICAgIHJldHVybiBjbG9zdXJlOworICAvLyAgIH0KKyAgLy8KKyAgLy8gICBoLT5TZXRTdGFydFN1Yk1lc3NhZ2VIYW5kbGVyKGYsIFVwYkJpbmQoc3RhcnRzdWJtc2csCisgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNeUhhbmRsZXJEYXRhKC4uLikpKTsKKyAgLy8KKyAgLy8gUmV0dXJucyAiZmFsc2UiIGlmICJmIiBkb2VzIG5vdCBiZWxvbmcgdG8gdGhpcyBtZXNzYWdlIG9yIGlzIG5vdCBhCisgIC8vIHN1Ym1lc3NhZ2UvZ3JvdXAgZmllbGQuCisgIGJvb2wgU2V0U3RhcnRTdWJNZXNzYWdlSGFuZGxlcihjb25zdCBGaWVsZERlZiogZiwgY29uc3QgU3RhcnRGaWVsZEhhbmRsZXImIGgpOworCisgIC8vIFNldHMgdGhlIGVuZHN1Ym1zZyBoYW5kbGVyIGZvciB0aGUgZ2l2ZW4gZmllbGQsIHdoaWNoIGlzIGRlZmluZWQgYXMKKyAgLy8gZm9sbG93czoKKyAgLy8KKyAgLy8gICBib29sIGVuZHN1Ym1zZyhNeUNsb3N1cmUqIGMsIGNvbnN0IE15SGFuZGxlckRhdGEqIGQpIHsKKyAgLy8gICAgIC8vIENhbGxlZCB3aGVuIGEgc3VibWVzc2FnZSBlbmRzLiAgUmV0dXJucyB0cnVlIHRvIGNvbnRpbnVlIHByb2Nlc3NpbmcuCisgIC8vICAgICByZXR1cm4gdHJ1ZTsKKyAgLy8gICB9CisgIC8vCisgIC8vIFJldHVybnMgImZhbHNlIiBpZiAiZiIgZG9lcyBub3QgYmVsb25nIHRvIHRoaXMgbWVzc2FnZSBvciBpcyBub3QgYQorICAvLyBzdWJtZXNzYWdlL2dyb3VwIGZpZWxkLgorICBib29sIFNldEVuZFN1Yk1lc3NhZ2VIYW5kbGVyKGNvbnN0IEZpZWxkRGVmICpmLCBjb25zdCBFbmRGaWVsZEhhbmRsZXIgJmgpOworCisgIC8vIFN0YXJ0cyB0aGUgZW5kc3Vic2VxIGhhbmRsZXIgZm9yIHRoZSBnaXZlbiBmaWVsZCwgd2hpY2ggaXMgZGVmaW5lZCBhcworICAvLyBmb2xsb3dzOgorICAvLworICAvLyAgIGJvb2wgZW5kc2VxKE15Q2xvc3VyZSogYywgY29uc3QgTXlIYW5kbGVyRGF0YSogZCkgeworICAvLyAgICAgLy8gQ2FsbGVkIHdoZW4gYSBzZXF1ZW5jZSBlbmRzLiAgUmV0dXJucyB0cnVlIGNvbnRpbnVlIHByb2Nlc3NpbmcuCisgIC8vICAgICByZXR1cm4gdHJ1ZTsKKyAgLy8gICB9CisgIC8vCisgIC8vIFJldHVybnMgImZhbHNlIiBpZiAiZiIgZG9lcyBub3QgYmVsb25nIHRvIHRoaXMgbWVzc2FnZSBvciBpcyBub3QgYQorICAvLyByZXBlYXRlZCBmaWVsZC4KKyAgYm9vbCBTZXRFbmRTZXF1ZW5jZUhhbmRsZXIoY29uc3QgRmllbGREZWYqIGYsIGNvbnN0IEVuZEZpZWxkSGFuZGxlciYgaCk7CisKKyAgLy8gU2V0cyBvciBnZXRzIHRoZSBvYmplY3QgdGhhdCBzcGVjaWZpZXMgaGFuZGxlcnMgZm9yIHRoZSBnaXZlbiBmaWVsZCwgd2hpY2gKKyAgLy8gbXVzdCBiZSBhIHN1Ym1lc3NhZ2Ugb3IgZ3JvdXAuICBSZXR1cm5zIE5VTEwgaWYgbm8gaGFuZGxlcnMgYXJlIHNldC4KKyAgYm9vbCBTZXRTdWJIYW5kbGVycyhjb25zdCBGaWVsZERlZiogZiwgY29uc3QgSGFuZGxlcnMqIHN1Yik7CisgIGNvbnN0IEhhbmRsZXJzKiBHZXRTdWJIYW5kbGVycyhjb25zdCBGaWVsZERlZiogZikgY29uc3Q7CisKKyAgLy8gRXF1aXZhbGVudCB0byBHZXRTdWJIYW5kbGVycywgYnV0IHRha2VzIHRoZSBTVEFSVFNVQk1TRyBzZWxlY3RvciBmb3IgdGhlCisgIC8vIGZpZWxkLgorICBjb25zdCBIYW5kbGVycyogR2V0U3ViSGFuZGxlcnMoU2VsZWN0b3Igc3RhcnRzdWJtc2cpIGNvbnN0OworCisgIC8vIEEgc2VsZWN0b3IgcmVmZXJzIHRvIGEgc3BlY2lmaWMgZmllbGQgaGFuZGxlciBpbiB0aGUgSGFuZGxlcnMgb2JqZWN0CisgIC8vIChmb3IgZXhhbXBsZTogdGhlIFNUQVJUU1VCTVNHIGhhbmRsZXIgZm9yIGZpZWxkICJmaWVsZDE1IikuCisgIC8vIE9uIHN1Y2Nlc3MsIHJldHVybnMgdHJ1ZSBhbmQgc3RvcmVzIHRoZSBzZWxlY3RvciBpbiAicyIuCisgIC8vIElmIHRoZSBGaWVsZERlZiBvciBUeXBlIGFyZSBpbnZhbGlkLCByZXR1cm5zIGZhbHNlLgorICAvLyBUaGUgcmV0dXJuZWQgc2VsZWN0b3IgaXMgT05MWSB2YWxpZCBmb3IgSGFuZGxlcnMgd2hvc2UgTWVzc2FnZURlZgorICAvLyBjb250YWlucyB0aGlzIEZpZWxkRGVmLgorICBzdGF0aWMgYm9vbCBHZXRTZWxlY3Rvcihjb25zdCBGaWVsZERlZiogZiwgVHlwZSB0eXBlLCBTZWxlY3Rvciogcyk7CisKKyAgLy8gR2l2ZW4gYSBTVEFSVCBzZWxlY3RvciBvZiBhbnkga2luZCwgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBFTkQgc2VsZWN0b3IuCisgIHN0YXRpYyBTZWxlY3RvciBHZXRFbmRTZWxlY3RvcihTZWxlY3RvciBzdGFydF9zZWxlY3Rvcik7CisKKyAgLy8gUmV0dXJucyB0aGUgZnVuY3Rpb24gcG9pbnRlciBmb3IgdGhpcyBoYW5kbGVyLiAgSXQgaXMgdGhlIGNsaWVudCdzCisgIC8vIHJlc3BvbnNpYmlsaXR5IHRvIGNhc3QgdG8gdGhlIGNvcnJlY3QgZnVuY3Rpb24gdHlwZSBiZWZvcmUgY2FsbGluZyBpdC4KKyAgR2VuZXJpY0Z1bmN0aW9uKiBHZXRIYW5kbGVyKFNlbGVjdG9yIHNlbGVjdG9yKTsKKworICAvLyBTZXRzIHRoZSBnaXZlbiBhdHRyaWJ1dGVzIHRvIHRoZSBhdHRyaWJ1dGVzIGZvciB0aGlzIHNlbGVjdG9yLgorICBib29sIEdldEF0dHJpYnV0ZXMoU2VsZWN0b3Igc2VsZWN0b3IsIEhhbmRsZXJBdHRyaWJ1dGVzKiBhdHRyKTsKKworICAvLyBSZXR1cm5zIHRoZSBoYW5kbGVyIGRhdGEgdGhhdCB3YXMgcmVnaXN0ZXJlZCB3aXRoIHRoaXMgaGFuZGxlci4KKyAgY29uc3Qgdm9pZCogR2V0SGFuZGxlckRhdGEoU2VsZWN0b3Igc2VsZWN0b3IpOworCisgIC8vIENvdWxkIGFkZCBhbnkgb2YgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgYXMtbmVlZGVkLCB3aXRoIHNvbWUgbWlub3IKKyAgLy8gaW1wbGVtZW50YXRpb24gY2hhbmdlczoKKyAgLy8KKyAgLy8gY29uc3QgRmllbGREZWYqIEdldEZpZWxkRGVmKFNlbGVjdG9yIHNlbGVjdG9yKTsKKyAgLy8gc3RhdGljIGJvb2wgSXNTZXF1ZW5jZShTZWxlY3RvciBzZWxlY3Rvcik7CisKKyBwcml2YXRlOgorICBVUEJfRElTQUxMT1dfUE9EX09QUyhIYW5kbGVycywgdXBiOjpIYW5kbGVycyk7CisKKyAgZnJpZW5kIFVQQl9JTkxJTkUgR2VuZXJpY0Z1bmN0aW9uICo6OnVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKAorICAgICAgY29uc3QgdXBiX2hhbmRsZXJzICpoLCB1cGJfc2VsZWN0b3JfdCBzKTsKKyAgZnJpZW5kIFVQQl9JTkxJTkUgY29uc3Qgdm9pZCAqOjp1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcmRhdGEoCisgICAgICBjb25zdCB1cGJfaGFuZGxlcnMgKmgsIHVwYl9zZWxlY3Rvcl90IHMpOworCissCitVUEJfREVGSU5FX1NUUlVDVCh1cGJfaGFuZGxlcnMsIHVwYl9yZWZjb3VudGVkLAorICBjb25zdCB1cGJfbXNnZGVmICptc2c7CisgIGNvbnN0IHVwYl9oYW5kbGVycyAqKnN1YjsKKyAgY29uc3Qgdm9pZCAqdG9wX2Nsb3N1cmVfdHlwZTsKKyAgdXBiX2ludHRhYmxlIGNsZWFudXBfOworICB1cGJfc3RhdHVzIHN0YXR1c187ICAvLyBVc2VkIG9ubHkgd2hlbiBtdXRhYmxlLgorICB1cGJfaGFuZGxlcnNfdGFiZW50IHRhYmxlWzFdOyAgLy8gRHluYW1pY2FsbHktc2l6ZWQgZmllbGQgaGFuZGxlciBhcnJheS4KKykpOworCisKKyNpZmRlZiBfX2NwbHVzcGx1cworCituYW1lc3BhY2UgdXBiIHsKKworLy8gQ29udmVuaWVuY2UgbWFjcm9zIGZvciBjcmVhdGluZyBhIEhhbmRsZXIgb2JqZWN0IHRoYXQgaXMgd3JhcHBlZCB3aXRoIGEKKy8vIHR5cGUtc2FmZSB3cmFwcGVyIGZ1bmN0aW9uIHRoYXQgY29udmVydHMgdGhlICJ2b2lkKiIgcGFyYW1ldGVycy9yZXR1cm5zCisvLyBvZiB0aGUgdW5kZXJseWluZyBDIEFQSSBpbnRvIG5pY2UgQysrIGZ1bmN0aW9uLgorLy8KKy8vIFNhbXBsZSB1c2FnZToKKy8vICAgdm9pZCBPblZhbHVlMShNeUNsb3N1cmUqIGMsIGNvbnN0IE15SGFuZGxlckRhdGEqIGQsIGludDMyX3QgdmFsKSB7CisvLyAgICAgLy8gZG8gc3R1ZmYgLi4uCisvLyAgIH0KKy8vCisvLyAgIC8vIEhhbmRsZXIgdGhhdCBkb2Vzbid0IG5lZWQgYW55IGRhdGEgYm91bmQgdG8gaXQuCisvLyAgIHZvaWQgT25WYWx1ZTIoTXlDbG9zdXJlKiBjLCBpbnQzMl90IHZhbCkgeworLy8gICAgIC8vIGRvIHN0dWZmIC4uLgorLy8gICB9CisvLworLy8gICAvLyBIYW5kbGVyIHRoYXQgcmV0dXJucyBib29sIHNvIGl0IGNhbiByZXR1cm4gZmFpbHVyZSBpZiBuZWNlc3NhcnkuCisvLyAgIGJvb2wgT25WYWx1ZTMoTXlDbG9zdXJlKiBjLCBpbnQzMl90IHZhbCkgeworLy8gICAgIC8vIGRvIHN0dWZmIC4uLgorLy8gICAgIHJldHVybiBvazsKKy8vICAgfQorLy8KKy8vICAgLy8gTWVtYmVyIGZ1bmN0aW9uIGhhbmRsZXIuCisvLyAgIGNsYXNzIE15Q2xvc3VyZSB7CisvLyAgICBwdWJsaWM6CisvLyAgICAgdm9pZCBPblZhbHVlKGludDMyX3QgdmFsKSB7CisvLyAgICAgICAvLyBkbyBzdHVmZiAuLi4KKy8vICAgICB9CisvLyAgIH07CisvLworLy8gICAvLyBUYWtlcyBvd25lcnNoaXAgb2YgdGhlIE15SGFuZGxlckRhdGEuCisvLyAgIGhhbmRsZXJzLT5TZXRJbnQzMkhhbmRsZXIoZjEsIFVwYkJpbmQoT25WYWx1ZTEsIG5ldyBNeUhhbmRsZXJEYXRhKC4uLikpKTsKKy8vICAgaGFuZGxlcnMtPlNldEludDMySGFuZGxlcihmMiwgVXBiTWFrZUhhbmRsZXIoT25WYWx1ZTIpKTsKKy8vICAgaGFuZGxlcnMtPlNldEludDMySGFuZGxlcihmMSwgVXBiTWFrZUhhbmRsZXIoT25WYWx1ZTMpKTsKKy8vICAgaGFuZGxlcnMtPlNldEludDMySGFuZGxlcihmMiwgVXBiTWFrZUhhbmRsZXIoJk15Q2xvc3VyZTo6T25WYWx1ZSkpOworCisjaWZkZWYgVVBCX0NYWDExCisKKy8vIEluIEMrKzExLCB0aGUgInRlbXBsYXRlIiBkaXNhbWJpZ3VhdG9yIGNhbiBhcHBlYXIgZXZlbiBvdXRzaWRlIHRlbXBsYXRlcywKKy8vIHNvIGFsbCBjYWxscyBjYW4gc2FmZWx5IHVzZSB0aGlzIHBhaXIgb2YgbWFjcm9zLgorCisjZGVmaW5lIFVwYk1ha2VIYW5kbGVyKGYpIHVwYjo6TWF0Y2hGdW5jKGYpLnRlbXBsYXRlIEdldEZ1bmM8Zj4oKQorCisvLyBXZSBoYXZlIHRvIGJlIGNhcmVmdWwgdG8gb25seSBldmFsdWF0ZSAiZCIgb25jZS4KKyNkZWZpbmUgVXBiQmluZChmLCBkKSB1cGI6Ok1hdGNoRnVuYyhmKS50ZW1wbGF0ZSBHZXRGdW5jPGY+KChkKSkKKworI2Vsc2UKKworLy8gUHJpb3IgdG8gQysrMTEsIHRoZSAidGVtcGxhdGUiIGRpc2FtYmlndWF0b3IgbWF5IG9ubHkgYXBwZWFyIGluc2lkZSBhCisvLyB0ZW1wbGF0ZSwgc28gdGhlIHJlZ3VsYXIgbWFjcm8gbXVzdCBub3QgdXNlICJ0ZW1wbGF0ZSIKKworI2RlZmluZSBVcGJNYWtlSGFuZGxlcihmKSB1cGI6Ok1hdGNoRnVuYyhmKS5HZXRGdW5jPGY+KCkKKworI2RlZmluZSBVcGJCaW5kKGYsIGQpIHVwYjo6TWF0Y2hGdW5jKGYpLkdldEZ1bmM8Zj4oKGQpKQorCisjZW5kaWYgIC8vIFVQQl9DWFgxMQorCisvLyBUaGlzIG1hY3JvIG11c3QgYmUgdXNlZCBpbiBDKys5OCBmb3IgY2FsbHMgZnJvbSBpbnNpZGUgYSB0ZW1wbGF0ZS4gIEJ1dCB3ZQorLy8gZGVmaW5lIHRoaXMgdmFyaWFudCBpbiBhbGwgY2FzZXM7IGNvZGUgdGhhdCB3YW50cyB0byBiZSBjb21wYXRpYmxlIHdpdGggYm90aAorLy8gQysrOTggYW5kIEMrKzExIHNob3VsZCBhbHdheXMgdXNlIHRoaXMgbWFjcm8gd2hlbiBjYWxsaW5nIGZyb20gYSB0ZW1wbGF0ZS4KKyNkZWZpbmUgVXBiTWFrZUhhbmRsZXJUKGYpIHVwYjo6TWF0Y2hGdW5jKGYpLnRlbXBsYXRlIEdldEZ1bmM8Zj4oKQorCisvLyBXZSBoYXZlIHRvIGJlIGNhcmVmdWwgdG8gb25seSBldmFsdWF0ZSAiZCIgb25jZS4KKyNkZWZpbmUgVXBiQmluZFQoZiwgZCkgdXBiOjpNYXRjaEZ1bmMoZikudGVtcGxhdGUgR2V0RnVuYzxmPigoZCkpCisKKy8vIEhhbmRsZXI6IGEgc3RydWN0IHRoYXQgY29udGFpbnMgdGhlIChoYW5kbGVyLCBkYXRhLCBkZWxldGVyKSB0dXBsZSB0aGF0IGlzCisvLyB1c2VkIHRvIHJlZ2lzdGVyIGFsbCBoYW5kbGVycy4gIFVzZXJzIGNhbiBNYWtlKCkgdGhlc2UgZGlyZWN0bHkgYnV0IGl0J3MKKy8vIG1vcmUgY29udmVuaWVudCB0byB1c2UgdGhlIFVwYk1ha2VIYW5kbGVyL1VwYkJpbmQgbWFjcm9zIGFib3ZlLgordGVtcGxhdGUgPGNsYXNzIFQ+IGNsYXNzIEhhbmRsZXIgeworIHB1YmxpYzoKKyAgLy8gVGhlIHVuZGVybHlpbmcsIGhhbmRsZXIgZnVuY3Rpb24gc2lnbmF0dXJlIHRoYXQgdXBiIHVzZXMgaW50ZXJuYWxseS4KKyAgdHlwZWRlZiBUIEZ1bmNQdHI7CisKKyAgLy8gSW50ZW50aW9uYWxseSBpbXBsaWNpdC4KKyAgdGVtcGxhdGUgPGNsYXNzIEY+IEhhbmRsZXIoRiBmdW5jKTsKKyAgfkhhbmRsZXIoKTsKKworIHByaXZhdGU6CisgIHZvaWQgQWRkQ2xlYW51cChIYW5kbGVycyogaCkgY29uc3QgeworICAgIGlmIChjbGVhbnVwX2Z1bmNfKSB7CisgICAgICBib29sIG9rID0gaC0+QWRkQ2xlYW51cChjbGVhbnVwX2RhdGFfLCBjbGVhbnVwX2Z1bmNfKTsKKyAgICAgIFVQQl9BU1NFUlRfVkFSKG9rLCBvayk7CisgICAgfQorICB9CisKKyAgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihIYW5kbGVyKTsKKyAgZnJpZW5kIGNsYXNzIEhhbmRsZXJzOworICBGdW5jUHRyIGhhbmRsZXJfOworICBtdXRhYmxlIEhhbmRsZXJBdHRyaWJ1dGVzIGF0dHJfOworICBtdXRhYmxlIGJvb2wgcmVnaXN0ZXJlZF87CisgIHZvaWQgKmNsZWFudXBfZGF0YV87CisgIHVwYl9oYW5kbGVyZnJlZSAqY2xlYW51cF9mdW5jXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSB1cGIKKworI2VuZGlmICAvLyBfX2NwbHVzcGx1cworCitVUEJfQkVHSU5fRVhURVJOX0MKKworLy8gTmF0aXZlIEMgQVBJLgorCisvLyBIYW5kbGVyIGZ1bmN0aW9uIHR5cGVkZWZzLgordHlwZWRlZiBib29sIHVwYl9zdGFydG1zZ19oYW5kbGVyZnVuYyh2b2lkICpjLCBjb25zdCB2b2lkKik7Cit0eXBlZGVmIGJvb2wgdXBiX2VuZG1zZ19oYW5kbGVyZnVuYyh2b2lkICpjLCBjb25zdCB2b2lkICosIHVwYl9zdGF0dXMgKnN0YXR1cyk7Cit0eXBlZGVmIHZvaWQqIHVwYl9zdGFydGZpZWxkX2hhbmRsZXJmdW5jKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkKTsKK3R5cGVkZWYgYm9vbCB1cGJfZW5kZmllbGRfaGFuZGxlcmZ1bmModm9pZCAqYywgY29uc3Qgdm9pZCAqaGQpOwordHlwZWRlZiBib29sIHVwYl9pbnQzMl9oYW5kbGVyZnVuYyh2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgaW50MzJfdCB2YWwpOwordHlwZWRlZiBib29sIHVwYl9pbnQ2NF9oYW5kbGVyZnVuYyh2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgaW50NjRfdCB2YWwpOwordHlwZWRlZiBib29sIHVwYl91aW50MzJfaGFuZGxlcmZ1bmModm9pZCAqYywgY29uc3Qgdm9pZCAqaGQsIHVpbnQzMl90IHZhbCk7Cit0eXBlZGVmIGJvb2wgdXBiX3VpbnQ2NF9oYW5kbGVyZnVuYyh2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgdWludDY0X3QgdmFsKTsKK3R5cGVkZWYgYm9vbCB1cGJfZmxvYXRfaGFuZGxlcmZ1bmModm9pZCAqYywgY29uc3Qgdm9pZCAqaGQsIGZsb2F0IHZhbCk7Cit0eXBlZGVmIGJvb2wgdXBiX2RvdWJsZV9oYW5kbGVyZnVuYyh2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgZG91YmxlIHZhbCk7Cit0eXBlZGVmIGJvb2wgdXBiX2Jvb2xfaGFuZGxlcmZ1bmModm9pZCAqYywgY29uc3Qgdm9pZCAqaGQsIGJvb2wgdmFsKTsKK3R5cGVkZWYgdm9pZCAqdXBiX3N0YXJ0c3RyX2hhbmRsZXJmdW5jKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemVfaGludCk7Cit0eXBlZGVmIHNpemVfdCB1cGJfc3RyaW5nX2hhbmRsZXJmdW5jKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkLCBjb25zdCBjaGFyICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBuLCBjb25zdCB1cGJfYnVmaGFuZGxlKiBoYW5kbGUpOworCisvLyB1cGJfYnVmaGFuZGxlCitzaXplX3QgdXBiX2J1ZmhhbmRsZV9vYmpvZnMoY29uc3QgdXBiX2J1ZmhhbmRsZSAqaCk7CisKKy8vIHVwYl9oYW5kbGVyYXR0cgordm9pZCB1cGJfaGFuZGxlcmF0dHJfaW5pdCh1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOwordm9pZCB1cGJfaGFuZGxlcmF0dHJfdW5pbml0KHVwYl9oYW5kbGVyYXR0ciAqYXR0cik7CisKK2Jvb2wgdXBiX2hhbmRsZXJhdHRyX3NldGhhbmRsZXJkYXRhKHVwYl9oYW5kbGVyYXR0ciAqYXR0ciwgY29uc3Qgdm9pZCAqaGQpOworYm9vbCB1cGJfaGFuZGxlcmF0dHJfc2V0Y2xvc3VyZXR5cGUodXBiX2hhbmRsZXJhdHRyICphdHRyLCBjb25zdCB2b2lkICp0eXBlKTsKK2NvbnN0IHZvaWQgKnVwYl9oYW5kbGVyYXR0cl9jbG9zdXJldHlwZShjb25zdCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcmF0dHJfc2V0cmV0dXJuY2xvc3VyZXR5cGUodXBiX2hhbmRsZXJhdHRyICphdHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqdHlwZSk7Citjb25zdCB2b2lkICp1cGJfaGFuZGxlcmF0dHJfcmV0dXJuY2xvc3VyZXR5cGUoY29uc3QgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJhdHRyX3NldGFsd2F5c29rKHVwYl9oYW5kbGVyYXR0ciAqYXR0ciwgYm9vbCBhbHdheXNvayk7Citib29sIHVwYl9oYW5kbGVyYXR0cl9hbHdheXNvayhjb25zdCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworCitVUEJfSU5MSU5FIGNvbnN0IHZvaWQgKnVwYl9oYW5kbGVyYXR0cl9oYW5kbGVyZGF0YSgKKyAgICBjb25zdCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpIHsKKyAgcmV0dXJuIGF0dHItPmhhbmRsZXJfZGF0YV87Cit9CisKKy8vIHVwYl9oYW5kbGVycwordHlwZWRlZiB2b2lkIHVwYl9oYW5kbGVyc19jYWxsYmFjayhjb25zdCB2b2lkICpjbG9zdXJlLCB1cGJfaGFuZGxlcnMgKmgpOwordXBiX2hhbmRsZXJzICp1cGJfaGFuZGxlcnNfbmV3KGNvbnN0IHVwYl9tc2dkZWYgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpOworY29uc3QgdXBiX2hhbmRsZXJzICp1cGJfaGFuZGxlcnNfbmV3ZnJvemVuKGNvbnN0IHVwYl9tc2dkZWYgKm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJzX2NhbGxiYWNrICpjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpjbG9zdXJlKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX2lzZnJvemVuKGNvbnN0IHVwYl9oYW5kbGVycyAqaCk7Cit2b2lkIHVwYl9oYW5kbGVyc19yZWYoY29uc3QgdXBiX2hhbmRsZXJzICpoLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9oYW5kbGVyc191bnJlZihjb25zdCB1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHZvaWQgKm93bmVyKTsKK3ZvaWQgdXBiX2hhbmRsZXJzX2RvbmF0ZXJlZihjb25zdCB1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHZvaWQgKmZyb20sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqdG8pOwordm9pZCB1cGJfaGFuZGxlcnNfY2hlY2tyZWYoY29uc3QgdXBiX2hhbmRsZXJzICpoLCBjb25zdCB2b2lkICpvd25lcik7CisKK2NvbnN0IHVwYl9zdGF0dXMgKnVwYl9oYW5kbGVyc19zdGF0dXModXBiX2hhbmRsZXJzICpoKTsKK3ZvaWQgdXBiX2hhbmRsZXJzX2NsZWFyZXJyKHVwYl9oYW5kbGVycyAqaCk7Citjb25zdCB1cGJfbXNnZGVmICp1cGJfaGFuZGxlcnNfbXNnZGVmKGNvbnN0IHVwYl9oYW5kbGVycyAqaCk7Citib29sIHVwYl9oYW5kbGVyc19hZGRjbGVhbnVwKHVwYl9oYW5kbGVycyAqaCwgdm9pZCAqcCwgdXBiX2hhbmRsZXJmcmVlICpoZnJlZSk7CisKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldHN0YXJ0bXNnKHVwYl9oYW5kbGVycyAqaCwgdXBiX3N0YXJ0bXNnX2hhbmRsZXJmdW5jICpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldGVuZG1zZyh1cGJfaGFuZGxlcnMgKmgsIHVwYl9lbmRtc2dfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldGludDMyKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2ludDMyX2hhbmRsZXJmdW5jICpmdW5jLCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcnNfc2V0aW50NjQodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaW50NjRfaGFuZGxlcmZ1bmMgKmZ1bmMsIHVwYl9oYW5kbGVyYXR0ciAqYXR0cik7Citib29sIHVwYl9oYW5kbGVyc19zZXR1aW50MzIodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3VpbnQzMl9oYW5kbGVyZnVuYyAqZnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcnNfc2V0dWludDY0KHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl91aW50NjRfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldGZsb2F0KHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2Zsb2F0X2hhbmRsZXJmdW5jICpmdW5jLCB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcnNfc2V0ZG91YmxlKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9kb3VibGVfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldGJvb2wodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9ib29sX2hhbmRsZXJmdW5jICpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdHIodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zdHJpbmdfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldGVuZHN0cih1cGJfaGFuZGxlcnMgKmgsIGNvbnN0IHVwYl9maWVsZGRlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfZW5kZmllbGRfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2hhbmRsZXJhdHRyICphdHRyKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldHN0YXJ0c2VxKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXJ0ZmllbGRfaGFuZGxlcmZ1bmMgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfaGFuZGxlcmF0dHIgKmF0dHIpOworYm9vbCB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdWJtc2codXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhcnRmaWVsZF9oYW5kbGVyZnVuYyAqZnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyYXR0ciAqYXR0cik7Citib29sIHVwYl9oYW5kbGVyc19zZXRlbmRzdWJtc2codXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jICpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyYXR0ciAqYXR0cik7Citib29sIHVwYl9oYW5kbGVyc19zZXRlbmRzZXEodXBiX2hhbmRsZXJzICpoLCBjb25zdCB1cGJfZmllbGRkZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jICpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyYXR0ciAqYXR0cik7CisKK2Jvb2wgdXBiX2hhbmRsZXJzX3NldHN1YmhhbmRsZXJzKHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2hhbmRsZXJzICpzdWIpOworY29uc3QgdXBiX2hhbmRsZXJzICp1cGJfaGFuZGxlcnNfZ2V0c3ViaGFuZGxlcnMoY29uc3QgdXBiX2hhbmRsZXJzICpoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX2hhbmRsZXJzX2dldHN1YmhhbmRsZXJzX3NlbChjb25zdCB1cGJfaGFuZGxlcnMgKmgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3NlbGVjdG9yX3Qgc2VsKTsKKworVVBCX0lOTElORSB1cGJfZnVuYyAqdXBiX2hhbmRsZXJzX2dldGhhbmRsZXIoY29uc3QgdXBiX2hhbmRsZXJzICpoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3NlbGVjdG9yX3QgcykgeworICByZXR1cm4gKHVwYl9mdW5jICopaC0+dGFibGVbc10uZnVuYzsKK30KKworYm9vbCB1cGJfaGFuZGxlcnNfZ2V0YXR0cihjb25zdCB1cGJfaGFuZGxlcnMgKmgsIHVwYl9zZWxlY3Rvcl90IHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9oYW5kbGVyYXR0ciAqYXR0cik7CisKK1VQQl9JTkxJTkUgY29uc3Qgdm9pZCAqdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKGNvbnN0IHVwYl9oYW5kbGVycyAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zZWxlY3Rvcl90IHMpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyYXR0cl9oYW5kbGVyZGF0YSgmaC0+dGFibGVbc10uYXR0cik7Cit9CisKKy8vIEhhbmRsZXIgdHlwZXMgZm9yIHNpbmdsZSBmaWVsZHMuCisvLyBSaWdodCBub3cgd2Ugb25seSBoYXZlIG9uZSBmb3IgVFlQRV9CWVRFUyBidXQgb25lcyBmb3Igb3RoZXIgdHlwZXMKKy8vIHNob3VsZCBmb2xsb3cuCisvLworLy8gVGhlc2UgZm9sbG93IHRoZSBzYW1lIGhhbmRsZXJzIHByb3RvY29sIGZvciBmaWVsZHMgb2YgYSBtZXNzYWdlLgorVVBCX0RFRklORV9DTEFTUzAodXBiOjpCeXRlc0hhbmRsZXIsCisgcHVibGljOgorICBCeXRlc0hhbmRsZXIoKTsKKyAgfkJ5dGVzSGFuZGxlcigpOworLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9ieXRlc2hhbmRsZXIsCisgIHVwYl9oYW5kbGVyc190YWJlbnQgdGFibGVbM107CispKTsKKwordm9pZCB1cGJfYnl0ZXNoYW5kbGVyX2luaXQodXBiX2J5dGVzaGFuZGxlciAqaCk7Cit2b2lkIHVwYl9ieXRlc2hhbmRsZXJfdW5pbml0KHVwYl9ieXRlc2hhbmRsZXIgKmgpOworCisvLyBDYWxsZXIgbXVzdCBlbnN1cmUgdGhhdCAiZCIgb3V0bGl2ZXMgdGhlIGhhbmRsZXJzLgorLy8gVE9ETyhoYWJlcm1hbik6IHN1cHBvcnQgaGFuZGxlcmZyZWUgZnVuY3Rpb24gZm9yIHRoZSBkYXRhLgorLy8gVE9ETyhoYWJlcm1hbik6IHNob3VsZCB0aGlzIGhhdmUgYSAiZnJlZXplIiBvcGVyYXRpb24/ICBJdCdzIG5vdCBuZWNlc3NhcnkKKy8vIGZvciBtZW1vcnkgbWFuYWdlbWVudCwgYnV0IGNvdWxkIGJlIHVzZWZ1bCB0byBmb3JjZSBpbW11dGFiaWxpdHkgYW5kIHByb3ZpZGUKKy8vIGEgY29udmVuaWVudCBtb21lbnQgdG8gdmVyaWZ5IHRoYXQgYWxsIHJlZ2lzdHJhdGlvbiBzdWNjZWVkZWQuCitib29sIHVwYl9ieXRlc2hhbmRsZXJfc2V0c3RhcnRzdHIodXBiX2J5dGVzaGFuZGxlciAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMgKmZ1bmMsIHZvaWQgKmQpOworYm9vbCB1cGJfYnl0ZXNoYW5kbGVyX3NldHN0cmluZyh1cGJfYnl0ZXNoYW5kbGVyICpoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RyaW5nX2hhbmRsZXJmdW5jICpmdW5jLCB2b2lkICpkKTsKK2Jvb2wgdXBiX2J5dGVzaGFuZGxlcl9zZXRlbmRzdHIodXBiX2J5dGVzaGFuZGxlciAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jICpmdW5jLCB2b2lkICpkKTsKKworLy8gIlN0YXRpYyIgbWV0aG9kcworYm9vbCB1cGJfaGFuZGxlcnNfZnJlZXplKHVwYl9oYW5kbGVycyAqY29uc3QgKmhhbmRsZXJzLCBpbnQgbiwgdXBiX3N0YXR1cyAqcyk7Cit1cGJfaGFuZGxlcnR5cGVfdCB1cGJfaGFuZGxlcnNfZ2V0cHJpbWl0aXZlaGFuZGxlcnR5cGUoY29uc3QgdXBiX2ZpZWxkZGVmICpmKTsKK2Jvb2wgdXBiX2hhbmRsZXJzX2dldHNlbGVjdG9yKGNvbnN0IHVwYl9maWVsZGRlZiAqZiwgdXBiX2hhbmRsZXJ0eXBlX3QgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zZWxlY3Rvcl90ICpzKTsKK1VQQl9JTkxJTkUgdXBiX3NlbGVjdG9yX3QgdXBiX2hhbmRsZXJzX2dldGVuZHNlbGVjdG9yKHVwYl9zZWxlY3Rvcl90IHN0YXJ0KSB7CisgIHJldHVybiBzdGFydCArIDE7Cit9CisKKy8vIEludGVybmFsLW9ubHkuCit1aW50MzJfdCB1cGJfaGFuZGxlcnNfc2VsZWN0b3JiYXNlb2Zmc2V0KGNvbnN0IHVwYl9maWVsZGRlZiAqZik7Cit1aW50MzJfdCB1cGJfaGFuZGxlcnNfc2VsZWN0b3Jjb3VudChjb25zdCB1cGJfZmllbGRkZWYgKmYpOworCitVUEJfRU5EX0VYVEVSTl9DCisKKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTEtMjAxMiBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogSW5saW5lIGRlZmluaXRpb25zIGZvciBoYW5kbGVycy5oLCB3aGljaCBhcmUgcGFydGljdWxhcmx5IGxvbmcgYW5kIGEgYml0CisgKiB0cmlja3kuCisgKi8KKworI2lmbmRlZiBVUEJfSEFORExFUlNfSU5MX0hfCisjZGVmaW5lIFVQQl9IQU5ETEVSU19JTkxfSF8KKworI2luY2x1ZGUgPGxpbWl0cy5oPgorCisvLyBUeXBlIGRldGVjdGlvbiBhbmQgdHlwZWRlZnMgZm9yIGludGVnZXIgdHlwZXMuCisvLyBGb3IgcGxhdGZvcm1zIHdoZXJlIHRoZXJlIGFyZSBtdWx0aXBsZSAzMi1iaXQgb3IgNjQtYml0IHR5cGVzLCB3ZSBuZWVkIHRvIGJlCisvLyBhYmxlIHRvIGVudW1lcmF0ZSB0aGVtIHNvIHdlIGNhbiBwcm9wZXJseSBjcmVhdGUgb3ZlcmxvYWRzIGZvciBhbGwgdmFyaWFudHMuCisvLworLy8gSWYgYW55IHBsYXRmb3JtIGV4aXN0ZWQgd2hlcmUgdGhlcmUgd2VyZSB0aHJlZSBpbnRlZ2VyIHR5cGVzIHdpdGggdGhlIHNhbWUKKy8vIHNpemUsIHRoaXMgd291bGQgaGF2ZSB0byBiZWNvbWUgbW9yZSBjb21wbGljYXRlZC4gIEZvciBleGFtcGxlLCBzaG9ydCwgaW50LAorLy8gYW5kIGxvbmcgY291bGQgYWxsIGJlIDMyLWJpdHMuICBFdmVuIG1vcmUgZGlhYm9saWNhbGx5LCBzaG9ydCwgaW50LCBsb25nLAorLy8gYW5kIGxvbmcgbG9uZyBjb3VsZCBhbGwgYmUgNjQgYml0cyBhbmQgc3RpbGwgYmUgc3RhbmRhcmQtY29tcGxpYW50LgorLy8gSG93ZXZlciwgZmV3IHBsYXRmb3JtcyBhcmUgdGhpcyBzdHJhbmdlLCBhbmQgaXQncyB1bmxpa2VseSB0aGF0IHVwYiB3aWxsIGJlCisvLyB1c2VkIG9uIHRoZSBzdHJhbmdlc3Qgb25lcy4KKworLy8gQ2FuJ3QgY291bnQgb24gc3RkaW50LmggbGltaXRzIGxpa2UgSU5UMzJfTUFYLCBiZWNhdXNlIGluIEMrKyB0aGVzZSBhcmUKKy8vIG9ubHkgZGVmaW5lZCB3aGVuIF9fU1REQ19MSU1JVF9NQUNST1MgYXJlIGRlZmluZWQgYmVmb3JlIHRoZSAqZmlyc3QqIGluY2x1ZGUKKy8vIG9mIHN0ZGludC5oLiAgV2UgY2FuJ3QgZ3VhcmFudGVlIHRoYXQgc29tZW9uZSBlbHNlIGRpZG4ndCBpbmNsdWRlIHRoZXNlIGZpcnN0CisvLyB3aXRob3V0IGRlZmluaW5nIF9fU1REQ19MSU1JVF9NQUNST1MuCisjZGVmaW5lIFVQQl9JTlQzMl9NQVggMHg3ZmZmZmZmZkxMCisjZGVmaW5lIFVQQl9JTlQzMl9NSU4gKC1VUEJfSU5UMzJfTUFYIC0gMSkKKyNkZWZpbmUgVVBCX0lOVDY0X01BWCAweDdmZmZmZmZmZmZmZmZmZmZMTAorI2RlZmluZSBVUEJfSU5UNjRfTUlOICgtVVBCX0lOVDY0X01BWCAtIDEpCisKKyNpZiBJTlRfTUFYID09IFVQQl9JTlQzMl9NQVggJiYgSU5UX01JTiA9PSBVUEJfSU5UMzJfTUlOCisjZGVmaW5lIFVQQl9JTlRfSVNfMzJCSVRTIDEKKyNlbmRpZgorCisjaWYgTE9OR19NQVggPT0gVVBCX0lOVDMyX01BWCAmJiBMT05HX01JTiA9PSBVUEJfSU5UMzJfTUlOCisjZGVmaW5lIFVQQl9MT05HX0lTXzMyQklUUyAxCisjZW5kaWYKKworI2lmIExPTkdfTUFYID09IFVQQl9JTlQ2NF9NQVggJiYgTE9OR19NSU4gPT0gVVBCX0lOVDY0X01JTgorI2RlZmluZSBVUEJfTE9OR19JU182NEJJVFMgMQorI2VuZGlmCisKKyNpZiBMTE9OR19NQVggPT0gVVBCX0lOVDY0X01BWCAmJiBMTE9OR19NSU4gPT0gVVBCX0lOVDY0X01JTgorI2RlZmluZSBVUEJfTExPTkdfSVNfNjRCSVRTIDEKKyNlbmRpZgorCisvLyBXZSB1c2UgbWFjcm9zIGluc3RlYWQgb2YgdHlwZWRlZnMgc28gd2UgY2FuIHVuZGVmaW5lIHRoZW0gbGF0ZXIgYW5kIGF2b2lkCisvLyBsZWFraW5nIHRoZW0gb3V0c2lkZSB0aGlzIGhlYWRlciBmaWxlLgorI2lmIFVQQl9JTlRfSVNfMzJCSVRTCisjZGVmaW5lIFVQQl9JTlQzMl9UIGludAorI2RlZmluZSBVUEJfVUlOVDMyX1QgdW5zaWduZWQgaW50CisKKyNpZiBVUEJfTE9OR19JU18zMkJJVFMKKyNkZWZpbmUgVVBCX1RXT18zMkJJVF9UWVBFUyAxCisjZGVmaW5lIFVQQl9JTlQzMkFMVF9UIGxvbmcKKyNkZWZpbmUgVVBCX1VJTlQzMkFMVF9UIHVuc2lnbmVkIGxvbmcKKyNlbmRpZiAgLy8gVVBCX0xPTkdfSVNfMzJCSVRTCisKKyNlbGlmIFVQQl9MT05HX0lTXzMyQklUUyAgLy8gJiYgIVVQQl9JTlRfSVNfMzJCSVRTCisjZGVmaW5lIFVQQl9JTlQzMl9UIGxvbmcKKyNkZWZpbmUgVVBCX1VJTlQzMl9UIHVuc2lnbmVkIGxvbmcKKyNlbmRpZiAgLy8gVVBCX0lOVF9JU18zMkJJVFMKKworCisjaWYgVVBCX0xPTkdfSVNfNjRCSVRTCisjZGVmaW5lIFVQQl9JTlQ2NF9UIGxvbmcKKyNkZWZpbmUgVVBCX1VJTlQ2NF9UIHVuc2lnbmVkIGxvbmcKKworI2lmIFVQQl9MTE9OR19JU182NEJJVFMKKyNkZWZpbmUgVVBCX1RXT182NEJJVF9UWVBFUyAxCisjZGVmaW5lIFVQQl9JTlQ2NEFMVF9UIGxvbmcgbG9uZworI2RlZmluZSBVUEJfVUlOVDY0QUxUX1QgdW5zaWduZWQgbG9uZyBsb25nCisjZW5kaWYgIC8vIFVQQl9MTE9OR19JU182NEJJVFMKKworI2VsaWYgVVBCX0xMT05HX0lTXzY0QklUUyAgLy8gJiYgIVVQQl9MT05HX0lTXzY0QklUUworI2RlZmluZSBVUEJfSU5UNjRfVCBsb25nIGxvbmcKKyNkZWZpbmUgVVBCX1VJTlQ2NF9UIHVuc2lnbmVkIGxvbmcgbG9uZworI2VuZGlmICAvLyBVUEJfTE9OR19JU182NEJJVFMKKworI3VuZGVmIFVQQl9JTlQzMl9NQVgKKyN1bmRlZiBVUEJfSU5UMzJfTUlOCisjdW5kZWYgVVBCX0lOVDY0X01BWAorI3VuZGVmIFVQQl9JTlQ2NF9NSU4KKyN1bmRlZiBVUEJfSU5UX0lTXzMyQklUUworI3VuZGVmIFVQQl9MT05HX0lTXzMyQklUUworI3VuZGVmIFVQQl9MT05HX0lTXzY0QklUUworI3VuZGVmIFVQQl9MTE9OR19JU182NEJJVFMKKworLy8gQyBpbmxpbmUgbWV0aG9kcy4KKworLy8gdXBiX2J1ZmhhbmRsZQorVVBCX0lOTElORSB2b2lkIHVwYl9idWZoYW5kbGVfaW5pdCh1cGJfYnVmaGFuZGxlICpoKSB7CisgIGgtPm9ial8gPSBOVUxMOworICBoLT5vYmp0eXBlXyA9IE5VTEw7CisgIGgtPmJ1Zl8gPSBOVUxMOworICBoLT5vYmpvZnNfID0gMDsKK30KK1VQQl9JTkxJTkUgdm9pZCB1cGJfYnVmaGFuZGxlX3VuaW5pdCh1cGJfYnVmaGFuZGxlICpoKSB7CisgIFVQQl9VTlVTRUQoaCk7Cit9CitVUEJfSU5MSU5FIHZvaWQgdXBiX2J1ZmhhbmRsZV9zZXRvYmoodXBiX2J1ZmhhbmRsZSAqaCwgY29uc3Qgdm9pZCAqb2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnR5cGUpIHsKKyAgaC0+b2JqXyA9IG9iajsKKyAgaC0+b2JqdHlwZV8gPSB0eXBlOworfQorVVBCX0lOTElORSB2b2lkIHVwYl9idWZoYW5kbGVfc2V0YnVmKHVwYl9idWZoYW5kbGUgKmgsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgb2ZzKSB7CisgIGgtPmJ1Zl8gPSBidWY7CisgIGgtPm9iam9mc18gPSBvZnM7Cit9CitVUEJfSU5MSU5FIGNvbnN0IHZvaWQgKnVwYl9idWZoYW5kbGVfb2JqKGNvbnN0IHVwYl9idWZoYW5kbGUgKmgpIHsKKyAgcmV0dXJuIGgtPm9ial87Cit9CitVUEJfSU5MSU5FIGNvbnN0IHZvaWQgKnVwYl9idWZoYW5kbGVfb2JqdHlwZShjb25zdCB1cGJfYnVmaGFuZGxlICpoKSB7CisgIHJldHVybiBoLT5vYmp0eXBlXzsKK30KK1VQQl9JTkxJTkUgY29uc3QgY2hhciAqdXBiX2J1ZmhhbmRsZV9idWYoY29uc3QgdXBiX2J1ZmhhbmRsZSAqaCkgeworICByZXR1cm4gaC0+YnVmXzsKK30KKworCisjaWZkZWYgX19jcGx1c3BsdXMKKworbmFtZXNwYWNlIHVwYiB7CisKK3R5cGVkZWYgdm9pZCBDbGVhbnVwRnVuYyh2b2lkICpwdHIpOworCisvLyBUZW1wbGF0ZSB0byByZW1vdmUgImNvbnN0IiBmcm9tICJjb25zdCBUKiIgYW5kIGp1c3QgcmV0dXJuICJUKiIuCisvLworLy8gV2UgZGVmaW5lIGEgbm9uc2Vuc2UgZGVmYXVsdCBiZWNhdXNlIG90aGVyd2lzZSBpdCB3aWxsIGZhaWwgdG8gaW5zdGFudGlhdGUgYXMKKy8vIGEgZnVuY3Rpb24gcGFyYW1ldGVyIHR5cGUgZXZlbiBpbiBjYXNlcyB3aGVyZSB3ZSBkb24ndCBleHBlY3QgYW55IGNhbGxlciB0bworLy8gYWN0dWFsbHkgbWF0Y2ggdGhlIG92ZXJsb2FkLgorY2xhc3MgQ291bGRudFJlbW92ZUNvbnN0IHt9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCByZW1vdmVfY29uc3RwdHIgeyB0eXBlZGVmIENvdWxkbnRSZW1vdmVDb25zdCB0eXBlOyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCByZW1vdmVfY29uc3RwdHI8Y29uc3QgVCAqPiB7IHR5cGVkZWYgVCAqdHlwZTsgfTsKKworLy8gVGVtcGxhdGUgdGhhdCB3ZSB1c2UgYmVsb3cgdG8gcmVtb3ZlIGEgdGVtcGxhdGUgc3BlY2lhbGl6YXRpb24gZnJvbQorLy8gY29uc2lkZXJhdGlvbiBpZiBpdCBtYXRjaGVzIGEgc3BlY2lmaWMgdHlwZS4KK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPiBzdHJ1Y3QgZGlzYWJsZV9pZl9zYW1lIHsgdHlwZWRlZiB2b2lkIFR5cGU7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGRpc2FibGVfaWZfc2FtZTxULCBUPiB7fTsKKwordGVtcGxhdGUgPGNsYXNzIFQ+IHZvaWQgRGVsZXRlUG9pbnRlcih2b2lkICpwKSB7IGRlbGV0ZSBzdGF0aWNfY2FzdDxUPihwKTsgfQorCit0ZW1wbGF0ZSA8Y2xhc3MgVDEsIGNsYXNzIFQyPgorc3RydWN0IEZpcnN0VW5sZXNzVm9pZCB7CisgIHR5cGVkZWYgVDEgdmFsdWU7Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgVDI+CitzdHJ1Y3QgRmlyc3RVbmxlc3NWb2lkPHZvaWQsIFQyPiB7CisgIHR5cGVkZWYgVDIgdmFsdWU7Cit9OworCit0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBVPgorc3RydWN0IGlzX3NhbWUgeworICBzdGF0aWMgYm9vbCB2YWx1ZTsKK307CisKK3RlbXBsYXRlPGNsYXNzIFQ+CitzdHJ1Y3QgaXNfc2FtZTxULCBUPiB7CisgIHN0YXRpYyBib29sIHZhbHVlOworfTsKKwordGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgVT4KK2Jvb2wgaXNfc2FtZTxULCBVPjo6dmFsdWUgPSBmYWxzZTsKKwordGVtcGxhdGU8Y2xhc3MgVD4KK2Jvb2wgaXNfc2FtZTxULCBUPjo6dmFsdWUgPSB0cnVlOworCisvLyBGdW5jSW5mbyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisvLyBJbmZvIGFib3V0IHRoZSB1c2VyJ3Mgb3JpZ2luYWwsIHByZS13cmFwcGVkIGZ1bmN0aW9uLgordGVtcGxhdGUgPGNsYXNzIEMsIGNsYXNzIFIgPSB2b2lkPgorc3RydWN0IEZ1bmNJbmZvIHsKKyAgLy8gVGhlIHR5cGUgb2YgdGhlIGNsb3N1cmUgdGhhdCB0aGUgZnVuY3Rpb24gdGFrZXMgKGl0cyBmaXJzdCBwYXJhbSkuCisgIHR5cGVkZWYgQyBDbG9zdXJlOworCisgIC8vIFRoZSByZXR1cm4gdHlwZS4KKyAgdHlwZWRlZiBSIFJldHVybjsKK307CisKKy8vIEZ1bmMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKy8vIEZ1bmMxLCBGdW5jMiwgRnVuYzM6IFRlbXBsYXRlIGNsYXNzZXMgcmVwcmVzZW50aW5nIGEgZnVuY3Rpb24gYW5kIGl0cworLy8gc2lnbmF0dXJlLgorLy8KKy8vIFNpbmNlIHRoZSBmdW5jdGlvbiBpcyBhIHRlbXBsYXRlIHBhcmFtZXRlciwgY2FsbGluZyB0aGUgZnVuY3Rpb24gY2FuIGJlCisvLyBpbmxpbmVkIGF0IGNvbXBpbGUtdGltZSBhbmQgZG9lcyBub3QgcmVxdWlyZSBhIGZ1bmN0aW9uIHBvaW50ZXIgYXQgcnVudGltZS4KKy8vIFRoZXNlIGZ1bmN0aW9ucyBhcmUgbm90IGJvdW5kIHRvIGEgaGFuZGxlciBkYXRhIHNvIGhhdmUgbm8gZGF0YSBvciBjbGVhbnVwCisvLyBoYW5kbGVyLgorc3RydWN0IFVuYm91bmRGdW5jIHsKKyAgQ2xlYW51cEZ1bmMgKkdldENsZWFudXAoKSB7IHJldHVybiBOVUxMOyB9CisgIHZvaWQgKkdldERhdGEoKSB7IHJldHVybiBOVUxMOyB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIFIgRihQMSksIGNsYXNzIEk+CitzdHJ1Y3QgRnVuYzEgOiBwdWJsaWMgVW5ib3VuZEZ1bmMgeworICB0eXBlZGVmIFIgUmV0dXJuOworICB0eXBlZGVmIEkgRnVuY0luZm87CisgIHN0YXRpYyBSIENhbGwoUDEgcDEpIHsgcmV0dXJuIEYocDEpOyB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBSIEYoUDEsIFAyKSwgY2xhc3MgST4KK3N0cnVjdCBGdW5jMiA6IHB1YmxpYyBVbmJvdW5kRnVuYyB7CisgIHR5cGVkZWYgUiBSZXR1cm47CisgIHR5cGVkZWYgSSBGdW5jSW5mbzsKKyAgc3RhdGljIFIgQ2FsbChQMSBwMSwgUDIgcDIpIHsgcmV0dXJuIEYocDEsIHAyKTsgfQorfTsKKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIFIgRihQMSwgUDIsIFAzKSwgY2xhc3MgST4KK3N0cnVjdCBGdW5jMyA6IHB1YmxpYyBVbmJvdW5kRnVuYyB7CisgIHR5cGVkZWYgUiBSZXR1cm47CisgIHR5cGVkZWYgSSBGdW5jSW5mbzsKKyAgc3RhdGljIFIgQ2FsbChQMSBwMSwgUDIgcDIsIFAzIHAzKSB7IHJldHVybiBGKHAxLCBwMiwgcDMpOyB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgY2xhc3MgUDQsIFIgRihQMSwgUDIsIFAzLCBQNCksCisgICAgICAgICAgY2xhc3MgST4KK3N0cnVjdCBGdW5jNCA6IHB1YmxpYyBVbmJvdW5kRnVuYyB7CisgIHR5cGVkZWYgUiBSZXR1cm47CisgIHR5cGVkZWYgSSBGdW5jSW5mbzsKKyAgc3RhdGljIFIgQ2FsbChQMSBwMSwgUDIgcDIsIFAzIHAzLCBQNCBwNCkgeyByZXR1cm4gRihwMSwgcDIsIHAzLCBwNCk7IH0KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQNCwgY2xhc3MgUDUsCisgICAgICAgICAgUiBGKFAxLCBQMiwgUDMsIFA0LCBQNSksIGNsYXNzIEk+CitzdHJ1Y3QgRnVuYzUgOiBwdWJsaWMgVW5ib3VuZEZ1bmMgeworICB0eXBlZGVmIFIgUmV0dXJuOworICB0eXBlZGVmIEkgRnVuY0luZm87CisgIHN0YXRpYyBSIENhbGwoUDEgcDEsIFAyIHAyLCBQMyBwMywgUDQgcDQsIFA1IHA1KSB7CisgICAgcmV0dXJuIEYocDEsIHAyLCBwMywgcDQsIHA1KTsKKyAgfQorfTsKKworLy8gQm91bmRGdW5jIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworLy8gQm91bmRGdW5jMiwgQm91bmRGdW5jMzogTGlrZSBGdW5jMi9GdW5jMyBleGNlcHQgYWxzbyBjb250YWlucyBhIHZhbHVlIHRoYXQKKy8vIHNoYWxsIGJlIGJvdW5kIHRvIHRoZSBmdW5jdGlvbidzIHNlY29uZCBwYXJhbWV0ZXIuCisvLworLy8gTm90ZSB0aGF0IHRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIGEgY29uc3QgcG9pbnRlciwgYnV0IG91ciBzdG9yZWQgYm91bmQgdmFsdWUKKy8vIGlzIG5vbi1jb25zdCBzbyB3ZSBjYW4gZnJlZSBpdCB3aGVuIHRoZSBoYW5kbGVycyBhcmUgZGVzdHJveWVkLgordGVtcGxhdGUgPGNsYXNzIFQ+CitzdHJ1Y3QgQm91bmRGdW5jIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSByZW1vdmVfY29uc3RwdHI8VD46OnR5cGUgTXV0YWJsZVAyOworICBleHBsaWNpdCBCb3VuZEZ1bmMoTXV0YWJsZVAyIGRhdGFfKSA6IGRhdGEoZGF0YV8pIHt9CisgIENsZWFudXBGdW5jICpHZXRDbGVhbnVwKCkgeyByZXR1cm4gJkRlbGV0ZVBvaW50ZXI8TXV0YWJsZVAyPjsgfQorICBNdXRhYmxlUDIgR2V0RGF0YSgpIHsgcmV0dXJuIGRhdGE7IH0KKyAgTXV0YWJsZVAyIGRhdGE7Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBSIEYoUDEsIFAyKSwgY2xhc3MgST4KK3N0cnVjdCBCb3VuZEZ1bmMyIDogcHVibGljIEJvdW5kRnVuYzxQMj4geworICB0eXBlZGVmIEJvdW5kRnVuYzxQMj4gQmFzZTsKKyAgdHlwZWRlZiBJIEZ1bmNJbmZvOworICBleHBsaWNpdCBCb3VuZEZ1bmMyKHR5cGVuYW1lIEJhc2U6Ok11dGFibGVQMiBhcmcpIDogQmFzZShhcmcpIHt9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgUiBGKFAxLCBQMiwgUDMpLCBjbGFzcyBJPgorc3RydWN0IEJvdW5kRnVuYzMgOiBwdWJsaWMgQm91bmRGdW5jPFAyPiB7CisgIHR5cGVkZWYgQm91bmRGdW5jPFAyPiBCYXNlOworICB0eXBlZGVmIEkgRnVuY0luZm87CisgIGV4cGxpY2l0IEJvdW5kRnVuYzModHlwZW5hbWUgQmFzZTo6TXV0YWJsZVAyIGFyZykgOiBCYXNlKGFyZykge30KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQNCwgUiBGKFAxLCBQMiwgUDMsIFA0KSwKKyAgICAgICAgICBjbGFzcyBJPgorc3RydWN0IEJvdW5kRnVuYzQgOiBwdWJsaWMgQm91bmRGdW5jPFAyPiB7CisgIHR5cGVkZWYgQm91bmRGdW5jPFAyPiBCYXNlOworICB0eXBlZGVmIEkgRnVuY0luZm87CisgIGV4cGxpY2l0IEJvdW5kRnVuYzQodHlwZW5hbWUgQmFzZTo6TXV0YWJsZVAyIGFyZykgOiBCYXNlKGFyZykge30KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQNCwgY2xhc3MgUDUsCisgICAgICAgICAgUiBGKFAxLCBQMiwgUDMsIFA0LCBQNSksIGNsYXNzIEk+CitzdHJ1Y3QgQm91bmRGdW5jNSA6IHB1YmxpYyBCb3VuZEZ1bmM8UDI+IHsKKyAgdHlwZWRlZiBCb3VuZEZ1bmM8UDI+IEJhc2U7CisgIHR5cGVkZWYgSSBGdW5jSW5mbzsKKyAgZXhwbGljaXQgQm91bmRGdW5jNSh0eXBlbmFtZSBCYXNlOjpNdXRhYmxlUDIgYXJnKSA6IEJhc2UoYXJnKSB7fQorfTsKKworLy8gRnVuY1NpZyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworLy8gRnVuY1NpZzEsIEZ1bmNTaWcyLCBGdW5jU2lnMzogdGVtcGxhdGUgY2xhc3NlcyByZWZsZWN0aW5nIGEgZnVuY3Rpb24KKy8vICpzaWduYXR1cmUqLCBidXQgd2l0aG91dCBhIHNwZWNpZmljIGZ1bmN0aW9uIGF0dGFjaGVkLgorLy8KKy8vIFRoZXNlIGNsYXNzZXMgY29udGFpbiBtZW1iZXIgZnVuY3Rpb25zIHRoYXQgY2FuIGJlIGludm9rZWQgd2l0aCBhCisvLyBzcGVjaWZpYyBmdW5jdGlvbiB0byByZXR1cm4gYSBGdW5jL0JvdW5kRnVuYyBjbGFzcy4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMT4KK3N0cnVjdCBGdW5jU2lnMSB7CisgIHRlbXBsYXRlIDxSIEYoUDEpPgorICBGdW5jMTxSLCBQMSwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzE8UiwgUDEsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+KCk7CisgIH0KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDI+CitzdHJ1Y3QgRnVuY1NpZzIgeworICB0ZW1wbGF0ZSA8UiBGKFAxLCBQMik+CisgIEZ1bmMyPFIsIFAxLCBQMiwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzI8UiwgUDEsIFAyLCBGLCBGdW5jSW5mbzxQMSwgUj4gPigpOworICB9CisKKyAgdGVtcGxhdGUgPFIgRihQMSwgUDIpPgorICBCb3VuZEZ1bmMyPFIsIFAxLCBQMiwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygKKyAgICAgIHR5cGVuYW1lIHJlbW92ZV9jb25zdHB0cjxQMj46OnR5cGUgcGFyYW0yKSB7CisgICAgcmV0dXJuIEJvdW5kRnVuYzI8UiwgUDEsIFAyLCBGLCBGdW5jSW5mbzxQMSwgUj4gPihwYXJhbTIpOworICB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMz4KK3N0cnVjdCBGdW5jU2lnMyB7CisgIHRlbXBsYXRlIDxSIEYoUDEsIFAyLCBQMyk+CisgIEZ1bmMzPFIsIFAxLCBQMiwgUDMsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+IEdldEZ1bmMoKSB7CisgICAgcmV0dXJuIEZ1bmMzPFIsIFAxLCBQMiwgUDMsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+KCk7CisgIH0KKworICB0ZW1wbGF0ZSA8UiBGKFAxLCBQMiwgUDMpPgorICBCb3VuZEZ1bmMzPFIsIFAxLCBQMiwgUDMsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+IEdldEZ1bmMoCisgICAgICB0eXBlbmFtZSByZW1vdmVfY29uc3RwdHI8UDI+Ojp0eXBlIHBhcmFtMikgeworICAgIHJldHVybiBCb3VuZEZ1bmMzPFIsIFAxLCBQMiwgUDMsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+KHBhcmFtMik7CisgIH0KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQND4KK3N0cnVjdCBGdW5jU2lnNCB7CisgIHRlbXBsYXRlIDxSIEYoUDEsIFAyLCBQMywgUDQpPgorICBGdW5jNDxSLCBQMSwgUDIsIFAzLCBQNCwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzQ8UiwgUDEsIFAyLCBQMywgUDQsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+KCk7CisgIH0KKworICB0ZW1wbGF0ZSA8UiBGKFAxLCBQMiwgUDMsIFA0KT4KKyAgQm91bmRGdW5jNDxSLCBQMSwgUDIsIFAzLCBQNCwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygKKyAgICAgIHR5cGVuYW1lIHJlbW92ZV9jb25zdHB0cjxQMj46OnR5cGUgcGFyYW0yKSB7CisgICAgcmV0dXJuIEJvdW5kRnVuYzQ8UiwgUDEsIFAyLCBQMywgUDQsIEYsIEZ1bmNJbmZvPFAxLCBSPiA+KHBhcmFtMik7CisgIH0KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQNCwgY2xhc3MgUDU+CitzdHJ1Y3QgRnVuY1NpZzUgeworICB0ZW1wbGF0ZSA8UiBGKFAxLCBQMiwgUDMsIFA0LCBQNSk+CisgIEZ1bmM1PFIsIFAxLCBQMiwgUDMsIFA0LCBQNSwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzU8UiwgUDEsIFAyLCBQMywgUDQsIFA1LCBGLCBGdW5jSW5mbzxQMSwgUj4gPigpOworICB9CisKKyAgdGVtcGxhdGUgPFIgRihQMSwgUDIsIFAzLCBQNCwgUDUpPgorICBCb3VuZEZ1bmM1PFIsIFAxLCBQMiwgUDMsIFA0LCBQNSwgRiwgRnVuY0luZm88UDEsIFI+ID4gR2V0RnVuYygKKyAgICAgIHR5cGVuYW1lIHJlbW92ZV9jb25zdHB0cjxQMj46OnR5cGUgcGFyYW0yKSB7CisgICAgcmV0dXJuIEJvdW5kRnVuYzU8UiwgUDEsIFAyLCBQMywgUDQsIFA1LCBGLCBGdW5jSW5mbzxQMSwgUj4gPihwYXJhbTIpOworICB9Cit9OworCisvLyBPdmVybG9hZGVkIHRlbXBsYXRlIGZ1bmN0aW9uIHRoYXQgY2FuIGNvbnN0cnVjdCB0aGUgYXBwcm9wcmlhdGUgRnVuY1NpZyoKKy8vIGNsYXNzIGdpdmVuIGEgZnVuY3Rpb24gcG9pbnRlciBieSBkZWR1Y2luZyB0aGUgdGVtcGxhdGUgcGFyYW1ldGVycy4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMT4KK2lubGluZSBGdW5jU2lnMTxSLCBQMT4gTWF0Y2hGdW5jKFIgKCpmKShQMSkpIHsKKyAgVVBCX1VOVVNFRChmKTsgIC8vIE9ubHkgdXNlZCBmb3IgdGVtcGxhdGUgcGFyYW1ldGVyIGRlZHVjdGlvbi4KKyAgcmV0dXJuIEZ1bmNTaWcxPFIsIFAxPigpOworfQorCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyPgoraW5saW5lIEZ1bmNTaWcyPFIsIFAxLCBQMj4gTWF0Y2hGdW5jKFIgKCpmKShQMSwgUDIpKSB7CisgIFVQQl9VTlVTRUQoZik7ICAvLyBPbmx5IHVzZWQgZm9yIHRlbXBsYXRlIHBhcmFtZXRlciBkZWR1Y3Rpb24uCisgIHJldHVybiBGdW5jU2lnMjxSLCBQMSwgUDI+KCk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzPgoraW5saW5lIEZ1bmNTaWczPFIsIFAxLCBQMiwgUDM+IE1hdGNoRnVuYyhSICgqZikoUDEsIFAyLCBQMykpIHsKKyAgVVBCX1VOVVNFRChmKTsgIC8vIE9ubHkgdXNlZCBmb3IgdGVtcGxhdGUgcGFyYW1ldGVyIGRlZHVjdGlvbi4KKyAgcmV0dXJuIEZ1bmNTaWczPFIsIFAxLCBQMiwgUDM+KCk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQND4KK2lubGluZSBGdW5jU2lnNDxSLCBQMSwgUDIsIFAzLCBQND4gTWF0Y2hGdW5jKFIgKCpmKShQMSwgUDIsIFAzLCBQNCkpIHsKKyAgVVBCX1VOVVNFRChmKTsgIC8vIE9ubHkgdXNlZCBmb3IgdGVtcGxhdGUgcGFyYW1ldGVyIGRlZHVjdGlvbi4KKyAgcmV0dXJuIEZ1bmNTaWc0PFIsIFAxLCBQMiwgUDMsIFA0PigpOworfQorCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgY2xhc3MgUDQsIGNsYXNzIFA1PgoraW5saW5lIEZ1bmNTaWc1PFIsIFAxLCBQMiwgUDMsIFA0LCBQNT4gTWF0Y2hGdW5jKFIgKCpmKShQMSwgUDIsIFAzLCBQNCwgUDUpKSB7CisgIFVQQl9VTlVTRUQoZik7ICAvLyBPbmx5IHVzZWQgZm9yIHRlbXBsYXRlIHBhcmFtZXRlciBkZWR1Y3Rpb24uCisgIHJldHVybiBGdW5jU2lnNTxSLCBQMSwgUDIsIFAzLCBQNCwgUDU+KCk7Cit9CisKKy8vIE1ldGhvZFNpZyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKy8vIENhbGxNZXRob2QqOiBhIGZ1bmN0aW9uIHRlbXBsYXRlIHRoYXQgY2FsbHMgYSBnaXZlbiBtZXRob2QuCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgQywgUiAoQzo6KkYpKCk+CitSIENhbGxNZXRob2QwKEMgKm9iaikgeworICByZXR1cm4gKCgqb2JqKS4qRikoKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxLCBSIChDOjoqRikoUDEpPgorUiBDYWxsTWV0aG9kMShDICpvYmosIFAxIGFyZzEpIHsKKyAgcmV0dXJuICgoKm9iaikuKkYpKGFyZzEpOworfQorCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgQywgY2xhc3MgUDEsIGNsYXNzIFAyLCBSIChDOjoqRikoUDEsIFAyKT4KK1IgQ2FsbE1ldGhvZDIoQyAqb2JqLCBQMSBhcmcxLCBQMiBhcmcyKSB7CisgIHJldHVybiAoKCpvYmopLipGKShhcmcxLCBhcmcyKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIFIgKEM6OipGKShQMSwgUDIsIFAzKT4KK1IgQ2FsbE1ldGhvZDMoQyAqb2JqLCBQMSBhcmcxLCBQMiBhcmcyLCBQMyBhcmczKSB7CisgIHJldHVybiAoKCpvYmopLipGKShhcmcxLCBhcmcyLCBhcmczKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIGNsYXNzIFA0LAorICAgICAgICAgIFIgKEM6OipGKShQMSwgUDIsIFAzLCBQNCk+CitSIENhbGxNZXRob2Q0KEMgKm9iaiwgUDEgYXJnMSwgUDIgYXJnMiwgUDMgYXJnMywgUDQgYXJnNCkgeworICByZXR1cm4gKCgqb2JqKS4qRikoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCk7Cit9CisKKy8vIE1ldGhvZFNpZzogbGlrZSBGdW5jU2lnLCBidXQgZm9yIG1lbWJlciBmdW5jdGlvbnMuCisvLworLy8gR2V0RnVuYygpIHJldHVybnMgYSBub3JtYWwgRnVuY04gb2JqZWN0LCBzbyBhZnRlciBjYWxsaW5nIEdldEZ1bmMoKSBubworLy8gbW9yZSBsb2dpYyBpcyByZXF1aXJlZCB0byBzcGVjaWFsLWNhc2UgbWV0aG9kcy4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBDPgorc3RydWN0IE1ldGhvZFNpZzAgeworICB0ZW1wbGF0ZSA8UiAoQzo6KkYpKCk+CisgIEZ1bmMxPFIsIEMgKiwgQ2FsbE1ldGhvZDA8UiwgQywgRj4sIEZ1bmNJbmZvPEMgKiwgUj4gPiBHZXRGdW5jKCkgeworICAgIHJldHVybiBGdW5jMTxSLCBDICosIENhbGxNZXRob2QwPFIsIEMsIEY+LCBGdW5jSW5mbzxDICosIFI+ID4oKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxPgorc3RydWN0IE1ldGhvZFNpZzEgeworICB0ZW1wbGF0ZSA8UiAoQzo6KkYpKFAxKT4KKyAgRnVuYzI8UiwgQyAqLCBQMSwgQ2FsbE1ldGhvZDE8UiwgQywgUDEsIEY+LCBGdW5jSW5mbzxDICosIFI+ID4gR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzI8UiwgQyAqLCBQMSwgQ2FsbE1ldGhvZDE8UiwgQywgUDEsIEY+LCBGdW5jSW5mbzxDICosIFI+ID4oKTsKKyAgfQorCisgIHRlbXBsYXRlIDxSIChDOjoqRikoUDEpPgorICBCb3VuZEZ1bmMyPFIsIEMgKiwgUDEsIENhbGxNZXRob2QxPFIsIEMsIFAxLCBGPiwgRnVuY0luZm88QyAqLCBSPiA+IEdldEZ1bmMoCisgICAgICB0eXBlbmFtZSByZW1vdmVfY29uc3RwdHI8UDE+Ojp0eXBlIHBhcmFtMSkgeworICAgIHJldHVybiBCb3VuZEZ1bmMyPFIsIEMgKiwgUDEsIENhbGxNZXRob2QxPFIsIEMsIFAxLCBGPiwgRnVuY0luZm88QyAqLCBSPiA+KAorICAgICAgICBwYXJhbTEpOworICB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgQywgY2xhc3MgUDEsIGNsYXNzIFAyPgorc3RydWN0IE1ldGhvZFNpZzIgeworICB0ZW1wbGF0ZSA8UiAoQzo6KkYpKFAxLCBQMik+CisgIEZ1bmMzPFIsIEMgKiwgUDEsIFAyLCBDYWxsTWV0aG9kMjxSLCBDLCBQMSwgUDIsIEY+LCBGdW5jSW5mbzxDICosIFI+ID4KKyAgR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzM8UiwgQyAqLCBQMSwgUDIsIENhbGxNZXRob2QyPFIsIEMsIFAxLCBQMiwgRj4sCisgICAgICAgICAgICAgICAgIEZ1bmNJbmZvPEMgKiwgUj4gPigpOworICB9CisKKyAgdGVtcGxhdGUgPFIgKEM6OipGKShQMSwgUDIpPgorICBCb3VuZEZ1bmMzPFIsIEMgKiwgUDEsIFAyLCBDYWxsTWV0aG9kMjxSLCBDLCBQMSwgUDIsIEY+LCBGdW5jSW5mbzxDICosIFI+ID4KKyAgR2V0RnVuYyh0eXBlbmFtZSByZW1vdmVfY29uc3RwdHI8UDE+Ojp0eXBlIHBhcmFtMSkgeworICAgIHJldHVybiBCb3VuZEZ1bmMzPFIsIEMgKiwgUDEsIFAyLCBDYWxsTWV0aG9kMjxSLCBDLCBQMSwgUDIsIEY+LAorICAgICAgICAgICAgICAgICAgICAgIEZ1bmNJbmZvPEMgKiwgUj4gPihwYXJhbTEpOworICB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgQywgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMz4KK3N0cnVjdCBNZXRob2RTaWczIHsKKyAgdGVtcGxhdGUgPFIgKEM6OipGKShQMSwgUDIsIFAzKT4KKyAgRnVuYzQ8UiwgQyAqLCBQMSwgUDIsIFAzLCBDYWxsTWV0aG9kMzxSLCBDLCBQMSwgUDIsIFAzLCBGPiwgRnVuY0luZm88QyAqLCBSPiA+CisgIEdldEZ1bmMoKSB7CisgICAgcmV0dXJuIEZ1bmM0PFIsIEMgKiwgUDEsIFAyLCBQMywgQ2FsbE1ldGhvZDM8UiwgQywgUDEsIFAyLCBQMywgRj4sCisgICAgICAgICAgICAgICAgIEZ1bmNJbmZvPEMgKiwgUj4gPigpOworICB9CisKKyAgdGVtcGxhdGUgPFIgKEM6OipGKShQMSwgUDIsIFAzKT4KKyAgQm91bmRGdW5jNDxSLCBDICosIFAxLCBQMiwgUDMsIENhbGxNZXRob2QzPFIsIEMsIFAxLCBQMiwgUDMsIEY+LAorICAgICAgICAgICAgIEZ1bmNJbmZvPEMgKiwgUj4gPgorICBHZXRGdW5jKHR5cGVuYW1lIHJlbW92ZV9jb25zdHB0cjxQMT46OnR5cGUgcGFyYW0xKSB7CisgICAgcmV0dXJuIEJvdW5kRnVuYzQ8UiwgQyAqLCBQMSwgUDIsIFAzLCBDYWxsTWV0aG9kMzxSLCBDLCBQMSwgUDIsIFAzLCBGPiwKKyAgICAgICAgICAgICAgICAgICAgICBGdW5jSW5mbzxDICosIFI+ID4ocGFyYW0xKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIGNsYXNzIFA0Pgorc3RydWN0IE1ldGhvZFNpZzQgeworICB0ZW1wbGF0ZSA8UiAoQzo6KkYpKFAxLCBQMiwgUDMsIFA0KT4KKyAgRnVuYzU8UiwgQyAqLCBQMSwgUDIsIFAzLCBQNCwgQ2FsbE1ldGhvZDQ8UiwgQywgUDEsIFAyLCBQMywgUDQsIEY+LAorICAgICAgICBGdW5jSW5mbzxDICosIFI+ID4KKyAgR2V0RnVuYygpIHsKKyAgICByZXR1cm4gRnVuYzU8UiwgQyAqLCBQMSwgUDIsIFAzLCBQNCwgQ2FsbE1ldGhvZDQ8UiwgQywgUDEsIFAyLCBQMywgUDQsIEY+LAorICAgICAgICAgICAgICAgICBGdW5jSW5mbzxDICosIFI+ID4oKTsKKyAgfQorCisgIHRlbXBsYXRlIDxSIChDOjoqRikoUDEsIFAyLCBQMywgUDQpPgorICBCb3VuZEZ1bmM1PFIsIEMgKiwgUDEsIFAyLCBQMywgUDQsIENhbGxNZXRob2Q0PFIsIEMsIFAxLCBQMiwgUDMsIFA0LCBGPiwKKyAgICAgICAgICAgICBGdW5jSW5mbzxDICosIFI+ID4KKyAgR2V0RnVuYyh0eXBlbmFtZSByZW1vdmVfY29uc3RwdHI8UDE+Ojp0eXBlIHBhcmFtMSkgeworICAgIHJldHVybiBCb3VuZEZ1bmM1PFIsIEMgKiwgUDEsIFAyLCBQMywgUDQsCisgICAgICAgICAgICAgICAgICAgICAgQ2FsbE1ldGhvZDQ8UiwgQywgUDEsIFAyLCBQMywgUDQsIEY+LCBGdW5jSW5mbzxDICosIFI+ID4oCisgICAgICAgIHBhcmFtMSk7CisgIH0KK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBDPgoraW5saW5lIE1ldGhvZFNpZzA8UiwgQz4gTWF0Y2hGdW5jKFIgKEM6OipmKSgpKSB7CisgIFVQQl9VTlVTRUQoZik7ICAvLyBPbmx5IHVzZWQgZm9yIHRlbXBsYXRlIHBhcmFtZXRlciBkZWR1Y3Rpb24uCisgIHJldHVybiBNZXRob2RTaWcwPFIsIEM+KCk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBDLCBjbGFzcyBQMT4KK2lubGluZSBNZXRob2RTaWcxPFIsIEMsIFAxPiBNYXRjaEZ1bmMoUiAoQzo6KmYpKFAxKSkgeworICBVUEJfVU5VU0VEKGYpOyAgLy8gT25seSB1c2VkIGZvciB0ZW1wbGF0ZSBwYXJhbWV0ZXIgZGVkdWN0aW9uLgorICByZXR1cm4gTWV0aG9kU2lnMTxSLCBDLCBQMT4oKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxLCBjbGFzcyBQMj4KK2lubGluZSBNZXRob2RTaWcyPFIsIEMsIFAxLCBQMj4gTWF0Y2hGdW5jKFIgKEM6OipmKShQMSwgUDIpKSB7CisgIFVQQl9VTlVTRUQoZik7ICAvLyBPbmx5IHVzZWQgZm9yIHRlbXBsYXRlIHBhcmFtZXRlciBkZWR1Y3Rpb24uCisgIHJldHVybiBNZXRob2RTaWcyPFIsIEMsIFAxLCBQMj4oKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIEMsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDM+CitpbmxpbmUgTWV0aG9kU2lnMzxSLCBDLCBQMSwgUDIsIFAzPiBNYXRjaEZ1bmMoUiAoQzo6KmYpKFAxLCBQMiwgUDMpKSB7CisgIFVQQl9VTlVTRUQoZik7ICAvLyBPbmx5IHVzZWQgZm9yIHRlbXBsYXRlIHBhcmFtZXRlciBkZWR1Y3Rpb24uCisgIHJldHVybiBNZXRob2RTaWczPFIsIEMsIFAxLCBQMiwgUDM+KCk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBDLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQND4KK2lubGluZSBNZXRob2RTaWc0PFIsIEMsIFAxLCBQMiwgUDMsIFA0PiBNYXRjaEZ1bmMoUiAoQzo6KmYpKFAxLCBQMiwgUDMsIFA0KSkgeworICBVUEJfVU5VU0VEKGYpOyAgLy8gT25seSB1c2VkIGZvciB0ZW1wbGF0ZSBwYXJhbWV0ZXIgZGVkdWN0aW9uLgorICByZXR1cm4gTWV0aG9kU2lnNDxSLCBDLCBQMSwgUDIsIFAzLCBQND4oKTsKK30KKworLy8gTWF5YmVXcmFwUmV0dXJuIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworLy8gVGVtcGxhdGUgY2xhc3MgdGhhdCBhdHRlbXB0cyB0byB3cmFwIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHNvIGl0CisvLyBtYXRjaGVzIHRoZSBleHBlY3RlZCB0eXBlLiAgVGhlcmUgYXJlIHR3byBtYWluIGFkanVzdG1lbnRzIGl0IG1heSBtYWtlOgorLy8KKy8vICAgMS4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdm9pZCwgbWFrZSBpdCByZXR1cm4gdGhlIGV4cGVjdGVkIHR5cGUgYW5kIHdpdGgKKy8vICAgICAgYSB2YWx1ZSB0aGF0IGFsd2F5cyBpbmRpY2F0ZXMgc3VjY2Vzcy4KKy8vICAgMi4gSWYgdGhlIGZ1bmN0aW9uIGlzIGV4cGVjdGVkIHRvIHJldHVybiB2b2lkKiBidXQgZG9lc24ndCwgd3JhcCBpdCBzbyBpdAorLy8gICAgICBkb2VzIChlaXRoZXIgYnkgcmV0dXJuaW5nIHRoZSBjbG9zdXJlIHBhcmFtIGlmIHRoZSB3cmFwcGVkIGZ1bmN0aW9uCisvLyAgICAgIHJldHVybnMgdm9pZCBvciBieSBjYXN0aW5nIGEgZGlmZmVyZW50IHBvaW50ZXIgdHlwZSB0byB2b2lkKiBmb3IKKy8vICAgICAgcmV0dXJuKS4KKworLy8gVGVtcGxhdGUgcGFyYW1ldGVycyBhcmUgRnVuY04gdHlwZSBhbmQgZGVzaXJlZCByZXR1cm4gdHlwZS4KK3RlbXBsYXRlIDxjbGFzcyBGLCBjbGFzcyBSLCBjbGFzcyBFbmFibGUgPSB2b2lkPgorc3RydWN0IE1heWJlV3JhcFJldHVybjsKKworLy8gSWYgdGhlIHJldHVybiB0eXBlIG1hdGNoZXMsIHJldHVybiB0aGUgZ2l2ZW4gZnVuY3Rpb24gdW53cmFwcGVkLgordGVtcGxhdGUgPGNsYXNzIEY+CitzdHJ1Y3QgTWF5YmVXcmFwUmV0dXJuPEYsIHR5cGVuYW1lIEY6OlJldHVybj4geworICB0eXBlZGVmIEYgRnVuYzsKK307CisKKy8vIEZ1bmN0aW9uIHdyYXBwZXIgdGhhdCBtdW5nZXMgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHZvaWQgdG8gKGJvb2wpdHJ1ZS4KK3RlbXBsYXRlIDxjbGFzcyBQMSwgY2xhc3MgUDIsIHZvaWQgRihQMSwgUDIpPgorYm9vbCBSZXR1cm5UcnVlMihQMSBwMSwgUDIgcDIpIHsKKyAgRihwMSwgcDIpOworICByZXR1cm4gdHJ1ZTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIHZvaWQgRihQMSwgUDIsIFAzKT4KK2Jvb2wgUmV0dXJuVHJ1ZTMoUDEgcDEsIFAyIHAyLCBQMyBwMykgeworICBGKHAxLCBwMiwgcDMpOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gRnVuY3Rpb24gd3JhcHBlciB0aGF0IG11bmdlcyB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdm9pZCB0byAodm9pZCopYXJnMQordGVtcGxhdGUgPGNsYXNzIFAxLCBjbGFzcyBQMiwgdm9pZCBGKFAxLCBQMik+Cit2b2lkICpSZXR1cm5DbG9zdXJlMihQMSBwMSwgUDIgcDIpIHsKKyAgRihwMSwgcDIpOworICByZXR1cm4gcDE7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCB2b2lkIEYoUDEsIFAyLCBQMyk+Cit2b2lkICpSZXR1cm5DbG9zdXJlMyhQMSBwMSwgUDIgcDIsIFAzIHAzKSB7CisgIEYocDEsIHAyLCBwMyk7CisgIHJldHVybiBwMTsKK30KKworLy8gRnVuY3Rpb24gd3JhcHBlciB0aGF0IG11bmdlcyB0aGUgcmV0dXJuIHZhbHVlIGZyb20gUiB0byB2b2lkKi4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIFIgRihQMSwgUDIpPgordm9pZCAqQ2FzdFJldHVyblRvVm9pZFB0cjIoUDEgcDEsIFAyIHAyKSB7CisgIHJldHVybiBGKHAxLCBwMik7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBSIEYoUDEsIFAyLCBQMyk+Cit2b2lkICpDYXN0UmV0dXJuVG9Wb2lkUHRyMyhQMSBwMSwgUDIgcDIsIFAzIHAzKSB7CisgIHJldHVybiBGKHAxLCBwMiwgcDMpOworfQorCisvLyBGdW5jdGlvbiB3cmFwcGVyIHRoYXQgbXVuZ2VzIHRoZSByZXR1cm4gdmFsdWUgZnJvbSBib29sIHRvIHZvaWQqLgordGVtcGxhdGUgPGNsYXNzIFAxLCBjbGFzcyBQMiwgYm9vbCBGKFAxLCBQMik+Cit2b2lkICpSZXR1cm5DbG9zdXJlT3JCcmVhazIoUDEgcDEsIFAyIHAyKSB7CisgIHJldHVybiBGKHAxLCBwMikgPyBwMSA6IFVQQl9CUkVBSzsKK30KKwordGVtcGxhdGUgPGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIGJvb2wgRihQMSwgUDIsIFAzKT4KK3ZvaWQgKlJldHVybkNsb3N1cmVPckJyZWFrMyhQMSBwMSwgUDIgcDIsIFAzIHAzKSB7CisgIHJldHVybiBGKHAxLCBwMiwgcDMpID8gcDEgOiBVUEJfQlJFQUs7Cit9CisKKy8vIEZvciB0aGUgc3RyaW5nIGNhbGxiYWNrLCB3aGljaCB0YWtlcyBmaXZlIHBhcmFtcywgcmV0dXJucyB0aGUgc2l6ZSBwYXJhbS4KK3RlbXBsYXRlIDxjbGFzcyBQMSwgY2xhc3MgUDIsCisgICAgICAgICAgdm9pZCBGKFAxLCBQMiwgY29uc3QgY2hhciAqLCBzaXplX3QsIGNvbnN0IEJ1ZmZlckhhbmRsZSAqKT4KK3NpemVfdCBSZXR1cm5TdHJpbmdMZW4oUDEgcDEsIFAyIHAyLCBjb25zdCBjaGFyICpwMywgc2l6ZV90IHA0LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBCdWZmZXJIYW5kbGUgKnA1KSB7CisgIEYocDEsIHAyLCBwMywgcDQsIHA1KTsKKyAgcmV0dXJuIHA0OworfQorCisvLyBGb3IgdGhlIHN0cmluZyBjYWxsYmFjaywgd2hpY2ggdGFrZXMgZml2ZSBwYXJhbXMsIHJldHVybnMgdGhlIHNpemUgcGFyYW0gb3IKKy8vIHplcm8uCit0ZW1wbGF0ZSA8Y2xhc3MgUDEsIGNsYXNzIFAyLAorICAgICAgICAgIGJvb2wgRihQMSwgUDIsIGNvbnN0IGNoYXIgKiwgc2l6ZV90LCBjb25zdCBCdWZmZXJIYW5kbGUgKik+CitzaXplX3QgUmV0dXJuTk9yMChQMSBwMSwgUDIgcDIsIGNvbnN0IGNoYXIgKnAzLCBzaXplX3QgcDQsCisgICAgICAgICAgICAgICAgICBjb25zdCBCdWZmZXJIYW5kbGUgKnA1KSB7CisgIHJldHVybiBGKHAxLCBwMiwgcDMsIHA0LCBwNSkgPyBwNCA6IDA7Cit9CisKKy8vIElmIHdlIGhhdmUgYSBmdW5jdGlvbiByZXR1cm5pbmcgdm9pZCBidXQgd2FudCBhIGZ1bmN0aW9uIHJldHVybmluZyBib29sLCB3cmFwCisvLyBpdCBpbiBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0cnVlLgordGVtcGxhdGUgPGNsYXNzIFAxLCBjbGFzcyBQMiwgdm9pZCBGKFAxLCBQMiksIGNsYXNzIEk+CitzdHJ1Y3QgTWF5YmVXcmFwUmV0dXJuPEZ1bmMyPHZvaWQsIFAxLCBQMiwgRiwgST4sIGJvb2w+IHsKKyAgdHlwZWRlZiBGdW5jMjxib29sLCBQMSwgUDIsIFJldHVyblRydWUyPFAxLCBQMiwgRj4sIEk+IEZ1bmM7Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgdm9pZCBGKFAxLCBQMiwgUDMpLCBjbGFzcyBJPgorc3RydWN0IE1heWJlV3JhcFJldHVybjxGdW5jMzx2b2lkLCBQMSwgUDIsIFAzLCBGLCBJPiwgYm9vbD4geworICB0eXBlZGVmIEZ1bmMzPGJvb2wsIFAxLCBQMiwgUDMsIFJldHVyblRydWUzPFAxLCBQMiwgUDMsIEY+LCBJPiBGdW5jOworfTsKKworLy8gSWYgb3VyIGZ1bmN0aW9uIHJldHVybnMgdm9pZCBidXQgd2Ugd2FudCBvbmUgcmV0dXJuaW5nIHZvaWQqLCB3cmFwIGl0IGluIGEKKy8vIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQuCit0ZW1wbGF0ZSA8Y2xhc3MgUDEsIGNsYXNzIFAyLCB2b2lkIEYoUDEsIFAyKSwgY2xhc3MgST4KK3N0cnVjdCBNYXliZVdyYXBSZXR1cm48RnVuYzI8dm9pZCwgUDEsIFAyLCBGLCBJPiwgdm9pZCAqPiB7CisgIHR5cGVkZWYgRnVuYzI8dm9pZCAqLCBQMSwgUDIsIFJldHVybkNsb3N1cmUyPFAxLCBQMiwgRj4sIEk+IEZ1bmM7Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgdm9pZCBGKFAxLCBQMiwgUDMpLCBjbGFzcyBJPgorc3RydWN0IE1heWJlV3JhcFJldHVybjxGdW5jMzx2b2lkLCBQMSwgUDIsIFAzLCBGLCBJPiwgdm9pZCAqPiB7CisgIHR5cGVkZWYgRnVuYzM8dm9pZCAqLCBQMSwgUDIsIFAzLCBSZXR1cm5DbG9zdXJlMzxQMSwgUDIsIFAzLCBGPiwgST4gRnVuYzsKK307CisKKy8vIElmIG91ciBmdW5jdGlvbiByZXR1cm5zIFIqIGJ1dCB3ZSB3YW50IG9uZSByZXR1cm5pbmcgdm9pZCosIHdyYXAgaXQgaW4gYQorLy8gZnVuY3Rpb24gdGhhdCBjYXN0cyB0byB2b2lkKi4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIFIgKkYoUDEsIFAyKSwgY2xhc3MgST4KK3N0cnVjdCBNYXliZVdyYXBSZXR1cm48RnVuYzI8UiAqLCBQMSwgUDIsIEYsIEk+LCB2b2lkICosCisgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIGRpc2FibGVfaWZfc2FtZTxSICosIHZvaWQgKj46OlR5cGU+IHsKKyAgdHlwZWRlZiBGdW5jMjx2b2lkICosIFAxLCBQMiwgQ2FzdFJldHVyblRvVm9pZFB0cjI8UiAqLCBQMSwgUDIsIEY+LCBJPiBGdW5jOworfTsKKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIFIgKkYoUDEsIFAyLCBQMyksIGNsYXNzIEk+CitzdHJ1Y3QgTWF5YmVXcmFwUmV0dXJuPEZ1bmMzPFIgKiwgUDEsIFAyLCBQMywgRiwgST4sIHZvaWQgKiwKKyAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgZGlzYWJsZV9pZl9zYW1lPFIgKiwgdm9pZCAqPjo6VHlwZT4geworICB0eXBlZGVmIEZ1bmMzPHZvaWQgKiwgUDEsIFAyLCBQMywgQ2FzdFJldHVyblRvVm9pZFB0cjM8UiAqLCBQMSwgUDIsIFAzLCBGPiwgST4KKyAgICAgIEZ1bmM7Cit9OworCisvLyBJZiBvdXIgZnVuY3Rpb24gcmV0dXJucyBib29sIGJ1dCB3ZSB3YW50IG9uZSByZXR1cm5pbmcgdm9pZCosIHdyYXAgaXQgaW4gYQorLy8gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGVpdGhlciB0aGUgZmlyc3QgcGFyYW0gb3IgVVBCX0JSRUFLLgordGVtcGxhdGUgPGNsYXNzIFAxLCBjbGFzcyBQMiwgYm9vbCBGKFAxLCBQMiksIGNsYXNzIEk+CitzdHJ1Y3QgTWF5YmVXcmFwUmV0dXJuPEZ1bmMyPGJvb2wsIFAxLCBQMiwgRiwgST4sIHZvaWQgKj4geworICB0eXBlZGVmIEZ1bmMyPHZvaWQgKiwgUDEsIFAyLCBSZXR1cm5DbG9zdXJlT3JCcmVhazI8UDEsIFAyLCBGPiwgST4gRnVuYzsKK307CisKK3RlbXBsYXRlIDxjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBib29sIEYoUDEsIFAyLCBQMyksIGNsYXNzIEk+CitzdHJ1Y3QgTWF5YmVXcmFwUmV0dXJuPEZ1bmMzPGJvb2wsIFAxLCBQMiwgUDMsIEYsIEk+LCB2b2lkICo+IHsKKyAgdHlwZWRlZiBGdW5jMzx2b2lkICosIFAxLCBQMiwgUDMsIFJldHVybkNsb3N1cmVPckJyZWFrMzxQMSwgUDIsIFAzLCBGPiwgST4KKyAgICAgIEZ1bmM7Cit9OworCisvLyBJZiBvdXIgZnVuY3Rpb24gcmV0dXJucyB2b2lkIGJ1dCB3ZSB3YW50IG9uZSByZXR1cm5pbmcgc2l6ZV90LCB3cmFwIGl0IGluIGEKKy8vIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgc2l6ZSBhcmd1bWVudC4KK3RlbXBsYXRlIDxjbGFzcyBQMSwgY2xhc3MgUDIsCisgICAgICAgICAgdm9pZCBGKFAxLCBQMiwgY29uc3QgY2hhciAqLCBzaXplX3QsIGNvbnN0IEJ1ZmZlckhhbmRsZSAqKSwgY2xhc3MgST4KK3N0cnVjdCBNYXliZVdyYXBSZXR1cm48CisgICAgRnVuYzU8dm9pZCwgUDEsIFAyLCBjb25zdCBjaGFyICosIHNpemVfdCwgY29uc3QgQnVmZmVySGFuZGxlICosIEYsIEk+LAorICAgICAgICAgIHNpemVfdD4geworICB0eXBlZGVmIEZ1bmM1PHNpemVfdCwgUDEsIFAyLCBjb25zdCBjaGFyICosIHNpemVfdCwgY29uc3QgQnVmZmVySGFuZGxlICosCisgICAgICAgICAgICAgICAgUmV0dXJuU3RyaW5nTGVuPFAxLCBQMiwgRj4sIEk+IEZ1bmM7Cit9OworCisvLyBJZiBvdXIgZnVuY3Rpb24gcmV0dXJucyBib29sIGJ1dCB3ZSB3YW50IG9uZSByZXR1cm5pbmcgc2l6ZV90LCB3cmFwIGl0IGluIGEKKy8vIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBlaXRoZXIgMCBvciB0aGUgYnVmIHNpemUuCit0ZW1wbGF0ZSA8Y2xhc3MgUDEsIGNsYXNzIFAyLAorICAgICAgICAgIGJvb2wgRihQMSwgUDIsIGNvbnN0IGNoYXIgKiwgc2l6ZV90LCBjb25zdCBCdWZmZXJIYW5kbGUgKiksIGNsYXNzIEk+CitzdHJ1Y3QgTWF5YmVXcmFwUmV0dXJuPAorICAgIEZ1bmM1PGJvb2wsIFAxLCBQMiwgY29uc3QgY2hhciAqLCBzaXplX3QsIGNvbnN0IEJ1ZmZlckhhbmRsZSAqLCBGLCBJPiwKKyAgICBzaXplX3Q+IHsKKyAgdHlwZWRlZiBGdW5jNTxzaXplX3QsIFAxLCBQMiwgY29uc3QgY2hhciAqLCBzaXplX3QsIGNvbnN0IEJ1ZmZlckhhbmRsZSAqLAorICAgICAgICAgICAgICAgIFJldHVybk5PcjA8UDEsIFAyLCBGPiwgST4gRnVuYzsKK307CisKKy8vIENvbnZlcnRQYXJhbXMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKy8vIFRlbXBsYXRlIGNsYXNzIHRoYXQgY29udmVydHMgdGhlIGZ1bmN0aW9uIHBhcmFtZXRlcnMgaWYgbmVjZXNzYXJ5LCBhbmQKKy8vIGlnbm9yZXMgdGhlIEhhbmRsZXJEYXRhIHBhcmFtZXRlciBpZiBhcHByb3ByaWF0ZS4KKy8vCisvLyBUZW1wbGF0ZSBwYXJhbWV0ZXIgaXMgdGhlIGFyZSBGdW5jTiBmdW5jdGlvbiB0eXBlLgordGVtcGxhdGUgPGNsYXNzIEYsIGNsYXNzIFQ+CitzdHJ1Y3QgQ29udmVydFBhcmFtczsKKworLy8gRnVuY3Rpb24gdGhhdCBkaXNjYXJkcyB0aGUgaGFuZGxlciBkYXRhIHBhcmFtZXRlci4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgUiBGKFAxKT4KK1IgSWdub3JlSGFuZGxlckRhdGEyKHZvaWQgKnAxLCBjb25zdCB2b2lkICpoZCkgeworICBVUEJfVU5VU0VEKGhkKTsKKyAgcmV0dXJuIEYoc3RhdGljX2Nhc3Q8UDE+KHAxKSk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDJXcmFwcGVyLCBjbGFzcyBQMldyYXBwZWQsCisgICAgICAgICAgUiBGKFAxLCBQMldyYXBwZWQpPgorUiBJZ25vcmVIYW5kbGVyRGF0YTModm9pZCAqcDEsIGNvbnN0IHZvaWQgKmhkLCBQMldyYXBwZXIgcDIpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHJldHVybiBGKHN0YXRpY19jYXN0PFAxPihwMSksIHAyKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIFIgRihQMSwgUDIsIFAzKT4KK1IgSWdub3JlSGFuZGxlckRhdGE0KHZvaWQgKnAxLCBjb25zdCB2b2lkICpoZCwgUDIgcDIsIFAzIHAzKSB7CisgIFVQQl9VTlVTRUQoaGQpOworICByZXR1cm4gRihzdGF0aWNfY2FzdDxQMT4ocDEpLCBwMiwgcDMpOworfQorCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgY2xhc3MgUDQsIFIgRihQMSwgUDIsIFAzLCBQNCk+CitSIElnbm9yZUhhbmRsZXJEYXRhNSh2b2lkICpwMSwgY29uc3Qgdm9pZCAqaGQsIFAyIHAyLCBQMyBwMywgUDQgcDQpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIHJldHVybiBGKHN0YXRpY19jYXN0PFAxPihwMSksIHAyLCBwMywgcDQpOworfQorCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIFIgRihQMSwgY29uc3QgY2hhciosIHNpemVfdCk+CitSIElnbm9yZUhhbmRsZXJEYXRhSWdub3JlSGFuZGxlKHZvaWQgKnAxLCBjb25zdCB2b2lkICpoZCwgY29uc3QgY2hhciAqcDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBwMywgY29uc3QgQnVmZmVySGFuZGxlICpoYW5kbGUpIHsKKyAgVVBCX1VOVVNFRChoZCk7CisgIFVQQl9VTlVTRUQoaGFuZGxlKTsKKyAgcmV0dXJuIEYoc3RhdGljX2Nhc3Q8UDE+KHAxKSwgcDIsIHAzKTsKK30KKworLy8gRnVuY3Rpb24gdGhhdCBjYXN0cyB0aGUgaGFuZGxlciBkYXRhIHBhcmFtZXRlci4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIFIgRihQMSwgUDIpPgorUiBDYXN0SGFuZGxlckRhdGEyKHZvaWQgKmMsIGNvbnN0IHZvaWQgKmhkKSB7CisgIHJldHVybiBGKHN0YXRpY19jYXN0PFAxPihjKSwgc3RhdGljX2Nhc3Q8UDI+KGhkKSk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzV3JhcHBlciwgY2xhc3MgUDNXcmFwcGVkLAorICAgICAgICAgIFIgRihQMSwgUDIsIFAzV3JhcHBlZCk+CitSIENhc3RIYW5kbGVyRGF0YTModm9pZCAqYywgY29uc3Qgdm9pZCAqaGQsIFAzV3JhcHBlciBwMykgeworICByZXR1cm4gRihzdGF0aWNfY2FzdDxQMT4oYyksIHN0YXRpY19jYXN0PFAyPihoZCksIHAzKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIGNsYXNzIFA0LCBjbGFzcyBQNSwKKyAgICAgICAgICBSIEYoUDEsIFAyLCBQMywgUDQsIFA1KT4KK1IgQ2FzdEhhbmRsZXJEYXRhNSh2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgUDMgcDMsIFA0IHA0LCBQNSBwNSkgeworICByZXR1cm4gRihzdGF0aWNfY2FzdDxQMT4oYyksIHN0YXRpY19jYXN0PFAyPihoZCksIHAzLCBwNCwgcDUpOworfQorCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBSIEYoUDEsIFAyLCBjb25zdCBjaGFyICosIHNpemVfdCk+CitSIENhc3RIYW5kbGVyRGF0YUlnbm9yZUhhbmRsZSh2b2lkICpjLCBjb25zdCB2b2lkICpoZCwgY29uc3QgY2hhciAqcDMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcDQsIGNvbnN0IEJ1ZmZlckhhbmRsZSAqaGFuZGxlKSB7CisgIFVQQl9VTlVTRUQoaGFuZGxlKTsKKyAgcmV0dXJuIEYoc3RhdGljX2Nhc3Q8UDE+KGMpLCBzdGF0aWNfY2FzdDxQMj4oaGQpLCBwMywgcDQpOworfQorCisvLyBGb3IgdW5ib3VuZCBmdW5jdGlvbnMsIGlnbm9yZSB0aGUgaGFuZGxlciBkYXRhLgordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIFAxLCBSIEYoUDEpLCBjbGFzcyBJLCBjbGFzcyBUPgorc3RydWN0IENvbnZlcnRQYXJhbXM8RnVuYzE8UiwgUDEsIEYsIEk+LCBUPiB7CisgIHR5cGVkZWYgRnVuYzI8Uiwgdm9pZCAqLCBjb25zdCB2b2lkICosIElnbm9yZUhhbmRsZXJEYXRhMjxSLCBQMSwgRj4sIEk+IEZ1bmM7Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBSIEYoUDEsIFAyKSwgY2xhc3MgSSwKKyAgICAgICAgICBjbGFzcyBSMiwgY2xhc3MgUDFfMiwgY2xhc3MgUDJfMiwgY2xhc3MgUDNfMj4KK3N0cnVjdCBDb252ZXJ0UGFyYW1zPEZ1bmMyPFIsIFAxLCBQMiwgRiwgST4sCisgICAgICAgICAgICAgICAgICAgICBSMiAoKikoUDFfMiwgUDJfMiwgUDNfMik+IHsKKyAgdHlwZWRlZiBGdW5jMzxSLCB2b2lkICosIGNvbnN0IHZvaWQgKiwgUDNfMiwKKyAgICAgICAgICAgICAgICBJZ25vcmVIYW5kbGVyRGF0YTM8UiwgUDEsIFAzXzIsIFAyLCBGPiwgST4gRnVuYzsKK307CisKKy8vIEZvciBTdHJpbmdCdWZmZXIgb25seTsgdGhpcyBpZ25vcmVzIGJvdGggdGhlIGhhbmRsZXIgZGF0YSBhbmQgdGhlCisvLyBCdWZmZXJIYW5kbGUuCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIFIgRihQMSwgY29uc3QgY2hhciAqLCBzaXplX3QpLCBjbGFzcyBJLCBjbGFzcyBUPgorc3RydWN0IENvbnZlcnRQYXJhbXM8RnVuYzM8UiwgUDEsIGNvbnN0IGNoYXIgKiwgc2l6ZV90LCBGLCBJPiwgVD4geworICB0eXBlZGVmIEZ1bmM1PFIsIHZvaWQgKiwgY29uc3Qgdm9pZCAqLCBjb25zdCBjaGFyICosIHNpemVfdCwKKyAgICAgICAgICAgICAgICBjb25zdCBCdWZmZXJIYW5kbGUgKiwgSWdub3JlSGFuZGxlckRhdGFJZ25vcmVIYW5kbGU8UiwgUDEsIEY+LAorICAgICAgICAgICAgICAgIEk+IEZ1bmM7Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgY2xhc3MgUDQsIFIgRihQMSwgUDIsIFAzLCBQNCksCisgICAgICAgICAgY2xhc3MgSSwgY2xhc3MgVD4KK3N0cnVjdCBDb252ZXJ0UGFyYW1zPEZ1bmM0PFIsIFAxLCBQMiwgUDMsIFA0LCBGLCBJPiwgVD4geworICB0eXBlZGVmIEZ1bmM1PFIsIHZvaWQgKiwgY29uc3Qgdm9pZCAqLCBQMiwgUDMsIFA0LAorICAgICAgICAgICAgICAgIElnbm9yZUhhbmRsZXJEYXRhNTxSLCBQMSwgUDIsIFAzLCBQNCwgRj4sIEk+IEZ1bmM7Cit9OworCisvLyBGb3IgYm91bmQgZnVuY3Rpb25zLCBjYXN0IHRoZSBoYW5kbGVyIGRhdGEuCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBSIEYoUDEsIFAyKSwgY2xhc3MgSSwgY2xhc3MgVD4KK3N0cnVjdCBDb252ZXJ0UGFyYW1zPEJvdW5kRnVuYzI8UiwgUDEsIFAyLCBGLCBJPiwgVD4geworICB0eXBlZGVmIEZ1bmMyPFIsIHZvaWQgKiwgY29uc3Qgdm9pZCAqLCBDYXN0SGFuZGxlckRhdGEyPFIsIFAxLCBQMiwgRj4sIEk+CisgICAgICBGdW5jOworfTsKKwordGVtcGxhdGUgPGNsYXNzIFIsIGNsYXNzIFAxLCBjbGFzcyBQMiwgY2xhc3MgUDMsIFIgRihQMSwgUDIsIFAzKSwgY2xhc3MgSSwKKyAgICAgICAgICBjbGFzcyBSMiwgY2xhc3MgUDFfMiwgY2xhc3MgUDJfMiwgY2xhc3MgUDNfMj4KK3N0cnVjdCBDb252ZXJ0UGFyYW1zPEJvdW5kRnVuYzM8UiwgUDEsIFAyLCBQMywgRiwgST4sCisgICAgICAgICAgICAgICAgICAgICBSMiAoKikoUDFfMiwgUDJfMiwgUDNfMik+IHsKKyAgdHlwZWRlZiBGdW5jMzxSLCB2b2lkICosIGNvbnN0IHZvaWQgKiwgUDNfMiwKKyAgICAgICAgICAgICAgICBDYXN0SGFuZGxlckRhdGEzPFIsIFAxLCBQMiwgUDNfMiwgUDMsIEY+LCBJPiBGdW5jOworfTsKKworLy8gRm9yIFN0cmluZ0J1ZmZlciBvbmx5OyB0aGlzIGlnbm9yZXMgdGhlIEJ1ZmZlckhhbmRsZS4KK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIFIgRihQMSwgUDIsIGNvbnN0IGNoYXIgKiwgc2l6ZV90KSwKKyAgICAgICAgICBjbGFzcyBJLCBjbGFzcyBUPgorc3RydWN0IENvbnZlcnRQYXJhbXM8Qm91bmRGdW5jNDxSLCBQMSwgUDIsIGNvbnN0IGNoYXIgKiwgc2l6ZV90LCBGLCBJPiwgVD4geworICB0eXBlZGVmIEZ1bmM1PFIsIHZvaWQgKiwgY29uc3Qgdm9pZCAqLCBjb25zdCBjaGFyICosIHNpemVfdCwKKyAgICAgICAgICAgICAgICBjb25zdCBCdWZmZXJIYW5kbGUgKiwgQ2FzdEhhbmRsZXJEYXRhSWdub3JlSGFuZGxlPFIsIFAxLCBQMiwgRj4sCisgICAgICAgICAgICAgICAgST4gRnVuYzsKK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzLCBjbGFzcyBQNCwgY2xhc3MgUDUsCisgICAgICAgICAgUiBGKFAxLCBQMiwgUDMsIFA0LCBQNSksIGNsYXNzIEksIGNsYXNzIFQ+CitzdHJ1Y3QgQ29udmVydFBhcmFtczxCb3VuZEZ1bmM1PFIsIFAxLCBQMiwgUDMsIFA0LCBQNSwgRiwgST4sIFQ+IHsKKyAgdHlwZWRlZiBGdW5jNTxSLCB2b2lkICosIGNvbnN0IHZvaWQgKiwgUDMsIFA0LCBQNSwKKyAgICAgICAgICAgICAgICBDYXN0SGFuZGxlckRhdGE1PFIsIFAxLCBQMiwgUDMsIFA0LCBQNSwgRj4sIEk+IEZ1bmM7Cit9OworCisvLyB1dHlwZS9sdHlwZSBhcmUgdXBwZXIvbG93ZXItY2FzZSwgY3R5cGUgaXMgY2Fub25pY2FsIEMgdHlwZSwgdnR5cGUgaXMKKy8vIHZhcmlhbnQgQyB0eXBlLgorI2RlZmluZSBUWVBFX01FVEhPRFModXR5cGUsIGx0eXBlLCBjdHlwZSwgdnR5cGUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPD4gc3RydWN0IENhbm9uaWNhbFR5cGU8dnR5cGU+IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdHlwZWRlZiBjdHlwZSBUeXBlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBib29sIEhhbmRsZXJzOjpTZXRWYWx1ZUhhbmRsZXI8dnR5cGU+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgRmllbGREZWYgKmYsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IEhhbmRsZXJzOjp1dHlwZSAjIyBIYW5kbGVyJiBoYW5kbGVyKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgYXNzZXJ0KCFoYW5kbGVyLnJlZ2lzdGVyZWRfKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGhhbmRsZXIuQWRkQ2xlYW51cCh0aGlzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBoYW5kbGVyLnJlZ2lzdGVyZWRfID0gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHVwYl9oYW5kbGVyc19zZXQjI2x0eXBlKHRoaXMsIGYsIGhhbmRsZXIuaGFuZGxlcl8sICZoYW5kbGVyLmF0dHJfKTsgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKworVFlQRV9NRVRIT0RTKERvdWJsZSwgZG91YmxlLCBkb3VibGUsICAgZG91YmxlKTsKK1RZUEVfTUVUSE9EUyhGbG9hdCwgIGZsb2F0LCAgZmxvYXQsICAgIGZsb2F0KTsKK1RZUEVfTUVUSE9EUyhVSW50NjQsIHVpbnQ2NCwgdWludDY0X3QsIFVQQl9VSU5UNjRfVCk7CitUWVBFX01FVEhPRFMoVUludDMyLCB1aW50MzIsIHVpbnQzMl90LCBVUEJfVUlOVDMyX1QpOworVFlQRV9NRVRIT0RTKEludDY0LCAgaW50NjQsICBpbnQ2NF90LCAgVVBCX0lOVDY0X1QpOworVFlQRV9NRVRIT0RTKEludDMyLCAgaW50MzIsICBpbnQzMl90LCAgVVBCX0lOVDMyX1QpOworVFlQRV9NRVRIT0RTKEJvb2wsICAgYm9vbCwgICBib29sLCAgICAgYm9vbCk7CisKKyNpZmRlZiBVUEJfVFdPXzMyQklUX1RZUEVTCitUWVBFX01FVEhPRFMoSW50MzIsICBpbnQzMiwgIGludDMyX3QsICBVUEJfSU5UMzJBTFRfVCk7CitUWVBFX01FVEhPRFMoVUludDMyLCB1aW50MzIsIHVpbnQzMl90LCBVUEJfVUlOVDMyQUxUX1QpOworI2VuZGlmCisKKyNpZmRlZiBVUEJfVFdPXzY0QklUX1RZUEVTCitUWVBFX01FVEhPRFMoSW50NjQsICBpbnQ2NCwgIGludDY0X3QsICBVUEJfSU5UNjRBTFRfVCk7CitUWVBFX01FVEhPRFMoVUludDY0LCB1aW50NjQsIHVpbnQ2NF90LCBVUEJfVUlOVDY0QUxUX1QpOworI2VuZGlmCisjdW5kZWYgVFlQRV9NRVRIT0RTCisKK3RlbXBsYXRlIDw+IHN0cnVjdCBDYW5vbmljYWxUeXBlPFN0YXR1cyo+IHsKKyAgdHlwZWRlZiBTdGF0dXMqIFR5cGU7Cit9OworCisvLyBUeXBlIG1ldGhvZHMgdGhhdCBhcmUgb25seSBvbmUtcGVyLWNhbm9uaWNhbC10eXBlIGFuZCBub3Qgb25lLXBlci1jdmFyaWFudC4KKworI2RlZmluZSBUWVBFX01FVEhPRFModXR5cGUsIGN0eXBlKSBcCisgICAgaW5saW5lIGJvb2wgSGFuZGxlcnM6OlNldCMjdXR5cGUjI0hhbmRsZXIoY29uc3QgRmllbGREZWYgKmYsIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1dHlwZSMjSGFuZGxlciAmaCkgeyBcCisgICAgICByZXR1cm4gU2V0VmFsdWVIYW5kbGVyPGN0eXBlPihmLCBoKTsgXAorICAgIH0gXAorCitUWVBFX01FVEhPRFMoRG91YmxlLCBkb3VibGUpOworVFlQRV9NRVRIT0RTKEZsb2F0LCAgZmxvYXQpOworVFlQRV9NRVRIT0RTKFVJbnQ2NCwgdWludDY0X3QpOworVFlQRV9NRVRIT0RTKFVJbnQzMiwgdWludDMyX3QpOworVFlQRV9NRVRIT0RTKEludDY0LCAgaW50NjRfdCk7CitUWVBFX01FVEhPRFMoSW50MzIsICBpbnQzMl90KTsKK1RZUEVfTUVUSE9EUyhCb29sLCAgIGJvb2wpOworI3VuZGVmIFRZUEVfTUVUSE9EUworCit0ZW1wbGF0ZSA8Y2xhc3MgRj4gc3RydWN0IFJldHVybk9mOworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyPgorc3RydWN0IFJldHVybk9mPFIgKCopKFAxLCBQMik+IHsKKyAgdHlwZWRlZiBSIFJldHVybjsKK307CisKK3RlbXBsYXRlIDxjbGFzcyBSLCBjbGFzcyBQMSwgY2xhc3MgUDIsIGNsYXNzIFAzPgorc3RydWN0IFJldHVybk9mPFIgKCopKFAxLCBQMiwgUDMpPiB7CisgIHR5cGVkZWYgUiBSZXR1cm47Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgY2xhc3MgUDQ+CitzdHJ1Y3QgUmV0dXJuT2Y8UiAoKikoUDEsIFAyLCBQMywgUDQpPiB7CisgIHR5cGVkZWYgUiBSZXR1cm47Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgUiwgY2xhc3MgUDEsIGNsYXNzIFAyLCBjbGFzcyBQMywgY2xhc3MgUDQsIGNsYXNzIFA1Pgorc3RydWN0IFJldHVybk9mPFIgKCopKFAxLCBQMiwgUDMsIFA0LCBQNSk+IHsKKyAgdHlwZWRlZiBSIFJldHVybjsKK307CisKK3RlbXBsYXRlPGNsYXNzIFQ+IGNvbnN0IHZvaWQgKlVuaXF1ZVB0ckZvclR5cGUoKSB7CisgIHN0YXRpYyBjb25zdCBjaGFyIGNoID0gMDsKKyAgcmV0dXJuICZjaDsKK30KKwordGVtcGxhdGUgPGNsYXNzIFQ+Cit0ZW1wbGF0ZSA8Y2xhc3MgRj4KK2lubGluZSBIYW5kbGVyPFQ+OjpIYW5kbGVyKEYgZnVuYykKKyAgICA6IHJlZ2lzdGVyZWRfKGZhbHNlKSwKKyAgICAgIGNsZWFudXBfZGF0YV8oZnVuYy5HZXREYXRhKCkpLAorICAgICAgY2xlYW51cF9mdW5jXyhmdW5jLkdldENsZWFudXAoKSkgeworICB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEoJmF0dHJfLCBmdW5jLkdldERhdGEoKSk7CisgIHR5cGVkZWYgdHlwZW5hbWUgUmV0dXJuT2Y8VD46OlJldHVybiBSZXR1cm47CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29udmVydFBhcmFtczxGLCBUPjo6RnVuYyBDb252ZXJ0ZWRQYXJhbXNGdW5jOworICB0eXBlZGVmIHR5cGVuYW1lIE1heWJlV3JhcFJldHVybjxDb252ZXJ0ZWRQYXJhbXNGdW5jLCBSZXR1cm4+OjpGdW5jCisgICAgICBSZXR1cm5XcmFwcGVkRnVuYzsKKyAgaGFuZGxlcl8gPSBSZXR1cm5XcmFwcGVkRnVuYygpLkNhbGw7CisKKyAgLy8gU2V0IGF0dHJpYnV0ZXMgYmFzZWQgb24gd2hhdCB0ZW1wbGF0ZXMgY2FuIHN0YXRpY2FsbHkgdGVsbCB1cyBhYm91dCB0aGUKKyAgLy8gdXNlcidzIGZ1bmN0aW9uLgorCisgIC8vIElmIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiByZXR1cm5zIHZvaWQsIHRoZW4gd2Uga25vdyB0aGF0IHdlIHdyYXBwZWQgaXQgdG8KKyAgLy8gYWx3YXlzIHJldHVybiBvay4KKyAgYm9vbCBhbHdheXNfb2sgPSBpc19zYW1lPHR5cGVuYW1lIEY6OkZ1bmNJbmZvOjpSZXR1cm4sIHZvaWQ+Ojp2YWx1ZTsKKyAgYXR0cl8uU2V0QWx3YXlzT2soYWx3YXlzX29rKTsKKworICAvLyBDbG9zdXJlIHBhcmFtZXRlciBhbmQgcmV0dXJuIHR5cGUuCisgIGF0dHJfLlNldENsb3N1cmVUeXBlKFVuaXF1ZVB0ckZvclR5cGU8dHlwZW5hbWUgRjo6RnVuY0luZm86OkNsb3N1cmU+KCkpOworCisgIC8vIFdlIHVzZSB0aGUgY2xvc3VyZSB0eXBlIChmcm9tIHRoZSBmaXJzdCBwYXJhbWV0ZXIpIGlmIHRoZSByZXR1cm4gdHlwZSBpcworICAvLyB2b2lkLiAgVGhpcyBpcyBhbGwgbm9uc2Vuc2UgZm9yIG5vbiBTVEFSVCogaGFuZGxlcnMsIGJ1dCBpdCBkb2Vzbid0IG1hdHRlcgorICAvLyBiZWNhdXNlIGluIHRoYXQgY2FzZSB0aGUgdmFsdWUgd2lsbCBiZSBpZ25vcmVkLgorICB0eXBlZGVmIHR5cGVuYW1lIEZpcnN0VW5sZXNzVm9pZDx0eXBlbmFtZSBGOjpGdW5jSW5mbzo6UmV0dXJuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBGOjpGdW5jSW5mbzo6Q2xvc3VyZT46OnZhbHVlCisgICAgICBFZmZlY3RpdmVSZXR1cm47CisgIGF0dHJfLlNldFJldHVybkNsb3N1cmVUeXBlKFVuaXF1ZVB0ckZvclR5cGU8RWZmZWN0aXZlUmV0dXJuPigpKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFQ+CitpbmxpbmUgSGFuZGxlcjxUPjo6fkhhbmRsZXIoKSB7CisgIGFzc2VydChyZWdpc3RlcmVkXyk7Cit9CisKK2lubGluZSBIYW5kbGVyQXR0cmlidXRlczo6SGFuZGxlckF0dHJpYnV0ZXMoKSB7IHVwYl9oYW5kbGVyYXR0cl9pbml0KHRoaXMpOyB9CitpbmxpbmUgSGFuZGxlckF0dHJpYnV0ZXM6On5IYW5kbGVyQXR0cmlidXRlcygpIHsgdXBiX2hhbmRsZXJhdHRyX3VuaW5pdCh0aGlzKTsgfQoraW5saW5lIGJvb2wgSGFuZGxlckF0dHJpYnV0ZXM6OlNldEhhbmRsZXJEYXRhKGNvbnN0IHZvaWQgKmhkKSB7CisgIHJldHVybiB1cGJfaGFuZGxlcmF0dHJfc2V0aGFuZGxlcmRhdGEodGhpcywgaGQpOworfQoraW5saW5lIGNvbnN0IHZvaWQqIEhhbmRsZXJBdHRyaWJ1dGVzOjpoYW5kbGVyX2RhdGEoKSBjb25zdCB7CisgIHJldHVybiB1cGJfaGFuZGxlcmF0dHJfaGFuZGxlcmRhdGEodGhpcyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyQXR0cmlidXRlczo6U2V0Q2xvc3VyZVR5cGUoY29uc3Qgdm9pZCAqdHlwZSkgeworICByZXR1cm4gdXBiX2hhbmRsZXJhdHRyX3NldGNsb3N1cmV0eXBlKHRoaXMsIHR5cGUpOworfQoraW5saW5lIGNvbnN0IHZvaWQqIEhhbmRsZXJBdHRyaWJ1dGVzOjpjbG9zdXJlX3R5cGUoKSBjb25zdCB7CisgIHJldHVybiB1cGJfaGFuZGxlcmF0dHJfY2xvc3VyZXR5cGUodGhpcyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyQXR0cmlidXRlczo6U2V0UmV0dXJuQ2xvc3VyZVR5cGUoY29uc3Qgdm9pZCAqdHlwZSkgeworICByZXR1cm4gdXBiX2hhbmRsZXJhdHRyX3NldHJldHVybmNsb3N1cmV0eXBlKHRoaXMsIHR5cGUpOworfQoraW5saW5lIGNvbnN0IHZvaWQqIEhhbmRsZXJBdHRyaWJ1dGVzOjpyZXR1cm5fY2xvc3VyZV90eXBlKCkgY29uc3QgeworICByZXR1cm4gdXBiX2hhbmRsZXJhdHRyX3JldHVybmNsb3N1cmV0eXBlKHRoaXMpOworfQoraW5saW5lIGJvb2wgSGFuZGxlckF0dHJpYnV0ZXM6OlNldEFsd2F5c09rKGJvb2wgYWx3YXlzX29rKSB7CisgIHJldHVybiB1cGJfaGFuZGxlcmF0dHJfc2V0YWx3YXlzb2sodGhpcywgYWx3YXlzX29rKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJBdHRyaWJ1dGVzOjphbHdheXNfb2soKSBjb25zdCB7CisgIHJldHVybiB1cGJfaGFuZGxlcmF0dHJfYWx3YXlzb2sodGhpcyk7Cit9CisKK2lubGluZSBCdWZmZXJIYW5kbGU6OkJ1ZmZlckhhbmRsZSgpIHsgdXBiX2J1ZmhhbmRsZV9pbml0KHRoaXMpOyB9CitpbmxpbmUgQnVmZmVySGFuZGxlOjp+QnVmZmVySGFuZGxlKCkgeyB1cGJfYnVmaGFuZGxlX3VuaW5pdCh0aGlzKTsgfQoraW5saW5lIGNvbnN0IGNoYXIqIEJ1ZmZlckhhbmRsZTo6YnVmZmVyKCkgY29uc3QgeworICByZXR1cm4gdXBiX2J1ZmhhbmRsZV9idWYodGhpcyk7Cit9CitpbmxpbmUgc2l6ZV90IEJ1ZmZlckhhbmRsZTo6b2JqZWN0X29mZnNldCgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9idWZoYW5kbGVfb2Jqb2ZzKHRoaXMpOworfQoraW5saW5lIHZvaWQgQnVmZmVySGFuZGxlOjpTZXRCdWZmZXIoY29uc3QgY2hhciogYnVmLCBzaXplX3Qgb2ZzKSB7CisgIHVwYl9idWZoYW5kbGVfc2V0YnVmKHRoaXMsIGJ1Ziwgb2ZzKTsKK30KK3RlbXBsYXRlIDxjbGFzcyBUPgordm9pZCBCdWZmZXJIYW5kbGU6OlNldEF0dGFjaGVkT2JqZWN0KGNvbnN0IFQqIG9iaikgeworICB1cGJfYnVmaGFuZGxlX3NldG9iaih0aGlzLCBvYmosIFVuaXF1ZVB0ckZvclR5cGU8VD4oKSk7Cit9Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4KK2NvbnN0IFQqIEJ1ZmZlckhhbmRsZTo6R2V0QXR0YWNoZWRPYmplY3QoKSBjb25zdCB7CisgIHJldHVybiB1cGJfYnVmaGFuZGxlX29ianR5cGUodGhpcykgPT0gVW5pcXVlUHRyRm9yVHlwZTxUPigpCisgICAgICA/IHN0YXRpY19jYXN0PGNvbnN0IFQgKj4odXBiX2J1ZmhhbmRsZV9vYmoodGhpcykpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBOVUxMOworfQorCitpbmxpbmUgcmVmZmVkX3B0cjxIYW5kbGVycz4gSGFuZGxlcnM6Ok5ldyhjb25zdCBNZXNzYWdlRGVmICptKSB7CisgIHVwYl9oYW5kbGVycyAqaCA9IHVwYl9oYW5kbGVyc19uZXcobSwgJmgpOworICByZXR1cm4gcmVmZmVkX3B0cjxIYW5kbGVycz4oaCwgJmgpOworfQoraW5saW5lIHJlZmZlZF9wdHI8Y29uc3QgSGFuZGxlcnM+IEhhbmRsZXJzOjpOZXdGcm96ZW4oCisgICAgY29uc3QgTWVzc2FnZURlZiAqbSwgdXBiX2hhbmRsZXJzX2NhbGxiYWNrICpjYWxsYmFjaywKKyAgICBjb25zdCB2b2lkICpjbG9zdXJlKSB7CisgIGNvbnN0IHVwYl9oYW5kbGVycyAqaCA9IHVwYl9oYW5kbGVyc19uZXdmcm96ZW4obSwgJmgsIGNhbGxiYWNrLCBjbG9zdXJlKTsKKyAgcmV0dXJuIHJlZmZlZF9wdHI8Y29uc3QgSGFuZGxlcnM+KGgsICZoKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpJc0Zyb3plbigpIGNvbnN0IHsgcmV0dXJuIHVwYl9oYW5kbGVyc19pc2Zyb3plbih0aGlzKTsgfQoraW5saW5lIHZvaWQgSGFuZGxlcnM6OlJlZihjb25zdCB2b2lkICpvd25lcikgY29uc3QgeworICB1cGJfaGFuZGxlcnNfcmVmKHRoaXMsIG93bmVyKTsKK30KK2lubGluZSB2b2lkIEhhbmRsZXJzOjpVbnJlZihjb25zdCB2b2lkICpvd25lcikgY29uc3QgeworICB1cGJfaGFuZGxlcnNfdW5yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgSGFuZGxlcnM6OkRvbmF0ZVJlZihjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0bykgY29uc3QgeworICB1cGJfaGFuZGxlcnNfZG9uYXRlcmVmKHRoaXMsIGZyb20sIHRvKTsKK30KK2lubGluZSB2b2lkIEhhbmRsZXJzOjpDaGVja1JlZihjb25zdCB2b2lkICpvd25lcikgY29uc3QgeworICB1cGJfaGFuZGxlcnNfY2hlY2tyZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIGNvbnN0IFN0YXR1cyogSGFuZGxlcnM6OnN0YXR1cygpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19zdGF0dXModGhpcyk7Cit9CitpbmxpbmUgdm9pZCBIYW5kbGVyczo6Q2xlYXJFcnJvcigpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19jbGVhcmVycih0aGlzKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpGcmVlemUoU3RhdHVzICpzKSB7CisgIHVwYjo6SGFuZGxlcnMqIGggPSB0aGlzOworICByZXR1cm4gdXBiX2hhbmRsZXJzX2ZyZWV6ZSgmaCwgMSwgcyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyczo6RnJlZXplKEhhbmRsZXJzICpjb25zdCAqaGFuZGxlcnMsIGludCBuLCBTdGF0dXMgKnMpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19mcmVlemUoaGFuZGxlcnMsIG4sIHMpOworfQoraW5saW5lIGJvb2wgSGFuZGxlcnM6OkZyZWV6ZShjb25zdCBzdGQ6OnZlY3RvcjxIYW5kbGVycyo+JiBoLCBTdGF0dXMqIHN0YXR1cykgeworICByZXR1cm4gdXBiX2hhbmRsZXJzX2ZyZWV6ZSgoSGFuZGxlcnMqIGNvbnN0KikmaFswXSwgaC5zaXplKCksIHN0YXR1cyk7Cit9CitpbmxpbmUgY29uc3QgTWVzc2FnZURlZiAqSGFuZGxlcnM6Om1lc3NhZ2VfZGVmKCkgY29uc3QgeworICByZXR1cm4gdXBiX2hhbmRsZXJzX21zZ2RlZih0aGlzKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpBZGRDbGVhbnVwKHZvaWQgKnAsIHVwYl9oYW5kbGVyZnJlZSAqZnVuYykgeworICByZXR1cm4gdXBiX2hhbmRsZXJzX2FkZGNsZWFudXAodGhpcywgcCwgZnVuYyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyczo6U2V0U3RhcnRNZXNzYWdlSGFuZGxlcigKKyAgICBjb25zdCBIYW5kbGVyczo6U3RhcnRNZXNzYWdlSGFuZGxlciAmaGFuZGxlcikgeworICBhc3NlcnQoIWhhbmRsZXIucmVnaXN0ZXJlZF8pOworICBoYW5kbGVyLnJlZ2lzdGVyZWRfID0gdHJ1ZTsKKyAgaGFuZGxlci5BZGRDbGVhbnVwKHRoaXMpOworICByZXR1cm4gdXBiX2hhbmRsZXJzX3NldHN0YXJ0bXNnKHRoaXMsIGhhbmRsZXIuaGFuZGxlcl8sICZoYW5kbGVyLmF0dHJfKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpTZXRFbmRNZXNzYWdlSGFuZGxlcigKKyAgICBjb25zdCBIYW5kbGVyczo6RW5kTWVzc2FnZUhhbmRsZXIgJmhhbmRsZXIpIHsKKyAgYXNzZXJ0KCFoYW5kbGVyLnJlZ2lzdGVyZWRfKTsKKyAgaGFuZGxlci5yZWdpc3RlcmVkXyA9IHRydWU7CisgIGhhbmRsZXIuQWRkQ2xlYW51cCh0aGlzKTsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19zZXRlbmRtc2codGhpcywgaGFuZGxlci5oYW5kbGVyXywgJmhhbmRsZXIuYXR0cl8pOworfQoraW5saW5lIGJvb2wgSGFuZGxlcnM6OlNldFN0YXJ0U3RyaW5nSGFuZGxlcihjb25zdCBGaWVsZERlZiAqZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3RhcnRTdHJpbmdIYW5kbGVyICZoYW5kbGVyKSB7CisgIGFzc2VydCghaGFuZGxlci5yZWdpc3RlcmVkXyk7CisgIGhhbmRsZXIucmVnaXN0ZXJlZF8gPSB0cnVlOworICBoYW5kbGVyLkFkZENsZWFudXAodGhpcyk7CisgIHJldHVybiB1cGJfaGFuZGxlcnNfc2V0c3RhcnRzdHIodGhpcywgZiwgaGFuZGxlci5oYW5kbGVyXywgJmhhbmRsZXIuYXR0cl8pOworfQoraW5saW5lIGJvb2wgSGFuZGxlcnM6OlNldEVuZFN0cmluZ0hhbmRsZXIoY29uc3QgRmllbGREZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbmRGaWVsZEhhbmRsZXIgJmhhbmRsZXIpIHsKKyAgYXNzZXJ0KCFoYW5kbGVyLnJlZ2lzdGVyZWRfKTsKKyAgaGFuZGxlci5yZWdpc3RlcmVkXyA9IHRydWU7CisgIGhhbmRsZXIuQWRkQ2xlYW51cCh0aGlzKTsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19zZXRlbmRzdHIodGhpcywgZiwgaGFuZGxlci5oYW5kbGVyXywgJmhhbmRsZXIuYXR0cl8pOworfQoraW5saW5lIGJvb2wgSGFuZGxlcnM6OlNldFN0cmluZ0hhbmRsZXIoY29uc3QgRmllbGREZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTdHJpbmdIYW5kbGVyJiBoYW5kbGVyKSB7CisgIGFzc2VydCghaGFuZGxlci5yZWdpc3RlcmVkXyk7CisgIGhhbmRsZXIucmVnaXN0ZXJlZF8gPSB0cnVlOworICBoYW5kbGVyLkFkZENsZWFudXAodGhpcyk7CisgIHJldHVybiB1cGJfaGFuZGxlcnNfc2V0c3RyaW5nKHRoaXMsIGYsIGhhbmRsZXIuaGFuZGxlcl8sICZoYW5kbGVyLmF0dHJfKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpTZXRTdGFydFNlcXVlbmNlSGFuZGxlcigKKyAgICBjb25zdCBGaWVsZERlZiAqZiwgY29uc3QgU3RhcnRGaWVsZEhhbmRsZXIgJmhhbmRsZXIpIHsKKyAgYXNzZXJ0KCFoYW5kbGVyLnJlZ2lzdGVyZWRfKTsKKyAgaGFuZGxlci5yZWdpc3RlcmVkXyA9IHRydWU7CisgIGhhbmRsZXIuQWRkQ2xlYW51cCh0aGlzKTsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19zZXRzdGFydHNlcSh0aGlzLCBmLCBoYW5kbGVyLmhhbmRsZXJfLCAmaGFuZGxlci5hdHRyXyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyczo6U2V0U3RhcnRTdWJNZXNzYWdlSGFuZGxlcigKKyAgICBjb25zdCBGaWVsZERlZiAqZiwgY29uc3QgU3RhcnRGaWVsZEhhbmRsZXIgJmhhbmRsZXIpIHsKKyAgYXNzZXJ0KCFoYW5kbGVyLnJlZ2lzdGVyZWRfKTsKKyAgaGFuZGxlci5yZWdpc3RlcmVkXyA9IHRydWU7CisgIGhhbmRsZXIuQWRkQ2xlYW51cCh0aGlzKTsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19zZXRzdGFydHN1Ym1zZyh0aGlzLCBmLCBoYW5kbGVyLmhhbmRsZXJfLCAmaGFuZGxlci5hdHRyXyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyczo6U2V0RW5kU3ViTWVzc2FnZUhhbmRsZXIoY29uc3QgRmllbGREZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW5kRmllbGRIYW5kbGVyICZoYW5kbGVyKSB7CisgIGFzc2VydCghaGFuZGxlci5yZWdpc3RlcmVkXyk7CisgIGhhbmRsZXIucmVnaXN0ZXJlZF8gPSB0cnVlOworICBoYW5kbGVyLkFkZENsZWFudXAodGhpcyk7CisgIHJldHVybiB1cGJfaGFuZGxlcnNfc2V0ZW5kc3VibXNnKHRoaXMsIGYsIGhhbmRsZXIuaGFuZGxlcl8sICZoYW5kbGVyLmF0dHJfKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpTZXRFbmRTZXF1ZW5jZUhhbmRsZXIoY29uc3QgRmllbGREZWYgKmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVuZEZpZWxkSGFuZGxlciAmaGFuZGxlcikgeworICBhc3NlcnQoIWhhbmRsZXIucmVnaXN0ZXJlZF8pOworICBoYW5kbGVyLnJlZ2lzdGVyZWRfID0gdHJ1ZTsKKyAgaGFuZGxlci5BZGRDbGVhbnVwKHRoaXMpOworICByZXR1cm4gdXBiX2hhbmRsZXJzX3NldGVuZHNlcSh0aGlzLCBmLCBoYW5kbGVyLmhhbmRsZXJfLCAmaGFuZGxlci5hdHRyXyk7Cit9CitpbmxpbmUgYm9vbCBIYW5kbGVyczo6U2V0U3ViSGFuZGxlcnMoY29uc3QgRmllbGREZWYgKmYsIGNvbnN0IEhhbmRsZXJzICpzdWIpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19zZXRzdWJoYW5kbGVycyh0aGlzLCBmLCBzdWIpOworfQoraW5saW5lIGNvbnN0IEhhbmRsZXJzICpIYW5kbGVyczo6R2V0U3ViSGFuZGxlcnMoY29uc3QgRmllbGREZWYgKmYpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19nZXRzdWJoYW5kbGVycyh0aGlzLCBmKTsKK30KK2lubGluZSBjb25zdCBIYW5kbGVycyAqSGFuZGxlcnM6OkdldFN1YkhhbmRsZXJzKEhhbmRsZXJzOjpTZWxlY3RvciBzZWwpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19nZXRzdWJoYW5kbGVyc19zZWwodGhpcywgc2VsKTsKK30KK2lubGluZSBib29sIEhhbmRsZXJzOjpHZXRTZWxlY3Rvcihjb25zdCBGaWVsZERlZiAqZiwgSGFuZGxlcnM6OlR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIYW5kbGVyczo6U2VsZWN0b3IgKnMpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19nZXRzZWxlY3RvcihmLCB0eXBlLCBzKTsKK30KK2lubGluZSBIYW5kbGVyczo6U2VsZWN0b3IgSGFuZGxlcnM6OkdldEVuZFNlbGVjdG9yKEhhbmRsZXJzOjpTZWxlY3RvciBzdGFydCkgeworICByZXR1cm4gdXBiX2hhbmRsZXJzX2dldGVuZHNlbGVjdG9yKHN0YXJ0KTsKK30KK2lubGluZSBIYW5kbGVyczo6R2VuZXJpY0Z1bmN0aW9uICpIYW5kbGVyczo6R2V0SGFuZGxlcigKKyAgICBIYW5kbGVyczo6U2VsZWN0b3Igc2VsZWN0b3IpIHsKKyAgcmV0dXJuIHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKHRoaXMsIHNlbGVjdG9yKTsKK30KK2lubGluZSBjb25zdCB2b2lkICpIYW5kbGVyczo6R2V0SGFuZGxlckRhdGEoSGFuZGxlcnM6OlNlbGVjdG9yIHNlbGVjdG9yKSB7CisgIHJldHVybiB1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcmRhdGEodGhpcywgc2VsZWN0b3IpOworfQorCitpbmxpbmUgQnl0ZXNIYW5kbGVyOjpCeXRlc0hhbmRsZXIoKSB7CisgIHVwYl9ieXRlc2hhbmRsZXJfaW5pdCh0aGlzKTsKK30KKworaW5saW5lIEJ5dGVzSGFuZGxlcjo6fkJ5dGVzSGFuZGxlcigpIHsKKyAgdXBiX2J5dGVzaGFuZGxlcl91bmluaXQodGhpcyk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSB1cGIKKworI2VuZGlmICAvLyBfX2NwbHVzcGx1cworCisKKyN1bmRlZiBVUEJfVFdPXzMyQklUX1RZUEVTCisjdW5kZWYgVVBCX1RXT182NEJJVF9UWVBFUworI3VuZGVmIFVQQl9JTlQzMl9UCisjdW5kZWYgVVBCX1VJTlQzMl9UCisjdW5kZWYgVVBCX0lOVDMyQUxUX1QKKyN1bmRlZiBVUEJfVUlOVDMyQUxUX1QKKyN1bmRlZiBVUEJfSU5UNjRfVAorI3VuZGVmIFVQQl9VSU5UNjRfVAorI3VuZGVmIFVQQl9JTlQ2NEFMVF9UCisjdW5kZWYgVVBCX1VJTlQ2NEFMVF9UCisKKyNlbmRpZiAgLy8gVVBCX0hBTkRMRVJTX0lOTF9IXworCisjZW5kaWYgIC8vIFVQQl9IQU5ETEVSU19ICisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTIgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIEEgdXBiX3NpbmsgaXMgYW4gb2JqZWN0IHRoYXQgYmluZHMgYSB1cGJfaGFuZGxlcnMgb2JqZWN0IHRvIHNvbWUgcnVudGltZQorICogc3RhdGUuICBJdCBpcyB0aGUgb2JqZWN0IHRoYXQgY2FuIGFjdHVhbGx5IHJlY2VpdmUgZGF0YSB2aWEgdGhlIHVwYl9oYW5kbGVycworICogaW50ZXJmYWNlLgorICoKKyAqIFVubGlrZSB1cGJfZGVmIGFuZCB1cGJfaGFuZGxlcnMsIHVwYl9zaW5rIGlzIG5ldmVyIGZyb3plbiwgaW1tdXRhYmxlLCBvcgorICogdGhyZWFkLXNhZmUuICBZb3UgY2FuIGNyZWF0ZSBhcyBtYW55IG9mIHRoZW0gYXMgeW91IHdhbnQsIGJ1dCBlYWNoIG9uZSBtYXkKKyAqIG9ubHkgYmUgdXNlZCBpbiBhIHNpbmdsZSB0aHJlYWQgYXQgYSB0aW1lLgorICoKKyAqIElmIHdlIGNvbXBhcmUgd2l0aCBjbGFzcy1iYXNlZCBPT1AsIGEgeW91IGNhbiB0aGluayBvZiBhIHVwYl9kZWYgYXMgYW4KKyAqIGFic3RyYWN0IGJhc2UgY2xhc3MsIGEgdXBiX2hhbmRsZXJzIGFzIGEgY29uY3JldGUgZGVyaXZlZCBjbGFzcywgYW5kIGEKKyAqIHVwYl9zaW5rIGFzIGFuIG9iamVjdCAoY2xhc3MgaW5zdGFuY2UpLgorICovCisKKyNpZm5kZWYgVVBCX1NJTktfSAorI2RlZmluZSBVUEJfU0lOS19ICisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK2NsYXNzIEJ1ZmZlclNvdXJjZTsKK2NsYXNzIEJ5dGVzU2luazsKK2NsYXNzIFNpbms7Cit9CisjZW5kaWYKKworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OkJ1ZmZlclNvdXJjZSwgdXBiX2J1ZnNyYyk7CitVUEJfREVDTEFSRV9UWVBFKHVwYjo6Qnl0ZXNTaW5rLCB1cGJfYnl0ZXNzaW5rKTsKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpTaW5rLCB1cGJfc2luayk7CisKKy8vIEludGVybmFsLW9ubHkgc3RydWN0IGZvciB0aGUgc2luay4KK3N0cnVjdCB1cGJfc2lua2ZyYW1lIHsKKyBVUEJfUFJJVkFURV9GT1JfQ1BQCisgIGNvbnN0IHVwYl9oYW5kbGVycyAqaDsKKyAgdm9pZCAqY2xvc3VyZTsKKworICAvLyBGb3IgYW55IGZyYW1lcyBiZXNpZGVzIHRoZSB0b3AsIHRoaXMgaXMgdGhlIEVORCogY2FsbGJhY2sgdGhhdCB3aWxsIHJ1bgorICAvLyB3aGVuIHRoZSBzdWJmcmFtZSBpcyBwb3BwZWQgKGZvciBleGFtcGxlLCBmb3IgYSAic2VxdWVuY2UiIGZyYW1lIHRoZSBmcmFtZQorICAvLyBhYm92ZSBpdCB3aWxsIGJlIGEgVVBCX0hBTkRMRVJfRU5EU0VRIGhhbmRsZXIpLiAgQnV0IHRoaXMgaXMgb25seQorICAvLyBuZWNlc3NhcnkgZm9yIGFzc2VydGlvbiBjaGVja2luZyBpbnNpZGUgdXBiX3NpbmsgYW5kIGNhbiBiZSBvbWl0dGVkIGlmIHRoZQorICAvLyBzaW5rIGhhcyBvbmx5IG9uZSBjYWxsZXIuCisgIC8vCisgIC8vIFRPRE8oaGFiZXJtYW4pOiBoYXZlIGEgbWVjaGFuaXNtIGZvciBlbnN1cmluZyB0aGF0IGEgc2luayBvbmx5IGhhcyBvbmUKKyAgLy8gY2FsbGVyLgorICB1cGJfc2VsZWN0b3JfdCBzZWxlY3RvcjsKK307CisKKy8vIFRoZSBtYXhpbXVtIG5lc3RpbmcgZGVwdGggdGhhdCB1cGI6OlNpbmsgd2lsbCBhbGxvdy4gIE1hdGNoZXMgcHJvdG8yJ3MgbGltaXQuCisvLyBUT0RPOiBtYWtlIHRoaXMgYSBydW50aW1lLXNldHRhYmxlIHByb3BlcnR5IG9mIFNpbmsuCisjZGVmaW5lIFVQQl9TSU5LX01BWF9ORVNUSU5HIDY0CisKKy8vIEEgdXBiOjpTaW5rIGlzIGFuIG9iamVjdCB0aGF0IGJpbmRzIGEgdXBiOjpIYW5kbGVycyBvYmplY3QgdG8gc29tZSBydW50aW1lCisvLyBzdGF0ZS4gIEl0IHJlcHJlc2VudHMgYW4gZW5kcG9pbnQgdG8gd2hpY2ggZGF0YSBjYW4gYmUgc2VudC4KKy8vCisvLyBUT0RPKGhhYmVybWFuKTogcmlnaHQgbm93IGFsbCBvZiB0aGVzZSBmdW5jdGlvbnMgdGFrZSBzZWxlY3RvcnMuICBTaG91bGQgdGhleQorLy8gdGFrZSBzZWxlY3RvcmJhc2UgaW5zdGVhZD8KKy8vCisvLyBpZS4gaW5zdGVhZCBvZiBjYWxsaW5nOgorLy8gICBzaW5rLT5TdGFydFN0cmluZyhGT09fRklFTERfU1RBUlRfU1RSSU5HLCAuLi4pCisvLyBhIHNlbGVjdG9yIGJhc2Ugd291bGQgbGV0IHlvdSBzYXk6CisvLyAgIHNpbmstPlN0YXJ0U3RyaW5nKEZPT19GSUVMRCwgLi4uKQorLy8KKy8vIFRoaXMgd291bGQgbWFrZSBjYWxsIHNpdGVzIGEgbGl0dGxlIG5pY2VyIGFuZCByZXF1aXJlIGVtaXR0aW5nIGZld2VyIHNlbGVjdG9yCisvLyBkZWZpbml0aW9ucyBpbiAuaCBmaWxlcy4KKy8vCisvLyBCdXQgdGhlIGN1cnJlbnQgc2NoZW1lIGhhcyB0aGUgYmVuZWZpdCB0aGF0IHlvdSBjYW4gcmV0cmlldmUgYSBmdW5jdGlvbgorLy8gcG9pbnRlciBmb3IgYW55IGhhbmRsZXIgd2l0aCBoYW5kbGVycy0+R2V0SGFuZGxlcihzZWxlY3RvciksIHdpdGhvdXQgaGF2aW5nCisvLyB0byBoYXZlIGEgc2VwYXJhdGUgR2V0SGFuZGxlcigpIGZ1bmN0aW9uIGZvciBlYWNoIGhhbmRsZXIgdHlwZS4gIFRoZSBKSVQKKy8vIGNvbXBpbGVyIHVzZXMgdGhpcy4gIFRvIGFjY29tbW9kYXRlIHdlJ2QgaGF2ZSB0byBleHBvc2UgYSBzZXBhcmF0ZQorLy8gR2V0SGFuZGxlcigpIGZvciBldmVyeSBoYW5kbGVyIHR5cGUuCisvLworLy8gQWxzbyB0byBwb25kZXI6IHNlbGVjdG9ycyByaWdodCBub3cgYXJlIGluZGVwZW5kZW50IG9mIGEgc3BlY2lmaWMgSGFuZGxlcnMKKy8vIGluc3RhbmNlLiAgSW4gb3RoZXIgd29yZHMsIHRoZXkgYWxsb2NhdGUgYSBudW1iZXIgdG8gZXZlcnkgcG9zc2libGUgaGFuZGxlcgorLy8gdGhhdCAqY291bGQqIGJlIHJlZ2lzdGVyZWQsIHdpdGhvdXQga25vd2luZyBhbnl0aGluZyBhYm91dCB3aGF0IGhhbmRsZXJzCisvLyAqYXJlKiByZWdpc3RlcmVkLiAgVGhhdCBtZWFucyB0aGF0IHVzaW5nIHNlbGVjdG9ycyBhcyB0YWJsZSBvZmZzZXRzIHByb2hpYml0cworLy8gdXMgZnJvbSBjb21wYWN0aW5nIHRoZSBoYW5kbGVyIHRhYmxlIGF0IEZyZWV6ZSgpIHRpbWUuICBJZiB0aGUgdGFibGUgaXMgdmVyeQorLy8gc3BhcnNlLCB0aGlzIGNvdWxkIGJlIHdhc3RlZnVsLgorLy8KKy8vIEhhdmluZyBhbm90aGVyIHNlbGVjdG9yLWxpa2UgdGhpbmcgdGhhdCBpcyBzcGVjaWZpYyB0byBhIEhhbmRsZXJzIGluc3RhbmNlCisvLyB3b3VsZCBhbGxvdyB0aGlzIGNvbXBhY3RpbmcsIGJ1dCB0aGVuIGl0IHdvdWxkIGJlIGltcG9zc2libGUgdG8gd3JpdGUgY29kZQorLy8gYWhlYWQtb2YtdGltZSB0aGF0IGNhbiBiZSBib3VuZCB0byBhbnkgSGFuZGxlcnMgaW5zdGFuY2UgYXQgcnVudGltZS4gIEZvcgorLy8gZXhhbXBsZSwgYSAucHJvdG8gZmlsZSBwYXJzZXIgd3JpdHRlbiBhcyBzdHJhaWdodCBDIHdpbGwgbm90IGtub3cgd2hhdAorLy8gSGFuZGxlcnMgaXQgd2lsbCBiZSBib3VuZCB0bywgc28gd2hlbiBpdCBjYWxscyBzaW5rLT5TdGFydFN0cmluZygpIHdoYXQKKy8vIHNlbGVjdG9yIHdpbGwgaXQgcGFzcz8gIEl0IG5lZWRzIGEgc2VsZWN0b3IgbGlrZSB3ZSBoYXZlIHRvZGF5LCB0aGF0IGlzCisvLyBpbmRlcGVuZGVudCBvZiBhbnkgcGFydGljdWxhciB1cGI6OkhhbmRsZXJzLgorLy8KKy8vIElzIHRoZXJlIGEgd2F5IHRoZW4gdG8gYWxsb3cgSGFuZGxlcnMgdGFibGUgY29tcGFjdGlvbj8KK1VQQl9ERUZJTkVfQ0xBU1MwKHVwYjo6U2luaywKKyBwdWJsaWM6CisgIC8vIENvbnN0cnVjdG9yIHdpdGggbm8gaW5pdGlhbGl6YXRpb247IG11c3QgYmUgUmVzZXQoKSBiZWZvcmUgdXNlLgorICBTaW5rKCkge30KKworICAvLyBDb25zdHJ1Y3RzIGEgbmV3IHNpbmsgZm9yIHRoZSBnaXZlbiBmcm96ZW4gaGFuZGxlcnMgYW5kIGNsb3N1cmUuCisgIC8vCisgIC8vIFRPRE86IG9uY2UgdGhlIEhhbmRsZXJzIGtub3cgdGhlIGV4cGVjdGVkIGNsb3N1cmUgdHlwZSwgdmVyaWZ5IHRoYXQgVAorICAvLyBtYXRjaGVzIGl0LgorICB0ZW1wbGF0ZSA8Y2xhc3MgVD4gU2luayhjb25zdCBIYW5kbGVycyogaGFuZGxlcnMsIFQqIGNsb3N1cmUpOworCisgIC8vIFJlc2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNpbmsuCisgIHRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIFJlc2V0KGNvbnN0IEhhbmRsZXJzKiBoYW5kbGVycywgVCogY2xvc3VyZSk7CisKKyAgLy8gUmV0dXJucyB0aGUgdG9wLWxldmVsIG9iamVjdCB0aGF0IGlzIGJvdW5kIHRvIHRoaXMgc2luay4KKyAgLy8KKyAgLy8gVE9ETzogb25jZSB0aGUgSGFuZGxlcnMga25vdyB0aGUgZXhwZWN0ZWQgY2xvc3VyZSB0eXBlLCB2ZXJpZnkgdGhhdCBUCisgIC8vIG1hdGNoZXMgaXQuCisgIHRlbXBsYXRlIDxjbGFzcyBUPiBUKiBHZXRPYmplY3QoKSBjb25zdDsKKworICAvLyBGdW5jdGlvbnMgZm9yIHB1c2hpbmcgZGF0YSBpbnRvIHRoZSBzaW5rLgorICAvLworICAvLyBUaGVzZSByZXR1cm4gZmFsc2UgaWYgcHJvY2Vzc2luZyBzaG91bGQgc3RvcCAoZWl0aGVyIGR1ZSB0byBlcnJvciBvciBqdXN0CisgIC8vIHRvIHN1c3BlbmQpLgorICAvLworICAvLyBUaGVzZSBtYXkgbm90IGJlIGNhbGxlZCBmcm9tIHdpdGhpbiBvbmUgb2YgdGhlIHNhbWUgc2luaydzIGhhbmRsZXJzIChpbgorICAvLyBvdGhlciB3b3JkcywgaGFuZGxlcnMgYXJlIG5vdCByZS1lbnRyYW50KS4KKworICAvLyBTaG91bGQgYmUgY2FsbGVkIGF0IHRoZSBzdGFydCBhbmQgZW5kIG9mIGV2ZXJ5IG1lc3NhZ2U7IGJvdGggdGhlIHRvcC1sZXZlbAorICAvLyBtZXNzYWdlIGFuZCBzdWJtZXNzYWdlcy4gIFRoaXMgbWVhbnMgdGhhdCBzdWJtZXNzYWdlcyBzaG91bGQgdXNlIHRoZQorICAvLyBmb2xsb3dpbmcgc2VxdWVuY2U6CisgIC8vICAgc2luay0+U3RhcnRTdWJNZXNzYWdlKHN0YXJ0c3VibXNnX3NlbGVjdG9yKTsKKyAgLy8gICBzaW5rLT5TdGFydE1lc3NhZ2UoKTsKKyAgLy8gICAvLyAuLi4KKyAgLy8gICBzaW5rLT5FbmRNZXNzYWdlKCZzdGF0dXMpOworICAvLyAgIHNpbmstPkVuZFN1Yk1lc3NhZ2UoZW5kc3VibXNnX3NlbGVjdG9yKTsKKyAgYm9vbCBTdGFydE1lc3NhZ2UoKTsKKyAgYm9vbCBFbmRNZXNzYWdlKFN0YXR1cyogc3RhdHVzKTsKKworICAvLyBQdXR0aW5nIG9mIGluZGl2aWR1YWwgdmFsdWVzLiAgVGhlc2Ugd29yayBmb3IgYm90aCByZXBlYXRlZCBhbmQKKyAgLy8gbm9uLXJlcGVhdGVkIGZpZWxkcywgYnV0IGZvciByZXBlYXRlZCBmaWVsZHMgeW91IG11c3Qgd3JhcCB0aGVtIGluCisgIC8vIGNhbGxzIHRvIFN0YXJ0U2VxdWVuY2UoKS9FbmRTZXF1ZW5jZSgpLgorICBib29sIFB1dEludDMyKEhhbmRsZXJzOjpTZWxlY3RvciBzLCBpbnQzMl90IHZhbCk7CisgIGJvb2wgUHV0SW50NjQoSGFuZGxlcnM6OlNlbGVjdG9yIHMsIGludDY0X3QgdmFsKTsKKyAgYm9vbCBQdXRVSW50MzIoSGFuZGxlcnM6OlNlbGVjdG9yIHMsIHVpbnQzMl90IHZhbCk7CisgIGJvb2wgUHV0VUludDY0KEhhbmRsZXJzOjpTZWxlY3RvciBzLCB1aW50NjRfdCB2YWwpOworICBib29sIFB1dEZsb2F0KEhhbmRsZXJzOjpTZWxlY3RvciBzLCBmbG9hdCB2YWwpOworICBib29sIFB1dERvdWJsZShIYW5kbGVyczo6U2VsZWN0b3IgcywgZG91YmxlIHZhbCk7CisgIGJvb2wgUHV0Qm9vbChIYW5kbGVyczo6U2VsZWN0b3IgcywgYm9vbCB2YWwpOworCisgIC8vIFB1dHRpbmcgb2Ygc3RyaW5nL2J5dGVzIHZhbHVlcy4gIEVhY2ggc3RyaW5nIGNhbiBjb25zaXN0IG9mIHplcm8gb3IgbW9yZQorICAvLyBub24tY29udGlndW91cyBidWZmZXJzIG9mIGRhdGEuCisgIC8vCisgIC8vIEZvciBTdGFydFN0cmluZygpLCB0aGUgZnVuY3Rpb24gd2lsbCB3cml0ZSBhIHNpbmsgZm9yIHRoZSBzdHJpbmcgdG8gInN1Yi4iCisgIC8vIFRoZSBzdWItc2luayBtdXN0IGJlIHVzZWQgZm9yIGFueS9hbGwgUHV0U3RyaW5nQnVmZmVyKCkgY2FsbHMuCisgIGJvb2wgU3RhcnRTdHJpbmcoSGFuZGxlcnM6OlNlbGVjdG9yIHMsIHNpemVfdCBzaXplX2hpbnQsIFNpbmsqIHN1Yik7CisgIHNpemVfdCBQdXRTdHJpbmdCdWZmZXIoSGFuZGxlcnM6OlNlbGVjdG9yIHMsIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBCdWZmZXJIYW5kbGUgKmhhbmRsZSk7CisgIGJvb2wgRW5kU3RyaW5nKEhhbmRsZXJzOjpTZWxlY3RvciBzKTsKKworICAvLyBGb3Igc3VibWVzc2FnZSBmaWVsZHMuCisgIC8vCisgIC8vIEZvciBTdGFydFN1Yk1lc3NhZ2UoKSwgdGhlIGZ1bmN0aW9uIHdpbGwgd3JpdGUgYSBzaW5rIGZvciB0aGUgc3RyaW5nIHRvCisgIC8vICJzdWIuIiBUaGUgc3ViLXNpbmsgbXVzdCBiZSB1c2VkIGZvciBhbnkvYWxsIGhhbmRsZXJzIGNhbGxlZCB3aXRoaW4gdGhlCisgIC8vIHN1Ym1lc3NhZ2UuCisgIGJvb2wgU3RhcnRTdWJNZXNzYWdlKEhhbmRsZXJzOjpTZWxlY3RvciBzLCBTaW5rKiBzdWIpOworICBib29sIEVuZFN1Yk1lc3NhZ2UoSGFuZGxlcnM6OlNlbGVjdG9yIHMpOworCisgIC8vIEZvciByZXBlYXRlZCBmaWVsZHMgb2YgYW55IHR5cGUsIHRoZSBzZXF1ZW5jZSBvZiB2YWx1ZXMgbXVzdCBiZSB3cmFwcGVkIGluCisgIC8vIHRoZXNlIGNhbGxzLgorICAvLworICAvLyBGb3IgU3RhcnRTZXF1ZW5jZSgpLCB0aGUgZnVuY3Rpb24gd2lsbCB3cml0ZSBhIHNpbmsgZm9yIHRoZSBzdHJpbmcgdG8KKyAgLy8gInN1Yi4iIFRoZSBzdWItc2luayBtdXN0IGJlIHVzZWQgZm9yIGFueS9hbGwgaGFuZGxlcnMgY2FsbGVkIHdpdGhpbiB0aGUKKyAgLy8gc2VxdWVuY2UuCisgIGJvb2wgU3RhcnRTZXF1ZW5jZShIYW5kbGVyczo6U2VsZWN0b3IgcywgU2luayogc3ViKTsKKyAgYm9vbCBFbmRTZXF1ZW5jZShIYW5kbGVyczo6U2VsZWN0b3Igcyk7CisKKyAgLy8gQ29weSBhbmQgYXNzaWduIHNwZWNpZmljYWxseSBhbGxvd2VkLgorICAvLyBXZSBkb24ndCBldmVuIGJvdGhlciBtYWtpbmcgdGhlc2UgbWVtYmVycyBwcml2YXRlIGJlY2F1c2Ugc28gbWFueQorICAvLyBmdW5jdGlvbnMgbmVlZCB0aGVtIGFuZCB0aGlzIGlzIG1haW5seSBqdXN0IGEgZHVtYiBkYXRhIGNvbnRhaW5lciBhbnl3YXkuCissCitVUEJfREVGSU5FX1NUUlVDVDAodXBiX3NpbmssCisgIGNvbnN0IHVwYl9oYW5kbGVycyAqaGFuZGxlcnM7CisgIHZvaWQgKmNsb3N1cmU7CispKTsKKworVVBCX0RFRklORV9DTEFTUzAodXBiOjpCeXRlc1NpbmssCisgcHVibGljOgorICBCeXRlc1NpbmsoKSB7fQorCisgIC8vIENvbnN0cnVjdHMgYSBuZXcgc2luayBmb3IgdGhlIGdpdmVuIGZyb3plbiBoYW5kbGVycyBhbmQgY2xvc3VyZS4KKyAgLy8KKyAgLy8gVE9ETyhoYWJlcm1hbik6IG9uY2UgdGhlIEhhbmRsZXJzIGtub3cgdGhlIGV4cGVjdGVkIGNsb3N1cmUgdHlwZSwgdmVyaWZ5CisgIC8vIHRoYXQgVCBtYXRjaGVzIGl0LgorICB0ZW1wbGF0ZSA8Y2xhc3MgVD4gQnl0ZXNTaW5rKGNvbnN0IEJ5dGVzSGFuZGxlciogaGFuZGxlciwgVCogY2xvc3VyZSk7CisKKyAgLy8gUmVzZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc2luay4KKyAgdGVtcGxhdGUgPGNsYXNzIFQ+IHZvaWQgUmVzZXQoY29uc3QgQnl0ZXNIYW5kbGVyKiBoYW5kbGVyLCBUKiBjbG9zdXJlKTsKKworICBib29sIFN0YXJ0KHNpemVfdCBzaXplX2hpbnQsIHZvaWQgKipzdWJjKTsKKyAgc2l6ZV90IFB1dEJ1ZmZlcih2b2lkICpzdWJjLCBjb25zdCBjaGFyICpidWYsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgY29uc3QgQnVmZmVySGFuZGxlICpoYW5kbGUpOworICBib29sIEVuZCgpOworLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9ieXRlc3NpbmssCisgIGNvbnN0IHVwYl9ieXRlc2hhbmRsZXIgKmhhbmRsZXI7CisgIHZvaWQgKmNsb3N1cmU7CispKTsKKworLy8gQSBjbGFzcyBmb3IgcHVzaGluZyBhIGZsYXQgYnVmZmVyIG9mIGRhdGEgdG8gYSBCeXRlc1NpbmsuCisvLyBZb3UgY2FuIGNvbnN0cnVjdCBhbiBpbnN0YW5jZSBvZiB0aGlzIHRvIGdldCBhIHJlc3VtYWJsZSBzb3VyY2UsCisvLyBvciBqdXN0IGNhbGwgdGhlIHN0YXRpYyBQdXRCdWZmZXIoKSB0byBkbyBhIG5vbi1yZXN1bWFibGUgcHVzaCBhbGwgaW4gb25lIGdvLgorVVBCX0RFRklORV9DTEFTUzAodXBiOjpCdWZmZXJTb3VyY2UsCisgcHVibGljOgorICBCdWZmZXJTb3VyY2UoKTsKKyAgQnVmZmVyU291cmNlKGNvbnN0IGNoYXIqIGJ1Ziwgc2l6ZV90IGxlbiwgQnl0ZXNTaW5rKiBzaW5rKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGVudGlyZSBidWZmZXIgd2FzIHB1c2hlZCBzdWNjZXNzZnVsbHkuICBPdGhlcndpc2UgdGhlCisgIC8vIG5leHQgY2FsbCB0byBQdXROZXh0KCkgd2lsbCByZXN1bWUgd2hlcmUgdGhlIHByZXZpb3VzIG9uZSBsZWZ0IG9mZi4KKyAgLy8gVE9ETyhoYWJlcm1hbik6IGltcGxlbWVudCB0aGlzLgorICBib29sIFB1dE5leHQoKTsKKworICAvLyBBIHN0YXRpYyB2ZXJzaW9uOyB3aXRoIHRoaXMgdmVyc2lvbiBpcyBpdCBub3QgcG9zc2libGUgdG8gcmVzdW1lIGluIHRoZQorICAvLyBjYXNlIG9mIGZhaWx1cmUgb3IgYSBwYXJ0aWFsbHktY29uc3VtZWQgYnVmZmVyLgorICBzdGF0aWMgYm9vbCBQdXRCdWZmZXIoY29uc3QgY2hhciogYnVmLCBzaXplX3QgbGVuLCBCeXRlc1NpbmsqIHNpbmspOworCisgIHRlbXBsYXRlIDxjbGFzcyBUPiBzdGF0aWMgYm9vbCBQdXRCdWZmZXIoY29uc3QgVCYgc3RyLCBCeXRlc1NpbmsqIHNpbmspIHsKKyAgICByZXR1cm4gUHV0QnVmZmVyKHN0ci5jX3N0cigpLCBzdHIuc2l6ZSgpLCBzaW5rKTsKKyAgfQorLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9idWZzcmMsCispKTsKKworVVBCX0JFR0lOX0VYVEVSTl9DICAvLyB7CisKKy8vIElubGluZSBkZWZpbml0aW9ucy4KKworVVBCX0lOTElORSB2b2lkIHVwYl9ieXRlc3NpbmtfcmVzZXQodXBiX2J5dGVzc2luayAqcywgY29uc3QgdXBiX2J5dGVzaGFuZGxlciAqaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNsb3N1cmUpIHsKKyAgcy0+aGFuZGxlciA9IGg7CisgIHMtPmNsb3N1cmUgPSBjbG9zdXJlOworfQorCitVUEJfSU5MSU5FIGJvb2wgdXBiX2J5dGVzc2lua19zdGFydCh1cGJfYnl0ZXNzaW5rICpzLCBzaXplX3Qgc2l6ZV9oaW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKnN1YmMpIHsKKyAgKnN1YmMgPSBzLT5jbG9zdXJlOworICBpZiAoIXMtPmhhbmRsZXIpIHJldHVybiB0cnVlOworICB1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMgKnN0YXJ0ID0KKyAgICAgICh1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMgKilzLT5oYW5kbGVyLT50YWJsZVtVUEJfU1RBUlRTVFJfU0VMRUNUT1JdLmZ1bmM7CisKKyAgaWYgKCFzdGFydCkgcmV0dXJuIHRydWU7CisgICpzdWJjID0gc3RhcnQocy0+Y2xvc3VyZSwgdXBiX2hhbmRsZXJhdHRyX2hhbmRsZXJkYXRhKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcy0+aGFuZGxlci0+dGFibGVbVVBCX1NUQVJUU1RSX1NFTEVDVE9SXS5hdHRyKSwKKyAgICAgICAgICAgICAgICBzaXplX2hpbnQpOworICByZXR1cm4gKnN1YmMgIT0gTlVMTDsKK30KKworVVBCX0lOTElORSBzaXplX3QgdXBiX2J5dGVzc2lua19wdXRidWYodXBiX2J5dGVzc2luayAqcywgdm9pZCAqc3ViYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfYnVmaGFuZGxlKiBoYW5kbGUpIHsKKyAgaWYgKCFzLT5oYW5kbGVyKSByZXR1cm4gdHJ1ZTsKKyAgdXBiX3N0cmluZ19oYW5kbGVyZnVuYyAqcHV0YnVmID0KKyAgICAgICh1cGJfc3RyaW5nX2hhbmRsZXJmdW5jICopcy0+aGFuZGxlci0+dGFibGVbVVBCX1NUUklOR19TRUxFQ1RPUl0uZnVuYzsKKworICBpZiAoIXB1dGJ1ZikgcmV0dXJuIHRydWU7CisgIHJldHVybiBwdXRidWYoc3ViYywgdXBiX2hhbmRsZXJhdHRyX2hhbmRsZXJkYXRhKAorICAgICAgICAgICAgICAgICAgICAgICAgICAmcy0+aGFuZGxlci0+dGFibGVbVVBCX1NUUklOR19TRUxFQ1RPUl0uYXR0ciksCisgICAgICAgICAgICAgICAgYnVmLCBzaXplLCBoYW5kbGUpOworfQorCitVUEJfSU5MSU5FIGJvb2wgdXBiX2J5dGVzc2lua19lbmQodXBiX2J5dGVzc2luayAqcykgeworICBpZiAoIXMtPmhhbmRsZXIpIHJldHVybiB0cnVlOworICB1cGJfZW5kZmllbGRfaGFuZGxlcmZ1bmMgKmVuZCA9CisgICAgICAodXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jICopcy0+aGFuZGxlci0+dGFibGVbVVBCX0VORFNUUl9TRUxFQ1RPUl0uZnVuYzsKKworICBpZiAoIWVuZCkgcmV0dXJuIHRydWU7CisgIHJldHVybiBlbmQocy0+Y2xvc3VyZSwKKyAgICAgICAgICAgICB1cGJfaGFuZGxlcmF0dHJfaGFuZGxlcmRhdGEoCisgICAgICAgICAgICAgICAgICZzLT5oYW5kbGVyLT50YWJsZVtVUEJfRU5EU1RSX1NFTEVDVE9SXS5hdHRyKSk7Cit9CisKK1VQQl9JTkxJTkUgYm9vbCB1cGJfYnVmc3JjX3B1dGJ1Zihjb25zdCBjaGFyICpidWYsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX2J5dGVzc2luayAqc2luaykgeworICB2b2lkICpzdWJjOworICB1cGJfYnVmaGFuZGxlIGhhbmRsZTsKKyAgdXBiX2J1ZmhhbmRsZV9pbml0KCZoYW5kbGUpOworICB1cGJfYnVmaGFuZGxlX3NldGJ1ZigmaGFuZGxlLCBidWYsIDApOworICBib29sIHJldCA9IHVwYl9ieXRlc3Npbmtfc3RhcnQoc2luaywgbGVuLCAmc3ViYyk7CisgIGlmIChyZXQgJiYgbGVuICE9IDApIHsKKyAgICByZXQgPSAodXBiX2J5dGVzc2lua19wdXRidWYoc2luaywgc3ViYywgYnVmLCBsZW4sICZoYW5kbGUpID09IGxlbik7CisgIH0KKyAgaWYgKHJldCkgeworICAgIHJldCA9IHVwYl9ieXRlc3NpbmtfZW5kKHNpbmspOworICB9CisgIHVwYl9idWZoYW5kbGVfdW5pbml0KCZoYW5kbGUpOworICByZXR1cm4gcmV0OworfQorCisjZGVmaW5lIFBVVFZBTCh0eXBlLCBjdHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVUEJfSU5MSU5FIGJvb2wgdXBiX3NpbmtfcHV0IyN0eXBlKHVwYl9zaW5rICpzLCB1cGJfc2VsZWN0b3JfdCBzZWwsICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHlwZSB2YWwpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKCFzLT5oYW5kbGVycykgcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHVwYl8jI3R5cGUjI19oYW5kbGVyZnVuYyAqZnVuYyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgKHVwYl8jI3R5cGUjI19oYW5kbGVyZnVuYyAqKXVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKHMtPmhhbmRsZXJzLCBzZWwpOyBcCisgICAgaWYgKCFmdW5jKSByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNvbnN0IHZvaWQgKmhkID0gdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKHMtPmhhbmRsZXJzLCBzZWwpOyAgICAgICAgICAgIFwKKyAgICByZXR1cm4gZnVuYyhzLT5jbG9zdXJlLCBoZCwgdmFsKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKworUFVUVkFMKGludDMyLCAgaW50MzJfdCk7CitQVVRWQUwoaW50NjQsICBpbnQ2NF90KTsKK1BVVFZBTCh1aW50MzIsIHVpbnQzMl90KTsKK1BVVFZBTCh1aW50NjQsIHVpbnQ2NF90KTsKK1BVVFZBTChmbG9hdCwgIGZsb2F0KTsKK1BVVFZBTChkb3VibGUsIGRvdWJsZSk7CitQVVRWQUwoYm9vbCwgICBib29sKTsKKyN1bmRlZiBQVVRWQUwKKworVVBCX0lOTElORSB2b2lkIHVwYl9zaW5rX3Jlc2V0KHVwYl9zaW5rICpzLCBjb25zdCB1cGJfaGFuZGxlcnMgKmgsIHZvaWQgKmMpIHsKKyAgcy0+aGFuZGxlcnMgPSBoOworICBzLT5jbG9zdXJlID0gYzsKK30KKworVVBCX0lOTElORSBzaXplX3QgdXBiX3NpbmtfcHV0c3RyaW5nKHVwYl9zaW5rICpzLCB1cGJfc2VsZWN0b3JfdCBzZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGJfYnVmaGFuZGxlICpoYW5kbGUpIHsKKyAgaWYgKCFzLT5oYW5kbGVycykgcmV0dXJuIG47CisgIHVwYl9zdHJpbmdfaGFuZGxlcmZ1bmMgKmhhbmRsZXIgPQorICAgICAgKHVwYl9zdHJpbmdfaGFuZGxlcmZ1bmMgKil1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihzLT5oYW5kbGVycywgc2VsKTsKKworICBpZiAoIWhhbmRsZXIpIHJldHVybiBuOworICBjb25zdCB2b2lkICpoZCA9IHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyZGF0YShzLT5oYW5kbGVycywgc2VsKTsKKyAgcmV0dXJuIGhhbmRsZXIocy0+Y2xvc3VyZSwgaGQsIGJ1ZiwgbiwgaGFuZGxlKTsKK30KKworVVBCX0lOTElORSBib29sIHVwYl9zaW5rX3N0YXJ0bXNnKHVwYl9zaW5rICpzKSB7CisgIGlmICghcy0+aGFuZGxlcnMpIHJldHVybiB0cnVlOworICB1cGJfc3RhcnRtc2dfaGFuZGxlcmZ1bmMgKnN0YXJ0bXNnID0KKyAgICAgICh1cGJfc3RhcnRtc2dfaGFuZGxlcmZ1bmMgKil1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihzLT5oYW5kbGVycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVQQl9TVEFSVE1TR19TRUxFQ1RPUik7CisgIGlmICghc3RhcnRtc2cpIHJldHVybiB0cnVlOworICBjb25zdCB2b2lkICpoZCA9CisgICAgICB1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcmRhdGEocy0+aGFuZGxlcnMsIFVQQl9TVEFSVE1TR19TRUxFQ1RPUik7CisgIHJldHVybiBzdGFydG1zZyhzLT5jbG9zdXJlLCBoZCk7Cit9CisKK1VQQl9JTkxJTkUgYm9vbCB1cGJfc2lua19lbmRtc2codXBiX3NpbmsgKnMsIHVwYl9zdGF0dXMgKnN0YXR1cykgeworICBpZiAoIXMtPmhhbmRsZXJzKSByZXR1cm4gdHJ1ZTsKKyAgdXBiX2VuZG1zZ19oYW5kbGVyZnVuYyAqZW5kbXNnID0KKyAgICAgICh1cGJfZW5kbXNnX2hhbmRsZXJmdW5jICopdXBiX2hhbmRsZXJzX2dldGhhbmRsZXIocy0+aGFuZGxlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVQQl9FTkRNU0dfU0VMRUNUT1IpOworCisgIGlmICghZW5kbXNnKSByZXR1cm4gdHJ1ZTsKKyAgY29uc3Qgdm9pZCAqaGQgPQorICAgICAgdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKHMtPmhhbmRsZXJzLCBVUEJfRU5ETVNHX1NFTEVDVE9SKTsKKyAgcmV0dXJuIGVuZG1zZyhzLT5jbG9zdXJlLCBoZCwgc3RhdHVzKTsKK30KKworVVBCX0lOTElORSBib29sIHVwYl9zaW5rX3N0YXJ0c2VxKHVwYl9zaW5rICpzLCB1cGJfc2VsZWN0b3JfdCBzZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3NpbmsgKnN1YikgeworICBzdWItPmNsb3N1cmUgPSBzLT5jbG9zdXJlOworICBzdWItPmhhbmRsZXJzID0gcy0+aGFuZGxlcnM7CisgIGlmICghcy0+aGFuZGxlcnMpIHJldHVybiB0cnVlOworICB1cGJfc3RhcnRmaWVsZF9oYW5kbGVyZnVuYyAqc3RhcnRzZXEgPQorICAgICAgKHVwYl9zdGFydGZpZWxkX2hhbmRsZXJmdW5jKil1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihzLT5oYW5kbGVycywgc2VsKTsKKworICBpZiAoIXN0YXJ0c2VxKSByZXR1cm4gdHJ1ZTsKKyAgY29uc3Qgdm9pZCAqaGQgPSB1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcmRhdGEocy0+aGFuZGxlcnMsIHNlbCk7CisgIHN1Yi0+Y2xvc3VyZSA9IHN0YXJ0c2VxKHMtPmNsb3N1cmUsIGhkKTsKKyAgcmV0dXJuIHN1Yi0+Y2xvc3VyZSA/IHRydWUgOiBmYWxzZTsKK30KKworVVBCX0lOTElORSBib29sIHVwYl9zaW5rX2VuZHNlcSh1cGJfc2luayAqcywgdXBiX3NlbGVjdG9yX3Qgc2VsKSB7CisgIGlmICghcy0+aGFuZGxlcnMpIHJldHVybiB0cnVlOworICB1cGJfZW5kZmllbGRfaGFuZGxlcmZ1bmMgKmVuZHNlcSA9CisgICAgICAodXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jKil1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihzLT5oYW5kbGVycywgc2VsKTsKKworICBpZiAoIWVuZHNlcSkgcmV0dXJuIHRydWU7CisgIGNvbnN0IHZvaWQgKmhkID0gdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKHMtPmhhbmRsZXJzLCBzZWwpOworICByZXR1cm4gZW5kc2VxKHMtPmNsb3N1cmUsIGhkKTsKK30KKworVVBCX0lOTElORSBib29sIHVwYl9zaW5rX3N0YXJ0c3RyKHVwYl9zaW5rICpzLCB1cGJfc2VsZWN0b3JfdCBzZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemVfaGludCwgdXBiX3NpbmsgKnN1YikgeworICBzdWItPmNsb3N1cmUgPSBzLT5jbG9zdXJlOworICBzdWItPmhhbmRsZXJzID0gcy0+aGFuZGxlcnM7CisgIGlmICghcy0+aGFuZGxlcnMpIHJldHVybiB0cnVlOworICB1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMgKnN0YXJ0c3RyID0KKyAgICAgICh1cGJfc3RhcnRzdHJfaGFuZGxlcmZ1bmMqKXVwYl9oYW5kbGVyc19nZXRoYW5kbGVyKHMtPmhhbmRsZXJzLCBzZWwpOworCisgIGlmICghc3RhcnRzdHIpIHJldHVybiB0cnVlOworICBjb25zdCB2b2lkICpoZCA9IHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyZGF0YShzLT5oYW5kbGVycywgc2VsKTsKKyAgc3ViLT5jbG9zdXJlID0gc3RhcnRzdHIocy0+Y2xvc3VyZSwgaGQsIHNpemVfaGludCk7CisgIHJldHVybiBzdWItPmNsb3N1cmUgPyB0cnVlIDogZmFsc2U7Cit9CisKK1VQQl9JTkxJTkUgYm9vbCB1cGJfc2lua19lbmRzdHIodXBiX3NpbmsgKnMsIHVwYl9zZWxlY3Rvcl90IHNlbCkgeworICBpZiAoIXMtPmhhbmRsZXJzKSByZXR1cm4gdHJ1ZTsKKyAgdXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jICplbmRzdHIgPQorICAgICAgKHVwYl9lbmRmaWVsZF9oYW5kbGVyZnVuYyopdXBiX2hhbmRsZXJzX2dldGhhbmRsZXIocy0+aGFuZGxlcnMsIHNlbCk7CisKKyAgaWYgKCFlbmRzdHIpIHJldHVybiB0cnVlOworICBjb25zdCB2b2lkICpoZCA9IHVwYl9oYW5kbGVyc19nZXRoYW5kbGVyZGF0YShzLT5oYW5kbGVycywgc2VsKTsKKyAgcmV0dXJuIGVuZHN0cihzLT5jbG9zdXJlLCBoZCk7Cit9CisKK1VQQl9JTkxJTkUgYm9vbCB1cGJfc2lua19zdGFydHN1Ym1zZyh1cGJfc2luayAqcywgdXBiX3NlbGVjdG9yX3Qgc2VsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9zaW5rICpzdWIpIHsKKyAgc3ViLT5jbG9zdXJlID0gcy0+Y2xvc3VyZTsKKyAgaWYgKCFzLT5oYW5kbGVycykgeworICAgIHN1Yi0+aGFuZGxlcnMgPSBOVUxMOworICAgIHJldHVybiB0cnVlOworICB9CisgIHN1Yi0+aGFuZGxlcnMgPSB1cGJfaGFuZGxlcnNfZ2V0c3ViaGFuZGxlcnNfc2VsKHMtPmhhbmRsZXJzLCBzZWwpOworICB1cGJfc3RhcnRmaWVsZF9oYW5kbGVyZnVuYyAqc3RhcnRzdWJtc2cgPQorICAgICAgKHVwYl9zdGFydGZpZWxkX2hhbmRsZXJmdW5jKil1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihzLT5oYW5kbGVycywgc2VsKTsKKworICBpZiAoIXN0YXJ0c3VibXNnKSByZXR1cm4gdHJ1ZTsKKyAgY29uc3Qgdm9pZCAqaGQgPSB1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcmRhdGEocy0+aGFuZGxlcnMsIHNlbCk7CisgIHN1Yi0+Y2xvc3VyZSA9IHN0YXJ0c3VibXNnKHMtPmNsb3N1cmUsIGhkKTsKKyAgcmV0dXJuIHN1Yi0+Y2xvc3VyZSA/IHRydWUgOiBmYWxzZTsKK30KKworVVBCX0lOTElORSBib29sIHVwYl9zaW5rX2VuZHN1Ym1zZyh1cGJfc2luayAqcywgdXBiX3NlbGVjdG9yX3Qgc2VsKSB7CisgIGlmICghcy0+aGFuZGxlcnMpIHJldHVybiB0cnVlOworICB1cGJfZW5kZmllbGRfaGFuZGxlcmZ1bmMgKmVuZHN1Ym1zZyA9CisgICAgICAodXBiX2VuZGZpZWxkX2hhbmRsZXJmdW5jKil1cGJfaGFuZGxlcnNfZ2V0aGFuZGxlcihzLT5oYW5kbGVycywgc2VsKTsKKworICBpZiAoIWVuZHN1Ym1zZykgcmV0dXJuIHMtPmNsb3N1cmU7CisgIGNvbnN0IHZvaWQgKmhkID0gdXBiX2hhbmRsZXJzX2dldGhhbmRsZXJkYXRhKHMtPmhhbmRsZXJzLCBzZWwpOworICByZXR1cm4gZW5kc3VibXNnKHMtPmNsb3N1cmUsIGhkKTsKK30KKworVVBCX0VORF9FWFRFUk5fQyAgLy8gfQorCisjaWZkZWYgX19jcGx1c3BsdXMKKworbmFtZXNwYWNlIHVwYiB7CisKK3RlbXBsYXRlIDxjbGFzcyBUPiBTaW5rOjpTaW5rKGNvbnN0IEhhbmRsZXJzKiBoYW5kbGVycywgVCogY2xvc3VyZSkgeworICB1cGJfc2lua19yZXNldCh0aGlzLCBoYW5kbGVycywgY2xvc3VyZSk7Cit9Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4KK2lubGluZSB2b2lkIFNpbms6OlJlc2V0KGNvbnN0IEhhbmRsZXJzKiBoYW5kbGVycywgVCogY2xvc3VyZSkgeworICB1cGJfc2lua19yZXNldCh0aGlzLCBoYW5kbGVycywgY2xvc3VyZSk7Cit9CitpbmxpbmUgYm9vbCBTaW5rOjpTdGFydE1lc3NhZ2UoKSB7CisgIHJldHVybiB1cGJfc2lua19zdGFydG1zZyh0aGlzKTsKK30KK2lubGluZSBib29sIFNpbms6OkVuZE1lc3NhZ2UoU3RhdHVzKiBzdGF0dXMpIHsKKyAgcmV0dXJuIHVwYl9zaW5rX2VuZG1zZyh0aGlzLCBzdGF0dXMpOworfQoraW5saW5lIGJvb2wgU2luazo6UHV0SW50MzIoSGFuZGxlcnM6OlNlbGVjdG9yIHNlbCwgaW50MzJfdCB2YWwpIHsKKyAgcmV0dXJuIHVwYl9zaW5rX3B1dGludDMyKHRoaXMsIHNlbCwgdmFsKTsKK30KK2lubGluZSBib29sIFNpbms6OlB1dEludDY0KEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIGludDY0X3QgdmFsKSB7CisgIHJldHVybiB1cGJfc2lua19wdXRpbnQ2NCh0aGlzLCBzZWwsIHZhbCk7Cit9CitpbmxpbmUgYm9vbCBTaW5rOjpQdXRVSW50MzIoSGFuZGxlcnM6OlNlbGVjdG9yIHNlbCwgdWludDMyX3QgdmFsKSB7CisgIHJldHVybiB1cGJfc2lua19wdXR1aW50MzIodGhpcywgc2VsLCB2YWwpOworfQoraW5saW5lIGJvb2wgU2luazo6UHV0VUludDY0KEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIHVpbnQ2NF90IHZhbCkgeworICByZXR1cm4gdXBiX3NpbmtfcHV0dWludDY0KHRoaXMsIHNlbCwgdmFsKTsKK30KK2lubGluZSBib29sIFNpbms6OlB1dEZsb2F0KEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIGZsb2F0IHZhbCkgeworICByZXR1cm4gdXBiX3NpbmtfcHV0ZmxvYXQodGhpcywgc2VsLCB2YWwpOworfQoraW5saW5lIGJvb2wgU2luazo6UHV0RG91YmxlKEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIGRvdWJsZSB2YWwpIHsKKyAgcmV0dXJuIHVwYl9zaW5rX3B1dGRvdWJsZSh0aGlzLCBzZWwsIHZhbCk7Cit9CitpbmxpbmUgYm9vbCBTaW5rOjpQdXRCb29sKEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIGJvb2wgdmFsKSB7CisgIHJldHVybiB1cGJfc2lua19wdXRib29sKHRoaXMsIHNlbCwgdmFsKTsKK30KK2lubGluZSBib29sIFNpbms6OlN0YXJ0U3RyaW5nKEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIHNpemVfdCBzaXplX2hpbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaW5rICpzdWIpIHsKKyAgcmV0dXJuIHVwYl9zaW5rX3N0YXJ0c3RyKHRoaXMsIHNlbCwgc2l6ZV9oaW50LCBzdWIpOworfQoraW5saW5lIHNpemVfdCBTaW5rOjpQdXRTdHJpbmdCdWZmZXIoSGFuZGxlcnM6OlNlbGVjdG9yIHNlbCwgY29uc3QgY2hhciAqYnVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbiwgY29uc3QgQnVmZmVySGFuZGxlKiBoYW5kbGUpIHsKKyAgcmV0dXJuIHVwYl9zaW5rX3B1dHN0cmluZyh0aGlzLCBzZWwsIGJ1ZiwgbGVuLCBoYW5kbGUpOworfQoraW5saW5lIGJvb2wgU2luazo6RW5kU3RyaW5nKEhhbmRsZXJzOjpTZWxlY3RvciBzZWwpIHsKKyAgcmV0dXJuIHVwYl9zaW5rX2VuZHN0cih0aGlzLCBzZWwpOworfQoraW5saW5lIGJvb2wgU2luazo6U3RhcnRTdWJNZXNzYWdlKEhhbmRsZXJzOjpTZWxlY3RvciBzZWwsIFNpbmsqIHN1YikgeworICByZXR1cm4gdXBiX3Npbmtfc3RhcnRzdWJtc2codGhpcywgc2VsLCBzdWIpOworfQoraW5saW5lIGJvb2wgU2luazo6RW5kU3ViTWVzc2FnZShIYW5kbGVyczo6U2VsZWN0b3Igc2VsKSB7CisgIHJldHVybiB1cGJfc2lua19lbmRzdWJtc2codGhpcywgc2VsKTsKK30KK2lubGluZSBib29sIFNpbms6OlN0YXJ0U2VxdWVuY2UoSGFuZGxlcnM6OlNlbGVjdG9yIHNlbCwgU2luayogc3ViKSB7CisgIHJldHVybiB1cGJfc2lua19zdGFydHNlcSh0aGlzLCBzZWwsIHN1Yik7Cit9CitpbmxpbmUgYm9vbCBTaW5rOjpFbmRTZXF1ZW5jZShIYW5kbGVyczo6U2VsZWN0b3Igc2VsKSB7CisgIHJldHVybiB1cGJfc2lua19lbmRzZXEodGhpcywgc2VsKTsKK30KKwordGVtcGxhdGUgPGNsYXNzIFQ+CitCeXRlc1Npbms6OkJ5dGVzU2luayhjb25zdCBCeXRlc0hhbmRsZXIqIGhhbmRsZXIsIFQqIGNsb3N1cmUpIHsKKyAgUmVzZXQoaGFuZGxlciwgY2xvc3VyZSk7Cit9CisKK3RlbXBsYXRlIDxjbGFzcyBUPgordm9pZCBCeXRlc1Npbms6OlJlc2V0KGNvbnN0IEJ5dGVzSGFuZGxlciAqaGFuZGxlciwgVCAqY2xvc3VyZSkgeworICB1cGJfYnl0ZXNzaW5rX3Jlc2V0KHRoaXMsIGhhbmRsZXIsIGNsb3N1cmUpOworfQoraW5saW5lIGJvb2wgQnl0ZXNTaW5rOjpTdGFydChzaXplX3Qgc2l6ZV9oaW50LCB2b2lkICoqc3ViYykgeworICByZXR1cm4gdXBiX2J5dGVzc2lua19zdGFydCh0aGlzLCBzaXplX2hpbnQsIHN1YmMpOworfQoraW5saW5lIHNpemVfdCBCeXRlc1Npbms6OlB1dEJ1ZmZlcih2b2lkICpzdWJjLCBjb25zdCBjaGFyICpidWYsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEJ1ZmZlckhhbmRsZSAqaGFuZGxlKSB7CisgIHJldHVybiB1cGJfYnl0ZXNzaW5rX3B1dGJ1Zih0aGlzLCBzdWJjLCBidWYsIGxlbiwgaGFuZGxlKTsKK30KK2lubGluZSBib29sIEJ5dGVzU2luazo6RW5kKCkgeworICByZXR1cm4gdXBiX2J5dGVzc2lua19lbmQodGhpcyk7Cit9CisKK2lubGluZSBib29sIEJ1ZmZlclNvdXJjZTo6UHV0QnVmZmVyKGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVzU2luayAqc2luaykgeworICByZXR1cm4gdXBiX2J1ZnNyY19wdXRidWYoYnVmLCBsZW4sIHNpbmspOworfQorCit9ICAvLyBuYW1lc3BhY2UgdXBiCisjZW5kaWYKKworI2VuZGlmCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDEzIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiBGb3IgaGFuZGxlcnMgdGhhdCBkbyB2ZXJ5IHRpbnksIHZlcnkgc2ltcGxlIG9wZXJhdGlvbnMsIHRoZSBmdW5jdGlvbiBjYWxsCisgKiBvdmVyaGVhZCBvZiBjYWxsaW5nIGEgaGFuZGxlciBjYW4gYmUgc2lnbmlmaWNhbnQuICBUaGlzIGZpbGUgYWxsb3dzIHRoZQorICogdXNlciB0byBkZWZpbmUgaGFuZGxlcnMgdGhhdCBkbyBzb21ldGhpbmcgdmVyeSBzaW1wbGUgbGlrZSBzdG9yZSB0aGUgdmFsdWUKKyAqIHRvIG1lbW9yeSBhbmQvb3Igc2V0IGEgaGFzYml0LiAgSklUIGNvbXBpbGVycyBjYW4gdGhlbiBzcGVjaWFsLWNhc2UgdGhlc2UKKyAqIGhhbmRsZXJzIGFuZCBlbWl0IHNwZWNpYWxpemVkIGNvZGUgZm9yIHRoZW0gaW5zdGVhZCBvZiBhY3R1YWxseSBjYWxsaW5nIHRoZQorICogaGFuZGxlci4KKyAqCisgKiBUaGUgZnVuY3Rpb25hbGl0eSBpcyB2ZXJ5IHNpbXBsZS9saW1pdGVkIHJpZ2h0IG5vdyBidXQgbWF5IGV4cGFuZCB0byBiZSBhYmxlCisgKiB0byBjYWxsIGFub3RoZXIgZnVuY3Rpb24uCisgKi8KKworI2lmbmRlZiBVUEJfU0hJTV9ICisjZGVmaW5lIFVQQl9TSElNX0gKKworCit0eXBlZGVmIHN0cnVjdCB7CisgIHNpemVfdCBvZmZzZXQ7CisgIGludDMyX3QgaGFzYml0OworfSB1cGJfc2hpbV9kYXRhOworCisjaWZkZWYgX19jcGx1c3BsdXMKKworbmFtZXNwYWNlIHVwYiB7CisKK3N0cnVjdCBTaGltIHsKKyAgdHlwZWRlZiB1cGJfc2hpbV9kYXRhIERhdGE7CisKKyAgLy8gU2V0cyBhIGhhbmRsZXIgZm9yIHRoZSBnaXZlbiBmaWVsZCB0aGF0IHdyaXRlcyB0aGUgdmFsdWUgdG8gdGhlIGdpdmVuCisgIC8vIG9mZnNldCBhbmQsIGlmIGhhc2JpdCA+PSAwLCBzZXRzIGEgYml0IGF0IHRoZSBnaXZlbiBiaXQgb2Zmc2V0LiAgUmV0dXJucworICAvLyB0cnVlIGlmIHRoZSBoYW5kbGVyIHdhcyBzZXQgc3VjY2Vzc2Z1bGx5LgorICBzdGF0aWMgYm9vbCBTZXQoSGFuZGxlcnMgKmgsIGNvbnN0IEZpZWxkRGVmICpmLCBzaXplX3Qgb2ZzLCBpbnQzMl90IGhhc2JpdCk7CisKKyAgLy8gSWYgdGhpcyBoYW5kbGVyIGlzIGEgc2hpbSwgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyB1cGI6OlNoaW06OkRhdGEgYW5kCisgIC8vIHN0b3JlcyB0aGUgdHlwZSBpbiAidHlwZSIuICBPdGhlcndpc2UgcmV0dXJucyBOVUxMLgorICBzdGF0aWMgY29uc3QgRGF0YSogR2V0RGF0YShjb25zdCBIYW5kbGVycyogaCwgSGFuZGxlcnM6OlNlbGVjdG9yIHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVmOjpUeXBlKiB0eXBlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSB1cGIKKworI2VuZGlmCisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCisvLyBDIEFQSS4KK2Jvb2wgdXBiX3NoaW1fc2V0KHVwYl9oYW5kbGVycyAqaCwgY29uc3QgdXBiX2ZpZWxkZGVmICpmLCBzaXplX3Qgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgaW50MzJfdCBoYXNiaXQpOworY29uc3QgdXBiX3NoaW1fZGF0YSAqdXBiX3NoaW1fZ2V0ZGF0YShjb25zdCB1cGJfaGFuZGxlcnMgKmgsIHVwYl9zZWxlY3Rvcl90IHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwYl9maWVsZHR5cGVfdCAqdHlwZSk7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworI2lmZGVmIF9fY3BsdXNwbHVzCisvLyBDKysgV3JhcHBlcnMuCituYW1lc3BhY2UgdXBiIHsKK2lubGluZSBib29sIFNoaW06OlNldChIYW5kbGVycyogaCwgY29uc3QgRmllbGREZWYqIGYsIHNpemVfdCBvZnMsCisgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBoYXNiaXQpIHsKKyAgcmV0dXJuIHVwYl9zaGltX3NldChoLCBmLCBvZnMsIGhhc2JpdCk7Cit9CitpbmxpbmUgY29uc3QgU2hpbTo6RGF0YSogU2hpbTo6R2V0RGF0YShjb25zdCBIYW5kbGVycyogaCwgSGFuZGxlcnM6OlNlbGVjdG9yIHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlZjo6VHlwZSogdHlwZSkgeworICByZXR1cm4gdXBiX3NoaW1fZ2V0ZGF0YShoLCBzLCB0eXBlKTsKK30KK30gIC8vIG5hbWVzcGFjZSB1cGIKKyNlbmRpZgorCisjZW5kaWYgIC8vIFVQQl9TSElNX0gKKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTEgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIHVwYjo6ZGVzY3JpcHRvcjo6UmVhZGVyIHByb3ZpZGVzIGEgd2F5IG9mIGJ1aWxkaW5nIHVwYjo6RGVmcyBmcm9tCisgKiBkYXRhIGluIGRlc2NyaXB0b3IucHJvdG8gZm9ybWF0LgorICovCisKKyNpZm5kZWYgVVBCX0RFU0NSSVBUT1JfSAorI2RlZmluZSBVUEJfREVTQ1JJUFRPUl9ICisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBkZXNjcmlwdG9yIHsKK2NsYXNzIFJlYWRlcjsKK30gIC8vIG5hbWVzcGFjZSBkZXNjcmlwdG9yCit9ICAvLyBuYW1lc3BhY2UgdXBiCisjZW5kaWYKKworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OmRlc2NyaXB0b3I6OlJlYWRlciwgdXBiX2Rlc2NyZWFkZXIpOworCisvLyBJbnRlcm5hbC1vbmx5IHN0cnVjdHMgdXNlZCBieSBSZWFkZXIuCisKKy8vIHVwYl9kZWZsaXN0IGlzIGFuIGludGVybmFsLW9ubHkgZHluYW1pYyBhcnJheSBmb3Igc3RvcmluZyBhIGdyb3dpbmcgbGlzdCBvZgorLy8gdXBiX2RlZnMuCit0eXBlZGVmIHN0cnVjdCB7CisgVVBCX1BSSVZBVEVfRk9SX0NQUAorICB1cGJfZGVmICoqZGVmczsKKyAgc2l6ZV90IGxlbjsKKyAgc2l6ZV90IHNpemU7CisgIGJvb2wgb3duZWQ7Cit9IHVwYl9kZWZsaXN0OworCisvLyBXZSBrZWVwIGEgc3RhY2sgb2YgYWxsIHRoZSBtZXNzYWdlcyBzY29wZXMgd2UgYXJlIGN1cnJlbnRseSBpbiwgYXMgd2VsbCBhcworLy8gdGhlIHRvcC1sZXZlbCBmaWxlIHNjb3BlLiAgVGhpcyBpcyBuZWNlc3NhcnkgdG8gY29ycmVjdGx5IHF1YWxpZnkgdGhlCisvLyBkZWZpbml0aW9ucyB0aGF0IGFyZSBjb250YWluZWQgaW5zaWRlLiAgIm5hbWUiIHRyYWNrcyB0aGUgbmFtZSBvZiB0aGUKKy8vIG1lc3NhZ2Ugb3IgcGFja2FnZSAoYSBiYXJlIG5hbWUgLS0gbm90IHF1YWxpZmllZCBieSBhbnkgZW5jbG9zaW5nIHNjb3BlcykuCit0eXBlZGVmIHN0cnVjdCB7CisgVVBCX1BSSVZBVEVfRk9SX0NQUAorICBjaGFyICpuYW1lOworICAvLyBJbmRleCBvZiB0aGUgZmlyc3QgZGVmIHRoYXQgaXMgdW5kZXIgdGhpcyBzY29wZS4gIEZvciBtc2dkZWZzLCB0aGUKKyAgLy8gbXNnZGVmIGl0c2VsZiBpcyBhdCBzdGFydC0xLgorICBpbnQgc3RhcnQ7Cit9IHVwYl9kZXNjcmVhZGVyX2ZyYW1lOworCisvLyBUaGUgbWF4aW11bSBudW1iZXIgb2YgbmVzdGVkIGRlY2xhcmF0aW9ucyB0aGF0IGFyZSBhbGxvd2VkLCBpZS4KKy8vIG1lc3NhZ2UgRm9vIHsKKy8vICAgbWVzc2FnZSBCYXIgeworLy8gICAgIG1lc3NhZ2UgQmF6IHsKKy8vICAgICB9CisvLyAgIH0KKy8vIH0KKy8vCisvLyBUaGlzIGlzIGEgcmVzb3VyY2UgbGltaXQgdGhhdCBhZmZlY3RzIGhvdyBiaWcgb3VyIHJ1bnRpbWUgc3RhY2sgY2FuIGdyb3cuCisvLyBUT0RPOiBtYWtlIHRoaXMgYSBydW50aW1lLXNldHRhYmxlIHByb3BlcnR5IG9mIHRoZSBSZWFkZXIgaW5zdGFuY2UuCisjZGVmaW5lIFVQQl9NQVhfTUVTU0FHRV9ORVNUSU5HIDY0CisKKy8vIENsYXNzIHRoYXQgcmVjZWl2ZXMgZGVzY3JpcHRvciBkYXRhIGFjY29yZGluZyB0byB0aGUgZGVzY3JpcHRvci5wcm90byBzY2hlbWEKKy8vIGFuZCB1c2UgaXQgdG8gYnVpbGQgdXBiOjpEZWZzIGNvcnJlc3BvbmRpbmcgdG8gdGhhdCBzY2hlbWEuCitVUEJfREVGSU5FX0NMQVNTMCh1cGI6OmRlc2NyaXB0b3I6OlJlYWRlciwKKyBwdWJsaWM6CisgIC8vIFRoZXNlIGhhbmRsZXJzIG11c3QgaGF2ZSBjb21lIGZyb20gTmV3SGFuZGxlcnMoKSBhbmQgbXVzdCBvdXRsaXZlIHRoZQorICAvLyBSZWFkZXIuCisgIC8vCisgIC8vIFRPRE86IGdlbmVyYXRlIHRoZSBoYW5kbGVycyBzdGF0aWNhbGx5IChsaWtlIHdlIGRvIHdpdGggdGhlCisgIC8vIGRlc2NyaXB0b3IucHJvdG8gZGVmcykgc28gdGhhdCB0aGVyZSBpcyBubyBuZWVkIHRvIHBhc3MgdGhpcyBwYXJhbWV0ZXIgKG9yCisgIC8vIHRvIGJ1aWxkL21lbW9yeS1tYW5hZ2UgdGhlIGhhbmRsZXJzIGF0IHJ1bnRpbWUgYXQgYWxsKS4gIFVuZm9ydHVuYXRlbHkgdGhpcworICAvLyBpcyBhIGJpdCB0cmlja3kgdG8gaW1wbGVtZW50IGZvciBIYW5kbGVycywgYnV0IG5lY2Vzc2FyeSB0byBzaW1wbGlmeSB0aGlzCisgIC8vIGludGVyZmFjZS4KKyAgUmVhZGVyKGNvbnN0IEhhbmRsZXJzKiBoYW5kbGVycywgU3RhdHVzKiBzdGF0dXMpOworICB+UmVhZGVyKCk7CisKKyAgLy8gUmVzZXRzIHRoZSByZWFkZXIncyBzdGF0ZSBhbmQgZGlzY2FyZHMgYW55IGRlZnMgaXQgbWF5IGhhdmUgYnVpbHQuCisgIHZvaWQgUmVzZXQoKTsKKworICAvLyBUaGUgcmVhZGVyJ3MgaW5wdXQ7IHRoaXMgaXMgd2hlcmUgZGVzY3JpcHRvci5wcm90byBkYXRhIHNob3VsZCBiZSBzZW50LgorICBTaW5rKiBpbnB1dCgpOworCisgIC8vIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGRlZnMgdGhhdCBoYXZlIGJlZW4gcGFyc2VkLCBhbmQgdHJhbnNmZXJzIG93bmVyc2hpcAorICAvLyBvZiB0aGVtIHRvICJvd25lciIuICBUaGUgbnVtYmVyIG9mIGRlZnMgaXMgc3RvcmVkIGluICpuLiAgT3duZXJzaGlwIG9mIHRoZQorICAvLyByZXR1cm5lZCBhcnJheSBpcyByZXRhaW5lZCBhbmQgaXMgaW52YWxpZGF0ZWQgYnkgYW55IG90aGVyIGNhbGwgaW50bworICAvLyBSZWFkZXIuCisgIC8vCisgIC8vIFRoZXNlIGRlZnMgYXJlIG5vdCBmcm96ZW4gb3IgcmVzb2x2ZWQ7IHRoZXkgYXJlIHJlYWR5IHRvIGJlIGFkZGVkIHRvIGEKKyAgLy8gc3ltdGFiLgorICB1cGI6OkRlZioqIEdldERlZnModm9pZCogb3duZXIsIGludCogbik7CisKKyAgLy8gQnVpbGRzIGFuZCByZXR1cm5zIGhhbmRsZXJzIGZvciB0aGUgcmVhZGVyLCBvd25lZCBieSAib3duZXIuIgorICBzdGF0aWMgSGFuZGxlcnMqIE5ld0hhbmRsZXJzKGNvbnN0IHZvaWQqIG93bmVyKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfZGVzY3JlYWRlciwKKyAgdXBiX3Npbmsgc2luazsKKyAgdXBiX2RlZmxpc3QgZGVmczsKKyAgdXBiX2Rlc2NyZWFkZXJfZnJhbWUgc3RhY2tbVVBCX01BWF9NRVNTQUdFX05FU1RJTkddOworICBpbnQgc3RhY2tfbGVuOworCisgIHVpbnQzMl90IG51bWJlcjsKKyAgY2hhciAqbmFtZTsKKyAgYm9vbCBzYXdfbnVtYmVyOworICBib29sIHNhd19uYW1lOworCisgIGNoYXIgKmRlZmF1bHRfc3RyaW5nOworCisgIHVwYl9maWVsZGRlZiAqZjsKKykpOworCitVUEJfQkVHSU5fRVhURVJOX0MgIC8vIHsKKworLy8gQyBBUEkuCit2b2lkIHVwYl9kZXNjcmVhZGVyX2luaXQodXBiX2Rlc2NyZWFkZXIgKnIsIGNvbnN0IHVwYl9oYW5kbGVycyAqaGFuZGxlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgdXBiX3N0YXR1cyAqc3RhdHVzKTsKK3ZvaWQgdXBiX2Rlc2NyZWFkZXJfdW5pbml0KHVwYl9kZXNjcmVhZGVyICpyKTsKK3ZvaWQgdXBiX2Rlc2NyZWFkZXJfcmVzZXQodXBiX2Rlc2NyZWFkZXIgKnIpOwordXBiX3NpbmsgKnVwYl9kZXNjcmVhZGVyX2lucHV0KHVwYl9kZXNjcmVhZGVyICpyKTsKK3VwYl9kZWYgKip1cGJfZGVzY3JlYWRlcl9nZXRkZWZzKHVwYl9kZXNjcmVhZGVyICpyLCB2b2lkICpvd25lciwgaW50ICpuKTsKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX2Rlc2NyZWFkZXJfbmV3aGFuZGxlcnMoY29uc3Qgdm9pZCAqb3duZXIpOworCitVUEJfRU5EX0VYVEVSTl9DICAvLyB9CisKKyNpZmRlZiBfX2NwbHVzcGx1cworLy8gQysrIGltcGxlbWVudGF0aW9uIGRldGFpbHMuIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KK25hbWVzcGFjZSB1cGIgeworbmFtZXNwYWNlIGRlc2NyaXB0b3IgeworaW5saW5lIFJlYWRlcjo6UmVhZGVyKGNvbnN0IEhhbmRsZXJzICpoLCBTdGF0dXMgKnMpIHsKKyAgdXBiX2Rlc2NyZWFkZXJfaW5pdCh0aGlzLCBoLCBzKTsKK30KK2lubGluZSBSZWFkZXI6On5SZWFkZXIoKSB7IHVwYl9kZXNjcmVhZGVyX3VuaW5pdCh0aGlzKTsgfQoraW5saW5lIHZvaWQgUmVhZGVyOjpSZXNldCgpIHsgdXBiX2Rlc2NyZWFkZXJfcmVzZXQodGhpcyk7IH0KK2lubGluZSBTaW5rKiBSZWFkZXI6OmlucHV0KCkgeyByZXR1cm4gdXBiX2Rlc2NyZWFkZXJfaW5wdXQodGhpcyk7IH0KK2lubGluZSB1cGI6OkRlZioqIFJlYWRlcjo6R2V0RGVmcyh2b2lkKiBvd25lciwgaW50KiBuKSB7CisgIHJldHVybiB1cGJfZGVzY3JlYWRlcl9nZXRkZWZzKHRoaXMsIG93bmVyLCBuKTsKK30KK30gIC8vIG5hbWVzcGFjZSBkZXNjcmlwdG9yCit9ICAvLyBuYW1lc3BhY2UgdXBiCisjZW5kaWYKKworI2VuZGlmICAvLyBVUEJfREVTQ1JJUFRPUl9ICisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIEludGVybmFsLW9ubHkgZGVmaW5pdGlvbnMgZm9yIHRoZSBkZWNvZGVyLgorICovCisKKyNpZm5kZWYgVVBCX0RFQ09ERVJfSU5UX0hfCisjZGVmaW5lIFVQQl9ERUNPREVSX0lOVF9IXworCisjaW5jbHVkZSA8c3RkbGliLmg+CisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIHVwYjo6cGI6OkRlY29kZXIgaW1wbGVtZW50cyBhIGhpZ2ggcGVyZm9ybWFuY2UsIHN0cmVhbWluZywgcmVzdW1hYmxlIGRlY29kZXIKKyAqIGZvciB0aGUgYmluYXJ5IHByb3RvYnVmIGZvcm1hdC4KKyAqCisgKiBUaGlzIGludGVyZmFjZSB3b3JrcyB0aGUgc2FtZSByZWdhcmRsZXNzIG9mIHdoYXQgZGVjb2RlciBiYWNrZW5kIGlzIGJlaW5nCisgKiB1c2VkLiAgQSBjbGllbnQgb2YgdGhpcyBjbGFzcyBkb2VzIG5vdCBuZWVkIHRvIGtub3cgd2hldGhlciBkZWNvZGluZyBpcyB1c2luZworICogYSBKSVR0ZWQgZGVjb2RlciAoRHluQVNNLCBMTFZNLCBldGMpIG9yIGFuIGludGVycHJldGVkIGRlY29kZXIuICBCeSBkZWZhdWx0LAorICogaXQgd2lsbCBhbHdheXMgdXNlIHRoZSBmYXN0ZXN0IGF2YWlsYWJsZSBkZWNvZGVyLiAgSG93ZXZlciwgeW91IGNhbiBjYWxsCisgKiBzZXRfYWxsb3dfaml0KGZhbHNlKSB0byBkaXNhYmxlIGFueSBKSVQgZGVjb2RlciB0aGF0IG1pZ2h0IGJlIGF2YWlsYWJsZS4KKyAqIFRoaXMgaXMgcHJpbWFyaWx5IHVzZWZ1bCBmb3IgdGVzdGluZyBwdXJwb3Nlcy4KKyAqLworCisjaWZuZGVmIFVQQl9ERUNPREVSX0hfCisjZGVmaW5lIFVQQl9ERUNPREVSX0hfCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBwYiB7CitjbGFzcyBDb2RlQ2FjaGU7CitjbGFzcyBEZWNvZGVyOworY2xhc3MgRGVjb2Rlck1ldGhvZDsKK2NsYXNzIERlY29kZXJNZXRob2RPcHRpb25zOworfSAgLy8gbmFtZXNwYWNlIHBiCit9ICAvLyBuYW1lc3BhY2UgdXBiCisjZW5kaWYKKworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OnBiOjpDb2RlQ2FjaGUsIHVwYl9wYmNvZGVjYWNoZSk7CitVUEJfREVDTEFSRV9UWVBFKHVwYjo6cGI6OkRlY29kZXIsIHVwYl9wYmRlY29kZXIpOworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OnBiOjpEZWNvZGVyTWV0aG9kLCB1cGJfcGJkZWNvZGVybWV0aG9kKTsKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpwYjo6RGVjb2Rlck1ldGhvZE9wdGlvbnMsIHVwYl9wYmRlY29kZXJtZXRob2RvcHRzKTsKKworLy8gVGhlIG1heGltdW0gdGhhdCBhbnkgc3VibWVzc2FnZXMgY2FuIGJlIG5lc3RlZC4gIE1hdGNoZXMgcHJvdG8yJ3MgbGltaXQuCisvLyBUaGlzIHNwZWNpZmllcyB0aGUgc2l6ZSBvZiB0aGUgZGVjb2RlcidzIHN0YXRpY2FsbHktc2l6ZWQgYXJyYXkgYW5kIHRoZXJlZm9yZQorLy8gc2V0dGluZyBpdCBoaWdoIHdpbGwgY2F1c2UgdGhlIHVwYjo6cGI6OkRlY29kZXIgb2JqZWN0IHRvIGJlIGxhcmdlci4KKy8vCisvLyBJZiBuZWNlc3Nhcnkgd2UgY2FuIGFkZCBhIHJ1bnRpbWUtc2V0dGFibGUgcHJvcGVydHkgdG8gRGVjb2RlciB0aGF0IGFsbG93CisvLyB0aGlzIHRvIGJlIGxhcmdlciB0aGFuIHRoZSBjb21waWxlLXRpbWUgc2V0dGluZywgYnV0IHRoaXMgd291bGQgYWRkCisvLyBjb21wbGV4aXR5LCBwYXJ0aWN1bGFybHkgc2luY2Ugd2Ugd291bGQgaGF2ZSB0byBkZWNpZGUgaG93L2lmIHRvIGdpdmUgdXNlcnMKKy8vIHRoZSBhYmlsaXR5IHRvIHNldCBhIGN1c3RvbSBtZW1vcnkgYWxsb2NhdGlvbiBmdW5jdGlvbi4KKyNkZWZpbmUgVVBCX0RFQ09ERVJfTUFYX05FU1RJTkcgNjQKKworLy8gSW50ZXJuYWwtb25seSBzdHJ1Y3QgdXNlZCBieSB0aGUgZGVjb2Rlci4KK3R5cGVkZWYgc3RydWN0IHsKKyBVUEJfUFJJVkFURV9GT1JfQ1BQCisgIC8vIFNwYWNlIG9wdGltaXphdGlvbiBub3RlOiB3ZSBzdG9yZSB0d28gcG9pbnRlcnMgaGVyZSB0aGF0IHRoZSBKSVQKKyAgLy8gZG9lc24ndCBuZWVkIGF0IGFsbDsgdGhlIHVwYl9oYW5kbGVycyogaW5zaWRlIHRoZSBzaW5rIGFuZAorICAvLyB0aGUgZGlzcGF0Y2ggdGFibGUgcG9pbnRlci4gIFdlIGNhbiBvcHRpbXplIHNvIHRoYXQgdGhlIEpJVCB1c2VzCisgIC8vIHNtYWxsZXIgc3RhY2sgZnJhbWVzIHRoYW4gdGhlIGludGVycHJldGVyLiAgVGhlIG9ubHkgdGhpbmcgd2UgbmVlZAorICAvLyB0byBndWFyYW50ZWUgaXMgdGhhdCB0aGUgZmFsbGJhY2sgcm91dGluZXMgY2FuIGZpbmQgZW5kX29mcy4KKyAgdXBiX3Npbmsgc2luazsKKworICAvLyBUaGUgYWJzb2x1dGUgc3RyZWFtIG9mZnNldCBvZiB0aGUgZW5kLW9mLWZyYW1lIGRlbGltaXRlci4KKyAgLy8gTm9uLWRlbGltaXRlZCBmcmFtZXMgKGdyb3VwcyBhbmQgbm9uLXBhY2tlZCByZXBlYXRlZCBmaWVsZHMpIHJldXNlIHRoZQorICAvLyBkZWxpbWl0ZXIgb2YgdGhlaXIgcGFyZW50LCBldmVuIHRob3VnaCB0aGUgZnJhbWUgbWF5IG5vdCBlbmQgdGhlcmUuCisgIC8vCisgIC8vIE5PVEU6IHRoZSBKSVQgc3RvcmVzIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHZhbHVlIGhlcmUgZm9yIG5vbi10b3AgZnJhbWVzLgorICAvLyBJdCBzdG9yZXMgdGhlIHZhbHVlIHJlbGF0aXZlIHRvIHRoZSBlbmQgb2YgdGhlIGVuY2xvc2VkIG1lc3NhZ2UuICBCdXQgdGhlCisgIC8vIHRvcCBmcmFtZSBpcyBzdGlsbCBzdG9yZWQgdGhlIHNhbWUgd2F5LCB3aGljaCBpcyBpbXBvcnRhbnQgZm9yIGVuc3VyaW5nCisgIC8vIHRoYXQgY2FsbHMgZnJvbSB0aGUgSklUIGludG8gQyB3b3JrIGNvcnJlY3RseS4KKyAgdWludDY0X3QgZW5kX29mczsKKyAgY29uc3QgdWludDMyX3QgKmJhc2U7CisKKyAgLy8gMCBpbmRpY2F0ZXMgYSBsZW5ndGgtZGVsaW1pdGVkIGZpZWxkLgorICAvLyBBIHBvc2l0aXZlIG51bWJlciBpbmRpY2F0ZXMgYSBrbm93biBncm91cC4KKyAgLy8gQSBuZWdhdGl2ZSBudW1iZXIgaW5kaWNhdGVzIGFuIHVua25vd24gZ3JvdXAuCisgIGludDMyX3QgZ3JvdXBudW07CisgIHVwYl9pbnR0YWJsZSAqZGlzcGF0Y2g7ICAvLyBOb3QgdXNlZCBieSB0aGUgSklULgorfSB1cGJfcGJkZWNvZGVyX2ZyYW1lOworCisvLyBUaGUgcGFyYW1ldGVycyBvbmUgdXNlcyB0byBjb25zdHJ1Y3QgYSBEZWNvZGVyTWV0aG9kLgorLy8gVE9ETyhoYWJlcm1hbik6IG1vdmUgYWxsb3dqaXQgaGVyZT8gIFNlZW1zIG1vcmUgY29udmVuaWVudCBmb3IgdXNlcnMuCitVUEJfREVGSU5FX0NMQVNTMCh1cGI6OnBiOjpEZWNvZGVyTWV0aG9kT3B0aW9ucywKKyBwdWJsaWM6CisgIC8vIFBhcmFtZXRlciByZXByZXNlbnRzIHRoZSBkZXN0aW5hdGlvbiBoYW5kbGVycyB0aGF0IHRoaXMgbWV0aG9kIHdpbGwgcHVzaAorICAvLyB0by4KKyAgZXhwbGljaXQgRGVjb2Rlck1ldGhvZE9wdGlvbnMoY29uc3QgSGFuZGxlcnMqIGRlc3RfaGFuZGxlcnMpOworCisgIC8vIFNob3VsZCB0aGUgZGVjb2RlciBwdXNoIHN1Ym1lc3NhZ2VzIHRvIGxhenkgaGFuZGxlcnMgZm9yIGZpZWxkcyB0aGF0IGhhdmUKKyAgLy8gdGhlbT8gIFRoZSBjYWxsZXIgc2hvdWxkIHNldCB0aGlzIGlmZiB0aGUgbGF6eSBoYW5kbGVycyBleHBlY3QgZGF0YSB0aGF0IGlzCisgIC8vIGluIHByb3RvYnVmIGJpbmFyeSBmb3JtYXQgYW5kIHRoZSBjYWxsZXIgd2lzaGVzIHRvIGxhenkgcGFyc2UgaXQuCisgIHZvaWQgc2V0X2xhenkoYm9vbCBsYXp5KTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfcGJkZWNvZGVybWV0aG9kb3B0cywKKyAgY29uc3QgdXBiX2hhbmRsZXJzICpoYW5kbGVyczsKKyAgYm9vbCBsYXp5OworKSk7CisKKy8vIFJlcHJlc2VudHMgdGhlIGNvZGUgdG8gcGFyc2UgYSBwcm90b2J1ZiBhY2NvcmRpbmcgdG8gYSBkZXN0aW5hdGlvbiBIYW5kbGVycy4KK1VQQl9ERUZJTkVfQ0xBU1MxKHVwYjo6cGI6OkRlY29kZXJNZXRob2QsIHVwYjo6UmVmQ291bnRlZCwKKyBwdWJsaWM6CisgIC8vIEZyb20gdXBiOjpSZWZlcmVuY2VDb3VudGVkLgorICB2b2lkIFJlZihjb25zdCB2b2lkKiBvd25lcikgY29uc3Q7CisgIHZvaWQgVW5yZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworICB2b2lkIERvbmF0ZVJlZihjb25zdCB2b2lkKiBmcm9tLCBjb25zdCB2b2lkKiB0bykgY29uc3Q7CisgIHZvaWQgQ2hlY2tSZWYoY29uc3Qgdm9pZCogb3duZXIpIGNvbnN0OworCisgIC8vIFRoZSBkZXN0aW5hdGlvbiBoYW5kbGVycyB0aGF0IGFyZSBzdGF0aWNhbGx5IGJvdW5kIHRvIHRoaXMgbWV0aG9kLgorICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGNhcGFibGUgb2Ygb3V0cHV0dGluZyB0byBhIHNpbmsgdGhhdCB1c2VzIHRoZXNlCisgIC8vIGhhbmRsZXJzLgorICBjb25zdCBIYW5kbGVycyogZGVzdF9oYW5kbGVycygpIGNvbnN0OworCisgIC8vIFRoZSBpbnB1dCBoYW5kbGVycyBmb3IgdGhpcyBkZWNvZGVyIG1ldGhvZC4KKyAgY29uc3QgQnl0ZXNIYW5kbGVyKiBpbnB1dF9oYW5kbGVyKCkgY29uc3Q7CisKKyAgLy8gV2hldGhlciB0aGlzIG1ldGhvZCBpcyBuYXRpdmUuCisgIGJvb2wgaXNfbmF0aXZlKCkgY29uc3Q7CisKKyAgLy8gQ29udmVuaWVuY2UgbWV0aG9kIGZvciBnZW5lcmF0aW5nIGEgRGVjb2Rlck1ldGhvZCB3aXRob3V0IGV4cGxpY2l0bHkKKyAgLy8gY3JlYXRpbmcgYSBDb2RlQ2FjaGUuCisgIHN0YXRpYyByZWZmZWRfcHRyPGNvbnN0IERlY29kZXJNZXRob2Q+IE5ldyhjb25zdCBEZWNvZGVyTWV0aG9kT3B0aW9ucyYgb3B0cyk7CisKKyBwcml2YXRlOgorICBVUEJfRElTQUxMT1dfUE9EX09QUyhEZWNvZGVyTWV0aG9kLCB1cGI6OnBiOjpEZWNvZGVyTWV0aG9kKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUKHVwYl9wYmRlY29kZXJtZXRob2QsIHVwYl9yZWZjb3VudGVkLAorICAvLyBXaGlsZSBjb21waWxpbmcsIHRoZSBiYXNlIGlzIHJlbGF0aXZlIGluICJvZnMiLCBhZnRlciBjb21waWxpbmcgaXQgaXMKKyAgLy8gYWJzb2x1dGUgaW4gInB0ciIuCisgIHVuaW9uIHsKKyAgICB1aW50MzJfdCBvZnM7ICAgICAvLyBQQyBvZmZzZXQgb2YgbWV0aG9kLgorICAgIHZvaWQgKnB0cjsgICAgICAgIC8vIFBvaW50ZXIgdG8gYnl0ZWNvZGUgb3IgbWFjaGluZSBjb2RlIGZvciB0aGlzIG1ldGhvZC4KKyAgfSBjb2RlX2Jhc2U7CisKKyAgLy8gVGhlIGRlY29kZXIgbWV0aG9kIGdyb3VwIHRvIHdoaWNoIHRoaXMgbWV0aG9kIGJlbG9uZ3MuICBXZSBvd24gYSByZWYuCisgIC8vIE93bmluZyBhIHJlZiBvbiB0aGUgZW50aXJlIGdyb3VwIGlzIG1vcmUgY29hcnNlLWdyYWluZWQgdGhhbiBpcyBzdHJpY3RseQorICAvLyBuZWNlc3Nhcnk7IGFsbCB3ZSB0cnVseSByZXF1aXJlIGlzIHRoYXQgbWV0aG9kcyB3ZSBkaXJlY3RseSByZWZlcmVuY2UKKyAgLy8gb3V0bGl2ZSB1cywgd2hpbGUgdGhlIGdyb3VwIGNvdWxkIGNvbnRhaW4gbWFueSBvdGhlciBtZXNzYWdlcyB3ZSBkb24ndAorICAvLyByZXF1aXJlLiAgQnV0IHRoZSBncm91cCByZXByZXNlbnRzIHRoZSBtZXNzYWdlcyB0aGF0IHdlcmUKKyAgLy8gYWxsb2NhdGVkK2NvbXBpbGVkIHRvZ2V0aGVyLCBzbyBpdCBtYWtlcyB0aGUgbW9zdCBzZW5zZSB0byBmcmVlIHRoZW0KKyAgLy8gdG9nZXRoZXIgYWxzby4KKyAgY29uc3QgdXBiX3JlZmNvdW50ZWQgKmdyb3VwOworCisgIC8vIFdoZXRoZXIgdGhpcyBtZXRob2QgaXMgbmF0aXZlIGNvZGUgb3IgYnl0ZWNvZGUuCisgIGJvb2wgaXNfbmF0aXZlXzsKKworICAvLyBUaGUgaGFuZGxlciBvbmUgY2FsbHMgdG8gaW52b2tlIHRoaXMgbWV0aG9kLgorICB1cGJfYnl0ZXNoYW5kbGVyIGlucHV0X2hhbmRsZXJfOworCisgIC8vIFRoZSBkZXN0aW5hdGlvbiBoYW5kbGVycyB0aGlzIG1ldGhvZCBpcyBib3VuZCB0by4gIFdlIG93biBhIHJlZi4KKyAgY29uc3QgdXBiX2hhbmRsZXJzICpkZXN0X2hhbmRsZXJzXzsKKworICAvLyBEaXNwYXRjaCB0YWJsZSAtLSB1c2VkIGJ5IGJvdGggYnl0ZWNvZGUgZGVjb2RlciBhbmQgSklUIHdoZW4gZW5jb3VudGVyaW5nIGEKKyAgLy8gZmllbGQgbnVtYmVyIHRoYXQgd2Fzbid0IHRoZSBvbmUgd2Ugd2VyZSBleHBlY3RpbmcgdG8gc2VlLiAgU2VlCisgIC8vIGRlY29kZXIuaW50LmggZm9yIHRoZSBsYXlvdXQgb2YgdGhpcyB0YWJsZS4KKyAgdXBiX2ludHRhYmxlIGRpc3BhdGNoOworKSk7CisKKy8vIEEgRGVjb2RlciByZWNlaXZlcyBiaW5hcnkgcHJvdG9idWYgZGF0YSBvbiBpdHMgaW5wdXQgc2luayBhbmQgcHVzaGVzIHRoZQorLy8gZGVjb2RlZCBkYXRhIHRvIGl0cyBvdXRwdXQgc2luay4KK1VQQl9ERUZJTkVfQ0xBU1MwKHVwYjo6cGI6OkRlY29kZXIsCisgcHVibGljOgorICAvLyBDb25zdHJ1Y3RzIGEgZGVjb2RlciBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIG1ldGhvZCwgd2hpY2ggbXVzdCBvdXRsaXZlIHRoaXMKKyAgLy8gZGVjb2Rlci4gIEFueSBlcnJvcnMgZHVyaW5nIHBhcnNpbmcgd2lsbCBiZSBzZXQgb24gdGhlIGdpdmVuIHN0YXR1cywgd2hpY2gKKyAgLy8gbXVzdCBhbHNvIG91dGxpdmUgdGhpcyBkZWNvZGVyLgorICBEZWNvZGVyKGNvbnN0IERlY29kZXJNZXRob2QqIG1ldGhvZCwgU3RhdHVzKiBzdGF0dXMpOworICB+RGVjb2RlcigpOworCisgIC8vIFJldHVybnMgdGhlIERlY29kZXJNZXRob2QgdGhpcyBkZWNvZGVyIGlzIHBhcnNpbmcgZnJvbS4KKyAgLy8gVE9ETyhoYWJlcm1hbik6IERvIHVzZXJzIG5lZWQgdG8gYmUgYWJsZSB0byByZWJpbmQgdGhpcz8KKyAgY29uc3QgRGVjb2Rlck1ldGhvZCogbWV0aG9kKCkgY29uc3Q7CisKKyAgLy8gUmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgZGVjb2Rlci4KKyAgdm9pZCBSZXNldCgpOworCisgIC8vIFJldHVybnMgbnVtYmVyIG9mIGJ5dGVzIHN1Y2Nlc3NmdWxseSBwYXJzZWQuCisgIC8vCisgIC8vIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgZGV0ZXJtaW5pbmcgdGhlIHN0cmVhbSBwb3NpdGlvbiB3aGVyZSBhbiBlcnJvcgorICAvLyBvY2N1cnJlZC4KKyAgLy8KKyAgLy8gVGhpcyB2YWx1ZSBtYXkgbm90IGJlIHVwLXRvLWRhdGUgd2hlbiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwYXJzaW5nCisgIC8vIGNhbGxiYWNrLgorICB1aW50NjRfdCBCeXRlc1BhcnNlZCgpIGNvbnN0OworCisgIC8vIFJlc2V0cyB0aGUgb3V0cHV0IHNpbmsgb2YgdGhlIERlY29kZXIuCisgIC8vIFRoZSBnaXZlbiBzaW5rIG11c3QgbWF0Y2ggbWV0aG9kKCktPmRlc3RfaGFuZGxlcnMoKS4KKyAgLy8KKyAgLy8gVGhpcyBtdXN0IGJlIGNhbGxlZCBhdCBsZWFzdCBvbmNlIGJlZm9yZSB0aGUgZGVjb2RlciBjYW4gYmUgdXNlZC4gIEl0IG1heQorICAvLyBvbmx5IGJlIGNhbGxlZCB3aXRoIHRoZSBkZWNvZGVyIGlzIGluIGEgc3RhdGUgd2hlcmUgaXQgd2FzIGp1c3QgY3JlYXRlZCBvcgorICAvLyByZXNldCB3aXRoIHBpcGVsaW5lLlJlc2V0KCkuICBUaGUgZ2l2ZW4gc2luayBtdXN0IGJlIGZyb20gdGhlIHNhbWUgcGlwZWxpbmUKKyAgLy8gYXMgdGhpcyBkZWNvZGVyLgorICBib29sIFJlc2V0T3V0cHV0KFNpbmsqIHNpbmspOworCisgIC8vIFRoZSBzaW5rIG9uIHdoaWNoIHRoaXMgZGVjb2RlciByZWNlaXZlcyBpbnB1dC4KKyAgQnl0ZXNTaW5rKiBpbnB1dCgpOworCisgcHJpdmF0ZToKKyAgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihEZWNvZGVyKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfcGJkZWNvZGVyLCBVUEJfUVVPVEUoCisgIC8vIE91ciBpbnB1dCBzaW5rLgorICB1cGJfYnl0ZXNzaW5rIGlucHV0XzsKKworICAvLyBUaGUgZGVjb2RlciBtZXRob2Qgd2UgYXJlIHBhcnNpbmcgd2l0aCAob3duZWQpLgorICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptZXRob2RfOworCisgIHNpemVfdCBjYWxsX2xlbjsKKyAgY29uc3QgdWludDMyX3QgKnBjLCAqbGFzdDsKKworICAvLyBDdXJyZW50IGlucHV0IGJ1ZmZlciBhbmQgaXRzIHN0cmVhbSBvZmZzZXQuCisgIGNvbnN0IGNoYXIgKmJ1ZiwgKnB0ciwgKmVuZCwgKmNoZWNrcG9pbnQ7CisKKyAgLy8gRW5kIG9mIHRoZSBkZWxpbWl0ZWQgcmVnaW9uLCByZWxhdGl2ZSB0byBwdHIsIG9yIE5VTEwgaWYgbm90IGluIHRoaXMgYnVmLgorICBjb25zdCBjaGFyICpkZWxpbV9lbmQ7CisKKyAgLy8gRW5kIG9mIHRoZSBkZWxpbWl0ZWQgcmVnaW9uLCByZWxhdGl2ZSB0byBwdHIsIG9yIGVuZCBpZiBub3QgaW4gdGhpcyBidWYuCisgIGNvbnN0IGNoYXIgKmRhdGFfZW5kOworCisgIC8vIE92ZXJhbGwgc3RyZWFtIG9mZnNldCBvZiAiYnVmLiIKKyAgdWludDY0X3QgYnVmc3RhcnRfb2ZzOworCisgIC8vIEJ1ZmZlciBmb3IgcmVzaWR1YWwgYnl0ZXMgbm90IHBhcnNlZCBmcm9tIHRoZSBwcmV2aW91cyBidWZmZXIuCisgIC8vIFRoZSBtYXhpbXVtIG51bWJlciBvZiByZXNpZHVhbCBieXRlcyB3ZSByZXF1aXJlIGlzIDEyOyBhIGZpdmUtYnl0ZQorICAvLyB1bmtub3duIHRhZyBwbHVzIGFuIGVpZ2h0LWJ5dGUgdmFsdWUsIGxlc3Mgb25lIGJlY2F1c2UgdGhlIHZhbHVlCisgIC8vIGlzIG9ubHkgYSBwYXJ0aWFsIHZhbHVlLgorICBjaGFyIHJlc2lkdWFsWzEyXTsKKyAgY2hhciAqcmVzaWR1YWxfZW5kOworCisgIC8vIFN0b3JlcyB0aGUgdXNlciBidWZmZXIgcGFzc2VkIHRvIG91ciBkZWNvZGUgZnVuY3Rpb24uCisgIGNvbnN0IGNoYXIgKmJ1Zl9wYXJhbTsKKyAgc2l6ZV90IHNpemVfcGFyYW07CisgIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZTsKKworI2lmZGVmIFVQQl9VU0VfSklUX1g2NAorICAvLyBVc2VkIG1vbWVudGFyaWx5IGJ5IHRoZSBnZW5lcmF0ZWQgY29kZSB0byBzdG9yZSBhIHZhbHVlIHdoaWxlIGEgdXNlcgorICAvLyBmdW5jdGlvbiBpcyBjYWxsZWQuCisgIHVpbnQzMl90IHRtcF9sZW47CisKKyAgY29uc3Qgdm9pZCAqc2F2ZWRfcnNwOworI2VuZGlmCisKKyAgdXBiX3N0YXR1cyAqc3RhdHVzOworCisgIC8vIE91ciBpbnRlcm5hbCBzdGFjay4KKyAgdXBiX3BiZGVjb2Rlcl9mcmFtZSAqdG9wLCAqbGltaXQ7CisgIHVwYl9wYmRlY29kZXJfZnJhbWUgc3RhY2tbVVBCX0RFQ09ERVJfTUFYX05FU1RJTkddOworI2lmZGVmIFVQQl9VU0VfSklUX1g2NAorICAvLyBFYWNoIG5hdGl2ZSBzdGFjayBmcmFtZSBuZWVkcyB0d28gcG9pbnRlcnMsIHBsdXMgd2UgbmVlZCBhIGZldyBmcmFtZXMgZm9yCisgIC8vIHRoZSBlbnRlci9leGl0IHRyYW1wb2xpbmVzLgorICBjb25zdCB1aW50MzJfdCAqY2FsbHN0YWNrWyhVUEJfREVDT0RFUl9NQVhfTkVTVElORyAqIDIpICsgMTBdOworI2Vsc2UKKyAgY29uc3QgdWludDMyX3QgKmNhbGxzdGFja1tVUEJfREVDT0RFUl9NQVhfTkVTVElOR107CisjZW5kaWYKKykpKTsKKworLy8gQSBjbGFzcyBmb3IgY2FjaGluZyBwcm90b2J1ZiBwcm9jZXNzaW5nIGNvZGUsIHdoZXRoZXIgYnl0ZWNvZGUgZm9yIHRoZQorLy8gaW50ZXJwcmV0ZWQgZGVjb2RlciBvciBtYWNoaW5lIGNvZGUgZm9yIHRoZSBKSVQuCisvLworLy8gVGhpcyBjbGFzcyBpcyBub3QgdGhyZWFkLXNhZmUuCitVUEJfREVGSU5FX0NMQVNTMCh1cGI6OnBiOjpDb2RlQ2FjaGUsCisgcHVibGljOgorICBDb2RlQ2FjaGUoKTsKKyAgfkNvZGVDYWNoZSgpOworCisgIC8vIFdoZXRoZXIgdGhlIGNhY2hlIGlzIGFsbG93ZWQgdG8gZ2VuZXJhdGUgbWFjaGluZSBjb2RlLiAgRGVmYXVsdHMgdG8gdHJ1ZS4KKyAgLy8gVGhlcmUgaXMgbm8gcmVhbCByZWFzb24gdG8gdHVybiBpdCBvZmYgZXhjZXB0IGZvciB0ZXN0aW5nIG9yIGlmIHlvdSBhcmUKKyAgLy8gaGF2aW5nIGEgc3BlY2lmaWMgcHJvYmxlbSB3aXRoIHRoZSBKSVQuCisgIC8vCisgIC8vIE5vdGUgdGhhdCBhbGxvd19qaXQgPSB0cnVlIGRvZXMgbm90ICpndWFyYW50ZWUqIHRoYXQgdGhlIGNvZGUgd2lsbCBiZSBKSVQKKyAgLy8gY29tcGlsZWQuICBJZiB0aGlzIHBsYXRmb3JtIGlzIG5vdCBzdXBwb3J0ZWQgb3IgdGhlIEpJVCB3YXMgbm90IGNvbXBpbGVkCisgIC8vIGluLCB0aGUgY29kZSBtYXkgc3RpbGwgYmUgaW50ZXJwcmV0ZWQuCisgIGJvb2wgYWxsb3dfaml0KCkgY29uc3Q7CisKKyAgLy8gVGhpcyBtYXkgb25seSBiZSBjYWxsZWQgd2hlbiB0aGUgb2JqZWN0IGlzIGZpcnN0IGNvbnN0cnVjdGVkLCBhbmQgcHJpb3IgdG8KKyAgLy8gYW55IGNvZGUgZ2VuZXJhdGlvbiwgb3RoZXJ3aXNlIHJldHVybnMgZmFsc2UgYW5kIGRvZXMgbm90aGluZy4KKyAgYm9vbCBzZXRfYWxsb3dfaml0KGJvb2wgYWxsb3cpOworCisgIC8vIFJldHVybnMgYSBEZWNvZGVyTWV0aG9kIHRoYXQgY2FuIHB1c2ggZGF0YSB0byB0aGUgZ2l2ZW4gaGFuZGxlcnMuCisgIC8vIElmIGEgc3VpdGFibGUgbWV0aG9kIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIHJldHVybmVkIGZyb20gdGhlIGNhY2hlLgorICAvLworICAvLyBTcGVjaWZ5aW5nIHRoZSBkZXN0aW5hdGlvbiBoYW5kbGVycyBoZXJlIGFsbG93cyB0aGUgRGVjb2Rlck1ldGhvZCB0byBiZQorICAvLyBzdGF0aWNhbGx5IGJvdW5kIHRvIHRoZSBkZXN0aW5hdGlvbiBoYW5kbGVycyBpZiBwb3NzaWJsZSwgd2hpY2ggY2FuIGFsbG93CisgIC8vIG1vcmUgZWZmaWNpZW50IGRlY29kaW5nLiAgSG93ZXZlciB0aGUgcmV0dXJuZWQgbWV0aG9kIG1heSBvciBtYXkgbm90CisgIC8vIGFjdHVhbGx5IGJlIHN0YXRpY2FsbHkgYm91bmQuICBCdXQgaW4gYWxsIGNhc2VzLCB0aGUgcmV0dXJuZWQgbWV0aG9kIGNhbgorICAvLyBwdXNoIGRhdGEgdG8gdGhlIGdpdmVuIGhhbmRsZXJzLgorICBjb25zdCBEZWNvZGVyTWV0aG9kICpHZXREZWNvZGVyTWV0aG9kKGNvbnN0IERlY29kZXJNZXRob2RPcHRpb25zJiBvcHRzKTsKKworICAvLyBJZi93aGVuIHNvbWVvbmUgbmVlZHMgdG8gZXhwbGljaXRseSBjcmVhdGUgYSBkeW5hbWljYWxseS1ib3VuZAorICAvLyBEZWNvZGVyTWV0aG9kKiwgd2UgY2FuIGFkZCBhIG1ldGhvZCB0byBnZXQgaXQgaGVyZS4KKworIHByaXZhdGU6CisgIFVQQl9ESVNBTExPV19DT1BZX0FORF9BU1NJR04oQ29kZUNhY2hlKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfcGJjb2RlY2FjaGUsCisgIGJvb2wgYWxsb3dfaml0XzsKKworICAvLyBBcnJheSBvZiBtZ3JvdXBzLgorICB1cGJfaW50dGFibGUgZ3JvdXBzOworKSk7CisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCit2b2lkIHVwYl9wYmRlY29kZXJfaW5pdCh1cGJfcGJkZWNvZGVyICpkLCBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzdGF0dXMpOwordm9pZCB1cGJfcGJkZWNvZGVyX3VuaW5pdCh1cGJfcGJkZWNvZGVyICpkKTsKK3ZvaWQgdXBiX3BiZGVjb2Rlcl9yZXNldCh1cGJfcGJkZWNvZGVyICpkKTsKK2NvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKnVwYl9wYmRlY29kZXJfbWV0aG9kKGNvbnN0IHVwYl9wYmRlY29kZXIgKmQpOworYm9vbCB1cGJfcGJkZWNvZGVyX3Jlc2V0b3V0cHV0KHVwYl9wYmRlY29kZXIgKmQsIHVwYl9zaW5rICpzaW5rKTsKK3VwYl9ieXRlc3NpbmsgKnVwYl9wYmRlY29kZXJfaW5wdXQodXBiX3BiZGVjb2RlciAqZCk7Cit1aW50NjRfdCB1cGJfcGJkZWNvZGVyX2J5dGVzcGFyc2VkKGNvbnN0IHVwYl9wYmRlY29kZXIgKmQpOworCit2b2lkIHVwYl9wYmRlY29kZXJtZXRob2RvcHRzX2luaXQodXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHMgKm9wdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBiX2hhbmRsZXJzICpoKTsKK3ZvaWQgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfc2V0bGF6eSh1cGJfcGJkZWNvZGVybWV0aG9kb3B0cyAqb3B0cywgYm9vbCBsYXp5KTsKKwordm9pZCB1cGJfcGJkZWNvZGVybWV0aG9kX3JlZihjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptLCBjb25zdCB2b2lkICpvd25lcik7Cit2b2lkIHVwYl9wYmRlY29kZXJtZXRob2RfdW5yZWYoY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSwgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfcGJkZWNvZGVybWV0aG9kX2RvbmF0ZXJlZihjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICptLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpmcm9tLCBjb25zdCB2b2lkICp0byk7Cit2b2lkIHVwYl9wYmRlY29kZXJtZXRob2RfY2hlY2tyZWYoY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpvd25lcik7Citjb25zdCB1cGJfaGFuZGxlcnMgKnVwYl9wYmRlY29kZXJtZXRob2RfZGVzdGhhbmRsZXJzKAorICAgIGNvbnN0IHVwYl9wYmRlY29kZXJtZXRob2QgKm0pOworY29uc3QgdXBiX2J5dGVzaGFuZGxlciAqdXBiX3BiZGVjb2Rlcm1ldGhvZF9pbnB1dGhhbmRsZXIoCisgICAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSk7Citib29sIHVwYl9wYmRlY29kZXJtZXRob2RfaXNuYXRpdmUoY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSk7Citjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kICp1cGJfcGJkZWNvZGVybWV0aG9kX25ldygKKyAgICBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kb3B0cyAqb3B0cywgY29uc3Qgdm9pZCAqb3duZXIpOworCit2b2lkIHVwYl9wYmNvZGVjYWNoZV9pbml0KHVwYl9wYmNvZGVjYWNoZSAqYyk7Cit2b2lkIHVwYl9wYmNvZGVjYWNoZV91bmluaXQodXBiX3BiY29kZWNhY2hlICpjKTsKK2Jvb2wgdXBiX3BiY29kZWNhY2hlX2FsbG93aml0KGNvbnN0IHVwYl9wYmNvZGVjYWNoZSAqYyk7Citib29sIHVwYl9wYmNvZGVjYWNoZV9zZXRhbGxvd2ppdCh1cGJfcGJjb2RlY2FjaGUgKmMsIGJvb2wgYWxsb3cpOworY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqdXBiX3BiY29kZWNhY2hlX2dldGRlY29kZXJtZXRob2QoCisgICAgdXBiX3BiY29kZWNhY2hlICpjLCBjb25zdCB1cGJfcGJkZWNvZGVybWV0aG9kb3B0cyAqb3B0cyk7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworI2lmZGVmIF9fY3BsdXNwbHVzCisKK25hbWVzcGFjZSB1cGIgeworCituYW1lc3BhY2UgcGIgeworCitpbmxpbmUgRGVjb2Rlcjo6RGVjb2Rlcihjb25zdCBEZWNvZGVyTWV0aG9kKiBtLCBTdGF0dXMqIHMpIHsKKyAgdXBiX3BiZGVjb2Rlcl9pbml0KHRoaXMsIG0sIHMpOworfQoraW5saW5lIERlY29kZXI6On5EZWNvZGVyKCkgeworICB1cGJfcGJkZWNvZGVyX3VuaW5pdCh0aGlzKTsKK30KK2lubGluZSBjb25zdCBEZWNvZGVyTWV0aG9kKiBEZWNvZGVyOjptZXRob2QoKSBjb25zdCB7CisgIHJldHVybiB1cGJfcGJkZWNvZGVyX21ldGhvZCh0aGlzKTsKK30KK2lubGluZSB2b2lkIERlY29kZXI6OlJlc2V0KCkgeworICB1cGJfcGJkZWNvZGVyX3Jlc2V0KHRoaXMpOworfQoraW5saW5lIHVpbnQ2NF90IERlY29kZXI6OkJ5dGVzUGFyc2VkKCkgY29uc3QgeworICByZXR1cm4gdXBiX3BiZGVjb2Rlcl9ieXRlc3BhcnNlZCh0aGlzKTsKK30KK2lubGluZSBib29sIERlY29kZXI6OlJlc2V0T3V0cHV0KFNpbmsqIHNpbmspIHsKKyAgcmV0dXJuIHVwYl9wYmRlY29kZXJfcmVzZXRvdXRwdXQodGhpcywgc2luayk7Cit9CitpbmxpbmUgQnl0ZXNTaW5rKiBEZWNvZGVyOjppbnB1dCgpIHsKKyAgcmV0dXJuIHVwYl9wYmRlY29kZXJfaW5wdXQodGhpcyk7Cit9CisKK2lubGluZSBEZWNvZGVyTWV0aG9kT3B0aW9uczo6RGVjb2Rlck1ldGhvZE9wdGlvbnMoY29uc3QgSGFuZGxlcnMqIGgpIHsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfaW5pdCh0aGlzLCBoKTsKK30KK2lubGluZSB2b2lkIERlY29kZXJNZXRob2RPcHRpb25zOjpzZXRfbGF6eShib29sIGxhenkpIHsKKyAgdXBiX3BiZGVjb2Rlcm1ldGhvZG9wdHNfc2V0bGF6eSh0aGlzLCBsYXp5KTsKK30KKworaW5saW5lIHZvaWQgRGVjb2Rlck1ldGhvZDo6UmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdCB7CisgIHVwYl9wYmRlY29kZXJtZXRob2RfcmVmKHRoaXMsIG93bmVyKTsKK30KK2lubGluZSB2b2lkIERlY29kZXJNZXRob2Q6OlVucmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdCB7CisgIHVwYl9wYmRlY29kZXJtZXRob2RfdW5yZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIHZvaWQgRGVjb2Rlck1ldGhvZDo6RG9uYXRlUmVmKGNvbnN0IHZvaWQgKmZyb20sIGNvbnN0IHZvaWQgKnRvKSBjb25zdCB7CisgIHVwYl9wYmRlY29kZXJtZXRob2RfZG9uYXRlcmVmKHRoaXMsIGZyb20sIHRvKTsKK30KK2lubGluZSB2b2lkIERlY29kZXJNZXRob2Q6OkNoZWNrUmVmKGNvbnN0IHZvaWQgKm93bmVyKSBjb25zdCB7CisgIHVwYl9wYmRlY29kZXJtZXRob2RfY2hlY2tyZWYodGhpcywgb3duZXIpOworfQoraW5saW5lIGNvbnN0IEhhbmRsZXJzKiBEZWNvZGVyTWV0aG9kOjpkZXN0X2hhbmRsZXJzKCkgY29uc3QgeworICByZXR1cm4gdXBiX3BiZGVjb2Rlcm1ldGhvZF9kZXN0aGFuZGxlcnModGhpcyk7Cit9CitpbmxpbmUgY29uc3QgQnl0ZXNIYW5kbGVyKiBEZWNvZGVyTWV0aG9kOjppbnB1dF9oYW5kbGVyKCkgY29uc3QgeworICByZXR1cm4gdXBiX3BiZGVjb2Rlcm1ldGhvZF9pbnB1dGhhbmRsZXIodGhpcyk7Cit9CitpbmxpbmUgYm9vbCBEZWNvZGVyTWV0aG9kOjppc19uYXRpdmUoKSBjb25zdCB7CisgIHJldHVybiB1cGJfcGJkZWNvZGVybWV0aG9kX2lzbmF0aXZlKHRoaXMpOworfQorLy8gc3RhdGljCitpbmxpbmUgcmVmZmVkX3B0cjxjb25zdCBEZWNvZGVyTWV0aG9kPiBEZWNvZGVyTWV0aG9kOjpOZXcoCisgICAgY29uc3QgRGVjb2Rlck1ldGhvZE9wdGlvbnMgJm9wdHMpIHsKKyAgY29uc3QgdXBiX3BiZGVjb2Rlcm1ldGhvZCAqbSA9IHVwYl9wYmRlY29kZXJtZXRob2RfbmV3KCZvcHRzLCAmbSk7CisgIHJldHVybiByZWZmZWRfcHRyPGNvbnN0IERlY29kZXJNZXRob2Q+KG0sICZtKTsKK30KKworaW5saW5lIENvZGVDYWNoZTo6Q29kZUNhY2hlKCkgeworICB1cGJfcGJjb2RlY2FjaGVfaW5pdCh0aGlzKTsKK30KK2lubGluZSBDb2RlQ2FjaGU6On5Db2RlQ2FjaGUoKSB7CisgIHVwYl9wYmNvZGVjYWNoZV91bmluaXQodGhpcyk7Cit9CitpbmxpbmUgYm9vbCBDb2RlQ2FjaGU6OmFsbG93X2ppdCgpIGNvbnN0IHsKKyAgcmV0dXJuIHVwYl9wYmNvZGVjYWNoZV9hbGxvd2ppdCh0aGlzKTsKK30KK2lubGluZSBib29sIENvZGVDYWNoZTo6c2V0X2FsbG93X2ppdChib29sIGFsbG93KSB7CisgIHJldHVybiB1cGJfcGJjb2RlY2FjaGVfc2V0YWxsb3dqaXQodGhpcywgYWxsb3cpOworfQoraW5saW5lIGNvbnN0IERlY29kZXJNZXRob2QgKkNvZGVDYWNoZTo6R2V0RGVjb2Rlck1ldGhvZCgKKyAgICBjb25zdCBEZWNvZGVyTWV0aG9kT3B0aW9ucyYgb3B0cykgeworICByZXR1cm4gdXBiX3BiY29kZWNhY2hlX2dldGRlY29kZXJtZXRob2QodGhpcywgJm9wdHMpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcGIKK30gIC8vIG5hbWVzcGFjZSB1cGIKKworI2VuZGlmICAvLyBfX2NwbHVzcGx1cworCisjZW5kaWYgIC8qIFVQQl9ERUNPREVSX0hfICovCisKKy8vIE9wY29kZSBkZWZpbml0aW9ucy4gIFRoZSBjYW5vbmljYWwgbWVhbmluZyBvZiBlYWNoIG9wY29kZSBpcyBpdHMKKy8vIGltcGxlbWVudGF0aW9uIGluIHRoZSBpbnRlcnByZXRlciAodGhlIEpJVCBpcyB3cml0dGVuIHRvIG1hdGNoIHRoaXMpLgorLy8KKy8vIEFsbCBpbnN0cnVjdGlvbnMgaGF2ZSB0aGUgb3Bjb2RlIGluIHRoZSBsb3cgYnl0ZS4KKy8vIEluc3RydWN0aW9uIGZvcm1hdCBmb3IgbW9zdCBpbnN0cnVjdGlvbnMgaXM6CisvLworLy8gKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCisvLyB8ICAgICBhcmcgKDI0KSAgICAgIHwgb3AgKDgpIHwKKy8vICstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKworLy8KKy8vIEV4Y2VwdGlvbnMgYXJlIGluZGljYXRlZCBiZWxvdy4gIEEgZmV3IG9wY29kZXMgYXJlIG11bHRpLXdvcmQuCit0eXBlZGVmIGVudW0geworICAvLyBPcGNvZGVzIDEtOCwgMTMsIDE1LTE4IHBhcnNlIHRoZWlyIHJlc3BlY3RpdmUgZGVzY3JpcHRvciB0eXBlcy4KKyAgLy8gQXJnIGZvciBhbGwgb2YgdGhlc2UgaXMgdGhlIHVwYiBzZWxlY3RvciBmb3IgdGhpcyBmaWVsZC4KKyNkZWZpbmUgVCh0eXBlKSBPUF9QQVJTRV8gIyMgdHlwZSA9IFVQQl9ERVNDUklQVE9SX1RZUEVfICMjIHR5cGUKKyAgVChET1VCTEUpLCBUKEZMT0FUKSwgVChJTlQ2NCksIFQoVUlOVDY0KSwgVChJTlQzMiksIFQoRklYRUQ2NCksIFQoRklYRUQzMiksCisgIFQoQk9PTCksIFQoVUlOVDMyKSwgVChTRklYRUQzMiksIFQoU0ZJWEVENjQpLCBUKFNJTlQzMiksIFQoU0lOVDY0KSwKKyN1bmRlZiBUCisgIE9QX1NUQVJUTVNHICAgICAgID0gOSwgICAvLyBObyBhcmcuCisgIE9QX0VORE1TRyAgICAgICAgID0gMTAsICAvLyBObyBhcmcuCisgIE9QX1NUQVJUU0VRICAgICAgID0gMTEsCisgIE9QX0VORFNFUSAgICAgICAgID0gMTIsCisgIE9QX1NUQVJUU1VCTVNHICAgID0gMTQsCisgIE9QX0VORFNVQk1TRyAgICAgID0gMTksCisgIE9QX1NUQVJUU1RSICAgICAgID0gMjAsCisgIE9QX1NUUklORyAgICAgICAgID0gMjEsCisgIE9QX0VORFNUUiAgICAgICAgID0gMjIsCisKKyAgT1BfUFVTSFRBR0RFTElNICAgPSAyMywgIC8vIE5vIGFyZy4KKyAgT1BfUFVTSExFTkRFTElNICAgPSAyNCwgIC8vIE5vIGFyZy4KKyAgT1BfUE9QICAgICAgICAgICAgPSAyNSwgIC8vIE5vIGFyZy4KKyAgT1BfU0VUREVMSU0gICAgICAgPSAyNiwgIC8vIE5vIGFyZy4KKyAgT1BfU0VUQklHR1JPVVBOVU0gPSAyNywgIC8vIHR3byB3b3JkczogfCB1bnVzZWQgKDI0KSB8IG9wYyB8fCBncm91cG51bSAoMzIpIHwKKyAgT1BfQ0hFQ0tERUxJTSAgICAgPSAyOCwKKyAgT1BfQ0FMTCAgICAgICAgICAgPSAyOSwKKyAgT1BfUkVUICAgICAgICAgICAgPSAzMCwKKyAgT1BfQlJBTkNIICAgICAgICAgPSAzMSwKKworICAvLyBEaWZmZXJlbnQgb3Bjb2RlcyBkZXBlbmRpbmcgb24gaG93IG1hbnkgYnl0ZXMgZXhwZWN0ZWQuCisgIE9QX1RBRzEgICAgICAgICAgID0gMzIsICAvLyB8IGV4cGVjdGVkIHRhZyAoMTYpIHwganVtcCB0YXJnZXQgKDgpIHwgb3BjICg4KSB8CisgIE9QX1RBRzIgICAgICAgICAgID0gMzMsICAvLyB8IGV4cGVjdGVkIHRhZyAoMTYpIHwganVtcCB0YXJnZXQgKDgpIHwgb3BjICg4KSB8CisgIE9QX1RBR04gICAgICAgICAgID0gMzQsICAvLyB0aHJlZSB3b3JkczoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgfCB1bnVzZWQgKDE2KSB8IGp1bXAgdGFyZ2V0KDgpIHwgb3BjICg4KSB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgIHwgICAgICAgICAgIGV4cGVjdGVkIHRhZyAxICgzMikgICAgICAgICAgfAorICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICB8ICAgICAgICAgICBleHBlY3RlZCB0YWcgMiAoMzIpICAgICAgICAgIHwKKworICBPUF9TRVRESVNQQVRDSCAgICA9IDM1LCAgLy8gTiB3b3JkczoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgfCB1bnVzZWQgKDI0KSAgICAgICAgIHwgb3BjIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgfCB1cGJfaW50dGFibGUqICgzMiBvciA2NCkgIHwKKworICBPUF9ESVNQQVRDSCAgICAgICA9IDM2LCAgLy8gTm8gYXJnLgorCisgIE9QX0hBTFQgICAgICAgICAgID0gMzcsICAvLyBObyBhcmcuCit9IG9wY29kZTsKKworI2RlZmluZSBPUF9NQVggT1BfSEFMVAorCitVUEJfSU5MSU5FIG9wY29kZSBnZXRvcCh1aW50MzJfdCBpbnN0cikgeyByZXR1cm4gaW5zdHIgJiAweGZmOyB9CisKKy8vIE1ldGhvZCBncm91cDsgcmVwcmVzZW50cyBhIHNldCBvZiBkZWNvZGVyIG1ldGhvZHMgdGhhdCBoYWQgdGhlaXIgY29kZQorLy8gZW1pdHRlZCB0b2dldGhlciwgYW5kIG11c3QgdGhlcmVmb3JlIGJlIGZyZWVkIHRvZ2V0aGVyLiAgSW1tdXRhYmxlIG9uY2UKKy8vIGNyZWF0ZWQuICBJdCBpcyBwb3NzaWJsZSB3ZSBtYXkgd2FudCB0byBleHBvc2UgdGhpcyB0byB1c2VycyBhdCBzb21lIHBvaW50LgorLy8KKy8vIE92ZXJhbGwgb3duZXJzaGlwIG9mIERlY29kZXIgb2JqZWN0cyBsb29rcyBsaWtlIHRoaXM6CisvLworLy8gICAgICAgICAgICAgICAgKy0tLS0tLS0tLS0rCisvLyAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgPC0tLT4gRGVjb2Rlck1ldGhvZAorLy8gICAgICAgICAgICAgICAgfCBtZXRob2QgICB8CisvLyBDb2RlQ2FjaGUgLS0tPiB8ICBncm91cCAgIHwgPC0tLT4gRGVjb2Rlck1ldGhvZAorLy8gICAgICAgICAgICAgICAgfCAgICAgICAgICB8CisvLyAgICAgICAgICAgICAgICB8IChtZ3JvdXApIHwgPC0tLT4gRGVjb2Rlck1ldGhvZAorLy8gICAgICAgICAgICAgICAgKy0tLS0tLS0tLS0rCit0eXBlZGVmIHN0cnVjdCB7CisgIHVwYl9yZWZjb3VudGVkIGJhc2U7CisKKyAgLy8gTWFwcyB1cGJfbXNnZGVmL3VwYl9oYW5kbGVycyAtPiB1cGJfcGJkZWNvZGVybWV0aG9kLiAgV2Ugb3duIHJlZnMgb24gdGhlCisgIC8vIG1ldGhvZHMuCisgIHVwYl9pbnR0YWJsZSBtZXRob2RzOworCisgIC8vIFdoZW4gd2UgYWRkIHRoZSBhYmlsaXR5IHRvIGxpbmsgdG8gcHJldmlvdXNseSBleGlzdGluZyBtZ3JvdXBzLCB3ZSdsbAorICAvLyBuZWVkIGFuIGFycmF5IG9mIG1ncm91cHMgd2UgcmVmZXJlbmNlIGhlcmUsIGFuZCBvd24gcmVmcyBvbiB0aGVtLgorCisgIC8vIFRoZSBieXRlY29kZSBmb3Igb3VyIG1ldGhvZHMsIGlmIGFueSBleGlzdHMuICBPd25lZCBieSB1cy4KKyAgdWludDMyX3QgKmJ5dGVjb2RlOworICB1aW50MzJfdCAqYnl0ZWNvZGVfZW5kOworCisjaWZkZWYgVVBCX1VTRV9KSVRfWDY0CisgIC8vIEpJVC1nZW5lcmF0ZWQgbWFjaGluZSBjb2RlLCBpZiBhbnkuCisgIHVwYl9zdHJpbmdfaGFuZGxlcmZ1bmMgKmppdF9jb2RlOworICAvLyBUaGUgc2l6ZSBvZiB0aGUgaml0X2NvZGUgKHJlcXVpcmVkIHRvIG11bm1hcCgpKS4KKyAgc2l6ZV90IGppdF9zaXplOworICBjaGFyICpkZWJ1Z19pbmZvOworICB2b2lkICpkbDsKKyNlbmRpZgorfSBtZ3JvdXA7CisKKy8vIERlY29kZXIgZW50cnkgcG9pbnRzOyB1c2VkIGFzIGhhbmRsZXJzLgordm9pZCAqdXBiX3BiZGVjb2Rlcl9zdGFydGJjKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKnBjLCBzaXplX3Qgc2l6ZV9oaW50KTsKK3ZvaWQgKnVwYl9wYmRlY29kZXJfc3RhcnRqaXQodm9pZCAqY2xvc3VyZSwgY29uc3Qgdm9pZCAqaGQsIHNpemVfdCBzaXplX2hpbnQpOworc2l6ZV90IHVwYl9wYmRlY29kZXJfZGVjb2RlKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhkLCBjb25zdCBjaGFyICpidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemUsIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSk7Citib29sIHVwYl9wYmRlY29kZXJfZW5kKHZvaWQgKmNsb3N1cmUsIGNvbnN0IHZvaWQgKmhhbmRsZXJfZGF0YSk7CisKKy8vIERlY29kZXItaW50ZXJuYWwgZnVuY3Rpb25zIHRoYXQgdGhlIEpJVCBjYWxscyB0byBoYW5kbGUgZmFsbGJhY2sgcGF0aHMuCitpbnQzMl90IHVwYl9wYmRlY29kZXJfcmVzdW1lKHVwYl9wYmRlY29kZXIgKmQsIHZvaWQgKnAsIGNvbnN0IGNoYXIgKmJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemUsIGNvbnN0IHVwYl9idWZoYW5kbGUgKmhhbmRsZSk7CitzaXplX3QgdXBiX3BiZGVjb2Rlcl9zdXNwZW5kKHVwYl9wYmRlY29kZXIgKmQpOworaW50MzJfdCB1cGJfcGJkZWNvZGVyX3NraXB1bmtub3duKHVwYl9wYmRlY29kZXIgKmQsIGludDMyX3QgZmllbGRudW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCB3aXJlX3R5cGUpOworaW50MzJfdCB1cGJfcGJkZWNvZGVyX2NoZWNrdGFnX3Nsb3codXBiX3BiZGVjb2RlciAqZCwgdWludDY0X3QgZXhwZWN0ZWQpOworaW50MzJfdCB1cGJfcGJkZWNvZGVyX2RlY29kZV92YXJpbnRfc2xvdyh1cGJfcGJkZWNvZGVyICpkLCB1aW50NjRfdCAqdTY0KTsKK2ludDMyX3QgdXBiX3BiZGVjb2Rlcl9kZWNvZGVfZjMyKHVwYl9wYmRlY29kZXIgKmQsIHVpbnQzMl90ICp1MzIpOworaW50MzJfdCB1cGJfcGJkZWNvZGVyX2RlY29kZV9mNjQodXBiX3BiZGVjb2RlciAqZCwgdWludDY0X3QgKnU2NCk7Cit2b2lkIHVwYl9wYmRlY29kZXJfc2V0ZXJyKHVwYl9wYmRlY29kZXIgKmQsIGNvbnN0IGNoYXIgKm1zZyk7CisKKy8vIEVycm9yIG1lc3NhZ2VzIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIHRoZSBieXRlY29kZSBhbmQgSklUIGRlY29kZXJzLgorZXh0ZXJuIGNvbnN0IGNoYXIgKmtQYkRlY29kZXJTdGFja092ZXJmbG93OworCisvLyBBY2Nlc3MgdG8gZGVjb2RlcnBsYW4gbWVtYmVycyBuZWVkZWQgYnkgdGhlIGRlY29kZXIuCitjb25zdCBjaGFyICp1cGJfcGJkZWNvZGVyX2dldG9wbmFtZSh1bnNpZ25lZCBpbnQgb3ApOworCisvLyBKSVQgY29kZWdlbiBlbnRyeSBwb2ludC4KK3ZvaWQgdXBiX3BiZGVjb2Rlcl9qaXQobWdyb3VwICpncm91cCk7Cit2b2lkIHVwYl9wYmRlY29kZXJfZnJlZWppdChtZ3JvdXAgKmdyb3VwKTsKKworLy8gQSBzcGVjaWFsIGxhYmVsIHRoYXQgbWVhbnMgImRvIGZpZWxkIGRpc3BhdGNoIGZvciB0aGlzIG1lc3NhZ2UgYW5kIGJyYW5jaCB0bworLy8gd2hlcmV2ZXIgdGhhdCB0YWtlcyB5b3UuIgorI2RlZmluZSBMQUJFTF9ESVNQQVRDSCAwCisKKy8vIEEgc3BlY2lhbCBzbG90IGluIHRoZSBkaXNwYXRjaCB0YWJsZSB0aGF0IHN0b3JlcyB0aGUgZXBpbG9ndWUgKEVORE1TRyBhbmQvb3IKKy8vIFJFVCkgZm9yIGJyYW5jaGluZyB0byB3aGVuIHdlIGZpbmQgYW4gYXBwcm9wcmlhdGUgRU5ER1JPVVAgdGFnLgorI2RlZmluZSBESVNQQVRDSF9FTkRNU0cgMAorCisvLyBJdCdzIGltcG9ydGFudCB0byB1c2UgdGhpcyBpbnZhbGlkIHdpcmUgdHlwZSBpbnN0ZWFkIG9mIDAgKHdoaWNoIGlzIGEgdmFsaWQKKy8vIHdpcmUgdHlwZSkuCisjZGVmaW5lIE5PX1dJUkVfVFlQRSAweGZmCisKKy8vIFRoZSBkaXNwYXRjaCB0YWJsZSBsYXlvdXQgaXM6CisvLyAgIFtmaWVsZCBudW1iZXJdIC0+IFsgNDgtYml0IG9mZnNldCBdWyA4LWJpdCB3dDIgXVsgOC1iaXQgd3QxIF0KKy8vCisvLyBJZiB3dDEgbWF0Y2hlcywganVtcCB0byB0aGUgNDgtYml0IG9mZnNldC4gIElmIHd0MiBtYXRjaGVzLCBsb29rdXAKKy8vIChVUEJfTUFYX0ZJRUxETlVNQkVSICsgZmllbGRudW0pIGFuZCBqdW1wIHRoZXJlLgorLy8KKy8vIFdlIG5lZWQgdHdvIHdpcmUgdHlwZXMgYmVjYXVzZSBvZiBwYWNrZWQvbm9uLXBhY2tlZCBjb21wYXRpYmlsaXR5LiAgQQorLy8gcHJpbWl0aXZlIHJlcGVhdGVkIGZpZWxkIGNhbiB1c2UgZWl0aGVyIHdpcmUgdHlwZSBhbmQgYmUgdmFsaWQuICBXaGlsZSB3ZQorLy8gY291bGQga2V5IHRoZSB0YWJsZSBvbiBmaWVsZG51bSt3aXJldHlwZSwgdGhlIHRhYmxlIHdvdWxkIGJlIDh4IHNwYXJzZXIuCisvLworLy8gU3RvcmluZyB0d28gd2lyZSB0eXBlcyBpbiB0aGUgcHJpbWFyeSB2YWx1ZSBhbGxvd3MgdXMgdG8gcXVpY2tseSBydWxlIG91dAorLy8gdGhlIHNlY29uZCB3aXJlIHR5cGUgd2l0aG91dCBuZWVkaW5nIHRvIGRvIGEgc2VwYXJhdGUgbG9va3VwICh0aGlzIGNhc2UgaXMKKy8vIGxlc3MgY29tbW9uIHRoYW4gYW4gdW5rbm93biBmaWVsZCkuCitVUEJfSU5MSU5FIHVpbnQ2NF90IHVwYl9wYmRlY29kZXJfcGFja2Rpc3BhdGNoKHVpbnQ2NF90IG9mcywgdWludDhfdCB3dDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3Qgd3QyKSB7CisgIHJldHVybiAob2ZzIDw8IDE2KSB8ICh3dDIgPDwgOCkgfCB3dDE7Cit9CisKK1VQQl9JTkxJTkUgdm9pZCB1cGJfcGJkZWNvZGVyX3VucGFja2Rpc3BhdGNoKHVpbnQ2NF90IGRpc3BhdGNoLCB1aW50NjRfdCAqb2ZzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCAqd3QxLCB1aW50OF90ICp3dDIpIHsKKyAgKnd0MSA9ICh1aW50OF90KWRpc3BhdGNoOworICAqd3QyID0gKHVpbnQ4X3QpKGRpc3BhdGNoID4+IDgpOworICAqb2ZzID0gZGlzcGF0Y2ggPj4gMTY7Cit9CisKKy8vIEFsbCBvZiB0aGUgZnVuY3Rpb25zIGluIGRlY29kZXIuYyB0aGF0IHJldHVybiBpbnQzMl90IHJldHVybiB2YWx1ZXMgYWNjb3JkaW5nCisvLyB0byB0aGUgZm9sbG93aW5nIHNjaGVtZToKKy8vICAgMS4gbmVnYXRpdmUgdmFsdWVzIGluZGljYXRlIGEgcmV0dXJuIGNvZGUgZnJvbSB0aGUgZm9sbG93aW5nIGxpc3QuCisvLyAgIDIuIHBvc2l0aXZlIHZhbHVlcyBpbmRpY2F0ZSB0aGF0IGVycm9yIG9yIGVuZCBvZiBidWZmZXIgd2FzIGhpdCwgYW5kCisvLyAgICAgIHRoYXQgdGhlIGRlY29kZSBmdW5jdGlvbiBzaG91bGQgaW1tZWRpYXRlbHkgcmV0dXJuIHRoZSBnaXZlbiB2YWx1ZQorLy8gICAgICAodGhlIGRlY29kZXIgc3RhdGUgaGFzIGFscmVhZHkgYmVlbiBzdXNwZW5kZWQgYW5kIGlzIHJlYWR5IHRvIGJlCisvLyAgICAgIHJlc3VtZWQpLgorI2RlZmluZSBERUNPREVfT0sgLTEKKyNkZWZpbmUgREVDT0RFX01JU01BVENIIC0yICAvLyBVc2VkIG9ubHkgZnJvbSBjaGVja3RhZ19zbG93KCkuCisjZGVmaW5lIERFQ09ERV9FTkRHUk9VUCAtMyAgLy8gVXNlZCBvbmx5IGZyb20gY2hlY2t1bmtub3duKCkuCisKKyNkZWZpbmUgQ0hFQ0tfUkVUVVJOKHgpIHsgaW50MzJfdCByZXQgPSB4OyBpZiAocmV0ID49IDApIHJldHVybiByZXQ7IH0KKworI2VuZGlmICAvLyBVUEJfREVDT0RFUl9JTlRfSF8KKy8qCisgKiB1cGIgLSBhIG1pbmltYWxpc3QgaW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMTEgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIEEgbnVtYmVyIG9mIHJvdXRpbmVzIGZvciB2YXJpbnQgbWFuaXB1bGF0aW9uICh3ZSBrZWVwIHRoZW0gYWxsIGFyb3VuZCB0bworICogaGF2ZSBtdWx0aXBsZSBhcHByb2FjaGVzIGF2YWlsYWJsZSBmb3IgYmVuY2htYXJraW5nKS4KKyAqLworCisjaWZuZGVmIFVQQl9WQVJJTlRfREVDT0RFUl9IXworI2RlZmluZSBVUEJfVkFSSU5UX0RFQ09ERVJfSF8KKworI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8vIEEgbGlzdCBvZiB0eXBlcyBhcyB0aGV5IGFyZSBlbmNvZGVkIG9uLXRoZS13aXJlLgordHlwZWRlZiBlbnVtIHsKKyAgVVBCX1dJUkVfVFlQRV9WQVJJTlQgICAgICA9IDAsCisgIFVQQl9XSVJFX1RZUEVfNjRCSVQgICAgICAgPSAxLAorICBVUEJfV0lSRV9UWVBFX0RFTElNSVRFRCAgID0gMiwKKyAgVVBCX1dJUkVfVFlQRV9TVEFSVF9HUk9VUCA9IDMsCisgIFVQQl9XSVJFX1RZUEVfRU5EX0dST1VQICAgPSA0LAorICBVUEJfV0lSRV9UWVBFXzMyQklUICAgICAgID0gNSwKK30gdXBiX3dpcmV0eXBlX3Q7CisKKyNkZWZpbmUgVVBCX01BWF9XSVJFX1RZUEUgNQorCisvLyBUaGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBpdCB0YWtlcyB0byBlbmNvZGUgYSA2NC1iaXQgdmFyaW50LgorLy8gTm90ZSB0aGF0IHdpdGggYSBiZXR0ZXIgZW5jb2RpbmcgdGhpcyBjb3VsZCBiZSA5IChUT0RPOiB3cml0ZSB1cCBhCisvLyB3aWtpIGRvY3VtZW50IGFib3V0IHRoaXMpLgorI2RlZmluZSBVUEJfUEJfVkFSSU5UX01BWF9MRU4gMTAKKworLy8gQXJyYXkgb2YgdGhlICJuYXRpdmUiIChpZS4gbm9uLXBhY2tlZC1yZXBlYXRlZCkgd2lyZSB0eXBlIGZvciB0aGUgZ2l2ZW4gYQorLy8gZGVzY3JpcHRvciB0eXBlICh1cGJfZGVzY3JpcHRvcnR5cGVfdCkuCitleHRlcm4gY29uc3QgdWludDhfdCB1cGJfcGJfbmF0aXZlX3dpcmVfdHlwZXNbXTsKKworLyogWmlnLXphZyBlbmNvZGluZy9kZWNvZGluZyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworVVBCX0lOTElORSBpbnQzMl90IHVwYl96emRlY18zMih1aW50MzJfdCBuKSB7CisgIHJldHVybiAobiA+PiAxKSBeIC0oaW50MzJfdCkobiAmIDEpOworfQorVVBCX0lOTElORSBpbnQ2NF90IHVwYl96emRlY182NCh1aW50NjRfdCBuKSB7CisgIHJldHVybiAobiA+PiAxKSBeIC0oaW50NjRfdCkobiAmIDEpOworfQorVVBCX0lOTElORSB1aW50MzJfdCB1cGJfenplbmNfMzIoaW50MzJfdCBuKSB7IHJldHVybiAobiA8PCAxKSBeIChuID4+IDMxKTsgfQorVVBCX0lOTElORSB1aW50NjRfdCB1cGJfenplbmNfNjQoaW50NjRfdCBuKSB7IHJldHVybiAobiA8PCAxKSBeIChuID4+IDYzKTsgfQorCisvKiBEZWNvZGluZyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvLyBBbGwgZGVjb2RpbmcgZnVuY3Rpb25zIHJldHVybiB0aGlzIHN0cnVjdCBieSB2YWx1ZS4KK3R5cGVkZWYgc3RydWN0IHsKKyAgY29uc3QgY2hhciAqcDsgIC8vIE5VTEwgaWYgdGhlIHZhcmludCB3YXMgdW50ZXJtaW5hdGVkLgorICB1aW50NjRfdCB2YWw7Cit9IHVwYl9kZWNvZGVyZXQ7CisKKy8vIEZvdXIgZnVuY3Rpb25zIGZvciBkZWNvZGluZyBhIHZhcmludCBvZiBhdCBtb3N0IGVpZ2h0IGJ5dGVzLiAgVGhleSBhcmUgYWxsCisvLyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsLCBidXQgYXJlIGltcGxlbWVudGVkIGluIGRpZmZlcmVudCB3YXlzIGFuZCBsaWtlbHkgaGF2ZQorLy8gZGlmZmVyZW50IHBlcmZvcm1hbmNlIHByb2ZpbGVzLiAgV2Uga2VlcCB0aGVtIGFyb3VuZCBmb3IgcGVyZm9ybWFuY2UgdGVzdGluZy4KKy8vCisvLyBOb3RlIHRoYXQgdGhlc2UgZnVuY3Rpb25zIG1heSBub3QgcmVhZCBieXRlLWJ5LWJ5dGUsIHNvIHRoZXkgbXVzdCBub3QgYmUgdXNlZAorLy8gdW5sZXNzIHRoZXJlIGFyZSBhdCBsZWFzdCBlaWdodCBieXRlcyBsZWZ0IGluIHRoZSBidWZmZXIhCit1cGJfZGVjb2RlcmV0IHVwYl92ZGVjb2RlX21heDhfYnJhbmNoMzIodXBiX2RlY29kZXJldCByKTsKK3VwYl9kZWNvZGVyZXQgdXBiX3ZkZWNvZGVfbWF4OF9icmFuY2g2NCh1cGJfZGVjb2RlcmV0IHIpOwordXBiX2RlY29kZXJldCB1cGJfdmRlY29kZV9tYXg4X3dyaWdodCh1cGJfZGVjb2RlcmV0IHIpOwordXBiX2RlY29kZXJldCB1cGJfdmRlY29kZV9tYXg4X21hc3NpbWlubyh1cGJfZGVjb2RlcmV0IHIpOworCisvLyBUZW1wbGF0ZSBmb3IgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyB0aGUgZmlyc3QgdHdvIGJ5dGVzIHdpdGggYnJhbmNoaW5nCisvLyBhbmQgZGlzcGF0Y2hlcyAyLTEwIGJ5dGVzIHdpdGggYSBzZXBhcmF0ZSBmdW5jdGlvbi4gIE5vdGUgdGhhdCB0aGlzIG1heSByZWFkCisvLyB1cCB0byAxMCBieXRlcywgc28gaXQgbXVzdCBub3QgYmUgdXNlZCB1bmxlc3MgdGhlcmUgYXJlIGF0IGxlYXN0IHRlbiBieXRlcworLy8gbGVmdCBpbiB0aGUgYnVmZmVyIQorI2RlZmluZSBVUEJfVkFSSU5UX0RFQ09ERVJfQ0hFQ0syKG5hbWUsIGRlY29kZV9tYXg4X2Z1bmN0aW9uKSAgICAgICAgICAgICAgICAgIFwKK1VQQl9JTkxJTkUgdXBiX2RlY29kZXJldCB1cGJfdmRlY29kZV9jaGVjazJfICMjIG5hbWUoY29uc3QgY2hhciAqX3ApIHsgICAgICAgICBcCisgIHVpbnQ4X3QgKnAgPSAodWludDhfdCopX3A7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpZiAoKCpwICYgMHg4MCkgPT0gMCkgeyB1cGJfZGVjb2RlcmV0IHIgPSB7X3AgKyAxLCAqcCAmIDB4N2ZVfTsgcmV0dXJuIHI7IH0gIFwKKyAgdXBiX2RlY29kZXJldCByID0ge19wICsgMiwgKCpwICYgMHg3ZlUpIHwgKCgqKHAgKyAxKSAmIDB4N2ZVKSA8PCA3KX07ICAgICAgICBcCisgIGlmICgoKihwICsgMSkgJiAweDgwKSA9PSAwKSByZXR1cm4gcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICByZXR1cm4gZGVjb2RlX21heDhfZnVuY3Rpb24ocik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK30KKworVVBCX1ZBUklOVF9ERUNPREVSX0NIRUNLMihicmFuY2gzMiwgdXBiX3ZkZWNvZGVfbWF4OF9icmFuY2gzMik7CitVUEJfVkFSSU5UX0RFQ09ERVJfQ0hFQ0syKGJyYW5jaDY0LCB1cGJfdmRlY29kZV9tYXg4X2JyYW5jaDY0KTsKK1VQQl9WQVJJTlRfREVDT0RFUl9DSEVDSzIod3JpZ2h0LCB1cGJfdmRlY29kZV9tYXg4X3dyaWdodCk7CitVUEJfVkFSSU5UX0RFQ09ERVJfQ0hFQ0syKG1hc3NpbWlubywgdXBiX3ZkZWNvZGVfbWF4OF9tYXNzaW1pbm8pOworI3VuZGVmIFVQQl9WQVJJTlRfREVDT0RFUl9DSEVDSzIKKworLy8gT3VyIGNhbm9uaWNhbCBmdW5jdGlvbnMgZm9yIGRlY29kaW5nIHZhcmludHMsIGJhc2VkIG9uIHRoZSBjdXJyZW50bHkKKy8vIGZhdm9yZWQgYmVzdC1wZXJmb3JtaW5nIGltcGxlbWVudGF0aW9ucy4KK1VQQl9JTkxJTkUgdXBiX2RlY29kZXJldCB1cGJfdmRlY29kZV9mYXN0KGNvbnN0IGNoYXIgKnApIHsKKyAgaWYgKHNpemVvZihsb25nKSA9PSA4KQorICAgIHJldHVybiB1cGJfdmRlY29kZV9jaGVjazJfYnJhbmNoNjQocCk7CisgIGVsc2UKKyAgICByZXR1cm4gdXBiX3ZkZWNvZGVfY2hlY2syX2JyYW5jaDMyKHApOworfQorCitVUEJfSU5MSU5FIHVwYl9kZWNvZGVyZXQgdXBiX3ZkZWNvZGVfbWF4OF9mYXN0KHVwYl9kZWNvZGVyZXQgcikgeworICByZXR1cm4gdXBiX3ZkZWNvZGVfbWF4OF9tYXNzaW1pbm8ocik7Cit9CisKKworLyogRW5jb2RpbmcgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworVVBCX0lOTElORSBpbnQgdXBiX3ZhbHVlX3NpemUodWludDY0X3QgdmFsKSB7CisjaWZkZWYgX19HTlVDX18KKyAgaW50IGhpZ2hfYml0ID0gNjMgLSBfX2J1aWx0aW5fY2x6bGwodmFsKTsgIC8vIDAtYmFzZWQsIHVuZGVmIGlmIHZhbCA9PSAwLgorI2Vsc2UKKyAgaW50IGhpZ2hfYml0ID0gMDsKKyAgdWludDY0X3QgdG1wID0gdmFsOworICB3aGlsZSh0bXAgPj49IDEpIGhpZ2hfYml0Kys7CisjZW5kaWYKKyAgcmV0dXJuIHZhbCA9PSAwID8gMSA6IGhpZ2hfYml0IC8gOCArIDE7Cit9CisKKy8vIEVuY29kZXMgYSA2NC1iaXQgdmFyaW50IGludG8gYnVmICh3aGljaCBtdXN0IGJlID49VVBCX1BCX1ZBUklOVF9NQVhfTEVOCisvLyBieXRlcyBsb25nKSwgcmV0dXJuaW5nIGhvdyBtYW55IGJ5dGVzIHdlcmUgdXNlZC4KKy8vCisvLyBUT0RPOiBiZW5jaG1hcmsgYW5kIG9wdGltaXplIGlmIG5lY2Vzc2FyeS4KK1VQQl9JTkxJTkUgc2l6ZV90IHVwYl92ZW5jb2RlNjQodWludDY0X3QgdmFsLCBjaGFyICpidWYpIHsKKyAgaWYgKHZhbCA9PSAwKSB7IGJ1ZlswXSA9IDA7IHJldHVybiAxOyB9CisgIHNpemVfdCBpID0gMDsKKyAgd2hpbGUgKHZhbCkgeworICAgIHVpbnQ4X3QgYnl0ZSA9IHZhbCAmIDB4N2ZVOworICAgIHZhbCA+Pj0gNzsKKyAgICBpZiAodmFsKSBieXRlIHw9IDB4ODBVOworICAgIGJ1ZltpKytdID0gYnl0ZTsKKyAgfQorICByZXR1cm4gaTsKK30KKworVVBCX0lOTElORSBzaXplX3QgdXBiX3ZhcmludF9zaXplKHVpbnQ2NF90IHZhbCkgeworICBjaGFyIGJ1ZltVUEJfUEJfVkFSSU5UX01BWF9MRU5dOworICByZXR1cm4gdXBiX3ZlbmNvZGU2NCh2YWwsIGJ1Zik7Cit9CisKKy8vIEVuY29kZXMgYSAzMi1iaXQgdmFyaW50LCAqbm90KiBzaWduLWV4dGVuZGVkLgorVVBCX0lOTElORSB1aW50NjRfdCB1cGJfdmVuY29kZTMyKHVpbnQzMl90IHZhbCkgeworICBjaGFyIGJ1ZltVUEJfUEJfVkFSSU5UX01BWF9MRU5dOworICBzaXplX3QgYnl0ZXMgPSB1cGJfdmVuY29kZTY0KHZhbCwgYnVmKTsKKyAgdWludDY0X3QgcmV0ID0gMDsKKyAgYXNzZXJ0KGJ5dGVzIDw9IDUpOworICBtZW1jcHkoJnJldCwgYnVmLCBieXRlcyk7CisgIGFzc2VydChyZXQgPD0gMHhmZmZmZmZmZmZmVSk7CisgIHJldHVybiByZXQ7Cit9CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfSAgLyogZXh0ZXJuICJDIiAqLworI2VuZGlmCisKKyNlbmRpZiAgLyogVVBCX1ZBUklOVF9ERUNPREVSX0hfICovCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTAgR29vZ2xlIEluYy4gIFNlZSBMSUNFTlNFIGZvciBkZXRhaWxzLgorICogQXV0aG9yOiBKb3NoIEhhYmVybWFuIDxqaGFiZXJtYW5AZ21haWwuY29tPgorICoKKyAqIEltcGxlbWVudHMgYSBzZXQgb2YgdXBiX2hhbmRsZXJzIHRoYXQgd3JpdGUgcHJvdG9idWYgZGF0YSB0byB0aGUgYmluYXJ5IHdpcmUKKyAqIGZvcm1hdC4KKyAqCisgKiBUaGlzIGVuY29kZXIgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgaGF2ZSBhbnkgYWNjZXNzIHRvIGFueSBvdXQtb2YtYmFuZCBvcgorICogcHJlY29tcHV0ZWQgbGVuZ3RocyBmb3Igc3VibWVzc2FnZXMsIHNvIGl0IG11c3QgYnVmZmVyIHN1Ym1lc3NhZ2VzIGludGVybmFsbHkKKyAqIGJlZm9yZSBpdCBjYW4gZW1pdCB0aGUgZmlyc3QgYnl0ZS4KKyAqLworCisjaWZuZGVmIFVQQl9FTkNPREVSX0hfCisjZGVmaW5lIFVQQl9FTkNPREVSX0hfCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBwYiB7CitjbGFzcyBFbmNvZGVyOworfSAgLy8gbmFtZXNwYWNlIHBiCit9ICAvLyBuYW1lc3BhY2UgdXBiCisjZW5kaWYKKworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6OnBiOjpFbmNvZGVyLCB1cGJfcGJfZW5jb2Rlcik7CisKKyNkZWZpbmUgVVBCX1BCRU5DT0RFUl9NQVhfTkVTVElORyAxMDAKKworLyogdXBiOjpwYjo6RW5jb2RlciAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gVGhlIG91dHB1dCBidWZmZXIgaXMgZGl2aWRlZCBpbnRvIHNlZ21lbnRzOyBhIHNlZ21lbnQgaXMgYSBzdHJpbmcgb2YgZGF0YQorLy8gdGhhdCBpcyAicmVhZHkgdG8gZ28iIC0tIGl0IGRvZXMgbm90IG5lZWQgYW55IHZhcmludCBsZW5ndGhzIGluc2VydGVkIGludG8KKy8vIHRoZSBtaWRkbGUuICBUaGUgc2VhbXMgYmV0d2VlbiBzZWdtZW50cyBhcmUgd2hlcmUgdmFyaW50cyB3aWxsIGJlIGluc2VydGVkCisvLyBvbmNlIHRoZXkgYXJlIGtub3duLgorLy8KKy8vIFdlIGFsc28gdXNlIHRoZSBjb25jZXB0IG9mIGEgInJ1biIsIHdoaWNoIGlzIGEgcmFuZ2Ugb2YgZW5jb2RlZCBieXRlcyB0aGF0CisvLyBvY2N1ciBhdCBhIHNpbmdsZSBzdWJtZXNzYWdlIGxldmVsLiAgRXZlcnkgc2VnbWVudCBjb250YWlucyBvbmUgb3IgbW9yZSBydW5zLgorLy8KKy8vIEEgc2VnbWVudCBjYW4gc3BhbiBtZXNzYWdlcy4gIENvbnNpZGVyOgorLy8KKy8vICAgICAgICAgICAgICAgICAgLi0tU3VibWVzc2FnZSBsZW5ndGhzLS0tLS0tLS0tLgorLy8gICAgICAgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8CisvLyAgICAgICAgICAgICAgICAgIHwgICAgICAgViAgICAgICAgICAgICAgICAgICAgIFYKKy8vICAgICAgICAgICAgICAgICAgViAgICAgIHwgfC0tLS0tLS0tLS0tLS0tLSAgICB8IHwtLS0tLS0tLS0tLS0tLS0tLQorLy8gU3VibWVzc2FnZXM6ICAgIHwgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBUb3AtbGV2ZWwgbXNnOiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyBTZWdtZW50czogICAgICAgICAgLS0tLS0gICAtLS0tLS0tLS0tLS0tLS0tLS0tICAgLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFJ1bnM6ICAgICAgICAgICAgICAqLS0tLSAgICotLS0tLS0tLS0tLS0tLSotLS0gICAqLS0tLS0tLS0tLS0tLS0tLQorLy8gKCogbWFya3MgdGhlIHN0YXJ0KQorLy8KKy8vIE5vdGUgdGhhdCB0aGUgdG9wLWxldmVsIG1lbnNzYWdlIGlzIG5vdCBpbiBhbnkgc2VnbWVudCBiZWNhdXNlIGl0IGRvZXMgbm90CisvLyBoYXZlIGFueSBsZW5ndGggcHJlY2VkaW5nIGl0LgorLy8KKy8vIEEgc2VnbWVudCBpcyBvbmx5IGludGVycnVwdGVkIHdoZW4gYW5vdGhlciBsZW5ndGggbmVlZHMgdG8gYmUgaW5zZXJ0ZWQuICBTbworLy8gb2JzZXJ2ZSBob3cgdGhlIHNlY29uZCBzZWdtZW50IHNwYW5zIGJvdGggdGhlIGlubmVyIHN1Ym1lc3NhZ2UgYW5kIHBhcnQgb2YKKy8vIHRoZSBuZXh0IGVuY2xvc2luZyBtZXNzYWdlLgordHlwZWRlZiBzdHJ1Y3QgeworIFVQQl9QUklWQVRFX0ZPUl9DUFAKKyAgdWludDMyX3QgbXNnbGVuOyAgLy8gVGhlIGxlbmd0aCB0byB2YXJpbnQtZW5jb2RlIGJlZm9yZSB0aGlzIHNlZ21lbnQuCisgIHVpbnQzMl90IHNlZ2xlbjsgIC8vIExlbmd0aCBvZiB0aGUgc2VnbWVudC4KK30gdXBiX3BiX2VuY29kZXJfc2VnbWVudDsKKworVVBCX0RFRklORV9DTEFTUzAodXBiOjpwYjo6RW5jb2RlciwKKyBwdWJsaWM6CisgIEVuY29kZXIoY29uc3QgdXBiOjpIYW5kbGVycyogaGFuZGxlcnMpOworICB+RW5jb2RlcigpOworCisgIHN0YXRpYyByZWZmZWRfcHRyPGNvbnN0IEhhbmRsZXJzPiBOZXdIYW5kbGVycyhjb25zdCB1cGI6Ok1lc3NhZ2VEZWYqIG1zZyk7CisKKyAgLy8gUmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgcHJpbnRlciwgc28gdGhhdCBpdCB3aWxsIGV4cGVjdCB0byBiZWdpbiBhIG5ldworICAvLyBkb2N1bWVudC4KKyAgdm9pZCBSZXNldCgpOworCisgIC8vIFJlc2V0cyB0aGUgb3V0cHV0IHBvaW50ZXIgd2hpY2ggd2lsbCBzZXJ2ZSBhcyBvdXIgY2xvc3VyZS4KKyAgdm9pZCBSZXNldE91dHB1dChCeXRlc1NpbmsqIG91dHB1dCk7CisKKyAgLy8gVGhlIGlucHV0IHRvIHRoZSBlbmNvZGVyLgorICBTaW5rKiBpbnB1dCgpOworCisgcHJpdmF0ZToKKyAgVVBCX0RJU0FMTE9XX0NPUFlfQU5EX0FTU0lHTihFbmNvZGVyKTsKKywKK1VQQl9ERUZJTkVfU1RSVUNUMCh1cGJfcGJfZW5jb2RlciwgVVBCX1FVT1RFKAorICAvLyBPdXIgaW5wdXQgYW5kIG91dHB1dC4KKyAgdXBiX3NpbmsgaW5wdXRfOworICB1cGJfYnl0ZXNzaW5rICpvdXRwdXRfOworCisgIC8vIFRoZSAic3ViY2xvc3VyZSIgLS0gdXNlZCBhcyB0aGUgaW5uZXIgY2xvc3VyZSBhcyBwYXJ0IG9mIHRoZSBieXRlc3NpbmsKKyAgLy8gcHJvdG9jb2wuCisgIHZvaWQgKnN1YmM7CisKKyAgLy8gVGhlIG91dHB1dCBidWZmZXIgYW5kIGxpbWl0LCBhbmQgb3VyIGN1cnJlbnQgd3JpdGUgcG9zaXRpb24uICAiYnVmIgorICAvLyBpbml0aWFsbHkgcG9pbnRzIHRvICJpbml0YnVmIiwgYnV0IGlzIGR5bmFtaWNhbGx5IGFsbG9jYXRlZCBpZiB3ZSBuZWVkIHRvCisgIC8vIGdyb3cgYmV5b25kIHRoZSBpbml0aWFsIHNpemUuCisgIGNoYXIgKmJ1ZiwgKnB0ciwgKmxpbWl0OworCisgIC8vIFRoZSBiZWdpbm5pbmcgb2YgdGhlIGN1cnJlbnQgcnVuLCBvciB1bmRlZmluZWQgaWYgd2UgYXJlIGF0IHRoZSB0b3AgbGV2ZWwuCisgIGNoYXIgKnJ1bmJlZ2luOworCisgIC8vIFRoZSBsaXN0IG9mIHNlZ21lbnRzIHdlIGFyZSBhY2N1bXVsYXRpbmcuCisgIHVwYl9wYl9lbmNvZGVyX3NlZ21lbnQgKnNlZ2J1ZiwgKnNlZ3B0ciwgKnNlZ2xpbWl0OworCisgIC8vIFRoZSBzdGFjayBvZiBlbmNsb3Npbmcgc3VibWVzc2FnZXMuICBFYWNoIGVudHJ5IGluIHRoZSBzdGFjayBwb2ludHMgdG8gdGhlCisgIC8vIHNlZ21lbnQgd2hlcmUgdGhpcyBzdWJtZXNzYWdlJ3MgbGVuZ3RoIGlzIGJlaW5nIGFjY3VtdWxhdGVkLgorICBpbnQgc3RhY2tbVVBCX1BCRU5DT0RFUl9NQVhfTkVTVElOR10sICp0b3AsICpzdGFja2xpbWl0OworCisgIC8vIERlcHRoIG9mIHN0YXJ0bXNnL2VuZG1zZyBjYWxscy4KKyAgaW50IGRlcHRoOworCisgIC8vIEluaXRpYWwgYnVmZmVycyBmb3IgdGhlIG91dHB1dCBidWZmZXIgYW5kIHNlZ21lbnQgYnVmZmVyLiAgSWYgd2Ugb3V0Z3JvdworICAvLyB0aGVzZSB3ZSB3aWxsIGR5bmFtaWNhbGx5IGFsbG9jYXRlIGJpZ2dlciBvbmVzLgorICBjaGFyIGluaXRidWZbMjU2XTsKKyAgdXBiX3BiX2VuY29kZXJfc2VnbWVudCBzZWdpbml0YnVmWzMyXTsKKykpKTsKKworVVBCX0JFR0lOX0VYVEVSTl9DCisKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX3BiX2VuY29kZXJfbmV3aGFuZGxlcnMoY29uc3QgdXBiX21zZ2RlZiAqbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqb3duZXIpOwordm9pZCB1cGJfcGJfZW5jb2Rlcl9yZXNldCh1cGJfcGJfZW5jb2RlciAqZSk7Cit1cGJfc2luayAqdXBiX3BiX2VuY29kZXJfaW5wdXQodXBiX3BiX2VuY29kZXIgKnApOwordm9pZCB1cGJfcGJfZW5jb2Rlcl9pbml0KHVwYl9wYl9lbmNvZGVyICplLCBjb25zdCB1cGJfaGFuZGxlcnMgKmgpOwordm9pZCB1cGJfcGJfZW5jb2Rlcl9yZXNldG91dHB1dCh1cGJfcGJfZW5jb2RlciAqZSwgdXBiX2J5dGVzc2luayAqb3V0cHV0KTsKK3ZvaWQgdXBiX3BiX2VuY29kZXJfdW5pbml0KHVwYl9wYl9lbmNvZGVyICplKTsKKworVVBCX0VORF9FWFRFUk5fQworCisjaWZkZWYgX19jcGx1c3BsdXMKKworbmFtZXNwYWNlIHVwYiB7CituYW1lc3BhY2UgcGIgeworaW5saW5lIEVuY29kZXI6OkVuY29kZXIoY29uc3QgdXBiOjpIYW5kbGVycyogaGFuZGxlcnMpIHsKKyAgdXBiX3BiX2VuY29kZXJfaW5pdCh0aGlzLCBoYW5kbGVycyk7Cit9CitpbmxpbmUgRW5jb2Rlcjo6fkVuY29kZXIoKSB7CisgIHVwYl9wYl9lbmNvZGVyX3VuaW5pdCh0aGlzKTsKK30KK2lubGluZSB2b2lkIEVuY29kZXI6OlJlc2V0KCkgeworICB1cGJfcGJfZW5jb2Rlcl9yZXNldCh0aGlzKTsKK30KK2lubGluZSB2b2lkIEVuY29kZXI6OlJlc2V0T3V0cHV0KEJ5dGVzU2luayogb3V0cHV0KSB7CisgIHVwYl9wYl9lbmNvZGVyX3Jlc2V0b3V0cHV0KHRoaXMsIG91dHB1dCk7Cit9CitpbmxpbmUgU2luayogRW5jb2Rlcjo6aW5wdXQoKSB7CisgIHJldHVybiB1cGJfcGJfZW5jb2Rlcl9pbnB1dCh0aGlzKTsKK30KK2lubGluZSByZWZmZWRfcHRyPGNvbnN0IEhhbmRsZXJzPiBFbmNvZGVyOjpOZXdIYW5kbGVycygKKyAgICBjb25zdCB1cGI6Ok1lc3NhZ2VEZWYgKm1kKSB7CisgIGNvbnN0IEhhbmRsZXJzKiBoID0gdXBiX3BiX2VuY29kZXJfbmV3aGFuZGxlcnMobWQsICZoKTsKKyAgcmV0dXJuIHJlZmZlZF9wdHI8Y29uc3QgSGFuZGxlcnM+KGgsICZoKTsKK30KK30gIC8vIG5hbWVzcGFjZSBwYgorfSAgLy8gbmFtZXNwYWNlIHVwYgorCisjZW5kaWYKKworI2VuZGlmICAvKiBVUEJfRU5DT0RFUl9IXyAqLworLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAxMS0yMDEyIEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiB1cGIncyBjb3JlIGNvbXBvbmVudHMgbGlrZSB1cGJfZGVjb2RlciBhbmQgdXBiX21zZyBhcmUgY2FyZWZ1bGx5IGRlc2lnbmVkIHRvCisgKiBhdm9pZCBkZXBlbmRpbmcgb24gZWFjaCBvdGhlciBmb3IgbWF4aW11bSBvcnRob2dvbmFsaXR5LiAgSW4gb3RoZXIgd29yZHMsCisgKiB5b3UgY2FuIHVzZSBhIHVwYl9kZWNvZGVyIHRvIGRlY29kZSBpbnRvICphbnkqIGtpbmQgb2Ygc3RydWN0dXJlOyB1cGJfbXNnIGlzCisgKiBqdXN0IG9uZSBzdWNoIHN0cnVjdHVyZS4gIEEgdXBiX21zZyBjYW4gYmUgc2VyaWFsaXplZC9kZXNlcmlhbGl6ZWQgaW50byBhbnkKKyAqIGZvcm1hdCwgcHJvdG9idWYgYmluYXJ5IGZvcm1hdCBpcyBqdXN0IG9uZSBzdWNoIGZvcm1hdC4KKyAqCisgKiBIb3dldmVyLCBmb3IgY29udmVuaWVuY2Ugd2UgcHJvdmlkZSBmdW5jdGlvbnMgaGVyZSBmb3IgZG9pbmcgY29tbW9uCisgKiBvcGVyYXRpb25zIGxpa2UgZGVzZXJpYWxpemluZyBwcm90b2J1ZiBiaW5hcnkgZm9ybWF0IGludG8gYSB1cGJfbXNnLiAgVGhlCisgKiBjb21wcm9taXNlIGlzIHRoYXQgdGhpcyBmaWxlIGRyYWdzIGluIGFsbW9zdCBhbGwgb2YgdXBiIGFzIGEgZGVwZW5kZW5jeSwKKyAqIHdoaWNoIGNvdWxkIGJlIHVuZGVzaXJhYmxlIGlmIHlvdSdyZSB0cnlpbmcgdG8gdXNlIGEgdHJpbW1lZC1kb3duIGJ1aWxkIG9mCisgKiB1cGIuCisgKgorICogV2hpbGUgdGhlc2Ugcm91dGluZXMgYXJlIGNvbnZlbmllbnQsIHRoZXkgZG8gbm90IHJldXNlIGFueSBlbmNvZGluZy9kZWNvZGluZworICogc3RhdGUuICBGb3IgZXhhbXBsZSwgaWYgYSBkZWNvZGVyIGlzIEpJVC1iYXNlZCwgaXQgd2lsbCBiZSByZS1KSVR0ZWQgZXZlcnkKKyAqIHRpbWUgdGhlc2UgZnVuY3Rpb25zIGFyZSBjYWxsZWQuICBGb3IgdGhpcyByZWFzb24sIGlmIHlvdSBhcmUgcGFyc2luZyBsb3RzCisgKiBvZiBkYXRhIGFuZCBlZmZpY2llbmN5IGlzIGFuIGlzc3VlLCB0aGVzZSBtYXkgbm90IGJlIHRoZSBiZXN0IGZ1bmN0aW9ucyB0bworICogdXNlICh0aG91Z2ggdGhleSBhcmUgdXNlZnVsIGZvciBwcm90b3R5cGluZywgYmVmb3JlIG9wdGltaXppbmcpLgorICovCisKKyNpZm5kZWYgVVBCX0dMVUVfSAorI2RlZmluZSBVUEJfR0xVRV9ICisKKyNpbmNsdWRlIDxzdGRib29sLmg+CisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLy8gTG9hZHMgYWxsIGRlZnMgZnJvbSB0aGUgZ2l2ZW4gcHJvdG9idWYgYmluYXJ5IGRlc2NyaXB0b3IsIHNldHRpbmcgZGVmYXVsdAorLy8gYWNjZXNzb3JzIGFuZCBhIGRlZmF1bHQgbGF5b3V0IG9uIGFsbCBtZXNzYWdlcy4gIFRoZSBjYWxsZXIgb3ducyB0aGUKKy8vIHJldHVybmVkIGFycmF5IG9mIGRlZnMsIHdoaWNoIHdpbGwgYmUgb2YgbGVuZ3RoICpuLiAgT24gZXJyb3IgTlVMTCBpcworLy8gcmV0dXJuZWQgYW5kIHN0YXR1cyBpcyBzZXQgKGlmIG5vbi1OVUxMKS4KK3VwYl9kZWYgKip1cGJfbG9hZF9kZWZzX2Zyb21fZGVzY3JpcHRvcihjb25zdCBjaGFyICpzdHIsIHNpemVfdCBsZW4sIGludCAqbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpvd25lciwgdXBiX3N0YXR1cyAqc3RhdHVzKTsKKworLy8gTGlrZSB0aGUgcHJldmlvdXMgYnV0IGFsc28gYWRkcyB0aGUgbG9hZGVkIGRlZnMgdG8gdGhlIGdpdmVuIHN5bXRhYi4KK2Jvb2wgdXBiX2xvYWRfZGVzY3JpcHRvcl9pbnRvX3N5bXRhYih1cGJfc3ltdGFiICpzeW10YWIsIGNvbnN0IGNoYXIgKnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuLCB1cGJfc3RhdHVzICpzdGF0dXMpOworCisvLyBMaWtlIHRoZSBwcmV2aW91cyBidXQgYWxzbyByZWFkcyB0aGUgZGVzY3JpcHRvciBmcm9tIHRoZSBnaXZlbiBmaWxlbmFtZS4KK2Jvb2wgdXBiX2xvYWRfZGVzY3JpcHRvcl9maWxlX2ludG9fc3ltdGFiKHVwYl9zeW10YWIgKnN5bXRhYiwgY29uc3QgY2hhciAqZm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGJfc3RhdHVzICpzdGF0dXMpOworCisvLyBSZWFkcyB0aGUgZ2l2ZW4gZmlsZW5hbWUgaW50byBhIGNoYXJhY3RlciBzdHJpbmcsIHJldHVybmluZyBOVUxMIGlmIHRoZXJlCisvLyB3YXMgYW4gZXJyb3IuCitjaGFyICp1cGJfcmVhZGZpbGUoY29uc3QgY2hhciAqZmlsZW5hbWUsIHNpemVfdCAqbGVuKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9ICAvKiBleHRlcm4gIkMiICovCisKK25hbWVzcGFjZSB1cGIgeworCisvLyBBbGwgcm91dGluZXMgdGhhdCBsb2FkIGRlc2NyaXB0b3JzIGV4cGVjdCB0aGUgZGVzY3JpcHRvciB0byBiZSBhCisvLyBGaWxlRGVzY3JpcHRvclNldC4KK2lubGluZSBib29sIExvYWREZXNjcmlwdG9yRmlsZUludG9TeW10YWIoU3ltYm9sVGFibGUqIHMsIGNvbnN0IGNoYXIgKmZuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMqIHN0YXR1cykgeworICByZXR1cm4gdXBiX2xvYWRfZGVzY3JpcHRvcl9maWxlX2ludG9fc3ltdGFiKHMsIGZuYW1lLCBzdGF0dXMpOworfQorCitpbmxpbmUgYm9vbCBMb2FkRGVzY3JpcHRvckludG9TeW10YWIoU3ltYm9sVGFibGUqIHMsIGNvbnN0IGNoYXIqIHN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuLCBTdGF0dXMqIHN0YXR1cykgeworICByZXR1cm4gdXBiX2xvYWRfZGVzY3JpcHRvcl9pbnRvX3N5bXRhYihzLCBzdHIsIGxlbiwgc3RhdHVzKTsKK30KKworLy8gVGVtcGxhdGVkIHNvIGl0IGNhbiBhY2NlcHQgYm90aCBzdHJpbmcgYW5kIHN0ZDo6c3RyaW5nLgordGVtcGxhdGUgPHR5cGVuYW1lIFQ+Citib29sIExvYWREZXNjcmlwdG9ySW50b1N5bXRhYihTeW1ib2xUYWJsZSogcywgY29uc3QgVCYgZGVzYywgU3RhdHVzKiBzdGF0dXMpIHsKKyAgcmV0dXJuIHVwYl9sb2FkX2Rlc2NyaXB0b3JfaW50b19zeW10YWIocywgZGVzYy5jX3N0cigpLCBkZXNjLnNpemUoKSwgc3RhdHVzKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHVwYgorCisjZW5kaWYKKworI2VuZGlmCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDA5IEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqLworCisjaWZuZGVmIFVQQl9URVhUX0hfCisjZGVmaW5lIFVQQl9URVhUX0hfCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBwYiB7CitjbGFzcyBUZXh0UHJpbnRlcjsKK30gIC8vIG5hbWVzcGFjZSBwYgorfSAgLy8gbmFtZXNwYWNlIHVwYgorI2VuZGlmCisKK1VQQl9ERUNMQVJFX1RZUEUodXBiOjpwYjo6VGV4dFByaW50ZXIsIHVwYl90ZXh0cHJpbnRlcik7CisKK1VQQl9ERUZJTkVfQ0xBU1MwKHVwYjo6cGI6OlRleHRQcmludGVyLAorIHB1YmxpYzoKKyAgLy8gVGhlIGdpdmVuIGhhbmRsZXJzIG11c3QgaGF2ZSBjb21lIGZyb20gTmV3SGFuZGxlcnMoKS4gIEl0IG11c3Qgb3V0bGl2ZSB0aGUKKyAgLy8gVGV4dFByaW50ZXIuCisgIGV4cGxpY2l0IFRleHRQcmludGVyKGNvbnN0IHVwYjo6SGFuZGxlcnMqIGhhbmRsZXJzKTsKKworICB2b2lkIFNldFNpbmdsZUxpbmVNb2RlKGJvb2wgc2luZ2xlX2xpbmUpOworCisgIGJvb2wgUmVzZXRPdXRwdXQoQnl0ZXNTaW5rKiBvdXRwdXQpOworICBTaW5rKiBpbnB1dCgpOworCisgIC8vIElmIGhhbmRsZXIgY2FjaGluZyBiZWNvbWVzIGEgcmVxdWlyZW1lbnQgd2UgY2FuIGFkZCBhIGNvZGUgY2FjaGUgYXMgaW4KKyAgLy8gZGVjb2Rlci5oCisgIHN0YXRpYyByZWZmZWRfcHRyPGNvbnN0IEhhbmRsZXJzPiBOZXdIYW5kbGVycyhjb25zdCBNZXNzYWdlRGVmKiBtZCk7CisKKyBwcml2YXRlOgorLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl90ZXh0cHJpbnRlciwKKyAgdXBiX3NpbmsgaW5wdXRfOworICB1cGJfYnl0ZXNzaW5rICpvdXRwdXRfOworICBpbnQgaW5kZW50X2RlcHRoXzsKKyAgYm9vbCBzaW5nbGVfbGluZV87CisgIHZvaWQgKnN1YmM7CispKTsKKworVVBCX0JFR0lOX0VYVEVSTl9DICAvLyB7CisKKy8vIEMgQVBJLgordm9pZCB1cGJfdGV4dHByaW50ZXJfaW5pdCh1cGJfdGV4dHByaW50ZXIgKnAsIGNvbnN0IHVwYl9oYW5kbGVycyAqaCk7Cit2b2lkIHVwYl90ZXh0cHJpbnRlcl91bmluaXQodXBiX3RleHRwcmludGVyICpwKTsKK2Jvb2wgdXBiX3RleHRwcmludGVyX3Jlc2V0b3V0cHV0KHVwYl90ZXh0cHJpbnRlciAqcCwgdXBiX2J5dGVzc2luayAqb3V0cHV0KTsKK3ZvaWQgdXBiX3RleHRwcmludGVyX3NldHNpbmdsZWxpbmUodXBiX3RleHRwcmludGVyICpwLCBib29sIHNpbmdsZV9saW5lKTsKK3VwYl9zaW5rICp1cGJfdGV4dHByaW50ZXJfaW5wdXQodXBiX3RleHRwcmludGVyICpwKTsKKworY29uc3QgdXBiX2hhbmRsZXJzICp1cGJfdGV4dHByaW50ZXJfbmV3aGFuZGxlcnMoY29uc3QgdXBiX21zZ2RlZiAqbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKm93bmVyKTsKKworVVBCX0VORF9FWFRFUk5fQyAgLy8gfQorCisjaWZkZWYgX19jcGx1c3BsdXMKKworbmFtZXNwYWNlIHVwYiB7CituYW1lc3BhY2UgcGIgeworaW5saW5lIFRleHRQcmludGVyOjpUZXh0UHJpbnRlcihjb25zdCB1cGI6OkhhbmRsZXJzKiBoYW5kbGVycykgeworICB1cGJfdGV4dHByaW50ZXJfaW5pdCh0aGlzLCBoYW5kbGVycyk7Cit9CitpbmxpbmUgdm9pZCBUZXh0UHJpbnRlcjo6U2V0U2luZ2xlTGluZU1vZGUoYm9vbCBzaW5nbGVfbGluZSkgeworICB1cGJfdGV4dHByaW50ZXJfc2V0c2luZ2xlbGluZSh0aGlzLCBzaW5nbGVfbGluZSk7Cit9CitpbmxpbmUgYm9vbCBUZXh0UHJpbnRlcjo6UmVzZXRPdXRwdXQoQnl0ZXNTaW5rKiBvdXRwdXQpIHsKKyAgcmV0dXJuIHVwYl90ZXh0cHJpbnRlcl9yZXNldG91dHB1dCh0aGlzLCBvdXRwdXQpOworfQoraW5saW5lIFNpbmsqIFRleHRQcmludGVyOjppbnB1dCgpIHsKKyAgcmV0dXJuIHVwYl90ZXh0cHJpbnRlcl9pbnB1dCh0aGlzKTsKK30KK2lubGluZSByZWZmZWRfcHRyPGNvbnN0IEhhbmRsZXJzPiBUZXh0UHJpbnRlcjo6TmV3SGFuZGxlcnMoCisgICAgY29uc3QgTWVzc2FnZURlZiAqbWQpIHsKKyAgY29uc3QgSGFuZGxlcnMqIGggPSB1cGJfdGV4dHByaW50ZXJfbmV3aGFuZGxlcnMobWQsICZoKTsKKyAgcmV0dXJuIHJlZmZlZF9wdHI8Y29uc3QgSGFuZGxlcnM+KGgsICZoKTsKK30KK30gIC8vIG5hbWVzcGFjZSBwYgorfSAgLy8gbmFtZXNwYWNlIHVwYgorCisjZW5kaWYKKworI2VuZGlmICAvKiBVUEJfVEVYVF9IXyAqLworLyoKKyAqIHVwYiAtIGEgbWluaW1hbGlzdCBpbXBsZW1lbnRhdGlvbiBvZiBwcm90b2NvbCBidWZmZXJzLgorICoKKyAqIENvcHlyaWdodCAoYykgMjAxNCBHb29nbGUgSW5jLiAgU2VlIExJQ0VOU0UgZm9yIGRldGFpbHMuCisgKiBBdXRob3I6IEpvc2ggSGFiZXJtYW4gPGpoYWJlcm1hbkBnbWFpbC5jb20+CisgKgorICogdXBiOjpqc29uOjpQYXJzZXIgY2FuIHBhcnNlIEpTT04gYWNjb3JkaW5nIHRvIGEgc3BlY2lmaWMgc2NoZW1hLgorICogU3VwcG9ydCBmb3IgcGFyc2luZyBhcmJpdHJhcnkgSlNPTiAoc2NoZW1hLWxlc3MpIHdpbGwgYmUgYWRkZWQgbGF0ZXIuCisgKi8KKworI2lmbmRlZiBVUEJfSlNPTl9QQVJTRVJfSF8KKyNkZWZpbmUgVVBCX0pTT05fUEFSU0VSX0hfCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBqc29uIHsKK2NsYXNzIFBhcnNlcjsKK30gIC8vIG5hbWVzcGFjZSBqc29uCit9ICAvLyBuYW1lc3BhY2UgdXBiCisjZW5kaWYKKworVVBCX0RFQ0xBUkVfVFlQRSh1cGI6Ompzb246OlBhcnNlciwgdXBiX2pzb25fcGFyc2VyKTsKKworLy8gSW50ZXJuYWwtb25seSBzdHJ1Y3QgdXNlZCBieSB0aGUgcGFyc2VyLiBBIHBhcnNlciBmcmFtZSBjb3JyZXNwb25kcworLy8gb25lLXRvLW9uZSB3aXRoIGEgaGFuZGxlciAoc2luaykgZnJhbWUuCit0eXBlZGVmIHN0cnVjdCB7CisgVVBCX1BSSVZBVEVfRk9SX0NQUAorICB1cGJfc2luayBzaW5rOworICAvLyBUaGUgY3VycmVudCBtZXNzYWdlIGluIHdoaWNoIHdlJ3JlIHBhcnNpbmcsIGFuZCB0aGUgZmllbGQgd2hvc2UgdmFsdWUgd2UncmUKKyAgLy8gZXhwZWN0aW5nIG5leHQuCisgIGNvbnN0IHVwYl9tc2dkZWYgKm07CisgIGNvbnN0IHVwYl9maWVsZGRlZiAqZjsKKworICAvLyBXZSBhcmUgaW4gYSByZXBlYXRlZC1maWVsZCBjb250ZXh0LCByZWFkeSB0byBlbWl0IG1hcGVudHJpZXMgYXMKKyAgLy8gc3VibWVzc2FnZXMuIFRoaXMgZmxhZyBhbHRlcnMgdGhlIHN0YXJ0LW9mLW9iamVjdCAob3Blbi1icmFjZSkgYmVoYXZpb3IgdG8KKyAgLy8gYmVnaW4gYSBzZXF1ZW5jZSBvZiBtYXBlbnRyeSBtZXNzYWdlcyByYXRoZXIgdGhhbiBhIHNpbmdsZSBzdWJtZXNzYWdlLgorICBib29sIGlzX21hcDsKKyAgLy8gV2UgYXJlIGluIGEgbWFwLWVudHJ5IG1lc3NhZ2UgY29udGV4dC4gVGhpcyBmbGFnIGlzIHNldCB3aGVuIHBhcnNpbmcgdGhlCisgIC8vIHZhbHVlIGZpZWxkIG9mIGEgc2luZ2xlIG1hcCBlbnRyeSBhbmQgaW5kaWNhdGVzIHRvIGFsbCB2YWx1ZS1maWVsZCBwYXJzZXJzCisgIC8vIChzdWJvYmplY3RzLCBzdHJpbmdzLCBudW1iZXJzLCBhbmQgYm9vbHMpIHRoYXQgdGhlIG1hcC1lbnRyeSBzdWJtZXNzYWdlCisgIC8vIHNob3VsZCBlbmQgYXMgc29vbiBhcyB0aGUgdmFsdWUgaXMgcGFyc2VkLgorICBib29sIGlzX21hcGVudHJ5OworICAvLyBJZiB8aXNfbWFwfCBvciB8aXNfbWFwZW50cnl8IGlzIHRydWUsIHxtYXBmaWVsZHwgcmVmZXJzIHRvIHRoZSBwYXJlbnQKKyAgLy8gbWVzc2FnZSdzIG1hcCBmaWVsZCB0aGF0IHdlJ3JlIGN1cnJlbnRseSBwYXJzaW5nLiBUaGlzIGRpZmZlcnMgZnJvbSB8ZnwKKyAgLy8gYmVjYXVzZSB8ZnwgaXMgdGhlIGZpZWxkIGluIHRoZSAqY3VycmVudCogbWVzc2FnZSAoaS5lLiwgdGhlIG1hcC1lbnRyeQorICAvLyBtZXNzYWdlIGl0c2VsZiksIG5vdCB0aGUgcGFyZW50J3MgZmllbGQgdGhhdCBsZWFkcyB0byB0aGlzIG1hcC4KKyAgY29uc3QgdXBiX2ZpZWxkZGVmICptYXBmaWVsZDsKK30gdXBiX2pzb25wYXJzZXJfZnJhbWU7CisKKworLyogdXBiOjpqc29uOjpQYXJzZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2RlZmluZSBVUEJfSlNPTl9NQVhfREVQVEggNjQKKworLy8gUGFyc2VzIGFuIGluY29taW5nIEJ5dGVzU3RyZWFtLCBwdXNoaW5nIHRoZSByZXN1bHRzIHRvIHRoZSBkZXN0aW5hdGlvbiBzaW5rLgorVVBCX0RFRklORV9DTEFTUzAodXBiOjpqc29uOjpQYXJzZXIsCisgcHVibGljOgorICBQYXJzZXIoU3RhdHVzKiBzdGF0dXMpOworICB+UGFyc2VyKCk7CisKKyAgLy8gUmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgcHJpbnRlciwgc28gdGhhdCBpdCB3aWxsIGV4cGVjdCB0byBiZWdpbiBhIG5ldworICAvLyBkb2N1bWVudC4KKyAgdm9pZCBSZXNldCgpOworCisgIC8vIFJlc2V0cyB0aGUgb3V0cHV0IHBvaW50ZXIgd2hpY2ggd2lsbCBzZXJ2ZSBhcyBvdXIgY2xvc3VyZS4gIEltcGxpZXMKKyAgLy8gUmVzZXQoKS4KKyAgdm9pZCBSZXNldE91dHB1dChTaW5rKiBvdXRwdXQpOworCisgIC8vIFRoZSBpbnB1dCB0byB0aGUgcHJpbnRlci4KKyAgQnl0ZXNTaW5rKiBpbnB1dCgpOworLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9qc29uX3BhcnNlciwKKyAgdXBiX2J5dGVzaGFuZGxlciBpbnB1dF9oYW5kbGVyXzsKKyAgdXBiX2J5dGVzc2luayBpbnB1dF87CisKKyAgLy8gU3RhY2sgdG8gdHJhY2sgdGhlIEpTT04gc2NvcGVzIHdlIGFyZSBpbi4KKyAgdXBiX2pzb25wYXJzZXJfZnJhbWUgc3RhY2tbVVBCX0pTT05fTUFYX0RFUFRIXTsKKyAgdXBiX2pzb25wYXJzZXJfZnJhbWUgKnRvcDsKKyAgdXBiX2pzb25wYXJzZXJfZnJhbWUgKmxpbWl0OworCisgIHVwYl9zdGF0dXMgKnN0YXR1czsKKworICAvLyBSYWdlbCdzIGludGVybmFsIHBhcnNpbmcgc3RhY2sgZm9yIHRoZSBwYXJzaW5nIHN0YXRlIG1hY2hpbmUuCisgIGludCBjdXJyZW50X3N0YXRlOworICBpbnQgcGFyc2VyX3N0YWNrW1VQQl9KU09OX01BWF9ERVBUSF07CisgIGludCBwYXJzZXJfdG9wOworCisgIC8vIFRoZSBoYW5kbGUgZm9yIHRoZSBjdXJyZW50IGJ1ZmZlci4KKyAgY29uc3QgdXBiX2J1ZmhhbmRsZSAqaGFuZGxlOworCisgIC8vIEFjY3VtdWxhdGUgYnVmZmVyLiAgU2VlIGRldGFpbHMgaW4gcGFyc2VyLnJsLgorICBjb25zdCBjaGFyICphY2N1bXVsYXRlZDsKKyAgc2l6ZV90IGFjY3VtdWxhdGVkX2xlbjsKKyAgY2hhciAqYWNjdW11bGF0ZV9idWY7CisgIHNpemVfdCBhY2N1bXVsYXRlX2J1Zl9zaXplOworCisgIC8vIE11bHRpLXBhcnQgdGV4dCBkYXRhLiAgU2VlIGRldGFpbHMgaW4gcGFyc2VyLnJsLgorICBpbnQgbXVsdGlwYXJ0X3N0YXRlOworICB1cGJfc2VsZWN0b3JfdCBzdHJpbmdfc2VsZWN0b3I7CisKKyAgLy8gSW5wdXQgY2FwdHVyZS4gIFNlZSBkZXRhaWxzIGluIHBhcnNlci5ybC4KKyAgY29uc3QgY2hhciAqY2FwdHVyZTsKKworICAvLyBJbnRlcm1lZGlhdGUgcmVzdWx0IG9mIHBhcnNpbmcgYSB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZS4KKyAgdWludDMyX3QgZGlnaXQ7CispKTsKKworVVBCX0JFR0lOX0VYVEVSTl9DCisKK3ZvaWQgdXBiX2pzb25fcGFyc2VyX2luaXQodXBiX2pzb25fcGFyc2VyICpwLCB1cGJfc3RhdHVzICpzdGF0dXMpOwordm9pZCB1cGJfanNvbl9wYXJzZXJfdW5pbml0KHVwYl9qc29uX3BhcnNlciAqcCk7Cit2b2lkIHVwYl9qc29uX3BhcnNlcl9yZXNldCh1cGJfanNvbl9wYXJzZXIgKnApOwordm9pZCB1cGJfanNvbl9wYXJzZXJfcmVzZXRvdXRwdXQodXBiX2pzb25fcGFyc2VyICpwLCB1cGJfc2luayAqb3V0cHV0KTsKK3VwYl9ieXRlc3NpbmsgKnVwYl9qc29uX3BhcnNlcl9pbnB1dCh1cGJfanNvbl9wYXJzZXIgKnApOworCitVUEJfRU5EX0VYVEVSTl9DCisKKyNpZmRlZiBfX2NwbHVzcGx1cworCituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBqc29uIHsKK2lubGluZSBQYXJzZXI6OlBhcnNlcihTdGF0dXMqIHN0YXR1cykgeyB1cGJfanNvbl9wYXJzZXJfaW5pdCh0aGlzLCBzdGF0dXMpOyB9CitpbmxpbmUgUGFyc2VyOjp+UGFyc2VyKCkgeyB1cGJfanNvbl9wYXJzZXJfdW5pbml0KHRoaXMpOyB9CitpbmxpbmUgdm9pZCBQYXJzZXI6OlJlc2V0KCkgeyB1cGJfanNvbl9wYXJzZXJfcmVzZXQodGhpcyk7IH0KK2lubGluZSB2b2lkIFBhcnNlcjo6UmVzZXRPdXRwdXQoU2luayogb3V0cHV0KSB7CisgIHVwYl9qc29uX3BhcnNlcl9yZXNldG91dHB1dCh0aGlzLCBvdXRwdXQpOworfQoraW5saW5lIEJ5dGVzU2luayogUGFyc2VyOjppbnB1dCgpIHsKKyAgcmV0dXJuIHVwYl9qc29uX3BhcnNlcl9pbnB1dCh0aGlzKTsKK30KK30gIC8vIG5hbWVzcGFjZSBqc29uCit9ICAvLyBuYW1lc3BhY2UgdXBiCisKKyNlbmRpZgorCisKKyNlbmRpZiAgLy8gVVBCX0pTT05fUEFSU0VSX0hfCisvKgorICogdXBiIC0gYSBtaW5pbWFsaXN0IGltcGxlbWVudGF0aW9uIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDE0IEdvb2dsZSBJbmMuICBTZWUgTElDRU5TRSBmb3IgZGV0YWlscy4KKyAqIEF1dGhvcjogSm9zaCBIYWJlcm1hbiA8amhhYmVybWFuQGdtYWlsLmNvbT4KKyAqCisgKiB1cGI6Ompzb246OlByaW50ZXIgYWxsb3dzIHlvdSB0byBjcmVhdGUgaGFuZGxlcnMgdGhhdCBlbWl0IEpTT04KKyAqIGFjY29yZGluZyB0byBhIHNwZWNpZmljIHByb3RvYnVmIHNjaGVtYS4KKyAqLworCisjaWZuZGVmIFVQQl9KU09OX1RZUEVEX1BSSU5URVJfSF8KKyNkZWZpbmUgVVBCX0pTT05fVFlQRURfUFJJTlRFUl9IXworCisKKyNpZmRlZiBfX2NwbHVzcGx1cworbmFtZXNwYWNlIHVwYiB7CituYW1lc3BhY2UganNvbiB7CitjbGFzcyBQcmludGVyOworfSAgLy8gbmFtZXNwYWNlIGpzb24KK30gIC8vIG5hbWVzcGFjZSB1cGIKKyNlbmRpZgorCitVUEJfREVDTEFSRV9UWVBFKHVwYjo6anNvbjo6UHJpbnRlciwgdXBiX2pzb25fcHJpbnRlcik7CisKKworLyogdXBiOjpqc29uOjpQcmludGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLy8gUHJpbnRzIGFuIGluY29taW5nIHN0cmVhbSBvZiBkYXRhIHRvIGEgQnl0ZXNTaW5rIGluIEpTT04gZm9ybWF0LgorVVBCX0RFRklORV9DTEFTUzAodXBiOjpqc29uOjpQcmludGVyLAorIHB1YmxpYzoKKyAgUHJpbnRlcihjb25zdCB1cGI6OkhhbmRsZXJzKiBoYW5kbGVycyk7CisgIH5QcmludGVyKCk7CisKKyAgLy8gUmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgcHJpbnRlciwgc28gdGhhdCBpdCB3aWxsIGV4cGVjdCB0byBiZWdpbiBhIG5ldworICAvLyBkb2N1bWVudC4KKyAgdm9pZCBSZXNldCgpOworCisgIC8vIFJlc2V0cyB0aGUgb3V0cHV0IHBvaW50ZXIgd2hpY2ggd2lsbCBzZXJ2ZSBhcyBvdXIgY2xvc3VyZS4gIEltcGxpZXMKKyAgLy8gUmVzZXQoKS4KKyAgdm9pZCBSZXNldE91dHB1dChCeXRlc1NpbmsqIG91dHB1dCk7CisKKyAgLy8gVGhlIGlucHV0IHRvIHRoZSBwcmludGVyLgorICBTaW5rKiBpbnB1dCgpOworCisgIC8vIFJldHVybnMgaGFuZGxlcnMgZm9yIHByaW50aW5nIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIHNjaGVtYS4KKyAgc3RhdGljIHJlZmZlZF9wdHI8Y29uc3QgSGFuZGxlcnM+IE5ld0hhbmRsZXJzKGNvbnN0IHVwYjo6TWVzc2FnZURlZiogbWQpOworLAorVVBCX0RFRklORV9TVFJVQ1QwKHVwYl9qc29uX3ByaW50ZXIsCisgIHVwYl9zaW5rIGlucHV0XzsKKyAgLy8gQnl0ZXNTaW5rIGNsb3N1cmUuCisgIHZvaWQgKnN1YmNfOworICB1cGJfYnl0ZXNzaW5rICpvdXRwdXRfOworCisgIC8vIFdlIHRyYWNrIHRoZSBkZXB0aCBzbyB0aGF0IHdlIGtub3cgd2hlbiB0byBlbWl0IHN0YXJ0c3RyL2VuZHN0ciBvbiB0aGUKKyAgLy8gb3V0cHV0LgorICBpbnQgZGVwdGhfOworICAvLyBIYXZlIHdlIGVtaXR0ZWQgdGhlIGZpcnN0IGVsZW1lbnQ/IFRoaXMgc3RhdGUgaXMgbmVjZXNzYXJ5IHRvIGVtaXQgY29tbWFzCisgIC8vIHdpdGhvdXQgbGVhdmluZyBhIHRyYWlsaW5nIGNvbW1hIGluIGFycmF5cy9tYXBzLiBXZSBrZWVwIHRoaXMgc3RhdGUgcGVyCisgIC8vIGZyYW1lIGRlcHRoLgorICAvLworICAvLyBXaHkgbWF4X2RlcHRoICogMj8gVVBCX01BWF9IQU5ETEVSX0RFUFRIIGNvdW50cyBkZXB0aCBhcyBuZXN0ZWQgbWVzc2FnZXMuCisgIC8vIFdlIGNvdW50IGZyYW1lcyAoY29udGV4dHMgaW4gd2hpY2ggd2Ugc2VwYXJhdGUgZWxlbWVudHMgYnkgY29tbWFzKSBhcyBib3RoCisgIC8vIHJlcGVhdGVkIGZpZWxkcyBhbmQgbWVzc2FnZXMgKG1hcHMpLCBhbmQgdGhlIHdvcnN0IGNhc2UgaXMgYQorICAvLyBtZXNzYWdlLT5yZXBlYXRlZCBmaWVsZC0+c3VibWVzc2FnZS0+cmVwZWF0ZWQgZmllbGQtPi4uLiBuZXN0aW5nLgorICBib29sIGZpcnN0X2VsZW1fW1VQQl9NQVhfSEFORExFUl9ERVBUSCAqIDJdOworKSk7CisKK1VQQl9CRUdJTl9FWFRFUk5fQyAgLy8geworCisvLyBOYXRpdmUgQyBBUEkuCisKK3ZvaWQgdXBiX2pzb25fcHJpbnRlcl9pbml0KHVwYl9qc29uX3ByaW50ZXIgKnAsIGNvbnN0IHVwYl9oYW5kbGVycyAqaCk7Cit2b2lkIHVwYl9qc29uX3ByaW50ZXJfdW5pbml0KHVwYl9qc29uX3ByaW50ZXIgKnApOwordm9pZCB1cGJfanNvbl9wcmludGVyX3Jlc2V0KHVwYl9qc29uX3ByaW50ZXIgKnApOwordm9pZCB1cGJfanNvbl9wcmludGVyX3Jlc2V0b3V0cHV0KHVwYl9qc29uX3ByaW50ZXIgKnAsIHVwYl9ieXRlc3NpbmsgKm91dHB1dCk7Cit1cGJfc2luayAqdXBiX2pzb25fcHJpbnRlcl9pbnB1dCh1cGJfanNvbl9wcmludGVyICpwKTsKK2NvbnN0IHVwYl9oYW5kbGVycyAqdXBiX2pzb25fcHJpbnRlcl9uZXdoYW5kbGVycyhjb25zdCB1cGJfbXNnZGVmICptZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpvd25lcik7CisKK1VQQl9FTkRfRVhURVJOX0MgIC8vIH0KKworI2lmZGVmIF9fY3BsdXNwbHVzCisKK25hbWVzcGFjZSB1cGIgeworbmFtZXNwYWNlIGpzb24geworaW5saW5lIFByaW50ZXI6OlByaW50ZXIoY29uc3QgdXBiOjpIYW5kbGVycyogaGFuZGxlcnMpIHsKKyAgdXBiX2pzb25fcHJpbnRlcl9pbml0KHRoaXMsIGhhbmRsZXJzKTsKK30KK2lubGluZSBQcmludGVyOjp+UHJpbnRlcigpIHsgdXBiX2pzb25fcHJpbnRlcl91bmluaXQodGhpcyk7IH0KK2lubGluZSB2b2lkIFByaW50ZXI6OlJlc2V0KCkgeyB1cGJfanNvbl9wcmludGVyX3Jlc2V0KHRoaXMpOyB9CitpbmxpbmUgdm9pZCBQcmludGVyOjpSZXNldE91dHB1dChCeXRlc1NpbmsqIG91dHB1dCkgeworICB1cGJfanNvbl9wcmludGVyX3Jlc2V0b3V0cHV0KHRoaXMsIG91dHB1dCk7Cit9CitpbmxpbmUgU2luayogUHJpbnRlcjo6aW5wdXQoKSB7IHJldHVybiB1cGJfanNvbl9wcmludGVyX2lucHV0KHRoaXMpOyB9CitpbmxpbmUgcmVmZmVkX3B0cjxjb25zdCBIYW5kbGVycz4gUHJpbnRlcjo6TmV3SGFuZGxlcnMoCisgICAgY29uc3QgdXBiOjpNZXNzYWdlRGVmICptZCkgeworICBjb25zdCBIYW5kbGVycyogaCA9IHVwYl9qc29uX3ByaW50ZXJfbmV3aGFuZGxlcnMobWQsICZoKTsKKyAgcmV0dXJuIHJlZmZlZF9wdHI8Y29uc3QgSGFuZGxlcnM+KGgsICZoKTsKK30KK30gIC8vIG5hbWVzcGFjZSBqc29uCit9ICAvLyBuYW1lc3BhY2UgdXBiCisKKyNlbmRpZgorCisjZW5kaWYgIC8vIFVQQl9KU09OX1RZUEVEX1BSSU5URVJfSF8KZGlmZiAtLWdpdCBhL3J1YnkvZ29vZ2xlLXByb3RvYnVmLmdlbXNwZWMgYi9ydWJ5L2dvb2dsZS1wcm90b2J1Zi5nZW1zcGVjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjOTQ0OWQKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L2dvb2dsZS1wcm90b2J1Zi5nZW1zcGVjCkBAIC0wLDAgKzEsMjMgQEAKK0dlbTo6U3BlY2lmaWNhdGlvbi5uZXcgZG8gfHN8CisgIHMubmFtZSAgICAgICAgPSAiZ29vZ2xlLXByb3RvYnVmIgorICBzLnZlcnNpb24gICAgID0gIjMuMC4wLmFscGhhLjMuMC5wcmUiCisgIHMubGljZW5zZXMgICAgPSBbIkJTRCJdCisgIHMuc3VtbWFyeSAgICAgPSAiUHJvdG9jb2wgQnVmZmVycyIKKyAgcy5kZXNjcmlwdGlvbiA9ICJQcm90b2NvbCBCdWZmZXJzIGFyZSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdC4iCisgIHMuYXV0aG9ycyAgICAgPSBbIlByb3RvYnVmIEF1dGhvcnMiXQorICBzLmVtYWlsICAgICAgID0gInByb3RvYnVmQGdvb2dsZWdyb3Vwcy5jb20iCisgIHMucmVxdWlyZV9wYXRocyA9IFsibGliIl0KKyAgcy5maWxlcyAgICAgICA9IFsibGliL2dvb2dsZS9wcm90b2J1Zi5yYiJdCisgIHVubGVzcyBSVUJZX1BMQVRGT1JNID09ICJqYXZhIgorICAgIHMuZmlsZXMgICAgICs9IGBnaXQgbHMtZmlsZXMgIiouYyIgIiouaCIgZXh0Y29uZi5yYiBNYWtlZmlsZWAuc3BsaXQKKyAgICBzLmV4dGVuc2lvbnM9IFsiZXh0L2dvb2dsZS9wcm90b2J1Zl9jL2V4dGNvbmYucmIiXQorICBlbHNlCisgICAgcy5maWxlcyAgICAgKz0gWyJsaWIvZ29vZ2xlL3Byb3RvYnVmX2phdmEuamFyIl0KKyAgZW5kCisgIHMudGVzdF9maWxlcyAgPSBbInRlc3RzL2Jhc2ljLnJiIiwKKyAgICAgICAgICAgICAgICAgICJ0ZXN0cy9zdHJlc3MucmIiLAorICAgICAgICAgICAgICAgICAgInRlc3RzL2dlbmVyYXRlZF9jb2RlX3Rlc3QucmIiXQorICBzLmFkZF9kZXZlbG9wbWVudF9kZXBlbmRlbmN5ICJyYWtlLWNvbXBpbGVyIgorICBzLmFkZF9kZXZlbG9wbWVudF9kZXBlbmRlbmN5ICJ0ZXN0LXVuaXQiCisgIHMuYWRkX2RldmVsb3BtZW50X2RlcGVuZGVuY3kgInJ1YnlnZW1zLXRhc2tzIgorZW5kCmRpZmYgLS1naXQgYS9ydWJ5L2xpYi9nb29nbGUvcHJvdG9idWYucmIgYi9ydWJ5L2xpYi9nb29nbGUvcHJvdG9idWYucmIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzU4NjlkZAotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvbGliL2dvb2dsZS9wcm90b2J1Zi5yYgpAQCAtMCwwICsxLDM2IEBACisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK2lmIFJVQllfUExBVEZPUk0gPT0gImphdmEiCisgIHJlcXVpcmUgJ2pzb24nCisgIHJlcXVpcmUgJ2dvb2dsZS9wcm90b2J1Zl9qYXZhJworZWxzZQorICByZXF1aXJlICdnb29nbGUvcHJvdG9idWZfYycKK2VuZApkaWZmIC0tZ2l0IGEvcnVieS9wb20ueG1sIGIvcnVieS9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MzBmZTgKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3BvbS54bWwKQEAgLTAsMCArMSw4NCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisgICAgICAgICB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorICAgICAgICAgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcveHNkL21hdmVuLTQuMC4wLnhzZCI+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxwYXJlbnQ+CisgICAgICA8Z3JvdXBJZD5jb20uZ29vZ2xlPC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+Z29vZ2xlPC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+MTwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKworICAgIDxncm91cElkPmNvbS5nb29nbGUucHJvdG9idWYuanJ1Ynk8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+cHJvdG9idWYtanJ1Ynk8L2FydGlmYWN0SWQ+CisgICAgPHZlcnNpb24+MS4wLVNOQVBTSE9UPC92ZXJzaW9uPgorICAgIDxuYW1lPlByb3RvY29sIEJ1ZmZlciBKUnVieSBuYXRpdmUgZXh0ZW5zaW9uPC9uYW1lPgorICAgIDxkZXNjcmlwdGlvbj4KKyAgICAgIFByb3RvY29sIEJ1ZmZlcnMgYXJlIGEgd2F5IG9mIGVuY29kaW5nIHN0cnVjdHVyZWQgZGF0YSBpbiBhbiBlZmZpY2llbnQgeWV0CisgICAgICBleHRlbnNpYmxlIGZvcm1hdC4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICAgIDxpbmNlcHRpb25ZZWFyPjIwMTQ8L2luY2VwdGlvblllYXI+CisgICAgPHVybD5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLzwvdXJsPgorICAgIDxsaWNlbnNlcz4KKyAgICAgIDxsaWNlbnNlPgorICAgICAgICA8bmFtZT5OZXcgQlNEIGxpY2Vuc2U8L25hbWU+CisgICAgICAgIDx1cmw+aHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9ic2QtbGljZW5zZS5waHA8L3VybD4KKyAgICAgICAgPGRpc3RyaWJ1dGlvbj5yZXBvPC9kaXN0cmlidXRpb24+CisgICAgICA8L2xpY2Vuc2U+CisgICAgPC9saWNlbnNlcz4KKyAgICA8c2NtPgorICAgICAgPHVybD5odHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmPC91cmw+CisgICAgICA8Y29ubmVjdGlvbj4KKyAgICAgICAgc2NtOmdpdDpodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmLmdpdAorICAgICAgPC9jb25uZWN0aW9uPgorICAgIDwvc2NtPgorCisgICAgPHByb3BlcnRpZXM+CisgICAgICAgIDxwcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPlVURi04PC9wcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPgorICAgICAgICA8cnVieS5zb3VyY2VzPmxpYi9nb29nbGU8L3J1Ynkuc291cmNlcz4KKyAgICAgICAgPGphci5maW5hbE5hbWU+cHJvdG9idWZfamF2YTwvamFyLmZpbmFsTmFtZT4KKyAgICA8L3Byb3BlcnRpZXM+CisgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKyAgICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWFzc2VtYmx5LXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgICAgICAgPGZpbmFsTmFtZT4ke2phci5maW5hbE5hbWV9PC9maW5hbE5hbWU+CisgICAgICAgICAgICAgICAgICAgIDxvdXRwdXREaXJlY3Rvcnk+JHtydWJ5LnNvdXJjZXN9PC9vdXRwdXREaXJlY3Rvcnk+CisgICAgICAgICAgICAgICAgICAgIDxhcHBlbmRBc3NlbWJseUlkPmZhbHNlPC9hcHBlbmRBc3NlbWJseUlkPgorICAgICAgICAgICAgICAgICAgICA8ZGVzY3JpcHRvclJlZnM+CisgICAgICAgICAgICAgICAgICAgICAgICA8ZGVzY3JpcHRvclJlZj5qYXItd2l0aC1kZXBlbmRlbmNpZXM8L2Rlc2NyaXB0b3JSZWY+CisgICAgICAgICAgICAgICAgICAgIDwvZGVzY3JpcHRvclJlZnM+CisgICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICAgICAgICAgIDxleGVjdXRpb25zPgorICAgICAgICAgICAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgICAgICAgICAgPGlkPm1ha2UtYXNzZW1ibHk8L2lkPgorICAgICAgICAgICAgICAgICAgICAgICAgPHBoYXNlPnBhY2thZ2U8L3BoYXNlPgorICAgICAgICAgICAgICAgICAgICAgICAgPGdvYWxzPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnb2FsPnNpbmdsZTwvZ29hbD4KKyAgICAgICAgICAgICAgICAgICAgICAgIDwvZ29hbHM+CisgICAgICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5mYXN0ZXJ4bWwuamFja3Nvbi5jb3JlPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+amFja3Nvbi1jb3JlPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+Mi40LjM8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuanJ1Ynk8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qcnVieS1jb21wbGV0ZTwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjEuNy4xMzwvdmVyc2lvbj4KKyAgICAgICAgICAgIDxzY29wZT5wcm92aWRlZDwvc2NvcGU+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uZ29vZ2xlLnByb3RvYnVmPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+cHJvdG9idWYtamF2YTwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjMuMC4wLXByZTwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieUJ1aWxkZXIuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWFkZGFlNQotLS0gL2Rldi9udWxsCisrKyBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlCdWlsZGVyLmphdmEKQEAgLTAsMCArMSwxNjcgQEAKKy8qCisgKiBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyAqIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAqIG1ldDoKKyAqCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorICogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorICogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorICogZGlzdHJpYnV0aW9uLgorICogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworICogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1Ynk7CisKK2ltcG9ydCBvcmcuanJ1YnkuKjsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieUNsYXNzOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5TWV0aG9kOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLio7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuYnVpbHRpbi5JUnVieU9iamVjdDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJCdWlsZGVyIikKK3B1YmxpYyBjbGFzcyBSdWJ5QnVpbGRlciBleHRlbmRzIFJ1YnlPYmplY3QgeworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjcmVhdGVSdWJ5QnVpbGRlcihSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBwcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY0J1aWxkZXIgPSBwcm90b2J1Zi5kZWZpbmVDbGFzc1VuZGVyKCJCdWlsZGVyIiwgcnVudGltZS5nZXRPYmplY3QoKSwgbmV3IE9iamVjdEFsbG9jYXRvcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIElSdWJ5T2JqZWN0IGFsbG9jYXRlKFJ1YnkgcnVudGltZSwgUnVieUNsYXNzIGtsYXp6KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSdWJ5QnVpbGRlcihydW50aW1lLCBrbGF6eik7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBjQnVpbGRlci5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlCdWlsZGVyLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVieUJ1aWxkZXIoUnVieSBydW50aW1lLCBSdWJ5Q2xhc3MgbWV0YUNsYXNzKSB7CisgICAgICAgIHN1cGVyKHJ1bnRpbWUsIG1ldGFDbGFzcyk7CisgICAgICAgIHRoaXMuY0Rlc2NyaXB0b3IgPSAoUnVieUNsYXNzKSBydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkRlc2NyaXB0b3IiKTsKKyAgICAgICAgdGhpcy5jRW51bURlc2NyaXB0b3IgPSAoUnVieUNsYXNzKSBydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkVudW1EZXNjcmlwdG9yIik7CisgICAgICAgIHRoaXMuY01lc3NhZ2VCdWlsZGVyQ29udGV4dCA9IChSdWJ5Q2xhc3MpIHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1Zjo6TWVzc2FnZUJ1aWxkZXJDb250ZXh0Iik7CisgICAgICAgIHRoaXMuY0VudW1CdWlsZGVyQ29udGV4dCA9IChSdWJ5Q2xhc3MpIHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1Zjo6RW51bUJ1aWxkZXJDb250ZXh0Iik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgQnVpbGRlci5uZXcgPT4gYnVpbGRlcgorICAgICAqCisgICAgICogQ3JlYXRlcyBhIG5ldyBCdWlsZGVyLiBBIEJ1aWxkZXIgY2FuIGFjY3VtdWxhdGUgYSBzZXQgb2YgbmV3IG1lc3NhZ2UgYW5kIGVudW0KKyAgICAgKiBkZXNjcmlwdG9ycyBhbmQgYXRvbWljYWxseSByZWdpc3RlciB0aGVtIGludG8gYSBwb29sIGluIGEgd2F5IHRoYXQgYWxsb3dzIGZvcgorICAgICAqIChjbylyZWN1cnNpdmUgdHlwZSByZWZlcmVuY2VzLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBpbml0aWFsaXplKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIHRoaXMucGVuZGluZ0xpc3QgPSBydW50aW1lLm5ld0FycmF5KCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEJ1aWxkZXIuYWRkX21lc3NhZ2UobmFtZSwgJmJsb2NrKQorICAgICAqCisgICAgICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgZGVzY3JpcHRvciB3aXRoIHRoZSBnaXZlbiBuYW1lLCBhbmQgaW52b2tlcyB0aGUgYmxvY2sgaW4KKyAgICAgKiB0aGUgY29udGV4dCBvZiBhIE1lc3NhZ2VCdWlsZGVyQ29udGV4dCBvbiB0aGF0IGRlc2NyaXB0b3IuIFRoZSBibG9jayBjYW4gdGhlbgorICAgICAqIGNhbGwsIGUuZy4sIE1lc3NhZ2VCdWlsZGVyQ29udGV4dCNvcHRpb25hbCBhbmQgTWVzc2FnZUJ1aWxkZXJDb250ZXh0I3JlcGVhdGVkCisgICAgICogbWV0aG9kcyB0byBkZWZpbmUgdGhlIG1lc3NhZ2UgZmllbGRzLgorICAgICAqCisgICAgICogVGhpcyBpcyB0aGUgcmVjb21tZW5kZWQsIGlkaW9tYXRpYyB3YXkgdG8gYnVpbGQgbWVzc2FnZSBkZWZpbml0aW9ucy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJhZGRfbWVzc2FnZSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGFkZE1lc3NhZ2UoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBuYW1lLCBCbG9jayBibG9jaykgeworICAgICAgICBSdWJ5RGVzY3JpcHRvciBtc2dkZWYgPSAoUnVieURlc2NyaXB0b3IpIGNEZXNjcmlwdG9yLm5ld0luc3RhbmNlKGNvbnRleHQsIEJsb2NrLk5VTExfQkxPQ0spOworICAgICAgICBJUnVieU9iamVjdCBjdHggPSBjTWVzc2FnZUJ1aWxkZXJDb250ZXh0Lm5ld0luc3RhbmNlKGNvbnRleHQsIG1zZ2RlZiwgdGhpcywgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgIG1zZ2RlZi5zZXROYW1lKGNvbnRleHQsIG5hbWUpOworICAgICAgICBpZiAoYmxvY2suaXNHaXZlbigpKSB7CisgICAgICAgICAgICBpZiAoYmxvY2suYXJpdHkoKSA9PSBBcml0eS5PTkVfQVJHVU1FTlQpIHsKKyAgICAgICAgICAgICAgICBibG9jay55aWVsZChjb250ZXh0LCBjdHgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBCaW5kaW5nIGJpbmRpbmcgPSBibG9jay5nZXRCaW5kaW5nKCk7CisgICAgICAgICAgICAgICAgYmluZGluZy5zZXRTZWxmKGN0eCk7CisgICAgICAgICAgICAgICAgYmxvY2sueWllbGRTcGVjaWZpYyhjb250ZXh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLnBlbmRpbmdMaXN0LmFkZChtc2dkZWYpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEJ1aWxkZXIuYWRkX2VudW0obmFtZSwgJmJsb2NrKQorICAgICAqCisgICAgICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgZW51bSBkZXNjcmlwdG9yIHdpdGggdGhlIGdpdmVuIG5hbWUsIGFuZCBpbnZva2VzIHRoZSBibG9jayBpbgorICAgICAqIHRoZSBjb250ZXh0IG9mIGFuIEVudW1CdWlsZGVyQ29udGV4dCBvbiB0aGF0IGRlc2NyaXB0b3IuIFRoZSBibG9jayBjYW4gdGhlbgorICAgICAqIGNhbGwgRW51bUJ1aWxkZXJDb250ZXh0I2FkZF92YWx1ZSB0byBkZWZpbmUgdGhlIGVudW0gdmFsdWVzLgorICAgICAqCisgICAgICogVGhpcyBpcyB0aGUgcmVjb21tZW5kZWQsIGlkaW9tYXRpYyB3YXkgdG8gYnVpbGQgZW51bSBkZWZpbml0aW9ucy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJhZGRfZW51bSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGFkZEVudW0oVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBuYW1lLCBCbG9jayBibG9jaykgeworICAgICAgICBSdWJ5RW51bURlc2NyaXB0b3IgZW51bURlZiA9IChSdWJ5RW51bURlc2NyaXB0b3IpIGNFbnVtRGVzY3JpcHRvci5uZXdJbnN0YW5jZShjb250ZXh0LCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgSVJ1YnlPYmplY3QgY3R4ID0gY0VudW1CdWlsZGVyQ29udGV4dC5uZXdJbnN0YW5jZShjb250ZXh0LCBlbnVtRGVmLCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgZW51bURlZi5zZXROYW1lKGNvbnRleHQsIG5hbWUpOworCisgICAgICAgIGlmIChibG9jay5pc0dpdmVuKCkpIHsKKyAgICAgICAgICAgIGlmIChibG9jay5hcml0eSgpID09IEFyaXR5Lk9ORV9BUkdVTUVOVCkgeworICAgICAgICAgICAgICAgIGJsb2NrLnlpZWxkKGNvbnRleHQsIGN0eCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIEJpbmRpbmcgYmluZGluZyA9IGJsb2NrLmdldEJpbmRpbmcoKTsKKyAgICAgICAgICAgICAgICBiaW5kaW5nLnNldFNlbGYoY3R4KTsKKyAgICAgICAgICAgICAgICBibG9jay55aWVsZFNwZWNpZmljKGNvbnRleHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5wZW5kaW5nTGlzdC5hZGQoZW51bURlZik7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgQnVpbGRlci5maW5hbGl6ZV90b19wb29sKHBvb2wpCisgICAgICoKKyAgICAgKiBBZGRzIGFsbCBhY2N1bXVsYXRlZCBtZXNzYWdlIGFuZCBlbnVtIGRlc2NyaXB0b3JzIGNyZWF0ZWQgaW4gdGhpcyBidWlsZGVyCisgICAgICogY29udGV4dCB0byB0aGUgZ2l2ZW4gcG9vbC4gVGhlIG9wZXJhdGlvbiBvY2N1cnMgYXRvbWljYWxseSwgYW5kIGFsbAorICAgICAqIGRlc2NyaXB0b3JzIGNhbiByZWZlciB0byBlYWNoIG90aGVyIChpbmNsdWRpbmcgaW4gY3ljbGVzKS4gVGhpcyBpcyB0aGUgb25seQorICAgICAqIHdheSB0byBidWlsZCAoY28pcmVjdXJzaXZlIG1lc3NhZ2UgZGVmaW5pdGlvbnMuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IERlc2NyaXB0b3JQb29sI2J1aWxkIGFmdGVyIGl0CisgICAgICogaW52b2tlcyB0aGUgZ2l2ZW4gdXNlciBibG9jayBpbiB0aGUgY29udGV4dCBvZiB0aGUgYnVpbGRlci4gVGhlIHVzZXIgc2hvdWxkCisgICAgICogbm90IG5vcm1hbGx5IG5lZWQgdG8gY2FsbCB0aGlzIG1hbnVhbGx5IGJlY2F1c2UgYSBCdWlsZGVyIGlzIG5vdCBub3JtYWxseQorICAgICAqIGNyZWF0ZWQgbWFudWFsbHkuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiZmluYWxpemVfdG9fcG9vbCIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGZpbmFsaXplVG9Qb29sKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgcmJQb29sKSB7CisgICAgICAgIFJ1YnlEZXNjcmlwdG9yUG9vbCBwb29sID0gKFJ1YnlEZXNjcmlwdG9yUG9vbCkgcmJQb29sOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMucGVuZGluZ0xpc3Quc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIElSdWJ5T2JqZWN0IGRlZlJiID0gdGhpcy5wZW5kaW5nTGlzdC5lbnRyeShpKTsKKyAgICAgICAgICAgIGlmIChkZWZSYiBpbnN0YW5jZW9mIFJ1YnlEZXNjcmlwdG9yKSB7CisgICAgICAgICAgICAgICAgcG9vbC5hZGRUb1N5bXRhYihjb250ZXh0LCAoUnVieURlc2NyaXB0b3IpIGRlZlJiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcG9vbC5hZGRUb1N5bXRhYihjb250ZXh0LCAoUnVieUVudW1EZXNjcmlwdG9yKSBkZWZSYik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wZW5kaW5nTGlzdCA9IGNvbnRleHQucnVudGltZS5uZXdBcnJheSgpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCBSdWJ5QXJyYXkgcGVuZGluZ0xpc3Q7CisgICAgcHJpdmF0ZSBSdWJ5Q2xhc3MgY0Rlc2NyaXB0b3IsIGNFbnVtRGVzY3JpcHRvciwgY01lc3NhZ2VCdWlsZGVyQ29udGV4dCwgY0VudW1CdWlsZGVyQ29udGV4dDsKK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlEZXNjcmlwdG9yLmphdmEgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxYzUwYmUKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsMjY3IEBACisvKgorICogUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisgKiBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisgKiBtZXQ6CisgKgorICogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyAqIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyAqIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyAqIGRpc3RyaWJ1dGlvbi4KKyAqICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyAqIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisgKiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyAqICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyAqIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisgKiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisgKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5OworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnM7CitpbXBvcnQgb3JnLmpydWJ5Lio7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlDbGFzczsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieU1ldGhvZDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5CbG9jazsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5PYmplY3RBbGxvY2F0b3I7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuVGhyZWFkQ29udGV4dDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworCitASlJ1YnlDbGFzcyhuYW1lID0gIkRlc2NyaXB0b3IiLCBpbmNsdWRlID0gIkVudW1lcmFibGUiKQorcHVibGljIGNsYXNzIFJ1YnlEZXNjcmlwdG9yIGV4dGVuZHMgUnVieU9iamVjdCB7CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNyZWF0ZVJ1YnlEZXNjcmlwdG9yKFJ1YnkgcnVudGltZSkgeworICAgICAgICBSdWJ5TW9kdWxlIHByb3RvYnVmID0gcnVudGltZS5nZXRDbGFzc0Zyb21QYXRoKCJHb29nbGU6OlByb3RvYnVmIik7CisgICAgICAgIFJ1YnlDbGFzcyBjRGVzY3JpcHRvciA9IHByb3RvYnVmLmRlZmluZUNsYXNzVW5kZXIoIkRlc2NyaXB0b3IiLCBydW50aW1lLmdldE9iamVjdCgpLCBuZXcgT2JqZWN0QWxsb2NhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgSVJ1YnlPYmplY3QgYWxsb2NhdGUoUnVieSBydW50aW1lLCBSdWJ5Q2xhc3Mga2xhenopIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJ1YnlEZXNjcmlwdG9yKHJ1bnRpbWUsIGtsYXp6KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGNEZXNjcmlwdG9yLmluY2x1ZGVNb2R1bGUocnVudGltZS5nZXRFbnVtZXJhYmxlKCkpOworICAgICAgICBjRGVzY3JpcHRvci5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlEZXNjcmlwdG9yLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVieURlc2NyaXB0b3IoUnVieSBydW50aW1lLCBSdWJ5Q2xhc3Mga2xhenopIHsKKyAgICAgICAgc3VwZXIocnVudGltZSwga2xhenopOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIERlc2NyaXB0b3IubmV3ID0+IGRlc2NyaXB0b3IKKyAgICAgKgorICAgICAqIENyZWF0ZXMgYSBuZXcsIGVtcHR5LCBtZXNzYWdlIHR5cGUgZGVzY3JpcHRvci4gQXQgYSBtaW5pbXVtLCBpdHMgbmFtZSBtdXN0IGJlCisgICAgICogc2V0IGJlZm9yZSBpdCBpcyBhZGRlZCB0byBhIHBvb2wuIEl0IGNhbm5vdCBiZSB1c2VkIHRvIGNyZWF0ZSBtZXNzYWdlcyB1bnRpbAorICAgICAqIGl0IGlzIGFkZGVkIHRvIGEgcG9vbCwgYWZ0ZXIgd2hpY2ggaXQgYmVjb21lcyBpbW11dGFibGUgKGFzIHBhcnQgb2YgYQorICAgICAqIGZpbmFsaXphdGlvbiBwcm9jZXNzKS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5pdGlhbGl6ZShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyID0gRGVzY3JpcHRvclByb3Rvcy5EZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpOworICAgICAgICB0aGlzLmZpZWxkRGVmTWFwID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBSdWJ5RmllbGREZXNjcmlwdG9yPigpOworICAgICAgICB0aGlzLm9uZW9mRGVmcyA9IG5ldyBIYXNoTWFwPElSdWJ5T2JqZWN0LCBSdWJ5T25lb2ZEZXNjcmlwdG9yPigpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBEZXNjcmlwdG9yLm5hbWUgPT4gbmFtZQorICAgICAqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIG1lc3NhZ2UgdHlwZSBhcyBhIGZ1bGx5LXF1YWxmaWVkIHN0cmluZyAoZS5nLiwKKyAgICAgKiBNeS5QYWNrYWdlLk1lc3NhZ2VUeXBlKS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJuYW1lIikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgZ2V0TmFtZShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMubmFtZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgIERlc2NyaXB0b3IubmFtZSA9IG5hbWUKKyAgICAgKgorICAgICAqIEFzc2lnbnMgYSBuYW1lIHRvIHRoaXMgbWVzc2FnZSB0eXBlLiBUaGUgZGVzY3JpcHRvciBtdXN0IG5vdCBoYXZlIGJlZW4gYWRkZWQKKyAgICAgKiB0byBhIHBvb2wgeWV0LgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gIm5hbWU9IikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3Qgc2V0TmFtZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG5hbWUpIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgdGhpcy5idWlsZGVyLnNldE5hbWUoVXRpbHMuZXNjYXBlSWRlbnRpZmllcih0aGlzLm5hbWUuYXNKYXZhU3RyaW5nKCkpKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBEZXNjcmlwdG9yLmFkZF9maWVsZChmaWVsZCkgPT4gbmlsCisgICAgICoKKyAgICAgKiBBZGRzIHRoZSBnaXZlbiBGaWVsZERlc2NyaXB0b3IgdG8gdGhpcyBtZXNzYWdlIHR5cGUuIFRoZSBkZXNjcmlwdG9yIG11c3Qgbm90CisgICAgICogaGF2ZSBiZWVuIGFkZGVkIHRvIGEgcG9vbCB5ZXQuIFJhaXNlcyBhbiBleGNlcHRpb24gaWYgYSBmaWVsZCB3aXRoIHRoZSBzYW1lCisgICAgICogbmFtZSBvciBudW1iZXIgYWxyZWFkeSBleGlzdHMuIFN1Yi10eXBlIHJlZmVyZW5jZXMgKGUuZy4gZm9yIGZpZWxkcyBvZiB0eXBlCisgICAgICogbWVzc2FnZSkgYXJlIG5vdCByZXNvbHZlZCBhdCB0aGlzIHBvaW50LgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gImFkZF9maWVsZCIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGFkZEZpZWxkKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3Qgb2JqKSB7CisgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IgZmllbGREZWYgPSAoUnVieUZpZWxkRGVzY3JpcHRvcikgb2JqOworICAgICAgICB0aGlzLmZpZWxkRGVmTWFwLnB1dChmaWVsZERlZi5nZXROYW1lKGNvbnRleHQpLmFzSmF2YVN0cmluZygpLCBmaWVsZERlZik7CisgICAgICAgIHRoaXMuYnVpbGRlci5hZGRGaWVsZChmaWVsZERlZi5idWlsZCgpKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBEZXNjcmlwdG9yLmxvb2t1cChuYW1lKSA9PiBGaWVsZERlc2NyaXB0b3IKKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlIGZpZWxkIGRlc2NyaXB0b3IgZm9yIHRoZSBmaWVsZCB3aXRoIHRoZSBnaXZlbiBuYW1lLCBpZiBwcmVzZW50LAorICAgICAqIG9yIG5pbCBpZiBub25lLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBsb29rdXAoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBmaWVsZE5hbWUpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZmllbGREZWZNYXAuZ2V0KGZpZWxkTmFtZS5hc0phdmFTdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRGVzY3JpcHRvci5tc2djbGFzcyA9PiBtZXNzYWdlX2tsYXNzCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSBSdWJ5IGNsYXNzIGNyZWF0ZWQgZm9yIHRoaXMgbWVzc2FnZSB0eXBlLiBWYWxpZCBvbmx5IG9uY2UgdGhlCisgICAgICogbWVzc2FnZSB0eXBlIGhhcyBiZWVuIGFkZGVkIHRvIGEgcG9vbC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgbXNnY2xhc3MoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIGlmICh0aGlzLmtsYXp6ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMua2xhenogPSBidWlsZENsYXNzRnJvbURlc2NyaXB0b3IoY29udGV4dCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMua2xheno7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRGVzY3JpcHRvci5lYWNoKCZibG9jaykKKyAgICAgKgorICAgICAqIEl0ZXJhdGVzIG92ZXIgZmllbGRzIGluIHRoaXMgbWVzc2FnZSB0eXBlLCB5aWVsZGluZyB0byB0aGUgYmxvY2sgb24gZWFjaCBvbmUuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGVhY2goVGhyZWFkQ29udGV4dCBjb250ZXh0LCBCbG9jayBibG9jaykgeworICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFJ1YnlGaWVsZERlc2NyaXB0b3I+IGVudHJ5IDogZmllbGREZWZNYXAuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgYmxvY2sueWllbGQoY29udGV4dCwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBEZXNjcmlwdG9yLmFkZF9vbmVvZihvbmVvZikgPT4gbmlsCisgICAgICoKKyAgICAgKiBBZGRzIHRoZSBnaXZlbiBPbmVvZkRlc2NyaXB0b3IgdG8gdGhpcyBtZXNzYWdlIHR5cGUuIFRoaXMgZGVzY3JpcHRvciBtdXN0IG5vdAorICAgICAqIGhhdmUgYmVlbiBhZGRlZCB0byBhIHBvb2wgeWV0LiBSYWlzZXMgYW4gZXhjZXB0aW9uIGlmIGEgb25lb2Ygd2l0aCB0aGUgc2FtZQorICAgICAqIG5hbWUgYWxyZWFkeSBleGlzdHMsIG9yIGlmIGFueSBvZiB0aGUgb25lb2YncyBmaWVsZHMnIG5hbWVzIG9yIG51bWJlcnMKKyAgICAgKiBjb25mbGljdCB3aXRoIGFuIGV4aXN0aW5nIGZpZWxkIGluIHRoaXMgbWVzc2FnZSB0eXBlLiBBbGwgZmllbGRzIGluIHRoZSBvbmVvZgorICAgICAqIGFyZSBhZGRlZCB0byB0aGUgbWVzc2FnZSBkZXNjcmlwdG9yLiBTdWItdHlwZSByZWZlcmVuY2VzIChlLmcuIGZvciBmaWVsZHMgb2YKKyAgICAgKiB0eXBlIG1lc3NhZ2UpIGFyZSBub3QgcmVzb2x2ZWQgYXQgdGhpcyBwb2ludC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJhZGRfb25lb2YiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBhZGRPbmVvZihUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG9iaikgeworICAgICAgICBSdWJ5T25lb2ZEZXNjcmlwdG9yIGRlZiA9IChSdWJ5T25lb2ZEZXNjcmlwdG9yKSBvYmo7CisgICAgICAgIGJ1aWxkZXIuYWRkT25lb2ZEZWNsKGRlZi5idWlsZChidWlsZGVyLmdldE9uZW9mRGVjbENvdW50KCkpKTsKKyAgICAgICAgZm9yIChSdWJ5RmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA6IGRlZi5nZXRGaWVsZHMoKSkgeworICAgICAgICAgICAgYWRkRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgfQorICAgICAgICBvbmVvZkRlZnMucHV0KGRlZi5nZXROYW1lKGNvbnRleHQpLCBkZWYpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIERlc2NyaXB0b3IuZWFjaF9vbmVvZigmYmxvY2spID0+IG5pbAorICAgICAqCisgICAgICogSW52b2tlcyB0aGUgZ2l2ZW4gYmxvY2sgZm9yIGVhY2ggb25lb2YgaW4gdGhpcyBtZXNzYWdlIHR5cGUsIHBhc3NpbmcgdGhlCisgICAgICogY29ycmVzcG9uZGluZyBPbmVvZkRlc2NyaXB0b3IuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiZWFjaF9vbmVvZiIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGVhY2hPbmVvZihUaHJlYWRDb250ZXh0IGNvbnRleHQsIEJsb2NrIGJsb2NrKSB7CisgICAgICAgIGZvciAoUnVieU9uZW9mRGVzY3JpcHRvciBvbmVvZkRlc2NyaXB0b3IgOiBvbmVvZkRlZnMudmFsdWVzKCkpIHsKKyAgICAgICAgICAgIGJsb2NrLnlpZWxkU3BlY2lmaWMoY29udGV4dCwgb25lb2ZEZXNjcmlwdG9yKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIERlc2NyaXB0b3IubG9va3VwX29uZW9mKG5hbWUpID0+IE9uZW9mRGVzY3JpcHRvcgorICAgICAqCisgICAgICogUmV0dXJucyB0aGUgb25lb2YgZGVzY3JpcHRvciBmb3IgdGhlIG9uZW9mIHdpdGggdGhlIGdpdmVuIG5hbWUsIGlmIHByZXNlbnQsCisgICAgICogb3IgbmlsIGlmIG5vbmUuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAibG9va3VwX29uZW9mIikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgbG9va3VwT25lb2YoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lIGluc3RhbmNlb2YgUnVieVN5bWJvbCkgeworICAgICAgICAgICAgbmFtZSA9ICgoUnVieVN5bWJvbCkgbmFtZSkuaWQybmFtZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBvbmVvZkRlZnMuY29udGFpbnNLZXkobmFtZSkgPyBvbmVvZkRlZnMuZ2V0KG5hbWUpIDogY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERlc2NyaXB0b3IoRGVzY3JpcHRvcnMuRGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CisgICAgICAgIHRoaXMuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgICAgfQorCisgICAgcHVibGljIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZ2V0RGVzY3JpcHRvcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRvcjsKKyAgICB9CisKKyAgICBwdWJsaWMgRGVzY3JpcHRvclByb3Rvcy5EZXNjcmlwdG9yUHJvdG8uQnVpbGRlciBnZXRCdWlsZGVyKCkgeworICAgICAgICByZXR1cm4gYnVpbGRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNYXBFbnRyeShib29sZWFuIGlzTWFwRW50cnkpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyLnNldE9wdGlvbnMoRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucy5uZXdCdWlsZGVyKCkuc2V0TWFwRW50cnkoaXNNYXBFbnRyeSkpOworICAgIH0KKworICAgIHByaXZhdGUgUnVieU1vZHVsZSBidWlsZENsYXNzRnJvbURlc2NyaXB0b3IoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIFJ1YnkgcnVudGltZSA9IGNvbnRleHQucnVudGltZTsKKworICAgICAgICBPYmplY3RBbGxvY2F0b3IgYWxsb2NhdG9yID0gbmV3IE9iamVjdEFsbG9jYXRvcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIElSdWJ5T2JqZWN0IGFsbG9jYXRlKFJ1YnkgcnVudGltZSwgUnVieUNsYXNzIGtsYXp6KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSdWJ5TWVzc2FnZShydW50aW1lLCBrbGF6eiwgZGVzY3JpcHRvcik7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgLy8gcmJfZGVmaW5lX2NsYXNzX2lkCisgICAgICAgIFJ1YnlDbGFzcyBrbGFzcyA9IFJ1YnlDbGFzcy5uZXdDbGFzcyhydW50aW1lLCBydW50aW1lLmdldE9iamVjdCgpKTsKKyAgICAgICAga2xhc3Muc2V0QWxsb2NhdG9yKGFsbG9jYXRvcik7CisgICAgICAgIGtsYXNzLm1ha2VNZXRhQ2xhc3MocnVudGltZS5nZXRPYmplY3QoKS5nZXRNZXRhQ2xhc3MoKSk7CisgICAgICAgIGtsYXNzLmluaGVyaXQocnVudGltZS5nZXRPYmplY3QoKSk7CisgICAgICAgIGtsYXNzLmluc3RhbmNlX3ZhcmlhYmxlX3NldChydW50aW1lLm5ld1N0cmluZyhVdGlscy5ERVNDUklQVE9SX0lOU1RBTkNFX1ZBUiksIHRoaXMpOworICAgICAgICBrbGFzcy5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlNZXNzYWdlLmNsYXNzKTsKKyAgICAgICAgcmV0dXJuIGtsYXNzOworICAgIH0KKworICAgIHByb3RlY3RlZCBSdWJ5RmllbGREZXNjcmlwdG9yIGxvb2t1cChTdHJpbmcgZmllbGROYW1lKSB7CisgICAgICAgIHJldHVybiBmaWVsZERlZk1hcC5nZXQoVXRpbHMudW5lc2NhcGVJZGVudGlmaWVyKGZpZWxkTmFtZSkpOworICAgIH0KKworICAgIHByaXZhdGUgSVJ1YnlPYmplY3QgbmFtZTsKKyAgICBwcml2YXRlIFJ1YnlNb2R1bGUga2xheno7CisKKyAgICBwcml2YXRlIERlc2NyaXB0b3JQcm90b3MuRGVzY3JpcHRvclByb3RvLkJ1aWxkZXIgYnVpbGRlcjsKKyAgICBwcml2YXRlIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFJ1YnlGaWVsZERlc2NyaXB0b3I+IGZpZWxkRGVmTWFwOworICAgIHByaXZhdGUgTWFwPElSdWJ5T2JqZWN0LCBSdWJ5T25lb2ZEZXNjcmlwdG9yPiBvbmVvZkRlZnM7Cit9CmRpZmYgLS1naXQgYS9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RGVzY3JpcHRvclBvb2wuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlEZXNjcmlwdG9yUG9vbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNDVjYjkKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RGVzY3JpcHRvclBvb2wuamF2YQpAQCAtMCwwICsxLDE2OSBAQAorLyoKKyAqIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorICogQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorICogbWV0OgorICoKKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisgKiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisgKiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisgKiBkaXN0cmlidXRpb24uCisgKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisgKiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorICogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorICovCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieTsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzOworaW1wb3J0IG9yZy5qcnVieS4qOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlNZXRob2Q7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuKjsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJEZXNjcmlwdG9yUG9vbCIpCitwdWJsaWMgY2xhc3MgUnVieURlc2NyaXB0b3JQb29sIGV4dGVuZHMgUnVieU9iamVjdCB7CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNyZWF0ZVJ1YnlEZXNjcmlwdG9yUG9vbChSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBwcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY0Rlc2NyaXB0b3JQb29sID0gcHJvdG9idWYuZGVmaW5lQ2xhc3NVbmRlcigiRGVzY3JpcHRvclBvb2wiLCBydW50aW1lLmdldE9iamVjdCgpLCBuZXcgT2JqZWN0QWxsb2NhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgSVJ1YnlPYmplY3QgYWxsb2NhdGUoUnVieSBydW50aW1lLCBSdWJ5Q2xhc3Mga2xhenopIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJ1YnlEZXNjcmlwdG9yUG9vbChydW50aW1lLCBrbGF6eik7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIGNEZXNjcmlwdG9yUG9vbC5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlEZXNjcmlwdG9yUG9vbC5jbGFzcyk7CisgICAgICAgIGRlc2NyaXB0b3JQb29sID0gKFJ1YnlEZXNjcmlwdG9yUG9vbCkgY0Rlc2NyaXB0b3JQb29sLm5ld0luc3RhbmNlKHJ1bnRpbWUuZ2V0Q3VycmVudENvbnRleHQoKSwgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgfQorCisgICAgcHVibGljIFJ1YnlEZXNjcmlwdG9yUG9vbChSdWJ5IHJ1YnksIFJ1YnlDbGFzcyBrbGF6eikgeworICAgICAgICBzdXBlcihydWJ5LCBrbGF6eik7CisgICAgfQorCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluaXRpYWxpemUoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIHRoaXMuc3ltdGFiID0gbmV3IEhhc2hNYXA8SVJ1YnlPYmplY3QsIElSdWJ5T2JqZWN0PigpOworICAgICAgICB0aGlzLmNCdWlsZGVyID0gKFJ1YnlDbGFzcykgY29udGV4dC5ydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkJ1aWxkZXIiKTsKKyAgICAgICAgdGhpcy5idWlsZGVyID0gRGVzY3JpcHRvclByb3Rvcy5GaWxlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGJ1aWxkKFRocmVhZENvbnRleHQgY29udGV4dCwgQmxvY2sgYmxvY2spIHsKKyAgICAgICAgUnVieUJ1aWxkZXIgY3R4ID0gKFJ1YnlCdWlsZGVyKSBjQnVpbGRlci5uZXdJbnN0YW5jZShjb250ZXh0LCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgaWYgKGJsb2NrLmFyaXR5KCkgPT0gQXJpdHkuT05FX0FSR1VNRU5UKSB7CisgICAgICAgICAgICBibG9jay55aWVsZChjb250ZXh0LCBjdHgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQmluZGluZyBiaW5kaW5nID0gYmxvY2suZ2V0QmluZGluZygpOworICAgICAgICAgICAgYmluZGluZy5zZXRTZWxmKGN0eCk7CisgICAgICAgICAgICBibG9jay55aWVsZFNwZWNpZmljKGNvbnRleHQpOworICAgICAgICB9CisgICAgICAgIGN0eC5maW5hbGl6ZVRvUG9vbChjb250ZXh0LCB0aGlzKTsKKyAgICAgICAgYnVpbGRGaWxlRGVzY3JpcHRvcihjb250ZXh0KTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgbG9va3VwKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgbmFtZSkgeworICAgICAgICBJUnVieU9iamVjdCBkZXNjcmlwdG9yID0gdGhpcy5zeW10YWIuZ2V0KG5hbWUpOworICAgICAgICBpZiAoZGVzY3JpcHRvciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZXNjcmlwdG9yOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIERlc2NyaXB0b3JQb29sLmdlbmVyYXRlZF9wb29sID0+IGRlc2NyaXB0b3JfcG9vbAorICAgICAqCisgICAgICogQ2xhc3MgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgZ2xvYmFsIERlc2NyaXB0b3JQb29sLiBUaGlzIGlzIGEgc2luZ2xldG9uIGludG8KKyAgICAgKiB3aGljaCBnZW5lcmF0ZWQtY29kZSBtZXNzYWdlIGFuZCBlbnVtIHR5cGVzIGFyZSByZWdpc3RlcmVkLiBUaGUgdXNlciBtYXkgYWxzbworICAgICAqIHJlZ2lzdGVyIHR5cGVzIGluIHRoaXMgcG9vbCBmb3IgY29udmVuaWVuY2Ugc28gdGhhdCB0aGV5IGRvIG5vdCBoYXZlIHRvIGhvbGQKKyAgICAgKiBhIHJlZmVyZW5jZSB0byBhIHByaXZhdGUgcG9vbCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobWV0YSA9IHRydWUsIG5hbWUgPSAiZ2VuZXJhdGVkX3Bvb2wiKQorICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3QgZ2VuZXJhdGVkUG9vbChUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IHJlY3YpIHsKKyAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3JQb29sOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGFkZFRvU3ltdGFiKFRocmVhZENvbnRleHQgY29udGV4dCwgUnVieURlc2NyaXB0b3IgZGVmKSB7CisgICAgICAgIHN5bXRhYi5wdXQoZGVmLmdldE5hbWUoY29udGV4dCksIGRlZik7CisgICAgICAgIHRoaXMuYnVpbGRlci5hZGRNZXNzYWdlVHlwZShkZWYuZ2V0QnVpbGRlcigpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBhZGRUb1N5bXRhYihUaHJlYWRDb250ZXh0IGNvbnRleHQsIFJ1YnlFbnVtRGVzY3JpcHRvciBkZWYpIHsKKyAgICAgICAgc3ltdGFiLnB1dChkZWYuZ2V0TmFtZShjb250ZXh0KSwgZGVmKTsKKyAgICAgICAgdGhpcy5idWlsZGVyLmFkZEVudW1UeXBlKGRlZi5nZXRCdWlsZGVyKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBidWlsZEZpbGVEZXNjcmlwdG9yKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLmJ1aWxkZXIuc2V0U3ludGF4KCJwcm90bzMiKTsKKyAgICAgICAgICAgIGZpbmFsIERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yIGZpbGVEZXNjcmlwdG9yID0gRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuYnVpbGRGcm9tKAorICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkZXIuYnVpbGQoKSwgbmV3IERlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW117fSk7CisKKyAgICAgICAgICAgIGZvciAoRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IgZW51bURlc2NyaXB0b3IgOiBmaWxlRGVzY3JpcHRvci5nZXRFbnVtVHlwZXMoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBlbnVtTmFtZSA9IFV0aWxzLnVuZXNjYXBlSWRlbnRpZmllcihlbnVtRGVzY3JpcHRvci5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGlmIChlbnVtRGVzY3JpcHRvci5maW5kVmFsdWVCeU51bWJlcigwKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFbnVtIGRlZmluaXRpb24gIiArIGVudW1OYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGRvZXMgbm90IGNvbnRhaW4gYSB2YWx1ZSBmb3IgJzAnIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICgoUnVieUVudW1EZXNjcmlwdG9yKSBzeW10YWIuZ2V0KHJ1bnRpbWUubmV3U3RyaW5nKGVudW1OYW1lKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGVzY3JpcHRvcihlbnVtRGVzY3JpcHRvcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZGVzY3JpcHRvciA6IGZpbGVEZXNjcmlwdG9yLmdldE1lc3NhZ2VUeXBlcygpKSB7CisgICAgICAgICAgICAgICAgUnVieURlc2NyaXB0b3IgcnVieURlc2NyaXB0b3IgPSAoKFJ1YnlEZXNjcmlwdG9yKQorICAgICAgICAgICAgICAgICAgICAgICAgc3ltdGFiLmdldChydW50aW1lLm5ld1N0cmluZyhVdGlscy51bmVzY2FwZUlkZW50aWZpZXIoZGVzY3JpcHRvci5nZXROYW1lKCkpKSkpOworICAgICAgICAgICAgICAgIGZvciAoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA6IGRlc2NyaXB0b3IuZ2V0RmllbGRzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkRGVzY3JpcHRvci5pc1JlcXVpcmVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJSZXF1aXJlZCBmaWVsZHMgYXJlIHVuc3VwcG9ydGVkIGluIHByb3RvMyIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IgcnVieUZpZWxkRGVzY3JpcHRvciA9IHJ1YnlEZXNjcmlwdG9yLmxvb2t1cChmaWVsZERlc2NyaXB0b3IuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgcnVieUZpZWxkRGVzY3JpcHRvci5zZXRGaWVsZERlZihmaWVsZERlc2NyaXB0b3IpOworICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGREZXNjcmlwdG9yLmdldFR5cGUoKSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBSdWJ5RGVzY3JpcHRvciBzdWJUeXBlID0gKFJ1YnlEZXNjcmlwdG9yKSBsb29rdXAoY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVudGltZS5uZXdTdHJpbmcoVXRpbHMudW5lc2NhcGVJZGVudGlmaWVyKGZpZWxkRGVzY3JpcHRvci5nZXRNZXNzYWdlVHlwZSgpLmdldE5hbWUoKSkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1YnlGaWVsZERlc2NyaXB0b3Iuc2V0U3ViVHlwZShzdWJUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGREZXNjcmlwdG9yLmdldFR5cGUoKSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5FTlVNKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBSdWJ5RW51bURlc2NyaXB0b3Igc3ViVHlwZSA9IChSdWJ5RW51bURlc2NyaXB0b3IpIGxvb2t1cChjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW50aW1lLm5ld1N0cmluZyhVdGlscy51bmVzY2FwZUlkZW50aWZpZXIoZmllbGREZXNjcmlwdG9yLmdldEVudW1UeXBlKCkuZ2V0TmFtZSgpKSkpOworICAgICAgICAgICAgICAgICAgICAgICAgcnVieUZpZWxkRGVzY3JpcHRvci5zZXRTdWJUeXBlKHN1YlR5cGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJ1YnlEZXNjcmlwdG9yLnNldERlc2NyaXB0b3IoZGVzY3JpcHRvcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKERlc2NyaXB0b3JzLkRlc2NyaXB0b3JWYWxpZGF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3UnVudGltZUVycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFJ1YnlEZXNjcmlwdG9yUG9vbCBkZXNjcmlwdG9yUG9vbDsKKworICAgIHByaXZhdGUgUnVieUNsYXNzIGNCdWlsZGVyOworICAgIHByaXZhdGUgTWFwPElSdWJ5T2JqZWN0LCBJUnVieU9iamVjdD4gc3ltdGFiOworICAgIHByaXZhdGUgRGVzY3JpcHRvclByb3Rvcy5GaWxlRGVzY3JpcHRvclByb3RvLkJ1aWxkZXIgYnVpbGRlcjsKK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlFbnVtLmphdmEgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RW51bS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyOWQ4NjkKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RW51bS5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyAqIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAqIG1ldDoKKyAqCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorICogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorICogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorICogZGlzdHJpYnV0aW9uLgorICogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworICogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1Ynk7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzOworaW1wb3J0IG9yZy5qcnVieS5SdWJ5TW9kdWxlOworaW1wb3J0IG9yZy5qcnVieS5SdWJ5TnVtZXJpYzsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieU1ldGhvZDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5UaHJlYWRDb250ZXh0OworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLmJ1aWx0aW4uSVJ1YnlPYmplY3Q7CisKK3B1YmxpYyBjbGFzcyBSdWJ5RW51bSB7CisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRW51bS5sb29rdXAobnVtYmVyKSA9PiBuYW1lCisgICAgICoKKyAgICAgKiBUaGlzIG1vZHVsZSBtZXRob2QsIHByb3ZpZGVkIG9uIGVhY2ggZ2VuZXJhdGVkIGVudW0gbW9kdWxlLCBsb29rcyB1cCBhbiBlbnVtCisgICAgICogdmFsdWUgYnkgbnVtYmVyIGFuZCByZXR1cm5zIGl0cyBuYW1lIGFzIGEgUnVieSBzeW1ib2wsIG9yIG5pbCBpZiBub3QgZm91bmQuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG1ldGEgPSB0cnVlKQorICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3QgbG9va3VwKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgcmVjdiwgSVJ1YnlPYmplY3QgbnVtYmVyKSB7CisgICAgICAgIFJ1YnlFbnVtRGVzY3JpcHRvciBydWJ5RW51bURlc2NyaXB0b3Jlc2NyaXB0b3IgPSAoUnVieUVudW1EZXNjcmlwdG9yKSBnZXREZXNjcmlwdG9yKGNvbnRleHQsIHJlY3YpOworICAgICAgICBEZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gcnVieUVudW1EZXNjcmlwdG9yZXNjcmlwdG9yLmdldERlc2NyaXB0b3IoKTsKKyAgICAgICAgRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciB2YWx1ZSA9IGRlc2NyaXB0b3IuZmluZFZhbHVlQnlOdW1iZXIoUnVieU51bWVyaWMubnVtMmludChudW1iZXIpKTsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUubmV3U3ltYm9sKHZhbHVlLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRW51bS5yZXNvbHZlKG5hbWUpID0+IG51bWJlcgorICAgICAqCisgICAgICogVGhpcyBtb2R1bGUgbWV0aG9kLCBwcm92aWRlZCBvbiBlYWNoIGdlbmVyYXRlZCBlbnVtIG1vZHVsZSwgbG9va3MgdXAgYW4gZW51bQorICAgICAqIHZhbHVlIGJ5IG5hbWUgKGFzIGEgUnVieSBzeW1ib2wpIGFuZCByZXR1cm5zIGl0cyBuYW1lLCBvciBuaWwgaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChtZXRhID0gdHJ1ZSkKKyAgICBwdWJsaWMgc3RhdGljIElSdWJ5T2JqZWN0IHJlc29sdmUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCByZWN2LCBJUnVieU9iamVjdCBuYW1lKSB7CisgICAgICAgIFJ1YnlFbnVtRGVzY3JpcHRvciBydWJ5RW51bURlc2NyaXB0b3Jlc2NyaXB0b3IgPSAoUnVieUVudW1EZXNjcmlwdG9yKSBnZXREZXNjcmlwdG9yKGNvbnRleHQsIHJlY3YpOworICAgICAgICBEZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gcnVieUVudW1EZXNjcmlwdG9yZXNjcmlwdG9yLmdldERlc2NyaXB0b3IoKTsKKyAgICAgICAgRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciB2YWx1ZSA9IGRlc2NyaXB0b3IuZmluZFZhbHVlQnlOYW1lKG5hbWUuYXNKYXZhU3RyaW5nKCkpOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5uZXdGaXhudW0odmFsdWUuZ2V0TnVtYmVyKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEVudW0uZGVzY3JpcHRvcgorICAgICAqCisgICAgICogVGhpcyBtb2R1bGUgbWV0aG9kLCBwcm92aWRlZCBvbiBlYWNoIGdlbmVyYXRlZCBlbnVtIG1vZHVsZSwgcmV0dXJucyB0aGUKKyAgICAgKiBFbnVtRGVzY3JpcHRvciBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZW51bSB0eXBlLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChtZXRhID0gdHJ1ZSwgbmFtZSA9ICJkZXNjcmlwdG9yIikKKyAgICBwdWJsaWMgc3RhdGljIElSdWJ5T2JqZWN0IGdldERlc2NyaXB0b3IoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCByZWN2KSB7CisgICAgICAgIHJldHVybiAoKFJ1YnlNb2R1bGUpIHJlY3YpLmdldEluc3RhbmNlVmFyaWFibGUoVXRpbHMuREVTQ1JJUFRPUl9JTlNUQU5DRV9WQVIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlFbnVtQnVpbGRlckNvbnRleHQuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlFbnVtQnVpbGRlckNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGNhYzM0Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieUVudW1CdWlsZGVyQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyAqIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAqIG1ldDoKKyAqCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorICogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorICogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorICogZGlzdHJpYnV0aW9uLgorICogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworICogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1Ynk7CisKK2ltcG9ydCBvcmcuanJ1YnkuUnVieTsKK2ltcG9ydCBvcmcuanJ1YnkuUnVieUNsYXNzOworaW1wb3J0IG9yZy5qcnVieS5SdWJ5TW9kdWxlOworaW1wb3J0IG9yZy5qcnVieS5SdWJ5T2JqZWN0OworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlNZXRob2Q7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuT2JqZWN0QWxsb2NhdG9yOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLlRocmVhZENvbnRleHQ7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuYnVpbHRpbi5JUnVieU9iamVjdDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJFbnVtQnVpbGRlckNvbnRleHQiKQorcHVibGljIGNsYXNzIFJ1YnlFbnVtQnVpbGRlckNvbnRleHQgZXh0ZW5kcyBSdWJ5T2JqZWN0IHsKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlUnVieUVudW1CdWlsZGVyQ29udGV4dChSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBwcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY01lc3NhZ2VCdWlsZGVyQ29udGV4dCA9IHByb3RvYnVmLmRlZmluZUNsYXNzVW5kZXIoIkVudW1CdWlsZGVyQ29udGV4dCIsIHJ1bnRpbWUuZ2V0T2JqZWN0KCksIG5ldyBPYmplY3RBbGxvY2F0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJUnVieU9iamVjdCBhbGxvY2F0ZShSdWJ5IHJ1bnRpbWUsIFJ1YnlDbGFzcyBrbGF6eikgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUnVieUVudW1CdWlsZGVyQ29udGV4dChydW50aW1lLCBrbGF6eik7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBjTWVzc2FnZUJ1aWxkZXJDb250ZXh0LmRlZmluZUFubm90YXRlZE1ldGhvZHMoUnVieUVudW1CdWlsZGVyQ29udGV4dC5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIFJ1YnlFbnVtQnVpbGRlckNvbnRleHQoUnVieSBydWJ5LCBSdWJ5Q2xhc3Mga2xhenopIHsKKyAgICAgICAgc3VwZXIocnVieSwga2xhenopOworICAgIH0KKworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBpbml0aWFsaXplKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgZW51bURlc2NyaXB0b3IpIHsKKyAgICAgICAgdGhpcy5lbnVtRGVzY3JpcHRvciA9IChSdWJ5RW51bURlc2NyaXB0b3IpIGVudW1EZXNjcmlwdG9yOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBFbnVtQnVpbGRlci5hZGRfdmFsdWUobmFtZSwgbnVtYmVyKQorICAgICAqCisgICAgICogQWRkcyB0aGUgZ2l2ZW4gbmFtZSA9PiBudW1iZXIgbWFwcGluZyB0byB0aGUgZW51bSB0eXBlLiBOYW1lIG11c3QgYmUgYSBSdWJ5CisgICAgICogc3ltYm9sLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCB2YWx1ZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG5hbWUsIElSdWJ5T2JqZWN0IG51bWJlcikgeworICAgICAgICB0aGlzLmVudW1EZXNjcmlwdG9yLmFkZFZhbHVlKGNvbnRleHQsIG5hbWUsIG51bWJlcik7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBSdWJ5RW51bURlc2NyaXB0b3IgZW51bURlc2NyaXB0b3I7Cit9CmRpZmYgLS1naXQgYS9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RW51bURlc2NyaXB0b3IuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlFbnVtRGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkZjgzMmQKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RW51bURlc2NyaXB0b3IuamF2YQpAQCAtMCwwICsxLDE4NSBAQAorLyoKKyAqIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorICogQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorICogbWV0OgorICoKKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisgKiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisgKiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisgKiBkaXN0cmlidXRpb24uCisgKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisgKiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorICogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorICovCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieTsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzOworaW1wb3J0IG9yZy5qcnVieS5SdWJ5OworaW1wb3J0IG9yZy5qcnVieS5SdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlNb2R1bGU7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlPYmplY3Q7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlOdW1lcmljOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlNZXRob2Q7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuQmxvY2s7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuT2JqZWN0QWxsb2NhdG9yOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLlRocmVhZENvbnRleHQ7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuYnVpbHRpbi5JUnVieU9iamVjdDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJFbnVtRGVzY3JpcHRvciIsIGluY2x1ZGUgPSAiRW51bWVyYWJsZSIpCitwdWJsaWMgY2xhc3MgUnVieUVudW1EZXNjcmlwdG9yIGV4dGVuZHMgUnVieU9iamVjdCB7CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNyZWF0ZVJ1YnlFbnVtRGVzY3JpcHRvcihSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBtUHJvdG9idWYgPSBydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWYiKTsKKyAgICAgICAgUnVieUNsYXNzIGNFbnVtRGVzY3JpcHRvciA9IG1Qcm90b2J1Zi5kZWZpbmVDbGFzc1VuZGVyKCJFbnVtRGVzY3JpcHRvciIsIHJ1bnRpbWUuZ2V0T2JqZWN0KCksIG5ldyBPYmplY3RBbGxvY2F0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJUnVieU9iamVjdCBhbGxvY2F0ZShSdWJ5IHJ1bnRpbWUsIFJ1YnlDbGFzcyBrbGF6eikgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUnVieUVudW1EZXNjcmlwdG9yKHJ1bnRpbWUsIGtsYXp6KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGNFbnVtRGVzY3JpcHRvci5pbmNsdWRlTW9kdWxlKHJ1bnRpbWUuZ2V0RW51bWVyYWJsZSgpKTsKKyAgICAgICAgY0VudW1EZXNjcmlwdG9yLmRlZmluZUFubm90YXRlZE1ldGhvZHMoUnVieUVudW1EZXNjcmlwdG9yLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVieUVudW1EZXNjcmlwdG9yKFJ1YnkgcnVudGltZSwgUnVieUNsYXNzIGtsYXp6KSB7CisgICAgICAgIHN1cGVyKHJ1bnRpbWUsIGtsYXp6KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBFbnVtRGVzY3JpcHRvci5uZXcgPT4gZW51bV9kZXNjcmlwdG9yCisgICAgICoKKyAgICAgKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSwgZW51bSBkZXNjcmlwdG9yLiBNdXN0IGJlIGFkZGVkIHRvIGEgcG9vbCBiZWZvcmUgdGhlCisgICAgICogZW51bSB0eXBlIGNhbiBiZSB1c2VkLiBUaGUgZW51bSB0eXBlIG1heSBvbmx5IGJlIG1vZGlmaWVkIHByaW9yIHRvIGFkZGluZyB0bworICAgICAqIGEgcG9vbC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5pdGlhbGl6ZShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyID0gRGVzY3JpcHRvclByb3Rvcy5FbnVtRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRW51bURlc2NyaXB0b3IubmFtZSA9PiBuYW1lCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgZW51bSB0eXBlLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gIm5hbWUiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBnZXROYW1lKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICByZXR1cm4gdGhpcy5uYW1lOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEVudW1EZXNjcmlwdG9yLm5hbWUgPSBuYW1lCisgICAgICoKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoaXMgZW51bSB0eXBlLiBDYW5ub3QgYmUgY2FsbGVkIGlmIHRoZSBlbnVtIHR5cGUgaGFzCisgICAgICogYWxyZWFkeSBiZWVuIGFkZGVkIHRvIGEgcG9vbC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJuYW1lPSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IHNldE5hbWUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBuYW1lKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMuYnVpbGRlci5zZXROYW1lKFV0aWxzLmVzY2FwZUlkZW50aWZpZXIobmFtZS5hc0phdmFTdHJpbmcoKSkpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEVudW1EZXNjcmlwdG9yLmFkZF92YWx1ZShrZXksIHZhbHVlKQorICAgICAqCisgICAgICogQWRkcyBhIG5ldyBrZXkgPT4gdmFsdWUgbWFwcGluZyB0byB0aGlzIGVudW0gdHlwZS4gS2V5IG11c3QgYmUgZ2l2ZW4gYXMgYQorICAgICAqIFJ1Ynkgc3ltYm9sLiBDYW5ub3QgYmUgY2FsbGVkIGlmIHRoZSBlbnVtIHR5cGUgaGFzIGFscmVhZHkgYmVlbiBhZGRlZCB0byBhCisgICAgICogcG9vbC4gV2lsbCByYWlzZSBhbiBleGNlcHRpb24gaWYgdGhlIGtleSBvciB2YWx1ZSBpcyBhbHJlYWR5IGluIHVzZS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJhZGRfdmFsdWUiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBhZGRWYWx1ZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG5hbWUsIElSdWJ5T2JqZWN0IG51bWJlcikgeworICAgICAgICBEZXNjcmlwdG9yUHJvdG9zLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5CdWlsZGVyIHZhbHVlQnVpbGRlciA9IERlc2NyaXB0b3JQcm90b3MuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5ld0J1aWxkZXIoKTsKKyAgICAgICAgdmFsdWVCdWlsZGVyLnNldE5hbWUobmFtZS5hc0phdmFTdHJpbmcoKSk7CisgICAgICAgIHZhbHVlQnVpbGRlci5zZXROdW1iZXIoUnVieU51bWVyaWMubnVtMmludChudW1iZXIpKTsKKyAgICAgICAgdGhpcy5idWlsZGVyLmFkZFZhbHVlKHZhbHVlQnVpbGRlcik7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRW51bURlc2NyaXB0b3IuZWFjaCgmYmxvY2spCisgICAgICoKKyAgICAgKiBJdGVyYXRlcyBvdmVyIGtleSA9PiB2YWx1ZSBtYXBwaW5ncyBpbiB0aGlzIGVudW0ncyBkZWZpbml0aW9uLCB5aWVsZGluZyB0bworICAgICAqIHRoZSBibG9jayB3aXRoIChrZXksIHZhbHVlKSBhcmd1bWVudHMgZm9yIGVhY2ggb25lLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBlYWNoKFRocmVhZENvbnRleHQgY29udGV4dCwgQmxvY2sgYmxvY2spIHsKKyAgICAgICAgUnVieSBydW50aW1lID0gY29udGV4dC5ydW50aW1lOworICAgICAgICBmb3IgKERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZW51bVZhbHVlRGVzY3JpcHRvciA6IGRlc2NyaXB0b3IuZ2V0VmFsdWVzKCkpIHsKKyAgICAgICAgICAgIGJsb2NrLnlpZWxkKGNvbnRleHQsIHJ1bnRpbWUubmV3QXJyYXkocnVudGltZS5uZXdTeW1ib2woZW51bVZhbHVlRGVzY3JpcHRvci5nZXROYW1lKCkpLAorICAgICAgICAgICAgICAgICAgICBydW50aW1lLm5ld0ZpeG51bShlbnVtVmFsdWVEZXNjcmlwdG9yLmdldE51bWJlcigpKSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEVudW1EZXNjcmlwdG9yLmVudW1tb2R1bGUgPT4gbW9kdWxlCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSBSdWJ5IG1vZHVsZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZW51bSB0eXBlLiBDYW5ub3QgYmUgY2FsbGVkCisgICAgICogdW50aWwgdGhlIGVudW0gZGVzY3JpcHRvciBoYXMgYmVlbiBhZGRlZCB0byBhIHBvb2wuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGVudW1tb2R1bGUoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIGlmICh0aGlzLmtsYXp6ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMua2xhenogPSBidWlsZE1vZHVsZUZyb21EZXNjcmlwdG9yKGNvbnRleHQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzLmtsYXp6OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERlc2NyaXB0b3IoRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICAgICAgICB0aGlzLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yOworICAgIH0KKworICAgIHB1YmxpYyBEZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvciBnZXREZXNjcmlwdG9yKCkgeworICAgICAgICByZXR1cm4gdGhpcy5kZXNjcmlwdG9yOworICAgIH0KKworICAgIHB1YmxpYyBEZXNjcmlwdG9yUHJvdG9zLkVudW1EZXNjcmlwdG9yUHJvdG8uQnVpbGRlciBnZXRCdWlsZGVyKCkgeworICAgICAgICByZXR1cm4gdGhpcy5idWlsZGVyOworICAgIH0KKworICAgIHByaXZhdGUgUnVieU1vZHVsZSBidWlsZE1vZHVsZUZyb21EZXNjcmlwdG9yKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIFV0aWxzLmNoZWNrTmFtZUF2YWlsYWJpbGl0eShjb250ZXh0LCBuYW1lLmFzSmF2YVN0cmluZygpKTsKKworICAgICAgICBSdWJ5TW9kdWxlIGVudW1Nb2R1bGUgPSBSdWJ5TW9kdWxlLm5ld01vZHVsZShydW50aW1lKTsKKyAgICAgICAgZm9yIChEZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIHZhbHVlIDogZGVzY3JpcHRvci5nZXRWYWx1ZXMoKSkgeworICAgICAgICAgICAgZW51bU1vZHVsZS5kZWZpbmVDb25zdGFudCh2YWx1ZS5nZXROYW1lKCksIHJ1bnRpbWUubmV3Rml4bnVtKHZhbHVlLmdldE51bWJlcigpKSk7CisgICAgICAgIH0KKworICAgICAgICBlbnVtTW9kdWxlLmluc3RhbmNlX3ZhcmlhYmxlX3NldChydW50aW1lLm5ld1N0cmluZyhVdGlscy5ERVNDUklQVE9SX0lOU1RBTkNFX1ZBUiksIHRoaXMpOworICAgICAgICBlbnVtTW9kdWxlLmRlZmluZUFubm90YXRlZE1ldGhvZHMoUnVieUVudW0uY2xhc3MpOworICAgICAgICByZXR1cm4gZW51bU1vZHVsZTsKKyAgICB9CisKKyAgICBwcml2YXRlIElSdWJ5T2JqZWN0IG5hbWU7CisgICAgcHJpdmF0ZSBSdWJ5TW9kdWxlIGtsYXp6OworICAgIHByaXZhdGUgRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIERlc2NyaXB0b3JQcm90b3MuRW51bURlc2NyaXB0b3JQcm90by5CdWlsZGVyIGJ1aWxkZXI7Cit9CmRpZmYgLS1naXQgYS9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RmllbGREZXNjcmlwdG9yLmphdmEgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5RmllbGREZXNjcmlwdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzgyMjZjNAotLS0gL2Rldi9udWxsCisrKyBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlGaWVsZERlc2NyaXB0b3IuamF2YQpAQCAtMCwwICsxLDI0OCBAQAorLyoKKyAqIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorICogQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorICogbWV0OgorICoKKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisgKiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisgKiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisgKiBkaXN0cmlidXRpb24uCisgKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisgKiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorICogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorICovCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieTsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzOworaW1wb3J0IG9yZy5qcnVieS4qOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlNZXRob2Q7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuT2JqZWN0QWxsb2NhdG9yOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLlRocmVhZENvbnRleHQ7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuYnVpbHRpbi5JUnVieU9iamVjdDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJGaWVsZERlc2NyaXB0b3IiKQorcHVibGljIGNsYXNzIFJ1YnlGaWVsZERlc2NyaXB0b3IgZXh0ZW5kcyBSdWJ5T2JqZWN0IHsKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlUnVieUZpbGVEZXNjcmlwdG9yKFJ1YnkgcnVudGltZSkgeworICAgICAgICBSdWJ5TW9kdWxlIG1Qcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY0ZpZWxkRGVzY3JpcHRvciA9IG1Qcm90b2J1Zi5kZWZpbmVDbGFzc1VuZGVyKCJGaWVsZERlc2NyaXB0b3IiLCBydW50aW1lLmdldE9iamVjdCgpLCBuZXcgT2JqZWN0QWxsb2NhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgSVJ1YnlPYmplY3QgYWxsb2NhdGUoUnVieSBydW50aW1lLCBSdWJ5Q2xhc3Mga2xhenopIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJ1YnlGaWVsZERlc2NyaXB0b3IocnVudGltZSwga2xhenopOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgY0ZpZWxkRGVzY3JpcHRvci5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlGaWVsZERlc2NyaXB0b3IuY2xhc3MpOworICAgIH0KKworICAgIHB1YmxpYyBSdWJ5RmllbGREZXNjcmlwdG9yKFJ1YnkgcnVudGltZSwgUnVieUNsYXNzIGtsYXp6KSB7CisgICAgICAgIHN1cGVyKHJ1bnRpbWUsIGtsYXp6KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBGaWVsZERlc2NyaXB0b3IubmV3ID0+IGZpZWxkCisgICAgICoKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGZpZWxkIGRlc2NyaXB0b3IuIEl0cyBuYW1lLCB0eXBlLCBldGMuIG11c3QgYmUgc2V0IGJlZm9yZSBpdCBpcworICAgICAqIGFkZGVkIHRvIGEgbWVzc2FnZSB0eXBlLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBpbml0aWFsaXplKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBidWlsZGVyID0gRGVzY3JpcHRvclByb3Rvcy5GaWVsZERlc2NyaXB0b3JQcm90by5uZXdCdWlsZGVyKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEZpZWxkRGVzY3JpcHRvci5sYWJlbCA9IGxhYmVsCisgICAgICoKKyAgICAgKiBTZXRzIHRoZSBsYWJlbCBvbiB0aGlzIGZpZWxkLiBDYW5ub3QgYmUgY2FsbGVkIGlmIGZpZWxkIGlzIHBhcnQgb2YgYSBtZXNzYWdlCisgICAgICogdHlwZSBhbHJlYWR5IGluIGEgcG9vbC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJsYWJlbD0iKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBzZXRMYWJlbChUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHRoaXMuYnVpbGRlci5zZXRMYWJlbCgKKyAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG9zLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsLnZhbHVlT2YoIkxBQkVMXyIgKyB2YWx1ZS5hc0phdmFTdHJpbmcoKS50b1VwcGVyQ2FzZSgpKSk7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRmllbGREZXNjcmlwdG9yLm5hbWUgPT4gbmFtZQorICAgICAqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGZpZWxkLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gIm5hbWUiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBnZXROYW1lKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICByZXR1cm4gdGhpcy5uYW1lOworICAgIH0KKworICAgIEBKUnVieU1ldGhvZChuYW1lID0gInN1YnR5cGUiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBnZXRTdWJUeXBlKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICByZXR1cm4gc3ViVHlwZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBGaWVsZERlc2NyaXB0b3IubmFtZSA9IG5hbWUKKyAgICAgKgorICAgICAqIFNldHMgdGhlIG5hbWUgb2YgdGhpcyBmaWVsZC4gQ2Fubm90IGJlIGNhbGxlZCBvbmNlIHRoZSBjb250YWluaW5nIG1lc3NhZ2UKKyAgICAgKiB0eXBlLCBpZiBhbnksIGlzIGFkZGVkIHRvIGEgcG9vbC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJuYW1lPSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IHNldE5hbWUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCB2YWx1ZSkgeworICAgICAgICBTdHJpbmcgbmFtZVN0ciA9IHZhbHVlLmFzSmF2YVN0cmluZygpOworICAgICAgICB0aGlzLm5hbWUgPSBjb250ZXh0LnJ1bnRpbWUubmV3U3RyaW5nKG5hbWVTdHIpOworICAgICAgICB0aGlzLmJ1aWxkZXIuc2V0TmFtZShVdGlscy5lc2NhcGVJZGVudGlmaWVyKG5hbWVTdHIpKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBGaWVsZERlc2NyaXB0b3IudHlwZSA9PiB0eXBlCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoaXMgZmllbGQncyB0eXBlLCBhcyBhIFJ1Ynkgc3ltYm9sLCBvciBuaWwgaWYgbm90IHlldCBzZXQuCisgICAgICoKKyAgICAgKiBWYWxpZCBmaWVsZCB0eXBlcyBhcmU6CisgICAgICogICAgIDppbnQzMiwgOmludDY0LCA6dWludDMyLCA6dWludDY0LCA6ZmxvYXQsIDpkb3VibGUsIDpib29sLCA6c3RyaW5nLAorICAgICAqICAgICA6Ynl0ZXMsIDptZXNzYWdlLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gInR5cGUiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBnZXRUeXBlKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICByZXR1cm4gVXRpbHMuZmllbGRUeXBlVG9SdWJ5KGNvbnRleHQsIHRoaXMuYnVpbGRlci5nZXRUeXBlKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEZpZWxkRGVzY3JpcHRvci50eXBlID0gdHlwZQorICAgICAqCisgICAgICogU2V0cyB0aGlzIGZpZWxkJ3MgdHlwZS4gQ2Fubm90IGJlIGNhbGxlZCBpZiBmaWVsZCBpcyBwYXJ0IG9mIGEgbWVzc2FnZSB0eXBlCisgICAgICogYWxyZWFkeSBpbiBhIHBvb2wuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAidHlwZT0iKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBzZXRUeXBlKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyLnNldFR5cGUoRGVzY3JpcHRvclByb3Rvcy5GaWVsZERlc2NyaXB0b3JQcm90by5UeXBlLnZhbHVlT2YoIlRZUEVfIiArIHZhbHVlLmFzSmF2YVN0cmluZygpLnRvVXBwZXJDYXNlKCkpKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBGaWVsZERlc2NyaXB0b3IubnVtYmVyID0gbnVtYmVyCisgICAgICoKKyAgICAgKiBTZXRzIHRoZSB0YWcgbnVtYmVyIGZvciB0aGlzIGZpZWxkLiBDYW5ub3QgYmUgY2FsbGVkIGlmIGZpZWxkIGlzIHBhcnQgb2YgYQorICAgICAqIG1lc3NhZ2UgdHlwZSBhbHJlYWR5IGluIGEgcG9vbC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJudW1iZXI9IikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3Qgc2V0TnVtYmVyKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyLnNldE51bWJlcihSdWJ5TnVtZXJpYy5udW0yaW50KHZhbHVlKSk7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgRmllbGREZXNjcmlwdG9yLnN1Ym1zZ19uYW1lID0gc3VibXNnX25hbWUKKyAgICAgKgorICAgICAqIFNldHMgdGhlIG5hbWUgb2YgdGhlIG1lc3NhZ2Ugb3IgZW51bSB0eXBlIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBmaWVsZCwgaWYgaXQKKyAgICAgKiBpcyBhIG1lc3NhZ2Ugb3IgZW51bSBmaWVsZCAocmVzcGVjdGl2ZWx5KS4gVGhpcyB0eXBlIG5hbWUgd2lsbCBiZSByZXNvbHZlZAorICAgICAqIHdpdGhpbiB0aGUgY29udGV4dCBvZiB0aGUgcG9vbCB0byB3aGljaCB0aGUgY29udGFpbmluZyBtZXNzYWdlIHR5cGUgaXMgYWRkZWQuCisgICAgICogQ2Fubm90IGJlIGNhbGxlZCBvbiBmaWVsZCB0aGF0IGFyZSBub3Qgb2YgbWVzc2FnZSBvciBlbnVtIHR5cGUsIG9yIG9uIGZpZWxkcworICAgICAqIHRoYXQgYXJlIHBhcnQgb2YgYSBtZXNzYWdlIHR5cGUgYWxyZWFkeSBhZGRlZCB0byBhIHBvb2wuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAic3VibXNnX25hbWU9IikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3Qgc2V0U3VibXNnTmFtZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG5hbWUpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyLnNldFR5cGVOYW1lKCIuIiArIFV0aWxzLmVzY2FwZUlkZW50aWZpZXIobmFtZS5hc0phdmFTdHJpbmcoKSkpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEZpZWxkRGVzY3JpcHRvci5nZXQobWVzc2FnZSkgPT4gdmFsdWUKKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIHNldCBmb3IgdGhpcyBmaWVsZCBvbiB0aGUgZ2l2ZW4gbWVzc2FnZS4gUmFpc2VzIGFuCisgICAgICogZXhjZXB0aW9uIGlmIG1lc3NhZ2UgaXMgb2YgdGhlIHdyb25nIHR5cGUuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiZ2V0IikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgZ2V0VmFsdWUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBtc2dSYikgeworICAgICAgICBSdWJ5TWVzc2FnZSBtZXNzYWdlID0gKFJ1YnlNZXNzYWdlKSBtc2dSYjsKKyAgICAgICAgaWYgKG1lc3NhZ2UuZ2V0RGVzY3JpcHRvcigpICE9IGZpZWxkRGVmLmdldENvbnRhaW5pbmdUeXBlKCkpIHsKKyAgICAgICAgICAgIHRocm93IGNvbnRleHQucnVudGltZS5uZXdUeXBlRXJyb3IoInNldCBtZXRob2QgY2FsbGVkIG9uIHdyb25nIG1lc3NhZ2UgdHlwZSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtZXNzYWdlLmdldEZpZWxkKGNvbnRleHQsIGZpZWxkRGVmKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBGaWVsZERlc2NyaXB0b3Iuc2V0KG1lc3NhZ2UsIHZhbHVlKQorICAgICAqCisgICAgICogU2V0cyB0aGUgdmFsdWUgY29ycmVzcG9uZGluZyB0byB0aGlzIGZpZWxkIHRvIHRoZSBnaXZlbiB2YWx1ZSBvbiB0aGUgZ2l2ZW4KKyAgICAgKiBtZXNzYWdlLiBSYWlzZXMgYW4gZXhjZXB0aW9uIGlmIG1lc3NhZ2UgaXMgb2YgdGhlIHdyb25nIHR5cGUuIFBlcmZvcm1zIHRoZQorICAgICAqIG9yZGluYXJ5IHR5cGUtY2hlY2tzIGZvciBmaWVsZCBzZXR0aW5nLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gInNldCIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IHNldFZhbHVlKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgbXNnUmIsIElSdWJ5T2JqZWN0IHZhbHVlKSB7CisgICAgICAgIFJ1YnlNZXNzYWdlIG1lc3NhZ2UgPSAoUnVieU1lc3NhZ2UpIG1zZ1JiOworICAgICAgICBpZiAobWVzc2FnZS5nZXREZXNjcmlwdG9yKCkgIT0gZmllbGREZWYuZ2V0Q29udGFpbmluZ1R5cGUoKSkgeworICAgICAgICAgICAgdGhyb3cgY29udGV4dC5ydW50aW1lLm5ld1R5cGVFcnJvcigic2V0IG1ldGhvZCBjYWxsZWQgb24gd3JvbmcgbWVzc2FnZSB0eXBlIik7CisgICAgICAgIH0KKyAgICAgICAgbWVzc2FnZS5zZXRGaWVsZChjb250ZXh0LCBmaWVsZERlZiwgdmFsdWUpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFN1YlR5cGUoSVJ1YnlPYmplY3QgcnVieURlc2NyaXB0b3IpIHsKKyAgICAgICAgdGhpcy5zdWJUeXBlID0gcnVieURlc2NyaXB0b3I7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0RmllbGREZWYoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvcikgeworICAgICAgICB0aGlzLmZpZWxkRGVmID0gZmllbGREZXNjcmlwdG9yOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldE9uZW9mTmFtZShJUnVieU9iamVjdCBuYW1lKSB7CisgICAgICAgIG9uZW9mTmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0T25lb2ZJbmRleChpbnQgaW5kZXgpIHsKKyAgICAgICAgaGFzT25lb2ZJbmRleCA9IHRydWU7CisgICAgICAgIG9uZW9mSW5kZXggPSBpbmRleDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgSVJ1YnlPYmplY3QgZ2V0T25lb2ZOYW1lKCkgeworICAgICAgICByZXR1cm4gb25lb2ZOYW1lOworICAgIH0KKworICAgIHByb3RlY3RlZCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZ2V0RmllbGREZWYoKSB7CisgICAgICAgIHJldHVybiBmaWVsZERlZjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgRGVzY3JpcHRvclByb3Rvcy5GaWVsZERlc2NyaXB0b3JQcm90byBidWlsZCgpIHsKKyAgICAgICAgaWYgKGhhc09uZW9mSW5kZXgpCisgICAgICAgICAgICBidWlsZGVyLnNldE9uZW9mSW5kZXgob25lb2ZJbmRleCk7CisgICAgICAgIHJldHVybiB0aGlzLmJ1aWxkZXIuYnVpbGQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIERlc2NyaXB0b3JQcm90b3MuRmllbGREZXNjcmlwdG9yUHJvdG8uQnVpbGRlciBidWlsZGVyOworICAgIHByaXZhdGUgSVJ1YnlPYmplY3QgbmFtZTsKKyAgICBwcml2YXRlIElSdWJ5T2JqZWN0IHN1YlR5cGU7CisgICAgcHJpdmF0ZSBJUnVieU9iamVjdCBvbmVvZk5hbWU7CisgICAgcHJpdmF0ZSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZWY7CisgICAgcHJpdmF0ZSBpbnQgb25lb2ZJbmRleDsKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzT25lb2ZJbmRleCA9IGZhbHNlOworfQpkaWZmIC0tZ2l0IGEvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieU1hcC5qYXZhIGIvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieU1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyNWRjNmUKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5TWFwLmphdmEKQEAgLTAsMCArMSw0MzQgQEAKKy8qCisgKiBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyAqIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAqIG1ldDoKKyAqCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorICogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorICogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorICogZGlzdHJpYnV0aW9uLgorICogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworICogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1Ynk7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRHluYW1pY01lc3NhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTsKK2ltcG9ydCBvcmcuanJ1YnkuKjsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieUNsYXNzOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5TWV0aG9kOworaW1wb3J0IG9yZy5qcnVieS5pbnRlcm5hbC5ydW50aW1lLm1ldGhvZHMuRHluYW1pY01ldGhvZDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5CbG9jazsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5PYmplY3RBbGxvY2F0b3I7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuVGhyZWFkQ29udGV4dDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworaW1wb3J0IG9yZy5qcnVieS51dGlsLkJ5dGVMaXN0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJNYXAiLCBpbmNsdWRlID0gIkVudW1lcmFibGUiKQorcHVibGljIGNsYXNzIFJ1YnlNYXAgZXh0ZW5kcyBSdWJ5T2JqZWN0IHsKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlUnVieU1hcChSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBwcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY01hcCA9IHByb3RvYnVmLmRlZmluZUNsYXNzVW5kZXIoIk1hcCIsIHJ1bnRpbWUuZ2V0T2JqZWN0KCksIG5ldyBPYmplY3RBbGxvY2F0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJUnVieU9iamVjdCBhbGxvY2F0ZShSdWJ5IHJ1YnksIFJ1YnlDbGFzcyBydWJ5Q2xhc3MpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJ1YnlNYXAocnVieSwgcnVieUNsYXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGNNYXAuaW5jbHVkZU1vZHVsZShydW50aW1lLmdldEVudW1lcmFibGUoKSk7CisgICAgICAgIGNNYXAuZGVmaW5lQW5ub3RhdGVkTWV0aG9kcyhSdWJ5TWFwLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVieU1hcChSdWJ5IHJ1YnksIFJ1YnlDbGFzcyBydWJ5Q2xhc3MpIHsKKyAgICAgICAgc3VwZXIocnVieSwgcnVieUNsYXNzKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNYXAubmV3KGtleV90eXBlLCB2YWx1ZV90eXBlLCB2YWx1ZV90eXBlY2xhc3MgPSBuaWwsIGluaXRfaGFzaG1hcCA9IHt9KQorICAgICAqICAgICA9PiBuZXcgbWFwCisgICAgICoKKyAgICAgKiBBbGxvY2F0ZXMgYSBuZXcgTWFwIGNvbnRhaW5lci4gVGhpcyBjb25zdHJ1Y3RvciBtYXkgYmUgY2FsbGVkIHdpdGggMiwgMywgb3IgNAorICAgICAqIGFyZ3VtZW50cy4gVGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIGFsd2F5cyBwcmVzZW50IGFuZCBhcmUgc3ltYm9scyAodGFraW5nCisgICAgICogb24gdGhlIHNhbWUgdmFsdWVzIGFzIGZpZWxkLXR5cGUgc3ltYm9scyBpbiBtZXNzYWdlIGRlc2NyaXB0b3JzKSB0aGF0CisgICAgICogaW5kaWNhdGUgdGhlIHR5cGUgb2YgdGhlIG1hcCBrZXkgYW5kIHZhbHVlIGZpZWxkcy4KKyAgICAgKgorICAgICAqIFRoZSBzdXBwb3J0ZWQga2V5IHR5cGVzIGFyZTogOmludDMyLCA6aW50NjQsIDp1aW50MzIsIDp1aW50NjQsIDpib29sLAorICAgICAqIDpzdHJpbmcsIDpieXRlcy4KKyAgICAgKgorICAgICAqIFRoZSBzdXBwb3J0ZWQgdmFsdWUgdHlwZXMgYXJlOiA6aW50MzIsIDppbnQ2NCwgOnVpbnQzMiwgOnVpbnQ2NCwgOmJvb2wsCisgICAgICogOnN0cmluZywgOmJ5dGVzLCA6ZW51bSwgOm1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBUaGUgdGhpcmQgYXJndW1lbnQsIHZhbHVlX3R5cGVjbGFzcywgbXVzdCBiZSBwcmVzZW50IGlmIHZhbHVlX3R5cGUgaXMgOmVudW0KKyAgICAgKiBvciA6bWVzc2FnZS4gQXMgaW4gUmVwZWF0ZWRGaWVsZCNuZXcsIHRoaXMgYXJndW1lbnQgbXVzdCBiZSBhIG1lc3NhZ2UgY2xhc3MKKyAgICAgKiAoZm9yIDptZXNzYWdlKSBvciBlbnVtIG1vZHVsZSAoZm9yIDplbnVtKS4KKyAgICAgKgorICAgICAqIFRoZSBsYXN0IGFyZ3VtZW50LCBpZiBwcmVzZW50LCBwcm92aWRlcyBpbml0aWFsIGNvbnRlbnQgZm9yIG1hcC4gTm90ZSB0aGF0CisgICAgICogdGhpcyBtYXkgYmUgYW4gb3JkaW5hcnkgUnVieSBoYXNobWFwIG9yIGFub3RoZXIgTWFwIGluc3RhbmNlIHdpdGggaWRlbnRpY2FsCisgICAgICoga2V5IGFuZCB2YWx1ZSB0eXBlcy4gQWxzbyBub3RlIHRoYXQgdGhpcyBhcmd1bWVudCBtYXkgYmUgcHJlc2VudCB3aGV0aGVyIG9yCisgICAgICogbm90IHZhbHVlX3R5cGVjbGFzcyBpcyBwcmVzZW50IChhbmQgaXQgaXMgdW5hbWJpZ3VvdXNseSBzZXBhcmF0ZSBmcm9tCisgICAgICogdmFsdWVfdHlwZWNsYXNzIGJlY2F1c2UgdmFsdWVfdHlwZWNsYXNzJ3MgcHJlc2VuY2UgaXMgc3RyaWN0bHkgZGV0ZXJtaW5lZCBieQorICAgICAqIHZhbHVlX3R5cGUpLiBUaGUgY29udGVudHMgb2YgdGhpcyBpbml0aWFsIGhhc2htYXAgb3IgTWFwIGluc3RhbmNlIGFyZQorICAgICAqIHNoYWxsb3ctY29waWVkIGludG8gdGhlIG5ldyBNYXA6IHRoZSBvcmlnaW5hbCBtYXAgaXMgdW5tb2RpZmllZCwgYnV0CisgICAgICogcmVmZXJlbmNlcyB0byB1bmRlcmx5aW5nIG9iamVjdHMgd2lsbCBiZSBzaGFyZWQgaWYgdGhlIHZhbHVlIHR5cGUgaXMgYQorICAgICAqIG1lc3NhZ2UgdHlwZS4KKyAgICAgKi8KKworICAgIEBKUnVieU1ldGhvZChyZXF1aXJlZCA9IDIsIG9wdGlvbmFsID0gMikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5pdGlhbGl6ZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0W10gYXJncykgeworICAgICAgICB0aGlzLnRhYmxlID0gbmV3IEhhc2hNYXA8SVJ1YnlPYmplY3QsIElSdWJ5T2JqZWN0PigpOworICAgICAgICB0aGlzLmtleVR5cGUgPSBVdGlscy5ydWJ5VG9GaWVsZFR5cGUoYXJnc1swXSk7CisgICAgICAgIHRoaXMudmFsdWVUeXBlID0gVXRpbHMucnVieVRvRmllbGRUeXBlKGFyZ3NbMV0pOworCisgICAgICAgIHN3aXRjaChrZXlUeXBlKSB7CisgICAgICAgICAgICBjYXNlIElOVDMyOgorICAgICAgICAgICAgY2FzZSBJTlQ2NDoKKyAgICAgICAgICAgIGNhc2UgVUlOVDMyOgorICAgICAgICAgICAgY2FzZSBVSU5UNjQ6CisgICAgICAgICAgICBjYXNlIEJPT0w6CisgICAgICAgICAgICBjYXNlIFNUUklORzoKKyAgICAgICAgICAgIGNhc2UgQllURVM6CisgICAgICAgICAgICAgICAgLy8gVGhlc2UgYXJlIE9LLgorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBjb250ZXh0LnJ1bnRpbWUubmV3QXJndW1lbnRFcnJvcigiSW52YWxpZCBrZXkgdHlwZSBmb3IgbWFwLiIpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGluaXRWYWx1ZUFyZyA9IDI7CisgICAgICAgIGlmIChuZWVkVHlwZWNsYXNzKHRoaXMudmFsdWVUeXBlKSAmJiBhcmdzLmxlbmd0aCA+IDIpIHsKKyAgICAgICAgICAgIHRoaXMudmFsdWVUeXBlQ2xhc3MgPSBhcmdzWzJdOworICAgICAgICAgICAgVXRpbHMudmFsaWRhdGVUeXBlQ2xhc3MoY29udGV4dCwgdGhpcy52YWx1ZVR5cGUsIHRoaXMudmFsdWVUeXBlQ2xhc3MpOworICAgICAgICAgICAgaW5pdFZhbHVlQXJnID0gMzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMudmFsdWVUeXBlQ2xhc3MgPSBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsQ2xhc3MoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRhYmxlIHZhbHVlIHR5cGUgaXMgYWx3YXlzIFVJTlQ2NDogdGhpcyBlbnN1cmVzIGVub3VnaCBzcGFjZSB0byBzdG9yZSB0aGUKKyAgICAgICAgLy8gbmF0aXZlX3Nsb3QgdmFsdWUuCisgICAgICAgIGlmIChhcmdzLmxlbmd0aCA+IGluaXRWYWx1ZUFyZykgeworICAgICAgICAgICAgbWVyZ2VJbnRvU2VsZihjb250ZXh0LCBhcmdzW2luaXRWYWx1ZUFyZ10pOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1hcC5bXT0oa2V5LCB2YWx1ZSkgPT4gdmFsdWUKKyAgICAgKgorICAgICAqIEluc2VydHMgb3Igb3ZlcndyaXRlcyB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGtleSB3aXRoIHRoZSBnaXZlbiBuZXcgdmFsdWUuCisgICAgICogVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUga2V5IHR5cGUgaXMgaW5jb3JyZWN0LiBSZXR1cm5zIHRoZSBuZXcgdmFsdWUgdGhhdAorICAgICAqIHdhcyBqdXN0IGluc2VydGVkLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gIltdPSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluZGV4U2V0KFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3Qga2V5LCBJUnVieU9iamVjdCB2YWx1ZSkgeworICAgICAgICBVdGlscy5jaGVja1R5cGUoY29udGV4dCwga2V5VHlwZSwga2V5LCAoUnVieU1vZHVsZSkgdmFsdWVUeXBlQ2xhc3MpOworICAgICAgICBVdGlscy5jaGVja1R5cGUoY29udGV4dCwgdmFsdWVUeXBlLCB2YWx1ZSwgKFJ1YnlNb2R1bGUpIHZhbHVlVHlwZUNsYXNzKTsKKyAgICAgICAgSVJ1YnlPYmplY3Qgc3ltYm9sOworICAgICAgICBpZiAodmFsdWVUeXBlID09IERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlLkVOVU0gJiYKKyAgICAgICAgICAgICAgICBVdGlscy5pc1J1YnlOdW0odmFsdWUpICYmCisgICAgICAgICAgICAgICAgISAoc3ltYm9sID0gUnVieUVudW0ubG9va3VwKGNvbnRleHQsIHZhbHVlVHlwZUNsYXNzLCB2YWx1ZSkpLmlzTmlsKCkpIHsKKyAgICAgICAgICAgIHZhbHVlID0gc3ltYm9sOworICAgICAgICB9CisgICAgICAgIHRoaXMudGFibGUucHV0KGtleSwgdmFsdWUpOworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWFwLltdKGtleSkgPT4gdmFsdWUKKyAgICAgKgorICAgICAqIEFjY2Vzc2VzIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBrZXkuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIGtleSB0eXBlIGlzCisgICAgICogaW5jb3JyZWN0LiBSZXR1cm5zIG5pbCB3aGVuIHRoZSBrZXkgaXMgbm90IHByZXNlbnQgaW4gdGhlIG1hcC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJbXSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluZGV4KFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3Qga2V5KSB7CisgICAgICAgIGlmICh0YWJsZS5jb250YWluc0tleShrZXkpKQorICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFibGUuZ2V0KGtleSk7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWFwLj09KG90aGVyKSA9PiBib29sZWFuCisgICAgICoKKyAgICAgKiBDb21wYXJlcyB0aGlzIG1hcCB0byBhbm90aGVyLiBNYXBzIGFyZSBlcXVhbCBpZiB0aGV5IGhhdmUgaWRlbnRpY2FsIGtleSBzZXRzLAorICAgICAqIGFuZCBmb3IgZWFjaCBrZXksIHRoZSB2YWx1ZXMgaW4gYm90aCBtYXBzIGNvbXBhcmUgZXF1YWwuIEVsZW1lbnRzIGFyZQorICAgICAqIGNvbXBhcmVkIGFzIHBlciBub3JtYWwgUnVieSBzZW1hbnRpY3MsIGJ5IGNhbGxpbmcgdGhlaXIgOj09IG1ldGhvZHMgKG9yCisgICAgICogcGVyZm9ybWluZyBhIG1vcmUgZWZmaWNpZW50IGNvbXBhcmlzb24gZm9yIHByaW1pdGl2ZSB0eXBlcykuCisgICAgICoKKyAgICAgKiBNYXBzIHdpdGggZGlzc2ltaWxhciBrZXkgdHlwZXMgb3IgdmFsdWUgdHlwZXMvdHlwZWNsYXNzZXMgYXJlIG5ldmVyIGVxdWFsLAorICAgICAqIGV2ZW4gaWYgdmFsdWUgY29tcGFyaXNvbiAoZm9yIGV4YW1wbGUsIGJldHdlZW4gaW50ZWdlcnMgYW5kIGZsb2F0cykgd291bGQKKyAgICAgKiBoYXZlIG90aGVyd2lzZSBpbmRpY2F0ZWQgdGhhdCBldmVyeSBlbGVtZW50IGhhcyBlcXVhbCB2YWx1ZS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICI9PSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGVxKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgX290aGVyKSB7CisgICAgICAgIGlmIChfb3RoZXIgaW5zdGFuY2VvZiBSdWJ5SGFzaCkKKyAgICAgICAgICAgIHJldHVybiB0b0hhc2goY29udGV4dCkub3BfZXF1YWwoY29udGV4dCwgX290aGVyKTsKKyAgICAgICAgUnVieU1hcCBvdGhlciA9IChSdWJ5TWFwKSBfb3RoZXI7CisgICAgICAgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldFRydWUoKTsKKyAgICAgICAgaWYgKCF0eXBlQ29tcGF0aWJsZShvdGhlcikgfHwgdGhpcy50YWJsZS5zaXplKCkgIT0gb3RoZXIudGFibGUuc2l6ZSgpKQorICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXRGYWxzZSgpOworICAgICAgICBmb3IgKElSdWJ5T2JqZWN0IGtleSA6IHRhYmxlLmtleVNldCgpKSB7CisgICAgICAgICAgICBpZiAoISBvdGhlci50YWJsZS5jb250YWluc0tleShrZXkpKQorICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0RmFsc2UoKTsKKyAgICAgICAgICAgIGlmICghIG90aGVyLnRhYmxlLmdldChrZXkpLmVxdWFscyh0YWJsZS5nZXQoa2V5KSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXRGYWxzZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0VHJ1ZSgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1hcC5pbnNwZWN0ID0+IHN0cmluZworICAgICAqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhpcyBtYXAncyBlbGVtZW50cy4gSXQgd2lsbCBiZSBmb3JtYXR0ZWQgYXMKKyAgICAgKiAie2tleSA9PiB2YWx1ZSwga2V5ID0+IHZhbHVlLCAuLi59Iiwgd2l0aCBlYWNoIGtleSBhbmQgdmFsdWUgc3RyaW5nCisgICAgICogcmVwcmVzZW50YXRpb24gY29tcHV0ZWQgYnkgaXRzIG93biAjaW5zcGVjdCBtZXRob2QuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluc3BlY3QoKSB7CisgICAgICAgIHJldHVybiB0b0hhc2goZ2V0UnVudGltZSgpLmdldEN1cnJlbnRDb250ZXh0KCkpLmluc3BlY3QoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNYXAuaGFzaCA9PiBoYXNoX3ZhbHVlCisgICAgICoKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCB2YWx1ZSBiYXNlZCBvbiB0aGlzIG1hcCdzIGNvbnRlbnRzLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBoYXNoKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEtMjU2Iik7CisgICAgICAgICAgICBmb3IgKElSdWJ5T2JqZWN0IGtleSA6IHRhYmxlLmtleVNldCgpKSB7CisgICAgICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZSgoYnl0ZSkga2V5Lmhhc2hDb2RlKCkpOworICAgICAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoKGJ5dGUpIHRhYmxlLmdldChrZXkpLmhhc2hDb2RlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5uZXdTdHJpbmcobmV3IEJ5dGVMaXN0KGRpZ2VzdC5kaWdlc3QoKSkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLm5ld0ZpeG51bShTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh0YWJsZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWFwLmtleXMgPT4gW2xpc3Rfb2Zfa2V5c10KKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2Yga2V5cyBjb250YWluZWQgaW4gdGhlIG1hcCwgaW4gdW5zcGVjaWZpZWQgb3JkZXIuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGtleXMoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBSdWJ5QXJyYXkubmV3QXJyYXkoY29udGV4dC5ydW50aW1lLCB0YWJsZS5rZXlTZXQoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWFwLnZhbHVlcyA9PiBbbGlzdF9vZl92YWx1ZXNdCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHZhbHVlcyBjb250YWluZWQgaW4gdGhlIG1hcCwgaW4gdW5zcGVjaWZpZWQgb3JkZXIuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IHZhbHVlcyhUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIFJ1YnlBcnJheS5uZXdBcnJheShjb250ZXh0LnJ1bnRpbWUsIHRhYmxlLnZhbHVlcygpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNYXAuY2xlYXIKKyAgICAgKgorICAgICAqIFJlbW92ZXMgYWxsIGVudHJpZXMgZnJvbSB0aGUgbWFwLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBjbGVhcihUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgdGFibGUuY2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNYXAuZWFjaCgmYmxvY2spCisgICAgICoKKyAgICAgKiBJbnZva2VzICZibG9jayBvbiBlYWNoIHxrZXksIHZhbHVlfCBwYWlyIGluIHRoZSBtYXAsIGluIHVuc3BlY2lmaWVkIG9yZGVyLgorICAgICAqIE5vdGUgdGhhdCBNYXAgYWxzbyBpbmNsdWRlcyBFbnVtZXJhYmxlOyBtYXAgdGh1cyBhY3RzIGxpa2UgYSBub3JtYWwgUnVieQorICAgICAqIHNlcXVlbmNlLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBlYWNoKFRocmVhZENvbnRleHQgY29udGV4dCwgQmxvY2sgYmxvY2spIHsKKyAgICAgICAgZm9yIChJUnVieU9iamVjdCBrZXkgOiB0YWJsZS5rZXlTZXQoKSkgeworICAgICAgICAgICAgYmxvY2sueWllbGRTcGVjaWZpYyhjb250ZXh0LCBrZXksIHRhYmxlLmdldChrZXkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1hcC5kZWxldGUoa2V5KSA9PiBvbGRfdmFsdWUKKyAgICAgKgorICAgICAqIERlbGV0ZXMgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiBrZXksIGlmIGFueSwgcmV0dXJuaW5nIGVpdGhlciB0aGUgb2xkIHZhbHVlIG9yCisgICAgICogbmlsIGlmIG5vbmUgd2FzIHByZXNlbnQuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIGtleSBpcyBvZiB0aGUgd3JvbmcgdHlwZS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgZGVsZXRlKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3Qga2V5KSB7CisgICAgICAgIHJldHVybiB0YWJsZS5yZW1vdmUoa2V5KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNYXAuaGFzX2tleT8oa2V5KSA9PiBib29sCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGtleSBpcyBwcmVzZW50IGluIHRoZSBtYXAuIFRocm93cyBhbiBleGNlcHRpb24gaWYKKyAgICAgKiB0aGUga2V5IGhhcyB0aGUgd3JvbmcgdHlwZS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJoYXNfa2V5PyIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGhhc0tleShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IGtleSkgeworICAgICAgICByZXR1cm4gdGhpcy50YWJsZS5jb250YWluc0tleShrZXkpID8gY29udGV4dC5ydW50aW1lLmdldFRydWUoKSA6IGNvbnRleHQucnVudGltZS5nZXRGYWxzZSgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1hcC5sZW5ndGgKKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbnRyaWVzIChrZXktdmFsdWUgcGFpcnMpIGluIHRoZSBtYXAuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGxlbmd0aChUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5uZXdGaXhudW0odGhpcy50YWJsZS5zaXplKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1hcC5kdXAgPT4gbmV3X21hcAorICAgICAqCisgICAgICogRHVwbGljYXRlcyB0aGlzIG1hcCB3aXRoIGEgc2hhbGxvdyBjb3B5LiBSZWZlcmVuY2VzIHRvIGFsbCBub24tcHJpbWl0aXZlCisgICAgICogZWxlbWVudCBvYmplY3RzIChlLmcuLCBzdWJtZXNzYWdlcykgYXJlIHNoYXJlZC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgZHVwKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBSdWJ5TWFwIG5ld01hcCA9IG5ld1RoaXNUeXBlKGNvbnRleHQpOworICAgICAgICBmb3IgKE1hcC5FbnRyeTxJUnVieU9iamVjdCwgSVJ1YnlPYmplY3Q+IGVudHJ5IDogdGFibGUuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgbmV3TWFwLnRhYmxlLnB1dChlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ld01hcDsKKyAgICB9CisKKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJ0b19oIikKKyAgICBwdWJsaWMgUnVieUhhc2ggdG9IYXNoKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICByZXR1cm4gUnVieUhhc2gubmV3SGFzaChjb250ZXh0LnJ1bnRpbWUsIHRhYmxlLCBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCkpOworICAgIH0KKworICAgIC8vIFVzZWQgYnkgR29vZ2xlOjpQcm90b2J1Zi5kZWVwX2NvcHkgYnV0IG5vdCBleHBvc2VkIGRpcmVjdGx5LgorICAgIHByb3RlY3RlZCBJUnVieU9iamVjdCBkZWVwQ29weShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgUnVieU1hcCBuZXdNYXAgPSBuZXdUaGlzVHlwZShjb250ZXh0KTsKKyAgICAgICAgc3dpdGNoICh2YWx1ZVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgTUVTU0FHRToKKyAgICAgICAgICAgICAgICBmb3IgKElSdWJ5T2JqZWN0IGtleSA6IHRhYmxlLmtleVNldCgpKSB7CisgICAgICAgICAgICAgICAgICAgIFJ1YnlNZXNzYWdlIG1lc3NhZ2UgPSAoUnVieU1lc3NhZ2UpIHRhYmxlLmdldChrZXkpOworICAgICAgICAgICAgICAgICAgICBuZXdNYXAudGFibGUucHV0KGtleS5kdXAoKSwgbWVzc2FnZS5kZWVwQ29weShjb250ZXh0KSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBmb3IgKElSdWJ5T2JqZWN0IGtleSA6IHRhYmxlLmtleVNldCgpKSB7CisgICAgICAgICAgICAgICAgICAgIG5ld01hcC50YWJsZS5wdXQoa2V5LmR1cCgpLCB0YWJsZS5nZXQoa2V5KS5kdXAoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXdNYXA7CisgICAgfQorCisgICAgcHJvdGVjdGVkIExpc3Q8RHluYW1pY01lc3NhZ2U+IGJ1aWxkKFRocmVhZENvbnRleHQgY29udGV4dCwgUnVieURlc2NyaXB0b3IgZGVzY3JpcHRvcikgeworICAgICAgICBMaXN0PER5bmFtaWNNZXNzYWdlPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxEeW5hbWljTWVzc2FnZT4oKTsKKyAgICAgICAgUnVieUNsYXNzIHJ1YnlDbGFzcyA9IChSdWJ5Q2xhc3MpIGRlc2NyaXB0b3IubXNnY2xhc3MoY29udGV4dCk7CisgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBrZXlGaWVsZCA9IGRlc2NyaXB0b3IubG9va3VwKCJrZXkiKS5nZXRGaWVsZERlZigpOworICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgdmFsdWVGaWVsZCA9IGRlc2NyaXB0b3IubG9va3VwKCJ2YWx1ZSIpLmdldEZpZWxkRGVmKCk7CisgICAgICAgIGZvciAoSVJ1YnlPYmplY3Qga2V5IDogdGFibGUua2V5U2V0KCkpIHsKKyAgICAgICAgICAgIFJ1YnlNZXNzYWdlIG1hcE1lc3NhZ2UgPSAoUnVieU1lc3NhZ2UpIHJ1YnlDbGFzcy5uZXdJbnN0YW5jZShjb250ZXh0LCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgICAgIG1hcE1lc3NhZ2Uuc2V0RmllbGQoY29udGV4dCwga2V5RmllbGQsIGtleSk7CisgICAgICAgICAgICBtYXBNZXNzYWdlLnNldEZpZWxkKGNvbnRleHQsIHZhbHVlRmllbGQsIHRhYmxlLmdldChrZXkpKTsKKyAgICAgICAgICAgIGxpc3QuYWRkKG1hcE1lc3NhZ2UuYnVpbGQoY29udGV4dCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIHByb3RlY3RlZCBSdWJ5TWFwIG1lcmdlSW50b1NlbGYoZmluYWwgVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBoYXNobWFwKSB7CisgICAgICAgIGlmIChoYXNobWFwIGluc3RhbmNlb2YgUnVieUhhc2gpIHsKKyAgICAgICAgICAgICgoUnVieUhhc2gpIGhhc2htYXApLnZpc2l0QWxsKG5ldyBSdWJ5SGFzaC5WaXNpdG9yKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0KElSdWJ5T2JqZWN0IGtleSwgSVJ1YnlPYmplY3QgdmFsKSB7CisgICAgICAgICAgICAgICAgICAgIGluZGV4U2V0KGNvbnRleHQsIGtleSwgdmFsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgfSBlbHNlIGlmIChoYXNobWFwIGluc3RhbmNlb2YgUnVieU1hcCkgeworICAgICAgICAgICAgUnVieU1hcCBvdGhlciA9IChSdWJ5TWFwKSBoYXNobWFwOworICAgICAgICAgICAgaWYgKCF0eXBlQ29tcGF0aWJsZShvdGhlcikpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBjb250ZXh0LnJ1bnRpbWUubmV3VHlwZUVycm9yKCJBdHRlbXB0IHRvIG1lcmdlIE1hcCB3aXRoIG1pc21hdGNoaW5nIHR5cGVzIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBjb250ZXh0LnJ1bnRpbWUubmV3VHlwZUVycm9yKCJVbmtub3duIHR5cGUgbWVyZ2luZyBpbnRvIE1hcCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHByb3RlY3RlZCBib29sZWFuIHR5cGVDb21wYXRpYmxlKFJ1YnlNYXAgb3RoZXIpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMua2V5VHlwZSA9PSBvdGhlci5rZXlUeXBlICYmCisgICAgICAgICAgICAgICAgdGhpcy52YWx1ZVR5cGUgPT0gb3RoZXIudmFsdWVUeXBlICYmCisgICAgICAgICAgICAgICAgdGhpcy52YWx1ZVR5cGVDbGFzcyA9PSBvdGhlci52YWx1ZVR5cGVDbGFzczsKKyAgICB9CisKKyAgICBwcml2YXRlIFJ1YnlNYXAgbmV3VGhpc1R5cGUoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIFJ1YnlNYXAgbmV3TWFwOworICAgICAgICBpZiAobmVlZFR5cGVjbGFzcyh2YWx1ZVR5cGUpKSB7CisgICAgICAgICAgICBuZXdNYXAgPSAoUnVieU1hcCkgbWV0YUNsYXNzLm5ld0luc3RhbmNlKGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgIFV0aWxzLmZpZWxkVHlwZVRvUnVieShjb250ZXh0LCBrZXlUeXBlKSwKKyAgICAgICAgICAgICAgICAgICAgVXRpbHMuZmllbGRUeXBlVG9SdWJ5KGNvbnRleHQsIHZhbHVlVHlwZSksCisgICAgICAgICAgICAgICAgICAgIHZhbHVlVHlwZUNsYXNzLCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG5ld01hcCA9IChSdWJ5TWFwKSBtZXRhQ2xhc3MubmV3SW5zdGFuY2UoY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgVXRpbHMuZmllbGRUeXBlVG9SdWJ5KGNvbnRleHQsIGtleVR5cGUpLAorICAgICAgICAgICAgICAgICAgICBVdGlscy5maWVsZFR5cGVUb1J1YnkoY29udGV4dCwgdmFsdWVUeXBlKSwKKyAgICAgICAgICAgICAgICAgICAgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgIH0KKyAgICAgICAgbmV3TWFwLnRhYmxlID0gbmV3IEhhc2hNYXA8SVJ1YnlPYmplY3QsIElSdWJ5T2JqZWN0PigpOworICAgICAgICByZXR1cm4gbmV3TWFwOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBuZWVkVHlwZWNsYXNzKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIHR5cGUpIHsKKyAgICAgICAgc3dpdGNoKHR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgTUVTU0FHRToKKyAgICAgICAgICAgIGNhc2UgRU5VTToKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZSBrZXlUeXBlOworICAgIHByaXZhdGUgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUgdmFsdWVUeXBlOworICAgIHByaXZhdGUgSVJ1YnlPYmplY3QgdmFsdWVUeXBlQ2xhc3M7CisgICAgcHJpdmF0ZSBNYXA8SVJ1YnlPYmplY3QsIElSdWJ5T2JqZWN0PiB0YWJsZTsKK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlNZXNzYWdlLmphdmEgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5TWVzc2FnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0YmMwYjcKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5TWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsNzQ0IEBACisvKgorICogUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisgKiBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisgKiBtZXQ6CisgKgorICogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyAqIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyAqIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyAqIGRpc3RyaWJ1dGlvbi4KKyAqICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyAqIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisgKiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyAqICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyAqIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisgKiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisgKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5OworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi4qOworaW1wb3J0IG9yZy5qcnVieS4qOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5TWV0aG9kOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLkJsb2NrOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLkhlbHBlcnM7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuVGhyZWFkQ29udGV4dDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworaW1wb3J0IG9yZy5qcnVieS51dGlsLkJ5dGVMaXN0OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworcHVibGljIGNsYXNzIFJ1YnlNZXNzYWdlIGV4dGVuZHMgUnVieU9iamVjdCB7CisgICAgcHVibGljIFJ1YnlNZXNzYWdlKFJ1YnkgcnVieSwgUnVieUNsYXNzIGtsYXp6LCBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGRlc2NyaXB0b3IpIHsKKyAgICAgICAgc3VwZXIocnVieSwga2xhenopOworICAgICAgICB0aGlzLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2UubmV3KGt3YXJncykgPT4gbmV3X21lc3NhZ2UKKyAgICAgKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG1lc3NhZ2UgY2xhc3MuIEtleXdvcmQgYXJndW1lbnRzIG1heSBiZQorICAgICAqIHByb3ZpZGVkIHdpdGgga2V5d29yZHMgY29ycmVzcG9uZGluZyB0byBmaWVsZCBuYW1lcy4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBubyBsaXRlcmFsIE1lc3NhZ2UgY2xhc3MgZXhpc3RzLiBPbmx5IGNvbmNyZXRlIGNsYXNzZXMgcGVyIG1lc3NhZ2UKKyAgICAgKiB0eXBlIGV4aXN0LCBhcyBwcm92aWRlZCBieSB0aGUgI21zZ2NsYXNzIG1ldGhvZCBvbiBEZXNjcmlwdG9ycyBhZnRlciB0aGV5CisgICAgICogaGF2ZSBiZWVuIGFkZGVkIHRvIGEgcG9vbC4gVGhlIG1ldGhvZCBkZWZpbml0aW9ucyBkZXNjcmliZWQgaGVyZSBvbiB0aGUKKyAgICAgKiBNZXNzYWdlIGNsYXNzIGFyZSBwcm92aWRlZCBvbiBlYWNoIGNvbmNyZXRlIG1lc3NhZ2UgY2xhc3MuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG9wdGlvbmFsID0gMSkKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5pdGlhbGl6ZShmaW5hbCBUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0W10gYXJncykgeworICAgICAgICBmaW5hbCBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIHRoaXMuY1JlcGVhdGVkRmllbGQgPSAoUnVieUNsYXNzKSBydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OlJlcGVhdGVkRmllbGQiKTsKKyAgICAgICAgdGhpcy5jTWFwID0gKFJ1YnlDbGFzcykgcnVudGltZS5nZXRDbGFzc0Zyb21QYXRoKCJHb29nbGU6OlByb3RvYnVmOjpNYXAiKTsKKyAgICAgICAgdGhpcy5idWlsZGVyID0gRHluYW1pY01lc3NhZ2UubmV3QnVpbGRlcih0aGlzLmRlc2NyaXB0b3IpOworICAgICAgICB0aGlzLnJlcGVhdGVkRmllbGRzID0gbmV3IEhhc2hNYXA8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBSdWJ5UmVwZWF0ZWRGaWVsZD4oKTsKKyAgICAgICAgdGhpcy5tYXBzID0gbmV3IEhhc2hNYXA8RGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLCBSdWJ5TWFwPigpOworICAgICAgICB0aGlzLmZpZWxkcyA9IG5ldyBIYXNoTWFwPERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciwgSVJ1YnlPYmplY3Q+KCk7CisgICAgICAgIHRoaXMub25lb2ZDYXNlcyA9IG5ldyBIYXNoTWFwPERlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yPigpOworICAgICAgICBpZiAoYXJncy5sZW5ndGggPT0gMSkgeworICAgICAgICAgICAgaWYgKCEoYXJnc1swXSBpbnN0YW5jZW9mIFJ1YnlIYXNoKSkgeworICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3QXJndW1lbnRFcnJvcigiZXhwZWN0ZWQgSGFzaCBhcmd1bWVudHMuIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBSdWJ5SGFzaCBoYXNoID0gYXJnc1swXS5jb252ZXJ0VG9IYXNoKCk7CisgICAgICAgICAgICBoYXNoLnZpc2l0QWxsKG5ldyBSdWJ5SGFzaC5WaXNpdG9yKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0KElSdWJ5T2JqZWN0IGtleSwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCEoa2V5IGluc3RhbmNlb2YgUnVieVN5bWJvbCkpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiRXhwZWN0ZWQgc3ltYm9scyBhcyBoYXNoIGtleXMgaW4gaW5pdGlhbGl6YXRpb24gbWFwLiIpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yID0gZmluZEZpZWxkKGNvbnRleHQsIGtleSk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKFV0aWxzLmlzTWFwRW50cnkoZmllbGREZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBSdWJ5SGFzaCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgcnVudGltZS5uZXdBcmd1bWVudEVycm9yKCJFeHBlY3RlZCBIYXNoIG9iamVjdCBhcyBpbml0aWFsaXplciB2YWx1ZSBmb3IgbWFwIGZpZWxkLiIpOworCisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBSdWJ5TWFwIG1hcCA9IG5ld01hcEZvckZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICAgICAgICAgICAgICBtYXAubWVyZ2VJbnRvU2VsZihjb250ZXh0LCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBtYXBzLnB1dChmaWVsZERlc2NyaXB0b3IsIG1hcCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmllbGREZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBSdWJ5QXJyYXkpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFeHBlY3RlZCBhcnJheSBhcyBpbml0aWFsaXplciB2YXIgZm9yIHJlcGVhdGVkIGZpZWxkLiIpOworICAgICAgICAgICAgICAgICAgICAgICAgUnVieVJlcGVhdGVkRmllbGQgcmVwZWF0ZWRGaWVsZCA9IHJ1YnlUb1JlcGVhdGVkRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZXBlYXRlZEZpZWxkKGZpZWxkRGVzY3JpcHRvciwgcmVwZWF0ZWRGaWVsZCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YgPSBmaWVsZERlc2NyaXB0b3IuZ2V0Q29udGFpbmluZ09uZW9mKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAob25lb2YgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZW9mQ2FzZXMucHV0KG9uZW9mLCBmaWVsZERlc2NyaXB0b3IpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRzLnB1dChmaWVsZERlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWVzc2FnZS5bXT0oaW5kZXgsIHZhbHVlKQorICAgICAqCisgICAgICogU2V0cyBhIGZpZWxkJ3MgdmFsdWUgYnkgZmllbGQgbmFtZS4gVGhlIHByb3ZpZGVkIGZpZWxkIG5hbWUgc2hvdWxkIGJlIGEKKyAgICAgKiBzdHJpbmcuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiW109IikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5kZXhTZXQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBmaWVsZE5hbWUsIElSdWJ5T2JqZWN0IHZhbHVlKSB7CisgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IgPSBmaW5kRmllbGQoY29udGV4dCwgZmllbGROYW1lKTsKKyAgICAgICAgcmV0dXJuIHNldEZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvciwgdmFsdWUpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2UuW10oaW5kZXgpID0+IHZhbHVlCisgICAgICoKKyAgICAgKiBBY2Nlc3NlcyBhIGZpZWxkJ3MgdmFsdWUgYnkgZmllbGQgbmFtZS4gVGhlIHByb3ZpZGVkIGZpZWxkIG5hbWUgc2hvdWxkIGJlIGEKKyAgICAgKiBzdHJpbmcuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiW10iKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBpbmRleChUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IGZpZWxkTmFtZSkgeworICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yID0gZmluZEZpZWxkKGNvbnRleHQsIGZpZWxkTmFtZSk7CisgICAgICAgIHJldHVybiBnZXRGaWVsZChjb250ZXh0LCBmaWVsZERlc2NyaXB0b3IpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2UuaW5zcGVjdCA9PiBzdHJpbmcKKyAgICAgKgorICAgICAqIFJldHVybnMgYSBodW1hbi1yZWFkYWJsZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoaXMgbWVzc2FnZS4gSXQgd2lsbCBiZQorICAgICAqIGZvcm1hdHRlZCBhcyAiPE1lc3NhZ2VUeXBlOiBmaWVsZDE6IHZhbHVlMSwgZmllbGQyOiB2YWx1ZTIsIC4uLj4iLiBFYWNoCisgICAgICogZmllbGQncyB2YWx1ZSBpcyByZXByZXNlbnRlZCBhY2NvcmRpbmcgdG8gaXRzIG93biAjaW5zcGVjdCBtZXRob2QuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluc3BlY3QoKSB7CisgICAgICAgIFN0cmluZyBjbmFtZSA9IG1ldGFDbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiPCIpOworICAgICAgICBzYi5hcHBlbmQoY25hbWUpOworICAgICAgICBzYi5hcHBlbmQoIjogIik7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmxheW91dEluc3BlY3QoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiPiIpOworCisgICAgICAgIHJldHVybiBnZXRSdW50aW1lKCkubmV3U3RyaW5nKHNiLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2UuaGFzaCA9PiBoYXNoX3ZhbHVlCisgICAgICoKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgdGhpcyBtZXNzYWdlJ3MgZmllbGQgdmFsdWVzLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBoYXNoKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBpbnQgaGFzaENvZGUgPSBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh0aGlzKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5uZXdGaXhudW0oaGFzaENvZGUpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2UuPT0ob3RoZXIpID0+IGJvb2xlYW4KKyAgICAgKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIG9mIHRoaXMgbWVzc2FnZSB3aXRoIGFub3RoZXIuIE1lc3NhZ2VzIGFyZSBlcXVhbAorICAgICAqIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSB0eXBlIGFuZCBpZiBlYWNoIGZpZWxkIGlzIGVxdWFsIGFjY29yZGluZyB0byB0aGUgOj09CisgICAgICogbWV0aG9kJ3Mgc2VtYW50aWNzIChhIG1vcmUgZWZmaWNpZW50IGNvbXBhcmlzb24gbWF5IGFjdHVhbGx5IGJlIGRvbmUgaWYgdGhlCisgICAgICogZmllbGQgaXMgb2YgYSBwcmltaXRpdmUgdHlwZSkuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiPT0iKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBlcShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG90aGVyKSB7CisgICAgICAgIFJ1YnkgcnVudGltZSA9IGNvbnRleHQucnVudGltZTsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBSdWJ5TWVzc2FnZSkpCisgICAgICAgICAgICByZXR1cm4gcnVudGltZS5nZXRGYWxzZSgpOworICAgICAgICBSdWJ5TWVzc2FnZSBtZXNzYWdlID0gKFJ1YnlNZXNzYWdlKSBvdGhlcjsKKyAgICAgICAgaWYgKGRlc2NyaXB0b3IgIT0gbWVzc2FnZS5kZXNjcmlwdG9yKSB7CisgICAgICAgICAgICByZXR1cm4gcnVudGltZS5nZXRGYWxzZSgpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmRlZiA6IGRlc2NyaXB0b3IuZ2V0RmllbGRzKCkpIHsKKyAgICAgICAgICAgIElSdWJ5T2JqZWN0IHRoaXNWYWwgPSBnZXRGaWVsZChjb250ZXh0LCBmZGVmKTsKKyAgICAgICAgICAgIElSdWJ5T2JqZWN0IHRoYXRWYWwgPSBtZXNzYWdlLmdldEZpZWxkKGNvbnRleHQsIGZkZWYpOworICAgICAgICAgICAgSVJ1YnlPYmplY3QgcmV0ID0gdGhpc1ZhbC5jYWxsTWV0aG9kKGNvbnRleHQsICI9PSIsIHRoYXRWYWwpOworICAgICAgICAgICAgaWYgKCFyZXQuaXNUcnVlKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcnVudGltZS5nZXRGYWxzZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBydW50aW1lLmdldFRydWUoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNZXNzYWdlLm1ldGhvZF9taXNzaW5nKCphcmdzKQorICAgICAqCisgICAgICogUHJvdmlkZXMgYWNjZXNzb3JzIGFuZCBzZXR0ZXJzIGZvciBtZXNzYWdlIGZpZWxkcyBhY2NvcmRpbmcgdG8gdGhlaXIgZmllbGQKKyAgICAgKiBuYW1lcy4gRm9yIGFueSBmaWVsZCB3aG9zZSBuYW1lIGRvZXMgbm90IGNvbmZsaWN0IHdpdGggYSBidWlsdC1pbiBtZXRob2QsIGFuCisgICAgICogYWNjZXNzb3IgaXMgcHJvdmlkZWQgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBmaWVsZCwgYW5kIGEgc2V0dGVyIGlzCisgICAgICogcHJvdmlkZWQgd2l0aCB0aGUgbmFtZSBvZiB0aGUgZmllbGQgcGx1cyB0aGUgJz0nIHN1ZmZpeC4gVGh1cywgZ2l2ZW4gYQorICAgICAqIG1lc3NhZ2UgaW5zdGFuY2UgJ21zZycgd2l0aCBmaWVsZCAnZm9vJywgdGhlIGZvbGxvd2luZyBjb2RlIGlzIHZhbGlkOgorICAgICAqCisgICAgICogICAgIG1zZy5mb28gPSA0MgorICAgICAqICAgICBwdXRzIG1zZy5mb28KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJtZXRob2RfbWlzc2luZyIsIHJlc3QgPSB0cnVlKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBtZXRob2RNaXNzaW5nKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PSAxKSB7CisgICAgICAgICAgICBSdWJ5RGVzY3JpcHRvciBydWJ5RGVzY3JpcHRvciA9IChSdWJ5RGVzY3JpcHRvcikgZ2V0RGVzY3JpcHRvcihjb250ZXh0LCBtZXRhQ2xhc3MpOworICAgICAgICAgICAgSVJ1YnlPYmplY3Qgb25lb2ZEZXNjcmlwdG9yID0gcnVieURlc2NyaXB0b3IubG9va3VwT25lb2YoY29udGV4dCwgYXJnc1swXSk7CisgICAgICAgICAgICBpZiAob25lb2ZEZXNjcmlwdG9yLmlzTmlsKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXgoY29udGV4dCwgYXJnc1swXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBSdWJ5T25lb2ZEZXNjcmlwdG9yIHJ1YnlPbmVvZkRlc2NyaXB0b3IgPSAoUnVieU9uZW9mRGVzY3JpcHRvcikgb25lb2ZEZXNjcmlwdG9yOworICAgICAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA9CisgICAgICAgICAgICAgICAgICAgIG9uZW9mQ2FzZXMuZ2V0KHJ1YnlPbmVvZkRlc2NyaXB0b3IuZ2V0T25lb2ZEZXNjcmlwdG9yKCkpOworICAgICAgICAgICAgaWYgKGZpZWxkRGVzY3JpcHRvciA9PSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisKKyAgICAgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUubmV3U3ltYm9sKGZpZWxkRGVzY3JpcHRvci5nZXROYW1lKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gZmllbGROYW1lIGlzIFJ1YnlTeW1ib2wKKyAgICAgICAgICAgIFJ1YnlTdHJpbmcgZmllbGQgPSBhcmdzWzBdLmFzU3RyaW5nKCk7CisgICAgICAgICAgICBSdWJ5U3RyaW5nIGVxdWFsU2lnbiA9IGNvbnRleHQucnVudGltZS5uZXdTdHJpbmcoVXRpbHMuRVFVQUxfU0lHTik7CisgICAgICAgICAgICBpZiAoZmllbGQuZW5kX3dpdGhfcChjb250ZXh0LCBlcXVhbFNpZ24pLmlzVHJ1ZSgpKSB7CisgICAgICAgICAgICAgICAgZmllbGQuY2hvbXBfYmFuZyhjb250ZXh0LCBlcXVhbFNpZ24pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGluZGV4U2V0KGNvbnRleHQsIGZpZWxkLCBhcmdzWzFdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqIE1lc3NhZ2UuZHVwID0+IG5ld19tZXNzYWdlCisgICAgICogUGVyZm9ybXMgYSBzaGFsbG93IGNvcHkgb2YgdGhpcyBtZXNzYWdlIGFuZCByZXR1cm5zIHRoZSBuZXcgY29weS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgZHVwKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBSdWJ5TWVzc2FnZSBkdXAgPSAoUnVieU1lc3NhZ2UpIG1ldGFDbGFzcy5uZXdJbnN0YW5jZShjb250ZXh0LCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgSVJ1YnlPYmplY3QgdmFsdWU7CisgICAgICAgIGZvciAoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA6IGJ1aWxkZXIuZ2V0QWxsRmllbGRzKCkua2V5U2V0KCkpIHsKKyAgICAgICAgICAgIGlmIChmaWVsZERlc2NyaXB0b3IuaXNSZXBlYXRlZCgpKSB7CisgICAgICAgICAgICAgICAgZHVwLnJlcGVhdGVkRmllbGRzLnB1dChmaWVsZERlc2NyaXB0b3IsIGdldFJlcGVhdGVkRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1aWxkZXIuaGFzRmllbGQoZmllbGREZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgICAgIGR1cC5maWVsZHMucHV0KGZpZWxkRGVzY3JpcHRvciwgd3JhcEZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvciwgYnVpbGRlci5nZXRGaWVsZChmaWVsZERlc2NyaXB0b3IpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yIDogZmllbGRzLmtleVNldCgpKSB7CisgICAgICAgICAgICBkdXAuZmllbGRzLnB1dChmaWVsZERlc2NyaXB0b3IsIGZpZWxkcy5nZXQoZmllbGREZXNjcmlwdG9yKSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yIDogbWFwcy5rZXlTZXQoKSkgeworICAgICAgICAgICAgZHVwLm1hcHMucHV0KGZpZWxkRGVzY3JpcHRvciwgbWFwcy5nZXQoZmllbGREZXNjcmlwdG9yKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGR1cDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNZXNzYWdlLmRlc2NyaXB0b3IgPT4gZGVzY3JpcHRvcgorICAgICAqCisgICAgICogQ2xhc3MgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgRGVzY3JpcHRvciBpbnN0YW5jZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMKKyAgICAgKiBtZXNzYWdlIGNsYXNzJ3MgdHlwZS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJkZXNjcmlwdG9yIiwgbWV0YSA9IHRydWUpCisgICAgcHVibGljIHN0YXRpYyBJUnVieU9iamVjdCBnZXREZXNjcmlwdG9yKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgcmVjdikgeworICAgICAgICByZXR1cm4gKChSdWJ5Q2xhc3MpIHJlY3YpLmdldEluc3RhbmNlVmFyaWFibGUoVXRpbHMuREVTQ1JJUFRPUl9JTlNUQU5DRV9WQVIpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2VDbGFzcy5lbmNvZGUobXNnKSA9PiBieXRlcworICAgICAqCisgICAgICogRW5jb2RlcyB0aGUgZ2l2ZW4gbWVzc2FnZSBvYmplY3QgdG8gaXRzIHNlcmlhbGl6ZWQgZm9ybSBpbiBwcm90b2NvbCBidWZmZXJzCisgICAgICogd2lyZSBmb3JtYXQuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG1ldGEgPSB0cnVlKQorICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3QgZW5jb2RlKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgcmVjdiwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgUnVieU1lc3NhZ2UgbWVzc2FnZSA9IChSdWJ5TWVzc2FnZSkgdmFsdWU7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUubmV3U3RyaW5nKG5ldyBCeXRlTGlzdChtZXNzYWdlLmJ1aWxkKGNvbnRleHQpLnRvQnl0ZUFycmF5KCkpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBNZXNzYWdlQ2xhc3MuZGVjb2RlKGRhdGEpID0+IG1lc3NhZ2UKKyAgICAgKgorICAgICAqIERlY29kZXMgdGhlIGdpdmVuIGRhdGEgKGFzIGEgc3RyaW5nIGNvbnRhaW5pbmcgYnl0ZXMgaW4gcHJvdG9jb2wgYnVmZmVycyB3aXJlCisgICAgICogZm9ybWF0KSB1bmRlciB0aGUgaW50ZXJwcmV0cmF0aW9uIGdpdmVuIGJ5IHRoaXMgbWVzc2FnZSBjbGFzcydzIGRlZmluaXRpb24KKyAgICAgKiBhbmQgcmV0dXJucyBhIG1lc3NhZ2Ugb2JqZWN0IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgdmFsdWVzLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChtZXRhID0gdHJ1ZSkKKyAgICBwdWJsaWMgc3RhdGljIElSdWJ5T2JqZWN0IGRlY29kZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IHJlY3YsIElSdWJ5T2JqZWN0IGRhdGEpIHsKKyAgICAgICAgYnl0ZVtdIGJpbiA9IGRhdGEuY29udmVydFRvU3RyaW5nKCkuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgUnVieU1lc3NhZ2UgcmV0ID0gKFJ1YnlNZXNzYWdlKSAoKFJ1YnlDbGFzcykgcmVjdikubmV3SW5zdGFuY2UoY29udGV4dCwgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQuYnVpbGRlci5tZXJnZUZyb20oYmluKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGNvbnRleHQucnVudGltZS5uZXdSdW50aW1lRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWVzc2FnZUNsYXNzLmVuY29kZV9qc29uKG1zZykgPT4ganNvbl9zdHJpbmcKKyAgICAgKgorICAgICAqIEVuY29kZXMgdGhlIGdpdmVuIG1lc3NhZ2Ugb2JqZWN0IGludG8gaXRzIHNlcmlhbGl6ZWQgSlNPTiByZXByZXNlbnRhdGlvbi4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJlbmNvZGVfanNvbiIsIG1ldGEgPSB0cnVlKQorICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3QgZW5jb2RlSnNvbihUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IHJlY3YsIElSdWJ5T2JqZWN0IG1zZ1JiKSB7CisgICAgICAgIFJ1YnlNZXNzYWdlIG1lc3NhZ2UgPSAoUnVieU1lc3NhZ2UpIG1zZ1JiOworICAgICAgICByZXR1cm4gSGVscGVycy5pbnZva2UoY29udGV4dCwgbWVzc2FnZS50b0hhc2goY29udGV4dCksICJ0b19qc29uIik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWVzc2FnZUNsYXNzLmRlY29kZV9qc29uKGRhdGEpID0+IG1lc3NhZ2UKKyAgICAgKgorICAgICAqIERlY29kZXMgdGhlIGdpdmVuIGRhdGEgKGFzIGEgc3RyaW5nIGNvbnRhaW5pbmcgYnl0ZXMgaW4gcHJvdG9jb2wgYnVmZmVycyB3aXJlCisgICAgICogZm9ybWF0KSB1bmRlciB0aGUgaW50ZXJwcmV0cmF0aW9uIGdpdmVuIGJ5IHRoaXMgbWVzc2FnZSBjbGFzcydzIGRlZmluaXRpb24KKyAgICAgKiBhbmQgcmV0dXJucyBhIG1lc3NhZ2Ugb2JqZWN0IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgdmFsdWVzLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gImRlY29kZV9qc29uIiwgbWV0YSA9IHRydWUpCisgICAgcHVibGljIHN0YXRpYyBJUnVieU9iamVjdCBkZWNvZGVKc29uKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgcmVjdiwgSVJ1YnlPYmplY3QganNvbikgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIFJ1YnlNZXNzYWdlIHJldCA9IChSdWJ5TWVzc2FnZSkgKChSdWJ5Q2xhc3MpIHJlY3YpLm5ld0luc3RhbmNlKGNvbnRleHQsIEJsb2NrLk5VTExfQkxPQ0spOworICAgICAgICBSdWJ5TW9kdWxlIGpzb25Nb2R1bGUgPSBydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkpTT04iKTsKKyAgICAgICAgUnVieUhhc2ggb3B0cyA9IFJ1YnlIYXNoLm5ld0hhc2gocnVudGltZSk7CisgICAgICAgIG9wdHMuZmFzdEFTZXQocnVudGltZS5uZXdTeW1ib2woInN5bWJvbGl6ZV9uYW1lcyIpLCBydW50aW1lLmdldFRydWUoKSk7CisgICAgICAgIElSdWJ5T2JqZWN0W10gYXJncyA9IG5ldyBJUnVieU9iamVjdFtdIHsgSGVscGVycy5pbnZva2UoY29udGV4dCwganNvbk1vZHVsZSwgInBhcnNlIiwganNvbiwgb3B0cykgfTsKKyAgICAgICAgcmV0LmluaXRpYWxpemUoY29udGV4dCwgYXJncyk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAidG9faCIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IHRvSGFzaChUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgUnVieSBydW50aW1lID0gY29udGV4dC5ydW50aW1lOworICAgICAgICBSdWJ5SGFzaCByZXQgPSBSdWJ5SGFzaC5uZXdIYXNoKHJ1bnRpbWUpOworICAgICAgICBmb3IgKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmZGVmIDogdGhpcy5kZXNjcmlwdG9yLmdldEZpZWxkcygpKSB7CisgICAgICAgICAgICBJUnVieU9iamVjdCB2YWx1ZSA9IGdldEZpZWxkKGNvbnRleHQsIGZkZWYpOworICAgICAgICAgICAgaWYgKHZhbHVlLnJlc3BvbmRzVG8oInRvX2giKSkgeworICAgICAgICAgICAgICAgIHZhbHVlID0gSGVscGVycy5pbnZva2UoY29udGV4dCwgdmFsdWUsICJ0b19oIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXQuZmFzdEFTZXQocnVudGltZS5uZXdTdHJpbmcoZmRlZi5nZXROYW1lKCkpLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgRHluYW1pY01lc3NhZ2UgYnVpbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBidWlsZChjb250ZXh0LCAwKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgRHluYW1pY01lc3NhZ2UgYnVpbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBpbnQgZGVwdGgpIHsKKyAgICAgICAgaWYgKGRlcHRoID4gU0lOS19NQVhJTVVNX05FU1RJTkcpIHsKKyAgICAgICAgICAgIHRocm93IGNvbnRleHQucnVudGltZS5uZXdSdW50aW1lRXJyb3IoIk1heGltdW0gcmVjdXJzaW9uIGRlcHRoIGV4Y2VlZGVkIGR1cmluZyBlbmNvZGluZy4iKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IgOiBtYXBzLmtleVNldCgpKSB7CisgICAgICAgICAgICB0aGlzLmJ1aWxkZXIuY2xlYXJGaWVsZChmaWVsZERlc2NyaXB0b3IpOworICAgICAgICAgICAgUnVieURlc2NyaXB0b3IgbWFwRGVzY3JpcHRvciA9IChSdWJ5RGVzY3JpcHRvcikgZ2V0RGVzY3JpcHRvckZvckZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICBmb3IgKER5bmFtaWNNZXNzYWdlIGt2IDogbWFwcy5nZXQoZmllbGREZXNjcmlwdG9yKS5idWlsZChjb250ZXh0LCBtYXBEZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkRGVzY3JpcHRvciwga3YpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA6IHJlcGVhdGVkRmllbGRzLmtleVNldCgpKSB7CisgICAgICAgICAgICBSdWJ5UmVwZWF0ZWRGaWVsZCByZXBlYXRlZEZpZWxkID0gcmVwZWF0ZWRGaWVsZHMuZ2V0KGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICB0aGlzLmJ1aWxkZXIuY2xlYXJGaWVsZChmaWVsZERlc2NyaXB0b3IpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZpZWxkLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGl0ZW0gPSBjb252ZXJ0KGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvciwgcmVwZWF0ZWRGaWVsZC5nZXQoaSksIGRlcHRoKTsKKyAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZERlc2NyaXB0b3IsIGl0ZW0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciA6IGZpZWxkcy5rZXlTZXQoKSkgeworICAgICAgICAgICAgSVJ1YnlPYmplY3QgdmFsdWUgPSBmaWVsZHMuZ2V0KGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICB0aGlzLmJ1aWxkZXIuc2V0RmllbGQoZmllbGREZXNjcmlwdG9yLCBjb252ZXJ0KGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvciwgdmFsdWUsIGRlcHRoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRlci5idWlsZCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCBEZXNjcmlwdG9ycy5EZXNjcmlwdG9yIGdldERlc2NyaXB0b3IoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmRlc2NyaXB0b3I7CisgICAgfQorCisgICAgLy8gSW50ZXJuYWwgdXNlIG9ubHksIGNhbGxlZCBieSBHb29nbGU6OlByb3RvYnVmLmRlZXBfY29weQorICAgIHByb3RlY3RlZCBJUnVieU9iamVjdCBkZWVwQ29weShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgUnVieU1lc3NhZ2UgY29weSA9IChSdWJ5TWVzc2FnZSkgbWV0YUNsYXNzLm5ld0luc3RhbmNlKGNvbnRleHQsIEJsb2NrLk5VTExfQkxPQ0spOworICAgICAgICBmb3IgKERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmZGVmIDogdGhpcy5kZXNjcmlwdG9yLmdldEZpZWxkcygpKSB7CisgICAgICAgICAgICBpZiAoZmRlZi5pc1JlcGVhdGVkKCkpIHsKKyAgICAgICAgICAgICAgICBjb3B5LmFkZFJlcGVhdGVkRmllbGQoZmRlZiwgdGhpcy5nZXRSZXBlYXRlZEZpZWxkKGNvbnRleHQsIGZkZWYpLmRlZXBDb3B5KGNvbnRleHQpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZmllbGRzLmNvbnRhaW5zS2V5KGZkZWYpKSB7CisgICAgICAgICAgICAgICAgY29weS5maWVsZHMucHV0KGZkZWYsIGZpZWxkcy5nZXQoZmRlZikpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmJ1aWxkZXIuaGFzRmllbGQoZmRlZikpIHsKKyAgICAgICAgICAgICAgICBjb3B5LmZpZWxkcy5wdXQoZmRlZiwgd3JhcEZpZWxkKGNvbnRleHQsIGZkZWYsIHRoaXMuYnVpbGRlci5nZXRGaWVsZChmZGVmKSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3B5OworICAgIH0KKworICAgIHByaXZhdGUgUnVieVJlcGVhdGVkRmllbGQgZ2V0UmVwZWF0ZWRGaWVsZChUaHJlYWRDb250ZXh0IGNvbnRleHQsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IpIHsKKyAgICAgICAgaWYgKHRoaXMucmVwZWF0ZWRGaWVsZHMuY29udGFpbnNLZXkoZmllbGREZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVwZWF0ZWRGaWVsZHMuZ2V0KGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgIH0KKyAgICAgICAgaW50IGNvdW50ID0gdGhpcy5idWlsZGVyLmdldFJlcGVhdGVkRmllbGRDb3VudChmaWVsZERlc2NyaXB0b3IpOworICAgICAgICBSdWJ5UmVwZWF0ZWRGaWVsZCByZXQgPSByZXBlYXRlZEZpZWxkRm9yRmllbGREZXNjcmlwdG9yKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgcmV0LnB1c2goY29udGV4dCwgd3JhcEZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvciwgdGhpcy5idWlsZGVyLmdldFJlcGVhdGVkRmllbGQoZmllbGREZXNjcmlwdG9yLCBpKSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFkZFJlcGVhdGVkRmllbGQoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciwgUnVieVJlcGVhdGVkRmllbGQgcmVwZWF0ZWRGaWVsZCkgeworICAgICAgICB0aGlzLnJlcGVhdGVkRmllbGRzLnB1dChmaWVsZERlc2NyaXB0b3IsIHJlcGVhdGVkRmllbGQpOworICAgIH0KKworICAgIHByaXZhdGUgSVJ1YnlPYmplY3QgYnVpbGRGcm9tKFRocmVhZENvbnRleHQgY29udGV4dCwgRHluYW1pY01lc3NhZ2UgZHluYW1pY01lc3NhZ2UpIHsKKyAgICAgICAgdGhpcy5idWlsZGVyLm1lcmdlRnJvbShkeW5hbWljTWVzc2FnZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHByaXZhdGUgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpbmRGaWVsZChUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IGZpZWxkTmFtZSkgeworICAgICAgICBTdHJpbmcgbmFtZVN0ciA9IGZpZWxkTmFtZS5hc0phdmFTdHJpbmcoKTsKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIHJldCA9IHRoaXMuZGVzY3JpcHRvci5maW5kRmllbGRCeU5hbWUoVXRpbHMuZXNjYXBlSWRlbnRpZmllcihuYW1lU3RyKSk7CisgICAgICAgIGlmIChyZXQgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IGNvbnRleHQucnVudGltZS5uZXdBcmd1bWVudEVycm9yKCJmaWVsZCAiICsgZmllbGROYW1lLmFzSmF2YVN0cmluZygpICsgIiBpcyBub3QgZm91bmQiKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSZXBlYXRlZEZpZWxkVHlwZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IpIHsKKyAgICAgICAgUnVieSBydW50aW1lID0gY29udGV4dC5ydW50aW1lOworICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIFJ1YnlSZXBlYXRlZEZpZWxkKSkgeworICAgICAgICAgICAgdGhyb3cgcnVudGltZS5uZXdUeXBlRXJyb3IoIkV4cGVjdGVkIHJlcGVhdGVkIGZpZWxkIGFycmF5Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBjb252ZXJ0IGEgcnVieSBvYmplY3QgdG8gcHJvdG9idWYgdHlwZSwgd2l0aCB0eXBlIGNoZWNrCisgICAgcHJpdmF0ZSBPYmplY3QgY29udmVydChUaHJlYWRDb250ZXh0IGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgSVJ1YnlPYmplY3QgdmFsdWUsIGludCBkZXB0aCkgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIE9iamVjdCB2YWwgPSBudWxsOworICAgICAgICBzd2l0Y2ggKGZpZWxkRGVzY3JpcHRvci5nZXRUeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgSU5UMzI6CisgICAgICAgICAgICBjYXNlIElOVDY0OgorICAgICAgICAgICAgY2FzZSBVSU5UMzI6CisgICAgICAgICAgICBjYXNlIFVJTlQ2NDoKKyAgICAgICAgICAgICAgICBpZiAoIVV0aWxzLmlzUnVieU51bSh2YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgcnVudGltZS5uZXdUeXBlRXJyb3IoIkV4cGVjdGVkIG51bWJlciB0eXBlIGZvciBpbnRlZ3JhbCBmaWVsZC4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgVXRpbHMuY2hlY2tJbnRUeXBlUHJlY2lzaW9uKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvci5nZXRUeXBlKCksIHZhbHVlKTsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGZpZWxkRGVzY3JpcHRvci5nZXRUeXBlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBJTlQzMjoKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IFJ1YnlOdW1lcmljLm51bTJpbnQodmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBSdWJ5TnVtZXJpYy5udW0ybG9uZyh2YWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBVSU5UMzI6CisgICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBVdGlscy5udW0ydWludCh2YWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBVSU5UNjQ6CisgICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBVdGlscy5udW0ydWxvbmcoY29udGV4dC5ydW50aW1lLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRkxPQVQ6CisgICAgICAgICAgICAgICAgaWYgKCFVdGlscy5pc1J1YnlOdW0odmFsdWUpKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiRXhwZWN0ZWQgbnVtYmVyIHR5cGUgZm9yIGZsb2F0IGZpZWxkLiIpOworICAgICAgICAgICAgICAgIHZhbCA9IChmbG9hdCkgUnVieU51bWVyaWMubnVtMmRibCh2YWx1ZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERPVUJMRToKKyAgICAgICAgICAgICAgICBpZiAoIVV0aWxzLmlzUnVieU51bSh2YWx1ZSkpCisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFeHBlY3RlZCBudW1iZXIgdHlwZSBmb3IgZG91YmxlIGZpZWxkLiIpOworICAgICAgICAgICAgICAgIHZhbCA9IFJ1YnlOdW1lcmljLm51bTJkYmwodmFsdWUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBCT09MOgorICAgICAgICAgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgUnVieUJvb2xlYW4pKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiSW52YWxpZCBhcmd1bWVudCBmb3IgYm9vbGVhbiBmaWVsZC4iKTsKKyAgICAgICAgICAgICAgICB2YWwgPSB2YWx1ZS5pc1RydWUoKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQllURVM6CisgICAgICAgICAgICBjYXNlIFNUUklORzoKKyAgICAgICAgICAgICAgICBVdGlscy52YWxpZGF0ZVN0cmluZ0VuY29kaW5nKGNvbnRleHQucnVudGltZSwgZmllbGREZXNjcmlwdG9yLmdldFR5cGUoKSwgdmFsdWUpOworICAgICAgICAgICAgICAgIFJ1YnlTdHJpbmcgc3RyID0gKFJ1YnlTdHJpbmcpIHZhbHVlOworICAgICAgICAgICAgICAgIHN3aXRjaCAoZmllbGREZXNjcmlwdG9yLmdldFR5cGUoKSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIEJZVEVTOgorICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gQnl0ZVN0cmluZy5jb3B5RnJvbShzdHIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFJJTkc6CisgICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBzdHIuYXNKYXZhU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgTUVTU0FHRToKKyAgICAgICAgICAgICAgICBSdWJ5Q2xhc3MgdHlwZUNsYXNzID0gKFJ1YnlDbGFzcykgKChSdWJ5RGVzY3JpcHRvcikgZ2V0RGVzY3JpcHRvckZvckZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcikpLm1zZ2NsYXNzKGNvbnRleHQpOworICAgICAgICAgICAgICAgIGlmICghdmFsdWUuZ2V0TWV0YUNsYXNzKCkuZXF1YWxzKHR5cGVDbGFzcykpCisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKHZhbHVlLCAiSW52YWxpZCB0eXBlIHRvIGFzc2lnbiB0byBzdWJtZXNzYWdlIGZpZWxkLiIpOworICAgICAgICAgICAgICAgIHZhbCA9ICgoUnVieU1lc3NhZ2UpIHZhbHVlKS5idWlsZChjb250ZXh0LCBkZXB0aCArIDEpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBFTlVNOgorICAgICAgICAgICAgICAgIERlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yIGVudW1EZXNjcmlwdG9yID0gZmllbGREZXNjcmlwdG9yLmdldEVudW1UeXBlKCk7CisKKyAgICAgICAgICAgICAgICBpZiAoVXRpbHMuaXNSdWJ5TnVtKHZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICB2YWwgPSBlbnVtRGVzY3JpcHRvci5maW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKFJ1YnlOdW1lcmljLm51bTJpbnQodmFsdWUpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgUnVieVN5bWJvbCkgeworICAgICAgICAgICAgICAgICAgICB2YWwgPSBlbnVtRGVzY3JpcHRvci5maW5kVmFsdWVCeU5hbWUodmFsdWUuYXNKYXZhU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFeHBlY3RlZCBudW1iZXIgb3Igc3ltYm9sIHR5cGUgZm9yIGVudW0gZmllbGQuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh2YWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1JhbmdlRXJyb3IoIkVudW0gdmFsdWUgIiArIHZhbHVlICsgIiBpcyBub3QgZm91bmQuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsOworICAgIH0KKworICAgIHByaXZhdGUgSVJ1YnlPYmplY3Qgd3JhcEZpZWxkKFRocmVhZENvbnRleHQgY29udGV4dCwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgICAgICB9CisgICAgICAgIFJ1YnkgcnVudGltZSA9IGNvbnRleHQucnVudGltZTsKKyAgICAgICAgc3dpdGNoIChmaWVsZERlc2NyaXB0b3IuZ2V0VHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIElOVDMyOgorICAgICAgICAgICAgY2FzZSBJTlQ2NDoKKyAgICAgICAgICAgIGNhc2UgVUlOVDMyOgorICAgICAgICAgICAgY2FzZSBVSU5UNjQ6CisgICAgICAgICAgICBjYXNlIEZMT0FUOgorICAgICAgICAgICAgY2FzZSBET1VCTEU6CisgICAgICAgICAgICBjYXNlIEJPT0w6CisgICAgICAgICAgICBjYXNlIEJZVEVTOgorICAgICAgICAgICAgY2FzZSBTVFJJTkc6CisgICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLndyYXBQcmltYXJ5VmFsdWUoY29udGV4dCwgZmllbGREZXNjcmlwdG9yLmdldFR5cGUoKSwgdmFsdWUpOworICAgICAgICAgICAgY2FzZSBNRVNTQUdFOgorICAgICAgICAgICAgICAgIFJ1YnlDbGFzcyB0eXBlQ2xhc3MgPSAoUnVieUNsYXNzKSAoKFJ1YnlEZXNjcmlwdG9yKSBnZXREZXNjcmlwdG9yRm9yRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKSkubXNnY2xhc3MoY29udGV4dCk7CisgICAgICAgICAgICAgICAgUnVieU1lc3NhZ2UgbXNnID0gKFJ1YnlNZXNzYWdlKSB0eXBlQ2xhc3MubmV3SW5zdGFuY2UoY29udGV4dCwgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1zZy5idWlsZEZyb20oY29udGV4dCwgKER5bmFtaWNNZXNzYWdlKSB2YWx1ZSk7CisgICAgICAgICAgICBjYXNlIEVOVU06CisgICAgICAgICAgICAgICAgRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBlbnVtVmFsdWVEZXNjcmlwdG9yID0gKERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IpIHZhbHVlOworICAgICAgICAgICAgICAgIGlmIChlbnVtVmFsdWVEZXNjcmlwdG9yLmdldEluZGV4KCkgPT0gLTEpIHsgLy8gVU5LTk9XTiBFTlVNIFZBTFVFCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBydW50aW1lLm5ld0ZpeG51bShlbnVtVmFsdWVEZXNjcmlwdG9yLmdldE51bWJlcigpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJ1bnRpbWUubmV3U3ltYm9sKGVudW1WYWx1ZURlc2NyaXB0b3IuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJ1bnRpbWUubmV3U3RyaW5nKHZhbHVlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBSdWJ5UmVwZWF0ZWRGaWVsZCByZXBlYXRlZEZpZWxkRm9yRmllbGREZXNjcmlwdG9yKFRocmVhZENvbnRleHQgY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvcikgeworICAgICAgICBJUnVieU9iamVjdCB0eXBlQ2xhc3MgPSBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsQ2xhc3MoKTsKKworICAgICAgICBJUnVieU9iamVjdCBkZXNjcmlwdG9yID0gZ2V0RGVzY3JpcHRvckZvckZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIHR5cGUgPSBmaWVsZERlc2NyaXB0b3IuZ2V0VHlwZSgpOworICAgICAgICBpZiAodHlwZSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFKSB7CisgICAgICAgICAgICB0eXBlQ2xhc3MgPSAoKFJ1YnlEZXNjcmlwdG9yKSBkZXNjcmlwdG9yKS5tc2djbGFzcyhjb250ZXh0KTsKKworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuRU5VTSkgeworICAgICAgICAgICAgdHlwZUNsYXNzID0gKChSdWJ5RW51bURlc2NyaXB0b3IpIGRlc2NyaXB0b3IpLmVudW1tb2R1bGUoY29udGV4dCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBSdWJ5UmVwZWF0ZWRGaWVsZChjb250ZXh0LnJ1bnRpbWUsIGNSZXBlYXRlZEZpZWxkLCB0eXBlLCB0eXBlQ2xhc3MpOworICAgIH0KKworICAgIHByb3RlY3RlZCBJUnVieU9iamVjdCBnZXRGaWVsZChUaHJlYWRDb250ZXh0IGNvbnRleHQsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IpIHsKKyAgICAgICAgRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mRGVzY3JpcHRvciA9IGZpZWxkRGVzY3JpcHRvci5nZXRDb250YWluaW5nT25lb2YoKTsKKyAgICAgICAgaWYgKG9uZW9mRGVzY3JpcHRvciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAob25lb2ZDYXNlcy5jb250YWluc0tleShvbmVvZkRlc2NyaXB0b3IpKSB7CisgICAgICAgICAgICAgICAgaWYgKG9uZW9mQ2FzZXMuZ2V0KG9uZW9mRGVzY3JpcHRvcikgIT0gZmllbGREZXNjcmlwdG9yKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgICAgICAgICAgICAgIHJldHVybiBmaWVsZHMuZ2V0KGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBvbmVvZkNhc2UgPSBidWlsZGVyLmdldE9uZW9mRmllbGREZXNjcmlwdG9yKG9uZW9mRGVzY3JpcHRvcik7CisgICAgICAgICAgICAgICAgaWYgKG9uZW9mQ2FzZSAhPSBmaWVsZERlc2NyaXB0b3IpIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgICAgICAgICAgICAgSVJ1YnlPYmplY3QgdmFsdWUgPSB3cmFwRmllbGQoY29udGV4dCwgb25lb2ZDYXNlLCBidWlsZGVyLmdldEZpZWxkKG9uZW9mQ2FzZSkpOworICAgICAgICAgICAgICAgIGZpZWxkcy5wdXQoZmllbGREZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKFV0aWxzLmlzTWFwRW50cnkoZmllbGREZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgUnVieU1hcCBtYXAgPSBtYXBzLmdldChmaWVsZERlc2NyaXB0b3IpOworICAgICAgICAgICAgaWYgKG1hcCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbWFwID0gbmV3TWFwRm9yRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgICAgICAgICBpbnQgbWFwU2l6ZSA9IHRoaXMuYnVpbGRlci5nZXRSZXBlYXRlZEZpZWxkQ291bnQoZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3Iga2V5RmllbGQgPSBmaWVsZERlc2NyaXB0b3IuZ2V0TWVzc2FnZVR5cGUoKS5maW5kRmllbGRCeU51bWJlcigxKTsKKyAgICAgICAgICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgdmFsdWVGaWVsZCA9IGZpZWxkRGVzY3JpcHRvci5nZXRNZXNzYWdlVHlwZSgpLmZpbmRGaWVsZEJ5TnVtYmVyKDIpOworICAgICAgICAgICAgICAgIFJ1YnlEZXNjcmlwdG9yIGt2RGVzY3JpcHRvciA9IChSdWJ5RGVzY3JpcHRvcikgZ2V0RGVzY3JpcHRvckZvckZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICAgICAgUnVieUNsYXNzIGt2Q2xhc3MgPSAoUnVieUNsYXNzKSBrdkRlc2NyaXB0b3IubXNnY2xhc3MoY29udGV4dCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBTaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgUnVieU1lc3NhZ2Uga3ZNZXNzYWdlID0gKFJ1YnlNZXNzYWdlKSBrdkNsYXNzLm5ld0luc3RhbmNlKGNvbnRleHQsIEJsb2NrLk5VTExfQkxPQ0spOworICAgICAgICAgICAgICAgICAgICBEeW5hbWljTWVzc2FnZSBtZXNzYWdlID0gKER5bmFtaWNNZXNzYWdlKSB0aGlzLmJ1aWxkZXIuZ2V0UmVwZWF0ZWRGaWVsZChmaWVsZERlc2NyaXB0b3IsIGkpOworICAgICAgICAgICAgICAgICAgICBrdk1lc3NhZ2UuYnVpbGRGcm9tKGNvbnRleHQsIG1lc3NhZ2UpOworICAgICAgICAgICAgICAgICAgICBtYXAuaW5kZXhTZXQoY29udGV4dCwga3ZNZXNzYWdlLmdldEZpZWxkKGNvbnRleHQsIGtleUZpZWxkKSwga3ZNZXNzYWdlLmdldEZpZWxkKGNvbnRleHQsIHZhbHVlRmllbGQpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbWFwcy5wdXQoZmllbGREZXNjcmlwdG9yLCBtYXApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG1hcDsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmllbGREZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmllbGREZXNjcmlwdG9yLmdldFR5cGUoKSAhPSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5NRVNTQUdFIHx8CisgICAgICAgICAgICAgICAgdGhpcy5idWlsZGVyLmhhc0ZpZWxkKGZpZWxkRGVzY3JpcHRvcikgfHwgZmllbGRzLmNvbnRhaW5zS2V5KGZpZWxkRGVzY3JpcHRvcikpIHsKKyAgICAgICAgICAgIGlmIChmaWVsZHMuY29udGFpbnNLZXkoZmllbGREZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmaWVsZHMuZ2V0KGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIElSdWJ5T2JqZWN0IHZhbHVlID0gd3JhcEZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvciwgdGhpcy5idWlsZGVyLmdldEZpZWxkKGZpZWxkRGVzY3JpcHRvcikpOworICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1aWxkZXIuaGFzRmllbGQoZmllbGREZXNjcmlwdG9yKSkgeworICAgICAgICAgICAgICAgICAgICBmaWVsZHMucHV0KGZpZWxkRGVzY3JpcHRvciwgdmFsdWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgSVJ1YnlPYmplY3Qgc2V0RmllbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yLCBJUnVieU9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAoVXRpbHMuaXNNYXBFbnRyeShmaWVsZERlc2NyaXB0b3IpKSB7CisgICAgICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIFJ1YnlNYXApKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgY29udGV4dC5ydW50aW1lLm5ld1R5cGVFcnJvcigiRXhwZWN0ZWQgTWFwIGluc3RhbmNlIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBSdWJ5TWFwIHRoaXNNYXAgPSAoUnVieU1hcCkgZ2V0RmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgICAgIHRoaXNNYXAubWVyZ2VJbnRvU2VsZihjb250ZXh0LCB2YWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZmllbGREZXNjcmlwdG9yLmlzUmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgY2hlY2tSZXBlYXRlZEZpZWxkVHlwZShjb250ZXh0LCB2YWx1ZSwgZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJ1YnlSZXBlYXRlZEZpZWxkKSB7CisgICAgICAgICAgICAgICAgYWRkUmVwZWF0ZWRGaWVsZChmaWVsZERlc2NyaXB0b3IsIChSdWJ5UmVwZWF0ZWRGaWVsZCkgdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBSdWJ5QXJyYXkgYXJ5ID0gdmFsdWUuY29udmVydFRvQXJyYXkoKTsKKyAgICAgICAgICAgICAgICBSdWJ5UmVwZWF0ZWRGaWVsZCByZXBlYXRlZEZpZWxkID0gcnVieVRvUmVwZWF0ZWRGaWVsZChjb250ZXh0LCBmaWVsZERlc2NyaXB0b3IsIGFyeSk7CisgICAgICAgICAgICAgICAgYWRkUmVwZWF0ZWRGaWVsZChmaWVsZERlc2NyaXB0b3IsIHJlcGVhdGVkRmllbGQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mRGVzY3JpcHRvciA9IGZpZWxkRGVzY3JpcHRvci5nZXRDb250YWluaW5nT25lb2YoKTsKKyAgICAgICAgICAgIGlmIChvbmVvZkRlc2NyaXB0b3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBvbmVvZkNhc2UgPSBvbmVvZkNhc2VzLmdldChvbmVvZkRlc2NyaXB0b3IpOworICAgICAgICAgICAgICAgIGlmIChvbmVvZkNhc2UgIT0gbnVsbCAmJiBvbmVvZkNhc2UgIT0gZmllbGREZXNjcmlwdG9yKSB7CisgICAgICAgICAgICAgICAgICAgIGZpZWxkcy5yZW1vdmUob25lb2ZDYXNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmlzTmlsKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgb25lb2ZDYXNlcy5yZW1vdmUob25lb2ZEZXNjcmlwdG9yKTsKKyAgICAgICAgICAgICAgICAgICAgZmllbGRzLnJlbW92ZShmaWVsZERlc2NyaXB0b3IpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG9uZW9mQ2FzZXMucHV0KG9uZW9mRGVzY3JpcHRvciwgZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgICAgICAgICAgICAgZmllbGRzLnB1dChmaWVsZERlc2NyaXB0b3IsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIGZpZWxkVHlwZSA9IGZpZWxkRGVzY3JpcHRvci5nZXRUeXBlKCk7CisgICAgICAgICAgICAgICAgSVJ1YnlPYmplY3QgdHlwZUNsYXNzID0gY29udGV4dC5ydW50aW1lLmdldE9iamVjdCgpOworICAgICAgICAgICAgICAgIGlmIChmaWVsZFR5cGUgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuTUVTU0FHRSkgeworICAgICAgICAgICAgICAgICAgICB0eXBlQ2xhc3MgPSAoKFJ1YnlEZXNjcmlwdG9yKSBnZXREZXNjcmlwdG9yRm9yRmllbGQoY29udGV4dCwgZmllbGREZXNjcmlwdG9yKSkubXNnY2xhc3MoY29udGV4dCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZFR5cGUgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuRU5VTSkgeworICAgICAgICAgICAgICAgICAgICB0eXBlQ2xhc3MgPSAoKFJ1YnlFbnVtRGVzY3JpcHRvcikgZ2V0RGVzY3JpcHRvckZvckZpZWxkKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcikpLmVudW1tb2R1bGUoY29udGV4dCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFV0aWxzLmNoZWNrVHlwZShjb250ZXh0LCBmaWVsZFR5cGUsIHZhbHVlLCAoUnVieU1vZHVsZSkgdHlwZUNsYXNzKTsKKyAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IGludGVnZXIgZW51bSB0byBzeW1ib2wKKyAgICAgICAgICAgICAgICBpZiAoZmllbGRUeXBlID09IERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlLkVOVU0pIHsKKyAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IgZW51bURlc2NyaXB0b3IgPSBmaWVsZERlc2NyaXB0b3IuZ2V0RW51bVR5cGUoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKFV0aWxzLmlzUnVieU51bSh2YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgdmFsID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bURlc2NyaXB0b3IuZmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bihSdWJ5TnVtZXJpYy5udW0yaW50KHZhbHVlKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsLmdldEluZGV4KCkgIT0gLTEpIHZhbHVlID0gY29udGV4dC5ydW50aW1lLm5ld1N5bWJvbCh2YWwuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aGlzLmZpZWxkcy5wdXQoZmllbGREZXNjcmlwdG9yLCB2YWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBsYXlvdXRJbnNwZWN0KCkgeworICAgICAgICBUaHJlYWRDb250ZXh0IGNvbnRleHQgPSBnZXRSdW50aW1lKCkuZ2V0Q3VycmVudENvbnRleHQoKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZkZWYgOiBkZXNjcmlwdG9yLmdldEZpZWxkcygpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoVXRpbHMudW5lc2NhcGVJZGVudGlmaWVyKGZkZWYuZ2V0TmFtZSgpKSk7CisgICAgICAgICAgICBzYi5hcHBlbmQoIjogIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoZ2V0RmllbGQoY29udGV4dCwgZmRlZikuaW5zcGVjdCgpKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2Iuc3Vic3RyaW5nKDAsIHNiLmxlbmd0aCgpIC0gMik7CisgICAgfQorCisgICAgcHJpdmF0ZSBJUnVieU9iamVjdCBnZXREZXNjcmlwdG9yRm9yRmllbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yKSB7CisgICAgICAgIFJ1YnlEZXNjcmlwdG9yIHRoaXNSYkRlc2NyaXB0b3IgPSAoUnVieURlc2NyaXB0b3IpIGdldERlc2NyaXB0b3IoY29udGV4dCwgbWV0YUNsYXNzKTsKKyAgICAgICAgcmV0dXJuIHRoaXNSYkRlc2NyaXB0b3IubG9va3VwKGZpZWxkRGVzY3JpcHRvci5nZXROYW1lKCkpLmdldFN1YlR5cGUoY29udGV4dCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBSdWJ5UmVwZWF0ZWRGaWVsZCBydWJ5VG9SZXBlYXRlZEZpZWxkKFRocmVhZENvbnRleHQgY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkRGVzY3JpcHRvciwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgUnVieUFycmF5IGFyciA9IHZhbHVlLmNvbnZlcnRUb0FycmF5KCk7CisgICAgICAgIFJ1YnlSZXBlYXRlZEZpZWxkIHJlcGVhdGVkRmllbGQgPSByZXBlYXRlZEZpZWxkRm9yRmllbGREZXNjcmlwdG9yKGNvbnRleHQsIGZpZWxkRGVzY3JpcHRvcik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICByZXBlYXRlZEZpZWxkLnB1c2goY29udGV4dCwgYXJyLmVsdEludGVybmFsKGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaWVsZDsKKyAgICB9CisKKyAgICBwcml2YXRlIFJ1YnlNYXAgbmV3TWFwRm9yRmllbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGREZXNjcmlwdG9yKSB7CisgICAgICAgIFJ1YnlEZXNjcmlwdG9yIG1hcERlc2NyaXB0b3IgPSAoUnVieURlc2NyaXB0b3IpIGdldERlc2NyaXB0b3JGb3JGaWVsZChjb250ZXh0LCBmaWVsZERlc2NyaXB0b3IpOworICAgICAgICBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3Iga2V5RmllbGQgPSBmaWVsZERlc2NyaXB0b3IuZ2V0TWVzc2FnZVR5cGUoKS5maW5kRmllbGRCeU51bWJlcigxKTsKKyAgICAgICAgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIHZhbHVlRmllbGQgPSBmaWVsZERlc2NyaXB0b3IuZ2V0TWVzc2FnZVR5cGUoKS5maW5kRmllbGRCeU51bWJlcigyKTsKKyAgICAgICAgSVJ1YnlPYmplY3Qga2V5VHlwZSA9IFJ1YnlTeW1ib2wubmV3U3ltYm9sKGNvbnRleHQucnVudGltZSwga2V5RmllbGQuZ2V0VHlwZSgpLm5hbWUoKSk7CisgICAgICAgIElSdWJ5T2JqZWN0IHZhbHVlVHlwZSA9IFJ1YnlTeW1ib2wubmV3U3ltYm9sKGNvbnRleHQucnVudGltZSwgdmFsdWVGaWVsZC5nZXRUeXBlKCkubmFtZSgpKTsKKyAgICAgICAgaWYgKHZhbHVlRmllbGQuZ2V0VHlwZSgpID09IERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlLk1FU1NBR0UpIHsKKyAgICAgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IgcnVieUZpZWxkRGVzY3JpcHRvciA9IChSdWJ5RmllbGREZXNjcmlwdG9yKSBtYXBEZXNjcmlwdG9yLmxvb2t1cChjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnJ1bnRpbWUubmV3U3RyaW5nKCJ2YWx1ZSIpKTsKKyAgICAgICAgICAgIFJ1YnlEZXNjcmlwdG9yIHJ1YnlEZXNjcmlwdG9yID0gKFJ1YnlEZXNjcmlwdG9yKSBydWJ5RmllbGREZXNjcmlwdG9yLmdldFN1YlR5cGUoY29udGV4dCk7CisgICAgICAgICAgICByZXR1cm4gKFJ1YnlNYXApIGNNYXAubmV3SW5zdGFuY2UoY29udGV4dCwga2V5VHlwZSwgdmFsdWVUeXBlLAorICAgICAgICAgICAgICAgICAgICBydWJ5RGVzY3JpcHRvci5tc2djbGFzcyhjb250ZXh0KSwgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gKFJ1YnlNYXApIGNNYXAubmV3SW5zdGFuY2UoY29udGV4dCwga2V5VHlwZSwgdmFsdWVUeXBlLCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGdldE9uZW9mQ2FzZShEZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKKyAgICAgICAgaWYgKG9uZW9mQ2FzZXMuY29udGFpbnNLZXkob25lb2YpKSB7CisgICAgICAgICAgICByZXR1cm4gb25lb2ZDYXNlcy5nZXQob25lb2YpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWlsZGVyLmdldE9uZW9mRmllbGREZXNjcmlwdG9yKG9uZW9mKTsKKyAgICB9CisKKyAgICBwcml2YXRlIERlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIER5bmFtaWNNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcjsKKyAgICBwcml2YXRlIFJ1YnlDbGFzcyBjUmVwZWF0ZWRGaWVsZDsKKyAgICBwcml2YXRlIFJ1YnlDbGFzcyBjTWFwOworICAgIHByaXZhdGUgTWFwPERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciwgUnVieVJlcGVhdGVkRmllbGQ+IHJlcGVhdGVkRmllbGRzOworICAgIHByaXZhdGUgTWFwPERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciwgUnVieU1hcD4gbWFwczsKKyAgICBwcml2YXRlIE1hcDxEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IsIElSdWJ5T2JqZWN0PiBmaWVsZHM7CisgICAgcHJpdmF0ZSBNYXA8RGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yLCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3I+IG9uZW9mQ2FzZXM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0lOS19NQVhJTVVNX05FU1RJTkcgPSA2NDsKK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlNZXNzYWdlQnVpbGRlckNvbnRleHQuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlNZXNzYWdlQnVpbGRlckNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjE5YjgwCi0tLSAvZGV2L251bGwKKysrIGIvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieU1lc3NhZ2VCdWlsZGVyQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsMjE3IEBACisvKgorICogUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisgKiBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisgKiBtZXQ6CisgKgorICogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyAqIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyAqIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyAqIGRpc3RyaWJ1dGlvbi4KKyAqICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyAqIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisgKiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyAqICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyAqIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisgKiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisgKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5OworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yczsKK2ltcG9ydCBvcmcuanJ1YnkuKjsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieUNsYXNzOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5TWV0aG9kOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLkJpbmRpbmc7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuQmxvY2s7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuT2JqZWN0QWxsb2NhdG9yOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLlRocmVhZENvbnRleHQ7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuYnVpbHRpbi5JUnVieU9iamVjdDsKKworQEpSdWJ5Q2xhc3MobmFtZSA9ICJNZXNzYWdlQnVpbGRlckNvbnRleHQiKQorcHVibGljIGNsYXNzIFJ1YnlNZXNzYWdlQnVpbGRlckNvbnRleHQgZXh0ZW5kcyBSdWJ5T2JqZWN0IHsKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlUnVieU1lc3NhZ2VCdWlsZGVyQ29udGV4dChSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBwcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY01lc3NhZ2VCdWlsZGVyQ29udGV4dCA9IHByb3RvYnVmLmRlZmluZUNsYXNzVW5kZXIoIk1lc3NhZ2VCdWlsZGVyQ29udGV4dCIsIHJ1bnRpbWUuZ2V0T2JqZWN0KCksIG5ldyBPYmplY3RBbGxvY2F0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJUnVieU9iamVjdCBhbGxvY2F0ZShSdWJ5IHJ1bnRpbWUsIFJ1YnlDbGFzcyBrbGF6eikgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUnVieU1lc3NhZ2VCdWlsZGVyQ29udGV4dChydW50aW1lLCBrbGF6eik7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBjTWVzc2FnZUJ1aWxkZXJDb250ZXh0LmRlZmluZUFubm90YXRlZE1ldGhvZHMoUnVieU1lc3NhZ2VCdWlsZGVyQ29udGV4dC5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIFJ1YnlNZXNzYWdlQnVpbGRlckNvbnRleHQoUnVieSBydWJ5LCBSdWJ5Q2xhc3Mga2xhenopIHsKKyAgICAgICAgc3VwZXIocnVieSwga2xhenopOworICAgIH0KKworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBpbml0aWFsaXplKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgZGVzY3JpcHRvciwgSVJ1YnlPYmplY3QgcnVieUJ1aWxkZXIpIHsKKyAgICAgICAgdGhpcy5jRmllbGREZXNjcmlwdG9yID0gKFJ1YnlDbGFzcykgY29udGV4dC5ydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciIpOworICAgICAgICB0aGlzLmNEZXNjcmlwdG9yID0gKFJ1YnlDbGFzcykgY29udGV4dC5ydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkRlc2NyaXB0b3IiKTsKKyAgICAgICAgdGhpcy5jT25lb2ZEZXNjcmlwdG9yID0gKFJ1YnlDbGFzcykgY29udGV4dC5ydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvciIpOworICAgICAgICB0aGlzLmNPbmVvZkJ1aWxkZXJDb250ZXh0ID0gKFJ1YnlDbGFzcykgY29udGV4dC5ydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkludGVybmFsOjpPbmVvZkJ1aWxkZXJDb250ZXh0Iik7CisgICAgICAgIHRoaXMuZGVzY3JpcHRvciA9IChSdWJ5RGVzY3JpcHRvcikgZGVzY3JpcHRvcjsKKyAgICAgICAgdGhpcy5idWlsZGVyID0gKFJ1YnlCdWlsZGVyKSBydWJ5QnVpbGRlcjsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0Lm9wdGlvbmFsKG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZV9jbGFzcyA9IG5pbCkKKyAgICAgKgorICAgICAqIERlZmluZXMgYSBuZXcgb3B0aW9uYWwgZmllbGQgb24gdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gdHlwZSwgdGFnCisgICAgICogbnVtYmVyLCBhbmQgdHlwZSBjbGFzcyAoZm9yIG1lc3NhZ2UgYW5kIGVudW0gZmllbGRzKS4gVGhlIHR5cGUgbXVzdCBiZSBhIFJ1YnkKKyAgICAgKiBzeW1ib2wgKGFzIGFjY2VwdGVkIGJ5IEZpZWxkRGVzY3JpcHRvciN0eXBlPSkgYW5kIHRoZSB0eXBlX2NsYXNzIG11c3QgYmUgYQorICAgICAqIHN0cmluZywgaWYgcHJlc2VudCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3N1Ym1zZ19uYW1lPSkuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKHJlcXVpcmVkID0gMywgb3B0aW9uYWwgPSAxKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBvcHRpb25hbChUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0W10gYXJncykgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIElSdWJ5T2JqZWN0IHR5cGVDbGFzcyA9IHJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDMpIHR5cGVDbGFzcyA9IGFyZ3NbM107CisgICAgICAgIG1zZ2RlZkFkZEZpZWxkKGNvbnRleHQsICJvcHRpb25hbCIsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIHR5cGVDbGFzcyk7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgTWVzc2FnZUJ1aWxkZXJDb250ZXh0LnJlcXVpcmVkKG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZV9jbGFzcyA9IG5pbCkKKyAgICAgKgorICAgICAqIERlZmluZXMgYSBuZXcgcmVxdWlyZWQgZmllbGQgb24gdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gdHlwZSwgdGFnCisgICAgICogbnVtYmVyLCBhbmQgdHlwZSBjbGFzcyAoZm9yIG1lc3NhZ2UgYW5kIGVudW0gZmllbGRzKS4gVGhlIHR5cGUgbXVzdCBiZSBhIFJ1YnkKKyAgICAgKiBzeW1ib2wgKGFzIGFjY2VwdGVkIGJ5IEZpZWxkRGVzY3JpcHRvciN0eXBlPSkgYW5kIHRoZSB0eXBlX2NsYXNzIG11c3QgYmUgYQorICAgICAqIHN0cmluZywgaWYgcHJlc2VudCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3N1Ym1zZ19uYW1lPSkuCisgICAgICoKKyAgICAgKiBQcm90bzMgZG9lcyBub3QgaGF2ZSByZXF1aXJlZCBmaWVsZHMsIGJ1dCB0aGlzIG1ldGhvZCBleGlzdHMgZm9yCisgICAgICogY29tcGxldGVuZXNzLiBBbnkgYXR0ZW1wdCB0byBhZGQgYSBtZXNzYWdlIHR5cGUgd2l0aCByZXF1aXJlZCBmaWVsZHMgdG8gYQorICAgICAqIHBvb2wgd2lsbCBjdXJyZW50bHkgcmVzdWx0IGluIGFuIGVycm9yLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChyZXF1aXJlZCA9IDMsIG9wdGlvbmFsID0gMSkKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgcmVxdWlyZWQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdFtdIGFyZ3MpIHsKKyAgICAgICAgSVJ1YnlPYmplY3QgdHlwZUNsYXNzID0gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAzKSB0eXBlQ2xhc3MgPSBhcmdzWzNdOworICAgICAgICBtc2dkZWZBZGRGaWVsZChjb250ZXh0LCAicmVxdWlyZWQiLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCB0eXBlQ2xhc3MpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dC5yZXBlYXRlZChuYW1lLCB0eXBlLCBudW1iZXIsIHR5cGVfY2xhc3MgPSBuaWwpCisgICAgICoKKyAgICAgKiBEZWZpbmVzIGEgbmV3IHJlcGVhdGVkIGZpZWxkIG9uIHRoaXMgbWVzc2FnZSB0eXBlIHdpdGggdGhlIGdpdmVuIHR5cGUsIHRhZworICAgICAqIG51bWJlciwgYW5kIHR5cGUgY2xhc3MgKGZvciBtZXNzYWdlIGFuZCBlbnVtIGZpZWxkcykuIFRoZSB0eXBlIG11c3QgYmUgYSBSdWJ5CisgICAgICogc3ltYm9sIChhcyBhY2NlcHRlZCBieSBGaWVsZERlc2NyaXB0b3IjdHlwZT0pIGFuZCB0aGUgdHlwZV9jbGFzcyBtdXN0IGJlIGEKKyAgICAgKiBzdHJpbmcsIGlmIHByZXNlbnQgKGFzIGFjY2VwdGVkIGJ5IEZpZWxkRGVzY3JpcHRvciNzdWJtc2dfbmFtZT0pLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChyZXF1aXJlZCA9IDMsIG9wdGlvbmFsID0gMSkKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgcmVwZWF0ZWQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdFtdIGFyZ3MpIHsKKyAgICAgICAgSVJ1YnlPYmplY3QgdHlwZUNsYXNzID0gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAzKSB0eXBlQ2xhc3MgPSBhcmdzWzNdOworICAgICAgICBtc2dkZWZBZGRGaWVsZChjb250ZXh0LCAicmVwZWF0ZWQiLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCB0eXBlQ2xhc3MpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE1lc3NhZ2VCdWlsZGVyQ29udGV4dC5tYXAobmFtZSwga2V5X3R5cGUsIHZhbHVlX3R5cGUsIG51bWJlciwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV90eXBlX2NsYXNzID0gbmlsKQorICAgICAqCisgICAgICogRGVmaW5lcyBhIG5ldyBtYXAgZmllbGQgb24gdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4ga2V5IGFuZCB2YWx1ZQorICAgICAqIHR5cGVzLCB0YWcgbnVtYmVyLCBhbmQgdHlwZSBjbGFzcyAoZm9yIG1lc3NhZ2UgYW5kIGVudW0gdmFsdWUgdHlwZXMpLiBUaGUga2V5CisgICAgICogdHlwZSBtdXN0IGJlIDppbnQzMi86dWludDMyLzppbnQ2NC86dWludDY0LCA6Ym9vbCwgb3IgOnN0cmluZy4gVGhlIHZhbHVlIHR5cGUKKyAgICAgKiB0eXBlIG11c3QgYmUgYSBSdWJ5IHN5bWJvbCAoYXMgYWNjZXB0ZWQgYnkgRmllbGREZXNjcmlwdG9yI3R5cGU9KSBhbmQgdGhlCisgICAgICogdHlwZV9jbGFzcyBtdXN0IGJlIGEgc3RyaW5nLCBpZiBwcmVzZW50IChhcyBhY2NlcHRlZCBieQorICAgICAqIEZpZWxkRGVzY3JpcHRvciNzdWJtc2dfbmFtZT0pLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChyZXF1aXJlZCA9IDQsIG9wdGlvbmFsID0gMSkKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgbWFwKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIFJ1YnkgcnVudGltZSA9IGNvbnRleHQucnVudGltZTsKKyAgICAgICAgSVJ1YnlPYmplY3QgbmFtZSA9IGFyZ3NbMF07CisgICAgICAgIElSdWJ5T2JqZWN0IGtleVR5cGUgPSBhcmdzWzFdOworICAgICAgICBJUnVieU9iamVjdCB2YWx1ZVR5cGUgPSBhcmdzWzJdOworICAgICAgICBJUnVieU9iamVjdCBudW1iZXIgPSBhcmdzWzNdOworICAgICAgICBJUnVieU9iamVjdCB0eXBlQ2xhc3MgPSBhcmdzLmxlbmd0aCA+IDQgPyBhcmdzWzRdIDogY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworCisgICAgICAgIC8vIFZhbGlkYXRlIHRoZSBrZXkgdHlwZS4gV2UgY2FuJ3QgYWNjZXB0IGVudW1zLCBtZXNzYWdlcywgb3IgZmxvYXRzL2RvdWJsZXMKKyAgICAgICAgLy8gYXMgbWFwIGtleXMuIChXZSBleGNsdWRlIHRoZXNlIGV4cGxpY2l0bHksIGFuZCB0aGUgZmllbGQtZGVzY3JpcHRvciBzZXR0ZXIKKyAgICAgICAgLy8gYmVsb3cgdGhlbiBlbnN1cmVzIHRoYXQgdGhlIHR5cGUgaXMgb25lIG9mIHRoZSByZW1haW5pbmcgdmFsaWQgb3B0aW9ucy4pCisgICAgICAgIGlmIChrZXlUeXBlLmVxdWFscyhSdWJ5U3ltYm9sLm5ld1N5bWJvbChydW50aW1lLCAiZmxvYXQiKSkgfHwKKyAgICAgICAgICAgICAgICBrZXlUeXBlLmVxdWFscyhSdWJ5U3ltYm9sLm5ld1N5bWJvbChydW50aW1lLCAiZG91YmxlIikpIHx8CisgICAgICAgICAgICAgICAga2V5VHlwZS5lcXVhbHMoUnVieVN5bWJvbC5uZXdTeW1ib2wocnVudGltZSwgImVudW0iKSkgfHwKKyAgICAgICAgICAgICAgICBrZXlUeXBlLmVxdWFscyhSdWJ5U3ltYm9sLm5ld1N5bWJvbChydW50aW1lLCAibWVzc2FnZSIpKSkKKyAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3QXJndW1lbnRFcnJvcigiQ2Fubm90IGFkZCBhIG1hcCBmaWVsZCB3aXRoIGEgZmxvYXQsIGRvdWJsZSwgZW51bSwgb3IgbWVzc2FnZSB0eXBlLiIpOworCisgICAgICAgIC8vIENyZWF0ZSBhIG5ldyBtZXNzYWdlIGRlc2NyaXB0b3IgZm9yIHRoZSBtYXAgZW50cnkgbWVzc2FnZSwgYW5kIGNyZWF0ZSBhCisgICAgICAgIC8vIHJlcGVhdGVkIHN1Ym1lc3NhZ2UgZmllbGQgaGVyZSB3aXRoIHRoYXQgdHlwZS4KKyAgICAgICAgUnVieURlc2NyaXB0b3IgbWFwZW50cnlEZXNjID0gKFJ1YnlEZXNjcmlwdG9yKSBjRGVzY3JpcHRvci5uZXdJbnN0YW5jZShjb250ZXh0LCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgSVJ1YnlPYmplY3QgbWFwZW50cnlEZXNjTmFtZSA9IFJ1YnlTeW1ib2wubmV3U3ltYm9sKHJ1bnRpbWUsIG5hbWUpLmlkMm5hbWUoY29udGV4dCk7CisgICAgICAgIG1hcGVudHJ5RGVzYy5zZXROYW1lKGNvbnRleHQsIG1hcGVudHJ5RGVzY05hbWUpOworICAgICAgICBtYXBlbnRyeURlc2Muc2V0TWFwRW50cnkodHJ1ZSk7CisKKyAgICAgICAgLy9vcHRpb25hbCA8dHlwZT4ga2V5ID0gMTsKKyAgICAgICAgUnVieUZpZWxkRGVzY3JpcHRvciBrZXlGaWVsZCA9IChSdWJ5RmllbGREZXNjcmlwdG9yKSBjRmllbGREZXNjcmlwdG9yLm5ld0luc3RhbmNlKGNvbnRleHQsIEJsb2NrLk5VTExfQkxPQ0spOworICAgICAgICBrZXlGaWVsZC5zZXROYW1lKGNvbnRleHQsIHJ1bnRpbWUubmV3U3RyaW5nKCJrZXkiKSk7CisgICAgICAgIGtleUZpZWxkLnNldExhYmVsKGNvbnRleHQsIFJ1YnlTeW1ib2wubmV3U3ltYm9sKHJ1bnRpbWUsICJvcHRpb25hbCIpKTsKKyAgICAgICAga2V5RmllbGQuc2V0TnVtYmVyKGNvbnRleHQsIHJ1bnRpbWUubmV3Rml4bnVtKDEpKTsKKyAgICAgICAga2V5RmllbGQuc2V0VHlwZShjb250ZXh0LCBrZXlUeXBlKTsKKyAgICAgICAgbWFwZW50cnlEZXNjLmFkZEZpZWxkKGNvbnRleHQsIGtleUZpZWxkKTsKKworICAgICAgICAvL29wdGlvbmFsIDx0eXBlPiB2YWx1ZSA9IDI7CisgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IgdmFsdWVGaWVsZCA9IChSdWJ5RmllbGREZXNjcmlwdG9yKSBjRmllbGREZXNjcmlwdG9yLm5ld0luc3RhbmNlKGNvbnRleHQsIEJsb2NrLk5VTExfQkxPQ0spOworICAgICAgICB2YWx1ZUZpZWxkLnNldE5hbWUoY29udGV4dCwgcnVudGltZS5uZXdTdHJpbmcoInZhbHVlIikpOworICAgICAgICB2YWx1ZUZpZWxkLnNldExhYmVsKGNvbnRleHQsIFJ1YnlTeW1ib2wubmV3U3ltYm9sKHJ1bnRpbWUsICJvcHRpb25hbCIpKTsKKyAgICAgICAgdmFsdWVGaWVsZC5zZXROdW1iZXIoY29udGV4dCwgcnVudGltZS5uZXdGaXhudW0oMikpOworICAgICAgICB2YWx1ZUZpZWxkLnNldFR5cGUoY29udGV4dCwgdmFsdWVUeXBlKTsKKyAgICAgICAgaWYgKCEgdHlwZUNsYXNzLmlzTmlsKCkpIHZhbHVlRmllbGQuc2V0U3VibXNnTmFtZShjb250ZXh0LCB0eXBlQ2xhc3MpOworICAgICAgICBtYXBlbnRyeURlc2MuYWRkRmllbGQoY29udGV4dCwgdmFsdWVGaWVsZCk7CisKKyAgICAgICAgLy8gQWRkIHRoZSBtYXAtZW50cnkgbWVzc2FnZSB0eXBlIHRvIHRoZSBjdXJyZW50IGJ1aWxkZXIsIGFuZCB1c2UgdGhlIHR5cGUgdG8KKyAgICAgICAgLy8gY3JlYXRlIHRoZSBtYXAgZmllbGQgaXRzZWxmLgorICAgICAgICB0aGlzLmJ1aWxkZXIucGVuZGluZ0xpc3QuYWRkKG1hcGVudHJ5RGVzYyk7CisKKyAgICAgICAgbXNnZGVmQWRkRmllbGQoY29udGV4dCwgInJlcGVhdGVkIiwgbmFtZSwgcnVudGltZS5uZXdTeW1ib2woIm1lc3NhZ2UiKSwgbnVtYmVyLCBtYXBlbnRyeURlc2NOYW1lKTsKKyAgICAgICAgcmV0dXJuIHJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IG9uZW9mKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgbmFtZSwgQmxvY2sgYmxvY2spIHsKKyAgICAgICAgUnVieU9uZW9mRGVzY3JpcHRvciBvbmVvZmRlZiA9IChSdWJ5T25lb2ZEZXNjcmlwdG9yKQorICAgICAgICAgICAgICAgIGNPbmVvZkRlc2NyaXB0b3IubmV3SW5zdGFuY2UoY29udGV4dCwgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgIFJ1YnlPbmVvZkJ1aWxkZXJDb250ZXh0IGN0eCA9IChSdWJ5T25lb2ZCdWlsZGVyQ29udGV4dCkKKyAgICAgICAgICAgICAgICBjT25lb2ZCdWlsZGVyQ29udGV4dC5uZXdJbnN0YW5jZShjb250ZXh0LCBvbmVvZmRlZiwgQmxvY2suTlVMTF9CTE9DSyk7CisgICAgICAgIG9uZW9mZGVmLnNldE5hbWUoY29udGV4dCwgbmFtZSk7CisgICAgICAgIEJpbmRpbmcgYmluZGluZyA9IGJsb2NrLmdldEJpbmRpbmcoKTsKKyAgICAgICAgYmluZGluZy5zZXRTZWxmKGN0eCk7CisgICAgICAgIGJsb2NrLnlpZWxkU3BlY2lmaWMoY29udGV4dCk7CisgICAgICAgIGRlc2NyaXB0b3IuYWRkT25lb2YoY29udGV4dCwgb25lb2ZkZWYpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBtc2dkZWZBZGRGaWVsZChUaHJlYWRDb250ZXh0IGNvbnRleHQsIFN0cmluZyBsYWJlbCwgSVJ1YnlPYmplY3QgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVJ1YnlPYmplY3QgdHlwZSwgSVJ1YnlPYmplY3QgbnVtYmVyLCBJUnVieU9iamVjdCB0eXBlQ2xhc3MpIHsKKyAgICAgICAgZGVzY3JpcHRvci5hZGRGaWVsZChjb250ZXh0LAorICAgICAgICAgICAgICAgIFV0aWxzLm1zZ2RlZkNyZWF0ZUZpZWxkKGNvbnRleHQsIGxhYmVsLCBuYW1lLCB0eXBlLCBudW1iZXIsIHR5cGVDbGFzcywgY0ZpZWxkRGVzY3JpcHRvcikpOworICAgIH0KKworICAgIHByaXZhdGUgUnVieURlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIFJ1YnlCdWlsZGVyIGJ1aWxkZXI7CisgICAgcHJpdmF0ZSBSdWJ5Q2xhc3MgY0ZpZWxkRGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIFJ1YnlDbGFzcyBjT25lb2ZEZXNjcmlwdG9yOworICAgIHByaXZhdGUgUnVieUNsYXNzIGNPbmVvZkJ1aWxkZXJDb250ZXh0OworICAgIHByaXZhdGUgUnVieUNsYXNzIGNEZXNjcmlwdG9yOworfQpkaWZmIC0tZ2l0IGEvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieU9uZW9mQnVpbGRlckNvbnRleHQuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlPbmVvZkJ1aWxkZXJDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzliOTllMAotLS0gL2Rldi9udWxsCisrKyBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlPbmVvZkJ1aWxkZXJDb250ZXh0LmphdmEKQEAgLTAsMCArMSw4NCBAQAorLyoKKyAqIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorICogQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorICogbWV0OgorICoKKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisgKiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisgKiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisgKiBkaXN0cmlidXRpb24uCisgKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisgKiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorICogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorICovCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieTsKKworaW1wb3J0IG9yZy5qcnVieS5SdWJ5OworaW1wb3J0IG9yZy5qcnVieS5SdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlNb2R1bGU7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlPYmplY3Q7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlDbGFzczsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieU1ldGhvZDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5PYmplY3RBbGxvY2F0b3I7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuVGhyZWFkQ29udGV4dDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworCitASlJ1YnlDbGFzcyhuYW1lID0gIk9uZW9mQnVpbGRlckNvbnRleHQiKQorcHVibGljIGNsYXNzIFJ1YnlPbmVvZkJ1aWxkZXJDb250ZXh0IGV4dGVuZHMgUnVieU9iamVjdCB7CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNyZWF0ZVJ1YnlPbmVvZkJ1aWxkZXJDb250ZXh0KFJ1YnkgcnVudGltZSkgeworICAgICAgICBSdWJ5TW9kdWxlIHByb3RvYnVmID0gcnVudGltZS5nZXRDbGFzc0Zyb21QYXRoKCJHb29nbGU6OlByb3RvYnVmIik7CisgICAgICAgIFJ1YnlNb2R1bGUgaW50ZXJuYWwgPSBwcm90b2J1Zi5kZWZpbmVNb2R1bGVVbmRlcigiSW50ZXJuYWwiKTsKKyAgICAgICAgUnVieUNsYXNzIGNSdWJ5T25lb2ZCdWlkbGVyQ29udGV4dCA9IGludGVybmFsLmRlZmluZUNsYXNzVW5kZXIoIk9uZW9mQnVpbGRlckNvbnRleHQiLCBydW50aW1lLmdldE9iamVjdCgpLCBuZXcgT2JqZWN0QWxsb2NhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgSVJ1YnlPYmplY3QgYWxsb2NhdGUoUnVieSBydWJ5LCBSdWJ5Q2xhc3MgcnVieUNsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSdWJ5T25lb2ZCdWlsZGVyQ29udGV4dChydWJ5LCBydWJ5Q2xhc3MpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgY1J1YnlPbmVvZkJ1aWRsZXJDb250ZXh0LmRlZmluZUFubm90YXRlZE1ldGhvZHMoUnVieU9uZW9mQnVpbGRlckNvbnRleHQuY2xhc3MpOworICAgIH0KKworICAgIHB1YmxpYyBSdWJ5T25lb2ZCdWlsZGVyQ29udGV4dChSdWJ5IHJ1YnksIFJ1YnlDbGFzcyBydWJ5Q2xhc3MpIHsKKyAgICAgICAgc3VwZXIocnVieSwgcnVieUNsYXNzKTsKKyAgICB9CisKKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5pdGlhbGl6ZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG9uZW9mZGVmKSB7CisgICAgICAgIHRoaXMuZGVzY3JpcHRvciA9IChSdWJ5T25lb2ZEZXNjcmlwdG9yKSBvbmVvZmRlZjsKKyAgICAgICAgdGhpcy5jRmllbGREZXNjcmlwdG9yID0gKFJ1YnlDbGFzcykgY29udGV4dC5ydW50aW1lLmdldENsYXNzRnJvbVBhdGgoIkdvb2dsZTo6UHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBASlJ1YnlNZXRob2QocmVxdWlyZWQgPSAzLCBvcHRpb25hbCA9IDEpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IG9wdGlvbmFsKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIElSdWJ5T2JqZWN0IG5hbWUgPSBhcmdzWzBdOworICAgICAgICBJUnVieU9iamVjdCB0eXBlID0gYXJnc1sxXTsKKyAgICAgICAgSVJ1YnlPYmplY3QgbnVtYmVyID0gYXJnc1syXTsKKyAgICAgICAgSVJ1YnlPYmplY3QgdHlwZUNsYXNzID0gYXJncy5sZW5ndGggPiAzID8gYXJnc1szXSA6IGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICAgICAgUnVieUZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IgPSBVdGlscy5tc2dkZWZDcmVhdGVGaWVsZChjb250ZXh0LCAib3B0aW9uYWwiLAorICAgICAgICAgICAgICAgIG5hbWUsIHR5cGUsIG51bWJlciwgdHlwZUNsYXNzLCBjRmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgZGVzY3JpcHRvci5hZGRGaWVsZChjb250ZXh0LCBmaWVsZERlc2NyaXB0b3IpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwcml2YXRlIFJ1YnlPbmVvZkRlc2NyaXB0b3IgZGVzY3JpcHRvcjsKKyAgICBwcml2YXRlIFJ1YnlDbGFzcyBjRmllbGREZXNjcmlwdG9yOworfQpkaWZmIC0tZ2l0IGEvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieU9uZW9mRGVzY3JpcHRvci5qYXZhIGIvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieU9uZW9mRGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjNGFiNjYKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5T25lb2ZEZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSwxMjQgQEAKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieTsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzOworaW1wb3J0IG9yZy5qcnVieS5SdWJ5OworaW1wb3J0IG9yZy5qcnVieS5SdWJ5Q2xhc3M7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlNb2R1bGU7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlPYmplY3Q7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlDbGFzczsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieU1ldGhvZDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5CbG9jazsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5PYmplY3RBbGxvY2F0b3I7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuVGhyZWFkQ29udGV4dDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworCitpbXBvcnQgamF2YS51dGlsLio7CisKK0BKUnVieUNsYXNzKG5hbWUgPSAiT25lb2ZEZXNjcmlwdG9yIiwgaW5jbHVkZSA9ICJFbnVtZXJhYmxlIikKK3B1YmxpYyBjbGFzcyBSdWJ5T25lb2ZEZXNjcmlwdG9yIGV4dGVuZHMgUnVieU9iamVjdCB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlUnVieU9uZW9mRGVzY3JpcHRvcihSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBwcm90b2J1ZiA9IHJ1bnRpbWUuZ2V0Q2xhc3NGcm9tUGF0aCgiR29vZ2xlOjpQcm90b2J1ZiIpOworICAgICAgICBSdWJ5Q2xhc3MgY1J1YnlPbmVvZkRlc2NyaXB0b3IgPSBwcm90b2J1Zi5kZWZpbmVDbGFzc1VuZGVyKCJPbmVvZkRlc2NyaXB0b3IiLCBydW50aW1lLmdldE9iamVjdCgpLCBuZXcgT2JqZWN0QWxsb2NhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgSVJ1YnlPYmplY3QgYWxsb2NhdGUoUnVieSBydWJ5LCBSdWJ5Q2xhc3MgcnVieUNsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSdWJ5T25lb2ZEZXNjcmlwdG9yKHJ1YnksIHJ1YnlDbGFzcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBjUnVieU9uZW9mRGVzY3JpcHRvci5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlPbmVvZkRlc2NyaXB0b3IuY2xhc3MpOworICAgICAgICBjUnVieU9uZW9mRGVzY3JpcHRvci5pbmNsdWRlTW9kdWxlKHJ1bnRpbWUuZ2V0RW51bWVyYWJsZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVieU9uZW9mRGVzY3JpcHRvcihSdWJ5IHJ1YnksIFJ1YnlDbGFzcyBydWJ5Q2xhc3MpIHsKKyAgICAgICAgc3VwZXIocnVieSwgcnVieUNsYXNzKTsKKyAgICB9CisKKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5pdGlhbGl6ZShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgYnVpbGRlciA9IERlc2NyaXB0b3JQcm90b3MuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmV3QnVpbGRlcigpOworICAgICAgICBmaWVsZHMgPSBuZXcgQXJyYXlMaXN0PFJ1YnlGaWVsZERlc2NyaXB0b3I+KCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIE9uZW9mRGVzY3JpcHRvci5uYW1lID0+IG5hbWUKKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBvbmVvZi4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJuYW1lIikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgZ2V0TmFtZShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgT25lb2ZEZXNjcmlwdG9yLm5hbWUgPSBuYW1lCisgICAgICoKKyAgICAgKiBTZXRzIGEgbmV3IG5hbWUgZm9yIHRoaXMgb25lb2YuIFRoZSBvbmVvZiBtdXN0IG5vdCBoYXZlIGJlZW4gYWRkZWQgdG8gYQorICAgICAqIG1lc3NhZ2UgZGVzY3JpcHRvciB5ZXQuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAibmFtZT0iKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBzZXROYW1lKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgbmFtZSkgeworICAgICAgICB0aGlzLm5hbWUgPSBjb250ZXh0LnJ1bnRpbWUubmV3U3RyaW5nKG5hbWUuYXNKYXZhU3RyaW5nKCkpOworICAgICAgICB0aGlzLmJ1aWxkZXIuc2V0TmFtZShuYW1lLmFzSmF2YVN0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBPbmVvZkRlc2NyaXB0b3IuYWRkX2ZpZWxkKGZpZWxkKSA9PiBuaWwKKyAgICAgKgorICAgICAqIEFkZHMgYSBmaWVsZCB0byB0aGlzIG9uZW9mLiBUaGUgZmllbGQgbWF5IGhhdmUgYmVlbiBhZGRlZCB0byB0aGlzIG9uZW9mIGluCisgICAgICogdGhlIHBhc3QsIG9yIHRoZSBtZXNzYWdlIHRvIHdoaWNoIHRoaXMgb25lb2YgYmVsb25ncyAoaWYgYW55KSwgYnV0IG1heSBub3QKKyAgICAgKiBoYXZlIGFscmVhZHkgYmVlbiBhZGRlZCB0byBhbnkgb3RoZXIgb25lb2Ygb3IgbWVzc2FnZS4gT3RoZXJ3aXNlLCBhbgorICAgICAqIGV4Y2VwdGlvbiBpcyByYWlzZWQuCisgICAgICoKKyAgICAgKiBBbGwgZmllbGRzIGFkZGVkIHRvIHRoZSBvbmVvZiB2aWEgdGhpcyBtZXRob2Qgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGFkZGVkIHRvCisgICAgICogdGhlIG1lc3NhZ2UgdG8gd2hpY2ggdGhpcyBvbmVvZiBiZWxvbmdzLCBpZiBpdCBiZWxvbmdzIHRvIG9uZSBjdXJyZW50bHksIG9yCisgICAgICogZWxzZSB3aWxsIGJlIGFkZGVkIHRvIGFueSBtZXNzYWdlIHRvIHdoaWNoIHRoZSBvbmVvZiBpcyBsYXRlciBhZGRlZCBhdCB0aGUKKyAgICAgKiB0aW1lIHRoYXQgaXQgaXMgYWRkZWQuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiYWRkX2ZpZWxkIikKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgYWRkRmllbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBvYmopIHsKKyAgICAgICAgUnVieUZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IgPSAoUnVieUZpZWxkRGVzY3JpcHRvcikgb2JqOworICAgICAgICBmaWVsZERlc2NyaXB0b3Iuc2V0T25lb2ZOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIGZpZWxkcy5hZGQoZmllbGREZXNjcmlwdG9yKTsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5nZXROaWwoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBPbmVvZkRlc2NyaXB0b3IuZWFjaCgmYmxvY2spID0+IG5pbAorICAgICAqCisgICAgICogSXRlcmF0ZXMgdGhyb3VnaCBmaWVsZHMgaW4gdGhpcyBvbmVvZiwgeWllbGRpbmcgdG8gdGhlIGJsb2NrIG9uIGVhY2ggb25lLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBlYWNoKFRocmVhZENvbnRleHQgY29udGV4dCwgQmxvY2sgYmxvY2spIHsKKyAgICAgICAgZm9yIChSdWJ5RmllbGREZXNjcmlwdG9yIGZpZWxkIDogZmllbGRzKSB7CisgICAgICAgICAgICBibG9jay55aWVsZFNwZWNpZmljKGNvbnRleHQsIGZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIHB1YmxpYyBEZXNjcmlwdG9yUHJvdG9zLk9uZW9mRGVzY3JpcHRvclByb3RvIGJ1aWxkKGludCBpbmRleCkgeworICAgICAgICBmb3IgKFJ1YnlGaWVsZERlc2NyaXB0b3IgZmllbGQ6IGZpZWxkcykgeworICAgICAgICAgICAgZmllbGQuc2V0T25lb2ZJbmRleChpbmRleCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRlci5idWlsZCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCBDb2xsZWN0aW9uPFJ1YnlGaWVsZERlc2NyaXB0b3I+IGdldEZpZWxkcygpIHsKKyAgICAgICAgcmV0dXJuIGZpZWxkczsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIGdldE9uZW9mRGVzY3JpcHRvcigpIHsKKyAgICAgICAgUnVieUZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IgPSBmaWVsZHMuZ2V0KDApOworICAgICAgICByZXR1cm4gZmllbGREZXNjcmlwdG9yLmdldEZpZWxkRGVmKCkuZ2V0Q29udGFpbmluZ09uZW9mKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBJUnVieU9iamVjdCBuYW1lOworICAgIHByaXZhdGUgRGVzY3JpcHRvclByb3Rvcy5PbmVvZkRlc2NyaXB0b3JQcm90by5CdWlsZGVyIGJ1aWxkZXI7CisgICAgcHJpdmF0ZSBMaXN0PFJ1YnlGaWVsZERlc2NyaXB0b3I+IGZpZWxkczsKK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlQcm90b2J1Zi5qYXZhIGIvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvUnVieVByb3RvYnVmLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2IzZmNkNAotLS0gL2Rldi9udWxsCisrKyBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlQcm90b2J1Zi5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisvKgorICogUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisgKiBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisgKiBtZXQ6CisgKgorICogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyAqIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyAqIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyAqIGRpc3RyaWJ1dGlvbi4KKyAqICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyAqIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisgKiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyAqICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyAqIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisgKiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisgKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5OworCitpbXBvcnQgb3JnLmpydWJ5LlJ1Ynk7CitpbXBvcnQgb3JnLmpydWJ5LlJ1YnlNb2R1bGU7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlNZXRob2Q7CitpbXBvcnQgb3JnLmpydWJ5LmFubm8uSlJ1YnlNb2R1bGU7CitpbXBvcnQgb3JnLmpydWJ5LnJ1bnRpbWUuVGhyZWFkQ29udGV4dDsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5idWlsdGluLklSdWJ5T2JqZWN0OworCitASlJ1YnlNb2R1bGUobmFtZSA9ICJQcm90b2J1ZiIpCitwdWJsaWMgY2xhc3MgUnVieVByb3RvYnVmIHsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjcmVhdGVQcm90b2J1ZihSdWJ5IHJ1bnRpbWUpIHsKKyAgICAgICAgUnVieU1vZHVsZSBtR29vZ2xlID0gcnVudGltZS5nZXRNb2R1bGUoIkdvb2dsZSIpOworICAgICAgICBSdWJ5TW9kdWxlIG1Qcm90b2J1ZiA9IG1Hb29nbGUuZGVmaW5lTW9kdWxlVW5kZXIoIlByb3RvYnVmIik7CisgICAgICAgIG1Qcm90b2J1Zi5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlQcm90b2J1Zi5jbGFzcyk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgR29vZ2xlOjpQcm90b2J1Zi5lbmNvZGUobXNnKSA9PiBieXRlcworICAgICAqCisgICAgICogRW5jb2RlcyB0aGUgZ2l2ZW4gbWVzc2FnZSBvYmplY3QgdG8gcHJvdG9jb2wgYnVmZmVycyB3aXJlIGZvcm1hdC4gVGhpcyBpcyBhbgorICAgICAqIGFsdGVybmF0aXZlIHRvIHRoZSAjZW5jb2RlIG1ldGhvZCBvbiBtc2cncyBjbGFzcy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobWV0YSA9IHRydWUpCisgICAgcHVibGljIHN0YXRpYyBJUnVieU9iamVjdCBlbmNvZGUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBzZWxmLCBJUnVieU9iamVjdCBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBSdWJ5TWVzc2FnZS5lbmNvZGUoY29udGV4dCwgbWVzc2FnZS5nZXRNZXRhQ2xhc3MoKSwgbWVzc2FnZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgR29vZ2xlOjpQcm90b2J1Zi5kZWNvZGUoY2xhc3MsIGJ5dGVzKSA9PiBtc2cKKyAgICAgKgorICAgICAqIERlY29kZXMgdGhlIGdpdmVuIGJ5dGVzIGFzIHByb3RvY29sIGJ1ZmZlcnMgd2lyZSBmb3JtYXQgdW5kZXIgdGhlCisgICAgICogaW50ZXJwcmV0YXRpb24gZ2l2ZW4gYnkgdGhlIGdpdmVuIGNsYXNzJ3MgbWVzc2FnZSBkZWZpbml0aW9uLiBUaGlzIGlzIGFuCisgICAgICogYWx0ZXJuYXRpdmUgdG8gdGhlICNkZWNvZGUgbWV0aG9kIG9uIHRoZSBnaXZlbiBjbGFzcy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobWV0YSA9IHRydWUpCisgICAgcHVibGljIHN0YXRpYyBJUnVieU9iamVjdCBkZWNvZGUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBzZWxmLCBJUnVieU9iamVjdCBrbGF6eiwgSVJ1YnlPYmplY3QgbWVzc2FnZSkgeworICAgICAgICByZXR1cm4gUnVieU1lc3NhZ2UuZGVjb2RlKGNvbnRleHQsIGtsYXp6LCBtZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBHb29nbGU6OlByb3RvYnVmLmVuY29kZV9qc29uKG1zZykgPT4ganNvbl9zdHJpbmcKKyAgICAgKgorICAgICAqIEVuY29kZXMgdGhlIGdpdmVuIG1lc3NhZ2Ugb2JqZWN0IHRvIGl0cyBKU09OIHJlcHJlc2VudGF0aW9uLiBUaGlzIGlzIGFuCisgICAgICogYWx0ZXJuYXRpdmUgdG8gdGhlICNlbmNvZGVfanNvbiBtZXRob2Qgb24gbXNnJ3MgY2xhc3MuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiZW5jb2RlX2pzb24iLCBtZXRhID0gdHJ1ZSkKKyAgICBwdWJsaWMgc3RhdGljIElSdWJ5T2JqZWN0IGVuY29kZUpzb24oVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBzZWxmLCBJUnVieU9iamVjdCBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBSdWJ5TWVzc2FnZS5lbmNvZGVKc29uKGNvbnRleHQsIG1lc3NhZ2UuZ2V0TWV0YUNsYXNzKCksIG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIEdvb2dsZTo6UHJvdG9idWYuZGVjb2RlX2pzb24oY2xhc3MsIGpzb25fc3RyaW5nKSA9PiBtc2cKKyAgICAgKgorICAgICAqIERlY29kZXMgdGhlIGdpdmVuIEpTT04gc3RyaW5nIHVuZGVyIHRoZSBpbnRlcnByZXRhdGlvbiBnaXZlbiBieSB0aGUgZ2l2ZW4KKyAgICAgKiBjbGFzcydzIG1lc3NhZ2UgZGVmaW5pdGlvbi4gVGhpcyBpcyBhbiBhbHRlcm5hdGl2ZSB0byB0aGUgI2RlY29kZV9qc29uIG1ldGhvZAorICAgICAqIG9uIHRoZSBnaXZlbiBjbGFzcy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJkZWNvZGVfanNvbiIsIG1ldGEgPSB0cnVlKQorICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3QgZGVjb2RlSnNvbihUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IHNlbGYsIElSdWJ5T2JqZWN0IGtsYXp6LCBJUnVieU9iamVjdCBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBSdWJ5TWVzc2FnZS5kZWNvZGVKc29uKGNvbnRleHQsIGtsYXp6LCBtZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBHb29nbGU6OlByb3RvYnVmLmRlZXBfY29weShvYmopID0+IGNvcHlfb2Zfb2JqCisgICAgICoKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvZiBlaXRoZXIgYSBSZXBlYXRlZEZpZWxkIGluc3RhbmNlIG9yIGEgbWVzc2FnZSBvYmplY3QsCisgICAgICogcmVjdXJzaXZlbHkgY29weWluZyBpdHMgbWVtYmVycy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJkZWVwX2NvcHkiLCBtZXRhID0gdHJ1ZSkKKyAgICBwdWJsaWMgc3RhdGljIElSdWJ5T2JqZWN0IGRlZXBDb3B5KFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3Qgc2VsZiwgSVJ1YnlPYmplY3QgbWVzc2FnZSkgeworICAgICAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFJ1YnlNZXNzYWdlKSB7CisgICAgICAgICAgICByZXR1cm4gKChSdWJ5TWVzc2FnZSkgbWVzc2FnZSkuZGVlcENvcHkoY29udGV4dCk7CisgICAgICAgIH0gZWxzZSBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFJ1YnlSZXBlYXRlZEZpZWxkKSB7CisgICAgICAgICAgICByZXR1cm4gKChSdWJ5UmVwZWF0ZWRGaWVsZCkgbWVzc2FnZSkuZGVlcENvcHkoY29udGV4dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gKChSdWJ5TWFwKSBtZXNzYWdlKS5kZWVwQ29weShjb250ZXh0KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1J1YnlSZXBlYXRlZEZpZWxkLmphdmEgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5UmVwZWF0ZWRGaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3ODgzMTcKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9SdWJ5UmVwZWF0ZWRGaWVsZC5qYXZhCkBAIC0wLDAgKzEsMzkxIEBACisvKgorICogUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisgKiBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisgKiBtZXQ6CisgKgorICogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyAqIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyAqIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyAqIGRpc3RyaWJ1dGlvbi4KKyAqICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyAqIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisgKiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyAqICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyAqIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisgKiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisgKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5OworCitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yczsKK2ltcG9ydCBvcmcuanJ1YnkuKjsKK2ltcG9ydCBvcmcuanJ1YnkuYW5uby5KUnVieUNsYXNzOworaW1wb3J0IG9yZy5qcnVieS5hbm5vLkpSdWJ5TWV0aG9kOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLkJsb2NrOworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLk9iamVjdEFsbG9jYXRvcjsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5UaHJlYWRDb250ZXh0OworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLmJ1aWx0aW4uSVJ1YnlPYmplY3Q7CisKK0BKUnVieUNsYXNzKG5hbWUgPSAiUmVwZWF0ZWRDbGFzcyIsIGluY2x1ZGUgPSAiRW51bWVyYWJsZSIpCitwdWJsaWMgY2xhc3MgUnVieVJlcGVhdGVkRmllbGQgZXh0ZW5kcyBSdWJ5T2JqZWN0IHsKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlUnVieVJlcGVhdGVkRmllbGQoUnVieSBydW50aW1lKSB7CisgICAgICAgIFJ1YnlNb2R1bGUgbVByb3RvYnVmID0gcnVudGltZS5nZXRDbGFzc0Zyb21QYXRoKCJHb29nbGU6OlByb3RvYnVmIik7CisgICAgICAgIFJ1YnlDbGFzcyBjUmVwZWF0ZWRGaWVsZCA9IG1Qcm90b2J1Zi5kZWZpbmVDbGFzc1VuZGVyKCJSZXBlYXRlZEZpZWxkIiwgcnVudGltZS5nZXRPYmplY3QoKSwKKyAgICAgICAgICAgICAgICBuZXcgT2JqZWN0QWxsb2NhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIElSdWJ5T2JqZWN0IGFsbG9jYXRlKFJ1YnkgcnVudGltZSwgUnVieUNsYXNzIGtsYXp6KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJ1YnlSZXBlYXRlZEZpZWxkKHJ1bnRpbWUsIGtsYXp6KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0pOworICAgICAgICBjUmVwZWF0ZWRGaWVsZC5kZWZpbmVBbm5vdGF0ZWRNZXRob2RzKFJ1YnlSZXBlYXRlZEZpZWxkLmNsYXNzKTsKKyAgICAgICAgY1JlcGVhdGVkRmllbGQuaW5jbHVkZU1vZHVsZShydW50aW1lLmdldEVudW1lcmFibGUoKSk7CisgICAgfQorCisgICAgcHVibGljIFJ1YnlSZXBlYXRlZEZpZWxkKFJ1YnkgcnVudGltZSwgUnVieUNsYXNzIGtsYXp6KSB7CisgICAgICAgIHN1cGVyKHJ1bnRpbWUsIGtsYXp6KTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVieVJlcGVhdGVkRmllbGQoUnVieSBydW50aW1lLCBSdWJ5Q2xhc3Mga2xhenosIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIGZpZWxkVHlwZSwgSVJ1YnlPYmplY3QgdHlwZUNsYXNzKSB7CisgICAgICAgIHRoaXMocnVudGltZSwga2xhenopOworICAgICAgICB0aGlzLmZpZWxkVHlwZSA9IGZpZWxkVHlwZTsKKyAgICAgICAgdGhpcy5zdG9yYWdlID0gcnVudGltZS5uZXdBcnJheSgpOworICAgICAgICB0aGlzLnR5cGVDbGFzcyA9IHR5cGVDbGFzczsKKyAgICB9CisKKyAgICBASlJ1YnlNZXRob2QocmVxdWlyZWQgPSAxLCBvcHRpb25hbCA9IDIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluaXRpYWxpemUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdFtdIGFyZ3MpIHsKKyAgICAgICAgUnVieSBydW50aW1lID0gY29udGV4dC5ydW50aW1lOworICAgICAgICB0aGlzLnN0b3JhZ2UgPSBydW50aW1lLm5ld0FycmF5KCk7CisgICAgICAgIElSdWJ5T2JqZWN0IGFyeSA9IG51bGw7CisgICAgICAgIGlmICghKGFyZ3NbMF0gaW5zdGFuY2VvZiBSdWJ5U3ltYm9sKSkgeworICAgICAgICAgICAgdGhyb3cgcnVudGltZS5uZXdBcmd1bWVudEVycm9yKCJFeHBlY3RlZCBTeW1ib2wgZm9yIHR5cGUgbmFtZSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZmllbGRUeXBlID0gVXRpbHMucnVieVRvRmllbGRUeXBlKGFyZ3NbMF0pOworICAgICAgICBpZiAoZmllbGRUeXBlID09IERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlLk1FU1NBR0UKKyAgICAgICAgICAgICAgICB8fCBmaWVsZFR5cGUgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuRU5VTSkgeworICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMikKKyAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld0FyZ3VtZW50RXJyb3IoIkV4cGVjdGVkIGF0IGxlYXN0IDIgYXJndW1lbnRzIGZvciBtZXNzYWdlL2VudW0iKTsKKyAgICAgICAgICAgIHR5cGVDbGFzcyA9IGFyZ3NbMV07CisgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAyKQorICAgICAgICAgICAgICAgIGFyeSA9IGFyZ3NbMl07CisgICAgICAgICAgICBVdGlscy52YWxpZGF0ZVR5cGVDbGFzcyhjb250ZXh0LCBmaWVsZFR5cGUsIHR5cGVDbGFzcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAyKQorICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3QXJndW1lbnRFcnJvcigiVG9vIG1hbnkgYXJndW1lbnRzOiBleHBlY3RlZCAxIG9yIDIiKTsKKyAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDEpCisgICAgICAgICAgICAgICAgYXJ5ID0gYXJnc1sxXTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIFJ1YnlBcnJheSBhcnIgPSBhcnkuY29udmVydFRvQXJyYXkoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmFkZChhcnIuZWx0SW50ZXJuYWwoaSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIFJlcGVhdGVkRmllbGQuW109KGluZGV4LCB2YWx1ZSkKKyAgICAgKgorICAgICAqIFNldHMgdGhlIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGV4LiBPbiBvdXQtb2YtYm91bmRzIGFzc2lnbm1lbnRzLCBleHRlbmRzCisgICAgICogdGhlIGFycmF5IGFuZCBmaWxscyB0aGUgaG9sZSAoaWYgYW55KSB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gIltdPSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluZGV4U2V0KFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgaW5kZXgsIElSdWJ5T2JqZWN0IHZhbHVlKSB7CisgICAgICAgIFV0aWxzLmNoZWNrVHlwZShjb250ZXh0LCBmaWVsZFR5cGUsIHZhbHVlLCAoUnVieU1vZHVsZSkgdHlwZUNsYXNzKTsKKyAgICAgICAgdGhpcy5zdG9yYWdlLnNldChSdWJ5TnVtZXJpYy5udW0yaW50KGluZGV4KSwgdmFsdWUpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIFJlcGVhdGVkRmllbGQuW10oaW5kZXgpID0+IHZhbHVlCisgICAgICoKKyAgICAgKiBBY2Nlc3NlcyB0aGUgZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kZXguIFRocm93cyBhbiBleGNlcHRpb24gb24gb3V0LW9mLWJvdW5kcworICAgICAqIGVycm9ycy4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9ICJbXSIpCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGluZGV4KFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5lbHRJbnRlcm5hbChSdWJ5TnVtZXJpYy5udW0yaW50KGluZGV4KSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgUmVwZWF0ZWRGaWVsZC5pbnNlcnQoKmFyZ3MpCisgICAgICoKKyAgICAgKiBQdXNoZXMgZWFjaCBhcmcgaW4gdHVybiBvbnRvIHRoZSBlbmQgb2YgdGhlIHJlcGVhdGVkIGZpZWxkLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChyZXN0ID0gdHJ1ZSkKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgaW5zZXJ0KFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgVXRpbHMuY2hlY2tUeXBlKGNvbnRleHQsIGZpZWxkVHlwZSwgYXJnc1tpXSwgKFJ1YnlNb2R1bGUpIHR5cGVDbGFzcyk7CisgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuYWRkKGFyZ3NbaV0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgUmVwZWF0ZWRGaWVsZC5wdXNoKHZhbHVlKQorICAgICAqCisgICAgICogQWRkcyBhIG5ldyBlbGVtZW50IHRvIHRoZSByZXBlYXRlZCBmaWVsZC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9IHsicHVzaCIsICI8PCJ9KQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBwdXNoKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgVXRpbHMuY2hlY2tUeXBlKGNvbnRleHQsIGZpZWxkVHlwZSwgdmFsdWUsIChSdWJ5TW9kdWxlKSB0eXBlQ2xhc3MpOworICAgICAgICB0aGlzLnN0b3JhZ2UuYWRkKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgUmVwZWF0ZWRGaWVsZC5wb3AgPT4gdmFsdWUKKyAgICAgKgorICAgICAqIFJlbW92ZXMgdGhlIGxhc3QgZWxlbWVudCBhbmQgcmV0dXJucyBpdC4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgcmVwZWF0ZWQKKyAgICAgKiBmaWVsZCBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgcG9wKFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBJUnVieU9iamVjdCByZXQgPSB0aGlzLnN0b3JhZ2UubGFzdCgpOworICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKHJldCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgUmVwZWF0ZWRGaWVsZC5yZXBsYWNlKGxpc3QpCisgICAgICoKKyAgICAgKiBSZXBsYWNlcyB0aGUgY29udGVudHMgb2YgdGhlIHJlcGVhdGVkIGZpZWxkIHdpdGggdGhlIGdpdmVuIGxpc3Qgb2YgZWxlbWVudHMuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IHJlcGxhY2UoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBJUnVieU9iamVjdCBsaXN0KSB7CisgICAgICAgIFJ1YnlBcnJheSBhcnIgPSAoUnVieUFycmF5KSBsaXN0OworICAgICAgICBjaGVja0FycmF5RWxlbWVudFR5cGUoY29udGV4dCwgYXJyKTsKKyAgICAgICAgdGhpcy5zdG9yYWdlID0gYXJyOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIFJlcGVhdGVkRmllbGQuY2xlYXIKKyAgICAgKgorICAgICAqIENsZWFycyAocmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSkgdGhpcyByZXBlYXRlZCBmaWVsZC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QKKyAgICBwdWJsaWMgSVJ1YnlPYmplY3QgY2xlYXIoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIHRoaXMuc3RvcmFnZS5jbGVhcigpOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIFJlcGVhdGVkRmllbGQubGVuZ3RoCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyByZXBlYXRlZCBmaWVsZC4KKyAgICAgKi8KKyAgICBASlJ1YnlNZXRob2QobmFtZSA9IHsiY291bnQiLCAibGVuZ3RoIn0pCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGxlbmd0aChUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQucnVudGltZS5uZXdGaXhudW0odGhpcy5zdG9yYWdlLnNpemUoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBjYWxsLXNlcToKKyAgICAgKiAgICAgUmVwZWF0ZWRGaWVsZC4rKG90aGVyKSA9PiByZXBlYXRlZCBmaWVsZAorICAgICAqCisgICAgICogUmV0dXJucyBhIG5ldyByZXBlYXRlZCBmaWVsZCB0aGF0IGNvbnRhaW5zIHRoZSBjb25jYXRlbmF0ZWQgbGlzdCBvZiB0aGlzCisgICAgICogcmVwZWF0ZWQgZmllbGQncyBlbGVtZW50cyBhbmQgb3RoZXIncyBlbGVtZW50cy4gVGhlIG90aGVyIChzZWNvbmQpIGxpc3QgbWF5CisgICAgICogYmUgZWl0aGVyIGFub3RoZXIgcmVwZWF0ZWQgZmllbGQgb3IgYSBSdWJ5IGFycmF5LgorICAgICAqLworICAgIEBKUnVieU1ldGhvZChuYW1lID0gIisiKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBwbHVzKFRocmVhZENvbnRleHQgY29udGV4dCwgSVJ1YnlPYmplY3QgbGlzdCkgeworICAgICAgICBSdWJ5UmVwZWF0ZWRGaWVsZCBkdXAgPSAoUnVieVJlcGVhdGVkRmllbGQpIGR1cChjb250ZXh0KTsKKyAgICAgICAgaWYgKGxpc3QgaW5zdGFuY2VvZiBSdWJ5QXJyYXkpIHsKKyAgICAgICAgICAgIGNoZWNrQXJyYXlFbGVtZW50VHlwZShjb250ZXh0LCAoUnVieUFycmF5KSBsaXN0KTsKKyAgICAgICAgICAgIGR1cC5zdG9yYWdlLmFkZEFsbCgoUnVieUFycmF5KSBsaXN0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFJ1YnlSZXBlYXRlZEZpZWxkIHJlcGVhdGVkRmllbGQgPSAoUnVieVJlcGVhdGVkRmllbGQpIGxpc3Q7CisgICAgICAgICAgICBpZiAoISBmaWVsZFR5cGUuZXF1YWxzKHJlcGVhdGVkRmllbGQuZmllbGRUeXBlKSB8fCAodHlwZUNsYXNzICE9IG51bGwgJiYgIQorICAgICAgICAgICAgICAgICAgICB0eXBlQ2xhc3MuZXF1YWxzKHJlcGVhdGVkRmllbGQudHlwZUNsYXNzKSkpCisgICAgICAgICAgICAgICAgdGhyb3cgY29udGV4dC5ydW50aW1lLm5ld0FyZ3VtZW50RXJyb3IoIkF0dGVtcHQgdG8gYXBwZW5kIFJlcGVhdGVkRmllbGQgd2l0aCBkaWZmZXJlbnQgZWxlbWVudCB0eXBlLiIpOworICAgICAgICAgICAgZHVwLnN0b3JhZ2UuYWRkQWxsKChSdWJ5QXJyYXkpIHJlcGVhdGVkRmllbGQudG9BcnJheShjb250ZXh0KSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGR1cDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBSZXBlYXRlZEZpZWxkLmhhc2ggPT4gaGFzaF92YWx1ZQorICAgICAqCisgICAgICogUmV0dXJucyBhIGhhc2ggdmFsdWUgY29tcHV0ZWQgZnJvbSB0aGlzIHJlcGVhdGVkIGZpZWxkJ3MgZWxlbWVudHMuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kCisgICAgcHVibGljIElSdWJ5T2JqZWN0IGhhc2goVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIGludCBoYXNoQ29kZSA9IFN5c3RlbS5pZGVudGl0eUhhc2hDb2RlKHRoaXMuc3RvcmFnZSk7CisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUubmV3Rml4bnVtKGhhc2hDb2RlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBSZXBlYXRlZEZpZWxkLj09KG90aGVyKSA9PiBib29sZWFuCisgICAgICoKKyAgICAgKiBDb21wYXJlcyB0aGlzIHJlcGVhdGVkIGZpZWxkIHRvIGFub3RoZXIuIFJlcGVhdGVkIGZpZWxkcyBhcmUgZXF1YWwgaWYgdGhlaXIKKyAgICAgKiBlbGVtZW50IHR5cGVzIGFyZSBlcXVhbCwgdGhlaXIgbGVuZ3RocyBhcmUgZXF1YWwsIGFuZCBlYWNoIGVsZW1lbnQgaXMgZXF1YWwuCisgICAgICogRWxlbWVudHMgYXJlIGNvbXBhcmVkIGFzIHBlciBub3JtYWwgUnVieSBzZW1hbnRpY3MsIGJ5IGNhbGxpbmcgdGhlaXIgOj09CisgICAgICogbWV0aG9kcyAob3IgcGVyZm9ybWluZyBhIG1vcmUgZWZmaWNpZW50IGNvbXBhcmlzb24gZm9yIHByaW1pdGl2ZSB0eXBlcykuCisgICAgICovCisgICAgQEpSdWJ5TWV0aG9kKG5hbWUgPSAiPT0iKQorICAgIHB1YmxpYyBJUnVieU9iamVjdCBlcShUaHJlYWRDb250ZXh0IGNvbnRleHQsIElSdWJ5T2JqZWN0IG90aGVyKSB7CisgICAgICAgIHJldHVybiB0aGlzLnRvQXJyYXkoY29udGV4dCkub3BfZXF1YWwoY29udGV4dCwgb3RoZXIpOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIFJlcGVhdGVkRmllbGQuZWFjaCgmYmxvY2spCisgICAgICoKKyAgICAgKiBJbnZva2VzIHRoZSBibG9jayBvbmNlIGZvciBlYWNoIGVsZW1lbnQgb2YgdGhlIHJlcGVhdGVkIGZpZWxkLiBSZXBlYXRlZEZpZWxkCisgICAgICogYWxzbyBpbmNsdWRlcyBFbnVtZXJhYmxlOyBjb21iaW5lZCB3aXRoIHRoaXMgbWV0aG9kLCB0aGUgcmVwZWF0ZWQgZmllbGQgdGh1cworICAgICAqIGFjdHMgbGlrZSBhbiBvcmRpbmFyeSBSdWJ5IHNlcXVlbmNlLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBlYWNoKFRocmVhZENvbnRleHQgY29udGV4dCwgQmxvY2sgYmxvY2spIHsKKyAgICAgICAgdGhpcy5zdG9yYWdlLmVhY2goY29udGV4dCwgYmxvY2spOworICAgICAgICByZXR1cm4gY29udGV4dC5ydW50aW1lLmdldE5pbCgpOworICAgIH0KKworICAgIEBKUnVieU1ldGhvZChuYW1lID0geyJ0b19hcnkiLCAidG9fYSJ9KQorICAgIHB1YmxpYyBJUnVieU9iamVjdCB0b0FycmF5KFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuc3RvcmFnZS5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgSVJ1YnlPYmplY3QgZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlKGNvbnRleHQpOworICAgICAgICAgICAgaWYgKHN0b3JhZ2UuZWx0SW50ZXJuYWwoaSkuaXNOaWwoKSkgeworICAgICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0KGksIGRlZmF1bHRWYWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNhbGwtc2VxOgorICAgICAqICAgICBSZXBlYXRlZEZpZWxkLmR1cCA9PiByZXBlYXRlZF9maWVsZAorICAgICAqCisgICAgICogRHVwbGljYXRlcyB0aGlzIHJlcGVhdGVkIGZpZWxkIHdpdGggYSBzaGFsbG93IGNvcHkuIFJlZmVyZW5jZXMgdG8gYWxsCisgICAgICogbm9uLXByaW1pdGl2ZSBlbGVtZW50IG9iamVjdHMgKGUuZy4sIHN1Ym1lc3NhZ2VzKSBhcmUgc2hhcmVkLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBkdXAoVGhyZWFkQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIFJ1YnlSZXBlYXRlZEZpZWxkIGR1cCA9IG5ldyBSdWJ5UmVwZWF0ZWRGaWVsZChjb250ZXh0LnJ1bnRpbWUsIG1ldGFDbGFzcywgZmllbGRUeXBlLCB0eXBlQ2xhc3MpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuc3RvcmFnZS5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgZHVwLnB1c2goY29udGV4dCwgdGhpcy5zdG9yYWdlLmVsdEludGVybmFsKGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZHVwOworICAgIH0KKworICAgIC8qCisgICAgICogY2FsbC1zZXE6CisgICAgICogICAgIFJlcGVhdGVkRmllbGQuaW5zcGVjdCA9PiBzdHJpbmcKKyAgICAgKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoaXMgcmVwZWF0ZWQgZmllbGQncyBlbGVtZW50cy4gSXQgd2lsbCBiZQorICAgICAqIGZvcm1hdGVkIGFzICJbPGVsZW1lbnQ+LCA8ZWxlbWVudD4sIC4uLl0iLCB3aXRoIGVhY2ggZWxlbWVudCdzIHN0cmluZworICAgICAqIHJlcHJlc2VudGF0aW9uIGNvbXB1dGVkIGJ5IGl0cyBvd24gI2luc3BlY3QgbWV0aG9kLgorICAgICAqLworICAgIEBKUnVieU1ldGhvZAorICAgIHB1YmxpYyBJUnVieU9iamVjdCBpbnNwZWN0KCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHN0ciA9IG5ldyBTdHJpbmdCdWlsZGVyKCJbIik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5zdG9yYWdlLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBzdHIuYXBwZW5kKHN0b3JhZ2UuZWx0SW50ZXJuYWwoaSkuaW5zcGVjdCgpKTsKKyAgICAgICAgICAgIHN0ci5hcHBlbmQoIiwgIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3RyLmxlbmd0aCgpID4gMSkgeworICAgICAgICAgICAgc3RyLnJlcGxhY2Uoc3RyLmxlbmd0aCgpIC0gMiwgc3RyLmxlbmd0aCgpLCAiXSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc3RyLmFwcGVuZCgiXSIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGdldFJ1bnRpbWUoKS5uZXdTdHJpbmcoc3RyLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8vIEphdmEgQVBJCisgICAgcHJvdGVjdGVkIElSdWJ5T2JqZWN0IGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5lbHRJbnRlcm5hbChpbmRleCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFJ1YnlSZXBlYXRlZEZpZWxkIGRlZXBDb3B5KFRocmVhZENvbnRleHQgY29udGV4dCkgeworICAgICAgICBSdWJ5UmVwZWF0ZWRGaWVsZCBjb3B5ID0gbmV3IFJ1YnlSZXBlYXRlZEZpZWxkKGNvbnRleHQucnVudGltZSwgbWV0YUNsYXNzLCBmaWVsZFR5cGUsIHR5cGVDbGFzcyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIElSdWJ5T2JqZWN0IHZhbHVlID0gc3RvcmFnZS5lbHRJbnRlcm5hbChpKTsKKyAgICAgICAgICAgIGlmIChmaWVsZFR5cGUgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuTUVTU0FHRSkgeworICAgICAgICAgICAgICAgIGNvcHkuc3RvcmFnZS5hZGQoKChSdWJ5TWVzc2FnZSkgdmFsdWUpLmRlZXBDb3B5KGNvbnRleHQpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29weS5zdG9yYWdlLmFkZCh2YWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvcHk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLnNpemUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIElSdWJ5T2JqZWN0IGRlZmF1bHRWYWx1ZShUaHJlYWRDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIHNlbnRpbmVsID0gU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsLmdldERlZmF1bHRJbnN0YW5jZSgpOworICAgICAgICBPYmplY3QgdmFsdWU7CisgICAgICAgIHN3aXRjaCAoZmllbGRUeXBlKSB7CisgICAgICAgICAgICBjYXNlIElOVDMyOgorICAgICAgICAgICAgICAgIHZhbHVlID0gc2VudGluZWwuZ2V0RGVmYXVsdEludDMyKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIElOVDY0OgorICAgICAgICAgICAgICAgIHZhbHVlID0gc2VudGluZWwuZ2V0RGVmYXVsdEludDY0KCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFVJTlQzMjoKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbnRpbmVsLmdldERlZmF1bHRVbml0MzIoKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVUlOVDY0OgorICAgICAgICAgICAgICAgIHZhbHVlID0gc2VudGluZWwuZ2V0RGVmYXVsdFVpbnQ2NCgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBGTE9BVDoKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbnRpbmVsLmdldERlZmF1bHRGbG9hdCgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBET1VCTEU6CisgICAgICAgICAgICAgICAgdmFsdWUgPSBzZW50aW5lbC5nZXREZWZhdWx0RG91YmxlKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEJPT0w6CisgICAgICAgICAgICAgICAgdmFsdWUgPSBzZW50aW5lbC5nZXREZWZhdWx0Qm9vbCgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBCWVRFUzoKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbnRpbmVsLmdldERlZmF1bHRCeXRlcygpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTVFJJTkc6CisgICAgICAgICAgICAgICAgdmFsdWUgPSBzZW50aW5lbC5nZXREZWZhdWx0U3RyaW5nKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUuZ2V0TmlsKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFV0aWxzLndyYXBQcmltYXJ5VmFsdWUoY29udGV4dCwgZmllbGRUeXBlLCB2YWx1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQXJyYXlFbGVtZW50VHlwZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIFJ1YnlBcnJheSBhcnIpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnIuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgVXRpbHMuY2hlY2tUeXBlKGNvbnRleHQsIGZpZWxkVHlwZSwgYXJyLmVsdEludGVybmFsKGkpLCAoUnVieU1vZHVsZSkgdHlwZUNsYXNzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgUnVieUFycmF5IHN0b3JhZ2U7CisgICAgcHJpdmF0ZSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZSBmaWVsZFR5cGU7CisgICAgcHJpdmF0ZSBJUnVieU9iamVjdCB0eXBlQ2xhc3M7Cit9CmRpZmYgLS1naXQgYS9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9TZW50aW5lbE91dGVyQ2xhc3MuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1NlbnRpbmVsT3V0ZXJDbGFzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0ZjJjNzIKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL2phdmEvY29tL2dvb2dsZS9wcm90b2J1Zi9qcnVieS9TZW50aW5lbE91dGVyQ2xhc3MuamF2YQpAQCAtMCwwICsxLDc3NiBAQAorLyoKKyAqIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorICogQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorICogbWV0OgorICoKKyAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisgKiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisgKiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisgKiBkaXN0cmlidXRpb24uCisgKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisgKiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorICogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorICovCisKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IHNlbnRpbmVsLnByb3RvCisKK3BhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieTsKKworcHVibGljIGZpbmFsIGNsYXNzIFNlbnRpbmVsT3V0ZXJDbGFzcyB7CisgIHByaXZhdGUgU2VudGluZWxPdXRlckNsYXNzKCkge30KKyAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKKyAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKKyAgfQorICBwdWJsaWMgaW50ZXJmYWNlIFNlbnRpbmVsT3JCdWlsZGVyIGV4dGVuZHMKKyAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsKQorICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKKworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSAxOzwvY29kZT4KKyAgICAgKi8KKyAgICBpbnQgZ2V0RGVmYXVsdEludDMyKCk7CisKKyAgICAvKioKKyAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkZWZhdWx0X2ludDY0ID0gMjs8L2NvZGU+CisgICAgICovCisgICAgbG9uZyBnZXREZWZhdWx0SW50NjQoKTsKKworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkZWZhdWx0X3VuaXQzMiA9IDM7PC9jb2RlPgorICAgICAqLworICAgIGludCBnZXREZWZhdWx0VW5pdDMyKCk7CisKKyAgICAvKioKKyAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGVmYXVsdF91aW50NjQgPSA0OzwvY29kZT4KKyAgICAgKi8KKyAgICBsb25nIGdldERlZmF1bHRVaW50NjQoKTsKKworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDU7PC9jb2RlPgorICAgICAqLworICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVmYXVsdFN0cmluZygpOworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDU7PC9jb2RlPgorICAgICAqLworICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZworICAgICAgICBnZXREZWZhdWx0U3RyaW5nQnl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9ib29sID0gNjs8L2NvZGU+CisgICAgICovCisgICAgYm9vbGVhbiBnZXREZWZhdWx0Qm9vbCgpOworCisgICAgLyoqCisgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZGVmYXVsdF9mbG9hdCA9IDc7PC9jb2RlPgorICAgICAqLworICAgIGZsb2F0IGdldERlZmF1bHRGbG9hdCgpOworCisgICAgLyoqCisgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gODs8L2NvZGU+CisgICAgICovCisgICAgZG91YmxlIGdldERlZmF1bHREb3VibGUoKTsKKworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgPSA5OzwvY29kZT4KKyAgICAgKi8KKyAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RGVmYXVsdEJ5dGVzKCk7CisgIH0KKyAgLyoqCisgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWx9CisgICAqLworICBwdWJsaWMgIHN0YXRpYyBmaW5hbCBjbGFzcyBTZW50aW5lbCBleHRlbmRzCisgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UgaW1wbGVtZW50cworICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsKQorICAgICAgU2VudGluZWxPckJ1aWxkZXIgeworICAgIC8vIFVzZSBTZW50aW5lbC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgorICAgIHByaXZhdGUgU2VudGluZWwoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgc3VwZXIoYnVpbGRlcik7CisgICAgfQorICAgIHByaXZhdGUgU2VudGluZWwoKSB7CisgICAgICBkZWZhdWx0SW50MzJfID0gMDsKKyAgICAgIGRlZmF1bHRJbnQ2NF8gPSAwTDsKKyAgICAgIGRlZmF1bHRVbml0MzJfID0gMDsKKyAgICAgIGRlZmF1bHRVaW50NjRfID0gMEw7CisgICAgICBkZWZhdWx0U3RyaW5nXyA9ICIiOworICAgICAgZGVmYXVsdEJvb2xfID0gZmFsc2U7CisgICAgICBkZWZhdWx0RmxvYXRfID0gMEY7CisgICAgICBkZWZhdWx0RG91YmxlXyA9IDBEOworICAgICAgZGVmYXVsdEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKKyAgICB9CisKKyAgICBAamF2YS5sYW5nLk92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0CisgICAgZ2V0VW5rbm93bkZpZWxkcygpIHsKKyAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKKyAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKKyAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfY29tX2dvb2dsZV9wcm90b2J1Zl9qcnVieV9TZW50aW5lbF9kZXNjcmlwdG9yOworICAgIH0KKworICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRmllbGRBY2Nlc3NvclRhYmxlCisgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgeworICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19jb21fZ29vZ2xlX3Byb3RvYnVmX2pydWJ5X1NlbnRpbmVsX2ZpZWxkQWNjZXNzb3JUYWJsZQorICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAorICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuU2VudGluZWwuQnVpbGRlci5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTZW50aW5lbD4gUEFSU0VSID0KKyAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U2VudGluZWw+KCkgeworICAgICAgcHVibGljIFNlbnRpbmVsIHBhcnNlUGFydGlhbEZyb20oCisgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAorICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKAorICAgICAgICAgICAgICBlLmdldE1lc3NhZ2UoKSkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CisgICAgICB9CisgICAgfTsKKworICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKKyAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U2VudGluZWw+IGdldFBhcnNlckZvclR5cGUoKSB7CisgICAgICByZXR1cm4gUEFSU0VSOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfSU5UMzJfRklFTERfTlVNQkVSID0gMTsKKyAgICBwcml2YXRlIGludCBkZWZhdWx0SW50MzJfOworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSAxOzwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERlZmF1bHRJbnQzMigpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0SW50MzJfOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfSU5UNjRfRklFTERfTlVNQkVSID0gMjsKKyAgICBwcml2YXRlIGxvbmcgZGVmYXVsdEludDY0XzsKKyAgICAvKioKKyAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkZWZhdWx0X2ludDY0ID0gMjs8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0RGVmYXVsdEludDY0KCkgeworICAgICAgcmV0dXJuIGRlZmF1bHRJbnQ2NF87CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9VTklUMzJfRklFTERfTlVNQkVSID0gMzsKKyAgICBwcml2YXRlIGludCBkZWZhdWx0VW5pdDMyXzsKKyAgICAvKioKKyAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGVmYXVsdF91bml0MzIgPSAzOzwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERlZmF1bHRVbml0MzIoKSB7CisgICAgICByZXR1cm4gZGVmYXVsdFVuaXQzMl87CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9VSU5UNjRfRklFTERfTlVNQkVSID0gNDsKKyAgICBwcml2YXRlIGxvbmcgZGVmYXVsdFVpbnQ2NF87CisgICAgLyoqCisgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRlZmF1bHRfdWludDY0ID0gNDs8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0RGVmYXVsdFVpbnQ2NCgpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0VWludDY0XzsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NUUklOR19GSUVMRF9OVU1CRVIgPSA1OworICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBkZWZhdWx0U3RyaW5nXzsKKyAgICAvKioKKyAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgPSA1OzwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0U3RyaW5nKCkgeworICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZWZhdWx0U3RyaW5nXzsKKyAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CisgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCisgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CisgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOworICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgeworICAgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gczsKKyAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNTs8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZworICAgICAgICBnZXREZWZhdWx0U3RyaW5nQnl0ZXMoKSB7CisgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlZmF1bHRTdHJpbmdfOworICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKKyAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCisgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CisgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gYjsKKyAgICAgICAgcmV0dXJuIGI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQk9PTF9GSUVMRF9OVU1CRVIgPSA2OworICAgIHByaXZhdGUgYm9vbGVhbiBkZWZhdWx0Qm9vbF87CisgICAgLyoqCisgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA2OzwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXREZWZhdWx0Qm9vbCgpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0Qm9vbF87CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9GTE9BVF9GSUVMRF9OVU1CRVIgPSA3OworICAgIHByaXZhdGUgZmxvYXQgZGVmYXVsdEZsb2F0XzsKKyAgICAvKioKKyAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzs8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldERlZmF1bHRGbG9hdCgpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0RmxvYXRfOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDg7CisgICAgcHJpdmF0ZSBkb3VibGUgZGVmYXVsdERvdWJsZV87CisgICAgLyoqCisgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gODs8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXREZWZhdWx0RG91YmxlKCkgeworICAgICAgcmV0dXJuIGRlZmF1bHREb3VibGVfOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQllURVNfRklFTERfTlVNQkVSID0gOTsKKyAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0Qnl0ZXNfOworICAgIC8qKgorICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgPSA5OzwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldERlZmF1bHRCeXRlcygpIHsKKyAgICAgIHJldHVybiBkZWZhdWx0Qnl0ZXNfOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuU2VudGluZWwgcGFyc2VGcm9tKAorICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKKyAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIHBhcnNlRnJvbSgKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCisgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIHBhcnNlRnJvbShieXRlW10gZGF0YSkKKyAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIHBhcnNlRnJvbSgKKyAgICAgICAgYnl0ZVtdIGRhdGEsCisgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQorICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQorICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShpbnB1dCk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuU2VudGluZWwgcGFyc2VGcm9tKAorICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAorICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIHBhcnNlRGVsaW1pdGVkRnJvbSgKKyAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBQQVJTRVIucGFyc2VEZWxpbWl0ZWRGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuU2VudGluZWwgcGFyc2VGcm9tKAorICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGlucHV0KTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCBwYXJzZUZyb20oCisgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7IHJldHVybiBuZXcgQnVpbGRlcigpOyB9CisgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KKyAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCBwcm90b3R5cGUpIHsKKyAgICAgIHJldHVybiBuZXdCdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CisgICAgfQorICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsgcmV0dXJuIG5ld0J1aWxkZXIodGhpcyk7IH0KKworICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CisgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOworICAgICAgcmV0dXJuIGJ1aWxkZXI7CisgICAgfQorICAgIC8qKgorICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWx9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKKyAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cworICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWwpCisgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsT3JCdWlsZGVyIHsKKyAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCisgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKKyAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19jb21fZ29vZ2xlX3Byb3RvYnVmX2pydWJ5X1NlbnRpbmVsX2Rlc2NyaXB0b3I7CisgICAgICB9CisKKyAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRmllbGRBY2Nlc3NvclRhYmxlCisgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CisgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfY29tX2dvb2dsZV9wcm90b2J1Zl9qcnVieV9TZW50aW5lbF9maWVsZEFjY2Vzc29yVGFibGUKKyAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAorICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbC5CdWlsZGVyLmNsYXNzKTsKKyAgICAgIH0KKworICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsLm5ld0J1aWxkZXIoKQorICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgeworICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CisgICAgICB9CisKKyAgICAgIHByaXZhdGUgQnVpbGRlcigKKyAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKKyAgICAgICAgc3VwZXIocGFyZW50KTsKKyAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOworICAgICAgfQorICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CisgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgeworICAgICAgICB9CisgICAgICB9CisgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKKyAgICAgICAgc3VwZXIuY2xlYXIoKTsKKyAgICAgICAgZGVmYXVsdEludDMyXyA9IDA7CisKKyAgICAgICAgZGVmYXVsdEludDY0XyA9IDBMOworCisgICAgICAgIGRlZmF1bHRVbml0MzJfID0gMDsKKworICAgICAgICBkZWZhdWx0VWludDY0XyA9IDBMOworCisgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gIiI7CisKKyAgICAgICAgZGVmYXVsdEJvb2xfID0gZmFsc2U7CisKKyAgICAgICAgZGVmYXVsdEZsb2F0XyA9IDBGOworCisgICAgICAgIGRlZmF1bHREb3VibGVfID0gMEQ7CisKKyAgICAgICAgZGVmYXVsdEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKKworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgorICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgeworICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX2NvbV9nb29nbGVfcHJvdG9idWZfanJ1YnlfU2VudGluZWxfZGVzY3JpcHRvcjsKKyAgICAgIH0KKworICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CisgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIGJ1aWxkKCkgeworICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKKyAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorCisgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuU2VudGluZWwgYnVpbGRQYXJ0aWFsKCkgeworICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5qcnVieS5TZW50aW5lbE91dGVyQ2xhc3MuU2VudGluZWwodGhpcyk7CisgICAgICAgIHJlc3VsdC5kZWZhdWx0SW50MzJfID0gZGVmYXVsdEludDMyXzsKKyAgICAgICAgcmVzdWx0LmRlZmF1bHRJbnQ2NF8gPSBkZWZhdWx0SW50NjRfOworICAgICAgICByZXN1bHQuZGVmYXVsdFVuaXQzMl8gPSBkZWZhdWx0VW5pdDMyXzsKKyAgICAgICAgcmVzdWx0LmRlZmF1bHRVaW50NjRfID0gZGVmYXVsdFVpbnQ2NF87CisgICAgICAgIHJlc3VsdC5kZWZhdWx0U3RyaW5nXyA9IGRlZmF1bHRTdHJpbmdfOworICAgICAgICByZXN1bHQuZGVmYXVsdEJvb2xfID0gZGVmYXVsdEJvb2xfOworICAgICAgICByZXN1bHQuZGVmYXVsdEZsb2F0XyA9IGRlZmF1bHRGbG9hdF87CisgICAgICAgIHJlc3VsdC5kZWZhdWx0RG91YmxlXyA9IGRlZmF1bHREb3VibGVfOworICAgICAgICByZXN1bHQuZGVmYXVsdEJ5dGVzXyA9IGRlZmF1bHRCeXRlc187CisgICAgICAgIG9uQnVpbHQoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKworCisgICAgICBwcml2YXRlIGludCBkZWZhdWx0SW50MzJfIDsKKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZGVmYXVsdF9pbnQzMiA9IDE7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgaW50IGdldERlZmF1bHRJbnQzMigpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRJbnQzMl87CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSAxOzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEludDMyKGludCB2YWx1ZSkgeworICAgICAgICAKKyAgICAgICAgZGVmYXVsdEludDMyXyA9IHZhbHVlOworICAgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSAxOzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0SW50MzIoKSB7CisgICAgICAgIAorICAgICAgICBkZWZhdWx0SW50MzJfID0gMDsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorCisgICAgICBwcml2YXRlIGxvbmcgZGVmYXVsdEludDY0XyA7CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRlZmF1bHRfaW50NjQgPSAyOzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIGxvbmcgZ2V0RGVmYXVsdEludDY0KCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdEludDY0XzsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZGVmYXVsdF9pbnQ2NCA9IDI7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0SW50NjQobG9uZyB2YWx1ZSkgeworICAgICAgICAKKyAgICAgICAgZGVmYXVsdEludDY0XyA9IHZhbHVlOworICAgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRlZmF1bHRfaW50NjQgPSAyOzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0SW50NjQoKSB7CisgICAgICAgIAorICAgICAgICBkZWZhdWx0SW50NjRfID0gMEw7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBpbnQgZGVmYXVsdFVuaXQzMl8gOworICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGVmYXVsdF91bml0MzIgPSAzOzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIGludCBnZXREZWZhdWx0VW5pdDMyKCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdFVuaXQzMl87CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkZWZhdWx0X3VuaXQzMiA9IDM7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0VW5pdDMyKGludCB2YWx1ZSkgeworICAgICAgICAKKyAgICAgICAgZGVmYXVsdFVuaXQzMl8gPSB2YWx1ZTsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGVmYXVsdF91bml0MzIgPSAzOzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0VW5pdDMyKCkgeworICAgICAgICAKKyAgICAgICAgZGVmYXVsdFVuaXQzMl8gPSAwOworICAgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIHByaXZhdGUgbG9uZyBkZWZhdWx0VWludDY0XyA7CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCA9IDQ7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgbG9uZyBnZXREZWZhdWx0VWludDY0KCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdFVpbnQ2NF87CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCA9IDQ7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0VWludDY0KGxvbmcgdmFsdWUpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHRVaW50NjRfID0gdmFsdWU7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRlZmF1bHRfdWludDY0ID0gNDs8L2NvZGU+CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdFVpbnQ2NCgpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHRVaW50NjRfID0gMEw7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGRlZmF1bHRTdHJpbmdfID0gIiI7CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDU7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0U3RyaW5nKCkgeworICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlZmF1bHRTdHJpbmdfOworICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgeworICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CisgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKKyAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKKyAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgeworICAgICAgICAgICAgZGVmYXVsdFN0cmluZ18gPSBzOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgPSA1OzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZworICAgICAgICAgIGdldERlZmF1bHRTdHJpbmdCeXRlcygpIHsKKyAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZWZhdWx0U3RyaW5nXzsKKyAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCisgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCisgICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKKyAgICAgICAgICBkZWZhdWx0U3RyaW5nXyA9IGI7CisgICAgICAgICAgcmV0dXJuIGI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgPSA1OzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdFN0cmluZygKKyAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgIH0KKyAgCisgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gdmFsdWU7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNTs8L2NvZGU+CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdFN0cmluZygpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGVmYXVsdFN0cmluZygpOworICAgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDU7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0U3RyaW5nQnl0ZXMoCisgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgIH0KKyAgCisgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gdmFsdWU7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRCb29sXyA7CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9ib29sID0gNjs8L2NvZGU+CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRCb29sKCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdEJvb2xfOworICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRfYm9vbCA9IDY7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0Qm9vbChib29sZWFuIHZhbHVlKSB7CisgICAgICAgIAorICAgICAgICBkZWZhdWx0Qm9vbF8gPSB2YWx1ZTsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRfYm9vbCA9IDY7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRCb29sKCkgeworICAgICAgICAKKyAgICAgICAgZGVmYXVsdEJvb2xfID0gZmFsc2U7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBmbG9hdCBkZWZhdWx0RmxvYXRfIDsKKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZGVmYXVsdF9mbG9hdCA9IDc7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgZmxvYXQgZ2V0RGVmYXVsdEZsb2F0KCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdEZsb2F0XzsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZGVmYXVsdF9mbG9hdCA9IDc7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0RmxvYXQoZmxvYXQgdmFsdWUpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHRGbG9hdF8gPSB2YWx1ZTsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzs8L2NvZGU+CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEZsb2F0KCkgeworICAgICAgICAKKyAgICAgICAgZGVmYXVsdEZsb2F0XyA9IDBGOworICAgICAgICBvbkNoYW5nZWQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIHByaXZhdGUgZG91YmxlIGRlZmF1bHREb3VibGVfIDsKKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gODs8L2NvZGU+CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RGVmYXVsdERvdWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHREb3VibGVfOworICAgICAgfQorICAgICAgLyoqCisgICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZGVmYXVsdF9kb3VibGUgPSA4OzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdERvdWJsZShkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHREb3VibGVfID0gdmFsdWU7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gODs8L2NvZGU+CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdERvdWJsZSgpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHREb3VibGVfID0gMEQ7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGVmYXVsdF9ieXRlcyA9IDk7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldERlZmF1bHRCeXRlcygpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRCeXRlc187CisgICAgICB9CisgICAgICAvKioKKyAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgPSA5OzwvY29kZT4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgeworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICB9CisgIAorICAgICAgICBkZWZhdWx0Qnl0ZXNfID0gdmFsdWU7CisgICAgICAgIG9uQ2hhbmdlZCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGVmYXVsdF9ieXRlcyA9IDk7PC9jb2RlPgorICAgICAgICovCisgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRCeXRlcygpIHsKKyAgICAgICAgCisgICAgICAgIGRlZmF1bHRCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXREZWZhdWx0Qnl0ZXMoKTsKKyAgICAgICAgb25DaGFuZ2VkKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKKyAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorCisgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCisgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgeworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworCisgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsKQorICAgIH0KKworICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsKQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsIGRlZmF1bHRJbnN0YW5jZTtzdGF0aWMgeworICAgICAgZGVmYXVsdEluc3RhbmNlID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuU2VudGluZWxPdXRlckNsYXNzLlNlbnRpbmVsKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgICByZXR1cm4gZGVmYXVsdEluc3RhbmNlOworICAgIH0KKworICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5LlNlbnRpbmVsT3V0ZXJDbGFzcy5TZW50aW5lbCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgeworICAgICAgcmV0dXJuIGRlZmF1bHRJbnN0YW5jZTsKKyAgICB9CisKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgorICAgIGludGVybmFsX3N0YXRpY19jb21fZ29vZ2xlX3Byb3RvYnVmX2pydWJ5X1NlbnRpbmVsX2Rlc2NyaXB0b3I7CisgIHByaXZhdGUgc3RhdGljCisgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkZpZWxkQWNjZXNzb3JUYWJsZQorICAgICAgaW50ZXJuYWxfc3RhdGljX2NvbV9nb29nbGVfcHJvdG9idWZfanJ1YnlfU2VudGluZWxfZmllbGRBY2Nlc3NvclRhYmxlOworCisgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgorICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gZGVzY3JpcHRvcjsKKyAgfQorICBwcml2YXRlIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCisgICAgICBkZXNjcmlwdG9yOworICBzdGF0aWMgeworICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKKyAgICAgICJcblwwMTZzZW50aW5lbC5wcm90b1wwMjJcMDMxY29tLmdvb2dsZS5wcm90b2J1Zi5qciIgKworICAgICAgInVieVwiXDMzNFwwMDFcblwwMTBTZW50aW5lbFwwMjJcMDI1XG5ccmRlZmF1bHRfaW50MzJcMDMwXDAwMSBcMDAxKFwwMDVcMDIyIiArCisgICAgICAiXDAyNVxuXHJkZWZhdWx0X2ludDY0XDAzMFwwMDIgXDAwMShcMDAzXDAyMlwwMjZcblwwMTZkZWZhdWx0X3VuaXQzMiIgKworICAgICAgIlwwMzBcMDAzIFwwMDEoXHJcMDIyXDAyNlxuXDAxNmRlZmF1bHRfdWludDY0XDAzMFwwMDQgXDAwMShcMDA0XDAyMlwwMjZcblwwMTZkZWZhdWwiICsKKyAgICAgICJ0X3N0cmluZ1wwMzBcMDA1IFwwMDEoXHRcMDIyXDAyNFxuXDAxNGRlZmF1bHRfYm9vbFwwMzBcMDA2IFwwMDEoXDAxMFwwMjJcMDI1XG5cciIgKworICAgICAgImRlZmF1bHRfZmxvYXRcMDMwXDAwNyBcMDAxKFwwMDJcMDIyXDAyNlxuXDAxNmRlZmF1bHRfZG91YmxlXDAzMFwwMTAgIiArCisgICAgICAiXDAwMShcMDAxXDAyMlwwMjVcblxyZGVmYXVsdF9ieXRlc1wwMzBcdCBcMDAxKFwwMTRCXDAwMkhcMDAyYlwwMDZwcm90bzMiCisgICAgfTsKKyAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLkludGVybmFsRGVzY3JpcHRvckFzc2lnbmVyIGFzc2lnbmVyID0KKyAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuICAgIEludGVybmFsRGVzY3JpcHRvckFzc2lnbmVyKCkgeworICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IGFzc2lnbkRlc2NyaXB0b3JzKAorICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yIHJvb3QpIHsKKyAgICAgICAgICAgIGRlc2NyaXB0b3IgPSByb290OworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9OworICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKKyAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCisgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10geworICAgICAgICB9LCBhc3NpZ25lcik7CisgICAgaW50ZXJuYWxfc3RhdGljX2NvbV9nb29nbGVfcHJvdG9idWZfanJ1YnlfU2VudGluZWxfZGVzY3JpcHRvciA9CisgICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOworICAgIGludGVybmFsX3N0YXRpY19jb21fZ29vZ2xlX3Byb3RvYnVmX2pydWJ5X1NlbnRpbmVsX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldworICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkZpZWxkQWNjZXNzb3JUYWJsZSgKKyAgICAgICAgaW50ZXJuYWxfc3RhdGljX2NvbV9nb29nbGVfcHJvdG9idWZfanJ1YnlfU2VudGluZWxfZGVzY3JpcHRvciwKKyAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEZWZhdWx0SW50MzIiLCAiRGVmYXVsdEludDY0IiwgIkRlZmF1bHRVbml0MzIiLCAiRGVmYXVsdFVpbnQ2NCIsICJEZWZhdWx0U3RyaW5nIiwgIkRlZmF1bHRCb29sIiwgIkRlZmF1bHRGbG9hdCIsICJEZWZhdWx0RG91YmxlIiwgIkRlZmF1bHRCeXRlcyIsIH0pOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQorfQpkaWZmIC0tZ2l0IGEvcnVieS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvcHJvdG9idWYvanJ1YnkvVXRpbHMuamF2YSBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1V0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTk2YTA5NwotLS0gL2Rldi9udWxsCisrKyBiL3J1Ynkvc3JjL21haW4vamF2YS9jb20vZ29vZ2xlL3Byb3RvYnVmL2pydWJ5L1V0aWxzLmphdmEKQEAgLTAsMCArMSwzMDAgQEAKKy8qCisgKiBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyAqIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAqIG1ldDoKKyAqCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorICogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorICogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorICogZGlzdHJpYnV0aW9uLgorICogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworICogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCitwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYuanJ1Ynk7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnM7CitpbXBvcnQgb3JnLmpjb2RpbmdzLkVuY29kaW5nOworaW1wb3J0IG9yZy5qY29kaW5ncy5zcGVjaWZpYy5BU0NJSUVuY29kaW5nOworaW1wb3J0IG9yZy5qY29kaW5ncy5zcGVjaWZpYy5VU0FTQ0lJRW5jb2Rpbmc7CitpbXBvcnQgb3JnLmpjb2RpbmdzLnNwZWNpZmljLlVURjhFbmNvZGluZzsKK2ltcG9ydCBvcmcuanJ1YnkuKjsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5CbG9jazsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5UaHJlYWRDb250ZXh0OworaW1wb3J0IG9yZy5qcnVieS5ydW50aW1lLmJ1aWx0aW4uSVJ1YnlPYmplY3Q7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworcHVibGljIGNsYXNzIFV0aWxzIHsKKyAgICBwdWJsaWMgc3RhdGljIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIHJ1YnlUb0ZpZWxkVHlwZShJUnVieU9iamVjdCB0eXBlQ2xhc3MpIHsKKyAgICAgICAgcmV0dXJuIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlLnZhbHVlT2YodHlwZUNsYXNzLmFzSmF2YVN0cmluZygpLnRvVXBwZXJDYXNlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3QgZmllbGRUeXBlVG9SdWJ5KFRocmVhZENvbnRleHQgY29udGV4dCwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUgdHlwZSkgeworICAgICAgICByZXR1cm4gZmllbGRUeXBlVG9SdWJ5KGNvbnRleHQsIHR5cGUubmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIElSdWJ5T2JqZWN0IGZpZWxkVHlwZVRvUnVieShUaHJlYWRDb250ZXh0IGNvbnRleHQsIERlc2NyaXB0b3JQcm90b3MuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSB0eXBlKSB7CisgICAgICAgIHJldHVybiBmaWVsZFR5cGVUb1J1YnkoY29udGV4dCwgdHlwZS5uYW1lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIElSdWJ5T2JqZWN0IGZpZWxkVHlwZVRvUnVieShUaHJlYWRDb250ZXh0IGNvbnRleHQsIFN0cmluZyB0eXBlTmFtZSkgeworCisgICAgICAgIHJldHVybiBjb250ZXh0LnJ1bnRpbWUubmV3U3ltYm9sKHR5cGVOYW1lLnJlcGxhY2UoIlRZUEVfIiwgIiIpLnRvTG93ZXJDYXNlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja1R5cGUoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZSBmaWVsZFR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVJ1YnlPYmplY3QgdmFsdWUsIFJ1YnlNb2R1bGUgdHlwZUNsYXNzKSB7CisgICAgICAgIFJ1YnkgcnVudGltZSA9IGNvbnRleHQucnVudGltZTsKKyAgICAgICAgT2JqZWN0IHZhbDsKKyAgICAgICAgc3dpdGNoKGZpZWxkVHlwZSkgeworICAgICAgICAgICAgY2FzZSBJTlQzMjoKKyAgICAgICAgICAgIGNhc2UgSU5UNjQ6CisgICAgICAgICAgICBjYXNlIFVJTlQzMjoKKyAgICAgICAgICAgIGNhc2UgVUlOVDY0OgorICAgICAgICAgICAgICAgIGlmICghaXNSdWJ5TnVtKHZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiRXhwZWN0ZWQgbnVtYmVyIHR5cGUgZm9yIGludGVncmFsIGZpZWxkLiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzd2l0Y2goZmllbGRUeXBlKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5UMzI6CisgICAgICAgICAgICAgICAgICAgICAgICBSdWJ5TnVtZXJpYy5udW0yaW50KHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIElOVDY0OgorICAgICAgICAgICAgICAgICAgICAgICAgUnVieU51bWVyaWMubnVtMmxvbmcodmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgVUlOVDMyOgorICAgICAgICAgICAgICAgICAgICAgICAgbnVtMnVpbnQodmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICBudW0ydWxvbmcoY29udGV4dC5ydW50aW1lLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2hlY2tJbnRUeXBlUHJlY2lzaW9uKGNvbnRleHQsIGZpZWxkVHlwZSwgdmFsdWUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBGTE9BVDoKKyAgICAgICAgICAgICAgICBpZiAoIWlzUnVieU51bSh2YWx1ZSkpCisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFeHBlY3RlZCBudW1iZXIgdHlwZSBmb3IgZmxvYXQgZmllbGQuIik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERPVUJMRToKKyAgICAgICAgICAgICAgICBpZiAoIWlzUnVieU51bSh2YWx1ZSkpCisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFeHBlY3RlZCBudW1iZXIgdHlwZSBmb3IgZG91YmxlIGZpZWxkLiIpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBCT09MOgorICAgICAgICAgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgUnVieUJvb2xlYW4pKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiSW52YWxpZCBhcmd1bWVudCBmb3IgYm9vbGVhbiBmaWVsZC4iKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQllURVM6CisgICAgICAgICAgICBjYXNlIFNUUklORzoKKyAgICAgICAgICAgICAgICB2YWxpZGF0ZVN0cmluZ0VuY29kaW5nKGNvbnRleHQucnVudGltZSwgZmllbGRUeXBlLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmdldE1ldGFDbGFzcygpICE9IHR5cGVDbGFzcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcih2YWx1ZSwgdHlwZUNsYXNzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEVOVU06CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUnVieVN5bWJvbCkgeworICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvciBlbnVtRGVzY3JpcHRvciA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChSdWJ5RW51bURlc2NyaXB0b3IpIHR5cGVDbGFzcy5nZXRJbnN0YW5jZVZhcmlhYmxlKERFU0NSSVBUT1JfSU5TVEFOQ0VfVkFSKSkuZ2V0RGVzY3JpcHRvcigpOworICAgICAgICAgICAgICAgICAgICB2YWwgPSBlbnVtRGVzY3JpcHRvci5maW5kVmFsdWVCeU5hbWUodmFsdWUuYXNKYXZhU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1JhbmdlRXJyb3IoIkVudW0gdmFsdWUgIiArIHZhbHVlICsgIiBpcyBub3QgZm91bmQuIik7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmKCFpc1J1YnlOdW0odmFsdWUpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3VHlwZUVycm9yKCJFeHBlY3RlZCBudW1iZXIgb3Igc3ltYm9sIHR5cGUgZm9yIGVudW0gZmllbGQuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgSVJ1YnlPYmplY3Qgd3JhcFByaW1hcnlWYWx1ZShUaHJlYWRDb250ZXh0IGNvbnRleHQsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIGZpZWxkVHlwZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIFJ1YnkgcnVudGltZSA9IGNvbnRleHQucnVudGltZTsKKyAgICAgICAgc3dpdGNoIChmaWVsZFR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgSU5UMzI6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJ1bnRpbWUubmV3Rml4bnVtKChJbnRlZ2VyKSB2YWx1ZSk7CisgICAgICAgICAgICBjYXNlIElOVDY0OgorICAgICAgICAgICAgICAgIHJldHVybiBydW50aW1lLm5ld0ZpeG51bSgoTG9uZykgdmFsdWUpOworICAgICAgICAgICAgY2FzZSBVSU5UMzI6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJ1bnRpbWUubmV3Rml4bnVtKCgoSW50ZWdlcikgdmFsdWUpICYgKC0xbCA+Pj4gMzIpKTsKKyAgICAgICAgICAgIGNhc2UgVUlOVDY0OgorICAgICAgICAgICAgICAgIGxvbmcgcmV0ID0gKExvbmcpIHZhbHVlOworICAgICAgICAgICAgICAgIHJldHVybiByZXQgPj0gMCA/IHJ1bnRpbWUubmV3Rml4bnVtKHJldCkgOgorICAgICAgICAgICAgICAgICAgICAgICAgUnVieUJpZ251bS5uZXdCaWdudW0ocnVudGltZSwgVUlOVDY0X0NPTVBMRU1FTlRBUlkuYWRkKG5ldyBCaWdJbnRlZ2VyKHJldCArICIiKSkpOworICAgICAgICAgICAgY2FzZSBGTE9BVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gcnVudGltZS5uZXdGbG9hdCgoRmxvYXQpIHZhbHVlKTsKKyAgICAgICAgICAgIGNhc2UgRE9VQkxFOgorICAgICAgICAgICAgICAgIHJldHVybiBydW50aW1lLm5ld0Zsb2F0KChEb3VibGUpIHZhbHVlKTsKKyAgICAgICAgICAgIGNhc2UgQk9PTDoKKyAgICAgICAgICAgICAgICByZXR1cm4gKEJvb2xlYW4pIHZhbHVlID8gcnVudGltZS5nZXRUcnVlKCkgOiBydW50aW1lLmdldEZhbHNlKCk7CisgICAgICAgICAgICBjYXNlIEJZVEVTOgorICAgICAgICAgICAgICAgIHJldHVybiBydW50aW1lLm5ld1N0cmluZygoKEJ5dGVTdHJpbmcpIHZhbHVlKS50b1N0cmluZ1V0ZjgoKSk7CisgICAgICAgICAgICBjYXNlIFNUUklORzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcnVudGltZS5uZXdTdHJpbmcodmFsdWUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHJldHVybiBydW50aW1lLmdldE5pbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBpbnQgbnVtMnVpbnQoSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgbG9uZyBsb25nVmFsID0gUnVieU51bWVyaWMubnVtMmxvbmcodmFsdWUpOworICAgICAgICBpZiAobG9uZ1ZhbCA+IFVJTlRfTUFYKQorICAgICAgICAgICAgdGhyb3cgdmFsdWUuZ2V0UnVudGltZSgpLm5ld1JhbmdlRXJyb3IoIkludGVnZXIgIiArIGxvbmdWYWwgKyAiIHRvbyBiaWcgdG8gY29udmVydCB0byAndW5zaWduZWQgaW50JyIpOworICAgICAgICBsb25nIG51bSA9IGxvbmdWYWw7CisgICAgICAgIGlmIChudW0gPiBJbnRlZ2VyLk1BWF9WQUxVRSB8fCBudW0gPCBJbnRlZ2VyLk1JTl9WQUxVRSkKKyAgICAgICAgICAgIC8vIGVuY29kZSB0byBVSU5UMzIKKyAgICAgICAgICAgIG51bSA9ICgtbG9uZ1ZhbCBeICgtMWwgPj4+IDMyKSApICsgMTsKKyAgICAgICAgUnVieU51bWVyaWMuY2hlY2tJbnQodmFsdWUsIG51bSk7CisgICAgICAgIHJldHVybiAoaW50KSBudW07CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBsb25nIG51bTJ1bG9uZyhSdWJ5IHJ1bnRpbWUsIElSdWJ5T2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJ1YnlGbG9hdCkgeworICAgICAgICAgICAgUnVieUJpZ251bSBiaWdudW0gPSBSdWJ5QmlnbnVtLm5ld0JpZ251bShydW50aW1lLCAoKFJ1YnlGbG9hdCkgdmFsdWUpLmdldERvdWJsZVZhbHVlKCkpOworICAgICAgICAgICAgcmV0dXJuIFJ1YnlCaWdudW0uYmlnMnVsb25nKGJpZ251bSk7CisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBSdWJ5QmlnbnVtKSB7CisgICAgICAgICAgICByZXR1cm4gUnVieUJpZ251bS5iaWcydWxvbmcoKFJ1YnlCaWdudW0pIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBSdWJ5TnVtZXJpYy5udW0ybG9uZyh2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdmFsaWRhdGVTdHJpbmdFbmNvZGluZyhSdWJ5IHJ1bnRpbWUsIERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvci5UeXBlIHR5cGUsIElSdWJ5T2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgUnVieVN0cmluZykpCisgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiSW52YWxpZCBhcmd1bWVudCBmb3Igc3RyaW5nIGZpZWxkLiIpOworICAgICAgICBFbmNvZGluZyBlbmNvZGluZyA9ICgoUnVieVN0cmluZykgdmFsdWUpLmdldEVuY29kaW5nKCk7CisgICAgICAgIHN3aXRjaCh0eXBlKSB7CisgICAgICAgICAgICBjYXNlIEJZVEVTOgorICAgICAgICAgICAgICAgIGlmIChlbmNvZGluZyAhPSBBU0NJSUVuY29kaW5nLklOU1RBTkNFKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiRW5jb2RpbmcgZm9yIGJ5dGVzIGZpZWxkcyIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgbXVzdCBiZSBcIkFTQ0lJLThCSVRcIiwgYnV0IHdhcyAiICsgZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTVFJJTkc6CisgICAgICAgICAgICAgICAgaWYgKGVuY29kaW5nICE9IFVURjhFbmNvZGluZy5JTlNUQU5DRQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgZW5jb2RpbmcgIT0gVVNBU0NJSUVuY29kaW5nLklOU1RBTkNFKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld1R5cGVFcnJvcigiRW5jb2RpbmcgZm9yIHN0cmluZyBmaWVsZHMiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG11c3QgYmUgXCJVVEYtOFwiIG9yIFwiQVNDSUlcIiwgYnV0IHdhcyAiICsgZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja05hbWVBdmFpbGFiaWxpdHkoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBTdHJpbmcgbmFtZSkgeworICAgICAgICBpZiAoY29udGV4dC5ydW50aW1lLmdldE9iamVjdCgpLmdldENvbnN0YW50QXQobmFtZSkgIT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IGNvbnRleHQucnVudGltZS5uZXdOYW1lRXJyb3IobmFtZSArICIgaXMgYWxyZWFkeSBkZWZpbmVkIiwgbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZSBpbnZhbGlkICIuIiBpbiBkZXNjcmlwdG9yIHdpdGggX19ET1RfXworICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVzY2FwZUlkZW50aWZpZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUucmVwbGFjZSgiLiIsIEJBRE5BTUVfUkVQTEFDRU1FTlQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2UgX19ET1RfXyBpbiBkZXNjcmlwdG9yIG5hbWUgd2l0aCAiLiIKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB1bmVzY2FwZUlkZW50aWZpZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUucmVwbGFjZShCQUROQU1FX1JFUExBQ0VNRU5ULCAiLiIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc01hcEVudHJ5KERlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZERlc2NyaXB0b3IpIHsKKyAgICAgICAgcmV0dXJuIGZpZWxkRGVzY3JpcHRvci5nZXRUeXBlKCkgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuTUVTU0FHRSAmJgorICAgICAgICAgICAgICAgIGZpZWxkRGVzY3JpcHRvci5pc1JlcGVhdGVkKCkgJiYKKyAgICAgICAgICAgICAgICBmaWVsZERlc2NyaXB0b3IuZ2V0TWVzc2FnZVR5cGUoKS5nZXRPcHRpb25zKCkuZ2V0TWFwRW50cnkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFJ1YnlGaWVsZERlc2NyaXB0b3IgbXNnZGVmQ3JlYXRlRmllbGQoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBTdHJpbmcgbGFiZWwsIElSdWJ5T2JqZWN0IG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElSdWJ5T2JqZWN0IHR5cGUsIElSdWJ5T2JqZWN0IG51bWJlciwgSVJ1YnlPYmplY3QgdHlwZUNsYXNzLCBSdWJ5Q2xhc3MgY0ZpZWxkRGVzY3JpcHRvcikgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IgZmllbGREZWYgPSAoUnVieUZpZWxkRGVzY3JpcHRvcikgY0ZpZWxkRGVzY3JpcHRvci5uZXdJbnN0YW5jZShjb250ZXh0LCBCbG9jay5OVUxMX0JMT0NLKTsKKyAgICAgICAgZmllbGREZWYuc2V0TGFiZWwoY29udGV4dCwgcnVudGltZS5uZXdTdHJpbmcobGFiZWwpKTsKKyAgICAgICAgZmllbGREZWYuc2V0TmFtZShjb250ZXh0LCBuYW1lKTsKKyAgICAgICAgZmllbGREZWYuc2V0VHlwZShjb250ZXh0LCB0eXBlKTsKKyAgICAgICAgZmllbGREZWYuc2V0TnVtYmVyKGNvbnRleHQsIG51bWJlcik7CisKKyAgICAgICAgaWYgKCF0eXBlQ2xhc3MuaXNOaWwoKSkgeworICAgICAgICAgICAgaWYgKCEodHlwZUNsYXNzIGluc3RhbmNlb2YgUnVieVN0cmluZykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld0FyZ3VtZW50RXJyb3IoImV4cGVjdGVkIHN0cmluZyBmb3IgdHlwZSBjbGFzcyIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmllbGREZWYuc2V0U3VibXNnTmFtZShjb250ZXh0LCB0eXBlQ2xhc3MpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmaWVsZERlZjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgY2hlY2tJbnRUeXBlUHJlY2lzaW9uKFRocmVhZENvbnRleHQgY29udGV4dCwgRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUgdHlwZSwgSVJ1YnlPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUnVieUZsb2F0KSB7CisgICAgICAgICAgICBkb3VibGUgZG91YmxlVmFsID0gUnVieU51bWVyaWMubnVtMmRibCh2YWx1ZSk7CisgICAgICAgICAgICBpZiAoTWF0aC5mbG9vcihkb3VibGVWYWwpICE9IGRvdWJsZVZhbCkgeworICAgICAgICAgICAgICAgIHRocm93IGNvbnRleHQucnVudGltZS5uZXdSYW5nZUVycm9yKCJOb24taW50ZWdyYWwgZmxvYXRpbmcgcG9pbnQgdmFsdWUgYXNzaWduZWQgdG8gaW50ZWdlciBmaWVsZC4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAodHlwZSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5VSU5UMzIgfHwgdHlwZSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5VSU5UNjQpIHsKKyAgICAgICAgICAgIGlmIChSdWJ5TnVtZXJpYy5udW0yZGJsKHZhbHVlKSA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBjb250ZXh0LnJ1bnRpbWUubmV3UmFuZ2VFcnJvcigiQXNzaWduaW5nIG5lZ2F0aXZlIHZhbHVlIHRvIHVuc2lnbmVkIGludGVnZXIgZmllbGQuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gaXNSdWJ5TnVtKE9iamVjdCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBSdWJ5Rml4bnVtIHx8IHZhbHVlIGluc3RhbmNlb2YgUnVieUZsb2F0IHx8IHZhbHVlIGluc3RhbmNlb2YgUnVieUJpZ251bTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgdmFsaWRhdGVUeXBlQ2xhc3MoVGhyZWFkQ29udGV4dCBjb250ZXh0LCBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZSB0eXBlLCBJUnVieU9iamVjdCB2YWx1ZSkgeworICAgICAgICBSdWJ5IHJ1bnRpbWUgPSBjb250ZXh0LnJ1bnRpbWU7CisgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgUnVieU1vZHVsZSkpIHsKKyAgICAgICAgICAgIHRocm93IHJ1bnRpbWUubmV3QXJndW1lbnRFcnJvcigiVHlwZUNsYXNzIGhhcyBpbmNvcnJlY3QgdHlwZSIpOworICAgICAgICB9CisgICAgICAgIFJ1YnlNb2R1bGUga2xhc3MgPSAoUnVieU1vZHVsZSkgdmFsdWU7CisgICAgICAgIElSdWJ5T2JqZWN0IGRlc2NyaXB0b3IgPSBrbGFzcy5nZXRJbnN0YW5jZVZhcmlhYmxlKERFU0NSSVBUT1JfSU5TVEFOQ0VfVkFSKTsKKyAgICAgICAgaWYgKGRlc2NyaXB0b3IuaXNOaWwoKSkgeworICAgICAgICAgICAgdGhyb3cgcnVudGltZS5uZXdBcmd1bWVudEVycm9yKCJUeXBlIGNsYXNzIGhhcyBubyBkZXNjcmlwdG9yLiBQbGVhc2UgcGFzcyBhICIgKworICAgICAgICAgICAgICAgICAgICAiY2xhc3Mgb3IgZW51bSBhcyByZXR1cm5lZCBieSB0aGUgRGVzY3JpcHRvclBvb2wuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHR5cGUgPT0gRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yLlR5cGUuTUVTU0FHRSkgeworICAgICAgICAgICAgaWYgKCEgKGRlc2NyaXB0b3IgaW5zdGFuY2VvZiBSdWJ5RGVzY3JpcHRvcikpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld0FyZ3VtZW50RXJyb3IoIkRlc2NyaXB0b3IgaGFzIGFuIGluY29ycmVjdCB0eXBlIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBEZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IuVHlwZS5FTlVNKSB7CisgICAgICAgICAgICBpZiAoISAoZGVzY3JpcHRvciBpbnN0YW5jZW9mIFJ1YnlFbnVtRGVzY3JpcHRvcikpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBydW50aW1lLm5ld0FyZ3VtZW50RXJyb3IoIkRlc2NyaXB0b3IgaGFzIGFuIGluY29ycmVjdCB0eXBlIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBCQUROQU1FX1JFUExBQ0VNRU5UID0gIl9fRE9UX18iOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgREVTQ1JJUFRPUl9JTlNUQU5DRV9WQVIgPSAiQGRlc2NyaXB0b3IiOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgRVFVQUxfU0lHTiA9ICI9IjsKKworICAgIHByaXZhdGUgc3RhdGljIEJpZ0ludGVnZXIgVUlOVDY0X0NPTVBMRU1FTlRBUlkgPSBuZXcgQmlnSW50ZWdlcigiMTg0NDY3NDQwNzM3MDk1NTE2MTYiKTsgLy9NYXRoLnBvdygyLCA2NCkKKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgVUlOVF9NQVggPSAweGZmZmZmZmZmbDsKK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vamF2YS9nb29nbGUvUHJvdG9idWZKYXZhU2VydmljZS5qYXZhIGIvcnVieS9zcmMvbWFpbi9qYXZhL2dvb2dsZS9Qcm90b2J1ZkphdmFTZXJ2aWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZmYjQ5MgotLS0gL2Rldi9udWxsCisrKyBiL3J1Ynkvc3JjL21haW4vamF2YS9nb29nbGUvUHJvdG9idWZKYXZhU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsNjAgQEAKKy8qCisgKiBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyAqIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAqIG1ldDoKKyAqCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorICogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorICogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorICogZGlzdHJpYnV0aW9uLgorICogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworICogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCitwYWNrYWdlIGdvb2dsZTsKKworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuanJ1YnkuKjsKK2ltcG9ydCBvcmcuanJ1YnkuUnVieTsKK2ltcG9ydCBvcmcuanJ1YnkucnVudGltZS5sb2FkLkJhc2ljTGlicmFyeVNlcnZpY2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgUHJvdG9idWZKYXZhU2VydmljZSBpbXBsZW1lbnRzIEJhc2ljTGlicmFyeVNlcnZpY2UgeworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGJhc2ljTG9hZChSdWJ5IHJ1YnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJ1YnkuZGVmaW5lTW9kdWxlKCJHb29nbGUiKTsKKyAgICAgICAgUnVieVByb3RvYnVmLmNyZWF0ZVByb3RvYnVmKHJ1YnkpOworICAgICAgICBSdWJ5RGVzY3JpcHRvci5jcmVhdGVSdWJ5RGVzY3JpcHRvcihydWJ5KTsKKyAgICAgICAgUnVieUJ1aWxkZXIuY3JlYXRlUnVieUJ1aWxkZXIocnVieSk7CisgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IuY3JlYXRlUnVieUZpbGVEZXNjcmlwdG9yKHJ1YnkpOworICAgICAgICBSdWJ5TWVzc2FnZUJ1aWxkZXJDb250ZXh0LmNyZWF0ZVJ1YnlNZXNzYWdlQnVpbGRlckNvbnRleHQocnVieSk7CisgICAgICAgIFJ1YnlFbnVtRGVzY3JpcHRvci5jcmVhdGVSdWJ5RW51bURlc2NyaXB0b3IocnVieSk7CisgICAgICAgIFJ1YnlFbnVtQnVpbGRlckNvbnRleHQuY3JlYXRlUnVieUVudW1CdWlsZGVyQ29udGV4dChydWJ5KTsKKyAgICAgICAgUnVieURlc2NyaXB0b3JQb29sLmNyZWF0ZVJ1YnlEZXNjcmlwdG9yUG9vbChydWJ5KTsKKyAgICAgICAgUnVieVJlcGVhdGVkRmllbGQuY3JlYXRlUnVieVJlcGVhdGVkRmllbGQocnVieSk7CisgICAgICAgIFJ1YnlGaWVsZERlc2NyaXB0b3IuY3JlYXRlUnVieUZpbGVEZXNjcmlwdG9yKHJ1YnkpOworICAgICAgICBSdWJ5TWFwLmNyZWF0ZVJ1YnlNYXAocnVieSk7CisgICAgICAgIFJ1YnlPbmVvZkRlc2NyaXB0b3IuY3JlYXRlUnVieU9uZW9mRGVzY3JpcHRvcihydWJ5KTsKKyAgICAgICAgUnVieU9uZW9mQnVpbGRlckNvbnRleHQuY3JlYXRlUnVieU9uZW9mQnVpbGRlckNvbnRleHQocnVieSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3J1Ynkvc3JjL21haW4vc2VudGluZWwucHJvdG8gYi9ydWJ5L3NyYy9tYWluL3NlbnRpbmVsLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5YTFhZTEKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3NyYy9tYWluL3NlbnRpbmVsLnByb3RvCkBAIC0wLDAgKzEsMTUgQEAKK3N5bnRheCA9ICJwcm90bzMiOworcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLmpydWJ5Oworb3B0aW9uIG9wdGltaXplX2ZvciA9IENPREVfU0laRTsKKworbWVzc2FnZSBTZW50aW5lbCB7CisgIG9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSAxOworICBvcHRpb25hbCBpbnQ2NCBkZWZhdWx0X2ludDY0ID0gMjsKKyAgb3B0aW9uYWwgdWludDMyIGRlZmF1bHRfdW5pdDMyID0gMzsKKyAgb3B0aW9uYWwgdWludDY0IGRlZmF1bHRfdWludDY0ID0gNDsKKyAgb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNTsKKyAgb3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA2OworICBvcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzsKKyAgb3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gODsKKyAgb3B0aW9uYWwgYnl0ZXMgZGVmYXVsdF9ieXRlcyA9IDk7Cit9CmRpZmYgLS1naXQgYS9ydWJ5L3Rlc3RzL2Jhc2ljLnJiIGIvcnVieS90ZXN0cy9iYXNpYy5yYgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDBmMGE5Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS90ZXN0cy9iYXNpYy5yYgpAQCAtMCwwICsxLDEwMDYgQEAKKyMhL3Vzci9iaW4vcnVieQorCityZXF1aXJlICdnb29nbGUvcHJvdG9idWYnCityZXF1aXJlICd0ZXN0L3VuaXQnCisKKyMgLS0tLS0tLS0tLS0tLSBnZW5lcmF0ZWQgY29kZSAtLS0tLS0tLS0tLS0tLQorCittb2R1bGUgQmFzaWNUZXN0CisgIHBvb2wgPSBHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5uZXcKKyAgcG9vbC5idWlsZCBkbworICAgIGFkZF9tZXNzYWdlICJUZXN0TWVzc2FnZSIgZG8KKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9pbnQzMiwgIDppbnQzMiwgICAgICAgIDEKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9pbnQ2NCwgIDppbnQ2NCwgICAgICAgIDIKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF91aW50MzIsIDp1aW50MzIsICAgICAgIDMKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF91aW50NjQsIDp1aW50NjQsICAgICAgIDQKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9ib29sLCAgIDpib29sLCAgICAgICAgIDUKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9mbG9hdCwgIDpmbG9hdCwgICAgICAgIDYKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9kb3VibGUsIDpkb3VibGUsICAgICAgIDcKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9zdHJpbmcsIDpzdHJpbmcsICAgICAgIDgKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9ieXRlcywgIDpieXRlcywgICAgICAgIDkKKyAgICAgIG9wdGlvbmFsIDpvcHRpb25hbF9tc2csICAgIDptZXNzYWdlLCAgICAgIDEwLCAiVGVzdE1lc3NhZ2UyIgorICAgICAgb3B0aW9uYWwgOm9wdGlvbmFsX2VudW0sICAgOmVudW0sICAgICAgICAgMTEsICJUZXN0RW51bSIKKworICAgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2ludDMyLCAgOmludDMyLCAgICAgICAgMTIKKyAgICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9pbnQ2NCwgIDppbnQ2NCwgICAgICAgIDEzCisgICAgICByZXBlYXRlZCA6cmVwZWF0ZWRfdWludDMyLCA6dWludDMyLCAgICAgICAxNAorICAgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX3VpbnQ2NCwgOnVpbnQ2NCwgICAgICAgMTUKKyAgICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9ib29sLCAgIDpib29sLCAgICAgICAgIDE2CisgICAgICByZXBlYXRlZCA6cmVwZWF0ZWRfZmxvYXQsICA6ZmxvYXQsICAgICAgICAxNworICAgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2RvdWJsZSwgOmRvdWJsZSwgICAgICAgMTgKKyAgICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9zdHJpbmcsIDpzdHJpbmcsICAgICAgIDE5CisgICAgICByZXBlYXRlZCA6cmVwZWF0ZWRfYnl0ZXMsICA6Ynl0ZXMsICAgICAgICAyMAorICAgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX21zZywgICAgOm1lc3NhZ2UsICAgICAgMjEsICJUZXN0TWVzc2FnZTIiCisgICAgICByZXBlYXRlZCA6cmVwZWF0ZWRfZW51bSwgICA6ZW51bSwgICAgICAgICAyMiwgIlRlc3RFbnVtIgorICAgIGVuZAorICAgIGFkZF9tZXNzYWdlICJUZXN0TWVzc2FnZTIiIGRvCisgICAgICBvcHRpb25hbCA6Zm9vLCA6aW50MzIsIDEKKyAgICBlbmQKKworICAgIGFkZF9tZXNzYWdlICJSZWN1cnNpdmUxIiBkbworICAgICAgb3B0aW9uYWwgOmZvbywgOm1lc3NhZ2UsIDEsICJSZWN1cnNpdmUyIgorICAgIGVuZAorICAgIGFkZF9tZXNzYWdlICJSZWN1cnNpdmUyIiBkbworICAgICAgb3B0aW9uYWwgOmZvbywgOm1lc3NhZ2UsIDEsICJSZWN1cnNpdmUxIgorICAgIGVuZAorCisgICAgYWRkX2VudW0gIlRlc3RFbnVtIiBkbworICAgICAgdmFsdWUgOkRlZmF1bHQsIDAKKyAgICAgIHZhbHVlIDpBLCAxCisgICAgICB2YWx1ZSA6QiwgMgorICAgICAgdmFsdWUgOkMsIDMKKyAgICBlbmQKKworICAgIGFkZF9tZXNzYWdlICJCYWRGaWVsZE5hbWVzIiBkbworICAgICAgb3B0aW9uYWwgOmR1cCwgOmludDMyLCAxCisgICAgICBvcHRpb25hbCA6Y2xhc3MsIDppbnQzMiwgMgorICAgICAgb3B0aW9uYWwgOiJhLmIiLCA6aW50MzIsIDMKKyAgICBlbmQKKworICAgIGFkZF9tZXNzYWdlICJNYXBNZXNzYWdlIiBkbworICAgICAgbWFwIDptYXBfc3RyaW5nX2ludDMyLCA6c3RyaW5nLCA6aW50MzIsIDEKKyAgICAgIG1hcCA6bWFwX3N0cmluZ19tc2csIDpzdHJpbmcsIDptZXNzYWdlLCAyLCAiVGVzdE1lc3NhZ2UyIgorICAgIGVuZAorICAgIGFkZF9tZXNzYWdlICJNYXBNZXNzYWdlV2lyZUVxdWl2IiBkbworICAgICAgcmVwZWF0ZWQgOm1hcF9zdHJpbmdfaW50MzIsIDptZXNzYWdlLCAxLCAiTWFwTWVzc2FnZVdpcmVFcXVpdl9lbnRyeTEiCisgICAgICByZXBlYXRlZCA6bWFwX3N0cmluZ19tc2csIDptZXNzYWdlLCAyLCAiTWFwTWVzc2FnZVdpcmVFcXVpdl9lbnRyeTIiCisgICAgZW5kCisgICAgYWRkX21lc3NhZ2UgIk1hcE1lc3NhZ2VXaXJlRXF1aXZfZW50cnkxIiBkbworICAgICAgb3B0aW9uYWwgOmtleSwgOnN0cmluZywgMQorICAgICAgb3B0aW9uYWwgOnZhbHVlLCA6aW50MzIsIDIKKyAgICBlbmQKKyAgICBhZGRfbWVzc2FnZSAiTWFwTWVzc2FnZVdpcmVFcXVpdl9lbnRyeTIiIGRvCisgICAgICBvcHRpb25hbCA6a2V5LCA6c3RyaW5nLCAxCisgICAgICBvcHRpb25hbCA6dmFsdWUsIDptZXNzYWdlLCAyLCAiVGVzdE1lc3NhZ2UyIgorICAgIGVuZAorCisgICAgYWRkX21lc3NhZ2UgIk9uZW9mTWVzc2FnZSIgZG8KKyAgICAgIG9uZW9mIDpteV9vbmVvZiBkbworICAgICAgICBvcHRpb25hbCA6YSwgOnN0cmluZywgMQorICAgICAgICBvcHRpb25hbCA6YiwgOmludDMyLCAyCisgICAgICAgIG9wdGlvbmFsIDpjLCA6bWVzc2FnZSwgMywgIlRlc3RNZXNzYWdlMiIKKyAgICAgICAgb3B0aW9uYWwgOmQsIDplbnVtLCA0LCAiVGVzdEVudW0iCisgICAgICBlbmQKKyAgICBlbmQKKyAgZW5kCisKKyAgVGVzdE1lc3NhZ2UgPSBwb29sLmxvb2t1cCgiVGVzdE1lc3NhZ2UiKS5tc2djbGFzcworICBUZXN0TWVzc2FnZTIgPSBwb29sLmxvb2t1cCgiVGVzdE1lc3NhZ2UyIikubXNnY2xhc3MKKyAgUmVjdXJzaXZlMSA9IHBvb2wubG9va3VwKCJSZWN1cnNpdmUxIikubXNnY2xhc3MKKyAgUmVjdXJzaXZlMiA9IHBvb2wubG9va3VwKCJSZWN1cnNpdmUyIikubXNnY2xhc3MKKyAgVGVzdEVudW0gPSBwb29sLmxvb2t1cCgiVGVzdEVudW0iKS5lbnVtbW9kdWxlCisgIEJhZEZpZWxkTmFtZXMgPSBwb29sLmxvb2t1cCgiQmFkRmllbGROYW1lcyIpLm1zZ2NsYXNzCisgIE1hcE1lc3NhZ2UgPSBwb29sLmxvb2t1cCgiTWFwTWVzc2FnZSIpLm1zZ2NsYXNzCisgIE1hcE1lc3NhZ2VXaXJlRXF1aXYgPSBwb29sLmxvb2t1cCgiTWFwTWVzc2FnZVdpcmVFcXVpdiIpLm1zZ2NsYXNzCisgIE1hcE1lc3NhZ2VXaXJlRXF1aXZfZW50cnkxID0KKyAgICBwb29sLmxvb2t1cCgiTWFwTWVzc2FnZVdpcmVFcXVpdl9lbnRyeTEiKS5tc2djbGFzcworICBNYXBNZXNzYWdlV2lyZUVxdWl2X2VudHJ5MiA9CisgICAgcG9vbC5sb29rdXAoIk1hcE1lc3NhZ2VXaXJlRXF1aXZfZW50cnkyIikubXNnY2xhc3MKKyAgT25lb2ZNZXNzYWdlID0gcG9vbC5sb29rdXAoIk9uZW9mTWVzc2FnZSIpLm1zZ2NsYXNzCisKKyMgLS0tLS0tLS0tLS0tIHRlc3QgY2FzZXMgLS0tLS0tLS0tLS0tLS0tCisKKyAgY2xhc3MgTWVzc2FnZUNvbnRhaW5lclRlc3QgPCBUZXN0OjpVbml0OjpUZXN0Q2FzZQorCisgICAgZGVmIHRlc3RfZGVmYXVsdHMKKyAgICAgIG0gPSBUZXN0TWVzc2FnZS5uZXcKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2ludDMyID09IDAKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2ludDY0ID09IDAKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX3VpbnQzMiA9PSAwCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF91aW50NjQgPT0gMAorICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfYm9vbCA9PSBmYWxzZQorICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfZmxvYXQgPT0gMC4wCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9kb3VibGUgPT0gMC4wCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9zdHJpbmcgPT0gIiIKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2J5dGVzID09ICIiCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9tc2cgPT0gbmlsCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9lbnVtID09IDpEZWZhdWx0CisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9zZXR0ZXJzCisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3CisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gLTQyCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9pbnQzMiA9PSAtNDIKKyAgICAgIG0ub3B0aW9uYWxfaW50NjQgPSAtMHgxXzAwMDBfMDAwMAorICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfaW50NjQgPT0gLTB4MV8wMDAwXzAwMDAKKyAgICAgIG0ub3B0aW9uYWxfdWludDMyID0gMHg5MDAwXzAwMDAKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX3VpbnQzMiA9PSAweDkwMDBfMDAwMAorICAgICAgbS5vcHRpb25hbF91aW50NjQgPSAweDkwMDBfMDAwMF8wMDAwXzAwMDAKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX3VpbnQ2NCA9PSAweDkwMDBfMDAwMF8wMDAwXzAwMDAKKyAgICAgIG0ub3B0aW9uYWxfYm9vbCA9IHRydWUKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2Jvb2wgPT0gdHJ1ZQorICAgICAgbS5vcHRpb25hbF9mbG9hdCA9IDAuNQorICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfZmxvYXQgPT0gMC41CisgICAgICBtLm9wdGlvbmFsX2RvdWJsZSA9IDAuNQorICAgICAgbS5vcHRpb25hbF9zdHJpbmcgPSAiaGVsbG8iCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9zdHJpbmcgPT0gImhlbGxvIgorICAgICAgbS5vcHRpb25hbF9ieXRlcyA9ICJ3b3JsZCIuZW5jb2RlISgnQVNDSUktOEJJVCcpCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9ieXRlcyA9PSAid29ybGQiCisgICAgICBtLm9wdGlvbmFsX21zZyA9IFRlc3RNZXNzYWdlMi5uZXcoOmZvbyA9PiA0MikKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX21zZyA9PSBUZXN0TWVzc2FnZTIubmV3KDpmb28gPT4gNDIpCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9jdG9yX2FyZ3MKKyAgICAgIG0gPSBUZXN0TWVzc2FnZS5uZXcoOm9wdGlvbmFsX2ludDMyID0+IC00MiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOm9wdGlvbmFsX21zZyA9PiBUZXN0TWVzc2FnZTIubmV3LAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfZW51bSA9PiA6QywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOnJlcGVhdGVkX3N0cmluZyA9PiBbImhlbGxvIiwgInRoZXJlIiwgIndvcmxkIl0pCisgICAgICBhc3NlcnQgbS5vcHRpb25hbF9pbnQzMiA9PSAtNDIKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX21zZy5jbGFzcyA9PSBUZXN0TWVzc2FnZTIKKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX3N0cmluZy5sZW5ndGggPT0gMworICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfZW51bSA9PSA6QworICAgICAgYXNzZXJ0IG0ucmVwZWF0ZWRfc3RyaW5nWzBdID09ICJoZWxsbyIKKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX3N0cmluZ1sxXSA9PSAidGhlcmUiCisgICAgICBhc3NlcnQgbS5yZXBlYXRlZF9zdHJpbmdbMl0gPT0gIndvcmxkIgorICAgIGVuZAorCisgICAgZGVmIHRlc3RfaW5zcGVjdAorICAgICAgbSA9IFRlc3RNZXNzYWdlLm5ldyg6b3B0aW9uYWxfaW50MzIgPT4gLTQyLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfZW51bSA9PiA6QSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOm9wdGlvbmFsX21zZyA9PiBUZXN0TWVzc2FnZTIubmV3LAorICAgICAgICAgICAgICAgICAgICAgICAgICA6cmVwZWF0ZWRfc3RyaW5nID0+IFsiaGVsbG8iLCAidGhlcmUiLCAid29ybGQiXSkKKyAgICAgIGV4cGVjdGVkID0gJzxCYXNpY1Rlc3Q6OlRlc3RNZXNzYWdlOiBvcHRpb25hbF9pbnQzMjogLTQyLCBvcHRpb25hbF9pbnQ2NDogMCwgb3B0aW9uYWxfdWludDMyOiAwLCBvcHRpb25hbF91aW50NjQ6IDAsIG9wdGlvbmFsX2Jvb2w6IGZhbHNlLCBvcHRpb25hbF9mbG9hdDogMC4wLCBvcHRpb25hbF9kb3VibGU6IDAuMCwgb3B0aW9uYWxfc3RyaW5nOiAiIiwgb3B0aW9uYWxfYnl0ZXM6ICIiLCBvcHRpb25hbF9tc2c6IDxCYXNpY1Rlc3Q6OlRlc3RNZXNzYWdlMjogZm9vOiAwPiwgb3B0aW9uYWxfZW51bTogOkEsIHJlcGVhdGVkX2ludDMyOiBbXSwgcmVwZWF0ZWRfaW50NjQ6IFtdLCByZXBlYXRlZF91aW50MzI6IFtdLCByZXBlYXRlZF91aW50NjQ6IFtdLCByZXBlYXRlZF9ib29sOiBbXSwgcmVwZWF0ZWRfZmxvYXQ6IFtdLCByZXBlYXRlZF9kb3VibGU6IFtdLCByZXBlYXRlZF9zdHJpbmc6IFsiaGVsbG8iLCAidGhlcmUiLCAid29ybGQiXSwgcmVwZWF0ZWRfYnl0ZXM6IFtdLCByZXBlYXRlZF9tc2c6IFtdLCByZXBlYXRlZF9lbnVtOiBbXT4nCisgICAgICBhc3NlcnQgbS5pbnNwZWN0ID09IGV4cGVjdGVkCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9oYXNoCisgICAgICBtMSA9IFRlc3RNZXNzYWdlLm5ldyg6b3B0aW9uYWxfaW50MzIgPT4gNDIpCisgICAgICBtMiA9IFRlc3RNZXNzYWdlLm5ldyg6b3B0aW9uYWxfaW50MzIgPT4gMTAyKQorICAgICAgYXNzZXJ0IG0xLmhhc2ggIT0gMAorICAgICAgYXNzZXJ0IG0yLmhhc2ggIT0gMAorICAgICAgIyByZWx5aW5nIG9uIHRoZSByYW5kb21uZXNzIGhlcmUgLS0gaWYgaGFzaCBmdW5jdGlvbiBjaGFuZ2VzIGFuZCB3ZSBhcmUKKyAgICAgICMgdW5sdWNreSBlbm91Z2ggdG8gZ2V0IGEgY29sbGlzaW9uLCB0aGVuIGNoYW5nZSB0aGUgdmFsdWVzIGFib3ZlLgorICAgICAgYXNzZXJ0IG0xLmhhc2ggIT0gbTIuaGFzaAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfdHlwZV9lcnJvcnMKKyAgICAgIG0gPSBUZXN0TWVzc2FnZS5uZXcKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9pbnQzMiA9ICJoZWxsbyIKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3N0cmluZyA9IDQyCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9zdHJpbmcgPSBuaWwKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX2Jvb2wgPSA0MgorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfbXNnID0gVGVzdE1lc3NhZ2UubmV3ICAjIGV4cGVjdHMgVGVzdE1lc3NhZ2UyCisgICAgICBlbmQKKworICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBtLnJlcGVhdGVkX2ludDMyID0gW10gICMgbmVlZHMgUmVwZWF0ZWRGaWVsZAorICAgICAgZW5kCisKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbS5yZXBlYXRlZF9pbnQzMi5wdXNoICJoZWxsbyIKKyAgICAgIGVuZAorCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG0ucmVwZWF0ZWRfbXNnLnB1c2ggVGVzdE1lc3NhZ2UubmV3CisgICAgICBlbmQKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X3N0cmluZ19lbmNvZGluZworICAgICAgbSA9IFRlc3RNZXNzYWdlLm5ldworCisgICAgICAjIEFzc2lnbmluZyBhIG5vcm1hbCAoQVNDSUkgb3IgVVRGOCkgc3RyaW5nIHRvIGEgYnl0ZXMgZmllbGQsIG9yCisgICAgICAjIEFTQ0lJLThCSVQgdG8gYSBzdHJpbmcgZmllbGQsIHJhaXNlcyBhbiBlcnJvci4KKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9ieXRlcyA9ICJUZXN0IHN0cmluZyBBU0NJSSIuZW5jb2RlISgnQVNDSUknKQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfYnl0ZXMgPSAiVGVzdCBzdHJpbmcgVVRGLTggXHUwMTAwIi5lbmNvZGUhKCdVVEYtOCcpCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9zdHJpbmcgPSBbIkZGRkYiXS5wYWNrKCdIKicpCisgICAgICBlbmQKKworICAgICAgIyAiT3JkaW5hcnkiIHVzZSBjYXNlLgorICAgICAgbS5vcHRpb25hbF9ieXRlcyA9IFsiRkZGRiJdLnBhY2soJ0gqJykKKyAgICAgIG0ub3B0aW9uYWxfc3RyaW5nID0gIlx1MDEwMCIKKworICAgICAgIyBzdHJpbmdzIGFyZSBtdXRhYmxlIHNvIHdlIGNhbiBkbyB0aGlzLCBidXQgc2VyaWFsaXplIHNob3VsZCBjYXRjaCBpdC4KKyAgICAgIG0ub3B0aW9uYWxfc3RyaW5nID0gImFzZGYiLmVuY29kZSEoJ1VURi04JykKKyAgICAgIG0ub3B0aW9uYWxfc3RyaW5nLmVuY29kZSEoJ0FTQ0lJLThCSVQnKQorICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBkYXRhID0gVGVzdE1lc3NhZ2UuZW5jb2RlKG0pCisgICAgICBlbmQKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X3JwdGZpZWxkX2ludDMyCisgICAgICBsID0gR29vZ2xlOjpQcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZC5uZXcoOmludDMyKQorICAgICAgYXNzZXJ0IGwuY291bnQgPT0gMAorICAgICAgbCA9IEdvb2dsZTo6UHJvdG9idWY6OlJlcGVhdGVkRmllbGQubmV3KDppbnQzMiwgWzEsIDIsIDNdKQorICAgICAgYXNzZXJ0IGwuY291bnQgPT0gMworICAgICAgYXNzZXJ0X2VxdWFsIFsxLCAyLCAzXSwgbAorICAgICAgYXNzZXJ0X2VxdWFsIGwsIFsxLCAyLCAzXQorICAgICAgbC5wdXNoIDQKKyAgICAgIGFzc2VydCBsID09IFsxLCAyLCAzLCA0XQorICAgICAgZHN0X2xpc3QgPSBbXQorICAgICAgbC5lYWNoIHsgfHZhbHwgZHN0X2xpc3QucHVzaCB2YWwgfQorICAgICAgYXNzZXJ0IGRzdF9saXN0ID09IFsxLCAyLCAzLCA0XQorICAgICAgYXNzZXJ0IGwudG9fYSA9PSBbMSwgMiwgMywgNF0KKyAgICAgIGFzc2VydCBsWzBdID09IDEKKyAgICAgIGFzc2VydCBsWzNdID09IDQKKyAgICAgIGxbMF0gPSA1CisgICAgICBhc3NlcnQgbCA9PSBbNSwgMiwgMywgNF0KKworICAgICAgbDIgPSBsLmR1cAorICAgICAgYXNzZXJ0IGwgPT0gbDIKKyAgICAgIGFzc2VydCBsLm9iamVjdF9pZCAhPSBsMi5vYmplY3RfaWQKKyAgICAgIGwyLnB1c2ggNgorICAgICAgYXNzZXJ0IGwuY291bnQgPT0gNAorICAgICAgYXNzZXJ0IGwyLmNvdW50ID09IDUKKworICAgICAgYXNzZXJ0IGwuaW5zcGVjdCA9PSAnWzUsIDIsIDMsIDRdJworCisgICAgICBsLmluc2VydCg3LCA4LCA5KQorICAgICAgYXNzZXJ0IGwgPT0gWzUsIDIsIDMsIDQsIDcsIDgsIDldCisgICAgICBhc3NlcnQgbC5wb3AgPT0gOQorICAgICAgYXNzZXJ0IGwgPT0gWzUsIDIsIDMsIDQsIDcsIDhdCisKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbSA9IFRlc3RNZXNzYWdlLm5ldworICAgICAgICBsLnB1c2ggbQorICAgICAgZW5kCisKKyAgICAgIG0gPSBUZXN0TWVzc2FnZS5uZXcKKyAgICAgIG0ucmVwZWF0ZWRfaW50MzIgPSBsCisgICAgICBhc3NlcnQgbS5yZXBlYXRlZF9pbnQzMiA9PSBbNSwgMiwgMywgNCwgNywgOF0KKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX2ludDMyLm9iamVjdF9pZCA9PSBsLm9iamVjdF9pZAorICAgICAgbC5wdXNoIDQyCisgICAgICBhc3NlcnQgbS5yZXBlYXRlZF9pbnQzMi5wb3AgPT0gNDIKKworICAgICAgbDMgPSBsICsgbC5kdXAKKyAgICAgIGFzc2VydCBsMy5jb3VudCA9PSBsLmNvdW50ICogMgorICAgICAgbC5jb3VudC50aW1lcyBkbyB8aXwKKyAgICAgICAgYXNzZXJ0IGwzW2ldID09IGxbaV0KKyAgICAgICAgYXNzZXJ0IGwzW2wuY291bnQgKyBpXSA9PSBsW2ldCisgICAgICBlbmQKKworICAgICAgbC5jbGVhcgorICAgICAgYXNzZXJ0IGwuY291bnQgPT0gMAorICAgICAgbCArPSBbMSwgMiwgMywgNF0KKyAgICAgIGwucmVwbGFjZShbNSwgNiwgNywgOF0pCisgICAgICBhc3NlcnQgbCA9PSBbNSwgNiwgNywgOF0KKworICAgICAgbDQgPSBHb29nbGU6OlByb3RvYnVmOjpSZXBlYXRlZEZpZWxkLm5ldyg6aW50MzIpCisgICAgICBsNFs1XSA9IDQyCisgICAgICBhc3NlcnQgbDQgPT0gWzAsIDAsIDAsIDAsIDAsIDQyXQorCisgICAgICBsNCA8PCAxMDAKKyAgICAgIGFzc2VydCBsNCA9PSBbMCwgMCwgMCwgMCwgMCwgNDIsIDEwMF0KKyAgICAgIGw0IDw8IDEwMSA8PCAxMDIKKyAgICAgIGFzc2VydCBsNCA9PSBbMCwgMCwgMCwgMCwgMCwgNDIsIDEwMCwgMTAxLCAxMDJdCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9ycHRmaWVsZF9tc2cKKyAgICAgIGwgPSBHb29nbGU6OlByb3RvYnVmOjpSZXBlYXRlZEZpZWxkLm5ldyg6bWVzc2FnZSwgVGVzdE1lc3NhZ2UpCisgICAgICBsLnB1c2ggVGVzdE1lc3NhZ2UubmV3CisgICAgICBhc3NlcnQgbC5jb3VudCA9PSAxCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIGwucHVzaCBUZXN0TWVzc2FnZTIubmV3CisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbC5wdXNoIDQyCisgICAgICBlbmQKKworICAgICAgbDIgPSBsLmR1cAorICAgICAgYXNzZXJ0IGwyWzBdID09IGxbMF0KKyAgICAgIGFzc2VydCBsMlswXS5vYmplY3RfaWQgPT0gbFswXS5vYmplY3RfaWQKKworICAgICAgbDIgPSBHb29nbGU6OlByb3RvYnVmLmRlZXBfY29weShsKQorICAgICAgYXNzZXJ0IGwyWzBdID09IGxbMF0KKyAgICAgIGFzc2VydCBsMlswXS5vYmplY3RfaWQgIT0gbFswXS5vYmplY3RfaWQKKworICAgICAgbDMgPSBsICsgbDIKKyAgICAgIGFzc2VydCBsMy5jb3VudCA9PSAyCisgICAgICBhc3NlcnQgbDNbMF0gPT0gbFswXQorICAgICAgYXNzZXJ0IGwzWzFdID09IGwyWzBdCisgICAgICBsM1swXS5vcHRpb25hbF9pbnQzMiA9IDEwMDAKKyAgICAgIGFzc2VydCBsWzBdLm9wdGlvbmFsX2ludDMyID09IDEwMDAKKworICAgICAgbmV3X21zZyA9IFRlc3RNZXNzYWdlLm5ldyg6b3B0aW9uYWxfaW50MzIgPT4gMjAwKQorICAgICAgbDQgPSBsICsgW25ld19tc2ddCisgICAgICBhc3NlcnQgbDQuY291bnQgPT0gMgorICAgICAgbmV3X21zZy5vcHRpb25hbF9pbnQzMiA9IDEwMDAKKyAgICAgIGFzc2VydCBsNFsxXS5vcHRpb25hbF9pbnQzMiA9PSAxMDAwCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9ycHRmaWVsZF9lbnVtCisgICAgICBsID0gR29vZ2xlOjpQcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZC5uZXcoOmVudW0sIFRlc3RFbnVtKQorICAgICAgbC5wdXNoIDpBCisgICAgICBsLnB1c2ggOkIKKyAgICAgIGwucHVzaCA6QworICAgICAgYXNzZXJ0IGwuY291bnQgPT0gMworICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbC5wdXNoIDpECisgICAgICBlbmQKKyAgICAgIGFzc2VydCBsWzBdID09IDpBCisKKyAgICAgIGwucHVzaCA0CisgICAgICBhc3NlcnQgbFszXSA9PSA0CisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9ycHRmaWVsZF9pbml0aWFsaXplCisgICAgICBhc3NlcnRfcmFpc2UgQXJndW1lbnRFcnJvciBkbworICAgICAgICBsID0gR29vZ2xlOjpQcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZC5uZXcKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIEFyZ3VtZW50RXJyb3IgZG8KKyAgICAgICAgbCA9IEdvb2dsZTo6UHJvdG9idWY6OlJlcGVhdGVkRmllbGQubmV3KDptZXNzYWdlKQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgQXJndW1lbnRFcnJvciBkbworICAgICAgICBsID0gR29vZ2xlOjpQcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZC5uZXcoWzEsIDIsIDNdKQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgQXJndW1lbnRFcnJvciBkbworICAgICAgICBsID0gR29vZ2xlOjpQcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZC5uZXcoOm1lc3NhZ2UsIFtUZXN0TWVzc2FnZTIubmV3XSkKKyAgICAgIGVuZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfbWFwX2Jhc2ljCisgICAgICAjIGFsbG93ZWQga2V5IHR5cGVzOgorICAgICAgIyA6aW50MzIsIDppbnQ2NCwgOnVpbnQzMiwgOnVpbnQ2NCwgOmJvb2wsIDpzdHJpbmcsIDpieXRlcy4KKworICAgICAgbSA9IEdvb2dsZTo6UHJvdG9idWY6Ok1hcC5uZXcoOnN0cmluZywgOmludDMyKQorICAgICAgbVsiYXNkZiJdID0gMQorICAgICAgYXNzZXJ0IG1bImFzZGYiXSA9PSAxCisgICAgICBtWyJqa2w7Il0gPSA0MgorICAgICAgYXNzZXJ0IG0gPT0geyAiamtsOyIgPT4gNDIsICJhc2RmIiA9PiAxIH0KKyAgICAgIGFzc2VydCBtLmhhc19rZXk/KCJhc2RmIikKKyAgICAgIGFzc2VydCAhbS5oYXNfa2V5PygicXdlcnR5IikKKyAgICAgIGFzc2VydCBtLmxlbmd0aCA9PSAyCisKKyAgICAgIG0yID0gbS5kdXAKKyAgICAgIGFzc2VydCBtID09IG0yCisgICAgICBhc3NlcnQgbS5oYXNoICE9IDAKKyAgICAgIGFzc2VydCBtLmhhc2ggPT0gbTIuaGFzaAorCisgICAgICBjb2xsZWN0ZWQgPSB7fQorICAgICAgbS5lYWNoIHsgfGssdnwgY29sbGVjdGVkW3ZdID0gayB9CisgICAgICBhc3NlcnQgY29sbGVjdGVkID09IHsgNDIgPT4gImprbDsiLCAxID0+ICJhc2RmIiB9CisKKyAgICAgIGFzc2VydCBtLmRlbGV0ZSgiYXNkZiIpID09IDEKKyAgICAgIGFzc2VydCAhbS5oYXNfa2V5PygiYXNkZiIpCisgICAgICBhc3NlcnQgbVsiYXNkZiJdID09IG5pbAorICAgICAgYXNzZXJ0ICFtLmhhc19rZXk/KCJhc2RmIikKKworICAgICAgIyBXZSBvbmx5IGFzc2VydCBvbiBpbnNwZWN0IHZhbHVlIHdoZW4gdGhlcmUgaXMgb25lIG1hcCBlbnRyeSBiZWNhdXNlIHRoZQorICAgICAgIyBvcmRlciBpbiB3aGljaCBlbGVtZW50cyBhcHBlYXIgaXMgdW5zcGVjaWZpZWQgKGRlcGVuZHMgb24gdGhlIGludGVybmFsCisgICAgICAjIGhhc2ggZnVuY3Rpb24pLiBXZSBkb24ndCB3YW50IGEgYnJpdHRsZSB0ZXN0LgorICAgICAgYXNzZXJ0IG0uaW5zcGVjdCA9PSAie1wiamtsO1wiPT40Mn0iCisKKyAgICAgIGFzc2VydCBtLmtleXMgPT0gWyJqa2w7Il0KKyAgICAgIGFzc2VydCBtLnZhbHVlcyA9PSBbNDJdCisKKyAgICAgIG0uY2xlYXIKKyAgICAgIGFzc2VydCBtLmxlbmd0aCA9PSAwCisgICAgICBhc3NlcnQgbSA9PSB7fQorCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG1bMV0gPSAxCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG1bImFzZGYiXSA9IDB4MV8wMDAwXzAwMDAKKyAgICAgIGVuZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfbWFwX2N0b3IKKyAgICAgIG0gPSBHb29nbGU6OlByb3RvYnVmOjpNYXAubmV3KDpzdHJpbmcsIDppbnQzMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiYSIgPT4gMSwgImIiID0+IDIsICJjIiA9PiAzfSkKKyAgICAgIGFzc2VydCBtID09IHsiYSIgPT4gMSwgImMiID0+IDMsICJiIiA9PiAyfQorICAgIGVuZAorCisgICAgZGVmIHRlc3RfbWFwX2tleXR5cGVzCisgICAgICBtID0gR29vZ2xlOjpQcm90b2J1Zjo6TWFwLm5ldyg6aW50MzIsIDppbnQzMikKKyAgICAgIG1bMV0gPSA0MgorICAgICAgbVstMV0gPSA0MgorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbVsweDgwMDBfMDAwMF0gPSAxCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbVsiYXNkZiJdID0gMQorICAgICAgZW5kCisKKyAgICAgIG0gPSBHb29nbGU6OlByb3RvYnVmOjpNYXAubmV3KDppbnQ2NCwgOmludDMyKQorICAgICAgbVsweDEwMDBfMDAwMF8wMDAwXzAwMDBdID0gMQorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbVsweDFfMDAwMF8wMDAwXzAwMDBfMDAwMF0gPSAxCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbVsiYXNkZiJdID0gMQorICAgICAgZW5kCisKKyAgICAgIG0gPSBHb29nbGU6OlByb3RvYnVmOjpNYXAubmV3KDp1aW50MzIsIDppbnQzMikKKyAgICAgIG1bMHg4MDAwXzAwMDBdID0gMQorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbVsweDFfMDAwMF8wMDAwXSA9IDEKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbVstMV0gPSAxCisgICAgICBlbmQKKworICAgICAgbSA9IEdvb2dsZTo6UHJvdG9idWY6Ok1hcC5uZXcoOnVpbnQ2NCwgOmludDMyKQorICAgICAgbVsweDgwMDBfMDAwMF8wMDAwXzAwMDBdID0gMQorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbVsweDFfMDAwMF8wMDAwXzAwMDBfMDAwMF0gPSAxCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG1bLTFdID0gMQorICAgICAgZW5kCisKKyAgICAgIG0gPSBHb29nbGU6OlByb3RvYnVmOjpNYXAubmV3KDpib29sLCA6aW50MzIpCisgICAgICBtW3RydWVdID0gMQorICAgICAgbVtmYWxzZV0gPSAyCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG1bMV0gPSAxCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbVsiYXNkZiJdID0gMQorICAgICAgZW5kCisKKyAgICAgIG0gPSBHb29nbGU6OlByb3RvYnVmOjpNYXAubmV3KDpzdHJpbmcsIDppbnQzMikKKyAgICAgIG1bImFzZGYiXSA9IDEKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbVsxXSA9IDEKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBieXRlc3RyaW5nID0gWyJGRkZGIl0ucGFjaygiSCoiKQorICAgICAgICBtW2J5dGVzdHJpbmddID0gMQorICAgICAgZW5kCisKKyAgICAgIG0gPSBHb29nbGU6OlByb3RvYnVmOjpNYXAubmV3KDpieXRlcywgOmludDMyKQorICAgICAgYnl0ZXN0cmluZyA9IFsiRkZGRiJdLnBhY2soIkgqIikKKyAgICAgIG1bYnl0ZXN0cmluZ10gPSAxCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG1bImFzZGYiXSA9IDEKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBtWzFdID0gMQorICAgICAgZW5kCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9tYXBfbXNnX2VudW1fdmFsdWV0eXBlcworICAgICAgbSA9IEdvb2dsZTo6UHJvdG9idWY6Ok1hcC5uZXcoOnN0cmluZywgOm1lc3NhZ2UsIFRlc3RNZXNzYWdlKQorICAgICAgbVsiYXNkZiJdID0gVGVzdE1lc3NhZ2UubmV3CisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG1bImprbDsiXSA9IFRlc3RNZXNzYWdlMi5uZXcKKyAgICAgIGVuZAorCisgICAgICBtID0gR29vZ2xlOjpQcm90b2J1Zjo6TWFwLm5ldygKKyAgICAgICAgOnN0cmluZywgOm1lc3NhZ2UsIFRlc3RNZXNzYWdlLAorICAgICAgICB7ICJhIiA9PiBUZXN0TWVzc2FnZS5uZXcoOm9wdGlvbmFsX2ludDMyID0+IDQyKSwKKyAgICAgICAgICAiYiIgPT4gVGVzdE1lc3NhZ2UubmV3KDpvcHRpb25hbF9pbnQzMiA9PiA4NCkgfSkKKyAgICAgIGFzc2VydCBtLmxlbmd0aCA9PSAyCisgICAgICBhc3NlcnQgbS52YWx1ZXMubWFwe3xtc2d8IG1zZy5vcHRpb25hbF9pbnQzMn0uc29ydCA9PSBbNDIsIDg0XQorCisgICAgICBtID0gR29vZ2xlOjpQcm90b2J1Zjo6TWFwLm5ldyg6c3RyaW5nLCA6ZW51bSwgVGVzdEVudW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJ4IiA9PiA6QSwgInkiID0+IDpCLCAieiIgPT4gOkMgfSkKKyAgICAgIGFzc2VydCBtLmxlbmd0aCA9PSAzCisgICAgICBhc3NlcnQgbVsieiJdID09IDpDCisgICAgICBtWyJ6Il0gPSAyCisgICAgICBhc3NlcnQgbVsieiJdID09IDpCCisgICAgICBtWyJ6Il0gPSA0CisgICAgICBhc3NlcnQgbVsieiJdID09IDQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG1bInoiXSA9IDpaCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgbVsieiJdID0gInoiCisgICAgICBlbmQKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X21hcF9kdXBfZGVlcF9jb3B5CisgICAgICBtID0gR29vZ2xlOjpQcm90b2J1Zjo6TWFwLm5ldygKKyAgICAgICAgOnN0cmluZywgOm1lc3NhZ2UsIFRlc3RNZXNzYWdlLAorICAgICAgICB7ICJhIiA9PiBUZXN0TWVzc2FnZS5uZXcoOm9wdGlvbmFsX2ludDMyID0+IDQyKSwKKyAgICAgICAgICAiYiIgPT4gVGVzdE1lc3NhZ2UubmV3KDpvcHRpb25hbF9pbnQzMiA9PiA4NCkgfSkKKworICAgICAgbTIgPSBtLmR1cAorICAgICAgYXNzZXJ0IG0gPT0gbTIKKyAgICAgIGFzc2VydCBtLm9iamVjdF9pZCAhPSBtMi5vYmplY3RfaWQKKyAgICAgIGFzc2VydCBtWyJhIl0ub2JqZWN0X2lkID09IG0yWyJhIl0ub2JqZWN0X2lkCisgICAgICBhc3NlcnQgbVsiYiJdLm9iamVjdF9pZCA9PSBtMlsiYiJdLm9iamVjdF9pZAorCisgICAgICBtMiA9IEdvb2dsZTo6UHJvdG9idWYuZGVlcF9jb3B5KG0pCisgICAgICBhc3NlcnQgbSA9PSBtMgorICAgICAgYXNzZXJ0IG0ub2JqZWN0X2lkICE9IG0yLm9iamVjdF9pZAorICAgICAgYXNzZXJ0IG1bImEiXS5vYmplY3RfaWQgIT0gbTJbImEiXS5vYmplY3RfaWQKKyAgICAgIGFzc2VydCBtWyJiIl0ub2JqZWN0X2lkICE9IG0yWyJiIl0ub2JqZWN0X2lkCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9tYXBfZmllbGQKKyAgICAgIG0gPSBNYXBNZXNzYWdlLm5ldworICAgICAgYXNzZXJ0IG0ubWFwX3N0cmluZ19pbnQzMiA9PSB7fQorICAgICAgYXNzZXJ0IG0ubWFwX3N0cmluZ19tc2cgPT0ge30KKworICAgICAgbSA9IE1hcE1lc3NhZ2UubmV3KAorICAgICAgICA6bWFwX3N0cmluZ19pbnQzMiA9PiB7ImEiID0+IDEsICJiIiA9PiAyfSwKKyAgICAgICAgOm1hcF9zdHJpbmdfbXNnID0+IHsiYSIgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiIiA9PiBUZXN0TWVzc2FnZTIubmV3KDpmb28gPT4gMil9KQorICAgICAgYXNzZXJ0IG0ubWFwX3N0cmluZ19pbnQzMi5rZXlzLnNvcnQgPT0gWyJhIiwgImIiXQorICAgICAgYXNzZXJ0IG0ubWFwX3N0cmluZ19pbnQzMlsiYSJdID09IDEKKyAgICAgIGFzc2VydCBtLm1hcF9zdHJpbmdfbXNnWyJiIl0uZm9vID09IDIKKworICAgICAgbS5tYXBfc3RyaW5nX2ludDMyWyJjIl0gPSAzCisgICAgICBhc3NlcnQgbS5tYXBfc3RyaW5nX2ludDMyWyJjIl0gPT0gMworICAgICAgbS5tYXBfc3RyaW5nX21zZ1siYyJdID0gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDMpCisgICAgICBhc3NlcnQgbS5tYXBfc3RyaW5nX21zZ1siYyJdID09IFRlc3RNZXNzYWdlMi5uZXcoOmZvbyA9PiAzKQorICAgICAgbS5tYXBfc3RyaW5nX21zZy5kZWxldGUoImIiKQorICAgICAgbS5tYXBfc3RyaW5nX21zZy5kZWxldGUoImMiKQorICAgICAgYXNzZXJ0IG0ubWFwX3N0cmluZ19tc2cgPT0geyAiYSIgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDEpIH0KKworICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBtLm1hcF9zdHJpbmdfbXNnWyJlIl0gPSBUZXN0TWVzc2FnZS5uZXcgIyB3cm9uZyB2YWx1ZSB0eXBlCisgICAgICBlbmQKKyAgICAgICMgZW5zdXJlIG5vdGhpbmcgd2FzIGFkZGVkIGJ5IHRoZSBhYm92ZQorICAgICAgYXNzZXJ0IG0ubWFwX3N0cmluZ19tc2cgPT0geyAiYSIgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDEpIH0KKworICAgICAgbS5tYXBfc3RyaW5nX2ludDMyID0gR29vZ2xlOjpQcm90b2J1Zjo6TWFwLm5ldyg6c3RyaW5nLCA6aW50MzIpCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG0ubWFwX3N0cmluZ19pbnQzMiA9IEdvb2dsZTo6UHJvdG9idWY6Ok1hcC5uZXcoOnN0cmluZywgOmludDY0KQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgVHlwZUVycm9yIGRvCisgICAgICAgIG0ubWFwX3N0cmluZ19pbnQzMiA9IHt9CisgICAgICBlbmQKKworICAgICAgYXNzZXJ0X3JhaXNlIFR5cGVFcnJvciBkbworICAgICAgICBtID0gTWFwTWVzc2FnZS5uZXcoOm1hcF9zdHJpbmdfaW50MzIgPT4geyAxID0+ICJJIGFtIG5vdCBhIG51bWJlciIgfSkKKyAgICAgIGVuZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfbWFwX2VuY29kZV9kZWNvZGUKKyAgICAgIG0gPSBNYXBNZXNzYWdlLm5ldygKKyAgICAgICAgOm1hcF9zdHJpbmdfaW50MzIgPT4geyJhIiA9PiAxLCAiYiIgPT4gMn0sCisgICAgICAgIDptYXBfc3RyaW5nX21zZyA9PiB7ImEiID0+IFRlc3RNZXNzYWdlMi5uZXcoOmZvbyA9PiAxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYiIgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDIpfSkKKyAgICAgIG0yID0gTWFwTWVzc2FnZS5kZWNvZGUoTWFwTWVzc2FnZS5lbmNvZGUobSkpCisgICAgICBhc3NlcnQgbSA9PSBtMgorCisgICAgICBtMyA9IE1hcE1lc3NhZ2VXaXJlRXF1aXYuZGVjb2RlKE1hcE1lc3NhZ2UuZW5jb2RlKG0pKQorICAgICAgYXNzZXJ0IG0zLm1hcF9zdHJpbmdfaW50MzIubGVuZ3RoID09IDIKKworICAgICAga3YgPSB7fQorICAgICAgbTMubWFwX3N0cmluZ19pbnQzMi5tYXAgeyB8bXNnfCBrdlttc2cua2V5XSA9IG1zZy52YWx1ZSB9CisgICAgICBhc3NlcnQga3YgPT0geyJhIiA9PiAxLCAiYiIgPT4gMn0KKworICAgICAga3YgPSB7fQorICAgICAgbTMubWFwX3N0cmluZ19tc2cubWFwIHsgfG1zZ3wga3ZbbXNnLmtleV0gPSBtc2cudmFsdWUgfQorICAgICAgYXNzZXJ0IGt2ID09IHsiYSIgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDEpLAorICAgICAgICAgICAgICAgICAgICAiYiIgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDIpfQorICAgIGVuZAorCisgICAgZGVmIHRlc3Rfb25lb2ZfZGVzY3JpcHRvcnMKKyAgICAgIGQgPSBPbmVvZk1lc3NhZ2UuZGVzY3JpcHRvcgorICAgICAgbyA9IGQubG9va3VwX29uZW9mKCJteV9vbmVvZiIpCisgICAgICBhc3NlcnQgbyAhPSBuaWwKKyAgICAgIGFzc2VydCBvLmNsYXNzID09IEdvb2dsZTo6UHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvcgorICAgICAgYXNzZXJ0IG8ubmFtZSA9PSAibXlfb25lb2YiCisgICAgICBvbmVvZl9jb3VudCA9IDAKKyAgICAgIGQuZWFjaF9vbmVvZnsgfG9uZW9mfAorICAgICAgICBvbmVvZl9jb3VudCArPSAxCisgICAgICAgIGFzc2VydCBvbmVvZiA9PSBvCisgICAgICB9CisgICAgICBhc3NlcnQgb25lb2ZfY291bnQgPT0gMQorICAgICAgYXNzZXJ0IG8uY291bnQgPT0gNAorICAgICAgZmllbGRfbmFtZXMgPSBvLm1hcHt8ZnwgZi5uYW1lfS5zb3J0CisgICAgICBhc3NlcnQgZmllbGRfbmFtZXMgPT0gWyJhIiwgImIiLCAiYyIsICJkIl0KKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X29uZW9mCisgICAgICBkID0gT25lb2ZNZXNzYWdlLm5ldworICAgICAgYXNzZXJ0IGQuYSA9PSBuaWwKKyAgICAgIGFzc2VydCBkLmIgPT0gbmlsCisgICAgICBhc3NlcnQgZC5jID09IG5pbAorICAgICAgYXNzZXJ0IGQuZCA9PSBuaWwKKyAgICAgIGFzc2VydCBkLm15X29uZW9mID09IG5pbAorCisgICAgICBkLmEgPSAiaGkiCisgICAgICBhc3NlcnQgZC5hID09ICJoaSIKKyAgICAgIGFzc2VydCBkLmIgPT0gbmlsCisgICAgICBhc3NlcnQgZC5jID09IG5pbAorICAgICAgYXNzZXJ0IGQuZCA9PSBuaWwKKyAgICAgIGFzc2VydCBkLm15X29uZW9mID09IDphCisKKyAgICAgIGQuYiA9IDQyCisgICAgICBhc3NlcnQgZC5hID09IG5pbAorICAgICAgYXNzZXJ0IGQuYiA9PSA0MgorICAgICAgYXNzZXJ0IGQuYyA9PSBuaWwKKyAgICAgIGFzc2VydCBkLmQgPT0gbmlsCisgICAgICBhc3NlcnQgZC5teV9vbmVvZiA9PSA6YgorCisgICAgICBkLmMgPSBUZXN0TWVzc2FnZTIubmV3KDpmb28gPT4gMTAwKQorICAgICAgYXNzZXJ0IGQuYSA9PSBuaWwKKyAgICAgIGFzc2VydCBkLmIgPT0gbmlsCisgICAgICBhc3NlcnQgZC5jLmZvbyA9PSAxMDAKKyAgICAgIGFzc2VydCBkLmQgPT0gbmlsCisgICAgICBhc3NlcnQgZC5teV9vbmVvZiA9PSA6YworCisgICAgICBkLmQgPSA6QworICAgICAgYXNzZXJ0IGQuYSA9PSBuaWwKKyAgICAgIGFzc2VydCBkLmIgPT0gbmlsCisgICAgICBhc3NlcnQgZC5jID09IG5pbAorICAgICAgYXNzZXJ0IGQuZCA9PSA6QworICAgICAgYXNzZXJ0IGQubXlfb25lb2YgPT0gOmQKKworICAgICAgZDIgPSBPbmVvZk1lc3NhZ2UuZGVjb2RlKE9uZW9mTWVzc2FnZS5lbmNvZGUoZCkpCisgICAgICBhc3NlcnQgZDIgPT0gZAorCisgICAgICBlbmNvZGVkX2ZpZWxkX2EgPSBPbmVvZk1lc3NhZ2UuZW5jb2RlKE9uZW9mTWVzc2FnZS5uZXcoOmEgPT4gInN0cmluZyIpKQorICAgICAgZW5jb2RlZF9maWVsZF9iID0gT25lb2ZNZXNzYWdlLmVuY29kZShPbmVvZk1lc3NhZ2UubmV3KDpiID0+IDEwMDApKQorICAgICAgZW5jb2RlZF9maWVsZF9jID0gT25lb2ZNZXNzYWdlLmVuY29kZSgKKyAgICAgICAgT25lb2ZNZXNzYWdlLm5ldyg6YyA9PiBUZXN0TWVzc2FnZTIubmV3KDpmb28gPT4gMSkpKQorICAgICAgZW5jb2RlZF9maWVsZF9kID0gT25lb2ZNZXNzYWdlLmVuY29kZShPbmVvZk1lc3NhZ2UubmV3KDpkID0+IDpCKSkKKworICAgICAgZDMgPSBPbmVvZk1lc3NhZ2UuZGVjb2RlKAorICAgICAgICBlbmNvZGVkX2ZpZWxkX2MgKyBlbmNvZGVkX2ZpZWxkX2EgKyBlbmNvZGVkX2ZpZWxkX2QpCisgICAgICBhc3NlcnQgZDMuYSA9PSBuaWwKKyAgICAgIGFzc2VydCBkMy5iID09IG5pbAorICAgICAgYXNzZXJ0IGQzLmMgPT0gbmlsCisgICAgICBhc3NlcnQgZDMuZCA9PSA6QgorCisgICAgICBkNCA9IE9uZW9mTWVzc2FnZS5kZWNvZGUoCisgICAgICAgIGVuY29kZWRfZmllbGRfYyArIGVuY29kZWRfZmllbGRfYSArIGVuY29kZWRfZmllbGRfZCArCisgICAgICAgIGVuY29kZWRfZmllbGRfYykKKyAgICAgIGFzc2VydCBkNC5hID09IG5pbAorICAgICAgYXNzZXJ0IGQ0LmIgPT0gbmlsCisgICAgICBhc3NlcnQgZDQuYy5mb28gPT0gMQorICAgICAgYXNzZXJ0IGQ0LmQgPT0gbmlsCisKKyAgICAgIGQ1ID0gT25lb2ZNZXNzYWdlLm5ldyg6YSA9PiAiaGVsbG8iKQorICAgICAgYXNzZXJ0IGQ1LmEgIT0gbmlsCisgICAgICBkNS5hID0gbmlsCisgICAgICBhc3NlcnQgZDUuYSA9PSBuaWwKKyAgICAgIGFzc2VydCBPbmVvZk1lc3NhZ2UuZW5jb2RlKGQ1KSA9PSAnJworICAgICAgYXNzZXJ0IGQ1Lm15X29uZW9mID09IG5pbAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfZW51bV9maWVsZAorICAgICAgbSA9IFRlc3RNZXNzYWdlLm5ldworICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfZW51bSA9PSA6RGVmYXVsdAorICAgICAgbS5vcHRpb25hbF9lbnVtID0gOkEKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2VudW0gPT0gOkEKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfZW51bSA9IDpBU0RGCisgICAgICBlbmQKKyAgICAgIG0ub3B0aW9uYWxfZW51bSA9IDEKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2VudW0gPT0gOkEKKyAgICAgIG0ub3B0aW9uYWxfZW51bSA9IDEwMAorICAgICAgYXNzZXJ0IG0ub3B0aW9uYWxfZW51bSA9PSAxMDAKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X2R1cAorICAgICAgbSA9IFRlc3RNZXNzYWdlLm5ldworICAgICAgbS5vcHRpb25hbF9zdHJpbmcgPSAiaGVsbG8iCisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gNDIKKyAgICAgIG0ucmVwZWF0ZWRfbXNnLnB1c2ggVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDEwMCkKKyAgICAgIG0ucmVwZWF0ZWRfbXNnLnB1c2ggVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDIwMCkKKworICAgICAgbTIgPSBtLmR1cAorICAgICAgYXNzZXJ0IG0gPT0gbTIKKyAgICAgIG0ub3B0aW9uYWxfaW50MzIgKz0gMQorICAgICAgYXNzZXJ0IG0gIT0gbTIKKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX21zZ1swXSA9PSBtMi5yZXBlYXRlZF9tc2dbMF0KKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX21zZ1swXS5vYmplY3RfaWQgPT0gbTIucmVwZWF0ZWRfbXNnWzBdLm9iamVjdF9pZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfZGVlcF9jb3B5CisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3KDpvcHRpb25hbF9pbnQzMiA9PiA0MiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOnJlcGVhdGVkX21zZyA9PiBbVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDEwMCldKQorICAgICAgbTIgPSBHb29nbGU6OlByb3RvYnVmLmRlZXBfY29weShtKQorICAgICAgYXNzZXJ0IG0gPT0gbTIKKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX21zZyA9PSBtMi5yZXBlYXRlZF9tc2cKKyAgICAgIGFzc2VydCBtLnJlcGVhdGVkX21zZy5vYmplY3RfaWQgIT0gbTIucmVwZWF0ZWRfbXNnLm9iamVjdF9pZAorICAgICAgYXNzZXJ0IG0ucmVwZWF0ZWRfbXNnWzBdLm9iamVjdF9pZCAhPSBtMi5yZXBlYXRlZF9tc2dbMF0ub2JqZWN0X2lkCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9lcQorICAgICAgbSA9IFRlc3RNZXNzYWdlLm5ldyg6b3B0aW9uYWxfaW50MzIgPT4gNDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpyZXBlYXRlZF9pbnQzMiA9PiBbMSwgMiwgM10pCisgICAgICBtMiA9IFRlc3RNZXNzYWdlLm5ldyg6b3B0aW9uYWxfaW50MzIgPT4gNDMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICA6cmVwZWF0ZWRfaW50MzIgPT4gWzEsIDIsIDNdKQorICAgICAgYXNzZXJ0IG0gIT0gbTIKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X2VudW1fbG9va3VwCisgICAgICBhc3NlcnQgVGVzdEVudW06OkEgPT0gMQorICAgICAgYXNzZXJ0IFRlc3RFbnVtOjpCID09IDIKKyAgICAgIGFzc2VydCBUZXN0RW51bTo6QyA9PSAzCisKKyAgICAgIGFzc2VydCBUZXN0RW51bTo6bG9va3VwKDEpID09IDpBCisgICAgICBhc3NlcnQgVGVzdEVudW06Omxvb2t1cCgyKSA9PSA6QgorICAgICAgYXNzZXJ0IFRlc3RFbnVtOjpsb29rdXAoMykgPT0gOkMKKworICAgICAgYXNzZXJ0IFRlc3RFbnVtOjpyZXNvbHZlKDpBKSA9PSAxCisgICAgICBhc3NlcnQgVGVzdEVudW06OnJlc29sdmUoOkIpID09IDIKKyAgICAgIGFzc2VydCBUZXN0RW51bTo6cmVzb2x2ZSg6QykgPT0gMworICAgIGVuZAorCisgICAgZGVmIHRlc3RfcGFyc2Vfc2VyaWFsaXplCisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3KDpvcHRpb25hbF9pbnQzMiA9PiA0MiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOm9wdGlvbmFsX3N0cmluZyA9PiAiaGVsbG8gd29ybGQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfZW51bSA9PiA6QiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOnJlcGVhdGVkX3N0cmluZyA9PiBbImEiLCAiYiIsICJjIl0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpyZXBlYXRlZF9pbnQzMiA9PiBbNDIsIDQzLCA0NF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpyZXBlYXRlZF9lbnVtID0+IFs6QSwgOkIsIDpDLCAxMDBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6cmVwZWF0ZWRfbXNnID0+IFtUZXN0TWVzc2FnZTIubmV3KDpmb28gPT4gMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RNZXNzYWdlMi5uZXcoOmZvbyA9PiAyKV0pCisgICAgICBkYXRhID0gVGVzdE1lc3NhZ2UuZW5jb2RlIG0KKyAgICAgIG0yID0gVGVzdE1lc3NhZ2UuZGVjb2RlIGRhdGEKKyAgICAgIGFzc2VydCBtID09IG0yCisKKyAgICAgIGRhdGEgPSBHb29nbGU6OlByb3RvYnVmLmVuY29kZSBtCisgICAgICBtMiA9IEdvb2dsZTo6UHJvdG9idWYuZGVjb2RlKFRlc3RNZXNzYWdlLCBkYXRhKQorICAgICAgYXNzZXJ0IG0gPT0gbTIKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X2RlZl9lcnJvcnMKKyAgICAgIHMgPSBHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5uZXcKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgcy5idWlsZCBkbworICAgICAgICAgICMgZW51bSB3aXRoIG5vIGRlZmF1bHQgKGludGVnZXIgdmFsdWUgMCkKKyAgICAgICAgICBhZGRfZW51bSAiTXlFbnVtIiBkbworICAgICAgICAgICAgdmFsdWUgOkEsIDEKKyAgICAgICAgICBlbmQKKyAgICAgICAgZW5kCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBUeXBlRXJyb3IgZG8KKyAgICAgICAgcy5idWlsZCBkbworICAgICAgICAgICMgbWVzc2FnZSB3aXRoIHJlcXVpcmVkIGZpZWxkICh1bnN1cHBvcnRlZCBpbiBwcm90bzMpCisgICAgICAgICAgYWRkX21lc3NhZ2UgIk15TWVzc2FnZSIgZG8KKyAgICAgICAgICAgIHJlcXVpcmVkIDpmb28sIDppbnQzMiwgMQorICAgICAgICAgIGVuZAorICAgICAgICBlbmQKKyAgICAgIGVuZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfY29yZWN1cnNpdmUKKyAgICAgICMganVzdCBiZSBzdXJlIHRoYXQgd2UgY2FuIGluc3RhbnRpYXRlIHR5cGVzIHdpdGggY29yZWN1cnNpdmUgZmllbGQtdHlwZQorICAgICAgIyByZWZlcmVuY2VzLgorICAgICAgbSA9IFJlY3Vyc2l2ZTEubmV3KDpmb28gPT4gUmVjdXJzaXZlMi5uZXcoOmZvbyA9PiBSZWN1cnNpdmUxLm5ldykpCisgICAgICBhc3NlcnQgUmVjdXJzaXZlMS5kZXNjcmlwdG9yLmxvb2t1cCgiZm9vIikuc3VidHlwZSA9PQorICAgICAgICBSZWN1cnNpdmUyLmRlc2NyaXB0b3IKKyAgICAgIGFzc2VydCBSZWN1cnNpdmUyLmRlc2NyaXB0b3IubG9va3VwKCJmb28iKS5zdWJ0eXBlID09CisgICAgICAgIFJlY3Vyc2l2ZTEuZGVzY3JpcHRvcgorCisgICAgICBzZXJpYWxpemVkID0gUmVjdXJzaXZlMS5lbmNvZGUobSkKKyAgICAgIG0yID0gUmVjdXJzaXZlMS5kZWNvZGUoc2VyaWFsaXplZCkKKyAgICAgIGFzc2VydCBtID09IG0yCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9zZXJpYWxpemVfY3ljbGUKKyAgICAgIG0gPSBSZWN1cnNpdmUxLm5ldyg6Zm9vID0+IFJlY3Vyc2l2ZTIubmV3KQorICAgICAgbS5mb28uZm9vID0gbQorICAgICAgYXNzZXJ0X3JhaXNlIFJ1bnRpbWVFcnJvciBkbworICAgICAgICBzZXJpYWxpemVkID0gUmVjdXJzaXZlMS5lbmNvZGUobSkKKyAgICAgIGVuZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfYmFkX2ZpZWxkX25hbWVzCisgICAgICBtID0gQmFkRmllbGROYW1lcy5uZXcoOmR1cCA9PiAxLCA6Y2xhc3MgPT4gMikKKyAgICAgIG0yID0gbS5kdXAKKyAgICAgIGFzc2VydCBtID09IG0yCisgICAgICBhc3NlcnQgbVsnZHVwJ10gPT0gMQorICAgICAgYXNzZXJ0IG1bJ2NsYXNzJ10gPT0gMgorICAgICAgbVsnZHVwJ10gPSAzCisgICAgICBhc3NlcnQgbVsnZHVwJ10gPT0gMworICAgICAgbVsnYS5iJ10gPSA0CisgICAgICBhc3NlcnQgbVsnYS5iJ10gPT0gNAorICAgIGVuZAorCisKKyAgICBkZWYgdGVzdF9pbnRfcmFuZ2VzCisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3CisKKyAgICAgIG0ub3B0aW9uYWxfaW50MzIgPSAwCisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gLTB4ODAwMF8wMDAwCisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gKzB4N2ZmZl9mZmZmCisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gMS4wCisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gLTEuMAorICAgICAgbS5vcHRpb25hbF9pbnQzMiA9IDJlOQorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9pbnQzMiA9IC0weDgwMDBfMDAwMQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX2ludDMyID0gKzB4ODAwMF8wMDAwCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfaW50MzIgPSArMHgxMDAwXzAwMDBfMDAwMF8wMDAwXzAwMDBfMDAwMCAjIGZvcmNlIEJpZ251bQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX2ludDMyID0gMWUxMgorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX2ludDMyID0gMS41CisgICAgICBlbmQKKworICAgICAgbS5vcHRpb25hbF91aW50MzIgPSAwCisgICAgICBtLm9wdGlvbmFsX3VpbnQzMiA9ICsweGZmZmZfZmZmZgorICAgICAgbS5vcHRpb25hbF91aW50MzIgPSAxLjAKKyAgICAgIG0ub3B0aW9uYWxfdWludDMyID0gNGU5CisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQzMiA9IC0xCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfdWludDMyID0gLTEuNQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQzMiA9IC0xLjVlMTIKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF91aW50MzIgPSAtMHgxMDAwXzAwMDBfMDAwMF8wMDAwCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfdWludDMyID0gKzB4MV8wMDAwXzAwMDAKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF91aW50MzIgPSArMHgxMDAwXzAwMDBfMDAwMF8wMDAwXzAwMDBfMDAwMCAjIGZvcmNlIEJpZ251bQorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQzMiA9IDFlMTIKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF91aW50MzIgPSAxLjUKKyAgICAgIGVuZAorCisgICAgICBtLm9wdGlvbmFsX2ludDY0ID0gMAorICAgICAgbS5vcHRpb25hbF9pbnQ2NCA9IC0weDgwMDBfMDAwMF8wMDAwXzAwMDAKKyAgICAgIG0ub3B0aW9uYWxfaW50NjQgPSArMHg3ZmZmX2ZmZmZfZmZmZl9mZmZmCisgICAgICBtLm9wdGlvbmFsX2ludDY0ID0gMS4wCisgICAgICBtLm9wdGlvbmFsX2ludDY0ID0gLTEuMAorICAgICAgbS5vcHRpb25hbF9pbnQ2NCA9IDhlMTgKKyAgICAgIG0ub3B0aW9uYWxfaW50NjQgPSAtOGUxOAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9pbnQ2NCA9IC0weDgwMDBfMDAwMF8wMDAwXzAwMDEKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9pbnQ2NCA9ICsweDgwMDBfMDAwMF8wMDAwXzAwMDAKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF9pbnQ2NCA9ICsweDEwMDBfMDAwMF8wMDAwXzAwMDBfMDAwMF8wMDAwICMgZm9yY2UgQmlnbnVtCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfaW50NjQgPSAxZTUwCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfaW50NjQgPSAxLjUKKyAgICAgIGVuZAorCisgICAgICBtLm9wdGlvbmFsX3VpbnQ2NCA9IDAKKyAgICAgIG0ub3B0aW9uYWxfdWludDY0ID0gKzB4ZmZmZl9mZmZmX2ZmZmZfZmZmZgorICAgICAgbS5vcHRpb25hbF91aW50NjQgPSAxLjAKKyAgICAgIG0ub3B0aW9uYWxfdWludDY0ID0gMTZlMTgKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfdWludDY0ID0gLTEKKyAgICAgIGVuZAorICAgICAgYXNzZXJ0X3JhaXNlIFJhbmdlRXJyb3IgZG8KKyAgICAgICAgbS5vcHRpb25hbF91aW50NjQgPSAtMS41CisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfdWludDY0ID0gLTEuNWUxMgorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQ2NCA9IC0weDFfMDAwMF8wMDAwXzAwMDBfMDAwMAorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQ2NCA9ICsweDFfMDAwMF8wMDAwXzAwMDBfMDAwMAorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQ2NCA9ICsweDEwMDBfMDAwMF8wMDAwXzAwMDBfMDAwMF8wMDAwICMgZm9yY2UgQmlnbnVtCisgICAgICBlbmQKKyAgICAgIGFzc2VydF9yYWlzZSBSYW5nZUVycm9yIGRvCisgICAgICAgIG0ub3B0aW9uYWxfdWludDY0ID0gMWU1MAorICAgICAgZW5kCisgICAgICBhc3NlcnRfcmFpc2UgUmFuZ2VFcnJvciBkbworICAgICAgICBtLm9wdGlvbmFsX3VpbnQ2NCA9IDEuNQorICAgICAgZW5kCisKKyAgICBlbmQKKworICAgIGRlZiB0ZXN0X3N0cmVzc190ZXN0CisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3CisgICAgICBtLm9wdGlvbmFsX2ludDMyID0gNDIKKyAgICAgIG0ub3B0aW9uYWxfaW50NjQgPSAweDEwMDAwMDAwMAorICAgICAgbS5vcHRpb25hbF9zdHJpbmcgPSAiaGVsbG8gd29ybGQiCisgICAgICAxMC50aW1lcyBkbyBtLnJlcGVhdGVkX21zZy5wdXNoIFRlc3RNZXNzYWdlMi5uZXcoOmZvbyA9PiA0MikgZW5kCisgICAgICAxMC50aW1lcyBkbyBtLnJlcGVhdGVkX3N0cmluZy5wdXNoICJoZWxsbyB3b3JsZCIgZW5kCisKKyAgICAgIGRhdGEgPSBUZXN0TWVzc2FnZS5lbmNvZGUobSkKKworICAgICAgbCA9IDAKKyAgICAgIDEwXzAwMC50aW1lcyBkbworICAgICAgICBtID0gVGVzdE1lc3NhZ2UuZGVjb2RlKGRhdGEpCisgICAgICAgIGRhdGFfbmV3ID0gVGVzdE1lc3NhZ2UuZW5jb2RlKG0pCisgICAgICAgIGFzc2VydCBkYXRhX25ldyA9PSBkYXRhCisgICAgICAgIGRhdGEgPSBkYXRhX25ldworICAgICAgZW5kCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9yZWZsZWN0aW9uCisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3KDpvcHRpb25hbF9pbnQzMiA9PiAxMjM0KQorICAgICAgbXNnZGVmID0gbS5jbGFzcy5kZXNjcmlwdG9yCisgICAgICBhc3NlcnQgbXNnZGVmLmNsYXNzID09IEdvb2dsZTo6UHJvdG9idWY6OkRlc2NyaXB0b3IKKyAgICAgIGFzc2VydCBtc2dkZWYuYW55PyB7fGZpZWxkfCBmaWVsZC5uYW1lID09ICJvcHRpb25hbF9pbnQzMiJ9CisgICAgICBvcHRpb25hbF9pbnQzMiA9IG1zZ2RlZi5sb29rdXAgIm9wdGlvbmFsX2ludDMyIgorICAgICAgYXNzZXJ0IG9wdGlvbmFsX2ludDMyLmNsYXNzID09IEdvb2dsZTo6UHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcgorICAgICAgYXNzZXJ0IG9wdGlvbmFsX2ludDMyICE9IG5pbAorICAgICAgYXNzZXJ0IG9wdGlvbmFsX2ludDMyLm5hbWUgPT0gIm9wdGlvbmFsX2ludDMyIgorICAgICAgYXNzZXJ0IG9wdGlvbmFsX2ludDMyLnR5cGUgPT0gOmludDMyCisgICAgICBvcHRpb25hbF9pbnQzMi5zZXQobSwgNTY3OCkKKyAgICAgIGFzc2VydCBtLm9wdGlvbmFsX2ludDMyID09IDU2NzgKKyAgICAgIG0ub3B0aW9uYWxfaW50MzIgPSAxMDAwCisgICAgICBhc3NlcnQgb3B0aW9uYWxfaW50MzIuZ2V0KG0pID09IDEwMDAKKworICAgICAgb3B0aW9uYWxfbXNnID0gbXNnZGVmLmxvb2t1cCAib3B0aW9uYWxfbXNnIgorICAgICAgYXNzZXJ0IG9wdGlvbmFsX21zZy5zdWJ0eXBlID09IFRlc3RNZXNzYWdlMi5kZXNjcmlwdG9yCisKKyAgICAgIG9wdGlvbmFsX21zZy5zZXQobSwgb3B0aW9uYWxfbXNnLnN1YnR5cGUubXNnY2xhc3MubmV3KQorCisgICAgICBhc3NlcnQgbXNnZGVmLm1zZ2NsYXNzID09IFRlc3RNZXNzYWdlCisKKyAgICAgIG9wdGlvbmFsX2VudW0gPSBtc2dkZWYubG9va3VwICJvcHRpb25hbF9lbnVtIgorICAgICAgYXNzZXJ0IG9wdGlvbmFsX2VudW0uc3VidHlwZSA9PSBUZXN0RW51bS5kZXNjcmlwdG9yCisgICAgICBhc3NlcnQgb3B0aW9uYWxfZW51bS5zdWJ0eXBlLmNsYXNzID09IEdvb2dsZTo6UHJvdG9idWY6OkVudW1EZXNjcmlwdG9yCisgICAgICBvcHRpb25hbF9lbnVtLnN1YnR5cGUuZWFjaCBkbyB8aywgdnwKKyAgICAgICAgIyBzZXQgd2l0aCBpbnRlZ2VyLCBjaGVjayByZXNvbHV0aW9uIHRvIHN5bWJvbGljIG5hbWUKKyAgICAgICAgb3B0aW9uYWxfZW51bS5zZXQobSwgdikKKyAgICAgICAgYXNzZXJ0IG9wdGlvbmFsX2VudW0uZ2V0KG0pID09IGsKKyAgICAgIGVuZAorICAgIGVuZAorCisgICAgZGVmIHRlc3RfanNvbgorICAgICAgc2tpcCgiVW5pbXBsZW1lbnRlZCIpIGlmIFJVQllfUExBVEZPUk0gPT0gImphdmEiCisgICAgICBtID0gVGVzdE1lc3NhZ2UubmV3KDpvcHRpb25hbF9pbnQzMiA9PiAxMjM0LAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfaW50NjQgPT4gLTB4MV8wMDAwXzAwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpvcHRpb25hbF91aW50MzIgPT4gMHg4MDAwXzAwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpvcHRpb25hbF91aW50NjQgPT4gMHhmZmZmX2ZmZmZfZmZmZl9mZmZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfYm9vbCA9PiB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfZmxvYXQgPT4gMS4wLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfZG91YmxlID0+IC0xZTEwMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOm9wdGlvbmFsX3N0cmluZyA9PiAiVGVzdCBzdHJpbmciLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6b3B0aW9uYWxfYnl0ZXMgPT4gWyJGRkZGRkZGRiJdLnBhY2soJ0gqJyksCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpvcHRpb25hbF9tc2cgPT4gVGVzdE1lc3NhZ2UyLm5ldyg6Zm9vID0+IDQyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOnJlcGVhdGVkX2ludDMyID0+IFsxLCAyLCAzLCA0XSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOnJlcGVhdGVkX3N0cmluZyA9PiBbImEiLCAiYiIsICJjIl0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIDpyZXBlYXRlZF9ib29sID0+IFt0cnVlLCBmYWxzZSwgdHJ1ZSwgZmFsc2VdLAorICAgICAgICAgICAgICAgICAgICAgICAgICA6cmVwZWF0ZWRfbXNnID0+IFtUZXN0TWVzc2FnZTIubmV3KDpmb28gPT4gMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RNZXNzYWdlMi5uZXcoOmZvbyA9PiAyKV0pCisKKyAgICAgIGpzb25fdGV4dCA9IFRlc3RNZXNzYWdlLmVuY29kZV9qc29uKG0pCisgICAgICBtMiA9IFRlc3RNZXNzYWdlLmRlY29kZV9qc29uKGpzb25fdGV4dCkKKyAgICAgIGFzc2VydCBtID09IG0yCisgICAgZW5kCisKKyAgICBkZWYgdGVzdF9qc29uX21hcHMKKyAgICAgIHNraXAoIlVuaW1wbGVtZW50ZWQiKSBpZiBSVUJZX1BMQVRGT1JNID09ICJqYXZhIgorICAgICAgbSA9IE1hcE1lc3NhZ2UubmV3KDptYXBfc3RyaW5nX2ludDMyID0+IHsiYSIgPT4gMX0pCisgICAgICBleHBlY3RlZCA9ICd7Im1hcF9zdHJpbmdfaW50MzIiOnsiYSI6MX0sIm1hcF9zdHJpbmdfbXNnIjp7fX0nCisgICAgICBhc3NlcnQgTWFwTWVzc2FnZS5lbmNvZGVfanNvbihtKSA9PSBleHBlY3RlZAorICAgICAgbTIgPSBNYXBNZXNzYWdlLmRlY29kZV9qc29uKE1hcE1lc3NhZ2UuZW5jb2RlX2pzb24obSkpCisgICAgICBhc3NlcnQgbSA9PSBtMgorICAgIGVuZAorICBlbmQKK2VuZApkaWZmIC0tZ2l0IGEvcnVieS90ZXN0cy9nZW5lcmF0ZWRfY29kZS5wcm90byBiL3J1YnkvdGVzdHMvZ2VuZXJhdGVkX2NvZGUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFkNjMyMwotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvdGVzdHMvZ2VuZXJhdGVkX2NvZGUucHJvdG8KQEAgLTAsMCArMSw2NyBAQAorc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgQS5CLkM7CisKK21lc3NhZ2UgVGVzdE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7CisgIG9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjsKKyAgb3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7CisgIG9wdGlvbmFsIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OworICBvcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2wgPSA1OworICBvcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gNjsKKyAgb3B0aW9uYWwgZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSA3OworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gODsKKyAgb3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSA5OworICBvcHRpb25hbCBUZXN0RW51bSBvcHRpb25hbF9lbnVtID0gMTA7CisgIG9wdGlvbmFsIFRlc3RNZXNzYWdlIG9wdGlvbmFsX21zZyA9IDExOworCisgIHJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7CisgIHJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMjI7CisgIHJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAyMzsKKyAgcmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDI0OworICByZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAyNTsKKyAgcmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDI2OworICByZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI3OworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjg7CisgIHJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjk7CisgIHJlcGVhdGVkIFRlc3RFbnVtIHJlcGVhdGVkX2VudW0gPSAzMDsKKyAgcmVwZWF0ZWQgVGVzdE1lc3NhZ2UgcmVwZWF0ZWRfbXNnID0gMzE7CisKKyAgb25lb2YgbXlfb25lb2YgeworICAgIGludDMyIG9uZW9mX2ludDMyID0gNDE7CisgICAgaW50NjQgb25lb2ZfaW50NjQgPSA0MjsKKyAgICB1aW50MzIgb25lb2ZfdWludDMyID0gNDM7CisgICAgdWludDY0IG9uZW9mX3VpbnQ2NCA9IDQ0OworICAgIGJvb2wgb25lb2ZfYm9vbCA9IDQ1OworICAgIGRvdWJsZSBvbmVvZl9kb3VibGUgPSA0NjsKKyAgICBmbG9hdCBvbmVvZl9mbG9hdCA9IDQ3OworICAgIHN0cmluZyBvbmVvZl9zdHJpbmcgPSA0ODsKKyAgICBieXRlcyBvbmVvZl9ieXRlcyA9IDQ5OworICAgIFRlc3RFbnVtIG9uZW9mX2VudW0gPSA1MDsKKyAgICBUZXN0TWVzc2FnZSBvbmVvZl9tc2cgPSA1MTsKKyAgfQorCisgIG1hcDxpbnQzMiwgc3RyaW5nPiBtYXBfaW50MzJfc3RyaW5nID0gNjE7CisgIG1hcDxpbnQ2NCwgc3RyaW5nPiBtYXBfaW50NjRfc3RyaW5nID0gNjI7CisgIG1hcDx1aW50MzIsIHN0cmluZz4gbWFwX3VpbnQzMl9zdHJpbmcgPSA2MzsKKyAgbWFwPHVpbnQ2NCwgc3RyaW5nPiBtYXBfdWludDY0X3N0cmluZyA9IDY0OworICBtYXA8Ym9vbCwgc3RyaW5nPiBtYXBfYm9vbF9zdHJpbmcgPSA2NTsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtYXBfc3RyaW5nX3N0cmluZyA9IDY2OworICBtYXA8c3RyaW5nLCBUZXN0TWVzc2FnZT4gbWFwX3N0cmluZ19tc2cgPSA2NzsKKyAgbWFwPHN0cmluZywgVGVzdEVudW0+IG1hcF9zdHJpbmdfZW51bSA9IDY4OworICBtYXA8c3RyaW5nLCBpbnQzMj4gbWFwX3N0cmluZ19pbnQzMiA9IDY5OworICBtYXA8c3RyaW5nLCBib29sPiBtYXBfc3RyaW5nX2Jvb2wgPSA3MDsKKworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDMyIGZvbyA9IDE7CisgIH0KKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gODA7Cit9CisKK2VudW0gVGVzdEVudW0geworICBEZWZhdWx0ID0gMDsKKyAgQSA9IDE7CisgIEIgPSAyOworICBDID0gMzsKK30KZGlmZiAtLWdpdCBhL3J1YnkvdGVzdHMvZ2VuZXJhdGVkX2NvZGUucmIgYi9ydWJ5L3Rlc3RzL2dlbmVyYXRlZF9jb2RlLnJiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhNjg1NDMKLS0tIC9kZXYvbnVsbAorKysgYi9ydWJ5L3Rlc3RzL2dlbmVyYXRlZF9jb2RlLnJiCkBAIC0wLDAgKzEsNzQgQEAKKyMgR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKyMgc291cmNlOiBnZW5lcmF0ZWRfY29kZS5wcm90bworCityZXF1aXJlICdnb29nbGUvcHJvdG9idWYnCisKK0dvb2dsZTo6UHJvdG9idWY6OkRlc2NyaXB0b3JQb29sLmdlbmVyYXRlZF9wb29sLmJ1aWxkIGRvCisgIGFkZF9tZXNzYWdlICJBLkIuQy5UZXN0TWVzc2FnZSIgZG8KKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfaW50MzIsIDppbnQzMiwgMQorICAgIG9wdGlvbmFsIDpvcHRpb25hbF9pbnQ2NCwgOmludDY0LCAyCisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX3VpbnQzMiwgOnVpbnQzMiwgMworICAgIG9wdGlvbmFsIDpvcHRpb25hbF91aW50NjQsIDp1aW50NjQsIDQKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfYm9vbCwgOmJvb2wsIDUKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfZG91YmxlLCA6ZG91YmxlLCA2CisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX2Zsb2F0LCA6ZmxvYXQsIDcKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfc3RyaW5nLCA6c3RyaW5nLCA4CisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX2J5dGVzLCA6c3RyaW5nLCA5CisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX2VudW0sIDplbnVtLCAxMCwgIkEuQi5DLlRlc3RFbnVtIgorICAgIG9wdGlvbmFsIDpvcHRpb25hbF9tc2csIDptZXNzYWdlLCAxMSwgIkEuQi5DLlRlc3RNZXNzYWdlIgorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9pbnQzMiwgOmludDMyLCAyMQorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9pbnQ2NCwgOmludDY0LCAyMgorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF91aW50MzIsIDp1aW50MzIsIDIzCisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX3VpbnQ2NCwgOnVpbnQ2NCwgMjQKKyAgICByZXBlYXRlZCA6cmVwZWF0ZWRfYm9vbCwgOmJvb2wsIDI1CisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2RvdWJsZSwgOmRvdWJsZSwgMjYKKyAgICByZXBlYXRlZCA6cmVwZWF0ZWRfZmxvYXQsIDpmbG9hdCwgMjcKKyAgICByZXBlYXRlZCA6cmVwZWF0ZWRfc3RyaW5nLCA6c3RyaW5nLCAyOAorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9ieXRlcywgOnN0cmluZywgMjkKKyAgICByZXBlYXRlZCA6cmVwZWF0ZWRfZW51bSwgOmVudW0sIDMwLCAiQS5CLkMuVGVzdEVudW0iCisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX21zZywgOm1lc3NhZ2UsIDMxLCAiQS5CLkMuVGVzdE1lc3NhZ2UiCisgICAgbWFwIDptYXBfaW50MzJfc3RyaW5nLCA6aW50MzIsIDpzdHJpbmcsIDYxCisgICAgbWFwIDptYXBfaW50NjRfc3RyaW5nLCA6aW50NjQsIDpzdHJpbmcsIDYyCisgICAgbWFwIDptYXBfdWludDMyX3N0cmluZywgOnVpbnQzMiwgOnN0cmluZywgNjMKKyAgICBtYXAgOm1hcF91aW50NjRfc3RyaW5nLCA6dWludDY0LCA6c3RyaW5nLCA2NAorICAgIG1hcCA6bWFwX2Jvb2xfc3RyaW5nLCA6Ym9vbCwgOnN0cmluZywgNjUKKyAgICBtYXAgOm1hcF9zdHJpbmdfc3RyaW5nLCA6c3RyaW5nLCA6c3RyaW5nLCA2NgorICAgIG1hcCA6bWFwX3N0cmluZ19tc2csIDpzdHJpbmcsIDptZXNzYWdlLCA2NywgIkEuQi5DLlRlc3RNZXNzYWdlIgorICAgIG1hcCA6bWFwX3N0cmluZ19lbnVtLCA6c3RyaW5nLCA6ZW51bSwgNjgsICJBLkIuQy5UZXN0RW51bSIKKyAgICBtYXAgOm1hcF9zdHJpbmdfaW50MzIsIDpzdHJpbmcsIDppbnQzMiwgNjkKKyAgICBtYXAgOm1hcF9zdHJpbmdfYm9vbCwgOnN0cmluZywgOmJvb2wsIDcwCisgICAgb3B0aW9uYWwgOm5lc3RlZF9tZXNzYWdlLCA6bWVzc2FnZSwgODAsICJBLkIuQy5UZXN0TWVzc2FnZS5OZXN0ZWRNZXNzYWdlIgorICAgIG9uZW9mIDpteV9vbmVvZiBkbworICAgICAgb3B0aW9uYWwgOm9uZW9mX2ludDMyLCA6aW50MzIsIDQxCisgICAgICBvcHRpb25hbCA6b25lb2ZfaW50NjQsIDppbnQ2NCwgNDIKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl91aW50MzIsIDp1aW50MzIsIDQzCisgICAgICBvcHRpb25hbCA6b25lb2ZfdWludDY0LCA6dWludDY0LCA0NAorICAgICAgb3B0aW9uYWwgOm9uZW9mX2Jvb2wsIDpib29sLCA0NQorICAgICAgb3B0aW9uYWwgOm9uZW9mX2RvdWJsZSwgOmRvdWJsZSwgNDYKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9mbG9hdCwgOmZsb2F0LCA0NworICAgICAgb3B0aW9uYWwgOm9uZW9mX3N0cmluZywgOnN0cmluZywgNDgKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9ieXRlcywgOnN0cmluZywgNDkKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9lbnVtLCA6ZW51bSwgNTAsICJBLkIuQy5UZXN0RW51bSIKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9tc2csIDptZXNzYWdlLCA1MSwgIkEuQi5DLlRlc3RNZXNzYWdlIgorICAgIGVuZAorICBlbmQKKyAgYWRkX21lc3NhZ2UgIkEuQi5DLlRlc3RNZXNzYWdlLk5lc3RlZE1lc3NhZ2UiIGRvCisgICAgb3B0aW9uYWwgOmZvbywgOmludDMyLCAxCisgIGVuZAorICBhZGRfZW51bSAiQS5CLkMuVGVzdEVudW0iIGRvCisgICAgdmFsdWUgOkRlZmF1bHQsIDAKKyAgICB2YWx1ZSA6QSwgMQorICAgIHZhbHVlIDpCLCAyCisgICAgdmFsdWUgOkMsIDMKKyAgZW5kCitlbmQKKworbW9kdWxlIEEKKyAgbW9kdWxlIEIKKyAgICBtb2R1bGUgQworICAgICAgVGVzdE1lc3NhZ2UgPSBHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5nZW5lcmF0ZWRfcG9vbC5sb29rdXAoIkEuQi5DLlRlc3RNZXNzYWdlIikubXNnY2xhc3MKKyAgICAgIFRlc3RNZXNzYWdlOjpOZXN0ZWRNZXNzYWdlID0gR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wubG9va3VwKCJBLkIuQy5UZXN0TWVzc2FnZS5OZXN0ZWRNZXNzYWdlIikubXNnY2xhc3MKKyAgICAgIFRlc3RFbnVtID0gR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wubG9va3VwKCJBLkIuQy5UZXN0RW51bSIpLmVudW1tb2R1bGUKKyAgICBlbmQKKyAgZW5kCitlbmQKZGlmZiAtLWdpdCBhL3J1YnkvdGVzdHMvZ2VuZXJhdGVkX2NvZGVfdGVzdC5yYiBiL3J1YnkvdGVzdHMvZ2VuZXJhdGVkX2NvZGVfdGVzdC5yYgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYWVmMzU3Ci0tLSAvZGV2L251bGwKKysrIGIvcnVieS90ZXN0cy9nZW5lcmF0ZWRfY29kZV90ZXN0LnJiCkBAIC0wLDAgKzEsMTcgQEAKKyMhL3Vzci9iaW4vcnVieQorCisjIGdlbmVyYXRlZF9jb2RlLnJiIGlzIGluIHRoZSBzYW1lIGRpcmVjdG9yeSBhcyB0aGlzIHRlc3QuCiskTE9BRF9QQVRILnVuc2hpZnQoRmlsZS5leHBhbmRfcGF0aChGaWxlLmRpcm5hbWUoX19GSUxFX18pKSkKKworcmVxdWlyZSAnZ2VuZXJhdGVkX2NvZGUnCityZXF1aXJlICd0ZXN0L3VuaXQnCisKK2NsYXNzIEdlbmVyYXRlZENvZGVUZXN0IDwgVGVzdDo6VW5pdDo6VGVzdENhc2UKKyAgZGVmIHRlc3RfZ2VuZXJhdGVkX21zZworICAgICMganVzdCB0ZXN0IHRoYXQgd2UgY2FuIGluc3RhbnRpYXRlIHRoZSBtZXNzYWdlLiBUaGUgcHVycG9zZSBvZiB0aGlzIHRlc3QKKyAgICAjIGlzIHRvIGVuc3VyZSB0aGF0IHRoZSBvdXRwdXQgb2YgdGhlIGNvZGUgZ2VuZXJhdG9yIGlzIHZhbGlkIFJ1YnkgYW5kCisgICAgIyBzdWNjZXNzZnVsbHkgY3JlYXRlcyBtZXNzYWdlIGRlZmluaXRpb25zIGFuZCBjbGFzc2VzLCBub3QgdG8gdGVzdCBldmVyeQorICAgICMgYXNwZWN0IG9mIHRoZSBleHRlbnNpb24gKGJhc2ljLnJiIGlzIGZvciB0aGF0KS4KKyAgICBtID0gQTo6Qjo6Qzo6VGVzdE1lc3NhZ2UubmV3KCkKKyAgZW5kCitlbmQKZGlmZiAtLWdpdCBhL3J1YnkvdGVzdHMvc3RyZXNzLnJiIGIvcnVieS90ZXN0cy9zdHJlc3MucmIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDgyZDVlMgotLS0gL2Rldi9udWxsCisrKyBiL3J1YnkvdGVzdHMvc3RyZXNzLnJiCkBAIC0wLDAgKzEsMzggQEAKKyMhL3Vzci9iaW4vcnVieQorCityZXF1aXJlICdnb29nbGUvcHJvdG9idWYnCityZXF1aXJlICd0ZXN0L3VuaXQnCisKK21vZHVsZSBTdHJlc3NUZXN0CisgIHBvb2wgPSBHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5uZXcKKyAgcG9vbC5idWlsZCBkbworICAgIGFkZF9tZXNzYWdlICJUZXN0TWVzc2FnZSIgZG8KKyAgICAgIG9wdGlvbmFsIDphLCAgOmludDMyLCAgICAgICAgMQorICAgICAgcmVwZWF0ZWQgOmIsICA6bWVzc2FnZSwgICAgICAyLCAiTSIKKyAgICBlbmQKKyAgICBhZGRfbWVzc2FnZSAiTSIgZG8KKyAgICAgIG9wdGlvbmFsIDpmb28sIDpzdHJpbmcsIDEKKyAgICBlbmQKKyAgZW5kCisKKyAgVGVzdE1lc3NhZ2UgPSBwb29sLmxvb2t1cCgiVGVzdE1lc3NhZ2UiKS5tc2djbGFzcworICBNID0gcG9vbC5sb29rdXAoIk0iKS5tc2djbGFzcworCisgIGNsYXNzIFN0cmVzc1Rlc3QgPCBUZXN0OjpVbml0OjpUZXN0Q2FzZQorICAgIGRlZiBnZXRfbXNnCisgICAgICBUZXN0TWVzc2FnZS5uZXcoOmEgPT4gMTAwMCwKKyAgICAgICAgICAgICAgICAgICAgICA6YiA9PiBbTS5uZXcoOmZvbyA9PiAiaGVsbG8iKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTS5uZXcoOmZvbyA9PiAid29ybGQiKV0pCisgICAgZW5kCisgICAgZGVmIHRlc3Rfc3RyZXNzCisgICAgICBtID0gZ2V0X21zZworICAgICAgZGF0YSA9IFRlc3RNZXNzYWdlLmVuY29kZShtKQorICAgICAgMTAwXzAwMC50aW1lcyBkbworICAgICAgICBtbmV3ID0gVGVzdE1lc3NhZ2UuZGVjb2RlKGRhdGEpCisgICAgICAgIG1uZXcgPSBtbmV3LmR1cAorICAgICAgICBhc3NlcnRfZXF1YWwgbW5ldy5pbnNwZWN0LCBtLmluc3BlY3QKKyAgICAgICAgYXNzZXJ0IFRlc3RNZXNzYWdlLmVuY29kZShtbmV3KSA9PSBkYXRhCisgICAgICBlbmQKKyAgICBlbmQKKyAgZW5kCitlbmQKZGlmZiAtLWdpdCBhL3NyYy9NYWtlZmlsZS5hbSBiL3NyYy9NYWtlZmlsZS5hbQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTI3YjgyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL01ha2VmaWxlLmFtCkBAIC0wLDAgKzEsNTQ2IEBACisjIyBQcm9jZXNzIHRoaXMgZmlsZSB3aXRoIGF1dG9tYWtlIHRvIHByb2R1Y2UgTWFrZWZpbGUuaW4KKworaWYgSEFWRV9aTElCCitHWkNIRUNLUFJPR1JBTVMgPSB6Y2d6aXAgemNndW56aXAKK0daSEVBREVSUyA9IGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oCitHWlRFU1RTID0gZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtX3VuaXR0ZXN0LnNoCitlbHNlCitHWkNIRUNLUFJPR1JBTVMgPQorR1pIRUFERVJTID0KK0daVEVTVFMgPQorZW5kaWYKKworaWYgR0NDCisjIFRoZXNlIGFyZSBnb29kIHdhcm5pbmdzIHRvIHR1cm4gb24gYnkgZGVmYXVsdAorTk9fT1BUX0NYWEZMQUdTID0gJChQVEhSRUFEX0NGTEFHUykgLVdhbGwgLVd3cml0ZS1zdHJpbmdzIC1Xb3ZlcmxvYWRlZC12aXJ0dWFsIC1Xbm8tc2lnbi1jb21wYXJlCitlbHNlCitOT19PUFRfQ1hYRkxBR1MgPSAkKFBUSFJFQURfQ0ZMQUdTKQorZW5kaWYKKworQU1fQ1hYRkxBR1MgPSAkKE5PX09QVF9DWFhGTEFHUykgJChQUk9UT0JVRl9PUFRfRkxBRykKKworQU1fTERGTEFHUyA9ICQoUFRIUkVBRF9DRkxBR1MpCisKKyMgSWYgSSBzYXkgImRpc3RfaW5jbHVkZV9EQVRBIiwgYXV0b21ha2UgY29tcGxhaW5zIHRoYXQgJChpbmNsdWRlZGlyKSBpcyBub3QKKyMgYSAibGVnaXRpbWF0ZSIgZGlyZWN0b3J5IGZvciBEQVRBLiAgU2NyZXcgeW91LCBhdXRvbWFrZS4KK3Byb3RvZGlyID0gJChpbmNsdWRlZGlyKQorbm9iYXNlX2Rpc3RfcHJvdG9fREFUQSA9IGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCisKKyMgTm90IHN1cmUgd2h5IHRoZXNlIGRvbid0IGdldCBjbGVhbmVkIGF1dG9tYXRpY2FsbHkuCitjbGVhbi1sb2NhbDoKKwlybSAtZiAqLmxvVAorCitwdWJsaWNfY29uZmlnID0gZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BiY29uZmlnLmgKKworQ0xFQU5GSUxFUyA9ICQocHJvdG9jX291dHB1dHMpICQocHVibGljX2NvbmZpZykgdW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuIFwKKyAgICAgICAgICAgICB0ZXN0emlwLmphciB0ZXN0emlwLmxpc3QgdGVzdHppcC5wcm90byB0ZXN0emlwLnppcAorCitNQUlOVEFJTkVSQ0xFQU5GSUxFUyA9ICAgXAorICBNYWtlZmlsZS5pbgorCisjIEdlbmVyYXRlIGFuZCBkaXN0cmlidXRlIGEgbWluaW11bSBjb25maWcuaCBmaWxlIHRvIG1ha2UgaGFzaF9tYXAgd29yay4KKyMgVGhlIGF1dG9oZWFkZXIgY29uZmlnIGhhcyB0b28gbXVjaCBpbmZvLCB3aGljaCBtaWdodCBjb25mbGljdCB3aXRoIG90aGVyCisjIG1hY3JvcyBhcHBsaWNhdGlvbnMgbWlnaHQgaW5jbHVkZS4gVGh1cywgd2UgY3JlYXRlIGEgc3R1YnMvcGJjb25maWcuaCwgdGhhdAorIyBvbmx5ICNkZWZpbmVzIHdoYXQgd2UgcmVhbGx5IG5lZWQsIGFuZCBwcmVmaXggaXQgd2l0aCBHT09HTEVfUFJPVE9CVUZfIHRvCisjIGF2b2lkIGNvbmZsaWN0cy4KKyQocHVibGljX2NvbmZpZyk6ICQodG9wX2J1aWxkZGlyKS9jb25maWcuaCAkKHRvcF9zcmNkaXIpL2NvbmZpZy5oLmluY2x1ZGUKKwllY2hvICIvLyBOb3RlOiBHb29nbGUgUHJvdG9idWYgaW50ZXJuYWwgb25seS4gRG8gTk9UIGluY2x1ZGUuIiA+ICRACisJY2F0ICQodG9wX2J1aWxkZGlyKS9jb25maWcuaCB8IGdyZXAgLWYgJCh0b3Bfc3JjZGlyKS9jb25maWcuaC5pbmNsdWRlIHwgXAorCXNlZCAncywjZGVmaW5lICwgI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfLCcgPj4gJEAKKworbm9iYXNlX2luY2x1ZGVfSEVBREVSUyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY19zZXF1ZW5jZV9udW0uaCAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19haXguaCAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtNjRfZ2NjLmggICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9nY2MuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm1fcW54LmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXRvbWljd29yZF9jb21wYXQuaCBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2dlbmVyaWNfZ2NjLmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19tYWNvc3guaCAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWlwc19nY2MuaCAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3BuYWNsLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfdHNhbi5oICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Nhc3RzLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvZmFzdG1lbS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvcGxhdGZvcm1fbWFjcm9zLmggICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaW5nbGV0b24uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYXJlbmEuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmggICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaCAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfZW50cnkuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5X2xpdGUuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfbGl0ZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2lubC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdHlwZV9oYW5kbGVyLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbi5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICQoR1pIRUFERVJTKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaCAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaCAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuaCAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaCAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZXMuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmggICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmggICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmgKKworbm9iYXNlX25vZGlzdF9pbmNsdWRlX0hFQURFUlMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgJChwdWJsaWNfY29uZmlnKQorCitsaWJfTFRMSUJSQVJJRVMgPSBsaWJwcm90b2J1Zi1saXRlLmxhIGxpYnByb3RvYnVmLmxhIGxpYnByb3RvYy5sYQorCitsaWJwcm90b2J1Zl9saXRlX2xhX0xJQkFERCA9ICQoUFRIUkVBRF9MSUJTKQorbGlicHJvdG9idWZfbGl0ZV9sYV9MREZMQUdTID0gLXZlcnNpb24taW5mbyAxMDowOjAgLWV4cG9ydC1keW5hbWljIC1uby11bmRlZmluZWQKK2xpYnByb3RvYnVmX2xpdGVfbGFfU09VUkNFUyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5jYyAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5jYyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FyZW5hLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuY2MgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbV9pbmwuaCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjCitub2Rpc3RfbGlicHJvdG9idWZfbGl0ZV9sYV9TT1VSQ0VTID0gJChwdWJsaWNfY29uZmlnKQorCitsaWJwcm90b2J1Zl9sYV9MSUJBREQgPSAkKFBUSFJFQURfTElCUykKK2xpYnByb3RvYnVmX2xhX0xERkxBR1MgPSAtdmVyc2lvbi1pbmZvIDEwOjA6MCAtZXhwb3J0LWR5bmFtaWMgLW5vLXVuZGVmaW5lZAorbGlicHJvdG9idWZfbGFfU09VUkNFUyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAkKGxpYnByb3RvYnVmX2xpdGVfbGFfU09VUkNFUykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldF9oZWF2eS5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9pbnRlcm5hbC5oICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc2VydmljZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmNjCitub2Rpc3RfbGlicHJvdG9idWZfbGFfU09VUkNFUyA9ICQobm9kaXN0X2xpYnByb3RvYnVmX2xpdGVfbGFfU09VUkNFUykKKworbGlicHJvdG9jX2xhX0xJQkFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYQorbGlicHJvdG9jX2xhX0xERkxBR1MgPSAtdmVyc2lvbi1pbmZvIDEwOjA6MCAtZXhwb3J0LWR5bmFtaWMgLW5vLXVuZGVmaW5lZAorbGlicHJvdG9jX2xhX1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvc3VicHJvY2Vzcy5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvc3VicHJvY2Vzcy5oICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5oICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmNjICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmggICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5jYyAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWxlLmNjICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWxlLmggICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmNjICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuY2MgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaCAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuY2MgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuaCAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpbGUuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpbGUuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvci5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmNjICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5jYyAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5oICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZC5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZC5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5jYyAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5oICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5jYyAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3N0cmluZ19maWVsZC5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3N0cmluZ19maWVsZC5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmNjICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bS5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bS5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bV9maWVsZC5jYyAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bV9maWVsZC5oICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmNjICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmNjICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5jYyAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmNjICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZS5jYyAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZS5oICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZV9maWVsZC5jYyAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZV9maWVsZC5oICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmggICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmNjIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5oIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuY2MKKworYmluX1BST0dSQU1TID0gcHJvdG9jCitwcm90b2NfTERBREQgPSAkKFBUSFJFQURfTElCUykgbGlicHJvdG9idWYubGEgbGlicHJvdG9jLmxhCitwcm90b2NfU09VUkNFUyA9IGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tYWluLmNjCisKKyMgVGVzdHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworcHJvdG9jX2lucHV0cyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucHJvdG8gICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wcm90byAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnByb3RvICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8gICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wcm90byAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8gICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90byAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8gICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnByb3RvICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucHJvdG8gICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucHJvdG8gICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wcm90byAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnByb3RvICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wcm90byAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL3Rlc3RfbGFyZ2VfZW51bV92YWx1ZS5wcm90bworCitFWFRSQV9ESVNUID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICQocHJvdG9jX2lucHV0cykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHNvbGFyaXMvbGlic3RkYysrLmxhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbV91bml0dGVzdC5zaCAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9vbmVvZl9pbXBsZW1lbnRlZCAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9wcm90bzMgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9iYWRfdXRmOF9zdHJpbmcgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhLnR4dCAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX29uZW9mX2ltcGxlbWVudGVkLnR4dCAgXAorICBnb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9wb2ludHkudHh0ICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfcG9pbnR5X29uZW9mLnR4dCAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0ICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhX3BvaW50eS50eHQgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3BhY2thZ2VfaW5mby5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3BhY2thZ2VfaW5mby5oICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhY2thZ2VfaW5mby5oICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2ggICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8KKworcHJvdG9jX2xpdGVfb3V0cHV0cyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuY2MgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuaCAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmNjICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmgKKworcHJvdG9jX291dHB1dHMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAkKHByb3RvY19saXRlX291dHB1dHMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wYi5jYyAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wYi5oICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmNjICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5jYyAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5oICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucGIuY2MgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucGIuaCAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuY2MgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuaCAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnBiLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnBiLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmNjICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmggICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi5jYyAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi5oICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL3Rlc3RfbGFyZ2VfZW51bV92YWx1ZS5wYi5jYyAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL3Rlc3RfbGFyZ2VfZW51bV92YWx1ZS5wYi5oICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5jYyAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5oCisKK0JVSUxUX1NPVVJDRVMgPSAkKHB1YmxpY19jb25maWcpICQocHJvdG9jX291dHB1dHMpCisKK2lmIFVTRV9FWFRFUk5BTF9QUk9UT0MKKwordW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuOiAkKHByb3RvY19pbnB1dHMpCisJJChQUk9UT0MpIC1JJChzcmNkaXIpIC0tY3BwX291dD0uICReCisJdG91Y2ggdW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuCisKK2Vsc2UKKworIyBXZSBoYXZlIHRvIGNkIHRvICQoc3JjZGlyKSBiZWZvcmUgZXhlY3V0aW5nIHByb3RvYyBiZWNhdXNlICQocHJvdG9jX2lucHV0cykgaXMKKyMgcmVsYXRpdmUgdG8gc3JjZGlyLCB3aGljaCBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IGRpcmVjdG9yeSB3aGVuCisjIGJ1aWxkaW5nIG91dC1vZi10cmVlLgordW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuOiBwcm90b2MkKEVYRUVYVCkgJChwcm90b2NfaW5wdXRzKQorCW9sZHB3ZD1gcHdkYCAmJiAoIGNkICQoc3JjZGlyKSAmJiAkJG9sZHB3ZC9wcm90b2MkKEVYRUVYVCkgLUkuIC0tY3BwX291dD0kJG9sZHB3ZCAkKHByb3RvY19pbnB1dHMpICkKKwl0b3VjaCB1bml0dGVzdF9wcm90b19taWRkbGVtYW4KKworZW5kaWYKKworJChwcm90b2Nfb3V0cHV0cyk6IHVuaXR0ZXN0X3Byb3RvX21pZGRsZW1hbgorCitDT01NT05fVEVTVF9TT1VSQ0VTID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsX2ltcGwuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaAorCitjaGVja19QUk9HUkFNUyA9IHByb3RvYyBwcm90b2J1Zi10ZXN0IHByb3RvYnVmLWxhenktZGVzY3JpcHRvci10ZXN0IFwKKyAgICAgICAgICAgICAgICAgcHJvdG9idWYtbGl0ZS10ZXN0IHRlc3RfcGx1Z2luICQoR1pDSEVDS1BST0dSQU1TKQorcHJvdG9idWZfdGVzdF9MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYSBsaWJwcm90b2MubGEgXAorICAgICAgICAgICAgICAgICAgICAgICQodG9wX2J1aWxkZGlyKS9ndGVzdC9saWIvbGliZ3Rlc3QubGEgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICQodG9wX2J1aWxkZGlyKS9ndGVzdC9saWIvbGliZ3Rlc3RfbWFpbi5sYQorcHJvdG9idWZfdGVzdF9DUFBGTEFHUyA9IC1JJCh0b3Bfc3JjZGlyKS9ndGVzdC9pbmNsdWRlICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgIC1JJCh0b3BfYnVpbGRkaXIpL2d0ZXN0L2luY2x1ZGUKKyMgRGlzYWJsZSBvcHRpbWl6YXRpb24gZm9yIHRlc3RzIHVubGVzcyB0aGUgdXNlciBleHBsaWNpdGx5IGFza2VkIGZvciBpdCwKKyMgc2luY2UgdGVzdF91dGlsLmNjIHRha2VzIGZvcmV2ZXIgdG8gY29tcGlsZSB3aXRoIG9wdGltaXphdGlvbiAod2l0aCBHQ0MpLgorIyBTZWUgY29uZmlndXJlLmFjIGZvciBtb3JlIGluZm8uCitwcm90b2J1Zl90ZXN0X0NYWEZMQUdTID0gJChOT19PUFRfQ1hYRkxBR1MpCitwcm90b2J1Zl90ZXN0X1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb25fdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWRfdW5pdHRlc3QuY2MgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0c191bml0dGVzdC5jYyAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZ191bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYV91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9kcm9wX3Vua25vd25fZmllbGRzX3Rlc3QuY2MgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2VfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0X3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfdGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9ub19maWVsZF9wcmVzZW5jZV90ZXN0LmNjICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9wcmVzZXJ2ZV91bmtub3duX2VudW1fdGVzdC5jYyAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9wcm90bzNfYXJlbmFfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wc191bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdF91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldF91bml0dGVzdC5jYyAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1fdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXJfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlX3VuaXR0ZXN0LmNjICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlcl91bml0dGVzdC5jYyAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmNjICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmggICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXJfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2Jvb3RzdHJhcF91bml0dGVzdC5jYyAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0LmggICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3BsdWdpbl91bml0dGVzdC5jYyAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcGx1Z2luX3VuaXR0ZXN0LmNjICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnRfdW5pdHRlc3QuY2MgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX3BsdWdpbl91bml0dGVzdC5jYyAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yX3VuaXR0ZXN0LmNjICAgICBcCisgICQoQ09NTU9OX1RFU1RfU09VUkNFUykKK25vZGlzdF9wcm90b2J1Zl90ZXN0X1NPVVJDRVMgPSAkKHByb3RvY19vdXRwdXRzKQorCisjIFJ1biBjcHBfdW5pdHRlc3QgYWdhaW4gd2l0aCBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTIGRlZmluZWQuCitwcm90b2J1Zl9sYXp5X2Rlc2NyaXB0b3JfdGVzdF9MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYSBcCisgICAgICAgICAgICAgICAgICAgICAgbGlicHJvdG9jLmxhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgJCh0b3BfYnVpbGRkaXIpL2d0ZXN0L2xpYi9saWJndGVzdC5sYSAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgJCh0b3BfYnVpbGRkaXIpL2d0ZXN0L2xpYi9saWJndGVzdF9tYWluLmxhCitwcm90b2J1Zl9sYXp5X2Rlc2NyaXB0b3JfdGVzdF9DUFBGTEFHUyA9IC1JJCh0b3Bfc3JjZGlyKS9ndGVzdC9pbmNsdWRlICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLUkkKHRvcF9idWlsZGRpcikvZ3Rlc3QvaW5jbHVkZSAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtRFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKK3Byb3RvYnVmX2xhenlfZGVzY3JpcHRvcl90ZXN0X0NYWEZMQUdTID0gJChOT19PUFRfQ1hYRkxBR1MpCitwcm90b2J1Zl9sYXp5X2Rlc2NyaXB0b3JfdGVzdF9TT1VSQ0VTID0gICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICBcCisgICQoQ09NTU9OX1RFU1RfU09VUkNFUykKK25vZGlzdF9wcm90b2J1Zl9sYXp5X2Rlc2NyaXB0b3JfdGVzdF9TT1VSQ0VTID0gJChwcm90b2Nfb3V0cHV0cykKKworIyBCdWlsZCBsaXRlX3VuaXR0ZXN0IHNlcGFyYXRlbHksIHNpbmNlIGl0IGRvZXNuJ3QgdXNlIGd0ZXN0LgorcHJvdG9idWZfbGl0ZV90ZXN0X0xEQUREID0gJChQVEhSRUFEX0xJQlMpIGxpYnByb3RvYnVmLWxpdGUubGEKK3Byb3RvYnVmX2xpdGVfdGVzdF9DWFhGTEFHUyA9ICQoTk9fT1BUX0NYWEZMQUdTKQorcHJvdG9idWZfbGl0ZV90ZXN0X1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9saXRlX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdF91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWxfbGl0ZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmgKKyAgIyBUT0RPKHRlYm9yaW5nKSBhZGQgdGhlIGZpbGUgYmFjayBhbmQgbWFrZSB0aGUgdGVzdCBidWlsZC4KKyAgIyBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdC5jYworbm9kaXN0X3Byb3RvYnVmX2xpdGVfdGVzdF9TT1VSQ0VTID0gJChwcm90b2NfbGl0ZV9vdXRwdXRzKQorCisjIFRlc3QgcGx1Z2luIGJpbmFyeS4KK3Rlc3RfcGx1Z2luX0xEQUREID0gJChQVEhSRUFEX0xJQlMpIGxpYnByb3RvYnVmLmxhIGxpYnByb3RvYy5sYSBcCisgICAgICAgICAgICAgICAgICAgICQodG9wX2J1aWxkZGlyKS9ndGVzdC9saWIvbGliZ3Rlc3QubGEKK3Rlc3RfcGx1Z2luX0NQUEZMQUdTID0gLUkkKHRvcF9zcmNkaXIpL2d0ZXN0L2luY2x1ZGUgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgIC1JJCh0b3BfYnVpbGRkaXIpL2d0ZXN0L2luY2x1ZGUKK3Rlc3RfcGx1Z2luX1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3Rlc3RfcGx1Z2luLmNjCisKK2lmIEhBVkVfWkxJQgoremNnemlwX0xEQUREID0gJChQVEhSRUFEX0xJQlMpIGxpYnByb3RvYnVmLmxhCit6Y2d6aXBfU09VUkNFUyA9IGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3ppcC5jYworCit6Y2d1bnppcF9MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYQoremNndW56aXBfU09VUkNFUyA9IGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3VuemlwLmNjCitlbmRpZgorCitURVNUUyA9IHByb3RvYnVmLXRlc3QgcHJvdG9idWYtbGF6eS1kZXNjcmlwdG9yLXRlc3QgcHJvdG9idWYtbGl0ZS10ZXN0IFwKKyAgICAgICAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2ggJChHWlRFU1RTKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9TRUJTIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9TRUJTCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhMzNjNzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL1NFQlMKQEAgLTAsMCArMSwyNDAgQEAKKyMgKipFWFBFUklNRU5UQUwqKgorIworIyBTZWUgaHR0cDovL3NlYnMuZ29vZ2xlY29kZS5jb20KKyMKKyMgVGhpcyBpcyBhbiBleHBlcmltZW50YWwgYnVpbGQgZGVmaW5pdGlvbiBmaWxlIHVzaW5nIHRoZSBTRUJTIGJ1aWxkIHN5c3RlbS4KKyMgSSAoS2VudG9uIFZhcmRhLCBtYWludGFpbmVyIG9mIFByb3RvY29sIEJ1ZmZlcnMpIGhhcHBlbiB0byBiZSB0aGUgYXV0aG9yIG9mCisjIFNFQlMsIHRob3VnaCBTRUJTIGlzIG5vdCBhIEdvb2dsZSBwcm9qZWN0LiAgSSdtIHN0aWNraW5nIHRoaXMgZmlsZSBpbgorIyBwcm90b2J1ZidzIFNWTiBiZWNhdXNlIHRoYXQncyB0aGUgZWFzaWVzdCBwbGFjZSBmb3IgbWUgdG8gcHV0IGl0LCBhbmQgaXQKKyMgc2hvdWxkbid0IGhhcm0gYW55b25lLiAgVGhpcyBmaWxlIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgZGlzdHJpYnV0aW9uLgorIworIyBDdXJyZW50bHksIHRvIHVzZSB0aGlzIGZpbGUsIHlvdSBtdXN0IGdlbmVyYXRlIGNvbmZpZy5oIGFuZCBwdXQgaXQgYXQgdGhlCisjIHRvcCBsZXZlbCBvZiB0aGUgc291cmNlIHRyZWUuCisKK19jcHAgPSBzZWJzLmltcG9ydF8oIi8vc2Vicy9jcHAuc2VicyIpCisKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyMgUHVibGljIHRhcmdldHMKKworcHJvdG9idWZfbGl0ZSA9IF9jcHAuTGlicmFyeSgKKyAgbmFtZSA9ICJwcm90b2J1Zi1saXRlIiwKKyAgc3JjcyA9IFsgInN0dWJzL2NvbW1vbi5jYyIsCisgICAgICAgICAgICJzdHVicy9vbmNlLmNjIiwKKyAgICAgICAgICAgInN0dWJzL2hhc2guY2MiLAorICAgICAgICAgICAic3R1YnMvaGFzaC5oIiwKKyAgICAgICAgICAgInN0dWJzL21hcC11dGlsLmgiLAorICAgICAgICAgICAic3R1YnMvc3RsX3V0aWwtaW5sLmgiLAorICAgICAgICAgICAiZXh0ZW5zaW9uX3NldC5jYyIsCisgICAgICAgICAgICJnZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmNjIiwKKyAgICAgICAgICAgIm1lc3NhZ2VfbGl0ZS5jYyIsCisgICAgICAgICAgICJyZXBlYXRlZF9maWVsZC5jYyIsCisgICAgICAgICAgICJ3aXJlX2Zvcm1hdF9saXRlLmNjIiwKKyAgICAgICAgICAgImlvL2NvZGVkX3N0cmVhbS5jYyIsCisgICAgICAgICAgICJpby96ZXJvX2NvcHlfc3RyZWFtLmNjIiwKKyAgICAgICAgICAgImlvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjIiBdLAorICBkZXBzID0gWyBfY3BwLlN5c3RlbUxpYnJhcnkobmFtZSA9ICJwdGhyZWFkIikgXSkKKworcHJvdG9idWYgPSBfY3BwLkxpYnJhcnkoCisgIG5hbWUgPSAicHJvdG9idWYiLAorICBzcmNzID0gWyAic3R1YnMvc3RydXRpbC5jYyIsCisgICAgICAgICAgICJzdHVicy9zdHJ1dGlsLmgiLAorICAgICAgICAgICAic3R1YnMvc3Vic3RpdHV0ZS5jYyIsCisgICAgICAgICAgICJzdHVicy9zdWJzdGl0dXRlLmgiLAorICAgICAgICAgICAic3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkLmNjIiwKKyAgICAgICAgICAgImRlc2NyaXB0b3IuY2MiLAorICAgICAgICAgICAiZGVzY3JpcHRvci5wYi5jYyIsCisgICAgICAgICAgICJkZXNjcmlwdG9yX2RhdGFiYXNlLmNjIiwKKyAgICAgICAgICAgImR5bmFtaWNfbWVzc2FnZS5jYyIsCisgICAgICAgICAgICJleHRlbnNpb25fc2V0X2hlYXZ5LmNjIiwKKyAgICAgICAgICAgImdlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MiLAorICAgICAgICAgICAibWVzc2FnZS5jYyIsCisgICAgICAgICAgICJyZWZsZWN0aW9uX29wcy5jYyIsCisgICAgICAgICAgICJzZXJ2aWNlLmNjIiwKKyAgICAgICAgICAgInRleHRfZm9ybWF0LmNjIiwKKyAgICAgICAgICAgInVua25vd25fZmllbGRfc2V0LmNjIiwKKyAgICAgICAgICAgIndpcmVfZm9ybWF0LmNjIiwKKyAgICAgICAgICAgImlvL2d6aXBfc3RyZWFtLmNjIiwKKyAgICAgICAgICAgImlvL3ByaW50ZXIuY2MiLAorICAgICAgICAgICAiaW8vdG9rZW5pemVyLmNjIiwKKyAgICAgICAgICAgImlvL3plcm9fY29weV9zdHJlYW1faW1wbC5jYyIsCisgICAgICAgICAgICJjb21waWxlci9pbXBvcnRlci5jYyIsCisgICAgICAgICAgICJjb21waWxlci9wYXJzZXIuY2MiIF0sCisgIGRlcHMgPSBbIHByb3RvYnVmX2xpdGUsCisgICAgICAgICAgIF9jcHAuU3lzdGVtTGlicmFyeShuYW1lID0gInoiKSBdKQorCitsaWJwcm90b2MgPSBfY3BwLkxpYnJhcnkoCisgIG5hbWUgPSAicHJvdG9jIiwKKyAgc3JjcyA9IFsgImNvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvY3BwL2NwcF9lbnVtLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfZW51bS5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX2VudW1fZmllbGQuaCIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfZmllbGQuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfZmlsZS5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX2ZpbGUuaCIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX2dlbmVyYXRvci5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX2hlbHBlcnMuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmgiLAorICAgICAgICAgICAiY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX21lc3NhZ2VfZmllbGQuaCIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX3ByaW1pdGl2ZV9maWVsZC5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX3ByaW1pdGl2ZV9maWVsZC5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX3NlcnZpY2UuaCIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5jYyIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9lbnVtLmgiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuaCIsCisgICAgICAgICAgICJjb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaCIsCisgICAgICAgICAgICJjb21waWxlci9qYXZhL2phdmFfZmllbGQuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmgiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX2ZpbGUuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX2ZpbGUuaCIsCisgICAgICAgICAgICJjb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmgiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaCIsCisgICAgICAgICAgICJjb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5jYyIsCisgICAgICAgICAgICJjb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5oIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmgiLAorICAgICAgICAgICAiY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuY2MiIF0sCisgIGRlcHMgPSBbIHByb3RvYnVmIF0pCisKK3Byb3RvYyA9IF9jcHAuQmluYXJ5KAorICBuYW1lID0gInByb3RvYyIsCisgIHNyY3MgPSBbICJjb21waWxlci9tYWluLmNjIiBdLAorICBkZXBzID0gWyBsaWJwcm90b2MgXSkKKworIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorIyBQcm90b2J1ZkxpYnJhcnkgcnVsZSBjbGFzcworCitjbGFzcyBQcm90b2J1ZkxpYnJhcnkoc2Vicy5SdWxlKToKKyAgYXJndW1lbnRfc3BlYyA9IHNlYnMuQXJndW1lbnRTcGVjKHNyY3MgPSBbc2Vicy5BcnRpZmFjdF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBzID0gKFtzZWJzLlJ1bGVdLCBbXSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXRlID0gKGJvb2wsIEZhbHNlKSkKKworICBkZWYgX2V4cGFuZChzZWxmLCBhcmdzKToKKyAgICBmb3IgZGVwIGluIGFyZ3MuZGVwczoKKyAgICAgIGlmIG5vdCBpc2luc3RhbmNlKGRlcCwgUHJvdG9idWZMaWJyYXJ5KToKKyAgICAgICAgcmFpc2Ugc2Vicy5EZWZpbml0aW9uRXJyb3IoCisgICAgICAgICAgIkRlcGVuZGVuY3kgb2YgUHJvdG9idWZMaWJyYXJ5IGlzIG5vdCBhIFByb3RvYnVmTGlicmFyeTogJXMiICUgZGVwKQorCisgICAgcHJvdG9jLmV4cGFuZF9vbmNlKCkKKworICAgICMgV2UgbXVzdCBidWlsZCBwcm90b2MgZm9yIHRoZSBob3N0IGNvbmZpZ3VyYXRpb24gdG8gYWxsb3cgY3Jvc3MtY29tcGlsaW5nLgorICAgIGhvc3RfcHJvdG9jID0gc2VsZi5jb250ZXh0LmNvbmZpZ3VyZWRfYXJ0aWZhY3QocHJvdG9jLmJpbmFyeSwgImhvc3QiKQorCisgICAgcHJvdG9jX2FjdGlvbiA9IHNlbGYuY29udGV4dC5hY3Rpb24oc2VsZiwgInByb3RvYnVmIikKKyAgICBwcm90b2NfYXJncyA9IFtob3N0X3Byb3RvYywgIi1Jc3JjIiwgIi1JdG1wIiwgIi1JaW5jbHVkZSIsIi0tY3BwX291dD10bXAiXQorCisgICAgY3BwX3NyY3MgPSBbXQorICAgIGZvciBzcmMgaW4gYXJncy5zcmNzOgorICAgICAgcHJvdG9jX2FyZ3MuYXBwZW5kKHNyYykKKworICAgICAgIyBXZSBjYW5ub3QgYnVpbGQgLnByb3RvIGZpbGVzIGZyb20gb3RoZXIgcGFja2FnZXMgYmVjYXVzZSB0aGUgLnBiLmNjCisgICAgICAjIGFuZCAucGIuaCBmaWxlcyB3b3VsZCBiZSB3cml0dGVuIHRvIHRoYXQgcGFja2FnZSwgYW5kIHdlIGFyZW4ndCBhbGxvd2VkCisgICAgICAjIHRvIHdyaXRlIHRvIG90aGVyIHBhY2thZ2VzLgorICAgICAgaWYgc2VsZi5jb250ZXh0LmxvY2FsX2ZpbGVuYW1lKHNyYykgaXMgTm9uZToKKyAgICAgICAgcmFpc2Ugc2Vicy5EZWZpbml0aW9uRXJyb3IoCisgICAgICAgICAgIlNvdXJjZSBmaWxlIGlzIG5vdCBpbiB0aGlzIHBhY2thZ2U6ICVzIiAlIHNyYykKKworICAgICAgY2NfYXJ0aWZhY3QgPSBzZWxmLmNvbnRleHQuZGVyaXZlZF9hcnRpZmFjdChzcmMsICIucGIuY2MiLCBwcm90b2NfYWN0aW9uKQorICAgICAgaGVhZGVyX2FydGlmYWN0ID0gc2VsZi5jb250ZXh0LmRlcml2ZWRfYXJ0aWZhY3QoCisgICAgICAgICAgc3JjLCAiLnBiLmgiLCBwcm90b2NfYWN0aW9uKQorCisgICAgICBjcHBfc3Jjcy5hcHBlbmQoY2NfYXJ0aWZhY3QpCisgICAgICBjcHBfc3Jjcy5hcHBlbmQoaGVhZGVyX2FydGlmYWN0KQorCisgICAgcHJvdG9jX2FjdGlvbi5zZXRfY29tbWFuZCgKKyAgICAgIHNlYnMuU3VicHJvY2Vzc0NvbW1hbmQocHJvdG9jX2FjdGlvbiwgcHJvdG9jX2FyZ3MsIGltcGxpY2l0ID0gY3BwX3NyY3MpKQorCisgICAgZGVwcyA9IGxpc3QoYXJncy5kZXBzKQorICAgIGlmIGFyZ3MubGl0ZToKKyAgICAgIGRlcHMuYXBwZW5kKHByb3RvYnVmX2xpdGUpCisgICAgZWxzZToKKyAgICAgIGRlcHMuYXBwZW5kKHByb3RvYnVmKQorCisgICAgc2VsZi5fX2NwcF9saWJyYXJ5ID0gX2NwcC5MaWJyYXJ5KHNyY3MgPSBjcHBfc3JjcywgZGVwcyA9IGRlcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBzZWxmLmNvbnRleHQpCisgICAgc2VsZi5fX2NwcF9saWJyYXJ5LmxhYmVsID0gc2VsZi5sYWJlbAorICAgIHNlbGYub3V0cHV0cyA9IFtdCisKKyAgZGVmIGFzX2NwcF9saWJyYXJ5KHNlbGYpOgorICAgIHNlbGYuZXhwYW5kX29uY2UoKQorICAgIHJldHVybiBzZWxmLl9fY3BwX2xpYnJhcnkKKworIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorIyBUZXN0cworCitfbGl0ZV90ZXN0X3Byb3RvcyA9IFByb3RvYnVmTGlicmFyeSgKKyAgc3JjcyA9IFsgInVuaXR0ZXN0X2xpdGUucHJvdG8iLAorICAgICAgICAgICAidW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8iIF0sCisgIGxpdGUgPSBUcnVlKQorX3Rlc3RfcHJvdG9zID0gUHJvdG9idWZMaWJyYXJ5KAorICBzcmNzID0gWyAidW5pdHRlc3QucHJvdG8iLAorICAgICAgICAgICAidW5pdHRlc3RfZW1wdHkucHJvdG8iLAorICAgICAgICAgICAidW5pdHRlc3RfaW1wb3J0LnByb3RvIiwKKyAgICAgICAgICAgInVuaXR0ZXN0X21zZXQucHJvdG8iLAorICAgICAgICAgICAidW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvIiwKKyAgICAgICAgICAgInVuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wcm90byIsCisgICAgICAgICAgICJ1bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byIsCisgICAgICAgICAgICJ1bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90byIsCisgICAgICAgICAgICJjb21waWxlci9jcHAvY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvIiBdLAorICBkZXBzID0gWyBfbGl0ZV90ZXN0X3Byb3RvcyBdKQorCitfdGVzdF91dGlsID0gX2NwcC5MaWJyYXJ5KAorICBuYW1lID0gInRlc3RfdXRpbCIsCisgIHNyY3MgPSBbICJ0ZXN0X3V0aWwuY2MiLAorICAgICAgICAgICAidGVzdF91dGlsLmgiLAorICAgICAgICAgICAidGVzdGluZy9nb29nbGV0ZXN0LmNjIiwKKyAgICAgICAgICAgInRlc3RpbmcvZ29vZ2xldGVzdC5oIiwKKyAgICAgICAgICAgInRlc3RpbmcvZmlsZS5jYyIsCisgICAgICAgICAgICJ0ZXN0aW5nL2ZpbGUuaCIgXSwKKyAgZGVwcyA9IFsgcHJvdG9idWYsIF90ZXN0X3Byb3RvcywgX2NwcC5TeXN0ZW1MaWJyYXJ5KG5hbWUgPSAiZ3Rlc3QiKV0gKQorCitwcm90b2J1Zl9saXRlX3Rlc3QgPSBfY3BwLlRlc3QoCisgIHNyY3MgPSBbICJsaXRlX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgInRlc3RfdXRpbF9saXRlLmNjIiwKKyAgICAgICAgICAgInRlc3RfdXRpbF9saXRlLmgiIF0sCisgIGRlcHMgPSBbIF9saXRlX3Rlc3RfcHJvdG9zIF0pCisKK3Byb3RvYnVmX3Rlc3QgPSBfY3BwLlRlc3QoCisgIHNyY3MgPSBbICJzdHVicy9jb21tb25fdW5pdHRlc3QuY2MiLAorICAgICAgICAgICAic3R1YnMvb25jZV91bml0dGVzdC5jYyIsCisgICAgICAgICAgICJzdHVicy9zdHJ1dGlsX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgInN0dWJzL3N0cnVjdHVyYWxseV92YWxpZF91bml0dGVzdC5jYyIsCisgICAgICAgICAgICJkZXNjcmlwdG9yX2RhdGFiYXNlX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImRlc2NyaXB0b3JfdW5pdHRlc3QuY2MiLAorICAgICAgICAgICAiZHluYW1pY19tZXNzYWdlX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImV4dGVuc2lvbl9zZXRfdW5pdHRlc3QuY2MiLAorICAgICAgICAgICAiZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbl91bml0dGVzdC5jYyIsCisgICAgICAgICAgICJtZXNzYWdlX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgInJlZmxlY3Rpb25fb3BzX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgInJlcGVhdGVkX2ZpZWxkX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgInRleHRfZm9ybWF0X3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgInVua25vd25fZmllbGRfc2V0X3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgIndpcmVfZm9ybWF0X3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImlvL2NvZGVkX3N0cmVhbV91bml0dGVzdC5jYyIsCisgICAgICAgICAgICJpby9wcmludGVyX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImlvL3Rva2VuaXplcl91bml0dGVzdC5jYyIsCisgICAgICAgICAgICJpby96ZXJvX2NvcHlfc3RyZWFtX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2VfdW5pdHRlc3QuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvaW1wb3J0ZXJfdW5pdHRlc3QuY2MiLAorICAgICAgICAgICAiY29tcGlsZXIvcGFyc2VyX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfYm9vdHN0cmFwX3VuaXR0ZXN0LmNjIiwKKyAgICAgICAgICAgImNvbXBpbGVyL2NwcC9jcHBfdW5pdHRlc3QuY2MiIF0sCisgIGRlcHMgPSBbIHByb3RvYnVmLCBsaWJwcm90b2MsIF90ZXN0X3V0aWwsCisgICAgICAgICAgIF9jcHAuU3lzdGVtTGlicmFyeShuYW1lID0gImd0ZXN0X21haW4iKSBdKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjJhYTBhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8KQEAgLTAsMCArMSw5OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiQW55UHJvdG8iOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKKworCisvLyBgQW55YCBjb250YWlucyBhbiBhcmJpdHJhcnkgc2VyaWFsaXplZCBtZXNzYWdlIGFsb25nIHdpdGggYSBVUkwKKy8vIHRoYXQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZSBzZXJpYWxpemVkIG1lc3NhZ2UuCisvLworLy8KKy8vCisvLyAjIEpTT04KKy8vIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIG9mIGFuIGBBbnlgIHZhbHVlIHVzZXMgdGhlIHJlZ3VsYXIKKy8vIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkZXNlcmlhbGl6ZWQsIGVtYmVkZGVkIG1lc3NhZ2UsIHdpdGggYW4KKy8vIGFkZGl0aW9uYWwgZmllbGQgYEB0eXBlYCB3aGljaCBjb250YWlucyB0aGUgdHlwZSBVUkwuIEV4YW1wbGU6CisvLworLy8gICAgIHBhY2thZ2UgZ29vZ2xlLnByb2ZpbGU7CisvLyAgICAgbWVzc2FnZSBQZXJzb24geworLy8gICAgICAgc3RyaW5nIGZpcnN0X25hbWUgPSAxOworLy8gICAgICAgc3RyaW5nIGxhc3RfbmFtZSA9IDI7CisvLyAgICAgfQorLy8KKy8vICAgICB7CisvLyAgICAgICAiQHR5cGUiOiAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvZmlsZS5QZXJzb24iLAorLy8gICAgICAgImZpcnN0TmFtZSI6IDxzdHJpbmc+LAorLy8gICAgICAgImxhc3ROYW1lIjogPHN0cmluZz4KKy8vICAgICB9CisvLworLy8gSWYgdGhlIGVtYmVkZGVkIG1lc3NhZ2UgdHlwZSBpcyB3ZWxsLWtub3duIGFuZCBoYXMgYSBjdXN0b20gSlNPTgorLy8gcmVwcmVzZW50YXRpb24sIHRoYXQgcmVwcmVzZW50YXRpb24gd2lsbCBiZSBlbWJlZGRlZCBhZGRpbmcgYSBmaWVsZAorLy8gYHZhbHVlYCB3aGljaCBob2xkcyB0aGUgY3VzdG9tIEpTT04gaW4gYWRkaXRpb24gdG8gdGhlIHRoZSBgQHR5cGVgCisvLyBmaWVsZC4gRXhhbXBsZSAoZm9yIG1lc3NhZ2UgW2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbl1bZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uXSk6CisvLworLy8gICAgIHsKKy8vICAgICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIsCisvLyAgICAgICAidmFsdWUiOiAiMS4yMTJzIgorLy8gICAgIH0KKy8vCittZXNzYWdlIEFueSB7CisgIC8vIEEgVVJML3Jlc291cmNlIG5hbWUgd2hvc2UgY29udGVudCBkZXNjcmliZXMgdGhlIHR5cGUgb2YgdGhlCisgIC8vIHNlcmlhbGl6ZWQgbWVzc2FnZS4KKyAgLy8KKyAgLy8gRm9yIFVSTHMgd2hpY2ggdXNlIHRoZSBzY2hlbWEgYGh0dHBgLCBgaHR0cHNgLCBvciBubyBzY2hlbWEsIHRoZQorICAvLyBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIGFuZCBpbnRlcnByZXRhdGlvbnMgYXBwbHk6CisgIC8vCisgIC8vICogSWYgbm8gc2NoZW1hIGlzIHByb3ZpZGVkLCBodHRwcyBpcyBhc3N1bWVkLgorICAvLyAqIFRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIFVSTCdzIHBhdGggbXVzdCByZXByZXNlbnQgdGhlIGZ1bGx5CisgIC8vICAgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgKGFzIGluIGBwYXRoL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbmApLgorICAvLyAqIEFuIEhUVFAgR0VUIG9uIHRoZSBVUkwgbXVzdCB5aWVsZCBhIFtnb29nbGUucHJvdG9idWYuVHlwZV1bZ29vZ2xlLnByb3RvYnVmLlR5cGVdCisgIC8vICAgdmFsdWUgaW4gYmluYXJ5IGZvcm1hdCwgb3IgcHJvZHVjZSBhbiBlcnJvci4KKyAgLy8gKiBBcHBsaWNhdGlvbnMgYXJlIGFsbG93ZWQgdG8gY2FjaGUgbG9va3VwIHJlc3VsdHMgYmFzZWQgb24gdGhlCisgIC8vICAgVVJMLCBvciBoYXZlIHRoZW0gcHJlY29tcGlsZWQgaW50byBhIGJpbmFyeSB0byBhdm9pZCBhbnkKKyAgLy8gICBsb29rdXAuIFRoZXJlZm9yZSwgYmluYXJ5IGNvbXBhdGliaWxpdHkgbmVlZCB0byBiZSBwcmVzZXJ2ZWQKKyAgLy8gICBvbiBjaGFuZ2VzIHRvIHR5cGVzLiAoVXNlIHZlcnNpb25lZCB0eXBlIG5hbWVzIHRvIG1hbmFnZQorICAvLyAgIGJyZWFraW5nIGNoYW5nZXMuKQorICAvLworICAvLyBTY2hlbWFzIG90aGVyIHRoYW4gYGh0dHBgLCBgaHR0cHNgIChvciB0aGUgZW1wdHkgc2NoZW1hKSBtaWdodCBiZQorICAvLyB1c2VkIHdpdGggaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgc2VtYW50aWNzLgorICAvLworICAvLworICBzdHJpbmcgdHlwZV91cmwgPSAxOworCisgIC8vIE11c3QgYmUgdmFsaWQgc2VyaWFsaXplZCBkYXRhIG9mIHRoZSBhYm92ZSBzcGVjaWZpZWQgdHlwZS4KKyAgYnl0ZXMgdmFsdWUgPSAyOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmEuY2MKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uYmRhMzc0MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmEuY2MKQEAgLTAsMCArMSwyODUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisKKyNpZmRlZiBBRERSRVNTX1NBTklUSVpFUgorI2luY2x1ZGUgPHNhbml0aXplci9hc2FuX2ludGVyZmFjZS5oPgorI2VuZGlmCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlNlcXVlbmNlTnVtYmVyIEFyZW5hOjpsaWZlY3ljbGVfaWRfZ2VuZXJhdG9yXzsKKyNpZmRlZiBQUk9UT0JVRl9VU0VfRExMUworQXJlbmE6OlRocmVhZENhY2hlJiBBcmVuYTo6dGhyZWFkX2NhY2hlKCkgeworICBzdGF0aWMgR09PR0xFX1RIUkVBRF9MT0NBTCBUaHJlYWRDYWNoZSB0aHJlYWRfY2FjaGVfID0geyAtMSwgTlVMTCB9OworICByZXR1cm4gdGhyZWFkX2NhY2hlXzsKK30KKyNlbHNlCitHT09HTEVfVEhSRUFEX0xPQ0FMIEFyZW5hOjpUaHJlYWRDYWNoZSBBcmVuYTo6dGhyZWFkX2NhY2hlXyA9IHsgLTEsIE5VTEwgfTsKKyNlbmRpZgorCit2b2lkIEFyZW5hOjpJbml0KCkgeworICBsaWZlY3ljbGVfaWRfID0gbGlmZWN5Y2xlX2lkX2dlbmVyYXRvcl8uR2V0TmV4dCgpOworICBibG9ja3NfID0gMDsKKyAgaGludF8gPSAwOworICBvd25zX2ZpcnN0X2Jsb2NrXyA9IHRydWU7CisgIGNsZWFudXBfbGlzdF8gPSAwOworCisgIGlmIChvcHRpb25zXy5pbml0aWFsX2Jsb2NrICE9IE5VTEwgJiYgb3B0aW9uc18uaW5pdGlhbF9ibG9ja19zaXplID4gMCkgeworICAgIC8vIEFkZCBmaXJzdCB1bm93bmVkIGJsb2NrIHRvIGxpc3QuCisgICAgQmxvY2sqIGZpcnN0X2Jsb2NrID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KG9wdGlvbnNfLmluaXRpYWxfYmxvY2spOworICAgIGZpcnN0X2Jsb2NrLT5zaXplID0gb3B0aW9uc18uaW5pdGlhbF9ibG9ja19zaXplOworICAgIGZpcnN0X2Jsb2NrLT5wb3MgPSBrSGVhZGVyU2l6ZTsKKyAgICBmaXJzdF9ibG9jay0+bmV4dCA9IE5VTEw7CisgICAgZmlyc3RfYmxvY2stPm93bmVyID0gJmZpcnN0X2Jsb2NrLT5vd25lcjsKKyAgICBBZGRCbG9jayhmaXJzdF9ibG9jayk7CisgICAgb3duc19maXJzdF9ibG9ja18gPSBmYWxzZTsKKyAgfQorCisgIC8vIENhbGwgdGhlIGluaXRpYWxpemF0aW9uIGhvb2sKKyAgaWYgKG9wdGlvbnNfLm9uX2FyZW5hX2luaXQgIT0gTlVMTCkgeworICAgIGhvb2tzX2Nvb2tpZV8gPSBvcHRpb25zXy5vbl9hcmVuYV9pbml0KHRoaXMpOworICB9IGVsc2UgeworICAgIGhvb2tzX2Nvb2tpZV8gPSBOVUxMOworICB9Cit9CisKK0FyZW5hOjp+QXJlbmEoKSB7CisgIHVpbnQ2NCBzcGFjZV9hbGxvY2F0ZWQgPSBSZXNldCgpOworCisgIC8vIENhbGwgdGhlIGRlc3RydWN0aW9uIGhvb2sKKyAgaWYgKG9wdGlvbnNfLm9uX2FyZW5hX2Rlc3RydWN0aW9uICE9IE5VTEwpIHsKKyAgICBvcHRpb25zXy5vbl9hcmVuYV9kZXN0cnVjdGlvbih0aGlzLCBob29rc19jb29raWVfLCBzcGFjZV9hbGxvY2F0ZWQpOworICB9Cit9CisKK3VpbnQ2NCBBcmVuYTo6UmVzZXQoKSB7CisgIENsZWFudXBMaXN0KCk7CisgIHVpbnQ2NCBzcGFjZV9hbGxvY2F0ZWQgPSBGcmVlQmxvY2tzKCk7CisgIC8vIEludmFsaWRhdGUgYW55IFRocmVhZENhY2hlcyBwb2ludGluZyB0byBhbnkgYmxvY2tzIHdlIGp1c3QgZGVzdHJveWVkLgorICBsaWZlY3ljbGVfaWRfID0gbGlmZWN5Y2xlX2lkX2dlbmVyYXRvcl8uR2V0TmV4dCgpOworCisgIC8vIENhbGwgdGhlIHJlc2V0IGhvb2sKKyAgaWYgKG9wdGlvbnNfLm9uX2FyZW5hX3Jlc2V0ICE9IE5VTEwpIHsKKyAgICBvcHRpb25zXy5vbl9hcmVuYV9yZXNldCh0aGlzLCBob29rc19jb29raWVfLCBzcGFjZV9hbGxvY2F0ZWQpOworICB9CisKKyAgcmV0dXJuIHNwYWNlX2FsbG9jYXRlZDsKK30KKworQXJlbmE6OkJsb2NrKiBBcmVuYTo6TmV3QmxvY2sodm9pZCogbWUsIEJsb2NrKiBteV9sYXN0X2Jsb2NrLCBzaXplX3QgbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzdGFydF9ibG9ja19zaXplLCBzaXplX3QgbWF4X2Jsb2NrX3NpemUpIHsKKyAgc2l6ZV90IHNpemU7CisgIGlmIChteV9sYXN0X2Jsb2NrICE9IE5VTEwpIHsKKyAgICAvLyBEb3VibGUgdGhlIGN1cnJlbnQgYmxvY2sgc2l6ZSwgdXAgdG8gYSBsaW1pdC4KKyAgICBzaXplID0gMiAqIChteV9sYXN0X2Jsb2NrLT5zaXplKTsKKyAgICBpZiAoc2l6ZSA+IG1heF9ibG9ja19zaXplKSBzaXplID0gbWF4X2Jsb2NrX3NpemU7CisgIH0gZWxzZSB7CisgICAgc2l6ZSA9IHN0YXJ0X2Jsb2NrX3NpemU7CisgIH0KKyAgaWYgKG4gPiBzaXplIC0ga0hlYWRlclNpemUpIHsKKyAgICAvLyBUT0RPKHNhbmpheSk6IENoZWNrIGlmIG4gKyBrSGVhZGVyU2l6ZSB3b3VsZCBvdmVyZmxvdworICAgIHNpemUgPSBrSGVhZGVyU2l6ZSArIG47CisgIH0KKworICBCbG9jayogYiA9IHJlaW50ZXJwcmV0X2Nhc3Q8QmxvY2sqPihvcHRpb25zXy5ibG9ja19hbGxvYyhzaXplKSk7CisgIGItPnBvcyA9IGtIZWFkZXJTaXplICsgbjsKKyAgYi0+c2l6ZSA9IHNpemU7CisgIGlmIChiLT5hdmFpbCgpID09IDApIHsKKyAgICAvLyBEbyBub3QgYXR0ZW1wdCB0byByZXVzZSB0aGlzIGJsb2NrLgorICAgIGItPm93bmVyID0gTlVMTDsKKyAgfSBlbHNlIHsKKyAgICBiLT5vd25lciA9IG1lOworICB9CisjaWZkZWYgQUREUkVTU19TQU5JVElaRVIKKyAgLy8gUG9pc29uIHRoZSByZXN0IG9mIHRoZSBibG9jayBmb3IgQVNBTi4gSXQgd2FzIHVucG9pc29uZWQgYnkgdGhlIHVuZGVybHlpbmcKKyAgLy8gbWFsbG9jIGJ1dCBpdCdzIG5vdCB5ZXQgdXNhYmxlIHVudGlsIHdlIHJldHVybiBpdCBhcyBwYXJ0IG9mIGFuIGFsbG9jYXRpb24uCisgIEFTQU5fUE9JU09OX01FTU9SWV9SRUdJT04oCisgICAgICByZWludGVycHJldF9jYXN0PGNoYXIqPihiKSArIGItPnBvcywgYi0+c2l6ZSAtIGItPnBvcyk7CisjZW5kaWYKKyAgcmV0dXJuIGI7Cit9CisKK3ZvaWQgQXJlbmE6OkFkZEJsb2NrKEJsb2NrKiBiKSB7CisgIE11dGV4TG9jayBsKCZibG9ja3NfbG9ja18pOworICBiLT5uZXh0ID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOb0JhcnJpZXJfTG9hZCgmYmxvY2tzXykpOworICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVsZWFzZV9TdG9yZSgmYmxvY2tzXywgcmVpbnRlcnByZXRfY2FzdDxnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXRvbWljV29yZD4oYikpOworICBpZiAoYi0+YXZhaWwoKSAhPSAwKSB7CisgICAgLy8gRGlyZWN0IGZ1dHVyZSBhbGxvY2F0aW9ucyB0byB0aGlzIGJsb2NrLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWxlYXNlX1N0b3JlKCZoaW50XywgcmVpbnRlcnByZXRfY2FzdDxnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXRvbWljV29yZD4oYikpOworICB9Cit9CisKK3ZvaWQgQXJlbmE6OkFkZExpc3ROb2RlKHZvaWQqIGVsZW0sIHZvaWQgKCpjbGVhbnVwKSh2b2lkKikpIHsKKyAgTm9kZSogbm9kZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Tm9kZSo+KEFsbG9jYXRlQWxpZ25lZChzaXplb2YoTm9kZSkpKTsKKyAgbm9kZS0+ZWxlbSA9IGVsZW07CisgIG5vZGUtPmNsZWFudXAgPSBjbGVhbnVwOworICBub2RlLT5uZXh0ID0gcmVpbnRlcnByZXRfY2FzdDxOb2RlKj4oCisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKCZjbGVhbnVwX2xpc3RfLAorICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXRvbWljV29yZD4obm9kZSkpKTsKK30KKwordm9pZCogQXJlbmE6OkFsbG9jYXRlQWxpZ25lZChzaXplX3QgbikgeworICAvLyBBbGlnbiBuIHRvIG5leHQgbXVsdGlwbGUgb2YgOCAoZnJvbSBIYWNrZXIncyBEZWxpZ2h0LCBDaGFwdGVyIDMuKQorICBuID0gKG4gKyA3KSAmIC04OworCisgIC8vIElmIHRoaXMgdGhyZWFkIGFscmVhZHkgb3ducyBhIGJsb2NrIGluIHRoaXMgYXJlbmEgdGhlbiB0cnkgdG8gdXNlIHRoYXQuCisgIC8vIFRoaXMgZmFzdCBwYXRoIG9wdGltaXplcyB0aGUgY2FzZSB3aGVyZSBtdWx0aXBsZSB0aHJlYWRzIGFsbG9jYXRlIGZyb20gdGhlCisgIC8vIHNhbWUgYXJlbmEuCisgIGlmICh0aHJlYWRfY2FjaGUoKS5sYXN0X2xpZmVjeWNsZV9pZF9zZWVuID09IGxpZmVjeWNsZV9pZF8gJiYKKyAgICAgIHRocmVhZF9jYWNoZSgpLmxhc3RfYmxvY2tfdXNlZF8gIT0gTlVMTCkgeworICAgIGlmICh0aHJlYWRfY2FjaGUoKS5sYXN0X2Jsb2NrX3VzZWRfLT5hdmFpbCgpIDwgbikgeworICAgICAgcmV0dXJuIFNsb3dBbGxvYyhuKTsKKyAgICB9CisgICAgcmV0dXJuIEFsbG9jRnJvbUJsb2NrKHRocmVhZF9jYWNoZSgpLmxhc3RfYmxvY2tfdXNlZF8sIG4pOworICB9CisKKyAgLy8gQ2hlY2sgd2hldGhlciB3ZSBvd24gdGhlIGxhc3QgYWNjZXNzZWQgYmxvY2sgb24gdGhpcyBhcmVuYS4KKyAgLy8gVGhpcyBmYXN0IHBhdGggb3B0aW1pemVzIHRoZSBjYXNlIHdoZXJlIGEgc2luZ2xlIHRocmVhZCB1c2VzIG11bHRpcGxlCisgIC8vIGFyZW5hcy4KKyAgdm9pZCogbWUgPSAmdGhyZWFkX2NhY2hlKCk7CisgIEJsb2NrKiBiID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBY3F1aXJlX0xvYWQoJmhpbnRfKSk7CisgIGlmICghYiB8fCBiLT5vd25lciAhPSBtZSB8fCBiLT5hdmFpbCgpIDwgbikgeworICAgIC8vIElmIHRoZSBuZXh0IGJsb2NrIHRvIGFsbG9jYXRlIGZyb20gaXMgdGhlIGZpcnN0IGJsb2NrLCB0cnkgdG8gY2xhaW0gaXQKKyAgICAvLyBmb3IgdGhpcyB0aHJlYWQuCisgICAgaWYgKCFvd25zX2ZpcnN0X2Jsb2NrXyAmJiBiLT5uZXh0ID09IE5VTEwpIHsKKyAgICAgIE11dGV4TG9jayBsKCZibG9ja3NfbG9ja18pOworICAgICAgaWYgKGItPm93bmVyID09ICZiLT5vd25lciAmJiBiLT5hdmFpbCgpID49IG4pIHsKKyAgICAgICAgYi0+b3duZXIgPSBtZTsKKyAgICAgICAgU2V0VGhyZWFkQ2FjaGVCbG9jayhiKTsKKyAgICAgICAgcmV0dXJuIEFsbG9jRnJvbUJsb2NrKGIsIG4pOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gU2xvd0FsbG9jKG4pOworICB9CisgIHJldHVybiBBbGxvY0Zyb21CbG9jayhiLCBuKTsKK30KKwordm9pZCogQXJlbmE6OkFsbG9jRnJvbUJsb2NrKEJsb2NrKiBiLCBzaXplX3QgbikgeworICBzaXplX3QgcCA9IGItPnBvczsKKyAgYi0+cG9zID0gcCArIG47CisjaWZkZWYgQUREUkVTU19TQU5JVElaRVIKKyAgQVNBTl9VTlBPSVNPTl9NRU1PUllfUkVHSU9OKHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KGIpICsgcCwgbik7CisjZW5kaWYKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KGIpICsgcDsKK30KKwordm9pZCogQXJlbmE6OlNsb3dBbGxvYyhzaXplX3QgbikgeworICB2b2lkKiBtZSA9ICZ0aHJlYWRfY2FjaGUoKTsKKyAgQmxvY2sqIGIgPSBGaW5kQmxvY2sobWUpOyAgLy8gRmluZCBibG9jayBvd25lZCBieSBtZS4KKyAgLy8gU2VlIGlmIGFsbG9jYXRpb24gZml0cyBpbiBteSBsYXRlc3QgYmxvY2suCisgIGlmIChiICE9IE5VTEwgJiYgYi0+YXZhaWwoKSA+PSBuKSB7CisgICAgU2V0VGhyZWFkQ2FjaGVCbG9jayhiKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX1N0b3JlKCZoaW50XywgcmVpbnRlcnByZXRfY2FzdDxnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXRvbWljV29yZD4oYikpOworICAgIHJldHVybiBBbGxvY0Zyb21CbG9jayhiLCBuKTsKKyAgfQorICBiID0gTmV3QmxvY2sobWUsIGIsIG4sIG9wdGlvbnNfLnN0YXJ0X2Jsb2NrX3NpemUsIG9wdGlvbnNfLm1heF9ibG9ja19zaXplKTsKKyAgQWRkQmxvY2soYik7CisgIGlmIChiLT5vd25lciA9PSBtZSkgeyAgLy8gSWYgdGhpcyBibG9jayBjYW4gYmUgcmV1c2VkIChzZWUgTmV3QmxvY2soKSkuCisgICAgU2V0VGhyZWFkQ2FjaGVCbG9jayhiKTsKKyAgfQorICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oYikgKyBrSGVhZGVyU2l6ZTsKK30KKwordWludDY0IEFyZW5hOjpTcGFjZUFsbG9jYXRlZCgpIGNvbnN0IHsKKyAgdWludDY0IHNwYWNlX2FsbG9jYXRlZCA9IDA7CisgIEJsb2NrKiBiID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOb0JhcnJpZXJfTG9hZCgmYmxvY2tzXykpOworICB3aGlsZSAoYiAhPSBOVUxMKSB7CisgICAgc3BhY2VfYWxsb2NhdGVkICs9IChiLT5zaXplKTsKKyAgICBiID0gYi0+bmV4dDsKKyAgfQorICByZXR1cm4gc3BhY2VfYWxsb2NhdGVkOworfQorCit1aW50NjQgQXJlbmE6OlNwYWNlVXNlZCgpIGNvbnN0IHsKKyAgdWludDY0IHNwYWNlX3VzZWQgPSAwOworICBCbG9jayogYiA9IHJlaW50ZXJwcmV0X2Nhc3Q8QmxvY2sqPihnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX0xvYWQoJmJsb2Nrc18pKTsKKyAgd2hpbGUgKGIgIT0gTlVMTCkgeworICAgIHNwYWNlX3VzZWQgKz0gKGItPnBvcyAtIGtIZWFkZXJTaXplKTsKKyAgICBiID0gYi0+bmV4dDsKKyAgfQorICByZXR1cm4gc3BhY2VfdXNlZDsKK30KKwordWludDY0IEFyZW5hOjpGcmVlQmxvY2tzKCkgeworICB1aW50NjQgc3BhY2VfYWxsb2NhdGVkID0gMDsKKyAgQmxvY2sqIGIgPSByZWludGVycHJldF9jYXN0PEJsb2NrKj4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vQmFycmllcl9Mb2FkKCZibG9ja3NfKSk7CisgIEJsb2NrKiBmaXJzdF9ibG9jayA9IE5VTEw7CisgIHdoaWxlIChiICE9IE5VTEwpIHsKKyAgICBzcGFjZV9hbGxvY2F0ZWQgKz0gKGItPnNpemUpOworICAgIEJsb2NrKiBuZXh0ID0gYi0+bmV4dDsKKyAgICBpZiAobmV4dCAhPSBOVUxMKSB7CisgICAgICBvcHRpb25zXy5ibG9ja19kZWFsbG9jKGIsIGItPnNpemUpOworICAgIH0gZWxzZSB7CisgICAgICBpZiAob3duc19maXJzdF9ibG9ja18pIHsKKyAgICAgICAgb3B0aW9uc18uYmxvY2tfZGVhbGxvYyhiLCBiLT5zaXplKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFVzZXIgcGFzc2VkIGluIHRoZSBmaXJzdCBibG9jaywgc2tpcCBmcmVlJ2luZyB0aGUgbWVtb3J5LgorICAgICAgICBmaXJzdF9ibG9jayA9IGI7CisgICAgICB9CisgICAgfQorICAgIGIgPSBuZXh0OworICB9CisgIGJsb2Nrc18gPSAwOworICBoaW50XyA9IDA7CisgIGlmICghb3duc19maXJzdF9ibG9ja18pIHsKKyAgICAvLyBNYWtlIHRoZSBmaXJzdCBibG9jayB0aGF0IHdhcyBwYXNzZWQgaW4gdGhyb3VnaCBBcmVuYU9wdGlvbnMKKyAgICAvLyBhdmFpbGFibGUgZm9yIHJldXNlLgorICAgIGZpcnN0X2Jsb2NrLT5wb3MgPSBrSGVhZGVyU2l6ZTsKKyAgICBmaXJzdF9ibG9jay0+b3duZXIgPSAmZmlyc3RfYmxvY2stPm93bmVyOworICAgIEFkZEJsb2NrKGZpcnN0X2Jsb2NrKTsKKyAgfQorICByZXR1cm4gc3BhY2VfYWxsb2NhdGVkOworfQorCit2b2lkIEFyZW5hOjpDbGVhbnVwTGlzdCgpIHsKKyAgTm9kZSogaGVhZCA9CisgICAgICByZWludGVycHJldF9jYXN0PE5vZGUqPihnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX0xvYWQoJmNsZWFudXBfbGlzdF8pKTsKKyAgd2hpbGUgKGhlYWQgIT0gTlVMTCkgeworICAgIGhlYWQtPmNsZWFudXAoaGVhZC0+ZWxlbSk7CisgICAgaGVhZCA9IGhlYWQtPm5leHQ7CisgIH0KKyAgY2xlYW51cF9saXN0XyA9IDA7Cit9CisKK0FyZW5hOjpCbG9jayogQXJlbmE6OkZpbmRCbG9jayh2b2lkKiBtZSkgeworICAvLyBUT0RPKHNhbmpheSk6IFdlIG1pZ2h0IHdhbnQgdG8ga2VlcCBhIHNlcGFyYXRlIGxpc3Qgd2l0aCBvbmUKKyAgLy8gZW50cnkgcGVyIHRocmVhZC4KKyAgQmxvY2sqIGIgPSByZWludGVycHJldF9jYXN0PEJsb2NrKj4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFjcXVpcmVfTG9hZCgmYmxvY2tzXykpOworICB3aGlsZSAoYiAhPSBOVUxMICYmIGItPm93bmVyICE9IG1lKSB7CisgICAgYiA9IGItPm5leHQ7CisgIH0KKyAgcmV0dXJuIGI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiMTVlODAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hLmgKQEAgLTAsMCArMSw2MDIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGhlYWRlciBpcyBsb2dpY2FsbHkgaW50ZXJuYWwsIGJ1dCBpcyBtYWRlIHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQKKy8vIGZyb20gcHJvdG9jb2wtY29tcGlsZXItZ2VuZXJhdGVkIGNvZGUsIHdoaWNoIG1heSByZXNpZGUgaW4gb3RoZXIgY29tcG9uZW50cy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVJFTkFfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9IX18KKworI2luY2x1ZGUgPHR5cGVpbmZvPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY19zZXF1ZW5jZV9udW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIEFyZW5hOyAgICAgICAvLyBkZWZpbmVkIGJlbG93CitjbGFzcyBNZXNzYWdlOyAgICAgLy8gbWVzc2FnZS5oCisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CitjbGFzcyBBcmVuYVN0cmluZzsgLy8gYXJlbmFzdHJpbmcuaAorY2xhc3MgTGF6eUZpZWxkOyAgIC8vIGxhenlfZmllbGQuaAorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPgorY2xhc3MgR2VuZXJpY1R5cGVIYW5kbGVyOyAvLyByZXBlYXRlZF9maWVsZC5oCisKKy8vIFRlbXBsYXRlZCBjbGVhbnVwIG1ldGhvZHMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB2b2lkIGFyZW5hX2Rlc3RydWN0X29iamVjdCh2b2lkKiBvYmplY3QpIHsKKyAgcmVpbnRlcnByZXRfY2FzdDxUKj4ob2JqZWN0KS0+flQoKTsKK30KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHZvaWQgYXJlbmFfZGVsZXRlX29iamVjdCh2b2lkKiBvYmplY3QpIHsKKyAgZGVsZXRlIHJlaW50ZXJwcmV0X2Nhc3Q8VCo+KG9iamVjdCk7Cit9CitpbmxpbmUgdm9pZCBhcmVuYV9mcmVlKHZvaWQqIG9iamVjdCwgc2l6ZV90IHNpemUpIHsKKyAgZnJlZShvYmplY3QpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gQXJlbmFPcHRpb25zIHByb3ZpZGVzIG9wdGlvbmFsIGFkZGl0aW9uYWwgcGFyYW1ldGVycyB0byBhcmVuYSBjb25zdHJ1Y3Rpb24KKy8vIHRoYXQgY29udHJvbCBpdHMgYmxvY2stYWxsb2NhdGlvbiBiZWhhdmlvci4KK3N0cnVjdCBBcmVuYU9wdGlvbnMgeworICAvLyBUaGlzIGRlZmluZXMgdGhlIHNpemUgb2YgdGhlIGZpcnN0IGJsb2NrIHJlcXVlc3RlZCBmcm9tIHRoZSBzeXN0ZW0gbWFsbG9jLgorICAvLyBTdWJzZXF1ZW50IGJsb2NrIHNpemVzIHdpbGwgaW5jcmVhc2UgaW4gYSBnZW9tZXRyaWMgc2VyaWVzIHVwIHRvIGEgbWF4aW11bS4KKyAgc2l6ZV90IHN0YXJ0X2Jsb2NrX3NpemU7CisKKyAgLy8gVGhpcyBkZWZpbmVzIHRoZSBtYXhpbXVtIGJsb2NrIHNpemUgcmVxdWVzdGVkIGZyb20gc3lzdGVtIG1hbGxvYyAodW5sZXNzIGFuCisgIC8vIGluZGl2aWR1YWwgYXJlbmEgYWxsb2NhdGlvbiByZXF1ZXN0IG9jY3VycyB3aXRoIGEgc2l6ZSBsYXJnZXIgdGhhbiB0aGlzCisgIC8vIG1heGltdW0pLiBSZXF1ZXN0ZWQgYmxvY2sgc2l6ZXMgaW5jcmVhc2UgdXAgdG8gdGhpcyB2YWx1ZSwgdGhlbiByZW1haW4KKyAgLy8gaGVyZS4KKyAgc2l6ZV90IG1heF9ibG9ja19zaXplOworCisgIC8vIEFuIGluaXRpYWwgYmxvY2sgb2YgbWVtb3J5IGZvciB0aGUgYXJlbmEgdG8gdXNlLCBvciBOVUxMIGZvciBub25lLiBJZgorICAvLyBwcm92aWRlZCwgdGhlIGJsb2NrIG11c3QgbGl2ZSBhdCBsZWFzdCBhcyBsb25nIGFzIHRoZSBhcmVuYSBpdHNlbGYuIFRoZQorICAvLyBjcmVhdG9yIG9mIHRoZSBBcmVuYSByZXRhaW5zIG93bmVyc2hpcCBvZiB0aGUgYmxvY2sgYWZ0ZXIgdGhlIEFyZW5hIGlzCisgIC8vIGRlc3Ryb3llZC4KKyAgY2hhciogaW5pdGlhbF9ibG9jazsKKworICAvLyBUaGUgc2l6ZSBvZiB0aGUgaW5pdGlhbCBibG9jaywgaWYgcHJvdmlkZWQuCisgIHNpemVfdCBpbml0aWFsX2Jsb2NrX3NpemU7CisKKyAgLy8gQSBmdW5jdGlvbiBwb2ludGVyIHRvIGFuIGFsbG9jIG1ldGhvZCB0aGF0IHJldHVybnMgbWVtb3J5IGJsb2NrcyBvZiBzaXplCisgIC8vIHJlcXVlc3RlZC4gQnkgZGVmYXVsdCwgaXQgY29udGFpbnMgYSBwdHIgdG8gdGhlIG1hbGxvYyBmdW5jdGlvbi4KKyAgLy8KKyAgLy8gTk9URTogYmxvY2tfYWxsb2MgYW5kIGRlYWxsb2MgZnVuY3Rpb25zIGFyZSBleHBlY3RlZCB0byBiZWhhdmUgbGlrZQorICAvLyBtYWxsb2MgYW5kIGZyZWUsIGluY2x1ZGluZyBBc2FuIHBvaXNvbmluZy4KKyAgdm9pZCogKCpibG9ja19hbGxvYykoc2l6ZV90KTsKKyAgLy8gQSBmdW5jdGlvbiBwb2ludGVyIHRvIGEgZGVhbGxvYyBtZXRob2QgdGhhdCB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIGJsb2NrcworICAvLyBmcm9tIHRoZSBhcmVuYS4gQnkgZGVmYXVsdCwgaXQgY29udGFpbnMgYSBwdHIgdG8gYSB3cmFwcGVyIGZ1bmN0aW9uIHRoYXQKKyAgLy8gY2FsbHMgZnJlZS4KKyAgdm9pZCAoKmJsb2NrX2RlYWxsb2MpKHZvaWQqLCBzaXplX3QpOworCisgIC8vIEhvb2tzIGZvciBhZGRpbmcgZXh0ZXJuYWwgZnVuY3Rpb25hbGl0eSBzdWNoIGFzIHVzZXItc3BlY2lmaWMgbWV0cmljcworICAvLyBjb2xsZWN0aW9uLCBzcGVjaWZpYyBkZWJ1Z2dpbmcgYWJpbGl0aWVzLCBldGMuCisgIC8vIEluaXQgaG9vayBtYXkgcmV0dXJuIGEgcG9pbnRlciB0byBhIGNvb2tpZSB0byBiZSBzdG9yZWQgaW4gdGhlIGFyZW5hLgorICAvLyByZXNldCBhbmQgZGVzdHJ1Y3Rpb24gaG9va3Mgd2lsbCB0aGVuIGJlIGNhbGxlZCB3aXRoIHRoZSBzYW1lIGNvb2tpZQorICAvLyBwb2ludGVyLiBUaGlzIGFsbG93cyB1cyB0byBzYXZlIGFuIGV4dGVybmFsIG9iamVjdCBwZXIgYXJlbmEgaW5zdGFuY2UgYW5kCisgIC8vIHVzZSBpdCBvbiB0aGUgb3RoZXIgaG9va3MgKE5vdGU6IEl0IGlzIGp1c3QgYXMgbGVnYWwgZm9yIGluaXQgdG8gcmV0dXJuCisgIC8vIE5VTEwgYW5kIG5vdCB1c2UgdGhlIGNvb2tpZSBmZWF0dXJlKS4KKyAgLy8gb25fYXJlbmFfcmVzZXQgYW5kIG9uX2FyZW5hX2Rlc3RydWN0aW9uIGFsc28gcmVjZWl2ZSB0aGUgc3BhY2UgdXNlZCBpbgorICAvLyB0aGUgYXJlbmEganVzdCBiZWZvcmUgdGhlIHJlc2V0LgorICB2b2lkKiAoKm9uX2FyZW5hX2luaXQpKEFyZW5hKiBhcmVuYSk7CisgIHZvaWQgKCpvbl9hcmVuYV9yZXNldCkoQXJlbmEqIGFyZW5hLCB2b2lkKiBjb29raWUsIHVpbnQ2NCBzcGFjZV91c2VkKTsKKyAgdm9pZCAoKm9uX2FyZW5hX2Rlc3RydWN0aW9uKShBcmVuYSogYXJlbmEsIHZvaWQqIGNvb2tpZSwgdWludDY0IHNwYWNlX3VzZWQpOworCisgIC8vIHR5cGVfbmFtZSBpcyBwcm9taXNlZCB0byBiZSBhIHN0YXRpYyBzdHJpbmcgLSBpdHMgbGlmZXRpbWUgZXh0ZW5kcyB0bworICAvLyBtYXRjaCBwcm9ncmFtJ3MgbGlmZXRpbWUuCisgIHZvaWQgKCpvbl9hcmVuYV9hbGxvY2F0aW9uKShjb25zdCBjaGFyKiB0eXBlX25hbWUsIHVpbnQ2NCBhbGxvY19zaXplLAorICAgICAgQXJlbmEqIGFyZW5hLCB2b2lkKiBjb29raWUpOworCisgIEFyZW5hT3B0aW9ucygpCisgICAgICA6IHN0YXJ0X2Jsb2NrX3NpemUoa0RlZmF1bHRTdGFydEJsb2NrU2l6ZSksCisgICAgICAgIG1heF9ibG9ja19zaXplKGtEZWZhdWx0TWF4QmxvY2tTaXplKSwKKyAgICAgICAgaW5pdGlhbF9ibG9jayhOVUxMKSwKKyAgICAgICAgaW5pdGlhbF9ibG9ja19zaXplKDApLAorICAgICAgICBibG9ja19hbGxvYygmbWFsbG9jKSwKKyAgICAgICAgYmxvY2tfZGVhbGxvYygmaW50ZXJuYWw6OmFyZW5hX2ZyZWUpLAorICAgICAgICBvbl9hcmVuYV9pbml0KE5VTEwpLAorICAgICAgICBvbl9hcmVuYV9yZXNldChOVUxMKSwKKyAgICAgICAgb25fYXJlbmFfZGVzdHJ1Y3Rpb24oTlVMTCksCisgICAgICAgIG9uX2FyZW5hX2FsbG9jYXRpb24oTlVMTCkge30KKworIHByaXZhdGU6CisgIC8vIENvbnN0YW50cyBkZWZpbmUgZGVmYXVsdCBzdGFydGluZyBibG9jayBzaXplIGFuZCBtYXggYmxvY2sgc2l6ZSBmb3IKKyAgLy8gYXJlbmEgYWxsb2NhdG9yIGJlaGF2aW9yIC0tIHNlZSBkZXNjcmlwdGlvbnMgYWJvdmUuCisgIHN0YXRpYyBjb25zdCBzaXplX3Qga0RlZmF1bHRTdGFydEJsb2NrU2l6ZSA9IDI1NjsKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBrRGVmYXVsdE1heEJsb2NrU2l6ZSAgID0gODE5MjsKK307CisKKy8vIEFyZW5hIGFsbG9jYXRvci4gQXJlbmEgYWxsb2NhdGlvbiByZXBsYWNlcyBvcmRpbmFyeSAoaGVhcC1iYXNlZCkgYWxsb2NhdGlvbgorLy8gd2l0aCBuZXcvZGVsZXRlLCBhbmQgaW1wcm92ZXMgcGVyZm9ybWFuY2UgYnkgYWdncmVnYXRpbmcgYWxsb2NhdGlvbnMgaW50bworLy8gbGFyZ2VyIGJsb2NrcyBhbmQgZnJlZWluZyBhbGxvY2F0aW9ucyBhbGwgYXQgb25jZS4gUHJvdG9jb2wgbWVzc2FnZXMgYXJlCisvLyBhbGxvY2F0ZWQgb24gYW4gYXJlbmEgYnkgdXNpbmcgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VD4oQXJlbmEqKSwgYmVsb3csIGFuZAorLy8gYXJlIGF1dG9tYXRpY2FsbHkgZnJlZWQgd2hlbiB0aGUgYXJlbmEgaXMgZGVzdHJveWVkLgorLy8KKy8vIFRoaXMgaXMgYSB0aHJlYWQtc2FmZSBpbXBsZW1lbnRhdGlvbjogbXVsdGlwbGUgdGhyZWFkcyBtYXkgYWxsb2NhdGUgZnJvbSB0aGUKKy8vIGFyZW5hIGNvbmN1cnJlbnRseS4gRGVzdHJ1Y3Rpb24gaXMgbm90IHRocmVhZC1zYWZlIGFuZCB0aGUgZGVzdHJ1Y3RpbmcKKy8vIHRocmVhZCBtdXN0IHN5bmNocm9uaXplIHdpdGggdXNlcnMgb2YgdGhlIGFyZW5hIGZpcnN0LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEFyZW5hIHsKKyBwdWJsaWM6CisgIC8vIEFyZW5hIGNvbnN0cnVjdG9yIHRha2luZyBjdXN0b20gb3B0aW9ucy4gU2VlIEFyZW5hT3B0aW9ucyBiZWxvdyBmb3IKKyAgLy8gZGVzY3JpcHRpb25zIG9mIHRoZSBvcHRpb25zIGF2YWlsYWJsZS4KKyAgZXhwbGljaXQgQXJlbmEoY29uc3QgQXJlbmFPcHRpb25zJiBvcHRpb25zKSA6IG9wdGlvbnNfKG9wdGlvbnMpIHsKKyAgICBJbml0KCk7CisgIH0KKworICAvLyBEZWZhdWx0IGNvbnN0cnVjdG9yIHdpdGggc2Vuc2libGUgZGVmYXVsdCBvcHRpb25zLCB0dW5lZCBmb3IgYXZlcmFnZQorICAvLyB1c2UtY2FzZXMuCisgIEFyZW5hKCkgeworICAgIEluaXQoKTsKKyAgfQorCisgIC8vIERlc3RydWN0b3IgZGVsZXRlcyBhbGwgb3duZWQgaGVhcCBhbGxvY2F0ZWQgb2JqZWN0cywgYW5kIGRlc3RydWN0cyBvYmplY3RzCisgIC8vIHRoYXQgaGF2ZSBub24tdHJpdmlhbCBkZXN0cnVjdG9ycywgZXhjZXB0IGZvciBwcm90bzIgbWVzc2FnZSBvYmplY3RzIHdob3NlCisgIC8vIGRlc3RydWN0b3JzIGNhbiBiZSBza2lwcGVkLiBBbHNvLCBmcmVlcyBhbGwgYmxvY2tzIGV4Y2VwdCB0aGUgaW5pdGlhbCBibG9jaworICAvLyBpZiBpdCB3YXMgcGFzc2VkIGluLgorICB+QXJlbmEoKTsKKworICAvLyBBUEkgdG8gY3JlYXRlIHByb3RvMiBtZXNzYWdlIG9iamVjdHMgb24gdGhlIGFyZW5hLiBJZiB0aGUgYXJlbmEgcGFzc2VkIGluCisgIC8vIGlzIE5VTEwsIHRoZW4gYSBoZWFwIGFsbG9jYXRlZCBvYmplY3QgaXMgcmV0dXJuZWQuIFR5cGUgVCBtdXN0IGJlIGEgbWVzc2FnZQorICAvLyBkZWZpbmVkIGluIGEgLnByb3RvIGZpbGUgd2l0aCBjY19lbmFibGVfYXJlbmFzIHNldCB0byB0cnVlLCBvdGhlcndpc2UgYQorICAvLyBjb21waWxhdGlvbiBlcnJvciB3aWxsIG9jY3VyLgorICAvLworICAvLyBSZXBlYXRlZEZpZWxkIGFuZCBSZXBlYXRlZFB0ckZpZWxkIG1heSBhbHNvIGJlIGluc3RhbnRpYXRlZCBkaXJlY3RseSBvbiBhbgorICAvLyBhcmVuYSB3aXRoIHRoaXMgbWV0aG9kOiB0aGV5IGFjdCBhcyAiYXJlbmEtY2FwYWJsZSBtZXNzYWdlIHR5cGVzIiBmb3IgdGhlCisgIC8vIHB1cnBvc2VzIG9mIHRoZSBBcmVuYSBBUEkuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIFQqIENyZWF0ZU1lc3NhZ2UoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyBUOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gYXJlbmEtPkNyZWF0ZU1lc3NhZ2VJbnRlcm5hbDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpOworICAgIH0KKyAgfQorCisgIC8vIEFQSSB0byBjcmVhdGUgYW55IG9iamVjdHMgb24gdGhlIGFyZW5hLiBOb3RlIHRoYXQgb25seSB0aGUgb2JqZWN0IHdpbGwKKyAgLy8gYmUgY3JlYXRlZCBvbiB0aGUgYXJlbmE7IHRoZSB1bmRlcmx5aW5nIHB0cnMgKGluIGNhc2Ugb2YgYSBwcm90bzIgbWVzc2FnZSkKKyAgLy8gd2lsbCBiZSBzdGlsbCBoZWFwIGFsbG9jYXRlZC4gUHJvdG8gbWVzc2FnZXMgc2hvdWxkIHVzdWFsbHkgYmUgYWxsb2NhdGVkCisgIC8vIHdpdGggQ3JlYXRlTWVzc2FnZTxUPigpIGluc3RlYWQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIFQqIENyZWF0ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVJbnRlcm5hbDxUPigKKyAgICAgICAgICBTa2lwRGVsZXRlTGlzdDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIG9uZSBjb25zdHJ1Y3RvciBhcmd1bWVudCBmb3IgdGhlIGNyZWF0ZWQgb2JqZWN0LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIFQqIENyZWF0ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwgY29uc3QgQXJnJiBhcmcpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyBUKGFyZyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oU2tpcERlbGV0ZUxpc3Q8VD4oc3RhdGljX2Nhc3Q8VCo+KDApKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIHR3byBjb25zdHJ1Y3RvciBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGVkIG9iamVjdC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgVCogQ3JlYXRlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLCBjb25zdCBBcmcxJiBhcmcxLCBjb25zdCBBcmcyJiBhcmcyKSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgVChhcmcxLCBhcmcyKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVJbnRlcm5hbDxUPihTa2lwRGVsZXRlTGlzdDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcyKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIHRocmVlIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBmb3IgdGhlIGNyZWF0ZWQKKyAgLy8gb2JqZWN0LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMiwgdHlwZW5hbWUgQXJnMz4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHN0YXRpYyBUKiBDcmVhdGUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMSYgYXJnMSwgY29uc3QgQXJnMiYgYXJnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmczJiBhcmczKSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgVChhcmcxLCBhcmcyLCBhcmczKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVJbnRlcm5hbDxUPihTa2lwRGVsZXRlTGlzdDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmczKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIGZvdXIgY29uc3RydWN0b3IgYXJndW1lbnRzIGZvciB0aGUgY3JlYXRlZAorICAvLyBvYmplY3QuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyLCB0eXBlbmFtZSBBcmczLAorICAgICAgICAgICAgdHlwZW5hbWUgQXJnND4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHN0YXRpYyBUKiBDcmVhdGUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMSYgYXJnMSwgY29uc3QgQXJnMiYgYXJnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmczJiBhcmczLCBjb25zdCBBcmc0JiBhcmc0KSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgVChhcmcxLCBhcmcyLCBhcmczLCBhcmc0KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVJbnRlcm5hbDxUPihTa2lwRGVsZXRlTGlzdDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmczLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmc0KTsKKyAgICB9CisgIH0KKworICAvLyBDcmVhdGUgYW4gYXJyYXkgb2Ygb2JqZWN0IHR5cGUgVCBvbiB0aGUgYXJlbmEuIFR5cGUgVCBtdXN0IGhhdmUgYSB0cml2aWFsCisgIC8vIGNvbnN0cnVjdG9yLCBhcyBpdCB3aWxsIG5vdCBiZSBpbnZva2VkIHdoZW4gY3JlYXRlZCBvbiB0aGUgYXJlbmEuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIFQqIENyZWF0ZUFycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLCBzaXplX3QgbnVtX2VsZW1lbnRzKSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgVFtudW1fZWxlbWVudHNdOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gYXJlbmEtPkNyZWF0ZUludGVybmFsUmF3QXJyYXk8VD4obnVtX2VsZW1lbnRzKTsKKyAgICB9CisgIH0KKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBzcGFjZSB1c2VkIGJ5IHRoZSBhcmVuYSwgd2hpY2ggaXMgdGhlIHN1bXMgb2YgdGhlIHNpemVzCisgIC8vIG9mIHRoZSB1bmRlcmx5aW5nIGJsb2Nrcy4gVGhlIHRvdGFsIHNwYWNlIHVzZWQgbWF5IG5vdCBpbmNsdWRlIHRoZSBuZXcKKyAgLy8gYmxvY2tzIHRoYXQgYXJlIGFsbG9jYXRlZCBieSB0aGlzIGFyZW5hIGZyb20gb3RoZXIgdGhyZWFkcyBjb25jdXJyZW50bHkKKyAgLy8gd2l0aCB0aGUgY2FsbCB0byB0aGlzIG1ldGhvZC4KKyAgdWludDY0IFNwYWNlQWxsb2NhdGVkKCkgY29uc3QgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORTsKKyAgLy8gQXMgYWJvdmUsIGJ1dCBkb2VzIG5vdCBpbmNsdWRlIGFueSBmcmVlIHNwYWNlIGluIHVuZGVybHlpbmcgYmxvY2tzLgorICB1aW50NjQgU3BhY2VVc2VkKCkgY29uc3QgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORTsKKworICAvLyBGcmVlcyBhbGwgc3RvcmFnZSBhbGxvY2F0ZWQgYnkgdGhpcyBhcmVuYSBhZnRlciBjYWxsaW5nIGRlc3RydWN0b3JzCisgIC8vIHJlZ2lzdGVyZWQgd2l0aCBPd25EZXN0cnVjdG9yKCkgYW5kIGZyZWVpbmcgb2JqZWN0cyByZWdpc3RlcmVkIHdpdGggT3duKCkuCisgIC8vIEFueSBvYmplY3RzIGFsbG9jYXRlZCBvbiB0aGlzIGFyZW5hIGFyZSB1bnVzYWJsZSBhZnRlciB0aGlzIGNhbGwuIEl0IGFsc28KKyAgLy8gcmV0dXJucyB0aGUgdG90YWwgc3BhY2UgdXNlZCBieSB0aGUgYXJlbmEgd2hpY2ggaXMgdGhlIHN1bXMgb2YgdGhlIHNpemVzCisgIC8vIG9mIHRoZSBhbGxvY2F0ZWQgYmxvY2tzLiBUaGlzIG1ldGhvZCBpcyBub3QgdGhyZWFkLXNhZmUuCisgIHVpbnQ2NCBSZXNldCgpIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkU7CisKKyAgLy8gQWRkcyB8b2JqZWN0fCB0byBhIGxpc3Qgb2YgaGVhcC1hbGxvY2F0ZWQgb2JqZWN0cyB0byBiZSBmcmVlZCB3aXRoIHxkZWxldGV8CisgIC8vIHdoZW4gdGhlIGFyZW5hIGlzIGRlc3Ryb3llZCBvciByZXNldC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUKKyAgdm9pZCBPd24oVCogb2JqZWN0KSB7CisgICAgT3duSW50ZXJuYWwob2JqZWN0LCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfY29udmVydGlibGU8VCosIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSo+KCkpOworICB9CisKKyAgLy8gQWRkcyB8b2JqZWN0fCB0byBhIGxpc3Qgb2Ygb2JqZWN0cyB3aG9zZSBkZXN0cnVjdG9ycyB3aWxsIGJlIG1hbnVhbGx5CisgIC8vIGNhbGxlZCB3aGVuIHRoZSBhcmVuYSBpcyBkZXN0cm95ZWQgb3IgcmVzZXQuIFRoaXMgZGlmZmVycyBmcm9tIE93bigpIGluCisgIC8vIHRoYXQgaXQgZG9lcyBub3QgZnJlZSB0aGUgdW5kZXJseWluZyBtZW1vcnkgd2l0aCB8ZGVsZXRlfDsgaGVuY2UsIGl0IGlzCisgIC8vIG5vcm1hbGx5IG9ubHkgdXNlZCBmb3Igb2JqZWN0cyB0aGF0IGFyZSBwbGFjZW1lbnQtbmV3ZWQgaW50bworICAvLyBhcmVuYS1hbGxvY2F0ZWQgbWVtb3J5LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9OT0lOTElORQorICB2b2lkIE93bkRlc3RydWN0b3IoVCogb2JqZWN0KSB7CisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSB7CisgICAgICBBZGRMaXN0Tm9kZShvYmplY3QsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgIH0KKworICAvLyBBZGRzIGEgY3VzdG9tIG1lbWJlciBmdW5jdGlvbiBvbiBhbiBvYmplY3QgdG8gdGhlIGxpc3Qgb2YgZGVzdHJ1Y3RvcnMgdGhhdAorICAvLyB3aWxsIGJlIG1hbnVhbGx5IGNhbGxlZCB3aGVuIHRoZSBhcmVuYSBpcyBkZXN0cm95ZWQgb3IgcmVzZXQuIFRoaXMgZGlmZmVycworICAvLyBmcm9tIE93bkRlc3RydWN0b3IoKSBpbiB0aGF0IGFueSBtZW1iZXIgZnVuY3Rpb24gbWF5IGJlIHNwZWNpZmllZCwgbm90IG9ubHkKKyAgLy8gdGhlIGNsYXNzIGRlc3RydWN0b3IuCisgIHZvaWQgT3duQ3VzdG9tRGVzdHJ1Y3Rvcih2b2lkKiBvYmplY3QsIHZvaWQgKCpkZXN0cnVjdCkodm9pZCopKQorICAgICAgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORSB7CisgICAgQWRkTGlzdE5vZGUob2JqZWN0LCBkZXN0cnVjdCk7CisgIH0KKworICAvLyBSZXRyaWV2ZXMgdGhlIGFyZW5hIGFzc29jaWF0ZWQgd2l0aCB8dmFsdWV8IGlmIHx2YWx1ZXwgaXMgYW4gYXJlbmEtY2FwYWJsZQorICAvLyBtZXNzYWdlLCBvciBOVUxMIG90aGVyd2lzZS4gVGhpcyBkaWZmZXJzIGZyb20gdmFsdWUtPkdldEFyZW5hKCkgaW4gdGhhdCB0aGUKKyAgLy8gbGF0dGVyIGlzIGEgdmlydHVhbCBjYWxsLCB3aGlsZSB0aGlzIG1ldGhvZCBpcyBhIHRlbXBsYXRlZCBjYWxsIHRoYXQKKyAgLy8gcmVzb2x2ZXMgYXQgY29tcGlsZS10aW1lLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYShjb25zdCBUKiB2YWx1ZSkgeworICAgIHJldHVybiBHZXRBcmVuYUludGVybmFsKHZhbHVlLCBzdGF0aWNfY2FzdDxUKj4oMCkpOworICB9CisKKyAgLy8gSGVscGVyIHR5cGV0cmFpdCB0aGF0IGluZGljYXRlcyBzdXBwb3J0IGZvciBhcmVuYXMgaW4gYSB0eXBlIFQgYXQgY29tcGlsZQorICAvLyB0aW1lLiBUaGlzIGlzIHB1YmxpYyBvbmx5IHRvIGFsbG93IGNvbnN0cnVjdGlvbiBvZiBoaWdoZXItbGV2ZWwgdGVtcGxhdGVkCisgIC8vIHV0aWxpdGllcy4gaXNfYXJlbmFfY29uc3RydWN0YWJsZTxUPjo6dmFsdWUgaXMgYW4gaW5zdGFuY2Ugb2YKKyAgLy8gZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSBpZiB0aGUgbWVzc2FnZSB0eXBlIFQgaGFzIGFyZW5hIHN1cHBvcnQgZW5hYmxlZCwgYW5kCisgIC8vIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlIG90aGVyd2lzZS4KKyAgLy8KKyAgLy8gVGhpcyBpcyBpbnNpZGUgQXJlbmEgYmVjYXVzZSBvbmx5IEFyZW5hIGhhcyB0aGUgZnJpZW5kIHJlbGF0aW9uc2hpcHMKKyAgLy8gbmVjZXNzYXJ5IHRvIHNlZSB0aGUgdW5kZXJseWluZyBnZW5lcmF0ZWQgY29kZSB0cmFpdHMuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIHN0cnVjdCBpc19hcmVuYV9jb25zdHJ1Y3RhYmxlIHsKKyAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgorICAgIHN0YXRpYyBjaGFyIEFyZW5hQ29uc3RydWN0YWJsZSgKKyAgICAgICAgY29uc3QgdHlwZW5hbWUgVTo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKik7CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVT4KKyAgICBzdGF0aWMgZG91YmxlIEFyZW5hQ29uc3RydWN0YWJsZSguLi4pOworCisgICAgLy8gVGhpcyB3aWxsIHJlc29sdmUgdG8gZWl0aGVyIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUgb3IgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUuCisgICAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKKyAgICAgICAgICAgICAgc2l6ZW9mKEFyZW5hQ29uc3RydWN0YWJsZTxjb25zdCBUPihzdGF0aWNfY2FzdDxjb25zdCBUKj4oMCkpKSA9PQorICAgICAgICAgICAgICBzaXplb2YoY2hhcik+IHR5cGU7CisgICAgc3RhdGljIGNvbnN0IHR5cGUgdmFsdWU7CisgIH07CisKKyBwcml2YXRlOgorICAvLyBCbG9ja3MgYXJlIHZhcmlhYmxlIGxlbmd0aCBtYWxsb2MtZWQgb2JqZWN0cy4gIFRoZSBmb2xsb3dpbmcgc3RydWN0dXJlCisgIC8vIGRlc2NyaWJlcyB0aGUgY29tbW9uIGhlYWRlciBmb3IgYWxsIGJsb2Nrcy4KKyAgc3RydWN0IEJsb2NrIHsKKyAgICB2b2lkKiBvd25lcjsgICAvLyAmVGhyZWFkQ2FjaGUgb2YgdGhyZWFkIHRoYXQgb3ducyB0aGlzIGJsb2NrLCBvcgorICAgICAgICAgICAgICAgICAgIC8vICZ0aGlzLT5vd25lciBpZiBub3QgeWV0IG93bmVkIGJ5IGEgdGhyZWFkLgorICAgIEJsb2NrKiBuZXh0OyAgIC8vIE5leHQgYmxvY2sgaW4gYXJlbmEgKG1heSBoYXZlIGRpZmZlcmVudCBvd25lcikKKyAgICAvLyAoKGNoYXIqKSAmYmxvY2spICsgcG9zIGlzIG5leHQgYXZhaWxhYmxlIGJ5dGUuIEl0IGlzIGFsd2F5cworICAgIC8vIGFsaWduZWQgYXQgYSBtdWx0aXBsZSBvZiA4IGJ5dGVzLgorICAgIHNpemVfdCBwb3M7CisgICAgc2l6ZV90IHNpemU7ICAvLyB0b3RhbCBzaXplIG9mIHRoZSBibG9jay4KKyAgICBzaXplX3QgYXZhaWwoKSBjb25zdCBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgeyByZXR1cm4gc2l6ZSAtIHBvczsgfQorICAgIC8vIGRhdGEgZm9sbG93cworICB9OworCisgIHRlbXBsYXRlPHR5cGVuYW1lIFR5cGU+IGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmljVHlwZUhhbmRsZXI7CisgIGZyaWVuZCBjbGFzcyBNb2NrQXJlbmE7ICAgICAgICAgICAgICAvLyBGb3IgdW5pdC10ZXN0aW5nLgorICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkFyZW5hU3RyaW5nOyAgLy8gRm9yIEFsbG9jYXRlQWxpZ25lZC4KKyAgZnJpZW5kIGNsYXNzIGludGVybmFsOjpMYXp5RmllbGQ7ICAgIC8vIEZvciBDcmVhdGVNYXliZU1lc3NhZ2UuCisKKyAgc3RydWN0IFRocmVhZENhY2hlIHsKKyAgICAvLyBUaGUgVGhyZWFkQ2FjaGUgaXMgY29uc2lkZXJlZCB2YWxpZCBhcyBsb25nIGFzIHRoaXMgbWF0Y2hlcyB0aGUKKyAgICAvLyBsaWZlY3ljbGVfaWQgb2YgdGhlIGFyZW5hIGJlaW5nIHVzZWQuCisgICAgaW50NjQgbGFzdF9saWZlY3ljbGVfaWRfc2VlbjsKKyAgICBCbG9jayogbGFzdF9ibG9ja191c2VkXzsKKyAgfTsKKworICBzdGF0aWMgY29uc3Qgc2l6ZV90IGtIZWFkZXJTaXplID0gc2l6ZW9mKEJsb2NrKTsKKyAgc3RhdGljIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpTZXF1ZW5jZU51bWJlciBsaWZlY3ljbGVfaWRfZ2VuZXJhdG9yXzsKKyNpZmRlZiBQUk9UT0JVRl9VU0VfRExMUworICAvLyBUaHJlYWQgbG9jYWwgdmFyaWFibGVzIGNhbm5vdCBiZSBleHBvc2VkIHRocm91Z2ggRExMIGludGVyZmFjZSBidXQgd2UgY2FuCisgIC8vIHdyYXAgdGhlbSBpbiBzdGF0aWMgZnVuY3Rpb25zLgorICBzdGF0aWMgVGhyZWFkQ2FjaGUmIHRocmVhZF9jYWNoZSgpOworI2Vsc2UKKyAgc3RhdGljIEdPT0dMRV9USFJFQURfTE9DQUwgVGhyZWFkQ2FjaGUgdGhyZWFkX2NhY2hlXzsKKyAgc3RhdGljIFRocmVhZENhY2hlJiB0aHJlYWRfY2FjaGUoKSB7IHJldHVybiB0aHJlYWRfY2FjaGVfOyB9CisjZW5kaWYKKworICAvLyBTRklOQUUgZm9yIHNraXBwaW5nIGFkZGl0aW9uIHRvIGRlbGV0ZSBsaXN0IGZvciBhIFR5cGUuIFRoaXMgaXMgbWFpbmx5IHRvCisgIC8vIHNraXAgcHJvdG8yL3Byb3RvMSBtZXNzYWdlIG9iamVjdHMgd2l0aCBjY19lbmFibGVfYXJlbmFzPXRydWUgZnJvbSBiZWluZworICAvLyBwYXJ0IG9mIHRoZSBkZWxldGUgbGlzdC4gQWxzbywgbm90ZSwgY29tcGlsZXIgd2lsbCBvcHRpbWl6ZSBvdXQgdGhlIGJyYW5jaAorICAvLyBpbiBDcmVhdGVJbnRlcm5hbDxUPi4KKyAgLy8KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgc3RhdGljIGlubGluZSBib29sIFNraXBEZWxldGVMaXN0KHR5cGVuYW1lIFQ6OkRlc3RydWN0b3JTa2lwcGFibGVfKikgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gRm9yIG5vbiBtZXNzYWdlIG9iamVjdHMsIHdlIHNraXAgYWRkaXRpb24gdG8gZGVsZXRlIGxpc3QgaWYgdGhlIG9iamVjdCBoYXMKKyAgLy8gYSB0cml2aWFsIGRlc3RydWN0b3IuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBTa2lwRGVsZXRlTGlzdCguLi4pIHsKKyAgICByZXR1cm4gZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlOworICB9CisKKyAgLy8gQ3JlYXRlTWVzc2FnZTxUPiByZXF1aXJlcyB0aGF0IFQgc3VwcG9ydHMgYXJlbmFzLCBidXQgdGhpcyBwcml2YXRlIG1ldGhvZAorICAvLyB3b3JrcyB3aGV0aGVyIG9yIG5vdCBUIHN1cHBvcnRzIGFyZW5hcy4gVGhlc2UgYXJlIG5vdCBleHBvc2VkIHRvIHVzZXIgY29kZQorICAvLyBhcyBpdCBjYW4gY2F1c2UgY29uZnVzaW5nIEFQSSB1c2FnZXMsIGFuZCBlbmQgdXAgaGF2aW5nIGRvdWJsZSBmcmVlIGluCisgIC8vIHVzZXIgY29kZS4gVGhlc2UgYXJlIHVzZWQgb25seSBpbnRlcm5hbGx5IGZyb20gTGF6eUZpZWxkIGFuZCBSZXBlYXRlZAorICAvLyBmaWVsZHMsIHNpbmNlIHRoZXkgYXJlIGRlc2lnbmVkIHRvIHdvcmsgaW4gYWxsIG1vZGUgY29tYmluYXRpb25zLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBNc2c+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgTXNnKiBDcmVhdGVNYXliZU1lc3NhZ2UoCisgICAgICBBcmVuYSogYXJlbmEsIHR5cGVuYW1lIE1zZzo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKikgeworICAgIHJldHVybiBDcmVhdGVNZXNzYWdlPE1zZz4oYXJlbmEpOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGVNYXliZU1lc3NhZ2UoQXJlbmEqIGFyZW5hLCAuLi4pIHsKKyAgICByZXR1cm4gQ3JlYXRlPFQ+KGFyZW5hKTsKKyAgfQorCisgIC8vIEp1c3QgYWxsb2NhdGUgdGhlIHJlcXVpcmVkIHNpemUgZm9yIHRoZSBnaXZlbiB0eXBlIGFzc3VtaW5nIHRoZQorICAvLyB0eXBlIGhhcyBhIHRyaXZpYWwgY29uc3RydWN0b3IuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBpbmxpbmUgVCogQ3JlYXRlSW50ZXJuYWxSYXdBcnJheSh1aW50MzIgbnVtX2VsZW1lbnRzKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQqPihBbGxvY2F0ZUFsaWduZWQoc2l6ZW9mKFQpICogbnVtX2VsZW1lbnRzKSk7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIGlubGluZSBUKiBDcmVhdGVJbnRlcm5hbCgKKyAgICAgIGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoc2l6ZW9mKFQpKSkgVCgpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgaW5saW5lIFQqIENyZWF0ZUludGVybmFsKAorICAgICAgYm9vbCBza2lwX2V4cGxpY2l0X293bmVyc2hpcCwgY29uc3QgQXJnJiBhcmcpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoc2l6ZW9mKFQpKSkgVChhcmcpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMj4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIGlubGluZSBUKiBDcmVhdGVJbnRlcm5hbCgKKyAgICAgIGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXAsIGNvbnN0IEFyZzEmIGFyZzEsIGNvbnN0IEFyZzImIGFyZzIpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoc2l6ZW9mKFQpKSkgVChhcmcxLCBhcmcyKTsKKyAgICBpZiAoIXNraXBfZXhwbGljaXRfb3duZXJzaGlwKSB7CisgICAgICBBZGRMaXN0Tm9kZSh0LCAmaW50ZXJuYWw6OmFyZW5hX2Rlc3RydWN0X29iamVjdDxUPik7CisgICAgfQorICAgIHJldHVybiB0OworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzM+CisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBpbmxpbmUgVCogQ3JlYXRlSW50ZXJuYWwoYm9vbCBza2lwX2V4cGxpY2l0X293bmVyc2hpcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcyJiBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMyYgYXJnMykgeworICAgIFQqIHQgPSBuZXcgKEFsbG9jYXRlQWxpZ25lZChzaXplb2YoVCkpKSBUKGFyZzEsIGFyZzIsIGFyZzMpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMiwgdHlwZW5hbWUgQXJnMywKKyAgICAgICAgICAgIHR5cGVuYW1lIEFyZzQ+CisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBpbmxpbmUgVCogQ3JlYXRlSW50ZXJuYWwoYm9vbCBza2lwX2V4cGxpY2l0X293bmVyc2hpcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcyJiBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMyYgYXJnMywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzQmIGFyZzQpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoc2l6ZW9mKFQpKSkgVChhcmcxLCBhcmcyLCBhcmczLCBhcmc0KTsKKyAgICBpZiAoIXNraXBfZXhwbGljaXRfb3duZXJzaGlwKSB7CisgICAgICBBZGRMaXN0Tm9kZSh0LCAmaW50ZXJuYWw6OmFyZW5hX2Rlc3RydWN0X29iamVjdDxUPik7CisgICAgfQorICAgIHJldHVybiB0OworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBpbmxpbmUgVCogQ3JlYXRlTWVzc2FnZUludGVybmFsKHR5cGVuYW1lIFQ6OkludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXyopIHsKKyAgICByZXR1cm4gQ3JlYXRlSW50ZXJuYWw8VCwgQXJlbmEqPihTa2lwRGVsZXRlTGlzdDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMpOworICB9CisKKyAgLy8gQ3JlYXRlSW5BcmVuYVN0b3JhZ2UgaXMgdXNlZCB0byBpbXBsZW1lbnQgbWFwIGZpZWxkLiBXaXRob3V0IGl0LAorICAvLyBnb29nbGU6OnByb3RvYnVmOjpNYXAgbmVlZCB0byBjYWxsIGdlbmVyYXRlZCBtZXNzYWdlJ3MgcHJvdGVjdGVkIGFyZW5hIGNvbnN0cnVjdG9yLAorICAvLyB3aGljaCBuZWVkcyB0byBkZWNsYXJlIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBhcyBmcmllbmQgb2YgZ2VuZXJhdGVkIG1lc3NhZ2UuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICBzdGF0aWMgdm9pZCBDcmVhdGVJbkFyZW5hU3RvcmFnZShUKiBwdHIsIEFyZW5hKiBhcmVuYSkgeworICAgIENyZWF0ZUluQXJlbmFTdG9yYWdlSW50ZXJuYWwocHRyLCBhcmVuYSwgaXNfYXJlbmFfY29uc3RydWN0YWJsZTxUPjo6dmFsdWUpOworICB9CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICBzdGF0aWMgdm9pZCBDcmVhdGVJbkFyZW5hU3RvcmFnZUludGVybmFsKAorICAgICAgVCogcHRyLCBBcmVuYSogYXJlbmEsIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpIHsKKyAgICBuZXcgKHB0cikgVChhcmVuYSk7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KKyAgc3RhdGljIHZvaWQgQ3JlYXRlSW5BcmVuYVN0b3JhZ2VJbnRlcm5hbCgKKyAgICAgIFQqIHB0ciwgQXJlbmEqIGFyZW5hLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSkgeworICAgIG5ldyAocHRyKSBUOworICB9CisKKyAgLy8gVGhlc2UgaW1wbGVtZW50IE93bigpLCB3aGljaCByZWdpc3RlcnMgYW4gb2JqZWN0IGZvciBkZWxldGlvbiAoZGVzdHJ1Y3RvcgorICAvLyBjYWxsIGFuZCBvcGVyYXRvciBkZWxldGUoKSkuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGhhcyB0eXBlICd0cnVlX3R5cGUnIGlmIFQKKyAgLy8gaXMgYSBzdWJ0eXBlIG9mIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSBhbmQgJ2ZhbHNlX3R5cGUnIG90aGVyd2lzZS4gQ29sbGFwc2luZworICAvLyBhbGwgdGVtcGxhdGUgaW5zdGFudGlhdGlvbnMgdG8gb25lIGZvciBnZW5lcmljIE1lc3NhZ2UgcmVkdWNlcyBjb2RlIHNpemUsCisgIC8vIHVzaW5nIHRoZSB2aXJ0dWFsIGRlc3RydWN0b3IgaW5zdGVhZC4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHZvaWQgT3duSW50ZXJuYWwoVCogb2JqZWN0LCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlKSB7CisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSB7CisgICAgICBBZGRMaXN0Tm9kZShvYmplY3QsICZpbnRlcm5hbDo6YXJlbmFfZGVsZXRlX29iamVjdDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlID4pOworICAgIH0KKyAgfQorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgdm9pZCBPd25JbnRlcm5hbChUKiBvYmplY3QsIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKSB7CisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSB7CisgICAgICBBZGRMaXN0Tm9kZShvYmplY3QsICZpbnRlcm5hbDo6YXJlbmFfZGVsZXRlX29iamVjdDxUPik7CisgICAgfQorICB9CisKKyAgLy8gSW1wbGVtZW50YXRpb24gZm9yIEdldEFyZW5hKCkuIE9ubHkgbWVzc2FnZSBvYmplY3RzIHdpdGgKKyAgLy8gSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfIHRhZ3MgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCBhbiBhcmVuYSwgYW5kIHN1Y2gKKyAgLy8gb2JqZWN0cyBtdXN0IGltcGxlbWVudCBhIEdldEFyZW5hTm9WaXJ0dWFsKCkgbWV0aG9kLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYUludGVybmFsKGNvbnN0IFQqIHZhbHVlLAorICAgICAgdHlwZW5hbWUgVDo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKikgeworICAgIHJldHVybiB2YWx1ZS0+R2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hSW50ZXJuYWwoY29uc3QgVCogdmFsdWUsIC4uLikgeworICAgIHJldHVybiBOVUxMOworICB9CisKKworICB2b2lkKiBBbGxvY2F0ZUFsaWduZWQoc2l6ZV90IHNpemUpOworCisgIHZvaWQgSW5pdCgpOworCisgIC8vIEZyZWUgYWxsIGJsb2NrcyBhbmQgcmV0dXJuIHRoZSB0b3RhbCBzcGFjZSB1c2VkIHdoaWNoIGlzIHRoZSBzdW1zIG9mIHNpemVzCisgIC8vIG9mIHRoZSBhbGwgdGhlIGFsbG9jYXRlZCBibG9ja3MuCisgIHVpbnQ2NCBGcmVlQmxvY2tzKCk7CisKKyAgLy8gQWRkIG9iamVjdCBwb2ludGVyIGFuZCBjbGVhbnVwIGZ1bmN0aW9uIHBvaW50ZXIgdG8gdGhlIGxpc3QuCisgIC8vIFRPRE8ocm9oYW5hbmlsLCBjZmFsbGluKTogV2UgY291bGQgcGFzcyBpbiBhIHN1Yi1hcmVuYSBpbnRvIHRoaXMgbWV0aG9kCisgIC8vIHRvIGF2b2lkIHBvbGx1dGluZyBibG9ja3Mgb2YgdGhpcyBhcmVuYSB3aXRoIGxpc3Qgbm9kZXMuIFRoaXMgd291bGQgaGVscCBpbgorICAvLyBtaXhlZCBtb2RlICh3aGVyZSBtYW55IHByb3RvYnVmcyBoYXZlIGNjX2VuYWJsZV9hcmVuYXM9ZmFsc2UpLCBhbmQgaXMgYW4KKyAgLy8gYWx0ZXJuYXRpdmUgdG8gYSBjaHVua2VkIGxpbmtlZC1saXN0LCBidXQgd2l0aCBleHRyYSBvdmVyaGVhZCBvZiAqbmV4dC4KKyAgdm9pZCBBZGRMaXN0Tm9kZSh2b2lkKiBlbGVtLCB2b2lkICgqY2xlYW51cCkodm9pZCopKTsKKyAgLy8gRGVsZXRlIG9yIERlc3RydWN0IGFsbCBvYmplY3RzIG93bmVkIGJ5IHRoZSBhcmVuYS4KKyAgdm9pZCBDbGVhbnVwTGlzdCgpOworCisgIGlubGluZSB2b2lkIFNldFRocmVhZENhY2hlQmxvY2soQmxvY2sqIGJsb2NrKSB7CisgICAgdGhyZWFkX2NhY2hlKCkubGFzdF9ibG9ja191c2VkXyA9IGJsb2NrOworICAgIHRocmVhZF9jYWNoZSgpLmxhc3RfbGlmZWN5Y2xlX2lkX3NlZW4gPSBsaWZlY3ljbGVfaWRfOworICB9CisKKyAgaW50NjQgbGlmZWN5Y2xlX2lkXzsgIC8vIFVuaXF1ZSBmb3IgZWFjaCBhcmVuYS4gQ2hhbmdlcyBvbiBSZXNldCgpLgorCisgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBdG9taWNXb3JkIGJsb2Nrc187ICAvLyBIZWFkIG9mIGxpbmtlZCBsaXN0IG9mIGFsbCBhbGxvY2F0ZWQgYmxvY2tzCisgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBdG9taWNXb3JkIGhpbnRfOyAgICAvLyBGYXN0IHRocmVhZC1sb2NhbCBibG9jayBhY2Nlc3MKKworICAvLyBOb2RlIGNvbnRhaW5zIHRoZSBwdHIgb2YgdGhlIG9iamVjdCB0byBiZSBjbGVhbmVkIHVwIGFuZCB0aGUgYXNzb2NpYXRlZAorICAvLyBjbGVhbnVwIGZ1bmN0aW9uIHB0ci4KKyAgc3RydWN0IE5vZGUgeworICAgIHZvaWQqIGVsZW07ICAgICAgICAgICAgICAvLyBQb2ludGVyIHRvIHRoZSBvYmplY3QgdG8gYmUgY2xlYW5lZCB1cC4KKyAgICB2b2lkICgqY2xlYW51cCkodm9pZCopOyAgLy8gRnVuY3Rpb24gcG9pbnRlciB0byB0aGUgZGVzdHJ1Y3RvciBvciBkZWxldGVyLgorICAgIE5vZGUqIG5leHQ7ICAgICAgICAgICAgICAvLyBOZXh0IG5vZGUgaW4gdGhlIGxpc3QuCisgIH07CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkF0b21pY1dvcmQgY2xlYW51cF9saXN0XzsgIC8vIEhlYWQgb2YgYSBsaW5rZWQgbGlzdCBvZiBub2RlcyBjb250YWluaW5nIG9iamVjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwdHJzIGFuZCBjbGVhbnVwIG1ldGhvZHMuCisKKyAgYm9vbCBvd25zX2ZpcnN0X2Jsb2NrXzsgICAgLy8gSW5kaWNhdGVzIHRoYXQgYXJlbmEgb3ducyB0aGUgZmlyc3QgYmxvY2sKKyAgTXV0ZXggYmxvY2tzX2xvY2tfOworCisgIHZvaWQgQWRkQmxvY2soQmxvY2sqIGIpOworICB2b2lkKiBTbG93QWxsb2Moc2l6ZV90IG4pOworICBCbG9jayogRmluZEJsb2NrKHZvaWQqIG1lKTsKKyAgQmxvY2sqIE5ld0Jsb2NrKHZvaWQqIG1lLCBCbG9jayogbXlfbGFzdF9ibG9jaywgc2l6ZV90IG4sCisgICAgICAgICAgICAgICAgICBzaXplX3Qgc3RhcnRfYmxvY2tfc2l6ZSwgc2l6ZV90IG1heF9ibG9ja19zaXplKTsKKyAgc3RhdGljIHZvaWQqIEFsbG9jRnJvbUJsb2NrKEJsb2NrKiBiLCBzaXplX3Qgbik7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CisgIGZyaWVuZCBjbGFzcyBNYXA7CisKKyAgLy8gVGhlIGFyZW5hIG1heSBzYXZlIGEgY29va2llIGl0IHJlY2VpdmVzIGZyb20gdGhlIGV4dGVybmFsIG9uX2luaXQgaG9vaworICAvLyBhbmQgdGhlbiB1c2UgaXQgd2hlbiBjYWxsaW5nIHRoZSBvbl9yZXNldCBhbmQgb25fZGVzdHJ1Y3Rpb24gaG9va3MuCisgIHZvaWQqIGhvb2tzX2Nvb2tpZV87CisKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhBcmVuYSk7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY29uc3QgdHlwZW5hbWUgQXJlbmE6OmlzX2FyZW5hX2NvbnN0cnVjdGFibGU8VD46OnR5cGUKKyAgICBBcmVuYTo6aXNfYXJlbmFfY29uc3RydWN0YWJsZTxUPjo6dmFsdWUgPQorICAgICAgICB0eXBlbmFtZSBBcmVuYTo6aXNfYXJlbmFfY29uc3RydWN0YWJsZTxUPjo6dHlwZSgpOworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVJFTkFfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX25jLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYV9uYy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMmYwODQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYV9uYy5jYwpAQCAtMCwwICsxLDQ1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gTmVnYXRpdmUgY29tcGlsYXRpb24gdGVzdCBmb3IgYXJlbmEgdXNhZ2UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKworI2lmZGVmIFRFU1RfQVJFTkFfUFJJVkFURV9DT05TVFJVQ1RPUgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK3ZvaWQgQXJlbmFQcml2YXRlQ29uc3RydWN0b3IoKSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hIGFyZW5hOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UoJmFyZW5hKTsKK30KKworI2VuZGlmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX25jX3Rlc3QucHkgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX25jX3Rlc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDFiMWI1ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfbmNfdGVzdC5weQpAQCAtMCwwICsxLDU5IEBACisjISAvdXNyL2Jpbi9weXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiTmVnYXRpdmUgY29tcGlsYXRpb24gdW5pdCB0ZXN0cyBmb3IgYXJlbmEgQVBJLiIiIgorCitmcm9tIGdvb2dsZTMudGVzdGluZy5weWJhc2UgaW1wb3J0IGZha2VfdGFyZ2V0X3V0aWwKK2Zyb20gZ29vZ2xlLmFwcHV0aWxzIGltcG9ydCBiYXNldGVzdAorCisKK2NsYXNzIEFyZW5hTmNUZXN0KGJhc2V0ZXN0LlRlc3RDYXNlKToKKworICBkZWYgdGVzdENvbXBpbGVyRXJyb3JzKHNlbGYpOgorICAgICIiIlJ1bnMgYSBsaXN0IG9mIHRlc3RzIHRvIHZlcmlmeSBjb21waWxlciBlcnJvciBtZXNzYWdlcy4iIiIKKworICAgICMgRGVmaW5lcyBhIGxpc3Qgb2YgdGVzdCBzcGVjcywgd2hlcmUgZWFjaCBlbGVtZW50IGlzIGEgdHVwbGUKKyAgICAjICh0ZXN0IG5hbWUsIGxpc3Qgb2YgcmVnZXhlcyBmb3IgbWF0Y2hpbmcgdGhlIGNvbXBpbGVyIGVycm9ycykuCisgICAgdGVzdF9zcGVjcyA9IFsKKyAgICAgICAgKCdBUkVOQV9QUklWQVRFX0NPTlNUUlVDVE9SJywKKyAgICAgICAgIFtyJ2NhbGxpbmcgYSBwcm90ZWN0ZWQgY29uc3RydWN0b3InXSksCisgICAgICAgICgnU0FOSVRZJywgTm9uZSldCisKKyAgICBmYWtlX3RhcmdldF91dGlsLkFzc2VydENjQ29tcGlsZXJFcnJvcnMoCisgICAgICAgIHNlbGYsICAgICAgICAgICAgICAgICAgICAgICAgICMgVGhlIGN1cnJlbnQgdGVzdCBjYXNlLgorICAgICAgICAnZ29vZ2xlMy9nb29nbGUvcHJvdG9idWYvYXJlbmFfbmMnLCAgIyBUaGUgZmFrZSB0YXJnZXQgZmlsZS4KKyAgICAgICAgJ2FyZW5hX25jLm8nLCAgICAgICAgICAgICAgICAgIyBUaGUgc3ViLXRhcmdldCB0byBidWlsZC4KKyAgICAgICAgdGVzdF9zcGVjcyAgICAgICAgICAgICAgICAgICAgIyBMaXN0IG9mIHRlc3Qgc3BlY2lmaWNhdGlvbnMuCisgICAgICAgICkKKworaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKKyAgYmFzZXRlc3QubWFpbigpCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxZjU1YzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5jYwpAQCAtMCwwICsxLDQ5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmg+CisKKworI2RlZmluZSBFWFBFQ1RfRVEgR09PR0xFX0NIRUNLX0VRCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK05vSGVhcENoZWNrZXI6On5Ob0hlYXBDaGVja2VyKCkgeworICBjYXB0dXJlX2FsbG9jLlVuaG9vaygpOworICBFWFBFQ1RfRVEoMCwgY2FwdHVyZV9hbGxvYy5hbGxvY19jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsIGNhcHR1cmVfYWxsb2MuZnJlZV9jb3VudCgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkYjdhOTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oCkBAIC0wLDAgKzEsNTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9URVNUX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9URVNUX1VUSUxfSF9fCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2NsYXNzIE5vSGVhcENoZWNrZXIgeworIHB1YmxpYzoKKyAgTm9IZWFwQ2hlY2tlcigpIHsKKyAgICBjYXB0dXJlX2FsbG9jLkhvb2soKTsKKyAgfQorICB+Tm9IZWFwQ2hlY2tlcigpOworIHByaXZhdGU6CisgIGNsYXNzIE5ld0RlbGV0ZUNhcHR1cmUgeworICAgcHVibGljOgorICAgIC8vIFRPT0QoeGlhb2ZlbmcpOiBJbXBsZW1lbnQgdGhpcyBmb3Igb3BlbnNvdXJjZSBwcm90b2J1Zi4KKyAgICB2b2lkIEhvb2soKSB7fQorICAgIHZvaWQgVW5ob29rKCkge30KKyAgICBpbnQgYWxsb2NfY291bnQoKSB7IHJldHVybiAwOyB9CisgICAgaW50IGZyZWVfY291bnQoKSB7IHJldHVybiAwOyB9CisgIH0gY2FwdHVyZV9hbGxvYzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FSRU5BX1RFU1RfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5YjE5OGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTE3MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKworI2luY2x1ZGUgPHN0ZGludC5oPgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK3VzaW5nIHByb3RvMl9hcmVuYV91bml0dGVzdDo6QXJlbmFNZXNzYWdlOwordXNpbmcgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczsKK3VzaW5nIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczsKK3VzaW5nIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0T25lb2YyOwordXNpbmcgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2U7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgeworCitjbGFzcyBOb3RpZmllciB7CisgcHVibGljOgorICBOb3RpZmllcigpIDogY291bnRfKDApIHt9CisgIHZvaWQgTm90aWZ5KCkgeworICAgIGNvdW50XysrOworICB9CisgIGludCBHZXRDb3VudCgpIHsKKyAgICByZXR1cm4gY291bnRfOworICB9CisKKyBwcml2YXRlOgorICBpbnQgY291bnRfOworfTsKKworY2xhc3MgU2ltcGxlRGF0YVR5cGUgeworIHB1YmxpYzoKKyAgU2ltcGxlRGF0YVR5cGUoKSA6IG5vdGlmaWVyXyhOVUxMKSB7fQorICB2b2lkIFNldE5vdGlmaWVyKE5vdGlmaWVyKiBub3RpZmllcikgeworICAgIG5vdGlmaWVyXyA9IG5vdGlmaWVyOworICB9CisgIHZpcnR1YWwgflNpbXBsZURhdGFUeXBlKCkgeworICAgIGlmIChub3RpZmllcl8gIT0gTlVMTCkgeworICAgICAgbm90aWZpZXJfLT5Ob3RpZnkoKTsKKyAgICB9CisgIH07CisgcHJpdmF0ZToKKyAgTm90aWZpZXIqIG5vdGlmaWVyXzsKK307CisKKy8vIEEgc2ltcGxlIGNsYXNzIHRoYXQgZG9lcyBub3QgYWxsb3cgY29weWluZyBhbmQgc28gY2Fubm90IGJlIHVzZWQgYXMgYQorLy8gcGFyYW1ldGVyIHR5cGUgd2l0aG91dCAiY29uc3QgJiIuCitjbGFzcyBQbGVhc2VEb250Q29weU1lIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFBsZWFzZURvbnRDb3B5TWUoaW50IHZhbHVlKSA6IHZhbHVlXyh2YWx1ZSkge30KKworICBpbnQgdmFsdWUoKSBjb25zdCB7IHJldHVybiB2YWx1ZV87IH0KKworIHByaXZhdGU6CisgIGludCB2YWx1ZV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQbGVhc2VEb250Q29weU1lKTsKK307CisKKy8vIEEgY2xhc3MgdGhhdCB0YWtlcyBmb3VyIGRpZmZlcmVudCB0eXBlcyBhcyBjb25zdHJ1Y3RvciBhcmd1bWVudHMuCitjbGFzcyBNdXN0QmVDb25zdHJ1Y3RlZFdpdGhPbmVUaHJvdWdoRm91ciB7CisgcHVibGljOgorICBNdXN0QmVDb25zdHJ1Y3RlZFdpdGhPbmVUaHJvdWdoRm91cigKKyAgICAgIGludCBvbmUsIGNvbnN0IGNoYXIqIHR3bywgY29uc3Qgc3RyaW5nJiB0aHJlZSwKKyAgICAgIGNvbnN0IFBsZWFzZURvbnRDb3B5TWUqIGZvdXIpCisgICAgICA6IG9uZV8ob25lKSwgdHdvXyh0d28pLCB0aHJlZV8odGhyZWUpLCBmb3VyXyhmb3VyKSB7fQorCisgIGludCBvbmVfOworICBjb25zdCBjaGFyKiBjb25zdCB0d29fOworICBzdHJpbmcgdGhyZWVfOworICBjb25zdCBQbGVhc2VEb250Q29weU1lKiBmb3VyXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNdXN0QmVDb25zdHJ1Y3RlZFdpdGhPbmVUaHJvdWdoRm91cik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UKKworVEVTVChBcmVuYVRlc3QsIEFyZW5hQ29uc3RydWN0YWJsZSkgeworICBFWFBFQ1RfVFJVRShBcmVuYTo6aXNfYXJlbmFfY29uc3RydWN0YWJsZTxUZXN0QWxsVHlwZXM+Ojp0eXBlOjp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjppc19hcmVuYV9jb25zdHJ1Y3RhYmxlPGNvbnN0IFRlc3RBbGxUeXBlcz46OnR5cGU6OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKEFyZW5hOjppc19hcmVuYV9jb25zdHJ1Y3RhYmxlPEFyZW5hPjo6dHlwZTo6dmFsdWUpOworfQorCitURVNUKEFyZW5hVGVzdCwgQmFzaWNDcmVhdGUpIHsKKyAgQXJlbmEgYXJlbmE7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8aW50MzI+KCZhcmVuYSkgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8aW50NjQ+KCZhcmVuYSkgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8ZmxvYXQ+KCZhcmVuYSkgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8ZG91YmxlPigmYXJlbmEpICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShBcmVuYTo6Q3JlYXRlPHN0cmluZz4oJmFyZW5hKSAhPSBOVUxMKTsKKyAgYXJlbmEuT3duKG5ldyBpbnQzMik7CisgIGFyZW5hLk93bihuZXcgaW50NjQpOworICBhcmVuYS5Pd24obmV3IGZsb2F0KTsKKyAgYXJlbmEuT3duKG5ldyBkb3VibGUpOworICBhcmVuYS5Pd24obmV3IHN0cmluZyk7CisgIGFyZW5hLk93bjxpbnQ+KE5VTEwpOworICBOb3RpZmllciBub3RpZmllcjsKKyAgU2ltcGxlRGF0YVR5cGUqIGRhdGEgPSBBcmVuYTo6Q3JlYXRlPFNpbXBsZURhdGFUeXBlPigmYXJlbmEpOworICBkYXRhLT5TZXROb3RpZmllcigmbm90aWZpZXIpOworICBkYXRhID0gbmV3IFNpbXBsZURhdGFUeXBlOworICBkYXRhLT5TZXROb3RpZmllcigmbm90aWZpZXIpOworICBhcmVuYS5Pd24oZGF0YSk7CisgIGFyZW5hLlJlc2V0KCk7CisgIEVYUEVDVF9FUSgyLCBub3RpZmllci5HZXRDb3VudCgpKTsKK30KKworVEVTVChBcmVuYVRlc3QsIENyZWF0ZVdpdGhNYW55Q29uc3RydWN0b3JBcmd1bWVudHMpIHsKKyAgQXJlbmEgYXJlbmE7CisgIGNvbnN0IHN0cmluZyB0aHJlZSgiMyIpOworICBjb25zdCBQbGVhc2VEb250Q29weU1lIGZvdXIoNCk7CisgIGNvbnN0IE11c3RCZUNvbnN0cnVjdGVkV2l0aE9uZVRocm91Z2hGb3VyKiBuZXdfb2JqZWN0ID0KKyAgICAgIEFyZW5hOjpDcmVhdGU8TXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEZvdXI+KAorICAgICAgICAgICZhcmVuYSwgMSwgIjIiLCB0aHJlZSwgJmZvdXIpOworICBFWFBFQ1RfVFJVRShuZXdfb2JqZWN0ICE9IE5VTEwpOworICBBU1NFUlRfRVEoMSwgbmV3X29iamVjdC0+b25lXyk7CisgIEFTU0VSVF9TVFJFUSgiMiIsIG5ld19vYmplY3QtPnR3b18pOworICBBU1NFUlRfRVEoIjMiLCBuZXdfb2JqZWN0LT50aHJlZV8pOworICBBU1NFUlRfRVEoNCwgbmV3X29iamVjdC0+Zm91cl8tPnZhbHVlKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgSW5pdGlhbEJsb2NrVG9vU21hbGwpIHsKKyAgLy8gQ29uc3RydWN0IGEgc21hbGwgKDY0IGJ5dGUpIGluaXRpYWwgYmxvY2sgb2YgbWVtb3J5IHRvIGJlIHVzZWQgYnkgdGhlCisgIC8vIGFyZW5hIGFsbG9jYXRvcjsgdGhlbiwgYWxsb2NhdGUgYW4gb2JqZWN0IHdoaWNoIHdpbGwgbm90IGZpdCBpbiB0aGUKKyAgLy8gaW5pdGlhbCBibG9jay4KKyAgc3RkOjp2ZWN0b3I8Y2hhcj4gYXJlbmFfYmxvY2soNjQpOworICBBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gJmFyZW5hX2Jsb2NrWzBdOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgQXJlbmEgYXJlbmEob3B0aW9ucyk7CisKKyAgY2hhciogcCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZUFycmF5PGNoYXI+KCZhcmVuYSwgOTYpOworICB1aW50cHRyX3QgYWxsb2NhdGlvbiA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihwKTsKKworICAvLyBFbnN1cmUgdGhhdCB0aGUgYXJlbmEgYWxsb2NhdG9yIGRpZCBub3QgcmV0dXJuIG1lbW9yeSBwb2ludGluZyBpbnRvIHRoZQorICAvLyBpbml0aWFsIGJsb2NrIG9mIG1lbW9yeS4KKyAgdWludHB0cl90IGFyZW5hX3N0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KCZhcmVuYV9ibG9ja1swXSk7CisgIHVpbnRwdHJfdCBhcmVuYV9lbmQgPSBhcmVuYV9zdGFydCArIGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgRVhQRUNUX0ZBTFNFKGFsbG9jYXRpb24gPj0gYXJlbmFfc3RhcnQgJiYgYWxsb2NhdGlvbiA8IGFyZW5hX2VuZCk7CisKKyAgLy8gV3JpdGUgdG8gdGhlIG1lbW9yeSB3ZSBhbGxvY2F0ZWQ7IHRoaXMgc2hvdWxkIChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgIC8vIHRyaWdnZXIgYSBjaGVjayBmb3IgaGVhcCBjb3JydXB0aW9uIGlmIHRoZSBvYmplY3Qgd2FzIGFsbG9jYXRlZCBmcm9tIHRoZQorICAvLyBpbml0aWFsbHktcHJvdmlkZWQgYmxvY2suCisgIG1lbXNldChwLCAnXDAnLCA5Nik7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBQYXJzaW5nKSB7CisgIFRlc3RBbGxUeXBlcyBvcmlnaW5hbDsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmb3JpZ2luYWwpOworCisgIC8vIFRlc3QgbWVtb3J5IGxlYWsuCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIGFyZW5hX21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhvcmlnaW5hbC5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldCgqYXJlbmFfbWVzc2FnZSk7CisKKyAgLy8gVGVzdCB0aGF0IHN0cmluZyBmaWVsZHMgaGF2ZSBudWxsIHRlcm1pbmF0b3IgYnl0ZXMgKGVhcmxpZXIgYnVnKS4KKyAgRVhQRUNUX0VRKHN0cmxlbihvcmlnaW5hbC5vcHRpb25hbF9zdHJpbmcoKS5jX3N0cigpKSwKKyAgICAgICAgICAgIHN0cmxlbihhcmVuYV9tZXNzYWdlLT5vcHRpb25hbF9zdHJpbmcoKS5jX3N0cigpKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbmtub3duRmllbGRzKSB7CisgIFRlc3RBbGxUeXBlcyBvcmlnaW5hbDsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmb3JpZ2luYWwpOworCisgIC8vIFRlc3QgYmFzaWMgcGFyc2luZyBpbnRvIChwb3B1bGF0aW5nKSBhbmQgcmVhZGluZyBvdXQgb2YgdW5rbm93biBmaWVsZHMgb24KKyAgLy8gYW4gYXJlbmEuCisgIEFyZW5hIGFyZW5hOworICBUZXN0RW1wdHlNZXNzYWdlKiBhcmVuYV9tZXNzYWdlID0KKyAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RFbXB0eU1lc3NhZ2U+KCZhcmVuYSk7CisgIGFyZW5hX21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhvcmlnaW5hbC5TZXJpYWxpemVBc1N0cmluZygpKTsKKworICBUZXN0QWxsVHlwZXMgY29waWVkOworICBjb3BpZWQuUGFyc2VGcm9tU3RyaW5nKGFyZW5hX21lc3NhZ2UtPlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KGNvcGllZCk7CisKKyAgLy8gRXhlcmNpc2UgVUZTIG1hbnVhbCBtYW5pcHVsYXRpb24gKHNldHRlcnMpLgorICBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEVtcHR5TWVzc2FnZT4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoCisgICAgICBUZXN0QWxsVHlwZXM6OmtPcHRpb25hbEludDMyRmllbGROdW1iZXIsIDQyKTsKKyAgY29waWVkLkNsZWFyKCk7CisgIGNvcGllZC5QYXJzZUZyb21TdHJpbmcoYXJlbmFfbWVzc2FnZS0+U2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIEVYUEVDVF9UUlVFKGNvcGllZC5oYXNfb3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSg0MiwgY29waWVkLm9wdGlvbmFsX2ludDMyKCkpOworCisgIC8vIEV4ZXJjaXNlIFVGUyBzd2FwIHBhdGguCisgIFRlc3RFbXB0eU1lc3NhZ2UqIGFyZW5hX21lc3NhZ2VfMiA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0RW1wdHlNZXNzYWdlPigmYXJlbmEpOworICBhcmVuYV9tZXNzYWdlXzItPlN3YXAoYXJlbmFfbWVzc2FnZSk7CisgIGNvcGllZC5DbGVhcigpOworICBjb3BpZWQuUGFyc2VGcm9tU3RyaW5nKGFyZW5hX21lc3NhZ2VfMi0+U2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIEVYUEVDVF9UUlVFKGNvcGllZC5oYXNfb3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSg0MiwgY29waWVkLm9wdGlvbmFsX2ludDMyKCkpOworCisgIC8vIFRlc3QgZmllbGQgbWFuaXB1bGF0aW9uLgorICBUZXN0RW1wdHlNZXNzYWdlKiBhcmVuYV9tZXNzYWdlXzMgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEVtcHR5TWVzc2FnZT4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZV8zLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxMDAwLCA0Mik7CisgIGFyZW5hX21lc3NhZ2VfMy0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRGaXhlZDMyKDEwMDEsIDQyKTsKKyAgYXJlbmFfbWVzc2FnZV8zLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZEZpeGVkNjQoMTAwMiwgNDIpOworICBhcmVuYV9tZXNzYWdlXzMtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkTGVuZ3RoRGVsaW1pdGVkKDEwMDMpOworICBhcmVuYV9tZXNzYWdlXzMtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+RGVsZXRlU3VicmFuZ2UoMCwgMik7CisgIGFyZW5hX21lc3NhZ2VfMy0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5EZWxldGVCeU51bWJlcigxMDAyKTsKKyAgYXJlbmFfbWVzc2FnZV8zLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkRlbGV0ZUJ5TnVtYmVyKDEwMDMpOworICBFWFBFQ1RfVFJVRShhcmVuYV9tZXNzYWdlXzMtPnVua25vd25fZmllbGRzKCkuZW1wdHkoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTd2FwKSB7CisgIEFyZW5hIGFyZW5hMTsKKyAgQXJlbmEgYXJlbmEyOworICBUZXN0QWxsVHlwZXMqIGFyZW5hMV9tZXNzYWdlOworICBUZXN0QWxsVHlwZXMqIGFyZW5hMl9tZXNzYWdlOworCisgIC8vIENhc2UgMTogU3dhcCgpLCBubyBVRlMgb24gZWl0aGVyIG1lc3NhZ2UsIGJvdGggbWVzc2FnZXMgb24gZGlmZmVyZW50CisgIC8vIGFyZW5hcy4gQXJlbmEgcG9pbnRlcnMgc2hvdWxkIHJlbWFpbiB0aGUgc2FtZSBhZnRlciBzd2FwLgorICBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIGFyZW5hMl9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEyKTsKKyAgYXJlbmExX21lc3NhZ2UtPlN3YXAoYXJlbmEyX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoJmFyZW5hMSwgYXJlbmExX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICBFWFBFQ1RfRVEoJmFyZW5hMiwgYXJlbmEyX21lc3NhZ2UtPkdldEFyZW5hKCkpOworCisgIC8vIENhc2UgMjogU3dhcCgpLCBVRlMgb24gb25lIG1lc3NhZ2UsIGJvdGggbWVzc2FnZXMgb24gZGlmZmVyZW50IGFyZW5hcy4KKyAgYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgIGFyZW5hMV9tZXNzYWdlLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxLCA0Mik7CisgIGFyZW5hMV9tZXNzYWdlLT5Td2FwKGFyZW5hMl9tZXNzYWdlKTsKKyAgRVhQRUNUX0VRKCZhcmVuYTEsIGFyZW5hMV9tZXNzYWdlLT5HZXRBcmVuYSgpKTsKKyAgRVhQRUNUX0VRKCZhcmVuYTIsIGFyZW5hMl9tZXNzYWdlLT5HZXRBcmVuYSgpKTsKKyAgRVhQRUNUX0VRKDAsIGFyZW5hMV9tZXNzYWdlLT51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgYXJlbmEyX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSg0MiwgYXJlbmEyX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudmFyaW50KCkpOworCisgIC8vIENhc2UgMzogU3dhcCgpLCBVRlMgb24gYm90aCBtZXNzYWdlcywgYm90aCBtZXNzYWdlcyBvbiBkaWZmZXJlbnQgYXJlbmFzLgorICBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIGFyZW5hMl9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEyKTsKKyAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEsIDQyKTsKKyAgYXJlbmEyX21lc3NhZ2UtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDIsIDg0KTsKKyAgYXJlbmExX21lc3NhZ2UtPlN3YXAoYXJlbmEyX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoJmFyZW5hMSwgYXJlbmExX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICBFWFBFQ1RfRVEoJmFyZW5hMiwgYXJlbmEyX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICBFWFBFQ1RfRVEoMSwgYXJlbmExX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBhcmVuYTJfbWVzc2FnZS0+dW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDg0LCBhcmVuYTFfbWVzc2FnZS0+dW5rbm93bl9maWVsZHMoKS5maWVsZCgwKS52YXJpbnQoKSk7CisgIEVYUEVDVF9FUSg0MiwgYXJlbmEyX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudmFyaW50KCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgU2V0QWxsb2NhdGVkTWVzc2FnZSkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzICphcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3RlZCA9IG5ldyBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U7CisgIG5lc3RlZC0+c2V0X2JiKDExOCk7CisgIGFyZW5hX21lc3NhZ2UtPnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UobmVzdGVkKTsKKyAgRVhQRUNUX0VRKDExOCwgYXJlbmFfbWVzc2FnZS0+b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKKworICBwcm90b2J1Zl91bml0dGVzdF9ub19hcmVuYTo6VGVzdE5vQXJlbmFNZXNzYWdlIG5vX2FyZW5hX21lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShub19hcmVuYV9tZXNzYWdlLmhhc19hcmVuYV9tZXNzYWdlKCkpOworICBub19hcmVuYV9tZXNzYWdlLnNldF9hbGxvY2F0ZWRfYXJlbmFfbWVzc2FnZShOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG5vX2FyZW5hX21lc3NhZ2UuaGFzX2FyZW5hX21lc3NhZ2UoKSk7CisgIG5vX2FyZW5hX21lc3NhZ2Uuc2V0X2FsbG9jYXRlZF9hcmVuYV9tZXNzYWdlKG5ldyBBcmVuYU1lc3NhZ2UpOworICBFWFBFQ1RfVFJVRShub19hcmVuYV9tZXNzYWdlLmhhc19hcmVuYV9tZXNzYWdlKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgUmVsZWFzZU1lc3NhZ2UpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTE4KTsKKyAgc2NvcGVkX3B0cjxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+IG5lc3RlZCgKKyAgICAgIGFyZW5hX21lc3NhZ2UtPnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgxMTgsIG5lc3RlZC0+YmIoKSk7CisKKyAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiByZWxlYXNlZF9udWxsID0KKyAgICAgIGFyZW5hX21lc3NhZ2UtPnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0VRKE5VTEwsIHJlbGVhc2VkX251bGwpOworfQorCitURVNUKEFyZW5hVGVzdCwgU2V0QWxsb2NhdGVkU3RyaW5nKSB7CisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIHN0cmluZyogYWxsb2NhdGVkX3N0ciA9IG5ldyBzdHJpbmcoImhlbGxvIik7CisgIGFyZW5hX21lc3NhZ2UtPnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfc3RyaW5nKGFsbG9jYXRlZF9zdHIpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgYXJlbmFfbWVzc2FnZS0+b3B0aW9uYWxfc3RyaW5nKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgUmVsZWFzZVN0cmluZykgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBhcmVuYV9tZXNzYWdlLT5zZXRfb3B0aW9uYWxfc3RyaW5nKCJoZWxsbyIpOworICBzY29wZWRfcHRyPHN0cmluZz4gcmVsZWFzZWRfc3RyKAorICAgICAgYXJlbmFfbWVzc2FnZS0+cmVsZWFzZV9vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCAqcmVsZWFzZWRfc3RyKTsKKworICAvLyBUZXN0IGRlZmF1bHQgdmFsdWUuCit9CisKKworVEVTVChBcmVuYVRlc3QsIFN3YXBCZXR3ZWVuQXJlbmFzV2l0aEFsbEZpZWxkc1NldCkgeworICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICB7CisgICAgQXJlbmEgYXJlbmEyOworICAgIFRlc3RBbGxUeXBlcyogYXJlbmEyX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTIpOworICAgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoYXJlbmEyX21lc3NhZ2UpOworICAgIGFyZW5hMl9tZXNzYWdlLT5Td2FwKGFyZW5hMV9tZXNzYWdlKTsKKyAgICBzdHJpbmcgb3V0cHV0OworICAgIGFyZW5hMl9tZXNzYWdlLT5TZXJpYWxpemVUb1N0cmluZygmb3V0cHV0KTsKKyAgICBFWFBFQ1RfRVEoMCwgb3V0cHV0LnNpemUoKSk7CisgIH0KKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldCgqYXJlbmExX21lc3NhZ2UpOworfQorCitURVNUKEFyZW5hVGVzdCwgU3dhcEJldHdlZW5BcmVuYUFuZE5vbkFyZW5hV2l0aEFsbEZpZWxkc1NldCkgeworICBUZXN0QWxsVHlwZXMgbm9uX2FyZW5hX21lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm5vbl9hcmVuYV9tZXNzYWdlKTsKKyAgeworICAgIEFyZW5hIGFyZW5hMjsKKyAgICBUZXN0QWxsVHlwZXMqIGFyZW5hMl9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEyKTsKKyAgICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKGFyZW5hMl9tZXNzYWdlKTsKKyAgICBhcmVuYTJfbWVzc2FnZS0+U3dhcCgmbm9uX2FyZW5hX21lc3NhZ2UpOworICAgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQoKmFyZW5hMl9tZXNzYWdlKTsKKyAgICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG5vbl9hcmVuYV9tZXNzYWdlKTsKKyAgfQorfQorCitURVNUKEFyZW5hVGVzdCwgVW5zYWZlQXJlbmFTd2FwKSB7CisgIEFyZW5hIHNoYXJlZF9hcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlMSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJnNoYXJlZF9hcmVuYSk7CisgIFRlc3RBbGxUeXBlcyogbWVzc2FnZTIgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZzaGFyZWRfYXJlbmEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKG1lc3NhZ2UxKTsKKyAgbWVzc2FnZTEtPlVuc2FmZUFyZW5hU3dhcChtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQoKm1lc3NhZ2UyKTsKK30KKworVEVTVChBcmVuYVRlc3QsIFN3YXBCZXR3ZWVuQXJlbmFzVXNpbmdSZWZsZWN0aW9uKSB7CisgIEFyZW5hIGFyZW5hMTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzKiBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcyhhcmVuYTJfbWVzc2FnZSk7CisgICAgY29uc3QgUmVmbGVjdGlvbiogciA9IGFyZW5hMl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgci0+U3dhcChhcmVuYTFfbWVzc2FnZSwgYXJlbmEyX21lc3NhZ2UpOworICAgIHN0cmluZyBvdXRwdXQ7CisgICAgYXJlbmEyX21lc3NhZ2UtPlNlcmlhbGl6ZVRvU3RyaW5nKCZvdXRwdXQpOworICAgIEVYUEVDVF9FUSgwLCBvdXRwdXQuc2l6ZSgpKTsKKyAgfQorICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KCphcmVuYTFfbWVzc2FnZSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTd2FwQmV0d2VlbkFyZW5hQW5kTm9uQXJlbmFVc2luZ1JlZmxlY3Rpb24pIHsKKyAgVGVzdEFsbFR5cGVzIG5vbl9hcmVuYV9tZXNzYWdlOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZub25fYXJlbmFfbWVzc2FnZSk7CisgIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzKiBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcyhhcmVuYTJfbWVzc2FnZSk7CisgICAgY29uc3QgUmVmbGVjdGlvbiogciA9IGFyZW5hMl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgci0+U3dhcCgmbm9uX2FyZW5hX21lc3NhZ2UsIGFyZW5hMl9tZXNzYWdlKTsKKyAgICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KCphcmVuYTJfbWVzc2FnZSk7CisgICAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChub25fYXJlbmFfbWVzc2FnZSk7CisgIH0KK30KKworVEVTVChBcmVuYVRlc3QsIFJlbGVhc2VGcm9tQXJlbmFNZXNzYWdlTWFrZXNDb3B5KSB7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkX21zZyA9IE5VTEw7CisgIHN0cmluZyogbmVzdGVkX3N0cmluZyA9IE5VTEw7CisgIHsKKyAgICBBcmVuYSBhcmVuYTsKKyAgICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgICAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICAgICphcmVuYV9tZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX3N0cmluZygpID0gIkhlbGxvIjsKKyAgICBuZXN0ZWRfbXNnID0gYXJlbmFfbWVzc2FnZS0+cmVsZWFzZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICAgIG5lc3RlZF9zdHJpbmcgPSBhcmVuYV9tZXNzYWdlLT5yZWxlYXNlX29wdGlvbmFsX3N0cmluZygpOworICB9CisgIEVYUEVDVF9FUSg0MiwgbmVzdGVkX21zZy0+YmIoKSk7CisgIEVYUEVDVF9FUSgiSGVsbG8iLCAqbmVzdGVkX3N0cmluZyk7CisgIGRlbGV0ZSBuZXN0ZWRfbXNnOworICBkZWxldGUgbmVzdGVkX3N0cmluZzsKK30KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fUlRUSQorVEVTVChBcmVuYVRlc3QsIFJlbGVhc2VGcm9tQXJlbmFNZXNzYWdlVXNpbmdSZWZsZWN0aW9uTWFrZXNDb3B5KSB7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkX21zZyA9IE5VTEw7CisgIC8vIE5vdGU6IG5vIHN0cmluZzogcmVmbGVjdGlvbiBBUEkgb25seSBzdXBwb3J0cyByZWxlYXNpbmcgc3VibWVzc2FnZXMuCisgIHsKKyAgICBBcmVuYSBhcmVuYTsKKyAgICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgICAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHIgPSBhcmVuYV9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmID0gYXJlbmFfbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAgICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICAgIG5lc3RlZF9tc2cgPSBzdGF0aWNfY2FzdDxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqPigKKyAgICAgICAgci0+UmVsZWFzZU1lc3NhZ2UoYXJlbmFfbWVzc2FnZSwgZikpOworICB9CisgIEVYUEVDVF9FUSg0MiwgbmVzdGVkX21zZy0+YmIoKSk7CisgIGRlbGV0ZSBuZXN0ZWRfbXNnOworfQorI2VuZGlmICAvLyAhR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKworVEVTVChBcmVuYVRlc3QsIFVuc2FmZUFyZW5hUmVsZWFzZURvZXNOb3RNYWtlQ29weSkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3RlZF9tc2cgPSBOVUxMOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG9yaWdfbmVzdGVkX21zZyA9IE5VTEw7CisgIHN0cmluZyogbmVzdGVkX3N0cmluZyA9IE5VTEw7CisgIHN0cmluZyogb3JpZ19uZXN0ZWRfc3RyaW5nID0gTlVMTDsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICAqYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKSA9ICJIZWxsbyI7CisgIG9yaWdfbmVzdGVkX21zZyA9IGFyZW5hX21lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgb3JpZ19uZXN0ZWRfc3RyaW5nID0gYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKTsKKyAgbmVzdGVkX21zZyA9IGFyZW5hX21lc3NhZ2UtPnVuc2FmZV9hcmVuYV9yZWxlYXNlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCk7CisgIG5lc3RlZF9zdHJpbmcgPSBhcmVuYV9tZXNzYWdlLT51bnNhZmVfYXJlbmFfcmVsZWFzZV9vcHRpb25hbF9zdHJpbmcoKTsKKworICBFWFBFQ1RfRVEob3JpZ19uZXN0ZWRfbXNnLCBuZXN0ZWRfbXNnKTsKKyAgRVhQRUNUX0VRKG9yaWdfbmVzdGVkX3N0cmluZywgbmVzdGVkX3N0cmluZyk7CisgIC8vIFJlbGVhc2VkIHBvaW50ZXJzIHN0aWxsIG9uIGFyZW5hOyBubyAnZGVsZXRlJyBjYWxscyBuZWVkZWQgaGVyZS4KK30KKworVEVTVChBcmVuYVRlc3QsIFNldEFsbG9jYXRlZEFjcm9zc0FyZW5hcykgeworICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGhlYXBfc3VibWVzc2FnZSA9CisgICAgICBuZXcgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKCk7CisgIGhlYXBfc3VibWVzc2FnZS0+c2V0X2JiKDQyKTsKKyAgYXJlbmExX21lc3NhZ2UtPnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoaGVhcF9zdWJtZXNzYWdlKTsKKyAgLy8gU2hvdWxkIGtlZXAgc2FtZSBvYmplY3QgYW5kIGFkZCB0byBhcmVuYSdzIE93bigpLWxpc3QuCisgIEVYUEVDVF9FUShoZWFwX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgeworICAgIEFyZW5hIGFyZW5hMjsKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGFyZW5hMl9zdWJtZXNzYWdlID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmEyKTsKKyAgICBhcmVuYTJfc3VibWVzc2FnZS0+c2V0X2JiKDQyKTsKKyAgICBhcmVuYTFfbWVzc2FnZS0+c2V0X2FsbG9jYXRlZF9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZShhcmVuYTJfc3VibWVzc2FnZSk7CisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgfQorCisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogYXJlbmExX3N1Ym1lc3NhZ2UgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmExKTsKKyAgYXJlbmExX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgIFRlc3RBbGxUeXBlcyogaGVhcF9tZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlczsKKyAgaGVhcF9tZXNzYWdlLT5zZXRfYWxsb2NhdGVkX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKGFyZW5hMV9zdWJtZXNzYWdlKTsKKyAgRVhQRUNUX05FKGFyZW5hMV9zdWJtZXNzYWdlLAorICAgICAgICAgICAgaGVhcF9tZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBkZWxldGUgaGVhcF9tZXNzYWdlOworfQorCitURVNUKEFyZW5hVGVzdCwgU2V0QWxsb2NhdGVkQWNyb3NzQXJlbmFzV2l0aFJlZmxlY3Rpb24pIHsKKyAgLy8gU2FtZSBhcyBhYm92ZSwgd2l0aCByZWZsZWN0aW9uLgorICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gYXJlbmExX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IGFyZW5hMV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbXNnX2ZpZWxkID0gZC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogaGVhcF9zdWJtZXNzYWdlID0KKyAgICAgIG5ldyBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UoKTsKKyAgaGVhcF9zdWJtZXNzYWdlLT5zZXRfYmIoNDIpOworICByLT5TZXRBbGxvY2F0ZWRNZXNzYWdlKGFyZW5hMV9tZXNzYWdlLCBoZWFwX3N1Ym1lc3NhZ2UsIG1zZ19maWVsZCk7CisgIC8vIFNob3VsZCBrZWVwIHNhbWUgb2JqZWN0IGFuZCBhZGQgdG8gYXJlbmEncyBPd24oKS1saXN0LgorICBFWFBFQ1RfRVEoaGVhcF9zdWJtZXNzYWdlLAorICAgICAgICAgICAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBhcmVuYTJfc3VibWVzc2FnZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZT4oJmFyZW5hMik7CisgICAgYXJlbmEyX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgICAgci0+U2V0QWxsb2NhdGVkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgYXJlbmEyX3N1Ym1lc3NhZ2UsIG1zZ19maWVsZCk7CisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgfQorCisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogYXJlbmExX3N1Ym1lc3NhZ2UgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmExKTsKKyAgYXJlbmExX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgIFRlc3RBbGxUeXBlcyogaGVhcF9tZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlczsKKyAgci0+U2V0QWxsb2NhdGVkTWVzc2FnZShoZWFwX21lc3NhZ2UsIGFyZW5hMV9zdWJtZXNzYWdlLCBtc2dfZmllbGQpOworICBFWFBFQ1RfTkUoYXJlbmExX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICBoZWFwX21lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIGRlbGV0ZSBoZWFwX21lc3NhZ2U7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBBZGRBbGxvY2F0ZWRXaXRoUmVmbGVjdGlvbikgeworICBBcmVuYSBhcmVuYTE7CisgIEFyZW5hTWVzc2FnZSogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxBcmVuYU1lc3NhZ2U+KCZhcmVuYTEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gYXJlbmExX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IGFyZW5hMV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmQgPQorICAgICAgZC0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbXBvcnRfbm9fYXJlbmFfbWVzc2FnZSIpOworICAvLyBNZXNzYWdlIHdpdGggY2NfZW5hYmxlX2FyZW5hcyA9IGZhbHNlOworICByLT5BZGRNZXNzYWdlKGFyZW5hMV9tZXNzYWdlLCBmZCk7CisgIHItPkFkZE1lc3NhZ2UoYXJlbmExX21lc3NhZ2UsIGZkKTsKKyAgci0+QWRkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgZmQpOworICBFWFBFQ1RfRVEoMywgci0+RmllbGRTaXplKCphcmVuYTFfbWVzc2FnZSwgZmQpKTsKKyAgLy8gTWVzc2FnZSB3aXRoIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworICBmZCA9IGQtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKTsKKyAgci0+QWRkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgZmQpOworICByLT5BZGRNZXNzYWdlKGFyZW5hMV9tZXNzYWdlLCBmZCk7CisgIHItPkFkZE1lc3NhZ2UoYXJlbmExX21lc3NhZ2UsIGZkKTsKKyAgRVhQRUNUX0VRKDMsIHItPkZpZWxkU2l6ZSgqYXJlbmExX21lc3NhZ2UsIGZkKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBSZXBlYXRlZFB0ckZpZWxkQWRkQ2xlYXJlZFRlc3QpIHsKKyAgeworICAgIFJlcGVhdGVkUHRyRmllbGQ8VGVzdEFsbFR5cGVzPiByZXBlYXRlZF9maWVsZDsKKyAgICBFWFBFQ1RfVFJVRShyZXBlYXRlZF9maWVsZC5lbXB0eSgpKTsKKyAgICBFWFBFQ1RfRVEoMCwgcmVwZWF0ZWRfZmllbGQuc2l6ZSgpKTsKKyAgICAvLyBPd25lcnNoaXAgaXMgcGFzc2VkIHRvIHJlcGVhdGVkX2ZpZWxkLgorICAgIFRlc3RBbGxUeXBlcyogY2xlYXJlZCA9IG5ldyBUZXN0QWxsVHlwZXMoKTsKKyAgICByZXBlYXRlZF9maWVsZC5BZGRDbGVhcmVkKGNsZWFyZWQpOworICAgIEVYUEVDVF9UUlVFKHJlcGVhdGVkX2ZpZWxkLmVtcHR5KCkpOworICAgIEVYUEVDVF9FUSgwLCByZXBlYXRlZF9maWVsZC5zaXplKCkpOworICB9CisgIHsKKyAgICBSZXBlYXRlZFB0ckZpZWxkPFRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRfZmllbGQ7CisgICAgRVhQRUNUX1RSVUUocmVwZWF0ZWRfZmllbGQuZW1wdHkoKSk7CisgICAgRVhQRUNUX0VRKDAsIHJlcGVhdGVkX2ZpZWxkLnNpemUoKSk7CisgICAgLy8gT3duZXJzaGlwIGlzIHBhc3NlZCB0byByZXBlYXRlZF9maWVsZC4KKyAgICBUZXN0QWxsVHlwZXMqIGNsZWFyZWQgPSBuZXcgVGVzdEFsbFR5cGVzKCk7CisgICAgcmVwZWF0ZWRfZmllbGQuQWRkQWxsb2NhdGVkKGNsZWFyZWQpOworICAgIEVYUEVDVF9GQUxTRShyZXBlYXRlZF9maWVsZC5lbXB0eSgpKTsKKyAgICBFWFBFQ1RfRVEoMSwgcmVwZWF0ZWRfZmllbGQuc2l6ZSgpKTsKKyAgfQorfQorCisvLyBOLkIuOiBubyByZWZsZWN0aW9uIHZlcnNpb24gb2YgdGhpcyB0ZXN0IGJlY2F1c2UgYWxsIHRoZSBhcmVuYS1zcGVjaWZpYyBjb2RlCisvLyBpcyBpbiBSZXBlYXRlZFB0ckZpZWxkLCBhbmQgdGhlIHJlZmxlY3Rpb24gd29ya3MgaW1wbGljaXRseSBiYXNlZCBvbiB0aGF0LgorVEVTVChBcmVuYVRlc3QsIEFkZEFsbG9jYXRlZFRvUmVwZWF0ZWRGaWVsZCkgeworICAvLyBIZWFwLT5hcmVuYSBjYXNlLgorICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGhlYXBfc3VibWVzc2FnZSA9CisgICAgICAgIG5ldyBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UoKTsKKyAgICBoZWFwX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgICAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+CisgICAgICAgIEFkZEFsbG9jYXRlZChoZWFwX3N1Ym1lc3NhZ2UpOworICAgIC8vIFNob3VsZCBub3QgY29weSBvYmplY3QgLS0gd2lsbCB1c2UgYXJlbmFfLT5Pd24oKS4KKyAgICBFWFBFQ1RfRVEoaGVhcF9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICAmYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpKTsKKyAgICBFWFBFQ1RfRVEoNDIsIGFyZW5hMV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZShpKS5iYigpKTsKKyAgfQorCisgIC8vIEFyZW5hMS0+QXJlbmEyIGNhc2UuCisgIGFyZW5hMV9tZXNzYWdlLT5DbGVhcigpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBhcmVuYTJfc3VibWVzc2FnZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZT4oJmFyZW5hMik7CisgICAgYXJlbmEyX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgICAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+CisgICAgICAgIEFkZEFsbG9jYXRlZChhcmVuYTJfc3VibWVzc2FnZSk7CisgICAgLy8gU2hvdWxkIGNvcHkgb2JqZWN0LgorICAgIEVYUEVDVF9ORShhcmVuYTJfc3VibWVzc2FnZSwKKyAgICAgICAgICAgICAgJmFyZW5hMV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZShpKSk7CisgICAgRVhQRUNUX0VRKDQyLCBhcmVuYTFfbWVzc2FnZS0+cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoaSkuYmIoKSk7CisgIH0KKworICAvLyBBcmVuYS0+aGVhcCBjYXNlLgorICBUZXN0QWxsVHlwZXMqIGhlYXBfbWVzc2FnZSA9IG5ldyBUZXN0QWxsVHlwZXMoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgQXJlbmEgYXJlbmEyOworICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogYXJlbmEyX3N1Ym1lc3NhZ2UgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+KCZhcmVuYTIpOworICAgIGFyZW5hMl9zdWJtZXNzYWdlLT5zZXRfYmIoNDIpOworICAgIGhlYXBfbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT4KKyAgICAgICAgQWRkQWxsb2NhdGVkKGFyZW5hMl9zdWJtZXNzYWdlKTsKKyAgICAvLyBTaG91bGQgY29weSBvYmplY3QuCisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICAmaGVhcF9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZShpKSk7CisgICAgRVhQRUNUX0VRKDQyLCBoZWFwX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpLmJiKCkpOworICB9CisgIGRlbGV0ZSBoZWFwX21lc3NhZ2U7CisKKyAgLy8gSGVhcC1hcmVuYSBjYXNlIGZvciBzdHJpbmdzICh3aGljaCBhcmUgbm90IGFyZW5hLWFsbG9jYXRlZCkuCisgIGFyZW5hMV9tZXNzYWdlLT5DbGVhcigpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBzdHJpbmcqIHMgPSBuZXcgc3RyaW5nKCJUZXN0Iik7CisgICAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPgorICAgICAgICBBZGRBbGxvY2F0ZWQocyk7CisgICAgLy8gU2hvdWxkIG5vdCBjb3B5LgorICAgIEVYUEVDVF9FUShzLCAmYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX3N0cmluZyhpKSk7CisgICAgRVhQRUNUX0VRKCJUZXN0IiwgYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX3N0cmluZyhpKSk7CisgIH0KK30KKworVEVTVChBcmVuYVRlc3QsIFJlbGVhc2VMYXN0UmVwZWF0ZWRGaWVsZCkgeworICAvLyBSZWxlYXNlIGZyb20gYXJlbmEtYWxsb2NhdGVkIHJlcGVhdGVkIGZpZWxkIGFuZCBlbnN1cmUgdGhhdCByZXR1cm5lZCBvYmplY3QKKyAgLy8gaXMgaGVhcC1hbGxvY2F0ZWQuCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmEpOworICAgIG5lc3RlZC0+c2V0X2JiKDQyKTsKKyAgICBhcmVuYV9tZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPkFkZEFsbG9jYXRlZChuZXN0ZWQpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgY29uc3QgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlICpvcmlnX3N1Ym1lc3NhZ2UgPQorICAgICAgICAmYXJlbmFfbWVzc2FnZS0+cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMTAgLSAxIC0gaSk7ICAvLyBsYXN0IGVsZW1lbnQKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgKnJlbGVhc2VkID0KKyAgICAgICAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5SZWxlYXNlTGFzdCgpOworICAgIEVYUEVDVF9ORShyZWxlYXNlZCwgb3JpZ19zdWJtZXNzYWdlKTsKKyAgICBFWFBFQ1RfRVEoNDIsIHJlbGVhc2VkLT5iYigpKTsKKyAgICBkZWxldGUgcmVsZWFzZWQ7CisgIH0KKworICAvLyBUZXN0IFVuc2FmZUFyZW5hUmVsZWFzZUxhc3QoKS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBuZXN0ZWQgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+KCZhcmVuYSk7CisgICAgbmVzdGVkLT5zZXRfYmIoNDIpOworICAgIGFyZW5hX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+QWRkQWxsb2NhdGVkKG5lc3RlZCk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBjb25zdCBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgKm9yaWdfc3VibWVzc2FnZSA9CisgICAgICAgICZhcmVuYV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgxMCAtIDEgLSBpKTsgIC8vIGxhc3QgZWxlbWVudAorICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSAqcmVsZWFzZWQgPQorICAgICAgICBhcmVuYV9tZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPgorICAgICAgICBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCk7CisgICAgRVhQRUNUX0VRKHJlbGVhc2VkLCBvcmlnX3N1Ym1lc3NhZ2UpOworICAgIEVYUEVDVF9FUSg0MiwgcmVsZWFzZWQtPmJiKCkpOworICAgIC8vIG5vIGRlbGV0ZSAtLSB8cmVsZWFzZWR8IGlzIG9uIHRoZSBhcmVuYS4KKyAgfQorCisgIC8vIFRlc3Qgc3RyaW5nIGNhc2UgYXMgd2VsbC4gUmVsZWFzZUxhc3QoKSBpbiB0aGlzIGNhc2UgbXVzdCBjb3B5IHRoZSBzdHJpbmcsCisgIC8vIGV2ZW4gdGhvdWdoIGl0IHdhcyBvcmlnaW5hbGx5IGhlYXAtYWxsb2NhdGVkIGFuZCBpdHMgcG9pbnRlciB3YXMgc2ltcGx5CisgIC8vIGFwcGVuZGVkIHRvIHRoZSByZXBlYXRlZCBmaWVsZCdzIGludGVybmFsIHZlY3RvciwgYmVjYXVzZSB0aGUgc3RyaW5nIHdhcworICAvLyBwbGFjZWQgb24gdGhlIGFyZW5hJ3MgZGVzdHJ1Y3RvciBsaXN0IGFuZCBjYW5ub3QgYmUgcmVtb3ZlZCBmcm9tIHRoYXQgbGlzdAorICAvLyAoc28gdGhlIGFyZW5hIHBlcm1hbmVudGx5IG93bnMgdGhlIG9yaWdpbmFsIGluc3RhbmNlKS4KKyAgYXJlbmFfbWVzc2FnZS0+Q2xlYXIoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgc3RyaW5nKiBzID0gbmV3IHN0cmluZygiVGVzdCIpOworICAgIGFyZW5hX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPkFkZEFsbG9jYXRlZChzKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBjb25zdCBzdHJpbmcqIG9yaWdfZWxlbWVudCA9ICZhcmVuYV9tZXNzYWdlLT5yZXBlYXRlZF9zdHJpbmcoMTAgLSAxIC0gaSk7CisgICAgc3RyaW5nKiByZWxlYXNlZCA9IGFyZW5hX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPlJlbGVhc2VMYXN0KCk7CisgICAgRVhQRUNUX05FKHJlbGVhc2VkLCBvcmlnX2VsZW1lbnQpOworICAgIEVYUEVDVF9FUSgiVGVzdCIsICpyZWxlYXNlZCk7CisgICAgZGVsZXRlIHJlbGVhc2VkOworICB9Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbnNhZmVBcmVuYVJlbGVhc2VBZGQpIHsKKyAgLy8gVXNlIHVuc2FmZV9hcmVuYV9yZWxlYXNlKCkgYW5kIHVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkKCkgdG8gdHJhbnNmZXIgYW4KKyAgLy8gYXJlbmEtYWxsb2NhdGVkIHN0cmluZyBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIuCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIG1lc3NhZ2UxID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBUZXN0QWxsVHlwZXMqIG1lc3NhZ2UyID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBzdHJpbmcqIGFyZW5hX3N0cmluZyA9IEFyZW5hOjpDcmVhdGU8c3RyaW5nPigmYXJlbmEpOworICAqYXJlbmFfc3RyaW5nID0gIlRlc3QgY29udGVudCI7CisKKyAgbWVzc2FnZTEtPnVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkX29wdGlvbmFsX3N0cmluZyhhcmVuYV9zdHJpbmcpOworICBFWFBFQ1RfRVEoYXJlbmFfc3RyaW5nLCBtZXNzYWdlMS0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKSk7CisgIG1lc3NhZ2UyLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9zdHJpbmcoCisgICAgICBtZXNzYWdlMS0+dW5zYWZlX2FyZW5hX3JlbGVhc2Vfb3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoYXJlbmFfc3RyaW5nLCBtZXNzYWdlMi0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZCkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBzdHJpbmcqIGFyZW5hX3N0cmluZyA9IEFyZW5hOjpDcmVhdGU8c3RyaW5nPigmYXJlbmEpOworICAgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPlVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkKGFyZW5hX3N0cmluZyk7CisgICAgRVhQRUNUX0VRKGFyZW5hX3N0cmluZywgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9zdHJpbmcoaSkpOworICB9Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbnNhZmVBcmVuYVJlbGVhc2UpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKworICBzdHJpbmcqIHMgPSBuZXcgc3RyaW5nKCJ0ZXN0IHN0cmluZyIpOworICBtZXNzYWdlLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9zdHJpbmcocyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgidGVzdCBzdHJpbmciLCBtZXNzYWdlLT5vcHRpb25hbF9zdHJpbmcoKSk7CisgIHMgPSBtZXNzYWdlLT51bnNhZmVfYXJlbmFfcmVsZWFzZV9vcHRpb25hbF9zdHJpbmcoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIGRlbGV0ZSBzOworCisgIHMgPSBuZXcgc3RyaW5nKCJ0ZXN0IHN0cmluZyIpOworICBtZXNzYWdlLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vbmVvZl9zdHJpbmcocyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vbmVvZl9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgidGVzdCBzdHJpbmciLCBtZXNzYWdlLT5vbmVvZl9zdHJpbmcoKSk7CisgIHMgPSBtZXNzYWdlLT51bnNhZmVfYXJlbmFfcmVsZWFzZV9vbmVvZl9zdHJpbmcoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPmhhc19vbmVvZl9zdHJpbmcoKSk7CisgIGRlbGV0ZSBzOworfQorCitURVNUKEFyZW5hVGVzdCwgQXJlbmFPbmVvZlJlZmxlY3Rpb24pIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHN0cmluZ19maWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJvbmVvZl9zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtc2dfZmllbGQgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAib25lb2ZfbmVzdGVkX21lc3NhZ2UiKTsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGRlc2MtPkZpbmRPbmVvZkJ5TmFtZSgKKyAgICAgICJvbmVvZl9maWVsZCIpOworCisgIHJlZmwtPlNldFN0cmluZyhtZXNzYWdlLCBzdHJpbmdfZmllbGQsICJUZXN0IHZhbHVlIik7CisgIEVYUEVDVF9UUlVFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICByZWZsLT5DbGVhck9uZW9mKG1lc3NhZ2UsIG9uZW9mKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworCisgIE1lc3NhZ2UqIHN1Ym1zZyA9IHJlZmwtPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIG1zZ19maWVsZCk7CisgIEVYUEVDVF9UUlVFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICByZWZsLT5DbGVhck9uZW9mKG1lc3NhZ2UsIG9uZW9mKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICByZWZsLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBtc2dfZmllbGQpOworICBFWFBFQ1RfVFJVRShyZWZsLT5IYXNPbmVvZigqbWVzc2FnZSwgb25lb2YpKTsKKyAgc3VibXNnID0gcmVmbC0+UmVsZWFzZU1lc3NhZ2UobWVzc2FnZSwgbXNnX2ZpZWxkKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICBFWFBFQ1RfVFJVRShzdWJtc2ctPkdldEFyZW5hKCkgPT0gTlVMTCk7CisgIGRlbGV0ZSBzdWJtc2c7Cit9CisKK25hbWVzcGFjZSB7Cit2b2lkIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZChBcmVuYSogYXJlbmExLCBBcmVuYSogYXJlbmEyKSB7CisgIC8vIFRlc3QgInNhZmUiIChjb3B5aW5nKSBzZW1hbnRpY3MgZm9yIGRpcmVjdCBTd2FwKCkgb24gUmVwZWF0ZWRQdHJGaWVsZAorICAvLyBiZXR3ZWVuIGFyZW5hcy4KKyAgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+IGZpZWxkMShhcmVuYTEpOworICBSZXBlYXRlZFB0ckZpZWxkPFRlc3RBbGxUeXBlcz4gZmllbGQyKGFyZW5hMik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIFRlc3RBbGxUeXBlcyogdCA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oYXJlbmExKTsKKyAgICB0LT5zZXRfb3B0aW9uYWxfc3RyaW5nKCJmaWVsZDEiKTsKKyAgICB0LT5zZXRfb3B0aW9uYWxfaW50MzIoaSk7CisgICAgaWYgKGFyZW5hMSAhPSBOVUxMKSB7CisgICAgICBmaWVsZDEuVW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQodCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGZpZWxkMS5BZGRBbGxvY2F0ZWQodCk7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgVGVzdEFsbFR5cGVzKiB0ID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPihhcmVuYTIpOworICAgIHQtPnNldF9vcHRpb25hbF9zdHJpbmcoImZpZWxkMiIpOworICAgIHQtPnNldF9vcHRpb25hbF9pbnQzMihpKTsKKyAgICBpZiAoYXJlbmEyICE9IE5VTEwpIHsKKyAgICAgIGZpZWxkMi5VbnNhZmVBcmVuYUFkZEFsbG9jYXRlZCh0KTsKKyAgICB9IGVsc2UgeworICAgICAgZmllbGQyLkFkZEFsbG9jYXRlZCh0KTsKKyAgICB9CisgIH0KKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisgIEVYUEVDVF9FUSg1LCBmaWVsZDEuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBmaWVsZDIuc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUoc3RyaW5nKCJmaWVsZDEiKSA9PSBmaWVsZDIuR2V0KDApLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX1RSVUUoc3RyaW5nKCJmaWVsZDIiKSA9PSBmaWVsZDEuR2V0KDApLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgLy8gRW5zdXJlIHRoYXQgZmllbGRzIHJldGFpbmVkIHRoZWlyIG9yaWdpbmFsIG9yZGVyOgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkMS5zaXplKCk7IGkrKykgeworICAgIEVYUEVDVF9FUShpLCBmaWVsZDEuR2V0KGkpLm9wdGlvbmFsX2ludDMyKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGQyLnNpemUoKTsgaSsrKSB7CisgICAgRVhQRUNUX0VRKGksIGZpZWxkMi5HZXQoaSkub3B0aW9uYWxfaW50MzIoKSk7CisgIH0KK30KK30gIC8vIG5hbWVzcGFjZQorCitURVNUKEFyZW5hVGVzdCwgU3dhcFJlcGVhdGVkRmllbGQpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZCgmYXJlbmEsICZhcmVuYSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTd2FwUmVwZWF0ZWRGaWVsZFdpdGhEaWZmZXJlbnRBcmVuYXMpIHsKKyAgQXJlbmEgYXJlbmExOworICBBcmVuYSBhcmVuYTI7CisgIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZCgmYXJlbmExLCAmYXJlbmEyKTsKK30KKworVEVTVChBcmVuYVRlc3QsIFN3YXBSZXBlYXRlZEZpZWxkV2l0aE5vQXJlbmFPblJpZ2h0SGFuZFNpZGUpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZCgmYXJlbmEsIE5VTEwpOworfQorCitURVNUKEFyZW5hVGVzdCwgU3dhcFJlcGVhdGVkRmllbGRXaXRoTm9BcmVuYU9uTGVmdEhhbmRTaWRlKSB7CisgIEFyZW5hIGFyZW5hOworICBUZXN0U3dhcFJlcGVhdGVkRmllbGQoTlVMTCwgJmFyZW5hKTsKK30KKworVEVTVChBcmVuYVRlc3QsIEV4dGVuc2lvbnNPbkFyZW5hKSB7CisgIEFyZW5hIGFyZW5hOworICAvLyBFbnN1cmUgbm8gbGVha3MuCisgIFRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlX2V4dCA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hKTsKKyAgbWVzc2FnZV9leHQtPlNldEV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sIDQyKTsKKyAgbWVzc2FnZV9leHQtPlNldEV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uLCBzdHJpbmcoInRlc3QiKSk7CisgIG1lc3NhZ2VfZXh0LT5NdXRhYmxlRXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9iYig0Mik7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBSZXBlYXRlZEZpZWxkT25BcmVuYSkgeworICAvLyBQcmVhbGxvY2F0ZSBhbiBpbml0aWFsIGFyZW5hIGJsb2NrIHRvIGF2b2lkIG1hbGxvY3MgZHVyaW5nIGhvb2tlZCByZWdpb24uCisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEwMjQgKiAxMDI0KTsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hKG9wdGlvbnMpOworCisgIHsKKyAgICBpbnRlcm5hbDo6Tm9IZWFwQ2hlY2tlciBub19oZWFwOworCisgICAgLy8gRmlsbCBzb21lIHJlcGVhdGVkIGZpZWxkcyBvbiB0aGUgYXJlbmEgdG8gdGVzdCBmb3IgbGVha3MuIEFsc28gdmVyaWZ5IG5vCisgICAgLy8gbWVtb3J5IGFsbG9jYXRpb25zLgorICAgIFJlcGVhdGVkRmllbGQ8aW50MzI+IHJlcGVhdGVkX2ludDMyKCZhcmVuYSk7CisgICAgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+IHJlcGVhdGVkX21lc3NhZ2UoJmFyZW5hKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICByZXBlYXRlZF9pbnQzMi5BZGQoNDIpOworICAgICAgcmVwZWF0ZWRfbWVzc2FnZS5BZGQoKS0+c2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgICAgIEVYUEVDVF9FUSgmYXJlbmEsIHJlcGVhdGVkX21lc3NhZ2UuR2V0KDApLkdldEFyZW5hKCkpOworICAgICAgY29uc3QgVGVzdEFsbFR5cGVzKiBtc2dfaW5fcmVwZWF0ZWRfZmllbGQgPSAmcmVwZWF0ZWRfbWVzc2FnZS5HZXQoMCk7CisgICAgICBUZXN0QWxsVHlwZXMqIG1zZyA9IHJlcGVhdGVkX21lc3NhZ2UuVW5zYWZlQXJlbmFSZWxlYXNlTGFzdCgpOworICAgICAgRVhQRUNUX0VRKG1zZ19pbl9yZXBlYXRlZF9maWVsZCwgbXNnKTsKKyAgICB9CisKKyAgICAvLyBVbnNhZmVBcmVuYUV4dHJhY3RTdWJyYW5nZSAoaSkgc2hvdWxkIG5vdCBsZWFrIGFuZCAoaWkpIHNob3VsZCByZXR1cm4KKyAgICAvLyBvbi1hcmVuYSBwb2ludGVycy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIHJlcGVhdGVkX21lc3NhZ2UuQWRkKCktPnNldF9vcHRpb25hbF9pbnQzMig0Mik7CisgICAgfQorICAgIFRlc3RBbGxUeXBlcyogZXh0cmFjdGVkX21lc3NhZ2VzWzVdOworICAgIHJlcGVhdGVkX21lc3NhZ2UuVW5zYWZlQXJlbmFFeHRyYWN0U3VicmFuZ2UoMCwgNSwgZXh0cmFjdGVkX21lc3NhZ2VzKTsKKyAgICBFWFBFQ1RfRVEoJmFyZW5hLCByZXBlYXRlZF9tZXNzYWdlLkdldCgwKS5HZXRBcmVuYSgpKTsKKyAgICBFWFBFQ1RfRVEoNSwgcmVwZWF0ZWRfbWVzc2FnZS5zaXplKCkpOworICB9CisKKyAgLy8gTm93LCBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGUgTm9IZWFwQ2hlY2tlciwgdGVzdCBFeHRyYWN0U3VicmFuZ2UncyBjb3B5aW5nCisgIC8vIHNlbWFudGljcy4KKyAgeworICAgIFJlcGVhdGVkUHRyRmllbGQ8VGVzdEFsbFR5cGVzPiByZXBlYXRlZF9tZXNzYWdlKCZhcmVuYSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgcmVwZWF0ZWRfbWVzc2FnZS5BZGQoKS0+c2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgICB9CisKKyAgICBUZXN0QWxsVHlwZXMqIGV4dHJhY3RlZF9tZXNzYWdlc1s1XTsKKyAgICAvLyBFeHRyYWN0U3VicmFuZ2Ugc2hvdWxkIGNvcHkgdG8gdGhlIGhlYXAuCisgICAgcmVwZWF0ZWRfbWVzc2FnZS5FeHRyYWN0U3VicmFuZ2UoMCwgNSwgZXh0cmFjdGVkX21lc3NhZ2VzKTsKKyAgICBFWFBFQ1RfRVEoTlVMTCwgZXh0cmFjdGVkX21lc3NhZ2VzWzBdLT5HZXRBcmVuYSgpKTsKKyAgICAvLyBXZSBuZWVkIHRvIGZyZWUgdGhlIGhlYXAtYWxsb2NhdGVkIG1lc3NhZ2VzIHRvIHByZXZlbnQgYSBsZWFrLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgICBkZWxldGUgZXh0cmFjdGVkX21lc3NhZ2VzW2ldOworICAgICAgZXh0cmFjdGVkX21lc3NhZ2VzW2ldID0gTlVMTDsKKyAgICB9CisgIH0KKworICAvLyBOb3cgY2hlY2sgdGhhdCB3ZSBjYW4gY3JlYXRlIFJlcGVhdGVkRmllbGRzL1JlcGVhdGVkUHRyRmllbGRzIHRoZW1zZWx2ZXMgb24KKyAgLy8gdGhlIGFyZW5hLiBUaGV5IGhhdmUgdGhlIG5lY2Vzc2FyeSB0eXBlIHRyYWl0cyBzbyB0aGF0IHRoZXkgY2FuIGJlaGF2ZSBsaWtlCisgIC8vIG1lc3NhZ2VzIGluIHRoaXMgd2F5LiBUaGlzIGlzIHVzZWZ1bCBmb3IgaGlnaGVyLWxldmVsIGdlbmVyaWMgdGVtcGxhdGVkCisgIC8vIGNvZGUgdGhhdCBtYXkgYWxsb2NhdGUgbWVzc2FnZXMgb3IgcmVwZWF0ZWQgZmllbGRzIG9mIG1lc3NhZ2VzIG9uIGFuIGFyZW5hLgorICB7CisgICAgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+KiByZXBlYXRlZF9wdHJfb25fYXJlbmEgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+ID4oJmFyZW5hKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIC8vIEFkZCBzb21lIGVsZW1lbnRzIGFuZCBsZXQgdGhlIGxlYWstY2hlY2tlciBlbnN1cmUgdGhhdCBldmVyeXRoaW5nIGlzCisgICAgICAvLyBmcmVlZC4KKyAgICAgIHJlcGVhdGVkX3B0cl9vbl9hcmVuYS0+QWRkKCk7CisgICAgfQorCisgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+KiByZXBlYXRlZF9pbnRfb25fYXJlbmEgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgUmVwZWF0ZWRGaWVsZDxpbnQ+ID4oJmFyZW5hKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICByZXBlYXRlZF9pbnRfb25fYXJlbmEtPkFkZChpKTsKKyAgICB9CisKKyAgfQorCisgIGFyZW5hLlJlc2V0KCk7Cit9CisKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fUlRUSQorVEVTVChBcmVuYVRlc3QsIE11dGFibGVNZXNzYWdlUmVmbGVjdGlvbikgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIHN1Ym1lc3NhZ2UgPQorICAgICAgc3RhdGljX2Nhc3Q8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKj4oCisgICAgICAgICAgci0+TXV0YWJsZU1lc3NhZ2UobWVzc2FnZSwgZmllbGQpKTsKKyAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBzdWJtZXNzYWdlX2V4cGVjdGVkID0KKyAgICAgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKworICBFWFBFQ1RfRVEoc3VibWVzc2FnZV9leHBlY3RlZCwgc3VibWVzc2FnZSk7CisgIEVYUEVDVF9FUSgmYXJlbmEsIHN1Ym1lc3NhZ2UtPkdldEFyZW5hKCkpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb25lb2ZfZmllbGQgPSBkLT5GaW5kRmllbGRCeU5hbWUoIm9uZW9mX25lc3RlZF9tZXNzYWdlIik7CisgIHN1Ym1lc3NhZ2UgPSBzdGF0aWNfY2FzdDxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqPigKKyAgICAgIHItPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIG9uZW9mX2ZpZWxkKSk7CisgIHN1Ym1lc3NhZ2VfZXhwZWN0ZWQgPSBtZXNzYWdlLT5tdXRhYmxlX29uZW9mX25lc3RlZF9tZXNzYWdlKCk7CisKKyAgRVhQRUNUX0VRKHN1Ym1lc3NhZ2VfZXhwZWN0ZWQsIHN1Ym1lc3NhZ2UpOworICBFWFBFQ1RfRVEoJmFyZW5hLCBzdWJtZXNzYWdlLT5HZXRBcmVuYSgpKTsKK30KKyNlbmRpZiAgLy8gIUdPT0dMRV9QUk9UT0JVRl9OT19SVFRJCisKKworbmFtZXNwYWNlIHsKKwordm9pZCBGaWxsQXJlbmFBd2FyZUZpZWxkcyhUZXN0QWxsVHlwZXMqIG1lc3NhZ2UpIHsKKyAgc3RyaW5nIHRlc3Rfc3RyaW5nID0gImhlbGxvIHdvcmxkIjsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3N0cmluZyh0ZXN0X3N0cmluZyk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9ieXRlcyh0ZXN0X3N0cmluZyk7CisgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKworICBtZXNzYWdlLT5zZXRfb25lb2ZfdWludDMyKDQyKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBtZXNzYWdlLT5zZXRfb25lb2Zfc3RyaW5nKHRlc3Rfc3RyaW5nKTsKKyAgbWVzc2FnZS0+c2V0X29uZW9mX2J5dGVzKHRlc3Rfc3RyaW5nKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50MzIoNDIpOworICAvLyBObyByZXBlYXRlZCBzdHJpbmc6IG5vdCB5ZXQgYXJlbmEtYXdhcmUuCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworfQorCit9CisKKy8vIFRlc3Q6IG5vIGFsbG9jYXRpb25zIG9jY3VyIG9uIGhlYXAgd2hpbGUgdG91Y2hpbmcgYWxsIHN1cHBvcnRlZCBmaWVsZCB0eXBlcy4KK1RFU1QoQXJlbmFUZXN0LCBOb0hlYXBBbGxvY2F0aW9uc1Rlc3QpIHsKKyAgLy8gQWxsb2NhdGUgYSBsYXJnZSBpbml0aWFsIGJsb2NrIHRvIGF2b2lkIG1hbGxvY3MgZHVyaW5nIGhvb2tlZCB0ZXN0LgorICBzdGQ6OnZlY3RvcjxjaGFyPiBhcmVuYV9ibG9jaygxMjggKiAxMDI0KTsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hKG9wdGlvbnMpOworCisgIHsKKworICAgIFRlc3RBbGxUeXBlcyogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgICBGaWxsQXJlbmFBd2FyZUZpZWxkcyhtZXNzYWdlKTsKKyAgfQorCisgIGFyZW5hLlJlc2V0KCk7Cit9CisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKy8vIFRlc3QgY29uc3RydWN0aW9uIG9uIGFuIGFyZW5hIHZpYSBnZW5lcmljIE1lc3NhZ2VMaXRlIGludGVyZmFjZS4gV2Ugc2hvdWxkIGJlCisvLyBhYmxlIHRvIHN1Y2Nlc3NmdWxseSBkZXNlcmlhbGl6ZSBvbiB0aGUgYXJlbmEgd2l0aG91dCBpbmN1cnJpbmcgaGVhcAorLy8gYWxsb2NhdGlvbnMsIGkuZS4sIGV2ZXJ5dGhpbmcgc2hvdWxkIHN0aWxsIGJlIGFyZW5hLWFsbG9jYXRpb24tYXdhcmUuCitURVNUKEFyZW5hVGVzdCwgTWVzc2FnZUxpdGVPbkFyZW5hKSB7CisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEyOCAqIDEwMjQpOworICBBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gJmFyZW5hX2Jsb2NrWzBdOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgQXJlbmEgYXJlbmEob3B0aW9ucyk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VMaXRlKiBwcm90b3R5cGUgPSAmVGVzdEFsbFR5cGVzOjpkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgVGVzdEFsbFR5cGVzIGluaXRpYWxfbWVzc2FnZTsKKyAgRmlsbEFyZW5hQXdhcmVGaWVsZHMoJmluaXRpYWxfbWVzc2FnZSk7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBpbml0aWFsX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworCisgIHsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VMaXRlKiBnZW5lcmljX21lc3NhZ2UgPSBwcm90b3R5cGUtPk5ldygmYXJlbmEpOworICAgIEVYUEVDVF9UUlVFKGdlbmVyaWNfbWVzc2FnZSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoJmFyZW5hLCBnZW5lcmljX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICAgIEVYUEVDVF9UUlVFKGdlbmVyaWNfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgICBUZXN0QWxsVHlwZXMqIGRlc2VyaWFsaXplZCA9IHN0YXRpY19jYXN0PFRlc3RBbGxUeXBlcyo+KGdlbmVyaWNfbWVzc2FnZSk7CisgICAgRVhQRUNUX0VRKDQyLCBkZXNlcmlhbGl6ZWQtPm9wdGlvbmFsX2ludDMyKCkpOworICB9CisKKyAgYXJlbmEuUmVzZXQoKTsKK30KKyNlbmRpZiAgLy8gIUdPT0dMRV9QUk9UT0JVRl9OT19SVFRJCisKKworLy8gUmVwZWF0ZWRGaWVsZCBzaG91bGQgc3VwcG9ydCBub24tUE9EIHR5cGVzLCBhbmQgaW52b2tlIGNvbnN0cnVjdG9ycyBhbmQKKy8vIGRlc3RydWN0b3JzIGFwcHJvcHJpYXRlbHksIGJlY2F1c2UgaXQncyB1c2VkIHRoaXMgd2F5IGJ5IGxvdHMgb2Ygb3RoZXIgY29kZQorLy8gKGV2ZW4gaWYgdGhpcyB3YXMgbm90IGl0cyBvcmlnaW5hbCBpbnRlbnQpLgorVEVTVChBcmVuYVRlc3QsIFJlcGVhdGVkRmllbGRXaXRoTm9uUE9EVHlwZSkgeworICB7CisgICAgUmVwZWF0ZWRGaWVsZDxzdHJpbmc+IGZpZWxkX29uX2hlYXA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgKmZpZWxkX29uX2hlYXAuQWRkKCkgPSAidGVzdCBzdHJpbmcgbG9uZyBlbm91Z2ggdG8gZXhjZWVkIGlubGluZSBidWZmZXIiOworICAgIH0KKyAgfQorICB7CisgICAgQXJlbmEgYXJlbmE7CisgICAgUmVwZWF0ZWRGaWVsZDxzdHJpbmc+IGZpZWxkX29uX2FyZW5hKCZhcmVuYSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgKmZpZWxkX29uX2FyZW5hLkFkZCgpID0gInRlc3Qgc3RyaW5nIGxvbmcgZW5vdWdoIHRvIGV4Y2VlZCBpbmxpbmUgYnVmZmVyIjsKKyAgICB9CisgIH0KK30KKworLy8gQWxpZ24gbiB0byBuZXh0IG11bHRpcGxlIG9mIDgKK25hbWVzcGFjZSB7Cit1aW50NjQgQWxpZ244KHVpbnQ2NCBuKSB7IHJldHVybiAobiArIDcpICYgLTg7IH0KK30gIC8vIG5hbWVzcGFjZQorCitURVNUKEFyZW5hVGVzdCwgU3BhY2VBbGxvY2F0ZWRfYW5kX1VzZWQpIHsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuc3RhcnRfYmxvY2tfc2l6ZSA9IDI1NjsKKyAgb3B0aW9ucy5tYXhfYmxvY2tfc2l6ZSA9IDgxOTI7CisgIEFyZW5hIGFyZW5hXzEob3B0aW9ucyk7CisgIEVYUEVDVF9FUSgwLCBhcmVuYV8xLlNwYWNlQWxsb2NhdGVkKCkpOworICBFWFBFQ1RfRVEoMCwgYXJlbmFfMS5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUSgwLCBhcmVuYV8xLlJlc2V0KCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmFfMSwgMzIwKTsKKyAgLy8gQXJlbmEgd2lsbCBhbGxvY2F0ZSBzbGlnaHRseSBtb3JlIHRoYW4gMzIwIGZvciB0aGUgYmxvY2sgaGVhZGVycy4KKyAgRVhQRUNUX0xFKDMyMCwgYXJlbmFfMS5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCgzMjApLCBhcmVuYV8xLlNwYWNlVXNlZCgpKTsKKyAgRVhQRUNUX0xFKDMyMCwgYXJlbmFfMS5SZXNldCgpKTsKKworICAvLyBUZXN0IHdpdGggaW5pdGlhbCBibG9jay4KKyAgc3RkOjp2ZWN0b3I8Y2hhcj4gYXJlbmFfYmxvY2soMTAyNCk7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hXzIob3B0aW9ucyk7CisgIEVYUEVDVF9FUSgxMDI0LCBhcmVuYV8yLlNwYWNlQWxsb2NhdGVkKCkpOworICBFWFBFQ1RfRVEoMCwgYXJlbmFfMi5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUSgxMDI0LCBhcmVuYV8yLlJlc2V0KCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmFfMiwgNTUpOworICBFWFBFQ1RfRVEoMTAyNCwgYXJlbmFfMi5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCg1NSksIGFyZW5hXzIuU3BhY2VVc2VkKCkpOworICBFWFBFQ1RfRVEoMTAyNCwgYXJlbmFfMi5SZXNldCgpKTsKKworICAvLyBSZXNldCBvcHRpb25zIHRvIHRlc3QgZG91YmxpbmcgcG9saWN5IGV4cGxpY2l0bHkuCisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9IE5VTEw7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9ja19zaXplID0gMDsKKyAgQXJlbmEgYXJlbmFfMyhvcHRpb25zKTsKKyAgRVhQRUNUX0VRKDAsIGFyZW5hXzMuU3BhY2VVc2VkKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmFfMywgMTkwKTsKKyAgRVhQRUNUX0VRKDI1NiwgYXJlbmFfMy5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCgxOTApLCBhcmVuYV8zLlNwYWNlVXNlZCgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlQXJyYXk8Y2hhcj4oJmFyZW5hXzMsIDcwKTsKKyAgRVhQRUNUX0VRKDI1NiArIDUxMiwgYXJlbmFfMy5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCgxOTApICsgQWxpZ244KDcwKSwgYXJlbmFfMy5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUSgyNTYgKyA1MTIsIGFyZW5hXzMuUmVzZXQoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBBbGlnbm1lbnQpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDA7IGkrKykgeworICAgIHZvaWQqIHAgPSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmEsIGkpOworICAgIEdPT0dMRV9DSEVDS19FUShyZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4ocCkgJSA4LCAwKSA8PCBpIDw8ICI6ICIgPDwgcDsKKyAgfQorfQorCitURVNUKEFyZW5hVGVzdCwgR2V0QXJlbmFTaG91bGRSZXR1cm5UaGVBcmVuYUZvckFyZW5hQWxsb2NhdGVkTWVzc2FnZXMpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTsKKyAgQXJlbmFNZXNzYWdlKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8QXJlbmFNZXNzYWdlPigmYXJlbmEpOworICBjb25zdCBBcmVuYU1lc3NhZ2UqIGNvbnN0X3BvaW50ZXJfdG9fbWVzc2FnZSA9IG1lc3NhZ2U7CisgIEVYUEVDVF9FUSgmYXJlbmEsIEFyZW5hOjpHZXRBcmVuYShtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgmYXJlbmEsIEFyZW5hOjpHZXRBcmVuYShjb25zdF9wb2ludGVyX3RvX21lc3NhZ2UpKTsKK30KKworVEVTVChBcmVuYVRlc3QsIEdldEFyZW5hU2hvdWxkUmV0dXJuTnVsbEZvck5vbkFyZW5hQWxsb2NhdGVkTWVzc2FnZXMpIHsKKyAgQXJlbmFNZXNzYWdlIG1lc3NhZ2U7CisgIGNvbnN0IEFyZW5hTWVzc2FnZSogY29uc3RfcG9pbnRlcl90b19tZXNzYWdlID0gJm1lc3NhZ2U7CisgIEVYUEVDVF9FUShOVUxMLCBBcmVuYTo6R2V0QXJlbmEoJm1lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKE5VTEwsIEFyZW5hOjpHZXRBcmVuYShjb25zdF9wb2ludGVyX3RvX21lc3NhZ2UpKTsKK30KKworLy8gQSBoZWxwZXIgdXRpbGl0eSBjbGFzcyB0byBvbmx5IGNvbnRhaW4gc3RhdGljIGhvb2sgZnVuY3Rpb25zLCBzb21lCisvLyBjb3VudGVycyB0byBiZSB1c2VkIHRvIHZlcmlmeSB0aGUgY291bnRlcnMgaGF2ZSBiZWVuIGNhbGxlZCBhbmQgYSBjb29raWUKKy8vIHZhbHVlIHRvIGJlIHZlcmlmaWVkLgorY2xhc3MgQXJlbmFIb29rc1Rlc3RVdGlsIHsKKyBwdWJsaWM6CisgIHN0YXRpYyB2b2lkKiBvbl9pbml0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgKytudW1faW5pdDsKKyAgICBpbnQqIGNvb2tpZSA9IG5ldyBpbnQoa0Nvb2tpZVZhbHVlKTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8dm9pZCo+KGNvb2tpZSk7CisgIH0KKworICBzdGF0aWMgdm9pZCBvbl9yZXNldCg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwgdm9pZCogY29va2llLAorICAgICAgICAgICAgICAgICAgICAgICB1aW50NjQgc3BhY2VfdXNlZCkgeworICAgICsrbnVtX3Jlc2V0OworICAgIGludCBjb29raWVfdmFsdWUgPSAqc3RhdGljX2Nhc3Q8aW50Kj4oY29va2llKTsKKyAgICBFWFBFQ1RfRVEoa0Nvb2tpZVZhbHVlLCBjb29raWVfdmFsdWUpOworICB9CisKKyAgc3RhdGljIHZvaWQgb25fZGVzdHJ1Y3Rpb24oOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsIHZvaWQqIGNvb2tpZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0IHNwYWNlX3VzZWQpIHsKKyAgICArK251bV9kZXN0cnVjdDsKKyAgICBpbnQgY29va2llX3ZhbHVlID0gKnN0YXRpY19jYXN0PGludCo+KGNvb2tpZSk7CisgICAgRVhQRUNUX0VRKGtDb29raWVWYWx1ZSwgY29va2llX3ZhbHVlKTsKKyAgICBkZWxldGUgc3RhdGljX2Nhc3Q8aW50Kj4oY29va2llKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCBpbnQga0Nvb2tpZVZhbHVlID0gOTk5OworICBzdGF0aWMgdWludDMyIG51bV9pbml0OworICBzdGF0aWMgdWludDMyIG51bV9yZXNldDsKKyAgc3RhdGljIHVpbnQzMiBudW1fZGVzdHJ1Y3Q7Cit9OwordWludDMyIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2luaXQgPSAwOwordWludDMyIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX3Jlc2V0ID0gMDsKK3VpbnQzMiBBcmVuYUhvb2tzVGVzdFV0aWw6Om51bV9kZXN0cnVjdCA9IDA7Citjb25zdCBpbnQgQXJlbmFIb29rc1Rlc3RVdGlsOjprQ29va2llVmFsdWU7CisKKy8vIFRlc3QgdGhlIGhvb2tzIGFyZSBjb3JyZWN0bHkgY2FsbGVkIGFuZCB0aGF0IHRoZSBjb29raWUgaXMgcGFzc2VkLgorVEVTVChBcmVuYVRlc3QsIEFyZW5hSG9va3NTYW5pdHkpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5vbl9hcmVuYV9pbml0ID0gQXJlbmFIb29rc1Rlc3RVdGlsOjpvbl9pbml0OworICBvcHRpb25zLm9uX2FyZW5hX3Jlc2V0ID0gQXJlbmFIb29rc1Rlc3RVdGlsOjpvbl9yZXNldDsKKyAgb3B0aW9ucy5vbl9hcmVuYV9kZXN0cnVjdGlvbiA9IEFyZW5hSG9va3NUZXN0VXRpbDo6b25fZGVzdHJ1Y3Rpb247CisKKyAgLy8gU2NvcGUgZm9yIGRlZmluaW5nIHRoZSBhcmVuYQorICB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYShvcHRpb25zKTsKKyAgICBFWFBFQ1RfRVEoMSwgQXJlbmFIb29rc1Rlc3RVdGlsOjpudW1faW5pdCk7CisKKyAgICBhcmVuYS5SZXNldCgpOworICAgIGFyZW5hLlJlc2V0KCk7CisgICAgRVhQRUNUX0VRKDIsIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX3Jlc2V0KTsKKyAgfQorICBFWFBFQ1RfRVEoMywgQXJlbmFIb29rc1Rlc3RVdGlsOjpudW1fcmVzZXQpOworICBFWFBFQ1RfRVEoMSwgQXJlbmFIb29rc1Rlc3RVdGlsOjpudW1fZGVzdHJ1Y3QpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjZTYxZDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmNjCkBAIC0wLDAgKzEsNTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGUgQXJlbmFTdHJpbmcgaW1wbGVtZW50YXRpb24gaXMgbm90IGluY2x1ZGVkIGluIHRoZSBvcGVuLXNvdXJjZSByZWxlYXNlLiBEbworLy8gbm90IGluY2x1ZGUgdGhpcyBmaWxlIGluIHRoZSBkaXN0cmlidXRpb24uCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworCit2b2lkIEFyZW5hU3RyaW5nUHRyOjpBc3NpZ25XaXRoRGVmYXVsdChjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmFTdHJpbmdQdHIgdmFsdWUpIHsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyogbWUgPSAqVW5zYWZlUmF3U3RyaW5nUG9pbnRlcigpOworICBjb25zdCA6OnN0ZDo6c3RyaW5nKiBvdGhlciA9ICp2YWx1ZS5VbnNhZmVSYXdTdHJpbmdQb2ludGVyKCk7CisgIC8vIElmIHRoZSBwb2ludGVycyBhcmUgdGhlIHNhbWUgdGhlbiBkbyBub3RoaW5nLgorICBpZiAobWUgIT0gb3RoZXIpIHsKKyAgICBTZXROb0FyZW5hKGRlZmF1bHRfdmFsdWUsIHZhbHVlLkdldE5vQXJlbmEoZGVmYXVsdF92YWx1ZSkpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmgKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZDgyOWVkOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaApAQCAtMCwwICsxLDMxNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FSRU5BU1RSSU5HX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJFTkFTVFJJTkdfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Zhc3RtZW0uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisKKworCisvLyBUaGlzIGlzIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBhcmVuYSBzdHJpbmcgZmllbGRzIHdyaXR0ZW4gZm9yIHRoZSBvcGVuLXNvdXJjZQorLy8gcmVsZWFzZS4gVGhlIEFyZW5hU3RyaW5nUHRyIHN0cnVjdCBiZWxvdyBpcyBhbiBpbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBjbGFzcworLy8gYW5kICpzaG91bGQgbm90IGJlIHVzZWQqIGJ5IHVzZXIgY29kZS4gSXQgaXMgdXNlZCB0byBjb2xsZWN0IHN0cmluZworLy8gb3BlcmF0aW9ucyB0b2dldGhlciBpbnRvIG9uZSBwbGFjZSBhbmQgYWJzdHJhY3QgYXdheSB0aGUgdW5kZXJseWluZworLy8gc3RyaW5nLWZpZWxkIHBvaW50ZXIgcmVwcmVzZW50YXRpb24sIHNvIHRoYXQgKGZvciBleGFtcGxlKSBhbiBhbHRlcm5hdGUKKy8vIGltcGxlbWVudGF0aW9uIHRoYXQga25ldyBtb3JlIGFib3V0IDo6c3RkOjpzdHJpbmcncyBpbnRlcm5hbHMgY291bGQgaW50ZWdyYXRlIG1vcmUKKy8vIGNsb3NlbHkgd2l0aCB0aGUgYXJlbmEgYWxsb2NhdG9yLgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitzdHJ1Y3QgTElCUFJPVE9CVUZfRVhQT1JUIEFyZW5hU3RyaW5nUHRyIHsKKyAgaW5saW5lIHZvaWQgU2V0KGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSwgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBDcmVhdGVJbnN0YW5jZShhcmVuYSwgJnZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgKnB0cl8gPSB2YWx1ZTsKKyAgICB9CisgIH0KKworICAvLyBCYXNpYyBhY2Nlc3NvcnMuCisgIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBHZXQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSkgY29uc3QgeworICAgIHJldHVybiAqcHRyXzsKKyAgfQorCisgIGlubGluZSA6OnN0ZDo6c3RyaW5nKiBNdXRhYmxlKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICAgIGlmIChwdHJfID09IGRlZmF1bHRfdmFsdWUpIHsKKyAgICAgIENyZWF0ZUluc3RhbmNlKGFyZW5hLCBkZWZhdWx0X3ZhbHVlKTsKKyAgICB9CisgICAgcmV0dXJuIHB0cl87CisgIH0KKworICAvLyBSZWxlYXNlIHJldHVybnMgYSA6OnN0ZDo6c3RyaW5nKiBpbnN0YW5jZSB0aGF0IGlzIGhlYXAtYWxsb2NhdGVkIGFuZCBpcyBub3QKKyAgLy8gT3duKCknZCBieSBhbnkgYXJlbmEuIElmIHRoZSBmaWVsZCB3YXMgbm90IHNldCwgaXQgcmV0dXJucyBOVUxMLiBUaGUgY2FsbGVyCisgIC8vIHJldGFpbnMgb3duZXJzaGlwLiBDbGVhcnMgdGhpcyBmaWVsZCBiYWNrIHRvIE5VTEwgc3RhdGUuIFVzZWQgdG8gaW1wbGVtZW50CisgIC8vIHJlbGVhc2VfPGZpZWxkPigpIG1ldGhvZHMgb24gZ2VuZXJhdGVkIGNsYXNzZXMuCisgIGlubGluZSA6OnN0ZDo6c3RyaW5nKiBSZWxlYXNlKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICAgIGlmIChwdHJfID09IGRlZmF1bHRfdmFsdWUpIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlZCA9IE5VTEw7CisgICAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICAgIC8vIHB0cl8gaXMgb3duZWQgYnkgdGhlIGFyZW5hIC0tIHdlIG5lZWQgdG8gcmV0dXJuIGEgY29weS4KKyAgICAgIHJlbGVhc2VkID0gbmV3IDo6c3RkOjpzdHJpbmcoKnB0cl8pOworICAgIH0gZWxzZSB7CisgICAgICByZWxlYXNlZCA9IHB0cl87CisgICAgfQorICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICAgIHJldHVybiByZWxlYXNlZDsKKyAgfQorCisgIC8vIFVuc2FmZUFyZW5hUmVsZWFzZSByZXR1cm5zIGEgOjpzdGQ6OnN0cmluZyosIGJ1dCBpdCBtYXkgYmUgYXJlbmEtb3duZWQgKGkuZS4KKyAgLy8gaGF2ZSBpdHMgZGVzdHJ1Y3RvciBhbHJlYWR5IHJlZ2lzdGVyZWQpIGlmIGFyZW5hICE9IE5VTEwuIElmIHRoZSBmaWVsZCB3YXMKKyAgLy8gbm90IHNldCwgdGhpcyByZXR1cm5zIE5VTEwuIFRoaXMgbWV0aG9kIGNsZWFycyB0aGlzIGZpZWxkIGJhY2sgdG8gTlVMTAorICAvLyBzdGF0ZS4gVXNlZCB0byBpbXBsZW1lbnQgdW5zYWZlX2FyZW5hX3JlbGVhc2VfPGZpZWxkPigpIG1ldGhvZHMgb24KKyAgLy8gZ2VuZXJhdGVkIGNsYXNzZXMuCisgIGlubGluZSA6OnN0ZDo6c3RyaW5nKiBVbnNhZmVBcmVuYVJlbGVhc2UoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZWQgPSBwdHJfOworICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICAgIHJldHVybiByZWxlYXNlZDsKKyAgfQorCisgIC8vIFRha2VzIGEgc3RyaW5nIHRoYXQgaXMgaGVhcC1hbGxvY2F0ZWQsIGFuZCB0YWtlcyBvd25lcnNoaXAuIFRoZSBzdHJpbmcncworICAvLyBkZXN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgYXJlbmEuIFVzZWQgdG8gaW1wbGVtZW50CisgIC8vIHNldF9hbGxvY2F0ZWRfPGZpZWxkPiBpbiBnZW5lcmF0ZWQgY2xhc3Nlcy4KKyAgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6c3RyaW5nKiB2YWx1ZSwgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCAmJiBwdHJfICE9IGRlZmF1bHRfdmFsdWUpIHsKKyAgICAgIERlc3Ryb3koZGVmYXVsdF92YWx1ZSwgYXJlbmEpOworICAgIH0KKyAgICBpZiAodmFsdWUgIT0gTlVMTCkgeworICAgICAgcHRyXyA9IHZhbHVlOworICAgICAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICAgICAgYXJlbmEtPk93bih2YWx1ZSk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICAgIH0KKyAgfQorCisgIC8vIFRha2VzIGEgc3RyaW5nIHRoYXQgaGFzIGxpZmV0aW1lIGVxdWFsIHRvIHRoZSBhcmVuYSdzIGxpZmV0aW1lLiBUaGUgYXJlbmEKKyAgLy8gbXVzdCBiZSBub24tbnVsbC4gSXQgaXMgc2FmZSBvbmx5IHRvIHBhc3MgdGhpcyBtZXRob2QgYSB2YWx1ZSByZXR1cm5lZCBieQorICAvLyBVbnNhZmVBcmVuYVJlbGVhc2UoKSBvbiBhbm90aGVyIGZpZWxkIG9mIGEgbWVzc2FnZSBpbiB0aGUgc2FtZSBhcmVuYS4gVXNlZAorICAvLyB0byBpbXBsZW1lbnQgdW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWRfPGZpZWxkPiBpbiBnZW5lcmF0ZWQgY2xhc3Nlcy4KKyAgaW5saW5lIHZvaWQgVW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpzdGQ6OnN0cmluZyogdmFsdWUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAgIHB0cl8gPSB2YWx1ZTsKKyAgICB9IGVsc2UgeworICAgICAgcHRyXyA9IGNvbnN0X2Nhc3Q8IDo6c3RkOjpzdHJpbmcqID4oZGVmYXVsdF92YWx1ZSk7CisgICAgfQorICB9CisKKyAgLy8gU3dhcHMgaW50ZXJuYWwgcG9pbnRlcnMuIEFyZW5hLXNhZmV0eSBzZW1hbnRpY3M6IHRoaXMgaXMgZ3VhcmRlZCBieSB0aGUKKyAgLy8gbG9naWMgaW4gU3dhcCgpL1Vuc2FmZUFyZW5hU3dhcCgpIGF0IHRoZSBtZXNzYWdlIGxldmVsLCBzbyB0aGlzIG1ldGhvZCBpcworICAvLyAndW5zYWZlJyBpZiBjYWxsZWQgZGlyZWN0bHkuCisgIGlubGluZSB2b2lkIFN3YXAoQXJlbmFTdHJpbmdQdHIqIG90aGVyKSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgeworICAgIHN0ZDo6c3dhcChwdHJfLCBvdGhlci0+cHRyXyk7CisgIH0KKworICAvLyBGcmVlcyBzdG9yYWdlIChpZiBub3Qgb24gYW4gYXJlbmEpIGFuZCBzZXRzIGZpZWxkIHRvIGRlZmF1bHQgdmFsdWUuCisgIGlubGluZSB2b2lkIERlc3Ryb3koY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICAgIGlmIChhcmVuYSA9PSBOVUxMICYmIHB0cl8gIT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgZGVsZXRlIHB0cl87CisgICAgfQorICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICB9CisKKyAgLy8gQ2xlYXJzIGNvbnRlbnQsIGJ1dCBrZWVwcyBhbGxvY2F0ZWQgc3RyaW5nIGlmIGFyZW5hICE9IE5VTEwsIHRvIGF2b2lkIHRoZQorICAvLyBvdmVyaGVhZCBvZiBoZWFwIG9wZXJhdGlvbnMuIEFmdGVyIHRoaXMgcmV0dXJucywgdGhlIGNvbnRlbnQgKGFzIHNlZW4gYnkKKyAgLy8gdGhlIHVzZXIpIHdpbGwgYWx3YXlzIGJlIHRoZSBlbXB0eSBzdHJpbmcuIEFzc3VtZXMgdGhhdCB8ZGVmYXVsdF92YWx1ZXwKKyAgLy8gaXMgYW4gZW1wdHkgc3RyaW5nLgorICBpbmxpbmUgdm9pZCBDbGVhclRvRW1wdHkoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKHB0cl8gPT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgLy8gQWxyZWFkeSBzZXQgdG8gZGVmYXVsdCAod2hpY2ggaXMgZW1wdHkpIC0tIGRvIG5vdGhpbmcuCisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8tPmNsZWFyKCk7CisgICAgfQorICB9CisKKyAgLy8gQ2xlYXJzIGNvbnRlbnQsIGJ1dCBrZWVwcyBhbGxvY2F0ZWQgc3RyaW5nIGlmIGFyZW5hICE9IE5VTEwsIHRvIGF2b2lkIHRoZQorICAvLyBvdmVyaGVhZCBvZiBoZWFwIG9wZXJhdGlvbnMuIEFmdGVyIHRoaXMgcmV0dXJucywgdGhlIGNvbnRlbnQgKGFzIHNlZW4gYnkKKyAgLy8gdGhlIHVzZXIpIHdpbGwgYWx3YXlzIGJlIGVxdWFsIHRvIHxkZWZhdWx0X3ZhbHVlfC4KKyAgaW5saW5lIHZvaWQgQ2xlYXJUb0RlZmF1bHQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICAvLyBBbHJlYWR5IHNldCB0byBkZWZhdWx0IC0tIGRvIG5vdGhpbmcuCisgICAgfSBlbHNlIHsKKyAgICAgIC8vIEhhdmUgYW5vdGhlciBhbGxvY2F0ZWQgc3RyaW5nIC0tIHJhdGhlciB0aGFuIHRocm93aW5nIHRoaXMgYXdheSBhbmQKKyAgICAgIC8vIHJlc2V0dGluZyBwdHJfIHRvIHRoZSBjYW5vbmljYWwgZGVmYXVsdCBzdHJpbmcgaW5zdGFuY2UsIHdlIGp1c3QgcmV1c2UKKyAgICAgIC8vIHRoaXMgaW5zdGFuY2UuCisgICAgICAqcHRyXyA9ICpkZWZhdWx0X3ZhbHVlOworICAgIH0KKyAgfQorCisgIC8vIENhbGxlZCBmcm9tIGdlbmVyYXRlZCBjb2RlIC8gcmVmbGVjdGlvbiBydW50aW1lIG9ubHkuIFJlc2V0cyB2YWx1ZSB0byBwb2ludAorICAvLyB0byBhIGRlZmF1bHQgc3RyaW5nIHBvaW50ZXIsIHdpdGggdGhlIHNlbWFudGljcyB0aGF0IHRoaXMgQXJlbmFTdHJpbmdQdHIKKyAgLy8gZG9lcyBub3Qgb3duIHRoZSBwb2ludGVkLXRvIG1lbW9yeS4gRGlzcmVnYXJkcyBpbml0aWFsIHZhbHVlIG9mIHB0cl8gKHNvCisgIC8vIHRoaXMgaXMgdGhlICpPTkxZKiBzYWZlIG1ldGhvZCB0byBjYWxsIGFmdGVyIGNvbnN0cnVjdGlvbiBvciB3aGVuCisgIC8vIHJlaW5pdGlhbGl6aW5nIGFmdGVyIGJlY29taW5nIHRoZSBhY3RpdmUgZmllbGQgaW4gYSBvbmVvZiB1bmlvbikuCisgIGlubGluZSB2b2lkIFVuc2FmZVNldERlZmF1bHQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSkgeworICAgIC8vIENhc3RpbmcgYXdheSAnY29uc3QnIGlzIHNhZmUgaGVyZTogYWNjZXNzb3JzIGVuc3VyZSB0aGF0IHB0cl8gaXMgb25seQorICAgIC8vIHJldHVybmVkIGFzIGEgY29uc3QgaWYgaXQgaXMgZXF1YWwgdG8gZGVmYXVsdF92YWx1ZS4KKyAgICBwdHJfID0gY29uc3RfY2FzdDwgOjpzdGQ6OnN0cmluZyogPihkZWZhdWx0X3ZhbHVlKTsKKyAgfQorCisgIC8vIFRoZSAnTm9BcmVuYScgdmFyaWFudHMgb2YgbWV0aG9kcyBiZWxvdyBhc3N1bWUgYXJlbmEgPT0gTlVMTCBhbmQgYXJlCisgIC8vIG9wdGltaXplZCB0byBwcm92aWRlIHZlcnkgbGl0dGxlIG92ZXJoZWFkIHJlbGF0aXZlIHRvIGEgcmF3IHN0cmluZyBwb2ludGVyCisgIC8vICh3aGlsZSBzdGlsbCBiZWluZyBpbi1tZW1vcnkgY29tcGF0aWJsZSB3aXRoIG90aGVyIGNvZGUgdGhhdCBhc3N1bWVzCisgIC8vIEFyZW5hU3RyaW5nUHRyKS4gTm90ZSB0aGUgaW52YXJpYW50IHRoYXQgYSBjbGFzcyBpbnN0YW5jZSB0aGF0IGhhcyBvbmx5CisgIC8vIGV2ZXIgYmVlbiBtdXRhdGVkIGJ5IE5vQXJlbmEgbWV0aG9kcyBtdXN0ICpvbmx5KiBiZSBpbiB0aGUgU3RyaW5nIHN0YXRlCisgIC8vIChpLmUuLCB0YWcgYml0cyBhcmUgbm90IHVzZWQpLCAqTkVWRVIqIEFyZW5hU3RyaW5nLiBUaGlzIGFsbG93cyBhbGwKKyAgLy8gdGFnZ2VkLXBvaW50ZXIgbWFuaXB1bGF0aW9ucyB0byBiZSBhdm9pZGVkLgorICBpbmxpbmUgdm9pZCBTZXROb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBDcmVhdGVJbnN0YW5jZU5vQXJlbmEoJnZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgKnB0cl8gPSB2YWx1ZTsKKyAgICB9CisgIH0KKworICB2b2lkIEFzc2lnbldpdGhEZWZhdWx0KGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsIEFyZW5hU3RyaW5nUHRyIHZhbHVlKTsKKworICBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgR2V0Tm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlKSBjb25zdCB7CisgICAgcmV0dXJuICpwdHJfOworICB9CisKKyAgaW5saW5lIDo6c3RkOjpzdHJpbmcqIE11dGFibGVOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBDcmVhdGVJbnN0YW5jZU5vQXJlbmEoZGVmYXVsdF92YWx1ZSk7CisgICAgfQorICAgIHJldHVybiBwdHJfOworICB9CisKKyAgaW5saW5lIDo6c3RkOjpzdHJpbmcqIFJlbGVhc2VOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9IGVsc2UgeworICAgICAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZWQgPSBwdHJfOworICAgICAgcHRyXyA9IGNvbnN0X2Nhc3Q8IDo6c3RkOjpzdHJpbmcqID4oZGVmYXVsdF92YWx1ZSk7CisgICAgICByZXR1cm4gcmVsZWFzZWQ7CisgICAgfQorICB9CisKKyAgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkTm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6c3RkOjpzdHJpbmcqIHZhbHVlKSB7CisgICAgaWYgKHB0cl8gIT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgZGVsZXRlIHB0cl87CisgICAgfQorICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgICBwdHJfID0gdmFsdWU7CisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICAgIH0KKyAgfQorCisgIGlubGluZSB2b2lkIERlc3Ryb3lOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyAhPSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBkZWxldGUgcHRyXzsKKyAgICB9CisgICAgcHRyXyA9IE5VTEw7CisgIH0KKworICBpbmxpbmUgdm9pZCBDbGVhclRvRW1wdHlOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICAvLyBOb3RoaW5nOiBhbHJlYWR5IGVxdWFsIHRvIGRlZmF1bHQgKHdoaWNoIGlzIHRoZSBlbXB0eSBzdHJpbmcpLgorICAgIH0gZWxzZSB7CisgICAgICBwdHJfLT5jbGVhcigpOworICAgIH0KKyAgfQorCisgIGlubGluZSB2b2lkIENsZWFyVG9EZWZhdWx0Tm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlKSB7CisgICAgaWYgKHB0cl8gPT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgLy8gTm90aGluZzogYWxyZWFkeSBzZXQgdG8gZGVmYXVsdC4KKyAgICB9IGVsc2UgeworICAgICAgLy8gUmV1c2UgZXhpc3RpbmcgYWxsb2NhdGVkIGluc3RhbmNlLgorICAgICAgKnB0cl8gPSAqZGVmYXVsdF92YWx1ZTsKKyAgICB9CisgIH0KKworICAvLyBJbnRlcm5hbCBhY2Nlc3NvciB1c2VkIG9ubHkgYXQgcGFyc2UgdGltZSB0byBwcm92aWRlIGRpcmVjdCBhY2Nlc3MgdG8gdGhlCisgIC8vIHJhdyBwb2ludGVyIGZyb20gdGhlIHNoYXJlZCBwYXJzZSByb3V0aW5lIChpbiB0aGUgbm9uLWFyZW5hcyBjYXNlKS4gVGhlCisgIC8vIHBhcnNlIHJvdXRpbmUgZG9lcyB0aGUgc3RyaW5nIGFsbG9jYXRpb24gaW4gb3JkZXIgdG8gc2F2ZSBjb2RlIHNpemUgaW4gdGhlCisgIC8vIGdlbmVyYXRlZCBwYXJzaW5nIGNvZGUuCisgIGlubGluZSA6OnN0ZDo6c3RyaW5nKiogVW5zYWZlUmF3U3RyaW5nUG9pbnRlcigpIHsKKyAgICByZXR1cm4gJnB0cl87CisgIH0KKworIHByaXZhdGU6CisgIDo6c3RkOjpzdHJpbmcqIHB0cl87CisKKyAgaW5saW5lIHZvaWQgQ3JlYXRlSW5zdGFuY2UoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IDo6c3RkOjpzdHJpbmcqIGluaXRpYWxfdmFsdWUpCisgICAgICBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FIHsKKyAgICAvLyBBc3N1bWVzIHB0cl8gaXMgbm90IE5VTEwuCisgICAgaWYgKGluaXRpYWxfdmFsdWUgIT0gTlVMTCkgeworICAgICAgcHRyXyA9IG5ldyA6OnN0ZDo6c3RyaW5nKCppbml0aWFsX3ZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgcHRyXyA9IG5ldyA6OnN0ZDo6c3RyaW5nKCk7CisgICAgfQorICAgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgICBhcmVuYS0+T3duKHB0cl8pOworICAgIH0KKyAgfQorICBpbmxpbmUgdm9pZCBDcmVhdGVJbnN0YW5jZU5vQXJlbmEoY29uc3QgOjpzdGQ6OnN0cmluZyogaW5pdGlhbF92YWx1ZSkKKyAgICAgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgeworICAgIGlmIChpbml0aWFsX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgIHB0cl8gPSBuZXcgOjpzdGQ6OnN0cmluZygqaW5pdGlhbF92YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8gPSBuZXcgOjpzdGQ6OnN0cmluZygpOworICAgIH0KKyAgfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FSRU5BU1RSSU5HX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZ191bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmdfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGViZDRiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmdfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBhcmVuYXN0cmluZ191bml0dGVzdC5jYyBpcyBub3Qgb3Blbi1zb3VyY2VkLiBEbyBub3QgaW5jbHVkZSBpbiBvcGVuLXNvdXJjZQorLy8gZGlzdHJpYnV0aW9uLgorCisvLyBCYXNlZCBvbiBtdmVsc0AncyBmcmFua2Vuc3RyaW5nLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPGNzdGRsaWI+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmc7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHI7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKworc3RhdGljIHN0cmluZyBXcmFwU3RyaW5nKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHJldHVybiB2YWx1ZTsKK30KKworLy8gVGVzdCBBcmVuYVN0cmluZ1B0ciB3aXRoIGFyZW5hID09IE5VTEwuCitURVNUKEFyZW5hU3RyaW5nUHRyVGVzdCwgQXJlbmFTdHJpbmdQdHJPbkhlYXApIHsKKyAgQXJlbmFTdHJpbmdQdHIgZmllbGQ7CisgIDo6c3RkOjpzdHJpbmcgZGVmYXVsdF92YWx1ZSA9ICJkZWZhdWx0IjsKKyAgZmllbGQuVW5zYWZlU2V0RGVmYXVsdCgmZGVmYXVsdF92YWx1ZSk7CisgIEVYUEVDVF9FUShzdHJpbmcoImRlZmF1bHQiKSwgZmllbGQuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIGZpZWxkLlNldCgmZGVmYXVsdF92YWx1ZSwgV3JhcFN0cmluZygiVGVzdCBzaG9ydCIpLCBOVUxMKTsKKyAgRVhQRUNUX0VRKHN0cmluZygiVGVzdCBzaG9ydCIpLCBmaWVsZC5HZXQoJmRlZmF1bHRfdmFsdWUpKTsKKyAgZmllbGQuU2V0KCZkZWZhdWx0X3ZhbHVlLCBXcmFwU3RyaW5nKCJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiKSwgTlVMTCk7CisgIEVYUEVDVF9FUShzdHJpbmcoIlRlc3QgbG9uZyBsb25nIGxvbmcgbG9uZyB2YWx1ZSIpLCBmaWVsZC5HZXQoJmRlZmF1bHRfdmFsdWUpKTsKKyAgZmllbGQuU2V0KCZkZWZhdWx0X3ZhbHVlLCBzdHJpbmcoIiIpLCBOVUxMKTsKKyAgZmllbGQuRGVzdHJveSgmZGVmYXVsdF92YWx1ZSwgTlVMTCk7CisKKyAgQXJlbmFTdHJpbmdQdHIgZmllbGQyOworICBmaWVsZDIuVW5zYWZlU2V0RGVmYXVsdCgmZGVmYXVsdF92YWx1ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dCA9IGZpZWxkMi5NdXRhYmxlKCZkZWZhdWx0X3ZhbHVlLCBOVUxMKTsKKyAgRVhQRUNUX0VRKG11dCwgZmllbGQyLk11dGFibGUoJmRlZmF1bHRfdmFsdWUsIE5VTEwpKTsKKyAgRVhQRUNUX0VRKG11dCwgJmZpZWxkMi5HZXQoJmRlZmF1bHRfdmFsdWUpKTsKKyAgRVhQRUNUX05FKCZkZWZhdWx0X3ZhbHVlLCBtdXQpOworICBFWFBFQ1RfRVEoc3RyaW5nKCJkZWZhdWx0IiksICptdXQpOworICAqbXV0ID0gIlRlc3QgbG9uZyBsb25nIGxvbmcgbG9uZyB2YWx1ZSI7ICAvLyBlbnN1cmUgc3RyaW5nIGFsbG9jYXRlcyBzdG9yYWdlCisgIEVYUEVDVF9FUShzdHJpbmcoIlRlc3QgbG9uZyBsb25nIGxvbmcgbG9uZyB2YWx1ZSIpLCBmaWVsZDIuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIGZpZWxkMi5EZXN0cm95KCZkZWZhdWx0X3ZhbHVlLCBOVUxMKTsKK30KKworVEVTVChBcmVuYVN0cmluZ1B0clRlc3QsIEFyZW5hU3RyaW5nUHRyT25BcmVuYSkgeworICBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTsKKyAgQXJlbmFTdHJpbmdQdHIgZmllbGQ7CisgIDo6c3RkOjpzdHJpbmcgZGVmYXVsdF92YWx1ZSA9ICJkZWZhdWx0IjsKKyAgZmllbGQuVW5zYWZlU2V0RGVmYXVsdCgmZGVmYXVsdF92YWx1ZSk7CisgIEVYUEVDVF9FUShzdHJpbmcoImRlZmF1bHQiKSwgZmllbGQuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIGZpZWxkLlNldCgmZGVmYXVsdF92YWx1ZSwgV3JhcFN0cmluZygiVGVzdCBzaG9ydCIpLCAmYXJlbmEpOworICBFWFBFQ1RfRVEoc3RyaW5nKCJUZXN0IHNob3J0IiksIGZpZWxkLkdldCgmZGVmYXVsdF92YWx1ZSkpOworICBmaWVsZC5TZXQoJmRlZmF1bHRfdmFsdWUsIFdyYXBTdHJpbmcoIlRlc3QgbG9uZyBsb25nIGxvbmcgbG9uZyB2YWx1ZSIpLCAmYXJlbmEpOworICBFWFBFQ1RfRVEoc3RyaW5nKCJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiKSwKKyAgICAgICAgICAgIGZpZWxkLkdldCgmZGVmYXVsdF92YWx1ZSkpOworICBmaWVsZC5TZXQoJmRlZmF1bHRfdmFsdWUsIHN0cmluZygiIiksICZhcmVuYSk7CisgIGZpZWxkLkRlc3Ryb3koJmRlZmF1bHRfdmFsdWUsICZhcmVuYSk7CisKKyAgQXJlbmFTdHJpbmdQdHIgZmllbGQyOworICBmaWVsZDIuVW5zYWZlU2V0RGVmYXVsdCgmZGVmYXVsdF92YWx1ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dCA9IGZpZWxkMi5NdXRhYmxlKCZkZWZhdWx0X3ZhbHVlLCAmYXJlbmEpOworICBFWFBFQ1RfRVEobXV0LCBmaWVsZDIuTXV0YWJsZSgmZGVmYXVsdF92YWx1ZSwgJmFyZW5hKSk7CisgIEVYUEVDVF9FUShtdXQsICZmaWVsZDIuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIEVYUEVDVF9ORSgmZGVmYXVsdF92YWx1ZSwgbXV0KTsKKyAgRVhQRUNUX0VRKHN0cmluZygiZGVmYXVsdCIpLCAqbXV0KTsKKyAgKm11dCA9ICJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiOyAgLy8gZW5zdXJlIHN0cmluZyBhbGxvY2F0ZXMgc3RvcmFnZQorICBFWFBFQ1RfRVEoc3RyaW5nKCJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiKSwKKyAgICAgICAgICAgIGZpZWxkMi5HZXQoJmRlZmF1bHRfdmFsdWUpKTsKKyAgZmllbGQyLkRlc3Ryb3koJmRlZmF1bHRfdmFsdWUsICZhcmVuYSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDAzOWIwMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuY2MKQEAgLTAsMCArMSw4NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworQ29kZUdlbmVyYXRvcjo6fkNvZGVHZW5lcmF0b3IoKSB7fQorR2VuZXJhdG9yQ29udGV4dDo6fkdlbmVyYXRvckNvbnRleHQoKSB7fQorCitpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qCitHZW5lcmF0b3JDb250ZXh0OjpPcGVuRm9yQXBwZW5kKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2lvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogR2VuZXJhdG9yQ29udGV4dDo6T3BlbkZvckluc2VydCgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCkgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGhpcyBHZW5lcmF0b3JDb250ZXh0IGRvZXMgbm90IHN1cHBvcnQgaW5zZXJ0aW9uLiI7CisgIHJldHVybiBOVUxMOyAgLy8gbWFrZSBjb21waWxlciBoYXBweQorfQorCit2b2lkIEdlbmVyYXRvckNvbnRleHQ6Okxpc3RQYXJzZWRGaWxlcygKKyAgICB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogb3V0cHV0KSB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJUaGlzIEdlbmVyYXRvckNvbnRleHQgZG9lcyBub3Qgc3VwcG9ydCBMaXN0UGFyc2VkRmlsZXMiOworfQorCisvLyBQYXJzZXMgYSBzZXQgb2YgY29tbWEtZGVsaW1pdGVkIG5hbWUvdmFsdWUgcGFpcnMuCit2b2lkIFBhcnNlR2VuZXJhdG9yUGFyYW1ldGVyKGNvbnN0IHN0cmluZyYgdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4qIG91dHB1dCkgeworICB2ZWN0b3I8c3RyaW5nPiBwYXJ0cyA9IFNwbGl0KHRleHQsICIsIiwgdHJ1ZSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCk7IGkrKykgeworICAgIHN0cmluZzo6c2l6ZV90eXBlIGVxdWFsc19wb3MgPSBwYXJ0c1tpXS5maW5kX2ZpcnN0X29mKCc9Jyk7CisgICAgcGFpcjxzdHJpbmcsIHN0cmluZz4gdmFsdWU7CisgICAgaWYgKGVxdWFsc19wb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICB2YWx1ZS5maXJzdCA9IHBhcnRzW2ldOworICAgICAgdmFsdWUuc2Vjb25kID0gIiI7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhbHVlLmZpcnN0ID0gcGFydHNbaV0uc3Vic3RyKDAsIGVxdWFsc19wb3MpOworICAgICAgdmFsdWUuc2Vjb25kID0gcGFydHNbaV0uc3Vic3RyKGVxdWFsc19wb3MgKyAxKTsKKyAgICB9CisgICAgb3V0cHV0LT5wdXNoX2JhY2sodmFsdWUpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzIxYThjYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDE0NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIERlZmluZXMgdGhlIGFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBlYWNoIG9mIHRoZSBsYW5ndWFnZS1zcGVjaWZpYworLy8gY29kZSBnZW5lcmF0b3JzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DT0RFX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NPREVfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW8geyBjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsgfQorY2xhc3MgRmlsZURlc2NyaXB0b3I7CisKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgQ29kZUdlbmVyYXRvcjsKK2NsYXNzIEdlbmVyYXRvckNvbnRleHQ7CisKKy8vIFRoZSBhYnN0cmFjdCBpbnRlcmZhY2UgdG8gYSBjbGFzcyB3aGljaCBnZW5lcmF0ZXMgY29kZSBpbXBsZW1lbnRpbmcgYQorLy8gcGFydGljdWxhciBwcm90byBmaWxlIGluIGEgcGFydGljdWxhciBsYW5ndWFnZS4gIEEgbnVtYmVyIG9mIHRoZXNlIG1heQorLy8gYmUgcmVnaXN0ZXJlZCB3aXRoIENvbW1hbmRMaW5lSW50ZXJmYWNlIHRvIHN1cHBvcnQgdmFyaW91cyBsYW5ndWFnZXMuCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgaW5saW5lIENvZGVHZW5lcmF0b3IoKSB7fQorICB2aXJ0dWFsIH5Db2RlR2VuZXJhdG9yKCk7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgZm9yIHRoZSBnaXZlbiBwcm90byBmaWxlLCBnZW5lcmF0aW5nIG9uZSBvciBtb3JlIGZpbGVzIGluCisgIC8vIHRoZSBnaXZlbiBvdXRwdXQgZGlyZWN0b3J5LgorICAvLworICAvLyBBIHBhcmFtZXRlciB0byBiZSBwYXNzZWQgdG8gdGhlIGdlbmVyYXRvciBjYW4gYmUgc3BlY2lmaWVkIG9uIHRoZQorICAvLyBjb21tYW5kIGxpbmUuICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkgSmF2YSBhbmQgc2ltaWxhciBsYW5ndWFnZXMKKyAgLy8gdG8gc3BlY2lmeSB3aGljaCBzcGVjaWZpYyBjbGFzcyBmcm9tIHRoZSBwcm90byBmaWxlIGlzIHRvIGJlIGdlbmVyYXRlZCwKKyAgLy8gdGhvdWdoIGl0IGNvdWxkIGhhdmUgb3RoZXIgdXNlcyBhcyB3ZWxsLiAgSXQgaXMgZW1wdHkgaWYgbm8gcGFyYW1ldGVyIHdhcworICAvLyBnaXZlbi4KKyAgLy8KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHN1Y2Nlc3NmdWwuICBPdGhlcndpc2UsIHNldHMgKmVycm9yIHRvIGEgZGVzY3JpcHRpb24gb2YKKyAgLy8gdGhlIHByb2JsZW0gKGUuZy4gImludmFsaWQgcGFyYW1ldGVyIikgYW5kIHJldHVybnMgZmFsc2UuCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29kZUdlbmVyYXRvcik7Cit9OworCisvLyBDb2RlR2VuZXJhdG9ycyBnZW5lcmF0ZSBvbmUgb3IgbW9yZSBmaWxlcyBpbiBhIGdpdmVuIGRpcmVjdG9yeS4gIFRoaXMKKy8vIGFic3RyYWN0IGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBkaXJlY3RvcnkgdG8gd2hpY2ggdGhlIENvZGVHZW5lcmF0b3IgaXMKKy8vIHRvIHdyaXRlIGFuZCBvdGhlciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udGV4dCBpbiB3aGljaCB0aGUgR2VuZXJhdG9yCisvLyBydW5zLgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBHZW5lcmF0b3JDb250ZXh0IHsKKyBwdWJsaWM6CisgIGlubGluZSBHZW5lcmF0b3JDb250ZXh0KCkge30KKyAgdmlydHVhbCB+R2VuZXJhdG9yQ29udGV4dCgpOworCisgIC8vIE9wZW5zIHRoZSBnaXZlbiBmaWxlLCB0cnVuY2F0aW5nIGl0IGlmIGl0IGV4aXN0cywgYW5kIHJldHVybnMgYQorICAvLyBaZXJvQ29weU91dHB1dFN0cmVhbSB0aGF0IHdyaXRlcyB0byB0aGUgZmlsZS4gIFRoZSBjYWxsZXIgdGFrZXMgb3duZXJzaGlwCisgIC8vIG9mIHRoZSByZXR1cm5lZCBvYmplY3QuICBUaGlzIG1ldGhvZCBuZXZlciBmYWlscyAoYSBkdW1teSBzdHJlYW0gd2lsbCBiZQorICAvLyByZXR1cm5lZCBpbnN0ZWFkKS4KKyAgLy8KKyAgLy8gVGhlIGZpbGVuYW1lIGdpdmVuIHNob3VsZCBiZSByZWxhdGl2ZSB0byB0aGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUuCisgIC8vIEUuZy4gdGhlIEMrKyBnZW5lcmF0b3IsIHdoZW4gZ2VuZXJhdGluZyBjb2RlIGZvciAiZm9vL2Jhci5wcm90byIsIHdpbGwKKyAgLy8gZ2VuZXJhdGUgdGhlIGZpbGVzICJmb28vYmFyLnBiLmgiIGFuZCAiZm9vL2Jhci5wYi5jYyI7IG5vdGUgdGhhdAorICAvLyAiZm9vLyIgaXMgaW5jbHVkZWQgaW4gdGhlc2UgZmlsZW5hbWVzLiAgVGhlIGZpbGVuYW1lIGlzIG5vdCBhbGxvd2VkIHRvCisgIC8vIGNvbnRhaW4gIi4iIG9yICIuLiIgY29tcG9uZW50cy4KKyAgdmlydHVhbCBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgPSAwOworCisgIC8vIFNpbWlsYXIgdG8gT3BlbigpIGJ1dCB0aGUgb3V0cHV0IHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIGZpbGUgaWYgZXhpc3RzCisgIHZpcnR1YWwgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuRm9yQXBwZW5kKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisgIC8vIENyZWF0ZXMgYSBaZXJvQ29weU91dHB1dFN0cmVhbSB3aGljaCB3aWxsIGluc2VydCBjb2RlIGludG8gdGhlIGdpdmVuIGZpbGUKKyAgLy8gYXQgdGhlIGdpdmVuIGluc2VydGlvbiBwb2ludC4gIFNlZSBwbHVnaW4ucHJvdG8gKHBsdWdpbi5wYi5oKSBmb3IgbW9yZQorICAvLyBpbmZvcm1hdGlvbiBvbiBpbnNlcnRpb24gcG9pbnRzLiAgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgLy8gYXNzZXJ0LWZhaWxzIC0tIGl0IGV4aXN0cyBvbmx5IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgLy8KKyAgLy8gV0FSTklORzogIFRoaXMgZmVhdHVyZSBpcyBjdXJyZW50bHkgRVhQRVJJTUVOVEFMIGFuZCBpcyBzdWJqZWN0IHRvIGNoYW5nZS4KKyAgdmlydHVhbCBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIE9wZW5Gb3JJbnNlcnQoCisgICAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCk7CisKKyAgLy8gUmV0dXJucyBhIHZlY3RvciBvZiBGaWxlRGVzY3JpcHRvcnMgZm9yIGFsbCB0aGUgZmlsZXMgYmVpbmcgY29tcGlsZWQKKyAgLy8gaW4gdGhpcyBydW4uICBVc2VmdWwgZm9yIGxhbmd1YWdlcywgc3VjaCBhcyBHbywgdGhhdCB0cmVhdCBmaWxlcworICAvLyBkaWZmZXJlbnRseSB3aGVuIGNvbXBpbGVkIGFzIGEgc2V0IHJhdGhlciB0aGFuIGluZGl2aWR1YWxseS4KKyAgdmlydHVhbCB2b2lkIExpc3RQYXJzZWRGaWxlcyh2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogb3V0cHV0KTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhHZW5lcmF0b3JDb250ZXh0KTsKK307CisKKy8vIFRoZSB0eXBlIEdlbmVyYXRvckNvbnRleHQgd2FzIG9uY2UgY2FsbGVkIE91dHB1dERpcmVjdG9yeS4gVGhpcyB0eXBlZGVmCisvLyBwcm92aWRlcyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LgordHlwZWRlZiBHZW5lcmF0b3JDb250ZXh0IE91dHB1dERpcmVjdG9yeTsKKworLy8gU2V2ZXJhbCBjb2RlIGdlbmVyYXRvcnMgdHJlYXQgdGhlIHBhcmFtZXRlciBhcmd1bWVudCBhcyBob2xkaW5nIGEKKy8vIGxpc3Qgb2Ygb3B0aW9ucyBzZXBhcmF0ZWQgYnkgY29tbWFzLiAgVGhpcyBoZWxwZXIgZnVuY3Rpb24gcGFyc2VzCisvLyBhIHNldCBvZiBjb21tYS1kZWxpbWl0ZWQgbmFtZS92YWx1ZSBwYWlyczogZS5nLiwKKy8vICAgImZvbz1iYXIsYmF6LHF1eD1jb3JnZSIKKy8vIHBhcnNlcyB0byB0aGUgcGFpcnM6CisvLyAgICgiZm9vIiwgImJhciIpLCAoImJheiIsICIiKSwgKCJxdXgiLCAiY29yZ2UiKQorZXh0ZXJuIHZvaWQgUGFyc2VHZW5lcmF0b3JQYXJhbWV0ZXIoY29uc3Qgc3RyaW5nJiwKKyAgICAgICAgICAgIHZlY3RvcjxwYWlyPHN0cmluZywgc3RyaW5nPiA+Kik7CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NPREVfR0VORVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2NzIzOGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuY2MKQEAgLTAsMCArMSwxNzM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oPgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaWZkZWYgX01TQ19WRVIKKyNpbmNsdWRlIDxpby5oPgorI2luY2x1ZGUgPGRpcmVjdC5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8aW9zdHJlYW0+CisjaW5jbHVkZSA8Y3R5cGUuaD4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKKyNpZiBkZWZpbmVkKF9XSU4zMikKKyNkZWZpbmUgbWtkaXIobmFtZSwgbW9kZSkgbWtkaXIobmFtZSkKKyNpZm5kZWYgV19PSworI2RlZmluZSBXX09LIDAyICAvLyBub3QgZGVmaW5lZCBieSBNU1ZDIGZvciB3aGF0ZXZlciByZWFzb24KKyNlbmRpZgorI2lmbmRlZiBGX09LCisjZGVmaW5lIEZfT0sgMDAgIC8vIG5vdCBkZWZpbmVkIGJ5IE1TVkMgZm9yIHdoYXRldmVyIHJlYXNvbgorI2VuZGlmCisjaWZuZGVmIFNURElOX0ZJTEVOTworI2RlZmluZSBTVERJTl9GSUxFTk8gMAorI2VuZGlmCisjaWZuZGVmIFNURE9VVF9GSUxFTk8KKyNkZWZpbmUgU1RET1VUX0ZJTEVOTyAxCisjZW5kaWYKKyNlbmRpZgorCisjaWZuZGVmIE9fQklOQVJZCisjaWZkZWYgX09fQklOQVJZCisjZGVmaW5lIE9fQklOQVJZIF9PX0JJTkFSWQorI2Vsc2UKKyNkZWZpbmUgT19CSU5BUlkgMCAgICAgLy8gSWYgdGhpcyBpc24ndCBkZWZpbmVkLCB0aGUgcGxhdGZvcm0gZG9lc24ndCBuZWVkIGl0LgorI2VuZGlmCisjZW5kaWYKKworbmFtZXNwYWNlIHsKKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoX19DWUdXSU5fXykKK3N0YXRpYyBjb25zdCBjaGFyKiBrUGF0aFNlcGFyYXRvciA9ICI7IjsKKyNlbHNlCitzdGF0aWMgY29uc3QgY2hhcioga1BhdGhTZXBhcmF0b3IgPSAiOiI7CisjZW5kaWYKKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSB0ZXh0IGxvb2tzIGxpa2UgYSBXaW5kb3dzLXN0eWxlIGFic29sdXRlIHBhdGgsIHN0YXJ0aW5nCisvLyB3aXRoIGEgZHJpdmUgbGV0dGVyLiAgRXhhbXBsZTogICJDOlxmb28iLiAgVE9ETyhrZW50b24pOiAgU2hhcmUgdGhpcyB3aXRoCisvLyBjb3B5IGluIGltcG9ydGVyLmNjPworc3RhdGljIGJvb2wgSXNXaW5kb3dzQWJzb2x1dGVQYXRoKGNvbnN0IHN0cmluZyYgdGV4dCkgeworI2lmIGRlZmluZWQoX1dJTjMyKSB8fCBkZWZpbmVkKF9fQ1lHV0lOX18pCisgIHJldHVybiB0ZXh0LnNpemUoKSA+PSAzICYmIHRleHRbMV0gPT0gJzonICYmCisgICAgICAgICBpc2FscGhhKHRleHRbMF0pICYmCisgICAgICAgICAodGV4dFsyXSA9PSAnLycgfHwgdGV4dFsyXSA9PSAnXFwnKSAmJgorICAgICAgICAgdGV4dC5maW5kX2xhc3Rfb2YoJzonKSA9PSAxOworI2Vsc2UKKyAgcmV0dXJuIGZhbHNlOworI2VuZGlmCit9CisKK3ZvaWQgU2V0RmRUb1RleHRNb2RlKGludCBmZCkgeworI2lmZGVmIF9XSU4zMgorICBpZiAoX3NldG1vZGUoZmQsIF9PX1RFWFQpID09IC0xKSB7CisgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBJIHRoaW5rLgorICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIl9zZXRtb2RlKCIgPDwgZmQgPDwgIiwgX09fVEVYVCk6ICIgPDwgc3RyZXJyb3IoZXJybm8pOworICB9CisjZW5kaWYKKyAgLy8gKFRleHQgYW5kIGJpbmFyeSBhcmUgdGhlIHNhbWUgb24gbm9uLVdpbmRvd3MgcGxhdGZvcm1zLikKK30KKwordm9pZCBTZXRGZFRvQmluYXJ5TW9kZShpbnQgZmQpIHsKKyNpZmRlZiBfV0lOMzIKKyAgaWYgKF9zZXRtb2RlKGZkLCBfT19CSU5BUlkpID09IC0xKSB7CisgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBJIHRoaW5rLgorICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIl9zZXRtb2RlKCIgPDwgZmQgPDwgIiwgX09fQklOQVJZKTogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgIH0KKyNlbmRpZgorICAvLyAoVGV4dCBhbmQgYmluYXJ5IGFyZSB0aGUgc2FtZSBvbiBub24tV2luZG93cyBwbGF0Zm9ybXMuKQorfQorCit2b2lkIEFkZFRyYWlsaW5nU2xhc2goc3RyaW5nKiBwYXRoKSB7CisgIGlmICghcGF0aC0+ZW1wdHkoKSAmJiBwYXRoLT5hdChwYXRoLT5zaXplKCkgLSAxKSAhPSAnLycpIHsKKyAgICBwYXRoLT5wdXNoX2JhY2soJy8nKTsKKyAgfQorfQorCitib29sIFZlcmlmeURpcmVjdG9yeUV4aXN0cyhjb25zdCBzdHJpbmcmIHBhdGgpIHsKKyAgaWYgKHBhdGguZW1wdHkoKSkgcmV0dXJuIHRydWU7CisKKyAgaWYgKGFjY2VzcyhwYXRoLmNfc3RyKCksIEZfT0spID09IC0xKSB7CisgICAgc3RkOjpjZXJyIDw8IHBhdGggPDwgIjogIiA8PCBzdHJlcnJvcihlcnJubykgPDwgc3RkOjplbmRsOworICAgIHJldHVybiBmYWxzZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCisvLyBUcnkgdG8gY3JlYXRlIHRoZSBwYXJlbnQgZGlyZWN0b3J5IG9mIHRoZSBnaXZlbiBmaWxlLCBjcmVhdGluZyB0aGUgcGFyZW50J3MKKy8vIHBhcmVudCBpZiBuZWNlc3NhcnksIGFuZCBzbyBvbi4gIFRoZSBmdWxsIGZpbGUgbmFtZSBpcyBhY3R1YWxseQorLy8gKHByZWZpeCArIGZpbGVuYW1lKSwgYnV0IHdlIGFzc3VtZSB8cHJlZml4fCBhbHJlYWR5IGV4aXN0cyBhbmQgb25seSBjcmVhdGUKKy8vIGRpcmVjdG9yaWVzIGxpc3RlZCBpbiB8ZmlsZW5hbWV8LgorYm9vbCBUcnlDcmVhdGVQYXJlbnREaXJlY3RvcnkoY29uc3Qgc3RyaW5nJiBwcmVmaXgsIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgLy8gUmVjdXJzaXZlbHkgY3JlYXRlIHBhcmVudCBkaXJlY3RvcmllcyB0byB0aGUgb3V0cHV0IGZpbGUuCisgIHZlY3RvcjxzdHJpbmc+IHBhcnRzID0gU3BsaXQoZmlsZW5hbWUsICIvIiwgdHJ1ZSk7CisgIHN0cmluZyBwYXRoX3NvX2ZhciA9IHByZWZpeDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCkgLSAxOyBpKyspIHsKKyAgICBwYXRoX3NvX2ZhciArPSBwYXJ0c1tpXTsKKyAgICBpZiAobWtkaXIocGF0aF9zb19mYXIuY19zdHIoKSwgMDc3NykgIT0gMCkgeworICAgICAgaWYgKGVycm5vICE9IEVFWElTVCkgeworICAgICAgICBzdGQ6OmNlcnIgPDwgZmlsZW5hbWUgPDwgIjogd2hpbGUgdHJ5aW5nIHRvIGNyZWF0ZSBkaXJlY3RvcnkgIgorICAgICAgICAgICAgICAgICAgPDwgcGF0aF9zb19mYXIgPDwgIjogIiA8PCBzdHJlcnJvcihlcnJubykgPDwgc3RkOjplbmRsOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHBhdGhfc29fZmFyICs9ICcvJzsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gQSBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciB0aGF0IHByaW50cyBlcnJvcnMgdG8gc3RkZXJyLgorY2xhc3MgQ29tbWFuZExpbmVJbnRlcmZhY2U6OkVycm9yUHJpbnRlciA6IHB1YmxpYyBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW86OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIEVycm9yUHJpbnRlcihFcnJvckZvcm1hdCBmb3JtYXQsIERpc2tTb3VyY2VUcmVlICp0cmVlID0gTlVMTCkKKyAgICA6IGZvcm1hdF8oZm9ybWF0KSwgdHJlZV8odHJlZSkge30KKyAgfkVycm9yUHJpbnRlcigpIHt9CisKKyAgLy8gaW1wbGVtZW50cyBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBpbnQgbGluZSwgaW50IGNvbHVtbiwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKworICAgIC8vIFByaW50IGZ1bGwgcGF0aCB3aGVuIHJ1bm5pbmcgdW5kZXIgTVNWUworICAgIHN0cmluZyBkZmlsZTsKKyAgICBpZiAoZm9ybWF0XyA9PSBDb21tYW5kTGluZUludGVyZmFjZTo6RVJST1JfRk9STUFUX01TVlMgJiYKKyAgICAgICAgdHJlZV8gIT0gTlVMTCAmJgorICAgICAgICB0cmVlXy0+VmlydHVhbEZpbGVUb0Rpc2tGaWxlKGZpbGVuYW1lLCAmZGZpbGUpKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgZGZpbGU7CisgICAgfSBlbHNlIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZTsKKyAgICB9CisKKyAgICAvLyBVc2VycyB0eXBpY2FsbHkgZXhwZWN0IDEtYmFzZWQgbGluZS9jb2x1bW4gbnVtYmVycywgc28gd2UgYWRkIDEKKyAgICAvLyB0byBlYWNoIGhlcmUuCisgICAgaWYgKGxpbmUgIT0gLTEpIHsKKyAgICAgIC8vIEFsbG93IGZvciBib3RoIEdDQy0gYW5kIFZpc3VhbC1TdHVkaW8tY29tcGF0aWJsZSBvdXRwdXQuCisgICAgICBzd2l0Y2ggKGZvcm1hdF8pIHsKKyAgICAgICAgY2FzZSBDb21tYW5kTGluZUludGVyZmFjZTo6RVJST1JfRk9STUFUX0dDQzoKKyAgICAgICAgICBzdGQ6OmNlcnIgPDwgIjoiIDw8IChsaW5lICsgMSkgPDwgIjoiIDw8IChjb2x1bW4gKyAxKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBDb21tYW5kTGluZUludGVyZmFjZTo6RVJST1JfRk9STUFUX01TVlM6CisgICAgICAgICAgc3RkOjpjZXJyIDw8ICIoIiA8PCAobGluZSArIDEpCisgICAgICAgICAgICAgICAgICAgIDw8ICIpIDogZXJyb3IgaW4gY29sdW1uPSIgPDwgKGNvbHVtbiArIDEpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKworICAgIHN0ZDo6Y2VyciA8PCAiOiAiIDw8IG1lc3NhZ2UgPDwgc3RkOjplbmRsOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBpbzo6RXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBBZGRFcnJvcihpbnQgbGluZSwgaW50IGNvbHVtbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgQWRkRXJyb3IoImlucHV0IiwgbGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgY29uc3QgRXJyb3JGb3JtYXQgZm9ybWF0XzsKKyAgRGlza1NvdXJjZVRyZWUgKnRyZWVfOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBBIEdlbmVyYXRvckNvbnRleHQgaW1wbGVtZW50YXRpb24gdGhhdCBidWZmZXJzIGZpbGVzIGluIG1lbW9yeSwgdGhlbiBkdW1wcworLy8gdGhlbSBhbGwgdG8gZGlzayBvbiBkZW1hbmQuCitjbGFzcyBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGwgOiBwdWJsaWMgR2VuZXJhdG9yQ29udGV4dCB7CisgcHVibGljOgorICBHZW5lcmF0b3JDb250ZXh0SW1wbChjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzKTsKKyAgfkdlbmVyYXRvckNvbnRleHRJbXBsKCk7CisKKyAgLy8gV3JpdGUgYWxsIGZpbGVzIGluIHRoZSBkaXJlY3RvcnkgdG8gZGlzayBhdCB0aGUgZ2l2ZW4gb3V0cHV0IGxvY2F0aW9uLAorICAvLyB3aGljaCBtdXN0IGVuZCBpbiBhICcvJy4KKyAgYm9vbCBXcml0ZUFsbFRvRGlzayhjb25zdCBzdHJpbmcmIHByZWZpeCk7CisKKyAgLy8gV3JpdGUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgZGlyZWN0b3J5IHRvIGEgWklQLWZvcm1hdCBhcmNoaXZlIHdpdGggdGhlCisgIC8vIGdpdmVuIG5hbWUuCisgIGJvb2wgV3JpdGVBbGxUb1ppcChjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworICAvLyBBZGQgYSBib2lsZXJwbGF0ZSBNRVRBLUlORi9NQU5JRkVTVC5NRiBmaWxlIGFzIHJlcXVpcmVkIGJ5IHRoZSBKYXZhIEpBUgorICAvLyBmb3JtYXQsIHVubGVzcyBvbmUgaGFzIGFscmVhZHkgYmVlbiB3cml0dGVuLgorICB2b2lkIEFkZEphck1hbmlmZXN0KCk7CisKKyAgLy8gR2V0IG5hbWUgb2YgYWxsIG91dHB1dCBmaWxlcy4KKyAgdm9pZCBHZXRPdXRwdXRGaWxlbmFtZXModmVjdG9yPHN0cmluZz4qIG91dHB1dF9maWxlbmFtZXMpOworCisgIC8vIGltcGxlbWVudHMgR2VuZXJhdG9yQ29udGV4dCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogT3BlbkZvckFwcGVuZChjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKyAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuRm9ySW5zZXJ0KAorICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQpOworICB2b2lkIExpc3RQYXJzZWRGaWxlcyh2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogb3V0cHV0KSB7CisgICAgKm91dHB1dCA9IHBhcnNlZF9maWxlc187CisgIH0KKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBNZW1vcnlPdXRwdXRTdHJlYW07CisKKyAgLy8gbWFwIGluc3RlYWQgb2YgaGFzaF9tYXAgc28gdGhhdCBmaWxlcyBhcmUgd3JpdHRlbiBpbiBvcmRlciAoZ29vZCB3aGVuCisgIC8vIHdyaXRpbmcgemlwcykuCisgIG1hcDxzdHJpbmcsIHN0cmluZyo+IGZpbGVzXzsKKyAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlc187CisgIGJvb2wgaGFkX2Vycm9yXzsKK307CisKK2NsYXNzIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpNZW1vcnlPdXRwdXRTdHJlYW0KKyAgICA6IHB1YmxpYyBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgTWVtb3J5T3V0cHV0U3RyZWFtKEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnksIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICBib29sIGFwcGVuZF9tb2RlKTsKKyAgTWVtb3J5T3V0cHV0U3RyZWFtKEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnksIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCk7CisgIHZpcnR1YWwgfk1lbW9yeU91dHB1dFN0cmVhbSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlPdXRwdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZpcnR1YWwgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsgcmV0dXJuIGlubmVyXy0+TmV4dChkYXRhLCBzaXplKTsgfQorICB2aXJ0dWFsIHZvaWQgQmFja1VwKGludCBjb3VudCkgICAgICAgICAgICB7ICAgICAgICBpbm5lcl8tPkJhY2tVcChjb3VudCk7ICAgIH0KKyAgdmlydHVhbCBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCAgICAgICAgICAgeyByZXR1cm4gaW5uZXJfLT5CeXRlQ291bnQoKTsgICAgICB9CisKKyBwcml2YXRlOgorICAvLyBXaGVyZSB0byBpbnNlcnQgdGhlIHN0cmluZyB3aGVuIGl0J3MgZG9uZS4KKyAgR2VuZXJhdG9yQ29udGV4dEltcGwqIGRpcmVjdG9yeV87CisgIHN0cmluZyBmaWxlbmFtZV87CisgIHN0cmluZyBpbnNlcnRpb25fcG9pbnRfOworCisgIC8vIFRoZSBzdHJpbmcgd2UncmUgYnVpbGRpbmcuCisgIHN0cmluZyBkYXRhXzsKKworICAvLyBXaGV0aGVyIHdlIHNob3VsZCBhcHBlbmQgdGhlIG91dHB1dCBzdHJlYW0gdG8gdGhlIGV4aXN0aW5nIGZpbGUuCisgIGJvb2wgYXBwZW5kX21vZGVfOworCisgIC8vIFN0cmluZ091dHB1dFN0cmVhbSB3cml0aW5nIHRvIGRhdGFfLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0+IGlubmVyXzsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6OkdlbmVyYXRvckNvbnRleHRJbXBsOjpHZW5lcmF0b3JDb250ZXh0SW1wbCgKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzKQorICAgIDogcGFyc2VkX2ZpbGVzXyhwYXJzZWRfZmlsZXMpLAorICAgICAgaGFkX2Vycm9yXyhmYWxzZSkgeworfQorCitDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6On5HZW5lcmF0b3JDb250ZXh0SW1wbCgpIHsKKyAgU1RMRGVsZXRlVmFsdWVzKCZmaWxlc18pOworfQorCitib29sIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0b3JDb250ZXh0SW1wbDo6V3JpdGVBbGxUb0Rpc2soCisgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgpIHsKKyAgaWYgKGhhZF9lcnJvcl8pIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIVZlcmlmeURpcmVjdG9yeUV4aXN0cyhwcmVmaXgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZm9yIChtYXA8c3RyaW5nLCBzdHJpbmcqPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGZpbGVzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZmlsZXNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBjb25zdCBzdHJpbmcmIHJlbGF0aXZlX2ZpbGVuYW1lID0gaXRlci0+Zmlyc3Q7CisgICAgY29uc3QgY2hhciogZGF0YSA9IGl0ZXItPnNlY29uZC0+ZGF0YSgpOworICAgIGludCBzaXplID0gaXRlci0+c2Vjb25kLT5zaXplKCk7CisKKyAgICBpZiAoIVRyeUNyZWF0ZVBhcmVudERpcmVjdG9yeShwcmVmaXgsIHJlbGF0aXZlX2ZpbGVuYW1lKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBzdHJpbmcgZmlsZW5hbWUgPSBwcmVmaXggKyByZWxhdGl2ZV9maWxlbmFtZTsKKworICAgIC8vIENyZWF0ZSB0aGUgb3V0cHV0IGZpbGUuCisgICAgaW50IGZpbGVfZGVzY3JpcHRvcjsKKyAgICBkbyB7CisgICAgICBmaWxlX2Rlc2NyaXB0b3IgPQorICAgICAgICBvcGVuKGZpbGVuYW1lLmNfc3RyKCksIE9fV1JPTkxZIHwgT19DUkVBVCB8IE9fVFJVTkMgfCBPX0JJTkFSWSwgMDY2Nik7CisgICAgfSB3aGlsZSAoZmlsZV9kZXNjcmlwdG9yIDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisKKyAgICBpZiAoZmlsZV9kZXNjcmlwdG9yIDwgMCkgeworICAgICAgaW50IGVycm9yID0gZXJybm87CisgICAgICBzdGQ6OmNlcnIgPDwgZmlsZW5hbWUgPDwgIjogIiA8PCBzdHJlcnJvcihlcnJvcik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gV3JpdGUgdGhlIGZpbGUuCisgICAgd2hpbGUgKHNpemUgPiAwKSB7CisgICAgICBpbnQgd3JpdGVfcmVzdWx0OworICAgICAgZG8geworICAgICAgICB3cml0ZV9yZXN1bHQgPSB3cml0ZShmaWxlX2Rlc2NyaXB0b3IsIGRhdGEsIHNpemUpOworICAgICAgfSB3aGlsZSAod3JpdGVfcmVzdWx0IDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisKKyAgICAgIGlmICh3cml0ZV9yZXN1bHQgPD0gMCkgeworICAgICAgICAvLyBXcml0ZSBlcnJvci4KKworICAgICAgICAvLyBGSVhNRShrZW50b24pOiAgQWNjb3JkaW5nIHRvIHRoZSBtYW4gcGFnZSwgaWYgd3JpdGUoKSByZXR1cm5zIHplcm8sCisgICAgICAgIC8vICAgdGhlcmUgd2FzIG5vIGVycm9yOyB3cml0ZSgpIHNpbXBseSBkaWQgbm90IHdyaXRlIGFueXRoaW5nLiAgSXQncworICAgICAgICAvLyAgIHVuY2xlYXIgdW5kZXIgd2hhdCBjaXJjdW1zdGFuY2VzIHRoaXMgbWlnaHQgaGFwcGVuLCBidXQgcHJlc3VtYWJseQorICAgICAgICAvLyAgIGVycm5vIHdvbid0IGJlIHNldCBpbiB0aGlzIGNhc2UuICBJIGFtIGNvbmZ1c2VkIGFzIHRvIGhvdyBzdWNoIGFuCisgICAgICAgIC8vICAgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuICBGb3Igbm93IEknbSB0cmVhdGluZyBpdCBhcyBhbiBlcnJvciwKKyAgICAgICAgLy8gICBzaW5jZSByZXRyeWluZyBzZWVtcyBsaWtlIGl0IGNvdWxkIGxlYWQgdG8gYW4gaW5maW5pdGUgbG9vcC4gIEkKKyAgICAgICAgLy8gICBzdXNwZWN0IHRoaXMgbmV2ZXIgYWN0dWFsbHkgaGFwcGVucyBhbnl3YXkuCisKKyAgICAgICAgaWYgKHdyaXRlX3Jlc3VsdCA8IDApIHsKKyAgICAgICAgICBpbnQgZXJyb3IgPSBlcnJubzsKKyAgICAgICAgICBzdGQ6OmNlcnIgPDwgZmlsZW5hbWUgPDwgIjogd3JpdGU6ICIgPDwgc3RyZXJyb3IoZXJyb3IpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiB3cml0ZSgpIHJldHVybmVkIHplcm8/IiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBkYXRhICs9IHdyaXRlX3Jlc3VsdDsKKyAgICAgIHNpemUgLT0gd3JpdGVfcmVzdWx0OworICAgIH0KKworICAgIGlmIChjbG9zZShmaWxlX2Rlc2NyaXB0b3IpICE9IDApIHsKKyAgICAgIGludCBlcnJvciA9IGVycm5vOworICAgICAgc3RkOjpjZXJyIDw8IGZpbGVuYW1lIDw8ICI6IGNsb3NlOiAiIDw8IHN0cmVycm9yKGVycm9yKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6OldyaXRlQWxsVG9aaXAoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBpZiAoaGFkX2Vycm9yXykgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIENyZWF0ZSB0aGUgb3V0cHV0IGZpbGUuCisgIGludCBmaWxlX2Rlc2NyaXB0b3I7CisgIGRvIHsKKyAgICBmaWxlX2Rlc2NyaXB0b3IgPQorICAgICAgb3BlbihmaWxlbmFtZS5jX3N0cigpLCBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX1RSVU5DIHwgT19CSU5BUlksIDA2NjYpOworICB9IHdoaWxlIChmaWxlX2Rlc2NyaXB0b3IgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKworICBpZiAoZmlsZV9kZXNjcmlwdG9yIDwgMCkgeworICAgIGludCBlcnJvciA9IGVycm5vOworICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiAiIDw8IHN0cmVycm9yKGVycm9yKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBDcmVhdGUgdGhlIFppcFdyaXRlcgorICBpbzo6RmlsZU91dHB1dFN0cmVhbSBzdHJlYW0oZmlsZV9kZXNjcmlwdG9yKTsKKyAgWmlwV3JpdGVyIHppcF93cml0ZXIoJnN0cmVhbSk7CisKKyAgZm9yIChtYXA8c3RyaW5nLCBzdHJpbmcqPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGZpbGVzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZmlsZXNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICB6aXBfd3JpdGVyLldyaXRlKGl0ZXItPmZpcnN0LCAqaXRlci0+c2Vjb25kKTsKKyAgfQorCisgIHppcF93cml0ZXIuV3JpdGVEaXJlY3RvcnkoKTsKKworICBpZiAoc3RyZWFtLkdldEVycm5vKCkgIT0gMCkgeworICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiAiIDw8IHN0cmVycm9yKHN0cmVhbS5HZXRFcnJubygpKSA8PCBzdGQ6OmVuZGw7CisgIH0KKworICBpZiAoIXN0cmVhbS5DbG9zZSgpKSB7CisgICAgc3RkOjpjZXJyIDw8IGZpbGVuYW1lIDw8ICI6ICIgPDwgc3RyZXJyb3Ioc3RyZWFtLkdldEVycm5vKCkpIDw8IHN0ZDo6ZW5kbDsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0b3JDb250ZXh0SW1wbDo6QWRkSmFyTWFuaWZlc3QoKSB7CisgIHN0cmluZyoqIG1hcF9zbG90ID0gJmZpbGVzX1siTUVUQS1JTkYvTUFOSUZFU1QuTUYiXTsKKyAgaWYgKCptYXBfc2xvdCA9PSBOVUxMKSB7CisgICAgKm1hcF9zbG90ID0gbmV3IHN0cmluZygKKyAgICAgICAgIk1hbmlmZXN0LVZlcnNpb246IDEuMFxuIgorICAgICAgICAiQ3JlYXRlZC1CeTogMS42LjAgKHByb3RvYylcbiIKKyAgICAgICAgIlxuIik7CisgIH0KK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6OkdldE91dHB1dEZpbGVuYW1lcygKKyAgICB2ZWN0b3I8c3RyaW5nPiogb3V0cHV0X2ZpbGVuYW1lcykgeworICBmb3IgKG1hcDxzdHJpbmcsIHN0cmluZyo+OjppdGVyYXRvciBpdGVyID0gZmlsZXNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBmaWxlc18uZW5kKCk7ICsraXRlcikgeworICAgIG91dHB1dF9maWxlbmFtZXMtPnB1c2hfYmFjayhpdGVyLT5maXJzdCk7CisgIH0KK30KKworaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6Ok9wZW4oCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gbmV3IE1lbW9yeU91dHB1dFN0cmVhbSh0aGlzLCBmaWxlbmFtZSwgZmFsc2UpOworfQorCitpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qCitDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6Ok9wZW5Gb3JBcHBlbmQoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gbmV3IE1lbW9yeU91dHB1dFN0cmVhbSh0aGlzLCBmaWxlbmFtZSwgdHJ1ZSk7Cit9CisKK2lvOjpaZXJvQ29weU91dHB1dFN0cmVhbSoKK0NvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0b3JDb250ZXh0SW1wbDo6T3BlbkZvckluc2VydCgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCkgeworICByZXR1cm4gbmV3IE1lbW9yeU91dHB1dFN0cmVhbSh0aGlzLCBmaWxlbmFtZSwgaW5zZXJ0aW9uX3BvaW50KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitDb21tYW5kTGluZUludGVyZmFjZTo6TWVtb3J5T3V0cHV0U3RyZWFtOjpNZW1vcnlPdXRwdXRTdHJlYW0oCisgICAgR2VuZXJhdG9yQ29udGV4dEltcGwqIGRpcmVjdG9yeSwgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgYm9vbCBhcHBlbmRfbW9kZSkKKyAgICA6IGRpcmVjdG9yeV8oZGlyZWN0b3J5KSwKKyAgICAgIGZpbGVuYW1lXyhmaWxlbmFtZSksCisgICAgICBhcHBlbmRfbW9kZV8oYXBwZW5kX21vZGUpLAorICAgICAgaW5uZXJfKG5ldyBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtKCZkYXRhXykpIHsKK30KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6Ok1lbW9yeU91dHB1dFN0cmVhbTo6TWVtb3J5T3V0cHV0U3RyZWFtKAorICAgIEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnksIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQpCisgICAgOiBkaXJlY3RvcnlfKGRpcmVjdG9yeSksCisgICAgICBmaWxlbmFtZV8oZmlsZW5hbWUpLAorICAgICAgaW5zZXJ0aW9uX3BvaW50XyhpbnNlcnRpb25fcG9pbnQpLAorICAgICAgaW5uZXJfKG5ldyBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtKCZkYXRhXykpIHsKK30KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6Ok1lbW9yeU91dHB1dFN0cmVhbTo6fk1lbW9yeU91dHB1dFN0cmVhbSgpIHsKKyAgLy8gTWFrZSBzdXJlIGFsbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4uCisgIGlubmVyXy5yZXNldCgpOworCisgIC8vIEluc2VydCBpbnRvIHRoZSBkaXJlY3RvcnkuCisgIHN0cmluZyoqIG1hcF9zbG90ID0gJmRpcmVjdG9yeV8tPmZpbGVzX1tmaWxlbmFtZV9dOworCisgIGlmIChpbnNlcnRpb25fcG9pbnRfLmVtcHR5KCkpIHsKKyAgICAvLyBUaGlzIHdhcyBqdXN0IGEgcmVndWxhciBPcGVuKCkuCisgICAgaWYgKCptYXBfc2xvdCAhPSBOVUxMKSB7CisgICAgICBpZiAoYXBwZW5kX21vZGVfKSB7CisgICAgICAgICgqbWFwX3Nsb3QpLT5hcHBlbmQoZGF0YV8pOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8IGZpbGVuYW1lXyA8PCAiOiBUcmllZCB0byB3cml0ZSB0aGUgc2FtZSBmaWxlIHR3aWNlLiIKKyAgICAgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgZGlyZWN0b3J5Xy0+aGFkX2Vycm9yXyA9IHRydWU7CisgICAgICB9CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgKm1hcF9zbG90ID0gbmV3IHN0cmluZzsKKyAgICAoKm1hcF9zbG90KS0+c3dhcChkYXRhXyk7CisgIH0gZWxzZSB7CisgICAgLy8gVGhpcyB3YXMgYW4gT3BlbkZvckluc2VydCgpLgorCisgICAgLy8gSWYgdGhlIGRhdGEgZG9lbnMndCBlbmQgd2l0aCBhIGNsZWFuIGxpbmUgYnJlYWssIGFkZCBvbmUuCisgICAgaWYgKCFkYXRhXy5lbXB0eSgpICYmIGRhdGFfW2RhdGFfLnNpemUoKSAtIDFdICE9ICdcbicpIHsKKyAgICAgIGRhdGFfLnB1c2hfYmFjaygnXG4nKTsKKyAgICB9CisKKyAgICAvLyBGaW5kIHRoZSBmaWxlIHdlIGFyZSBnb2luZyB0byBpbnNlcnQgaW50by4KKyAgICBpZiAoKm1hcF9zbG90ID09IE5VTEwpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZV8KKyAgICAgICAgICAgICAgICA8PCAiOiBUcmllZCB0byBpbnNlcnQgaW50byBmaWxlIHRoYXQgZG9lc24ndCBleGlzdC4iCisgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgICAgZGlyZWN0b3J5Xy0+aGFkX2Vycm9yXyA9IHRydWU7CisgICAgICByZXR1cm47CisgICAgfQorICAgIHN0cmluZyogdGFyZ2V0ID0gKm1hcF9zbG90OworCisgICAgLy8gRmluZCB0aGUgaW5zZXJ0aW9uIHBvaW50LgorICAgIHN0cmluZyBtYWdpY19zdHJpbmcgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAiQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KCQwKSIsIGluc2VydGlvbl9wb2ludF8pOworICAgIHN0cmluZzo6c2l6ZV90eXBlIHBvcyA9IHRhcmdldC0+ZmluZChtYWdpY19zdHJpbmcpOworCisgICAgaWYgKHBvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZV8gPDwgIjogaW5zZXJ0aW9uIHBvaW50IFwiIiA8PCBpbnNlcnRpb25fcG9pbnRfCisgICAgICAgICAgICAgICAgPDwgIlwiIG5vdCBmb3VuZC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIGRpcmVjdG9yeV8tPmhhZF9lcnJvcl8gPSB0cnVlOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIFNlZWsgYmFja3dhcmRzIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpbmUsIHdoaWNoIGlzIHdoZXJlIHdlIHdpbGwKKyAgICAvLyBpbnNlcnQgdGhlIGRhdGEuICBOb3RlIHRoYXQgdGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBwdXNoaW5nIHRoZSBpbnNlcnRpb24KKyAgICAvLyBwb2ludCBkb3duLCBzbyB0aGUgZGF0YSBpcyBpbnNlcnRlZCBiZWZvcmUgaXQuICBUaGlzIGlzIGludGVudGlvbmFsCisgICAgLy8gYmVjYXVzZSBpdCBtZWFucyB0aGF0IG11bHRpcGxlIGluc2VydGlvbnMgYXQgdGhlIHNhbWUgcG9pbnQgd2lsbCBlbmQKKyAgICAvLyB1cCBpbiB0aGUgZXhwZWN0ZWQgb3JkZXIgaW4gdGhlIGZpbmFsIG91dHB1dC4KKyAgICBwb3MgPSB0YXJnZXQtPmZpbmRfbGFzdF9vZignXG4nLCBwb3MpOworICAgIGlmIChwb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICAvLyBJbnNlcnRpb24gcG9pbnQgaXMgb24gdGhlIGZpcnN0IGxpbmUuCisgICAgICBwb3MgPSAwOworICAgIH0gZWxzZSB7CisgICAgICAvLyBBZHZhbmNlIHRvIGNoYXJhY3RlciBhZnRlciAnXG4nLgorICAgICAgKytwb3M7CisgICAgfQorCisgICAgLy8gRXh0cmFjdCBpbmRlbnQuCisgICAgc3RyaW5nIGluZGVudF8oKnRhcmdldCwgcG9zLCB0YXJnZXQtPmZpbmRfZmlyc3Rfbm90X29mKCIgXHQiLCBwb3MpIC0gcG9zKTsKKworICAgIGlmIChpbmRlbnRfLmVtcHR5KCkpIHsKKyAgICAgIC8vIE5vIGluZGVudC4gIFRoaXMgbWFrZXMgdGhpbmdzIGVhc2llci4KKyAgICAgIHRhcmdldC0+aW5zZXJ0KHBvcywgZGF0YV8pOworICAgIH0gZWxzZSB7CisgICAgICAvLyBDYWxjdWxhdGUgaG93IG11Y2ggc3BhY2Ugd2UgbmVlZC4KKyAgICAgIGludCBpbmRlbnRfc2l6ZSA9IDA7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGFfLnNpemUoKTsgaSsrKSB7CisgICAgICAgIGlmIChkYXRhX1tpXSA9PSAnXG4nKSBpbmRlbnRfc2l6ZSArPSBpbmRlbnRfLnNpemUoKTsKKyAgICAgIH0KKworICAgICAgLy8gTWFrZSBhIGhvbGUgZm9yIGl0LgorICAgICAgdGFyZ2V0LT5pbnNlcnQocG9zLCBkYXRhXy5zaXplKCkgKyBpbmRlbnRfc2l6ZSwgJ1wwJyk7CisKKyAgICAgIC8vIE5vdyBjb3B5IGluIHRoZSBkYXRhLgorICAgICAgc3RyaW5nOjpzaXplX3R5cGUgZGF0YV9wb3MgPSAwOworICAgICAgY2hhciogdGFyZ2V0X3B0ciA9IHN0cmluZ19hc19hcnJheSh0YXJnZXQpICsgcG9zOworICAgICAgd2hpbGUgKGRhdGFfcG9zIDwgZGF0YV8uc2l6ZSgpKSB7CisgICAgICAgIC8vIENvcHkgaW5kZW50LgorICAgICAgICBtZW1jcHkodGFyZ2V0X3B0ciwgaW5kZW50Xy5kYXRhKCksIGluZGVudF8uc2l6ZSgpKTsKKyAgICAgICAgdGFyZ2V0X3B0ciArPSBpbmRlbnRfLnNpemUoKTsKKworICAgICAgICAvLyBDb3B5IGxpbmUgZnJvbSBkYXRhXy4KKyAgICAgICAgLy8gV2UgYWxyZWFkeSBndWFyYW50ZWVkIHRoYXQgZGF0YV8gZW5kcyB3aXRoIGEgbmV3bGluZSAoYWJvdmUpLCBzbyB0aGlzCisgICAgICAgIC8vIHNlYXJjaCBjYW4ndCBmYWlsLgorICAgICAgICBzdHJpbmc6OnNpemVfdHlwZSBsaW5lX2xlbmd0aCA9CisgICAgICAgICAgICBkYXRhXy5maW5kX2ZpcnN0X29mKCdcbicsIGRhdGFfcG9zKSArIDEgLSBkYXRhX3BvczsKKyAgICAgICAgbWVtY3B5KHRhcmdldF9wdHIsIGRhdGFfLmRhdGEoKSArIGRhdGFfcG9zLCBsaW5lX2xlbmd0aCk7CisgICAgICAgIHRhcmdldF9wdHIgKz0gbGluZV9sZW5ndGg7CisgICAgICAgIGRhdGFfcG9zICs9IGxpbmVfbGVuZ3RoOworICAgICAgfQorCisgICAgICBHT09HTEVfQ0hFQ0tfRVEodGFyZ2V0X3B0ciwKKyAgICAgICAgICBzdHJpbmdfYXNfYXJyYXkodGFyZ2V0KSArIHBvcyArIGRhdGFfLnNpemUoKSArIGluZGVudF9zaXplKTsKKyAgICB9CisgIH0KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitDb21tYW5kTGluZUludGVyZmFjZTo6Q29tbWFuZExpbmVJbnRlcmZhY2UoKQorICA6IG1vZGVfKE1PREVfQ09NUElMRSksCisgICAgcHJpbnRfbW9kZV8oUFJJTlRfTk9ORSksCisgICAgZXJyb3JfZm9ybWF0XyhFUlJPUl9GT1JNQVRfR0NDKSwKKyAgICBpbXBvcnRzX2luX2Rlc2NyaXB0b3Jfc2V0XyhmYWxzZSksCisgICAgc291cmNlX2luZm9faW5fZGVzY3JpcHRvcl9zZXRfKGZhbHNlKSwKKyAgICBkaXNhbGxvd19zZXJ2aWNlc18oZmFsc2UpLAorICAgIGlucHV0c19hcmVfcHJvdG9fcGF0aF9yZWxhdGl2ZV8oZmFsc2UpIHt9CitDb21tYW5kTGluZUludGVyZmFjZTo6fkNvbW1hbmRMaW5lSW50ZXJmYWNlKCkge30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6UmVnaXN0ZXJHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBmbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGhlbHBfdGV4dCkgeworICBHZW5lcmF0b3JJbmZvIGluZm87CisgIGluZm8uZmxhZ19uYW1lID0gZmxhZ19uYW1lOworICBpbmZvLmdlbmVyYXRvciA9IGdlbmVyYXRvcjsKKyAgaW5mby5oZWxwX3RleHQgPSBoZWxwX3RleHQ7CisgIGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lX1tmbGFnX25hbWVdID0gaW5mbzsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6UmVnaXN0ZXJHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBmbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9mbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGhlbHBfdGV4dCkgeworICBHZW5lcmF0b3JJbmZvIGluZm87CisgIGluZm8uZmxhZ19uYW1lID0gZmxhZ19uYW1lOworICBpbmZvLm9wdGlvbl9mbGFnX25hbWUgPSBvcHRpb25fZmxhZ19uYW1lOworICBpbmZvLmdlbmVyYXRvciA9IGdlbmVyYXRvcjsKKyAgaW5mby5oZWxwX3RleHQgPSBoZWxwX3RleHQ7CisgIGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lX1tmbGFnX25hbWVdID0gaW5mbzsKKyAgZ2VuZXJhdG9yc19ieV9vcHRpb25fbmFtZV9bb3B0aW9uX2ZsYWdfbmFtZV0gPSBpbmZvOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpBbGxvd1BsdWdpbnMoY29uc3Qgc3RyaW5nJiBleGVfbmFtZV9wcmVmaXgpIHsKKyAgcGx1Z2luX3ByZWZpeF8gPSBleGVfbmFtZV9wcmVmaXg7Cit9CisKK2ludCBDb21tYW5kTGluZUludGVyZmFjZTo6UnVuKGludCBhcmdjLCBjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pIHsKKyAgQ2xlYXIoKTsKKyAgc3dpdGNoIChQYXJzZUFyZ3VtZW50cyhhcmdjLCBhcmd2KSkgeworICAgIGNhc2UgUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfRVhJVDoKKyAgICAgIHJldHVybiAwOworICAgIGNhc2UgUEFSU0VfQVJHVU1FTlRfRkFJTDoKKyAgICAgIHJldHVybiAxOworICAgIGNhc2UgUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfQ09OVElOVUU6CisgICAgICBicmVhazsKKyAgfQorCisgIC8vIFNldCB1cCB0aGUgc291cmNlIHRyZWUuCisgIERpc2tTb3VyY2VUcmVlIHNvdXJjZV90cmVlOworICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvX3BhdGhfLnNpemUoKTsgaSsrKSB7CisgICAgc291cmNlX3RyZWUuTWFwUGF0aChwcm90b19wYXRoX1tpXS5maXJzdCwgcHJvdG9fcGF0aF9baV0uc2Vjb25kKTsKKyAgfQorCisgIC8vIE1hcCBpbnB1dCBmaWxlcyB0byB2aXJ0dWFsIHBhdGhzIGlmIG5lY2Vzc2FyeS4KKyAgaWYgKCFpbnB1dHNfYXJlX3Byb3RvX3BhdGhfcmVsYXRpdmVfKSB7CisgICAgaWYgKCFNYWtlSW5wdXRzQmVQcm90b1BhdGhSZWxhdGl2ZSgmc291cmNlX3RyZWUpKSB7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKworICAvLyBBbGxvY2F0ZSB0aGUgSW1wb3J0ZXIuCisgIEVycm9yUHJpbnRlciBlcnJvcl9jb2xsZWN0b3IoZXJyb3JfZm9ybWF0XywgJnNvdXJjZV90cmVlKTsKKyAgSW1wb3J0ZXIgaW1wb3J0ZXIoJnNvdXJjZV90cmVlLCAmZXJyb3JfY29sbGVjdG9yKTsKKworICB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBwYXJzZWRfZmlsZXM7CisKKyAgLy8gUGFyc2UgZWFjaCBmaWxlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0X2ZpbGVzXy5zaXplKCk7IGkrKykgeworICAgIC8vIEltcG9ydCB0aGUgZmlsZS4KKyAgICBpbXBvcnRlci5BZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoaW5wdXRfZmlsZXNfW2ldKTsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogcGFyc2VkX2ZpbGUgPSBpbXBvcnRlci5JbXBvcnQoaW5wdXRfZmlsZXNfW2ldKTsKKyAgICBpbXBvcnRlci5DbGVhclVudXNlZEltcG9ydFRyYWNrRmlsZXMoKTsKKyAgICBpZiAocGFyc2VkX2ZpbGUgPT0gTlVMTCkgcmV0dXJuIDE7CisgICAgcGFyc2VkX2ZpbGVzLnB1c2hfYmFjayhwYXJzZWRfZmlsZSk7CisKKyAgICAvLyBFbmZvcmNlIC0tZGlzYWxsb3dfc2VydmljZXMuCisgICAgaWYgKGRpc2FsbG93X3NlcnZpY2VzXyAmJiBwYXJzZWRfZmlsZS0+c2VydmljZV9jb3VudCgpID4gMCkgeworICAgICAgY2VyciA8PCBwYXJzZWRfZmlsZS0+bmFtZSgpIDw8ICI6IFRoaXMgZmlsZSBjb250YWlucyBzZXJ2aWNlcywgYnV0ICIKKyAgICAgICAgICAgICAgIi0tZGlzYWxsb3dfc2VydmljZXMgd2FzIHVzZWQuIiA8PCBlbmRsOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisKKyAgLy8gV2UgY29uc3RydWN0IGEgc2VwYXJhdGUgR2VuZXJhdG9yQ29udGV4dCBmb3IgZWFjaCBvdXRwdXQgbG9jYXRpb24uICBOb3RlCisgIC8vIHRoYXQgdHdvIGNvZGUgZ2VuZXJhdG9ycyBtYXkgb3V0cHV0IHRvIHRoZSBzYW1lIGxvY2F0aW9uLCBpbiB3aGljaCBjYXNlCisgIC8vIHRoZXkgc2hvdWxkIHNoYXJlIGEgc2luZ2xlIEdlbmVyYXRvckNvbnRleHQgc28gdGhhdCBPcGVuRm9ySW5zZXJ0KCkgd29ya3MuCisgIEdlbmVyYXRvckNvbnRleHRNYXAgb3V0cHV0X2RpcmVjdG9yaWVzOworCisgIC8vIEdlbmVyYXRlIG91dHB1dC4KKyAgaWYgKG1vZGVfID09IE1PREVfQ09NUElMRSkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb3V0cHV0X2RpcmVjdGl2ZXNfLnNpemUoKTsgaSsrKSB7CisgICAgICBzdHJpbmcgb3V0cHV0X2xvY2F0aW9uID0gb3V0cHV0X2RpcmVjdGl2ZXNfW2ldLm91dHB1dF9sb2NhdGlvbjsKKyAgICAgIGlmICghSGFzU3VmZml4U3RyaW5nKG91dHB1dF9sb2NhdGlvbiwgIi56aXAiKSAmJgorICAgICAgICAgICFIYXNTdWZmaXhTdHJpbmcob3V0cHV0X2xvY2F0aW9uLCAiLmphciIpKSB7CisgICAgICAgIEFkZFRyYWlsaW5nU2xhc2goJm91dHB1dF9sb2NhdGlvbik7CisgICAgICB9CisgICAgICBHZW5lcmF0b3JDb250ZXh0SW1wbCoqIG1hcF9zbG90ID0gJm91dHB1dF9kaXJlY3Rvcmllc1tvdXRwdXRfbG9jYXRpb25dOworCisgICAgICBpZiAoKm1hcF9zbG90ID09IE5VTEwpIHsKKyAgICAgICAgLy8gRmlyc3QgdGltZSB3ZSd2ZSBzZWVuIHRoaXMgb3V0cHV0IGxvY2F0aW9uLgorICAgICAgICAqbWFwX3Nsb3QgPSBuZXcgR2VuZXJhdG9yQ29udGV4dEltcGwocGFyc2VkX2ZpbGVzKTsKKyAgICAgIH0KKworICAgICAgaWYgKCFHZW5lcmF0ZU91dHB1dChwYXJzZWRfZmlsZXMsIG91dHB1dF9kaXJlY3RpdmVzX1tpXSwgKm1hcF9zbG90KSkgeworICAgICAgICBTVExEZWxldGVWYWx1ZXMoJm91dHB1dF9kaXJlY3Rvcmllcyk7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFdyaXRlIGFsbCBvdXRwdXQgdG8gZGlzay4KKyAgZm9yIChHZW5lcmF0b3JDb250ZXh0TWFwOjppdGVyYXRvciBpdGVyID0gb3V0cHV0X2RpcmVjdG9yaWVzLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBvdXRwdXRfZGlyZWN0b3JpZXMuZW5kKCk7ICsraXRlcikgeworICAgIGNvbnN0IHN0cmluZyYgbG9jYXRpb24gPSBpdGVyLT5maXJzdDsKKyAgICBHZW5lcmF0b3JDb250ZXh0SW1wbCogZGlyZWN0b3J5ID0gaXRlci0+c2Vjb25kOworICAgIGlmIChIYXNTdWZmaXhTdHJpbmcobG9jYXRpb24sICIvIikpIHsKKyAgICAgIGlmICghZGlyZWN0b3J5LT5Xcml0ZUFsbFRvRGlzayhsb2NhdGlvbikpIHsKKyAgICAgICAgU1RMRGVsZXRlVmFsdWVzKCZvdXRwdXRfZGlyZWN0b3JpZXMpOworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKEhhc1N1ZmZpeFN0cmluZyhsb2NhdGlvbiwgIi5qYXIiKSkgeworICAgICAgICBkaXJlY3RvcnktPkFkZEphck1hbmlmZXN0KCk7CisgICAgICB9CisKKyAgICAgIGlmICghZGlyZWN0b3J5LT5Xcml0ZUFsbFRvWmlwKGxvY2F0aW9uKSkgeworICAgICAgICBTVExEZWxldGVWYWx1ZXMoJm91dHB1dF9kaXJlY3Rvcmllcyk7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmICghZGVwZW5kZW5jeV9vdXRfbmFtZV8uZW1wdHkoKSkgeworICAgIGlmICghR2VuZXJhdGVEZXBlbmRlbmN5TWFuaWZlc3RGaWxlKHBhcnNlZF9maWxlcywgb3V0cHV0X2RpcmVjdG9yaWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzb3VyY2VfdHJlZSkpIHsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorCisgIFNUTERlbGV0ZVZhbHVlcygmb3V0cHV0X2RpcmVjdG9yaWVzKTsKKworICBpZiAoIWRlc2NyaXB0b3Jfc2V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICBpZiAoIVdyaXRlRGVzY3JpcHRvclNldChwYXJzZWRfZmlsZXMpKSB7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKworICBpZiAobW9kZV8gPT0gTU9ERV9FTkNPREUgfHwgbW9kZV8gPT0gTU9ERV9ERUNPREUpIHsKKyAgICBpZiAoY29kZWNfdHlwZV8uZW1wdHkoKSkgeworICAgICAgLy8gSEFDSzogIERlZmluZSBhbiBFbXB0eU1lc3NhZ2UgdHlwZSB0byB1c2UgZm9yIGRlY29kaW5nLgorICAgICAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICAgIGZpbGUuc2V0X25hbWUoImVtcHR5X21lc3NhZ2UucHJvdG8iKTsKKyAgICAgIGZpbGUuYWRkX21lc3NhZ2VfdHlwZSgpLT5zZXRfbmFtZSgiRW1wdHlNZXNzYWdlIik7CisgICAgICBHT09HTEVfQ0hFQ0socG9vbC5CdWlsZEZpbGUoZmlsZSkgIT0gTlVMTCk7CisgICAgICBjb2RlY190eXBlXyA9ICJFbXB0eU1lc3NhZ2UiOworICAgICAgaWYgKCFFbmNvZGVPckRlY29kZSgmcG9vbCkpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGlmICghRW5jb2RlT3JEZWNvZGUoaW1wb3J0ZXIucG9vbCgpKSkgeworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAobW9kZV8gPT0gTU9ERV9QUklOVCkgeworICAgIHN3aXRjaCAocHJpbnRfbW9kZV8pIHsKKyAgICAgIGNhc2UgUFJJTlRfRlJFRV9GSUVMRFM6CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgKytpKSB7CisgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZkID0gcGFyc2VkX2ZpbGVzW2ldOworICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZmQtPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2opIHsKKyAgICAgICAgICAgIFByaW50RnJlZUZpZWxkTnVtYmVycyhmZC0+bWVzc2FnZV90eXBlKGopKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFBSSU5UX05PTkU6CisgICAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJJZiB0aGUgY29kZSByZWFjaGVzIGhlcmUsIGl0IHVzdWFsbHkgbWVhbnMgYSBidWcgb2YgIgorICAgICAgICAgICAgICAgICAgICAgImZsYWcgcGFyc2luZyBpbiB0aGUgQ29tbW9uYWRMaW5lSW50ZXJmYWNlLiI7CisgICAgICAgIHJldHVybiAxOworCisgICAgICAvLyBEbyBub3QgYWRkIGEgZGVmYXVsdCBjYXNlLgorICAgIH0KKyAgfQorCisgIHJldHVybiAwOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpDbGVhcigpIHsKKyAgLy8gQ2xlYXIgYWxsIG1lbWJlcnMgdGhhdCBhcmUgc2V0IGJ5IFJ1bigpLiAgTm90ZSB0aGF0IHdlIG11c3Qgbm90IGNsZWFyCisgIC8vIG1lbWJlcnMgd2hpY2ggYXJlIHNldCBieSBvdGhlciBtZXRob2RzIGJlZm9yZSBSdW4oKSBpcyBjYWxsZWQuCisgIGV4ZWN1dGFibGVfbmFtZV8uY2xlYXIoKTsKKyAgcHJvdG9fcGF0aF8uY2xlYXIoKTsKKyAgaW5wdXRfZmlsZXNfLmNsZWFyKCk7CisgIG91dHB1dF9kaXJlY3RpdmVzXy5jbGVhcigpOworICBjb2RlY190eXBlXy5jbGVhcigpOworICBkZXNjcmlwdG9yX3NldF9uYW1lXy5jbGVhcigpOworICBkZXBlbmRlbmN5X291dF9uYW1lXy5jbGVhcigpOworCisgIG1vZGVfID0gTU9ERV9DT01QSUxFOworICBwcmludF9tb2RlXyA9IFBSSU5UX05PTkU7CisgIGltcG9ydHNfaW5fZGVzY3JpcHRvcl9zZXRfID0gZmFsc2U7CisgIHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XyA9IGZhbHNlOworICBkaXNhbGxvd19zZXJ2aWNlc18gPSBmYWxzZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6TWFrZUlucHV0c0JlUHJvdG9QYXRoUmVsYXRpdmUoCisgICAgRGlza1NvdXJjZVRyZWUqIHNvdXJjZV90cmVlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXRfZmlsZXNfLnNpemUoKTsgaSsrKSB7CisgICAgc3RyaW5nIHZpcnR1YWxfZmlsZSwgc2hhZG93aW5nX2Rpc2tfZmlsZTsKKyAgICBzd2l0Y2ggKHNvdXJjZV90cmVlLT5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAgIGlucHV0X2ZpbGVzX1tpXSwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKSB7CisgICAgICBjYXNlIERpc2tTb3VyY2VUcmVlOjpTVUNDRVNTOgorICAgICAgICBpbnB1dF9maWxlc19baV0gPSB2aXJ0dWFsX2ZpbGU7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBEaXNrU291cmNlVHJlZTo6U0hBRE9XRUQ6CisgICAgICAgIHN0ZDo6Y2VyciA8PCBpbnB1dF9maWxlc19baV0KKyAgICAgICAgICAgICAgICAgIDw8ICI6IElucHV0IGlzIHNoYWRvd2VkIGluIHRoZSAtLXByb3RvX3BhdGggYnkgXCIiCisgICAgICAgICAgICAgICAgICA8PCBzaGFkb3dpbmdfZGlza19maWxlCisgICAgICAgICAgICAgICAgICA8PCAiXCIuICBFaXRoZXIgdXNlIHRoZSBsYXR0ZXIgZmlsZSBhcyB5b3VyIGlucHV0IG9yIHJlb3JkZXIgIgorICAgICAgICAgICAgICAgICAgICAgInRoZSAtLXByb3RvX3BhdGggc28gdGhhdCB0aGUgZm9ybWVyIGZpbGUncyBsb2NhdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICAiY29tZXMgZmlyc3QuIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGNhc2UgRGlza1NvdXJjZVRyZWU6OkNBTk5PVF9PUEVOOgorICAgICAgICBzdGQ6OmNlcnIgPDwgaW5wdXRfZmlsZXNfW2ldIDw8ICI6ICIgPDwgc3RyZXJyb3IoZXJybm8pIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgY2FzZSBEaXNrU291cmNlVHJlZTo6Tk9fTUFQUElORzoKKyAgICAgICAgLy8gRmlyc3QgY2hlY2sgaWYgdGhlIGZpbGUgZXhpc3RzIGF0IGFsbC4KKyAgICAgICAgaWYgKGFjY2VzcyhpbnB1dF9maWxlc19baV0uY19zdHIoKSwgRl9PSykgPCAwKSB7CisgICAgICAgICAgLy8gRmlsZSBkb2VzIG5vdCBldmVuIGV4aXN0LgorICAgICAgICAgIHN0ZDo6Y2VyciA8PCBpbnB1dF9maWxlc19baV0gPDwgIjogIiA8PCBzdHJlcnJvcihFTk9FTlQpIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzdGQ6OmNlcnIKKyAgICAgICAgICAgICAgPDwgaW5wdXRfZmlsZXNfW2ldCisgICAgICAgICAgICAgIDw8ICI6IEZpbGUgZG9lcyBub3QgcmVzaWRlIHdpdGhpbiBhbnkgcGF0aCAiCisgICAgICAgICAgICAgICAgICJzcGVjaWZpZWQgdXNpbmcgLS1wcm90b19wYXRoIChvciAtSSkuICBZb3UgbXVzdCBzcGVjaWZ5IGEgIgorICAgICAgICAgICAgICAgICAiLS1wcm90b19wYXRoIHdoaWNoIGVuY29tcGFzc2VzIHRoaXMgZmlsZS4gIE5vdGUgdGhhdCB0aGUgIgorICAgICAgICAgICAgICAgICAicHJvdG9fcGF0aCBtdXN0IGJlIGFuIGV4YWN0IHByZWZpeCBvZiB0aGUgLnByb3RvIGZpbGUgIgorICAgICAgICAgICAgICAgICAibmFtZXMgLS0gcHJvdG9jIGlzIHRvbyBkdW1iIHRvIGZpZ3VyZSBvdXQgd2hlbiB0d28gcGF0aHMgIgorICAgICAgICAgICAgICAgICAiKGUuZy4gYWJzb2x1dGUgYW5kIHJlbGF0aXZlKSBhcmUgZXF1aXZhbGVudCAoaXQncyBoYXJkZXIgIgorICAgICAgICAgICAgICAgICAidGhhbiB5b3UgdGhpbmspLiIgPDwgc3RkOjplbmRsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6OlBhcnNlQXJndW1lbnRTdGF0dXMKK0NvbW1hbmRMaW5lSW50ZXJmYWNlOjpQYXJzZUFyZ3VtZW50cyhpbnQgYXJnYywgY29uc3QgY2hhciogY29uc3QgYXJndltdKSB7CisgIGV4ZWN1dGFibGVfbmFtZV8gPSBhcmd2WzBdOworCisgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgYXJndW1lbnRzIGFuZCBwYXJzZSB0aGVtLgorICBmb3IgKGludCBpID0gMTsgaSA8IGFyZ2M7IGkrKykgeworICAgIHN0cmluZyBuYW1lLCB2YWx1ZTsKKworICAgIGlmIChQYXJzZUFyZ3VtZW50KGFyZ3ZbaV0sICZuYW1lLCAmdmFsdWUpKSB7CisgICAgICAvLyBSZXR1cm5lZCB0cnVlID0+IFVzZSB0aGUgbmV4dCBhcmd1bWVudCBhcyB0aGUgZmxhZyB2YWx1ZS4KKyAgICAgIGlmIChpICsgMSA9PSBhcmdjIHx8IGFyZ3ZbaSsxXVswXSA9PSAnLScpIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJNaXNzaW5nIHZhbHVlIGZvciBmbGFnOiAiIDw8IG5hbWUgPDwgc3RkOjplbmRsOworICAgICAgICBpZiAobmFtZSA9PSAiLS1kZWNvZGUiKSB7CisgICAgICAgICAgc3RkOjpjZXJyIDw8ICJUbyBkZWNvZGUgYW4gdW5rbm93biBtZXNzYWdlLCB1c2UgLS1kZWNvZGVfcmF3LiIKKyAgICAgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgKytpOworICAgICAgICB2YWx1ZSA9IGFyZ3ZbaV07CisgICAgICB9CisgICAgfQorCisgICAgUGFyc2VBcmd1bWVudFN0YXR1cyBzdGF0dXMgPSBJbnRlcnByZXRBcmd1bWVudChuYW1lLCB2YWx1ZSk7CisgICAgaWYgKHN0YXR1cyAhPSBQQVJTRV9BUkdVTUVOVF9ET05FX0FORF9DT05USU5VRSkKKyAgICAgIHJldHVybiBzdGF0dXM7CisgIH0KKworICAvLyBJZiBubyAtLXByb3RvX3BhdGggd2FzIGdpdmVuLCB1c2UgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuCisgIGlmIChwcm90b19wYXRoXy5lbXB0eSgpKSB7CisgICAgLy8gRG9uJ3QgdXNlIG1ha2VfcGFpciBhcyB0aGUgb2xkL2RlZmF1bHQgc3RhbmRhcmQgbGlicmFyeSBvbiBTb2xhcmlzCisgICAgLy8gZG9lc24ndCBzdXBwb3J0IGl0IHdpdGhvdXQgZXhwbGljaXQgdGVtcGxhdGUgcGFyYW1ldGVycywgd2hpY2ggYXJlCisgICAgLy8gaW5jb21wYXRpYmxlIHdpdGggQysrMHgncyBtYWtlX3BhaXIuCisgICAgcHJvdG9fcGF0aF8ucHVzaF9iYWNrKHBhaXI8c3RyaW5nLCBzdHJpbmc+KCIiLCAiLiIpKTsKKyAgfQorCisgIC8vIENoZWNrIHNvbWUgZXJycm9yIGNhc2VzLgorICBib29sIGRlY29kaW5nX3JhdyA9IChtb2RlXyA9PSBNT0RFX0RFQ09ERSkgJiYgY29kZWNfdHlwZV8uZW1wdHkoKTsKKyAgaWYgKGRlY29kaW5nX3JhdyAmJiAhaW5wdXRfZmlsZXNfLmVtcHR5KCkpIHsKKyAgICBzdGQ6OmNlcnIgPDwgIldoZW4gdXNpbmcgLS1kZWNvZGVfcmF3LCBubyBpbnB1dCBmaWxlcyBzaG91bGQgYmUgZ2l2ZW4uIgorICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgIH0gZWxzZSBpZiAoIWRlY29kaW5nX3JhdyAmJiBpbnB1dF9maWxlc18uZW1wdHkoKSkgeworICAgIHN0ZDo6Y2VyciA8PCAiTWlzc2luZyBpbnB1dCBmaWxlLiIgPDwgc3RkOjplbmRsOworICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICB9CisgIGlmIChtb2RlXyA9PSBNT0RFX0NPTVBJTEUgJiYgb3V0cHV0X2RpcmVjdGl2ZXNfLmVtcHR5KCkgJiYKKyAgICAgIGRlc2NyaXB0b3Jfc2V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICBzdGQ6OmNlcnIgPDwgIk1pc3Npbmcgb3V0cHV0IGRpcmVjdGl2ZXMuIiA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgIH0KKyAgaWYgKG1vZGVfICE9IE1PREVfQ09NUElMRSAmJiAhZGVwZW5kZW5jeV9vdXRfbmFtZV8uZW1wdHkoKSkgeworICAgIGNlcnIgPDwgIkNhbiBvbmx5IHVzZSAtLWRlcGVuZGVuY3lfb3V0PUZJTEUgd2hlbiBnZW5lcmF0aW5nIGNvZGUuIiA8PCBlbmRsOworICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICB9CisgIGlmICghZGVwZW5kZW5jeV9vdXRfbmFtZV8uZW1wdHkoKSAmJiBpbnB1dF9maWxlc18uc2l6ZSgpID4gMSkgeworICAgIGNlcnIgPDwgIkNhbiBvbmx5IHByb2Nlc3Mgb25lIGlucHV0IGZpbGUgd2hlbiB1c2luZyAtLWRlcGVuZGVuY3lfb3V0PUZJTEUuIgorICAgICAgICAgPDwgZW5kbDsKKyAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgfQorICBpZiAoaW1wb3J0c19pbl9kZXNjcmlwdG9yX3NldF8gJiYgZGVzY3JpcHRvcl9zZXRfbmFtZV8uZW1wdHkoKSkgeworICAgIHN0ZDo6Y2VyciA8PCAiLS1pbmNsdWRlX2ltcG9ydHMgb25seSBtYWtlcyBzZW5zZSB3aGVuIGNvbWJpbmVkIHdpdGggIgorICAgICAgICAgICAgICAgICAiLS1kZXNjcmlwdG9yX3NldF9vdXQuIiA8PCBzdGQ6OmVuZGw7CisgIH0KKyAgaWYgKHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XyAmJiBkZXNjcmlwdG9yX3NldF9uYW1lXy5lbXB0eSgpKSB7CisgICAgc3RkOjpjZXJyIDw8ICItLWluY2x1ZGVfc291cmNlX2luZm8gb25seSBtYWtlcyBzZW5zZSB3aGVuIGNvbWJpbmVkIHdpdGggIgorICAgICAgICAgICAgICAgICAiLS1kZXNjcmlwdG9yX3NldF9vdXQuIiA8PCBzdGQ6OmVuZGw7CisgIH0KKworICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfQ09OVElOVUU7Cit9CisKK2Jvb2wgQ29tbWFuZExpbmVJbnRlcmZhY2U6OlBhcnNlQXJndW1lbnQoY29uc3QgY2hhciogYXJnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIG5hbWUsIHN0cmluZyogdmFsdWUpIHsKKyAgYm9vbCBwYXJzZWRfdmFsdWUgPSBmYWxzZTsKKworICBpZiAoYXJnWzBdICE9ICctJykgeworICAgIC8vIE5vdCBhIGZsYWcuCisgICAgbmFtZS0+Y2xlYXIoKTsKKyAgICBwYXJzZWRfdmFsdWUgPSB0cnVlOworICAgICp2YWx1ZSA9IGFyZzsKKyAgfSBlbHNlIGlmIChhcmdbMV0gPT0gJy0nKSB7CisgICAgLy8gVHdvIGRhc2hlczogIE11bHRpLWNoYXJhY3RlciBuYW1lLCB3aXRoICc9JyBzZXBhcmF0aW5nIG5hbWUgYW5kCisgICAgLy8gICB2YWx1ZS4KKyAgICBjb25zdCBjaGFyKiBlcXVhbHNfcG9zID0gc3RyY2hyKGFyZywgJz0nKTsKKyAgICBpZiAoZXF1YWxzX3BvcyAhPSBOVUxMKSB7CisgICAgICAqbmFtZSA9IHN0cmluZyhhcmcsIGVxdWFsc19wb3MgLSBhcmcpOworICAgICAgKnZhbHVlID0gZXF1YWxzX3BvcyArIDE7CisgICAgICBwYXJzZWRfdmFsdWUgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAqbmFtZSA9IGFyZzsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gT25lIGRhc2g6ICBPbmUtY2hhcmFjdGVyIG5hbWUsIGFsbCBzdWJzZXF1ZW50IGNoYXJhY3RlcnMgYXJlIHRoZQorICAgIC8vICAgdmFsdWUuCisgICAgaWYgKGFyZ1sxXSA9PSAnXDAnKSB7CisgICAgICAvLyBhcmcgaXMganVzdCAiLSIuICBXZSB0cmVhdCB0aGlzIGFzIGFuIGlucHV0IGZpbGUsIGV4Y2VwdCB0aGF0IGF0CisgICAgICAvLyBwcmVzZW50IHRoaXMgd2lsbCBqdXN0IGxlYWQgdG8gYSAiZmlsZSBub3QgZm91bmQiIGVycm9yLgorICAgICAgbmFtZS0+Y2xlYXIoKTsKKyAgICAgICp2YWx1ZSA9IGFyZzsKKyAgICAgIHBhcnNlZF92YWx1ZSA9IHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgICpuYW1lID0gc3RyaW5nKGFyZywgMik7CisgICAgICAqdmFsdWUgPSBhcmcgKyAyOworICAgICAgcGFyc2VkX3ZhbHVlID0gIXZhbHVlLT5lbXB0eSgpOworICAgIH0KKyAgfQorCisgIC8vIE5lZWQgdG8gcmV0dXJuIHRydWUgaWZmIHRoZSBuZXh0IGFyZyBzaG91bGQgYmUgdXNlZCBhcyB0aGUgdmFsdWUgZm9yIHRoaXMKKyAgLy8gb25lLCBmYWxzZSBvdGhlcndpc2UuCisKKyAgaWYgKHBhcnNlZF92YWx1ZSkgeworICAgIC8vIFdlIGFscmVhZHkgcGFyc2VkIGEgdmFsdWUgZm9yIHRoaXMgZmxhZy4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoKm5hbWUgPT0gIi1oIiB8fCAqbmFtZSA9PSAiLS1oZWxwIiB8fAorICAgICAgKm5hbWUgPT0gIi0tZGlzYWxsb3dfc2VydmljZXMiIHx8CisgICAgICAqbmFtZSA9PSAiLS1pbmNsdWRlX2ltcG9ydHMiIHx8CisgICAgICAqbmFtZSA9PSAiLS1pbmNsdWRlX3NvdXJjZV9pbmZvIiB8fAorICAgICAgKm5hbWUgPT0gIi0tdmVyc2lvbiIgfHwKKyAgICAgICpuYW1lID09ICItLWRlY29kZV9yYXciIHx8CisgICAgICAqbmFtZSA9PSAiLS1wcmludF9mcmVlX2ZpZWxkX251bWJlcnMiKSB7CisgICAgLy8gSEFDSzogIFRoZXNlIGFyZSB0aGUgb25seSBmbGFncyB0aGF0IGRvbid0IHRha2UgYSB2YWx1ZS4KKyAgICAvLyAgIFRoZXkgcHJvYmFibHkgc2hvdWxkIG5vdCBiZSBoYXJkLWNvZGVkIGxpa2UgdGhpcyBidXQgZm9yIG5vdyBpdCdzCisgICAgLy8gICBub3Qgd29ydGggZG9pbmcgYmV0dGVyLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIE5leHQgYXJndW1lbnQgaXMgdGhlIGZsYWcgdmFsdWUuCisgIHJldHVybiB0cnVlOworfQorCitDb21tYW5kTGluZUludGVyZmFjZTo6UGFyc2VBcmd1bWVudFN0YXR1cworQ29tbWFuZExpbmVJbnRlcmZhY2U6OkludGVycHJldEFyZ3VtZW50KGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIGlmIChuYW1lLmVtcHR5KCkpIHsKKyAgICAvLyBOb3QgYSBmbGFnLiAgSnVzdCBhIGZpbGVuYW1lLgorICAgIGlmICh2YWx1ZS5lbXB0eSgpKSB7CisgICAgICBzdGQ6OmNlcnIKKyAgICAgICAgICA8PCAiWW91IHNlZW0gdG8gaGF2ZSBwYXNzZWQgYW4gZW1wdHkgc3RyaW5nIGFzIG9uZSBvZiB0aGUgIgorICAgICAgICAgICAgICJhcmd1bWVudHMgdG8gIiA8PCBleGVjdXRhYmxlX25hbWVfCisgICAgICAgICAgPDwgIi4gIFRoaXMgaXMgYWN0dWFsbHkgIgorICAgICAgICAgICAgICJzb3J0IG9mIGhhcmQgdG8gZG8uICBDb25ncmF0cy4gIFVuZm9ydHVuYXRlbHkgaXQgaXMgbm90IHZhbGlkICIKKyAgICAgICAgICAgICAiaW5wdXQgc28gdGhlIHByb2dyYW0gaXMgZ29pbmcgdG8gZGllIG5vdy4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKworICAgIGlucHV0X2ZpbGVzXy5wdXNoX2JhY2sodmFsdWUpOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLUkiIHx8IG5hbWUgPT0gIi0tcHJvdG9fcGF0aCIpIHsKKyAgICAvLyBKYXZhJ3MgLWNsYXNzcGF0aCAoYW5kIHNvbWUgb3RoZXIgbGFuZ3VhZ2VzKSBkZWxpbWl0cyBwYXRoIGNvbXBvbmVudHMKKyAgICAvLyB3aXRoIGNvbG9ucy4gIExldCdzIGFjY2VwdCB0aGF0IHN5bnRheCB0b28ganVzdCB0byBtYWtlIHRoaW5ncyBtb3JlCisgICAgLy8gaW50dWl0aXZlLgorICAgIHZlY3RvcjxzdHJpbmc+IHBhcnRzID0gU3BsaXQoCisgICAgICAgIHZhbHVlLCBrUGF0aFNlcGFyYXRvciwgdHJ1ZSk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLnNpemUoKTsgaSsrKSB7CisgICAgICBzdHJpbmcgdmlydHVhbF9wYXRoOworICAgICAgc3RyaW5nIGRpc2tfcGF0aDsKKworICAgICAgc3RyaW5nOjpzaXplX3R5cGUgZXF1YWxzX3BvcyA9IHBhcnRzW2ldLmZpbmRfZmlyc3Rfb2YoJz0nKTsKKyAgICAgIGlmIChlcXVhbHNfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgICB2aXJ0dWFsX3BhdGggPSAiIjsKKyAgICAgICAgZGlza19wYXRoID0gcGFydHNbaV07CisgICAgICB9IGVsc2UgeworICAgICAgICB2aXJ0dWFsX3BhdGggPSBwYXJ0c1tpXS5zdWJzdHIoMCwgZXF1YWxzX3Bvcyk7CisgICAgICAgIGRpc2tfcGF0aCA9IHBhcnRzW2ldLnN1YnN0cihlcXVhbHNfcG9zICsgMSk7CisgICAgICB9CisKKyAgICAgIGlmIChkaXNrX3BhdGguZW1wdHkoKSkgeworICAgICAgICBzdGQ6OmNlcnIKKyAgICAgICAgICAgIDw8ICItLXByb3RvX3BhdGggcGFzc2VkIGVtcHR5IGRpcmVjdG9yeSBuYW1lLiAgKFVzZSBcIi5cIiBmb3IgIgorICAgICAgICAgICAgICAgImN1cnJlbnQgZGlyZWN0b3J5LikiIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgICB9CisKKyAgICAgIC8vIE1ha2Ugc3VyZSBkaXNrIHBhdGggZXhpc3RzLCB3YXJuIG90aGVyd2lzZS4KKyAgICAgIGlmIChhY2Nlc3MoZGlza19wYXRoLmNfc3RyKCksIEZfT0spIDwgMCkgeworICAgICAgICBzdGQ6OmNlcnIgPDwgZGlza19wYXRoIDw8ICI6IHdhcm5pbmc6IGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdC4iCisgICAgICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgICB9CisKKyAgICAgIC8vIERvbid0IHVzZSBtYWtlX3BhaXIgYXMgdGhlIG9sZC9kZWZhdWx0IHN0YW5kYXJkIGxpYnJhcnkgb24gU29sYXJpcworICAgICAgLy8gZG9lc24ndCBzdXBwb3J0IGl0IHdpdGhvdXQgZXhwbGljaXQgdGVtcGxhdGUgcGFyYW1ldGVycywgd2hpY2ggYXJlCisgICAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCBDKysweCdzIG1ha2VfcGFpci4KKyAgICAgIHByb3RvX3BhdGhfLnB1c2hfYmFjayhwYWlyPHN0cmluZywgc3RyaW5nPih2aXJ0dWFsX3BhdGgsIGRpc2tfcGF0aCkpOworICAgIH0KKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi1vIiB8fCBuYW1lID09ICItLWRlc2NyaXB0b3Jfc2V0X291dCIpIHsKKyAgICBpZiAoIWRlc2NyaXB0b3Jfc2V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgbWF5IG9ubHkgYmUgcGFzc2VkIG9uY2UuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaWYgKHZhbHVlLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgcmVxdWlyZXMgYSBub24tZW1wdHkgdmFsdWUuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaWYgKG1vZGVfICE9IE1PREVfQ09NUElMRSkgeworICAgICAgc3RkOjpjZXJyCisgICAgICAgICAgPDwgIkNhbm5vdCB1c2UgLS1lbmNvZGUgb3IgLS1kZWNvZGUgYW5kIGdlbmVyYXRlIGRlc2NyaXB0b3JzIGF0IHRoZSAiCisgICAgICAgICAgICAgInNhbWUgdGltZS4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBkZXNjcmlwdG9yX3NldF9uYW1lXyA9IHZhbHVlOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLS1kZXBlbmRlbmN5X291dCIpIHsKKyAgICBpZiAoIWRlcGVuZGVuY3lfb3V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICAgIGNlcnIgPDwgbmFtZSA8PCAiIG1heSBvbmx5IGJlIHBhc3NlZCBvbmNlLiIgPDwgZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBpZiAodmFsdWUuZW1wdHkoKSkgeworICAgICAgY2VyciA8PCBuYW1lIDw8ICIgcmVxdWlyZXMgYSBub24tZW1wdHkgdmFsdWUuIiA8PCBlbmRsOworICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfQorICAgIGRlcGVuZGVuY3lfb3V0X25hbWVfID0gdmFsdWU7CisKKyAgfSBlbHNlIGlmIChuYW1lID09ICItLWluY2x1ZGVfaW1wb3J0cyIpIHsKKyAgICBpZiAoaW1wb3J0c19pbl9kZXNjcmlwdG9yX3NldF8pIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgbWF5IG9ubHkgYmUgcGFzc2VkIG9uY2UuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaW1wb3J0c19pbl9kZXNjcmlwdG9yX3NldF8gPSB0cnVlOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLS1pbmNsdWRlX3NvdXJjZV9pbmZvIikgeworICAgIGlmIChzb3VyY2VfaW5mb19pbl9kZXNjcmlwdG9yX3NldF8pIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgbWF5IG9ubHkgYmUgcGFzc2VkIG9uY2UuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgc291cmNlX2luZm9faW5fZGVzY3JpcHRvcl9zZXRfID0gdHJ1ZTsKKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi1oIiB8fCBuYW1lID09ICItLWhlbHAiKSB7CisgICAgUHJpbnRIZWxwVGV4dCgpOworICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9ET05FX0FORF9FWElUOyAgLy8gRXhpdCB3aXRob3V0IHJ1bm5pbmcgY29tcGlsZXIuCisKKyAgfSBlbHNlIGlmIChuYW1lID09ICItLXZlcnNpb24iKSB7CisgICAgaWYgKCF2ZXJzaW9uX2luZm9fLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y291dCA8PCB2ZXJzaW9uX2luZm9fIDw8IHN0ZDo6ZW5kbDsKKyAgICB9CisgICAgY291dCA8PCAibGlicHJvdG9jICIKKyAgICAgICAgIDw8IHByb3RvYnVmOjppbnRlcm5hbDo6VmVyc2lvblN0cmluZyhHT09HTEVfUFJPVE9CVUZfVkVSU0lPTikKKyAgICAgICAgIDw8IGVuZGw7CisgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0RPTkVfQU5EX0VYSVQ7ICAvLyBFeGl0IHdpdGhvdXQgcnVubmluZyBjb21waWxlci4KKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi0tZGlzYWxsb3dfc2VydmljZXMiKSB7CisgICAgZGlzYWxsb3dfc2VydmljZXNfID0gdHJ1ZTsKKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi0tZW5jb2RlIiB8fCBuYW1lID09ICItLWRlY29kZSIgfHwKKyAgICAgICAgICAgICBuYW1lID09ICItLWRlY29kZV9yYXciKSB7CisgICAgaWYgKG1vZGVfICE9IE1PREVfQ09NUElMRSkgeworICAgICAgc3RkOjpjZXJyIDw8ICJPbmx5IG9uZSBvZiAtLWVuY29kZSBhbmQgLS1kZWNvZGUgY2FuIGJlIHNwZWNpZmllZC4iCisgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfQorICAgIGlmICghb3V0cHV0X2RpcmVjdGl2ZXNfLmVtcHR5KCkgfHwgIWRlc2NyaXB0b3Jfc2V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiQ2Fubm90IHVzZSAiIDw8IG5hbWUKKyAgICAgICAgICAgICAgICA8PCAiIGFuZCBnZW5lcmF0ZSBjb2RlIG9yIGRlc2NyaXB0b3JzIGF0IHRoZSBzYW1lIHRpbWUuIgorICAgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKworICAgIG1vZGVfID0gKG5hbWUgPT0gIi0tZW5jb2RlIikgPyBNT0RFX0VOQ09ERSA6IE1PREVfREVDT0RFOworCisgICAgaWYgKHZhbHVlLmVtcHR5KCkgJiYgbmFtZSAhPSAiLS1kZWNvZGVfcmF3IikgeworICAgICAgc3RkOjpjZXJyIDw8ICJUeXBlIG5hbWUgZm9yICIgPDwgbmFtZSA8PCAiIGNhbm5vdCBiZSBibGFuay4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIGlmIChuYW1lID09ICItLWRlY29kZSIpIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJUbyBkZWNvZGUgYW4gdW5rbm93biBtZXNzYWdlLCB1c2UgLS1kZWNvZGVfcmF3LiIKKyAgICAgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIH0KKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0gZWxzZSBpZiAoIXZhbHVlLmVtcHR5KCkgJiYgbmFtZSA9PSAiLS1kZWNvZGVfcmF3IikgeworICAgICAgc3RkOjpjZXJyIDw8ICItLWRlY29kZV9yYXcgZG9lcyBub3QgdGFrZSBhIHBhcmFtZXRlci4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKworICAgIGNvZGVjX3R5cGVfID0gdmFsdWU7CisKKyAgfSBlbHNlIGlmIChuYW1lID09ICItLWVycm9yX2Zvcm1hdCIpIHsKKyAgICBpZiAodmFsdWUgPT0gImdjYyIpIHsKKyAgICAgIGVycm9yX2Zvcm1hdF8gPSBFUlJPUl9GT1JNQVRfR0NDOworICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gIm1zdnMiKSB7CisgICAgICBlcnJvcl9mb3JtYXRfID0gRVJST1JfRk9STUFUX01TVlM7CisgICAgfSBlbHNlIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiVW5rbm93biBlcnJvciBmb3JtYXQ6ICIgPDwgdmFsdWUgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfQorCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLS1wbHVnaW4iKSB7CisgICAgaWYgKHBsdWdpbl9wcmVmaXhfLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiVGhpcyBjb21waWxlciBkb2VzIG5vdCBzdXBwb3J0IHBsdWdpbnMuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisKKyAgICBzdHJpbmcgcGx1Z2luX25hbWU7CisgICAgc3RyaW5nIHBhdGg7CisKKyAgICBzdHJpbmc6OnNpemVfdHlwZSBlcXVhbHNfcG9zID0gdmFsdWUuZmluZF9maXJzdF9vZignPScpOworICAgIGlmIChlcXVhbHNfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgLy8gVXNlIHRoZSBiYXNlbmFtZSBvZiB0aGUgZmlsZS4KKyAgICAgIHN0cmluZzo6c2l6ZV90eXBlIHNsYXNoX3BvcyA9IHZhbHVlLmZpbmRfbGFzdF9vZignLycpOworICAgICAgaWYgKHNsYXNoX3BvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgICAgcGx1Z2luX25hbWUgPSB2YWx1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHBsdWdpbl9uYW1lID0gdmFsdWUuc3Vic3RyKHNsYXNoX3BvcyArIDEpOworICAgICAgfQorICAgICAgcGF0aCA9IHZhbHVlOworICAgIH0gZWxzZSB7CisgICAgICBwbHVnaW5fbmFtZSA9IHZhbHVlLnN1YnN0cigwLCBlcXVhbHNfcG9zKTsKKyAgICAgIHBhdGggPSB2YWx1ZS5zdWJzdHIoZXF1YWxzX3BvcyArIDEpOworICAgIH0KKworICAgIHBsdWdpbnNfW3BsdWdpbl9uYW1lXSA9IHBhdGg7CisKKyAgfSBlbHNlIGlmIChuYW1lID09ICItLXByaW50X2ZyZWVfZmllbGRfbnVtYmVycyIpIHsKKyAgICBpZiAobW9kZV8gIT0gTU9ERV9DT01QSUxFKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIkNhbm5vdCB1c2UgIiA8PCBuYW1lCisgICAgICAgICAgICAgICAgPDwgIiBhbmQgdXNlIC0tZW5jb2RlLCAtLWRlY29kZSBvciBwcmludCAiCisgICAgICAgICAgICAgICAgPDwgIm90aGVyIGluZm8gYXQgdGhlIHNhbWUgdGltZS4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBpZiAoIW91dHB1dF9kaXJlY3RpdmVzXy5lbXB0eSgpIHx8ICFkZXNjcmlwdG9yX3NldF9uYW1lXy5lbXB0eSgpKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIkNhbm5vdCB1c2UgIiA8PCBuYW1lCisgICAgICAgICAgICAgICAgPDwgIiBhbmQgZ2VuZXJhdGUgY29kZSBvciBkZXNjcmlwdG9ycyBhdCB0aGUgc2FtZSB0aW1lLiIKKyAgICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgbW9kZV8gPSBNT0RFX1BSSU5UOworICAgIHByaW50X21vZGVfID0gUFJJTlRfRlJFRV9GSUVMRFM7CisgIH0gZWxzZSB7CisgICAgLy8gU29tZSBvdGhlciBmbGFnLiAgTG9vayBpdCB1cCBpbiB0aGUgZ2VuZXJhdG9ycyBsaXN0LgorICAgIGNvbnN0IEdlbmVyYXRvckluZm8qIGdlbmVyYXRvcl9pbmZvID0KKyAgICAgICAgRmluZE9yTnVsbChnZW5lcmF0b3JzX2J5X2ZsYWdfbmFtZV8sIG5hbWUpOworICAgIGlmIChnZW5lcmF0b3JfaW5mbyA9PSBOVUxMICYmCisgICAgICAgIChwbHVnaW5fcHJlZml4Xy5lbXB0eSgpIHx8ICFIYXNTdWZmaXhTdHJpbmcobmFtZSwgIl9vdXQiKSkpIHsKKyAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSBnZW5lcmF0b3Igb3B0aW9uIGZsYWcuCisgICAgICBnZW5lcmF0b3JfaW5mbyA9IEZpbmRPck51bGwoZ2VuZXJhdG9yc19ieV9vcHRpb25fbmFtZV8sIG5hbWUpOworICAgICAgaWYgKGdlbmVyYXRvcl9pbmZvID09IE5VTEwpIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJVbmtub3duIGZsYWc6ICIgPDwgbmFtZSA8PCBzdGQ6OmVuZGw7CisgICAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3RyaW5nKiBwYXJhbWV0ZXJzID0gJmdlbmVyYXRvcl9wYXJhbWV0ZXJzX1tnZW5lcmF0b3JfaW5mby0+ZmxhZ19uYW1lXTsKKyAgICAgICAgaWYgKCFwYXJhbWV0ZXJzLT5lbXB0eSgpKSB7CisgICAgICAgICAgcGFyYW1ldGVycy0+YXBwZW5kKCIsIik7CisgICAgICAgIH0KKyAgICAgICAgcGFyYW1ldGVycy0+YXBwZW5kKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gSXQncyBhbiBvdXRwdXQgZmxhZy4gIEFkZCBpdCB0byB0aGUgb3V0cHV0IGRpcmVjdGl2ZXMuCisgICAgICBpZiAobW9kZV8gIT0gTU9ERV9DT01QSUxFKSB7CisgICAgICAgIHN0ZDo6Y2VyciA8PCAiQ2Fubm90IHVzZSAtLWVuY29kZSwgLS1kZWNvZGUgb3IgcHJpbnQgLnByb3RvIGluZm8gYW5kICIKKyAgICAgICAgICAgICAgICAgICAgICJnZW5lcmF0ZSBjb2RlIGF0IHRoZSBzYW1lIHRpbWUuIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgICAgfQorCisgICAgICBPdXRwdXREaXJlY3RpdmUgZGlyZWN0aXZlOworICAgICAgZGlyZWN0aXZlLm5hbWUgPSBuYW1lOworICAgICAgaWYgKGdlbmVyYXRvcl9pbmZvID09IE5VTEwpIHsKKyAgICAgICAgZGlyZWN0aXZlLmdlbmVyYXRvciA9IE5VTEw7CisgICAgICB9IGVsc2UgeworICAgICAgICBkaXJlY3RpdmUuZ2VuZXJhdG9yID0gZ2VuZXJhdG9yX2luZm8tPmdlbmVyYXRvcjsKKyAgICAgIH0KKworICAgICAgLy8gU3BsaXQgdmFsdWUgYXQgJzonIHRvIHNlcGFyYXRlIHRoZSBnZW5lcmF0b3IgcGFyYW1ldGVyIGZyb20gdGhlCisgICAgICAvLyBmaWxlbmFtZS4gIEhvd2V2ZXIsIGF2b2lkIGRvaW5nIHRoaXMgaWYgdGhlIGNvbG9uIGlzIHBhcnQgb2YgYSB2YWxpZAorICAgICAgLy8gV2luZG93cy1zdHlsZSBhYnNvbHV0ZSBwYXRoLgorICAgICAgc3RyaW5nOjpzaXplX3R5cGUgY29sb25fcG9zID0gdmFsdWUuZmluZF9maXJzdF9vZignOicpOworICAgICAgaWYgKGNvbG9uX3BvcyA9PSBzdHJpbmc6Om5wb3MgfHwgSXNXaW5kb3dzQWJzb2x1dGVQYXRoKHZhbHVlKSkgeworICAgICAgICBkaXJlY3RpdmUub3V0cHV0X2xvY2F0aW9uID0gdmFsdWU7CisgICAgICB9IGVsc2UgeworICAgICAgICBkaXJlY3RpdmUucGFyYW1ldGVyID0gdmFsdWUuc3Vic3RyKDAsIGNvbG9uX3Bvcyk7CisgICAgICAgIGRpcmVjdGl2ZS5vdXRwdXRfbG9jYXRpb24gPSB2YWx1ZS5zdWJzdHIoY29sb25fcG9zICsgMSk7CisgICAgICB9CisKKyAgICAgIG91dHB1dF9kaXJlY3RpdmVzXy5wdXNoX2JhY2soZGlyZWN0aXZlKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfQ09OVElOVUU7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2U6OlByaW50SGVscFRleHQoKSB7CisgIC8vIFNvcnJ5IGZvciBpbmRlbnRhdGlvbiBoZXJlOyBsaW5lIHdyYXBwaW5nIHdvdWxkIGJlIHVnbGllci4KKyAgc3RkOjpjZXJyIDw8CisiVXNhZ2U6ICIgPDwgZXhlY3V0YWJsZV9uYW1lXyA8PCAiIFtPUFRJT05dIFBST1RPX0ZJTEVTXG4iCisiUGFyc2UgUFJPVE9fRklMRVMgYW5kIGdlbmVyYXRlIG91dHB1dCBiYXNlZCBvbiB0aGUgb3B0aW9ucyBnaXZlbjpcbiIKKyIgIC1JUEFUSCwgLS1wcm90b19wYXRoPVBBVEggICBTcGVjaWZ5IHRoZSBkaXJlY3RvcnkgaW4gd2hpY2ggdG8gc2VhcmNoIGZvclxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydHMuICBNYXkgYmUgc3BlY2lmaWVkIG11bHRpcGxlIHRpbWVzO1xuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdG9yaWVzIHdpbGwgYmUgc2VhcmNoZWQgaW4gb3JkZXIuICBJZiBub3RcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnaXZlbiwgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgaXMgdXNlZC5cbiIKKyIgIC0tdmVyc2lvbiAgICAgICAgICAgICAgICAgICBTaG93IHZlcnNpb24gaW5mbyBhbmQgZXhpdC5cbiIKKyIgIC1oLCAtLWhlbHAgICAgICAgICAgICAgICAgICBTaG93IHRoaXMgdGV4dCBhbmQgZXhpdC5cbiIKKyIgIC0tZW5jb2RlPU1FU1NBR0VfVFlQRSAgICAgICBSZWFkIGEgdGV4dC1mb3JtYXQgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gdHlwZVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gc3RhbmRhcmQgaW5wdXQgYW5kIHdyaXRlIGl0IGluIGJpbmFyeVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHN0YW5kYXJkIG91dHB1dC4gIFRoZSBtZXNzYWdlIHR5cGUgbXVzdFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlIGRlZmluZWQgaW4gUFJPVE9fRklMRVMgb3IgdGhlaXIgaW1wb3J0cy5cbiIKKyIgIC0tZGVjb2RlPU1FU1NBR0VfVFlQRSAgICAgICBSZWFkIGEgYmluYXJ5IG1lc3NhZ2Ugb2YgdGhlIGdpdmVuIHR5cGUgZnJvbVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YW5kYXJkIGlucHV0IGFuZCB3cml0ZSBpdCBpbiB0ZXh0IGZvcm1hdFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHN0YW5kYXJkIG91dHB1dC4gIFRoZSBtZXNzYWdlIHR5cGUgbXVzdFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlIGRlZmluZWQgaW4gUFJPVE9fRklMRVMgb3IgdGhlaXIgaW1wb3J0cy5cbiIKKyIgIC0tZGVjb2RlX3JhdyAgICAgICAgICAgICAgICBSZWFkIGFuIGFyYml0cmFyeSBwcm90b2NvbCBtZXNzYWdlIGZyb21cbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFuZGFyZCBpbnB1dCBhbmQgd3JpdGUgdGhlIHJhdyB0YWcvdmFsdWVcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWlycyBpbiB0ZXh0IGZvcm1hdCB0byBzdGFuZGFyZCBvdXRwdXQuICBOb1xuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBST1RPX0ZJTEVTIHNob3VsZCBiZSBnaXZlbiB3aGVuIHVzaW5nIHRoaXNcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGFnLlxuIgorIiAgLW9GSUxFLCAgICAgICAgICAgICAgICAgICAgIFdyaXRlcyBhIEZpbGVEZXNjcmlwdG9yU2V0IChhIHByb3RvY29sIGJ1ZmZlcixcbiIKKyIgICAgLS1kZXNjcmlwdG9yX3NldF9vdXQ9RklMRSBkZWZpbmVkIGluIGRlc2NyaXB0b3IucHJvdG8pIGNvbnRhaW5pbmcgYWxsIG9mXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGlucHV0IGZpbGVzIHRvIEZJTEUuXG4iCisiICAtLWluY2x1ZGVfaW1wb3J0cyAgICAgICAgICAgV2hlbiB1c2luZyAtLWRlc2NyaXB0b3Jfc2V0X291dCwgYWxzbyBpbmNsdWRlXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsIGRlcGVuZGVuY2llcyBvZiB0aGUgaW5wdXQgZmlsZXMgaW4gdGhlXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0LCBzbyB0aGF0IHRoZSBzZXQgaXMgc2VsZi1jb250YWluZWQuXG4iCisiICAtLWluY2x1ZGVfc291cmNlX2luZm8gICAgICAgV2hlbiB1c2luZyAtLWRlc2NyaXB0b3Jfc2V0X291dCwgZG8gbm90IHN0cmlwXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlQ29kZUluZm8gZnJvbSB0aGUgRmlsZURlc2NyaXB0b3JQcm90by5cbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIHJlc3VsdHMgaW4gdmFzdGx5IGxhcmdlciBkZXNjcmlwdG9ycyB0aGF0XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb3JpZ2luYWxcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiBvZiBlYWNoIGRlY2wgaW4gdGhlIHNvdXJjZSBmaWxlIGFzXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VsbCBhcyBzdXJyb3VuZGluZyBjb21tZW50cy5cbiIKKyIgIC0tZGVwZW5kZW5jeV9vdXQ9RklMRSAgICAgICBXcml0ZSBhIGRlcGVuZGVuY3kgb3V0cHV0IGZpbGUgaW4gdGhlIGZvcm1hdFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkIGJ5IG1ha2UuIFRoaXMgd3JpdGVzIHRoZSB0cmFuc2l0aXZlXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0IG9mIGlucHV0IGZpbGUgcGF0aHMgdG8gRklMRVxuIgorIiAgLS1lcnJvcl9mb3JtYXQ9Rk9STUFUICAgICAgIFNldCB0aGUgZm9ybWF0IGluIHdoaWNoIHRvIHByaW50IGVycm9ycy5cbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGT1JNQVQgbWF5IGJlICdnY2MnICh0aGUgZGVmYXVsdCkgb3IgJ21zdnMnXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1pY3Jvc29mdCBWaXN1YWwgU3R1ZGlvIGZvcm1hdCkuXG4iCisiICAtLXByaW50X2ZyZWVfZmllbGRfbnVtYmVycyAgUHJpbnQgdGhlIGZyZWUgZmllbGQgbnVtYmVycyBvZiB0aGUgbWVzc2FnZXNcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZpbmVkIGluIHRoZSBnaXZlbiBwcm90byBmaWxlcy4gR3JvdXBzIHNoYXJlXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHNhbWUgZmllbGQgbnVtYmVyIHNwYWNlIHdpdGggdGhlIHBhcmVudCBcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLiBFeHRlbnNpb24gcmFuZ2VzIGFyZSBjb3VudGVkIGFzIFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGZpZWxkcyBudW1iZXJzLiIgIDw8IHN0ZDo6ZW5kbDsKKyAgaWYgKCFwbHVnaW5fcHJlZml4Xy5lbXB0eSgpKSB7CisgICAgc3RkOjpjZXJyIDw8CisiICAtLXBsdWdpbj1FWEVDVVRBQkxFICAgICAgICAgU3BlY2lmaWVzIGEgcGx1Z2luIGV4ZWN1dGFibGUgdG8gdXNlLlxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGx5LCBwcm90b2Mgc2VhcmNoZXMgdGhlIFBBVEggZm9yXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2lucywgYnV0IHlvdSBtYXkgc3BlY2lmeSBhZGRpdGlvbmFsXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0YWJsZXMgbm90IGluIHRoZSBwYXRoIHVzaW5nIHRoaXMgZmxhZy5cbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBZGRpdGlvbmFsbHksIEVYRUNVVEFCTEUgbWF5IGJlIG9mIHRoZSBmb3JtXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRT1QQVRILCBpbiB3aGljaCBjYXNlIHRoZSBnaXZlbiBwbHVnaW4gbmFtZVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIG1hcHBlZCB0byB0aGUgZ2l2ZW4gZXhlY3V0YWJsZSBldmVuIGlmXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGV4ZWN1dGFibGUncyBvd24gbmFtZSBkaWZmZXJzLiIgPDwgc3RkOjplbmRsOworICB9CisKKyAgZm9yIChHZW5lcmF0b3JNYXA6Oml0ZXJhdG9yIGl0ZXIgPSBnZW5lcmF0b3JzX2J5X2ZsYWdfbmFtZV8uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lXy5lbmQoKTsgKytpdGVyKSB7CisgICAgLy8gRklYTUUoa2VudG9uKTogIElmIHRoZSB0ZXh0IGlzIGxvbmcgZW5vdWdoIGl0IHdpbGwgd3JhcCwgd2hpY2ggaXMgdWdseSwKKyAgICAvLyAgIGJ1dCBmaXhpbmcgdGhpcyBuaWNlbHkgKGUuZy4gc3BsaXR0aW5nIG9uIHNwYWNlcykgaXMgcHJvYmFibHkgbW9yZQorICAgIC8vICAgdHJvdWJsZSB0aGFuIGl0J3Mgd29ydGguCisgICAgc3RkOjpjZXJyIDw8ICIgICIgPDwgaXRlci0+Zmlyc3QgPDwgIj1PVVRfRElSICIKKyAgICAgICAgICAgICAgPDwgc3RyaW5nKDE5IC0gaXRlci0+Zmlyc3Quc2l6ZSgpLCAnICcpICAvLyBTcGFjZXMgZm9yIGFsaWdubWVudC4KKyAgICAgICAgICAgICAgPDwgaXRlci0+c2Vjb25kLmhlbHBfdGV4dCA8PCBzdGQ6OmVuZGw7CisgIH0KK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdGVPdXRwdXQoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlcywKKyAgICBjb25zdCBPdXRwdXREaXJlY3RpdmUmIG91dHB1dF9kaXJlY3RpdmUsCisgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQpIHsKKyAgLy8gQ2FsbCB0aGUgZ2VuZXJhdG9yLgorICBzdHJpbmcgZXJyb3I7CisgIGlmIChvdXRwdXRfZGlyZWN0aXZlLmdlbmVyYXRvciA9PSBOVUxMKSB7CisgICAgLy8gVGhpcyBpcyBhIHBsdWdpbi4KKyAgICBHT09HTEVfQ0hFQ0soSGFzUHJlZml4U3RyaW5nKG91dHB1dF9kaXJlY3RpdmUubmFtZSwgIi0tIikgJiYKKyAgICAgICAgICBIYXNTdWZmaXhTdHJpbmcob3V0cHV0X2RpcmVjdGl2ZS5uYW1lLCAiX291dCIpKQorICAgICAgICA8PCAiQmFkIG5hbWUgZm9yIHBsdWdpbiBnZW5lcmF0b3I6ICIgPDwgb3V0cHV0X2RpcmVjdGl2ZS5uYW1lOworCisgICAgLy8gU3RyaXAgdGhlICItLSIgYW5kICJfb3V0IiBhbmQgYWRkIHRoZSBwbHVnaW4gcHJlZml4LgorICAgIHN0cmluZyBwbHVnaW5fbmFtZSA9IHBsdWdpbl9wcmVmaXhfICsgImdlbi0iICsKKyAgICAgICAgb3V0cHV0X2RpcmVjdGl2ZS5uYW1lLnN1YnN0cigyLCBvdXRwdXRfZGlyZWN0aXZlLm5hbWUuc2l6ZSgpIC0gNik7CisKKyAgICBpZiAoIUdlbmVyYXRlUGx1Z2luT3V0cHV0KHBhcnNlZF9maWxlcywgcGx1Z2luX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfZGlyZWN0aXZlLnBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LCAmZXJyb3IpKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgb3V0cHV0X2RpcmVjdGl2ZS5uYW1lIDw8ICI6ICIgPDwgZXJyb3IgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBSZWd1bGFyIGdlbmVyYXRvci4KKyAgICBzdHJpbmcgcGFyYW1ldGVycyA9IG91dHB1dF9kaXJlY3RpdmUucGFyYW1ldGVyOworICAgIGlmICghZ2VuZXJhdG9yX3BhcmFtZXRlcnNfW291dHB1dF9kaXJlY3RpdmUubmFtZV0uZW1wdHkoKSkgeworICAgICAgaWYgKCFwYXJhbWV0ZXJzLmVtcHR5KCkpIHsKKyAgICAgICAgcGFyYW1ldGVycy5hcHBlbmQoIiwiKTsKKyAgICAgIH0KKyAgICAgIHBhcmFtZXRlcnMuYXBwZW5kKGdlbmVyYXRvcl9wYXJhbWV0ZXJzX1tvdXRwdXRfZGlyZWN0aXZlLm5hbWVdKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZWRfZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGlmICghb3V0cHV0X2RpcmVjdGl2ZS5nZW5lcmF0b3ItPkdlbmVyYXRlKHBhcnNlZF9maWxlc1tpXSwgcGFyYW1ldGVycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LCAmZXJyb3IpKSB7CisgICAgICAgIC8vIEdlbmVyYXRvciByZXR1cm5lZCBhbiBlcnJvci4KKyAgICAgICAgc3RkOjpjZXJyIDw8IG91dHB1dF9kaXJlY3RpdmUubmFtZSA8PCAiOiAiIDw8IHBhcnNlZF9maWxlc1tpXS0+bmFtZSgpCisgICAgICAgICAgICAgICAgICA8PCAiOiAiIDw8IGVycm9yIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0ZURlcGVuZGVuY3lNYW5pZmVzdEZpbGUoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlcywKKyAgICBjb25zdCBHZW5lcmF0b3JDb250ZXh0TWFwJiBvdXRwdXRfZGlyZWN0b3JpZXMsCisgICAgRGlza1NvdXJjZVRyZWUqIHNvdXJjZV90cmVlKSB7CisgIEZpbGVEZXNjcmlwdG9yU2V0IGZpbGVfc2V0OworCisgIHNldDxjb25zdCBGaWxlRGVzY3JpcHRvcio+IGFscmVhZHlfc2VlbjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZWRfZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICBHZXRUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKHBhcnNlZF9maWxlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFscmVhZHlfc2VlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfc2V0Lm11dGFibGVfZmlsZSgpKTsKKyAgfQorCisgIHZlY3RvcjxzdHJpbmc+IG91dHB1dF9maWxlbmFtZXM7CisgIGZvciAoR2VuZXJhdG9yQ29udGV4dE1hcDo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IG91dHB1dF9kaXJlY3Rvcmllcy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gb3V0cHV0X2RpcmVjdG9yaWVzLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBjb25zdCBzdHJpbmcmIGxvY2F0aW9uID0gaXRlci0+Zmlyc3Q7CisgICAgR2VuZXJhdG9yQ29udGV4dEltcGwqIGRpcmVjdG9yeSA9IGl0ZXItPnNlY29uZDsKKyAgICB2ZWN0b3I8c3RyaW5nPiByZWxhdGl2ZV9vdXRwdXRfZmlsZW5hbWVzOworICAgIGRpcmVjdG9yeS0+R2V0T3V0cHV0RmlsZW5hbWVzKCZyZWxhdGl2ZV9vdXRwdXRfZmlsZW5hbWVzKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlbGF0aXZlX291dHB1dF9maWxlbmFtZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIHN0cmluZyBvdXRwdXRfZmlsZW5hbWUgPSBsb2NhdGlvbiArIHJlbGF0aXZlX291dHB1dF9maWxlbmFtZXNbaV07CisgICAgICBpZiAob3V0cHV0X2ZpbGVuYW1lLmNvbXBhcmUoMCwgMiwgIi4vIikgPT0gMCkgeworICAgICAgICBvdXRwdXRfZmlsZW5hbWUgPSBvdXRwdXRfZmlsZW5hbWUuc3Vic3RyKDIpOworICAgICAgfQorICAgICAgb3V0cHV0X2ZpbGVuYW1lcy5wdXNoX2JhY2sob3V0cHV0X2ZpbGVuYW1lKTsKKyAgICB9CisgIH0KKworICBpbnQgZmQ7CisgIGRvIHsKKyAgICBmZCA9IG9wZW4oZGVwZW5kZW5jeV9vdXRfbmFtZV8uY19zdHIoKSwKKyAgICAgICAgICAgICAgT19XUk9OTFkgfCBPX0NSRUFUIHwgT19UUlVOQyB8IE9fQklOQVJZLCAwNjY2KTsKKyAgfSB3aGlsZSAoZmQgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKworICBpZiAoZmQgPCAwKSB7CisgICAgcGVycm9yKGRlcGVuZGVuY3lfb3V0X25hbWVfLmNfc3RyKCkpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dChmZCk7CisgIGlvOjpQcmludGVyIHByaW50ZXIoJm91dCwgJyQnKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IG91dHB1dF9maWxlbmFtZXMuc2l6ZSgpOyBpKyspIHsKKyAgICBwcmludGVyLlByaW50KG91dHB1dF9maWxlbmFtZXNbaV0uY19zdHIoKSk7CisgICAgaWYgKGkgPT0gb3V0cHV0X2ZpbGVuYW1lcy5zaXplKCkgLSAxKSB7CisgICAgICBwcmludGVyLlByaW50KCI6Iik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiBcXFxuIik7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlX3NldC5maWxlX3NpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSA9IGZpbGVfc2V0LmZpbGUoaSk7CisgICAgY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUgPSBmaWxlLm5hbWUoKTsKKyAgICBzdHJpbmcgZGlza19maWxlOworICAgIGlmIChzb3VyY2VfdHJlZSAmJgorICAgICAgICBzb3VyY2VfdHJlZS0+VmlydHVhbEZpbGVUb0Rpc2tGaWxlKHZpcnR1YWxfZmlsZSwgJmRpc2tfZmlsZSkpIHsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiAkZGlza19maWxlJCIsICJkaXNrX2ZpbGUiLCBkaXNrX2ZpbGUpOworICAgICAgaWYgKGkgPCBmaWxlX3NldC5maWxlX3NpemUoKSAtIDEpIHByaW50ZXIuUHJpbnQoIlxcXG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgY2VyciA8PCAiVW5hYmxlIHRvIGlkZW50aWZ5IHBhdGggZm9yIGZpbGUgIiA8PCB2aXJ0dWFsX2ZpbGUgPDwgZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdGVQbHVnaW5PdXRwdXQoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlcywKKyAgICBjb25zdCBzdHJpbmcmIHBsdWdpbl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgIHN0cmluZyogZXJyb3IpIHsKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3QgcmVxdWVzdDsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlIHJlc3BvbnNlOworCisgIC8vIEJ1aWxkIHRoZSByZXF1ZXN0LgorICBpZiAoIXBhcmFtZXRlci5lbXB0eSgpKSB7CisgICAgcmVxdWVzdC5zZXRfcGFyYW1ldGVyKHBhcmFtZXRlcik7CisgIH0KKworICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBhbHJlYWR5X3NlZW47CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgcmVxdWVzdC5hZGRfZmlsZV90b19nZW5lcmF0ZShwYXJzZWRfZmlsZXNbaV0tPm5hbWUoKSk7CisgICAgR2V0VHJhbnNpdGl2ZURlcGVuZGVuY2llcyhwYXJzZWRfZmlsZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgLy8gSW5jbHVkZSBzb3VyY2UgY29kZSBpbmZvLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFscmVhZHlfc2VlbiwgcmVxdWVzdC5tdXRhYmxlX3Byb3RvX2ZpbGUoKSk7CisgIH0KKworICAvLyBJbnZva2UgdGhlIHBsdWdpbi4KKyAgU3VicHJvY2VzcyBzdWJwcm9jZXNzOworCisgIGlmIChwbHVnaW5zXy5jb3VudChwbHVnaW5fbmFtZSkgPiAwKSB7CisgICAgc3VicHJvY2Vzcy5TdGFydChwbHVnaW5zX1twbHVnaW5fbmFtZV0sIFN1YnByb2Nlc3M6OkVYQUNUX05BTUUpOworICB9IGVsc2UgeworICAgIHN1YnByb2Nlc3MuU3RhcnQocGx1Z2luX25hbWUsIFN1YnByb2Nlc3M6OlNFQVJDSF9QQVRIKTsKKyAgfQorCisgIHN0cmluZyBjb21tdW5pY2F0ZV9lcnJvcjsKKyAgaWYgKCFzdWJwcm9jZXNzLkNvbW11bmljYXRlKHJlcXVlc3QsICZyZXNwb25zZSwgJmNvbW11bmljYXRlX2Vycm9yKSkgeworICAgICplcnJvciA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoIiQwOiAkMSIsIHBsdWdpbl9uYW1lLCBjb21tdW5pY2F0ZV9lcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gV3JpdGUgdGhlIGZpbGVzLiAgV2UgZG8gdGhpcyBldmVuIGlmIHRoZXJlIHdhcyBhIGdlbmVyYXRvciBlcnJvciBpbiBvcmRlcgorICAvLyB0byBtYXRjaCB0aGUgYmVoYXZpb3Igb2YgYSBjb21waWxlZC1pbiBnZW5lcmF0b3IuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBjdXJyZW50X291dHB1dDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXNwb25zZS5maWxlX3NpemUoKTsgaSsrKSB7CisgICAgY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpGaWxlJiBvdXRwdXRfZmlsZSA9IHJlc3BvbnNlLmZpbGUoaSk7CisKKyAgICBpZiAoIW91dHB1dF9maWxlLmluc2VydGlvbl9wb2ludCgpLmVtcHR5KCkpIHsKKyAgICAgIC8vIE9wZW4gYSBmaWxlIGZvciBpbnNlcnQuCisgICAgICAvLyBXZSByZXNldCBjdXJyZW50X291dHB1dCB0byBOVUxMIGZpcnN0IHNvIHRoYXQgdGhlIG9sZCBmaWxlIGlzIGNsb3NlZAorICAgICAgLy8gYmVmb3JlIHRoZSBuZXcgb25lIGlzIG9wZW5lZC4KKyAgICAgIGN1cnJlbnRfb3V0cHV0LnJlc2V0KCk7CisgICAgICBjdXJyZW50X291dHB1dC5yZXNldChnZW5lcmF0b3JfY29udGV4dC0+T3BlbkZvckluc2VydCgKKyAgICAgICAgICBvdXRwdXRfZmlsZS5uYW1lKCksIG91dHB1dF9maWxlLmluc2VydGlvbl9wb2ludCgpKSk7CisgICAgfSBlbHNlIGlmICghb3V0cHV0X2ZpbGUubmFtZSgpLmVtcHR5KCkpIHsKKyAgICAgIC8vIFN0YXJ0aW5nIGEgbmV3IGZpbGUuICBPcGVuIGl0LgorICAgICAgLy8gV2UgcmVzZXQgY3VycmVudF9vdXRwdXQgdG8gTlVMTCBmaXJzdCBzbyB0aGF0IHRoZSBvbGQgZmlsZSBpcyBjbG9zZWQKKyAgICAgIC8vIGJlZm9yZSB0aGUgbmV3IG9uZSBpcyBvcGVuZWQuCisgICAgICBjdXJyZW50X291dHB1dC5yZXNldCgpOworICAgICAgY3VycmVudF9vdXRwdXQucmVzZXQoZ2VuZXJhdG9yX2NvbnRleHQtPk9wZW4ob3V0cHV0X2ZpbGUubmFtZSgpKSk7CisgICAgfSBlbHNlIGlmIChjdXJyZW50X291dHB1dCA9PSBOVUxMKSB7CisgICAgICAqZXJyb3IgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAiJDA6IEZpcnN0IGZpbGUgY2h1bmsgcmV0dXJuZWQgYnkgcGx1Z2luIGRpZCBub3Qgc3BlY2lmeSBhIGZpbGUgbmFtZS4iLAorICAgICAgICBwbHVnaW5fbmFtZSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gVXNlIENvZGVkT3V0cHV0U3RyZWFtIGZvciBjb252ZW5pZW5jZTsgb3RoZXJ3aXNlIHdlJ2QgbmVlZCB0byBwcm92aWRlCisgICAgLy8gb3VyIG93biBidWZmZXItY29weWluZyBsb29wLgorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSB3cml0ZXIoY3VycmVudF9vdXRwdXQuZ2V0KCkpOworICAgIHdyaXRlci5Xcml0ZVN0cmluZyhvdXRwdXRfZmlsZS5jb250ZW50KCkpOworICB9CisKKyAgLy8gQ2hlY2sgZm9yIGVycm9ycy4KKyAgaWYgKCFyZXNwb25zZS5lcnJvcigpLmVtcHR5KCkpIHsKKyAgICAvLyBHZW5lcmF0b3IgcmV0dXJuZWQgYW4gZXJyb3IuCisgICAgKmVycm9yID0gcmVzcG9uc2UuZXJyb3IoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6RW5jb2RlT3JEZWNvZGUoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpIHsKKyAgLy8gTG9vayB1cCB0aGUgdHlwZS4KKyAgY29uc3QgRGVzY3JpcHRvciogdHlwZSA9IHBvb2wtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZShjb2RlY190eXBlXyk7CisgIGlmICh0eXBlID09IE5VTEwpIHsKKyAgICBzdGQ6OmNlcnIgPDwgIlR5cGUgbm90IGRlZmluZWQ6ICIgPDwgY29kZWNfdHlwZV8gPDwgc3RkOjplbmRsOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBkeW5hbWljX2ZhY3RvcnkocG9vbCk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShkeW5hbWljX2ZhY3RvcnkuR2V0UHJvdG90eXBlKHR5cGUpLT5OZXcoKSk7CisKKyAgaWYgKG1vZGVfID09IE1PREVfRU5DT0RFKSB7CisgICAgU2V0RmRUb1RleHRNb2RlKFNURElOX0ZJTEVOTyk7CisgICAgU2V0RmRUb0JpbmFyeU1vZGUoU1RET1VUX0ZJTEVOTyk7CisgIH0gZWxzZSB7CisgICAgU2V0RmRUb0JpbmFyeU1vZGUoU1RESU5fRklMRU5PKTsKKyAgICBTZXRGZFRvVGV4dE1vZGUoU1RET1VUX0ZJTEVOTyk7CisgIH0KKworICBpbzo6RmlsZUlucHV0U3RyZWFtIGluKFNURElOX0ZJTEVOTyk7CisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dChTVERPVVRfRklMRU5PKTsKKworICBpZiAobW9kZV8gPT0gTU9ERV9FTkNPREUpIHsKKyAgICAvLyBJbnB1dCBpcyB0ZXh0LgorICAgIEVycm9yUHJpbnRlciBlcnJvcl9jb2xsZWN0b3IoZXJyb3JfZm9ybWF0Xyk7CisgICAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgICBwYXJzZXIuUmVjb3JkRXJyb3JzVG8oJmVycm9yX2NvbGxlY3Rvcik7CisgICAgcGFyc2VyLkFsbG93UGFydGlhbE1lc3NhZ2UodHJ1ZSk7CisKKyAgICBpZiAoIXBhcnNlci5QYXJzZSgmaW4sIG1lc3NhZ2UuZ2V0KCkpKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIkZhaWxlZCB0byBwYXJzZSBpbnB1dC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gSW5wdXQgaXMgYmluYXJ5LgorICAgIGlmICghbWVzc2FnZS0+UGFyc2VQYXJ0aWFsRnJvbVplcm9Db3B5U3RyZWFtKCZpbikpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiRmFpbGVkIHRvIHBhcnNlIGlucHV0LiIgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIGlmICghbWVzc2FnZS0+SXNJbml0aWFsaXplZCgpKSB7CisgICAgc3RkOjpjZXJyIDw8ICJ3YXJuaW5nOiAgSW5wdXQgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogICIKKyAgICAgICAgICAgICAgPDwgbWVzc2FnZS0+SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpIDw8IHN0ZDo6ZW5kbDsKKyAgfQorCisgIGlmIChtb2RlXyA9PSBNT0RFX0VOQ09ERSkgeworICAgIC8vIE91dHB1dCBpcyBiaW5hcnkuCisgICAgaWYgKCFtZXNzYWdlLT5TZXJpYWxpemVQYXJ0aWFsVG9aZXJvQ29weVN0cmVhbSgmb3V0KSkgeworICAgICAgc3RkOjpjZXJyIDw8ICJvdXRwdXQ6IEkvTyBlcnJvci4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gT3V0cHV0IGlzIHRleHQuCisgICAgaWYgKCFUZXh0Rm9ybWF0OjpQcmludCgqbWVzc2FnZSwgJm91dCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAib3V0cHV0OiBJL08gZXJyb3IuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQ29tbWFuZExpbmVJbnRlcmZhY2U6OldyaXRlRGVzY3JpcHRvclNldCgKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBwYXJzZWRfZmlsZXMpIHsKKyAgRmlsZURlc2NyaXB0b3JTZXQgZmlsZV9zZXQ7CisKKyAgaWYgKGltcG9ydHNfaW5fZGVzY3JpcHRvcl9zZXRfKSB7CisgICAgc2V0PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gYWxyZWFkeV9zZWVuOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICBHZXRUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKHBhcnNlZF9maWxlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX2luZm9faW5fZGVzY3JpcHRvcl9zZXRfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYWxyZWFkeV9zZWVuLCBmaWxlX3NldC5tdXRhYmxlX2ZpbGUoKSk7CisgICAgfQorICB9IGVsc2UgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlX3Byb3RvID0gZmlsZV9zZXQuYWRkX2ZpbGUoKTsKKyAgICAgIHBhcnNlZF9maWxlc1tpXS0+Q29weVRvKGZpbGVfcHJvdG8pOworICAgICAgaWYgKHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XykgeworICAgICAgICBwYXJzZWRfZmlsZXNbaV0tPkNvcHlTb3VyY2VDb2RlSW5mb1RvKGZpbGVfcHJvdG8pOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGludCBmZDsKKyAgZG8geworICAgIGZkID0gb3BlbihkZXNjcmlwdG9yX3NldF9uYW1lXy5jX3N0cigpLAorICAgICAgICAgICAgICBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX1RSVU5DIHwgT19CSU5BUlksIDA2NjYpOworICB9IHdoaWxlIChmZCA8IDAgJiYgZXJybm8gPT0gRUlOVFIpOworCisgIGlmIChmZCA8IDApIHsKKyAgICBwZXJyb3IoZGVzY3JpcHRvcl9zZXRfbmFtZV8uY19zdHIoKSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaW86OkZpbGVPdXRwdXRTdHJlYW0gb3V0KGZkKTsKKyAgaWYgKCFmaWxlX3NldC5TZXJpYWxpemVUb1plcm9Db3B5U3RyZWFtKCZvdXQpKSB7CisgICAgc3RkOjpjZXJyIDw8IGRlc2NyaXB0b3Jfc2V0X25hbWVfIDw8ICI6ICIgPDwgc3RyZXJyb3Iob3V0LkdldEVycm5vKCkpCisgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICBvdXQuQ2xvc2UoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKCFvdXQuQ2xvc2UoKSkgeworICAgIHN0ZDo6Y2VyciA8PCBkZXNjcmlwdG9yX3NldF9uYW1lXyA8PCAiOiAiIDw8IHN0cmVycm9yKG91dC5HZXRFcnJubygpKQorICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2U6OkdldFRyYW5zaXRpdmVEZXBlbmRlbmNpZXMoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW5jbHVkZV9zb3VyY2VfY29kZV9pbmZvLAorICAgIHNldDxjb25zdCBGaWxlRGVzY3JpcHRvcio+KiBhbHJlYWR5X3NlZW4sCisgICAgUmVwZWF0ZWRQdHJGaWVsZDxGaWxlRGVzY3JpcHRvclByb3RvPiogb3V0cHV0KSB7CisgIGlmICghYWxyZWFkeV9zZWVuLT5pbnNlcnQoZmlsZSkuc2Vjb25kKSB7CisgICAgLy8gQWxyZWFkeSBzYXcgdGhpcyBmaWxlLiAgU2tpcC4KKyAgICByZXR1cm47CisgIH0KKworICAvLyBBZGQgYWxsIGRlcGVuZGVuY2llcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIEdldFRyYW5zaXRpdmVEZXBlbmRlbmNpZXMoZmlsZS0+ZGVwZW5kZW5jeShpKSwgaW5jbHVkZV9zb3VyY2VfY29kZV9pbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxyZWFkeV9zZWVuLCBvdXRwdXQpOworICB9CisKKyAgLy8gQWRkIHRoaXMgZmlsZS4KKyAgRmlsZURlc2NyaXB0b3JQcm90byogbmV3X2Rlc2NyaXB0b3IgPSBvdXRwdXQtPkFkZCgpOworICBmaWxlLT5Db3B5VG8obmV3X2Rlc2NyaXB0b3IpOworICBpZiAoaW5jbHVkZV9zb3VyY2VfY29kZV9pbmZvKSB7CisgICAgZmlsZS0+Q29weVNvdXJjZUNvZGVJbmZvVG8obmV3X2Rlc2NyaXB0b3IpOworICB9Cit9CisKK25hbWVzcGFjZSB7CisKKy8vIFV0aWxpdHkgZnVuY3Rpb24gZm9yIFByaW50RnJlZUZpZWxkTnVtYmVycy4KKy8vIFN0b3JlcyBvY2N1cGllZCByYW5nZXMgaW50byB0aGUgcmFuZ2VzIHBhcmFtZXRlciwgYW5kIG5leHQgbGV2ZWwgb2Ygc3ViCisvLyBtZXNzYWdlIHR5cGVzIGludG8gdGhlIG5lc3RlZF9tZXNzYWdlcyBwYXJhbWV0ZXIuICBUaGUgRmllbGRSYW5nZSBpcyBsZWZ0CisvLyBpbmNsdXNpdmUsIHJpZ2h0IGV4Y2x1c2l2ZS4gaS5lLiBbYSwgYikuCisvLworLy8gTmVzdGVkIE1lc3NhZ2VzOgorLy8gTm90ZSB0aGF0IGl0IG9ubHkgc3RvcmVzIHRoZSBuZXN0ZWQgbWVzc2FnZSB0eXBlLCBpZmYgdGhlIG5lc3RlZCB0eXBlIGlzCisvLyBlaXRoZXIgYSBkaXJlY3QgY2hpbGQgb2YgdGhlIGdpdmVuIGRlc2NyaXB0b3IsIG9yIHRoZSBuZXN0ZWQgdHlwZSBpcyBhCisvLyBkZWNlbmRlbnQgb2YgdGhlIGdpdmVuIGRlc2NyaXB0b3IgYW5kIGFsbCB0aGUgbm9kZXMgYmV0d2VlbiB0aGUKKy8vIG5lc3RlZCB0eXBlIGFuZCB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBhcmUgZ3JvdXAgdHlwZXMuIGUuZy4KKy8vCisvLyBtZXNzYWdlIEZvbyB7CisvLyAgIG1lc3NhZ2UgQmFyIHsKKy8vICAgICBtZXNzYWdlIE5lc3RlZEJhciB7fQorLy8gICB9CisvLyAgIGdyb3VwIEJheiA9IDEgeworLy8gICAgIGdyb3VwIE5lc3RlZEJhekdyb3VwID0gMiB7CisvLyAgICAgICBtZXNzYWdlIFF1eiB7CisvLyAgICAgICAgIG1lc3NhZ2UgTmVzdGVkUXV6IHt9CisvLyAgICAgICB9CisvLyAgICAgfQorLy8gICAgIG1lc3NhZ2UgTmVzdGVkQmF6IHt9CisvLyAgIH0KKy8vIH0KKy8vCisvLyBJbiB0aGlzIGNhc2UsIEJhciwgUXV6IGFuZCBOZXN0ZWRCYXogd2lsbCBiZSBhZGRlZCBpbnRvIHRoZSBuZXN0ZWQgdHlwZXMuCisvLyBTaW5jZSBmcmVlIGZpZWxkIG51bWJlcnMgb2YgZ3JvdXAgdHlwZXMgd2lsbCBub3QgYmUgcHJpbnRlZCwgdGhpcyBtYWtlcyBzdXJlCisvLyB0aGUgbmVzdGVkIG1lc3NhZ2UgdHlwZXMgaW4gZ3JvdXBzIHdpbGwgbm90IGJlIGRyb3BwZWQuIFRoZSBuZXN0ZWRfbWVzc2FnZXMKKy8vIHBhcmFtZXRlciB3aWxsIGNvbnRhaW4gdGhlIGRpcmVjdCBjaGlsZHJlbiAod2hlbiBncm91cHMgYXJlIGlnbm9yZWQgaW4gdGhlCisvLyB0cmVlKSBvZiB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBmb3IgdGhlIGNhbGxlciB0byB0cmF2ZXJzZS4gVGhlIGRlY2xhcmF0aW9uCisvLyBvcmRlciBvZiB0aGUgbmVzdGVkIG1lc3NhZ2VzIGlzIGFsc28gcHJlc2VydmVkLgordHlwZWRlZiBwYWlyPGludCwgaW50PiBGaWVsZFJhbmdlOwordm9pZCBHYXRoZXJPY2N1cGllZEZpZWxkUmFuZ2VzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0PEZpZWxkUmFuZ2U+KiByYW5nZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiogbmVzdGVkX21lc3NhZ2VzKSB7CisgIHNldDxjb25zdCBEZXNjcmlwdG9yKj4gZ3JvdXBzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmQgPSBkZXNjcmlwdG9yLT5maWVsZChpKTsKKyAgICByYW5nZXMtPmluc2VydChGaWVsZFJhbmdlKGZkLT5udW1iZXIoKSwgZmQtPm51bWJlcigpICsgMSkpOworICAgIGlmIChmZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgICAgZ3JvdXBzLmluc2VydChmZC0+bWVzc2FnZV90eXBlKCkpOworICAgIH0KKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyArK2kpIHsKKyAgICByYW5nZXMtPmluc2VydChGaWVsZFJhbmdlKGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9yYW5nZShpKS0+c3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5leHRlbnNpb25fcmFuZ2UoaSktPmVuZCkpOworICB9CisgIC8vIEhhbmRsZSB0aGUgbmVzdGVkIG1lc3NhZ2VzL2dyb3VwcyBpbiBkZWNsYXJhdGlvbiBvcmRlciB0byBtYWtlIGl0CisgIC8vIHBvc3Qtb3JkZXIgc3RyaWN0LgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IERlc2NyaXB0b3IqIG5lc3RlZF9kZXNjID0gZGVzY3JpcHRvci0+bmVzdGVkX3R5cGUoaSk7CisgICAgaWYgKGdyb3Vwcy5maW5kKG5lc3RlZF9kZXNjKSAhPSBncm91cHMuZW5kKCkpIHsKKyAgICAgIEdhdGhlck9jY3VwaWVkRmllbGRSYW5nZXMobmVzdGVkX2Rlc2MsIHJhbmdlcywgbmVzdGVkX21lc3NhZ2VzKTsKKyAgICB9IGVsc2UgeworICAgICAgbmVzdGVkX21lc3NhZ2VzLT5wdXNoX2JhY2sobmVzdGVkX2Rlc2MpOworICAgIH0KKyAgfQorfQorCisvLyBVdGlsaXR5IGZ1bmN0aW9uIGZvciBQcmludEZyZWVGaWVsZE51bWJlcnMuCisvLyBBY3R1YWxseSBwcmludHMgdGhlIGZvcm1hdHRlZCBmcmVlIGZpZWxkIG51bWJlcnMgZm9yIGdpdmVuIG1lc3NhZ2UgbmFtZSBhbmQKKy8vIG9jY3VwaWVkIHJhbmdlcy4KK3ZvaWQgRm9ybWF0RnJlZUZpZWxkTnVtYmVycyhjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2V0PEZpZWxkUmFuZ2U+JiByYW5nZXMpIHsKKyAgc3RyaW5nIG91dHB1dDsKKyAgU3RyaW5nQXBwZW5kRigmb3V0cHV0LCAiJS0zNXMgZnJlZToiLCBuYW1lLmNfc3RyKCkpOworICBpbnQgbmV4dF9mcmVlX251bWJlciA9IDE7CisgIGZvciAoc2V0PEZpZWxkUmFuZ2U+Ojpjb25zdF9pdGVyYXRvciBpID0gcmFuZ2VzLmJlZ2luKCk7CisgICAgICAgaSAhPSByYW5nZXMuZW5kKCk7ICsraSkgeworICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIGdyb3VwcyByZS11c2UgcGFyZW50IGZpZWxkIG51bWJlcnMsIGluIHdoaWNoCisgICAgLy8gY2FzZSB3ZSBza2lwIHRoZSBGaWVsZFJhbmdlIGVudGlyZWx5LgorICAgIGlmIChuZXh0X2ZyZWVfbnVtYmVyID49IGktPnNlY29uZCkgY29udGludWU7CisKKyAgICBpZiAobmV4dF9mcmVlX251bWJlciA8IGktPmZpcnN0KSB7CisgICAgICBpZiAobmV4dF9mcmVlX251bWJlciArIDEgPT0gaS0+Zmlyc3QpIHsKKyAgICAgICAgLy8gU2luZ2xldG9uCisgICAgICAgIFN0cmluZ0FwcGVuZEYoJm91dHB1dCwgIiAlZCIsIG5leHRfZnJlZV9udW1iZXIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gUmFuZ2UKKyAgICAgICAgU3RyaW5nQXBwZW5kRigmb3V0cHV0LCAiICVkLSVkIiwgbmV4dF9mcmVlX251bWJlciwgaS0+Zmlyc3QgLSAxKTsKKyAgICAgIH0KKyAgICB9CisgICAgbmV4dF9mcmVlX251bWJlciA9IGktPnNlY29uZDsKKyAgfQorICBpZiAobmV4dF9mcmVlX251bWJlciA8PSBGaWVsZERlc2NyaXB0b3I6OmtNYXhOdW1iZXIpIHsKKyAgICBTdHJpbmdBcHBlbmRGKCZvdXRwdXQsICIgJWQtSU5GIiwgbmV4dF9mcmVlX251bWJlcik7CisgIH0KKyAgc3RkOjpjb3V0IDw8IG91dHB1dCA8PCBzdGQ6OmVuZGw7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpQcmludEZyZWVGaWVsZE51bWJlcnMoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzZXQ8RmllbGRSYW5nZT4gcmFuZ2VzOworICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcio+IG5lc3RlZF9tZXNzYWdlczsKKyAgR2F0aGVyT2NjdXBpZWRGaWVsZFJhbmdlcyhkZXNjcmlwdG9yLCAmcmFuZ2VzLCAmbmVzdGVkX21lc3NhZ2VzKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IG5lc3RlZF9tZXNzYWdlcy5zaXplKCk7ICsraSkgeworICAgIFByaW50RnJlZUZpZWxkTnVtYmVycyhuZXN0ZWRfbWVzc2FnZXNbaV0pOworICB9CisgIEZvcm1hdEZyZWVGaWVsZE51bWJlcnMoZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCksIHJhbmdlcyk7Cit9CisKKworCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTYxMWM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmgKQEAgLTAsMCArMSwzOTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBJbXBsZW1lbnRzIHRoZSBQcm90b2NvbCBDb21waWxlciBmcm9udC1lbmQgc3VjaCB0aGF0IGl0IG1heSBiZSByZXVzZWQgYnkKKy8vIGN1c3RvbSBjb21waWxlcnMgd3JpdHRlbiB0byBzdXBwb3J0IG90aGVyIGxhbmd1YWdlcy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ09NTUFORF9MSU5FX0lOVEVSRkFDRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NPTU1BTkRfTElORV9JTlRFUkZBQ0VfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzZXQ+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBEZXNjcmlwdG9yOyAgICAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorY2xhc3MgRGVzY3JpcHRvclBvb2w7ICAgICAgICAvLyBkZXNjcmlwdG9yLmgKK2NsYXNzIEZpbGVEZXNjcmlwdG9yOyAgICAgICAgLy8gZGVzY3JpcHRvci5oCitjbGFzcyBGaWxlRGVzY3JpcHRvclByb3RvOyAgIC8vIGRlc2NyaXB0b3IucGIuaAordGVtcGxhdGU8dHlwZW5hbWUgVD4gY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZDsgIC8vIHJlcGVhdGVkX2ZpZWxkLmgKKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworY2xhc3MgQ29kZUdlbmVyYXRvcjsgICAgICAgIC8vIGNvZGVfZ2VuZXJhdG9yLmgKK2NsYXNzIEdlbmVyYXRvckNvbnRleHQ7ICAgICAgLy8gY29kZV9nZW5lcmF0b3IuaAorY2xhc3MgRGlza1NvdXJjZVRyZWU7ICAgICAgIC8vIGltcG9ydGVyLmgKKworLy8gVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBjb21tYW5kLWxpbmUgaW50ZXJmYWNlIHRvIHRoZSBwcm90b2NvbCBjb21waWxlci4KKy8vIEl0IGlzIGRlc2lnbmVkIHRvIG1ha2UgaXQgdmVyeSBlYXN5IHRvIGNyZWF0ZSBhIGN1c3RvbSBwcm90b2NvbCBjb21waWxlcgorLy8gc3VwcG9ydGluZyB0aGUgbGFuZ3VhZ2VzIG9mIHlvdXIgY2hvaWNlLiAgRm9yIGV4YW1wbGUsIGlmIHlvdSB3YW50ZWQgdG8KKy8vIGNyZWF0ZSBhIGN1c3RvbSBwcm90b2NvbCBjb21waWxlciBiaW5hcnkgd2hpY2ggaW5jbHVkZXMgYm90aCB0aGUgcmVndWxhcgorLy8gQysrIHN1cHBvcnQgcGx1cyBzdXBwb3J0IGZvciB5b3VyIG93biBjdXN0b20gb3V0cHV0ICJGb28iLCB5b3Ugd291bGQKKy8vIHdyaXRlIGEgY2xhc3MgIkZvb0dlbmVyYXRvciIgd2hpY2ggaW1wbGVtZW50cyB0aGUgQ29kZUdlbmVyYXRvciBpbnRlcmZhY2UsCisvLyB0aGVuIHdyaXRlIGEgbWFpbigpIHByb2NlZHVyZSBsaWtlIHRoaXM6CisvLworLy8gICBpbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CisvLyAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvbW1hbmRMaW5lSW50ZXJmYWNlIGNsaTsKKy8vCisvLyAgICAgLy8gU3VwcG9ydCBnZW5lcmF0aW9uIG9mIEMrKyBzb3VyY2UgYW5kIGhlYWRlcnMuCisvLyAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OmNwcDo6Q3BwR2VuZXJhdG9yIGNwcF9nZW5lcmF0b3I7CisvLyAgICAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLWNwcF9vdXQiLCAmY3BwX2dlbmVyYXRvciwKKy8vICAgICAgICJHZW5lcmF0ZSBDKysgc291cmNlIGFuZCBoZWFkZXIuIik7CisvLworLy8gICAgIC8vIFN1cHBvcnQgZ2VuZXJhdGlvbiBvZiBGb28gY29kZS4KKy8vICAgICBGb29HZW5lcmF0b3IgZm9vX2dlbmVyYXRvcjsKKy8vICAgICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tZm9vX291dCIsICZmb29fZ2VuZXJhdG9yLAorLy8gICAgICAgIkdlbmVyYXRlIEZvbyBmaWxlLiIpOworLy8KKy8vICAgICByZXR1cm4gY2xpLlJ1bihhcmdjLCBhcmd2KTsKKy8vICAgfQorLy8KKy8vIFRoZSBjb21waWxlciBpcyBpbnZva2VkIHdpdGggc3ludGF4IGxpa2U6CisvLyAgIHByb3RvYyAtLWNwcF9vdXQ9b3V0ZGlyIC0tZm9vX291dD1vdXRkaXIgLS1wcm90b19wYXRoPXNyYyBzcmMvZm9vLnByb3RvCisvLworLy8gRm9yIGEgZnVsbCBkZXNjcmlwdGlvbiBvZiB0aGUgY29tbWFuZC1saW5lIHN5bnRheCwgaW52b2tlIGl0IHdpdGggLS1oZWxwLgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBDb21tYW5kTGluZUludGVyZmFjZSB7CisgcHVibGljOgorICBDb21tYW5kTGluZUludGVyZmFjZSgpOworICB+Q29tbWFuZExpbmVJbnRlcmZhY2UoKTsKKworICAvLyBSZWdpc3RlciBhIGNvZGUgZ2VuZXJhdG9yIGZvciBhIGxhbmd1YWdlLgorICAvLworICAvLyBQYXJhbWV0ZXJzOgorICAvLyAqIGZsYWdfbmFtZTogVGhlIGNvbW1hbmQtbGluZSBmbGFnIHVzZWQgdG8gc3BlY2lmeSBhbiBvdXRwdXQgZmlsZSBvZgorICAvLyAgIHRoaXMgdHlwZS4gIFRoZSBuYW1lIG11c3Qgc3RhcnQgd2l0aCBhICctJy4gIElmIHRoZSBuYW1lIGlzIGxvbmdlcgorICAvLyAgIHRoYW4gb25lIGxldHRlciwgaXQgbXVzdCBzdGFydCB3aXRoIHR3byAnLSdzLgorICAvLyAqIGdlbmVyYXRvcjogVGhlIENvZGVHZW5lcmF0b3Igd2hpY2ggd2lsbCBiZSBjYWxsZWQgdG8gZ2VuZXJhdGUgZmlsZXMKKyAgLy8gICBvZiB0aGlzIHR5cGUuCisgIC8vICogaGVscF90ZXh0OiBUZXh0IGRlc2NyaWJpbmcgdGhpcyBmbGFnIGluIHRoZSAtLWhlbHAgb3V0cHV0LgorICAvLworICAvLyBTb21lIGdlbmVyYXRvcnMgYWNjZXB0IGV4dHJhIHBhcmFtZXRlcnMuICBZb3UgY2FuIHNwZWNpZnkgdGhpcyBwYXJhbWV0ZXIKKyAgLy8gb24gdGhlIGNvbW1hbmQtbGluZSBieSBwbGFjaW5nIGl0IGJlZm9yZSB0aGUgb3V0cHV0IGRpcmVjdG9yeSwgc2VwYXJhdGVkCisgIC8vIGJ5IGEgY29sb246CisgIC8vICAgcHJvdG9jIC0tZm9vX291dD1lbmFibGVfYmFyOm91dGRpcgorICAvLyBUaGUgdGV4dCBiZWZvcmUgdGhlIGNvbG9uIGlzIHBhc3NlZCB0byBDb2RlR2VuZXJhdG9yOjpHZW5lcmF0ZSgpIGFzIHRoZQorICAvLyAicGFyYW1ldGVyIi4KKyAgdm9pZCBSZWdpc3RlckdlbmVyYXRvcihjb25zdCBzdHJpbmcmIGZsYWdfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBoZWxwX3RleHQpOworCisgIC8vIFJlZ2lzdGVyIGEgY29kZSBnZW5lcmF0b3IgZm9yIGEgbGFuZ3VhZ2UuCisgIC8vIEJlc2lkZXMgZmxhZ19uYW1lIHlvdSBjYW4gc3BlY2lmeSBhbm90aGVyIG9wdGlvbl9mbGFnX25hbWUgdGhhdCBjb3VsZCBiZQorICAvLyB1c2VkIHRvIHBhc3MgZXh0cmEgcGFyYW1ldGVycyB0byB0aGUgcmVnaXN0ZXJlZCBjb2RlIGdlbmVyYXRvci4KKyAgLy8gU3VwcG9zZSB5b3UgaGF2ZSByZWdpc3RlcmVkIGEgZ2VuZXJhdG9yIGJ5IGNhbGxpbmc6CisgIC8vICAgY29tbWFuZF9saW5lX2ludGVyZmFjZS5SZWdpc3RlckdlbmVyYXRvcigiLS1mb29fb3V0IiwgIi0tZm9vX29wdCIsIC4uLikKKyAgLy8gVGhlbiB5b3UgY291bGQgaW52b2tlIHRoZSBjb21waWxlciB3aXRoIGEgY29tbWFuZCBsaWtlOgorICAvLyAgIHByb3RvYyAtLWZvb19vdXQ9ZW5hYmxlX2JhcjpvdXRkaXIgLS1mb29fb3B0PWVuYWJsZV9iYXoKKyAgLy8gVGhpcyB3aWxsIHBhc3MgImVuYWJsZV9iYXIsZW5hYmxlX2JheiIgYXMgdGhlIHBhcmFtZXRlciB0byB0aGUgZ2VuZXJhdG9yLgorICB2b2lkIFJlZ2lzdGVyR2VuZXJhdG9yKGNvbnN0IHN0cmluZyYgZmxhZ19uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgb3B0aW9uX2ZsYWdfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBoZWxwX3RleHQpOworCisgIC8vIEVuYWJsZXMgInBsdWdpbnMiLiAgSW4gdGhpcyBtb2RlLCBpZiBhIGNvbW1hbmQtbGluZSBmbGFnIGVuZHMgd2l0aCAiX291dCIKKyAgLy8gYnV0IGRvZXMgbm90IG1hdGNoIGFueSByZWdpc3RlcmVkIGdlbmVyYXRvciwgdGhlIGNvbXBpbGVyIHdpbGwgYXR0ZW1wdCB0bworICAvLyBmaW5kIGEgInBsdWdpbiIgdG8gaW1wbGVtZW50IHRoZSBnZW5lcmF0b3IuICBQbHVnaW5zIGFyZSBqdXN0IGV4ZWN1dGFibGVzLgorICAvLyBUaGV5IHNob3VsZCBsaXZlIHNvbWV3aGVyZSBpbiB0aGUgUEFUSC4KKyAgLy8KKyAgLy8gVGhlIGNvbXBpbGVyIGRldGVybWluZXMgdGhlIGV4ZWN1dGFibGUgbmFtZSB0byBzZWFyY2ggZm9yIGJ5IGNvbmNhdGVuYXRpbmcKKyAgLy8gZXhlX25hbWVfcHJlZml4IHdpdGggdGhlIHVucmVjb2duaXplZCBmbGFnIG5hbWUsIHJlbW92aW5nICJfb3V0Ii4gIFNvLCBmb3IKKyAgLy8gZXhhbXBsZSwgaWYgZXhlX25hbWVfcHJlZml4IGlzICJwcm90b2MtIiBhbmQgeW91IHBhc3MgdGhlIGZsYWcgLS1mb29fb3V0LAorICAvLyB0aGUgY29tcGlsZXIgd2lsbCB0cnkgdG8gcnVuIHRoZSBwcm9ncmFtICJwcm90b2MtZm9vIi4KKyAgLy8KKyAgLy8gVGhlIHBsdWdpbiBwcm9ncmFtIHNob3VsZCBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZyB1c2FnZToKKyAgLy8gICBwbHVnaW4gWy0tb3V0PU9VVERJUl0gWy0tcGFyYW1ldGVyPVBBUkFNRVRFUl0gUFJPVE9fRklMRVMgPCBERVNDUklQVE9SUworICAvLyAtLW91dCBpbmRpY2F0ZXMgdGhlIG91dHB1dCBkaXJlY3RvcnkgKGFzIHBhc3NlZCB0byB0aGUgLS1mb29fb3V0CisgIC8vIHBhcmFtZXRlcik7IGlmIG9taXR0ZWQsIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBzaG91bGQgYmUgdXNlZC4gIC0tcGFyYW1ldGVyCisgIC8vIGdpdmVzIHRoZSBnZW5lcmF0b3IgcGFyYW1ldGVyLCBpZiBhbnkgd2FzIHByb3ZpZGVkLiAgVGhlIFBST1RPX0ZJTEVTIGxpc3QKKyAgLy8gdGhlIC5wcm90byBmaWxlcyB3aGljaCB3ZXJlIGdpdmVuIG9uIHRoZSBjb21waWxlciBjb21tYW5kLWxpbmU7IHRoZXNlIGFyZQorICAvLyB0aGUgZmlsZXMgZm9yIHdoaWNoIHRoZSBwbHVnaW4gaXMgZXhwZWN0ZWQgdG8gZ2VuZXJhdGUgb3V0cHV0IGNvZGUuCisgIC8vIEZpbmFsbHksIERFU0NSSVBUT1JTIGlzIGFuIGVuY29kZWQgRmlsZURlc2NyaXB0b3JTZXQgKGFzIGRlZmluZWQgaW4KKyAgLy8gZGVzY3JpcHRvci5wcm90bykuICBUaGlzIGlzIHBpcGVkIHRvIHRoZSBwbHVnaW4ncyBzdGRpbi4gIFRoZSBzZXQgd2lsbAorICAvLyBpbmNsdWRlIGRlc2NyaXB0b3JzIGZvciBhbGwgdGhlIGZpbGVzIGxpc3RlZCBpbiBQUk9UT19GSUxFUyBhcyB3ZWxsIGFzCisgIC8vIGFsbCBmaWxlcyB0aGF0IHRoZXkgaW1wb3J0LiAgVGhlIHBsdWdpbiBNVVNUIE5PVCBhdHRlbXB0IHRvIHJlYWQgdGhlCisgIC8vIFBST1RPX0ZJTEVTIGRpcmVjdGx5IC0tIGl0IG11c3QgdXNlIHRoZSBGaWxlRGVzY3JpcHRvclNldC4KKyAgLy8KKyAgLy8gVGhlIHBsdWdpbiBzaG91bGQgZ2VuZXJhdGUgd2hhdGV2ZXIgZmlsZXMgYXJlIG5lY2Vzc2FyeSwgYXMgY29kZSBnZW5lcmF0b3JzCisgIC8vIG5vcm1hbGx5IGRvLiAgSXQgc2hvdWxkIHdyaXRlIHRoZSBuYW1lcyBvZiBhbGwgZmlsZXMgaXQgZ2VuZXJhdGVzIHRvCisgIC8vIHN0ZG91dC4gIFRoZSBuYW1lcyBzaG91bGQgYmUgcmVsYXRpdmUgdG8gdGhlIG91dHB1dCBkaXJlY3RvcnksIE5PVCBhYnNvbHV0ZQorICAvLyBuYW1lcyBvciByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBkaXJlY3RvcnkuICBJZiBhbnkgZXJyb3JzIG9jY3VyLCBlcnJvcgorICAvLyBtZXNzYWdlcyBzaG91bGQgYmUgd3JpdHRlbiB0byBzdGRlcnIuICBJZiBhbiBlcnJvciBpcyBmYXRhbCwgdGhlIHBsdWdpbgorICAvLyBzaG91bGQgZXhpdCB3aXRoIGEgbm9uLXplcm8gZXhpdCBjb2RlLgorICB2b2lkIEFsbG93UGx1Z2lucyhjb25zdCBzdHJpbmcmIGV4ZV9uYW1lX3ByZWZpeCk7CisKKyAgLy8gUnVuIHRoZSBQcm90b2NvbCBDb21waWxlciB3aXRoIHRoZSBnaXZlbiBjb21tYW5kLWxpbmUgcGFyYW1ldGVycy4KKyAgLy8gUmV0dXJucyB0aGUgZXJyb3IgY29kZSB3aGljaCBzaG91bGQgYmUgcmV0dXJuZWQgYnkgbWFpbigpLgorICAvLworICAvLyBJdCBtYXkgbm90IGJlIHNhZmUgdG8gY2FsbCBSdW4oKSBpbiBhIG11bHRpLXRocmVhZGVkIGVudmlyb25tZW50IGJlY2F1c2UKKyAgLy8gaXQgY2FsbHMgc3RyZXJyb3IoKS4gIEknbSBub3Qgc3VyZSB3aHkgeW91J2Qgd2FudCB0byBkbyB0aGlzIGFueXdheS4KKyAgaW50IFJ1bihpbnQgYXJnYywgY29uc3QgY2hhciogY29uc3QgYXJndltdKTsKKworICAvLyBDYWxsIFNldElucHV0c0FyZUN3ZFJlbGF0aXZlKHRydWUpIGlmIHRoZSBpbnB1dCBmaWxlcyBnaXZlbiBvbiB0aGUgY29tbWFuZAorICAvLyBsaW5lIHNob3VsZCBiZSBpbnRlcnByZXRlZCByZWxhdGl2ZSB0byB0aGUgcHJvdG8gaW1wb3J0IHBhdGggc3BlY2lmaWVkCisgIC8vIHVzaW5nIC0tcHJvdG9fcGF0aCBvciAtSSBmbGFncy4gIE90aGVyd2lzZSwgaW5wdXQgZmlsZSBuYW1lcyB3aWxsIGJlCisgIC8vIGludGVycHJldGVkIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IChvciBhcyBhYnNvbHV0ZQorICAvLyBwYXRocyBpZiB0aGV5IHN0YXJ0IHdpdGggJy8nKSwgdGhvdWdoIHRoZXkgbXVzdCBzdGlsbCByZXNpZGUgaW5zaWRlCisgIC8vIGEgZGlyZWN0b3J5IGdpdmVuIGJ5IC0tcHJvdG9fcGF0aCBvciB0aGUgY29tcGlsZXIgd2lsbCBmYWlsLiAgVGhlIGxhdHRlcgorICAvLyBtb2RlIGlzIGdlbmVyYWxseSBtb3JlIGludHVpdGl2ZSBhbmQgZWFzaWVyIHRvIHVzZSwgZXNwZWNpYWxseSBlLmcuIHdoZW4KKyAgLy8gZGVmaW5pbmcgaW1wbGljaXQgcnVsZXMgaW4gTWFrZWZpbGVzLgorICB2b2lkIFNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKGJvb2wgZW5hYmxlKSB7CisgICAgaW5wdXRzX2FyZV9wcm90b19wYXRoX3JlbGF0aXZlXyA9IGVuYWJsZTsKKyAgfQorCisgIC8vIFByb3ZpZGVzIHNvbWUgdGV4dCB3aGljaCB3aWxsIGJlIHByaW50ZWQgd2hlbiB0aGUgLS12ZXJzaW9uIGZsYWcgaXMKKyAgLy8gdXNlZC4gIFRoZSB2ZXJzaW9uIG9mIGxpYnByb3RvYyB3aWxsIGFsc28gYmUgcHJpbnRlZCBvbiB0aGUgbmV4dCBsaW5lCisgIC8vIGFmdGVyIHRoaXMgdGV4dC4KKyAgdm9pZCBTZXRWZXJzaW9uSW5mbyhjb25zdCBzdHJpbmcmIHRleHQpIHsKKyAgICB2ZXJzaW9uX2luZm9fID0gdGV4dDsKKyAgfQorCisKKyBwcml2YXRlOgorICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGNsYXNzIEVycm9yUHJpbnRlcjsKKyAgY2xhc3MgR2VuZXJhdG9yQ29udGV4dEltcGw7CisgIGNsYXNzIE1lbW9yeU91dHB1dFN0cmVhbTsKKyAgdHlwZWRlZiBoYXNoX21hcDxzdHJpbmcsIEdlbmVyYXRvckNvbnRleHRJbXBsKj4gR2VuZXJhdG9yQ29udGV4dE1hcDsKKworICAvLyBDbGVhciBzdGF0ZSBmcm9tIHByZXZpb3VzIFJ1bigpLgorICB2b2lkIENsZWFyKCk7CisKKyAgLy8gUmVtYXBzIGVhY2ggZmlsZSBpbiBpbnB1dF9maWxlc18gc28gdGhhdCBpdCBpcyByZWxhdGl2ZSB0byBvbmUgb2YgdGhlCisgIC8vIGRpcmVjdG9yaWVzIGluIHByb3RvX3BhdGhfLiAgUmV0dXJucyBmYWxzZSBpZiBhbiBlcnJvciBvY2N1cnJlZC4gIFRoaXMKKyAgLy8gaXMgb25seSB1c2VkIGlmIGlucHV0c19hcmVfcHJvdG9fcGF0aF9yZWxhdGl2ZV8gaXMgZmFsc2UuCisgIGJvb2wgTWFrZUlucHV0c0JlUHJvdG9QYXRoUmVsYXRpdmUoCisgICAgRGlza1NvdXJjZVRyZWUqIHNvdXJjZV90cmVlKTsKKworICAvLyBSZXR1cm4gc3RhdHVzIGZvciBQYXJzZUFyZ3VtZW50cygpIGFuZCBJbnRlcnByZXRBcmd1bWVudCgpLgorICBlbnVtIFBhcnNlQXJndW1lbnRTdGF0dXMgeworICAgIFBBUlNFX0FSR1VNRU5UX0RPTkVfQU5EX0NPTlRJTlVFLAorICAgIFBBUlNFX0FSR1VNRU5UX0RPTkVfQU5EX0VYSVQsCisgICAgUEFSU0VfQVJHVU1FTlRfRkFJTAorICB9OworCisgIC8vIFBhcnNlIGFsbCBjb21tYW5kLWxpbmUgYXJndW1lbnRzLgorICBQYXJzZUFyZ3VtZW50U3RhdHVzIFBhcnNlQXJndW1lbnRzKGludCBhcmdjLCBjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pOworCisgIC8vIFBhcnNlcyBhIGNvbW1hbmQtbGluZSBhcmd1bWVudCBpbnRvIGEgbmFtZS92YWx1ZSBwYWlyLiAgUmV0dXJucworICAvLyB0cnVlIGlmIHRoZSBuZXh0IGFyZ3VtZW50IGluIHRoZSBhcmd2IHNob3VsZCBiZSB1c2VkIGFzIHRoZSB2YWx1ZSwKKyAgLy8gZmFsc2Ugb3RoZXJ3aXNlLgorICAvLworICAvLyBFeGFtcGxlczoKKyAgLy8gICAiLUlzcmMvcHJvdG9zIiAtPgorICAvLyAgICAgbmFtZSA9ICItSSIsIHZhbHVlID0gInNyYy9wcm90b3MiCisgIC8vICAgIi0tY3BwX291dD1zcmMvZm9vLnBiMi5jYyIgLT4KKyAgLy8gICAgIG5hbWUgPSAiLS1jcHBfb3V0IiwgdmFsdWUgPSAic3JjL2Zvby5wYjIuY2MiCisgIC8vICAgImZvby5wcm90byIgLT4KKyAgLy8gICAgIG5hbWUgPSAiIiwgdmFsdWUgPSAiZm9vLnByb3RvIgorICBib29sIFBhcnNlQXJndW1lbnQoY29uc3QgY2hhciogYXJnLCBzdHJpbmcqIG5hbWUsIHN0cmluZyogdmFsdWUpOworCisgIC8vIEludGVycHJldHMgYXJndW1lbnRzIHBhcnNlZCB3aXRoIFBhcnNlQXJndW1lbnQuCisgIFBhcnNlQXJndW1lbnRTdGF0dXMgSW50ZXJwcmV0QXJndW1lbnQoY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpOworCisgIC8vIFByaW50IHRoZSAtLWhlbHAgdGV4dCB0byBzdGRlcnIuCisgIHZvaWQgUHJpbnRIZWxwVGV4dCgpOworCisgIC8vIEdlbmVyYXRlIHRoZSBnaXZlbiBvdXRwdXQgZmlsZSBmcm9tIHRoZSBnaXZlbiBpbnB1dC4KKyAgc3RydWN0IE91dHB1dERpcmVjdGl2ZTsgIC8vIHNlZSBiZWxvdworICBib29sIEdlbmVyYXRlT3V0cHV0KGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBwYXJzZWRfZmlsZXMsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3V0cHV0RGlyZWN0aXZlJiBvdXRwdXRfZGlyZWN0aXZlLAorICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0KTsKKyAgYm9vbCBHZW5lcmF0ZVBsdWdpbk91dHB1dChjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGx1Z2luX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcik7CisKKyAgLy8gSW1wbGVtZW50cyAtLWVuY29kZSBhbmQgLS1kZWNvZGUuCisgIGJvb2wgRW5jb2RlT3JEZWNvZGUoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpOworCisgIC8vIEltcGxlbWVudHMgdGhlIC0tZGVzY3JpcHRvcl9zZXRfb3V0IG9wdGlvbi4KKyAgYm9vbCBXcml0ZURlc2NyaXB0b3JTZXQoY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gcGFyc2VkX2ZpbGVzKTsKKworICAvLyBJbXBsZW1lbnRzIHRoZSAtLWRlcGVuZGVuY3lfb3V0IG9wdGlvbgorICBib29sIEdlbmVyYXRlRGVwZW5kZW5jeU1hbmlmZXN0RmlsZSgKKyAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBwYXJzZWRfZmlsZXMsCisgICAgICBjb25zdCBHZW5lcmF0b3JDb250ZXh0TWFwJiBvdXRwdXRfZGlyZWN0b3JpZXMsCisgICAgICBEaXNrU291cmNlVHJlZSogc291cmNlX3RyZWUpOworCisgIC8vIEdldCBhbGwgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMgb2YgdGhlIGdpdmVuIGZpbGUgKGluY2x1ZGluZyB0aGUgZmlsZQorICAvLyBpdHNlbGYpLCBhZGRpbmcgdGhlbSB0byB0aGUgZ2l2ZW4gbGlzdCBvZiBGaWxlRGVzY3JpcHRvclByb3Rvcy4gIFRoZQorICAvLyBwcm90b3Mgd2lsbCBiZSBvcmRlcmVkIHN1Y2ggdGhhdCBldmVyeSBmaWxlIGlzIGxpc3RlZCBiZWZvcmUgYW55IGZpbGUgdGhhdAorICAvLyBkZXBlbmRzIG9uIGl0LCBzbyB0aGF0IHlvdSBjYW4gY2FsbCBEZXNjcmlwdG9yUG9vbDo6QnVpbGRGaWxlKCkgb24gdGhlbQorICAvLyBpbiBvcmRlci4gIEFueSBmaWxlcyBpbiAqYWxyZWFkeV9zZWVuIHdpbGwgbm90IGJlIGFkZGVkLCBhbmQgZWFjaCBmaWxlCisgIC8vIGFkZGVkIHdpbGwgYmUgaW5zZXJ0ZWQgaW50byAqYWxyZWFkeV9zZWVuLiAgSWYgaW5jbHVkZV9zb3VyY2VfY29kZV9pbmZvIGlzCisgIC8vIHRydWUgdGhlbiBpbmNsdWRlIHRoZSBzb3VyY2UgY29kZSBpbmZvcm1hdGlvbiBpbiB0aGUgRmlsZURlc2NyaXB0b3JQcm90b3MuCisgIHN0YXRpYyB2b2lkIEdldFRyYW5zaXRpdmVEZXBlbmRlbmNpZXMoCisgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgIGJvb2wgaW5jbHVkZV9zb3VyY2VfY29kZV9pbmZvLAorICAgICAgc2V0PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4qIGFscmVhZHlfc2VlbiwKKyAgICAgIFJlcGVhdGVkUHRyRmllbGQ8RmlsZURlc2NyaXB0b3JQcm90bz4qIG91dHB1dCk7CisKKyAgLy8gSW1wbGVtZW50cyB0aGUgLS1wcmludF9mcmVlX2ZpZWxkX251bWJlcnMuIFRoaXMgZnVuY3Rpb24gcHJpbnRzIGZyZWUgZmllbGQKKyAgLy8gbnVtYmVycyBpbnRvIHN0ZG91dCBmb3IgdGhlIG1lc3NhZ2UgYW5kIGl0J3MgbmVzdGVkIG1lc3NhZ2UgdHlwZXMgaW4KKyAgLy8gcG9zdC1vcmRlciwgaS5lLiBuZXN0ZWQgdHlwZXMgZmlyc3QuIFByaW50ZWQgcmFuZ2UgYXJlIGxlZnQtcmlnaHQKKyAgLy8gaW5jbHVzaXZlLCBpLmUuIFthLCBiXS4KKyAgLy8KKyAgLy8gR3JvdXBzOgorICAvLyBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBncm91cHMgYXJlIGNvbnNpZGVyZWQgdG8gc2hhcmUgdGhlIHNhbWUKKyAgLy8gZmllbGQgbnVtYmVyIHNwYWNlIHdpdGggdGhlIHBhcmVudCBtZXNzYWdlLCB0aHVzIGl0IHdpbGwgbm90IHByaW50IGZyZWUKKyAgLy8gZmllbGQgbnVtYmVycyBmb3IgZ3JvdXBzLiBUaGUgZmllbGQgbnVtYmVycyB1c2VkIGluIHRoZSBncm91cHMgYXJlCisgIC8vIGV4Y2x1ZGVkIGluIHRoZSBmcmVlIGZpZWxkIG51bWJlcnMgb2YgdGhlIHBhcmVudCBtZXNzYWdlLgorICAvLworICAvLyBFeHRlbnNpb24gUmFuZ2VzOgorICAvLyBFeHRlbnNpb24gcmFuZ2VzIGFyZSBjb25zaWRlcmVkIG9jdXBwaWVkIGZpZWxkIG51bWJlcnMgYW5kIHRoZXkgd2lsbCBub3QgYmUKKyAgLy8gbGlzdGVkIGFzIGZyZWUgbnVtYmVycyBpbiB0aGUgb3V0cHV0LgorICB2b2lkIFByaW50RnJlZUZpZWxkTnVtYmVycyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFRoZSBuYW1lIG9mIHRoZSBleGVjdXRhYmxlIGFzIGludm9rZWQgKGkuZS4gYXJndlswXSkuCisgIHN0cmluZyBleGVjdXRhYmxlX25hbWVfOworCisgIC8vIFZlcnNpb24gaW5mbyBzZXQgd2l0aCBTZXRWZXJzaW9uSW5mbygpLgorICBzdHJpbmcgdmVyc2lvbl9pbmZvXzsKKworICAvLyBSZWdpc3RlcmVkIGdlbmVyYXRvcnMuCisgIHN0cnVjdCBHZW5lcmF0b3JJbmZvIHsKKyAgICBzdHJpbmcgZmxhZ19uYW1lOworICAgIHN0cmluZyBvcHRpb25fZmxhZ19uYW1lOworICAgIENvZGVHZW5lcmF0b3IqIGdlbmVyYXRvcjsKKyAgICBzdHJpbmcgaGVscF90ZXh0OworICB9OworICB0eXBlZGVmIG1hcDxzdHJpbmcsIEdlbmVyYXRvckluZm8+IEdlbmVyYXRvck1hcDsKKyAgR2VuZXJhdG9yTWFwIGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lXzsKKyAgR2VuZXJhdG9yTWFwIGdlbmVyYXRvcnNfYnlfb3B0aW9uX25hbWVfOworICAvLyBBIG1hcCBmcm9tIGdlbmVyYXRvciBuYW1lcyB0byB0aGUgcGFyYW1ldGVycyBzcGVjaWZpZWQgdXNpbmcgdGhlIG9wdGlvbgorICAvLyBmbGFnLiBGb3IgZXhhbXBsZSwgaWYgdGhlIHVzZXIgaW52b2tlcyB0aGUgY29tcGlsZXIgd2l0aDoKKyAgLy8gICBwcm90b2MgLS1mb29fb3V0PW91dHB1dGRpciAtLWZvb19vcHQ9ZW5hYmxlX2JhciAuLi4KKyAgLy8gVGhlbiB0aGVyZSB3aWxsIGJlIGFuIGVudHJ5ICgiLS1mb29fb3V0IiwgImVuYWJsZV9iYXIiKSBpbiB0aGlzIG1hcC4KKyAgbWFwPHN0cmluZywgc3RyaW5nPiBnZW5lcmF0b3JfcGFyYW1ldGVyc187CisKKyAgLy8gU2VlIEFsbG93UGx1Z2lucygpLiAgSWYgdGhpcyBpcyBlbXB0eSwgcGx1Z2lucyBhcmVuJ3QgYWxsb3dlZC4KKyAgc3RyaW5nIHBsdWdpbl9wcmVmaXhfOworCisgIC8vIE1hcHMgc3BlY2lmaWMgcGx1Z2luIG5hbWVzIHRvIGZpbGVzLiAgV2hlbiBleGVjdXRpbmcgYSBwbHVnaW4sIHRoaXMgbWFwCisgIC8vIGlzIHNlYXJjaGVkIGZpcnN0IHRvIGZpbmQgdGhlIHBsdWdpbiBleGVjdXRhYmxlLiAgSWYgbm90IGZvdW5kIGhlcmUsIHRoZQorICAvLyBQQVRIIChvciBvdGhlciBPUy1zcGVjaWZpYyBzZWFyY2ggc3RyYXRlZ3kpIGlzIHNlYXJjaGVkLgorICBtYXA8c3RyaW5nLCBzdHJpbmc+IHBsdWdpbnNfOworCisgIC8vIFN0dWZmIHBhcnNlZCBmcm9tIGNvbW1hbmQgbGluZS4KKyAgZW51bSBNb2RlIHsKKyAgICBNT0RFX0NPTVBJTEUsICAvLyBOb3JtYWwgbW9kZTogIHBhcnNlIC5wcm90byBmaWxlcyBhbmQgY29tcGlsZSB0aGVtLgorICAgIE1PREVfRU5DT0RFLCAgIC8vIC0tZW5jb2RlOiAgcmVhZCB0ZXh0IGZyb20gc3RkaW4sIHdyaXRlIGJpbmFyeSB0byBzdGRvdXQuCisgICAgTU9ERV9ERUNPREUsICAgLy8gLS1kZWNvZGU6ICByZWFkIGJpbmFyeSBmcm9tIHN0ZGluLCB3cml0ZSB0ZXh0IHRvIHN0ZG91dC4KKyAgICBNT0RFX1BSSU5ULCAgICAvLyBQcmludCBtb2RlOiBwcmludCBpbmZvIG9mIHRoZSBnaXZlbiAucHJvdG8gZmlsZXMgYW5kIGV4aXQuCisgIH07CisKKyAgTW9kZSBtb2RlXzsKKworICBlbnVtIFByaW50TW9kZSB7CisgICAgUFJJTlRfTk9ORSwgICAgICAgICAgICAgICAvLyBOb3QgaW4gTU9ERV9QUklOVAorICAgIFBSSU5UX0ZSRUVfRklFTERTLCAgICAgICAgLy8gLS1wcmludF9mcmVlX2ZpZWxkcworICB9OworCisgIFByaW50TW9kZSBwcmludF9tb2RlXzsKKworICBlbnVtIEVycm9yRm9ybWF0IHsKKyAgICBFUlJPUl9GT1JNQVRfR0NDLCAgIC8vIEdDQyBlcnJvciBvdXRwdXQgZm9ybWF0IChkZWZhdWx0KS4KKyAgICBFUlJPUl9GT1JNQVRfTVNWUyAgIC8vIFZpc3VhbCBTdHVkaW8gb3V0cHV0ICgtLWVycm9yX2Zvcm1hdD1tc3ZzKS4KKyAgfTsKKworICBFcnJvckZvcm1hdCBlcnJvcl9mb3JtYXRfOworCisgIHZlY3RvcjxwYWlyPHN0cmluZywgc3RyaW5nPiA+IHByb3RvX3BhdGhfOyAgLy8gU2VhcmNoIHBhdGggZm9yIHByb3RvIGZpbGVzLgorICB2ZWN0b3I8c3RyaW5nPiBpbnB1dF9maWxlc187ICAgICAgICAgICAgICAgIC8vIE5hbWVzIG9mIHRoZSBpbnB1dCBwcm90byBmaWxlcy4KKworICAvLyBvdXRwdXRfZGlyZWN0aXZlc18gbGlzdHMgYWxsIHRoZSBmaWxlcyB3ZSBhcmUgc3VwcG9zZWQgdG8gb3V0cHV0IGFuZCB3aGF0CisgIC8vIGdlbmVyYXRvciB0byB1c2UgZm9yIGVhY2guCisgIHN0cnVjdCBPdXRwdXREaXJlY3RpdmUgeworICAgIHN0cmluZyBuYW1lOyAgICAgICAgICAgICAgICAvLyBFLmcuICItLWZvb19vdXQiCisgICAgQ29kZUdlbmVyYXRvciogZ2VuZXJhdG9yOyAgIC8vIE5VTEwgZm9yIHBsdWdpbnMKKyAgICBzdHJpbmcgcGFyYW1ldGVyOworICAgIHN0cmluZyBvdXRwdXRfbG9jYXRpb247CisgIH07CisgIHZlY3RvcjxPdXRwdXREaXJlY3RpdmU+IG91dHB1dF9kaXJlY3RpdmVzXzsKKworICAvLyBXaGVuIHVzaW5nIC0tZW5jb2RlIG9yIC0tZGVjb2RlLCB0aGlzIG5hbWVzIHRoZSB0eXBlIHdlIGFyZSBlbmNvZGluZyBvcgorICAvLyBkZWNvZGluZy4gIChFbXB0eSBzdHJpbmcgaW5kaWNhdGVzIC0tZGVjb2RlX3Jhdy4pCisgIHN0cmluZyBjb2RlY190eXBlXzsKKworICAvLyBJZiAtLWRlc2NyaXB0b3Jfc2V0X291dCB3YXMgZ2l2ZW4sIHRoaXMgaXMgdGhlIGZpbGVuYW1lIHRvIHdoaWNoIHRoZQorICAvLyBGaWxlRGVzY3JpcHRvclNldCBzaG91bGQgYmUgd3JpdHRlbi4gIE90aGVyd2lzZSwgZW1wdHkuCisgIHN0cmluZyBkZXNjcmlwdG9yX3NldF9uYW1lXzsKKworICAvLyBJZiAtLWRlcGVuZGVuY3lfb3V0IHdhcyBnaXZlbiwgdGhpcyBpcyB0aGUgcGF0aCB0byB0aGUgZmlsZSB3aGVyZSB0aGUKKyAgLy8gZGVwZW5kZW5jeSBmaWxlIHdpbGwgYmUgd3JpdHRlbi4gT3RoZXJ3aXNlLCBlbXB0eS4KKyAgc3RyaW5nIGRlcGVuZGVuY3lfb3V0X25hbWVfOworCisgIC8vIFRydWUgaWYgLS1pbmNsdWRlX2ltcG9ydHMgd2FzIGdpdmVuLCBtZWFuaW5nIHRoYXQgd2Ugc2hvdWxkCisgIC8vIHdyaXRlIGFsbCB0cmFuc2l0aXZlIGRlcGVuZGVuY2llcyB0byB0aGUgRGVzY3JpcHRvclNldC4gIE90aGVyd2lzZSwgb25seQorICAvLyB0aGUgLnByb3RvIGZpbGVzIGxpc3RlZCBvbiB0aGUgY29tbWFuZC1saW5lIGFyZSBhZGRlZC4KKyAgYm9vbCBpbXBvcnRzX2luX2Rlc2NyaXB0b3Jfc2V0XzsKKworICAvLyBUcnVlIGlmIC0taW5jbHVkZV9zb3VyY2VfaW5mbyB3YXMgZ2l2ZW4sIG1lYW5pbmcgdGhhdCB3ZSBzaG91bGQgbm90IHN0cmlwCisgIC8vIFNvdXJjZUNvZGVJbmZvIGZyb20gdGhlIERlc2NyaXB0b3JTZXQuCisgIGJvb2wgc291cmNlX2luZm9faW5fZGVzY3JpcHRvcl9zZXRfOworCisgIC8vIFdhcyB0aGUgLS1kaXNhbGxvd19zZXJ2aWNlcyBmbGFnIHVzZWQ/CisgIGJvb2wgZGlzYWxsb3dfc2VydmljZXNfOworCisgIC8vIFNlZSBTZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZSgpLgorICBib29sIGlucHV0c19hcmVfcHJvdG9fcGF0aF9yZWxhdGl2ZV87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvbW1hbmRMaW5lSW50ZXJmYWNlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NPTU1BTkRfTElORV9JTlRFUkZBQ0VfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2VfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2VfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmIyNmYzYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZV91bml0dGVzdC5jYwpAQCAtMCwwICsxLDE3NTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpZmRlZiBfTVNDX1ZFUgorI2luY2x1ZGUgPGlvLmg+CisjZWxzZQorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2VuZGlmCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworCisvLyBEaXNhYmxlIHRoZSB3aG9sZSB0ZXN0IHdoZW4gd2UgdXNlIHRjbWFsbG9jIGZvciAiZHJhY29uaWFuIiBoZWFwIGNoZWNrcywgaW4KKy8vIHdoaWNoIGNhc2UgdGNtYWxsb2Mgd2lsbCBwcmludCB3YXJuaW5ncyB0aGF0IGZhaWwgdGhlIHBsdWdpbiB0ZXN0cy4KKyNpZiAhR09PR0xFX1BST1RPQlVGX0hFQVBfQ0hFQ0tfRFJBQ09OSUFOCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCisjaWYgZGVmaW5lZChfV0lOMzIpCisjaWZuZGVmIFNURElOX0ZJTEVOTworI2RlZmluZSBTVERJTl9GSUxFTk8gMAorI2VuZGlmCisjaWZuZGVmIFNURE9VVF9GSUxFTk8KKyNkZWZpbmUgU1RET1VUX0ZJTEVOTyAxCisjZW5kaWYKKyNpZm5kZWYgRl9PSworI2RlZmluZSBGX09LIDAwICAvLyBub3QgZGVmaW5lZCBieSBNU1ZDIGZvciB3aGF0ZXZlciByZWFzb24KKyNlbmRpZgorI2VuZGlmCisKK25hbWVzcGFjZSB7CisKK2Jvb2wgRmlsZUV4aXN0cyhjb25zdCBzdHJpbmcmIHBhdGgpIHsKKyAgcmV0dXJuIEZpbGU6OkV4aXN0cyhwYXRoKTsKK30KKworY2xhc3MgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdmlydHVhbCB2b2lkIFNldFVwKCk7CisgIHZpcnR1YWwgdm9pZCBUZWFyRG93bigpOworCisgIC8vIFJ1bnMgdGhlIENvbW1hbmRMaW5lSW50ZXJmYWNlIHdpdGggdGhlIGdpdmVuIGNvbW1hbmQgbGluZS4gIFRoZQorICAvLyBjb21tYW5kIGlzIGF1dG9tYXRpY2FsbHkgc3BsaXQgb24gc3BhY2VzLCBhbmQgdGhlIHN0cmluZyAiJHRtcGRpciIKKyAgLy8gaXMgcmVwbGFjZWQgd2l0aCBUZXN0VGVtcERpcigpLgorICB2b2lkIFJ1bihjb25zdCBzdHJpbmcmIGNvbW1hbmQpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIE1ldGhvZHMgdG8gc2V0IHVwIHRoZSB0ZXN0IChjYWxsZWQgYmVmb3JlIFJ1bigpKS4KKworICBjbGFzcyBOdWxsQ29kZUdlbmVyYXRvcjsKKworICAvLyBOb3JtYWxseSBwbHVnaW5zIGFyZSBhbGxvd2VkIGZvciBhbGwgdGVzdHMuICBDYWxsIHRoaXMgdG8gZXhwbGljaXRseQorICAvLyBkaXNhYmxlIHRoZW0uCisgIHZvaWQgRGlzYWxsb3dQbHVnaW5zKCkgeyBkaXNhbGxvd19wbHVnaW5zXyA9IHRydWU7IH0KKworICAvLyBDcmVhdGUgYSB0ZW1wIGZpbGUgd2l0aGluIHRlbXBfZGlyZWN0b3J5XyB3aXRoIHRoZSBnaXZlbiBuYW1lLgorICAvLyBUaGUgY29udGFpbmluZyBkaXJlY3RvcnkgaXMgYWxzbyBjcmVhdGVkIGlmIG5lY2Vzc2FyeS4KKyAgdm9pZCBDcmVhdGVUZW1wRmlsZShjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyYgY29udGVudHMpOworCisgIC8vIENyZWF0ZSBhIHN1YmRpcmVjdG9yeSB3aXRoaW4gdGVtcF9kaXJlY3RvcnlfLgorICB2b2lkIENyZWF0ZVRlbXBEaXIoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICAvLyBDaGFuZ2Ugd29ya2luZyBkaXJlY3RvcnkgdG8gdGVtcCBkaXJlY3RvcnkuCisgIHZvaWQgU3dpdGNoVG9UZW1wRGlyZWN0b3J5KCkgeworICAgIEZpbGU6OkNoYW5nZVdvcmtpbmdEaXJlY3RvcnkodGVtcF9kaXJlY3RvcnlfKTsKKyAgfQorCisgIHZvaWQgU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUoYm9vbCBlbmFibGUpIHsKKyAgICBjbGlfLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKGVuYWJsZSk7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBNZXRob2RzIHRvIGNoZWNrIHRoZSB0ZXN0IHJlc3VsdHMgKGNhbGxlZCBhZnRlciBSdW4oKSkuCisKKyAgLy8gQ2hlY2tzIHRoYXQgbm8gdGV4dCB3YXMgd3JpdHRlbiB0byBzdGRlcnIgZHVyaW5nIFJ1bigpLCBhbmQgUnVuKCkKKyAgLy8gcmV0dXJuZWQgMC4KKyAgdm9pZCBFeHBlY3ROb0Vycm9ycygpOworCisgIC8vIENoZWNrcyB0aGF0IFJ1bigpIHJldHVybmVkIG5vbi16ZXJvIGFuZCB0aGUgc3RkZXJyIG91dHB1dCBpcyBleGFjdGx5CisgIC8vIHRoZSB0ZXh0IGdpdmVuLiAgZXhwZWN0ZWRfdGVzdCBtYXkgY29udGFpbiByZWZlcmVuY2VzIHRvICIkdG1wZGlyIiwKKyAgLy8gd2hpY2ggd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgdGVtcG9yYXJ5IGRpcmVjdG9yeSBwYXRoLgorICB2b2lkIEV4cGVjdEVycm9yVGV4dChjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3RleHQpOworCisgIC8vIENoZWNrcyB0aGF0IFJ1bigpIHJldHVybmVkIG5vbi16ZXJvIGFuZCB0aGUgc3RkZXJyIGNvbnRhaW5zIHRoZSBnaXZlbgorICAvLyBzdWJzdHJpbmcuCisgIHZvaWQgRXhwZWN0RXJyb3JTdWJzdHJpbmcoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9zdWJzdHJpbmcpOworCisgIC8vIExpa2UgRXhwZWN0RXJyb3JTdWJzdHJpbmcsIGJ1dCBjaGVja3MgdGhhdCBSdW4oKSByZXR1cm5lZCB6ZXJvLgorICB2b2lkIEV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKAorICAgICAgY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9zdWJzdHJpbmcpOworCisgIC8vIENoZWNrcyB0aGF0IHRoZSBjYXB0dXJlZCBzdGRvdXQgaXMgdGhlIHNhbWUgYXMgdGhlIGV4cGVjdGVkX3RleHQuCisgIHZvaWQgRXhwZWN0Q2FwdHVyZWRTdGRvdXQoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF90ZXh0KTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgRXhwZWN0RXJyb3JTdWJzdHJpbmcoZXhwZWN0ZWRfc3Vic3RyaW5nKSB3b3VsZCBwYXNzLCBidXQKKyAgLy8gZG9lcyBub3QgZmFpbCBvdGhlcndpc2UuCisgIGJvb2wgSGFzQWx0ZXJuYXRlRXJyb3JTdWJzdHJpbmcoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9zdWJzdHJpbmcpOworCisgIC8vIENoZWNrcyB0aGF0IE1vY2tDb2RlR2VuZXJhdG9yOjpHZW5lcmF0ZSgpIHdhcyBjYWxsZWQgaW4gdGhlIGdpdmVuCisgIC8vIGNvbnRleHQgKG9yIHRoZSBnZW5lcmF0b3IgaW4gdGVzdF9wbHVnaW4uY2MsIHdoaWNoIHByb2R1Y2VzIHRoZSBzYW1lCisgIC8vIG91dHB1dCkuICBUaGF0IGlzLCB0aGlzIHRlc3RzIGlmIHRoZSBnZW5lcmF0b3Igd2l0aCB0aGUgZ2l2ZW4gbmFtZQorICAvLyB3YXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuIHBhcmFtZXRlciBhbmQgcHJvdG8gZmlsZSBhbmQgcHJvZHVjZWQgdGhlCisgIC8vIGdpdmVuIG91dHB1dCBmaWxlLiAgVGhpcyBpcyBjaGVja2VkIGJ5IHJlYWRpbmcgdGhlIG91dHB1dCBmaWxlIGFuZAorICAvLyBjaGVja2luZyB0aGF0IGl0IGNvbnRhaW5zIHRoZSBjb250ZW50IHRoYXQgTW9ja0NvZGVHZW5lcmF0b3Igd291bGQKKyAgLy8gZ2VuZXJhdGUgZ2l2ZW4gdGhlc2UgaW5wdXRzLiAgbWVzc2FnZV9uYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBmaXJzdAorICAvLyBtZXNzYWdlIHRoYXQgYXBwZWFyZWQgaW4gdGhlIHByb3RvIGZpbGU7IHRoaXMgaXMganVzdCB0byBtYWtlIGV4dHJhCisgIC8vIHN1cmUgdGhhdCB0aGUgY29ycmVjdCBmaWxlIHdhcyBwYXJzZWQuCisgIHZvaWQgRXhwZWN0R2VuZXJhdGVkKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lKTsKKyAgdm9pZCBFeHBlY3RHZW5lcmF0ZWQoY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJvdG9fbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgb3V0cHV0X2RpcmVjdG9yeSk7CisgIHZvaWQgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgYWxsX3Byb3RvX25hbWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lKTsKKyAgdm9pZCBFeHBlY3RHZW5lcmF0ZWRXaXRoSW5zZXJ0aW9ucyhjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUpOworCisgIHZvaWQgRXhwZWN0TnVsbENvZGVHZW5lcmF0b3JDYWxsZWQoY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIpOworCisgIHZvaWQgUmVhZERlc2NyaXB0b3JTZXQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclNldCogZGVzY3JpcHRvcl9zZXQpOworCisgIHZvaWQgRXhwZWN0RmlsZUNvbnRlbnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGNvbnRlbnQpOworCisgcHJpdmF0ZToKKyAgLy8gVGhlIG9iamVjdCB3ZSBhcmUgdGVzdGluZy4KKyAgQ29tbWFuZExpbmVJbnRlcmZhY2UgY2xpXzsKKworICAvLyBXYXMgRGlzYWxsb3dQbHVnaW5zKCkgY2FsbGVkPworICBib29sIGRpc2FsbG93X3BsdWdpbnNfOworCisgIC8vIFdlIGNyZWF0ZSBhIGRpcmVjdG9yeSB3aXRoaW4gVGVzdFRlbXBEaXIoKSBpbiBvcmRlciB0byBhZGQgZXh0cmEKKyAgLy8gcHJvdGVjdGlvbiBhZ2FpbnN0IGFjY2lkZW50YWxseSBkZWxldGluZyB1c2VyIGZpbGVzIChzaW5jZSB3ZSByZWN1cnNpdmVseQorICAvLyBkZWxldGUgdGhpcyBkaXJlY3RvcnkgZHVyaW5nIHRoZSB0ZXN0KS4gIFRoaXMgaXMgdGhlIGZ1bGwgcGF0aCBvZiB0aGF0CisgIC8vIGRpcmVjdG9yeS4KKyAgc3RyaW5nIHRlbXBfZGlyZWN0b3J5XzsKKworICAvLyBUaGUgcmVzdWx0IG9mIFJ1bigpLgorICBpbnQgcmV0dXJuX2NvZGVfOworCisgIC8vIFRoZSBjYXB0dXJlZCBzdGRlcnIgb3V0cHV0LgorICBzdHJpbmcgZXJyb3JfdGV4dF87CisKKyAgLy8gVGhlIGNhcHR1cmVkIHN0ZG91dC4KKyAgc3RyaW5nIGNhcHR1cmVkX3N0ZG91dF87CisKKyAgLy8gUG9pbnRlcnMgd2hpY2ggbmVlZCB0byBiZSBkZWxldGVkIGxhdGVyLgorICB2ZWN0b3I8Q29kZUdlbmVyYXRvcio+IG1vY2tfZ2VuZXJhdG9yc190b19kZWxldGVfOworCisgIE51bGxDb2RlR2VuZXJhdG9yKiBudWxsX2dlbmVyYXRvcl87Cit9OworCitjbGFzcyBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6Ok51bGxDb2RlR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgTnVsbENvZGVHZW5lcmF0b3IoKSA6IGNhbGxlZF8oZmFsc2UpIHt9CisgIH5OdWxsQ29kZUdlbmVyYXRvcigpIHt9CisKKyAgbXV0YWJsZSBib29sIGNhbGxlZF87CisgIG11dGFibGUgc3RyaW5nIHBhcmFtZXRlcl87CisKKyAgLy8gaW1wbGVtZW50cyBDb2RlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgICBjYWxsZWRfID0gdHJ1ZTsKKyAgICBwYXJhbWV0ZXJfID0gcGFyYW1ldGVyOworICAgIHJldHVybiB0cnVlOworICB9Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpTZXRVcCgpIHsKKyAgLy8gTW9zdCBvZiB0aGVzZSB0ZXN0cyB3ZXJlIHdyaXR0ZW4gYmVmb3JlIHRoaXMgb3B0aW9uIHdhcyBhZGRlZCwgc28gd2UKKyAgLy8gcnVuIHdpdGggdGhlIG9wdGlvbiBvbiAod2hpY2ggdXNlZCB0byBiZSB0aGUgb25seSB3YXkpIGV4Y2VwdCBpbiBjZXJ0YWluCisgIC8vIHRlc3RzIHdoZXJlIHdlIHR1cm4gaXQgb2ZmLgorICBjbGlfLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKHRydWUpOworCisgIHRlbXBfZGlyZWN0b3J5XyA9IFRlc3RUZW1wRGlyKCkgKyAiL3Byb3RvMl9jbGlfdGVzdF90ZW1wIjsKKworICAvLyBJZiB0aGUgdGVtcCBkaXJlY3RvcnkgYWxyZWFkeSBleGlzdHMsIGl0IG11c3QgYmUgbGVmdCBvdmVyIGZyb20gYQorICAvLyBwcmV2aW91cyBydW4uICBEZWxldGUgaXQuCisgIGlmIChGaWxlRXhpc3RzKHRlbXBfZGlyZWN0b3J5XykpIHsKKyAgICBGaWxlOjpEZWxldGVSZWN1cnNpdmVseSh0ZW1wX2RpcmVjdG9yeV8sIE5VTEwsIE5VTEwpOworICB9CisKKyAgLy8gQ3JlYXRlIHRoZSB0ZW1wIGRpcmVjdG9yeS4KKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkNyZWF0ZURpcih0ZW1wX2RpcmVjdG9yeV8sIDA3NzcpKTsKKworICAvLyBSZWdpc3RlciBnZW5lcmF0b3JzLgorICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IgPSBuZXcgTW9ja0NvZGVHZW5lcmF0b3IoInRlc3RfZ2VuZXJhdG9yIik7CisgIG1vY2tfZ2VuZXJhdG9yc190b19kZWxldGVfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICBjbGlfLlJlZ2lzdGVyR2VuZXJhdG9yKCItLXRlc3Rfb3V0IiwgIi0tdGVzdF9vcHQiLCBnZW5lcmF0b3IsICJUZXN0IG91dHB1dC4iKTsKKyAgY2xpXy5SZWdpc3RlckdlbmVyYXRvcigiLXQiLCBnZW5lcmF0b3IsICJUZXN0IG91dHB1dC4iKTsKKworICBnZW5lcmF0b3IgPSBuZXcgTW9ja0NvZGVHZW5lcmF0b3IoImFsdF9nZW5lcmF0b3IiKTsKKyAgbW9ja19nZW5lcmF0b3JzX3RvX2RlbGV0ZV8ucHVzaF9iYWNrKGdlbmVyYXRvcik7CisgIGNsaV8uUmVnaXN0ZXJHZW5lcmF0b3IoIi0tYWx0X291dCIsIGdlbmVyYXRvciwgIkFsdCBvdXRwdXQuIik7CisKKyAgZ2VuZXJhdG9yID0gbnVsbF9nZW5lcmF0b3JfID0gbmV3IE51bGxDb2RlR2VuZXJhdG9yKCk7CisgIG1vY2tfZ2VuZXJhdG9yc190b19kZWxldGVfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICBjbGlfLlJlZ2lzdGVyR2VuZXJhdG9yKCItLW51bGxfb3V0IiwgZ2VuZXJhdG9yLCAiTnVsbCBvdXRwdXQuIik7CisKKyAgZGlzYWxsb3dfcGx1Z2luc18gPSBmYWxzZTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OlRlYXJEb3duKCkgeworICAvLyBEZWxldGUgdGhlIHRlbXAgZGlyZWN0b3J5LgorICBpZiAoRmlsZUV4aXN0cyh0ZW1wX2RpcmVjdG9yeV8pKSB7CisgICAgRmlsZTo6RGVsZXRlUmVjdXJzaXZlbHkodGVtcF9kaXJlY3RvcnlfLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIC8vIERlbGV0ZSBhbGwgdGhlIE1vY2tDb2RlR2VuZXJhdG9ycy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtb2NrX2dlbmVyYXRvcnNfdG9fZGVsZXRlXy5zaXplKCk7IGkrKykgeworICAgIGRlbGV0ZSBtb2NrX2dlbmVyYXRvcnNfdG9fZGVsZXRlX1tpXTsKKyAgfQorICBtb2NrX2dlbmVyYXRvcnNfdG9fZGVsZXRlXy5jbGVhcigpOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6UnVuKGNvbnN0IHN0cmluZyYgY29tbWFuZCkgeworICB2ZWN0b3I8c3RyaW5nPiBhcmdzID0gU3BsaXQoY29tbWFuZCwgIiAiLCB0cnVlKTsKKworICBpZiAoIWRpc2FsbG93X3BsdWdpbnNfKSB7CisgICAgY2xpXy5BbGxvd1BsdWdpbnMoInByZWZpeC0iKTsKKyAgICBjb25zdCBjaGFyKiBwb3NzaWJsZV9wYXRoc1tdID0geworICAgICAgLy8gV2hlbiBidWlsZGluZyB3aXRoIHNoYXJlZCBsaWJyYXJpZXMsIGxpYnRvb2wgaGlkZXMgdGhlIHJlYWwgZXhlY3V0YWJsZQorICAgICAgLy8gaW4gLmxpYnMgYW5kIHB1dHMgYSBmYWtlIHdyYXBwZXIgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LgorICAgICAgLy8gVW5mb3J0dW5hdGVseSwgZHVlIHRvIGFuIGFwcGFyZW50IGJ1ZyBvbiBDeWd3aW4vTWluR1csIGlmIG9uZSBwcm9ncmFtCisgICAgICAvLyB3cmFwcGVkIGluIHRoaXMgd2F5IChlLmcuIHByb3RvYnVmLXRlc3RzLmV4ZSkgdHJpZXMgdG8gZXhlY3V0ZSBhbm90aGVyCisgICAgICAvLyBwcm9ncmFtIHdyYXBwZWQgaW4gdGhpcyB3YXkgKGUuZy4gdGVzdF9wbHVnaW4uZXhlKSwgdGhlIGxhdHRlciBmYWlscworICAgICAgLy8gd2l0aCBlcnJvciBjb2RlIDEyNyBhbmQgbm8gZXhwbGFuYXRpb24gbWVzc2FnZS4gIFByZXN1bWFibHkgdGhlIHByb2JsZW0KKyAgICAgIC8vIGlzIHRoYXQgdGhlIHdyYXBwZXIgZm9yIHByb3RvYnVmLXRlc3RzLmV4ZSBzZXQgc29tZSBlbnZpcm9ubWVudAorICAgICAgLy8gdmFyaWFibGVzIHRoYXQgY29uZnVzZSB0aGUgd3JhcHBlciBmb3IgdGVzdF9wbHVnaW4uZXhlLiAgTHVja2lseSwgaXQKKyAgICAgIC8vIHR1cm5zIG91dCB0aGF0IGlmIHdlIHNpbXBseSBpbnZva2UgdGhlIHdyYXBwZWQgdGVzdF9wbHVnaW4uZXhlCisgICAgICAvLyBkaXJlY3RseSwgaXQgd29ya3MgLS0gSSBndWVzcyB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHNldCBieSB0aGUKKyAgICAgIC8vIHByb3RvYnVmLXRlc3RzLmV4ZSB3cmFwcGVyIGhhcHBlbiB0byBiZSBjb3JyZWN0IGZvciBpdCB0b28uICBTbyB3ZSBkbworICAgICAgLy8gdGhhdC4KKyAgICAgICIubGlicy90ZXN0X3BsdWdpbi5leGUiLCAgLy8gV2luMzIgdy9hdXRvdG9vbCAoQ3lnd2luIC8gTWluR1cpCisgICAgICAidGVzdF9wbHVnaW4uZXhlIiwgICAgICAgIC8vIE90aGVyIFdpbjMyIChNU1ZDKQorICAgICAgInRlc3RfcGx1Z2luIiwgICAgICAgICAgICAvLyBVbml4CisgICAgfTsKKworICAgIHN0cmluZyBwbHVnaW5fcGF0aDsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShwb3NzaWJsZV9wYXRocyk7IGkrKykgeworICAgICAgaWYgKGFjY2Vzcyhwb3NzaWJsZV9wYXRoc1tpXSwgRl9PSykgPT0gMCkgeworICAgICAgICBwbHVnaW5fcGF0aCA9IHBvc3NpYmxlX3BhdGhzW2ldOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAocGx1Z2luX3BhdGguZW1wdHkoKSkgeworICAgICAgR09PR0xFX0xPRyhFUlJPUikKKyAgICAgICAgICA8PCAiUGx1Z2luIGV4ZWN1dGFibGUgbm90IGZvdW5kLiAgUGx1Z2luIHRlc3RzIGFyZSBsaWtlbHkgdG8gZmFpbC4iOworICAgIH0gZWxzZSB7CisgICAgICBhcmdzLnB1c2hfYmFjaygiLS1wbHVnaW49cHJlZml4LWdlbi1wbHVnPSIgKyBwbHVnaW5fcGF0aCk7CisgICAgfQorICB9CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNvbnN0IGNoYXIgKiA+IGFyZ3YobmV3IGNvbnN0IGNoYXIqIFthcmdzLnNpemUoKV0pOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5zaXplKCk7IGkrKykgeworICAgIGFyZ3NbaV0gPSBTdHJpbmdSZXBsYWNlKGFyZ3NbaV0sICIkdG1wZGlyIiwgdGVtcF9kaXJlY3RvcnlfLCB0cnVlKTsKKyAgICBhcmd2W2ldID0gYXJnc1tpXS5jX3N0cigpOworICB9CisKKyAgLy8gVE9ETyhqaWVsdW8pOiBDeWd3aW4gZG9lc24ndCB3b3JrIHdlbGwgaWYgd2UgdHJ5IHRvIGNhcHR1cmUgc3RkZXJyIGFuZAorICAvLyBzdGRvdXQgYXQgdGhlIHNhbWUgdGltZS4gTmVlZCB0byBmaWd1cmUgb3V0IHdoeSBhbmQgYWRkIHRoaXMgY2FwdHVyZSBiYWNrCisgIC8vIGZvciBDeWd3aW4uCisjaWYgIWRlZmluZWQoX19DWUdXSU5fXykKKyAgQ2FwdHVyZVRlc3RTdGRvdXQoKTsKKyNlbmRpZgorICBDYXB0dXJlVGVzdFN0ZGVycigpOworCisgIHJldHVybl9jb2RlXyA9IGNsaV8uUnVuKGFyZ3Muc2l6ZSgpLCBhcmd2LmdldCgpKTsKKworICBlcnJvcl90ZXh0XyA9IEdldENhcHR1cmVkVGVzdFN0ZGVycigpOworI2lmICFkZWZpbmVkKF9fQ1lHV0lOX18pCisgIGNhcHR1cmVkX3N0ZG91dF8gPSBHZXRDYXB0dXJlZFRlc3RTdGRvdXQoKTsKKyNlbmRpZgorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpDcmVhdGVUZW1wRmlsZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBjb250ZW50cykgeworICAvLyBDcmVhdGUgcGFyZW50IGRpcmVjdG9yeSwgaWYgbmVjZXNzYXJ5LgorICBzdHJpbmc6OnNpemVfdHlwZSBzbGFzaF9wb3MgPSBuYW1lLmZpbmRfbGFzdF9vZignLycpOworICBpZiAoc2xhc2hfcG9zICE9IHN0cmluZzo6bnBvcykgeworICAgIHN0cmluZyBkaXIgPSBuYW1lLnN1YnN0cigwLCBzbGFzaF9wb3MpOworICAgIGlmICghRmlsZUV4aXN0cyh0ZW1wX2RpcmVjdG9yeV8gKyAiLyIgKyBkaXIpKSB7CisgICAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6UmVjdXJzaXZlbHlDcmVhdGVEaXIodGVtcF9kaXJlY3RvcnlfICsgIi8iICsgZGlyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMDc3NykpOworICAgIH0KKyAgfQorCisgIC8vIFdyaXRlIGZpbGUuCisgIHN0cmluZyBmdWxsX25hbWUgPSB0ZW1wX2RpcmVjdG9yeV8gKyAiLyIgKyBuYW1lOworICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6U2V0Q29udGVudHMoZnVsbF9uYW1lLCBjb250ZW50cywgdHJ1ZSkpOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6Q3JlYXRlVGVtcERpcihjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OlJlY3Vyc2l2ZWx5Q3JlYXRlRGlyKHRlbXBfZGlyZWN0b3J5XyArICIvIiArIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDA3NzcpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6RXhwZWN0Tm9FcnJvcnMoKSB7CisgIEVYUEVDVF9FUSgwLCByZXR1cm5fY29kZV8pOworICBFWFBFQ1RfRVEoIiIsIGVycm9yX3RleHRfKTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdEVycm9yVGV4dChjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3RleHQpIHsKKyAgRVhQRUNUX05FKDAsIHJldHVybl9jb2RlXyk7CisgIEVYUEVDVF9FUShTdHJpbmdSZXBsYWNlKGV4cGVjdGVkX3RleHQsICIkdG1wZGlyIiwgdGVtcF9kaXJlY3RvcnlfLCB0cnVlKSwKKyAgICAgICAgICAgIGVycm9yX3RleHRfKTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdEVycm9yU3Vic3RyaW5nKAorICAgIGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfc3Vic3RyaW5nKSB7CisgIEVYUEVDVF9ORSgwLCByZXR1cm5fY29kZV8pOworICBFWFBFQ1RfUFJFRF9GT1JNQVQyKHRlc3Rpbmc6OklzU3Vic3RyaW5nLCBleHBlY3RlZF9zdWJzdHJpbmcsIGVycm9yX3RleHRfKTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKAorICAgIGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfc3Vic3RyaW5nKSB7CisgIEVYUEVDVF9FUSgwLCByZXR1cm5fY29kZV8pOworICBFWFBFQ1RfUFJFRF9GT1JNQVQyKHRlc3Rpbmc6OklzU3Vic3RyaW5nLCBleHBlY3RlZF9zdWJzdHJpbmcsIGVycm9yX3RleHRfKTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6Okhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKAorICAgIGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfc3Vic3RyaW5nKSB7CisgIEVYUEVDVF9ORSgwLCByZXR1cm5fY29kZV8pOworICByZXR1cm4gZXJyb3JfdGV4dF8uZmluZChleHBlY3RlZF9zdWJzdHJpbmcpICE9IHN0cmluZzo6bnBvczsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdEdlbmVyYXRlZCgKKyAgICBjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IHN0cmluZyYgcHJvdG9fbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2VfbmFtZSkgeworICBNb2NrQ29kZUdlbmVyYXRvcjo6RXhwZWN0R2VuZXJhdGVkKAorICAgICAgZ2VuZXJhdG9yX25hbWUsIHBhcmFtZXRlciwgIiIsIHByb3RvX25hbWUsIG1lc3NhZ2VfbmFtZSwgcHJvdG9fbmFtZSwKKyAgICAgIHRlbXBfZGlyZWN0b3J5Xyk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RHZW5lcmF0ZWQoCisgICAgY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBvdXRwdXRfZGlyZWN0b3J5KSB7CisgIE1vY2tDb2RlR2VuZXJhdG9yOjpFeHBlY3RHZW5lcmF0ZWQoCisgICAgICBnZW5lcmF0b3JfbmFtZSwgcGFyYW1ldGVyLCAiIiwgcHJvdG9fbmFtZSwgbWVzc2FnZV9uYW1lLCBwcm90b19uYW1lLAorICAgICAgdGVtcF9kaXJlY3RvcnlfICsgIi8iICsgb3V0cHV0X2RpcmVjdG9yeSk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RHZW5lcmF0ZWRXaXRoTXVsdGlwbGVJbnB1dHMoCisgICAgY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIGFsbF9wcm90b19uYW1lcywKKyAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUpIHsKKyAgTW9ja0NvZGVHZW5lcmF0b3I6OkV4cGVjdEdlbmVyYXRlZCgKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCAiIiwgIiIsIHByb3RvX25hbWUsIG1lc3NhZ2VfbmFtZSwKKyAgICAgIGFsbF9wcm90b19uYW1lcywKKyAgICAgIHRlbXBfZGlyZWN0b3J5Xyk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RHZW5lcmF0ZWRXaXRoSW5zZXJ0aW9ucygKKyAgICBjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUpIHsKKyAgTW9ja0NvZGVHZW5lcmF0b3I6OkV4cGVjdEdlbmVyYXRlZCgKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCBwYXJhbWV0ZXIsIGluc2VydGlvbnMsIHByb3RvX25hbWUsIG1lc3NhZ2VfbmFtZSwKKyAgICAgIHByb3RvX25hbWUsIHRlbXBfZGlyZWN0b3J5Xyk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3ROdWxsQ29kZUdlbmVyYXRvckNhbGxlZCgKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlcikgeworICBFWFBFQ1RfVFJVRShudWxsX2dlbmVyYXRvcl8tPmNhbGxlZF8pOworICBFWFBFQ1RfRVEocGFyYW1ldGVyLCBudWxsX2dlbmVyYXRvcl8tPnBhcmFtZXRlcl8pOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6UmVhZERlc2NyaXB0b3JTZXQoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgRmlsZURlc2NyaXB0b3JTZXQqIGRlc2NyaXB0b3Jfc2V0KSB7CisgIHN0cmluZyBwYXRoID0gdGVtcF9kaXJlY3RvcnlfICsgIi8iICsgZmlsZW5hbWU7CisgIHN0cmluZyBmaWxlX2NvbnRlbnRzOworICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6R2V0Q29udGVudHMocGF0aCwgJmZpbGVfY29udGVudHMsIHRydWUpKTsKKworICBpZiAoIWRlc2NyaXB0b3Jfc2V0LT5QYXJzZUZyb21TdHJpbmcoZmlsZV9jb250ZW50cykpIHsKKyAgICBGQUlMKCkgPDwgIkNvdWxkIG5vdCBwYXJzZSBmaWxlIGNvbnRlbnRzOiAiIDw8IHBhdGg7CisgIH0KK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdENhcHR1cmVkU3Rkb3V0KAorICAgIGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfdGV4dCkgeworICBFWFBFQ1RfRVEoZXhwZWN0ZWRfdGV4dCwgY2FwdHVyZWRfc3Rkb3V0Xyk7Cit9CisKKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdEZpbGVDb250ZW50KAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGNvbnN0IHN0cmluZyYgY29udGVudCkgeworICBzdHJpbmcgcGF0aCA9IHRlbXBfZGlyZWN0b3J5XyArICIvIiArIGZpbGVuYW1lOworICBzdHJpbmcgZmlsZV9jb250ZW50czsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkdldENvbnRlbnRzKHBhdGgsICZmaWxlX2NvbnRlbnRzLCB0cnVlKSk7CisKKyAgRVhQRUNUX0VRKFN0cmluZ1JlcGxhY2UoY29udGVudCwgIiR0bXBkaXIiLCB0ZW1wX2RpcmVjdG9yeV8sIHRydWUpLAorICAgICAgICAgICAgZmlsZV9jb250ZW50cyk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQmFzaWNPdXRwdXQpIHsKKyAgLy8gVGVzdCB0aGF0IHRoZSBjb21tb24gY2FzZSB3b3Jrcy4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEJhc2ljUGx1Z2luKSB7CisgIC8vIFRlc3QgdGhhdCBiYXNpYyBwbHVnaW5zIHdvcmsuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tcGx1Z19vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X3BsdWdpbiIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHZW5lcmF0b3JBbmRQbHVnaW4pIHsKKyAgLy8gSW52b2tlIGEgZ2VuZXJhdG9yIGFuZCBhIHBsdWdpbiBhdCB0aGUgc2FtZSB0aW1lLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgLS1wbHVnX291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9wbHVnaW4iLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgTXVsdGlwbGVJbnB1dHMpIHsKKyAgLy8gVGVzdCBwYXJzaW5nIG11bHRpcGxlIGlucHV0IGZpbGVzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEJhciB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgLS1wbHVnX291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8gYmFyLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKCJ0ZXN0X2dlbmVyYXRvciIsICJmb28ucHJvdG8sYmFyLnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhNdWx0aXBsZUlucHV0cygidGVzdF9nZW5lcmF0b3IiLCAiZm9vLnByb3RvLGJhci5wcm90byIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmFyLnByb3RvIiwgIkJhciIpOworICBFeHBlY3RHZW5lcmF0ZWRXaXRoTXVsdGlwbGVJbnB1dHMoInRlc3RfcGx1Z2luIiwgImZvby5wcm90byxiYXIucHJvdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvby5wcm90byIsICJGb28iKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKCJ0ZXN0X3BsdWdpbiIsICJmb28ucHJvdG8sYmFyLnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiYXIucHJvdG8iLCAiQmFyIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIE11bHRpcGxlSW5wdXRzV2l0aEltcG9ydCkgeworICAvLyBUZXN0IHBhcnNpbmcgbXVsdGlwbGUgaW5wdXQgZmlsZXMgd2l0aCBhbiBpbXBvcnQgb2YgYSBzZXBhcmF0ZSBmaWxlLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJiYXoucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICIgIG9wdGlvbmFsIEJheiBhID0gMTtcbiIKKyAgICAifVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXoucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEJheiB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgLS1wbHVnX291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8gYmFyLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKCJ0ZXN0X2dlbmVyYXRvciIsICJmb28ucHJvdG8sYmFyLnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhNdWx0aXBsZUlucHV0cygidGVzdF9nZW5lcmF0b3IiLCAiZm9vLnByb3RvLGJhci5wcm90byIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmFyLnByb3RvIiwgIkJhciIpOworICBFeHBlY3RHZW5lcmF0ZWRXaXRoTXVsdGlwbGVJbnB1dHMoInRlc3RfcGx1Z2luIiwgImZvby5wcm90byxiYXIucHJvdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvby5wcm90byIsICJGb28iKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKCJ0ZXN0X3BsdWdpbiIsICJmb28ucHJvdG8sYmFyLnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiYXIucHJvdG8iLCAiQmFyIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIENyZWF0ZURpcmVjdG9yeSkgeworICAvLyBUZXN0IHRoYXQgd2hlbiB3ZSBvdXRwdXQgdG8gYSBzdWItZGlyZWN0b3J5LCBpdCBpcyBjcmVhdGVkLgorCisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvYmF6L2Zvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcERpcigib3V0Iik7CisgIENyZWF0ZVRlbXBEaXIoInBsdWdvdXQiKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpci9vdXQgLS1wbHVnX291dD0kdG1wZGlyL3BsdWdvdXQgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGJhci9iYXovZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiYmFyL2Jhei9mb28ucHJvdG8iLCAiRm9vIiwgIm91dCIpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfcGx1Z2luIiwgIiIsICJiYXIvYmF6L2Zvby5wcm90byIsICJGb28iLCAicGx1Z291dCIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHZW5lcmF0b3JQYXJhbWV0ZXJzKSB7CisgIC8vIFRlc3QgdGhhdCBnZW5lcmF0b3IgcGFyYW1ldGVycyBhcmUgY29ycmVjdGx5IHBhcnNlZCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9VGVzdFBhcmFtZXRlcjokdG1wZGlyICIKKyAgICAgICItLXBsdWdfb3V0PVRlc3RQbHVnaW5QYXJhbWV0ZXI6JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICJUZXN0UGFyYW1ldGVyIiwgImZvby5wcm90byIsICJGb28iKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X3BsdWdpbiIsICJUZXN0UGx1Z2luUGFyYW1ldGVyIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgRXh0cmFHZW5lcmF0b3JQYXJhbWV0ZXJzKSB7CisgIC8vIFRlc3QgdGhhdCBnZW5lcmF0b3IgcGFyYW1ldGVycyBzcGVjaWZpZWQgd2l0aCB0aGUgb3B0aW9uIGZsYWcgYXJlCisgIC8vIGNvcnJlY3RseSBwYXNzZWQgdG8gdGhlIGNvZGUgZ2VuZXJhdG9yLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIC8vIENyZWF0ZSB0aGUgImEiIGFuZCAiYiIgc3ViLWRpcmVjdG9yaWVzLgorICBDcmVhdGVUZW1wRGlyKCJhIik7CisgIENyZWF0ZVRlbXBEaXIoImIiKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyICIKKyAgICAgICItLXRlc3Rfb3B0PWZvbzEgIgorICAgICAgIi0tdGVzdF9vdXQ9YmFyOiR0bXBkaXIvYSAiCisgICAgICAiLS10ZXN0X29wdD1mb28yICIKKyAgICAgICItLXRlc3Rfb3V0PWJhejokdG1wZGlyL2IgIgorICAgICAgIi0tdGVzdF9vcHQ9Zm9vMyAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKAorICAgICAgInRlc3RfZ2VuZXJhdG9yIiwgImJhcixmb28xLGZvbzIsZm9vMyIsICJmb28ucHJvdG8iLCAiRm9vIiwgImEiKTsKKyAgRXhwZWN0R2VuZXJhdGVkKAorICAgICAgInRlc3RfZ2VuZXJhdG9yIiwgImJheixmb28xLGZvbzIsZm9vMyIsICJmb28ucHJvdG8iLCAiRm9vIiwgImIiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgSW5zZXJ0KSB7CisgIC8vIFRlc3QgcnVubmluZyBhIGdlbmVyYXRvciB0aGF0IGluc2VydHMgY29kZSBpbnRvIGFub3RoZXIncyBvdXRwdXQuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyICIKKyAgICAgICItLXRlc3Rfb3V0PVRlc3RQYXJhbWV0ZXI6JHRtcGRpciAiCisgICAgICAiLS1wbHVnX291dD1UZXN0UGx1Z2luUGFyYW1ldGVyOiR0bXBkaXIgIgorICAgICAgIi0tdGVzdF9vdXQ9aW5zZXJ0PXRlc3RfZ2VuZXJhdG9yLHRlc3RfcGx1Z2luOiR0bXBkaXIgIgorICAgICAgIi0tcGx1Z19vdXQ9aW5zZXJ0PXRlc3RfZ2VuZXJhdG9yLHRlc3RfcGx1Z2luOiR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhJbnNlcnRpb25zKAorICAgICAgInRlc3RfZ2VuZXJhdG9yIiwgIlRlc3RQYXJhbWV0ZXIiLCAidGVzdF9nZW5lcmF0b3IsdGVzdF9wbHVnaW4iLAorICAgICAgImZvby5wcm90byIsICJGb28iKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aEluc2VydGlvbnMoCisgICAgICAidGVzdF9wbHVnaW4iLCAiVGVzdFBsdWdpblBhcmFtZXRlciIsICJ0ZXN0X2dlbmVyYXRvcix0ZXN0X3BsdWdpbiIsCisgICAgICAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCisjaWYgZGVmaW5lZChfV0lOMzIpCisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdpbmRvd3NPdXRwdXRQYXRoKSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgb3V0cHV0IHBhdGggY2FuIGJlIGEgV2luZG93cy1zdHlsZSBwYXRoLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLW51bGxfb3V0PUM6XFwgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdE51bGxDb2RlR2VuZXJhdG9yQ2FsbGVkKCIiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgV2luZG93c091dHB1dFBhdGhBbmRQYXJhbWV0ZXIpIHsKKyAgLy8gVGVzdCB0aGF0IHdlIGNhbiBoYXZlIGEgd2luZG93cy1zdHlsZSBvdXRwdXQgcGF0aCBhbmQgYSBwYXJhbWV0ZXIuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tbnVsbF9vdXQ9YmFyOkM6XFwgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdE51bGxDb2RlR2VuZXJhdG9yQ2FsbGVkKCJiYXIiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgVHJhaWxpbmdCYWNrc2xhc2gpIHsKKyAgLy8gVGVzdCB0aGF0IHRoZSBkaXJlY3RvcmllcyBjYW4gZW5kIGluIGJhY2tzbGFzaGVzLiAgU29tZSB1c2VycyBjbGFpbSB0aGlzCisgIC8vIGRvZXNuJ3Qgd29yayBvbiB0aGVpciBzeXN0ZW0uCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpclxcICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpclxcIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworI2VuZGlmICAvLyBkZWZpbmVkKF9XSU4zMikgfHwgZGVmaW5lZChfX0NZR1dJTl9fKQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXRoTG9va3VwKSB7CisgIC8vIFRlc3QgdGhhdCBzcGVjaWZ5aW5nIG11bHRpcGxlIGRpcmVjdG9yaWVzIGluIHRoZSBwcm90byBzZWFyY2ggcGF0aCB3b3Jrcy4KKworICBDcmVhdGVUZW1wRmlsZSgiYi9iYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEJhciB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJhL2Zvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImJhci5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgb3B0aW9uYWwgQmFyIGEgPSAxO1xuIgorICAgICJ9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImIvZm9vLnByb3RvIiwgInRoaXMgc2hvdWxkIG5vdCBiZSBwYXJzZWRcbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpci9hIC0tcHJvdG9fcGF0aD0kdG1wZGlyL2IgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBDb2xvbkRlbGltaXRlZFBhdGgpIHsKKyAgLy8gU2FtZSBhcyBQYXRoTG9va3VwLCBidXQgd2UgcHJvdmlkZSB0aGUgcHJvdG9fcGF0aCBpbiBhIHNpbmdsZSBmbGFnLgorCisgIENyZWF0ZVRlbXBGaWxlKCJiL2Jhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImEvZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiYmFyLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBCYXIgYSA9IDE7XG4iCisgICAgIn1cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYi9mb28ucHJvdG8iLCAidGhpcyBzaG91bGQgbm90IGJlIHBhcnNlZFxuIik7CisKKyN1bmRlZiBQQVRIX1NFUEFSQVRPUgorI2lmIGRlZmluZWQoX1dJTjMyKQorI2RlZmluZSBQQVRIX1NFUEFSQVRPUiAiOyIKKyNlbHNlCisjZGVmaW5lIFBBVEhfU0VQQVJBVE9SICI6IgorI2VuZGlmCisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyL2EiIFBBVEhfU0VQQVJBVE9SICIkdG1wZGlyL2IgZm9vLnByb3RvIik7CisKKyN1bmRlZiBQQVRIX1NFUEFSQVRPUgorCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgTm9uUm9vdE1hcHBpbmcpIHsKKyAgLy8gVGVzdCBzZXR0aW5nIHVwIGEgc2VhcmNoIHBhdGggbWFwcGluZyBhIGRpcmVjdG9yeSB0byBhIG5vbi1yb290IGxvY2F0aW9uLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD1iYXI9JHRtcGRpciBiYXIvZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiYmFyL2Zvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgTXVsdGlwbGVHZW5lcmF0b3JzKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gaGF2ZSBtdWx0aXBsZSBnZW5lcmF0b3JzIGFuZCB1c2UgYm90aCBpbiBvbmUgaW52b2NhdGlvbiwKKyAgLy8gZWFjaCB3aXRoIGEgZGlmZmVyZW50IG91dHB1dCBkaXJlY3RvcnkuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgLy8gQ3JlYXRlIHRoZSAiYSIgYW5kICJiIiBzdWItZGlyZWN0b3JpZXMuCisgIENyZWF0ZVRlbXBEaXIoImEiKTsKKyAgQ3JlYXRlVGVtcERpcigiYiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgIgorICAgICAgIi0tdGVzdF9vdXQ9JHRtcGRpci9hICIKKyAgICAgICItLWFsdF9vdXQ9JHRtcGRpci9iICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIiwgImEiKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJhbHRfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIiwgImIiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgRGlzYWxsb3dTZXJ2aWNlc05vU2VydmljZXMpIHsKKyAgLy8gVGVzdCB0aGF0IC0tZGlzYWxsb3dfc2VydmljZXMgZG9lc24ndCBjYXVzZSBhIHByb2JsZW0gd2hlbiB0aGVyZSBhcmUgbm8KKyAgLy8gc2VydmljZXMuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGlzYWxsb3dfc2VydmljZXMgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIERpc2FsbG93U2VydmljZXNIYXNTZXJ2aWNlKSB7CisgIC8vIFRlc3QgdGhhdCAtLWRpc2FsbG93X3NlcnZpY2VzIHByb2R1Y2VzIGFuIGVycm9yIHdoZW4gdGhlcmUgYXJlIHNlcnZpY2VzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIgorICAgICJzZXJ2aWNlIEJhciB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLWRpc2FsbG93X3NlcnZpY2VzIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoImZvby5wcm90bzogVGhpcyBmaWxlIGNvbnRhaW5zIHNlcnZpY2VzIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEFsbG93U2VydmljZXNIYXNTZXJ2aWNlKSB7CisgIC8vIFRlc3QgdGhhdCBzZXJ2aWNlcyB3b3JrIGZpbmUgYXMgbG9uZyBhcyAtLWRpc2FsbG93X3NlcnZpY2VzIGlzIG5vdCB1c2VkLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIgorICAgICJzZXJ2aWNlIEJhciB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQ3dkUmVsYXRpdmVJbnB1dHMpIHsKKyAgLy8gVGVzdCB0aGF0IHdlIGNhbiBhY2NlcHQgd29ya2luZy1kaXJlY3RvcnktcmVsYXRpdmUgaW5wdXQgZmlsZXMuCisKKyAgU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUoZmFsc2UpOworCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyICR0bXBkaXIvZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBXcml0ZURlc2NyaXB0b3JTZXQpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImZvby5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgIiAgb3B0aW9uYWwgRm9vIGZvbyA9IDE7XG4iCisgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXNjcmlwdG9yX3NldF9vdXQ9JHRtcGRpci9kZXNjcmlwdG9yX3NldCAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgYmFyLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKworICBGaWxlRGVzY3JpcHRvclNldCBkZXNjcmlwdG9yX3NldDsKKyAgUmVhZERlc2NyaXB0b3JTZXQoImRlc2NyaXB0b3Jfc2V0IiwgJmRlc2NyaXB0b3Jfc2V0KTsKKyAgaWYgKEhhc0ZhdGFsRmFpbHVyZSgpKSByZXR1cm47CisgIEVYUEVDVF9FUSgxLCBkZXNjcmlwdG9yX3NldC5maWxlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5uYW1lKCkpOworICAvLyBEZXNjcmlwdG9yIHNldCBzaG91bGQgbm90IGhhdmUgc291cmNlIGNvZGUgaW5mby4KKyAgRVhQRUNUX0ZBTFNFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkuaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlRGVzY3JpcHRvclNldFdpdGhTb3VyY2VJbmZvKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICIgIG9wdGlvbmFsIEZvbyBmb28gPSAxO1xuIgorICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGVzY3JpcHRvcl9zZXRfb3V0PSR0bXBkaXIvZGVzY3JpcHRvcl9zZXQgIgorICAgICAgIi0taW5jbHVkZV9zb3VyY2VfaW5mbyAtLXByb3RvX3BhdGg9JHRtcGRpciBiYXIucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworCisgIEZpbGVEZXNjcmlwdG9yU2V0IGRlc2NyaXB0b3Jfc2V0OworICBSZWFkRGVzY3JpcHRvclNldCgiZGVzY3JpcHRvcl9zZXQiLCAmZGVzY3JpcHRvcl9zZXQpOworICBpZiAoSGFzRmF0YWxGYWlsdXJlKCkpIHJldHVybjsKKyAgRVhQRUNUX0VRKDEsIGRlc2NyaXB0b3Jfc2V0LmZpbGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBkZXNjcmlwdG9yX3NldC5maWxlKDApLm5hbWUoKSk7CisgIC8vIFNvdXJjZSBjb2RlIGluZm8gaW5jbHVkZWQuCisgIEVYUEVDVF9UUlVFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkuaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlVHJhbnNpdGl2ZURlc2NyaXB0b3JTZXQpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImZvby5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgIiAgb3B0aW9uYWwgRm9vIGZvbyA9IDE7XG4iCisgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXNjcmlwdG9yX3NldF9vdXQ9JHRtcGRpci9kZXNjcmlwdG9yX3NldCAiCisgICAgICAiLS1pbmNsdWRlX2ltcG9ydHMgLS1wcm90b19wYXRoPSR0bXBkaXIgYmFyLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKworICBGaWxlRGVzY3JpcHRvclNldCBkZXNjcmlwdG9yX3NldDsKKyAgUmVhZERlc2NyaXB0b3JTZXQoImRlc2NyaXB0b3Jfc2V0IiwgJmRlc2NyaXB0b3Jfc2V0KTsKKyAgaWYgKEhhc0ZhdGFsRmFpbHVyZSgpKSByZXR1cm47CisgIEVYUEVDVF9FUSgyLCBkZXNjcmlwdG9yX3NldC5maWxlX3NpemUoKSk7CisgIGlmIChkZXNjcmlwdG9yX3NldC5maWxlKDApLm5hbWUoKSA9PSAiYmFyLnByb3RvIikgeworICAgIHN0ZDo6c3dhcChkZXNjcmlwdG9yX3NldC5tdXRhYmxlX2ZpbGUoKS0+bXV0YWJsZV9kYXRhKClbMF0sCisgICAgICAgICAgICAgIGRlc2NyaXB0b3Jfc2V0Lm11dGFibGVfZmlsZSgpLT5tdXRhYmxlX2RhdGEoKVsxXSk7CisgIH0KKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBkZXNjcmlwdG9yX3NldC5maWxlKDApLm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgxKS5uYW1lKCkpOworICAvLyBEZXNjcmlwdG9yIHNldCBzaG91bGQgbm90IGhhdmUgc291cmNlIGNvZGUgaW5mby4KKyAgRVhQRUNUX0ZBTFNFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkuaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisgIEVYUEVDVF9GQUxTRShkZXNjcmlwdG9yX3NldC5maWxlKDEpLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBXcml0ZVRyYW5zaXRpdmVEZXNjcmlwdG9yU2V0V2l0aFNvdXJjZUluZm8pIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImZvby5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgIiAgb3B0aW9uYWwgRm9vIGZvbyA9IDE7XG4iCisgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXNjcmlwdG9yX3NldF9vdXQ9JHRtcGRpci9kZXNjcmlwdG9yX3NldCAiCisgICAgICAiLS1pbmNsdWRlX2ltcG9ydHMgLS1pbmNsdWRlX3NvdXJjZV9pbmZvIC0tcHJvdG9fcGF0aD0kdG1wZGlyIGJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgRmlsZURlc2NyaXB0b3JTZXQgZGVzY3JpcHRvcl9zZXQ7CisgIFJlYWREZXNjcmlwdG9yU2V0KCJkZXNjcmlwdG9yX3NldCIsICZkZXNjcmlwdG9yX3NldCk7CisgIGlmIChIYXNGYXRhbEZhaWx1cmUoKSkgcmV0dXJuOworICBFWFBFQ1RfRVEoMiwgZGVzY3JpcHRvcl9zZXQuZmlsZV9zaXplKCkpOworICBpZiAoZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5uYW1lKCkgPT0gImJhci5wcm90byIpIHsKKyAgICBzdGQ6OnN3YXAoZGVzY3JpcHRvcl9zZXQubXV0YWJsZV9maWxlKCktPm11dGFibGVfZGF0YSgpWzBdLAorICAgICAgICAgICAgICBkZXNjcmlwdG9yX3NldC5tdXRhYmxlX2ZpbGUoKS0+bXV0YWJsZV9kYXRhKClbMV0pOworICB9CisgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGRlc2NyaXB0b3Jfc2V0LmZpbGUoMSkubmFtZSgpKTsKKyAgLy8gU291cmNlIGNvZGUgaW5mbyBpbmNsdWRlZC4KKyAgRVhQRUNUX1RSVUUoZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5oYXNfc291cmNlX2NvZGVfaW5mbygpKTsKKyAgRVhQRUNUX1RSVUUoZGVzY3JpcHRvcl9zZXQuZmlsZSgxKS5oYXNfc291cmNlX2NvZGVfaW5mbygpKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgV3JpdGVEZXBlbmRlbmN5TWFuaWZlc3RGaWxlR2l2ZW5Ud29JbnB1dHMpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImZvby5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgIiAgb3B0aW9uYWwgRm9vIGZvbyA9IDE7XG4iCisgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXBlbmRlbmN5X291dD0kdG1wZGlyL21hbmlmZXN0ICIKKyAgICAgICItLXRlc3Rfb3V0PSR0bXBkaXIgLS1wcm90b19wYXRoPSR0bXBkaXIgYmFyLnByb3RvIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAgICJDYW4gb25seSBwcm9jZXNzIG9uZSBpbnB1dCBmaWxlIHdoZW4gdXNpbmcgLS1kZXBlbmRlbmN5X291dD1GSUxFLlxuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlRGVwZW5kZW5jeU1hbmlmZXN0RmlsZSkgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiZm9vLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAiICBvcHRpb25hbCBGb28gZm9vID0gMTtcbiIKKyAgICAifVxuIik7CisKKyAgc3RyaW5nIGN1cnJlbnRfd29ya2luZ19kaXJlY3RvcnkgPSBnZXRfY3VycmVudF9kaXJfbmFtZSgpOworICBTd2l0Y2hUb1RlbXBEaXJlY3RvcnkoKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGVwZW5kZW5jeV9vdXQ9bWFuaWZlc3QgLS10ZXN0X291dD0uICIKKyAgICAgICJiYXIucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworCisgIEV4cGVjdEZpbGVDb250ZW50KCJtYW5pZmVzdCIsCisgICAgICAgICAgICAgICAgICAgICJiYXIucHJvdG8uTW9ja0NvZGVHZW5lcmF0b3IudGVzdF9nZW5lcmF0b3I6ICIKKyAgICAgICAgICAgICAgICAgICAgImZvby5wcm90b1xcXG4gYmFyLnByb3RvIik7CisKKyAgRmlsZTo6Q2hhbmdlV29ya2luZ0RpcmVjdG9yeShjdXJyZW50X3dvcmtpbmdfZGlyZWN0b3J5KTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgV3JpdGVEZXBlbmRlbmN5TWFuaWZlc3RGaWxlRm9yQWJzb2x1dGVQYXRoKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICIgIG9wdGlvbmFsIEZvbyBmb28gPSAxO1xuIgorICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGVwZW5kZW5jeV9vdXQ9JHRtcGRpci9tYW5pZmVzdCAiCisgICAgICAiLS10ZXN0X291dD0kdG1wZGlyIC0tcHJvdG9fcGF0aD0kdG1wZGlyIGJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnQoIm1hbmlmZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgIiR0bXBkaXIvYmFyLnByb3RvLk1vY2tDb2RlR2VuZXJhdG9yLnRlc3RfZ2VuZXJhdG9yOiAiCisgICAgICAgICAgICAgICAgICAgICIkdG1wZGlyL2Zvby5wcm90b1xcXG4gJHRtcGRpci9iYXIucHJvdG8iKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXJzZUVycm9ycykgeworICAvLyBUZXN0IHRoYXQgcGFyc2UgZXJyb3JzIGFyZSByZXBvcnRlZC4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiYmFkc3ludGF4XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICJmb28ucHJvdG86MjoxOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXJzZUVycm9yc011bHRpcGxlRmlsZXMpIHsKKyAgLy8gVGVzdCB0aGF0IHBhcnNlIGVycm9ycyBhcmUgcmVwb3J0ZWQgZnJvbSBtdWx0aXBsZSBmaWxlcy4KKworICAvLyBXZSBzZXQgdXAgZmlsZXMgc3VjaCB0aGF0IGZvby5wcm90byBhY3R1YWxseSBkZXBlbmRzIG9uIGJhci5wcm90byBpbgorICAvLyB0d28gd2F5czogIERpcmVjdGx5IGFuZCB0aHJvdWdoIGJhei5wcm90by4gIGJhci5wcm90bydzIGVycm9ycyBzaG91bGQKKyAgLy8gb25seSBiZSByZXBvcnRlZCBvbmNlLgorICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiYmFkc3ludGF4XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhei5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImJhci5wcm90b1wiO1xuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJiYXIucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IFwiYmF6LnByb3RvXCI7XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICJiYXIucHJvdG86MjoxOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIKKyAgICAiYmF6LnByb3RvOiBJbXBvcnQgXCJiYXIucHJvdG9cIiB3YXMgbm90IGZvdW5kIG9yIGhhZCBlcnJvcnMuXG4iCisgICAgImZvby5wcm90bzogSW1wb3J0IFwiYmFyLnByb3RvXCIgd2FzIG5vdCBmb3VuZCBvciBoYWQgZXJyb3JzLlxuIgorICAgICJmb28ucHJvdG86IEltcG9ydCBcImJhei5wcm90b1wiIHdhcyBub3QgZm91bmQgb3IgaGFkIGVycm9ycy5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBJbnB1dE5vdEZvdW5kRXJyb3IpIHsKKyAgLy8gVGVzdCB3aGF0IGhhcHBlbnMgaWYgdGhlIGlucHV0IGZpbGUgaXMgbm90IGZvdW5kLgorCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgImZvby5wcm90bzogRmlsZSBub3QgZm91bmQuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQ3dkUmVsYXRpdmVJbnB1dE5vdEZvdW5kRXJyb3IpIHsKKyAgLy8gVGVzdCB3aGF0IGhhcHBlbnMgd2hlbiBhIHdvcmtpbmctZGlyZWN0b3J5LXJlbGF0aXZlIGlucHV0IGZpbGUgaXMgbm90CisgIC8vIGZvdW5kLgorCisgIFNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKGZhbHNlKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgJHRtcGRpci9mb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgIiR0bXBkaXIvZm9vLnByb3RvOiBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5XG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQ3dkUmVsYXRpdmVJbnB1dE5vdE1hcHBlZEVycm9yKSB7CisgIC8vIFRlc3Qgd2hhdCBoYXBwZW5zIHdoZW4gYSB3b3JraW5nLWRpcmVjdG9yeS1yZWxhdGl2ZSBpbnB1dCBmaWxlIGlzIG5vdAorICAvLyBtYXBwZWQgdG8gYSB2aXJ0dWFsIHBhdGguCisKKyAgU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUoZmFsc2UpOworCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGNhbGxlZCAiYmFyIiBzbyB0aGF0IHdlIGNhbiBwb2ludCAtLXByb3RvX3BhdGggYXQgaXQuCisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvZHVtbXkiLCAiIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyL2JhciAkdG1wZGlyL2Zvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb28ucHJvdG86IEZpbGUgZG9lcyBub3QgcmVzaWRlIHdpdGhpbiBhbnkgcGF0aCAiCisgICAgICAic3BlY2lmaWVkIHVzaW5nIC0tcHJvdG9fcGF0aCAob3IgLUkpLiAgWW91IG11c3Qgc3BlY2lmeSBhICIKKyAgICAgICItLXByb3RvX3BhdGggd2hpY2ggZW5jb21wYXNzZXMgdGhpcyBmaWxlLiAgTm90ZSB0aGF0IHRoZSAiCisgICAgICAicHJvdG9fcGF0aCBtdXN0IGJlIGFuIGV4YWN0IHByZWZpeCBvZiB0aGUgLnByb3RvIGZpbGUgIgorICAgICAgIm5hbWVzIC0tIHByb3RvYyBpcyB0b28gZHVtYiB0byBmaWd1cmUgb3V0IHdoZW4gdHdvIHBhdGhzICIKKyAgICAgICIoZS5nLiBhYnNvbHV0ZSBhbmQgcmVsYXRpdmUpIGFyZSBlcXVpdmFsZW50IChpdCdzIGhhcmRlciAiCisgICAgICAidGhhbiB5b3UgdGhpbmspLlxuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEN3ZFJlbGF0aXZlSW5wdXROb3RGb3VuZEFuZE5vdE1hcHBlZEVycm9yKSB7CisgIC8vIENoZWNrIHdoYXQgaGFwcGVucyBpZiB0aGUgaW5wdXQgZmlsZSBpcyBub3QgZm91bmQgKmFuZCogaXMgbm90IG1hcHBlZAorICAvLyBpbiB0aGUgcHJvdG9fcGF0aC4KKworICBTZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZShmYWxzZSk7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGNhbGxlZCAiYmFyIiBzbyB0aGF0IHdlIGNhbiBwb2ludCAtLXByb3RvX3BhdGggYXQgaXQuCisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvZHVtbXkiLCAiIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyL2JhciAkdG1wZGlyL2Zvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb28ucHJvdG86IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnlcbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBDd2RSZWxhdGl2ZUlucHV0U2hhZG93ZWRFcnJvcikgeworICAvLyBUZXN0IHdoYXQgaGFwcGVucyB3aGVuIGEgd29ya2luZy1kaXJlY3RvcnktcmVsYXRpdmUgaW5wdXQgZmlsZSBpcyBzaGFkb3dlZAorICAvLyBieSBhbm90aGVyIGZpbGUgaW4gdGhlIHZpcnR1YWwgcGF0aC4KKworICBTZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZShmYWxzZSk7CisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby9mb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpci9mb28gLS1wcm90b19wYXRoPSR0bXBkaXIvYmFyICIKKyAgICAgICIkdG1wZGlyL2Jhci9mb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgIiR0bXBkaXIvYmFyL2Zvby5wcm90bzogSW5wdXQgaXMgc2hhZG93ZWQgaW4gdGhlIC0tcHJvdG9fcGF0aCAiCisgICAgImJ5IFwiJHRtcGRpci9mb28vZm9vLnByb3RvXCIuICBFaXRoZXIgdXNlIHRoZSBsYXR0ZXIgIgorICAgICJmaWxlIGFzIHlvdXIgaW5wdXQgb3IgcmVvcmRlciB0aGUgLS1wcm90b19wYXRoIHNvIHRoYXQgdGhlICIKKyAgICAiZm9ybWVyIGZpbGUncyBsb2NhdGlvbiBjb21lcyBmaXJzdC5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQcm90b1BhdGhOb3RGb3VuZEVycm9yKSB7CisgIC8vIFRlc3Qgd2hhdCBoYXBwZW5zIGlmIHRoZSBpbnB1dCBmaWxlIGlzIG5vdCBmb3VuZC4KKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIvZm9vIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb286IHdhcm5pbmc6IGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdC5cbiIKKyAgICAiZm9vLnByb3RvOiBGaWxlIG5vdCBmb3VuZC5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBNaXNzaW5nSW5wdXRFcnJvcikgeworICAvLyBUZXN0IHRoYXQgd2UgZ2V0IGFuIGVycm9yIGlmIG5vIGlucHV0cyBhcmUgZ2l2ZW4uCisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KCJNaXNzaW5nIGlucHV0IGZpbGUuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgTWlzc2luZ091dHB1dEVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoIk1pc3Npbmcgb3V0cHV0IGRpcmVjdGl2ZXMuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgT3V0cHV0V3JpdGVFcnJvcikgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIHN0cmluZyBvdXRwdXRfZmlsZSA9CisgICAgICBNb2NrQ29kZUdlbmVyYXRvcjo6R2V0T3V0cHV0RmlsZU5hbWUoInRlc3RfZ2VuZXJhdG9yIiwgImZvby5wcm90byIpOworCisgIC8vIENyZWF0ZSBhIGRpcmVjdG9yeSBibG9ja2luZyBvdXIgb3V0cHV0IGxvY2F0aW9uLgorICBDcmVhdGVUZW1wRGlyKG91dHB1dF9maWxlKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgLy8gTW9ja0NvZGVHZW5lcmF0b3Igbm8gbG9uZ2VyIGRldGVjdHMgYW4gZXJyb3IgYmVjYXVzZSB3ZSBhY3R1YWxseSB3cml0ZSB0bworICAvLyBhbiBpbi1tZW1vcnkgbG9jYXRpb24gZmlyc3QsIHRoZW4gZHVtcCB0byBkaXNrIGF0IHRoZSBlbmQuICBUaGlzIGlzIG5vCisgIC8vIGJpZyBkZWFsLgorICAvLyAgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJNb2NrQ29kZUdlbmVyYXRvciBkZXRlY3RlZCB3cml0ZSBlcnJvci4iKTsKKworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorICAvLyBXaW5kb3dzIHdpdGggTVNWQ1JULmRsbCBwcm9kdWNlcyBFUEVSTSBpbnN0ZWFkIG9mIEVJU0RJUi4KKyAgaWYgKEhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKG91dHB1dF9maWxlICsgIjogUGVybWlzc2lvbiBkZW5pZWQiKSkgeworICAgIHJldHVybjsKKyAgfQorI2VuZGlmCisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcob3V0cHV0X2ZpbGUgKyAiOiBJcyBhIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQbHVnaW5PdXRwdXRXcml0ZUVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgc3RyaW5nIG91dHB1dF9maWxlID0KKyAgICAgIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlTmFtZSgidGVzdF9wbHVnaW4iLCAiZm9vLnByb3RvIik7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGJsb2NraW5nIG91ciBvdXRwdXQgbG9jYXRpb24uCisgIENyZWF0ZVRlbXBEaXIob3V0cHV0X2ZpbGUpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1wbHVnX291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorICAvLyBXaW5kb3dzIHdpdGggTVNWQ1JULmRsbCBwcm9kdWNlcyBFUEVSTSBpbnN0ZWFkIG9mIEVJU0RJUi4KKyAgaWYgKEhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKG91dHB1dF9maWxlICsgIjogUGVybWlzc2lvbiBkZW5pZWQiKSkgeworICAgIHJldHVybjsKKyAgfQorI2VuZGlmCisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcob3V0cHV0X2ZpbGUgKyAiOiBJcyBhIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBPdXRwdXREaXJlY3RvcnlOb3RGb3VuZEVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIvbm9zdWNoZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygibm9zdWNoZGlyLzogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQbHVnaW5PdXRwdXREaXJlY3RvcnlOb3RGb3VuZEVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PSR0bXBkaXIvbm9zdWNoZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygibm9zdWNoZGlyLzogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBPdXRwdXREaXJlY3RvcnlJc0ZpbGVFcnJvcikgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyL2Zvby5wcm90byAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoX19DWUdXSU5fXykKKyAgLy8gV2luZG93cyB3aXRoIE1TVkNSVC5kbGwgcHJvZHVjZXMgRUlOVkFMIGluc3RlYWQgb2YgRU5PVERJUi4KKyAgaWYgKEhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKCJmb28ucHJvdG8vOiBJbnZhbGlkIGFyZ3VtZW50IikpIHsKKyAgICByZXR1cm47CisgIH0KKyNlbmRpZgorCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJmb28ucHJvdG8vOiBOb3QgYSBkaXJlY3RvcnkiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yRXJyb3IpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgTW9ja0NvZGVHZW5lcmF0b3JfRXJyb3Ige31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLXRlc3Rfb3V0OiBmb28ucHJvdG86IFNhdyBtZXNzYWdlIHR5cGUgTW9ja0NvZGVHZW5lcmF0b3JfRXJyb3IuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEdlbmVyYXRvclBsdWdpbkVycm9yKSB7CisgIC8vIFRlc3QgYSBnZW5lcmF0b3IgcGx1Z2luIHRoYXQgcmV0dXJucyBhbiBlcnJvci4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBNb2NrQ29kZUdlbmVyYXRvcl9FcnJvciB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PVRlc3RQYXJhbWV0ZXI6JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoCisgICAgICAiLS1wbHVnX291dDogZm9vLnByb3RvOiBTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0Vycm9yLiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHZW5lcmF0b3JQbHVnaW5GYWlsKSB7CisgIC8vIFRlc3QgYSBnZW5lcmF0b3IgcGx1Z2luIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1wbHVnX291dD1UZXN0UGFyYW1ldGVyOiR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQuIik7CisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKAorICAgICAgIi0tcGx1Z19vdXQ6IHByZWZpeC1nZW4tcGx1ZzogUGx1Z2luIGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlIDEyMy4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yUGx1Z2luQ3Jhc2gpIHsKKyAgLy8gVGVzdCBhIGdlbmVyYXRvciBwbHVnaW4gdGhhdCBjcmFzaGVzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIE1vY2tDb2RlR2VuZXJhdG9yX0Fib3J0IHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tcGx1Z19vdXQ9VGVzdFBhcmFtZXRlcjokdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9BYm9ydC4iKTsKKworI2lmZGVmIF9XSU4zMgorICAvLyBXaW5kb3dzIGRvZXNuJ3QgaGF2ZSBzaWduYWxzLiAgSXQgbG9va3MgbGlrZSBhYm9ydCgpaW5nIGNhdXNlcyB0aGUgcHJvY2VzcworICAvLyB0byBleGl0IHdpdGggc3RhdHVzIGNvZGUgMywgYnV0IGxldCdzIG5vdCBkZXBlbmQgb24gdGhlIGV4YWN0IG51bWJlciBoZXJlLgorICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLXBsdWdfb3V0OiBwcmVmaXgtZ2VuLXBsdWc6IFBsdWdpbiBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSIpOworI2Vsc2UKKyAgLy8gRG9uJ3QgZGVwZW5kIG9uIHRoZSBleGFjdCBzaWduYWwgbnVtYmVyLgorICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLXBsdWdfb3V0OiBwcmVmaXgtZ2VuLXBsdWc6IFBsdWdpbiBraWxsZWQgYnkgc2lnbmFsIik7CisjZW5kaWYKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgUGx1Z2luUmVjZWl2ZXNTb3VyY2VDb2RlSW5mbykgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBNb2NrQ29kZUdlbmVyYXRvcl9IYXNTb3VyY2VDb2RlSW5mbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PSR0bXBkaXIgLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoCisgICAgICAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9IYXNTb3VyY2VDb2RlSW5mbzogMS4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yUGx1Z2luTm90Rm91bmQpIHsKKyAgLy8gVGVzdCB3aGF0IGhhcHBlbnMgaWYgdGhlIHBsdWdpbiBpc24ndCBmb3VuZC4KKworICBDcmVhdGVUZW1wRmlsZSgiZXJyb3IucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLWJhZHBsdWdfb3V0PVRlc3RQYXJhbWV0ZXI6JHRtcGRpciAiCisgICAgICAiLS1wbHVnaW49cHJlZml4LWdlbi1iYWRwbHVnPW5vX3N1Y2hfZmlsZSAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZXJyb3IucHJvdG8iKTsKKworI2lmZGVmIF9XSU4zMgorICBFeHBlY3RFcnJvclN1YnN0cmluZygiLS1iYWRwbHVnX291dDogcHJlZml4LWdlbi1iYWRwbHVnOiAiICsKKyAgICAgIFN1YnByb2Nlc3M6OldpbjMyRXJyb3JNZXNzYWdlKEVSUk9SX0ZJTEVfTk9UX0ZPVU5EKSk7CisjZWxzZQorICAvLyBFcnJvciB3cml0dGVuIHRvIHN0ZG91dCBieSBjaGlsZCBwcm9jZXNzIGFmdGVyIGV4ZWMoKSBmYWlscy4KKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoCisgICAgICAibm9fc3VjaF9maWxlOiBwcm9ncmFtIG5vdCBmb3VuZCBvciBpcyBub3QgZXhlY3V0YWJsZSIpOworCisgIC8vIEVycm9yIHdyaXR0ZW4gYnkgcGFyZW50IHByb2Nlc3Mgd2hlbiBjaGlsZCBmYWlscy4KKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoCisgICAgICAiLS1iYWRwbHVnX291dDogcHJlZml4LWdlbi1iYWRwbHVnOiBQbHVnaW4gZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgMS4iKTsKKyNlbmRpZgorfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHZW5lcmF0b3JQbHVnaW5Ob3RBbGxvd2VkKSB7CisgIC8vIFRlc3Qgd2hhdCBoYXBwZW5zIGlmIHBsdWdpbnMgYXJlbid0IGFsbG93ZWQuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImVycm9yLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIERpc2FsbG93UGx1Z2lucygpOworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tcGx1Z19vdXQ9VGVzdFBhcmFtZXRlcjokdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBlcnJvci5wcm90byIpOworCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJVbmtub3duIGZsYWc6IC0tcGx1Z19vdXQiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgSGVscFRleHQpIHsKKyAgUnVuKCJ0ZXN0X2V4ZWNfbmFtZSAtLWhlbHAiKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZ1dpdGhaZXJvUmV0dXJuQ29kZSgiVXNhZ2U6IHRlc3RfZXhlY19uYW1lICIpOworICBFeHBlY3RFcnJvclN1YnN0cmluZ1dpdGhaZXJvUmV0dXJuQ29kZSgiLS10ZXN0X291dD1PVVRfRElSIik7CisgIEV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKCJUZXN0IG91dHB1dC4iKTsKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmdXaXRoWmVyb1JldHVybkNvZGUoIi0tYWx0X291dD1PVVRfRElSIik7CisgIEV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKCJBbHQgb3V0cHV0LiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHY2NGb3JtYXRFcnJvcnMpIHsKKyAgLy8gVGVzdCAtLWVycm9yX2Zvcm1hdD1nY2MgKHdoaWNoIGlzIHRoZSBkZWZhdWx0LCBidXQgd2Ugd2FudCB0byB2ZXJpZnkKKyAgLy8gdGhhdCBpdCBjYW4gYmUgc2V0IGV4cGxpY2l0bHkpLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJiYWRzeW50YXhcbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciAtLWVycm9yX2Zvcm1hdD1nY2MgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICJmb28ucHJvdG86MjoxOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBNc3ZzRm9ybWF0RXJyb3JzKSB7CisgIC8vIFRlc3QgLS1lcnJvcl9mb3JtYXQ9bXN2cworCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJiYWRzeW50YXhcbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciAtLWVycm9yX2Zvcm1hdD1tc3ZzIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb28ucHJvdG8oMikgOiBlcnJvciBpbiBjb2x1bW49MTogRXhwZWN0ZWQgdG9wLWxldmVsIHN0YXRlbWVudCAiCisgICAgICAiKGUuZy4gXCJtZXNzYWdlXCIpLlxuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEludmFsaWRFcnJvckZvcm1hdCkgeworICAvLyBUZXN0IC0tZXJyb3JfZm9ybWF0PW1zdnMKKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiYmFkc3ludGF4XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgLS1lcnJvcl9mb3JtYXQ9aW52YWxpZCBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgIlVua25vd24gZXJyb3IgZm9ybWF0OiBpbnZhbGlkXG4iKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRmxhZyBwYXJzaW5nIHRlc3RzCisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFBhcnNlU2luZ2xlQ2hhcmFjdGVyRmxhZykgeworICAvLyBUZXN0IHRoYXQgYSBzaW5nbGUtY2hhcmFjdGVyIGZsYWcgd29ya3MuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC10JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXJzZVNwYWNlRGVsaW1pdGVkVmFsdWUpIHsKKyAgLy8gVGVzdCB0aGF0IHNlcGFyYXRpbmcgdGhlIGZsYWcgdmFsdWUgd2l0aCBhIHNwYWNlIHdvcmtzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0ICR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgUGFyc2VTaW5nbGVDaGFyYWN0ZXJTcGFjZURlbGltaXRlZFZhbHVlKSB7CisgIC8vIFRlc3QgdGhhdCBzZXBhcmF0aW5nIHRoZSBmbGFnIHZhbHVlIHdpdGggYSBzcGFjZSB3b3JrcyBmb3IKKyAgLy8gc2luZ2xlLWNoYXJhY3RlciBmbGFncy4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLXQgJHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBNaXNzaW5nVmFsdWVFcnJvcikgeworICAvLyBUZXN0IHRoYXQgd2UgZ2V0IGFuIGVycm9yIGlmIGEgZmxhZyBpcyBtaXNzaW5nIGl0cyB2YWx1ZS4KKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQgLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KCJNaXNzaW5nIHZhbHVlIGZvciBmbGFnOiAtLXRlc3Rfb3V0XG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgTWlzc2luZ1ZhbHVlQXRFbmRFcnJvcikgeworICAvLyBUZXN0IHRoYXQgd2UgZ2V0IGFuIGVycm9yIGlmIHRoZSBsYXN0IGFyZ3VtZW50IGlzIGEgZmxhZyByZXF1aXJpbmcgYQorICAvLyB2YWx1ZS4KKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQiKTsKKworICBFeHBlY3RFcnJvclRleHQoIk1pc3NpbmcgdmFsdWUgZm9yIGZsYWc6IC0tdGVzdF9vdXRcbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQcmludEZyZWVGaWVsZE51bWJlcnMpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoCisgICAgICAiZm9vLnByb3RvIiwKKyAgICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICAgInBhY2thZ2UgZm9vO1xuIgorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgIG9wdGlvbmFsIGludDMyIGEgPSAyO1xuIgorICAgICAgIiAgb3B0aW9uYWwgc3RyaW5nIGIgPSA0O1xuIgorICAgICAgIiAgb3B0aW9uYWwgc3RyaW5nIGMgPSA1O1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50NjQgZCA9IDg7XG4iCisgICAgICAiICBvcHRpb25hbCBkb3VibGUgZSA9IDEwO1xuIgorICAgICAgIn1cbiIpOworICBDcmVhdGVUZW1wRmlsZSgKKyAgICAgICJiYXIucHJvdG8iLAorICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50MzIgYSA9IDI7XG4iCisgICAgICAiICBleHRlbnNpb25zIDQgdG8gNTtcbiIKKyAgICAgICIgIG9wdGlvbmFsIGludDY0IGQgPSA4O1xuIgorICAgICAgIiAgZXh0ZW5zaW9ucyAxMDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoCisgICAgICAiYmF6LnByb3RvIiwKKyAgICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICAgIm1lc3NhZ2UgQmF6IHtcbiIKKyAgICAgICIgIG9wdGlvbmFsIGludDMyIGEgPSAyO1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50NjQgZCA9IDg7XG4iCisgICAgICAiICBleHRlbnNpb25zIDE1IHRvIG1heDtcbiIgIC8vIHVub3JkZXJlZC4KKyAgICAgICIgIGV4dGVuc2lvbnMgMTM7XG4iCisgICAgICAiICBleHRlbnNpb25zIDEwIHRvIDEyO1xuIgorICAgICAgIiAgZXh0ZW5zaW9ucyA1O1xuIgorICAgICAgIiAgZXh0ZW5zaW9ucyA0O1xuIgorICAgICAgIn1cbiIpOworICBDcmVhdGVUZW1wRmlsZSgKKyAgICAgICJxdXoucHJvdG8iLAorICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAibWVzc2FnZSBRdXoge1xuIgorICAgICAgIiAgbWVzc2FnZSBGb28ge31cbiIgIC8vIG5lc3RlZCBtZXNzYWdlCisgICAgICAiICBvcHRpb25hbCBpbnQzMiBhID0gMjtcbiIKKyAgICAgICIgIG9wdGlvbmFsIGdyb3VwIEMgPSA0IHtcbiIKKyAgICAgICIgICAgb3B0aW9uYWwgaW50MzIgZCA9IDU7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICBleHRlbnNpb25zIDggdG8gMTA7XG4iCisgICAgICAiICBvcHRpb25hbCBncm91cCBFID0gMTEge1xuIgorICAgICAgIiAgICBvcHRpb25hbCBpbnQzMiBmID0gOTtcbiIgICAgLy8gZXhwbGljaXRseSByZXVzZSBleHRlbnNpb24gcmFuZ2UgOC0xMAorICAgICAgIiAgICBvcHRpb25hbCBncm91cCBHID0gMTUge1xuIiAgLy8gbmVzdGVkIGdyb3VwCisgICAgICAiICAgICAgbWVzc2FnZSBGb28ge31cbiIgICAgICAgICAvLyBuZXN0ZWQgbWVzc2FnZSBpbnNpZGUgbmVzdGVkIGdyb3VwCisgICAgICAiICAgIH1cbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tcHJpbnRfZnJlZV9maWVsZF9udW1iZXJzIC0tcHJvdG9fcGF0aD0kdG1wZGlyICIKKyAgICAgICJmb28ucHJvdG8gYmFyLnByb3RvIGJhei5wcm90byBxdXoucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworCisgIC8vIFRPRE8oamllbHVvKTogQ3lnd2luIGRvZXNuJ3Qgd29yayB3ZWxsIGlmIHdlIHRyeSB0byBjYXB0dXJlIHN0ZGVyciBhbmQKKyAgLy8gc3Rkb3V0IGF0IHRoZSBzYW1lIHRpbWUuIE5lZWQgdG8gZmlndXJlIG91dCB3aHkgYW5kIGFkZCB0aGlzIHRlc3QgYmFjaworICAvLyBmb3IgQ3lnd2luLgorI2lmICFkZWZpbmVkKF9fQ1lHV0lOX18pCisgIEV4cGVjdENhcHR1cmVkU3Rkb3V0KAorICAgICAgImZvby5Gb28gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWU6IDEgMyA2LTcgOSAxMS1JTkZcbiIKKyAgICAgICJCYXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlOiAxIDMgNi03IDkgMTEtSU5GXG4iCisgICAgICAiQmF6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZTogMSAzIDYtNyA5IDE0XG4iCisgICAgICAiUXV6LkZvbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZTogMS1JTkZcbiIKKyAgICAgICJRdXouRS5HLkZvbyAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlOiAxLUlORlxuIgorICAgICAgIlF1eiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWU6IDEgMyA2LTcgMTItMTQgMTYtSU5GXG4iKTsKKyNlbmRpZgorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRlc3QgZm9yIC0tZW5jb2RlIGFuZCAtLWRlY29kZS4gIE5vdGUgdGhhdCBpdCB3b3VsZCBiZSBlYXNpZXIgdG8gZG8gdGhpcworLy8gdGVzdCBhcyBhIHNoZWxsIHNjcmlwdCwgYnV0IHdlJ2QgbGlrZSB0byBiZSBhYmxlIHRvIHJ1biB0aGUgdGVzdCBvbgorLy8gcGxhdGZvcm1zIHRoYXQgZG9uJ3QgaGF2ZSBhIEJvdXJuZS1jb21wYXRpYmxlIHNoZWxsIGF2YWlsYWJsZSAoZXNwZWNpYWxseQorLy8gV2luZG93cy9NU1ZDKS4KK2NsYXNzIEVuY29kZURlY29kZVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgZHVwZWRfc3RkaW5fID0gZHVwKFNURElOX0ZJTEVOTyk7CisgIH0KKworICB2aXJ0dWFsIHZvaWQgVGVhckRvd24oKSB7CisgICAgZHVwMihkdXBlZF9zdGRpbl8sIFNURElOX0ZJTEVOTyk7CisgICAgY2xvc2UoZHVwZWRfc3RkaW5fKTsKKyAgfQorCisgIHZvaWQgUmVkaXJlY3RTdGRpbkZyb21UZXh0KGNvbnN0IHN0cmluZyYgaW5wdXQpIHsKKyAgICBzdHJpbmcgZmlsZW5hbWUgPSBUZXN0VGVtcERpcigpICsgIi90ZXN0X3N0ZGluIjsKKyAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6U2V0Q29udGVudHMoZmlsZW5hbWUsIGlucHV0LCB0cnVlKSk7CisgICAgR09PR0xFX0NIRUNLKFJlZGlyZWN0U3RkaW5Gcm9tRmlsZShmaWxlbmFtZSkpOworICB9CisKKyAgYm9vbCBSZWRpcmVjdFN0ZGluRnJvbUZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIGludCBmZCA9IG9wZW4oZmlsZW5hbWUuY19zdHIoKSwgT19SRE9OTFkpOworICAgIGlmIChmZCA8IDApIHJldHVybiBmYWxzZTsKKyAgICBkdXAyKGZkLCBTVERJTl9GSUxFTk8pOworICAgIGNsb3NlKGZkKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFJlbW92ZSAnXHInIGNoYXJhY3RlcnMgZnJvbSB0ZXh0LgorICBzdHJpbmcgU3RyaXBDUihjb25zdCBzdHJpbmcmIHRleHQpIHsKKyAgICBzdHJpbmcgcmVzdWx0OworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXh0LnNpemUoKTsgaSsrKSB7CisgICAgICBpZiAodGV4dFtpXSAhPSAnXHInKSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2sodGV4dFtpXSk7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIGVudW0gVHlwZSB7IFRFWFQsIEJJTkFSWSB9OworICBlbnVtIFJldHVybkNvZGUgeyBTVUNDRVNTLCBFUlJPUiB9OworCisgIGJvb2wgUnVuKGNvbnN0IHN0cmluZyYgY29tbWFuZCkgeworICAgIHZlY3RvcjxzdHJpbmc+IGFyZ3M7CisgICAgYXJncy5wdXNoX2JhY2soInByb3RvYyIpOworICAgIFNwbGl0U3RyaW5nVXNpbmcoY29tbWFuZCwgIiAiLCAmYXJncyk7CisgICAgYXJncy5wdXNoX2JhY2soIi0tcHJvdG9fcGF0aD0iICsgVGVzdFNvdXJjZURpcigpKTsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjb25zdCBjaGFyICogPiBhcmd2KG5ldyBjb25zdCBjaGFyKiBbYXJncy5zaXplKCldKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3Muc2l6ZSgpOyBpKyspIHsKKyAgICAgIGFyZ3ZbaV0gPSBhcmdzW2ldLmNfc3RyKCk7CisgICAgfQorCisgICAgQ29tbWFuZExpbmVJbnRlcmZhY2UgY2xpOworICAgIGNsaS5TZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZSh0cnVlKTsKKworICAgIENhcHR1cmVUZXN0U3Rkb3V0KCk7CisgICAgQ2FwdHVyZVRlc3RTdGRlcnIoKTsKKworICAgIGludCByZXN1bHQgPSBjbGkuUnVuKGFyZ3Muc2l6ZSgpLCBhcmd2LmdldCgpKTsKKworICAgIGNhcHR1cmVkX3N0ZG91dF8gPSBHZXRDYXB0dXJlZFRlc3RTdGRvdXQoKTsKKyAgICBjYXB0dXJlZF9zdGRlcnJfID0gR2V0Q2FwdHVyZWRUZXN0U3RkZXJyKCk7CisKKyAgICByZXR1cm4gcmVzdWx0ID09IDA7CisgIH0KKworICB2b2lkIEV4cGVjdFN0ZG91dE1hdGNoZXNCaW5hcnlGaWxlKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgICBzdHJpbmcgZXhwZWN0ZWRfb3V0cHV0OworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cyhmaWxlbmFtZSwgJmV4cGVjdGVkX291dHB1dCwgdHJ1ZSkpOworCisgICAgLy8gRG9uJ3QgdXNlIEVYUEVDVF9FUSBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gcHJpbnQgcmF3IGJpbmFyeSBkYXRhIHRvCisgICAgLy8gc3Rkb3V0IG9uIGZhaWx1cmUuCisgICAgRVhQRUNUX1RSVUUoY2FwdHVyZWRfc3Rkb3V0XyA9PSBleHBlY3RlZF9vdXRwdXQpOworICB9CisKKyAgdm9pZCBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dEZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIHN0cmluZyBleHBlY3RlZF9vdXRwdXQ7CisgICAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkdldENvbnRlbnRzKGZpbGVuYW1lLCAmZXhwZWN0ZWRfb3V0cHV0LCB0cnVlKSk7CisKKyAgICBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dChleHBlY3RlZF9vdXRwdXQpOworICB9CisKKyAgdm9pZCBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dChjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3RleHQpIHsKKyAgICBFWFBFQ1RfRVEoU3RyaXBDUihleHBlY3RlZF90ZXh0KSwgU3RyaXBDUihjYXB0dXJlZF9zdGRvdXRfKSk7CisgIH0KKworICB2b2lkIEV4cGVjdFN0ZGVyck1hdGNoZXNUZXh0KGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfdGV4dCkgeworICAgIEVYUEVDVF9FUShTdHJpcENSKGV4cGVjdGVkX3RleHQpLCBTdHJpcENSKGNhcHR1cmVkX3N0ZGVycl8pKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgaW50IGR1cGVkX3N0ZGluXzsKKyAgc3RyaW5nIGNhcHR1cmVkX3N0ZG91dF87CisgIHN0cmluZyBjYXB0dXJlZF9zdGRlcnJfOworfTsKKworVEVTVF9GKEVuY29kZURlY29kZVRlc3QsIEVuY29kZSkgeworICBSZWRpcmVjdFN0ZGluRnJvbUZpbGUoVGVzdFNvdXJjZURpcigpICsgIi9nb29nbGUvcHJvdG9idWYvIgorICAgICJ0ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX29uZW9mX2ltcGxlbWVudGVkLnR4dCIpOworICBFWFBFQ1RfVFJVRShSdW4oImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byAiCisgICAgICAgICAgICAgICAgICAiLS1lbmNvZGU9cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIikpOworICBFeHBlY3RTdGRvdXRNYXRjaGVzQmluYXJ5RmlsZShUZXN0U291cmNlRGlyKCkgKworICAgICIvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlX29uZW9mX2ltcGxlbWVudGVkIik7CisgIEV4cGVjdFN0ZGVyck1hdGNoZXNUZXh0KCIiKTsKK30KKworVEVTVF9GKEVuY29kZURlY29kZVRlc3QsIERlY29kZSkgeworICBSZWRpcmVjdFN0ZGluRnJvbUZpbGUoVGVzdFNvdXJjZURpcigpICsKKyAgICAiL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9vbmVvZl9pbXBsZW1lbnRlZCIpOworICBFWFBFQ1RfVFJVRShSdW4oImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byAiCisgICAgICAgICAgICAgICAgICAiLS1kZWNvZGU9cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIikpOworICBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dEZpbGUoVGVzdFNvdXJjZURpcigpICsKKyAgICAiL2dvb2dsZS9wcm90b2J1Zi8iCisgICAgInRlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfb25lb2ZfaW1wbGVtZW50ZWQudHh0Iik7CisgIEV4cGVjdFN0ZGVyck1hdGNoZXNUZXh0KCIiKTsKK30KKworVEVTVF9GKEVuY29kZURlY29kZVRlc3QsIFBhcnRpYWwpIHsKKyAgUmVkaXJlY3RTdGRpbkZyb21UZXh0KCIiKTsKKyAgRVhQRUNUX1RSVUUoUnVuKCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8gIgorICAgICAgICAgICAgICAgICAgIi0tZW5jb2RlPXByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCIpKTsKKyAgRXhwZWN0U3Rkb3V0TWF0Y2hlc1RleHQoIiIpOworICBFeHBlY3RTdGRlcnJNYXRjaGVzVGV4dCgKKyAgICAid2FybmluZzogIElucHV0IG1lc3NhZ2UgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICBhLCBiLCBjXG4iKTsKK30KKworVEVTVF9GKEVuY29kZURlY29kZVRlc3QsIERlY29kZVJhdykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDMyKDEyMyk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3N0cmluZygiZm9vIik7CisgIHN0cmluZyBkYXRhOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICBSZWRpcmVjdFN0ZGluRnJvbVRleHQoZGF0YSk7CisgIEVYUEVDVF9UUlVFKFJ1bigiLS1kZWNvZGVfcmF3IikpOworICBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dCgiMTogMTIzXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICIxNDogXCJmb29cIlxuIik7CisgIEV4cGVjdFN0ZGVyck1hdGNoZXNUZXh0KCIiKTsKK30KKworVEVTVF9GKEVuY29kZURlY29kZVRlc3QsIFVua25vd25UeXBlKSB7CisgIEVYUEVDVF9GQUxTRShSdW4oImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byAiCisgICAgICAgICAgICAgICAgICAgIi0tZW5jb2RlPU5vU3VjaFR5cGUiKSk7CisgIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0KCIiKTsKKyAgRXhwZWN0U3RkZXJyTWF0Y2hlc1RleHQoIlR5cGUgbm90IGRlZmluZWQ6IE5vU3VjaFR5cGVcbiIpOworfQorCitURVNUX0YoRW5jb2RlRGVjb2RlVGVzdCwgUHJvdG9QYXJzZUVycm9yKSB7CisgIEVYUEVDVF9GQUxTRShSdW4oImdvb2dsZS9wcm90b2J1Zi9ub19zdWNoX2ZpbGUucHJvdG8gIgorICAgICAgICAgICAgICAgICAgICItLWVuY29kZT1Ob1N1Y2hUeXBlIikpOworICBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dCgiIik7CisgIEV4cGVjdFN0ZGVyck1hdGNoZXNUZXh0KAorICAgICJnb29nbGUvcHJvdG9idWYvbm9fc3VjaF9maWxlLnByb3RvOiBGaWxlIG5vdCBmb3VuZC5cbiIpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKyNlbmRpZiAgLy8gIUdPT0dMRV9QUk9UT0JVRl9IRUFQX0NIRUNLX0RSQUNPTklBTgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2Jvb3RzdHJhcF91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9ib290c3RyYXBfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNlZDBiNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9ib290c3RyYXBfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxNTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIHRlc3QgaW5zdXJlcyB0aGF0IGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLntoLGNjfSBtYXRjaCBleGFjdGx5CisvLyB3aGF0IHdvdWxkIGJlIGdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgY29tcGlsZXIuICBUaGVzZSBmaWxlcyBhcmUgbm90CisvLyBnZW5lcmF0ZWQgYXV0b21hdGljYWxseSBhdCBidWlsZCB0aW1lIGJlY2F1c2UgdGhleSBhcmUgY29tcGlsZWQgaW50byB0aGUKKy8vIHByb3RvY29sIGNvbXBpbGVyIGl0c2VsZi4gIFNvLCBpZiB0aGV5IHdlcmUgYXV0by1nZW5lcmF0ZWQsIHlvdSdkIGhhdmUgYQorLy8gY2hpY2tlbi1hbmQtZWdnIHByb2JsZW0uCisvLworLy8gSWYgdGhpcyB0ZXN0IGZhaWxzLCBydW4gdGhlIHNjcmlwdAorLy8gImdlbmVyYXRlX2Rlc2NyaXB0b3JfcHJvdG8uc2giIGFuZCBhZGQKKy8vIGRlc2NyaXB0b3IucGIue2gsY2N9IHRvIHlvdXIgY2hhbmdlbGlzdC4KKworI2luY2x1ZGUgPG1hcD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCituYW1lc3BhY2UgeworCitjbGFzcyBNb2NrRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgTW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKyAgfk1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisKKyAgc3RyaW5nIHRleHRfOworCisgIC8vIGltcGxlbWVudHMgRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1bW4sCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmdGV4dF8sICIkMDokMTokMjogJDNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgfQorfTsKKworY2xhc3MgTW9ja0dlbmVyYXRvckNvbnRleHQgOiBwdWJsaWMgR2VuZXJhdG9yQ29udGV4dCB7CisgcHVibGljOgorICBNb2NrR2VuZXJhdG9yQ29udGV4dCgpIHt9CisgIH5Nb2NrR2VuZXJhdG9yQ29udGV4dCgpIHsKKyAgICBTVExEZWxldGVWYWx1ZXMoJmZpbGVzXyk7CisgIH0KKworICB2b2lkIEV4cGVjdEZpbGVNYXRjaGVzKGNvbnN0IHN0cmluZyYgdmlydHVhbF9maWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBoeXNpY2FsX2ZpbGVuYW1lKSB7CisgICAgc3RyaW5nKiBleHBlY3RlZF9jb250ZW50cyA9IEZpbmRQdHJPck51bGwoZmlsZXNfLCB2aXJ0dWFsX2ZpbGVuYW1lKTsKKyAgICBBU1NFUlRfVFJVRShleHBlY3RlZF9jb250ZW50cyAhPSBOVUxMKQorICAgICAgPDwgIkdlbmVyYXRvciBmYWlsZWQgdG8gZ2VuZXJhdGUgZmlsZTogIiA8PCB2aXJ0dWFsX2ZpbGVuYW1lOworCisgICAgc3RyaW5nIGFjdHVhbF9jb250ZW50czsKKyAgICBHT09HTEVfQ0hFQ0tfT0soCisgICAgICAgIEZpbGU6OkdldENvbnRlbnRzKFRlc3RTb3VyY2VEaXIoKSArICIvIiArIHBoeXNpY2FsX2ZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAmYWN0dWFsX2NvbnRlbnRzLCB0cnVlKSk7CisgICAgRVhQRUNUX1RSVUUoYWN0dWFsX2NvbnRlbnRzID09ICpleHBlY3RlZF9jb250ZW50cykKKyAgICAgIDw8IHBoeXNpY2FsX2ZpbGVuYW1lIDw8ICIgbmVlZHMgdG8gYmUgcmVnZW5lcmF0ZWQuICBQbGVhc2UgcnVuICIKKyAgICAgICAgICJnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcmVsZWFzZV9jb21waWxlci5zaCBhbmQgIgorICAgICAgICAgImdlbmVyYXRlX2Rlc2NyaXB0b3JfcHJvdG8uc2guIFRoZW4gYWRkIHRoaXMgZmlsZSAiCisgICAgICAgICAidG8geW91ciBDTC4iOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBHZW5lcmF0b3JDb250ZXh0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgdmlydHVhbCBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIHN0cmluZyoqIG1hcF9zbG90ID0gJmZpbGVzX1tmaWxlbmFtZV07CisgICAgaWYgKCptYXBfc2xvdCAhPSBOVUxMKSBkZWxldGUgKm1hcF9zbG90OworICAgICptYXBfc2xvdCA9IG5ldyBzdHJpbmc7CisKKyAgICByZXR1cm4gbmV3IGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0oKm1hcF9zbG90KTsKKyAgfQorCisgcHJpdmF0ZToKKyAgbWFwPHN0cmluZywgc3RyaW5nKj4gZmlsZXNfOworfTsKKworVEVTVChCb290c3RyYXBUZXN0LCBHZW5lcmF0ZWREZXNjcmlwdG9yTWF0Y2hlcykgeworICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBEaXNrU291cmNlVHJlZSBzb3VyY2VfdHJlZTsKKyAgc291cmNlX3RyZWUuTWFwUGF0aCgiIiwgVGVzdFNvdXJjZURpcigpKTsKKyAgSW1wb3J0ZXIgaW1wb3J0ZXIoJnNvdXJjZV90cmVlLCAmZXJyb3JfY29sbGVjdG9yKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHByb3RvX2ZpbGUgPQorICAgIGltcG9ydGVyLkltcG9ydCgiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHBsdWdpbl9wcm90b19maWxlID0KKyAgICBpbXBvcnRlci5JbXBvcnQoImdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8iKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworICBBU1NFUlRfVFJVRShwcm90b19maWxlICE9IE5VTEwpOworICBBU1NFUlRfVFJVRShwbHVnaW5fcHJvdG9fZmlsZSAhPSBOVUxMKTsKKworICBDcHBHZW5lcmF0b3IgZ2VuZXJhdG9yOworICBNb2NrR2VuZXJhdG9yQ29udGV4dCBjb250ZXh0OworICBzdHJpbmcgZXJyb3I7CisgIHN0cmluZyBwYXJhbWV0ZXI7CisgIHBhcmFtZXRlciA9ICJkbGxleHBvcnRfZGVjbD1MSUJQUk9UT0JVRl9FWFBPUlQiOworICBBU1NFUlRfVFJVRShnZW5lcmF0b3IuR2VuZXJhdGUocHJvdG9fZmlsZSwgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbnRleHQsICZlcnJvcikpOworICBwYXJhbWV0ZXIgPSAiZGxsZXhwb3J0X2RlY2w9TElCUFJPVE9DX0VYUE9SVCI7CisgIEFTU0VSVF9UUlVFKGdlbmVyYXRvci5HZW5lcmF0ZShwbHVnaW5fcHJvdG9fZmlsZSwgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbnRleHQsICZlcnJvcikpOworCisgIGNvbnRleHQuRXhwZWN0RmlsZU1hdGNoZXMoImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oIik7CisgIGNvbnRleHQuRXhwZWN0RmlsZU1hdGNoZXMoImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuY2MiKTsKKyAgY29udGV4dC5FeHBlY3RGaWxlTWF0Y2hlcygiZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oIik7CisgIGNvbnRleHQuRXhwZWN0RmlsZU1hdGNoZXMoImdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmNjIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWIyMGFiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uY2MKQEAgLTAsMCArMSwzMDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPHNldD4KKyNpbmNsdWRlIDxtYXA+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCituYW1lc3BhY2UgeworLy8gVGhlIEdPT0dMRV9BUlJBWVNJWkUgY29uc3RhbnQgaXMgdGhlIG1heCBlbnVtIHZhbHVlIHBsdXMgMS4gSWYgdGhlIG1heCBlbnVtIHZhbHVlCisvLyBpcyA6Omdvb2dsZTo6cHJvdG9idWY6OmtpbnQzMm1heCwgR09PR0xFX0FSUkFZU0laRSB3aWxsIG92ZXJmbG93LiBJbiBzdWNoIGNhc2VzIHdlIHNob3VsZCBvbWl0IHRoZQorLy8gZ2VuZXJhdGlvbiBvZiB0aGUgR09PR0xFX0FSUkFZU0laRSBjb25zdGFudC4KK2Jvb2wgU2hvdWxkR2VuZXJhdGVBcnJheVNpemUoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgaW50MzIgbWF4X3ZhbHVlID0gZGVzY3JpcHRvci0+dmFsdWUoMCktPm51bWJlcigpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yLT52YWx1ZShpKS0+bnVtYmVyKCkgPiBtYXhfdmFsdWUpIHsKKyAgICAgIG1heF92YWx1ZSA9IGRlc2NyaXB0b3ItPnZhbHVlKGkpLT5udW1iZXIoKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIG1heF92YWx1ZSAhPSA6Omdvb2dsZTo6cHJvdG9idWY6OmtpbnQzMm1heDsKK30KK30gIC8vIG5hbWVzcGFjZQorCitFbnVtR2VuZXJhdG9yOjpFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLAorICAgIGNsYXNzbmFtZV8oQ2xhc3NOYW1lKGRlc2NyaXB0b3IsIGZhbHNlKSksCisgICAgb3B0aW9uc18ob3B0aW9ucyksCisgICAgZ2VuZXJhdGVfYXJyYXlfc2l6ZV8oU2hvdWxkR2VuZXJhdGVBcnJheVNpemUoZGVzY3JpcHRvcikpIHsKK30KKworRW51bUdlbmVyYXRvcjo6fkVudW1HZW5lcmF0b3IoKSB7fQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lXzsKKyAgdmFyc1sic2hvcnRfbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKworICBwcmludGVyLT5QcmludCh2YXJzLCAiZW51bSAkY2xhc3NuYW1lJCB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogbWluX3ZhbHVlID0gZGVzY3JpcHRvcl8tPnZhbHVlKDApOworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBtYXhfdmFsdWUgPSBkZXNjcmlwdG9yXy0+dmFsdWUoMCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgdmFyc1sibmFtZSJdID0gRW51bVZhbHVlTmFtZShkZXNjcmlwdG9yXy0+dmFsdWUoaSkpOworICAgIC8vIEluIEMrKywgYW4gdmFsdWUgb2YgLTIxNDc0ODM2NDggZ2V0cyBpbnRlcnByZXRlZCBhcyB0aGUgbmVnYXRpdmUgb2YKKyAgICAvLyAyMTQ3NDgzNjQ4LCBhbmQgc2luY2UgMjE0NzQ4MzY0OCBjYW4ndCBmaXQgaW4gYW4gaW50ZWdlciwgdGhpcyBwcm9kdWNlcyBhCisgICAgLy8gY29tcGlsZXIgd2FybmluZy4gIFRoaXMgd29ya3MgYXJvdW5kIHRoYXQgaXNzdWUuCisgICAgdmFyc1sibnVtYmVyIl0gPSBJbnQzMlRvU3RyaW5nKGRlc2NyaXB0b3JfLT52YWx1ZShpKS0+bnVtYmVyKCkpOworICAgIHZhcnNbInByZWZpeCJdID0gKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSA9PSBOVUxMKSA/CisgICAgICAiIiA6IGNsYXNzbmFtZV8gKyAiXyI7CisKKworICAgIGlmIChpID4gMCkgcHJpbnRlci0+UHJpbnQoIixcbiIpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsICIkcHJlZml4JCRuYW1lJCA9ICRudW1iZXIkIik7CisKKyAgICBpZiAoZGVzY3JpcHRvcl8tPnZhbHVlKGkpLT5udW1iZXIoKSA8IG1pbl92YWx1ZS0+bnVtYmVyKCkpIHsKKyAgICAgIG1pbl92YWx1ZSA9IGRlc2NyaXB0b3JfLT52YWx1ZShpKTsKKyAgICB9CisgICAgaWYgKGRlc2NyaXB0b3JfLT52YWx1ZShpKS0+bnVtYmVyKCkgPiBtYXhfdmFsdWUtPm51bWJlcigpKSB7CisgICAgICBtYXhfdmFsdWUgPSBkZXNjcmlwdG9yXy0+dmFsdWUoaSk7CisgICAgfQorICB9CisKKyAgaWYgKEhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIEZvciBuZXcgZW51bSBzZW1hbnRpY3M6IGdlbmVyYXRlIG1pbiBhbmQgbWF4IHNlbnRpbmVsIHZhbHVlcyBlcXVhbCB0bworICAgIC8vIElOVDMyX01JTiBhbmQgSU5UMzJfTUFYCisgICAgaWYgKGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpID4gMCkgcHJpbnRlci0+UHJpbnQoIixcbiIpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICIkY2xhc3NuYW1lJF8kcHJlZml4JElOVF9NSU5fU0VOVElORUxfRE9fTk9UX1VTRV8gPSA6Omdvb2dsZTo6cHJvdG9idWY6OmtpbnQzMm1pbixcbiIKKyAgICAgICAgIiRjbGFzc25hbWUkXyRwcmVmaXgkSU5UX01BWF9TRU5USU5FTF9ET19OT1RfVVNFXyA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWF4Iik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJcbn07XG4iKTsKKworICB2YXJzWyJtaW5fbmFtZSJdID0gRW51bVZhbHVlTmFtZShtaW5fdmFsdWUpOworICB2YXJzWyJtYXhfbmFtZSJdID0gRW51bVZhbHVlTmFtZShtYXhfdmFsdWUpOworCisgIGlmIChvcHRpb25zXy5kbGxleHBvcnRfZGVjbC5lbXB0eSgpKSB7CisgICAgdmFyc1siZGxsZXhwb3J0Il0gPSAiIjsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJkbGxleHBvcnQiXSA9IG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsICsgIiAiOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiJGRsbGV4cG9ydCRib29sICRjbGFzc25hbWUkX0lzVmFsaWQoaW50IHZhbHVlKTtcbiIKKyAgICAiY29uc3QgJGNsYXNzbmFtZSQgJHByZWZpeCQkc2hvcnRfbmFtZSRfTUlOID0gJHByZWZpeCQkbWluX25hbWUkO1xuIgorICAgICJjb25zdCAkY2xhc3NuYW1lJCAkcHJlZml4JCRzaG9ydF9uYW1lJF9NQVggPSAkcHJlZml4JCRtYXhfbmFtZSQ7XG4iKTsKKworICBpZiAoZ2VuZXJhdGVfYXJyYXlfc2l6ZV8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgImNvbnN0IGludCAkcHJlZml4JCRzaG9ydF9uYW1lJF9BUlJBWVNJWkUgPSAiCisgICAgICAiJHByZWZpeCQkc2hvcnRfbmFtZSRfTUFYICsgMTtcblxuIik7CisgIH0KKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRkbGxleHBvcnQkY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogJGNsYXNzbmFtZSRfZGVzY3JpcHRvcigpO1xuIik7CisgICAgLy8gVGhlIF9OYW1lIGFuZCBfUGFyc2UgbWV0aG9kcworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmICRjbGFzc25hbWUkX05hbWUoJGNsYXNzbmFtZSQgdmFsdWUpIHtcbiIKKyAgICAgICIgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOYW1lT2ZFbnVtKFxuIgorICAgICAgIiAgICAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yKCksIHZhbHVlKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgImlubGluZSBib29sICRjbGFzc25hbWUkX1BhcnNlKFxuIgorICAgICAgIiAgICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLCAkY2xhc3NuYW1lJCogdmFsdWUpIHtcbiIKKyAgICAgICIgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpQYXJzZU5hbWVkRW51bTwkY2xhc3NuYW1lJD4oXG4iCisgICAgICAiICAgICRjbGFzc25hbWUkX2Rlc2NyaXB0b3IoKSwgbmFtZSwgdmFsdWUpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUdlbmVyYXRvcjo6CitHZW5lcmF0ZUdldEVudW1EZXNjcmlwdG9yU3BlY2lhbGl6YXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgInRlbXBsYXRlIDw+IHN0cnVjdCBpc19wcm90b19lbnVtPCAkY2xhc3NuYW1lJD4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUgIgorICAgICAgInt9O1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBDbGFzc05hbWUoZGVzY3JpcHRvcl8sIHRydWUpKTsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidGVtcGxhdGUgPD5cbiIKKyAgICAgICJpbmxpbmUgY29uc3QgRW51bURlc2NyaXB0b3IqIEdldEVudW1EZXNjcmlwdG9yPCAkY2xhc3NuYW1lJD4oKSB7XG4iCisgICAgICAiICByZXR1cm4gJGNsYXNzbmFtZSRfZGVzY3JpcHRvcigpO1xuIgorICAgICAgIn1cbiIsCisgICAgICAiY2xhc3NuYW1lIiwgQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLCB0cnVlKSk7CisgIH0KK30KKwordm9pZCBFbnVtR2VuZXJhdG9yOjpHZW5lcmF0ZVN5bWJvbEltcG9ydHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJuZXN0ZWRfbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBjbGFzc25hbWVfOworICBwcmludGVyLT5QcmludCh2YXJzLCAidHlwZWRlZiAkY2xhc3NuYW1lJCAkbmVzdGVkX25hbWUkO1xuIik7CisKKyAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaisrKSB7CisgICAgdmFyc1sidGFnIl0gPSBFbnVtVmFsdWVOYW1lKGRlc2NyaXB0b3JfLT52YWx1ZShqKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJzdGF0aWMgY29uc3QgJG5lc3RlZF9uYW1lJCAkdGFnJCA9ICRjbGFzc25hbWUkXyR0YWckO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICJzdGF0aWMgaW5saW5lIGJvb2wgJG5lc3RlZF9uYW1lJF9Jc1ZhbGlkKGludCB2YWx1ZSkge1xuIgorICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9Jc1ZhbGlkKHZhbHVlKTtcbiIKKyAgICAifVxuIgorICAgICJzdGF0aWMgY29uc3QgJG5lc3RlZF9uYW1lJCAkbmVzdGVkX25hbWUkX01JTiA9XG4iCisgICAgIiAgJGNsYXNzbmFtZSRfJG5lc3RlZF9uYW1lJF9NSU47XG4iCisgICAgInN0YXRpYyBjb25zdCAkbmVzdGVkX25hbWUkICRuZXN0ZWRfbmFtZSRfTUFYID1cbiIKKyAgICAiICAkY2xhc3NuYW1lJF8kbmVzdGVkX25hbWUkX01BWDtcbiIpOworICBpZiAoZ2VuZXJhdGVfYXJyYXlfc2l6ZV8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInN0YXRpYyBjb25zdCBpbnQgJG5lc3RlZF9uYW1lJF9BUlJBWVNJWkUgPVxuIgorICAgICAgIiAgJGNsYXNzbmFtZSRfJG5lc3RlZF9uYW1lJF9BUlJBWVNJWkU7XG4iKTsKKyAgfQorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAic3RhdGljIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKlxuIgorICAgICAgIiRuZXN0ZWRfbmFtZSRfZGVzY3JpcHRvcigpIHtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yKCk7XG4iCisgICAgICAifVxuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJzdGF0aWMgaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmICRuZXN0ZWRfbmFtZSRfTmFtZSgkbmVzdGVkX25hbWUkIHZhbHVlKSB7XG4iCisgICAgICAiICByZXR1cm4gJGNsYXNzbmFtZSRfTmFtZSh2YWx1ZSk7XG4iCisgICAgICAifVxuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJzdGF0aWMgaW5saW5lIGJvb2wgJG5lc3RlZF9uYW1lJF9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLFxuIgorICAgICAgIiAgICAkbmVzdGVkX25hbWUkKiB2YWx1ZSkge1xuIgorICAgICAgIiAgcmV0dXJuICRjbGFzc25hbWUkX1BhcnNlKG5hbWUsIHZhbHVlKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemVyKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBpbnQgaW5kZXgpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGluZGV4KTsKKworICBpZiAoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpID09IE5VTEwpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfID0gZmlsZS0+ZW51bV90eXBlKCRpbmRleCQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgdmFyc1sicGFyZW50Il0gPSBDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpLCBmYWxzZSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICIkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXyA9ICRwYXJlbnQkX2Rlc2NyaXB0b3JfLT5lbnVtX3R5cGUoJGluZGV4JCk7XG4iKTsKKyAgfQorfQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lXzsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqICRjbGFzc25hbWUkX2Rlc2NyaXB0b3IoKSB7XG4iCisgICAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgImJvb2wgJGNsYXNzbmFtZSRfSXNWYWxpZChpbnQgdmFsdWUpIHtcbiIKKyAgICAiICBzd2l0Y2godmFsdWUpIHtcbiIpOworCisgIC8vIE11bHRpcGxlIHZhbHVlcyBtYXkgaGF2ZSB0aGUgc2FtZSBudW1iZXIuICBNYWtlIHN1cmUgd2Ugb25seSBjb3ZlcgorICAvLyBlYWNoIG51bWJlciBvbmNlIGJ5IGZpcnN0IGNvbnN0cnVjdGluZyBhIHNldCBjb250YWluaW5nIGFsbCB2YWxpZAorICAvLyBudW1iZXJzLCB0aGVuIHByaW50aW5nIGEgY2FzZSBzdGF0ZW1lbnQgZm9yIGVhY2ggZWxlbWVudC4KKworICBzZXQ8aW50PiBudW1iZXJzOworICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpOyBqKyspIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSA9IGRlc2NyaXB0b3JfLT52YWx1ZShqKTsKKyAgICBudW1iZXJzLmluc2VydCh2YWx1ZS0+bnVtYmVyKCkpOworICB9CisKKyAgZm9yIChzZXQ8aW50Pjo6aXRlcmF0b3IgaXRlciA9IG51bWJlcnMuYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IG51bWJlcnMuZW5kKCk7ICsraXRlcikgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICBjYXNlICRudW1iZXIkOlxuIiwKKyAgICAgICJudW1iZXIiLCBJbnQzMlRvU3RyaW5nKCppdGVyKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgICByZXR1cm4gdHJ1ZTtcbiIKKyAgICAiICAgIGRlZmF1bHQ6XG4iCisgICAgIiAgICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBpZiAoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpICE9IE5VTEwpIHsKKyAgICAvLyBXZSBuZWVkIHRvICJkZWZpbmUiIHRoZSBzdGF0aWMgY29uc3RhbnRzIHdoaWNoIHdlcmUgZGVjbGFyZWQgaW4gdGhlCisgICAgLy8gaGVhZGVyLCB0byBnaXZlIHRoZSBsaW5rZXIgYSBwbGFjZSB0byBwdXQgdGhlbS4gIE9yIGF0IGxlYXN0IHRoZSBDKysKKyAgICAvLyBzdGFuZGFyZCBzYXlzIHdlIGhhdmUgdG8uICBNU1ZDIGFjdHVhbGx5IGluc2lzdHMgdGhhIHdlIGRvIF9ub3RfIGRlZmluZQorICAgIC8vIHRoZW0gYWdhaW4gaW4gdGhlIC5jYyBmaWxlLgorICAgIHByaW50ZXItPlByaW50KCIjaWZuZGVmIF9NU0NfVkVSXG4iKTsKKworICAgIHZhcnNbInBhcmVudCJdID0gQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSwgZmFsc2UpOworICAgIHZhcnNbIm5lc3RlZF9uYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgICAgdmFyc1sidmFsdWUiXSA9IEVudW1WYWx1ZU5hbWUoZGVzY3JpcHRvcl8tPnZhbHVlKGkpKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICJjb25zdCAkY2xhc3NuYW1lJCAkcGFyZW50JDo6JHZhbHVlJDtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgImNvbnN0ICRjbGFzc25hbWUkICRwYXJlbnQkOjokbmVzdGVkX25hbWUkX01JTjtcbiIKKyAgICAgICJjb25zdCAkY2xhc3NuYW1lJCAkcGFyZW50JDo6JG5lc3RlZF9uYW1lJF9NQVg7XG4iKTsKKyAgICBpZiAoZ2VuZXJhdGVfYXJyYXlfc2l6ZV8pIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICJjb25zdCBpbnQgJHBhcmVudCQ6OiRuZXN0ZWRfbmFtZSRfQVJSQVlTSVpFO1xuIik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoIiNlbmRpZiAgLy8gX01TQ19WRVJcbiIpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWJkN2NmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uaApAQCAtMCwwICsxLDEwMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRU5VTV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9FTlVNX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX29wdGlvbnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitjbGFzcyBFbnVtR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIC8vIFNlZSBnZW5lcmF0b3IuY2MgZm9yIHRoZSBtZWFuaW5nIG9mIGRsbGV4cG9ydF9kZWNsLgorICBleHBsaWNpdCBFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+RW51bUdlbmVyYXRvcigpOworCisgIC8vIEhlYWRlciBzdHVmZi4KKworICAvLyBHZW5lcmF0ZSBoZWFkZXIgY29kZSBkZWZpbmluZyB0aGUgZW51bS4gIFRoaXMgY29kZSBzaG91bGQgYmUgcGxhY2VkCisgIC8vIHdpdGhpbiB0aGUgZW51bSdzIHBhY2thZ2UgbmFtZXNwYWNlLCBidXQgTk9UIHdpdGhpbiBhbnkgY2xhc3MsIGV2ZW4gZm9yCisgIC8vIG5lc3RlZCBlbnVtcy4KKyAgdm9pZCBHZW5lcmF0ZURlZmluaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHNwZWNpYWxpemF0aW9uIG9mIEdldEVudW1EZXNjcmlwdG9yPE15RW51bT4oKS4KKyAgLy8gUHJlY29uZGl0aW9uOiBpbiA6Omdvb2dsZTo6cHJvdG9idWYgbmFtZXNwYWNlLgorICB2b2lkIEdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEZvciBlbnVtcyBuZXN0ZWQgd2l0aGluIGEgbWVzc2FnZSwgZ2VuZXJhdGUgY29kZSB0byBpbXBvcnQgYWxsIHRoZSBlbnVtJ3MKKyAgLy8gc3ltYm9scyAoZS5nLiB0aGUgZW51bSB0eXBlIG5hbWUsIGFsbCBpdHMgdmFsdWVzLCBldGMuKSBpbnRvIHRoZSBjbGFzcydzCisgIC8vIG5hbWVzcGFjZS4gIFRoaXMgc2hvdWxkIGJlIHBsYWNlZCBpbnNpZGUgdGhlIGNsYXNzIGRlZmluaXRpb24gaW4gdGhlCisgIC8vIGhlYWRlci4KKyAgdm9pZCBHZW5lcmF0ZVN5bWJvbEltcG9ydHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIFNvdXJjZSBmaWxlIHN0dWZmLgorCisgIC8vIEdlbmVyYXRlIGNvZGUgdGhhdCBpbml0aWFsaXplcyB0aGUgZ2xvYmFsIHZhcmlhYmxlIHN0b3JpbmcgdGhlIGVudW0ncworICAvLyBkZXNjcmlwdG9yLgorICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyLCBpbnQgaW5kZXgpOworCisgIC8vIEdlbmVyYXRlIG5vbi1pbmxpbmUgbWV0aG9kcyByZWxhdGVkIHRvIHRoZSBlbnVtLCBzdWNoIGFzIElzVmFsaWRWYWx1ZSgpLgorICAvLyBHb2VzIGluIHRoZSAuY2MgZmlsZS4KKyAgdm9pZCBHZW5lcmF0ZU1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBzdHJpbmcgY2xhc3NuYW1lXzsKKyAgT3B0aW9ucyBvcHRpb25zXzsKKyAgLy8gd2hldGhlciB0byBnZW5lcmF0ZSB0aGUgKl9BUlJBWVNJWkUgY29uc3RhbnQuCisgIGJvb2wgZ2VuZXJhdGVfYXJyYXlfc2l6ZV87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVudW1HZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0VOVU1fSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0OTg5NzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5jYwpAQCAtMCwwICsxLDUwOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCituYW1lc3BhY2UgeworCit2b2lkIFNldEVudW1WYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIHZhcmlhYmxlcywgb3B0aW9ucyk7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlZmF1bHRfdmFsdWUgPSBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2VudW0oKTsKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBDbGFzc05hbWUoZGVzY3JpcHRvci0+ZW51bV90eXBlKCksIHRydWUpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IEludDMyVG9TdHJpbmcoZGVmYXVsdF92YWx1ZS0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6CitFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRFbnVtVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfLCBvcHRpb25zKTsKK30KKworRW51bUZpZWxkR2VuZXJhdG9yOjp+RW51bUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiaW50ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkdHlwZSQgJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoJHR5cGUkIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCAkdHlwZSQgJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiBzdGF0aWNfY2FzdDwgJHR5cGUkID4oJG5hbWUkXyk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBhc3NlcnQoJHR5cGUkX0lzVmFsaWQodmFsdWUpKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInNldF8kbmFtZSQoZnJvbS4kbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInN0ZDo6c3dhcCgkbmFtZSRfLCBvdGhlci0+JG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgdmFsdWU7XG4iCisgICAgIkRPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8XG4iCisgICAgIiAgICAgICAgIGludCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oXG4iCisgICAgIiAgICAgICBpbnB1dCwgJnZhbHVlKSkpO1xuIik7CisgIGlmIChIYXNQcmVzZXJ2aW5nVW5rbm93bkVudW1TZW1hbnRpY3MoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNldF8kbmFtZSQoc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KHZhbHVlKSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICgkdHlwZSRfSXNWYWxpZCh2YWx1ZSkpIHtcbiIKKyAgICAgICIgIHNldF8kbmFtZSQoc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KHZhbHVlKSk7XG4iKTsKKyAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICAgIiAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoJG51bWJlciQsIHZhbHVlKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICIgIHVua25vd25fZmllbGRzX3N0cmVhbS5Xcml0ZVZhcmludDMyKHRhZyk7XG4iCisgICAgICAgICIgIHVua25vd25fZmllbGRzX3N0cmVhbS5Xcml0ZVZhcmludDMyKHZhbHVlKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW0oXG4iCisgICAgIiAgJG51bWJlciQsIHRoaXMtPiRuYW1lJCgpLCBvdXRwdXQpO1xuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheShcbiIKKyAgICAiICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKCksIHRhcmdldCk7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT4kbmFtZSQoKSk7XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IEVudW1GaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBvcHRpb25zKSB7CisgIFNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6fkVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkICR0eXBlJCAkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICIgICAgcmV0dXJuIHN0YXRpY19jYXN0PCAkdHlwZSQgPigkb25lb2ZfcHJlZml4JCRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KCRkZWZhdWx0JCk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBhc3NlcnQoJHR5cGUkX0lzVmFsaWQodmFsdWUpKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG9uJ3QgcHJpbnQgYW55IHN3YXBwaW5nIGNvZGUuIFN3YXBwaW5nIHRoZSB1bmlvbiB3aWxsIHN3YXAgdGhpcyBmaWVsZC4KK30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLT4kbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldEVudW1WYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18sIG9wdGlvbnMpOworfQorCitSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6flJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDxpbnQ+ICRuYW1lJF87XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkKKyAgICAgICYmIEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIm11dGFibGUgaW50IF8kbmFtZSRfY2FjaGVkX2J5dGVfc2l6ZV87XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHR5cGUkICRuYW1lJChpbnQgaW5kZXgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgYWRkXyRuYW1lJCgkdHlwZSQgdmFsdWUpJGRlcHJlY2F0aW9uJDtcbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8aW50PiYgJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8aW50PiogbXV0YWJsZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkICR0eXBlJCAkY2xhc3NuYW1lJDo6JG5hbWUkKGludCBpbmRleCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuIHN0YXRpY19jYXN0PCAkdHlwZSQgPigkbmFtZSRfLkdldChpbmRleCkpO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBhc3NlcnQoJHR5cGUkX0lzVmFsaWQodmFsdWUpKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICAkbmFtZSRfLlNldChpbmRleCwgdmFsdWUpO1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6YWRkXyRuYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBhc3NlcnQoJHR5cGUkX0lzVmFsaWQodmFsdWUpKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICAkbmFtZSRfLkFkZCh2YWx1ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPGludD4mXG4iCisgICAgIiRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPGludD4qXG4iCisgICAgIiRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAmJG5hbWUkXztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uQ2xlYXIoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uTWVyZ2VGcm9tKGZyb20uJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIE5vdCBuZWVkZWQgZm9yIHJlcGVhdGVkIGZpZWxkcy4KK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIERvbid0IHVzZSBSZWFkUmVwZWF0ZWRQcmltaXRpdmUgaGVyZSBzbyB0aGF0IHRoZSBlbnVtIGNhbiBiZSB2YWxpZGF0ZWQuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCB2YWx1ZTtcbiIKKyAgICAiRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxcbiIKKyAgICAiICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPihcbiIKKyAgICAiICAgICAgIGlucHV0LCAmdmFsdWUpKSk7XG4iKTsKKyAgaWYgKEhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiYWRkXyRuYW1lJChzdGF0aWNfY2FzdDwgJHR5cGUkID4odmFsdWUpKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCR0eXBlJF9Jc1ZhbGlkKHZhbHVlKSkge1xuIgorICAgICAgIiAgYWRkXyRuYW1lJChzdGF0aWNfY2FzdDwgJHR5cGUkID4odmFsdWUpKTtcbiIpOworICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgICAiICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgkbnVtYmVyJCwgdmFsdWUpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICAgIiAgdW5rbm93bl9maWVsZHNfc3RyZWFtLldyaXRlVmFyaW50MzIodGFnKTtcbiIKKyAgICAgICAgIiAgdW5rbm93bl9maWVsZHNfc3RyZWFtLldyaXRlVmFyaW50MzIodmFsdWUpO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoIWRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICAgIC8vIFRoaXMgcGF0aCBpcyByYXJlbHkgZXhlY3V0ZWQsIHNvIHdlIHVzZSBhIG5vbi1pbmxpbmVkIGltcGxlbWVudGF0aW9uLgorICAgIGlmIChIYXNQcmVzZXJ2aW5nVW5rbm93bkVudW1TZW1hbnRpY3MoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OiIKKyAgICAgICAgICAgICAgICAgICAgIldpcmVGb3JtYXRMaXRlOjpSZWFkUGFja2VkRW51bVByZXNlcnZlVW5rbm93bnMoXG4iCisgICAgICAgICIgICAgICAgaW5wdXQsXG4iCisgICAgICAgICIgICAgICAgJG51bWJlciQsXG4iCisgICAgICAgICIgICAgICAgTlVMTCxcbiIKKyAgICAgICAgIiAgICAgICBOVUxMLFxuIgorICAgICAgICAiICAgICAgIHRoaXMtPm11dGFibGVfJG5hbWUkKCkpKSk7XG4iKTsKKyAgICB9IGVsc2UgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIkRPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UmVhZFBhY2tlZEVudW1QcmVzZXJ2ZVVua25vd25zKFxuIgorICAgICAgICAiICAgICAgIGlucHV0LFxuIgorICAgICAgICAiICAgICAgICRudW1iZXIkLFxuIgorICAgICAgICAiICAgICAgICR0eXBlJF9Jc1ZhbGlkLFxuIgorICAgICAgICAiICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSxcbiIKKyAgICAgICAgIiAgICAgICB0aGlzLT5tdXRhYmxlXyRuYW1lJCgpKSkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OiIKKyAgICAgICAgICAgICAgICAgICAgICJXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZEVudW1QcmVzZXJ2ZVVua25vd25zKFxuIgorICAgICAgICAiICAgICAgIGlucHV0LFxuIgorICAgICAgICAiICAgICAgICRudW1iZXIkLFxuIgorICAgICAgICAiICAgICAgICR0eXBlJF9Jc1ZhbGlkLFxuIgorICAgICAgICAiICAgICAgICZ1bmtub3duX2ZpZWxkc19zdHJlYW0sXG4iCisgICAgICAgICIgICAgICAgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpKTtcbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIGxlbmd0aDtcbiIKKyAgICAgICJET18oaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSk7XG4iCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSAiCisgICAgICAgICAgImlucHV0LT5QdXNoTGltaXQobGVuZ3RoKTtcbiIKKyAgICAgICJ3aGlsZSAoaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIgorICAgICAgIiAgaW50IHZhbHVlO1xuIgorICAgICAgIiAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxcbiIKKyAgICAgICIgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KFxuIgorICAgICAgIiAgICAgICBpbnB1dCwgJnZhbHVlKSkpO1xuIik7CisgICAgaWYgKEhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGFkZF8kbmFtZSQoc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KHZhbHVlKSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGlmICgkdHlwZSRfSXNWYWxpZCh2YWx1ZSkpIHtcbiIKKyAgICAgICIgICAgYWRkXyRuYW1lJChzdGF0aWNfY2FzdDwgJHR5cGUkID4odmFsdWUpKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iKTsKKyAgICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgkbnVtYmVyJCwgdmFsdWUpO1xuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICAgIHVua25vd25fZmllbGRzX3N0cmVhbS5Xcml0ZVZhcmludDMyKHRhZyk7XG4iCisgICAgICAgICIgICAgdW5rbm93bl9maWVsZHNfc3RyZWFtLldyaXRlVmFyaW50MzIodmFsdWUpO1xuIik7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn1cbiIKKyAgICAgICJpbnB1dC0+UG9wTGltaXQobGltaXQpO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIC8vIFdyaXRlIHRoZSB0YWcgYW5kIHRoZSBzaXplLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMtPiRuYW1lJF9zaXplKCkgPiAwKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoXG4iCisgICAgICAiICAgICRudW1iZXIkLFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCxcbiIKKyAgICAgICIgICAgb3V0cHV0KTtcbiIKKyAgICAgICIgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihfJG5hbWUkX2NhY2hlZF9ieXRlX3NpemVfKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+JG5hbWUkX3NpemUoKTsgaSsrKSB7XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bU5vVGFnKFxuIgorICAgICAgIiAgICB0aGlzLT4kbmFtZSQoaSksIG91dHB1dCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bShcbiIKKyAgICAgICIgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJChpKSwgb3V0cHV0KTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICAvLyBXcml0ZSB0aGUgdGFnIGFuZCB0aGUgc2l6ZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICh0aGlzLT4kbmFtZSRfc2l6ZSgpID4gMCkge1xuIgorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlVGFnVG9BcnJheShcbiIKKyAgICAgICIgICAgJG51bWJlciQsXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELFxuIgorICAgICAgIiAgICB0YXJnZXQpO1xuIgorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJUb0FycmF5KCIKKyAgICAgICIgICAgXyRuYW1lJF9jYWNoZWRfYnl0ZV9zaXplXywgdGFyZ2V0KTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+JG5hbWUkX3NpemUoKTsgaSsrKSB7XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bU5vVGFnVG9BcnJheShcbiIKKyAgICAgICIgICAgdGhpcy0+JG5hbWUkKGkpLCB0YXJnZXQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KFxuIgorICAgICAgIiAgICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKGkpLCB0YXJnZXQpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAie1xuIgorICAgICIgIGludCBkYXRhX3NpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+JG5hbWUkX3NpemUoKTsgaSsrKSB7XG4iCisgICAgICAiICBkYXRhX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKFxuIgorICAgICAgIiAgICB0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICAgIn1cbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoZGF0YV9zaXplID4gMCkge1xuIgorICAgICAgIiAgdG90YWxfc2l6ZSArPSAkdGFnX3NpemUkICtcbiIKKyAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZShkYXRhX3NpemUpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpO1xuIgorICAgICAgIl8kbmFtZSRfY2FjaGVkX2J5dGVfc2l6ZV8gPSBkYXRhX3NpemU7XG4iCisgICAgICAiR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7XG4iCisgICAgICAidG90YWxfc2l6ZSArPSBkYXRhX3NpemU7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRvdGFsX3NpemUgKz0gJHRhZ19zaXplJCAqIHRoaXMtPiRuYW1lJF9zaXplKCkgKyBkYXRhX3NpemU7XG4iKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViMWQwMWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5oCkBAIC0wLDAgKzEsMTI1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9FTlVNX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0VOVU1fRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworY2xhc3MgRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEVudW1GaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgfkVudW1GaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFbnVtRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgRW51bU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRW51bUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5FbnVtT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgflJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtV2l0aFBhY2tpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRU5VTV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2OGNhNDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmNjCkBAIC0wLDAgKzEsMjEwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uaD4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK25hbWVzcGFjZSB7CisKKy8vIFJldHVybnMgdGhlIGZ1bGx5LXF1YWxpZmllZCBjbGFzcyBuYW1lIG9mIHRoZSBtZXNzYWdlIHRoYXQgdGhpcyBmaWVsZAorLy8gZXh0ZW5kcy4gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIHRoZSBHb29nbGUtaW50ZXJuYWwgY29kZSB0byBoYW5kbGUgc29tZQorLy8gbGVnYWN5IGNhc2VzLgorc3RyaW5nIEV4dGVuZGVlQ2xhc3NOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBjb25zdCBEZXNjcmlwdG9yKiBleHRlbmRlZSA9IGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpOworICByZXR1cm4gQ2xhc3NOYW1lKGV4dGVuZGVlLCB0cnVlKTsKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorCitFeHRlbnNpb25HZW5lcmF0b3I6OkV4dGVuc2lvbkdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLAorICAgIG9wdGlvbnNfKG9wdGlvbnMpIHsKKyAgLy8gQ29uc3RydWN0IHR5cGVfdHJhaXRzXy4KKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19yZXBlYXRlZCgpKSB7CisgICAgdHlwZV90cmFpdHNfID0gIlJlcGVhdGVkIjsKKyAgfQorCisgIHN3aXRjaCAoZGVzY3JpcHRvcl8tPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgdHlwZV90cmFpdHNfLmFwcGVuZCgiRW51bVR5cGVUcmFpdHM8ICIpOworICAgICAgdHlwZV90cmFpdHNfLmFwcGVuZChDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpLCB0cnVlKSk7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKCIsICIpOworICAgICAgdHlwZV90cmFpdHNfLmFwcGVuZChDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpLCB0cnVlKSk7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKCJfSXNWYWxpZD4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoIlN0cmluZ1R5cGVUcmFpdHMiKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKCJNZXNzYWdlVHlwZVRyYWl0czwgIik7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKENsYXNzTmFtZShkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCksIHRydWUpKTsKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoIiA+Iik7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgdHlwZV90cmFpdHNfLmFwcGVuZCgiUHJpbWl0aXZlVHlwZVRyYWl0czwgIik7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKFByaW1pdGl2ZVR5cGVOYW1lKGRlc2NyaXB0b3JfLT5jcHBfdHlwZSgpKSk7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKCIgPiIpOworICAgICAgYnJlYWs7CisgIH0KK30KKworRXh0ZW5zaW9uR2VuZXJhdG9yOjp+RXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKwordm9pZCBFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJleHRlbmRlZSIgICAgIF0gPSBFeHRlbmRlZUNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgIHZhcnNbIm51bWJlciIgICAgICAgXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm51bWJlcigpKTsKKyAgdmFyc1sidHlwZV90cmFpdHMiICBdID0gdHlwZV90cmFpdHNfOworICB2YXJzWyJuYW1lIiAgICAgICAgIF0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICB2YXJzWyJmaWVsZF90eXBlIiAgIF0gPSBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludD4oZGVzY3JpcHRvcl8tPnR5cGUoKSkpOworICB2YXJzWyJwYWNrZWQiICAgICAgIF0gPSBkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgdmFyc1siY29uc3RhbnRfbmFtZSJdID0gRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcl8pOworCisgIC8vIElmIHRoaXMgaXMgYSBjbGFzcyBtZW1iZXIsIGl0IG5lZWRzIHRvIGJlIGRlY2xhcmVkICJzdGF0aWMiLiAgT3RoZXJ3aXNlLAorICAvLyBpdCBuZWVkcyB0byBiZSAiZXh0ZXJuIi4gIEluIHRoZSBsYXR0ZXIgY2FzZSwgaXQgYWxzbyBuZWVkcyB0aGUgRExMCisgIC8vIGV4cG9ydC9pbXBvcnQgc3BlY2lmaWVyLgorICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpIHsKKyAgICB2YXJzWyJxdWFsaWZpZXIiXSA9ICJleHRlcm4iOworICAgIGlmICghb3B0aW9uc18uZGxsZXhwb3J0X2RlY2wuZW1wdHkoKSkgeworICAgICAgdmFyc1sicXVhbGlmaWVyIl0gPSBvcHRpb25zXy5kbGxleHBvcnRfZGVjbCArICIgIiArIHZhcnNbInF1YWxpZmllciJdOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJxdWFsaWZpZXIiXSA9ICJzdGF0aWMiOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAic3RhdGljIGNvbnN0IGludCAkY29uc3RhbnRfbmFtZSQgPSAkbnVtYmVyJDtcbiIKKyAgICAiJHF1YWxpZmllciQgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgJGV4dGVuZGVlJCxcbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OiR0eXBlX3RyYWl0cyQsICRmaWVsZF90eXBlJCwgJHBhY2tlZCQgPlxuIgorICAgICIgICRuYW1lJDtcbiIKKyAgICApOworCit9CisKK3ZvaWQgRXh0ZW5zaW9uR2VuZXJhdG9yOjpHZW5lcmF0ZURlZmluaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gSWYgdGhpcyBpcyBhIGNsYXNzIG1lbWJlciwgaXQgbmVlZHMgdG8gYmUgZGVjbGFyZWQgaW4gaXRzIGNsYXNzIHNjb3BlLgorICBzdHJpbmcgc2NvcGUgPSAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpID8gIiIgOgorICAgIENsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCksIGZhbHNlKSArICI6OiI7CisgIHN0cmluZyBuYW1lID0gc2NvcGUgKyBkZXNjcmlwdG9yXy0+bmFtZSgpOworCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siZXh0ZW5kZWUiICAgICBdID0gRXh0ZW5kZWVDbGFzc05hbWUoZGVzY3JpcHRvcl8pOworICB2YXJzWyJ0eXBlX3RyYWl0cyIgIF0gPSB0eXBlX3RyYWl0c187CisgIHZhcnNbIm5hbWUiICAgICAgICAgXSA9IG5hbWU7CisgIHZhcnNbImNvbnN0YW50X25hbWUiXSA9IEZpZWxkQ29uc3RhbnROYW1lKGRlc2NyaXB0b3JfKTsKKyAgdmFyc1siZGVmYXVsdCIgICAgICBdID0gRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3JfKTsKKyAgdmFyc1siZmllbGRfdHlwZSIgICBdID0gU2ltcGxlSXRvYShzdGF0aWNfY2FzdDxpbnQ+KGRlc2NyaXB0b3JfLT50eXBlKCkpKTsKKyAgdmFyc1sicGFja2VkIiAgICAgICBdID0gZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgIHZhcnNbInNjb3BlIiAgICAgICAgXSA9IHNjb3BlOworCisgIGlmIChkZXNjcmlwdG9yXy0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgLy8gV2UgbmVlZCB0byBkZWNsYXJlIGEgZ2xvYmFsIHN0cmluZyB3aGljaCB3aWxsIGNvbnRhaW4gdGhlIGRlZmF1bHQgdmFsdWUuCisgICAgLy8gV2UgY2Fubm90IGRlY2xhcmUgaXQgYXQgY2xhc3Mgc2NvcGUgYmVjYXVzZSB0aGF0IHdvdWxkIHJlcXVpcmUgZXhwb3NpbmcKKyAgICAvLyBpdCBpbiB0aGUgaGVhZGVyIHdoaWNoIHdvdWxkIGJlIGFubm95aW5nIGZvciBvdGhlciByZWFzb25zLiAgU28gd2UKKyAgICAvLyByZXBsYWNlIDo6IHdpdGggXyBpbiB0aGUgbmFtZSBhbmQgZGVjbGFyZSBpdCBhcyBhIGdsb2JhbC4KKyAgICBzdHJpbmcgZ2xvYmFsX25hbWUgPSBTdHJpbmdSZXBsYWNlKG5hbWUsICI6OiIsICJfIiwgdHJ1ZSk7CisgICAgdmFyc1siZ2xvYmFsX25hbWUiXSA9IGdsb2JhbF9uYW1lOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiY29uc3QgOjpzdGQ6OnN0cmluZyAkZ2xvYmFsX25hbWUkX2RlZmF1bHQoJGRlZmF1bHQkKTtcbiIpOworCisgICAgLy8gVXBkYXRlIHRoZSBkZWZhdWx0IHRvIHJlZmVyIHRvIHRoZSBzdHJpbmcgZ2xvYmFsLgorICAgIHZhcnNbImRlZmF1bHQiXSA9IGdsb2JhbF9uYW1lICsgIl9kZWZhdWx0IjsKKyAgfQorCisgIC8vIExpa2V3aXNlLCBjbGFzcyBtZW1iZXJzIG5lZWQgdG8gZGVjbGFyZSB0aGUgZmllbGQgY29uc3RhbnQgdmFyaWFibGUuCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCkgIT0gTlVMTCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiI2lmbmRlZiBfTVNDX1ZFUlxuIgorICAgICAgImNvbnN0IGludCAkc2NvcGUkJGNvbnN0YW50X25hbWUkO1xuIgorICAgICAgIiNlbmRpZlxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAkZXh0ZW5kZWUkLFxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6JHR5cGVfdHJhaXRzJCwgJGZpZWxkX3R5cGUkLCAkcGFja2VkJCA+XG4iCisgICAgIiAgJG5hbWUkKCRjb25zdGFudF9uYW1lJCwgJGRlZmF1bHQkKTtcbiIpOworfQorCit2b2lkIEV4dGVuc2lvbkdlbmVyYXRvcjo6R2VuZXJhdGVSZWdpc3RyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJleHRlbmRlZSIgICBdID0gRXh0ZW5kZWVDbGFzc05hbWUoZGVzY3JpcHRvcl8pOworICB2YXJzWyJudW1iZXIiICAgICBdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+bnVtYmVyKCkpOworICB2YXJzWyJmaWVsZF90eXBlIiBdID0gU2ltcGxlSXRvYShzdGF0aWNfY2FzdDxpbnQ+KGRlc2NyaXB0b3JfLT50eXBlKCkpKTsKKyAgdmFyc1siaXNfcmVwZWF0ZWQiXSA9IGRlc2NyaXB0b3JfLT5pc19yZXBlYXRlZCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgdmFyc1siaXNfcGFja2VkIiAgXSA9IChkZXNjcmlwdG9yXy0+aXNfcmVwZWF0ZWQoKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpCisgICAgICAgICAgICAgICAgICAgICAgICA/ICJ0cnVlIiA6ICJmYWxzZSI7CisKKyAgc3dpdGNoIChkZXNjcmlwdG9yXy0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0OjpSZWdpc3RlckVudW1FeHRlbnNpb24oXG4iCisgICAgICAgICIgICYkZXh0ZW5kZWUkOjpkZWZhdWx0X2luc3RhbmNlKCksXG4iCisgICAgICAgICIgICRudW1iZXIkLCAkZmllbGRfdHlwZSQsICRpc19yZXBlYXRlZCQsICRpc19wYWNrZWQkLFxuIik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgJiR0eXBlJF9Jc1ZhbGlkKTtcbiIsCisgICAgICAgICJ0eXBlIiwgQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5lbnVtX3R5cGUoKSwgdHJ1ZSkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQ6OlJlZ2lzdGVyTWVzc2FnZUV4dGVuc2lvbihcbiIKKyAgICAgICAgIiAgJiRleHRlbmRlZSQ6OmRlZmF1bHRfaW5zdGFuY2UoKSxcbiIKKyAgICAgICAgIiAgJG51bWJlciQsICRmaWVsZF90eXBlJCwgJGlzX3JlcGVhdGVkJCwgJGlzX3BhY2tlZCQsXG4iKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICAmJHR5cGUkOjpkZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICAgInR5cGUiLCBDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLCB0cnVlKSk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvblNldDo6UmVnaXN0ZXJFeHRlbnNpb24oXG4iCisgICAgICAgICIgICYkZXh0ZW5kZWUkOjpkZWZhdWx0X2luc3RhbmNlKCksXG4iCisgICAgICAgICIgICRudW1iZXIkLCAkZmllbGRfdHlwZSQsICRpc19yZXBlYXRlZCQsICRpc19wYWNrZWQkKTtcbiIpOworICAgICAgYnJlYWs7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzFjYWYxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5oCkBAIC0wLDAgKzEsODYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0VYVEVOU0lPTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9FWFRFTlNJT05fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX29wdGlvbnMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBGaWVsZERlc2NyaXB0b3I7ICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKKy8vIEdlbmVyYXRlcyBjb2RlIGZvciBhbiBleHRlbnNpb24sIHdoaWNoIG1heSBiZSB3aXRoaW4gdGhlIHNjb3BlIG9mIHNvbWUKKy8vIG1lc3NhZ2Ugb3IgbWF5IGJlIGF0IGZpbGUgc2NvcGUuICBUaGlzIGlzIG11Y2ggc2ltcGxlciB0aGFuIEZpZWxkR2VuZXJhdG9yCisvLyBzaW5jZSBleHRlbnNpb25zIGFyZSBqdXN0IHNpbXBsZSBpZGVudGlmaWVycyB3aXRoIGludGVyZXN0aW5nIHR5cGVzLgorY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIC8vIFNlZSBnZW5lcmF0b3IuY2MgZm9yIHRoZSBtZWFuaW5nIG9mIGRsbGV4cG9ydF9kZWNsLgorICBleHBsaWNpdCBFeHRlbnNpb25HZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5FeHRlbnNpb25HZW5lcmF0b3IoKTsKKworICAvLyBIZWFkZXIgc3R1ZmYuCisgIHZvaWQgR2VuZXJhdGVEZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gU291cmNlIGZpbGUgc3R1ZmYuCisgIHZvaWQgR2VuZXJhdGVEZWZpbml0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBjb2RlIHRvIHJlZ2lzdGVyIHRoZSBleHRlbnNpb24uCisgIHZvaWQgR2VuZXJhdGVSZWdpc3RyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgc3RyaW5nIHR5cGVfdHJhaXRzXzsKKyAgT3B0aW9ucyBvcHRpb25zXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRXh0ZW5zaW9uR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzZGYxZDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuY2MKQEAgLTAsMCArMSwxOTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmg+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3ByaW1pdGl2ZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW1fZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OworCit2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0gRmllbGROYW1lKGRlc2NyaXB0b3IpOworICAoKnZhcmlhYmxlcylbImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmluZGV4KCkpOworICAoKnZhcmlhYmxlcylbIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgICgqdmFyaWFibGVzKVsiY2xhc3NuYW1lIl0gPSBDbGFzc05hbWUoRmllbGRTY29wZShkZXNjcmlwdG9yKSwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbImRlY2xhcmVkX3R5cGUiXSA9IERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKworICAvLyBub25fbnVsbF9wdHJfdG9fbmFtZSBpcyB1c2FibGUgb25seSBpZiBoYXNfJG5hbWUkIGlzIHRydWUuICBJdCB5aWVsZHMgYQorICAvLyBwb2ludGVyIHRoYXQgd2lsbCBub3QgYmUgTlVMTC4gIFN1YmNsYXNzZXMgb2YgRmllbGRHZW5lcmF0b3IgbWF5IHNldAorICAvLyAoKnZhcmlhYmxlcylbIm5vbl9udWxsX3B0cl90b19uYW1lIl0gZGlmZmVyZW50bHkuCisgICgqdmFyaWFibGVzKVsibm9uX251bGxfcHRyX3RvX25hbWUiXSA9CisgICAgICBTdHJDYXQoIiZ0aGlzLT4iLCBGaWVsZE5hbWUoZGVzY3JpcHRvciksICIoKSIpOworCisgICgqdmFyaWFibGVzKVsidGFnX3NpemUiXSA9IFNpbXBsZUl0b2EoCisgICAgV2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgZGVzY3JpcHRvci0+dHlwZSgpKSk7CisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIiBQUk9UT0JVRl9ERVBSRUNBVEVEIiA6ICIiOworCisgICgqdmFyaWFibGVzKVsiY3BwZ2V0Il0gPSAiR2V0IjsKKworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzYml0Il0gPQorICAgICAgICAic2V0X2hhc18iICsgRmllbGROYW1lKGRlc2NyaXB0b3IpICsgIigpOyI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNiaXQiXSA9CisgICAgICAgICJjbGVhcl9oYXNfIiArIEZpZWxkTmFtZShkZXNjcmlwdG9yKSArICIoKTsiOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc2JpdCJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNiaXQiXSA9ICIiOworICB9CisKKyAgLy8gQnkgZGVmYXVsdCwgZW1wdHkgc3RyaW5nLCBzbyB0aGF0IGdlbmVyaWMgY29kZSB1c2VkIGZvciBib3RoIG9uZW9mcyBhbmQKKyAgLy8gc2luZ3VsYXIgZmllbGRzIGNhbiBiZSB3cml0dGVuLgorICAoKnZhcmlhYmxlcylbIm9uZW9mX3ByZWZpeCJdID0gIiI7Cit9CisKK3ZvaWQgU2V0Q29tbW9uT25lb2ZGaWVsZFZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIGNvbnN0IHN0cmluZyBwcmVmaXggPSBkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCktPm5hbWUoKSArICJfLiI7CisgICgqdmFyaWFibGVzKVsib25lb2ZfcHJlZml4Il0gPSBwcmVmaXg7CisgICgqdmFyaWFibGVzKVsib25lb2ZfbmFtZSJdID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpLT5uYW1lKCk7CisgICgqdmFyaWFibGVzKVsibm9uX251bGxfcHRyX3RvX25hbWUiXSA9CisgICAgICBTdHJDYXQocHJlZml4LCAoKnZhcmlhYmxlcylbIm5hbWUiXSwgIl8iKTsKK30KKworRmllbGRHZW5lcmF0b3I6On5GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbVdpdGhQYWNraW5nKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFJlYWNoaW5nIGhlcmUgaW5kaWNhdGVzIGEgYnVnLiBDYXNlcyBhcmU6CisgIC8vICAgLSBUaGlzIEZpZWxkR2VuZXJhdG9yIHNob3VsZCBzdXBwb3J0IHBhY2tpbmcsIGJ1dCB0aGlzIG1ldGhvZCBzaG91bGQgYmUKKyAgLy8gICAgIG92ZXJyaWRkZW4uCisgIC8vICAgLSBUaGlzIEZpZWxkR2VuZXJhdG9yIGRvZXNuJ3Qgc3VwcG9ydCBwYWNraW5nLCBhbmQgdGhpcyBtZXRob2Qgc2hvdWxkCisgIC8vICAgICBuZXZlciBoYXZlIGJlZW4gY2FsbGVkLgorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbVdpdGhQYWNraW5nKCkgIgorICAgICAgICAgICAgIDw8ICJjYWxsZWQgb24gZmllbGQgZ2VuZXJhdG9yIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCBwYWNraW5nLiI7CisKK30KKworRmllbGRHZW5lcmF0b3JNYXA6OkZpZWxkR2VuZXJhdG9yTWFwKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLAorICAgICAgZmllbGRfZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCldKSB7CisgIC8vIENvbnN0cnVjdCBhbGwgdGhlIEZpZWxkR2VuZXJhdG9ycy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzX1tpXS5yZXNldChNYWtlR2VuZXJhdG9yKGRlc2NyaXB0b3ItPmZpZWxkKGkpLCBvcHRpb25zKSk7CisgIH0KK30KKworRmllbGRHZW5lcmF0b3IqIEZpZWxkR2VuZXJhdG9yTWFwOjpNYWtlR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoZmllbGQtPmlzX21hcCgpKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBNYXBGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgICAgIH0KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvciBoYW5kbGVzIHVua25vd24gY3R5cGVzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3IoZmllbGQsIG9wdGlvbnMpOworICAgICAgICB9CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgfQorICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvciBoYW5kbGVzIHVua25vd24gY3R5cGVzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoZmllbGQsIG9wdGlvbnMpOworICAgICAgICB9CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IEVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHJldHVybiBuZXcgTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gU3RyaW5nRmllbGRHZW5lcmF0b3IgaGFuZGxlcyB1bmtub3duIGN0eXBlcy4KKyAgICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgICAgIH0KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICAgIHJldHVybiBuZXcgRW51bUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZmllbGQsIG9wdGlvbnMpOworICAgIH0KKyAgfQorfQorCitGaWVsZEdlbmVyYXRvck1hcDo6fkZpZWxkR2VuZXJhdG9yTWFwKCkge30KKworY29uc3QgRmllbGRHZW5lcmF0b3ImIEZpZWxkR2VuZXJhdG9yTWFwOjpnZXQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBkZXNjcmlwdG9yXyk7CisgIHJldHVybiAqZmllbGRfZ2VuZXJhdG9yc19bZmllbGQtPmluZGV4KCldOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNkMmI2YjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaApAQCAtMCwwICsxLDE5OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworLy8gSGVscGVyIGZ1bmN0aW9uOiBzZXQgdmFyaWFibGVzIGluIHRoZSBtYXAgdGhhdCBhcmUgdGhlIHNhbWUgZm9yIGFsbAorLy8gZmllbGQgY29kZSBnZW5lcmF0b3JzLgorLy8gWyduYW1lJywgJ2luZGV4JywgJ251bWJlcicsICdjbGFzc25hbWUnLCAnZGVjbGFyZWRfdHlwZScsICd0YWdfc2l6ZScsCisvLyAnZGVwcmVjYXRpb24nXS4KK3ZvaWQgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworCit2b2lkIFNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7CisKK2NsYXNzIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEZpZWxkR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+RmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBHZW5lcmF0ZSBsaW5lcyBvZiBjb2RlIGRlY2xhcmluZyBtZW1iZXJzIGZpZWxkcyBvZiB0aGUgbWVzc2FnZSBjbGFzcworICAvLyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoaXMgZmllbGQuICBUaGVzZSBhcmUgcGxhY2VkIGluc2lkZSB0aGUgbWVzc2FnZQorICAvLyBjbGFzcy4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICAvLyBHZW5lcmF0ZSBzdGF0aWMgZGVmYXVsdCB2YXJpYWJsZSBmb3IgdGhpcyBmaWVsZC4gVGhlc2UgYXJlIHBsYWNlZCBpbnNpZGUKKyAgLy8gdGhlIG1lc3NhZ2UgY2xhc3MuIE1vc3QgZmllbGQgdHlwZXMgZG9uJ3QgbmVlZCB0aGlzLCBzbyB0aGUgZGVmYXVsdAorICAvLyBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU3RhdGljTWVtYmVycyhpbzo6UHJpbnRlciogLypwcmludGVyKi8pIGNvbnN0IHt9CisKKyAgLy8gR2VuZXJhdGUgcHJvdG90eXBlcyBmb3IgYWxsIG9mIHRoZSBhY2Nlc3NvciBmdW5jdGlvbnMgcmVsYXRlZCB0byB0aGlzCisgIC8vIGZpZWxkLiAgVGhlc2UgYXJlIHBsYWNlZCBpbnNpZGUgdGhlIGNsYXNzIGRlZmluaXRpb24uCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgaW5saW5lIGRlZmluaXRpb25zIG9mIGFjY2Vzc29yIGZ1bmN0aW9ucyBmb3IgdGhpcyBmaWVsZC4KKyAgLy8gVGhlc2UgYXJlIHBsYWNlZCBpbnNpZGUgdGhlIGhlYWRlciBhZnRlciBhbGwgY2xhc3MgZGVmaW5pdGlvbnMuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgaXNfaW5saW5lKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgZGVmaW5pdGlvbnMgb2YgYWNjZXNzb3JzIHRoYXQgYXJlbid0IGlubGluZWQuICBUaGVzZSBhcmUKKyAgLy8gcGxhY2VkIHNvbWV3aGVyZSBpbiB0aGUgLmNjIGZpbGUuCisgIC8vIE1vc3QgZmllbGQgdHlwZXMgZG9uJ3QgbmVlZCB0aGlzLCBzbyB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTm9uSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucygKKyAgICBpbzo6UHJpbnRlciogLypwcmludGVyKi8pIGNvbnN0IHt9CisKKyAgLy8gR2VuZXJhdGUgbGluZXMgb2YgY29kZSAoc3RhdGVtZW50cywgbm90IGRlY2xhcmF0aW9ucykgd2hpY2ggY2xlYXIgdGhlCisgIC8vIGZpZWxkLiAgVGhpcyBpcyB1c2VkIHRvIGRlZmluZSB0aGUgY2xlYXJfJG5hbWUkKCkgbWV0aG9kIGFzIHdlbGwgYXMKKyAgLy8gdGhlIENsZWFyKCkgbWV0aG9kIGZvciB0aGUgd2hvbGUgbWVzc2FnZS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgbGluZXMgb2YgY29kZSAoc3RhdGVtZW50cywgbm90IGRlY2xhcmF0aW9ucykgd2hpY2ggbWVyZ2VzIHRoZQorICAvLyBjb250ZW50cyBvZiB0aGUgZmllbGQgZnJvbSB0aGUgY3VycmVudCBtZXNzYWdlIHRvIHRoZSB0YXJnZXQgbWVzc2FnZSwKKyAgLy8gd2hpY2ggaXMgc3RvcmVkIGluIHRoZSBnZW5lcmF0ZWQgY29kZSB2YXJpYWJsZSAiZnJvbSIuCisgIC8vIFRoaXMgaXMgdXNlZCB0byBmaWxsIGluIHRoZSBNZXJnZUZyb20gbWV0aG9kIGZvciB0aGUgd2hvbGUgbWVzc2FnZS4KKyAgLy8gRGV0YWlscyBvZiB0aGlzIHVzYWdlIGNhbiBiZSBmb3VuZCBpbiBtZXNzYWdlLmNjIHVuZGVyIHRoZQorICAvLyBHZW5lcmF0ZU1lcmdlRnJvbSBtZXRob2QuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgbGluZXMgb2YgY29kZSAoc3RhdGVtZW50cywgbm90IGRlY2xhcmF0aW9ucykgd2hpY2ggc3dhcHMKKyAgLy8gdGhpcyBmaWVsZCBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgb2YgYW5vdGhlciBtZXNzYWdlLCB3aGljaAorICAvLyBpcyBzdG9yZWQgaW4gdGhlIGdlbmVyYXRlZCBjb2RlIHZhcmlhYmxlICJvdGhlciIuIFRoaXMgaXMgdXNlZCB0bworICAvLyBkZWZpbmUgdGhlIFN3YXAgbWV0aG9kLiBEZXRhaWxzIG9mIHVzYWdlIGNhbiBiZSBmb3VuZCBpbgorICAvLyBtZXNzYWdlLmNjIHVuZGVyIHRoZSBHZW5lcmF0ZVN3YXAgbWV0aG9kLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICAvLyBHZW5lcmF0ZSBpbml0aWFsaXphdGlvbiBjb2RlIGZvciBwcml2YXRlIG1lbWJlcnMgZGVjbGFyZWQgYnkKKyAgLy8gR2VuZXJhdGVQcml2YXRlTWVtYmVycygpLiBUaGVzZSBnbyBpbnRvIHRoZSBtZXNzYWdlIGNsYXNzJ3MgU2hhcmVkQ3RvcigpCisgIC8vIG1ldGhvZCwgaW52b2tlZCBieSBlYWNoIG9mIHRoZSBnZW5lcmF0ZWQgY29uc3RydWN0b3JzLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICAvLyBHZW5lcmF0ZSBhbnkgY29kZSB0aGF0IG5lZWRzIHRvIGdvIGluIHRoZSBjbGFzcydzIFNoYXJlZER0b3IoKSBtZXRob2QsCisgIC8vIGludm9rZWQgYnkgdGhlIGRlc3RydWN0b3IuCisgIC8vIE1vc3QgZmllbGQgdHlwZXMgZG9uJ3QgbmVlZCB0aGlzLCBzbyB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIC8qcHJpbnRlciovKSBjb25zdCB7fQorCisgIC8vIEdlbmVyYXRlIGEgbWFudWFsIGRlc3RydWN0b3IgaW52b2NhdGlvbiBmb3IgdXNlIHdoZW4gdGhlIG1lc3NhZ2UgaXMgb24gYW4KKyAgLy8gYXJlbmEuIFRoZSBjb2RlIHRoYXQgdGhpcyBtZXRob2QgZ2VuZXJhdGVzIHdpbGwgYmUgZXhlY3V0ZWQgaW5zaWRlIGEKKyAgLy8gc2hhcmVkLWZvci10aGUtd2hvbGUtbWVzc2FnZS1jbGFzcyBtZXRob2QgcmVnaXN0ZXJlZCB3aXRoIE93bkRlc3RydWN0b3IoKS4KKyAgLy8gVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIHx0cnVlfCBpZiBpdCBnZW5lcmF0ZWQgYW55IGNvZGUgdGhhdCByZXF1aXJlcyBhCisgIC8vIGNhbGw7IHRoaXMgYWxsb3dzIHRoZSBtZXNzYWdlIGdlbmVyYXRvciB0byBlbGltaW5hdGUgdGhlIE93bkRlc3RydWN0b3IoKQorICAvLyByZWdpc3RyYXRpb24gaWYgbm8gZmllbGRzIHJlcXVpcmUgaXQuCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZUFyZW5hRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBHZW5lcmF0ZSBjb2RlIHRoYXQgYWxsb2NhdGVzIHRoZSBmaWVsZHMncyBkZWZhdWx0IGluc3RhbmNlLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VBbGxvY2F0b3IoaW86OlByaW50ZXIqIC8qcHJpbnRlciovKQorICAgICAgY29uc3Qge30KKworICAvLyBHZW5lcmF0ZSBjb2RlIHRoYXQgc2hvdWxkIGJlIHJ1biB3aGVuIFNodXRkb3duUHJvdG9idWZMaWJyYXJ5KCkgaXMgY2FsbGVkLAorICAvLyB0byBkZWxldGUgYWxsIGR5bmFtaWNhbGx5LWFsbG9jYXRlZCBvYmplY3RzLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTaHV0ZG93bkNvZGUoaW86OlByaW50ZXIqIC8qcHJpbnRlciovKSBjb25zdCB7fQorCisgIC8vIEdlbmVyYXRlIGxpbmVzIHRvIGRlY29kZSB0aGlzIGZpZWxkLCB3aGljaCB3aWxsIGJlIHBsYWNlZCBpbnNpZGUgdGhlCisgIC8vIG1lc3NhZ2UncyBNZXJnZUZyb21Db2RlZFN0cmVhbSgpIG1ldGhvZC4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICAvLyBHZW5lcmF0ZSBsaW5lcyB0byBkZWNvZGUgdGhpcyBmaWVsZCBmcm9tIGEgcGFja2VkIHZhbHVlLCB3aGljaCB3aWxsIGJlCisgIC8vIHBsYWNlZCBpbnNpZGUgdGhlIG1lc3NhZ2UncyBNZXJnZUZyb21Db2RlZFN0cmVhbSgpIG1ldGhvZC4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhpbzo6UHJpbnRlciogcHJpbnRlcikKKyAgICAgIGNvbnN0OworCisgIC8vIEdlbmVyYXRlIGxpbmVzIHRvIHNlcmlhbGl6ZSB0aGlzIGZpZWxkLCB3aGljaCBhcmUgcGxhY2VkIHdpdGhpbiB0aGUKKyAgLy8gbWVzc2FnZSdzIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygpIG1ldGhvZC4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgbGluZXMgdG8gc2VyaWFsaXplIHRoaXMgZmllbGQgZGlyZWN0bHkgdG8gdGhlIGFycmF5ICJ0YXJnZXQiLAorICAvLyB3aGljaCBhcmUgcGxhY2VkIHdpdGhpbiB0aGUgbWVzc2FnZSdzIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoKQorICAvLyBtZXRob2QuIFRoaXMgbXVzdCBhbHNvIGFkdmFuY2UgInRhcmdldCIgcGFzdCB0aGUgd3JpdHRlbiBieXRlcy4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgbGluZXMgdG8gY29tcHV0ZSB0aGUgc2VyaWFsaXplZCBzaXplIG9mIHRoaXMgZmllbGQsIHdoaWNoCisgIC8vIGFyZSBwbGFjZWQgaW4gdGhlIG1lc3NhZ2UncyBCeXRlU2l6ZSgpIG1ldGhvZC4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWVsZEdlbmVyYXRvcik7Cit9OworCisvLyBDb252ZW5pZW5jZSBjbGFzcyB3aGljaCBjb25zdHJ1Y3RzIEZpZWxkR2VuZXJhdG9ycyBmb3IgYSBEZXNjcmlwdG9yLgorY2xhc3MgRmllbGRHZW5lcmF0b3JNYXAgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRmllbGRHZW5lcmF0b3JNYXAoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5GaWVsZEdlbmVyYXRvck1hcCgpOworCisgIGNvbnN0IEZpZWxkR2VuZXJhdG9yJiBnZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3I+ID4gZmllbGRfZ2VuZXJhdG9yc187CisKKyAgc3RhdGljIEZpZWxkR2VuZXJhdG9yKiBNYWtlR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3JNYXApOworfTsKKworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWxlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5OGM3ZDkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5jYwpAQCAtMCwwICsxLDcxMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5oPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzZXQ+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ZpbGVHZW5lcmF0b3I6OkZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgICAgOiBmaWxlXyhmaWxlKSwKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZUdlbmVyYXRvcj5bZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCldKSwKKyAgICAgIGVudW1fZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RW51bUdlbmVyYXRvcj5bZmlsZS0+ZW51bV90eXBlX2NvdW50KCldKSwKKyAgICAgIHNlcnZpY2VfZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8U2VydmljZUdlbmVyYXRvcj5bZmlsZS0+c2VydmljZV9jb3VudCgpXSksCisgICAgICBleHRlbnNpb25fZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RXh0ZW5zaW9uR2VuZXJhdG9yPltmaWxlLT5leHRlbnNpb25fY291bnQoKV0pLAorICAgICAgb3B0aW9uc18ob3B0aW9ucykgeworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICBuZXcgTWVzc2FnZUdlbmVyYXRvcihmaWxlLT5tZXNzYWdlX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICBuZXcgRW51bUdlbmVyYXRvcihmaWxlLT5lbnVtX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLnJlc2V0KAorICAgICAgbmV3IFNlcnZpY2VHZW5lcmF0b3IoZmlsZS0+c2VydmljZShpKSwgb3B0aW9ucykpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLnJlc2V0KAorICAgICAgbmV3IEV4dGVuc2lvbkdlbmVyYXRvcihmaWxlLT5leHRlbnNpb24oaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIFNwbGl0U3RyaW5nVXNpbmcoZmlsZV8tPnBhY2thZ2UoKSwgIi4iLCAmcGFja2FnZV9wYXJ0c18pOworfQorCitGaWxlR2VuZXJhdG9yOjp+RmlsZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVIZWFkZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgc3RyaW5nIGZpbGVuYW1lX2lkZW50aWZpZXIgPSBGaWxlbmFtZUlkZW50aWZpZXIoZmlsZV8tPm5hbWUoKSk7CisKKyAgLy8gR2VuZXJhdGUgdG9wIG9mIGhlYWRlci4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgIi8vIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICJcbiIKKyAgICAiI2lmbmRlZiBQUk9UT0JVRl8kZmlsZW5hbWVfaWRlbnRpZmllciRfX0lOQ0xVREVEXG4iCisgICAgIiNkZWZpbmUgUFJPVE9CVUZfJGZpbGVuYW1lX2lkZW50aWZpZXIkX19JTkNMVURFRFxuIgorICAgICJcbiIKKyAgICAiI2luY2x1ZGUgPHN0cmluZz5cbiIKKyAgICAiXG4iLAorICAgICJmaWxlbmFtZSIsIGZpbGVfLT5uYW1lKCksCisgICAgImZpbGVuYW1lX2lkZW50aWZpZXIiLCBmaWxlbmFtZV9pZGVudGlmaWVyKTsKKworCisgIHByaW50ZXItPlByaW50KAorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPlxuIgorICAgICJcbiIpOworCisgIC8vIFZlcmlmeSB0aGUgcHJvdG9idWYgbGlicmFyeSBoZWFkZXIgdmVyc2lvbiBpcyBjb21wYXRpYmxlIHdpdGggdGhlIHByb3RvYworICAvLyB2ZXJzaW9uIGJlZm9yZSBnb2luZyBhbnkgZnVydGhlci4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8ICRtaW5faGVhZGVyX3ZlcnNpb24kXG4iCisgICAgIiNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzXG4iCisgICAgIiNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlIHVwZGF0ZVxuIgorICAgICIjZXJyb3IgeW91ciBoZWFkZXJzLlxuIgorICAgICIjZW5kaWZcbiIKKyAgICAiI2lmICRwcm90b2NfdmVyc2lvbiQgPCBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OXG4iCisgICAgIiNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpc1xuIgorICAgICIjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZVxuIgorICAgICIjZXJyb3IgcmVnZW5lcmF0ZSB0aGlzIGZpbGUgd2l0aCBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jLlxuIgorICAgICIjZW5kaWZcbiIKKyAgICAiXG4iLAorICAgICJtaW5faGVhZGVyX3ZlcnNpb24iLAorICAgICAgU2ltcGxlSXRvYShwcm90b2J1Zjo6aW50ZXJuYWw6OmtNaW5IZWFkZXJWZXJzaW9uRm9yUHJvdG9jKSwKKyAgICAicHJvdG9jX3ZlcnNpb24iLCBTaW1wbGVJdG9hKEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OKSk7CisKKyAgLy8gT0ssIGl0J3Mgbm93IHNhZmUgdG8gI2luY2x1ZGUgb3RoZXIgZmlsZXMuCisgIHByaW50ZXItPlByaW50KAorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD5cbiIKKyAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+XG4iKTsKKyAgaWYgKFVzZVVua25vd25GaWVsZFNldChmaWxlXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+XG4iKTsKKyAgfQorICBpZiAoZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID4gMCkgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPlxuIik7CisgICAgfQorICB9CisgIHByaW50ZXItPlByaW50KAorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPlxuIik7CisgIGlmIChIYXNNYXBGaWVsZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcC5oPlxuIik7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGZpbGVfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2lubC5oPlxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9saXRlLmg+XG4iKTsKKyAgICB9CisgIH0KKworICBpZiAoSGFzRW51bURlZmluaXRpb25zKGZpbGVfKSkgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaD5cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmg+XG4iKTsKKyAgICB9CisgIH0KKworICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGVfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc2VydmljZS5oPlxuIik7CisgIH0KKworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGZpbGVfKSAmJiBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPlxuIik7CisgIH0KKworCisgIHNldDxzdHJpbmc+IHB1YmxpY19pbXBvcnRfbmFtZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIHB1YmxpY19pbXBvcnRfbmFtZXMuaW5zZXJ0KGZpbGVfLT5wdWJsaWNfZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3Qgc3RyaW5nJiBuYW1lID0gZmlsZV8tPmRlcGVuZGVuY3koaSktPm5hbWUoKTsKKyAgICBib29sIHB1YmxpY19pbXBvcnQgPSAocHVibGljX2ltcG9ydF9uYW1lcy5jb3VudChuYW1lKSAhPSAwKTsKKworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI2luY2x1ZGUgXCIkZGVwZW5kZW5jeSQucGIuaFwiJGl3eXUkXG4iLAorICAgICAgImRlcGVuZGVuY3kiLCBTdHJpcFByb3RvKG5hbWUpLAorICAgICAgIml3eXUiLCAocHVibGljX2ltcG9ydCkgPyAiICAvLyBJV1lVIHByYWdtYTogZXhwb3J0IiA6ICIiKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpXG4iKTsKKworCisKKyAgLy8gT3BlbiBuYW1lc3BhY2UuCisgIEdlbmVyYXRlTmFtZXNwYWNlT3BlbmVycyhwcmludGVyKTsKKworICAvLyBGb3J3YXJkLWRlY2xhcmUgdGhlIEFkZERlc2NyaXB0b3JzLCBBc3NpZ25EZXNjcmlwdG9ycywgYW5kIFNodXRkb3duRmlsZQorICAvLyBmdW5jdGlvbnMsIHNvIHRoYXQgd2UgY2FuIGRlY2xhcmUgdGhlbSB0byBiZSBmcmllbmRzIG9mIGVhY2ggY2xhc3MuCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIC0tIGRvIG5vdCBjYWxsIHRoZXNlLlxuIgorICAgICJ2b2lkICRkbGxleHBvcnRfZGVjbCQkYWRkZGVzY3JpcHRvcnNuYW1lJCgpO1xuIiwKKyAgICAiYWRkZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQWRkRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpLAorICAgICJkbGxleHBvcnRfZGVjbCIsCisgICAgb3B0aW9uc18uZGxsZXhwb3J0X2RlY2wuZW1wdHkoKSA/ICIiIDogb3B0aW9uc18uZGxsZXhwb3J0X2RlY2wgKyAiICIpOworCisgIHByaW50ZXItPlByaW50KAorICAgIC8vIE5vdGUgdGhhdCB3ZSBkb24ndCBwdXQgZGxsZXhwb3J0X2RlY2wgb24gdGhlc2UgYmVjYXVzZSB0aGV5IGFyZSBvbmx5CisgICAgLy8gY2FsbGVkIGJ5IHRoZSAucGIuY2MgZmlsZSBpbiB3aGljaCB0aGV5IGFyZSBkZWZpbmVkLgorICAgICJ2b2lkICRhc3NpZ25kZXNjcmlwdG9yc25hbWUkKCk7XG4iCisgICAgInZvaWQgJHNodXRkb3duZmlsZW5hbWUkKCk7XG4iCisgICAgIlxuIiwKKyAgICAiYXNzaWduZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQXNzaWduRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpLAorICAgICJzaHV0ZG93bmZpbGVuYW1lIiwgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShmaWxlXy0+bmFtZSgpKSk7CisKKyAgLy8gR2VuZXJhdGUgZm9yd2FyZCBkZWNsYXJhdGlvbnMgb2YgY2xhc3Nlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRm9yd2FyZERlY2xhcmF0aW9uKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgZW51bSBkZWZpbml0aW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRW51bURlZmluaXRpb25zKHByaW50ZXIpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlZmluaXRpb24ocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICAvLyBHZW5lcmF0ZSBjbGFzcyBkZWZpbml0aW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChpID4gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICBwcmludGVyLT5QcmludChrVGhpblNlcGFyYXRvcik7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVDbGFzc0RlZmluaXRpb24ocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoa1RoaWNrU2VwYXJhdG9yKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgaWYgKEhhc0dlbmVyaWNTZXJ2aWNlcyhmaWxlXykpIHsKKyAgICAvLyBHZW5lcmF0ZSBzZXJ2aWNlIGRlZmluaXRpb25zLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnNlcnZpY2VfY291bnQoKTsgaSsrKSB7CisgICAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICAgIHByaW50ZXItPlByaW50KGtUaGluU2VwYXJhdG9yKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICB9CisgICAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgLy8gRGVjbGFyZSBleHRlbnNpb24gaWRlbnRpZmllcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVjbGFyYXRpb24ocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoa1RoaWNrU2VwYXJhdG9yKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoIiNpZiAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTXG4iKTsKKyAgLy8gR2VuZXJhdGUgY2xhc3MgaW5saW5lIG1ldGhvZHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoaSA+IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KGtUaGluU2VwYXJhdG9yKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIH0KKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUlubGluZU1ldGhvZHMocHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaXNfaW5saW5lID0gKi8gdHJ1ZSk7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIiNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSU1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKVxuIik7CisKKyAgLy8gQ2xvc2UgdXAgbmFtZXNwYWNlLgorICBHZW5lcmF0ZU5hbWVzcGFjZUNsb3NlcnMocHJpbnRlcik7CisKKyAgLy8gRW1pdCBHZXRFbnVtRGVzY3JpcHRvciBzcGVjaWFsaXphdGlvbnMgaW50byBnb29nbGU6OnByb3RvYnVmIG5hbWVzcGFjZToKKyAgaWYgKEhhc0VudW1EZWZpbml0aW9ucyhmaWxlXykpIHsKKyAgICAvLyBUaGUgU1dJRyBjb25kaXRpb25hbCBpcyB0byBhdm9pZCBhIG51bGwtcG9pbnRlciBkZXJlZmVyZW5jZQorICAgIC8vIChidWcgMTk4NDk2NCkgaW4gc3dpZy0xLjMuMjEgcmVzdWx0aW5nIGZyb20gdGhlIGZvbGxvd2luZyBzeW50YXg6CisgICAgLy8gICBuYW1lc3BhY2UgWCB7IHZvaWQgWTxaOjpXPigpOyB9CisgICAgLy8gd2hpY2ggYXBwZWFycyBpbiBHZXRFbnVtRGVzY3JpcHRvcigpIHNwZWNpYWxpemF0aW9ucy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIlxuIgorICAgICAgICAiI2lmbmRlZiBTV0lHXG4iCisgICAgICAgICJuYW1lc3BhY2UgZ29vZ2xlIHtcbm5hbWVzcGFjZSBwcm90b2J1ZiB7XG4iCisgICAgICAgICJcbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMocHJpbnRlcik7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIGVudW1fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMocHJpbnRlcik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiXG4iCisgICAgICAgICJ9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWZcbn0gIC8vIG5hbWVzcGFjZSBnb29nbGVcbiIKKyAgICAgICAgIiNlbmRpZiAgLy8gU1dJR1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpXG4iCisgICAgIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiNlbmRpZiAgLy8gUFJPVE9CVUZfJGZpbGVuYW1lX2lkZW50aWZpZXIkX19JTkNMVURFRFxuIiwKKyAgICAiZmlsZW5hbWVfaWRlbnRpZmllciIsIGZpbGVuYW1lX2lkZW50aWZpZXIpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICIvLyBzb3VyY2U6ICRmaWxlbmFtZSRcbiIKKyAgICAiXG4iCisKKyAgICAvLyBUaGUgZ2VuZXJhdGVkIGNvZGUgY2FsbHMgYWNjZXNzb3JzIHRoYXQgbWlnaHQgYmUgZGVwcmVjYXRlZC4gV2UgZG9uJ3QKKyAgICAvLyB3YW50IHRoZSBjb21waWxlciB0byB3YXJuIGluIGdlbmVyYXRlZCBjb2RlLgorICAgICIjZGVmaW5lIElOVEVSTkFMX1NVUFBSRVNTX1BST1RPQlVGX0ZJRUxEX0RFUFJFQ0FUSU9OXG4iCisgICAgIiNpbmNsdWRlIFwiJGJhc2VuYW1lJC5wYi5oXCJcbiIKKyAgICAiXG4iCisgICAgIiNpbmNsdWRlIDxhbGdvcml0aG0+XG4iICAgIC8vIGZvciBzd2FwKCkKKyAgICAiXG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPlxuIgorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPlxuIgorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+XG4iLAorICAgICJmaWxlbmFtZSIsIGZpbGVfLT5uYW1lKCksCisgICAgImJhc2VuYW1lIiwgU3RyaXBQcm90byhmaWxlXy0+bmFtZSgpKSk7CisKKyAgLy8gVW5rbm93biBmaWVsZHMgaW1wbGVtZW50YXRpb24gaW4gbGl0ZSBtb2RlIHVzZXMgU3RyaW5nT3V0cHV0U3RyZWFtCisgIGlmICghVXNlVW5rbm93bkZpZWxkU2V0KGZpbGVfKSAmJiBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oPlxuIik7CisgIH0KKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+XG4iCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+XG4iCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPlxuIgorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD5cbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcylcbiIpOworCisgIEdlbmVyYXRlTmFtZXNwYWNlT3BlbmVycyhwcmludGVyKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAibmFtZXNwYWNlIHtcbiIKKyAgICAgICJcbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVzY3JpcHRvckRlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiAkbmFtZSRfZGVzY3JpcHRvcl8gPSBOVUxMO1xuIiwKKyAgICAgICAgIm5hbWUiLCBDbGFzc05hbWUoZmlsZV8tPmVudW1fdHlwZShpKSwgZmFsc2UpKTsKKyAgICB9CisKKyAgICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGVfKSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3IqICRuYW1lJF9kZXNjcmlwdG9yXyA9IE5VTEw7XG4iLAorICAgICAgICAgICJuYW1lIiwgZmlsZV8tPnNlcnZpY2UoaSktPm5hbWUoKSk7CisgICAgICB9CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAifSAgLy8gbmFtZXNwYWNlXG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIC8vIERlZmluZSBvdXIgZXh0ZXJuYWxseS12aXNpYmxlIEJ1aWxkRGVzY3JpcHRvcnMoKSBmdW5jdGlvbi4gIChGb3IgdGhlIGxpdGUKKyAgLy8gbGlicmFyeSwgYWxsIHRoaXMgZG9lcyBpcyBpbml0aWFsaXplIGRlZmF1bHQgaW5zdGFuY2VzLikKKyAgR2VuZXJhdGVCdWlsZERlc2NyaXB0b3JzKHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGVudW1zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVNZXRob2RzKHByaW50ZXIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgY2xhc3Nlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChpID09IDAgJiYgSGFzR2VuZXJhdGVkTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJcbiIKKyAgICAgICAgICAibmFtZXNwYWNlIHtcbiIKKyAgICAgICAgICAiXG4iCisgICAgICAgICAgInN0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDtcbiIKKyAgICAgICAgICAic3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkge1xuIgorICAgICAgICAgICIgIEdPT0dMRV9DSEVDSyhmYWxzZSkgPDwgX19GSUxFX18gPDwgXCI6XCIgPDwgbGluZTtcbiIKKyAgICAgICAgICAifVxuIgorICAgICAgICAgICJcbiIKKyAgICAgICAgICAifSAgLy8gbmFtZXNwYWNlXG4iCisgICAgICAgICAgIlxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIHByaW50ZXItPlByaW50KGtUaGlja1NlcGFyYXRvcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVDbGFzc01ldGhvZHMocHJpbnRlcik7CisKKyAgICBwcmludGVyLT5QcmludCgiI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSU1xuIik7CisgICAgLy8gR2VuZXJhdGUgY2xhc3MgaW5saW5lIG1ldGhvZHMuCisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVJbmxpbmVNZXRob2RzKHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlzX2lubGluZSA9ICovIGZhbHNlKTsKKyAgICBwcmludGVyLT5QcmludCgiI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlNcbiIpOworICB9CisKKyAgaWYgKEhhc0dlbmVyaWNTZXJ2aWNlcyhmaWxlXykpIHsKKyAgICAvLyBHZW5lcmF0ZSBzZXJ2aWNlcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKGkgPT0gMCkgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUltcGxlbWVudGF0aW9uKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIC8vIERlZmluZSBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlZmluaXRpb24ocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpXG4iKTsKKworICBHZW5lcmF0ZU5hbWVzcGFjZUNsb3NlcnMocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKVxuIik7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVCdWlsZERlc2NyaXB0b3JzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEFkZERlc2NyaXB0b3JzKCkgaXMgYSBmaWxlLWxldmVsIHByb2NlZHVyZSB3aGljaCBhZGRzIHRoZSBlbmNvZGVkCisgIC8vIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9yIHRoaXMgLnByb3RvIGZpbGUgdG8gdGhlIGdsb2JhbCBEZXNjcmlwdG9yUG9vbCBmb3IKKyAgLy8gZ2VuZXJhdGVkIGZpbGVzIChEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkuIEl0IGVpdGhlciBydW5zIGF0CisgIC8vIHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lIChieSBkZWZhdWx0KSBvciB3aGVuIGRlZmF1bHRfaW5zdGFuY2UoKSBpcworICAvLyBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lIChpbiBMSVRFX1JVTlRJTUUgbW9kZSB3aXRoCisgIC8vIEdPT0dMRV9QUk9UT0JVRl9OT19TVEFUSUNfSU5JVElBTElaRVIgZmxhZyBlbmFibGVkKS4gVGhpcyBwcm9jZWR1cmUgYWxzbworICAvLyBjb25zdHJ1Y3RzIGRlZmF1bHQgaW5zdGFuY2VzIGFuZCByZWdpc3RlcnMgZXh0ZW5zaW9ucy4KKyAgLy8KKyAgLy8gSXRzIHNpYmxpbmcsIEFzc2lnbkRlc2NyaXB0b3JzKCksIGFjdHVhbGx5IHB1bGxzIHRoZSBjb21waWxlZAorICAvLyBGaWxlRGVzY3JpcHRvciBmcm9tIHRoZSBEZXNjcmlwdG9yUG9vbCBhbmQgdXNlcyBpdCB0byBwb3B1bGF0ZSBhbGwgb2YKKyAgLy8gdGhlIGdsb2JhbCB2YXJpYWJsZXMgd2hpY2ggc3RvcmUgcG9pbnRlcnMgdG8gdGhlIGRlc2NyaXB0b3Igb2JqZWN0cy4KKyAgLy8gSXQgYWxzbyBjb25zdHJ1Y3RzIHRoZSByZWZsZWN0aW9uIG9iamVjdHMuICBJdCBpcyBjYWxsZWQgdGhlIGZpcnN0IHRpbWUKKyAgLy8gYW55b25lIGNhbGxzIGRlc2NyaXB0b3IoKSBvciBHZXRSZWZsZWN0aW9uKCkgb24gb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkCisgIC8vIGluIHRoZSBmaWxlLgorCisgIC8vIEluIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRSBtb2RlLCB3ZSBkb24ndCBnZW5lcmF0ZSBBc3NpZ25EZXNjcmlwdG9ycygpCisgIC8vIGFuZCB3ZSBvbmx5IHVzZSBBZGREZXNjcmlwdG9ycygpIHRvIGFsbG9jYXRlIGRlZmF1bHQgaW5zdGFuY2VzLgorICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAidm9pZCAkYXNzaWduZGVzY3JpcHRvcnNuYW1lJCgpIHtcbiIsCisgICAgICAiYXNzaWduZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQXNzaWduRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGUgZmlsZSBoYXMgZm91bmQgaXRzIHdheSBpbnRvIHRoZSBwb29sLiAgSWYgYSBkZXNjcmlwdG9yCisgICAgLy8gaXMgcmVxdWVzdGVkICpkdXJpbmcqIHN0YXRpYyBpbml0IHRoZW4gQWRkRGVzY3JpcHRvcnMoKSBtYXkgbm90IGhhdmUKKyAgICAvLyBiZWVuIGNhbGxlZCB5ZXQsIHNvIHdlIGNhbGwgaXQgbWFudWFsbHkuICBOb3RlIHRoYXQgaXQncyBmaW5lIGlmCisgICAgLy8gQWRkRGVzY3JpcHRvcnMoKSBpcyBjYWxsZWQgbXVsdGlwbGUgdGltZXMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGFkZGRlc2NyaXB0b3JzbmFtZSQoKTtcbiIsCisgICAgICAiYWRkZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQWRkRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpKTsKKworICAgIC8vIEdldCB0aGUgZmlsZSdzIGRlc2NyaXB0b3IgZnJvbSB0aGUgcG9vbC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlID1cbiIKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPkZpbmRGaWxlQnlOYW1lKFxuIgorICAgICAgIiAgICBcIiRmaWxlbmFtZSRcIik7XG4iCisgICAgICAvLyBOb3RlIHRoYXQgdGhpcyBHT09HTEVfQ0hFQ0sgaXMgbmVjZXNzYXJ5IHRvIHByZXZlbnQgYSB3YXJuaW5nIGFib3V0ICJmaWxlIgorICAgICAgLy8gYmVpbmcgdW51c2VkIHdoZW4gY29tcGlsaW5nIGFuIGVtcHR5IC5wcm90byBmaWxlLgorICAgICAgIkdPT0dMRV9DSEVDSyhmaWxlICE9IE5VTEwpO1xuIiwKKyAgICAgICJmaWxlbmFtZSIsIGZpbGVfLT5uYW1lKCkpOworCisgICAgLy8gR28gdGhyb3VnaCBhbGwgdGhlIHN0dWZmIGRlZmluZWQgaW4gdGhpcyBmaWxlIGFuZCBnZW5lcmF0ZWQgY29kZSB0bworICAgIC8vIGFzc2lnbiB0aGUgZ2xvYmFsIGRlc2NyaXB0b3IgcG9pbnRlcnMgYmFzZWQgb24gdGhlIGZpbGUgZGVzY3JpcHRvci4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcihwcmludGVyLCBpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIocHJpbnRlciwgaSk7CisgICAgfQorICAgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZV8pKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcihwcmludGVyLCBpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8vIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOiAgVGhlIGZpcnN0IHRpbWUgaXQgaXMgY2FsbGVkLCBjYWxscworICAgIC8vIEFzc2lnbkRlc2NyaXB0b3JzKCkuICBBbGwgbGF0ZXIgdGltZXMsIHdhaXRzIGZvciB0aGUgZmlyc3QgY2FsbCB0bworICAgIC8vIGNvbXBsZXRlIGFuZCB0aGVuIHJldHVybnMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAibmFtZXNwYWNlIHtcbiIKKyAgICAgICJcbiIKKyAgICAgICJHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTtcbiIKKyAgICAgICJpbmxpbmUgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXyxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICYkYXNzaWduZGVzY3JpcHRvcnNuYW1lJCk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJhc3NpZ25kZXNjcmlwdG9yc25hbWUiLCBHbG9iYWxBc3NpZ25EZXNjcmlwdG9yc05hbWUoZmlsZV8tPm5hbWUoKSkpOworCisgICAgLy8gcHJvdG9idWZfUmVnaXN0ZXJUeXBlcygpOiAgQ2FsbHMKKyAgICAvLyBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZFR5cGUoKSBmb3IgZWFjaCBtZXNzYWdlIHR5cGUuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7XG4iCisgICAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVUeXBlUmVnaXN0cmF0aW9ucyhwcmludGVyKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgIn0gIC8vIG5hbWVzcGFjZVxuIik7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFNodXRkb3duRmlsZSgpOiAgRGVsZXRlcyBkZXNjcmlwdG9ycywgZGVmYXVsdCBpbnN0YW5jZXMsIGV0Yy4gb24gc2h1dGRvd24uCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAidm9pZCAkc2h1dGRvd25maWxlbmFtZSQoKSB7XG4iLAorICAgICJzaHV0ZG93bmZpbGVuYW1lIiwgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShmaWxlXy0+bmFtZSgpKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVNodXRkb3duQ29kZShwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cblxuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBOb3cgZ2VuZXJhdGUgdGhlIEFkZERlc2NyaXB0b3JzKCkgZnVuY3Rpb24uCisgIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICBmaWxlXywgcHJpbnRlciwKKyAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgLy8gTm90ZSB0aGF0IHdlIGRvbid0IG5lZWQgYW55IHNwZWNpYWwgc3luY2hyb25pemF0aW9uIGluIHRoZSBmb2xsb3dpbmcgY29kZQorICAgIC8vIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGF0IHN0YXRpYyBpbml0IHRpbWUgYmVmb3JlIGFueSB0aHJlYWRzIGV4aXN0LgorICAgICJ2b2lkICRhZGRkZXNjcmlwdG9yc25hbWUkKCkge1xuIgorICAgICIgIHN0YXRpYyBib29sIGFscmVhZHlfaGVyZSA9IGZhbHNlO1xuIgorICAgICIgIGlmIChhbHJlYWR5X2hlcmUpIHJldHVybjtcbiIKKyAgICAiICBhbHJlYWR5X2hlcmUgPSB0cnVlO1xuIgorICAgICIgIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTjtcbiIKKyAgICAiXG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgInZvaWQgJGFkZGRlc2NyaXB0b3JzbmFtZSRfaW1wbCgpIHtcbiIKKyAgICAiICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047XG4iCisgICAgIlxuIiwKKyAgICAvLyBWYXJzLgorICAgICJhZGRkZXNjcmlwdG9yc25hbWUiLCBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZmlsZV8tPm5hbWUoKSkpOworCisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIENhbGwgdGhlIEFkZERlc2NyaXB0b3JzKCkgbWV0aG9kcyBmb3IgYWxsIG9mIG91ciBkZXBlbmRlbmNpZXMsIHRvIG1ha2UKKyAgLy8gc3VyZSB0aGV5IGdldCBhZGRlZCBmaXJzdC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVwZW5kZW5jeSA9IGZpbGVfLT5kZXBlbmRlbmN5KGkpOworICAgIC8vIFByaW50IHRoZSBuYW1lc3BhY2UgcHJlZml4IGZvciB0aGUgZGVwZW5kZW5jeS4KKyAgICBzdHJpbmcgYWRkX2Rlc2NfbmFtZSA9IFF1YWxpZmllZEZpbGVMZXZlbFN5bWJvbCgKKyAgICAgICAgZGVwZW5kZW5jeS0+cGFja2FnZSgpLCBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZGVwZW5kZW5jeS0+bmFtZSgpKSk7CisgICAgLy8gQ2FsbCBpdHMgQWRkRGVzY3JpcHRvcnMgZnVuY3Rpb24uCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJG5hbWUkKCk7XG4iLAorICAgICAgIm5hbWUiLCBhZGRfZGVzY19uYW1lKTsKKyAgfQorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAvLyBFbWJlZCB0aGUgZGVzY3JpcHRvci4gIFdlIHNpbXBseSBzZXJpYWxpemUgdGhlIGVudGlyZSBGaWxlRGVzY3JpcHRvclByb3RvCisgICAgLy8gYW5kIGVtYmVkIGl0IGFzIGEgc3RyaW5nIGxpdGVyYWwsIHdoaWNoIGlzIHBhcnNlZCBhbmQgYnVpbHQgaW50byByZWFsCisgICAgLy8gZGVzY3JpcHRvcnMgYXQgaW5pdGlhbGl6YXRpb24gdGltZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgZmlsZV8tPkNvcHlUbygmZmlsZV9wcm90byk7CisgICAgc3RyaW5nIGZpbGVfZGF0YTsKKyAgICBmaWxlX3Byb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCZmaWxlX2RhdGEpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKCIpOworCisgICAgLy8gT25seSB3cml0ZSA0MCBieXRlcyBwZXIgbGluZS4KKyAgICBzdGF0aWMgY29uc3QgaW50IGtCeXRlc1BlckxpbmUgPSA0MDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfZGF0YS5zaXplKCk7IGkgKz0ga0J5dGVzUGVyTGluZSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuICBcIiRkYXRhJFwiIiwKKyAgICAgICAgICAgICAgICAgICAgICJkYXRhIiwKKyAgICAgICAgICAgICAgICAgICAgIEVzY2FwZVRyaWdyYXBocygKKyAgICAgICAgICAgICAgICAgICAgICAgICBDRXNjYXBlKGZpbGVfZGF0YS5zdWJzdHIoaSwga0J5dGVzUGVyTGluZSkpKSk7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLCAkc2l6ZSQpO1xuIiwKKyAgICAgICJzaXplIiwgU2ltcGxlSXRvYShmaWxlX2RhdGEuc2l6ZSgpKSk7CisKKyAgICAvLyBDYWxsIE1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkRmlsZSgpLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRGaWxlKFxuIgorICAgICAgIiAgXCIkZmlsZW5hbWUkXCIsICZwcm90b2J1Zl9SZWdpc3RlclR5cGVzKTtcbiIsCisgICAgICAiZmlsZW5hbWUiLCBmaWxlXy0+bmFtZSgpKTsKKyAgfQorCisgIC8vIEFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGRlZmF1bHQgaW5zdGFuY2VzLiAgVGhpcyBjYW4ndCBiZSBkb25lIGxhemlseQorICAvLyBzaW5jZSBkZWZhdWx0IGluc3RhbmNlcyBhcmUgcmV0dXJuZWQgYnkgc2ltcGxlIGFjY2Vzc29ycyBhbmQgYXJlIHVzZWQgd2l0aAorICAvLyBleHRlbnNpb25zLiAgU3BlYWtpbmcgb2Ygd2hpY2gsIHdlIGFsc28gcmVnaXN0ZXIgZXh0ZW5zaW9ucyBhdCB0aGlzIHRpbWUuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlZmF1bHRJbnN0YW5jZUFsbG9jYXRvcihwcmludGVyKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVJlZ2lzdHJhdGlvbihwcmludGVyKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VJbml0aWFsaXplcihwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCYkc2h1dGRvd25maWxlbmFtZSQpO1xuIiwKKyAgICAic2h1dGRvd25maWxlbmFtZSIsIEdsb2JhbFNodXRkb3duRmlsZU5hbWUoZmlsZV8tPm5hbWUoKSkpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgZmlsZV8sIHByaW50ZXIsCisgICAgLy8gV2l0aCBzdGF0aWMgaW5pdGlhbGl6ZXJzLgorICAgICIvLyBGb3JjZSBBZGREZXNjcmlwdG9ycygpIHRvIGJlIGNhbGxlZCBhdCBzdGF0aWMgaW5pdGlhbGl6YXRpb24gdGltZS5cbiIKKyAgICAic3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl8kZmlsZW5hbWUkIHtcbiIKKyAgICAiICBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfJGZpbGVuYW1lJCgpIHtcbiIKKyAgICAiICAgICRhZGRkZXNjcmlwdG9yc25hbWUkKCk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9IHN0YXRpY19kZXNjcmlwdG9yX2luaXRpYWxpemVyXyRmaWxlbmFtZSRfO1xuIiwKKyAgICAvLyBXaXRob3V0LgorICAgICJHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKCRhZGRkZXNjcmlwdG9yc25hbWUkX29uY2VfKTtcbiIKKyAgICAidm9pZCAkYWRkZGVzY3JpcHRvcnNuYW1lJCgpIHtcbiIKKyAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCYkYWRkZGVzY3JpcHRvcnNuYW1lJF9vbmNlXyxcbiIKKyAgICAiICAgICAgICAgICAgICAgICAmJGFkZGRlc2NyaXB0b3JzbmFtZSRfaW1wbCk7XG4iCisgICAgIn1cbiIsCisgICAgLy8gVmFycy4KKyAgICAiYWRkZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQWRkRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpLAorICAgICJmaWxlbmFtZSIsIEZpbGVuYW1lSWRlbnRpZmllcihmaWxlXy0+bmFtZSgpKSk7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVOYW1lc3BhY2VPcGVuZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChwYWNrYWdlX3BhcnRzXy5zaXplKCkgPiAwKSBwcmludGVyLT5QcmludCgiXG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2thZ2VfcGFydHNfLnNpemUoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIm5hbWVzcGFjZSAkcGFydCQge1xuIiwKKyAgICAgICAgICAgICAgICAgICAicGFydCIsIHBhY2thZ2VfcGFydHNfW2ldKTsKKyAgfQorfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlTmFtZXNwYWNlQ2xvc2Vycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAocGFja2FnZV9wYXJ0c18uc2l6ZSgpID4gMCkgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgZm9yIChpbnQgaSA9IHBhY2thZ2VfcGFydHNfLnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIn0gIC8vIG5hbWVzcGFjZSAkcGFydCRcbiIsCisgICAgICAgICAgICAgICAgICAgInBhcnQiLCBwYWNrYWdlX3BhcnRzX1tpXSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWxlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlMDY1NDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5oCkBAIC0wLDAgKzEsMTAyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9GSUxFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0ZJTEVfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7ICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitjbGFzcyBFbnVtR2VuZXJhdG9yOyAgICAgICAgICAgLy8gZW51bS5oCitjbGFzcyBNZXNzYWdlR2VuZXJhdG9yOyAgICAgICAgLy8gbWVzc2FnZS5oCitjbGFzcyBTZXJ2aWNlR2VuZXJhdG9yOyAgICAgICAgLy8gc2VydmljZS5oCitjbGFzcyBFeHRlbnNpb25HZW5lcmF0b3I7ICAgICAgLy8gZXh0ZW5zaW9uLmgKKworY2xhc3MgRmlsZUdlbmVyYXRvciB7CisgcHVibGljOgorICAvLyBTZWUgZ2VuZXJhdG9yLmNjIGZvciB0aGUgbWVhbmluZyBvZiBkbGxleHBvcnRfZGVjbC4KKyAgZXhwbGljaXQgRmlsZUdlbmVyYXRvcihjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgfkZpbGVHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNvdXJjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICAvLyBHZW5lcmF0ZSB0aGUgQnVpbGREZXNjcmlwdG9ycygpIHByb2NlZHVyZSwgd2hpY2ggYnVpbGRzIGFsbCBkZXNjcmlwdG9ycworICAvLyBmb3IgdHlwZXMgZGVmaW5lZCBpbiB0aGUgZmlsZS4KKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkRGVzY3JpcHRvcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIHZvaWQgR2VuZXJhdGVOYW1lc3BhY2VPcGVuZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZU5hbWVzcGFjZUNsb3NlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlR2VuZXJhdG9yPiA+IG1lc3NhZ2VfZ2VuZXJhdG9yc187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEVudW1HZW5lcmF0b3I+ID4gZW51bV9nZW5lcmF0b3JzXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8U2VydmljZUdlbmVyYXRvcj4gPiBzZXJ2aWNlX2dlbmVyYXRvcnNfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxFeHRlbnNpb25HZW5lcmF0b3I+ID4gZXh0ZW5zaW9uX2dlbmVyYXRvcnNfOworCisgIC8vIEUuZy4gaWYgdGhlIHBhY2thZ2UgaXMgZm9vLmJhciwgcGFja2FnZV9wYXJ0c18gaXMgeyJmb28iLCAiYmFyIn0uCisgIHZlY3RvcjxzdHJpbmc+IHBhY2thZ2VfcGFydHNfOworICBjb25zdCBPcHRpb25zIG9wdGlvbnNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWxlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9GSUxFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2dlbmVyYXRvci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzk5OWI5MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuY2MKQEAgLTAsMCArMSwxMjggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2dlbmVyYXRvci5oPgorCisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx1dGlsaXR5PgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitDcHBHZW5lcmF0b3I6OkNwcEdlbmVyYXRvcigpIHt9CitDcHBHZW5lcmF0b3I6On5DcHBHZW5lcmF0b3IoKSB7fQorCitib29sIENwcEdlbmVyYXRvcjo6R2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3QgeworICB2ZWN0b3I8cGFpcjxzdHJpbmcsIHN0cmluZz4gPiBvcHRpb25zOworICBQYXJzZUdlbmVyYXRvclBhcmFtZXRlcihwYXJhbWV0ZXIsICZvcHRpb25zKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBwYXJzZSBnZW5lcmF0b3Igb3B0aW9ucworCisgIC8vIFRPRE8oa2VudG9uKTogIElmIHdlIGV2ZXIgaGF2ZSBtb3JlIG9wdGlvbnMsIHdlIG1heSB3YW50IHRvIGNyZWF0ZSBhCisgIC8vICAgY2xhc3MgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlbSB3aGljaCB3ZSBjYW4gcGFzcyBkb3duIHRvIGFsbCB0aGUKKyAgLy8gICBnZW5lcmF0b3IgY2xhc3Nlcy4gIEN1cnJlbnRseSB3ZSBwYXNzIGRsbGV4cG9ydF9kZWNsIGRvd24gdG8gYWxsIG9mCisgIC8vICAgdGhlbSB2aWEgdGhlIGNvbnN0cnVjdG9ycywgYnV0IHdlIGRvbid0IHdhbnQgdG8gaGF2ZSB0byBhZGQgYW5vdGhlcgorICAvLyAgIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBmb3IgZXZlcnkgb3B0aW9uLgorCisgIC8vIElmIHRoZSBkbGxleHBvcnRfZGVjbCBvcHRpb24gaXMgcGFzc2VkIHRvIHRoZSBjb21waWxlciwgd2UgbmVlZCB0byB3cml0ZQorICAvLyBpdCBpbiBmcm9udCBvZiBldmVyeSBzeW1ib2wgdGhhdCBzaG91bGQgYmUgZXhwb3J0ZWQgaWYgdGhpcyAucHJvdG8gaXMKKyAgLy8gY29tcGlsZWQgaW50byBhIFdpbmRvd3MgRExMLiAgRS5nLiwgaWYgdGhlIHVzZXIgaW52b2tlcyB0aGUgcHJvdG9jb2wKKyAgLy8gY29tcGlsZXIgYXM6CisgIC8vICAgcHJvdG9jIC0tY3BwX291dD1kbGxleHBvcnRfZGVjbD1GT09fRVhQT1JUOm91dGRpciBmb28ucHJvdG8KKyAgLy8gdGhlbiB3ZSdsbCBkZWZpbmUgY2xhc3NlcyBsaWtlIHRoaXM6CisgIC8vICAgY2xhc3MgRk9PX0VYUE9SVCBGb28geworICAvLyAgICAgLi4uCisgIC8vICAgfQorICAvLyBGT09fRVhQT1JUIGlzIGEgbWFjcm8gd2hpY2ggc2hvdWxkIGV4cGFuZCB0byBfX2RlY2xzcGVjKGRsbGV4cG9ydCkgb3IKKyAgLy8gX19kZWNsc3BlYyhkbGxpbXBvcnQpIGRlcGVuZGluZyBvbiB3aGF0IGlzIGJlaW5nIGNvbXBpbGVkLgorICBPcHRpb25zIGZpbGVfb3B0aW9uczsKKworICBmb3IgKGludCBpID0gMDsgaSA8IG9wdGlvbnMuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAob3B0aW9uc1tpXS5maXJzdCA9PSAiZGxsZXhwb3J0X2RlY2wiKSB7CisgICAgICBmaWxlX29wdGlvbnMuZGxsZXhwb3J0X2RlY2wgPSBvcHRpb25zW2ldLnNlY29uZDsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gInNhZmVfYm91bmRhcnlfY2hlY2siKSB7CisgICAgICBmaWxlX29wdGlvbnMuc2FmZV9ib3VuZGFyeV9jaGVjayA9IHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgICplcnJvciA9ICJVbmtub3duIGdlbmVyYXRvciBvcHRpb246ICIgKyBvcHRpb25zW2ldLmZpcnN0OworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworICBzdHJpbmcgYmFzZW5hbWUgPSBTdHJpcFByb3RvKGZpbGUtPm5hbWUoKSk7CisgIGJhc2VuYW1lLmFwcGVuZCgiLnBiIik7CisKKyAgRmlsZUdlbmVyYXRvciBmaWxlX2dlbmVyYXRvcihmaWxlLCBmaWxlX29wdGlvbnMpOworCisgIC8vIEdlbmVyYXRlIGhlYWRlci4KKyAgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LT5PcGVuKGJhc2VuYW1lICsgIi5oIikpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlSGVhZGVyKCZwcmludGVyKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIGNjIGZpbGUuCisgIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICBnZW5lcmF0b3JfY29udGV4dC0+T3BlbihiYXNlbmFtZSArICIuY2MiKSk7CisgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgZmlsZV9nZW5lcmF0b3IuR2VuZXJhdGVTb3VyY2UoJnByaW50ZXIpOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2Q1MTdjZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDcyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gR2VuZXJhdGVzIEMrKyBjb2RlIGZvciBhIGdpdmVuIC5wcm90byBmaWxlLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfR0VORVJBVE9SX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0dFTkVSQVRPUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBDb2RlR2VuZXJhdG9yIGltcGxlbWVudGF0aW9uIHdoaWNoIGdlbmVyYXRlcyBhIEMrKyBzb3VyY2UgZmlsZSBhbmQKKy8vIGhlYWRlci4gIElmIHlvdSBjcmVhdGUgeW91ciBvd24gcHJvdG9jb2wgY29tcGlsZXIgYmluYXJ5IGFuZCB5b3Ugd2FudAorLy8gaXQgdG8gc3VwcG9ydCBDKysgb3V0cHV0LCB5b3UgY2FuIGRvIHNvIGJ5IHJlZ2lzdGVyaW5nIGFuIGluc3RhbmNlIG9mIHRoaXMKKy8vIENvZGVHZW5lcmF0b3Igd2l0aCB0aGUgQ29tbWFuZExpbmVJbnRlcmZhY2UgaW4geW91ciBtYWluKCkgZnVuY3Rpb24uCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIENwcEdlbmVyYXRvciA6IHB1YmxpYyBDb2RlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIENwcEdlbmVyYXRvcigpOworICB+Q3BwR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBDb2RlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCwKKyAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhDcHBHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0dFTkVSQVRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGU3MTU1YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmNjCkBAIC0wLDAgKzEsNTI3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK25hbWVzcGFjZSB7CisKK3N0cmluZyBEb3RzVG9VbmRlcnNjb3Jlcyhjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgcmV0dXJuIFN0cmluZ1JlcGxhY2UobmFtZSwgIi4iLCAiXyIsIHRydWUpOworfQorCitzdHJpbmcgRG90c1RvQ29sb25zKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gU3RyaW5nUmVwbGFjZShuYW1lLCAiLiIsICI6OiIsIHRydWUpOworfQorCitjb25zdCBjaGFyKiBjb25zdCBrS2V5d29yZExpc3RbXSA9IHsKKyAgImFsaWduYXMiLCAiYWxpZ25vZiIsICJhbmQiLCAiYW5kX2VxIiwgImFzbSIsICJhdXRvIiwgImJpdGFuZCIsICJiaXRvciIsCisgICJib29sIiwgImJyZWFrIiwgImNhc2UiLCAiY2F0Y2giLCAiY2hhciIsICJjbGFzcyIsICJjb21wbCIsICJjb25zdCIsCisgICJjb25zdGV4cHIiLCAiY29uc3RfY2FzdCIsICJjb250aW51ZSIsICJkZWNsdHlwZSIsICJkZWZhdWx0IiwgImRlbGV0ZSIsICJkbyIsCisgICJkb3VibGUiLCAiZHluYW1pY19jYXN0IiwgImVsc2UiLCAiZW51bSIsICJleHBsaWNpdCIsICJleHRlcm4iLCAiZmFsc2UiLAorICAiZmxvYXQiLCAiZm9yIiwgImZyaWVuZCIsICJnb3RvIiwgImlmIiwgImlubGluZSIsICJpbnQiLCAibG9uZyIsICJtdXRhYmxlIiwKKyAgIm5hbWVzcGFjZSIsICJuZXciLCAibm9leGNlcHQiLCAibm90IiwgIm5vdF9lcSIsICJudWxscHRyIiwgIm9wZXJhdG9yIiwgIm9yIiwKKyAgIm9yX2VxIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwgInB1YmxpYyIsICJyZWdpc3RlciIsICJyZWludGVycHJldF9jYXN0IiwKKyAgInJldHVybiIsICJzaG9ydCIsICJzaWduZWQiLCAic2l6ZW9mIiwgInN0YXRpYyIsICJzdGF0aWNfYXNzZXJ0IiwKKyAgInN0YXRpY19jYXN0IiwgInN0cnVjdCIsICJzd2l0Y2giLCAidGVtcGxhdGUiLCAidGhpcyIsICJ0aHJlYWRfbG9jYWwiLAorICAidGhyb3ciLCAidHJ1ZSIsICJ0cnkiLCAidHlwZWRlZiIsICJ0eXBlaWQiLCAidHlwZW5hbWUiLCAidW5pb24iLCAidW5zaWduZWQiLAorICAidXNpbmciLCAidmlydHVhbCIsICJ2b2lkIiwgInZvbGF0aWxlIiwgIndjaGFyX3QiLCAid2hpbGUiLCAieG9yIiwgInhvcl9lcSIKK307CisKK2hhc2hfc2V0PHN0cmluZz4gTWFrZUtleXdvcmRzTWFwKCkgeworICBoYXNoX3NldDxzdHJpbmc+IHJlc3VsdDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKGtLZXl3b3JkTGlzdCk7IGkrKykgeworICAgIHJlc3VsdC5pbnNlcnQoa0tleXdvcmRMaXN0W2ldKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitoYXNoX3NldDxzdHJpbmc+IGtLZXl3b3JkcyA9IE1ha2VLZXl3b3Jkc01hcCgpOworCisvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIHByb3ZpZGVkIGRlc2NyaXB0b3IgaGFzIGFuIGV4dGVuc2lvbi4gVGhpcyBpbmNsdWRlcyBpdHMKKy8vIG5lc3RlZCB0eXBlcy4KK2Jvb2wgSGFzRXh0ZW5zaW9uKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgaWYgKGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9jb3VudCgpID4gMCkgeworICAgIHJldHVybiB0cnVlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgaWYgKEhhc0V4dGVuc2lvbihkZXNjcmlwdG9yLT5uZXN0ZWRfdHlwZShpKSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBzdHJpbmcmIGlucHV0LCBib29sIGNhcF9uZXh0X2xldHRlcikgeworICBzdHJpbmcgcmVzdWx0OworICAvLyBOb3RlOiAgSSBkaXN0cnVzdCBjdHlwZS5oIGR1ZSB0byBsb2NhbGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCdhJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAneicpIHsKKyAgICAgIGlmIChjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldICsgKCdBJyAtICdhJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICB9CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCdBJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnWicpIHsKKyAgICAgIC8vIENhcGl0YWwgbGV0dGVycyBhcmUgbGVmdCBhcy1pcy4KKyAgICAgIHJlc3VsdCArPSBpbnB1dFtpXTsKKyAgICAgIGNhcF9uZXh0X2xldHRlciA9IGZhbHNlOworICAgIH0gZWxzZSBpZiAoJzAnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICc5JykgeworICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgY2FwX25leHRfbGV0dGVyID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgY2FwX25leHRfbGV0dGVyID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXSA9CisgICIvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iOworY29uc3QgY2hhciBrVGhpblNlcGFyYXRvcltdID0KKyAgIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBxdWFsaWZpZWQpIHsKKworICAvLyBGaW5kICJvdXRlciIsIHRoZSBkZXNjcmlwdG9yIG9mIHRoZSB0b3AtbGV2ZWwgbWVzc2FnZSBpbiB3aGljaAorICAvLyAiZGVzY3JpcHRvciIgaXMgZW1iZWRkZWQuCisgIGNvbnN0IERlc2NyaXB0b3IqIG91dGVyID0gZGVzY3JpcHRvcjsKKyAgd2hpbGUgKG91dGVyLT5jb250YWluaW5nX3R5cGUoKSAhPSBOVUxMKSBvdXRlciA9IG91dGVyLT5jb250YWluaW5nX3R5cGUoKTsKKworICBjb25zdCBzdHJpbmcmIG91dGVyX25hbWUgPSBvdXRlci0+ZnVsbF9uYW1lKCk7CisgIHN0cmluZyBpbm5lcl9uYW1lID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkuc3Vic3RyKG91dGVyX25hbWUuc2l6ZSgpKTsKKworICBpZiAocXVhbGlmaWVkKSB7CisgICAgcmV0dXJuICI6OiIgKyBEb3RzVG9Db2xvbnMob3V0ZXJfbmFtZSkgKyBEb3RzVG9VbmRlcnNjb3Jlcyhpbm5lcl9uYW1lKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gb3V0ZXItPm5hbWUoKSArIERvdHNUb1VuZGVyc2NvcmVzKGlubmVyX25hbWUpOworICB9Cit9CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fZGVzY3JpcHRvciwgYm9vbCBxdWFsaWZpZWQpIHsKKyAgaWYgKGVudW1fZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgIGlmIChxdWFsaWZpZWQpIHsKKyAgICAgIHJldHVybiAiOjoiICsgRG90c1RvQ29sb25zKGVudW1fZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZW51bV9kZXNjcmlwdG9yLT5uYW1lKCk7CisgICAgfQorICB9IGVsc2UgeworICAgIHN0cmluZyByZXN1bHQgPSBDbGFzc05hbWUoZW51bV9kZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSwgcXVhbGlmaWVkKTsKKyAgICByZXN1bHQgKz0gJ18nOworICAgIHJlc3VsdCArPSBlbnVtX2Rlc2NyaXB0b3ItPm5hbWUoKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKKworc3RyaW5nIFN1cGVyQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3ItPmZpbGUoKSkgPworICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSIgOiAiOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlTGl0ZSI7Cit9CisKK3N0cmluZyBGaWVsZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzdHJpbmcgcmVzdWx0ID0gZmllbGQtPm5hbWUoKTsKKyAgTG93ZXJTdHJpbmcoJnJlc3VsdCk7CisgIGlmIChrS2V5d29yZHMuY291bnQocmVzdWx0KSA+IDApIHsKKyAgICByZXN1bHQuYXBwZW5kKCJfIik7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIEVudW1WYWx1ZU5hbWUoY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSkgeworICBzdHJpbmcgcmVzdWx0ID0gZW51bV92YWx1ZS0+bmFtZSgpOworICBpZiAoa0tleXdvcmRzLmNvdW50KHJlc3VsdCkgPiAwKSB7CisgICAgcmVzdWx0LmFwcGVuZCgiXyIpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKSB7CisgIHN0cmluZyBmaWVsZF9uYW1lID0gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShmaWVsZC0+bmFtZSgpLCB0cnVlKTsKKyAgc3RyaW5nIHJlc3VsdCA9ICJrIiArIGZpZWxkX25hbWUgKyAiRmllbGROdW1iZXIiOworCisgIGlmICghZmllbGQtPmlzX2V4dGVuc2lvbigpICYmCisgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgKKyAgICAgICAgZmllbGQtPmNhbWVsY2FzZV9uYW1lKCkpICE9IGZpZWxkKSB7CisgICAgLy8gVGhpcyBmaWVsZCdzIGNhbWVsY2FzZSBuYW1lIGlzIG5vdCB1bmlxdWUuICBBcyBhIGhhY2ssIGFkZCB0aGUgZmllbGQKKyAgICAvLyBudW1iZXIgdG8gdGhlIGNvbnN0YW50IG5hbWUuICBUaGlzIG1ha2VzIHRoZSBjb25zdGFudCByYXRoZXIgdXNlbGVzcywKKyAgICAvLyBidXQgd2hhdCBjYW4gd2UgZG8/CisgICAgcmVzdWx0ICs9ICJfIiArIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKTsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBGaWVsZE1lc3NhZ2VUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIE5vdGU6ICBUaGUgR29vZ2xlLWludGVybmFsIHZlcnNpb24gb2YgUHJvdG9jb2wgQnVmZmVycyB1c2VzIHRoaXMgZnVuY3Rpb24KKyAgLy8gICBhcyBhIGhvb2sgcG9pbnQgZm9yIGhhY2tzIHRvIHN1cHBvcnQgbGVnYWN5IGNvZGUuCisgIHJldHVybiBDbGFzc05hbWUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCB0cnVlKTsKK30KKworc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBpZiAoSGFzU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvZGV2ZWwiKSkgeworICAgIHJldHVybiBTdHJpcFN1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90b2RldmVsIik7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFN0cmlwU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvIik7CisgIH0KK30KKworY29uc3QgY2hhciogUHJpbWl0aXZlVHlwZU5hbWUoRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzIgIDogcmV0dXJuICI6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NCAgOiByZXR1cm4gIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMiA6IHJldHVybiAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRSA6IHJldHVybiAiZG91YmxlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVCAgOiByZXR1cm4gImZsb2F0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MICAgOiByZXR1cm4gImJvb2wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gICA6IHJldHVybiAiaW50IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcgOiByZXR1cm4gIjo6c3RkOjpzdHJpbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHJldHVybiBOVUxMOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBDcHBUeXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2NvbnN0IGNoYXIqIERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAiSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gIkludDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzIgIDogcmV0dXJuICJVSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NCAgOiByZXR1cm4gIlVJbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyICA6IHJldHVybiAiU0ludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQgIDogcmV0dXJuICJTSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzIgOiByZXR1cm4gIkZpeGVkMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gIkZpeGVkNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gIlNGaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJTRml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiAiRmxvYXQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gIkRvdWJsZSI7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MICAgIDogcmV0dXJuICJCb29sIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuICJFbnVtIjsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAgOiByZXR1cm4gIlN0cmluZyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMgICA6IHJldHVybiAiQnl0ZXMiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gIkdyb3VwIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuICJNZXNzYWdlIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBJbnQzMlRvU3RyaW5nKGludCBudW1iZXIpIHsKKyAgLy8gZ2NjIHJlamVjdHMgdGhlIGRlY2ltYWwgZm9ybSBvZiBraW50MzJtaW4uCisgIGlmIChudW1iZXIgPT0ga2ludDMybWluKSB7CisgICAgR09PR0xFX0NPTVBJTEVfQVNTRVJUKGtpbnQzMm1pbiA9PSAofjB4N2ZmZmZmZmYpLCBraW50MzJtaW5fdmFsdWVfZXJyb3IpOworICAgIHJldHVybiAiKH4weDdmZmZmZmZmKSI7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFNpbXBsZUl0b2EobnVtYmVyKTsKKyAgfQorfQorCitzdHJpbmcgSW50NjRUb1N0cmluZyhpbnQ2NCBudW1iZXIpIHsKKyAgLy8gZ2NjIHJlamVjdHMgdGhlIGRlY2ltYWwgZm9ybSBvZiBraW50NjRtaW4KKyAgaWYgKG51bWJlciA9PSBraW50NjRtaW4pIHsKKyAgICAvLyBNYWtlIHN1cmUgd2UgYXJlIGluIGEgMidzIGNvbXBsZW1lbnQgc3lzdGVtLgorICAgIEdPT0dMRV9DT01QSUxFX0FTU0VSVChraW50NjRtaW4gPT0gR09PR0xFX0xPTkdMT05HKH4weDdmZmZmZmZmZmZmZmZmZmYpLAorICAgICAgICAgICAgICAgICAgIGtpbnQ2NG1pbl92YWx1ZV9lcnJvcik7CisgICAgcmV0dXJuICJHT09HTEVfTE9OR0xPTkcofjB4N2ZmZmZmZmZmZmZmZmZmZikiOworICB9CisgIHJldHVybiAiR09PR0xFX0xPTkdMT05HKCIgKyBTaW1wbGVJdG9hKG51bWJlcikgKyAiKSI7Cit9CisKK3N0cmluZyBEZWZhdWx0VmFsdWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gSW50MzJUb1N0cmluZyhmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSkgKyAidSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gSW50NjRUb1N0cmluZyhmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gIkdPT0dMRV9VTE9OR0xPTkcoIiArIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDY0KCkpKyAiKSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW5maW5pdHkoKSI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiLTo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkluZmluaXR5KCkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hTigpIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBTaW1wbGVEdG9hKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICB7CisgICAgICAgIGZsb2F0IHZhbHVlID0gZmllbGQtPmRlZmF1bHRfdmFsdWVfZmxvYXQoKTsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICAgIHJldHVybiAic3RhdGljX2Nhc3Q8ZmxvYXQ+KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkluZmluaXR5KCkpIjsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgICAgcmV0dXJuICJzdGF0aWNfY2FzdDxmbG9hdD4oLTo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkluZmluaXR5KCkpIjsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICAgIHJldHVybiAic3RhdGljX2Nhc3Q8ZmxvYXQ+KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hTigpKSI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc3RyaW5nIGZsb2F0X3ZhbHVlID0gU2ltcGxlRnRvYSh2YWx1ZSk7CisgICAgICAgICAgLy8gSWYgZmxvYXRpbmcgcG9pbnQgdmFsdWUgY29udGFpbnMgYSBwZXJpb2QgKC4pIG9yIGFuIGV4cG9uZW50CisgICAgICAgICAgLy8gKGVpdGhlciBFIG9yIGUpLCB0aGVuIGFwcGVuZCBzdWZmaXggJ2YnIHRvIG1ha2UgaXQgYSBmbG9hdAorICAgICAgICAgIC8vIGxpdGVyYWwuCisgICAgICAgICAgaWYgKGZsb2F0X3ZhbHVlLmZpbmRfZmlyc3Rfb2YoIi5lRSIpICE9IHN0cmluZzo6bnBvcykgeworICAgICAgICAgICAgZmxvYXRfdmFsdWUucHVzaF9iYWNrKCdmJyk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBmbG9hdF92YWx1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfYm9vbCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgLy8gTGF6eTogIEdlbmVyYXRlIGEgc3RhdGljX2Nhc3QgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIGEgaGVscGVyIGZ1bmN0aW9uCisgICAgICAvLyAgIHRoYXQgY29uc3RydWN0cyB0aGUgZnVsbCBuYW1lIG9mIGFuIGVudW0gdmFsdWUuCisgICAgICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAic3RhdGljX2Nhc3Q8ICQwID4oJDEpIiwKKyAgICAgICAgICBDbGFzc05hbWUoZmllbGQtPmVudW1fdHlwZSgpLCB0cnVlKSwKKyAgICAgICAgICBJbnQzMlRvU3RyaW5nKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2VudW0oKS0+bnVtYmVyKCkpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gIlwiIiArIEVzY2FwZVRyaWdyYXBocygKKyAgICAgICAgQ0VzY2FwZShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkpICsKKyAgICAgICAgIlwiIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIEZpZWxkTWVzc2FnZVR5cGVOYW1lKGZpZWxkKSArICI6OmRlZmF1bHRfaW5zdGFuY2UoKSI7CisgIH0KKyAgLy8gQ2FuJ3QgYWN0dWFsbHkgZ2V0IGhlcmU7IG1ha2UgY29tcGlsZXIgaGFwcHkuICAoV2UgY291bGQgYWRkIGEgZGVmYXVsdAorICAvLyBjYXNlIGFib3ZlIGJ1dCB0aGVuIHdlIHdvdWxkbid0IGdldCB0aGUgbmljZSBjb21waWxlciB3YXJuaW5nIHdoZW4gYQorICAvLyBuZXcgdHlwZSBpcyBhZGRlZC4pCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKKy8vIENvbnZlcnQgYSBmaWxlIG5hbWUgaW50byBhIHZhbGlkIGlkZW50aWZpZXIuCitzdHJpbmcgRmlsZW5hbWVJZGVudGlmaWVyKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlbmFtZS5zaXplKCk7IGkrKykgeworICAgIGlmIChhc2NpaV9pc2FsbnVtKGZpbGVuYW1lW2ldKSkgeworICAgICAgcmVzdWx0LnB1c2hfYmFjayhmaWxlbmFtZVtpXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE5vdCBhbHBoYW51bWVyaWMuICBUbyBhdm9pZCBhbnkgcG9zc2liaWxpdHkgb2YgbmFtZSBjb25mbGljdHMgd2UKKyAgICAgIC8vIHVzZSB0aGUgaGV4IGNvZGUgZm9yIHRoZSBjaGFyYWN0ZXIuCisgICAgICBTdHJBcHBlbmQoJnJlc3VsdCwgIl8iLCBUb0hleChzdGF0aWNfY2FzdDx1aW50OD4oZmlsZW5hbWVbaV0pKSk7CisgICAgfQorICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgQWRkRGVzY3JpcHRvcnMoKSBmdW5jdGlvbiBmb3IgYSBnaXZlbiBmaWxlLgorc3RyaW5nIEdsb2JhbEFkZERlc2NyaXB0b3JzTmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIHJldHVybiAicHJvdG9idWZfQWRkRGVzY18iICsgRmlsZW5hbWVJZGVudGlmaWVyKGZpbGVuYW1lKTsKK30KKworLy8gUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBBc3NpZ25EZXNjcmlwdG9ycygpIGZ1bmN0aW9uIGZvciBhIGdpdmVuIGZpbGUuCitzdHJpbmcgR2xvYmFsQXNzaWduRGVzY3JpcHRvcnNOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuICJwcm90b2J1Zl9Bc3NpZ25EZXNjXyIgKyBGaWxlbmFtZUlkZW50aWZpZXIoZmlsZW5hbWUpOworfQorCisvLyBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIFNodXRkb3duRmlsZSgpIGZ1bmN0aW9uIGZvciBhIGdpdmVuIGZpbGUuCitzdHJpbmcgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIHJldHVybiAicHJvdG9idWZfU2h1dGRvd25GaWxlXyIgKyBGaWxlbmFtZUlkZW50aWZpZXIoZmlsZW5hbWUpOworfQorCisvLyBSZXR1cm4gdGhlIHF1YWxpZmllZCBDKysgbmFtZSBmb3IgYSBmaWxlIGxldmVsIHN5bWJvbC4KK3N0cmluZyBRdWFsaWZpZWRGaWxlTGV2ZWxTeW1ib2woY29uc3Qgc3RyaW5nJiBwYWNrYWdlLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgaWYgKHBhY2thZ2UuZW1wdHkoKSkgeworICAgIHJldHVybiBTdHJDYXQoIjo6IiwgbmFtZSk7CisgIH0KKyAgcmV0dXJuIFN0ckNhdCgiOjoiLCBEb3RzVG9Db2xvbnMocGFja2FnZSksICI6OiIsIG5hbWUpOworfQorCisvLyBFc2NhcGUgQysrIHRyaWdyYXBocyBieSBlc2NhcGluZyBxdWVzdGlvbiBtYXJrcyB0byBcPworc3RyaW5nIEVzY2FwZVRyaWdyYXBocyhjb25zdCBzdHJpbmcmIHRvX2VzY2FwZSkgeworICByZXR1cm4gU3RyaW5nUmVwbGFjZSh0b19lc2NhcGUsICI/IiwgIlxcPyIsIHRydWUpOworfQorCisvLyBFc2NhcGVkIGZ1bmN0aW9uIG5hbWUgdG8gZWxpbWluYXRlIG5hbWluZyBjb25mbGljdC4KK3N0cmluZyBTYWZlRnVuY3Rpb25OYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgpIHsKKyAgLy8gRG8gbm90IHVzZSBGaWVsZE5hbWUoKSBzaW5jZSBpdCB3aWxsIGVzY2FwZSBrZXl3b3Jkcy4KKyAgc3RyaW5nIG5hbWUgPSBmaWVsZC0+bmFtZSgpOworICBMb3dlclN0cmluZygmbmFtZSk7CisgIHN0cmluZyBmdW5jdGlvbl9uYW1lID0gcHJlZml4ICsgbmFtZTsKKyAgaWYgKGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZShmdW5jdGlvbl9uYW1lKSkgeworICAgIC8vIFNpbmdsZSB1bmRlcnNjb3JlIHdpbGwgYWxzbyBtYWtlIGl0IGNvbmZsaWN0aW5nIHdpdGggdGhlIHByaXZhdGUgZGF0YQorICAgIC8vIG1lbWJlci4gV2UgdXNlIGRvdWJsZSB1bmRlcnNjb3JlIHRvIGVzY2FwZSBmdW5jdGlvbiBuYW1lcy4KKyAgICBmdW5jdGlvbl9uYW1lLmFwcGVuZCgiX18iKTsKKyAgfSBlbHNlIGlmIChrS2V5d29yZHMuY291bnQobmFtZSkgPiAwKSB7CisgICAgLy8gSWYgdGhlIGZpZWxkIG5hbWUgaXMgYSBrZXl3b3JkLCB3ZSBhcHBlbmQgdGhlIHVuZGVyc2NvcmUgYmFjayB0byBrZWVwIGl0CisgICAgLy8gY29uc2lzdGVudCB3aXRoIG90aGVyIGZ1bmN0aW9uIG5hbWVzLgorICAgIGZ1bmN0aW9uX25hbWUuYXBwZW5kKCJfIik7CisgIH0KKyAgcmV0dXJuIGZ1bmN0aW9uX25hbWU7Cit9CisKK2Jvb2wgU3RhdGljSW5pdGlhbGl6ZXJzRm9yY2VkKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlKSB8fCBmaWxlLT5leHRlbnNpb25fY291bnQoKSA+IDApIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoSGFzRXh0ZW5zaW9uKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK3ZvaWQgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICBjb25zdCBjaGFyKiB3aXRoX3N0YXRpY19pbml0LCBjb25zdCBjaGFyKiB3aXRob3V0X3N0YXRpY19pbml0LAorICAgIGNvbnN0IGNoYXIqIHZhcjEsIGNvbnN0IHN0cmluZyYgdmFsMSwKKyAgICBjb25zdCBjaGFyKiB2YXIyLCBjb25zdCBzdHJpbmcmIHZhbDIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICBpZiAodmFyMSkgeworICAgIHZhcnNbdmFyMV0gPSB2YWwxOworICB9CisgIGlmICh2YXIyKSB7CisgICAgdmFyc1t2YXIyXSA9IHZhbDI7CisgIH0KKyAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgdmFycywgZmlsZSwgcHJpbnRlciwgd2l0aF9zdGF0aWNfaW5pdCwgd2l0aG91dF9zdGF0aWNfaW5pdCk7Cit9CisKK3ZvaWQgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcnMsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBjaGFyKiB3aXRoX3N0YXRpY19pbml0LAorICAgIGNvbnN0IGNoYXIqIHdpdGhvdXRfc3RhdGljX2luaXQpIHsKKyAgaWYgKFN0YXRpY0luaXRpYWxpemVyc0ZvcmNlZChmaWxlKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsIHdpdGhfc3RhdGljX2luaXQpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsIChzdHJpbmcoCisgICAgICAiI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9OT19TVEFUSUNfSU5JVElBTElaRVJcbiIpICsKKyAgICAgIHdpdGhvdXRfc3RhdGljX2luaXQgKworICAgICAgIiNlbHNlXG4iICsKKyAgICAgIHdpdGhfc3RhdGljX2luaXQgKworICAgICAgIiNlbmRpZlxuIikuY19zdHIoKSk7CisgIH0KK30KKworCitzdGF0aWMgYm9vbCBIYXNNYXBGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIGlmIChkZXNjcmlwdG9yLT5maWVsZChpKS0+aXNfbWFwKCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGlmIChIYXNNYXBGaWVsZHMoZGVzY3JpcHRvci0+bmVzdGVkX3R5cGUoaSkpKSByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgSGFzTWFwRmllbGRzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGlmIChIYXNNYXBGaWVsZHMoZmlsZS0+bWVzc2FnZV90eXBlKGkpKSkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitzdGF0aWMgYm9vbCBIYXNFbnVtRGVmaW5pdGlvbnMoY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlKSB7CisgIGlmIChtZXNzYWdlX3R5cGUtPmVudW1fdHlwZV9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoSGFzRW51bURlZmluaXRpb25zKG1lc3NhZ2VfdHlwZS0+bmVzdGVkX3R5cGUoaSkpKSByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgSGFzRW51bURlZmluaXRpb25zKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGlmIChmaWxlLT5lbnVtX3R5cGVfY291bnQoKSA+IDApIHJldHVybiB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoSGFzRW51bURlZmluaXRpb25zKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSkpIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBJc1N0cmluZ09yTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gZmFsc2U7Cit9CisKK0ZpZWxkT3B0aW9uczo6Q1R5cGUgRWZmZWN0aXZlU3RyaW5nQ1R5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBHT09HTEVfRENIRUNLKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcpOworICAvLyBPcGVuLXNvdXJjZSBwcm90b2J1ZiByZWxlYXNlIG9ubHkgc3VwcG9ydHMgU1RSSU5HIGN0eXBlLgorICByZXR1cm4gRmllbGRPcHRpb25zOjpTVFJJTkc7CisKK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NGZhMmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oCkBAIC0wLDAgKzEsMjUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9IRUxQRVJTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0hFTFBFUlNfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW8geworY2xhc3MgUHJpbnRlcjsKK30KKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBDb21tb25seS11c2VkIHNlcGFyYXRvciBjb21tZW50cy4gIFRoaWNrIGlzIGEgbGluZSBvZiAnPScsIHRoaW4gaXMgYSBsaW5lCisvLyBvZiAnLScuCitleHRlcm4gY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXTsKK2V4dGVybiBjb25zdCBjaGFyIGtUaGluU2VwYXJhdG9yW107CisKKy8vIFJldHVybnMgdGhlIG5vbi1uZXN0ZWQgdHlwZSBuYW1lIGZvciB0aGUgZ2l2ZW4gdHlwZS4gIElmICJxdWFsaWZpZWQiIGlzCisvLyB0cnVlLCBwcmVmaXggdGhlIHR5cGUgd2l0aCB0aGUgZnVsbCBuYW1lc3BhY2UuICBGb3IgZXhhbXBsZSwgaWYgeW91IGhhZDoKKy8vICAgcGFja2FnZSBmb28uYmFyOworLy8gICBtZXNzYWdlIEJheiB7IG1lc3NhZ2UgUXV4IHt9IH0KKy8vIFRoZW4gdGhlIHF1YWxpZmllZCBDbGFzc05hbWUgZm9yIFF1eCB3b3VsZCBiZToKKy8vICAgOjpmb286OmJhcjo6QmF6X1F1eAorLy8gV2hpbGUgdGhlIG5vbi1xdWFsaWZpZWQgdmVyc2lvbiB3b3VsZCBiZToKKy8vICAgQmF6X1F1eAorc3RyaW5nIENsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBib29sIHF1YWxpZmllZCk7CitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3IsIGJvb2wgcXVhbGlmaWVkKTsKKworc3RyaW5nIFN1cGVyQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBHZXQgdGhlICh1bnF1YWxpZmllZCkgbmFtZSB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciB0aGlzIGZpZWxkIGluIEMrKyBjb2RlLgorLy8gVGhlIG5hbWUgaXMgY29lcmNlZCB0byBsb3dlci1jYXNlIHRvIGVtdWxhdGUgcHJvdG8xIGJlaGF2aW9yLiAgUGVvcGxlCisvLyBzaG91bGQgYmUgdXNpbmcgbG93ZXJjYXNlLXdpdGgtdW5kZXJzY29yZXMgc3R5bGUgZm9yIHByb3RvIGZpZWxkIG5hbWVzCisvLyBhbnl3YXksIHNvIG5vcm1hbGx5IHRoaXMganVzdCByZXR1cm5zIGZpZWxkLT5uYW1lKCkuCitzdHJpbmcgRmllbGROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBHZXQgdGhlIHNhbml0aXplZCBuYW1lIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBnaXZlbiBlbnVtIGluIEMrKyBjb2RlLgorc3RyaW5nIEVudW1WYWx1ZU5hbWUoY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSk7CisKKy8vIEdldCB0aGUgdW5xdWFsaWZpZWQgbmFtZSB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBhIGZpZWxkJ3MgZmllbGQKKy8vIG51bWJlciBjb25zdGFudC4KK3N0cmluZyBGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKTsKKworLy8gUmV0dXJucyB0aGUgc2NvcGUgd2hlcmUgdGhlIGZpZWxkIHdhcyBkZWZpbmVkIChmb3IgZXh0ZW5zaW9ucywgdGhpcyBpcworLy8gZGlmZmVyZW50IGZyb20gdGhlIG1lc3NhZ2UgdHlwZSB0byB3aGljaCB0aGUgZmllbGQgYXBwbGllcykuCitpbmxpbmUgY29uc3QgRGVzY3JpcHRvciogRmllbGRTY29wZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBmaWVsZC0+aXNfZXh0ZW5zaW9uKCkgPworICAgIGZpZWxkLT5leHRlbnNpb25fc2NvcGUoKSA6IGZpZWxkLT5jb250YWluaW5nX3R5cGUoKTsKK30KKworLy8gUmV0dXJucyB0aGUgZnVsbHktcXVhbGlmaWVkIHR5cGUgbmFtZSBmaWVsZC0+bWVzc2FnZV90eXBlKCkuICBVc3VhbGx5IHRoaXMKKy8vIGlzIGp1c3QgQ2xhc3NOYW1lKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgdHJ1ZSk7CitzdHJpbmcgRmllbGRNZXNzYWdlVHlwZU5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKy8vIFN0cmlwcyAiLnByb3RvIiBvciAiLnByb3RvZGV2ZWwiIGZyb20gdGhlIGVuZCBvZiBhIGZpbGVuYW1lLgorc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisKKy8vIEdldCB0aGUgQysrIHR5cGUgbmFtZSBmb3IgYSBwcmltaXRpdmUgdHlwZSAoZS5nLiAiZG91YmxlIiwgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIiLCBldGMuKS4KKy8vIE5vdGU6ICBub24tYnVpbHQtaW4gdHlwZSBuYW1lcyB3aWxsIGJlIHF1YWxpZmllZCwgbWVhbmluZyB0aGV5IHdpbGwgc3RhcnQKKy8vIHdpdGggYSA6Oi4gIElmIHlvdSBhcmUgdXNpbmcgdGhlIHR5cGUgYXMgYSB0ZW1wbGF0ZSBwYXJhbWV0ZXIsIHlvdSB3aWxsCisvLyBuZWVkIHRvIGluc3VyZSB0aGVyZSBpcyBhIHNwYWNlIGJldHdlZW4gdGhlIDwgYW5kIHRoZSA6OiwgYmVjYXVzZSB0aGUKKy8vIHJpZGljdWxvdXMgQysrIHN0YW5kYXJkIGRlZmluZXMgIjw6IiB0byBiZSBhIHN5bm9ueW0gZm9yICJbIi4KK2NvbnN0IGNoYXIqIFByaW1pdGl2ZVR5cGVOYW1lKEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSB0eXBlKTsKKworLy8gR2V0IHRoZSBkZWNsYXJlZCB0eXBlIG5hbWUgaW4gQ2FtZWxDYXNlIGZvcm1hdCwgYXMgaXMgdXNlZCBlLmcuIGZvciB0aGUKKy8vIG1ldGhvZHMgb2YgV2lyZUZvcm1hdC4gIEZvciBleGFtcGxlLCBUWVBFX0lOVDMyIGJlY29tZXMgIkludDMyIi4KK2NvbnN0IGNoYXIqIERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpOworCisvLyBSZXR1cm4gdGhlIGNvZGUgdGhhdCBldmFsdWF0ZXMgdG8gdGhlIG51bWJlciB3aGVuIGNvbXBpbGVkLgorc3RyaW5nIEludDMyVG9TdHJpbmcoaW50IG51bWJlcik7CisKKy8vIFJldHVybiB0aGUgY29kZSB0aGF0IGV2YWx1YXRlcyB0byB0aGUgbnVtYmVyIHdoZW4gY29tcGlsZWQuCitzdHJpbmcgSW50NjRUb1N0cmluZyhpbnQ2NCBudW1iZXIpOworCisvLyBHZXQgY29kZSB0aGF0IGV2YWx1YXRlcyB0byB0aGUgZmllbGQncyBkZWZhdWx0IHZhbHVlLgorc3RyaW5nIERlZmF1bHRWYWx1ZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworLy8gQ29udmVydCBhIGZpbGUgbmFtZSBpbnRvIGEgdmFsaWQgaWRlbnRpZmllci4KK3N0cmluZyBGaWxlbmFtZUlkZW50aWZpZXIoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisKKy8vIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgQWRkRGVzY3JpcHRvcnMoKSBmdW5jdGlvbiBmb3IgYSBnaXZlbiBmaWxlLgorc3RyaW5nIEdsb2JhbEFkZERlc2NyaXB0b3JzTmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworLy8gUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBBc3NpZ25EZXNjcmlwdG9ycygpIGZ1bmN0aW9uIGZvciBhIGdpdmVuIGZpbGUuCitzdHJpbmcgR2xvYmFsQXNzaWduRGVzY3JpcHRvcnNOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisvLyBSZXR1cm4gdGhlIHF1YWxpZmllZCBDKysgbmFtZSBmb3IgYSBmaWxlIGxldmVsIHN5bWJvbC4KK3N0cmluZyBRdWFsaWZpZWRGaWxlTGV2ZWxTeW1ib2woY29uc3Qgc3RyaW5nJiBwYWNrYWdlLCBjb25zdCBzdHJpbmcmIG5hbWUpOworCisvLyBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIFNodXRkb3duRmlsZSgpIGZ1bmN0aW9uIGZvciBhIGdpdmVuIGZpbGUuCitzdHJpbmcgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworLy8gRXNjYXBlIEMrKyB0cmlncmFwaHMgYnkgZXNjYXBpbmcgcXVlc3Rpb24gbWFya3MgdG8gXD8KK3N0cmluZyBFc2NhcGVUcmlncmFwaHMoY29uc3Qgc3RyaW5nJiB0b19lc2NhcGUpOworCisvLyBFc2NhcGVkIGZ1bmN0aW9uIG5hbWUgdG8gZWxpbWluYXRlIG5hbWluZyBjb25mbGljdC4KK3N0cmluZyBTYWZlRnVuY3Rpb25OYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgpOworCisvLyBSZXR1cm5zIHRydWUgaWYgdW5rbm93biBmaWVsZHMgYXJlIHByZXNldmVkIGFmdGVyIHBhcnNpbmcuCitpbmxpbmUgYm9vbCBQcmVzZXJ2ZVVua25vd25GaWVsZHMoY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSkgeworICByZXR1cm4gbWVzc2FnZS0+ZmlsZSgpLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworLy8gSWYgUHJlc2VydmVVbmtub3duRmllbGRzKCkgaXMgdHJ1ZSwgZGV0ZXJtaW5lcyB3aGV0aGVyIHVua25vd24KKy8vIGZpZWxkcyB3aWxsIGJlIHN0b3JlZCBpbiBhbiBVbmtub3duRmllbGRTZXQgb3IgYSBzdHJpbmcuCisvLyBJZiBQcmVzZXJ2ZVVua25vd25GaWVsZHMoKSBpcyBmYWxzZSwgdGhpcyBtZXRob2Qgd2lsbCBub3QgYmUKKy8vIHVzZWQuCitpbmxpbmUgYm9vbCBVc2VVbmtub3duRmllbGRTZXQoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPSBGaWxlT3B0aW9uczo6TElURV9SVU5USU1FOworfQorCisKKy8vIERvZXMgdGhlIGZpbGUgaGF2ZSBhbnkgbWFwIGZpZWxkcywgbmVjZXNzaXRhdGluZyB0aGUgZmlsZSB0byBpbmNsdWRlCisvLyBtYXBfZmllbGRfaW5sLmggYW5kIG1hcC5oLgorYm9vbCBIYXNNYXBGaWVsZHMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisvLyBEb2VzIHRoaXMgZmlsZSBoYXZlIGFueSBlbnVtIHR5cGUgZGVmaW5pdGlvbnM/Citib29sIEhhc0VudW1EZWZpbml0aW9ucyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIERvZXMgdGhpcyBmaWxlIGhhdmUgZ2VuZXJhdGVkIHBhcnNpbmcsIHNlcmlhbGl6YXRpb24sIGFuZCBvdGhlcgorLy8gc3RhbmRhcmQgbWV0aG9kcyBmb3Igd2hpY2ggcmVmbGVjdGlvbi1iYXNlZCBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbnMgZXhpc3Q/CitpbmxpbmUgYm9vbCBIYXNHZW5lcmF0ZWRNZXRob2RzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0gRmlsZU9wdGlvbnM6OkNPREVfU0laRTsKK30KKworLy8gRG8gbWVzc2FnZSBjbGFzc2VzIGluIHRoaXMgZmlsZSBoYXZlIGRlc2NyaXB0b3IgYW5kIHJlZmxlY3Rpb24gbWV0aG9kcz8KK2lubGluZSBib29sIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0gRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK30KKworLy8gU2hvdWxkIHdlIGdlbmVyYXRlIGdlbmVyaWMgc2VydmljZXMgZm9yIHRoaXMgZmlsZT8KK2lubGluZSBib29sIEhhc0dlbmVyaWNTZXJ2aWNlcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICByZXR1cm4gZmlsZS0+c2VydmljZV9jb3VudCgpID4gMCAmJgorICAgICAgICAgZmlsZS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpICE9IEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUUgJiYKKyAgICAgICAgIGZpbGUtPm9wdGlvbnMoKS5jY19nZW5lcmljX3NlcnZpY2VzKCk7Cit9CisKKy8vIFNob3VsZCBzdHJpbmcgZmllbGRzIGluIHRoaXMgZmlsZSB2ZXJpZnkgdGhhdCB0aGVpciBjb250ZW50cyBhcmUgVVRGLTg/CitpbmxpbmUgYm9vbCBIYXNVdGY4VmVyaWZpY2F0aW9uKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0gRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK30KKworLy8gU2hvdWxkIHdlIGdlbmVyYXRlIGEgc2VwYXJhdGUsIHN1cGVyLW9wdGltaXplZCBjb2RlIHBhdGggZm9yIHNlcmlhbGl6aW5nIHRvCisvLyBmbGF0IGFycmF5cz8gIFdlIGRvbid0IGRvIHRoaXMgaW4gTGl0ZSBtb2RlIGJlY2F1c2Ugd2UnZCByYXRoZXIgcmVkdWNlIGNvZGUKKy8vIHNpemUuCitpbmxpbmUgYm9vbCBIYXNGYXN0QXJyYXlTZXJpYWxpemF0aW9uKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgPT0gRmlsZU9wdGlvbnM6OlNQRUVEOworfQorCisvLyBSZXR1cm5zIHdoZXRoZXIgd2UgaGF2ZSB0byBnZW5lcmF0ZSBjb2RlIHdpdGggc3RhdGljIGluaXRpYWxpemVycy4KK2Jvb2wgU3RhdGljSW5pdGlhbGl6ZXJzRm9yY2VkKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gUHJpbnRzICd3aXRoX3N0YXRpY19pbml0JyBpZiBzdGF0aWMgaW5pdGlhbGl6ZXJzIGhhdmUgdG8gYmUgdXNlZCBmb3IgdGhlCisvLyBwcm92aWRlZCBmaWxlLiBPdGhlcndpc2UgZW1pdHMgYm90aCAnd2l0aF9zdGF0aWNfaW5pdCcgYW5kCisvLyAnd2l0aG91dF9zdGF0aWNfaW5pdCcgdXNpbmcgI2lmZGVmLgordm9pZCBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IGNoYXIqIHdpdGhfc3RhdGljX2luaXQsIGNvbnN0IGNoYXIqIHdpdGhvdXRfc3RhdGljX2luaXQsCisgICAgY29uc3QgY2hhciogdmFyMSA9IE5VTEwsIGNvbnN0IHN0cmluZyYgdmFsMSA9ICIiLAorICAgIGNvbnN0IGNoYXIqIHZhcjIgPSBOVUxMLCBjb25zdCBzdHJpbmcmIHZhbDIgPSAiIik7CisKK3ZvaWQgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcnMsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBjaGFyKiB3aXRoX3N0YXRpY19pbml0LAorICAgIGNvbnN0IGNoYXIqIHdpdGhvdXRfc3RhdGljX2luaXQpOworCisKK2lubGluZSBib29sIElzTWFwRW50cnlNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tYXBfZW50cnkoKTsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBmaWVsZCdzIENQUFRZUEUgaXMgc3RyaW5nIG9yIG1lc3NhZ2UuCitib29sIElzU3RyaW5nT3JNZXNzYWdlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBGb3IgYSBzdHJpbmcgZmllbGQsIHJldHVybnMgdGhlIGVmZmVjdGl2ZSBjdHlwZS4gIElmIHRoZSBhY3R1YWwgY3R5cGUgaXMKKy8vIG5vdCBzdXBwb3J0ZWQsIHJldHVybnMgdGhlIGRlZmF1bHQgb2YgU1RSSU5HLgorRmllbGRPcHRpb25zOjpDVHlwZSBFZmZlY3RpdmVTdHJpbmdDVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3Qgc3RyaW5nJiBpbnB1dCwgYm9vbCBjYXBfbmV4dF9sZXR0ZXIpOworCitpbmxpbmUgYm9vbCBIYXNGaWVsZFByZXNlbmNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmICdlbnVtJyBzZW1hbnRpY3MgYXJlIHN1Y2ggdGhhdCB1bmtub3duIHZhbHVlcyBhcmUgcHJlc2VydmVkCisvLyBpbiB0aGUgZW51bSBmaWVsZCBpdHNlbGYsIHJhdGhlciB0aGFuIGdvaW5nIHRvIHRoZSBVbmtub3duRmllbGRTZXQuCitpbmxpbmUgYm9vbCBIYXNQcmVzZXJ2aW5nVW5rbm93bkVudW1TZW1hbnRpY3MoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCitpbmxpbmUgYm9vbCBTdXBwb3J0c0FyZW5hcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICByZXR1cm4gZmlsZS0+b3B0aW9ucygpLmNjX2VuYWJsZV9hcmVuYXMoKTsKK30KKworaW5saW5lIGJvb2wgU3VwcG9ydHNBcmVuYXMoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICByZXR1cm4gU3VwcG9ydHNBcmVuYXMoZGVzYy0+ZmlsZSgpKTsKK30KKworaW5saW5lIGJvb2wgU3VwcG9ydHNBcmVuYXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gU3VwcG9ydHNBcmVuYXMoZmllbGQtPmZpbGUoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9IRUxQRVJTX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGMzOGRiMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuY2MKQEAgLTAsMCArMSwzNDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitib29sIElzUHJvdG8zRmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlX2Rlc2NyaXB0b3IgPSBmaWVsZF9kZXNjcmlwdG9yLT5maWxlKCk7CisgIHJldHVybiBmaWxlX2Rlc2NyaXB0b3ItPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCit2b2lkIFNldE1lc3NhZ2VWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIHZhcmlhYmxlcywgb3B0aW9ucyk7CisgICgqdmFyaWFibGVzKVsidHlwZSJdID0gRmllbGRNZXNzYWdlVHlwZU5hbWUoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsic3RyZWFtX3dyaXRlciJdID0gKCp2YXJpYWJsZXMpWyJkZWNsYXJlZF90eXBlIl0gKworICAgICAgKEhhc0Zhc3RBcnJheVNlcmlhbGl6YXRpb24oZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPmZpbGUoKSkgPworICAgICAgICJNYXliZVRvQXJyYXkiIDoKKyAgICAgICAiIik7CisgICgqdmFyaWFibGVzKVsiZnVsbF9uYW1lIl0gPSBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleSA9CisgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWwgPQorICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfY3BwIl0gPSBQcmltaXRpdmVUeXBlTmFtZShrZXktPmNwcF90eXBlKCkpOworICBzd2l0Y2ggKHZhbC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAoKnZhcmlhYmxlcylbInZhbF9jcHAiXSA9IEZpZWxkTWVzc2FnZVR5cGVOYW1lKHZhbCk7CisgICAgICAoKnZhcmlhYmxlcylbIndyYXBwZXIiXSA9ICJFbnRyeVdyYXBwZXIiOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICgqdmFyaWFibGVzKVsidmFsX2NwcCJdID0gQ2xhc3NOYW1lKHZhbC0+ZW51bV90eXBlKCksIGZhbHNlKTsKKyAgICAgICgqdmFyaWFibGVzKVsid3JhcHBlciJdID0gIkVudW1FbnRyeVdyYXBwZXIiOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICgqdmFyaWFibGVzKVsidmFsX2NwcCJdID0gUHJpbWl0aXZlVHlwZU5hbWUodmFsLT5jcHBfdHlwZSgpKTsKKyAgICAgICgqdmFyaWFibGVzKVsid3JhcHBlciJdID0gIkVudHJ5V3JhcHBlciI7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJrZXlfd2lyZV90eXBlIl0gPQorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFXyIgKworICAgICAgVG9VcHBlcihEZWNsYXJlZFR5cGVNZXRob2ROYW1lKGtleS0+dHlwZSgpKSk7CisgICgqdmFyaWFibGVzKVsidmFsX3dpcmVfdHlwZSJdID0KKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV8iICsKKyAgICAgIFRvVXBwZXIoRGVjbGFyZWRUeXBlTWV0aG9kTmFtZSh2YWwtPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbIm1hcF9jbGFzc25hbWUiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKGludGVybmFsOjpXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvci0+ZmlsZSgpKSkgeworICAgICgqdmFyaWFibGVzKVsibGl0ZSJdID0gIiI7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJsaXRlIl0gPSAiTGl0ZSI7CisgIH0KKworICBpZiAoIUlzUHJvdG8zRmllbGQoZGVzY3JpcHRvcikgJiYKKyAgICAgIHZhbC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZGVmYXVsdF92YWx1ZSA9IHZhbC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCk7CisgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2VudW1fdmFsdWUiXSA9IEludDMyVG9TdHJpbmcoZGVmYXVsdF92YWx1ZS0+bnVtYmVyKCkpOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9lbnVtX3ZhbHVlIl0gPSAiMCI7CisgIH0KK30KKworTWFwRmllbGRHZW5lcmF0b3I6OgorTWFwRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7Cit9CisKK01hcEZpZWxkR2VuZXJhdG9yOjp+TWFwRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ0eXBlZGVmIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok1hcEVudHJ5TGl0ZTxcbiIKKyAgICAgICIgICAgJGtleV9jcHAkLCAkdmFsX2NwcCQsXG4iCisgICAgICAiICAgICRrZXlfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgJHZhbF93aXJlX3R5cGUkLFxuIgorICAgICAgIiAgICAkZGVmYXVsdF9lbnVtX3ZhbHVlJCA+XG4iCisgICAgICAiICAgICRtYXBfY2xhc3NuYW1lJDtcbiIKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpNYXBGaWVsZCRsaXRlJDxcbiIKKyAgICAgICIgICAgJGtleV9jcHAkLCAkdmFsX2NwcCQsXG4iCisgICAgICAiICAgICRrZXlfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgJHZhbF93aXJlX3R5cGUkLFxuIgorICAgICAgIiAgICAkZGVmYXVsdF9lbnVtX3ZhbHVlJCA+ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID4mXG4iCisgICAgICAiICAgICRuYW1lJCgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6Ok1hcDwgJGtleV9jcHAkLCAkdmFsX2NwcCQgPipcbiIKKyAgICAgICIgICAgbXV0YWJsZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID4mXG4iCisgICAgICAiJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tYXA6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXy5HZXRNYXAoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID4qXG4iCisgICAgICAiJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbWFwOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uTXV0YWJsZU1hcCgpO1xuIgorICAgICAgIn1cbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLkNsZWFyKCk7XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLk1lcmdlRnJvbShmcm9tLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uU3dhcCgmb3RoZXItPiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uU2V0QXNzaWduRGVzY3JpcHRvckNhbGxiYWNrKFxuIgorICAgICAgICAiICAgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSk7XG4iCisgICAgICAgICIkbmFtZSRfLlNldEVudHJ5RGVzY3JpcHRvcihcbiIKKyAgICAgICAgIiAgICAmJHR5cGUkX2Rlc2NyaXB0b3JfKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2ZpZWxkID0KKyAgICAgIGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjwkbWFwX2NsYXNzbmFtZSQ+IGVudHJ5KCRuYW1lJF8uTmV3RW50cnkoKSk7XG4iKTsKKworICBpZiAoSXNQcm90bzNGaWVsZChkZXNjcmlwdG9yXykgfHwKKyAgICAgIHZhbHVlX2ZpZWxkLT50eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbChcbiIKKyAgICAgICAgIiAgICBpbnB1dCwgZW50cnkuZ2V0KCkpKTtcbiIpOworICAgIHN3aXRjaCAodmFsdWVfZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgICAiKCptdXRhYmxlXyRuYW1lJCgpKVtlbnRyeS0+a2V5KCldLlN3YXAoIgorICAgICAgICAgICAgImVudHJ5LT5tdXRhYmxlX3ZhbHVlKCkpO1xuIik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAgICIoKm11dGFibGVfJG5hbWUkKCkpW2VudHJ5LT5rZXkoKV0gPVxuIgorICAgICAgICAgICAgIiAgICBzdGF0aWNfY2FzdDwkdmFsX2NwcCQ+KCplbnRyeS0+bXV0YWJsZV92YWx1ZSgpKTtcbiIpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgICAiKCptdXRhYmxlXyRuYW1lJCgpKVtlbnRyeS0+a2V5KCldID0gKmVudHJ5LT5tdXRhYmxlX3ZhbHVlKCk7XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJ7XG4iCisgICAgICAgICIgIDo6c3RkOjpzdHJpbmcgZGF0YTtcbiIKKyAgICAgICAgIiAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKGlucHV0LCAmZGF0YSkpO1xuIgorICAgICAgICAiICBET18oZW50cnktPlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7XG4iCisgICAgICAgICIgIGlmICgkdmFsX2NwcCRfSXNWYWxpZCgqZW50cnktPm11dGFibGVfdmFsdWUoKSkpIHtcbiIKKyAgICAgICAgIiAgICAoKm11dGFibGVfJG5hbWUkKCkpW2VudHJ5LT5rZXkoKV0gPVxuIgorICAgICAgICAiICAgICAgICBzdGF0aWNfY2FzdDwkdmFsX2NwcCQ+KCplbnRyeS0+bXV0YWJsZV92YWx1ZSgpKTtcbiIKKyAgICAgICAgIiAgfSBlbHNlIHtcbiIpOworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAiICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSIKKyAgICAgICAgICAiLT5BZGRMZW5ndGhEZWxpbWl0ZWQoJG51bWJlciQsIGRhdGEpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMigkdGFnJCk7XG4iCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMihkYXRhLnNpemUoKSk7XG4iCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVTdHJpbmcoZGF0YSk7XG4iKTsKKyAgICB9CisKKworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaWYgKGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIGVudHJ5LnJlbGVhc2UoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8JG1hcF9jbGFzc25hbWUkPiBlbnRyeTtcbiIKKyAgICAgICIgIGZvciAoOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID46OmNvbnN0X2l0ZXJhdG9yXG4iCisgICAgICAiICAgICAgaXQgPSAkbmFtZSQoKS5iZWdpbigpOyBpdCAhPSAkbmFtZSQoKS5lbmQoKTsgKytpdCkge1xuIik7CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICAgIGlmIChlbnRyeS5nZXQoKSAhPSBOVUxMICYmIGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGVudHJ5LnJlc2V0KCRuYW1lJF8uTmV3JHdyYXBwZXIkKGl0LT5maXJzdCwgaXQtPnNlY29uZCkpO1xuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGUkc3RyZWFtX3dyaXRlciQoXG4iCisgICAgICAiICAgICAgICAkbnVtYmVyJCwgKmVudHJ5LCBvdXRwdXQpO1xuIgorICAgICAgIiAgfVxuIik7CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICBpZiAoZW50cnkuZ2V0KCkgIT0gTlVMTCAmJiBlbnRyeS0+R2V0QXJlbmEoKSAhPSBOVUxMKSB7XG4iCisgICAgICAgICIgICAgZW50cnkucmVsZWFzZSgpO1xuIgorICAgICAgICAiICB9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8JG1hcF9jbGFzc25hbWUkPiBlbnRyeTtcbiIKKyAgICAgICIgIGZvciAoOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID46OmNvbnN0X2l0ZXJhdG9yXG4iCisgICAgICAiICAgICAgaXQgPSAkbmFtZSQoKS5iZWdpbigpOyBpdCAhPSAkbmFtZSQoKS5lbmQoKTsgKytpdCkge1xuIik7CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICAgIGlmIChlbnRyeS5nZXQoKSAhPSBOVUxMICYmIGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGVudHJ5LnJlc2V0KCRuYW1lJF8uTmV3JHdyYXBwZXIkKGl0LT5maXJzdCwgaXQtPnNlY29uZCkpO1xuIgorICAgICAgIiAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6XG4iCisgICAgICAiICAgICAgICBXcml0ZSRkZWNsYXJlZF90eXBlJE5vVmlydHVhbFRvQXJyYXkoXG4iCisgICAgICAiICAgICAgICAgICAgJG51bWJlciQsICplbnRyeSwgdGFyZ2V0KTtcbiIKKyAgICAgICIgIH1cbiIpOworCisgIC8vIElmIGVudHJ5IGlzIGFsbG9jYXRlZCBieSBhcmVuYSwgaXRzIGRlc2N0cnVjdG9yIHNob3VsZCBiZSBhdm9pZGVkLgorICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgaWYgKGVudHJ5LmdldCgpICE9IE5VTEwgJiYgZW50cnktPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgfVxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRvdGFsX3NpemUgKz0gJHRhZ19zaXplJCAqIHRoaXMtPiRuYW1lJF9zaXplKCk7XG4iCisgICAgICAie1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPCRtYXBfY2xhc3NuYW1lJD4gZW50cnk7XG4iCisgICAgICAiICBmb3IgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCAka2V5X2NwcCQsICR2YWxfY3BwJCA+Ojpjb25zdF9pdGVyYXRvclxuIgorICAgICAgIiAgICAgIGl0ID0gJG5hbWUkKCkuYmVnaW4oKTsgaXQgIT0gJG5hbWUkKCkuZW5kKCk7ICsraXQpIHtcbiIpOworCisgIC8vIElmIGVudHJ5IGlzIGFsbG9jYXRlZCBieSBhcmVuYSwgaXRzIGRlc2N0cnVjdG9yIHNob3VsZCBiZSBhdm9pZGVkLgorICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgICBpZiAoZW50cnkuZ2V0KCkgIT0gTlVMTCAmJiBlbnRyeS0+R2V0QXJlbmEoKSAhPSBOVUxMKSB7XG4iCisgICAgICAgICIgICAgICBlbnRyeS5yZWxlYXNlKCk7XG4iCisgICAgICAgICIgICAgfVxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICBlbnRyeS5yZXNldCgkbmFtZSRfLk5ldyR3cmFwcGVyJChpdC0+Zmlyc3QsIGl0LT5zZWNvbmQpKTtcbiIKKyAgICAgICIgICAgdG90YWxfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6XG4iCisgICAgICAiICAgICAgICAkZGVjbGFyZWRfdHlwZSRTaXplTm9WaXJ0dWFsKCplbnRyeSk7XG4iCisgICAgICAiICB9XG4iKTsKKworICAvLyBJZiBlbnRyeSBpcyBhbGxvY2F0ZWQgYnkgYXJlbmEsIGl0cyBkZXNjdHJ1Y3RvciBzaG91bGQgYmUgYXZvaWRlZC4KKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgIGlmIChlbnRyeS5nZXQoKSAhPSBOVUxMICYmIGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICBlbnRyeS5yZWxlYXNlKCk7XG4iCisgICAgICAgICIgIH1cbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21hcF9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21hcF9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyN2Q0ODUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmgKQEAgLTAsMCArMSw3NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NQVBfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfTUFQX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2VfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitjbGFzcyBNYXBGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNYXBGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+TWFwRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNYXBGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfTUFQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYWZhMzZmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2UuY2MKQEAgLTAsMCArMSwzMzU0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHNldD4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit2b2lkIFByaW50RmllbGRDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIFByaW50IHRoZSBmaWVsZCdzIHByb3RvLXN5bnRheCBkZWZpbml0aW9uIGFzIGEgY29tbWVudC4gIFdlIGRvbid0IHdhbnQgdG8KKyAgLy8gcHJpbnQgZ3JvdXAgYm9kaWVzIHNvIHdlIGN1dCBvZmYgYWZ0ZXIgdGhlIGZpcnN0IGxpbmUuCisgIHN0cmluZyBkZWYgPSBmaWVsZC0+RGVidWdTdHJpbmcoKTsKKyAgcHJpbnRlci0+UHJpbnQoIi8vICRkZWYkXG4iLAorICAgICJkZWYiLCBkZWYuc3Vic3RyKDAsIGRlZi5maW5kX2ZpcnN0X29mKCdcbicpKSk7Cit9CisKK3N0cnVjdCBGaWVsZE9yZGVyaW5nQnlOdW1iZXIgeworICBpbmxpbmUgYm9vbCBvcGVyYXRvcigpKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYS0+bnVtYmVyKCkgPCBiLT5udW1iZXIoKTsKKyAgfQorfTsKKworLy8gU29ydCB0aGUgZmllbGRzIG9mIHRoZSBnaXZlbiBEZXNjcmlwdG9yIGJ5IG51bWJlciBpbnRvIGEgbmV3W10nZCBhcnJheQorLy8gYW5kIHJldHVybiBpdC4KK2NvbnN0IEZpZWxkRGVzY3JpcHRvcioqIFNvcnRGaWVsZHNCeU51bWJlcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioqIGZpZWxkcyA9CisgICAgbmV3IGNvbnN0IEZpZWxkRGVzY3JpcHRvcipbZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKV07CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRzW2ldID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgIH0KKyAgc3RkOjpzb3J0KGZpZWxkcywgZmllbGRzICsgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKSwKKyAgICAgICAgICAgIEZpZWxkT3JkZXJpbmdCeU51bWJlcigpKTsKKyAgcmV0dXJuIGZpZWxkczsKK30KKworLy8gRnVuY3RvciBmb3Igc29ydGluZyBleHRlbnNpb24gcmFuZ2VzIGJ5IHRoZWlyICJzdGFydCIgZmllbGQgbnVtYmVyLgorc3RydWN0IEV4dGVuc2lvblJhbmdlU29ydGVyIHsKKyAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiBsZWZ0LAorICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJpZ2h0KSBjb25zdCB7CisgICAgcmV0dXJuIGxlZnQtPnN0YXJ0IDwgcmlnaHQtPnN0YXJ0OworICB9Cit9OworCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlICJyZXF1aXJlZCIgcmVzdHJpY3Rpb24gY2hlY2sgc2hvdWxkIGJlIGlnbm9yZWQgZm9yIHRoZQorLy8gZ2l2ZW4gZmllbGQuCitpbmxpbmUgc3RhdGljIGJvb2wgU2hvdWxkSWdub3JlUmVxdWlyZWRGaWVsZENoZWNrKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIGZhbHNlOworfQorCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG1lc3NhZ2UgdHlwZSBoYXMgYW55IHJlcXVpcmVkIGZpZWxkcy4gIElmIGl0IGRvZXNuJ3QsCisvLyB3ZSBjYW4gb3B0aW1pemUgb3V0IGNhbGxzIHRvIGl0cyBJc0luaXRpYWxpemVkKCkgbWV0aG9kLgorLy8KKy8vIGFscmVhZHlfc2VlbiBpcyB1c2VkIHRvIGF2b2lkIGNoZWNraW5nIHRoZSBzYW1lIHR5cGUgbXVsdGlwbGUgdGltZXMKKy8vIChhbmQgYWxzbyB0byBwcm90ZWN0IGFnYWluc3QgcmVjdXJzaW9uKS4KK3N0YXRpYyBib29sIEhhc1JlcXVpcmVkRmllbGRzKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUsCisgICAgaGFzaF9zZXQ8Y29uc3QgRGVzY3JpcHRvcio+KiBhbHJlYWR5X3NlZW4pIHsKKyAgaWYgKGFscmVhZHlfc2Vlbi0+Y291bnQodHlwZSkgPiAwKSB7CisgICAgLy8gU2luY2UgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYSByZXF1aXJlZCBmaWVsZCBjYXVzZXMgdGhlIHdob2xlCisgICAgLy8gZnVuY3Rpb24gdG8gcmV0dXJuIHRydWUsIHdlIGNhbiBhc3N1bWUgdGhhdCBpZiB0aGUgdHlwZSBpcyBhbHJlYWR5CisgICAgLy8gaW4gdGhlIGNhY2hlIGl0IGRpZG4ndCBoYXZlIGFueSByZXF1aXJlZCBmaWVsZHMuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGFscmVhZHlfc2Vlbi0+aW5zZXJ0KHR5cGUpOworCisgIC8vIElmIHRoZSB0eXBlIGhhcyBleHRlbnNpb25zLCBhbiBleHRlbnNpb24gd2l0aCBtZXNzYWdlIHR5cGUgY291bGQgY29udGFpbgorICAvLyByZXF1aXJlZCBmaWVsZHMsIHNvIHdlIGhhdmUgdG8gYmUgY29uc2VydmF0aXZlIGFuZCBhc3N1bWUgc3VjaCBhbgorICAvLyBleHRlbnNpb24gZXhpc3RzLgorICBpZiAodHlwZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSByZXR1cm4gdHJ1ZTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSB0eXBlLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgIVNob3VsZElnbm9yZVJlcXVpcmVkRmllbGRDaGVjayhmaWVsZCkpIHsKKyAgICAgIGlmIChIYXNSZXF1aXJlZEZpZWxkcyhmaWVsZC0+bWVzc2FnZV90eXBlKCksIGFscmVhZHlfc2VlbikpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIGZhbHNlOworfQorCitzdGF0aWMgYm9vbCBIYXNSZXF1aXJlZEZpZWxkcyhjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSB7CisgIGhhc2hfc2V0PGNvbnN0IERlc2NyaXB0b3IqPiBhbHJlYWR5X3NlZW47CisgIHJldHVybiBIYXNSZXF1aXJlZEZpZWxkcyh0eXBlLCAmYWxyZWFkeV9zZWVuKTsKK30KKworLy8gVGhpcyByZXR1cm5zIGFuIGVzdGltYXRlIG9mIHRoZSBjb21waWxlcidzIGFsaWdubWVudCBmb3IgdGhlIGZpZWxkLiAgVGhpcworLy8gY2FuJ3QgZ3VhcmFudGVlIHRvIGJlIGNvcnJlY3QgYmVjYXVzZSB0aGUgZ2VuZXJhdGVkIGNvZGUgY291bGQgYmUgY29tcGlsZWQgb24KKy8vIGRpZmZlcmVudCBzeXN0ZW1zIHdpdGggZGlmZmVyZW50IGFsaWdubWVudCBydWxlcy4gIFRoZSBlc3RpbWF0ZXMgYmVsb3cgYXNzdW1lCisvLyA2NC1iaXQgcG9pbnRlcnMuCitpbnQgRXN0aW1hdGVBbGlnbm1lbnRTaXplKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKGZpZWxkID09IE5VTEwpIHJldHVybiAwOworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHJldHVybiA4OworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiAxOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gNDsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gODsKKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIC0xOyAgLy8gTWFrZSBjb21waWxlciBoYXBweS4KK30KKworLy8gRmllbGRHcm91cCBpcyBqdXN0IGEgaGVscGVyIGZvciBPcHRpbWl6ZVBhZGRpbmcgYmVsb3cuICBJdCBob2xkcyBhIHZlY3RvciBvZgorLy8gZmllbGRzIHRoYXQgYXJlIGdyb3VwZWQgdG9nZXRoZXIgYmVjYXVzZSB0aGV5IGhhdmUgY29tcGF0aWJsZSBhbGlnbm1lbnQsIGFuZAorLy8gYSBwcmVmZXJyZWQgbG9jYXRpb24gaW4gdGhlIGZpbmFsIGZpZWxkIG9yZGVyaW5nLgorY2xhc3MgRmllbGRHcm91cCB7CisgcHVibGljOgorICBGaWVsZEdyb3VwKCkKKyAgICAgIDogcHJlZmVycmVkX2xvY2F0aW9uXygwKSB7fQorCisgIC8vIEEgZ3JvdXAgd2l0aCBhIHNpbmdsZSBmaWVsZC4KKyAgRmllbGRHcm91cChmbG9hdCBwcmVmZXJyZWRfbG9jYXRpb24sIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpCisgICAgICA6IHByZWZlcnJlZF9sb2NhdGlvbl8ocHJlZmVycmVkX2xvY2F0aW9uKSwKKyAgICAgICAgZmllbGRzXygxLCBmaWVsZCkge30KKworICAvLyBBcHBlbmQgdGhlIGZpZWxkcyBpbiAnb3RoZXInIHRvIHRoaXMgZ3JvdXAuCisgIHZvaWQgQXBwZW5kKGNvbnN0IEZpZWxkR3JvdXAmIG90aGVyKSB7CisgICAgaWYgKG90aGVyLmZpZWxkc18uZW1wdHkoKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvLyBQcmVmZXJyZWQgbG9jYXRpb24gaXMgdGhlIGF2ZXJhZ2UgYW1vbmcgYWxsIHRoZSBmaWVsZHMsIHNvIHdlIHdlaWdodCBieQorICAgIC8vIHRoZSBudW1iZXIgb2YgZmllbGRzIG9uIGVhY2ggRmllbGRHcm91cCBvYmplY3QuCisgICAgcHJlZmVycmVkX2xvY2F0aW9uXyA9CisgICAgICAgIChwcmVmZXJyZWRfbG9jYXRpb25fICogZmllbGRzXy5zaXplKCkgKworICAgICAgICAgKG90aGVyLnByZWZlcnJlZF9sb2NhdGlvbl8gKiBvdGhlci5maWVsZHNfLnNpemUoKSkpIC8KKyAgICAgICAgKGZpZWxkc18uc2l6ZSgpICsgb3RoZXIuZmllbGRzXy5zaXplKCkpOworICAgIGZpZWxkc18uaW5zZXJ0KGZpZWxkc18uZW5kKCksIG90aGVyLmZpZWxkc18uYmVnaW4oKSwgb3RoZXIuZmllbGRzXy5lbmQoKSk7CisgIH0KKworICB2b2lkIFNldFByZWZlcnJlZExvY2F0aW9uKGZsb2F0IGxvY2F0aW9uKSB7IHByZWZlcnJlZF9sb2NhdGlvbl8gPSBsb2NhdGlvbjsgfQorICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcygpIGNvbnN0IHsgcmV0dXJuIGZpZWxkc187IH0KKworICAvLyBGaWVsZEdyb3VwIG9iamVjdHMgc29ydCBieSB0aGVpciBwcmVmZXJyZWQgbG9jYXRpb24uCisgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IEZpZWxkR3JvdXAmIG90aGVyKSBjb25zdCB7CisgICAgcmV0dXJuIHByZWZlcnJlZF9sb2NhdGlvbl8gPCBvdGhlci5wcmVmZXJyZWRfbG9jYXRpb25fOworICB9CisKKyBwcml2YXRlOgorICAvLyAicHJlZmVycmVkX2xvY2F0aW9uXyIgaXMgYW4gZXN0aW1hdGUgb2Ygd2hlcmUgdGhpcyBncm91cCBzaG91bGQgZ28gaW4gdGhlCisgIC8vIGZpbmFsIGxpc3Qgb2YgZmllbGRzLiAgV2UgY29tcHV0ZSB0aGlzIGJ5IHRha2luZyB0aGUgYXZlcmFnZSBpbmRleCBvZiBlYWNoCisgIC8vIGZpZWxkIGluIHRoaXMgZ3JvdXAgaW4gdGhlIG9yaWdpbmFsIG9yZGVyaW5nIG9mIGZpZWxkcy4gIFRoaXMgaXMgdmVyeQorICAvLyBhcHByb3hpbWF0ZSwgYnV0IHNob3VsZCBwdXQgdGhpcyBncm91cCBjbG9zZSB0byB3aGVyZSBpdHMgbWVtYmVyIGZpZWxkcworICAvLyBvcmlnaW5hbGx5IHdlbnQuCisgIGZsb2F0IHByZWZlcnJlZF9sb2NhdGlvbl87CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHNfOworICAvLyBXZSByZWx5IG9uIHRoZSBkZWZhdWx0IGNvcHkgY29uc3RydWN0b3IgYW5kIG9wZXJhdG9yPSBzbyB0aGlzIHR5cGUgY2FuIGJlCisgIC8vIHVzZWQgaW4gYSB2ZWN0b3IuCit9OworCisvLyBSZW9yZGVyICdmaWVsZHMnIHNvIHRoYXQgaWYgdGhlIGZpZWxkcyBhcmUgb3V0cHV0IGludG8gYSBjKysgY2xhc3MgaW4gdGhlIG5ldworLy8gb3JkZXIsIHRoZSBhbGlnbm1lbnQgcGFkZGluZyBpcyBtaW5pbWl6ZWQuICBXZSB0cnkgdG8gZG8gdGhpcyB3aGlsZSBrZWVwaW5nCisvLyBlYWNoIGZpZWxkIGFzIGNsb3NlIGFzIHBvc3NpYmxlIHRvIGl0cyBvcmlnaW5hbCBwb3NpdGlvbiBzbyB0aGF0IHdlIGRvbid0CisvLyByZWR1Y2UgY2FjaGUgbG9jYWxpdHkgbXVjaCBmb3IgZnVuY3Rpb24gdGhhdCBhY2Nlc3MgZWFjaCBmaWVsZCBpbiBvcmRlci4KK3ZvaWQgT3B0aW1pemVQYWRkaW5nKHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogZmllbGRzKSB7CisgIC8vIEZpcnN0IGRpdmlkZSBmaWVsZHMgaW50byB0aG9zZSB0aGF0IGFsaWduIHRvIDEgYnl0ZSwgNCBieXRlcyBvciA4IGJ5dGVzLgorICB2ZWN0b3I8RmllbGRHcm91cD4gYWxpZ25lZF90b18xLCBhbGlnbmVkX3RvXzQsIGFsaWduZWRfdG9fODsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMtPnNpemUoKTsgKytpKSB7CisgICAgc3dpdGNoIChFc3RpbWF0ZUFsaWdubWVudFNpemUoKCpmaWVsZHMpW2ldKSkgeworICAgICAgY2FzZSAxOiBhbGlnbmVkX3RvXzEucHVzaF9iYWNrKEZpZWxkR3JvdXAoaSwgKCpmaWVsZHMpW2ldKSk7IGJyZWFrOworICAgICAgY2FzZSA0OiBhbGlnbmVkX3RvXzQucHVzaF9iYWNrKEZpZWxkR3JvdXAoaSwgKCpmaWVsZHMpW2ldKSk7IGJyZWFrOworICAgICAgY2FzZSA4OiBhbGlnbmVkX3RvXzgucHVzaF9iYWNrKEZpZWxkR3JvdXAoaSwgKCpmaWVsZHMpW2ldKSk7IGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVua25vd24gYWxpZ25tZW50IHNpemUuIjsKKyAgICB9CisgIH0KKworICAvLyBOb3cgZ3JvdXAgZmllbGRzIGFsaWduZWQgdG8gMSBieXRlIGludG8gc2V0cyBvZiA0LCBhbmQgdHJlYXQgdGhvc2UgbGlrZSBhCisgIC8vIHNpbmdsZSBmaWVsZCBhbGlnbmVkIHRvIDQgYnl0ZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxpZ25lZF90b18xLnNpemUoKTsgaSArPSA0KSB7CisgICAgRmllbGRHcm91cCBmaWVsZF9ncm91cDsKKyAgICBmb3IgKGludCBqID0gaTsgaiA8IGFsaWduZWRfdG9fMS5zaXplKCkgJiYgaiA8IGkgKyA0OyArK2opIHsKKyAgICAgIGZpZWxkX2dyb3VwLkFwcGVuZChhbGlnbmVkX3RvXzFbal0pOworICAgIH0KKyAgICBhbGlnbmVkX3RvXzQucHVzaF9iYWNrKGZpZWxkX2dyb3VwKTsKKyAgfQorICAvLyBTb3J0IGJ5IHByZWZlcnJlZCBsb2NhdGlvbiB0byBrZWVwIGZpZWxkcyBhcyBjbG9zZSB0byB0aGVpciBvcmlnaW5hbAorICAvLyBsb2NhdGlvbiBhcyBwb3NzaWJsZS4gIFVzaW5nIHN0YWJsZV9zb3J0IGVuc3VyZXMgdGhhdCB0aGUgb3V0cHV0IGlzCisgIC8vIGNvbnNpc3RlbnQgYWNyb3NzIHJ1bnMuCisgIHN0ZDo6c3RhYmxlX3NvcnQoYWxpZ25lZF90b180LmJlZ2luKCksIGFsaWduZWRfdG9fNC5lbmQoKSk7CisKKyAgLy8gTm93IGdyb3VwIGZpZWxkcyBhbGlnbmVkIHRvIDQgYnl0ZXMgKG9yIHRoZSA0LWZpZWxkIGdyb3VwcyBjcmVhdGVkIGFib3ZlKQorICAvLyBpbnRvIHBhaXJzLCBhbmQgdHJlYXQgdGhvc2UgbGlrZSBhIHNpbmdsZSBmaWVsZCBhbGlnbmVkIHRvIDggYnl0ZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxpZ25lZF90b180LnNpemUoKTsgaSArPSAyKSB7CisgICAgRmllbGRHcm91cCBmaWVsZF9ncm91cDsKKyAgICBmb3IgKGludCBqID0gaTsgaiA8IGFsaWduZWRfdG9fNC5zaXplKCkgJiYgaiA8IGkgKyAyOyArK2opIHsKKyAgICAgIGZpZWxkX2dyb3VwLkFwcGVuZChhbGlnbmVkX3RvXzRbal0pOworICAgIH0KKyAgICBpZiAoaSA9PSBhbGlnbmVkX3RvXzQuc2l6ZSgpIC0gMSkgeworICAgICAgLy8gTW92ZSBpbmNvbXBsZXRlIDQtYnl0ZSBibG9jayB0byB0aGUgZW5kLgorICAgICAgZmllbGRfZ3JvdXAuU2V0UHJlZmVycmVkTG9jYXRpb24oZmllbGRzLT5zaXplKCkgKyAxKTsKKyAgICB9CisgICAgYWxpZ25lZF90b184LnB1c2hfYmFjayhmaWVsZF9ncm91cCk7CisgIH0KKyAgLy8gU29ydCBieSBwcmVmZXJyZWQgbG9jYXRpb24uCisgIHN0ZDo6c3RhYmxlX3NvcnQoYWxpZ25lZF90b184LmJlZ2luKCksIGFsaWduZWRfdG9fOC5lbmQoKSk7CisKKyAgLy8gTm93IHB1bGwgb3V0IGFsbCB0aGUgRmllbGREZXNjcmlwdG9ycyBpbiBvcmRlci4KKyAgZmllbGRzLT5jbGVhcigpOworICBmb3IgKGludCBpID0gMDsgaSA8IGFsaWduZWRfdG9fOC5zaXplKCk7ICsraSkgeworICAgIGZpZWxkcy0+aW5zZXJ0KGZpZWxkcy0+ZW5kKCksCisgICAgICAgICAgICAgICAgICAgYWxpZ25lZF90b184W2ldLmZpZWxkcygpLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgYWxpZ25lZF90b184W2ldLmZpZWxkcygpLmVuZCgpKTsKKyAgfQorfQorCisvLyBFbWl0cyBhbiBpZi1zdGF0ZW1lbnQgd2l0aCBhIGNvbmRpdGlvbiB0aGF0IGV2YWx1YXRlcyB0byB0cnVlIGlmIHxmaWVsZHwgaXMKKy8vIGNvbnNpZGVyZWQgbm9uLWRlZmF1bHQgKHdpbGwgYmUgc2VudCBvdmVyIHRoZSB3aXJlKSwgZm9yIG1lc3NhZ2UgdHlwZXMKKy8vIHdpdGhvdXQgdHJ1ZSBmaWVsZCBwcmVzZW5jZS4gU2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmCisvLyAhSGFzRmllbGRQcmVzZW5jZShtZXNzYWdlX2Rlc2NyaXB0b3IpLgorYm9vbCBFbWl0RmllbGROb25EZWZhdWx0Q29uZGl0aW9uKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgLy8gTWVyZ2UgYW5kIHNlcmlhbGl6ZSBzZW1hbnRpY3M6IHByaW1pdGl2ZSBmaWVsZHMgYXJlIG1lcmdlZC9zZXJpYWxpemVkIG9ubHkKKyAgLy8gaWYgbm9uLXplcm8gKG51bWVyaWMpIG9yIG5vbi1lbXB0eSAoc3RyaW5nKS4KKyAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiAhZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaWYgKCRwcmVmaXgkJG5hbWUkKCkuc2l6ZSgpID4gMCkge1xuIiwKKyAgICAgICAgICAicHJlZml4IiwgcHJlZml4LAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgfSBlbHNlIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgLy8gTWVzc2FnZSBmaWVsZHMgc3RpbGwgaGF2ZSBoYXNfJG5hbWUkKCkgbWV0aG9kcy4KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoJHByZWZpeCRoYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgInByZWZpeCIsIHByZWZpeCwKKyAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShmaWVsZCkpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaWYgKCRwcmVmaXgkJG5hbWUkKCkgIT0gMCkge1xuIiwKKyAgICAgICAgICAicHJlZml4IiwgcHJlZml4LAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgfQorICAgIHByaW50ZXItPkluZGVudCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlmIChoYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCisvLyBEb2VzIHRoZSBnaXZlbiBmaWVsZCBoYXZlIGEgaGFzXyRuYW1lJCgpIG1ldGhvZD8KK2Jvb2wgSGFzSGFzTWV0aG9kKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZmllbGQtPmZpbGUoKSkpIHsKKyAgICAvLyBJbiBwcm90bzEvcHJvdG8yLCBldmVyeSBmaWVsZCBoYXMgYSBoYXNfJG5hbWUkKCkgbWV0aG9kLgorICAgIHJldHVybiB0cnVlOworICB9CisgIC8vIEZvciBtZXNzYWdlIHR5cGVzIHdpdGhvdXQgdHJ1ZSBmaWVsZCBwcmVzZW5jZSwgb25seSBmaWVsZHMgd2l0aCBhIG1lc3NhZ2UKKyAgLy8gdHlwZSBoYXZlIGEgaGFzXyRuYW1lJCgpIG1ldGhvZC4KKyAgcmV0dXJuIGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOworfQorCisvLyBDb2xsZWN0cyBtYXAgZW50cnkgbWVzc2FnZSB0eXBlIGluZm9ybWF0aW9uLgordm9pZCBDb2xsZWN0TWFwSW5mbyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgR09PR0xFX0NIRUNLKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3IpKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXkiXSA9IFByaW1pdGl2ZVR5cGVOYW1lKGtleS0+Y3BwX3R5cGUoKSk7CisgIHN3aXRjaCAodmFsLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICgqdmFyaWFibGVzKVsidmFsIl0gPSBGaWVsZE1lc3NhZ2VUeXBlTmFtZSh2YWwpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICgqdmFyaWFibGVzKVsidmFsIl0gPSBDbGFzc05hbWUodmFsLT5lbnVtX3R5cGUoKSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICgqdmFyaWFibGVzKVsidmFsIl0gPSBQcmltaXRpdmVUeXBlTmFtZSh2YWwtPmNwcF90eXBlKCkpOworICB9CisgICgqdmFyaWFibGVzKVsia2V5X3dpcmVfdHlwZSJdID0KKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV8iICsKKyAgICAgIFRvVXBwZXIoRGVjbGFyZWRUeXBlTWV0aG9kTmFtZShrZXktPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbInZhbF93aXJlX3R5cGUiXSA9CisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfIiArCisgICAgICBUb1VwcGVyKERlY2xhcmVkVHlwZU1ldGhvZE5hbWUodmFsLT50eXBlKCkpKTsKK30KKworLy8gRG9lcyB0aGUgZ2l2ZW4gZmllbGQgaGF2ZSBhIHByaXZhdGUgKGludGVybmFsIGhlbHBlciBvbmx5KSBoYXNfJG5hbWUkKCkKKy8vIG1ldGhvZD8KK2Jvb2wgSGFzUHJpdmF0ZUhhc01ldGhvZChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIE9ubHkgZm9yIG9uZW9mcyBpbiBtZXNzYWdlIHR5cGVzIHdpdGggbm8gZmllbGQgcHJlc2VuY2UuIGhhc18kbmFtZSQoKSwKKyAgLy8gYmFzZWQgb24gdGhlIG9uZW9mIGNhc2UsIGlzIHN0aWxsIHVzZWZ1bCBpbnRlcm5hbGx5IGZvciBnZW5lcmF0ZWQgY29kZS4KKyAgcmV0dXJuICghSGFzRmllbGRQcmVzZW5jZShmaWVsZC0+ZmlsZSgpKSAmJgorICAgICAgICAgIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitNZXNzYWdlR2VuZXJhdG9yOjpNZXNzYWdlR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIGNsYXNzbmFtZV8oQ2xhc3NOYW1lKGRlc2NyaXB0b3IsIGZhbHNlKSksCisgICAgICBvcHRpb25zXyhvcHRpb25zKSwKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfKGRlc2NyaXB0b3IsIG9wdGlvbnMpLAorICAgICAgbmVzdGVkX2dlbmVyYXRvcnNfKG5ldyBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPAorICAgICAgICAgIE1lc3NhZ2VHZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPm5lc3RlZF90eXBlX2NvdW50KCldKSwKKyAgICAgIGVudW1fZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RW51bUdlbmVyYXRvcj5bZGVzY3JpcHRvci0+ZW51bV90eXBlX2NvdW50KCldKSwKKyAgICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzXyhuZXcgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjwKKyAgICAgICAgICBFeHRlbnNpb25HZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPmV4dGVuc2lvbl9jb3VudCgpXSkgeworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLnJlc2V0KAorICAgICAgbmV3IE1lc3NhZ2VHZW5lcmF0b3IoZGVzY3JpcHRvci0+bmVzdGVkX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICBuZXcgRW51bUdlbmVyYXRvcihkZXNjcmlwdG9yLT5lbnVtX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS5yZXNldCgKKyAgICAgIG5ldyBFeHRlbnNpb25HZW5lcmF0b3IoZGVzY3JpcHRvci0+ZXh0ZW5zaW9uKGkpLCBvcHRpb25zKSk7CisgIH0KKworICBudW1fcmVxdWlyZWRfZmllbGRzXyA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPmZpZWxkKGkpLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICArK251bV9yZXF1aXJlZF9maWVsZHNfOworICAgIH0KKyAgfQorfQorCitNZXNzYWdlR2VuZXJhdG9yOjp+TWVzc2FnZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUZvcndhcmREZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgiY2xhc3MgJGNsYXNzbmFtZSQ7XG4iLAorICAgICAgICAgICAgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gbWFwIGVudHJ5IG1lc3NhZ2UgZG9lc24ndCBuZWVkIGZvcndhcmQgZGVjbGFyYXRpb24uIFNpbmNlIG1hcCBlbnRyeQorICAgIC8vIG1lc3NhZ2UgY2Fubm90IGJlIGEgdG9wIGxldmVsIGNsYXNzLCB3ZSBqdXN0IG5lZWQgdG8gYXZvaWQgY2FsbGluZworICAgIC8vIEdlbmVyYXRlRm9yd2FyZERlY2xhcmF0aW9uIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVGb3J3YXJkRGVjbGFyYXRpb24ocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRW51bURlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVFbnVtRGVmaW5pdGlvbnMocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZWZpbml0aW9uKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUdldEVudW1EZXNjcmlwdG9yU3BlY2lhbGl6YXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVHZXRFbnVtRGVzY3JpcHRvclNwZWNpYWxpemF0aW9ucyhwcmludGVyKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVHZXRFbnVtRGVzY3JpcHRvclNwZWNpYWxpemF0aW9ucyhwcmludGVyKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoZmllbGQsICZ2YXJzLCBvcHRpb25zXyk7CisgICAgdmFyc1siY29uc3RhbnRfbmFtZSJdID0gRmllbGRDb25zdGFudE5hbWUoZmllbGQpOworCisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLCAiaW50ICRuYW1lJF9zaXplKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIik7CisgICAgfSBlbHNlIGlmIChIYXNIYXNNZXRob2QoZmllbGQpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLCAiYm9vbCBoYXNfJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIik7CisgICAgfSBlbHNlIGlmIChIYXNQcml2YXRlSGFzTWV0aG9kKGZpZWxkKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgICAicHJpdmF0ZTpcbiIKKyAgICAgICAgICAiYm9vbCBoYXNfJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICAgICAgICJwdWJsaWM6XG4iKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCh2YXJzLCAidm9pZCBjbGVhcl8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLCAic3RhdGljIGNvbnN0IGludCAkY29uc3RhbnRfbmFtZSQgPSAkbnVtYmVyJDtcbiIpOworCisgICAgLy8gR2VuZXJhdGUgdHlwZS1zcGVjaWZpYyBhY2Nlc3NvciBkZWNsYXJhdGlvbnMuCisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKHByaW50ZXIpOworCisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIC8vIEdlbmVyYXRlIGFjY2Vzc29ycyBmb3IgZXh0ZW5zaW9ucy4gIFdlIGp1c3QgY2FsbCBhIG1hY3JvIGxvY2F0ZWQgaW4KKyAgICAvLyBleHRlbnNpb25fc2V0Lmggc2luY2UgdGhlIGFjY2Vzc29ycyBhYm91dCA4MCBsaW5lcyBvZiBzdGF0aWMgY29kZS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUygkY2xhc3NuYW1lJClcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJGNhbWVsX29uZW9mX25hbWUkQ2FzZSAkb25lb2ZfbmFtZSRfY2FzZSgpIGNvbnN0O1xuIiwKKyAgICAgICAgImNhbWVsX29uZW9mX25hbWUiLAorICAgICAgICBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIHRydWUpLAorICAgICAgICAib25lb2ZfbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBpc19pbmxpbmUpIHsKKyAgcHJpbnRlci0+UHJpbnQoIi8vICRjbGFzc25hbWUkXG5cbiIsICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworCisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGZpZWxkLCAmdmFycywgb3B0aW9uc18pOworICAgIHZhcnNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKworICAgIC8vIEdlbmVyYXRlIGhhc18kbmFtZSQoKSBvciAkbmFtZSRfc2l6ZSgpLgorICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgIiRpbmxpbmUkIGludCAkY2xhc3NuYW1lJDo6JG5hbWUkX3NpemUoKSBjb25zdCB7XG4iCisgICAgICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0gZWxzZSBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgLy8gU2luZ3VsYXIgZmllbGQgaW4gYSBvbmVvZgorICAgICAgLy8gTi5CLjogV2l0aG91dCBmaWVsZCBwcmVzZW5jZSwgd2UgZG8gbm90IHVzZSBoYXMtYml0cyBvciBnZW5lcmF0ZQorICAgICAgLy8gaGFzXyRuYW1lJCgpIG1ldGhvZHMsIGJ1dCBvbmVvZnMgc3RpbGwgaGF2ZSBzZXRfaGFzXyRuYW1lJCgpLgorICAgICAgLy8gT25lb2ZzIGFsc28gaGF2ZSBoYXNfJG5hbWUkKCkgYnV0IG9ubHkgYXMgYSBwcml2YXRlIGhlbHBlcgorICAgICAgLy8gbWV0aG9kLCBzbyB0aGF0IGdlbmVyYXRlZCBjb2RlIGlzIHNsaWdodGx5IGNsZWFuZXIgKHZzLiAgY29tcGFyaW5nCisgICAgICAvLyBfb25lb2ZfY2FzZV9baW5kZXhdIGFnYWluc3QgYSBjb25zdGFudCBldmVyeXdoZXJlKS4KKyAgICAgIHZhcnNbImZpZWxkX25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQtPm5hbWUoKSwgdHJ1ZSk7CisgICAgICB2YXJzWyJvbmVvZl9uYW1lIl0gPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5uYW1lKCk7CisgICAgICB2YXJzWyJvbmVvZl9pbmRleCJdID0gU2ltcGxlSXRvYShmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICIkaW5saW5lJCBib29sICRjbGFzc25hbWUkOjpoYXNfJG5hbWUkKCkgY29uc3Qge1xuIgorICAgICAgICAiICByZXR1cm4gJG9uZW9mX25hbWUkX2Nhc2UoKSA9PSBrJGZpZWxkX25hbWUkO1xuIgorICAgICAgICAifVxuIik7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0X2hhc18kbmFtZSQoKSB7XG4iCisgICAgICAgICIgIF9vbmVvZl9jYXNlX1skb25lb2ZfaW5kZXgkXSA9IGskZmllbGRfbmFtZSQ7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gU2luZ3VsYXIgZmllbGQuCisgICAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgICAvLyBOLkIuOiB3aXRob3V0IGZpZWxkIHByZXNlbmNlLCB3ZSBkbyBub3QgdXNlIGhhcy1iaXRzIG9yIGdlbmVyYXRlCisgICAgICAgIC8vIGhhc18kbmFtZSQoKSBtZXRob2RzLgorICAgICAgICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgICAgICAgIHZhcnNbImhhc19hcnJheV9pbmRleCJdID0gU2ltcGxlSXRvYShmaWVsZC0+aW5kZXgoKSAvIDMyKTsKKyAgICAgICAgdmFyc1siaGFzX21hc2siXSA9IEZhc3RIZXgzMlRvQnVmZmVyKDF1IDw8IChmaWVsZC0+aW5kZXgoKSAlIDMyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcik7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICAgIiRpbmxpbmUkIGJvb2wgJGNsYXNzbmFtZSQ6Omhhc18kbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIChfaGFzX2JpdHNfWyRoYXNfYXJyYXlfaW5kZXgkXSAmIDB4JGhhc19tYXNrJHUpICE9IDA7XG4iCisgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0X2hhc18kbmFtZSQoKSB7XG4iCisgICAgICAgICAgIiAgX2hhc19iaXRzX1skaGFzX2FycmF5X2luZGV4JF0gfD0gMHgkaGFzX21hc2skdTtcbiIKKyAgICAgICAgICAifVxuIgorICAgICAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpjbGVhcl9oYXNfJG5hbWUkKCkge1xuIgorICAgICAgICAgICIgIF9oYXNfYml0c19bJGhhc19hcnJheV9pbmRleCRdICY9IH4weCRoYXNfbWFzayR1O1xuIgorICAgICAgICAgICJ9XG4iCisgICAgICAgICAgKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE1lc3NhZ2UgZmllbGRzIGhhdmUgYSBoYXNfJG5hbWUkKCkgbWV0aG9kLgorICAgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgICAgICBib29sIGlzX2xhenkgPSBmYWxzZTsKKyAgICAgICAgICBpZiAoaXNfbGF6eSkgeworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgICAgICAgIiRpbmxpbmUkIGJvb2wgJGNsYXNzbmFtZSQ6Omhhc18kbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAgICAgICAgICIgIHJldHVybiAhJG5hbWUkXy5Jc0NsZWFyZWQoKTtcbiIKKyAgICAgICAgICAgICAgIn1cbiIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAgICAgICAiJGlubGluZSQgYm9vbCAkY2xhc3NuYW1lJDo6aGFzXyRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAgICAgICAgICAgIiAgcmV0dXJuICFfaXNfZGVmYXVsdF9pbnN0YW5jZV8gJiYgJG5hbWUkXyAhPSBOVUxMO1xuIgorICAgICAgICAgICAgICAifVxuIik7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gR2VuZXJhdGUgY2xlYXJfJG5hbWUkKCkKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OmNsZWFyXyRuYW1lJCgpIHtcbiIpOworCisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgLy8gQ2xlYXIgdGhpcyBmaWVsZCBvbmx5IGlmIGl0IGlzIHRoZSBhY3RpdmUgZmllbGQgaW4gdGhpcyBvbmVvZiwKKyAgICAgIC8vIG90aGVyd2lzZSBpZ25vcmUKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICJpZiAoaGFzXyRuYW1lJCgpKSB7XG4iKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUNsZWFyaW5nQ29kZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICJjbGVhcl9oYXNfJG9uZW9mX25hbWUkKCk7XG4iKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUNsZWFyaW5nQ29kZShwcmludGVyKTsKKyAgICAgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICJjbGVhcl9oYXNfJG5hbWUkKCk7XG4iKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisKKyAgICAvLyBHZW5lcmF0ZSB0eXBlLXNwZWNpZmljIGFjY2Vzc29ycy4KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2lubGluZSk7CisKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIGhhc18kbmFtZSQoKSBhbmQgY2xlYXJfaGFzXyRuYW1lJCgpIGZ1bmN0aW9ucyBmb3Igb25lb2ZzCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCk7CisgICAgdmFyc1sib25lb2ZfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmluZGV4KCkpOworICAgIHZhcnNbImNhcF9vbmVvZl9uYW1lIl0gPQorICAgICAgICBUb1VwcGVyKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICAgIHZhcnNbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lXzsKKyAgICB2YXJzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJzLAorICAgICAgIiRpbmxpbmUkIGJvb2wgJGNsYXNzbmFtZSQ6Omhhc18kb25lb2ZfbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gJG9uZW9mX25hbWUkX2Nhc2UoKSAhPSAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OmNsZWFyX2hhc18kb25lb2ZfbmFtZSQoKSB7XG4iCisgICAgICAiICBfb25lb2ZfY2FzZV9bJG9uZW9mX2luZGV4JF0gPSAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKworLy8gSGVscGVyIGZvciB0aGUgY29kZSB0aGF0IGVtaXRzIHRoZSBDbGVhcigpIG1ldGhvZC4KK3N0YXRpYyBib29sIENhbkNsZWFyQnlaZXJvaW5nKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpIHx8IGZpZWxkLT5pc19leHRlbnNpb24oKSkgcmV0dXJuIGZhbHNlOworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRU5VTToKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpID09IDA7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50MzIoKSA9PSAwOworICAgIGNhc2UgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkgPT0gMDsKKyAgICBjYXNlIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDMyKCkgPT0gMDsKKyAgICBjYXNlIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDY0KCkgPT0gMDsKKyAgICBjYXNlIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpID09IDA7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpID09IDA7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9ib29sKCkgPT0gZmFsc2U7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGFzc0RlZmluaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gbWFwIGVudHJ5IG1lc3NhZ2UgZG9lc24ndCBuZWVkIGNsYXNzIGRlZmluaXRpb24uIFNpbmNlIG1hcCBlbnRyeSBtZXNzYWdlCisgICAgLy8gY2Fubm90IGJlIGEgdG9wIGxldmVsIGNsYXNzLCB3ZSBqdXN0IG5lZWQgdG8gYXZvaWQgY2FsbGluZworICAgIC8vIEdlbmVyYXRlQ2xhc3NEZWZpbml0aW9uIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVDbGFzc0RlZmluaXRpb24ocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgcHJpbnRlci0+UHJpbnQoa1RoaW5TZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisgIHZhcnNbImZpZWxkX2NvdW50Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKTsKKyAgdmFyc1sib25lb2ZfZGVjbF9jb3VudCJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpKTsKKyAgaWYgKG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsLmVtcHR5KCkpIHsKKyAgICB2YXJzWyJkbGxleHBvcnQiXSA9ICIiOworICB9IGVsc2UgeworICAgIHZhcnNbImRsbGV4cG9ydCJdID0gb3B0aW9uc18uZGxsZXhwb3J0X2RlY2wgKyAiICI7CisgIH0KKyAgdmFyc1sic3VwZXJjbGFzcyJdID0gU3VwZXJDbGFzc05hbWUoZGVzY3JpcHRvcl8pOworCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgImNsYXNzICRkbGxleHBvcnQkJGNsYXNzbmFtZSQgOiBwdWJsaWMgJHN1cGVyY2xhc3MkIHtcbiIKKyAgICAiIHB1YmxpYzpcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIkY2xhc3NuYW1lJCgpO1xuIgorICAgICJ2aXJ0dWFsIH4kY2xhc3NuYW1lJCgpO1xuIgorICAgICJcbiIKKyAgICAiJGNsYXNzbmFtZSQoY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pO1xuIgorICAgICJcbiIKKyAgICAiaW5saW5lICRjbGFzc25hbWUkJiBvcGVyYXRvcj0oY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pIHtcbiIKKyAgICAiICBDb3B5RnJvbShmcm9tKTtcbiIKKyAgICAiICByZXR1cm4gKnRoaXM7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTtcbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIlxuIgorICAgICAgICAiaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkge1xuIgorICAgICAgICAiICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7XG4iCisgICAgICAgICJ9XG4iCisgICAgICAgICJcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIF91bmtub3duX2ZpZWxkc187XG4iCisgICAgICAgICJ9XG4iCisgICAgICAgICJcbiIKKyAgICAgICAgImlubGluZSA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkge1xuIgorICAgICAgICAiICByZXR1cm4gJl91bmtub3duX2ZpZWxkc187XG4iCisgICAgICAgICJ9XG4iCisgICAgICAgICJcbiIpOworICAgIH0KKyAgfQorCisgIC8vIE4uQi46IFdlIGV4Y2x1ZGUgR2V0QXJlbmEoKSB3aGVuIGFyZW5hIHN1cHBvcnQgaXMgZGlzYWJsZWQsIGZhbGxpbmcgYmFjayBvbgorICAvLyBNZXNzYWdlTGl0ZSdzIGltcGxlbWVudGF0aW9uIHdoaWNoIHJldHVybnMgTlVMTCByYXRoZXIgdGhhbiBnZW5lcmF0aW5nIG91cgorICAvLyBvd24gbWV0aG9kIHdoaWNoIHJldHVybnMgTlVMTCwgaW4gb3JkZXIgdG8gcmVkdWNlIGNvZGUgc2l6ZS4KKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIHZpcnR1YWwgbWV0aG9kIHZlcnNpb24gb2YgR2V0QXJlbmFOb1ZpcnR1YWwoKSwgcmVxdWlyZWQgZm9yIGdlbmVyaWMgZGlzcGF0Y2ggZ2l2ZW4gYQorICAgIC8vIE1lc3NhZ2VMaXRlKiAoZS5nLiwgaW4gUmVwZWF0ZWRGaWVsZDo6QWRkQWxsb2NhdGVkKCkpLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsgfVxuIgorICAgICAgICAiaW5saW5lIHZvaWQqIEdldE1heWJlQXJlbmFQb2ludGVyKCkgY29uc3Qge1xuIgorICAgICAgICAiICByZXR1cm4gTWF5YmVBcmVuYVB0cigpO1xuIgorICAgICAgICAifVxuIik7CisgIH0KKworICAvLyBPbmx5IGdlbmVyYXRlIHRoaXMgbWVtYmVyIGlmIGl0J3Mgbm90IGRpc2FibGVkLgorICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgICFkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAic3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICJzdGF0aWMgY29uc3QgJGNsYXNzbmFtZSQmIGRlZmF1bHRfaW5zdGFuY2UoKTtcbiIKKyAgICAiXG4iKTsKKworICAvLyBHZW5lcmF0ZSBlbnVtIHZhbHVlcyBmb3IgZXZlcnkgZmllbGQgaW4gb25lb2ZzLiBPbmUgbGlzdCBpcyBnZW5lcmF0ZWQgZm9yCisgIC8vIGVhY2ggb25lb2Ygd2l0aCBhbiBhZGRpdGlvbmFsICpfTk9UX1NFVCB2YWx1ZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImVudW0gJGNhbWVsX29uZW9mX25hbWUkQ2FzZSB7XG4iLAorICAgICAgICAiY2FtZWxfb25lb2ZfbmFtZSIsCisgICAgICAgIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgdHJ1ZSkpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImskZmllbGRfbmFtZSQgPSAkZmllbGRfbnVtYmVyJCxcbiIsCisgICAgICAgICAgImZpZWxkX25hbWUiLAorICAgICAgICAgIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoCisgICAgICAgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKS0+bmFtZSgpLCB0cnVlKSwKKyAgICAgICAgICAiZmllbGRfbnVtYmVyIiwKKyAgICAgICAgICBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKS0+bnVtYmVyKCkpKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIkY2FwX29uZW9mX25hbWUkX05PVF9TRVQgPSAwLFxuIiwKKyAgICAgICAgImNhcF9vbmVvZl9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifTtcbiIKKyAgICAgICAgIlxuIik7CisgIH0KKworICBpZiAoIVN0YXRpY0luaXRpYWxpemVyc0ZvcmNlZChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9OT19TVEFUSUNfSU5JVElBTElaRVJcbiIKKyAgICAgICIvLyBSZXR1cm5zIHRoZSBpbnRlcm5hbCBkZWZhdWx0IGluc3RhbmNlIHBvaW50ZXIuIFRoaXMgZnVuY3Rpb24gY2FuXG4iCisgICAgICAiLy8gcmV0dXJuIE5VTEwgdGh1cyBzaG91bGQgbm90IGJlIHVzZWQgYnkgdGhlIHVzZXIuIFRoaXMgaXMgaW50ZW5kZWRcbiIKKyAgICAgICIvLyBmb3IgUHJvdG9idWYgaW50ZXJuYWwgY29kZS4gUGxlYXNlIHVzZSBkZWZhdWx0X2luc3RhbmNlKCkgZGVjbGFyZWRcbiIKKyAgICAgICIvLyBhYm92ZSBpbnN0ZWFkLlxuIgorICAgICAgInN0YXRpYyBpbmxpbmUgY29uc3QgJGNsYXNzbmFtZSQqIGludGVybmFsX2RlZmF1bHRfaW5zdGFuY2UoKSB7XG4iCisgICAgICAiICByZXR1cm4gZGVmYXVsdF9pbnN0YW5jZV87XG4iCisgICAgICAifVxuIgorICAgICAgIiNlbmRpZlxuIgorICAgICAgIlxuIik7CisgIH0KKworCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInZvaWQgVW5zYWZlQXJlbmFTd2FwKCRjbGFzc25hbWUkKiBvdGhlcik7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICJ2b2lkIFN3YXAoJGNsYXNzbmFtZSQqIG90aGVyKTtcbiIKKyAgICAiXG4iCisgICAgIi8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCisgICAgIlxuIgorICAgICJpbmxpbmUgJGNsYXNzbmFtZSQqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfVxuIgorICAgICJcbiIKKyAgICAiJGNsYXNzbmFtZSQqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7XG4iKTsKKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgInZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTtcbiIKKyAgICAgICAgInZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgInZvaWQgQ2hlY2tUeXBlQW5kTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUxpdGUmIGZyb20pO1xuIik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJ2b2lkIENvcHlGcm9tKGNvbnN0ICRjbGFzc25hbWUkJiBmcm9tKTtcbiIKKyAgICAgICJ2b2lkIE1lcmdlRnJvbShjb25zdCAkY2xhc3NuYW1lJCYgZnJvbSk7XG4iCisgICAgICAidm9pZCBDbGVhcigpO1xuIgorICAgICAgImJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0O1xuIgorICAgICAgIlxuIgorICAgICAgImludCBCeXRlU2l6ZSgpIGNvbnN0O1xuIgorICAgICAgImJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7XG4iCisgICAgICAidm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0O1xuIik7CisgICAgLy8gRGlzY2FyZFVua25vd25GaWVsZHMoKSBpcyBpbXBsZW1lbnRlZCBpbiBtZXNzYWdlLmNjIHVzaW5nIHJlZmxlY3Rpb25zLiBXZQorICAgIC8vIG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgZnVuY3Rpb24gaW4gZ2VuZXJhdGVkIGNvZGUgZm9yIG1lc3NhZ2VzLgorICAgIGlmICghVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInZvaWQgRGlzY2FyZFVua25vd25GaWVsZHMoKTtcbiIpOworICAgIH0KKyAgICBpZiAoSGFzRmFzdEFycmF5U2VyaWFsaXphdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7XG4iKTsKKyAgICB9CisgIH0KKworICAvLyBDaGVjayBhbGwgRmllbGREZXNjcmlwdG9ycyBpbmNsdWRpbmcgdGhvc2UgaW4gb25lb2ZzIHRvIGVzdGltYXRlCisgIC8vIHdoZXRoZXIgOjpzdGQ6OnN0cmluZyBpcyBsaWtlbHkgdG8gYmUgdXNlZCwgYW5kIGRlcGVuZGluZyBvbiB0aGF0CisgIC8vIGVzdGltYXRlLCBzZXQgdXNlc19zdHJpbmdfIHRvIHRydWUgb3IgZmFsc2UuICBUaGF0IGNvbnRvbHMKKyAgLy8gd2hldGhlciB0byBmb3JjZSBpbml0aWFsaXphdGlvbiBvZiBlbXB0eV9zdHJpbmdfIGluIFNoYXJlZEN0b3IoKS4KKyAgLy8gSXQncyBvZnRlbiBhZHZhbnRhZ2VvdXMgdG8gZG8gc28gdG8ga2VlcCAiaXMgZW1wdHlfc3RyaW5nXworICAvLyBpbml0ZWQ/IiBjb2RlIGZyb20gYXBwZWFyaW5nIGFsbCBvdmVyIHRoZSBwbGFjZS4KKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGRlc2NyaXB0b3JzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZGVzY3JpcHRvcl8tPmZpZWxkKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgZGVzY3JpcHRvcnMucHVzaF9iYWNrKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKSk7CisgICAgfQorICB9CisgIHVzZXNfc3RyaW5nXyA9IGZhbHNlOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JzW2ldOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICBkZWZhdWx0OiB1c2VzX3N0cmluZ18gPSB0cnVlOyBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9XG4iCisgICAgInByaXZhdGU6XG4iCisgICAgInZvaWQgU2hhcmVkQ3RvcigpO1xuIgorICAgICJ2b2lkIFNoYXJlZER0b3IoKTtcbiIKKyAgICAidm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDtcbiIKKyAgICAidm9pZCBJbnRlcm5hbFN3YXAoJGNsYXNzbmFtZSQqIG90aGVyKTtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJvdGVjdGVkOlxuIgorICAgICAgImV4cGxpY2l0ICRjbGFzc25hbWUkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTtcbiIKKyAgICAgICJwcml2YXRlOlxuIgorICAgICAgInN0YXRpYyB2b2lkIEFyZW5hRHRvcih2b2lkKiBvYmplY3QpO1xuIgorICAgICAgImlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZTpcbiIKKyAgICAgICJpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHtcbiIKKyAgICAgICIgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAicHVibGljOlxuIgorICAgICAgIlxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZTpcbiIKKyAgICAgICJpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gX2FyZW5hX3B0cl87XG4iCisgICAgICAifVxuIgorICAgICAgImlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBNYXliZUFyZW5hUHRyKCkgY29uc3Qge1xuIgorICAgICAgIiAgcmV0dXJuIF9hcmVuYV9wdHJfO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJwdWJsaWM6XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDtcbiIKKyAgICAgICJcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6c3RkOjpzdHJpbmcgR2V0VHlwZU5hbWUoKSBjb25zdDtcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCisgICAgIlxuIik7CisKKyAgLy8gSW1wb3J0IGFsbCBuZXN0ZWQgbWVzc2FnZSBjbGFzc2VzIGludG8gdGhpcyBjbGFzcydzIHNjb3BlIHdpdGggdHlwZWRlZnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IERlc2NyaXB0b3IqIG5lc3RlZF90eXBlID0gZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpOworICAgIGlmICghSXNNYXBFbnRyeU1lc3NhZ2UobmVzdGVkX3R5cGUpKSB7CisgICAgICBwcmludGVyLT5QcmludCgidHlwZWRlZiAkbmVzdGVkX2Z1bGxfbmFtZSQgJG5lc3RlZF9uYW1lJDtcbiIsCisgICAgICAgICAgICAgICAgICAgICAibmVzdGVkX25hbWUiLCBuZXN0ZWRfdHlwZS0+bmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIm5lc3RlZF9mdWxsX25hbWUiLCBDbGFzc05hbWUobmVzdGVkX3R5cGUsIGZhbHNlKSk7CisgICAgfQorICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgLy8gSW1wb3J0IGFsbCBuZXN0ZWQgZW51bXMgYW5kIHRoZWlyIHZhbHVlcyBpbnRvIHRoaXMgY2xhc3MncyBzY29wZSB3aXRoCisgIC8vIHR5cGVkZWZzIGFuZCBjb25zdGFudHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVN5bWJvbEltcG9ydHMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIKKyAgICAiXG4iKTsKKworICAvLyBHZW5lcmF0ZSBhY2Nlc3NvciBtZXRob2RzIGZvciBhbGwgZmllbGRzLgorICBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMocHJpbnRlcik7CisKKyAgLy8gRGVjbGFyZSBleHRlbnNpb24gaWRlbnRpZmllcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVjbGFyYXRpb24ocHJpbnRlcik7CisgIH0KKworCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIC8vIEdlbmVyYXRlIHByaXZhdGUgbWVtYmVycy4KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgiIHByaXZhdGU6XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgLy8gc2V0X2hhc18qKiooKSBnZW5lcmF0ZWQgaW4gYWxsIHByb3RvMS8yIGNvZGUgYW5kIGluIG9uZW9mcyAob25seSkgZm9yCisgICAgICAvLyBtZXNzYWdlcyB3aXRob3V0IHRydWUgZmllbGQgcHJlc2VuY2UuCisgICAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSB8fAorICAgICAgICAgIGRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpbmxpbmUgdm9pZCBzZXRfaGFzXyRuYW1lJCgpO1xuIiwKKyAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShkZXNjcmlwdG9yXy0+ZmllbGQoaSkpKTsKKyAgICAgIH0KKyAgICAgIC8vIGNsZWFyX2hhc18qKiooKSBnZW5lcmF0ZWQgb25seSBmb3Igbm9uLW9uZW9mIGZpZWxkcworICAgICAgLy8gaW4gcHJvdG8xLzIuCisgICAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpICYmCisgICAgICAgICAgSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaW5saW5lIHZvaWQgY2xlYXJfaGFzXyRuYW1lJCgpO1xuIiwKKyAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShkZXNjcmlwdG9yXy0+ZmllbGQoaSkpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgb25lb2YgZnVuY3Rpb24gZGVjbGFyYXRpb25zCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpbmxpbmUgYm9vbCBoYXNfJG9uZW9mX25hbWUkKCkgY29uc3Q7XG4iCisgICAgICAgICJ2b2lkIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgICAiaW5saW5lIHZvaWQgY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuXG4iLAorICAgICAgICAib25lb2ZfbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICB9CisKKyAgaWYgKEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgICFkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgJiYKKyAgICAgIG51bV9yZXF1aXJlZF9maWVsZHNfID4gMSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLy8gaGVscGVyIGZvciBCeXRlU2l6ZSgpXG4iCisgICAgICAgICJpbnQgUmVxdWlyZWRGaWVsZHNCeXRlU2l6ZUZhbGxiYWNrKCkgY29uc3Q7XG5cbiIpOworICB9CisKKyAgLy8gUHJlcGFyZSBkZWNscyBmb3IgX2NhY2hlZF9zaXplXyBhbmQgX2hhc19iaXRzXy4gIFRoZWlyIHBvc2l0aW9uIGluIHRoZQorICAvLyBvdXRwdXQgd2lsbCBiZSBkZXRlcm1pbmVkIGxhdGVyLgorCisgIGJvb2wgbmVlZF90b19lbWl0X2NhY2hlZF9zaXplID0gdHJ1ZTsKKyAgLy8gVE9ETyhrZW50b24pOiAgTWFrZSBfY2FjaGVkX3NpemVfIGFuIGF0b21pYzxpbnQ+IHdoZW4gQysrIHN1cHBvcnRzIGl0LgorICBjb25zdCBzdHJpbmcgY2FjaGVkX3NpemVfZGVjbCA9ICJtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfO1xuIjsKKworICAvLyBUT0RPKGppZWx1bykgLSBPcHRpbWl6ZSBfaGFzX2JpdHNfIGZvciByZXBlYXRlZCBhbmQgb25lb2YgZmllbGRzLgorICBzaXplX3Qgc2l6ZW9mX2hhc19iaXRzID0gKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpICsgMzEpIC8gMzIgKiA0OworICBpZiAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgPT0gMCkgeworICAgIC8vIFplcm8tc2l6ZSBhcnJheXMgYXJlbid0IHRlY2huaWNhbGx5IGFsbG93ZWQsIGFuZCBNU1ZDIGluIHBhcnRpY3VsYXIKKyAgICAvLyBkb2Vzbid0IGxpa2UgdGhlbS4gIFdlIHN0aWxsIG5lZWQgdG8gZGVjbGFyZSB0aGVzZSBhcnJheXMgdG8gbWFrZQorICAgIC8vIG90aGVyIGNvZGUgY29tcGlsZS4gIFNpbmNlIHRoaXMgaXMgYW4gdW5jb21tb24gY2FzZSwgd2UnbGwganVzdCBkZWNsYXJlCisgICAgLy8gdGhlbSB3aXRoIHNpemUgMSBhbmQgd2FzdGUgc29tZSBzcGFjZS4gIE9oIHdlbGwuCisgICAgc2l6ZW9mX2hhc19iaXRzID0gNDsKKyAgfQorICBjb25zdCBzdHJpbmcgaGFzX2JpdHNfZGVjbCA9IHNpemVvZl9oYXNfYml0cyA9PSAwID8gIiIgOgorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bIiArIFNpbXBsZUl0b2Eoc2l6ZW9mX2hhc19iaXRzIC8gNCkgKyAiXTtcbiI7CisKKworICAvLyBUbyBtaW5pbWl6ZSBwYWRkaW5nLCBkYXRhIG1lbWJlcnMgYXJlIGRpdmlkZWQgaW50byB0aHJlZSBzZWN0aW9uczoKKyAgLy8gKDEpIG1lbWJlcnMgYXNzdW1lZCB0byBhbGlnbiB0byA4IGJ5dGVzCisgIC8vICgyKSBtZW1iZXJzIGNvcnJlc3BvbmRpbmcgdG8gbWVzc2FnZSBmaWVsZHMsIHJlLW9yZGVyZWQgdG8gb3B0aW1pemUKKyAgLy8gICAgIGFsaWdubWVudC4KKyAgLy8gKDMpIG1lbWJlcnMgYXNzdW1lZCB0byBhbGlnbiB0byA0IGJ5dGVzLgorCisgIC8vIE1lbWJlcnMgYXNzdW1lZCB0byBhbGlnbiB0byA4IGJ5dGVzOgorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0IF9leHRlbnNpb25zXztcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6c3RkOjpzdHJpbmcgX3Vua25vd25fZmllbGRzXztcbiIKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBfYXJlbmFfcHRyXztcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hO1xuIgorICAgICAgInR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87XG4iCisgICAgICAidHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfO1xuIik7CisgIH0KKworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIF9oYXNfYml0c18gaXMgZnJlcXVlbnRseSBhY2Nlc3NlZCwgc28gdG8gcmVkdWNlIGNvZGUgc2l6ZSBhbmQgaW1wcm92ZQorICAgIC8vIHNwZWVkLCBpdCBzaG91bGQgYmUgY2xvc2UgdG8gdGhlIHN0YXJ0IG9mIHRoZSBvYmplY3QuICBCdXQsIHRyeSBub3QgdG8KKyAgICAvLyB3YXN0ZSBzcGFjZTpfaGFzX2JpdHNfIGJ5IGl0c2VsZiBhbHdheXMgbWFrZXMgc2Vuc2UgaWYgaXRzIHNpemUgaXMgYQorICAgIC8vIG11bHRpcGxlIG9mIDgsIGJ1dCwgb3RoZXJ3aXNlLCBtYXliZSBfaGFzX2JpdHNfIGFuZCBjYWNoZWRfc2l6ZV8gdG9nZXRoZXIKKyAgICAvLyB3aWxsIHdvcmsgd2VsbC4KKyAgICBwcmludGVyLT5QcmludChoYXNfYml0c19kZWNsLmNfc3RyKCkpOworICAgIGlmICgoc2l6ZW9mX2hhc19iaXRzICUgOCkgIT0gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoY2FjaGVkX3NpemVfZGVjbC5jX3N0cigpKTsKKyAgICAgIG5lZWRfdG9fZW1pdF9jYWNoZWRfc2l6ZSA9IGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBXaXRob3V0IGZpZWxkIHByZXNlbmNlLCB3ZSBuZWVkIGFub3RoZXIgd2F5IHRvIGRpc2FtYmlndWF0ZSB0aGUgZGVmYXVsdAorICAgIC8vIGluc3RhbmNlLCBiZWNhdXNlIHRoZSBkZWZhdWx0IGluc3RhbmNlJ3Mgc3VibWVzc2FnZSBmaWVsZHMgKGlmIGFueSkgc3RvcmUKKyAgICAvLyBwb2ludGVycyB0byB0aGUgZGVmYXVsdCBpbnN0YW5jZXMgb2YgdGhlIHN1Ym1lc3NhZ2VzIGV2ZW4gd2hlbiB0aGV5CisgICAgLy8gYXJlbid0IHByZXNlbnQuIEFsdGVybmF0aXZlcyB0byB0aGlzIGFwcHJvYWNoIG1pZ2h0IGJlIHRvIChpKSB1c2UgYQorICAgIC8vIHRhZ2dlZCBwb2ludGVyIG9uIGFsbCBtZXNzYWdlIGZpZWxkcywgc2V0dGluZyBhIHRhZyBiaXQgZm9yICJub3QgcmVhbGx5CisgICAgLy8gcHJlc2VudCwganVzdCBkZWZhdWx0IGluc3RhbmNlIjsgb3IgKGlpKSBjb21wYXJpbmcgfHRoaXN8IGFnYWluc3QgdGhlCisgICAgLy8gcmV0dXJuIHZhbHVlIGZyb20gR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OkdldFByb3RvdHlwZSgpIGluIGFsbAorICAgIC8vIGhhc18kZmllbGQkKCkgY2FsbHMuIEhvd2V2ZXIsIGJvdGggb2YgdGhlc2Ugb3B0aW9ucyBhcmUgbXVjaCBtb3JlCisgICAgLy8gZXhwZW5zaXZlIChpbiBjb2RlIHNpemUgYW5kIENQVSBvdmVyaGVhZCkgdGhhbiBqdXN0IGNoZWNraW5nIGEgZmllbGQgaW4KKyAgICAvLyB0aGUgbWVzc2FnZS4gTG9uZy10ZXJtLCB0aGUgYmVzdCBzb2x1dGlvbiB3b3VsZCBiZSB0byByZWFyY2hpdGVjdCB0aGUKKyAgICAvLyBkZWZhdWx0IGluc3RhbmNlIGRlc2lnbiBub3QgdG8gc3RvcmUgcG9pbnRlcnMgdG8gc3VibWVzc2FnZSBkZWZhdWx0CisgICAgLy8gaW5zdGFuY2VzLCBhbmQgaGF2ZSByZWZsZWN0aW9uIGdldCB0aG9zZSBzb21lIG90aGVyIHdheTsgYnV0IHRoYXQgY2hhbmdlCisgICAgLy8gd291bGQgaGF2ZSB0b28gbXVjaCBpbXBhY3Qgb24gcHJvdG8yLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgImJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfO1xuIik7CisgIH0KKworICAvLyBGaWVsZCBtZW1iZXJzOgorCisgIC8vIExpc3QgZmllbGRzIHdoaWNoIGRvZXNuJ3QgYmVsb25nIHRvIGFueSBvbmVvZgorICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBoYXNoX21hcDxzdHJpbmcsIGludD4gZmllbGRuYW1lX3RvX2NodW5rOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgICAgZmllbGRzLnB1c2hfYmFjayhmaWVsZCk7CisgICAgICBmaWVsZG5hbWVfdG9fY2h1bmtbRmllbGROYW1lKGZpZWxkKV0gPSBpIC8gODsKKyAgICB9CisgIH0KKyAgT3B0aW1pemVQYWRkaW5nKCZmaWVsZHMpOworICAvLyBFbWl0IHNvbWUgcHJpdmF0ZSBhbmQgc3RhdGljIG1lbWJlcnMKKyAgcnVuc19vZl9maWVsZHNfID0gdmVjdG9yPCB2ZWN0b3I8c3RyaW5nPiA+KDEpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBmaWVsZHNbaV07CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3ImIGdlbmVyYXRvciA9IGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCk7CisgICAgZ2VuZXJhdG9yLkdlbmVyYXRlU3RhdGljTWVtYmVycyhwcmludGVyKTsKKyAgICBnZW5lcmF0b3IuR2VuZXJhdGVQcml2YXRlTWVtYmVycyhwcmludGVyKTsKKyAgICBpZiAoQ2FuQ2xlYXJCeVplcm9pbmcoZmllbGQpKSB7CisgICAgICBjb25zdCBzdHJpbmcmIGZpZWxkbmFtZSA9IEZpZWxkTmFtZShmaWVsZCk7CisgICAgICBpZiAoIXJ1bnNfb2ZfZmllbGRzXy5iYWNrKCkuZW1wdHkoKSAmJgorICAgICAgICAgIChmaWVsZG5hbWVfdG9fY2h1bmtbcnVuc19vZl9maWVsZHNfLmJhY2soKS5iYWNrKCldICE9CisgICAgICAgICAgIGZpZWxkbmFtZV90b19jaHVua1tmaWVsZG5hbWVdKSkgeworICAgICAgICBydW5zX29mX2ZpZWxkc18ucHVzaF9iYWNrKHZlY3RvcjxzdHJpbmc+KCkpOworICAgICAgfQorICAgICAgcnVuc19vZl9maWVsZHNfLmJhY2soKS5wdXNoX2JhY2soZmllbGRuYW1lKTsKKyAgICB9IGVsc2UgaWYgKCFydW5zX29mX2ZpZWxkc18uYmFjaygpLmVtcHR5KCkpIHsKKyAgICAgIHJ1bnNfb2ZfZmllbGRzXy5wdXNoX2JhY2sodmVjdG9yPHN0cmluZz4oKSk7CisgICAgfQorICB9CisKKyAgLy8gRm9yIGVhY2ggb25lb2YgZ2VuZXJhdGUgYSB1bmlvbgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidW5pb24gJGNhbWVsX29uZW9mX25hbWUkVW5pb24ge1xuIgorICAgICAgICAvLyBleHBsaWNpdCBlbXB0eSBjb25zdHJ1Y3RvciBpcyBuZWVkZWQgd2hlbiB1bmlvbiBjb250YWlucworICAgICAgICAvLyBBcmVuYVN0cmluZ1B0ciBtZW1iZXJzIGZvciBzdHJpbmcgZmllbGRzLgorICAgICAgICAiICAkY2FtZWxfb25lb2ZfbmFtZSRVbmlvbigpIHt9XG4iLAorICAgICAgICAiY2FtZWxfb25lb2ZfbmFtZSIsCisgICAgICAgIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgdHJ1ZSkpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZChqKSkuR2VuZXJhdGVQcml2YXRlTWVtYmVycyhwcmludGVyKTsKKyAgICB9CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifSAkb25lb2ZfbmFtZSRfO1xuIiwKKyAgICAgICAgIm9uZW9mX25hbWUiLCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQoaikpLkdlbmVyYXRlU3RhdGljTWVtYmVycyhwcmludGVyKTsKKyAgICB9CisgIH0KKworICAvLyBNZW1iZXJzIGFzc3VtZWQgdG8gYWxpZ24gdG8gNCBieXRlczoKKworICBpZiAobmVlZF90b19lbWl0X2NhY2hlZF9zaXplKSB7CisgICAgcHJpbnRlci0+UHJpbnQoY2FjaGVkX3NpemVfZGVjbC5jX3N0cigpKTsKKyAgICBuZWVkX3RvX2VtaXRfY2FjaGVkX3NpemUgPSBmYWxzZTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIF9vbmVvZl9jYXNlXy4KKyAgaWYgKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfb25lb2ZfY2FzZV9bJG9uZW9mX2RlY2xfY291bnQkXTtcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgLy8gRGVjbGFyZSBBZGREZXNjcmlwdG9ycygpLCBCdWlsZERlc2NyaXB0b3JzKCksIGFuZCBTaHV0ZG93bkZpbGUoKSBhcworICAvLyBmcmllbmRzIHNvIHRoYXQgdGhleSBjYW4gYWNjZXNzIHByaXZhdGUgc3RhdGljIHZhcmlhYmxlcyBsaWtlCisgIC8vIGRlZmF1bHRfaW5zdGFuY2VfIGFuZCByZWZsZWN0aW9uXy4KKyAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgLy8gV2l0aCBzdGF0aWMgaW5pdGlhbGl6ZXJzLgorICAgICJmcmllbmQgdm9pZCAkZGxsZXhwb3J0X2RlY2wkICRhZGRkZXNjcmlwdG9yc25hbWUkKCk7XG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgImZyaWVuZCB2b2lkICRkbGxleHBvcnRfZGVjbCQgJGFkZGRlc2NyaXB0b3JzbmFtZSRfaW1wbCgpO1xuIiwKKyAgICAvLyBWYXJzLgorICAgICJkbGxleHBvcnRfZGVjbCIsIG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsLAorICAgICJhZGRkZXNjcmlwdG9yc25hbWUiLAorICAgIEdsb2JhbEFkZERlc2NyaXB0b3JzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiZnJpZW5kIHZvaWQgJGFzc2lnbmRlc2NyaXB0b3JzbmFtZSQoKTtcbiIKKyAgICAiZnJpZW5kIHZvaWQgJHNodXRkb3duZmlsZW5hbWUkKCk7XG4iCisgICAgIlxuIiwKKyAgICAiYXNzaWduZGVzY3JpcHRvcnNuYW1lIiwKKyAgICAgIEdsb2JhbEFzc2lnbkRlc2NyaXB0b3JzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpLAorICAgICJzaHV0ZG93bmZpbGVuYW1lIiwgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAidm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAic3RhdGljICRjbGFzc25hbWUkKiBkZWZhdWx0X2luc3RhbmNlXztcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFycywgIn07Iik7CisgIEdPT0dMRV9EQ0hFQ0soIW5lZWRfdG9fZW1pdF9jYWNoZWRfc2l6ZSk7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZU1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgaXNfaW5saW5lKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIG1hcCBlbnRyeSBtZXNzYWdlIGRvZXNuJ3QgbmVlZCBpbmxpbmUgbWV0aG9kcy4gU2luY2UgbWFwIGVudHJ5IG1lc3NhZ2UKKyAgICAvLyBjYW5ub3QgYmUgYSB0b3AgbGV2ZWwgY2xhc3MsIHdlIGp1c3QgbmVlZCB0byBhdm9pZCBjYWxsaW5nCisgICAgLy8gR2VuZXJhdGVJbmxpbmVNZXRob2RzIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVJbmxpbmVNZXRob2RzKHByaW50ZXIsIGlzX2lubGluZSk7CisgICAgcHJpbnRlci0+UHJpbnQoa1RoaW5TZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgR2VuZXJhdGVGaWVsZEFjY2Vzc29yRGVmaW5pdGlvbnMocHJpbnRlciwgaXNfaW5saW5lKTsKKworICAvLyBHZW5lcmF0ZSBvbmVvZl9jYXNlKCkgZnVuY3Rpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJjbGFzc19uYW1lIl0gPSBjbGFzc25hbWVfOworICAgIHZhcnNbImNhbWVsX29uZW9mX25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoCisgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIHRydWUpOworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCk7CisgICAgdmFyc1sib25lb2ZfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmluZGV4KCkpOworICAgIHZhcnNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSAiIDogIiI7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcnMsCisgICAgICAgICIkaW5saW5lJCRjbGFzc19uYW1lJDo6JGNhbWVsX29uZW9mX25hbWUkQ2FzZSAkY2xhc3NfbmFtZSQ6OiIKKyAgICAgICAgIiRvbmVvZl9uYW1lJF9jYXNlKCkgY29uc3Qge1xuIgorICAgICAgICAiICByZXR1cm4gJGNsYXNzX25hbWUkOjokY2FtZWxfb25lb2ZfbmFtZSRDYXNlKCIKKyAgICAgICAgIl9vbmVvZl9jYXNlX1skb25lb2ZfaW5kZXgkXSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVEZXNjcmlwdG9yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiAkbmFtZSRfZGVzY3JpcHRvcl8gPSBOVUxMO1xuIgorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKlxuIgorICAgICAgIiAgJG5hbWUkX3JlZmxlY3Rpb25fID0gTlVMTDtcbiIsCisgICAgICAibmFtZSIsIGNsYXNzbmFtZV8pOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogJG5hbWUkX2Rlc2NyaXB0b3JfID0gTlVMTDtcbiIsCisgICAgICAibmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisKKyAgLy8gR2VuZXJhdGUgb25lb2YgZGVmYXVsdCBpbnN0YW5jZSBmb3IgcmVmbGVjdGlvbiB1c2FnZS4KKyAgaWYgKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInN0cnVjdCAkbmFtZSRPbmVvZkluc3RhbmNlIHtcbiIsCisgICAgICAgICAgICAgICAgICAgIm5hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICAgIHByaW50ZXItPlByaW50KCIgICIpOworICAgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgfHwKKyAgICAgICAgICAgIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HICYmCisgICAgICAgICAgICAgRWZmZWN0aXZlU3RyaW5nQ1R5cGUoZmllbGQpICE9IEZpZWxkT3B0aW9uczo6U1RSSU5HKSkgeworICAgICAgICAgIHByaW50ZXItPlByaW50KCJjb25zdCAiKTsKKyAgICAgICAgfQorICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgICB9CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoIn0qICRuYW1lJF9kZWZhdWx0X29uZW9mX2luc3RhbmNlXyA9IE5VTEw7XG4iLAorICAgICAgICAgICAgICAgICAgICJuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVzY3JpcHRvckRlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiAkbmFtZSRfZGVzY3JpcHRvcl8gPSBOVUxMO1xuIiwKKyAgICAgICJuYW1lIiwgQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5lbnVtX3R5cGUoaSksIGZhbHNlKSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyLCBpbnQgaW5kZXgpIHsKKyAgLy8gVE9ETyhrZW50b24pOiAgUGFzc2luZyB0aGUgaW5kZXggdG8gdGhpcyBtZXRob2QgaXMgcmVkdW5kYW50OyBqdXN0IHVzZQorICAvLyAgIGRlc2NyaXB0b3JfLT5pbmRleCgpIGluc3RlYWQuCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBjbGFzc25hbWVfOworICB2YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpbmRleCk7CisKKyAgLy8gT2J0YWluIHRoZSBkZXNjcmlwdG9yIGZyb20gdGhlIHBhcmVudCdzIGRlc2NyaXB0b3IuCisgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoJGluZGV4JCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJwYXJlbnQiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCksIGZhbHNlKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfID0gIgorICAgICAgICAiJHBhcmVudCRfZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKCRpbmRleCQpO1xuIik7CisgIH0KKworICBpZiAoSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSByZXR1cm47CisKKyAgLy8gR2VuZXJhdGUgdGhlIG9mZnNldHMuCisgIEdlbmVyYXRlT2Zmc2V0cyhwcmludGVyKTsKKworICBjb25zdCBib29sIHBhc3NfcG9vbF9hbmRfZmFjdG9yeSA9IGZhbHNlOworICB2YXJzWyJmbiJdID0gcGFzc19wb29sX2FuZF9mYWN0b3J5ID8KKyAgICAgICJuZXcgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24iIDoKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiIKKyAgICAgICI6Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uIjsKKyAgLy8gQ29uc3RydWN0IHRoZSByZWZsZWN0aW9uIG9iamVjdC4KKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiJGNsYXNzbmFtZSRfcmVmbGVjdGlvbl8gPVxuIgorICAgICIgICRmbiQoXG4iCisgICAgIiAgICAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXyxcbiIKKyAgICAiICAgICRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXyxcbiIKKyAgICAiICAgICRjbGFzc25hbWUkX29mZnNldHNfLFxuIik7CisgIGlmICghSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIElmIHdlIGRvbid0IGhhdmUgZmllbGQgcHJlc2VuY2UsIHRoZW4gX2hhc19iaXRzXyBkb2VzIG5vdCBleGlzdC4KKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgLTEsXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgkY2xhc3NuYW1lJCwgX2hhc19iaXRzX1swXSksXG4iKTsKKyAgfQorCisgIC8vIFVua25vd24gZmllbGQgb2Zmc2V0OiBlaXRoZXIgcG9pbnRzIHRvIHRoZSB1bmtub3duIGZpZWxkIHNldCBpZiBlbWJlZGRlZAorICAvLyBkaXJlY3RseSwgb3IgaW5kaWNhdGVzIHRoYXQgdGhlIHVua25vd24gZmllbGQgc2V0IGlzIHN0b3JlZCBhcyBwYXJ0IG9mIHRoZQorICAvLyBpbnRlcm5hbCBtZXRhZGF0YSBpZiBub3QuCisgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgLTEsXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgiCisgICAgICAiJGNsYXNzbmFtZSQsIF91bmtub3duX2ZpZWxkc18pLFxuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoIgorICAgICAgICAiJGNsYXNzbmFtZSQsIF9leHRlbnNpb25zXyksXG4iKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBObyBleHRlbnNpb25zLgorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiICAgIC0xLFxuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgJGNsYXNzbmFtZSRfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8sXG4iCisgICAgIiAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKCIKKyAgICAgICIkY2xhc3NuYW1lJCwgX29uZW9mX2Nhc2VfWzBdKSxcbiIpOworICB9CisKKyAgaWYgKHBhc3NfcG9vbF9hbmRfZmFjdG9yeSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCksXG4iKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICAgICAgICAgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCksXG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiAgICBzaXplb2YoJGNsYXNzbmFtZSQpLFxuIik7CisKKyAgLy8gQXJlbmEgb2Zmc2V0OiBlaXRoZXIgYW4gb2Zmc2V0IHRvIHRoZSBtZXRhZGF0YSBzdHJ1Y3QgdGhhdCBjb250YWlucyB0aGUKKyAgLy8gYXJlbmEgcG9pbnRlciBhbmQgdW5rbm93biBmaWVsZCBzZXQgKGluIGEgc3BhY2UtZWZmaWNpZW50IHdheSkgaWYgd2UgdXNlCisgIC8vIHRoYXQgaW1wbGVtZW50YXRpb24gc3RyYXRlZ3ksIG9yIGFuIG9mZnNldCBkaXJlY3RseSB0byB0aGUgYXJlbmEgcG9pbnRlciBpZgorICAvLyBub3QgKGJlY2F1c2UgZS5nLiB3ZSBkb24ndCBoYXZlIGFuIHVua25vd24gZmllbGQgc2V0KS4KKyAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKCIKKyAgICAiJGNsYXNzbmFtZSQsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLFxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoIgorICAgICIkY2xhc3NuYW1lJCwgX2FyZW5hXyksXG4iKTsKKyAgfQorCisgIC8vIGlzX2RlZmF1bHRfaW5zdGFuY2VfIG9mZnNldC4KKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgLTEpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoIgorICAgICIkY2xhc3NuYW1lJCwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7XG4iKTsKKyAgfQorCisgIC8vIEhhbmRsZSBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIocHJpbnRlciwgaSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIocHJpbnRlciwgaSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlVHlwZVJlZ2lzdHJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gUmVnaXN0ZXIgdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgbWVzc2FnZSBmYWN0b3J5LgorICBpZiAoIUlzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKFxuIgorICAgICAgIiAgICAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXywgJiRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorICBlbHNlIHsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgQ29sbGVjdE1hcEluZm8oZGVzY3JpcHRvcl8sICZ2YXJzKTsKKyAgICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbCA9IGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgaWYgKGRlc2NyaXB0b3JfLT5maWxlKCktPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8yICYmCisgICAgICAgIHZhbC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNKSB7CisgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZWZhdWx0X3ZhbHVlID0gdmFsLT5kZWZhdWx0X3ZhbHVlX2VudW0oKTsKKyAgICAgIHZhcnNbImRlZmF1bHRfZW51bV92YWx1ZSJdID0gSW50MzJUb1N0cmluZyhkZWZhdWx0X3ZhbHVlLT5udW1iZXIoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhcnNbImRlZmF1bHRfZW51bV92YWx1ZSJdID0gIjAiOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoXG4iCisgICAgICAiICAgICAgJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8sXG4iCisgICAgICAiICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TWFwRW50cnk8XG4iCisgICAgICAiICAgICAgICAgICRrZXkkLFxuIgorICAgICAgIiAgICAgICAgICAkdmFsJCxcbiIKKyAgICAgICIgICAgICAgICAgJGtleV93aXJlX3R5cGUkLFxuIgorICAgICAgIiAgICAgICAgICAkdmFsX3dpcmVfdHlwZSQsXG4iCisgICAgICAiICAgICAgICAgICRkZWZhdWx0X2VudW1fdmFsdWUkPjo6Q3JlYXRlRGVmYXVsdEluc3RhbmNlKFxuIgorICAgICAgIiAgICAgICAgICAgICAgJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8pKTtcbiIpOworICB9CisKKyAgLy8gSGFuZGxlIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVR5cGVSZWdpc3RyYXRpb25zKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZURlZmF1bHRJbnN0YW5jZUFsbG9jYXRvcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBDb25zdHJ1Y3QgdGhlIGRlZmF1bHQgaW5zdGFuY2VzIG9mIGFsbCBmaWVsZHMsIGFzIHRoZXkgd2lsbCBiZSB1c2VkCisgIC8vIHdoZW4gY3JlYXRpbmcgdGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhlIGVudGlyZSBtZXNzYWdlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgICAgICAgICAgICAgLkdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKHByaW50ZXIpOworICB9CisKKyAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfKSkgcmV0dXJuOworCisgIC8vIENvbnN0cnVjdCB0aGUgZGVmYXVsdCBpbnN0YW5jZS4gIFdlIGNhbid0IGNhbGwgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeWV0CisgIC8vIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUgYWxsIGRlZmF1bHQgaW5zdGFuY2VzIHRoYXQgdGhpcyBvbmUgbWlnaHQKKyAgLy8gZGVwZW5kIG9uIGFyZSBjb25zdHJ1Y3RlZCBmaXJzdC4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyAkY2xhc3NuYW1lJCgpO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgaWYgKChkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgJiYKKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfID0gbmV3ICRjbGFzc25hbWUkT25lb2ZJbnN0YW5jZSgpO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICAvLyBIYW5kbGUgbmVzdGVkIHR5cGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKHByaW50ZXIpOworICB9CisKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVmYXVsdEluc3RhbmNlSW5pdGlhbGl6ZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICAvLyBSZWdpc3RlciBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVJlZ2lzdHJhdGlvbihwcmludGVyKTsKKyAgfQorCisgIC8vIEhhbmRsZSBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIG1hcCBlbnRyeSBtZXNzYWdlIGRvZXNuJ3QgbmVlZCB0byBpbml0aWFsaXplIGRlZmF1bHQgaW5zdGFuY2UgbWFudWFsbHkuCisgICAgLy8gU2luY2UgbWFwIGVudHJ5IG1lc3NhZ2UgY2Fubm90IGJlIGEgdG9wIGxldmVsIGNsYXNzLCB3ZSBqdXN0IG5lZWQgdG8KKyAgICAvLyBhdm9pZCBjYWxsaW5nIERlZmF1bHRJbnN0YW5jZUluaXRpYWxpemVyIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VJbml0aWFsaXplcihwcmludGVyKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTaHV0ZG93bkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImRlbGV0ZSAkY2xhc3NuYW1lJDo6ZGVmYXVsdF9pbnN0YW5jZV87XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZGVsZXRlICRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfO1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJkZWxldGUgJGNsYXNzbmFtZSRfcmVmbGVjdGlvbl87XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisKKyAgLy8gSGFuZGxlIGRlZmF1bHQgaW5zdGFuY2VzIG9mIGZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZVNodXRkb3duQ29kZShwcmludGVyKTsKKyAgfQorCisgIC8vIEhhbmRsZSBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChJc01hcEVudHJ5TWVzc2FnZShkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpKSBjb250aW51ZTsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlU2h1dGRvd25Db2RlKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsYXNzTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVNZXRob2RzKHByaW50ZXIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gbWFwIGVudHJ5IG1lc3NhZ2UgZG9lc24ndCBuZWVkIGNsYXNzIG1ldGhvZHMuIFNpbmNlIG1hcCBlbnRyeSBtZXNzYWdlCisgICAgLy8gY2Fubm90IGJlIGEgdG9wIGxldmVsIGNsYXNzLCB3ZSBqdXN0IG5lZWQgdG8gYXZvaWQgY2FsbGluZworICAgIC8vIEdlbmVyYXRlQ2xhc3NNZXRob2RzIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVDbGFzc01ldGhvZHMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgcHJpbnRlci0+UHJpbnQoa1RoaW5TZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgbm9uLWlubGluZSBmaWVsZCBkZWZpbml0aW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMocHJpbnRlcik7CisgIH0KKworICAvLyBHZW5lcmF0ZSBmaWVsZCBudW1iZXIgY29uc3RhbnRzLgorICBwcmludGVyLT5QcmludCgiI2lmbmRlZiBfTVNDX1ZFUlxuIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY29uc3QgaW50ICRjbGFzc25hbWUkOjokY29uc3RhbnRfbmFtZSQ7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIENsYXNzTmFtZShGaWVsZFNjb3BlKGZpZWxkKSwgZmFsc2UpLAorICAgICAgImNvbnN0YW50X25hbWUiLCBGaWVsZENvbnN0YW50TmFtZShmaWVsZCkpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICIjZW5kaWYgIC8vICFfTVNDX1ZFUlxuIgorICAgICJcbiIpOworCisgIC8vIERlZmluZSBleHRlbnNpb24gaWRlbnRpZmllcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmaW5pdGlvbihwcmludGVyKTsKKyAgfQorCisgIEdlbmVyYXRlU3RydWN0b3JzKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICBpZiAoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICBHZW5lcmF0ZU9uZW9mQ2xlYXIocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIEdlbmVyYXRlQ2xlYXIocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgICAgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBpZiAoSGFzRmFzdEFycmF5U2VyaWFsaXphdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHByaW50ZXIpOworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgfQorCisgICAgR2VuZXJhdGVCeXRlU2l6ZShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICAgIEdlbmVyYXRlTWVyZ2VGcm9tKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgICAgR2VuZXJhdGVDb3B5RnJvbShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICAgIEdlbmVyYXRlSXNJbml0aWFsaXplZChwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIEdlbmVyYXRlU3dhcChwcmludGVyKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSAkY2xhc3NuYW1lJDo6R2V0TWV0YWRhdGEoKSBjb25zdCB7XG4iCisgICAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7XG4iCisgICAgICAiICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl87XG4iCisgICAgICAiICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gJGNsYXNzbmFtZSRfcmVmbGVjdGlvbl87XG4iCisgICAgICAiICByZXR1cm4gbWV0YWRhdGE7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICI6OnN0ZDo6c3RyaW5nICRjbGFzc25hbWUkOjpHZXRUeXBlTmFtZSgpIGNvbnN0IHtcbiIKKyAgICAgICIgIHJldHVybiBcIiR0eXBlX25hbWUkXCI7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgInR5cGVfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisgIH0KKworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVPZmZzZXRzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJzdGF0aWMgY29uc3QgaW50ICRjbGFzc25hbWUkX29mZnNldHNfWyRmaWVsZF9jb3VudCRdID0ge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXywKKyAgICAiZmllbGRfY291bnQiLCBTaW1wbGVJdG9hKG1heCgKKyAgICAgICAgMSwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpKSkpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiUFJPVE8yX0dFTkVSQVRFRF9ERUZBVUxUX09ORU9GX0ZJRUxEX09GRlNFVCgiCisgICAgICAgICAgIiRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLCAkbmFtZSRfKSxcbiIsCisgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIkdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoJGNsYXNzbmFtZSQsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJG5hbWUkXyksXG4iLAorICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgkY2xhc3NuYW1lJCwgJG5hbWUkXyksXG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAibmFtZSIsIG9uZW9mLT5uYW1lKCkpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifTtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTaGFyZWRDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlNoYXJlZEN0b3IoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKCFIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoU3RyQ2F0KAorICAgICAgdXNlc19zdHJpbmdfID8gIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7XG4iIDogIiIsCisgICAgICAiX2NhY2hlZF9zaXplXyA9IDA7XG4iKS5jX3N0cigpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KKworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7XG4iKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjbGVhcl9oYXNfJG9uZW9mX25hbWUkKCk7XG4iLAorICAgICAgICAib25lb2ZfbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2hhcmVkRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlNoYXJlZER0b3IoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBEbyBub3RoaW5nIHdoZW4gdGhlIG1lc3NhZ2UgaXMgYWxsb2NhdGVkIGluIGFuIGFyZW5hLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgImlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHtcbiIKKyAgICAgICIgIHJldHVybjtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iKTsKKyAgfQorICAvLyBXcml0ZSB0aGUgZGVzdHJ1Y3RvcnMgZm9yIGVhY2ggZmllbGQgZXhjZXB0IG9uZW9mIG1lbWJlcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICghZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZURlc3RydWN0b3JDb2RlKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIC8vIEdlbmVyYXRlIGNvZGUgdG8gZGVzdHJ1Y3Qgb25lb2ZzLiBDbGVhcmluZyBzaG91bGQgZG8gdGhlIHdvcmsuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoaGFzXyRvbmVvZl9uYW1lJCgpKSB7XG4iCisgICAgICAgICIgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgIm9uZW9mX25hbWUiLCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKTsKKyAgfQorCisgIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAiaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHtcbiIsCisgICAgLy8gV2l0aG91dC4KKyAgICAiaWYgKHRoaXMgIT0gJmRlZmF1bHRfaW5zdGFuY2UoKSkge1xuIik7CisKKyAgLy8gV2UgbmVlZCB0byBkZWxldGUgYWxsIGVtYmVkZGVkIG1lc3NhZ2VzLgorICAvLyBUT0RPKGtlbnRvbik6ICBJZiB3ZSBtYWtlIHVuc2V0IG1lc3NhZ2VzIHBvaW50IGF0IGRlZmF1bHQgaW5zdGFuY2VzCisgIC8vICAgaW5zdGVhZCBvZiBOVUxMLCB0aGVuIGl0IHdvdWxkIG1ha2Ugc2Vuc2UgdG8gbW92ZSB0aGlzIGNvZGUgaW50bworICAvLyAgIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVEZXN0cnVjdG9yQ29kZSgpLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJgorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgLy8gU2tpcCBvbmVvZiBtZW1iZXJzCisgICAgICBpZiAoIWZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiICBkZWxldGUgJG5hbWUkXztcbiIsCisgICAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShmaWVsZCkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUFyZW5hRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gR2VuZXJhdGUgdGhlIEFyZW5hRHRvcigpIG1ldGhvZC4gVHJhY2sgd2hldGhlciBhbnkgZmllbGRzIGFjdHVhbGx5IHByb2R1Y2VkCisgIC8vIGNvZGUgdGhhdCBuZWVkcyB0byBiZSBjYWxsZWQuCisgIHByaW50ZXItPlByaW50KAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkFyZW5hRHRvcih2b2lkKiBvYmplY3QpIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIFRoaXMgY29kZSBpcyBwbGFjZWQgaW5zaWRlIGEgc3RhdGljIG1ldGhvZCwgcmF0aGVyIHRoYW4gYW4gb3JkaW5hcnkgb25lLAorICAvLyBzaW5jZSB0aGF0IHNpbXBsaWZpZXMgQXJlbmEncyBkZXN0cnVjdG9yIGxpc3QgKG9yZGluYXJ5IGZ1bmN0aW9uIHBvaW50ZXJzCisgIC8vIHJhdGhlciB0aGFuIG1lbWJlciBmdW5jdGlvbiBwb2ludGVycykuIF90aGlzIGlzIHRoZSBvYmplY3QgYmVpbmcKKyAgLy8gZGVzdHJ1Y3RlZC4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGNsYXNzbmFtZSQqIF90aGlzID0gcmVpbnRlcnByZXRfY2FzdDwgJGNsYXNzbmFtZSQqID4ob2JqZWN0KTtcbiIKKyAgICAgIC8vIGF2b2lkIGFuICJ1bnVzZWQgdmFyaWFibGUiIHdhcm5pbmcgaW4gY2FzZSBubyBmaWVsZHMgaGF2ZSBkdG9yIGNvZGUuCisgICAgICAiKHZvaWQpX3RoaXM7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIGJvb2wgbmVlZF9yZWdpc3RyYXRpb24gPSBmYWxzZTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgLkdlbmVyYXRlQXJlbmFEZXN0cnVjdG9yQ29kZShwcmludGVyKSkgeworICAgICAgbmVlZF9yZWdpc3RyYXRpb24gPSB0cnVlOworICAgIH0KKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIn1cbiIpOworCisgIGlmIChuZWVkX3JlZ2lzdHJhdGlvbikgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaW5saW5lIHZvaWQgJGNsYXNzbmFtZSQ6OlJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7XG4iCisgICAgICAgICIgIGlmIChhcmVuYSAhPSBOVUxMKSB7IgorICAgICAgICAiICAgIGFyZW5hLT5Pd25DdXN0b21EZXN0cnVjdG9yKHRoaXMsICYkY2xhc3NuYW1lJDo6QXJlbmFEdG9yKTtcbiIKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHtcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTdHJ1Y3RvcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgc3RyaW5nIHN1cGVyY2xhc3MgPSBTdXBlckNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgIHN0cmluZyBpbml0aWFsaXplcl93aXRoX2FyZW5hOworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYSA9ICJfaW50ZXJuYWxfbWV0YWRhdGFfKGFyZW5hKSI7CisgIH0gZWxzZSB7CisgICAgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYSA9ICJfYXJlbmFfcHRyXyhhcmVuYSkiOworICB9CisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgICBpbml0aWFsaXplcl93aXRoX2FyZW5hICA9IHN0cmluZygiXG4gIF9leHRlbnNpb25zXyhhcmVuYSkiKSArCisgICAgICAgICghaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYS5lbXB0eSgpID8gICIsICIgOiAiIikgKyBpbml0aWFsaXplcl93aXRoX2FyZW5hOworICB9IGVsc2UgeworICAgIGluaXRpYWxpemVyX3dpdGhfYXJlbmEgID0gIlxuICAiICsgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYTsKKyAgfQorCisgIC8vIEluaXRpYWxpemUgbWVtYmVyIHZhcmlhYmxlcyB3aXRoIGFyZW5hIGNvbnN0cnVjdG9yLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBib29sIGhhc19hcmVuYV9jb25zdHJ1Y3RvciA9IGRlc2NyaXB0b3JfLT5maWVsZChpKS0+aXNfcmVwZWF0ZWQoKTsKKyAgICBpZiAoaGFzX2FyZW5hX2NvbnN0cnVjdG9yKSB7CisgICAgICBpbml0aWFsaXplcl93aXRoX2FyZW5hICs9IHN0cmluZygiLFxuICAiKSArCisgICAgICAgICAgRmllbGROYW1lKGRlc2NyaXB0b3JfLT5maWVsZChpKSkgKyBzdHJpbmcoIl8oYXJlbmEpIik7CisgICAgfQorICB9CisgIGluaXRpYWxpemVyX3dpdGhfYXJlbmEgPSBzdXBlcmNsYXNzICsgIigpIiArCisgICAgICAoIWluaXRpYWxpemVyX3dpdGhfYXJlbmEuZW1wdHkoKSA/ICAiLCIgOiAiICIpICsgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYTsKKworICBzdHJpbmcgaW5pdGlhbGl6ZXJfbnVsbDsKKyAgaW5pdGlhbGl6ZXJfbnVsbCA9IChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkgPworICAgICIsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIiA6ICIsIF9hcmVuYV9wdHJfKE5VTEwpIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGNsYXNzbmFtZSQ6OiRjbGFzc25hbWUkKClcbiIKKyAgICAgICIgIDogJHN1cGVyY2xhc3MkKCkgJGluaXRpYWxpemVyJCB7XG4iCisgICAgICAiICBTaGFyZWRDdG9yKCk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgInN1cGVyY2xhc3MiLCBzdXBlcmNsYXNzLAorICAgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSwKKyAgICAgICJpbml0aWFsaXplciIsIGluaXRpYWxpemVyX251bGwpOworCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIlxuIgorICAgICAgICAiJGNsYXNzbmFtZSQ6OiRjbGFzc25hbWUkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKVxuIgorICAgICAgICAiICA6ICRpbml0aWFsaXplciQge1xuIgorICAgICAgICAiICBTaGFyZWRDdG9yKCk7XG4iCisgICAgICAgICIgIFJlZ2lzdGVyQXJlbmFEdG9yKGFyZW5hKTtcbiIKKyAgICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGFyZW5hX2NvbnN0cnVjdG9yOiRmdWxsX25hbWUkKVxuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImluaXRpYWxpemVyIiwgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYSwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAgICJzdXBlcmNsYXNzIiwgc3VwZXJjbGFzcywKKyAgICAgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIGlmICghSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTtcbiIpOworICB9CisKKyAgLy8gVGhlIGRlZmF1bHQgaW5zdGFuY2UgbmVlZHMgYWxsIG9mIGl0cyBlbWJlZGRlZCBtZXNzYWdlIHBvaW50ZXJzCisgIC8vIGNyb3NzLWxpbmtlZCB0byBvdGhlciBkZWZhdWx0IGluc3RhbmNlcy4gIFdlIGNhbid0IGRvIHRoaXMgaW5pdGlhbGl6YXRpb24KKyAgLy8gaW4gdGhlIGNvbnN0cnVjdG9yIGJlY2F1c2Ugc29tZSBvdGhlciBkZWZhdWx0IGluc3RhbmNlcyBtYXkgbm90IGhhdmUgYmVlbgorICAvLyBjb25zdHJ1Y3RlZCB5ZXQgYXQgdGhhdCB0aW1lLgorICAvLyBUT0RPKGtlbnRvbik6ICBNYXliZSBhbGwgbWVzc2FnZSBmaWVsZHMgKGV2ZW4gZm9yIG5vbi1kZWZhdWx0IG1lc3NhZ2VzKQorICAvLyAgIHNob3VsZCBiZSBpbml0aWFsaXplZCB0byBwb2ludCBhdCBkZWZhdWx0IGluc3RhbmNlcyByYXRoZXIgdGhhbiBOVUxMPworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJgorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgICAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMIHx8CisgICAgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkpIHsKKyAgICAgIHN0cmluZyBuYW1lOworICAgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgbmFtZSA9IGNsYXNzbmFtZV8gKyAiX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLT4iOworICAgICAgfQorICAgICAgbmFtZSArPSBGaWVsZE5hbWUoZmllbGQpOworICAgICAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgICBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgICAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgICAgICIgICRuYW1lJF8gPSBjb25zdF9jYXN0PCAkdHlwZSQqPigmJHR5cGUkOjpkZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICAgLy8gV2l0aG91dC4KKyAgICAgICAgIiAgJG5hbWUkXyA9IGNvbnN0X2Nhc3Q8ICR0eXBlJCo+KFxuIgorICAgICAgICAiICAgICAgJHR5cGUkOjppbnRlcm5hbF9kZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICAgLy8gVmFycy4KKyAgICAgICAgIm5hbWUiLCBuYW1lLAorICAgICAgICAidHlwZSIsIEZpZWxkTWVzc2FnZVR5cGVOYW1lKGZpZWxkKSk7CisgICAgfSBlbHNlIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICYmCisgICAgICAgICAgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAuR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUocHJpbnRlcik7CisgICAgfQorICB9CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGNvcHkgY29uc3RydWN0b3IuCisgIHByaW50ZXItPlByaW50KAorICAgICIkY2xhc3NuYW1lJDo6JGNsYXNzbmFtZSQoY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pXG4iCisgICAgIiAgOiAkc3VwZXJjbGFzcyQoKSIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgInN1cGVyY2xhc3MiLCBzdXBlcmNsYXNzLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIsXG4gICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7XG4iKTsKKyAgfSBlbHNlIGlmICghVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIixcbiAgICBfYXJlbmFfcHRyXyhOVUxMKSB7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAiICBTaGFyZWRDdG9yKCk7XG4iCisgICAgIiAgTWVyZ2VGcm9tKGZyb20pO1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXywKKyAgICAic3VwZXJjbGFzcyIsIHN1cGVyY2xhc3MsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgLy8gR2VuZXJhdGUgdGhlIHNoYXJlZCBjb25zdHJ1Y3RvciBjb2RlLgorICBHZW5lcmF0ZVNoYXJlZENvbnN0cnVjdG9yQ29kZShwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgZGVzdHJ1Y3Rvci4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkOjp+JGNsYXNzbmFtZSQoKSB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgU2hhcmVkRHRvcigpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXywKKyAgICAiZnVsbF9uYW1lIiwgZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgc2hhcmVkIGRlc3RydWN0b3IgY29kZS4KKyAgR2VuZXJhdGVTaGFyZWREZXN0cnVjdG9yQ29kZShwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgYXJlbmEtc3BlY2lmaWMgZGVzdHJ1Y3RvciBjb2RlLgorICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgR2VuZXJhdGVBcmVuYURlc3RydWN0b3JDb2RlKHByaW50ZXIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgU2V0Q2FjaGVkU2l6ZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHtcbiIKKyAgICAiICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpO1xuIgorICAgICIgIF9jYWNoZWRfc2l6ZV8gPSBzaXplO1xuIgorICAgICIgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpO1xuIgorICAgICJ9XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICAvLyBPbmx5IGdlbmVyYXRlIHRoaXMgbWVtYmVyIGlmIGl0J3Mgbm90IGRpc2FibGVkLgorICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgICFkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogJGNsYXNzbmFtZSQ6OmRlc2NyaXB0b3IoKSB7XG4iCisgICAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAiYWRkZGVzY3JpcHRvcnNuYW1lIiwKKyAgICAgIEdsb2JhbEFkZERlc2NyaXB0b3JzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJjb25zdCAkY2xhc3NuYW1lJCYgJGNsYXNzbmFtZSQ6OmRlZmF1bHRfaW5zdGFuY2UoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgZGVzY3JpcHRvcl8tPmZpbGUoKSwgcHJpbnRlciwKKyAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgIiAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpICRhZGRkZXNjcmlwdG9yc25hbWUkKCk7XG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgIiAgJGFkZGRlc2NyaXB0b3JzbmFtZSQoKTtcbiIsCisgICAgLy8gVmFycy4KKyAgICAiYWRkZGVzY3JpcHRvcnNuYW1lIiwKKyAgICBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKS0+bmFtZSgpKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXztcbiIKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAiJGNsYXNzbmFtZSQqICRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiRjbGFzc25hbWUkKiAkY2xhc3NuYW1lJDo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTwkY2xhc3NuYW1lJD4oYXJlbmEpO1xuIgorICAgICAgIn1cbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGNsYXNzbmFtZSQqICRjbGFzc25hbWUkOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHtcbiIKKyAgICAgICIgICRjbGFzc25hbWUkKiBuID0gbmV3ICRjbGFzc25hbWUkO1xuIgorICAgICAgIiAgaWYgKGFyZW5hICE9IE5VTEwpIHtcbiIKKyAgICAgICIgICAgYXJlbmEtPk93bihuKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiBuO1xuIgorICAgICAgIn1cbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworfQorCisvLyBSZXR1cm4gdGhlIG51bWJlciBvZiBiaXRzIHNldCBpbiBuLCBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLgorc3RhdGljIGludCBwb3BjbnQodWludDMyIG4pIHsKKyAgaW50IHJlc3VsdCA9IDA7CisgIHdoaWxlIChuICE9IDApIHsKKyAgICByZXN1bHQgKz0gKG4gJiAxKTsKKyAgICBuID0gbiAvIDI7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoInZvaWQgJGNsYXNzbmFtZSQ6OkNsZWFyKCkge1xuIiwKKyAgICAgICAgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBTdGVwIDE6IEV4dGVuc2lvbnMKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgiX2V4dGVuc2lvbnNfLkNsZWFyKCk7XG4iKTsKKyAgfQorCisgIC8vIFN0ZXAgMjogRXZlcnl0aGluZyBidXQgZXh0ZW5zaW9ucywgcmVwZWF0ZWRzLCB1bmlvbnMuCisgIC8vIFRoZXNlIGFyZSBoYW5kbGVkIGluIGNodW5rcyBvZiA4LiAgVGhlIGZpcnN0IGNodW5rIGlzCisgIC8vIHRoZSBub24tZXh0ZW5zaW9ucy1ub24tcmVwZWF0ZWRzLW5vbi11bmlvbnMgaW4KKyAgLy8gIGRlc2NyaXB0b3JfLT5maWVsZCgwKSwgZGVzY3JpcHRvcl8tPmZpZWxkKDEpLCAuLi4gZGVzY3JpcHRvcl8tPmZpZWxkKDcpLAorICAvLyBhbmQgdGhlIHNlY29uZCBjaHVuayBpcyB0aGUgc2FtZSBmb3IKKyAgLy8gIGRlc2NyaXB0b3JfLT5maWVsZCg4KSwgZGVzY3JpcHRvcl8tPmZpZWxkKDkpLCAuLi4gZGVzY3JpcHRvcl8tPmZpZWxkKDE1KSwKKyAgLy8gZXRjLgorICBzZXQ8aW50PiBzdGVwMl9pbmRpY2VzOworICBoYXNoX21hcDxzdHJpbmcsIGludD4gZmllbGRuYW1lX3RvX2NodW5rOworICBoYXNoX21hcDxpbnQsIHN0cmluZz4gbWVtc2V0c19mb3JfY2h1bms7CisgIGhhc2hfbWFwPGludCwgaW50PiBtZW1zZXRfZmllbGRfY291bnRfZm9yX2NodW5rOworICBoYXNoX3NldDxzdHJpbmc+IGhhbmRsZWQ7ICAvLyBmaWVsZHMgdGhhdCBhcHBlYXIgYW55d2hlcmUgaW4gbWVtc2V0c19mb3JfY2h1bmsKKyAgaGFzaF9tYXA8aW50LCB1aW50MzI+IGZpZWxkc19tYXNrX2Zvcl9jaHVuazsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpICYmICFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBzdGVwMl9pbmRpY2VzLmluc2VydChpKTsKKyAgICAgIGludCBjaHVuayA9IGkgLyA4OworICAgICAgZmllbGRuYW1lX3RvX2NodW5rW0ZpZWxkTmFtZShmaWVsZCldID0gY2h1bms7CisgICAgICBmaWVsZHNfbWFza19mb3JfY2h1bmtbY2h1bmtdIHw9IHN0YXRpY19jYXN0PHVpbnQzMj4oMSkgPDwgKGkgJSAzMik7CisgICAgfQorICB9CisKKyAgLy8gU3RlcCAyYTogR3JlZWRpbHkgc2VlayBydW5zIG9mIGZpZWxkcyB0aGF0IGNhbiBiZSBjbGVhcmVkIGJ5IG1lbXNldC10by0wLgorICAvLyBUaGUgZ2VuZXJhdGVkIGNvZGUgdXNlcyB0d28gbWFjcm9zIHRvIGhlbHAgaXQgY2xlYXIgcnVucyBvZiBmaWVsZHM6CisgIC8vIFpSX0hFTFBFUl8oZjEpIC0gWlJfSEVMUEVSXyhmMCkgY29tcHV0ZXMgdGhlIGRpZmZlcmVuY2UsIGluIGJ5dGVzLCBvZiB0aGUKKyAgLy8gcG9zaXRpb25zIG9mIHR3byBmaWVsZHMgaW4gdGhlIE1lc3NhZ2UuCisgIC8vIFpSXyB6ZXJvZXMgYSBub24tZW1wdHkgcmFuZ2Ugb2YgZmllbGRzIHZpYSBtZW1zZXQuCisgIGNvbnN0IGNoYXIqIG1hY3JvcyA9CisgICAgICAiI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFxcXG4iCisgICAgICAiICAmcmVpbnRlcnByZXRfY2FzdDwkY2xhc3NuYW1lJCo+KDE2KS0+ZilcblxuIgorICAgICAgIiNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XFxcbiIKKyAgICAgICIgIDo6bWVtc2V0KCZmaXJzdCwgMCxcXFxuIgorICAgICAgIiAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcXFxuIgorICAgICAgIn0gd2hpbGUgKDApXG5cbiI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcnVuc19vZl9maWVsZHNfLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgdmVjdG9yPHN0cmluZz4mIHJ1biA9IHJ1bnNfb2ZfZmllbGRzX1tpXTsKKyAgICBpZiAocnVuLnNpemUoKSA8IDIpIGNvbnRpbnVlOworICAgIGNvbnN0IHN0cmluZyYgZmlyc3RfZmllbGRfbmFtZSA9IHJ1blswXTsKKyAgICBjb25zdCBzdHJpbmcmIGxhc3RfZmllbGRfbmFtZSA9IHJ1bi5iYWNrKCk7CisgICAgaW50IGNodW5rID0gZmllbGRuYW1lX3RvX2NodW5rW3J1blswXV07CisgICAgbWVtc2V0c19mb3JfY2h1bmtbY2h1bmtdLmFwcGVuZCgKKyAgICAgICJaUl8oIiArIGZpcnN0X2ZpZWxkX25hbWUgKyAiXywgIiArIGxhc3RfZmllbGRfbmFtZSArICJfKTtcbiIpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgcnVuLnNpemUoKTsgaisrKSB7CisgICAgICBHT09HTEVfRENIRUNLX0VRKGNodW5rLCBmaWVsZG5hbWVfdG9fY2h1bmtbcnVuW2pdXSk7CisgICAgICBoYW5kbGVkLmluc2VydChydW5bal0pOworICAgIH0KKyAgICBtZW1zZXRfZmllbGRfY291bnRfZm9yX2NodW5rW2NodW5rXSArPSBydW4uc2l6ZSgpOworICB9CisgIGNvbnN0IGJvb2wgbWFjcm9zX2FyZV9uZWVkZWQgPSBoYW5kbGVkLnNpemUoKSA+IDA7CisgIGlmIChtYWNyb3NfYXJlX25lZWRlZCkgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludChtYWNyb3MsCisgICAgICAgICAgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICAgIHByaW50ZXItPkluZGVudCgpOworICB9CisgIC8vIFN0ZXAgMmI6IEZpbmlzaCBzdGVwIDIsIGlnbm9yaW5nIGZpZWxkcyBoYW5kbGVkIGluIHN0ZXAgMmEuCisgIGludCBsYXN0X2luZGV4ID0gLTE7CisgIGJvb2wgY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MgPSBmYWxzZTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKHN0ZXAyX2luZGljZXMuY291bnQoaSkgPT0gMCkgY29udGludWU7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBjb25zdCBzdHJpbmcgZmllbGRuYW1lID0gRmllbGROYW1lKGZpZWxkKTsKKyAgICBpZiAoaSAvIDggIT0gbGFzdF9pbmRleCAvIDggfHwgbGFzdF9pbmRleCA8IDApIHsKKyAgICAgIC8vIEVuZCBwcmV2aW91cyBjaHVuaywgaWYgdGhlcmUgd2FzIG9uZS4KKyAgICAgIGlmIChjaHVua19ibG9ja19pbl9wcm9ncmVzcykgeworICAgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgICAgICAgY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MgPSBmYWxzZTsKKyAgICAgIH0KKyAgICAgIC8vIFN0YXJ0IGNodW5rLgorICAgICAgY29uc3Qgc3RyaW5nJiBtZW1zZXRzID0gbWVtc2V0c19mb3JfY2h1bmtbaSAvIDhdOworICAgICAgdWludDMyIG1hc2sgPSBmaWVsZHNfbWFza19mb3JfY2h1bmtbaSAvIDhdOworICAgICAgaW50IGNvdW50ID0gcG9wY250KG1hc2spOworICAgICAgR09PR0xFX0RDSEVDS19HRShjb3VudCwgMSk7CisgICAgICBpZiAoY291bnQgPT0gMSB8fAorICAgICAgICAgIChjb3VudCA8PSA0ICYmIGNvdW50ID09IG1lbXNldF9maWVsZF9jb3VudF9mb3JfY2h1bmtbaSAvIDhdKSkgeworICAgICAgICAvLyBObyAiaWYiIGhlcmUgYmVjYXVzZSB0aGUgY2h1bmsgaXMgdHJpdmlhbC4KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiaWYgKF9oYXNfYml0c19bJGluZGV4JCAvIDMyXSAmICRtYXNrJCkge1xuIiwKKyAgICAgICAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoaSAvIDggKiA4KSwKKyAgICAgICAgICAgICJtYXNrIiwgU2ltcGxlSXRvYShtYXNrKSk7CisgICAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgICAgY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MgPSB0cnVlOworICAgICAgICB9CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludChtZW1zZXRzLmNfc3RyKCkpOworICAgIH0KKyAgICBsYXN0X2luZGV4ID0gaTsKKyAgICBpZiAoaGFuZGxlZC5jb3VudChmaWVsZG5hbWUpID4gMCkgY29udGludWU7CisKKyAgICAvLyBJdCdzIGZhc3RlciB0byBqdXN0IG92ZXJ3cml0ZSBwcmltaXRpdmUgdHlwZXMsIGJ1dCB3ZSBzaG91bGQKKyAgICAvLyBvbmx5IGNsZWFyIHN0cmluZ3MgYW5kIG1lc3NhZ2VzIGlmIHRoZXkgd2VyZSBzZXQuCisgICAgLy8gVE9ETyhrZW50b24pOiAgTGV0IHRoZSBDcHBGaWVsZEdlbmVyYXRvciBkZWNpZGUgdGhpcyBzb21laG93LgorICAgIGJvb2wgc2hvdWxkX2NoZWNrX2JpdCA9CisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSB8fAorICAgICAgZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzsKKworICAgIGJvb2wgaGF2ZV9lbmNsb3NpbmdfaWYgPSBmYWxzZTsKKyAgICBpZiAoc2hvdWxkX2NoZWNrX2JpdCAmJgorICAgICAgICAvLyBJZiBubyBmaWVsZCBwcmVzZW5jZSwgdGhlbiBhbHdheXMgY2xlYXIgc3RyaW5ncy9tZXNzYWdlcyBhcyB3ZWxsLgorICAgICAgICBIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgiaWYgKGhhc18kbmFtZSQoKSkge1xuIiwgIm5hbWUiLCBmaWVsZG5hbWUpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBoYXZlX2VuY2xvc2luZ19pZiA9IHRydWU7CisgICAgfQorCisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUNsZWFyaW5nQ29kZShwcmludGVyKTsKKworICAgIGlmIChoYXZlX2VuY2xvc2luZ19pZikgeworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgIH0KKyAgfQorCisgIGlmIChjaHVua19ibG9ja19pbl9wcm9ncmVzcykgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKyAgaWYgKG1hY3Jvc19hcmVfbmVlZGVkKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJcbiN1bmRlZiBaUl9IRUxQRVJfXG4jdW5kZWYgWlJfXG5cbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICB9CisKKyAgLy8gU3RlcCAzOiBSZXBlYXRlZCBmaWVsZHMgZG9uJ3QgdXNlIF9oYXNfYml0c187IGVtaXQgY29kZSB0byBjbGVhciB0aGVtIGhlcmUuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVDbGVhcmluZ0NvZGUocHJpbnRlcik7CisgICAgfQorICB9CisKKyAgLy8gU3RlcCA0OiBVbmlvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIsCisgICAgICAgICJvbmVvZl9uYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgIH0KKworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIFN0ZXAgNTogRXZlcnl0aGluZyBlbHNlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7XG4iKTsKKyAgfQorCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHtcbiIKKyAgICAgICAgIiAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpO1xuIgorICAgICAgICAifVxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAibXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5jbGVhcigpO1xuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU9uZW9mQ2xlYXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gR2VuZXJhdGVkIGZ1bmN0aW9uIGNsZWFycyB0aGUgYWN0aXZlIGZpZWxkIGFuZCB1bmlvbiBjYXNlIChlLmcuIGZvb19jYXNlXykuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpjbGVhcl8kb25lb2ZuYW1lJCgpIHtcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgICAib25lb2ZuYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzd2l0Y2goJG9uZW9mbmFtZSRfY2FzZSgpKSB7XG4iLAorICAgICAgICAib25lb2ZuYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNhc2UgayRmaWVsZF9uYW1lJDoge1xuIiwKKyAgICAgICAgICAiZmllbGRfbmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQtPm5hbWUoKSwgdHJ1ZSkpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAvLyBXZSBjbGVhciBvbmx5IGFsbG9jYXRlZCBvYmplY3RzIGluIG9uZW9mcworICAgICAgaWYgKCFJc1N0cmluZ09yTWVzc2FnZShmaWVsZCkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiLy8gTm8gbmVlZCB0byBjbGVhclxuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQ2xlYXJpbmdDb2RlKHByaW50ZXIpOworICAgICAgfQorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImJyZWFrO1xuIik7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAifVxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ6IHtcbiIKKyAgICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAiY2FwX29uZW9mX25hbWUiLAorICAgICAgICBUb1VwcGVyKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9XG4iCisgICAgICAgICJfb25lb2ZfY2FzZV9bJG9uZW9mX2luZGV4JF0gPSAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ7XG4iLAorICAgICAgICAib25lb2ZfaW5kZXgiLCBTaW1wbGVJdG9hKGkpLAorICAgICAgICAiY2FwX29uZW9mX25hbWUiLAorICAgICAgICBUb1VwcGVyKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9XG4iCisgICAgICAgICJcbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXAoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIEdlbmVyYXRlIHRoZSBTd2FwIG1lbWJlciBmdW5jdGlvbi4gVGhpcyBpcyBhIGxpZ2h0d2VpZ2h0IHdyYXBwZXIgYXJvdW5kCisgICAgLy8gVW5zYWZlQXJlbmFTd2FwKCkgLyBNZXJnZUZyb20oKSB3aXRoIHRlbXBvcmFyaWVzLCBkZXBlbmRpbmcgb24gdGhlIG1lbW9yeQorICAgIC8vIG93bmVyc2hpcCBzaXR1YXRpb246IHN3YXBwaW5nIGFjcm9zcyBhcmVuYXMgb3IgYmV0d2VlbiBhbiBhcmVuYSBhbmQgYQorICAgIC8vIGhlYXAgcmVxdWlyZXMgY29weWluZy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlN3YXAoJGNsYXNzbmFtZSQqIG90aGVyKSB7XG4iCisgICAgICAgICIgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47XG4iCisgICAgICAgICIgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7XG4iCisgICAgICAgICIgICAgSW50ZXJuYWxTd2FwKG90aGVyKTtcbiIKKyAgICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICAgIiAgICAkY2xhc3NuYW1lJCB0ZW1wO1xuIgorICAgICAgICAiICAgIHRlbXAuTWVyZ2VGcm9tKCp0aGlzKTtcbiIKKyAgICAgICAgIiAgICBDb3B5RnJvbSgqb3RoZXIpO1xuIgorICAgICAgICAiICAgIG90aGVyLT5Db3B5RnJvbSh0ZW1wKTtcbiIKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAifVxuIgorICAgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6VW5zYWZlQXJlbmFTd2FwKCRjbGFzc25hbWUkKiBvdGhlcikge1xuIgorICAgICAgICAiICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuO1xuIgorICAgICAgICAiICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgICAiICBJbnRlcm5hbFN3YXAob3RoZXIpO1xuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6U3dhcCgkY2xhc3NuYW1lJCogb3RoZXIpIHtcbiIKKyAgICAgICAgIiAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjtcbiIKKyAgICAgICAgIiAgSW50ZXJuYWxTd2FwKG90aGVyKTtcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIHRoZSBVbnNhZmVBcmVuYVN3YXAgbWVtYmVyIGZ1bmN0aW9uLgorICBwcmludGVyLT5QcmludCgidm9pZCAkY2xhc3NuYW1lJDo6SW50ZXJuYWxTd2FwKCRjbGFzc25hbWUkKiBvdGhlcikge1xuIiwKKyAgICAgICAgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVTd2FwcGluZ0NvZGUocHJpbnRlcik7CisgICAgfQorCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAic3RkOjpzd2FwKCRvbmVvZl9uYW1lJF8sIG90aGVyLT4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAgICAgInN0ZDo6c3dhcChfb25lb2ZfY2FzZV9bJGkkXSwgb3RoZXItPl9vbmVvZl9jYXNlX1skaSRdKTtcbiIsCisgICAgICAgICJvbmVvZl9uYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwKKyAgICAgICAgImkiLCBTaW1wbGVJdG9hKGkpKTsKKyAgICB9CisKKyAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyAzMSkgLyAzMjsgKytpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJzdGQ6OnN3YXAoX2hhc19iaXRzX1skaSRdLCBvdGhlci0+X2hhc19iaXRzX1skaSRdKTtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICJpIiwgU2ltcGxlSXRvYShpKSk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIl9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pO1xuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgiX3Vua25vd25fZmllbGRzXy5zd2FwKG90aGVyLT5fdW5rbm93bl9maWVsZHNfKTtcbiIpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBTdGlsbCBzd2FwIGludGVybmFsX21ldGFkYXRhIGFzIGl0IG1heSBjb250YWluIG1vcmUgdGhhbiBqdXN0CisgICAgICAvLyB1bmtub3duIGZpZWxkcy4KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoInN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7XG4iKTsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIl9leHRlbnNpb25zXy5Td2FwKCZvdGhlci0+X2V4dGVuc2lvbnNfKTtcbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgiR2V0UmVmbGVjdGlvbigpLT5Td2FwKHRoaXMsIG90aGVyKTsiKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb20oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gR2VuZXJhdGUgdGhlIGdlbmVyYWxpemVkIE1lcmdlRnJvbSAoYWthIHRoYXQgd2hpY2ggdGFrZXMgaW4gdGhlIE1lc3NhZ2UKKyAgICAvLyBiYXNlIGNsYXNzIGFzIGEgcGFyYW1ldGVyKS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7XG4iCisgICAgICAiICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIC8vIENhc3QgdGhlIG1lc3NhZ2UgdG8gdGhlIHByb3BlciB0eXBlLiBJZiB3ZSBmaW5kIHRoYXQgdGhlIG1lc3NhZ2UgaXMKKyAgICAvLyAqbm90KiBvZiB0aGUgcHJvcGVyIHR5cGUsIHdlIGNhbiBzdGlsbCBjYWxsIE1lcmdlIHZpYSB0aGUgcmVmbGVjdGlvbgorICAgIC8vIHN5c3RlbSwgYXMgdGhlIEdPT0dMRV9DSEVDSyBhYm92ZSBlbnN1cmVkIHRoYXQgd2UgaGF2ZSB0aGUgc2FtZSBkZXNjcmlwdG9yCisgICAgLy8gZm9yIGVhY2ggbWVzc2FnZS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb25zdCAkY2xhc3NuYW1lJCogc291cmNlID1cbiIKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgJGNsYXNzbmFtZSQqPihcbiIKKyAgICAgICIgICAgJmZyb20pO1xuIgorICAgICAgImlmIChzb3VyY2UgPT0gTlVMTCkge1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7XG4iCisgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICIgIE1lcmdlRnJvbSgqc291cmNlKTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworICB9IGVsc2UgeworICAgIC8vIEdlbmVyYXRlIENoZWNrVHlwZUFuZE1lcmdlRnJvbSgpLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkNoZWNrVHlwZUFuZE1lcmdlRnJvbShcbiIKKyAgICAgICIgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlTGl0ZSYgZnJvbSkge1xuIgorICAgICAgIiAgTWVyZ2VGcm9tKCo6Omdvb2dsZTo6cHJvdG9idWY6OmRvd25fY2FzdDxjb25zdCAkY2xhc3NuYW1lJCo+KCZmcm9tKSk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIHRoZSBjbGFzcy1zcGVjaWZpYyBNZXJnZUZyb20sIHdoaWNoIGF2b2lkcyB0aGUgR09PR0xFX0NIRUNLIGFuZCBjYXN0LgorICBwcmludGVyLT5QcmludCgKKyAgICAidm9pZCAkY2xhc3NuYW1lJDo6TWVyZ2VGcm9tKGNvbnN0ICRjbGFzc25hbWUkJiBmcm9tKSB7XG4iCisgICAgIiAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBNZXJnZSBSZXBlYXRlZCBmaWVsZHMuIFRoZXNlIGZpZWxkcyBkbyBub3QgcmVxdWlyZSBhCisgIC8vIGNoZWNrIGFzIHdlIGNhbiBzaW1wbHkgaXRlcmF0ZSBvdmVyIHRoZW0uCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVNZXJnaW5nQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KKworICAvLyBNZXJnZSBvbmVvZiBmaWVsZHMuIE9uZW9mIGZpZWxkIHJlcXVpcmVzIG9uZW9mIGNhc2UgY2hlY2suCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgKytpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzd2l0Y2ggKGZyb20uJG9uZW9mbmFtZSRfY2FzZSgpKSB7XG4iLAorICAgICAgICAib25lb2ZuYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNhc2UgayRmaWVsZF9uYW1lJDoge1xuIiwKKyAgICAgICAgICAiZmllbGRfbmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQtPm5hbWUoKSwgdHJ1ZSkpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlTWVyZ2luZ0NvZGUocHJpbnRlcik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiYnJlYWs7XG4iKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjYXNlICRjYXBfb25lb2ZfbmFtZSRfTk9UX1NFVDoge1xuIgorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJjYXBfb25lb2ZfbmFtZSIsCisgICAgICAgIFRvVXBwZXIoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSkpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gTWVyZ2UgT3B0aW9uYWwgYW5kIFJlcXVpcmVkIGZpZWxkcyAoYWZ0ZXIgYSBfaGFzX2JpdCBjaGVjaykuCisgIGludCBsYXN0X2luZGV4ID0gLTE7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgIWZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIC8vIFNlZSBhYm92ZSBpbiBHZW5lcmF0ZUNsZWFyIGZvciBhbiBleHBsYW5hdGlvbiBvZiB0aGlzLgorICAgICAgICBpZiAoaSAvIDggIT0gbGFzdF9pbmRleCAvIDggfHwgbGFzdF9pbmRleCA8IDApIHsKKyAgICAgICAgICBpZiAobGFzdF9pbmRleCA+PSAwKSB7CisgICAgICAgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgICAgICAgfQorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImlmIChmcm9tLl9oYXNfYml0c19bJGluZGV4JCAvIDMyXSAmICIKKyAgICAgICAgICAgICIoMHhmZnUgPDwgKCRpbmRleCQgJSAzMikpKSB7XG4iLAorICAgICAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShmaWVsZC0+aW5kZXgoKSkpOworICAgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGxhc3RfaW5kZXggPSBpOworCisgICAgICBib29sIGhhdmVfZW5jbG9zaW5nX2lmID0gZmFsc2U7CisgICAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaWYgKGZyb20uaGFzXyRuYW1lJCgpKSB7XG4iLAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBoYXZlX2VuY2xvc2luZ19pZiA9IHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBNZXJnZSBzZW1hbnRpY3Mgd2l0aG91dCB0cnVlIGZpZWxkIHByZXNlbmNlOiBwcmltaXRpdmUgZmllbGRzIGFyZQorICAgICAgICAvLyBtZXJnZWQgb25seSBpZiBub24temVybyAobnVtZXJpYykgb3Igbm9uLWVtcHR5IChzdHJpbmcpLgorICAgICAgICBoYXZlX2VuY2xvc2luZ19pZiA9IEVtaXRGaWVsZE5vbkRlZmF1bHRDb25kaXRpb24oCisgICAgICAgICAgICBwcmludGVyLCAiZnJvbS4iLCBmaWVsZCk7CisgICAgICB9CisKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVNZXJnaW5nQ29kZShwcmludGVyKTsKKworICAgICAgaWYgKGhhdmVfZW5jbG9zaW5nX2lmKSB7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICBsYXN0X2luZGV4ID49IDApIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgiX2V4dGVuc2lvbnNfLk1lcmdlRnJvbShmcm9tLl9leHRlbnNpb25zXyk7XG4iKTsKKyAgfQorCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkge1xuIgorICAgICAgICAiICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpO1xuIgorICAgICAgICAifVxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAibXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5hcHBlbmQoZnJvbS51bmtub3duX2ZpZWxkcygpKTtcbiIpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVDb3B5RnJvbShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBHZW5lcmF0ZSB0aGUgZ2VuZXJhbGl6ZWQgQ29weUZyb20gKGFrYSB0aGF0IHdoaWNoIHRha2VzIGluIHRoZSBNZXNzYWdlCisgICAgLy8gYmFzZSBjbGFzcyBhcyBhIHBhcmFtZXRlcikuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjtcbiIKKyAgICAgICJDbGVhcigpO1xuIgorICAgICAgIk1lcmdlRnJvbShmcm9tKTtcbiIpOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgdGhlIGNsYXNzLXNwZWNpZmljIENvcHlGcm9tLgorICBwcmludGVyLT5QcmludCgKKyAgICAidm9pZCAkY2xhc3NuYW1lJDo6Q29weUZyb20oY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjtcbiIKKyAgICAiQ2xlYXIoKTtcbiIKKyAgICAiTWVyZ2VGcm9tKGZyb20pO1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAvLyBTcGVjaWFsLWNhc2UgTWVzc2FnZVNldC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJib29sICRjbGFzc25hbWUkOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgICAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgZGVzY3JpcHRvcl8tPmZpbGUoKSwgcHJpbnRlciwKKyAgICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAgICIgIHJldHVybiBfZXh0ZW5zaW9uc18uUGFyc2VNZXNzYWdlU2V0KGlucHV0LCBkZWZhdWx0X2luc3RhbmNlXyxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSk7XG4iLAorICAgICAgLy8gV2l0aG91dC4KKyAgICAgICIgIHJldHVybiBfZXh0ZW5zaW9uc18uUGFyc2VNZXNzYWdlU2V0KGlucHV0LCAmZGVmYXVsdF9pbnN0YW5jZSgpLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKTtcbiIsCisgICAgICAvLyBWYXJzLgorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIik7CisgICAgcmV0dXJuOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImJvb2wgJGNsYXNzbmFtZSQ6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShcbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7XG4iCisgICAgIiNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmVcbiIKKyAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICBpZiAoIVVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHVua25vd25fZmllbGRzX3N0cmluZyhcbiIKKyAgICAgICIgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpO1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0gdW5rbm93bl9maWVsZHNfc3RyZWFtKFxuIgorICAgICAgIiAgICAgICZ1bmtub3duX2ZpZWxkc19zdHJpbmcpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgiZm9yICg7Oykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IgKiA+IG9yZGVyZWRfZmllbGRzKAorICAgICAgU29ydEZpZWxkc0J5TnVtYmVyKGRlc2NyaXB0b3JfKSk7CisgIHVpbnQzMiBtYXh0YWcgPSBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSA9PSAwID8gMCA6CisgICAgICBXaXJlRm9ybWF0OjpNYWtlVGFnKG9yZGVyZWRfZmllbGRzW2Rlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpIC0gMV0pOworICBjb25zdCBpbnQga0N1dG9mZjAgPSAxMjc7ICAgICAgICAgICAgICAgLy8gZml0cyBpbiAxLWJ5dGUgdmFyaW50CisgIGNvbnN0IGludCBrQ3V0b2ZmMSA9ICgxMjcgPDwgNykgKyAxMjc7ICAvLyBmaXRzIGluIDItYnl0ZSB2YXJpbnQKKyAgcHJpbnRlci0+UHJpbnQoIjo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9ICIKKyAgICAgICAgICAgICAgICAgImlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigkbWF4JCk7XG4iCisgICAgICAgICAgICAgICAgICJ0YWcgPSBwLmZpcnN0O1xuIgorICAgICAgICAgICAgICAgICAiaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDtcbiIsCisgICAgICAgICAgICAgICAgICJtYXgiLCBTaW1wbGVJdG9hKG1heHRhZyA8PSBrQ3V0b2ZmMCA/IGtDdXRvZmYwIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1heHRhZyA8PSBrQ3V0b2ZmMSA/IGtDdXRvZmYxIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heHRhZykpKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpID4gMCkgeworICAgIC8vIFdlIGRvbid0IGV2ZW4gd2FudCB0byBwcmludCB0aGUgc3dpdGNoKCkgaWYgd2UgaGF2ZSBubyBmaWVsZHMgYmVjYXVzZQorICAgIC8vIE1TVkMgZGlzbGlrZXMgc3dpdGNoKCkgc3RhdGVtZW50cyB0aGF0IGNvbnRhaW4gb25seSBhIGRlZmF1bHQgdmFsdWUuCisKKyAgICAvLyBOb3RlOiAgSWYgd2UganVzdCBzd2l0Y2hlZCBvbiB0aGUgdGFnIHJhdGhlciB0aGFuIHRoZSBmaWVsZCBudW1iZXIsIHdlCisgICAgLy8gY291bGQgYXZvaWQgdGhlIG5lZWQgZm9yIHRoZSBpZigpIHRvIGNoZWNrIHRoZSB3aXJlIHR5cGUgYXQgdGhlIGJlZ2lubmluZworICAgIC8vIG9mIGVhY2ggY2FzZS4gIEhvd2V2ZXIsIHRoaXMgaXMgYWN0dWFsbHkgYSBiaXQgc2xvd2VyIGluIHByYWN0aWNlIGFzIGl0CisgICAgLy8gY3JlYXRlcyBhIGp1bXAgdGFibGUgdGhhdCBpcyA4eCBsYXJnZXIgYW5kIHNwYXJzZXIsIGFuZCBtZWFud2hpbGUgdGhlCisgICAgLy8gaWYoKXMgYXJlIGhpZ2hseSBwcmVkaWN0YWJsZS4KKyAgICBwcmludGVyLT5QcmludCgic3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6IgorICAgICAgICAgICAgICAgICAgICJHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7XG4iKTsKKworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3JkZXJlZF9maWVsZHNbaV07CisKKyAgICAgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjYXNlICRudW1iZXIkOiB7XG4iLAorICAgICAgICAibnVtYmVyIiwgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3ImIGZpZWxkX2dlbmVyYXRvciA9IGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCk7CisKKyAgICAgIC8vIEVtaXQgY29kZSB0byBwYXJzZSB0aGUgY29tbW9uLCBleHBlY3RlZCBjYXNlLgorICAgICAgcHJpbnRlci0+UHJpbnQoImlmICh0YWcgPT0gJGNvbW1vbnRhZyQpIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAiY29tbW9udGFnIiwgU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGZpZWxkKSkpOworCisgICAgICBpZiAoaSA+IDAgfHwgKGZpZWxkLT5pc19yZXBlYXRlZCgpICYmICFmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiIHBhcnNlXyRuYW1lJDpcbiIsCisgICAgICAgICAgIm5hbWUiLCBmaWVsZC0+bmFtZSgpKTsKKyAgICAgIH0KKworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBpZiAoZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgICAgICBmaWVsZF9nZW5lcmF0b3IuR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbVdpdGhQYWNraW5nKHByaW50ZXIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZmllbGRfZ2VuZXJhdG9yLkdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0ocHJpbnRlcik7CisgICAgICB9CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgICAgIC8vIEVtaXQgY29kZSB0byBwYXJzZSB1bmV4cGVjdGVkbHkgcGFja2VkIG9yIHVucGFja2VkIHZhbHVlcy4KKyAgICAgIGlmIChmaWVsZC0+aXNfcGFja2FibGUoKSAmJiBmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZXR5cGUgPQorICAgICAgICAgICAgV2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZmllbGQtPnR5cGUoKSk7CisgICAgICAgIHByaW50ZXItPlByaW50KCJ9IGVsc2UgaWYgKHRhZyA9PSAkdW5jb21tb250YWckKSB7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAidW5jb21tb250YWciLCBTaW1wbGVJdG9hKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgd2lyZXR5cGUpKSk7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBmaWVsZF9nZW5lcmF0b3IuR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShwcmludGVyKTsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcGFja2FibGUoKSAmJiAhZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIHdpcmV0eXBlID0KKyAgICAgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRDsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIn0gZWxzZSBpZiAodGFnID09ICR1bmNvbW1vbnRhZyQpIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICJ1bmNvbW1vbnRhZyIsIFNpbXBsZUl0b2EoCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpLCB3aXJldHlwZSkpKTsKKyAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgIGZpZWxkX2dlbmVyYXRvci5HZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtV2l0aFBhY2tpbmcocHJpbnRlcik7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIH0KKworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgICAiICBnb3RvIGhhbmRsZV91bnVzdWFsO1xuIgorICAgICAgICAifVxuIik7CisKKyAgICAgIC8vIHN3aXRjaCgpIGlzIHNsb3cgc2luY2UgaXQgY2FuJ3QgYmUgcHJlZGljdGVkIHdlbGwuICBJbnNlcnQgc29tZSBpZigpcworICAgICAgLy8gaGVyZSB0aGF0IGF0dGVtcHQgdG8gcHJlZGljdCB0aGUgbmV4dCB0YWcuCisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgIWZpZWxkLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICAgICAgLy8gRXhwZWN0IHJlcGVhdHMgb2YgdGhpcyBmaWVsZC4KKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmIChpbnB1dC0+RXhwZWN0VGFnKCR0YWckKSkgZ290byBwYXJzZV8kbmFtZSQ7XG4iLAorICAgICAgICAgICJ0YWciLCBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZmllbGQpKSwKKyAgICAgICAgICAibmFtZSIsIGZpZWxkLT5uYW1lKCkpOworICAgICAgfQorCisgICAgICBpZiAoaSArIDEgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSkgeworICAgICAgICAvLyBFeHBlY3QgdGhlIG5leHQgZmllbGQgaW4gb3JkZXIuCisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmV4dF9maWVsZCA9IG9yZGVyZWRfZmllbGRzW2kgKyAxXTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmIChpbnB1dC0+RXhwZWN0VGFnKCRuZXh0X3RhZyQpKSBnb3RvIHBhcnNlXyRuZXh0X25hbWUkO1xuIiwKKyAgICAgICAgICAibmV4dF90YWciLCBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcobmV4dF9maWVsZCkpLAorICAgICAgICAgICJuZXh0X25hbWUiLCBuZXh0X2ZpZWxkLT5uYW1lKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gRXhwZWN0IEVPRi4KKyAgICAgICAgLy8gVE9ETyhrZW50b24pOiAgRXhwZWN0IGdyb3VwIGVuZC10YWc/CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzcztcbiIpOworICAgICAgfQorCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImJyZWFrO1xuIik7CisKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KCJkZWZhdWx0OiB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoImhhbmRsZV91bnVzdWFsOlxuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICAvLyBJZiB0YWcgaXMgMCBvciBhbiBlbmQtZ3JvdXAgdGFnIHRoZW4gdGhpcyBtdXN0IGJlIHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UuCisgIHByaW50ZXItPlByaW50KAorICAgICJpZiAodGFnID09IDAgfHxcbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09XG4iCisgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7XG4iCisgICAgIiAgZ290byBzdWNjZXNzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBIYW5kbGUgZXh0ZW5zaW9uIHJhbmdlcy4KKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJpZiAoIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlID0KKyAgICAgICAgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZShpKTsKKyAgICAgIGlmIChpID4gMCkgcHJpbnRlci0+UHJpbnQoIiB8fFxuICAgICIpOworCisgICAgICB1aW50MzIgc3RhcnRfdGFnID0gV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgIHJhbmdlLT5zdGFydCwgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OldpcmVUeXBlPigwKSk7CisgICAgICB1aW50MzIgZW5kX3RhZyA9IFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICByYW5nZS0+ZW5kLCBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGU+KDApKTsKKworICAgICAgaWYgKHJhbmdlLT5lbmQgPiBGaWVsZERlc2NyaXB0b3I6OmtNYXhOdW1iZXIpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIigkc3RhcnQkdSA8PSB0YWcpIiwKKyAgICAgICAgICAic3RhcnQiLCBTaW1wbGVJdG9hKHN0YXJ0X3RhZykpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIigkc3RhcnQkdSA8PSB0YWcgJiYgdGFnIDwgJGVuZCR1KSIsCisgICAgICAgICAgInN0YXJ0IiwgU2ltcGxlSXRvYShzdGFydF90YWcpLAorICAgICAgICAgICJlbmQiLCBTaW1wbGVJdG9hKGVuZF90YWcpKTsKKyAgICAgIH0KKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIikge1xuIik7CisgICAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgICAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgICAgICAgLy8gV2l0aCBzdGF0aWMgaW5pdGlhbGl6ZXJzLgorICAgICAgICAgICIgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCBkZWZhdWx0X2luc3RhbmNlXyxcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7XG4iLAorICAgICAgICAgIC8vIFdpdGhvdXQuCisgICAgICAgICAgIiAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsICZkZWZhdWx0X2luc3RhbmNlKCksXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpO1xuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgICAgICAgZGVzY3JpcHRvcl8tPmZpbGUoKSwgcHJpbnRlciwKKyAgICAgICAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgICAgICAgIiAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdW5rbm93bl9maWVsZHNfc3RyZWFtKSk7XG4iLAorICAgICAgICAgIC8vIFdpdGhvdXQuCisgICAgICAgICAgIiAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsICZkZWZhdWx0X2luc3RhbmNlKCksXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1bmtub3duX2ZpZWxkc19zdHJlYW0pKTtcbiIpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAgICAgIiAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfKTtcbiIsCisgICAgICAgIC8vIFdpdGhvdXQuCisgICAgICAgICIgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZGVmYXVsdF9pbnN0YW5jZSgpKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIGNvbnRpbnVlO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gV2UgcmVhbGx5IGRvbid0IHJlY29nbml6ZSB0aGlzIHRhZy4gIFNraXAgaXQuCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKFxuIgorICAgICAgICAiICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChcbiIKKyAgICAgICAgIiAgICBpbnB1dCwgdGFnLCAmdW5rbm93bl9maWVsZHNfc3RyZWFtKSk7XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpO1xuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoImJyZWFrO1xuIik7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsgICAgLy8gZGVmYXVsdDoKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOyAgICAvLyBzd2l0Y2gKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICB9XG4iICAgICAgICAgICAgICAgICAgIC8vIGZvciAoOzspCisgICAgInN1Y2Nlc3M6XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuIHRydWU7XG4iCisgICAgImZhaWx1cmU6XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICIjdW5kZWYgRE9fXG4iCisgICAgIn1cbiIsICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgdG9fYXJyYXkpIHsKKyAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworCisgIGJvb2wgaGF2ZV9lbmNsb3NpbmdfaWYgPSBmYWxzZTsKKyAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiBIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIiwKKyAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgaGF2ZV9lbmNsb3NpbmdfaWYgPSB0cnVlOworICB9IGVsc2UgaWYgKCFIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgaGF2ZV9lbmNsb3NpbmdfaWYgPSBFbWl0RmllbGROb25EZWZhdWx0Q29uZGl0aW9uKHByaW50ZXIsICJ0aGlzLT4iLCBmaWVsZCk7CisgIH0KKworICBpZiAodG9fYXJyYXkpIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgICAgcHJpbnRlcik7CisgIH0gZWxzZSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhwcmludGVyKTsKKyAgfQorCisgIGlmIChoYXZlX2VuY2xvc2luZ19pZikgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVPbmVFeHRlbnNpb25SYW5nZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlLAorICAgIGJvb2wgdG9fYXJyYXkpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJzdGFydCJdID0gU2ltcGxlSXRvYShyYW5nZS0+c3RhcnQpOworICB2YXJzWyJlbmQiXSA9IFNpbXBsZUl0b2EocmFuZ2UtPmVuZCk7CisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIi8vIEV4dGVuc2lvbiByYW5nZSBbJHN0YXJ0JCwgJGVuZCQpXG4iKTsKKyAgaWYgKHRvX2FycmF5KSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJ0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShcbiIKKyAgICAgICIgICAgJHN0YXJ0JCwgJGVuZCQsIHRhcmdldCk7XG5cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhcbiIKKyAgICAgICIgICAgJHN0YXJ0JCwgJGVuZCQsIG91dHB1dCk7XG5cbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgLy8gU3BlY2lhbC1jYXNlIE1lc3NhZ2VTZXQuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7XG4iCisgICAgICAiICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplTWVzc2FnZVNldFdpdGhDYWNoZWRTaXplcyhvdXRwdXQpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBHT09HTEVfQ0hFQ0soVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25NZXNzYWdlU2V0SXRlbXMoXG4iCisgICAgICAiICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTtcbiIpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIn1cbiIpOworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJ2b2lkICRjbGFzc25hbWUkOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoXG4iCisgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzQm9keShwcmludGVyLCBmYWxzZSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOiRmdWxsX25hbWUkKVxuIiwKKyAgICAiZnVsbF9uYW1lIiwgZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgLy8gU3BlY2lhbC1jYXNlIE1lc3NhZ2VTZXQuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogJGNsYXNzbmFtZSQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3Qge1xuIgorICAgICAgIiAgdGFyZ2V0ID1cbiIKKyAgICAgICIgICAgICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplTWVzc2FnZVNldFdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgICAgR09PR0xFX0NIRUNLKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpcbiIKKyAgICAgICIgICAgICAgICAgICAgU2VyaWFsaXplVW5rbm93bk1lc3NhZ2VTZXRJdGVtc1RvQXJyYXkoXG4iCisgICAgICAiICAgICAgICAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTtcbiIpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgcmV0dXJuIHRhcmdldDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICByZXR1cm47CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogJGNsYXNzbmFtZSQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoXG4iCisgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNCb2R5KHByaW50ZXIsIHRydWUpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gdGFyZ2V0O1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzQm9keShpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCB0b19hcnJheSkgeworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Y29uc3QgRmllbGREZXNjcmlwdG9yICogPiBvcmRlcmVkX2ZpZWxkcygKKyAgICAgIFNvcnRGaWVsZHNCeU51bWJlcihkZXNjcmlwdG9yXykpOworCisgIHZlY3Rvcjxjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSo+IHNvcnRlZF9leHRlbnNpb25zOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKTsgKytpKSB7CisgICAgc29ydGVkX2V4dGVuc2lvbnMucHVzaF9iYWNrKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2UoaSkpOworICB9CisgIHN0ZDo6c29ydChzb3J0ZWRfZXh0ZW5zaW9ucy5iZWdpbigpLCBzb3J0ZWRfZXh0ZW5zaW9ucy5lbmQoKSwKKyAgICAgICAgICAgIEV4dGVuc2lvblJhbmdlU29ydGVyKCkpOworCisgIC8vIE1lcmdlIHRoZSBmaWVsZHMgYW5kIHRoZSBleHRlbnNpb24gcmFuZ2VzLCBib3RoIHNvcnRlZCBieSBmaWVsZCBudW1iZXIuCisgIGludCBpLCBqOworICBmb3IgKGkgPSAwLCBqID0gMDsKKyAgICAgICBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgfHwgaiA8IHNvcnRlZF9leHRlbnNpb25zLnNpemUoKTsKKyAgICAgICApIHsKKyAgICBpZiAoaSA9PSBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSkgeworICAgICAgR2VuZXJhdGVTZXJpYWxpemVPbmVFeHRlbnNpb25SYW5nZShwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3J0ZWRfZXh0ZW5zaW9uc1tqKytdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b19hcnJheSk7CisgICAgfSBlbHNlIGlmIChqID09IHNvcnRlZF9leHRlbnNpb25zLnNpemUoKSkgeworICAgICAgR2VuZXJhdGVTZXJpYWxpemVPbmVGaWVsZChwcmludGVyLCBvcmRlcmVkX2ZpZWxkc1tpKytdLCB0b19hcnJheSk7CisgICAgfSBlbHNlIGlmIChvcmRlcmVkX2ZpZWxkc1tpXS0+bnVtYmVyKCkgPCBzb3J0ZWRfZXh0ZW5zaW9uc1tqXS0+c3RhcnQpIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQocHJpbnRlciwgb3JkZXJlZF9maWVsZHNbaSsrXSwgdG9fYXJyYXkpOworICAgIH0gZWxzZSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUV4dGVuc2lvblJhbmdlKHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRlZF9leHRlbnNpb25zW2orK10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvX2FycmF5KTsKKyAgICB9CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHtcbiIpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBpZiAodG9fYXJyYXkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgInRhcmdldCA9ICIKKyAgICAgICAgICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KFxuIgorICAgICAgICAgICIgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTtcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoXG4iCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpO1xuIik7CisgICAgICB9CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifVxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAib3V0cHV0LT5Xcml0ZVJhdyh1bmtub3duX2ZpZWxkcygpLmRhdGEoKSxcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgdW5rbm93bl9maWVsZHMoKS5zaXplKCkpO1xuIik7CisgICAgfQorICB9Cit9CisKK3N0YXRpYyB2ZWN0b3I8dWludDMyPiBSZXF1aXJlZEZpZWxkc0JpdE1hc2soY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICB2ZWN0b3I8dWludDMyPiByZXN1bHQ7CisgIHVpbnQzMiBtYXNrID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoaSA+IDAgJiYgaSAlIDMyID09IDApIHsKKyAgICAgIHJlc3VsdC5wdXNoX2JhY2sobWFzayk7CisgICAgICBtYXNrID0gMDsKKyAgICB9CisgICAgaWYgKGRlc2MtPmZpZWxkKGkpLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICBtYXNrIHw9ICgxIDw8IChpICYgMzEpKTsKKyAgICB9CisgIH0KKyAgaWYgKG1hc2sgIT0gMCkgeworICAgIHJlc3VsdC5wdXNoX2JhY2sobWFzayk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gQ3JlYXRlIGFuIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8KKy8vICAiZm9yIGFsbCBpLCAoX2hhc19iaXRzX1tpXSAmIG1hc2tzW2ldKSA9PSBtYXNrc1tpXSIKKy8vIG1hc2tzIGlzIGFsbG93ZWQgdG8gYmUgc2hvcnRlciB0aGFuIF9oYXNfYml0c18sIGJ1dCBhdCBsZWFzdCBvbmUgZWxlbWVudCBvZgorLy8gbWFza3MgbXVzdCBiZSBub24temVyby4KK3N0YXRpYyBzdHJpbmcgQ29uZGl0aW9uYWxUb0NoZWNrQml0bWFza3MoY29uc3QgdmVjdG9yPHVpbnQzMj4mIG1hc2tzKSB7CisgIHZlY3RvcjxzdHJpbmc+IHBhcnRzOworICBmb3IgKGludCBpID0gMDsgaSA8IG1hc2tzLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKG1hc2tzW2ldID09IDApIGNvbnRpbnVlOworICAgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgICBGYXN0SGV4MzJUb0J1ZmZlcihtYXNrc1tpXSwgYnVmZmVyKTsKKyAgICBzdHJpbmcgbSA9IFN0ckNhdCgiMHgiLCBidWZmZXIpOworICAgIC8vIEVhY2ggeG9yIGV2YWx1YXRlcyB0byAwIGlmIHRoZSBleHBlY3RlZCBiaXRzIGFyZSBwcmVzZW50LgorICAgIHBhcnRzLnB1c2hfYmFjayhTdHJDYXQoIigoX2hhc19iaXRzX1siLCBpLCAiXSAmICIsIG0sICIpIF4gIiwgbSwgIikiKSk7CisgIH0KKyAgR09PR0xFX0NIRUNLKCFwYXJ0cy5lbXB0eSgpKTsKKyAgLy8gSWYgd2UgaGF2ZSBtdWx0aXBsZSBwYXJ0cywgZWFjaCBleHBlY3RlZCB0byBiZSAwLCB0aGVuIGJpdHdpc2Utb3IgdGhlbS4KKyAgc3RyaW5nIHJlc3VsdCA9IHBhcnRzLnNpemUoKSA9PSAxID8gcGFydHNbMF0gOgorICAgICAgU3RyQ2F0KCIoIiwgSm9pbihwYXJ0cywgIlxuICAgICAgIHwgIiksICIpIik7CisgIHJldHVybiByZXN1bHQgKyAiID09IDAiOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgLy8gU3BlY2lhbC1jYXNlIE1lc3NhZ2VTZXQuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaW50ICRjbGFzc25hbWUkOjpCeXRlU2l6ZSgpIGNvbnN0IHtcbiIKKyAgICAgICIgIGludCB0b3RhbF9zaXplID0gX2V4dGVuc2lvbnNfLk1lc3NhZ2VTZXRCeXRlU2l6ZSgpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBHT09HTEVfQ0hFQ0soVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHtcbiIKKyAgICAgICIgIHRvdGFsX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6XG4iCisgICAgICAiICAgICAgQ29tcHV0ZVVua25vd25NZXNzYWdlU2V0SXRlbXNTaXplKHVua25vd25fZmllbGRzKCkpO1xuIgorICAgICAgIn1cbiIpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTtcbiIKKyAgICAgICIgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplO1xuIgorICAgICAgIiAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7XG4iCisgICAgICAiICByZXR1cm4gdG90YWxfc2l6ZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAobnVtX3JlcXVpcmVkX2ZpZWxkc18gPiAxICYmIEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBFbWl0IGEgZnVuY3Rpb24gKHJhcmVseSB1c2VkLCB3ZSBob3BlKSB0aGF0IGhhbmRsZXMgdGhlIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGJ5IGNoZWNraW5nIGZvciBlYWNoIG9uZSBpbmRpdmlkdWFsbHkuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpbnQgJGNsYXNzbmFtZSQ6OlJlcXVpcmVkRmllbGRzQnl0ZVNpemVGYWxsYmFjaygpIGNvbnN0IHtcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgiaW50IHRvdGFsX3NpemUgPSAwO1xuIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgICAgaWYgKGZpZWxkLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgImlmIChoYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisgICAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVCeXRlU2l6ZShwcmludGVyKTsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgICB9CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJcbiIKKyAgICAgICAgICAgICAgICAgICAicmV0dXJuIHRvdGFsX3NpemU7XG4iKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImludCAkY2xhc3NuYW1lJDo6Qnl0ZVNpemUoKSBjb25zdCB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgdG90YWxfc2l6ZSA9IDA7XG4iCisgICAgIlxuIik7CisKKyAgLy8gSGFuZGxlIHJlcXVpcmVkIGZpZWxkcyAoaWYgYW55KS4gIFdlIGV4cGVjdCBhbGwgb2YgdGhlbSB0byBiZQorICAvLyBwcmVzZW50LCBzbyBlbWl0IG9uZSBjb25kaXRpb25hbCB0aGF0IGNoZWNrcyBmb3IgdGhhdC4gIElmIHRoZXkgYXJlIGFsbAorICAvLyBwcmVzZW50IHRoZW4gdGhlIGZhc3QgcGF0aCBleGVjdXRlczsgb3RoZXJ3aXNlIHRoZSBzbG93IHBhdGggZXhlY3V0ZXMuCisgIGlmIChudW1fcmVxdWlyZWRfZmllbGRzXyA+IDEgJiYgSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIFRoZSBmYXN0IHBhdGggd29ya3MgaWYgYWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudC4KKyAgICB2ZWN0b3I8dWludDMyPiBtYXNrc19mb3JfaGFzX2JpdHMgPSBSZXF1aXJlZEZpZWxkc0JpdE1hc2soZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KChzdHJpbmcoImlmICgiKSArCisgICAgICAgICAgICAgICAgICAgIENvbmRpdGlvbmFsVG9DaGVja0JpdG1hc2tzKG1hc2tzX2Zvcl9oYXNfYml0cykgKworICAgICAgICAgICAgICAgICAgICAiKSB7ICAvLyBBbGwgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50LlxuIikuY19zdHIoKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgICAgaWYgKCFmaWVsZC0+aXNfcmVxdWlyZWQoKSkgY29udGludWU7CisgICAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQnl0ZVNpemUocHJpbnRlcik7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9IGVsc2Uge1xuIiAgLy8gdGhlIHNsb3cgcGF0aAorICAgICAgICAgICAgICAgICAgICIgIHRvdGFsX3NpemUgKz0gUmVxdWlyZWRGaWVsZHNCeXRlU2l6ZUZhbGxiYWNrKCk7XG4iCisgICAgICAgICAgICAgICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIC8vIG51bV9yZXF1aXJlZF9maWVsZHNfIDw9IDE6IG5vIG5lZWQgdG8gYmUgdHJpY2t5CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgICAgaWYgKCFmaWVsZC0+aXNfcmVxdWlyZWQoKSkgY29udGludWU7CisgICAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisgICAgICBwcmludGVyLT5QcmludCgiaWYgKGhhc18kbmFtZSQoKSkge1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVCeXRlU2l6ZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgICB9CisgIH0KKworICAvLyBIYW5kbGUgb3B0aW9uYWwgZmllbGRzICh3b3JyeSBiZWxvdyBhYm91dCByZXBlYXRlZHMsIG9uZW9mcywgZXRjLikuCisgIC8vIFRoZXNlIGFyZSBoYW5kbGVkIGluIGNodW5rcyBvZiA4LiAgVGhlIGZpcnN0IGNodW5rIGlzCisgIC8vIHRoZSBub24tcmVxdWlyZWRzLW5vbi1yZXBlYXRlZHMtbm9uLXVuaW9ucy1ub24tZXh0ZW5zaW9ucyBpbgorICAvLyAgZGVzY3JpcHRvcl8tPmZpZWxkKDApLCBkZXNjcmlwdG9yXy0+ZmllbGQoMSksIC4uLiBkZXNjcmlwdG9yXy0+ZmllbGQoNyksCisgIC8vIGFuZCB0aGUgc2Vjb25kIGNodW5rIGlzIHRoZSBzYW1lIGZvcgorICAvLyAgZGVzY3JpcHRvcl8tPmZpZWxkKDgpLCBkZXNjcmlwdG9yXy0+ZmllbGQoOSksIC4uLiBkZXNjcmlwdG9yXy0+ZmllbGQoMTUpLAorICAvLyBldGMuCisgIGhhc2hfbWFwPGludCwgdWludDMyPiBmaWVsZHNfbWFza19mb3JfY2h1bms7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgaWYgKCFmaWVsZC0+aXNfcmVxdWlyZWQoKSAmJiAhZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYKKyAgICAgICAgIWZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkc19tYXNrX2Zvcl9jaHVua1tpIC8gOF0gfD0gc3RhdGljX2Nhc3Q8dWludDMyPigxKSA8PCAoaSAlIDMyKTsKKyAgICB9CisgIH0KKworICBpbnQgbGFzdF9pbmRleCA9IC0xOworICBib29sIGNodW5rX2Jsb2NrX2luX3Byb2dyZXNzID0gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgaWYgKCFmaWVsZC0+aXNfcmVxdWlyZWQoKSAmJiAhZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYKKyAgICAgICAgIWZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIC8vIFNlZSBhYm92ZSBpbiBHZW5lcmF0ZUNsZWFyIGZvciBhbiBleHBsYW5hdGlvbiBvZiB0aGlzLgorICAgICAgLy8gVE9ETyhrZW50b24pOiAgU2hhcmUgY29kZT8gIFVuY2xlYXIgaG93IHRvIGRvIHNvIHdpdGhvdXQKKyAgICAgIC8vICAgb3Zlci1lbmdpbmVlcmluZy4KKyAgICAgIGlmIChpIC8gOCAhPSBsYXN0X2luZGV4IC8gOCB8fCBsYXN0X2luZGV4IDwgMCkgeworICAgICAgICAvLyBFbmQgcHJldmlvdXMgY2h1bmssIGlmIHRoZXJlIHdhcyBvbmUuCisgICAgICAgIGlmIChjaHVua19ibG9ja19pbl9wcm9ncmVzcykgeworICAgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgICAgICAgY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICAvLyBTdGFydCBjaHVuay4KKyAgICAgICAgdWludDMyIG1hc2sgPSBmaWVsZHNfbWFza19mb3JfY2h1bmtbaSAvIDhdOworICAgICAgICBpbnQgY291bnQgPSBwb3BjbnQobWFzayk7CisgICAgICAgIEdPT0dMRV9EQ0hFQ0tfR0UoY291bnQsIDEpOworICAgICAgICBpZiAoY291bnQgPT0gMSkgeworICAgICAgICAgIC8vIE5vICJpZiIgaGVyZSBiZWNhdXNlIHRoZSBjaHVuayBpcyB0cml2aWFsLgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImlmIChfaGFzX2JpdHNfWyRpbmRleCQgLyAzMl0gJiAkbWFzayQpIHtcbiIsCisgICAgICAgICAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoaSksCisgICAgICAgICAgICAgICJtYXNrIiwgU2ltcGxlSXRvYShtYXNrKSk7CisgICAgICAgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgICAgICAgIGNodW5rX2Jsb2NrX2luX3Byb2dyZXNzID0gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGxhc3RfaW5kZXggPSBpOworCisgICAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisKKyAgICAgIGJvb2wgaGF2ZV9lbmNsb3NpbmdfaWYgPSBmYWxzZTsKKyAgICAgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoaGFzXyRuYW1lJCgpKSB7XG4iLAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBoYXZlX2VuY2xvc2luZ19pZiA9IHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBXaXRob3V0IGZpZWxkIHByZXNlbmNlOiBmaWVsZCBpcyBzZXJpYWxpemVkIG9ubHkgaWYgaXQgaGFzIGEKKyAgICAgICAgLy8gbm9uLWRlZmF1bHQgdmFsdWUuCisgICAgICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gRW1pdEZpZWxkTm9uRGVmYXVsdENvbmRpdGlvbigKKyAgICAgICAgICAgIHByaW50ZXIsICJ0aGlzLT4iLCBmaWVsZCk7CisgICAgICB9CisKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVCeXRlU2l6ZShwcmludGVyKTsKKworICAgICAgaWYgKGhhdmVfZW5jbG9zaW5nX2lmKSB7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAiXG4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9CisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGRvbid0IHVzZSBfaGFzX2JpdHNfIHNvIHdlIGNvdW50IHRoZW0gaW4gYSBzZXBhcmF0ZQorICAvLyBwYXNzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQnl0ZVNpemUocHJpbnRlcik7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgIH0KKworICAvLyBGaWVsZHMgaW5zaWRlIGEgb25lb2YgZG9uJ3QgdXNlIF9oYXNfYml0c18gc28gd2UgY291bnQgdGhlbSBpbiBhIHNlcGFyYXRlCisgIC8vIHBhc3MuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzd2l0Y2ggKCRvbmVvZm5hbWUkX2Nhc2UoKSkge1xuIiwKKyAgICAgICAgIm9uZW9mbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJjYXNlIGskZmllbGRfbmFtZSQ6IHtcbiIsCisgICAgICAgICAgImZpZWxkX25hbWUiLCBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGZpZWxkLT5uYW1lKCksIHRydWUpKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUJ5dGVTaXplKHByaW50ZXIpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImJyZWFrO1xuIik7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAifVxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ6IHtcbiIKKyAgICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAiY2FwX29uZW9mX25hbWUiLAorICAgICAgICBUb1VwcGVyKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9XG4iKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidG90YWxfc2l6ZSArPSBfZXh0ZW5zaW9uc18uQnl0ZVNpemUoKTtcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkge1xuIgorICAgICAgICAiICB0b3RhbF9zaXplICs9XG4iCisgICAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKFxuIgorICAgICAgICAiICAgICAgdW5rbm93bl9maWVsZHMoKSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ0b3RhbF9zaXplICs9IHVua25vd25fZmllbGRzKCkuc2l6ZSgpO1xuIgorICAgICAgICAiXG4iKTsKKyAgICB9CisgIH0KKworICAvLyBXZSB1cGRhdGUgX2NhY2hlZF9zaXplXyBldmVuIHRob3VnaCB0aGlzIGlzIGEgY29uc3QgbWV0aG9kLiAgSW4gdGhlb3J5LAorICAvLyB0aGlzIGlzIG5vdCB0aHJlYWQtY29tcGF0aWJsZSwgYmVjYXVzZSBjb25jdXJyZW50IHdyaXRlcyBoYXZlIHVuZGVmaW5lZAorICAvLyByZXN1bHRzLiAgSW4gcHJhY3RpY2UsIHNpbmNlIGFueSBjb25jdXJyZW50IHdyaXRlcyB3aWxsIGJlIHdyaXRpbmcgdGhlCisgIC8vIGV4YWN0IHNhbWUgdmFsdWUsIGl0IHdvcmtzIG9uIGFsbCBjb21tb24gcHJvY2Vzc29ycy4gIEluIGEgZnV0dXJlIHZlcnNpb24KKyAgLy8gb2YgQysrLCBfY2FjaGVkX3NpemVfIHNob3VsZCBiZSBtYWRlIGludG8gYW4gYXRvbWljPGludD4uCisgIHByaW50ZXItPlByaW50KAorICAgICJHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpO1xuIgorICAgICJfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTtcbiIKKyAgICAiR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7XG4iCisgICAgInJldHVybiB0b3RhbF9zaXplO1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUlzSW5pdGlhbGl6ZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImJvb2wgJGNsYXNzbmFtZSQ6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBDaGVjayB0aGF0IGFsbCByZXF1aXJlZCBmaWVsZHMgaW4gdGhpcyBtZXNzYWdlIGFyZSBzZXQuICBXZSBjYW4gZG8gdGhpcworICAgIC8vIG1vc3QgZWZmaWNpZW50bHkgYnkgY2hlY2tpbmcgMzIgImhhcyBiaXRzIiBhdCBhIHRpbWUuCisgICAgaW50IGhhc19iaXRzX2FycmF5X3NpemUgPSAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyAzMSkgLyAzMjsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGhhc19iaXRzX2FycmF5X3NpemU7IGkrKykgeworICAgICAgdWludDMyIG1hc2sgPSAwOworICAgICAgZm9yIChpbnQgYml0ID0gMDsgYml0IDwgMzI7IGJpdCsrKSB7CisgICAgICAgIGludCBpbmRleCA9IGkgKiAzMiArIGJpdDsKKyAgICAgICAgaWYgKGluZGV4ID49IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKSBicmVhazsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpbmRleCk7CisKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICAgICAgbWFzayB8PSAxIDw8IGJpdDsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAobWFzayAhPSAwKSB7CisgICAgICAgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmICgoX2hhc19iaXRzX1skaSRdICYgMHgkbWFzayQpICE9IDB4JG1hc2skKSByZXR1cm4gZmFsc2U7XG4iLAorICAgICAgICAgICJpIiwgU2ltcGxlSXRvYShpKSwKKyAgICAgICAgICAibWFzayIsIEZhc3RIZXgzMlRvQnVmZmVyKG1hc2ssIGJ1ZmZlcikpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIE5vdyBjaGVjayB0aGF0IGFsbCBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgaW5pdGlhbGl6ZWQuCisgIHByaW50ZXItPlByaW50KCJcbiIpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgICAhU2hvdWxkSWdub3JlUmVxdWlyZWRGaWVsZENoZWNrKGZpZWxkKSAmJgorICAgICAgICBIYXNSZXF1aXJlZEZpZWxkcyhmaWVsZC0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+JG5hbWUkKCkpKSIKKyAgICAgICAgICAiIHJldHVybiBmYWxzZTtcbiIsCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChmaWVsZC0+b3B0aW9ucygpLndlYWsoKSB8fCAhZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgICAgIC8vIEZvciB3ZWFrIGZpZWxkcywgdXNlIHRoZSBkYXRhIG1lbWJlciAoOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKikgaW5zdGVhZAorICAgICAgICAgIC8vIG9mIHRoZSBnZXR0ZXIgdG8gYXZvaWQgYSBsaW5rIGRlcGVuZGVuY3kgb24gdGhlIHdlYWsgbWVzc2FnZSB0eXBlCisgICAgICAgICAgLy8gd2hpY2ggaXMgb25seSBmb3J3YXJkIGRlY2xhcmVkLgorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgICAgICAgICAiICBpZiAoIXRoaXMtPiRuYW1lJF8tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgICAgICAgIiAgaWYgKCF0aGlzLT4kbmFtZSQoKS5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAiaWYgKCFfZXh0ZW5zaW9uc18uSXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7Iik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICIgIHJldHVybiB0cnVlO1xuIgorICAgICJ9XG4iKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWE5NjU4MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmgKQEAgLTAsMCArMSwxODAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfTUVTU0FHRV9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworY2xhc3MgRW51bUdlbmVyYXRvcjsgICAgICAgICAgIC8vIGVudW0uaAorY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yOyAgICAgIC8vIGV4dGVuc2lvbi5oCisKK2NsYXNzIE1lc3NhZ2VHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgLy8gU2VlIGdlbmVyYXRvci5jYyBmb3IgdGhlIG1lYW5pbmcgb2YgZGxsZXhwb3J0X2RlY2wuCisgIE1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5NZXNzYWdlR2VuZXJhdG9yKCk7CisKKyAgLy8gSGVhZGVyIHN0dWZmLgorCisgIC8vIEdlbmVyYXRlIGZvd2FyZCBkZWNsYXJhdGlvbnMgZm9yIHRoaXMgY2xhc3MgYW5kIGFsbCBpdHMgbmVzdGVkIHR5cGVzLgorICB2b2lkIEdlbmVyYXRlRm9yd2FyZERlY2xhcmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBkZWZpbml0aW9ucyBvZiBhbGwgbmVzdGVkIGVudW1zIChtdXN0IGNvbWUgYmVmb3JlIGNsYXNzCisgIC8vIGRlZmluaXRpb25zIGJlY2F1c2UgdGhvc2UgY2xhc3NlcyB1c2UgdGhlIGVudW1zIGRlZmluaXRpb25zKS4KKyAgdm9pZCBHZW5lcmF0ZUVudW1EZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgc3BlY2lhbGl6YXRpb25zIG9mIEdldEVudW1EZXNjcmlwdG9yPE15RW51bT4oKS4KKyAgLy8gUHJlY29uZGl0aW9uOiBpbiA6Omdvb2dsZTo6cHJvdG9idWYgbmFtZXNwYWNlLgorICB2b2lkIEdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGRlZmluaXRpb25zIGZvciB0aGlzIGNsYXNzIGFuZCBhbGwgaXRzIG5lc3RlZCB0eXBlcy4KKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgZGVmaW5pdGlvbnMgb2YgaW5saW5lIG1ldGhvZHMgKHBsYWNlZCBhdCB0aGUgZW5kIG9mIHRoZSBoZWFkZXIKKyAgLy8gZmlsZSkuCisgIHZvaWQgR2VuZXJhdGVJbmxpbmVNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSk7CisKKyAgLy8gU291cmNlIGZpbGUgc3R1ZmYuCisKKyAgLy8gR2VuZXJhdGUgY29kZSB3aGljaCBkZWNsYXJlcyBhbGwgdGhlIGdsb2JhbCBkZXNjcmlwdG9yIHBvaW50ZXJzIHdoaWNoCisgIC8vIHdpbGwgYmUgaW5pdGlhbGl6ZWQgYnkgdGhlIG1ldGhvZHMgYmVsb3cuCisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBjb2RlIHRoYXQgaW5pdGlhbGl6ZXMgdGhlIGdsb2JhbCB2YXJpYWJsZSBzdG9yaW5nIHRoZSBtZXNzYWdlJ3MKKyAgLy8gZGVzY3JpcHRvci4KKyAgdm9pZCBHZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcihpbzo6UHJpbnRlciogcHJpbnRlciwgaW50IGluZGV4KTsKKworICAvLyBHZW5lcmF0ZSBjb2RlIHRoYXQgY2FsbHMgTWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKCkKKyAgLy8gZm9yIGFsbCB0eXBlcy4KKyAgdm9pZCBHZW5lcmF0ZVR5cGVSZWdpc3RyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZXMgY29kZSB0aGF0IGFsbG9jYXRlcyB0aGUgbWVzc2FnZSdzIGRlZmF1bHQgaW5zdGFuY2UuCisgIHZvaWQgR2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VBbGxvY2F0b3IoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlcyBjb2RlIHRoYXQgaW5pdGlhbGl6ZXMgdGhlIG1lc3NhZ2UncyBkZWZhdWx0IGluc3RhbmNlLiAgVGhpcworICAvLyBpcyBzZXBhcmF0ZSBmcm9tIGFsbG9jYXRpbmcgYmVjYXVzZSBhbGwgZGVmYXVsdCBpbnN0YW5jZXMgbXVzdCBiZQorICAvLyBhbGxvY2F0ZWQgYmVmb3JlIGFueSBjYW4gYmUgaW5pdGlhbGl6ZWQuCisgIHZvaWQgR2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VJbml0aWFsaXplcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgdGhhdCBzaG91bGQgYmUgcnVuIHdoZW4gU2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKSBpcyBjYWxsZWQsCisgIC8vIHRvIGRlbGV0ZSBhbGwgZHluYW1pY2FsbHktYWxsb2NhdGVkIG9iamVjdHMuCisgIHZvaWQgR2VuZXJhdGVTaHV0ZG93bkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGFsbCBub24taW5saW5lIG1ldGhvZHMgZm9yIHRoaXMgY2xhc3MuCisgIHZvaWQgR2VuZXJhdGVDbGFzc01ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgLy8gR2VuZXJhdGUgZGVjbGFyYXRpb25zIGFuZCBkZWZpbml0aW9ucyBvZiBhY2Nlc3NvcnMgZm9yIGZpZWxkcy4KKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRmllbGRBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSk7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGZpZWxkIG9mZnNldHMgYXJyYXkuCisgIHZvaWQgR2VuZXJhdGVPZmZzZXRzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBjb25zdHJ1Y3RvcnMgYW5kIGRlc3RydWN0b3IuCisgIHZvaWQgR2VuZXJhdGVTdHJ1Y3RvcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIFRoZSBjb21waWxlciB0eXBpY2FsbHkgZ2VuZXJhdGVzIG11bHRpcGxlIGNvcGllcyBvZiBlYWNoIGNvbnN0cnVjdG9yIGFuZAorICAvLyBkZXN0cnVjdG9yOiBodHRwOi8vZ2NjLmdudS5vcmcvYnVncy5odG1sI25vbmJ1Z3NfY3h4CisgIC8vIFBsYWNpbmcgY29tbW9uIGNvZGUgaW4gYSBzZXBhcmF0ZSBtZXRob2QgcmVkdWNlcyB0aGUgZ2VuZXJhdGVkIGNvZGUgc2l6ZS4KKyAgLy8KKyAgLy8gR2VuZXJhdGUgdGhlIHNoYXJlZCBjb25zdHJ1Y3RvciBjb2RlLgorICB2b2lkIEdlbmVyYXRlU2hhcmVkQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgLy8gR2VuZXJhdGUgdGhlIHNoYXJlZCBkZXN0cnVjdG9yIGNvZGUuCisgIHZvaWQgR2VuZXJhdGVTaGFyZWREZXN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIC8vIEdlbmVyYXRlIHRoZSBhcmVuYS1zcGVjaWZpYyBkZXN0cnVjdG9yIGNvZGUuCisgIHZvaWQgR2VuZXJhdGVBcmVuYURlc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBzdGFuZGFyZCBNZXNzYWdlIG1ldGhvZHMuCisgIHZvaWQgR2VuZXJhdGVDbGVhcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVPbmVvZkNsZWFyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc0JvZHkoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgdG9fYXJyYXkpOworICB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUNvcHlGcm9tKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVN3YXAoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlSXNJbml0aWFsaXplZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gSGVscGVycyBmb3IgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKS4KKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgdW5ib3VuZGVkKTsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUV4dGVuc2lvblJhbmdlKAorICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSwKKyAgICAgIGJvb2wgdW5ib3VuZGVkKTsKKworCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBzdHJpbmcgY2xhc3NuYW1lXzsKKyAgT3B0aW9ucyBvcHRpb25zXzsKKyAgRmllbGRHZW5lcmF0b3JNYXAgZmllbGRfZ2VuZXJhdG9yc187CisgIHZlY3RvcjwgdmVjdG9yPHN0cmluZz4gPiBydW5zX29mX2ZpZWxkc187ICAvLyB0aGF0IG1pZ2h0IGJlIHRyaXZpYWxseSBjbGVhcmVkCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2VHZW5lcmF0b3I+ID4gbmVzdGVkX2dlbmVyYXRvcnNfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxFbnVtR2VuZXJhdG9yPiA+IGVudW1fZ2VuZXJhdG9yc187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEV4dGVuc2lvbkdlbmVyYXRvcj4gPiBleHRlbnNpb25fZ2VuZXJhdG9yc187CisgIGludCBudW1fcmVxdWlyZWRfZmllbGRzXzsKKyAgYm9vbCB1c2VzX3N0cmluZ187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX01FU1NBR0VfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2N2I2YmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5jYwpAQCAtMCwwICsxLDY3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCB2YXJpYWJsZXMsIG9wdGlvbnMpOworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IEZpZWxkTWVzc2FnZVR5cGVOYW1lKGRlc2NyaXB0b3IpOworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLndlYWsoKSB8fCAhZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJub25fbnVsbF9wdHJfdG9fbmFtZSJdID0KKyAgICAgICAgU3RyQ2F0KCJ0aGlzLT4iLCAoKnZhcmlhYmxlcylbIm5hbWUiXSwgIl8iKTsKKyAgfQorICAoKnZhcmlhYmxlcylbInN0cmVhbV93cml0ZXIiXSA9ICgqdmFyaWFibGVzKVsiZGVjbGFyZWRfdHlwZSJdICsKKyAgICAgIChIYXNGYXN0QXJyYXlTZXJpYWxpemF0aW9uKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5maWxlKCkpID8KKyAgICAgICAiTWF5YmVUb0FycmF5IiA6CisgICAgICAgIiIpOworICAvLyBOT1RFOiBFc2NhcGVkIGhlcmUgdG8gdW5ibG9jayBwcm90bzEtPnByb3RvMiBtaWdyYXRpb24uCisgIC8vIFRPRE8obGl1amlzaSk6IEV4dGVuZCB0aGlzIHRvIGFwcGx5IGZvciBvdGhlciBjb25mbGljdGluZyBtZXRob2RzLgorICAoKnZhcmlhYmxlcylbInJlbGVhc2VfbmFtZSJdID0KKyAgICAgIFNhZmVGdW5jdGlvbk5hbWUoZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IsICJyZWxlYXNlXyIpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitNZXNzYWdlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfLCBvcHRpb25zKTsKK30KKworTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJHR5cGUkKiAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgInByaXZhdGU6XG4iCisgICAgICAgInZvaWQgX3Nsb3dfbXV0YWJsZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAidm9pZCBfc2xvd19zZXRfYWxsb2NhdGVkXyRuYW1lJChcbiIKKyAgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIG1lc3NhZ2VfYXJlbmEsICR0eXBlJCoqICRuYW1lJCkkZGVwcmVjYXRpb24kO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgIiR0eXBlJCogX3Nsb3dfJHJlbGVhc2VfbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAgInB1YmxpYzpcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImNvbnN0ICR0eXBlJCYgJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICIkdHlwZSQqIG11dGFibGVfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICIkdHlwZSQqICRyZWxlYXNlX25hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF9hbGxvY2F0ZWRfJG5hbWUkKCR0eXBlJCogJG5hbWUkKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJHR5cGUkKiB1bnNhZmVfYXJlbmFfcmVsZWFzZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAidm9pZCB1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF8kbmFtZSQoXG4iCisgICAgICAiICAgICR0eXBlJCogJG5hbWUkKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVOb25JbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6Ol9zbG93X211dGFibGVfJG5hbWUkKCkge1xuIik7CisgICAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICAkbmFtZSRfID0gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgJHR5cGUkID4oXG4iCisgICAgICAiICAgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICIgICRuYW1lJF8gPSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGU8ICR0eXBlJCA+KFxuIgorICAgICAgICAgIiAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iKTsKKyAgICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn1cbiIKKyAgICAgICIkdHlwZSQqICRjbGFzc25hbWUkOjpfc2xvd18kcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIE5VTEw7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAkdHlwZSQqIHRlbXAgPSBuZXcgJHR5cGUkO1xuIgorICAgICAgIiAgICB0ZW1wLT5NZXJnZUZyb20oKiRuYW1lJF8pO1xuIgorICAgICAgIiAgICAkbmFtZSRfID0gTlVMTDtcbiIKKyAgICAgICIgICAgcmV0dXJuIHRlbXA7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIgorICAgICAgIiR0eXBlJCogJGNsYXNzbmFtZSQ6OnVuc2FmZV9hcmVuYV9yZWxlYXNlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICAkdHlwZSQqIHRlbXAgPSAkbmFtZSRfO1xuIgorICAgICAgIiAgJG5hbWUkXyA9IE5VTEw7XG4iCisgICAgICAiICByZXR1cm4gdGVtcDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpfc2xvd19zZXRfYWxsb2NhdGVkXyRuYW1lJChcbiIKKyAgICAgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIG1lc3NhZ2VfYXJlbmEsICR0eXBlJCoqICRuYW1lJCkge1xuIgorICAgICAgICAgICIgICAgaWYgKG1lc3NhZ2VfYXJlbmEgIT0gTlVMTCAmJiBcbiIKKyAgICAgICAgICAiICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpHZXRBcmVuYSgqJG5hbWUkKSA9PSBOVUxMKSB7XG4iCisgICAgICAgICAgIiAgICAgIG1lc3NhZ2VfYXJlbmEtPk93bigqJG5hbWUkKTtcbiIKKyAgICAgICAgICAiICAgIH0gZWxzZSBpZiAobWVzc2FnZV9hcmVuYSAhPVxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpHZXRBcmVuYSgqJG5hbWUkKSkge1xuIgorICAgICAgICAgICIgICAgICAkdHlwZSQqIG5ld18kbmFtZSQgPSBcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgJHR5cGUkID4oXG4iCisgICAgICAgICAgIiAgICAgICAgICAgIG1lc3NhZ2VfYXJlbmEpO1xuIgorICAgICAgICAgICIgICAgICBuZXdfJG5hbWUkLT5Db3B5RnJvbSgqKiRuYW1lJCk7XG4iCisgICAgICAgICAgIiAgICAgICokbmFtZSQgPSBuZXdfJG5hbWUkO1xuIgorICAgICAgICAgICIgICAgfVxuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjp1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF8kbmFtZSQoXG4iCisgICAgICAiICAgICR0eXBlJCogJG5hbWUkKSB7XG4iCisgICAgICAvLyBJZiB3ZSdyZSBub3Qgb24gYW4gYXJlbmEsIGZyZWUgd2hhdGV2ZXIgd2Ugd2VyZSBob2xkaW5nIGJlZm9yZS4KKyAgICAgIC8vIChJZiB3ZSBhcmUgb24gYXJlbmEsIHdlIGNhbiBqdXN0IGZvcmdldCB0aGUgZWFybGllciBwb2ludGVyLikKKyAgICAgICIgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgZGVsZXRlICRuYW1lJF87XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkbmFtZSRfID0gJG5hbWUkO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCkge1xuIgorICAgICAgIiAgICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfdW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWQiCisgICAgICAiOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgY29uc3QgJHR5cGUkJiAkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iKTsKKworICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgdmFyaWFibGVzLCBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAiICByZXR1cm4gJG5hbWUkXyAhPSBOVUxMID8gKiRuYW1lJF8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPiRuYW1lJF87XG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgIiAgcmV0dXJuICRuYW1lJF8gIT0gTlVMTCA/ICokbmFtZSRfIDogKmRlZmF1bHRfaW5zdGFuY2UoKS4kbmFtZSRfO1xuIik7CisKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgJHR5cGUkKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgX3Nsb3dfbXV0YWJsZV8kbmFtZSQoKTsiCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCAkdHlwZSQqICRjbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgIHJldHVybiBfc2xvd18kcmVsZWFzZV9uYW1lJCgpO1xuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJHR5cGUkKiB0ZW1wID0gJG5hbWUkXztcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IE5VTEw7XG4iCisgICAgICAiICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfYWxsb2NhdGVkXyRuYW1lJCgkdHlwZSQqICRuYW1lJCkge1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogbWVzc2FnZV9hcmVuYSA9IEdldEFyZW5hTm9WaXJ0dWFsKCk7XG4iCisgICAgICAiICBpZiAobWVzc2FnZV9hcmVuYSA9PSBOVUxMKSB7XG4iCisgICAgICAiICAgIGRlbGV0ZSAkbmFtZSRfO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgaWYgKCRuYW1lJCAhPSBOVUxMKSB7XG4iKTsKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgLy8gSWYgd2UncmUgb24gYW4gYXJlbmEgYW5kIHRoZSBpbmNvbWluZyBtZXNzYWdlIGlzIG5vdCwgc2ltcGx5IE93bigpIGl0CisgICAgICAvLyByYXRoZXIgdGhhbiBjb3B5IHRvIHRoZSBhcmVuYSAtLSBlaXRoZXIgd2F5IHdlIG5lZWQgYSBoZWFwIGRlYWxsb2MsCisgICAgICAvLyBzbyB3ZSBtaWdodCBhcyB3ZWxsIGRlZmVyIGl0LiBPdGhlcndpc2UsIGlmIGluY29taW5nIG1lc3NhZ2UgaXMgb24gYQorICAgICAgLy8gZGlmZmVyZW50IG93bmVyc2hpcCBkb21haW4gKHNwZWNpZmljIGFyZW5hLCBvciB0aGUgaGVhcCkgdGhhbiB3ZSBhcmUsCisgICAgICAvLyBjb3B5IHRvIG91ciBhcmVuYSAob3IgaGVhcCwgYXMgdGhlIGNhc2UgbWF5IGJlKS4KKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgIiAgICBfc2xvd19zZXRfYWxsb2NhdGVkXyRuYW1lJChtZXNzYWdlX2FyZW5hLCAmJG5hbWUkKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAgICIgICAgaWYgKG1lc3NhZ2VfYXJlbmEgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgICAgbWVzc2FnZV9hcmVuYS0+T3duKCRuYW1lJCk7XG4iCisgICAgICAgICIgICAgfVxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRuYW1lJF8gPSAkbmFtZSQ7XG4iCisgICAgICAiICBpZiAoJG5hbWUkKSB7XG4iCisgICAgICAiICAgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgJHR5cGUkKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IG5ldyAkdHlwZSQ7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCAkdHlwZSQqICRjbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICAkdHlwZSQqIHRlbXAgPSAkbmFtZSRfO1xuIgorICAgICAgIiAgJG5hbWUkXyA9IE5VTEw7XG4iCisgICAgICAiICByZXR1cm4gdGVtcDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0X2FsbG9jYXRlZF8kbmFtZSQoJHR5cGUkKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIGRlbGV0ZSAkbmFtZSRfO1xuIik7CisKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiAgaWYgKCRuYW1lJCAhPSBOVUxMICYmICRuYW1lJC0+R2V0QXJlbmEoKSAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgICR0eXBlJCogbmV3XyRuYW1lJCA9IG5ldyAkdHlwZSQ7XG4iCisgICAgICAiICAgIG5ld18kbmFtZSQtPkNvcHlGcm9tKCokbmFtZSQpO1xuIgorICAgICAgIiAgICAkbmFtZSQgPSBuZXdfJG5hbWUkO1xuIgorICAgICAgIiAgfVxuIik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiAgJG5hbWUkXyA9ICRuYW1lJDtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQpIHtcbiIKKyAgICAgICIgICAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKCFIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBoYXMtYml0cywgbWVzc2FnZSBwcmVzZW5jZSBpcyBpbmRpY2F0ZWQgb25seSBieSBwdHIgIT0KKyAgICAvLyBOVUxMLiBUaHVzIG9uIGNsZWFyLCB3ZSBuZWVkIHRvIGRlbGV0ZSB0aGUgb2JqZWN0LgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRuYW1lJF8gIT0gTlVMTCkgZGVsZXRlICRuYW1lJF87XG4iCisgICAgICAiJG5hbWUkXyA9IE5VTEw7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICgkbmFtZSRfICE9IE5VTEwpICRuYW1lJF8tPiR0eXBlJDo6Q2xlYXIoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAibXV0YWJsZV8kbmFtZSQoKS0+JHR5cGUkOjpNZXJnZUZyb20oZnJvbS4kbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInN0ZDo6c3dhcCgkbmFtZSRfLCBvdGhlci0+JG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSBOVUxMO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoXG4iCisgICAgICAiICAgICBpbnB1dCwgbXV0YWJsZV8kbmFtZSQoKSkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRHcm91cE5vVmlydHVhbChcbiIKKyAgICAgICIgICAgICAkbnVtYmVyJCwgaW5wdXQsIG11dGFibGVfJG5hbWUkKCkpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZSRzdHJlYW1fd3JpdGVyJChcbiIKKyAgICAiICAkbnVtYmVyJCwgKiRub25fbnVsbF9wdHJfdG9fbmFtZSQsIG91dHB1dCk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAiICBXcml0ZSRkZWNsYXJlZF90eXBlJE5vVmlydHVhbFRvQXJyYXkoXG4iCisgICAgIiAgICAkbnVtYmVyJCwgKiRub25fbnVsbF9wdHJfdG9fbmFtZSQsIHRhcmdldCk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokZGVjbGFyZWRfdHlwZSRTaXplTm9WaXJ0dWFsKFxuIgorICAgICIgICAgKiRub25fbnVsbF9wdHJfdG9fbmFtZSQpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBNZXNzYWdlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgb3B0aW9ucykgeworICBTZXRDb21tb25PbmVvZkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6On5NZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIkaW5saW5lJCBjb25zdCAkdHlwZSQmICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuIGhhc18kbmFtZSQoKSA/ICokb25lb2ZfcHJlZml4JCRuYW1lJF9cbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgOiAkdHlwZSQ6OmRlZmF1bHRfaW5zdGFuY2UoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgJHR5cGUkKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIpOworICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXyA9IFxuIgorICAgICAgICAgIiAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8ICR0eXBlJCA+KFxuIgorICAgICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gXG4iCisgICAgICAgICAiICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlPCAkdHlwZSQgPihcbiIKKyAgICAgICAgICIgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkb25lb2ZfcHJlZml4JCRuYW1lJF87XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkICR0eXBlJCogJGNsYXNzbmFtZSQ6OiRyZWxlYXNlX25hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl9oYXNfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHtcbiIKKyAgICAgIC8vIE4uQi46IHNhZmUgdG8gdXNlIHRoZSB1bmRlcmx5aW5nIGZpZWxkIHBvaW50ZXIgaGVyZSBiZWNhdXNlIHdlIGFyZSBzdXJlCisgICAgICAvLyB0aGF0IGl0IGlzIG5vbi1OVUxMIChiZWNhdXNlIGhhc18kbmFtZSQoKSByZXR1cm5lZCB0cnVlKS4KKyAgICAgICIgICAgICAkdHlwZSQqIHRlbXAgPSBuZXcgJHR5cGUkO1xuIgorICAgICAgIiAgICAgIHRlbXAtPk1lcmdlRnJvbSgqJG9uZW9mX3ByZWZpeCQkbmFtZSRfKTtcbiIKKyAgICAgICIgICAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAgICR0eXBlJCogdGVtcCA9ICRvbmVvZl9wcmVmaXgkJG5hbWUkXztcbiIKKyAgICAgICIgICAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gTlVMTDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgJHR5cGUkKiAkY2xhc3NuYW1lJDo6dW5zYWZlX2FyZW5hX3JlbGVhc2VfJG5hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl9oYXNfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgICR0eXBlJCogdGVtcCA9ICRvbmVvZl9wcmVmaXgkJG5hbWUkXztcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gTlVMTDtcbiIKKyAgICAgICIgICAgcmV0dXJuIHRlbXA7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gTlVMTDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0X2FsbG9jYXRlZF8kbmFtZSQoJHR5cGUkKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCkge1xuIik7CisKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAvLyBJZiBpbmNvbWluZyBtZXNzYWdlIGlzIG9uIHRoZSBoZWFwIGFuZCB3ZSBhcmUgb24gYW4gYXJlbmEsIGp1c3QgT3duKCkKKyAgICAgICAgLy8gaXQgKHNlZSBhYm92ZSkuIElmIGl0J3Mgb24gYSBkaWZmZXJlbnQgYXJlbmEgdGhhbiB3ZSBhcmUgb3Igb25lIG9mIHVzCisgICAgICAgIC8vIGlzIG9uIHRoZSBoZWFwLCB3ZSBtYWtlIGEgY29weSB0byBvdXIgYXJlbmEvaGVhcC4KKyAgICAgICAgIiAgICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMICYmXG4iCisgICAgICAgICIgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkdldEFyZW5hKCRuYW1lJCkgPT0gTlVMTCkge1xuIgorICAgICAgICAiICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKS0+T3duKCRuYW1lJCk7XG4iCisgICAgICAgICIgICAgfSBlbHNlIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9XG4iCisgICAgICAgICIgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpHZXRBcmVuYSgkbmFtZSQpKSB7XG4iCisgICAgICAgICIgICAgICAkdHlwZSQqIG5ld18kbmFtZSQgPSBcbiIKKyAgICAgICAgIiAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPCAkdHlwZSQgPihcbiIKKyAgICAgICAgIiAgICAgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICAgIiAgICAgIG5ld18kbmFtZSQtPkNvcHlGcm9tKCokbmFtZSQpO1xuIgorICAgICAgICAiICAgICAgJG5hbWUkID0gbmV3XyRuYW1lJDtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAiICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCktPk93bigkbmFtZSQpO1xuIgorICAgICAgICAiICAgIH1cbiIpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gJG5hbWUkO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkXyRuYW1lJCgiCisgICAgICAiJHR5cGUkKiAkbmFtZSQpIHtcbiIKKyAgICAgIC8vIFdlIHJlbHkgb24gdGhlIG9uZW9mIGNsZWFyIG1ldGhvZCB0byBmcmVlIHRoZSBlYXJsaWVyIGNvbnRlbnRzIG9mIHRoaXMKKyAgICAgIC8vIG9uZW9mLiBXZSBjYW4gZGlyZWN0bHkgdXNlIHRoZSBwb2ludGVyIHdlJ3JlIGdpdmVuIHRvIHNldCB0aGUgbmV3CisgICAgICAvLyB2YWx1ZS4KKyAgICAgICIgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCkge1xuIgorICAgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSAkbmFtZSQ7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfdW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWQ6IgorICAgICAgIiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIkaW5saW5lJCBjb25zdCAkdHlwZSQmICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuIGhhc18kbmFtZSQoKSA/ICokb25lb2ZfcHJlZml4JCRuYW1lJF9cbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgOiAkdHlwZSQ6OmRlZmF1bHRfaW5zdGFuY2UoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgJHR5cGUkKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gbmV3ICR0eXBlJDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRvbmVvZl9wcmVmaXgkJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgJHR5cGUkKiAkY2xhc3NuYW1lJDo6JHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIGNsZWFyX2hhc18kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJHR5cGUkKiB0ZW1wID0gJG9uZW9mX3ByZWZpeCQkbmFtZSRfO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgICByZXR1cm4gdGVtcDtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIHJldHVybiBOVUxMO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfYWxsb2NhdGVkXyRuYW1lJCgkdHlwZSQqICRuYW1lJCkge1xuIgorICAgICAgIiAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICBpZiAoJG5hbWUkKSB7XG4iKTsKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAiICAgIGlmICgkbmFtZSQtPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgICAgJHR5cGUkKiBuZXdfJG5hbWUkID0gbmV3ICR0eXBlJDtcbiIKKyAgICAgICAgIiAgICAgIG5ld18kbmFtZSQtPkNvcHlGcm9tKCokbmFtZSQpO1xuIgorICAgICAgICAiICAgICAgJG5hbWUkID0gbmV3XyRuYW1lJDtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSAkbmFtZSQ7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwpIHtcbiIKKyAgICAgICIgIGRlbGV0ZSAkb25lb2ZfcHJlZml4JCRuYW1lJF87XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJkZWxldGUgJG9uZW9mX3ByZWZpeCQkbmFtZSRfO1xuIik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBEb24ndCBwcmludCBhbnkgc3dhcHBpbmcgY29kZS4gU3dhcHBpbmcgdGhlIHVuaW9uIHdpbGwgc3dhcCB0aGlzIGZpZWxkLgorfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIERvbid0IHByaW50IGFueSBjb25zdHJ1Y3RvciBjb2RlLiBUaGUgZmllbGQgaXMgaW4gYSB1bmlvbi4gV2UgYWxsb2NhdGUKKyAgLy8gc3BhY2Ugb25seSB3aGVuIHRoaXMgZmllbGQgaXMgdXNlZC4KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7Cit9CisKK1JlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCAkdHlwZSQgPiAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb25zdCAkdHlwZSQmICRuYW1lJChpbnQgaW5kZXgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAiJHR5cGUkKiBtdXRhYmxlXyRuYW1lJChpbnQgaW5kZXgpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAiJHR5cGUkKiBhZGRfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgJHR5cGUkID4mXG4iCisgICAgIiAgICAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgJHR5cGUkID4qXG4iCisgICAgIiAgICBtdXRhYmxlXyRuYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgY29uc3QgJHR5cGUkJiAkY2xhc3NuYW1lJDo6JG5hbWUkKGludCBpbmRleCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uJGNwcGdldCQoaW5kZXgpO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkICR0eXBlJCogJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAkbmFtZSRfLk11dGFibGUoaW5kZXgpO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkICR0eXBlJCogJGNsYXNzbmFtZSQ6OmFkZF8kbmFtZSQoKSB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5BZGQoKTtcbiIKKyAgICAifVxuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCAkdHlwZSQgPiZcbiIKKyAgICAiJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8ICR0eXBlJCA+KlxuIgorICAgICIkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJiRuYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLkNsZWFyKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLk1lcmdlRnJvbShmcm9tLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+JG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBOb3QgbmVlZGVkIGZvciByZXBlYXRlZCBmaWVsZHMuCit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbChcbiIKKyAgICAgICIgICAgICBpbnB1dCwgYWRkXyRuYW1lJCgpKSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZEdyb3VwTm9WaXJ0dWFsKFxuIgorICAgICAgIiAgICAgICRudW1iZXIkLCBpbnB1dCwgYWRkXyRuYW1lJCgpKSk7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+JG5hbWUkX3NpemUoKTsgaSA8IG47IGkrKykge1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZSRzdHJlYW1fd3JpdGVyJChcbiIKKyAgICAiICAgICRudW1iZXIkLCB0aGlzLT4kbmFtZSQoaSksIG91dHB1dCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkgPCBuOyBpKyspIHtcbiIKKyAgICAiICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6XG4iCisgICAgIiAgICBXcml0ZSRkZWNsYXJlZF90eXBlJE5vVmlydHVhbFRvQXJyYXkoXG4iCisgICAgIiAgICAgICRudW1iZXIkLCB0aGlzLT4kbmFtZSQoaSksIHRhcmdldCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidG90YWxfc2l6ZSArPSAkdGFnX3NpemUkICogdGhpcy0+JG5hbWUkX3NpemUoKTtcbiIKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT4kbmFtZSRfc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICB0b3RhbF9zaXplICs9XG4iCisgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6JGRlY2xhcmVkX3R5cGUkU2l6ZU5vVmlydHVhbChcbiIKKyAgICAiICAgICAgdGhpcy0+JG5hbWUkKGkpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2VfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTcwNGZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDEyNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfTUVTU0FHRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIE1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5NZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTm9uSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgTWVzc2FnZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5NZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVOb25JbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7fQorICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5SZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NRVNTQUdFX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX29wdGlvbnMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM5OWNmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmgKQEAgLTAsMCArMSw1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogcmVubmllQGdvb2dsZS5jb20gKEplZmZyZXkgUmVubmllKQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfT1BUSU9OU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9PUFRJT05TX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBHZW5lcmF0b3Igb3B0aW9uczoKK3N0cnVjdCBPcHRpb25zIHsKKyAgT3B0aW9ucygpIDogc2FmZV9ib3VuZGFyeV9jaGVjayhmYWxzZSkgeworICB9CisgIHN0cmluZyBkbGxleHBvcnRfZGVjbDsKKyAgYm9vbCBzYWZlX2JvdW5kYXJ5X2NoZWNrOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfT1BUSU9OU19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wbHVnaW5fdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcGx1Z2luX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxZWZiZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcGx1Z2luX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFRPRE8oa2VudG9uKTogIFNoYXJlIGNvZGUgd2l0aCB0aGUgdmVyc2lvbnMgb2YgdGhpcyB0ZXN0IGluIG90aGVyIGxhbmd1YWdlcz8KKy8vICAgSXQgc2VlbWVkIGxpa2UgcGFyYW1ldGVyaXppbmcgaXQgd291bGQgYWRkIG1vcmUgY29tcGxleGl0eSB0aGFuIGl0IGlzCisvLyAgIHdvcnRoLgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKK25hbWVzcGFjZSB7CisKK2NsYXNzIFRlc3RHZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBUZXN0R2VuZXJhdG9yKCkge30KKyAgflRlc3RHZW5lcmF0b3IoKSB7fQorCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJpbmNsdWRlcyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgIm5hbWVzcGFjZV9zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImdsb2JhbF9zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImNsYXNzX3Njb3BlOmZvby5CYXIiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJjbGFzc19zY29wZTpmb28uQmFyLkJheiIsIGNvbnRleHQpOworCisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmNjIiwgImluY2x1ZGVzIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmNjIiwgIm5hbWVzcGFjZV9zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5jYyIsICJnbG9iYWxfc2NvcGUiLCBjb250ZXh0KTsKKworICAgIC8vIENoZWNrIGZpZWxkIGFjY2Vzc29ycyBmb3IgYW4gb3B0aW9uYWwgaW50MzI6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIub3B0SW50IiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIub3B0SW50IiwgY29udGV4dCk7CisKKyAgICAvLyBDaGVjayBmaWVsZCBhY2Nlc3NvcnMgZm9yIGEgcmVwZWF0ZWQgaW50MzI6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVwZWF0ZWRJbnQiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXQ6Zm9vLkJhci5yZXBlYXRlZEludCIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcXVpcmVkIHN0cmluZzoKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5yZXF1aXJlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLnJlcXVpcmVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X2NoYXI6Zm9vLkJhci5yZXF1aXJlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9wb2ludGVyOmZvby5CYXIucmVxdWlyZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIucmVxdWlyZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfYWxsb2NhdGVkOmZvby5CYXIucmVxdWlyZWRTdHJpbmciLAorICAgICAgICAgICAgICBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfY2hhcjpmb28uQmFyLnJlcXVpcmVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X3BvaW50ZXI6Zm9vLkJhci5yZXF1aXJlZFN0cmluZyIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcGVhdGVkIHN0cmluZzoKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5yZXBlYXRlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLnJlcGVhdGVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X2NoYXI6Zm9vLkJhci5yZXBlYXRlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9wb2ludGVyOmZvby5CYXIucmVwZWF0ZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIucmVwZWF0ZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfY2hhcjpmb28uQmFyLnJlcGVhdGVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X3BvaW50ZXI6Zm9vLkJhci5yZXBlYXRlZFN0cmluZyIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhbiBpbnQgaW5zaWRlIG9uZW9me306CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIub25lT2ZJbnQiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXQ6Zm9vLkJhci5vbmVPZkludCIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHN0cmluZyBpbnNpZGUgb25lb2Z7fToKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5vbmVPZlN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLm9uZU9mU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X2NoYXI6Zm9vLkJhci5vbmVPZlN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9wb2ludGVyOmZvby5CYXIub25lT2ZTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIub25lT2ZTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfYWxsb2NhdGVkOmZvby5CYXIub25lT2ZTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfY2hhcjpmb28uQmFyLm9uZU9mU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X3BvaW50ZXI6Zm9vLkJhci5vbmVPZlN0cmluZyIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhbiBvcHRpb25hbCBtZXNzYWdlOgorICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX2dldDpmb28uQmFyLm9wdE1lc3NhZ2UiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIub3B0TWVzc2FnZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9hbGxvY2F0ZWQ6Zm9vLkJhci5vcHRNZXNzYWdlIiwgY29udGV4dCk7CisKKyAgICAvLyBDaGVjayBmaWVsZCBhY2Nlc3NvcnMgZm9yIGEgcmVwZWF0ZWQgbWVzc2FnZToKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9hZGQ6Zm9vLkJhci5yZXBlYXRlZE1lc3NhZ2UiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5yZXBlYXRlZE1lc3NhZ2UiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9saXN0OmZvby5CYXIucmVwZWF0ZWRNZXNzYWdlIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbXV0YWJsZTpmb28uQmFyLnJlcGVhdGVkTWVzc2FnZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGVfbGlzdDpmb28uQmFyLnJlcGVhdGVkTWVzc2FnZSIsCisgICAgICAgICAgICAgIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIG1lc3NhZ2UgaW5zaWRlIG9uZW9me306CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIub25lT2ZNZXNzYWdlIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbXV0YWJsZTpmb28uQmFyLm9uZU9mTWVzc2FnZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9hbGxvY2F0ZWQ6Zm9vLkJhci5vbmVPZk1lc3NhZ2UiLCBjb250ZXh0KTsKKworICAgIC8vIENoZWNrIGZpZWxkIGFjY2Vzc29ycyBmb3IgYW4gb3B0aW9uYWwgZW51bToKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5vcHRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIub3B0RW51bSIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcGVhdGVkIGVudW06CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVwZWF0ZWRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIucmVwZWF0ZWRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfYWRkOmZvby5CYXIucmVwZWF0ZWRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbGlzdDpmb28uQmFyLnJlcGVhdGVkRW51bSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGVfbGlzdDpmb28uQmFyLnJlcGVhdGVkRW51bSIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhbiBlbnVtIGluc2lkZSBvbmVvZnt9OgorICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX2dldDpmb28uQmFyLm9uZU9mRW51bSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLm9uZU9mRW51bSIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcXVpcmVkIGNvcmQ6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVxdWlyZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIucmVxdWlyZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbXV0YWJsZTpmb28uQmFyLnJlcXVpcmVkQ29yZCIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcGVhdGVkIGNvcmQ6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVwZWF0ZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIucmVwZWF0ZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfYWRkOmZvby5CYXIucmVwZWF0ZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbGlzdDpmb28uQmFyLnJlcGVhdGVkQ29yZCIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGU6Zm9vLkJhci5yZXBlYXRlZENvcmQiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlX2xpc3Q6Zm9vLkJhci5yZXBlYXRlZENvcmQiLCBjb250ZXh0KTsKKworICAgIC8vIENoZWNrIGZpZWxkIGFjY2Vzc29ycyBmb3IgYSBjb3JkIGluc2lkZSBvbmVvZnt9OgorICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX2dldDpmb28uQmFyLm9uZU9mQ29yZCIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLm9uZU9mQ29yZCIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGU6Zm9vLkJhci5vbmVPZkNvcmQiLCBjb250ZXh0KTsKKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgdm9pZCBUcnlJbnNlcnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQsCisgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQpIGNvbnN0IHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICBjb250ZXh0LT5PcGVuRm9ySW5zZXJ0KGZpbGVuYW1lLCBpbnNlcnRpb25fcG9pbnQpKTsKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBwcmludGVyLlByaW50KCIvLyBpbnNlcnRlZCAkbmFtZSRcbiIsICJuYW1lIiwgaW5zZXJ0aW9uX3BvaW50KTsKKyAgfQorfTsKKworLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgYWxsIHRoZSBleHBlY3RlZCBpbnNlcnRpb24gcG9pbnRzIGV4aXN0LiAgSXQgZG9lcworLy8gbm90IHZlcmlmeSB0aGF0IHRoZXkgYXJlIGNvcnJlY3RseS1wbGFjZWQ7IHRoYXQgd291bGQgcmVxdWlyZSBhY3R1YWxseQorLy8gY29tcGlsaW5nIHRoZSBvdXRwdXQgd2hpY2ggaXMgYSBiaXQgbW9yZSB0aGFuIEkgY2FyZSB0byBkbyBmb3IgdGhpcyB0ZXN0LgorVEVTVChDcHBQbHVnaW5UZXN0LCBQbHVnaW5UZXN0KSB7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhUZXN0VGVtcERpcigpICsgIi90ZXN0LnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYWNrYWdlIGZvbztcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZW51bSBUaHVkIHsgVkFMVUUgPSAwOyB9XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgbWVzc2FnZSBCYXoge31cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgb3B0aW9uYWwgaW50MzIgb3B0SW50ID0gMTtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRJbnQgPSAyO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcXVpcmVkIHN0cmluZyByZXF1aXJlZFN0cmluZyA9IDM7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZFN0cmluZyA9IDQ7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgb3B0aW9uYWwgQmF6IG9wdE1lc3NhZ2UgPSA2O1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICByZXBlYXRlZCBCYXogcmVwZWF0ZWRNZXNzYWdlID0gNztcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBvcHRpb25hbCBUaHVkIG9wdEVudW0gPSA4O1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICByZXBlYXRlZCBUaHVkIHJlcGVhdGVkRW51bSA9IDk7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVxdWlyZWQgc3RyaW5nIHJlcXVpcmVkQ29yZCA9IDEwIFtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBjdHlwZSA9IENPUkRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgXTtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkQ29yZCA9IDExIFtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBjdHlwZSA9IENPUkRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgXTtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBvbmVvZiBRdXgge1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIGludDY0IG9uZU9mSW50ID0gMjA7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgc3RyaW5nIG9uZU9mU3RyaW5nID0gMjE7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgQmF6IG9uZU9mTWVzc2FnZSA9IDIyO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIFRodWQgb25lT2ZFbnVtID0gMjM7IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIHN0cmluZyBvbmVPZkNvcmQgPSAyNCBbXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgICBjdHlwZSA9IENPUkRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBdO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKSk7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvbW1hbmRMaW5lSW50ZXJmYWNlIGNsaTsKKyAgY2xpLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKHRydWUpOworCisgIENwcEdlbmVyYXRvciBjcHBfZ2VuZXJhdG9yOworICBUZXN0R2VuZXJhdG9yIHRlc3RfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tY3BwX291dCIsICZjcHBfZ2VuZXJhdG9yLCAiIik7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS10ZXN0X291dCIsICZ0ZXN0X2dlbmVyYXRvciwgIiIpOworCisgIHN0cmluZyBwcm90b19wYXRoID0gIi1JIiArIFRlc3RUZW1wRGlyKCk7CisgIHN0cmluZyBjcHBfb3V0ID0gIi0tY3BwX291dD0iICsgVGVzdFRlbXBEaXIoKTsKKyAgc3RyaW5nIHRlc3Rfb3V0ID0gIi0tdGVzdF9vdXQ9IiArIFRlc3RUZW1wRGlyKCk7CisKKyAgY29uc3QgY2hhciogYXJndltdID0geworICAgICJwcm90b2MiLAorICAgIHByb3RvX3BhdGguY19zdHIoKSwKKyAgICBjcHBfb3V0LmNfc3RyKCksCisgICAgdGVzdF9vdXQuY19zdHIoKSwKKyAgICAidGVzdC5wcm90byIKKyAgfTsKKworICBFWFBFQ1RfRVEoMCwgY2xpLlJ1big1LCBhcmd2KSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyOWVhZTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmNjCkBAIC0wLDAgKzEsNDU5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworLy8gRm9yIGVuY29kaW5ncyB3aXRoIGZpeGVkIHNpemVzLCByZXR1cm5zIHRoYXQgc2l6ZSBpbiBieXRlcy4gIE90aGVyd2lzZQorLy8gcmV0dXJucyAtMS4KK2ludCBGaXhlZFNpemUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NCAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0ICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzIgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NCAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMiA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtGaXhlZDY0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprU0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtTRml4ZWQ2NFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0Zsb2F0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEUgIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRG91YmxlU2l6ZTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0wgICAgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtCb29sU2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuIC0xOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSA6IHJldHVybiAtMTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gLTE7Cit9CisKK3ZvaWQgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpIHsKKyAgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgdmFyaWFibGVzLCBvcHRpb25zKTsKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBQcmltaXRpdmVUeXBlTmFtZShkZXNjcmlwdG9yLT5jcHBfdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBEZWZhdWx0VmFsdWUoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKGludGVybmFsOjpXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgaW50IGZpeGVkX3NpemUgPSBGaXhlZFNpemUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgaWYgKGZpeGVkX3NpemUgIT0gLTEpIHsKKyAgICAoKnZhcmlhYmxlcylbImZpeGVkX3NpemUiXSA9IFNpbXBsZUl0b2EoZml4ZWRfc2l6ZSk7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJ3aXJlX2Zvcm1hdF9maWVsZF90eXBlIl0gPQorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoiICsgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9OYW1lKAorICAgICAgICAgIHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGU+KGRlc2NyaXB0b3ItPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18sIG9wdGlvbnMpOworfQorCitQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6flByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkdHlwZSQgJG5hbWUkXztcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHR5cGUkICRuYW1lJCgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgJHR5cGUkICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRkZWZhdWx0JDtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInNldF8kbmFtZSQoZnJvbS4kbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAic3RkOjpzd2FwKCRuYW1lJF8sIG90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPFxuIgorICAgICIgICAgICAgICAkdHlwZSQsICR3aXJlX2Zvcm1hdF9maWVsZF90eXBlJD4oXG4iCisgICAgIiAgICAgICBpbnB1dCwgJiRuYW1lJF8pKSk7XG4iCisgICAgIiRzZXRfaGFzYml0JFxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkKCIKKyAgICAgICIkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKCksIG91dHB1dCk7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkVG9BcnJheSgiCisgICAgICAiJG51bWJlciQsIHRoaXMtPiRuYW1lJCgpLCB0YXJnZXQpO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpbnQgZml4ZWRfc2l6ZSA9IEZpeGVkU2l6ZShkZXNjcmlwdG9yXy0+dHlwZSgpKTsKKyAgaWYgKGZpeGVkX3NpemUgPT0gLTEpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRvdGFsX3NpemUgKz0gJHRhZ19zaXplJCArXG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6JGRlY2xhcmVkX3R5cGUkU2l6ZShcbiIKKyAgICAgICIgICAgdGhpcy0+JG5hbWUkKCkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgKyAkZml4ZWRfc2l6ZSQ7XG4iKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1ByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgb3B0aW9ucykgeworICBTZXRDb21tb25PbmVvZkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6flByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgJHR5cGUkICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgIiAgICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAiICAgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBEb24ndCBwcmludCBhbnkgc3dhcHBpbmcgY29kZS4gU3dhcHBpbmcgdGhlIHVuaW9uIHdpbGwgc3dhcCB0aGlzIGZpZWxkLgorfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiAgJGNsYXNzbmFtZSRfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgIkRPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8XG4iCisgICAgIiAgICAgICAgICR0eXBlJCwgJHdpcmVfZm9ybWF0X2ZpZWxkX3R5cGUkPihcbiIKKyAgICAiICAgICAgIGlucHV0LCAmJG9uZW9mX3ByZWZpeCQkbmFtZSRfKSkpO1xuIgorICAgICJzZXRfaGFzXyRuYW1lJCgpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7CisKKyAgaWYgKGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHZhcmlhYmxlc19bInBhY2tlZF9yZWFkZXIiXSA9ICJSZWFkUGFja2VkUHJpbWl0aXZlIjsKKyAgICB2YXJpYWJsZXNfWyJyZXBlYXRlZF9yZWFkZXIiXSA9ICJSZWFkUmVwZWF0ZWRQcmltaXRpdmVOb0lubGluZSI7CisgIH0gZWxzZSB7CisgICAgdmFyaWFibGVzX1sicGFja2VkX3JlYWRlciJdID0gIlJlYWRQYWNrZWRQcmltaXRpdmVOb0lubGluZSI7CisgICAgdmFyaWFibGVzX1sicmVwZWF0ZWRfcmVhZGVyIl0gPSAiUmVhZFJlcGVhdGVkUHJpbWl0aXZlIjsKKyAgfQorfQorCitSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgJHR5cGUkID4gJG5hbWUkXztcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSAmJiBIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJtdXRhYmxlIGludCBfJG5hbWUkX2NhY2hlZF9ieXRlX3NpemVfO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHR5cGUkICRuYW1lJChpbnQgaW5kZXgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgYWRkXyRuYW1lJCgkdHlwZSQgdmFsdWUpJGRlcHJlY2F0aW9uJDtcbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8ICR0eXBlJCA+JlxuIgorICAgICIgICAgJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8ICR0eXBlJCA+KlxuIgorICAgICIgICAgbXV0YWJsZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkICR0eXBlJCAkY2xhc3NuYW1lJDo6JG5hbWUkKGludCBpbmRleCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uR2V0KGluZGV4KTtcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgJG5hbWUkXy5TZXQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OmFkZF8kbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgJG5hbWUkXy5BZGQodmFsdWUpO1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgJHR5cGUkID4mXG4iCisgICAgIiRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCAkdHlwZSQgPipcbiIKKyAgICAiJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICYkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLkNsZWFyKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uTWVyZ2VGcm9tKGZyb20uJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBOb3QgbmVlZGVkIGZvciByZXBlYXRlZCBmaWVsZHMuCit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIkRPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OiRyZXBlYXRlZF9yZWFkZXIkPFxuIgorICAgICIgICAgICAgICAkdHlwZSQsICR3aXJlX2Zvcm1hdF9maWVsZF90eXBlJD4oXG4iCisgICAgIiAgICAgICAkdGFnX3NpemUkLCAkdGFnJCwgaW5wdXQsIHRoaXMtPm11dGFibGVfJG5hbWUkKCkpKSk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokcGFja2VkX3JlYWRlciQ8XG4iCisgICAgIiAgICAgICAgICR0eXBlJCwgJHdpcmVfZm9ybWF0X2ZpZWxkX3R5cGUkPihcbiIKKyAgICAiICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlXyRuYW1lJCgpKSkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIC8vIFdyaXRlIHRoZSB0YWcgYW5kIHRoZSBzaXplLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMtPiRuYW1lJF9zaXplKCkgPiAwKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoIgorICAgICAgICAgICIkbnVtYmVyJCwgIgorICAgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgIgorICAgICAgICAgICJvdXRwdXQpO1xuIgorICAgICAgIiAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKF8kbmFtZSRfY2FjaGVkX2J5dGVfc2l6ZV8pO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT4kbmFtZSRfc2l6ZSgpOyBpKyspIHtcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGUkZGVjbGFyZWRfdHlwZSROb1RhZyhcbiIKKyAgICAgICIgICAgdGhpcy0+JG5hbWUkKGkpLCBvdXRwdXQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZSRkZWNsYXJlZF90eXBlJChcbiIKKyAgICAgICIgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJChpKSwgb3V0cHV0KTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIC8vIFdyaXRlIHRoZSB0YWcgYW5kIHRoZSBzaXplLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMtPiRuYW1lJF9zaXplKCkgPiAwKSB7XG4iCisgICAgICAiICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KFxuIgorICAgICAgIiAgICAkbnVtYmVyJCxcbiIKKyAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsXG4iCisgICAgICAiICAgIHRhcmdldCk7XG4iCisgICAgICAiICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoXG4iCisgICAgICAiICAgIF8kbmFtZSRfY2FjaGVkX2J5dGVfc2l6ZV8sIHRhcmdldCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIik7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgV3JpdGUkZGVjbGFyZWRfdHlwZSROb1RhZ1RvQXJyYXkodGhpcy0+JG5hbWUkKGkpLCB0YXJnZXQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgV3JpdGUkZGVjbGFyZWRfdHlwZSRUb0FycmF5KCRudW1iZXIkLCB0aGlzLT4kbmFtZSQoaSksIHRhcmdldCk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YV9zaXplID0gMDtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaW50IGZpeGVkX3NpemUgPSBGaXhlZFNpemUoZGVzY3JpcHRvcl8tPnR5cGUoKSk7CisgIGlmIChmaXhlZF9zaXplID09IC0xKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgZGF0YV9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgJGRlY2xhcmVkX3R5cGUkU2l6ZSh0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZGF0YV9zaXplID0gJGZpeGVkX3NpemUkICogdGhpcy0+JG5hbWUkX3NpemUoKTtcbiIpOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChkYXRhX3NpemUgPiAwKSB7XG4iCisgICAgICAiICB0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKGRhdGFfc2l6ZSk7XG4iCisgICAgICAifVxuIgorICAgICAgIkdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7XG4iCisgICAgICAiXyRuYW1lJF9jYWNoZWRfYnl0ZV9zaXplXyA9IGRhdGFfc2l6ZTtcbiIKKyAgICAgICJHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTtcbiIKKyAgICAgICJ0b3RhbF9zaXplICs9IGRhdGFfc2l6ZTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAidG90YWxfc2l6ZSArPSAkdGFnX3NpemUkICogdGhpcy0+JG5hbWUkX3NpemUoKSArIGRhdGFfc2l6ZTtcbiIpOworICB9CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3ByaW1pdGl2ZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3ByaW1pdGl2ZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjZDdkNjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmgKQEAgLTAsMCArMSwxMjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1BSSU1JVElWRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9QUklNSVRJVkVfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworY2xhc3MgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgflByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5QcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5SZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtV2l0aFBhY2tpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9QUklNSVRJVkVfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyNmMyYWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5jYwpAQCAtMCwwICsxLDMzNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworU2VydmljZUdlbmVyYXRvcjo6U2VydmljZUdlbmVyYXRvcihjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIHZhcnNfWyJjbGFzc25hbWUiXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgIHZhcnNfWyJmdWxsX25hbWUiXSA9IGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKTsKKyAgaWYgKG9wdGlvbnMuZGxsZXhwb3J0X2RlY2wuZW1wdHkoKSkgeworICAgIHZhcnNfWyJkbGxleHBvcnQiXSA9ICIiOworICB9IGVsc2UgeworICAgIHZhcnNfWyJkbGxleHBvcnQiXSA9IG9wdGlvbnMuZGxsZXhwb3J0X2RlY2wgKyAiICI7CisgIH0KK30KKworU2VydmljZUdlbmVyYXRvcjo6flNlcnZpY2VHZW5lcmF0b3IoKSB7fQorCit2b2lkIFNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEZvcndhcmQtZGVjbGFyZSB0aGUgc3R1YiB0eXBlLgorICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiY2xhc3MgJGNsYXNzbmFtZSRfU3R1YjtcbiIKKyAgICAiXG4iKTsKKworICBHZW5lcmF0ZUludGVyZmFjZShwcmludGVyKTsKKyAgR2VuZXJhdGVTdHViRGVmaW5pdGlvbihwcmludGVyKTsKK30KKwordm9pZCBTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUludGVyZmFjZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiY2xhc3MgJGRsbGV4cG9ydCQkY2xhc3NuYW1lJCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2Uge1xuIgorICAgICIgcHJvdGVjdGVkOlxuIgorICAgICIgIC8vIFRoaXMgY2xhc3Mgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYW4gYWJzdHJhY3QgaW50ZXJmYWNlLlxuIgorICAgICIgIGlubGluZSAkY2xhc3NuYW1lJCgpIHt9O1xuIgorICAgICIgcHVibGljOlxuIgorICAgICIgIHZpcnR1YWwgfiRjbGFzc25hbWUkKCk7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyc18sCisgICAgIlxuIgorICAgICJ0eXBlZGVmICRjbGFzc25hbWUkX1N0dWIgU3R1YjtcbiIKKyAgICAiXG4iCisgICAgInN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7XG4iCisgICAgIlxuIik7CisKKyAgR2VuZXJhdGVNZXRob2RTaWduYXR1cmVzKFZJUlRVQUwsIHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gaW1wbGVtZW50cyBTZXJ2aWNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIKKyAgICAiXG4iCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3IqIEdldERlc2NyaXB0b3IoKTtcbiIKKyAgICAidm9pZCBDYWxsTWV0aG9kKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLFxuIgorICAgICIgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpScGNDb250cm9sbGVyKiBjb250cm9sbGVyLFxuIgorICAgICIgICAgICAgICAgICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKiByZXF1ZXN0LFxuIgorICAgICIgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKiByZXNwb25zZSxcbiIKKyAgICAiICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Q2xvc3VyZSogZG9uZSk7XG4iCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgR2V0UmVxdWVzdFByb3RvdHlwZShcbiIKKyAgICAiICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgY29uc3Q7XG4iCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgR2V0UmVzcG9uc2VQcm90b3R5cGUoXG4iCisgICAgIiAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpIGNvbnN0O1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiXG4iCisgICAgIiBwcml2YXRlOlxuIgorICAgICIgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUygkY2xhc3NuYW1lJCk7XG4iCisgICAgIn07XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVTdHViRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiY2xhc3MgJGRsbGV4cG9ydCQkY2xhc3NuYW1lJF9TdHViIDogcHVibGljICRjbGFzc25hbWUkIHtcbiIKKyAgICAiIHB1YmxpYzpcbiIpOworCisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIkY2xhc3NuYW1lJF9TdHViKDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ2hhbm5lbCogY2hhbm5lbCk7XG4iCisgICAgIiRjbGFzc25hbWUkX1N0dWIoOjpnb29nbGU6OnByb3RvYnVmOjpScGNDaGFubmVsKiBjaGFubmVsLFxuIgorICAgICIgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZTo6Q2hhbm5lbE93bmVyc2hpcCBvd25lcnNoaXApO1xuIgorICAgICJ+JGNsYXNzbmFtZSRfU3R1YigpO1xuIgorICAgICJcbiIKKyAgICAiaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ2hhbm5lbCogY2hhbm5lbCgpIHsgcmV0dXJuIGNoYW5uZWxfOyB9XG4iCisgICAgIlxuIgorICAgICIvLyBpbXBsZW1lbnRzICRjbGFzc25hbWUkIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIgorICAgICJcbiIpOworCisgIEdlbmVyYXRlTWV0aG9kU2lnbmF0dXJlcyhOT05fVklSVFVBTCwgcHJpbnRlcik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiIHByaXZhdGU6XG4iCisgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpScGNDaGFubmVsKiBjaGFubmVsXztcbiIKKyAgICAiICBib29sIG93bnNfY2hhbm5lbF87XG4iCisgICAgIiAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKCRjbGFzc25hbWUkX1N0dWIpO1xuIgorICAgICJ9O1xuIgorICAgICJcbiIpOworfQorCit2b2lkIFNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlTWV0aG9kU2lnbmF0dXJlcygKKyAgICBWaXJ0dWFsT3JOb24gdmlydHVhbF9vcl9ub24sIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gc3ViX3ZhcnM7CisgICAgc3ViX3ZhcnNbIm5hbWUiXSA9IG1ldGhvZC0+bmFtZSgpOworICAgIHN1Yl92YXJzWyJpbnB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5pbnB1dF90eXBlKCksIHRydWUpOworICAgIHN1Yl92YXJzWyJvdXRwdXRfdHlwZSJdID0gQ2xhc3NOYW1lKG1ldGhvZC0+b3V0cHV0X3R5cGUoKSwgdHJ1ZSk7CisgICAgc3ViX3ZhcnNbInZpcnR1YWwiXSA9IHZpcnR1YWxfb3Jfbm9uID09IFZJUlRVQUwgPyAidmlydHVhbCAiIDogIiI7CisKKyAgICBwcmludGVyLT5QcmludChzdWJfdmFycywKKyAgICAgICIkdmlydHVhbCR2b2lkICRuYW1lJCg6Omdvb2dsZTo6cHJvdG9idWY6OlJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgY29uc3QgJGlucHV0X3R5cGUkKiByZXF1ZXN0LFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICRvdXRwdXRfdHlwZSQqIHJlc3BvbnNlLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Q2xvc3VyZSogZG9uZSk7XG4iKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGludCBpbmRleCkgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbImNsYXNzbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaW5kZXgpOworCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfID0gZmlsZS0+c2VydmljZSgkaW5kZXgkKTtcbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVJbXBsZW1lbnRhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiJGNsYXNzbmFtZSQ6On4kY2xhc3NuYW1lJCgpIHt9XG4iCisgICAgIlxuIgorICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yKiAkY2xhc3NuYW1lJDo6ZGVzY3JpcHRvcigpIHtcbiIKKyAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIKKyAgICAiICByZXR1cm4gJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl87XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3IqICRjbGFzc25hbWUkOjpHZXREZXNjcmlwdG9yKCkge1xuIgorICAgICIgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpO1xuIgorICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXztcbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIC8vIEdlbmVyYXRlIG1ldGhvZHMgb2YgdGhlIGludGVyZmFjZS4KKyAgR2VuZXJhdGVOb3RJbXBsZW1lbnRlZE1ldGhvZHMocHJpbnRlcik7CisgIEdlbmVyYXRlQ2FsbE1ldGhvZChwcmludGVyKTsKKyAgR2VuZXJhdGVHZXRQcm90b3R5cGUoUkVRVUVTVCwgcHJpbnRlcik7CisgIEdlbmVyYXRlR2V0UHJvdG90eXBlKFJFU1BPTlNFLCBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBzdHViIGltcGxlbWVudGF0aW9uLgorICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiJGNsYXNzbmFtZSRfU3R1Yjo6JGNsYXNzbmFtZSRfU3R1Yig6Omdvb2dsZTo6cHJvdG9idWY6OlJwY0NoYW5uZWwqIGNoYW5uZWwpXG4iCisgICAgIiAgOiBjaGFubmVsXyhjaGFubmVsKSwgb3duc19jaGFubmVsXyhmYWxzZSkge31cbiIKKyAgICAiJGNsYXNzbmFtZSRfU3R1Yjo6JGNsYXNzbmFtZSRfU3R1YihcbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ2hhbm5lbCogY2hhbm5lbCxcbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZTo6Q2hhbm5lbE93bmVyc2hpcCBvd25lcnNoaXApXG4iCisgICAgIiAgOiBjaGFubmVsXyhjaGFubmVsKSxcbiIKKyAgICAiICAgIG93bnNfY2hhbm5lbF8ob3duZXJzaGlwID09IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZTo6U1RVQl9PV05TX0NIQU5ORUwpIHt9XG4iCisgICAgIiRjbGFzc25hbWUkX1N0dWI6On4kY2xhc3NuYW1lJF9TdHViKCkge1xuIgorICAgICIgIGlmIChvd25zX2NoYW5uZWxfKSBkZWxldGUgY2hhbm5lbF87XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBHZW5lcmF0ZVN0dWJNZXRob2RzKHByaW50ZXIpOworfQorCit2b2lkIFNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlTm90SW1wbGVtZW50ZWRNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gc3ViX3ZhcnM7CisgICAgc3ViX3ZhcnNbImNsYXNzbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgICBzdWJfdmFyc1sibmFtZSJdID0gbWV0aG9kLT5uYW1lKCk7CisgICAgc3ViX3ZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHN1Yl92YXJzWyJpbnB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5pbnB1dF90eXBlKCksIHRydWUpOworICAgIHN1Yl92YXJzWyJvdXRwdXRfdHlwZSJdID0gQ2xhc3NOYW1lKG1ldGhvZC0+b3V0cHV0X3R5cGUoKSwgdHJ1ZSk7CisKKyAgICBwcmludGVyLT5QcmludChzdWJfdmFycywKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjokbmFtZSQoOjpnb29nbGU6OnByb3RvYnVmOjpScGNDb250cm9sbGVyKiBjb250cm9sbGVyLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAkaW5wdXRfdHlwZSQqLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAkb3V0cHV0X3R5cGUkKixcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpDbG9zdXJlKiBkb25lKSB7XG4iCisgICAgICAiICBjb250cm9sbGVyLT5TZXRGYWlsZWQoXCJNZXRob2QgJG5hbWUkKCkgbm90IGltcGxlbWVudGVkLlwiKTtcbiIKKyAgICAgICIgIGRvbmUtPlJ1bigpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9Cit9CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVDYWxsTWV0aG9kKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICJ2b2lkICRjbGFzc25hbWUkOjpDYWxsTWV0aG9kKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLFxuIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ29udHJvbGxlciogY29udHJvbGxlcixcbiIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIHJlcXVlc3QsXG4iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKiByZXNwb25zZSxcbiIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkNsb3N1cmUqIGRvbmUpIHtcbiIKKyAgICAiICBHT09HTEVfRENIRUNLX0VRKG1ldGhvZC0+c2VydmljZSgpLCAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXyk7XG4iCisgICAgIiAgc3dpdGNoKG1ldGhvZC0+aW5kZXgoKSkge1xuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiBzdWJfdmFyczsKKyAgICBzdWJfdmFyc1sibmFtZSJdID0gbWV0aG9kLT5uYW1lKCk7CisgICAgc3ViX3ZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHN1Yl92YXJzWyJpbnB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5pbnB1dF90eXBlKCksIHRydWUpOworICAgIHN1Yl92YXJzWyJvdXRwdXRfdHlwZSJdID0gQ2xhc3NOYW1lKG1ldGhvZC0+b3V0cHV0X3R5cGUoKSwgdHJ1ZSk7CisKKyAgICAvLyBOb3RlOiAgZG93bl9jYXN0IGRvZXMgbm90IHdvcmsgaGVyZSBiZWNhdXNlIGl0IG9ubHkgd29ya3Mgb24gcG9pbnRlcnMsCisgICAgLy8gICBub3QgcmVmZXJlbmNlcy4KKyAgICBwcmludGVyLT5QcmludChzdWJfdmFycywKKyAgICAgICIgICAgY2FzZSAkaW5kZXgkOlxuIgorICAgICAgIiAgICAgICRuYW1lJChjb250cm9sbGVyLFxuIgorICAgICAgIiAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmRvd25fY2FzdDxjb25zdCAkaW5wdXRfdHlwZSQqPihyZXF1ZXN0KSxcbiIKKyAgICAgICIgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpkb3duX2Nhc3Q8ICRvdXRwdXRfdHlwZSQqPihyZXNwb25zZSksXG4iCisgICAgICAiICAgICAgICAgICAgIGRvbmUpO1xuIgorICAgICAgIiAgICAgIGJyZWFrO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiICAgIGRlZmF1bHQ6XG4iCisgICAgIiAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8IFwiQmFkIG1ldGhvZCBpbmRleDsgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLlwiO1xuIgorICAgICIgICAgICBicmVhaztcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUdldFByb3RvdHlwZShSZXF1ZXN0T3JSZXNwb25zZSB3aGljaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKHdoaWNoID09IFJFUVVFU1QpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmICRjbGFzc25hbWUkOjpHZXRSZXF1ZXN0UHJvdG90eXBlKFxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyc18sCisgICAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiAkY2xhc3NuYW1lJDo6R2V0UmVzcG9uc2VQcm90b3R5cGUoXG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpIGNvbnN0IHtcbiIKKyAgICAiICBHT09HTEVfRENIRUNLX0VRKG1ldGhvZC0+c2VydmljZSgpLCBkZXNjcmlwdG9yKCkpO1xuIgorICAgICIgIHN3aXRjaChtZXRob2QtPmluZGV4KCkpIHtcbiIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUgPQorICAgICAgKHdoaWNoID09IFJFUVVFU1QpID8gbWV0aG9kLT5pbnB1dF90eXBlKCkgOiBtZXRob2QtPm91dHB1dF90eXBlKCk7CisKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHN1Yl92YXJzOworICAgIHN1Yl92YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpKTsKKyAgICBzdWJfdmFyc1sidHlwZSJdID0gQ2xhc3NOYW1lKHR5cGUsIHRydWUpOworCisgICAgcHJpbnRlci0+UHJpbnQoc3ViX3ZhcnMsCisgICAgICAiICAgIGNhc2UgJGluZGV4JDpcbiIKKyAgICAgICIgICAgICByZXR1cm4gJHR5cGUkOjpkZWZhdWx0X2luc3RhbmNlKCk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIgICAgZGVmYXVsdDpcbiIKKyAgICAiICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgXCJCYWQgbWV0aG9kIGluZGV4OyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4uXCI7XG4iCisgICAgIiAgICAgIHJldHVybiAqc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSo+KE5VTEwpO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCit2b2lkIFNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlU3R1Yk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiBzdWJfdmFyczsKKyAgICBzdWJfdmFyc1siY2xhc3NuYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICAgIHN1Yl92YXJzWyJuYW1lIl0gPSBtZXRob2QtPm5hbWUoKTsKKyAgICBzdWJfdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgc3ViX3ZhcnNbImlucHV0X3R5cGUiXSA9IENsYXNzTmFtZShtZXRob2QtPmlucHV0X3R5cGUoKSwgdHJ1ZSk7CisgICAgc3ViX3ZhcnNbIm91dHB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5vdXRwdXRfdHlwZSgpLCB0cnVlKTsKKworICAgIHByaW50ZXItPlByaW50KHN1Yl92YXJzLAorICAgICAgInZvaWQgJGNsYXNzbmFtZSRfU3R1Yjo6JG5hbWUkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ29udHJvbGxlciogY29udHJvbGxlcixcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAkaW5wdXRfdHlwZSQqIHJlcXVlc3QsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG91dHB1dF90eXBlJCogcmVzcG9uc2UsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpDbG9zdXJlKiBkb25lKSB7XG4iCisgICAgICAiICBjaGFubmVsXy0+Q2FsbE1ldGhvZChkZXNjcmlwdG9yKCktPm1ldGhvZCgkaW5kZXgkKSxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIsIHJlcXVlc3QsIHJlc3BvbnNlLCBkb25lKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3NlcnZpY2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWRlMmZkOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmgKQEAgLTAsMCArMSwxMTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1NFUlZJQ0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfU0VSVklDRV9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitjbGFzcyBTZXJ2aWNlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIC8vIFNlZSBnZW5lcmF0b3IuY2MgZm9yIHRoZSBtZWFuaW5nIG9mIGRsbGV4cG9ydF9kZWNsLgorICBleHBsaWNpdCBTZXJ2aWNlR2VuZXJhdG9yKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+U2VydmljZUdlbmVyYXRvcigpOworCisgIC8vIEhlYWRlciBzdHVmZi4KKworICAvLyBHZW5lcmF0ZSB0aGUgY2xhc3MgZGVmaW5pdGlvbnMgZm9yIHRoZSBzZXJ2aWNlJ3MgaW50ZXJmYWNlIGFuZCB0aGUKKyAgLy8gc3R1YiBpbXBsZW1lbnRhdGlvbi4KKyAgdm9pZCBHZW5lcmF0ZURlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gU291cmNlIGZpbGUgc3R1ZmYuCisKKyAgLy8gR2VuZXJhdGUgY29kZSB0aGF0IGluaXRpYWxpemVzIHRoZSBnbG9iYWwgdmFyaWFibGUgc3RvcmluZyB0aGUgc2VydmljZSdzCisgIC8vIGRlc2NyaXB0b3IuCisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIoaW86OlByaW50ZXIqIHByaW50ZXIsIGludCBpbmRleCk7CisKKyAgLy8gR2VuZXJhdGUgaW1wbGVtZW50YXRpb25zIG9mIGV2ZXJ5dGhpbmcgZGVjbGFyZWQgYnkgR2VuZXJhdGVEZWNsYXJhdGlvbnMoKS4KKyAgdm9pZCBHZW5lcmF0ZUltcGxlbWVudGF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGVudW0gUmVxdWVzdE9yUmVzcG9uc2UgeyBSRVFVRVNULCBSRVNQT05TRSB9OworICBlbnVtIFZpcnR1YWxPck5vbiB7IFZJUlRVQUwsIE5PTl9WSVJUVUFMIH07CisKKyAgLy8gSGVhZGVyIHN0dWZmLgorCisgIC8vIEdlbmVyYXRlIHRoZSBzZXJ2aWNlIGFic3RyYWN0IGludGVyZmFjZS4KKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIHN0dWIgY2xhc3MgZGVmaW5pdGlvbi4KKyAgdm9pZCBHZW5lcmF0ZVN0dWJEZWZpbml0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBQcmludHMgc2lnbmF0dXJlcyBmb3IgYWxsIG1ldGhvZHMgaW4gdGhlCisgIHZvaWQgR2VuZXJhdGVNZXRob2RTaWduYXR1cmVzKFZpcnR1YWxPck5vbiB2aXJ0dWFsX29yX25vbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIFNvdXJjZSBmaWxlIHN0dWZmLgorCisgIC8vIEdlbmVyYXRlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9ucyBvZiB0aGUgc2VydmljZSBtZXRob2RzLCB3aGljaAorICAvLyBwcm9kdWNlIGEgIm5vdCBpbXBsZW1lbnRlZCIgZXJyb3IuCisgIHZvaWQgR2VuZXJhdGVOb3RJbXBsZW1lbnRlZE1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHRoZSBDYWxsTWV0aG9kKCkgbWV0aG9kIG9mIHRoZSBzZXJ2aWNlLgorICB2b2lkIEdlbmVyYXRlQ2FsbE1ldGhvZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIEdldHtSZXF1ZXN0LFJlc3BvbnNlfVByb3RvdHlwZSgpIG1ldGhvZHMuCisgIHZvaWQgR2VuZXJhdGVHZXRQcm90b3R5cGUoUmVxdWVzdE9yUmVzcG9uc2Ugd2hpY2gsIGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgc3R1YidzIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgc2VydmljZSBtZXRob2RzLgorICB2b2lkIEdlbmVyYXRlU3R1Yk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU2VydmljZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfU0VSVklDRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc3RyaW5nX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhMWJjZDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc3RyaW5nX2ZpZWxkLmNjCkBAIC0wLDAgKzEsODY0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRTdHJpbmdWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCB2YXJpYWJsZXMsIG9wdGlvbnMpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IERlZmF1bHRWYWx1ZShkZXNjcmlwdG9yKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2xlbmd0aCJdID0KKyAgICAgIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5sZW5ndGgoKSk7CisgIHN0cmluZyBkZWZhdWx0X3ZhcmlhYmxlX3N0cmluZyA9CisgICAgICBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpLmVtcHR5KCkKKyAgICAgICAgICA/ICImOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkiCisgICAgICAgICAgOiAiX2RlZmF1bHRfIiArIEZpZWxkTmFtZShkZXNjcmlwdG9yKSArICJfIjsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X3ZhcmlhYmxlIl0gPSBkZWZhdWx0X3ZhcmlhYmxlX3N0cmluZzsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X3ZhbHVlX2luaXQiXSA9CisgICAgICBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpLmVtcHR5KCkKKyAgICAgID8gIiIgOiAiKiIgKyBkZWZhdWx0X3ZhcmlhYmxlX3N0cmluZzsKKyAgKCp2YXJpYWJsZXMpWyJwb2ludGVyX3R5cGUiXSA9CisgICAgICBkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTID8gInZvaWQiIDogImNoYXIiOworICAvLyBOT1RFOiBFc2NhcGVkIGhlcmUgdG8gdW5ibG9jayBwcm90bzEtPnByb3RvMiBtaWdyYXRpb24uCisgIC8vIFRPRE8obGl1amlzaSk6IEV4dGVuZCB0aGlzIHRvIGFwcGx5IGZvciBvdGhlciBjb25mbGljdGluZyBtZXRob2RzLgorICAoKnZhcmlhYmxlcylbInJlbGVhc2VfbmFtZSJdID0KKyAgICAgIFNhZmVGdW5jdGlvbk5hbWUoZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IsICJyZWxlYXNlXyIpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7CisKKyAgKCp2YXJpYWJsZXMpWyJzdHJpbmdfcGllY2UiXSA9ICI6OnN0ZDo6c3RyaW5nIjsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorU3RyaW5nRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFN0cmluZ1ZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7Cit9CisKK1N0cmluZ0ZpZWxkR2VuZXJhdG9yOjp+U3RyaW5nRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTi5CLiB0aGF0IHdlIGNvbnRpbnVlIHRvIHVzZSB8QXJlbmFTdHJpbmdQdHJ8IGluc3RlYWQgb2YgfHN0cmluZyp8IGZvcgorICAvLyBzdHJpbmcgZmllbGRzLCBldmVuIHdoZW4gU3VwcG9ydEFyZW5hcyhkZXNjcmlwdG9yXykgPT0gZmFsc2UuIFdoeT8KKyAgLy8gVGhlIHNpbXBsZSBhbnN3ZXIgaXMgdG8gYXZvaWQgdW5tYWludGFpbmFibGUgY29tcGxleGl0eS4gVGhlIHJlZmxlY3Rpb24KKyAgLy8gY29kZSBhc3N1bWVzIEFyZW5hU3RyaW5nUHRycy4gVGhlc2UgYXJlICphbG1vc3QqIGluLW1lbW9yeS1jb21wYXRpYmxlIHdpdGgKKyAgLy8gc3RyaW5nKiwgZXhjZXB0IGZvciB0aGUgcG9pbnRlciB0YWdzIGFuZCByZWxhdGVkIG93bmVyc2hpcCBzZW1hbnRpY3MuIFdlCisgIC8vIGNvdWxkIG1vZGlmeSB0aGUgcnVudGltZSBjb2RlIHRvIHVzZSBzdHJpbmcqIGZvciB0aGUgbm90LXN1cHBvcnRpbmctYXJlbmFzCisgIC8vIGNhc2UsIGJ1dCB0aGlzIHdvdWxkIHJlcXVpcmUgYSB3YXkgdG8gZGV0ZWN0IHdoaWNoIHR5cGUgb2YgY2xhc3Mgd2FzCisgIC8vIGdlbmVyYXRlZCAoYWRkaW5nIG92ZXJoZWFkIGFuZCBjb21wbGV4aXR5IHRvIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKQorICAvLyBhbmQgbGl0dGVyaW5nIHRoZSBydW50aW1lIGNvZGUgcGF0aHMgd2l0aCBjb25kaXRpb25hbHMuIEl0J3Mgc2ltcGxlciB0bworICAvLyBzdGljayB3aXRoIHRoaXMgYnV0IHVzZSBsaWdodHdlaWdodCBhY2Nlc3NvcnMgdGhhdCBhc3N1bWUgYXJlbmEgPT0gTlVMTC4KKyAgLy8gVGhlcmUgc2hvdWxkIGJlIHZlcnkgbGl0dGxlIG92ZXJoZWFkIGFueXdheSBiZWNhdXNlIGl0J3MganVzdCBhIHRhZ2dlZAorICAvLyBwb2ludGVyIGluLW1lbW9yeS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN0YXRpY01lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKCFkZXNjcmlwdG9yXy0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInN0YXRpYyA6OnN0ZDo6c3RyaW5nKiAkZGVmYXVsdF92YXJpYWJsZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gSWYgd2UncmUgdXNpbmcgU3RyaW5nRmllbGRHZW5lcmF0b3IgZm9yIGEgZmllbGQgd2l0aCBhIGN0eXBlLCBpdCdzCisgIC8vIGJlY2F1c2UgdGhhdCBjdHlwZSBpc24ndCBhY3R1YWxseSBpbXBsZW1lbnRlZC4gIEluIHBhcnRpY3VsYXIsIHRoaXMgaXMKKyAgLy8gdHJ1ZSBvZiBjdHlwZT1DT1JEIGFuZCBjdHlwZT1TVFJJTkdfUElFQ0UgaW4gdGhlIG9wZW4gc291cmNlIHJlbGVhc2UuCisgIC8vIFdlIGFyZW4ndCByZWxlYXNpbmcgQ29yZCBiZWNhdXNlIGl0IGhhcyB0b28gbWFueSBHb29nbGUtc3BlY2lmaWMKKyAgLy8gZGVwZW5kZW5jaWVzIGFuZCB3ZSBhcmVuJ3QgcmVsZWFzaW5nIFN0cmluZ1BpZWNlIGJlY2F1c2UgaXQncyBoYXJkbHkKKyAgLy8gdXNlZnVsIG91dHNpZGUgb2YgR29vZ2xlIGFuZCBiZWNhdXNlIGl0IHdvdWxkIGdldCBjb25mdXNpbmcgdG8gaGF2ZQorICAvLyBtdWx0aXBsZSBpbnN0YW5jZXMgb2YgdGhlIFN0cmluZ1BpZWNlIGNsYXNzIGluIGRpZmZlcmVudCBsaWJyYXJpZXMgKFBDUkUKKyAgLy8gYWxyZWFkeSBpbmNsdWRlcyBpdCBmb3IgdGhlaXIgQysrIGJpbmRpbmdzLCB3aGljaCBjYW1lIGZyb20gR29vZ2xlKS4KKyAgLy8KKyAgLy8gSW4gYW55IGNhc2UsIHdlIG1ha2UgYWxsIHRoZSBhY2Nlc3NvcnMgcHJpdmF0ZSB3aGlsZSBzdGlsbCBhY3R1YWxseQorICAvLyB1c2luZyBhIHN0cmluZyB0byByZXByZXNlbnQgdGhlIGZpZWxkIGludGVybmFsbHkuICBUaGlzIHdheSwgd2UgY2FuCisgIC8vIGd1YXJhbnRlZSB0aGF0IGlmIHdlIGRvIGV2ZXIgaW1wbGVtZW50IHRoZSBjdHlwZSwgaXQgd29uJ3QgYnJlYWsgYW55CisgIC8vIGV4aXN0aW5nIHVzZXJzIHdobyBtaWdodCBiZSAtLSBmb3Igd2hhdGV2ZXIgcmVhc29uIC0tIGFscmVhZHkgdXNpbmcgLnByb3RvCisgIC8vIGZpbGVzIHRoYXQgYXBwbGllZCB0aGUgY3R5cGUuICBUaGUgZmllbGQgY2FuIHN0aWxsIGJlIGFjY2Vzc2VkIHZpYSB0aGUKKyAgLy8gcmVmbGVjdGlvbiBpbnRlcmZhY2Ugc2luY2UgdGhlIHJlZmxlY3Rpb24gaW50ZXJmYWNlIGlzIGluZGVwZW5kZW50IG9mCisgIC8vIHRoZSBzdHJpbmcncyB1bmRlcmx5aW5nIHJlcHJlc2VudGF0aW9uLgorCisgIGJvb2wgdW5rbm93bl9jdHlwZSA9CisgICAgICBkZXNjcmlwdG9yXy0+b3B0aW9ucygpLmN0eXBlKCkgIT0gRWZmZWN0aXZlU3RyaW5nQ1R5cGUoZGVzY3JpcHRvcl8pOworCisgIGlmICh1bmtub3duX2N0eXBlKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiBwcml2YXRlOlxuIgorICAgICAgIiAgLy8gSGlkZGVuIGR1ZSB0byB1bmtub3duIGN0eXBlIG9wdGlvbi5cbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiY29uc3QgOjpzdGQ6OnN0cmluZyYgJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKGNvbnN0IGNoYXIqIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgc2V0XyRuYW1lJChjb25zdCAkcG9pbnRlcl90eXBlJCogdmFsdWUsIHNpemVfdCBzaXplKSIKKyAgICAgICAgICAgICAgICAgIiRkZXByZWNhdGlvbiQ7XG4iCisgICAgIjo6c3RkOjpzdHJpbmcqIG11dGFibGVfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICI6OnN0ZDo6c3RyaW5nKiAkcmVsZWFzZV9uYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfYWxsb2NhdGVkXyRuYW1lJCg6OnN0ZDo6c3RyaW5nKiAkbmFtZSQpJGRlcHJlY2F0aW9uJDtcbiIpOworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6OnN0ZDo6c3RyaW5nKiB1bnNhZmVfYXJlbmFfcmVsZWFzZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAidm9pZCB1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF8kbmFtZSQoXG4iCisgICAgICAiICAgIDo6c3RkOjpzdHJpbmcqICRuYW1lJCkkZGVwcmVjYXRpb24kO1xuIik7CisgIH0KKworCisgIGlmICh1bmtub3duX2N0eXBlKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCIgcHVibGljOlxuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgIH0KK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiRpbmxpbmUkIGNvbnN0IDo6c3RkOjpzdHJpbmcmICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uR2V0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXQoJGRlZmF1bHRfdmFyaWFibGUkLCB2YWx1ZSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0IGNoYXIqIHZhbHVlKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgICRuYW1lJF8uU2V0KCRkZWZhdWx0X3ZhcmlhYmxlJCwgJHN0cmluZ19waWVjZSQodmFsdWUpLFxuIgorICAgICAgIiAgICAgICAgICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkICIKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0ICRwb2ludGVyX3R5cGUkKiB2YWx1ZSxcbiIKKyAgICAgICIgICAgc2l6ZV90IHNpemUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXQoJGRlZmF1bHRfdmFyaWFibGUkLCAkc3RyaW5nX3BpZWNlJChcbiIKKyAgICAgICIgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICAgIiAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLk11dGFibGUoJGRlZmF1bHRfdmFyaWFibGUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6OiRyZWxlYXNlX25hbWUkKCkge1xuIgorICAgICAgIiAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLlJlbGVhc2UoJGRlZmF1bHRfdmFyaWFibGUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6OnVuc2FmZV9hcmVuYV9yZWxlYXNlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKTtcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXy5VbnNhZmVBcmVuYVJlbGVhc2UoJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfYWxsb2NhdGVkXyRuYW1lJCg6OnN0ZDo6c3RyaW5nKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQgIT0gTlVMTCkge1xuIgorICAgICAgIiAgICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkbmFtZSRfLlNldEFsbG9jYXRlZCgkZGVmYXVsdF92YXJpYWJsZSQsICRuYW1lJCxcbiIKKyAgICAgICIgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjp1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF8kbmFtZSQoXG4iCisgICAgICAiICAgIDo6c3RkOjpzdHJpbmcqICRuYW1lJCkge1xuIgorICAgICAgIiAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5VbnNhZmVBcmVuYVNldEFsbG9jYXRlZCgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICAgJG5hbWUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIC8vIE5vLWFyZW5hIGNhc2UuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiRpbmxpbmUkIGNvbnN0IDo6c3RkOjpzdHJpbmcmICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uR2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgICRuYW1lJF8uU2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQsIHZhbHVlKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgY2hhciogdmFsdWUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCwgJHN0cmluZ19waWVjZSQodmFsdWUpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgIgorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLCAiCisgICAgICAic2l6ZV90IHNpemUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCxcbiIKKyAgICAgICIgICAgICAkc3RyaW5nX3BpZWNlJChyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICAgIiAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLk11dGFibGVOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXy5SZWxlYXNlTm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfYWxsb2NhdGVkXyRuYW1lJCg6OnN0ZDo6c3RyaW5nKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQgIT0gTlVMTCkge1xuIgorICAgICAgIiAgICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkbmFtZSRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJGRlZmF1bHRfdmFyaWFibGUkLCAkbmFtZSQpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKCFkZXNjcmlwdG9yXy0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5lbXB0eSgpKSB7CisgICAgLy8gSW5pdGlhbGl6ZWQgaW4gR2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VBbGxvY2F0b3IuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6JGRlZmF1bHRfdmFyaWFibGUkID0gTlVMTDtcbiIpOworICB9Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVHdvLWRpbWVuc2lvbiBzcGVjaWFsaXphdGlvbiBoZXJlOiBzdXBwb3J0aW5nIGFyZW5hcyBvciBub3QsIGFuZCBkZWZhdWx0CisgIC8vIHZhbHVlIGlzIHRoZSBlbXB0eSBzdHJpbmcgb3Igbm90LiBDb21wbGV4aXR5IGhlcmUgZW5zdXJlcyB0aGUgbWluaW1hbAorICAvLyBudW1iZXIgb2YgYnJhbmNoZXMgLyBhbW91bnQgb2YgZXh0cmFuZW91cyBjb2RlIGF0IHJ1bnRpbWUgKGdpdmVuIHRoYXQgdGhlCisgIC8vIGJlbG93IG1ldGhvZHMgYXJlIGlubGluZWQgb25lLWxpbmVycykhCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uQ2xlYXJUb0VtcHR5KCRkZWZhdWx0X3ZhcmlhYmxlJCwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uQ2xlYXJUb0RlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkbmFtZSRfLkNsZWFyVG9EZWZhdWx0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIik7CisgICAgfQorICB9Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pIHx8IGRlc2NyaXB0b3JfLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgIC8vIFRPRE8oZ3Bpa2UpOiBpbXByb3ZlIHRoaXMKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAic2V0XyRuYW1lJChmcm9tLiRuYW1lJCgpKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJHNldF9oYXNiaXQkXG4iCisgICAgICAiJG5hbWUkXy5Bc3NpZ25XaXRoRGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQsIGZyb20uJG5hbWUkXyk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLlN3YXAoJm90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uRGVzdHJveSgkZGVmYXVsdF92YXJpYWJsZSQsIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRfLkRlc3Ryb3lOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGNsYXNzbmFtZSQ6OiRkZWZhdWx0X3ZhcmlhYmxlJCA9XG4iCisgICAgICAiICAgIG5ldyA6OnN0ZDo6c3RyaW5nKCRkZWZhdWx0JCwgJGRlZmF1bHRfbGVuZ3RoJCk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2h1dGRvd25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZGVsZXRlICRjbGFzc25hbWUkOjokZGVmYXVsdF92YXJpYWJsZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkJGRlY2xhcmVkX3R5cGUkKFxuIgorICAgICIgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpO1xuIik7CisKKyAgaWYgKEhhc1V0ZjhWZXJpZmljYXRpb24oZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgIGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoXG4iCisgICAgICAiICB0aGlzLT4kbmFtZSQoKS5kYXRhKCksIHRoaXMtPiRuYW1lJCgpLmxlbmd0aCgpLFxuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsXG4iCisgICAgICAiICBcIiRmdWxsX25hbWUkXCIpO1xuIik7CisgIH0KK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoSGFzVXRmOFZlcmlmaWNhdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSAmJgorICAgICAgZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZChcbiIKKyAgICAgICIgIHRoaXMtPiRuYW1lJCgpLmRhdGEoKSwgdGhpcy0+JG5hbWUkKCkubGVuZ3RoKCksXG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsXG4iCisgICAgICAiICBcIiRmdWxsX25hbWUkXCIpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkTWF5YmVBbGlhc2VkKFxuIgorICAgICIgICRudW1iZXIkLCB0aGlzLT4kbmFtZSQoKSwgb3V0cHV0KTtcbiIpOworfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoSGFzVXRmOFZlcmlmaWNhdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSAmJgorICAgICAgZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZChcbiIKKyAgICAgICIgIHRoaXMtPiRuYW1lJCgpLmRhdGEoKSwgdGhpcy0+JG5hbWUkKCkubGVuZ3RoKCksXG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsXG4iCisgICAgICAiICBcIiRmdWxsX25hbWUkXCIpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGFyZ2V0ID1cbiIKKyAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGUkZGVjbGFyZWRfdHlwZSRUb0FycmF5KFxuIgorICAgICIgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJCgpLCB0YXJnZXQpO1xuIik7Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokZGVjbGFyZWRfdHlwZSRTaXplKFxuIgorICAgICIgICAgdGhpcy0+JG5hbWUkKCkpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBTdHJpbmdGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBvcHRpb25zKSB7CisgIFNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjp+U3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiRpbmxpbmUkIGNvbnN0IDo6c3RkOjpzdHJpbmcmICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkdldCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgcmV0dXJuICokZGVmYXVsdF92YXJpYWJsZSQ7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHtcbiIKKyAgICAgICIgIGlmICghaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlNldCgkZGVmYXVsdF92YXJpYWJsZSQsIHZhbHVlLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCBjaGFyKiB2YWx1ZSkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uU2V0KCRkZWZhdWx0X3ZhcmlhYmxlJCxcbiIKKyAgICAgICIgICAgICAkc3RyaW5nX3BpZWNlJCh2YWx1ZSksIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCAiCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCAkcG9pbnRlcl90eXBlJCogdmFsdWUsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZSkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uU2V0KCRkZWZhdWx0X3ZhcmlhYmxlJCwgJHN0cmluZ19waWVjZSQoXG4iCisgICAgICAiICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSxcbiIKKyAgICAgICIgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfLk11dGFibGUoJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmIChoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlJlbGVhc2UoJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gTlVMTDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6OnVuc2FmZV9hcmVuYV9yZWxlYXNlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKTtcbiIKKyAgICAgICIgIGlmIChoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZUFyZW5hUmVsZWFzZShcbiIKKyAgICAgICIgICAgICAgICRkZWZhdWx0X3ZhcmlhYmxlJCwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gTlVMTDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0X2FsbG9jYXRlZF8kbmFtZSQoOjpzdGQ6OnN0cmluZyogJG5hbWUkKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICBpZiAoJG5hbWUkICE9IE5VTEwpIHtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlNldEFsbG9jYXRlZCgkZGVmYXVsdF92YXJpYWJsZSQsICRuYW1lJCxcbiIKKyAgICAgICIgICAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkXyRuYW1lJCgiCisgICAgICAiOjpzdGQ6OnN0cmluZyogJG5hbWUkKSB7XG4iCisgICAgICAiICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCk7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICBpZiAoJG5hbWUkKSB7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVBcmVuYVNldEFsbG9jYXRlZCgkZGVmYXVsdF92YXJpYWJsZSQsICIKKyAgICAgICIkbmFtZSQsIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgLy8gTm8tYXJlbmEgY2FzZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQgY29uc3QgOjpzdGQ6OnN0cmluZyYgJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIHJldHVybiAkb25lb2ZfcHJlZml4JCRuYW1lJF8uR2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgcmV0dXJuICokZGVmYXVsdF92YXJpYWJsZSQ7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCwgdmFsdWUpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCBjaGFyKiB2YWx1ZSkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uU2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICAgJHN0cmluZ19waWVjZSQodmFsdWUpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgIgorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLCBzaXplX3Qgc2l6ZSkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uU2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQsICRzdHJpbmdfcGllY2UkKFxuIgorICAgICAgIiAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5NdXRhYmxlTm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6JHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIGNsZWFyX2hhc18kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgcmV0dXJuICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5SZWxlYXNlTm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIE5VTEw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF9hbGxvY2F0ZWRfJG5hbWUkKDo6c3RkOjpzdHJpbmcqICRuYW1lJCkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCxcbiIKKyAgICAgICIgICAgICAgICRuYW1lJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkRlc3Ryb3koJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkRlc3Ryb3lOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG9uJ3QgcHJpbnQgYW55IHN3YXBwaW5nIGNvZGUuIFN3YXBwaW5nIHRoZSB1bmlvbiB3aWxsIHN3YXAgdGhpcyBmaWVsZC4KK30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgJGNsYXNzbmFtZSRfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPiRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgiCisgICAgIiRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKK30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkRlc3Ryb3koJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkRlc3Ryb3lOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZCRkZWNsYXJlZF90eXBlJChcbiIKKyAgICAgICIgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpO1xuIik7CisKKyAgaWYgKEhhc1V0ZjhWZXJpZmljYXRpb24oZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgIGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoXG4iCisgICAgICAiICB0aGlzLT4kbmFtZSQoKS5kYXRhKCksIHRoaXMtPiRuYW1lJCgpLmxlbmd0aCgpLFxuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsXG4iCisgICAgICAiICBcIiRmdWxsX25hbWUkXCIpO1xuIik7CisgIH0KK30KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRTdHJpbmdWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18sIG9wdGlvbnMpOworfQorCitSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4gJG5hbWUkXztcbiIpOworfQorCit2b2lkIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBTZWUgY29tbWVudCBhYm92ZSBhYm91dCB1bmtub3duIGN0eXBlcy4KKyAgYm9vbCB1bmtub3duX2N0eXBlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5vcHRpb25zKCkuY3R5cGUoKSAhPSBFZmZlY3RpdmVTdHJpbmdDVHlwZShkZXNjcmlwdG9yXyk7CisKKyAgaWYgKHVua25vd25fY3R5cGUpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiIHByaXZhdGU6XG4iCisgICAgICAiICAvLyBIaWRkZW4gZHVlIHRvIHVua25vd24gY3R5cGUgb3B0aW9uLlxuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb25zdCA6OnN0ZDo6c3RyaW5nJiAkbmFtZSQoaW50IGluZGV4KSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgIjo6c3RkOjpzdHJpbmcqIG11dGFibGVfJG5hbWUkKGludCBpbmRleCkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIgorICAgICIiCisgICAgInZvaWQgc2V0XyRuYW1lJChpbnQgaW5kZXgsIGNvbnN0ICRwb2ludGVyX3R5cGUkKiB2YWx1ZSwgc2l6ZV90IHNpemUpIgorICAgICAgICAgICAgICAgICAiJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAiOjpzdGQ6OnN0cmluZyogYWRkXyRuYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBhZGRfJG5hbWUkKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgYWRkXyRuYW1lJChjb25zdCBjaGFyKiB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIGFkZF8kbmFtZSQoY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLCBzaXplX3Qgc2l6ZSkiCisgICAgICAgICAgICAgICAgICIkZGVwcmVjYXRpb24kO1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYgJG5hbWUkKCkgY29uc3QiCisgICAgICAgICAgICAgICAgICIkZGVwcmVjYXRpb24kO1xuIgorICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KiBtdXRhYmxlXyRuYW1lJCgpIgorICAgICAgICAgICAgICAgICAiJGRlcHJlY2F0aW9uJDtcbiIpOworCisgIGlmICh1bmtub3duX2N0eXBlKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCIgcHVibGljOlxuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgY29uc3QgOjpzdGQ6OnN0cmluZyYgJGNsYXNzbmFtZSQ6OiRuYW1lJChpbnQgaW5kZXgpIGNvbnN0IHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAkbmFtZSRfLiRjcHBnZXQkKGluZGV4KTtcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uTXV0YWJsZShpbmRleCk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAiICAkbmFtZSRfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgIgorICAgICIkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJCIKKyAgICAiKGludCBpbmRleCwgY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLCBzaXplX3Qgc2l6ZSkge1xuIgorICAgICIgICRuYW1lJF8uTXV0YWJsZShpbmRleCktPmFzc2lnbihcbiIKKyAgICAiICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjphZGRfJG5hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLkFkZCgpO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OmFkZF8kbmFtZSQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHtcbiIKKyAgICAiICAkbmFtZSRfLkFkZCgpLT5hc3NpZ24odmFsdWUpO1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6YWRkXyRuYW1lJChjb25zdCBjaGFyKiB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8uQWRkKCktPmFzc2lnbih2YWx1ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgIgorICAgICIkY2xhc3NuYW1lJDo6YWRkXyRuYW1lJChjb25zdCAkcG9pbnRlcl90eXBlJCogdmFsdWUsIHNpemVfdCBzaXplKSB7XG4iCisgICAgIiAgJG5hbWUkXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9wb2ludGVyOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JlxuIgorICAgICIkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qXG4iCisgICAgIiRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAmJG5hbWUkXztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5DbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLk1lcmdlRnJvbShmcm9tLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90IG5lZWRlZCBmb3IgcmVwZWF0ZWQgZmllbGRzLgorfQorCit2b2lkIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWQkZGVjbGFyZWRfdHlwZSQoXG4iCisgICAgIiAgICAgIGlucHV0LCB0aGlzLT5hZGRfJG5hbWUkKCkpKTtcbiIpOworICBpZiAoSGFzVXRmOFZlcmlmaWNhdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSAmJgorICAgICAgZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZChcbiIKKyAgICAgICIgIHRoaXMtPiRuYW1lJCh0aGlzLT4kbmFtZSRfc2l6ZSgpIC0gMSkuZGF0YSgpLFxuIgorICAgICAgIiAgdGhpcy0+JG5hbWUkKHRoaXMtPiRuYW1lJF9zaXplKCkgLSAxKS5sZW5ndGgoKSxcbiIKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLFxuIgorICAgICAgIiAgXCIkZnVsbF9uYW1lJFwiKTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIik7CisgIGlmIChIYXNVdGY4VmVyaWZpY2F0aW9uKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICBkZXNjcmlwdG9yXy0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKFxuIgorICAgICAgIiAgdGhpcy0+JG5hbWUkKGkpLmRhdGEoKSwgdGhpcy0+JG5hbWUkKGkpLmxlbmd0aCgpLFxuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLFxuIgorICAgICAgIiAgXCIkZnVsbF9uYW1lJFwiKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkKFxuIgorICAgICIgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJChpKSwgb3V0cHV0KTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT4kbmFtZSRfc2l6ZSgpOyBpKyspIHtcbiIpOworICBpZiAoSGFzVXRmOFZlcmlmaWNhdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSAmJgorICAgICAgZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKFxuIgorICAgICAgIiAgICB0aGlzLT4kbmFtZSQoaSkuZGF0YSgpLCB0aGlzLT4kbmFtZSQoaSkubGVuZ3RoKCksXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSxcbiIKKyAgICAgICIgICAgXCIkZnVsbF9uYW1lJFwiKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlxuIgorICAgICIgICAgV3JpdGUkZGVjbGFyZWRfdHlwZSRUb0FycmF5KCRudW1iZXIkLCB0aGlzLT4kbmFtZSQoaSksIHRhcmdldCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLT4kbmFtZSRfc2l6ZSgpO1xuIgorICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIgorICAgICIgIHRvdGFsX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OiRkZWNsYXJlZF90eXBlJFNpemUoXG4iCisgICAgIiAgICB0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMWYxOWNkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5oCkBAIC0wLDAgKzEsMTMxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9TVFJJTkdfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfU1RSSU5HX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIFN0cmluZ0ZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFN0cmluZ0ZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5TdHJpbmdGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTdGF0aWNNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNodXRkb3duQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTdHJpbmdGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yIDogcHVibGljIFN0cmluZ0ZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+U3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEZXN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+UmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1NUUklOR19GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZjYzMTU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvCkBAIC0wLDAgKzEsMTU2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIHRlc3RzIHRoYXQgdmFyaW91cyBpZGVudGlmaWVycyB3b3JrIGFzIGZpZWxkIGFuZCB0eXBlIG5hbWVzIGV2ZW4KKy8vIHRob3VnaCB0aGUgc2FtZSBpZGVudGlmaWVycyBhcmUgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBDKysgY29kZSBnZW5lcmF0b3IuCisKK3N5bnRheCA9ICJwcm90bzIiOworCisvLyBTb21lIGdlbmVyaWNfc2VydmljZXMgb3B0aW9uKHMpIGFkZGVkIGF1dG9tYXRpY2FsbHkuCisvLyBTZWU6ICBodHRwOi8vZ28vcHJvdG8yLWdlbmVyaWMtc2VydmljZXMtZGVmYXVsdAorb3B0aW9uIGNjX2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOyAgICAgLy8gYXV0by1hZGRlZAorCisvLyBXZSBkb24ndCBwdXQgdGhpcyBpbiBhIHBhY2thZ2Ugd2l0aGluIHByb3RvMiBiZWNhdXNlIHdlIG5lZWQgdG8gbWFrZSBzdXJlCisvLyB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZSBkb2Vzbid0IGRlcGVuZCBvbiBiZWluZyBpbiB0aGUgcHJvdG8yIG5hbWVzcGFjZS4KK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKy8vIFRlc3QgdGhhdCBmaWVsZHMgY2FuIGhhdmUgbmFtZXMgbGlrZSAiaW5wdXQiIGFuZCAiaSIgd2hpY2ggYXJlIGFsc28gdXNlZAorLy8gaW50ZXJuYWxseSBieSB0aGUgY29kZSBnZW5lcmF0b3IgZm9yIGxvY2FsIHZhcmlhYmxlcy4KK21lc3NhZ2UgVGVzdENvbmZsaWN0aW5nU3ltYm9sTmFtZXMgeworICBtZXNzYWdlIEJ1aWxkRGVzY3JpcHRvcnMge30KKyAgbWVzc2FnZSBUeXBlVHJhaXRzIHt9CisKKyAgb3B0aW9uYWwgaW50MzIgaW5wdXQgPSAxOworICBvcHRpb25hbCBpbnQzMiBvdXRwdXQgPSAyOworICBvcHRpb25hbCBzdHJpbmcgbGVuZ3RoID0gMzsKKyAgcmVwZWF0ZWQgaW50MzIgaSA9IDQ7CisgIHJlcGVhdGVkIHN0cmluZyBuZXdfZWxlbWVudCA9IDUgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIGludDMyIHRvdGFsX3NpemUgPSA2OworICBvcHRpb25hbCBpbnQzMiB0YWcgPSA3OworCisgIGVudW0gVGVzdEVudW0geyBGT08gPSAwOyB9CisgIG1lc3NhZ2UgRGF0YTEgeyByZXBlYXRlZCBpbnQzMiBkYXRhID0gMTsgfQorICBtZXNzYWdlIERhdGEyIHsgcmVwZWF0ZWQgVGVzdEVudW0gZGF0YSA9IDE7IH0KKyAgbWVzc2FnZSBEYXRhMyB7IHJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTsgfQorICBtZXNzYWdlIERhdGE0IHsgcmVwZWF0ZWQgRGF0YTQgZGF0YSA9IDE7IH0KKyAgbWVzc2FnZSBEYXRhNSB7IHJlcGVhdGVkIHN0cmluZyBkYXRhID0gMSBbY3R5cGU9U1RSSU5HX1BJRUNFXTsgfQorICBtZXNzYWdlIERhdGE2IHsgcmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxIFtjdHlwZT1DT1JEXTsgfQorCisgIG9wdGlvbmFsIGludDMyIHNvdXJjZSA9IDg7CisgIG9wdGlvbmFsIGludDMyIHZhbHVlID0gOTsKKyAgb3B0aW9uYWwgaW50MzIgZmlsZSA9IDEwOworICBvcHRpb25hbCBpbnQzMiBmcm9tID0gMTE7CisgIG9wdGlvbmFsIGludDMyIGhhbmRsZV91bmludGVycHJldGVkID0gMTI7CisgIHJlcGVhdGVkIGludDMyIGluZGV4ID0gMTM7CisgIG9wdGlvbmFsIGludDMyIGNvbnRyb2xsZXIgPSAxNDsKKyAgb3B0aW9uYWwgaW50MzIgYWxyZWFkeV9oZXJlID0gMTU7CisKKyAgb3B0aW9uYWwgdWludDMyIHVpbnQzMiA9IDE2OworICBvcHRpb25hbCB1aW50NjQgdWludDY0ID0gMTc7CisgIG9wdGlvbmFsIHN0cmluZyBzdHJpbmcgPSAxODsKKyAgb3B0aW9uYWwgaW50MzIgbWVtc2V0ID0gMTk7CisgIG9wdGlvbmFsIGludDMyIGludDMyID0gMjA7CisgIG9wdGlvbmFsIGludDY0IGludDY0ID0gMjE7CisKKyAgb3B0aW9uYWwgdWludDMyIGNhY2hlZF9zaXplID0gMjI7CisgIG9wdGlvbmFsIHVpbnQzMiBleHRlbnNpb25zID0gMjM7CisgIG9wdGlvbmFsIHVpbnQzMiBiaXQgPSAyNDsKKyAgb3B0aW9uYWwgdWludDMyIGJpdHMgPSAyNTsKKyAgb3B0aW9uYWwgdWludDMyIG9mZnNldHMgPSAyNjsKKyAgb3B0aW9uYWwgdWludDMyIHJlZmxlY3Rpb24gPSAyNzsKKworICBtZXNzYWdlIENvcmQge30KKyAgb3B0aW9uYWwgc3RyaW5nIHNvbWVfY29yZCA9IDI4IFtjdHlwZT1DT1JEXTsKKworICBtZXNzYWdlIFN0cmluZ1BpZWNlIHt9CisgIG9wdGlvbmFsIHN0cmluZyBzb21lX3N0cmluZ19waWVjZSA9IDI5IFtjdHlwZT1TVFJJTkdfUElFQ0VdOworCisgIC8vIFNvbWUga2V5d29yZHMuCisgIG9wdGlvbmFsIHVpbnQzMiBpbnQgPSAzMDsKKyAgb3B0aW9uYWwgdWludDMyIGZyaWVuZCA9IDMxOworICBvcHRpb25hbCB1aW50MzIgY2xhc3MgPSAzNzsKKyAgb3B0aW9uYWwgdWludDMyIHR5cGVkZWNsID0gMzk7CisgIG9wdGlvbmFsIHVpbnQzMiBhdXRvID0gNDA7CisKKyAgLy8gVGhlIGdlbmVyYXRvciB1c2VkIHRvICNkZWZpbmUgYSBtYWNybyBjYWxsZWQgIkRPIiBpbnNpZGUgdGhlIC5jYyBmaWxlLgorICBtZXNzYWdlIERPIHt9CisgIG9wdGlvbmFsIERPIGRvID0gMzI7CisKKyAgLy8gU29tZSB0ZW1wbGF0ZSBwYXJhbWV0ZXIgbmFtZXMgZm9yIGV4dGVuc2lvbnMuCisgIG9wdGlvbmFsIGludDMyIGZpZWxkX3R5cGUgPSAzMzsKKyAgb3B0aW9uYWwgYm9vbCBpc19wYWNrZWQgPSAzNDsKKworICAvLyB0ZXN0IGNvbmZsaWN0aW5nIHJlbGVhc2VfJG5hbWUkLiAibGVuZ3RoIiBhbmQgImRvIiBmaWVsZCBpbiB0aGlzIG1lc3NhZ2UKKyAgLy8gbXVzdCByZW1haW4gc3RyaW5nIG9yIG1lc3NhZ2UgZmllbGRzIHRvIG1ha2UgdGhlIHRlc3QgdmFsaWQuCisgIG9wdGlvbmFsIHN0cmluZyByZWxlYXNlX2xlbmd0aCA9IDM1OworICAvLyBBIG1vcmUgZXh0cmVtZSBjYXNlLCB0aGUgZmllbGQgbmFtZSAiZG8iIGhlcmUgaXMgYSBrZXl3b3JkLCB3aGljaCB3aWxsIGJlCisgIC8vIGVzY2FwZWQgdG8gImRvXyIgYWxyZWFkeS4gVGVzdCB0aGVyZSBpcyBubyBjb25mbGljdCBldmVuIHdpdGggZXNjYXBlZCBmaWVsZAorICAvLyBuYW1lcy4KKyAgb3B0aW9uYWwgRE8gcmVsZWFzZV9kbyA9IDM2OworCisgIC8vIEZvciBjbGFzaGluZyBsb2NhbCB2YXJpYWJsZXMgaW4gU2VyaWFsaXplIGFuZCBCeXRlU2l6ZSBjYWxjdWxhdGlvbi4KKyAgb3B0aW9uYWwgc3RyaW5nIHRhcmdldCA9IDM4OworCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7ICAvLyBOT19QUk9UTzMKK30KKworbWVzc2FnZSBUZXN0Q29uZmxpY3RpbmdTeW1ib2xOYW1lc0V4dGVuc2lvbiB7ICAgICAgICAgICAgICAgICAgICAvLyBOT19QUk9UTzMKKyAgZXh0ZW5kIFRlc3RDb25mbGljdGluZ1N5bWJvbE5hbWVzIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8zCisgICAgcmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfZXh0ID0gMjA0MjM2MzggW3BhY2tlZD10cnVlXTsgIC8vIE5PX1BST1RPMworICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT19QUk9UTzMKK30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8zCisKK21lc3NhZ2UgVGVzdENvbmZsaWN0aW5nRW51bU5hbWVzIHsKKyAgZW51bSBOZXN0ZWRDb25mbGljdGluZ0VudW0geworICAgIGFuZCA9IDE7CisgICAgY2xhc3MgPSAyOworICAgIGludCA9IDM7CisgICAgdHlwZWRlZiA9IDQ7CisgICAgWE9SID0gNTsKKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZENvbmZsaWN0aW5nRW51bSBjb25mbGljdGluZ19lbnVtID0gMTsKK30KKworZW51bSBDb25mbGljdGluZ0VudW0geworICBOT1RfRVEgPSAxOworICB2b2xhdGlsZSA9IDI7CisgIHJldHVybiA9IDM7Cit9CisKK21lc3NhZ2UgRHVtbXlNZXNzYWdlIHt9CisKK3NlcnZpY2UgVGVzdENvbmZsaWN0aW5nTWV0aG9kTmFtZXMgeworICBycGMgQ2xvc3VyZShEdW1teU1lc3NhZ2UpIHJldHVybnMgKER1bW15TWVzc2FnZSk7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2M3NThjZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDIwOTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUbyB0ZXN0IHRoZSBjb2RlIGdlbmVyYXRvciwgd2UgYWN0dWFsbHkgdXNlIGl0IHRvIGdlbmVyYXRlIGNvZGUgZm9yCisvLyBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8sIHRoZW4gdGVzdCB0aGF0LiAgVGhpcyBtZWFucyB0aGF0IHdlCisvLyBhcmUgYWN0dWFsbHkgdGVzdGluZyB0aGUgcGFyc2VyIGFuZCBvdGhlciBwYXJ0cyBvZiB0aGUgc3lzdGVtIGF0IHRoZSBzYW1lCisvLyB0aW1lLCBhbmQgdGhhdCBwcm9ibGVtcyBpbiB0aGUgZ2VuZXJhdG9yIG1heSBzaG93IHVwIGFzIGNvbXBpbGUtdGltZSBlcnJvcnMKKy8vIHJhdGhlciB0aGFuIHVuaXR0ZXN0IGZhaWx1cmVzLCB3aGljaCBtYXkgYmUgc3VycHJpc2luZy4gIEhvd2V2ZXIsIHRlc3RpbmcKKy8vIHRoZSBvdXRwdXQgb2YgdGhlIEMrKyBnZW5lcmF0b3IgZGlyZWN0bHkgd291bGQgYmUgdmVyeSBoYXJkLiAgV2UgY2FuJ3QgdmVyeQorLy8gd2VsbCBqdXN0IGNoZWNrIGl0IGFnYWluc3QgZ29sZGVuIGZpbGVzIHNpbmNlIHRob3NlIGZpbGVzIHdvdWxkIGhhdmUgdG8gYmUKKy8vIHVwZGF0ZWQgZm9yIGFueSBzbWFsbCBjaGFuZ2U7IHN1Y2ggYSB0ZXN0IHdvdWxkIGJlIHZlcnkgYnJpdHRsZSBhbmQgcHJvYmFibHkKKy8vIG5vdCB2ZXJ5IGhlbHBmdWwuICBXaGF0IHdlIHJlYWxseSB3YW50IHRvIHRlc3QgaXMgdGhhdCB0aGUgY29kZSBjb21waWxlcworLy8gY29ycmVjdGx5IGFuZCBwcm9kdWNlcyB0aGUgaW50ZXJmYWNlcyB3ZSBleHBlY3QsIHdoaWNoIGlzIHdoeSB0aGlzIHRlc3QKKy8vIGlzIHdyaXR0ZW4gdGhpcyB3YXkuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBDYW4ndCB1c2UgYW4gYW5vbnltb3VzIG5hbWVzcGFjZSBoZXJlIGR1ZSB0byBicm9rZW5uZXNzIG9mIFRydTY0IGNvbXBpbGVyLgorbmFtZXNwYWNlIGNwcF91bml0dGVzdCB7CisKK25hbWVzcGFjZSBwcm90b2J1Zl91bml0dGVzdCA9IDo6cHJvdG9idWZfdW5pdHRlc3Q7CisKKworY2xhc3MgTW9ja0Vycm9yQ29sbGVjdG9yIDogcHVibGljIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIE1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisgIH5Nb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHN0cmluZyB0ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGludCBsaW5lLCBpbnQgY29sdW1uLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJnRleHRfLCAiJDA6JDE6JDI6ICQzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KK307CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyBUZXN0IHRoYXQgZ2VuZXJhdGVkIGNvZGUgaGFzIHByb3BlciBkZXNjcmlwdG9yczoKKy8vIFBhcnNlIGEgZGVzY3JpcHRvciBkaXJlY3RseSAodXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkltcG9ydGVyKSBhbmQKKy8vIGNvbXBhcmUgaXQgdG8gdGhlIG9uZSB0aGF0IHdhcyBwcm9kdWNlZCBieSBnZW5lcmF0ZWQgY29kZS4KK1RFU1QoR2VuZXJhdGVkRGVzY3JpcHRvclRlc3QsIElkZW50aWNhbERlc2NyaXB0b3JzKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBnZW5lcmF0ZWRfZGVzY3JpcHRvciA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisKKyAgLy8gU2V0IHVwIHRoZSBJbXBvcnRlci4KKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgRGlza1NvdXJjZVRyZWUgc291cmNlX3RyZWU7CisgIHNvdXJjZV90cmVlLk1hcFBhdGgoIiIsIFRlc3RTb3VyY2VEaXIoKSk7CisgIEltcG9ydGVyIGltcG9ydGVyKCZzb3VyY2VfdHJlZSwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgLy8gSW1wb3J0IChwYXJzZSkgdW5pdHRlc3QucHJvdG8uCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBwYXJzZWRfZGVzY3JpcHRvciA9CisgICAgaW1wb3J0ZXIuSW1wb3J0KCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworICBBU1NFUlRfVFJVRShwYXJzZWRfZGVzY3JpcHRvciAhPSBOVUxMKTsKKworICAvLyBUZXN0IHRoYXQgZGVzY3JpcHRvcnMgYXJlIGdlbmVyYXRlZCBjb3JyZWN0bHkgYnkgY29udmVydGluZyB0aGVtIHRvCisgIC8vIEZpbGVEZXNjcmlwdG9yUHJvdG9zIGFuZCBjb21wYXJpbmcuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZ2VuZXJhdGVkX2RlY3NyaXB0b3JfcHJvdG8sIHBhcnNlZF9kZXNjcmlwdG9yX3Byb3RvOworICBnZW5lcmF0ZWRfZGVzY3JpcHRvci0+Q29weVRvKCZnZW5lcmF0ZWRfZGVjc3JpcHRvcl9wcm90byk7CisgIHBhcnNlZF9kZXNjcmlwdG9yLT5Db3B5VG8oJnBhcnNlZF9kZXNjcmlwdG9yX3Byb3RvKTsKKworICBFWFBFQ1RfRVEocGFyc2VkX2Rlc2NyaXB0b3JfcHJvdG8uRGVidWdTdHJpbmcoKSwKKyAgICAgICAgICAgIGdlbmVyYXRlZF9kZWNzcmlwdG9yX3Byb3RvLkRlYnVnU3RyaW5nKCkpOworfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgRGVmYXVsdHMpIHsKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZGVmYXVsdCB2YWx1ZXMgYXJlIHNldCBjb3JyZWN0bHkgaW4gdGhlIGluaXRpYWwgbWVzc2FnZS4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKworICAvLyBNZXNzYWdlcyBzaG91bGQgcmV0dXJuIHBvaW50ZXJzIHRvIGRlZmF1bHQgaW5zdGFuY2VzIHVudGlsIGZpcnN0IHVzZS4KKyAgLy8gKFRoaXMgaXMgbm90IGNoZWNrZWQgYnkgRXhwZWN0Q2xlYXIoKSBzaW5jZSBpdCBpcyBub3QgYWN0dWFsbHkgdHJ1ZSBhZnRlcgorICAvLyB0aGUgZmllbGRzIGhhdmUgYmVlbiBzZXQgYW5kIHRoZW4gY2xlYXJlZC4pCisgIEVYUEVDVF9FUSgmdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6T3B0aW9uYWxHcm91cDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxncm91cCgpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdF9pbXBvcnQ6OkltcG9ydE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlKCkpOworfQorCisjaWZuZGVmIFBST1RPQlVGX1VTRV9ETExTCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBJbnQzMlN0cmluZ0NvbnZlcnNpb24pIHsKKyAgRVhQRUNUX0VRKCI5NzEiLCBJbnQzMlRvU3RyaW5nKDk3MSkpOworICBFWFBFQ1RfRVEoIih+MHg3ZmZmZmZmZikiLCBJbnQzMlRvU3RyaW5nKGtpbnQzMm1pbikpOworICBFWFBFQ1RfRVEoIjIxNDc0ODM2NDciLCBJbnQzMlRvU3RyaW5nKGtpbnQzMm1heCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBJbnQ2NFN0cmluZ0NvbnZlcnNpb24pIHsKKyAgRVhQRUNUX0VRKCJHT09HTEVfTE9OR0xPTkcoOTcxKSIsIEludDY0VG9TdHJpbmcoOTcxKSk7CisgIEVYUEVDVF9FUSgiR09PR0xFX0xPTkdMT05HKC0yMTQ3NDgzNjQ4KSIsIEludDY0VG9TdHJpbmcoa2ludDMybWluKSk7CisgIEVYUEVDVF9FUSgiR09PR0xFX0xPTkdMT05HKH4weDdmZmZmZmZmZmZmZmZmZmYpIiwgSW50NjRUb1N0cmluZyhraW50NjRtaW4pKTsKKyAgRVhQRUNUX0VRKCJHT09HTEVfTE9OR0xPTkcoOTIyMzM3MjAzNjg1NDc3NTgwNykiLCBJbnQ2NFRvU3RyaW5nKGtpbnQ2NG1heCkpOworfQorI2VuZGlmICAvLyAhUFJPVE9CVUZfVVNFX0RMTFMKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgRmxvYXRpbmdQb2ludERlZmF1bHRzKSB7CisgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMmIGV4dHJlbWVfZGVmYXVsdCA9CisgICAgICB1bml0dGVzdDo6VGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzOjpkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgRVhQRUNUX0VRKDAuMGYsIGV4dHJlbWVfZGVmYXVsdC56ZXJvX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoMS4wZiwgZXh0cmVtZV9kZWZhdWx0Lm9uZV9mbG9hdCgpKTsKKyAgRVhQRUNUX0VRKDEuNWYsIGV4dHJlbWVfZGVmYXVsdC5zbWFsbF9mbG9hdCgpKTsKKyAgRVhQRUNUX0VRKC0xLjBmLCBleHRyZW1lX2RlZmF1bHQubmVnYXRpdmVfb25lX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoLTEuNWYsIGV4dHJlbWVfZGVmYXVsdC5uZWdhdGl2ZV9mbG9hdCgpKTsKKyAgRVhQRUNUX0VRKDIuMGU4ZiwgZXh0cmVtZV9kZWZhdWx0LmxhcmdlX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoLThlLTI4ZiwgZXh0cmVtZV9kZWZhdWx0LnNtYWxsX25lZ2F0aXZlX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEobnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSwKKyAgICAgICAgICAgIGV4dHJlbWVfZGVmYXVsdC5pbmZfZG91YmxlKCkpOworICBFWFBFQ1RfRVEoLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCksCisgICAgICAgICAgICBleHRyZW1lX2RlZmF1bHQubmVnX2luZl9kb3VibGUoKSk7CisgIEVYUEVDVF9UUlVFKGV4dHJlbWVfZGVmYXVsdC5uYW5fZG91YmxlKCkgIT0gZXh0cmVtZV9kZWZhdWx0Lm5hbl9kb3VibGUoKSk7CisgIEVYUEVDVF9FUShudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCksCisgICAgICAgICAgICBleHRyZW1lX2RlZmF1bHQuaW5mX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoLW51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSwKKyAgICAgICAgICAgIGV4dHJlbWVfZGVmYXVsdC5uZWdfaW5mX2Zsb2F0KCkpOworICBFWFBFQ1RfVFJVRShleHRyZW1lX2RlZmF1bHQubmFuX2Zsb2F0KCkgIT0gZXh0cmVtZV9kZWZhdWx0Lm5hbl9mbG9hdCgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgVHJpZ3JhcGgpIHsKKyAgY29uc3QgdW5pdHRlc3Q6OlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyYgZXh0cmVtZV9kZWZhdWx0ID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKworICBFWFBFQ1RfRVEoIj8gPyA/PyA/PyA/Pz8gP1w/LyA/XD8tIiwgZXh0cmVtZV9kZWZhdWx0LmNwcF90cmlncmFwaCgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgRXh0cmVtZVNtYWxsSW50ZWdlckRlZmF1bHQpIHsKKyAgY29uc3QgdW5pdHRlc3Q6OlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyYgZXh0cmVtZV9kZWZhdWx0ID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgRVhQRUNUX0VRKH4weDdmZmZmZmZmLCBraW50MzJtaW4pOworICBFWFBFQ1RfRVEoR09PR0xFX0xPTkdMT05HKH4weDdmZmZmZmZmZmZmZmZmZmYpLCBraW50NjRtaW4pOworICBFWFBFQ1RfRVEoa2ludDMybWluLCBleHRyZW1lX2RlZmF1bHQucmVhbGx5X3NtYWxsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoa2ludDY0bWluLCBleHRyZW1lX2RlZmF1bHQucmVhbGx5X3NtYWxsX2ludDY0KCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBBY2Nlc3NvcnMpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlIHRoZW4gZ28gYmFjayBhbmQgY2hlY2sgYWxsIHRob3NlCisgIC8vIHZhbHVlcy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpNb2RpZnlSZXBlYXRlZEZpZWxkcygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RSZXBlYXRlZEZpZWxkc01vZGlmaWVkKG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBNdXRhYmxlU3RyaW5nRGVmYXVsdCkgeworICAvLyBtdXRhYmxlX2ZvbygpIGZvciBhIHN0cmluZyBzaG91bGQgcmV0dXJuIGEgc3RyaW5nIGluaXRpYWxpemVkIHRvIGl0cworICAvLyBkZWZhdWx0IHZhbHVlLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0VRKCJoZWxsbyIsICptZXNzYWdlLm11dGFibGVfZGVmYXVsdF9zdHJpbmcoKSk7CisKKyAgLy8gTm90ZSB0aGF0IHRoZSBmaXJzdCB0aW1lIHdlIGNhbGwgbXV0YWJsZV9mb28oKSwgd2UgZ2V0IGEgbmV3bHktYWxsb2NhdGVkCisgIC8vIHN0cmluZywgYnV0IGlmIHdlIGNsZWFyIGl0IGFuZCBjYWxsIGl0IGFnYWluLCB3ZSBnZXQgdGhlIHNhbWUgb2JqZWN0IGFnYWluLgorICAvLyBXZSBzaG91bGQgdmVyaWZ5IHRoYXQgaXQgaGFzIGl0cyBkZWZhdWx0IHZhbHVlIGluIGJvdGggY2FzZXMuCisgIG1lc3NhZ2Uuc2V0X2RlZmF1bHRfc3RyaW5nKCJibGFoIik7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKworICBFWFBFQ1RfRVEoImhlbGxvIiwgKm1lc3NhZ2UubXV0YWJsZV9kZWZhdWx0X3N0cmluZygpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU3RyaW5nRGVmYXVsdHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBtZXNzYWdlOworICAvLyBDaGVjayBpZiAnXDAwMCcgY2FuIGJlIHVzZWQgaW4gZGVmYXVsdCBzdHJpbmcgdmFsdWUuCisgIEVYUEVDVF9FUShzdHJpbmcoImhlbFwwMDBsbyIsIDYpLCBtZXNzYWdlLnN0cmluZ193aXRoX3plcm8oKSk7CisgIEVYUEVDVF9FUShzdHJpbmcoIndvclwwMDBsZCIsIDYpLCBtZXNzYWdlLmJ5dGVzX3dpdGhfemVybygpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgUmVsZWFzZVN0cmluZykgeworICAvLyBDaGVjayB0aGF0IHJlbGVhc2VfZm9vKCkgc3RhcnRzIG91dCBOVUxMLCBhbmQgZ2l2ZXMgdXMgYSB2YWx1ZQorICAvLyB0aGF0IHdlIGNhbiBkZWxldGUgYWZ0ZXIgaXQncyBiZWVuIHNldC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIEVYUEVDVF9FUShOVUxMLCBtZXNzYWdlLnJlbGVhc2VfZGVmYXVsdF9zdHJpbmcoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIG1lc3NhZ2UuZGVmYXVsdF9zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5zZXRfZGVmYXVsdF9zdHJpbmcoImJsYWgiKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZGVmYXVsdF9zdHJpbmcoKSk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8c3RyaW5nPiBzdHIobWVzc2FnZS5yZWxlYXNlX2RlZmF1bHRfc3RyaW5nKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zdHJpbmcoKSk7CisgIEFTU0VSVF9UUlVFKHN0ciAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJibGFoIiwgKnN0cik7CisKKyAgRVhQRUNUX0VRKE5VTEwsIG1lc3NhZ2UucmVsZWFzZV9kZWZhdWx0X3N0cmluZygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgbWVzc2FnZS5kZWZhdWx0X3N0cmluZygpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgUmVsZWFzZU1lc3NhZ2UpIHsKKyAgLy8gQ2hlY2sgdGhhdCByZWxlYXNlX2ZvbygpIHN0YXJ0cyBvdXQgTlVMTCwgYW5kIGdpdmVzIHVzIGEgdmFsdWUKKyAgLy8gdGhhdCB3ZSBjYW4gZGVsZXRlIGFmdGVyIGl0J3MgYmVlbiBzZXQuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBFWFBFQ1RfRVEoTlVMTCwgbWVzc2FnZS5yZWxlYXNlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigxKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjx1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPiBuZXN0KAorICAgICAgbWVzc2FnZS5yZWxlYXNlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEFTU0VSVF9UUlVFKG5lc3QgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgxLCBuZXN0LT5iYigpKTsKKworICBFWFBFQ1RfRVEoTlVMTCwgbWVzc2FnZS5yZWxlYXNlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFNldEFsbG9jYXRlZFN0cmluZykgeworICAvLyBDaGVjayB0aGF0IHNldF9hbGxvY2F0ZWRfZm9vKCkgd29ya3MgZm9yIHN0cmluZ3MuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc3RyaW5nKCkpOworICBjb25zdCBzdHJpbmcga0hlbGxvKCJoZWxsbyIpOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zdHJpbmcoa0hlbGxvKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9zdHJpbmcoTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiIiwgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX29wdGlvbmFsX3N0cmluZyhuZXcgc3RyaW5nKGtIZWxsbykpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShrSGVsbG8sIG1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBTZXRBbGxvY2F0ZWRNZXNzYWdlKSB7CisgIC8vIENoZWNrIHRoYXQgc2V0X2FsbG9jYXRlZF9mb28oKSBjYW4gYmUgY2FsbGVkIGluIGFsbCBjYXNlcy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEpOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBuZXN0ID0KKyAgICAgIG1lc3NhZ2UucmVsZWFzZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICBBU1NFUlRfVFJVRShuZXN0ICE9IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKG5lc3QpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgQ2xlYXIpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlLCBjbGVhciB0aGUgbWVzc2FnZSwgdGhlbiBjaGVjayB0aGF0CisgIC8vIGl0IGlzIGNsZWFyZWQuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7CisKKyAgLy8gVW5saWtlIHdpdGggdGhlIGRlZmF1bHRzIHRlc3QsIHdlIGRvIE5PVCBleHBlY3QgdGhhdCByZXF1ZXN0aW5nIGVtYmVkZGVkCisgIC8vIG1lc3NhZ2VzIHdpbGwgcmV0dXJuIGEgcG9pbnRlciB0byB0aGUgZGVmYXVsdCBpbnN0YW5jZS4gIEluc3RlYWQsIHRoZXkKKyAgLy8gc2hvdWxkIHJldHVybiB0aGUgb2JqZWN0cyB0aGF0IHdlcmUgY3JlYXRlZCB3aGVuIG11dGFibGVfYmxhaCgpIHdhcworICAvLyBjYWxsZWQuCisgIEVYUEVDVF9ORSgmdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6T3B0aW9uYWxHcm91cDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxncm91cCgpKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdF9pbXBvcnQ6OkltcG9ydE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBFbWJlZGRlZE51bGxzSW5CeXRlc0NoYXJTdGFyKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBjb25zdCBjaGFyKiB2YWx1ZSA9ICJcMGxhbGFsYVwwXDAiOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9ieXRlcyh2YWx1ZSwgOSk7CisgIEFTU0VSVF9FUSg5LCBtZXNzYWdlLm9wdGlvbmFsX2J5dGVzKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lbWNtcCh2YWx1ZSwgbWVzc2FnZS5vcHRpb25hbF9ieXRlcygpLmRhdGEoKSwgOSkpOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2J5dGVzKHZhbHVlLCA5KTsKKyAgQVNTRVJUX0VRKDksIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMoMCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lbWNtcCh2YWx1ZSwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcygwKS5kYXRhKCksIDkpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgQ2xlYXJPbmVGaWVsZCkgeworICAvLyBTZXQgZXZlcnkgZmllbGQgdG8gYSB1bmlxdWUgdmFsdWUsIHRoZW4gY2xlYXIgb25lIHZhbHVlIGFuZCBpbnN1cmUgdGhhdAorICAvLyBvbmx5IHRoYXQgb25lIHZhbHVlIGlzIGNsZWFyZWQuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgaW50NjQgb3JpZ2luYWxfdmFsdWUgPSBtZXNzYWdlLm9wdGlvbmFsX2ludDY0KCk7CisKKyAgLy8gQ2xlYXIgdGhlIGZpZWxkIGFuZCBtYWtlIHN1cmUgaXQgc2hvd3MgdXAgYXMgY2xlYXJlZC4KKyAgbWVzc2FnZS5jbGVhcl9vcHRpb25hbF9pbnQ2NCgpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW50NjQoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0KCkpOworCisgIC8vIE90aGVyIGFkamFjZW50IGZpZWxkcyBzaG91bGQgbm90IGJlIGNsZWFyZWQuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF91aW50MzIoKSk7CisKKyAgLy8gTWFrZSBzdXJlIGlmIHdlIHNldCBpdCBhZ2FpbiwgdGhlbiBhbGwgZmllbGRzIGFyZSBzZXQuCisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDY0KG9yaWdpbmFsX3ZhbHVlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU3RyaW5nQ2hhclN0YXJMZW5ndGgpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgd2UgY2FuIHVzZSBhIGNoYXIqLGxlbmd0aCB0byBzZXQgb25lIG9mIHRoZSBzdHJpbmcgZmllbGRzLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3N0cmluZygiYWJjZGVmIiwgMyk7CisgIEVYUEVDVF9FUSgiYWJjIiwgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmcoKSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgd2UgY2FuIHVzZSBhIGNoYXIqLGxlbmd0aCB0byBhZGQgdG8gYSByZXBlYXRlZCBzdHJpbmcgZmllbGQuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiYWJjZGVmIiwgMyk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoImFiYyIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKDApKTsKKworICAvLyBWZXJpZnkgdGhhdCB3ZSBjYW4gdXNlIGEgY2hhciosbGVuZ3RoIHRvIHNldCBhIHJlcGVhdGVkIHN0cmluZyBmaWVsZC4KKyAgbWVzc2FnZS5zZXRfcmVwZWF0ZWRfc3RyaW5nKDAsICJ3eHl6IiwgMik7CisgIEVYUEVDVF9FUSgid3giLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZygwKSk7Cit9CisKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgQ29weUZyb20pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworCisgIC8vIENvcHlpbmcgZnJvbSBzZWxmIHNob3VsZCBiZSBhIG5vLW9wLgorICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFN3YXBXaXRoRW1wdHkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdENsZWFyKG1lc3NhZ2UyKTsKKyAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgVGVzdFV0aWw6OkV4cGVjdENsZWFyKG1lc3NhZ2UxKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU3dhcFdpdGhTZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgIG1lc3NhZ2UuU3dhcCgmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFN3YXBXaXRoT3RoZXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX2ludDMyKDEyMyk7CisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF9zdHJpbmcoImFiYyIpOworICBtZXNzYWdlMS5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigxKTsKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX25lc3RlZF9lbnVtKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgIG1lc3NhZ2UxLmFkZF9yZXBlYXRlZF9pbnQzMigxKTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX2ludDMyKDIpOworICBtZXNzYWdlMS5hZGRfcmVwZWF0ZWRfc3RyaW5nKCJhIik7CisgIG1lc3NhZ2UxLmFkZF9yZXBlYXRlZF9zdHJpbmcoImIiKTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig3KTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig4KTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgIG1lc3NhZ2UxLmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIpOworCisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9pbnQzMig0NTYpOworICBtZXNzYWdlMi5zZXRfb3B0aW9uYWxfc3RyaW5nKCJkZWYiKTsKKyAgbWVzc2FnZTIubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMik7CisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9uZXN0ZWRfZW51bSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIpOworICBtZXNzYWdlMi5hZGRfcmVwZWF0ZWRfaW50MzIoMyk7CisgIG1lc3NhZ2UyLmFkZF9yZXBlYXRlZF9zdHJpbmcoImMiKTsKKyAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig5KTsKKyAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWik7CisKKyAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworCisgIEVYUEVDVF9FUSg0NTYsIG1lc3NhZ2UxLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoImRlZiIsIG1lc3NhZ2UxLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UxLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UxLm9wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZTEucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDMsIG1lc3NhZ2UxLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UxLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoImMiLCBtZXNzYWdlMS5yZXBlYXRlZF9zdHJpbmcoMCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZTEucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDksIG1lc3NhZ2UxLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApLmJiKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZTEucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWiwgbWVzc2FnZTEucmVwZWF0ZWRfbmVzdGVkX2VudW0oMCkpOworCisgIEVYUEVDVF9FUSgxMjMsIG1lc3NhZ2UyLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoImFiYyIsIG1lc3NhZ2UyLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UyLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UyLm9wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZTIucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UyLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UyLnJlcGVhdGVkX2ludDMyKDEpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UyLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoImEiLCBtZXNzYWdlMi5yZXBlYXRlZF9zdHJpbmcoMCkpOworICBFWFBFQ1RfRVEoImIiLCBtZXNzYWdlMi5yZXBlYXRlZF9zdHJpbmcoMSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZTIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDcsIG1lc3NhZ2UyLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApLmJiKCkpOworICBFWFBFQ1RfRVEoOCwgbWVzc2FnZTIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMSkuYmIoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMi5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlMi5yZXBlYXRlZF9uZXN0ZWRfZW51bSgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UyLnJlcGVhdGVkX25lc3RlZF9lbnVtKDEpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgQ29weUNvbnN0cnVjdG9yKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTE7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UyKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIENvcHlBc3NpZ25tZW50T3BlcmF0b3IpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTI7CisgIG1lc3NhZ2UyID0gbWVzc2FnZTE7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworCisgIC8vIE1ha2Ugc3VyZSB0aGF0IHNlbGYtYXNzaWdubWVudCBkb2VzIHNvbWV0aGluZyBzYW5lLgorICBtZXNzYWdlMi5vcGVyYXRvcj0obWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworI2lmICFkZWZpbmVkKFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMpIHx8IFwKKyAgICAhZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSkKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFVwY2FzdENvcHlGcm9tKSB7CisgIC8vIFRlc3QgdGhlIENvcHlGcm9tIG1ldGhvZCB0aGF0IHRha2VzIGluIHRoZSBnZW5lcmljIGNvbnN0IE1lc3NhZ2UmCisgIC8vIHBhcmFtZXRlci4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworCisgIGNvbnN0IE1lc3NhZ2UqIHNvdXJjZSA9IGltcGxpY2l0X2Nhc3Q8Y29uc3QgTWVzc2FnZSo+KCZtZXNzYWdlMSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKCpzb3VyY2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworfQorI2VuZGlmCisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBEeW5hbWljTWVzc2FnZUNvcHlGcm9tKSB7CisgIC8vIFRlc3QgY29weWluZyBmcm9tIGEgRHluYW1pY01lc3NhZ2UsIHdoaWNoIG11c3QgZmFsbCBiYWNrIHRvIHVzaW5nCisgIC8vIHJlZmxlY3Rpb24uCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTI7CisKKyAgLy8gQ29uc3RydWN0IGEgbmV3IHZlcnNpb24gb2YgdGhlIGR5bmFtaWMgbWVzc2FnZSB2aWEgdGhlIGZhY3RvcnkuCisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UxOworICBtZXNzYWdlMS5yZXNldChmYWN0b3J5LkdldFByb3RvdHlwZSgKKyAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSktPk5ldygpKTsKKworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UxLmdldCgpKTsKKworICBtZXNzYWdlMi5Db3B5RnJvbSgqbWVzc2FnZTEpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIE5vbkVtcHR5TWVyZ2VGcm9tKSB7CisgIC8vIFRlc3QgbWVyZ2luZyB3aXRoIGEgbm9uLWVtcHR5IG1lc3NhZ2UuIENvZGUgaXMgYSBtb2RpZmllZCBmb3JtCisgIC8vIG9mIHRoYXQgZm91bmQgaW4gZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzX3VuaXR0ZXN0LmNjLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlMSk7CisKKyAgLy8gVGhpcyBmaWVsZCB3aWxsIHRlc3QgbWVyZ2luZyBpbnRvIGFuIGVtcHR5IHNwb3QuCisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9pbnQzMihtZXNzYWdlMS5vcHRpb25hbF9pbnQzMigpKTsKKyAgbWVzc2FnZTEuY2xlYXJfb3B0aW9uYWxfaW50MzIoKTsKKworICAvLyBUaGlzIHRlc3RzIG92ZXJ3cml0aW5nLgorICBtZXNzYWdlMi5zZXRfb3B0aW9uYWxfc3RyaW5nKG1lc3NhZ2UxLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX3N0cmluZygic29tZXRoaW5nIGVsc2UiKTsKKworICAvLyBUaGlzIHRlc3RzIGNvbmNhdGVuYXRpbmcuCisgIG1lc3NhZ2UyLmFkZF9yZXBlYXRlZF9pbnQzMihtZXNzYWdlMS5yZXBlYXRlZF9pbnQzMigxKSk7CisgIGludDMyIGkgPSBtZXNzYWdlMS5yZXBlYXRlZF9pbnQzMigwKTsKKyAgbWVzc2FnZTEuY2xlYXJfcmVwZWF0ZWRfaW50MzIoKTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX2ludDMyKGkpOworCisgIG1lc3NhZ2UxLk1lcmdlRnJvbShtZXNzYWdlMik7CisKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMSk7Cit9CisKKyNpZiAhZGVmaW5lZChQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTKSB8fCBcCisgICAgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1JUVEkpCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgTWVyZ2VGcm9tU2VsZikgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIEVYUEVDVF9ERUFUSChtZXNzYWdlLk1lcmdlRnJvbShtZXNzYWdlKSwgIkNoZWNrIGZhaWxlZDouKnBiWy5dY2MiKTsKKyAgRVhQRUNUX0RFQVRIKG1lc3NhZ2UuTWVyZ2VGcm9tKGltcGxpY2l0X2Nhc3Q8Y29uc3QgTWVzc2FnZSY+KG1lc3NhZ2UpKSwKKyAgICAgICAgICAgICAgICJDaGVjayBmYWlsZWQ6LipwYlsuXWNjIik7Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKyNlbmRpZiAgLy8gIVBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMgfHwgIUdPT0dMRV9QUk9UT0JVRl9OT19SVFRJCisKKy8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KCksCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBTZXJpYWxpemF0aW9uVG9BcnJheSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgc3RyaW5nIGRhdGE7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZGF0YSkpOworICB1aW50OCogZW5kID0gbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIEVYUEVDVF9FUShzaXplLCBlbmQgLSBzdGFydCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworCit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFBhY2tlZEZpZWxkc1NlcmlhbGl6YXRpb25Ub0FycmF5KSB7CisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgcGFja2VkX21lc3NhZ2UxLCBwYWNrZWRfbWVzc2FnZTI7CisgIHN0cmluZyBwYWNrZWRfZGF0YTsKKyAgVGVzdFV0aWw6OlNldFBhY2tlZEZpZWxkcygmcGFja2VkX21lc3NhZ2UxKTsKKyAgaW50IHBhY2tlZF9zaXplID0gcGFja2VkX21lc3NhZ2UxLkJ5dGVTaXplKCk7CisgIHBhY2tlZF9kYXRhLnJlc2l6ZShwYWNrZWRfc2l6ZSk7CisgIHVpbnQ4KiBzdGFydCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJnBhY2tlZF9kYXRhKSk7CisgIHVpbnQ4KiBlbmQgPSBwYWNrZWRfbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIEVYUEVDVF9FUShwYWNrZWRfc2l6ZSwgZW5kIC0gc3RhcnQpOworICBFWFBFQ1RfVFJVRShwYWNrZWRfbWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKHBhY2tlZF9kYXRhKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRGaWVsZHNTZXQocGFja2VkX21lc3NhZ2UyKTsKK30KKworLy8gVGVzdCB0aGUgZ2VuZXJhdGVkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygpIGJ5IGZvcmNpbmcgdGhlIGJ1ZmZlciB0byB3cml0ZQorLy8gb25lIGJ5dGUgYXQgYSB0aW1lLgorVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU2VyaWFsaXphdGlvblRvU3RyZWFtKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlMSk7CisgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgc3RyaW5nIGRhdGE7CisgIGRhdGEucmVzaXplKHNpemUpOworICB7CisgICAgLy8gQWxsb3cgdGhlIG91dHB1dCBzdHJlYW0gdG8gYnVmZmVyIG9ubHkgb25lIGJ5dGUgYXQgYSB0aW1lLgorICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgb3V0cHV0X3N0cmVhbS5CeXRlQ291bnQoKSk7CisgIH0KKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgUGFja2VkRmllbGRzU2VyaWFsaXphdGlvblRvU3RyZWFtKSB7CisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0UGFja2VkRmllbGRzKCZtZXNzYWdlMSk7CisgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgc3RyaW5nIGRhdGE7CisgIGRhdGEucmVzaXplKHNpemUpOworICB7CisgICAgLy8gQWxsb3cgdGhlIG91dHB1dCBzdHJlYW0gdG8gYnVmZmVyIG9ubHkgb25lIGJ5dGUgYXQgYSB0aW1lLgorICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgb3V0cHV0X3N0cmVhbS5CeXRlQ291bnQoKSk7CisgIH0KKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgUmVxdWlyZWQpIHsKKyAgLy8gVGVzdCB0aGF0IElzSW5pdGlhbGl6ZWQoKSByZXR1cm5zIGZhbHNlIGlmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZy4KKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2Uuc2V0X2EoMSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2Uuc2V0X2IoMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2Uuc2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgUmVxdWlyZWRGb3JlaWduKSB7CisgIC8vIFRlc3QgdGhhdCBJc0luaXRpYWxpemVkKCkgcmV0dXJucyBmYWxzZSBpZiByZXF1aXJlZCBmaWVsZHMgaW4gbmVzdGVkCisgIC8vIG1lc3NhZ2VzIGFyZSBtaXNzaW5nLgorICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkRm9yZWlnbiBtZXNzYWdlOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9tZXNzYWdlKCktPnNldF9hKDEpOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpLT5zZXRfYigyKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9tZXNzYWdlKCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX3JlcGVhdGVkX21lc3NhZ2UoMCktPnNldF9hKDEpOworICBtZXNzYWdlLm11dGFibGVfcmVwZWF0ZWRfbWVzc2FnZSgwKS0+c2V0X2IoMik7CisgIG1lc3NhZ2UubXV0YWJsZV9yZXBlYXRlZF9tZXNzYWdlKDApLT5zZXRfYygzKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBGb3JlaWduTmVzdGVkKSB7CisgIC8vIFRlc3QgdGhhdCBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgY2FuIGJlIGVtYmVkZGVkIGRpcmVjdGx5IGludG8KKyAgLy8gYW5vdGhlciBtZXNzYWdlLgorICB1bml0dGVzdDo6VGVzdEZvcmVpZ25OZXN0ZWQgbWVzc2FnZTsKKworICAvLyBJZiB0aGlzIGNvbXBpbGVzIGFuZCBydW5zIHdpdGhvdXQgY3Jhc2hpbmcsIGl0IG11c3Qgd29yay4gIFdlIGhhdmUKKyAgLy8gbm90aGluZyBtb3JlIHRvIHRlc3QuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3RlZCA9CisgICAgbWVzc2FnZS5tdXRhYmxlX2ZvcmVpZ25fbmVzdGVkKCk7CisgIG5lc3RlZC0+c2V0X2JiKDEpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBSZWFsbHlMYXJnZVRhZ051bWJlcikgeworICAvLyBUZXN0IHRoYXQgcmVhbGx5IGxhcmdlIHRhZyBudW1iZXJzIGRvbid0IGJyZWFrIGFueXRoaW5nLgorICB1bml0dGVzdDo6VGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgc3RyaW5nIGRhdGE7CisKKyAgLy8gRm9yIHRoZSBtb3N0IHBhcnQsIGlmIHRoaXMgY29tcGlsZXMgYW5kIHJ1bnMgdGhlbiB3ZSdyZSBwcm9iYWJseSBnb29kLgorICAvLyAoVGhlIG1vc3QgbGlrZWx5IGNhdXNlIGZvciBmYWlsdXJlIHdvdWxkIGJlIGlmIHNvbWV0aGluZyB3ZXJlIGF0dGVtcHRpbmcKKyAgLy8gdG8gYWxsb2NhdGUgYSBsb29rdXAgdGFibGUgb2Ygc29tZSBzb3J0IHVzaW5nIHRhZyBudW1iZXJzIGFzIHRoZSBpbmRleC4pCisgIC8vIFdlJ2xsIHRyeSBzZXJpYWxpemluZyBqdXN0IGZvciBmdW4uCisgIG1lc3NhZ2UxLnNldF9hKDEyMzQpOworICBtZXNzYWdlMS5zZXRfYmIoNTY3OCk7CisgIG1lc3NhZ2UxLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEyMzQsIG1lc3NhZ2UyLmEoKSk7CisgIEVYUEVDVF9FUSg1Njc4LCBtZXNzYWdlMi5iYigpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgTXV0dWFsUmVjdXJzaW9uKSB7CisgIC8vIFRlc3QgdGhhdCBtdXR1YWxseS1yZWN1cnNpdmUgbWVzc2FnZSB0eXBlcyB3b3JrLgorICB1bml0dGVzdDo6VGVzdE11dHVhbFJlY3Vyc2lvbkEgbWVzc2FnZTsKKyAgdW5pdHRlc3Q6OlRlc3RNdXR1YWxSZWN1cnNpb25BKiBuZXN0ZWQgPSBtZXNzYWdlLm11dGFibGVfYmIoKS0+bXV0YWJsZV9hKCk7CisgIHVuaXR0ZXN0OjpUZXN0TXV0dWFsUmVjdXJzaW9uQSogbmVzdGVkMiA9IG5lc3RlZC0+bXV0YWJsZV9iYigpLT5tdXRhYmxlX2EoKTsKKworICAvLyBBZ2FpbiwgaWYgdGhlIGFib3ZlIGNvbXBpbGVzIGFuZCBydW5zLCB0aGF0J3MgYWxsIHdlIHJlYWxseSBoYXZlIHRvCisgIC8vIHRlc3QsIGJ1dCBqdXN0IGZvciBydW4gd2UnbGwgY2hlY2sgdGhhdCB0aGUgc3lzdGVtIGRpZG4ndCBzb21laG93IGNvbWUKKyAgLy8gdXAgd2l0aCBhIHBvaW50ZXIgbG9vcC4uLgorICBFWFBFQ1RfTkUoJm1lc3NhZ2UsIG5lc3RlZCk7CisgIEVYUEVDVF9ORSgmbWVzc2FnZSwgbmVzdGVkMik7CisgIEVYUEVDVF9ORShuZXN0ZWQsIG5lc3RlZDIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBDYW1lbENhc2VGaWVsZE5hbWVzKSB7CisgIC8vIFRoaXMgdGVzdCBpcyBtYWlubHkgY2hlY2tpbmcgdGhhdCB0aGUgZm9sbG93aW5nIGNvbXBpbGVzLCB3aGljaCB2ZXJpZmllcworICAvLyB0aGF0IHRoZSBmaWVsZCBuYW1lcyB3ZXJlIGNvZXJjZWQgdG8gbG93ZXItY2FzZS4KKyAgLy8KKyAgLy8gUHJvdG9jb2wgYnVmZmVycyBzdGFuZGFyZCBzdHlsZSBpcyB0byB1c2UgbG93ZXJjYXNlLXdpdGgtdW5kZXJzY29yZXMgZm9yCisgIC8vIGZpZWxkIG5hbWVzLiAgU29tZSBvbGQgcHJvdG8xIC5wcm90b3MgdW5mb3J0dW5hdGVseSB1c2VkIGNhbWVsLWNhc2UgZmllbGQKKyAgLy8gbmFtZXMuICBJbiBwcm90bzEsIHRoZXNlIG5hbWVzIHdlcmUgZm9yY2VkIHRvIGxvd2VyLWNhc2UuICBTbywgd2UgZG8gdGhlCisgIC8vIHNhbWUgdGhpbmcgaW4gcHJvdG8yLgorCisgIHVuaXR0ZXN0OjpUZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBtZXNzYWdlOworCisgIG1lc3NhZ2Uuc2V0X3ByaW1pdGl2ZWZpZWxkKDIpOworICBtZXNzYWdlLnNldF9zdHJpbmdmaWVsZCgiZm9vIik7CisgIG1lc3NhZ2Uuc2V0X2VudW1maWVsZCh1bml0dGVzdDo6Rk9SRUlHTl9GT08pOworICBtZXNzYWdlLm11dGFibGVfbWVzc2FnZWZpZWxkKCktPnNldF9jKDYpOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkcHJpbWl0aXZlZmllbGQoOCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkc3RyaW5nZmllbGQoInF1eCIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZGVudW1maWVsZCh1bml0dGVzdDo6Rk9SRUlHTl9CQVIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZG1lc3NhZ2VmaWVsZCgpLT5zZXRfYygxNSk7CisKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UucHJpbWl0aXZlZmllbGQoKSk7CisgIEVYUEVDVF9FUSgiZm9vIiwgbWVzc2FnZS5zdHJpbmdmaWVsZCgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0ZPTywgbWVzc2FnZS5lbnVtZmllbGQoKSk7CisgIEVYUEVDVF9FUSg2LCBtZXNzYWdlLm1lc3NhZ2VmaWVsZCgpLmMoKSk7CisKKyAgRVhQRUNUX0VRKDgsIG1lc3NhZ2UucmVwZWF0ZWRwcmltaXRpdmVmaWVsZCgwKSk7CisgIEVYUEVDVF9FUSgicXV4IiwgbWVzc2FnZS5yZXBlYXRlZHN0cmluZ2ZpZWxkKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwgbWVzc2FnZS5yZXBlYXRlZGVudW1maWVsZCgwKSk7CisgIEVYUEVDVF9FUSgxNSwgbWVzc2FnZS5yZXBlYXRlZG1lc3NhZ2VmaWVsZCgwKS5jKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBUZXN0Q29uZmxpY3RpbmdTeW1ib2xOYW1lcykgeworICAvLyB0ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byBzdWNjZXNzZnVsbHkgY29tcGlsZWQsIHRoZW4gaXQgd29ya3MuICBUaGUKKyAgLy8gZm9sbG93aW5nIGlzIGp1c3QgYSB0b2tlbiB1c2FnZSB0byBpbnN1cmUgdGhhdCB0aGUgY29kZSBpcywgaW4gZmFjdCwKKyAgLy8gYmVpbmcgY29tcGlsZWQgYW5kIGxpbmtlZC4KKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdENvbmZsaWN0aW5nU3ltYm9sTmFtZXMgbWVzc2FnZTsKKyAgbWVzc2FnZS5zZXRfdWludDMyKDEpOworICBFWFBFQ1RfRVEoMywgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKworICBtZXNzYWdlLnNldF9mcmllbmRfKDUpOworICBFWFBFQ1RfRVEoNSwgbWVzc2FnZS5mcmllbmRfKCkpOworCisgIG1lc3NhZ2Uuc2V0X2NsYXNzXyg2KTsKKyAgRVhQRUNUX0VRKDYsIG1lc3NhZ2UuY2xhc3NfKCkpOworCisgIC8vIEluc3RhbnRpYXRlIGV4dGVuc2lvbiB0ZW1wbGF0ZSBmdW5jdGlvbnMgdG8gdGVzdCBjb25mbGljdGluZyB0ZW1wbGF0ZQorICAvLyBwYXJhbWV0ZXIgbmFtZXMuCisgIHR5cGVkZWYgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RDb25mbGljdGluZ1N5bWJvbE5hbWVzRXh0ZW5zaW9uIEV4dGVuc2lvbk1lc3NhZ2U7CisgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKEV4dGVuc2lvbk1lc3NhZ2U6OnJlcGVhdGVkX2ludDMyX2V4dCwgMTIzKTsKKyAgRVhQRUNUX0VRKDEyMywKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKEV4dGVuc2lvbk1lc3NhZ2U6OnJlcGVhdGVkX2ludDMyX2V4dCwgMCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBUZXN0Q29uZmxpY3RpbmdFbnVtTmFtZXMpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RDb25mbGljdGluZ0VudW1OYW1lcyBtZXNzYWdlOworICBtZXNzYWdlLnNldF9jb25mbGljdGluZ19lbnVtKHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0Q29uZmxpY3RpbmdFbnVtTmFtZXNfTmVzdGVkQ29uZmxpY3RpbmdFbnVtX2FuZF8pOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5jb25mbGljdGluZ19lbnVtKCkpOworICBtZXNzYWdlLnNldF9jb25mbGljdGluZ19lbnVtKHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0Q29uZmxpY3RpbmdFbnVtTmFtZXNfTmVzdGVkQ29uZmxpY3RpbmdFbnVtX1hPUik7CisgIEVYUEVDVF9FUSg1LCBtZXNzYWdlLmNvbmZsaWN0aW5nX2VudW0oKSk7CisKKworICBwcm90b2J1Zl91bml0dGVzdDo6Q29uZmxpY3RpbmdFbnVtIGNvbmZsaWN0aW5nX2VudW07CisgIGNvbmZsaWN0aW5nX2VudW0gPSBwcm90b2J1Zl91bml0dGVzdDo6Tk9UX0VROworICBFWFBFQ1RfRVEoMSwgY29uZmxpY3RpbmdfZW51bSk7CisgIGNvbmZsaWN0aW5nX2VudW0gPSBwcm90b2J1Zl91bml0dGVzdDo6cmV0dXJuXzsKKyAgRVhQRUNUX0VRKDMsIGNvbmZsaWN0aW5nX2VudW0pOworfQorCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgVGVzdE9wdGltaXplZEZvclNpemUpIHsKKyAgLy8gV2UgcmVseSBvbiB0aGUgdGVzdHMgaW4gcmVmbGVjdGlvbl9vcHNfdW5pdHRlc3QgYW5kIHdpcmVfZm9ybWF0X3VuaXR0ZXN0CisgIC8vIHRvIHJlYWxseSB0ZXN0IHRoYXQgcmVmbGVjdGlvbi1iYXNlZCBtZXRob2RzIHdvcmsuICBIZXJlIHdlIGFyZSBtb3N0bHkKKyAgLy8ganVzdCBtYWtpbmcgc3VyZSB0aGF0IFRlc3RPcHRpbWl6ZWRGb3JTaXplIGFjdHVhbGx5IGJ1aWxkcyBhbmQgc2VlbXMgdG8KKyAgLy8gZnVuY3Rpb24uCisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RPcHRpbWl6ZWRGb3JTaXplIG1lc3NhZ2UsIG1lc3NhZ2UyOworICBtZXNzYWdlLnNldF9pKDEpOworICBtZXNzYWdlLm11dGFibGVfbXNnKCktPnNldF9jKDIpOworICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UyLmkoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlMi5tc2coKS5jKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBUZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplKSB7CisgIC8vIFZlcmlmaWVzIHRoYXQgc29tZXRoaW5nIG9wdGltaXplZCBmb3Igc3BlZWQgY2FuIGNvbnRhaW4gc29tZXRoaW5nIG9wdGltaXplZAorICAvLyBmb3Igc2l6ZS4KKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBtZXNzYWdlLCBtZXNzYWdlMjsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKS0+c2V0X2koMSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX21lc3NhZ2UoKS0+bXV0YWJsZV9tc2coKS0+c2V0X2MoMik7CisgIHN0cmluZyBkYXRhOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UyLm9wdGlvbmFsX21lc3NhZ2UoKS5pKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZTIucmVwZWF0ZWRfbWVzc2FnZSgwKS5tc2coKS5jKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBUZXN0U3BhY2VVc2VkKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTE7CisgIC8vIHNpemVvZiBwcm92aWRlcyBhIGxvd2VyIGJvdW5kIG9uIFNwYWNlVXNlZCgpLgorICBFWFBFQ1RfTEUoc2l6ZW9mKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMpLCBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7CisgIGNvbnN0IGludCBlbXB0eV9tZXNzYWdlX3NpemUgPSBtZXNzYWdlMS5TcGFjZVVzZWQoKTsKKworICAvLyBTZXR0aW5nIHByaW1pdGl2ZSB0eXBlcyBzaG91bGRuJ3QgYWZmZWN0IHRoZSBzcGFjZSB1c2VkLgorICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfaW50MzIoMTIzKTsKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX2ludDY0KDEyMzQ1KTsKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX3VpbnQzMigxMjMpOworICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfdWludDY0KDEyMzQ1KTsKKyAgRVhQRUNUX0VRKGVtcHR5X21lc3NhZ2Vfc2l6ZSwgbWVzc2FnZTEuU3BhY2VVc2VkKCkpOworCisgIC8vIE9uIHNvbWUgU1RMIGltcGxlbWVudGF0aW9ucywgc2V0dGluZyB0aGUgc3RyaW5nIHRvIGEgc21hbGwgdmFsdWUgc2hvdWxkCisgIC8vIG9ubHkgaW5jcmVhc2UgU3BhY2VVc2VkKCkgYnkgdGhlIHNpemUgb2YgYSBzdHJpbmcgb2JqZWN0LCB0aG91Z2ggdGhpcyBpcworICAvLyBub3QgdHJ1ZSBldmVyeXdoZXJlLgorICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJhYmMiKTsKKyAgRVhQRUNUX0xFKGVtcHR5X21lc3NhZ2Vfc2l6ZSArIHNpemVvZihzdHJpbmcpLCBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7CisKKyAgLy8gU2V0dGluZyBhIHN0cmluZyB0byBhIHZhbHVlIGxhcmdlciB0aGFuIHRoZSBzdHJpbmcgb2JqZWN0IGl0c2VsZiBzaG91bGQKKyAgLy8gaW5jcmVhc2UgU3BhY2VVc2VkKCksIGJlY2F1c2UgaXQgY2Fubm90IHN0b3JlIHRoZSB2YWx1ZSBpbnRlcm5hbGx5LgorICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfc3RyaW5nKHN0cmluZyhzaXplb2Yoc3RyaW5nKSArIDEsICd4JykpOworICBpbnQgbWluX2V4cGVjdGVkX2luY3JlYXNlID0gbWVzc2FnZTEub3B0aW9uYWxfc3RyaW5nKCkuY2FwYWNpdHkoKSArCisgICAgICBzaXplb2Yoc3RyaW5nKTsKKyAgRVhQRUNUX0xFKGVtcHR5X21lc3NhZ2Vfc2l6ZSArIG1pbl9leHBlY3RlZF9pbmNyZWFzZSwKKyAgICAgICAgICAgIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKKworICBpbnQgcHJldmlvdXNfc2l6ZSA9IG1lc3NhZ2UxLlNwYWNlVXNlZCgpOworICAvLyBBZGRpbmcgYW4gb3B0aW9uYWwgbWVzc2FnZSBzaG91bGQgaW5jcmVhc2UgdGhlIHNpemUgYnkgdGhlIHNpemUgb2YgdGhlCisgIC8vIG5lc3RlZCBtZXNzYWdlIHR5cGUuIE5lc3RlZE1lc3NhZ2UgaXMgc2ltcGxlIGVub3VnaCAoMSBpbnQgZmllbGQpIHRoYXQgaXQKKyAgLy8gaXMgZXF1YWwgdG8gc2l6ZW9mKE5lc3RlZE1lc3NhZ2UpCisgIG1lc3NhZ2UxLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgQVNTRVJUX0VRKHNpemVvZih1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKSwKKyAgICAgICAgICAgIG1lc3NhZ2UxLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuU3BhY2VVc2VkKCkpOworICBFWFBFQ1RfRVEocHJldmlvdXNfc2l6ZSArCisgICAgICAgICAgICBzaXplb2YodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSksCisgICAgICAgICAgICBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFRlc3RPbmVvZlNwYWNlVXNlZCkgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMTsKKyAgRVhQRUNUX0xFKHNpemVvZih1bml0dGVzdDo6VGVzdE9uZW9mMiksIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKKworICBjb25zdCBpbnQgZW1wdHlfbWVzc2FnZV9zaXplID0gbWVzc2FnZTEuU3BhY2VVc2VkKCk7CisgIC8vIFNldHRpbmcgcHJpbWl0aXZlIHR5cGVzIHNob3VsZG4ndCBhZmZlY3QgdGhlIHNwYWNlIHVzZWQuCisgIG1lc3NhZ2UxLnNldF9mb29faW50KDEyMyk7CisgIG1lc3NhZ2UxLnNldF9iYXJfaW50KDEyMzQ1KTsKKyAgRVhQRUNUX0VRKGVtcHR5X21lc3NhZ2Vfc2l6ZSwgbWVzc2FnZTEuU3BhY2VVc2VkKCkpOworCisgIC8vIFNldHRpbmcgYSBzdHJpbmcgaW4gb25lb2YgdG8gYSBzbWFsbCB2YWx1ZSBzaG91bGQgb25seSBpbmNyZWFzZSBTcGFjZVVzZWQoKQorICAvLyBieSB0aGUgc2l6ZSBvZiBhIHN0cmluZyBvYmplY3QuCisgIG1lc3NhZ2UxLnNldF9mb29fc3RyaW5nKCJhYmMiKTsKKyAgRVhQRUNUX0xFKGVtcHR5X21lc3NhZ2Vfc2l6ZSArIHNpemVvZihzdHJpbmcpLCBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7CisKKyAgLy8gU2V0dGluZyBhIHN0cmluZyBpbiBvbmVvZiB0byBhIHZhbHVlIGxhcmdlciB0aGFuIHRoZSBzdHJpbmcgb2JqZWN0IGl0c2VsZgorICAvLyBzaG91bGQgaW5jcmVhc2UgU3BhY2VVc2VkKCksIGJlY2F1c2UgaXQgY2Fubm90IHN0b3JlIHRoZSB2YWx1ZSBpbnRlcm5hbGx5LgorICBtZXNzYWdlMS5zZXRfZm9vX3N0cmluZyhzdHJpbmcoc2l6ZW9mKHN0cmluZykgKyAxLCAneCcpKTsKKyAgaW50IG1pbl9leHBlY3RlZF9pbmNyZWFzZSA9IG1lc3NhZ2UxLmZvb19zdHJpbmcoKS5jYXBhY2l0eSgpICsKKyAgICAgIHNpemVvZihzdHJpbmcpOworICBFWFBFQ1RfTEUoZW1wdHlfbWVzc2FnZV9zaXplICsgbWluX2V4cGVjdGVkX2luY3JlYXNlLAorICAgICAgICAgICAgbWVzc2FnZTEuU3BhY2VVc2VkKCkpOworCisgIC8vIFNldHRpbmcgYSBtZXNzYWdlIGluIG9uZW9mIHNob3VsZCBkZWxldGUgdGhlIG90aGVyIGZpZWxkcyBhbmQgaW5jcmVhc2UgdGhlCisgIC8vIHNpemUgYnkgdGhlIHNpemUgb2YgdGhlIG5lc3RlZCBtZXNzYWdlIHR5cGUuIE5lc3RlZE1lc3NhZ2UgaXMgc2ltcGxlIGVub3VnaAorICAvLyB0aGF0IGl0IGlzIGVxdWFsIHRvIHNpemVvZihOZXN0ZWRNZXNzYWdlKQorICBtZXNzYWdlMS5tdXRhYmxlX2Zvb19tZXNzYWdlKCk7CisgIEFTU0VSVF9FUShzaXplb2YodW5pdHRlc3Q6OlRlc3RPbmVvZjI6Ok5lc3RlZE1lc3NhZ2UpLAorICAgICAgICAgICAgbWVzc2FnZTEuZm9vX21lc3NhZ2UoKS5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUShlbXB0eV9tZXNzYWdlX3NpemUgKworICAgICAgICAgICAgc2l6ZW9mKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpOZXN0ZWRNZXNzYWdlKSwKKyAgICAgICAgICAgIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEZpZWxkQ29uc3RhbnRWYWx1ZXMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlOjprQmJGaWVsZE51bWJlciwgMSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprT3B0aW9uYWxJbnQzMkZpZWxkTnVtYmVyLCAxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtPcHRpb25hbGdyb3VwRmllbGROdW1iZXIsIDE2KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZE51bWJlciwgMTgpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a09wdGlvbmFsTmVzdGVkRW51bUZpZWxkTnVtYmVyLCAyMSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprUmVwZWF0ZWRJbnQzMkZpZWxkTnVtYmVyLCAzMSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprUmVwZWF0ZWRncm91cEZpZWxkTnVtYmVyLCA0Nik7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprUmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGROdW1iZXIsIDQ4KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtSZXBlYXRlZE5lc3RlZEVudW1GaWVsZE51bWJlciwgNTEpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBFeHRlbnNpb25Db25zdGFudFZhbHVlcykgeworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6a1NpbmdsZUZpZWxkTnVtYmVyLCAxMDAwKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OmtNdWx0aUZpZWxkTnVtYmVyLCAxMDAxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprT3B0aW9uYWxJbnQzMkV4dGVuc2lvbkZpZWxkTnVtYmVyLCAxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprT3B0aW9uYWxncm91cEV4dGVuc2lvbkZpZWxkTnVtYmVyLCAxNik7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6a09wdGlvbmFsTmVzdGVkTWVzc2FnZUV4dGVuc2lvbkZpZWxkTnVtYmVyLCAxOCk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6a09wdGlvbmFsTmVzdGVkRW51bUV4dGVuc2lvbkZpZWxkTnVtYmVyLCAyMSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6a1JlcGVhdGVkSW50MzJFeHRlbnNpb25GaWVsZE51bWJlciwgMzEpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OmtSZXBlYXRlZGdyb3VwRXh0ZW5zaW9uRmllbGROdW1iZXIsIDQ2KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprUmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uRmllbGROdW1iZXIsIDQ4KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprUmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uRmllbGROdW1iZXIsIDUxKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBFbnVtVmFsdWVzQXNTd2l0Y2hDYXNlcykgeworICAvLyBUZXN0IHRoYXQgb3VyIG5lc3RlZCBlbnVtIHZhbHVlcyBjYW4gYmUgdXNlZCBhcyBzd2l0Y2ggY2FzZXMuICBUaGlzIHRlc3QKKyAgLy8gZG9lc24ndCBhY3R1YWxseSBkbyBhbnl0aGluZywgdGhlIHByb29mIHRoYXQgaXQgd29ya3MgaXMgdGhhdCBpdAorICAvLyBjb21waWxlcy4KKyAgaW50IGkgPTA7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0gYSA9IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUjsKKyAgc3dpdGNoIChhKSB7CisgICAgY2FzZSB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT086CisgICAgICBpID0gMTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSOgorICAgICAgaSA9IDI7CisgICAgICBicmVhazsKKyAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWjoKKyAgICAgIGkgPSAzOworICAgICAgYnJlYWs7CisgICAgY2FzZSB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpORUc6CisgICAgICBpID0gLTE7CisgICAgICBicmVhazsKKyAgICAvLyBubyBkZWZhdWx0IGNhc2U6ICBXZSB3YW50IHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgcmVjb2duaXplcyB0aGF0CisgICAgLy8gICBhbGwgY2FzZXMgYXJlIGNvdmVyZWQuICAoR0NDIHdhcm5zIGlmIHlvdSBkbyBub3QgY292ZXIgYWxsIGNhc2VzIG9mCisgICAgLy8gICBhbiBlbnVtIGluIGEgc3dpdGNoLikKKyAgfQorCisgIC8vIFRva2VuIGNoZWNrIGp1c3QgZm9yIGZ1bi4KKyAgRVhQRUNUX0VRKDIsIGkpOworfQorCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBJc1ZhbGlkVmFsdWUpIHsKKyAgLy8gVGVzdCBlbnVtIElzVmFsaWRWYWx1ZS4KKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDEpKTsKKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDIpKTsKKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDMpKTsKKworICBFWFBFQ1RfRkFMU0UodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDApKTsKKyAgRVhQRUNUX0ZBTFNFKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fSXNWYWxpZCg0KSk7CisKKyAgLy8gTWFrZSBzdXJlIGl0IGFsc28gd29ya3Mgd2hlbiB0aGVyZSBhcmUgZHVwcy4KKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX0lzVmFsaWQoMSkpOworICBFWFBFQ1RfVFJVRSh1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfSXNWYWxpZCgyKSk7CisgIEVYUEVDVF9UUlVFKHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZV9Jc1ZhbGlkKDMpKTsKKworICBFWFBFQ1RfRkFMU0UodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX0lzVmFsaWQoMCkpOworICBFWFBFQ1RfRkFMU0UodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX0lzVmFsaWQoNCkpOworfQorCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBNaW5BbmRNYXgpIHsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5FRywKKyAgICAgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUlOKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWiwKKyAgICAgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUFYKTsKKyAgRVhQRUNUX0VRKDQsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fQVJSQVlTSVpFKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PLCB1bml0dGVzdDo6Rm9yZWlnbkVudW1fTUlOKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiwgdW5pdHRlc3Q6OkZvcmVpZ25FbnVtX01BWCk7CisgIEVYUEVDVF9FUSg3LCB1bml0dGVzdDo6Rm9yZWlnbkVudW1fQVJSQVlTSVpFKTsKKworICBFWFBFQ1RfRVEoMSwgdW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX01JTik7CisgIEVYUEVDVF9FUSgzLCB1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfTUFYKTsKKyAgRVhQRUNUX0VRKDQsIHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZV9BUlJBWVNJWkUpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6U1BBUlNFX0UsIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9NSU4pOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlNQQVJTRV9DLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTUFYKTsKKyAgRVhQRUNUX0VRKDEyNTg5MjM1LCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fQVJSQVlTSVpFKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIHRha2UgdGhlIGFkZHJlc3Mgb2YgX01JTiwgX01BWCBhbmQgX0FSUkFZU0laRS4KKyAgdm9pZCogbnVsbF9wb2ludGVyID0gMDsgIC8vIE5VTEwgbWF5IGJlIGludGVnZXItdHlwZSwgbm90IHBvaW50ZXItdHlwZS4KKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUlOKTsKKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUFYKTsKKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fQVJSQVlTSVpFKTsKKworICBFWFBFQ1RfTkUobnVsbF9wb2ludGVyLCAmdW5pdHRlc3Q6OkZvcmVpZ25FbnVtX01JTik7CisgIEVYUEVDVF9ORShudWxsX3BvaW50ZXIsICZ1bml0dGVzdDo6Rm9yZWlnbkVudW1fTUFYKTsKKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpGb3JlaWduRW51bV9BUlJBWVNJWkUpOworCisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gdXNlIF9NSU4gYW5kIF9NQVggYXMgc3dpdGNoIGNhc2VzLgorICBzd2l0Y2ggKHVuaXR0ZXN0OjpTUEFSU0VfQSkgeworICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX01JTjoKKyAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9NQVg6CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKK1RFU1QoR2VuZXJhdGVkRW51bVRlc3QsIE5hbWUpIHsKKyAgLy8gIk5hbWVzIiBpbiB0aGUgcHJlc2VuY2Ugb2YgZHVwIHZhbHVlcyBhcmUgYSBiaXQgYXJiaXRyYXJ5LgorICBFWFBFQ1RfRVEoIkZPTzEiLCB1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfTmFtZSh1bml0dGVzdDo6Rk9PMSkpOworICBFWFBFQ1RfRVEoIkZPTzEiLCB1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfTmFtZSh1bml0dGVzdDo6Rk9PMikpOworCisgIEVYUEVDVF9FUSgiU1BBUlNFX0EiLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTmFtZSh1bml0dGVzdDo6U1BBUlNFX0EpKTsKKyAgRVhQRUNUX0VRKCJTUEFSU0VfQiIsIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9OYW1lKHVuaXR0ZXN0OjpTUEFSU0VfQikpOworICBFWFBFQ1RfRVEoIlNQQVJTRV9DIiwgdW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX05hbWUodW5pdHRlc3Q6OlNQQVJTRV9DKSk7CisgIEVYUEVDVF9FUSgiU1BBUlNFX0QiLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTmFtZSh1bml0dGVzdDo6U1BBUlNFX0QpKTsKKyAgRVhQRUNUX0VRKCJTUEFSU0VfRSIsIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9OYW1lKHVuaXR0ZXN0OjpTUEFSU0VfRSkpOworICBFWFBFQ1RfRVEoIlNQQVJTRV9GIiwgdW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX05hbWUodW5pdHRlc3Q6OlNQQVJTRV9GKSk7CisgIEVYUEVDVF9FUSgiU1BBUlNFX0ciLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTmFtZSh1bml0dGVzdDo6U1BBUlNFX0cpKTsKK30KKworVEVTVChHZW5lcmF0ZWRFbnVtVGVzdCwgUGFyc2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlIGR1cF92YWx1ZSA9IHVuaXR0ZXN0OjpGT08xOworICBFWFBFQ1RfVFJVRSh1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfUGFyc2UoIkZPTzEiLCAmZHVwX3ZhbHVlKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9PMSwgZHVwX3ZhbHVlKTsKKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX1BhcnNlKCJGT08yIiwgJmR1cF92YWx1ZSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPTzIsIGR1cF92YWx1ZSk7CisgIEVYUEVDVF9GQUxTRSh1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfUGFyc2UoIkZPTyIsICZkdXBfdmFsdWUpKTsKK30KKworVEVTVChHZW5lcmF0ZWRFbnVtVGVzdCwgR2V0RW51bURlc2NyaXB0b3IpIHsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fZGVzY3JpcHRvcigpLAorICAgICAgICAgICAgR2V0RW51bURlc2NyaXB0b3I8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bT4oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rm9yZWlnbkVudW1fZGVzY3JpcHRvcigpLAorICAgICAgICAgICAgR2V0RW51bURlc2NyaXB0b3I8dW5pdHRlc3Q6OkZvcmVpZ25FbnVtPigpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZV9kZXNjcmlwdG9yKCksCisgICAgICAgICAgICBHZXRFbnVtRGVzY3JpcHRvcjx1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWU+KCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX2Rlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgIEdldEVudW1EZXNjcmlwdG9yPHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bT4oKSk7Cit9CisKK2VudW0gTm9uUHJvdG9FbnVtIHsKKyAga0ZvbyA9IDEsCit9OworCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBJc1Byb3RvRW51bVR5cGVUcmFpdCkgeworICBFWFBFQ1RfVFJVRShpc19wcm90b19lbnVtPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3Byb3RvX2VudW08dW5pdHRlc3Q6OkZvcmVpZ25FbnVtPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wcm90b19lbnVtPHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcHJvdG9fZW51bTx1bml0dGVzdDo6VGVzdFNwYXJzZUVudW0+Ojp2YWx1ZSk7CisKKyAgRVhQRUNUX0ZBTFNFKGlzX3Byb3RvX2VudW08aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcHJvdG9fZW51bTxOb25Qcm90b0VudW0+Ojp2YWx1ZSk7Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyBTdXBwb3J0IGNvZGUgZm9yIHRlc3Rpbmcgc2VydmljZXMuCitjbGFzcyBHZW5lcmF0ZWRTZXJ2aWNlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIGNsYXNzIE1vY2tUZXN0U2VydmljZSA6IHB1YmxpYyB1bml0dGVzdDo6VGVzdFNlcnZpY2UgeworICAgcHVibGljOgorICAgIE1vY2tUZXN0U2VydmljZSgpCisgICAgICA6IGNhbGxlZF8oZmFsc2UpLAorICAgICAgICBtZXRob2RfKCIiKSwKKyAgICAgICAgY29udHJvbGxlcl8oTlVMTCksCisgICAgICAgIHJlcXVlc3RfKE5VTEwpLAorICAgICAgICByZXNwb25zZV8oTlVMTCksCisgICAgICAgIGRvbmVfKE5VTEwpIHt9CisKKyAgICB+TW9ja1Rlc3RTZXJ2aWNlKCkge30KKworICAgIHZvaWQgUmVzZXQoKSB7IGNhbGxlZF8gPSBmYWxzZTsgfQorCisgICAgLy8gaW1wbGVtZW50cyBUZXN0U2VydmljZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICB2b2lkIEZvbyhScGNDb250cm9sbGVyKiBjb250cm9sbGVyLAorICAgICAgICAgICAgIGNvbnN0IHVuaXR0ZXN0OjpGb29SZXF1ZXN0KiByZXF1ZXN0LAorICAgICAgICAgICAgIHVuaXR0ZXN0OjpGb29SZXNwb25zZSogcmVzcG9uc2UsCisgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgeworICAgICAgQVNTRVJUX0ZBTFNFKGNhbGxlZF8pOworICAgICAgY2FsbGVkXyA9IHRydWU7CisgICAgICBtZXRob2RfID0gIkZvbyI7CisgICAgICBjb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7CisgICAgICByZXF1ZXN0XyA9IHJlcXVlc3Q7CisgICAgICByZXNwb25zZV8gPSByZXNwb25zZTsKKyAgICAgIGRvbmVfID0gZG9uZTsKKyAgICB9CisKKyAgICB2b2lkIEJhcihScGNDb250cm9sbGVyKiBjb250cm9sbGVyLAorICAgICAgICAgICAgIGNvbnN0IHVuaXR0ZXN0OjpCYXJSZXF1ZXN0KiByZXF1ZXN0LAorICAgICAgICAgICAgIHVuaXR0ZXN0OjpCYXJSZXNwb25zZSogcmVzcG9uc2UsCisgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgeworICAgICAgQVNTRVJUX0ZBTFNFKGNhbGxlZF8pOworICAgICAgY2FsbGVkXyA9IHRydWU7CisgICAgICBtZXRob2RfID0gIkJhciI7CisgICAgICBjb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7CisgICAgICByZXF1ZXN0XyA9IHJlcXVlc3Q7CisgICAgICByZXNwb25zZV8gPSByZXNwb25zZTsKKyAgICAgIGRvbmVfID0gZG9uZTsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIGJvb2wgY2FsbGVkXzsKKyAgICBzdHJpbmcgbWV0aG9kXzsKKyAgICBScGNDb250cm9sbGVyKiBjb250cm9sbGVyXzsKKyAgICBjb25zdCBNZXNzYWdlKiByZXF1ZXN0XzsKKyAgICBNZXNzYWdlKiByZXNwb25zZV87CisgICAgQ2xvc3VyZSogZG9uZV87CisgIH07CisKKyAgY2xhc3MgTW9ja1JwY0NoYW5uZWwgOiBwdWJsaWMgUnBjQ2hhbm5lbCB7CisgICBwdWJsaWM6CisgICAgTW9ja1JwY0NoYW5uZWwoKQorICAgICAgOiBjYWxsZWRfKGZhbHNlKSwKKyAgICAgICAgbWV0aG9kXyhOVUxMKSwKKyAgICAgICAgY29udHJvbGxlcl8oTlVMTCksCisgICAgICAgIHJlcXVlc3RfKE5VTEwpLAorICAgICAgICByZXNwb25zZV8oTlVMTCksCisgICAgICAgIGRvbmVfKE5VTEwpLAorICAgICAgICBkZXN0cm95ZWRfKE5VTEwpIHt9CisKKyAgICB+TW9ja1JwY0NoYW5uZWwoKSB7CisgICAgICBpZiAoZGVzdHJveWVkXyAhPSBOVUxMKSAqZGVzdHJveWVkXyA9IHRydWU7CisgICAgfQorCisgICAgdm9pZCBSZXNldCgpIHsgY2FsbGVkXyA9IGZhbHNlOyB9CisKKyAgICAvLyBpbXBsZW1lbnRzIFRlc3RTZXJ2aWNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHZvaWQgQ2FsbE1ldGhvZChjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgIFJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIHJlcXVlc3QsCisgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIHJlc3BvbnNlLAorICAgICAgICAgICAgICAgICAgICBDbG9zdXJlKiBkb25lKSB7CisgICAgICBBU1NFUlRfRkFMU0UoY2FsbGVkXyk7CisgICAgICBjYWxsZWRfID0gdHJ1ZTsKKyAgICAgIG1ldGhvZF8gPSBtZXRob2Q7CisgICAgICBjb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7CisgICAgICByZXF1ZXN0XyA9IHJlcXVlc3Q7CisgICAgICByZXNwb25zZV8gPSByZXNwb25zZTsKKyAgICAgIGRvbmVfID0gZG9uZTsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIGJvb2wgY2FsbGVkXzsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2RfOworICAgIFJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXJfOworICAgIGNvbnN0IE1lc3NhZ2UqIHJlcXVlc3RfOworICAgIE1lc3NhZ2UqIHJlc3BvbnNlXzsKKyAgICBDbG9zdXJlKiBkb25lXzsKKyAgICBib29sKiBkZXN0cm95ZWRfOworICB9OworCisgIGNsYXNzIE1vY2tDb250cm9sbGVyIDogcHVibGljIFJwY0NvbnRyb2xsZXIgeworICAgcHVibGljOgorICAgIHZvaWQgUmVzZXQoKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJSZXNldCgpIG5vdCBleHBlY3RlZCBkdXJpbmcgdGhpcyB0ZXN0LiI7CisgICAgfQorICAgIGJvb2wgRmFpbGVkKCkgY29uc3QgeworICAgICAgQUREX0ZBSUxVUkUoKSA8PCAiRmFpbGVkKCkgbm90IGV4cGVjdGVkIGR1cmluZyB0aGlzIHRlc3QuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgc3RyaW5nIEVycm9yVGV4dCgpIGNvbnN0IHsKKyAgICAgIEFERF9GQUlMVVJFKCkgPDwgIkVycm9yVGV4dCgpIG5vdCBleHBlY3RlZCBkdXJpbmcgdGhpcyB0ZXN0LiI7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorICAgIHZvaWQgU3RhcnRDYW5jZWwoKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJTdGFydENhbmNlbCgpIG5vdCBleHBlY3RlZCBkdXJpbmcgdGhpcyB0ZXN0LiI7CisgICAgfQorICAgIHZvaWQgU2V0RmFpbGVkKGNvbnN0IHN0cmluZyYgcmVhc29uKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJTZXRGYWlsZWQoKSBub3QgZXhwZWN0ZWQgZHVyaW5nIHRoaXMgdGVzdC4iOworICAgIH0KKyAgICBib29sIElzQ2FuY2VsZWQoKSBjb25zdCB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJJc0NhbmNlbGVkKCkgbm90IGV4cGVjdGVkIGR1cmluZyB0aGlzIHRlc3QuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgdm9pZCBOb3RpZnlPbkNhbmNlbChDbG9zdXJlKiBjYWxsYmFjaykgeworICAgICAgQUREX0ZBSUxVUkUoKSA8PCAiTm90aWZ5T25DYW5jZWwoKSBub3QgZXhwZWN0ZWQgZHVyaW5nIHRoaXMgdGVzdC4iOworICAgIH0KKyAgfTsKKworICBHZW5lcmF0ZWRTZXJ2aWNlVGVzdCgpCisgICAgOiBkZXNjcmlwdG9yXyh1bml0dGVzdDo6VGVzdFNlcnZpY2U6OmRlc2NyaXB0b3IoKSksCisgICAgICBmb29fKGRlc2NyaXB0b3JfLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKSksCisgICAgICBiYXJfKGRlc2NyaXB0b3JfLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXIiKSksCisgICAgICBzdHViXygmbW9ja19jaGFubmVsXyksCisgICAgICBkb25lXyhOZXdQZXJtYW5lbnRDYWxsYmFjaygmRG9Ob3RoaW5nKSkge30KKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgQVNTRVJUX1RSVUUoZm9vXyAhPSBOVUxMKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfICE9IE5VTEwpOworICB9CisKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBmb29fOworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBiYXJfOworCisgIE1vY2tUZXN0U2VydmljZSBtb2NrX3NlcnZpY2VfOworICBNb2NrQ29udHJvbGxlciBtb2NrX2NvbnRyb2xsZXJfOworCisgIE1vY2tScGNDaGFubmVsIG1vY2tfY2hhbm5lbF87CisgIHVuaXR0ZXN0OjpUZXN0U2VydmljZTo6U3R1YiBzdHViXzsKKworICAvLyBKdXN0IHNvIHdlIGRvbid0IGhhdmUgdG8gcmUtZGVmaW5lIHRoZXNlIHdpdGggZXZlcnkgdGVzdC4KKyAgdW5pdHRlc3Q6OkZvb1JlcXVlc3QgZm9vX3JlcXVlc3RfOworICB1bml0dGVzdDo6Rm9vUmVzcG9uc2UgZm9vX3Jlc3BvbnNlXzsKKyAgdW5pdHRlc3Q6OkJhclJlcXVlc3QgYmFyX3JlcXVlc3RfOworICB1bml0dGVzdDo6QmFyUmVzcG9uc2UgYmFyX3Jlc3BvbnNlXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxDbG9zdXJlPiBkb25lXzsKK307CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgR2V0RGVzY3JpcHRvcikgeworICAvLyBUZXN0IHRoYXQgR2V0RGVzY3JpcHRvcigpIHdvcmtzLgorCisgIEVYUEVDVF9FUShkZXNjcmlwdG9yXywgbW9ja19zZXJ2aWNlXy5HZXREZXNjcmlwdG9yKCkpOworfQorCitURVNUX0YoR2VuZXJhdGVkU2VydmljZVRlc3QsIEdldENoYW5uZWwpIHsKKyAgRVhQRUNUX0VRKCZtb2NrX2NoYW5uZWxfLCBzdHViXy5jaGFubmVsKCkpOworfQorCitURVNUX0YoR2VuZXJhdGVkU2VydmljZVRlc3QsIE93bnNDaGFubmVsKSB7CisgIE1vY2tScGNDaGFubmVsKiBjaGFubmVsID0gbmV3IE1vY2tScGNDaGFubmVsOworICBib29sIGRlc3Ryb3llZCA9IGZhbHNlOworICBjaGFubmVsLT5kZXN0cm95ZWRfID0gJmRlc3Ryb3llZDsKKworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RTZXJ2aWNlOjpTdHViIG93bmluZ19zdHViKGNoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZpY2U6OlNUVUJfT1dOU19DSEFOTkVMKTsKKyAgICBFWFBFQ1RfRkFMU0UoZGVzdHJveWVkKTsKKyAgfQorCisgIEVYUEVDVF9UUlVFKGRlc3Ryb3llZCk7Cit9CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgQ2FsbE1ldGhvZCkgeworICAvLyBUZXN0IHRoYXQgQ2FsbE1ldGhvZCgpIHdvcmtzLgorCisgIC8vIENhbGwgRm9vKCkgdmlhIENhbGxNZXRob2QoKS4KKyAgbW9ja19zZXJ2aWNlXy5DYWxsTWV0aG9kKGZvb18sICZtb2NrX2NvbnRyb2xsZXJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvb19yZXF1ZXN0XywgJmZvb19yZXNwb25zZV8sIGRvbmVfLmdldCgpKTsKKworICBBU1NFUlRfVFJVRShtb2NrX3NlcnZpY2VfLmNhbGxlZF8pOworCisgIEVYUEVDVF9FUSgiRm9vIiAgICAgICAgICAgICwgbW9ja19zZXJ2aWNlXy5tZXRob2RfICAgICk7CisgIEVYUEVDVF9FUSgmbW9ja19jb250cm9sbGVyXywgbW9ja19zZXJ2aWNlXy5jb250cm9sbGVyXyk7CisgIEVYUEVDVF9FUSgmZm9vX3JlcXVlc3RfICAgICwgbW9ja19zZXJ2aWNlXy5yZXF1ZXN0XyAgICk7CisgIEVYUEVDVF9FUSgmZm9vX3Jlc3BvbnNlXyAgICwgbW9ja19zZXJ2aWNlXy5yZXNwb25zZV8gICk7CisgIEVYUEVDVF9FUShkb25lXy5nZXQoKSAgICAgICwgbW9ja19zZXJ2aWNlXy5kb25lXyAgICAgICk7CisKKyAgLy8gVHJ5IGFnYWluLCBidXQgY2FsbCBCYXIoKSBpbnN0ZWFkLgorICBtb2NrX3NlcnZpY2VfLlJlc2V0KCk7CisgIG1vY2tfc2VydmljZV8uQ2FsbE1ldGhvZChiYXJfLCAmbW9ja19jb250cm9sbGVyXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICZiYXJfcmVxdWVzdF8sICZiYXJfcmVzcG9uc2VfLCBkb25lXy5nZXQoKSk7CisKKyAgQVNTRVJUX1RSVUUobW9ja19zZXJ2aWNlXy5jYWxsZWRfKTsKKyAgRVhQRUNUX0VRKCJCYXIiLCBtb2NrX3NlcnZpY2VfLm1ldGhvZF8pOworfQorCitURVNUX0YoR2VuZXJhdGVkU2VydmljZVRlc3QsIENhbGxNZXRob2RUeXBlRmFpbHVyZSkgeworICAvLyBWZXJpZnkgZGVhdGggaWYgd2UgY2FsbCBGb28oKSB3aXRoIEJhcidzIG1lc3NhZ2UgdHlwZXMuCisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVCAgLy8gZGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyB5ZXQKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKAorICAgIG1vY2tfc2VydmljZV8uQ2FsbE1ldGhvZChmb29fLCAmbW9ja19jb250cm9sbGVyXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvb19yZXF1ZXN0XywgJmJhcl9yZXNwb25zZV8sIGRvbmVfLmdldCgpKSwKKyAgICAiZHluYW1pY19jYXN0Iik7CisKKyAgbW9ja19zZXJ2aWNlXy5SZXNldCgpOworICBFWFBFQ1RfREVCVUdfREVBVEgoCisgICAgbW9ja19zZXJ2aWNlXy5DYWxsTWV0aG9kKGZvb18sICZtb2NrX2NvbnRyb2xsZXJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYmFyX3JlcXVlc3RfLCAmZm9vX3Jlc3BvbnNlXywgZG9uZV8uZ2V0KCkpLAorICAgICJkeW5hbWljX2Nhc3QiKTsKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK30KKworVEVTVF9GKEdlbmVyYXRlZFNlcnZpY2VUZXN0LCBHZXRQcm90b3R5cGVzKSB7CisgIC8vIFRlc3QgR2V0e1JlcXVlc3QsUmVzcG9uc2V9UHJvdG90eXBlKCkgbWV0aG9kcy4KKworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpGb29SZXF1ZXN0OjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbW9ja19zZXJ2aWNlXy5HZXRSZXF1ZXN0UHJvdG90eXBlKGZvb18pKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6QmFyUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1vY2tfc2VydmljZV8uR2V0UmVxdWVzdFByb3RvdHlwZShiYXJfKSk7CisKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6Rm9vUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtb2NrX3NlcnZpY2VfLkdldFJlc3BvbnNlUHJvdG90eXBlKGZvb18pKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6QmFyUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtb2NrX3NlcnZpY2VfLkdldFJlc3BvbnNlUHJvdG90eXBlKGJhcl8pKTsKK30KKworVEVTVF9GKEdlbmVyYXRlZFNlcnZpY2VUZXN0LCBTdHViKSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgc3R1YiBjbGFzcyB3b3Jrcy4KKworICAvLyBDYWxsIEZvbygpIHZpYSB0aGUgc3R1Yi4KKyAgc3R1Yl8uRm9vKCZtb2NrX2NvbnRyb2xsZXJfLCAmZm9vX3JlcXVlc3RfLCAmZm9vX3Jlc3BvbnNlXywgZG9uZV8uZ2V0KCkpOworCisgIEFTU0VSVF9UUlVFKG1vY2tfY2hhbm5lbF8uY2FsbGVkXyk7CisKKyAgRVhQRUNUX0VRKGZvb18gICAgICAgICAgICAgLCBtb2NrX2NoYW5uZWxfLm1ldGhvZF8gICAgKTsKKyAgRVhQRUNUX0VRKCZtb2NrX2NvbnRyb2xsZXJfLCBtb2NrX2NoYW5uZWxfLmNvbnRyb2xsZXJfKTsKKyAgRVhQRUNUX0VRKCZmb29fcmVxdWVzdF8gICAgLCBtb2NrX2NoYW5uZWxfLnJlcXVlc3RfICAgKTsKKyAgRVhQRUNUX0VRKCZmb29fcmVzcG9uc2VfICAgLCBtb2NrX2NoYW5uZWxfLnJlc3BvbnNlXyAgKTsKKyAgRVhQRUNUX0VRKGRvbmVfLmdldCgpICAgICAgLCBtb2NrX2NoYW5uZWxfLmRvbmVfICAgICAgKTsKKworICAvLyBDYWxsIEJhcigpIHZpYSB0aGUgc3R1Yi4KKyAgbW9ja19jaGFubmVsXy5SZXNldCgpOworICBzdHViXy5CYXIoJm1vY2tfY29udHJvbGxlcl8sICZiYXJfcmVxdWVzdF8sICZiYXJfcmVzcG9uc2VfLCBkb25lXy5nZXQoKSk7CisKKyAgQVNTRVJUX1RSVUUobW9ja19jaGFubmVsXy5jYWxsZWRfKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1vY2tfY2hhbm5lbF8ubWV0aG9kXyk7Cit9CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgTm90SW1wbGVtZW50ZWQpIHsKKyAgLy8gVGVzdCB0aGF0IGZhaWxpbmcgdG8gaW1wbGVtZW50IGEgbWV0aG9kIG9mIGEgc2VydmljZSBjYXVzZXMgaXQgdG8gZmFpbAorICAvLyB3aXRoIGEgIm5vdCBpbXBsZW1lbnRlZCIgZXJyb3IgbWVzc2FnZS4KKworICAvLyBBIHNlcnZpY2Ugd2hpY2ggZG9lc24ndCBpbXBsZW1lbnQgYW55IG1ldGhvZHMuCisgIGNsYXNzIFVuaW1wbGVtZW50ZWRTZXJ2aWNlIDogcHVibGljIHVuaXR0ZXN0OjpUZXN0U2VydmljZSB7CisgICBwdWJsaWM6CisgICAgVW5pbXBsZW1lbnRlZFNlcnZpY2UoKSB7fQorICB9OworCisgIFVuaW1wbGVtZW50ZWRTZXJ2aWNlIHVuaW1wbGVtZW50ZWRfc2VydmljZTsKKworICAvLyBBbmQgYSBjb250cm9sbGVyIHdoaWNoIGV4cGVjdHMgdG8gZ2V0IGEgIm5vdCBpbXBsZW1lbnRlZCIgZXJyb3IuCisgIGNsYXNzIEV4cGVjdFVuaW1wbGVtZW50ZWRDb250cm9sbGVyIDogcHVibGljIE1vY2tDb250cm9sbGVyIHsKKyAgIHB1YmxpYzoKKyAgICBFeHBlY3RVbmltcGxlbWVudGVkQ29udHJvbGxlcigpIDogY2FsbGVkXyhmYWxzZSkge30KKworICAgIHZvaWQgU2V0RmFpbGVkKGNvbnN0IHN0cmluZyYgcmVhc29uKSB7CisgICAgICBFWFBFQ1RfRkFMU0UoY2FsbGVkXyk7CisgICAgICBjYWxsZWRfID0gdHJ1ZTsKKyAgICAgIEVYUEVDVF9FUSgiTWV0aG9kIEZvbygpIG5vdCBpbXBsZW1lbnRlZC4iLCByZWFzb24pOworICAgIH0KKworICAgIGJvb2wgY2FsbGVkXzsKKyAgfTsKKworICBFeHBlY3RVbmltcGxlbWVudGVkQ29udHJvbGxlciBjb250cm9sbGVyOworCisgIC8vIENhbGwgRm9vLgorICB1bmltcGxlbWVudGVkX3NlcnZpY2UuRm9vKCZjb250cm9sbGVyLCAmZm9vX3JlcXVlc3RfLCAmZm9vX3Jlc3BvbnNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lXy5nZXQoKSk7CisKKyAgRVhQRUNUX1RSVUUoY29udHJvbGxlci5jYWxsZWRfKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBPbmVvZlRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgIH0KKworICB2b2lkIEV4cGVjdEVudW1DYXNlc1dvcmsoY29uc3QgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgJm1lc3NhZ2UpIHsKKyAgICBzd2l0Y2ggKG1lc3NhZ2UuZm9vX2Nhc2UoKSkgeworICAgICAgY2FzZSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6a0Zvb0ludDoKKyAgICAgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX2ludCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjprRm9vU3RyaW5nOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OmtGb29CeXRlczoKKyAgICAgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX2J5dGVzKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OmtGb29FbnVtOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fZW51bSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjprRm9vTWVzc2FnZToKKyAgICAgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6a0Zvb2dyb3VwOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29ncm91cCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT09fTk9UX1NFVDoKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9OworCitURVNUX0YoT25lb2ZUZXN0LCBTZXR0aW5nT25lRmllbGRDbGVhcnNPdGhlcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBtZXNzYWdlLnNldF9mb29faW50KDEyMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZygiZm9vIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKworICBtZXNzYWdlLnNldF9mb29fYnl0ZXMoInF1eCIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fYnl0ZXMoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKyAgbWVzc2FnZS5zZXRfZm9vX2VudW0odW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpOworICBUZXN0VXRpbDo6RXhwZWN0QXRNb3N0T25lRmllbGRTZXRJbk9uZW9mKG1lc3NhZ2UpOworCisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgyMzQpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlKTsKKworICBtZXNzYWdlLm11dGFibGVfZm9vZ3JvdXAoKS0+c2V0X2EoMzQ1KTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vZ3JvdXAoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKworICAvLyB3ZSByZXBlYXQgdGhpcyBiZWNhdXNlIHdlIGRpZG4ndCB0ZXN0IGlmIHRoaXMgcHJvcGVybHkgY2xlYXJzIG90aGVyIGZpZWxkcworICAvLyBhdCB0aGUgYmVnaW5uaW5nLgorICBtZXNzYWdlLnNldF9mb29faW50KDEyMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIEVudW1DYXNlcykgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19pbnQoMTIzKTsKKyAgRXhwZWN0RW51bUNhc2VzV29yayhtZXNzYWdlKTsKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZygiZm9vIik7CisgIEV4cGVjdEVudW1DYXNlc1dvcmsobWVzc2FnZSk7CisgIG1lc3NhZ2Uuc2V0X2Zvb19ieXRlcygicXV4Iik7CisgIEV4cGVjdEVudW1DYXNlc1dvcmsobWVzc2FnZSk7CisgIG1lc3NhZ2Uuc2V0X2Zvb19lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworICBFeHBlY3RFbnVtQ2FzZXNXb3JrKG1lc3NhZ2UpOworICBtZXNzYWdlLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMjM0KTsKKyAgRXhwZWN0RW51bUNhc2VzV29yayhtZXNzYWdlKTsKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb2dyb3VwKCktPnNldF9hKDM0NSk7CisgIEV4cGVjdEVudW1DYXNlc1dvcmsobWVzc2FnZSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIFByaW1pdGl2ZVR5cGUpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgLy8gVW5zZXQgZmllbGQgcmV0dXJucyBkZWZhdWx0IHZhbHVlCisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19pbnQoKSwgMCk7CisKKyAgbWVzc2FnZS5zZXRfZm9vX2ludCgxMjMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29faW50KCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29faW50KCksIDEyMyk7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX2ludCgpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2ludCgpKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgRW51bVR5cGUpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgLy8gVW5zZXQgZmllbGQgcmV0dXJucyBkZWZhdWx0IHZhbHVlCisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19lbnVtKCksIDEpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fZW51bSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX2VudW0oKSwgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTyk7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX2VudW0oKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBTZXRTdHJpbmcpIHsKKyAgLy8gQ2hlY2sgdGhhdCBzZXR0aW5nIGEgc3RyaW5nIGZpZWxkIGluIHZhcmlvdXMgd2F5cyB3b3JrcworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIC8vIFVuc2V0IGZpZWxkIHJldHVybnMgZGVmYXVsdCB2YWx1ZQorICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fc3RyaW5nKCksICIiKTsKKworICBtZXNzYWdlLnNldF9mb29fc3RyaW5nKCJmb28iKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX3N0cmluZygpLCAiZm9vIik7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX3N0cmluZygpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKworICBtZXNzYWdlLnNldF9mb29fc3RyaW5nKHN0cmluZygiYmFyIikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fc3RyaW5nKCksICJiYXIiKTsKKyAgbWVzc2FnZS5jbGVhcl9mb29fc3RyaW5nKCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZygicXV4IiwgMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgInF1eCIpOworICBtZXNzYWdlLmNsZWFyX2Zvb19zdHJpbmcoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb19zdHJpbmcoKS0+YXNzaWduKCJxdXV4Iik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgInF1dXgiKTsKKyAgbWVzc2FnZS5jbGVhcl9mb29fc3RyaW5nKCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19zdHJpbmcoImNvcmdlIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgImNvcmdlIik7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX3N0cmluZygpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgUmVsZWFzZVN0cmluZykgeworICAvLyBDaGVjayB0aGF0IHJlbGVhc2VfZm9vKCkgc3RhcnRzIG91dCBOVUxMLCBhbmQgZ2l2ZXMgdXMgYSB2YWx1ZQorICAvLyB0aGF0IHdlIGNhbiBkZWxldGUgYWZ0ZXIgaXQncyBiZWVuIHNldC4KKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBFWFBFQ1RfRVEoTlVMTCwgbWVzc2FnZS5yZWxlYXNlX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19zdHJpbmcoImJsYWgiKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxzdHJpbmc+IHN0cihtZXNzYWdlLnJlbGVhc2VfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEFTU0VSVF9UUlVFKHN0ciAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJibGFoIiwgKnN0cik7CisKKyAgRVhQRUNUX0VRKE5VTEwsIG1lc3NhZ2UucmVsZWFzZV9mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgU2V0QWxsb2NhdGVkU3RyaW5nKSB7CisgIC8vIENoZWNrIHRoYXQgc2V0X2FsbG9jYXRlZF9mb28oKSB3b3JrcyBmb3Igc3RyaW5ncy4KKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgY29uc3Qgc3RyaW5nIGtIZWxsbygiaGVsbG8iKTsKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZyhrSGVsbG8pOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2FsbG9jYXRlZF9mb29fc3RyaW5nKE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLmZvb19zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX2Zvb19zdHJpbmcobmV3IHN0cmluZyhrSGVsbG8pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKGtIZWxsbywgbWVzc2FnZS5mb29fc3RyaW5nKCkpOworfQorCisKK1RFU1RfRihPbmVvZlRlc3QsIFNldE1lc3NhZ2UpIHsKKyAgLy8gQ2hlY2sgdGhhdCBzZXR0aW5nIGEgbWVzc2FnZSBmaWVsZCB3b3JrcworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIC8vIFVuc2V0IGZpZWxkIHJldHVybnMgZGVmYXVsdCBpbnN0YW5jZQorICBFWFBFQ1RfRVEoJm1lc3NhZ2UuZm9vX21lc3NhZ2UoKSwKKyAgICAgICAgICAgICZ1bml0dGVzdDo6VGVzdE9uZW9mMl9OZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMCk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb19tZXNzYWdlKCktPnNldF9xdXhfaW50KDIzNCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMjM0KTsKKyAgbWVzc2FnZS5jbGVhcl9mb29fbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIFJlbGVhc2VNZXNzYWdlKSB7CisgIC8vIENoZWNrIHRoYXQgcmVsZWFzZV9mb28oKSBzdGFydHMgb3V0IE5VTEwsIGFuZCBnaXZlcyB1cyBhIHZhbHVlCisgIC8vIHRoYXQgd2UgY2FuIGRlbGV0ZSBhZnRlciBpdCdzIGJlZW4gc2V0LgorICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIEVYUEVDVF9FUShOVUxMLCBtZXNzYWdlLnJlbGVhc2VfZm9vX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPHVuaXR0ZXN0OjpUZXN0T25lb2YyX05lc3RlZE1lc3NhZ2U+IG1lcygKKyAgICAgIG1lc3NhZ2UucmVsZWFzZV9mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBBU1NFUlRfVFJVRShtZXMgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgxLCBtZXMtPnF1eF9pbnQoKSk7CisKKyAgRVhQRUNUX0VRKE5VTEwsIG1lc3NhZ2UucmVsZWFzZV9mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBTZXRBbGxvY2F0ZWRNZXNzYWdlKSB7CisgIC8vIENoZWNrIHRoYXQgc2V0X2FsbG9jYXRlZF9mb28oKSB3b3JrcyBmb3IgbWVzc2FnZXMuCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgxKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX2Zvb19tZXNzYWdlKE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgmbWVzc2FnZS5mb29fbWVzc2FnZSgpLAorICAgICAgICAgICAgJnVuaXR0ZXN0OjpUZXN0T25lb2YyX05lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb19tZXNzYWdlKCktPnNldF9xdXhfaW50KDEpOworICB1bml0dGVzdDo6VGVzdE9uZW9mMl9OZXN0ZWRNZXNzYWdlKiBtZXMgPSBtZXNzYWdlLnJlbGVhc2VfZm9vX21lc3NhZ2UoKTsKKyAgQVNTRVJUX1RSVUUobWVzICE9IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX2Zvb19tZXNzYWdlKG1lcyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSk7Cit9CisKKworVEVTVF9GKE9uZW9mVGVzdCwgQ2xlYXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBtZXNzYWdlLnNldF9mb29faW50KDEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29faW50KCkpOworICBtZXNzYWdlLmNsZWFyX2Zvb19pbnQoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIERlZmF1bHRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19pbnQoKSwgMCk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgIiIpOworCisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19ieXRlcygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX2J5dGVzKCksICIiKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19lbnVtKCksIDEpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX21lc3NhZ2UoKS5xdXhfaW50KCksIDApOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29ncm91cCgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vZ3JvdXAoKS5hKCksIDApOworCisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9pbnQoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmJhcl9pbnQoKSwgNSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmJhcl9zdHJpbmcoKSwgIlNUUklORyIpOworCisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9ieXRlcygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuYmFyX2J5dGVzKCksICJCWVRFUyIpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iYXJfZW51bSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuYmFyX2VudW0oKSwgMik7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIFN3YXBXaXRoRW1wdHkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBtZXNzYWdlMS5zZXRfZm9vX3N0cmluZygiRk9PIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UxLmhhc19mb29fc3RyaW5nKCkpOworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fc3RyaW5nKCksICJGT08iKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgU3dhcFdpdGhTZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X2Zvb19zdHJpbmcoIkZPTyIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBtZXNzYWdlLlN3YXAoJm1lc3NhZ2UpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fc3RyaW5nKCksICJGT08iKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgU3dhcEJvdGhIYXNGaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIG1lc3NhZ2UxLnNldF9mb29fc3RyaW5nKCJGT08iKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTEuaGFzX2Zvb19zdHJpbmcoKSk7CisgIG1lc3NhZ2UyLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fbWVzc2FnZSgpKTsKKworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UyLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTEuaGFzX2Zvb19tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTEuZm9vX21lc3NhZ2UoKS5xdXhfaW50KCksIDEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19zdHJpbmcoKSwgIkZPTyIpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBDb3B5Q29uc3RydWN0b3IpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTE7CisgIG1lc3NhZ2UxLnNldF9mb29fYnl0ZXMoIkZPTyIpOworCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UyKG1lc3NhZ2UxKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuaGFzX2Zvb19ieXRlcygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19ieXRlcygpLCAiRk9PIik7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIENvcHlGcm9tKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEuc2V0X2Zvb19lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpCQVIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5oYXNfZm9vX2VudW0oKSk7CisKKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fZW51bSgpLCB1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFSKTsKKworICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fZW51bSgpLCB1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFSKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgQ29weUFzc2lnbm1lbnRPcGVyYXRvcikgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMTsKKyAgbWVzc2FnZTEubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgxMjMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5oYXNfZm9vX21lc3NhZ2UoKSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTI7CisgIG1lc3NhZ2UyID0gbWVzc2FnZTE7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMTIzKTsKKworICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxmLWFzc2lnbm1lbnQgZG9lcyBzb21ldGhpbmcgc2FuZS4KKyAgbWVzc2FnZTIgPSBtZXNzYWdlMjsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19tZXNzYWdlKCkucXV4X2ludCgpLCAxMjMpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBVcGNhc3RDb3B5RnJvbSkgeworICAvLyBUZXN0IHRoZSBDb3B5RnJvbSBtZXRob2QgdGhhdCB0YWtlcyBpbiB0aGUgZ2VuZXJpYyBjb25zdCBNZXNzYWdlJgorICAvLyBwYXJhbWV0ZXIuCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEubXV0YWJsZV9mb29ncm91cCgpLT5zZXRfYSgxMjMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5oYXNfZm9vZ3JvdXAoKSk7CisKKyAgY29uc3QgTWVzc2FnZSogc291cmNlID0gaW1wbGljaXRfY2FzdDxjb25zdCBNZXNzYWdlKj4oJm1lc3NhZ2UxKTsKKyAgbWVzc2FnZTIuQ29weUZyb20oKnNvdXJjZSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuaGFzX2Zvb2dyb3VwKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vZ3JvdXAoKS5hKCksIDEyMyk7Cit9CisKKy8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KCksCisvLyBUaGlzIGluZGlyZWN0bHkgdGVzdHMgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKCkKKy8vIFdlIGhhdmUgdG8gdGVzdCBlYWNoIGZpZWxkIHR5cGUgc2VwYXJhdGVseSBiZWNhdXNlIHdlIGNhbm5vdCBzZXQgdGhlbSBhdCB0aGUKKy8vIHNhbWUgdGltZQorVEVTVF9GKE9uZW9mVGVzdCwgU2VyaWFsaXphdGlvblRvQXJyYXkpIHsKKyAgLy8gUHJpbWl0aXZlIHR5cGUKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5zZXRfZm9vX2ludCgxMjMpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgICB1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgICAgdWludDgqIGVuZCA9IG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoc3RhcnQpOworICAgIEVYUEVDVF9FUShzaXplLCBlbmQgLSBzdGFydCk7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX2ludCgpLCAxMjMpOworICB9CisKKyAgLy8gU3RyaW5nCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEuc2V0X2Zvb19zdHJpbmcoImZvbyIpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgICB1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgICAgdWludDgqIGVuZCA9IG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoc3RhcnQpOworICAgIEVYUEVDVF9FUShzaXplLCBlbmQgLSBzdGFydCk7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX3N0cmluZygpLCAiZm9vIik7CisgIH0KKworCisgIC8vIEJ5dGVzCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEuc2V0X2Zvb19ieXRlcygicXV4Iik7CisgICAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICAgIGRhdGEucmVzaXplKHNpemUpOworICAgIHVpbnQ4KiBzdGFydCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgICB1aW50OCogZW5kID0gbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgICAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHN0YXJ0KTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fYnl0ZXMoKSwgInF1eCIpOworICB9CisKKyAgLy8gRW51bQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLnNldF9mb29fZW51bSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PKTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisgICAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZGF0YSkpOworICAgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gc3RhcnQpOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19lbnVtKCksIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworICB9CisKKyAgLy8gTWVzc2FnZQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMjM0KTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisgICAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZGF0YSkpOworICAgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gc3RhcnQpOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19tZXNzYWdlKCkucXV4X2ludCgpLCAyMzQpOworICB9CisKKyAgLy8gR3JvdXAKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5tdXRhYmxlX2Zvb2dyb3VwKCktPnNldF9hKDM0NSk7CisgICAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICAgIGRhdGEucmVzaXplKHNpemUpOworICAgIHVpbnQ4KiBzdGFydCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgICB1aW50OCogZW5kID0gbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgICAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHN0YXJ0KTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29ncm91cCgpLmEoKSwgMzQ1KTsKKyAgfQorCit9CisKKy8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSBieSBmb3JjaW5nIHRoZSBidWZmZXIgdG8gd3JpdGUKKy8vIG9uZSBieXRlIGF0IGEgdGltZS4KKy8vIFRoaXMgaW5kaXJlY3RseSB0ZXN0cyBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oKQorLy8gV2UgaGF2ZSB0byB0ZXN0IGVhY2ggZmllbGQgdHlwZSBzZXBhcmF0ZWx5IGJlY2F1c2Ugd2UgY2Fubm90IHNldCB0aGVtIGF0IHRoZQorLy8gc2FtZSB0aW1lCitURVNUX0YoT25lb2ZUZXN0LCBTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgLy8gUHJpbWl0aXZlIHR5cGUKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5zZXRfZm9vX2ludCgxMjMpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29faW50KCksIDEyMyk7CisgIH0KKworICAvLyBTdHJpbmcKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5zZXRfZm9vX3N0cmluZygiZm9vIik7CisgICAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICAgIGRhdGEucmVzaXplKHNpemUpOworCisgICAgeworICAgICAgLy8gQWxsb3cgdGhlIG91dHB1dCBzdHJlYW0gdG8gYnVmZmVyIG9ubHkgb25lIGJ5dGUgYXQgYSB0aW1lLgorICAgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZhcnJheV9zdHJlYW0pOworICAgICAgbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgIEVYUEVDVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICAgICAgRVhQRUNUX0VRKHNpemUsIG91dHB1dF9zdHJlYW0uQnl0ZUNvdW50KCkpOworICAgIH0KKworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19zdHJpbmcoKSwgImZvbyIpOworICB9CisKKworICAvLyBCeXRlcworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLnNldF9mb29fYnl0ZXMoInF1eCIpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fYnl0ZXMoKSwgInF1eCIpOworICB9CisKKyAgLy8gRW51bQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLnNldF9mb29fZW51bSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PKTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisKKyAgICB7CisgICAgICAvLyBBbGxvdyB0aGUgb3V0cHV0IHN0cmVhbSB0byBidWZmZXIgb25seSBvbmUgYnl0ZSBhdCBhIHRpbWUuCisgICAgICBpbzo6QXJyYXlPdXRwdXRTdHJlYW0gYXJyYXlfc3RyZWFtKHN0cmluZ19hc19hcnJheSgmZGF0YSksIHNpemUsIDEpOworICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgICBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgICAgRVhQRUNUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgICAgICBFWFBFQ1RfRVEoc2l6ZSwgb3V0cHV0X3N0cmVhbS5CeXRlQ291bnQoKSk7CisgICAgfQorCisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX2VudW0oKSwgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTyk7CisgIH0KKworICAvLyBNZXNzYWdlCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgyMzQpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMjM0KTsKKyAgfQorCisgIC8vIEdyb3VwCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEubXV0YWJsZV9mb29ncm91cCgpLT5zZXRfYSgzNDUpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29ncm91cCgpLmEoKSwgMzQ1KTsKKyAgfQorCit9CisKK1RFU1RfRihPbmVvZlRlc3QsIE1lcmdlRnJvbSkgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgbWVzc2FnZTEuc2V0X2Zvb19pbnQoMTIzKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29faW50KCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX2ludCgpLCAxMjMpOworCisgIG1lc3NhZ2UxLnNldF9mb29fc3RyaW5nKCJmb28iKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX3N0cmluZygpLCAiZm9vIik7CisKKworICBtZXNzYWdlMS5zZXRfZm9vX2J5dGVzKCJxdXgiKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fYnl0ZXMoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fYnl0ZXMoKSwgInF1eCIpOworCisgIG1lc3NhZ2UxLnNldF9mb29fZW51bSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fZW51bSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19lbnVtKCksIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworCisgIG1lc3NhZ2UxLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMjM0KTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19tZXNzYWdlKCkucXV4X2ludCgpLCAyMzQpOworCisgIG1lc3NhZ2UxLm11dGFibGVfZm9vZ3JvdXAoKS0+c2V0X2EoMzQ1KTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29ncm91cCgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb2dyb3VwKCkuYSgpLCAzNDUpOworCit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHBfdW5pdHRlc3QKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorCituYW1lc3BhY2Ugbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0IHsKKyAgLy8gVmVyaWZ5IHRoYXQgbm8gY2xhc3MgY2FsbGVkICJUZXN0U2VydmljZSIgd2FzIGRlZmluZWQgaW4KKyAgLy8gdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5oIGJ5IGRlZmluaW5nIGEgZGlmZmVyZW50IHR5cGUgYnkgdGhlIHNhbWUKKyAgLy8gbmFtZS4gIElmIHN1Y2ggYSBzZXJ2aWNlIHdhcyBnZW5lcmF0ZWQsIHRoaXMgd2lsbCBub3QgY29tcGlsZS4KKyAgc3RydWN0IFRlc3RTZXJ2aWNlIHsKKyAgICBpbnQgaTsKKyAgfTsKK30KKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworbmFtZXNwYWNlIGNwcF91bml0dGVzdCB7CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgTm9HZW5lcmljU2VydmljZXMpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgbm9uLXNlcnZpY2VzIGluIHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucHJvdG8gd2VyZQorICAvLyBnZW5lcmF0ZWQuCisgIG5vX2dlbmVyaWNfc2VydmljZXNfdGVzdDo6VGVzdE1lc3NhZ2UgbWVzc2FnZTsKKyAgbWVzc2FnZS5zZXRfYSgxKTsKKyAgbWVzc2FnZS5TZXRFeHRlbnNpb24obm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0Ojp0ZXN0X2V4dGVuc2lvbiwgMTIzKTsKKyAgbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0OjpUZXN0RW51bSBlID0gbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0OjpGT087CisgIEVYUEVDVF9FUShlLCAxKTsKKworICAvLyBWZXJpZnkgdGhhdCBhIFNlcnZpY2VEZXNjcmlwdG9yIGlzIGdlbmVyYXRlZCBmb3IgdGhlIHNlcnZpY2UgZXZlbiBpZiB0aGUKKyAgLy8gY2xhc3MgaXRzZWxmIGlzIG5vdC4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPQorICAgICAgbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0OjpUZXN0TWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisKKyAgQVNTRVJUX0VRKDEsIGZpbGUtPnNlcnZpY2VfY291bnQoKSk7CisgIEVYUEVDVF9FUSgiVGVzdFNlcnZpY2UiLCBmaWxlLT5zZXJ2aWNlKDApLT5uYW1lKCkpOworICBBU1NFUlRfRVEoMSwgZmlsZS0+c2VydmljZSgwKS0+bWV0aG9kX2NvdW50KCkpOworICBFWFBFQ1RfRVEoIkZvbyIsIGZpbGUtPnNlcnZpY2UoMCktPm1ldGhvZCgwKS0+bmFtZSgpKTsKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRoaXMgdGVzdCBtdXN0IHJ1biBsYXN0LiAgSXQgdmVyaWZpZXMgdGhhdCBkZXNjcmlwdG9ycyB3ZXJlIG9yIHdlcmUgbm90CisvLyBpbml0aWFsaXplZCBkZXBlbmRpbmcgb24gd2hldGhlciBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTIHdhcyBkZWZpbmVkLgorLy8gV2hlbiB0aGlzIGlzIGRlZmluZWQsIHdlIHNraXAgYWxsIHRlc3RzIHdoaWNoIGFyZSBleHBlY3RlZCB0byB0cmlnZ2VyCisvLyBkZXNjcmlwdG9yIGluaXRpYWxpemF0aW9uLiAgVGhpcyB2ZXJpZmllcyB0aGF0IGV2ZXJ5dGhpbmcgZWxzZSBzdGlsbCB3b3JrcworLy8gaWYgZGVzY3JpcHRvcnMgYXJlIG5vdCBpbml0aWFsaXplZC4KK1RFU1QoRGVzY3JpcHRvckluaXRpYWxpemF0aW9uVGVzdCwgSW5pdGlhbGl6ZWQpIHsKKyNpZmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIGJvb2wgc2hvdWxkX2hhdmVfZGVzY3JpcHRvcnMgPSBmYWxzZTsKKyNlbHNlCisgIGJvb2wgc2hvdWxkX2hhdmVfZGVzY3JpcHRvcnMgPSB0cnVlOworI2VuZGlmCisKKyAgRVhQRUNUX0VRKHNob3VsZF9oYXZlX2Rlc2NyaXB0b3JzLAorICAgIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLT5JbnRlcm5hbElzRmlsZUxvYWRlZCgKKyAgICAgICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHBfdW5pdHRlc3QKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjljOGY0NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5oCkBAIC0wLDAgKzEsNTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGhlYWRlciBkZWNsYXJlcyB0aGUgbmFtZXNwYWNlIGdvb2dsZTo6cHJvdG9idWY6OnByb3RvYnVmX3VuaXR0ZXN0IGluIG9yZGVyIHRvIGV4cG9zZQorLy8gYW55IHByb2JsZW1zIHdpdGggdGhlIGdlbmVyYXRlZCBjbGFzcyBuYW1lcy4gV2UgdXNlIHRoaXMgaGVhZGVyIHRvIGVuc3VyZQorLy8gdW5pdHRlc3QuY2Mgd2lsbCBkZWNsYXJlIHRoZSBuYW1lc3BhY2UgcHJpb3IgdG8gb3RoZXIgaW5jbHVkZXMsIHdoaWxlIG9iZXlpbmcKKy8vIG5vcm1hbCBpbmNsdWRlIG9yZGVyaW5nLgorLy8KKy8vIFdoZW4gZ2VuZXJhdGluZyBhIGNsYXNzIG5hbWUgb2YgImZvby5CYXIiIHdlIG11c3QgZW5zdXJlIHdlIHByZWZpeCB0aGUgY2xhc3MKKy8vIG5hbWUgd2l0aCAiOjoiLCBpbiBjYXNlIHRoZSBuYW1lc3BhY2UgZ29vZ2xlOjpwcm90b2J1Zjo6Zm9vIGV4aXN0cy4gV2UgaW50ZW50aW9uYWxseQorLy8gdHJpZ2dlciB0aGF0IGNhc2UgaGVyZSBieSBkZWNsYXJpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6cHJvdG9idWZfdW5pdHRlc3QuCisvLworLy8gU2VlIENsYXNzTmFtZSBpbiBoZWxwZXJzLmggZm9yIG1vcmUgZGV0YWlscy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1VOSVRURVNUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1VOSVRURVNUX0hfXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHJvdG9idWZfdW5pdHRlc3Qge30KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfVU5JVFRFU1RfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC90ZXN0X2xhcmdlX2VudW1fdmFsdWUucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC90ZXN0X2xhcmdlX2VudW1fdmFsdWUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2I2Y2ExYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL3Rlc3RfbGFyZ2VfZW51bV92YWx1ZS5wcm90bwpAQCAtMCwwICsxLDQzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGVzdCB0aGF0IHByb3RvMiBjb21waWxlciBjYW4gZ2VuZXJhdGUgdmFsaWQgY29kZSB3aGVuIHRoZSBlbnVtIHZhbHVlCisvLyBpcyBJTlRfTUFYLiBOb3RlIHRoYXQgdGhpcyBpcyBhIGNvbXBpbGUtb25seSB0ZXN0IGFuZCB0aGlzIHByb3RvIGlzIG5vdAorLy8gcmVmZXJlbmNlZCBpbiBhbnkgQysrIGNvZGUuCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworbWVzc2FnZSBUZXN0TGFyZ2VFbnVtVmFsdWUgeworICBlbnVtIEVudW1XaXRoTGFyZ2VWYWx1ZSB7CisgICAgVkFMVUVfMSA9IDE7CisgICAgVkFMVUVfTUFYID0gMHg3ZmZmZmZmZjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODMzMzY4NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuY2MKQEAgLTAsMCArMSw0ODMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8aW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dW5pc3RkLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKKyNpZmRlZiBfV0lOMzIKKyNpZm5kZWYgRl9PSworI2RlZmluZSBGX09LIDAwICAvLyBub3QgZGVmaW5lZCBieSBNU1ZDIGZvciB3aGF0ZXZlciByZWFzb24KKyNlbmRpZgorI2luY2x1ZGUgPGN0eXBlLmg+CisjZW5kaWYKKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSB0ZXh0IGxvb2tzIGxpa2UgYSBXaW5kb3dzLXN0eWxlIGFic29sdXRlIHBhdGgsIHN0YXJ0aW5nCisvLyB3aXRoIGEgZHJpdmUgbGV0dGVyLiAgRXhhbXBsZTogICJDOlxmb28iLiAgVE9ETyhrZW50b24pOiAgU2hhcmUgdGhpcyB3aXRoCisvLyBjb3B5IGluIGNvbW1hbmRfbGluZV9pbnRlcmZhY2UuY2M/CitzdGF0aWMgYm9vbCBJc1dpbmRvd3NBYnNvbHV0ZVBhdGgoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisjaWYgZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX19DWUdXSU5fXykKKyAgcmV0dXJuIHRleHQuc2l6ZSgpID49IDMgJiYgdGV4dFsxXSA9PSAnOicgJiYKKyAgICAgICAgIGlzYWxwaGEodGV4dFswXSkgJiYKKyAgICAgICAgICh0ZXh0WzJdID09ICcvJyB8fCB0ZXh0WzJdID09ICdcXCcpICYmCisgICAgICAgICB0ZXh0LmZpbmRfbGFzdF9vZignOicpID09IDE7CisjZWxzZQorICByZXR1cm4gZmFsc2U7CisjZW5kaWYKK30KKworTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3I6On5NdWx0aUZpbGVFcnJvckNvbGxlY3RvcigpIHt9CisKKy8vIFRoaXMgY2xhc3Mgc2VydmVzIHR3byBwdXJwb3NlczoKKy8vIC0gSXQgaW1wbGVtZW50cyB0aGUgRXJyb3JDb2xsZWN0b3IgaW50ZXJmYWNlICh1c2VkIGJ5IFRva2VuaXplciBhbmQgUGFyc2VyKQorLy8gICBpbiB0ZXJtcyBvZiBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciwgdXNpbmcgYSBwYXJ0aWN1bGFyIGZpbGVuYW1lLgorLy8gLSBJdCBsZXRzIHVzIGNoZWNrIGlmIGFueSBlcnJvcnMgaGF2ZSBvY2N1cnJlZC4KK2NsYXNzIFNvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6OlNpbmdsZUZpbGVFcnJvckNvbGxlY3RvcgorICAgIDogcHVibGljIGlvOjpFcnJvckNvbGxlY3RvciB7CisgcHVibGljOgorICBTaW5nbGVGaWxlRXJyb3JDb2xsZWN0b3IoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKiBtdWx0aV9maWxlX2Vycm9yX2NvbGxlY3RvcikKKyAgICA6IGZpbGVuYW1lXyhmaWxlbmFtZSksCisgICAgICBtdWx0aV9maWxlX2Vycm9yX2NvbGxlY3Rvcl8obXVsdGlfZmlsZV9lcnJvcl9jb2xsZWN0b3IpLAorICAgICAgaGFkX2Vycm9yc18oZmFsc2UpIHt9CisgIH5TaW5nbGVGaWxlRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIGJvb2wgaGFkX2Vycm9ycygpIHsgcmV0dXJuIGhhZF9lcnJvcnNfOyB9CisKKyAgLy8gaW1wbGVtZW50cyBFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBBZGRFcnJvcihpbnQgbGluZSwgaW50IGNvbHVtbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgaWYgKG11bHRpX2ZpbGVfZXJyb3JfY29sbGVjdG9yXyAhPSBOVUxMKSB7CisgICAgICBtdWx0aV9maWxlX2Vycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGZpbGVuYW1lXywgbGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgICB9CisgICAgaGFkX2Vycm9yc18gPSB0cnVlOworICB9CisKKyBwcml2YXRlOgorICBzdHJpbmcgZmlsZW5hbWVfOworICBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciogbXVsdGlfZmlsZV9lcnJvcl9jb2xsZWN0b3JfOworICBib29sIGhhZF9lcnJvcnNfOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlOjpTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKAorICAgIFNvdXJjZVRyZWUqIHNvdXJjZV90cmVlKQorICA6IHNvdXJjZV90cmVlXyhzb3VyY2VfdHJlZSksCisgICAgZXJyb3JfY29sbGVjdG9yXyhOVUxMKSwKKyAgICB1c2luZ192YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3Rvcl8oZmFsc2UpLAorICAgIHZhbGlkYXRpb25fZXJyb3JfY29sbGVjdG9yXyh0aGlzKSB7fQorCitTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlOjp+U291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CisKK2Jvb2wgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEZpbGVCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5SW5wdXRTdHJlYW0+IGlucHV0KHNvdXJjZV90cmVlXy0+T3BlbihmaWxlbmFtZSkpOworICBpZiAoaW5wdXQgPT0gTlVMTCkgeworICAgIGlmIChlcnJvcl9jb2xsZWN0b3JfICE9IE5VTEwpIHsKKyAgICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGZpbGVuYW1lLCAtMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV90cmVlXy0+R2V0TGFzdEVycm9yTWVzc2FnZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gU2V0IHVwIHRoZSB0b2tlbml6ZXIgYW5kIHBhcnNlci4KKyAgU2luZ2xlRmlsZUVycm9yQ29sbGVjdG9yIGZpbGVfZXJyb3JfY29sbGVjdG9yKGZpbGVuYW1lLCBlcnJvcl9jb2xsZWN0b3JfKTsKKyAgaW86OlRva2VuaXplciB0b2tlbml6ZXIoaW5wdXQuZ2V0KCksICZmaWxlX2Vycm9yX2NvbGxlY3Rvcik7CisKKyAgUGFyc2VyIHBhcnNlcjsKKyAgaWYgKGVycm9yX2NvbGxlY3Rvcl8gIT0gTlVMTCkgeworICAgIHBhcnNlci5SZWNvcmRFcnJvcnNUbygmZmlsZV9lcnJvcl9jb2xsZWN0b3IpOworICB9CisgIGlmICh1c2luZ192YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3Rvcl8pIHsKKyAgICBwYXJzZXIuUmVjb3JkU291cmNlTG9jYXRpb25zVG8oJnNvdXJjZV9sb2NhdGlvbnNfKTsKKyAgfQorCisgIC8vIFBhcnNlIGl0LgorICBvdXRwdXQtPnNldF9uYW1lKGZpbGVuYW1lKTsKKyAgcmV0dXJuIHBhcnNlci5QYXJzZSgmdG9rZW5pemVyLCBvdXRwdXQpICYmCisgICAgICAgICAhZmlsZV9lcnJvcl9jb2xsZWN0b3IuaGFkX2Vycm9ycygpOworfQorCitib29sIFNvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLCBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIFNvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigKKyAgICBjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwgaW50IGZpZWxkX251bWJlciwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgcmV0dXJuIGZhbHNlOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1NvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6OlZhbGlkYXRpb25FcnJvckNvbGxlY3Rvcjo6CitWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IoU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSogb3duZXIpCisgIDogb3duZXJfKG93bmVyKSB7fQorCitTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlOjpWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3I6OgorflZhbGlkYXRpb25FcnJvckNvbGxlY3RvcigpIHt9CisKK3ZvaWQgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZTo6VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yOjpBZGRFcnJvcigKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgIGNvbnN0IHN0cmluZyYgZWxlbWVudF9uYW1lLAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgRXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgaWYgKG93bmVyXy0+ZXJyb3JfY29sbGVjdG9yXyA9PSBOVUxMKSByZXR1cm47CisKKyAgaW50IGxpbmUsIGNvbHVtbjsKKyAgb3duZXJfLT5zb3VyY2VfbG9jYXRpb25zXy5GaW5kKGRlc2NyaXB0b3IsIGxvY2F0aW9uLCAmbGluZSwgJmNvbHVtbik7CisgIG93bmVyXy0+ZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IoZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1wb3J0ZXI6OkltcG9ydGVyKFNvdXJjZVRyZWUqIHNvdXJjZV90cmVlLAorICAgICAgICAgICAgICAgICAgIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpCisgIDogZGF0YWJhc2VfKHNvdXJjZV90cmVlKSwKKyAgICBwb29sXygmZGF0YWJhc2VfLCBkYXRhYmFzZV8uR2V0VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yKCkpIHsKKyAgcG9vbF8uRW5mb3JjZVdlYWtEZXBlbmRlbmNpZXModHJ1ZSk7CisgIGRhdGFiYXNlXy5SZWNvcmRFcnJvcnNUbyhlcnJvcl9jb2xsZWN0b3IpOworfQorCitJbXBvcnRlcjo6fkltcG9ydGVyKCkge30KKworY29uc3QgRmlsZURlc2NyaXB0b3IqIEltcG9ydGVyOjpJbXBvcnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gcG9vbF8uRmluZEZpbGVCeU5hbWUoZmlsZW5hbWUpOworfQorCit2b2lkIEltcG9ydGVyOjpBZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpIHsKKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKGZpbGVfbmFtZSk7Cit9CisKK3ZvaWQgSW1wb3J0ZXI6OkNsZWFyVW51c2VkSW1wb3J0VHJhY2tGaWxlcygpIHsKKyAgcG9vbF8uQ2xlYXJVbnVzZWRJbXBvcnRUcmFja0ZpbGVzKCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworU291cmNlVHJlZTo6flNvdXJjZVRyZWUoKSB7fQorCitzdHJpbmcgU291cmNlVHJlZTo6R2V0TGFzdEVycm9yTWVzc2FnZSgpIHsKKyAgcmV0dXJuICJGaWxlIG5vdCBmb3VuZC4iOworfQorCitEaXNrU291cmNlVHJlZTo6RGlza1NvdXJjZVRyZWUoKSB7fQorCitEaXNrU291cmNlVHJlZTo6fkRpc2tTb3VyY2VUcmVlKCkge30KKworc3RhdGljIGlubGluZSBjaGFyIExhc3RDaGFyKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIHJldHVybiBzdHJbc3RyLnNpemUoKSAtIDFdOworfQorCisvLyBHaXZlbiBhIHBhdGgsIHJldHVybnMgYW4gZXF1aXZhbGVudCBwYXRoIHdpdGggdGhlc2UgY2hhbmdlczoKKy8vIC0gT24gV2luZG93cywgYW55IGJhY2tzbGFzaGVzIGFyZSByZXBsYWNlZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4KKy8vIC0gQW55IGluc3RhbmNlcyBvZiB0aGUgZGlyZWN0b3J5ICIuIiBhcmUgcmVtb3ZlZC4KKy8vIC0gQW55IGNvbnNlY3V0aXZlICcvJ3MgYXJlIGNvbGxhcHNlZCBpbnRvIGEgc2luZ2xlIHNsYXNoLgorLy8gTm90ZSB0aGF0IHRoZSByZXN1bHRpbmcgc3RyaW5nIG1heSBiZSBlbXB0eS4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBJdCB3b3VsZCBiZSBuaWNlIHRvIGhhbmRsZSAiLi4iLCBlLmcuIHNvIHRoYXQgd2UgY2FuIGZpZ3VyZQorLy8gICBvdXQgdGhhdCAiZm9vL2Jhci5wcm90byIgaXMgaW5zaWRlICJiYXovLi4vZm9vIi4gIEhvd2V2ZXIsIGlmIGJheiBpcyBhCisvLyAgIHN5bWxpbmsgb3IgZG9lc24ndCBleGlzdCwgdGhlbiB0aGluZ3MgZ2V0IGNvbXBsaWNhdGVkLCBhbmQgd2UgY2FuJ3QKKy8vICAgYWN0dWFsbHkgZGV0ZXJtaW5lIHRoaXMgd2l0aG91dCBpbnZlc3RpZ2F0aW5nIHRoZSBmaWxlc3lzdGVtLCBwcm9iYWJseQorLy8gICBpbiBub24tcG9ydGFibGUgd2F5cy4gIFNvLCB3ZSBwdW50LgorLy8KKy8vIFRPRE8oa2VudG9uKTogIEl0IHdvdWxkIGJlIG5pY2UgdG8gdXNlIHJlYWxwYXRoKCkgaGVyZSBleGNlcHQgdGhhdCBpdAorLy8gICByZXNvbHZlcyBzeW1ib2xpYyBsaW5rcy4gIFRoaXMgY291bGQgY2F1c2UgcHJvYmxlbXMgaWYgcGVvcGxlIHBsYWNlCisvLyAgIHN5bWJvbGljIGxpbmtzIGluIHRoZWlyIHNvdXJjZSB0cmVlLiAgRm9yIGV4YW1wbGUsIGlmIHlvdSBleGVjdXRlZDoKKy8vICAgICBwcm90b2MgLS1wcm90b19wYXRoPWZvbyBmb28vYmFyL2Jhei5wcm90bworLy8gICB0aGVuIGlmIGZvby9iYXIgaXMgYSBzeW1ib2xpYyBsaW5rLCBmb28vYmFyL2Jhei5wcm90byB3aWxsIGNhbm9uaWNhbGl6ZQorLy8gICB0byBhIHBhdGggd2hpY2ggZG9lcyBub3QgYXBwZWFyIHRvIGJlIHVuZGVyIGZvbywgYW5kIHRodXMgdGhlIGNvbXBpbGVyCisvLyAgIHdpbGwgY29tcGxhaW4gdGhhdCBiYXoucHJvdG8gaXMgbm90IGluc2lkZSB0aGUgLS1wcm90b19wYXRoLgorc3RhdGljIHN0cmluZyBDYW5vbmljYWxpemVQYXRoKHN0cmluZyBwYXRoKSB7CisjaWZkZWYgX1dJTjMyCisgIC8vIFRoZSBXaW4zMiBBUEkgYWNjZXB0cyBmb3J3YXJkIHNsYXNoZXMgYXMgYSBwYXRoIGRlbGltaXRlciBldmVuIHRob3VnaAorICAvLyBiYWNrc2xhc2hlcyBhcmUgc3RhbmRhcmQuICBMZXQncyBhdm9pZCBjb25mdXNpb24gYW5kIHVzZSBvbmx5IGZvcndhcmQKKyAgLy8gc2xhc2hlcy4KKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhwYXRoLCAiXFxcXCIpKSB7CisgICAgLy8gQXZvaWQgY29udmVydGluZyB0d28gbGVhZGluZyBiYWNrc2xhc2hlcy4KKyAgICBwYXRoID0gIlxcXFwiICsgU3RyaW5nUmVwbGFjZShwYXRoLnN1YnN0cigyKSwgIlxcIiwgIi8iLCB0cnVlKTsKKyAgfSBlbHNlIHsKKyAgICBwYXRoID0gU3RyaW5nUmVwbGFjZShwYXRoLCAiXFwiLCAiLyIsIHRydWUpOworICB9CisjZW5kaWYKKworICB2ZWN0b3I8c3RyaW5nPiBjYW5vbmljYWxfcGFydHM7CisgIHZlY3RvcjxzdHJpbmc+IHBhcnRzID0gU3BsaXQoCisgICAgICBwYXRoLCAiLyIsIHRydWUpOyAgLy8gTm90ZTogIFJlbW92ZXMgZW1wdHkgcGFydHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFydHMuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAocGFydHNbaV0gPT0gIi4iKSB7CisgICAgICAvLyBJZ25vcmUuCisgICAgfSBlbHNlIHsKKyAgICAgIGNhbm9uaWNhbF9wYXJ0cy5wdXNoX2JhY2socGFydHNbaV0pOworICAgIH0KKyAgfQorICBzdHJpbmcgcmVzdWx0ID0gSm9pbihjYW5vbmljYWxfcGFydHMsICIvIik7CisgIGlmICghcGF0aC5lbXB0eSgpICYmIHBhdGhbMF0gPT0gJy8nKSB7CisgICAgLy8gUmVzdG9yZSBsZWFkaW5nIHNsYXNoLgorICAgIHJlc3VsdCA9ICcvJyArIHJlc3VsdDsKKyAgfQorICBpZiAoIXBhdGguZW1wdHkoKSAmJiBMYXN0Q2hhcihwYXRoKSA9PSAnLycgJiYKKyAgICAgICFyZXN1bHQuZW1wdHkoKSAmJiBMYXN0Q2hhcihyZXN1bHQpICE9ICcvJykgeworICAgIC8vIFJlc3RvcmUgdHJhaWxpbmcgc2xhc2guCisgICAgcmVzdWx0ICs9ICcvJzsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgaW5saW5lIGJvb2wgQ29udGFpbnNQYXJlbnRSZWZlcmVuY2UoY29uc3Qgc3RyaW5nJiBwYXRoKSB7CisgIHJldHVybiBwYXRoID09ICIuLiIgfHwKKyAgICAgICAgIEhhc1ByZWZpeFN0cmluZyhwYXRoLCAiLi4vIikgfHwKKyAgICAgICAgIEhhc1N1ZmZpeFN0cmluZyhwYXRoLCAiLy4uIikgfHwKKyAgICAgICAgIHBhdGguZmluZCgiLy4uLyIpICE9IHN0cmluZzo6bnBvczsKK30KKworLy8gTWFwcyBhIGZpbGUgZnJvbSBhbiBvbGQgbG9jYXRpb24gdG8gYSBuZXcgb25lLiAgVHlwaWNhbGx5LCBvbGRfcHJlZml4IGlzCisvLyBhIHZpcnR1YWwgcGF0aCBhbmQgbmV3X3ByZWZpeCBpcyBpdHMgY29ycmVzcG9uZGluZyBkaXNrIHBhdGguICBSZXR1cm5zCisvLyBmYWxzZSBpZiB0aGUgZmlsZW5hbWUgZGlkIG5vdCBzdGFydCB3aXRoIG9sZF9wcmVmaXgsIG90aGVyd2lzZSByZXBsYWNlcworLy8gb2xkX3ByZWZpeCB3aXRoIG5ld19wcmVmaXggYW5kIHN0b3JlcyB0aGUgcmVzdWx0IGluICpyZXN1bHQuICBFeGFtcGxlczoKKy8vICAgc3RyaW5nIHJlc3VsdDsKKy8vICAgYXNzZXJ0KEFwcGx5TWFwcGluZygiZm9vL2JhciIsICIiLCAiYmF6IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQocmVzdWx0ID09ICJiYXovZm9vL2JhciIpOworLy8KKy8vICAgYXNzZXJ0KEFwcGx5TWFwcGluZygiZm9vL2JhciIsICJmb28iLCAiYmF6IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQocmVzdWx0ID09ICJiYXovYmFyIik7CisvLworLy8gICBhc3NlcnQoQXBwbHlNYXBwaW5nKCJmb28iLCAiZm9vIiwgImJhciIsICZyZXN1bHQpKTsKKy8vICAgYXNzZXJ0KHJlc3VsdCA9PSAiYmFyIik7CisvLworLy8gICBhc3NlcnQoIUFwcGx5TWFwcGluZygiZm9vL2JhciIsICJiYXoiLCAicXV4IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQoIUFwcGx5TWFwcGluZygiZm9vL2JhciIsICJiYXoiLCAicXV4IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQoIUFwcGx5TWFwcGluZygiZm9vYmFyIiwgImZvbyIsICJiYXoiLCAmcmVzdWx0KSk7CitzdGF0aWMgYm9vbCBBcHBseU1hcHBpbmcoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG9sZF9wcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuZXdfcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogcmVzdWx0KSB7CisgIGlmIChvbGRfcHJlZml4LmVtcHR5KCkpIHsKKyAgICAvLyBvbGRfcHJlZml4IG1hdGNoZXMgYW55IHJlbGF0aXZlIHBhdGguCisgICAgaWYgKENvbnRhaW5zUGFyZW50UmVmZXJlbmNlKGZpbGVuYW1lKSkgeworICAgICAgLy8gV2UgZG8gbm90IGFsbG93IHRoZSBmaWxlIG5hbWUgdG8gdXNlICIuLiIuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChIYXNQcmVmaXhTdHJpbmcoZmlsZW5hbWUsICIvIikgfHwKKyAgICAgICAgSXNXaW5kb3dzQWJzb2x1dGVQYXRoKGZpbGVuYW1lKSkgeworICAgICAgLy8gVGhpcyBpcyBhbiBhYnNvbHV0ZSBwYXRoLCBzbyBpdCBpc24ndCBtYXRjaGVkIGJ5IHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJlc3VsdC0+YXNzaWduKG5ld19wcmVmaXgpOworICAgIGlmICghcmVzdWx0LT5lbXB0eSgpKSByZXN1bHQtPnB1c2hfYmFjaygnLycpOworICAgIHJlc3VsdC0+YXBwZW5kKGZpbGVuYW1lKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChIYXNQcmVmaXhTdHJpbmcoZmlsZW5hbWUsIG9sZF9wcmVmaXgpKSB7CisgICAgLy8gb2xkX3ByZWZpeCBpcyBhIHByZWZpeCBvZiB0aGUgZmlsZW5hbWUuICBJcyBpdCB0aGUgd2hvbGUgZmlsZW5hbWU/CisgICAgaWYgKGZpbGVuYW1lLnNpemUoKSA9PSBvbGRfcHJlZml4LnNpemUoKSkgeworICAgICAgLy8gWWVwLCBpdCdzIGFuIGV4YWN0IG1hdGNoLgorICAgICAgKnJlc3VsdCA9IG5ld19wcmVmaXg7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTm90IGFuIGV4YWN0IG1hdGNoLiAgSXMgdGhlIG5leHQgY2hhcmFjdGVyIGEgJy8nPyAgT3RoZXJ3aXNlLAorICAgICAgLy8gdGhpcyBpc24ndCBhY3R1YWxseSBhIG1hdGNoIGF0IGFsbC4gIEUuZy4gdGhlIHByZWZpeCAiZm9vL2JhciIKKyAgICAgIC8vIGRvZXMgbm90IG1hdGNoIHRoZSBmaWxlbmFtZSAiZm9vL2JhcmJheiIuCisgICAgICBpbnQgYWZ0ZXJfcHJlZml4X3N0YXJ0ID0gLTE7CisgICAgICBpZiAoZmlsZW5hbWVbb2xkX3ByZWZpeC5zaXplKCldID09ICcvJykgeworICAgICAgICBhZnRlcl9wcmVmaXhfc3RhcnQgPSBvbGRfcHJlZml4LnNpemUoKSArIDE7CisgICAgICB9IGVsc2UgaWYgKGZpbGVuYW1lW29sZF9wcmVmaXguc2l6ZSgpIC0gMV0gPT0gJy8nKSB7CisgICAgICAgIC8vIG9sZF9wcmVmaXggaXMgbmV2ZXIgZW1wdHksIGFuZCBjYW5vbmljYWxpemVkIHBhdGhzIG5ldmVyIGhhdmUKKyAgICAgICAgLy8gY29uc2VjdXRpdmUgJy8nIGNoYXJhY3RlcnMuCisgICAgICAgIGFmdGVyX3ByZWZpeF9zdGFydCA9IG9sZF9wcmVmaXguc2l6ZSgpOworICAgICAgfQorICAgICAgaWYgKGFmdGVyX3ByZWZpeF9zdGFydCAhPSAtMSkgeworICAgICAgICAvLyBZZXAuICBTbyB0aGUgcHJlZml4ZXMgYXJlIGRpcmVjdG9yaWVzIGFuZCB0aGUgZmlsZW5hbWUgaXMgYSBmaWxlCisgICAgICAgIC8vIGluc2lkZSB0aGVtLgorICAgICAgICBzdHJpbmcgYWZ0ZXJfcHJlZml4ID0gZmlsZW5hbWUuc3Vic3RyKGFmdGVyX3ByZWZpeF9zdGFydCk7CisgICAgICAgIGlmIChDb250YWluc1BhcmVudFJlZmVyZW5jZShhZnRlcl9wcmVmaXgpKSB7CisgICAgICAgICAgLy8gV2UgZG8gbm90IGFsbG93IHRoZSBmaWxlIG5hbWUgdG8gdXNlICIuLiIuCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC0+YXNzaWduKG5ld19wcmVmaXgpOworICAgICAgICBpZiAoIXJlc3VsdC0+ZW1wdHkoKSkgcmVzdWx0LT5wdXNoX2JhY2soJy8nKTsKKyAgICAgICAgcmVzdWx0LT5hcHBlbmQoYWZ0ZXJfcHJlZml4KTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIERpc2tTb3VyY2VUcmVlOjpNYXBQYXRoKGNvbnN0IHN0cmluZyYgdmlydHVhbF9wYXRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGRpc2tfcGF0aCkgeworICBtYXBwaW5nc18ucHVzaF9iYWNrKE1hcHBpbmcodmlydHVhbF9wYXRoLCBDYW5vbmljYWxpemVQYXRoKGRpc2tfcGF0aCkpKTsKK30KKworRGlza1NvdXJjZVRyZWU6OkRpc2tGaWxlVG9WaXJ0dWFsRmlsZVJlc3VsdAorRGlza1NvdXJjZVRyZWU6OkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICBjb25zdCBzdHJpbmcmIGRpc2tfZmlsZSwKKyAgICBzdHJpbmcqIHZpcnR1YWxfZmlsZSwKKyAgICBzdHJpbmcqIHNoYWRvd2luZ19kaXNrX2ZpbGUpIHsKKyAgaW50IG1hcHBpbmdfaW5kZXggPSAtMTsKKyAgc3RyaW5nIGNhbm9uaWNhbF9kaXNrX2ZpbGUgPSBDYW5vbmljYWxpemVQYXRoKGRpc2tfZmlsZSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBwaW5nc18uc2l6ZSgpOyBpKyspIHsKKyAgICAvLyBBcHBseSB0aGUgbWFwcGluZyBpbiByZXZlcnNlLgorICAgIGlmIChBcHBseU1hcHBpbmcoY2Fub25pY2FsX2Rpc2tfZmlsZSwgbWFwcGluZ3NfW2ldLmRpc2tfcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmdzX1tpXS52aXJ0dWFsX3BhdGgsIHZpcnR1YWxfZmlsZSkpIHsKKyAgICAgIC8vIFN1Y2Nlc3MuCisgICAgICBtYXBwaW5nX2luZGV4ID0gaTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIGlmIChtYXBwaW5nX2luZGV4ID09IC0xKSB7CisgICAgcmV0dXJuIE5PX01BUFBJTkc7CisgIH0KKworICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIG1hcHBpbmdzIHdpdGggaGlnaGVyIHByZWNlZGVuY2UgYW5kIHZlcmlmeSB0aGF0IG5vbmUKKyAgLy8gb2YgdGhlbSBtYXAgdGhpcyBmaWxlIHRvIHNvbWUgb3RoZXIgZXhpc3RpbmcgZmlsZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBwaW5nX2luZGV4OyBpKyspIHsKKyAgICBpZiAoQXBwbHlNYXBwaW5nKCp2aXJ0dWFsX2ZpbGUsIG1hcHBpbmdzX1tpXS52aXJ0dWFsX3BhdGgsCisgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nc19baV0uZGlza19wYXRoLCBzaGFkb3dpbmdfZGlza19maWxlKSkgeworICAgICAgaWYgKGFjY2VzcyhzaGFkb3dpbmdfZGlza19maWxlLT5jX3N0cigpLCBGX09LKSA+PSAwKSB7CisgICAgICAgIC8vIEZpbGUgZXhpc3RzLgorICAgICAgICByZXR1cm4gU0hBRE9XRUQ7CisgICAgICB9CisgICAgfQorICB9CisgIHNoYWRvd2luZ19kaXNrX2ZpbGUtPmNsZWFyKCk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgd2UgY2FuIG9wZW4gdGhlIGZpbGUuICBOb3RlIHRoYXQgdGhpcyBhbHNvIGhhcyB0aGUgc2lkZS1lZmZlY3QKKyAgLy8gb2YgdmVyaWZ5aW5nIHRoYXQgd2UgYXJlIG5vdCBjYW5vbmljYWxpemluZyBhd2F5IGFueSBub24tZXhpc3RlbnQKKyAgLy8gZGlyZWN0b3JpZXMuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5SW5wdXRTdHJlYW0+IHN0cmVhbShPcGVuRGlza0ZpbGUoZGlza19maWxlKSk7CisgIGlmIChzdHJlYW0gPT0gTlVMTCkgeworICAgIHJldHVybiBDQU5OT1RfT1BFTjsKKyAgfQorCisgIHJldHVybiBTVUNDRVNTOworfQorCitib29sIERpc2tTb3VyY2VUcmVlOjpWaXJ0dWFsRmlsZVRvRGlza0ZpbGUoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBkaXNrX2ZpbGUpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbT4gc3RyZWFtKAorICAgICAgT3BlblZpcnR1YWxGaWxlKHZpcnR1YWxfZmlsZSwgZGlza19maWxlKSk7CisgIHJldHVybiBzdHJlYW0gIT0gTlVMTDsKK30KKworaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIERpc2tTb3VyY2VUcmVlOjpPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuIE9wZW5WaXJ0dWFsRmlsZShmaWxlbmFtZSwgTlVMTCk7Cit9CisKK3N0cmluZyBEaXNrU291cmNlVHJlZTo6R2V0TGFzdEVycm9yTWVzc2FnZSgpIHsKKyAgcmV0dXJuIGxhc3RfZXJyb3JfbWVzc2FnZV87Cit9CisKK2lvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBEaXNrU291cmNlVHJlZTo6T3BlblZpcnR1YWxGaWxlKAorICAgIGNvbnN0IHN0cmluZyYgdmlydHVhbF9maWxlLAorICAgIHN0cmluZyogZGlza19maWxlKSB7CisgIGlmICh2aXJ0dWFsX2ZpbGUgIT0gQ2Fub25pY2FsaXplUGF0aCh2aXJ0dWFsX2ZpbGUpIHx8CisgICAgICBDb250YWluc1BhcmVudFJlZmVyZW5jZSh2aXJ0dWFsX2ZpbGUpKSB7CisgICAgLy8gV2UgZG8gbm90IGFsbG93IGltcG9ydGluZyBvZiBwYXRocyBjb250YWluaW5nIHRoaW5ncyBsaWtlICIuLiIgb3IKKyAgICAvLyBjb25zZWN1dGl2ZSBzbGFzaGVzIHNpbmNlIHRoZSBjb21waWxlciBleHBlY3RzIGZpbGVzIHRvIGJlIHVuaXF1ZWx5CisgICAgLy8gaWRlbnRpZmllZCBieSBmaWxlIG5hbWUuCisgICAgbGFzdF9lcnJvcl9tZXNzYWdlXyA9ICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICJhcmUgbm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCI7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IG1hcHBpbmdzXy5zaXplKCk7IGkrKykgeworICAgIHN0cmluZyB0ZW1wX2Rpc2tfZmlsZTsKKyAgICBpZiAoQXBwbHlNYXBwaW5nKHZpcnR1YWxfZmlsZSwgbWFwcGluZ3NfW2ldLnZpcnR1YWxfcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmdzX1tpXS5kaXNrX3BhdGgsICZ0ZW1wX2Rpc2tfZmlsZSkpIHsKKyAgICAgIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBzdHJlYW0gPSBPcGVuRGlza0ZpbGUodGVtcF9kaXNrX2ZpbGUpOworICAgICAgaWYgKHN0cmVhbSAhPSBOVUxMKSB7CisgICAgICAgIGlmIChkaXNrX2ZpbGUgIT0gTlVMTCkgeworICAgICAgICAgICpkaXNrX2ZpbGUgPSB0ZW1wX2Rpc2tfZmlsZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RyZWFtOworICAgICAgfQorCisgICAgICBpZiAoZXJybm8gPT0gRUFDQ0VTKSB7CisgICAgICAgIC8vIFRoZSBmaWxlIGV4aXN0cyBidXQgaXMgbm90IHJlYWRhYmxlLgorICAgICAgICBsYXN0X2Vycm9yX21lc3NhZ2VfID0gIlJlYWQgYWNjZXNzIGlzIGRlbmllZCBmb3IgZmlsZTogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2Rpc2tfZmlsZTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgfQorICB9CisgIGxhc3RfZXJyb3JfbWVzc2FnZV8gPSAiRmlsZSBub3QgZm91bmQuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2lvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBEaXNrU291cmNlVHJlZTo6T3BlbkRpc2tGaWxlKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgaW50IGZpbGVfZGVzY3JpcHRvcjsKKyAgZG8geworICAgIGZpbGVfZGVzY3JpcHRvciA9IG9wZW4oZmlsZW5hbWUuY19zdHIoKSwgT19SRE9OTFkpOworICB9IHdoaWxlIChmaWxlX2Rlc2NyaXB0b3IgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKyAgaWYgKGZpbGVfZGVzY3JpcHRvciA+PSAwKSB7CisgICAgaW86OkZpbGVJbnB1dFN0cmVhbSogcmVzdWx0ID0gbmV3IGlvOjpGaWxlSW5wdXRTdHJlYW0oZmlsZV9kZXNjcmlwdG9yKTsKKyAgICByZXN1bHQtPlNldENsb3NlT25EZWxldGUodHJ1ZSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwMTBmZDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmgKQEAgLTAsMCArMSwzMTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgaXMgdGhlIHB1YmxpYyBpbnRlcmZhY2UgdG8gdGhlIC5wcm90byBmaWxlIHBhcnNlci4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSU1QT1JURVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9JTVBPUlRFUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW8geyBjbGFzcyBaZXJvQ29weUlucHV0U3RyZWFtOyB9CisKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgSW1wb3J0ZXI7CitjbGFzcyBNdWx0aUZpbGVFcnJvckNvbGxlY3RvcjsKK2NsYXNzIFNvdXJjZVRyZWU7CitjbGFzcyBEaXNrU291cmNlVHJlZTsKKworLy8gVE9ETyhrZW50b24pOiAgTW92ZSBhbGwgU291cmNlVHJlZSBzdHVmZiB0byBhIHNlcGFyYXRlIGZpbGU/CisKKy8vIEFuIGltcGxlbWVudGF0aW9uIG9mIERlc2NyaXB0b3JEYXRhYmFzZSB3aGljaCBsb2FkcyBmaWxlcyBmcm9tIGEgU291cmNlVHJlZQorLy8gYW5kIHBhcnNlcyB0aGVtLgorLy8KKy8vIE5vdGU6ICBUaGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZSBzaW5jZSBpdCBtYWludGFpbnMgYSB0YWJsZSBvZiBzb3VyY2UKKy8vICAgY29kZSBsb2NhdGlvbnMgZm9yIGVycm9yIHJlcG9ydGluZy4gIEhvd2V2ZXIsIHdoZW4gYSBEZXNjcmlwdG9yUG9vbCB3cmFwcworLy8gICBhIERlc2NyaXB0b3JEYXRhYmFzZSwgaXQgdXNlcyBtdXRleCBsb2NraW5nIHRvIG1ha2Ugc3VyZSBvbmx5IG9uZSBtZXRob2QKKy8vICAgb2YgdGhlIGRhdGFiYXNlIGlzIGNhbGxlZCBhdCBhIHRpbWUsIGV2ZW4gaWYgdGhlIERlc2NyaXB0b3JQb29sIGlzIHVzZWQKKy8vICAgZnJvbSBtdWx0aXBsZSB0aHJlYWRzLiAgVGhlcmVmb3JlLCB0aGVyZSBpcyBvbmx5IGEgcHJvYmxlbSBpZiB5b3UgY3JlYXRlCisvLyAgIG11bHRpcGxlIERlc2NyaXB0b3JQb29scyB3cmFwcGluZyB0aGUgc2FtZSBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlCisvLyAgIGFuZCB1c2UgdGhlbSBmcm9tIG11bHRpcGxlIHRocmVhZHMuCisvLworLy8gTm90ZTogIFRoaXMgY2xhc3MgZG9lcyBub3QgaW1wbGVtZW50IEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgpIG9yCisvLyAgIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigpOyB0aGVzZSB3aWxsIGFsd2F5cyByZXR1cm4gZmFsc2UuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2UgeworIHB1YmxpYzoKKyAgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZShTb3VyY2VUcmVlKiBzb3VyY2VfdHJlZSk7CisgIH5Tb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKCk7CisKKyAgLy8gSW5zdHJ1Y3RzIHRoZSBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlIHRvIHJlcG9ydCBhbnkgcGFyc2UgZXJyb3JzCisgIC8vIHRvIHRoZSBnaXZlbiBNdWx0aUZpbGVFcnJvckNvbGxlY3Rvci4gIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUKKyAgLy8gcGFyc2luZy4gIGVycm9yX2NvbGxlY3RvciBtdXN0IHJlbWFpbiB2YWxpZCB1bnRpbCBlaXRoZXIgdGhpcyBtZXRob2QKKyAgLy8gaXMgY2FsbGVkIGFnYWluIG9yIHRoZSBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlIGlzIGRlc3Ryb3llZC4KKyAgdm9pZCBSZWNvcmRFcnJvcnNUbyhNdWx0aUZpbGVFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKSB7CisgICAgZXJyb3JfY29sbGVjdG9yXyA9IGVycm9yX2NvbGxlY3RvcjsKKyAgfQorCisgIC8vIEdldHMgYSBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3Igd2hpY2ggcmVjb3JkcyBlcnJvcnMgdG8gdGhlCisgIC8vIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yIHNwZWNpZmllZCB3aXRoIFJlY29yZEVycm9yc1RvKCkuICBUaGlzIGNvbGxlY3RvcgorICAvLyBoYXMgdGhlIGFiaWxpdHkgdG8gZGV0ZXJtaW5lIGV4YWN0IGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzIG9mIGVycm9ycworICAvLyBmcm9tIHRoZSBpbmZvcm1hdGlvbiBnaXZlbiB0byBpdCBieSB0aGUgRGVzY3JpcHRvclBvb2wuCisgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3RvciogR2V0VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yKCkgeworICAgIHVzaW5nX3ZhbGlkYXRpb25fZXJyb3JfY29sbGVjdG9yXyA9IHRydWU7CisgICAgcmV0dXJuICZ2YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3Rvcl87CisgIH0KKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworCisgcHJpdmF0ZToKKyAgY2xhc3MgU2luZ2xlRmlsZUVycm9yQ29sbGVjdG9yOworCisgIFNvdXJjZVRyZWUqIHNvdXJjZV90cmVlXzsKKyAgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3Rvcl87CisKKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFZhbGlkYXRpb25FcnJvckNvbGxlY3RvciA6IHB1YmxpYyBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IgeworICAgcHVibGljOgorICAgIFZhbGlkYXRpb25FcnJvckNvbGxlY3RvcihTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKiBvd25lcik7CisgICAgflZhbGlkYXRpb25FcnJvckNvbGxlY3RvcigpOworCisgICAgLy8gaW1wbGVtZW50cyBFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKTsKKworICAgcHJpdmF0ZToKKyAgICBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKiBvd25lcl87CisgIH07CisgIGZyaWVuZCBjbGFzcyBWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3I7CisKKyAgYm9vbCB1c2luZ192YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3Rvcl87CisgIFNvdXJjZUxvY2F0aW9uVGFibGUgc291cmNlX2xvY2F0aW9uc187CisgIFZhbGlkYXRpb25FcnJvckNvbGxlY3RvciB2YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3Rvcl87Cit9OworCisvLyBTaW1wbGUgaW50ZXJmYWNlIGZvciBwYXJzaW5nIC5wcm90byBmaWxlcy4gIFRoaXMgd3JhcHMgdGhlIHByb2Nlc3MKKy8vIG9mIG9wZW5pbmcgdGhlIGZpbGUsIHBhcnNpbmcgaXQgd2l0aCBhIFBhcnNlciwgcmVjdXJzaXZlbHkgcGFyc2luZyBhbGwgaXRzCisvLyBpbXBvcnRzLCBhbmQgdGhlbiBjcm9zcy1saW5raW5nIHRoZSByZXN1bHRzIHRvIHByb2R1Y2UgYSBGaWxlRGVzY3JpcHRvci4KKy8vCisvLyBUaGlzIGlzIHJlYWxseSBqdXN0IGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlLgorLy8gWW91IG1heSBmaW5kIHRoYXQgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSBpcyBtb3JlIGZsZXhpYmxlLgorLy8KKy8vIFRPRE8oa2VudG9uKTogIEkgZmVlbCBsaWtlIHRoaXMgY2xhc3MgaXMgbm90IHdlbGwtbmFtZWQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgSW1wb3J0ZXIgeworIHB1YmxpYzoKKyAgSW1wb3J0ZXIoU291cmNlVHJlZSogc291cmNlX3RyZWUsCisgICAgICAgICAgIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpOworICB+SW1wb3J0ZXIoKTsKKworICAvLyBJbXBvcnQgdGhlIGdpdmVuIGZpbGUgYW5kIGJ1aWxkIGEgRmlsZURlc2NyaXB0b3IgcmVwcmVzZW50aW5nIGl0LiAgSWYKKyAgLy8gdGhlIGZpbGUgaXMgYWxyZWFkeSBpbiB0aGUgRGVzY3JpcHRvclBvb2wsIHRoZSBleGlzdGluZyBGaWxlRGVzY3JpcHRvcgorICAvLyB3aWxsIGJlIHJldHVybmVkLiAgVGhlIEZpbGVEZXNjcmlwdG9yIGlzIHByb3BlcnR5IG9mIHRoZSBEZXNjcmlwdG9yUG9vbCwKKyAgLy8gYW5kIHdpbGwgcmVtYWluIHZhbGlkIHVudGlsIGl0IGlzIGRlc3Ryb3llZC4gIElmIGFueSBlcnJvcnMgb2NjdXIsIHRoZXkKKyAgLy8gd2lsbCBiZSByZXBvcnRlZCB1c2luZyB0aGUgZXJyb3IgY29sbGVjdG9yIGFuZCBJbXBvcnQoKSB3aWxsIHJldHVybiBOVUxMLgorICAvLworICAvLyBBIHBhcnRpY3VsYXIgSW1wb3J0ZXIgb2JqZWN0IHdpbGwgb25seSByZXBvcnQgZXJyb3JzIGZvciBhIHBhcnRpY3VsYXIKKyAgLy8gZmlsZSBvbmNlLiAgQWxsIGZ1dHVyZSBhdHRlbXB0cyB0byBpbXBvcnQgdGhlIHNhbWUgZmlsZSB3aWxsIHJldHVybiBOVUxMCisgIC8vIHdpdGhvdXQgcmVwb3J0aW5nIGFueSBlcnJvcnMuICBUaGUgaWRlYSBpcyB0aGF0IHlvdSBtaWdodCB3YW50IHRvIGltcG9ydAorICAvLyBhIGxvdCBvZiBmaWxlcyB3aXRob3V0IHNlZWluZyB0aGUgc2FtZSBlcnJvcnMgb3ZlciBhbmQgb3ZlciBhZ2Fpbi4gIElmCisgIC8vIHlvdSB3YW50IHRvIHNlZSBlcnJvcnMgZm9yIHRoZSBzYW1lIGZpbGVzIHJlcGVhdGVkbHksIHlvdSBjYW4gdXNlIGEKKyAgLy8gc2VwYXJhdGUgSW1wb3J0ZXIgb2JqZWN0IHRvIGltcG9ydCBlYWNoIG9uZSAoYnV0IHVzZSB0aGUgc2FtZQorICAvLyBEZXNjcmlwdG9yUG9vbCBzbyB0aGF0IHRoZXkgY2FuIGJlIGNyb3NzLWxpbmtlZCkuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBJbXBvcnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisKKyAgLy8gVGhlIERlc2NyaXB0b3JQb29sIGluIHdoaWNoIGFsbCBpbXBvcnRlZCBGaWxlRGVzY3JpcHRvcnMgYW5kIHRoZWlyCisgIC8vIGNvbnRlbnRzIGFyZSBzdG9yZWQuCisgIGlubGluZSBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gJnBvb2xfOworICB9CisKKyAgdm9pZCBBZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpOworICB2b2lkIENsZWFyVW51c2VkSW1wb3J0VHJhY2tGaWxlcygpOworCisgcHJpdmF0ZToKKyAgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSBkYXRhYmFzZV87CisgIERlc2NyaXB0b3JQb29sIHBvb2xfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbXBvcnRlcik7Cit9OworCisvLyBJZiB0aGUgaW1wb3J0ZXIgZW5jb3VudGVycyBwcm9ibGVtcyB3aGlsZSB0cnlpbmcgdG8gaW1wb3J0IHRoZSBwcm90byBmaWxlcywKKy8vIGl0IHJlcG9ydHMgdGhlbSB0byBhIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIGlubGluZSBNdWx0aUZpbGVFcnJvckNvbGxlY3RvcigpIHt9CisgIHZpcnR1YWwgfk11bHRpRmlsZUVycm9yQ29sbGVjdG9yKCk7CisKKyAgLy8gTGluZSBhbmQgY29sdW1uIG51bWJlcnMgYXJlIHplcm8tYmFzZWQuICBBIGxpbmUgbnVtYmVyIG9mIC0xIGluZGljYXRlcworICAvLyBhbiBlcnJvciB3aXRoIHRoZSBlbnRpcmUgZmlsZSAoZS5nLiAibm90IGZvdW5kIikuCisgIHZpcnR1YWwgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBpbnQgbGluZSwgaW50IGNvbHVtbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgPSAwOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKTsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSB3aGljaCByZXByZXNlbnRzIGEgZGlyZWN0b3J5IHRyZWUgY29udGFpbmluZyBwcm90byBmaWxlcy4KKy8vIFVzZWQgYnkgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgSW1wb3J0ZXIgdG8gcmVzb2x2ZSBpbXBvcnQgc3RhdGVtZW50cworLy8gTW9zdCB1c2VycyB3aWxsIHByb2JhYmx5IHdhbnQgdG8gdXNlIHRoZSBEaXNrU291cmNlVHJlZSBpbXBsZW1lbnRhdGlvbiwKKy8vIGJlbG93LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFNvdXJjZVRyZWUgeworIHB1YmxpYzoKKyAgaW5saW5lIFNvdXJjZVRyZWUoKSB7fQorICB2aXJ0dWFsIH5Tb3VyY2VUcmVlKCk7CisKKyAgLy8gT3BlbiB0aGUgZ2l2ZW4gZmlsZSBhbmQgcmV0dXJuIGEgc3RyZWFtIHRoYXQgcmVhZHMgaXQsIG9yIE5VTEwgaWYgbm90CisgIC8vIGZvdW5kLiAgVGhlIGNhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIG9iamVjdC4gIFRoZSBmaWxlbmFtZQorICAvLyBtdXN0IGJlIGEgcGF0aCByZWxhdGl2ZSB0byB0aGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUgYW5kIG11c3Qgbm90CisgIC8vIGNvbnRhaW4gIi4iIG9yICIuLiIgY29tcG9uZW50cy4KKyAgdmlydHVhbCBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogT3Blbihjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSA9IDA7CisKKyAgLy8gSWYgT3BlbigpIHJldHVybnMgTlVMTCwgY2FsbGluZyB0aGlzIG1ldGhvZCBpbW1lZGlhdGVseSB3aWxsIHJldHVybiBhbgorICAvLyBkZXNjcmlwdGlvbiBvZiB0aGUgZXJyb3IuCisgIC8vIFN1YmNsYXNzZXMgc2hvdWxkIGltcGxlbWVudCB0aGlzIG1ldGhvZCBhbmQgcmV0dXJuIGEgbWVhbmluZ2Z1bCB2YWx1ZSBmb3IKKyAgLy8gYmV0dGVyIGVycm9yIHJlcG9ydGluZy4KKyAgLy8gVE9ETyh4aWFvZmVuZyk6IGNoYW5nZSB0aGlzIHRvIGEgcHVyZSB2aXJ0dWFsIGZ1bmN0aW9uLgorICB2aXJ0dWFsIHN0cmluZyBHZXRMYXN0RXJyb3JNZXNzYWdlKCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU291cmNlVHJlZSk7Cit9OworCisvLyBBbiBpbXBsZW1lbnRhdGlvbiBvZiBTb3VyY2VUcmVlIHdoaWNoIGxvYWRzIGZpbGVzIGZyb20gbG9jYXRpb25zIG9uIGRpc2suCisvLyBNdWx0aXBsZSBtYXBwaW5ncyBjYW4gYmUgc2V0IHVwIHRvIG1hcCBsb2NhdGlvbnMgaW4gdGhlIERpc2tTb3VyY2VUcmVlIHRvCisvLyBsb2NhdGlvbnMgaW4gdGhlIHBoeXNpY2FsIGZpbGVzeXN0ZW0uCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGlza1NvdXJjZVRyZWUgOiBwdWJsaWMgU291cmNlVHJlZSB7CisgcHVibGljOgorICBEaXNrU291cmNlVHJlZSgpOworICB+RGlza1NvdXJjZVRyZWUoKTsKKworICAvLyBNYXAgYSBwYXRoIG9uIGRpc2sgdG8gYSBsb2NhdGlvbiBpbiB0aGUgU291cmNlVHJlZS4gIFRoZSBwYXRoIG1heSBiZQorICAvLyBlaXRoZXIgYSBmaWxlIG9yIGEgZGlyZWN0b3J5LiAgSWYgaXQgaXMgYSBkaXJlY3RvcnksIHRoZSBlbnRpcmUgdHJlZQorICAvLyB1bmRlciBpdCB3aWxsIGJlIG1hcHBlZCB0byB0aGUgZ2l2ZW4gdmlydHVhbCBsb2NhdGlvbi4gIFRvIG1hcCBhIGRpcmVjdG9yeQorICAvLyB0byB0aGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUsIHBhc3MgYW4gZW1wdHkgc3RyaW5nIGZvciB2aXJ0dWFsX3BhdGguCisgIC8vCisgIC8vIElmIG11bHRpcGxlIG1hcHBlZCBwYXRocyBhcHBseSB3aGVuIG9wZW5pbmcgYSBmaWxlLCB0aGV5IHdpbGwgYmUgc2VhcmNoZWQKKyAgLy8gaW4gb3JkZXIuICBGb3IgZXhhbXBsZSwgaWYgeW91IGRvOgorICAvLyAgIE1hcFBhdGgoImJhciIsICJmb28vYmFyIik7CisgIC8vICAgTWFwUGF0aCgiIiwgImJheiIpOworICAvLyBhbmQgdGhlbiB5b3UgZG86CisgIC8vICAgT3BlbigiYmFyL3F1eCIpOworICAvLyB0aGUgRGlza1NvdXJjZVRyZWUgd2lsbCBmaXJzdCB0cnkgdG8gb3BlbiBmb28vYmFyL3F1eCwgdGhlbiBiYXovYmFyL3F1eCwKKyAgLy8gcmV0dXJuaW5nIHRoZSBmaXJzdCBvbmUgdGhhdCBvcGVucyBzdWNjZXNzZnVseS4KKyAgLy8KKyAgLy8gZGlza19wYXRoIG1heSBiZSBhbiBhYnNvbHV0ZSBwYXRoIG9yIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwKKyAgLy8ganVzdCBsaWtlIGEgcGF0aCB5b3UnZCBwYXNzIHRvIG9wZW4oKS4KKyAgdm9pZCBNYXBQYXRoKGNvbnN0IHN0cmluZyYgdmlydHVhbF9wYXRoLCBjb25zdCBzdHJpbmcmIGRpc2tfcGF0aCk7CisKKyAgLy8gUmV0dXJuIHR5cGUgZm9yIERpc2tGaWxlVG9WaXJ0dWFsRmlsZSgpLgorICBlbnVtIERpc2tGaWxlVG9WaXJ0dWFsRmlsZVJlc3VsdCB7CisgICAgU1VDQ0VTUywKKyAgICBTSEFET1dFRCwKKyAgICBDQU5OT1RfT1BFTiwKKyAgICBOT19NQVBQSU5HCisgIH07CisKKyAgLy8gR2l2ZW4gYSBwYXRoIHRvIGEgZmlsZSBvbiBkaXNrLCBmaW5kIGEgdmlydHVhbCBwYXRoIG1hcHBpbmcgdG8gdGhhdAorICAvLyBmaWxlLiAgVGhlIGZpcnN0IG1hcHBpbmcgY3JlYXRlZCB3aXRoIE1hcFBhdGgoKSB3aG9zZSBkaXNrX3BhdGggY29udGFpbnMKKyAgLy8gdGhlIGZpbGVuYW1lIGlzIHVzZWQuICBIb3dldmVyLCB0aGF0IHZpcnR1YWwgcGF0aCBtYXkgbm90IGFjdHVhbGx5IGJlCisgIC8vIHVzYWJsZSB0byBvcGVuIHRoZSBnaXZlbiBmaWxlLiAgUG9zc2libGUgcmV0dXJuIHZhbHVlcyBhcmU6CisgIC8vICogU1VDQ0VTUzogVGhlIG1hcHBpbmcgd2FzIGZvdW5kLiAgKnZpcnR1YWxfZmlsZSBpcyBmaWxsZWQgaW4gc28gdGhhdAorICAvLyAgIGNhbGxpbmcgT3BlbigqdmlydHVhbF9maWxlKSB3aWxsIG9wZW4gdGhlIGZpbGUgbmFtZWQgYnkgZGlza19maWxlLgorICAvLyAqIFNIQURPV0VEOiBBIG1hcHBpbmcgd2FzIGZvdW5kLCBidXQgdXNpbmcgT3BlbigpIHRvIG9wZW4gdGhpcyB2aXJ0dWFsCisgIC8vICAgcGF0aCB3aWxsIGVuZCB1cCByZXR1cm5pbmcgc29tZSBkaWZmZXJlbnQgZmlsZS4gIFRoaXMgaXMgYmVjYXVzZSBzb21lCisgIC8vICAgb3RoZXIgbWFwcGluZyB3aXRoIGEgaGlnaGVyIHByZWNlZGVuY2UgYWxzbyBtYXRjaGVzIHRoaXMgdmlydHVhbCBwYXRoCisgIC8vICAgYW5kIG1hcHMgaXQgdG8gYSBkaWZmZXJlbnQgZmlsZSB0aGF0IGV4aXN0cyBvbiBkaXNrLiAgKnZpcnR1YWxfZmlsZQorICAvLyAgIGlzIGZpbGxlZCBpbiBhcyBpdCB3b3VsZCBiZSBpbiB0aGUgU1VDQ0VTUyBjYXNlLiAgKnNoYWRvd2luZ19kaXNrX2ZpbGUKKyAgLy8gICBpcyBmaWxsZWQgaW4gd2l0aCB0aGUgZGlzayBwYXRoIG9mIHRoZSBmaWxlIHdoaWNoIHdvdWxkIGJlIG9wZW5lZCBpZgorICAvLyAgIHlvdSB3ZXJlIHRvIGNhbGwgT3BlbigqdmlydHVhbF9maWxlKS4KKyAgLy8gKiBDQU5OT1RfT1BFTjogVGhlIG1hcHBpbmcgd2FzIGZvdW5kIGFuZCB3YXMgbm90IHNoYWRvd2VkLCBidXQgdGhlCisgIC8vICAgZmlsZSBzcGVjaWZpZWQgY2Fubm90IGJlIG9wZW5lZC4gIFdoZW4gdGhpcyB2YWx1ZSBpcyByZXR1cm5lZCwKKyAgLy8gICBlcnJubyB3aWxsIGluZGljYXRlIHRoZSByZWFzb24gdGhlIGZpbGUgY2Fubm90IGJlIG9wZW5lZC4gICp2aXJ0dWFsX2ZpbGUKKyAgLy8gICB3aWxsIGJlIHNldCB0byB0aGUgdmlydHVhbCBwYXRoIGFzIGluIHRoZSBTVUNDRVNTIGNhc2UsIGV2ZW4gdGhvdWdoCisgIC8vICAgaXQgaXMgbm90IHVzZWZ1bC4KKyAgLy8gKiBOT19NQVBQSU5HOiBJbmRpY2F0ZXMgdGhhdCBubyBtYXBwaW5nIHdhcyBmb3VuZCB3aGljaCBjb250YWlucyB0aGlzCisgIC8vICAgZmlsZS4KKyAgRGlza0ZpbGVUb1ZpcnR1YWxGaWxlUmVzdWx0CisgICAgRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKGNvbnN0IHN0cmluZyYgZGlza19maWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHZpcnR1YWxfZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBzaGFkb3dpbmdfZGlza19maWxlKTsKKworICAvLyBHaXZlbiBhIHZpcnR1YWwgcGF0aCwgZmluZCB0aGUgcGF0aCB0byB0aGUgZmlsZSBvbiBkaXNrLgorICAvLyBSZXR1cm4gdHJ1ZSBhbmQgdXBkYXRlIGRpc2tfZmlsZSB3aXRoIHRoZSBvbi1kaXNrIHBhdGggaWYgdGhlIGZpbGUgZXhpc3RzLgorICAvLyBSZXR1cm4gZmFsc2UgYW5kIGxlYXZlIGRpc2tfZmlsZSB1bnRvdWNoZWQgaWYgdGhlIGZpbGUgZG9lc24ndCBleGlzdC4KKyAgYm9vbCBWaXJ0dWFsRmlsZVRvRGlza0ZpbGUoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUsIHN0cmluZyogZGlza19maWxlKTsKKworICAvLyBpbXBsZW1lbnRzIFNvdXJjZVRyZWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2aXJ0dWFsIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisgIHZpcnR1YWwgc3RyaW5nIEdldExhc3RFcnJvck1lc3NhZ2UoKTsKKworIHByaXZhdGU6CisgIHN0cnVjdCBNYXBwaW5nIHsKKyAgICBzdHJpbmcgdmlydHVhbF9wYXRoOworICAgIHN0cmluZyBkaXNrX3BhdGg7CisKKyAgICBpbmxpbmUgTWFwcGluZyhjb25zdCBzdHJpbmcmIHZpcnR1YWxfcGF0aF9wYXJhbSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGRpc2tfcGF0aF9wYXJhbSkKKyAgICAgIDogdmlydHVhbF9wYXRoKHZpcnR1YWxfcGF0aF9wYXJhbSksIGRpc2tfcGF0aChkaXNrX3BhdGhfcGFyYW0pIHt9CisgIH07CisgIHZlY3RvcjxNYXBwaW5nPiBtYXBwaW5nc187CisgIHN0cmluZyBsYXN0X2Vycm9yX21lc3NhZ2VfOworCisgIC8vIExpa2UgT3BlbigpLCBidXQgcmV0dXJucyB0aGUgb24tZGlzayBwYXRoIGluIGRpc2tfZmlsZSBpZiBkaXNrX2ZpbGUgaXMKKyAgLy8gbm9uLU5VTEwgYW5kIHRoZSBmaWxlIGNvdWxkIGJlIHN1Y2Nlc3NmdWxseSBvcGVuZWQuCisgIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBPcGVuVmlydHVhbEZpbGUoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBkaXNrX2ZpbGUpOworCisgIC8vIExpa2UgT3BlbigpIGJ1dCBnaXZlbiB0aGUgYWN0dWFsIG9uLWRpc2sgcGF0aC4KKyAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIE9wZW5EaXNrRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGlza1NvdXJjZVRyZWUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSU1QT1JURVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40M2ViMGVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlcl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDUxMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworbmFtZXNwYWNlIHsKKworYm9vbCBGaWxlRXhpc3RzKGNvbnN0IHN0cmluZyYgcGF0aCkgeworICByZXR1cm4gRmlsZTo6RXhpc3RzKHBhdGgpOworfQorCisjZGVmaW5lIEVYUEVDVF9TVUJTVFJJTkcobmVlZGxlLCBoYXlzdGFjaykgXAorICBFWFBFQ1RfUFJFRF9GT1JNQVQyKHRlc3Rpbmc6OklzU3Vic3RyaW5nLCAobmVlZGxlKSwgKGhheXN0YWNrKSkKKworY2xhc3MgTW9ja0Vycm9yQ29sbGVjdG9yIDogcHVibGljIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIE1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisgIH5Nb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHN0cmluZyB0ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGludCBsaW5lLCBpbnQgY29sdW1uLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJnRleHRfLCAiJDA6JDE6JDI6ICQzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gQSBkdW1teSBpbXBsZW1lbnRhdGlvbiBvZiBTb3VyY2VUcmVlIGJhY2tlZCBieSBhIHNpbXBsZSBtYXAuCitjbGFzcyBNb2NrU291cmNlVHJlZSA6IHB1YmxpYyBTb3VyY2VUcmVlIHsKKyBwdWJsaWM6CisgIE1vY2tTb3VyY2VUcmVlKCkge30KKyAgfk1vY2tTb3VyY2VUcmVlKCkge30KKworICB2b2lkIEFkZEZpbGUoY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBjaGFyKiBjb250ZW50cykgeworICAgIGZpbGVzX1tuYW1lXSA9IGNvbnRlbnRzOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBTb3VyY2VUcmVlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIGNvbnN0IGNoYXIqIGNvbnRlbnRzID0gRmluZFB0ck9yTnVsbChmaWxlc18sIGZpbGVuYW1lKTsKKyAgICBpZiAoY29udGVudHMgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBuZXcgaW86OkFycmF5SW5wdXRTdHJlYW0oY29udGVudHMsIHN0cmxlbihjb250ZW50cykpOworICAgIH0KKyAgfQorCisgIHN0cmluZyBHZXRMYXN0RXJyb3JNZXNzYWdlKCkgeworICAgIHJldHVybiAiRmlsZSBub3QgZm91bmQuIjsKKyAgfQorCisgcHJpdmF0ZToKKyAgaGFzaF9tYXA8c3RyaW5nLCBjb25zdCBjaGFyKj4gZmlsZXNfOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBJbXBvcnRlclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBJbXBvcnRlclRlc3QoKQorICAgIDogaW1wb3J0ZXJfKCZzb3VyY2VfdHJlZV8sICZlcnJvcl9jb2xsZWN0b3JfKSB7fQorCisgIHZvaWQgQWRkRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgc291cmNlX3RyZWVfLkFkZEZpbGUoZmlsZW5hbWUsIHRleHQpOworICB9CisKKyAgLy8gUmV0dXJuIHRoZSBjb2xsZWN0ZWQgZXJyb3IgdGV4dAorICBzdHJpbmcgZXJyb3IoKSBjb25zdCB7IHJldHVybiBlcnJvcl9jb2xsZWN0b3JfLnRleHRfOyB9CisKKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3Rvcl87CisgIE1vY2tTb3VyY2VUcmVlIHNvdXJjZV90cmVlXzsKKyAgSW1wb3J0ZXIgaW1wb3J0ZXJfOworfTsKKworVEVTVF9GKEltcG9ydGVyVGVzdCwgSW1wb3J0KSB7CisgIC8vIFRlc3Qgbm9ybWFsIGltcG9ydGluZy4KKyAgQWRkRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gaW1wb3J0ZXJfLkltcG9ydCgiZm9vLnByb3RvIik7CisgIEVYUEVDVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKDEsIGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKCJGb28iLCBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm5hbWUoKSk7CisKKyAgLy8gSW1wb3J0aW5nIGFnYWluIHNob3VsZCByZXR1cm4gc2FtZSBvYmplY3QuCisgIEVYUEVDVF9FUShmaWxlLCBpbXBvcnRlcl8uSW1wb3J0KCJmb28ucHJvdG8iKSk7Cit9CisKK1RFU1RfRihJbXBvcnRlclRlc3QsIEltcG9ydE5lc3RlZCkgeworICAvLyBUZXN0IHRoYXQgaW1wb3J0aW5nIGEgZmlsZSB3aGljaCBpbXBvcnRzIGFub3RoZXIgZmlsZSB3b3Jrcy4KKyAgQWRkRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiYmFyLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBCYXIgYmFyID0gMTtcbiIKKyAgICAifVxuIik7CisgIEFkZEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHt9XG4iKTsKKworICAvLyBOb3RlIHRoYXQgYm90aCBmaWxlcyBhcmUgYWN0dWFsbHkgcGFyc2VkIGJ5IHRoZSBmaXJzdCBjYWxsIHRvIEltcG9ydCgpCisgIC8vIGhlcmUsIHNpbmNlIGZvby5wcm90byBpbXBvcnRzIGJhci5wcm90by4gIFRoZSBzZWNvbmQgY2FsbCBqdXN0IHJldHVybnMKKyAgLy8gdGhlIHNhbWUgUHJvdG9GaWxlIGZvciBiYXIucHJvdG8gd2hpY2ggd2FzIGNvbnN0cnVjdGVkIHdoaWxlIGltcG9ydGluZworICAvLyBmb28ucHJvdG8uICBXZSB0ZXN0IHRoYXQgdGhpcyBpcyB0aGUgY2FzZSBiZWxvdyBieSBjaGVja2luZyB0aGF0IGJhcgorICAvLyBpcyBhbW9uZyBmb28ncyBkZXBlbmRlbmNpZXMgKGJ5IHBvaW50ZXIpLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vID0gaW1wb3J0ZXJfLkltcG9ydCgiZm9vLnByb3RvIik7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXIgPSBpbXBvcnRlcl8uSW1wb3J0KCJiYXIucHJvdG8iKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKyAgQVNTRVJUX1RSVUUoZm9vICE9IE5VTEwpOworICBBU1NFUlRfVFJVRShiYXIgIT0gTlVMTCk7CisKKyAgLy8gQ2hlY2sgdGhhdCBmb28ncyBkZXBlbmRlbmN5IGlzIHRoZSBzYW1lIG9iamVjdCBhcyBiYXIuCisgIEFTU0VSVF9FUSgxLCBmb28tPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShiYXIsIGZvby0+ZGVwZW5kZW5jeSgwKSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBmb28gcHJvcGVybHkgY3Jvc3MtbGlua3MgYmFyLgorICBBU1NFUlRfRVEoMSwgZm9vLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgIEFTU0VSVF9FUSgxLCBiYXItPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKDEsIGZvby0+bWVzc2FnZV90eXBlKDApLT5maWVsZF9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgZm9vLT5tZXNzYWdlX3R5cGUoMCktPmZpZWxkKDApLT50eXBlKCkpOworICBFWFBFQ1RfRVEoYmFyLT5tZXNzYWdlX3R5cGUoMCksCisgICAgICAgICAgICBmb28tPm1lc3NhZ2VfdHlwZSgwKS0+ZmllbGQoMCktPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworVEVTVF9GKEltcG9ydGVyVGVzdCwgRmlsZU5vdEZvdW5kKSB7CisgIC8vIEVycm9yOiAgUGFyc2luZyBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LgorICBFWFBFQ1RfVFJVRShpbXBvcnRlcl8uSW1wb3J0KCJmb28ucHJvdG8iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX0VRKAorICAgICJmb28ucHJvdG86LTE6MDogRmlsZSBub3QgZm91bmQuXG4iLAorICAgIGVycm9yX2NvbGxlY3Rvcl8udGV4dF8pOworfQorCitURVNUX0YoSW1wb3J0ZXJUZXN0LCBJbXBvcnROb3RGb3VuZCkgeworICAvLyBFcnJvcjogIEltcG9ydGluZyBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LgorICBBZGRGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJiYXIucHJvdG9cIjtcbiIpOworCisgIEVYUEVDVF9UUlVFKGltcG9ydGVyXy5JbXBvcnQoImZvby5wcm90byIpID09IE5VTEwpOworICBFWFBFQ1RfRVEoCisgICAgImJhci5wcm90bzotMTowOiBGaWxlIG5vdCBmb3VuZC5cbiIKKyAgICAiZm9vLnByb3RvOi0xOjA6IEltcG9ydCBcImJhci5wcm90b1wiIHdhcyBub3QgZm91bmQgb3IgaGFkIGVycm9ycy5cbiIsCisgICAgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7Cit9CisKK1RFU1RfRihJbXBvcnRlclRlc3QsIFJlY3Vyc2l2ZUltcG9ydCkgeworICAvLyBFcnJvcjogIFJlY3Vyc2l2ZSBpbXBvcnQuCisgIEFkZEZpbGUoInJlY3Vyc2l2ZTEucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJyZWN1cnNpdmUyLnByb3RvXCI7XG4iKTsKKyAgQWRkRmlsZSgicmVjdXJzaXZlMi5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcInJlY3Vyc2l2ZTEucHJvdG9cIjtcbiIpOworCisgIEVYUEVDVF9UUlVFKGltcG9ydGVyXy5JbXBvcnQoInJlY3Vyc2l2ZTEucHJvdG8iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX0VRKAorICAgICJyZWN1cnNpdmUxLnByb3RvOi0xOjA6IEZpbGUgcmVjdXJzaXZlbHkgaW1wb3J0cyBpdHNlbGY6IHJlY3Vyc2l2ZTEucHJvdG8gIgorICAgICAgIi0+IHJlY3Vyc2l2ZTIucHJvdG8gLT4gcmVjdXJzaXZlMS5wcm90b1xuIgorICAgICJyZWN1cnNpdmUyLnByb3RvOi0xOjA6IEltcG9ydCBcInJlY3Vyc2l2ZTEucHJvdG9cIiB3YXMgbm90IGZvdW5kICIKKyAgICAgICJvciBoYWQgZXJyb3JzLlxuIgorICAgICJyZWN1cnNpdmUxLnByb3RvOi0xOjA6IEltcG9ydCBcInJlY3Vyc2l2ZTIucHJvdG9cIiB3YXMgbm90IGZvdW5kICIKKyAgICAgICJvciBoYWQgZXJyb3JzLlxuIiwKKyAgICBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKK30KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIERpc2tTb3VyY2VUcmVlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBkaXJuYW1lc18ucHVzaF9iYWNrKFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3RfcHJvdG8yX2ltcG9ydF9wYXRoXzEiKTsKKyAgICBkaXJuYW1lc18ucHVzaF9iYWNrKFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3RfcHJvdG8yX2ltcG9ydF9wYXRoXzIiKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGlybmFtZXNfLnNpemUoKTsgaSsrKSB7CisgICAgICBpZiAoRmlsZUV4aXN0cyhkaXJuYW1lc19baV0pKSB7CisgICAgICAgIEZpbGU6OkRlbGV0ZVJlY3Vyc2l2ZWx5KGRpcm5hbWVzX1tpXSwgTlVMTCwgTlVMTCk7CisgICAgICB9CisgICAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6Q3JlYXRlRGlyKGRpcm5hbWVzX1tpXSwgMDc3NykpOworICAgIH0KKyAgfQorCisgIHZpcnR1YWwgdm9pZCBUZWFyRG93bigpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRpcm5hbWVzXy5zaXplKCk7IGkrKykgeworICAgICAgaWYgKEZpbGVFeGlzdHMoZGlybmFtZXNfW2ldKSkgeworICAgICAgICBGaWxlOjpEZWxldGVSZWN1cnNpdmVseShkaXJuYW1lc19baV0sIE5VTEwsIE5VTEwpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHZvaWQgQWRkRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBjaGFyKiBjb250ZW50cykgeworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhmaWxlbmFtZSwgY29udGVudHMsIHRydWUpKTsKKyAgfQorCisgIHZvaWQgQWRkU3ViZGlyKGNvbnN0IHN0cmluZyYgZGlybmFtZSkgeworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpDcmVhdGVEaXIoZGlybmFtZSwgMDc3NykpOworICB9CisKKyAgdm9pZCBFeHBlY3RGaWxlQ29udGVudHMoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfY29udGVudHMpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weUlucHV0U3RyZWFtPiBpbnB1dChzb3VyY2VfdHJlZV8uT3BlbihmaWxlbmFtZSkpOworCisgICAgQVNTRVJUX0ZBTFNFKGlucHV0ID09IE5VTEwpOworCisgICAgLy8gUmVhZCBhbGwgdGhlIGRhdGEgZnJvbSB0aGUgZmlsZS4KKyAgICBzdHJpbmcgZmlsZV9jb250ZW50czsKKyAgICBjb25zdCB2b2lkKiBkYXRhOworICAgIGludCBzaXplOworICAgIHdoaWxlIChpbnB1dC0+TmV4dCgmZGF0YSwgJnNpemUpKSB7CisgICAgICBmaWxlX2NvbnRlbnRzLmFwcGVuZChyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihkYXRhKSwgc2l6ZSk7CisgICAgfQorCisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2NvbnRlbnRzLCBmaWxlX2NvbnRlbnRzKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0Q2Fubm90T3BlbkZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVycm9yX21lc3NhZ2UpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weUlucHV0U3RyZWFtPiBpbnB1dChzb3VyY2VfdHJlZV8uT3BlbihmaWxlbmFtZSkpOworICAgIEVYUEVDVF9UUlVFKGlucHV0ID09IE5VTEwpOworICAgIEVYUEVDVF9FUShlcnJvcl9tZXNzYWdlLCBzb3VyY2VfdHJlZV8uR2V0TGFzdEVycm9yTWVzc2FnZSgpKTsKKyAgfQorCisgIERpc2tTb3VyY2VUcmVlIHNvdXJjZV90cmVlXzsKKworICAvLyBQYXRocyBvZiB0d28gb24tZGlzayBkaXJlY3RvcmllcyB0byB1c2UgZHVyaW5nIHRoZSB0ZXN0LgorICB2ZWN0b3I8c3RyaW5nPiBkaXJuYW1lc187Cit9OworCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBNYXBSb290KSB7CisgIC8vIFRlc3Qgb3BlbmluZyBhIGZpbGUgaW4gYSBkaXJlY3RvcnkgdGhhdCBpcyBtYXBwZWQgdG8gdGhlIHJvb3Qgb2YgdGhlCisgIC8vIHNvdXJjZSB0cmVlLgorICBBZGRGaWxlKGRpcm5hbWVzX1swXSArICIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiIiwgZGlybmFtZXNfWzBdKTsKKworICBFeHBlY3RGaWxlQ29udGVudHMoImZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoImJhciIsICJGaWxlIG5vdCBmb3VuZC4iKTsKK30KKworVEVTVF9GKERpc2tTb3VyY2VUcmVlVGVzdCwgTWFwRGlyZWN0b3J5KSB7CisgIC8vIFRlc3Qgb3BlbmluZyBhIGZpbGUgaW4gYSBkaXJlY3RvcnkgdGhhdCBpcyBtYXBwZWQgdG8gc29tZXdoZXJlIG90aGVyCisgIC8vIHRoYW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlLgorCisgIEFkZEZpbGUoZGlybmFtZXNfWzBdICsgIi9mb28iLCAiSGVsbG8gV29ybGQhIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJiYXoiLCBkaXJuYW1lc19bMF0pOworCisgIEV4cGVjdEZpbGVDb250ZW50cygiYmF6L2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoImJhei9iYXIiLCAiRmlsZSBub3QgZm91bmQuIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJmb28iLCAiRmlsZSBub3QgZm91bmQuIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXIiLCAiRmlsZSBub3QgZm91bmQuIik7CisKKyAgLy8gTm9uLWNhbm9uaWNhbCBmaWxlIG5hbWVzIHNob3VsZCBub3Qgd29yay4KKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoImJhei8vZm9vIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIkJhY2tzbGFzaGVzLCBjb25zZWN1dGl2ZSBzbGFzaGVzLCBcIi5cIiwgb3IgXCIuLlwiIGFyZSAiCisgICAgICAgICAgICAgICAgICAgICAgICJub3QgYWxsb3dlZCBpbiB0aGUgdmlydHVhbCBwYXRoIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXovLi4vYmF6L2ZvbyIsCisgICAgICAgICAgICAgICAgICAgICAgICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiBhcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCIpOworICBFeHBlY3RDYW5ub3RPcGVuRmlsZSgiYmF6Ly4vZm9vIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIkJhY2tzbGFzaGVzLCBjb25zZWN1dGl2ZSBzbGFzaGVzLCBcIi5cIiwgb3IgXCIuLlwiIGFyZSAiCisgICAgICAgICAgICAgICAgICAgICAgICJub3QgYWxsb3dlZCBpbiB0aGUgdmlydHVhbCBwYXRoIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXovZm9vLyIsICJGaWxlIG5vdCBmb3VuZC4iKTsKK30KKworVEVTVF9GKERpc2tTb3VyY2VUcmVlVGVzdCwgTm9QYXJlbnQpIHsKKyAgLy8gVGVzdCB0aGF0IHdlIGNhbm5vdCBvcGVuIGZpbGVzIGluIGEgcGFyZW50IG9mIGEgbWFwcGVkIGRpcmVjdG9yeS4KKworICBBZGRGaWxlKGRpcm5hbWVzX1swXSArICIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworICBBZGRTdWJkaXIoZGlybmFtZXNfWzBdICsgIi9iYXIiKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2Jhci9iYXoiLCAiQmxhaC4iKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoIiIsIGRpcm5hbWVzX1swXSArICIvYmFyIik7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJiYXoiLCAiQmxhaC4iKTsKKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoIi4uL2ZvbyIsCisgICAgICAgICAgICAgICAgICAgICAgICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiBhcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCIpOworICBFeHBlY3RDYW5ub3RPcGVuRmlsZSgiLi4vYmFyL2JheiIsCisgICAgICAgICAgICAgICAgICAgICAgICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiBhcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCIpOworfQorCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBNYXBGaWxlKSB7CisgIC8vIFRlc3Qgb3BlbmluZyBhIGZpbGUgdGhhdCBpcyBtYXBwZWQgZGlyZWN0bHkgaW50byB0aGUgc291cmNlIHRyZWUuCisKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoImZvbyIsIGRpcm5hbWVzX1swXSArICIvZm9vIik7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJmb28iLCAiSGVsbG8gV29ybGQhIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXIiLCAiRmlsZSBub3QgZm91bmQuIik7Cit9CisKK1RFU1RfRihEaXNrU291cmNlVHJlZVRlc3QsIFNlYXJjaE11bHRpcGxlRGlyZWN0b3JpZXMpIHsKKyAgLy8gVGVzdCBtYXBwaW5nIGFuZCBzZWFyY2hpbmcgbXVsdGlwbGUgZGlyZWN0b3JpZXMuCisKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMV0gKyAiL2ZvbyIsICJUaGlzIGZpbGUgc2hvdWxkIGJlIGhpZGRlbi4iKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMV0gKyAiL2JhciIsICJHb29kYnllIFdvcmxkISIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiIiwgZGlybmFtZXNfWzBdKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoIiIsIGRpcm5hbWVzX1sxXSk7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJmb28iLCAiSGVsbG8gV29ybGQhIik7CisgIEV4cGVjdEZpbGVDb250ZW50cygiYmFyIiwgIkdvb2RieWUgV29ybGQhIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXoiLCAiRmlsZSBub3QgZm91bmQuIik7Cit9CisKK1RFU1RfRihEaXNrU291cmNlVHJlZVRlc3QsIE9yZGVyaW5nVHJ1bXBzU3BlY2lmaWNpdHkpIHsKKyAgLy8gVGVzdCB0aGF0IGRpcmVjdG9yaWVzIGFyZSBhbHdheXMgc2VhcmNoZWQgaW4gb3JkZXIsIGV2ZW4gd2hlbiBhIGxhdHRlcgorICAvLyBkaXJlY3RvcnkgaXMgbW9yZS1zcGVjaWZpYyB0aGFuIGEgZm9ybWVyIG9uZS4KKworICAvLyBDcmVhdGUgdGhlICJiYXIiIGRpcmVjdG9yeSBzbyB3ZSBjYW4gcHV0IGEgZmlsZSBpbiBpdC4KKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkNyZWF0ZURpcihkaXJuYW1lc19bMF0gKyAiL2JhciIsIDA3NzcpKTsKKworICAvLyBBZGQgZmlsZXMgYW5kIG1hcCBwYXRocy4KKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2Jhci9mb28iLCAiSGVsbG8gV29ybGQhIik7CisgIEFkZEZpbGUoZGlybmFtZXNfWzFdICsgIi9mb28iLCAiVGhpcyBmaWxlIHNob3VsZCBiZSBoaWRkZW4uIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCIiLCBkaXJuYW1lc19bMF0pOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiYmFyIiwgZGlybmFtZXNfWzFdKTsKKworICAvLyBDaGVjay4KKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJiYXIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworfQorCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBEaXNrRmlsZVRvVmlydHVhbEZpbGUpIHsKKyAgLy8gVGVzdCBEaXNrRmlsZVRvVmlydHVhbEZpbGUuCisKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMV0gKyAiL2ZvbyIsICJUaGlzIGZpbGUgc2hvdWxkIGJlIGhpZGRlbi4iKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoImJhciIsIGRpcm5hbWVzX1swXSk7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJiYXIiLCBkaXJuYW1lc19bMV0pOworCisgIHN0cmluZyB2aXJ0dWFsX2ZpbGU7CisgIHN0cmluZyBzaGFkb3dpbmdfZGlza19maWxlOworCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6Tk9fTUFQUElORywKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgIi9mb28iLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6U0hBRE9XRUQsCisgICAgc291cmNlX3RyZWVfLkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgIGRpcm5hbWVzX1sxXSArICIvZm9vIiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJiYXIvZm9vIiwgdmlydHVhbF9maWxlKTsKKyAgRVhQRUNUX0VRKGRpcm5hbWVzX1swXSArICIvZm9vIiwgc2hhZG93aW5nX2Rpc2tfZmlsZSk7CisKKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgZGlybmFtZXNfWzFdICsgIi9iYXoiLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoImJhci9iYXoiLCB2aXJ0dWFsX2ZpbGUpOworCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6U1VDQ0VTUywKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgZGlybmFtZXNfWzBdICsgIi9mb28iLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoImJhci9mb28iLCB2aXJ0dWFsX2ZpbGUpOworfQorCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBEaXNrRmlsZVRvVmlydHVhbEZpbGVDYW5vbmljYWxpemF0aW9uKSB7CisgIC8vIFRlc3QgaGFuZGxpbmcgb2YgIi4uIiwgIi4iLCBldGMuIGluIERpc2tGaWxlVG9WaXJ0dWFsRmlsZSgpLgorCisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJkaXIxIiwgIi4uIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJkaXIyIiwgIi4uLy4uL2ZvbyIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiZGlyMyIsICIuL2Zvby9iYXIvLiIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiZGlyNCIsICIuIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCIiLCAiL3F1eCIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiZGlyNSIsICIvcXV1eC8iKTsKKworICBzdHJpbmcgdmlydHVhbF9maWxlOworICBzdHJpbmcgc2hhZG93aW5nX2Rpc2tfZmlsZTsKKworICAvLyAiLi4vLi4iIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCB0byBiZSB1bmRlciAiLi4iLgorICBFWFBFQ1RfRVEoRGlza1NvdXJjZVRyZWU6Ok5PX01BUFBJTkcsCisgICAgc291cmNlX3RyZWVfLkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgICIuLi8uLi9iYXoiLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworCisgIC8vICIvZm9vIiBpcyBub3QgbWFwcGVkIChpdCBzaG91bGQgbm90IGJlIG1pc2ludGVwcmV0ZWQgYXMgYmVpbmcgdW5kZXIgIi4iKS4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpOT19NQVBQSU5HLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiL2ZvbyIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisKKyNpZmRlZiBXSU4zMgorICAvLyAiQzpcZm9vIiBpcyBub3QgbWFwcGVkIChpdCBzaG91bGQgbm90IGJlIG1pc2ludGVwcmV0ZWQgYXMgYmVpbmcgdW5kZXIgIi4iKS4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpOT19NQVBQSU5HLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiQzpcXGZvbyIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisjZW5kaWYgIC8vIFdJTjMyCisKKyAgLy8gQnV0ICIuLi9iYXoiIHNob3VsZCBiZS4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgIi4uL2JheiIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisgIEVYUEVDVF9FUSgiZGlyMS9iYXoiLCB2aXJ0dWFsX2ZpbGUpOworCisgIC8vICIuLi8uLi9mb28vYmF6IiBpcyB1bmRlciAiLi4vLi4vZm9vIi4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgIi4uLy4uL2Zvby9iYXoiLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoImRpcjIvYmF6IiwgdmlydHVhbF9maWxlKTsKKworICAvLyAiZm9vLy4vYmFyL2JheiIgaXMgdW5kZXIgIi4vZm9vL2Jhci8uIi4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgImZvby9iYXIvYmF6IiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJkaXIzL2JheiIsIHZpcnR1YWxfZmlsZSk7CisKKyAgLy8gImJhciIgaXMgdW5kZXIgIi4iLgorICBFWFBFQ1RfRVEoRGlza1NvdXJjZVRyZWU6OkNBTk5PVF9PUEVOLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiYmFyIiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJkaXI0L2JhciIsIHZpcnR1YWxfZmlsZSk7CisKKyAgLy8gIi9xdXgvYmF6IiBpcyB1bmRlciAiL3F1eCIuCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6Q0FOTk9UX09QRU4sCisgICAgc291cmNlX3RyZWVfLkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgICIvcXV4L2JheiIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgdmlydHVhbF9maWxlKTsKKworICAvLyAiL3F1dXgvYmFyIiBpcyB1bmRlciAiL3F1dXgiLgorICBFWFBFQ1RfRVEoRGlza1NvdXJjZVRyZWU6OkNBTk5PVF9PUEVOLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiL3F1dXgvYmFyIiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJkaXI1L2JhciIsIHZpcnR1YWxfZmlsZSk7Cit9CisKK1RFU1RfRihEaXNrU291cmNlVHJlZVRlc3QsIFZpcnR1YWxGaWxlVG9EaXNrRmlsZSkgeworICAvLyBUZXN0IFZpcnR1YWxGaWxlVG9EaXNrRmlsZS4KKworICBBZGRGaWxlKGRpcm5hbWVzX1swXSArICIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworICBBZGRGaWxlKGRpcm5hbWVzX1sxXSArICIvZm9vIiwgIlRoaXMgZmlsZSBzaG91bGQgYmUgaGlkZGVuLiIpOworICBBZGRGaWxlKGRpcm5hbWVzX1sxXSArICIvcXV1eCIsICJUaGlzIGZpbGUgc2hvdWxkIG5vdCBiZSBoaWRkZW4uIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJiYXIiLCBkaXJuYW1lc19bMF0pOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiYmFyIiwgZGlybmFtZXNfWzFdKTsKKworICAvLyBFeGlzdGVudCBmaWxlcywgc2hhZG93ZWQgYW5kIG5vbi1zaGFkb3dlZCBjYXNlLgorICBzdHJpbmcgZGlza19maWxlOworICBFWFBFQ1RfVFJVRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXIvZm9vIiwgJmRpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoZGlybmFtZXNfWzBdICsgIi9mb28iLCBkaXNrX2ZpbGUpOworICBFWFBFQ1RfVFJVRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXIvcXV1eCIsICZkaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKGRpcm5hbWVzX1sxXSArICIvcXV1eCIsIGRpc2tfZmlsZSk7CisKKyAgLy8gTm9uZXhpc3RlbnQgZmlsZSBpbiBleGlzdGVudCBkaXJlY3RvcnkgYW5kIHZpY2UgdmVyc2EuCisgIHN0cmluZyBub3RfdG91Y2hlZCA9ICJub3QgdG91Y2hlZCI7CisgIEVYUEVDVF9GQUxTRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXIvYmF6IiwgJm5vdF90b3VjaGVkKSk7CisgIEVYUEVDVF9FUSgibm90IHRvdWNoZWQiLCBub3RfdG91Y2hlZCk7CisgIEVYUEVDVF9GQUxTRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXovZm9vIiwgJm5vdF90b3VjaGVkKSk7CisgIEVYUEVDVF9FUSgibm90IHRvdWNoZWQiLCBub3RfdG91Y2hlZCk7CisKKyAgLy8gQWNjZXB0IE5VTEwgYXMgb3V0cHV0IHBhcmFtZXRlci4KKyAgRVhQRUNUX1RSVUUoc291cmNlX3RyZWVfLlZpcnR1YWxGaWxlVG9EaXNrRmlsZSgiYmFyL2ZvbyIsIE5VTEwpKTsKKyAgRVhQRUNUX0ZBTFNFKHNvdXJjZV90cmVlXy5WaXJ0dWFsRmlsZVRvRGlza0ZpbGUoImJhei9mb28iLCBOVUxMKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QyMWZlNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuY2MKQEAgLTAsMCArMSwxOTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitDb250ZXh0OjpDb250ZXh0KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKQorICAgIDogbmFtZV9yZXNvbHZlcl8obmV3IENsYXNzTmFtZVJlc29sdmVyKSB7CisgIEluaXRpYWxpemVGaWVsZEdlbmVyYXRvckluZm8oZmlsZSk7Cit9CisKK0NvbnRleHQ6On5Db250ZXh0KCkgeworfQorCitDbGFzc05hbWVSZXNvbHZlciogQ29udGV4dDo6R2V0TmFtZVJlc29sdmVyKCkgeworICByZXR1cm4gbmFtZV9yZXNvbHZlcl8uZ2V0KCk7Cit9CisKK25hbWVzcGFjZSB7CisvLyBXaGV0aGVyIHR3byBmaWVsZHMgaGF2ZSBjb25mbGljdGluZyBhY2Nlc3NvcnMgKGFzc3VtaW5nIG5hbWUxIGFuZCBuYW1lMgorLy8gYXJlIGRpZmZlcmVudCkuIG5hbWUxIGFuZCBuYW1lMiBhcmUgZmllbGQxIGFuZCBmaWVsZDIncyBjYW1lbC1jYXNlIG5hbWUKKy8vIHJlc3BlY3RpdmVseS4KK2Jvb2wgSXNDb25mbGljdGluZyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMSwgY29uc3Qgc3RyaW5nJiBuYW1lMSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMiwgY29uc3Qgc3RyaW5nJiBuYW1lMiwKKyAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGluZm8pIHsKKyAgaWYgKGZpZWxkMS0+aXNfcmVwZWF0ZWQoKSkgeworICAgIGlmIChmaWVsZDItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIC8vIEJvdGggZmllbGRzIGFyZSByZXBlYXRlZC4KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gZmllbGQxIGlzIHJlcGVhdGVkLCBhbmQgZmllbGQyIGlzIG5vdC4KKyAgICAgIGlmIChuYW1lMSArICJDb3VudCIgPT0gbmFtZTIpIHsKKyAgICAgICAgKmluZm8gPSAiYm90aCByZXBlYXRlZCBmaWVsZCBcIiIgKyBmaWVsZDEtPm5hbWUoKSArICJcIiBhbmQgc2luZ3VsYXIgIiArCisgICAgICAgICAgICAiZmllbGQgXCIiICsgZmllbGQyLT5uYW1lKCkgKyAiXCIgZ2VuZXJhdGVzIHRoZSBtZXRob2QgXCIiICsKKyAgICAgICAgICAgICJnZXQiICsgbmFtZTEgKyAiQ291bnQoKVwiIjsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAobmFtZTEgKyAiTGlzdCIgPT0gbmFtZTIpIHsKKyAgICAgICAgKmluZm8gPSAiYm90aCByZXBlYXRlZCBmaWVsZCBcIiIgKyBmaWVsZDEtPm5hbWUoKSArICJcIiBhbmQgc2luZ3VsYXIgIiArCisgICAgICAgICAgICAiZmllbGQgXCIiICsgZmllbGQyLT5uYW1lKCkgKyAiXCIgZ2VuZXJhdGVzIHRoZSBtZXRob2QgXCIiICsKKyAgICAgICAgICAgICJnZXQiICsgbmFtZTEgKyAiTGlzdCgpXCIiOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIC8vIFdlbGwsIHRoZXJlIGFyZSBvYnZpb3VzbHkgbWFueSBtb3JlIGNvbmZsaWN0aW5nIGNhc2VzLCBidXQgaXQgcHJvYmFibHkKKyAgICAgIC8vIGRvZXNuJ3Qgd29ydGggdGhlIGVmZm9ydCB0byBleGhhdXN0IGFsbCBvZiB0aGVtIGJlY2F1c2UgdGhleSByYXJlbHkKKyAgICAgIC8vIGhhcHBlbiBhbmQgYXMgd2UgYXJlIGNvbnRpbnVpbmcgYWRkaW5nIG5ldyBtZXRob2RzL2NoYW5naW5nIGV4aXN0aW5nCisgICAgICAvLyBtZXRob2RzIHRoZSBudW1iZXIgb2YgZGlmZmVyZW50IGNvbmZsaWN0aW5nIGNhc2VzIHdpbGwga2VlcCBncm93aW5nLgorICAgICAgLy8gV2UgY2FuIGp1c3QgYWRkIG1vcmUgY2FzZXMgaGVyZSB3aGVuIHRoZXkgYXJlIGZvdW5kIGluIHRoZSByZWFsIHdvcmxkLgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZmllbGQyLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICByZXR1cm4gSXNDb25mbGljdGluZyhmaWVsZDIsIG5hbWUyLCBmaWVsZDEsIG5hbWUxLCBpbmZvKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTm9uZSBvZiB0aGUgdHdvIGZpZWxkcyBhcmUgcmVwZWF0ZWQuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9Cit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBDb250ZXh0OjpJbml0aWFsaXplRmllbGRHZW5lcmF0b3JJbmZvKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEluaXRpYWxpemVGaWVsZEdlbmVyYXRvckluZm9Gb3JNZXNzYWdlKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KK30KKwordm9pZCBDb250ZXh0OjpJbml0aWFsaXplRmllbGRHZW5lcmF0b3JJbmZvRm9yTWVzc2FnZSgKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0Zvck1lc3NhZ2UobWVzc2FnZS0+bmVzdGVkX3R5cGUoaSkpOworICB9CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgZmllbGRzLnB1c2hfYmFjayhtZXNzYWdlLT5maWVsZChpKSk7CisgIH0KKyAgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0ZvckZpZWxkcyhmaWVsZHMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+b25lb2ZfZGVjbF9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gbWVzc2FnZS0+b25lb2ZfZGVjbChpKTsKKyAgICBPbmVvZkdlbmVyYXRvckluZm8gaW5mbzsKKyAgICBpbmZvLm5hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG9uZW9mLT5uYW1lKCksIGZhbHNlKTsKKyAgICBpbmZvLmNhcGl0YWxpemVkX25hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG9uZW9mLT5uYW1lKCksIHRydWUpOworICAgIG9uZW9mX2dlbmVyYXRvcl9pbmZvX21hcF9bb25lb2ZdID0gaW5mbzsKKyAgfQorfQorCit2b2lkIENvbnRleHQ6OkluaXRpYWxpemVGaWVsZEdlbmVyYXRvckluZm9Gb3JGaWVsZHMoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMpIHsKKyAgLy8gRmluZCBvdXQgYWxsIGZpZWxkcyB0aGF0IGNvbmZsaWN0IHdpdGggc29tZSBvdGhlciBmaWVsZCBpbiB0aGUgc2FtZQorICAvLyBtZXNzYWdlLgorICB2ZWN0b3I8Ym9vbD4gaXNfY29uZmxpY3QoZmllbGRzLnNpemUoKSk7CisgIHZlY3RvcjxzdHJpbmc+IGNvbmZsaWN0X3JlYXNvbihmaWVsZHMuc2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShmaWVsZCk7CisgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgZmllbGRzLnNpemUoKTsgKytqKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG90aGVyID0gZmllbGRzW2pdOworICAgICAgY29uc3Qgc3RyaW5nJiBvdGhlcl9uYW1lID0gVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKG90aGVyKTsKKyAgICAgIGlmIChuYW1lID09IG90aGVyX25hbWUpIHsKKyAgICAgICAgaXNfY29uZmxpY3RbaV0gPSBpc19jb25mbGljdFtqXSA9IHRydWU7CisgICAgICAgIGNvbmZsaWN0X3JlYXNvbltpXSA9IGNvbmZsaWN0X3JlYXNvbltqXSA9CisgICAgICAgICAgICAiY2FwaXRhbGl6ZWQgbmFtZSBvZiBmaWVsZCBcIiIgKyBmaWVsZC0+bmFtZSgpICsKKyAgICAgICAgICAgICJcIiBjb25mbGljdHMgd2l0aCBmaWVsZCBcIiIgKyBvdGhlci0+bmFtZSgpICsgIlwiIjsKKyAgICAgIH0gZWxzZSBpZiAoSXNDb25mbGljdGluZyhmaWVsZCwgbmFtZSwgb3RoZXIsIG90aGVyX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbmZsaWN0X3JlYXNvbltqXSkpIHsKKyAgICAgICAgaXNfY29uZmxpY3RbaV0gPSBpc19jb25mbGljdFtqXSA9IHRydWU7CisgICAgICAgIGNvbmZsaWN0X3JlYXNvbltpXSA9IGNvbmZsaWN0X3JlYXNvbltqXTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKGlzX2NvbmZsaWN0W2ldKSB7CisgICAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJmaWVsZCBcIiIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICJcIiBpcyBjb25mbGljdGluZyAiCisgICAgICAgICAgICAgICAgICAgPDwgIndpdGggYW5vdGhlciBmaWVsZDogIiA8PCBjb25mbGljdF9yZWFzb25baV07CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBGaWVsZEdlbmVyYXRvckluZm8gaW5mbzsKKyAgICBpbmZvLm5hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGZpZWxkKTsKKyAgICBpbmZvLmNhcGl0YWxpemVkX25hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoZmllbGQpOworICAgIC8vIEZvciBmaWVsZHMgY29uZmxpY3Rpbmcgd2l0aCBzb21lIG90aGVyIGZpZWxkcywgd2UgYXBwZW5kIHRoZSBmaWVsZAorICAgIC8vIG51bWJlciB0byB0aGVpciBmaWVsZCBuYW1lcyBpbiBnZW5lcmF0ZWQgY29kZSB0byBhdm9pZCBjb25mbGljdHMuCisgICAgaWYgKGlzX2NvbmZsaWN0W2ldKSB7CisgICAgICBpbmZvLm5hbWUgKz0gU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpOworICAgICAgaW5mby5jYXBpdGFsaXplZF9uYW1lICs9IFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKTsKKyAgICAgIGluZm8uZGlzYW1iaWd1YXRlZF9yZWFzb24gPSBjb25mbGljdF9yZWFzb25baV07CisgICAgfQorICAgIGZpZWxkX2dlbmVyYXRvcl9pbmZvX21hcF9bZmllbGRdID0gaW5mbzsKKyAgfQorfQorCitjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIENvbnRleHQ6OkdldEZpZWxkR2VuZXJhdG9ySW5mbygKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogcmVzdWx0ID0KKyAgICAgIEZpbmRPck51bGwoZmllbGRfZ2VuZXJhdG9yX2luZm9fbWFwXywgZmllbGQpOworICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCBmaW5kIEZpZWxkR2VuZXJhdG9ySW5mbyBmb3IgZmllbGQ6ICIKKyAgICAgICAgICAgICAgIDw8IGZpZWxkLT5mdWxsX25hbWUoKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIENvbnRleHQ6OkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSBjb25zdCB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogcmVzdWx0ID0KKyAgICAgIEZpbmRPck51bGwob25lb2ZfZ2VuZXJhdG9yX2luZm9fbWFwXywgb25lb2YpOworICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCBmaW5kIE9uZW9mR2VuZXJhdG9ySW5mbyBmb3Igb25lb2Y6ICIKKyAgICAgICAgICAgICAgIDw8IG9uZW9mLT5uYW1lKCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWI1OTVkMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaApAQCAtMCwwICsxLDk4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9DT05URVhUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9DT05URVhUX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7CisgIGNsYXNzIEZpZWxkRGVzY3JpcHRvcjsKKyAgY2xhc3MgT25lb2ZEZXNjcmlwdG9yOworICBjbGFzcyBEZXNjcmlwdG9yOworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3N0cnVjdCBGaWVsZEdlbmVyYXRvckluZm87CitzdHJ1Y3QgT25lb2ZHZW5lcmF0b3JJbmZvOworLy8gQSBjb250ZXh0IG9iamVjdCBob2xkcyB0aGUgaW5mb3JtYXRpb24gdGhhdCBpcyBzaGFyZWQgYW1vbmcgYWxsIGNvZGUKKy8vIGdlbmVyYXRvcnMuCitjbGFzcyBDb250ZXh0IHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IENvbnRleHQoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICB+Q29udGV4dCgpOworCisgIC8vIEdldCB0aGUgbmFtZSByZXNvbHZlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb250ZXh0LiBUaGUgcmVzb2x2ZXIKKyAgLy8gY2FuIGJlIHVzZWQgdG8gbWFwIGRlc2NyaXB0b3JzIHRvIEphdmEgY2xhc3MgbmFtZXMuCisgIENsYXNzTmFtZVJlc29sdmVyKiBHZXROYW1lUmVzb2x2ZXIoKTsKKworICAvLyBHZXQgdGhlIEZpZWxkR2VuZXJhdG9ySW5mbyBmb3IgYSBnaXZlbiBmaWVsZC4KKyAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBHZXRGaWVsZEdlbmVyYXRvckluZm8oCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICAvLyBHZXQgdGhlIE9uZW9mR2VuZXJhdG9ySW5mbyBmb3IgYSBnaXZlbiBvbmVvZi4KKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBHZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mbyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisgIHZvaWQgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0Zvck1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSk7CisgIHZvaWQgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0ZvckZpZWxkcygKKyAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgZmllbGRzKTsKKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPENsYXNzTmFtZVJlc29sdmVyPiBuYW1lX3Jlc29sdmVyXzsKKyAgbWFwPGNvbnN0IEZpZWxkRGVzY3JpcHRvciosIEZpZWxkR2VuZXJhdG9ySW5mbz4gZmllbGRfZ2VuZXJhdG9yX2luZm9fbWFwXzsKKyAgbWFwPGNvbnN0IE9uZW9mRGVzY3JpcHRvciosIE9uZW9mR2VuZXJhdG9ySW5mbz4gb25lb2ZfZ2VuZXJhdG9yX2luZm9fbWFwXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvbnRleHQpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfQ09OVEVYVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjYzZjBjOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmNjCkBAIC0wLDAgKzEsMjMzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3N0cmluZyBFc2NhcGVKYXZhZG9jKGNvbnN0IHN0cmluZyYgaW5wdXQpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUoaW5wdXQuc2l6ZSgpICogMik7CisKKyAgY2hhciBwcmV2ID0gJyonOworCisgIGZvciAoc3RyaW5nOjpzaXplX3R5cGUgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgIGNoYXIgYyA9IGlucHV0W2ldOworICAgIHN3aXRjaCAoYykgeworICAgICAgY2FzZSAnKic6CisgICAgICAgIC8vIEF2b2lkICIvKiIuCisgICAgICAgIGlmIChwcmV2ID09ICcvJykgeworICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiYjNDI7Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhjKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJy8nOgorICAgICAgICAvLyBBdm9pZCAiKi8iLgorICAgICAgICBpZiAocHJldiA9PSAnKicpIHsKKyAgICAgICAgICByZXN1bHQuYXBwZW5kKCImIzQ3OyIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soYyk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICdAJzoKKyAgICAgICAgLy8gJ0AnIHN0YXJ0cyBqYXZhZG9jIHRhZ3MgaW5jbHVkaW5nIHRoZSBAZGVwcmVjYXRlZCB0YWcsIHdoaWNoIHdpbGwKKyAgICAgICAgLy8gY2F1c2UgYSBjb21waWxlLXRpbWUgZXJyb3IgaWYgaW5zZXJ0ZWQgYmVmb3JlIGEgZGVjbGFyYXRpb24gdGhhdAorICAgICAgICAvLyBkb2VzIG5vdCBoYXZlIGEgY29ycmVzcG9uZGluZyBARGVwcmVjYXRlZCBhbm5vdGF0aW9uLgorICAgICAgICByZXN1bHQuYXBwZW5kKCImIzY0OyIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJzwnOgorICAgICAgICAvLyBBdm9pZCBpbnRlcnByZXRhdGlvbiBhcyBIVE1MLgorICAgICAgICByZXN1bHQuYXBwZW5kKCImbHQ7Iik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAnPic6CisgICAgICAgIC8vIEF2b2lkIGludGVycHJldGF0aW9uIGFzIEhUTUwuCisgICAgICAgIHJlc3VsdC5hcHBlbmQoIiZndDsiKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICcmJzoKKyAgICAgICAgLy8gQXZvaWQgaW50ZXJwcmV0YXRpb24gYXMgSFRNTC4KKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiJmFtcDsiKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICdcXCc6CisgICAgICAgIC8vIEphdmEgaW50ZXJwcmV0cyBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZXMgYW55d2hlcmUhCisgICAgICAgIHJlc3VsdC5hcHBlbmQoIiYjOTI7Iik7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhjKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgcHJldiA9IGM7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdm9pZCBXcml0ZURvY0NvbW1lbnRCb2R5Rm9yTG9jYXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IFNvdXJjZUxvY2F0aW9uJiBsb2NhdGlvbikgeworICBzdHJpbmcgY29tbWVudHMgPSBsb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzLmVtcHR5KCkgPworICAgICAgbG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMgOiBsb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzOworICBpZiAoIWNvbW1lbnRzLmVtcHR5KCkpIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBJZGVhbGx5IHdlIHNob3VsZCBwYXJzZSB0aGUgY29tbWVudCB0ZXh0IGFzIE1hcmtkb3duIGFuZAorICAgIC8vICAgd3JpdGUgaXQgYmFjayBhcyBIVE1MLCBidXQgdGhpcyByZXF1aXJlcyBhIE1hcmtkb3duIHBhcnNlci4gIEZvciBub3cKKyAgICAvLyAgIHdlIGp1c3QgdXNlIDxwcmU+IHRvIGdldCBmaXhlZC13aWR0aCB0ZXh0IGZvcm1hdHRpbmcuCisKKyAgICAvLyBJZiB0aGUgY29tbWVudCBpdHNlbGYgY29udGFpbnMgYmxvY2sgY29tbWVudCBzdGFydCBvciBlbmQgbWFya2VycywKKyAgICAvLyBIVE1MLWVzY2FwZSB0aGVtIHNvIHRoYXQgdGhleSBkb24ndCBhY2NpZGVudGFsbHkgY2xvc2UgdGhlIGRvYyBjb21tZW50LgorICAgIGNvbW1lbnRzID0gRXNjYXBlSmF2YWRvYyhjb21tZW50cyk7CisKKyAgICB2ZWN0b3I8c3RyaW5nPiBsaW5lcyA9IFNwbGl0KGNvbW1lbnRzLCAiXG4iKTsKKyAgICB3aGlsZSAoIWxpbmVzLmVtcHR5KCkgJiYgbGluZXMuYmFjaygpLmVtcHR5KCkpIHsKKyAgICAgIGxpbmVzLnBvcF9iYWNrKCk7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgKlxuIgorICAgICAgICAiICogPHByZT5cbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGluZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIC8vIE1vc3QgbGluZXMgc2hvdWxkIHN0YXJ0IHdpdGggYSBzcGFjZS4gIFdhdGNoIG91dCBmb3IgbGluZXMgdGhhdCBzdGFydAorICAgICAgLy8gd2l0aCBhIC8sIHNpbmNlIHB1dHRpbmcgdGhhdCByaWdodCBhZnRlciB0aGUgbGVhZGluZyBhc3RlcmlzayB3aWxsCisgICAgICAvLyBjbG9zZSB0aGUgY29tbWVudC4KKyAgICAgIGlmICghbGluZXNbaV0uZW1wdHkoKSAmJiBsaW5lc1tpXVswXSA9PSAnLycpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIiAqICRsaW5lJFxuIiwgImxpbmUiLCBsaW5lc1tpXSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgiICokbGluZSRcbiIsICJsaW5lIiwgbGluZXNbaV0pOworICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiICogPC9wcmU+XG4iKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclR5cGU+CitzdGF0aWMgdm9pZCBXcml0ZURvY0NvbW1lbnRCb2R5KAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yVHlwZSogZGVzY3JpcHRvcikgeworICBTb3VyY2VMb2NhdGlvbiBsb2NhdGlvbjsKKyAgaWYgKGRlc2NyaXB0b3ItPkdldFNvdXJjZUxvY2F0aW9uKCZsb2NhdGlvbikpIHsKKyAgICBXcml0ZURvY0NvbW1lbnRCb2R5Rm9yTG9jYXRpb24ocHJpbnRlciwgbG9jYXRpb24pOworICB9Cit9CisKK3N0YXRpYyBzdHJpbmcgRmlyc3RMaW5lT2YoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICBzdHJpbmcgcmVzdWx0ID0gdmFsdWU7CisKKyAgc3RyaW5nOjpzaXplX3R5cGUgcG9zID0gcmVzdWx0LmZpbmRfZmlyc3Rfb2YoJ1xuJyk7CisgIGlmIChwb3MgIT0gc3RyaW5nOjpucG9zKSB7CisgICAgcmVzdWx0LmVyYXNlKHBvcyk7CisgIH0KKworICAvLyBJZiBsaW5lIGVuZHMgaW4gYW4gb3BlbmluZyBicmFjZSwgbWFrZSBpdCAieyAuLi4gfSIgc28gaXQgbG9va3MgbmljZS4KKyAgaWYgKCFyZXN1bHQuZW1wdHkoKSAmJiByZXN1bHRbcmVzdWx0LnNpemUoKSAtIDFdID09ICd7JykgeworICAgIHJlc3VsdC5hcHBlbmQoIiAuLi4gfSIpOworICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBXcml0ZU1lc3NhZ2VEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICIvKipcbiIKKyAgICAiICogUHJvdG9idWYgdHlwZSB7QGNvZGUgJGZ1bGxuYW1lJH1cbiIsCisgICAgImZ1bGxuYW1lIiwgRXNjYXBlSmF2YWRvYyhtZXNzYWdlLT5mdWxsX25hbWUoKSkpOworICBXcml0ZURvY0NvbW1lbnRCb2R5KHByaW50ZXIsIG1lc3NhZ2UpOworICBwcmludGVyLT5QcmludCgiICovXG4iKTsKK30KKwordm9pZCBXcml0ZUZpZWxkRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAvLyBJbiB0aGVvcnkgd2Ugc2hvdWxkIGhhdmUgc2xpZ2h0bHkgZGlmZmVyZW50IGNvbW1lbnRzIGZvciBzZXR0ZXJzLCBnZXR0ZXJzLAorICAvLyBldGMuLCBidXQgaW4gcHJhY3RpY2UgZXZlcnlvbmUgYWxyZWFkeSBrbm93cyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZXNlCisgIC8vIHNvIGl0J3MgcmVkdW5kYW50IGluZm9ybWF0aW9uLgorCisgIC8vIFdlIHVzZSB0aGUgZmllbGQgZGVjbGFyYXRpb24gYXMgdGhlIGZpcnN0IGxpbmUgb2YgdGhlIGNvbW1lbnQsIGUuZy46CisgIC8vICAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDU7CisgIC8vIFRoaXMgY29tbXVuaWNhdGVzIGEgbG90IG9mIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaWVsZCBpbiBhIHNtYWxsIHNwYWNlLgorICAvLyBJZiB0aGUgZmllbGQgaXMgYSBncm91cCwgdGhlIGRlYnVnIHN0cmluZyBtaWdodCBlbmQgd2l0aCB7LgorICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIDxjb2RlPiRkZWYkPC9jb2RlPlxuIiwKKyAgICAiZGVmIiwgRXNjYXBlSmF2YWRvYyhGaXJzdExpbmVPZihmaWVsZC0+RGVidWdTdHJpbmcoKSkpKTsKKyAgV3JpdGVEb2NDb21tZW50Qm9keShwcmludGVyLCBmaWVsZCk7CisgIHByaW50ZXItPlByaW50KCIgKi9cbiIpOworfQorCit2b2lkIFdyaXRlRW51bURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtXykgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIFByb3RvYnVmIGVudW0ge0Bjb2RlICRmdWxsbmFtZSR9XG4iLAorICAgICJmdWxsbmFtZSIsIEVzY2FwZUphdmFkb2MoZW51bV8tPmZ1bGxfbmFtZSgpKSk7CisgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgZW51bV8pOworICBwcmludGVyLT5QcmludCgiICovXG4iKTsKK30KKwordm9pZCBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIDxjb2RlPiRkZWYkPC9jb2RlPlxuIiwKKyAgICAiZGVmIiwgRXNjYXBlSmF2YWRvYyhGaXJzdExpbmVPZih2YWx1ZS0+RGVidWdTdHJpbmcoKSkpKTsKKyAgV3JpdGVEb2NDb21tZW50Qm9keShwcmludGVyLCB2YWx1ZSk7CisgIHByaW50ZXItPlByaW50KCIgKi9cbiIpOworfQorCit2b2lkIFdyaXRlU2VydmljZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8qKlxuIgorICAgICIgKiBQcm90b2J1ZiBzZXJ2aWNlIHtAY29kZSAkZnVsbG5hbWUkfVxuIiwKKyAgICAiZnVsbG5hbWUiLCBFc2NhcGVKYXZhZG9jKHNlcnZpY2UtPmZ1bGxfbmFtZSgpKSk7CisgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgc2VydmljZSk7CisgIHByaW50ZXItPlByaW50KCIgKi9cbiIpOworfQorCit2b2lkIFdyaXRlTWV0aG9kRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIDxjb2RlPiRkZWYkPC9jb2RlPlxuIiwKKyAgICAiZGVmIiwgRXNjYXBlSmF2YWRvYyhGaXJzdExpbmVPZihtZXRob2QtPkRlYnVnU3RyaW5nKCkpKSk7CisgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgbWV0aG9kKTsKKyAgcHJpbnRlci0+UHJpbnQoIiAqL1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Q5NTM1YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmgKQEAgLTAsMCArMSw2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0RPQ19DT01NRU5UX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9ET0NfQ09NTUVOVF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKwordm9pZCBXcml0ZU1lc3NhZ2VEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKTsKK3ZvaWQgV3JpdGVGaWVsZERvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOwordm9pZCBXcml0ZUVudW1Eb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV8pOwordm9pZCBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSk7Cit2b2lkIFdyaXRlU2VydmljZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UpOwordm9pZCBXcml0ZU1ldGhvZERvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpOworCisvLyBFeHBvc2VkIGZvciB0ZXN0aW5nIG9ubHkuCitMSUJQUk9UT0NfRVhQT1JUIHN0cmluZyBFc2NhcGVKYXZhZG9jKGNvbnN0IHN0cmluZyYgaW5wdXQpOworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9ET0NfQ09NTUVOVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50X3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnRfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWU1ODJlYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50X3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNjcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisKKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworbmFtZXNwYWNlIHsKKworVEVTVChKYXZhRG9jQ29tbWVudFRlc3QsIEVzY2FwaW5nKSB7CisgIEVYUEVDVF9FUSgiZm9vIC8mIzQyOyBiYXIgKiYjNDc7IGJheiIsIEVzY2FwZUphdmFkb2MoImZvbyAvKiBiYXIgKi8gYmF6IikpOworICBFWFBFQ1RfRVEoImZvbyAvJiM0MjsmIzQ3OyBiYXoiLCBFc2NhcGVKYXZhZG9jKCJmb28gLyovIGJheiIpKTsKKyAgRVhQRUNUX0VRKCJ7JiM2NDtmb299IiwgRXNjYXBlSmF2YWRvYygie0Bmb299IikpOworICBFWFBFQ1RfRVEoIiZsdDtpJmd0OyZhbXA7Jmx0Oy9pJmd0OyIsIEVzY2FwZUphdmFkb2MoIjxpPiY8L2k+IikpOworICBFWFBFQ1RfRVEoImZvbyYjOTI7dTEyMzRiYXIiLCBFc2NhcGVKYXZhZG9jKCJmb29cXHUxMjM0YmFyIikpOworICBFWFBFQ1RfRVEoIiYjNjQ7ZGVwcmVjYXRlZCIsIEVzY2FwZUphdmFkb2MoIkBkZXByZWNhdGVkIikpOworfQorCisvLyBUT0RPKGtlbnRvbik6ICBJdCdzIGhhcmQgdG8gd3JpdGUgYSByb2J1c3QgdGVzdCBvZiB0aGUgZG9jIGNvbW1lbnRzIC0tIHdlCisvLyAgIGNhbiBvbmx5IHJlYWxseSBjb21wYXJlIHRoZSBvdXRwdXQgYWdhaW5zdCBhIGdvbGRlbiB2YWx1ZSwgd2hpY2ggaXMgYQorLy8gICBmYWlybHkgdGVkaW91cyBhbmQgZnJhZ2lsZSB0ZXN0aW5nIHN0cmF0ZWd5LiAgSWYgd2Ugd2FudCB0byBnbyB0aGF0IHJvdXRlLAorLy8gICBpdCBwcm9iYWJseSBtYWtlcyBzZW5zZSB0byBiaXRlIHRoZSBidWxsZXQgYW5kIHdyaXRlIGEgdGVzdCB0aGF0IGNvbXBhcmVzCisvLyAgIHRoZSB3aG9sZSBnZW5lcmF0ZWQgb3V0cHV0IGZvciB1bml0dGVzdC5wcm90byBhZ2FpbnN0IGEgZ29sZGVuIHZhbHVlLCB3aXRoCisvLyAgIGEgdmVyeSBzaW1wbGUgc2NyaXB0IHRoYXQgY2FuIGJlIHJ1biB0byByZWdlbmVyYXRlIGl0IHdpdGggdGhlIGxhdGVzdCBjb2RlLgorLy8gICBUaGlzIHdvdWxkIG1lYW4gdGhhdCB1cGRhdGVzIHRvIHRoZSBnb2xkZW4gZmlsZSB3b3VsZCBoYXZlIHRvIGJlIGluY2x1ZGVkCisvLyAgIGluIGFueSBjaGFuZ2UgdG8gdGhlIGNvZGUgZ2VuZXJhdG9yLCB3aGljaCB3b3VsZCBhY3R1YWxseSBiZSBmYWlybHkgdXNlZnVsCisvLyAgIGFzIGl0IGFsbG93cyB0aGUgcmV2aWV3ZXIgdG8gc2VlIGNsZWFybHkgaG93IHRoZSBnZW5lcmF0ZWQgY29kZSBpcworLy8gICBjaGFuZ2luZy4KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNTNiNjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjCkBAIC0wLDAgKzEsMzU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworYm9vbCBFbnVtSGFzQ3VzdG9tT3B0aW9ucyhjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSA+IDApIHJldHVybiB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPnZhbHVlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZGVzY3JpcHRvci0+dmFsdWUoaSk7CisgICAgaWYgKHZhbHVlLT5vcHRpb25zKCkudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorfSAgLy8gbmFtZXNwYWNlCisKK0VudW1HZW5lcmF0b3I6OkVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlX2FwaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgaW1tdXRhYmxlX2FwaV8oaW1tdXRhYmxlX2FwaSksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpICB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZGVzY3JpcHRvcl8tPnZhbHVlKGkpOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGNhbm9uaWNhbF92YWx1ZSA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUtPm51bWJlcigpKTsKKworICAgIGlmICh2YWx1ZSA9PSBjYW5vbmljYWxfdmFsdWUpIHsKKyAgICAgIGNhbm9uaWNhbF92YWx1ZXNfLnB1c2hfYmFjayh2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEFsaWFzIGFsaWFzOworICAgICAgYWxpYXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgIGFsaWFzLmNhbm9uaWNhbF92YWx1ZSA9IGNhbm9uaWNhbF92YWx1ZTsKKyAgICAgIGFsaWFzZXNfLnB1c2hfYmFjayhhbGlhcyk7CisgICAgfQorICB9Cit9CisKK0VudW1HZW5lcmF0b3I6On5FbnVtR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBXcml0ZUVudW1Eb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBlbnVtICRjbGFzc25hbWUkXG4iCisgICAgICAiICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGVudW0gJGNsYXNzbmFtZSRcbiIKKyAgICAgICIgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0KKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjYW5vbmljYWxfdmFsdWVzXy5zaXplKCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJuYW1lIl0gPSBjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpOworICAgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5pbmRleCgpKTsKKyAgICB2YXJzWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoY2Fub25pY2FsX3ZhbHVlc19baV0tPm51bWJlcigpKTsKKyAgICBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc19baV0pOworICAgIGlmIChjYW5vbmljYWxfdmFsdWVzX1tpXS0+b3B0aW9ucygpLmRlcHJlY2F0ZWQoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIkBqYXZhLmxhbmcuRGVwcmVjYXRlZFxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJG5hbWUkKCRpbmRleCQsICRudW1iZXIkKSxcbiIpOworICB9CisKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIlVOUkVDT0dOSVpFRCgtMSwgLTEpLFxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiO1xuIgorICAgICJcbiIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGlhc2VzXy5zaXplKCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJjbGFzc25hbWUiXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgICAgdmFyc1sibmFtZSJdID0gYWxpYXNlc19baV0udmFsdWUtPm5hbWUoKTsKKyAgICB2YXJzWyJjYW5vbmljYWxfbmFtZSJdID0gYWxpYXNlc19baV0uY2Fub25pY2FsX3ZhbHVlLT5uYW1lKCk7CisgICAgV3JpdGVFbnVtVmFsdWVEb2NDb21tZW50KHByaW50ZXIsIGFsaWFzZXNfW2ldLnZhbHVlKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgJGNsYXNzbmFtZSQgJG5hbWUkID0gJGNhbm9uaWNhbF9uYW1lJDtcbiIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbIm5hbWUiXSA9IGRlc2NyaXB0b3JfLT52YWx1ZShpKS0+bmFtZSgpOworICAgIHZhcnNbIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm51bWJlcigpKTsKKyAgICBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8tPnZhbHVlKGkpKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRuYW1lJF9WQUxVRSA9ICRudW1iZXIkO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkge1xuIik7CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgaWYgKGluZGV4ID09IC0xKSB7XG4iCisgICAgICAiICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFxuIgorICAgICAgIiAgICAgICAgXCJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuXCIpO1xuIgorICAgICAgIiAgfVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuIHZhbHVlO1xuIgorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHZhbHVlT2YoaW50IHZhbHVlKSB7XG4iCisgICAgIiAgc3dpdGNoICh2YWx1ZSkge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGNhbm9uaWNhbF92YWx1ZXNfLnNpemUoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY2FzZSAkbnVtYmVyJDogcmV0dXJuICRuYW1lJDtcbiIsCisgICAgICAibmFtZSIsIGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5uYW1lKCksCisgICAgICAibnVtYmVyIiwgU2ltcGxlSXRvYShjYW5vbmljYWxfdmFsdWVzX1tpXS0+bnVtYmVyKCkpKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICAgIGRlZmF1bHQ6IHJldHVybiBudWxsO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAicHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPCRjbGFzc25hbWUkPlxuIgorICAgICIgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDtcbiIKKyAgICAifVxuIgorICAgICJwcml2YXRlIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPCRjbGFzc25hbWUkPlxuIgorICAgICIgICAgaW50ZXJuYWxWYWx1ZU1hcCA9XG4iCisgICAgIiAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPCRjbGFzc25hbWUkPigpIHtcbiIKKyAgICAiICAgICAgICBwdWJsaWMgJGNsYXNzbmFtZSQgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikge1xuIgorICAgICIgICAgICAgICAgcmV0dXJuICRjbGFzc25hbWUkLnZhbHVlT2YobnVtYmVyKTtcbiIKKyAgICAiICAgICAgICB9XG4iCisgICAgIiAgICAgIH07XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gUmVmbGVjdGlvbgorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yXG4iCisgICAgICAiICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHtcbiIKKyAgICAgICIgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KGluZGV4KTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAicHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3JcbiIKKyAgICAgICIgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7XG4iCisgICAgICAiICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3JcbiIKKyAgICAgICIgICAgZ2V0RGVzY3JpcHRvcigpIHtcbiIpOworCisgICAgLy8gVE9ETyhrZW50b24pOiAgQ2FjaGUgc3RhdGljYWxseT8gIE5vdGUgdGhhdCB3ZSBjYW4ndCBhY2Nlc3MgZGVzY3JpcHRvcnMKKyAgICAvLyAgIGF0IG1vZHVsZSBpbml0IHRpbWUgYmVjYXVzZSBpdCB3b3VsZG4ndCB3b3JrIHdpdGggZGVzY3JpcHRvci5wcm90bywgYnV0CisgICAgLy8gICB3ZSBjYW4gY2FjaGUgdGhlIHZhbHVlIHRoZSBmaXJzdCB0aW1lIGdldERlc2NyaXB0b3IoKSBpcyBjYWxsZWQuCisgICAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSA9PSBOVUxMKSB7CisgICAgICBpZiAoIU11bHRpcGxlSmF2YUZpbGVzKGRlc2NyaXB0b3JfLT5maWxlKCksIGltbXV0YWJsZV9hcGlfKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICByZXR1cm4gJGZpbGUkLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoJGluZGV4JCk7XG4iLAorICAgICAgICAgICJmaWxlIiwgbmFtZV9yZXNvbHZlcl8tPkdldENsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW11dGFibGVfYXBpXyksCisgICAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+aW5kZXgoKSkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgIGlmIChFbnVtSGFzQ3VzdG9tT3B0aW9ucyhkZXNjcmlwdG9yXykpIHsKKyAgICAgICAgICAvLyBXZSBuZWVkIHRvIGxvYWQgdGhlIGltbXV0YWJsZSBjbGFzc2VzIGluIG9yZGVyIHRvIHBhcnNlIGN1c3RvbQorICAgICAgICAgIC8vIG9wdGlvbnMuIEhvd2V2ZXIsIHNpbmNlIGZpbGUgbGV2ZWwgZW51bXMgKG5vIG91dGVyIGNsYXNzKSBhcmUKKyAgICAgICAgICAvLyBzaGFyZWQgYnkgaW1tdXRhYmxlIGNvZGUgYW5kIG11dGFibGUgY29kZSwgdGhlIGltbXV0YWJsZSBjbGFzc2VzCisgICAgICAgICAgLy8gbWF5IG5vdCBleGlzdC4gU28gd2UgdHJ5IHRvIHVzZSBKYXZhIHJlZmxlY3Rpb24gdG8gcmV0cmlldmUgdGhlCisgICAgICAgICAgLy8gZGVzY3JpcHRvciBmcm9tIGltbXV0YWJsZSBjbGFzc2VzLgorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgInRyeSB7XG4iCisgICAgICAgICAgICAiICBqYXZhLmxhbmcuQ2xhc3MgaW1tdXRhYmxlRmlsZUNsYXNzID1cbiIKKyAgICAgICAgICAgICIgICAgICBqYXZhLmxhbmcuQ2xhc3MuZm9yTmFtZShcIiRpbW11dGFibGVfZmlsZV9jbGFzc19uYW1lJFwiKTtcbiIKKyAgICAgICAgICAgICIgIEBqYXZhLmxhbmcuU3VwcHJlc3NXYXJuaW5ncyhcInVuY2hlY2tlZFwiKVxuIgorICAgICAgICAgICAgIiAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG0gPVxuIgorICAgICAgICAgICAgIiAgICAgIGltbXV0YWJsZUZpbGVDbGFzcy5nZXRNZXRob2QoXCJnZXREZXNjcmlwdG9yXCIpO1xuIgorICAgICAgICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvciBmaWxlID1cbiIKKyAgICAgICAgICAgICIgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcilcbiIKKyAgICAgICAgICAgICIgICAgICAgICAgbS5pbnZva2UoaW1tdXRhYmxlRmlsZUNsYXNzKTtcbiIKKyAgICAgICAgICAgICIgIHJldHVybiBmaWxlLmdldEVudW1UeXBlcygpLmdldCgkaW5kZXgkKTtcbiIKKyAgICAgICAgICAgICJ9IGNhdGNoIChFeGNlcHRpb24gZSkge1xuIgorICAgICAgICAgICAgLy8gSW1tdXRhYmxlIGNsYXNzZXMgY2Fubm90IGJlIGZvdW5kLiBQcm9jZWVkIGFzIGlmIGN1c3RvbSBvcHRpb25zCisgICAgICAgICAgICAvLyBkb24ndCBleGlzdC4KKyAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgImltbXV0YWJsZV9maWxlX2NsYXNzX25hbWUiLAorICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSwKKyAgICAgICAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpKTsKKyAgICAgICAgfQorICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAicmV0dXJuICRpbW11dGFibGVfcGFja2FnZSQuJGRlc2NyaXB0b3JfY2xhc3MkLiRkZXNjcmlwdG9yJFxuIgorICAgICAgICAgICIgICAgLmdldEVudW1UeXBlcygpLmdldCgkaW5kZXgkKTtcbiIsCisgICAgICAgICAgImltbXV0YWJsZV9wYWNrYWdlIiwgRmlsZUphdmFQYWNrYWdlKGRlc2NyaXB0b3JfLT5maWxlKCksIHRydWUpLAorICAgICAgICAgICJkZXNjcmlwdG9yX2NsYXNzIiwKKyAgICAgICAgICBuYW1lX3Jlc29sdmVyXy0+R2V0RGVzY3JpcHRvckNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSwKKyAgICAgICAgICAiZGVzY3JpcHRvciIsICJnZXREZXNjcmlwdG9yKCkiLAorICAgICAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpKTsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICByZXR1cm4gJHBhcmVudCQuJGRlc2NyaXB0b3IkLmdldEVudW1UeXBlcygpLmdldCgkaW5kZXgkKTtcbiIsCisgICAgICAgICAgInBhcmVudCIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltbXV0YWJsZV9hcGlfKSwKKyAgICAgICAgICAiZGVzY3JpcHRvciIsIGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKS0+b3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgICAubm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpCisgICAgICAgICAgICAgICAgICAgICAgICA/ICJnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpIgorICAgICAgICAgICAgICAgICAgICAgICAgOiAiZ2V0RGVzY3JpcHRvcigpIiwKKyAgICAgICAgICAiaW5kZXgiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5pbmRleCgpKSk7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgInByaXZhdGUgc3RhdGljIGZpbmFsICRjbGFzc25hbWUkW10gVkFMVUVTID0gIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKworICAgIGlmIChDYW5Vc2VFbnVtVmFsdWVzKCkpIHsKKyAgICAgIC8vIElmIHRoZSBjb25zdGFudHMgd2UgYXJlIGdvaW5nIHRvIG91dHB1dCBhcmUgZXhhY3RseSB0aGUgb25lcyB3ZQorICAgICAgLy8gaGF2ZSBkZWNsYXJlZCBpbiB0aGUgSmF2YSBlbnVtIGluIHRoZSBzYW1lIG9yZGVyLCB0aGVuIHdlIGNhbiB1c2UKKyAgICAgIC8vIHRoZSB2YWx1ZXMoKSBtZXRob2QgdGhhdCB0aGUgSmF2YSBjb21waWxlciBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlcworICAgICAgLy8gZm9yIGV2ZXJ5IGVudW0uCisgICAgICBwcmludGVyLT5QcmludCgidmFsdWVzKCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ7XG4iCisgICAgICAgICIgICIpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCIkbmFtZSQsICIsCisgICAgICAgICAgIm5hbWUiLCBkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm5hbWUoKSk7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiXG4iCisgICAgICAgICAgIn07XG4iKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHZhbHVlT2YoXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7XG4iCisgICAgICAiICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7XG4iCisgICAgICAiICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFxuIgorICAgICAgIiAgICAgIFwiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS5cIik7XG4iCisgICAgICAiICB9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHtcbiIKKyAgICAgICAgIiAgICByZXR1cm4gVU5SRUNPR05JWkVEO1xuIgorICAgICAgICAiICB9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisKKyAgICAvLyBpbmRleCBpcyBvbmx5IHVzZWQgZm9yIHJlZmxlY3Rpb247IGxpdGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgbmVlZCBpdAorICAgIHByaW50ZXItPlByaW50KCJwcml2YXRlIGZpbmFsIGludCBpbmRleDtcbiIpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7XG5cbiIKKyAgICAicHJpdmF0ZSAkY2xhc3NuYW1lJChpbnQgaW5kZXgsIGludCB2YWx1ZSkge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgiICB0aGlzLmluZGV4ID0gaW5kZXg7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAiICB0aGlzLnZhbHVlID0gdmFsdWU7XG4iCisgICAgIn1cbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7Cit9CisKK2Jvb2wgRW51bUdlbmVyYXRvcjo6Q2FuVXNlRW51bVZhbHVlcygpIHsKKyAgaWYgKGNhbm9uaWNhbF92YWx1ZXNfLnNpemUoKSAhPSBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPnZhbHVlKGkpLT5uYW1lKCkgIT0gY2Fub25pY2FsX3ZhbHVlc19baV0tPm5hbWUoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTBkOTFmNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uaApAQCAtMCwwICsxLDk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRU5VTV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRU5VTV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgRW51bUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlX2FwaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkVudW1HZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKworICAvLyBUaGUgcHJvdG8gbGFuZ3VhZ2UgYWxsb3dzIG11bHRpcGxlIGVudW0gY29uc3RhbnRzIHRvIGhhdmUgdGhlIHNhbWUgbnVtZXJpYworICAvLyB2YWx1ZS4gIEphdmEsIGhvd2V2ZXIsIGRvZXMgbm90IGFsbG93IG11bHRpcGxlIGVudW0gY29uc3RhbnRzIHRvIGJlCisgIC8vIGNvbnNpZGVyZWQgZXF1aXZhbGVudC4gIFdlIHRyZWF0IHRoZSBmaXJzdCBkZWZpbmVkIGNvbnN0YW50IGZvciBhbnkKKyAgLy8gZ2l2ZW4gbnVtZXJpYyB2YWx1ZSBhcyAiY2Fub25pY2FsIiBhbmQgdGhlIHJlc3QgYXMgYWxpYXNlcyBvZiB0aGF0CisgIC8vIGNhbm9uaWNhbCB2YWx1ZS4KKyAgdmVjdG9yPGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqPiBjYW5vbmljYWxfdmFsdWVzXzsKKworICBzdHJ1Y3QgQWxpYXMgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGNhbm9uaWNhbF92YWx1ZTsKKyAgfTsKKyAgdmVjdG9yPEFsaWFzPiBhbGlhc2VzXzsKKworICBib29sIGltbXV0YWJsZV9hcGlfOworCisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgYm9vbCBDYW5Vc2VFbnVtVmFsdWVzKCk7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVudW1HZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRU5VTV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxYTJiYTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmNjCkBAIC0wLDAgKzEsOTYyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK25hbWVzcGFjZSB7CisKK3ZvaWQgU2V0RW51bVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlciwKKyAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgdmFyaWFibGVzKTsKKworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9CisgICAgICBuYW1lX3Jlc29sdmVyLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvci0+ZW51bV90eXBlKCkpOworICAoKnZhcmlhYmxlcylbIm11dGFibGVfdHlwZSJdID0KKyAgICAgIG5hbWVfcmVzb2x2ZXItPkdldE11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvci0+ZW51bV90eXBlKCkpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IEltbXV0YWJsZURlZmF1bHRWYWx1ZShkZXNjcmlwdG9yLCBuYW1lX3Jlc29sdmVyKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X251bWJlciJdID0gU2ltcGxlSXRvYSgKKyAgICAgIGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKSk7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKGludGVybmFsOjpXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSgKKyAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0OjpUYWdTaXplKGRlc2NyaXB0b3ItPm51bWJlcigpLCBHZXRUeXBlKGRlc2NyaXB0b3IpKSk7CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgICgqdmFyaWFibGVzKVsib25fY2hhbmdlZCJdID0KKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKSA/ICJvbkNoYW5nZWQoKTsiIDogIiI7CisKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3ItPmZpbGUoKSkpIHsKKyAgICAvLyBGb3Igc2luZ3VsYXIgbWVzc2FnZXMgYW5kIGJ1aWxkZXJzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHRoZSBoYXNGaWVsZCBiaXQuCisgICAgKCp2YXJpYWJsZXMpWyJnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVHZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKworICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBoYXZlIGEgdHJhaWxpbmcgIjsiLgorICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVTZXRCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9CisgICAgICAgIEdlbmVyYXRlQ2xlYXJCaXQoYnVpbGRlckJpdEluZGV4KSArICI7IjsKKworICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0KKyAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyAhPSAiICsKKyAgICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gKyAiLmdldE51bWJlcigpIjsKKyAgfQorCisgIC8vIEZvciByZXBhdGVkIGJ1aWxkZXJzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHdoZXRoZXIgdGhlIGFycmF5IGlzIGltbXV0YWJsZS4KKyAgKCp2YXJpYWJsZXMpWyJnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVHZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVTZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgLy8gRm9yIHJlcGVhdGVkIGZpZWxkcywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUKKyAgLy8gaW4gdGhlIHBhcnNpbmcgY29uc3RydWN0b3IuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgKCp2YXJpYWJsZXMpWyJnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVHZXRCaXRGcm9tTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF90b19sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0VG9Mb2NhbChtZXNzYWdlQml0SW5kZXgpOworCisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJ1bmtub3duIl0gPSAoKnZhcmlhYmxlcylbInR5cGUiXSArICIuVU5SRUNPR05JWkVEIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInVua25vd24iXSA9ICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgIFNldEVudW1WYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKworaW50IEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgaW50ICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkdHlwZSQgcmVzdWx0ID0gJHR5cGUkLnZhbHVlT2YoJG5hbWUkXyk7XG4iCisgICAgIiAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gJHVua25vd24kIDogcmVzdWx0O1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGludCAkbmFtZSRfID0gJGRlZmF1bHRfbnVtYmVyJDtcbiIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJHR5cGUkIHJlc3VsdCA9ICR0eXBlJC52YWx1ZU9mKCRuYW1lJF8pO1xuIgorICAgICIgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/ICR1bmtub3duJCA6IHJlc3VsdDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZS5nZXROdW1iZXIoKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iCisgICAgIiAgJG5hbWUkXyA9ICRkZWZhdWx0X251bWJlciQ7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgZW51bXMKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZGVmYXVsdF9udW1iZXIkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gJGRlZmF1bHRfbnVtYmVyJDtcbiIKKyAgICAiJGNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAob3RoZXIuJG5hbWUkXyAhPSAkZGVmYXVsdF9udW1iZXIkKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgcmVhY2ggaGVyZS4iOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7XG4iCisgICAgICAiJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgICAiJG5hbWUkXyA9IHJhd1ZhbHVlO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpO1xuIgorICAgICAgIiR0eXBlJCB2YWx1ZSA9ICR0eXBlJC52YWx1ZU9mKHJhd1ZhbHVlKTtcbiIKKyAgICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIik7CisgICAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICB1bmtub3duRmllbGRzLm1lcmdlVmFyaW50RmllbGQoJG51bWJlciQsIHJhd1ZhbHVlKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAgICIgICRuYW1lJF8gPSByYXdWYWx1ZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBub29wIGZvciBlbnVtcworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZUVudW0oJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUVudW1TaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgJG5hbWUkXyA9PSBvdGhlci4kbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICJoYXNoID0gKDUzICogaGFzaCkgKyAkbmFtZSRfO1xuIik7Cit9CisKK3N0cmluZyBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgIGNvbnRleHQtPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpOworICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICAgIiAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgcmV0dXJuICRkZWZhdWx0X251bWJlciQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJHR5cGUkIHJlc3VsdCA9ICAkdHlwZSQudmFsdWVPZigoamF2YS5sYW5nLkludGVnZXIpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gJHVua25vd24kIDogcmVzdWx0O1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICAgIiAgICByZXR1cm4gKChqYXZhLmxhbmcuSW50ZWdlcikgJG9uZW9mX25hbWUkXykuaW50VmFsdWUoKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiAkZGVmYXVsdF9udW1iZXIkO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICIgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJHR5cGUkIHJlc3VsdCA9ICAkdHlwZSQudmFsdWVPZigoamF2YS5sYW5nLkludGVnZXIpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gJHVua25vd24kIDogcmVzdWx0O1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZS5nZXROdW1iZXIoKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICRjbGVhcl9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgIiAgICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICByZXN1bHQuJG9uZW9mX25hbWUkXyA9ICRvbmVvZl9uYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2V0JGNhcGl0YWxpemVkX25hbWUkKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7XG4iCisgICAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiRvbmVvZl9uYW1lJF8gPSByYXdWYWx1ZTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTtcbiIKKyAgICAgICIkdHlwZSQgdmFsdWUgPSAkdHlwZSQudmFsdWVPZihyYXdWYWx1ZSk7XG4iCisgICAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIpOworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgdW5rbm93bkZpZWxkcy5tZXJnZVZhcmludEZpZWxkKCRudW1iZXIkLCByYXdWYWx1ZSk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkXyA9IHJhd1ZhbHVlO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlRW51bSgkbnVtYmVyJCwgKChqYXZhLmxhbmcuSW50ZWdlcikgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUVudW1TaXplKCRudW1iZXIkLCAoKGphdmEubGFuZy5JbnRlZ2VyKSAkb25lb2ZfbmFtZSRfKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpXG4iCisgICAgICAiICAgID09IG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKVxuIgorICAgICAgIiAgICAuZXF1YWxzKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TnVtYmVyKCk7XG4iKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpIHsKKyAgU2V0RW51bVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8sICZ2YXJpYWJsZXNfKTsKK30KKworUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpO1xuIik7CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj5cbiIKKyAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZUxpc3QoKTtcbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IGluZGV4KTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+ICRuYW1lJF87XG4iCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPFxuIgorICAgICIgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4gJG5hbWUkX2NvbnZlcnRlcl8gPVxuIgorICAgICIgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjxcbiIKKyAgICAiICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4oKSB7XG4iCisgICAgIiAgICAgICAgICBwdWJsaWMgJHR5cGUkIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkge1xuIgorICAgICIgICAgICAgICAgICAkdHlwZSQgcmVzdWx0ID0gJHR5cGUkLnZhbHVlT2YoZnJvbSk7XG4iCisgICAgIiAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/ICR1bmtub3duJCA6IHJlc3VsdDtcbiIKKyAgICAiICAgICAgICAgIH1cbiIKKyAgICAiICAgICAgICB9O1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPFxuIgorICAgICIgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgJHR5cGUkPigkbmFtZSRfLCAkbmFtZSRfY29udmVydGVyXyk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfY29udmVydGVyXy5jb252ZXJ0KCRuYW1lJF8uZ2V0KGluZGV4KSk7XG4iCisgICAgIn1cbiIpOworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPlxuIgorICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlTGlzdCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKGludCBpbmRleCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpICYmCisgICAgICBIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgaW50ICRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemU7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAvLyBPbmUgZmllbGQgaXMgdGhlIGxpc3QgYW5kIHRoZSBvdGhlciBmaWVsZCBrZWVwcyB0cmFjayBvZiB3aGV0aGVyIHRoZQorICAgIC8vIGxpc3QgaXMgaW1tdXRhYmxlLiBJZiBpdCdzIGltbXV0YWJsZSwgdGhlIGludmFyaWFudCBpcyB0aGF0IGl0IG11c3QKKyAgICAvLyBlaXRoZXIgYW4gaW5zdGFuY2Ugb2YgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkgb3IgaXQncyBhbiBBcnJheUxpc3QKKyAgICAvLyB3cmFwcGVkIGluIGEgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgpIHdyYXBwZXIgYW5kIG5vYm9keSBlbHNlIGhhcworICAgIC8vIGEgcmVmZXJlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgQXJyYXlMaXN0LiBUaGlzIGludmFyaWFudCBhbGxvd3MgdXMgdG8KKyAgICAvLyBzaGFyZSBpbnN0YW5jZXMgb2YgbGlzdHMgYmV0d2VlbiBwcm90b2NvbCBidWZmZXJzIGF2b2lkaW5nIGV4cGVuc2l2ZQorICAgIC8vIG1lbW9yeSBhbGxvY2F0aW9ucy4gTm90ZSwgaW1tdXRhYmxlIGlzIGEgc3Ryb25nIGd1YXJhbnRlZSBoZXJlIC0tIG5vdAorICAgIC8vIGp1c3QgdGhhdCB0aGUgbGlzdCBjYW5ub3QgYmUgbW9kaWZpZWQgdmlhIHRoZSByZWZlcmVuY2UgYnV0IHRoYXQgdGhlCisgICAgLy8gbGlzdCBjYW4gbmV2ZXIgYmUgbW9kaWZpZWQuCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+ICRuYW1lJF8gPVxuIgorICAgICIgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIKKworICAgICJwcml2YXRlIHZvaWQgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCkge1xuIgorICAgICIgIGlmICghJGdldF9tdXRhYmxlX2JpdF9idWlsZGVyJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPigkbmFtZSRfKTtcbiIKKyAgICAiICAgICRzZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgLy8gTm90ZTogIFdlIHJldHVybiBhbiB1bm1vZGlmaWFibGUgbGlzdCBiZWNhdXNlIG90aGVyd2lzZSB0aGUgY2FsbGVyCisgICAgLy8gICBjb3VsZCBob2xkIG9uIHRvIHRoZSByZXR1cm5lZCBsaXN0IGFuZCBtb2RpZnkgaXQgYWZ0ZXIgdGhlIG1lc3NhZ2UKKyAgICAvLyAgIGhhcyBiZWVuIGJ1aWx0LCB0aHVzIG11dGF0aW5nIHRoZSBtZXNzYWdlIHdoaWNoIGlzIHN1cHBvc2VkIHRvIGJlCisgICAgLy8gICBpbW11dGFibGUuCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkge1xuIgorICAgICIgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjxcbiIKKyAgICAiICAgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4oJG5hbWUkXywgJG5hbWUkX2NvbnZlcnRlcl8pO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkX2NvbnZlcnRlcl8uY29udmVydCgkbmFtZSRfLmdldChpbmRleCkpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzICR0eXBlJD4gdmFsdWVzKSB7XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgZm9yICgkdHlwZSQgdmFsdWUgOiB2YWx1ZXMpIHtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpO1xuIgorICAgICIgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj5cbiIKKyAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZUxpc3QoKSB7XG4iCisgICAgICAiICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IGluZGV4KSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShcbiIKKyAgICAgICIgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKGludCB2YWx1ZSkge1xuIgorICAgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgICAiICAkbmFtZSRfLmFkZCh2YWx1ZSk7XG4iCisgICAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShcbiIKKyAgICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHtcbiIKKyAgICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICAgIiAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkXy5hZGQodmFsdWUpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBlbnVtcworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7XG4iCisgICAgIiRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvZGUgYmVsb3cgZG9lcyB0d28gb3B0aW1pemF0aW9uczoKKyAgLy8gICAxLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBlbXB0eSwgdGhlcmUncyBub3RoaW5nIHRvIGRvLiBUaGlzIGVuc3VyZXMgd2UKKyAgLy8gICAgICBkb24ndCBhbGxvY2F0ZSBhIG5ldyBhcnJheSBpZiB3ZSBhbHJlYWR5IGhhdmUgYW4gaW1tdXRhYmxlIG9uZS4KKyAgLy8gICAyLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBub24tZW1wdHkgYW5kIG91ciBjdXJyZW50IGxpc3QgaXMgZW1wdHksIHdlIGNhbgorICAvLyAgICAgIHJldXNlIHRoZSBvdGhlciBsaXN0IHdoaWNoIGlzIGd1YXJhbnRlZWQgdG8gYmUgaW1tdXRhYmxlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gb3RoZXIuJG5hbWUkXztcbiIKKyAgICAiICAgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgICAkbmFtZSRfLmFkZEFsbChvdGhlci4kbmFtZSRfKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb2RlIGJlbG93IGVuc3VyZXMgdGhhdCB0aGUgcmVzdWx0IGhhcyBhbiBpbW11dGFibGUgbGlzdC4gSWYgb3VyCisgIC8vIGxpc3QgaXMgaW1tdXRhYmxlLCB3ZSBjYW4ganVzdCByZXVzZSBpdC4gSWYgbm90LCB3ZSBtYWtlIGl0IGltbXV0YWJsZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgIiAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICJ9XG4iCisgICAgInJlc3VsdC4kbmFtZSRfID0gJG5hbWUkXztcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gUmVhZCBhbmQgc3RvcmUgdGhlIGVudW0KKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpO1xuIgorICAgICAgImlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgICAiICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KCk7XG4iCisgICAgICAiICAkc2V0X211dGFibGVfYml0X3BhcnNlciQ7XG4iCisgICAgICAifVxuIgorICAgICAgIiRuYW1lJF8uYWRkKHJhd1ZhbHVlKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTtcbiIKKyAgICAgICIkdHlwZSQgdmFsdWUgPSAkdHlwZSQudmFsdWVPZihyYXdWYWx1ZSk7XG4iCisgICAgICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIik7CisgICAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICB1bmtub3duRmllbGRzLm1lcmdlVmFyaW50RmllbGQoJG51bWJlciQsIHJhd1ZhbHVlKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAiICBpZiAoISRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICAgIiAgICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KCk7XG4iCisgICAgICAiICAgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRuYW1lJF8uYWRkKHJhd1ZhbHVlKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFdyYXAgR2VuZXJhdGVQYXJzaW5nQ29kZSdzIGNvbnRlbnRzIHdpdGggYSB3aGlsZSBsb29wLgorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTtcbiIKKyAgICAiaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7XG4iCisgICAgIndoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIEdlbmVyYXRlUGFyc2luZ0NvZGUocHJpbnRlcik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ9XG4iCisgICAgImlucHV0LnBvcExpbWl0KG9sZExpbWl0KTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpID4gMCkge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJHRhZyQpO1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7XG4iCisgICAgICAifVxuIgorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlRW51bU5vVGFnKCRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlRW51bSgkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAie1xuIgorICAgICIgIGludCBkYXRhU2l6ZSA9IDA7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgIiAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKCRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAifVxuIik7CisgIHByaW50ZXItPlByaW50KAorICAgICJzaXplICs9IGRhdGFTaXplO1xuIik7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoIWdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5pc0VtcHR5KCkpIHsiCisgICAgICAiICBzaXplICs9ICR0YWdfc2l6ZSQ7XG4iCisgICAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAgICIgICAgLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZGF0YVNpemUpO1xuIgorICAgICAgIn0iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNpemUgKz0gJHRhZ19zaXplJCAqICRuYW1lJF8uc2l6ZSgpO1xuIik7CisgIH0KKworICAvLyBjYWNoZSB0aGUgZGF0YSBzaXplIGZvciBwYWNrZWQgZmllbGRzLgorICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplO1xuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmICRuYW1lJF8uZXF1YWxzKG90aGVyLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSA+IDApIHtcbiIKKyAgICAiICBoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgIiAgaGFzaCA9ICg1MyAqIGhhc2gpICsgJG5hbWUkXy5oYXNoQ29kZSgpO1xuIgorICAgICJ9XG4iKTsKK30KKworc3RyaW5nIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5lbnVtX3R5cGUoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4ZmY3MzQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmgKQEAgLTAsMCArMSwxNjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7ICAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgflJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3Q7CisgIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VOVU1fRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdjZjQxNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5jYwpAQCAtMCwwICsxLDIwNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK0ltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcjo6SW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fc2NvcGUoKSAhPSBOVUxMKSB7CisgICAgc2NvcGVfID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICAgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9zY29wZSgpKTsKKyAgfSBlbHNlIHsKKyAgICBzY29wZV8gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5maWxlKCkpOworICB9Cit9CisKK0ltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcjo6fkltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcigpIHt9CisKKy8vIEluaXRpYWxpemVzIHRoZSB2YXJzIHJlZmVyZW5jZWQgaW4gdGhlIGdlbmVyYXRlZCBjb2RlIHRlbXBsYXRlcy4KK3ZvaWQgRXh0ZW5zaW9uR2VuZXJhdG9yOjpJbml0VGVtcGxhdGVWYXJzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgc2NvcGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyc19wb2ludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gJnZhcnMgPSAqdmFyc19wb2ludGVyOworICB2YXJzWyJzY29wZSJdID0gc2NvcGU7CisgIHZhcnNbIm5hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcik7CisgIHZhcnNbImNvbnRhaW5pbmdfdHlwZSJdID0KKyAgICAgIG5hbWVfcmVzb2x2ZXItPkdldENsYXNzTmFtZShkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSwgaW1tdXRhYmxlKTsKKyAgdmFyc1sibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKKyAgdmFyc1siY29uc3RhbnRfbmFtZSJdID0gRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcik7CisgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmluZGV4KCkpOworICB2YXJzWyJkZWZhdWx0Il0gPSBkZXNjcmlwdG9yLT5pc19yZXBlYXRlZCgpID8KKyAgICAgICIiIDogRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IsIGltbXV0YWJsZSwgbmFtZV9yZXNvbHZlcik7CisgIHZhcnNbInR5cGVfY29uc3RhbnQiXSA9IEZpZWxkVHlwZU5hbWUoR2V0VHlwZShkZXNjcmlwdG9yKSk7CisgIHZhcnNbInBhY2tlZCJdID0gZGVzY3JpcHRvci0+b3B0aW9ucygpLnBhY2tlZCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgdmFyc1siZW51bV9tYXAiXSA9ICJudWxsIjsKKyAgdmFyc1sicHJvdG90eXBlIl0gPSAibnVsbCI7CisKKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZGVzY3JpcHRvcik7CisgIHN0cmluZyBzaW5ndWxhcl90eXBlOworICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgIHNpbmd1bGFyX3R5cGUgPSBuYW1lX3Jlc29sdmVyLT5HZXRDbGFzc05hbWUoZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW11dGFibGUpOworICAgICAgdmFyc1sicHJvdG90eXBlIl0gPSBzaW5ndWxhcl90eXBlICsgIi5nZXREZWZhdWx0SW5zdGFuY2UoKSI7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU06CisgICAgICBzaW5ndWxhcl90eXBlID0gbmFtZV9yZXNvbHZlci0+R2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tdXRhYmxlKTsKKyAgICAgIHZhcnNbImVudW1fbWFwIl0gPSBzaW5ndWxhcl90eXBlICsgIi5pbnRlcm5hbEdldFZhbHVlTWFwKCkiOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkc6CisgICAgICBzaW5ndWxhcl90eXBlID0gImphdmEubGFuZy5TdHJpbmciOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUzoKKyAgICAgIHNpbmd1bGFyX3R5cGUgPSBpbW11dGFibGUgPyAiY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIiA6ICJieXRlW10iOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHNpbmd1bGFyX3R5cGUgPSBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKGphdmFfdHlwZSk7CisgICAgICBicmVhazsKKyAgfQorICB2YXJzWyJ0eXBlIl0gPSBkZXNjcmlwdG9yLT5pc19yZXBlYXRlZCgpID8KKyAgICAgICJqYXZhLnV0aWwuTGlzdDwiICsgc2luZ3VsYXJfdHlwZSArICI+IiA6IHNpbmd1bGFyX3R5cGU7CisgIHZhcnNbInNpbmd1bGFyX3R5cGUiXSA9IHNpbmd1bGFyX3R5cGU7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIGNvbnN0IGJvb2wga1VzZUltbXV0YWJsZU5hbWVzID0gdHJ1ZTsKKyAgSW5pdFRlbXBsYXRlVmFycyhkZXNjcmlwdG9yXywgc2NvcGVfLCBrVXNlSW1tdXRhYmxlTmFtZXMsIG5hbWVfcmVzb2x2ZXJfLAorICAgICAgICAgICAgICAgICAgICZ2YXJzKTsKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGludCAkY29uc3RhbnRfbmFtZSQgPSAkbnVtYmVyJDtcbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gTm9uLWxpdGUgZXh0ZW5zaW9ucworICAgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCkgeworICAgICAgLy8gTm9uLW5lc3RlZAorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFycywKKyAgICAgICAgICAicHVibGljIHN0YXRpYyBmaW5hbFxuIgorICAgICAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248XG4iCisgICAgICAgICAgIiAgICAkY29udGFpbmluZ190eXBlJCxcbiIKKyAgICAgICAgICAiICAgICR0eXBlJD4gJG5hbWUkID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlXG4iCisgICAgICAgICAgIiAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oXG4iCisgICAgICAgICAgIiAgICAgICRzaW5ndWxhcl90eXBlJC5jbGFzcyxcbiIKKyAgICAgICAgICAiICAgICAgJHByb3RvdHlwZSQpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE5lc3RlZAorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFycywKKyAgICAgICAgICAicHVibGljIHN0YXRpYyBmaW5hbFxuIgorICAgICAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248XG4iCisgICAgICAgICAgIiAgICAkY29udGFpbmluZ190eXBlJCxcbiIKKyAgICAgICAgICAiICAgICR0eXBlJD4gJG5hbWUkID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlXG4iCisgICAgICAgICAgIiAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oXG4iCisgICAgICAgICAgIiAgICAgICRzY29wZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCksXG4iCisgICAgICAgICAgIiAgICAgICRpbmRleCQsXG4iCisgICAgICAgICAgIiAgICAgICRzaW5ndWxhcl90eXBlJC5jbGFzcyxcbiIKKyAgICAgICAgICAiICAgICAgJHByb3RvdHlwZSQpO1xuIik7CisgICAgfQorICB9IGVsc2UgeworICAgIC8vIExpdGUgZXh0ZW5zaW9ucworICAgIGlmIChkZXNjcmlwdG9yXy0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFycywKKyAgICAgICAgICAicHVibGljIHN0YXRpYyBmaW5hbFxuIgorICAgICAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUuR2VuZXJhdGVkRXh0ZW5zaW9uPFxuIgorICAgICAgICAgICIgICAgJGNvbnRhaW5pbmdfdHlwZSQsXG4iCisgICAgICAgICAgIiAgICAkdHlwZSQ+ICRuYW1lJCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGVcbiIKKyAgICAgICAgICAiICAgICAgICAubmV3UmVwZWF0ZWRHZW5lcmF0ZWRFeHRlbnNpb24oXG4iCisgICAgICAgICAgIiAgICAgICRjb250YWluaW5nX3R5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpLFxuIgorICAgICAgICAgICIgICAgICAkcHJvdG90eXBlJCxcbiIKKyAgICAgICAgICAiICAgICAgJGVudW1fbWFwJCxcbiIKKyAgICAgICAgICAiICAgICAgJG51bWJlciQsXG4iCisgICAgICAgICAgIiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuJHR5cGVfY29uc3RhbnQkLFxuIgorICAgICAgICAgICIgICAgICAkcGFja2VkJCxcbiIKKyAgICAgICAgICAiICAgICAgJHNpbmd1bGFyX3R5cGUkLmNsYXNzKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJzLAorICAgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsXG4iCisgICAgICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZS5HZW5lcmF0ZWRFeHRlbnNpb248XG4iCisgICAgICAgICAgIiAgICAkY29udGFpbmluZ190eXBlJCxcbiIKKyAgICAgICAgICAiICAgICR0eXBlJD4gJG5hbWUkID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZVxuIgorICAgICAgICAgICIgICAgICAgIC5uZXdTaW5ndWxhckdlbmVyYXRlZEV4dGVuc2lvbihcbiIKKyAgICAgICAgICAiICAgICAgJGNvbnRhaW5pbmdfdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCksXG4iCisgICAgICAgICAgIiAgICAgICRkZWZhdWx0JCxcbiIKKyAgICAgICAgICAiICAgICAgJHByb3RvdHlwZSQsXG4iCisgICAgICAgICAgIiAgICAgICRlbnVtX21hcCQsXG4iCisgICAgICAgICAgIiAgICAgICRudW1iZXIkLFxuIgorICAgICAgICAgICIgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLiR0eXBlX2NvbnN0YW50JCxcbiIKKyAgICAgICAgICAiICAgICAgJHNpbmd1bGFyX3R5cGUkLmNsYXNzKTtcbiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIEltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcjo6R2VuZXJhdGVOb25OZXN0ZWRJbml0aWFsaXphdGlvbkNvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fc2NvcGUoKSA9PSBOVUxMICYmCisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIE9ubHkgYXBwbGllcyB0byBub24tbmVzdGVkLCBub24tbGl0ZSBleHRlbnNpb25zLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJG5hbWUkLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoJGluZGV4JCkpO1xuIiwKKyAgICAgICAgIm5hbWUiLCBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfKSwKKyAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+aW5kZXgoKSkpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yOjpHZW5lcmF0ZVJlZ2lzdHJhdGlvbkNvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInJlZ2lzdHJ5LmFkZCgkc2NvcGUkLiRuYW1lJCk7XG4iLAorICAgICJzY29wZSIsIHNjb3BlXywKKyAgICAibmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8pKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNzAxZmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaApAQCAtMCwwICsxLDEwOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VYVEVOU0lPTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRVhURU5TSU9OX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBGaWVsZERlc2NyaXB0b3I7ICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworLy8gR2VuZXJhdGVzIGNvZGUgZm9yIGFuIGV4dGVuc2lvbiwgd2hpY2ggbWF5IGJlIHdpdGhpbiB0aGUgc2NvcGUgb2Ygc29tZQorLy8gbWVzc2FnZSBvciBtYXkgYmUgYXQgZmlsZSBzY29wZS4gIFRoaXMgaXMgbXVjaCBzaW1wbGVyIHRoYW4gRmllbGRHZW5lcmF0b3IKKy8vIHNpbmNlIGV4dGVuc2lvbnMgYXJlIGp1c3Qgc2ltcGxlIGlkZW50aWZpZXJzIHdpdGggaW50ZXJlc3RpbmcgdHlwZXMuCitjbGFzcyBFeHRlbnNpb25HZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+RXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTm9uTmVzdGVkSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVJlZ2lzdHJhdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworIHByb3RlY3RlZDoKKyAgc3RhdGljIHZvaWQgSW5pdFRlbXBsYXRlVmFycyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBzY29wZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJzX3BvaW50ZXIpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEV4dGVuc2lvbkdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3IgOiBwdWJsaWMgRXh0ZW5zaW9uR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KTsKKyAgdmlydHVhbCB+SW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTm9uTmVzdGVkSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUmVnaXN0cmF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisgIHN0cmluZyBzY29wZV87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VYVEVOU0lPTl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWY5OTc4ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMjIzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworCitJbW11dGFibGVGaWVsZEdlbmVyYXRvciogTWFrZUltbXV0YWJsZUdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgbWVzc2FnZUJpdEluZGV4LCBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgIENvbnRleHQqIGNvbnRleHQpIHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgc3dpdGNoIChHZXRKYXZhVHlwZShmaWVsZCkpIHsKKyAgICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKElzTWFwRW50cnkoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKElzTGF6eShmaWVsZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBzd2l0Y2ggKEdldEphdmFUeXBlKGZpZWxkKSkgeworICAgICAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKElzTGF6eShmaWVsZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9CisgICAgICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBzd2l0Y2ggKEdldEphdmFUeXBlKGZpZWxkKSkgeworICAgICAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKElzTGF6eShmaWVsZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICB9CisgICAgfQorICB9Cit9CisKKworc3RhdGljIGlubGluZSB2b2lkIFJlcG9ydFVuZXhwZWN0ZWRQYWNrZWRGaWVsZHNDYWxsKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFJlYWNoaW5nIGhlcmUgaW5kaWNhdGVzIGEgYnVnLiBDYXNlcyBhcmU6CisgIC8vICAgLSBUaGlzIEZpZWxkR2VuZXJhdG9yIHNob3VsZCBzdXBwb3J0IHBhY2tpbmcsCisgIC8vICAgICBidXQgdGhpcyBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRkZW4uCisgIC8vICAgLSBUaGlzIEZpZWxkR2VuZXJhdG9yIGRvZXNuJ3Qgc3VwcG9ydCBwYWNraW5nLCBhbmQgdGhpcyBtZXRob2QKKyAgLy8gICAgIHNob3VsZCBuZXZlciBoYXZlIGJlZW4gY2FsbGVkLgorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoKSAiCisgICAgICAgICAgICAgPDwgImNhbGxlZCBvbiBmaWVsZCBnZW5lcmF0b3IgdGhhdCBkb2VzIG5vdCBzdXBwb3J0IHBhY2tpbmcuIjsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0ltbXV0YWJsZUZpZWxkR2VuZXJhdG9yOjp+SW1tdXRhYmxlRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFJlcG9ydFVuZXhwZWN0ZWRQYWNrZWRGaWVsZHNDYWxsKHByaW50ZXIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3RlbXBsYXRlIDw+CitGaWVsZEdlbmVyYXRvck1hcDxJbW11dGFibGVGaWVsZEdlbmVyYXRvcj46OkZpZWxkR2VuZXJhdG9yTWFwKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfKG5ldyBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPAorICAgICAgICAgIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPltkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpXSkgeworCisgIC8vIENvbnN0cnVjdCBhbGwgdGhlIEZpZWxkR2VuZXJhdG9ycyBhbmQgYXNzaWduIHRoZW0gYml0IGluZGljZXMgZm9yIHRoZWlyCisgIC8vIGJpdCBmaWVsZHMuCisgIGludCBtZXNzYWdlQml0SW5kZXggPSAwOworICBpbnQgYnVpbGRlckJpdEluZGV4ID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBJbW11dGFibGVGaWVsZEdlbmVyYXRvciogZ2VuZXJhdG9yID0gTWFrZUltbXV0YWJsZUdlbmVyYXRvcigKKyAgICAgICAgZGVzY3JpcHRvci0+ZmllbGQoaSksIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzX1tpXS5yZXNldChnZW5lcmF0b3IpOworICAgIG1lc3NhZ2VCaXRJbmRleCArPSBnZW5lcmF0b3ItPkdldE51bUJpdHNGb3JNZXNzYWdlKCk7CisgICAgYnVpbGRlckJpdEluZGV4ICs9IGdlbmVyYXRvci0+R2V0TnVtQml0c0ZvckJ1aWxkZXIoKTsKKyAgfQorfQorCit0ZW1wbGF0ZTw+CitGaWVsZEdlbmVyYXRvck1hcDxJbW11dGFibGVGaWVsZEdlbmVyYXRvcj46On5GaWVsZEdlbmVyYXRvck1hcCgpIHt9CisKKwordm9pZCBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsiZmllbGRfbmFtZSJdID0gZGVzY3JpcHRvci0+bmFtZSgpOworICAoKnZhcmlhYmxlcylbIm5hbWUiXSA9IGluZm8tPm5hbWU7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdID0gaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZTsKKyAgKCp2YXJpYWJsZXMpWyJkaXNhbWJpZ3VhdGVkX3JlYXNvbiJdID0gaW5mby0+ZGlzYW1iaWd1YXRlZF9yZWFzb247CisgICgqdmFyaWFibGVzKVsiY29uc3RhbnRfbmFtZSJdID0gRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKK30KKwordm9pZCBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsib25lb2ZfbmFtZSJdID0gaW5mby0+bmFtZTsKKyAgKCp2YXJpYWJsZXMpWyJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIl0gPSBpbmZvLT5jYXBpdGFsaXplZF9uYW1lOworICAoKnZhcmlhYmxlcylbIm9uZW9mX2luZGV4Il0gPQorICAgICAgU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCkpOworICAoKnZhcmlhYmxlcylbInNldF9vbmVvZl9jYXNlX21lc3NhZ2UiXSA9IGluZm8tPm5hbWUgKworICAgICAgIkNhc2VfID0gIiArIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbImNsZWFyX29uZW9mX2Nhc2VfbWVzc2FnZSJdID0gaW5mby0+bmFtZSArCisgICAgICAiQ2FzZV8gPSAwIjsKKyAgKCp2YXJpYWJsZXMpWyJoYXNfb25lb2ZfY2FzZV9tZXNzYWdlIl0gPSBpbmZvLT5uYW1lICsKKyAgICAgICJDYXNlXyA9PSAiICsgU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7Cit9CisKK3ZvaWQgUHJpbnRFeHRyYUZpZWxkSW5mbyhjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXQgPQorICAgICAgdmFyaWFibGVzLmZpbmQoImRpc2FtYmlndWF0ZWRfcmVhc29uIik7CisgIGlmIChpdCAhPSB2YXJpYWJsZXMuZW5kKCkgJiYgIWl0LT5zZWNvbmQuZW1wdHkoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXMsCisgICAgICAgICIvLyBBbiBhbHRlcm5hdGl2ZSBuYW1lIGlzIHVzZWQgZm9yIGZpZWxkIFwiJGZpZWxkX25hbWUkXCIgYmVjYXVzZTpcbiIKKyAgICAgICAgIi8vICAgICAkZGlzYW1iaWd1YXRlZF9yZWFzb24kXG4iKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjZjM2MGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oCkBAIC0wLDAgKzEsMTY2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7ICAgICAgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IoKSB7fQorICB2aXJ0dWFsIH5JbW11dGFibGVGaWVsZEdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikKKyAgICAgIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU3RhdGljSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7fQorCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICB2aXJ0dWFsIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdCA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IpOworfTsKKworCisvLyBDb252ZW5pZW5jZSBjbGFzcyB3aGljaCBjb25zdHJ1Y3RzIEZpZWxkR2VuZXJhdG9ycyBmb3IgYSBEZXNjcmlwdG9yLgordGVtcGxhdGU8dHlwZW5hbWUgRmllbGRHZW5lcmF0b3JUeXBlPgorY2xhc3MgRmllbGRHZW5lcmF0b3JNYXAgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRmllbGRHZW5lcmF0b3JNYXAoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCk7CisgIH5GaWVsZEdlbmVyYXRvck1hcCgpOworCisgIGNvbnN0IEZpZWxkR2VuZXJhdG9yVHlwZSYgZ2V0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yVHlwZT4gPiBmaWVsZF9nZW5lcmF0b3JzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3JNYXApOworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgRmllbGRHZW5lcmF0b3JUeXBlPgoraW5saW5lIGNvbnN0IEZpZWxkR2VuZXJhdG9yVHlwZSYKK0ZpZWxkR2VuZXJhdG9yTWFwPEZpZWxkR2VuZXJhdG9yVHlwZT46OmdldChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDS19FUShmaWVsZC0+Y29udGFpbmluZ190eXBlKCksIGRlc2NyaXB0b3JfKTsKKyAgcmV0dXJuICpmaWVsZF9nZW5lcmF0b3JzX1tmaWVsZC0+aW5kZXgoKV07Cit9CisKKy8vIEluc3RhbnRpYXRlIHRlbXBsYXRlIGZvciBtdXRhYmxlIGFuZCBpbW11dGFibGUgbWFwcy4KK3RlbXBsYXRlPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPjo6CitGaWVsZEdlbmVyYXRvck1hcChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCk7CisKK3RlbXBsYXRlPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPjo6fkZpZWxkR2VuZXJhdG9yTWFwKCk7CisKKworLy8gRmllbGQgaW5mb3JtYXRpb24gdXNlZCBpbiBGaWVsZEdlbmVhcnRvcnMuCitzdHJ1Y3QgRmllbGRHZW5lcmF0b3JJbmZvIHsKKyAgc3RyaW5nIG5hbWU7CisgIHN0cmluZyBjYXBpdGFsaXplZF9uYW1lOworICBzdHJpbmcgZGlzYW1iaWd1YXRlZF9yZWFzb247Cit9OworCisvLyBPbmVvZiBpbmZvcm1hdGlvbiB1c2VkIGluIE9uZW9mRmllbGRHZW5lYXJ0b3JzLgorc3RydWN0IE9uZW9mR2VuZXJhdG9ySW5mbyB7CisgIHN0cmluZyBuYW1lOworICBzdHJpbmcgY2FwaXRhbGl6ZWRfbmFtZTsKK307CisKKy8vIFNldCBzb21lIGNvbW1vbiB2YXJpYWJsZXMgdXNlZCBpbiB2YXJpYWJsZSBGaWVsZEdlbmVyYXRvcnMuCit2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpOworCisvLyBTZXQgc29tZSBjb21tb24gb25lb2YgdmFyaWFibGVzIHVzZWQgaW4gT25lb2ZGaWVsZEdlbmVyYXRvcnMuCit2b2lkIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpOworCisvLyBQcmludCB1c2VmdWwgY29tbWVudHMgYmVmb3JlIGEgZmllbGQncyBhY2Nlc3NvcnMuCit2b2lkIFByaW50RXh0cmFGaWVsZEluZm8oY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWUzY2Y2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5jYwpAQCAtMCwwICsxLDUxNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworCisKKy8vIFJlY3Vyc2l2ZWx5IHNlYXJjaGVzIHRoZSBnaXZlbiBtZXNzYWdlIHRvIGNvbGxlY3QgZXh0ZW5zaW9ucy4KKy8vIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIGV4dGVuc2lvbnMgY2FuIGJlIHJlY29nbml6ZWQuIFRoZSBleHRlbnNpb25zIHdpbGwgYmUKKy8vIGFwcGVuZGVkIGluIHRvIHRoZSBleHRlbnNpb25zIHBhcmFtZXRlci4KKy8vIFJldHVybnMgZmFsc2Ugd2hlbiB0aGVyZSBhcmUgdW5rbm93biBmaWVsZHMsIGluIHdoaWNoIGNhc2UgdGhlIGRhdGEgaW4gdGhlCisvLyBleHRlbnNpb25zIG91dHB1dCBwYXJhbWV0ZXIgaXMgbm90IHJlbGlhYmxlIGFuZCBzaG91bGQgYmUgZGlzY2FyZGVkLgorYm9vbCBDb2xsZWN0RXh0ZW5zaW9ucyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIGV4dGVuc2lvbnMpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIFRoZXJlIGFyZSB1bmtub3duIGZpZWxkcyB0aGF0IGNvdWxkIGJlIGV4dGVuc2lvbnMsIHRodXMgdGhpcyBjYWxsIGZhaWxzLgorICBpZiAocmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKS5maWVsZF9jb3VudCgpID4gMCkgcmV0dXJuIGZhbHNlOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZSwgJmZpZWxkcyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoZmllbGRzW2ldLT5pc19leHRlbnNpb24oKSkgZXh0ZW5zaW9ucy0+cHVzaF9iYWNrKGZpZWxkc1tpXSk7CisKKyAgICBpZiAoR2V0SmF2YVR5cGUoZmllbGRzW2ldKSA9PSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgICBpZiAoZmllbGRzW2ldLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIGludCBzaXplID0gcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIGZpZWxkc1tpXSk7CisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTsgaisrKSB7CisgICAgICAgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPQorICAgICAgICAgICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkc1tpXSwgaik7CisgICAgICAgICAgaWYgKCFDb2xsZWN0RXh0ZW5zaW9ucyhzdWJfbWVzc2FnZSwgZXh0ZW5zaW9ucykpIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkc1tpXSk7CisgICAgICAgIGlmICghQ29sbGVjdEV4dGVuc2lvbnMoc3ViX21lc3NhZ2UsIGV4dGVuc2lvbnMpKSByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIEZpbmRzIGFsbCBleHRlbnNpb25zIGluIHRoZSBnaXZlbiBtZXNzYWdlIGFuZCBpdHMgc3ViLW1lc3NhZ2VzLiAgSWYgdGhlCisvLyBtZXNzYWdlIGNvbnRhaW5zIHVua25vd24gZmllbGRzICh3aGljaCBjb3VsZCBiZSBleHRlbnNpb25zKSwgdGhlbiB0aG9zZQorLy8gZXh0ZW5zaW9ucyBhcmUgZGVmaW5lZCBpbiBhbHRlcm5hdGVfcG9vbC4KKy8vIFRoZSBtZXNzYWdlIHdpbGwgYmUgY29udmVydGVkIHRvIGEgRHluYW1pY01lc3NhZ2UgYmFja2VkIGJ5IGFsdGVybmF0ZV9wb29sCisvLyBpbiBvcmRlciB0byBoYW5kbGUgdGhpcyBjYXNlLgordm9pZCBDb2xsZWN0RXh0ZW5zaW9ucyhjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmaWxlX3Byb3RvLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCYgYWx0ZXJuYXRlX3Bvb2wsCisgICAgICAgICAgICAgICAgICAgICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogZXh0ZW5zaW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlX2RhdGEpIHsKKyAgaWYgKCFDb2xsZWN0RXh0ZW5zaW9ucyhmaWxlX3Byb3RvLCBleHRlbnNpb25zKSkgeworICAgIC8vIFRoZXJlIGFyZSB1bmtub3duIGZpZWxkcyBpbiB0aGUgZmlsZV9wcm90bywgd2hpY2ggYXJlIHByb2JhYmx5CisgICAgLy8gZXh0ZW5zaW9ucy4gV2UgbmVlZCB0byBwYXJzZSB0aGUgZGF0YSBpbnRvIGEgZHluYW1pYyBtZXNzYWdlIGJhc2VkIG9uIHRoZQorICAgIC8vIGJ1aWxkZXItcG9vbCB0byBmaW5kIG91dCBhbGwgZXh0ZW5zaW9ucy4KKyAgICBjb25zdCBEZXNjcmlwdG9yKiBmaWxlX3Byb3RvX2Rlc2MgPSBhbHRlcm5hdGVfcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoCisgICAgICAgIGZpbGVfcHJvdG8uR2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKSk7CisgICAgR09PR0xFX0NIRUNLKGZpbGVfcHJvdG9fZGVzYykKKyAgICAgICAgPDwgIkZpbmQgdW5rbm93biBmaWVsZHMgaW4gRmlsZURlc2NyaXB0b3JQcm90byB3aGVuIGJ1aWxkaW5nICIKKyAgICAgICAgPDwgZmlsZV9wcm90by5uYW1lKCkKKyAgICAgICAgPDwgIi4gSXQncyBsaWtlbHkgdGhhdCB0aG9zZSBmaWVsZHMgYXJlIGN1c3RvbSBvcHRpb25zLCBob3dldmVyLCAiCisgICAgICAgICAgICJkZXNjcmlwdG9yLnByb3RvIGlzIG5vdCBpbiB0aGUgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMuICIKKyAgICAgICAgICAgIlRoaXMgbm9ybWFsbHkgc2hvdWxkIG5vdCBoYXBwZW4uIFBsZWFzZSByZXBvcnQgYSBidWcuIjsKKyAgICBEeW5hbWljTWVzc2FnZUZhY3RvcnkgZmFjdG9yeTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IGR5bmFtaWNfZmlsZV9wcm90bygKKyAgICAgICAgZmFjdG9yeS5HZXRQcm90b3R5cGUoZmlsZV9wcm90b19kZXNjKS0+TmV3KCkpOworICAgIEdPT0dMRV9DSEVDSyhkeW5hbWljX2ZpbGVfcHJvdG8uZ2V0KCkgIT0gTlVMTCk7CisgICAgR09PR0xFX0NIRUNLKGR5bmFtaWNfZmlsZV9wcm90by0+UGFyc2VGcm9tU3RyaW5nKGZpbGVfZGF0YSkpOworCisgICAgLy8gQ29sbGVjdCB0aGUgZXh0ZW5zaW9ucyBhZ2FpbiBmcm9tIHRoZSBkeW5hbWljIG1lc3NhZ2UuIFRoZXJlIHNob3VsZCBiZSBubworICAgIC8vIG1vcmUgdW5rbm93biBmaWVsZHMgdGhpcyB0aW1lLCBpLmUuIGFsbCB0aGUgY3VzdG9tIG9wdGlvbnMgc2hvdWxkIGJlCisgICAgLy8gcGFyc2VkIGFzIGV4dGVuc2lvbnMgbm93LgorICAgIGV4dGVuc2lvbnMtPmNsZWFyKCk7CisgICAgR09PR0xFX0NIRUNLKENvbGxlY3RFeHRlbnNpb25zKCpkeW5hbWljX2ZpbGVfcHJvdG8sIGV4dGVuc2lvbnMpKQorICAgICAgICA8PCAiRmluZCB1bmtub3duIGZpZWxkcyBpbiBGaWxlRGVzY3JpcHRvclByb3RvIHdoZW4gYnVpbGRpbmcgIgorICAgICAgICA8PCBmaWxlX3Byb3RvLm5hbWUoKQorICAgICAgICA8PCAiLiBJdCdzIGxpa2VseSB0aGF0IHRob3NlIGZpZWxkcyBhcmUgY3VzdG9tIG9wdGlvbnMsIGhvd2V2ZXIsICIKKyAgICAgICAgICAgInRob3NlIG9wdGlvbnMgY2Fubm90IGJlIHJlY29nbml6ZWQgaW4gdGhlIGJ1aWxkZXIgcG9vbC4gIgorICAgICAgICAgICAiVGhpcyBub3JtYWxseSBzaG91bGQgbm90IGhhcHBlbi4gUGxlYXNlIHJlcG9ydCBhIGJ1Zy4iOworICB9Cit9CisKKworfSAgLy8gbmFtZXNwYWNlCisKK0ZpbGVHZW5lcmF0b3I6OkZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlX2FwaSkKKyAgICA6IGZpbGVfKGZpbGUpLAorICAgICAgamF2YV9wYWNrYWdlXyhGaWxlSmF2YVBhY2thZ2UoZmlsZSwgaW1tdXRhYmxlX2FwaSkpLAorICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzXygKKyAgICAgICAgICBuZXcgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlR2VuZXJhdG9yPltmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKV0pLAorICAgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfKAorICAgICAgICAgIG5ldyBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEV4dGVuc2lvbkdlbmVyYXRvcj5bZmlsZS0+ZXh0ZW5zaW9uX2NvdW50KCldKSwKKyAgICAgIGNvbnRleHRfKG5ldyBDb250ZXh0KGZpbGUpKSwKKyAgICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHRfLT5HZXROYW1lUmVzb2x2ZXIoKSksCisgICAgICBpbW11dGFibGVfYXBpXyhpbW11dGFibGVfYXBpKSB7CisgIGNsYXNzbmFtZV8gPSBuYW1lX3Jlc29sdmVyXy0+R2V0RmlsZUNsYXNzTmFtZShmaWxlLCBpbW11dGFibGVfYXBpKTsKKyAgZ2VuZXJhdG9yX2ZhY3RvcnlfLnJlc2V0KAorICAgICAgbmV3IEltbXV0YWJsZUdlbmVyYXRvckZhY3RvcnkoY29udGV4dF8uZ2V0KCkpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICAgIGdlbmVyYXRvcl9mYWN0b3J5Xy0+TmV3TWVzc2FnZUdlbmVyYXRvcihmaWxlXy0+bWVzc2FnZV90eXBlKGkpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS5yZXNldCgKKyAgICAgICAgZ2VuZXJhdG9yX2ZhY3RvcnlfLT5OZXdFeHRlbnNpb25HZW5lcmF0b3IoZmlsZV8tPmV4dGVuc2lvbihpKSkpOworICB9Cit9CisKK0ZpbGVHZW5lcmF0b3I6On5GaWxlR2VuZXJhdG9yKCkge30KKworYm9vbCBGaWxlR2VuZXJhdG9yOjpWYWxpZGF0ZShzdHJpbmcqIGVycm9yKSB7CisgIC8vIENoZWNrIHRoYXQgbm8gY2xhc3MgbmFtZSBtYXRjaGVzIHRoZSBmaWxlJ3MgY2xhc3MgbmFtZS4gIFRoaXMgaXMgYSBjb21tb24KKyAgLy8gcHJvYmxlbSB0aGF0IGxlYWRzIHRvIEphdmEgY29tcGlsZSBlcnJvcnMgdGhhdCBjYW4gYmUgaGFyZCB0byB1bmRlcnN0YW5kLgorICAvLyBJdCdzIGVzcGVjaWFsbHkgYmFkIHdoZW4gdXNpbmcgdGhlIGphdmFfbXVsdGlwbGVfZmlsZXMsIHNpbmNlIHdlIHdvdWxkCisgIC8vIGVuZCB1cCBvdmVyd3JpdGluZyB0aGUgb3V0ZXIgY2xhc3Mgd2l0aCBvbmUgb2YgdGhlIGlubmVyIG9uZXMuCisgIGlmIChuYW1lX3Jlc29sdmVyXy0+SGFzQ29uZmxpY3RpbmdDbGFzc05hbWUoZmlsZV8sIGNsYXNzbmFtZV8pKSB7CisgICAgZXJyb3ItPmFzc2lnbihmaWxlXy0+bmFtZSgpKTsKKyAgICBlcnJvci0+YXBwZW5kKAorICAgICAgIjogQ2Fubm90IGdlbmVyYXRlIEphdmEgb3V0cHV0IGJlY2F1c2UgdGhlIGZpbGUncyBvdXRlciBjbGFzcyBuYW1lLCBcIiIpOworICAgIGVycm9yLT5hcHBlbmQoY2xhc3NuYW1lXyk7CisgICAgZXJyb3ItPmFwcGVuZCgKKyAgICAgICJcIiwgbWF0Y2hlcyB0aGUgbmFtZSBvZiBvbmUgb2YgdGhlIHR5cGVzIGRlY2xhcmVkIGluc2lkZSBpdC4gICIKKyAgICAgICJQbGVhc2UgZWl0aGVyIHJlbmFtZSB0aGUgdHlwZSBvciB1c2UgdGhlIGphdmFfb3V0ZXJfY2xhc3NuYW1lICIKKyAgICAgICJvcHRpb24gdG8gc3BlY2lmeSBhIGRpZmZlcmVudCBvdXRlciBjbGFzcyBuYW1lIGZvciB0aGUgLnByb3RvIGZpbGUuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFdlIGRvbid0IGltcG9ydCBhbnl0aGluZyBiZWNhdXNlIHdlIHJlZmVyIHRvIGFsbCBjbGFzc2VzIGJ5IHRoZWlyCisgIC8vIGZ1bGx5LXF1YWxpZmllZCBuYW1lcyBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgIi8vIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICJcbiIsCisgICAgImZpbGVuYW1lIiwgZmlsZV8tPm5hbWUoKSk7CisgIGlmICghamF2YV9wYWNrYWdlXy5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicGFja2FnZSAkcGFja2FnZSQ7XG4iCisgICAgICAiXG4iLAorICAgICAgInBhY2thZ2UiLCBqYXZhX3BhY2thZ2VfKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIHtcbiIKKyAgICAiICBwcml2YXRlICRjbGFzc25hbWUkKCkge31cbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSRsaXRlJCByZWdpc3RyeSkge1xuIiwKKyAgICAibGl0ZSIsIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGZpbGVfKSA/ICIiIDogIkxpdGUiKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVJlZ2lzdHJhdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpZiAoIU11bHRpcGxlSmF2YUZpbGVzKGZpbGVfLCBpbW11dGFibGVfYXBpXykpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBFbnVtR2VuZXJhdG9yKGZpbGVfLT5lbnVtX3R5cGUoaSksIGltbXV0YWJsZV9hcGlfLCBjb250ZXh0Xy5nZXQoKSkKKyAgICAgICAgICAuR2VuZXJhdGUocHJpbnRlcik7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlSW50ZXJmYWNlKHByaW50ZXIpOworICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGUocHJpbnRlcik7CisgICAgfQorICAgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZV8pKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFNlcnZpY2VHZW5lcmF0b3I+IGdlbmVyYXRvcigKKyAgICAgICAgICAgIGdlbmVyYXRvcl9mYWN0b3J5Xy0+TmV3U2VydmljZUdlbmVyYXRvcihmaWxlXy0+c2VydmljZShpKSkpOworICAgICAgICBnZW5lcmF0b3ItPkdlbmVyYXRlKHByaW50ZXIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIEV4dGVuc2lvbnMgbXVzdCBiZSBnZW5lcmF0ZWQgaW4gdGhlIG91dGVyIGNsYXNzIHNpbmNlIHRoZXkgYXJlIHZhbHVlcywKKyAgLy8gbm90IGNsYXNzZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlKHByaW50ZXIpOworICB9CisKKyAgLy8gU3RhdGljIHZhcmlhYmxlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlU3RhdGljVmFyaWFibGVzKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGZpbGVfKSkgeworICAgIGlmIChpbW11dGFibGVfYXBpXykgeworICAgICAgR2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9ySW1tdXRhYmxlKHByaW50ZXIpOworICAgIH0gZWxzZSB7CisgICAgICBHZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXphdGlvbkNvZGVGb3JNdXRhYmxlKHByaW50ZXIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJzdGF0aWMge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKHByaW50ZXIpOworICAgIH0KKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKVxuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9ySW1tdXRhYmxlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JcbiIKKyAgICAiICAgIGdldERlc2NyaXB0b3IoKSB7XG4iCisgICAgIiAgcmV0dXJuIGRlc2NyaXB0b3I7XG4iCisgICAgIn1cbiIKKyAgICAicHJpdmF0ZSBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvclxuIgorICAgICIgICAgZGVzY3JpcHRvcjtcbiIKKyAgICAic3RhdGljIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBTaGFyZWRDb2RlR2VuZXJhdG9yIHNoYXJlZF9jb2RlX2dlbmVyYXRvcihmaWxlXyk7CisgIHNoYXJlZF9jb2RlX2dlbmVyYXRvci5HZW5lcmF0ZURlc2NyaXB0b3JzKHByaW50ZXIpOworCisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMocHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVOb25OZXN0ZWRJbml0aWFsaXphdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKworICAvLyBQcm90byBjb21waWxlciBidWlsZHMgYSBEZXNjcmlwdG9yUG9vbCwgd2hpY2ggaG9sZHMgYWxsIHRoZSBkZXNjcmlwdG9ycyB0bworICAvLyBnZW5lcmF0ZSwgd2hlbiBwcm9jZXNzaW5nIHRoZSAiLnByb3RvIiBmaWxlcy4gV2UgY2FsbCB0aGlzIERlc2NyaXB0b3JQb29sCisgIC8vIHRoZSBwYXJzZWQgcG9vbCAoYS5rLmEuIGZpbGVfLT5wb29sKCkpLgorICAvLworICAvLyBOb3RlIHRoYXQgd2hlbiB1c2VycyB0cnkgdG8gZXh0ZW5kIHRoZSAoLiopRGVzY3JpcHRvclByb3RvIGluIHRoZWlyCisgIC8vICIucHJvdG8iIGZpbGVzLCBpdCBkb2VzIG5vdCBhZmZlY3QgdGhlIHByZS1idWlsdCBGaWxlRGVzY3JpcHRvclByb3RvIGNsYXNzCisgIC8vIGluIHByb3RvIGNvbXBpbGVyLiBXaGVuIHdlIHB1dCB0aGUgZGVzY3JpcHRvciBkYXRhIGluIHRoZSBmaWxlX3Byb3RvLCB0aG9zZQorICAvLyBleHRlbnNpb25zIGJlY29tZSB1bmtub3duIGZpZWxkcy4KKyAgLy8KKyAgLy8gTm93IHdlIG5lZWQgdG8gZmluZCBvdXQgYWxsIHRoZSBleHRlbnNpb24gdmFsdWUgdG8gdGhlICguKilEZXNjcmlwdG9yUHJvdG8KKyAgLy8gaW4gdGhlIGZpbGVfcHJvdG8gbWVzc2FnZSwgYW5kIHByZXBhcmUgYW4gRXh0ZW5zaW9uUmVnaXN0cnkgdG8gcmV0dXJuLgorICAvLworICAvLyBUbyBmaW5kIHRob3NlIGV4dGVuc2lvbnMsIHdlIG5lZWQgdG8gcGFyc2UgdGhlIGRhdGEgaW50byBhIGR5bmFtaWMgbWVzc2FnZQorICAvLyBvZiB0aGUgRmlsZURlc2NyaXB0b3IgYmFzZWQgb24gdGhlIGJ1aWxkZXItcG9vbCwgdGhlbiB3ZSBjYW4gdXNlCisgIC8vIHJlZmxlY3Rpb25zIHRvIGZpbmQgYWxsIGV4dGVuc2lvbiBmaWVsZHMKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlXy0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgc3RyaW5nIGZpbGVfZGF0YTsKKyAgZmlsZV9wcm90by5TZXJpYWxpemVUb1N0cmluZygmZmlsZV9kYXRhKTsKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGV4dGVuc2lvbnM7CisgIENvbGxlY3RFeHRlbnNpb25zKGZpbGVfcHJvdG8sICpmaWxlXy0+cG9vbCgpLCAmZXh0ZW5zaW9ucywgZmlsZV9kYXRhKTsKKworICBpZiAoZXh0ZW5zaW9ucy5zaXplKCkgPiAwKSB7CisgICAgLy8gTXVzdCBjb25zdHJ1Y3QgYW4gRXh0ZW5zaW9uUmVnaXN0cnkgY29udGFpbmluZyBhbGwgZXhpc3RpbmcgZXh0ZW5zaW9ucworICAgIC8vIGFuZCB1c2UgaXQgdG8gcGFyc2UgdGhlIGRlc2NyaXB0b3IgZGF0YSBhZ2FpbiB0byByZWNvZ25pemUgZXh0ZW5zaW9ucy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID1cbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeS5uZXdJbnN0YW5jZSgpO1xuIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25zLnNpemUoKTsgaSsrKSB7CisgICAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEV4dGVuc2lvbkdlbmVyYXRvcj4gZ2VuZXJhdG9yKAorICAgICAgICAgIGdlbmVyYXRvcl9mYWN0b3J5Xy0+TmV3RXh0ZW5zaW9uR2VuZXJhdG9yKGV4dGVuc2lvbnNbaV0pKTsKKyAgICAgIGdlbmVyYXRvci0+R2VuZXJhdGVSZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yXG4iCisgICAgICAiICAgIC5pbnRlcm5hbFVwZGF0ZUZpbGVEZXNjcmlwdG9yKGRlc2NyaXB0b3IsIHJlZ2lzdHJ5KTtcbiIpOworICB9CisKKyAgLy8gRm9yY2UgZGVzY3JpcHRvciBpbml0aWFsaXphdGlvbiBvZiBhbGwgZGVwZW5kZW5jaWVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIGlmIChTaG91bGRJbmNsdWRlRGVwZW5kZW5jeShmaWxlXy0+ZGVwZW5kZW5jeShpKSwgdHJ1ZSkpIHsKKyAgICAgIHN0cmluZyBkZXBlbmRlbmN5ID0KKyAgICAgICAgICBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGZpbGVfLT5kZXBlbmRlbmN5KGkpKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJGRlcGVuZGVuY3kkLmdldERlc2NyaXB0b3IoKTtcbiIsCisgICAgICAgICJkZXBlbmRlbmN5IiwgZGVwZW5kZW5jeSk7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9yTXV0YWJsZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yXG4iCisgICAgIiAgICBnZXREZXNjcmlwdG9yKCkge1xuIgorICAgICIgIHJldHVybiBkZXNjcmlwdG9yO1xuIgorICAgICJ9XG4iCisgICAgInByaXZhdGUgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JcbiIKKyAgICAiICAgIGRlc2NyaXB0b3I7XG4iCisgICAgInN0YXRpYyB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImRlc2NyaXB0b3IgPSAkaW1tdXRhYmxlX3BhY2thZ2UkLiRkZXNjcmlwdG9yX2NsYXNzbmFtZSQuZGVzY3JpcHRvcjtcbiIsCisgICAgImltbXV0YWJsZV9wYWNrYWdlIiwgRmlsZUphdmFQYWNrYWdlKGZpbGVfLCB0cnVlKSwKKyAgICAiZGVzY3JpcHRvcl9jbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0RGVzY3JpcHRvckNsYXNzTmFtZShmaWxlXykpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKHByaW50ZXIpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlTm9uTmVzdGVkSW5pdGlhbGl6YXRpb25Db2RlKHByaW50ZXIpOworICB9CisKKyAgLy8gQ2hlY2sgaWYgY3VzdG9tIG9wdGlvbnMgZXhpc3QuIElmIGFueSwgdHJ5IHRvIGxvYWQgaW1tdXRhYmxlIGNsYXNzZXMgc2luY2UKKyAgLy8gY3VzdG9tIG9wdGlvbnMgYXJlIG9ubHkgcmVwcmVzZW50ZWQgd2l0aCBpbW11dGFibGUgbWVzc2FnZXMuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgZmlsZV8tPkNvcHlUbygmZmlsZV9wcm90byk7CisgIHN0cmluZyBmaWxlX2RhdGE7CisgIGZpbGVfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoJmZpbGVfZGF0YSk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBleHRlbnNpb25zOworICBDb2xsZWN0RXh0ZW5zaW9ucyhmaWxlX3Byb3RvLCAqZmlsZV8tPnBvb2woKSwgJmV4dGVuc2lvbnMsIGZpbGVfZGF0YSk7CisKKyAgaWYgKGV4dGVuc2lvbnMuc2l6ZSgpID4gMCkgeworICAgIC8vIFRyeSB0byBsb2FkIGltbXV0YWJsZSBtZXNzYWdlcycgb3V0ZXIgY2xhc3MuIEl0cyBpbml0aWFsaXphdGlvbiBjb2RlCisgICAgLy8gd2lsbCB0YWtlIGNhcmUgb2YgaW50ZXJwcmV0aW5nIGN1c3RvbSBvcHRpb25zLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInRyeSB7XG4iCisgICAgICAvLyBOb3RlIHRoYXQgd2UgaGF2ZSB0byBsb2FkIHRoZSBpbW11dGFibGUgY2xhc3MgZHluYW1pY2FsbHkgaGVyZSBhcworICAgICAgLy8gd2Ugd2FudCB0aGUgbXV0YWJsZSBjb2RlIHRvIGJlIGluZGVwZW5kZW50IGZyb20gdGhlIGltbXV0YWJsZSBjb2RlCisgICAgICAvLyBhdCBjb21waWxlIHRpbWUuIEl0IGlzIHJlcXVpcmVkIHRvIGltcGxlbWVudCBkdWFsLWNvbXBpbGUgZm9yCisgICAgICAvLyBtdXRhYmxlIGFuZCBpbW11dGFibGUgQVBJIGluIGJsYXplLgorICAgICAgIiAgamF2YS5sYW5nLkNsYXNzIGltbXV0YWJsZUNsYXNzID0gamF2YS5sYW5nLkNsYXNzLmZvck5hbWUoXG4iCisgICAgICAiICAgICAgXCIkaW1tdXRhYmxlX2NsYXNzbmFtZSRcIik7XG4iCisgICAgICAifSBjYXRjaCAoamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkge1xuIgorICAgICAgLy8gVGhlIGltbXV0YWJsZSBjbGFzcyBjYW4gbm90IGJlIGZvdW5kLiBDdXN0b20gb3B0aW9ucyBhcmUgbGVmdAorICAgICAgLy8gYXMgdW5rbm93biBmaWVsZHMuCisgICAgICAvLyBUT0RPKHhpYW9mZW5nKTogaW5mb3JtIHRoZSB1c2VyIHdpdGggYSB3YXJuaW5nPworICAgICAgIn1cbiIsCisgICAgICAiaW1tdXRhYmxlX2NsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZmlsZV8pKTsKKyAgfQorCisgIC8vIEZvcmNlIGRlc2NyaXB0b3IgaW5pdGlhbGl6YXRpb24gb2YgYWxsIGRlcGVuZGVuY2llcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoU2hvdWxkSW5jbHVkZURlcGVuZGVuY3koZmlsZV8tPmRlcGVuZGVuY3koaSksIGZhbHNlKSkgeworICAgICAgc3RyaW5nIGRlcGVuZGVuY3kgPSBuYW1lX3Jlc29sdmVyXy0+R2V0TXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICAgICBmaWxlXy0+ZGVwZW5kZW5jeShpKSk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiRkZXBlbmRlbmN5JC5nZXREZXNjcmlwdG9yKCk7XG4iLAorICAgICAgICAiZGVwZW5kZW5jeSIsIGRlcGVuZGVuY3kpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBHZW5lcmF0b3JDbGFzcywgdHlwZW5hbWUgRGVzY3JpcHRvckNsYXNzPgorc3RhdGljIHZvaWQgR2VuZXJhdGVTaWJsaW5nKGNvbnN0IHN0cmluZyYgcGFja2FnZV9kaXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBqYXZhX3BhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvckNsYXNzKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGZpbGVfbGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWVfc3VmZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNsYXNzKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoR2VuZXJhdG9yQ2xhc3M6OipwZm4pKGlvOjpQcmludGVyKiBwcmludGVyKSkgeworICBzdHJpbmcgZmlsZW5hbWUgPSBwYWNrYWdlX2RpciArIGRlc2NyaXB0b3ItPm5hbWUoKSArIG5hbWVfc3VmZml4ICsgIi5qYXZhIjsKKyAgZmlsZV9saXN0LT5wdXNoX2JhY2soZmlsZW5hbWUpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoY29udGV4dC0+T3BlbihmaWxlbmFtZSkpOworICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKworICBwcmludGVyLlByaW50KAorICAgICIvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICIvLyBzb3VyY2U6ICRmaWxlbmFtZSRcbiIKKyAgICAiXG4iLAorICAgICJmaWxlbmFtZSIsIGRlc2NyaXB0b3ItPmZpbGUoKS0+bmFtZSgpKTsKKyAgaWYgKCFqYXZhX3BhY2thZ2UuZW1wdHkoKSkgeworICAgIHByaW50ZXIuUHJpbnQoCisgICAgICAicGFja2FnZSAkcGFja2FnZSQ7XG4iCisgICAgICAiXG4iLAorICAgICAgInBhY2thZ2UiLCBqYXZhX3BhY2thZ2UpOworICB9CisKKyAgKGdlbmVyYXRvci0+KnBmbikoJnByaW50ZXIpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlU2libGluZ3MoY29uc3Qgc3RyaW5nJiBwYWNrYWdlX2RpciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBmaWxlX2xpc3QpIHsKKyAgaWYgKE11bHRpcGxlSmF2YUZpbGVzKGZpbGVfLCBpbW11dGFibGVfYXBpXykpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBFbnVtR2VuZXJhdG9yIGdlbmVyYXRvcihmaWxlXy0+ZW51bV90eXBlKGkpLCBpbW11dGFibGVfYXBpXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRfLmdldCgpKTsKKyAgICAgIEdlbmVyYXRlU2libGluZzxFbnVtR2VuZXJhdG9yPihwYWNrYWdlX2RpciwgamF2YV9wYWNrYWdlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlXy0+ZW51bV90eXBlKGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGZpbGVfbGlzdCwgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmdlbmVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmRW51bUdlbmVyYXRvcjo6R2VuZXJhdGUpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBpZiAoaW1tdXRhYmxlX2FwaV8pIHsKKyAgICAgICAgR2VuZXJhdGVTaWJsaW5nPE1lc3NhZ2VHZW5lcmF0b3I+KHBhY2thZ2VfZGlyLCBqYXZhX3BhY2thZ2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGZpbGVfbGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPckJ1aWxkZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZUludGVyZmFjZSk7CisgICAgICB9CisgICAgICBHZW5lcmF0ZVNpYmxpbmc8TWVzc2FnZUdlbmVyYXRvcj4ocGFja2FnZV9kaXIsIGphdmFfcGFja2FnZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBmaWxlX2xpc3QsICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0uZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlKTsKKyAgICB9CisgICAgaWYgKEhhc0dlbmVyaWNTZXJ2aWNlcyhmaWxlXykpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnNlcnZpY2VfY291bnQoKTsgaSsrKSB7CisgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8U2VydmljZUdlbmVyYXRvcj4gZ2VuZXJhdG9yKAorICAgICAgICAgICAgZ2VuZXJhdG9yX2ZhY3RvcnlfLT5OZXdTZXJ2aWNlR2VuZXJhdG9yKGZpbGVfLT5zZXJ2aWNlKGkpKSk7CisgICAgICAgIEdlbmVyYXRlU2libGluZzxTZXJ2aWNlR2VuZXJhdG9yPihwYWNrYWdlX2RpciwgamF2YV9wYWNrYWdlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfLT5zZXJ2aWNlKGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgZmlsZV9saXN0LCAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRvci5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZSk7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK2Jvb2wgRmlsZUdlbmVyYXRvcjo6U2hvdWxkSW5jbHVkZURlcGVuZGVuY3koCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGJvb2wgaW1tdXRhYmxlX2FwaSkgeworICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDgwYjM0MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpbGUuaApAQCAtMCwwICsxLDExOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0ZJTEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0ZJTEVfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7ICAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBjbGFzcyBHZW5lcmF0b3JDb250ZXh0OyAgICAgIC8vIGNvZGVfZ2VuZXJhdG9yLmgKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIE1lc3NhZ2VHZW5lcmF0b3I7ICAgIC8vIG1lc3NhZ2UuaAorICAgICAgY2xhc3MgR2VuZXJhdG9yRmFjdG9yeTsgICAgLy8gZ2VuZXJhdG9yX2ZhY3RvcnkuaAorICAgICAgY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yOyAgLy8gZXh0ZW5zaW9uLmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAgIC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgRmlsZUdlbmVyYXRvciB7CisgcHVibGljOgorICBGaWxlR2VuZXJhdG9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBib29sIGltbXV0YWJsZV9hcGkgPSB0cnVlKTsKKyAgfkZpbGVHZW5lcmF0b3IoKTsKKworICAvLyBDaGVja3MgZm9yIHByb2JsZW1zIHRoYXQgd291bGQgb3RoZXJ3aXNlIGxlYWQgdG8gY3J5cHRpYyBjb21waWxlIGVycm9ycy4KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBubyBwcm9ibGVtcywgb3Igd3JpdGVzIGFuIGVycm9yIGRlc2NyaXB0aW9uIHRvCisgIC8vIHRoZSBnaXZlbiBzdHJpbmcgYW5kIHJldHVybnMgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIFZhbGlkYXRlKHN0cmluZyogZXJyb3IpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIElmIHdlIGFyZW4ndCBwdXR0aW5nIGV2ZXJ5dGhpbmcgaW50byBvbmUgZmlsZSwgdGhpcyB3aWxsIHdyaXRlIGFsbCB0aGUKKyAgLy8gZmlsZXMgb3RoZXIgdGhhbiB0aGUgb3V0ZXIgZmlsZSAoaS5lLiBvbmUgZm9yIGVhY2ggbWVzc2FnZSwgZW51bSwgYW5kCisgIC8vIHNlcnZpY2UgdHlwZSkuCisgIHZvaWQgR2VuZXJhdGVTaWJsaW5ncyhjb25zdCBzdHJpbmcmIHBhY2thZ2VfZGlyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZmlsZV9saXN0KTsKKworICBjb25zdCBzdHJpbmcmIGphdmFfcGFja2FnZSgpIHsgcmV0dXJuIGphdmFfcGFja2FnZV87IH0KKyAgY29uc3Qgc3RyaW5nJiBjbGFzc25hbWUoKSAgICB7IHJldHVybiBjbGFzc25hbWVfOyAgICB9CisKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9ySW1tdXRhYmxlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXphdGlvbkNvZGVGb3JNdXRhYmxlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICBib29sIFNob3VsZEluY2x1ZGVEZXBlbmRlbmN5KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlX2FwaV8pOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgc3RyaW5nIGphdmFfcGFja2FnZV87CisgIHN0cmluZyBjbGFzc25hbWVfOworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2VHZW5lcmF0b3I+ID4gbWVzc2FnZV9nZW5lcmF0b3JzXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RXh0ZW5zaW9uR2VuZXJhdG9yPiA+IGV4dGVuc2lvbl9nZW5lcmF0b3JzXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxHZW5lcmF0b3JGYWN0b3J5PiBnZW5lcmF0b3JfZmFjdG9yeV87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Q29udGV4dD4gY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKyAgYm9vbCBpbW11dGFibGVfYXBpXzsKKworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWxlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0ZJTEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmM2ZjcyOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDE2NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaD4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKKworSmF2YUdlbmVyYXRvcjo6SmF2YUdlbmVyYXRvcigpIHt9CitKYXZhR2VuZXJhdG9yOjp+SmF2YUdlbmVyYXRvcigpIHt9CisKK2Jvb2wgSmF2YUdlbmVyYXRvcjo6R2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIHBhcnNlIGdlbmVyYXRvciBvcHRpb25zCisKKyAgLy8gTmFtZSBhIGZpbGUgd2hlcmUgd2Ugd2lsbCB3cml0ZSBhIGxpc3Qgb2YgZ2VuZXJhdGVkIGZpbGUgbmFtZXMsIG9uZQorICAvLyBwZXIgbGluZS4KKyAgc3RyaW5nIG91dHB1dF9saXN0X2ZpbGU7CisKKworICB2ZWN0b3I8cGFpcjxzdHJpbmcsIHN0cmluZz4gPiBvcHRpb25zOworICBQYXJzZUdlbmVyYXRvclBhcmFtZXRlcihwYXJhbWV0ZXIsICZvcHRpb25zKTsKKworICBib29sIGdlbmVyYXRlX2ltbXV0YWJsZV9jb2RlID0gZmFsc2U7CisgIGJvb2wgZ2VuZXJhdGVfbXV0YWJsZV9jb2RlID0gZmFsc2U7CisgIGJvb2wgZ2VuZXJhdGVfc2hhcmVkX2NvZGUgPSBmYWxzZTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gIm91dHB1dF9saXN0X2ZpbGUiKSB7CisgICAgICBvdXRwdXRfbGlzdF9maWxlID0gb3B0aW9uc1tpXS5zZWNvbmQ7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJpbW11dGFibGUiKSB7CisgICAgICBnZW5lcmF0ZV9pbW11dGFibGVfY29kZSA9IHRydWU7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJtdXRhYmxlIikgeworICAgICAgZ2VuZXJhdGVfbXV0YWJsZV9jb2RlID0gdHJ1ZTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gInNoYXJlZCIpIHsKKyAgICAgIGdlbmVyYXRlX3NoYXJlZF9jb2RlID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgKmVycm9yID0gIlVua25vd24gZ2VuZXJhdG9yIG9wdGlvbjogIiArIG9wdGlvbnNbaV0uZmlyc3Q7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgLy8gQnkgZGVmYXVsdCB3ZSBnZW5lcmF0ZSBpbW11dGFibGUgY29kZSBhbmQgc2hhcmVkIGNvZGUgZm9yIGltbXV0YWJsZSBBUEkuCisgIGlmICghZ2VuZXJhdGVfaW1tdXRhYmxlX2NvZGUgJiYgIWdlbmVyYXRlX211dGFibGVfY29kZSAmJgorICAgICAgIWdlbmVyYXRlX3NoYXJlZF9jb2RlKSB7CisgICAgZ2VuZXJhdGVfaW1tdXRhYmxlX2NvZGUgPSB0cnVlOworICAgIGdlbmVyYXRlX3NoYXJlZF9jb2RlID0gdHJ1ZTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworICB2ZWN0b3I8c3RyaW5nPiBhbGxfZmlsZXM7CisKKworICB2ZWN0b3I8RmlsZUdlbmVyYXRvcio+IGZpbGVfZ2VuZXJhdG9yczsKKyAgaWYgKGdlbmVyYXRlX2ltbXV0YWJsZV9jb2RlKSB7CisgICAgZmlsZV9nZW5lcmF0b3JzLnB1c2hfYmFjayhuZXcgRmlsZUdlbmVyYXRvcihmaWxlLCAvKiBpbW11dGFibGUgPSAqLyB0cnVlKSk7CisgIH0KKyAgaWYgKGdlbmVyYXRlX211dGFibGVfY29kZSkgeworICAgIGZpbGVfZ2VuZXJhdG9ycy5wdXNoX2JhY2sobmV3IEZpbGVHZW5lcmF0b3IoZmlsZSwgLyogbXV0YWJsZSA9ICovIGZhbHNlKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlX2dlbmVyYXRvcnMuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoIWZpbGVfZ2VuZXJhdG9yc1tpXS0+VmFsaWRhdGUoZXJyb3IpKSB7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpbGVfZ2VuZXJhdG9ycy5zaXplKCk7ICsraikgeworICAgICAgICBkZWxldGUgZmlsZV9nZW5lcmF0b3JzW2pdOworICAgICAgfQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV9nZW5lcmF0b3JzLnNpemUoKTsgKytpKSB7CisgICAgRmlsZUdlbmVyYXRvciogZmlsZV9nZW5lcmF0b3IgPSBmaWxlX2dlbmVyYXRvcnNbaV07CisKKyAgICBzdHJpbmcgcGFja2FnZV9kaXIgPSBKYXZhUGFja2FnZVRvRGlyKGZpbGVfZ2VuZXJhdG9yLT5qYXZhX3BhY2thZ2UoKSk7CisKKyAgICBzdHJpbmcgamF2YV9maWxlbmFtZSA9IHBhY2thZ2VfZGlyOworICAgIGphdmFfZmlsZW5hbWUgKz0gZmlsZV9nZW5lcmF0b3ItPmNsYXNzbmFtZSgpOworICAgIGphdmFfZmlsZW5hbWUgKz0gIi5qYXZhIjsKKyAgICBhbGxfZmlsZXMucHVzaF9iYWNrKGphdmFfZmlsZW5hbWUpOworCisgICAgLy8gR2VuZXJhdGUgbWFpbiBqYXZhIGZpbGUuCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dCgKKyAgICAgICAgY29udGV4dC0+T3BlbihqYXZhX2ZpbGVuYW1lKSk7CisgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgZmlsZV9nZW5lcmF0b3ItPkdlbmVyYXRlKCZwcmludGVyKTsKKworICAgIC8vIEdlbmVyYXRlIHNpYmxpbmcgZmlsZXMuCisgICAgZmlsZV9nZW5lcmF0b3ItPkdlbmVyYXRlU2libGluZ3MocGFja2FnZV9kaXIsIGNvbnRleHQsICZhbGxfZmlsZXMpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlX2dlbmVyYXRvcnMuc2l6ZSgpOyArK2kpIHsKKyAgICBkZWxldGUgZmlsZV9nZW5lcmF0b3JzW2ldOworICB9CisgIGZpbGVfZ2VuZXJhdG9ycy5jbGVhcigpOworCisgIC8vIEdlbmVyYXRlIG91dHB1dCBsaXN0IGlmIHJlcXVlc3RlZC4KKyAgaWYgKCFvdXRwdXRfbGlzdF9maWxlLmVtcHR5KCkpIHsKKyAgICAvLyBHZW5lcmF0ZSBvdXRwdXQgbGlzdC4gIFRoaXMgaXMganVzdCBhIHNpbXBsZSB0ZXh0IGZpbGUgcGxhY2VkIGluIGEKKyAgICAvLyBkZXRlcm1pbmlzdGljIGxvY2F0aW9uIHdoaWNoIGxpc3RzIHRoZSAuamF2YSBmaWxlcyBiZWluZyBnZW5lcmF0ZWQuCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IHNyY2xpc3RfcmF3X291dHB1dCgKKyAgICAgICAgY29udGV4dC0+T3BlbihvdXRwdXRfbGlzdF9maWxlKSk7CisgICAgaW86OlByaW50ZXIgc3JjbGlzdF9wcmludGVyKHNyY2xpc3RfcmF3X291dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsbF9maWxlcy5zaXplKCk7IGkrKykgeworICAgICAgc3JjbGlzdF9wcmludGVyLlByaW50KCIkZmlsZW5hbWUkXG4iLCAiZmlsZW5hbWUiLCBhbGxfZmlsZXNbaV0pOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdmNzZiZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvci5oCkBAIC0wLDAgKzEsNzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBHZW5lcmF0ZXMgSmF2YSBjb2RlIGZvciBhIGdpdmVuIC5wcm90byBmaWxlLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCisvLyBDb2RlR2VuZXJhdG9yIGltcGxlbWVudGF0aW9uIHdoaWNoIGdlbmVyYXRlcyBKYXZhIGNvZGUuICBJZiB5b3UgY3JlYXRlIHlvdXIKKy8vIG93biBwcm90b2NvbCBjb21waWxlciBiaW5hcnkgYW5kIHlvdSB3YW50IGl0IHRvIHN1cHBvcnQgSmF2YSBvdXRwdXQsIHlvdQorLy8gY2FuIGRvIHNvIGJ5IHJlZ2lzdGVyaW5nIGFuIGluc3RhbmNlIG9mIHRoaXMgQ29kZUdlbmVyYXRvciB3aXRoIHRoZQorLy8gQ29tbWFuZExpbmVJbnRlcmZhY2UgaW4geW91ciBtYWluKCkgZnVuY3Rpb24uCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIEphdmFHZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBKYXZhR2VuZXJhdG9yKCk7CisgIH5KYXZhR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBDb2RlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEphdmFHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfR0VORVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDE0MzdmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuY2MKQEAgLTAsMCArMSw3NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbGl1amlzaUBnb29nbGUuY29tIChQaGVybCBMaXUpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5Lmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworR2VuZXJhdG9yRmFjdG9yeTo6R2VuZXJhdG9yRmFjdG9yeSgpIHt9CitHZW5lcmF0b3JGYWN0b3J5Ojp+R2VuZXJhdG9yRmFjdG9yeSgpIHt9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeTo6SW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeSgKKyAgICBDb250ZXh0KiBjb250ZXh0KSA6IGNvbnRleHRfKGNvbnRleHQpIHsKK30KK0ltbXV0YWJsZUdlbmVyYXRvckZhY3Rvcnk6On5JbW11dGFibGVHZW5lcmF0b3JGYWN0b3J5KCkge30KKworTWVzc2FnZUdlbmVyYXRvciogSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeTo6TmV3TWVzc2FnZUdlbmVyYXRvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIHJldHVybiBuZXcgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yLCBjb250ZXh0Xyk7Cit9CisKK0V4dGVuc2lvbkdlbmVyYXRvciogSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeTo6TmV3RXh0ZW5zaW9uR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgY29uc3QgeworICByZXR1cm4gbmV3IEltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcihkZXNjcmlwdG9yLCBjb250ZXh0Xyk7Cit9CisKK1NlcnZpY2VHZW5lcmF0b3IqIEltbXV0YWJsZUdlbmVyYXRvckZhY3Rvcnk6Ok5ld1NlcnZpY2VHZW5lcmF0b3IoCisgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgcmV0dXJuIG5ldyBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yKGRlc2NyaXB0b3IsIGNvbnRleHRfKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1MzY1YTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oCkBAIC0wLDAgKzEsMTAxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBsaXVqaXNpQGdvb2dsZS5jb20gKFBoZXJsIExpdSkKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9HRU5FUkFUT1JfRkFDVE9SWV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfR0VORVJBVE9SX0ZBQ1RPUllfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmllbGREZXNjcmlwdG9yOyAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBjbGFzcyBEZXNjcmlwdG9yOyAgICAgICAgICAgICAgLy8gZGVzY3JpcHRvci5oCisgIGNsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOyAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBNZXNzYWdlR2VuZXJhdG9yOyAgICAvLyBtZXNzYWdlLmgKKyAgICAgIGNsYXNzIEV4dGVuc2lvbkdlbmVyYXRvcjsgIC8vIGV4dGVuc2lvbi5oCisgICAgICBjbGFzcyBTZXJ2aWNlR2VuZXJhdG9yOyAgICAvLyBzZXJ2aWNlLmgKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgIH0KKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgR2VuZXJhdG9yRmFjdG9yeSB7CisgcHVibGljOgorICBHZW5lcmF0b3JGYWN0b3J5KCk7CisgIHZpcnR1YWwgfkdlbmVyYXRvckZhY3RvcnkoKTsKKworICB2aXJ0dWFsIE1lc3NhZ2VHZW5lcmF0b3IqIE5ld01lc3NhZ2VHZW5lcmF0b3IoCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCA9IDA7CisKKyAgdmlydHVhbCBFeHRlbnNpb25HZW5lcmF0b3IqIE5ld0V4dGVuc2lvbkdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgY29uc3QgPSAwOworCisgIHZpcnR1YWwgU2VydmljZUdlbmVyYXRvciogTmV3U2VydmljZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoR2VuZXJhdG9yRmFjdG9yeSk7Cit9OworCisvLyBGYWN0b3J5IHRoYXQgY3JlYXRlcyBnZW5lcmF0b3JzIGZvciBpbW11dGFibGUtZGVmYXVsdCBtZXNzYWdlcy4KK2NsYXNzIEltbXV0YWJsZUdlbmVyYXRvckZhY3RvcnkgOiBwdWJsaWMgR2VuZXJhdG9yRmFjdG9yeSB7CisgcHVibGljOgorICBJbW11dGFibGVHZW5lcmF0b3JGYWN0b3J5KENvbnRleHQqIGNvbnRleHQpOworICB2aXJ0dWFsIH5JbW11dGFibGVHZW5lcmF0b3JGYWN0b3J5KCk7CisKKyAgdmlydHVhbCBNZXNzYWdlR2VuZXJhdG9yKiBOZXdNZXNzYWdlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdmlydHVhbCBFeHRlbnNpb25HZW5lcmF0b3IqIE5ld0V4dGVuc2lvbkdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdmlydHVhbCBTZXJ2aWNlR2VuZXJhdG9yKiBOZXdTZXJ2aWNlR2VuZXJhdG9yKAorICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgQ29udGV4dCogY29udGV4dF87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVHZW5lcmF0b3JGYWN0b3J5KTsKK307CisKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfR0VORVJBVE9SX0ZBQ1RPUllfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjQ4OTRiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwpAQCAtMCwwICsxLDc1NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXSA9CisgICIvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iOworY29uc3QgY2hhciBrVGhpblNlcGFyYXRvcltdID0KKyAgIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisKK25hbWVzcGFjZSB7CisKK2NvbnN0IGNoYXIqIGtEZWZhdWx0UGFja2FnZSA9ICIiOworCisvLyBOYW1lcyB0aGF0IHNob3VsZCBiZSBhdm9pZGVkIGFzIGZpZWxkIG5hbWVzLgorLy8gVXNpbmcgdGhlbSB3aWxsIGNhdXNlIHRoZSBjb21waWxlciB0byBnZW5lcmF0ZSBhY2Nlc3NvcnMgd2hvc2UgbmFtZXMgYXJlCisvLyBjb2xsaWRpbmcgd2l0aCBtZXRob2RzIGRlZmluZWQgaW4gYmFzZSBjbGFzc2VzLgorY29uc3QgY2hhcioga0ZvcmJpZGRlbldvcmRMaXN0W10gPSB7CisgIC8vIG1lc3NhZ2UgYmFzZSBjbGFzczoKKyAgImNhY2hlZF9zaXplIiwgInNlcmlhbGl6ZWRfc2l6ZSIsCisgIC8vIGphdmEubGFuZy5PYmplY3Q6CisgICJjbGFzcyIsCit9OworCitib29sIElzRm9yYmlkZGVuKGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoa0ZvcmJpZGRlbldvcmRMaXN0KTsgKytpKSB7CisgICAgaWYgKGZpZWxkX25hbWUgPT0ga0ZvcmJpZGRlbldvcmRMaXN0W2ldKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitzdHJpbmcgRmllbGROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3RyaW5nIGZpZWxkX25hbWU7CisgIC8vIEdyb3VwcyBhcmUgaGFja3k6ICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaXMganVzdCB0aGUgbG93ZXItY2FzZWQgbmFtZQorICAvLyBvZiB0aGUgZ3JvdXAgdHlwZS4gIEluIEphdmEsIHRob3VnaCwgd2Ugd291bGQgbGlrZSB0byByZXRhaW4gdGhlIG9yaWdpbmFsCisgIC8vIGNhcGl0YWxpemF0aW9uIG9mIHRoZSB0eXBlIG5hbWUuCisgIGlmIChHZXRUeXBlKGZpZWxkKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICBmaWVsZF9uYW1lID0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgZmllbGRfbmFtZSA9IGZpZWxkLT5uYW1lKCk7CisgIH0KKyAgaWYgKElzRm9yYmlkZGVuKGZpZWxkX25hbWUpKSB7CisgICAgLy8gQXBwZW5kIGEgdHJhaWxpbmcgIiMiIHRvIGluZGljYXRlIHRoYXQgdGhlIG5hbWUgc2hvdWxkIGJlIGRlY29yYXRlZCB0bworICAgIC8vIGF2b2lkIGNvbGxpc2lvbiB3aXRoIG90aGVyIG5hbWVzLgorICAgIGZpZWxkX25hbWUgKz0gIiMiOworICB9CisgIHJldHVybiBmaWVsZF9uYW1lOworfQorCisKK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBzdHJpbmcmIGlucHV0LCBib29sIGNhcF9uZXh0X2xldHRlcikgeworICBzdHJpbmcgcmVzdWx0OworICAvLyBOb3RlOiAgSSBkaXN0cnVzdCBjdHlwZS5oIGR1ZSB0byBsb2NhbGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCdhJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAneicpIHsKKyAgICAgIGlmIChjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldICsgKCdBJyAtICdhJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICB9CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCdBJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnWicpIHsKKyAgICAgIGlmIChpID09IDAgJiYgIWNhcF9uZXh0X2xldHRlcikgeworICAgICAgICAvLyBGb3JjZSBmaXJzdCBsZXR0ZXIgdG8gbG93ZXItY2FzZSB1bmxlc3MgZXhwbGljaXRseSB0b2xkIHRvCisgICAgICAgIC8vIGNhcGl0YWxpemUgaXQuCisgICAgICAgIHJlc3VsdCArPSBpbnB1dFtpXSArICgnYScgLSAnQScpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gQ2FwaXRhbCBsZXR0ZXJzIGFmdGVyIHRoZSBmaXJzdCBhcmUgbGVmdCBhcy1pcy4KKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgfQorICAgICAgY2FwX25leHRfbGV0dGVyID0gZmFsc2U7CisgICAgfSBlbHNlIGlmICgnMCcgPD0gaW5wdXRbaV0gJiYgaW5wdXRbaV0gPD0gJzknKSB7CisgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSB0cnVlOworICAgIH0KKyAgfQorICAvLyBBZGQgYSB0cmFpbGluZyAiXyIgaWYgdGhlIG5hbWUgc2hvdWxkIGJlIGFsdGVyZWQuCisgIGlmIChpbnB1dFtpbnB1dC5zaXplKCkgLSAxXSA9PSAnIycpIHsKKyAgICByZXN1bHQgKz0gJ18nOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoRmllbGROYW1lKGZpZWxkKSwgZmFsc2UpOworfQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoRmllbGROYW1lKGZpZWxkKSwgdHJ1ZSk7Cit9CisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgeworICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShtZXRob2QtPm5hbWUoKSwgZmFsc2UpOworfQorCitzdHJpbmcgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiAic3RhdGljXyIgKyBTdHJpbmdSZXBsYWNlKGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLCAiLiIsICJfIiwgdHJ1ZSk7Cit9CisKK3N0cmluZyBTdHJpcFByb3RvKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgaWYgKEhhc1N1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90b2RldmVsIikpIHsKKyAgICByZXR1cm4gU3RyaXBTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG9kZXZlbCIpOworICB9IGVsc2UgeworICAgIHJldHVybiBTdHJpcFN1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90byIpOworICB9Cit9CisKK3N0cmluZyBGaWxlQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBib29sIGltbXV0YWJsZSkgeworICBDbGFzc05hbWVSZXNvbHZlciBuYW1lX3Jlc29sdmVyOworICByZXR1cm4gbmFtZV9yZXNvbHZlci5HZXRGaWxlQ2xhc3NOYW1lKGZpbGUsIGltbXV0YWJsZSk7Cit9CisKK3N0cmluZyBGaWxlSmF2YVBhY2thZ2UoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlKSB7CisgIHN0cmluZyByZXN1bHQ7CisKKyAgaWYgKGZpbGUtPm9wdGlvbnMoKS5oYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICByZXN1bHQgPSBmaWxlLT5vcHRpb25zKCkuamF2YV9wYWNrYWdlKCk7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0ga0RlZmF1bHRQYWNrYWdlOworICAgIGlmICghZmlsZS0+cGFja2FnZSgpLmVtcHR5KCkpIHsKKyAgICAgIGlmICghcmVzdWx0LmVtcHR5KCkpIHJlc3VsdCArPSAnLic7CisgICAgICByZXN1bHQgKz0gZmlsZS0+cGFja2FnZSgpOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBKYXZhUGFja2FnZVRvRGlyKHN0cmluZyBwYWNrYWdlX25hbWUpIHsKKyAgc3RyaW5nIHBhY2thZ2VfZGlyID0KKyAgICBTdHJpbmdSZXBsYWNlKHBhY2thZ2VfbmFtZSwgIi4iLCAiLyIsIHRydWUpOworICBpZiAoIXBhY2thZ2VfZGlyLmVtcHR5KCkpIHBhY2thZ2VfZGlyICs9ICIvIjsKKyAgcmV0dXJuIHBhY2thZ2VfZGlyOworfQorCisvLyBUT0RPKHhpYW9mZW5nKTogVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGtlcHQgZm9yIGl0J3MgcHVibGljbHkgcmVmZXJlbmNlZC4KKy8vIEl0IHNob3VsZCBiZSByZW1vdmVkIGFmdGVyIG11dGFibGUgQVBJIHVwLWludGVncmF0aW9uLgorc3RyaW5nIFRvSmF2YU5hbWUoY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsCisgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBzdHJpbmcgcmVzdWx0OworICBpZiAoZmlsZS0+b3B0aW9ucygpLmphdmFfbXVsdGlwbGVfZmlsZXMoKSkgeworICAgIHJlc3VsdCA9IEZpbGVKYXZhUGFja2FnZShmaWxlKTsKKyAgfSBlbHNlIHsKKyAgICByZXN1bHQgPSBDbGFzc05hbWUoZmlsZSk7CisgIH0KKyAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgeworICAgIHJlc3VsdCArPSAnLic7CisgIH0KKyAgaWYgKGZpbGUtPnBhY2thZ2UoKS5lbXB0eSgpKSB7CisgICAgcmVzdWx0ICs9IGZ1bGxfbmFtZTsKKyAgfSBlbHNlIHsKKyAgICAvLyBTdHJpcCB0aGUgcHJvdG8gcGFja2FnZSBmcm9tIGZ1bGxfbmFtZSBzaW5jZSB3ZSd2ZSByZXBsYWNlZCBpdCB3aXRoCisgICAgLy8gdGhlIEphdmEgcGFja2FnZS4KKyAgICByZXN1bHQgKz0gZnVsbF9uYW1lLnN1YnN0cihmaWxlLT5wYWNrYWdlKCkuc2l6ZSgpICsgMSk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIENsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIENsYXNzTmFtZVJlc29sdmVyIG5hbWVfcmVzb2x2ZXI7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLkdldENsYXNzTmFtZShkZXNjcmlwdG9yLCB0cnVlKTsKK30KKworc3RyaW5nIENsYXNzTmFtZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBDbGFzc05hbWVSZXNvbHZlciBuYW1lX3Jlc29sdmVyOworICByZXR1cm4gbmFtZV9yZXNvbHZlci5HZXRDbGFzc05hbWUoZGVzY3JpcHRvciwgdHJ1ZSk7Cit9CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIgbmFtZV9yZXNvbHZlcjsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXIuR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3IsIHRydWUpOworfQorCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIENsYXNzTmFtZVJlc29sdmVyIG5hbWVfcmVzb2x2ZXI7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLkdldENsYXNzTmFtZShkZXNjcmlwdG9yLCB0cnVlKTsKK30KKworc3RyaW5nIEV4dHJhTWVzc2FnZUludGVyZmFjZXMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgaW50ZXJmYWNlcyA9ICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOiIKKyAgICAgICsgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgKyAiKSI7CisgIHJldHVybiBpbnRlcmZhY2VzOworfQorCisKK3N0cmluZyBFeHRyYUJ1aWxkZXJJbnRlcmZhY2VzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgc3RyaW5nIGludGVyZmFjZXMgPSAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czoiCisgICAgICArIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpICsgIikiOworICByZXR1cm4gaW50ZXJmYWNlczsKK30KKworc3RyaW5nIEV4dHJhTWVzc2FnZU9yQnVpbGRlckludGVyZmFjZXMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgaW50ZXJmYWNlcyA9ICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6IgorICAgICAgKyBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSArICIpIjsKKyAgcmV0dXJuIGludGVyZmFjZXM7Cit9CisKK3N0cmluZyBGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKSB7CisgIHN0cmluZyBuYW1lID0gZmllbGQtPm5hbWUoKSArICJfRklFTERfTlVNQkVSIjsKKyAgVXBwZXJTdHJpbmcoJm5hbWUpOworICByZXR1cm4gbmFtZTsKK30KKworRmllbGREZXNjcmlwdG9yOjpUeXBlIEdldFR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gZmllbGQtPnR5cGUoKTsKK30KKworSmF2YVR5cGUgR2V0SmF2YVR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKEdldFR5cGUoZmllbGQpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0lOVDsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9MT05HOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gSkFWQVRZUEVfRkxPQVQ7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gSkFWQVRZUEVfRE9VQkxFOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9CT09MRUFOOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX1NUUklORzsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0JZVEVTOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTToKKyAgICAgIHJldHVybiBKQVZBVFlQRV9FTlVNOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVA6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiBKQVZBVFlQRV9NRVNTQUdFOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIEpBVkFUWVBFX0lOVDsKK30KKworY29uc3QgY2hhciogUHJpbWl0aXZlVHlwZU5hbWUoSmF2YVR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEpBVkFUWVBFX0lOVCAgICA6IHJldHVybiAiaW50IjsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiAibG9uZyI7CisgICAgY2FzZSBKQVZBVFlQRV9GTE9BVCAgOiByZXR1cm4gImZsb2F0IjsKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRSA6IHJldHVybiAiZG91YmxlIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiAiYm9vbGVhbiI7CisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkcgOiByZXR1cm4gImphdmEubGFuZy5TdHJpbmciOworICAgIGNhc2UgSkFWQVRZUEVfQllURVMgIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmciOworICAgIGNhc2UgSkFWQVRZUEVfRU5VTSAgIDogcmV0dXJuIE5VTEw7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOiByZXR1cm4gTlVMTDsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gSmF2YVR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworY29uc3QgY2hhciogQm94ZWRQcmltaXRpdmVUeXBlTmFtZShKYXZhVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuICJqYXZhLmxhbmcuSW50ZWdlciI7CisgICAgY2FzZSBKQVZBVFlQRV9MT05HICAgOiByZXR1cm4gImphdmEubGFuZy5Mb25nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiAiamF2YS5sYW5nLkZsb2F0IjsKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRSA6IHJldHVybiAiamF2YS5sYW5nLkRvdWJsZSI7CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOiByZXR1cm4gImphdmEubGFuZy5Cb29sZWFuIjsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiAiamF2YS5sYW5nLlN0cmluZyI7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUyAgOiByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyI7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gTlVMTDsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiBOVUxMOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBjaGFyKiBGaWVsZFR5cGVOYW1lKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSBmaWVsZF90eXBlKSB7CisgIHN3aXRjaCAoZmllbGRfdHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyICAgOiByZXR1cm4gIklOVDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzIgIDogcmV0dXJuICJVSU5UMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMiAgOiByZXR1cm4gIlNJTlQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMiA6IHJldHVybiAiRklYRUQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6IHJldHVybiAiU0ZJWEVEMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gIklOVDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQgIDogcmV0dXJuICJVSU5UNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NCAgOiByZXR1cm4gIlNJTlQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NCA6IHJldHVybiAiRklYRUQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6IHJldHVybiAiU0ZJWEVENjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUICAgOiByZXR1cm4gIkZMT0FUIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEUgIDogcmV0dXJuICJET1VCTEUiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0wgICAgOiByZXR1cm4gIkJPT0wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAgOiByZXR1cm4gIlNUUklORyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMgICA6IHJldHVybiAiQllURVMiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0gICAgOiByZXR1cm4gIkVOVU0iOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gIkdST1VQIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuICJNRVNTQUdFIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitib29sIEFsbEFzY2lpKGNvbnN0IHN0cmluZyYgdGV4dCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHRleHQuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoKHRleHRbaV0gJiAweDgwKSAhPSAwKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCitzdHJpbmcgRGVmYXVsdFZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcikgeworICAvLyBTd2l0Y2ggb24gQ3BwVHlwZSBzaW5jZSB3ZSBuZWVkIHRvIGtub3cgd2hpY2ggZGVmYXVsdF92YWx1ZV8qIG1ldGhvZAorICAvLyBvZiBGaWVsZERlc2NyaXB0b3IgdG8gY2FsbC4KKyAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50MzIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgLy8gTmVlZCB0byBwcmludCBhcyBhIHNpZ25lZCBpbnQgc2luY2UgSmF2YSBoYXMgbm8gdW5zaWduZWQuCisgICAgICByZXR1cm4gU2ltcGxlSXRvYShzdGF0aWNfY2FzdDxpbnQzMj4oZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDMyKCkpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkpICsgIkwiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludDY0PihmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50NjQoKSkpICsKKyAgICAgICAgICAgICAiTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiRG91YmxlLlBPU0lUSVZFX0lORklOSVRZIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgcmV0dXJuICJEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gIkRvdWJsZS5OYU4iOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIFNpbXBsZUR0b2EodmFsdWUpICsgIkQiOworICAgICAgfQorICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDogeworICAgICAgZmxvYXQgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICByZXR1cm4gIkZsb2F0LlBPU0lUSVZFX0lORklOSVRZIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICByZXR1cm4gIkZsb2F0Lk5FR0FUSVZFX0lORklOSVRZIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuICJGbG9hdC5OYU4iOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIFNpbXBsZUZ0b2EodmFsdWUpICsgIkYiOworICAgICAgfQorICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2Jvb2woKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgaWYgKEdldFR5cGUoZmllbGQpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUykgeworICAgICAgICBpZiAoZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgICAgICAvLyBTZWUgY29tbWVudHMgaW4gSW50ZXJuYWwuamF2YSBmb3IgZ29yeSBkZXRhaWxzLgorICAgICAgICAgIHJldHVybiBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoXCIkMFwiKSIsCisgICAgICAgICAgICBDRXNjYXBlKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkiOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoQWxsQXNjaWkoZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpKSB7CisgICAgICAgICAgLy8gQWxsIGNoYXJzIGFyZSBBU0NJSS4gIEluIHRoaXMgY2FzZSBDRXNjYXBlKCkgd29ya3MgZmluZS4KKyAgICAgICAgICByZXR1cm4gIlwiIiArIENFc2NhcGUoZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpICsgIlwiIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBTZWUgY29tbWVudHMgaW4gSW50ZXJuYWwuamF2YSBmb3IgZ29yeSBkZXRhaWxzLgorICAgICAgICAgIHJldHVybiBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5zdHJpbmdEZWZhdWx0VmFsdWUoXCIkMFwiKSIsCisgICAgICAgICAgICAgIENFc2NhcGUoZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgIHJldHVybiBuYW1lX3Jlc29sdmVyLT5HZXRDbGFzc05hbWUoZmllbGQtPmVudW1fdHlwZSgpLCBpbW11dGFibGUpICsgIi4iICsKKyAgICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm5hbWUoKTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gbmFtZV9yZXNvbHZlci0+R2V0Q2xhc3NOYW1lKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgaW1tdXRhYmxlKSArCisgICAgICAgICAgIi5nZXREZWZhdWx0SW5zdGFuY2UoKSI7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIHR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKK2Jvb2wgSXNEZWZhdWx0VmFsdWVKYXZhRGVmYXVsdChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIFN3aXRjaCBvbiBDcHBUeXBlIHNpbmNlIHdlIG5lZWQgdG8ga25vdyB3aGljaCBkZWZhdWx0X3ZhbHVlXyogbWV0aG9kCisgIC8vIG9mIEZpZWxkRGVzY3JpcHRvciB0byBjYWxsLgorICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50MzIoKSA9PSAwOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSA9PSAwOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkgPT0gMEw7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpID09IDBMOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKSA9PSAwLjA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfZmxvYXQoKSA9PSAwLjA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9ib29sKCkgPT0gZmFsc2U7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIGZhbHNlOworfQorCitjb25zdCBjaGFyKiBiaXRfbWFza3NbXSA9IHsKKyAgIjB4MDAwMDAwMDEiLAorICAiMHgwMDAwMDAwMiIsCisgICIweDAwMDAwMDA0IiwKKyAgIjB4MDAwMDAwMDgiLAorICAiMHgwMDAwMDAxMCIsCisgICIweDAwMDAwMDIwIiwKKyAgIjB4MDAwMDAwNDAiLAorICAiMHgwMDAwMDA4MCIsCisKKyAgIjB4MDAwMDAxMDAiLAorICAiMHgwMDAwMDIwMCIsCisgICIweDAwMDAwNDAwIiwKKyAgIjB4MDAwMDA4MDAiLAorICAiMHgwMDAwMTAwMCIsCisgICIweDAwMDAyMDAwIiwKKyAgIjB4MDAwMDQwMDAiLAorICAiMHgwMDAwODAwMCIsCisKKyAgIjB4MDAwMTAwMDAiLAorICAiMHgwMDAyMDAwMCIsCisgICIweDAwMDQwMDAwIiwKKyAgIjB4MDAwODAwMDAiLAorICAiMHgwMDEwMDAwMCIsCisgICIweDAwMjAwMDAwIiwKKyAgIjB4MDA0MDAwMDAiLAorICAiMHgwMDgwMDAwMCIsCisKKyAgIjB4MDEwMDAwMDAiLAorICAiMHgwMjAwMDAwMCIsCisgICIweDA0MDAwMDAwIiwKKyAgIjB4MDgwMDAwMDAiLAorICAiMHgxMDAwMDAwMCIsCisgICIweDIwMDAwMDAwIiwKKyAgIjB4NDAwMDAwMDAiLAorICAiMHg4MDAwMDAwMCIsCit9OworCitzdHJpbmcgR2V0Qml0RmllbGROYW1lKGludCBpbmRleCkgeworICBzdHJpbmcgdmFyTmFtZSA9ICJiaXRGaWVsZCI7CisgIHZhck5hbWUgKz0gU2ltcGxlSXRvYShpbmRleCk7CisgIHZhck5hbWUgKz0gIl8iOworICByZXR1cm4gdmFyTmFtZTsKK30KKworc3RyaW5nIEdldEJpdEZpZWxkTmFtZUZvckJpdChpbnQgYml0SW5kZXgpIHsKKyAgcmV0dXJuIEdldEJpdEZpZWxkTmFtZShiaXRJbmRleCAvIDMyKTsKK30KKworbmFtZXNwYWNlIHsKKworc3RyaW5nIEdlbmVyYXRlR2V0Qml0SW50ZXJuYWwoY29uc3Qgc3RyaW5nJiBwcmVmaXgsIGludCBiaXRJbmRleCkgeworICBzdHJpbmcgdmFyTmFtZSA9IHByZWZpeCArIEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRJbmRleCk7CisgIGludCBiaXRJblZhckluZGV4ID0gYml0SW5kZXggJSAzMjsKKworICBzdHJpbmcgbWFzayA9IGJpdF9tYXNrc1tiaXRJblZhckluZGV4XTsKKyAgc3RyaW5nIHJlc3VsdCA9ICIoKCIgKyB2YXJOYW1lICsgIiAmICIgKyBtYXNrICsgIikgPT0gIiArIG1hc2sgKyAiKSI7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBHZW5lcmF0ZVNldEJpdEludGVybmFsKGNvbnN0IHN0cmluZyYgcHJlZml4LCBpbnQgYml0SW5kZXgpIHsKKyAgc3RyaW5nIHZhck5hbWUgPSBwcmVmaXggKyBHZXRCaXRGaWVsZE5hbWVGb3JCaXQoYml0SW5kZXgpOworICBpbnQgYml0SW5WYXJJbmRleCA9IGJpdEluZGV4ICUgMzI7CisKKyAgc3RyaW5nIG1hc2sgPSBiaXRfbWFza3NbYml0SW5WYXJJbmRleF07CisgIHN0cmluZyByZXN1bHQgPSB2YXJOYW1lICsgIiB8PSAiICsgbWFzazsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK3N0cmluZyBHZW5lcmF0ZUdldEJpdChpbnQgYml0SW5kZXgpIHsKKyAgcmV0dXJuIEdlbmVyYXRlR2V0Qml0SW50ZXJuYWwoIiIsIGJpdEluZGV4KTsKK30KKworc3RyaW5nIEdlbmVyYXRlU2V0Qml0KGludCBiaXRJbmRleCkgeworICByZXR1cm4gR2VuZXJhdGVTZXRCaXRJbnRlcm5hbCgiIiwgYml0SW5kZXgpOworfQorCitzdHJpbmcgR2VuZXJhdGVDbGVhckJpdChpbnQgYml0SW5kZXgpIHsKKyAgc3RyaW5nIHZhck5hbWUgPSBHZXRCaXRGaWVsZE5hbWVGb3JCaXQoYml0SW5kZXgpOworICBpbnQgYml0SW5WYXJJbmRleCA9IGJpdEluZGV4ICUgMzI7CisKKyAgc3RyaW5nIG1hc2sgPSBiaXRfbWFza3NbYml0SW5WYXJJbmRleF07CisgIHN0cmluZyByZXN1bHQgPSB2YXJOYW1lICsgIiA9ICgiICsgdmFyTmFtZSArICIgJiB+IiArIG1hc2sgKyAiKSI7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBHZW5lcmF0ZUdldEJpdEZyb21Mb2NhbChpbnQgYml0SW5kZXgpIHsKKyAgcmV0dXJuIEdlbmVyYXRlR2V0Qml0SW50ZXJuYWwoImZyb21fIiwgYml0SW5kZXgpOworfQorCitzdHJpbmcgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKGludCBiaXRJbmRleCkgeworICByZXR1cm4gR2VuZXJhdGVTZXRCaXRJbnRlcm5hbCgidG9fIiwgYml0SW5kZXgpOworfQorCitzdHJpbmcgR2VuZXJhdGVHZXRCaXRNdXRhYmxlTG9jYWwoaW50IGJpdEluZGV4KSB7CisgIHJldHVybiBHZW5lcmF0ZUdldEJpdEludGVybmFsKCJtdXRhYmxlXyIsIGJpdEluZGV4KTsKK30KKworc3RyaW5nIEdlbmVyYXRlU2V0Qml0TXV0YWJsZUxvY2FsKGludCBiaXRJbmRleCkgeworICByZXR1cm4gR2VuZXJhdGVTZXRCaXRJbnRlcm5hbCgibXV0YWJsZV8iLCBiaXRJbmRleCk7Cit9CisKK2Jvb2wgSXNSZWZlcmVuY2VUeXBlKEphdmFUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQgICAgOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9MT05HICAgOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9GTE9BVCAgOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEUgOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkcgOiByZXR1cm4gdHJ1ZTsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTICA6IHJldHVybiB0cnVlOworICAgIGNhc2UgSkFWQVRZUEVfRU5VTSAgIDogcmV0dXJuIHRydWU7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOiByZXR1cm4gdHJ1ZTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gSmF2YVR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gZmFsc2U7Cit9CisKK2NvbnN0IGNoYXIqIEdldENhcGl0YWxpemVkVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBib29sIGltbXV0YWJsZSkgeworICBzd2l0Y2ggKEdldFR5cGUoZmllbGQpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAiSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gIlVJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyICA6IHJldHVybiAiU0ludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuICJGaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjogcmV0dXJuICJTRml4ZWQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQgICA6IHJldHVybiAiSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NCAgOiByZXR1cm4gIlVJbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0ICA6IHJldHVybiAiU0ludDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0IDogcmV0dXJuICJGaXhlZDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJTRml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiAiRmxvYXQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gIkRvdWJsZSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTCAgICA6IHJldHVybiAiQm9vbCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAiU3RyaW5nIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogeworICAgICAgcmV0dXJuICJCeXRlcyI7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0gICAgOiByZXR1cm4gIkVudW0iOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gIkdyb3VwIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuICJNZXNzYWdlIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCisvLyBGb3IgZW5jb2RpbmdzIHdpdGggZml4ZWQgc2l6ZXMsIHJldHVybnMgdGhhdCBzaXplIGluIGJ5dGVzLiAgT3RoZXJ3aXNlCisvLyByZXR1cm5zIC0xLgoraW50IEZpeGVkU2l6ZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMiAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMiAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0ICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRml4ZWQzMlNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NCA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0ZpeGVkNjRTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtTRml4ZWQzMlNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a1NGaXhlZDY0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVCAgIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRmxvYXRTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtEb3VibGVTaXplOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTCAgICA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0Jvb2xTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0gICAgOiByZXR1cm4gLTE7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuIC0xOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAtMTsKK30KKworLy8gU29ydCB0aGUgZmllbGRzIG9mIHRoZSBnaXZlbiBEZXNjcmlwdG9yIGJ5IG51bWJlciBpbnRvIGEgbmV3W10nZCBhcnJheQorLy8gYW5kIHJldHVybiBpdC4gVGhlIGNhbGxlciBzaG91bGQgZGVsZXRlIHRoZSByZXR1cm5lZCBhcnJheS4KK2NvbnN0IEZpZWxkRGVzY3JpcHRvcioqIFNvcnRGaWVsZHNCeU51bWJlcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioqIGZpZWxkcyA9CisgICAgbmV3IGNvbnN0IEZpZWxkRGVzY3JpcHRvcipbZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKV07CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRzW2ldID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgIH0KKyAgc3RkOjpzb3J0KGZpZWxkcywgZmllbGRzICsgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKSwKKyAgICAgICAgICAgIEZpZWxkT3JkZXJpbmdCeU51bWJlcigpKTsKKyAgcmV0dXJuIGZpZWxkczsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBtZXNzYWdlIHR5cGUgaGFzIGFueSByZXF1aXJlZCBmaWVsZHMuICBJZiBpdCBkb2Vzbid0LAorLy8gd2UgY2FuIG9wdGltaXplIG91dCBjYWxscyB0byBpdHMgaXNJbml0aWFsaXplZCgpIG1ldGhvZC4KKy8vCisvLyBhbHJlYWR5X3NlZW4gaXMgdXNlZCB0byBhdm9pZCBjaGVja2luZyB0aGUgc2FtZSB0eXBlIG11bHRpcGxlIHRpbWVzCisvLyAoYW5kIGFsc28gdG8gcHJvdGVjdCBhZ2FpbnN0IHJlY3Vyc2lvbikuCitib29sIEhhc1JlcXVpcmVkRmllbGRzKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUsCisgICAgaGFzaF9zZXQ8Y29uc3QgRGVzY3JpcHRvcio+KiBhbHJlYWR5X3NlZW4pIHsKKyAgaWYgKGFscmVhZHlfc2Vlbi0+Y291bnQodHlwZSkgPiAwKSB7CisgICAgLy8gVGhlIHR5cGUgaXMgYWxyZWFkeSBpbiBjYWNoZS4gIFRoaXMgbWVhbnMgdGhhdCBlaXRoZXI6CisgICAgLy8gYS4gVGhlIHR5cGUgaGFzIG5vIHJlcXVpcmVkIGZpZWxkcy4KKyAgICAvLyBiLiBXZSBhcmUgaW4gdGhlIG1pZHN0IG9mIGNoZWNraW5nIGlmIHRoZSB0eXBlIGhhcyByZXF1aXJlZCBmaWVsZHMsCisgICAgLy8gICAgc29tZXdoZXJlIHVwIHRoZSBzdGFjay4gIEluIHRoaXMgY2FzZSwgd2Uga25vdyB0aGF0IGlmIHRoZSB0eXBlCisgICAgLy8gICAgaGFzIGFueSByZXF1aXJlZCBmaWVsZHMsIHRoZXknbGwgYmUgZm91bmQgd2hlbiB3ZSByZXR1cm4gdG8gaXQsCisgICAgLy8gICAgYW5kIHRoZSB3aG9sZSBjYWxsIHRvIEhhc1JlcXVpcmVkRmllbGRzKCkgd2lsbCByZXR1cm4gdHJ1ZS4KKyAgICAvLyAgICBUaGVyZWZvcmUsIHdlIGRvbid0IGhhdmUgdG8gY2hlY2sgaWYgdGhpcyB0eXBlIGhhcyByZXF1aXJlZCBmaWVsZHMKKyAgICAvLyAgICBoZXJlLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBhbHJlYWR5X3NlZW4tPmluc2VydCh0eXBlKTsKKworICAvLyBJZiB0aGUgdHlwZSBoYXMgZXh0ZW5zaW9ucywgYW4gZXh0ZW5zaW9uIHdpdGggbWVzc2FnZSB0eXBlIGNvdWxkIGNvbnRhaW4KKyAgLy8gcmVxdWlyZWQgZmllbGRzLCBzbyB3ZSBoYXZlIHRvIGJlIGNvbnNlcnZhdGl2ZSBhbmQgYXNzdW1lIHN1Y2ggYW4KKyAgLy8gZXh0ZW5zaW9uIGV4aXN0cy4KKyAgaWYgKHR5cGUtPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgICBpZiAoSGFzUmVxdWlyZWRGaWVsZHMoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCBhbHJlYWR5X3NlZW4pKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBIYXNSZXF1aXJlZEZpZWxkcyhjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSB7CisgIGhhc2hfc2V0PGNvbnN0IERlc2NyaXB0b3IqPiBhbHJlYWR5X3NlZW47CisgIHJldHVybiBIYXNSZXF1aXJlZEZpZWxkcyh0eXBlLCAmYWxyZWFkeV9zZWVuKTsKK30KKworYm9vbCBIYXNSZXBlYXRlZEZpZWxkcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjJlZmJlZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaApAQCAtMCwwICsxLDM0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0hFTFBFUlNfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0hFTFBFUlNfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCisvLyBDb21tb25seS11c2VkIHNlcGFyYXRvciBjb21tZW50cy4gIFRoaWNrIGlzIGEgbGluZSBvZiAnPScsIHRoaW4gaXMgYSBsaW5lCisvLyBvZiAnLScuCitleHRlcm4gY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXTsKK2V4dGVybiBjb25zdCBjaGFyIGtUaGluU2VwYXJhdG9yW107CisKKy8vIENvbnZlcnRzIGEgbmFtZSB0byBjYW1lbC1jYXNlLiBJZiBjYXBfZmlyc3RfbGV0dGVyIGlzIHRydWUsIGNhcGl0YWxpemUgdGhlCisvLyBmaXJzdCBsZXR0ZXIuCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBzdHJpbmcmIG5hbWUsIGJvb2wgY2FwX2ZpcnN0X2xldHRlcik7CisvLyBDb252ZXJ0cyB0aGUgZmllbGQncyBuYW1lIHRvIGNhbWVsLWNhc2UsIGUuZy4gImZvb19iYXJfYmF6IiBiZWNvbWVzCisvLyAiZm9vQmFyQmF6IiBvciAiRm9vQmFyQmF6IiwgcmVzcGVjdGl2ZWx5Lgorc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CitzdHJpbmcgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBTaW1pbGFyLCBidXQgZm9yIG1ldGhvZCBuYW1lcy4gIChUeXBpY2FsbHksIHRoaXMgbWVyZWx5IGhhcyB0aGUgZWZmZWN0CisvLyBvZiBsb3dlci1jYXNpbmcgdGhlIGZpcnN0IGxldHRlciBvZiB0aGUgbmFtZS4pCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpOworCisvLyBHZXQgYW4gaWRlbnRpZmllciB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyB0eXBlIHdpdGhpbiB0aGUgZmlsZS4KKy8vIFRoaXMgaXMgdXNlZCB0byBkZWNsYXJlIHN0YXRpYyB2YXJpYWJsZXMgcmVsYXRlZCB0byB0aGlzIHR5cGUgYXQgdGhlCisvLyBvdXRlcm1vc3QgZmlsZSBzY29wZS4KK3N0cmluZyBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBTdHJpcHMgIi5wcm90byIgb3IgIi5wcm90b2RldmVsIiBmcm9tIHRoZSBlbmQgb2YgYSBmaWxlbmFtZS4KK3N0cmluZyBTdHJpcFByb3RvKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisvLyBHZXRzIHRoZSB1bnF1YWxpZmllZCBjbGFzcyBuYW1lIGZvciB0aGUgZmlsZS4gIEZvciBlYWNoIC5wcm90byBmaWxlLCB0aGVyZQorLy8gd2lsbCBiZSBvbmUgSmF2YSBjbGFzcyBjb250YWluaW5nIGFsbCB0aGUgaW1tdXRhYmxlIG1lc3NhZ2VzIGFuZCBhbm90aGVyCisvLyBKYXZhIGNsYXNzIGNvbnRhaW5pbmcgYWxsIHRoZSBtdXRhYmxlIG1lc3NhZ2VzLgorLy8gVE9ETyh4aWFvZmVuZyk6IHJlbW92ZSB0aGUgZGVmYXVsdCB2YWx1ZSBhZnRlciB1cGRhdGluZyBjbGllbnQgY29kZS4KK3N0cmluZyBGaWxlQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBib29sIGltbXV0YWJsZSA9IHRydWUpOworCisvLyBSZXR1cm5zIHRoZSBmaWxlJ3MgSmF2YSBwYWNrYWdlIG5hbWUuCitzdHJpbmcgRmlsZUphdmFQYWNrYWdlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBib29sIGltbXV0YWJsZSA9IHRydWUpOworCisvLyBSZXR1cm5zIG91dHB1dCBkaXJlY3RvcnkgZm9yIHRoZSBnaXZlbiBwYWNrYWdlIG5hbWUuCitzdHJpbmcgSmF2YVBhY2thZ2VUb0RpcihzdHJpbmcgcGFja2FnZV9uYW1lKTsKKworLy8gQ29udmVydHMgdGhlIGdpdmVuIGZ1bGx5LXF1YWxpZmllZCBuYW1lIGluIHRoZSBwcm90byBuYW1lc3BhY2UgdG8gaXRzCisvLyBmdWxseS1xdWFsaWZpZWQgbmFtZSBpbiB0aGUgSmF2YSBuYW1lc3BhY2UsIGdpdmVuIHRoYXQgaXQgaXMgaW4gdGhlIGdpdmVuCisvLyBmaWxlLgorLy8gVE9ETyh4aWFvZmVuZyk6IHRoaXMgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYW5kIHNob3VsZCBiZSByZW1vdmVkIGluIHRoZQorLy8gZnV0dXJlLgorc3RyaW5nIFRvSmF2YU5hbWUoY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsCisgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIFRPRE8oeGlhb2ZlbmcpOiB0aGUgZm9sbG93aW5nIG1ldGhvZHMgYXJlIGtlcHQgZm9yIHRoZXkgYXJlIGV4cG9zZWQKKy8vIHB1YmxpY2x5IGluIC8vZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvbmFtZXMuaC4gVGhleSByZXR1cm4KKy8vIGltbXV0YWJsZSBuYW1lcyBvbmx5IGFuZCBzaG91bGQgYmUgcmVtb3ZlZCBhZnRlciBtdXRhYmxlIEFQSSBpcworLy8gaW50ZWdyYXRlZCBpbnRvIGdvb2dsZTMuCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworc3RyaW5nIENsYXNzTmFtZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBDb21tYS1zZXBhcmF0ZSBsaXN0IG9mIG9wdGlvbi1zcGVjaWZpZWQgaW50ZXJmYWNlcyBpbXBsZW1lbnRlZCBieSB0aGUKKy8vIE1lc3NhZ2UsIHRvIGZvbGxvdyB0aGUgImltcGxlbWVudHMiIGRlY2xhcmF0aW9uIG9mIHRoZSBNZXNzYWdlIGRlZmluaXRpb24uCitzdHJpbmcgRXh0cmFNZXNzYWdlSW50ZXJmYWNlcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKy8vIENvbW1hLXNlcGFyYXRlIGxpc3Qgb2Ygb3B0aW9uLXNwZWNpZmllZCBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IHRoZQorLy8gTXV0YWJsZU1lc3NhZ2UsIHRvIGZvbGxvdyB0aGUgImltcGxlbWVudHMiIGRlY2xhcmF0aW9uIG9mIHRoZSBNdXRhYmxlTWVzc2FnZQorLy8gZGVmaW5pdGlvbi4KK3N0cmluZyBFeHRyYU11dGFibGVNZXNzYWdlSW50ZXJmYWNlcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKy8vIENvbW1hLXNlcGFyYXRlIGxpc3Qgb2Ygb3B0aW9uLXNwZWNpZmllZCBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IHRoZQorLy8gQnVpbGRlciwgdG8gZm9sbG93IHRoZSAiaW1wbGVtZW50cyIgZGVjbGFyYXRpb24gb2YgdGhlIEJ1aWxkZXIgZGVmaW5pdGlvbi4KK3N0cmluZyBFeHRyYUJ1aWxkZXJJbnRlcmZhY2VzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworLy8gQ29tbWEtc2VwYXJhdGUgbGlzdCBvZiBvcHRpb24tc3BlY2lmaWVkIGludGVyZmFjZXMgZXh0ZW5kZWQgYnkgdGhlCisvLyBNZXNzYWdlT3JCdWlsZGVyLCB0byBmb2xsb3cgdGhlICJleHRlbmRzIiBkZWNsYXJhdGlvbiBvZiB0aGUKKy8vIE1lc3NhZ2VPckJ1aWxkZXIgZGVmaW5pdGlvbi4KK3N0cmluZyBFeHRyYU1lc3NhZ2VPckJ1aWxkZXJJbnRlcmZhY2VzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBHZXQgdGhlIHVucXVhbGlmaWVkIEphdmEgY2xhc3MgbmFtZSBmb3IgbXV0YWJsZSBtZXNzYWdlcy4gaS5lLiB3aXRob3V0CisvLyBwYWNrYWdlIG9yIG91dGVyIGNsYXNzbmFtZXMuCitpbmxpbmUgc3RyaW5nIFNob3J0TXV0YWJsZUphdmFDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+bmFtZSgpOworfQorCisKKy8vIFdoZXRoZXIgd2Ugc2hvdWxkIGdlbmVyYXRlIG11bHRpcGxlIGphdmEgZmlsZXMgZm9yIG1lc3NhZ2VzLgoraW5saW5lIGJvb2wgTXVsdGlwbGVKYXZhRmlsZXMoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGJvb2wgaW1tdXRhYmxlKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5vcHRpb25zKCkuamF2YV9tdWx0aXBsZV9maWxlcygpOworfQorCisvLyBHZXQgdGhlIHVucXVhbGlmaWVkIG5hbWUgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgYSBmaWVsZCdzIGZpZWxkCisvLyBudW1iZXIgY29uc3RhbnQuCitzdHJpbmcgRmllbGRDb25zdGFudE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZCk7CisKKy8vIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIEZpZWxkRGVzY3JpcHRvci4KKy8vIFRoaXMgZG9lcyBub3RoaW5nIGludGVyZXN0aW5nIGZvciB0aGUgb3BlbiBzb3VyY2UgcmVsZWFzZSwgYnV0IGlzIHVzZWQgZm9yCisvLyBoYWNrcyB0aGF0IGltcHJvdmUgY29tcGF0aWJpbGl0eSB3aXRoIHZlcnNpb24gMSBwcm90b2NvbCBidWZmZXJzIGF0IEdvb2dsZS4KK0ZpZWxkRGVzY3JpcHRvcjo6VHlwZSBHZXRUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCitlbnVtIEphdmFUeXBlIHsKKyAgSkFWQVRZUEVfSU5ULAorICBKQVZBVFlQRV9MT05HLAorICBKQVZBVFlQRV9GTE9BVCwKKyAgSkFWQVRZUEVfRE9VQkxFLAorICBKQVZBVFlQRV9CT09MRUFOLAorICBKQVZBVFlQRV9TVFJJTkcsCisgIEpBVkFUWVBFX0JZVEVTLAorICBKQVZBVFlQRV9FTlVNLAorICBKQVZBVFlQRV9NRVNTQUdFCit9OworCitKYXZhVHlwZSBHZXRKYXZhVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworY29uc3QgY2hhciogUHJpbWl0aXZlVHlwZU5hbWUoSmF2YVR5cGUgdHlwZSk7CisKKy8vIEdldCB0aGUgZnVsbHktcXVhbGlmaWVkIGNsYXNzIG5hbWUgZm9yIGEgYm94ZWQgcHJpbWl0aXZlIHR5cGUsIGUuZy4KKy8vICJqYXZhLmxhbmcuSW50ZWdlciIgZm9yIEpBVkFUWVBFX0lOVC4gIFJldHVybnMgTlVMTCBmb3IgZW51bSBhbmQgbWVzc2FnZQorLy8gdHlwZXMuCitjb25zdCBjaGFyKiBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEphdmFUeXBlIHR5cGUpOworCisvLyBHZXQgdGhlIG5hbWUgb2YgdGhlIGphdmEgZW51bSBjb25zdGFudCByZXByZXNlbnRpbmcgdGhpcyB0eXBlLiBFLmcuLAorLy8gIklOVDMyIiBmb3IgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyLiBUaGUgZW51bSBjb25zdGFudCdzIGZ1bGwKKy8vIG5hbWUgaXMgImNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIiLgorY29uc3QgY2hhciogRmllbGRUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3I6OlR5cGUgZmllbGRfdHlwZSk7CisKK2NsYXNzIENsYXNzTmFtZVJlc29sdmVyOworc3RyaW5nIERlZmF1bHRWYWx1ZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBib29sIGltbXV0YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIpOworaW5saW5lIHN0cmluZyBJbW11dGFibGVEZWZhdWx0VmFsdWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyKSB7CisgIHJldHVybiBEZWZhdWx0VmFsdWUoZmllbGQsIHRydWUsIG5hbWVfcmVzb2x2ZXIpOworfQorYm9vbCBJc0RlZmF1bHRWYWx1ZUphdmFEZWZhdWx0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBEb2VzIHRoaXMgbWVzc2FnZSBjbGFzcyBoYXZlIGdlbmVyYXRlZCBwYXJzaW5nLCBzZXJpYWxpemF0aW9uLCBhbmQgb3RoZXIKKy8vIHN0YW5kYXJkIG1ldGhvZHMgZm9yIHdoaWNoIHJlZmxlY3Rpb24tYmFzZWQgZmFsbGJhY2sgaW1wbGVtZW50YXRpb25zIGV4aXN0PworaW5saW5lIGJvb2wgSGFzR2VuZXJhdGVkTWV0aG9kcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPQorICAgICAgICAgICBGaWxlT3B0aW9uczo6Q09ERV9TSVpFOworfQorCisvLyBEb2VzIHRoaXMgbWVzc2FnZSBoYXZlIHNwZWNpYWxpemVkIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpIG1ldGhvZHM/CitpbmxpbmUgYm9vbCBIYXNFcXVhbHNBbmRIYXNoQ29kZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworfQorCisvLyBEb2VzIHRoaXMgbWVzc2FnZSBjbGFzcyBoYXZlIGRlc2NyaXB0b3IgYW5kIHJlZmxlY3Rpb24gbWV0aG9kcz8KK2lubGluZSBib29sIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPmZpbGUoKS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpICE9CisgICAgICAgICAgIEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUU7Cit9CitpbmxpbmUgYm9vbCBIYXNEZXNjcmlwdG9yTWV0aG9kcyhjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0KKyAgICAgICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK30KK2lubGluZSBib29sIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0KKyAgICAgICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK30KKworaW5saW5lIGJvb2wgSGFzTmVzdGVkQnVpbGRlcnMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAvLyBUaGUgcHJvdG8tbGl0ZSB2ZXJzaW9uIGRvZXNuJ3Qgc3VwcG9ydCBuZXN0ZWQgYnVpbGRlcnMuCisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPQorICAgICAgICAgICBGaWxlT3B0aW9uczo6TElURV9SVU5USU1FOworfQorCisvLyBTaG91bGQgd2UgZ2VuZXJhdGUgZ2VuZXJpYyBzZXJ2aWNlcyBmb3IgdGhpcyBmaWxlPworaW5saW5lIGJvb2wgSGFzR2VuZXJpY1NlcnZpY2VzKGNvbnN0IEZpbGVEZXNjcmlwdG9yICpmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zZXJ2aWNlX2NvdW50KCkgPiAwICYmCisgICAgICAgICBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0gRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSAmJgorICAgICAgICAgZmlsZS0+b3B0aW9ucygpLmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpOworfQorCitpbmxpbmUgYm9vbCBJc0xhenkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIC8vIEN1cnJlbnRseSwgdGhlIHByb3RvLWxpdGUgdmVyc2lvbiBzdXBvcnRzIGxhenkgZmllbGQuCisgIC8vIFRPRE8obml3YXNha2kpOiBTdXBwb3J0IGxhenkgZmllbGRzIGFsc28gZm9yIG90aGVyIHByb3RvIHJ1bnRpbWVzLgorICBpZiAoZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0KKyAgICAgIEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUUpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5sYXp5KCk7Cit9CisKKy8vIE1ldGhvZHMgZm9yIHNoYXJlZCBiaXRmaWVsZHMuCisKKy8vIEdldHMgdGhlIG5hbWUgb2YgdGhlIHNoYXJlZCBiaXRmaWVsZCBmb3IgdGhlIGdpdmVuIGluZGV4Lgorc3RyaW5nIEdldEJpdEZpZWxkTmFtZShpbnQgaW5kZXgpOworCisvLyBHZXRzIHRoZSBuYW1lIG9mIHRoZSBzaGFyZWQgYml0ZmllbGQgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFZmZlY3RpdmVseSwgR2V0Qml0RmllbGROYW1lKGJpdEluZGV4IC8gMzIpCitzdHJpbmcgR2V0Qml0RmllbGROYW1lRm9yQml0KGludCBiaXRJbmRleCk7CisKKy8vIEdlbmVyYXRlcyB0aGUgamF2YSBjb2RlIGZvciB0aGUgZXhwcmVzc2lvbiB0aGF0IHJldHVybnMgdGhlIGJvb2xlYW4gdmFsdWUKKy8vIG9mIHRoZSBiaXQgb2YgdGhlIHNoYXJlZCBiaXRmaWVsZHMgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFeGFtcGxlOiAiKChiaXRGaWVsZDFfICYgMHgwNCkgPT0gMHgwNCkiCitzdHJpbmcgR2VuZXJhdGVHZXRCaXQoaW50IGJpdEluZGV4KTsKKworLy8gR2VuZXJhdGVzIHRoZSBqYXZhIGNvZGUgZm9yIHRoZSBleHByZXNzaW9uIHRoYXQgc2V0cyB0aGUgYml0IG9mIHRoZSBzaGFyZWQKKy8vIGJpdGZpZWxkcyBmb3IgdGhlIGdpdmVuIGJpdCBpbmRleC4KKy8vIEV4YW1wbGU6ICJiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gfCAweDA0KSIKK3N0cmluZyBHZW5lcmF0ZVNldEJpdChpbnQgYml0SW5kZXgpOworCisvLyBHZW5lcmF0ZXMgdGhlIGphdmEgY29kZSBmb3IgdGhlIGV4cHJlc3Npb24gdGhhdCBjbGVhcnMgdGhlIGJpdCBvZiB0aGUgc2hhcmVkCisvLyBiaXRmaWVsZHMgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFeGFtcGxlOiAiYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQpIgorc3RyaW5nIEdlbmVyYXRlQ2xlYXJCaXQoaW50IGJpdEluZGV4KTsKKworLy8gRG9lcyB0aGUgc2FtZSBhcyBHZW5lcmF0ZUdldEJpdCBidXQgb3BlcmF0ZXMgb24gdGhlIGJpdCBmaWVsZCBvbiBhIGxvY2FsCisvLyB2YXJpYWJsZS4gVGhpcyBpcyB1c2VkIGJ5IHRoZSBidWlsZGVyIHRvIGNvcHkgdGhlIHZhbHVlIGluIHRoZSBidWlsZGVyIHRvCisvLyB0aGUgbWVzc2FnZS4KKy8vIEV4YW1wbGU6ICIoKGZyb21fYml0RmllbGQxXyAmIDB4MDQpID09IDB4MDQpIgorc3RyaW5nIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGludCBiaXRJbmRleCk7CisKKy8vIERvZXMgdGhlIHNhbWUgYXMgR2VuZXJhdGVTZXRCaXQgYnV0IG9wZXJhdGVzIG9uIHRoZSBiaXQgZmllbGQgb24gYSBsb2NhbAorLy8gdmFyaWFibGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgYnVpbGRlciB0byBjb3B5IHRoZSB2YWx1ZSBpbiB0aGUgYnVpbGRlciB0bworLy8gdGhlIG1lc3NhZ2UuCisvLyBFeGFtcGxlOiAidG9fYml0RmllbGQxXyA9ICh0b19iaXRGaWVsZDFfIHwgMHgwNCkiCitzdHJpbmcgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKGludCBiaXRJbmRleCk7CisKKy8vIERvZXMgdGhlIHNhbWUgYXMgR2VuZXJhdGVHZXRCaXQgYnV0IG9wZXJhdGVzIG9uIHRoZSBiaXQgZmllbGQgb24gYSBsb2NhbAorLy8gdmFyaWFibGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgcGFyc2luZyBjb25zdHJ1Y3RvciB0byByZWNvcmQgaWYgYSByZXBlYXRlZAorLy8gZmllbGQgaXMgbXV0YWJsZS4KKy8vIEV4YW1wbGU6ICIoKG11dGFibGVfYml0RmllbGQxXyAmIDB4MDQpID09IDB4MDQpIgorc3RyaW5nIEdlbmVyYXRlR2V0Qml0TXV0YWJsZUxvY2FsKGludCBiaXRJbmRleCk7CisKKy8vIERvZXMgdGhlIHNhbWUgYXMgR2VuZXJhdGVTZXRCaXQgYnV0IG9wZXJhdGVzIG9uIHRoZSBiaXQgZmllbGQgb24gYSBsb2NhbAorLy8gdmFyaWFibGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgcGFyc2luZyBjb25zdHJ1Y3RvciB0byByZWNvcmQgaWYgYSByZXBlYXRlZAorLy8gZmllbGQgaXMgbXV0YWJsZS4KKy8vIEV4YW1wbGU6ICJtdXRhYmxlX2JpdEZpZWxkMV8gPSAobXV0YWJsZV9iaXRGaWVsZDFfIHwgMHgwNCkiCitzdHJpbmcgR2VuZXJhdGVTZXRCaXRNdXRhYmxlTG9jYWwoaW50IGJpdEluZGV4KTsKKworLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBKYXZhVHlwZSBpcyBhIHJlZmVyZW5jZSB0eXBlLgorYm9vbCBJc1JlZmVyZW5jZVR5cGUoSmF2YVR5cGUgdHlwZSk7CisKKy8vIFJldHVybnMgdGhlIGNhcGl0YWxpemVkIG5hbWUgZm9yIGNhbGxpbmcgcmVsYXRpdmUgZnVuY3Rpb25zIGluCisvLyBDb2RlZElucHV0U3RyZWFtCitjb25zdCBjaGFyKiBHZXRDYXBpdGFsaXplZFR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCBpbW11dGFibGUpOworCisvLyBGb3IgZW5jb2RpbmdzIHdpdGggZml4ZWQgc2l6ZXMsIHJldHVybnMgdGhhdCBzaXplIGluIGJ5dGVzLiAgT3RoZXJ3aXNlCisvLyByZXR1cm5zIC0xLgoraW50IEZpeGVkU2l6ZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSk7CisKKy8vIENvbXBhcmF0b3JzIHVzZWQgdG8gc29ydCBmaWVsZHMgaW4gTWVzc2FnZUdlbmVyYXRvcgorc3RydWN0IEZpZWxkT3JkZXJpbmdCeU51bWJlciB7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBhLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYikgY29uc3QgeworICAgIHJldHVybiBhLT5udW1iZXIoKSA8IGItPm51bWJlcigpOworICB9Cit9OworCitzdHJ1Y3QgRXh0ZW5zaW9uUmFuZ2VPcmRlcmluZyB7CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogYSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEtPnN0YXJ0IDwgYi0+c3RhcnQ7CisgIH0KK307CisKKy8vIFNvcnQgdGhlIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gRGVzY3JpcHRvciBieSBudW1iZXIgaW50byBhIG5ld1tdJ2QgYXJyYXkKKy8vIGFuZCByZXR1cm4gaXQuIFRoZSBjYWxsZXIgc2hvdWxkIGRlbGV0ZSB0aGUgcmV0dXJuZWQgYXJyYXkuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBTb3J0RmllbGRzQnlOdW1iZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIERvZXMgdGhpcyBtZXNzYWdlIGNsYXNzIGhhdmUgYW55IHBhY2tlZCBmaWVsZHM/CitpbmxpbmUgYm9vbCBIYXNQYWNrZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yLT5maWVsZChpKS0+aXNfcGFja2VkKCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIENoZWNrIGEgbWVzc2FnZSB0eXBlIGFuZCBpdHMgc3ViLW1lc3NhZ2UgdHlwZXMgcmVjdXJzaXZlbHkgdG8gc2VlIGlmIGFueSBvZgorLy8gdGhlbSBoYXMgYSByZXF1aXJlZCBmaWVsZC4gUmV0dXJuIHRydWUgaWYgYSByZXF1aXJlZCBmaWVsZCBpcyBmb3VuZC4KK2Jvb2wgSGFzUmVxdWlyZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIFdoZXRoZXIgYSAucHJvdG8gZmlsZSBzdXBwb3J0cyBmaWVsZCBwcmVzZW5jZSB0ZXN0IGZvciBub24tbWVzc2FnZSB0eXBlcy4KK2lubGluZSBib29sIFN1cHBvcnRGaWVsZFByZXNlbmNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworLy8gV2hldGhlciB1bmtub3duIGVudW0gdmFsdWVzIGFyZSBrZXB0IChpLmUuLCBub3Qgc3RvcmVkIGluIFVua25vd25GaWVsZFNldAorLy8gYnV0IGluIHRoZSBtZXNzYWdlIGFuZCBjYW4gYmUgcXVlcmllZCB1c2luZyBhZGRpdGlvbmFsIGdldHRlcnMgdGhhdCByZXR1cm4KKy8vIGludHMuCitpbmxpbmUgYm9vbCBTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+c3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM7Cit9CisKKy8vIENoZWNrIHdoZXRoZXIgYSBtZXNhc2dlIGhhcyByZXBlYXRlZCBmaWVsZHMuCitib29sIEhhc1JlcGVhdGVkRmllbGRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCitpbmxpbmUgYm9vbCBJc01hcEVudHJ5KGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tYXBfZW50cnkoKTsKK30KKworaW5saW5lIGJvb2wgUHJlc2VydmVVbmtub3duRmllbGRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPmZpbGUoKS0+c3ludGF4KCkgIT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0hFTFBFUlNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmUyOWE0MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5jYwpAQCAtMCwwICsxLDgyNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbml3YXNha2lAZ29vZ2xlLmNvbSAoTmFva2kgSXdhc2FraSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworfQorCitJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+SW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUgJG5hbWUkXyA9XG4iCisgICAgIiAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlKCk7XG4iKTsKKworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICgkdHlwZSQpICRuYW1lJF8uZ2V0VmFsdWUoJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICJ9XG4iKTsKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBXaGVuIHVzaW5nIG5lc3RlZC1idWlsZGVycywgdGhlIGNvZGUgaW5pdGlhbGx5IHdvcmtzIGp1c3QgbGlrZSB0aGUKKyAgLy8gbm9uLW5lc3RlZCBidWlsZGVyIGNhc2UuIEl0IG9ubHkgY3JlYXRlcyBhIG5lc3RlZCBidWlsZGVyIGxhemlseSBvbgorICAvLyBkZW1hbmQgYW5kIHRoZW4gZm9yZXZlciBkZWxlZ2F0ZXMgdG8gaXQgYWZ0ZXIgY3JlYXRpb24uCisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUgJG5hbWUkXyA9XG4iCisgICAgIiAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlKCk7XG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAvLyBJZiB0aGlzIGJ1aWxkZXIgaXMgbm9uLW51bGwsIGl0IGlzIHVzZWQgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlCisgICAgICAvLyBpZ25vcmVkLgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gJG5hbWUkQnVpbGRlcl87IgorICAgICAgIlxuIik7CisgIH0KKworICAvLyBUaGUgY29tbWVudHMgYWJvdmUgdGhlIG1ldGhvZHMgYmVsb3cgYXJlIGJhc2VkIG9uIGEgaHlwb3RoZXRpY2FsCisgIC8vIGZpZWxkIG9mIHR5cGUgIkZpZWxkIiBjYWxsZWQgIkZpZWxkIi4KKworICAvLyBib29sZWFuIGhhc0ZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQ7XG4iCisgICAgIn1cbiIpOworCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gKCR0eXBlJCkgJG5hbWUkXy5nZXRWYWx1ZSgkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpO1xuIgorICAgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgIiRuYW1lJF8uc2V0VmFsdWUodmFsdWUpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAgTlVMTCwgIC8vIExhenkgZmllbGRzIGFyZSBzdXBwb3J0ZWQgb25seSBmb3IgbGl0ZS1ydW50aW1lLgorCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICIkbmFtZSRfLnNldFZhbHVlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgTlVMTCwKKworICAgICIkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQ7XG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBtZXJnZUZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAoJGdldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkICYmXG4iCisgICAgIiAgICAhJG5hbWUkXy5jb250YWluc0RlZmF1bHRJbnN0YW5jZSgpKSB7XG4iCisgICAgIiAgJG5hbWUkXy5zZXRWYWx1ZShcbiIKKyAgICAiICAgICR0eXBlJC5uZXdCdWlsZGVyKFxuIgorICAgICIgICAgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKS5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpKTtcbiIKKyAgICAifSBlbHNlIHtcbiIKKyAgICAiICAkbmFtZSRfLnNldFZhbHVlKHZhbHVlKTtcbiIKKyAgICAifVxuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICBOVUxMLAorCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIGNsZWFyRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICIkbmFtZSRfLmNsZWFyKCk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgIE5VTEwsCisKKyAgICAiJGNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciQ7XG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJC5CdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXIoKSB7XG4iCisgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQ7XG4iCisgICAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfICE9IG51bGwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgICAiICAgICRuYW1lJEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyPFxuIgorICAgICAgIiAgICAgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPihcbiIKKyAgICAgICIgICAgICAgICAgICAkbmFtZSRfLFxuIgorICAgICAgIiAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksXG4iCisgICAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IG51bGw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKworCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uY2xlYXIoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLmNsZWFyKCk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmIChvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSkge1xuIgorICAgICIgICRuYW1lJF8ubWVyZ2Uob3RoZXIuJG5hbWUkXyk7XG4iCisgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdC4kbmFtZSRfLnNldChcbiIKKyAgICAgICIgICAgJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXy5zZXRCeXRlU3RyaW5nKGlucHV0LnJlYWRCeXRlcygpLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIERvIG5vdCBkZS1zZXJpYWxpemUgbGF6eSBmaWVsZHMuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVCeXRlcygkbnVtYmVyJCwgJG5hbWUkXy50b0J5dGVTdHJpbmcoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGVMYXp5RmllbGRTaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9CisgICAgICBjb250ZXh0LT5HZXRPbmVvZkdlbmVyYXRvckluZm8oZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgJnZhcmlhYmxlc18pOworICB2YXJpYWJsZXNfWyJsYXp5X3R5cGUiXSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUiOworfQorCitJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorfkltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICByZXR1cm4gKCR0eXBlJCkgKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykuZ2V0VmFsdWUoXG4iCisgICAgIiAgICAgICAgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gYm9vbGVhbiBoYXNGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICJ9XG4iKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmV0dXJuICgkdHlwZSQpICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLmdldFZhbHVlKFxuIgorICAgICIgICAgICAgICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgImlmICghKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICJ9XG4iCisgICAgIigoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnNldFZhbHVlKHZhbHVlKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIE5VTEwsICAvLyBMYXp5IGZpZWxkcyBhcmUgc3VwcG9ydGVkIG9ubHkgZm9yIGxpdGUtcnVudGltZS4KKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkiLAorCisgICAgImlmICghKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICJ9XG4iCisgICAgIigoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnNldFZhbHVlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgTlVMTCwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSIsCisKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCAmJlxuIgorICAgICIgICAgISgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLmNvbnRhaW5zRGVmYXVsdEluc3RhbmNlKCkpIHtcbiIKKyAgICAiICAoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5zZXRWYWx1ZShcbiIKKyAgICAiICAgICR0eXBlJC5uZXdCdWlsZGVyKFxuIgorICAgICIgICAgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKS5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpKTtcbiIKKyAgICAifSBlbHNlIHtcbiIKKyAgICAiICBpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgIiAgICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgfVxuIgorICAgICIgICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnNldFZhbHVlKHZhbHVlKTtcbiIKKyAgICAifVxuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICBOVUxMLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBjbGVhckZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSIsCisKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICRjbGVhcl9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICJ9XG4iLAorCisgICAgTlVMTCwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgIn1cbiIKKyAgICAiKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykubWVyZ2UoXG4iCisgICAgIiAgICAoJGxhenlfdHlwZSQpIG90aGVyLiRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAgICAgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdC4kb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgICAiKCgkbGF6eV90eXBlJCkgcmVzdWx0LiRvbmVvZl9uYW1lJF8pLnNldChcbiIKKyAgICAgICIgICAgKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykpO1xuIik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgIn1cbiIKKyAgICAiKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykuc2V0Qnl0ZVN0cmluZyhcbiIKKyAgICAiICAgIGlucHV0LnJlYWRCeXRlcygpLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIERvIG5vdCBkZS1zZXJpYWxpemUgbGF6eSBmaWVsZHMuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVCeXRlcyhcbiIKKyAgICAiICAgICAgJG51bWJlciQsICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnRvQnl0ZVN0cmluZygpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlTGF6eUZpZWxkU2l6ZSgkbnVtYmVyJCwgKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworfQorCisKK1JlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6Cit+UmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlPiAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+XG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkge1xuIgorICAgICIgIGphdmEudXRpbC5MaXN0PCR0eXBlJD4gbGlzdCA9XG4iCisgICAgIiAgICAgIG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PCR0eXBlJD4oJG5hbWUkXy5zaXplKCkpO1xuIgorICAgICIgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlIGxmIDogJG5hbWUkXykge1xuIgorICAgICIgICAgbGlzdC5hZGQoKCR0eXBlJCkgbGYuZ2V0VmFsdWUoJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiBsaXN0O1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyAkdHlwZSRPckJ1aWxkZXI+XG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXJMaXN0KCkge1xuIgorICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAoJHR5cGUkKVxuIgorICAgICIgICAgICAkbmFtZSRfLmdldChpbmRleCkuZ2V0VmFsdWUoJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKFxuIgorICAgICIgICAgaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICgkdHlwZSRPckJ1aWxkZXIpXG4iCisgICAgIiAgICAgICRuYW1lJF8uZ2V0KGluZGV4KS5nZXRWYWx1ZSgkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBXaGVuIHVzaW5nIG5lc3RlZC1idWlsZGVycywgdGhlIGNvZGUgaW5pdGlhbGx5IHdvcmtzIGp1c3QgbGlrZSB0aGUKKyAgLy8gbm9uLW5lc3RlZCBidWlsZGVyIGNhc2UuIEl0IG9ubHkgY3JlYXRlcyBhIG5lc3RlZCBidWlsZGVyIGxhemlseSBvbgorICAvLyBkZW1hbmQgYW5kIHRoZW4gZm9yZXZlciBkZWxlZ2F0ZXMgdG8gaXQgYWZ0ZXIgY3JlYXRpb24uCisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGU+ICRuYW1lJF8gPVxuIgorICAgICIgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIKKworICAgICJwcml2YXRlIHZvaWQgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCkge1xuIgorICAgICIgIGlmICghJGdldF9tdXRhYmxlX2JpdF9idWlsZGVyJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9XG4iCisgICAgIiAgICAgICAgbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlPihcbiIKKyAgICAiICAgICAgICAgICAgJG5hbWUkXyk7XG4iCisgICAgIiAgICAkc2V0X211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAvLyBJZiB0aGlzIGJ1aWxkZXIgaXMgbm9uLW51bGwsIGl0IGlzIHVzZWQgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlCisgICAgICAvLyBpZ25vcmVkLgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlcjxcbiIKKyAgICAgICIgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPiAkbmFtZSRCdWlsZGVyXztcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgLy8gVGhlIGNvbW1lbnRzIGFib3ZlIHRoZSBtZXRob2RzIGJlbG93IGFyZSBiYXNlZCBvbiBhIGh5cG90aGV0aWNhbAorICAvLyByZXBlYXRlZCBmaWVsZCBvZiB0eXBlICJGaWVsZCIgY2FsbGVkICJSZXBlYXRlZEZpZWxkIi4KKworICAvLyBMaXN0PEZpZWxkPiBnZXRSZXBlYXRlZEZpZWxkTGlzdCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSIsCisKKyAgICAiamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBsaXN0ID1cbiIKKyAgICAiICAgIG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PCR0eXBlJD4oJG5hbWUkXy5zaXplKCkpO1xuIgorICAgICJmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZSBsZiA6ICRuYW1lJF8pIHtcbiIKKyAgICAiICBsaXN0LmFkZCgoJHR5cGUkKSBsZi5nZXRWYWx1ZSgkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTtcbiIKKyAgICAifVxuIgorICAgICJyZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGlzdCk7XG4iLAorCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkiLAorCisgICAgInJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIsCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRDb3VudCgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIEZpZWxkIGdldFJlcGVhdGVkRmllbGQoaW50IGluZGV4KQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIiwKKworICAgICJyZXR1cm4gKCR0eXBlJCkgJG5hbWUkXy5nZXQoaW5kZXgpLmdldFZhbHVlKFxuIgorICAgICIgICAgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIsCisKKyAgICAicmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkiLAorICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLnNldChpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlLmZyb21WYWx1ZSh2YWx1ZSkpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTtcbiIsCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSIsCisKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uc2V0KGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKFxuIgorICAgICIgICAgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKHZhbHVlKSk7XG4iCisKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uYWRkKGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKHZhbHVlKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlLmZyb21WYWx1ZShcbiIKKyAgICAiICAgIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5hZGQoaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUoXG4iCisgICAgIiAgICBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSkpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaWVsZChJdGVyYWJsZTxGaWVsZD4gdmFsdWVzKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzICR0eXBlJD4gdmFsdWVzKSIsCisKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgImZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZSB2IDogdmFsdWVzKSB7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlLmZyb21WYWx1ZSh2KSk7XG4iCisgICAgIn1cbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBjbGVhckFsbFJlcGVhdGVkRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICIkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpO1xuIgorICAgICIkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHJlbW92ZSRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5yZW1vdmUoaW5kZXgpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcihcbiIKKyAgICAgICIgICAgaW50IGluZGV4KSB7XG4iCisgICAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7XG4iCisgICAgICAifVxuIik7CisKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKFxuIgorICAgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgICAiICAgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7IgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworCisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgICAiICAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXJMaXN0KCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfICE9IG51bGwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKCkge1xuIgorICAgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoXG4iCisgICAgICAiICAgICAgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKFxuIgorICAgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKFxuIgorICAgICAgIiAgICAgIGluZGV4LCAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCR0eXBlJC5CdWlsZGVyPiBcbiIKKyAgICAgICIgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXJMaXN0KCkge1xuIgorICAgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7XG4iCisgICAgICAifVxuIgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlcjxcbiIKKyAgICAgICIgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPiBcbiIKKyAgICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlcjxcbiIKKyAgICAgICIgICAgICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4oXG4iCisgICAgICAiICAgICAgICAgICAgJG5hbWUkXyxcbiIKKyAgICAgICIgICAgICAgICAgICAkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkLFxuIgorICAgICAgIiAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksXG4iCisgICAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IG51bGw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoISRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPVxuIgorICAgICIgICAgICBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGU+KCk7XG4iCisgICAgIiAgJHNldF9tdXRhYmxlX2JpdF9wYXJzZXIkO1xuIgorICAgICJ9XG4iCisgICAgIiRuYW1lJF8uYWRkKG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUoXG4iCisgICAgIiAgICBleHRlbnNpb25SZWdpc3RyeSwgaW5wdXQucmVhZEJ5dGVzKCkpKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIG91dHB1dC53cml0ZUJ5dGVzKCRudW1iZXIkLCAkbmFtZSRfLmdldChpKS50b0J5dGVTdHJpbmcoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlTGF6eUZpZWxkU2l6ZSgkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxYjdmMjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDEyMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbml3YXNha2lAZ29vZ2xlLmNvbSAoTmFva2kgSXdhc2FraSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0xBWllfTUVTU0FHRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTEFaWV9NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBjb21waWxlciB7CisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ29udGV4dDsgIC8vIGNvbnRleHQuaAorICAgIH0KKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gb3ZlcnJvYWRzIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IKKyAgICA6IHB1YmxpYyBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+UmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gb3ZlcnJvYWRzIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTEFaWV9NRVNTQUdFX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmMWVmNTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGQuY2MKQEAgLTAsMCArMSw0ODQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGQuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIEtleUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBHT09HTEVfQ0hFQ0tfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIGRlc2NyaXB0b3ItPnR5cGUoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPSBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKTsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2UtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSk7CisgIHJldHVybiBtZXNzYWdlLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIFZhbHVlRmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEdPT0dMRV9DSEVDS19FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpOworICBHT09HTEVfQ0hFQ0sobWVzc2FnZS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKTsKKyAgcmV0dXJuIG1lc3NhZ2UtPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKK30KKworc3RyaW5nIFR5cGVOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgYm9vbCBib3hlZCkgeworICBpZiAoR2V0SmF2YVR5cGUoZmllbGQpID09IEpBVkFUWVBFX01FU1NBR0UpIHsKKyAgICByZXR1cm4gbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgIH0gZWxzZSBpZiAoR2V0SmF2YVR5cGUoZmllbGQpID09IEpBVkFUWVBFX0VOVU0pIHsKKyAgICByZXR1cm4gbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGZpZWxkLT5lbnVtX3R5cGUoKSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGJveGVkID8gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShmaWVsZCkpCisgICAgICAgICAgICAgICAgIDogUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZmllbGQpKTsKKyAgfQorfQorCitzdHJpbmcgV2lyZVR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuIiArCisgICAgICBzdHJpbmcoRmllbGRUeXBlTmFtZShmaWVsZC0+dHlwZSgpKSk7Cit9CisKK3ZvaWQgU2V0TWVzc2FnZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgdmFyaWFibGVzKTsKKworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9CisgICAgICBuYW1lX3Jlc29sdmVyLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCkpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleSA9IEtleUZpZWxkKGRlc2NyaXB0b3IpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlID0gVmFsdWVGaWVsZChkZXNjcmlwdG9yKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfdHlwZSJdID0gVHlwZU5hbWUoa2V5LCBuYW1lX3Jlc29sdmVyLCBmYWxzZSk7CisgICgqdmFyaWFibGVzKVsiYm94ZWRfa2V5X3R5cGUiXSA9IFR5cGVOYW1lKGtleSwgbmFtZV9yZXNvbHZlciwgdHJ1ZSk7CisgICgqdmFyaWFibGVzKVsia2V5X3dpcmVfdHlwZSJdID0gV2lyZVR5cGUoa2V5KTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfZGVmYXVsdF92YWx1ZSJdID0gRGVmYXVsdFZhbHVlKGtleSwgdHJ1ZSwgbmFtZV9yZXNvbHZlcik7CisgIGlmIChHZXRKYXZhVHlwZSh2YWx1ZSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIC8vIFdlIHN0b3JlIGVudW1zIGFzIEludGVnZXJzIGludGVybmFsbHkuCisgICAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV90eXBlIl0gPSAiaW50IjsKKyAgICAoKnZhcmlhYmxlcylbImJveGVkX3ZhbHVlX3R5cGUiXSA9ICJqYXZhLmxhbmcuSW50ZWdlciI7CisgICAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV93aXJlX3R5cGUiXSA9IFdpcmVUeXBlKHZhbHVlKTsKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX2RlZmF1bHRfdmFsdWUiXSA9CisgICAgICAgIERlZmF1bHRWYWx1ZSh2YWx1ZSwgdHJ1ZSwgbmFtZV9yZXNvbHZlcikgKyAiLmdldE51bWJlcigpIjsKKworICAgICgqdmFyaWFibGVzKVsidmFsdWVfZW51bV90eXBlIl0gPSBUeXBlTmFtZSh2YWx1ZSwgbmFtZV9yZXNvbHZlciwgZmFsc2UpOworCisgICAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3ItPmZpbGUoKSkpIHsKKyAgICAgIC8vIE1hcCB1bmtub3duIHZhbHVlcyB0byBhIHNwZWNpYWwgVU5SRUNPR05JWkVEIHZhbHVlIGlmIHN1cHBvcnRlZC4KKyAgICAgICgqdmFyaWFibGVzKVsidW5yZWNvZ25pemVkX3ZhbHVlIl0gPQorICAgICAgICAgICgqdmFyaWFibGVzKVsidmFsdWVfZW51bV90eXBlIl0gKyAiLlVOUkVDT0dOSVpFRCI7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE1hcCB1bmtub3duIHZhbHVlcyB0byB0aGUgZGVmYXVsdCB2YWx1ZSBpZiB3ZSBkb24ndCBoYXZlIFVOUkVDT0dOSVpFRC4KKyAgICAgICgqdmFyaWFibGVzKVsidW5yZWNvZ25pemVkX3ZhbHVlIl0gPQorICAgICAgICAgIERlZmF1bHRWYWx1ZSh2YWx1ZSwgdHJ1ZSwgbmFtZV9yZXNvbHZlcik7CisgICAgfQorICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsidmFsdWVfdHlwZSJdID0gVHlwZU5hbWUodmFsdWUsIG5hbWVfcmVzb2x2ZXIsIGZhbHNlKTsKKyAgICAoKnZhcmlhYmxlcylbImJveGVkX3ZhbHVlX3R5cGUiXSA9IFR5cGVOYW1lKHZhbHVlLCBuYW1lX3Jlc29sdmVyLCB0cnVlKTsKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX3dpcmVfdHlwZSJdID0gV2lyZVR5cGUodmFsdWUpOworICAgICgqdmFyaWFibGVzKVsidmFsdWVfZGVmYXVsdF92YWx1ZSJdID0KKyAgICAgICAgRGVmYXVsdFZhbHVlKHZhbHVlLCB0cnVlLCBuYW1lX3Jlc29sdmVyKTsKKyAgfQorICAoKnZhcmlhYmxlcylbInR5cGVfcGFyYW1ldGVycyJdID0KKyAgICAgICgqdmFyaWFibGVzKVsiYm94ZWRfa2V5X3R5cGUiXSArICIsICIgKyAoKnZhcmlhYmxlcylbImJveGVkX3ZhbHVlX3R5cGUiXTsKKyAgLy8gVE9ETyhiaXJkbyk6IEFkZCBAZGVwcmVjYXRlZCBqYXZhZG9jIHdoZW4gZ2VuZXJhdGluZyBqYXZhZG9jIGlzIHN1cHBvcnRlZAorICAvLyBieSB0aGUgcHJvdG8gY29tcGlsZXIKKyAgKCp2YXJpYWJsZXMpWyJkZXByZWNhdGlvbiJdID0gZGVzY3JpcHRvci0+b3B0aW9ucygpLmRlcHJlY2F0ZWQoKQorICAgICAgPyAiQGphdmEubGFuZy5EZXByZWNhdGVkICIgOiAiIjsKKyAgKCp2YXJpYWJsZXMpWyJvbl9jaGFuZ2VkIl0gPQorICAgICAgSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpID8gIm9uQ2hhbmdlZCgpOyIgOiAiIjsKKworICAvLyBGb3IgcmVwZWF0ZWQgZmllbGRzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHdoZXRoZXIgdGhlIGFycmF5IGlzIGltbXV0YWJsZQorICAvLyBpbiB0aGUgcGFyc2luZyBjb25zdHJ1Y3Rvci4KKyAgKCp2YXJpYWJsZXMpWyJnZXRfbXV0YWJsZV9iaXRfcGFyc2VyIl0gPQorICAgICAgR2VuZXJhdGVHZXRCaXRNdXRhYmxlTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfbXV0YWJsZV9iaXRfcGFyc2VyIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRNdXRhYmxlTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvci0+ZmlsZSgpKSkgeworICAgICgqdmFyaWFibGVzKVsibGl0ZSJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJtYXBfZmllbGRfcGFyYW1ldGVyIl0gPSAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJEZWZhdWx0RW50cnkiOworICAgICgqdmFyaWFibGVzKVsiZGVzY3JpcHRvciJdID0KKyAgICAgICAgbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPmZpbGUoKSkgKworICAgICAgICAiLmludGVybmFsXyIgKyBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKSArCisgICAgICAgICJfZGVzY3JpcHRvciwgIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbImxpdGUiXSA9ICJMaXRlIjsKKyAgICAoKnZhcmlhYmxlcylbIm1hcF9maWVsZF9wYXJhbWV0ZXIiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsiZGVzY3JpcHRvciJdID0gIiI7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0ltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpICB7CisgIFNldE1lc3NhZ2VWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKEdldEphdmFUeXBlKFZhbHVlRmllbGQoZGVzY3JpcHRvcl8pKSA9PSBKQVZBVFlQRV9FTlVNKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTdGF0aWNJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJERlZmF1bHRFbnRyeSA9XG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSRcbiIKKyAgICAgICIgICAgLjwkdHlwZV9wYXJhbWV0ZXJzJD5uZXdEZWZhdWx0SW5zdGFuY2UoXG4iCisgICAgICAiICAgICAgICAkZGVzY3JpcHRvciRcbiIKKyAgICAgICIgICAgICAgICRrZXlfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgICAgICRrZXlfZGVmYXVsdF92YWx1ZSQsXG4iCisgICAgICAiICAgICAgICAkdmFsdWVfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgICAgICR2YWx1ZV9kZWZhdWx0X3ZhbHVlJCk7XG4iCisgICAgICAiXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSQ8XG4iCisgICAgICAiICAgICR0eXBlX3BhcmFtZXRlcnMkPiAkbmFtZSREZWZhdWx0RW50cnk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJDxcbiIKKyAgICAgICIgICAgJHR5cGVfcGFyYW1ldGVycyQ+ICRuYW1lJF87XG4iCisgICAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkJGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgImludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJF8gPT0gbnVsbCkge1xuIgorICAgICAgIiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJC5lbXB0eU1hcEZpZWxkKFxuIgorICAgICAgIiAgICAgICAgJG1hcF9maWVsZF9wYXJhbWV0ZXIkKTtcbiIKKyAgICAgICIgfVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgICAifVxuIik7CisgIGlmIChHZXRKYXZhVHlwZShWYWx1ZUZpZWxkKGRlc2NyaXB0b3JfKSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAicHJpdmF0ZSBzdGF0aWMgZmluYWxcbiIKKyAgICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8XG4iCisgICAgICAgICIgICAgamF2YS5sYW5nLkludGVnZXIsICR2YWx1ZV9lbnVtX3R5cGUkPiAkbmFtZSRWYWx1ZUNvbnZlcnRlciA9XG4iCisgICAgICAgICIgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKFxuIgorICAgICAgICAiICAgICAgICAgICAgJHZhbHVlX2VudW1fdHlwZSQuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLFxuIgorICAgICAgICAiICAgICAgICAgICAgJHVucmVjb2duaXplZF92YWx1ZSQpO1xuIik7CisgICAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICRib3hlZF92YWx1ZV90eXBlJD5cbiIKKyAgICAgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TWFwKCk7XG4iCisgICAgICAgICAgIn1cbiIpOworICAgIH0KKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkdmFsdWVfZW51bV90eXBlJD5cbiIKKyAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8XG4iCisgICAgICAgICIgICAgICAkYm94ZWRfa2V5X3R5cGUkLCAkdmFsdWVfZW51bV90eXBlJCwgamF2YS5sYW5nLkludGVnZXI+KFxuIgorICAgICAgICAiICAgICAgICAgIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TWFwKCksXG4iCisgICAgICAgICIgICAgICAgICAgJG5hbWUkVmFsdWVDb252ZXJ0ZXIpO1xuIgorICAgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TWFwKCk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJDxcbiIKKyAgICAgICIgICAgJHR5cGVfcGFyYW1ldGVycyQ+ICRuYW1lJF87XG4iCisgICAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkJGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgImludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJF8gPT0gbnVsbCkge1xuIgorICAgICAgIiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJC5lbXB0eU1hcEZpZWxkKFxuIgorICAgICAgIiAgICAgICAgJG1hcF9maWVsZF9wYXJhbWV0ZXIkKTtcbiIKKyAgICAgICIgfVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgICAifVxuIgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJDwkdHlwZV9wYXJhbWV0ZXJzJD5cbiIKKyAgICAgICJpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICAkb25fY2hhbmdlZCQ7XG4iCisgICAgICAiICBpZiAoJG5hbWUkXyA9PSBudWxsKSB7XG4iCisgICAgICAiICAgICRuYW1lJF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkJGxpdGUkLm5ld01hcEZpZWxkKFxuIgorICAgICAgIiAgICAgICAgJG1hcF9maWVsZF9wYXJhbWV0ZXIkKTtcbiIKKyAgICAgICIgfVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgICAifVxuIik7CisgIGlmIChHZXRKYXZhVHlwZShWYWx1ZUZpZWxkKGRlc2NyaXB0b3JfKSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkPlxuIgorICAgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjxcbiIKKyAgICAgICAgIiAgICAgICRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkLCBqYXZhLmxhbmcuSW50ZWdlcj4oXG4iCisgICAgICAgICIgICAgICAgICAgaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKSxcbiIKKyAgICAgICAgIiAgICAgICAgICAkbmFtZSRWYWx1ZUNvbnZlcnRlcik7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkdmFsdWVfZW51bV90eXBlJD5cbiIKKyAgICAgICAgImdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPFxuIgorICAgICAgICAiICAgICAgJGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQsIGphdmEubGFuZy5JbnRlZ2VyPihcbiIKKyAgICAgICAgIiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNdXRhYmxlTWFwKCksXG4iCisgICAgICAgICIgICAgICAgICAgJG5hbWUkVmFsdWVDb252ZXJ0ZXIpO1xuIgorICAgICAgICAifVxuIik7CisgICAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICRib3hlZF92YWx1ZV90eXBlJD5cbiIKKyAgICAgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TWFwKCk7XG4iCisgICAgICAgICAgIn1cbiIpOworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkYm94ZWRfdmFsdWVfdHlwZSQ+XG4iCisgICAgICAgICAgImdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpIHtcbiIKKyAgICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TXV0YWJsZU1hcCgpO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TWFwKCk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkdHlwZV9wYXJhbWV0ZXJzJD5cbiIKKyAgICAgICAgImdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNdXRhYmxlTWFwKCk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBOb3RoaW5nIHRvIGluaXRpYWxpemUuCit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90aGluZyB0byBpbml0aWFsaXplLgorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiaW50ZXJuYWxHZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkuY2xlYXIoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImludGVybmFsR2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpLm1lcmdlRnJvbShcbiIKKyAgICAgICIgICAgb3RoZXIuaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAvLyBXZSBkbyBhIGNvcHkgb2YgdGhlIG1hcCBmaWVsZCB0byBlbnN1cmUgdGhhdCB0aGUgYnVpbHQgcmVzdWx0IGlzCisgICAgICAvLyBpbW11dGFibGUuIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgY29weSgpIG1ldGhvZCBjYW4gZG8gY29weS1vbi13cml0ZQorICAgICAgLy8gdG8gZGVmZXIgdGhpcyBjb3B5IHVudGlsIGZ1cnRoZXIgbW9kaWZpY2F0aW9ucyBhcmUgbWFkZSBvbiB0aGUgZmllbGQuCisgICAgICAicmVzdWx0LiRuYW1lJF8gPSBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmNvcHkoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgICAiICAkbmFtZSRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJC5uZXdNYXBGaWVsZChcbiIKKyAgICAgICIgICAgICAkbWFwX2ZpZWxkX3BhcmFtZXRlciQpO1xuIgorICAgICAgIiAgJHNldF9tdXRhYmxlX2JpdF9wYXJzZXIkO1xuIgorICAgICAgIn1cbiIpOworICBpZiAoIVN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICBHZXRKYXZhVHlwZShWYWx1ZUZpZWxkKGRlc2NyaXB0b3JfKSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7XG4iCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgICAiJG5hbWUkID0gJG5hbWUkRGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpO1xuIik7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJHZhbHVlX2VudW1fdHlwZSQudmFsdWVPZigkbmFtZSQuZ2V0VmFsdWUoKSkgPT0gbnVsbCkge1xuIgorICAgICAgICAiICB1bmtub3duRmllbGRzLm1lcmdlTGVuZ3RoRGVsaW1pdGVkRmllbGQoJG51bWJlciQsIGJ5dGVzKTtcbiIKKyAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICIgICRuYW1lJF8uZ2V0TXV0YWJsZU1hcCgpLnB1dCgkbmFtZSQuZ2V0S2V5KCksICRuYW1lJC5nZXRWYWx1ZSgpKTtcbiIKKyAgICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeSRsaXRlJDwkdHlwZV9wYXJhbWV0ZXJzJD5cbiIKKyAgICAgICAgIiRuYW1lJCA9IGlucHV0LnJlYWRNZXNzYWdlKFxuIgorICAgICAgICAiICAgICRuYW1lJERlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAgICAgIiRuYW1lJF8uZ2V0TXV0YWJsZU1hcCgpLnB1dCgkbmFtZSQuZ2V0S2V5KCksICRuYW1lJC5nZXRWYWx1ZSgpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90aGluZyB0byBkbyBoZXJlLgorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImZvciAoamF2YS51dGlsLk1hcC5FbnRyeTwkdHlwZV9wYXJhbWV0ZXJzJD4gZW50cnlcbiIKKyAgICAgICIgICAgIDogaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7XG4iCisgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgIiAgJG5hbWUkID0gJG5hbWUkRGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKClcbiIKKyAgICAgICIgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKVxuIgorICAgICAgIiAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKVxuIgorICAgICAgIiAgICAgIC5idWlsZCgpO1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlTWVzc2FnZSgkbnVtYmVyJCwgJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PCR0eXBlX3BhcmFtZXRlcnMkPiBlbnRyeVxuIgorICAgICAgIiAgICAgOiBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHtcbiIKKyAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSQ8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAiICAkbmFtZSQgPSAkbmFtZSREZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKVxuIgorICAgICAgIiAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpXG4iCisgICAgICAiICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpXG4iCisgICAgICAiICAgICAgLmJ1aWxkKCk7XG4iCisgICAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAgICIgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKCRudW1iZXIkLCAkbmFtZSQpO1xuIgorICAgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZXF1YWxzKFxuIgorICAgICAgIiAgICBvdGhlci5pbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImlmICghaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHtcbiIKKyAgICAgICIgIGhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICIgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuaGFzaENvZGUoKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKworc3RyaW5nIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZTZkZDk3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmgKQEAgLTAsMCArMSw4MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUFQX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NQVBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3RhdGljSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKyAgY29uc3QgaW50IG1lc3NhZ2VCaXRJbmRleF87CisgIGNvbnN0IGludCBidWlsZGVyQml0SW5kZXhfOworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUFQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk4MmExNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MKQEAgLTAsMCArMSwxOTE5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKK2Jvb2wgR2VuZXJhdGVIYXNCaXRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3ItPmZpbGUoKSkgfHwKKyAgICAgIEhhc1JlcGVhdGVkRmllbGRzKGRlc2NyaXB0b3IpOworfQorCitzdHJpbmcgTWFwVmFsdWVJbW11dGFibGVDbGFzc2ROYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIEdPT0dMRV9DSEVDS19FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgdmFsdWVfZmllbGQtPnR5cGUoKSk7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLT5HZXRJbW11dGFibGVDbGFzc05hbWUodmFsdWVfZmllbGQtPm1lc3NhZ2VfdHlwZSgpKTsKK30KK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VHZW5lcmF0b3I6Ok1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7fQorCitNZXNzYWdlR2VuZXJhdG9yOjp+TWVzc2FnZUdlbmVyYXRvcigpIHt9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFRPRE8oYXBpKTogTW92ZSB0aGlzIGNsYXNzIHRvIGEgc2VwYXJhdGUgaW1tdXRhYmxlX21lc3NhZ2UuY2MgZmlsZS4KK0ltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgOiBNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3IpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oZGVzY3JpcHRvciwgY29udGV4dF8pIHsKK30KKworSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6fkltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU3RhdGljVmFyaWFibGVzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBCZWNhdXNlIGRlc2NyaXB0b3IucHJvdG8gKGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvcykgaXMKKyAgICAvLyB1c2VkIGluIHRoZSBjb25zdHJ1Y3Rpb24gb2YgZGVzY3JpcHRvcnMsIHdlIGhhdmUgYSB0cmlja3kgYm9vdHN0cmFwcGluZworICAgIC8vIHByb2JsZW0uICBUbyBoZWxwIGNvbnRyb2wgc3RhdGljIGluaXRpYWxpemF0aW9uIG9yZGVyLCB3ZSBtYWtlIHN1cmUgYWxsCisgICAgLy8gZGVzY3JpcHRvcnMgYW5kIG90aGVyIHN0YXRpYyBkYXRhIHRoYXQgZGVwZW5kcyBvbiB0aGVtIGFyZSBtZW1iZXJzIG9mCisgICAgLy8gdGhlIG91dGVybW9zdCBjbGFzcyBpbiB0aGUgZmlsZS4gIFRoaXMgd2F5LCB0aGV5IHdpbGwgYmUgaW5pdGlhbGl6ZWQgaW4KKyAgICAvLyBhIGRldGVybWluaXN0aWMgb3JkZXIuCisKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siaWRlbnRpZmllciJdID0gVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXyk7CisgICAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpOworICAgIHZhcnNbImNsYXNzbmFtZSJdID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgICAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSAhPSBOVUxMKSB7CisgICAgICB2YXJzWyJwYXJlbnQiXSA9IFVuaXF1ZUZpbGVTY29wZUlkZW50aWZpZXIoCisgICAgICAgICAgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgICB9CisgICAgaWYgKE11bHRpcGxlSmF2YUZpbGVzKGRlc2NyaXB0b3JfLT5maWxlKCksIC8qIGltbXV0YWJsZSA9ICovIHRydWUpKSB7CisgICAgICAvLyBXZSBjYW4gb25seSBtYWtlIHRoZXNlIHBhY2thZ2UtcHJpdmF0ZSBzaW5jZSB0aGUgY2xhc3NlcyB0aGF0IHVzZSB0aGVtCisgICAgICAvLyBhcmUgaW4gc2VwYXJhdGUgZmlsZXMuCisgICAgICB2YXJzWyJwcml2YXRlIl0gPSAiIjsKKyAgICB9IGVsc2UgeworICAgICAgdmFyc1sicHJpdmF0ZSJdID0gInByaXZhdGUgIjsKKyAgICB9CisKKyAgICAvLyBUaGUgZGVzY3JpcHRvciBmb3IgdGhpcyB0eXBlLgorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJHByaXZhdGUkc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvclxuIgorICAgICAgIiAgaW50ZXJuYWxfJGlkZW50aWZpZXIkX2Rlc2NyaXB0b3I7XG4iKTsKKworICAgIC8vIEFuZCB0aGUgRmllbGRBY2Nlc3NvclRhYmxlLgorICAgIEdlbmVyYXRlRmllbGRBY2Nlc3NvclRhYmxlKHByaW50ZXIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgc3RhdGljIG1lbWJlcnMgZm9yIGFsbCBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIFRPRE8oa2VudG9uKTogIFJldXNlIE1lc3NhZ2VHZW5lcmF0b3Igb2JqZWN0cz8KKyAgICBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgY29udGV4dF8pCisgICAgICAuR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siaWRlbnRpZmllciJdID0gVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXyk7CisgICAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpOworICAgIHZhcnNbImNsYXNzbmFtZSJdID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgICAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSAhPSBOVUxMKSB7CisgICAgICB2YXJzWyJwYXJlbnQiXSA9IFVuaXF1ZUZpbGVTY29wZUlkZW50aWZpZXIoCisgICAgICAgICAgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgICB9CisKKyAgICAvLyBUaGUgZGVzY3JpcHRvciBmb3IgdGhpcyB0eXBlLgorICAgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgImludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yID1cbiIKKyAgICAgICAgIiAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgkaW5kZXgkKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiaW50ZXJuYWxfJGlkZW50aWZpZXIkX2Rlc2NyaXB0b3IgPVxuIgorICAgICAgICAiICBpbnRlcm5hbF8kcGFyZW50JF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KCRpbmRleCQpO1xuIik7CisgICAgfQorCisgICAgLy8gQW5kIHRoZSBGaWVsZEFjY2Vzc29yVGFibGUuCisgICAgR2VuZXJhdGVGaWVsZEFjY2Vzc29yVGFibGVJbml0aWFsaXplcihwcmludGVyKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIHN0YXRpYyBtZW1iZXIgaW5pdGlhbGl6ZXJzIGZvciBhbGwgbmVzdGVkIHR5cGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBSZXVzZSBNZXNzYWdlR2VuZXJhdG9yIG9iamVjdHM/CisgICAgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSksIGNvbnRleHRfKQorICAgICAgLkdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRBY2Nlc3NvclRhYmxlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siaWRlbnRpZmllciJdID0gVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXyk7CisgIGlmIChNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpLCAvKiBpbW11dGFibGUgPSAqLyB0cnVlKSkgeworICAgIC8vIFdlIGNhbiBvbmx5IG1ha2UgdGhlc2UgcGFja2FnZS1wcml2YXRlIHNpbmNlIHRoZSBjbGFzc2VzIHRoYXQgdXNlIHRoZW0KKyAgICAvLyBhcmUgaW4gc2VwYXJhdGUgZmlsZXMuCisgICAgdmFyc1sicHJpdmF0ZSJdID0gIiI7CisgIH0gZWxzZSB7CisgICAgdmFyc1sicHJpdmF0ZSJdID0gInByaXZhdGUgIjsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIkcHJpdmF0ZSRzdGF0aWNcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRmllbGRBY2Nlc3NvclRhYmxlXG4iCisgICAgIiAgICBpbnRlcm5hbF8kaWRlbnRpZmllciRfZmllbGRBY2Nlc3NvclRhYmxlO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQWNjZXNzb3JUYWJsZUluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJpbnRlcm5hbF8kaWRlbnRpZmllciRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3XG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkZpZWxkQWNjZXNzb3JUYWJsZShcbiIKKyAgICAiICAgIGludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yLFxuIgorICAgICIgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICIsCisgICAgImlkZW50aWZpZXIiLAorICAgIFVuaXF1ZUZpbGVTY29wZUlkZW50aWZpZXIoZGVzY3JpcHRvcl8pKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcIiRmaWVsZF9uYW1lJFwiLCAiLAorICAgICAgImZpZWxkX25hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKTsKKyAgICBjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKG9uZW9mKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcIiRvbmVvZl9uYW1lJFwiLCAiLAorICAgICAgIm9uZW9mX25hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgfQorICBwcmludGVyLT5QcmludCgifSk7XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlSW50ZXJmYWNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgaW50ZXJmYWNlICRjbGFzc25hbWUkT3JCdWlsZGVyIGV4dGVuZHNcbiIKKyAgICAgICAgIiAgICAkZXh0cmFfaW50ZXJmYWNlcyRcbiIKKyAgICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuXG4iCisgICAgICAgICIgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPCRjbGFzc25hbWUkPiB7XG4iLAorICAgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhTWVzc2FnZU9yQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pLAorICAgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAicHVibGljIGludGVyZmFjZSAkY2xhc3NuYW1lJE9yQnVpbGRlciBleHRlbmRzIFxuIgorICAgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgICAiICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLlxuIgorICAgICAgICAiICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPFxuIgorICAgICAgICAiICAgICAgICAgICAgICAkY2xhc3NuYW1lJCwgJGNsYXNzbmFtZSQuQnVpbGRlcj4ge1xuIiwKKyAgICAgICAgImV4dHJhX2ludGVyZmFjZXMiLCBFeHRyYU1lc3NhZ2VPckJ1aWxkZXJJbnRlcmZhY2VzKGRlc2NyaXB0b3JfKSwKKyAgICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInB1YmxpYyBpbnRlcmZhY2UgJGNsYXNzbmFtZSRPckJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7XG4iLAorICAgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhTWVzc2FnZU9yQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pLAorICAgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAicHVibGljIGludGVyZmFjZSAkY2xhc3NuYW1lJE9yQnVpbGRlciBleHRlbmRzXG4iCisgICAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlciB7XG4iLAorICAgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhTWVzc2FnZU9yQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pLAorICAgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMocHJpbnRlcik7CisgICAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgYm9vbCBpc19vd25fZmlsZSA9CisgICAgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpID09IE5VTEwgJiYKKyAgICBNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpLCAvKiBpbW11dGFibGUgPSAqLyB0cnVlKTsKKworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlczsKKyAgdmFyaWFibGVzWyJzdGF0aWMiXSA9IGlzX293bl9maWxlID8gIiAiIDogIiBzdGF0aWMgIjsKKyAgdmFyaWFibGVzWyJjbGFzc25hbWUiXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgIHZhcmlhYmxlc1siZXh0cmFfaW50ZXJmYWNlcyJdID0gRXh0cmFNZXNzYWdlSW50ZXJmYWNlcyhkZXNjcmlwdG9yXyk7CisgIHZhcmlhYmxlc1sibGl0ZSJdID0gSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pID8gIiIgOiAiTGl0ZSI7CisKKyAgV3JpdGVNZXNzYWdlRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisKKyAgLy8gVGhlIGJ1aWxkZXJfdHlwZSBzdG9yZXMgdGhlIHN1cGVyIHR5cGUgbmFtZSBvZiB0aGUgbmVzdGVkIEJ1aWxkZXIgY2xhc3MuCisgIHN0cmluZyBidWlsZGVyX3R5cGU7CisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAicHVibGljICRzdGF0aWMkZmluYWwgY2xhc3MgJGNsYXNzbmFtZSQgZXh0ZW5kc1xuIgorICAgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5FeHRlbmRhYmxlTWVzc2FnZTxcbiIKKyAgICAgICAgIiAgICAgICRjbGFzc25hbWUkPiBpbXBsZW1lbnRzXG4iCisgICAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAgICIgICAgJGNsYXNzbmFtZSRPckJ1aWxkZXIge1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgInB1YmxpYyAkc3RhdGljJGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIGV4dGVuZHNcbiIKKyAgICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLkV4dGVuZGFibGVNZXNzYWdlPFxuIgorICAgICAgICAiICAgICAgJGNsYXNzbmFtZSQsICRjbGFzc25hbWUkLkJ1aWxkZXI+IGltcGxlbWVudHNcbiIKKyAgICAgICAgIiAgICAkZXh0cmFfaW50ZXJmYWNlcyRcbiIKKyAgICAgICAgIiAgICAkY2xhc3NuYW1lJE9yQnVpbGRlciB7XG4iKTsKKyAgICB9CisgICAgYnVpbGRlcl90eXBlID0gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlJDEuRXh0ZW5kYWJsZUJ1aWxkZXI8JDAsID8+IiwKKyAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSwKKyAgICAgICAgICAgICB2YXJpYWJsZXNbImxpdGUiXSk7CisgIH0gZWxzZSB7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAicHVibGljICRzdGF0aWMkZmluYWwgY2xhc3MgJGNsYXNzbmFtZSQgZXh0ZW5kc1xuIgorICAgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZSBpbXBsZW1lbnRzXG4iCisgICAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAgICIgICAgJGNsYXNzbmFtZSRPckJ1aWxkZXIge1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgInB1YmxpYyAkc3RhdGljJGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIGV4dGVuZHNcbiIKKyAgICAgICAgICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlPFxuIgorICAgICAgICAgICAgICAiICAgICAgICAkY2xhc3NuYW1lJCwgJGNsYXNzbmFtZSQuQnVpbGRlcj4gaW1wbGVtZW50c1xuIgorICAgICAgICAgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgICAgICAgICAiICAgICRjbGFzc25hbWUkT3JCdWlsZGVyIHtcbiIpOworICAgIH0KKworICAgIGJ1aWxkZXJfdHlwZSA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UkMC5CdWlsZGVyIiwKKyAgICAgICAgdmFyaWFibGVzWyJsaXRlIl0pOworICB9CisgIHByaW50ZXItPkluZGVudCgpOworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gVXNpbmcgYnVpbGRlcl90eXBlLCBpbnN0ZWFkIG9mIEJ1aWxkZXIsIHByZXZlbnRzIHRoZSBCdWlsZGVyIGNsYXNzIGZyb20KKyAgICAvLyBiZWluZyBsb2FkZWQgaW50byBQZXJtR2VuIHNwYWNlIHdoZW4gdGhlIGRlZmF1bHQgaW5zdGFuY2UgaXMgY3JlYXRlZC4KKyAgICAvLyBUaGlzIG9wdGltaXplcyB0aGUgUGVybUdlbiBzcGFjZSB1c2FnZSBmb3IgY2xpZW50cyB0aGF0IGRvIG5vdCBtb2RpZnkKKyAgICAvLyBtZXNzYWdlcy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIvLyBVc2UgJGNsYXNzbmFtZSQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC5cbiIKKyAgICAgICJwcml2YXRlICRjbGFzc25hbWUkKCRidWlsZGVydHlwZSQgYnVpbGRlcikge1xuIgorICAgICAgIiAgc3VwZXIoYnVpbGRlcik7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpLAorICAgICAgImJ1aWxkZXJ0eXBlIiwgYnVpbGRlcl90eXBlKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwcml2YXRlICRjbGFzc25hbWUkKCkge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBHZW5lcmF0ZUluaXRpYWxpemVycyhwcmludGVyKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICAgInB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldFxuIgorICAgICAgImdldFVua25vd25GaWVsZHMoKSB7XG4iKTsKKyAgICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIHJldHVybiB0aGlzLnVua25vd25GaWVsZHM7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIEdlbmVyYXRlUGFyc2luZ0NvbnN0cnVjdG9yKHByaW50ZXIpOworICB9CisKKyAgR2VuZXJhdGVEZXNjcmlwdG9yTWV0aG9kcyhwcmludGVyLCBmYWxzZSk7CisgIEdlbmVyYXRlUGFyc2VyKHByaW50ZXIpOworCisgIC8vIE5lc3RlZCB0eXBlcworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgRW51bUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+ZW51bV90eXBlKGkpLCB0cnVlLCBjb250ZXh0XykKKyAgICAgICAgLkdlbmVyYXRlKHByaW50ZXIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gRG9uJ3QgZ2VuZXJhdGUgSmF2YSBjbGFzc2VzIGZvciBtYXAgZW50cnkgbWVzc2FnZXMuCisgICAgaWYgKElzTWFwRW50cnkoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpKSkgY29udGludWU7CisgICAgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvciBtZXNzYWdlR2VuZXJhdG9yKAorICAgICAgICBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSksIGNvbnRleHRfKTsKKyAgICBtZXNzYWdlR2VuZXJhdG9yLkdlbmVyYXRlSW50ZXJmYWNlKHByaW50ZXIpOworICAgIG1lc3NhZ2VHZW5lcmF0b3IuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICBpZiAoR2VuZXJhdGVIYXNCaXRzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIEludGVnZXJzIGZvciBiaXQgZmllbGRzLgorICAgIGludCB0b3RhbEJpdHMgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgdG90YWxCaXRzICs9IGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdldE51bUJpdHNGb3JNZXNzYWdlKCk7CisgICAgfQorICAgIGludCB0b3RhbEludHMgPSAodG90YWxCaXRzICsgMzEpIC8gMzI7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbEludHM7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoInByaXZhdGUgaW50ICRiaXRfZmllbGRfbmFtZSQ7XG4iLAorICAgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICAgIH0KKyAgfQorCisgIC8vIG9uZW9mCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICB2YXJzWyJvbmVvZl9uYW1lIl0gPSBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPm5hbWU7CisgICAgdmFyc1sib25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSJdID0gY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5jYXBpdGFsaXplZF9uYW1lOworICAgIHZhcnNbIm9uZW9mX2luZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5pbmRleCgpKTsKKyAgICAvLyBvbmVvZkNhc2VfIGFuZCBvbmVvZl8KKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInByaXZhdGUgaW50ICRvbmVvZl9uYW1lJENhc2VfID0gMDtcbiIKKyAgICAgICJwcml2YXRlIGphdmEubGFuZy5PYmplY3QgJG9uZW9mX25hbWUkXztcbiIpOworICAgIC8vIE9uZW9mQ2FzZSBlbnVtCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgZW51bSAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlXG4iCisgICAgICAiICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiRmaWVsZF9uYW1lJCgkZmllbGRfbnVtYmVyJCksXG4iLAorICAgICAgICAiZmllbGRfbmFtZSIsCisgICAgICAgIFRvVXBwZXIoZmllbGQtPm5hbWUoKSksCisgICAgICAgICJmaWVsZF9udW1iZXIiLAorICAgICAgICBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIkY2FwX29uZW9mX25hbWUkX05PVF9TRVQoMCk7XG4iLAorICAgICAgImNhcF9vbmVvZl9uYW1lIiwKKyAgICAgIFRvVXBwZXIodmFyc1sib25lb2ZfbmFtZSJdKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwcml2YXRlIGludCB2YWx1ZSA9IDA7XG4iCisgICAgICAicHJpdmF0ZSAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlKGludCB2YWx1ZSkge1xuIgorICAgICAgIiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuIgorICAgICAgIn1cbiIpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHVibGljIHN0YXRpYyAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICBzd2l0Y2ggKHZhbHVlKSB7XG4iKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgICBjYXNlICRmaWVsZF9udW1iZXIkOiByZXR1cm4gJGZpZWxkX25hbWUkO1xuIiwKKyAgICAgICAgImZpZWxkX251bWJlciIsCisgICAgICAgIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKSwKKyAgICAgICAgImZpZWxkX25hbWUiLAorICAgICAgICBUb1VwcGVyKGZpZWxkLT5uYW1lKCkpKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgIGNhc2UgMDogcmV0dXJuICRjYXBfb25lb2ZfbmFtZSRfTk9UX1NFVDtcbiIKKyAgICAgICIgICAgZGVmYXVsdDogdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oXG4iCisgICAgICAiICAgICAgXCJWYWx1ZSBpcyB1bmRlZmluZWQgZm9yIHRoaXMgb25lb2YgZW51bS5cIik7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIgorICAgICAgInB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkge1xuIgorICAgICAgIiAgcmV0dXJuIHRoaXMudmFsdWU7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjYXBfb25lb2ZfbmFtZSIsIFRvVXBwZXIodmFyc1sib25lb2ZfbmFtZSJdKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9O1xuXG4iKTsKKyAgICAvLyBvbmVvZkNhc2UoKQorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHVibGljICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2VcbiIKKyAgICAgICJnZXQkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UudmFsdWVPZihcbiIKKyAgICAgICIgICAgICAkb25lb2ZfbmFtZSRDYXNlXyk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KKworICAvLyBGaWVsZHMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkO1xuIiwKKyAgICAgICJjb25zdGFudF9uYW1lIiwgRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSwKKyAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5maWVsZChpKS0+bnVtYmVyKCkpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKS5HZW5lcmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBHZW5lcmF0ZUlzSW5pdGlhbGl6ZWQocHJpbnRlciwgTUVNT0laRSk7CisgICAgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMocHJpbnRlcik7CisgIH0KKworICBpZiAoSGFzRXF1YWxzQW5kSGFzaENvZGUoZGVzY3JpcHRvcl8pKSB7CisgICAgR2VuZXJhdGVFcXVhbHNBbmRIYXNoQ29kZShwcmludGVyKTsKKyAgfQorCisKKyAgR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKHByaW50ZXIpOworICBHZW5lcmF0ZUJ1aWxkZXIocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisKKyAgLy8gQ2FyZWZ1bGx5IGluaXRpYWxpemUgdGhlIGRlZmF1bHQgaW5zdGFuY2UgaW4gc3VjaCBhIHdheSB0aGF0IGl0IGRvZXNuJ3QKKyAgLy8gY29uZmxpY3Qgd2l0aCBvdGhlciBpbml0aWFsaXphdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsICRjbGFzc25hbWUkIGRlZmF1bHRJbnN0YW5jZTtcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInN0YXRpYyB7XG4iCisgICAgICAiICBkZWZhdWx0SW5zdGFuY2UgPSBuZXcgJGNsYXNzbmFtZSQoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBMSVRFX1JVTlRJTUUgb25seSBoYXMgb25lIGNvbnN0cnVjdG9yLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInN0YXRpYyB7XG4iCisgICAgICAiICBkZWZhdWx0SW5zdGFuY2UgPSBuZXcgJGNsYXNzbmFtZSQoXG4iCisgICAgICAiICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbFxuIgorICAgICAgIiAgICAgICAgICAuRU1QVFlfQ09ERURfSU5QVVRfU1RSRUFNLFxuIgorICAgICAgIiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlXG4iCisgICAgICAiICAgICAgICAgIC5nZXRFbXB0eVJlZ2lzdHJ5KCkpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7XG4iCisgICAgICAiICByZXR1cm4gZGVmYXVsdEluc3RhbmNlO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBMSVRFX1JVTlRJTUUgaW1wbGVtZW50cyB0aGlzIGF0IHRoZSBHZW5lcmF0ZWRNZXNzYWdlTGl0ZSBsZXZlbC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiBkZWZhdWx0SW5zdGFuY2U7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgIH0gZWxzZSB7CisgICAgLy8gTElURV9SVU5USU1FIHVzZXMgdGhpcyB0byBpbXBsZW1lbnQgdGhlICpGb3JUeXBlIG1ldGhvZHMgYXQgdGhlCisgICAgLy8gR2VuZXJhdGVkTWVzc2FnZUxpdGUgbGV2ZWwuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAic3RhdGljIHsiCisgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLm9uTG9hZChcbiIKKyAgICAgICIgICAgICAkY2xhc3NuYW1lJC5jbGFzcywgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGVcbiIKKyAgICAgICIgICAgICAgICAgLlByb3RvdHlwZUhvbGRlcjwkY2xhc3NuYW1lJCwgQnVpbGRlcj4oXG4iCisgICAgICAiICAgICAgICAgICAgICBkZWZhdWx0SW5zdGFuY2UsIFBBUlNFUikpOyIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbnMgbXVzdCBiZSBkZWNsYXJlZCBhZnRlciB0aGUgZGVmYXVsdEluc3RhbmNlIGlzIGluaXRpYWxpemVkCisgIC8vIGJlY2F1c2UgdGhlIGRlZmF1bHRJbnN0YW5jZSBpcyB1c2VkIGJ5IHRoZSBleHRlbnNpb24gdG8gbGF6aWx5IHJldHJpZXZlCisgIC8vIHRoZSBvdXRlciBjbGFzcydzIEZpbGVEZXNjcmlwdG9yLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5leHRlbnNpb24oaSksIGNvbnRleHRfKQorICAgICAgICAuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICAvLyBTb21lIGZpZWxkcyBhbHNvIGhhdmUgc3RhdGljIG1lbWJlcnMgdGhhdCBtdXN0IGJlIGluaXRpYWxpemVkIGFmdGVyIHdlCisgIC8vIGhhdmUgdGhlIGRlZmF1bHQgaW5zdGFuY2UgYXZhaWxhYmxlLgorICBwcmludGVyLT5QcmludCgKKyAgICAgICJzdGF0aWMge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAuR2VuZXJhdGVTdGF0aWNJbml0aWFsaXphdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IgKiA+IHNvcnRlZF9maWVsZHMoCisgICAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqPiBzb3J0ZWRfZXh0ZW5zaW9uczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIHNvcnRlZF9leHRlbnNpb25zLnB1c2hfYmFjayhkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlKGkpKTsKKyAgfQorICBzdGQ6OnNvcnQoc29ydGVkX2V4dGVuc2lvbnMuYmVnaW4oKSwgc29ydGVkX2V4dGVuc2lvbnMuZW5kKCksCisgICAgICAgICAgICBFeHRlbnNpb25SYW5nZU9yZGVyaW5nKCkpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KVxuIgorICAgICIgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaWYgKEhhc1BhY2tlZEZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyB3cml0ZVRvKENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkgbWlnaHQgYmUgaW52b2tlZCB3aXRob3V0CisgICAgLy8gZ2V0U2VyaWFsaXplZFNpemUoKSBldmVyIGJlaW5nIGNhbGxlZCwgYnV0IHdlIG5lZWQgdGhlIG1lbW9pemVkCisgICAgLy8gc2l6ZXMgaW4gY2FzZSB0aGlzIG1lc3NhZ2UgaGFzIHBhY2tlZCBmaWVsZHMuIFJhdGhlciB0aGFuIGVtaXQgY2hlY2tzIGZvcgorICAgIC8vIGVhY2ggcGFja2VkIGZpZWxkLCBqdXN0IGNhbGwgZ2V0U2VyaWFsaXplZFNpemUoKSB1cCBmcm9udC4KKyAgICAvLyBJbiBtb3N0IGNhc2VzLCBnZXRTZXJpYWxpemVkU2l6ZSgpIHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4gY2FsbGVkIGFueXdheQorICAgIC8vIGJ5IG9uZSBvZiB0aGUgd3JhcHBlciB3cml0ZVRvKCkgbWV0aG9kcywgbWFraW5nIHRoaXMgY2FsbCBjaGVhcC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJnZXRTZXJpYWxpemVkU2l6ZSgpO1xuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVxuIgorICAgICAgICAgICIgIC5FeHRlbmRhYmxlTWVzc2FnZTwkY2xhc3NuYW1lJD4uRXh0ZW5zaW9uV3JpdGVyXG4iCisgICAgICAgICAgIiAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdNZXNzYWdlU2V0RXh0ZW5zaW9uV3JpdGVyKCk7XG4iLAorICAgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZVxuIgorICAgICAgICAgICIgIC5FeHRlbmRhYmxlTWVzc2FnZTwkY2xhc3NuYW1lJCwgJGNsYXNzbmFtZSQuQnVpbGRlcj5cbiIKKyAgICAgICAgICAiICAgIC5FeHRlbnNpb25Xcml0ZXIgZXh0ZW5zaW9uV3JpdGVyID1cbiIKKyAgICAgICAgICAiICAgICAgbmV3TWVzc2FnZVNldEV4dGVuc2lvbldyaXRlcigpO1xuIiwKKyAgICAgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VcbiIKKyAgICAgICAgICAiICAuRXh0ZW5kYWJsZU1lc3NhZ2U8JGNsYXNzbmFtZSQ+LkV4dGVuc2lvbldyaXRlclxuIgorICAgICAgICAgICIgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7XG4iLAorICAgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZVxuIgorICAgICAgICAgICIgIC5FeHRlbmRhYmxlTWVzc2FnZTwkY2xhc3NuYW1lJCwgJGNsYXNzbmFtZSQuQnVpbGRlcj5cbiIKKyAgICAgICAgICAiICAgIC5FeHRlbnNpb25Xcml0ZXIgZXh0ZW5zaW9uV3JpdGVyID1cbiIKKyAgICAgICAgICAiICAgICAgbmV3RXh0ZW5zaW9uV3JpdGVyKCk7XG4iLAorICAgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gTWVyZ2UgdGhlIGZpZWxkcyBhbmQgdGhlIGV4dGVuc2lvbiByYW5nZXMsIGJvdGggc29ydGVkIGJ5IGZpZWxkIG51bWJlci4KKyAgZm9yIChpbnQgaSA9IDAsIGogPSAwOworICAgICAgIGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSB8fCBqIDwgc29ydGVkX2V4dGVuc2lvbnMuc2l6ZSgpOworICAgICAgICkgeworICAgIGlmIChpID09IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUV4dGVuc2lvblJhbmdlKHByaW50ZXIsIHNvcnRlZF9leHRlbnNpb25zW2orK10pOworICAgIH0gZWxzZSBpZiAoaiA9PSBzb3J0ZWRfZXh0ZW5zaW9ucy5zaXplKCkpIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQocHJpbnRlciwgc29ydGVkX2ZpZWxkc1tpKytdKTsKKyAgICB9IGVsc2UgaWYgKHNvcnRlZF9maWVsZHNbaV0tPm51bWJlcigpIDwgc29ydGVkX2V4dGVuc2lvbnNbal0tPnN0YXJ0KSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKHByaW50ZXIsIHNvcnRlZF9maWVsZHNbaSsrXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UocHJpbnRlciwgc29ydGVkX2V4dGVuc2lvbnNbaisrXSk7CisgICAgfQorICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpCisgICAgICAgICYmIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ1bmtub3duRmllbGRzLndyaXRlQXNNZXNzYWdlU2V0VG8ob3V0cHV0KTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInVua25vd25GaWVsZHMud3JpdGVUbyhvdXRwdXQpO1xuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAicHJpdmF0ZSBpbnQgbWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xO1xuIgorICAgICJwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkge1xuIgorICAgICIgIGludCBzaXplID0gbWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTtcbiIKKyAgICAiICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7XG4iCisgICAgIlxuIgorICAgICIgIHNpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChzb3J0ZWRfZmllbGRzW2ldKS5HZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShwcmludGVyKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZUFzTWVzc2FnZVNldCgpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAic2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTtcbiIpOworICAgIH0KKyAgfQorCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKQorICAgICAgICAmJiBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAic2l6ZSArPSB1bmtub3duRmllbGRzLmdldFNlcmlhbGl6ZWRTaXplQXNNZXNzYWdlU2V0KCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzaXplICs9IHVua25vd25GaWVsZHMuZ2V0U2VyaWFsaXplZFNpemUoKTtcbiIpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgbWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IHNpemU7XG4iCisgICAgIiAgcmV0dXJuIHNpemU7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBOb3RlOiAgVGhlc2UgYXJlIHNlcGFyYXRlIGZyb20gR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoKQorICAvLyAgIGJlY2F1c2UgdGhleSBuZWVkIHRvIGJlIGdlbmVyYXRlZCBldmVuIGZvciBtZXNzYWdlcyB0aGF0IGFyZSBvcHRpbWl6ZWQKKyAgLy8gICBmb3IgY29kZSBzaXplLgorICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSlcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpXG4iCisgICAgIiAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgYnl0ZVtdIGRhdGEsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSlcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oaW5wdXQpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dClcbiIKKyAgICAiICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gUEFSU0VSLnBhcnNlRGVsaW1pdGVkRnJvbShpbnB1dCk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZURlbGltaXRlZEZyb20oXG4iCisgICAgIiAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIFBBUlNFUi5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dClcbiIKKyAgICAiICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShpbnB1dCk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSlcbiIKKyAgICAiICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKHByaW50ZXIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoJGVuZCQsIG91dHB1dCk7XG4iLAorICAgICJlbmQiLCBTaW1wbGVJdG9hKHJhbmdlLT5lbmQpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlQnVpbGRlcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTElURV9SVU5USU1FIGltcGxlbWVudHMgdGhpcyBhdCB0aGUgR2VuZXJhdGVkTWVzc2FnZUxpdGUgbGV2ZWwuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH1cbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkge1xuIgorICAgICIgIHJldHVybiBkZWZhdWx0SW5zdGFuY2UudG9CdWlsZGVyKCk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoJGNsYXNzbmFtZSQgcHJvdG90eXBlKSB7XG4iCisgICAgIiAgcmV0dXJuIGRlZmF1bHRJbnN0YW5jZS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7XG4iCisgICAgIiAgcmV0dXJuIHRoaXMgPT0gZGVmYXVsdEluc3RhbmNlXG4iCisgICAgIiAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIGlmIChIYXNOZXN0ZWRCdWlsZGVycyhkZXNjcmlwdG9yXykpIHsKKyAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICAgInByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudCBwYXJlbnQpIHtcbiIKKyAgICAgICIgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7XG4iCisgICAgICAiICByZXR1cm4gYnVpbGRlcjtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlTWVzc2FnZURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5FeHRlbmRhYmxlQnVpbGRlcjxcbiIKKyAgICAgICAgIiAgICAgICRjbGFzc25hbWUkLCBCdWlsZGVyPiBpbXBsZW1lbnRzXG4iCisgICAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAgICIgICAgJGNsYXNzbmFtZSRPckJ1aWxkZXIge1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pLAorICAgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUuRXh0ZW5kYWJsZUJ1aWxkZXI8XG4iCisgICAgICAgICIgICAgICAkY2xhc3NuYW1lJCwgQnVpbGRlcj4gaW1wbGVtZW50c1xuIgorICAgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgICAiICAgICRjbGFzc25hbWUkT3JCdWlsZGVyIHtcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSwKKyAgICAgICAgImV4dHJhX2ludGVyZmFjZXMiLCBFeHRyYUJ1aWxkZXJJbnRlcmZhY2VzKGRlc2NyaXB0b3JfKSk7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAicHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHNcbiIKKyAgICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzXG4iCisgICAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAgICIgICAgJGNsYXNzbmFtZSRPckJ1aWxkZXIge1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pLAorICAgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUuQnVpbGRlcjxcbiIKKyAgICAgICAgIiAgICAgICRjbGFzc25hbWUkLCBCdWlsZGVyPlxuIgorICAgICAgICAiICAgIGltcGxlbWVudHNcbiIKKyAgICAgICAgIiAgICAkZXh0cmFfaW50ZXJmYWNlcyRcbiIKKyAgICAgICAgIiAgICAkY2xhc3NuYW1lJE9yQnVpbGRlciB7XG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXyksCisgICAgICAgICJleHRyYV9pbnRlcmZhY2VzIiwgRXh0cmFCdWlsZGVySW50ZXJmYWNlcyhkZXNjcmlwdG9yXykpOworICAgIH0KKyAgfQorICBwcmludGVyLT5JbmRlbnQoKTsKKworICBHZW5lcmF0ZURlc2NyaXB0b3JNZXRob2RzKHByaW50ZXIsIHRydWUpOworICBHZW5lcmF0ZUNvbW1vbkJ1aWxkZXJNZXRob2RzKHByaW50ZXIpOworCisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIEdlbmVyYXRlSXNJbml0aWFsaXplZChwcmludGVyLCBET05UX01FTU9JWkUpOworICAgIEdlbmVyYXRlQnVpbGRlclBhcnNpbmdNZXRob2RzKHByaW50ZXIpOworICB9CisKKyAgLy8gb25lb2YKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKS0+bmFtZTsKKyAgICB2YXJzWyJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIl0gPSBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPmNhcGl0YWxpemVkX25hbWU7CisgICAgdmFyc1sib25lb2ZfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmluZGV4KCkpOworICAgIC8vIG9uZW9mQ2FzZV8gYW5kIG9uZW9mXworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHJpdmF0ZSBpbnQgJG9uZW9mX25hbWUkQ2FzZV8gPSAwO1xuIgorICAgICAgInByaXZhdGUgamF2YS5sYW5nLk9iamVjdCAkb25lb2ZfbmFtZSRfO1xuIik7CisgICAgLy8gb25lb2ZDYXNlKCkgYW5kIGNsZWFyT25lb2YoKQorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHVibGljICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2VcbiIKKyAgICAgICIgICAgZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlLnZhbHVlT2YoXG4iCisgICAgICAiICAgICAgJG9uZW9mX25hbWUkQ2FzZV8pO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgQnVpbGRlciBjbGVhciRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgICRvbmVvZl9uYW1lJENhc2VfID0gMDtcbiIKKyAgICAgICIgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIik7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIiAgb25DaGFuZ2VkKCk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIGlmIChHZW5lcmF0ZUhhc0JpdHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gSW50ZWdlcnMgZm9yIGJpdCBmaWVsZHMuCisgICAgaW50IHRvdGFsQml0cyA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICB0b3RhbEJpdHMgKz0gZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAuR2V0TnVtQml0c0ZvckJ1aWxkZXIoKTsKKyAgICB9CisgICAgaW50IHRvdGFsSW50cyA9ICh0b3RhbEJpdHMgKyAzMSkgLyAzMjsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsSW50czsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgicHJpdmF0ZSBpbnQgJGJpdF9maWVsZF9uYW1lJDtcbiIsCisgICAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKHByaW50ZXIpOworICB9CisKKyAgaWYgKCFQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcyhcbiIKKyAgICAgICIgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykge1xuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgInB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcyhcbiIKKyAgICAgICIgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykge1xuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOiRmdWxsX25hbWUkKVxuIiwKKyAgICAiZnVsbF9uYW1lIiwgZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVzY3JpcHRvck1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgaXNfYnVpbGRlcikgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgaWYgKCFkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvclxuIgorICAgICAgICAiICAgIGdldERlc2NyaXB0b3IoKSB7XG4iCisgICAgICAgICIgIHJldHVybiAkZmlsZWNsYXNzJC5pbnRlcm5hbF8kaWRlbnRpZmllciRfZGVzY3JpcHRvcjtcbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgImZpbGVjbGFzcyIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSksCisgICAgICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworICAgIH0KKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gbWFwX2ZpZWxkczsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgICBpZiAoR2V0SmF2YVR5cGUoZmllbGQpID09IEpBVkFUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgICBJc01hcEVudHJ5KGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgICAgbWFwX2ZpZWxkcy5wdXNoX2JhY2soZmllbGQpOworICAgICAgfQorICAgIH0KKyAgICBpZiAoIW1hcF9maWVsZHMuZW1wdHkoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJAU3VwcHJlc3NXYXJuaW5ncyh7XCJyYXd0eXBlc1wifSlcbiIKKyAgICAgICAgInByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkIGludGVybmFsR2V0TWFwRmllbGQoXG4iCisgICAgICAgICIgICAgaW50IG51bWJlcikge1xuIgorICAgICAgICAiICBzd2l0Y2ggKG51bWJlcikge1xuIik7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBfZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBtYXBfZmllbGRzW2ldOworICAgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNhc2UgJG51bWJlciQ6XG4iCisgICAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iLAorICAgICAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSksCisgICAgICAgICAgImNhcGl0YWxpemVkX25hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJkZWZhdWx0OlxuIgorICAgICAgICAgICIgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFxuIgorICAgICAgICAgICIgICAgICBcIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogXCIgKyBudW1iZXIpO1xuIik7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgIn1cbiIpOworICAgICAgaWYgKGlzX2J1aWxkZXIpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIkBTdXBwcmVzc1dhcm5pbmdzKHtcInJhd3R5cGVzXCJ9KVxuIgorICAgICAgICAgICJwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZChcbiIKKyAgICAgICAgICAiICAgIGludCBudW1iZXIpIHtcbiIKKyAgICAgICAgICAiICBzd2l0Y2ggKG51bWJlcikge1xuIik7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBfZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG1hcF9maWVsZHNbaV07CisgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgICAgICAgICAgY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiY2FzZSAkbnVtYmVyJDpcbiIKKyAgICAgICAgICAgICIgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIsCisgICAgICAgICAgICAibnVtYmVyIiwgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpLAorICAgICAgICAgICAgImNhcGl0YWxpemVkX25hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgfQorICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICJkZWZhdWx0OlxuIgorICAgICAgICAgICAgIiAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oXG4iCisgICAgICAgICAgICAiICAgICAgXCJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6IFwiICsgbnVtYmVyKTtcbiIpOworICAgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgICAifVxuIik7CisgICAgICB9CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRmllbGRBY2Nlc3NvclRhYmxlXG4iCisgICAgICAiICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRmaWxlY2xhc3MkLmludGVybmFsXyRpZGVudGlmaWVyJF9maWVsZEFjY2Vzc29yVGFibGVcbiIKKyAgICAgICIgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZChcbiIKKyAgICAgICIgICAgICAgICAgJGNsYXNzbmFtZSQuY2xhc3MsICRjbGFzc25hbWUkLkJ1aWxkZXIuY2xhc3MpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXyksCisgICAgICAiZmlsZWNsYXNzIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSwKKyAgICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29tbW9uQnVpbGRlck1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLy8gQ29uc3RydWN0IHVzaW5nICRjbGFzc25hbWUkLm5ld0J1aWxkZXIoKVxuIgorICAgICAgICAicHJpdmF0ZSBCdWlsZGVyKCkge1xuIgorICAgICAgICAiICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7XG4iCisgICAgICAgICJ9XG4iCisgICAgICAgICJcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwcml2YXRlIEJ1aWxkZXIoXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyUGFyZW50IHBhcmVudCkge1xuIgorICAgICAgIiAgc3VwZXIocGFyZW50KTtcbiIKKyAgICAgICIgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBMSVRFIHJ1bnRpbWUgcGFzc2VzIGFsb25nIHRoZSBkZWZhdWx0IGluc3RhbmNlIHRvIGltcGxlbWVudAorICAgIC8vIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSBhdCB0aGUgR2VuZXJhdGVkTWVzc2FnZUxpdGUgbGV2ZWwuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIvLyBDb25zdHJ1Y3QgdXNpbmcgJGNsYXNzbmFtZSQubmV3QnVpbGRlcigpXG4iCisgICAgICAgICJwcml2YXRlIEJ1aWxkZXIoKSB7XG4iCisgICAgICAgICIgIHN1cGVyKGRlZmF1bHRJbnN0YW5jZSk7XG4iCisgICAgICAgICIgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTtcbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfQorCisKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkge1xuIgorICAgICAgIiAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7XG4iKTsKKworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKCFkZXNjcmlwdG9yXy0+ZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgICAgLkdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKHByaW50ZXIpOworICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7XG4iCisgICAgIiAgc3VwZXIuY2xlYXIoKTtcbiIpOworCisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICghZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiRvbmVvZl9uYW1lJENhc2VfID0gMDtcbiIKKyAgICAgICIkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIsCisgICAgICAib25lb2ZfbmFtZSIsIGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yXG4iCisgICAgICAiICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRmaWxlY2xhc3MkLmludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiZmlsZWNsYXNzIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSwKKyAgICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworCisgICAgLy8gTElURSBydW50aW1lIGltcGxlbWVudHMgdGhpcyBpbiBHZW5lcmF0ZWRNZXNzYWdlTGl0ZS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIExJVEUgaW1wbGVtZW50cyBidWlsZCBpbiBHZW5lcmF0ZWRNZXNzYWdlTGl0ZSB0byBzYXZlIG1ldGhvZHMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljICRjbGFzc25hbWUkIGJ1aWxkKCkge1xuIgorICAgICAgIiAgJGNsYXNzbmFtZSQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7XG4iCisgICAgICAiICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICIgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiByZXN1bHQ7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgIH0KKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgYnVpbGRQYXJ0aWFsKCkge1xuIgorICAgICAgICAiICAkY2xhc3NuYW1lJCByZXN1bHQgPSBuZXcgJGNsYXNzbmFtZSQodGhpcyk7XG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworICB9IGVsc2UgeworICAgIC8vIExJVEVfUlVOVElNRSBvbmx5IHByb3ZpZGVzIGEgc2luZ2xlIG1lc3NhZ2UgY29uc3RydWN0b3IuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgYnVpbGRQYXJ0aWFsKCkge1xuIgorICAgICAgICAiICAkY2xhc3NuYW1lJCByZXN1bHQgPSBuZXcgJGNsYXNzbmFtZSQoXG4iCisgICAgICAgICIgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsXG4iCisgICAgICAgICIgICAgICAgICAgLkVNUFRZX0NPREVEX0lOUFVUX1NUUkVBTSxcbiIKKyAgICAgICAgIiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlXG4iCisgICAgICAgICIgICAgICAgICAgLmdldEVtcHR5UmVnaXN0cnkoKSk7XG4iCisgICAgICAgICIgIHJlc3VsdC51bmtub3duRmllbGRzID0gdGhpcy51bmtub3duRmllbGRzO1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKworICAgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgcmVzdWx0LmV4dGVuc2lvbnMgPSB0aGlzLmJ1aWxkRXh0ZW5zaW9ucygpO1xuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaW50IHRvdGFsQnVpbGRlckJpdHMgPSAwOworICBpbnQgdG90YWxNZXNzYWdlQml0cyA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yJiBmaWVsZCA9CisgICAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpOworICAgIHRvdGFsQnVpbGRlckJpdHMgKz0gZmllbGQuR2V0TnVtQml0c0ZvckJ1aWxkZXIoKTsKKyAgICB0b3RhbE1lc3NhZ2VCaXRzICs9IGZpZWxkLkdldE51bUJpdHNGb3JNZXNzYWdlKCk7CisgIH0KKyAgaW50IHRvdGFsQnVpbGRlckludHMgPSAodG90YWxCdWlsZGVyQml0cyArIDMxKSAvIDMyOworICBpbnQgdG90YWxNZXNzYWdlSW50cyA9ICh0b3RhbE1lc3NhZ2VCaXRzICsgMzEpIC8gMzI7CisKKyAgaWYgKEdlbmVyYXRlSGFzQml0cyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBMb2NhbCB2YXJzIGZvciBmcm9tIGFuZCB0byBiaXQgZmllbGRzIHRvIGF2b2lkIGFjY2Vzc2luZyB0aGUgYnVpbGRlciBhbmQKKyAgICAvLyBtZXNzYWdlIG92ZXIgYW5kIG92ZXIgZm9yIHRoZXNlIGZpZWxkcy4gU2VlbXMgdG8gcHJvdmlkZSBhIHNsaWdodAorICAgIC8vIHBlcmZvcmFtYW5jZSBpbXByb3ZlbWVudCBpbiBtaWNybyBiZW5jaG1hcmsgYW5kIHRoaXMgaXMgYWxzbyB3aGF0IHByb3RvMQorICAgIC8vIGNvZGUgZG9lcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsQnVpbGRlckludHM7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoImludCBmcm9tXyRiaXRfZmllbGRfbmFtZSQgPSAkYml0X2ZpZWxkX25hbWUkO1xuIiwKKyAgICAgICAgImJpdF9maWVsZF9uYW1lIiwgR2V0Qml0RmllbGROYW1lKGkpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbE1lc3NhZ2VJbnRzOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJpbnQgdG9fJGJpdF9maWVsZF9uYW1lJCA9IDA7XG4iLAorICAgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICAgIH0KKyAgfQorCisgIC8vIE91dHB1dCBnZW5lcmF0aW9uIGNvZGUgZm9yIGVhY2ggZmllbGQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpLkdlbmVyYXRlQnVpbGRpbmdDb2RlKHByaW50ZXIpOworICB9CisKKyAgaWYgKEdlbmVyYXRlSGFzQml0cyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBDb3B5IHRoZSBiaXQgZmllbGQgcmVzdWx0cyB0byB0aGUgZ2VuZXJhdGVkIG1lc3NhZ2UKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsTWVzc2FnZUludHM7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoInJlc3VsdC4kYml0X2ZpZWxkX25hbWUkID0gdG9fJGJpdF9maWVsZF9uYW1lJDtcbiIsCisgICAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgicmVzdWx0LiRvbmVvZl9uYW1lJENhc2VfID0gJG9uZW9mX25hbWUkQ2FzZV87XG4iLAorICAgICAgICAgICAgICAgICAgICJvbmVvZl9uYW1lIiwgY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgb25CdWlsdCgpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gcmVzdWx0O1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaWYgKEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTWVyZ2VGcm9tKE1lc3NhZ2Ugb3RoZXIpIHJlcXVpcmVzIHRoZSBhYmlsaXR5IHRvIGRpc3Rpbmd1aXNoIHRoZSBvdGhlcgorICAgIC8vIG1lc3NhZ2VzIHR5cGUgYnkgaXRzIGRlc2NyaXB0b3IuCisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7XG4iCisgICAgICAgICIgIGlmIChvdGhlciBpbnN0YW5jZW9mICRjbGFzc25hbWUkKSB7XG4iCisgICAgICAgICIgICAgcmV0dXJuIG1lcmdlRnJvbSgoJGNsYXNzbmFtZSQpb3RoZXIpO1xuIgorICAgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgICAiICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7XG4iCisgICAgICAgICIgICAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oJGNsYXNzbmFtZSQgb3RoZXIpIHtcbiIKKyAgICAgIC8vIE9wdGltaXphdGlvbjogIElmIG90aGVyIGlzIHRoZSBkZWZhdWx0IGluc3RhbmNlLCB3ZSBrbm93IG5vbmUgb2YgaXRzCisgICAgICAvLyAgIGZpZWxkcyBhcmUgc2V0IHNvIHdlIGNhbiBza2lwIHRoZSBtZXJnZS4KKyAgICAgICIgIGlmIChvdGhlciA9PSAkY2xhc3NuYW1lJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKCFkZXNjcmlwdG9yXy0+ZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoCisgICAgICAgICAgICBkZXNjcmlwdG9yXy0+ZmllbGQoaSkpLkdlbmVyYXRlTWVyZ2luZ0NvZGUocHJpbnRlcik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gTWVyZ2Ugb25lb2YgZmllbGRzLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgKytpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInN3aXRjaCAob3RoZXIuZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpKSB7XG4iLAorICAgICAgICAib25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSIsCisgICAgICAgIGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPmNhcGl0YWxpemVkX25hbWUpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNhc2UgJGZpZWxkX25hbWUkOiB7XG4iLAorICAgICAgICAgICJmaWVsZF9uYW1lIiwKKyAgICAgICAgICBUb1VwcGVyKGZpZWxkLT5uYW1lKCkpKTsKKyAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVNZXJnaW5nQ29kZShwcmludGVyKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiYnJlYWs7XG4iKTsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICJ9XG4iKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ6IHtcbiIKKyAgICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAiY2FwX29uZW9mX25hbWUiLAorICAgICAgICBUb1VwcGVyKGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPm5hbWUpKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgICAvLyBpZiBtZXNzYWdlIHR5cGUgaGFzIGV4dGVuc2lvbnMKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpO1xuIik7CisgICAgfQorCisgICAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci51bmtub3duRmllbGRzKTtcbiIpOworICAgIH0KKworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCIgIG9uQ2hhbmdlZCgpO1xuIik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJQYXJzaW5nTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTElURV9SVU5USU1FIGltcGxlbWVudHMgdGhpcyBhdCB0aGUgR2VuZXJhdGVkTWVzc2FnZUxpdGUgbGV2ZWwuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgICAiICAkY2xhc3NuYW1lJCBwYXJzZWRNZXNzYWdlID0gbnVsbDtcbiIKKyAgICAgICIgIHRyeSB7XG4iCisgICAgICAiICAgIHBhcnNlZE1lc3NhZ2UgPSBQQVJTRVIucGFyc2VQYXJ0aWFsRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICAgIiAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkge1xuIgorICAgICAgIiAgICBwYXJzZWRNZXNzYWdlID0gKCRjbGFzc25hbWUkKSBlLmdldFVuZmluaXNoZWRNZXNzYWdlKCk7XG4iCisgICAgICAiICAgIHRocm93IGU7XG4iCisgICAgICAiICB9IGZpbmFsbHkge1xuIgorICAgICAgIiAgICBpZiAocGFyc2VkTWVzc2FnZSAhPSBudWxsKSB7XG4iCisgICAgICAiICAgICAgbWVyZ2VGcm9tKHBhcnNlZE1lc3NhZ2UpO1xuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVJc0luaXRpYWxpemVkKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBVc2VNZW1vaXphdGlvbiB1c2VNZW1vaXphdGlvbikgeworICAvLyBMSVRFX1JVTlRJTUUgYXZvaWRzIGdlbmVyYXRpbmcgaXNJbml0aWFsaXplZCBpZiBpdCdzIG5vdCBuZWVkZWQuCisgIGlmICghSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pCisgICAgICAmJiAhSGFzUmVxdWlyZWRGaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgYm9vbCBtZW1vaXphdGlvbiA9IHVzZU1lbW9pemF0aW9uID09IE1FTU9JWkU7CisgIGlmIChtZW1vaXphdGlvbikgeworICAgIC8vIE1lbW9pemVzIHdoZXRoZXIgdGhlIHByb3RvY29sIGJ1ZmZlciBpcyBmdWxseSBpbml0aWFsaXplZCAoaGFzIGFsbAorICAgIC8vIHJlcXVpcmVkIGZpZWxkcykuIC0xIG1lYW5zIG5vdCB5ZXQgY29tcHV0ZWQuIDAgbWVhbnMgZmFsc2UgYW5kIDEgbWVhbnMKKyAgICAvLyB0cnVlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGlmIChtZW1vaXphdGlvbikgeworICAgIC8vIERvbid0IGRpcmVjdGx5IGNvbXBhcmUgdG8gLTEgdG8gYXZvaWQgYW4gQW5kcm9pZCB4ODYgSklUIGJ1Zy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7XG4iCisgICAgICAiaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7XG4iCisgICAgICAiaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIlxuIik7CisgIH0KKworICAvLyBDaGVjayB0aGF0IGFsbCByZXF1aXJlZCBmaWVsZHMgaW4gdGhpcyBtZXNzYWdlIGFyZSBzZXQuCisgIC8vIFRPRE8oa2VudG9uKTogIFdlIGNhbiBvcHRpbWl6ZSB0aGlzIHdoZW4gd2Ugc3dpdGNoIHRvIHB1dHRpbmcgYWxsIHRoZQorICAvLyAgICJoYXMiIGZpZWxkcyBpbnRvIGEgc2luZ2xlIGJpdGZpZWxkLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZmllbGQpOworCisgICAgaWYgKGZpZWxkLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlmICghaGFzJG5hbWUkKCkpIHtcbiIKKyAgICAgICAgIiAgJG1lbW9pemUkXG4iCisgICAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSwKKyAgICAgICAgIm1lbW9pemUiLCBtZW1vaXphdGlvbiA/ICJtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOyIgOiAiIik7CisgICAgfQorICB9CisKKyAgLy8gTm93IGNoZWNrIHRoYXQgYWxsIGVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBpbml0aWFsaXplZC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICBpZiAoR2V0SmF2YVR5cGUoZmllbGQpID09IEpBVkFUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgSGFzUmVxdWlyZWRGaWVsZHMoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgc3dpdGNoIChmaWVsZC0+bGFiZWwoKSkgeworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVRVUlSRUQ6CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiaWYgKCFnZXQkbmFtZSQoKS5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICAgICAgICAiICAkbWVtb2l6ZSRcbiIKKyAgICAgICAgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAidHlwZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgICAgICAgICAgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSwKKyAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSwKKyAgICAgICAgICAgICJtZW1vaXplIiwgbWVtb2l6YXRpb24gPyAibWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsiIDogIiIpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUw6CisgICAgICAgICAgaWYgKCFTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSAmJgorICAgICAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YgPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpOworICAgICAgICAgICAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBvbmVvZl9pbmZvID0KKyAgICAgICAgICAgICAgICBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKG9uZW9mKTsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiaWYgKCRvbmVvZl9uYW1lJENhc2VfID09ICRmaWVsZF9udW1iZXIkKSB7XG4iLAorICAgICAgICAgICAgICAib25lb2ZfbmFtZSIsIG9uZW9mX2luZm8tPm5hbWUsCisgICAgICAgICAgICAgICJmaWVsZF9udW1iZXIiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImlmIChoYXMkbmFtZSQoKSkge1xuIiwKKyAgICAgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiICBpZiAoIWdldCRuYW1lJCgpLmlzSW5pdGlhbGl6ZWQoKSkge1xuIgorICAgICAgICAgICAgIiAgICAkbWVtb2l6ZSRcbiIKKyAgICAgICAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUsCisgICAgICAgICAgICAibWVtb2l6ZSIsIG1lbW9pemF0aW9uID8gIm1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7IiA6ICIiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEOgorICAgICAgICAgIGlmIChJc01hcEVudHJ5KGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiZm9yICgkdHlwZSQgaXRlbSA6IGdldCRuYW1lJCgpLnZhbHVlcygpKSB7XG4iCisgICAgICAgICAgICAgICIgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICAgICAgICAgIiAgICAkbWVtb2l6ZSRcbiIKKyAgICAgICAgICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAgICIgIH1cbiIKKyAgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAgICJ0eXBlIiwgTWFwVmFsdWVJbW11dGFibGVDbGFzc2ROYW1lKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8pLAorICAgICAgICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUsCisgICAgICAgICAgICAgICJtZW1vaXplIiwgbWVtb2l6YXRpb24gPyAibWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsiIDogIiIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgZ2V0JG5hbWUkQ291bnQoKTsgaSsrKSB7XG4iCisgICAgICAgICAgICAgICIgIGlmICghZ2V0JG5hbWUkKGkpLmlzSW5pdGlhbGl6ZWQoKSkge1xuIgorICAgICAgICAgICAgICAiICAgICRtZW1vaXplJFxuIgorICAgICAgICAgICAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICAgInR5cGUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICAgICAgICAgICAgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSwKKyAgICAgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lLAorICAgICAgICAgICAgICAibWVtb2l6ZSIsIG1lbW9pemF0aW9uID8gIm1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7IiA6ICIiKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAiICAkbWVtb2l6ZSRcbiIKKyAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgIm1lbW9pemUiLCBtZW1vaXphdGlvbiA/ICJtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOyIgOiAiIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgaWYgKG1lbW9pemF0aW9uKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gdHJ1ZTtcbiIKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK25hbWVzcGFjZSB7Citib29sIENoZWNrSGFzQml0c0ZvckVxdWFsc0FuZEhhc2hDb2RlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShmaWVsZC0+ZmlsZSgpKSkgeworICAgIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBHZXRKYXZhVHlwZShmaWVsZCkgPT0gSkFWQVRZUEVfTUVTU0FHRSAmJgorICAgICAgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMOworfQorfSAgLy8gbmFtZXNwYWNlCisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0FuZEhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJAamF2YS5sYW5nLk92ZXJyaWRlXG4iCisgICAgInB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiaWYgKG9iaiA9PSB0aGlzKSB7XG4iCisgICAgIiByZXR1cm4gdHJ1ZTtcbiIKKyAgICAifVxuIgorICAgICJpZiAoIShvYmogaW5zdGFuY2VvZiAkY2xhc3NuYW1lJCkpIHtcbiIKKyAgICAiICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7XG4iCisgICAgIn1cbiIKKyAgICAiJGNsYXNzbmFtZSQgb3RoZXIgPSAoJGNsYXNzbmFtZSQpIG9iajtcbiIKKyAgICAiXG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoImJvb2xlYW4gcmVzdWx0ID0gdHJ1ZTtcbiIpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZmllbGQpOworICAgIGJvb2wgY2hlY2tfaGFzX2JpdHMgPSBDaGVja0hhc0JpdHNGb3JFcXVhbHNBbmRIYXNoQ29kZShmaWVsZCk7CisgICAgaWYgKGNoZWNrX2hhc19iaXRzKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiAoaGFzJG5hbWUkKCkgPT0gb3RoZXIuaGFzJG5hbWUkKCkpO1xuIgorICAgICAgICAiaWYgKGhhcyRuYW1lJCgpKSB7XG4iLAorICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgfQorICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVFcXVhbHNDb2RlKHByaW50ZXIpOworICAgIGlmIChjaGVja19oYXNfYml0cykgeworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9XG4iKTsKKyAgICB9CisgIH0KKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBBbHdheXMgY29uc2lkZXIgdW5rbm93biBmaWVsZHMgZm9yIGVxdWFsaXR5LiBUaGlzIHdpbGwgc29tZXRpbWVzIHJldHVybgorICAgIC8vIGZhbHNlIGZvciBub24tY2Fub25pY2FsIG9yZGVyaW5nIHdoZW4gcnVubmluZyBpbiBMSVRFX1JVTlRJTUUgYnV0IGl0J3MKKyAgICAvLyB0aGUgYmVzdCB3ZSBjYW4gZG8uCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicmVzdWx0ID0gcmVzdWx0ICYmIHVua25vd25GaWVsZHMuZXF1YWxzKG90aGVyLnVua25vd25GaWVsZHMpO1xuIik7CisgIH0KKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJlxuIgorICAgICAgICAiICAgIGdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSk7XG4iKTsKKyAgICB9CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInJldHVybiByZXN1bHQ7XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJAamF2YS5sYW5nLk92ZXJyaWRlXG4iCisgICAgInB1YmxpYyBpbnQgaGFzaENvZGUoKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJyZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTtcbiIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgImludCBoYXNoID0gNDE7XG4iKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoImhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3JGb3JUeXBlKCkuaGFzaENvZGUoKTtcbiIpOworICB9IGVsc2UgeworICAgIC8vIEluY2x1ZGUgdGhlIGhhc2ggb2YgdGhlIGNsYXNzIHNvIHRoYXQgdHdvIG9iamVjdHMgd2l0aCBkaWZmZXJlbnQgdHlwZXMKKyAgICAvLyBidXQgdGhlIHNhbWUgZmllbGQgdmFsdWVzIHdpbGwgcHJvYmFibHkgaGF2ZSBkaWZmZXJlbnQgaGFzaGVzLgorICAgIHByaW50ZXItPlByaW50KCJoYXNoID0gKDE5ICogaGFzaCkgKyAkY2xhc3NuYW1lJC5jbGFzcy5oYXNoQ29kZSgpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZmllbGQpOworICAgIGJvb2wgY2hlY2tfaGFzX2JpdHMgPSBDaGVja0hhc0JpdHNGb3JFcXVhbHNBbmRIYXNoQ29kZShmaWVsZCk7CisgICAgaWYgKGNoZWNrX2hhc19iaXRzKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlmIChoYXMkbmFtZSQoKSkge1xuIiwKKyAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgIH0KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlSGFzaENvZGUocHJpbnRlcik7CisgICAgaWYgKGNoZWNrX2hhc19iaXRzKSB7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgfQorICB9CisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7XG4iKTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiaGFzaCA9ICgyOSAqIGhhc2gpICsgdW5rbm93bkZpZWxkcy5oYXNoQ29kZSgpO1xuIik7CisgIHByaW50ZXItPlByaW50KAorICAgICJtZW1vaXplZEhhc2hDb2RlID0gaGFzaDtcbiIKKyAgICAicmV0dXJuIGhhc2g7XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUV4dGVuc2lvblJlZ2lzdHJhdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIEltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcihkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uKGkpLCBjb250ZXh0XykKKyAgICAgIC5HZW5lcmF0ZVJlZ2lzdHJhdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgY29udGV4dF8pCisgICAgICAuR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb25zdHJ1Y3Rvcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Y29uc3QgRmllbGREZXNjcmlwdG9yICogPiBzb3J0ZWRfZmllbGRzKAorICAgICAgU29ydEZpZWxkc0J5TnVtYmVyKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZSAkY2xhc3NuYW1lJChcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gSW5pdGlhbGl6ZSBhbGwgZmllbGRzIHRvIGRlZmF1bHQuCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInRoaXMoKTtcbiIpOworICB9IGVsc2UgeworICAgIC8vIExJVEVfUlVOVElNRSBvbmx5IGhhcyBvbmUgY29uc3RydWN0b3IuCisgICAgR2VuZXJhdGVJbml0aWFsaXplcnMocHJpbnRlcik7CisgIH0KKworICAvLyBVc2UgYnVpbGRlciBiaXRzIHRvIHRyYWNrIG11dGFibGUgcmVwZWF0ZWQgZmllbGRzLgorICBpbnQgdG90YWxCdWlsZGVyQml0cyA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yJiBmaWVsZCA9CisgICAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpOworICAgIHRvdGFsQnVpbGRlckJpdHMgKz0gZmllbGQuR2V0TnVtQml0c0ZvckJ1aWxkZXIoKTsKKyAgfQorICBpbnQgdG90YWxCdWlsZGVySW50cyA9ICh0b3RhbEJ1aWxkZXJCaXRzICsgMzEpIC8gMzI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdG90YWxCdWlsZGVySW50czsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoImludCBtdXRhYmxlXyRiaXRfZmllbGRfbmFtZSQgPSAwO1xuIiwKKyAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQuQnVpbGRlciB1bmtub3duRmllbGRzID1cbiIKKyAgICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldC5uZXdCdWlsZGVyKCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldExpdGUuQnVpbGRlciB1bmtub3duRmllbGRzID1cbiIKKyAgICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldExpdGUubmV3QnVpbGRlcigpO1xuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidHJ5IHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiYm9vbGVhbiBkb25lID0gZmFsc2U7XG4iCisgICAgIndoaWxlICghZG9uZSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpO1xuIgorICAgICJzd2l0Y2ggKHRhZykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJjYXNlIDA6XG4iICAgICAgICAgIC8vIHplcm8gc2lnbmFscyBFT0YgLyBsaW1pdCByZWFjaGVkCisgICAgIiAgZG9uZSA9IHRydWU7XG4iCisgICAgIiAgYnJlYWs7XG4iKTsKKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmICghSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pCisgICAgICAgICYmIGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICAgIC8vIExpdGUgcnVudGltZSBkaXJlY3RseSBpbnZva2VzIHBhcnNlVW5rbm93bkZpZWxkIHRvIHJlZHVjZSBtZXRob2QKKyAgICAgIC8vIGNvdW50cy4KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZGVmYXVsdDoge1xuIgorICAgICAgICAiICBpZiAoIXBhcnNlVW5rbm93bkZpZWxkKGV4dGVuc2lvbnMsIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSxcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dCwgdW5rbm93bkZpZWxkcyxcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkge1xuIgorICAgICAgICAiICAgIGRvbmUgPSB0cnVlO1xuIiAgLy8gaXQncyBhbiBlbmRncm91cCB0YWcKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImRlZmF1bHQ6IHtcbiIKKyAgICAgICAgIiAgaWYgKCFwYXJzZVVua25vd25GaWVsZChpbnB1dCwgdW5rbm93bkZpZWxkcyxcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkge1xuIgorICAgICAgICAiICAgIGRvbmUgPSB0cnVlO1xuIiAgLy8gaXQncyBhbiBlbmRncm91cCB0YWcKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJkZWZhdWx0OiB7XG4iCisgICAgICAiICBpZiAoIWlucHV0LnNraXBGaWVsZCh0YWcpKSB7XG4iCisgICAgICAiICAgIGRvbmUgPSB0cnVlO1xuIiAgLy8gaXQncyBhbiBlbmRncm91cCB0YWcKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIGJyZWFrO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IHNvcnRlZF9maWVsZHNbaV07CisgICAgdWludDMyIHRhZyA9IFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwKKyAgICAgIFdpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGRUeXBlKGZpZWxkLT50eXBlKCkpKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNhc2UgJHRhZyQ6IHtcbiIsCisgICAgICAidGFnIiwgU2ltcGxlSXRvYSh0YWcpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVQYXJzaW5nQ29kZShwcmludGVyKTsKKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIGJyZWFrO1xuIgorICAgICAgIn1cbiIpOworCisgICAgaWYgKGZpZWxkLT5pc19wYWNrYWJsZSgpKSB7CisgICAgICAvLyBUbyBtYWtlIHBhY2tlZCA9IHRydWUgd2lyZSBjb21wYXRpYmxlLCB3ZSBnZW5lcmF0ZSBwYXJzaW5nIGNvZGUgZnJvbSBhCisgICAgICAvLyBwYWNrZWQgdmVyc2lvbiBvZiB0aGlzIGZpZWxkIHJlZ2FyZGxlc3Mgb2YgZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKS4KKyAgICAgIHVpbnQzMiBwYWNrZWRfdGFnID0gV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQtPm51bWJlcigpLAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImNhc2UgJHRhZyQ6IHtcbiIsCisgICAgICAgICJ0YWciLCBTaW1wbGVJdG9hKHBhY2tlZF90YWcpKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKHByaW50ZXIpOworCisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICB9XG4iICAgICAvLyBzd2l0Y2ggKHRhZykKKyAgICAgICJ9XG4iKTsgICAgIC8vIHdoaWxlICghZG9uZSkKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIn0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAgICIgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UodGhpcykpO1xuIgorICAgICAgIn0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkge1xuIgorICAgICAgIiAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oXG4iCisgICAgICAiICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKFxuIgorICAgICAgIiAgICAgICAgICBlLmdldE1lc3NhZ2UoKSkuc2V0VW5maW5pc2hlZE1lc3NhZ2UodGhpcykpO1xuIgorICAgICAgIn0gZmluYWxseSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gTWFrZSByZXBlYXRlZCBmaWVsZCBsaXN0IGltbXV0YWJsZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IHNvcnRlZF9maWVsZHNbaV07CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShwcmludGVyKTsKKyAgfQorCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTWFrZSB1bmtub3duIGZpZWxkcyBpbW11dGFibGUuCisgICAgcHJpbnRlci0+UHJpbnQoInRoaXMudW5rbm93bkZpZWxkcyA9IHVua25vd25GaWVsZHMuYnVpbGQoKTtcbiIpOworICB9CisKKyAgaWYgKCFIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBMSVRFIHJ1bnRpbWUgdXNlcyBhIHN0YXRpYyBtZXRob2QgdG8gcmVkdWNlIG1ldGhvZCBjb3VudC4KKyAgICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgICAgLy8gTWFrZSBleHRlbnNpb25zIGltbXV0YWJsZS4KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJtYWtlRXh0ZW5zaW9uc0ltbXV0YWJsZShleHRlbnNpb25zKTtcbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBNYWtlIGV4dGVuc2lvbnMgaW1tdXRhYmxlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAibWFrZUV4dGVuc2lvbnNJbW11dGFibGUoKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgfVxuIiAgICAgLy8gZmluYWxseQorICAgICAgIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2VyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8JGNsYXNzbmFtZSQ+IFBBUlNFUiA9XG4iCisgICAgICAiICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPCRjbGFzc25hbWUkPigpIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgcGFyc2VQYXJ0aWFsRnJvbShcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSlcbiIKKyAgICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIFRoZSBwYXJzaW5nIGNvbnN0cnVjdG9yIHRocm93cyBhbiBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gdmlhIGEKKyAgICAvLyBSdW50aW1lRXhjZXB0aW9uIHRvIGFpZCBpbiBtZXRob2QgcHJ1bmluZy4gV2UgdW53cmFwIGl0IGhlcmUuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIHRyeSB7XG4iCisgICAgICAgICIgICAgcmV0dXJuIG5ldyAkY2xhc3NuYW1lJChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICAgICAiICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAgICAgIiAgICBpZiAoZS5nZXRDYXVzZSgpIGluc3RhbmNlb2ZcbiIKKyAgICAgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24pIHtcbiIKKyAgICAgICAgIiAgICAgIHRocm93IChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbilcbiIKKyAgICAgICAgIiAgICAgICAgICBlLmdldENhdXNlKCk7XG4iCisgICAgICAgICIgICAgfVxuIgorICAgICAgICAiICAgIHRocm93IGU7XG4iCisgICAgICAgICIgIH1cbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBXaGVuIHBhcnNpbmcgY29uc3RydWN0b3IgaXNuJ3QgZ2VuZXJhdGVkLCB1c2UgYnVpbGRlciB0byBwYXJzZSBtZXNzYWdlcy4KKyAgICAvLyBOb3RlLCB3aWxsIGZhbGxiYWNrIHRvIHVzZSByZWZsZWN0aW9uIGJhc2VkIG1lcmdlRmllbGRGcm9tKCkgaW4KKyAgICAvLyBBYnN0cmFjdE1lc3NhZ2UuQnVpbGRlci4KKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIkJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTtcbiIKKyAgICAgICAgInRyeSB7XG4iCisgICAgICAgICIgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgICAgICJ9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7XG4iCisgICAgICAgICIgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7XG4iCisgICAgICAgICJ9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAgICAgIiAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKFxuIgorICAgICAgICAiICAgICAgZS5nZXRNZXNzYWdlKCkpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpO1xuIgorICAgICAgICAifVxuIgorICAgICAgICAicmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7XG4iKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9O1xuIgorICAgICAgIlxuIik7CisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIExJVEVfUlVOVElNRSBpbXBsZW1lbnRzIHRoaXMgYXQgdGhlIEdlbmVyYXRlZE1lc3NhZ2VMaXRlIGxldmVsLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICAgICAicHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPCRjbGFzc25hbWUkPiBnZXRQYXJzZXJGb3JUeXBlKCkge1xuIgorICAgICAgICAiICByZXR1cm4gUEFSU0VSO1xuIgorICAgICAgICAifVxuIgorICAgICAgICAiXG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZUluaXRpYWxpemVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KK30KKworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTZmZGQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZS5oCkBAIC0wLDAgKzEsMTQxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBjb21waWxlciB7CisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ29udGV4dDsgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7IC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBNZXNzYWdlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgIHZpcnR1YWwgfk1lc3NhZ2VHZW5lcmF0b3IoKTsKKworICAvLyBBbGwgc3RhdGljIHZhcmlhYmxlcyBoYXZlIHRvIGJlIGRlY2xhcmVkIGF0IHRoZSB0b3AtbGV2ZWwgb2YgdGhlIGZpbGUKKyAgLy8gc28gdGhhdCB3ZSBjYW4gY29udHJvbCBpbml0aWFsaXphdGlvbiBvcmRlciwgd2hpY2ggaXMgaW1wb3J0YW50IGZvcgorICAvLyBEZXNjcmlwdG9yUHJvdG8gYm9vdHN0cmFwcGluZyB0byB3b3JrLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBPdXRwdXQgY29kZSB3aGljaCBpbml0aWFsaXplcyB0aGUgc3RhdGljIHZhcmlhYmxlcyBnZW5lcmF0ZWQgYnkKKyAgLy8gR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoKS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBHZW5lcmF0ZSB0aGUgY2xhc3MgaXRzZWxmLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBHZW5lcmF0ZXMgdGhlIGJhc2UgaW50ZXJmYWNlIHRoYXQgYm90aCB0aGUgY2xhc3MgYW5kIGl0cyBidWlsZGVyIGltcGxlbWVudAorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2UoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBHZW5lcmF0ZSBjb2RlIHRvIHJlZ2lzdGVyIGFsbCBjb250YWluZWQgZXh0ZW5zaW9ucyB3aXRoIGFuCisgIC8vIEV4dGVuc2lvblJlZ2lzdHJ5LgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSA9IDA7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvciA6IHB1YmxpYyBNZXNzYWdlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KTsKKyAgdmlydHVhbCB+SW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUludGVyZmFjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUV4dGVuc2lvblJlZ2lzdHJhdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBlbnVtIFVzZU1lbW9pemF0aW9uIHsKKyAgICBNRU1PSVpFLAorICAgIERPTlRfTUVNT0laRQorICB9OworCisgIHZvaWQgR2VuZXJhdGVGaWVsZEFjY2Vzc29yVGFibGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRmllbGRBY2Nlc3NvclRhYmxlSW5pdGlhbGl6ZXIoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlUGFyc2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVPbmVGaWVsZChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UoCisgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlKTsKKworICB2b2lkIEdlbmVyYXRlQnVpbGRlcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVDb21tb25CdWlsZGVyTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9yTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBpc19idWlsZGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJQYXJzaW5nTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVJc0luaXRpYWxpemVkKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgVXNlTWVtb2l6YXRpb24gdXNlTWVtb2l6YXRpb24pOworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6ZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0FuZEhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNlcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29uc3RydWN0b3IoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisgIEZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPiBmaWVsZF9nZW5lcmF0b3JzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTJkMTJhMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuY2MKQEAgLTAsMCArMSwxMzIwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCB2YXJpYWJsZXMpOworCisgICgqdmFyaWFibGVzKVsidHlwZSJdID0KKyAgICAgIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsibXV0YWJsZV90eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0TXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsiZ3JvdXBfb3JfbWVzc2FnZSJdID0KKyAgICAoR2V0VHlwZShkZXNjcmlwdG9yKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApID8KKyAgICAiR3JvdXAiIDogIk1lc3NhZ2UiOworICAvLyBUT0RPKGJpcmRvKTogQWRkIEBkZXByZWNhdGVkIGphdmFkb2Mgd2hlbiBnZW5lcmF0aW5nIGphdmFkb2MgaXMgc3VwcG9ydGVkCisgIC8vIGJ5IHRoZSBwcm90byBjb21waWxlcgorICAoKnZhcmlhYmxlcylbImRlcHJlY2F0aW9uIl0gPSBkZXNjcmlwdG9yLT5vcHRpb25zKCkuZGVwcmVjYXRlZCgpCisgICAgICA/ICJAamF2YS5sYW5nLkRlcHJlY2F0ZWQgIiA6ICIiOworICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhlc2UgaGF2ZSBhIHRyYWlsaW5nICI7Ii4KKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KG1lc3NhZ2VCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpICsgIjsiOworICAgICgqdmFyaWFibGVzKVsiY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9ICIiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9CisgICAgICAgICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8gIT0gbnVsbCI7CisgIH0KKworICAvLyBGb3IgcmVwYXRlZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlU2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsiY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVDbGVhckJpdChidWlsZGVyQml0SW5kZXgpOworCisgIC8vIEZvciByZXBlYXRlZCBmaWVsZHMsIG9uZSBiaXQgaXMgdXNlZCBmb3Igd2hldGhlciB0aGUgYXJyYXkgaXMgaW1tdXRhYmxlCisgIC8vIGluIHRoZSBwYXJzaW5nIGNvbnN0cnVjdG9yLgorICAoKnZhcmlhYmxlcylbImdldF9tdXRhYmxlX2JpdF9wYXJzZXIiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdE11dGFibGVMb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9tdXRhYmxlX2JpdF9wYXJzZXIiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdE11dGFibGVMb2NhbChidWlsZGVyQml0SW5kZXgpOworCisgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfZnJvbV9sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfdG9fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdFRvTG9jYWwobWVzc2FnZUJpdEluZGV4KTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgICAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKworaW50IEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVE9ETyhqb25wKTogSW4gdGhlIGZ1dHVyZSwgY29uc2lkZXIgaGF2aW5nIGEgbWV0aG9kIHNwZWNpZmljIHRvIHRoZQorICAvLyBpbnRlcmZhY2Ugc28gdGhhdCBidWlsZGVycyBjYW4gY2hvb3NlIGR5bmFtaWNhbGx5IHRvIGVpdGhlciByZXR1cm4gYQorICAvLyBtZXNzYWdlIG9yIGEgbmVzdGVkIGJ1aWxkZXIsIHNvIHRoYXQgYXNraW5nIGZvciB0aGUgaW50ZXJmYWNlIGRvZXNuJ3QKKyAgLy8gY2F1c2UgYSBtZXNzYWdlIHRvIGV2ZXIgYmUgYnVpbHQuCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSB8fAorICAgICAgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiQkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKCk7XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSAkdHlwZSQgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfID09IG51bGwgPyAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworCisgICAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciAiCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgICAgICIgIHJldHVybiAkbmFtZSRfID09IG51bGwgPyAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiAkbmFtZSRfO1xuIgorICAgICAgICAifVxuIik7CisgICAgfQorICB9IGVsc2UgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXyAhPSBudWxsO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfID09IG51bGwgPyAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworCisgICAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciAiCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IGNoYXIqIHJlZ3VsYXJfY2FzZSwKKyAgICBjb25zdCBjaGFyKiBuZXN0ZWRfYnVpbGRlcl9jYXNlKSBjb25zdCB7CisgIGlmIChIYXNOZXN0ZWRCdWlsZGVycyhkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICJpZiAoJG5hbWUkQnVpbGRlcl8gPT0gbnVsbCkge1xuIik7CisgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCByZWd1bGFyX2Nhc2UpOworICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgIHByaW50ZXItPlByaW50KCJ9IGVsc2Uge1xuIik7CisgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCBuZXN0ZWRfYnVpbGRlcl9jYXNlKTsKKyAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICB9IGVsc2UgeworICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCByZWd1bGFyX2Nhc2UpOworICAgfQorfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgY2hhciogbWV0aG9kX3Byb3RvdHlwZSwKKyAgICBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsCisgICAgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSwKKyAgICBjb25zdCBjaGFyKiB0cmFpbGluZ19jb2RlKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIG1ldGhvZF9wcm90b3R5cGUpOworICBwcmludGVyLT5QcmludCgiIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsIHJlZ3VsYXJfY2FzZSwgbmVzdGVkX2J1aWxkZXJfY2FzZSk7CisgIGlmICh0cmFpbGluZ19jb2RlICE9IE5VTEwpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCB0cmFpbGluZ19jb2RlKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBXaGVuIHVzaW5nIG5lc3RlZC1idWlsZGVycywgdGhlIGNvZGUgaW5pdGlhbGx5IHdvcmtzIGp1c3QgbGlrZSB0aGUKKyAgLy8gbm9uLW5lc3RlZCBidWlsZGVyIGNhc2UuIEl0IG9ubHkgY3JlYXRlcyBhIG5lc3RlZCBidWlsZGVyIGxhemlseSBvbgorICAvLyBkZW1hbmQgYW5kIHRoZW4gZm9yZXZlciBkZWxlZ2F0ZXMgdG8gaXQgYWZ0ZXIgY3JlYXRpb24uCisKKyAgYm9vbCBzdXBwb3J0X2ZpZWxkX3ByZXNlbmNlID0gU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSAkdHlwZSQgJG5hbWUkXyA9IG51bGw7XG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAvLyBJZiB0aGlzIGJ1aWxkZXIgaXMgbm9uLW51bGwsIGl0IGlzIHVzZWQgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlCisgICAgICAvLyBpZ25vcmVkLgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gJG5hbWUkQnVpbGRlcl87IgorICAgICAgIlxuIik7CisgIH0KKworICAvLyBUaGUgY29tbWVudHMgYWJvdmUgdGhlIG1ldGhvZHMgYmVsb3cgYXJlIGJhc2VkIG9uIGEgaHlwb3RoZXRpY2FsCisgIC8vIGZpZWxkIG9mIHR5cGUgIkZpZWxkIiBjYWxsZWQgIkZpZWxkIi4KKworICAvLyBib29sZWFuIGhhc0ZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBpZiAoc3VwcG9ydF9maWVsZF9wcmVzZW5jZSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQ7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfICE9IG51bGwgfHwgJG5hbWUkXyAhPSBudWxsO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gRmllbGQgZ2V0RmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKyAgICAicmV0dXJuICRuYW1lJF8gPT0gbnVsbCA/ICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6ICRuYW1lJF87XG4iLAorICAgICJyZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpO1xuIiwKKyAgICBOVUxMKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSIsCisKKyAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAifVxuIgorICAgICIkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTtcbiIsCisKKyAgICAiJHNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSIsCisKKyAgICAiJG5hbWUkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSIsCisKKyAgICBzdXBwb3J0X2ZpZWxkX3ByZXNlbmNlCisgICAgICAgID8gImlmICgkZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQgJiZcbiIKKyAgICAgICAgICAiICAgICRuYW1lJF8gIT0gbnVsbCAmJlxuIgorICAgICAgICAgICIgICAgJG5hbWUkXyAhPSAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHtcbiIKKyAgICAgICAgICAiICAkbmFtZSRfID1cbiIKKyAgICAgICAgICAiICAgICR0eXBlJC5uZXdCdWlsZGVyKCRuYW1lJF8pLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7XG4iCisgICAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICAgIiAgJG5hbWUkXyA9IHZhbHVlO1xuIgorICAgICAgICAgICJ9XG4iCisgICAgICAgICAgIiRvbl9jaGFuZ2VkJFxuIgorICAgICAgICA6ICJpZiAoJG5hbWUkXyAhPSBudWxsKSB7XG4iCisgICAgICAgICAgIiAgJG5hbWUkXyA9XG4iCisgICAgICAgICAgIiAgICAkdHlwZSQubmV3QnVpbGRlcigkbmFtZSRfKS5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAgICAgICAifVxuIgorICAgICAgICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTtcbiIsCisKKyAgICAiJHNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBjbGVhckZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSIsCisKKyAgICAiJG5hbWUkXyA9IG51bGw7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgIHN1cHBvcnRfZmllbGRfcHJlc2VuY2UKKyAgICAgICAgPyAiJG5hbWUkQnVpbGRlcl8uY2xlYXIoKTtcbiIKKyAgICAgICAgOiAiJG5hbWUkXyA9IG51bGw7XG4iCisgICAgICAgICAgIiRuYW1lJEJ1aWxkZXJfID0gbnVsbDtcbiIsCisKKyAgICAiJGNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcigpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcigpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyAhPSBudWxsKSB7XG4iCisgICAgICAiICAgIHJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gJG5hbWUkXyA9PSBudWxsID9cbiIKKyAgICAgICIgICAgICAgICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6ICRuYW1lJF87XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlcjxcbiIKKyAgICAgICIgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPiBcbiIKKyAgICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgICAiICAgICAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+KFxuIgorICAgICAgIiAgICAgICAgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpLFxuIgorICAgICAgIiAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksXG4iCisgICAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IG51bGw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCk7XG4iKTsKKyAgfQorfQorCisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7fQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgICAiJG5hbWUkXyA9IG51bGw7XG4iLAorCisgICAgICAiJG5hbWUkQnVpbGRlcl8uY2xlYXIoKTtcbiIpOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIik7CisgIH0gZWxzZSB7CisgICAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgICAiJG5hbWUkXyA9IG51bGw7XG4iLAorCisgICAgICAiJG5hbWUkXyA9IG51bGw7XG4iCisgICAgICAiJG5hbWUkQnVpbGRlcl8gPSBudWxsO1xuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAob3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAiICBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJChvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfdG9fbG9jYWwkO1xuIgorICAgICAgICAifVxuIik7CisgIH0KKworICBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24ocHJpbnRlciwKKyAgICAicmVzdWx0LiRuYW1lJF8gPSAkbmFtZSRfO1xuIiwKKworICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJEJ1aWxkZXJfLmJ1aWxkKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkdHlwZSQuQnVpbGRlciBzdWJCdWlsZGVyID0gbnVsbDtcbiIKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc3ViQnVpbGRlciA9ICRuYW1lJF8udG9CdWlsZGVyKCk7XG4iCisgICAgIn1cbiIpOworCisgIGlmIChHZXRUeXBlKGRlc2NyaXB0b3JfKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8gPSBpbnB1dC5yZWFkR3JvdXAoJG51bWJlciQsICR0eXBlJC5QQVJTRVIsXG4iCisgICAgICAiICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXyA9IGlucHV0LnJlYWRNZXNzYWdlKCR0eXBlJC5QQVJTRVIsIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHN1YkJ1aWxkZXIgIT0gbnVsbCkge1xuIgorICAgICIgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKCRuYW1lJF8pO1xuIgorICAgICIgICRuYW1lJF8gPSBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICJ9XG4iCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIG1lc3NhZ2VzLgorfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkKClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5oYXNoQ29kZSgpO1xuIik7Cit9CisKK3N0cmluZyBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgIGNvbnRleHQtPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpOworICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICByZXR1cm4gKCR0eXBlJCkgJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgICAiICAgICByZXR1cm4gKCR0eXBlJCkgJG9uZW9mX25hbWUkXztcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFdoZW4gdXNpbmcgbmVzdGVkLWJ1aWxkZXJzLCB0aGUgY29kZSBpbml0aWFsbHkgd29ya3MganVzdCBsaWtlIHRoZQorICAvLyBub24tbmVzdGVkIGJ1aWxkZXIgY2FzZS4gSXQgb25seSBjcmVhdGVzIGEgbmVzdGVkIGJ1aWxkZXIgbGF6aWx5IG9uCisgIC8vIGRlbWFuZCBhbmQgdGhlbiBmb3JldmVyIGRlbGVnYXRlcyB0byBpdCBhZnRlciBjcmVhdGlvbi4KKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgLy8gSWYgdGhpcyBidWlsZGVyIGlzIG5vbi1udWxsLCBpdCBpcyB1c2VkIGFuZCB0aGUgb3RoZXIgZmllbGRzIGFyZQorICAgICAgLy8gaWdub3JlZC4KKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyPFxuIgorICAgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+ICRuYW1lJEJ1aWxkZXJfOyIKKyAgICAgICJcbiIpOworICB9CisKKyAgLy8gVGhlIGNvbW1lbnRzIGFib3ZlIHRoZSBtZXRob2RzIGJlbG93IGFyZSBiYXNlZCBvbiBhIGh5cG90aGV0aWNhbAorICAvLyBmaWVsZCBvZiB0eXBlICJGaWVsZCIgY2FsbGVkICJGaWVsZCIuCisKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gYm9vbGVhbiBoYXNGaWVsZCgpCisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICAvLyBGaWVsZCBnZXRGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkiLAorCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICByZXR1cm4gKCR0eXBlJCkgJG9uZW9mX25hbWUkXztcbiIKKyAgICAifVxuIgorICAgICJyZXR1cm4gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIiwKKworICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTtcbiIKKyAgICAifVxuIgorICAgICJyZXR1cm4gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgIiRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpO1xuIiwKKworICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSIsCisKKyAgICAiJG9uZW9mX25hbWUkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIG1lcmdlRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIG1lcmdlJGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQgJiZcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gIT0gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9ICR0eXBlJC5uZXdCdWlsZGVyKCgkdHlwZSQpICRvbmVvZl9uYW1lJF8pXG4iCisgICAgIiAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICJ9IGVsc2Uge1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAifVxuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICRuYW1lJEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7XG4iCisgICAgIn1cbiIKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7XG4iLAorCisgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIGNsZWFyRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgJGNsZWFyX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIn1cbiIsCisKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICRjbGVhcl9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICJ9XG4iCisgICAgIiRuYW1lJEJ1aWxkZXJfLmNsZWFyKCk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJC5CdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXIoKSB7XG4iCisgICAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcigpIHtcbiIKKyAgICAgICIgIGlmICgoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSAmJiAoJG5hbWUkQnVpbGRlcl8gIT0gbnVsbCkpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAgICIgICAgICByZXR1cm4gKCR0eXBlJCkgJG9uZW9mX25hbWUkXztcbiIKKyAgICAgICIgICAgfVxuIgorICAgICAgIiAgICByZXR1cm4gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgICAiICAgIGlmICghKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAgICIgICAgICAkb25lb2ZfbmFtZSRfID0gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICAgICRuYW1lJEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyPFxuIgorICAgICAgIiAgICAgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPihcbiIKKyAgICAgICIgICAgICAgICAgICAoJHR5cGUkKSAkb25lb2ZfbmFtZSRfLFxuIgorICAgICAgIiAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksXG4iCisgICAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAiICAkb25fY2hhbmdlZCQ7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgICAgICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgInJlc3VsdC4kb25lb2ZfbmFtZSRfID0gJG9uZW9mX25hbWUkXztcbiIsCisKKyAgICAicmVzdWx0LiRvbmVvZl9uYW1lJF8gPSAkbmFtZSRCdWlsZGVyXy5idWlsZCgpO1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJtZXJnZSRjYXBpdGFsaXplZF9uYW1lJChvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiR0eXBlJC5CdWlsZGVyIHN1YkJ1aWxkZXIgPSBudWxsO1xuIgorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc3ViQnVpbGRlciA9ICgoJHR5cGUkKSAkb25lb2ZfbmFtZSRfKS50b0J1aWxkZXIoKTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKEdldFR5cGUoZGVzY3JpcHRvcl8pID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG9uZW9mX25hbWUkXyA9IGlucHV0LnJlYWRHcm91cCgkbnVtYmVyJCwgJHR5cGUkLlBBUlNFUixcbiIKKyAgICAgICIgICAgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkb25lb2ZfbmFtZSRfID0gaW5wdXQucmVhZE1lc3NhZ2UoJHR5cGUkLlBBUlNFUiwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoc3ViQnVpbGRlciAhPSBudWxsKSB7XG4iCisgICAgIiAgc3ViQnVpbGRlci5tZXJnZUZyb20oKCR0eXBlJCkgJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHN1YkJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7XG4iCisgICAgIn1cbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGUkZ3JvdXBfb3JfbWVzc2FnZSQoJG51bWJlciQsICgkdHlwZSQpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsICgkdHlwZSQpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSAgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6Cit+UmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoKSB7fQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIDE7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRPRE8oam9ucCk6IEluIHRoZSBmdXR1cmUsIGNvbnNpZGVyIGhhdmluZyBtZXRob2RzIHNwZWNpZmljIHRvIHRoZQorICAvLyBpbnRlcmZhY2Ugc28gdGhhdCBidWlsZGVycyBjYW4gY2hvb3NlIGR5bmFtaWNhbGx5IHRvIGVpdGhlciByZXR1cm4gYQorICAvLyBtZXNzYWdlIG9yIGEgbmVzdGVkIGJ1aWxkZXIsIHNvIHRoYXQgYXNraW5nIGZvciB0aGUgaW50ZXJmYWNlIGRvZXNuJ3QKKyAgLy8gY2F1c2UgYSBtZXNzYWdlIHRvIGV2ZXIgYmUgYnVpbHQuCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5MaXN0PCR0eXBlJD4gXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpO1xuIik7CisgIGlmIChIYXNOZXN0ZWRCdWlsZGVycyhkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXJMaXN0KCk7XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcihcbiIKKyAgICAgICIgICAgaW50IGluZGV4KTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iICAgLy8gbm90ZTogIHVubW9kaWZpYWJsZSBsaXN0CisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXJMaXN0KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoXG4iCisgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgY2hhciogcmVndWxhcl9jYXNlLAorICAgIGNvbnN0IGNoYXIqIG5lc3RlZF9idWlsZGVyX2Nhc2UpIGNvbnN0IHsKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgImlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iKTsKKyAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIHJlZ3VsYXJfY2FzZSk7CisgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgcHJpbnRlci0+UHJpbnQoIn0gZWxzZSB7XG4iKTsKKyAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIG5lc3RlZF9idWlsZGVyX2Nhc2UpOworICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgIH0gZWxzZSB7CisgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIHJlZ3VsYXJfY2FzZSk7CisgICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OlByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IGNoYXIqIG1ldGhvZF9wcm90b3R5cGUsCisgICAgY29uc3QgY2hhciogcmVndWxhcl9jYXNlLAorICAgIGNvbnN0IGNoYXIqIG5lc3RlZF9idWlsZGVyX2Nhc2UsCisgICAgY29uc3QgY2hhciogdHJhaWxpbmdfY29kZSkgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCBtZXRob2RfcHJvdG90eXBlKTsKKyAgcHJpbnRlci0+UHJpbnQoIiB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIFByaW50TmVzdGVkQnVpbGRlckNvbmRpdGlvbihwcmludGVyLCByZWd1bGFyX2Nhc2UsIG5lc3RlZF9idWlsZGVyX2Nhc2UpOworICBpZiAodHJhaWxpbmdfY29kZSAhPSBOVUxMKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgdHJhaWxpbmdfY29kZSk7CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBXaGVuIHVzaW5nIG5lc3RlZC1idWlsZGVycywgdGhlIGNvZGUgaW5pdGlhbGx5IHdvcmtzIGp1c3QgbGlrZSB0aGUKKyAgLy8gbm9uLW5lc3RlZCBidWlsZGVyIGNhc2UuIEl0IG9ubHkgY3JlYXRlcyBhIG5lc3RlZCBidWlsZGVyIGxhemlseSBvbgorICAvLyBkZW1hbmQgYW5kIHRoZW4gZm9yZXZlciBkZWxlZ2F0ZXMgdG8gaXQgYWZ0ZXIgY3JlYXRpb24uCisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAvLyBVc2VkIHdoZW4gdGhlIGJ1aWxkZXIgaXMgbnVsbC4KKyAgICAvLyBPbmUgZmllbGQgaXMgdGhlIGxpc3QgYW5kIHRoZSBvdGhlciBmaWVsZCBrZWVwcyB0cmFjayBvZiB3aGV0aGVyIHRoZQorICAgIC8vIGxpc3QgaXMgaW1tdXRhYmxlLiBJZiBpdCdzIGltbXV0YWJsZSwgdGhlIGludmFyaWFudCBpcyB0aGF0IGl0IG11c3QKKyAgICAvLyBlaXRoZXIgYW4gaW5zdGFuY2Ugb2YgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkgb3IgaXQncyBhbiBBcnJheUxpc3QKKyAgICAvLyB3cmFwcGVkIGluIGEgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgpIHdyYXBwZXIgYW5kIG5vYm9keSBlbHNlIGhhcworICAgIC8vIGEgcmVmZXJlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgQXJyYXlMaXN0LiBUaGlzIGludmFyaWFudCBhbGxvd3MgdXMgdG8KKyAgICAvLyBzaGFyZSBpbnN0YW5jZXMgb2YgbGlzdHMgYmV0d2VlbiBwcm90b2NvbCBidWZmZXJzIGF2b2lkaW5nIGV4cGVuc2l2ZQorICAgIC8vIG1lbW9yeSBhbGxvY2F0aW9ucy4gTm90ZSwgaW1tdXRhYmxlIGlzIGEgc3Ryb25nIGd1YXJhbnRlZSBoZXJlIC0tIG5vdAorICAgIC8vIGp1c3QgdGhhdCB0aGUgbGlzdCBjYW5ub3QgYmUgbW9kaWZpZWQgdmlhIHRoZSByZWZlcmVuY2UgYnV0IHRoYXQgdGhlCisgICAgLy8gbGlzdCBjYW4gbmV2ZXIgYmUgbW9kaWZpZWQuCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiAkbmFtZSRfID1cbiIKKyAgICAiICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7XG4iCisKKyAgICAicHJpdmF0ZSB2b2lkIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpIHtcbiIKKyAgICAiICBpZiAoISRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDwkdHlwZSQ+KCRuYW1lJF8pO1xuIgorICAgICIgICAgJHNldF9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgaWYgKEhhc05lc3RlZEJ1aWxkZXJzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgLy8gSWYgdGhpcyBidWlsZGVyIGlzIG5vbi1udWxsLCBpdCBpcyB1c2VkIGFuZCB0aGUgb3RoZXIgZmllbGRzIGFyZQorICAgICAgLy8gaWdub3JlZC4KKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8XG4iCisgICAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gcmVwZWF0ZWQgZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiUmVwZWF0ZWRGaWVsZCIuCisKKyAgLy8gTGlzdDxGaWVsZD4gZ2V0UmVwZWF0ZWRGaWVsZExpc3QoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkiLAorCisgICAgInJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIsCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkiLAorCisgICAgInJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIsCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRDb3VudCgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIEZpZWxkIGdldFJlcGVhdGVkRmllbGQoaW50IGluZGV4KQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIiwKKworICAgICJyZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIiwKKworICAgICJyZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7XG4iLAorCisgICAgTlVMTCk7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSIsCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uc2V0KGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpO1xuIiwKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLmFkZCh2YWx1ZSk7XG4iCisKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uYWRkKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSIsCisKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpZWxkKEl0ZXJhYmxlPEZpZWxkPiB2YWx1ZXMpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgJHR5cGUkPiB2YWx1ZXMpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKFxuIgorICAgICIgICAgdmFsdWVzLCAkbmFtZSRfKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBjbGVhckFsbFJlcGVhdGVkRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICIkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpO1xuIgorICAgICIkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHJlbW92ZSRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5yZW1vdmUoaW5kZXgpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICBpZiAoSGFzTmVzdGVkQnVpbGRlcnMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcihcbiIKKyAgICAgICIgICAgaW50IGluZGV4KSB7XG4iCisgICAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7XG4iCisgICAgICAifVxuIik7CisKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKFxuIgorICAgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgICAiICAgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7IgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworCisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgICAiICAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXJMaXN0KCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfICE9IG51bGwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKCkge1xuIgorICAgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoXG4iCisgICAgICAiICAgICAgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKFxuIgorICAgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKFxuIgorICAgICAgIiAgICAgIGluZGV4LCAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCR0eXBlJC5CdWlsZGVyPiBcbiIKKyAgICAgICIgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXJMaXN0KCkge1xuIgorICAgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7XG4iCisgICAgICAifVxuIgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlcjxcbiIKKyAgICAgICIgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPiBcbiIKKyAgICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlcjxcbiIKKyAgICAgICIgICAgICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4oXG4iCisgICAgICAiICAgICAgICAgICAgJG5hbWUkXyxcbiIKKyAgICAgICIgICAgICAgICAgICAkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkLFxuIgorICAgICAgIiAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksXG4iCisgICAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IG51bGw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24ocHJpbnRlciwKKyAgICAiJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIKKyAgICAiJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBkb2VzIHR3byBvcHRpbWl6YXRpb25zIChub24tbmVzdGVkIGJ1aWxkZXIgY2FzZSk6CisgIC8vICAgMS4gSWYgdGhlIG90aGVyIGxpc3QgaXMgZW1wdHksIHRoZXJlJ3Mgbm90aGluZyB0byBkby4gVGhpcyBlbnN1cmVzIHdlCisgIC8vICAgICAgZG9uJ3QgYWxsb2NhdGUgYSBuZXcgYXJyYXkgaWYgd2UgYWxyZWFkeSBoYXZlIGFuIGltbXV0YWJsZSBvbmUuCisgIC8vICAgMi4gSWYgdGhlIG90aGVyIGxpc3QgaXMgbm9uLWVtcHR5IGFuZCBvdXIgY3VycmVudCBsaXN0IGlzIGVtcHR5LCB3ZSBjYW4KKyAgLy8gICAgICByZXVzZSB0aGUgb3RoZXIgbGlzdCB3aGljaCBpcyBndWFyYW50ZWVkIHRvIGJlIGltbXV0YWJsZS4KKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgImlmICghb3RoZXIuJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICIgICAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkQWxsKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAifVxuIiwKKworICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfLmlzRW1wdHkoKSkge1xuIgorICAgICIgICAgJG5hbWUkQnVpbGRlcl8uZGlzcG9zZSgpO1xuIgorICAgICIgICAgJG5hbWUkQnVpbGRlcl8gPSBudWxsO1xuIgorICAgICIgICAgJG5hbWUkXyA9IG90aGVyLiRuYW1lJF87XG4iCisgICAgIiAgICAkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgICAkbmFtZSRCdWlsZGVyXyA9IFxuIgorICAgICIgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/XG4iCisgICAgIiAgICAgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpIDogbnVsbDtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgJG5hbWUkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuJG5hbWUkXyk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyAobm9uLW5lc3RlZCBidWlsZGVyIGNhc2UpIGVuc3VyZXMgdGhhdCB0aGUgcmVzdWx0IGhhcyBhbgorICAvLyBpbW11dGFibGUgbGlzdC4gSWYgb3VyIGxpc3QgaXMgaW1tdXRhYmxlLCB3ZSBjYW4ganVzdCByZXVzZSBpdC4gSWYgbm90LAorICAvLyB3ZSBtYWtlIGl0IGltbXV0YWJsZS4KKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgImlmICgkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCRuYW1lJF8pO1xuIgorICAgICIgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAifVxuIgorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iLAorCisgICAgInJlc3VsdC4kbmFtZSRfID0gJG5hbWUkQnVpbGRlcl8uYnVpbGQoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JHR5cGUkPigpO1xuIgorICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKEdldFR5cGUoZGVzY3JpcHRvcl8pID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXy5hZGQoaW5wdXQucmVhZEdyb3VwKCRudW1iZXIkLCAkdHlwZSQuUEFSU0VSLFxuIgorICAgICAgIiAgICBleHRlbnNpb25SZWdpc3RyeSkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRfLmFkZChpbnB1dC5yZWFkTWVzc2FnZSgkdHlwZSQuUEFSU0VSLCBleHRlbnNpb25SZWdpc3RyeSkpO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlJGdyb3VwX29yX21lc3NhZ2UkU2l6ZSgkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKVxuIgorICAgICIgICAgLmVxdWFscyhvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSA+IDApIHtcbiIKKyAgICAiICBoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgIiAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmhhc2hDb2RlKCk7XG4iCisgICAgIn1cbiIpOworfQorCitzdHJpbmcgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWE4MjI1YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDE3MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworICB2b2lkIFByaW50TmVzdGVkQnVpbGRlckNvbmRpdGlvbihpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgIGNvbnN0IGNoYXIqIHJlZ3VsYXJfY2FzZSwgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSkgY29uc3Q7CisgIHZvaWQgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24oaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICBjb25zdCBjaGFyKiBtZXRob2RfcHJvdG90eXBlLCBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsCisgICAgICBjb25zdCBjaGFyKiBuZXN0ZWRfYnVpbGRlcl9jYXNlLAorICAgICAgY29uc3QgY2hhciogdHJhaWxpbmdfY29kZSkgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5SZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworICB2b2lkIFByaW50TmVzdGVkQnVpbGRlckNvbmRpdGlvbihpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgIGNvbnN0IGNoYXIqIHJlZ3VsYXJfY2FzZSwgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSkgY29uc3Q7CisgIHZvaWQgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24oaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICBjb25zdCBjaGFyKiBtZXRob2RfcHJvdG90eXBlLCBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsCisgICAgICBjb25zdCBjaGFyKiBuZXN0ZWRfYnVpbGRlcl9jYXNlLAorICAgICAgY29uc3QgY2hhciogdHJhaWxpbmdfY29kZSkgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjMzYzZjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmNjCkBAIC0wLDAgKzEsMjY2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK25hbWVzcGFjZSB7CisvLyBBIHN1ZmZpeCB0aGF0IHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIGZpbGUncyBvdXRlciBjbGFzcyBuYW1lIGlmIHRoZSBuYW1lCisvLyBjb25mbGljdHMgd2l0aCBzb21lIG90aGVyIHR5cGVzIGRlZmluZWQgaW4gdGhlIGZpbGUuCitjb25zdCBjaGFyKiBrT3V0ZXJDbGFzc05hbWVTdWZmaXggPSAiT3V0ZXJDbGFzcyI7CisKKy8vIFN0cmlwIHBhY2thZ2UgbmFtZSBmcm9tIGEgZGVzY3JpcHRvcidzIGZ1bGwgbmFtZS4KKy8vIEZvciBleGFtcGxlOgorLy8gICBGdWxsIG5hbWUgICA6IGZvby5CYXIuQmF6CisvLyAgIFBhY2thZ2UgbmFtZTogZm9vCisvLyAgIEFmdGVyIHN0cmlwIDogQmFyLkJhegorc3RyaW5nIFN0cmlwUGFja2FnZU5hbWUoY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBpZiAoZmlsZS0+cGFja2FnZSgpLmVtcHR5KCkpIHsKKyAgICByZXR1cm4gZnVsbF9uYW1lOworICB9IGVsc2UgeworICAgIC8vIFN0cmlwIHBhY2thZ2UgbmFtZQorICAgIHJldHVybiBmdWxsX25hbWUuc3Vic3RyKGZpbGUtPnBhY2thZ2UoKS5zaXplKCkgKyAxKTsKKyAgfQorfQorCisvLyBHZXQgdGhlIG5hbWUgb2YgYSBtZXNzYWdlJ3MgSmF2YSBjbGFzcyB3aXRob3V0IHBhY2thZ2UgbmFtZSBwcmVmaXguCitzdHJpbmcgQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSkgeworICByZXR1cm4gU3RyaXBQYWNrYWdlTmFtZShkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpKTsKK30KKworLy8gR2V0IHRoZSBuYW1lIG9mIGFuIGVudW0ncyBKYXZhIGNsYXNzIHdpdGhvdXQgcGFja2FnZSBuYW1lIHByZWZpeC4KK3N0cmluZyBDbGFzc05hbWVXaXRob3V0UGFja2FnZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSkgeworICAvLyBEb2Vzbid0IGFwcGVuZCAiTXV0YWJsZSIgZm9yIGVudW0gdHlwZSdzIG5hbWUuCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfZGVzY3JpcHRvciA9IGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpOworICBpZiAobWVzc2FnZV9kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICByZXR1cm4gZGVzY3JpcHRvci0+bmFtZSgpOworICB9IGVsc2UgeworICAgIHJldHVybiBDbGFzc05hbWVXaXRob3V0UGFja2FnZShtZXNzYWdlX2Rlc2NyaXB0b3IsIGltbXV0YWJsZSkgKworICAgICAgICAgICAiLiIgKyBkZXNjcmlwdG9yLT5uYW1lKCk7CisgIH0KK30KKworLy8gR2V0IHRoZSBuYW1lIG9mIGEgc2VydmljZSdzIEphdmEgY2xhc3Mgd2l0aG91dCBwYWNrYWdlIG5hbWUgcHJlZml4Lgorc3RyaW5nIENsYXNzTmFtZVdpdGhvdXRQYWNrYWdlKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlKSB7CisgIHN0cmluZyBmdWxsX25hbWUgPSBTdHJpcFBhY2thZ2VOYW1lKGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5maWxlKCkpOworICAvLyBXZSBkb24ndCBhbGxvdyBuZXN0ZWQgc2VydmljZSBkZWZpbml0aW9ucy4KKyAgR09PR0xFX0NIRUNLKGZ1bGxfbmFtZS5maW5kKCcuJykgPT0gc3RyaW5nOjpucG9zKTsKKyAgcmV0dXJuIGZ1bGxfbmFtZTsKK30KKworLy8gQ2hlY2sgd2hldGhlciBhIGdpdmVuIG1lc3NhZ2Ugb3IgaXRzIG5lc3RlZCB0eXBlcyBoYXMgdGhlIGdpdmVuIGNsYXNzIG5hbWUuCitib29sIE1lc3NhZ2VIYXNDb25mbGljdGluZ0NsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBjbGFzc25hbWUpIHsKKyAgaWYgKG1lc3NhZ2UtPm5hbWUoKSA9PSBjbGFzc25hbWUpIHJldHVybiB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGlmIChNZXNzYWdlSGFzQ29uZmxpY3RpbmdDbGFzc05hbWUobWVzc2FnZS0+bmVzdGVkX3R5cGUoaSksIGNsYXNzbmFtZSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmVudW1fdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAobWVzc2FnZS0+ZW51bV90eXBlKGkpLT5uYW1lKCkgPT0gY2xhc3NuYW1lKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworQ2xhc3NOYW1lUmVzb2x2ZXI6OkNsYXNzTmFtZVJlc29sdmVyKCkgeworfQorCitDbGFzc05hbWVSZXNvbHZlcjo6fkNsYXNzTmFtZVJlc29sdmVyKCkgeworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldEZpbGVEZWZhdWx0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHN0cmluZyBiYXNlbmFtZTsKKyAgc3RyaW5nOjpzaXplX3R5cGUgbGFzdF9zbGFzaCA9IGZpbGUtPm5hbWUoKS5maW5kX2xhc3Rfb2YoJy8nKTsKKyAgaWYgKGxhc3Rfc2xhc2ggPT0gc3RyaW5nOjpucG9zKSB7CisgICAgYmFzZW5hbWUgPSBmaWxlLT5uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgYmFzZW5hbWUgPSBmaWxlLT5uYW1lKCkuc3Vic3RyKGxhc3Rfc2xhc2ggKyAxKTsKKyAgfQorICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShTdHJpcFByb3RvKGJhc2VuYW1lKSwgdHJ1ZSk7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0RmlsZUltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBzdHJpbmcmIGNsYXNzX25hbWUgPSBmaWxlX2ltbXV0YWJsZV9vdXRlcl9jbGFzc19uYW1lc19bZmlsZV07CisgIGlmIChjbGFzc19uYW1lLmVtcHR5KCkpIHsKKyAgICBpZiAoZmlsZS0+b3B0aW9ucygpLmhhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpKSB7CisgICAgICBjbGFzc19uYW1lID0gZmlsZS0+b3B0aW9ucygpLmphdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGNsYXNzX25hbWUgPSBHZXRGaWxlRGVmYXVsdEltbXV0YWJsZUNsYXNzTmFtZShmaWxlKTsKKyAgICAgIGlmIChIYXNDb25mbGljdGluZ0NsYXNzTmFtZShmaWxlLCBjbGFzc19uYW1lKSkgeworICAgICAgICBjbGFzc19uYW1lICs9IGtPdXRlckNsYXNzTmFtZVN1ZmZpeDsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIGNsYXNzX25hbWU7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0RmlsZUNsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSkgeworICBpZiAoaW1tdXRhYmxlKSB7CisgICAgcmV0dXJuIEdldEZpbGVJbW11dGFibGVDbGFzc05hbWUoZmlsZSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuICJNdXRhYmxlIiArIEdldEZpbGVJbW11dGFibGVDbGFzc05hbWUoZmlsZSk7CisgIH0KK30KKworLy8gQ2hlY2sgd2hldGhlciB0aGVyZSBpcyBhbnkgdHlwZSBkZWZpbmVkIGluIHRoZSBwcm90byBmaWxlIHRoYXQgaGFzCisvLyB0aGUgZ2l2ZW4gY2xhc3MgbmFtZS4KK2Jvb2wgQ2xhc3NOYW1lUmVzb2x2ZXI6Okhhc0NvbmZsaWN0aW5nQ2xhc3NOYW1lKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBjb25zdCBzdHJpbmcmIGNsYXNzbmFtZSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZmlsZS0+ZW51bV90eXBlKGkpLT5uYW1lKCkgPT0gY2xhc3NuYW1lKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChmaWxlLT5zZXJ2aWNlKGkpLT5uYW1lKCkgPT0gY2xhc3NuYW1lKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKE1lc3NhZ2VIYXNDb25mbGljdGluZ0NsYXNzTmFtZShmaWxlLT5tZXNzYWdlX3R5cGUoaSksIGNsYXNzbmFtZSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0RGVzY3JpcHRvckNsYXNzTmFtZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gR2V0RmlsZUltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yKTsKK30KKworc3RyaW5nIENsYXNzTmFtZVJlc29sdmVyOjpHZXRDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSkgeworICBzdHJpbmcgcmVzdWx0ID0gRmlsZUphdmFQYWNrYWdlKGRlc2NyaXB0b3IsIGltbXV0YWJsZSk7CisgIGlmICghcmVzdWx0LmVtcHR5KCkpIHJlc3VsdCArPSAnLic7CisgIHJlc3VsdCArPSBHZXRGaWxlQ2xhc3NOYW1lKGRlc2NyaXB0b3IsIGltbXV0YWJsZSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEdldCB0aGUgZnVsbCBuYW1lIG9mIGEgSmF2YSBjbGFzcyBieSBwcmVwZW5kaW5nIHRoZSBKYXZhIHBhY2thZ2UgbmFtZQorLy8gb3Igb3V0ZXIgY2xhc3MgbmFtZS4KK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0Q2xhc3NGdWxsTmFtZShjb25zdCBzdHJpbmcmIG5hbWVfd2l0aG91dF9wYWNrYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgbXVsdGlwbGVfZmlsZXMpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgaWYgKG11bHRpcGxlX2ZpbGVzKSB7CisgICAgcmVzdWx0ID0gRmlsZUphdmFQYWNrYWdlKGZpbGUsIGltbXV0YWJsZSk7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0gR2V0Q2xhc3NOYW1lKGZpbGUsIGltbXV0YWJsZSk7CisgIH0KKyAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgeworICAgIHJlc3VsdCArPSAnLic7CisgIH0KKyAgcmVzdWx0ICs9IG5hbWVfd2l0aG91dF9wYWNrYWdlOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldENsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgcmV0dXJuIEdldENsYXNzRnVsbE5hbWUoQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UoZGVzY3JpcHRvciwgaW1tdXRhYmxlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLCBpbW11dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpcGxlSmF2YUZpbGVzKGRlc2NyaXB0b3ItPmZpbGUoKSwgaW1tdXRhYmxlKSk7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0Q2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgcmV0dXJuIEdldENsYXNzRnVsbE5hbWUoQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UoZGVzY3JpcHRvciwgaW1tdXRhYmxlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLCBpbW11dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpcGxlSmF2YUZpbGVzKGRlc2NyaXB0b3ItPmZpbGUoKSwgaW1tdXRhYmxlKSk7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0Q2xhc3NOYW1lKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgcmV0dXJuIEdldENsYXNzRnVsbE5hbWUoQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UoZGVzY3JpcHRvciwgaW1tdXRhYmxlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLCBpbW11dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpcGxlSmF2YUZpbGVzKGRlc2NyaXB0b3ItPmZpbGUoKSwgaW1tdXRhYmxlKSk7Cit9CisKKy8vIEdldCB0aGUgSmF2YSBDbGFzcyBzdHlsZSBmdWxsIG5hbWUgb2YgYSBtZXNzYWdlLgorc3RyaW5nIENsYXNzTmFtZVJlc29sdmVyOjpHZXRKYXZhQ2xhc3NGdWxsTmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWVfd2l0aG91dF9wYWNrYWdlLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgIGJvb2wgaW1tdXRhYmxlKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGlmIChNdWx0aXBsZUphdmFGaWxlcyhmaWxlLCBpbW11dGFibGUpKSB7CisgICAgcmVzdWx0ID0gRmlsZUphdmFQYWNrYWdlKGZpbGUsIGltbXV0YWJsZSk7CisgICAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgcmVzdWx0ICs9ICcuJzsKKyAgfSBlbHNlIHsKKyAgICByZXN1bHQgPSBHZXRDbGFzc05hbWUoZmlsZSwgaW1tdXRhYmxlKTsKKyAgICBpZiAoIXJlc3VsdC5lbXB0eSgpKSByZXN1bHQgKz0gJyQnOworICB9CisgIHJlc3VsdCArPSBTdHJpbmdSZXBsYWNlKG5hbWVfd2l0aG91dF9wYWNrYWdlLCAiLiIsICIkIiwgdHJ1ZSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0RXh0ZW5zaW9uSWRlbnRpZmllck5hbWUoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBib29sIGltbXV0YWJsZSkgeworICByZXR1cm4gR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpLCBpbW11dGFibGUpICsgIi4iICsKKyAgICAgICAgIGRlc2NyaXB0b3ItPm5hbWUoKTsKK30KKworCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldEphdmFJbW11dGFibGVDbGFzc05hbWUoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gR2V0SmF2YUNsYXNzRnVsbE5hbWUoCisgICAgICBDbGFzc05hbWVXaXRob3V0UGFja2FnZShkZXNjcmlwdG9yLCB0cnVlKSwKKyAgICAgIGRlc2NyaXB0b3ItPmZpbGUoKSwgdHJ1ZSk7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWI2MGIwYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaApAQCAtMCwwICsxLDEyNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTkFNRV9SRVNPTFZFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTkFNRV9SRVNPTFZFUl9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK2NsYXNzIERlc2NyaXB0b3I7CitjbGFzcyBFbnVtRGVzY3JpcHRvcjsKK2NsYXNzIEZpZWxkRGVzY3JpcHRvcjsKK2NsYXNzIEZpbGVEZXNjcmlwdG9yOworY2xhc3MgU2VydmljZURlc2NyaXB0b3I7CisKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKKy8vIFVzZWQgdG8gZ2V0IHRoZSBKYXZhIGNsYXNzIHJlbGF0ZWQgbmFtZXMgZm9yIGEgZ2l2ZW4gZGVzY3JpcHRvci4gSXQgY2FjaGVzCisvLyB0aGUgcmVzdWx0cyB0byBhdm9pZCByZWR1bmRhbnQgY2FsY3VsYXRpb24gYWNyb3NzIG11bHRpcGxlIG5hbWUgcXVlcmllcy4KKy8vIFRocmVhZC1zYWZldHkgbm90ZTogVGhpcyBjbGFzcyBpcyAqbm90KiB0aHJlYWQtc2FmZS4KK2NsYXNzIENsYXNzTmFtZVJlc29sdmVyIHsKKyBwdWJsaWM6CisgIENsYXNzTmFtZVJlc29sdmVyKCk7CisgIH5DbGFzc05hbWVSZXNvbHZlcigpOworCisgIC8vIEdldHMgdGhlIHVucXVhbGlmaWVkIG91dGVyIGNsYXNzIG5hbWUgZm9yIHRoZSBmaWxlLgorICBzdHJpbmcgR2V0RmlsZUNsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgYm9vbCBpbW11dGFibGUpOworICAvLyBHZXRzIHRoZSB1bnF1YWxpZmllZCBpbW11dGFibGUgb3V0ZXIgY2xhc3MgbmFtZSBvZiBhIGZpbGUuCisgIHN0cmluZyBHZXRGaWxlSW1tdXRhYmxlQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKyAgLy8gR2V0cyB0aGUgdW5xdWFsaWZpZWQgZGVmYXVsdCBpbW11dGFibGUgb3V0ZXIgY2xhc3MgbmFtZSBvZiBhIGZpbGUKKyAgLy8gKGNvbnZlcnRlZCBmcm9tIHRoZSBwcm90byBmaWxlJ3MgbmFtZSkuCisgIHN0cmluZyBHZXRGaWxlRGVmYXVsdEltbXV0YWJsZUNsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKyAgLy8gQ2hlY2sgd2hldGhlciB0aGVyZSBpcyBhbnkgdHlwZSBkZWZpbmVkIGluIHRoZSBwcm90byBmaWxlIHRoYXQgaGFzCisgIC8vIHRoZSBnaXZlbiBjbGFzcyBuYW1lLgorICBib29sIEhhc0NvbmZsaWN0aW5nQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgY2xhc3NuYW1lKTsKKworICAvLyBHZXRzIHRoZSBuYW1lIG9mIHRoZSBvdXRlciBjbGFzcyB0aGF0IGhvbGRzIGRlc2NyaXB0b3IgaW5mb3JtYXRpb24uCisgIC8vIERlc2NyaXB0b3JzIGFyZSBzaGFyZWQgYmV0d2VlbiBpbW11dGFibGUgbWVzc2FnZXMgYW5kIG11dGFibGUgbWVzc2FnZXMuCisgIC8vIFNpbmNlIGJvdGggb2YgdGhlbSBhcmUgZ2VuZXJhdGVkIG9wdGlvbmFsbHksIHRoZSBkZXNjcmlwdG9ycyBuZWVkIHRvIGJlCisgIC8vIHB1dCBpbiBhbm90aGVyIGNvbW1vbiBwbGFjZS4KKyAgc3RyaW5nIEdldERlc2NyaXB0b3JDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisgIC8vIEdldHMgdGhlIGZ1bGx5LXF1YWxpZmllZCBjbGFzcyBuYW1lIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGRlc2NyaXB0b3IuCisgIHN0cmluZyBHZXRDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBpbW11dGFibGUpOworICBzdHJpbmcgR2V0Q2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBib29sIGltbXV0YWJsZSk7CisgIHN0cmluZyBHZXRDbGFzc05hbWUoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGJvb2wgaW1tdXRhYmxlKTsKKyAgc3RyaW5nIEdldENsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBpbW11dGFibGUpOworCisgIHRlbXBsYXRlPGNsYXNzIERlc2NyaXB0b3JUeXBlPgorICBzdHJpbmcgR2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3JUeXBlKiBkZXNjcmlwdG9yKSB7CisgICAgcmV0dXJuIEdldENsYXNzTmFtZShkZXNjcmlwdG9yLCB0cnVlKTsKKyAgfQorICB0ZW1wbGF0ZTxjbGFzcyBEZXNjcmlwdG9yVHlwZT4KKyAgc3RyaW5nIEdldE11dGFibGVDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvclR5cGUqIGRlc2NyaXB0b3IpIHsKKyAgICByZXR1cm4gR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3IsIGZhbHNlKTsKKyAgfQorCisgIC8vIEdldHMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIGFuIGV4dGVuc2lvbiBpZGVudGlmaWVyLgorICBzdHJpbmcgR2V0RXh0ZW5zaW9uSWRlbnRpZmllck5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpOworCisgIC8vIEdldHMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIGZvciBnZW5lcmF0ZWQgY2xhc3NlcyBpbiBKYXZhIGNvbnZlbnRpb24uCisgIC8vIE5lc3RlZCBjbGFzc2VzIHdpbGwgYmUgc2VwYXJhdGVkIHVzaW5nICckJyBpbnN0ZWFkIG9mICcuJworICAvLyBGb3IgZXhhbXBsZToKKyAgLy8gICBjb20ucGFja2FnZS5PdXRlckNsYXNzJE91dGVyTWVzc2FnZSRJbm5lck1lc3NhZ2UKKyAgc3RyaW5nIEdldEphdmFJbW11dGFibGVDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgcHJpdmF0ZToKKyAgLy8gR2V0IHRoZSBmdWxsIG5hbWUgb2YgYSBKYXZhIGNsYXNzIGJ5IHByZXBlbmRpbmcgdGhlIEphdmEgcGFja2FnZSBuYW1lCisgIC8vIG9yIG91dGVyIGNsYXNzIG5hbWUuCisgIHN0cmluZyBHZXRDbGFzc0Z1bGxOYW1lKGNvbnN0IHN0cmluZyYgbmFtZV93aXRob3V0X3BhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBtdWx0aXBsZV9maWxlcyk7CisgIC8vIEdldCB0aGUgSmF2YSBDbGFzcyBzdHlsZSBmdWxsIG5hbWUgb2YgYSBtZXNzYWdlLgorICBzdHJpbmcgR2V0SmF2YUNsYXNzRnVsbE5hbWUoCisgICAgICBjb25zdCBzdHJpbmcmIG5hbWVfd2l0aG91dF9wYWNrYWdlLAorICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICBib29sIGltbXV0YWJsZSk7CisgIC8vIENhY2hlcyB0aGUgcmVzdWx0IHRvIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLgorICBtYXA8Y29uc3QgRmlsZURlc2NyaXB0b3IqLCBzdHJpbmc+IGZpbGVfaW1tdXRhYmxlX291dGVyX2NsYXNzX25hbWVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ2xhc3NOYW1lUmVzb2x2ZXIpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTkFNRV9SRVNPTFZFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkNjE0MzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lcy5oCkBAIC0wLDAgKzEsODcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBQcm92aWRlcyBhIG1lY2hhbmlzbSBmb3IgbWFwcGluZyBhIGRlc2NyaXB0b3IgdG8gdGhlCisvLyBmdWxseS1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgY29ycmVzcG9uZGluZyBKYXZhIGNsYXNzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX05BTUVTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9OQU1FU19IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBEZXNjcmlwdG9yOworY2xhc3MgRW51bURlc2NyaXB0b3I7CitjbGFzcyBGaWxlRGVzY3JpcHRvcjsKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworCituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCisvLyBSZXF1aXJlczoKKy8vICAgZGVzY3JpcHRvciAhPSBOVUxMCisvLworLy8gUmV0dXJuczoKKy8vICAgVGhlIGZ1bGx5LXF1YWxpZmllZCBKYXZhIGNsYXNzIG5hbWUuCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZXF1aXJlczoKKy8vICAgZGVzY3JpcHRvciAhPSBOVUxMCisvLworLy8gUmV0dXJuczoKKy8vICAgVGhlIGZ1bGx5LXF1YWxpZmllZCBKYXZhIGNsYXNzIG5hbWUuCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworLy8gUmVxdWlyZXM6CisvLyAgIGRlc2NyaXB0b3IgIT0gTlVMTAorLy8KKy8vIFJldHVybnM6CisvLyAgIFRoZSBmdWxseS1xdWFsaWZpZWQgSmF2YSBjbGFzcyBuYW1lLgorc3RyaW5nIENsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIFJlcXVpcmVzOgorLy8gICBkZXNjcmlwdG9yICE9IE5VTEwKKy8vCisvLyBSZXR1cm5zOgorLy8gICBUaGUgZnVsbHktcXVhbGlmaWVkIEphdmEgY2xhc3MgbmFtZS4KK3N0cmluZyBDbGFzc05hbWUoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9OQU1FU19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3BsdWdpbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3BsdWdpbl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTUyNzYyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcGx1Z2luX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTI3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFRPRE8oa2VudG9uKTogIFNoYXJlIGNvZGUgd2l0aCB0aGUgdmVyc2lvbnMgb2YgdGhpcyB0ZXN0IGluIG90aGVyIGxhbmd1YWdlcz8KKy8vICAgSXQgc2VlbWVkIGxpa2UgcGFyYW1ldGVyaXppbmcgaXQgd291bGQgYWRkIG1vcmUgY29tcGxleGl0eSB0aGFuIGl0IGlzCisvLyAgIHdvcnRoLgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKK25hbWVzcGFjZSB7CisKK2NsYXNzIFRlc3RHZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBUZXN0R2VuZXJhdG9yKCkge30KKyAgflRlc3RHZW5lcmF0b3IoKSB7fQorCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgICBzdHJpbmcgZmlsZW5hbWUgPSAiVGVzdC5qYXZhIjsKKyAgICBUcnlJbnNlcnQoZmlsZW5hbWUsICJvdXRlcl9jbGFzc19zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydChmaWxlbmFtZSwgImNsYXNzX3Njb3BlOmZvby5CYXIiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoZmlsZW5hbWUsICJjbGFzc19zY29wZTpmb28uQmFyLkJheiIsIGNvbnRleHQpOworICAgIFRyeUluc2VydChmaWxlbmFtZSwgImJ1aWxkZXJfc2NvcGU6Zm9vLkJhciIsIGNvbnRleHQpOworICAgIFRyeUluc2VydChmaWxlbmFtZSwgImJ1aWxkZXJfc2NvcGU6Zm9vLkJhci5CYXoiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoZmlsZW5hbWUsICJlbnVtX3Njb3BlOmZvby5RdXgiLCBjb250ZXh0KTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHZvaWQgVHJ5SW5zZXJ0KGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9uX3BvaW50LAorICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0KSBjb25zdCB7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dCgKKyAgICAgICAgY29udGV4dC0+T3BlbkZvckluc2VydChmaWxlbmFtZSwgaW5zZXJ0aW9uX3BvaW50KSk7CisgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgcHJpbnRlci5QcmludCgiLy8gaW5zZXJ0ZWQgJG5hbWUkXG4iLCAibmFtZSIsIGluc2VydGlvbl9wb2ludCk7CisgIH0KK307CisKKy8vIFRoaXMgdGVzdCB2ZXJpZmllcyB0aGF0IGFsbCB0aGUgZXhwZWN0ZWQgaW5zZXJ0aW9uIHBvaW50cyBleGlzdC4gIEl0IGRvZXMKKy8vIG5vdCB2ZXJpZnkgdGhhdCB0aGV5IGFyZSBjb3JyZWN0bHktcGxhY2VkOyB0aGF0IHdvdWxkIHJlcXVpcmUgYWN0dWFsbHkKKy8vIGNvbXBpbGluZyB0aGUgb3V0cHV0IHdoaWNoIGlzIGEgYml0IG1vcmUgdGhhbiBJIGNhcmUgdG8gZG8gZm9yIHRoaXMgdGVzdC4KK1RFU1QoSmF2YVBsdWdpblRlc3QsIFBsdWdpblRlc3QpIHsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OlNldENvbnRlbnRzKFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3QucHJvdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhY2thZ2UgZm9vO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0aW9uIGphdmFfcGFja2FnZSA9IFwiXCI7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSBcIlRlc3RcIjtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgbWVzc2FnZSBCYXoge31cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVudW0gUXV4IHsgQkxBSCA9IDE7IH1cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpKTsKKworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29tbWFuZExpbmVJbnRlcmZhY2UgY2xpOworICBjbGkuU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUodHJ1ZSk7CisKKyAgSmF2YUdlbmVyYXRvciBqYXZhX2dlbmVyYXRvcjsKKyAgVGVzdEdlbmVyYXRvciB0ZXN0X2dlbmVyYXRvcjsKKyAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLWphdmFfb3V0IiwgJmphdmFfZ2VuZXJhdG9yLCAiIik7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS10ZXN0X291dCIsICZ0ZXN0X2dlbmVyYXRvciwgIiIpOworCisgIHN0cmluZyBwcm90b19wYXRoID0gIi1JIiArIFRlc3RUZW1wRGlyKCk7CisgIHN0cmluZyBqYXZhX291dCA9ICItLWphdmFfb3V0PSIgKyBUZXN0VGVtcERpcigpOworICBzdHJpbmcgdGVzdF9vdXQgPSAiLS10ZXN0X291dD0iICsgVGVzdFRlbXBEaXIoKTsKKworICBjb25zdCBjaGFyKiBhcmd2W10gPSB7CisgICAgInByb3RvYyIsCisgICAgcHJvdG9fcGF0aC5jX3N0cigpLAorICAgIGphdmFfb3V0LmNfc3RyKCksCisgICAgdGVzdF9vdXQuY19zdHIoKSwKKyAgICAidGVzdC5wcm90byIKKyAgfTsKKworICBFWFBFQ1RfRVEoMCwgY2xpLlJ1big1LCBhcmd2KSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDg3NTdjNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5jYwpAQCAtMCwwICsxLDg2MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit2b2lkIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiYm94ZWRfdHlwZSJdID0gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiZmllbGRfdHlwZSJdID0gKCp2YXJpYWJsZXMpWyJ0eXBlIl07CisgICgqdmFyaWFibGVzKVsiZmllbGRfbGlzdF90eXBlIl0gPSAiamF2YS51dGlsLkxpc3Q8IiArCisgICAgICAoKnZhcmlhYmxlcylbImJveGVkX3R5cGUiXSArICI+IjsKKyAgKCp2YXJpYWJsZXMpWyJlbXB0eV9saXN0Il0gPSAiamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpIjsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcik7CisgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9pbml0Il0gPSBJc0RlZmF1bHRWYWx1ZUphdmFEZWZhdWx0KGRlc2NyaXB0b3IpID8KKyAgICAgICIiIDogKCI9ICIgKyBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcikpOworICAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX3R5cGUiXSA9CisgICAgICBHZXRDYXBpdGFsaXplZFR5cGUoZGVzY3JpcHRvciwgLyogaW1tdXRhYmxlID0gKi8gdHJ1ZSk7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbInRhZ19zaXplIl0gPSBTaW1wbGVJdG9hKAorICAgICAgV2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgR2V0VHlwZShkZXNjcmlwdG9yKSkpOworICBpZiAoSXNSZWZlcmVuY2VUeXBlKEdldEphdmFUeXBlKGRlc2NyaXB0b3IpKSkgeworICAgICgqdmFyaWFibGVzKVsibnVsbF9jaGVjayJdID0KKyAgICAgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAgICAgIiAgfVxuIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbIm51bGxfY2hlY2siXSA9ICIiOworICB9CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgIGludCBmaXhlZF9zaXplID0gRml4ZWRTaXplKEdldFR5cGUoZGVzY3JpcHRvcikpOworICBpZiAoZml4ZWRfc2l6ZSAhPSAtMSkgeworICAgICgqdmFyaWFibGVzKVsiZml4ZWRfc2l6ZSJdID0gU2ltcGxlSXRvYShmaXhlZF9zaXplKTsKKyAgfQorICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhlc2UgaGF2ZSBhIHRyYWlsaW5nICI7Ii4KKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KG1lc3NhZ2VCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpICsgIjsiOworICAgICgqdmFyaWFibGVzKVsiY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9ICIiOworCisgICAgaWYgKGRlc2NyaXB0b3ItPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPQorICAgICAgICAgICIhIiArICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8uaXNFbXB0eSgpIjsKKyAgICB9IGVsc2UgeworICAgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9CisgICAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyAhPSAiICsgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il07CisgICAgfQorICB9CisKKyAgLy8gRm9yIHJlcGF0ZWQgYnVpbGRlcnMsIG9uZSBiaXQgaXMgdXNlZCBmb3Igd2hldGhlciB0aGUgYXJyYXkgaXMgaW1tdXRhYmxlLgorICAoKnZhcmlhYmxlcylbImdldF9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZUdldEJpdChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbImNsZWFyX211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlQ2xlYXJCaXQoYnVpbGRlckJpdEluZGV4KTsKKworICAvLyBGb3IgcmVwZWF0ZWQgZmllbGRzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHdoZXRoZXIgdGhlIGFycmF5IGlzIGltbXV0YWJsZQorICAvLyBpbiB0aGUgcGFyc2luZyBjb25zdHJ1Y3Rvci4KKyAgKCp2YXJpYWJsZXMpWyJnZXRfbXV0YWJsZV9iaXRfcGFyc2VyIl0gPQorICAgICAgR2VuZXJhdGVHZXRCaXRNdXRhYmxlTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfbXV0YWJsZV9iaXRfcGFyc2VyIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRNdXRhYmxlTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKworICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2Zyb21fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdEZyb21Mb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKG1lc3NhZ2VCaXRJbmRleCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpIHsKKyAgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8sICZ2YXJpYWJsZXNfKTsKK30KKworSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6On5JbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCitpbnQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSAkZmllbGRfdHlwZSQgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJGZpZWxkX3R5cGUkICRuYW1lJF8gJGRlZmF1bHRfaW5pdCQ7XG4iKTsKKworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iKTsKKyAgSmF2YVR5cGUgdHlwZSA9IEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKTsKKyAgaWYgKHR5cGUgPT0gSkFWQVRZUEVfU1RSSU5HIHx8IHR5cGUgPT0gSkFWQVRZUEVfQllURVMpIHsKKyAgICAvLyBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBub3QgYSBzaW1wbGUgbGl0ZXJhbCBzbyB3ZSB3YW50IHRvIGF2b2lkIGV4ZWN1dGluZworICAgIC8vIGl0IG11bHRpcGxlIHRpbWVzLiAgSW5zdGVhZCwgZ2V0IHRoZSBkZWZhdWx0IG91dCBvZiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgJG5hbWUkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgICRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iCisgICAgIiRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpICE9ICRkZWZhdWx0JCkge1xuIgorICAgICAgIiAgc2V0JGNhcGl0YWxpemVkX25hbWUkKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICIkbmFtZSRfID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcy4KK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpXG4iCisgICAgICAgICIgICAgPT0gb3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQ6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gcmVzdWx0ICYmIChcbiIKKyAgICAgICAgIiAgICBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpXG4iCisgICAgICAgICIgICAgPT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKFxuIgorICAgICAgICAiICAgICAgICBvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiAoXG4iCisgICAgICAgICIgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKVxuIgorICAgICAgICAiICAgID09IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhcbiIKKyAgICAgICAgIiAgICAgICAgb3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKVxuIgorICAgICAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIpOworICBzd2l0Y2ggKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfTE9ORzoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKFxuIgorICAgICAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbihcbiIKKyAgICAgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9GTE9BVDoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoXG4iCisgICAgICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoXG4iCisgICAgICAgICIgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKSk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkc6CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUzoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5oYXNoQ29kZSgpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgICAgYnJlYWs7CisgIH0KK30KKworc3RyaW5nIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9CisgICAgICBjb250ZXh0LT5HZXRPbmVvZkdlbmVyYXRvckluZm8oZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJGJveGVkX3R5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKK30KKworCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJGJveGVkX3R5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgICAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICByZXN1bHQuJG9uZW9mX25hbWUkXyA9ICRvbmVvZl9uYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiJG9uZW9mX25hbWUkXyA9IGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKFxuIgorICAgICIgICAgICAkbnVtYmVyJCwgKCR0eXBlJCkoKCRib3hlZF90eXBlJCkgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZShcbiIKKyAgICAiICAgICAgICAkbnVtYmVyJCwgKCR0eXBlJCkoKCRib3hlZF90eXBlJCkgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK35SZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDwkYm94ZWRfdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCk7XG4iKTsKK30KKworCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJGZpZWxkX2xpc3RfdHlwZSQgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JGJveGVkX3R5cGUkPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIgICAvLyBub3RlOiAgdW5tb2RpZmlhYmxlIGxpc3QKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkgJiYKKyAgICAgIEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBpbnQgJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gT25lIGZpZWxkIGlzIHRoZSBsaXN0IGFuZCB0aGUgYml0IGZpZWxkIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgdGhlCisgIC8vIGxpc3QgaXMgaW1tdXRhYmxlLiBJZiBpdCdzIGltbXV0YWJsZSwgdGhlIGludmFyaWFudCBpcyB0aGF0IGl0IG11c3QKKyAgLy8gZWl0aGVyIGFuIGluc3RhbmNlIG9mIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpIG9yIGl0J3MgYW4gQXJyYXlMaXN0CisgIC8vIHdyYXBwZWQgaW4gYSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCkgd3JhcHBlciBhbmQgbm9ib2R5IGVsc2UgaGFzCisgIC8vIGEgcmVmZXJlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgQXJyYXlMaXN0LiBUaGlzIGludmFyaWFudCBhbGxvd3MgdXMgdG8KKyAgLy8gc2hhcmUgaW5zdGFuY2VzIG9mIGxpc3RzIGJldHdlZW4gcHJvdG9jb2wgYnVmZmVycyBhdm9pZGluZyBleHBlbnNpdmUKKyAgLy8gbWVtb3J5IGFsbG9jYXRpb25zLiBOb3RlLCBpbW11dGFibGUgaXMgYSBzdHJvbmcgZ3VhcmFudGVlIGhlcmUgLS0gbm90CisgIC8vIGp1c3QgdGhhdCB0aGUgbGlzdCBjYW5ub3QgYmUgbW9kaWZpZWQgdmlhIHRoZSByZWZlcmVuY2UgYnV0IHRoYXQgdGhlCisgIC8vIGxpc3QgY2FuIG5ldmVyIGJlIG1vZGlmaWVkLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlICRmaWVsZF9saXN0X3R5cGUkICRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCkge1xuIgorICAgICIgIGlmICghJGdldF9tdXRhYmxlX2JpdF9idWlsZGVyJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PCRib3hlZF90eXBlJD4oJG5hbWUkXyk7XG4iCisgICAgIiAgICAkc2V0X211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgICB9XG4iCisgICAgIn1cbiIpOworCisgICAgLy8gTm90ZTogIFdlIHJldHVybiBhbiB1bm1vZGlmaWFibGUgbGlzdCBiZWNhdXNlIG90aGVyd2lzZSB0aGUgY2FsbGVyCisgICAgLy8gICBjb3VsZCBob2xkIG9uIHRvIHRoZSByZXR1cm5lZCBsaXN0IGFuZCBtb2RpZnkgaXQgYWZ0ZXIgdGhlIG1lc3NhZ2UKKyAgICAvLyAgIGhhcyBiZWVuIGJ1aWx0LCB0aHVzIG11dGF0aW5nIHRoZSBtZXNzYWdlIHdoaWNoIGlzIHN1cHBvc2VkIHRvIGJlCisgICAgLy8gICBpbW11dGFibGUuCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkYm94ZWRfdHlwZSQ+XG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkge1xuIgorICAgICIgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLnNldChpbmRleCwgdmFsdWUpO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQodmFsdWUpO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyAkYm94ZWRfdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbChcbiIKKyAgICAiICAgICAgdmFsdWVzLCAkbmFtZSRfKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iCisgICAgIiAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBwcmltaXRpdmVzCit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iCisgICAgIiRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBkb2VzIHR3byBvcHRpbWl6YXRpb25zOgorICAvLyAgIDEuIElmIHRoZSBvdGhlciBsaXN0IGlzIGVtcHR5LCB0aGVyZSdzIG5vdGhpbmcgdG8gZG8uIFRoaXMgZW5zdXJlcyB3ZQorICAvLyAgICAgIGRvbid0IGFsbG9jYXRlIGEgbmV3IGFycmF5IGlmIHdlIGFscmVhZHkgaGF2ZSBhbiBpbW11dGFibGUgb25lLgorICAvLyAgIDIuIElmIHRoZSBvdGhlciBsaXN0IGlzIG5vbi1lbXB0eSBhbmQgb3VyIGN1cnJlbnQgbGlzdCBpcyBlbXB0eSwgd2UgY2FuCisgIC8vICAgICAgcmV1c2UgdGhlIG90aGVyIGxpc3Qgd2hpY2ggaXMgZ3VhcmFudGVlZCB0byBiZSBpbW11dGFibGUuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghb3RoZXIuJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICIgICAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkQWxsKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBlbnN1cmVzIHRoYXQgdGhlIHJlc3VsdCBoYXMgYW4gaW1tdXRhYmxlIGxpc3QuIElmIG91cgorICAvLyBsaXN0IGlzIGltbXV0YWJsZSwgd2UgY2FuIGp1c3QgcmV1c2UgaXQuIElmIG5vdCwgd2UgbWFrZSBpdCBpbW11dGFibGUuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCRuYW1lJF8pO1xuIgorICAgICIgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAifVxuIgorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JGJveGVkX3R5cGUkPigpO1xuIgorICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAifVxuIgorICAgICIkbmFtZSRfLmFkZChpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7XG4iCisgICAgImludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpO1xuIgorICAgICJpZiAoISRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCAmJiBpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JGJveGVkX3R5cGUkPigpO1xuIgorICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAifVxuIgorICAgICJ3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQoaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpKTtcbiIKKyAgICAifVxuIgorICAgICJpbnB1dC5wb3BMaW1pdChsaW1pdCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIC8vIFdlIGludm9rZSBnZXRTZXJpYWxpemVkU2l6ZSBpbiB3cml0ZVRvIGZvciBtZXNzYWdlcyB0aGF0IGhhdmUgcGFja2VkCisgICAgLy8gZmllbGRzIGluIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzLgorICAgIC8vIFRoYXQgbWFrZXMgaXQgc2FmZSB0byByZWx5IG9uIHRoZSBtZW1vaXplZCBzaXplIGhlcmUuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKSA+IDApIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCR0YWckKTtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemUpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJE5vVGFnKCRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKCRudW1iZXIkLCAkbmFtZSRfLmdldChpKSk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YVNpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGlmIChGaXhlZFNpemUoR2V0VHlwZShkZXNjcmlwdG9yXykpID09IC0xKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAgICIgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplTm9UYWcoJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZGF0YVNpemUgPSAkZml4ZWRfc2l6ZSQgKiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICJzaXplICs9IGRhdGFTaXplO1xuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICghZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmlzRW1wdHkoKSkge1xuIgorICAgICAgIiAgc2l6ZSArPSAkdGFnX3NpemUkO1xuIgorICAgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgICAiICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpO1xuIik7CisgIH0KKworICAvLyBjYWNoZSB0aGUgZGF0YSBzaXplIGZvciBwYWNrZWQgZmllbGRzLgorICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplO1xuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpXG4iCisgICAgIiAgICAuZXF1YWxzKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkgPiAwKSB7XG4iCisgICAgIiAgaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICIgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5oYXNoQ29kZSgpO1xuIgorICAgICJ9XG4iKTsKK30KKworc3RyaW5nIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwY2QxMmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuaApAQCAtMCwwICsxLDE2MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1BSSU1JVElWRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfUFJJTUlUSVZFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IKKyAgICA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIHZpcnR1YWwgflJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworICBzdHJpbmcgR2V0Qm94ZWRUeXBlKCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9QUklNSVRJVkVfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmFlYWQxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5jYwpAQCAtMCwwICsxLDQ3MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK1NlcnZpY2VHZW5lcmF0b3I6OlNlcnZpY2VHZW5lcmF0b3IoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikge30KKworU2VydmljZUdlbmVyYXRvcjo6flNlcnZpY2VHZW5lcmF0b3IoKSB7fQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yKAorICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBDb250ZXh0KiBjb250ZXh0KQorICAgIDogU2VydmljZUdlbmVyYXRvcihkZXNjcmlwdG9yKSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpIHt9CisKK0ltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6On5JbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBib29sIGlzX293bl9maWxlID0KKyAgICBNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpLCAvKiBpbW11dGFibGUgPSAqLyB0cnVlKTsKKyAgV3JpdGVTZXJ2aWNlRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgJHN0YXRpYyQgYWJzdHJhY3QgY2xhc3MgJGNsYXNzbmFtZSRcbiIKKyAgICAiICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlIHtcbiIsCisgICAgInN0YXRpYyIsIGlzX293bl9maWxlID8gIiIgOiAic3RhdGljIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwcm90ZWN0ZWQgJGNsYXNzbmFtZSQoKSB7fVxuXG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKworICBHZW5lcmF0ZUludGVyZmFjZShwcmludGVyKTsKKworICBHZW5lcmF0ZU5ld1JlZmxlY3RpdmVTZXJ2aWNlTWV0aG9kKHByaW50ZXIpOworICBHZW5lcmF0ZU5ld1JlZmxlY3RpdmVCbG9ja2luZ1NlcnZpY2VNZXRob2QocHJpbnRlcik7CisKKyAgR2VuZXJhdGVBYnN0cmFjdE1ldGhvZHMocHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgZ2V0RGVzY3JpcHRvcigpIGFuZCBnZXREZXNjcmlwdG9yRm9yVHlwZSgpLgorICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyBmaW5hbFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvclxuIgorICAgICIgICAgZ2V0RGVzY3JpcHRvcigpIHtcbiIKKyAgICAiICByZXR1cm4gJGZpbGUkLmdldERlc2NyaXB0b3IoKS5nZXRTZXJ2aWNlcygpLmdldCgkaW5kZXgkKTtcbiIKKyAgICAifVxuIiwKKyAgICAiZmlsZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSksCisgICAgImluZGV4IiwgU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+aW5kZXgoKSkpOworICBHZW5lcmF0ZUdldERlc2NyaXB0b3JGb3JUeXBlKHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIG1vcmUgc3R1ZmYuCisgIEdlbmVyYXRlQ2FsbE1ldGhvZChwcmludGVyKTsKKyAgR2VuZXJhdGVHZXRQcm90b3R5cGUoUkVRVUVTVCwgcHJpbnRlcik7CisgIEdlbmVyYXRlR2V0UHJvdG90eXBlKFJFU1BPTlNFLCBwcmludGVyKTsKKyAgR2VuZXJhdGVTdHViKHByaW50ZXIpOworICBHZW5lcmF0ZUJsb2NraW5nU3R1YihwcmludGVyKTsKKworICAvLyBBZGQgYW4gaW5zZXJ0aW9uIHBvaW50LgorICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUdldERlc2NyaXB0b3JGb3JUeXBlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvclxuIgorICAgICIgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7XG4iCisgICAgIiAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVJbnRlcmZhY2UoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoInB1YmxpYyBpbnRlcmZhY2UgSW50ZXJmYWNlIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgR2VuZXJhdGVBYnN0cmFjdE1ldGhvZHMocHJpbnRlcik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVOZXdSZWZsZWN0aXZlU2VydmljZU1ldGhvZCgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2UgbmV3UmVmbGVjdGl2ZVNlcnZpY2UoXG4iCisgICAgIiAgICBmaW5hbCBJbnRlcmZhY2UgaW1wbCkge1xuIgorICAgICIgIHJldHVybiBuZXcgJGNsYXNzbmFtZSQoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIHByaW50ZXItPlByaW50KCJAamF2YS5sYW5nLk92ZXJyaWRlXG4iKTsKKyAgICBHZW5lcmF0ZU1ldGhvZFNpZ25hdHVyZShwcmludGVyLCBtZXRob2QsIElTX0NPTkNSRVRFKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIge1xuIgorICAgICAgIiAgaW1wbC4kbWV0aG9kJChjb250cm9sbGVyLCByZXF1ZXN0LCBkb25lKTtcbiIKKyAgICAgICJ9XG5cbiIsCisgICAgICAibWV0aG9kIiwgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShtZXRob2QpKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn07XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZU5ld1JlZmxlY3RpdmVCbG9ja2luZ1NlcnZpY2VNZXRob2QoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1NlcnZpY2VcbiIKKyAgICAiICAgIG5ld1JlZmxlY3RpdmVCbG9ja2luZ1NlcnZpY2UoZmluYWwgQmxvY2tpbmdJbnRlcmZhY2UgaW1wbCkge1xuIgorICAgICIgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1NlcnZpY2UoKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIEdlbmVyYXRlR2V0RGVzY3JpcHRvckZvclR5cGUocHJpbnRlcik7CisKKyAgR2VuZXJhdGVDYWxsQmxvY2tpbmdNZXRob2QocHJpbnRlcik7CisgIEdlbmVyYXRlR2V0UHJvdG90eXBlKFJFUVVFU1QsIHByaW50ZXIpOworICBHZW5lcmF0ZUdldFByb3RvdHlwZShSRVNQT05TRSwgcHJpbnRlcik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifTtcbiIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlQWJzdHJhY3RNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIFdyaXRlTWV0aG9kRG9jQ29tbWVudChwcmludGVyLCBtZXRob2QpOworICAgIEdlbmVyYXRlTWV0aG9kU2lnbmF0dXJlKHByaW50ZXIsIG1ldGhvZCwgSVNfQUJTVFJBQ1QpOworICAgIHByaW50ZXItPlByaW50KCI7XG5cbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVDYWxsTWV0aG9kKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAicHVibGljIGZpbmFsIHZvaWQgY2FsbE1ldGhvZChcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlcixcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSByZXF1ZXN0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazxcbiIKKyAgICAiICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlPiBkb25lKSB7XG4iCisgICAgIiAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihcbiIKKyAgICAiICAgICAgXCJTZXJ2aWNlLmNhbGxNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3Igd3JvbmcgXCIgK1xuIgorICAgICIgICAgICBcInNlcnZpY2UgdHlwZS5cIik7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgdmFyc1sibWV0aG9kIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG1ldGhvZCk7CisgICAgdmFyc1siaW5wdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgIG1ldGhvZC0+aW5wdXRfdHlwZSgpKTsKKyAgICB2YXJzWyJvdXRwdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgIG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJjYXNlICRpbmRleCQ6XG4iCisgICAgICAiICB0aGlzLiRtZXRob2QkKGNvbnRyb2xsZXIsICgkaW5wdXQkKXJlcXVlc3QsXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjVXRpbC48JG91dHB1dCQ+c3BlY2lhbGl6ZUNhbGxiYWNrKFxuIgorICAgICAgIiAgICAgIGRvbmUpKTtcbiIKKyAgICAgICIgIHJldHVybjtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImRlZmF1bHQ6XG4iCisgICAgIiAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcihcIkNhbid0IGdldCBoZXJlLlwiKTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlQ2FsbEJsb2NraW5nTWV0aG9kKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAicHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBjYWxsQmxvY2tpbmdNZXRob2QoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kLFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgcmVxdWVzdClcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VFeGNlcHRpb24ge1xuIgorICAgICIgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oXG4iCisgICAgIiAgICAgIFwiU2VydmljZS5jYWxsQmxvY2tpbmdNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3IgXCIgK1xuIgorICAgICIgICAgICBcIndyb25nIHNlcnZpY2UgdHlwZS5cIik7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgdmFyc1sibWV0aG9kIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG1ldGhvZCk7CisgICAgdmFyc1siaW5wdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgIG1ldGhvZC0+aW5wdXRfdHlwZSgpKTsKKyAgICB2YXJzWyJvdXRwdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgIG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJjYXNlICRpbmRleCQ6XG4iCisgICAgICAiICByZXR1cm4gaW1wbC4kbWV0aG9kJChjb250cm9sbGVyLCAoJGlucHV0JClyZXF1ZXN0KTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImRlZmF1bHQ6XG4iCisgICAgIiAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcihcIkNhbid0IGdldCBoZXJlLlwiKTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlR2V0UHJvdG90eXBlKFJlcXVlc3RPclJlc3BvbnNlIHdoaWNoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvKgorICAgKiBUT0RPKGNwb3ZpcmspOiBUaGUgZXhjZXB0aW9uIG1lc3NhZ2Ugc2F5cyAiU2VydmljZS5mb28iIHdoZW4gaXQgbWF5IGJlCisgICAqICJCbG9ja2luZ1NlcnZpY2UuZm9vLiIgIENvbnNpZGVyIGZpeGluZy4KKyAgICovCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlXG4iCisgICAgIiAgICBnZXQkcmVxdWVzdF9vcl9yZXNwb25zZSRQcm90b3R5cGUoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKSB7XG4iCisgICAgIiAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihcbiIKKyAgICAiICAgICAgXCJTZXJ2aWNlLmdldCRyZXF1ZXN0X29yX3Jlc3BvbnNlJFByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCBcIiArXG4iCisgICAgIiAgICAgIFwiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLlwiKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7XG4iLAorICAgICJyZXF1ZXN0X29yX3Jlc3BvbnNlIiwgKHdoaWNoID09IFJFUVVFU1QpID8gIlJlcXVlc3QiIDogIlJlc3BvbnNlIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgdmFyc1sidHlwZSJdID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICh3aGljaCA9PSBSRVFVRVNUKSA/IG1ldGhvZC0+aW5wdXRfdHlwZSgpIDogbWV0aG9kLT5vdXRwdXRfdHlwZSgpKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgImNhc2UgJGluZGV4JDpcbiIKKyAgICAgICIgIHJldHVybiAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJkZWZhdWx0OlxuIgorICAgICIgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoXCJDYW4ndCBnZXQgaGVyZS5cIik7XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZVN0dWIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgU3R1YiBuZXdTdHViKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGNoYW5uZWwpIHtcbiIKKyAgICAiICByZXR1cm4gbmV3IFN0dWIoY2hhbm5lbCk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3R1YiBleHRlbmRzICRjbGFzc25hbWUkIGltcGxlbWVudHMgSW50ZXJmYWNlIHsiCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSBTdHViKGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7XG4iCisgICAgIiAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcbiIKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAicHJpdmF0ZSBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgY2hhbm5lbDtcbiIKKyAgICAiXG4iCisgICAgInB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgZ2V0Q2hhbm5lbCgpIHtcbiIKKyAgICAiICByZXR1cm4gY2hhbm5lbDtcbiIKKyAgICAifVxuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgR2VuZXJhdGVNZXRob2RTaWduYXR1cmUocHJpbnRlciwgbWV0aG9kLCBJU19DT05DUkVURSk7CisgICAgcHJpbnRlci0+UHJpbnQoIiB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpKTsKKyAgICB2YXJzWyJvdXRwdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgIG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJjaGFubmVsLmNhbGxNZXRob2QoXG4iCisgICAgICAiICBnZXREZXNjcmlwdG9yKCkuZ2V0TWV0aG9kcygpLmdldCgkaW5kZXgkKSxcbiIKKyAgICAgICIgIGNvbnRyb2xsZXIsXG4iCisgICAgICAiICByZXF1ZXN0LFxuIgorICAgICAgIiAgJG91dHB1dCQuZ2V0RGVmYXVsdEluc3RhbmNlKCksXG4iCisgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY1V0aWwuZ2VuZXJhbGl6ZUNhbGxiYWNrKFxuIgorICAgICAgIiAgICBkb25lLFxuIgorICAgICAgIiAgICAkb3V0cHV0JC5jbGFzcyxcbiIKKyAgICAgICIgICAgJG91dHB1dCQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTtcbiIpOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUJsb2NraW5nU3R1Yihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyBCbG9ja2luZ0ludGVyZmFjZSBuZXdCbG9ja2luZ1N0dWIoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nUnBjQ2hhbm5lbCBjaGFubmVsKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyBCbG9ja2luZ1N0dWIoY2hhbm5lbCk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIGludGVyZmFjZSBCbG9ja2luZ0ludGVyZmFjZSB7Iik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIEdlbmVyYXRlQmxvY2tpbmdNZXRob2RTaWduYXR1cmUocHJpbnRlciwgbWV0aG9kKTsKKyAgICBwcmludGVyLT5QcmludCgiO1xuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEJsb2NraW5nU3R1YiBpbXBsZW1lbnRzIEJsb2NraW5nSW50ZXJmYWNlIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSBCbG9ja2luZ1N0dWIoY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbCkge1xuIgorICAgICIgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInByaXZhdGUgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbDtcbiIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIEdlbmVyYXRlQmxvY2tpbmdNZXRob2RTaWduYXR1cmUocHJpbnRlciwgbWV0aG9kKTsKKyAgICBwcmludGVyLT5QcmludCgiIHtcbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHZhcnNbIm91dHB1dCJdID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICAgbWV0aG9kLT5vdXRwdXRfdHlwZSgpKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInJldHVybiAoJG91dHB1dCQpIGNoYW5uZWwuY2FsbEJsb2NraW5nTWV0aG9kKFxuIgorICAgICAgIiAgZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoJGluZGV4JCksXG4iCisgICAgICAiICBjb250cm9sbGVyLFxuIgorICAgICAgIiAgcmVxdWVzdCxcbiIKKyAgICAgICIgICRvdXRwdXQkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIpOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVNZXRob2RTaWduYXR1cmUoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXNBYnN0cmFjdCBpc19hYnN0cmFjdCkgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbIm5hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UobWV0aG9kKTsKKyAgdmFyc1siaW5wdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUobWV0aG9kLT5pbnB1dF90eXBlKCkpOworICB2YXJzWyJvdXRwdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUobWV0aG9kLT5vdXRwdXRfdHlwZSgpKTsKKyAgdmFyc1siYWJzdHJhY3QiXSA9IChpc19hYnN0cmFjdCA9PSBJU19BQlNUUkFDVCkgPyAiYWJzdHJhY3QiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgInB1YmxpYyAkYWJzdHJhY3QkIHZvaWQgJG5hbWUkKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsXG4iCisgICAgIiAgICAkaW5wdXQkIHJlcXVlc3QsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPCRvdXRwdXQkPiBkb25lKSIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlQmxvY2tpbmdNZXRob2RTaWduYXR1cmUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1sibWV0aG9kIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG1ldGhvZCk7CisgIHZhcnNbImlucHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKG1ldGhvZC0+aW5wdXRfdHlwZSgpKTsKKyAgdmFyc1sib3V0cHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIlxuIgorICAgICJwdWJsaWMgJG91dHB1dCQgJG1ldGhvZCQoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlcixcbiIKKyAgICAiICAgICRpbnB1dCQgcmVxdWVzdClcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VFeGNlcHRpb24iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjcwN2U4MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuaApAQCAtMCwwICsxLDEzNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1NFUlZJQ0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1NFUlZJQ0VfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgIC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgU2VydmljZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBTZXJ2aWNlR2VuZXJhdG9yKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+U2VydmljZUdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgPSAwOworCisgIGVudW0gUmVxdWVzdE9yUmVzcG9uc2UgeyBSRVFVRVNULCBSRVNQT05TRSB9OworICBlbnVtIElzQWJzdHJhY3QgeyBJU19BQlNUUkFDVCwgSVNfQ09OQ1JFVEUgfTsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFNlcnZpY2VHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvciA6IHB1YmxpYyBTZXJ2aWNlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3IoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCk7CisgIHZpcnR1YWwgfkltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKworICAvLyBHZW5lcmF0ZSB0aGUgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSBtZXRob2QuCisgIHZvaWQgR2VuZXJhdGVHZXREZXNjcmlwdG9yRm9yVHlwZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgYSBKYXZhIGludGVyZmFjZSBmb3IgdGhlIHNlcnZpY2UuCisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2UoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIG5ld1JlZmxlY3RpdmVTZXJ2aWNlKCkgbWV0aG9kLgorICB2b2lkIEdlbmVyYXRlTmV3UmVmbGVjdGl2ZVNlcnZpY2VNZXRob2QoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIG5ld1JlZmxlY3RpdmVCbG9ja2luZ1NlcnZpY2UoKSBtZXRob2QuCisgIHZvaWQgR2VuZXJhdGVOZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlTWV0aG9kKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBhYnN0cmFjdCBtZXRob2QgZGVjbGFyYXRpb25zIGZvciBhbGwgbWV0aG9kcy4KKyAgdm9pZCBHZW5lcmF0ZUFic3RyYWN0TWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGltcGxlbWVudGF0aW9uIG9mIFNlcnZpY2UuY2FsbE1ldGhvZCgpLgorICB2b2lkIEdlbmVyYXRlQ2FsbE1ldGhvZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGltcGxlbWVudGF0aW9uIG9mIEJsb2NraW5nU2VydmljZS5jYWxsQmxvY2tpbmdNZXRob2QoKS4KKyAgdm9pZCBHZW5lcmF0ZUNhbGxCbG9ja2luZ01ldGhvZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGltcGxlbWVudGF0aW9ucyBvZiBTZXJ2aWNlLmdldHtSZXF1ZXN0LFJlc3BvbnNlfVByb3RvdHlwZSgpLgorICB2b2lkIEdlbmVyYXRlR2V0UHJvdG90eXBlKFJlcXVlc3RPclJlc3BvbnNlIHdoaWNoLCBpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgYSBzdHViIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzZXJ2aWNlLgorICB2b2lkIEdlbmVyYXRlU3R1Yihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgYSBtZXRob2Qgc2lnbmF0dXJlLCBwb3NzaWJseSBhYnN0cmFjdCwgd2l0aG91dCBib2R5IG9yIHRyYWlsaW5nCisgIC8vIHNlbWljb2xvbi4KKyAgdm9pZCBHZW5lcmF0ZU1ldGhvZFNpZ25hdHVyZShpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXNBYnN0cmFjdCBpc19hYnN0cmFjdCk7CisKKyAgLy8gR2VuZXJhdGUgYSBibG9ja2luZyBzdHViIGludGVyZmFjZSBhbmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UuCisgIHZvaWQgR2VuZXJhdGVCbG9ja2luZ1N0dWIoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHRoZSBtZXRob2Qgc2lnbmF0dXJlIGZvciBvbmUgbWV0aG9kIG9mIGEgYmxvY2tpbmcgc3R1Yi4KKyAgdm9pZCBHZW5lcmF0ZUJsb2NraW5nTWV0aG9kU2lnbmF0dXJlKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKTsKKworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworI2VuZGlmICAvLyBORVRfUFJPVE8yX0NPTVBJTEVSX0pBVkFfU0VSVklDRV9IX18KK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDE3NzM2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2hhcmVkX2NvZGVfZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsMjA1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB4aWFvZmVuZ0Bnb29nbGUuY29tIChGZW5nIFhpYW8pCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitTaGFyZWRDb2RlR2VuZXJhdG9yOjpTaGFyZWRDb2RlR2VuZXJhdG9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKQorICA6IG5hbWVfcmVzb2x2ZXJfKG5ldyBDbGFzc05hbWVSZXNvbHZlciksIGZpbGVfKGZpbGUpIHsKK30KKworU2hhcmVkQ29kZUdlbmVyYXRvcjo6flNoYXJlZENvZGVHZW5lcmF0b3IoKSB7Cit9CisKK3ZvaWQgU2hhcmVkQ29kZUdlbmVyYXRvcjo6R2VuZXJhdGUoR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGZpbGVfbGlzdCkgeworICBzdHJpbmcgamF2YV9wYWNrYWdlID0gRmlsZUphdmFQYWNrYWdlKGZpbGVfKTsKKyAgc3RyaW5nIHBhY2thZ2VfZGlyID0gSmF2YVBhY2thZ2VUb0RpcihqYXZhX3BhY2thZ2UpOworCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAvLyBHZW5lcmF0ZSBkZXNjcmlwdG9ycy4KKyAgICBzdHJpbmcgY2xhc3NuYW1lID0gbmFtZV9yZXNvbHZlcl8tPkdldERlc2NyaXB0b3JDbGFzc05hbWUoZmlsZV8pOworICAgIHN0cmluZyBmaWxlbmFtZSA9IHBhY2thZ2VfZGlyICsgY2xhc3NuYW1lICsgIi5qYXZhIjsKKyAgICBmaWxlX2xpc3QtPnB1c2hfYmFjayhmaWxlbmFtZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dChjb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6UHJpbnRlcj4gcHJpbnRlcihuZXcgaW86OlByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgICAiLy8gc291cmNlOiAkZmlsZW5hbWUkXG4iCisgICAgICAiXG4iLAorICAgICAgImZpbGVuYW1lIiwgZmlsZV8tPm5hbWUoKSk7CisgICAgaWYgKCFqYXZhX3BhY2thZ2UuZW1wdHkoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwYWNrYWdlICRwYWNrYWdlJDtcbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgInBhY2thZ2UiLCBqYXZhX3BhY2thZ2UpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgZmluYWwgY2xhc3MgJGNsYXNzbmFtZSQge1xuIgorICAgICAgIiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yXG4iCisgICAgICAiICAgICAgZGVzY3JpcHRvcjtcbiIKKyAgICAgICIgIHN0YXRpYyB7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgR2VuZXJhdGVEZXNjcmlwdG9ycyhwcmludGVyLmdldCgpKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworCisgICAgcHJpbnRlci5yZXNldCgpOworICAgIG91dHB1dC5yZXNldCgpOworICB9Cit9CisKKwordm9pZCBTaGFyZWRDb2RlR2VuZXJhdG9yOjpHZW5lcmF0ZURlc2NyaXB0b3JzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEVtYmVkIHRoZSBkZXNjcmlwdG9yLiAgV2Ugc2ltcGx5IHNlcmlhbGl6ZSB0aGUgZW50aXJlIEZpbGVEZXNjcmlwdG9yUHJvdG8KKyAgLy8gYW5kIGVtYmVkIGl0IGFzIGEgc3RyaW5nIGxpdGVyYWwsIHdoaWNoIGlzIHBhcnNlZCBhbmQgYnVpbHQgaW50byByZWFsCisgIC8vIGRlc2NyaXB0b3JzIGF0IGluaXRpYWxpemF0aW9uIHRpbWUuICBXZSB1bmZvcnR1bmF0ZWx5IGhhdmUgdG8gcHV0IGl0IGluCisgIC8vIGEgc3RyaW5nIGxpdGVyYWwsIG5vdCBhIGJ5dGUgYXJyYXksIGJlY2F1c2UgYXBwYXJlbnRseSB1c2luZyBhIGxpdGVyYWwKKyAgLy8gYnl0ZSBhcnJheSBjYXVzZXMgdGhlIEphdmEgY29tcGlsZXIgdG8gZ2VuZXJhdGUgKmluc3RydWN0aW9ucyogdG8KKyAgLy8gaW5pdGlhbGl6ZSBlYWNoIGFuZCBldmVyeSBieXRlIG9mIHRoZSBhcnJheSwgZS5nLiBhcyBpZiB5b3UgdHlwZWQ6CisgIC8vICAgYlswXSA9IDEyMzsgYlsxXSA9IDQ1NjsgYlsyXSA9IDc4OTsKKyAgLy8gVGhpcyBtYWtlcyBodWdlIGJ5dGVjb2RlIGZpbGVzIGFuZCBjYW4gZWFzaWx5IGhpdCB0aGUgY29tcGlsZXIncyBpbnRlcm5hbAorICAvLyBjb2RlIHNpemUgbGltaXRzIChlcnJvciAiY29kZSB0byBsYXJnZSIpLiAgU3RyaW5nIGxpdGVyYWxzIGFyZSBhcHBhcmVudGx5CisgIC8vIGVtYmVkZGVkIHJhdywgd2hpY2ggaXMgd2hhdCB3ZSB3YW50LgorICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIGZpbGVfLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworCisKKyAgc3RyaW5nIGZpbGVfZGF0YTsKKyAgZmlsZV9wcm90by5TZXJpYWxpemVUb1N0cmluZygmZmlsZV9kYXRhKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0ge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIE9ubHkgd3JpdGUgNDAgYnl0ZXMgcGVyIGxpbmUuCisgIHN0YXRpYyBjb25zdCBpbnQga0J5dGVzUGVyTGluZSA9IDQwOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfZGF0YS5zaXplKCk7IGkgKz0ga0J5dGVzUGVyTGluZSkgeworICAgIGlmIChpID4gMCkgeworICAgICAgLy8gRXZlcnkgNDAwIGxpbmVzLCBzdGFydCBhIG5ldyBzdHJpbmcgbGl0ZXJhbCwgaW4gb3JkZXIgdG8gYXZvaWQgdGhlCisgICAgICAvLyA2NGsgbGVuZ3RoIGxpbWl0LgorICAgICAgaWYgKGkgJSA0MDAgPT0gMCkgeworICAgICAgICBwcmludGVyLT5QcmludCgiLFxuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgiICtcbiIpOworICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiXCIkZGF0YSRcIiIsCisgICAgICAiZGF0YSIsIENFc2NhcGUoZmlsZV9kYXRhLnN1YnN0cihpLCBrQnl0ZXNQZXJMaW5lKSkpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgiXG59O1xuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gQ3JlYXRlIHRoZSBJbnRlcm5hbERlc2NyaXB0b3JBc3NpZ25lci4KKworICBwcmludGVyLT5QcmludCgKKyAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci4iCisgICAgIkludGVybmFsRGVzY3JpcHRvckFzc2lnbmVyIGFzc2lnbmVyID1cbiIKKyAgICAiICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yLiIKKyAgICAiICAgIEludGVybmFsRGVzY3JpcHRvckFzc2lnbmVyKCkge1xuIgorICAgICIgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSBhc3NpZ25EZXNjcmlwdG9ycyhcbiIKKyAgICAiICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3Igcm9vdCkge1xuIgorICAgICIgICAgICAgIGRlc2NyaXB0b3IgPSByb290O1xuIgorICAgIC8vIEN1c3RvbSBvcHRpb25zIHdpbGwgYmUgaGFuZGxlZCB3aGVuIGltbXV0YWJsZSBtZXNzYWdlcycgb3V0ZXIgY2xhc3MgaXMKKyAgICAvLyBsb2FkZWQuIEhlcmUgd2UganVzdCByZXR1cm4gbnVsbCBhbmQgbGV0IGN1c3RvbSBvcHRpb25zIGJlIHVua25vd24KKyAgICAvLyBmaWVsZHMuCisgICAgIiAgICAgICAgcmV0dXJuIG51bGw7XG4iCisgICAgIiAgICAgIH1cbiIKKyAgICAiICAgIH07XG4iKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBGaW5kIG91dCBhbGwgZGVwZW5kZW5jaWVzLgorICB2ZWN0b3I8cGFpcjxzdHJpbmcsIHN0cmluZz4gPiBkZXBlbmRlbmNpZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKFNob3VsZEluY2x1ZGVEZXBlbmRlbmN5KGZpbGVfLT5kZXBlbmRlbmN5KGkpKSkgeworICAgICAgc3RyaW5nIGZpbGVuYW1lID0gZmlsZV8tPmRlcGVuZGVuY3koaSktPm5hbWUoKTsKKyAgICAgIHN0cmluZyBjbGFzc25hbWUgPSBGaWxlSmF2YVBhY2thZ2UoZmlsZV8tPmRlcGVuZGVuY3koaSkpICsgIi4iICsKKyAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXy0+R2V0RGVzY3JpcHRvckNsYXNzTmFtZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV8tPmRlcGVuZGVuY3koaSkpOworICAgICAgZGVwZW5kZW5jaWVzLnB1c2hfYmFjayhzdGQ6Om1ha2VfcGFpcihmaWxlbmFtZSwgY2xhc3NuYW1lKSk7CisgICAgfQorICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSW52b2tlIGludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbSgpIHRvIGJ1aWxkIHRoZSBmaWxlLgorICBwcmludGVyLT5QcmludCgKKyAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvclxuIgorICAgICIgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsXG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHtcbiIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3Qgc3RyaW5nJiBkZXBlbmRlbmN5ID0gZGVwZW5kZW5jaWVzW2ldLnNlY29uZDsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgICAgICRkZXBlbmRlbmN5JC5nZXREZXNjcmlwdG9yKCksXG4iLAorICAgICAgICAiZGVwZW5kZW5jeSIsIGRlcGVuZGVuY3kpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgICB9LCBhc3NpZ25lcik7XG4iKTsKK30KKworYm9vbCBTaGFyZWRDb2RlR2VuZXJhdG9yOjpTaG91bGRJbmNsdWRlRGVwZW5kZW5jeSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4YTMyZmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDk0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB4aWFvZmVuZ0Bnb29nbGUuY29tIChGZW5nIFhpYW8pCisvLworLy8gR2VuZXJhdG9ycyB0aGF0IGdlbmVyYXRlIHNoYXJlZCBjb2RlIGJldHdlZW4gaW1tdXRhYmxlIEFQSSBhbmQgbXV0YWJsZSBBUEkuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU0hBUkVEX0NPREVfR0VORVJBVE9SX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9TSEFSRURfQ09ERV9HRU5FUkFUT1JfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBGaWxlRGVzY3JpcHRvcjsgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIGNsYXNzIEdlbmVyYXRvckNvbnRleHQ7ICAgIC8vIGNvZGVfZ2VuZXJhdG9yLmgKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgICAgICAgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKKy8vIEEgZ2VuZXJhdG9yIHRoYXQgZ2VuZXJhdGVzIGNvZGUgdGhhdCBhcmUgc2hhcmVkIGJldHdlZW4gaW1tdXRhYmxlIEFQSQorLy8gYW5kIG11dGFibGUgQVBJLiBDdXJyZW50bHkgb25seSBkZXNjcmlwdG9ycyBhcmUgc2hhcmVkLgorY2xhc3MgU2hhcmVkQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBTaGFyZWRDb2RlR2VuZXJhdG9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKyAgflNoYXJlZENvZGVHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlKEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBmaWxlX2xpc3QpOworCisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9ycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGRlcGVuZGVuY3kgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZS4KKyAgLy8gQWx3YXlzIHJldHVybnMgdHJ1ZSBmb3Igb3BlbnNvdXJjZSwgYnV0IHVzZWQgaW50ZXJuYWxseSBhdCBHb29nbGUgdG8gaGVscAorICAvLyBpbXByb3ZlIGNvbXBhdGliaWxpdHkgd2l0aCB2ZXJzaW9uIDEgb2YgcHJvdG9jb2wgYnVmZmVycy4KKyAgYm9vbCBTaG91bGRJbmNsdWRlRGVwZW5kZW5jeShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxDbGFzc05hbWVSZXNvbHZlcj4gbmFtZV9yZXNvbHZlcl87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFNoYXJlZENvZGVHZW5lcmF0b3IpOworfTsKKworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9TSEFSRURfQ09ERV9HRU5FUkFUT1JfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFhNTY5OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3N0cmluZ19maWVsZC5jYwpAQCAtMCwwICsxLDEwODEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBBdXRob3I6IGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit2b2lkIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJlbXB0eV9saXN0Il0gPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LkVNUFRZIjsKKworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IEltbXV0YWJsZURlZmF1bHRWYWx1ZShkZXNjcmlwdG9yLCBuYW1lX3Jlc29sdmVyKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2luaXQiXSA9CisgICAgICAiPSAiICsgSW1tdXRhYmxlRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IsIG5hbWVfcmVzb2x2ZXIpOworICAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX3R5cGUiXSA9ICJTdHJpbmciOworICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSgKKyAgICAgIFdpcmVGb3JtYXQ6OlRhZ1NpemUoZGVzY3JpcHRvci0+bnVtYmVyKCksIEdldFR5cGUoZGVzY3JpcHRvcikpKTsKKyAgKCp2YXJpYWJsZXMpWyJudWxsX2NoZWNrIl0gPQorICAgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgICAiICB9XG4iOworCisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgICgqdmFyaWFibGVzKVsib25fY2hhbmdlZCJdID0KKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKSA/ICJvbkNoYW5nZWQoKTsiIDogIiI7CisKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3ItPmZpbGUoKSkpIHsKKyAgICAvLyBGb3Igc2luZ3VsYXIgbWVzc2FnZXMgYW5kIGJ1aWxkZXJzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHRoZSBoYXNGaWVsZCBiaXQuCisgICAgKCp2YXJpYWJsZXMpWyJnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVHZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKworICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBoYXZlIGEgdHJhaWxpbmcgIjsiLgorICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVTZXRCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9CisgICAgICAgIEdlbmVyYXRlQ2xlYXJCaXQoYnVpbGRlckJpdEluZGV4KSArICI7IjsKKworICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0KKyAgICAgICAgIiFnZXQiICsgKCp2YXJpYWJsZXMpWyJjYXBpdGFsaXplZF9uYW1lIl0gKyAiQnl0ZXMoKS5pc0VtcHR5KCkiOworICB9CisKKyAgLy8gRm9yIHJlcGVhdGVkIGJ1aWxkZXJzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHdoZXRoZXIgdGhlIGFycmF5IGlzIGltbXV0YWJsZS4KKyAgKCp2YXJpYWJsZXMpWyJnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVHZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVTZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgLy8gRm9yIHJlcGVhdGVkIGZpZWxkcywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUKKyAgLy8gaW4gdGhlIHBhcnNpbmcgY29uc3RydWN0b3IuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgKCp2YXJpYWJsZXMpWyJnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVHZXRCaXRGcm9tTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF90b19sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0VG9Mb2NhbChtZXNzYWdlQml0SW5kZXgpOworfQorCitib29sIENoZWNrVXRmOChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPmZpbGUoKS0+b3B0aW9ucygpLmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKCkge30KKworaW50IEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCisvLyBBIG5vdGUgYWJvdXQgaG93IHN0cmluZ3MgYXJlIGhhbmRsZWQuIFRoaXMgY29kZSB1c2VkIHRvIGp1c3Qgc3RvcmUgYSBTdHJpbmcKKy8vIGluIHRoZSBNZXNzYWdlLiBUaGlzIGhhZCB0d28gaXNzdWVzOgorLy8KKy8vICAxLiBJdCB3b3VsZG4ndCByb3VuZHRyaXAgYnl0ZSBhcnJheXMgdGhhdCB3ZXJlIG5vdCB2YWlkIFVURi04IGVuY29kZWQKKy8vICAgICBzdHJpbmdzLCBidXQgcmF0aGVyIGZpZWxkcyB0aGF0IHdlcmUgcmF3IGJ5dGVzIGluY29ycmVjdGx5IG1hcmtlZAorLy8gICAgIGFzIHN0cmluZ3MgaW4gdGhlIHByb3RvIGZpbGUuIFRoaXMgaXMgY29tbW9uIGJlY2F1c2UgaW4gdGhlIHByb3RvMQorLy8gICAgIHN5bnRheCwgc3RyaW5nIHdhcyB0aGUgd2F5IHRvIGluZGljYXRlIGJ5dGVzIGFuZCBDKysgZW5naW5lZXJzIGNhbgorLy8gICAgIGVhc2lseSBtYWtlIHRoaXMgbWlzdGFrZSB3aXRob3V0IGFmZmVjdGluZyB0aGUgQysrIEFQSS4gQnkgY29udmVydGluZyB0bworLy8gICAgIHN0cmluZ3MgaW1tZWRpYXRlbHksIHNvbWUgamF2YSBjb2RlIG1pZ2h0IGNvcnJ1cHQgdGhlc2UgYnl0ZSBhcnJheXMgYXMKKy8vICAgICBpdCBwYXNzZXMgdGhyb3VnaCBhIGphdmEgc2VydmVyIGV2ZW4gaWYgdGhlIGZpZWxkIHdhcyBuZXZlciBhY2Nlc3NlZCBieQorLy8gICAgIGFwcGxpY2F0aW9uIGNvZGUuCisvLworLy8gIDIuIFRoZXJlJ3MgYSBwZXJmb3JtYW5jZSBoaXQgdG8gY29udmVydGluZyBiZXR3ZWVuIGJ5dGVzIGFuZCBzdHJpbmdzIGFuZAorLy8gICAgIGl0IG1hbnkgY2FzZXMsIHRoZSBmaWVsZCBpcyBuZXZlciBldmVuIHJlYWQgYnkgdGhlIGFwcGxpY2F0aW9uIGNvZGUuIFRoaXMKKy8vICAgICBhdm9pZHMgdW5uZWNlc3NhcnkgY29udmVyc2lvbnMgaW4gdGhlIGNvbW1vbiB1c2UgY2FzZXMuCisvLworLy8gU28gbm93LCB0aGUgZmllbGQgZm9yIFN0cmluZyBpcyBtYWludGFpbmVkIGFzIGFuIE9iamVjdCByZWZlcmVuY2Ugd2hpY2ggY2FuCisvLyBlaXRoZXIgc3RvcmUgYSBTdHJpbmcgb3IgYSBCeXRlU3RyaW5nLiBUaGUgY29kZSB1c2VzIGFuIGluc3RhbmNlb2YgY2hlY2sKKy8vIHRvIHNlZSB3aGljaCBvbmUgaXQgaGFzIGFuZCBjb252ZXJ0cyB0byB0aGUgb3RoZXIgb25lIGlmIG5lZWRlZC4gSXQgcmVtZW1iZXJzCisvLyB0aGUgbGFzdCB2YWx1ZSByZXF1ZXN0ZWQgKGluIGEgdGhyZWFkIHNhZmUgbWFubmVyKSBhcyB0aGlzIGlzIG1vc3QgbGlrZWx5CisvLyB0aGUgb25lIG5lZWRlZCBuZXh0LiBUaGUgdGhyZWFkIHNhZmV0eSBpcyBzdWNoIHRoYXQgaWYgdHdvIHRocmVhZHMgYm90aAorLy8gY29udmVydCB0aGUgZmllbGQgYmVjYXVzZSB0aGUgY2hhbmdlcyBtYWRlIGJ5IGVhY2ggdGhyZWFkIHdlcmUgbm90IHZpc2libGUgdG8KKy8vIHRoZSBvdGhlciwgdGhleSBtYXkgY2F1c2UgYSBjb252ZXJzaW9uIHRvIGhhcHBlbiBtb3JlIHRpbWVzIHRoYW4gd291bGQKKy8vIG90aGVyd2lzZSBiZSBuZWNlc3NhcnkuIFRoaXMgd2FzIGRlZW1lZCBiZXR0ZXIgdGhhbiBhZGRpbmcgc3luY2hyb25pemF0aW9uCisvLyBvdmVyaGVhZC4gSXQgd2lsbCBub3QgY2F1c2UgYW55IGNvcnJ1cHRpb24gaXNzdWVzIG9yIGFmZmVjdCB0aGUgYmVoYXZpb3Igb2YKKy8vIHRoZSBBUEkuIFRoZSBpbnN0YW5jZW9mIGNoZWNrIGlzIGFsc28gaGlnaGx5IG9wdGltaXplZCBpbiB0aGUgSlZNIGFuZCB3ZQorLy8gZGVjaWRlZCBpdCB3YXMgYmV0dGVyIHRvIHJlZHVjZSB0aGUgbWVtb3J5IG92ZXJoZWFkIGJ5IG5vdCBoYXZpbmcgdHdvCisvLyBzZXBhcmF0ZSBmaWVsZHMgYnV0IHJhdGhlciB1c2UgZHluYW1pYyB0eXBlIGNoZWNraW5nLgorLy8KKy8vIEZvciBzaW5nbGUgZmllbGRzLCB0aGUgbG9naWMgZm9yIHRoaXMgaXMgZG9uZSBpbnNpZGUgdGhlIGdlbmVyYXRlZCBjb2RlLiBGb3IKKy8vIHJlcGVhdGVkIGZpZWxkcywgdGhlIGxvZ2ljIGlzIGRvbmUgaW4gTGF6eVN0cmluZ0FycmF5TGlzdCBhbmQKKy8vIFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0Lgordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZ1xuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGphdmEubGFuZy5PYmplY3QgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGphdmEubGFuZy5PYmplY3QgcmVmID0gJG5hbWUkXztcbiIKKyAgICAiICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykge1xuIgorICAgICIgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IFxuIgorICAgICIgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjtcbiIKKyAgICAgICIgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7XG4iKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICAkbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7XG4iCisgICAgICAiICAgICAgJG5hbWUkXyA9IHM7XG4iCisgICAgICAiICAgIH1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICByZXR1cm4gcztcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICRuYW1lJF87XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gXG4iCisgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChcbiIKKyAgICAiICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7XG4iCisgICAgIiAgICAkbmFtZSRfID0gYjtcbiIKKyAgICAiICAgIHJldHVybiBiO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGphdmEubGFuZy5PYmplY3QgJG5hbWUkXyAkZGVmYXVsdF9pbml0JDtcbiIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICRuYW1lJF87XG4iCisgICAgIiAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9XG4iCisgICAgIiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmO1xuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7XG4iKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICAkbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7XG4iCisgICAgICAiICAgICAgJG5hbWUkXyA9IHM7XG4iCisgICAgICAiICAgIH1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICByZXR1cm4gcztcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICRuYW1lJF87XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykge1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSBcbiIKKyAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KFxuIgorICAgICIgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBiO1xuIgorICAgICIgICAgcmV0dXJuIGI7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIik7CisgIC8vIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vdCBhIHNpbXBsZSBsaXRlcmFsIHNvIHdlIHdhbnQgdG8gYXZvaWQgZXhlY3V0aW5nCisgIC8vIGl0IG11bHRpcGxlIHRpbWVzLiAgSW5zdGVhZCwgZ2V0IHRoZSBkZWZhdWx0IG91dCBvZiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkbmFtZSRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHByaW1pdGl2ZXMKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRkZWZhdWx0JDtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIgorICAgICIkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBBbGxvdyBhIHNsaWdodCBicmVhY2ggb2YgYWJzdHJhY3Rpb24gaGVyZSBpbiBvcmRlciB0byBhdm9pZCBmb3JjaW5nCisgICAgLy8gYWxsIHN0cmluZyBmaWVsZHMgdG8gU3RyaW5ncyB3aGVuIGNvcHlpbmcgZmllbGRzIGZyb20gYSBNZXNzYWdlLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAgICIgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoIW90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmlzRW1wdHkoKSkge1xuIgorICAgICAgIiAgJG5hbWUkXyA9IG90aGVyLiRuYW1lJF87XG4iCisgICAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpO1xuIgorICAgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiRuYW1lJF8gPSBzO1xuIik7CisgIH0gZWxzZSBpZiAoIUhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gTGl0ZSBydW50aW1lIHNob3VsZCBhdHRlbXB0IHRvIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBhdHRlbXB0aW5nIHRvCisgICAgLy8gY29uc3RydWN0IHRoZSBzdHJpbmcgZGlyZWN0bHkgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGJ1ZmZlci4gVGhpcyBhdm9pZHMKKyAgICAvLyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsIGFsbG9jYXRpb25zCisgICAgLy8gaW4gaGFsZi4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZygpO1xuIgorICAgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiRuYW1lJF8gPSBzO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTtcbiIKKyAgICAgICIkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAgICIkbmFtZSRfID0gYnM7XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHN0cmluZ3MuCit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVCeXRlcygkbnVtYmVyJCwgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGVCeXRlc1NpemUoJG51bWJlciQsIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpXG4iCisgICAgIiAgICAuZXF1YWxzKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmhhc2hDb2RlKCk7XG4iKTsKK30KKworc3RyaW5nIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiamF2YS5sYW5nLlN0cmluZyI7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9CisgICAgICBjb250ZXh0LT5HZXRPbmVvZkdlbmVyYXRvckluZm8oZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLk9iamVjdCByZWYgJGRlZmF1bHRfaW5pdCQ7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmVmID0gJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHtcbiIKKyAgICAiICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBcbiIKKyAgICAiICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7XG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTtcbiIpOworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSBzO1xuIgorICAgICIgICAgfVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSBzO1xuIgorICAgICIgICAgfVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgIHJldHVybiBzO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZ1xuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLk9iamVjdCByZWYgJGRlZmF1bHRfaW5pdCQ7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmVmID0gJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gXG4iCisgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChcbiIKKyAgICAiICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7XG4iCisgICAgIiAgICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSBiO1xuIgorICAgICIgICAgfVxuIgorICAgICIgICAgcmV0dXJuIGI7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLk9iamVjdCByZWYgJGRlZmF1bHRfaW5pdCQ7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmVmID0gJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9XG4iCisgICAgIiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmO1xuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7XG4iCisgICAgIiAgICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSBzO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkge1xuIgorICAgICAgIiAgICAgICAgJG9uZW9mX25hbWUkXyA9IHM7XG4iCisgICAgICAiICAgICAgfVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgIH1cbiIKKyAgICAiICAgIHJldHVybiBzO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmdcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKCkge1xuIgorICAgICIgIGphdmEubGFuZy5PYmplY3QgcmVmICRkZWZhdWx0X2luaXQkO1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJlZiA9ICRvbmVvZl9uYW1lJF87XG4iCisgICAgIiAgfVxuIgorICAgICIgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gXG4iCisgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChcbiIKKyAgICAiICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7XG4iCisgICAgIiAgICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSBiO1xuIgorICAgICIgICAgfVxuIgorICAgICIgICAgcmV0dXJuIGI7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJGNsZWFyX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiICAgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBBbGxvdyBhIHNsaWdodCBicmVhY2ggb2YgYWJzdHJhY3Rpb24gaGVyZSBpbiBvcmRlciB0byBhdm9pZCBmb3JjaW5nCisgIC8vIGFsbCBzdHJpbmcgZmllbGRzIHRvIFN0cmluZ3Mgd2hlbiBjb3B5aW5nIGZpZWxkcyBmcm9tIGEgTWVzc2FnZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIkb25lb2ZfbmFtZSRfID0gb3RoZXIuJG9uZW9mX25hbWUkXztcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICByZXN1bHQuJG9uZW9mX25hbWUkXyA9ICRvbmVvZl9uYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTtcbiIKKyAgICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAiJG9uZW9mX25hbWUkXyA9IHM7XG4iKTsKKyAgfSBlbHNlIGlmICghSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBMaXRlIHJ1bnRpbWUgc2hvdWxkIGF0dGVtcHQgdG8gcmVkdWNlIGFsbG9jYXRpb25zIGJ5IGF0dGVtcHRpbmcgdG8KKyAgICAvLyBjb25zdHJ1Y3QgdGhlIHN0cmluZyBkaXJlY3RseSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gYnVmZmVyLiBUaGlzIGF2b2lkcworICAgIC8vIHNwdXJpb3VzIGludGVybWVkaWFyeSBCeXRlU3RyaW5nIGFsbG9jYXRpb25zLCBjdXR0aW5nIG92ZXJhbGwgYWxsb2NhdGlvbnMKKyAgICAvLyBpbiBoYWxmLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nKCk7XG4iCisgICAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiRvbmVvZl9uYW1lJF8gPSBzO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTtcbiIKKyAgICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAiJG9uZW9mX25hbWUkXyA9IGJzO1xuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZUJ5dGVzKCRudW1iZXIkLCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgkbnVtYmVyJCwgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKSk7XG4iCisgICAgIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK1JlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorflJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoKSB7fQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0XG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmdcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKGludCBpbmRleCk7XG4iKTsKK30KKworCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nTGlzdCAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIgICAvLyBub3RlOiAgdW5tb2RpZmlhYmxlIGxpc3QKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkgJiYKKyAgICAgIEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBpbnQgJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gT25lIGZpZWxkIGlzIHRoZSBsaXN0IGFuZCB0aGUgYml0IGZpZWxkIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgdGhlCisgIC8vIGxpc3QgaXMgaW1tdXRhYmxlLiBJZiBpdCdzIGltbXV0YWJsZSwgdGhlIGludmFyaWFudCBpcyB0aGF0IGl0IG11c3QKKyAgLy8gZWl0aGVyIGFuIGluc3RhbmNlIG9mIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpIG9yIGl0J3MgYW4gQXJyYXlMaXN0CisgIC8vIHdyYXBwZWQgaW4gYSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCkgd3JhcHBlciBhbmQgbm9ib2R5IGVsc2UgaGFzCisgIC8vIGEgcmVmZXJlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgQXJyYXlMaXN0LiBUaGlzIGludmFyaWFudCBhbGxvd3MgdXMgdG8KKyAgLy8gc2hhcmUgaW5zdGFuY2VzIG9mIGxpc3RzIGJldHdlZW4gcHJvdG9jb2wgYnVmZmVycyBhdm9pZGluZyBleHBlbnNpdmUKKyAgLy8gbWVtb3J5IGFsbG9jYXRpb25zLiBOb3RlLCBpbW11dGFibGUgaXMgYSBzdHJvbmcgZ3VhcmFudGVlIGhlcmUgLS0gbm90CisgIC8vIGp1c3QgdGhhdCB0aGUgbGlzdCBjYW5ub3QgYmUgbW9kaWZpZWQgdmlhIHRoZSByZWZlcmVuY2UgYnV0IHRoYXQgdGhlCisgIC8vIGxpc3QgY2FuIG5ldmVyIGJlIG1vZGlmaWVkLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0xpc3QgJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIpOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKSB7XG4iCisgICAgIiAgaWYgKCEkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCgkbmFtZSRfKTtcbiIKKyAgICAiICAgICRzZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgIH1cbiIKKyAgICAifVxuIik7CisKKyAgICAvLyBOb3RlOiAgV2UgcmV0dXJuIGFuIHVubW9kaWZpYWJsZSBsaXN0IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBjYWxsZXIKKyAgICAvLyAgIGNvdWxkIGhvbGQgb24gdG8gdGhlIHJldHVybmVkIGxpc3QgYW5kIG1vZGlmeSBpdCBhZnRlciB0aGUgbWVzc2FnZQorICAgIC8vICAgaGFzIGJlZW4gYnVpbHQsIHRodXMgbXV0YXRpbmcgdGhlIG1lc3NhZ2Ugd2hpY2ggaXMgc3VwcG9zZWQgdG8gYmUKKyAgICAvLyAgIGltbXV0YWJsZS4KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0XG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldFVubW9kaWZpYWJsZVZpZXcoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKHZhbHVlKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoXG4iCisgICAgIiAgICAgIHZhbHVlcywgJG5hbWUkXyk7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gJGVtcHR5X2xpc3QkO1xuIgorICAgICIgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKHZhbHVlKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gJGVtcHR5X2xpc3QkO1xuIgorICAgICIkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvZGUgYmVsb3cgZG9lcyB0d28gb3B0aW1pemF0aW9uczoKKyAgLy8gICAxLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBlbXB0eSwgdGhlcmUncyBub3RoaW5nIHRvIGRvLiBUaGlzIGVuc3VyZXMgd2UKKyAgLy8gICAgICBkb24ndCBhbGxvY2F0ZSBhIG5ldyBhcnJheSBpZiB3ZSBhbHJlYWR5IGhhdmUgYW4gaW1tdXRhYmxlIG9uZS4KKyAgLy8gICAyLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBub24tZW1wdHkgYW5kIG91ciBjdXJyZW50IGxpc3QgaXMgZW1wdHksIHdlIGNhbgorICAvLyAgICAgIHJldXNlIHRoZSBvdGhlciBsaXN0IHdoaWNoIGlzIGd1YXJhbnRlZWQgdG8gYmUgaW1tdXRhYmxlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gb3RoZXIuJG5hbWUkXztcbiIKKyAgICAiICAgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgICAkbmFtZSRfLmFkZEFsbChvdGhlci4kbmFtZSRfKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvZGUgYmVsb3cgZW5zdXJlcyB0aGF0IHRoZSByZXN1bHQgaGFzIGFuIGltbXV0YWJsZSBsaXN0LiBJZiBvdXIKKyAgLy8gbGlzdCBpcyBpbW11dGFibGUsIHdlIGNhbiBqdXN0IHJldXNlIGl0LiBJZiBub3QsIHdlIG1ha2UgaXQgaW1tdXRhYmxlLgorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9ICRuYW1lJF8uZ2V0VW5tb2RpZmlhYmxlVmlldygpO1xuIgorICAgICIgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAifVxuIgorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpO1xuIik7CisgIH0gZWxzZSBpZiAoIUhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gTGl0ZSBydW50aW1lIHNob3VsZCBhdHRlbXB0IHRvIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBhdHRlbXB0aW5nIHRvCisgICAgLy8gY29uc3RydWN0IHRoZSBzdHJpbmcgZGlyZWN0bHkgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGJ1ZmZlci4gVGhpcyBhdm9pZHMKKyAgICAvLyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsIGFsbG9jYXRpb25zCisgICAgLy8gaW4gaGFsZi4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmcoKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCgpO1xuIgorICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAifVxuIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pIHx8ICFIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXy5hZGQocyk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uYWRkKGJzKTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7XG4iCisgICAgImludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpO1xuIgorICAgICJpZiAoISRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCAmJiBpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCgpO1xuIgorICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAifVxuIgorICAgICJ3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7XG4iKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmcoKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgJG5hbWUkLmFkZChzKTtcbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ9XG4iCisgICAgImlucHV0LnBvcExpbWl0KGxpbWl0KTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkbmFtZSRfLmdldFVubW9kaWZpYWJsZVZpZXcoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKSA+IDApIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCR0YWckKTtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemUpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJE5vVGFnKCRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlQnl0ZXMoJG51bWJlciQsICRuYW1lJF8uZ2V0Qnl0ZVN0cmluZyhpKSk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YVNpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcoJG5hbWUkXy5nZXRCeXRlU3RyaW5nKGkpKTtcbiIKKyAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAic2l6ZSArPSBkYXRhU2l6ZTtcbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoIWdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5pc0VtcHR5KCkpIHtcbiIKKyAgICAgICIgIHNpemUgKz0gJHRhZ19zaXplJDtcbiIKKyAgICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICAgIiAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2l6ZSArPSAkdGFnX3NpemUkICogZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKTtcbiIpOworICB9CisKKyAgLy8gY2FjaGUgdGhlIGRhdGEgc2l6ZSBmb3IgcGFja2VkIGZpZWxkcy4KKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKVxuIgorICAgICIgICAgLmVxdWFscyhvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmIChnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpID4gMCkge1xuIgorICAgICIgIGhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAiICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuaGFzaENvZGUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3N0cmluZyBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiU3RyaW5nIjsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3N0cmluZ19maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlYTQ0ZGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaApAQCAtMCwwICsxLDE2MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vIEF1dGhvcjogam9ucEBnb29nbGUuY29tIChKb24gUGVybG93KQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU1RSSU5HX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9TVFJJTkdfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgcHJpdmF0ZToKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5SZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3Q7CisgIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU1RSSU5HX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5MzRiMDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uY2MKQEAgLTAsMCArMSwxMTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitFbnVtR2VuZXJhdG9yOjpFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBwYXJhbXNfKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBkZXNjcmlwdG9yXy0+dmFsdWUoaSk7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogY2Fub25pY2FsX3ZhbHVlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZS0+bnVtYmVyKCkpOworCisgICAgaWYgKHZhbHVlID09IGNhbm9uaWNhbF92YWx1ZSkgeworICAgICAgY2Fub25pY2FsX3ZhbHVlc18ucHVzaF9iYWNrKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgQWxpYXMgYWxpYXM7CisgICAgICBhbGlhcy52YWx1ZSA9IHZhbHVlOworICAgICAgYWxpYXMuY2Fub25pY2FsX3ZhbHVlID0gY2Fub25pY2FsX3ZhbHVlOworICAgICAgYWxpYXNlc18ucHVzaF9iYWNrKGFsaWFzKTsKKyAgICB9CisgIH0KK30KKworRW51bUdlbmVyYXRvcjo6fkVudW1HZW5lcmF0b3IoKSB7fQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgIi8vIGVudW0gJGNsYXNzbmFtZSRcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgLy8gU3RhcnQgb2YgY29udGFpbmVyIGludGVyZmFjZQorICBib29sIHVzZV9zaGVsbF9jbGFzcyA9IHBhcmFtc18uamF2YV9lbnVtX3N0eWxlKCk7CisgIGlmICh1c2Vfc2hlbGxfY2xhc3MpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgaW50ZXJmYWNlICRjbGFzc25hbWUkIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgUmVuYW1lSmF2YUtleXdvcmRzKGRlc2NyaXB0b3JfLT5uYW1lKCkpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgfQorCisgIC8vIENhbm9uaWNhbCB2YWx1ZXMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjYW5vbmljYWxfdmFsdWVzXy5zaXplKCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRuYW1lJCA9ICRjYW5vbmljYWxfdmFsdWUkO1xuIiwKKyAgICAgICJuYW1lIiwgUmVuYW1lSmF2YUtleXdvcmRzKGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5uYW1lKCkpLAorICAgICAgImNhbm9uaWNhbF92YWx1ZSIsIFNpbXBsZUl0b2EoY2Fub25pY2FsX3ZhbHVlc19baV0tPm51bWJlcigpKSk7CisgIH0KKworICAvLyBBbGlhc2VzCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxpYXNlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGludCAkbmFtZSQgPSAkY2Fub25pY2FsX25hbWUkO1xuIiwKKyAgICAgICJuYW1lIiwgUmVuYW1lSmF2YUtleXdvcmRzKGFsaWFzZXNfW2ldLnZhbHVlLT5uYW1lKCkpLAorICAgICAgImNhbm9uaWNhbF9uYW1lIiwgUmVuYW1lSmF2YUtleXdvcmRzKGFsaWFzZXNfW2ldLmNhbm9uaWNhbF92YWx1ZS0+bmFtZSgpKSk7CisgIH0KKworICAvLyBFbmQgb2YgY29udGFpbmVyIGludGVyZmFjZQorICBpZiAodXNlX3NoZWxsX2NsYXNzKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwZGQzNjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaApAQCAtMCwwICsxLDg3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRU5VTV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0VOVU1fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2NsYXNzIEVudW1HZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRW51bUdlbmVyYXRvcihjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+RW51bUdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisKKyAgLy8gVGhlIHByb3RvIGxhbmd1YWdlIGFsbG93cyBtdWx0aXBsZSBlbnVtIGNvbnN0YW50cyB0byBoYXZlIHRoZSBzYW1lIG51bWVyaWMKKyAgLy8gdmFsdWUuICBKYXZhLCBob3dldmVyLCBkb2VzIG5vdCBhbGxvdyBtdWx0aXBsZSBlbnVtIGNvbnN0YW50cyB0byBiZQorICAvLyBjb25zaWRlcmVkIGVxdWl2YWxlbnQuICBXZSB0cmVhdCB0aGUgZmlyc3QgZGVmaW5lZCBjb25zdGFudCBmb3IgYW55CisgIC8vIGdpdmVuIG51bWVyaWMgdmFsdWUgYXMgImNhbm9uaWNhbCIgYW5kIHRoZSByZXN0IGFzIGFsaWFzZXMgb2YgdGhhdAorICAvLyBjYW5vbmljYWwgdmFsdWUuCisgIHZlY3Rvcjxjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKj4gY2Fub25pY2FsX3ZhbHVlc187CisKKyAgc3RydWN0IEFsaWFzIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZTsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBjYW5vbmljYWxfdmFsdWU7CisgIH07CisgIHZlY3RvcjxBbGlhcz4gYWxpYXNlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVudW1HZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19FTlVNX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhNTlkMzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuY2MKQEAgLTAsMCArMSw1MjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworbmFtZXNwYWNlIHsKKworLy8gVE9ETyhrZW50b24pOiAgRmFjdG9yIG91dCBhICJTZXRDb21tb25GaWVsZFZhcmlhYmxlcygpIiB0byBnZXQgcmlkIG9mCisvLyAgIHJlcGVhdCBjb2RlIGJldHdlZW4gdGhpcyBhbmQgdGhlIG90aGVyIGZpZWxkIHR5cGVzLgordm9pZCBTZXRFbnVtVmFyaWFibGVzKGNvbnN0IFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICBpZiAocGFyYW1zLnVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKQorICAgICAgJiYgIXBhcmFtcy5yZWZ0eXBlc19wcmltaXRpdmVfZW51bXMoKQorICAgICAgJiYgIWRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAoKnZhcmlhYmxlcylbInR5cGUiXSA9ICJqYXZhLmxhbmcuSW50ZWdlciI7CisgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSAibnVsbCI7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSAiaW50IjsKKyAgICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IERlZmF1bHRWYWx1ZShwYXJhbXMsIGRlc2NyaXB0b3IpOworICB9CisgICgqdmFyaWFibGVzKVsicmVwZWF0ZWRfZGVmYXVsdCJdID0KKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfSU5UX0FSUkFZIjsKKyAgKCp2YXJpYWJsZXMpWyJ0YWciXSA9IFNpbXBsZUl0b2EoaW50ZXJuYWw6OldpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbInRhZ19zaXplIl0gPSBTaW1wbGVJdG9hKAorICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXQ6OlRhZ1NpemUoZGVzY3JpcHRvci0+bnVtYmVyKCksIGRlc2NyaXB0b3ItPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbIm5vbl9wYWNrZWRfdGFnIl0gPSBTaW1wbGVJdG9hKAorICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGRlc2NyaXB0b3ItPm51bWJlcigpLAorICAgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0OjpXaXJlVHlwZUZvckZpZWxkVHlwZShkZXNjcmlwdG9yLT50eXBlKCkpKSk7CisgICgqdmFyaWFibGVzKVsibWVzc2FnZV9uYW1lIl0gPSBkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKS0+bmFtZSgpOworfQorCit2b2lkIExvYWRFbnVtVmFsdWVzKGNvbnN0IFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3IsIHZlY3RvcjxzdHJpbmc+KiBjYW5vbmljYWxfdmFsdWVzKSB7CisgIHN0cmluZyBlbnVtX2NsYXNzX25hbWUgPSBDbGFzc05hbWUocGFyYW1zLCBlbnVtX2Rlc2NyaXB0b3IpOworICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1fZGVzY3JpcHRvci0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBlbnVtX2Rlc2NyaXB0b3ItPnZhbHVlKGkpOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGNhbm9uaWNhbF92YWx1ZSA9CisgICAgICAgIGVudW1fZGVzY3JpcHRvci0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUtPm51bWJlcigpKTsKKyAgICBpZiAodmFsdWUgPT0gY2Fub25pY2FsX3ZhbHVlKSB7CisgICAgICBjYW5vbmljYWxfdmFsdWVzLT5wdXNoX2JhY2soCisgICAgICAgICAgZW51bV9jbGFzc19uYW1lICsgIi4iICsgUmVuYW1lSmF2YUtleXdvcmRzKHZhbHVlLT5uYW1lKCkpKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBQcmludENhc2VMYWJlbHMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBjYW5vbmljYWxfdmFsdWVzKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgY2Fub25pY2FsX3ZhbHVlcy5zaXplKCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgY2FzZSAkdmFsdWUkOlxuIiwKKyAgICAgICJ2YWx1ZSIsIGNhbm9uaWNhbF92YWx1ZXNbaV0pOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6CitFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldEVudW1WYXJpYWJsZXMocGFyYW1zLCBkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7CisgIExvYWRFbnVtVmFsdWVzKHBhcmFtcywgZGVzY3JpcHRvci0+ZW51bV90eXBlKCksICZjYW5vbmljYWxfdmFsdWVzXyk7Cit9CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6fkVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCAvKiB1bnVzZWQgbGF6eV9pbml0ICovKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInB1YmxpYyAkdHlwZSQgJG5hbWUkO1xuIik7CisKKyAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJDtcbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICRkZWZhdWx0JDtcbiIpOworCisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJoYXMkY2FwaXRhbGl6ZWRfbmFtZSQgPSBmYWxzZTtcbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IHZhbHVlID0gaW5wdXQucmVhZEludDMyKCk7XG4iCisgICAgInN3aXRjaCAodmFsdWUpIHtcbiIpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICAgdGhpcy4kbmFtZSQgPSB2YWx1ZTtcbiIpOworICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGhhcyRjYXBpdGFsaXplZF9uYW1lJCA9IHRydWU7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAiICAgIGJyZWFrO1xuIgorICAgICJ9XG4iKTsKKyAgLy8gTm8gZGVmYXVsdCBjYXNlOiBpbiBjYXNlIG9mIGludmFsaWQgdmFsdWUgZnJvbSB0aGUgd2lyZSwgcHJlc2VydmUgb2xkCisgIC8vIGZpZWxkIHZhbHVlLiBBbHNvIHdlIGFyZSBub3Qgc3RvcmluZyB0aGUgaW52YWxpZCB2YWx1ZSBpbnRvIHRoZSB1bmtub3duCisgIC8vIGZpZWxkcywgYmVjYXVzZSB0aGVyZSBpcyBubyB3YXkgdG8gZ2V0IHRoZSB2YWx1ZSBvdXQuCit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19yZXF1aXJlZCgpICYmICFwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgLy8gQWx3YXlzIHNlcmlhbGl6ZSBhIHJlcXVpcmVkIGZpZWxkIGlmIHdlIGRvbid0IGhhdmUgdGhlICdoYXMnIHNpZ25hbC4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIm91dHB1dC53cml0ZUludDMyKCRudW1iZXIkLCB0aGlzLiRuYW1lJCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICh0aGlzLiRuYW1lJCAhPSAkZGVmYXVsdCQgfHwgaGFzJGNhcGl0YWxpemVkX25hbWUkKSB7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICh0aGlzLiRuYW1lJCAhPSAkZGVmYXVsdCQpIHtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgb3V0cHV0LndyaXRlSW50MzIoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPmlzX3JlcXVpcmVkKCkgJiYgIXBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAgICIgIC5jb21wdXRlSW50MzJTaXplKCRudW1iZXIkLCB0aGlzLiRuYW1lJCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICh0aGlzLiRuYW1lJCAhPSAkZGVmYXVsdCQgfHwgaGFzJGNhcGl0YWxpemVkX25hbWUkKSB7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICh0aGlzLiRuYW1lJCAhPSAkZGVmYXVsdCQpIHtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICAgIiAgICAuY29tcHV0ZUludDMyU2l6ZSgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKHBhcmFtc18udXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpCisgICAgICAgICYmICFwYXJhbXNfLnJlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAodGhpcy4kbmFtZSQgPT0gbnVsbCkge1xuIgorICAgICAgIiAgaWYgKG90aGVyLiRuYW1lJCAhPSBudWxsKSB7XG4iCisgICAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9IGVsc2UgaWYgKCF0aGlzLiRuYW1lJC5lcXVhbHMob3RoZXIuJG5hbWUkKSkge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlOyIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBXZSBkZWZpbmUgZXF1YWxpdHkgYXMgc2VyaWFsaXplZCBmb3JtIGVxdWFsaXR5LiBJZiBnZW5lcmF0ZV9oYXMoKSwKKyAgICAvLyB0aGVuIGlmIHRoZSBmaWVsZCB2YWx1ZSBlcXVhbHMgdGhlIGRlZmF1bHQgdmFsdWUgaW4gYm90aCBtZXNzYWdlcywKKyAgICAvLyBidXQgb25lJ3MgJ2hhcycgZmllbGQgaXMgc2V0IGFuZCB0aGUgb3RoZXIncyBpcyBub3QsIHRoZSBzZXJpYWxpemVkCisgICAgLy8gZm9ybXMgYXJlIGRpZmZlcmVudCBhbmQgd2Ugc2hvdWxkIHJldHVybiBmYWxzZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICh0aGlzLiRuYW1lJCAhPSBvdGhlci4kbmFtZSQiKTsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIlxuIgorICAgICAgICAiICAgIHx8ICh0aGlzLiRuYW1lJCA9PSAkZGVmYXVsdCRcbiIKKyAgICAgICAgIiAgICAgICAgJiYgdGhpcy5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQgIT0gb3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKSIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiKSB7XG4iCisgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICIpOworICBpZiAocGFyYW1zXy51c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKCkKKyAgICAgICAgJiYgIXBhcmFtc18ucmVmdHlwZXNfcHJpbWl0aXZlX2VudW1zKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIih0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkKSIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAidGhpcy4kbmFtZSQiKTsKKyAgfQorICBwcmludGVyLT5QcmludCgiO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQWNjZXNzb3JFbnVtRmllbGRHZW5lcmF0b3I6OgorQWNjZXNzb3JFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBpbnQgaGFzX2JpdF9pbmRleCkKKyAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldEVudW1WYXJpYWJsZXMocGFyYW1zLCBkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7CisgIExvYWRFbnVtVmFsdWVzKHBhcmFtcywgZGVzY3JpcHRvci0+ZW51bV90eXBlKCksICZjYW5vbmljYWxfdmFsdWVzXyk7CisgIFNldEJpdE9wZXJhdGlvblZhcmlhYmxlcygiaGFzIiwgaGFzX2JpdF9pbmRleCwgJnZhcmlhYmxlc18pOworfQorCitBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6fkFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyogdW51c2VkIGxhenlfaW5pdCAqLykgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGludCAkbmFtZSRfO1xuIgorICAgICJwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgJG1lc3NhZ2VfbmFtZSQgc2V0JGNhcGl0YWxpemVkX25hbWUkKGludCB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkc2V0X2hhcyQ7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkZ2V0X2hhcyQ7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICRtZXNzYWdlX25hbWUkIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iCisgICAgIiAgJGNsZWFyX2hhcyQ7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCB2YWx1ZSA9IGlucHV0LnJlYWRJbnQzMigpO1xuIgorICAgICJzd2l0Y2ggKHZhbHVlKSB7XG4iKTsKKyAgUHJpbnRDYXNlTGFiZWxzKHByaW50ZXIsIGNhbm9uaWNhbF92YWx1ZXNfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAgICRzZXRfaGFzJDtcbiIKKyAgICAiICAgIGJyZWFrO1xuIgorICAgICJ9XG4iKTsKKyAgLy8gTm8gZGVmYXVsdCBjYXNlOiBpbiBjYXNlIG9mIGludmFsaWQgdmFsdWUgZnJvbSB0aGUgd2lyZSwgcHJlc2VydmUgb2xkCisgIC8vIGZpZWxkIHZhbHVlLiBBbHNvIHdlIGFyZSBub3Qgc3RvcmluZyB0aGUgaW52YWxpZCB2YWx1ZSBpbnRvIHRoZSB1bmtub3duCisgIC8vIGZpZWxkcywgYmVjYXVzZSB0aGVyZSBpcyBubyB3YXkgdG8gZ2V0IHRoZSB2YWx1ZSBvdXQuCit9CisKK3ZvaWQgQWNjZXNzb3JFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9oYXMkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlSW50MzIoJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9oYXMkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICIgICAgLmNvbXB1dGVJbnQzMlNpemUoJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRkaWZmZXJlbnRfaGFzJFxuIgorICAgICIgICAgfHwgJG5hbWUkXyAhPSBvdGhlci4kbmFtZSRfKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICRuYW1lJF87XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0RW51bVZhcmlhYmxlcyhwYXJhbXMsIGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKKyAgTG9hZEVudW1WYWx1ZXMocGFyYW1zLCBkZXNjcmlwdG9yLT5lbnVtX3R5cGUoKSwgJmNhbm9uaWNhbF92YWx1ZXNfKTsKK30KKworUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qIHVudXNlZCBsYXp5X2luaXQgKi8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljICR0eXBlJFtdICRuYW1lJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICRyZXBlYXRlZF9kZWZhdWx0JDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRmlyc3QsIGZpZ3VyZSBvdXQgdGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBhcnJheSwgdGhlbiBwYXJzZSwKKyAgLy8gYW5kIGZpbmFsbHkgY29weSB0aGUgdmFsaWQgdmFsdWVzIHRvIHRoZSBmaWVsZC4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGxlbmd0aCA9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFub1xuIgorICAgICIgICAgLmdldFJlcGVhdGVkRmllbGRBcnJheUxlbmd0aChpbnB1dCwgJG5vbl9wYWNrZWRfdGFnJCk7XG4iCisgICAgImludFtdIHZhbGlkVmFsdWVzID0gbmV3IGludFtsZW5ndGhdO1xuIgorICAgICJpbnQgdmFsaWRDb3VudCA9IDA7XG4iCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiIKKyAgICAiICBpZiAoaSAhPSAwKSB7IC8vIHRhZyBmb3IgZmlyc3QgdmFsdWUgYWxyZWFkeSBjb25zdW1lZC5cbiIKKyAgICAiICAgIGlucHV0LnJlYWRUYWcoKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgaW50IHZhbHVlID0gaW5wdXQucmVhZEludDMyKCk7XG4iCisgICAgIiAgc3dpdGNoICh2YWx1ZSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICAgIHZhbGlkVmFsdWVzW3ZhbGlkQ291bnQrK10gPSB2YWx1ZTtcbiIKKyAgICAiICAgICAgYnJlYWs7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iCisgICAgImlmICh2YWxpZENvdW50ICE9IDApIHtcbiIKKyAgICAiICBpbnQgaSA9IHRoaXMuJG5hbWUkID09IG51bGwgPyAwIDogdGhpcy4kbmFtZSQubGVuZ3RoO1xuIgorICAgICIgIGlmIChpID09IDAgJiYgdmFsaWRDb3VudCA9PSB2YWxpZFZhbHVlcy5sZW5ndGgpIHtcbiIKKyAgICAiICAgIHRoaXMuJG5hbWUkID0gdmFsaWRWYWx1ZXM7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGludFtdIG5ld0FycmF5ID0gbmV3IGludFtpICsgdmFsaWRDb3VudF07XG4iCisgICAgIiAgICBpZiAoaSAhPSAwKSB7XG4iCisgICAgIiAgICAgIGphdmEubGFuZy5TeXN0ZW0uYXJyYXljb3B5KHRoaXMuJG5hbWUkLCAwLCBuZXdBcnJheSwgMCwgaSk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3lzdGVtLmFycmF5Y29weSh2YWxpZFZhbHVlcywgMCwgbmV3QXJyYXksIGksIHZhbGlkQ291bnQpO1xuIgorICAgICIgICAgdGhpcy4kbmFtZSQgPSBuZXdBcnJheTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBieXRlcyA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpO1xuIgorICAgICJpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQoYnl0ZXMpO1xuIgorICAgICIvLyBGaXJzdCBwYXNzIHRvIGNvbXB1dGUgYXJyYXkgbGVuZ3RoLlxuIgorICAgICJpbnQgYXJyYXlMZW5ndGggPSAwO1xuIgorICAgICJpbnQgc3RhcnRQb3MgPSBpbnB1dC5nZXRQb3NpdGlvbigpO1xuIgorICAgICJ3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7XG4iCisgICAgIiAgc3dpdGNoIChpbnB1dC5yZWFkSW50MzIoKSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICAgIGFycmF5TGVuZ3RoKys7XG4iCisgICAgIiAgICAgIGJyZWFrO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJpZiAoYXJyYXlMZW5ndGggIT0gMCkge1xuIgorICAgICIgIGlucHV0LnJld2luZFRvUG9zaXRpb24oc3RhcnRQb3MpO1xuIgorICAgICIgIGludCBpID0gdGhpcy4kbmFtZSQgPT0gbnVsbCA/IDAgOiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iCisgICAgIiAgaW50W10gbmV3QXJyYXkgPSBuZXcgaW50W2kgKyBhcnJheUxlbmd0aF07XG4iCisgICAgIiAgaWYgKGkgIT0gMCkge1xuIgorICAgICIgICAgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkodGhpcy4kbmFtZSQsIDAsIG5ld0FycmF5LCAwLCBpKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIgorICAgICIgICAgaW50IHZhbHVlID0gaW5wdXQucmVhZEludDMyKCk7XG4iCisgICAgIiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgICAgICBuZXdBcnJheVtpKytdID0gdmFsdWU7XG4iCisgICAgIiAgICAgICAgYnJlYWs7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICIgIHRoaXMuJG5hbWUkID0gbmV3QXJyYXk7XG4iCisgICAgIn1cbiIKKyAgICAiaW5wdXQucG9wTGltaXQobGltaXQpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVSZXBlYXRlZERhdGFTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBDcmVhdGVzIGEgdmFyaWFibGUgZGF0YVNpemUgYW5kIHB1dHMgdGhlIHNlcmlhbGl6ZWQgc2l6ZSBpbiB0aGVyZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGRhdGFTaXplID0gMDtcbiIKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICIgIGludCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgIiAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAiICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhlbGVtZW50KTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBHZW5lcmF0ZVJlcGVhdGVkRGF0YVNpemVDb2RlKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAib3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJHRhZyQpO1xuIgorICAgICAgIm91dHB1dC53cml0ZVJhd1ZhcmludDMyKGRhdGFTaXplKTtcbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0aGlzLiRuYW1lJFtpXSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGVJbnQzMigkbnVtYmVyJCwgdGhpcy4kbmFtZSRbaV0pO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgR2VuZXJhdGVSZXBlYXRlZERhdGFTaXplQ29kZShwcmludGVyKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAic2l6ZSArPSBkYXRhU2l6ZTtcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2l6ZSArPSAkdGFnX3NpemUkO1xuIgorICAgICAgInNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAgICIgICAgLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZGF0YVNpemUpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5lcXVhbHMoXG4iCisgICAgIiAgICB0aGlzLiRuYW1lJCwgb3RoZXIuJG5hbWUkKSkge1xuIgorICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gMzEgKiByZXN1bHRcbiIKKyAgICAiICAgICsgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5oYXNoQ29kZSh0aGlzLiRuYW1lJCk7XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGFkYzYxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmgKQEAgLTAsMCArMSwxMjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19FTlVNX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRU5VTV9GSUVMRF9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEVudW1GaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+RW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICB2ZWN0b3I8c3RyaW5nPiBjYW5vbmljYWxfdmFsdWVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgIGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBpbnQgaGFzX2JpdF9pbmRleCk7CisgIH5BY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKyAgdmVjdG9yPHN0cmluZz4gY2Fub25pY2FsX3ZhbHVlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcyk7CisgIH5SZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlUmVwZWF0ZWREYXRhU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKyAgdmVjdG9yPHN0cmluZz4gY2Fub25pY2FsX3ZhbHVlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRU5VTV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzU0ZWQ1NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmNjCkBAIC0wLDAgKzEsMTUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGJkdWZmQGdvb2dsZS5jb20gKEJyaWFuIER1ZmYpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworY29uc3QgY2hhciogR2V0VHlwZUNvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMiAgIDogcmV0dXJuICJUWVBFX0lOVDMyIiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzIgIDogcmV0dXJuICJUWVBFX1VJTlQzMiIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzIgIDogcmV0dXJuICJUWVBFX1NJTlQzMiIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuICJUWVBFX0ZJWEVEMzIiIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjogcmV0dXJuICJUWVBFX1NGSVhFRDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NCAgIDogcmV0dXJuICJUWVBFX0lOVDY0IiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQgIDogcmV0dXJuICJUWVBFX1VJTlQ2NCIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQgIDogcmV0dXJuICJUWVBFX1NJTlQ2NCIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0IDogcmV0dXJuICJUWVBFX0ZJWEVENjQiIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJUWVBFX1NGSVhFRDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVCAgIDogcmV0dXJuICJUWVBFX0ZMT0FUIiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEUgIDogcmV0dXJuICJUWVBFX0RPVUJMRSIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MICAgIDogcmV0dXJuICJUWVBFX0JPT0wiICAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgIDogcmV0dXJuICJUWVBFX1NUUklORyIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuICJUWVBFX0JZVEVTIiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuICJUWVBFX0VOVU0iICAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCAgIDogcmV0dXJuICJUWVBFX0dST1VQIiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuICJUWVBFX01FU1NBR0UiIDsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBTZXRWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMgcGFyYW1zLAorICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsiZXh0ZW5kcyJdID0gQ2xhc3NOYW1lKHBhcmFtcywgZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpOworICAoKnZhcmlhYmxlcylbIm5hbWUiXSA9IFJlbmFtZUphdmFLZXl3b3JkcyhVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgYm9vbCByZXBlYXRlZCA9IGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCk7CisgICgqdmFyaWFibGVzKVsicmVwZWF0ZWQiXSA9IHJlcGVhdGVkID8gIlJlcGVhdGVkIiA6ICIiOworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IEdldFR5cGVDb25zdGFudE5hbWUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgc3RyaW5nIHRhZyA9IFNpbXBsZUl0b2EoV2lyZUZvcm1hdDo6TWFrZVRhZyhkZXNjcmlwdG9yKSk7CisgIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfTUVTU0FHRSkgeworICAgICgqdmFyaWFibGVzKVsiZXh0X3R5cGUiXSA9ICJNZXNzYWdlVHlwZWQiOworICAgIHN0cmluZyBtZXNzYWdlX3R5cGUgPSBDbGFzc05hbWUocGFyYW1zLCBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgaWYgKHJlcGVhdGVkKSB7CisgICAgICBtZXNzYWdlX3R5cGUgKz0gIltdIjsKKyAgICB9CisgICAgKCp2YXJpYWJsZXMpWyJjbGFzcyJdID0gbWVzc2FnZV90eXBlOworICAgIC8vIEZvciBtZXNzYWdlIHR5cGVkIGV4dGVuc2lvbnMsIHRhZ3NfcGFyYW1zIGNvbnRhaW5zIGEgc2luZ2xlIHRhZworICAgIC8vIGZvciBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZCBjYXNlcy4KKyAgICAoKnZhcmlhYmxlcylbInRhZ19wYXJhbXMiXSA9IHRhZzsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbImV4dF90eXBlIl0gPSAiUHJpbWl0aXZlVHlwZWQiOworICAgIGlmICghcmVwZWF0ZWQpIHsKKyAgICAgICgqdmFyaWFibGVzKVsiY2xhc3MiXSA9IEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoamF2YV90eXBlKTsKKyAgICAgICgqdmFyaWFibGVzKVsidGFnX3BhcmFtcyJdID0gdGFnOworICAgIH0gZWxzZSB7CisgICAgICAoKnZhcmlhYmxlcylbImNsYXNzIl0gPSBQcmltaXRpdmVUeXBlTmFtZShqYXZhX3R5cGUpICsgIltdIjsKKyAgICAgIGlmICghZGVzY3JpcHRvci0+aXNfcGFja2FibGUoKSkgeworICAgICAgICAvLyBOb24tcGFja2FibGU6IG5vblBhY2tlZFRhZyA9PSB0YWcsIHBhY2tlZFRhZyA9PSAwCisgICAgICAgICgqdmFyaWFibGVzKVsidGFnX3BhcmFtcyJdID0gdGFnICsgIiwgIiArIHRhZyArICIsIDAiOworICAgICAgfSBlbHNlIGlmIChkZXNjcmlwdG9yLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICAgICAgLy8gUGFja2FibGUgYW5kIHBhY2tlZDogdGFnID09IHBhY2tlZFRhZworICAgICAgICBzdHJpbmcgbm9uX3BhY2tlZF90YWcgPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICAgICAgZGVzY3JpcHRvci0+bnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0OjpXaXJlVHlwZUZvckZpZWxkVHlwZShkZXNjcmlwdG9yLT50eXBlKCkpKSk7CisgICAgICAgICgqdmFyaWFibGVzKVsidGFnX3BhcmFtcyJdID0gdGFnICsgIiwgIiArIG5vbl9wYWNrZWRfdGFnICsgIiwgIiArIHRhZzsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFBhY2thYmxlIGFuZCBub3QgcGFja2VkOiB0YWcgPT0gbm9uUGFja2VkVGFnCisgICAgICAgIHN0cmluZyBwYWNrZWRfdGFnID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygKKyAgICAgICAgICAgIGRlc2NyaXB0b3ItPm51bWJlcigpLCBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpOworICAgICAgICAoKnZhcmlhYmxlcylbInRhZ19wYXJhbXMiXSA9IHRhZyArICIsICIgKyB0YWcgKyAiLCAiICsgcGFja2VkX3RhZzsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworRXh0ZW5zaW9uR2VuZXJhdG9yOjoKK0V4dGVuc2lvbkdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IHBhcmFtc18ocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRWYXJpYWJsZXMoZGVzY3JpcHRvciwgcGFyYW1zLCAmdmFyaWFibGVzXyk7Cit9CisKK0V4dGVuc2lvbkdlbmVyYXRvcjo6fkV4dGVuc2lvbkdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRXh0ZW5zaW9uR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5FeHRlbnNpb248XG4iCisgICAgIiAgICAkZXh0ZW5kcyQsXG4iCisgICAgIiAgICAkY2xhc3MkPiAkbmFtZSQgPVxuIgorICAgICIgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5FeHRlbnNpb24uY3JlYXRlJHJlcGVhdGVkJCRleHRfdHlwZSQoXG4iCisgICAgIiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5FeHRlbnNpb24uJHR5cGUkLFxuIgorICAgICIgICAgICAgICAgICAkY2xhc3MkLmNsYXNzLFxuIgorICAgICIgICAgICAgICAgICAkdGFnX3BhcmFtcyQpO1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDg0M2UyOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmgKQEAgLTAsMCArMSw3NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBiZHVmZkBnb29nbGUuY29tIChCcmlhbiBEdWZmKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0VYVEVOU0lPTl9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRVhURU5TSU9OX0hfCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEV4dGVuc2lvbkdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfkV4dGVuc2lvbkdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEV4dGVuc2lvbkdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0VYVEVOU0lPTl9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODUyNTdmMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuY2MKQEAgLTAsMCArMSwyMDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitGaWVsZEdlbmVyYXRvcjo6fkZpZWxkR2VuZXJhdG9yKCkge30KKworYm9vbCBGaWVsZEdlbmVyYXRvcjo6U2F2ZWREZWZhdWx0TmVlZGVkKCkgY29uc3QgeworICAvLyBObyBzYXZlZCBkZWZhdWx0IGZvciB0aGlzIGZpZWxkIGJ5IGRlZmF1bHQuCisgIC8vIFN1YmNsYXNzZXMgd2hvc2UgaW5zdGFuY2VzIG1heSBuZWVkIHNhdmVkIGRlZmF1bHRzIHdpbGwgb3ZlcnJpZGUgdGhpcworICAvLyBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZS4KKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIE5vIHNhdmVkIGRlZmF1bHQgZm9yIHRoaXMgZmllbGQgYnkgZGVmYXVsdC4KKyAgLy8gU3ViY2xhc3NlcyB3aG9zZSBpbnN0YW5jZXMgbWF5IG5lZWQgc2F2ZWQgZGVmYXVsdHMgd2lsbCBvdmVycmlkZSB0aGlzCisgIC8vIGFuZCBnZW5lcmF0ZSB0aGUgYXBwcm9wcmlhdGUgaW5pdCBjb2RlIHRvIHRoZSBwcmludGVyLgorfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZU1lcmdpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBSZWFjaGluZyBoZXJlIGluZGljYXRlcyBhIGJ1Zy4gQ2FzZXMgYXJlOgorICAvLyAgIC0gVGhpcyBGaWVsZEdlbmVyYXRvciBzaG91bGQgc3VwcG9ydCBwYWNraW5nLCBidXQgdGhpcyBtZXRob2Qgc2hvdWxkIGJlCisgIC8vICAgICBvdmVycmlkZGVuLgorICAvLyAgIC0gVGhpcyBGaWVsZEdlbmVyYXRvciBkb2Vzbid0IHN1cHBvcnQgcGFja2luZywgYW5kIHRoaXMgbWV0aG9kIHNob3VsZAorICAvLyAgICAgbmV2ZXIgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKCkgIgorICAgICAgICAgICAgIDw8ICJjYWxsZWQgb24gZmllbGQgZ2VuZXJhdG9yIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCBwYWNraW5nLiI7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitGaWVsZEdlbmVyYXRvck1hcDo6RmllbGRHZW5lcmF0b3JNYXAoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zICZwYXJhbXMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oCisgICAgICBuZXcgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvcj5bZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKV0pIHsKKworICBpbnQgbmV4dF9oYXNfYml0X2luZGV4ID0gMDsKKyAgYm9vbCBzYXZlZF9kZWZhdWx0c19uZWVkZWQgPSBmYWxzZTsKKyAgLy8gQ29uc3RydWN0IGFsbCB0aGUgRmllbGRHZW5lcmF0b3JzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIEZpZWxkR2VuZXJhdG9yKiBmaWVsZF9nZW5lcmF0b3IgPSBNYWtlR2VuZXJhdG9yKAorICAgICAgICBkZXNjcmlwdG9yLT5maWVsZChpKSwgcGFyYW1zLCAmbmV4dF9oYXNfYml0X2luZGV4KTsKKyAgICBzYXZlZF9kZWZhdWx0c19uZWVkZWQgPSBzYXZlZF9kZWZhdWx0c19uZWVkZWQKKyAgICAgICAgfHwgZmllbGRfZ2VuZXJhdG9yLT5TYXZlZERlZmF1bHROZWVkZWQoKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzX1tpXS5yZXNldChmaWVsZF9nZW5lcmF0b3IpOworICB9CisgIHRvdGFsX2JpdHNfID0gbmV4dF9oYXNfYml0X2luZGV4OworICBzYXZlZF9kZWZhdWx0c19uZWVkZWRfID0gc2F2ZWRfZGVmYXVsdHNfbmVlZGVkOworfQorCitGaWVsZEdlbmVyYXRvciogRmllbGRHZW5lcmF0b3JNYXA6Ok1ha2VHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBQYXJhbXMgJnBhcmFtcywgaW50KiBuZXh0X2hhc19iaXRfaW5kZXgpIHsKKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZmllbGQpOworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBFbnRyeShmaWVsZC0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBNYXBGaWVsZEdlbmVyYXRvcihmaWVsZCwgcGFyYW1zKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgICAgICB9CisgICAgICBjYXNlIEpBVkFUWVBFX0VOVU06CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoZmllbGQsIHBhcmFtcyk7CisgICAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZmllbGQsIHBhcmFtcyk7CisgICAgfQorICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIG5ldyBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgIH0KKyAgfSBlbHNlIGlmIChwYXJhbXMub3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzKCkgJiYgZmllbGQtPmlzX29wdGlvbmFsKCkKKyAgICAgICYmIGphdmFfdHlwZSAhPSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgLy8gV2UgbmVlZCBhIGhhcy1iaXQgZm9yIGVhY2ggcHJpbWl0aXZlL2VudW0gZmllbGQgYmVjYXVzZSB0aGVpciBkZWZhdWx0CisgICAgLy8gdmFsdWVzIGNvdWxkIGJlIHNhbWUgYXMgZXhwbGljaXRseSBzZXQgdmFsdWVzLiBCdXQgd2UgZG9uJ3QgbmVlZCBpdAorICAgIC8vIGZvciBhIG1lc3NhZ2UgZmllbGQgYmVjYXVzZSB0aGV5IGhhdmUgbm8gZGVmYXVsdHMgYW5kIE5hbm8gdXNlcyAnbnVsbCcKKyAgICAvLyBmb3IgdW5zZXQgbWVzc2FnZXMsIHdoaWNoIGNhbm5vdCBiZSBzZXQgZXhwbGljaXRseS4KKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIHBhcmFtcywgKCpuZXh0X2hhc19iaXRfaW5kZXgpKyspOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIG5ldyBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIHBhcmFtcywgKCpuZXh0X2hhc19iaXRfaW5kZXgpKyspOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihmaWVsZCwgcGFyYW1zKTsKKyAgICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgICAgcmV0dXJuIG5ldyBFbnVtRmllbGRHZW5lcmF0b3IoZmllbGQsIHBhcmFtcyk7CisgICAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gbmV3IFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgIH0KKyAgfQorfQorCitGaWVsZEdlbmVyYXRvck1hcDo6fkZpZWxkR2VuZXJhdG9yTWFwKCkge30KKworY29uc3QgRmllbGRHZW5lcmF0b3ImIEZpZWxkR2VuZXJhdG9yTWFwOjpnZXQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBkZXNjcmlwdG9yXyk7CisgIHJldHVybiAqZmllbGRfZ2VuZXJhdG9yc19bZmllbGQtPmluZGV4KCldOworfQorCit2b2lkIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsib25lb2ZfbmFtZSJdID0KKyAgICAgIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgKCp2YXJpYWJsZXMpWyJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIl0gPQorICAgICAgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgICgqdmFyaWFibGVzKVsib25lb2ZfaW5kZXgiXSA9CisgICAgICBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKSk7CisgICgqdmFyaWFibGVzKVsic2V0X29uZW9mX2Nhc2UiXSA9CisgICAgICAidGhpcy4iICsgKCp2YXJpYWJsZXMpWyJvbmVvZl9uYW1lIl0gKworICAgICAgIkNhc2VfID0gIiArIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbImNsZWFyX29uZW9mX2Nhc2UiXSA9CisgICAgICAidGhpcy4iICsgKCp2YXJpYWJsZXMpWyJvbmVvZl9uYW1lIl0gKyAiQ2FzZV8gPSAwIjsKKyAgKCp2YXJpYWJsZXMpWyJoYXNfb25lb2ZfY2FzZSJdID0KKyAgICAgICJ0aGlzLiIgKyAoKnZhcmlhYmxlcylbIm9uZW9mX25hbWUiXSArICJDYXNlXyA9PSAiICsKKyAgICAgIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworfQorCit2b2lkIEdlbmVyYXRlT25lb2ZGaWVsZEVxdWFscyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcikgPT0gSkFWQVRZUEVfQllURVMpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiaWYgKHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAgICIgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHMoKGJ5dGVbXSkgdGhpcy4kb25lb2ZfbmFtZSRfLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSBvdGhlci4kb25lb2ZfbmFtZSRfKSkge1xuIgorICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgImlmICh0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICBpZiAoIXRoaXMuJG9uZW9mX25hbWUkXy5lcXVhbHMob3RoZXIuJG9uZW9mX25hbWUkXykpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVPbmVvZkZpZWxkSGFzaENvZGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSA9PSBKQVZBVFlQRV9CWVRFUykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICgkaGFzX29uZW9mX2Nhc2UkXG4iCisgICAgICAiICAgPyBqYXZhLnV0aWwuQXJyYXlzLmhhc2hDb2RlKChieXRlW10pIHRoaXMuJG9uZW9mX25hbWUkXykgOiAwKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArXG4iCisgICAgICAiICAoJGhhc19vbmVvZl9jYXNlJCA/IHRoaXMuJG9uZW9mX25hbWUkXy5oYXNoQ29kZSgpIDogMCk7XG4iKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzJjZjA5MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaApAQCAtMCwwICsxLDEyOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgRmllbGRHZW5lcmF0b3IoY29uc3QgUGFyYW1zJiBwYXJhbXMpIDogcGFyYW1zXyhwYXJhbXMpIHt9CisgIHZpcnR1YWwgfkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCBib29sIFNhdmVkRGVmYXVsdE5lZWRlZCgpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbml0U2F2ZWREZWZhdWx0Q29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgZm9yIEphdmEgZmllbGRzIGFuZCBtZXRob2RzIHN1cHBvcnRpbmcgdGhpcyBmaWVsZC4KKyAgLy8gSWYgdGhpcyBmaWVsZCBuZWVkcyBhIHNhdmVkIGRlZmF1bHQgKFNhdmVkRGVmYXVsdE5lZWRlZCgpIGlzIHRydWUpLAorICAvLyB0aGVuIEBsYXp5X2luaXQgY29udHJvbHMgaG93IHRoZSBzdGF0aWMgZmllbGQgZm9yIHRoYXQgZGVmYXVsdCB2YWx1ZQorICAvLyBhbmQgaXRzIGluaXRpYWxpemF0aW9uIGNvZGUgc2hvdWxkIGJlIGdlbmVyYXRlZC4gSWYgQGxhenlfaW5pdCBpcworICAvLyB0cnVlLCB0aGUgc3RhdGljIGZpZWxkIGlzIG5vdCBkZWNsYXJlZCBmaW5hbCBhbmQgdGhlIGluaXRpYWxpemF0aW9uCisgIC8vIGNvZGUgaXMgZ2VuZXJhdGVkIG9ubHkgd2hlbiBHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlIGlzIGNhbGxlZDsKKyAgLy8gb3RoZXJ3aXNlLCB0aGUgc3RhdGljIGZpZWxkIGlzIGRlY2xhcmVkIGZpbmFsIGFuZCBpbml0aWFsaXplZCBpbmxpbmUuCisgIC8vIEdlbmVyYXRlSW5pdFNhdmVkRGVmYXVsdENvZGUgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoZSBsYXR0ZXIgY2FzZS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVtYmVycygKKyAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3QgPSAwOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlcyBjb2RlIHRvIG1lcmdlIGZyb20gcGFja2VkIHNlcmlhbGl6ZWQgZm9ybS4gVGhlIGRlZmF1bHQKKyAgLy8gaW1wbGVtZW50YXRpb24gd2lsbCBmYWlsOyBzdWJjbGFzc2VzIHdoaWNoIGNhbiBoYW5kbGUgcGFja2VkIHNlcmlhbGl6ZWQKKyAgLy8gZm9ybXMgd2lsbCBvdmVycmlkZSB0aGlzIGFuZCBwcmludCBhcHByb3ByaWF0ZSBjb2RlIHRvIHRoZSBwcmludGVyLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgcHJvdGVjdGVkOgorICBjb25zdCBQYXJhbXMmIHBhcmFtc187CisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpZWxkR2VuZXJhdG9yKTsKK307CisKKy8vIENvbnZlbmllbmNlIGNsYXNzIHdoaWNoIGNvbnN0cnVjdHMgRmllbGRHZW5lcmF0b3JzIGZvciBhIERlc2NyaXB0b3IuCitjbGFzcyBGaWVsZEdlbmVyYXRvck1hcCB7CisgcHVibGljOgorICBleHBsaWNpdCBGaWVsZEdlbmVyYXRvck1hcChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMgJnBhcmFtcyk7CisgIH5GaWVsZEdlbmVyYXRvck1hcCgpOworCisgIGNvbnN0IEZpZWxkR2VuZXJhdG9yJiBnZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGludCB0b3RhbF9iaXRzKCkgY29uc3QgeyByZXR1cm4gdG90YWxfYml0c187IH0KKyAgYm9vbCBzYXZlZF9kZWZhdWx0c19uZWVkZWQoKSBjb25zdCB7IHJldHVybiBzYXZlZF9kZWZhdWx0c19uZWVkZWRfOyB9CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgc2NvcGVkX2FycmF5PHNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3I+ID4gZmllbGRfZ2VuZXJhdG9yc187CisgIGludCB0b3RhbF9iaXRzXzsKKyAgYm9vbCBzYXZlZF9kZWZhdWx0c19uZWVkZWRfOworCisgIHN0YXRpYyBGaWVsZEdlbmVyYXRvciogTWFrZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgY29uc3QgUGFyYW1zICZwYXJhbXMsIGludCogbmV4dF9oYXNfYml0X2luZGV4KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3JNYXApOworfTsKKwordm9pZCBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7Cit2b2lkIEdlbmVyYXRlT25lb2ZGaWVsZEVxdWFscyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7Cit2b2lkIEdlbmVyYXRlT25lb2ZGaWVsZEhhc2hDb2RlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY3NmFiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5jYwpAQCAtMCwwICsxLDI2MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCituYW1lc3BhY2UgeworCisvLyBSZWN1cnNpdmVseSBzZWFyY2hlcyB0aGUgZ2l2ZW4gbWVzc2FnZSB0byBzZWUgaWYgaXQgY29udGFpbnMgYW55IGV4dGVuc2lvbnMuCitib29sIFVzZXNFeHRlbnNpb25zKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIFdlIGNvbnNlcnZhdGl2ZWx5IGFzc3VtZSB0aGF0IHVua25vd24gZmllbGRzIGFyZSBleHRlbnNpb25zLgorICBpZiAocmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKS5maWVsZF9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlLCAmZmllbGRzKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIGlmIChmaWVsZHNbaV0tPmlzX2V4dGVuc2lvbigpKSByZXR1cm4gdHJ1ZTsKKworICAgIGlmIChmaWVsZHNbaV0tPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChmaWVsZHNbaV0tPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgZmllbGRzW2ldKTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzaXplOyBqKyspIHsKKyAgICAgICAgICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgICByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgZmllbGRzW2ldLCBqKTsKKyAgICAgICAgICBpZiAoVXNlc0V4dGVuc2lvbnMoc3ViX21lc3NhZ2UpKSByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkc1tpXSk7CisgICAgICAgIGlmIChVc2VzRXh0ZW5zaW9ucyhzdWJfbWVzc2FnZSkpIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0ZpbGVHZW5lcmF0b3I6OkZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IGZpbGVfKGZpbGUpLAorICAgIHBhcmFtc18ocGFyYW1zKSwKKyAgICBqYXZhX3BhY2thZ2VfKEZpbGVKYXZhUGFja2FnZShwYXJhbXMsIGZpbGUpKSwKKyAgICBjbGFzc25hbWVfKEZpbGVDbGFzc05hbWUocGFyYW1zLCBmaWxlKSkge30KKworRmlsZUdlbmVyYXRvcjo6fkZpbGVHZW5lcmF0b3IoKSB7fQorCitib29sIEZpbGVHZW5lcmF0b3I6OlZhbGlkYXRlKHN0cmluZyogZXJyb3IpIHsKKyAgLy8gQ2hlY2sgZm9yIGV4dGVuc2lvbnMKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlXy0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgaWYgKFVzZXNFeHRlbnNpb25zKGZpbGVfcHJvdG8pICYmICFwYXJhbXNfLnN0b3JlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBlcnJvci0+YXNzaWduKGZpbGVfLT5uYW1lKCkpOworICAgIGVycm9yLT5hcHBlbmQoCisgICAgICAgICI6IEphdmEgTkFOT19SVU5USU1FIG9ubHkgc3VwcG9ydHMgZXh0ZW5zaW9ucyB3aGVuIHRoZSAiCisgICAgICAgICInc3RvcmVfdW5rbm93bl9maWVsZHMnIGdlbmVyYXRvciBvcHRpb24gaXMgJ3RydWUnLiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChmaWxlXy0+c2VydmljZV9jb3VudCgpICE9IDAgJiYgIXBhcmFtc18uaWdub3JlX3NlcnZpY2VzKCkpIHsKKyAgICBlcnJvci0+YXNzaWduKGZpbGVfLT5uYW1lKCkpOworICAgIGVycm9yLT5hcHBlbmQoCisgICAgICAiOiBKYXZhIE5BTk9fUlVOVElNRSBkb2VzIG5vdCBzdXBwb3J0IHNlcnZpY2VzXCIiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIUlzT3V0ZXJDbGFzc05lZWRlZChwYXJhbXNfLCBmaWxlXykpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENoZWNrIHdoZXRoZXIgbGVnYWN5IGphdmFuYW5vIGdlbmVyYXRvciB3b3VsZCBvbWl0IHRoZSBvdXRlciBjbGFzcy4KKyAgaWYgKCFwYXJhbXNfLmhhc19qYXZhX291dGVyX2NsYXNzbmFtZShmaWxlXy0+bmFtZSgpKQorICAgICAgJiYgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID09IDEKKyAgICAgICYmIGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSA9PSAwICYmIGZpbGVfLT5leHRlbnNpb25fY291bnQoKSA9PSAwKSB7CisgICAgY291dCA8PCAiSU5GTzogIiA8PCBmaWxlXy0+bmFtZSgpIDw8ICI6IiA8PCBlbmRsOworICAgIGNvdXQgPDwgIkphdmFuYW5vIGdlbmVyYXRvciBoYXMgY2hhbmdlZCB0byBhbGlnbiB3aXRoIGphdmEgZ2VuZXJhdG9yLiAiCisgICAgICAgICJBbiBvdXRlciBjbGFzcyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgZmlsZSBhbmQgdGhlIHNpbmdsZSBtZXNzYWdlICIKKyAgICAgICAgImluIHRoZSBmaWxlIHdpbGwgYmVjb21lIGEgbmVzdGVkIGNsYXNzLiBVc2UgamF2YV9tdWx0aXBsZV9maWxlcyB0byAiCisgICAgICAgICJza2lwIGdlbmVyYXRpbmcgdGhlIG91dGVyIGNsYXNzLCBvciBzZXQgYW4gZXhwbGljaXQgIgorICAgICAgICAiamF2YV9vdXRlcl9jbGFzc25hbWUgdG8gc3VwcHJlc3MgdGhpcyBtZXNzYWdlLiIgPDwgZW5kbDsKKyAgfQorCisgIC8vIENoZWNrIHRoYXQgbm8gY2xhc3MgbmFtZSBtYXRjaGVzIHRoZSBmaWxlJ3MgY2xhc3MgbmFtZS4gIFRoaXMgaXMgYSBjb21tb24KKyAgLy8gcHJvYmxlbSB0aGF0IGxlYWRzIHRvIEphdmEgY29tcGlsZSBlcnJvcnMgdGhhdCBjYW4gYmUgaGFyZCB0byB1bmRlcnN0YW5kLgorICAvLyBJdCdzIGVzcGVjaWFsbHkgYmFkIHdoZW4gdXNpbmcgdGhlIGphdmFfbXVsdGlwbGVfZmlsZXMsIHNpbmNlIHdlIHdvdWxkCisgIC8vIGVuZCB1cCBvdmVyd3JpdGluZyB0aGUgb3V0ZXIgY2xhc3Mgd2l0aCBvbmUgb2YgdGhlIGlubmVyIG9uZXMuCisgIGJvb2wgZm91bmRfY29uZmxpY3QgPSBmYWxzZTsKKyAgZm9yIChpbnQgaSA9IDA7ICFmb3VuZF9jb25mbGljdCAmJiBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZmlsZV8tPm1lc3NhZ2VfdHlwZShpKS0+bmFtZSgpID09IGNsYXNzbmFtZV8pIHsKKyAgICAgIGZvdW5kX2NvbmZsaWN0ID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgaWYgKHBhcmFtc18uamF2YV9lbnVtX3N0eWxlKCkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgIWZvdW5kX2NvbmZsaWN0ICYmIGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKGZpbGVfLT5lbnVtX3R5cGUoaSktPm5hbWUoKSA9PSBjbGFzc25hbWVfKSB7CisgICAgICAgIGZvdW5kX2NvbmZsaWN0ID0gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgaWYgKGZvdW5kX2NvbmZsaWN0KSB7CisgICAgZXJyb3ItPmFzc2lnbihmaWxlXy0+bmFtZSgpKTsKKyAgICBlcnJvci0+YXBwZW5kKAorICAgICAgIjogQ2Fubm90IGdlbmVyYXRlIEphdmEgb3V0cHV0IGJlY2F1c2UgdGhlIGZpbGUncyBvdXRlciBjbGFzcyBuYW1lLCBcIiIpOworICAgIGVycm9yLT5hcHBlbmQoY2xhc3NuYW1lXyk7CisgICAgZXJyb3ItPmFwcGVuZCgKKyAgICAgICJcIiwgbWF0Y2hlcyB0aGUgbmFtZSBvZiBvbmUgb2YgdGhlIHR5cGVzIGRlY2xhcmVkIGluc2lkZSBpdC4gICIKKyAgICAgICJQbGVhc2UgZWl0aGVyIHJlbmFtZSB0aGUgdHlwZSBvciB1c2UgdGhlIGphdmFfb3V0ZXJfY2xhc3NuYW1lICIKKyAgICAgICJvcHRpb24gdG8gc3BlY2lmeSBhIGRpZmZlcmVudCBvdXRlciBjbGFzcyBuYW1lIGZvciB0aGUgLnByb3RvIGZpbGUuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFdlIGRvbid0IGltcG9ydCBhbnl0aGluZyBiZWNhdXNlIHdlIHJlZmVyIHRvIGFsbCBjbGFzc2VzIGJ5IHRoZWlyCisgIC8vIGZ1bGx5LXF1YWxpZmllZCBuYW1lcyBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iKTsKKyAgaWYgKCFqYXZhX3BhY2thZ2VfLmVtcHR5KCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwYWNrYWdlICRwYWNrYWdlJDtcbiIsCisgICAgICAicGFja2FnZSIsIGphdmFfcGFja2FnZV8pOworICB9CisKKyAgLy8gTm90ZTogY29uc3RhbnRzIChmcm9tIGVudW1zLCBlbWl0dGVkIGluIHRoZSBsb29wIGJlbG93KSBtYXkgaGF2ZSB0aGUgc2FtZSBuYW1lcyBhcyBjb25zdGFudHMKKyAgLy8gaW4gdGhlIG5lc3RlZCBjbGFzc2VzLiBUaGlzIGNhdXNlcyBKYXZhIHdhcm5pbmdzLCBidXQgaXMgbm90IGZhdGFsLCBzbyB3ZSBzdXBwcmVzcyB0aG9zZQorICAvLyB3YXJuaW5ncyBoZXJlIGluIHRoZSB0b3AtbW9zdCBjbGFzcyBkZWNsYXJhdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJAU3VwcHJlc3NXYXJuaW5ncyhcImhpZGluZ1wiKVxuIgorICAgICJwdWJsaWMgaW50ZXJmYWNlICRjbGFzc25hbWUkIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEV4dGVuc2lvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBFeHRlbnNpb25HZW5lcmF0b3IoZmlsZV8tPmV4dGVuc2lvbihpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICAvLyBFbnVtcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEVudW1HZW5lcmF0b3IoZmlsZV8tPmVudW1fdHlwZShpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICAvLyBNZXNzYWdlcy4KKyAgaWYgKCFwYXJhbXNfLmphdmFfbXVsdGlwbGVfZmlsZXMoZmlsZV8tPm5hbWUoKSkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBNZXNzYWdlR2VuZXJhdG9yKGZpbGVfLT5tZXNzYWdlX3R5cGUoaSksIHBhcmFtc18pLkdlbmVyYXRlKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIC8vIFN0YXRpYyB2YXJpYWJsZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBSZXVzZSBNZXNzYWdlR2VuZXJhdG9yIG9iamVjdHM/CisgICAgTWVzc2FnZUdlbmVyYXRvcihmaWxlXy0+bWVzc2FnZV90eXBlKGkpLCBwYXJhbXNfKS5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcyhwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBHZW5lcmF0b3JDbGFzcywgdHlwZW5hbWUgRGVzY3JpcHRvckNsYXNzPgorc3RhdGljIHZvaWQgR2VuZXJhdGVTaWJsaW5nKGNvbnN0IHN0cmluZyYgcGFja2FnZV9kaXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBqYXZhX3BhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvckNsYXNzKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIG91dHB1dF9kaXJlY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGZpbGVfbGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJhbXMmIHBhcmFtcykgeworICBzdHJpbmcgZmlsZW5hbWUgPSBwYWNrYWdlX2RpciArIGRlc2NyaXB0b3ItPm5hbWUoKSArICIuamF2YSI7CisgIGZpbGVfbGlzdC0+cHVzaF9iYWNrKGZpbGVuYW1lKTsKKworICBzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgIG91dHB1dF9kaXJlY3RvcnktPk9wZW4oZmlsZW5hbWUpKTsKKyAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisKKyAgcHJpbnRlci5QcmludCgKKyAgICAiLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCFcbiIpOworICBpZiAoIWphdmFfcGFja2FnZS5lbXB0eSgpKSB7CisgICAgcHJpbnRlci5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwYWNrYWdlICRwYWNrYWdlJDtcbiIsCisgICAgICAicGFja2FnZSIsIGphdmFfcGFja2FnZSk7CisgIH0KKworICBHZW5lcmF0b3JDbGFzcyhkZXNjcmlwdG9yLCBwYXJhbXMpLkdlbmVyYXRlKCZwcmludGVyKTsKK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZVNpYmxpbmdzKGNvbnN0IHN0cmluZyYgcGFja2FnZV9kaXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogb3V0cHV0X2RpcmVjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZmlsZV9saXN0KSB7CisgIGlmIChwYXJhbXNfLmphdmFfbXVsdGlwbGVfZmlsZXMoZmlsZV8tPm5hbWUoKSkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBHZW5lcmF0ZVNpYmxpbmc8TWVzc2FnZUdlbmVyYXRvcj4ocGFja2FnZV9kaXIsIGphdmFfcGFja2FnZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfZGlyZWN0b3J5LCBmaWxlX2xpc3QsIHBhcmFtc18pOworICAgIH0KKworICAgIGlmIChwYXJhbXNfLmphdmFfZW51bV9zdHlsZSgpKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICAgIEdlbmVyYXRlU2libGluZzxFbnVtR2VuZXJhdG9yPihwYWNrYWdlX2RpciwgamF2YV9wYWNrYWdlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfLT5lbnVtX3R5cGUoaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfZGlyZWN0b3J5LCBmaWxlX2xpc3QsIHBhcmFtc18pOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxN2VhZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuaApAQCAtMCwwICsxLDk0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRklMRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0ZJTEVfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7ICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIGNsYXNzIEdlbmVyYXRvckNvbnRleHQ7ICAgICAvLyBjb2RlX2dlbmVyYXRvci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitjbGFzcyBGaWxlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfkZpbGVHZW5lcmF0b3IoKTsKKworICAvLyBDaGVja3MgZm9yIHByb2JsZW1zIHRoYXQgd291bGQgb3RoZXJ3aXNlIGxlYWQgdG8gY3J5cHRpYyBjb21waWxlIGVycm9ycy4KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBubyBwcm9ibGVtcywgb3Igd3JpdGVzIGFuIGVycm9yIGRlc2NyaXB0aW9uIHRvCisgIC8vIHRoZSBnaXZlbiBzdHJpbmcgYW5kIHJldHVybnMgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIFZhbGlkYXRlKHN0cmluZyogZXJyb3IpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIElmIHdlIGFyZW4ndCBwdXR0aW5nIGV2ZXJ5dGhpbmcgaW50byBvbmUgZmlsZSwgdGhpcyB3aWxsIHdyaXRlIGFsbCB0aGUKKyAgLy8gZmlsZXMgb3RoZXIgdGhhbiB0aGUgb3V0ZXIgZmlsZSAoaS5lLiBvbmUgZm9yIGVhY2ggbWVzc2FnZSwgZW51bSwgYW5kCisgIC8vIHNlcnZpY2UgdHlwZSkuCisgIHZvaWQgR2VuZXJhdGVTaWJsaW5ncyhjb25zdCBzdHJpbmcmIHBhY2thZ2VfZGlyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogb3V0cHV0X2RpcmVjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBmaWxlX2xpc3QpOworCisgIGNvbnN0IHN0cmluZyYgamF2YV9wYWNrYWdlKCkgeyByZXR1cm4gamF2YV9wYWNrYWdlXzsgfQorICBjb25zdCBzdHJpbmcmIGNsYXNzbmFtZSgpICAgIHsgcmV0dXJuIGNsYXNzbmFtZV87ICAgIH0KKworIHByaXZhdGU6CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBzdHJpbmcgamF2YV9wYWNrYWdlXzsKKyAgc3RyaW5nIGNsYXNzbmFtZV87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpbGVHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19GSUxFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2dlbmVyYXRvci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWZiY2Q1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuY2MKQEAgLTAsMCArMSwyMTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK25hbWVzcGFjZSB7CisKK3N0cmluZyBUcmltU3RyaW5nKGNvbnN0IHN0cmluZyYgcykgeworICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydCA9IHMuZmluZF9maXJzdF9ub3Rfb2YoIiBcblxyXHQiKTsKKyAgaWYgKHN0YXJ0ID09IHN0cmluZzo6bnBvcykgeworICAgIHJldHVybiAiIjsKKyAgfQorICBzdHJpbmc6OnNpemVfdHlwZSBlbmQgPSBzLmZpbmRfbGFzdF9ub3Rfb2YoIiBcblxyXHQiKSArIDE7CisgIHJldHVybiBzLnN1YnN0cihzdGFydCwgZW5kIC0gc3RhcnQpOworfQorCit9IC8vIG5hbWVzcGFjZQorCit2b2lkIFVwZGF0ZVBhcmFtc1JlY3Vyc2l2ZWx5KFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIC8vIEFkZCBhbnkgcGFyYW1ldGVycyBmb3IgdGhpcyBmaWxlCisgIGlmIChmaWxlLT5vcHRpb25zKCkuaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkpIHsKKyAgICBwYXJhbXMuc2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKAorICAgICAgZmlsZS0+bmFtZSgpLCBmaWxlLT5vcHRpb25zKCkuamF2YV9vdXRlcl9jbGFzc25hbWUoKSk7CisgIH0KKyAgaWYgKGZpbGUtPm9wdGlvbnMoKS5oYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICBwYXJhbXMuc2V0X2phdmFfcGFja2FnZSgKKyAgICAgIGZpbGUtPm5hbWUoKSwgZmlsZS0+b3B0aW9ucygpLmphdmFfcGFja2FnZSgpKTsKKyAgfQorICBpZiAoZmlsZS0+b3B0aW9ucygpLmhhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkpIHsKKyAgICBwYXJhbXMuc2V0X2phdmFfbXVsdGlwbGVfZmlsZXMoCisgICAgICBmaWxlLT5uYW1lKCksIGZpbGUtPm9wdGlvbnMoKS5qYXZhX211bHRpcGxlX2ZpbGVzKCkpOworICB9CisKKyAgLy8gTG9vcCB0aHJvdWdoIGFsbCBkZXBlbmRlbnQgZmlsZXMgcmVjdXJzaXZlbHkKKyAgLy8gYWRkaW5nIGRlcAorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgVXBkYXRlUGFyYW1zUmVjdXJzaXZlbHkocGFyYW1zLCBmaWxlLT5kZXBlbmRlbmN5KGkpKTsKKyAgfQorfQorCitKYXZhTmFub0dlbmVyYXRvcjo6SmF2YU5hbm9HZW5lcmF0b3IoKSB7fQorSmF2YU5hbm9HZW5lcmF0b3I6On5KYXZhTmFub0dlbmVyYXRvcigpIHt9CisKK2Jvb2wgSmF2YU5hbm9HZW5lcmF0b3I6OkdlbmVyYXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogb3V0cHV0X2RpcmVjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3QgeworICB2ZWN0b3I8cGFpcjxzdHJpbmcsIHN0cmluZz4gPiBvcHRpb25zOworCisgIFBhcnNlR2VuZXJhdG9yUGFyYW1ldGVyKHBhcmFtZXRlciwgJm9wdGlvbnMpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIHBhcnNlIGdlbmVyYXRvciBvcHRpb25zCisKKyAgLy8gTmFtZSBhIGZpbGUgd2hlcmUgd2Ugd2lsbCB3cml0ZSBhIGxpc3Qgb2YgZ2VuZXJhdGVkIGZpbGUgbmFtZXMsIG9uZQorICAvLyBwZXIgbGluZS4KKyAgc3RyaW5nIG91dHB1dF9saXN0X2ZpbGU7CisgIFBhcmFtcyBwYXJhbXMoZmlsZS0+bmFtZSgpKTsKKworICAvLyBVcGRhdGUgcGVyIGZpbGUgcGFyYW1zCisgIFVwZGF0ZVBhcmFtc1JlY3Vyc2l2ZWx5KHBhcmFtcywgZmlsZSk7CisKKyAgLy8gUmVwbGFjZSBhbnkgZXhpc3Rpbmcgb3B0aW9ucyB3aXRoIG9uZXMgZnJvbSBjb21tYW5kIGxpbmUKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnNpemUoKTsgaSsrKSB7CisgICAgc3RyaW5nIG9wdGlvbl9uYW1lID0gVHJpbVN0cmluZyhvcHRpb25zW2ldLmZpcnN0KTsKKyAgICBzdHJpbmcgb3B0aW9uX3ZhbHVlID0gVHJpbVN0cmluZyhvcHRpb25zW2ldLnNlY29uZCk7CisgICAgaWYgKG9wdGlvbl9uYW1lID09ICJvdXRwdXRfbGlzdF9maWxlIikgeworICAgICAgb3V0cHV0X2xpc3RfZmlsZSA9IG9wdGlvbl92YWx1ZTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbl9uYW1lID09ICJqYXZhX3BhY2thZ2UiKSB7CisgICAgICAgIHZlY3RvcjxzdHJpbmc+IHBhcnRzOworICAgICAgICBTcGxpdFN0cmluZ1VzaW5nKG9wdGlvbl92YWx1ZSwgInwiLCAmcGFydHMpOworICAgICAgICBpZiAocGFydHMuc2l6ZSgpICE9IDIpIHsKKyAgICAgICAgICAqZXJyb3IgPSAiQmFkIGphdmFfcGFja2FnZSwgZXhwZWN0aW5nIGZpbGVuYW1lfFBhY2thZ2VOYW1lIGZvdW5kICciCisgICAgICAgICAgICArIG9wdGlvbl92YWx1ZSArICInIjsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcGFyYW1zLnNldF9qYXZhX3BhY2thZ2UocGFydHNbMF0sIHBhcnRzWzFdKTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbl9uYW1lID09ICJqYXZhX291dGVyX2NsYXNzbmFtZSIpIHsKKyAgICAgICAgdmVjdG9yPHN0cmluZz4gcGFydHM7CisgICAgICAgIFNwbGl0U3RyaW5nVXNpbmcob3B0aW9uX3ZhbHVlLCAifCIsICZwYXJ0cyk7CisgICAgICAgIGlmIChwYXJ0cy5zaXplKCkgIT0gMikgeworICAgICAgICAgICplcnJvciA9ICJCYWQgamF2YV9vdXRlcl9jbGFzc25hbWUsICIKKyAgICAgICAgICAgICAgICAgICAiZXhwZWN0aW5nIGZpbGVuYW1lfENsYXNzTmFtZSBmb3VuZCAnIgorICAgICAgICAgICAgICAgICAgICsgb3B0aW9uX3ZhbHVlICsgIiciOworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBwYXJhbXMuc2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKHBhcnRzWzBdLCBwYXJ0c1sxXSk7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAic3RvcmVfdW5rbm93bl9maWVsZHMiKSB7CisgICAgICBwYXJhbXMuc2V0X3N0b3JlX3Vua25vd25fZmllbGRzKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gImphdmFfbXVsdGlwbGVfZmlsZXMiKSB7CisgICAgICBwYXJhbXMuc2V0X292ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXMob3B0aW9uX3ZhbHVlID09ICJ0cnVlIik7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiamF2YV9uYW5vX2dlbmVyYXRlX2hhcyIpIHsKKyAgICAgIHBhcmFtcy5zZXRfZ2VuZXJhdGVfaGFzKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gImVudW1fc3R5bGUiKSB7CisgICAgICBwYXJhbXMuc2V0X2phdmFfZW51bV9zdHlsZShvcHRpb25fdmFsdWUgPT0gImphdmEiKTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbl9uYW1lID09ICJvcHRpb25hbF9maWVsZF9zdHlsZSIpIHsKKyAgICAgIHBhcmFtcy5zZXRfb3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzKG9wdGlvbl92YWx1ZSA9PSAiYWNjZXNzb3JzIik7CisgICAgICBwYXJhbXMuc2V0X3VzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMob3B0aW9uX3ZhbHVlID09ICJyZWZ0eXBlcyIKKyAgICAgICAgICB8fCBvcHRpb25fdmFsdWUgPT0gInJlZnR5cGVzX2NvbXBhdF9tb2RlIik7CisgICAgICBwYXJhbXMuc2V0X3JlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtcygKKyAgICAgICAgICBvcHRpb25fdmFsdWUgPT0gInJlZnR5cGVzX2NvbXBhdF9tb2RlIik7CisgICAgICBpZiAob3B0aW9uX3ZhbHVlID09ICJyZWZ0eXBlc19jb21wYXRfbW9kZSIpIHsKKyAgICAgICAgcGFyYW1zLnNldF9nZW5lcmF0ZV9jbGVhcihmYWxzZSk7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiZ2VuZXJhdGVfZXF1YWxzIikgeworICAgICAgcGFyYW1zLnNldF9nZW5lcmF0ZV9lcXVhbHMob3B0aW9uX3ZhbHVlID09ICJ0cnVlIik7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiaWdub3JlX3NlcnZpY2VzIikgeworICAgICAgcGFyYW1zLnNldF9pZ25vcmVfc2VydmljZXMob3B0aW9uX3ZhbHVlID09ICJ0cnVlIik7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAicGFyY2VsYWJsZV9tZXNzYWdlcyIpIHsKKyAgICAgIHBhcmFtcy5zZXRfcGFyY2VsYWJsZV9tZXNzYWdlcyhvcHRpb25fdmFsdWUgPT0gInRydWUiKTsKKyAgICB9IGVsc2UgeworICAgICAgKmVycm9yID0gIklnbm9yZSB1bmtub3duIGphdmFuYW5vIGdlbmVyYXRvciBvcHRpb246ICIgKyBvcHRpb25fbmFtZTsKKyAgICB9CisgIH0KKworICAvLyBDaGVjayBpbGxlZ2FsIHBhcmFtZXRlciBjb21iaW5hdGlvbnMKKyAgLy8gTm90ZTogdGhlIGVudW0tbGlrZSBvcHRpb25hbF9maWVsZF9zdHlsZSBnZW5lcmF0b3IgcGFyYW0gZW5zdXJlcworICAvLyB0aGF0IHdlIGNhbiBuZXZlciBoYXZlIGlsbGVnYWwgY29tYmluYXRpb25zIG9mIGZpZWxkIHN0eWxlcworICAvLyAoZS5nLiByZWZ0eXBlcyBhbmQgYWNjZXNzb3JzIGNhbid0IGJlIG9uIGF0IHRoZSBzYW1lIHRpbWUpLgorICBpZiAocGFyYW1zLmdlbmVyYXRlX2hhcygpCisgICAgICAmJiAocGFyYW1zLm9wdGlvbmFsX2ZpZWxkX2FjY2Vzc29ycygpCisgICAgICAgICAgfHwgcGFyYW1zLnVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKSkpIHsKKyAgICBlcnJvci0+YXNzaWduKCJqYXZhX25hbm9fZ2VuZXJhdGVfaGFzPXRydWUgY2Fubm90IGJlIHVzZWQgaW4gY29uanVuY3Rpb24iCisgICAgICAgICIgd2l0aCBvcHRpb25hbF9maWVsZF9zdHlsZT1hY2Nlc3NvcnMgb3Igb3B0aW9uYWxfZmllbGRfc3R5bGU9cmVmdHlwZXMiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEZpbGVHZW5lcmF0b3IgZmlsZV9nZW5lcmF0b3IoZmlsZSwgcGFyYW1zKTsKKyAgaWYgKCFmaWxlX2dlbmVyYXRvci5WYWxpZGF0ZShlcnJvcikpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBzdHJpbmcgcGFja2FnZV9kaXIgPQorICAgIFN0cmluZ1JlcGxhY2UoZmlsZV9nZW5lcmF0b3IuamF2YV9wYWNrYWdlKCksICIuIiwgIi8iLCB0cnVlKTsKKyAgaWYgKCFwYWNrYWdlX2Rpci5lbXB0eSgpKSBwYWNrYWdlX2RpciArPSAiLyI7CisKKyAgdmVjdG9yPHN0cmluZz4gYWxsX2ZpbGVzOworCisgIGlmIChJc091dGVyQ2xhc3NOZWVkZWQocGFyYW1zLCBmaWxlKSkgeworICAgIHN0cmluZyBqYXZhX2ZpbGVuYW1lID0gcGFja2FnZV9kaXI7CisgICAgamF2YV9maWxlbmFtZSArPSBmaWxlX2dlbmVyYXRvci5jbGFzc25hbWUoKTsKKyAgICBqYXZhX2ZpbGVuYW1lICs9ICIuamF2YSI7CisgICAgYWxsX2ZpbGVzLnB1c2hfYmFjayhqYXZhX2ZpbGVuYW1lKTsKKworICAgIC8vIEdlbmVyYXRlIG1haW4gamF2YSBmaWxlLgorICAgIHNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICBvdXRwdXRfZGlyZWN0b3J5LT5PcGVuKGphdmFfZmlsZW5hbWUpKTsKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBmaWxlX2dlbmVyYXRvci5HZW5lcmF0ZSgmcHJpbnRlcik7CisgIH0KKworICAvLyBHZW5lcmF0ZSBzaWJsaW5nIGZpbGVzLgorICBmaWxlX2dlbmVyYXRvci5HZW5lcmF0ZVNpYmxpbmdzKHBhY2thZ2VfZGlyLCBvdXRwdXRfZGlyZWN0b3J5LCAmYWxsX2ZpbGVzKTsKKworICAvLyBHZW5lcmF0ZSBvdXRwdXQgbGlzdCBpZiByZXF1ZXN0ZWQuCisgIGlmICghb3V0cHV0X2xpc3RfZmlsZS5lbXB0eSgpKSB7CisgICAgLy8gR2VuZXJhdGUgb3V0cHV0IGxpc3QuICBUaGlzIGlzIGp1c3QgYSBzaW1wbGUgdGV4dCBmaWxlIHBsYWNlZCBpbiBhCisgICAgLy8gZGV0ZXJtaW5pc3RpYyBsb2NhdGlvbiB3aGljaCBsaXN0cyB0aGUgLmphdmEgZmlsZXMgYmVpbmcgZ2VuZXJhdGVkLgorICAgIHNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBzcmNsaXN0X3Jhd19vdXRwdXQoCisgICAgICBvdXRwdXRfZGlyZWN0b3J5LT5PcGVuKG91dHB1dF9saXN0X2ZpbGUpKTsKKyAgICBpbzo6UHJpbnRlciBzcmNsaXN0X3ByaW50ZXIoc3JjbGlzdF9yYXdfb3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICBzcmNsaXN0X3ByaW50ZXIuUHJpbnQoIiRmaWxlbmFtZSRcbiIsICJmaWxlbmFtZSIsIGFsbF9maWxlc1tpXSk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmY5ZjdmMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmgKQEAgLTAsMCArMSw3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gR2VuZXJhdGVzIEphdmEgbmFubyBjb2RlIGZvciBhIGdpdmVuIC5wcm90byBmaWxlLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19OQU5PX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX05BTk9fR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworLy8gQ29kZUdlbmVyYXRvciBpbXBsZW1lbnRhdGlvbiB3aGljaCBnZW5lcmF0ZXMgSmF2YSBuYW5vIGNvZGUuICBJZiB5b3UgY3JlYXRlIHlvdXIKKy8vIG93biBwcm90b2NvbCBjb21waWxlciBiaW5hcnkgYW5kIHlvdSB3YW50IGl0IHRvIHN1cHBvcnQgSmF2YSBvdXRwdXQgZm9yIHRoZQorLy8gbmFubyBydW50aW1lLCB5b3UgY2FuIGRvIHNvIGJ5IHJlZ2lzdGVyaW5nIGFuIGluc3RhbmNlIG9mIHRoaXMgQ29kZUdlbmVyYXRvciB3aXRoCisvLyB0aGUgQ29tbWFuZExpbmVJbnRlcmZhY2UgaW4geW91ciBtYWluKCkgZnVuY3Rpb24uCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIEphdmFOYW5vR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSmF2YU5hbm9HZW5lcmF0b3IoKTsKKyAgfkphdmFOYW5vR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBDb2RlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBvdXRwdXRfZGlyZWN0b3J5LAorICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEphdmFOYW5vR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTkFOT19HRU5FUkFUT1JfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQyYWU5ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5jYwpAQCAtMCwwICsxLDU4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2NvbnN0IGNoYXIga1RoaWNrU2VwYXJhdG9yW10gPQorICAiLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIjsKK2NvbnN0IGNoYXIga1RoaW5TZXBhcmF0b3JbXSA9CisgICIvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOworCitjbGFzcyBSZW5hbWVLZXl3b3JkcyB7CisgcHJpdmF0ZToKKyAgaGFzaF9zZXQ8c3RyaW5nPiBqYXZhX2tleXdvcmRzX3NldF87CisKKyBwdWJsaWM6CisgIFJlbmFtZUtleXdvcmRzKCkgeworICAgIHN0YXRpYyBjb25zdCBjaGFyKiBrSmF2YUtleXdvcmRzTGlzdFtdID0geworICAgICAgLy8gUmVzZXJ2ZWQgSmF2YSBLZXl3b3JkcworICAgICAgImFic3RyYWN0IiwgImFzc2VydCIsICJib29sZWFuIiwgImJyZWFrIiwgImJ5dGUiLCAiY2FzZSIsICJjYXRjaCIsCisgICAgICAiY2hhciIsICJjbGFzcyIsICJjb25zdCIsICJjb250aW51ZSIsICJkZWZhdWx0IiwgImRvIiwgImRvdWJsZSIsICJlbHNlIiwKKyAgICAgICJlbnVtIiwgImV4dGVuZHMiLCAiZmluYWwiLCAiZmluYWxseSIsICJmbG9hdCIsICJmb3IiLCAiZ290byIsICJpZiIsCisgICAgICAiaW1wbGVtZW50cyIsICJpbXBvcnQiLCAiaW5zdGFuY2VvZiIsICJpbnQiLCAiaW50ZXJmYWNlIiwgImxvbmciLAorICAgICAgIm5hdGl2ZSIsICJuZXciLCAicGFja2FnZSIsICJwcml2YXRlIiwgInByb3RlY3RlZCIsICJwdWJsaWMiLCAicmV0dXJuIiwKKyAgICAgICJzaG9ydCIsICJzdGF0aWMiLCAic3RyaWN0ZnAiLCAic3VwZXIiLCAic3dpdGNoIiwgInN5bmNocm9uaXplZCIsCisgICAgICAidGhpcyIsICJ0aHJvdyIsICJ0aHJvd3MiLCAidHJhbnNpZW50IiwgInRyeSIsICJ2b2lkIiwgInZvbGF0aWxlIiwgIndoaWxlIiwKKworICAgICAgLy8gUmVzZXJ2ZWQgS2V5d29yZHMgZm9yIExpdGVyYWxzCisgICAgICAiZmFsc2UiLCAibnVsbCIsICJ0cnVlIgorICAgIH07CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoa0phdmFLZXl3b3Jkc0xpc3QpOyBpKyspIHsKKyAgICAgIGphdmFfa2V5d29yZHNfc2V0Xy5pbnNlcnQoa0phdmFLZXl3b3Jkc0xpc3RbaV0pOworICAgIH0KKyAgfQorCisgIC8vIFVzZWQgdG8gcmVuYW1lIHRoZSBhIGZpZWxkIG5hbWUgaWYgaXQncyBhIGphdmEga2V5d29yZC4gIFNwZWNpZmljYWxseQorICAvLyB0aGlzIGlzIHVzZWQgdG8gcmVuYW1lIHRoZSBbIm5hbWUiXSBvciBbImNhcGl0YWxpemVkX25hbWUiXSBmaWVsZCBwYXJhbXMuCisgIC8vIChodHRwOi8vZG9jcy5vcmFjbGUuY29tL2phdmFzZS90dXRvcmlhbC9qYXZhL251dHNhbmRib2x0cy9fa2V5d29yZHMuaHRtbCkKKyAgc3RyaW5nIFJlbmFtZUphdmFLZXl3b3Jkc0ltcGwoY29uc3Qgc3RyaW5nJiBpbnB1dCkgeworICAgIHN0cmluZyByZXN1bHQgPSBpbnB1dDsKKworICAgIGlmIChqYXZhX2tleXdvcmRzX3NldF8uZmluZChyZXN1bHQpICE9IGphdmFfa2V5d29yZHNfc2V0Xy5lbmQoKSkgeworICAgICAgcmVzdWx0ICs9ICJfIjsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKK307CisKK3N0YXRpYyBSZW5hbWVLZXl3b3JkcyBzUmVuYW1lS2V5d29yZHM7CisKK25hbWVzcGFjZSB7CisKK2NvbnN0IGNoYXIqIGtEZWZhdWx0UGFja2FnZSA9ICIiOworCitjb25zdCBzdHJpbmcmIEZpZWxkTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIEdyb3VwcyBhcmUgaGFja3k6ICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaXMganVzdCB0aGUgbG93ZXItY2FzZWQgbmFtZQorICAvLyBvZiB0aGUgZ3JvdXAgdHlwZS4gIEluIEphdmEsIHRob3VnaCwgd2Ugd291bGQgbGlrZSB0byByZXRhaW4gdGhlIG9yaWdpbmFsCisgIC8vIGNhcGl0YWxpemF0aW9uIG9mIHRoZSB0eXBlIG5hbWUuCisgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHJldHVybiBmaWVsZC0+bWVzc2FnZV90eXBlKCktPm5hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZmllbGQtPm5hbWUoKTsKKyAgfQorfQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZUltcGwoY29uc3Qgc3RyaW5nJiBpbnB1dCwgYm9vbCBjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgLy8gTm90ZTogIEkgZGlzdHJ1c3QgY3R5cGUuaCBkdWUgdG8gbG9jYWxlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgIGlmICgnYScgPD0gaW5wdXRbaV0gJiYgaW5wdXRbaV0gPD0gJ3onKSB7CisgICAgICBpZiAoY2FwX25leHRfbGV0dGVyKSB7CisgICAgICAgIHJlc3VsdCArPSBpbnB1dFtpXSArICgnQScgLSAnYScpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgfQorICAgICAgY2FwX25leHRfbGV0dGVyID0gZmFsc2U7CisgICAgfSBlbHNlIGlmICgnQScgPD0gaW5wdXRbaV0gJiYgaW5wdXRbaV0gPD0gJ1onKSB7CisgICAgICBpZiAoaSA9PSAwICYmICFjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgICAgICAgLy8gRm9yY2UgZmlyc3QgbGV0dGVyIHRvIGxvd2VyLWNhc2UgdW5sZXNzIGV4cGxpY2l0bHkgdG9sZCB0bworICAgICAgICAvLyBjYXBpdGFsaXplIGl0LgorICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV0gKyAoJ2EnIC0gJ0EnKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIENhcGl0YWwgbGV0dGVycyBhZnRlciB0aGUgZmlyc3QgYXJlIGxlZnQgYXMtaXMuCisgICAgICAgIHJlc3VsdCArPSBpbnB1dFtpXTsKKyAgICAgIH0KKyAgICAgIGNhcF9uZXh0X2xldHRlciA9IGZhbHNlOworICAgIH0gZWxzZSBpZiAoJzAnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICc5JykgeworICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgY2FwX25leHRfbGV0dGVyID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgY2FwX25leHRfbGV0dGVyID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2VJbXBsKEZpZWxkTmFtZShmaWVsZCksIGZhbHNlKTsKK30KKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlSW1wbChGaWVsZE5hbWUoZmllbGQpLCB0cnVlKTsKK30KKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlSW1wbChtZXRob2QtPm5hbWUoKSwgZmFsc2UpOworfQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlSW1wbChvbmVvZi0+bmFtZSgpLCBmYWxzZSk7Cit9CisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZikgeworICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZUltcGwob25lb2YtPm5hbWUoKSwgdHJ1ZSk7Cit9CisKK3N0cmluZyBSZW5hbWVKYXZhS2V5d29yZHMoY29uc3Qgc3RyaW5nJiBpbnB1dCkgeworICByZXR1cm4gc1JlbmFtZUtleXdvcmRzLlJlbmFtZUphdmFLZXl3b3Jkc0ltcGwoaW5wdXQpOworfQorCitzdHJpbmcgU3RyaXBQcm90byhjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIGlmIChIYXNTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG9kZXZlbCIpKSB7CisgICAgcmV0dXJuIFN0cmlwU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvZGV2ZWwiKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gU3RyaXBTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG8iKTsKKyAgfQorfQorCitzdHJpbmcgRmlsZUNsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgaWYgKHBhcmFtcy5oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoZmlsZS0+bmFtZSgpKSkgeworICAgIHJldHVybiBwYXJhbXMuamF2YV9vdXRlcl9jbGFzc25hbWUoZmlsZS0+bmFtZSgpKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBVc2UgdGhlIGZpbGVuYW1lIGl0c2VsZiB3aXRoIHVuZGVyc2NvcmVzIHJlbW92ZWQKKyAgICAvLyBhbmQgYSBDYW1lbENhc2Ugc3R5bGUgbmFtZS4KKyAgICBzdHJpbmcgYmFzZW5hbWU7CisgICAgc3RyaW5nOjpzaXplX3R5cGUgbGFzdF9zbGFzaCA9IGZpbGUtPm5hbWUoKS5maW5kX2xhc3Rfb2YoJy8nKTsKKyAgICBpZiAobGFzdF9zbGFzaCA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIGJhc2VuYW1lID0gZmlsZS0+bmFtZSgpOworICAgIH0gZWxzZSB7CisgICAgICBiYXNlbmFtZSA9IGZpbGUtPm5hbWUoKS5zdWJzdHIobGFzdF9zbGFzaCArIDEpOworICAgIH0KKyAgICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZUltcGwoU3RyaXBQcm90byhiYXNlbmFtZSksIHRydWUpOworICB9Cit9CisKK3N0cmluZyBGaWxlSmF2YVBhY2thZ2UoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGlmIChwYXJhbXMuaGFzX2phdmFfcGFja2FnZShmaWxlLT5uYW1lKCkpKSB7CisgICAgcmV0dXJuIHBhcmFtcy5qYXZhX3BhY2thZ2UoZmlsZS0+bmFtZSgpKTsKKyAgfSBlbHNlIHsKKyAgICBzdHJpbmcgcmVzdWx0ID0ga0RlZmF1bHRQYWNrYWdlOworICAgIGlmICghZmlsZS0+cGFja2FnZSgpLmVtcHR5KCkpIHsKKyAgICAgIGlmICghcmVzdWx0LmVtcHR5KCkpIHJlc3VsdCArPSAnLic7CisgICAgICByZXN1bHQgKz0gZmlsZS0+cGFja2FnZSgpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKK2Jvb2wgSXNPdXRlckNsYXNzTmVlZGVkKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICAvLyBJZiBqYXZhX211bHRpcGxlX2ZpbGVzIGlzIGZhbHNlLCB0aGUgb3V0ZXIgY2xhc3MgaXMgYWx3YXlzIG5lZWRlZC4KKyAgaWYgKCFwYXJhbXMuamF2YV9tdWx0aXBsZV9maWxlcyhmaWxlLT5uYW1lKCkpKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBGaWxlLXNjb3BlIGV4dGVuc2lvbnMgbmVlZCB0aGUgb3V0ZXIgY2xhc3MgYXMgdGhlIHNjb3BlLgorICBpZiAoZmlsZS0+ZXh0ZW5zaW9uX2NvdW50KCkgIT0gMCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gSWYgY29udGFpbmVyIGludGVyZmFjZXMgYXJlIG5vdCBnZW5lcmF0ZWQsIGZpbGUtc2NvcGUgZW51bXMgbmVlZCB0aGUKKyAgLy8gb3V0ZXIgY2xhc3MgYXMgdGhlIHNjb3BlLgorICBpZiAoZmlsZS0+ZW51bV90eXBlX2NvdW50KCkgIT0gMCAmJiAhcGFyYW1zLmphdmFfZW51bV9zdHlsZSgpKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICByZXR1cm4gZmFsc2U7Cit9CisKK3N0cmluZyBUb0phdmFOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBzdHJpbmcmIG5hbWUsIGJvb2wgaXNfY2xhc3MsCisgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBzdHJpbmcgcmVzdWx0OworICBpZiAocGFyZW50ICE9IE5VTEwpIHsKKyAgICByZXN1bHQuYXBwZW5kKENsYXNzTmFtZShwYXJhbXMsIHBhcmVudCkpOworICB9IGVsc2UgaWYgKGlzX2NsYXNzICYmIHBhcmFtcy5qYXZhX211bHRpcGxlX2ZpbGVzKGZpbGUtPm5hbWUoKSkpIHsKKyAgICByZXN1bHQuYXBwZW5kKEZpbGVKYXZhUGFja2FnZShwYXJhbXMsIGZpbGUpKTsKKyAgfSBlbHNlIHsKKyAgICByZXN1bHQuYXBwZW5kKENsYXNzTmFtZShwYXJhbXMsIGZpbGUpKTsKKyAgfQorICBpZiAoIXJlc3VsdC5lbXB0eSgpKSByZXN1bHQuYXBwZW5kKDEsICcuJyk7CisgIHJlc3VsdC5hcHBlbmQoUmVuYW1lSmF2YUtleXdvcmRzKG5hbWUpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIENsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgc3RyaW5nIHJlc3VsdCA9IEZpbGVKYXZhUGFja2FnZShwYXJhbXMsIGRlc2NyaXB0b3IpOworICBpZiAoIXJlc3VsdC5lbXB0eSgpKSByZXN1bHQgKz0gJy4nOworICByZXN1bHQgKz0gRmlsZUNsYXNzTmFtZShwYXJhbXMsIGRlc2NyaXB0b3IpOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQgPSBkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKTsKKyAgLy8gV2hlbiB1c2luZyBKYXZhIGVudW0gc3R5bGUsIGFuIGVudW0ncyBjbGFzcyBuYW1lIGNvbnRhaW5zIHRoZSBlbnVtIG5hbWUuCisgIC8vIFVzZSB0aGUgc3RhbmRhcmQgVG9KYXZhTmFtZSB0cmFuc2xhdGlvbi4KKyAgaWYgKHBhcmFtcy5qYXZhX2VudW1fc3R5bGUoKSkgeworICAgIHJldHVybiBUb0phdmFOYW1lKHBhcmFtcywgZGVzY3JpcHRvci0+bmFtZSgpLCB0cnVlLCBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpKTsKKyAgfQorICAvLyBPdGhlcndpc2UgdGhlIGVudW0gbWVtYmVycyBhcmUgYWNjZXNzZWQgZnJvbSB0aGUgZW5jbG9zaW5nIGNsYXNzLgorICBpZiAocGFyZW50ICE9IE5VTEwpIHsKKyAgICByZXR1cm4gQ2xhc3NOYW1lKHBhcmFtcywgcGFyZW50KTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gQ2xhc3NOYW1lKHBhcmFtcywgZGVzY3JpcHRvci0+ZmlsZSgpKTsKKyAgfQorfQorCitzdHJpbmcgRmllbGRDb25zdGFudE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZCkgeworICBzdHJpbmcgbmFtZSA9IGZpZWxkLT5uYW1lKCkgKyAiX0ZJRUxEX05VTUJFUiI7CisgIFVwcGVyU3RyaW5nKCZuYW1lKTsKKyAgcmV0dXJuIG5hbWU7Cit9CisKK3N0cmluZyBGaWVsZERlZmF1bHRDb25zdGFudE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZCkgeworICByZXR1cm4gIl8iICsgUmVuYW1lSmF2YUtleXdvcmRzKFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQpKSArICJEZWZhdWx0IjsKK30KKwordm9pZCBQcmludEZpZWxkQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAvLyBXZSBkb24ndCB3YW50IHRvIHByaW50IGdyb3VwIGJvZGllcyBzbyB3ZSBjdXQgb2ZmIGFmdGVyIHRoZSBmaXJzdCBsaW5lCisgIC8vICh0aGUgc2Vjb25kIGxpbmUgZm9yIGV4dGVuc2lvbnMpLgorICBzdHJpbmcgZGVmID0gZmllbGQtPkRlYnVnU3RyaW5nKCk7CisgIHN0cmluZzo6c2l6ZV90eXBlIGZpcnN0X2xpbmVfZW5kID0gZGVmLmZpbmRfZmlyc3Rfb2YoJ1xuJyk7CisgIHByaW50ZXItPlByaW50KCIvLyAkZGVmJFxuIiwKKyAgICAiZGVmIiwgZGVmLnN1YnN0cigwLCBmaXJzdF9saW5lX2VuZCkpOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgc3RyaW5nOjpzaXplX3R5cGUgc2Vjb25kX2xpbmVfc3RhcnQgPSBmaXJzdF9saW5lX2VuZCArIDE7CisgICAgc3RyaW5nOjpzaXplX3R5cGUgc2Vjb25kX2xpbmVfbGVuZ3RoID0KKyAgICAgICAgZGVmLmZpbmQoJ1xuJywgc2Vjb25kX2xpbmVfc3RhcnQpIC0gc2Vjb25kX2xpbmVfc3RhcnQ7CisgICAgcHJpbnRlci0+UHJpbnQoIi8vICRkZWYkXG4iLAorICAgICAgImRlZiIsIGRlZi5zdWJzdHIoc2Vjb25kX2xpbmVfc3RhcnQsIHNlY29uZF9saW5lX2xlbmd0aCkpOworICB9Cit9CisKK0phdmFUeXBlIEdldEphdmFUeXBlKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSBmaWVsZF90eXBlKSB7CisgIHN3aXRjaCAoZmllbGRfdHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9JTlQ7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6CisgICAgICByZXR1cm4gSkFWQVRZUEVfTE9ORzsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0ZMT0FUOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0RPVUJMRTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0w6CisgICAgICByZXR1cm4gSkFWQVRZUEVfQk9PTEVBTjsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9TVFJJTkc7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9CWVRFUzsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06CisgICAgICByZXR1cm4gSkFWQVRZUEVfRU5VTTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gSkFWQVRZUEVfTUVTU0FHRTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBKQVZBVFlQRV9JTlQ7Cit9CisKK3N0cmluZyBQcmltaXRpdmVUeXBlTmFtZShKYXZhVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuICJpbnQiOworICAgIGNhc2UgSkFWQVRZUEVfTE9ORyAgIDogcmV0dXJuICJsb25nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiAiZmxvYXQiOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuICJkb3VibGUiOworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjogcmV0dXJuICJib29sZWFuIjsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiAiamF2YS5sYW5nLlN0cmluZyI7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUyAgOiByZXR1cm4gImJ5dGVbXSI7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gImludCI7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOiByZXR1cm4gIiI7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIEphdmFUeXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuICIiOworfQorCitzdHJpbmcgQm94ZWRQcmltaXRpdmVUeXBlTmFtZShKYXZhVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuICJqYXZhLmxhbmcuSW50ZWdlciI7CisgICAgY2FzZSBKQVZBVFlQRV9MT05HICAgOiByZXR1cm4gImphdmEubGFuZy5Mb25nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiAiamF2YS5sYW5nLkZsb2F0IjsKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRSA6IHJldHVybiAiamF2YS5sYW5nLkRvdWJsZSI7CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOiByZXR1cm4gImphdmEubGFuZy5Cb29sZWFuIjsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiAiamF2YS5sYW5nLlN0cmluZyI7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUyAgOiByZXR1cm4gImJ5dGVbXSI7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gImphdmEubGFuZy5JbnRlZ2VyIjsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiAiIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gSmF2YVR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBFbXB0eUFycmF5TmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKEdldEphdmFUeXBlKGZpZWxkKSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfSU5UX0FSUkFZIjsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vLkVNUFRZX0xPTkdfQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQgIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfRkxPQVRfQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfRE9VQkxFX0FSUkFZIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vLkVNUFRZX0JPT0xFQU5fQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfU1RSSU5HX0FSUkFZIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTICA6IHJldHVybiAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vLkVNUFRZX0JZVEVTX0FSUkFZIjsKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU0gICA6IHJldHVybiAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vLkVNUFRZX0lOVF9BUlJBWSI7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOiByZXR1cm4gQ2xhc3NOYW1lKHBhcmFtcywgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSArICIuRU1QVFlfQVJSQVkiOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAiIjsKK30KKworc3RyaW5nIERlZmF1bHRWYWx1ZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBpZiAoZmllbGQtPmxhYmVsKCkgPT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCkgeworICAgIHJldHVybiBFbXB0eUFycmF5TmFtZShwYXJhbXMsIGZpZWxkKTsKKyAgfQorCisgIGlmIChwYXJhbXMudXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpKSB7CisgICAgaWYgKHBhcmFtcy5yZWZ0eXBlc19wcmltaXRpdmVfZW51bXMoKQorICAgICAgICAgICYmIGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNKSB7CisgICAgICByZXR1cm4gIkludGVnZXIuTUlOX1ZBTFVFIjsKKyAgICB9CisgICAgcmV0dXJuICJudWxsIjsKKyAgfQorCisgIC8vIFN3aXRjaCBvbiBjcHBfdHlwZSBzaW5jZSB3ZSBuZWVkIHRvIGtub3cgd2hpY2ggZGVmYXVsdF92YWx1ZV8qIG1ldGhvZAorICAvLyBvZiBGaWVsZERlc2NyaXB0b3IgdG8gY2FsbC4KKyAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50MzIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgLy8gTmVlZCB0byBwcmludCBhcyBhIHNpZ25lZCBpbnQgc2luY2UgSmF2YSBoYXMgbm8gdW5zaWduZWQuCisgICAgICByZXR1cm4gU2ltcGxlSXRvYShzdGF0aWNfY2FzdDxpbnQzMj4oZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDMyKCkpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkpICsgIkwiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludDY0PihmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50NjQoKSkpICsKKyAgICAgICAgICAgICAiTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiRG91YmxlLlBPU0lUSVZFX0lORklOSVRZIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgcmV0dXJuICJEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gIkRvdWJsZS5OYU4iOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIFNpbXBsZUR0b2EodmFsdWUpICsgIkQiOworICAgICAgfQorICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDogeworICAgICAgZmxvYXQgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICByZXR1cm4gIkZsb2F0LlBPU0lUSVZFX0lORklOSVRZIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICByZXR1cm4gIkZsb2F0Lk5FR0FUSVZFX0lORklOSVRZIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuICJGbG9hdC5OYU4iOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIFNpbXBsZUZ0b2EodmFsdWUpICsgIkYiOworICAgICAgfQorICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2Jvb2woKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgaWYgKCFmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5lbXB0eSgpKSB7CisgICAgICAgIC8vIFBvaW50IGl0IHRvIHRoZSBzdGF0aWMgZmluYWwgaW4gdGhlIGdlbmVyYXRlZCBjb2RlLgorICAgICAgICByZXR1cm4gRmllbGREZWZhdWx0Q29uc3RhbnROYW1lKGZpZWxkKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUykgeworICAgICAgICAgIHJldHVybiAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vLkVNUFRZX0JZVEVTIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gIlwiXCIiOworICAgICAgICB9CisgICAgICB9CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIENsYXNzTmFtZShwYXJhbXMsIGZpZWxkLT5lbnVtX3R5cGUoKSkgKyAiLiIgKworICAgICAgICAgICAgIFJlbmFtZUphdmFLZXl3b3JkcyhmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm5hbWUoKSk7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuICJudWxsIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAiIjsKK30KKworCitzdGF0aWMgY29uc3QgY2hhcioga0JpdE1hc2tzW10gPSB7CisgICIweDAwMDAwMDAxIiwKKyAgIjB4MDAwMDAwMDIiLAorICAiMHgwMDAwMDAwNCIsCisgICIweDAwMDAwMDA4IiwKKyAgIjB4MDAwMDAwMTAiLAorICAiMHgwMDAwMDAyMCIsCisgICIweDAwMDAwMDQwIiwKKyAgIjB4MDAwMDAwODAiLAorCisgICIweDAwMDAwMTAwIiwKKyAgIjB4MDAwMDAyMDAiLAorICAiMHgwMDAwMDQwMCIsCisgICIweDAwMDAwODAwIiwKKyAgIjB4MDAwMDEwMDAiLAorICAiMHgwMDAwMjAwMCIsCisgICIweDAwMDA0MDAwIiwKKyAgIjB4MDAwMDgwMDAiLAorCisgICIweDAwMDEwMDAwIiwKKyAgIjB4MDAwMjAwMDAiLAorICAiMHgwMDA0MDAwMCIsCisgICIweDAwMDgwMDAwIiwKKyAgIjB4MDAxMDAwMDAiLAorICAiMHgwMDIwMDAwMCIsCisgICIweDAwNDAwMDAwIiwKKyAgIjB4MDA4MDAwMDAiLAorCisgICIweDAxMDAwMDAwIiwKKyAgIjB4MDIwMDAwMDAiLAorICAiMHgwNDAwMDAwMCIsCisgICIweDA4MDAwMDAwIiwKKyAgIjB4MTAwMDAwMDAiLAorICAiMHgyMDAwMDAwMCIsCisgICIweDQwMDAwMDAwIiwKKyAgIjB4ODAwMDAwMDAiLAorfTsKKworc3RyaW5nIEdldEJpdEZpZWxkTmFtZShpbnQgaW5kZXgpIHsKKyAgc3RyaW5nIHZhcl9uYW1lID0gImJpdEZpZWxkIjsKKyAgdmFyX25hbWUgKz0gU2ltcGxlSXRvYShpbmRleCk7CisgIHZhcl9uYW1lICs9ICJfIjsKKyAgcmV0dXJuIHZhcl9uYW1lOworfQorCitzdHJpbmcgR2V0Qml0RmllbGROYW1lRm9yQml0KGludCBiaXRfaW5kZXgpIHsKKyAgcmV0dXJuIEdldEJpdEZpZWxkTmFtZShiaXRfaW5kZXggLyAzMik7Cit9CisKK3N0cmluZyBHZW5lcmF0ZUdldEJpdChpbnQgYml0X2luZGV4KSB7CisgIHN0cmluZyB2YXJfbmFtZSA9IEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRfaW5kZXgpOworICBpbnQgYml0X2luX3Zhcl9pbmRleCA9IGJpdF9pbmRleCAlIDMyOworCisgIHN0cmluZyBtYXNrID0ga0JpdE1hc2tzW2JpdF9pbl92YXJfaW5kZXhdOworICBzdHJpbmcgcmVzdWx0ID0gIigoIiArIHZhcl9uYW1lICsgIiAmICIgKyBtYXNrICsgIikgIT0gMCkiOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgR2VuZXJhdGVTZXRCaXQoaW50IGJpdF9pbmRleCkgeworICBzdHJpbmcgdmFyX25hbWUgPSBHZXRCaXRGaWVsZE5hbWVGb3JCaXQoYml0X2luZGV4KTsKKyAgaW50IGJpdF9pbl92YXJfaW5kZXggPSBiaXRfaW5kZXggJSAzMjsKKworICBzdHJpbmcgbWFzayA9IGtCaXRNYXNrc1tiaXRfaW5fdmFyX2luZGV4XTsKKyAgc3RyaW5nIHJlc3VsdCA9IHZhcl9uYW1lICsgIiB8PSAiICsgbWFzazsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIEdlbmVyYXRlQ2xlYXJCaXQoaW50IGJpdF9pbmRleCkgeworICBzdHJpbmcgdmFyX25hbWUgPSBHZXRCaXRGaWVsZE5hbWVGb3JCaXQoYml0X2luZGV4KTsKKyAgaW50IGJpdF9pbl92YXJfaW5kZXggPSBiaXRfaW5kZXggJSAzMjsKKworICBzdHJpbmcgbWFzayA9IGtCaXRNYXNrc1tiaXRfaW5fdmFyX2luZGV4XTsKKyAgc3RyaW5nIHJlc3VsdCA9IHZhcl9uYW1lICsgIiA9ICgiICsgdmFyX25hbWUgKyAiICYgfiIgKyBtYXNrICsgIikiOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgR2VuZXJhdGVEaWZmZXJlbnRCaXQoaW50IGJpdF9pbmRleCkgeworICBzdHJpbmcgdmFyX25hbWUgPSBHZXRCaXRGaWVsZE5hbWVGb3JCaXQoYml0X2luZGV4KTsKKyAgaW50IGJpdF9pbl92YXJfaW5kZXggPSBiaXRfaW5kZXggJSAzMjsKKworICBzdHJpbmcgbWFzayA9IGtCaXRNYXNrc1tiaXRfaW5fdmFyX2luZGV4XTsKKyAgc3RyaW5nIHJlc3VsdCA9ICIoKCIgKyB2YXJfbmFtZSArICIgJiAiICsgbWFzaworICAgICAgKyAiKSAhPSAob3RoZXIuIiArIHZhcl9uYW1lICsgIiAmICIgKyBtYXNrICsgIikpIjsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBTZXRCaXRPcGVyYXRpb25WYXJpYWJsZXMoY29uc3Qgc3RyaW5nIG5hbWUsCisgICAgaW50IGJpdEluZGV4LCBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgKCp2YXJpYWJsZXMpWyJnZXRfIiArIG5hbWVdID0gR2VuZXJhdGVHZXRCaXQoYml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF8iICsgbmFtZV0gPSBHZW5lcmF0ZVNldEJpdChiaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsiY2xlYXJfIiArIG5hbWVdID0gR2VuZXJhdGVDbGVhckJpdChiaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsiZGlmZmVyZW50XyIgKyBuYW1lXSA9IEdlbmVyYXRlRGlmZmVyZW50Qml0KGJpdEluZGV4KTsKK30KKworYm9vbCBIYXNNYXBGaWVsZChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFICYmCisgICAgICAgIElzTWFwRW50cnkoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTRjODVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmgKQEAgLTAsMCArMSwxOTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19IRUxQRVJTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fSEVMUEVSU19IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCisvLyBDb21tb25seS11c2VkIHNlcGFyYXRvciBjb21tZW50cy4gIFRoaWNrIGlzIGEgbGluZSBvZiAnPScsIHRoaW4gaXMgYSBsaW5lCisvLyBvZiAnLScuCitleHRlcm4gY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXTsKK2V4dGVybiBjb25zdCBjaGFyIGtUaGluU2VwYXJhdG9yW107CisKKy8vIENvbnZlcnRzIHRoZSBmaWVsZCdzIG5hbWUgdG8gY2FtZWwtY2FzZSwgZS5nLiAiZm9vX2Jhcl9iYXoiIGJlY29tZXMKKy8vICJmb29CYXJCYXoiIG9yICJGb29CYXJCYXoiLCByZXNwZWN0aXZlbHkuCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YpOworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZik7CisKKy8vIEFwcGVuZHMgYW4gIl8iIHRvIHRoZSBlbmQgb2YgYSBmaWVsZCB3aGVyZSB0aGUgbmFtZSBpcyBhIHJlc2VydmVkIGphdmEKKy8vIGtleXdvcmQuICBGb3IgZXhhbXBsZSBpbnQzMiBwdWJsaWMgPSAxIHdpbGwgZ2VuZXJhdGUgaW50IHB1YmxpY18uCitzdHJpbmcgUmVuYW1lSmF2YUtleXdvcmRzKGNvbnN0IHN0cmluZyYgaW5wdXQpOworCisvLyBTaW1pbGFyLCBidXQgZm9yIG1ldGhvZCBuYW1lcy4gIChUeXBpY2FsbHksIHRoaXMgbWVyZWx5IGhhcyB0aGUgZWZmZWN0CisvLyBvZiBsb3dlci1jYXNpbmcgdGhlIGZpcnN0IGxldHRlciBvZiB0aGUgbmFtZS4pCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpOworCisvLyBTdHJpcHMgIi5wcm90byIgb3IgIi5wcm90b2RldmVsIiBmcm9tIHRoZSBlbmQgb2YgYSBmaWxlbmFtZS4KK3N0cmluZyBTdHJpcFByb3RvKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisvLyBHZXRzIHRoZSB1bnF1YWxpZmllZCBjbGFzcyBuYW1lIGZvciB0aGUgZmlsZS4gIEVhY2ggLnByb3RvIGZpbGUgYmVjb21lcyBhCisvLyBzaW5nbGUgSmF2YSBjbGFzcywgd2l0aCBhbGwgaXRzIGNvbnRlbnRzIG5lc3RlZCBpbiB0aGF0IGNsYXNzLgorc3RyaW5nIEZpbGVDbGFzc05hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gUmV0dXJucyB0aGUgZmlsZSdzIEphdmEgcGFja2FnZSBuYW1lLgorc3RyaW5nIEZpbGVKYXZhUGFja2FnZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIEphdmEgb3V0ZXIgY2xhc3MgaXMgbmVlZGVkLCBpLmUuIHdoZXRoZXIgdGhlIG9wdGlvbgorLy8gamF2YV9tdWx0aXBsZV9maWxlcyBpcyBmYWxzZSwgb3IgdGhlIHByb3RvIGZpbGUgY29udGFpbnMgYW55IGZpbGUtc2NvcGUKKy8vIGVudW1zL2V4dGVuc2lvbnMuCitib29sIElzT3V0ZXJDbGFzc05lZWRlZChjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisvLyBDb252ZXJ0cyB0aGUgZ2l2ZW4gc2ltcGxlIG5hbWUgb2YgYSBwcm90byBlbnRpdHkgdG8gaXRzIGZ1bGx5LXF1YWxpZmllZCBuYW1lCisvLyBpbiB0aGUgSmF2YSBuYW1lc3BhY2UsIGdpdmVuIHRoYXQgaXQgaXMgaW4gdGhlIGdpdmVuIGZpbGUgZW5jbG9zZWQgaW4gdGhlCisvLyBnaXZlbiBwYXJlbnQgbWVzc2FnZSAob3IgTlVMTCBmb3IgZmlsZS1zY29wZSBlbnRpdGllcykuIFdoZXRoZXIgdGhlIGZpbGUncworLy8gb3V0ZXIgY2xhc3MgbmFtZSBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIHJldHVybiB2YWx1ZSBkZXBlbmRzIG9uIGZhY3RvcnMKKy8vIGluZmVycmFibGUgZnJvbSB0aGUgZ2l2ZW4gYXJndW1lbnRzLCBpbmNsdWRpbmcgaXNfY2xhc3Mgd2hpY2ggaW5kaWNhdGVzCisvLyB3aGV0aGVyIHRoZSBlbnRpdHkgdHJhbnNsYXRlcyB0byBhIEphdmEgY2xhc3MuCitzdHJpbmcgVG9KYXZhTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3Qgc3RyaW5nJiBuYW1lLCBib29sIGlzX2NsYXNzLAorICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisvLyBUaGVzZSByZXR1cm4gdGhlIGZ1bGx5LXF1YWxpZmllZCBjbGFzcyBuYW1lIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuCisvLyBkZXNjcmlwdG9yLgoraW5saW5lIHN0cmluZyBDbGFzc05hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIFRvSmF2YU5hbWUocGFyYW1zLCBkZXNjcmlwdG9yLT5uYW1lKCksIHRydWUsCisgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpLCBkZXNjcmlwdG9yLT5maWxlKCkpOworfQorc3RyaW5nIENsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworaW5saW5lIHN0cmluZyBDbGFzc05hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsCisgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIFRvSmF2YU5hbWUocGFyYW1zLCBkZXNjcmlwdG9yLT5uYW1lKCksIHRydWUsIE5VTEwsIGRlc2NyaXB0b3ItPmZpbGUoKSk7Cit9CitpbmxpbmUgc3RyaW5nIEV4dGVuc2lvbklkZW50aWZpZXJOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gVG9KYXZhTmFtZShwYXJhbXMsIGRlc2NyaXB0b3ItPm5hbWUoKSwgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9zY29wZSgpLCBkZXNjcmlwdG9yLT5maWxlKCkpOworfQorc3RyaW5nIENsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBHZXQgdGhlIHVucXVhbGlmaWVkIG5hbWUgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgYSBmaWVsZCdzIGZpZWxkCisvLyBudW1iZXIgY29uc3RhbnQuCitzdHJpbmcgRmllbGRDb25zdGFudE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZCk7CisKK3N0cmluZyBGaWVsZERlZmF1bHRDb25zdGFudE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZCk7CisKKy8vIFByaW50IHRoZSBmaWVsZCdzIHByb3RvLXN5bnRheCBkZWZpbml0aW9uIGFzIGEgY29tbWVudC4KK3ZvaWQgUHJpbnRGaWVsZENvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCitlbnVtIEphdmFUeXBlIHsKKyAgSkFWQVRZUEVfSU5ULAorICBKQVZBVFlQRV9MT05HLAorICBKQVZBVFlQRV9GTE9BVCwKKyAgSkFWQVRZUEVfRE9VQkxFLAorICBKQVZBVFlQRV9CT09MRUFOLAorICBKQVZBVFlQRV9TVFJJTkcsCisgIEpBVkFUWVBFX0JZVEVTLAorICBKQVZBVFlQRV9FTlVNLAorICBKQVZBVFlQRV9NRVNTQUdFCit9OworCitKYXZhVHlwZSBHZXRKYXZhVHlwZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgZmllbGRfdHlwZSk7CisKK2lubGluZSBKYXZhVHlwZSBHZXRKYXZhVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBHZXRKYXZhVHlwZShmaWVsZC0+dHlwZSgpKTsKK30KKworc3RyaW5nIFByaW1pdGl2ZVR5cGVOYW1lKEphdmFUeXBlIHR5cGUpOworCisvLyBHZXQgdGhlIGZ1bGx5LXF1YWxpZmllZCBjbGFzcyBuYW1lIGZvciBhIGJveGVkIHByaW1pdGl2ZSB0eXBlLCBlLmcuCisvLyAiamF2YS5sYW5nLkludGVnZXIiIGZvciBKQVZBVFlQRV9JTlQuICBSZXR1cm5zIE5VTEwgZm9yIGVudW0gYW5kIG1lc3NhZ2UKKy8vIHR5cGVzLgorc3RyaW5nIEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoSmF2YVR5cGUgdHlwZSk7CisKK3N0cmluZyBFbXB0eUFycmF5TmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKK3N0cmluZyBEZWZhdWx0VmFsdWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisKKy8vIE1ldGhvZHMgZm9yIHNoYXJlZCBiaXRmaWVsZHMuCisKKy8vIEdldHMgdGhlIG5hbWUgb2YgdGhlIHNoYXJlZCBiaXRmaWVsZCBmb3IgdGhlIGdpdmVuIGZpZWxkIGluZGV4Lgorc3RyaW5nIEdldEJpdEZpZWxkTmFtZShpbnQgaW5kZXgpOworCisvLyBHZXRzIHRoZSBuYW1lIG9mIHRoZSBzaGFyZWQgYml0ZmllbGQgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFZmZlY3RpdmVseSwgR2V0Qml0RmllbGROYW1lKGJpdF9pbmRleCAvIDMyKQorc3RyaW5nIEdldEJpdEZpZWxkTmFtZUZvckJpdChpbnQgYml0X2luZGV4KTsKKworLy8gR2VuZXJhdGVzIHRoZSBqYXZhIGNvZGUgZm9yIHRoZSBleHByZXNzaW9uIHRoYXQgcmV0dXJucyB3aGV0aGVyIHRoZSBiaXQgYXQKKy8vIHRoZSBnaXZlbiBiaXQgaW5kZXggaXMgc2V0LgorLy8gRXhhbXBsZTogIigoYml0RmllbGQxXyAmIDB4MDQwMDAwMDApICE9IDApIgorc3RyaW5nIEdlbmVyYXRlR2V0Qml0KGludCBiaXRfaW5kZXgpOworCisvLyBHZW5lcmF0ZXMgdGhlIGphdmEgY29kZSBmb3IgdGhlIGV4cHJlc3Npb24gdGhhdCBzZXRzIHRoZSBiaXQgYXQgdGhlIGdpdmVuCisvLyBiaXQgaW5kZXguCisvLyBFeGFtcGxlOiAiYml0RmllbGQxXyB8PSAweDA0MDAwMDAwIgorc3RyaW5nIEdlbmVyYXRlU2V0Qml0KGludCBiaXRfaW5kZXgpOworCisvLyBHZW5lcmF0ZXMgdGhlIGphdmEgY29kZSBmb3IgdGhlIGV4cHJlc3Npb24gdGhhdCBjbGVhcnMgdGhlIGJpdCBhdCB0aGUgZ2l2ZW4KKy8vIGJpdCBpbmRleC4KKy8vIEV4YW1wbGU6ICJiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwNDAwMDAwMCkiCitzdHJpbmcgR2VuZXJhdGVDbGVhckJpdChpbnQgYml0X2luZGV4KTsKKworLy8gR2VuZXJhdGVzIHRoZSBqYXZhIGNvZGUgZm9yIHRoZSBleHByZXNzaW9uIHRoYXQgcmV0dXJucyB3aGV0aGVyIHRoZSBiaXQgYXQKKy8vIHRoZSBnaXZlbiBiaXQgaW5kZXggY29udGFpbnMgZGlmZmVyZW50IHZhbHVlcyBpbiB0aGUgY3VycmVudCBvYmplY3QgYW5kCisvLyBhbm90aGVyIG9iamVjdCBhY2Nlc3NpYmxlIHZpYSB0aGUgdmFyaWFibGUgJ290aGVyJy4KKy8vIEV4YW1wbGU6ICIoKGJpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAob3RoZXIuYml0RmllbGQxXyAmIDB4MDQwMDAwMDApKSIKK3N0cmluZyBHZW5lcmF0ZURpZmZlcmVudEJpdChpbnQgYml0X2luZGV4KTsKKworLy8gU2V0cyB0aGUgJ2dldF8qJywgJ3NldF8qJywgJ2NsZWFyXyonIGFuZCAnZGlmZmVyZW50XyonIHZhcmlhYmxlcywgd2hlcmUgKiBpcworLy8gdGhlIGdpdmVuIG5hbWUgb2YgdGhlIGJpdCwgdG8gdGhlIGFwcHJvcHJpYXRlIEphdmEgZXhwcmVzc2lvbnMgZm9yIHRoZSBnaXZlbgorLy8gYml0IGluZGV4Lgordm9pZCBTZXRCaXRPcGVyYXRpb25WYXJpYWJsZXMoY29uc3Qgc3RyaW5nIG5hbWUsCisgICAgaW50IGJpdEluZGV4LCBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpOworCitpbmxpbmUgYm9vbCBJc01hcEVudHJ5KGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgLy8gVE9ETyhsaXVqaXNpKTogQWRkIGFuIG9wdGlvbiB0byB0dXJuIG9uIG1hcHMgZm9yIHByb3RvMiBzeW50YXggYXMgd2VsbC4KKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tYXBfZW50cnkoKSAmJgorICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworYm9vbCBIYXNNYXBGaWVsZChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19IRUxQRVJTX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tYXBfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21hcF9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44M2IyYjBjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tYXBfZmllbGQuY2MKQEAgLTAsMCArMSwxODYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworbmFtZXNwYWNlIHsKKworc3RyaW5nIFR5cGVOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgIGJvb2wgYm94ZWQpIHsKKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZmllbGQpOworICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiBDbGFzc05hbWUocGFyYW1zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICAgIGNhc2UgSkFWQVRZUEVfSU5UOgorICAgIGNhc2UgSkFWQVRZUEVfTE9ORzoKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUOgorICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjoKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTOgorICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgIGlmIChib3hlZCkgeworICAgICAgICByZXR1cm4gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShqYXZhX3R5cGUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIFByaW1pdGl2ZVR5cGVOYW1lKGphdmFfdHlwZSk7CisgICAgICB9CisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcgSmF2YVR5cGVzCisgICAgLy8gYXJlIGFkZGVkLi4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJzaG91bGQgbm90IHJlYWNoIGhlcmUuIjsKKyAgcmV0dXJuICIiOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIEtleUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBHT09HTEVfQ0hFQ0tfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIGRlc2NyaXB0b3ItPnR5cGUoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPSBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKTsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2UtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSk7CisgIHJldHVybiBtZXNzYWdlLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIFZhbHVlRmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEdPT0dMRV9DSEVDS19FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpOworICBHT09HTEVfQ0hFQ0sobWVzc2FnZS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKTsKKyAgcmV0dXJuIG1lc3NhZ2UtPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKK30KKwordm9pZCBTZXRNYXBWYXJpYWJsZXMoY29uc3QgUGFyYW1zJiBwYXJhbXMsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPSBLZXlGaWVsZChkZXNjcmlwdG9yKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9IFZhbHVlRmllbGQoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfdHlwZSJdID0gVHlwZU5hbWUocGFyYW1zLCBrZXksIGZhbHNlKTsKKyAgKCp2YXJpYWJsZXMpWyJib3hlZF9rZXlfdHlwZSJdID0gVHlwZU5hbWUocGFyYW1zLGtleSwgdHJ1ZSk7CisgICgqdmFyaWFibGVzKVsia2V5X2Rlc2NfdHlwZSJdID0KKyAgICAgICJUWVBFXyIgKyBUb1VwcGVyKEZpZWxkRGVzY3JpcHRvcjo6VHlwZU5hbWUoa2V5LT50eXBlKCkpKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfdGFnIl0gPSBTaW1wbGVJdG9hKGludGVybmFsOjpXaXJlRm9ybWF0OjpNYWtlVGFnKGtleSkpOworICAoKnZhcmlhYmxlcylbInZhbHVlX3R5cGUiXSA9IFR5cGVOYW1lKHBhcmFtcywgdmFsdWUsIGZhbHNlKTsKKyAgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl0gPSBUeXBlTmFtZShwYXJhbXMsIHZhbHVlLCB0cnVlKTsKKyAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV9kZXNjX3R5cGUiXSA9CisgICAgICAiVFlQRV8iICsgVG9VcHBlcihGaWVsZERlc2NyaXB0b3I6OlR5cGVOYW1lKHZhbHVlLT50eXBlKCkpKTsKKyAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV90YWciXSA9IFNpbXBsZUl0b2EoaW50ZXJuYWw6OldpcmVGb3JtYXQ6Ok1ha2VUYWcodmFsdWUpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlX3BhcmFtZXRlcnMiXSA9CisgICAgICAoKnZhcmlhYmxlcylbImJveGVkX2tleV90eXBlIl0gKyAiLCAiICsgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl07CisgICgqdmFyaWFibGVzKVsidmFsdWVfZGVmYXVsdCJdID0KKyAgICAgIHZhbHVlLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UKKyAgICAgICAgICA/ICJuZXcgIiArICgqdmFyaWFibGVzKVsidmFsdWVfdHlwZSJdICsgIigpIgorICAgICAgICAgIDogIm51bGwiOworfQorfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK01hcEZpZWxkR2VuZXJhdG9yOjpNYXBGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgICAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldE1hcFZhcmlhYmxlcyhwYXJhbXMsIGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworTWFwRmllbGRHZW5lcmF0b3I6On5NYXBGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qIHVudXNlZCBsYXp5X2luaXQgKi8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+ICRuYW1lJDtcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9IG51bGw7XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInRoaXMuJG5hbWUkID0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5tZXJnZU1hcEVudHJ5KFxuIgorICAgICIgIGlucHV0LCB0aGlzLiRuYW1lJCwgbWFwRmFjdG9yeSxcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLiRrZXlfZGVzY190eXBlJCxcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLiR2YWx1ZV9kZXNjX3R5cGUkLFxuIgorICAgICIgICR2YWx1ZV9kZWZhdWx0JCxcbiIKKyAgICAiICAka2V5X3RhZyQsICR2YWx1ZV90YWckKTtcbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRuYW1lJCAhPSBudWxsKSB7XG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5zZXJpYWxpemVNYXBGaWVsZChcbiIKKyAgICAiICAgIG91dHB1dCwgdGhpcy4kbmFtZSQsICRudW1iZXIkLFxuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uJGtleV9kZXNjX3R5cGUkLFxuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uJHZhbHVlX2Rlc2NfdHlwZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5jb21wdXRlTWFwRmllbGRTaXplKFxuIgorICAgICIgICAgdGhpcy4kbmFtZSQsICRudW1iZXIkLFxuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uJGtleV9kZXNjX3R5cGUkLFxuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uJHZhbHVlX2Rlc2NfdHlwZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmVxdWFscyhcbiIKKyAgICAiICB0aGlzLiRuYW1lJCwgb3RoZXIuJG5hbWUkKSkge1xuIgorICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgK1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5oYXNoQ29kZSh0aGlzLiRuYW1lJCk7XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tYXBfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzAxYmRlMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmgKQEAgLTAsMCArMSw3MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTUFQX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTUFQX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitjbGFzcyBNYXBGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNYXBGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+TWFwRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBsYXp5X2luaXQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1hcEZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX01BUF9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDdmNmI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmNjCkBAIC0wLDAgKzEsNjE1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworc3RydWN0IEZpZWxkT3JkZXJpbmdCeU51bWJlciB7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBhLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYikgY29uc3QgeworICAgIHJldHVybiBhLT5udW1iZXIoKSA8IGItPm51bWJlcigpOworICB9Cit9OworCisvLyBTb3J0IHRoZSBmaWVsZHMgb2YgdGhlIGdpdmVuIERlc2NyaXB0b3IgYnkgbnVtYmVyIGludG8gYSBuZXdbXSdkIGFycmF5CisvLyBhbmQgcmV0dXJuIGl0LgorY29uc3QgRmllbGREZXNjcmlwdG9yKiogU29ydEZpZWxkc0J5TnVtYmVyKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiogZmllbGRzID0KKyAgICBuZXcgY29uc3QgRmllbGREZXNjcmlwdG9yKltkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpXTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZHNbaV0gPSBkZXNjcmlwdG9yLT5maWVsZChpKTsKKyAgfQorICBzb3J0KGZpZWxkcywgZmllbGRzICsgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKSwKKyAgICAgICBGaWVsZE9yZGVyaW5nQnlOdW1iZXIoKSk7CisgIHJldHVybiBmaWVsZHM7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VHZW5lcmF0b3I6Ok1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgIDogcGFyYW1zXyhwYXJhbXMpLAorICAgIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLAorICAgIGZpZWxkX2dlbmVyYXRvcnNfKGRlc2NyaXB0b3IsIHBhcmFtcykgeworfQorCitNZXNzYWdlR2VuZXJhdG9yOjp+TWVzc2FnZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gR2VuZXJhdGUgc3RhdGljIG1lbWJlcnMgZm9yIGFsbCBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIFRPRE8oa2VudG9uKTogIFJldXNlIE1lc3NhZ2VHZW5lcmF0b3Igb2JqZWN0cz8KKyAgICBpZiAoSXNNYXBFbnRyeShkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpKSBjb250aW51ZTsKKyAgICBNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgcGFyYW1zXykKKyAgICAgIC5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcyhwcmludGVyKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gR2VuZXJhdGUgc3RhdGljIG1lbWJlciBpbml0aWFsaXplcnMgZm9yIGFsbCBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgLy8gVE9ETyhrZW50b24pOiAgUmV1c2UgTWVzc2FnZUdlbmVyYXRvciBvYmplY3RzPworICAgIGlmIChJc01hcEVudHJ5KGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIE1lc3NhZ2VHZW5lcmF0b3IoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpLCBwYXJhbXNfKQorICAgICAgLkdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoIXBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSAmJgorICAgICAgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKSAhPSAwIHx8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSAhPSAwKSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJFeHRlbnNpb25zIGFyZSBvbmx5IHN1cHBvcnRlZCBpbiBOQU5PX1JVTlRJTUUgaWYgdGhlICIKKyAgICAgICAgIidzdG9yZV91bmtub3duX2ZpZWxkcycgZ2VuZXJhdG9yIG9wdGlvbiBpcyAndHJ1ZSdcbiI7CisgIH0KKworICBjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSA9IGRlc2NyaXB0b3JfLT5maWxlKCktPm5hbWUoKTsKKyAgYm9vbCBpc19vd25fZmlsZSA9CisgICAgcGFyYW1zXy5qYXZhX211bHRpcGxlX2ZpbGVzKGZpbGVfbmFtZSkKKyAgICAgICYmIGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSA9PSBOVUxMOworCisgIGlmIChpc19vd25fZmlsZSkgeworICAgIC8vIE5vdGU6IGNvbnN0YW50cyAoZnJvbSBlbnVtcyBhbmQgZmllbGRzIHJlcXVpcmluZyBzdG9yZWQgZGVmYXVsdHMsIGVtaXR0ZWQgaW4gdGhlIGxvb3AgYmVsb3cpCisgICAgLy8gbWF5IGhhdmUgdGhlIHNhbWUgbmFtZXMgYXMgY29uc3RhbnRzIGluIHRoZSBuZXN0ZWQgY2xhc3Nlcy4gVGhpcyBjYXVzZXMgSmF2YSB3YXJuaW5ncywgYnV0CisgICAgLy8gaXMgbm90IGZhdGFsLCBzbyB3ZSBzdXBwcmVzcyB0aG9zZSB3YXJuaW5ncyBoZXJlIGluIHRoZSB0b3AtbW9zdCBjbGFzcyBkZWNsYXJhdGlvbi4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJAU3VwcHJlc3NXYXJuaW5ncyhcImhpZGluZ1wiKVxuIgorICAgICAgInB1YmxpYyBmaW5hbCBjbGFzcyAkY2xhc3NuYW1lJCBleHRlbmRzXG4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgJGNsYXNzbmFtZSQgZXh0ZW5kc1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgfQorICBpZiAocGFyYW1zXy5zdG9yZV91bmtub3duX2ZpZWxkcygpICYmIHBhcmFtc18ucGFyY2VsYWJsZV9tZXNzYWdlcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5hbmRyb2lkLlBhcmNlbGFibGVFeHRlbmRhYmxlTWVzc2FnZU5hbm88JGNsYXNzbmFtZSQ+IHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSBpZiAocGFyYW1zXy5zdG9yZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5FeHRlbmRhYmxlTWVzc2FnZU5hbm88JGNsYXNzbmFtZSQ+IHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSBpZiAocGFyYW1zXy5wYXJjZWxhYmxlX21lc3NhZ2VzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLmFuZHJvaWQuUGFyY2VsYWJsZU1lc3NhZ2VOYW5vIHtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTWVzc2FnZU5hbm8ge1xuIik7CisgIH0KKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gTmVzdGVkIHR5cGVzIGFuZCBleHRlbnNpb25zCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBFeHRlbnNpb25HZW5lcmF0b3IoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbihpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgRW51bUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+ZW51bV90eXBlKGkpLCBwYXJhbXNfKS5HZW5lcmF0ZShwcmludGVyKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChJc01hcEVudHJ5KGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIE1lc3NhZ2VHZW5lcmF0b3IoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpLCBwYXJhbXNfKS5HZW5lcmF0ZShwcmludGVyKTsKKyAgfQorCisgIC8vIG9uZW9mCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1sibWVzc2FnZV9uYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzYyA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpOworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2Uob25lb2ZfZGVzYyk7CisgICAgdmFyc1sib25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSJdID0KKyAgICAgICAgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKG9uZW9mX2Rlc2MpOworICAgIHZhcnNbIm9uZW9mX2luZGV4Il0gPSBTaW1wbGVJdG9hKG9uZW9mX2Rlc2MtPmluZGV4KCkpOworICAgIC8vIE9uZW9mIENvbnN0YW50cworICAgIGZvciAoaW50IGogPSAwOyBqIDwgb25lb2ZfZGVzYy0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb25lb2ZfZGVzYy0+ZmllbGQoaik7CisgICAgICB2YXJzWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKTsKKyAgICAgIHZhcnNbImNhcF9maWVsZF9uYW1lIl0gPSBUb1VwcGVyKGZpZWxkLT5uYW1lKCkpOworICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRjYXBfZmllbGRfbmFtZSRfRklFTERfTlVNQkVSID0gJG51bWJlciQ7XG4iKTsKKyAgICB9CisgICAgLy8gb25lb2ZDYXNlXyBhbmQgb25lb2ZfCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwcml2YXRlIGludCAkb25lb2ZfbmFtZSRDYXNlXyA9IDA7XG4iCisgICAgICAicHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0ICRvbmVvZl9uYW1lJF87XG4iKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBpbnQgZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzLiRvbmVvZl9uYW1lJENhc2VfO1xuIgorICAgICAgIn1cbiIpOworICAgIC8vIE9uZW9mIGNsZWFyCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgJG1lc3NhZ2VfbmFtZSQgY2xlYXIkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICB0aGlzLiRvbmVvZl9uYW1lJENhc2VfID0gMDtcbiIKKyAgICAgICIgIHRoaXMuJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIC8vIExhenkgaW5pdGlhbGl6YXRpb24gb2Ygb3RoZXJ3aXNlIHN0YXRpYyBmaW5hbCBmaWVsZHMgY2FuIGhlbHAgcHJldmVudCB0aGUKKyAgLy8gY2xhc3MgaW5pdGlhbGl6ZXIgZnJvbSBiZWluZyBnZW5lcmF0ZWQuIFdlIHdhbnQgdG8gcHJldmVudCBpdCBiZWNhdXNlIGl0CisgIC8vIHN0b3BzIFByb0d1YXJkIGZyb20gaW5saW5pbmcgYW55IG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBpbnRvIGNhbGwgc2l0ZXMgYW5kCisgIC8vIHRoZXJlZm9yZSByZWR1Y2luZyB0aGUgbWV0aG9kIGNvdW50LiBIb3dldmVyLCBleHRlbnNpb25zIGFyZSBiZXN0IGtlcHQgYXMKKyAgLy8gcHVibGljIHN0YXRpYyBmaW5hbCBmaWVsZHMgd2l0aCBpbml0aWFsaXplcnMsIHNvIHdpdGggdGhlaXIgZXhpc3RlbmNlIHdlCisgIC8vIHdvbid0IGJvdGhlciB3aXRoIGxhenkgaW5pdGlhbGl6YXRpb24uCisgIGJvb2wgbGF6eV9pbml0ID0gZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpID09IDA7CisKKyAgLy8gRW1wdHkgYXJyYXkKKyAgaWYgKGxhenlfaW5pdCkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgInByaXZhdGUgc3RhdGljIHZvbGF0aWxlICRjbGFzc25hbWUkW10gX2VtcHR5QXJyYXk7XG4iCisgICAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJFtdIGVtcHR5QXJyYXkoKSB7XG4iCisgICAgICAiICAvLyBMYXppbHkgaW5pdGlhbGl6ZXMgdGhlIGVtcHR5IGFycmF5XG4iCisgICAgICAiICBpZiAoX2VtcHR5QXJyYXkgPT0gbnVsbCkge1xuIgorICAgICAgIiAgICBzeW5jaHJvbml6ZWQgKFxuIgorICAgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5MQVpZX0lOSVRfTE9DSykge1xuIgorICAgICAgIiAgICAgIGlmIChfZW1wdHlBcnJheSA9PSBudWxsKSB7XG4iCisgICAgICAiICAgICAgICBfZW1wdHlBcnJheSA9IG5ldyAkY2xhc3NuYW1lJFswXTtcbiIKKyAgICAgICIgICAgICB9XG4iCisgICAgICAiICAgIH1cbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiBfZW1wdHlBcnJheTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgInByaXZhdGUgc3RhdGljIGZpbmFsICRjbGFzc25hbWUkW10gRU1QVFlfQVJSQVkgPSB7fTtcbiIKKyAgICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkW10gZW1wdHlBcnJheSgpIHtcbiIKKyAgICAgICIgIHJldHVybiBFTVBUWV9BUlJBWTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICB9CisKKyAgLy8gSW50ZWdlcnMgZm9yIGJpdCBmaWVsZHMKKyAgaW50IHRvdGFsSW50cyA9IChmaWVsZF9nZW5lcmF0b3JzXy50b3RhbF9iaXRzKCkgKyAzMSkgLyAzMjsKKyAgaWYgKHRvdGFsSW50cyA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsSW50czsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgicHJpdmF0ZSBpbnQgJGJpdF9maWVsZF9uYW1lJDtcbiIsCisgICAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgICAgfQorICB9CisKKyAgLy8gRmllbGRzIGFuZCBtYXliZSB0aGVpciBkZWZhdWx0IHZhbHVlcworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXy0+ZmllbGQoaSkpOworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpLkdlbmVyYXRlTWVtYmVycygKKyAgICAgICAgcHJpbnRlciwgbGF6eV9pbml0KTsKKyAgfQorCisgIC8vIENvbnN0cnVjdG9yLCB3aXRoIGxhenkgaW5pdCBjb2RlIGlmIG5lZWRlZAorICBpZiAobGF6eV9pbml0ICYmIGZpZWxkX2dlbmVyYXRvcnNfLnNhdmVkX2RlZmF1bHRzX25lZWRlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAicHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBfY2xhc3NJbml0aWFsaXplZDtcbiIKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQoKSB7XG4iCisgICAgICAiICAvLyBMYXppbHkgaW5pdGlhbGl6ZXMgdGhlIGZpZWxkIGRlZmF1bHRzXG4iCisgICAgICAiICBpZiAoIV9jbGFzc0luaXRpYWxpemVkKSB7XG4iCisgICAgICAiICAgIHN5bmNocm9uaXplZCAoXG4iCisgICAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLkxBWllfSU5JVF9MT0NLKSB7XG4iCisgICAgICAiICAgICAgaWYgKCFfY2xhc3NJbml0aWFsaXplZCkge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdlbmVyYXRlSW5pdFNhdmVkRGVmYXVsdENvZGUocHJpbnRlcik7CisgICAgfQorICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgICAgICAgIF9jbGFzc0luaXRpYWxpemVkID0gdHJ1ZTtcbiIKKyAgICAgICIgICAgICB9XG4iCisgICAgICAiICAgIH1cbiIKKyAgICAgICIgIH1cbiIpOworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2NsZWFyKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCIgIGNsZWFyKCk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9IGVsc2UgeworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2NsZWFyKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiXG4iCisgICAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQoKSB7XG4iCisgICAgICAgICIgIGNsZWFyKCk7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgICAgfQorICB9CisKKyAgLy8gT3RoZXIgbWV0aG9kcyBpbiB0aGlzIGNsYXNzCisKKyAgR2VuZXJhdGVDbGVhcihwcmludGVyKTsKKworICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9lcXVhbHMoKSkgeworICAgIEdlbmVyYXRlRXF1YWxzKHByaW50ZXIpOworICAgIEdlbmVyYXRlSGFzaENvZGUocHJpbnRlcik7CisgIH0KKworICBHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcyhwcmludGVyKTsKKyAgR2VuZXJhdGVNZXJnZUZyb21NZXRob2RzKHByaW50ZXIpOworICBHZW5lcmF0ZVBhcnNlRnJvbU1ldGhvZHMocHJpbnRlcik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFJlbHkgb24gdGhlIHBhcmVudCBpbXBsZW1lbnRhdGlvbnMgb2Ygd3JpdGVUbygpIGFuZCBnZXRTZXJpYWxpemVkU2l6ZSgpCisgIC8vIGlmIHRoZXJlIGFyZSBubyBmaWVsZHMgdG8gc2VyaWFsaXplIGluIHRoaXMgbWVzc2FnZS4KKyAgaWYgKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpID09IDApIHsKKyAgICByZXR1cm47CisgIH0KKworICBzY29wZWRfYXJyYXk8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gc29ydGVkX2ZpZWxkcygKKyAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIkBPdmVycmlkZVxuIgorICAgICJwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vIG91dHB1dClcbiIKKyAgICAiICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBPdXRwdXQgdGhlIGZpZWxkcyBpbiBzb3J0ZWQgb3JkZXIKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVTZXJpYWxpemVPbmVGaWVsZChwcmludGVyLCBzb3J0ZWRfZmllbGRzW2ldKTsKKyAgfQorCisgIC8vIFRoZSBwYXJlbnQgaW1wbGVtZW50YXRpb24gd2lsbCB3cml0ZSBhbnkgdW5rbm93biBmaWVsZHMgaWYgbmVjZXNzYXJ5LgorICBwcmludGVyLT5QcmludCgKKyAgICAic3VwZXIud3JpdGVUbyhvdXRwdXQpO1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7CisKKyAgLy8gVGhlIHBhcmVudCBpbXBsZW1lbnRhdGlvbiB3aWxsIGdldCB0aGUgc2VyaWFsaXplZCBzaXplIGZvciB1bmtub3duCisgIC8vIGZpZWxkcyBpZiBuZWNlc3NhcnkuCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiQE92ZXJyaWRlXG4iCisgICAgInByb3RlY3RlZCBpbnQgY29tcHV0ZVNlcmlhbGl6ZWRTaXplKCkge1xuIgorICAgICIgIGludCBzaXplID0gc3VwZXIuY29tcHV0ZVNlcmlhbGl6ZWRTaXplKCk7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KHNvcnRlZF9maWVsZHNbaV0pLkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gc2l6ZTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVNZXJnZUZyb21NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBzb3J0ZWRfZmllbGRzKAorICAgIFNvcnRGaWVsZHNCeU51bWJlcihkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiQE92ZXJyaWRlXG4iCisgICAgInB1YmxpYyAkY2xhc3NuYW1lJCBtZXJnZUZyb20oXG4iCisgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkSW5wdXRCeXRlQnVmZmVyTmFubyBpbnB1dClcbiIKKyAgICAiICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworCisgIHByaW50ZXItPkluZGVudCgpOworICBpZiAoSGFzTWFwRmllbGQoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLk1hcEZhY3Rvcmllcy5NYXBGYWN0b3J5IG1hcEZhY3RvcnkgPVxuIgorICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLk1hcEZhY3Rvcmllcy5nZXRNYXBGYWN0b3J5KCk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJ3aGlsZSAodHJ1ZSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpO1xuIgorICAgICJzd2l0Y2ggKHRhZykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJjYXNlIDA6XG4iICAgICAgICAgIC8vIHplcm8gc2lnbmFscyBFT0YgLyBsaW1pdCByZWFjaGVkCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgImRlZmF1bHQ6IHtcbiIpOworCisgIHByaW50ZXItPkluZGVudCgpOworICBpZiAocGFyYW1zXy5zdG9yZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoIXN0b3JlVW5rbm93bkZpZWxkKGlucHV0LCB0YWcpKSB7XG4iCisgICAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoIWNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFuby5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgdGFnKSkge1xuIgorICAgICAgICAiICByZXR1cm4gdGhpcztcbiIgICAvLyBpdCdzIGFuIGVuZGdyb3VwIHRhZworICAgICAgICAifVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoImJyZWFrO1xuIik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBzb3J0ZWRfZmllbGRzW2ldOworICAgIHVpbnQzMiB0YWcgPSBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICBXaXJlRm9ybWF0OjpXaXJlVHlwZUZvckZpZWxkVHlwZShmaWVsZC0+dHlwZSgpKSk7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjYXNlICR0YWckOiB7XG4iLAorICAgICAgInRhZyIsIFNpbXBsZUl0b2EodGFnKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlTWVyZ2luZ0NvZGUocHJpbnRlcik7CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBicmVhaztcbiIKKyAgICAgICJ9XG4iKTsKKworICAgIGlmIChmaWVsZC0+aXNfcGFja2FibGUoKSkgeworICAgICAgLy8gVG8gbWFrZSBwYWNrZWQgPSB0cnVlIHdpcmUgY29tcGF0aWJsZSwgd2UgZ2VuZXJhdGUgcGFyc2luZyBjb2RlIGZyb20gYQorICAgICAgLy8gcGFja2VkIHZlcnNpb24gb2YgdGhpcyBmaWVsZCByZWdhcmRsZXNzIG9mIGZpZWxkLT5vcHRpb25zKCkucGFja2VkKCkuCisgICAgICB1aW50MzIgcGFja2VkX3RhZyA9IFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjYXNlICR0YWckOiB7XG4iLAorICAgICAgICAidGFnIiwgU2ltcGxlSXRvYShwYWNrZWRfdGFnKSk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZU1lcmdpbmdDb2RlRnJvbVBhY2tlZChwcmludGVyKTsKKworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIGJyZWFrO1xuIgorICAgICAgICAifVxuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgICB9XG4iICAgICAvLyBzd2l0Y2ggKHRhZykKKyAgICAiICB9XG4iICAgICAgIC8vIHdoaWxlICh0cnVlKQorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBOb3RlOiAgVGhlc2UgYXJlIHNlcGFyYXRlIGZyb20gR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoKQorICAvLyAgIGJlY2F1c2UgdGhleSBuZWVkIHRvIGJlIGdlbmVyYXRlZCBldmVuIGZvciBtZXNzYWdlcyB0aGF0IGFyZSBvcHRpbWl6ZWQKKyAgLy8gICBmb3IgY29kZSBzaXplLgorICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKVxuIgorICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnZhbGlkUHJvdG9jb2xCdWZmZXJOYW5vRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLk1lc3NhZ2VOYW5vLm1lcmdlRnJvbShuZXcgJGNsYXNzbmFtZSQoKSwgZGF0YSk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8gaW5wdXQpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyAkY2xhc3NuYW1lJCgpLm1lcmdlRnJvbShpbnB1dCk7XG4iCisgICAgIn1cbiIsCisgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKHByaW50ZXIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlQ2xlYXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKCFwYXJhbXNfLmdlbmVyYXRlX2NsZWFyKCkpIHsKKyAgICByZXR1cm47CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgY2xlYXIoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gQ2xlYXIgYml0IGZpZWxkcy4KKyAgaW50IHRvdGFsSW50cyA9IChmaWVsZF9nZW5lcmF0b3JzXy50b3RhbF9iaXRzKCkgKyAzMSkgLyAzMjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbEludHM7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KCIkYml0X2ZpZWxkX25hbWUkID0gMDtcbiIsCisgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICB9CisKKyAgLy8gQ2FsbCBjbGVhciBmb3IgYWxsIG9mIHRoZSBmaWVsZHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUNsZWFyQ29kZShwcmludGVyKTsKKyAgfQorCisgIC8vIENsZWFyIG9uZW9mcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjbGVhciRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJCgpO1xuIiwKKyAgICAgICJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIiwgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKAorICAgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKSk7CisgIH0KKworICAvLyBDbGVhciB1bmtub3duIGZpZWxkcy4KKyAgaWYgKHBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHByaW50ZXItPlByaW50KCJ1bmtub3duRmllbGREYXRhID0gbnVsbDtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICBjYWNoZWRTaXplID0gLTE7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlRXF1YWxzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIERvbid0IG92ZXJyaWRlIGlmIHRoZXJlIGFyZSBubyBmaWVsZHMuIFdlIGNvdWxkIGdlbmVyYXRlIGFuCisgIC8vIGVxdWFscyBtZXRob2QgdGhhdCBjb21wYXJlcyB0eXBlcywgYnV0IG9mdGVuIGVtcHR5IG1lc3NhZ2VzCisgIC8vIGFyZSB1c2VkIGFzIG5hbWVzcGFjZXMuCisgIGlmIChkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSA9PSAwICYmICFwYXJhbXNfLnN0b3JlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICByZXR1cm47CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIkBPdmVycmlkZVxuIgorICAgICJwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImlmIChvID09IHRoaXMpIHtcbiIKKyAgICAiICByZXR1cm4gdHJ1ZTtcbiIKKyAgICAifVxuIgorICAgICJpZiAoIShvIGluc3RhbmNlb2YgJGNsYXNzbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iCisgICAgIiRjbGFzc25hbWUkIG90aGVyID0gKCRjbGFzc25hbWUkKSBvO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgLy8gQ2hlY2tpbmcgb25lb2YgY2FzZSBiZWZvcmUgY2hlY2tpbmcgZWFjaCBvbmVvZiBmaWVsZC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2MgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJpZiAodGhpcy4kb25lb2ZfbmFtZSRDYXNlXyAhPSBvdGhlci4kb25lb2ZfbmFtZSRDYXNlXykge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIn1cbiIsCisgICAgICAib25lb2ZfbmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2Uob25lb2ZfZGVzYykpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlRXF1YWxzQ29kZShwcmludGVyKTsKKyAgfQorCisgIGlmIChwYXJhbXNfLnN0b3JlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJyZXR1cm4gdW5rbm93bkZpZWxkRGF0YUVxdWFscyhvdGhlcik7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJyZXR1cm4gdHJ1ZTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgPT0gMCAmJiAhcGFyYW1zXy5zdG9yZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJAT3ZlcnJpZGVcbiIKKyAgICAicHVibGljIGludCBoYXNoQ29kZSgpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgiaW50IHJlc3VsdCA9IDE3O1xuIik7CisgIHByaW50ZXItPlByaW50KCJyZXN1bHQgPSAzMSAqIHJlc3VsdCArIGdldENsYXNzKCkuZ2V0TmFtZSgpLmhhc2hDb2RlKCk7XG4iKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlSGFzaENvZGVDb2RlKHByaW50ZXIpOworICB9CisKKyAgaWYgKHBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICsgdW5rbm93bkZpZWxkRGF0YUhhc2hDb2RlKCk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KCJyZXR1cm4gcmVzdWx0O1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZjI1YTNhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmgKQEAgLTAsMCArMSw5NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NRVNTQUdFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgTWVzc2FnZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfk1lc3NhZ2VHZW5lcmF0b3IoKTsKKworICAvLyBBbGwgc3RhdGljIHZhcmlhYmxlcyBoYXZlIHRvIGJlIGRlY2xhcmVkIGF0IHRoZSB0b3AtbGV2ZWwgb2YgdGhlIGZpbGUKKyAgLy8gc28gdGhhdCB3ZSBjYW4gY29udHJvbCBpbml0aWFsaXphdGlvbiBvcmRlciwgd2hpY2ggaXMgaW1wb3J0YW50IGZvcgorICAvLyBEZXNjcmlwdG9yUHJvdG8gYm9vdHN0cmFwcGluZyB0byB3b3JrLgorICB2b2lkIEdlbmVyYXRlU3RhdGljVmFyaWFibGVzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBPdXRwdXQgY29kZSB3aGljaCBpbml0aWFsaXplcyB0aGUgc3RhdGljIHZhcmlhYmxlcyBnZW5lcmF0ZWQgYnkKKyAgLy8gR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoKS4KKyAgdm9pZCBHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgY2xhc3MgaXRzZWxmLgorICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgRmllbGRHZW5lcmF0b3JNYXAgZmllbGRfZ2VuZXJhdG9yc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4MWM0MDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuY2MKQEAgLTAsMCArMSwzMzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworLy8gVE9ETyhrZW50b24pOiAgRmFjdG9yIG91dCBhICJTZXRDb21tb25GaWVsZFZhcmlhYmxlcygpIiB0byBnZXQgcmlkIG9mCisvLyAgIHJlcGVhdCBjb2RlIGJldHdlZW4gdGhpcyBhbmQgdGhlIG90aGVyIGZpZWxkIHR5cGVzLgordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IENsYXNzTmFtZShwYXJhbXMsIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJncm91cF9vcl9tZXNzYWdlIl0gPQorICAgIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSA/CisgICAgIkdyb3VwIiA6ICJNZXNzYWdlIjsKKyAgKCp2YXJpYWJsZXMpWyJtZXNzYWdlX25hbWUiXSA9IGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpLT5uYW1lKCk7CisgIC8vKCp2YXJpYWJsZXMpWyJtZXNzYWdlX3R5cGUiXSA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCk7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKHBhcmFtcywgZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitNZXNzYWdlRmllbGRHZW5lcmF0b3I6On5NZXNzYWdlRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyogdW51c2VkIGxhenlfaW5pdCAqLykgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgJHR5cGUkICRuYW1lJDtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSQgPSBudWxsO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkID09IG51bGwpIHtcbiIKKyAgICAiICB0aGlzLiRuYW1lJCA9IG5ldyAkdHlwZSQoKTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnB1dC5yZWFkR3JvdXAodGhpcy4kbmFtZSQsICRudW1iZXIkKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW5wdXQucmVhZE1lc3NhZ2UodGhpcy4kbmFtZSQpO1xuIik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgPT0gbnVsbCkgeyBcbiIKKyAgICAiICBpZiAob3RoZXIuJG5hbWUkICE9IG51bGwpIHtcbiIKKyAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAiICB9XG4iCisgICAgIn0gZWxzZSB7XG4iCisgICAgIiAgaWYgKCF0aGlzLiRuYW1lJC5lcXVhbHMob3RoZXIuJG5hbWUkKSkge1xuIgorICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICtcbiIKKyAgICAiICAgICh0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkLmhhc2hDb2RlKCkpO1xuIik7Cit9CisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjpNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICAgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICAgIFNldE1lc3NhZ2VWYXJpYWJsZXMocGFyYW1zLCBkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7CisgICAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6fk1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyogdW51c2VkIGxhenlfaW5pdCAqLykgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZSQ7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJHR5cGUkKSB0aGlzLiRvbmVvZl9uYW1lJF87XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiBudWxsO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyAkbWVzc2FnZV9uYW1lJCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9XG4iCisgICAgIiAgJHNldF9vbmVvZl9jYXNlJDtcbiIKKyAgICAiICB0aGlzLiRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm8gY2xlYXIgbWV0aG9kIGZvciBvbmVvZiBmaWVsZHMuCit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoISgkaGFzX29uZW9mX2Nhc2UkKSkge1xuIgorICAgICIgIHRoaXMuJG9uZW9mX25hbWUkXyA9IG5ldyAkdHlwZSQoKTtcbiIKKyAgICAifVxuIgorICAgICJpbnB1dC5yZWFkTWVzc2FnZShcbiIKKyAgICAiICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTWVzc2FnZU5hbm8pIHRoaXMuJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIiRzZXRfb25lb2ZfY2FzZSQ7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlTWVzc2FnZSgkbnVtYmVyJCxcbiIKKyAgICAiICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NZXNzYWdlTmFubykgdGhpcy4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgIiAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKCRudW1iZXIkLFxuIgorICAgICIgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uTWVzc2FnZU5hbm8pIHRoaXMuJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBHZW5lcmF0ZU9uZW9mRmllbGRFcXVhbHMoZGVzY3JpcHRvcl8sIHZhcmlhYmxlc18sIHByaW50ZXIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIEdlbmVyYXRlT25lb2ZGaWVsZEhhc2hDb2RlKGRlc2NyaXB0b3JfLCB2YXJpYWJsZXNfLCBwcmludGVyKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0TWVzc2FnZVZhcmlhYmxlcyhwYXJhbXMsIGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qIHVudXNlZCBsYXp5X2luaXQgKi8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljICR0eXBlJFtdICRuYW1lJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICR0eXBlJC5lbXB0eUFycmF5KCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIEZpcnN0LCBmaWd1cmUgb3V0IHRoZSBsZW5ndGggb2YgdGhlIGFycmF5LCB0aGVuIHBhcnNlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgYXJyYXlMZW5ndGggPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm9cbiIKKyAgICAiICAgIC5nZXRSZXBlYXRlZEZpZWxkQXJyYXlMZW5ndGgoaW5wdXQsICR0YWckKTtcbiIKKyAgICAiaW50IGkgPSB0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkLmxlbmd0aDtcbiIKKyAgICAiJHR5cGUkW10gbmV3QXJyYXkgPVxuIgorICAgICIgICAgbmV3ICR0eXBlJFtpICsgYXJyYXlMZW5ndGhdO1xuIgorICAgICJpZiAoaSAhPSAwKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkodGhpcy4kbmFtZSQsIDAsIG5ld0FycmF5LCAwLCBpKTtcbiIKKyAgICAifVxuIgorICAgICJmb3IgKDsgaSA8IG5ld0FycmF5Lmxlbmd0aCAtIDE7IGkrKykge1xuIgorICAgICIgIG5ld0FycmF5W2ldID0gbmV3ICR0eXBlJCgpO1xuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGlucHV0LnJlYWRHcm91cChuZXdBcnJheVtpXSwgJG51bWJlciQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGlucHV0LnJlYWRNZXNzYWdlKG5ld0FycmF5W2ldKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICBpbnB1dC5yZWFkVGFnKCk7XG4iCisgICAgIn1cbiIKKyAgICAiLy8gTGFzdCBvbmUgd2l0aG91dCByZWFkVGFnLlxuIgorICAgICJuZXdBcnJheVtpXSA9IG5ldyAkdHlwZSQoKTtcbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW5wdXQucmVhZEdyb3VwKG5ld0FycmF5W2ldLCAkbnVtYmVyJCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlucHV0LnJlYWRNZXNzYWdlKG5ld0FycmF5W2ldKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGhpcy4kbmFtZSQgPSBuZXdBcnJheTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwgJiYgdGhpcy4kbmFtZSQubGVuZ3RoID4gMCkge1xuIgorICAgICIgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy4kbmFtZSQubGVuZ3RoOyBpKyspIHtcbiIKKyAgICAiICAgICR0eXBlJCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgIiAgICBpZiAoZWxlbWVudCAhPSBudWxsKSB7XG4iCisgICAgIiAgICAgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgZWxlbWVudCk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iCisgICAgIiAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICIgICAgJHR5cGUkIGVsZW1lbnQgPSB0aGlzLiRuYW1lJFtpXTtcbiIKKyAgICAiICAgIGlmIChlbGVtZW50ICE9IG51bGwpIHtcbiIKKyAgICAiICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICIgICAgICAgIC5jb21wdXRlJGdyb3VwX29yX21lc3NhZ2UkU2l6ZSgkbnVtYmVyJCwgZWxlbWVudCk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmVxdWFscyhcbiIKKyAgICAiICAgIHRoaXMuJG5hbWUkLCBvdGhlci4kbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdFxuIgorICAgICIgICAgKyBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmhhc2hDb2RlKHRoaXMuJG5hbWUkKTtcbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjNjE1ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDExOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX01FU1NBR0VfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2NsYXNzIE1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfk1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBsYXp5X2luaXQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBsYXp5X2luaXQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTUVTU0FHRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2OTFmMzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oCkBAIC0wLDAgKzEsMjQwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IHdpbmtAZ29vZ2xlLmNvbSAoV2luayBTYXZpbGxlKQorCisjaWZuZGVmIFBST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0pBVkFOQU5PX1BBUkFNU19IXworI2RlZmluZSBQUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19KQVZBTkFOT19QQVJBTVNfSF8KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzZXQ+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2VudW0gZU11bHRpcGxlRmlsZXMgeyBKQVZBTkFOT19NVUxfVU5TRVQsIEpBVkFOQU5PX01VTF9GQUxTRSwgSkFWQU5BTk9fTVVMX1RSVUUgfTsKKworLy8gUGFyYW1ldGVycyBmb3IgdXNlZCBieSB0aGUgZ2VuZXJhdG9ycworY2xhc3MgUGFyYW1zIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgbWFwPHN0cmluZywgc3RyaW5nPiBOYW1lTWFwOworICB0eXBlZGVmIHNldDxzdHJpbmc+IE5hbWVTZXQ7CisgcHJpdmF0ZToKKyAgc3RyaW5nIGVtcHR5XzsKKyAgc3RyaW5nIGJhc2VfbmFtZV87CisgIGVNdWx0aXBsZUZpbGVzIG92ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXNfOworICBib29sIHN0b3JlX3Vua25vd25fZmllbGRzXzsKKyAgTmFtZU1hcCBqYXZhX3BhY2thZ2VzXzsKKyAgTmFtZU1hcCBqYXZhX291dGVyX2NsYXNzbmFtZXNfOworICBOYW1lU2V0IGphdmFfbXVsdGlwbGVfZmlsZXNfOworICBib29sIGdlbmVyYXRlX2hhc187CisgIGJvb2wgamF2YV9lbnVtX3N0eWxlXzsKKyAgYm9vbCBvcHRpb25hbF9maWVsZF9hY2Nlc3NvcnNfOworICBib29sIHVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXNfOworICBib29sIGdlbmVyYXRlX2VxdWFsc187CisgIGJvb2wgaWdub3JlX3NlcnZpY2VzXzsKKyAgYm9vbCBwYXJjZWxhYmxlX21lc3NhZ2VzXzsKKyAgYm9vbCByZWZ0eXBlc19wcmltaXRpdmVfZW51bXNfOworICBib29sIGdlbmVyYXRlX2NsZWFyXzsKKworIHB1YmxpYzoKKyAgUGFyYW1zKGNvbnN0IHN0cmluZyAmIGJhc2VfbmFtZSkgOgorICAgIGVtcHR5XygiIiksCisgICAgYmFzZV9uYW1lXyhiYXNlX25hbWUpLAorICAgIG92ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXNfKEpBVkFOQU5PX01VTF9VTlNFVCksCisgICAgc3RvcmVfdW5rbm93bl9maWVsZHNfKGZhbHNlKSwKKyAgICBnZW5lcmF0ZV9oYXNfKGZhbHNlKSwKKyAgICBqYXZhX2VudW1fc3R5bGVfKGZhbHNlKSwKKyAgICBvcHRpb25hbF9maWVsZF9hY2Nlc3NvcnNfKGZhbHNlKSwKKyAgICB1c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzXyhmYWxzZSksCisgICAgZ2VuZXJhdGVfZXF1YWxzXyhmYWxzZSksCisgICAgaWdub3JlX3NlcnZpY2VzXyhmYWxzZSksCisgICAgcGFyY2VsYWJsZV9tZXNzYWdlc18oZmFsc2UpLAorICAgIHJlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtc18oZmFsc2UpLAorICAgIGdlbmVyYXRlX2NsZWFyXyh0cnVlKSB7CisgIH0KKworICBjb25zdCBzdHJpbmcmIGJhc2VfbmFtZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYmFzZV9uYW1lXzsKKyAgfQorCisgIGJvb2wgaGFzX2phdmFfcGFja2FnZShjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSkgY29uc3QgeworICAgIHJldHVybiBqYXZhX3BhY2thZ2VzXy5maW5kKGZpbGVfbmFtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICE9IGphdmFfcGFja2FnZXNfLmVuZCgpOworICB9CisgIHZvaWQgc2V0X2phdmFfcGFja2FnZShjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSwKKyAgICAgIGNvbnN0IHN0cmluZyYgamF2YV9wYWNrYWdlKSB7CisgICAgamF2YV9wYWNrYWdlc19bZmlsZV9uYW1lXSA9IGphdmFfcGFja2FnZTsKKyAgfQorICBjb25zdCBzdHJpbmcmIGphdmFfcGFja2FnZShjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSkgY29uc3QgeworICAgIE5hbWVNYXA6OmNvbnN0X2l0ZXJhdG9yIGl0cjsKKworICAgIGl0ciA9IGphdmFfcGFja2FnZXNfLmZpbmQoZmlsZV9uYW1lKTsKKyAgICBpZiAgKGl0ciA9PSBqYXZhX3BhY2thZ2VzXy5lbmQoKSkgeworICAgICAgcmV0dXJuIGVtcHR5XzsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGl0ci0+c2Vjb25kOworICAgIH0KKyAgfQorICBjb25zdCBOYW1lTWFwJiBqYXZhX3BhY2thZ2VzKCkgeworICAgIHJldHVybiBqYXZhX3BhY2thZ2VzXzsKKyAgfQorCisgIGJvb2wgaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKSBjb25zdCB7CisgICAgcmV0dXJuIGphdmFfb3V0ZXJfY2xhc3NuYW1lc18uZmluZChmaWxlX25hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAhPSBqYXZhX291dGVyX2NsYXNzbmFtZXNfLmVuZCgpOworICB9CisgIHZvaWQgc2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lLAorICAgICAgY29uc3Qgc3RyaW5nJiBqYXZhX291dGVyX2NsYXNzbmFtZSkgeworICAgIGphdmFfb3V0ZXJfY2xhc3NuYW1lc19bZmlsZV9uYW1lXSA9IGphdmFfb3V0ZXJfY2xhc3NuYW1lOworICB9CisgIGNvbnN0IHN0cmluZyYgamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpIGNvbnN0IHsKKyAgICBOYW1lTWFwOjpjb25zdF9pdGVyYXRvciBpdHI7CisKKyAgICBpdHIgPSBqYXZhX291dGVyX2NsYXNzbmFtZXNfLmZpbmQoZmlsZV9uYW1lKTsKKyAgICBpZiAgKGl0ciA9PSBqYXZhX291dGVyX2NsYXNzbmFtZXNfLmVuZCgpKSB7CisgICAgICByZXR1cm4gZW1wdHlfOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gaXRyLT5zZWNvbmQ7CisgICAgfQorICB9CisgIGNvbnN0IE5hbWVNYXAmIGphdmFfb3V0ZXJfY2xhc3NuYW1lcygpIHsKKyAgICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVzXzsKKyAgfQorCisgIHZvaWQgc2V0X292ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXMoYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzKSB7CisgICAgaWYgKGphdmFfbXVsdGlwbGVfZmlsZXMpIHsKKyAgICAgIG92ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXNfID0gSkFWQU5BTk9fTVVMX1RSVUU7CisgICAgfSBlbHNlIHsKKyAgICAgIG92ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXNfID0gSkFWQU5BTk9fTVVMX0ZBTFNFOworICAgIH0KKyAgfQorICB2b2lkIGNsZWFyX292ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXMoKSB7CisgICAgb3ZlcnJpZGVfamF2YV9tdWx0aXBsZV9maWxlc18gPSBKQVZBTkFOT19NVUxfVU5TRVQ7CisgIH0KKworICB2b2lkIHNldF9qYXZhX211bHRpcGxlX2ZpbGVzKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lLCBib29sIHZhbHVlKSB7CisgICAgaWYgKHZhbHVlKSB7CisgICAgICBqYXZhX211bHRpcGxlX2ZpbGVzXy5pbnNlcnQoZmlsZV9uYW1lKTsKKyAgICB9IGVsc2UgeworICAgICAgamF2YV9tdWx0aXBsZV9maWxlc18uZXJhc2UoZmlsZV9uYW1lKTsKKyAgICB9CisgIH0KKyAgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKSBjb25zdCB7CisgICAgc3dpdGNoIChvdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzXykgeworICAgICAgY2FzZSBKQVZBTkFOT19NVUxfRkFMU0U6CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGNhc2UgSkFWQU5BTk9fTVVMX1RSVUU6CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIGphdmFfbXVsdGlwbGVfZmlsZXNfLmZpbmQoZmlsZV9uYW1lKQorICAgICAgICAgICAgICAgICE9IGphdmFfbXVsdGlwbGVfZmlsZXNfLmVuZCgpOworICAgIH0KKyAgfQorCisgIHZvaWQgc2V0X3N0b3JlX3Vua25vd25fZmllbGRzKGJvb2wgdmFsdWUpIHsKKyAgICBzdG9yZV91bmtub3duX2ZpZWxkc18gPSB2YWx1ZTsKKyAgfQorICBib29sIHN0b3JlX3Vua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBzdG9yZV91bmtub3duX2ZpZWxkc187CisgIH0KKworICB2b2lkIHNldF9nZW5lcmF0ZV9oYXMoYm9vbCB2YWx1ZSkgeworICAgIGdlbmVyYXRlX2hhc18gPSB2YWx1ZTsKKyAgfQorICBib29sIGdlbmVyYXRlX2hhcygpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2VuZXJhdGVfaGFzXzsKKyAgfQorCisgIHZvaWQgc2V0X2phdmFfZW51bV9zdHlsZShib29sIHZhbHVlKSB7CisgICAgamF2YV9lbnVtX3N0eWxlXyA9IHZhbHVlOworICB9CisgIGJvb2wgamF2YV9lbnVtX3N0eWxlKCkgY29uc3QgeworICAgIHJldHVybiBqYXZhX2VudW1fc3R5bGVfOworICB9CisKKyAgdm9pZCBzZXRfb3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzKGJvb2wgdmFsdWUpIHsKKyAgICBvcHRpb25hbF9maWVsZF9hY2Nlc3NvcnNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCBvcHRpb25hbF9maWVsZF9hY2Nlc3NvcnMoKSBjb25zdCB7CisgICAgcmV0dXJuIG9wdGlvbmFsX2ZpZWxkX2FjY2Vzc29yc187CisgIH0KKworICB2b2lkIHNldF91c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKGJvb2wgdmFsdWUpIHsKKyAgICB1c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzXyA9IHZhbHVlOworICB9CisgIGJvb2wgdXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpIGNvbnN0IHsKKyAgICByZXR1cm4gdXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlc187CisgIH0KKworICB2b2lkIHNldF9nZW5lcmF0ZV9lcXVhbHMoYm9vbCB2YWx1ZSkgeworICAgIGdlbmVyYXRlX2VxdWFsc18gPSB2YWx1ZTsKKyAgfQorICBib29sIGdlbmVyYXRlX2VxdWFscygpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2VuZXJhdGVfZXF1YWxzXzsKKyAgfQorCisgIHZvaWQgc2V0X2lnbm9yZV9zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgICAgaWdub3JlX3NlcnZpY2VzXyA9IHZhbHVlOworICB9CisgIGJvb2wgaWdub3JlX3NlcnZpY2VzKCkgY29uc3QgeworICAgIHJldHVybiBpZ25vcmVfc2VydmljZXNfOworICB9CisKKyAgdm9pZCBzZXRfcGFyY2VsYWJsZV9tZXNzYWdlcyhib29sIHZhbHVlKSB7CisgICAgcGFyY2VsYWJsZV9tZXNzYWdlc18gPSB2YWx1ZTsKKyAgfQorICBib29sIHBhcmNlbGFibGVfbWVzc2FnZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIHBhcmNlbGFibGVfbWVzc2FnZXNfOworICB9CisKKyAgdm9pZCBzZXRfcmVmdHlwZXNfcHJpbWl0aXZlX2VudW1zKGJvb2wgdmFsdWUpIHsKKyAgICByZWZ0eXBlc19wcmltaXRpdmVfZW51bXNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCByZWZ0eXBlc19wcmltaXRpdmVfZW51bXMoKSBjb25zdCB7CisgICAgcmV0dXJuIHJlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtc187CisgIH0KKworICB2b2lkIHNldF9nZW5lcmF0ZV9jbGVhcihib29sIHZhbHVlKSB7CisgICAgZ2VuZXJhdGVfY2xlYXJfID0gdmFsdWU7CisgIH0KKyAgYm9vbCBnZW5lcmF0ZV9jbGVhcigpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2VuZXJhdGVfY2xlYXJfOworICB9Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIFBST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0pBVkFOQU5PX1BBUkFNU19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MWJhZDBhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wcmltaXRpdmVfZmllbGQuY2MKQEAgLTAsMCArMSw5NjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworYm9vbCBJc1JlZmVyZW5jZVR5cGUoSmF2YVR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEpBVkFUWVBFX0lOVCAgICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRSA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiB0cnVlOworICAgIGNhc2UgSkFWQVRZUEVfQllURVMgIDogcmV0dXJuIHRydWU7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOiByZXR1cm4gdHJ1ZTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gSmF2YVR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgSXNBcnJheVR5cGUoSmF2YVR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEpBVkFUWVBFX0lOVCAgICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRSA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTICA6IHJldHVybiB0cnVlOworICAgIGNhc2UgSkFWQVRZUEVfRU5VTSAgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRTogcmV0dXJuIGZhbHNlOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBmYWxzZTsKK30KKworY29uc3QgY2hhciogR2V0Q2FwaXRhbGl6ZWRUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3dpdGNoIChmaWVsZC0+dHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAiSW50MzIiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gIlVJbnQzMiIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzIgIDogcmV0dXJuICJTSW50MzIiICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMiA6IHJldHVybiAiRml4ZWQzMiIgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gIlNGaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NCAgIDogcmV0dXJuICJJbnQ2NCIgICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0ICA6IHJldHVybiAiVUludDY0IiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NCAgOiByZXR1cm4gIlNJbnQ2NCIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0IDogcmV0dXJuICJGaXhlZDY0IiA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6IHJldHVybiAiU0ZpeGVkNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUICAgOiByZXR1cm4gIkZsb2F0IiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEUgIDogcmV0dXJuICJEb3VibGUiICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTCAgICA6IHJldHVybiAiQm9vbCIgICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAgOiByZXR1cm4gIlN0cmluZyIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuICJCeXRlcyIgICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICA6IHJldHVybiAiRW51bSIgICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gIkdyb3VwIiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuICJNZXNzYWdlIiA7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIHR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworLy8gRm9yIGVuY29kaW5ncyB3aXRoIGZpeGVkIHNpemVzLCByZXR1cm5zIHRoYXQgc2l6ZSBpbiBieXRlcy4gIE90aGVyd2lzZQorLy8gcmV0dXJucyAtMS4KK2ludCBGaXhlZFNpemUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NCAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0ICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzIgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NCAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMiA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtGaXhlZDY0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprU0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtTRml4ZWQ2NFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0Zsb2F0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEUgIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRG91YmxlU2l6ZTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0wgICAgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtCb29sU2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuIC0xOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSA6IHJldHVybiAtMTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gLTE7Cit9CisKK2Jvb2wgQWxsQXNjaWkoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGV4dC5zaXplKCk7IGkrKykgeworICAgIGlmICgodGV4dFtpXSAmIDB4ODApICE9IDApIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKwordm9pZCBTZXRQcmltaXRpdmVWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMgcGFyYW1zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICBpZiAocGFyYW1zLnVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKQorICAgICAgJiYgIWRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcikpOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsidHlwZSJdID0gUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcikpOworICB9CisgIC8vIERlYWxzIHdpdGggZGVmYXVsdHMuIEZvciBDKystc3RyaW5nIHR5cGVzIChzdHJpbmcgYW5kIGJ5dGVzKSwKKyAgLy8gd2UgbWlnaHQgbmVlZCB0byBoYXZlIHRoZSBnZW5lcmF0ZWQgY29kZSBkbyB0aGUgdW5pY29kZSBkZWNvZGluZworICAvLyAoc2VlIGNvbW1lbnRzIGluIEludGVybmFsTmFuby5qYXZhIGZvciBnb3J5IGRldGFpbHMuKS4gV2Ugd291bGQKKyAgLy8gbGlrZSB0byBkbyB0aGlzIG9uY2UgaW50byBhIHN0YXRpYyBmaWVsZCBhbmQgcmUtdXNlIHRoYXQgZnJvbQorICAvLyB0aGVuIG9uLgorICBpZiAoZGVzY3JpcHRvci0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HICYmCisgICAgICAhZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5lbXB0eSgpICYmCisgICAgICAhcGFyYW1zLnVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKSkgeworICAgIGlmIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTKSB7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IERlZmF1bHRWYWx1ZShwYXJhbXMsIGRlc2NyaXB0b3IpOworICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2NvbnN0YW50Il0gPSBGaWVsZERlZmF1bHRDb25zdGFudE5hbWUoZGVzY3JpcHRvcik7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfY29uc3RhbnRfdmFsdWUiXSA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICAgImNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uYnl0ZXNEZWZhdWx0VmFsdWUoXCIkMFwiKSIsCisgICAgICAgICAgQ0VzY2FwZShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSk7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfY29weV9pZl9uZWVkZWQiXSA9CisgICAgICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gKyAiLmNsb25lKCkiOworICAgIH0gZWxzZSBpZiAoQWxsQXNjaWkoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkpIHsKKyAgICAgIC8vIEFsbCBjaGFycyBhcmUgQVNDSUkuICBJbiB0aGlzIGNhc2UgZGlyZWN0bHkgcmVmZXJlbmNpbmcgYQorICAgICAgLy8gQ0VzY2FwZSgpJ2Qgc3RyaW5nIGxpdGVyYWwgd29ya3MgZmluZS4KKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0KKyAgICAgICAgICAiXCIiICsgQ0VzY2FwZShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSArICJcIiI7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfY29weV9pZl9uZWVkZWQiXSA9ICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdOworICAgIH0gZWxzZSB7CisgICAgICAvLyBTdHJpbmdzIHdoZXJlIHNvbWUgY2hhcnMgYXJlIG5vbi1BU0NJSS4gV2UgbmVlZCB0byBzYXZlIHRoZQorICAgICAgLy8gZGVmYXVsdCB2YWx1ZS4KKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gRGVmYXVsdFZhbHVlKHBhcmFtcywgZGVzY3JpcHRvcik7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfY29uc3RhbnQiXSA9IEZpZWxkRGVmYXVsdENvbnN0YW50TmFtZShkZXNjcmlwdG9yKTsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb25zdGFudF92YWx1ZSJdID0gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5zdHJpbmdEZWZhdWx0VmFsdWUoXCIkMFwiKSIsCisgICAgICAgICAgQ0VzY2FwZShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSk7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfY29weV9pZl9uZWVkZWQiXSA9ICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBOb24tc3RyaW5nLCBub24tYnl0ZXMgZmllbGQuIERlZmF1bHRzIGFyZSBsaXRlcmFscy4KKyAgICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IERlZmF1bHRWYWx1ZShwYXJhbXMsIGRlc2NyaXB0b3IpOworICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb3B5X2lmX25lZWRlZCJdID0gKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il07CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJib3hlZF90eXBlIl0gPSBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEdldEphdmFUeXBlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJjYXBpdGFsaXplZF90eXBlIl0gPSBHZXRDYXBpdGFsaXplZFR5cGUoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbInRhZ19zaXplIl0gPSBTaW1wbGVJdG9hKAorICAgICAgV2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgZGVzY3JpcHRvci0+dHlwZSgpKSk7CisgICgqdmFyaWFibGVzKVsibm9uX3BhY2tlZF90YWciXSA9IFNpbXBsZUl0b2EoCisgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZGVzY3JpcHRvci0+bnVtYmVyKCksCisgICAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGRUeXBlKGRlc2NyaXB0b3ItPnR5cGUoKSkpKTsKKyAgaW50IGZpeGVkX3NpemUgPSBGaXhlZFNpemUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgaWYgKGZpeGVkX3NpemUgIT0gLTEpIHsKKyAgICAoKnZhcmlhYmxlcylbImZpeGVkX3NpemUiXSA9IFNpbXBsZUl0b2EoZml4ZWRfc2l6ZSk7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJtZXNzYWdlX25hbWUiXSA9IGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpLT5uYW1lKCk7CisgICgqdmFyaWFibGVzKVsiZW1wdHlfYXJyYXlfbmFtZSJdID0gRW1wdHlBcnJheU5hbWUocGFyYW1zLCBkZXNjcmlwdG9yKTsKK30KK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgcGFyYW1zLCAmdmFyaWFibGVzXyk7Cit9CisKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjp+UHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKSB7fQorCitib29sIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpTYXZlZERlZmF1bHROZWVkZWQoKSBjb25zdCB7CisgIHJldHVybiB2YXJpYWJsZXNfLmZpbmQoImRlZmF1bHRfY29uc3RhbnQiKSAhPSB2YXJpYWJsZXNfLmVuZCgpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICh2YXJpYWJsZXNfLmZpbmQoImRlZmF1bHRfY29uc3RhbnQiKSAhPSB2YXJpYWJsZXNfLmVuZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVmYXVsdF9jb25zdGFudCQgPSAkZGVmYXVsdF9jb25zdGFudF92YWx1ZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBsYXp5X2luaXQpIGNvbnN0IHsKKyAgaWYgKHZhcmlhYmxlc18uZmluZCgiZGVmYXVsdF9jb25zdGFudCIpICE9IHZhcmlhYmxlc18uZW5kKCkpIHsKKyAgICAvLyBUaG9zZSBwcmltaXRpdmUgdHlwZXMgdGhhdCBuZWVkIGEgc2F2ZWQgZGVmYXVsdC4KKyAgICBpZiAobGF6eV9pbml0KSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicHJpdmF0ZSBzdGF0aWMgJHR5cGUkICRkZWZhdWx0X2NvbnN0YW50JDtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicHJpdmF0ZSBzdGF0aWMgZmluYWwgJHR5cGUkICRkZWZhdWx0X2NvbnN0YW50JCA9XG4iCisgICAgICAgICIgICAgJGRlZmF1bHRfY29uc3RhbnRfdmFsdWUkO1xuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljICR0eXBlJCAkbmFtZSQ7XG4iKTsKKworICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkO1xuIik7CisgIH0KK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSQgPSAkZGVmYXVsdF9jb3B5X2lmX25lZWRlZCQ7XG4iKTsKKworICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaGFzJGNhcGl0YWxpemVkX25hbWUkID0gZmFsc2U7XG4iKTsKKyAgfQorfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGhpcy4kbmFtZSQgPSBpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCk7XG4iKTsKKworICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaGFzJGNhcGl0YWxpemVkX25hbWUkID0gdHJ1ZTtcbiIpOworICB9Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29uZGl0aW9uYWwoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKHBhcmFtc18udXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpKSB7CisgICAgLy8gRm9yIHJlZmVyZW5jZSB0eXBlIG1vZGUsIHNlcmlhbGl6ZSBiYXNlZCBvbiBlcXVhbGl0eQorICAgIC8vIHRvIG51bGwuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCkge1xuIik7CisgICAgcmV0dXJuOworICB9CisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoaGFzJGNhcGl0YWxpemVkX25hbWUkIHx8ICIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCIpOworICB9CisgIEphdmFUeXBlIGphdmFfdHlwZSA9IEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKTsKKyAgaWYgKElzQXJyYXlUeXBlKGphdmFfdHlwZSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLiRuYW1lJCwgJGRlZmF1bHQkKSkge1xuIik7CisgIH0gZWxzZSBpZiAoSXNSZWZlcmVuY2VUeXBlKGphdmFfdHlwZSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiF0aGlzLiRuYW1lJC5lcXVhbHMoJGRlZmF1bHQkKSkge1xuIik7CisgIH0gZWxzZSBpZiAoamF2YV90eXBlID09IEpBVkFUWVBFX0ZMT0FUKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHModGhpcy4kbmFtZSQpXG4iCisgICAgICAiICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygkZGVmYXVsdCQpKSB7XG4iKTsKKyAgfSBlbHNlIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfRE9VQkxFKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModGhpcy4kbmFtZSQpXG4iCisgICAgICAiICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygkZGVmYXVsdCQpKSB7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRoaXMuJG5hbWUkICE9ICRkZWZhdWx0JCkge1xuIik7CisgIH0KK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcmVxdWlyZWQoKSAmJiAhcGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIC8vIEFsd2F5cyBzZXJpYWxpemUgYSByZXF1aXJlZCBmaWVsZCBpZiB3ZSBkb24ndCBoYXZlIHRoZSAnaGFzJyBzaWduYWwuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSQoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIpOworICB9IGVsc2UgeworICAgIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvbmRpdGlvbmFsKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSQoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcmVxdWlyZWQoKSAmJiAhcGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICAgIiAgICAuY29tcHV0ZSRjYXBpdGFsaXplZF90eXBlJFNpemUoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIpOworICB9IGVsc2UgeworICAgIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvbmRpdGlvbmFsKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgICAiICAgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplKCRudW1iZXIkLCB0aGlzLiRuYW1lJCk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gV2UgZGVmaW5lIGVxdWFsaXR5IGFzIHNlcmlhbGl6ZWQgZm9ybSBlcXVhbGl0eS4gSWYgZ2VuZXJhdGVfaGFzKCksCisgIC8vIHRoZW4gaWYgdGhlIGZpZWxkIHZhbHVlIGVxdWFscyB0aGUgZGVmYXVsdCB2YWx1ZSBpbiBib3RoIG1lc3NhZ2VzLAorICAvLyBidXQgb25lJ3MgJ2hhcycgZmllbGQgaXMgc2V0IGFuZCB0aGUgb3RoZXIncyBpcyBub3QsIHRoZSBzZXJpYWxpemVkCisgIC8vIGZvcm1zIGFyZSBkaWZmZXJlbnQgYW5kIHdlIHNob3VsZCByZXR1cm4gZmFsc2UuCisgIEphdmFUeXBlIGphdmFfdHlwZSA9IEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKTsKKyAgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9CWVRFUykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLiRuYW1lJCwgb3RoZXIuJG5hbWUkKSIpOworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiXG4iCisgICAgICAgICIgICAgfHwgKGphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMuJG5hbWUkLCAkZGVmYXVsdCQpXG4iCisgICAgICAgICIgICAgICAgICYmIHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkICE9IG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCkiKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIikge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9TVFJJTkcKKyAgICAgIHx8IHBhcmFtc18udXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAodGhpcy4kbmFtZSQgPT0gbnVsbCkge1xuIgorICAgICAgIiAgaWYgKG90aGVyLiRuYW1lJCAhPSBudWxsKSB7XG4iCisgICAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9IGVsc2UgaWYgKCF0aGlzLiRuYW1lJC5lcXVhbHMob3RoZXIuJG5hbWUkKSIpOworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiXG4iCisgICAgICAgICIgICAgfHwgKHRoaXMuJG5hbWUkLmVxdWFscygkZGVmYXVsdCQpXG4iCisgICAgICAgICIgICAgICAgICYmIHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkICE9IG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCkiKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIikge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9GTE9BVCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAie1xuIgorICAgICAgIiAgaW50IGJpdHMgPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHModGhpcy4kbmFtZSQpO1xuIgorICAgICAgIiAgaWYgKGJpdHMgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKG90aGVyLiRuYW1lJCkiKTsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIlxuIgorICAgICAgICAiICAgICAgfHwgKGJpdHMgPT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKCRkZWZhdWx0JClcbiIKKyAgICAgICAgIiAgICAgICAgICAmJiB0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCAhPSBvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQpIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9ET1VCTEUpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIntcbiIKKyAgICAgICIgIGxvbmcgYml0cyA9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyh0aGlzLiRuYW1lJCk7XG4iCisgICAgICAiICBpZiAoYml0cyAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMob3RoZXIuJG5hbWUkKSIpOworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiXG4iCisgICAgICAgICIgICAgICB8fCAoYml0cyA9PSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoJGRlZmF1bHQkKVxuIgorICAgICAgICAiICAgICAgICAgICYmIHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkICE9IG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCkiKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIikge1xuIgorICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gb3RoZXIuJG5hbWUkIik7CisgICAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJcbiIKKyAgICAgICAgIiAgICB8fCAodGhpcy4kbmFtZSQgPT0gJGRlZmF1bHQkXG4iCisgICAgICAgICIgICAgICAgICYmIHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkICE9IG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCkiKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIikge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pOworICBpZiAoamF2YV90eXBlID09IEpBVkFUWVBFX0JZVEVTKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArIGphdmEudXRpbC5BcnJheXMuaGFzaENvZGUodGhpcy4kbmFtZSQpO1xuIik7CisgIH0gZWxzZSBpZiAoamF2YV90eXBlID09IEpBVkFUWVBFX1NUUklORworICAgICAgfHwgcGFyYW1zXy51c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0XG4iCisgICAgICAiICAgICsgKHRoaXMuJG5hbWUkID09IG51bGwgPyAwIDogdGhpcy4kbmFtZSQuaGFzaENvZGUoKSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgLy8gRm9yIGFsbCBKYXZhIHByaW1pdGl2ZSB0eXBlcyBiZWxvdywgdGhlIGhhc2ggY29kZXMgbWF0Y2ggdGhlCisgICAgICAvLyByZXN1bHRzIG9mIEJveGVkVHlwZS52YWx1ZU9mKHByaW1pdGl2ZVZhbHVlKS5oYXNoQ29kZSgpLgorICAgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICsgdGhpcy4kbmFtZSQ7XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEpBVkFUWVBFX0xPTkc6CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0XG4iCisgICAgICAgICAgIiAgICArIChpbnQpICh0aGlzLiRuYW1lJCBeICh0aGlzLiRuYW1lJCA+Pj4gMzIpKTtcbiIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQ6CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0XG4iCisgICAgICAgICAgIiAgICArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyh0aGlzLiRuYW1lJCk7XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRToKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAie1xuIgorICAgICAgICAgICIgIGxvbmcgdiA9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyh0aGlzLiRuYW1lJCk7XG4iCisgICAgICAgICAgIiAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyAoaW50KSAodiBeICh2ID4+PiAzMikpO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICsgKHRoaXMuJG5hbWUkID8gMTIzMSA6IDEyMzcpO1xuIik7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgInVua25vd24gamF2YSB0eXBlIGZvciBwcmltaXRpdmUgZmllbGQiOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0FjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICBjb25zdCBQYXJhbXMmIHBhcmFtcywgaW50IGhhc19iaXRfaW5kZXgpCisgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgcGFyYW1zLCAmdmFyaWFibGVzXyk7CisgIFNldEJpdE9wZXJhdGlvblZhcmlhYmxlcygiaGFzIiwgaGFzX2JpdF9pbmRleCwgJnZhcmlhYmxlc18pOworfQorCitBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjp+QWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHt9CisKK2Jvb2wgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6U2F2ZWREZWZhdWx0TmVlZGVkKCkgY29uc3QgeworICByZXR1cm4gdmFyaWFibGVzXy5maW5kKCJkZWZhdWx0X2NvbnN0YW50IikgIT0gdmFyaWFibGVzXy5lbmQoKTsKK30KKwordm9pZCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdFNhdmVkRGVmYXVsdENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKHZhcmlhYmxlc18uZmluZCgiZGVmYXVsdF9jb25zdGFudCIpICE9IHZhcmlhYmxlc18uZW5kKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZWZhdWx0X2NvbnN0YW50JCA9ICRkZWZhdWx0X2NvbnN0YW50X3ZhbHVlJDtcbiIpOworICB9Cit9CisKK3ZvaWQgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdCB7CisgIGlmICh2YXJpYWJsZXNfLmZpbmQoImRlZmF1bHRfY29uc3RhbnQiKSAhPSB2YXJpYWJsZXNfLmVuZCgpKSB7CisgICAgLy8gVGhvc2UgcHJpbWl0aXZlIHR5cGVzIHRoYXQgbmVlZCBhIHNhdmVkIGRlZmF1bHQuCisgICAgaWYgKGxhenlfaW5pdCkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInByaXZhdGUgc3RhdGljICR0eXBlJCAkZGVmYXVsdF9jb25zdGFudCQ7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInByaXZhdGUgc3RhdGljIGZpbmFsICR0eXBlJCAkZGVmYXVsdF9jb25zdGFudCQgPVxuIgorICAgICAgICAiICAgICRkZWZhdWx0X2NvbnN0YW50X3ZhbHVlJDtcbiIpOworICAgIH0KKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlICR0eXBlJCAkbmFtZSRfO1xuIgorICAgICJwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgJG1lc3NhZ2VfbmFtZSQgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIik7CisgIGlmIChJc1JlZmVyZW5jZVR5cGUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICAgIiAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgICAiICB9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkc2V0X2hhcyQ7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkZ2V0X2hhcyQ7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICRtZXNzYWdlX25hbWUkIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkZGVmYXVsdF9jb3B5X2lmX25lZWRlZCQ7XG4iCisgICAgIiAgJGNsZWFyX2hhcyQ7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXyA9ICRkZWZhdWx0X2NvcHlfaWZfbmVlZGVkJDtcbiIpOworfQorCit2b2lkIEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIgorICAgICIkc2V0X2hhcyQ7XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfaGFzJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfaGFzJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAiICAgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgc3dpdGNoIChHZXRKYXZhVHlwZShkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBGb3IgYWxsIEphdmEgcHJpbWl0aXZlIHR5cGVzIGJlbG93LCB0aGUgZXF1YWxpdHkgY2hlY2tzIG1hdGNoIHRoZQorICAgIC8vIHJlc3VsdHMgb2YgQm94ZWRUeXBlLnZhbHVlT2YocHJpbWl0aXZlVmFsdWUpLmVxdWFscyhvdGhlclZhbHVlKS4KKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICgkZGlmZmVyZW50X2hhcyRcbiIKKyAgICAgICAgIiAgICB8fCBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoJG5hbWUkXylcbiIKKyAgICAgICAgIiAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKG90aGVyLiRuYW1lJF8pKSB7XG4iCisgICAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEU6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaWYgKCRkaWZmZXJlbnRfaGFzJFxuIgorICAgICAgICAiICAgIHx8IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygkbmFtZSRfKVxuIgorICAgICAgICAiICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMob3RoZXIuJG5hbWUkXykpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAifVxuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX0lOVDoKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkc6CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICgkZGlmZmVyZW50X2hhcyRcbiIKKyAgICAgICAgIiAgICB8fCAkbmFtZSRfICE9IG90aGVyLiRuYW1lJF8pIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAifVxuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgIC8vIEFjY2Vzc29yIHN0eWxlIHdvdWxkIGd1YXJhbnRlZSAkbmFtZSRfIG5vbi1udWxsCisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaWYgKCRkaWZmZXJlbnRfaGFzJFxuIgorICAgICAgICAiICAgIHx8ICEkbmFtZSRfLmVxdWFscyhvdGhlci4kbmFtZSRfKSkge1xuIgorICAgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfQllURVM6CisgICAgICAvLyBBY2Nlc3NvciBzdHlsZSB3b3VsZCBndWFyYW50ZWUgJG5hbWUkXyBub24tbnVsbAorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICgkZGlmZmVyZW50X2hhcyRcbiIKKyAgICAgICAgIiAgICB8fCAhamF2YS51dGlsLkFycmF5cy5lcXVhbHMoJG5hbWUkXywgb3RoZXIuJG5hbWUkXykpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAifVxuIik7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgInVua25vd24gamF2YSB0eXBlIGZvciBwcmltaXRpdmUgZmllbGQiOworICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gRm9yIGFsbCBKYXZhIHByaW1pdGl2ZSB0eXBlcyBiZWxvdywgdGhlIGhhc2ggY29kZXMgbWF0Y2ggdGhlCisgICAgLy8gcmVzdWx0cyBvZiBCb3hlZFR5cGUudmFsdWVPZihwcmltaXRpdmVWYWx1ZSkuaGFzaENvZGUoKS4KKyAgICBjYXNlIEpBVkFUWVBFX0lOVDoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICRuYW1lJF87XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfTE9ORzoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArIChpbnQpICgkbmFtZSRfIF4gKCRuYW1lJF8gPj4+IDMyKSk7XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQ6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgK1xuIgorICAgICAgICAiICAgIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygkbmFtZSRfKTtcbiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEU6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAie1xuIgorICAgICAgICAiICBsb25nIHYgPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoJG5hbWUkXyk7XG4iCisgICAgICAgICIgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgKGludCkgKHYgXiAodiA+Pj4gMzIpKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICsgKCRuYW1lJF8gPyAxMjMxIDogMTIzNyk7XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HOgorICAgICAgLy8gQWNjZXNzb3Igc3R5bGUgd291bGQgZ3VhcmFudGVlICRuYW1lJF8gbm9uLW51bGwKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICRuYW1lJF8uaGFzaENvZGUoKTtcbiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUzoKKyAgICAgIC8vIEFjY2Vzc29yIHN0eWxlIHdvdWxkIGd1YXJhbnRlZSAkbmFtZSRfIG5vbi1udWxsCisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgKyBqYXZhLnV0aWwuQXJyYXlzLmhhc2hDb2RlKCRuYW1lJF8pO1xuIik7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgInVua25vd24gamF2YSB0eXBlIGZvciBwcmltaXRpdmUgZmllbGQiOworICAgICAgYnJlYWs7CisgIH0KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjpQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICAgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBwYXJhbXMsICZ2YXJpYWJsZXNfKTsKKyAgICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7Cit9CisKK1ByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6On5QcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZU1lbWJlcnMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyp1bnVzZWQgbGF6eV9pbml0Ki8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkaGFzX29uZW9mX2Nhc2UkO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2UkKSB7XG4iCisgICAgIiAgICByZXR1cm4gKCR0eXBlJCkgKCRib3hlZF90eXBlJCkgdGhpcy4kb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyAkbWVzc2FnZV9uYW1lJCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgJHNldF9vbmVvZl9jYXNlJDtcbiIKKyAgICAiICB0aGlzLiRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVDbGVhckNvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm8gY2xlYXIgbWV0aG9kIGZvciBvbmVvZiBmaWVsZHMuCit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVNZXJnaW5nQ29kZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0aGlzLiRvbmVvZl9uYW1lJF8gPSBpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCk7XG4iCisgICAgIiRzZXRfb25lb2ZfY2FzZSQ7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKFxuIgorICAgICIgICAgICAkbnVtYmVyJCwgKCRib3hlZF90eXBlJCkgdGhpcy4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgIiAgICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZShcbiIKKyAgICAiICAgICAgICAgICRudW1iZXIkLCAoJGJveGVkX3R5cGUkKSB0aGlzLiRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUVxdWFsc0NvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgR2VuZXJhdGVPbmVvZkZpZWxkRXF1YWxzKGRlc2NyaXB0b3JfLCB2YXJpYWJsZXNfLCBwcmludGVyKTsKK30KKwordm9pZCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUhhc2hDb2RlQ29kZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBHZW5lcmF0ZU9uZW9mRmllbGRIYXNoQ29kZShkZXNjcmlwdG9yXywgdmFyaWFibGVzXywgcHJpbnRlcik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6UmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGRlc2NyaXB0b3IsIHBhcmFtcywgJnZhcmlhYmxlc18pOworfQorCitSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyp1bnVzZWQgaW5pdF9kZWZhdWx0cyovKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInB1YmxpYyAkdHlwZSRbXSAkbmFtZSQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICRkZWZhdWx0JDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBGaXJzdCwgZmlndXJlIG91dCB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheSwgdGhlbiBwYXJzZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGFycmF5TGVuZ3RoID0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vXG4iCisgICAgIiAgICAuZ2V0UmVwZWF0ZWRGaWVsZEFycmF5TGVuZ3RoKGlucHV0LCAkbm9uX3BhY2tlZF90YWckKTtcbiIKKyAgICAiaW50IGkgPSB0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkLmxlbmd0aDtcbiIpOworCisgIGlmIChHZXRKYXZhVHlwZShkZXNjcmlwdG9yXykgPT0gSkFWQVRZUEVfQllURVMpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImJ5dGVbXVtdIG5ld0FycmF5ID0gbmV3IGJ5dGVbaSArIGFycmF5TGVuZ3RoXVtdO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkdHlwZSRbXSBuZXdBcnJheSA9IG5ldyAkdHlwZSRbaSArIGFycmF5TGVuZ3RoXTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmIChpICE9IDApIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuU3lzdGVtLmFycmF5Y29weSh0aGlzLiRuYW1lJCwgMCwgbmV3QXJyYXksIDAsIGkpO1xuIgorICAgICJ9XG4iCisgICAgImZvciAoOyBpIDwgbmV3QXJyYXkubGVuZ3RoIC0gMTsgaSsrKSB7XG4iCisgICAgIiAgbmV3QXJyYXlbaV0gPSBpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCk7XG4iCisgICAgIiAgaW5wdXQucmVhZFRhZygpO1xuIgorICAgICJ9XG4iCisgICAgIi8vIExhc3Qgb25lIHdpdGhvdXQgcmVhZFRhZy5cbiIKKyAgICAibmV3QXJyYXlbaV0gPSBpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCk7XG4iCisgICAgInRoaXMuJG5hbWUkID0gbmV3QXJyYXk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7XG4iCisgICAgImludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpO1xuIik7CisKKyAgLy8gSWYgd2Uga25vdyB0aGUgZWxlbWVudHMgd2lsbCBhbGwgYmUgb2YgdGhlIHNhbWUgc2l6ZSwgdGhlIGFycmF5TGVuZ3RoCisgIC8vIGNhbiBiZSBjYWxjdWxhdGVkIG11Y2ggbW9yZSBlYXNpbHkuIEhvd2V2ZXIsIEZpeGVkU2l6ZSgpIHJldHVybnMgMSBmb3IKKyAgLy8gcmVwZWF0ZWQgYm9vbCBmaWVsZHMsIHdoaWNoIGFyZSBndWFyYW50ZWVkIHRvIGhhdmUgdGhlIGZpeGVkIHNpemUgb2YKKyAgLy8gMSBieXRlIHBlciB2YWx1ZSBvbmx5IGlmIHdlIGNvbnRyb2wgdGhlIG91dHB1dC4gT24gdGhlIHdpcmUgdGhleSBjYW4KKyAgLy8gbGVnYWxseSBhcHBlYXIgYXMgdmFyaWFibGUtc2l6ZSBpbnRlZ2Vycywgc28gd2UgbmVlZCB0byB1c2UgdGhlIHNsb3cKKyAgLy8gd2F5IGZvciByZXBlYXRlZCBib29sIGZpZWxkcy4KKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0wKKyAgICAgIHx8IEZpeGVkU2l6ZShkZXNjcmlwdG9yXy0+dHlwZSgpKSA9PSAtMSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiLy8gRmlyc3QgcGFzcyB0byBjb21wdXRlIGFycmF5IGxlbmd0aC5cbiIKKyAgICAgICJpbnQgYXJyYXlMZW5ndGggPSAwO1xuIgorICAgICAgImludCBzdGFydFBvcyA9IGlucHV0LmdldFBvc2l0aW9uKCk7XG4iCisgICAgICAid2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIgorICAgICAgIiAgaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIgorICAgICAgIiAgYXJyYXlMZW5ndGgrKztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiaW5wdXQucmV3aW5kVG9Qb3NpdGlvbihzdGFydFBvcyk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCBhcnJheUxlbmd0aCA9IGxlbmd0aCAvICRmaXhlZF9zaXplJDtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGkgPSB0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkLmxlbmd0aDtcbiIKKyAgICAiJHR5cGUkW10gbmV3QXJyYXkgPSBuZXcgJHR5cGUkW2kgKyBhcnJheUxlbmd0aF07XG4iCisgICAgImlmIChpICE9IDApIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuU3lzdGVtLmFycmF5Y29weSh0aGlzLiRuYW1lJCwgMCwgbmV3QXJyYXksIDAsIGkpO1xuIgorICAgICJ9XG4iCisgICAgImZvciAoOyBpIDwgbmV3QXJyYXkubGVuZ3RoOyBpKyspIHtcbiIKKyAgICAiICBuZXdBcnJheVtpXSA9IGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKTtcbiIKKyAgICAifVxuIgorICAgICJ0aGlzLiRuYW1lJCA9IG5ld0FycmF5O1xuIgorICAgICJpbnB1dC5wb3BMaW1pdChsaW1pdCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUmVwZWF0ZWREYXRhU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gQ3JlYXRlcyBhIHZhcmlhYmxlIGRhdGFTaXplIGFuZCBwdXRzIHRoZSBzZXJpYWxpemVkIHNpemUgaW4gdGhlcmUuCisgIC8vIElmIHRoZSBlbGVtZW50IHR5cGUgaXMgYSBKYXZhIHJlZmVyZW5jZSB0eXBlLCBhbHNvIGdlbmVyYXRlcworICAvLyBkYXRhQ291bnQgd2hpY2ggc3RvcmVzIHRoZSBudW1iZXIgb2Ygbm9uLW51bGwgZWxlbWVudHMgaW4gdGhlIGZpZWxkLgorICBpZiAoSXNSZWZlcmVuY2VUeXBlKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCBkYXRhQ291bnQgPSAwO1xuIgorICAgICAgImludCBkYXRhU2l6ZSA9IDA7XG4iCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICAgIiAgJHR5cGUkIGVsZW1lbnQgPSB0aGlzLiRuYW1lJFtpXTtcbiIKKyAgICAgICIgIGlmIChlbGVtZW50ICE9IG51bGwpIHtcbiIKKyAgICAgICIgICAgZGF0YUNvdW50Kys7XG4iCisgICAgICAiICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgICAiICAgICAgICAuY29tcHV0ZSRjYXBpdGFsaXplZF90eXBlJFNpemVOb1RhZyhlbGVtZW50KTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIGlmIChGaXhlZFNpemUoZGVzY3JpcHRvcl8tPnR5cGUoKSkgPT0gLTEpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCBkYXRhU2l6ZSA9IDA7XG4iCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICAgIiAgJHR5cGUkIGVsZW1lbnQgPSB0aGlzLiRuYW1lJFtpXTtcbiIKKyAgICAgICIgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgICAiICAgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplTm9UYWcoZWxlbWVudCk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgZGF0YVNpemUgPSAkZml4ZWRfc2l6ZSQgKiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrYWJsZSgpICYmIGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBHZW5lcmF0ZVJlcGVhdGVkRGF0YVNpemVDb2RlKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAib3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJHRhZyQpO1xuIgorICAgICAgIm91dHB1dC53cml0ZVJhd1ZhcmludDMyKGRhdGFTaXplKTtcbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSROb1RhZyh0aGlzLiRuYW1lJFtpXSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSBpZiAoSXNSZWZlcmVuY2VUeXBlKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy4kbmFtZSQubGVuZ3RoOyBpKyspIHtcbiIKKyAgICAgICIgICR0eXBlJCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgICAiICBpZiAoZWxlbWVudCAhPSBudWxsKSB7XG4iCisgICAgICAiICAgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgZWxlbWVudCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSQoJG51bWJlciQsIHRoaXMuJG5hbWUkW2ldKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwgJiYgdGhpcy4kbmFtZSQubGVuZ3RoID4gMCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIEdlbmVyYXRlUmVwZWF0ZWREYXRhU2l6ZUNvZGUocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInNpemUgKz0gZGF0YVNpemU7XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrYWJsZSgpICYmIGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNpemUgKz0gJHRhZ19zaXplJDtcbiIKKyAgICAgICJzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgICAiICAgIC5jb21wdXRlUmF3VmFyaW50MzJTaXplKGRhdGFTaXplKTtcbiIpOworICB9IGVsc2UgaWYgKElzUmVmZXJlbmNlVHlwZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yXykpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiBkYXRhQ291bnQ7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNpemUgKz0gJHRhZ19zaXplJCAqIHRoaXMuJG5hbWUkLmxlbmd0aDtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIWNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uZXF1YWxzKFxuIgorICAgICIgICAgdGhpcy4kbmFtZSQsIG90aGVyLiRuYW1lJCkpIHtcbiIKKyAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gMzEgKiByZXN1bHRcbiIKKyAgICAiICAgICsgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5oYXNoQ29kZSh0aGlzLiRuYW1lJCk7XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wcmltaXRpdmVfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E3MTE2ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmgKQEAgLTAsMCArMSwxNDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19QUklNSVRJVkVfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19QUklNSVRJVkVfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgflByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBTYXZlZERlZmF1bHROZWVkZWQoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db25kaXRpb25hbChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgY29uc3QgUGFyYW1zICZwYXJhbXMsIGludCBoYXNfYml0X2luZGV4KTsKKyAgfkFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIFNhdmVkRGVmYXVsdE5lZWRlZCgpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdFNhdmVkRGVmYXVsdENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBsYXp5X2luaXQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcyk7CisgIH5QcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+UmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlUmVwZWF0ZWREYXRhU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX1BSSU1JVElWRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvbWFpbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvbWFpbi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzFiOGZhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tYWluLmNjCkBAIC0wLDAgKzEsNzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmg+CisKK2ludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2W10pIHsKKworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29tbWFuZExpbmVJbnRlcmZhY2UgY2xpOworICBjbGkuQWxsb3dQbHVnaW5zKCJwcm90b2MtIik7CisKKyAgLy8gUHJvdG8yIEMrKworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Y3BwOjpDcHBHZW5lcmF0b3IgY3BwX2dlbmVyYXRvcjsKKyAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLWNwcF9vdXQiLCAiLS1jcHBfb3B0IiwgJmNwcF9nZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhdGUgQysrIGhlYWRlciBhbmQgc291cmNlLiIpOworCisgIC8vIFByb3RvMiBKYXZhCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpqYXZhOjpKYXZhR2VuZXJhdG9yIGphdmFfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tamF2YV9vdXQiLCAmamF2YV9nZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhdGUgSmF2YSBzb3VyY2UgZmlsZS4iKTsKKworCisgIC8vIFByb3RvMiBQeXRob24KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OnB5dGhvbjo6R2VuZXJhdG9yIHB5X2dlbmVyYXRvcjsKKyAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLXB5dGhvbl9vdXQiLCAmcHlfZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIkdlbmVyYXRlIFB5dGhvbiBzb3VyY2UgZmlsZS4iKTsKKworICAvLyBKYXZhIE5hbm8KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OmphdmFuYW5vOjpKYXZhTmFub0dlbmVyYXRvciBqYXZhbmFub19nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1qYXZhbmFub19vdXQiLCAmamF2YW5hbm9fZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIkdlbmVyYXRlIEphdmEgTmFubyBzb3VyY2UgZmlsZS4iKTsKKworICAvLyBSdWJ5CisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpydWJ5OjpHZW5lcmF0b3IgcmJfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tcnVieV9vdXQiLCAmcmJfZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIkdlbmVyYXRlIFJ1Ynkgc291cmNlIGZpbGUuIik7CisKKyAgcmV0dXJuIGNsaS5SdW4oYXJnYywgYXJndik7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTgyNjE0MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvbW9ja19jb2RlX2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDI0MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworLy8gUmV0dXJucyB0aGUgbGlzdCBvZiB0aGUgbmFtZXMgb2YgZmlsZXMgaW4gYWxsX2ZpbGVzIGluIHRoZSBmb3JtIG9mIGEKKy8vIGNvbW1hLXNlcGFyYXRlZCBzdHJpbmcuCitzdHJpbmcgQ29tbWFTZXBhcmF0ZWRMaXN0KGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+IGFsbF9maWxlcykgeworICB2ZWN0b3I8c3RyaW5nPiBuYW1lczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxfZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICBuYW1lcy5wdXNoX2JhY2soYWxsX2ZpbGVzW2ldLT5uYW1lKCkpOworICB9CisgIHJldHVybiBKb2luKG5hbWVzLCAiLCIpOworfQorCitzdGF0aWMgY29uc3QgY2hhcioga0ZpcnN0SW5zZXJ0aW9uUG9pbnROYW1lID0gImZpcnN0X21vY2tfaW5zZXJ0aW9uX3BvaW50IjsKK3N0YXRpYyBjb25zdCBjaGFyKiBrU2Vjb25kSW5zZXJ0aW9uUG9pbnROYW1lID0gInNlY29uZF9tb2NrX2luc2VydGlvbl9wb2ludCI7CitzdGF0aWMgY29uc3QgY2hhcioga0ZpcnN0SW5zZXJ0aW9uUG9pbnQgPQorICAgICIjIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaXJzdF9tb2NrX2luc2VydGlvbl9wb2ludCkgaXMgaGVyZVxuIjsKK3N0YXRpYyBjb25zdCBjaGFyKiBrU2Vjb25kSW5zZXJ0aW9uUG9pbnQgPQorICAgICIgICMgQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlY29uZF9tb2NrX2luc2VydGlvbl9wb2ludCkgaXMgaGVyZVxuIjsKKworTW9ja0NvZGVHZW5lcmF0b3I6Ok1vY2tDb2RlR2VuZXJhdG9yKGNvbnN0IHN0cmluZyYgbmFtZSkKKyAgICA6IG5hbWVfKG5hbWUpIHt9CisKK01vY2tDb2RlR2VuZXJhdG9yOjp+TW9ja0NvZGVHZW5lcmF0b3IoKSB7fQorCit2b2lkIE1vY2tDb2RlR2VuZXJhdG9yOjpFeHBlY3RHZW5lcmF0ZWQoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIGZpbGUsCisgICAgY29uc3Qgc3RyaW5nJiBmaXJzdF9tZXNzYWdlX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBmaXJzdF9wYXJzZWRfZmlsZV9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgb3V0cHV0X2RpcmVjdG9yeSkgeworICBzdHJpbmcgY29udGVudDsKKyAgR09PR0xFX0NIRUNLX09LKAorICAgICAgRmlsZTo6R2V0Q29udGVudHMob3V0cHV0X2RpcmVjdG9yeSArICIvIiArIEdldE91dHB1dEZpbGVOYW1lKG5hbWUsIGZpbGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgJmNvbnRlbnQsIHRydWUpKTsKKworICB2ZWN0b3I8c3RyaW5nPiBsaW5lcyA9IFNwbGl0KGNvbnRlbnQsICJcbiIsIHRydWUpOworCisgIHdoaWxlICghbGluZXMuZW1wdHkoKSAmJiBsaW5lcy5iYWNrKCkuZW1wdHkoKSkgeworICAgIGxpbmVzLnBvcF9iYWNrKCk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaW5lcy5zaXplKCk7IGkrKykgeworICAgIGxpbmVzW2ldICs9ICJcbiI7CisgIH0KKworICB2ZWN0b3I8c3RyaW5nPiBpbnNlcnRpb25fbGlzdDsKKyAgaWYgKCFpbnNlcnRpb25zLmVtcHR5KCkpIHsKKyAgICBTcGxpdFN0cmluZ1VzaW5nKGluc2VydGlvbnMsICIsIiwgJmluc2VydGlvbl9saXN0KTsKKyAgfQorCisgIEVYUEVDVF9FUShsaW5lcy5zaXplKCksIDMgKyBpbnNlcnRpb25fbGlzdC5zaXplKCkgKiAyKTsKKyAgRVhQRUNUX0VRKEdldE91dHB1dEZpbGVDb250ZW50KG5hbWUsIHBhcmFtZXRlciwgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0X3BhcnNlZF9maWxlX25hbWUsIGZpcnN0X21lc3NhZ2VfbmFtZSksCisgICAgICAgICAgICBsaW5lc1swXSk7CisKKyAgRVhQRUNUX0VRKGtGaXJzdEluc2VydGlvblBvaW50LCBsaW5lc1sxICsgaW5zZXJ0aW9uX2xpc3Quc2l6ZSgpXSk7CisgIEVYUEVDVF9FUShrU2Vjb25kSW5zZXJ0aW9uUG9pbnQsIGxpbmVzWzIgKyBpbnNlcnRpb25fbGlzdC5zaXplKCkgKiAyXSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnNlcnRpb25fbGlzdC5zaXplKCk7IGkrKykgeworICAgIEVYUEVDVF9FUShHZXRPdXRwdXRGaWxlQ29udGVudChpbnNlcnRpb25fbGlzdFtpXSwgImZpcnN0X2luc2VydCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUsIGZpbGUsIGZpcnN0X21lc3NhZ2VfbmFtZSksCisgICAgICAgICAgICAgIGxpbmVzWzEgKyBpXSk7CisgICAgLy8gU2Vjb25kIGluc2VydGlvbiBwb2ludCBpcyBpbmRlbnRlZCwgc28gdGhlIGluc2VydGVkIHRleHQgc2hvdWxkCisgICAgLy8gYXV0b21hdGljYWxseSBiZSBpbmRlbnRlZCB0b28uCisgICAgRVhQRUNUX0VRKCIgICIgKyBHZXRPdXRwdXRGaWxlQ29udGVudChpbnNlcnRpb25fbGlzdFtpXSwgInNlY29uZF9pbnNlcnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSwgZmlsZSwgZmlyc3RfbWVzc2FnZV9uYW1lKSwKKyAgICAgICAgICAgICAgbGluZXNbMiArIGluc2VydGlvbl9saXN0LnNpemUoKSArIGldKTsKKyAgfQorfQorCitib29sIE1vY2tDb2RlR2VuZXJhdG9yOjpHZW5lcmF0ZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKEhhc1ByZWZpeFN0cmluZyhmaWxlLT5tZXNzYWdlX3R5cGUoaSktPm5hbWUoKSwgIk1vY2tDb2RlR2VuZXJhdG9yXyIpKSB7CisgICAgICBzdHJpbmcgY29tbWFuZCA9IFN0cmlwUHJlZml4U3RyaW5nKGZpbGUtPm1lc3NhZ2VfdHlwZShpKS0+bmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9ja0NvZGVHZW5lcmF0b3JfIik7CisgICAgICBpZiAoY29tbWFuZCA9PSAiRXJyb3IiKSB7CisgICAgICAgICplcnJvciA9ICJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0Vycm9yLiI7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSAiRXhpdCIpIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQuIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIGV4aXQoMTIzKTsKKyAgICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSAiQWJvcnQiKSB7CisgICAgICAgIHN0ZDo6Y2VyciA8PCAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9BYm9ydC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgYWJvcnQoKTsKKyAgICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSAiSGFzU291cmNlQ29kZUluZm8iKSB7CisgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9kZXNjcmlwdG9yX3Byb3RvOworICAgICAgICBmaWxlLT5Db3B5U291cmNlQ29kZUluZm9UbygmZmlsZV9kZXNjcmlwdG9yX3Byb3RvKTsKKyAgICAgICAgYm9vbCBoYXNfc291cmNlX2NvZGVfaW5mbyA9CisgICAgICAgICAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSAmJgorICAgICAgICAgICAgZmlsZV9kZXNjcmlwdG9yX3Byb3RvLnNvdXJjZV9jb2RlX2luZm8oKS5sb2NhdGlvbl9zaXplKCkgPiAwOworICAgICAgICBzdGQ6OmNlcnIgPDwgIlNhdyBtZXNzYWdlIHR5cGUgTW9ja0NvZGVHZW5lcmF0b3JfSGFzU291cmNlQ29kZUluZm86ICIKKyAgICAgICAgICAgICAgICAgIDw8IGhhc19zb3VyY2VfY29kZV9pbmZvIDw8ICIuIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIGFib3J0KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5rbm93biBNb2NrQ29kZUdlbmVyYXRvciBjb21tYW5kOiAiIDw8IGNvbW1hbmQ7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhwYXJhbWV0ZXIsICJpbnNlcnQ9IikpIHsKKyAgICB2ZWN0b3I8c3RyaW5nPiBpbnNlcnRfaW50bzsKKyAgICBTcGxpdFN0cmluZ1VzaW5nKFN0cmlwUHJlZml4U3RyaW5nKHBhcmFtZXRlciwgImluc2VydD0iKSwKKyAgICAgICAgICAgICAgICAgICAgICIsIiwgJmluc2VydF9pbnRvKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5zZXJ0X2ludG8uc2l6ZSgpOyBpKyspIHsKKyAgICAgIHsKKyAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dChjb250ZXh0LT5PcGVuRm9ySW5zZXJ0KAorICAgICAgICAgICAgR2V0T3V0cHV0RmlsZU5hbWUoaW5zZXJ0X2ludG9baV0sIGZpbGUpLCBrRmlyc3RJbnNlcnRpb25Qb2ludE5hbWUpKTsKKyAgICAgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgICAgIHByaW50ZXIuUHJpbnRSYXcoR2V0T3V0cHV0RmlsZUNvbnRlbnQobmFtZV8sICJmaXJzdF9pbnNlcnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUsIGNvbnRleHQpKTsKKyAgICAgICAgaWYgKHByaW50ZXIuZmFpbGVkKCkpIHsKKyAgICAgICAgICAqZXJyb3IgPSAiTW9ja0NvZGVHZW5lcmF0b3IgZGV0ZWN0ZWQgd3JpdGUgZXJyb3IuIjsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgeworICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICAgICAgY29udGV4dC0+T3BlbkZvckluc2VydChHZXRPdXRwdXRGaWxlTmFtZShpbnNlcnRfaW50b1tpXSwgZmlsZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtTZWNvbmRJbnNlcnRpb25Qb2ludE5hbWUpKTsKKyAgICAgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgICAgIHByaW50ZXIuUHJpbnRSYXcoR2V0T3V0cHV0RmlsZUNvbnRlbnQobmFtZV8sICJzZWNvbmRfaW5zZXJ0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLCBjb250ZXh0KSk7CisgICAgICAgIGlmIChwcmludGVyLmZhaWxlZCgpKSB7CisgICAgICAgICAgKmVycm9yID0gIk1vY2tDb2RlR2VuZXJhdG9yIGRldGVjdGVkIHdyaXRlIGVycm9yLiI7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9IGVsc2UgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGNvbnRleHQtPk9wZW4oR2V0T3V0cHV0RmlsZU5hbWUobmFtZV8sIGZpbGUpKSk7CisKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBwcmludGVyLlByaW50UmF3KEdldE91dHB1dEZpbGVDb250ZW50KG5hbWVfLCBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLCBjb250ZXh0KSk7CisgICAgcHJpbnRlci5QcmludFJhdyhrRmlyc3RJbnNlcnRpb25Qb2ludCk7CisgICAgcHJpbnRlci5QcmludFJhdyhrU2Vjb25kSW5zZXJ0aW9uUG9pbnQpOworCisgICAgaWYgKHByaW50ZXIuZmFpbGVkKCkpIHsKKyAgICAgICplcnJvciA9ICJNb2NrQ29kZUdlbmVyYXRvciBkZXRlY3RlZCB3cml0ZSBlcnJvci4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitzdHJpbmcgTW9ja0NvZGVHZW5lcmF0b3I6OkdldE91dHB1dEZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBHZXRPdXRwdXRGaWxlTmFtZShnZW5lcmF0b3JfbmFtZSwgZmlsZS0+bmFtZSgpKTsKK30KKworc3RyaW5nIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlTmFtZShjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUgKyAiLk1vY2tDb2RlR2VuZXJhdG9yLiIgKyBnZW5lcmF0b3JfbmFtZTsKK30KKworc3RyaW5nIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlQ29udGVudCgKKyAgICBjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgIEdlbmVyYXRvckNvbnRleHQgKmNvbnRleHQpIHsKKyAgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gYWxsX2ZpbGVzOworICBjb250ZXh0LT5MaXN0UGFyc2VkRmlsZXMoJmFsbF9maWxlcyk7CisgIHJldHVybiBHZXRPdXRwdXRGaWxlQ29udGVudCgKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCBwYXJhbWV0ZXIsIGZpbGUtPm5hbWUoKSwKKyAgICAgIENvbW1hU2VwYXJhdGVkTGlzdChhbGxfZmlsZXMpLAorICAgICAgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkgPiAwID8KKyAgICAgICAgICBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm5hbWUoKSA6ICIobm9uZSkiKTsKK30KKworc3RyaW5nIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlQ29udGVudCgKKyAgICBjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IHN0cmluZyYgZmlsZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcnNlZF9maWxlX2xpc3QsCisgICAgY29uc3Qgc3RyaW5nJiBmaXJzdF9tZXNzYWdlX25hbWUpIHsKKyAgcmV0dXJuIHN0cmluZ3M6OlN1YnN0aXR1dGUoIiQwOiAkMSwgJDIsICQzLCAkNFxuIiwKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCBwYXJhbWV0ZXIsIGZpbGUsCisgICAgICBmaXJzdF9tZXNzYWdlX25hbWUsIHBhcnNlZF9maWxlX2xpc3QpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzgzNDhkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmgKQEAgLTAsMCArMSwxMTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX01PQ0tfQ09ERV9HRU5FUkFUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9NT0NLX0NPREVfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCisvLyBBIG1vY2sgQ29kZUdlbmVyYXRvciwgdXNlZCBieSBjb21tYW5kX2xpbmVfaW50ZXJmYWNlX3VuaXR0ZXN0LiAgVGhpcyBpcyBpbgorLy8gaXRzIG93biBmaWxlIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWQgYm90aCBkaXJlY3RseSBhbmQgYXMgYSBwbHVnaW4uCisvLworLy8gR2VuZXJhdGUoKSBwcm9kdWNlcyBzb21lIG91dHB1dCB3aGljaCBjYW4gYmUgY2hlY2tlZCBieSBFeHBlY3RDYWxsZWQoKS4gIFRoZQorLy8gZ2VuZXJhdG9yIGNhbiBydW4gaW4gYSBkaWZmZXJlbnQgcHJvY2VzcyAoZS5nLiBhIHBsdWdpbikuCisvLworLy8gSWYgdGhlIHBhcmFtZXRlciBpcyAiaW5zZXJ0PU5BTUVTIiwgdGhlIE1vY2tDb2RlR2VuZXJhdG9yIHdpbGwgaW5zZXJ0IGxpbmVzCisvLyBpbnRvIHRoZSBmaWxlcyBnZW5lcmF0ZWQgYnkgb3RoZXIgTW9ja0NvZGVHZW5lcmF0b3JzIGluc3RlYWQgb2YgY3JlYXRpbmcKKy8vIGl0cyBvd24gZmlsZS4gIE5BTUVTIGlzIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgdGhlIG5hbWVzIG9mIHRob3NlIG90aGVyCisvLyBNb2NrQ29kZUdlbmVyYXRvcnMuCisvLworLy8gTW9ja0NvZGVHZW5lcmF0b3Igd2lsbCBhbHNvIG1vZGlmeSBpdHMgYmVoYXZpb3Igc2xpZ2h0bHkgaWYgdGhlIGlucHV0IGZpbGUKKy8vIGNvbnRhaW5zIGEgbWVzc2FnZSB0eXBlIHdpdGggb25lIG9mIHRoZSBmb2xsb3dpbmcgbmFtZXM6CisvLyAgIE1vY2tDb2RlR2VuZXJhdG9yX0Vycm9yOiAgQ2F1c2VzIEdlbmVyYXRlKCkgdG8gcmV0dXJuIGZhbHNlIGFuZCBzZXQgdGhlCisvLyAgICAgZXJyb3IgbWVzc2FnZSB0byAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9FcnJvci4iCisvLyAgIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQ6ICBHZW5lcmF0ZSgpIHByaW50cyAiU2F3IG1lc3NhZ2UgdHlwZQorLy8gICAgIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQuIiB0byBzdGRlcnIgYW5kIHRoZW4gY2FsbHMgZXhpdCgxMjMpLgorLy8gICBNb2NrQ29kZUdlbmVyYXRvcl9BYm9ydDogIEdlbmVyYXRlKCkgcHJpbnRzICJTYXcgbWVzc2FnZSB0eXBlCisvLyAgICAgTW9ja0NvZGVHZW5lcmF0b3JfQWJvcnQuIiB0byBzdGRlcnIgYW5kIHRoZW4gY2FsbHMgYWJvcnQoKS4KKy8vICAgTW9ja0NvZGVHZW5lcmF0b3JfSGFzU291cmNlQ29kZUluZm86ICBDYXVzZXMgR2VuZXJhdGUoKSB0byBhYm9ydCBhZnRlcgorLy8gICAgIHByaW50aW5nICJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0hhc1NvdXJjZUNvZGVJbmZvOiBGT08uIiB0bworLy8gICAgIHN0ZGVyciwgd2hlcmUgRk9PIGlzICIxIiBpZiB0aGUgc3VwcGxpZWQgRmlsZURlc2NyaXB0b3JQcm90byBoYXMgc291cmNlCisvLyAgICAgY29kZSBpbmZvLCBhbmQgIjAiIG90aGVyd2lzZS4KK2NsYXNzIE1vY2tDb2RlR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgTW9ja0NvZGVHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKyAgdmlydHVhbCB+TW9ja0NvZGVHZW5lcmF0b3IoKTsKKworICAvLyBFeHBlY3QgKHZpYSBnVGVzdCkgdGhhdCBhIE1vY2tDb2RlR2VuZXJhdG9yIHdpdGggdGhlIGdpdmVuIG5hbWUgd2FzIGNhbGxlZAorICAvLyB3aXRoIHRoZSBnaXZlbiBwYXJhbWV0ZXJzIGJ5IGluc3BlY3RpbmcgdGhlIG91dHB1dCBsb2NhdGlvbi4KKyAgLy8KKyAgLy8gfGluc2VydGlvbnN8IGlzIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgbmFtZXMgb2YgTW9ja0NvZGVHZW5lcmF0b3JzIHdoaWNoCisgIC8vIHNob3VsZCBoYXZlIGluc2VydGVkIGxpbmVzIGludG8gdGhpcyBmaWxlLgorICAvLyB8cGFyc2VkX2ZpbGVfbGlzdHwgaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBuYW1lcyBvZiB0aGUgZmlsZXMKKyAgLy8gdGhhdCBhcmUgYmVpbmcgY29tcGlsZWQgdG9nZXRoZXIgaW4gdGhpcyBydW4uCisgIHN0YXRpYyB2b2lkIEV4cGVjdEdlbmVyYXRlZChjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlyc3RfbWVzc2FnZV9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJzZWRfZmlsZV9saXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBvdXRwdXRfZGlyZWN0b3J5KTsKKworICAvLyBHZXQgdGhlIG5hbWUgb2YgdGhlIGZpbGUgd2hpY2ggd291bGQgYmUgd3JpdHRlbiBieSB0aGUgZ2l2ZW4gZ2VuZXJhdG9yLgorICBzdGF0aWMgc3RyaW5nIEdldE91dHB1dEZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICBzdGF0aWMgc3RyaW5nIEdldE91dHB1dEZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlKTsKKworICAvLyBpbXBsZW1lbnRzIENvZGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgc3RyaW5nIG5hbWVfOworCisgIHN0YXRpYyBzdHJpbmcgR2V0T3V0cHV0RmlsZUNvbnRlbnQoY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0ICpjb250ZXh0KTsKKyAgc3RhdGljIHN0cmluZyBHZXRPdXRwdXRGaWxlQ29udGVudChjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcnNlZF9maWxlX2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBmaXJzdF9tZXNzYWdlX25hbWUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfTU9DS19DT0RFX0dFTkVSQVRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFja2FnZV9pbmZvLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhY2thZ2VfaW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiNmI0NzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhY2thZ2VfaW5mby5oCkBAIC0wLDAgKzEsNjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgZXhpc3RzIHNvbGVseSB0byBkb2N1bWVudCB0aGUgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXIgbmFtZXNwYWNlLgorLy8gSXQgaXMgbm90IGNvbXBpbGVkIGludG8gYW55dGhpbmcsIGJ1dCBpdCBtYXkgYmUgcmVhZCBieSBhbiBhdXRvbWF0ZWQKKy8vIGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yLgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIFByb3RvY29sIEJ1ZmZlciBjb21waWxlci4KKy8vCisvLyBUaGlzIHBhY2thZ2UgY29udGFpbnMgY29kZSBmb3IgcGFyc2luZyAucHJvdG8gZmlsZXMgYW5kIGdlbmVyYXRpbmcgY29kZQorLy8gYmFzZWQgb24gdGhlbS4gIFRoZXJlIGFyZSB0d28gcmVhc29ucyB5b3UgbWlnaHQgYmUgaW50ZXJlc3RlZCBpbiB0aGlzCisvLyBwYWNrYWdlOgorLy8gLSBZb3Ugd2FudCB0byBwYXJzZSAucHJvdG8gZmlsZXMgYXQgcnVudGltZS4gIEluIHRoaXMgY2FzZSwgeW91IHNob3VsZAorLy8gICBsb29rIGF0IGltcG9ydGVyLmguICBTaW5jZSB0aGlzIGZ1bmN0aW9uYWxpdHkgaXMgd2lkZWx5IHVzZWZ1bCwgaXQgaXMKKy8vICAgaW5jbHVkZWQgaW4gdGhlIGxpYnByb3RvYnVmIGJhc2UgbGlicmFyeTsgeW91IGRvIG5vdCBoYXZlIHRvIGxpbmsgYWdhaW5zdAorLy8gICBsaWJwcm90b2MuCisvLyAtIFlvdSB3YW50IHRvIHdyaXRlIGEgY3VzdG9tIHByb3RvY29sIGNvbXBpbGVyIHdoaWNoIGdlbmVyYXRlcyBkaWZmZXJlbnQKKy8vICAga2luZHMgb2YgY29kZSwgZS5nLiBjb2RlIGluIGEgZGlmZmVyZW50IGxhbmd1YWdlIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQKKy8vICAgYnkgdGhlIG9mZmljaWFsIGNvbXBpbGVyLiAgRm9yIHRoaXMgcHVycG9zZSwgY29tbWFuZF9saW5lX2ludGVyZmFjZS5oCisvLyAgIHByb3ZpZGVzIHlvdSB3aXRoIGEgY29tcGxldGUgY29tcGlsZXIgZnJvbnQtZW5kLCBzbyBhbGwgeW91IG5lZWQgdG8gZG8KKy8vICAgaXMgd3JpdGUgYSBjdXN0b20gaW1wbGVtZW50YXRpb24gb2YgQ29kZUdlbmVyYXRvciBhbmQgYSB0cml2aWFsIG1haW4oKQorLy8gICBmdW5jdGlvbi4gIFlvdSBjYW4gZXZlbiBtYWtlIHlvdXIgY29tcGlsZXIgc3VwcG9ydCB0aGUgb2ZmaWNpYWwgbGFuZ3VhZ2VzCisvLyAgIGluIGFkZGl0aW9uIHRvIHlvdXIgb3duLiAgU2luY2UgdGhpcyBmdW5jdGlvbmFsaXR5IGlzIG9ubHkgdXNlZnVsIHRvIHRob3NlCisvLyAgIHdyaXRpbmcgY3VzdG9tIGNvbXBpbGVycywgaXQgaXMgaW4gYSBzZXBhcmF0ZSBsaWJyYXJ5IGNhbGxlZCAibGlicHJvdG9jIgorLy8gICB3aGljaCB5b3Ugd2lsbCBoYXZlIHRvIGxpbmsgYWdhaW5zdC4KK25hbWVzcGFjZSBjb21waWxlciB7fQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzUwY2RmNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmNjCkBAIC0wLDAgKzEsMTkwOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFJlY3Vyc2l2ZSBkZXNjZW50IEZUVy4KKworI2luY2x1ZGUgPGZsb2F0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxsaW1pdHM+CisKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKKworbmFtZXNwYWNlIHsKKwordHlwZWRlZiBoYXNoX21hcDxzdHJpbmcsIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlPiBUeXBlTmFtZU1hcDsKKworVHlwZU5hbWVNYXAgTWFrZVR5cGVOYW1lVGFibGUoKSB7CisgIFR5cGVOYW1lTWFwIHJlc3VsdDsKKworICByZXN1bHRbImRvdWJsZSIgIF0gPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9ET1VCTEU7CisgIHJlc3VsdFsiZmxvYXQiICAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZMT0FUOworICByZXN1bHRbInVpbnQ2NCIgIF0gPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UNjQ7CisgIHJlc3VsdFsiZml4ZWQ2NCIgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZJWEVENjQ7CisgIHJlc3VsdFsiZml4ZWQzMiIgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZJWEVEMzI7CisgIHJlc3VsdFsiYm9vbCIgICAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0JPT0w7CisgIHJlc3VsdFsic3RyaW5nIiAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NUUklORzsKKyAgcmVzdWx0WyJncm91cCIgICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfR1JPVVA7CisKKyAgcmVzdWx0WyJieXRlcyIgICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfQllURVM7CisgIHJlc3VsdFsidWludDMyIiAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1VJTlQzMjsKKyAgcmVzdWx0WyJzZml4ZWQzMiJdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0ZJWEVEMzI7CisgIHJlc3VsdFsic2ZpeGVkNjQiXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NGSVhFRDY0OworICByZXN1bHRbImludDMyIiAgIF0gPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMjsKKyAgcmVzdWx0WyJpbnQ2NCIgICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UNjQ7CisgIHJlc3VsdFsic2ludDMyIiAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NJTlQzMjsKKyAgcmVzdWx0WyJzaW50NjQiICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDY0OworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2NvbnN0IFR5cGVOYW1lTWFwIGtUeXBlTmFtZXMgPSBNYWtlVHlwZU5hbWVUYWJsZSgpOworCisvLyBDYW1lbC1jYXNlIHRoZSBmaWVsZCBuYW1lIGFuZCBhcHBlbmQgIkVudHJ5IiBmb3IgZ2VuZXJhdGVkIG1hcCBlbnRyeSBuYW1lLgorLy8gZS5nLiBtYXA8S2V5VHlwZSwgVmFsdWVUeXBlPiBmb29fbWFwID0+IEZvb01hcEVudHJ5CitzdHJpbmcgTWFwRW50cnlOYW1lKGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSkgeworICBzdHJpbmcgcmVzdWx0OworICBzdGF0aWMgY29uc3QgY2hhciBrU3VmZml4W10gPSAiRW50cnkiOworICByZXN1bHQucmVzZXJ2ZShmaWVsZF9uYW1lLnNpemUoKSArIHNpemVvZihrU3VmZml4KSk7CisgIGJvb2wgY2FwX25leHQgPSB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkX25hbWUuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoZmllbGRfbmFtZVtpXSA9PSAnXycpIHsKKyAgICAgIGNhcF9uZXh0ID0gdHJ1ZTsKKyAgICB9IGVsc2UgaWYgKGNhcF9uZXh0KSB7CisgICAgICAvLyBOb3RlOiBEbyBub3QgdXNlIGN0eXBlLmggZHVlIHRvIGxvY2FsZXMuCisgICAgICBpZiAoJ2EnIDw9IGZpZWxkX25hbWVbaV0gJiYgZmllbGRfbmFtZVtpXSA8PSAneicpIHsKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhmaWVsZF9uYW1lW2ldIC0gJ2EnICsgJ0EnKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soZmllbGRfbmFtZVtpXSk7CisgICAgICB9CisgICAgICBjYXBfbmV4dCA9IGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQucHVzaF9iYWNrKGZpZWxkX25hbWVbaV0pOworICAgIH0KKyAgfQorICByZXN1bHQuYXBwZW5kKGtTdWZmaXgpOworICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKKy8vIE1ha2VzIGNvZGUgc2xpZ2h0bHkgbW9yZSByZWFkYWJsZS4gIFRoZSBtZWFuaW5nIG9mICJETyhmb28pIiBpcworLy8gIkV4ZWN1dGUgZm9vIGFuZCBmYWlsIGlmIGl0IGZhaWxzLiIsIHdoZXJlIGZhaWx1cmUgaXMgaW5kaWNhdGVkIGJ5CisvLyByZXR1cm5pbmcgZmFsc2UuCisjZGVmaW5lIERPKFNUQVRFTUVOVCkgaWYgKFNUQVRFTUVOVCkge30gZWxzZSByZXR1cm4gZmFsc2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitQYXJzZXI6OlBhcnNlcigpCisgIDogaW5wdXRfKE5VTEwpLAorICAgIGVycm9yX2NvbGxlY3Rvcl8oTlVMTCksCisgICAgc291cmNlX2xvY2F0aW9uX3RhYmxlXyhOVUxMKSwKKyAgICBoYWRfZXJyb3JzXyhmYWxzZSksCisgICAgcmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl8oZmFsc2UpLAorICAgIHN0b3BfYWZ0ZXJfc3ludGF4X2lkZW50aWZpZXJfKGZhbHNlKSB7Cit9CisKK1BhcnNlcjo6flBhcnNlcigpIHsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitpbmxpbmUgYm9vbCBQYXJzZXI6Okxvb2tpbmdBdChjb25zdCBjaGFyKiB0ZXh0KSB7CisgIHJldHVybiBpbnB1dF8tPmN1cnJlbnQoKS50ZXh0ID09IHRleHQ7Cit9CisKK2lubGluZSBib29sIFBhcnNlcjo6TG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUb2tlblR5cGUgdG9rZW5fdHlwZSkgeworICByZXR1cm4gaW5wdXRfLT5jdXJyZW50KCkudHlwZSA9PSB0b2tlbl90eXBlOworfQorCitpbmxpbmUgYm9vbCBQYXJzZXI6OkF0RW5kKCkgeworICByZXR1cm4gTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCk7Cit9CisKK2Jvb2wgUGFyc2VyOjpUcnlDb25zdW1lKGNvbnN0IGNoYXIqIHRleHQpIHsKKyAgaWYgKExvb2tpbmdBdCh0ZXh0KSkgeworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitib29sIFBhcnNlcjo6Q29uc3VtZShjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoVHJ5Q29uc3VtZSh0ZXh0KSkgeworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIEFkZEVycm9yKGVycm9yKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBQYXJzZXI6OkNvbnN1bWUoY29uc3QgY2hhciogdGV4dCkgeworICBpZiAoVHJ5Q29uc3VtZSh0ZXh0KSkgeworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIEFkZEVycm9yKCJFeHBlY3RlZCBcIiIgKyBzdHJpbmcodGV4dCkgKyAiXCIuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lSWRlbnRpZmllcihzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSKSkgeworICAgICpvdXRwdXQgPSBpbnB1dF8tPmN1cnJlbnQoKS50ZXh0OworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIEFkZEVycm9yKGVycm9yKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBQYXJzZXI6OkNvbnN1bWVJbnRlZ2VyKGludCogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgdWludDY0IHZhbHVlID0gMDsKKyAgICBpZiAoIWlvOjpUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcihpbnB1dF8tPmN1cnJlbnQoKS50ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbnQzMm1heCwgJnZhbHVlKSkgeworICAgICAgQWRkRXJyb3IoIkludGVnZXIgb3V0IG9mIHJhbmdlLiIpOworICAgICAgLy8gV2Ugc3RpbGwgcmV0dXJuIHRydWUgYmVjYXVzZSB3ZSBkaWQsIGluIGZhY3QsIHBhcnNlIGFuIGludGVnZXIuCisgICAgfQorICAgICpvdXRwdXQgPSB2YWx1ZTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lU2lnbmVkSW50ZWdlcihpbnQqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgYm9vbCBpc19uZWdhdGl2ZSA9IGZhbHNlOworICB1aW50NjQgbWF4X3ZhbHVlID0ga2ludDMybWF4OworICBpZiAoVHJ5Q29uc3VtZSgiLSIpKSB7CisgICAgaXNfbmVnYXRpdmUgPSB0cnVlOworICAgIG1heF92YWx1ZSArPSAxOworICB9CisgIHVpbnQ2NCB2YWx1ZSA9IDA7CisgIERPKENvbnN1bWVJbnRlZ2VyNjQobWF4X3ZhbHVlLCAmdmFsdWUsIGVycm9yKSk7CisgIGlmIChpc19uZWdhdGl2ZSkgdmFsdWUgKj0gLTE7CisgICpvdXRwdXQgPSB2YWx1ZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lSW50ZWdlcjY0KHVpbnQ2NCBtYXhfdmFsdWUsIHVpbnQ2NCogb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgIGlmICghaW86OlRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKGlucHV0Xy0+Y3VycmVudCgpLnRleHQsIG1heF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQpKSB7CisgICAgICBBZGRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICAvLyBXZSBzdGlsbCByZXR1cm4gdHJ1ZSBiZWNhdXNlIHdlIGRpZCwgaW4gZmFjdCwgcGFyc2UgYW4gaW50ZWdlci4KKyAgICAgICpvdXRwdXQgPSAwOworICAgIH0KKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lTnVtYmVyKGRvdWJsZSogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0ZMT0FUKSkgeworICAgICpvdXRwdXQgPSBpbzo6VG9rZW5pemVyOjpQYXJzZUZsb2F0KGlucHV0Xy0+Y3VycmVudCgpLnRleHQpOworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgIC8vIEFsc28gYWNjZXB0IGludGVnZXJzLgorICAgIHVpbnQ2NCB2YWx1ZSA9IDA7CisgICAgaWYgKCFpbzo6VG9rZW5pemVyOjpQYXJzZUludGVnZXIoaW5wdXRfLT5jdXJyZW50KCkudGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrdWludDY0bWF4LCAmdmFsdWUpKSB7CisgICAgICBBZGRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICAvLyBXZSBzdGlsbCByZXR1cm4gdHJ1ZSBiZWNhdXNlIHdlIGRpZCwgaW4gZmFjdCwgcGFyc2UgYSBudW1iZXIuCisgICAgfQorICAgICpvdXRwdXQgPSB2YWx1ZTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImluZiIpKSB7CisgICAgKm91dHB1dCA9IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgaW5wdXRfLT5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJuYW4iKSkgeworICAgICpvdXRwdXQgPSBudW1lcmljX2xpbWl0czxkb3VibGU+OjpxdWlldF9OYU4oKTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lU3RyaW5nKHN0cmluZyogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NUUklORykpIHsKKyAgICBpbzo6VG9rZW5pemVyOjpQYXJzZVN0cmluZyhpbnB1dF8tPmN1cnJlbnQoKS50ZXh0LCBvdXRwdXQpOworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIC8vIEFsbG93IEMrKyBsaWtlIGNvbmNhdGVuYXRpb24gb2YgYWRqYWNlbnQgc3RyaW5nIHRva2Vucy4KKyAgICB3aGlsZSAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NUUklORykpIHsKKyAgICAgIGlvOjpUb2tlbml6ZXI6OlBhcnNlU3RyaW5nQXBwZW5kKGlucHV0Xy0+Y3VycmVudCgpLnRleHQsIG91dHB1dCk7CisgICAgICBpbnB1dF8tPk5leHQoKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgQWRkRXJyb3IoZXJyb3IpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitib29sIFBhcnNlcjo6VHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oCisgICAgY29uc3QgY2hhciogdGV4dCwgY29uc3QgTG9jYXRpb25SZWNvcmRlciogbG9jYXRpb24pIHsKKyAgaWYgKExvb2tpbmdBdCh0ZXh0KSkgeworICAgIHN0cmluZyBsZWFkaW5nLCB0cmFpbGluZzsKKyAgICB2ZWN0b3I8c3RyaW5nPiBkZXRhY2hlZDsKKyAgICBpbnB1dF8tPk5leHRXaXRoQ29tbWVudHMoJnRyYWlsaW5nLCAmZGV0YWNoZWQsICZsZWFkaW5nKTsKKworICAgIC8vIFNhdmUgdGhlIGxlYWRpbmcgY29tbWVudHMgZm9yIG5leHQgdGltZSwgYW5kIHJlY2FsbCB0aGUgbGVhZGluZyBjb21tZW50cworICAgIC8vIGZyb20gbGFzdCB0aW1lLgorICAgIGxlYWRpbmcuc3dhcCh1cGNvbWluZ19kb2NfY29tbWVudHNfKTsKKworICAgIGlmIChsb2NhdGlvbiAhPSBOVUxMKSB7CisgICAgICB1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c18uc3dhcChkZXRhY2hlZCk7CisgICAgICBsb2NhdGlvbi0+QXR0YWNoQ29tbWVudHMoJmxlYWRpbmcsICZ0cmFpbGluZywgJmRldGFjaGVkKTsKKyAgICB9IGVsc2UgaWYgKHN0cmNtcCh0ZXh0LCAifSIpID09IDApIHsKKyAgICAgIC8vIElmIHRoZSBjdXJyZW50IGxvY2F0aW9uIGlzIG51bGwgYW5kIHdlIGFyZSBmaW5pc2hpbmcgdGhlIGN1cnJlbnQgc2NvcGUsCisgICAgICAvLyBkcm9wIHBlbmRpbmcgdXBjb21pbmcgZGV0YWNoZWQgY29tbWVudHMuCisgICAgICB1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c18uc3dhcChkZXRhY2hlZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE90aGVyd2lzZSwgYXBwZW5kIHRoZSBuZXcgZGV0YWNoZWQgY29tbWVudHMgdG8gdGhlIGV4aXN0aW5nIHVwY29taW5nCisgICAgICAvLyBkZXRhY2hlZCBjb21tZW50cy4KKyAgICAgIHVwY29taW5nX2RldGFjaGVkX2NvbW1lbnRzXy5pbnNlcnQodXBjb21pbmdfZGV0YWNoZWRfY29tbWVudHNfLmVuZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRhY2hlZC5iZWdpbigpLCBkZXRhY2hlZC5lbmQoKSk7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigKKyAgICBjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBMb2NhdGlvblJlY29yZGVyKiBsb2NhdGlvbikgeworICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24odGV4dCwgbG9jYXRpb24pKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgQWRkRXJyb3IoIkV4cGVjdGVkIFwiIiArIHN0cmluZyh0ZXh0KSArICJcIi4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFBhcnNlcjo6QWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgZXJyb3IpIHsKKyAgaWYgKGVycm9yX2NvbGxlY3Rvcl8gIT0gTlVMTCkgeworICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGxpbmUsIGNvbHVtbiwgZXJyb3IpOworICB9CisgIGhhZF9lcnJvcnNfID0gdHJ1ZTsKK30KKwordm9pZCBQYXJzZXI6OkFkZEVycm9yKGNvbnN0IHN0cmluZyYgZXJyb3IpIHsKKyAgQWRkRXJyb3IoaW5wdXRfLT5jdXJyZW50KCkubGluZSwgaW5wdXRfLT5jdXJyZW50KCkuY29sdW1uLCBlcnJvcik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpMb2NhdGlvblJlY29yZGVyKFBhcnNlciogcGFyc2VyKQorICA6IHBhcnNlcl8ocGFyc2VyKSwKKyAgICBsb2NhdGlvbl8ocGFyc2VyXy0+c291cmNlX2NvZGVfaW5mb18tPmFkZF9sb2NhdGlvbigpKSB7CisgIGxvY2F0aW9uXy0+YWRkX3NwYW4ocGFyc2VyXy0+aW5wdXRfLT5jdXJyZW50KCkubGluZSk7CisgIGxvY2F0aW9uXy0+YWRkX3NwYW4ocGFyc2VyXy0+aW5wdXRfLT5jdXJyZW50KCkuY29sdW1uKTsKK30KKworUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpMb2NhdGlvblJlY29yZGVyKGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCkgeworICBJbml0KHBhcmVudCk7Cit9CisKK1BhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6TG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBhdGgxKSB7CisgIEluaXQocGFyZW50KTsKKyAgQWRkUGF0aChwYXRoMSk7Cit9CisKK1BhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6TG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBhdGgxLCBpbnQgcGF0aDIpIHsKKyAgSW5pdChwYXJlbnQpOworICBBZGRQYXRoKHBhdGgxKTsKKyAgQWRkUGF0aChwYXRoMik7Cit9CisKK3ZvaWQgUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpJbml0KGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCkgeworICBwYXJzZXJfID0gcGFyZW50LnBhcnNlcl87CisgIGxvY2F0aW9uXyA9IHBhcnNlcl8tPnNvdXJjZV9jb2RlX2luZm9fLT5hZGRfbG9jYXRpb24oKTsKKyAgbG9jYXRpb25fLT5tdXRhYmxlX3BhdGgoKS0+Q29weUZyb20ocGFyZW50LmxvY2F0aW9uXy0+cGF0aCgpKTsKKworICBsb2NhdGlvbl8tPmFkZF9zcGFuKHBhcnNlcl8tPmlucHV0Xy0+Y3VycmVudCgpLmxpbmUpOworICBsb2NhdGlvbl8tPmFkZF9zcGFuKHBhcnNlcl8tPmlucHV0Xy0+Y3VycmVudCgpLmNvbHVtbik7Cit9CisKK1BhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6fkxvY2F0aW9uUmVjb3JkZXIoKSB7CisgIGlmIChsb2NhdGlvbl8tPnNwYW5fc2l6ZSgpIDw9IDIpIHsKKyAgICBFbmRBdChwYXJzZXJfLT5pbnB1dF8tPnByZXZpb3VzKCkpOworICB9Cit9CisKK3ZvaWQgUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpBZGRQYXRoKGludCBwYXRoX2NvbXBvbmVudCkgeworICBsb2NhdGlvbl8tPmFkZF9wYXRoKHBhdGhfY29tcG9uZW50KTsKK30KKwordm9pZCBQYXJzZXI6OkxvY2F0aW9uUmVjb3JkZXI6OlN0YXJ0QXQoY29uc3QgaW86OlRva2VuaXplcjo6VG9rZW4mIHRva2VuKSB7CisgIGxvY2F0aW9uXy0+c2V0X3NwYW4oMCwgdG9rZW4ubGluZSk7CisgIGxvY2F0aW9uXy0+c2V0X3NwYW4oMSwgdG9rZW4uY29sdW1uKTsKK30KKwordm9pZCBQYXJzZXI6OkxvY2F0aW9uUmVjb3JkZXI6OlN0YXJ0QXQoY29uc3QgTG9jYXRpb25SZWNvcmRlciYgb3RoZXIpIHsKKyAgbG9jYXRpb25fLT5zZXRfc3BhbigwLCBvdGhlci5sb2NhdGlvbl8tPnNwYW4oMCkpOworICBsb2NhdGlvbl8tPnNldF9zcGFuKDEsIG90aGVyLmxvY2F0aW9uXy0+c3BhbigxKSk7Cit9CisKK3ZvaWQgUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpFbmRBdChjb25zdCBpbzo6VG9rZW5pemVyOjpUb2tlbiYgdG9rZW4pIHsKKyAgaWYgKHRva2VuLmxpbmUgIT0gbG9jYXRpb25fLT5zcGFuKDApKSB7CisgICAgbG9jYXRpb25fLT5hZGRfc3Bhbih0b2tlbi5saW5lKTsKKyAgfQorICBsb2NhdGlvbl8tPmFkZF9zcGFuKHRva2VuLmVuZF9jb2x1bW4pOworfQorCit2b2lkIFBhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6UmVjb3JkTGVnYWN5TG9jYXRpb24oY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24pIHsKKyAgaWYgKHBhcnNlcl8tPnNvdXJjZV9sb2NhdGlvbl90YWJsZV8gIT0gTlVMTCkgeworICAgIHBhcnNlcl8tPnNvdXJjZV9sb2NhdGlvbl90YWJsZV8tPkFkZCgKKyAgICAgICAgZGVzY3JpcHRvciwgbG9jYXRpb24sIGxvY2F0aW9uXy0+c3BhbigwKSwgbG9jYXRpb25fLT5zcGFuKDEpKTsKKyAgfQorfQorCit2b2lkIFBhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6QXR0YWNoQ29tbWVudHMoCisgICAgc3RyaW5nKiBsZWFkaW5nLCBzdHJpbmcqIHRyYWlsaW5nLAorICAgIHZlY3RvcjxzdHJpbmc+KiBkZXRhY2hlZF9jb21tZW50cykgY29uc3QgeworICBHT09HTEVfQ0hFQ0soIWxvY2F0aW9uXy0+aGFzX2xlYWRpbmdfY29tbWVudHMoKSk7CisgIEdPT0dMRV9DSEVDSyghbG9jYXRpb25fLT5oYXNfdHJhaWxpbmdfY29tbWVudHMoKSk7CisKKyAgaWYgKCFsZWFkaW5nLT5lbXB0eSgpKSB7CisgICAgbG9jYXRpb25fLT5tdXRhYmxlX2xlYWRpbmdfY29tbWVudHMoKS0+c3dhcCgqbGVhZGluZyk7CisgIH0KKyAgaWYgKCF0cmFpbGluZy0+ZW1wdHkoKSkgeworICAgIGxvY2F0aW9uXy0+bXV0YWJsZV90cmFpbGluZ19jb21tZW50cygpLT5zd2FwKCp0cmFpbGluZyk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXRhY2hlZF9jb21tZW50cy0+c2l6ZSgpOyArK2kpIHsKKyAgICBsb2NhdGlvbl8tPmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCktPnN3YXAoCisgICAgICAgICgqZGV0YWNoZWRfY29tbWVudHMpW2ldKTsKKyAgfQorICBkZXRhY2hlZF9jb21tZW50cy0+Y2xlYXIoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFBhcnNlcjo6U2tpcFN0YXRlbWVudCgpIHsKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NZTUJPTCkpIHsKKyAgICAgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsIE5VTEwpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgieyIpKSB7CisgICAgICAgIFNraXBSZXN0T2ZCbG9jaygpOworICAgICAgICByZXR1cm47CisgICAgICB9IGVsc2UgaWYgKExvb2tpbmdBdCgifSIpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9CisgICAgaW5wdXRfLT5OZXh0KCk7CisgIH0KK30KKwordm9pZCBQYXJzZXI6OlNraXBSZXN0T2ZCbG9jaygpIHsKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NZTUJPTCkpIHsKKyAgICAgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigifSIsIE5VTEwpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgieyIpKSB7CisgICAgICAgIFNraXBSZXN0T2ZCbG9jaygpOworICAgICAgfQorICAgIH0KKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2Jvb2wgUGFyc2VyOjpQYXJzZShpbzo6VG9rZW5pemVyKiBpbnB1dCwgRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSkgeworICBpbnB1dF8gPSBpbnB1dDsKKyAgaGFkX2Vycm9yc18gPSBmYWxzZTsKKyAgc3ludGF4X2lkZW50aWZpZXJfLmNsZWFyKCk7CisKKyAgLy8gTm90ZSB0aGF0IHxmaWxlfCBjb3VsZCBiZSBOVUxMIGF0IHRoaXMgcG9pbnQgaWYKKyAgLy8gc3RvcF9hZnRlcl9zeW50YXhfaWRlbnRpZmllcl8gaXMgdHJ1ZS4gIFNvLCB3ZSBjb25zZXJ2YXRpdmVseSBhbGxvY2F0ZQorICAvLyBTb3VyY2VDb2RlSW5mbyBvbiB0aGUgc3RhY2ssIHRoZW4gc3dhcCBpdCBpbnRvIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvCisgIC8vIGxhdGVyIG9uLgorICBTb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvOworICBzb3VyY2VfY29kZV9pbmZvXyA9ICZzb3VyY2VfY29kZV9pbmZvOworCisgIHZlY3RvcjxzdHJpbmc+IHRvcF9kb2NfY29tbWVudHM7CisgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RBUlQpKSB7CisgICAgLy8gQWR2YW5jZSB0byBmaXJzdCB0b2tlbi4KKyAgICBpbnB1dF8tPk5leHRXaXRoQ29tbWVudHMoTlVMTCwgJnVwY29taW5nX2RldGFjaGVkX2NvbW1lbnRzXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVwY29taW5nX2RvY19jb21tZW50c18pOworICB9CisKKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgcm9vdF9sb2NhdGlvbih0aGlzKTsKKworICAgIGlmIChyZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXyB8fCBMb29raW5nQXQoInN5bnRheCIpKSB7CisgICAgICBpZiAoIVBhcnNlU3ludGF4SWRlbnRpZmllcihyb290X2xvY2F0aW9uKSkgeworICAgICAgICAvLyBEb24ndCBhdHRlbXB0IHRvIHBhcnNlIHRoZSBmaWxlIGlmIHdlIGRpZG4ndCByZWNvZ25pemUgdGhlIHN5bnRheAorICAgICAgICAvLyBpZGVudGlmaWVyLgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBTdG9yZSB0aGUgc3ludGF4IGludG8gdGhlIGZpbGUuCisgICAgICBpZiAoZmlsZSAhPSBOVUxMKSBmaWxlLT5zZXRfc3ludGF4KHN5bnRheF9pZGVudGlmaWVyXyk7CisgICAgfSBlbHNlIGlmICghc3RvcF9hZnRlcl9zeW50YXhfaWRlbnRpZmllcl8pIHsKKyAgICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIk5vIHN5bnRheCBzcGVjaWZpZWQgZm9yIHRoZSBwcm90byBmaWxlLiAiCisgICAgICAgICAgICAgICAgICAgPDwgIlBsZWFzZSB1c2UgJ3N5bnRheCA9IFwicHJvdG8yXCI7JyBvciAiCisgICAgICAgICAgICAgICAgICAgPDwgIidzeW50YXggPSBcInByb3RvM1wiOycgdG8gc3BlY2lmeSBhIHN5bnRheCAiCisgICAgICAgICAgICAgICAgICAgPDwgInZlcnNpb24uIChEZWZhdWx0ZWQgdG8gcHJvdG8yIHN5bnRheC4pIjsKKyAgICAgIHN5bnRheF9pZGVudGlmaWVyXyA9ICJwcm90bzIiOworICAgIH0KKworICAgIGlmIChzdG9wX2FmdGVyX3N5bnRheF9pZGVudGlmaWVyXykgcmV0dXJuICFoYWRfZXJyb3JzXzsKKworICAgIC8vIFJlcGVhdGVkbHkgcGFyc2Ugc3RhdGVtZW50cyB1bnRpbCB3ZSByZWFjaCB0aGUgZW5kIG9mIHRoZSBmaWxlLgorICAgIHdoaWxlICghQXRFbmQoKSkgeworICAgICAgaWYgKCFQYXJzZVRvcExldmVsU3RhdGVtZW50KGZpbGUsIHJvb3RfbG9jYXRpb24pKSB7CisgICAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgICAgLy8gb3RoZXIgc3RhdGVtZW50cy4KKyAgICAgICAgU2tpcFN0YXRlbWVudCgpOworCisgICAgICAgIGlmIChMb29raW5nQXQoIn0iKSkgeworICAgICAgICAgIEFkZEVycm9yKCJVbm1hdGNoZWQgXCJ9XCIuIik7CisgICAgICAgICAgaW5wdXRfLT5OZXh0V2l0aENvbW1lbnRzKE5VTEwsICZ1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c18sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1cGNvbWluZ19kb2NfY29tbWVudHNfKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIGlucHV0XyA9IE5VTEw7CisgIHNvdXJjZV9jb2RlX2luZm9fID0gTlVMTDsKKyAgc291cmNlX2NvZGVfaW5mby5Td2FwKGZpbGUtPm11dGFibGVfc291cmNlX2NvZGVfaW5mbygpKTsKKyAgcmV0dXJuICFoYWRfZXJyb3JzXzsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlU3ludGF4SWRlbnRpZmllcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQpIHsKKyAgTG9jYXRpb25SZWNvcmRlciBzeW50YXhfbG9jYXRpb24ocGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvOjprU3ludGF4RmllbGROdW1iZXIpOworICBETyhDb25zdW1lKAorICAgICAgInN5bnRheCIsCisgICAgICAiRmlsZSBtdXN0IGJlZ2luIHdpdGggYSBzeW50YXggc3RhdGVtZW50LCBlLmcuICdzeW50YXggPSBcInByb3RvMlwiOycuIikpOworICBETyhDb25zdW1lKCI9IikpOworICBpbzo6VG9rZW5pemVyOjpUb2tlbiBzeW50YXhfdG9rZW4gPSBpbnB1dF8tPmN1cnJlbnQoKTsKKyAgc3RyaW5nIHN5bnRheDsKKyAgRE8oQ29uc3VtZVN0cmluZygmc3ludGF4LCAiRXhwZWN0ZWQgc3ludGF4IGlkZW50aWZpZXIuIikpOworICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZzeW50YXhfbG9jYXRpb24pKTsKKworICBzeW50YXhfaWRlbnRpZmllcl8gPSBzeW50YXg7CisKKyAgaWYgKHN5bnRheCAhPSAicHJvdG8yIiAmJiBzeW50YXggIT0gInByb3RvMyIgJiYKKyAgICAgICFzdG9wX2FmdGVyX3N5bnRheF9pZGVudGlmaWVyXykgeworICAgIEFkZEVycm9yKHN5bnRheF90b2tlbi5saW5lLCBzeW50YXhfdG9rZW4uY29sdW1uLAorICAgICAgIlVucmVjb2duaXplZCBzeW50YXggaWRlbnRpZmllciBcIiIgKyBzeW50YXggKyAiXCIuICBUaGlzIHBhcnNlciAiCisgICAgICAib25seSByZWNvZ25pemVzIFwicHJvdG8yXCIgYW5kIFwicHJvdG8zXCIuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZVRvcExldmVsU3RhdGVtZW50KEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiByb290X2xvY2F0aW9uKSB7CisgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsIE5VTEwpKSB7CisgICAgLy8gZW1wdHkgc3RhdGVtZW50OyBpZ25vcmUKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIm1lc3NhZ2UiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtNZXNzYWdlVHlwZUZpZWxkTnVtYmVyLCBmaWxlLT5tZXNzYWdlX3R5cGVfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VNZXNzYWdlRGVmaW5pdGlvbihmaWxlLT5hZGRfbWVzc2FnZV90eXBlKCksIGxvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImVudW0iKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtFbnVtVHlwZUZpZWxkTnVtYmVyLCBmaWxlLT5lbnVtX3R5cGVfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VFbnVtRGVmaW5pdGlvbihmaWxlLT5hZGRfZW51bV90eXBlKCksIGxvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoInNlcnZpY2UiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtTZXJ2aWNlRmllbGROdW1iZXIsIGZpbGUtPnNlcnZpY2Vfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VTZXJ2aWNlRGVmaW5pdGlvbihmaWxlLT5hZGRfc2VydmljZSgpLCBsb2NhdGlvbiwgZmlsZSk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJleHRlbmQiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvbkZpZWxkTnVtYmVyKTsKKyAgICByZXR1cm4gUGFyc2VFeHRlbmQoZmlsZS0+bXV0YWJsZV9leHRlbnNpb24oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgZmlsZS0+bXV0YWJsZV9tZXNzYWdlX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgcm9vdF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6a01lc3NhZ2VUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImltcG9ydCIpKSB7CisgICAgcmV0dXJuIFBhcnNlSW1wb3J0KGZpbGUtPm11dGFibGVfZGVwZW5kZW5jeSgpLAorICAgICAgICAgICAgICAgICAgICAgICBmaWxlLT5tdXRhYmxlX3B1YmxpY19kZXBlbmRlbmN5KCksCisgICAgICAgICAgICAgICAgICAgICAgIGZpbGUtPm11dGFibGVfd2Vha19kZXBlbmRlbmN5KCksCisgICAgICAgICAgICAgICAgICAgICAgIHJvb3RfbG9jYXRpb24sIGZpbGUpOworICB9IGVsc2UgaWYgKExvb2tpbmdBdCgicGFja2FnZSIpKSB7CisgICAgcmV0dXJuIFBhcnNlUGFja2FnZShmaWxlLCByb290X2xvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIm9wdGlvbiIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihyb290X2xvY2F0aW9uLAorICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyKTsKKyAgICByZXR1cm4gUGFyc2VPcHRpb24oZmlsZS0+bXV0YWJsZV9vcHRpb25zKCksIGxvY2F0aW9uLCBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICBPUFRJT05fU1RBVEVNRU5UKTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcigiRXhwZWN0ZWQgdG9wLWxldmVsIHN0YXRlbWVudCAoZS5nLiBcIm1lc3NhZ2VcIikuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1lc3NhZ2VzCisKK2Jvb2wgUGFyc2VyOjpQYXJzZU1lc3NhZ2VEZWZpbml0aW9uKAorICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZSwKKyAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBtZXNzYWdlX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJtZXNzYWdlIikpOworICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgbWVzc2FnZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihtZXNzYWdlLT5tdXRhYmxlX25hbWUoKSwgIkV4cGVjdGVkIG1lc3NhZ2UgbmFtZS4iKSk7CisgIH0KKyAgRE8oUGFyc2VNZXNzYWdlQmxvY2sobWVzc2FnZSwgbWVzc2FnZV9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisgIHJldHVybiB0cnVlOworfQorCituYW1lc3BhY2UgeworCitjb25zdCBpbnQga01heEV4dGVuc2lvblJhbmdlU2VudGluZWwgPSAtMTsKKworYm9vbCBJc01lc3NhZ2VTZXRXaXJlRm9ybWF0TWVzc2FnZShjb25zdCBEZXNjcmlwdG9yUHJvdG8mIG1lc3NhZ2UpIHsKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMgPSBtZXNzYWdlLm9wdGlvbnMoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgKytpKSB7CisgICAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZCA9IG9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24oaSk7CisgICAgaWYgKHVuaW50ZXJwcmV0ZWQubmFtZV9zaXplKCkgPT0gMSAmJgorICAgICAgICB1bmludGVycHJldGVkLm5hbWUoMCkubmFtZV9wYXJ0KCkgPT0gIm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0IiAmJgorICAgICAgICB1bmludGVycHJldGVkLmlkZW50aWZpZXJfdmFsdWUoKSA9PSAidHJ1ZSIpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIE1vZGlmaWVzIGFueSBleHRlbnNpb24gcmFuZ2VzIHRoYXQgc3BlY2lmaWVkICdtYXgnIGFzIHRoZSBlbmQgb2YgdGhlCisvLyBleHRlbnNpb24gcmFuZ2UsIGFuZCBzZXRzIHRoZW0gdG8gdGhlIHR5cGUtc3BlY2lmaWMgbWF4aW11bS4gVGhlIGFjdHVhbCBtYXgKKy8vIHRhZyBudW1iZXIgY2FuIG9ubHkgYmUgZGV0ZXJtaW5lZCBhZnRlciBhbGwgb3B0aW9ucyBoYXZlIGJlZW4gcGFyc2VkLgordm9pZCBBZGp1c3RFeHRlbnNpb25SYW5nZXNXaXRoTWF4RW5kTnVtYmVyKERlc2NyaXB0b3JQcm90byogbWVzc2FnZSkgeworICBjb25zdCBib29sIGlzX21lc3NhZ2Vfc2V0ID0gSXNNZXNzYWdlU2V0V2lyZUZvcm1hdE1lc3NhZ2UoKm1lc3NhZ2UpOworICBjb25zdCBpbnQgbWF4X2V4dGVuc2lvbl9udW1iZXIgPSBpc19tZXNzYWdlX3NldCA/CisgICAgICBraW50MzJtYXggOgorICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyICsgMTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2Vfc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAobWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlKGkpLmVuZCgpID09IGtNYXhFeHRlbnNpb25SYW5nZVNlbnRpbmVsKSB7CisgICAgICBtZXNzYWdlLT5tdXRhYmxlX2V4dGVuc2lvbl9yYW5nZShpKS0+c2V0X2VuZChtYXhfZXh0ZW5zaW9uX251bWJlcik7CisgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIFBhcnNlcjo6UGFyc2VNZXNzYWdlQmxvY2soRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJm1lc3NhZ2VfbG9jYXRpb24pKTsKKworICB3aGlsZSAoIVRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ9IiwgTlVMTCkpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgQWRkRXJyb3IoIlJlYWNoZWQgZW5kIG9mIGlucHV0IGluIG1lc3NhZ2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghUGFyc2VNZXNzYWdlU3RhdGVtZW50KG1lc3NhZ2UsIG1lc3NhZ2VfbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSkpIHsKKyAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgIC8vIG90aGVyIHN0YXRlbWVudHMuCisgICAgICBTa2lwU3RhdGVtZW50KCk7CisgICAgfQorICB9CisKKyAgaWYgKG1lc3NhZ2UtPmV4dGVuc2lvbl9yYW5nZV9zaXplKCkgPiAwKSB7CisgICAgQWRqdXN0RXh0ZW5zaW9uUmFuZ2VzV2l0aE1heEVuZE51bWJlcihtZXNzYWdlKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlTWVzc2FnZVN0YXRlbWVudChEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCBOVUxMKSkgeworICAgIC8vIGVtcHR5IHN0YXRlbWVudDsgaWdub3JlCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJtZXNzYWdlIikpIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9zaXplKCkpOworICAgIHJldHVybiBQYXJzZU1lc3NhZ2VEZWZpbml0aW9uKG1lc3NhZ2UtPmFkZF9uZXN0ZWRfdHlwZSgpLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpOworICB9IGVsc2UgaWYgKExvb2tpbmdBdCgiZW51bSIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprRW51bVR5cGVGaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UtPmVudW1fdHlwZV9zaXplKCkpOworICAgIHJldHVybiBQYXJzZUVudW1EZWZpbml0aW9uKG1lc3NhZ2UtPmFkZF9lbnVtX3R5cGUoKSwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImV4dGVuc2lvbnMiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvblJhbmdlRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZUV4dGVuc2lvbnMobWVzc2FnZSwgbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJleHRlbmQiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvbkZpZWxkTnVtYmVyKTsKKyAgICByZXR1cm4gUGFyc2VFeHRlbmQobWVzc2FnZS0+bXV0YWJsZV9leHRlbnNpb24oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpOworICB9IGVsc2UgaWYgKExvb2tpbmdBdCgib3B0aW9uIikpIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZU9wdGlvbihtZXNzYWdlLT5tdXRhYmxlX29wdGlvbnMoKSwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSwgT1BUSU9OX1NUQVRFTUVOVCk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJvbmVvZiIpKSB7CisgICAgaW50IG9uZW9mX2luZGV4ID0gbWVzc2FnZS0+b25lb2ZfZGVjbF9zaXplKCk7CisgICAgTG9jYXRpb25SZWNvcmRlciBvbmVvZl9sb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprT25lb2ZEZWNsRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVvZl9pbmRleCk7CisKKyAgICByZXR1cm4gUGFyc2VPbmVvZihtZXNzYWdlLT5hZGRfb25lb2ZfZGVjbCgpLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgIG9uZW9mX2luZGV4LCBvbmVvZl9sb2NhdGlvbiwgbWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpOworICB9IGVsc2UgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0ZpZWxkRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLT5maWVsZF9zaXplKCkpOworICAgIHJldHVybiBQYXJzZU1lc3NhZ2VGaWVsZChtZXNzYWdlLT5hZGRfZmllbGQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZU1lc3NhZ2VGaWVsZChGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OmtMYWJlbEZpZWxkTnVtYmVyKTsKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWwgbGFiZWw7CisgICAgaWYgKFBhcnNlTGFiZWwoJmxhYmVsLCBjb250YWluaW5nX2ZpbGUpKSB7CisgICAgICBmaWVsZC0+c2V0X2xhYmVsKGxhYmVsKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gUGFyc2VNZXNzYWdlRmllbGROb0xhYmVsKGZpZWxkLCBtZXNzYWdlcywgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlTWVzc2FnZUZpZWxkTm9MYWJlbCgKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcywKKyAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24sCisgICAgaW50IGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIE1hcEZpZWxkIG1hcF9maWVsZDsKKyAgLy8gUGFyc2UgdHlwZS4KKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZmllbGRfbG9jYXRpb24pOyAgLy8gYWRkIHBhdGggbGF0ZXIKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbihmaWVsZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFKTsKKworICAgIGJvb2wgdHlwZV9wYXJzZWQgPSBmYWxzZTsKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZSB0eXBlID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzI7CisgICAgc3RyaW5nIHR5cGVfbmFtZTsKKworICAgIC8vIFNwZWNpYWwgY2FzZSBtYXAgZmllbGQuIFdlIG9ubHkgdHJlYXQgdGhlIGZpZWxkIGFzIGEgbWFwIGZpZWxkIGlmIHRoZQorICAgIC8vIGZpZWxkIHR5cGUgbmFtZSBzdGFydHMgd2l0aCB0aGUgd29yZCAibWFwIiB3aXRoIGEgZm9sbG93aW5nICI8Ii4KKyAgICBpZiAoVHJ5Q29uc3VtZSgibWFwIikpIHsKKyAgICAgIGlmIChMb29raW5nQXQoIjwiKSkgeworICAgICAgICBtYXBfZmllbGQuaXNfbWFwX2ZpZWxkID0gdHJ1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIEZhbHNlIHBvc2l0aXZlCisgICAgICAgIHR5cGVfcGFyc2VkID0gdHJ1ZTsKKyAgICAgICAgdHlwZV9uYW1lID0gIm1hcCI7CisgICAgICB9CisgICAgfQorICAgIGlmIChtYXBfZmllbGQuaXNfbWFwX2ZpZWxkKSB7CisgICAgICBpZiAoZmllbGQtPmhhc19vbmVvZl9pbmRleCgpKSB7CisgICAgICAgIEFkZEVycm9yKCJNYXAgZmllbGRzIGFyZSBub3QgYWxsb3dlZCBpbiBvbmVvZnMuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmIChmaWVsZC0+aGFzX2xhYmVsKCkpIHsKKyAgICAgICAgQWRkRXJyb3IoCisgICAgICAgICAgICAiRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uICIKKyAgICAgICAgICAgICJtYXAgZmllbGRzLiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBpZiAoZmllbGQtPmhhc19leHRlbmRlZSgpKSB7CisgICAgICAgIEFkZEVycm9yKCJNYXAgZmllbGRzIGFyZSBub3QgYWxsb3dlZCB0byBiZSBleHRlbnNpb25zLiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBmaWVsZC0+c2V0X2xhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVBFQVRFRCk7CisgICAgICBETyhDb25zdW1lKCI8IikpOworICAgICAgRE8oUGFyc2VUeXBlKCZtYXBfZmllbGQua2V5X3R5cGUsICZtYXBfZmllbGQua2V5X3R5cGVfbmFtZSkpOworICAgICAgRE8oQ29uc3VtZSgiLCIpKTsKKyAgICAgIERPKFBhcnNlVHlwZSgmbWFwX2ZpZWxkLnZhbHVlX3R5cGUsICZtYXBfZmllbGQudmFsdWVfdHlwZV9uYW1lKSk7CisgICAgICBETyhDb25zdW1lKCI+IikpOworICAgICAgLy8gRGVmZXIgc2V0dGluZyBvZiB0aGUgdHlwZSBuYW1lIG9mIHRoZSBtYXAgZmllbGQgdW50aWwgdGhlCisgICAgICAvLyBmaWVsZCBuYW1lIGlzIHBhcnNlZC4gQWRkIHRoZSBzb3VyY2UgbG9jYXRpb24gdGhvdWdoLgorICAgICAgbG9jYXRpb24uQWRkUGF0aChGaWVsZERlc2NyaXB0b3JQcm90bzo6a1R5cGVOYW1lRmllbGROdW1iZXIpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgbm8gZXhwbGljaXQgbGFiZWwgaXMgZ2l2ZW4gZm9yIGEgbm9uLW1hcCBmaWVsZC4KKyAgICAgIGlmICghZmllbGQtPmhhc19sYWJlbCgpICYmIERlZmF1bHRUb09wdGlvbmFsRmllbGRzKCkpIHsKKyAgICAgICAgZmllbGQtPnNldF9sYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwpOworICAgICAgfQorICAgICAgaWYgKCFmaWVsZC0+aGFzX2xhYmVsKCkpIHsKKyAgICAgICAgQWRkRXJyb3IoIkV4cGVjdGVkIFwicmVxdWlyZWRcIiwgXCJvcHRpb25hbFwiLCBvciBcInJlcGVhdGVkXCIuIik7CisgICAgICAgIC8vIFdlIGNhbiBhY3R1YWxseSByZWFzb25hYmx5IHJlY292ZXIgaGVyZSBieSBqdXN0IGFzc3VtaW5nIHRoZSB1c2VyCisgICAgICAgIC8vIGZvcmdvdCB0aGUgbGFiZWwgYWx0b2dldGhlci4KKyAgICAgICAgZmllbGQtPnNldF9sYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwpOworICAgICAgfQorCisgICAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgdGhlIGFjdHVhbCB0eXBlIGlzIGEgbWVzc2FnZSBvciBlbnVtIG5hbWVkICJtYXAiLAorICAgICAgLy8gd2hpY2ggd2UgYWxyZWFkeSBjb25zdW1lZCBpbiB0aGUgY29kZSBhYm92ZS4KKyAgICAgIGlmICghdHlwZV9wYXJzZWQpIHsKKyAgICAgICAgRE8oUGFyc2VUeXBlKCZ0eXBlLCAmdHlwZV9uYW1lKSk7CisgICAgICB9CisgICAgICBpZiAodHlwZV9uYW1lLmVtcHR5KCkpIHsKKyAgICAgICAgbG9jYXRpb24uQWRkUGF0aChGaWVsZERlc2NyaXB0b3JQcm90bzo6a1R5cGVGaWVsZE51bWJlcik7CisgICAgICAgIGZpZWxkLT5zZXRfdHlwZSh0eXBlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGxvY2F0aW9uLkFkZFBhdGgoRmllbGREZXNjcmlwdG9yUHJvdG86OmtUeXBlTmFtZUZpZWxkTnVtYmVyKTsKKyAgICAgICAgZmllbGQtPnNldF90eXBlX25hbWUodHlwZV9uYW1lKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBQYXJzZSBuYW1lIGFuZCAnPScuCisgIGlvOjpUb2tlbml6ZXI6OlRva2VuIG5hbWVfdG9rZW4gPSBpbnB1dF8tPmN1cnJlbnQoKTsKKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcik7CisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oZmllbGQsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSk7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoZmllbGQtPm11dGFibGVfbmFtZSgpLCAiRXhwZWN0ZWQgZmllbGQgbmFtZS4iKSk7CisgIH0KKyAgRE8oQ29uc3VtZSgiPSIsICJNaXNzaW5nIGZpZWxkIG51bWJlci4iKSk7CisKKyAgLy8gUGFyc2UgZmllbGQgbnVtYmVyLgorICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjprTnVtYmVyRmllbGROdW1iZXIpOworICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICBmaWVsZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIpOworICAgIGludCBudW1iZXI7CisgICAgRE8oQ29uc3VtZUludGVnZXIoJm51bWJlciwgIkV4cGVjdGVkIGZpZWxkIG51bWJlci4iKSk7CisgICAgZmllbGQtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgfQorCisgIC8vIFBhcnNlIG9wdGlvbnMuCisgIERPKFBhcnNlRmllbGRPcHRpb25zKGZpZWxkLCBmaWVsZF9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisKKyAgLy8gRGVhbCB3aXRoIGdyb3Vwcy4KKyAgaWYgKGZpZWxkLT5oYXNfdHlwZSgpICYmIGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfR1JPVVApIHsKKyAgICAvLyBBd2t3YXJkOiAgU2luY2UgYSBncm91cCBkZWNsYXJlcyBib3RoIGEgbWVzc2FnZSB0eXBlIGFuZCBhIGZpZWxkLCB3ZQorICAgIC8vICAgaGF2ZSB0byBjcmVhdGUgb3ZlcmxhcHBpbmcgbG9jYXRpb25zLgorICAgIExvY2F0aW9uUmVjb3JkZXIgZ3JvdXBfbG9jYXRpb24ocGFyZW50X2xvY2F0aW9uKTsKKyAgICBncm91cF9sb2NhdGlvbi5TdGFydEF0KGZpZWxkX2xvY2F0aW9uKTsKKyAgICBncm91cF9sb2NhdGlvbi5BZGRQYXRoKGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUpOworICAgIGdyb3VwX2xvY2F0aW9uLkFkZFBhdGgobWVzc2FnZXMtPnNpemUoKSk7CisKKyAgICBEZXNjcmlwdG9yUHJvdG8qIGdyb3VwID0gbWVzc2FnZXMtPkFkZCgpOworICAgIGdyb3VwLT5zZXRfbmFtZShmaWVsZC0+bmFtZSgpKTsKKworICAgIC8vIFJlY29yZCBuYW1lIGxvY2F0aW9uIHRvIG1hdGNoIHRoZSBmaWVsZCBuYW1lJ3MgbG9jYXRpb24uCisgICAgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihncm91cF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICAgIGxvY2F0aW9uLlN0YXJ0QXQobmFtZV90b2tlbik7CisgICAgICBsb2NhdGlvbi5FbmRBdChuYW1lX3Rva2VuKTsKKyAgICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICAgIGdyb3VwLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUpOworICAgIH0KKworICAgIC8vIFRoZSBmaWVsZCdzIHR5cGVfbmFtZSBhbHNvIGNvbWVzIGZyb20gdGhlIG5hbWUuICBDb25mdXNpbmchCisgICAgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OmtUeXBlTmFtZUZpZWxkTnVtYmVyKTsKKyAgICAgIGxvY2F0aW9uLlN0YXJ0QXQobmFtZV90b2tlbik7CisgICAgICBsb2NhdGlvbi5FbmRBdChuYW1lX3Rva2VuKTsKKyAgICB9CisKKyAgICAvLyBBcyBhIGhhY2sgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LCB3ZSBmb3JjZSB0aGUgZ3JvdXAgbmFtZSB0byBzdGFydAorICAgIC8vIHdpdGggYSBjYXBpdGFsIGxldHRlciBhbmQgbG93ZXItY2FzZSB0aGUgZmllbGQgbmFtZS4gIE5ldyBjb2RlIHNob3VsZAorICAgIC8vIG5vdCB1c2UgZ3JvdXBzOyBpdCBzaG91bGQgdXNlIG5lc3RlZCBtZXNzYWdlcy4KKyAgICBpZiAoZ3JvdXAtPm5hbWUoKVswXSA8ICdBJyB8fCAnWicgPCBncm91cC0+bmFtZSgpWzBdKSB7CisgICAgICBBZGRFcnJvcihuYW1lX3Rva2VuLmxpbmUsIG5hbWVfdG9rZW4uY29sdW1uLAorICAgICAgICAiR3JvdXAgbmFtZXMgbXVzdCBzdGFydCB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuIik7CisgICAgfQorICAgIExvd2VyU3RyaW5nKGZpZWxkLT5tdXRhYmxlX25hbWUoKSk7CisKKyAgICBmaWVsZC0+c2V0X3R5cGVfbmFtZShncm91cC0+bmFtZSgpKTsKKyAgICBpZiAoTG9va2luZ0F0KCJ7IikpIHsKKyAgICAgIERPKFBhcnNlTWVzc2FnZUJsb2NrKGdyb3VwLCBncm91cF9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEFkZEVycm9yKCJNaXNzaW5nIGdyb3VwIGJvZHkuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9IGVsc2UgeworICAgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgJmZpZWxkX2xvY2F0aW9uKSk7CisgIH0KKworICAvLyBDcmVhdGUgYSBtYXAgZW50cnkgdHlwZSBpZiB0aGlzIGlzIGEgbWFwIGZpZWxkLgorICBpZiAobWFwX2ZpZWxkLmlzX21hcF9maWVsZCkgeworICAgIEdlbmVyYXRlTWFwRW50cnkobWFwX2ZpZWxkLCBmaWVsZCwgbWVzc2FnZXMpOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgUGFyc2VyOjpHZW5lcmF0ZU1hcEVudHJ5KGNvbnN0IE1hcEZpZWxkJiBtYXBfZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZFB0ckZpZWxkPERlc2NyaXB0b3JQcm90bz4qIG1lc3NhZ2VzKSB7CisgIERlc2NyaXB0b3JQcm90byogZW50cnkgPSBtZXNzYWdlcy0+QWRkKCk7CisgIHN0cmluZyBlbnRyeV9uYW1lID0gTWFwRW50cnlOYW1lKGZpZWxkLT5uYW1lKCkpOworICBmaWVsZC0+c2V0X3R5cGVfbmFtZShlbnRyeV9uYW1lKTsKKyAgZW50cnktPnNldF9uYW1lKGVudHJ5X25hbWUpOworICBlbnRyeS0+bXV0YWJsZV9vcHRpb25zKCktPnNldF9tYXBfZW50cnkodHJ1ZSk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBrZXlfZmllbGQgPSBlbnRyeS0+YWRkX2ZpZWxkKCk7CisgIGtleV9maWVsZC0+c2V0X25hbWUoImtleSIpOworICBrZXlfZmllbGQtPnNldF9sYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwpOworICBrZXlfZmllbGQtPnNldF9udW1iZXIoMSk7CisgIGlmIChtYXBfZmllbGQua2V5X3R5cGVfbmFtZS5lbXB0eSgpKSB7CisgICAga2V5X2ZpZWxkLT5zZXRfdHlwZShtYXBfZmllbGQua2V5X3R5cGUpOworICB9IGVsc2UgeworICAgIGtleV9maWVsZC0+c2V0X3R5cGVfbmFtZShtYXBfZmllbGQua2V5X3R5cGVfbmFtZSk7CisgIH0KKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIHZhbHVlX2ZpZWxkID0gZW50cnktPmFkZF9maWVsZCgpOworICB2YWx1ZV9maWVsZC0+c2V0X25hbWUoInZhbHVlIik7CisgIHZhbHVlX2ZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAgdmFsdWVfZmllbGQtPnNldF9udW1iZXIoMik7CisgIGlmIChtYXBfZmllbGQudmFsdWVfdHlwZV9uYW1lLmVtcHR5KCkpIHsKKyAgICB2YWx1ZV9maWVsZC0+c2V0X3R5cGUobWFwX2ZpZWxkLnZhbHVlX3R5cGUpOworICB9IGVsc2UgeworICAgIHZhbHVlX2ZpZWxkLT5zZXRfdHlwZV9uYW1lKG1hcF9maWVsZC52YWx1ZV90eXBlX25hbWUpOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUZpZWxkT3B0aW9ucyhGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIGlmICghTG9va2luZ0F0KCJbIikpIHJldHVybiB0cnVlOworCisgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXIpOworCisgIERPKENvbnN1bWUoIlsiKSk7CisKKyAgLy8gUGFyc2UgZmllbGQgb3B0aW9ucy4KKyAgZG8geworICAgIGlmIChMb29raW5nQXQoImRlZmF1bHQiKSkgeworICAgICAgLy8gV2UgaW50ZW50aW9uYWxseSBwYXNzIGZpZWxkX2xvY2F0aW9uIHJhdGhlciB0aGFuIGxvY2F0aW9uIGhlcmUsIHNpbmNlCisgICAgICAvLyB0aGUgZGVmYXVsdCB2YWx1ZSBpcyBub3QgYWN0dWFsbHkgYW4gb3B0aW9uLgorICAgICAgRE8oUGFyc2VEZWZhdWx0QXNzaWdubWVudChmaWVsZCwgZmllbGRfbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSkpOworICAgIH0gZWxzZSB7CisgICAgICBETyhQYXJzZU9wdGlvbihmaWVsZC0+bXV0YWJsZV9vcHRpb25zKCksIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlLCBPUFRJT05fQVNTSUdOTUVOVCkpOworICAgIH0KKyAgfSB3aGlsZSAoVHJ5Q29uc3VtZSgiLCIpKTsKKworICBETyhDb25zdW1lKCJdIikpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlRGVmYXVsdEFzc2lnbm1lbnQoCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICBBZGRFcnJvcigiQWxyZWFkeSBzZXQgb3B0aW9uIFwiZGVmYXVsdFwiLiIpOworICAgIGZpZWxkLT5jbGVhcl9kZWZhdWx0X3ZhbHVlKCk7CisgIH0KKworICBETyhDb25zdW1lKCJkZWZhdWx0IikpOworICBETyhDb25zdW1lKCI9IikpOworCisgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OmtEZWZhdWx0VmFsdWVGaWVsZE51bWJlcik7CisgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgZmllbGQsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6REVGQVVMVF9WQUxVRSk7CisgIHN0cmluZyogZGVmYXVsdF92YWx1ZSA9IGZpZWxkLT5tdXRhYmxlX2RlZmF1bHRfdmFsdWUoKTsKKworICBpZiAoIWZpZWxkLT5oYXNfdHlwZSgpKSB7CisgICAgLy8gVGhlIGZpZWxkIGhhcyBhIHR5cGUgbmFtZSwgYnV0IHdlIGRvbid0IGtub3cgaWYgaXQgaXMgYSBtZXNzYWdlIG9yIGFuCisgICAgLy8gZW51bSB5ZXQuIChJZiBpdCB3ZXJlIGEgcHJpbWl0aXZlIHR5cGUsIHxmaWVsZHwgd291bGQgaGF2ZSBhIHR5cGUgc2V0CisgICAgLy8gYWxyZWFkeS4pIEluIHRoaXMgY2FzZSwgc2ltcGx5IHRha2UgdGhlIGN1cnJlbnQgc3RyaW5nIGFzIHRoZSBkZWZhdWx0CisgICAgLy8gdmFsdWU7IHdlIHdpbGwgY2F0Y2ggdGhlIGVycm9yIGxhdGVyIGlmIGl0IGlzIG5vdCBhIHZhbGlkIGVudW0gdmFsdWUuCisgICAgLy8gKE4uQi4gdGhhdCB3ZSBkbyBub3QgY2hlY2sgd2hldGhlciB0aGUgY3VycmVudCB0b2tlbiBpcyBhbiBpZGVudGlmaWVyOgorICAgIC8vIGRvaW5nIHNvIHRocm93cyBzdHJhbmdlIGVycm9ycyB3aGVuIHRoZSB1c2VyIG1pc3R5cGVzIGEgcHJpbWl0aXZlCisgICAgLy8gdHlwZW5hbWUgYW5kIHdlIGFzc3VtZSBpdCdzIGFuIGVudW0uIEUuZy46ICJvcHRpb25hbCBpbnQgZm9vID0gMSBbZGVmYXVsdAorICAgIC8vID0gNDJdIi4gSW4gc3VjaCBhIGNhc2UgdGhlIGZ1bmRhbWVudGFsIGVycm9yIGlzIHJlYWxseSB0aGF0ICJpbnQiIGlzIG5vdAorICAgIC8vIGEgdHlwZSwgbm90IHRoYXQgIjQyIiBpcyBub3QgYW4gaWRlbnRpZmllci4gU2VlIGIvMTI1MzM1ODIuKQorICAgICpkZWZhdWx0X3ZhbHVlID0gaW5wdXRfLT5jdXJyZW50KCkudGV4dDsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHN3aXRjaCAoZmllbGQtPnR5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NJTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NGSVhFRDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0ZJWEVENjQ6IHsKKyAgICAgIHVpbnQ2NCBtYXhfdmFsdWUgPSBraW50NjRtYXg7CisgICAgICBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMiB8fAorICAgICAgICAgIGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDMyIHx8CisgICAgICAgICAgZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TRklYRUQzMikgeworICAgICAgICBtYXhfdmFsdWUgPSBraW50MzJtYXg7CisgICAgICB9CisKKyAgICAgIC8vIFRoZXNlIHR5cGVzIGNhbiBiZSBuZWdhdGl2ZS4KKyAgICAgIGlmIChUcnlDb25zdW1lKCItIikpIHsKKyAgICAgICAgZGVmYXVsdF92YWx1ZS0+YXBwZW5kKCItIik7CisgICAgICAgIC8vIFR3bydzIGNvbXBsZW1lbnQgYWx3YXlzIGhhcyBvbmUgbW9yZSBuZWdhdGl2ZSB2YWx1ZSB0aGFuIHBvc2l0aXZlLgorICAgICAgICArK21heF92YWx1ZTsKKyAgICAgIH0KKyAgICAgIC8vIFBhcnNlIHRoZSBpbnRlZ2VyIHRvIHZlcmlmeSB0aGF0IGl0IGlzIG5vdCBvdXQtb2YtcmFuZ2UuCisgICAgICB1aW50NjQgdmFsdWU7CisgICAgICBETyhDb25zdW1lSW50ZWdlcjY0KG1heF92YWx1ZSwgJnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgaW50ZWdlciBmb3IgZmllbGQgZGVmYXVsdCB2YWx1ZS4iKSk7CisgICAgICAvLyBBbmQgc3RyaW5naWZ5IGl0IGFnYWluLgorICAgICAgZGVmYXVsdF92YWx1ZS0+YXBwZW5kKFNpbXBsZUl0b2EodmFsdWUpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfVUlOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZJWEVENjQ6IHsKKyAgICAgIHVpbnQ2NCBtYXhfdmFsdWUgPSBrdWludDY0bWF4OworICAgICAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfVUlOVDMyIHx8CisgICAgICAgICAgZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GSVhFRDMyKSB7CisgICAgICAgIG1heF92YWx1ZSA9IGt1aW50MzJtYXg7CisgICAgICB9CisKKyAgICAgIC8vIE51bWVyaWMsIG5vdCBuZWdhdGl2ZS4KKyAgICAgIGlmIChUcnlDb25zdW1lKCItIikpIHsKKyAgICAgICAgQWRkRXJyb3IoIlVuc2lnbmVkIGZpZWxkIGNhbid0IGhhdmUgbmVnYXRpdmUgZGVmYXVsdCB2YWx1ZS4iKTsKKyAgICAgIH0KKyAgICAgIC8vIFBhcnNlIHRoZSBpbnRlZ2VyIHRvIHZlcmlmeSB0aGF0IGl0IGlzIG5vdCBvdXQtb2YtcmFuZ2UuCisgICAgICB1aW50NjQgdmFsdWU7CisgICAgICBETyhDb25zdW1lSW50ZWdlcjY0KG1heF92YWx1ZSwgJnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgaW50ZWdlciBmb3IgZmllbGQgZGVmYXVsdCB2YWx1ZS4iKSk7CisgICAgICAvLyBBbmQgc3RyaW5naWZ5IGl0IGFnYWluLgorICAgICAgZGVmYXVsdF92YWx1ZS0+YXBwZW5kKFNpbXBsZUl0b2EodmFsdWUpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRkxPQVQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9ET1VCTEU6CisgICAgICAvLyBUaGVzZSB0eXBlcyBjYW4gYmUgbmVnYXRpdmUuCisgICAgICBpZiAoVHJ5Q29uc3VtZSgiLSIpKSB7CisgICAgICAgIGRlZmF1bHRfdmFsdWUtPmFwcGVuZCgiLSIpOworICAgICAgfQorICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgYmVjYXVzZSB3ZSBoYXZlIHRvIGNvbnZlcnQgaGV4IGludGVnZXJzIHRvIGRlY2ltYWwKKyAgICAgIC8vIGZsb2F0cy4KKyAgICAgIGRvdWJsZSB2YWx1ZTsKKyAgICAgIERPKENvbnN1bWVOdW1iZXIoJnZhbHVlLCAiRXhwZWN0ZWQgbnVtYmVyLiIpKTsKKyAgICAgIC8vIEFuZCBzdHJpbmdpZnkgaXQgYWdhaW4uCisgICAgICBkZWZhdWx0X3ZhbHVlLT5hcHBlbmQoU2ltcGxlRHRvYSh2YWx1ZSkpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0JPT0w6CisgICAgICBpZiAoVHJ5Q29uc3VtZSgidHJ1ZSIpKSB7CisgICAgICAgIGRlZmF1bHRfdmFsdWUtPmFzc2lnbigidHJ1ZSIpOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCJmYWxzZSIpKSB7CisgICAgICAgIGRlZmF1bHRfdmFsdWUtPmFzc2lnbigiZmFsc2UiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEFkZEVycm9yKCJFeHBlY3RlZCBcInRydWVcIiBvciBcImZhbHNlXCIuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TVFJJTkc6CisgICAgICAvLyBOb3RlOiBXaGVuIGZpbGUgb3B0b24gamF2YV9zdHJpbmdfY2hlY2tfdXRmOCBpcyB0cnVlLCBpZiBhCisgICAgICAvLyBub24tc3RyaW5nIHJlcHJlc2VudGF0aW9uIChlZyBieXRlW10pIGlzIGxhdGVyIHN1cHBvcnRlZCwgaXQgbXVzdAorICAgICAgLy8gYmUgY2hlY2tlZCBmb3IgVVRGLTgtbmVzcy4KKyAgICAgIERPKENvbnN1bWVTdHJpbmcoZGVmYXVsdF92YWx1ZSwgIkV4cGVjdGVkIHN0cmluZyBmb3IgZmllbGQgZGVmYXVsdCAiCisgICAgICAgICAgICAgICAgICAgICAgICJ2YWx1ZS4iKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfQllURVM6CisgICAgICBETyhDb25zdW1lU3RyaW5nKGRlZmF1bHRfdmFsdWUsICJFeHBlY3RlZCBzdHJpbmcuIikpOworICAgICAgKmRlZmF1bHRfdmFsdWUgPSBDRXNjYXBlKCpkZWZhdWx0X3ZhbHVlKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9FTlVNOgorICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoZGVmYXVsdF92YWx1ZSwgIkV4cGVjdGVkIGVudW0gaWRlbnRpZmllciBmb3IgZmllbGQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlZmF1bHQgdmFsdWUuIikpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX01FU1NBR0U6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9HUk9VUDoKKyAgICAgIEFkZEVycm9yKCJNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZU9wdGlvbk5hbWVQYXJ0KFVuaW50ZXJwcmV0ZWRPcHRpb24qIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFydF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBVbmludGVycHJldGVkT3B0aW9uOjpOYW1lUGFydCogbmFtZSA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5hZGRfbmFtZSgpOworICBzdHJpbmcgaWRlbnRpZmllcjsgIC8vIFdlIHBhcnNlIGlkZW50aWZpZXJzIGludG8gdGhpcyBzdHJpbmcuCisgIGlmIChMb29raW5nQXQoIigiKSkgeyAgLy8gVGhpcyBpcyBhbiBleHRlbnNpb24uCisgICAgRE8oQ29uc3VtZSgiKCIpKTsKKworICAgIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgICAgcGFydF9sb2NhdGlvbiwgVW5pbnRlcnByZXRlZE9wdGlvbjo6TmFtZVBhcnQ6OmtOYW1lUGFydEZpZWxkTnVtYmVyKTsKKyAgICAgIC8vIEFuIGV4dGVuc2lvbiBuYW1lIGNvbnNpc3RzIG9mIGRvdC1zZXBhcmF0ZWQgaWRlbnRpZmllcnMsIGFuZCBtYXkgYmVnaW4KKyAgICAgIC8vIHdpdGggYSBkb3QuCisgICAgICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICAgIERPKENvbnN1bWVJZGVudGlmaWVyKCZpZGVudGlmaWVyLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iKSk7CisgICAgICAgIG5hbWUtPm11dGFibGVfbmFtZV9wYXJ0KCktPmFwcGVuZChpZGVudGlmaWVyKTsKKyAgICAgIH0KKyAgICAgIHdoaWxlIChMb29raW5nQXQoIi4iKSkgeworICAgICAgICBETyhDb25zdW1lKCIuIikpOworICAgICAgICBuYW1lLT5tdXRhYmxlX25hbWVfcGFydCgpLT5hcHBlbmQoIi4iKTsKKyAgICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmlkZW50aWZpZXIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIpKTsKKyAgICAgICAgbmFtZS0+bXV0YWJsZV9uYW1lX3BhcnQoKS0+YXBwZW5kKGlkZW50aWZpZXIpOworICAgICAgfQorICAgIH0KKworICAgIERPKENvbnN1bWUoIikiKSk7CisgICAgbmFtZS0+c2V0X2lzX2V4dGVuc2lvbih0cnVlKTsKKyAgfSBlbHNlIHsgIC8vIFRoaXMgaXMgYSByZWd1bGFyIGZpZWxkLgorICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgIHBhcnRfbG9jYXRpb24sIFVuaW50ZXJwcmV0ZWRPcHRpb246Ok5hbWVQYXJ0OjprTmFtZVBhcnRGaWVsZE51bWJlcik7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmlkZW50aWZpZXIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIpKTsKKyAgICBuYW1lLT5tdXRhYmxlX25hbWVfcGFydCgpLT5hcHBlbmQoaWRlbnRpZmllcik7CisgICAgbmFtZS0+c2V0X2lzX2V4dGVuc2lvbihmYWxzZSk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZVVuaW50ZXJwcmV0ZWRCbG9jayhzdHJpbmcqIHZhbHVlKSB7CisgIC8vIE5vdGUgdGhhdCBlbmNsb3NpbmcgYnJhY2VzIGFyZSBub3QgYWRkZWQgdG8gKnZhbHVlLgorICAvLyBXZSBkbyBOT1QgdXNlIENvbnN1bWVFbmRPZlN0YXRlbWVudCBmb3IgdGhpcyBicmFjZSBiZWNhdXNlIGl0J3MgZGVsaW1pdGluZworICAvLyBhbiBleHByZXNzaW9uLCBub3QgYSBibG9jayBvZiBzdGF0ZW1lbnRzLgorICBETyhDb25zdW1lKCJ7IikpOworICBpbnQgYnJhY2VfZGVwdGggPSAxOworICB3aGlsZSAoIUF0RW5kKCkpIHsKKyAgICBpZiAoTG9va2luZ0F0KCJ7IikpIHsKKyAgICAgIGJyYWNlX2RlcHRoKys7CisgICAgfSBlbHNlIGlmIChMb29raW5nQXQoIn0iKSkgeworICAgICAgYnJhY2VfZGVwdGgtLTsKKyAgICAgIGlmIChicmFjZV9kZXB0aCA9PSAwKSB7CisgICAgICAgIGlucHV0Xy0+TmV4dCgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gVE9ETyhzYW5qYXkpOiBJbnRlcnByZXQgbGluZS9jb2x1bW4gbnVtYmVycyB0byBwcmVzZXJ2ZSBmb3JtYXR0aW5nCisgICAgaWYgKCF2YWx1ZS0+ZW1wdHkoKSkgdmFsdWUtPnB1c2hfYmFjaygnICcpOworICAgIHZhbHVlLT5hcHBlbmQoaW5wdXRfLT5jdXJyZW50KCkudGV4dCk7CisgICAgaW5wdXRfLT5OZXh0KCk7CisgIH0KKyAgQWRkRXJyb3IoIlVuZXhwZWN0ZWQgZW5kIG9mIHN0cmVhbSB3aGlsZSBwYXJzaW5nIGFnZ3JlZ2F0ZSB2YWx1ZS4iKTsKKyAgcmV0dXJuIGZhbHNlOworfQorCisvLyBXZSBkb24ndCBpbnRlcnByZXQgdGhlIG9wdGlvbiBoZXJlLiBJbnN0ZWFkIHdlIHN0b3JlIGl0IGluIGFuCisvLyBVbmludGVycHJldGVkT3B0aW9uLCB0byBiZSBpbnRlcnByZXRlZCBsYXRlci4KK2Jvb2wgUGFyc2VyOjpQYXJzZU9wdGlvbihNZXNzYWdlKiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG9wdGlvbnNfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvblN0eWxlIHN0eWxlKSB7CisgIC8vIENyZWF0ZSBhbiBlbnRyeSBpbiB0aGUgdW5pbnRlcnByZXRlZF9vcHRpb24gZmllbGQuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdW5pbnRlcnByZXRlZF9vcHRpb25fZmllbGQgPSBvcHRpb25zLT5HZXREZXNjcmlwdG9yKCktPgorICAgICAgRmluZEZpZWxkQnlOYW1lKCJ1bmludGVycHJldGVkX29wdGlvbiIpOworICBHT09HTEVfQ0hFQ0sodW5pbnRlcnByZXRlZF9vcHRpb25fZmllbGQgIT0gTlVMTCkKKyAgICAgIDw8ICJObyBmaWVsZCBuYW1lZCBcInVuaW50ZXJwcmV0ZWRfb3B0aW9uXCIgaW4gdGhlIE9wdGlvbnMgcHJvdG8uIjsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gb3B0aW9ucy0+R2V0UmVmbGVjdGlvbigpOworCisgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICBvcHRpb25zX2xvY2F0aW9uLCB1bmludGVycHJldGVkX29wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm9wdGlvbnMsIHVuaW50ZXJwcmV0ZWRfb3B0aW9uX2ZpZWxkKSk7CisKKyAgaWYgKHN0eWxlID09IE9QVElPTl9TVEFURU1FTlQpIHsKKyAgICBETyhDb25zdW1lKCJvcHRpb24iKSk7CisgIH0KKworICBVbmludGVycHJldGVkT3B0aW9uKiB1bmludGVycHJldGVkX29wdGlvbiA9IGRvd25fY2FzdDxVbmludGVycHJldGVkT3B0aW9uKj4oCisgICAgICBvcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPkFkZE1lc3NhZ2Uob3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbl9maWVsZCkpOworCisgIC8vIFBhcnNlIGRvdC1zZXBhcmF0ZWQgbmFtZS4KKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbmFtZV9sb2NhdGlvbihsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbjo6a05hbWVGaWVsZE51bWJlcik7CisgICAgbmFtZV9sb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1BUSU9OX05BTUUpOworCisgICAgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBwYXJ0X2xvY2F0aW9uKG5hbWVfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24tPm5hbWVfc2l6ZSgpKTsKKyAgICAgIERPKFBhcnNlT3B0aW9uTmFtZVBhcnQodW5pbnRlcnByZXRlZF9vcHRpb24sIHBhcnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSkpOworICAgIH0KKworICAgIHdoaWxlIChMb29raW5nQXQoIi4iKSkgeworICAgICAgRE8oQ29uc3VtZSgiLiIpKTsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgcGFydF9sb2NhdGlvbihuYW1lX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5uYW1lX3NpemUoKSk7CisgICAgICBETyhQYXJzZU9wdGlvbk5hbWVQYXJ0KHVuaW50ZXJwcmV0ZWRfb3B0aW9uLCBwYXJ0X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpKTsKKyAgICB9CisgIH0KKworICBETyhDb25zdW1lKCI9IikpOworCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIHZhbHVlX2xvY2F0aW9uKGxvY2F0aW9uKTsKKyAgICB2YWx1ZV9sb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1BUSU9OX1ZBTFVFKTsKKworICAgIC8vIEFsbCB2YWx1ZXMgYXJlIGEgc2luZ2xlIHRva2VuLCBleGNlcHQgZm9yIG5lZ2F0aXZlIG51bWJlcnMsIHdoaWNoIGNvbnNpc3QKKyAgICAvLyBvZiBhIHNpbmdsZSAnLScgc3ltYm9sLCBmb2xsb3dlZCBieSBhIHBvc2l0aXZlIG51bWJlci4KKyAgICBib29sIGlzX25lZ2F0aXZlID0gVHJ5Q29uc3VtZSgiLSIpOworCisgICAgc3dpdGNoIChpbnB1dF8tPmN1cnJlbnQoKS50eXBlKSB7CisgICAgICBjYXNlIGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RBUlQ6CisgICAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJUcnlpbmcgdG8gcmVhZCB2YWx1ZSBiZWZvcmUgYW55IHRva2VucyBoYXZlIGJlZW4gcmVhZC4iOworICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGNhc2UgaW86OlRva2VuaXplcjo6VFlQRV9FTkQ6CisgICAgICAgIEFkZEVycm9yKCJVbmV4cGVjdGVkIGVuZCBvZiBzdHJlYW0gd2hpbGUgcGFyc2luZyBvcHRpb24gdmFsdWUuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgY2FzZSBpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVI6IHsKKyAgICAgICAgdmFsdWVfbG9jYXRpb24uQWRkUGF0aCgKKyAgICAgICAgICAgIFVuaW50ZXJwcmV0ZWRPcHRpb246OmtJZGVudGlmaWVyVmFsdWVGaWVsZE51bWJlcik7CisgICAgICAgIGlmIChpc19uZWdhdGl2ZSkgeworICAgICAgICAgIEFkZEVycm9yKCJJbnZhbGlkICctJyBzeW1ib2wgYmVmb3JlIGlkZW50aWZpZXIuIik7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHN0cmluZyB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJnZhbHVlLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iKSk7CisgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5zZXRfaWRlbnRpZmllcl92YWx1ZSh2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIGlvOjpUb2tlbml6ZXI6OlRZUEVfSU5URUdFUjogeworICAgICAgICB1aW50NjQgdmFsdWU7CisgICAgICAgIHVpbnQ2NCBtYXhfdmFsdWUgPQorICAgICAgICAgICAgaXNfbmVnYXRpdmUgPyBzdGF0aWNfY2FzdDx1aW50NjQ+KGtpbnQ2NG1heCkgKyAxIDoga3VpbnQ2NG1heDsKKyAgICAgICAgRE8oQ29uc3VtZUludGVnZXI2NChtYXhfdmFsdWUsICZ2YWx1ZSwgIkV4cGVjdGVkIGludGVnZXIuIikpOworICAgICAgICBpZiAoaXNfbmVnYXRpdmUpIHsKKyAgICAgICAgICB2YWx1ZV9sb2NhdGlvbi5BZGRQYXRoKAorICAgICAgICAgICAgICBVbmludGVycHJldGVkT3B0aW9uOjprTmVnYXRpdmVJbnRWYWx1ZUZpZWxkTnVtYmVyKTsKKyAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbi0+c2V0X25lZ2F0aXZlX2ludF92YWx1ZSgKKyAgICAgICAgICAgICAgLXN0YXRpY19jYXN0PGludDY0Pih2YWx1ZSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHZhbHVlX2xvY2F0aW9uLkFkZFBhdGgoCisgICAgICAgICAgICAgIFVuaW50ZXJwcmV0ZWRPcHRpb246OmtQb3NpdGl2ZUludFZhbHVlRmllbGROdW1iZXIpOworICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5zZXRfcG9zaXRpdmVfaW50X3ZhbHVlKHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBpbzo6VG9rZW5pemVyOjpUWVBFX0ZMT0FUOiB7CisgICAgICAgIHZhbHVlX2xvY2F0aW9uLkFkZFBhdGgoVW5pbnRlcnByZXRlZE9wdGlvbjo6a0RvdWJsZVZhbHVlRmllbGROdW1iZXIpOworICAgICAgICBkb3VibGUgdmFsdWU7CisgICAgICAgIERPKENvbnN1bWVOdW1iZXIoJnZhbHVlLCAiRXhwZWN0ZWQgbnVtYmVyLiIpKTsKKyAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24tPnNldF9kb3VibGVfdmFsdWUoaXNfbmVnYXRpdmUgPyAtdmFsdWUgOiB2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HOiB7CisgICAgICAgIHZhbHVlX2xvY2F0aW9uLkFkZFBhdGgoVW5pbnRlcnByZXRlZE9wdGlvbjo6a1N0cmluZ1ZhbHVlRmllbGROdW1iZXIpOworICAgICAgICBpZiAoaXNfbmVnYXRpdmUpIHsKKyAgICAgICAgICBBZGRFcnJvcigiSW52YWxpZCAnLScgc3ltYm9sIGJlZm9yZSBzdHJpbmcuIik7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHN0cmluZyB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZVN0cmluZygmdmFsdWUsICJFeHBlY3RlZCBzdHJpbmcuIikpOworICAgICAgICB1bmludGVycHJldGVkX29wdGlvbi0+c2V0X3N0cmluZ192YWx1ZSh2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIGlvOjpUb2tlbml6ZXI6OlRZUEVfU1lNQk9MOgorICAgICAgICBpZiAoTG9va2luZ0F0KCJ7IikpIHsKKyAgICAgICAgICB2YWx1ZV9sb2NhdGlvbi5BZGRQYXRoKAorICAgICAgICAgICAgICBVbmludGVycHJldGVkT3B0aW9uOjprQWdncmVnYXRlVmFsdWVGaWVsZE51bWJlcik7CisgICAgICAgICAgRE8oUGFyc2VVbmludGVycHJldGVkQmxvY2soCisgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5tdXRhYmxlX2FnZ3JlZ2F0ZV92YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgQWRkRXJyb3IoIkV4cGVjdGVkIG9wdGlvbiB2YWx1ZS4iKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgaWYgKHN0eWxlID09IE9QVElPTl9TVEFURU1FTlQpIHsKKyAgICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZsb2NhdGlvbikpOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUV4dGVuc2lvbnMoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBleHRlbnNpb25zX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgLy8gUGFyc2UgdGhlIGRlY2xhcmF0aW9uLgorICBETyhDb25zdW1lKCJleHRlbnNpb25zIikpOworCisgIGRvIHsKKyAgICAvLyBOb3RlIHRoYXQga0V4dGVuc2lvblJhbmdlRmllbGROdW1iZXIgd2FzIGFscmVhZHkgcHVzaGVkIGJ5IHRoZSBwYXJlbnQuCisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihleHRlbnNpb25zX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlX3NpemUoKSk7CisKKyAgICBEZXNjcmlwdG9yUHJvdG86OkV4dGVuc2lvblJhbmdlKiByYW5nZSA9IG1lc3NhZ2UtPmFkZF9leHRlbnNpb25fcmFuZ2UoKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgcmFuZ2UsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSKTsKKworICAgIGludCBzdGFydCwgZW5kOworICAgIGlvOjpUb2tlbml6ZXI6OlRva2VuIHN0YXJ0X3Rva2VuOworCisgICAgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBzdGFydF9sb2NhdGlvbigKKyAgICAgICAgICBsb2NhdGlvbiwgRGVzY3JpcHRvclByb3RvOjpFeHRlbnNpb25SYW5nZTo6a1N0YXJ0RmllbGROdW1iZXIpOworICAgICAgc3RhcnRfdG9rZW4gPSBpbnB1dF8tPmN1cnJlbnQoKTsKKyAgICAgIERPKENvbnN1bWVJbnRlZ2VyKCZzdGFydCwgIkV4cGVjdGVkIGZpZWxkIG51bWJlciByYW5nZS4iKSk7CisgICAgfQorCisgICAgaWYgKFRyeUNvbnN1bWUoInRvIikpIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgZW5kX2xvY2F0aW9uKAorICAgICAgICAgIGxvY2F0aW9uLCBEZXNjcmlwdG9yUHJvdG86OkV4dGVuc2lvblJhbmdlOjprRW5kRmllbGROdW1iZXIpOworICAgICAgaWYgKFRyeUNvbnN1bWUoIm1heCIpKSB7CisgICAgICAgIC8vIFNldCB0byB0aGUgc2VudGluZWwgdmFsdWUgLSAxIHNpbmNlIHdlIGluY3JlbWVudCB0aGUgdmFsdWUgYmVsb3cuCisgICAgICAgIC8vIFRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGVuZCBvZiB0aGUgcmFuZ2Ugc2hvdWxkIGJlIHNldCB3aXRoCisgICAgICAgIC8vIEFkanVzdEV4dGVuc2lvblJhbmdlc1dpdGhNYXhFbmROdW1iZXIuCisgICAgICAgIGVuZCA9IGtNYXhFeHRlbnNpb25SYW5nZVNlbnRpbmVsIC0gMTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIERPKENvbnN1bWVJbnRlZ2VyKCZlbmQsICJFeHBlY3RlZCBpbnRlZ2VyLiIpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBlbmRfbG9jYXRpb24oCisgICAgICAgICAgbG9jYXRpb24sIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2U6OmtFbmRGaWVsZE51bWJlcik7CisgICAgICBlbmRfbG9jYXRpb24uU3RhcnRBdChzdGFydF90b2tlbik7CisgICAgICBlbmRfbG9jYXRpb24uRW5kQXQoc3RhcnRfdG9rZW4pOworICAgICAgZW5kID0gc3RhcnQ7CisgICAgfQorCisgICAgLy8gVXNlcnMgbGlrZSB0byBzcGVjaWZ5IGluY2x1c2l2ZSByYW5nZXMsIGJ1dCBpbiBjb2RlIHdlIGxpa2UgdGhlIGVuZAorICAgIC8vIG51bWJlciB0byBiZSBleGNsdXNpdmUuCisgICAgKytlbmQ7CisKKyAgICByYW5nZS0+c2V0X3N0YXJ0KHN0YXJ0KTsKKyAgICByYW5nZS0+c2V0X2VuZChlbmQpOworICB9IHdoaWxlIChUcnlDb25zdW1lKCIsIikpOworCisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgJmV4dGVuc2lvbnNfbG9jYXRpb24pKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUV4dGVuZChSZXBlYXRlZFB0ckZpZWxkPEZpZWxkRGVzY3JpcHRvclByb3RvPiogZXh0ZW5zaW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZFB0ckZpZWxkPERlc2NyaXB0b3JQcm90bz4qIG1lc3NhZ2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG9jYXRpb25fZmllbGRfbnVtYmVyX2Zvcl9uZXN0ZWRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBleHRlbmRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWUoImV4dGVuZCIpKTsKKworICAvLyBQYXJzZSB0aGUgZXh0ZW5kZWUgdHlwZS4KKyAgaW86OlRva2VuaXplcjo6VG9rZW4gZXh0ZW5kZWVfc3RhcnQgPSBpbnB1dF8tPmN1cnJlbnQoKTsKKyAgc3RyaW5nIGV4dGVuZGVlOworICBETyhQYXJzZVVzZXJEZWZpbmVkVHlwZSgmZXh0ZW5kZWUpKTsKKyAgaW86OlRva2VuaXplcjo6VG9rZW4gZXh0ZW5kZWVfZW5kID0gaW5wdXRfLT5wcmV2aW91cygpOworCisgIC8vIFBhcnNlIHRoZSBibG9jay4KKyAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oInsiLCAmZXh0ZW5kX2xvY2F0aW9uKSk7CisKKyAgYm9vbCBpc19maXJzdCA9IHRydWU7CisKKyAgZG8geworICAgIGlmIChBdEVuZCgpKSB7CisgICAgICBBZGRFcnJvcigiUmVhY2hlZCBlbmQgb2YgaW5wdXQgaW4gZXh0ZW5kIGRlZmluaXRpb24gKG1pc3NpbmcgJ30nKS4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBOb3RlIHRoYXQga0V4dGVuc2lvbkZpZWxkTnVtYmVyIHdhcyBhbHJlYWR5IHB1c2hlZCBieSB0aGUgcGFyZW50LgorICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZXh0ZW5kX2xvY2F0aW9uLCBleHRlbnNpb25zLT5zaXplKCkpOworCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkID0gZXh0ZW5zaW9ucy0+QWRkKCk7CisKKyAgICB7CisgICAgICBMb2NhdGlvblJlY29yZGVyIGV4dGVuZGVlX2xvY2F0aW9uKAorICAgICAgICAgIGxvY2F0aW9uLCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a0V4dGVuZGVlRmllbGROdW1iZXIpOworICAgICAgZXh0ZW5kZWVfbG9jYXRpb24uU3RhcnRBdChleHRlbmRlZV9zdGFydCk7CisgICAgICBleHRlbmRlZV9sb2NhdGlvbi5FbmRBdChleHRlbmRlZV9lbmQpOworCisgICAgICBpZiAoaXNfZmlyc3QpIHsKKyAgICAgICAgZXh0ZW5kZWVfbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICAgICAgICBmaWVsZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFWFRFTkRFRSk7CisgICAgICAgIGlzX2ZpcnN0ID0gZmFsc2U7CisgICAgICB9CisgICAgfQorCisgICAgZmllbGQtPnNldF9leHRlbmRlZShleHRlbmRlZSk7CisKKyAgICBpZiAoIVBhcnNlTWVzc2FnZUZpZWxkKGZpZWxkLCBtZXNzYWdlcywgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb25fZmllbGRfbnVtYmVyX2Zvcl9uZXN0ZWRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKSkgeworICAgICAgLy8gVGhpcyBzdGF0ZW1lbnQgZmFpbGVkIHRvIHBhcnNlLiAgU2tpcCBpdCwgYnV0IGtlZXAgbG9vcGluZyB0byBwYXJzZQorICAgICAgLy8gb3RoZXIgc3RhdGVtZW50cy4KKyAgICAgIFNraXBTdGF0ZW1lbnQoKTsKKyAgICB9CisgIH0gd2hpbGUgKCFUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigifSIsIE5VTEwpKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlT25lb2YoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG9uZW9mX2RlY2wsCisgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBvbmVvZl9pbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG9uZW9mX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgY29udGFpbmluZ190eXBlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWUoIm9uZW9mIikpOworCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIG5hbWVfbG9jYXRpb24ob25lb2ZfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9uZW9mRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihvbmVvZl9kZWNsLT5tdXRhYmxlX25hbWUoKSwgIkV4cGVjdGVkIG9uZW9mIG5hbWUuIikpOworICB9CisKKyAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oInsiLCAmb25lb2ZfbG9jYXRpb24pKTsKKworICBkbyB7CisgICAgaWYgKEF0RW5kKCkpIHsKKyAgICAgIEFkZEVycm9yKCJSZWFjaGVkIGVuZCBvZiBpbnB1dCBpbiBvbmVvZiBkZWZpbml0aW9uIChtaXNzaW5nICd9JykuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gUHJpbnQgYSBuaWNlIGVycm9yIGlmIHRoZSB1c2VyIGFjY2lkZW50YWxseSB0cmllcyB0byBwbGFjZSBhIGxhYmVsCisgICAgLy8gb24gYW4gaW5kaXZpZHVhbCBtZW1iZXIgb2YgYSBvbmVvZi4KKyAgICBpZiAoTG9va2luZ0F0KCJyZXF1aXJlZCIpIHx8CisgICAgICAgIExvb2tpbmdBdCgib3B0aW9uYWwiKSB8fAorICAgICAgICBMb29raW5nQXQoInJlcGVhdGVkIikpIHsKKyAgICAgIEFkZEVycm9yKCJGaWVsZHMgaW4gb25lb2ZzIG11c3Qgbm90IGhhdmUgbGFiZWxzIChyZXF1aXJlZCAvIG9wdGlvbmFsICIKKyAgICAgICAgICAgICAgICIvIHJlcGVhdGVkKS4iKTsKKyAgICAgIC8vIFdlIGNhbiBjb250aW51ZSBwYXJzaW5nIGhlcmUgYmVjYXVzZSB3ZSB1bmRlcnN0YW5kIHdoYXQgdGhlIHVzZXIKKyAgICAgIC8vIG1lYW50LiAgVGhlIGVycm9yIHJlcG9ydCB3aWxsIHN0aWxsIG1ha2UgcGFyc2luZyBmYWlsIG92ZXJhbGwuCisgICAgICBpbnB1dF8tPk5leHQoKTsKKyAgICB9CisKKyAgICBMb2NhdGlvblJlY29yZGVyIGZpZWxkX2xvY2F0aW9uKGNvbnRhaW5pbmdfdHlwZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0ZpZWxkRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGUtPmZpZWxkX3NpemUoKSk7CisKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQgPSBjb250YWluaW5nX3R5cGUtPmFkZF9maWVsZCgpOworICAgIGZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAgICBmaWVsZC0+c2V0X29uZW9mX2luZGV4KG9uZW9mX2luZGV4KTsKKworICAgIGlmICghUGFyc2VNZXNzYWdlRmllbGROb0xhYmVsKGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKSkgeworICAgICAgLy8gVGhpcyBzdGF0ZW1lbnQgZmFpbGVkIHRvIHBhcnNlLiAgU2tpcCBpdCwgYnV0IGtlZXAgbG9vcGluZyB0byBwYXJzZQorICAgICAgLy8gb3RoZXIgc3RhdGVtZW50cy4KKyAgICAgIFNraXBTdGF0ZW1lbnQoKTsKKyAgICB9CisgIH0gd2hpbGUgKCFUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigifSIsIE5VTEwpKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRW51bXMKKworYm9vbCBQYXJzZXI6OlBhcnNlRW51bURlZmluaXRpb24oRW51bURlc2NyaXB0b3JQcm90byogZW51bV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJlbnVtIikpOworCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGVudW1fbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgZW51bV90eXBlLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUpOworICAgIERPKENvbnN1bWVJZGVudGlmaWVyKGVudW1fdHlwZS0+bXV0YWJsZV9uYW1lKCksICJFeHBlY3RlZCBlbnVtIG5hbWUuIikpOworICB9CisKKyAgRE8oUGFyc2VFbnVtQmxvY2soZW51bV90eXBlLCBlbnVtX2xvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUVudW1CbG9jayhFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oInsiLCAmZW51bV9sb2NhdGlvbikpOworCisgIHdoaWxlICghVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIn0iLCBOVUxMKSkgeworICAgIGlmIChBdEVuZCgpKSB7CisgICAgICBBZGRFcnJvcigiUmVhY2hlZCBlbmQgb2YgaW5wdXQgaW4gZW51bSBkZWZpbml0aW9uIChtaXNzaW5nICd9JykuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKCFQYXJzZUVudW1TdGF0ZW1lbnQoZW51bV90eXBlLCBlbnVtX2xvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpKSB7CisgICAgICAvLyBUaGlzIHN0YXRlbWVudCBmYWlsZWQgdG8gcGFyc2UuICBTa2lwIGl0LCBidXQga2VlcCBsb29waW5nIHRvIHBhcnNlCisgICAgICAvLyBvdGhlciBzdGF0ZW1lbnRzLgorICAgICAgU2tpcFN0YXRlbWVudCgpOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VFbnVtU3RhdGVtZW50KEVudW1EZXNjcmlwdG9yUHJvdG8qIGVudW1fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsIE5VTEwpKSB7CisgICAgLy8gZW1wdHkgc3RhdGVtZW50OyBpZ25vcmUKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIm9wdGlvbiIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihlbnVtX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bURlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcik7CisgICAgcmV0dXJuIFBhcnNlT3B0aW9uKGVudW1fdHlwZS0+bXV0YWJsZV9vcHRpb25zKCksIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUsIE9QVElPTl9TVEFURU1FTlQpOworICB9IGVsc2UgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZW51bV9sb2NhdGlvbiwKKyAgICAgICAgRW51bURlc2NyaXB0b3JQcm90bzo6a1ZhbHVlRmllbGROdW1iZXIsIGVudW1fdHlwZS0+dmFsdWVfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VFbnVtQ29uc3RhbnQoZW51bV90eXBlLT5hZGRfdmFsdWUoKSwgbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSk7CisgIH0KK30KKworYm9vbCBQYXJzZXI6OlBhcnNlRW51bUNvbnN0YW50KEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogZW51bV92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX3ZhbHVlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICAvLyBQYXJzZSBuYW1lLgorICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihlbnVtX3ZhbHVlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgZW51bV92YWx1ZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihlbnVtX3ZhbHVlLT5tdXRhYmxlX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgZW51bSBjb25zdGFudCBuYW1lLiIpKTsKKyAgfQorCisgIERPKENvbnN1bWUoIj0iLCAiTWlzc2luZyBudW1lcmljIHZhbHVlIGZvciBlbnVtIGNvbnN0YW50LiIpKTsKKworICAvLyBQYXJzZSB2YWx1ZS4KKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgIGVudW1fdmFsdWVfbG9jYXRpb24sIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6a051bWJlckZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgZW51bV92YWx1ZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIpOworCisgICAgaW50IG51bWJlcjsKKyAgICBETyhDb25zdW1lU2lnbmVkSW50ZWdlcigmbnVtYmVyLCAiRXhwZWN0ZWQgaW50ZWdlci4iKSk7CisgICAgZW51bV92YWx1ZS0+c2V0X251bWJlcihudW1iZXIpOworICB9CisKKyAgRE8oUGFyc2VFbnVtQ29uc3RhbnRPcHRpb25zKGVudW1fdmFsdWUsIGVudW1fdmFsdWVfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpKTsKKworICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZlbnVtX3ZhbHVlX2xvY2F0aW9uKSk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUVudW1Db25zdGFudE9wdGlvbnMoCisgICAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiB2YWx1ZSwKKyAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX3ZhbHVlX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoIUxvb2tpbmdBdCgiWyIpKSByZXR1cm4gdHJ1ZTsKKworICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKAorICAgICAgZW51bV92YWx1ZV9sb2NhdGlvbiwgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyKTsKKworICBETyhDb25zdW1lKCJbIikpOworCisgIGRvIHsKKyAgICBETyhQYXJzZU9wdGlvbih2YWx1ZS0+bXV0YWJsZV9vcHRpb25zKCksIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSwgT1BUSU9OX0FTU0lHTk1FTlQpKTsKKyAgfSB3aGlsZSAoVHJ5Q29uc3VtZSgiLCIpKTsKKworICBETyhDb25zdW1lKCJdIikpOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU2VydmljZXMKKworYm9vbCBQYXJzZXI6OlBhcnNlU2VydmljZURlZmluaXRpb24oCisgICAgU2VydmljZURlc2NyaXB0b3JQcm90byogc2VydmljZSwKKyAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBzZXJ2aWNlX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJzZXJ2aWNlIikpOworCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKHNlcnZpY2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgc2VydmljZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihzZXJ2aWNlLT5tdXRhYmxlX25hbWUoKSwgIkV4cGVjdGVkIHNlcnZpY2UgbmFtZS4iKSk7CisgIH0KKworICBETyhQYXJzZVNlcnZpY2VCbG9jayhzZXJ2aWNlLCBzZXJ2aWNlX2xvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZVNlcnZpY2VCbG9jayhTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHNlcnZpY2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJnNlcnZpY2VfbG9jYXRpb24pKTsKKworICB3aGlsZSAoIVRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ9IiwgTlVMTCkpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgQWRkRXJyb3IoIlJlYWNoZWQgZW5kIG9mIGlucHV0IGluIHNlcnZpY2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghUGFyc2VTZXJ2aWNlU3RhdGVtZW50KHNlcnZpY2UsIHNlcnZpY2VfbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSkpIHsKKyAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgIC8vIG90aGVyIHN0YXRlbWVudHMuCisgICAgICBTa2lwU3RhdGVtZW50KCk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZVNlcnZpY2VTdGF0ZW1lbnQoU2VydmljZURlc2NyaXB0b3JQcm90byogc2VydmljZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgc2VydmljZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsIE5VTEwpKSB7CisgICAgLy8gZW1wdHkgc3RhdGVtZW50OyBpZ25vcmUKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIm9wdGlvbiIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgICAgc2VydmljZV9sb2NhdGlvbiwgU2VydmljZURlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcik7CisgICAgcmV0dXJuIFBhcnNlT3B0aW9uKHNlcnZpY2UtPm11dGFibGVfb3B0aW9ucygpLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlLCBPUFRJT05fU1RBVEVNRU5UKTsKKyAgfSBlbHNlIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKHNlcnZpY2VfbG9jYXRpb24sCisgICAgICAgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmtNZXRob2RGaWVsZE51bWJlciwgc2VydmljZS0+bWV0aG9kX3NpemUoKSk7CisgICAgcmV0dXJuIFBhcnNlU2VydmljZU1ldGhvZChzZXJ2aWNlLT5hZGRfbWV0aG9kKCksIGxvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZVNlcnZpY2VNZXRob2QoTWV0aG9kRGVzY3JpcHRvclByb3RvKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1ldGhvZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWUoInJwYyIpKTsKKworICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihtZXRob2RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXIpOworICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICBtZXRob2QsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSk7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIobWV0aG9kLT5tdXRhYmxlX25hbWUoKSwgIkV4cGVjdGVkIG1ldGhvZCBuYW1lLiIpKTsKKyAgfQorCisgIC8vIFBhcnNlIGlucHV0IHR5cGUuCisgIERPKENvbnN1bWUoIigiKSk7CisgIHsKKyAgICBpZiAoTG9va2luZ0F0KCJzdHJlYW0iKSkgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgICAgICBtZXRob2RfbG9jYXRpb24sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a0NsaWVudFN0cmVhbWluZ0ZpZWxkTnVtYmVyKTsKKyAgICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICAgIG1ldGhvZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUik7CisgICAgICBtZXRob2QtPnNldF9jbGllbnRfc3RyZWFtaW5nKHRydWUpOworICAgICAgRE8oQ29uc3VtZSgic3RyZWFtIikpOworCisgICAgfQorICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWV0aG9kX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprSW5wdXRUeXBlRmllbGROdW1iZXIpOworICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICBtZXRob2QsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6SU5QVVRfVFlQRSk7CisgICAgRE8oUGFyc2VVc2VyRGVmaW5lZFR5cGUobWV0aG9kLT5tdXRhYmxlX2lucHV0X3R5cGUoKSkpOworICB9CisgIERPKENvbnN1bWUoIikiKSk7CisKKyAgLy8gUGFyc2Ugb3V0cHV0IHR5cGUuCisgIERPKENvbnN1bWUoInJldHVybnMiKSk7CisgIERPKENvbnN1bWUoIigiKSk7CisgIHsKKyAgICBpZiAoTG9va2luZ0F0KCJzdHJlYW0iKSkgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgICAgICBtZXRob2RfbG9jYXRpb24sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a1NlcnZlclN0cmVhbWluZ0ZpZWxkTnVtYmVyKTsKKyAgICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICAgIG1ldGhvZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUik7CisgICAgICBETyhDb25zdW1lKCJzdHJlYW0iKSk7CisgICAgICBtZXRob2QtPnNldF9zZXJ2ZXJfc3RyZWFtaW5nKHRydWUpOworCisgICAgfQorICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWV0aG9kX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprT3V0cHV0VHlwZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgbWV0aG9kLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9VVFBVVF9UWVBFKTsKKyAgICBETyhQYXJzZVVzZXJEZWZpbmVkVHlwZShtZXRob2QtPm11dGFibGVfb3V0cHV0X3R5cGUoKSkpOworICB9CisgIERPKENvbnN1bWUoIikiKSk7CisKKyAgaWYgKExvb2tpbmdBdCgieyIpKSB7CisgICAgLy8gT3B0aW9ucyEKKyAgICBETyhQYXJzZU1ldGhvZE9wdGlvbnMobWV0aG9kX2xvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kLT5tdXRhYmxlX29wdGlvbnMoKSkpOworICB9IGVsc2UgeworICAgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgJm1ldGhvZF9sb2NhdGlvbikpOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKworYm9vbCBQYXJzZXI6OlBhcnNlTWV0aG9kT3B0aW9ucyhjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9wdGlvbnNGaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogbXV0YWJsZV9vcHRpb25zKSB7CisgIC8vIE9wdGlvbnMhCisgIENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJnBhcmVudF9sb2NhdGlvbik7CisgIHdoaWxlICghVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIn0iLCBOVUxMKSkgeworICAgIGlmIChBdEVuZCgpKSB7CisgICAgICBBZGRFcnJvcigiUmVhY2hlZCBlbmQgb2YgaW5wdXQgaW4gbWV0aG9kIG9wdGlvbnMgKG1pc3NpbmcgJ30nKS4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCBOVUxMKSkgeworICAgICAgLy8gZW1wdHkgc3RhdGVtZW50OyBpZ25vcmUKKyAgICB9IGVsc2UgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihwYXJlbnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNGaWVsZE51bWJlcik7CisgICAgICBpZiAoIVBhcnNlT3B0aW9uKG11dGFibGVfb3B0aW9ucywgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSwgT1BUSU9OX1NUQVRFTUVOVCkpIHsKKyAgICAgICAgLy8gVGhpcyBzdGF0ZW1lbnQgZmFpbGVkIHRvIHBhcnNlLiAgU2tpcCBpdCwgYnV0IGtlZXAgbG9vcGluZyB0bworICAgICAgICAvLyBwYXJzZSBvdGhlciBzdGF0ZW1lbnRzLgorICAgICAgICBTa2lwU3RhdGVtZW50KCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworYm9vbCBQYXJzZXI6OlBhcnNlTGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsKiBsYWJlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoVHJ5Q29uc3VtZSgib3B0aW9uYWwiKSkgeworICAgICpsYWJlbCA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCJyZXBlYXRlZCIpKSB7CisgICAgKmxhYmVsID0gRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUEVBVEVEOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoInJlcXVpcmVkIikpIHsKKyAgICAqbGFiZWwgPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQ7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VUeXBlKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlKiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHR5cGVfbmFtZSkgeworICBUeXBlTmFtZU1hcDo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGtUeXBlTmFtZXMuZmluZChpbnB1dF8tPmN1cnJlbnQoKS50ZXh0KTsKKyAgaWYgKGl0ZXIgIT0ga1R5cGVOYW1lcy5lbmQoKSkgeworICAgICp0eXBlID0gaXRlci0+c2Vjb25kOworICAgIGlucHV0Xy0+TmV4dCgpOworICB9IGVsc2UgeworICAgIERPKFBhcnNlVXNlckRlZmluZWRUeXBlKHR5cGVfbmFtZSkpOworICB9CisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VVc2VyRGVmaW5lZFR5cGUoc3RyaW5nKiB0eXBlX25hbWUpIHsKKyAgdHlwZV9uYW1lLT5jbGVhcigpOworCisgIFR5cGVOYW1lTWFwOjpjb25zdF9pdGVyYXRvciBpdGVyID0ga1R5cGVOYW1lcy5maW5kKGlucHV0Xy0+Y3VycmVudCgpLnRleHQpOworICBpZiAoaXRlciAhPSBrVHlwZU5hbWVzLmVuZCgpKSB7CisgICAgLy8gTm90ZTogIFRoZSBvbmx5IHBsYWNlIGVudW0gdHlwZXMgYXJlIGFsbG93ZWQgaXMgZm9yIGZpZWxkIHR5cGVzLCBidXQKKyAgICAvLyAgIGlmIHdlIGFyZSBwYXJzaW5nIGEgZmllbGQgdHlwZSB0aGVuIHdlIHdvdWxkIG5vdCBnZXQgaGVyZSBiZWNhdXNlCisgICAgLy8gICBwcmltaXRpdmVzIGFyZSBhbGxvd2VkIHRoZXJlIGFzIHdlbGwuICBTbyB0aGlzIGVycm9yIG1lc3NhZ2UgZG9lc24ndAorICAgIC8vICAgbmVlZCB0byBhY2NvdW50IGZvciBlbnVtcy4KKyAgICBBZGRFcnJvcigiRXhwZWN0ZWQgbWVzc2FnZSB0eXBlLiIpOworCisgICAgLy8gUHJldGVuZCB0byBhY2NlcHQgdGhpcyB0eXBlIHNvIHRoYXQgd2UgY2FuIGdvIG9uIHBhcnNpbmcuCisgICAgKnR5cGVfbmFtZSA9IGlucHV0Xy0+Y3VycmVudCgpLnRleHQ7CisgICAgaW5wdXRfLT5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBBIGxlYWRpbmcgIi4iIG1lYW5zIHRoZSBuYW1lIGlzIGZ1bGx5LXF1YWxpZmllZC4KKyAgaWYgKFRyeUNvbnN1bWUoIi4iKSkgdHlwZV9uYW1lLT5hcHBlbmQoIi4iKTsKKworICAvLyBDb25zdW1lIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBuYW1lLgorICBzdHJpbmcgaWRlbnRpZmllcjsKKyAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmlkZW50aWZpZXIsICJFeHBlY3RlZCB0eXBlIG5hbWUuIikpOworICB0eXBlX25hbWUtPmFwcGVuZChpZGVudGlmaWVyKTsKKworICAvLyBDb25zdW1lIG1vcmUgcGFydHMuCisgIHdoaWxlIChUcnlDb25zdW1lKCIuIikpIHsKKyAgICB0eXBlX25hbWUtPmFwcGVuZCgiLiIpOworICAgIERPKENvbnN1bWVJZGVudGlmaWVyKCZpZGVudGlmaWVyLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iKSk7CisgICAgdHlwZV9uYW1lLT5hcHBlbmQoaWRlbnRpZmllcik7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitib29sIFBhcnNlcjo6UGFyc2VQYWNrYWdlKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHJvb3RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoZmlsZS0+aGFzX3BhY2thZ2UoKSkgeworICAgIEFkZEVycm9yKCJNdWx0aXBsZSBwYWNrYWdlIGRlZmluaXRpb25zLiIpOworICAgIC8vIERvbid0IGFwcGVuZCB0aGUgbmV3IHBhY2thZ2UgdG8gdGhlIG9sZCBvbmUuICBKdXN0IHJlcGxhY2UgaXQuICBOb3QKKyAgICAvLyB0aGF0IGl0IHJlYWxseSBtYXR0ZXJzIHNpbmNlIHRoaXMgaXMgYW4gZXJyb3IgYW55d2F5LgorICAgIGZpbGUtPmNsZWFyX3BhY2thZ2UoKTsKKyAgfQorCisgIERPKENvbnN1bWUoInBhY2thZ2UiKSk7CisKKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtQYWNrYWdlRmllbGROdW1iZXIpOworICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKGZpbGUsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSk7CisKKyAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgc3RyaW5nIGlkZW50aWZpZXI7CisgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmaWRlbnRpZmllciwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIikpOworICAgICAgZmlsZS0+bXV0YWJsZV9wYWNrYWdlKCktPmFwcGVuZChpZGVudGlmaWVyKTsKKyAgICAgIGlmICghVHJ5Q29uc3VtZSgiLiIpKSBicmVhazsKKyAgICAgIGZpbGUtPm11dGFibGVfcGFja2FnZSgpLT5hcHBlbmQoIi4iKTsKKyAgICB9CisKKyAgICBsb2NhdGlvbi5FbmRBdChpbnB1dF8tPnByZXZpb3VzKCkpOworCisgICAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCAmbG9jYXRpb24pKTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VJbXBvcnQoUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiBkZXBlbmRlbmN5LAorICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50MzI+KiBwdWJsaWNfZGVwZW5kZW5jeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPGludDMyPiogd2Vha19kZXBlbmRlbmN5LAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHJvb3RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWUoImltcG9ydCIpKTsKKyAgaWYgKExvb2tpbmdBdCgicHVibGljIikpIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKAorICAgICAgICByb290X2xvY2F0aW9uLCBGaWxlRGVzY3JpcHRvclByb3RvOjprUHVibGljRGVwZW5kZW5jeUZpZWxkTnVtYmVyLAorICAgICAgICBwdWJsaWNfZGVwZW5kZW5jeS0+c2l6ZSgpKTsKKyAgICBETyhDb25zdW1lKCJwdWJsaWMiKSk7CisgICAgKnB1YmxpY19kZXBlbmRlbmN5LT5BZGQoKSA9IGRlcGVuZGVuY3ktPnNpemUoKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIndlYWsiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgIHJvb3RfbG9jYXRpb24sIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtXZWFrRGVwZW5kZW5jeUZpZWxkTnVtYmVyLAorICAgICAgICB3ZWFrX2RlcGVuZGVuY3ktPnNpemUoKSk7CisgICAgRE8oQ29uc3VtZSgid2VhayIpKTsKKyAgICAqd2Vha19kZXBlbmRlbmN5LT5BZGQoKSA9IGRlcGVuZGVuY3ktPnNpemUoKTsKKyAgfQorICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihyb290X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6a0RlcGVuZGVuY3lGaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3ktPnNpemUoKSk7CisgICAgRE8oQ29uc3VtZVN0cmluZyhkZXBlbmRlbmN5LT5BZGQoKSwKKyAgICAgICJFeHBlY3RlZCBhIHN0cmluZyBuYW1pbmcgdGhlIGZpbGUgdG8gaW1wb3J0LiIpKTsKKworICAgIGxvY2F0aW9uLkVuZEF0KGlucHV0Xy0+cHJldmlvdXMoKSk7CisKKyAgICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZsb2NhdGlvbikpOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1NvdXJjZUxvY2F0aW9uVGFibGU6OlNvdXJjZUxvY2F0aW9uVGFibGUoKSB7fQorU291cmNlTG9jYXRpb25UYWJsZTo6flNvdXJjZUxvY2F0aW9uVGFibGUoKSB7fQorCitib29sIFNvdXJjZUxvY2F0aW9uVGFibGU6OkZpbmQoCisgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgaW50KiBsaW5lLCBpbnQqIGNvbHVtbikgY29uc3QgeworICBjb25zdCBwYWlyPGludCwgaW50PiogcmVzdWx0ID0KKyAgICAgIEZpbmRPck51bGwobG9jYXRpb25fbWFwXywgc3RkOjptYWtlX3BhaXIoZGVzY3JpcHRvciwgbG9jYXRpb24pKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgKmxpbmUgICA9IC0xOworICAgICpjb2x1bW4gPSAwOworICAgIHJldHVybiBmYWxzZTsKKyAgfSBlbHNlIHsKKyAgICAqbGluZSAgID0gcmVzdWx0LT5maXJzdDsKKyAgICAqY29sdW1uID0gcmVzdWx0LT5zZWNvbmQ7CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKwordm9pZCBTb3VyY2VMb2NhdGlvblRhYmxlOjpBZGQoCisgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgaW50IGxpbmUsIGludCBjb2x1bW4pIHsKKyAgbG9jYXRpb25fbWFwX1tzdGQ6Om1ha2VfcGFpcihkZXNjcmlwdG9yLCBsb2NhdGlvbildID0KKyAgICAgIHN0ZDo6bWFrZV9wYWlyKGxpbmUsIGNvbHVtbik7Cit9CisKK3ZvaWQgU291cmNlTG9jYXRpb25UYWJsZTo6Q2xlYXIoKSB7CisgIGxvY2F0aW9uX21hcF8uY2xlYXIoKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjYjE2NzgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5oCkBAIC0wLDAgKzEsNTU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gSW1wbGVtZW50cyBwYXJzaW5nIG9mIC5wcm90byBmaWxlcyB0byBGaWxlRGVzY3JpcHRvclByb3Rvcy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUEFSU0VSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUEFSU0VSX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsgY2xhc3MgTWVzc2FnZTsgfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBQYXJzZXI7CitjbGFzcyBTb3VyY2VMb2NhdGlvblRhYmxlOworCisvLyBJbXBsZW1lbnRzIHBhcnNpbmcgb2YgcHJvdG9jb2wgZGVmaW5pdGlvbnMgKHN1Y2ggYXMgLnByb3RvIGZpbGVzKS4KKy8vCisvLyBOb3RlIHRoYXQgbW9zdCB1c2VycyB3aWxsIGJlIG1vcmUgaW50ZXJlc3RlZCBpbiB0aGUgSW1wb3J0ZXIgY2xhc3MuCisvLyBQYXJzZXIgaXMgYSBsb3dlci1sZXZlbCBjbGFzcyB3aGljaCBzaW1wbHkgY29udmVydHMgYSBzaW5nbGUgLnByb3RvIGZpbGUKKy8vIHRvIGEgRmlsZURlc2NyaXB0b3JQcm90by4gIEl0IGRvZXMgbm90IHJlc29sdmUgaW1wb3J0IGRpcmVjdGl2ZXMgb3IgcGVyZm9ybQorLy8gbWFueSBvdGhlciBraW5kcyBvZiB2YWxpZGF0aW9uIG5lZWRlZCB0byBjb25zdHJ1Y3QgYSBjb21wbGV0ZQorLy8gRmlsZURlc2NyaXB0b3IuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUGFyc2VyIHsKKyBwdWJsaWM6CisgIFBhcnNlcigpOworICB+UGFyc2VyKCk7CisKKyAgLy8gUGFyc2UgdGhlIGVudGlyZSBpbnB1dCBhbmQgY29uc3RydWN0IGEgRmlsZURlc2NyaXB0b3JQcm90byByZXByZXNlbnRpbmcKKyAgLy8gaXQuICBSZXR1cm5zIHRydWUgaWYgbm8gZXJyb3JzIG9jY3VycmVkLCBmYWxzZSBvdGhlcndpc2UuCisgIGJvb2wgUGFyc2UoaW86OlRva2VuaXplciogaW5wdXQsIEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUpOworCisgIC8vIE9wdGlvbmFsIGZldGF1cmVzOgorCisgIC8vIERFUFJFQ0FURUQ6ICBOZXcgY29kZSBzaG91bGQgdXNlIHRoZSBTb3VyY2VDb2RlSW5mbyBlbWJlZGRlZCBpbiB0aGUKKyAgLy8gICBGaWxlRGVzY3JpcHRvclByb3RvLgorICAvLworICAvLyBSZXF1ZXN0cyB0aGF0IGxvY2F0aW9ucyBvZiBjZXJ0YWluIGRlZmluaXRpb25zIGJlIHJlY29yZGVkIHRvIHRoZSBnaXZlbgorICAvLyBTb3VyY2VMb2NhdGlvblRhYmxlIHdoaWxlIHBhcnNpbmcuICBUaGlzIGNhbiBiZSB1c2VkIHRvIGxvb2sgdXAgZXhhY3QgbGluZQorICAvLyBhbmQgY29sdW1uIG51bWJlcnMgZm9yIGVycm9ycyByZXBvcnRlZCBieSBEZXNjcmlwdG9yUG9vbCBkdXJpbmcgdmFsaWRhdGlvbi4KKyAgLy8gU2V0IHRvIE5VTEwgKHRoZSBkZWZhdWx0KSB0byBkaXNjYXJkIHNvdXJjZSBsb2NhdGlvbiBpbmZvcm1hdGlvbi4KKyAgdm9pZCBSZWNvcmRTb3VyY2VMb2NhdGlvbnNUbyhTb3VyY2VMb2NhdGlvblRhYmxlKiBsb2NhdGlvbl90YWJsZSkgeworICAgIHNvdXJjZV9sb2NhdGlvbl90YWJsZV8gPSBsb2NhdGlvbl90YWJsZTsKKyAgfQorCisgIC8vIFJlcXVlc3RzIHRoYXQgZXJyb3JzIGJlIHJlY29yZGVkIHRvIHRoZSBnaXZlbiBFcnJvckNvbGxlY3RvciB3aGlsZQorICAvLyBwYXJzaW5nLiAgU2V0IHRvIE5VTEwgKHRoZSBkZWZhdWx0KSB0byBkaXNjYXJkIGVycm9yIG1lc3NhZ2VzLgorICB2b2lkIFJlY29yZEVycm9yc1RvKGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKSB7CisgICAgZXJyb3JfY29sbGVjdG9yXyA9IGVycm9yX2NvbGxlY3RvcjsKKyAgfQorCisgIC8vIFJldHVybnMgdGhlIGlkZW50aWZpZXIgdXNlZCBpbiB0aGUgInN5bnRheCA9ICIgZGVjbGFyYXRpb24sIGlmIG9uZSB3YXMKKyAgLy8gc2VlbiBkdXJpbmcgdGhlIGxhc3QgY2FsbCB0byBQYXJzZSgpLCBvciB0aGUgZW1wdHkgc3RyaW5nIG90aGVyd2lzZS4KKyAgY29uc3Qgc3RyaW5nJiBHZXRTeW50YXhJZGVudGlmaWVyKCkgeyByZXR1cm4gc3ludGF4X2lkZW50aWZpZXJfOyB9CisKKyAgLy8gSWYgc2V0IHRydWUsIGlucHV0IGZpbGVzIHdpbGwgYmUgcmVxdWlyZWQgdG8gYmVnaW4gd2l0aCBhIHN5bnRheAorICAvLyBpZGVudGlmaWVyLiAgT3RoZXJ3aXNlLCBmaWxlcyBtYXkgb21pdCB0aGlzLiAgSWYgYSBzeW50YXggaWRlbnRpZmllcgorICAvLyBpcyBwcm92aWRlZCwgaXQgbXVzdCBiZSAnc3ludGF4ID0gInByb3RvMiI7JyBhbmQgbXVzdCBhcHBlYXIgYXQgdGhlCisgIC8vIHRvcCBvZiB0aGlzIGZpbGUgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIG9yIG5vdCBpdCB3YXMgcmVxdWlyZWQuCisgIHZvaWQgU2V0UmVxdWlyZVN5bnRheElkZW50aWZpZXIoYm9vbCB2YWx1ZSkgeworICAgIHJlcXVpcmVfc3ludGF4X2lkZW50aWZpZXJfID0gdmFsdWU7CisgIH0KKworICAvLyBDYWxsIFNldFN0b3BBZnRlclN5bnRheElkZW50aWZpZXIodHJ1ZSkgdG8gdGVsbCB0aGUgcGFyc2VyIHRvIHN0b3AKKyAgLy8gcGFyc2luZyBhcyBzb29uIGFzIGl0IGhhcyBzZWVuIHRoZSBzeW50YXggaWRlbnRpZmllciwgb3IgbGFjayB0aGVyZW9mLgorICAvLyBUaGlzIGlzIHVzZWZ1bCBmb3IgcXVpY2tseSBpZGVudGlmeWluZyB0aGUgc3ludGF4IG9mIHRoZSBmaWxlIHdpdGhvdXQKKyAgLy8gcGFyc2luZyB0aGUgd2hvbGUgdGhpbmcuICBJZiB0aGlzIGlzIGVuYWJsZWQsIG5vIGVycm9yIHdpbGwgYmUgcmVjb3JkZWQKKyAgLy8gaWYgdGhlIHN5bnRheCBpZGVudGlmaWVyIGlzIHNvbWV0aGluZyBvdGhlciB0aGFuICJwcm90bzIiIChzaW5jZQorICAvLyBwcmVzdW1hYmx5IHRoZSBjYWxsZXIgaW50ZW5kcyB0byBkZWFsIHdpdGggdGhhdCksIGJ1dCBvdGhlciBraW5kcyBvZgorICAvLyBlcnJvcnMgKGUuZy4gcGFyc2UgZXJyb3JzKSB3aWxsIHN0aWxsIGJlIHJlcG9ydGVkLiAgV2hlbiB0aGlzIGlzIGVuYWJsZWQsCisgIC8vIHlvdSBtYXkgcGFzcyBhIE5VTEwgRmlsZURlc2NyaXB0b3JQcm90byB0byBQYXJzZSgpLgorICB2b2lkIFNldFN0b3BBZnRlclN5bnRheElkZW50aWZpZXIoYm9vbCB2YWx1ZSkgeworICAgIHN0b3BfYWZ0ZXJfc3ludGF4X2lkZW50aWZpZXJfID0gdmFsdWU7CisgIH0KKworIHByaXZhdGU6CisgIGNsYXNzIExvY2F0aW9uUmVjb3JkZXI7CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gRXJyb3IgcmVjb3ZlcnkgaGVscGVycworCisgIC8vIENvbnN1bWUgdGhlIHJlc3Qgb2YgdGhlIGN1cnJlbnQgc3RhdGVtZW50LiAgVGhpcyBjb25zdW1lcyB0b2tlbnMKKyAgLy8gdW50aWwgaXQgc2VlcyBvbmUgb2Y6CisgIC8vICAgJzsnICBDb25zdW1lcyB0aGUgdG9rZW4gYW5kIHJldHVybnMuCisgIC8vICAgJ3snICBDb25zdW1lcyB0aGUgYnJhY2UgdGhlbiBjYWxscyBTa2lwUmVzdE9mQmxvY2soKS4KKyAgLy8gICAnfScgIFJldHVybnMgd2l0aG91dCBjb25zdW1pbmcuCisgIC8vICAgRU9GICBSZXR1cm5zIChjYW4ndCBjb25zdW1lKS4KKyAgLy8gVGhlIFBhcnNlciBvZnRlbiBjYWxscyBTa2lwU3RhdGVtZW50KCkgYWZ0ZXIgZW5jb3VudGVyaW5nIGEgc3ludGF4CisgIC8vIGVycm9yLiAgVGhpcyBhbGxvd3MgaXQgdG8gZ28gb24gcGFyc2luZyB0aGUgZm9sbG93aW5nIGxpbmVzLCBhbGxvd2luZworICAvLyBpdCB0byByZXBvcnQgbW9yZSB0aGFuIGp1c3Qgb25lIGVycm9yIGluIHRoZSBmaWxlLgorICB2b2lkIFNraXBTdGF0ZW1lbnQoKTsKKworICAvLyBDb25zdW1lIHRoZSByZXN0IG9mIHRoZSBjdXJyZW50IGJsb2NrLCBpbmNsdWRpbmcgbmVzdGVkIGJsb2NrcywKKyAgLy8gZW5kaW5nIGFmdGVyIHRoZSBjbG9zaW5nICd9JyBpcyBlbmNvdW50ZXJlZCBhbmQgY29uc3VtZWQsIG9yIGF0IEVPRi4KKyAgdm9pZCBTa2lwUmVzdE9mQmxvY2soKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBTaW5nbGUtdG9rZW4gY29uc3VtaW5nIGhlbHBlcnMKKyAgLy8KKyAgLy8gVGhlc2UgbWFrZSBwYXJzaW5nIGNvZGUgbW9yZSByZWFkYWJsZS4KKworICAvLyBUcnVlIGlmIHRoZSBjdXJyZW50IHRva2VuIGlzIFRZUEVfRU5ELgorICBpbmxpbmUgYm9vbCBBdEVuZCgpOworCisgIC8vIFRydWUgaWYgdGhlIG5leHQgdG9rZW4gbWF0Y2hlcyB0aGUgZ2l2ZW4gdGV4dC4KKyAgaW5saW5lIGJvb2wgTG9va2luZ0F0KGNvbnN0IGNoYXIqIHRleHQpOworICAvLyBUcnVlIGlmIHRoZSBuZXh0IHRva2VuIGlzIG9mIHRoZSBnaXZlbiB0eXBlLgorICBpbmxpbmUgYm9vbCBMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRva2VuVHlwZSB0b2tlbl90eXBlKTsKKworICAvLyBJZiB0aGUgbmV4dCB0b2tlbiBleGFjdGx5IG1hdGNoZXMgdGhlIHRleHQgZ2l2ZW4sIGNvbnN1bWUgaXQgYW5kIHJldHVybgorICAvLyB0cnVlLiAgT3RoZXJ3aXNlLCByZXR1cm4gZmFsc2Ugd2l0aG91dCBsb2dnaW5nIGFuIGVycm9yLgorICBib29sIFRyeUNvbnN1bWUoY29uc3QgY2hhciogdGV4dCk7CisKKyAgLy8gVGhlc2UgYXR0ZW1wdCB0byByZWFkIHNvbWUga2luZCBvZiB0b2tlbiBmcm9tIHRoZSBpbnB1dC4gIElmIHN1Y2Nlc3NmdWwsCisgIC8vIHRoZXkgcmV0dXJuIHRydWUuICBPdGhlcndpc2UgdGhleSByZXR1cm4gZmFsc2UgYW5kIGFkZCB0aGUgZ2l2ZW4gZXJyb3IKKyAgLy8gdG8gdGhlIGVycm9yIGxpc3QuCisKKyAgLy8gQ29uc3VtZSBhIHRva2VuIHdpdGggdGhlIGV4YWN0IHRleHQgZ2l2ZW4uCisgIGJvb2wgQ29uc3VtZShjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBjaGFyKiBlcnJvcik7CisgIC8vIFNhbWUgYXMgYWJvdmUsIGJ1dCBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlcyB0aGUgZXJyb3IgIkV4cGVjdGVkIFwidGV4dFwiLiIsCisgIC8vIHdoZXJlICJ0ZXh0IiBpcyB0aGUgZXhwZWN0ZWQgdG9rZW4gdGV4dC4KKyAgYm9vbCBDb25zdW1lKGNvbnN0IGNoYXIqIHRleHQpOworICAvLyBDb25zdW1lIGEgdG9rZW4gb2YgdHlwZSBJREVOVElGSUVSIGFuZCBzdG9yZSBpdHMgdGV4dCBpbiAib3V0cHV0Ii4KKyAgYm9vbCBDb25zdW1lSWRlbnRpZmllcihzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpOworICAvLyBDb25zdW1lIGFuIGludGVnZXIgYW5kIHN0b3JlIGl0cyB2YWx1ZSBpbiAib3V0cHV0Ii4KKyAgYm9vbCBDb25zdW1lSW50ZWdlcihpbnQqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpOworICAvLyBDb25zdW1lIGEgc2lnbmVkIGludGVnZXIgYW5kIHN0b3JlIGl0cyB2YWx1ZSBpbiAib3V0cHV0Ii4KKyAgYm9vbCBDb25zdW1lU2lnbmVkSW50ZWdlcihpbnQqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpOworICAvLyBDb25zdW1lIGEgNjQtYml0IGludGVnZXIgYW5kIHN0b3JlIGl0cyB2YWx1ZSBpbiAib3V0cHV0Ii4gIElmIHRoZSB2YWx1ZQorICAvLyBpcyBncmVhdGVyIHRoYW4gbWF4X3ZhbHVlLCBhbiBlcnJvciB3aWxsIGJlIHJlcG9ydGVkLgorICBib29sIENvbnN1bWVJbnRlZ2VyNjQodWludDY0IG1heF92YWx1ZSwgdWludDY0KiBvdXRwdXQsIGNvbnN0IGNoYXIqIGVycm9yKTsKKyAgLy8gQ29uc3VtZSBhIG51bWJlciBhbmQgc3RvcmUgaXRzIHZhbHVlIGluICJvdXRwdXQiLiAgVGhpcyB3aWxsIGFjY2VwdAorICAvLyB0b2tlbnMgb2YgZWl0aGVyIElOVEVHRVIgb3IgRkxPQVQgdHlwZS4KKyAgYm9vbCBDb25zdW1lTnVtYmVyKGRvdWJsZSogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcik7CisgIC8vIENvbnN1bWUgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgc3RvcmUgaXRzICh1bmVzY2FwZWQpIHZhbHVlIGluICJvdXRwdXQiLgorICBib29sIENvbnN1bWVTdHJpbmcoc3RyaW5nKiBvdXRwdXQsIGNvbnN0IGNoYXIqIGVycm9yKTsKKworICAvLyBDb25zdW1lIGEgdG9rZW4gcmVwcmVzZW50aW5nIHRoZSBlbmQgb2YgdGhlIHN0YXRlbWVudC4gIENvbW1lbnRzIGJldHdlZW4KKyAgLy8gdGhpcyB0b2tlbiBhbmQgdGhlIG5leHQgd2lsbCBiZSBoYXJ2ZXN0ZWQgZm9yIGRvY3VtZW50YXRpb24uICBUaGUgZ2l2ZW4KKyAgLy8gTG9jYXRpb25SZWNvcmRlciBzaG91bGQgcmVmZXIgdG8gdGhlIGRlY2xhcmF0aW9uIHRoYXQgd2FzIGp1c3QgcGFyc2VkOworICAvLyBpdCB3aWxsIGJlIHBvcHVsYXRlZCB3aXRoIHRoZXNlIGNvbW1lbnRzLgorICAvLworICAvLyBUT0RPKGtlbnRvbik6ICBUaGUgTG9jYXRpb25SZWNvcmRlciBpcyBjb25zdCBiZWNhdXNlIGhpc3RvcmljYWxseSBsb2NhdGlvbnMKKyAgLy8gICBoYXZlIGJlZW4gcGFzc2VkIGFyb3VuZCBieSBjb25zdCByZWZlcmVuY2UsIGZvciBubyBwYXJ0aWN1bGFybHkgZ29vZAorICAvLyAgIHJlYXNvbi4gIFdlIHNob3VsZCBwcm9iYWJseSBnbyB0aHJvdWdoIGFuZCBjaGFuZ2UgdGhlbSBhbGwgdG8gbXV0YWJsZQorICAvLyAgIHBvaW50ZXIgdG8gbWFrZSB0aGlzIG1vcmUgaW50dWl0aXZlLgorICBib29sIFRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKAorICAgICAgY29uc3QgY2hhciogdGV4dCwgY29uc3QgTG9jYXRpb25SZWNvcmRlciogbG9jYXRpb24pOworICBib29sIFRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uRmluaXNoU2NvcGUoCisgICAgICBjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBMb2NhdGlvblJlY29yZGVyKiBsb2NhdGlvbik7CisKKyAgYm9vbCBDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigKKyAgICAgIGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IExvY2F0aW9uUmVjb3JkZXIqIGxvY2F0aW9uKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBFcnJvciBsb2dnaW5nIGhlbHBlcnMKKworICAvLyBJbnZva2VzIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKCksIGlmIGVycm9yX2NvbGxlY3Rvcl8gaXMgbm90IE5VTEwuCisgIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgZXJyb3IpOworCisgIC8vIEludm9rZXMgZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IoKSB3aXRoIHRoZSBsaW5lIGFuZCBjb2x1bW4gbnVtYmVyCisgIC8vIG9mIHRoZSBjdXJyZW50IHRva2VuLgorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZXJyb3IpOworCisgIC8vIFJlY29yZHMgYSBsb2NhdGlvbiBpbiB0aGUgU291cmNlQ29kZUluZm8ubG9jYXRpb24gdGFibGUgKHNlZQorICAvLyBkZXNjcmlwdG9yLnByb3RvKS4gIFdlIHVzZSBSQUlJIHRvIGVuc3VyZSB0aGF0IHRoZSBzdGFydCBhbmQgZW5kIGxvY2F0aW9ucworICAvLyBhcmUgcmVjb3JkZWQgLS0gdGhlIGNvbnN0cnVjdG9yIHJlY29yZHMgdGhlIHN0YXJ0IGxvY2F0aW9uIGFuZCB0aGUKKyAgLy8gZGVzdHJ1Y3RvciByZWNvcmRzIHRoZSBlbmQgbG9jYXRpb24uICBTaW5jZSB0aGUgcGFyc2VyIGlzCisgIC8vIHJlY3Vyc2l2ZS1kZXNjZW50LCB0aGlzIHdvcmtzIG91dCBiZWF1dGlmdWxseS4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIExvY2F0aW9uUmVjb3JkZXIgeworICAgcHVibGljOgorICAgIC8vIENvbnN0cnVjdCB0aGUgZmlsZSdzICJyb290IiBsb2NhdGlvbi4KKyAgICBMb2NhdGlvblJlY29yZGVyKFBhcnNlciogcGFyc2VyKTsKKworICAgIC8vIENvbnN0cnVjdCBhIGxvY2F0aW9uIHRoYXQgcmVwcmVzZW50cyBhIGRlY2xhcmF0aW9uIG5lc3RlZCB3aXRoaW4gdGhlCisgICAgLy8gZ2l2ZW4gcGFyZW50LiAgRS5nLiBhIGZpZWxkJ3MgbG9jYXRpb24gaXMgbmVzdGVkIHdpdGhpbiB0aGUgbG9jYXRpb24KKyAgICAvLyBmb3IgYSBtZXNzYWdlIHR5cGUuICBUaGUgcGFyZW50J3MgcGF0aCB3aWxsIGJlIGNvcGllZCwgc28geW91IHNob3VsZAorICAgIC8vIGNhbGwgQWRkUGF0aCgpIG9ubHkgdG8gYWRkIHRoZSBwYXRoIGNvbXBvbmVudHMgbGVhZGluZyBmcm9tIHRoZSBwYXJlbnQKKyAgICAvLyB0byB0aGUgY2hpbGQgKGFzIG9wcG9zZWQgdG8gbGVhZGluZyBmcm9tIHRoZSByb290IHRvIHRoZSBjaGlsZCkuCisgICAgTG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQpOworCisgICAgLy8gQ29udmVuaWVuY2UgY29uc3RydWN0b3JzIHRoYXQgY2FsbCBBZGRQYXRoKCkgb25lIG9yIHR3byB0aW1lcy4KKyAgICBMb2NhdGlvblJlY29yZGVyKGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCwgaW50IHBhdGgxKTsKKyAgICBMb2NhdGlvblJlY29yZGVyKGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCwgaW50IHBhdGgxLCBpbnQgcGF0aDIpOworCisgICAgfkxvY2F0aW9uUmVjb3JkZXIoKTsKKworICAgIC8vIEFkZCBhIHBhdGggY29tcG9uZW50LiAgU2VlIFNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGggaW4KKyAgICAvLyBkZXNjcmlwdG9yLnByb3RvLgorICAgIHZvaWQgQWRkUGF0aChpbnQgcGF0aF9jb21wb25lbnQpOworCisgICAgLy8gQnkgZGVmYXVsdCB0aGUgbG9jYXRpb24gaXMgY29uc2lkZXJlZCB0byBzdGFydCBhdCB0aGUgY3VycmVudCB0b2tlbiBhdAorICAgIC8vIHRoZSB0aW1lIHRoZSBMb2NhdGlvblJlY29yZGVyIGlzIGNyZWF0ZWQuICBTdGFydEF0KCkgc2V0cyB0aGUgc3RhcnQKKyAgICAvLyBsb2NhdGlvbiB0byB0aGUgZ2l2ZW4gdG9rZW4gaW5zdGVhZC4KKyAgICB2b2lkIFN0YXJ0QXQoY29uc3QgaW86OlRva2VuaXplcjo6VG9rZW4mIHRva2VuKTsKKworICAgIC8vIFN0YXJ0IGF0IHRoZSBzYW1lIGxvY2F0aW9uIGFzIHNvbWUgb3RoZXIgTG9jYXRpb25SZWNvcmRlci4KKyAgICB2b2lkIFN0YXJ0QXQoY29uc3QgTG9jYXRpb25SZWNvcmRlciYgb3RoZXIpOworCisgICAgLy8gQnkgZGVmYXVsdCB0aGUgbG9jYXRpb24gaXMgY29uc2lkZXJlZCB0byBlbmQgYXQgdGhlIHByZXZpb3VzIHRva2VuIGF0CisgICAgLy8gdGhlIHRpbWUgdGhlIExvY2F0aW9uUmVjb3JkZXIgaXMgZGVzdHJveWVkLiAgRW5kQXQoKSBzZXRzIHRoZSBlbmQKKyAgICAvLyBsb2NhdGlvbiB0byB0aGUgZ2l2ZW4gdG9rZW4gaW5zdGVhZC4KKyAgICB2b2lkIEVuZEF0KGNvbnN0IGlvOjpUb2tlbml6ZXI6OlRva2VuJiB0b2tlbik7CisKKyAgICAvLyBSZWNvcmRzIHRoZSBzdGFydCBwb2ludCBvZiB0aGlzIGxvY2F0aW9uIHRvIHRoZSBTb3VyY2VMb2NhdGlvblRhYmxlIHRoYXQKKyAgICAvLyB3YXMgcGFzc2VkIHRvIFJlY29yZFNvdXJjZUxvY2F0aW9uc1RvKCksIGlmIGFueS4gIFNvdXJjZUxvY2F0aW9uVGFibGUKKyAgICAvLyBpcyBhbiBvbGRlciB3YXkgb2Yga2VlcGluZyB0cmFjayBvZiBzb3VyY2UgbG9jYXRpb25zIHdoaWNoIGlzIHN0aWxsCisgICAgLy8gdXNlZCBpbiBzb21lIHBsYWNlcy4KKyAgICB2b2lkIFJlY29yZExlZ2FjeUxvY2F0aW9uKGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbik7CisKKyAgICAvLyBBdHRhY2hlcyBsZWFkaW5nIGFuZCB0cmFpbGluZyBjb21tZW50cyB0byB0aGUgbG9jYXRpb24uICBUaGUgdHdvIHN0cmluZ3MKKyAgICAvLyB3aWxsIGJlIHN3YXBwZWQgaW50byBwbGFjZSwgc28gYWZ0ZXIgdGhpcyBpcyBjYWxsZWQgKmxlYWRpbmcgYW5kCisgICAgLy8gKnRyYWlsaW5nIHdpbGwgYmUgZW1wdHkuCisgICAgLy8KKyAgICAvLyBUT0RPKGtlbnRvbik6ICBTZWUgY29tbWVudCBvbiBUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigpLCBhYm92ZSwgZm9yCisgICAgLy8gICB3aHkgdGhpcyBpcyBjb25zdC4KKyAgICB2b2lkIEF0dGFjaENvbW1lbnRzKHN0cmluZyogbGVhZGluZywgc3RyaW5nKiB0cmFpbGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBkZXRhY2hlZF9jb21tZW50cykgY29uc3Q7CisKKyAgIHByaXZhdGU6CisgICAgLy8gSW5kZXhlcyBvZiBwYXJlbnQgYW5kIGN1cnJlbnQgbG9jYXRpb24gaW4gdGhlIHBhcmVudAorICAgIC8vIFNvdXJjZUNvZGVJbmZvLmxvY2F0aW9uIHJlcGVhdGVkIGZpZWxkLiBGb3IgdG9wLWxldmVsIGVsZW1lbnRzLAorICAgIC8vIHBhcmVudF9pbmRleF8gaXMgLTEuCisgICAgUGFyc2VyKiBwYXJzZXJfOworICAgIFNvdXJjZUNvZGVJbmZvOjpMb2NhdGlvbiogbG9jYXRpb25fOworCisgICAgdm9pZCBJbml0KGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCk7CisgIH07CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gUGFyc2VycyBmb3IgdmFyaW91cyBsYW5ndWFnZSBjb25zdHJ1Y3RzCisKKyAgLy8gUGFyc2VzIHRoZSAic3ludGF4ID0gXCJwcm90bzJcIjsiIGxpbmUgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZS4gIFJldHVybnMKKyAgLy8gZmFsc2UgaWYgaXQgZmFpbGVkIHRvIHBhcnNlIG9yIGlmIHRoZSBzeW50YXggaWRlbnRpZmllciB3YXMgbm90CisgIC8vIHJlY29nbml6ZWQuCisgIGJvb2wgUGFyc2VTeW50YXhJZGVudGlmaWVyKGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCk7CisKKyAgLy8gVGhlc2UgbWV0aG9kcyBwYXJzZSB2YXJpb3VzIGluZGl2aWR1YWwgYml0cyBvZiBjb2RlLiAgVGhleSByZXR1cm4KKyAgLy8gZmFsc2UgaWYgdGhleSBjb21wbGV0ZWx5IGZhaWwgdG8gcGFyc2UgdGhlIGNvbnN0cnVjdC4gIEluIHRoaXMgY2FzZSwKKyAgLy8gaXQgaXMgcHJvYmFibHkgbmVjZXNzYXJ5IHRvIHNraXAgdGhlIHJlc3Qgb2YgdGhlIHN0YXRlbWVudCB0byByZWNvdmVyLgorICAvLyBIb3dldmVyLCBpZiB0aGVzZSBtZXRob2RzIHJldHVybiB0cnVlLCBpdCBkb2VzIE5PVCBtZWFuIHRoYXQgdGhlcmUKKyAgLy8gd2VyZSBubyBlcnJvcnM7IG9ubHkgdGhhdCB0aGVyZSB3ZXJlIG5vICpzeW50YXgqIGVycm9ycy4gIEZvciBpbnN0YW5jZSwKKyAgLy8gaWYgYSBzZXJ2aWNlIG1ldGhvZCBpcyBkZWZpbmVkIHVzaW5nIHByb3BlciBzeW50YXggYnV0IHVzZXMgYSBwcmltaXRpdmUKKyAgLy8gdHlwZSBhcyBpdHMgaW5wdXQgb3Igb3V0cHV0LCBQYXJzZU1ldGhvZEZpZWxkKCkgc3RpbGwgcmV0dXJucyB0cnVlCisgIC8vIGFuZCBvbmx5IHJlcG9ydHMgdGhlIGVycm9yIGJ5IGNhbGxpbmcgQWRkRXJyb3IoKS4gIEluIHByYWN0aWNlLCB0aGlzCisgIC8vIG1ha2VzIGxvZ2ljIG11Y2ggc2ltcGxlciBmb3IgdGhlIGNhbGxlci4KKworICAvLyBQYXJzZSBhIHRvcC1sZXZlbCBtZXNzYWdlLCBlbnVtLCBzZXJ2aWNlLCBldGMuCisgIGJvb2wgUGFyc2VUb3BMZXZlbFN0YXRlbWVudChGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcm9vdF9sb2NhdGlvbik7CisKKyAgLy8gUGFyc2UgdmFyaW91cyBsYW5ndWFnZSBoaWdoLWxldmVsIGxhbmd1YWdlIGNvbnN0cnVyY3RzLgorICBib29sIFBhcnNlTWVzc2FnZURlZmluaXRpb24oRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgbWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisgIGJvb2wgUGFyc2VFbnVtRGVmaW5pdGlvbihFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKyAgYm9vbCBQYXJzZVNlcnZpY2VEZWZpbml0aW9uKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKyAgYm9vbCBQYXJzZVBhY2thZ2UoRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcm9vdF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKyAgYm9vbCBQYXJzZUltcG9ydChSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qIGRlcGVuZGVuY3ksCisgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQzMj4qIHB1YmxpY19kZXBlbmRlbmN5LAorICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50MzI+KiB3ZWFrX2RlcGVuZGVuY3ksCisgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcm9vdF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFRoZXNlIG1ldGhvZHMgcGFyc2UgdGhlIGNvbnRlbnRzIG9mIGEgbWVzc2FnZSwgZW51bSwgb3Igc2VydmljZSB0eXBlIGFuZAorICAvLyBhZGQgdGhlbSB0byB0aGUgZ2l2ZW4gb2JqZWN0LiAgVGhleSBjb25zdW1lIHRoZSBlbnRpcmUgYmxvY2sgaW5jbHVkaW5nCisgIC8vIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBicmFjZS4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VCbG9jayhEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgbWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlRW51bUJsb2NrKEVudW1EZXNjcmlwdG9yUHJvdG8qIGVudW1fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisgIGJvb2wgUGFyc2VTZXJ2aWNlQmxvY2soU2VydmljZURlc2NyaXB0b3JQcm90byogc2VydmljZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gUGFyc2Ugb25lIHN0YXRlbWVudCB3aXRoaW4gYSBtZXNzYWdlLCBlbnVtLCBvciBzZXJ2aWNlIGJsb2NrLCBpbmNsdW5kaW5nCisgIC8vIGZpbmFsIHNlbWljb2xvbi4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VTdGF0ZW1lbnQoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlRW51bVN0YXRlbWVudChFbnVtRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlU2VydmljZVN0YXRlbWVudChTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGEgZmllbGQgb2YgYSBtZXNzYWdlLiAgSWYgdGhlIGZpZWxkIGlzIGEgZ3JvdXAsIGl0cyB0eXBlIHdpbGwgYmUKKyAgLy8gYWRkZWQgdG8gIm1lc3NhZ2VzIi4KKyAgLy8KKyAgLy8gcGFyZW50X2xvY2F0aW9uIGFuZCBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlIGFyZSBuZWVkZWQgd2hlbgorICAvLyBwYXJzaW5nIGdyb3VwcyAtLSB3ZSBuZWVkIHRvIGdlbmVyYXRlIGEgbmVzdGVkIG1lc3NhZ2UgdHlwZSB3aXRoaW4gdGhlCisgIC8vIHBhcmVudCBhbmQgcmVjb3JkIGl0cyBsb2NhdGlvbiBhY2NvcmRpbmdseS4gIFNpbmNlIHRoZSBwYXJlbnQgY291bGQgYmUKKyAgLy8gZWl0aGVyIGEgRmlsZURlc2NyaXB0b3JQcm90byBvciBhIERlc2NyaXB0b3JQcm90bywgd2UgbXVzdCBwYXNzIGluIHRoZQorICAvLyBjb3JyZWN0IGZpZWxkIG51bWJlciB0byB1c2UuCisgIGJvb2wgUGFyc2VNZXNzYWdlRmllbGQoRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8RGVzY3JpcHRvclByb3RvPiogbWVzc2FnZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gTGlrZSBQYXJzZU1lc3NhZ2VGaWVsZCgpIGJ1dCBleHBlY3RzIHRoZSBsYWJlbCBoYXMgYWxyZWFkeSBiZWVuIGZpbGxlZCBpbgorICAvLyBieSB0aGUgY2FsbGVyLgorICBib29sIFBhcnNlTWVzc2FnZUZpZWxkTm9MYWJlbChGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8RGVzY3JpcHRvclByb3RvPiogbWVzc2FnZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGFuICJleHRlbnNpb25zIiBkZWNsYXJhdGlvbi4KKyAgYm9vbCBQYXJzZUV4dGVuc2lvbnMoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBleHRlbnNpb25zX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGFuICJleHRlbmQiIGRlY2xhcmF0aW9uLiAgKFNlZSBhbHNvIGNvbW1lbnRzIGZvcgorICAvLyBQYXJzZU1lc3NhZ2VGaWVsZCgpLikKKyAgYm9vbCBQYXJzZUV4dGVuZChSZXBlYXRlZFB0ckZpZWxkPEZpZWxkRGVzY3JpcHRvclByb3RvPiogZXh0ZW5zaW9ucywKKyAgICAgICAgICAgICAgICAgICBSZXBlYXRlZFB0ckZpZWxkPERlc2NyaXB0b3JQcm90bz4qIG1lc3NhZ2VzLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICBpbnQgbG9jYXRpb25fZmllbGRfbnVtYmVyX2Zvcl9uZXN0ZWRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBleHRlbmRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBQYXJzZSBhICJvbmVvZiIgZGVjbGFyYXRpb24uICBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBzZXR0aW5nCisgIC8vIG9uZW9mX2RlY2wtPmxhYmVsKCkgc2luY2UgaXQgd2lsbCBoYXZlIGhhZCB0byBwYXJzZSB0aGUgbGFiZWwgYmVmb3JlIGl0CisgIC8vIGtuZXcgaXQgd2FzIHBhcnNpbmcgYSBvbmVvZi4KKyAgYm9vbCBQYXJzZU9uZW9mKE9uZW9mRGVzY3JpcHRvclByb3RvKiBvbmVvZl9kZWNsLAorICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICBpbnQgb25lb2ZfaW5kZXgsCisgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBvbmVvZl9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGNvbnRhaW5pbmdfdHlwZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gUGFyc2UgYSBzaW5nbGUgZW51bSB2YWx1ZSB3aXRoaW4gYW4gZW51bSBibG9jay4KKyAgYm9vbCBQYXJzZUVudW1Db25zdGFudChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIGVudW1fdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV92YWx1ZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGVudW0gY29uc3RhbnQgb3B0aW9ucywgaS5lLiB0aGUgbGlzdCBpbiBzcXVhcmUgYnJhY2tldHMgYXQgdGhlIGVuZAorICAvLyBvZiB0aGUgZW51bSBjb25zdGFudCB2YWx1ZSBkZWZpbml0aW9uLgorICBib29sIFBhcnNlRW51bUNvbnN0YW50T3B0aW9ucyhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX3ZhbHVlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGEgc2luZ2xlIG1ldGhvZCB3aXRoaW4gYSBzZXJ2aWNlIGRlZmluaXRpb24uCisgIGJvb2wgUGFyc2VTZXJ2aWNlTWV0aG9kKE1ldGhvZERlc2NyaXB0b3JQcm90byogbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBtZXRob2RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKworICAvLyBQYXJzZSBvcHRpb25zIG9mIGEgc2luZ2xlIG1ldGhvZCBvciBzdHJlYW0uCisgIGJvb2wgUGFyc2VNZXRob2RPcHRpb25zKGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgb3B0aW9uc0ZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtdXRhYmxlX29wdGlvbnMpOworCisgIC8vIFBhcnNlICJyZXF1aXJlZCIsICJvcHRpb25hbCIsIG9yICJyZXBlYXRlZCIgYW5kIGZpbGwgaW4gImxhYmVsIgorICAvLyB3aXRoIHRoZSB2YWx1ZS4gUmV0dXJucyB0cnVlIGlmIHNodWNoIGEgbGFiZWwgaXMgY29uc3VtZWQuCisgIGJvb2wgUGFyc2VMYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWwqIGxhYmVsLAorICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBQYXJzZSBhIHR5cGUgbmFtZSBhbmQgZmlsbCBpbiAidHlwZSIgKGlmIGl0IGlzIGEgcHJpbWl0aXZlKSBvcgorICAvLyAidHlwZV9uYW1lIiAoaWYgaXQgaXMgbm90KSB3aXRoIHRoZSB0eXBlIHBhcnNlZC4KKyAgYm9vbCBQYXJzZVR5cGUoRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGUqIHR5cGUsCisgICAgICAgICAgICAgICAgIHN0cmluZyogdHlwZV9uYW1lKTsKKyAgLy8gUGFyc2UgYSB1c2VyLWRlZmluZWQgdHlwZSBhbmQgZmlsbCBpbiAidHlwZV9uYW1lIiB3aXRoIHRoZSBuYW1lLgorICAvLyBJZiBhIHByaW1pdGl2ZSB0eXBlIGlzIG5hbWVkLCBpdCBpcyB0cmVhdGVkIGFzIGFuIGVycm9yLgorICBib29sIFBhcnNlVXNlckRlZmluZWRUeXBlKHN0cmluZyogdHlwZV9uYW1lKTsKKworICAvLyBQYXJzZXMgZmllbGQgb3B0aW9ucywgaS5lLiB0aGUgc3R1ZmYgaW4gc3F1YXJlIGJyYWNrZXRzIGF0IHRoZSBlbmQKKyAgLy8gb2YgYSBmaWVsZCBkZWZpbml0aW9uLiAgQWxzbyBwYXJzZXMgZGVmYXVsdCB2YWx1ZS4KKyAgYm9vbCBQYXJzZUZpZWxkT3B0aW9ucyhGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBQYXJzZSB0aGUgImRlZmF1bHQiIG9wdGlvbi4gIFRoaXMgbmVlZHMgc3BlY2lhbCBoYW5kbGluZyBiZWNhdXNlIGl0cworICAvLyB0eXBlIGlzIHRoZSBmaWVsZCdzIHR5cGUuCisgIGJvb2wgUGFyc2VEZWZhdWx0QXNzaWdubWVudChGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgZW51bSBPcHRpb25TdHlsZSB7CisgICAgT1BUSU9OX0FTU0lHTk1FTlQsICAvLyBqdXN0ICJuYW1lID0gdmFsdWUiCisgICAgT1BUSU9OX1NUQVRFTUVOVCAgICAvLyAib3B0aW9uIG5hbWUgPSB2YWx1ZTsiCisgIH07CisKKyAgLy8gUGFyc2UgYSBzaW5nbGUgb3B0aW9uIG5hbWUvdmFsdWUgcGFpciwgZS5nLiAiY3R5cGUgPSBDT1JEIi4gIFRoZSBuYW1lCisgIC8vIGlkZW50aWZpZXMgYSBmaWVsZCBvZiB0aGUgZ2l2ZW4gTWVzc2FnZSwgYW5kIHRoZSB2YWx1ZSBvZiB0aGF0IGZpZWxkCisgIC8vIGlzIHNldCB0byB0aGUgcGFyc2VkIHZhbHVlLgorICBib29sIFBhcnNlT3B0aW9uKE1lc3NhZ2UqIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgb3B0aW9uc19sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgT3B0aW9uU3R5bGUgc3R5bGUpOworCisgIC8vIFBhcnNlcyBhIHNpbmdsZSBwYXJ0IG9mIGEgbXVsdGlwYXJ0IG9wdGlvbiBuYW1lLiBBIG11bHRpcGFydCBuYW1lIGNvbnNpc3RzCisgIC8vIG9mIG5hbWVzIHNlcGFyYXRlZCBieSBkb3RzLiBFYWNoIG5hbWUgaXMgZWl0aGVyIGFuIGlkZW50aWZpZXIgb3IgYSBzZXJpZXMKKyAgLy8gb2YgaWRlbnRpZmllcnMgc2VwYXJhdGVkIGJ5IGRvdHMgYW5kIGVuY2xvc2VkIGluIHBhcmVudGhlc2VzLiBFLmcuLAorICAvLyAiZm9vLihiYXIuYmF6KS5xdXgiLgorICBib29sIFBhcnNlT3B0aW9uTmFtZVBhcnQoVW5pbnRlcnByZXRlZE9wdGlvbiogdW5pbnRlcnByZXRlZF9vcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJ0X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBQYXJzZXMgYSBzdHJpbmcgc3Vycm91bmRlZCBieSBiYWxhbmNlZCBicmFjZXMuICBTdHJpcHMgb2ZmIHRoZSBvdXRlcgorICAvLyBicmFjZXMgYW5kIHN0b3JlcyB0aGUgZW5jbG9zZWQgc3RyaW5nIGluICp2YWx1ZS4KKyAgLy8gRS5nLiwKKyAgLy8gICAgIHsgZm9vIH0gICAgICAgICAgICAgICAgICAgICAqdmFsdWUgZ2V0cyAnZm9vJworICAvLyAgICAgeyBmb28geyBiYXI6IGJveCB9IH0gICAgICAgICp2YWx1ZSBnZXRzICdmb28geyBiYXI6IGJveCB9JworICAvLyAgICAge30gICAgICAgICAgICAgICAgICAgICAgICAgICp2YWx1ZSBnZXRzICcnCisgIC8vCisgIC8vIFJFUVVJUkVTOiBMb29raW5nQXQoInsiKQorICAvLyBXaGVuIGZpbmlzaGVkIHN1Y2Nlc3NmdWxseSwgd2UgYXJlIGxvb2tpbmcgYXQgdGhlIGZpcnN0IHRva2VuIHBhc3QKKyAgLy8gdGhlIGVuZGluZyBicmFjZS4KKyAgYm9vbCBQYXJzZVVuaW50ZXJwcmV0ZWRCbG9jayhzdHJpbmcqIHZhbHVlKTsKKworICBzdHJ1Y3QgTWFwRmllbGQgeworICAgIC8vIFdoZXRoZXIgdGhlIGZpZWxkIGlzIGEgbWFwIGZpZWxkLgorICAgIGJvb2wgaXNfbWFwX2ZpZWxkOworICAgIC8vIFRoZSB0eXBlcyBvZiB0aGUga2V5IGFuZCB2YWx1ZSBpZiB0aGV5IGFyZSBwcmltaXRpdmUgdHlwZXMuCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGUga2V5X3R5cGU7CisgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGUgdmFsdWVfdHlwZTsKKyAgICAvLyBPciB0aGUgdHlwZSBuYW1lcyBzdHJpbmcgaWYgdGhlIHR5cGVzIGFyZSBjdXN0b21pemVkIHR5cGVzLgorICAgIHN0cmluZyBrZXlfdHlwZV9uYW1lOworICAgIHN0cmluZyB2YWx1ZV90eXBlX25hbWU7CisKKyAgICBNYXBGaWVsZCgpIDogaXNfbWFwX2ZpZWxkKGZhbHNlKSB7fQorICB9OworICAvLyBEZXN1Z2FyIHRoZSBtYXAgc3ludGF4IHRvIGdlbmVyYXRlIGEgbmVzdGVkIG1hcCBlbnRyeSBtZXNzYWdlLgorICB2b2lkIEdlbmVyYXRlTWFwRW50cnkoY29uc3QgTWFwRmllbGQmIG1hcF9maWVsZCwgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcyk7CisKKyAgLy8gV2hldGhlciBmaWVsZHMgd2l0aG91dCBsYWJlbCBkZWZhdWx0IHRvIG9wdGlvbmFsIGZpZWxkcy4KKyAgYm9vbCBEZWZhdWx0VG9PcHRpb25hbEZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gc3ludGF4X2lkZW50aWZpZXJfID09ICJwcm90bzMiOworICB9CisKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIGlvOjpUb2tlbml6ZXIqIGlucHV0XzsKKyAgaW86OkVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3JfOworICBTb3VyY2VDb2RlSW5mbyogc291cmNlX2NvZGVfaW5mb187CisgIFNvdXJjZUxvY2F0aW9uVGFibGUqIHNvdXJjZV9sb2NhdGlvbl90YWJsZV87ICAvLyBsZWdhY3kKKyAgYm9vbCBoYWRfZXJyb3JzXzsKKyAgYm9vbCByZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXzsKKyAgYm9vbCBzdG9wX2FmdGVyX3N5bnRheF9pZGVudGlmaWVyXzsKKyAgc3RyaW5nIHN5bnRheF9pZGVudGlmaWVyXzsKKworICAvLyBMZWFkaW5nIGRvYyBjb21tZW50cyBmb3IgdGhlIG5leHQgZGVjbGFyYXRpb24uICBUaGVzZSBhcmUgbm90IGNvbXBsZXRlCisgIC8vIHlldDsgdXNlIENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCkgdG8gZ2V0IHRoZSBjb21wbGV0ZSBjb21tZW50cy4KKyAgc3RyaW5nIHVwY29taW5nX2RvY19jb21tZW50c187CisKKyAgLy8gRGV0YWNoZWQgY29tbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgdG8gYW55IHN5bnRheCBlbnRpdGllcy4gRWxlbWVudHMgaW4KKyAgLy8gdGhpcyB2ZWN0b3IgYXJlIHBhcmFncmFwaHMgb2YgY29tbWVudHMgc2VwYXJhdGVkIGJ5IGVtcHR5IGxpbmVzLiBUaGUKKyAgLy8gZGV0YWNoZWQgY29tbWVudHMgd2lsbCBiZSBwdXQgaW50byB0aGUgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyBmaWVsZCBmb3IKKyAgLy8gdGhlIG5leHQgZWxlbWVudCAoU2VlIFNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIGluIGRlc2NyaXB0b3IucHJvdG8pLCB3aGVuCisgIC8vIENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCkgaXMgY2FsbGVkLgorICB2ZWN0b3I8c3RyaW5nPiB1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFBhcnNlcik7Cit9OworCisvLyBBIHRhYmxlIG1hcHBpbmcgKGRlc2NyaXB0b3IsIEVycm9yTG9jYXRpb24pIHBhaXJzIC0tIGFzIHJlcG9ydGVkIGJ5CisvLyBEZXNjcmlwdG9yUG9vbCB3aGVuIHZhbGlkYXRpbmcgZGVzY3JpcHRvcnMgLS0gdG8gbGluZSBhbmQgY29sdW1uIG51bWJlcnMKKy8vIHdpdGhpbiB0aGUgb3JpZ2luYWwgc291cmNlIGNvZGUuCisvLworLy8gVGhpcyBpcyBzZW1pLW9ic29sZXRlOiAgRmlsZURlc2NyaXB0b3JQcm90by5zb3VyY2VfY29kZV9pbmZvIG5vdyBjb250YWlucworLy8gZmFyIG1vcmUgY29tcGxldGUgaW5mb3JtYXRpb24gYWJvdXQgc291cmNlIGxvY2F0aW9ucy4gIEhvd2V2ZXIsIGFzIG9mIHRoaXMKKy8vIHdyaXRpbmcgeW91IHN0aWxsIG5lZWQgdG8gdXNlIFNvdXJjZUxvY2F0aW9uVGFibGUgd2hlbiBpbnRlZ3JhdGluZyB3aXRoCisvLyBEZXNjcmlwdG9yUG9vbC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTb3VyY2VMb2NhdGlvblRhYmxlIHsKKyBwdWJsaWM6CisgIFNvdXJjZUxvY2F0aW9uVGFibGUoKTsKKyAgflNvdXJjZUxvY2F0aW9uVGFibGUoKTsKKworICAvLyBGaW5kcyB0aGUgcHJlY2lzZSBsb2NhdGlvbiBvZiB0aGUgZ2l2ZW4gZXJyb3IgYW5kIGZpbGxzIGluICpsaW5lIGFuZAorICAvLyAqY29sdW1uIHdpdGggdGhlIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzLiAgSWYgbm90IGZvdW5kLCBzZXRzICpsaW5lIHRvCisgIC8vIC0xIGFuZCAqY29sdW1uIHRvIDAgKHNpbmNlIGxpbmUgPSAtMSBpcyB1c2VkIHRvIG1lYW4gImVycm9yIGhhcyBubyBleGFjdAorICAvLyBsb2NhdGlvbiIgaW4gdGhlIEVycm9yQ29sbGVjdG9yIGludGVyZmFjZSkuICBSZXR1cm5zIHRydWUgaWYgZm91bmQsIGZhbHNlCisgIC8vIG90aGVyd2lzZS4KKyAgYm9vbCBGaW5kKGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICBpbnQqIGxpbmUsIGludCogY29sdW1uKSBjb25zdDsKKworICAvLyBBZGRzIGEgbG9jYXRpb24gdG8gdGhlIHRhYmxlLgorICB2b2lkIEFkZChjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLAorICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgIGludCBsaW5lLCBpbnQgY29sdW1uKTsKKworICAvLyBDbGVhcnMgdGhlIGNvbnRlbnRzIG9mIHRoZSB0YWJsZS4KKyAgdm9pZCBDbGVhcigpOworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiBtYXA8CisgICAgcGFpcjxjb25zdCBNZXNzYWdlKiwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uPiwKKyAgICBwYWlyPGludCwgaW50PiA+IExvY2F0aW9uTWFwOworICBMb2NhdGlvbk1hcCBsb2NhdGlvbl9tYXBfOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUEFSU0VSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXJfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjg0YmViCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXJfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwyOTk2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxtYXA+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKK25hbWVzcGFjZSB7CisKK2NsYXNzIE1vY2tFcnJvckNvbGxlY3RvciA6IHB1YmxpYyBpbzo6RXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgTW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKyAgfk1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisKKyAgc3RyaW5nIHRleHRfOworCisgIC8vIGltcGxlbWVudHMgRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJnRleHRfLCAiJDA6JDE6ICQyXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgfQorfTsKKworY2xhc3MgTW9ja1ZhbGlkYXRpb25FcnJvckNvbGxlY3RvciA6IHB1YmxpYyBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgTW9ja1ZhbGlkYXRpb25FcnJvckNvbGxlY3Rvcihjb25zdCBTb3VyY2VMb2NhdGlvblRhYmxlJiBzb3VyY2VfbG9jYXRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpFcnJvckNvbGxlY3Rvciogd3JhcHBlZF9jb2xsZWN0b3IpCisgICAgOiBzb3VyY2VfbG9jYXRpb25zXyhzb3VyY2VfbG9jYXRpb25zKSwKKyAgICAgIHdyYXBwZWRfY29sbGVjdG9yXyh3cmFwcGVkX2NvbGxlY3Rvcikge30KKyAgfk1vY2tWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIC8vIGltcGxlbWVudHMgRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgIEVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgaW50IGxpbmUsIGNvbHVtbjsKKyAgICBzb3VyY2VfbG9jYXRpb25zXy5GaW5kKGRlc2NyaXB0b3IsIGxvY2F0aW9uLCAmbGluZSwgJmNvbHVtbik7CisgICAgd3JhcHBlZF9jb2xsZWN0b3JfLT5BZGRFcnJvcihsaW5lLCBjb2x1bW4sIG1lc3NhZ2UpOworICB9CisKKyBwcml2YXRlOgorICBjb25zdCBTb3VyY2VMb2NhdGlvblRhYmxlJiBzb3VyY2VfbG9jYXRpb25zXzsKKyAgaW86OkVycm9yQ29sbGVjdG9yKiB3cmFwcGVkX2NvbGxlY3Rvcl87Cit9OworCitjbGFzcyBQYXJzZXJUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgUGFyc2VyVGVzdCgpCisgICAgOiByZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXyhmYWxzZSkge30KKworICAvLyBTZXQgdXAgdGhlIHBhcnNlciB0byBwYXJzZSB0aGUgZ2l2ZW4gdGV4dC4KKyAgdm9pZCBTZXR1cFBhcnNlcihjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgcmF3X2lucHV0Xy5yZXNldChuZXcgaW86OkFycmF5SW5wdXRTdHJlYW0odGV4dCwgc3RybGVuKHRleHQpKSk7CisgICAgaW5wdXRfLnJlc2V0KG5ldyBpbzo6VG9rZW5pemVyKHJhd19pbnB1dF8uZ2V0KCksICZlcnJvcl9jb2xsZWN0b3JfKSk7CisgICAgcGFyc2VyXy5yZXNldChuZXcgUGFyc2VyKCkpOworICAgIHBhcnNlcl8tPlJlY29yZEVycm9yc1RvKCZlcnJvcl9jb2xsZWN0b3JfKTsKKyAgICBwYXJzZXJfLT5TZXRSZXF1aXJlU3ludGF4SWRlbnRpZmllcihyZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXyk7CisgIH0KKworICAvLyBQYXJzZSB0aGUgaW5wdXQgYW5kIGV4cGVjdCB0aGF0IHRoZSByZXN1bHRpbmcgRmlsZURlc2NyaXB0b3JQcm90byBtYXRjaGVzCisgIC8vIHRoZSBnaXZlbiBvdXRwdXQuICBUaGUgb3V0cHV0IGlzIGEgRmlsZURlc2NyaXB0b3JQcm90byBpbiBwcm90b2NvbCBidWZmZXIKKyAgLy8gdGV4dCBmb3JtYXQuCisgIHZvaWQgRXhwZWN0UGFyc2VzVG8oY29uc3QgY2hhciogaW5wdXQsIGNvbnN0IGNoYXIqIG91dHB1dCkgeworICAgIFNldHVwUGFyc2VyKGlucHV0KTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGFjdHVhbCwgZXhwZWN0ZWQ7CisKKyAgICBwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZhY3R1YWwpOworICAgIEVYUEVDVF9FUShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCwgaW5wdXRfLT5jdXJyZW50KCkudHlwZSk7CisgICAgQVNTRVJUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKworICAgIC8vIFdlIGRvbid0IGNvdmVyIFNvdXJjZUNvZGVJbmZvIGluIHRoZXNlIHRlc3RzLgorICAgIGFjdHVhbC5jbGVhcl9zb3VyY2VfY29kZV9pbmZvKCk7CisKKyAgICAvLyBQYXJzZSB0aGUgQVNDSUkgcmVwcmVzZW50YXRpb24gaW4gb3JkZXIgdG8gY2Fub25pY2FsaXplIGl0LiAgV2UgY291bGQKKyAgICAvLyBqdXN0IGNvbXBhcmUgZGlyZWN0bHkgdG8gYWN0dWFsLkRlYnVnU3RyaW5nKCksIGJ1dCB0aGF0IHdvdWxkIHJlcXVpcmUKKyAgICAvLyB0aGF0IHRoZSBjYWxsZXIgcHJlY2lzZWx5IG1hdGNoIHRoZSBmb3JtYXR0aW5nIHRoYXQgRGVidWdTdHJpbmcoKQorICAgIC8vIHByb2R1Y2VzLgorICAgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhvdXRwdXQsICZleHBlY3RlZCkpOworCisgICAgLy8gQ29tcGFyZSBieSBjb21wYXJpbmcgZGVidWcgc3RyaW5ncy4KKyAgICAvLyBUT0RPKGtlbnRvbik6ICBVc2UgZGlmZmVyZW5jZXIsIG9uY2UgaXQgaXMgYXZhaWxhYmxlLgorICAgIEVYUEVDVF9FUShleHBlY3RlZC5EZWJ1Z1N0cmluZygpLCBhY3R1YWwuRGVidWdTdHJpbmcoKSk7CisgIH0KKworICAvLyBQYXJzZSB0aGUgdGV4dCBhbmQgZXhwZWN0IHRoYXQgdGhlIGdpdmVuIGVycm9ycyBhcmUgcmVwb3J0ZWQuCisgIHZvaWQgRXhwZWN0SGFzRXJyb3JzKGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIGV4cGVjdGVkX2Vycm9ycykgeworICAgIEV4cGVjdEhhc0Vhcmx5RXhpdEVycm9ycyh0ZXh0LCBleHBlY3RlZF9lcnJvcnMpOworICAgIEVYUEVDVF9FUShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCwgaW5wdXRfLT5jdXJyZW50KCkudHlwZSk7CisgIH0KKworICAvLyBTYW1lIGFzIGFib3ZlIGJ1dCBkb2VzIG5vdCBleHBlY3QgdGhhdCB0aGUgcGFyc2VyIHBhcnNlcyB0aGUgY29tcGxldGUKKyAgLy8gaW5wdXQuCisgIHZvaWQgRXhwZWN0SGFzRWFybHlFeGl0RXJyb3JzKGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIGV4cGVjdGVkX2Vycm9ycykgeworICAgIFNldHVwUGFyc2VyKHRleHQpOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZmaWxlKTsKKyAgICBFWFBFQ1RfRVEoZXhwZWN0ZWRfZXJyb3JzLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKyAgfQorCisgIC8vIFBhcnNlIHRoZSB0ZXh0IGFzIGEgZmlsZSBhbmQgdmFsaWRhdGUgaXQgKHdpdGggYSBEZXNjcmlwdG9yUG9vbCksIGFuZAorICAvLyBleHBlY3QgdGhhdCB0aGUgdmFsaWRhdGlvbiBzdGVwIHJlcG9ydHMgdGhlIGdpdmVuIGVycm9ycy4KKyAgdm9pZCBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKGNvbnN0IGNoYXIqIHRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBleHBlY3RlZF9lcnJvcnMpIHsKKyAgICBTZXR1cFBhcnNlcih0ZXh0KTsKKyAgICBTb3VyY2VMb2NhdGlvblRhYmxlIHNvdXJjZV9sb2NhdGlvbnM7CisgICAgcGFyc2VyXy0+UmVjb3JkU291cmNlTG9jYXRpb25zVG8oJnNvdXJjZV9sb2NhdGlvbnMpOworCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIGZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworICAgIHBhcnNlcl8tPlBhcnNlKGlucHV0Xy5nZXQoKSwgJmZpbGUpOworICAgIEVYUEVDVF9FUShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCwgaW5wdXRfLT5jdXJyZW50KCkudHlwZSk7CisgICAgQVNTRVJUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKworICAgIE1vY2tWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IgdmFsaWRhdGlvbl9lcnJvcl9jb2xsZWN0b3IoCisgICAgICBzb3VyY2VfbG9jYXRpb25zLCAmZXJyb3JfY29sbGVjdG9yXyk7CisgICAgRVhQRUNUX1RSVUUocG9vbF8uQnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycygKKyAgICAgIGZpbGUsICZ2YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3RvcikgPT0gTlVMTCk7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2Vycm9ycywgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisgIH0KKworICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yXzsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbT4gcmF3X2lucHV0XzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6VG9rZW5pemVyPiBpbnB1dF87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8UGFyc2VyPiBwYXJzZXJfOworICBib29sIHJlcXVpcmVfc3ludGF4X2lkZW50aWZpZXJfOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUX0YoUGFyc2VyVGVzdCwgU3RvcEFmdGVyU3ludGF4SWRlbnRpZmllcikgeworICBTZXR1cFBhcnNlcigKKyAgICAiLy8gYmxhaFxuIgorICAgICJzeW50YXggPSBcImZvb2JhclwiO1xuIgorICAgICJ0aGlzIGxpbmUgd2lsbCBub3QgYmUgcGFyc2VkXG4iKTsKKyAgcGFyc2VyXy0+U2V0U3RvcEFmdGVyU3ludGF4SWRlbnRpZmllcih0cnVlKTsKKyAgRVhQRUNUX1RSVUUocGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCBOVUxMKSk7CisgIEVYUEVDVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisgIEVYUEVDVF9FUSgiZm9vYmFyIiwgcGFyc2VyXy0+R2V0U3ludGF4SWRlbnRpZmllcigpKTsKK30KKworVEVTVF9GKFBhcnNlclRlc3QsIFN0b3BBZnRlck9taXR0ZWRTeW50YXhJZGVudGlmaWVyKSB7CisgIFNldHVwUGFyc2VyKAorICAgICIvLyBibGFoXG4iCisgICAgInRoaXMgbGluZSB3aWxsIG5vdCBiZSBwYXJzZWRcbiIpOworICBwYXJzZXJfLT5TZXRTdG9wQWZ0ZXJTeW50YXhJZGVudGlmaWVyKHRydWUpOworICBFWFBFQ1RfVFJVRShwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksIE5VTEwpKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKyAgRVhQRUNUX0VRKCIiLCBwYXJzZXJfLT5HZXRTeW50YXhJZGVudGlmaWVyKCkpOworfQorCitURVNUX0YoUGFyc2VyVGVzdCwgU3RvcEFmdGVyU3ludGF4SWRlbnRpZmllcldpdGhFcnJvcnMpIHsKKyAgU2V0dXBQYXJzZXIoCisgICAgIi8vIGJsYWhcbiIKKyAgICAic3ludGF4ID0gZXJyb3I7XG4iKTsKKyAgcGFyc2VyXy0+U2V0U3RvcEFmdGVyU3ludGF4SWRlbnRpZmllcih0cnVlKTsKKyAgRVhQRUNUX0ZBTFNFKHBhcnNlcl8tPlBhcnNlKGlucHV0Xy5nZXQoKSwgTlVMTCkpOworICBFWFBFQ1RfRVEoIjE6OTogRXhwZWN0ZWQgc3ludGF4IGlkZW50aWZpZXIuXG4iLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKK30KKworVEVTVF9GKFBhcnNlclRlc3QsIFdhcm5JZlN5bnRheElkZW50aWZpZXJPbW1pdHRlZCkgeworICBTZXR1cFBhcnNlcigibWVzc2FnZSBBIHt9Iik7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgQ2FwdHVyZVRlc3RTdGRlcnIoKTsKKyAgRVhQRUNUX1RSVUUocGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmZmlsZSkpOworICBFWFBFQ1RfVFJVRSgKKyAgICAgIEdldENhcHR1cmVkVGVzdFN0ZGVycigpLmZpbmQoIk5vIHN5bnRheCBzcGVjaWZpZWQiKSAhPSBzdHJpbmc6Om5wb3MpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3R5cGVkZWYgUGFyc2VyVGVzdCBQYXJzZU1lc3NhZ2VUZXN0OworCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgU2ltcGxlTWVzc2FnZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgZm9vID0gMTtcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEltcGxpY2l0U3ludGF4SWRlbnRpZmllcikgeworICByZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXyA9IGZhbHNlOworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgZm9vID0gMTtcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxIH0iCisgICAgIn0iKTsKKyAgRVhQRUNUX0VRKCJwcm90bzIiLCBwYXJzZXJfLT5HZXRTeW50YXhJZGVudGlmaWVyKCkpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgRXhwbGljaXRTeW50YXhJZGVudGlmaWVyKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQzMiBmb28gPSAxO1xuIgorICAgICJ9XG4iLAorCisgICAgInN5bnRheDogJ3Byb3RvMicgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxIH0iCisgICAgIn0iKTsKKyAgRVhQRUNUX0VRKCJwcm90bzIiLCBwYXJzZXJfLT5HZXRTeW50YXhJZGVudGlmaWVyKCkpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgRXhwbGljaXRSZXF1aXJlZFN5bnRheElkZW50aWZpZXIpIHsKKyAgcmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl8gPSB0cnVlOworICBFeHBlY3RQYXJzZXNUbygKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgZm9vID0gMTtcbiIKKyAgICAifVxuIiwKKworICAgICJzeW50YXg6ICdwcm90bzInICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICJ9Iik7CisgIEVYUEVDVF9FUSgicHJvdG8yIiwgcGFyc2VyXy0+R2V0U3ludGF4SWRlbnRpZmllcigpKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIFNpbXBsZUZpZWxkcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgZm9vID0gMTU7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgYmFyID0gMzQ7XG4iCisgICAgIiAgcmVwZWF0ZWQgaW50MzIgYmF6ID0gMztcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxNSB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImJhclwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MzQgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXpcIiBsYWJlbDpMQUJFTF9SRVBFQVRFRCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjMgIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIFByaW1pdGl2ZUZpZWxkVHlwZXMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyICAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50NjQgICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCB1aW50MzIgICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIHVpbnQ2NCAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgc2ludDMyICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBzaW50NjQgICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIGZpeGVkMzIgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgZml4ZWQ2NCAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBzZml4ZWQzMiBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIHNmaXhlZDY0IGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgZmxvYXQgICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBkb3VibGUgICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIHN0cmluZyAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgYnl0ZXMgICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBib29sICAgICBmb28gPSAxO1xuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfSU5UMzIgICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfSU5UNjQgICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfVUlOVDMyICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfVUlOVDY0ICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfU0lOVDMyICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfU0lOVDY0ICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfRklYRUQzMiAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfRklYRUQ2NCAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfU0ZJWEVEMzIgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfU0ZJWEVENjQgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfRkxPQVQgICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfRE9VQkxFICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfU1RSSU5HICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfQllURVMgICAgbnVtYmVyOjEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfQk9PTCAgICAgbnVtYmVyOjEgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgRmllbGREZWZhdWx0cykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgIGZvbyA9IDEgW2RlZmF1bHQ9ICAxICBdO1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyICBmb28gPSAxIFtkZWZhdWx0PSAtMiAgXTtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQ2NCAgZm9vID0gMSBbZGVmYXVsdD0gIDMgIF07XG4iCisgICAgIiAgcmVxdWlyZWQgaW50NjQgIGZvbyA9IDEgW2RlZmF1bHQ9IC00ICBdO1xuIgorICAgICIgIHJlcXVpcmVkIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PSAgNSAgXTtcbiIKKyAgICAiICByZXF1aXJlZCB1aW50NjQgZm9vID0gMSBbZGVmYXVsdD0gIDYgIF07XG4iCisgICAgIiAgcmVxdWlyZWQgZmxvYXQgIGZvbyA9IDEgW2RlZmF1bHQ9ICA3LjVdO1xuIgorICAgICIgIHJlcXVpcmVkIGZsb2F0ICBmb28gPSAxIFtkZWZhdWx0PSAtOC41XTtcbiIKKyAgICAiICByZXF1aXJlZCBmbG9hdCAgZm9vID0gMSBbZGVmYXVsdD0gIDkgIF07XG4iCisgICAgIiAgcmVxdWlyZWQgZG91YmxlIGZvbyA9IDEgW2RlZmF1bHQ9IDEwLjVdO1xuIgorICAgICIgIHJlcXVpcmVkIGRvdWJsZSBmb28gPSAxIFtkZWZhdWx0PS0xMS41XTtcbiIKKyAgICAiICByZXF1aXJlZCBkb3VibGUgZm9vID0gMSBbZGVmYXVsdD0gMTIgIF07XG4iCisgICAgIiAgcmVxdWlyZWQgZG91YmxlIGZvbyA9IDEgW2RlZmF1bHQ9IGluZiBdO1xuIgorICAgICIgIHJlcXVpcmVkIGRvdWJsZSBmb28gPSAxIFtkZWZhdWx0PS1pbmYgXTtcbiIKKyAgICAiICByZXF1aXJlZCBkb3VibGUgZm9vID0gMSBbZGVmYXVsdD0gbmFuIF07XG4iCisgICAgIiAgcmVxdWlyZWQgc3RyaW5nIGZvbyA9IDEgW2RlZmF1bHQ9JzEzXFwwMDEnXTtcbiIKKyAgICAiICByZXF1aXJlZCBzdHJpbmcgZm9vID0gMSBbZGVmYXVsdD0nYScgXCJiXCIgXG4gXCJjXCJdO1xuIgorICAgICIgIHJlcXVpcmVkIGJ5dGVzICBmb28gPSAxIFtkZWZhdWx0PScxNFxcMDAyJ107XG4iCisgICAgIiAgcmVxdWlyZWQgYnl0ZXMgIGZvbyA9IDEgW2RlZmF1bHQ9J2EnIFwiYlwiIFxuICdjJ107XG4iCisgICAgIiAgcmVxdWlyZWQgYm9vbCAgIGZvbyA9IDEgW2RlZmF1bHQ9dHJ1ZSBdO1xuIgorICAgICIgIHJlcXVpcmVkIEZvbyAgICBmb28gPSAxIFtkZWZhdWx0PUZPTyAgXTtcbiIKKworICAgICIgIHJlcXVpcmVkIGludDMyICBmb28gPSAxIFtkZWZhdWx0PSAweDdGRkZGRkZGXTtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQzMiAgZm9vID0gMSBbZGVmYXVsdD0tMHg4MDAwMDAwMF07XG4iCisgICAgIiAgcmVxdWlyZWQgdWludDMyIGZvbyA9IDEgW2RlZmF1bHQ9IDB4RkZGRkZGRkZdO1xuIgorICAgICIgIHJlcXVpcmVkIGludDY0ICBmb28gPSAxIFtkZWZhdWx0PSAweDdGRkZGRkZGRkZGRkZGRkZdO1xuIgorICAgICIgIHJlcXVpcmVkIGludDY0ICBmb28gPSAxIFtkZWZhdWx0PS0weDgwMDAwMDAwMDAwMDAwMDBdO1xuIgorICAgICIgIHJlcXVpcmVkIHVpbnQ2NCBmb28gPSAxIFtkZWZhdWx0PSAweEZGRkZGRkZGRkZGRkZGRkZdO1xuIgorICAgICIgIHJlcXVpcmVkIGRvdWJsZSBmb28gPSAxIFtkZWZhdWx0PSAweGFiY2RdO1xuIgorICAgICJ9XG4iLAorCisjZGVmaW5lIEVUQyAibmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX1JFUVVJUkVEIG51bWJlcjoxIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfSU5UMzIgICBkZWZhdWx0X3ZhbHVlOlwiMVwiICAgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0lOVDMyICAgZGVmYXVsdF92YWx1ZTpcIi0yXCIgICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9JTlQ2NCAgIGRlZmF1bHRfdmFsdWU6XCIzXCIgICAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfSU5UNjQgICBkZWZhdWx0X3ZhbHVlOlwiLTRcIiAgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX1VJTlQzMiAgZGVmYXVsdF92YWx1ZTpcIjVcIiAgICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9VSU5UNjQgIGRlZmF1bHRfdmFsdWU6XCI2XCIgICAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfRkxPQVQgICBkZWZhdWx0X3ZhbHVlOlwiNy41XCIgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0ZMT0FUICAgZGVmYXVsdF92YWx1ZTpcIi04LjVcIiAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9GTE9BVCAgIGRlZmF1bHRfdmFsdWU6XCI5XCIgICAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfRE9VQkxFICBkZWZhdWx0X3ZhbHVlOlwiMTAuNVwiICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0RPVUJMRSAgZGVmYXVsdF92YWx1ZTpcIi0xMS41XCIgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9ET1VCTEUgIGRlZmF1bHRfdmFsdWU6XCIxMlwiICAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfRE9VQkxFICBkZWZhdWx0X3ZhbHVlOlwiaW5mXCIgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0RPVUJMRSAgZGVmYXVsdF92YWx1ZTpcIi1pbmZcIiAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9ET1VCTEUgIGRlZmF1bHRfdmFsdWU6XCJuYW5cIiAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfU1RSSU5HICBkZWZhdWx0X3ZhbHVlOlwiMTNcXDAwMVwiICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX1NUUklORyAgZGVmYXVsdF92YWx1ZTpcImFiY1wiICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9CWVRFUyAgIGRlZmF1bHRfdmFsdWU6XCIxNFxcXFwwMDJcIiAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfQllURVMgICBkZWZhdWx0X3ZhbHVlOlwiYWJjXCIgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0JPT0wgICAgZGVmYXVsdF92YWx1ZTpcInRydWVcIiAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGVfbmFtZTpcIkZvb1wiIGRlZmF1bHRfdmFsdWU6XCJGT09cIiAgICAgICAiIEVUQyAiIH0iCisKKyAgICAiICBmaWVsZCB7IgorICAgICIgICAgdHlwZTpUWVBFX0lOVDMyICAgZGVmYXVsdF92YWx1ZTpcIjIxNDc0ODM2NDdcIiAgICAgICAgICAgIiBFVEMKKyAgICAiICB9IgorICAgICIgIGZpZWxkIHsiCisgICAgIiAgICB0eXBlOlRZUEVfSU5UMzIgICBkZWZhdWx0X3ZhbHVlOlwiLTIxNDc0ODM2NDhcIiAgICAgICAgICAiIEVUQworICAgICIgIH0iCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIHR5cGU6VFlQRV9VSU5UMzIgIGRlZmF1bHRfdmFsdWU6XCI0Mjk0OTY3Mjk1XCIgICAgICAgICAgICIgRVRDCisgICAgIiAgfSIKKyAgICAiICBmaWVsZCB7IgorICAgICIgICAgdHlwZTpUWVBFX0lOVDY0ICAgZGVmYXVsdF92YWx1ZTpcIjkyMjMzNzIwMzY4NTQ3NzU4MDdcIiAgIiBFVEMKKyAgICAiICB9IgorICAgICIgIGZpZWxkIHsiCisgICAgIiAgICB0eXBlOlRZUEVfSU5UNjQgICBkZWZhdWx0X3ZhbHVlOlwiLTkyMjMzNzIwMzY4NTQ3NzU4MDhcIiAiIEVUQworICAgICIgIH0iCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIHR5cGU6VFlQRV9VSU5UNjQgIGRlZmF1bHRfdmFsdWU6XCIxODQ0Njc0NDA3MzcwOTU1MTYxNVwiICIgRVRDCisgICAgIiAgfSIKKyAgICAiICBmaWVsZCB7IgorICAgICIgICAgdHlwZTpUWVBFX0RPVUJMRSAgZGVmYXVsdF92YWx1ZTpcIjQzOTgxXCIgICAgICAgICAgICAgICAgIiBFVEMKKyAgICAiICB9IgorICAgICJ9Iik7CisjdW5kZWYgRVRDCit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBGaWVsZE9wdGlvbnMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHN0cmluZyBmb28gPSAxXG4iCisgICAgIiAgICAgIFtjdHlwZT1DT1JELCAoZm9vKT03LCBmb28uKC5iYXIuYmF6KS5xdXgucXV1eC4oY29yZ2UpPS0zMywgXG4iCisgICAgIiAgICAgICAocXV1eCk9XCJ4XDA0MHlcIiwgKGJhei5xdXgpPWhleV07XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9TVFJJTkcgbnVtYmVyOiAxIgorICAgICIgICAgICAgICAgb3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uOiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiY3R5cGVcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJDT1JEXCIgIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb246IHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDcgIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb246IHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCIuYmFyLmJhelwiIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJxdXhcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJxdXV4XCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwiY29yZ2VcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZV9pbnRfdmFsdWU6IC0zMyB9IgorICAgICIgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uOiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwicXV1eFwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ192YWx1ZTogXCJ4IHlcIiB9IgorICAgICIgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uOiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiYmF6LnF1eFwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiaGV5XCIgfSIKKyAgICAiICAgICAgICAgIH0iCisgICAgIiAgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgT25lb2YpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9uZW9mIGZvbyB7XG4iCisgICAgIiAgICBpbnQzMiBhID0gMTtcbiIKKyAgICAiICAgIHN0cmluZyBiID0gMjtcbiIKKyAgICAiICAgIFRlc3RNZXNzYWdlIGMgPSAzO1xuIgorICAgICIgICAgZ3JvdXAgRCA9IDQgeyBvcHRpb25hbCBpbnQzMiBpID0gNTsgfVxuIgorICAgICIgIH1cbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiYVwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiYlwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9TVFJJTkcgbnVtYmVyOjIgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6MCB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImNcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJUZXN0TWVzc2FnZVwiICIKKyAgICAiICAgICAgICAgIG51bWJlcjozIG9uZW9mX2luZGV4OjAgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJkXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0dST1VQICIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIkRcIiBudW1iZXI6NCBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgb25lb2ZfZGVjbCB7IgorICAgICIgICAgbmFtZTogXCJmb29cIiIKKyAgICAiICB9IgorICAgICIgIG5lc3RlZF90eXBlIHsiCisgICAgIiAgICBuYW1lOiBcIkRcIiIKKyAgICAiICAgIGZpZWxkIHsgbmFtZTpcImlcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjUgfSIKKyAgICAiICB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBNdWx0aXBsZU9uZW9mcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb25lb2YgZm9vIHtcbiIKKyAgICAiICAgIGludDMyIGEgPSAxO1xuIgorICAgICIgICAgc3RyaW5nIGIgPSAyO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBvbmVvZiBiYXIge1xuIgorICAgICIgICAgaW50MzIgYyA9IDM7XG4iCisgICAgIiAgICBzdHJpbmcgZCA9IDQ7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJhXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxICIKKyAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OjAgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX1NUUklORyBudW1iZXI6MiAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiY1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MyAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZFwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9TVFJJTkcgbnVtYmVyOjQgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6MSB9IgorICAgICIgIG9uZW9mX2RlY2wgeyIKKyAgICAiICAgIG5hbWU6IFwiZm9vXCIiCisgICAgIiAgfSIKKyAgICAiICBvbmVvZl9kZWNsIHsiCisgICAgIiAgICBuYW1lOiBcImJhclwiIgorICAgICIgIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIE1hcHMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG1hcDxpbnQzMiwgc3RyaW5nPiBwcmltaXRpdmVfdHlwZV9tYXAgPSAxO1xuIgorICAgICIgIG1hcDxLZXlUeXBlLCBWYWx1ZVR5cGU+IGNvbXBvc2l0ZV90eXBlX21hcCA9IDI7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIG5lc3RlZF90eXBlIHsiCisgICAgIiAgICBuYW1lOiBcIlByaW1pdGl2ZVR5cGVNYXBFbnRyeVwiIgorICAgICIgICAgZmllbGQgeyAiCisgICAgIiAgICAgICBuYW1lOiBcImtleVwiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgIH0iCisgICAgIiAgICBmaWVsZCB7ICIKKyAgICAiICAgICAgIG5hbWU6IFwidmFsdWVcIiBudW1iZXI6IDIgbGFiZWw6TEFCRUxfT1BUSU9OQUwiCisgICAgIiAgICAgICB0eXBlOlRZUEVfU1RSSU5HIgorICAgICIgICAgfSIKKyAgICAiICAgIG9wdGlvbnMgeyBtYXBfZW50cnk6IHRydWUgfSIKKyAgICAiICB9IgorICAgICIgIG5lc3RlZF90eXBlIHsiCisgICAgIiAgICBuYW1lOiBcIkNvbXBvc2l0ZVR5cGVNYXBFbnRyeVwiIgorICAgICIgICAgZmllbGQgeyAiCisgICAgIiAgICAgICBuYW1lOiBcImtleVwiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgIHR5cGVfbmFtZTogXCJLZXlUeXBlXCIiCisgICAgIiAgICB9IgorICAgICIgICAgZmllbGQgeyAiCisgICAgIiAgICAgICBuYW1lOiBcInZhbHVlXCIgbnVtYmVyOiAyIGxhYmVsOkxBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgdHlwZV9uYW1lOiBcIlZhbHVlVHlwZVwiIgorICAgICIgICAgfSIKKyAgICAiICAgIG9wdGlvbnMgeyBtYXBfZW50cnk6IHRydWUgfSIKKyAgICAiICB9IgorICAgICIgIGZpZWxkIHsiCisgICAgIiAgICBuYW1lOiBcInByaW1pdGl2ZV90eXBlX21hcFwiIgorICAgICIgICAgbGFiZWw6IExBQkVMX1JFUEVBVEVEIgorICAgICIgICAgdHlwZV9uYW1lOiBcIlByaW1pdGl2ZVR5cGVNYXBFbnRyeVwiIgorICAgICIgICAgbnVtYmVyOiAxIgorICAgICIgIH0iCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIG5hbWU6IFwiY29tcG9zaXRlX3R5cGVfbWFwXCIiCisgICAgIiAgICBsYWJlbDogTEFCRUxfUkVQRUFURUQiCisgICAgIiAgICB0eXBlX25hbWU6IFwiQ29tcG9zaXRlVHlwZU1hcEVudHJ5XCIiCisgICAgIiAgICBudW1iZXI6IDIiCisgICAgIiAgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgR3JvdXApIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGdyb3VwIFRlc3RHcm91cCA9IDEge307XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIG5lc3RlZF90eXBlIHsgbmFtZTogXCJUZXN0R3JvdXBcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcInRlc3Rncm91cFwiIGxhYmVsOkxBQkVMX09QVElPTkFMIG51bWJlcjoxIgorICAgICIgICAgICAgICAgdHlwZTpUWVBFX0dST1VQIHR5cGVfbmFtZTogXCJUZXN0R3JvdXBcIiB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBOZXN0ZWRNZXNzYWdlKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBtZXNzYWdlIE5lc3RlZCB7fVxuIgorICAgICIgIG9wdGlvbmFsIE5lc3RlZCB0ZXN0X25lc3RlZCA9IDE7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIG5lc3RlZF90eXBlIHsgbmFtZTogXCJOZXN0ZWRcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcInRlc3RfbmVzdGVkXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgbnVtYmVyOjEiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6IFwiTmVzdGVkXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgTmVzdGVkRW51bSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgZW51bSBOZXN0ZWRFbnVtIHt9XG4iCisgICAgIiAgb3B0aW9uYWwgTmVzdGVkRW51bSB0ZXN0X2VudW0gPSAxO1xuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBlbnVtX3R5cGUgeyBuYW1lOiBcIk5lc3RlZEVudW1cIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcInRlc3RfZW51bVwiIGxhYmVsOkxBQkVMX09QVElPTkFMIG51bWJlcjoxIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOiBcIk5lc3RlZEVudW1cIiB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBFeHRlbnNpb25SYW5nZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgZXh0ZW5zaW9ucyAxMCB0byAxOTtcbiIKKyAgICAiICBleHRlbnNpb25zIDMwIHRvIG1heDtcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6MTAgZW5kOjIwICAgICAgICB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjMwIGVuZDo1MzY4NzA5MTIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgQ29tcG91bmRFeHRlbnNpb25SYW5nZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgZXh0ZW5zaW9ucyAyLCAxNSwgOSB0byAxMSwgMTAwIHRvIG1heCwgMztcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6MiAgIGVuZDozICAgICAgICAgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDoxNSAgZW5kOjE2ICAgICAgICB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjkgICBlbmQ6MTIgICAgICAgIH0iCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6MTAwIGVuZDo1MzY4NzA5MTIgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDozICAgZW5kOjQgICAgICAgICB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBMYXJnZXJNYXhGb3JNZXNzYWdlU2V0V2lyZUZvcm1hdE1lc3NhZ2VzKSB7CisgIC8vIE1lc3NhZ2VzIHVzaW5nIHRoZSBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCBvcHRpb24gY2FuIGFjY2VwdCBsYXJnZXIKKyAgLy8gZXh0ZW5zaW9uIG51bWJlcnMsIGFzIHRoZSBudW1iZXJzIGFyZSBub3QgZW5jb2RlZCBhcyBpbnQzMiBmaWVsZCB2YWx1ZXMKKyAgLy8gcmF0aGVyIHRoYW4gdGFncy4KKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGV4dGVuc2lvbnMgNCB0byBtYXg7XG4iCisgICAgIiAgb3B0aW9uIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gdHJ1ZTtcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDo0IGVuZDogMHg3ZmZmZmZmZiB9IgorICAgICIgIG9wdGlvbnMge1xuIgorICAgICIgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyBcbiIKKyAgICAiICAgICAgbmFtZSB7XG4iCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcIm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XCJcbiIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlXG4iCisgICAgIiAgICAgIH1cbiIKKyAgICAiICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJ0cnVlXCJcbiIKKyAgICAiICAgIH1cbiIKKyAgICAiICB9XG4iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEV4dGVuc2lvbnMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgImV4dGVuZCBFeHRlbmRlZTEgeyBvcHRpb25hbCBpbnQzMiBmb28gPSAxMjsgfVxuIgorICAgICJleHRlbmQgRXh0ZW5kZWUyIHsgcmVwZWF0ZWQgVGVzdE1lc3NhZ2UgYmFyID0gMjI7IH1cbiIsCisKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MTIiCisgICAgIiAgICAgICAgICAgIGV4dGVuZGVlOiBcIkV4dGVuZGVlMVwiIH0gIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiYmFyXCIgbGFiZWw6TEFCRUxfUkVQRUFURUQgbnVtYmVyOjIyIgorICAgICIgICAgICAgICAgICB0eXBlX25hbWU6XCJUZXN0TWVzc2FnZVwiIGV4dGVuZGVlOiBcIkV4dGVuZGVlMlwiIH0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEV4dGVuc2lvbnNJbk1lc3NhZ2VTY29wZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgZXh0ZW5kIEV4dGVuZGVlMSB7IG9wdGlvbmFsIGludDMyIGZvbyA9IDEyOyB9XG4iCisgICAgIiAgZXh0ZW5kIEV4dGVuZGVlMiB7IHJlcGVhdGVkIFRlc3RNZXNzYWdlIGJhciA9IDIyOyB9XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGV4dGVuc2lvbiB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjEyIgorICAgICIgICAgICAgICAgICAgIGV4dGVuZGVlOiBcIkV4dGVuZGVlMVwiIH0iCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTpcImJhclwiIGxhYmVsOkxBQkVMX1JFUEVBVEVEIG51bWJlcjoyMiIKKyAgICAiICAgICAgICAgICAgICB0eXBlX25hbWU6XCJUZXN0TWVzc2FnZVwiIGV4dGVuZGVlOiBcIkV4dGVuZGVlMlwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIE11bHRpcGxlRXh0ZW5zaW9uc09uZUV4dGVuZGVlKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJleHRlbmQgRXh0ZW5kZWUxIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBmb28gPSAxMjtcbiIKKyAgICAiICByZXBlYXRlZCBUZXN0TWVzc2FnZSBiYXIgPSAyMjtcbiIKKyAgICAifVxuIiwKKworICAgICJleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxMiIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiRXh0ZW5kZWUxXCIgfSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJiYXJcIiBsYWJlbDpMQUJFTF9SRVBFQVRFRCBudW1iZXI6MjIiCisgICAgIiAgICAgICAgICAgIHR5cGVfbmFtZTpcIlRlc3RNZXNzYWdlXCIgZXh0ZW5kZWU6IFwiRXh0ZW5kZWUxXCIgfSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgT3B0aW9uYWxPcHRpb25hbExhYmVsUHJvdG8zKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJzeW50YXggPSBcInByb3RvM1wiO1xuIgorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBpbnQzMiBmb28gPSAxO1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDI7XG4iCisgICAgIn1cbiIsCisKKyAgICAic3ludGF4OiBcInByb3RvM1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImJhclwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MiB9IH0iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit0eXBlZGVmIFBhcnNlclRlc3QgUGFyc2VFbnVtVGVzdDsKKworVEVTVF9GKFBhcnNlRW51bVRlc3QsIFNpbXBsZUVudW0pIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgImVudW0gVGVzdEVudW0ge1xuIgorICAgICIgIEZPTyA9IDA7XG4iCisgICAgIn1cbiIsCisKKyAgICAiZW51bV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0RW51bVwiIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkZPT1wiIG51bWJlcjowIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlRW51bVRlc3QsIFZhbHVlcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAiZW51bSBUZXN0RW51bSB7XG4iCisgICAgIiAgRk9PID0gMTM7XG4iCisgICAgIiAgQkFSID0gLTEwO1xuIgorICAgICIgIEJBWiA9IDUwMDtcbiIKKyAgICAiICBIRVhfTUFYID0gMHg3RkZGRkZGRjtcbiIKKyAgICAiICBIRVhfTUlOID0gLTB4ODAwMDAwMDA7XG4iCisgICAgIiAgSU5UX01BWCA9IDIxNDc0ODM2NDc7XG4iCisgICAgIiAgSU5UX01JTiA9IC0yMTQ3NDgzNjQ4O1xuIgorICAgICJ9XG4iLAorCisgICAgImVudW1fdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdEVudW1cIiIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJGT09cIiBudW1iZXI6MTMgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJCQVJcIiBudW1iZXI6LTEwIH0iCisgICAgIiAgdmFsdWUgeyBuYW1lOlwiQkFaXCIgbnVtYmVyOjUwMCB9IgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkhFWF9NQVhcIiBudW1iZXI6MjE0NzQ4MzY0NyB9IgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkhFWF9NSU5cIiBudW1iZXI6LTIxNDc0ODM2NDggfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJJTlRfTUFYXCIgbnVtYmVyOjIxNDc0ODM2NDcgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJJTlRfTUlOXCIgbnVtYmVyOi0yMTQ3NDgzNjQ4IH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlRW51bVRlc3QsIFZhbHVlT3B0aW9ucykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAiZW51bSBUZXN0RW51bSB7XG4iCisgICAgIiAgRk9PID0gMTM7XG4iCisgICAgIiAgQkFSID0gLTEwIFsgKHNvbWV0aGluZy50ZXh0KSA9ICdhYmMnIF07XG4iCisgICAgIiAgQkFaID0gNTAwIFsgKHNvbWV0aGluZy50ZXh0KSA9ICdkZWYnLCBvdGhlciA9IDEgXTtcbiIKKyAgICAifVxuIiwKKworICAgICJlbnVtX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RFbnVtXCIiCisgICAgIiAgdmFsdWUgeyBuYW1lOiBcIkZPT1wiIG51bWJlcjogMTMgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6IFwiQkFSXCIgbnVtYmVyOiAtMTAgIgorICAgICIgICAgb3B0aW9ucyB7ICIKKyAgICAiICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJzb21ldGhpbmcudGV4dFwiIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICBzdHJpbmdfdmFsdWU6IFwiYWJjXCIgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICIgIHZhbHVlIHsgbmFtZTogXCJCQVpcIiBudW1iZXI6IDUwMCAiCisgICAgIiAgICBvcHRpb25zIHsgIgorICAgICIgICAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcInNvbWV0aGluZy50ZXh0XCIgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgIHN0cmluZ192YWx1ZTogXCJkZWZcIiAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcIm90aGVyXCIgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9ICIKKyAgICAiICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICJ9Iik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordHlwZWRlZiBQYXJzZXJUZXN0IFBhcnNlU2VydmljZVRlc3Q7CisKK1RFU1RfRihQYXJzZVNlcnZpY2VUZXN0LCBTaW1wbGVTZXJ2aWNlKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJzZXJ2aWNlIFRlc3RTZXJ2aWNlIHtcbiIKKyAgICAiICBycGMgRm9vKEluKSByZXR1cm5zIChPdXQpO1xuIgorICAgICJ9XG4iLAorCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTpcIkZvb1wiIGlucHV0X3R5cGU6XCJJblwiIG91dHB1dF90eXBlOlwiT3V0XCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VTZXJ2aWNlVGVzdCwgTWV0aG9kc0FuZFN0cmVhbXMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgInNlcnZpY2UgVGVzdFNlcnZpY2Uge1xuIgorICAgICIgIHJwYyBGb28oSW4xKSByZXR1cm5zIChPdXQxKTtcbiIKKyAgICAiICBycGMgQmFyKEluMikgcmV0dXJucyAoT3V0Mik7XG4iCisgICAgIiAgcnBjIEJheihJbjMpIHJldHVybnMgKE91dDMpO1xuIgorICAgICJ9XG4iLAorCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTpcIkZvb1wiIGlucHV0X3R5cGU6XCJJbjFcIiBvdXRwdXRfdHlwZTpcIk91dDFcIiB9IgorICAgICIgIG1ldGhvZCB7IG5hbWU6XCJCYXJcIiBpbnB1dF90eXBlOlwiSW4yXCIgb3V0cHV0X3R5cGU6XCJPdXQyXCIgfSIKKyAgICAiICBtZXRob2QgeyBuYW1lOlwiQmF6XCIgaW5wdXRfdHlwZTpcIkluM1wiIG91dHB1dF90eXBlOlwiT3V0M1wiIH0iCisgICAgIn0iKTsKK30KKworCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGltcG9ydHMgYW5kIHBhY2thZ2VzCisKK3R5cGVkZWYgUGFyc2VyVGVzdCBQYXJzZU1pc2NUZXN0OworCitURVNUX0YoUGFyc2VNaXNjVGVzdCwgUGFyc2VJbXBvcnQpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgImltcG9ydCBcImZvby9iYXIvYmF6LnByb3RvXCI7XG4iLAorICAgICJkZXBlbmRlbmN5OiBcImZvby9iYXIvYmF6LnByb3RvXCIiKTsKK30KKworVEVTVF9GKFBhcnNlTWlzY1Rlc3QsIFBhcnNlTXVsdGlwbGVJbXBvcnRzKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IFwiYmFyLnByb3RvXCI7XG4iCisgICAgImltcG9ydCBcImJhei5wcm90b1wiO1xuIiwKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXoucHJvdG9cIiIpOworfQorCitURVNUX0YoUGFyc2VNaXNjVGVzdCwgUGFyc2VQdWJsaWNJbXBvcnRzKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IHB1YmxpYyBcImJhci5wcm90b1wiO1xuIgorICAgICJpbXBvcnQgXCJiYXoucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IHB1YmxpYyBcInF1eC5wcm90b1wiO1xuIiwKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXoucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJxdXgucHJvdG9cIiIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDEgIgorICAgICJwdWJsaWNfZGVwZW5kZW5jeTogMyAiKTsKK30KKworVEVTVF9GKFBhcnNlTWlzY1Rlc3QsIFBhcnNlUGFja2FnZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAicGFja2FnZSBmb28uYmFyLmJhejtcbiIsCisgICAgInBhY2thZ2U6IFwiZm9vLmJhci5iYXpcIiIpOworfQorCitURVNUX0YoUGFyc2VNaXNjVGVzdCwgUGFyc2VQYWNrYWdlV2l0aFNwYWNlcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAicGFja2FnZSBmb28gICAuICAgYmFyLiAgXG4iCisgICAgIiAgYmF6O1xuIiwKKyAgICAicGFja2FnZTogXCJmb28uYmFyLmJhelwiIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIG9wdGlvbnMKKworVEVTVF9GKFBhcnNlTWlzY1Rlc3QsIFBhcnNlRmlsZU9wdGlvbnMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm9wdGlvbiBqYXZhX3BhY2thZ2UgPSBcImNvbS5nb29nbGUuZm9vXCI7XG4iCisgICAgIm9wdGlvbiBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkU7IiwKKworICAgICJvcHRpb25zIHsiCisgICAgInVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJqYXZhX3BhY2thZ2VcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdfdmFsdWU6IFwiY29tLmdvb2dsZS5mb29cIn0gIgorICAgICJ1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwib3B0aW1pemVfZm9yXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJDT0RFX1NJWkVcIiB9ICIKKyAgICAifSIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBFcnJvciB0ZXN0cworLy8KKy8vIFRoZXJlIGFyZSBhIHZlcnkgbGFyZ2UgbnVtYmVyIG9mIHBvc3NpYmxlIGVycm9ycyB0aGF0IHRoZSBwYXJzZXIgY291bGQKKy8vIHJlcG9ydCwgc28gaXQncyBpbmZlYXNpYmxlIHRvIHRlc3QgZXZlcnkgc2luZ2xlIG9uZSBvZiB0aGVtLiAgSW5zdGVhZCwKKy8vIHdlIHRlc3QgZWFjaCB1bmlxdWUgY2FsbCB0byBBZGRFcnJvcigpIGluIHBhcnNlci5oLiAgVGhpcyBkb2VzIG5vdCBtZWFuCisvLyB3ZSBhcmUgdGVzdGluZyBldmVyeSBwb3NzaWJsZSBlcnJvciB0aGF0IFBhcnNlciBjYW4gZ2VuZXJhdGUgYmVjYXVzZQorLy8gZWFjaCB2YXJpYW50IG9mIHRoZSBDb25zdW1lKCkgaGVscGVyIG9ubHkgY291bnRzIGFzIG9uZSB1bmlxdWUgY2FsbCB0bworLy8gQWRkRXJyb3IoKS4KKwordHlwZWRlZiBQYXJzZXJUZXN0IFBhcnNlRXJyb3JUZXN0OworCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE1pc3NpbmdTeW50YXhJZGVudGlmaWVyKSB7CisgIHJlcXVpcmVfc3ludGF4X2lkZW50aWZpZXJfID0gdHJ1ZTsKKyAgRXhwZWN0SGFzRWFybHlFeGl0RXJyb3JzKCJtZXNzYWdlIFRlc3RNZXNzYWdlIHt9IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICIwOjA6IEZpbGUgbXVzdCBiZWdpbiB3aXRoIGEgc3ludGF4IHN0YXRlbWVudCwgZS5nLiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiJ3N5bnRheCA9IFwicHJvdG8yXCI7Jy5cbiIpOworICBFWFBFQ1RfRVEoIiIsIHBhcnNlcl8tPkdldFN5bnRheElkZW50aWZpZXIoKSk7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgVW5rbm93blN5bnRheElkZW50aWZpZXIpIHsKKyAgRXhwZWN0SGFzRWFybHlFeGl0RXJyb3JzKAorICAgICJzeW50YXggPSBcIm5vX3N1Y2hfc3ludGF4XCI7IiwKKyAgICAiMDo5OiBVbnJlY29nbml6ZWQgc3ludGF4IGlkZW50aWZpZXIgXCJub19zdWNoX3N5bnRheFwiLiAgVGhpcyBwYXJzZXIgIgorICAgICAgIm9ubHkgcmVjb2duaXplcyBcInByb3RvMlwiIGFuZCBcInByb3RvM1wiLlxuIik7CisgIEVYUEVDVF9FUSgibm9fc3VjaF9zeW50YXgiLCBwYXJzZXJfLT5HZXRTeW50YXhJZGVudGlmaWVyKCkpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIFNpbXBsZVN5bnRheEVycm9yKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSBAIyQgeyBibGFoIH0iLAorICAgICIwOjIwOiBFeHBlY3RlZCBcIntcIi5cbiIpOworICBFWFBFQ1RfRVEoInByb3RvMiIsIHBhcnNlcl8tPkdldFN5bnRheElkZW50aWZpZXIoKSk7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRXhwZWN0ZWRUb3BMZXZlbCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgImJsYWg7IiwKKyAgICAiMDowOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIFVubWF0Y2hlZENsb3NlQnJhY2UpIHsKKyAgLy8gVGhpcyB1c2VkIHRvIGNhdXNlIGFuIGluZmluaXRlIGxvb3AuICBEb2guCisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAifSIsCisgICAgIjA6MDogRXhwZWN0ZWQgdG9wLWxldmVsIHN0YXRlbWVudCAoZS5nLiBcIm1lc3NhZ2VcIikuXG4iCisgICAgIjA6MDogVW5tYXRjaGVkIFwifVwiLlxuIik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1lc3NhZ2UgZXJyb3JzCisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWVzc2FnZU1pc3NpbmdOYW1lKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSB7fSIsCisgICAgIjA6ODogRXhwZWN0ZWQgbWVzc2FnZSBuYW1lLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWVzc2FnZU1pc3NpbmdCb2R5KSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZTsiLAorICAgICIwOjE5OiBFeHBlY3RlZCBcIntcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVvZkluTWVzc2FnZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2UgeyIsCisgICAgIjA6MjE6IFJlYWNoZWQgZW5kIG9mIGlucHV0IGluIG1lc3NhZ2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWlzc2luZ0ZpZWxkTnVtYmVyKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgZm9vO1xuIgorICAgICJ9XG4iLAorICAgICIxOjIwOiBNaXNzaW5nIGZpZWxkIG51bWJlci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEV4cGVjdGVkRmllbGROdW1iZXIpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBmb28gPSA7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MjM6IEV4cGVjdGVkIGZpZWxkIG51bWJlci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEZpZWxkTnVtYmVyT3V0T2ZSYW5nZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGZvbyA9IDB4MTAwMDAwMDAwO1xuIgorICAgICJ9XG4iLAorICAgICIxOjIzOiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE1pc3NpbmdMYWJlbCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGludDMyIGZvbyA9IDE7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MjogRXhwZWN0ZWQgXCJyZXF1aXJlZFwiLCBcIm9wdGlvbmFsXCIsIG9yIFwicmVwZWF0ZWRcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEV4cGVjdGVkT3B0aW9uTmFtZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtdO1xuIgorICAgICJ9XG4iLAorICAgICIxOjI3OiBFeHBlY3RlZCBpZGVudGlmaWVyLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTm9uRXh0ZW5zaW9uT3B0aW9uTmFtZUJlZ2lubmluZ1dpdGhEb3QpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCB1aW50MzIgZm9vID0gMSBbLmZvbz0xXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToyNzogRXhwZWN0ZWQgaWRlbnRpZmllci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIERlZmF1bHRWYWx1ZVR5cGVNaXNtYXRjaCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PXRydWVdO1xuIgorICAgICJ9XG4iLAorICAgICIxOjM1OiBFeHBlY3RlZCBpbnRlZ2VyIGZvciBmaWVsZCBkZWZhdWx0IHZhbHVlLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRGVmYXVsdFZhbHVlTm90Qm9vbGVhbikgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGJvb2wgZm9vID0gMSBbZGVmYXVsdD1ibGFoXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozMzogRXhwZWN0ZWQgXCJ0cnVlXCIgb3IgXCJmYWxzZVwiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRGVmYXVsdFZhbHVlTm90U3RyaW5nKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDEgW2RlZmF1bHQ9MV07XG4iCisgICAgIn1cbiIsCisgICAgIjE6MzU6IEV4cGVjdGVkIHN0cmluZyBmb3IgZmllbGQgZGVmYXVsdCB2YWx1ZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIERlZmF1bHRWYWx1ZVVuc2lnbmVkTmVnYXRpdmUpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCB1aW50MzIgZm9vID0gMSBbZGVmYXVsdD0tMV07XG4iCisgICAgIn1cbiIsCisgICAgIjE6MzY6IFVuc2lnbmVkIGZpZWxkIGNhbid0IGhhdmUgbmVnYXRpdmUgZGVmYXVsdCB2YWx1ZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIERlZmF1bHRWYWx1ZVRvb0xhcmdlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgIGZvbyA9IDEgW2RlZmF1bHQ9IDB4ODAwMDAwMDBdO1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyICBmb28gPSAxIFtkZWZhdWx0PS0weDgwMDAwMDAxXTtcbiIKKyAgICAiICBvcHRpb25hbCB1aW50MzIgZm9vID0gMSBbZGVmYXVsdD0gMHgxMDAwMDAwMDBdO1xuIgorICAgICIgIG9wdGlvbmFsIGludDY0ICBmb28gPSAxIFtkZWZhdWx0PSAweDgwMDAwMDAwMDAwMDAwMDAwXTtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQ2NCAgZm9vID0gMSBbZGVmYXVsdD0tMHg4MDAwMDAwMDAwMDAwMDAwMV07XG4iCisgICAgIiAgb3B0aW9uYWwgdWludDY0IGZvbyA9IDEgW2RlZmF1bHQ9IDB4MTAwMDAwMDAwMDAwMDAwMDAwXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozNjogSW50ZWdlciBvdXQgb2YgcmFuZ2UuXG4iCisgICAgIjI6MzY6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIgorICAgICIzOjM2OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIKKyAgICAiNDozNjogSW50ZWdlciBvdXQgb2YgcmFuZ2UuXG4iCisgICAgIjU6MzY6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIgorICAgICI2OjM2OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVudW1WYWx1ZU91dE9mUmFuZ2UpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIFRlc3RFbnVtIHtcbiIKKyAgICAiICBIRVhfVE9PX0JJRyAgID0gIDB4ODAwMDAwMDA7XG4iCisgICAgIiAgSEVYX1RPT19TTUFMTCA9IC0weDgwMDAwMDAxO1xuIgorICAgICIgIElOVF9UT09fQklHICAgPSAgMjE0NzQ4MzY0ODtcbiIKKyAgICAiICBJTlRfVE9PX1NNQUxMID0gLTIxNDc0ODM2NDk7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MTk6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIgorICAgICIyOjE5OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIKKyAgICAiMzoxOTogSW50ZWdlciBvdXQgb2YgcmFuZ2UuXG4iCisgICAgIjQ6MTk6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRGVmYXVsdFZhbHVlTWlzc2luZykgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PV07XG4iCisgICAgIn1cbiIsCisgICAgIjE6MzU6IEV4cGVjdGVkIGludGVnZXIgZm9yIGZpZWxkIGRlZmF1bHQgdmFsdWUuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBEZWZhdWx0VmFsdWVGb3JHcm91cCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGdyb3VwIEZvbyA9IDEgW2RlZmF1bHQ9YmxhaF0ge31cbiIKKyAgICAifVxuIiwKKyAgICAiMTozNDogTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0IHZhbHVlcy5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIER1cGxpY2F0ZURlZmF1bHRWYWx1ZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PTEsZGVmYXVsdD0yXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozNzogQWxyZWFkeSBzZXQgb3B0aW9uIFwiZGVmYXVsdFwiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWlzc2luZ09uZW9mTmFtZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9uZW9mIHtcbiIKKyAgICAiICAgIGludDMyIGJhciA9IDE7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iLAorICAgICIxOjg6IEV4cGVjdGVkIG9uZW9mIG5hbWUuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBMYWJlbEluT25lb2YpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvbmVvZiBmb28ge1xuIgorICAgICIgICAgb3B0aW9uYWwgaW50MzIgYmFyID0gMTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIsCisgICAgIjI6NDogRmllbGRzIGluIG9uZW9mcyBtdXN0IG5vdCBoYXZlIGxhYmVscyAocmVxdWlyZWQgLyBvcHRpb25hbCAiCisgICAgICAiLyByZXBlYXRlZCkuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBNYXBJbk9uZW9mKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb25lb2YgZm9vIHtcbiIKKyAgICAiICAgIG1hcDxpbnQzMiwgaW50MzI+IGZvb19tYXAgPSAxO1xuIgorICAgICIgICAgbWFwIG1lc3NhZ2VfZmllbGQgPSAyO1xuIiAgLy8gYSBub3JtYWwgbWVzc2FnZSBmaWVsZCBpcyBPSworICAgICIgIH1cbiIKKyAgICAifVxuIiwKKyAgICAiMjo3OiBNYXAgZmllbGRzIGFyZSBub3QgYWxsb3dlZCBpbiBvbmVvZnMuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBMYWJlbEZvck1hcCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIG1hcDxpbnQzMiwgaW50MzI+IGludF9tYXAgPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIG1hcDxpbnQzMiwgaW50MzI+IGludF9tYXAyID0gMjtcbiIKKyAgICAiICByZXBlYXRlZCBtYXA8aW50MzIsIGludDMyPiBpbnRfbWFwMyA9IDM7XG4iCisgICAgIiAgb3B0aW9uYWwgbWFwIG1hcF9tZXNzYWdlID0gNDtcbiIgIC8vIGEgbm9ybWFsIG1lc3NhZ2UgZmllbGQgaXMgT0sKKyAgICAifVxuIiwKKyAgICAiMToxNDogRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uIG1hcCAiCisgICAgImZpZWxkcy5cbiIKKyAgICAiMjoxNDogRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uIG1hcCAiCisgICAgImZpZWxkcy5cbiIKKyAgICAiMzoxNDogRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uIG1hcCAiCisgICAgImZpZWxkcy5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE1hbGZvcm1lZE1hcHMpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBtYXAgbWFwX21lc3NhZ2UgPSAxO1xuIiAgIC8vIGEgbm9ybWFsIG1lc3NhZ2UgZmllbGQgbGFja2luZyBsYWJlbAorICAgICIgIG1hcDxzdHJpbmc+IHN0cl9tYXAgPSAyO1xuIgorICAgICIgIG1hcDxzdHJpbmcsPiBzdHJfbWFwMiA9IDM7XG4iCisgICAgIiAgbWFwPCxzdHJpbmc+IHN0cl9tYXAzID0gNDtcbiIKKyAgICAiICBtYXA8PiBlbXB0eV9tYXAgPSA1O1xuIgorICAgICIgIG1hcDxzdHJpbmcsc3RyaW5nIHN0cl9tYXA2ID0gNjtcbiIKKyAgICAifSIKKyAgICAiZXh0ZW5kIFNvbWVNZXNzYWdlIHtcbiIKKyAgICAiICBtYXA8aW50MzIsIGludDMyPiBpbnRfbWFwID0gMTtcbiIKKyAgICAifSIsCisgICAgIjE6NjogRXhwZWN0ZWQgXCJyZXF1aXJlZFwiLCBcIm9wdGlvbmFsXCIsIG9yIFwicmVwZWF0ZWRcIi5cbiIKKyAgICAiMjoxMjogRXhwZWN0ZWQgXCIsXCIuXG4iCisgICAgIjM6MTM6IEV4cGVjdGVkIHR5cGUgbmFtZS5cbiIKKyAgICAiNDo2OiBFeHBlY3RlZCB0eXBlIG5hbWUuXG4iCisgICAgIjU6NjogRXhwZWN0ZWQgdHlwZSBuYW1lLlxuIgorICAgICI2OjIwOiBFeHBlY3RlZCBcIj5cIi5cbiIKKyAgICAiODo1OiBNYXAgZmllbGRzIGFyZSBub3QgYWxsb3dlZCB0byBiZSBleHRlbnNpb25zLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgR3JvdXBOb3RDYXBpdGFsaXplZCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGdyb3VwIGZvbyA9IDEge31cbiIKKyAgICAifVxuIiwKKyAgICAiMToxNzogR3JvdXAgbmFtZXMgbXVzdCBzdGFydCB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBHcm91cE1pc3NpbmdCb2R5KSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgZ3JvdXAgRm9vID0gMTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToyNDogTWlzc2luZyBncm91cCBib2R5LlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRXh0ZW5kaW5nUHJpbWl0aXZlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAiZXh0ZW5kIGludDMyIHsgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDQ7IH1cbiIsCisgICAgIjA6NzogRXhwZWN0ZWQgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRXJyb3JJbkV4dGVuc2lvbikgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHsgZXh0ZW5zaW9ucyAxMDAgdG8gMTk5OyB9XG4iCisgICAgImV4dGVuZCBGb28geyBvcHRpb25hbCBzdHJpbmcgZm9vOyB9XG4iLAorICAgICIxOjMyOiBNaXNzaW5nIGZpZWxkIG51bWJlci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE11bHRpcGxlUGFyc2VFcnJvcnMpIHsKKyAgLy8gV2hlbiBhIHN0YXRlbWVudCBoYXMgYSBwYXJzZSBlcnJvciwgdGhlIHBhcnNlciBzaG91bGQgYmUgYWJsZSB0byBjb250aW51ZQorICAvLyBwYXJzaW5nIGF0IHRoZSBuZXh0IHN0YXRlbWVudC4KKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBmb287XG4iCisgICAgIiAgIWludmFsaWQgc3RhdGVtZW50IGVuZGluZyBpbiBhIGJsb2NrIHsgYmxhaCBibGFoIHsgYmxhaCB9IGJsYWggfVxuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDMge31cbiIKKyAgICAifVxuIiwKKyAgICAiMToyMDogTWlzc2luZyBmaWVsZCBudW1iZXIuXG4iCisgICAgIjI6MjogRXhwZWN0ZWQgXCJyZXF1aXJlZFwiLCBcIm9wdGlvbmFsXCIsIG9yIFwicmVwZWF0ZWRcIi5cbiIKKyAgICAiMjoyOiBFeHBlY3RlZCB0eXBlIG5hbWUuXG4iCisgICAgIjM6MjU6IEV4cGVjdGVkIFwiO1wiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRW9mSW5BZ2dyZWdhdGVWYWx1ZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgICAib3B0aW9uIChmaWxlb3B0KSA9IHsgaToxMDBcbiIsCisgICAgICAiMTowOiBVbmV4cGVjdGVkIGVuZCBvZiBzdHJlYW0gd2hpbGUgcGFyc2luZyBhZ2dyZWdhdGUgdmFsdWUuXG4iKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRW51bSBlcnJvcnMKKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBFb2ZJbkVudW0pIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIFRlc3RFbnVtIHsiLAorICAgICIwOjE1OiBSZWFjaGVkIGVuZCBvZiBpbnB1dCBpbiBlbnVtIGRlZmluaXRpb24gKG1pc3NpbmcgJ30nKS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVudW1WYWx1ZU1pc3NpbmdOdW1iZXIpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIFRlc3RFbnVtIHtcbiIKKyAgICAiICBGT087XG4iCisgICAgIn1cbiIsCisgICAgIjE6NTogTWlzc2luZyBudW1lcmljIHZhbHVlIGZvciBlbnVtIGNvbnN0YW50LlxuIik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNlcnZpY2UgZXJyb3JzCisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRW9mSW5TZXJ2aWNlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAic2VydmljZSBUZXN0U2VydmljZSB7IiwKKyAgICAiMDoyMTogUmVhY2hlZCBlbmQgb2YgaW5wdXQgaW4gc2VydmljZSBkZWZpbml0aW9uIChtaXNzaW5nICd9JykuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBTZXJ2aWNlTWV0aG9kUHJpbWl0aXZlUGFyYW1zKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAic2VydmljZSBUZXN0U2VydmljZSB7XG4iCisgICAgIiAgcnBjIEZvbyhpbnQzMikgcmV0dXJucyAoc3RyaW5nKTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToxMDogRXhwZWN0ZWQgbWVzc2FnZSB0eXBlLlxuIgorICAgICIxOjI2OiBFeHBlY3RlZCBtZXNzYWdlIHR5cGUuXG4iKTsKK30KKworCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVvZkluTWV0aG9kT3B0aW9ucykgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgInNlcnZpY2UgVGVzdFNlcnZpY2Uge1xuIgorICAgICIgIHJwYyBGb28oQmFyKSByZXR1cm5zKEJhcikgeyIsCisgICAgIjE6Mjk6IFJlYWNoZWQgZW5kIG9mIGlucHV0IGluIG1ldGhvZCBvcHRpb25zIChtaXNzaW5nICd9JykuXG4iCisgICAgIjE6Mjk6IFJlYWNoZWQgZW5kIG9mIGlucHV0IGluIHNlcnZpY2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLlxuIik7Cit9CisKKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBQcmltaXRpdmVNZXRob2RJbnB1dCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgInNlcnZpY2UgVGVzdFNlcnZpY2Uge1xuIgorICAgICIgIHJwYyBGb28oaW50MzIpIHJldHVybnMoQmFyKTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToxMDogRXhwZWN0ZWQgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBNZXRob2RPcHRpb25UeXBlRXJyb3IpIHsKKyAgLy8gVGhpcyB1c2VkIHRvIGNhdXNlIGFuIGluZmluaXRlIGxvb3AuCisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBCYXoge31cbiIKKyAgICAic2VydmljZSBGb28ge1xuIgorICAgICIgIHJwYyBCYXIoQmF6KSByZXR1cm5zKEJheikgeyBvcHRpb24gaW52YWxpZCBzeW50YXg7IH1cbiIKKyAgICAifVxuIiwKKyAgICAiMjo0NTogRXhwZWN0ZWQgXCI9XCIuXG4iKTsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBJbXBvcnQgYW5kIHBhY2thZ2UgZXJyb3JzCisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgSW1wb3J0Tm90UXVvdGVkKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAiaW1wb3J0IGZvbztcbiIsCisgICAgIjA6NzogRXhwZWN0ZWQgYSBzdHJpbmcgbmFtaW5nIHRoZSBmaWxlIHRvIGltcG9ydC5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE11bHRpcGxlUGFja2FnZXNJbkZpbGUpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJwYWNrYWdlIGZvbztcbiIKKyAgICAicGFja2FnZSBiYXI7XG4iLAorICAgICIxOjA6IE11bHRpcGxlIHBhY2thZ2UgZGVmaW5pdGlvbnMuXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gVGVzdCB0aGF0IGVycm9ycyBkZXRlY3RlZCBieSBEZXNjcmlwdG9yUG9vbCBjb3JyZWN0bHkgcmVwb3J0IGxpbmUgYW5kCisvLyBjb2x1bW4gbnVtYmVycy4gIFdlIGhhdmUgb25lIHRlc3QgZm9yIGV2ZXJ5IGNhbGwgdG8gUmVjb3JkTG9jYXRpb24oKSBpbgorLy8gcGFyc2VyLmNjLgorCit0eXBlZGVmIFBhcnNlclRlc3QgUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdDsKKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIFBhY2thZ2VOYW1lRXJyb3IpIHsKKyAgLy8gQ3JlYXRlIGFub3RoZXIgZmlsZSB3aGljaCBkZWZpbmVzIHN5bWJvbCAiZm9vIi4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBvdGhlcl9maWxlOworICBvdGhlcl9maWxlLnNldF9uYW1lKCJiYXIucHJvdG8iKTsKKyAgb3RoZXJfZmlsZS5hZGRfbWVzc2FnZV90eXBlKCktPnNldF9uYW1lKCJmb28iKTsKKyAgRVhQRUNUX1RSVUUocG9vbF8uQnVpbGRGaWxlKG90aGVyX2ZpbGUpICE9IE5VTEwpOworCisgIC8vIE5vdyB0cnkgdG8gZGVmaW5lIGl0IGFzIGEgcGFja2FnZS4KKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAicGFja2FnZSBmb28uYmFyOyIsCisgICAgIjA6ODogXCJmb29cIiBpcyBhbHJlYWR5IGRlZmluZWQgKGFzIHNvbWV0aGluZyBvdGhlciB0aGFuIGEgcGFja2FnZSkgIgorICAgICAgImluIGZpbGUgXCJiYXIucHJvdG9cIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgTWVzc2FnZU5hbWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJtZXNzYWdlIEZvbyB7fVxuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIiwKKyAgICAiMTo4OiBcIkZvb1wiIGlzIGFscmVhZHkgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGROYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDE7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgYmFyID0gMjtcbiIKKyAgICAifVxuIiwKKyAgICAiMjoxNzogXCJiYXJcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gXCJGb29cIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIG9wdGlvbmFsIEJheiBiYXIgPSAxO1xuIgorICAgICJ9XG4iLAorICAgICIxOjExOiBcIkJhelwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZE51bWJlckVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBiYXIgPSAwO1xuIgorICAgICJ9XG4iLAorICAgICIxOjIzOiBGaWVsZCBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkRXh0ZW5kZWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJleHRlbmQgQmF6IHsgb3B0aW9uYWwgaW50MzIgYmFyID0gMTsgfVxuIiwKKyAgICAiMDo3OiBcIkJhelwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZERlZmF1bHRWYWx1ZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgImVudW0gQmF6IHsgUVVYID0gMTsgfVxuIgorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgb3B0aW9uYWwgQmF6IGJhciA9IDEgW2RlZmF1bHQ9Tk9fU1VDSF9WQUxVRV07XG4iCisgICAgIn1cbiIsCisgICAgIjI6MzI6IEVudW0gdHlwZSBcIkJhelwiIGhhcyBubyB2YWx1ZSBuYW1lZCBcIk5PX1NVQ0hfVkFMVUVcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmlsZU9wdGlvbk5hbWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJvcHRpb24gZm9vID0gNTsiLAorICAgICIwOjc6IE9wdGlvbiBcImZvb1wiIHVua25vd24uXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEZpbGVPcHRpb25WYWx1ZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm9wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9IDU7IiwKKyAgICAiMDozMDogVmFsdWUgbXVzdCBiZSBxdW90ZWQgc3RyaW5nIGZvciBzdHJpbmcgb3B0aW9uICIKKyAgICAiXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWVcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRPcHRpb25OYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIG9wdGlvbmFsIGJvb2wgYmFyID0gMSBbZm9vPTFdO1xuIgorICAgICJ9XG4iLAorICAgICIxOjI1OiBPcHRpb24gXCJmb29cIiB1bmtub3duLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZE9wdGlvblZhbHVlRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDEgW2N0eXBlPTFdO1xuIgorICAgICJ9XG4iLAorICAgICIxOjMyOiBWYWx1ZSBtdXN0IGJlIGlkZW50aWZpZXIgZm9yIGVudW0tdmFsdWVkIG9wdGlvbiAiCisgICAgIlwiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5jdHlwZVwiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBFeHRlbnNpb25SYW5nZU51bWJlckVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBleHRlbnNpb25zIDA7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MTM6IEV4dGVuc2lvbiBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1OYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAiZW51bSBGb28ge0EgPSAxO31cbiIKKyAgICAiZW51bSBGb28ge0IgPSAxO31cbiIsCisgICAgIjE6NTogXCJGb29cIiBpcyBhbHJlYWR5IGRlZmluZWQuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1WYWx1ZU5hbWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJlbnVtIEZvbyB7XG4iCisgICAgIiAgQkFSID0gMTtcbiIKKyAgICAiICBCQVIgPSAxO1xuIgorICAgICJ9XG4iLAorICAgICIyOjI6IFwiQkFSXCIgaXMgYWxyZWFkeSBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBTZXJ2aWNlTmFtZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgInNlcnZpY2UgRm9vIHt9XG4iCisgICAgInNlcnZpY2UgRm9vIHt9XG4iLAorICAgICIxOjg6IFwiRm9vXCIgaXMgYWxyZWFkeSBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBNZXRob2ROYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBCYXoge31cbiIKKyAgICAic2VydmljZSBGb28ge1xuIgorICAgICIgIHJwYyBCYXIoQmF6KSByZXR1cm5zKEJheik7XG4iCisgICAgIiAgcnBjIEJhcihCYXopIHJldHVybnMoQmF6KTtcbiIKKyAgICAifVxuIiwKKyAgICAiMzo2OiBcIkJhclwiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiBcIkZvb1wiLlxuIik7Cit9CisKKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIE1ldGhvZElucHV0VHlwZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgQmF6IHt9XG4iCisgICAgInNlcnZpY2UgRm9vIHtcbiIKKyAgICAiICBycGMgQmFyKFF1eCkgcmV0dXJucyhCYXopO1xuIgorICAgICJ9XG4iLAorICAgICIyOjEwOiBcIlF1eFwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIE1ldGhvZE91dHB1dFR5cGVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJtZXNzYWdlIEJheiB7fVxuIgorICAgICJzZXJ2aWNlIEZvbyB7XG4iCisgICAgIiAgcnBjIEJhcihCYXopIHJldHVybnMoUXV4KTtcbiIKKyAgICAifVxuIiwKKyAgICAiMjoyMzogXCJRdXhcIiBpcyBub3QgZGVmaW5lZC5cbiIpOworfQorCisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZXNvdmxlZFVuZGVmaW5lZEVycm9yKSB7CisgIC8vIENyZWF0ZSBhbm90aGVyIGZpbGUgd2hpY2ggZGVmaW5lcyBzeW1ib2wgIi5iYXNlLmJhciIuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gb3RoZXJfZmlsZTsKKyAgb3RoZXJfZmlsZS5zZXRfbmFtZSgiYmFzZS5wcm90byIpOworICBvdGhlcl9maWxlLnNldF9wYWNrYWdlKCJiYXNlIik7CisgIG90aGVyX2ZpbGUuYWRkX21lc3NhZ2VfdHlwZSgpLT5zZXRfbmFtZSgiYmFyIik7CisgIEVYUEVDVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShvdGhlcl9maWxlKSAhPSBOVUxMKTsKKworICAvLyBEZWZpbmUgImZvby5iYXNlIiBhbmQgdHJ5ICJiYXNlLmJhciIuCisgIC8vICJiYXNlLmJhciIgaXMgcmVzb2x2ZWQgdG8gImZvby5iYXNlLmJhciIgd2hpY2ggaXMgbm90IGRlZmluZWQuCisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgInBhY2thZ2UgZm9vLmJhc2U7XG4iCisgICAgImltcG9ydCBcImJhc2UucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBxdXgge1xuIgorICAgICIgIG9wdGlvbmFsIGJhc2UuYmFyIGJheiA9IDE7XG4iCisgICAgIiAgb3B0aW9uYWwgLmJhc2UuYmFyIHF1eiA9IDI7XG4iCisgICAgIn1cbiIsCisgICAgIjM6MTE6IFwiYmFzZS5iYXJcIiBpcyByZXNvbHZlZCB0byBcImZvby5iYXNlLmJhclwiLCIKKyAgICAiIHdoaWNoIGlzIG5vdCBkZWZpbmVkLiBUaGUgaW5uZXJtb3N0IHNjb3BlIGlzIHNlYXJjaGVkIGZpcnN0ICIKKyAgICAiaW4gbmFtZSByZXNvbHV0aW9uLiBDb25zaWRlciB1c2luZyBhIGxlYWRpbmcgJy4nKGkuZS4sIFwiLmJhc2UuYmFyXCIpIgorICAgICIgdG8gc3RhcnQgZnJvbSB0aGUgb3V0ZXJtb3N0IHNjb3BlLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZXNvdmxlZFVuZGVmaW5lZE9wdGlvbkVycm9yKSB7CisgIC8vIEJ1aWxkIGRlc2NyaXB0b3IgbWVzc2FnZSBpbiB0ZXN0IHBvb2wKKyAgRmlsZURlc2NyaXB0b3JQcm90byBkZXNjcmlwdG9yX3Byb3RvOworICBEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oJmRlc2NyaXB0b3JfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUoZGVzY3JpcHRvcl9wcm90bykgIT0gTlVMTCk7CisKKyAgLy8gYmFzZTIucHJvdG86CisgIC8vICAgcGFja2FnZSBiYXoKKyAgLy8gICBpbXBvcnQgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KKyAgLy8gICBtZXNzYWdlIEJhciB7IG9wdGlvbmFsIGludDMyIGZvbyA9IDE7IH0KKyAgLy8gICBleHRlbmQgRmlsZU9wdGlvbnMgeyBvcHRpb25hbCBCYXIgYmFyID0gNzY3Mjc1NzsgfQorICBGaWxlRGVzY3JpcHRvclByb3RvIG90aGVyX2ZpbGU7CisgIG90aGVyX2ZpbGUuc2V0X25hbWUoImJhc2UyLnByb3RvIik7CisgIG90aGVyX2ZpbGUuc2V0X3BhY2thZ2UoImJheiIpOworICBvdGhlcl9maWxlLmFkZF9kZXBlbmRlbmN5KCk7CisgIG90aGVyX2ZpbGUuc2V0X2RlcGVuZGVuY3koMCwgZGVzY3JpcHRvcl9wcm90by5uYW1lKCkpOworCisgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZShvdGhlcl9maWxlLmFkZF9tZXNzYWdlX3R5cGUoKSk7CisgIG1lc3NhZ2UtPnNldF9uYW1lKCJCYXIiKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkKG1lc3NhZ2UtPmFkZF9maWVsZCgpKTsKKyAgZmllbGQtPnNldF9uYW1lKCJmb28iKTsKKyAgZmllbGQtPnNldF9udW1iZXIoMSk7CisgIGZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfT1BUSU9OQUwpOworICBmaWVsZC0+c2V0X3R5cGUoRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0lOVDMyKTsKKworICBGaWVsZERlc2NyaXB0b3JQcm90byogZXh0ZW5zaW9uKG90aGVyX2ZpbGUuYWRkX2V4dGVuc2lvbigpKTsKKyAgZXh0ZW5zaW9uLT5zZXRfbmFtZSgiYmFyIik7CisgIGV4dGVuc2lvbi0+c2V0X251bWJlcig3NjcyNzU3KTsKKyAgZXh0ZW5zaW9uLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfT1BUSU9OQUwpOworICBleHRlbnNpb24tPnNldF90eXBlKEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9NRVNTQUdFKTsKKyAgZXh0ZW5zaW9uLT5zZXRfdHlwZV9uYW1lKCJCYXIiKTsKKyAgZXh0ZW5zaW9uLT5zZXRfZXh0ZW5kZWUoImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyIpOworCisgIEVYUEVDVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShvdGhlcl9maWxlKSAhPSBOVUxMKTsKKworICAvLyBxdXgucHJvdG86CisgIC8vICAgcGFja2FnZSBxdXguYmF6CisgIC8vICAgb3B0aW9uIChiYXouYmFyKS5mb28gPSAxOworICAvLworICAvLyBBbHRob3VnaCAiYmF6LmJhciIgaXMgYWxyZWFkeSBkZWZpbmVkLCB0aGUgbG9va3VwIGNvZGUgd2lsbCB0cnkKKyAgLy8gInF1eC5iYXouYmFyIiwgc2luY2UgaXQncyB0aGUgbWF0Y2ggZnJvbSB0aGUgaW5uZXJtb3N0IHNjb3BlLAorICAvLyB3aGljaCB3aWxsIGNhdXNlIGEgc3ltYm9sIG5vdCBkZWZpbmVkIGVycm9yLgorICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICAgInBhY2thZ2UgcXV4LmJhejtcbiIKKyAgICAgICJpbXBvcnQgXCJiYXNlMi5wcm90b1wiO1xuIgorICAgICAgIm9wdGlvbiAoYmF6LmJhcikuZm9vID0gMTtcbiIsCisgICAgICAiMjo3OiBPcHRpb24gXCIoYmF6LmJhcilcIiBpcyByZXNvbHZlZCB0byBcIihxdXguYmF6LmJhcilcIiwiCisgICAgICAiIHdoaWNoIGlzIG5vdCBkZWZpbmVkLiBUaGUgaW5uZXJtb3N0IHNjb3BlIGlzIHNlYXJjaGVkIGZpcnN0ICIKKyAgICAgICJpbiBuYW1lIHJlc29sdXRpb24uIENvbnNpZGVyIHVzaW5nIGEgbGVhZGluZyAnLicoaS5lLiwgXCIoLmJhei5iYXIpXCIpIgorICAgICAgIiB0byBzdGFydCBmcm9tIHRoZSBvdXRlcm1vc3Qgc2NvcGUuXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gVGVzdCB0aGF0IHRoZSBvdXRwdXQgZnJvbSBGaWxlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKSAoYW5kIGFsbCBvdGhlcgorLy8gZGVzY3JpcHRvciB0eXBlcykgaXMgcGFyc2VhYmxlLCBhbmQgcmVzdWx0cyBpbiB0aGUgc2FtZSBEZXNjcmlwdG9yCisvLyBkZWZpbml0aW9ucyBhZ2FpbiBhZm90ZXIgcGFyc2luZyAobm90ZSwgaG93ZXZlciwgdGhhdCB0aGUgb3JkZXIgb2YgbWVzc2FnZXMKKy8vIGNhbm5vdCBiZSBndWFyYW50ZWVkIHRvIGJlIHRoZSBzYW1lKQorCit0eXBlZGVmIFBhcnNlclRlc3QgUGFyc2VEZXNjcmlwdG9yRGVidWdUZXN0OworCitjbGFzcyBDb21wYXJlRGVzY3JpcHRvck5hbWVzIHsKKyBwdWJsaWM6CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBEZXNjcmlwdG9yUHJvdG8qIGxlZnQsCisgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUHJvdG8qIHJpZ2h0KSBjb25zdCB7CisgICAgcmV0dXJuIGxlZnQtPm5hbWUoKSA8IHJpZ2h0LT5uYW1lKCk7CisgIH0KK307CisKKy8vIFNvcnRzIG5lc3RlZCBEZXNjcmlwdG9yUHJvdG9zIG9mIGEgRGVzY3JpcHRvUHJvdG8sIGJ5IG5hbWUuCit2b2lkIFNvcnRNZXNzYWdlcyhEZXNjcmlwdG9yUHJvdG8gKmRlc2NyaXB0b3JfcHJvdG8pIHsKKyAgaW50IHNpemUgPSBkZXNjcmlwdG9yX3Byb3RvLT5uZXN0ZWRfdHlwZV9zaXplKCk7CisgIC8vIHJlY3Vyc2l2ZWx5IHNvcnQ7IHdlIGNhbid0IGd1YXJhbnRlZSB0aGUgb3JkZXIgb2YgbmVzdGVkIG1lc3NhZ2VzIGVpdGhlcgorICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgeworICAgIFNvcnRNZXNzYWdlcyhkZXNjcmlwdG9yX3Byb3RvLT5tdXRhYmxlX25lc3RlZF90eXBlKGkpKTsKKyAgfQorICBEZXNjcmlwdG9yUHJvdG8gKipkYXRhID0KKyAgICBkZXNjcmlwdG9yX3Byb3RvLT5tdXRhYmxlX25lc3RlZF90eXBlKCktPm11dGFibGVfZGF0YSgpOworICBzdGQ6OnNvcnQoZGF0YSwgZGF0YSArIHNpemUsIENvbXBhcmVEZXNjcmlwdG9yTmFtZXMoKSk7Cit9CisKKy8vIFNvcnRzIERlc2NyaXB0b3JQcm90b3MgYmVsb25naW5nIHRvIGEgRmlsZURlc2NyaXB0b3JQcm90bywgYnkgbmFtZS4KK3ZvaWQgU29ydE1lc3NhZ2VzKEZpbGVEZXNjcmlwdG9yUHJvdG8gKmZpbGVfZGVzY3JpcHRvcl9wcm90bykgeworICBpbnQgc2l6ZSA9IGZpbGVfZGVzY3JpcHRvcl9wcm90by0+bWVzc2FnZV90eXBlX3NpemUoKTsKKyAgLy8gcmVjdXJzaXZlbHkgc29ydDsgd2UgY2FuJ3QgZ3VhcmFudGVlIHRoZSBvcmRlciBvZiBuZXN0ZWQgbWVzc2FnZXMgZWl0aGVyCisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7CisgICAgU29ydE1lc3NhZ2VzKGZpbGVfZGVzY3JpcHRvcl9wcm90by0+bXV0YWJsZV9tZXNzYWdlX3R5cGUoaSkpOworICB9CisgIERlc2NyaXB0b3JQcm90byAqKmRhdGEgPQorICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by0+bXV0YWJsZV9tZXNzYWdlX3R5cGUoKS0+bXV0YWJsZV9kYXRhKCk7CisgIHN0ZDo6c29ydChkYXRhLCBkYXRhICsgc2l6ZSwgQ29tcGFyZURlc2NyaXB0b3JOYW1lcygpKTsKK30KKworLy8gU3RyaXBzIHRoZSBtZXNzYWdlIGFuZCBlbnVtIGZpZWxkIHR5cGUgbmFtZXMgZm9yIGNvbXBhcmlzb24gcHVycG9zZSBvbmx5Lgordm9pZCBTdHJpcEZpZWxkVHlwZU5hbWUoRGVzY3JpcHRvclByb3RvKiBwcm90bykgeworICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLT5maWVsZF9zaXplKCk7ICsraSkgeworICAgIHN0cmluZyB0eXBlX25hbWUgPSBwcm90by0+ZmllbGQoaSkudHlwZV9uYW1lKCk7CisgICAgc3RyaW5nOjpzaXplX3R5cGUgcG9zID0gdHlwZV9uYW1lLmZpbmRfbGFzdF9vZigiLiIpOworICAgIGlmIChwb3MgIT0gc3RyaW5nOjpucG9zKSB7CisgICAgICBwcm90by0+bXV0YWJsZV9maWVsZChpKS0+bXV0YWJsZV90eXBlX25hbWUoKS0+YXNzaWduKAorICAgICAgICAgIHR5cGVfbmFtZS5iZWdpbigpICsgcG9zICsgMSwgdHlwZV9uYW1lLmVuZCgpKTsKKyAgICB9CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by0+bmVzdGVkX3R5cGVfc2l6ZSgpOyArK2kpIHsKKyAgICBTdHJpcEZpZWxkVHlwZU5hbWUocHJvdG8tPm11dGFibGVfbmVzdGVkX3R5cGUoaSkpOworICB9Cit9CisKK3ZvaWQgU3RyaXBGaWVsZFR5cGVOYW1lKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGVfcHJvdG8pIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlX3Byb3RvLT5tZXNzYWdlX3R5cGVfc2l6ZSgpOyArK2kpIHsKKyAgICBTdHJpcEZpZWxkVHlwZU5hbWUoZmlsZV9wcm90by0+bXV0YWJsZV9tZXNzYWdlX3R5cGUoaSkpOworICB9Cit9CisKK1RFU1RfRihQYXJzZURlc2NyaXB0b3JEZWJ1Z1Rlc3QsIFRlc3RBbGxEZXNjcmlwdG9yVHlwZXMpIHsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIG9yaWdpbmFsX2ZpbGUgPQorICAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCktPmZpbGUoKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBleHBlY3RlZDsKKyAgb3JpZ2luYWxfZmlsZS0+Q29weVRvKCZleHBlY3RlZCk7CisKKyAgLy8gR2V0IHRoZSBEZWJ1Z1N0cmluZyBvZiB0aGUgdW5pdHRlc3QucHJvdG8gRmlsZURlY3JpcHRvciwgd2hpY2ggaW5jbHVkZXMKKyAgLy8gYWxsIG90aGVyIGRlc2NyaXB0b3IgdHlwZXMKKyAgc3RyaW5nIGRlYnVnX3N0cmluZyA9IG9yaWdpbmFsX2ZpbGUtPkRlYnVnU3RyaW5nKCk7CisKKyAgLy8gUGFyc2UgdGhlIGRlYnVnIHN0cmluZworICBTZXR1cFBhcnNlcihkZWJ1Z19zdHJpbmcuY19zdHIoKSk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gcGFyc2VkOworICBwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZwYXJzZWQpOworICBFWFBFQ1RfRVEoaW86OlRva2VuaXplcjo6VFlQRV9FTkQsIGlucHV0Xy0+Y3VycmVudCgpLnR5cGUpOworICBBU1NFUlRfRVEoIiIsIGVycm9yX2NvbGxlY3Rvcl8udGV4dF8pCisgICAgICA8PCAiRmFpbGVkIHRvIHBhcnNlOlxuIiA8PCBkZWJ1Z19zdHJpbmc7CisKKyAgLy8gV2Ugbm93IGhhdmUgYSBGaWxlRGVzY3JpcHRvclByb3RvLCBidXQgdG8gY29tcGFyZSB3aXRoIHRoZSBleHBlY3RlZCB3ZQorICAvLyBuZWVkIHRvIGxpbmsgdG8gYSBGaWxlRGVjcmlwdG9yLCB0aGVuIG91dHB1dCBiYWNrIHRvIGEgcHJvdG8uIFdlJ2xsCisgIC8vIGFsc28gbmVlZCB0byBnaXZlIGl0IHRoZSBzYW1lIG5hbWUgYXMgdGhlIG9yaWdpbmFsLgorICBwYXJzZWQuc2V0X25hbWUoImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byIpOworICAvLyBXZSBuZWVkIHRoZSBpbXBvcnRlZCBkZXBlbmRlbmN5IGJlZm9yZSB3ZSBjYW4gYnVpbGQgb3VyIHBhcnNlZCBwcm90bworICBjb25zdCBGaWxlRGVzY3JpcHRvciogcHVibGljX2ltcG9ydCA9CisgICAgICBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ6OlB1YmxpY0ltcG9ydE1lc3NhZ2U6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpOworICBGaWxlRGVzY3JpcHRvclByb3RvIHB1YmxpY19pbXBvcnRfcHJvdG87CisgIHB1YmxpY19pbXBvcnQtPkNvcHlUbygmcHVibGljX2ltcG9ydF9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShwdWJsaWNfaW1wb3J0X3Byb3RvKSAhPSBOVUxMKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGltcG9ydCA9CisgICAgICAgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OjpJbXBvcnRNZXNzYWdlOjpkZXNjcmlwdG9yKCktPmZpbGUoKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBpbXBvcnRfcHJvdG87CisgIGltcG9ydC0+Q29weVRvKCZpbXBvcnRfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUoaW1wb3J0X3Byb3RvKSAhPSBOVUxMKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGFjdHVhbCA9IHBvb2xfLkJ1aWxkRmlsZShwYXJzZWQpOworICBwYXJzZWQuQ2xlYXIoKTsKKyAgQVNTRVJUX1RSVUUoYWN0dWFsICE9IE5VTEwpCisgICAgICA8PCAiRmFpbGVkIHRvIHZhbGlkYXRlOlxuIiA8PCBkZWJ1Z19zdHJpbmc7CisgIGFjdHVhbC0+Q29weVRvKCZwYXJzZWQpOworICBBU1NFUlRfVFJVRShhY3R1YWwgIT0gTlVMTCk7CisKKyAgLy8gVGhlIG1lc3NhZ2VzIG1pZ2h0IGJlIGluIGRpZmZlcmVudCBvcmRlcnMsIG1ha2luZyB0aGVtIGhhcmQgdG8gY29tcGFyZS4KKyAgLy8gU28sIHNvcnQgdGhlIG1lc3NhZ2VzIGluIHRoZSBkZXNjcmlwdG9yIHByb3RvcyAoaW5jbHVkaW5nIG5lc3RlZCBtZXNzYWdlcywKKyAgLy8gcmVjdXJzaXZlbHkpLgorICBTb3J0TWVzc2FnZXMoJmV4cGVjdGVkKTsKKyAgU29ydE1lc3NhZ2VzKCZwYXJzZWQpOworCisgIC8vIEkgcmVhbGx5IHdhbnRlZCB0byB1c2UgU3RyaW5nRGlmZiBoZXJlIGZvciB0aGUgZGVidWcgb3V0cHV0IG9uIGZhaWwsCisgIC8vIGJ1dCB0aGUgc3RyaW5ncyBhcmUgdG9vIGxvbmcgZm9yIGl0LCBhbmQgaWYgSSBpbmNyZWFzZSBpdHMgbWF4IHNpemUsCisgIC8vIHdlIGdldCBhIG1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUgOigKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLkRlYnVnU3RyaW5nKCksIHBhcnNlZC5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFBhcnNlRGVzY3JpcHRvckRlYnVnVGVzdCwgVGVzdEN1c3RvbU9wdGlvbnMpIHsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIG9yaWdpbmFsX2ZpbGUgPQorICAgICBwcm90b2J1Zl91bml0dGVzdDo6QWdncmVnYXRlTWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZXhwZWN0ZWQ7CisgIG9yaWdpbmFsX2ZpbGUtPkNvcHlUbygmZXhwZWN0ZWQpOworCisgIHN0cmluZyBkZWJ1Z19zdHJpbmcgPSBvcmlnaW5hbF9maWxlLT5EZWJ1Z1N0cmluZygpOworCisgIC8vIFBhcnNlIHRoZSBkZWJ1ZyBzdHJpbmcKKyAgU2V0dXBQYXJzZXIoZGVidWdfc3RyaW5nLmNfc3RyKCkpOworICBGaWxlRGVzY3JpcHRvclByb3RvIHBhcnNlZDsKKyAgcGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmcGFyc2VkKTsKKyAgRVhQRUNUX0VRKGlvOjpUb2tlbml6ZXI6OlRZUEVfRU5ELCBpbnB1dF8tPmN1cnJlbnQoKS50eXBlKTsKKyAgQVNTRVJUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKworICAvLyBXZSBub3cgaGF2ZSBhIEZpbGVEZXNjcmlwdG9yUHJvdG8sIGJ1dCB0byBjb21wYXJlIHdpdGggdGhlIGV4cGVjdGVkIHdlCisgIC8vIG5lZWQgdG8gbGluayB0byBhIEZpbGVEZWNyaXB0b3IsIHRoZW4gb3V0cHV0IGJhY2sgdG8gYSBwcm90by4gV2UnbGwKKyAgLy8gYWxzbyBuZWVkIHRvIGdpdmUgaXQgdGhlIHNhbWUgbmFtZSBhcyB0aGUgb3JpZ2luYWwuCisgIHBhcnNlZC5zZXRfbmFtZShvcmlnaW5hbF9maWxlLT5uYW1lKCkpOworCisgIC8vIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIGRlcGVuZHMgb24gZGVzY3JpcHRvci5wcm90by4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGltcG9ydCA9IEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKS0+ZmlsZSgpOworICBGaWxlRGVzY3JpcHRvclByb3RvIGltcG9ydF9wcm90bzsKKyAgaW1wb3J0LT5Db3B5VG8oJmltcG9ydF9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShpbXBvcnRfcHJvdG8pICE9IE5VTEwpOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYWN0dWFsID0gcG9vbF8uQnVpbGRGaWxlKHBhcnNlZCk7CisgIEFTU0VSVF9UUlVFKGFjdHVhbCAhPSBOVUxMKTsKKyAgcGFyc2VkLkNsZWFyKCk7CisgIGFjdHVhbC0+Q29weVRvKCZwYXJzZWQpOworCisgIC8vIFRoZSBtZXNzYWdlcyBtaWdodCBiZSBpbiBkaWZmZXJlbnQgb3JkZXJzLCBtYWtpbmcgdGhlbSBoYXJkIHRvIGNvbXBhcmUuCisgIC8vIFNvLCBzb3J0IHRoZSBtZXNzYWdlcyBpbiB0aGUgZGVzY3JpcHRvciBwcm90b3MgKGluY2x1ZGluZyBuZXN0ZWQgbWVzc2FnZXMsCisgIC8vIHJlY3Vyc2l2ZWx5KS4KKyAgU29ydE1lc3NhZ2VzKCZleHBlY3RlZCk7CisgIFNvcnRNZXNzYWdlcygmcGFyc2VkKTsKKworICBFWFBFQ1RfRVEoZXhwZWN0ZWQuRGVidWdTdHJpbmcoKSwgcGFyc2VkLkRlYnVnU3RyaW5nKCkpOworfQorCisvLyBFbnN1cmUgdGhhdCBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKCksIHdpdGggfGluY2x1ZGVfY29tbWVudHN8IHNldCB0byB0cnVlLAorLy8gaW5jbHVkZXMgY29tbWVudHMgZnJvbSB0aGUgb3JpZ2luYWwgcGFyc2VyIGlucHV0IGluIGFsbCBvZiB0aGUgYXBwcm9wcmlhdGUKKy8vIHBsYWNlcy4KK1RFU1RfRihQYXJzZURlc2NyaXB0b3JEZWJ1Z1Rlc3QsIFRlc3RDb21tZW50c0luRGVidWdTdHJpbmcpIHsKKyAgU2V0dXBQYXJzZXIoCisgICAgICAiLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgc3ludGF4LlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIFN5bnRheCBjb21tZW50LlxuIgorICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAiXG4iCisgICAgICAiLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgcGFja2FnZS5cbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBQYWNrYWdlIGNvbW1lbnQuXG4iCisgICAgICAicGFja2FnZSBjb21tZW50X3Rlc3Q7XG4iCisgICAgICAiXG4iCisgICAgICAiLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgVGVzdE1lc3NhZ2UxLlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIE1lc3NhZ2UgY29tbWVudC5cbiIKKyAgICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlMSB7XG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBmb28uXG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBGaWVsZCBjb21tZW50LlxuIgorICAgICAgIiAgb3B0aW9uYWwgaW50MzIgZm9vID0gMTtcbiIKKyAgICAgICJcbiIKKyAgICAgICIgIC8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIE5lc3RlZE1lc3NhZ2UuXG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBOZXN0ZWQtbWVzc2FnZSBjb21tZW50LlxuIgorICAgICAgIiAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHtcbiIKKyAgICAgICIgICAgb3B0aW9uYWwgaW50MzIgYmFyID0gMTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iCisgICAgICAiLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTXlFbnVtVHlwZS5cbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBFbnVtIGNvbW1lbnQuXG4iCisgICAgICAiZW51bSBNeUVudW1UeXBlIHtcbiIKKyAgICAgICJcbiIKKyAgICAgICIgIC8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIEFTREYuXG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBFbnVtLXZhbHVlIGNvbW1lbnQuXG4iCisgICAgICAiICBBU0RGID0gMTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iCisgICAgICAiLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTXlTZXJ2aWNlLlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIFNlcnZpY2UgY29tbWVudC5cbiIKKyAgICAgICJzZXJ2aWNlIE15U2VydmljZSB7XG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBNeVJQQ0NhbGwuXG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBSUEMgY29tbWVudC5cbiIKKyAgICAgICIgIHJwYyBNeVJQQ0NhbGwoVGVzdE1lc3NhZ2UxKSByZXR1cm5zIChUZXN0TWVzc2FnZTEpIHsgfVxuIgorICAgICAgIn1cbiIpOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gcGFyc2VkX2Rlc2M7CisgIHBhcnNlZF9kZXNjLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgU291cmNlTG9jYXRpb25UYWJsZSBzb3VyY2VfbG9jYXRpb25zOworICBwYXJzZXJfLT5SZWNvcmRTb3VyY2VMb2NhdGlvbnNUbygmc291cmNlX2xvY2F0aW9ucyk7CisgIHBhcnNlcl8tPlBhcnNlKGlucHV0Xy5nZXQoKSwgJnBhcnNlZF9kZXNjKTsKKyAgRVhQRUNUX0VRKGlvOjpUb2tlbml6ZXI6OlRZUEVfRU5ELCBpbnB1dF8tPmN1cnJlbnQoKS50eXBlKTsKKyAgQVNTRVJUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKworICAvLyBXZSBuZWVkIHRvIGltcG9ydCB0aGUgRmlsZURlc2NyaXB0b3JQcm90byB0byBnZXQgYSBGaWxlRGVzY3JpcHRvci4KKyAgTW9ja1ZhbGlkYXRpb25FcnJvckNvbGxlY3RvciBjb2xsZWN0b3Ioc291cmNlX2xvY2F0aW9ucywgJmVycm9yX2NvbGxlY3Rvcl8pOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvciA9CisgICAgICBwb29sXy5CdWlsZEZpbGVDb2xsZWN0aW5nRXJyb3JzKHBhcnNlZF9kZXNjLCAmY29sbGVjdG9yKTsKKyAgQVNTRVJUX1RSVUUoZGVzY3JpcHRvciAhPSBOVUxMKTsKKworICBEZWJ1Z1N0cmluZ09wdGlvbnMgZGVidWdfc3RyaW5nX29wdGlvbnM7CisgIGRlYnVnX3N0cmluZ19vcHRpb25zLmluY2x1ZGVfY29tbWVudHMgPSB0cnVlOworICBjb25zdCBzdHJpbmcgZGVidWdfc3RyaW5nID0KKyAgICAgIGRlc2NyaXB0b3ItPkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoZGVidWdfc3RyaW5nX29wdGlvbnMpOworCisgIC8vIEVuc3VyZSB0aGF0IGVhY2ggb2YgdGhlIGNvbW1lbnRzIGFwcGVhcnMgc29tZXdoZXJlIGluIHRoZSBEZWJ1Z1N0cmluZygpLgorICAvLyBXZSBkb24ndCB0ZXN0IHRoZSBleGFjdCBjb21tZW50IHBsYWNlbWVudCBvciBmb3JtYXR0aW5nLCBiZWNhdXNlIHdlIGRvIG5vdAorICAvLyB3YW50IHRvIGJlIHRvbyBmcmFnaWxlIGhlcmUuCisgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX2NvbW1lbnRzW10gPSB7CisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIHN5bnRheC4iLAorICAgICJTeW50YXggY29tbWVudC4iLAorICAgICJEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBwYWNrYWdlLiIsCisgICAgIlBhY2thZ2UgY29tbWVudC4iLAorICAgICJEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBUZXN0TWVzc2FnZTEuIiwKKyAgICAiTWVzc2FnZSBjb21tZW50LiIsCisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIGZvby4iLAorICAgICJGaWVsZCBjb21tZW50IiwKKyAgICAiRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTmVzdGVkTWVzc2FnZS4iLAorICAgICJOZXN0ZWQtbWVzc2FnZSBjb21tZW50IiwKKyAgICAiRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTXlFbnVtVHlwZS4iLAorICAgICJFbnVtIGNvbW1lbnQiLAorICAgICJEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBBU0RGLiIsCisgICAgIkVudW0tdmFsdWUgY29tbWVudCIsCisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIE15U2VydmljZS4iLAorICAgICJTZXJ2aWNlIGNvbW1lbnQiLAorICAgICJEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBNeVJQQ0NhbGwuIiwKKyAgICAiUlBDIGNvbW1lbnQiLAorICB9OworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShleHBlY3RlZF9jb21tZW50cyk7ICsraSkgeworICAgIHN0cmluZzo6c2l6ZV90eXBlIGZvdW5kX3BvcyA9IGRlYnVnX3N0cmluZy5maW5kKGV4cGVjdGVkX2NvbW1lbnRzW2ldKTsKKyAgICBFWFBFQ1RfVFJVRShmb3VuZF9wb3MgIT0gc3RyaW5nOjpucG9zKQorICAgICAgICA8PCAiXCIiIDw8IGV4cGVjdGVkX2NvbW1lbnRzW2ldIDw8ICJcIiBub3QgZm91bmQuIjsKKyAgfQorfQorCitURVNUX0YoUGFyc2VEZXNjcmlwdG9yRGVidWdUZXN0LCBUZXN0TWFwcykgeworICBTZXR1cFBhcnNlcigKKyAgICAgICJzeW50YXggPSBcInByb3RvM1wiOyAiCisgICAgICAibWVzc2FnZSBGb28geyAiCisgICAgICAiICBtZXNzYWdlIEJhciB7IH0gIgorICAgICAgIiAgbWFwPGludDMyLCBCYXI+IGVudW1fbWVzc2FnZV9tYXAgPSAxOyAiCisgICAgICAiICBtYXA8c3RyaW5nLCBmbG9hdD4gcHJpbWl0aXZlX21hcCA9IDI7ICIKKyAgICAgICJ9ICIpOworICBGaWxlRGVzY3JpcHRvclByb3RvIG9yaWdpbmFsOworICBFWFBFQ1RfVFJVRShwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZvcmlnaW5hbCkpOworICBvcmlnaW5hbC5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbF8uQnVpbGRGaWxlKG9yaWdpbmFsKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKworICAvLyBNYWtlIHN1cmUgdGhlIGRlYnVnIHN0cmluZyB1c2VzIG1hcCBzeW50YXggYW5kIGRvZXMgbm90IGhhdmUgdGhlIGF1dG8KKyAgLy8gZ2VuZXJhdGVkIGVudHJ5LgorICBzdHJpbmcgZGVidWdfc3RyaW5nID0gZmlsZS0+RGVidWdTdHJpbmcoKTsKKyAgRVhQRUNUX1RSVUUoZGVidWdfc3RyaW5nLmZpbmQoIm1hcDwiKSAhPSBzdHJpbmc6Om5wb3MpOworICBFWFBFQ1RfVFJVRShkZWJ1Z19zdHJpbmcuZmluZCgib3B0aW9uIG1hcF9lbnRyeSIpID09IHN0cmluZzo6bnBvcyk7CisgIEVYUEVDVF9UUlVFKGRlYnVnX3N0cmluZy5maW5kKCJNYXBFbnRyeSIpID09IHN0cmluZzo6bnBvcyk7CisKKyAgLy8gTWFrZSBzdXJlIHRoZSBkZXNjcmlwdG9yIGRlYnVnIHN0cmluZyBpcyBwYXJzYWJsZS4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBwYXJzZWQ7CisgIFNldHVwUGFyc2VyKGRlYnVnX3N0cmluZy5jX3N0cigpKTsKKyAgcGFyc2VkLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUocGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmcGFyc2VkKSk7CisKKyAgb3JpZ2luYWwuY2xlYXJfc291cmNlX2NvZGVfaW5mbygpOworICBwYXJzZWQuY2xlYXJfc291cmNlX2NvZGVfaW5mbygpOworICBTdHJpcEZpZWxkVHlwZU5hbWUoJm9yaWdpbmFsKTsKKyAgU3RyaXBGaWVsZFR5cGVOYW1lKCZwYXJzZWQpOworICBFWFBFQ1RfRVEob3JpZ2luYWwuRGVidWdTdHJpbmcoKSwgcGFyc2VkLkRlYnVnU3RyaW5nKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBTb3VyY2VDb2RlSW5mbyB0ZXN0cy4KKworLy8gRm9sbG93cyBhIHBhdGggLS0gYXMgZGVmaW5lZCBieSBTb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoIC0tIGZyb20gYQorLy8gbWVzc2FnZSB0byBhIHBhcnRpY3VsYXIgc3ViLWZpZWxkLgorLy8gKiBJZiB0aGUgdGFyZ2V0IGlzIGl0c2VsZiBhIG1lc3NhZ2UsIHNldHMgKm91dHB1dF9tZXNzYWdlIHRvIHBvaW50IGF0IGl0LAorLy8gICAqb3V0cHV0X2ZpZWxkIHRvIE5VTEwsIGFuZCAqb3V0cHV0X2luZGV4IHRvIC0xLgorLy8gKiBPdGhlcndpc2UsIGlmIHRoZSB0YXJnZXQgaXMgYW4gZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkLCBzZXRzCisvLyAgICpvdXRwdXRfbWVzc2FnZSB0byB0aGUgY29udGFpbmluZyBtZXNzYWdlLCAqb3V0cHV0X2ZpZWxkIHRvIHRoZSBkZXNjcmlwdG9yCisvLyAgIG9mIHRoZSBmaWVsZCwgYW5kICpvdXRwdXRfaW5kZXggdG8gdGhlIGluZGV4IG9mIHRoZSBlbGVtZW50LgorLy8gKiBPdGhlcndpc2UsIHRoZSB0YXJnZXQgaXMgYSBmaWVsZCAocG9zc2libHkgYSByZXBlYXRlZCBmaWVsZCwgYnV0IG5vdCBhbnkKKy8vICAgb25lIGVsZW1lbnQpLiAgU2V0cyAqb3V0cHV0X21lc3NhZ2UgdG8gdGhlIGNvbnRhaW5pbmcgbWVzc2FnZSwKKy8vICAgKm91dHB1dF9maWVsZCB0byB0aGUgZGVzY3JpcHRvciBvZiB0aGUgZmllbGQsIGFuZCAqb3V0cHV0X2luZGV4IHRvIC0xLgorLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBwYXRoIHdhcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLiAgQSBnVGVzdCBmYWlsdXJlIGlzCisvLyByZWNvcmRlZCBiZWZvcmUgcmV0dXJuaW5nIGZhbHNlLgorYm9vbCBGb2xsb3dQYXRoKGNvbnN0IE1lc3NhZ2UmIHJvb3QsCisgICAgICAgICAgICAgICAgY29uc3QgaW50KiBwYXRoX2JlZ2luLCBjb25zdCBpbnQqIHBhdGhfZW5kLAorICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqKiBvdXRwdXRfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBvdXRwdXRfZmllbGQsCisgICAgICAgICAgICAgICAgaW50KiBvdXRwdXRfaW5kZXgpIHsKKyAgaWYgKHBhdGhfYmVnaW4gPT0gcGF0aF9lbmQpIHsKKyAgICAvLyBQYXRoIHJlZmVycyB0byB0aGlzIHdob2xlIG1lc3NhZ2UuCisgICAgKm91dHB1dF9tZXNzYWdlID0gJnJvb3Q7CisgICAgKm91dHB1dF9maWVsZCA9IE5VTEw7CisgICAgKm91dHB1dF9pbmRleCA9IC0xOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHJvb3QuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gcm9vdC5HZXRSZWZsZWN0aW9uKCk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TnVtYmVyKCpwYXRoX2JlZ2luKTsKKworICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgIEFERF9GQUlMVVJFKCkgPDwgZGVzY3JpcHRvci0+bmFtZSgpIDw8ICIgaGFzIG5vIGZpZWxkIG51bWJlcjogIgorICAgICAgICAgICAgICAgICAgPDwgKnBhdGhfYmVnaW47CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgKytwYXRoX2JlZ2luOworCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIGlmIChwYXRoX2JlZ2luID09IHBhdGhfZW5kKSB7CisgICAgICAvLyBQYXRoIHJlZmVycyB0byB0aGUgd2hvbGUgcmVwZWF0ZWQgZmllbGQuCisgICAgICAqb3V0cHV0X21lc3NhZ2UgPSAmcm9vdDsKKyAgICAgICpvdXRwdXRfZmllbGQgPSBmaWVsZDsKKyAgICAgICpvdXRwdXRfaW5kZXggPSAtMTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGludCBpbmRleCA9ICpwYXRoX2JlZ2luKys7CisgICAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUocm9vdCwgZmllbGQpOworCisgICAgaWYgKGluZGV4ID49IHNpemUpIHsKKyAgICAgIEFERF9GQUlMVVJFKCkgPDwgZGVzY3JpcHRvci0+bmFtZSgpIDw8ICIuIiA8PCBmaWVsZC0+bmFtZSgpCisgICAgICAgICAgICAgICAgICAgIDw8ICIgaGFzIHNpemUgIiA8PCBzaXplIDw8ICIsIGJ1dCBwYXRoIGNvbnRhaW5lZCBpbmRleDogIgorICAgICAgICAgICAgICAgICAgICA8PCBpbmRleDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIC8vIERlc2NlbmQgaW50byBjaGlsZCBtZXNzYWdlLgorICAgICAgY29uc3QgTWVzc2FnZSYgY2hpbGQgPSByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2Uocm9vdCwgZmllbGQsIGluZGV4KTsKKyAgICAgIHJldHVybiBGb2xsb3dQYXRoKGNoaWxkLCBwYXRoX2JlZ2luLCBwYXRoX2VuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dF9tZXNzYWdlLCBvdXRwdXRfZmllbGQsIG91dHB1dF9pbmRleCk7CisgICAgfSBlbHNlIGlmIChwYXRoX2JlZ2luID09IHBhdGhfZW5kKSB7CisgICAgICAvLyBQYXRoIHJlZmVycyB0byB0aGlzIGVsZW1lbnQuCisgICAgICAqb3V0cHV0X21lc3NhZ2UgPSAmcm9vdDsKKyAgICAgICpvdXRwdXRfZmllbGQgPSBmaWVsZDsKKyAgICAgICpvdXRwdXRfaW5kZXggPSBpbmRleDsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8IGRlc2NyaXB0b3ItPm5hbWUoKSA8PCAiLiIgPDwgZmllbGQtPm5hbWUoKQorICAgICAgICAgICAgICAgICAgICA8PCAiIGlzIG5vdCBhIG1lc3NhZ2U7IGNhbm5vdCBkZXNjZW5kIGludG8gaXQuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBjb25zdCBNZXNzYWdlJiBjaGlsZCA9IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2Uocm9vdCwgZmllbGQpOworICAgICAgcmV0dXJuIEZvbGxvd1BhdGgoY2hpbGQsIHBhdGhfYmVnaW4sIHBhdGhfZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0X21lc3NhZ2UsIG91dHB1dF9maWVsZCwgb3V0cHV0X2luZGV4KTsKKyAgICB9IGVsc2UgaWYgKHBhdGhfYmVnaW4gPT0gcGF0aF9lbmQpIHsKKyAgICAgIC8vIFBhdGggcmVmZXJzIHRvIHRoaXMgZmllbGQuCisgICAgICAqb3V0cHV0X21lc3NhZ2UgPSAmcm9vdDsKKyAgICAgICpvdXRwdXRfZmllbGQgPSBmaWVsZDsKKyAgICAgICpvdXRwdXRfaW5kZXggPSAtMTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8IGRlc2NyaXB0b3ItPm5hbWUoKSA8PCAiLiIgPDwgZmllbGQtPm5hbWUoKQorICAgICAgICAgICAgICAgICAgICA8PCAiIGlzIG5vdCBhIG1lc3NhZ2U7IGNhbm5vdCBkZXNjZW5kIGludG8gaXQuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KK30KKworLy8gQ2hlY2sgaWYgdHdvIHNwYW5zIGFyZSBlcXVhbC4KK2Jvb2wgQ29tcGFyZVNwYW5zKGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50PiYgc3BhbjEsCisgICAgICAgICAgICAgICAgICBjb25zdCBSZXBlYXRlZEZpZWxkPGludD4mIHNwYW4yKSB7CisgIGlmIChzcGFuMS5zaXplKCkgIT0gc3BhbjIuc2l6ZSgpKSByZXR1cm4gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc3BhbjEuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoc3BhbjEuR2V0KGkpICE9IHNwYW4yLkdldChpKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBUZXN0IGZpeHR1cmUgZm9yIHNvdXJjZSBpbmZvIHRlc3RzLCB3aGljaCBjaGVjayB0aGF0IHNvdXJjZSBsb2NhdGlvbnMgYXJlCisvLyByZWNvcmRlZCBjb3JyZWN0bHkgaW4gRmlsZURlc2NyaXB0b3JQcm90by5zb3VyY2VfY29kZV9pbmZvLmxvY2F0aW9uLgorY2xhc3MgU291cmNlSW5mb1Rlc3QgOiBwdWJsaWMgUGFyc2VyVGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBUaGUgcGFyc2VkIGZpbGUgKGluaXRpYWxpemVkIGJ5IFBhcnNlKCkpLgorICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfOworCisgIC8vIFBhcnNlIHRoZSBnaXZlbiB0ZXh0IGFzIGEgLnByb3RvIGZpbGUgYW5kIHBvcHVsYXRlIHRoZSBzcGFuc18gbWFwIHdpdGgKKyAgLy8gYWxsIHRoZSBzb3VyY2UgbG9jYXRpb24gc3BhbnMgaW4gaXRzIFNvdXJjZUNvZGVJbmZvIHRhYmxlLgorICBib29sIFBhcnNlKGNvbnN0IGNoYXIqIHRleHQpIHsKKyAgICBFeHRyYWN0TWFya2Vycyh0ZXh0KTsKKyAgICBTZXR1cFBhcnNlcih0ZXh0X3dpdGhvdXRfbWFya2Vyc18uY19zdHIoKSk7CisgICAgaWYgKCFwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZmaWxlXykpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBjb25zdCBTb3VyY2VDb2RlSW5mbyYgc291cmNlX2luZm8gPSBmaWxlXy5zb3VyY2VfY29kZV9pbmZvKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2VfaW5mby5sb2NhdGlvbl9zaXplKCk7IGkrKykgeworICAgICAgY29uc3QgU291cmNlQ29kZUluZm86OkxvY2F0aW9uJiBsb2NhdGlvbiA9IHNvdXJjZV9pbmZvLmxvY2F0aW9uKGkpOworICAgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvcl9wcm90byA9IE5VTEw7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gTlVMTDsKKyAgICAgIGludCBpbmRleCA9IDA7CisgICAgICBpZiAoIUZvbGxvd1BhdGgoZmlsZV8sIGxvY2F0aW9uLnBhdGgoKS5iZWdpbigpLCBsb2NhdGlvbi5wYXRoKCkuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICAgJmRlc2NyaXB0b3JfcHJvdG8sICZmaWVsZCwgJmluZGV4KSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHNwYW5zXy5pbnNlcnQoCisgICAgICAgICAgc3RkOjptYWtlX3BhaXIoU3BhbktleSgqZGVzY3JpcHRvcl9wcm90bywgZmllbGQsIGluZGV4KSwgJmxvY2F0aW9uKSk7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICB2aXJ0dWFsIHZvaWQgVGVhckRvd24oKSB7CisgICAgRVhQRUNUX1RSVUUoc3BhbnNfLmVtcHR5KCkpCisgICAgICAgIDw8ICJGb3Jnb3QgdG8gY2FsbCBIYXNTcGFuKCkgZm9yOlxuIgorICAgICAgICA8PCBzcGFuc18uYmVnaW4oKS0+c2Vjb25kLT5EZWJ1Z1N0cmluZygpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSGFzU3BhbigpIGNoZWNrcyB0aGF0IHRoZSBzcGFuIG9mIHNvdXJjZSBjb2RlIGRlbGltaXRlZCBieSB0aGUgZ2l2ZW4KKyAgLy8gdGFncyAoY29tbWVudHMpIGNvcnJlc3BvbmQgdmlhIHRoZSBTb3VyY2VDb2RlSW5mbyB0YWJsZSB0byB0aGUgZ2l2ZW4KKyAgLy8gcGFydCBvZiB0aGUgRmlsZURlc2NyaXB0b3JQcm90by4gIChJZiB1bmNsZWFyLCBsb29rIGF0IHRoZSBhY3R1YWwgdGVzdHM7CisgIC8vIGl0IHNob3VsZCBxdWlja2x5IGJlY29tZSBvYnZpb3VzLikKKworICBib29sIEhhc1NwYW4oY2hhciBzdGFydF9tYXJrZXIsIGNoYXIgZW5kX21hcmtlciwKKyAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3JfcHJvdG8pIHsKKyAgICByZXR1cm4gSGFzU3BhbldpdGhDb21tZW50KAorICAgICAgICBzdGFydF9tYXJrZXIsIGVuZF9tYXJrZXIsIGRlc2NyaXB0b3JfcHJvdG8sIE5VTEwsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIGJvb2wgSGFzU3BhbldpdGhDb21tZW50KGNoYXIgc3RhcnRfbWFya2VyLCBjaGFyIGVuZF9tYXJrZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3JfcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX2xlYWRpbmdfY29tbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBleHBlY3RlZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKSB7CisgICAgcmV0dXJuIEhhc1NwYW5XaXRoQ29tbWVudCgKKyAgICAgICAgc3RhcnRfbWFya2VyLCBlbmRfbWFya2VyLCBkZXNjcmlwdG9yX3Byb3RvLCBOVUxMLCAtMSwKKyAgICAgICAgZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywgZXhwZWN0ZWRfdHJhaWxpbmdfY29tbWVudHMsCisgICAgICAgIGV4cGVjdGVkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpOworICB9CisKKyAgYm9vbCBIYXNTcGFuKGNoYXIgc3RhcnRfbWFya2VyLCBjaGFyIGVuZF9tYXJrZXIsCisgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvLCBjb25zdCBzdHJpbmcmIGZpZWxkX25hbWUpIHsKKyAgICByZXR1cm4gSGFzU3BhbihzdGFydF9tYXJrZXIsIGVuZF9tYXJrZXIsIGRlc2NyaXB0b3JfcHJvdG8sIGZpZWxkX25hbWUsIC0xKTsKKyAgfQorCisgIGJvb2wgSGFzU3BhbihjaGFyIHN0YXJ0X21hcmtlciwgY2hhciBlbmRfbWFya2VyLAorICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bywgY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgcmV0dXJuIEhhc1NwYW4oc3RhcnRfbWFya2VyLCBlbmRfbWFya2VyLCBkZXNjcmlwdG9yX3Byb3RvLAorICAgICAgICAgICAgICAgICAgIGZpZWxkX25hbWUsIGluZGV4LCBOVUxMLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIGJvb2wgSGFzU3BhbihjaGFyIHN0YXJ0X21hcmtlciwgY2hhciBlbmRfbWFya2VyLAorICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bywKKyAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgICBkZXNjcmlwdG9yX3Byb3RvLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKGZpZWxkX25hbWUpOworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8IGRlc2NyaXB0b3JfcHJvdG8uR2V0RGVzY3JpcHRvcigpLT5uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgPDwgIiBoYXMgbm8gc3VjaCBmaWVsZDogIiA8PCBmaWVsZF9uYW1lOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiBIYXNTcGFuV2l0aENvbW1lbnQoCisgICAgICAgIHN0YXJ0X21hcmtlciwgZW5kX21hcmtlciwgZGVzY3JpcHRvcl9wcm90bywgZmllbGQsIGluZGV4LAorICAgICAgICBleHBlY3RlZF9sZWFkaW5nX2NvbW1lbnRzLCBleHBlY3RlZF90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgZXhwZWN0ZWRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyk7CisgIH0KKworICBib29sIEhhc1NwYW4oY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bykgeworICAgIHJldHVybiBIYXNTcGFuV2l0aENvbW1lbnQoCisgICAgICAgICdcMCcsICdcMCcsIGRlc2NyaXB0b3JfcHJvdG8sIE5VTEwsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIGJvb2wgSGFzU3Bhbihjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvLCBjb25zdCBzdHJpbmcmIGZpZWxkX25hbWUpIHsKKyAgICByZXR1cm4gSGFzU3BhbignXDAnLCAnXDAnLCBkZXNjcmlwdG9yX3Byb3RvLCBmaWVsZF9uYW1lLCAtMSk7CisgIH0KKworICBib29sIEhhc1NwYW4oY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bywgY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgcmV0dXJuIEhhc1NwYW4oJ1wwJywgJ1wwJywgZGVzY3JpcHRvcl9wcm90bywgZmllbGRfbmFtZSwgaW5kZXgpOworICB9CisKKyAgYm9vbCBIYXNTcGFuV2l0aENvbW1lbnQoCisgICAgICBjaGFyIHN0YXJ0X21hcmtlciwgY2hhciBlbmRfbWFya2VyLCBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywKKyAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykgeworICAgIHBhaXI8U3Bhbk1hcDo6aXRlcmF0b3IsIFNwYW5NYXA6Oml0ZXJhdG9yPiByYW5nZSA9CisgICAgICAgIHNwYW5zXy5lcXVhbF9yYW5nZShTcGFuS2V5KGRlc2NyaXB0b3JfcHJvdG8sIGZpZWxkLCBpbmRleCkpOworCisgICAgaWYgKHN0YXJ0X21hcmtlciA9PSAnXDAnKSB7CisgICAgICBpZiAocmFuZ2UuZmlyc3QgPT0gcmFuZ2Uuc2Vjb25kKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNwYW5zXy5lcmFzZShyYW5nZS5maXJzdCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBwYWlyPGludCwgaW50PiBzdGFydF9wb3MgPSBGaW5kT3JEaWUobWFya2Vyc18sIHN0YXJ0X21hcmtlcik7CisgICAgICBwYWlyPGludCwgaW50PiBlbmRfcG9zID0gRmluZE9yRGllKG1hcmtlcnNfLCBlbmRfbWFya2VyKTsKKworICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGV4cGVjdGVkX3NwYW47CisgICAgICBleHBlY3RlZF9zcGFuLkFkZChzdGFydF9wb3MuZmlyc3QpOworICAgICAgZXhwZWN0ZWRfc3Bhbi5BZGQoc3RhcnRfcG9zLnNlY29uZCk7CisgICAgICBpZiAoZW5kX3Bvcy5maXJzdCAhPSBzdGFydF9wb3MuZmlyc3QpIHsKKyAgICAgICAgZXhwZWN0ZWRfc3Bhbi5BZGQoZW5kX3Bvcy5maXJzdCk7CisgICAgICB9CisgICAgICBleHBlY3RlZF9zcGFuLkFkZChlbmRfcG9zLnNlY29uZCk7CisKKyAgICAgIGZvciAoU3Bhbk1hcDo6aXRlcmF0b3IgaXRlciA9IHJhbmdlLmZpcnN0OyBpdGVyICE9IHJhbmdlLnNlY29uZDsgKytpdGVyKSB7CisgICAgICAgIGlmIChDb21wYXJlU3BhbnMoZXhwZWN0ZWRfc3BhbiwgaXRlci0+c2Vjb25kLT5zcGFuKCkpKSB7CisgICAgICAgICAgaWYgKGV4cGVjdGVkX2xlYWRpbmdfY29tbWVudHMgPT0gTlVMTCkgeworICAgICAgICAgICAgRVhQRUNUX0ZBTFNFKGl0ZXItPnNlY29uZC0+aGFzX2xlYWRpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEVYUEVDVF9UUlVFKGl0ZXItPnNlY29uZC0+aGFzX2xlYWRpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgICBFWFBFQ1RfRVEoZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICBpdGVyLT5zZWNvbmQtPmxlYWRpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChleHBlY3RlZF90cmFpbGluZ19jb21tZW50cyA9PSBOVUxMKSB7CisgICAgICAgICAgICBFWFBFQ1RfRkFMU0UoaXRlci0+c2Vjb25kLT5oYXNfdHJhaWxpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEVYUEVDVF9UUlVFKGl0ZXItPnNlY29uZC0+aGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkpOworICAgICAgICAgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgIGl0ZXItPnNlY29uZC0+dHJhaWxpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChleHBlY3RlZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID09IE5VTEwpIHsKKyAgICAgICAgICAgIEVYUEVDVF9FUSgwLCBpdGVyLT5zZWNvbmQtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfc2l6ZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgRVhQRUNUX0VRKAorICAgICAgICAgICAgICAgIGV4cGVjdGVkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMsCisgICAgICAgICAgICAgICAgSm9pbihpdGVyLT5zZWNvbmQtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSwgIlxuIikpOworICAgICAgICAgIH0KKworICAgICAgICAgIHNwYW5zXy5lcmFzZShpdGVyKTsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyBwcml2YXRlOgorICBzdHJ1Y3QgU3BhbktleSB7CisgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvcl9wcm90bzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkOworICAgIGludCBpbmRleDsKKworICAgIGlubGluZSBTcGFuS2V5KCkge30KKyAgICBpbmxpbmUgU3BhbktleShjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvX3BhcmFtLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfcGFyYW0sCisgICAgICAgICAgICAgICAgICAgaW50IGluZGV4X3BhcmFtKQorICAgICAgICA6IGRlc2NyaXB0b3JfcHJvdG8oJmRlc2NyaXB0b3JfcHJvdG9fcGFyYW0pLCBmaWVsZChmaWVsZF9wYXJhbSksCisgICAgICAgICAgaW5kZXgoaW5kZXhfcGFyYW0pIHt9CisKKyAgICBpbmxpbmUgYm9vbCBvcGVyYXRvcjwoY29uc3QgU3BhbktleSYgb3RoZXIpIGNvbnN0IHsKKyAgICAgIGlmIChkZXNjcmlwdG9yX3Byb3RvIDwgb3RoZXIuZGVzY3JpcHRvcl9wcm90bykgcmV0dXJuIHRydWU7CisgICAgICBpZiAoZGVzY3JpcHRvcl9wcm90byA+IG90aGVyLmRlc2NyaXB0b3JfcHJvdG8pIHJldHVybiBmYWxzZTsKKyAgICAgIGlmIChmaWVsZCA8IG90aGVyLmZpZWxkKSByZXR1cm4gdHJ1ZTsKKyAgICAgIGlmIChmaWVsZCA+IG90aGVyLmZpZWxkKSByZXR1cm4gZmFsc2U7CisgICAgICByZXR1cm4gaW5kZXggPCBvdGhlci5pbmRleDsKKyAgICB9CisgIH07CisKKyAgdHlwZWRlZiBtdWx0aW1hcDxTcGFuS2V5LCBjb25zdCBTb3VyY2VDb2RlSW5mbzo6TG9jYXRpb24qPiBTcGFuTWFwOworICBTcGFuTWFwIHNwYW5zXzsKKyAgbWFwPGNoYXIsIHBhaXI8aW50LCBpbnQ+ID4gbWFya2Vyc187CisgIHN0cmluZyB0ZXh0X3dpdGhvdXRfbWFya2Vyc187CisKKyAgdm9pZCBFeHRyYWN0TWFya2Vycyhjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgbWFya2Vyc18uY2xlYXIoKTsKKyAgICB0ZXh0X3dpdGhvdXRfbWFya2Vyc18uY2xlYXIoKTsKKyAgICBpbnQgbGluZSA9IDA7CisgICAgaW50IGNvbHVtbiA9IDA7CisgICAgd2hpbGUgKCp0ZXh0ICE9ICdcMCcpIHsKKyAgICAgIGlmICgqdGV4dCA9PSAnJCcpIHsKKyAgICAgICAgKyt0ZXh0OworICAgICAgICBHT09HTEVfQ0hFQ0tfTkUoJ1wwJywgKnRleHQpOworICAgICAgICBpZiAoKnRleHQgPT0gJyQnKSB7CisgICAgICAgICAgdGV4dF93aXRob3V0X21hcmtlcnNfICs9ICckJzsKKyAgICAgICAgICArK2NvbHVtbjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBtYXJrZXJzX1sqdGV4dF0gPSBzdGQ6Om1ha2VfcGFpcihsaW5lLCBjb2x1bW4pOworICAgICAgICAgICsrdGV4dDsKKyAgICAgICAgICBHT09HTEVfQ0hFQ0tfRVEoJyQnLCAqdGV4dCk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAoKnRleHQgPT0gJ1xuJykgeworICAgICAgICArK2xpbmU7CisgICAgICAgIGNvbHVtbiA9IDA7CisgICAgICAgIHRleHRfd2l0aG91dF9tYXJrZXJzXyArPSAqdGV4dDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRleHRfd2l0aG91dF9tYXJrZXJzXyArPSAqdGV4dDsKKyAgICAgICAgKytjb2x1bW47CisgICAgICB9CisgICAgICArK3RleHQ7CisgICAgfQorICB9Cit9OworCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEJhc2ljRmlsZURlY2xzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJHN5bnRheCA9IFwicHJvdG8yXCI7JGkkXG4iCisgICAgICAicGFja2FnZSAkYiRmb28uYmFyJGMkO1xuIgorICAgICAgImltcG9ydCAkZCRcImJhei5wcm90b1wiJGUkO1xuIgorICAgICAgImltcG9ydCAkZiRcInF1eC5wcm90b1wiJGckOyRoJFxuIgorICAgICAgIlxuIgorICAgICAgIi8vIGNvbW1lbnQgaWdub3JlZFxuIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaCcsIGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpbGVfLCAicGFja2FnZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgZmlsZV8sICJkZXBlbmRlbmN5IiwgMCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCBmaWxlXywgImRlcGVuZGVuY3kiLCAxKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaScsIGZpbGVfLCAic3ludGF4IikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE1lc3NhZ2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJG1lc3NhZ2UgJGIkRm9vJGMkIHt9JGQkXG4iCisgICAgICAiJGUkbWVzc2FnZSAkZiRCYXIkZyQge30kaCRcbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2QnLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdoJywgZmlsZV8ubWVzc2FnZV90eXBlKDEpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIGZpbGVfLm1lc3NhZ2VfdHlwZSgxKSwgIm5hbWUiKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRmllbGRzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgICRhJG9wdGlvbmFsJGIkICRjJGludDMyJGQkICRlJGJhciRmJCA9ICRnJDEkaCQ7JGkkXG4iCisgICAgICAiICAkaiRyZXBlYXRlZCRrJCAkbCRYLlkkbSQgJG4kYmF6JG8kID0gJHAkMiRxJDskciRcbiIKKyAgICAgICJ9XG4iKSk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkMSA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkMiA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgxKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2knLCBmaWVsZDEpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdiJywgZmllbGQxLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIGZpZWxkMSwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnZicsIGZpZWxkMSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2cnLCAnaCcsIGZpZWxkMSwgIm51bWJlciIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdqJywgJ3InLCBmaWVsZDIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaicsICdrJywgZmllbGQyLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2wnLCAnbScsIGZpZWxkMiwgInR5cGVfbmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignbicsICdvJywgZmllbGQyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigncCcsICdxJywgZmllbGQyLCAibnVtYmVyIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm1lc3NhZ2VfdHlwZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm1lc3NhZ2VfdHlwZSgwKSwgIm5hbWUiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRXh0ZW5zaW9ucykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICIkYSRleHRlbmQgJGIkRm9vJGMkIHtcbiIKKyAgICAgICIgICRkJG9wdGlvbmFsJGUkIGludDMyIGJhciA9IDE7JGYkXG4iCisgICAgICAiICAkZyRyZXBlYXRlZCRoJCBYLlkgYmF6ID0gMjskaSRcbiIKKyAgICAgICJ9JGokXG4iCisgICAgICAiJGskZXh0ZW5kICRsJEJhciRtJCB7XG4iCisgICAgICAiICAkbiRvcHRpb25hbCBpbnQzMiBxdXggPSAxOyRvJFxuIgorICAgICAgIn0kcCRcbiIpKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQxID0gZmlsZV8uZXh0ZW5zaW9uKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQyID0gZmlsZV8uZXh0ZW5zaW9uKDEpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQzID0gZmlsZV8uZXh0ZW5zaW9uKDIpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaicsIGZpbGVfLCAiZXh0ZW5zaW9uIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdrJywgJ3AnLCBmaWxlXywgImV4dGVuc2lvbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdkJywgJ2YnLCBmaWVsZDEpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgZmllbGQxLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpZWxkMSwgImV4dGVuZGVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2cnLCAnaScsIGZpZWxkMikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdnJywgJ2gnLCBmaWVsZDIsICJsYWJlbCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgZmllbGQyLCAiZXh0ZW5kZWUiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignbicsICdvJywgZmllbGQzKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2wnLCAnbScsIGZpZWxkMywgImV4dGVuZGVlIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMSwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQxLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDEsICJudW1iZXIiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAidHlwZV9uYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQzLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDMsICJudW1iZXIiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgTmVzdGVkRXh0ZW5zaW9ucykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICJtZXNzYWdlIE1lc3NhZ2Uge1xuIgorICAgICAgIiAgJGEkZXh0ZW5kICRiJEZvbyRjJCB7XG4iCisgICAgICAiICAgICRkJG9wdGlvbmFsJGUkIGludDMyIGJhciA9IDE7JGYkXG4iCisgICAgICAiICAgICRnJHJlcGVhdGVkJGgkIFguWSBiYXogPSAyOyRpJFxuIgorICAgICAgIiAgfSRqJFxuIgorICAgICAgIiAgJGskZXh0ZW5kICRsJEJhciRtJCB7XG4iCisgICAgICAiICAgICRuJG9wdGlvbmFsIGludDMyIHF1eCA9IDE7JG8kXG4iCisgICAgICAiICB9JHAkXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZDEgPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZXh0ZW5zaW9uKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQyID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLmV4dGVuc2lvbigxKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkMyA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5leHRlbnNpb24oMik7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdqJywgZmlsZV8ubWVzc2FnZV90eXBlKDApLCAiZXh0ZW5zaW9uIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdrJywgJ3AnLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJleHRlbnNpb24iKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdmJywgZmllbGQxKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2QnLCAnZScsIGZpZWxkMSwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBmaWVsZDEsICJleHRlbmRlZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdnJywgJ2knLCBmaWVsZDIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZycsICdoJywgZmllbGQyLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpZWxkMiwgImV4dGVuZGVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ24nLCAnbycsIGZpZWxkMykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdsJywgJ20nLCBmaWVsZDMsICJleHRlbmRlZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMSwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQxLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDEsICJudW1iZXIiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAidHlwZV9uYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQzLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDMsICJudW1iZXIiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRXh0ZW5zaW9uUmFuZ2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgTWVzc2FnZSB7XG4iCisgICAgICAiICAkYSRleHRlbnNpb25zICRiJDEkYyQgdG8gJGQkNCRlJCwgJGYkNiRnJDskaCRcbiIKKyAgICAgICIgICRpJGV4dGVuc2lvbnMgJGokOCRrJCB0byAkbCRtYXgkbSQ7JG4kXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UmIHJhbmdlMSA9CisgICAgICBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZXh0ZW5zaW9uX3JhbmdlKDApOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG86OkV4dGVuc2lvblJhbmdlJiByYW5nZTIgPQorICAgICAgZmlsZV8ubWVzc2FnZV90eXBlKDApLmV4dGVuc2lvbl9yYW5nZSgxKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvOjpFeHRlbnNpb25SYW5nZSYgcmFuZ2UzID0KKyAgICAgIGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5leHRlbnNpb25fcmFuZ2UoMik7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdoJywgZmlsZV8ubWVzc2FnZV90eXBlKDApLCAiZXh0ZW5zaW9uX3JhbmdlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ24nLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJleHRlbnNpb25fcmFuZ2UiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdlJywgcmFuZ2UxKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIHJhbmdlMSwgInN0YXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdkJywgJ2UnLCByYW5nZTEsICJlbmQiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdnJywgcmFuZ2UyKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIHJhbmdlMiwgInN0YXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCByYW5nZTIsICJlbmQiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaicsICdtJywgcmFuZ2UzKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2onLCAnaycsIHJhbmdlMywgInN0YXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdsJywgJ20nLCByYW5nZTMsICJlbmQiKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKK30KKworVEVTVF9GKFNvdXJjZUluZm9UZXN0LCBPbmVvZnMpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgJGEkb25lb2YgJGMkZm9vJGQkIHtcbiIKKyAgICAgICIgICAgJGUkaW50MzIkZiQgJGckYSRoJCA9ICRpJDEkaiQ7JGskXG4iCisgICAgICAiICB9JHIkXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBvbmVvZl9kZWNsID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLm9uZW9mX2RlY2woMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZCA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ3InLCBvbmVvZl9kZWNsKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIG9uZW9mX2RlY2wsICJuYW1lIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnaycsIGZpZWxkKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnZicsIGZpZWxkLCAidHlwZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZycsICdoJywgZmllbGQsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ2onLCBmaWVsZCwgIm51bWJlciIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE5lc3RlZE1lc3NhZ2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgICRhJG1lc3NhZ2UgJGIkQmFyJGMkIHtcbiIKKyAgICAgICIgICAgJGQkbWVzc2FnZSAkZSRCYXokZiQge30kZyRcbiIKKyAgICAgICIgIH0kaCRcbiIKKyAgICAgICIgICRpJG1lc3NhZ2UgJGokUXV4JGskIHt9JGwkXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgYmFyID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLm5lc3RlZF90eXBlKDApOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGJheiA9IGJhci5uZXN0ZWRfdHlwZSgwKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBxdXggPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkubmVzdGVkX3R5cGUoMSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdoJywgYmFyKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2QnLCAnZycsIGJheikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2YnLCBiYXosICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ2wnLCBxdXgpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaicsICdrJywgcXV4LCAibmFtZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEdyb3VwcykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgICAiICBtZXNzYWdlIEJhciB7fVxuIgorICAgICAgIiAgJGEkb3B0aW9uYWwkYiQgJGMkZ3JvdXAkZCQgJGUkQmF6JGYkID0gJGckMSRoJCB7XG4iCisgICAgICAiICAgICRpJG1lc3NhZ2UgUXV4IHt9JGokXG4iCisgICAgICAiICB9JGskXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgYmFyID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLm5lc3RlZF90eXBlKDApOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGJheiA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5uZXN0ZWRfdHlwZSgxKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBxdXggPSBiYXoubmVzdGVkX3R5cGUoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZCA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2snLCBmaWVsZCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2InLCBmaWVsZCwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdjJywgJ2QnLCBmaWVsZCwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnZicsIGZpZWxkLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdmJywgZmllbGQsICJ0eXBlX25hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2cnLCAnaCcsIGZpZWxkLCAibnVtYmVyIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaycsIGJheikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2YnLCBiYXosICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ2onLCBxdXgpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhcikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ocXV4LCAibmFtZSIpKTsKK30KKworVEVTVF9GKFNvdXJjZUluZm9UZXN0LCBFbnVtcykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICIkYSRlbnVtICRiJEZvbyRjJCB7fSRkJFxuIgorICAgICAgIiRlJGVudW0gJGYkQmFyJGckIHt9JGgkXG4iKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdkJywgZmlsZV8uZW51bV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpbGVfLmVudW1fdHlwZSgwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnaCcsIGZpbGVfLmVudW1fdHlwZSgxKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCBmaWxlXy5lbnVtX3R5cGUoMSksICJuYW1lIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEVudW1WYWx1ZXMpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAiZW51bSBGb28ge1xuIgorICAgICAgIiAgJGEkQkFSJGIkID0gJGMkMSRkJDskZSRcbiIKKyAgICAgICIgICRmJEJBWiRnJCA9ICRoJDIkaSQ7JGokXG4iCisgICAgICAifSIpKTsKKworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGJhciA9IGZpbGVfLmVudW1fdHlwZSgwKS52YWx1ZSgwKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBiYXogPSBmaWxlXy5lbnVtX3R5cGUoMCkudmFsdWUoMSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdlJywgYmFyKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnYicsIGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIGJhciwgIm51bWJlciIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdqJywgYmF6KSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIGJheiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2gnLCAnaScsIGJheiwgIm51bWJlciIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE5lc3RlZEVudW1zKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgICRhJGVudW0gJGIkQmFyJGMkIHt9JGQkXG4iCisgICAgICAiICAkZSRlbnVtICRmJEJheiRnJCB7fSRoJFxuIgorICAgICAgIn1cbiIpKTsKKworICBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBiYXIgPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZW51bV90eXBlKDApOworICBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBiYXogPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZW51bV90eXBlKDEpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnZCcsIGJhcikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBiYXIsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2gnLCBiYXopKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdnJywgYmF6LCAibmFtZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIFNlcnZpY2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJHNlcnZpY2UgJGIkRm9vJGMkIHt9JGQkXG4iCisgICAgICAiJGUkc2VydmljZSAkZiRCYXIkZyQge30kaCRcbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2QnLCBmaWxlXy5zZXJ2aWNlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpbGVfLnNlcnZpY2UoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2gnLCBmaWxlXy5zZXJ2aWNlKDEpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIGZpbGVfLnNlcnZpY2UoMSksICJuYW1lIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE1ldGhvZHNBbmRTdHJlYW1zKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgInNlcnZpY2UgRm9vIHtcbiIKKyAgICAgICIgICRhJHJwYyAkYiRCYXIkYyQoJGQkWCRlJCkgcmV0dXJucygkZiRZJGckKTskaCQiCisgICAgICAiICAkaSRycGMgJGokQmF6JGskKCRsJFokbSQpIHJldHVybnMoJG4kVyRvJCk7JHAkIgorICAgICAgIn0iKSk7CisKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBiYXIgPSBmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKTsKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBiYXogPSBmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgxKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2gnLCBiYXIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgYmFyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgYmFyLCAiaW5wdXRfdHlwZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdnJywgYmFyLCAib3V0cHV0X3R5cGUiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaScsICdwJywgYmF6KSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2onLCAnaycsIGJheiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2wnLCAnbScsIGJheiwgImlucHV0X3R5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ24nLCAnbycsIGJheiwgIm91dHB1dF90eXBlIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLCAibmFtZSIpKTsKK30KKworCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE9wdGlvbnMpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAiJGEkb3B0aW9uICRiJGZvbyRjJC4kZCQoJGUkYmFyLmJheiRmJCkkZyQgPSAiCisgICAgICAgICAgIiRoJDEyMyRpJDskaiRcbiIKKyAgICAgICIkayRvcHRpb24gcXV4ID0gJGwkLTEyMyRtJDskbiRcbiIKKyAgICAgICIkbyRvcHRpb24gY29yZ2UgPSAkcCRhYmMkcSQ7JHIkXG4iCisgICAgICAiJHMkb3B0aW9uIGdyYXVsdCA9ICR0JCdibGFoJyR1JDskdiRcbiIKKyAgICAgICIkdyRvcHRpb24gZ2FycGx5ID0gJHgkeyB5YWRkYSB5YWRkYSB9JHkkOyR6JFxuIgorICAgICAgIiQwJG9wdGlvbiB3YWxkbyA9ICQxJDEyMy4wJDIkOyQzJFxuIgorICApKTsKKworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24xID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24yID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDEpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24zID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDIpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb240ID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDMpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb241ID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDQpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb242ID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDUpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaicsIGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2onLCBvcHRpb24xKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnZycsIG9wdGlvbjEsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBvcHRpb24xLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgb3B0aW9uMS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdkJywgJ2cnLCBvcHRpb24xLm5hbWUoMSkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdmJywgb3B0aW9uMS5uYW1lKDEpLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdoJywgJ2knLCBvcHRpb24xLCAicG9zaXRpdmVfaW50X3ZhbHVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2snLCAnbicsIGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdsJywgJ20nLCBvcHRpb24yLCAibmVnYXRpdmVfaW50X3ZhbHVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ28nLCAncicsIGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdwJywgJ3EnLCBvcHRpb24zLCAiaWRlbnRpZmllcl92YWx1ZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdzJywgJ3YnLCBmaWxlXy5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigndCcsICd1Jywgb3B0aW9uNCwgInN0cmluZ192YWx1ZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCd3JywgJ3onLCBmaWxlXy5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigneCcsICd5Jywgb3B0aW9uNSwgImFnZ3JlZ2F0ZV92YWx1ZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCcwJywgJzMnLCBmaWxlXy5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignMScsICcyJywgb3B0aW9uNiwgImRvdWJsZV92YWx1ZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjQpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb241KSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uNikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjMsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjQsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjUsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjYsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjMubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjQubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjUubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjYubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24zLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uNC5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjUubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb242Lm5hbWUoMCksICJuYW1lX3BhcnQiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgU2NvcGVkT3B0aW9ucykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgICRhJG9wdGlvbiBtb3B0ID0gMTskYiRcbiIKKyAgICAifVxuIgorICAgICJlbnVtIEJhciB7XG4iCisgICAgIiAgJGMkb3B0aW9uIGVvcHQgPSAxOyRkJFxuIgorICAgICJ9XG4iCisgICAgInNlcnZpY2UgQmF6IHtcbiIKKyAgICAiICAkZSRvcHRpb24gc29wdCA9IDE7JGYkXG4iCisgICAgIiAgcnBjIE0oWCkgcmV0dXJucyhZKSB7XG4iCisgICAgIiAgICAkZyRvcHRpb24gbW9wdCA9IDE7JGgkXG4iCisgICAgIiAgfVxuIgorICAgICIgIHJwYyBNUzQoJDEkc3RyZWFtJDIkIFgpIHJldHVybnMoJDMkc3RyZWFtJDQkIFkpIHtcbiIKKyAgICAiICAgICRrJG9wdGlvbiBtb3B0ID0gMTskbCRcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2InLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCkub3B0aW9ucygpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIGZpbGVfLmVudW1fdHlwZSgwKS5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdmJywgZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZycsICdoJywgZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMCkub3B0aW9ucygpKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLmVudW1fdHlwZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApLCAiaW5wdXRfdHlwZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKSwgIm91dHB1dF90eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaycsICdsJywgZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkub3B0aW9ucygpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgxKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSksICJpbnB1dF90eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLCAib3V0cHV0X3R5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgxKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgInBvc2l0aXZlX2ludF92YWx1ZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignMScsICcyJywgZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSksCisgICAgICAgICAgICAgICAgICAgICAgImNsaWVudF9zdHJlYW1pbmciKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJzMnLCAnNCcsIGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLAorICAgICAgICAgICAgICAgICAgICAgICJzZXJ2ZXJfc3RyZWFtaW5nIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEZpZWxkT3B0aW9ucykgeworICAvLyBUaGUgYWN0dWFsICJuYW1lID0gdmFsdWUiIHBhaXJzIGFyZSBwYXJzZWQgYnkgdGhlIHNhbWUgY29kZSBhcyBmb3IKKyAgLy8gdG9wLWxldmVsIG9wdGlvbnMgc28gd2Ugd29uJ3QgcmUtdGVzdCB0aGF0IC0tIGp1c3QgbWFrZSBzdXJlIHRoYXQgdGhlCisgIC8vIHN5bnRheCB1c2VkIGZvciBmaWVsZCBvcHRpb25zIGlzIHVuZGVyc3Rvb2QuCisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHsiCisgICAgICAiICBvcHRpb25hbCBpbnQzMiBiYXIgPSAxICIKKyAgICAgICAgICAiJGEkW2RlZmF1bHQ9JGIkMTIzJGMkLCRkJG9wdDE9MTIzJGUkLCIKKyAgICAgICAgICAiJGYkb3B0Mj0naGknJGckXSRoJDsiCisgICAgICAifVxuIgorICApKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQgPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZmllbGQoMCk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIG9wdGlvbjEgPSBmaWVsZC5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIG9wdGlvbjIgPSBmaWVsZC5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdoJywgZmllbGQub3B0aW9ucygpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpZWxkLCAiZGVmYXVsdF92YWx1ZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgb3B0aW9uMSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCBvcHRpb24yKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQsICJ0eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZCwgIm51bWJlciIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24xLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24xLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24xLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMi5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEsICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMiwgInN0cmluZ192YWx1ZSIpKTsKK30KKworVEVTVF9GKFNvdXJjZUluZm9UZXN0LCBFbnVtVmFsdWVPcHRpb25zKSB7CisgIC8vIFRoZSBhY3R1YWwgIm5hbWUgPSB2YWx1ZSIgcGFpcnMgYXJlIHBhcnNlZCBieSB0aGUgc2FtZSBjb2RlIGFzIGZvcgorICAvLyB0b3AtbGV2ZWwgb3B0aW9ucyBzbyB3ZSB3b24ndCByZS10ZXN0IHRoYXQgLS0ganVzdCBtYWtlIHN1cmUgdGhhdCB0aGUKKyAgLy8gc3ludGF4IHVzZWQgZm9yIGVudW0gb3B0aW9ucyBpcyB1bmRlcnN0b29kLgorICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICJlbnVtIEZvbyB7IgorICAgICAgIiAgQkFSID0gMSAkYSRbJGIkb3B0MT0xMjMkYyQsJGQkb3B0Mj0naGknJGUkXSRmJDsiCisgICAgICAifVxuIgorICApKTsKKworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIHZhbHVlID0gZmlsZV8uZW51bV90eXBlKDApLnZhbHVlKDApOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24xID0gdmFsdWUub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24yID0gdmFsdWUub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDEpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnZicsIHZhbHVlLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBvcHRpb24xKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2QnLCAnZScsIG9wdGlvbjIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKHZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4odmFsdWUsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKHZhbHVlLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMSwgInBvc2l0aXZlX2ludF92YWx1ZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLCAic3RyaW5nX3ZhbHVlIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIERvY0NvbW1lbnRzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIi8vIEZvbyBsZWFkaW5nXG4iCisgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAiJGEkbWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgLy8gRm9vIHRyYWlsaW5nXG4iCisgICAgICAiICAvLyBsaW5lIDJcbiIKKyAgICAgICJcbiIKKyAgICAgICIgIC8vIGRldGFjaGVkXG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBiYXIgbGVhZGluZ1xuIgorICAgICAgIiAgJGIkb3B0aW9uYWwgaW50MzIgYmFyID0gMTskYyRcbiIKKyAgICAgICIgIC8vIGJhciB0cmFpbGluZ1xuIgorICAgICAgIn0kZCRcbiIKKyAgICAgICIvLyBpZ25vcmVkXG4iCisgICkpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgZm9vID0gZmlsZV8ubWVzc2FnZV90eXBlKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgYmFyID0gZm9vLmZpZWxkKDApOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW5XaXRoQ29tbWVudCgnYScsICdkJywgZm9vLAorICAgICAgIiBGb28gbGVhZGluZ1xuIGxpbmUgMlxuIiwKKyAgICAgICIgRm9vIHRyYWlsaW5nXG4gbGluZSAyXG4iLAorICAgICAgTlVMTCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2InLCAnYycsIGJhciwKKyAgICAgICIgYmFyIGxlYWRpbmdcbiIsCisgICAgICAiIGJhciB0cmFpbGluZ1xuIiwKKyAgICAgICIgZGV0YWNoZWRcbiIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28sICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJudW1iZXIiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRG9jQ29tbWVudHMyKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIi8vIGRldGFjaGVkIGJlZm9yZSBtZXNzYWdlLlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIEZvbyBsZWFkaW5nXG4iCisgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAiJGEkbWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgLyogRm9vIHRyYWlsaW5nXG4iCisgICAgICAiICAgKiBsaW5lIDIgKi9cbiIKKyAgICAgICIgIC8vIGRldGFjaGVkXG4iCisgICAgICAiICAvKiBiYXIgbGVhZGluZ1xuIgorICAgICAgIiAgICovIgorICAgICAgIiAgJGIkb3B0aW9uYWwgaW50MzIgYmFyID0gMTskYyQgIC8vIGJhciB0cmFpbGluZ1xuIgorICAgICAgIiAgLy8gaWdub3JlZCBkZXRhY2hlZFxuIgorICAgICAgIn0kZCRcbiIKKyAgICAgICIvLyBpZ25vcmVkXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gZGV0YWNoZWQgYmVmb3JlIG9wdGlvblxuIgorICAgICAgIlxuIgorICAgICAgIi8vIG9wdGlvbiBsZWFkaW5nXG4iCisgICAgICAiJGUkb3B0aW9uIGJheiA9IDEyMzskZiRcbiIKKyAgICAgICIvLyBvcHRpb24gdHJhaWxpbmdcbiIKKyAgKSk7CisKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBmb28gPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBiYXIgPSBmb28uZmllbGQoMCk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGJheiA9IGZpbGVfLm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbigwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2EnLCAnZCcsIGZvbywKKyAgICAgICIgRm9vIGxlYWRpbmdcbiBsaW5lIDJcbiIsCisgICAgICAiIEZvbyB0cmFpbGluZ1xuIGxpbmUgMiAiLAorICAgICAgIiBkZXRhY2hlZCBiZWZvcmUgbWVzc2FnZS5cbiIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbldpdGhDb21tZW50KCdiJywgJ2MnLCBiYXIsCisgICAgICAiIGJhciBsZWFkaW5nXG4iLAorICAgICAgIiBiYXIgdHJhaWxpbmdcbiIsCisgICAgICAiIGRldGFjaGVkXG4iKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW5XaXRoQ29tbWVudCgnZScsICdmJywgYmF6LAorICAgICAgIiBvcHRpb24gbGVhZGluZ1xuIiwKKyAgICAgICIgb3B0aW9uIHRyYWlsaW5nXG4iLAorICAgICAgIiBkZXRhY2hlZCBiZWZvcmUgb3B0aW9uXG4iKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZm9vLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJsYWJlbCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJ0eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJheiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmF6Lm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXoubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXosICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRG9jQ29tbWVudHMzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJG1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgIC8vIGJhciBsZWFkaW5nXG4iCisgICAgICAiICAkYiRvcHRpb25hbCBpbnQzMiBiYXIgPSAxIFsoYmF6LnF1eCkgPSB7fV07JGMkXG4iCisgICAgICAiICAvLyBiYXIgdHJhaWxpbmdcbiIKKyAgICAgICJ9JGQkXG4iCisgICAgICAiLy8gaWdub3JlZFxuIgorICApKTsKKworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZvbyA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGJhciA9IGZvby5maWVsZCgwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2InLCAnYycsIGJhciwKKyAgICAgICIgYmFyIGxlYWRpbmdcbiIsCisgICAgICAiIGJhciB0cmFpbGluZ1xuIiwKKyAgICAgIE5VTEwpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28sICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJudW1iZXIiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhci5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigKKyAgICAgIGJhci5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigKKyAgICAgIGJhci5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJhZ2dyZWdhdGVfdmFsdWUiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRG9jQ29tbWVudHNUb3BMZXZlbCkgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICIvLyBkZXRhY2hlZCBiZWZvcmUgc3ludGF4IHBhcmFncmFwaCAxXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gZGV0YWNoZWQgYmVmb3JlIHN5bnRheCBwYXJhZ3JhcGggMlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIHN5bnRheCBsZWFkaW5nXG4iCisgICAgICAiJGEkc3ludGF4ID0gXCJwcm90bzJcIjskYiRcbiIKKyAgICAgICIvLyBzeW50YXggdHJhaWxpbmdcbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBzeW50YXgtcGFja2FnZSBkZXRhY2hlZCBjb21tZW50c1xuIgorICAgICAgIlxuIgorICAgICAgIjtcbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBkZXRhY2hlZCBhZnRlciBlbXB0eSBiZWZvcmUgcGFja2FnZVxuIgorICAgICAgIlxuIgorICAgICAgIi8vIHBhY2thZ2UgbGVhZGluZ1xuIgorICAgICAgInBhY2thZ2UgJGMkZm9vJGQkO1xuIgorICAgICAgIi8vIHBhY2thZ2UgdHJhaWxpbmdcbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBpZ25vcmVkIGRldGFjaFxuIgorICAgICAgIlxuIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnYicsIGZpbGVfLCAic3ludGF4IiwgLTEsCisgICAgICAiIHN5bnRheCBsZWFkaW5nXG4iLAorICAgICAgIiBzeW50YXggdHJhaWxpbmdcbiIsCisgICAgICAiIGRldGFjaGVkIGJlZm9yZSBzeW50YXggcGFyYWdyYXBoIDFcbiIKKyAgICAgICJcbiIKKyAgICAgICIgZGV0YWNoZWQgYmVmb3JlIHN5bnRheCBwYXJhZ3JhcGggMlxuIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdjJywgJ2QnLCBmaWxlXywgInBhY2thZ2UiLCAtMSwKKyAgICAgICIgcGFja2FnZSBsZWFkaW5nXG4iLAorICAgICAgIiBwYWNrYWdlIHRyYWlsaW5nXG4iLAorICAgICAgIiBzeW50YXgtcGFja2FnZSBkZXRhY2hlZCBjb21tZW50c1xuIgorICAgICAgIlxuIgorICAgICAgIiBkZXRhY2hlZCBhZnRlciBlbXB0eSBiZWZvcmUgcGFja2FnZVxuIikpOworCisgIC8vIGlnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIERvY0NvbW1lbnRzT25lb2YpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAiLy8gRm9vIGxlYWRpbmdcbiIKKyAgICAgICIkYSRtZXNzYWdlIEZvbyB7XG4iCisgICAgICAiICAvKiBGb28gdHJhaWxpbmdcbiIKKyAgICAgICIgICAqL1xuIgorICAgICAgIiAgLy8gZGV0YWNoZWQgYmVmb3JlIG9uZW9mXG4iCisgICAgICAiICAvKiBiYXIgbGVhZGluZ1xuIgorICAgICAgIiAgICogbGluZSAyICovXG4iCisgICAgICAiICAkYiRvbmVvZiBiYXIge1xuIgorICAgICAgIiAgLyogYmFyIHRyYWlsaW5nXG4iCisgICAgICAiICAgKiBsaW5lIDIgKi9cbiIKKyAgICAgICIgIC8vIGRldGFjaGVkIGJlZm9yZSBiYXJfaW50XG4iCisgICAgICAiICAvKiBiYXJfaW50IGxlYWRpbmdcbiIKKyAgICAgICIgICAqL1xuIgorICAgICAgIiAgJGMkaW50MzIgYmFyX2ludCA9IDE7JGQkICAvLyBiYXJfaW50IHRyYWlsaW5nXG4iCisgICAgICAiICAvLyBkZXRhY2ggY29tbWVudCBpZ25vcmVkXG4iCisgICAgICAiICB9JGUkXG4iCisgICAgICAifSRmJFxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgZm9vID0gZmlsZV8ubWVzc2FnZV90eXBlKDApOworICBjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgYmFyID0gZm9vLm9uZW9mX2RlY2woMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBiYXJfaW50ID0gZm9vLmZpZWxkKDApOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW5XaXRoQ29tbWVudCgnYScsICdmJywgZm9vLAorICAgICAgIiBGb28gbGVhZGluZ1xuIiwKKyAgICAgICIgRm9vIHRyYWlsaW5nXG4iLAorICAgICAgTlVMTCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2InLCAnZScsIGJhciwKKyAgICAgICIgYmFyIGxlYWRpbmdcbiBsaW5lIDIgIiwKKyAgICAgICIgYmFyIHRyYWlsaW5nXG4gbGluZSAyICIsCisgICAgICAiIGRldGFjaGVkIGJlZm9yZSBvbmVvZlxuIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2MnLCAnZCcsIGJhcl9pbnQsCisgICAgICAiIGJhcl9pbnQgbGVhZGluZ1xuIiwKKyAgICAgICIgYmFyX2ludCB0cmFpbGluZ1xuIiwKKyAgICAgICIgZGV0YWNoZWQgYmVmb3JlIGJhcl9pbnRcbiIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28sICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyX2ludCwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyX2ludCwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyX2ludCwgIm51bWJlciIpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkNTAxYWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5jYwpAQCAtMCwwICsxLDE2NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaD4KKworI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPHNldD4KKworI2lmZGVmIF9XSU4zMgorI2luY2x1ZGUgPGlvLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpZm5kZWYgU1RESU5fRklMRU5PCisjZGVmaW5lIFNURElOX0ZJTEVOTyAwCisjZW5kaWYKKyNpZm5kZWYgU1RET1VUX0ZJTEVOTworI2RlZmluZSBTVERPVVRfRklMRU5PIDEKKyNlbmRpZgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCitjbGFzcyBHZW5lcmF0b3JSZXNwb25zZUNvbnRleHQgOiBwdWJsaWMgR2VuZXJhdG9yQ29udGV4dCB7CisgcHVibGljOgorICBHZW5lcmF0b3JSZXNwb25zZUNvbnRleHQoQ29kZUdlbmVyYXRvclJlc3BvbnNlKiByZXNwb25zZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBwYXJzZWRfZmlsZXMpCisgICAgICA6IHJlc3BvbnNlXyhyZXNwb25zZSksCisgICAgICAgIHBhcnNlZF9maWxlc18ocGFyc2VkX2ZpbGVzKSB7fQorICB2aXJ0dWFsIH5HZW5lcmF0b3JSZXNwb25zZUNvbnRleHQoKSB7fQorCisgIC8vIGltcGxlbWVudHMgR2VuZXJhdG9yQ29udGV4dCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHZpcnR1YWwgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgICBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OkZpbGUqIGZpbGUgPSByZXNwb25zZV8tPmFkZF9maWxlKCk7CisgICAgZmlsZS0+c2V0X25hbWUoZmlsZW5hbWUpOworICAgIHJldHVybiBuZXcgaW86OlN0cmluZ091dHB1dFN0cmVhbShmaWxlLT5tdXRhYmxlX2NvbnRlbnQoKSk7CisgIH0KKworICB2aXJ0dWFsIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogT3BlbkZvckluc2VydCgKKyAgICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9uX3BvaW50KSB7CisgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpGaWxlKiBmaWxlID0gcmVzcG9uc2VfLT5hZGRfZmlsZSgpOworICAgIGZpbGUtPnNldF9uYW1lKGZpbGVuYW1lKTsKKyAgICBmaWxlLT5zZXRfaW5zZXJ0aW9uX3BvaW50KGluc2VydGlvbl9wb2ludCk7CisgICAgcmV0dXJuIG5ldyBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtKGZpbGUtPm11dGFibGVfY29udGVudCgpKTsKKyAgfQorCisgIHZvaWQgTGlzdFBhcnNlZEZpbGVzKHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+KiBvdXRwdXQpIHsKKyAgICAqb3V0cHV0ID0gcGFyc2VkX2ZpbGVzXzsKKyAgfQorCisgcHJpdmF0ZToKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlKiByZXNwb25zZV87CisgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBwYXJzZWRfZmlsZXNfOworfTsKKworaW50IFBsdWdpbk1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSwgY29uc3QgQ29kZUdlbmVyYXRvciogZ2VuZXJhdG9yKSB7CisKKyAgaWYgKGFyZ2MgPiAxKSB7CisgICAgc3RkOjpjZXJyIDw8IGFyZ3ZbMF0gPDwgIjogVW5rbm93biBvcHRpb246ICIgPDwgYXJndlsxXSA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIDE7CisgIH0KKworI2lmZGVmIF9XSU4zMgorICBfc2V0bW9kZShTVERJTl9GSUxFTk8sIF9PX0JJTkFSWSk7CisgIF9zZXRtb2RlKFNURE9VVF9GSUxFTk8sIF9PX0JJTkFSWSk7CisjZW5kaWYKKworICBDb2RlR2VuZXJhdG9yUmVxdWVzdCByZXF1ZXN0OworICBpZiAoIXJlcXVlc3QuUGFyc2VGcm9tRmlsZURlc2NyaXB0b3IoU1RESU5fRklMRU5PKSkgeworICAgIHN0ZDo6Y2VyciA8PCBhcmd2WzBdIDw8ICI6IHByb3RvYyBzZW50IHVucGFyc2VhYmxlIHJlcXVlc3QgdG8gcGx1Z2luLiIKKyAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgIHJldHVybiAxOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXF1ZXN0LnByb3RvX2ZpbGVfc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuQnVpbGRGaWxlKHJlcXVlc3QucHJvdG9fZmlsZShpKSk7CisgICAgaWYgKGZpbGUgPT0gTlVMTCkgeworICAgICAgLy8gQnVpbGRGaWxlKCkgYWxyZWFkeSB3cm90ZSBhbiBlcnJvciBtZXNzYWdlLgorICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisKKyAgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gcGFyc2VkX2ZpbGVzOworICBmb3IgKGludCBpID0gMDsgaSA8IHJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZV9zaXplKCk7IGkrKykgeworICAgIHBhcnNlZF9maWxlcy5wdXNoX2JhY2socG9vbC5GaW5kRmlsZUJ5TmFtZShyZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUoaSkpKTsKKyAgICBpZiAocGFyc2VkX2ZpbGVzLmJhY2soKSA9PSBOVUxMKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgYXJndlswXSA8PCAiOiBwcm90b2MgYXNrZWQgcGx1Z2luIHRvIGdlbmVyYXRlIGEgZmlsZSBidXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRpZCBub3QgcHJvdmlkZSBhIGRlc2NyaXB0b3IgZm9yIHRoZSBmaWxlOiAiCisgICAgICAgICAgICAgICAgPDwgcmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKGkpIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorCisgIENvZGVHZW5lcmF0b3JSZXNwb25zZSByZXNwb25zZTsKKyAgR2VuZXJhdG9yUmVzcG9uc2VDb250ZXh0IGNvbnRleHQoJnJlc3BvbnNlLCBwYXJzZWRfZmlsZXMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwYXJzZWRfZmlsZXNbaV07CisKKyAgICBzdHJpbmcgZXJyb3I7CisgICAgYm9vbCBzdWNjZWVkZWQgPSBnZW5lcmF0b3ItPkdlbmVyYXRlKAorICAgICAgICBmaWxlLCByZXF1ZXN0LnBhcmFtZXRlcigpLCAmY29udGV4dCwgJmVycm9yKTsKKworICAgIGlmICghc3VjY2VlZGVkICYmIGVycm9yLmVtcHR5KCkpIHsKKyAgICAgIGVycm9yID0gIkNvZGUgZ2VuZXJhdG9yIHJldHVybmVkIGZhbHNlIGJ1dCBwcm92aWRlZCBubyBlcnJvciAiCisgICAgICAgICAgICAgICJkZXNjcmlwdGlvbi4iOworICAgIH0KKyAgICBpZiAoIWVycm9yLmVtcHR5KCkpIHsKKyAgICAgIHJlc3BvbnNlLnNldF9lcnJvcihmaWxlLT5uYW1lKCkgKyAiOiAiICsgZXJyb3IpOworICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgaWYgKCFyZXNwb25zZS5TZXJpYWxpemVUb0ZpbGVEZXNjcmlwdG9yKFNURE9VVF9GSUxFTk8pKSB7CisgICAgc3RkOjpjZXJyIDw8IGFyZ3ZbMF0gPDwgIjogRXJyb3Igd3JpdGluZyB0byBzdGRvdXQuIiA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIDE7CisgIH0KKworICByZXR1cm4gMDsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3OWY5YmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oCkBAIC0wLDAgKzEsNzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gRnJvbnQtZW5kIGZvciBwcm90b2MgY29kZSBnZW5lcmF0b3IgcGx1Z2lucyB3cml0dGVuIGluIEMrKy4KKy8vCisvLyBUbyBpbXBsZW1lbnQgYSBwcm90b2MgcGx1Z2luIGluIEMrKywgc2ltcGx5IHdyaXRlIGFuIGltcGxlbWVudGF0aW9uIG9mCisvLyBDb2RlR2VuZXJhdG9yLCB0aGVuIGNyZWF0ZSBhIG1haW4oKSBmdW5jdGlvbiBsaWtlOgorLy8gICBpbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CisvLyAgICAgTXlDb2RlR2VuZXJhdG9yIGdlbmVyYXRvcjsKKy8vICAgICByZXR1cm4gZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OlBsdWdpbk1haW4oYXJnYywgYXJndiwgJmdlbmVyYXRvcik7CisvLyAgIH0KKy8vIFlvdSBtdXN0IGxpbmsgeW91ciBwbHVnaW4gYWdhaW5zdCBsaWJwcm90b2J1ZiBhbmQgbGlicHJvdG9jLgorLy8KKy8vIFRvIGdldCBwcm90b2MgdG8gdXNlIHRoZSBwbHVnaW4sIGRvIG9uZSBvZiB0aGUgZm9sbG93aW5nOgorLy8gKiBQbGFjZSB0aGUgcGx1Z2luIGJpbmFyeSBzb21ld2hlcmUgaW4gdGhlIFBBVEggYW5kIGdpdmUgaXQgdGhlIG5hbWUKKy8vICAgInByb3RvYy1nZW4tTkFNRSIgKHJlcGxhY2luZyAiTkFNRSIgd2l0aCB0aGUgbmFtZSBvZiB5b3VyIHBsdWdpbikuICBJZiB5b3UKKy8vICAgdGhlbiBpbnZva2UgcHJvdG9jIHdpdGggdGhlIHBhcmFtZXRlciAtLU5BTUVfb3V0PU9VVF9ESVIgKGFnYWluLCByZXBsYWNlCisvLyAgICJOQU1FIiB3aXRoIHlvdXIgcGx1Z2luJ3MgbmFtZSksIHByb3RvYyB3aWxsIGludm9rZSB5b3VyIHBsdWdpbiB0byBnZW5lcmF0ZQorLy8gICB0aGUgb3V0cHV0LCB3aGljaCB3aWxsIGJlIHBsYWNlZCBpbiBPVVRfRElSLgorLy8gKiBQbGFjZSB0aGUgcGx1Z2luIGJpbmFyeSBhbnl3aGVyZSwgd2l0aCBhbnkgbmFtZSwgYW5kIHBhc3MgdGhlIC0tcGx1Z2luCisvLyAgIHBhcmFtZXRlciB0byBwcm90b2MgdG8gZGlyZWN0IGl0IHRvIHlvdXIgcGx1Z2luIGxpa2Ugc286CisvLyAgICAgcHJvdG9jIC0tcGx1Z2luPXByb3RvYy1nZW4tTkFNRT1wYXRoL3RvL215YmluYXJ5IC0tTkFNRV9vdXQ9T1VUX0RJUgorLy8gICBPbiBXaW5kb3dzLCBtYWtlIHN1cmUgdG8gaW5jbHVkZSB0aGUgLmV4ZSBzdWZmaXg6CisvLyAgICAgcHJvdG9jIC0tcGx1Z2luPXByb3RvYy1nZW4tTkFNRT1wYXRoL3RvL215YmluYXJ5LmV4ZSAtLU5BTUVfb3V0PU9VVF9ESVIKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUExVR0lOX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUExVR0lOX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworY2xhc3MgQ29kZUdlbmVyYXRvcjsgICAgLy8gY29kZV9nZW5lcmF0b3IuaAorCisvLyBJbXBsZW1lbnRzIG1haW4oKSBmb3IgYSBwcm90b2MgcGx1Z2luIGV4cG9zaW5nIHRoZSBnaXZlbiBjb2RlIGdlbmVyYXRvci4KK0xJQlBST1RPQ19FWFBPUlQgaW50IFBsdWdpbk1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSwgY29uc3QgQ29kZUdlbmVyYXRvciogZ2VuZXJhdG9yKTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUExVR0lOX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWQxNzI2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MKQEAgLTAsMCArMSwxNTYzIEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCisKKyNkZWZpbmUgSU5URVJOQUxfU1VQUFJFU1NfUFJPVE9CVUZfRklFTERfREVQUkVDQVRJT04KKyNpbmNsdWRlICJnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmgiCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGluY2x1ZGVzKQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCituYW1lc3BhY2UgeworCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIENvZGVHZW5lcmF0b3JSZXF1ZXN0X2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBDb2RlR2VuZXJhdG9yUmVxdWVzdF9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX3JlZmxlY3Rpb25fID0gTlVMTDsKKworfSAgLy8gbmFtZXNwYWNlCisKKwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpIHsKKyAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wcm90byIpOworICBHT09HTEVfQ0hFQ0soZmlsZSAhPSBOVUxMKTsKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3RfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Rfb2Zmc2V0c19bM10gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVxdWVzdCwgZmlsZV90b19nZW5lcmF0ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlcXVlc3QsIHBhcmFtZXRlcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlcXVlc3QsIHByb3RvX2ZpbGVfKSwKKyAgfTsKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3RfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIENvZGVHZW5lcmF0b3JSZXF1ZXN0X2Rlc2NyaXB0b3JfLAorICAgICAgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgQ29kZUdlbmVyYXRvclJlcXVlc3Rfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKENvZGVHZW5lcmF0b3JSZXF1ZXN0LCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoQ29kZUdlbmVyYXRvclJlcXVlc3QpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVxdWVzdCwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgxKTsKKyAgc3RhdGljIGNvbnN0IGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2Vfb2Zmc2V0c19bMl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2UsIGVycm9yXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2UsIGZpbGVfKSwKKyAgfTsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfZGVzY3JpcHRvcl8sCisgICAgICBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2UsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihDb2RlR2VuZXJhdG9yUmVzcG9uc2UpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2UsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9kZXNjcmlwdG9yXyA9IENvZGVHZW5lcmF0b3JSZXNwb25zZV9kZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfb2Zmc2V0c19bM10gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUsIGluc2VydGlvbl9wb2ludF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUsIGNvbnRlbnRfKSwKKyAgfTsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX2Rlc2NyaXB0b3JfLAorICAgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7Cit9CisKK25hbWVzcGFjZSB7CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8pOworaW5saW5lIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXywKKyAgICAgICAgICAgICAgICAgJnByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKTsKK30KKwordm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIENvZGVHZW5lcmF0b3JSZXF1ZXN0X2Rlc2NyaXB0b3JfLCAmQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX2Rlc2NyaXB0b3JfLCAmQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX2Rlc2NyaXB0b3JfLCAmQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKSB7CisgIGRlbGV0ZSBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBDb2RlR2VuZXJhdG9yUmVxdWVzdF9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9yZWZsZWN0aW9uXzsKK30KKwordm9pZCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpIHsKKyAgc3RhdGljIGJvb2wgYWxyZWFkeV9oZXJlID0gZmFsc2U7CisgIGlmIChhbHJlYWR5X2hlcmUpIHJldHVybjsKKyAgYWxyZWFkeV9oZXJlID0gdHJ1ZTsKKyAgR09PR0xFX1BST1RPQlVGX1ZFUklGWV9WRVJTSU9OOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6cHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoCisgICAgIlxuJWdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG9cMDIyIgorICAgICJcMDMwZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyXDAzMiBnb29nbGUvcHJvdG9iIgorICAgICJ1Zi9kZXNjcmlwdG9yLnByb3RvXCJ9XG5cMDI0Q29kZUdlbmVyYXRvclJlcXUiCisgICAgImVzdFwwMjJcMDMwXG5cMDIwZmlsZV90b19nZW5lcmF0ZVwwMzBcMDAxIFwwMDMoXHRcMDIyXDAyMVxuXHRwYXJhbWV0IgorICAgICJlclwwMzBcMDAyIFwwMDEoXHRcMDIyOFxuXG5wcm90b19maWxlXDAzMFwwMTcgXDAwMyhcMDEzMiQuZ29vZ2xlLnByIgorICAgICJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90b1wiXDI1MlwwMDFcblwwMjVDb2RlR2VuZXIiCisgICAgImF0b3JSZXNwb25zZVwwMjJcclxuXDAwNWVycm9yXDAzMFwwMDEgXDAwMShcdFwwMjJCXG5cMDA0ZmlsZVwwMzBcMDE3IFwwMDMoIgorICAgICJcMDEzMjQuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0IgorICAgICJvclJlc3BvbnNlLkZpbGVcMDMyPlxuXDAwNEZpbGVcMDIyXDAxNFxuXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0XDAyMlwwMjdcbiIKKyAgICAiXDAxN2luc2VydGlvbl9wb2ludFwwMzBcMDAyIFwwMDEoXHRcMDIyXDAxN1xuXDAwN2NvbnRlbnRcMDMwXDAxNyBcMDAxKFx0QiIKKyAgICAiN1xuXDAzNGNvbS5nb29nbGUucHJvdG9idWYuY29tcGlsZXJCXDAxNFBsdWdpblAiCisgICAgInJvdG9zWlx0cGx1Z2luX2dvIiwgNDU2KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBDb2RlR2VuZXJhdG9yUmVxdWVzdCgpOworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IENvZGVHZW5lcmF0b3JSZXNwb25zZSgpOworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUoKTsKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJnByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8pOworfQorCisvLyBGb3JjZSBBZGREZXNjcmlwdG9ycygpIHRvIGJlIGNhbGxlZCBhdCBzdGF0aWMgaW5pdGlhbGl6YXRpb24gdGltZS4KK3N0cnVjdCBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpIHsKKyAgICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICB9Cit9IHN0YXRpY19kZXNjcmlwdG9yX2luaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90b187CisKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDsKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIHsKKyAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCBfX0ZJTEVfXyA8PCAiOiIgPDwgbGluZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmtGaWxlVG9HZW5lcmF0ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IENvZGVHZW5lcmF0b3JSZXF1ZXN0OjprUGFyYW1ldGVyRmllbGROdW1iZXI7Citjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmtQcm90b0ZpbGVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0OjpDb2RlR2VuZXJhdG9yUmVxdWVzdCgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Q29kZUdlbmVyYXRvclJlcXVlc3QoY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QpCit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBwYXJhbWV0ZXJfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworQ29kZUdlbmVyYXRvclJlcXVlc3Q6On5Db2RlR2VuZXJhdG9yUmVxdWVzdCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OlNoYXJlZER0b3IoKSB7CisgIHBhcmFtZXRlcl8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gQ29kZUdlbmVyYXRvclJlcXVlc3RfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0KiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitDb2RlR2VuZXJhdG9yUmVxdWVzdCogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBDb2RlR2VuZXJhdG9yUmVxdWVzdCogbiA9IG5ldyBDb2RlR2VuZXJhdG9yUmVxdWVzdDsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpDbGVhcigpIHsKKyAgaWYgKGhhc19wYXJhbWV0ZXIoKSkgeworICAgIHBhcmFtZXRlcl8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIGZpbGVfdG9fZ2VuZXJhdGVfLkNsZWFyKCk7CisgIHByb3RvX2ZpbGVfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICBwYXJzZV9maWxlX3RvX2dlbmVyYXRlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZSh0aGlzLT5maWxlX3RvX2dlbmVyYXRlX3NpemUoKSAtIDEpLmRhdGEoKSwKKyAgICAgICAgICAgIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUodGhpcy0+ZmlsZV90b19nZW5lcmF0ZV9zaXplKCkgLSAxKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMCkpIGdvdG8gcGFyc2VfZmlsZV90b19nZW5lcmF0ZTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3BhcmFtZXRlcjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX3BhcmFtZXRlcjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfcGFyYW1ldGVyKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnBhcmFtZXRlcigpLmRhdGEoKSwgdGhpcy0+cGFyYW1ldGVyKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjIpKSBnb3RvIHBhcnNlX3Byb3RvX2ZpbGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fZmlsZSA9IDE1OworICAgICAgY2FzZSAxNTogeworICAgICAgICBpZiAodGFnID09IDEyMikgeworICAgICAgICAgcGFyc2VfcHJvdG9fZmlsZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfcHJvdG9fZmlsZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjIpKSBnb3RvIHBhcnNlX3Byb3RvX2ZpbGU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGZpbGVfdG9fZ2VuZXJhdGUgPSAxOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGVfc2l6ZSgpOyBpKyspIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZShpKS5kYXRhKCksIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSkubGVuZ3RoKCksCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZygKKyAgICAgIDEsIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgcGFyYW1ldGVyID0gMjsKKyAgaWYgKGhhc19wYXJhbWV0ZXIoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+cGFyYW1ldGVyKCkuZGF0YSgpLCB0aGlzLT5wYXJhbWV0ZXIoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+cGFyYW1ldGVyKCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fZmlsZSA9IDE1OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnByb3RvX2ZpbGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDE1LCB0aGlzLT5wcm90b19maWxlKGkpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGZpbGVfdG9fZ2VuZXJhdGUgPSAxOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGVfc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSkuZGF0YSgpLCB0aGlzLT5maWxlX3RvX2dlbmVyYXRlKGkpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlIik7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVTdHJpbmdUb0FycmF5KDEsIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgcGFyYW1ldGVyID0gMjsKKyAgaWYgKGhhc19wYXJhbWV0ZXIoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+cGFyYW1ldGVyKCkuZGF0YSgpLCB0aGlzLT5wYXJhbWV0ZXIoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPnBhcmFtZXRlcigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX2ZpbGUgPSAxNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5wcm90b19maWxlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDE1LCB0aGlzLT5wcm90b19maWxlKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHBhcmFtZXRlciA9IDI7CisgIGlmIChoYXNfcGFyYW1ldGVyKCkpIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPnBhcmFtZXRlcigpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZmlsZV90b19nZW5lcmF0ZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICB0aGlzLT5maWxlX3RvX2dlbmVyYXRlKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBwcm90b19maWxlID0gMTU7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPnByb3RvX2ZpbGVfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnByb3RvX2ZpbGVfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPnByb3RvX2ZpbGUoaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0KiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QqPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6Ok1lcmdlRnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdCYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBmaWxlX3RvX2dlbmVyYXRlXy5NZXJnZUZyb20oZnJvbS5maWxlX3RvX2dlbmVyYXRlXyk7CisgIHByb3RvX2ZpbGVfLk1lcmdlRnJvbShmcm9tLnByb3RvX2ZpbGVfKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1sxIC8gMzJdICYgKDB4ZmZ1IDw8ICgxICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19wYXJhbWV0ZXIoKSkgeworICAgICAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgICAgIHBhcmFtZXRlcl8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnBhcmFtZXRlcl8pOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Q29weUZyb20oY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+cHJvdG9fZmlsZSgpKSkgcmV0dXJuIGZhbHNlOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6U3dhcChDb2RlR2VuZXJhdG9yUmVxdWVzdCogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OkludGVybmFsU3dhcChDb2RlR2VuZXJhdG9yUmVxdWVzdCogb3RoZXIpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZmlsZV90b19nZW5lcmF0ZV8pOworICBwYXJhbWV0ZXJfLlN3YXAoJm90aGVyLT5wYXJhbWV0ZXJfKTsKKyAgcHJvdG9fZmlsZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+cHJvdG9fZmlsZV8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gQ29kZUdlbmVyYXRvclJlcXVlc3RfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBDb2RlR2VuZXJhdG9yUmVxdWVzdF9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBDb2RlR2VuZXJhdG9yUmVxdWVzdAorCisvLyByZXBlYXRlZCBzdHJpbmcgZmlsZV90b19nZW5lcmF0ZSA9IDE7CisgaW50IENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpmaWxlX3RvX2dlbmVyYXRlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXy5zaXplKCk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Y2xlYXJfZmlsZV90b19nZW5lcmF0ZSgpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKKyAgcmV0dXJuIGZpbGVfdG9fZ2VuZXJhdGVfLkdldChpbmRleCk7Cit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXy5NdXRhYmxlKGluZGV4KTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIGZpbGVfdG9fZ2VuZXJhdGVfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9maWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoKSB7CisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9maWxlX3RvX2dlbmVyYXRlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JgorQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmZpbGVfdG9fZ2VuZXJhdGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0OjptdXRhYmxlX2ZpbGVfdG9fZ2VuZXJhdGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIHJldHVybiAmZmlsZV90b19nZW5lcmF0ZV87Cit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworIGJvb2wgQ29kZUdlbmVyYXRvclJlcXVlc3Q6Omhhc19wYXJhbWV0ZXIoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9oYXNfcGFyYW1ldGVyKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmNsZWFyX2hhc19wYXJhbWV0ZXIoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmNsZWFyX3BhcmFtZXRlcigpIHsKKyAgcGFyYW1ldGVyXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19wYXJhbWV0ZXIoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6cGFyYW1ldGVyKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCisgIHJldHVybiBwYXJhbWV0ZXJfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfcGFyYW1ldGVyKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIHBhcmFtZXRlcl8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9wYXJhbWV0ZXIoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgcGFyYW1ldGVyXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfcGFyYW1ldGVyKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3BhcmFtZXRlcigpOworICBwYXJhbWV0ZXJfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfcGFyYW1ldGVyKCkgeworICBzZXRfaGFzX3BhcmFtZXRlcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorICByZXR1cm4gcGFyYW1ldGVyXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpyZWxlYXNlX3BhcmFtZXRlcigpIHsKKyAgY2xlYXJfaGFzX3BhcmFtZXRlcigpOworICByZXR1cm4gcGFyYW1ldGVyXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9hbGxvY2F0ZWRfcGFyYW1ldGVyKDo6c3RkOjpzdHJpbmcqIHBhcmFtZXRlcikgeworICBpZiAocGFyYW1ldGVyICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3BhcmFtZXRlcigpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19wYXJhbWV0ZXIoKTsKKyAgfQorICBwYXJhbWV0ZXJfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBwYXJhbWV0ZXIpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fZmlsZSA9IDE1OworIGludCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6cHJvdG9fZmlsZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gcHJvdG9fZmlsZV8uc2l6ZSgpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmNsZWFyX3Byb3RvX2ZpbGUoKSB7CisgIHByb3RvX2ZpbGVfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvJiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6cHJvdG9fZmlsZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucHJvdG9fZmlsZSkKKyAgcmV0dXJuIHByb3RvX2ZpbGVfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9wcm90b19maWxlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucHJvdG9fZmlsZSkKKyAgcmV0dXJuIHByb3RvX2ZpbGVfLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9wcm90b19maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gcHJvdG9fZmlsZV8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiYKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0Ojpwcm90b19maWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucHJvdG9fZmlsZSkKKyAgcmV0dXJuIHByb3RvX2ZpbGVfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4qCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9wcm90b19maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gJnByb3RvX2ZpbGVfOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6a0luc2VydGlvblBvaW50RmllbGROdW1iZXI7Citjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmtDb250ZW50RmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorCitDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpICwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSAgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpbnNlcnRpb25fcG9pbnRfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY29udGVudF8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6fkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjb250ZW50Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0NvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBuID0gbmV3IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkNsZWFyKCkgeworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNykgeworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfaW5zZXJ0aW9uX3BvaW50KCkpIHsKKyAgICAgIGluc2VydGlvbl9wb2ludF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX2NvbnRlbnQoKSkgeworICAgICAgY29udGVudF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgfQorICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfaW5zZXJ0aW9uX3BvaW50OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGluc2VydGlvbl9wb2ludCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfaW5zZXJ0aW9uX3BvaW50OgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9pbnNlcnRpb25fcG9pbnQoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+aW5zZXJ0aW9uX3BvaW50KCkuZGF0YSgpLCB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDEyMikpIGdvdG8gcGFyc2VfY29udGVudDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBjb250ZW50ID0gMTU7CisgICAgICBjYXNlIDE1OiB7CisgICAgICAgIGlmICh0YWcgPT0gMTIyKSB7CisgICAgICAgICBwYXJzZV9jb250ZW50OgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9jb250ZW50KCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmNvbnRlbnQoKS5kYXRhKCksIHRoaXMtPmNvbnRlbnQoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworICBpZiAoaGFzX2luc2VydGlvbl9wb2ludCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKS5kYXRhKCksIHRoaXMtPmluc2VydGlvbl9wb2ludCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAyLCB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBjb250ZW50ID0gMTU7CisgIGlmIChoYXNfY29udGVudCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5jb250ZW50KCkuZGF0YSgpLCB0aGlzLT5jb250ZW50KCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxNSwgdGhpcy0+Y29udGVudCgpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworICBpZiAoaGFzX2luc2VydGlvbl9wb2ludCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKS5kYXRhKCksIHRoaXMtPmluc2VydGlvbl9wb2ludCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+aW5zZXJ0aW9uX3BvaW50KCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworICBpZiAoaGFzX2NvbnRlbnQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+Y29udGVudCgpLmRhdGEoKSwgdGhpcy0+Y29udGVudCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50Iik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDE1LCB0aGlzLT5jb250ZW50KCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNykgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKKyAgICBpZiAoaGFzX2luc2VydGlvbl9wb2ludCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKKyAgICBpZiAoaGFzX2NvbnRlbnQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+Y29udGVudCgpKTsKKyAgICB9CisKKyAgfQorICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6TWVyZ2VGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX25hbWUoKTsKKyAgICAgIG5hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5uYW1lXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19pbnNlcnRpb25fcG9pbnQoKSkgeworICAgICAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgICAgIGluc2VydGlvbl9wb2ludF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmluc2VydGlvbl9wb2ludF8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfY29udGVudCgpKSB7CisgICAgICBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgICAgIGNvbnRlbnRfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5jb250ZW50Xyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpDb3B5RnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OlN3YXAoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpJbnRlcm5hbFN3YXAoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIG90aGVyKSB7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIGluc2VydGlvbl9wb2ludF8uU3dhcCgmb3RoZXItPmluc2VydGlvbl9wb2ludF8pOworICBjb250ZW50Xy5Td2FwKCZvdGhlci0+Y29udGVudF8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IENvZGVHZW5lcmF0b3JSZXNwb25zZTo6a0Vycm9yRmllbGROdW1iZXI7Citjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjprRmlsZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2UoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpICwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSAgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OkNvZGVHZW5lcmF0b3JSZXNwb25zZShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGVycm9yXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0NvZGVHZW5lcmF0b3JSZXNwb25zZTo6fkNvZGVHZW5lcmF0b3JSZXNwb25zZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6U2hhcmVkRHRvcigpIHsKKyAgZXJyb3JfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gQ29kZUdlbmVyYXRvclJlc3BvbnNlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0NvZGVHZW5lcmF0b3JSZXNwb25zZSogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0NvZGVHZW5lcmF0b3JSZXNwb25zZSogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlKiBuID0gbmV3IENvZGVHZW5lcmF0b3JSZXNwb25zZTsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Q2xlYXIoKSB7CisgIGlmIChoYXNfZXJyb3IoKSkgeworICAgIGVycm9yXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAgZmlsZV8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfZXJyb3IoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+ZXJyb3IoKS5kYXRhKCksIHRoaXMtPmVycm9yKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjIpKSBnb3RvIHBhcnNlX2ZpbGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKKyAgICAgIGNhc2UgMTU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMjIpIHsKKyAgICAgICAgIHBhcnNlX2ZpbGU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2ZpbGUoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTIyKSkgZ290byBwYXJzZV9maWxlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorICAvLyBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworICBpZiAoaGFzX2Vycm9yKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmVycm9yKCkuZGF0YSgpLCB0aGlzLT5lcnJvcigpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5lcnJvcigpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSBmaWxlID0gMTU7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZmlsZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMTUsIHRoaXMtPmZpbGUoaSksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorICAvLyBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworICBpZiAoaGFzX2Vycm9yKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmVycm9yKCkuZGF0YSgpLCB0aGlzLT5lcnJvcigpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+ZXJyb3IoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUgZmlsZSA9IDE1OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpbGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMTUsIHRoaXMtPmZpbGUoaSksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBlcnJvciA9IDE7CisgIGlmIChoYXNfZXJyb3IoKSkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgdGhpcy0+ZXJyb3IoKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZmlsZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZmlsZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+ZmlsZShpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6Ok1lcmdlRnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgZmlsZV8uTWVyZ2VGcm9tKGZyb20uZmlsZV8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2Vycm9yKCkpIHsKKyAgICAgIHNldF9oYXNfZXJyb3IoKTsKKyAgICAgIGVycm9yXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uZXJyb3JfKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Q29weUZyb20oY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpTd2FwKENvZGVHZW5lcmF0b3JSZXNwb25zZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpJbnRlcm5hbFN3YXAoQ29kZUdlbmVyYXRvclJlc3BvbnNlKiBvdGhlcikgeworICBlcnJvcl8uU3dhcCgmb3RoZXItPmVycm9yXyk7CisgIGZpbGVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmZpbGVfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUKKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworIGJvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKKyBib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpoYXNfaW5zZXJ0aW9uX3BvaW50KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9pbnNlcnRpb25fcG9pbnQoKSB7CisgIGluc2VydGlvbl9wb2ludF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omluc2VydGlvbl9wb2ludCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorICByZXR1cm4gaW5zZXJ0aW9uX3BvaW50Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2luc2VydGlvbl9wb2ludChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICBpbnNlcnRpb25fcG9pbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIGluc2VydGlvbl9wb2ludF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQpCit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2luc2VydGlvbl9wb2ludChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjptdXRhYmxlX2luc2VydGlvbl9wb2ludCgpIHsKKyAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKKyAgcmV0dXJuIGluc2VydGlvbl9wb2ludF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6cmVsZWFzZV9pbnNlcnRpb25fcG9pbnQoKSB7CisgIGNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgcmV0dXJuIGluc2VydGlvbl9wb2ludF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfYWxsb2NhdGVkX2luc2VydGlvbl9wb2ludCg6OnN0ZDo6c3RyaW5nKiBpbnNlcnRpb25fcG9pbnQpIHsKKyAgaWYgKGluc2VydGlvbl9wb2ludCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIH0KKyAgaW5zZXJ0aW9uX3BvaW50Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgaW5zZXJ0aW9uX3BvaW50KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKKyBib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpoYXNfY29udGVudCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2hhc19jb250ZW50KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2hhc19jb250ZW50KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9jb250ZW50KCkgeworICBjb250ZW50Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19jb250ZW50KCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNvbnRlbnQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCisgIHJldHVybiBjb250ZW50Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2NvbnRlbnQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIGNvbnRlbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2NvbnRlbnQoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIGNvbnRlbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfY29udGVudChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIGNvbnRlbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjptdXRhYmxlX2NvbnRlbnQoKSB7CisgIHNldF9oYXNfY29udGVudCgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKKyAgcmV0dXJuIGNvbnRlbnRfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnJlbGVhc2VfY29udGVudCgpIHsKKyAgY2xlYXJfaGFzX2NvbnRlbnQoKTsKKyAgcmV0dXJuIGNvbnRlbnRfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2FsbG9jYXRlZF9jb250ZW50KDo6c3RkOjpzdHJpbmcqIGNvbnRlbnQpIHsKKyAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgeworICAgIHNldF9oYXNfY29udGVudCgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19jb250ZW50KCk7CisgIH0KKyAgY29udGVudF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGNvbnRlbnQpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBDb2RlR2VuZXJhdG9yUmVzcG9uc2UKKworLy8gb3B0aW9uYWwgc3RyaW5nIGVycm9yID0gMTsKKyBib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6aGFzX2Vycm9yKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2hhc19lcnJvcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Y2xlYXJfaGFzX2Vycm9yKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Y2xlYXJfZXJyb3IoKSB7CisgIGVycm9yXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19lcnJvcigpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZXJyb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKKyAgcmV0dXJuIGVycm9yXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9lcnJvcihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IpCit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9lcnJvcihjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2Vycm9yKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6bXV0YWJsZV9lcnJvcigpIHsKKyAgc2V0X2hhc19lcnJvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorICByZXR1cm4gZXJyb3JfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpyZWxlYXNlX2Vycm9yKCkgeworICBjbGVhcl9oYXNfZXJyb3IoKTsKKyAgcmV0dXJuIGVycm9yXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpzZXRfYWxsb2NhdGVkX2Vycm9yKDo6c3RkOjpzdHJpbmcqIGVycm9yKSB7CisgIGlmIChlcnJvciAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19lcnJvcigpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19lcnJvcigpOworICB9CisgIGVycm9yXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZXJyb3IpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKKyBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBmaWxlXy5zaXplKCk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmNsZWFyX2ZpbGUoKSB7CisgIGZpbGVfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZmlsZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXy5HZXQoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6Om11dGFibGVfZmlsZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5maWxlKQorICByZXR1cm4gZmlsZV8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6YWRkX2ZpbGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5maWxlKQorICByZXR1cm4gZmlsZV8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA+JgorQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlID4qCitDb2RlR2VuZXJhdG9yUmVzcG9uc2U6Om11dGFibGVfZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiAmZmlsZV87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYTQ4YjhiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuaApAQCAtMCwwICsxLDgwOCBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wcm90bworCisjaWZuZGVmIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90b19fSU5DTFVERUQKKyNkZWZpbmUgUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvX19JTkNMVURFRAorCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjaWYgR09PR0xFX1BST1RPQlVGX1ZFUlNJT04gPCAzMDAwMDAwCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UgdXBkYXRlCisjZXJyb3IgeW91ciBoZWFkZXJzLgorI2VuZGlmCisjaWYgMzAwMDAwMCA8IEdPT0dMRV9QUk9UT0JVRl9NSU5fUFJPVE9DX1ZFUlNJT04KKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UKKyNlcnJvciByZWdlbmVyYXRlIHRoaXMgZmlsZSB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2MuCisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgiCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIGRldGFpbCAtLSBkbyBub3QgY2FsbCB0aGVzZS4KK3ZvaWQgTElCUFJPVE9DX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisKK2NsYXNzIENvZGVHZW5lcmF0b3JSZXF1ZXN0OworY2xhc3MgQ29kZUdlbmVyYXRvclJlc3BvbnNlOworY2xhc3MgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBDb2RlR2VuZXJhdG9yUmVxdWVzdCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3QoKTsKKyAgdmlydHVhbCB+Q29kZUdlbmVyYXRvclJlcXVlc3QoKTsKKworICBDb2RlR2VuZXJhdG9yUmVxdWVzdChjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdCYgZnJvbSk7CisKKyAgaW5saW5lIENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBvcGVyYXRvcj0oY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoQ29kZUdlbmVyYXRvclJlcXVlc3QqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBDb2RlR2VuZXJhdG9yUmVxdWVzdCogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3QqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdCYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoQ29kZUdlbmVyYXRvclJlcXVlc3QqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKKyAgaW50IGZpbGVfdG9fZ2VuZXJhdGVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2ZpbGVfdG9fZ2VuZXJhdGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmlsZVRvR2VuZXJhdGVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9maWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCk7CisgIHZvaWQgc2V0X2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBhZGRfZmlsZV90b19nZW5lcmF0ZSgpOworICB2b2lkIGFkZF9maWxlX3RvX2dlbmVyYXRlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBhZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgYWRkX2ZpbGVfdG9fZ2VuZXJhdGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYgZmlsZV90b19nZW5lcmF0ZSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KiBtdXRhYmxlX2ZpbGVfdG9fZ2VuZXJhdGUoKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgcGFyYW1ldGVyID0gMjsKKyAgYm9vbCBoYXNfcGFyYW1ldGVyKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfcGFyYW1ldGVyKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1BhcmFtZXRlckZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgcGFyYW1ldGVyKCkgY29uc3Q7CisgIHZvaWQgc2V0X3BhcmFtZXRlcihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3BhcmFtZXRlcihjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3BhcmFtZXRlcihjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3BhcmFtZXRlcigpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3BhcmFtZXRlcigpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfcGFyYW1ldGVyKDo6c3RkOjpzdHJpbmcqIHBhcmFtZXRlcik7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX2ZpbGUgPSAxNTsKKyAgaW50IHByb3RvX2ZpbGVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3Byb3RvX2ZpbGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUHJvdG9GaWxlRmllbGROdW1iZXIgPSAxNTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90b19maWxlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogbXV0YWJsZV9wcm90b19maWxlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogYWRkX3Byb3RvX2ZpbGUoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIHByb3RvX2ZpbGUoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfcHJvdG9fZmlsZSgpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3BhcmFtZXRlcigpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiBmaWxlX3RvX2dlbmVyYXRlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgcGFyYW1ldGVyXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiBwcm90b19maWxlXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9DX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIENvZGVHZW5lcmF0b3JSZXF1ZXN0KiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKCk7CisgIHZpcnR1YWwgfkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKCk7CisKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUoY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIGZyb20pOworCisgIGlubGluZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgb3BlcmF0b3I9KGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGluc2VydGlvbl9wb2ludCA9IDI7CisgIGJvb2wgaGFzX2luc2VydGlvbl9wb2ludCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2luc2VydGlvbl9wb2ludCgpOworICBzdGF0aWMgY29uc3QgaW50IGtJbnNlcnRpb25Qb2ludEZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgaW5zZXJ0aW9uX3BvaW50KCkgY29uc3Q7CisgIHZvaWQgc2V0X2luc2VydGlvbl9wb2ludChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2luc2VydGlvbl9wb2ludChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2luc2VydGlvbl9wb2ludChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2luc2VydGlvbl9wb2ludCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2luc2VydGlvbl9wb2ludCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfaW5zZXJ0aW9uX3BvaW50KDo6c3RkOjpzdHJpbmcqIGluc2VydGlvbl9wb2ludCk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKKyAgYm9vbCBoYXNfY29udGVudCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2NvbnRlbnQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQ29udGVudEZpZWxkTnVtYmVyID0gMTU7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGNvbnRlbnQoKSBjb25zdDsKKyAgdm9pZCBzZXRfY29udGVudChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2NvbnRlbnQoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9jb250ZW50KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfY29udGVudCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2NvbnRlbnQoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2NvbnRlbnQoOjpzdGQ6OnN0cmluZyogY29udGVudCk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSkKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2luc2VydGlvbl9wb2ludCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2NvbnRlbnQoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBpbnNlcnRpb25fcG9pbnRfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBjb250ZW50XzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9DX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgQ29kZUdlbmVyYXRvclJlc3BvbnNlIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBDb2RlR2VuZXJhdG9yUmVzcG9uc2UoKTsKKyAgdmlydHVhbCB+Q29kZUdlbmVyYXRvclJlc3BvbnNlKCk7CisKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSYgZnJvbSk7CisKKyAgaW5saW5lIENvZGVHZW5lcmF0b3JSZXNwb25zZSYgb3BlcmF0b3I9KGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoQ29kZUdlbmVyYXRvclJlc3BvbnNlKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgQ29kZUdlbmVyYXRvclJlc3BvbnNlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICB0eXBlZGVmIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlIEZpbGU7CisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworICBib29sIGhhc19lcnJvcigpIGNvbnN0OworICB2b2lkIGNsZWFyX2Vycm9yKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0Vycm9yRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBlcnJvcigpIGNvbnN0OworICB2b2lkIHNldF9lcnJvcihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2Vycm9yKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfZXJyb3IoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9lcnJvcigpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2Vycm9yKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9lcnJvcig6OnN0ZDo6c3RyaW5nKiBlcnJvcik7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSBmaWxlID0gMTU7CisgIGludCBmaWxlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9maWxlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpbGVGaWVsZE51bWJlciA9IDE1OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgZmlsZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSogbXV0YWJsZV9maWxlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBhZGRfZmlsZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlID4mCisgICAgICBmaWxlKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUgPioKKyAgICAgIG11dGFibGVfZmlsZSgpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfZXJyb3IoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2Vycm9yKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBlcnJvcl87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUgPiBmaWxlXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9DX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIENvZGVHZW5lcmF0b3JSZXNwb25zZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIENvZGVHZW5lcmF0b3JSZXF1ZXN0CisKKy8vIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKK2lubGluZSBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmZpbGVfdG9fZ2VuZXJhdGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpbGVfdG9fZ2VuZXJhdGVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpjbGVhcl9maWxlX3RvX2dlbmVyYXRlKCkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpmaWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9maWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKKyAgcmV0dXJuIGZpbGVfdG9fZ2VuZXJhdGVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9maWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKKyAgZmlsZV90b19nZW5lcmF0ZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9maWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfZmlsZV90b19nZW5lcmF0ZSgpIHsKKyAgcmV0dXJuIGZpbGVfdG9fZ2VuZXJhdGVfLkFkZCgpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9maWxlX3RvX2dlbmVyYXRlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9maWxlX3RvX2dlbmVyYXRlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLkFkZCgpLT5hc3NpZ24ocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZmlsZV90b19nZW5lcmF0ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KgorQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfZmlsZV90b19nZW5lcmF0ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKKyAgcmV0dXJuICZmaWxlX3RvX2dlbmVyYXRlXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHBhcmFtZXRlciA9IDI7CitpbmxpbmUgYm9vbCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6aGFzX3BhcmFtZXRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X2hhc19wYXJhbWV0ZXIoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Y2xlYXJfaGFzX3BhcmFtZXRlcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Y2xlYXJfcGFyYW1ldGVyKCkgeworICBwYXJhbWV0ZXJfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3BhcmFtZXRlcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpwYXJhbWV0ZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKKyAgcmV0dXJuIHBhcmFtZXRlcl8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9wYXJhbWV0ZXIoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgcGFyYW1ldGVyXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X3BhcmFtZXRlcihjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3BhcmFtZXRlcigpOworICBwYXJhbWV0ZXJfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9wYXJhbWV0ZXIoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIHBhcmFtZXRlcl8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9wYXJhbWV0ZXIoKSB7CisgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCisgIHJldHVybiBwYXJhbWV0ZXJfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnJlbGVhc2VfcGFyYW1ldGVyKCkgeworICBjbGVhcl9oYXNfcGFyYW1ldGVyKCk7CisgIHJldHVybiBwYXJhbWV0ZXJfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X2FsbG9jYXRlZF9wYXJhbWV0ZXIoOjpzdGQ6OnN0cmluZyogcGFyYW1ldGVyKSB7CisgIGlmIChwYXJhbWV0ZXIgIT0gTlVMTCkgeworICAgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3BhcmFtZXRlcigpOworICB9CisgIHBhcmFtZXRlcl8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHBhcmFtZXRlcik7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBwcm90b19maWxlID0gMTU7CitpbmxpbmUgaW50IENvZGVHZW5lcmF0b3JSZXF1ZXN0Ojpwcm90b19maWxlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBwcm90b19maWxlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Y2xlYXJfcHJvdG9fZmlsZSgpIHsKKyAgcHJvdG9fZmlsZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8mIENvZGVHZW5lcmF0b3JSZXF1ZXN0Ojpwcm90b19maWxlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gcHJvdG9fZmlsZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8qIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjptdXRhYmxlX3Byb3RvX2ZpbGUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gcHJvdG9fZmlsZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6YWRkX3Byb3RvX2ZpbGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiBwcm90b19maWxlXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+JgorQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnByb3RvX2ZpbGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gcHJvdG9fZmlsZV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPioKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0OjptdXRhYmxlX3Byb3RvX2ZpbGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiAmcHJvdG9fZmlsZV87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUKKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKK2lubGluZSBib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpoYXNfaW5zZXJ0aW9uX3BvaW50KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9pbnNlcnRpb25fcG9pbnQoKSB7CisgIGluc2VydGlvbl9wb2ludF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omluc2VydGlvbl9wb2ludCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorICByZXR1cm4gaW5zZXJ0aW9uX3BvaW50Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2luc2VydGlvbl9wb2ludChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICBpbnNlcnRpb25fcG9pbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIGluc2VydGlvbl9wb2ludF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2luc2VydGlvbl9wb2ludChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjptdXRhYmxlX2luc2VydGlvbl9wb2ludCgpIHsKKyAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKKyAgcmV0dXJuIGluc2VydGlvbl9wb2ludF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6cmVsZWFzZV9pbnNlcnRpb25fcG9pbnQoKSB7CisgIGNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgcmV0dXJuIGluc2VydGlvbl9wb2ludF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfYWxsb2NhdGVkX2luc2VydGlvbl9wb2ludCg6OnN0ZDo6c3RyaW5nKiBpbnNlcnRpb25fcG9pbnQpIHsKKyAgaWYgKGluc2VydGlvbl9wb2ludCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIH0KKyAgaW5zZXJ0aW9uX3BvaW50Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgaW5zZXJ0aW9uX3BvaW50KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKK2lubGluZSBib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpoYXNfY29udGVudCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2hhc19jb250ZW50KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2hhc19jb250ZW50KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9jb250ZW50KCkgeworICBjb250ZW50Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19jb250ZW50KCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNvbnRlbnQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCisgIHJldHVybiBjb250ZW50Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2NvbnRlbnQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIGNvbnRlbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2NvbnRlbnQoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIGNvbnRlbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfY29udGVudChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIGNvbnRlbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjptdXRhYmxlX2NvbnRlbnQoKSB7CisgIHNldF9oYXNfY29udGVudCgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKKyAgcmV0dXJuIGNvbnRlbnRfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnJlbGVhc2VfY29udGVudCgpIHsKKyAgY2xlYXJfaGFzX2NvbnRlbnQoKTsKKyAgcmV0dXJuIGNvbnRlbnRfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2FsbG9jYXRlZF9jb250ZW50KDo6c3RkOjpzdHJpbmcqIGNvbnRlbnQpIHsKKyAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgeworICAgIHNldF9oYXNfY29udGVudCgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19jb250ZW50KCk7CisgIH0KKyAgY29udGVudF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGNvbnRlbnQpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBDb2RlR2VuZXJhdG9yUmVzcG9uc2UKKworLy8gb3B0aW9uYWwgc3RyaW5nIGVycm9yID0gMTsKK2lubGluZSBib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6aGFzX2Vycm9yKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2hhc19lcnJvcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Y2xlYXJfaGFzX2Vycm9yKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Y2xlYXJfZXJyb3IoKSB7CisgIGVycm9yXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19lcnJvcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZXJyb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKKyAgcmV0dXJuIGVycm9yXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9lcnJvcihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9lcnJvcihjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2Vycm9yKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6bXV0YWJsZV9lcnJvcigpIHsKKyAgc2V0X2hhc19lcnJvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorICByZXR1cm4gZXJyb3JfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpyZWxlYXNlX2Vycm9yKCkgeworICBjbGVhcl9oYXNfZXJyb3IoKTsKKyAgcmV0dXJuIGVycm9yXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpzZXRfYWxsb2NhdGVkX2Vycm9yKDo6c3RkOjpzdHJpbmcqIGVycm9yKSB7CisgIGlmIChlcnJvciAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19lcnJvcigpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19lcnJvcigpOworICB9CisgIGVycm9yXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZXJyb3IpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKK2lubGluZSBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBmaWxlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmNsZWFyX2ZpbGUoKSB7CisgIGZpbGVfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZmlsZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6Om11dGFibGVfZmlsZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5maWxlKQorICByZXR1cm4gZmlsZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6YWRkX2ZpbGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5maWxlKQorICByZXR1cm4gZmlsZV8uQWRkKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA+JgorQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlID4qCitDb2RlR2VuZXJhdG9yUmVzcG9uc2U6Om11dGFibGVfZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiAmZmlsZV87Cit9CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQorCisjZW5kaWYgIC8vIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90b19fSU5DTFVERUQKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNhZWUxZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCkBAIC0wLDAgKzEsMTUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFdBUk5JTkc6ICBUaGUgcGx1Z2luIGludGVyZmFjZSBpcyBjdXJyZW50bHkgRVhQRVJJTUVOVEFMIGFuZCBpcyBzdWJqZWN0IHRvCisvLyAgIGNoYW5nZS4KKy8vCisvLyBwcm90b2MgKGFrYSB0aGUgUHJvdG9jb2wgQ29tcGlsZXIpIGNhbiBiZSBleHRlbmRlZCB2aWEgcGx1Z2lucy4gIEEgcGx1Z2luIGlzCisvLyBqdXN0IGEgcHJvZ3JhbSB0aGF0IHJlYWRzIGEgQ29kZUdlbmVyYXRvclJlcXVlc3QgZnJvbSBzdGRpbiBhbmQgd3JpdGVzIGEKKy8vIENvZGVHZW5lcmF0b3JSZXNwb25zZSB0byBzdGRvdXQuCisvLworLy8gUGx1Z2lucyB3cml0dGVuIHVzaW5nIEMrKyBjYW4gdXNlIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaCBpbnN0ZWFkCisvLyBvZiBkZWFsaW5nIHdpdGggdGhlIHJhdyBwcm90b2NvbCBkZWZpbmVkIGhlcmUuCisvLworLy8gQSBwbHVnaW4gZXhlY3V0YWJsZSBuZWVkcyBvbmx5IHRvIGJlIHBsYWNlZCBzb21ld2hlcmUgaW4gdGhlIHBhdGguICBUaGUKKy8vIHBsdWdpbiBzaG91bGQgYmUgbmFtZWQgInByb3RvYy1nZW4tJE5BTUUiLCBhbmQgd2lsbCB0aGVuIGJlIHVzZWQgd2hlbiB0aGUKKy8vIGZsYWcgIi0tJHtOQU1FfV9vdXQiIGlzIHBhc3NlZCB0byBwcm90b2MuCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBnb29nbGUucHJvdG9idWYuY29tcGlsZXI7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYuY29tcGlsZXIiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlBsdWdpblByb3RvcyI7CisKK29wdGlvbiBnb19wYWNrYWdlID0gInBsdWdpbl9nbyI7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iOworCisvLyBBbiBlbmNvZGVkIENvZGVHZW5lcmF0b3JSZXF1ZXN0IGlzIHdyaXR0ZW4gdG8gdGhlIHBsdWdpbidzIHN0ZGluLgorbWVzc2FnZSBDb2RlR2VuZXJhdG9yUmVxdWVzdCB7CisgIC8vIFRoZSAucHJvdG8gZmlsZXMgdGhhdCB3ZXJlIGV4cGxpY2l0bHkgbGlzdGVkIG9uIHRoZSBjb21tYW5kLWxpbmUuICBUaGUKKyAgLy8gY29kZSBnZW5lcmF0b3Igc2hvdWxkIGdlbmVyYXRlIGNvZGUgb25seSBmb3IgdGhlc2UgZmlsZXMuICBFYWNoIGZpbGUncworICAvLyBkZXNjcmlwdG9yIHdpbGwgYmUgaW5jbHVkZWQgaW4gcHJvdG9fZmlsZSwgYmVsb3cuCisgIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKKworICAvLyBUaGUgZ2VuZXJhdG9yIHBhcmFtZXRlciBwYXNzZWQgb24gdGhlIGNvbW1hbmQtbGluZS4KKyAgb3B0aW9uYWwgc3RyaW5nIHBhcmFtZXRlciA9IDI7CisKKyAgLy8gRmlsZURlc2NyaXB0b3JQcm90b3MgZm9yIGFsbCBmaWxlcyBpbiBmaWxlc190b19nZW5lcmF0ZSBhbmQgZXZlcnl0aGluZworICAvLyB0aGV5IGltcG9ydC4gIFRoZSBmaWxlcyB3aWxsIGFwcGVhciBpbiB0b3BvbG9naWNhbCBvcmRlciwgc28gZWFjaCBmaWxlCisgIC8vIGFwcGVhcnMgYmVmb3JlIGFueSBmaWxlIHRoYXQgaW1wb3J0cyBpdC4KKyAgLy8KKyAgLy8gcHJvdG9jIGd1YXJhbnRlZXMgdGhhdCBhbGwgcHJvdG9fZmlsZXMgd2lsbCBiZSB3cml0dGVuIGFmdGVyCisgIC8vIHRoZSBmaWVsZHMgYWJvdmUsIGV2ZW4gdGhvdWdoIHRoaXMgaXMgbm90IHRlY2huaWNhbGx5IGd1YXJhbnRlZWQgYnkgdGhlCisgIC8vIHByb3RvYnVmIHdpcmUgZm9ybWF0LiAgVGhpcyB0aGVvcmV0aWNhbGx5IGNvdWxkIGFsbG93IGEgcGx1Z2luIHRvIHN0cmVhbQorICAvLyBpbiB0aGUgRmlsZURlc2NyaXB0b3JQcm90b3MgYW5kIGhhbmRsZSB0aGVtIG9uZSBieSBvbmUgcmF0aGVyIHRoYW4gcmVhZAorICAvLyB0aGUgZW50aXJlIHNldCBpbnRvIG1lbW9yeSBhdCBvbmNlLiAgSG93ZXZlciwgYXMgb2YgdGhpcyB3cml0aW5nLCB0aGlzCisgIC8vIGlzIG5vdCBzaW1pbGFybHkgb3B0aW1pemVkIG9uIHByb3RvYydzIGVuZCAtLSBpdCB3aWxsIHN0b3JlIGFsbCBmaWVsZHMgaW4KKyAgLy8gbWVtb3J5IGF0IG9uY2UgYmVmb3JlIHNlbmRpbmcgdGhlbSB0byB0aGUgcGx1Z2luLgorICByZXBlYXRlZCBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX2ZpbGUgPSAxNTsKK30KKworLy8gVGhlIHBsdWdpbiB3cml0ZXMgYW4gZW5jb2RlZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgdG8gc3Rkb3V0LgorbWVzc2FnZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgeworICAvLyBFcnJvciBtZXNzYWdlLiAgSWYgbm9uLWVtcHR5LCBjb2RlIGdlbmVyYXRpb24gZmFpbGVkLiAgVGhlIHBsdWdpbiBwcm9jZXNzCisgIC8vIHNob3VsZCBleGl0IHdpdGggc3RhdHVzIGNvZGUgemVybyBldmVuIGlmIGl0IHJlcG9ydHMgYW4gZXJyb3IgaW4gdGhpcyB3YXkuCisgIC8vCisgIC8vIFRoaXMgc2hvdWxkIGJlIHVzZWQgdG8gaW5kaWNhdGUgZXJyb3JzIGluIC5wcm90byBmaWxlcyB3aGljaCBwcmV2ZW50IHRoZQorICAvLyBjb2RlIGdlbmVyYXRvciBmcm9tIGdlbmVyYXRpbmcgY29ycmVjdCBjb2RlLiAgRXJyb3JzIHdoaWNoIGluZGljYXRlIGEKKyAgLy8gcHJvYmxlbSBpbiBwcm90b2MgaXRzZWxmIC0tIHN1Y2ggYXMgdGhlIGlucHV0IENvZGVHZW5lcmF0b3JSZXF1ZXN0IGJlaW5nCisgIC8vIHVucGFyc2VhYmxlIC0tIHNob3VsZCBiZSByZXBvcnRlZCBieSB3cml0aW5nIGEgbWVzc2FnZSB0byBzdGRlcnIgYW5kCisgIC8vIGV4aXRpbmcgd2l0aCBhIG5vbi16ZXJvIHN0YXR1cyBjb2RlLgorICBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworCisgIC8vIFJlcHJlc2VudHMgYSBzaW5nbGUgZ2VuZXJhdGVkIGZpbGUuCisgIG1lc3NhZ2UgRmlsZSB7CisgICAgLy8gVGhlIGZpbGUgbmFtZSwgcmVsYXRpdmUgdG8gdGhlIG91dHB1dCBkaXJlY3RvcnkuICBUaGUgbmFtZSBtdXN0IG5vdAorICAgIC8vIGNvbnRhaW4gIi4iIG9yICIuLiIgY29tcG9uZW50cyBhbmQgbXVzdCBiZSByZWxhdGl2ZSwgbm90IGJlIGFic29sdXRlIChzbywKKyAgICAvLyB0aGUgZmlsZSBjYW5ub3QgbGllIG91dHNpZGUgdGhlIG91dHB1dCBkaXJlY3RvcnkpLiAgIi8iIG11c3QgYmUgdXNlZCBhcworICAgIC8vIHRoZSBwYXRoIHNlcGFyYXRvciwgbm90ICJcIi4KKyAgICAvLworICAgIC8vIElmIHRoZSBuYW1lIGlzIG9taXR0ZWQsIHRoZSBjb250ZW50IHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIHByZXZpb3VzCisgICAgLy8gZmlsZS4gIFRoaXMgYWxsb3dzIHRoZSBnZW5lcmF0b3IgdG8gYnJlYWsgbGFyZ2UgZmlsZXMgaW50byBzbWFsbCBjaHVua3MsCisgICAgLy8gYW5kIGFsbG93cyB0aGUgZ2VuZXJhdGVkIHRleHQgdG8gYmUgc3RyZWFtZWQgYmFjayB0byBwcm90b2Mgc28gdGhhdCBsYXJnZQorICAgIC8vIGZpbGVzIG5lZWQgbm90IHJlc2lkZSBjb21wbGV0ZWx5IGluIG1lbW9yeSBhdCBvbmUgdGltZS4gIE5vdGUgdGhhdCBhcyBvZgorICAgIC8vIHRoaXMgd3JpdGluZyBwcm90b2MgZG9lcyBub3Qgb3B0aW1pemUgZm9yIHRoaXMgLS0gaXQgd2lsbCByZWFkIHRoZSBlbnRpcmUKKyAgICAvLyBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgYmVmb3JlIHdyaXRpbmcgZmlsZXMgdG8gZGlzay4KKyAgICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisKKyAgICAvLyBJZiBub24tZW1wdHksIGluZGljYXRlcyB0aGF0IHRoZSBuYW1lZCBmaWxlIHNob3VsZCBhbHJlYWR5IGV4aXN0LCBhbmQgdGhlCisgICAgLy8gY29udGVudCBoZXJlIGlzIHRvIGJlIGluc2VydGVkIGludG8gdGhhdCBmaWxlIGF0IGEgZGVmaW5lZCBpbnNlcnRpb24KKyAgICAvLyBwb2ludC4gIFRoaXMgZmVhdHVyZSBhbGxvd3MgYSBjb2RlIGdlbmVyYXRvciB0byBleHRlbmQgdGhlIG91dHB1dAorICAgIC8vIHByb2R1Y2VkIGJ5IGFub3RoZXIgY29kZSBnZW5lcmF0b3IuICBUaGUgb3JpZ2luYWwgZ2VuZXJhdG9yIG1heSBwcm92aWRlCisgICAgLy8gaW5zZXJ0aW9uIHBvaW50cyBieSBwbGFjaW5nIHNwZWNpYWwgYW5ub3RhdGlvbnMgaW4gdGhlIGZpbGUgdGhhdCBsb29rCisgICAgLy8gbGlrZToKKyAgICAvLyAgIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChOQU1FKQorICAgIC8vIFRoZSBhbm5vdGF0aW9uIGNhbiBoYXZlIGFyYml0cmFyeSB0ZXh0IGJlZm9yZSBhbmQgYWZ0ZXIgaXQgb24gdGhlIGxpbmUsCisgICAgLy8gd2hpY2ggYWxsb3dzIGl0IHRvIGJlIHBsYWNlZCBpbiBhIGNvbW1lbnQuICBOQU1FIHNob3VsZCBiZSByZXBsYWNlZCB3aXRoCisgICAgLy8gYW4gaWRlbnRpZmllciBuYW1pbmcgdGhlIHBvaW50IC0tIHRoaXMgaXMgd2hhdCBvdGhlciBnZW5lcmF0b3JzIHdpbGwgdXNlCisgICAgLy8gYXMgdGhlIGluc2VydGlvbl9wb2ludC4gIENvZGUgaW5zZXJ0ZWQgYXQgdGhpcyBwb2ludCB3aWxsIGJlIHBsYWNlZAorICAgIC8vIGltbWVkaWF0ZWx5IGFib3ZlIHRoZSBsaW5lIGNvbnRhaW5pbmcgdGhlIGluc2VydGlvbiBwb2ludCAodGh1cyBtdWx0aXBsZQorICAgIC8vIGluc2VydGlvbnMgdG8gdGhlIHNhbWUgcG9pbnQgd2lsbCBjb21lIG91dCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGFkZGVkKS4KKyAgICAvLyBUaGUgZG91YmxlLUAgaXMgaW50ZW5kZWQgdG8gbWFrZSBpdCB1bmxpa2VseSB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZQorICAgIC8vIGNvdWxkIGNvbnRhaW4gdGhpbmdzIHRoYXQgbG9vayBsaWtlIGluc2VydGlvbiBwb2ludHMgYnkgYWNjaWRlbnQuCisgICAgLy8KKyAgICAvLyBGb3IgZXhhbXBsZSwgdGhlIEMrKyBjb2RlIGdlbmVyYXRvciBwbGFjZXMgdGhlIGZvbGxvd2luZyBsaW5lIGluIHRoZQorICAgIC8vIC5wYi5oIGZpbGVzIHRoYXQgaXQgZ2VuZXJhdGVzOgorICAgIC8vICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKyAgICAvLyBUaGlzIGxpbmUgYXBwZWFycyB3aXRoaW4gdGhlIHNjb3BlIG9mIHRoZSBmaWxlJ3MgcGFja2FnZSBuYW1lc3BhY2UsIGJ1dAorICAgIC8vIG91dHNpZGUgb2YgYW55IHBhcnRpY3VsYXIgY2xhc3MuICBBbm90aGVyIHBsdWdpbiBjYW4gdGhlbiBzcGVjaWZ5IHRoZQorICAgIC8vIGluc2VydGlvbl9wb2ludCAibmFtZXNwYWNlX3Njb3BlIiB0byBnZW5lcmF0ZSBhZGRpdGlvbmFsIGNsYXNzZXMgb3IKKyAgICAvLyBvdGhlciBkZWNsYXJhdGlvbnMgdGhhdCBzaG91bGQgYmUgcGxhY2VkIGluIHRoaXMgc2NvcGUuCisgICAgLy8KKyAgICAvLyBOb3RlIHRoYXQgaWYgdGhlIGxpbmUgY29udGFpbmluZyB0aGUgaW5zZXJ0aW9uIHBvaW50IGJlZ2lucyB3aXRoCisgICAgLy8gd2hpdGVzcGFjZSwgdGhlIHNhbWUgd2hpdGVzcGFjZSB3aWxsIGJlIGFkZGVkIHRvIGV2ZXJ5IGxpbmUgb2YgdGhlCisgICAgLy8gaW5zZXJ0ZWQgdGV4dC4gIFRoaXMgaXMgdXNlZnVsIGZvciBsYW5ndWFnZXMgbGlrZSBQeXRob24sIHdoZXJlCisgICAgLy8gaW5kZW50YXRpb24gbWF0dGVycy4gIEluIHRoZXNlIGxhbmd1YWdlcywgdGhlIGluc2VydGlvbiBwb2ludCBjb21tZW50CisgICAgLy8gc2hvdWxkIGJlIGluZGVudGVkIHRoZSBzYW1lIGFtb3VudCBhcyBhbnkgaW5zZXJ0ZWQgY29kZSB3aWxsIG5lZWQgdG8gYmUKKyAgICAvLyBpbiBvcmRlciB0byB3b3JrIGNvcnJlY3RseSBpbiB0aGF0IGNvbnRleHQuCisgICAgLy8KKyAgICAvLyBUaGUgY29kZSBnZW5lcmF0b3IgdGhhdCBnZW5lcmF0ZXMgdGhlIGluaXRpYWwgZmlsZSBhbmQgdGhlIG9uZSB3aGljaAorICAgIC8vIGluc2VydHMgaW50byBpdCBtdXN0IGJvdGggcnVuIGFzIHBhcnQgb2YgYSBzaW5nbGUgaW52b2NhdGlvbiBvZiBwcm90b2MuCisgICAgLy8gQ29kZSBnZW5lcmF0b3JzIGFyZSBleGVjdXRlZCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcHBlYXIgb24gdGhlCisgICAgLy8gY29tbWFuZCBsaW5lLgorICAgIC8vCisgICAgLy8gSWYgfGluc2VydGlvbl9wb2ludHwgaXMgcHJlc2VudCwgfG5hbWV8IG11c3QgYWxzbyBiZSBwcmVzZW50LgorICAgIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworCisgICAgLy8gVGhlIGZpbGUgY29udGVudHMuCisgICAgb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKKyAgfQorICByZXBlYXRlZCBGaWxlIGZpbGUgPSAxNTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiM2I1ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsMTMzMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vI1BZMjUgY29tcGF0aWJsZSBnZW5lcmF0ZWQgY29kZSBmb3IgR0FFLgorLy8gQ29weXJpZ2h0IDIwMDcgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKy8vIEF1dGhvcjogcm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbikKKy8vCisvLyBUaGlzIG1vZHVsZSBvdXRwdXRzIHB1cmUtUHl0aG9uIHByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcyB0aGF0IHdpbGwKKy8vIGxhcmdlbHkgYmUgY29uc3RydWN0ZWQgYXQgcnVudGltZSB2aWEgdGhlIG1ldGFjbGFzcyBpbiByZWZsZWN0aW9uLnB5LgorLy8gSW4gb3RoZXIgd29yZHMsIG91ciBqb2IgaXMgYmFzaWNhbGx5IHRvIG91dHB1dCBhIFB5dGhvbiBlcXVpdmFsZW50CisvLyBvZiB0aGUgQysrICpEZXNjcmlwdG9yIG9iamVjdHMsIGFuZCBmaXggdXAgYWxsIGNpcmN1bGFyIHJlZmVyZW5jZXMKKy8vIHdpdGhpbiB0aGVzZSBvYmplY3RzLgorLy8KKy8vIE5vdGUgdGhhdCB0aGUgcnVudGltZSBwZXJmb3JtYW5jZSBvZiBwcm90b2NvbCBtZXNzYWdlIGNsYXNzZXMgY3JlYXRlZCBpbgorLy8gdGhpcyB3YXkgaXMgZXhwZWN0ZWQgdG8gYmUgbG91c3kuICBUaGUgcGxhbiBpcyB0byBjcmVhdGUgYW4gYWx0ZXJuYXRlCisvLyBnZW5lcmF0b3IgdGhhdCBvdXRwdXRzIGEgUHl0aG9uL0MgZXh0ZW5zaW9uIG1vZHVsZSB0aGF0IGxldHMKKy8vIHBlcmZvcm1hbmNlLW1pbmRlZCBQeXRob24gY29kZSBsZXZlcmFnZSB0aGUgZmFzdCBDKysgaW1wbGVtZW50YXRpb24KKy8vIGRpcmVjdGx5LgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworbmFtZXNwYWNlIHsKKworLy8gUmV0dXJucyBhIGNvcHkgb2YgfGZpbGVuYW1lfCB3aXRoIGFueSB0cmFpbGluZyAiLnByb3RvZGV2ZWwiIG9yICIucHJvdG8KKy8vIHN1ZmZpeCBzdHJpcHBlZC4KKy8vIFRPRE8ocm9iaW5zb24pOiBVbmlmeSB3aXRoIGNvcHkgaW4gY29tcGlsZXIvY3BwL2ludGVybmFsL2hlbHBlcnMuY2MuCitzdHJpbmcgU3RyaXBQcm90byhjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIGNvbnN0IGNoYXIqIHN1ZmZpeCA9IEhhc1N1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90b2RldmVsIikKKyAgICAgID8gIi5wcm90b2RldmVsIiA6ICIucHJvdG8iOworICByZXR1cm4gU3RyaXBTdWZmaXhTdHJpbmcoZmlsZW5hbWUsIHN1ZmZpeCk7Cit9CisKKworLy8gUmV0dXJucyB0aGUgUHl0aG9uIG1vZHVsZSBuYW1lIGV4cGVjdGVkIGZvciBhIGdpdmVuIC5wcm90byBmaWxlbmFtZS4KK3N0cmluZyBNb2R1bGVOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgc3RyaW5nIGJhc2VuYW1lID0gU3RyaXBQcm90byhmaWxlbmFtZSk7CisgIFN0cmlwU3RyaW5nKCZiYXNlbmFtZSwgIi0iLCAnXycpOworICBTdHJpcFN0cmluZygmYmFzZW5hbWUsICIvIiwgJy4nKTsKKyAgcmV0dXJuIGJhc2VuYW1lICsgIl9wYjIiOworfQorCisKKy8vIFJldHVybnMgdGhlIGFsaWFzIHdlIGFzc2lnbiB0byB0aGUgbW9kdWxlIG9mIHRoZSBnaXZlbiAucHJvdG8gZmlsZW5hbWUKKy8vIHdoZW4gaW1wb3J0aW5nLiBTZWUgdGVzdFBhY2thZ2VJbml0aWFsaXphdGlvbkltcG9ydCBpbgorLy8gZ29vZ2xlL3Byb3RvYnVmL3B5dGhvbi9yZWZsZWN0aW9uX3Rlc3QucHkKKy8vIHRvIHNlZSB3aHkgd2UgbmVlZCB0aGUgYWxpYXMuCitzdHJpbmcgTW9kdWxlQWxpYXMoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBzdHJpbmcgbW9kdWxlX25hbWUgPSBNb2R1bGVOYW1lKGZpbGVuYW1lKTsKKyAgLy8gV2UgY2FuJ3QgaGF2ZSBkb3RzIGluIHRoZSBtb2R1bGUgbmFtZSwgc28gd2UgcmVwbGFjZSBlYWNoIHdpdGggX2RvdF8uCisgIC8vIEJ1dCB0aGF0IGNvdWxkIGxlYWQgdG8gYSBjb2xsaXNpb24gYmV0d2VlbiBhLmIgYW5kIGFfZG90X2IsIHNvIHdlIGFsc28KKyAgLy8gZHVwbGljYXRlIGVhY2ggdW5kZXJzY29yZS4KKyAgR2xvYmFsUmVwbGFjZVN1YnN0cmluZygiXyIsICJfXyIsICZtb2R1bGVfbmFtZSk7CisgIEdsb2JhbFJlcGxhY2VTdWJzdHJpbmcoIi4iLCAiX2RvdF8iLCAmbW9kdWxlX25hbWUpOworICByZXR1cm4gbW9kdWxlX25hbWU7Cit9CisKKworLy8gUmV0dXJucyBhbiBpbXBvcnQgc3RhdGVtZW50IG9mIGZvcm0gImZyb20gWC5ZLlogaW1wb3J0IFQiIGZvciB0aGUgZ2l2ZW4KKy8vIC5wcm90byBmaWxlbmFtZS4KK3N0cmluZyBNb2R1bGVJbXBvcnRTdGF0ZW1lbnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBzdHJpbmcgbW9kdWxlX25hbWUgPSBNb2R1bGVOYW1lKGZpbGVuYW1lKTsKKyAgaW50IGxhc3RfZG90X3BvcyA9IG1vZHVsZV9uYW1lLnJmaW5kKCcuJyk7CisgIGlmIChsYXN0X2RvdF9wb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgLy8gTk9URShwZXR5YSk6IHRoaXMgaXMgbm90IHRlc3RlZCBhcyBpdCB3b3VsZCByZXF1aXJlIGEgcHJvdG9jb2wgYnVmZmVyCisgICAgLy8gb3V0c2lkZSBvZiBhbnkgcGFja2FnZSwgYW5kIEkgZG9uJ3QgdGhpbmsgdGhhdCBpcyBlYXNpbHkgYWNoaWV2YWJsZS4KKyAgICByZXR1cm4gImltcG9ydCAiICsgbW9kdWxlX25hbWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuICJmcm9tICIgKyBtb2R1bGVfbmFtZS5zdWJzdHIoMCwgbGFzdF9kb3RfcG9zKSArICIgaW1wb3J0ICIgKworICAgICAgICBtb2R1bGVfbmFtZS5zdWJzdHIobGFzdF9kb3RfcG9zICsgMSk7CisgIH0KK30KKworCisvLyBSZXR1cm5zIHRoZSBuYW1lIG9mIGFsbCBjb250YWluaW5nIHR5cGVzIGZvciBkZXNjcmlwdG9yLAorLy8gaW4gb3JkZXIgZnJvbSBvdXRlcm1vc3QgdG8gaW5uZXJtb3N0LCBmb2xsb3dlZCBieSBkZXNjcmlwdG9yJ3MKKy8vIG93biBuYW1lLiAgRWFjaCBuYW1lIGlzIHNlcGFyYXRlZCBieSB8c2VwYXJhdG9yfC4KK3RlbXBsYXRlIDx0eXBlbmFtZSBEZXNjcmlwdG9yVD4KK3N0cmluZyBOYW1lUHJlZml4ZWRXaXRoTmVzdGVkVHlwZXMoY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgc2VwYXJhdG9yKSB7CisgIHN0cmluZyBuYW1lID0gZGVzY3JpcHRvci5uYW1lKCk7CisgIGZvciAoY29uc3QgRGVzY3JpcHRvciogY3VycmVudCA9IGRlc2NyaXB0b3IuY29udGFpbmluZ190eXBlKCk7CisgICAgICAgY3VycmVudCAhPSBOVUxMOyBjdXJyZW50ID0gY3VycmVudC0+Y29udGFpbmluZ190eXBlKCkpIHsKKyAgICBuYW1lID0gY3VycmVudC0+bmFtZSgpICsgc2VwYXJhdG9yICsgbmFtZTsKKyAgfQorICByZXR1cm4gbmFtZTsKK30KKworCisvLyBOYW1lIG9mIHRoZSBjbGFzcyBhdHRyaWJ1dGUgd2hlcmUgd2Ugc3RvcmUgdGhlIFB5dGhvbgorLy8gZGVzY3JpcHRvci5EZXNjcmlwdG9yIGluc3RhbmNlIGZvciB0aGUgZ2VuZXJhdGVkIGNsYXNzLgorLy8gTXVzdCBzdGF5IGNvbnNpc3RlbnQgd2l0aCB0aGUgX0RFU0NSSVBUT1JfS0VZIGNvbnN0YW50CisvLyBpbiBwcm90bzIvcHVibGljL3JlZmxlY3Rpb24ucHkuCitjb25zdCBjaGFyIGtEZXNjcmlwdG9yS2V5W10gPSAiREVTQ1JJUFRPUiI7CisKKworLy8gRG9lcyB0aGUgZmlsZSBoYXZlIHRvcC1sZXZlbCBlbnVtcz8KK2lubGluZSBib29sIEhhc1RvcExldmVsRW51bXMoY29uc3QgRmlsZURlc2NyaXB0b3IgKmZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPmVudW1fdHlwZV9jb3VudCgpID4gMDsKK30KKworCisvLyBTaG91bGQgd2UgZ2VuZXJhdGUgZ2VuZXJpYyBzZXJ2aWNlcyBmb3IgdGhpcyBmaWxlPworaW5saW5lIGJvb2wgSGFzR2VuZXJpY1NlcnZpY2VzKGNvbnN0IEZpbGVEZXNjcmlwdG9yICpmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zZXJ2aWNlX2NvdW50KCkgPiAwICYmCisgICAgICAgICBmaWxlLT5vcHRpb25zKCkucHlfZ2VuZXJpY19zZXJ2aWNlcygpOworfQorCisKKy8vIFByaW50cyB0aGUgY29tbW9uIGJvaWxlcnBsYXRlIG5lZWRlZCBhdCB0aGUgdG9wIG9mIGV2ZXJ5IC5weQorLy8gZmlsZSBvdXRwdXQgYnkgdGhpcyBnZW5lcmF0b3IuCit2b2lkIFByaW50VG9wQm9pbGVycGxhdGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBib29sIGRlc2NyaXB0b3JfcHJvdG8pIHsKKyAgLy8gVE9ETyhyb2JpbnNvbik6IEFsbG93IHBhcmFtZXRlcml6YXRpb24gb2YgUHl0aG9uIHZlcnNpb24/CisgIHByaW50ZXItPlByaW50KAorICAgICAgIiMgR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCFcbiIKKyAgICAgICIjIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICAgIlxuaW1wb3J0IHN5c1xuX2I9c3lzLnZlcnNpb25faW5mb1swXTwzIGFuZCAobGFtYmRhIHg6eCkgb3IgKGxhbWJkYSB4OnguZW5jb2RlKCdsYXRpbjEnKSkiICAvLyMjUFkyNQorICAgICAgIlxuIiwKKyAgICAgICJmaWxlbmFtZSIsIGZpbGUtPm5hbWUoKSk7CisgIGlmIChIYXNUb3BMZXZlbEVudW1zKGZpbGUpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJmcm9tIGdvb2dsZS5wcm90b2J1Zi5pbnRlcm5hbCBpbXBvcnQgZW51bV90eXBlX3dyYXBwZXJcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICAgImZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yIGFzIF9kZXNjcmlwdG9yXG4iCisgICAgICAiZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IG1lc3NhZ2UgYXMgX21lc3NhZ2VcbiIKKyAgICAgICJmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgcmVmbGVjdGlvbiBhcyBfcmVmbGVjdGlvblxuIgorICAgICAgImZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBzeW1ib2xfZGF0YWJhc2UgYXMgIgorICAgICAgIl9zeW1ib2xfZGF0YWJhc2VcbiIpOworICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGUpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgc2VydmljZSBhcyBfc2VydmljZVxuIgorICAgICAgICAiZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHNlcnZpY2VfcmVmbGVjdGlvblxuIik7CisgIH0KKworICAvLyBBdm9pZCBjaXJjdWxhciBpbXBvcnRzIGlmIHRoaXMgbW9kdWxlIGlzIGRlc2NyaXB0b3JfcGIyLgorICBpZiAoIWRlc2NyaXB0b3JfcHJvdG8pIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBkZXNjcmlwdG9yX3BiMlxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiIyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW1wb3J0cylcblxuIgorICAgICAgIl9zeW1fZGIgPSBfc3ltYm9sX2RhdGFiYXNlLkRlZmF1bHQoKVxuIik7CisgIHByaW50ZXItPlByaW50KCJcblxuIik7Cit9CisKKworLy8gUmV0dXJucyBhIFB5dGhvbiBsaXRlcmFsIGdpdmluZyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgYSBmaWVsZC4KKy8vIElmIHRoZSBmaWVsZCBzcGVjaWZpZXMgbm8gZXhwbGljaXQgZGVmYXVsdCB2YWx1ZSwgd2UnbGwgcmV0dXJuCisvLyB0aGUgZGVmYXVsdCBkZWZhdWx0IHZhbHVlIGZvciB0aGUgZmllbGQgdHlwZSAoemVybyBmb3IgbnVtYmVycywKKy8vIGVtcHR5IHN0cmluZyBmb3Igc3RyaW5ncywgZW1wdHkgbGlzdCBmb3IgcmVwZWF0ZWQgZmllbGRzLCBhbmQKKy8vIE5vbmUgZm9yIG5vbi1yZXBlYXRlZCwgY29tcG9zaXRlIGZpZWxkcykuCisvLworLy8gVE9ETyhyb2JpbnNvbik6IFVuaWZ5IHdpdGggY29kZSBmcm9tCisvLyAvL2NvbXBpbGVyL2NwcC9pbnRlcm5hbC9wcmltaXRpdmVfZmllbGQuY2MKKy8vIC8vY29tcGlsZXIvY3BwL2ludGVybmFsL2VudW1fZmllbGQuY2MKKy8vIC8vY29tcGlsZXIvY3BwL2ludGVybmFsL3N0cmluZ19maWVsZC5jYworc3RyaW5nIFN0cmluZ2lmeURlZmF1bHRWYWx1ZShjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkKSB7CisgIGlmIChmaWVsZC5pc19yZXBlYXRlZCgpKSB7CisgICAgcmV0dXJuICJbXSI7CisgIH0KKworICBzd2l0Y2ggKGZpZWxkLmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLmRlZmF1bHRfdmFsdWVfaW50MzIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQuZGVmYXVsdF92YWx1ZV91aW50MzIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC5kZWZhdWx0X3ZhbHVlX2ludDY0KCkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLmRlZmF1bHRfdmFsdWVfdWludDY0KCkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRTogeworICAgICAgZG91YmxlIHZhbHVlID0gZmllbGQuZGVmYXVsdF92YWx1ZV9kb3VibGUoKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIC8vIFB5dGhvbiBwcmUtMi42IG9uIFdpbmRvd3MgZG9lcyBub3QgcGFyc2UgImluZiIgY29ycmVjdGx5LiAgSG93ZXZlciwKKyAgICAgICAgLy8gYSBudW1lcmljIGxpdGVyYWwgdGhhdCBpcyB0b28gYmlnIGZvciBhIGRvdWJsZSB3aWxsIGJlY29tZSBpbmZpbml0eS4KKyAgICAgICAgcmV0dXJuICIxZTEwMDAwIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgLy8gU2VlIGFib3ZlLgorICAgICAgICByZXR1cm4gIi0xZTEwMDAwIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gdmFsdWUpIHsKKyAgICAgICAgLy8gaW5maW5pdHkgKiAwID0gbmFuCisgICAgICAgIHJldHVybiAiKDFlMTAwMDAgKiAwKSI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gU2ltcGxlRHRvYSh2YWx1ZSk7CisgICAgICB9CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOiB7CisgICAgICBmbG9hdCB2YWx1ZSA9IGZpZWxkLmRlZmF1bHRfdmFsdWVfZmxvYXQoKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCkpIHsKKyAgICAgICAgLy8gUHl0aG9uIHByZS0yLjYgb24gV2luZG93cyBkb2VzIG5vdCBwYXJzZSAiaW5mIiBjb3JyZWN0bHkuICBIb3dldmVyLAorICAgICAgICAvLyBhIG51bWVyaWMgbGl0ZXJhbCB0aGF0IGlzIHRvbyBiaWcgZm9yIGEgZG91YmxlIHdpbGwgYmVjb21lIGluZmluaXR5LgorICAgICAgICByZXR1cm4gIjFlMTAwMDAiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgIC8vIFNlZSBhYm92ZS4KKyAgICAgICAgcmV0dXJuICItMWUxMDAwMCI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlICE9IHZhbHVlKSB7CisgICAgICAgIC8vIGluZmluaXR5IC0gaW5maW5pdHkgPSBuYW4KKyAgICAgICAgcmV0dXJuICIoMWUxMDAwMCAqIDApIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBTaW1wbGVGdG9hKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBmaWVsZC5kZWZhdWx0X3ZhbHVlX2Jvb2woKSA/ICJUcnVlIiA6ICJGYWxzZSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorLy8jIyFQWTI1ICAgICAgcmV0dXJuICJiXCIiICsgQ0VzY2FwZShmaWVsZC5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSArCisvLyMjIVBZMjUgICAgICAgICAgICAgKGZpZWxkLnR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HID8gIlwiIiA6CisvLyMjIVBZMjUgICAgICAgICAgICAgICAiXCIuZGVjb2RlKCd1dGYtOCcpIik7CisgICAgICByZXR1cm4gIl9iKFwiIiArIENFc2NhcGUoZmllbGQuZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkgKyAgLy8jI1BZMjUKKyAgICAgICAgICAgICAoZmllbGQudHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgPyAiXCIpIiA6ICAvLyMjUFkyNQorICAgICAgICAgICAgICAgIlwiKS5kZWNvZGUoJ3V0Zi04JykiKTsgIC8vIyNQWTI1CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiAiTm9uZSI7CisgIH0KKyAgLy8gKFdlIGNvdWxkIGFkZCBhIGRlZmF1bHQgY2FzZSBhYm92ZSBidXQgdGhlbiB3ZSB3b3VsZG4ndCBnZXQgdGhlIG5pY2UKKyAgLy8gY29tcGlsZXIgd2FybmluZyB3aGVuIGEgbmV3IHR5cGUgaXMgYWRkZWQuKQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm90IHJlYWNoZWQuIjsKKyAgcmV0dXJuICIiOworfQorCitzdHJpbmcgU3RyaW5naWZ5U3ludGF4KEZpbGVEZXNjcmlwdG9yOjpTeW50YXggc3ludGF4KSB7CisgIHN3aXRjaCAoc3ludGF4KSB7CisgICAgY2FzZSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMjoKKyAgICAgIHJldHVybiAicHJvdG8yIjsKKyAgICBjYXNlIEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOgorICAgICAgcmV0dXJuICJwcm90bzMiOworICAgIGNhc2UgRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9VTktOT1dOOgorICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5zdXBwb3J0ZWQgc3ludGF4OyB0aGlzIGdlbmVyYXRvciBvbmx5IHN1cHBvcnRzIHByb3RvMiAiCisgICAgICAgICAgICAgICAgICAgICJhbmQgcHJvdG8zIHN5bnRheC4iOworICAgICAgcmV0dXJuICIiOworICB9Cit9CisKKworfSAgLy8gbmFtZXNwYWNlCisKKworR2VuZXJhdG9yOjpHZW5lcmF0b3IoKSA6IGZpbGVfKE5VTEwpIHsKK30KKworR2VuZXJhdG9yOjp+R2VuZXJhdG9yKCkgeworfQorCitib29sIEdlbmVyYXRvcjo6R2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisKKyAgLy8gQ29tcGxldGVseSBzZXJpYWxpemUgYWxsIEdlbmVyYXRlKCkgY2FsbHMgb24gdGhpcyBpbnN0YW5jZS4gIFRoZQorICAvLyB0aHJlYWQtc2FmZXR5IGNvbnN0cmFpbnRzIG9mIHRoZSBDb2RlR2VuZXJhdG9yIGludGVyZmFjZSBhcmVuJ3QgY2xlYXIgc28KKyAgLy8ganVzdCBiZSBhcyBjb25zZXJ2YXRpdmUgYXMgcG9zc2libGUuICBJdCdzIGVhc2llciB0byByZWxheCB0aGlzIGxhdGVyIGlmCisgIC8vIHdlIG5lZWQgdG8sIGJ1dCBJIGRvdWJ0IGl0IHdpbGwgYmUgYW4gaXNzdWUuCisgIC8vIFRPRE8oa2VudG9uKTogIFRoZSBwcm9wZXIgdGhpbmcgdG8gZG8gd291bGQgYmUgdG8gYWxsb2NhdGUgYW55IHN0YXRlIG9uCisgIC8vICAgdGhlIHN0YWNrIGFuZCB1c2UgdGhhdCwgc28gdGhhdCB0aGUgR2VuZXJhdG9yIGNsYXNzIGl0c2VsZiBkb2VzIG5vdCBuZWVkCisgIC8vICAgdG8gaGF2ZSBhbnkgbXV0YWJsZSBtZW1iZXJzLiAgVGhlbiBpdCBpcyBpbXBsaWNpdGx5IHRocmVhZC1zYWZlLgorICBNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKyAgZmlsZV8gPSBmaWxlOworICBzdHJpbmcgbW9kdWxlX25hbWUgPSBNb2R1bGVOYW1lKGZpbGUtPm5hbWUoKSk7CisgIHN0cmluZyBmaWxlbmFtZSA9IG1vZHVsZV9uYW1lOworICBTdHJpcFN0cmluZygmZmlsZW5hbWUsICIuIiwgJy8nKTsKKyAgZmlsZW5hbWUgKz0gIi5weSI7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmZHA7CisgIGZpbGVfLT5Db3B5VG8oJmZkcCk7CisgIGZkcC5TZXJpYWxpemVUb1N0cmluZygmZmlsZV9kZXNjcmlwdG9yX3NlcmlhbGl6ZWRfKTsKKworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoY29udGV4dC0+T3BlbihmaWxlbmFtZSkpOworICBHT09HTEVfQ0hFQ0sob3V0cHV0LmdldCgpKTsKKyAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgIHByaW50ZXJfID0gJnByaW50ZXI7CisKKyAgUHJpbnRUb3BCb2lsZXJwbGF0ZShwcmludGVyXywgZmlsZV8sIEdlbmVyYXRpbmdEZXNjcmlwdG9yUHJvdG8oKSk7CisgIFByaW50SW1wb3J0cygpOworICBQcmludEZpbGVEZXNjcmlwdG9yKCk7CisgIFByaW50VG9wTGV2ZWxFbnVtcygpOworICBQcmludFRvcExldmVsRXh0ZW5zaW9ucygpOworICBQcmludEFsbE5lc3RlZEVudW1zSW5GaWxlKCk7CisgIFByaW50TWVzc2FnZURlc2NyaXB0b3JzKCk7CisgIEZpeEZvcmVpZ25GaWVsZHNJbkRlc2NyaXB0b3JzKCk7CisgIFByaW50TWVzc2FnZXMoKTsKKyAgLy8gV2UgaGF2ZSB0byBmaXggdXAgdGhlIGV4dGVuc2lvbnMgYWZ0ZXIgdGhlIG1lc3NhZ2UgY2xhc3NlcyB0aGVtc2VsdmVzLAorICAvLyBzaW5jZSB0aGV5IG5lZWQgdG8gY2FsbCBzdGF0aWMgUmVnaXN0ZXJFeHRlbnNpb24oKSBtZXRob2RzIG9uIHRoZXNlCisgIC8vIGNsYXNzZXMuCisgIEZpeEZvcmVpZ25GaWVsZHNJbkV4dGVuc2lvbnMoKTsKKyAgLy8gRGVzY3JpcHRvciBvcHRpb25zIG1heSBoYXZlIGN1c3RvbSBleHRlbnNpb25zLiBUaGVzZSBjdXN0b20gb3B0aW9ucworICAvLyBjYW4gb25seSBiZSBzdWNjZXNzZnVsbHkgcGFyc2VkIGFmdGVyIHdlIHJlZ2lzdGVyIGNvcnJlc3BvbmRpbmcKKyAgLy8gZXh0ZW5zaW9ucy4gVGhlcmVmb3JlIHdlIHBhcnNlIGFsbCBvcHRpb25zIGFnYWluIGhlcmUgdG8gcmVjb2duaXplCisgIC8vIGN1c3RvbSBvcHRpb25zIHRoYXQgbWF5IGJlIHVua25vd24gd2hlbiB3ZSBkZWZpbmUgdGhlIGRlc2NyaXB0b3JzLgorICBGaXhBbGxEZXNjcmlwdG9yT3B0aW9ucygpOworICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGUpKSB7CisgICAgUHJpbnRTZXJ2aWNlcygpOworICB9CisKKyAgcHJpbnRlci5QcmludCgKKyAgICAiIyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobW9kdWxlX3Njb3BlKVxuIik7CisKKyAgcmV0dXJuICFwcmludGVyLmZhaWxlZCgpOworfQorCisvLyBQcmludHMgUHl0aG9uIGltcG9ydHMgZm9yIGFsbCBtb2R1bGVzIGltcG9ydGVkIGJ5IHxmaWxlfC4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludEltcG9ydHMoKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgKytpKSB7CisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSA9IGZpbGVfLT5kZXBlbmRlbmN5KGkpLT5uYW1lKCk7CisgICAgc3RyaW5nIGltcG9ydF9zdGF0ZW1lbnQgPSBNb2R1bGVJbXBvcnRTdGF0ZW1lbnQoZmlsZW5hbWUpOworICAgIHN0cmluZyBtb2R1bGVfYWxpYXMgPSBNb2R1bGVBbGlhcyhmaWxlbmFtZSk7CisgICAgcHJpbnRlcl8tPlByaW50KCIkc3RhdGVtZW50JCBhcyAkYWxpYXMkXG4iLCAic3RhdGVtZW50IiwKKyAgICAgICAgICAgICAgICAgICAgaW1wb3J0X3N0YXRlbWVudCwgImFsaWFzIiwgbW9kdWxlX2FsaWFzKTsKKyAgICBDb3B5UHVibGljRGVwZW5kZW5jaWVzQWxpYXNlcyhtb2R1bGVfYWxpYXMsIGZpbGVfLT5kZXBlbmRlbmN5KGkpKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisKKyAgLy8gUHJpbnQgcHVibGljIGltcG9ydHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7ICsraSkgeworICAgIHN0cmluZyBtb2R1bGVfbmFtZSA9IE1vZHVsZU5hbWUoZmlsZV8tPnB1YmxpY19kZXBlbmRlbmN5KGkpLT5uYW1lKCkpOworICAgIHByaW50ZXJfLT5QcmludCgiZnJvbSAkbW9kdWxlJCBpbXBvcnQgKlxuIiwgIm1vZHVsZSIsIG1vZHVsZV9uYW1lKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIlxuIik7Cit9CisKKy8vIFByaW50cyB0aGUgc2luZ2xlIGZpbGUgZGVzY3JpcHRvciBmb3IgdGhpcyBmaWxlLgordm9pZCBHZW5lcmF0b3I6OlByaW50RmlsZURlc2NyaXB0b3IoKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBrRGVzY3JpcHRvcktleTsKKyAgbVsibmFtZSJdID0gZmlsZV8tPm5hbWUoKTsKKyAgbVsicGFja2FnZSJdID0gZmlsZV8tPnBhY2thZ2UoKTsKKyAgbVsic3ludGF4Il0gPSBTdHJpbmdpZnlTeW50YXgoZmlsZV8tPnN5bnRheCgpKTsKKyAgY29uc3QgY2hhciBmaWxlX2Rlc2NyaXB0b3JfdGVtcGxhdGVbXSA9CisgICAgICAiJGRlc2NyaXB0b3JfbmFtZSQgPSBfZGVzY3JpcHRvci5GaWxlRGVzY3JpcHRvcihcbiIKKyAgICAgICIgIG5hbWU9JyRuYW1lJCcsXG4iCisgICAgICAiICBwYWNrYWdlPSckcGFja2FnZSQnLFxuIgorICAgICAgIiAgc3ludGF4PSckc3ludGF4JCcsXG4iOworICBwcmludGVyXy0+UHJpbnQobSwgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoCisvLyMjIVBZMjUgICAgICAic2VyaWFsaXplZF9wYj1iJyR2YWx1ZSQnXG4iLAorICAgICAgInNlcmlhbGl6ZWRfcGI9X2IoJyR2YWx1ZSQnKVxuIiwgIC8vIyNQWTI1CisgICAgICAidmFsdWUiLCBzdHJpbmdzOjpDSGV4RXNjYXBlKGZpbGVfZGVzY3JpcHRvcl9zZXJpYWxpemVkXykpOworICBpZiAoZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKSAhPSAwKSB7CisgICAgcHJpbnRlcl8tPlByaW50KCIsXG5kZXBlbmRlbmNpZXM9WyIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgKytpKSB7CisgICAgICBzdHJpbmcgbW9kdWxlX2FsaWFzID0gTW9kdWxlQWxpYXMoZmlsZV8tPmRlcGVuZGVuY3koaSktPm5hbWUoKSk7CisgICAgICBwcmludGVyXy0+UHJpbnQoIiRtb2R1bGVfYWxpYXMkLkRFU0NSSVBUT1IsIiwgIm1vZHVsZV9hbGlhcyIsCisgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlX2FsaWFzKTsKKyAgICB9CisgICAgcHJpbnRlcl8tPlByaW50KCJdIik7CisgIH0KKworICAvLyBUT0RPKGZhbGspOiBBbHNvIHByaW50IG9wdGlvbnMgYW5kIGZpeCB0aGUgbWVzc2FnZV90eXBlLCBlbnVtX3R5cGUsCisgIC8vICAgICAgICAgICAgIHNlcnZpY2UgYW5kIGV4dGVuc2lvbiBsYXRlciBpbiB0aGUgZ2VuZXJhdGlvbi4KKworICBwcmludGVyXy0+T3V0ZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoIilcbiIpOworICBwcmludGVyXy0+UHJpbnQoIl9zeW1fZGIuUmVnaXN0ZXJGaWxlRGVzY3JpcHRvcigkbmFtZSQpXG4iLCAibmFtZSIsCisgICAgICAgICAgICAgICAgICBrRGVzY3JpcHRvcktleSk7CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKworLy8gUHJpbnRzIGRlc2NyaXB0b3JzIGFuZCBtb2R1bGUtbGV2ZWwgY29uc3RhbnRzIGZvciBhbGwgdG9wLWxldmVsCisvLyBlbnVtcyBkZWZpbmVkIGluIHxmaWxlfC4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludFRvcExldmVsRW51bXMoKSBjb25zdCB7CisgIHZlY3RvcjxwYWlyPHN0cmluZywgaW50PiA+IHRvcF9sZXZlbF9lbnVtX3ZhbHVlczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yJiBlbnVtX2Rlc2NyaXB0b3IgPSAqZmlsZV8tPmVudW1fdHlwZShpKTsKKyAgICBQcmludEVudW0oZW51bV9kZXNjcmlwdG9yKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIiRuYW1lJCA9ICIKKyAgICAgICAgICAgICAgICAgICAgImVudW1fdHlwZV93cmFwcGVyLkVudW1UeXBlV3JhcHBlcigkZGVzY3JpcHRvcl9uYW1lJCkiLAorICAgICAgICAgICAgICAgICAgICAibmFtZSIsIGVudW1fZGVzY3JpcHRvci5uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yX25hbWUiLAorICAgICAgICAgICAgICAgICAgICBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGVudW1fZGVzY3JpcHRvcikpOworICAgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKKworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZW51bV9kZXNjcmlwdG9yLnZhbHVlX2NvdW50KCk7ICsraikgeworICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciYgdmFsdWVfZGVzY3JpcHRvciA9ICplbnVtX2Rlc2NyaXB0b3IudmFsdWUoaik7CisgICAgICB0b3BfbGV2ZWxfZW51bV92YWx1ZXMucHVzaF9iYWNrKAorICAgICAgICAgIHN0ZDo6bWFrZV9wYWlyKHZhbHVlX2Rlc2NyaXB0b3IubmFtZSgpLCB2YWx1ZV9kZXNjcmlwdG9yLm51bWJlcigpKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3BfbGV2ZWxfZW51bV92YWx1ZXMuc2l6ZSgpOyArK2kpIHsKKyAgICBwcmludGVyXy0+UHJpbnQoIiRuYW1lJCA9ICR2YWx1ZSRcbiIsCisgICAgICAgICAgICAgICAgICAgICJuYW1lIiwgdG9wX2xldmVsX2VudW1fdmFsdWVzW2ldLmZpcnN0LAorICAgICAgICAgICAgICAgICAgICAidmFsdWUiLCBTaW1wbGVJdG9hKHRvcF9sZXZlbF9lbnVtX3ZhbHVlc1tpXS5zZWNvbmQpKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIlxuIik7Cit9CisKKy8vIFByaW50cyBhbGwgZW51bXMgY29udGFpbmVkIGluIGFsbCBtZXNzYWdlIHR5cGVzIGluIHxmaWxlfC4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludEFsbE5lc3RlZEVudW1zSW5GaWxlKCkgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgUHJpbnROZXN0ZWRFbnVtcygqZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KK30KKworLy8gUHJpbnRzIGEgUHl0aG9uIHN0YXRlbWVudCBhc3NpZ25pbmcgdGhlIGFwcHJvcHJpYXRlIG1vZHVsZS1sZXZlbAorLy8gZW51bSBuYW1lIHRvIGEgUHl0aG9uIEVudW1EZXNjcmlwdG9yIG9iamVjdCBlcXVpdmFsZW50IHRvCisvLyBlbnVtX2Rlc2NyaXB0b3IuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yJiBlbnVtX2Rlc2NyaXB0b3IpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICBzdHJpbmcgbW9kdWxlX2xldmVsX2Rlc2NyaXB0b3JfbmFtZSA9CisgICAgICBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGVudW1fZGVzY3JpcHRvcik7CisgIG1bImRlc2NyaXB0b3JfbmFtZSJdID0gbW9kdWxlX2xldmVsX2Rlc2NyaXB0b3JfbmFtZTsKKyAgbVsibmFtZSJdID0gZW51bV9kZXNjcmlwdG9yLm5hbWUoKTsKKyAgbVsiZnVsbF9uYW1lIl0gPSBlbnVtX2Rlc2NyaXB0b3IuZnVsbF9uYW1lKCk7CisgIG1bImZpbGUiXSA9IGtEZXNjcmlwdG9yS2V5OworICBjb25zdCBjaGFyIGVudW1fZGVzY3JpcHRvcl90ZW1wbGF0ZVtdID0KKyAgICAgICIkZGVzY3JpcHRvcl9uYW1lJCA9IF9kZXNjcmlwdG9yLkVudW1EZXNjcmlwdG9yKFxuIgorICAgICAgIiAgbmFtZT0nJG5hbWUkJyxcbiIKKyAgICAgICIgIGZ1bGxfbmFtZT0nJGZ1bGxfbmFtZSQnLFxuIgorICAgICAgIiAgZmlsZW5hbWU9Tm9uZSxcbiIKKyAgICAgICIgIGZpbGU9JGZpbGUkLFxuIgorICAgICAgIiAgdmFsdWVzPVtcbiI7CisgIHN0cmluZyBvcHRpb25zX3N0cmluZzsKKyAgZW51bV9kZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVUb1N0cmluZygmb3B0aW9uc19zdHJpbmcpOworICBwcmludGVyXy0+UHJpbnQobSwgZW51bV9kZXNjcmlwdG9yX3RlbXBsYXRlKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV9kZXNjcmlwdG9yLnZhbHVlX2NvdW50KCk7ICsraSkgeworICAgIFByaW50RW51bVZhbHVlRGVzY3JpcHRvcigqZW51bV9kZXNjcmlwdG9yLnZhbHVlKGkpKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIixcbiIpOworICB9CisgIHByaW50ZXJfLT5PdXRkZW50KCk7CisgIHByaW50ZXJfLT5QcmludCgiXSxcbiIpOworICBwcmludGVyXy0+UHJpbnQoImNvbnRhaW5pbmdfdHlwZT1Ob25lLFxuIik7CisgIHByaW50ZXJfLT5QcmludCgib3B0aW9ucz0kb3B0aW9uc192YWx1ZSQsXG4iLAorICAgICAgICAgICAgICAgICAgIm9wdGlvbnNfdmFsdWUiLAorICAgICAgICAgICAgICAgICAgT3B0aW9uc1ZhbHVlKCJFbnVtT3B0aW9ucyIsIG9wdGlvbnNfc3RyaW5nKSk7CisgIEVudW1EZXNjcmlwdG9yUHJvdG8gZWRwOworICBQcmludFNlcmlhbGl6ZWRQYkludGVydmFsKGVudW1fZGVzY3JpcHRvciwgZWRwKTsKKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCIpXG4iKTsKKyAgcHJpbnRlcl8tPlByaW50KCJfc3ltX2RiLlJlZ2lzdGVyRW51bURlc2NyaXB0b3IoJG5hbWUkKVxuIiwgIm5hbWUiLAorICAgICAgICAgICAgICAgICAgbW9kdWxlX2xldmVsX2Rlc2NyaXB0b3JfbmFtZSk7CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKworLy8gUmVjdXJzaXZlbHkgcHJpbnRzIGVudW1zIGluIG5lc3RlZCB0eXBlcyB3aXRoaW4gZGVzY3JpcHRvciwgdGhlbgorLy8gcHJpbnRzIGVudW1zIGNvbnRhaW5lZCBhdCB0aGUgdG9wIGxldmVsIGluIGRlc2NyaXB0b3IuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnROZXN0ZWRFbnVtcyhjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBQcmludE5lc3RlZEVudW1zKCpkZXNjcmlwdG9yLm5lc3RlZF90eXBlKGkpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgUHJpbnRFbnVtKCpkZXNjcmlwdG9yLmVudW1fdHlwZShpKSk7CisgIH0KK30KKwordm9pZCBHZW5lcmF0b3I6OlByaW50VG9wTGV2ZWxFeHRlbnNpb25zKCkgY29uc3QgeworICBjb25zdCBib29sIGlzX2V4dGVuc2lvbiA9IHRydWU7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGV4dGVuc2lvbl9maWVsZCA9ICpmaWxlXy0+ZXh0ZW5zaW9uKGkpOworICAgIHN0cmluZyBjb25zdGFudF9uYW1lID0gZXh0ZW5zaW9uX2ZpZWxkLm5hbWUoKSArICJfRklFTERfTlVNQkVSIjsKKyAgICBVcHBlclN0cmluZygmY29uc3RhbnRfbmFtZSk7CisgICAgcHJpbnRlcl8tPlByaW50KCIkY29uc3RhbnRfbmFtZSQgPSAkbnVtYmVyJFxuIiwKKyAgICAgICJjb25zdGFudF9uYW1lIiwgY29uc3RhbnRfbmFtZSwKKyAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGV4dGVuc2lvbl9maWVsZC5udW1iZXIoKSkpOworICAgIHByaW50ZXJfLT5QcmludCgiJG5hbWUkID0gIiwgIm5hbWUiLCBleHRlbnNpb25fZmllbGQubmFtZSgpKTsKKyAgICBQcmludEZpZWxkRGVzY3JpcHRvcihleHRlbnNpb25fZmllbGQsIGlzX2V4dGVuc2lvbik7CisgICAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKworLy8gUHJpbnRzIFB5dGhvbiBlcXVpdmFsZW50cyBvZiBhbGwgRGVzY3JpcHRvcnMgaW4gfGZpbGV8Lgordm9pZCBHZW5lcmF0b3I6OlByaW50TWVzc2FnZURlc2NyaXB0b3JzKCkgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgUHJpbnREZXNjcmlwdG9yKCpmaWxlXy0+bWVzc2FnZV90eXBlKGkpKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisgIH0KK30KKwordm9pZCBHZW5lcmF0b3I6OlByaW50U2VydmljZXMoKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnNlcnZpY2VfY291bnQoKTsgKytpKSB7CisgICAgUHJpbnRTZXJ2aWNlRGVzY3JpcHRvcigqZmlsZV8tPnNlcnZpY2UoaSkpOworICAgIFByaW50U2VydmljZUNsYXNzKCpmaWxlXy0+c2VydmljZShpKSk7CisgICAgUHJpbnRTZXJ2aWNlU3R1YigqZmlsZV8tPnNlcnZpY2UoaSkpOworICAgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRTZXJ2aWNlRGVzY3JpcHRvcigKKyAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisgIHN0cmluZyBzZXJ2aWNlX25hbWUgPSBNb2R1bGVMZXZlbFNlcnZpY2VEZXNjcmlwdG9yTmFtZShkZXNjcmlwdG9yKTsKKyAgc3RyaW5nIG9wdGlvbnNfc3RyaW5nOworICBkZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVUb1N0cmluZygmb3B0aW9uc19zdHJpbmcpOworCisgIHByaW50ZXJfLT5QcmludCgKKyAgICAgICIkc2VydmljZV9uYW1lJCA9IF9kZXNjcmlwdG9yLlNlcnZpY2VEZXNjcmlwdG9yKFxuIiwKKyAgICAgICJzZXJ2aWNlX25hbWUiLCBzZXJ2aWNlX25hbWUpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsibmFtZSJdID0gZGVzY3JpcHRvci5uYW1lKCk7CisgIG1bImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci5mdWxsX25hbWUoKTsKKyAgbVsiZmlsZSJdID0ga0Rlc2NyaXB0b3JLZXk7CisgIG1bImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3IuaW5kZXgoKSk7CisgIG1bIm9wdGlvbnNfdmFsdWUiXSA9IE9wdGlvbnNWYWx1ZSgiU2VydmljZU9wdGlvbnMiLCBvcHRpb25zX3N0cmluZyk7CisgIGNvbnN0IGNoYXIgcmVxdWlyZWRfZnVuY3Rpb25fYXJndW1lbnRzW10gPQorICAgICAgIm5hbWU9JyRuYW1lJCcsXG4iCisgICAgICAiZnVsbF9uYW1lPSckZnVsbF9uYW1lJCcsXG4iCisgICAgICAiZmlsZT0kZmlsZSQsXG4iCisgICAgICAiaW5kZXg9JGluZGV4JCxcbiIKKyAgICAgICJvcHRpb25zPSRvcHRpb25zX3ZhbHVlJCxcbiI7CisgIHByaW50ZXJfLT5QcmludChtLCByZXF1aXJlZF9mdW5jdGlvbl9hcmd1bWVudHMpOworCisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gc2RwOworICBQcmludFNlcmlhbGl6ZWRQYkludGVydmFsKGRlc2NyaXB0b3IsIHNkcCk7CisKKyAgcHJpbnRlcl8tPlByaW50KCJtZXRob2RzPVtcbiIpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IubWV0aG9kX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3IubWV0aG9kKGkpOworICAgIG1ldGhvZC0+b3B0aW9ucygpLlNlcmlhbGl6ZVRvU3RyaW5nKCZvcHRpb25zX3N0cmluZyk7CisKKyAgICBtLmNsZWFyKCk7CisgICAgbVsibmFtZSJdID0gbWV0aG9kLT5uYW1lKCk7CisgICAgbVsiZnVsbF9uYW1lIl0gPSBtZXRob2QtPmZ1bGxfbmFtZSgpOworICAgIG1bImluZGV4Il0gPSBTaW1wbGVJdG9hKG1ldGhvZC0+aW5kZXgoKSk7CisgICAgbVsic2VyaWFsaXplZF9vcHRpb25zIl0gPSBDRXNjYXBlKG9wdGlvbnNfc3RyaW5nKTsKKyAgICBtWyJpbnB1dF90eXBlIl0gPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKCoobWV0aG9kLT5pbnB1dF90eXBlKCkpKTsKKyAgICBtWyJvdXRwdXRfdHlwZSJdID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgqKG1ldGhvZC0+b3V0cHV0X3R5cGUoKSkpOworICAgIG1bIm9wdGlvbnNfdmFsdWUiXSA9IE9wdGlvbnNWYWx1ZSgiTWV0aG9kT3B0aW9ucyIsIG9wdGlvbnNfc3RyaW5nKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIl9kZXNjcmlwdG9yLk1ldGhvZERlc2NyaXB0b3IoXG4iKTsKKyAgICBwcmludGVyXy0+SW5kZW50KCk7CisgICAgcHJpbnRlcl8tPlByaW50KAorICAgICAgICBtLAorICAgICAgICAibmFtZT0nJG5hbWUkJyxcbiIKKyAgICAgICAgImZ1bGxfbmFtZT0nJGZ1bGxfbmFtZSQnLFxuIgorICAgICAgICAiaW5kZXg9JGluZGV4JCxcbiIKKyAgICAgICAgImNvbnRhaW5pbmdfc2VydmljZT1Ob25lLFxuIgorICAgICAgICAiaW5wdXRfdHlwZT0kaW5wdXRfdHlwZSQsXG4iCisgICAgICAgICJvdXRwdXRfdHlwZT0kb3V0cHV0X3R5cGUkLFxuIgorICAgICAgICAib3B0aW9ucz0kb3B0aW9uc192YWx1ZSQsXG4iKTsKKyAgICBwcmludGVyXy0+T3V0ZGVudCgpOworICAgIHByaW50ZXJfLT5QcmludCgiKSxcbiIpOworICB9CisKKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCJdKVxuXG4iKTsKK30KKworCit2b2lkIEdlbmVyYXRvcjo6UHJpbnREZXNjcmlwdG9yS2V5QW5kTW9kdWxlTmFtZSgKKyAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICBwcmludGVyXy0+UHJpbnQoCisgICAgICAiJGRlc2NyaXB0b3Jfa2V5JCA9ICRkZXNjcmlwdG9yX25hbWUkLFxuIiwKKyAgICAgICJkZXNjcmlwdG9yX2tleSIsIGtEZXNjcmlwdG9yS2V5LAorICAgICAgImRlc2NyaXB0b3JfbmFtZSIsIE1vZHVsZUxldmVsU2VydmljZURlc2NyaXB0b3JOYW1lKGRlc2NyaXB0b3IpKTsKKyAgcHJpbnRlcl8tPlByaW50KAorICAgICAgIl9fbW9kdWxlX18gPSAnJG1vZHVsZV9uYW1lJCdcbiIsCisgICAgICAibW9kdWxlX25hbWUiLCBNb2R1bGVOYW1lKGZpbGVfLT5uYW1lKCkpKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OlByaW50U2VydmljZUNsYXNzKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIC8vIFByaW50IHRoZSBzZXJ2aWNlLgorICBwcmludGVyXy0+UHJpbnQoIiRjbGFzc19uYW1lJCA9IHNlcnZpY2VfcmVmbGVjdGlvbi5HZW5lcmF0ZWRTZXJ2aWNlVHlwZSgiCisgICAgICAgICAgICAgICAgICAiJyRjbGFzc19uYW1lJCcsIChfc2VydmljZS5TZXJ2aWNlLCksIGRpY3QoXG4iLAorICAgICAgICAgICAgICAgICAgImNsYXNzX25hbWUiLCBkZXNjcmlwdG9yLm5hbWUoKSk7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgR2VuZXJhdG9yOjpQcmludERlc2NyaXB0b3JLZXlBbmRNb2R1bGVOYW1lKGRlc2NyaXB0b3IpOworICBwcmludGVyXy0+UHJpbnQoIikpXG5cbiIpOworICBwcmludGVyXy0+T3V0ZGVudCgpOworfQorCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRTZXJ2aWNlU3R1Yihjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICAvLyBQcmludCB0aGUgc2VydmljZSBzdHViLgorICBwcmludGVyXy0+UHJpbnQoIiRjbGFzc19uYW1lJF9TdHViID0gIgorICAgICAgICAgICAgICAgICAgInNlcnZpY2VfcmVmbGVjdGlvbi5HZW5lcmF0ZWRTZXJ2aWNlU3R1YlR5cGUoIgorICAgICAgICAgICAgICAgICAgIickY2xhc3NfbmFtZSRfU3R1YicsICgkY2xhc3NfbmFtZSQsKSwgZGljdChcbiIsCisgICAgICAgICAgICAgICAgICAiY2xhc3NfbmFtZSIsIGRlc2NyaXB0b3IubmFtZSgpKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworICBHZW5lcmF0b3I6OlByaW50RGVzY3JpcHRvcktleUFuZE1vZHVsZU5hbWUoZGVzY3JpcHRvcik7CisgIHByaW50ZXJfLT5QcmludCgiKSlcblxuIik7CisgIHByaW50ZXJfLT5PdXRkZW50KCk7Cit9CisKKy8vIFByaW50cyBzdGF0ZW1lbnQgYXNzaWduaW5nIE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUobWVzc2FnZV9kZXNjcmlwdG9yKQorLy8gdG8gYSBQeXRob24gRGVzY3JpcHRvciBvYmplY3QgZm9yIG1lc3NhZ2VfZGVzY3JpcHRvci4KKy8vCisvLyBNdXR1YWxseSByZWN1cnNpdmUgd2l0aCBQcmludE5lc3RlZERlc2NyaXB0b3JzKCkuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnREZXNjcmlwdG9yKGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvcikgY29uc3QgeworICBQcmludE5lc3RlZERlc2NyaXB0b3JzKG1lc3NhZ2VfZGVzY3JpcHRvcik7CisKKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworICBwcmludGVyXy0+UHJpbnQoIiRkZXNjcmlwdG9yX25hbWUkID0gX2Rlc2NyaXB0b3IuRGVzY3JpcHRvcihcbiIsCisgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRvcl9uYW1lIiwKKyAgICAgICAgICAgICAgICAgIE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUobWVzc2FnZV9kZXNjcmlwdG9yKSk7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICBtWyJuYW1lIl0gPSBtZXNzYWdlX2Rlc2NyaXB0b3IubmFtZSgpOworICBtWyJmdWxsX25hbWUiXSA9IG1lc3NhZ2VfZGVzY3JpcHRvci5mdWxsX25hbWUoKTsKKyAgbVsiZmlsZSJdID0ga0Rlc2NyaXB0b3JLZXk7CisgIGNvbnN0IGNoYXIgcmVxdWlyZWRfZnVuY3Rpb25fYXJndW1lbnRzW10gPQorICAgICAgIm5hbWU9JyRuYW1lJCcsXG4iCisgICAgICAiZnVsbF9uYW1lPSckZnVsbF9uYW1lJCcsXG4iCisgICAgICAiZmlsZW5hbWU9Tm9uZSxcbiIKKyAgICAgICJmaWxlPSRmaWxlJCxcbiIKKyAgICAgICJjb250YWluaW5nX3R5cGU9Tm9uZSxcbiI7CisgIHByaW50ZXJfLT5QcmludChtLCByZXF1aXJlZF9mdW5jdGlvbl9hcmd1bWVudHMpOworICBQcmludEZpZWxkc0luRGVzY3JpcHRvcihtZXNzYWdlX2Rlc2NyaXB0b3IpOworICBQcmludEV4dGVuc2lvbnNJbkRlc2NyaXB0b3IobWVzc2FnZV9kZXNjcmlwdG9yKTsKKworICAvLyBOZXN0ZWQgdHlwZXMKKyAgcHJpbnRlcl8tPlByaW50KCJuZXN0ZWRfdHlwZXM9WyIpOworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VfZGVzY3JpcHRvci5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBzdHJpbmcgbmVzdGVkX25hbWUgPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKAorICAgICAgICAqbWVzc2FnZV9kZXNjcmlwdG9yLm5lc3RlZF90eXBlKGkpKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIiRuYW1lJCwgIiwgIm5hbWUiLCBuZXN0ZWRfbmFtZSk7CisgIH0KKyAgcHJpbnRlcl8tPlByaW50KCJdLFxuIik7CisKKyAgLy8gRW51bSB0eXBlcworICBwcmludGVyXy0+UHJpbnQoImVudW1fdHlwZXM9W1xuIik7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlX2Rlc2NyaXB0b3IuZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IHN0cmluZyBkZXNjcmlwdG9yX25hbWUgPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKAorICAgICAgICAqbWVzc2FnZV9kZXNjcmlwdG9yLmVudW1fdHlwZShpKSk7CisgICAgcHJpbnRlcl8tPlByaW50KGRlc2NyaXB0b3JfbmFtZS5jX3N0cigpKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIixcbiIpOworICB9CisgIHByaW50ZXJfLT5PdXRkZW50KCk7CisgIHByaW50ZXJfLT5QcmludCgiXSxcbiIpOworICBzdHJpbmcgb3B0aW9uc19zdHJpbmc7CisgIG1lc3NhZ2VfZGVzY3JpcHRvci5vcHRpb25zKCkuU2VyaWFsaXplVG9TdHJpbmcoJm9wdGlvbnNfc3RyaW5nKTsKKyAgcHJpbnRlcl8tPlByaW50KAorICAgICAgIm9wdGlvbnM9JG9wdGlvbnNfdmFsdWUkLFxuIgorICAgICAgImlzX2V4dGVuZGFibGU9JGV4dGVuZGFibGUkLFxuIgorICAgICAgInN5bnRheD0nJHN5bnRheCQnIiwKKyAgICAgICJvcHRpb25zX3ZhbHVlIiwgT3B0aW9uc1ZhbHVlKCJNZXNzYWdlT3B0aW9ucyIsIG9wdGlvbnNfc3RyaW5nKSwKKyAgICAgICJleHRlbmRhYmxlIiwgbWVzc2FnZV9kZXNjcmlwdG9yLmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCA/CisgICAgICAgICAgICAgICAgICAgICAgIlRydWUiIDogIkZhbHNlIiwKKyAgICAgICJzeW50YXgiLCBTdHJpbmdpZnlTeW50YXgobWVzc2FnZV9kZXNjcmlwdG9yLmZpbGUoKS0+c3ludGF4KCkpKTsKKyAgcHJpbnRlcl8tPlByaW50KCIsXG4iKTsKKworICAvLyBFeHRlbnNpb24gcmFuZ2VzCisgIHByaW50ZXJfLT5QcmludCgiZXh0ZW5zaW9uX3Jhbmdlcz1bIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV9kZXNjcmlwdG9yLmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmFuZ2UgPQorICAgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IuZXh0ZW5zaW9uX3JhbmdlKGkpOworICAgIHByaW50ZXJfLT5QcmludCgiKCRzdGFydCQsICRlbmQkKSwgIiwKKyAgICAgICAgICAgICAgICAgICAgInN0YXJ0IiwgU2ltcGxlSXRvYShyYW5nZS0+c3RhcnQpLAorICAgICAgICAgICAgICAgICAgICAiZW5kIiwgU2ltcGxlSXRvYShyYW5nZS0+ZW5kKSk7CisgIH0KKyAgcHJpbnRlcl8tPlByaW50KCJdLFxuIik7CisgIHByaW50ZXJfLT5QcmludCgib25lb2ZzPVtcbiIpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV9kZXNjcmlwdG9yLm9uZW9mX2RlY2xfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZV9kZXNjcmlwdG9yLm9uZW9mX2RlY2woaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICAgIG1bIm5hbWUiXSA9IGRlc2MtPm5hbWUoKTsKKyAgICBtWyJmdWxsX25hbWUiXSA9IGRlc2MtPmZ1bGxfbmFtZSgpOworICAgIG1bImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2MtPmluZGV4KCkpOworICAgIHByaW50ZXJfLT5QcmludCgKKyAgICAgICAgbSwKKyAgICAgICAgIl9kZXNjcmlwdG9yLk9uZW9mRGVzY3JpcHRvcihcbiIKKyAgICAgICAgIiAgbmFtZT0nJG5hbWUkJywgZnVsbF9uYW1lPSckZnVsbF9uYW1lJCcsXG4iCisgICAgICAgICIgIGluZGV4PSRpbmRleCQsIGNvbnRhaW5pbmdfdHlwZT1Ob25lLCBmaWVsZHM9W10pLFxuIik7CisgIH0KKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCJdLFxuIik7CisgIC8vIFNlcmlhbGl6YXRpb24gb2YgcHJvdG8KKyAgRGVzY3JpcHRvclByb3RvIGVkcDsKKyAgUHJpbnRTZXJpYWxpemVkUGJJbnRlcnZhbChtZXNzYWdlX2Rlc2NyaXB0b3IsIGVkcCk7CisKKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCIpXG4iKTsKK30KKworLy8gUHJpbnRzIFB5dGhvbiBEZXNjcmlwdG9yIG9iamVjdHMgZm9yIGFsbCBuZXN0ZWQgdHlwZXMgY29udGFpbmVkIGluCisvLyBtZXNzYWdlX2Rlc2NyaXB0b3IuCisvLworLy8gTXV0dWFsbHkgcmVjdXJzaXZlIHdpdGggUHJpbnREZXNjcmlwdG9yKCkuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnROZXN0ZWREZXNjcmlwdG9ycygKKyAgICBjb25zdCBEZXNjcmlwdG9yJiBjb250YWluaW5nX2Rlc2NyaXB0b3IpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb250YWluaW5nX2Rlc2NyaXB0b3IubmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgUHJpbnREZXNjcmlwdG9yKCpjb250YWluaW5nX2Rlc2NyaXB0b3IubmVzdGVkX3R5cGUoaSkpOworICB9Cit9CisKKy8vIFByaW50cyBhbGwgbWVzc2FnZXMgaW4gfGZpbGV8Lgordm9pZCBHZW5lcmF0b3I6OlByaW50TWVzc2FnZXMoKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICB2ZWN0b3I8c3RyaW5nPiB0b19yZWdpc3RlcjsKKyAgICBQcmludE1lc3NhZ2UoKmZpbGVfLT5tZXNzYWdlX3R5cGUoaSksICIiLCAmdG9fcmVnaXN0ZXIpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgdG9fcmVnaXN0ZXIuc2l6ZSgpOyArK2opIHsKKyAgICAgIHByaW50ZXJfLT5QcmludCgiX3N5bV9kYi5SZWdpc3Rlck1lc3NhZ2UoJG5hbWUkKVxuIiwgIm5hbWUiLAorICAgICAgICAgICAgICAgICAgICAgIHRvX3JlZ2lzdGVyW2pdKTsKKyAgICB9CisgICAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworICB9Cit9CisKKy8vIFByaW50cyBhIFB5dGhvbiBjbGFzcyBmb3IgdGhlIGdpdmVuIG1lc3NhZ2UgZGVzY3JpcHRvci4gIFdlIGRlZmVyIHRvIHRoZQorLy8gbWV0YWNsYXNzIHRvIGRvIGFsbW9zdCBhbGwgb2YgdGhlIHdvcmsgb2YgYWN0dWFsbHkgY3JlYXRpbmcgYSB1c2VmdWwgY2xhc3MuCisvLyBUaGUgcHVycG9zZSBvZiB0aGlzIGZ1bmN0aW9uIGFuZCBpdHMgbWFueSBoZWxwZXIgZnVuY3Rpb25zIGFib3ZlIGlzIG1lcmVseQorLy8gdG8gb3V0cHV0IGEgUHl0aG9uIHZlcnNpb24gb2YgdGhlIGRlc2NyaXB0b3JzLCB3aGljaCB0aGUgbWV0YWNsYXNzIGluCisvLyByZWZsZWN0aW9uLnB5IHdpbGwgdXNlIHRvIGNvbnN0cnVjdCB0aGUgbWVhdCBvZiB0aGUgY2xhc3MgaXRzZWxmLgorLy8KKy8vIE11dHVhbGx5IHJlY3Vyc2l2ZSB3aXRoIFByaW50TmVzdGVkTWVzc2FnZXMoKS4KKy8vIENvbGxlY3QgbmVzdGVkIG1lc3NhZ2UgbmFtZXMgdG9fcmVnaXN0ZXIgZm9yIHRoZSBzeW1ib2xfZGF0YWJhc2UuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiB0b19yZWdpc3RlcikgY29uc3QgeworICBzdHJpbmcgcXVhbGlmaWVkX25hbWUocHJlZml4ICsgbWVzc2FnZV9kZXNjcmlwdG9yLm5hbWUoKSk7CisgIHRvX3JlZ2lzdGVyLT5wdXNoX2JhY2socXVhbGlmaWVkX25hbWUpOworICBwcmludGVyXy0+UHJpbnQoCisgICAgICAiJG5hbWUkID0gX3JlZmxlY3Rpb24uR2VuZXJhdGVkUHJvdG9jb2xNZXNzYWdlVHlwZSgnJG5hbWUkJywgIgorICAgICAgIihfbWVzc2FnZS5NZXNzYWdlLCksIGRpY3QoXG4iLAorICAgICAgIm5hbWUiLCBtZXNzYWdlX2Rlc2NyaXB0b3IubmFtZSgpKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworCisgIFByaW50TmVzdGVkTWVzc2FnZXMobWVzc2FnZV9kZXNjcmlwdG9yLCBxdWFsaWZpZWRfbmFtZSArICIuIiwgdG9fcmVnaXN0ZXIpOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bImRlc2NyaXB0b3Jfa2V5Il0gPSBrRGVzY3JpcHRvcktleTsKKyAgbVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKG1lc3NhZ2VfZGVzY3JpcHRvcik7CisgIHByaW50ZXJfLT5QcmludChtLCAiJGRlc2NyaXB0b3Jfa2V5JCA9ICRkZXNjcmlwdG9yX25hbWUkLFxuIik7CisgIHByaW50ZXJfLT5QcmludCgiX19tb2R1bGVfXyA9ICckbW9kdWxlX25hbWUkJ1xuIiwKKyAgICAgICAgICAgICAgICAgICJtb2R1bGVfbmFtZSIsIE1vZHVsZU5hbWUoZmlsZV8tPm5hbWUoKSkpOworICBwcmludGVyXy0+UHJpbnQoIiMgQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOiRmdWxsX25hbWUkKVxuIiwKKyAgICAgICAgICAgICAgICAgICJmdWxsX25hbWUiLCBtZXNzYWdlX2Rlc2NyaXB0b3IuZnVsbF9uYW1lKCkpOworICBwcmludGVyXy0+UHJpbnQoIikpXG4iKTsKKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKK30KKworLy8gUHJpbnRzIGFsbCBuZXN0ZWQgbWVzc2FnZXMgd2l0aGluIHxjb250YWluaW5nX2Rlc2NyaXB0b3J8LgorLy8gTXV0dWFsbHkgcmVjdXJzaXZlIHdpdGggUHJpbnRNZXNzYWdlKCkuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnROZXN0ZWRNZXNzYWdlcyhjb25zdCBEZXNjcmlwdG9yJiBjb250YWluaW5nX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiB0b19yZWdpc3RlcikgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnRhaW5pbmdfZGVzY3JpcHRvci5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisgICAgUHJpbnRNZXNzYWdlKCpjb250YWluaW5nX2Rlc2NyaXB0b3IubmVzdGVkX3R5cGUoaSksIHByZWZpeCwgdG9fcmVnaXN0ZXIpOworICAgIHByaW50ZXJfLT5QcmludCgiLFxuIik7CisgIH0KK30KKworLy8gUmVjdXJzaXZlbHkgZml4ZXMgZm9yZWlnbiBmaWVsZHMgaW4gYWxsIG5lc3RlZCB0eXBlcyBpbiB8ZGVzY3JpcHRvcnwsIHRoZW4KKy8vIHNldHMgdGhlIG1lc3NhZ2VfdHlwZSBhbmQgZW51bV90eXBlIG9mIGFsbCBtZXNzYWdlIGFuZCBlbnVtIGZpZWxkcyB0byBwb2ludAorLy8gdG8gdGhlaXIgcmVzcGVjdGl2ZSBkZXNjcmlwdG9ycy4KKy8vIEFyZ3M6CisvLyAgIGRlc2NyaXB0b3I6IGRlc2NyaXB0b3IgdG8gcHJpbnQgZmllbGRzIGZvci4KKy8vICAgY29udGFpbmluZ19kZXNjcmlwdG9yOiBpZiBkZXNjcmlwdG9yIGlzIGEgbmVzdGVkIHR5cGUsIHRoaXMgaXMgaXRzCisvLyAgICAgICBjb250YWluaW5nIHR5cGUsIG9yIE5VTEwgaWYgdGhpcyBpcyBhIHJvb3QvdG9wLWxldmVsIHR5cGUuCit2b2lkIEdlbmVyYXRvcjo6Rml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfZGVzY3JpcHRvcikgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IubmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcigqZGVzY3JpcHRvci5uZXN0ZWRfdHlwZShpKSwgJmRlc2NyaXB0b3IpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGRfZGVzY3JpcHRvciA9ICpkZXNjcmlwdG9yLmZpZWxkKGkpOworICAgIEZpeEZvcmVpZ25GaWVsZHNJbkZpZWxkKCZkZXNjcmlwdG9yLCBmaWVsZF9kZXNjcmlwdG9yLCAiZmllbGRzX2J5X25hbWUiKTsKKyAgfQorCisgIEZpeENvbnRhaW5pbmdUeXBlSW5EZXNjcmlwdG9yKGRlc2NyaXB0b3IsIGNvbnRhaW5pbmdfZGVzY3JpcHRvcik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRW51bURlc2NyaXB0b3ImIGVudW1fZGVzY3JpcHRvciA9ICpkZXNjcmlwdG9yLmVudW1fdHlwZShpKTsKKyAgICBGaXhDb250YWluaW5nVHlwZUluRGVzY3JpcHRvcihlbnVtX2Rlc2NyaXB0b3IsICZkZXNjcmlwdG9yKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3Iub25lb2ZfZGVjbF9jb3VudCgpOyArK2kpIHsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGRlc2NyaXB0b3Iub25lb2ZfZGVjbChpKTsKKyAgICBtWyJkZXNjcmlwdG9yX25hbWUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZGVzY3JpcHRvcik7CisgICAgbVsib25lb2ZfbmFtZSJdID0gb25lb2YtPm5hbWUoKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IG9uZW9mLT5maWVsZF9jb3VudCgpOyArK2opIHsKKyAgICAgIG1bImZpZWxkX25hbWUiXSA9IG9uZW9mLT5maWVsZChqKS0+bmFtZSgpOworICAgICAgcHJpbnRlcl8tPlByaW50KAorICAgICAgICAgIG0sCisgICAgICAgICAgIiRkZXNjcmlwdG9yX25hbWUkLm9uZW9mc19ieV9uYW1lWyckb25lb2ZfbmFtZSQnXS5maWVsZHMuYXBwZW5kKFxuIgorICAgICAgICAgICIgICRkZXNjcmlwdG9yX25hbWUkLmZpZWxkc19ieV9uYW1lWyckZmllbGRfbmFtZSQnXSlcbiIpOworICAgICAgcHJpbnRlcl8tPlByaW50KAorICAgICAgICAgIG0sCisgICAgICAgICAgIiRkZXNjcmlwdG9yX25hbWUkLmZpZWxkc19ieV9uYW1lWyckZmllbGRfbmFtZSQnXS5jb250YWluaW5nX29uZW9mID0gIgorICAgICAgICAgICIkZGVzY3JpcHRvcl9uYW1lJC5vbmVvZnNfYnlfbmFtZVsnJG9uZW9mX25hbWUkJ11cbiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6QWRkTWVzc2FnZVRvRmlsZURlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bImRlc2NyaXB0b3JfbmFtZSJdID0ga0Rlc2NyaXB0b3JLZXk7CisgIG1bIm1lc3NhZ2VfbmFtZSJdID0gZGVzY3JpcHRvci5uYW1lKCk7CisgIG1bIm1lc3NhZ2VfZGVzY3JpcHRvcl9uYW1lIl0gPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGRlc2NyaXB0b3IpOworICBjb25zdCBjaGFyIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZVtdID0KKyAgICAgICIkZGVzY3JpcHRvcl9uYW1lJC5tZXNzYWdlX3R5cGVzX2J5X25hbWVbJyRtZXNzYWdlX25hbWUkJ10gPSAiCisgICAgICAiJG1lc3NhZ2VfZGVzY3JpcHRvcl9uYW1lJFxuIjsKKyAgcHJpbnRlcl8tPlByaW50KG0sIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZSk7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpBZGRFbnVtVG9GaWxlRGVzY3JpcHRvcigKKyAgICBjb25zdCBFbnVtRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bImRlc2NyaXB0b3JfbmFtZSJdID0ga0Rlc2NyaXB0b3JLZXk7CisgIG1bImVudW1fbmFtZSJdID0gZGVzY3JpcHRvci5uYW1lKCk7CisgIG1bImVudW1fZGVzY3JpcHRvcl9uYW1lIl0gPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGRlc2NyaXB0b3IpOworICBjb25zdCBjaGFyIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZVtdID0KKyAgICAgICIkZGVzY3JpcHRvcl9uYW1lJC5lbnVtX3R5cGVzX2J5X25hbWVbJyRlbnVtX25hbWUkJ10gPSAiCisgICAgICAiJGVudW1fZGVzY3JpcHRvcl9uYW1lJFxuIjsKKyAgcHJpbnRlcl8tPlByaW50KG0sIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZSk7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpBZGRFeHRlbnNpb25Ub0ZpbGVEZXNjcmlwdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bImRlc2NyaXB0b3JfbmFtZSJdID0ga0Rlc2NyaXB0b3JLZXk7CisgIG1bImZpZWxkX25hbWUiXSA9IGRlc2NyaXB0b3IubmFtZSgpOworICBjb25zdCBjaGFyIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZVtdID0KKyAgICAgICIkZGVzY3JpcHRvcl9uYW1lJC5leHRlbnNpb25zX2J5X25hbWVbJyRmaWVsZF9uYW1lJCddID0gIgorICAgICAgIiRmaWVsZF9uYW1lJFxuIjsKKyAgcHJpbnRlcl8tPlByaW50KG0sIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZSk7Cit9CisKKy8vIFNldHMgYW55IG5lY2Vzc2FyeSBtZXNzYWdlX3R5cGUgYW5kIGVudW1fdHlwZSBhdHRyaWJ1dGVzCisvLyBmb3IgdGhlIFB5dGhvbiB2ZXJzaW9uIG9mIHxmaWVsZHwuCisvLworLy8gY29udGFpbmluZ190eXBlIG1heSBiZSBOVUxMLCBpbiB3aGljaCBjYXNlIHRoaXMgaXMgYSBtb2R1bGUtbGV2ZWwgZmllbGQuCisvLworLy8gcHl0aG9uX2RpY3RfbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUgUHl0aG9uIGRpY3Qgd2hlcmUgd2Ugc2hvdWxkCisvLyBsb29rIHRoZSBmaWVsZCB1cCBpbiB0aGUgY29udGFpbmluZyB0eXBlLiAgKGUuZy4sIGZpZWxkc19ieV9uYW1lCisvLyBvciBleHRlbnNpb25zX2J5X25hbWUpLiAgV2UgaWdub3JlIHB5dGhvbl9kaWN0X25hbWUgaWYgY29udGFpbmluZ190eXBlCisvLyBpcyBOVUxMLgordm9pZCBHZW5lcmF0b3I6OkZpeEZvcmVpZ25GaWVsZHNJbkZpZWxkKGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHl0aG9uX2RpY3RfbmFtZSkgY29uc3QgeworICBjb25zdCBzdHJpbmcgZmllbGRfcmVmZXJlbmNpbmdfZXhwcmVzc2lvbiA9IEZpZWxkUmVmZXJlbmNpbmdFeHByZXNzaW9uKAorICAgICAgY29udGFpbmluZ190eXBlLCBmaWVsZCwgcHl0aG9uX2RpY3RfbmFtZSk7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsiZmllbGRfcmVmIl0gPSBmaWVsZF9yZWZlcmVuY2luZ19leHByZXNzaW9uOworICBjb25zdCBEZXNjcmlwdG9yKiBmb3JlaWduX21lc3NhZ2VfdHlwZSA9IGZpZWxkLm1lc3NhZ2VfdHlwZSgpOworICBpZiAoZm9yZWlnbl9tZXNzYWdlX3R5cGUpIHsKKyAgICBtWyJmb3JlaWduX3R5cGUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoKmZvcmVpZ25fbWVzc2FnZV90eXBlKTsKKyAgICBwcmludGVyXy0+UHJpbnQobSwgIiRmaWVsZF9yZWYkLm1lc3NhZ2VfdHlwZSA9ICRmb3JlaWduX3R5cGUkXG4iKTsKKyAgfQorICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlID0gZmllbGQuZW51bV90eXBlKCk7CisgIGlmIChlbnVtX3R5cGUpIHsKKyAgICBtWyJlbnVtX3R5cGUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoKmVudW1fdHlwZSk7CisgICAgcHJpbnRlcl8tPlByaW50KG0sICIkZmllbGRfcmVmJC5lbnVtX3R5cGUgPSAkZW51bV90eXBlJFxuIik7CisgIH0KK30KKworLy8gUmV0dXJucyB0aGUgbW9kdWxlLWxldmVsIGV4cHJlc3Npb24gZm9yIHRoZSBnaXZlbiBGaWVsZERlc2NyaXB0b3IuCisvLyBPbmx5IHdvcmtzIGZvciBmaWVsZHMgaW4gdGhlIC5wcm90byBmaWxlIHRoaXMgR2VuZXJhdG9yIGlzIGdlbmVyYXRpbmcgZm9yLgorLy8KKy8vIGNvbnRhaW5pbmdfdHlwZSBtYXkgYmUgTlVMTCwgaW4gd2hpY2ggY2FzZSB0aGlzIGlzIGEgbW9kdWxlLWxldmVsIGZpZWxkLgorLy8KKy8vIHB5dGhvbl9kaWN0X25hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIFB5dGhvbiBkaWN0IHdoZXJlIHdlIHNob3VsZAorLy8gbG9vayB0aGUgZmllbGQgdXAgaW4gdGhlIGNvbnRhaW5pbmcgdHlwZS4gIChlLmcuLCBmaWVsZHNfYnlfbmFtZQorLy8gb3IgZXh0ZW5zaW9uc19ieV9uYW1lKS4gIFdlIGlnbm9yZSBweXRob25fZGljdF9uYW1lIGlmIGNvbnRhaW5pbmdfdHlwZQorLy8gaXMgTlVMTC4KK3N0cmluZyBHZW5lcmF0b3I6OkZpZWxkUmVmZXJlbmNpbmdFeHByZXNzaW9uKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgIGNvbnN0IHN0cmluZyYgcHl0aG9uX2RpY3RfbmFtZSkgY29uc3QgeworICAvLyBXZSBzaG91bGQgb25seSBldmVyIGJlIGxvb2tpbmcgdXAgZmllbGRzIGluIHRoZSBjdXJyZW50IGZpbGUuCisgIC8vIFRoZSBvbmx5IHRoaW5ncyB3ZSByZWZlciB0byBmcm9tIG90aGVyIGZpbGVzIGFyZSBtZXNzYWdlIGRlc2NyaXB0b3JzLgorICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQuZmlsZSgpLCBmaWxlXykgPDwgZmllbGQuZmlsZSgpLT5uYW1lKCkgPDwgIiB2cy4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBmaWxlXy0+bmFtZSgpOworICBpZiAoIWNvbnRhaW5pbmdfdHlwZSkgeworICAgIHJldHVybiBmaWVsZC5uYW1lKCk7CisgIH0KKyAgcmV0dXJuIHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAiJDAuJDFbJyQyJ10iLAorICAgICAgTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgqY29udGFpbmluZ190eXBlKSwKKyAgICAgIHB5dGhvbl9kaWN0X25hbWUsIGZpZWxkLm5hbWUoKSk7Cit9CisKKy8vIFByaW50cyBjb250YWluaW5nX3R5cGUgZm9yIG5lc3RlZCBkZXNjcmlwdG9ycyBvciBlbnVtIGRlc2NyaXB0b3JzLgordGVtcGxhdGUgPHR5cGVuYW1lIERlc2NyaXB0b3JUPgordm9pZCBHZW5lcmF0b3I6OkZpeENvbnRhaW5pbmdUeXBlSW5EZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3JUJiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfZGVzY3JpcHRvcikgY29uc3QgeworICBpZiAoY29udGFpbmluZ19kZXNjcmlwdG9yICE9IE5VTEwpIHsKKyAgICBjb25zdCBzdHJpbmcgbmVzdGVkX25hbWUgPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGRlc2NyaXB0b3IpOworICAgIGNvbnN0IHN0cmluZyBwYXJlbnRfbmFtZSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoCisgICAgICAgICpjb250YWluaW5nX2Rlc2NyaXB0b3IpOworICAgIHByaW50ZXJfLT5QcmludCgKKyAgICAgICAgIiRuZXN0ZWRfbmFtZSQuY29udGFpbmluZ190eXBlID0gJHBhcmVudF9uYW1lJFxuIiwKKyAgICAgICAgIm5lc3RlZF9uYW1lIiwgbmVzdGVkX25hbWUsCisgICAgICAgICJwYXJlbnRfbmFtZSIsIHBhcmVudF9uYW1lKTsKKyAgfQorfQorCisvLyBQcmludHMgc3RhdGVtZW50cyBzZXR0aW5nIHRoZSBtZXNzYWdlX3R5cGUgYW5kIGVudW1fdHlwZSBmaWVsZHMgaW4gdGhlCisvLyBQeXRob24gZGVzY3JpcHRvciBvYmplY3RzIHdlJ3ZlIGFscmVhZHkgb3V0cHV0IGluIHRocyBmaWxlLiAgV2UgbXVzdAorLy8gZG8gdGhpcyBpbiBhIHNlcGFyYXRlIHN0ZXAgZHVlIHRvIGNpcmN1bGFyIHJlZmVyZW5jZXMgKG90aGVyd2lzZSwgd2UnZAorLy8ganVzdCBzZXQgZXZlcnl0aGluZyBpbiB0aGUgaW5pdGlhbCBhc3NpZ25tZW50IHN0YXRlbWVudHMpLgordm9pZCBHZW5lcmF0b3I6OkZpeEZvcmVpZ25GaWVsZHNJbkRlc2NyaXB0b3JzKCkgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcigqZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSwgTlVMTCk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEFkZE1lc3NhZ2VUb0ZpbGVEZXNjcmlwdG9yKCpmaWxlXy0+bWVzc2FnZV90eXBlKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgQWRkRW51bVRvRmlsZURlc2NyaXB0b3IoKmZpbGVfLT5lbnVtX3R5cGUoaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBBZGRFeHRlbnNpb25Ub0ZpbGVEZXNjcmlwdG9yKCpmaWxlXy0+ZXh0ZW5zaW9uKGkpKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIlxuIik7Cit9CisKKy8vIFdlIG5lZWQgdG8gbm90IG9ubHkgc2V0IGFueSBuZWNlc3NhcnkgbWVzc2FnZV90eXBlIGZpZWxkcywgYnV0CisvLyBhbHNvIG5lZWQgdG8gY2FsbCBSZWdpc3RlckV4dGVuc2lvbigpIG9uIGVhY2ggbWVzc2FnZSB3ZSdyZQorLy8gZXh0ZW5kaW5nLgordm9pZCBHZW5lcmF0b3I6OkZpeEZvcmVpZ25GaWVsZHNJbkV4dGVuc2lvbnMoKSBjb25zdCB7CisgIC8vIFRvcC1sZXZlbCBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgKytpKSB7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9uKCpmaWxlXy0+ZXh0ZW5zaW9uKGkpKTsKKyAgfQorICAvLyBOZXN0ZWQgZXh0ZW5zaW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEZpeEZvcmVpZ25GaWVsZHNJbk5lc3RlZEV4dGVuc2lvbnMoKmZpbGVfLT5tZXNzYWdlX3R5cGUoaSkpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkZpeEZvcmVpZ25GaWVsZHNJbkV4dGVuc2lvbigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGV4dGVuc2lvbl9maWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soZXh0ZW5zaW9uX2ZpZWxkLmlzX2V4dGVuc2lvbigpKTsKKyAgLy8gZXh0ZW5zaW9uX3Njb3BlKCkgd2lsbCBiZSBOVUxMIGZvciB0b3AtbGV2ZWwgZXh0ZW5zaW9ucywgd2hpY2ggaXMKKyAgLy8gZXhhY3RseSB3aGF0IEZpeEZvcmVpZ25GaWVsZHNJbkZpZWxkKCkgd2FudHMuCisgIEZpeEZvcmVpZ25GaWVsZHNJbkZpZWxkKGV4dGVuc2lvbl9maWVsZC5leHRlbnNpb25fc2NvcGUoKSwgZXh0ZW5zaW9uX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiZXh0ZW5zaW9uc19ieV9uYW1lIik7CisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICAvLyBDb25mdXNpbmdseSwgZm9yIEZpZWxkRGVzY3JpcHRvcnMgdGhhdCBoYXBwZW4gdG8gYmUgZXh0ZW5zaW9ucywKKyAgLy8gY29udGFpbmluZ190eXBlKCkgbWVhbnMgImV4dGVuZGVkIHR5cGUuIgorICAvLyBPbiB0aGUgb3RoZXIgaGFuZCwgZXh0ZW5zaW9uX3Njb3BlKCkgd2lsbCBnaXZlIHVzIHdoYXQgd2Ugbm9ybWFsbHkKKyAgLy8gbWVhbiBieSBjb250YWluaW5nX3R5cGUoKS4KKyAgbVsiZXh0ZW5kZWRfbWVzc2FnZV9jbGFzcyJdID0gTW9kdWxlTGV2ZWxNZXNzYWdlTmFtZSgKKyAgICAgICpleHRlbnNpb25fZmllbGQuY29udGFpbmluZ190eXBlKCkpOworICBtWyJmaWVsZCJdID0gRmllbGRSZWZlcmVuY2luZ0V4cHJlc3Npb24oZXh0ZW5zaW9uX2ZpZWxkLmV4dGVuc2lvbl9zY29wZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImV4dGVuc2lvbnNfYnlfbmFtZSIpOworICBwcmludGVyXy0+UHJpbnQobSwgIiRleHRlbmRlZF9tZXNzYWdlX2NsYXNzJC5SZWdpc3RlckV4dGVuc2lvbigkZmllbGQkKVxuIik7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpGaXhGb3JlaWduRmllbGRzSW5OZXN0ZWRFeHRlbnNpb25zKAorICAgIGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgLy8gUmVjdXJzaXZlbHkgZml4IHVwIGV4dGVuc2lvbnMgaW4gYWxsIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEZpeEZvcmVpZ25GaWVsZHNJbk5lc3RlZEV4dGVuc2lvbnMoKmRlc2NyaXB0b3IubmVzdGVkX3R5cGUoaSkpOworICB9CisgIC8vIEZpeCB1cCBleHRlbnNpb25zIGRpcmVjdGx5IGNvbnRhaW5lZCB3aXRoaW4gdGhpcyB0eXBlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IuZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIEZpeEZvcmVpZ25GaWVsZHNJbkV4dGVuc2lvbigqZGVzY3JpcHRvci5leHRlbnNpb24oaSkpOworICB9Cit9CisKKy8vIFJldHVybnMgYSBQeXRob24gZXhwcmVzc2lvbiB0aGF0IGluc3RhbnRpYXRlcyBhIFB5dGhvbiBFbnVtVmFsdWVEZXNjcmlwdG9yCisvLyBvYmplY3QgZm9yIHRoZSBnaXZlbiBDKysgZGVzY3JpcHRvci4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludEVudW1WYWx1ZURlc2NyaXB0b3IoCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICAvLyBUT0RPKHJvYmluc29uKTogRml4IHVwIEVudW1WYWx1ZURlc2NyaXB0b3IgInR5cGUiIGZpZWxkcy4KKyAgLy8gTW9yZSBjaXJjdWxhciByZWZlcmVuY2VzLiAgOjpzaWdoOjoKKyAgc3RyaW5nIG9wdGlvbnNfc3RyaW5nOworICBkZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVUb1N0cmluZygmb3B0aW9uc19zdHJpbmcpOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bIm5hbWUiXSA9IGRlc2NyaXB0b3IubmFtZSgpOworICBtWyJpbmRleCJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLmluZGV4KCkpOworICBtWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci5udW1iZXIoKSk7CisgIG1bIm9wdGlvbnMiXSA9IE9wdGlvbnNWYWx1ZSgiRW51bVZhbHVlT3B0aW9ucyIsIG9wdGlvbnNfc3RyaW5nKTsKKyAgcHJpbnRlcl8tPlByaW50KAorICAgICAgbSwKKyAgICAgICJfZGVzY3JpcHRvci5FbnVtVmFsdWVEZXNjcmlwdG9yKFxuIgorICAgICAgIiAgbmFtZT0nJG5hbWUkJywgaW5kZXg9JGluZGV4JCwgbnVtYmVyPSRudW1iZXIkLFxuIgorICAgICAgIiAgb3B0aW9ucz0kb3B0aW9ucyQsXG4iCisgICAgICAiICB0eXBlPU5vbmUpIik7Cit9CisKKy8vIFJldHVybnMgYSBQeXRob24gZXhwcmVzc2lvbiB0aGF0IGNhbGxzIGRlc2NyaXB0b3IuX1BhcnNlT3B0aW9ucyB1c2luZworLy8gdGhlIGdpdmVuIGRlc2NyaXB0b3IgY2xhc3MgbmFtZSBhbmQgc2VyaWFsaXplZCBvcHRpb25zIHByb3RvYnVmIHN0cmluZy4KK3N0cmluZyBHZW5lcmF0b3I6Ok9wdGlvbnNWYWx1ZSgKKyAgICBjb25zdCBzdHJpbmcmIGNsYXNzX25hbWUsIGNvbnN0IHN0cmluZyYgc2VyaWFsaXplZF9vcHRpb25zKSBjb25zdCB7CisgIGlmIChzZXJpYWxpemVkX29wdGlvbnMubGVuZ3RoKCkgPT0gMCB8fCBHZW5lcmF0aW5nRGVzY3JpcHRvclByb3RvKCkpIHsKKyAgICByZXR1cm4gIk5vbmUiOworICB9IGVsc2UgeworICAgIHN0cmluZyBmdWxsX2NsYXNzX25hbWUgPSAiZGVzY3JpcHRvcl9wYjIuIiArIGNsYXNzX25hbWU7CisvLyMjIVBZMjUgICAgcmV0dXJuICJfZGVzY3JpcHRvci5fUGFyc2VPcHRpb25zKCIgKyBmdWxsX2NsYXNzX25hbWUgKyAiKCksIGInIgorLy8jIyFQWTI1ICAgICAgICArIENFc2NhcGUoc2VyaWFsaXplZF9vcHRpb25zKSsgIicpIjsKKyAgICByZXR1cm4gIl9kZXNjcmlwdG9yLl9QYXJzZU9wdGlvbnMoIiArIGZ1bGxfY2xhc3NfbmFtZSArICIoKSwgX2IoJyIgIC8vIyNQWTI1CisgICAgICAgICsgQ0VzY2FwZShzZXJpYWxpemVkX29wdGlvbnMpKyAiJykpIjsgIC8vIyNQWTI1CisgIH0KK30KKworLy8gUHJpbnRzIGFuIGV4cHJlc3Npb24gZm9yIGEgUHl0aG9uIEZpZWxkRGVzY3JpcHRvciBmb3IgfGZpZWxkfC4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludEZpZWxkRGVzY3JpcHRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLCBib29sIGlzX2V4dGVuc2lvbikgY29uc3QgeworICBzdHJpbmcgb3B0aW9uc19zdHJpbmc7CisgIGZpZWxkLm9wdGlvbnMoKS5TZXJpYWxpemVUb1N0cmluZygmb3B0aW9uc19zdHJpbmcpOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bIm5hbWUiXSA9IGZpZWxkLm5hbWUoKTsKKyAgbVsiZnVsbF9uYW1lIl0gPSBmaWVsZC5mdWxsX25hbWUoKTsKKyAgbVsiaW5kZXgiXSA9IFNpbXBsZUl0b2EoZmllbGQuaW5kZXgoKSk7CisgIG1bIm51bWJlciJdID0gU2ltcGxlSXRvYShmaWVsZC5udW1iZXIoKSk7CisgIG1bInR5cGUiXSA9IFNpbXBsZUl0b2EoZmllbGQudHlwZSgpKTsKKyAgbVsiY3BwX3R5cGUiXSA9IFNpbXBsZUl0b2EoZmllbGQuY3BwX3R5cGUoKSk7CisgIG1bImxhYmVsIl0gPSBTaW1wbGVJdG9hKGZpZWxkLmxhYmVsKCkpOworICBtWyJoYXNfZGVmYXVsdF92YWx1ZSJdID0gZmllbGQuaGFzX2RlZmF1bHRfdmFsdWUoKSA/ICJUcnVlIiA6ICJGYWxzZSI7CisgIG1bImRlZmF1bHRfdmFsdWUiXSA9IFN0cmluZ2lmeURlZmF1bHRWYWx1ZShmaWVsZCk7CisgIG1bImlzX2V4dGVuc2lvbiJdID0gaXNfZXh0ZW5zaW9uID8gIlRydWUiIDogIkZhbHNlIjsKKyAgbVsib3B0aW9ucyJdID0gT3B0aW9uc1ZhbHVlKCJGaWVsZE9wdGlvbnMiLCBvcHRpb25zX3N0cmluZyk7CisgIC8vIFdlIGFsd2F5cyBzZXQgbWVzc2FnZV90eXBlIGFuZCBlbnVtX3R5cGUgdG8gTm9uZSBhdCB0aGlzIHBvaW50LCBhbmQgdGhlbgorICAvLyB0aGVzZSBmaWVsZHMgaW4gY29ycmVjdGx5IGFmdGVyIGFsbCByZWZlcmVuY2VkIGRlc2NyaXB0b3JzIGhhdmUgYmVlbgorICAvLyBkZWZpbmVkIGFuZC9vciBpbXBvcnRlZCAoc2VlIEZpeEZvcmVpZ25GaWVsZHNJbkRlc2NyaXB0b3JzKCkpLgorICBjb25zdCBjaGFyIGZpZWxkX2Rlc2NyaXB0b3JfZGVjbFtdID0KKyAgICAiX2Rlc2NyaXB0b3IuRmllbGREZXNjcmlwdG9yKFxuIgorICAgICIgIG5hbWU9JyRuYW1lJCcsIGZ1bGxfbmFtZT0nJGZ1bGxfbmFtZSQnLCBpbmRleD0kaW5kZXgkLFxuIgorICAgICIgIG51bWJlcj0kbnVtYmVyJCwgdHlwZT0kdHlwZSQsIGNwcF90eXBlPSRjcHBfdHlwZSQsIGxhYmVsPSRsYWJlbCQsXG4iCisgICAgIiAgaGFzX2RlZmF1bHRfdmFsdWU9JGhhc19kZWZhdWx0X3ZhbHVlJCwgZGVmYXVsdF92YWx1ZT0kZGVmYXVsdF92YWx1ZSQsXG4iCisgICAgIiAgbWVzc2FnZV90eXBlPU5vbmUsIGVudW1fdHlwZT1Ob25lLCBjb250YWluaW5nX3R5cGU9Tm9uZSxcbiIKKyAgICAiICBpc19leHRlbnNpb249JGlzX2V4dGVuc2lvbiQsIGV4dGVuc2lvbl9zY29wZT1Ob25lLFxuIgorICAgICIgIG9wdGlvbnM9JG9wdGlvbnMkKSI7CisgIHByaW50ZXJfLT5QcmludChtLCBmaWVsZF9kZXNjcmlwdG9yX2RlY2wpOworfQorCisvLyBIZWxwZXIgZm9yIFByaW50e0ZpZWxkcyxFeHRlbnNpb25zfUluRGVzY3JpcHRvcigpLgordm9pZCBHZW5lcmF0b3I6OlByaW50RmllbGREZXNjcmlwdG9yc0luRGVzY3JpcHRvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yJiBtZXNzYWdlX2Rlc2NyaXB0b3IsCisgICAgYm9vbCBpc19leHRlbnNpb24sCisgICAgY29uc3Qgc3RyaW5nJiBsaXN0X3ZhcmlhYmxlX25hbWUsCisgICAgaW50IChEZXNjcmlwdG9yOjoqQ291bnRGbikoKSBjb25zdCwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIChEZXNjcmlwdG9yOjoqR2V0dGVyRm4pKGludCkgY29uc3QpIGNvbnN0IHsKKyAgcHJpbnRlcl8tPlByaW50KCIkbGlzdCQ9W1xuIiwgImxpc3QiLCBsaXN0X3ZhcmlhYmxlX25hbWUpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgKG1lc3NhZ2VfZGVzY3JpcHRvci4qQ291bnRGbikoKTsgKytpKSB7CisgICAgUHJpbnRGaWVsZERlc2NyaXB0b3IoKihtZXNzYWdlX2Rlc2NyaXB0b3IuKkdldHRlckZuKShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb24pOworICAgIHByaW50ZXJfLT5QcmludCgiLFxuIik7CisgIH0KKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCJdLFxuIik7Cit9CisKKy8vIFByaW50cyBhIHN0YXRlbWVudCBhc3NpZ25pbmcgImZpZWxkcyIgdG8gYSBsaXN0IG9mIFB5dGhvbiBGaWVsZERlc2NyaXB0b3JzLAorLy8gb25lIGZvciBlYWNoIGZpZWxkIHByZXNlbnQgaW4gbWVzc2FnZV9kZXNjcmlwdG9yLgordm9pZCBHZW5lcmF0b3I6OlByaW50RmllbGRzSW5EZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvcikgY29uc3QgeworICBjb25zdCBib29sIGlzX2V4dGVuc2lvbiA9IGZhbHNlOworICBQcmludEZpZWxkRGVzY3JpcHRvcnNJbkRlc2NyaXB0b3IoCisgICAgICBtZXNzYWdlX2Rlc2NyaXB0b3IsIGlzX2V4dGVuc2lvbiwgImZpZWxkcyIsCisgICAgICAmRGVzY3JpcHRvcjo6ZmllbGRfY291bnQsICZEZXNjcmlwdG9yOjpmaWVsZCk7Cit9CisKKy8vIFByaW50cyBhIHN0YXRlbWVudCBhc3NpZ25pbmcgImV4dGVuc2lvbnMiIHRvIGEgbGlzdCBvZiBQeXRob24KKy8vIEZpZWxkRGVzY3JpcHRvcnMsIG9uZSBmb3IgZWFjaCBleHRlbnNpb24gcHJlc2VudCBpbiBtZXNzYWdlX2Rlc2NyaXB0b3IuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRFeHRlbnNpb25zSW5EZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvcikgY29uc3QgeworICBjb25zdCBib29sIGlzX2V4dGVuc2lvbiA9IHRydWU7CisgIFByaW50RmllbGREZXNjcmlwdG9yc0luRGVzY3JpcHRvcigKKyAgICAgIG1lc3NhZ2VfZGVzY3JpcHRvciwgaXNfZXh0ZW5zaW9uLCAiZXh0ZW5zaW9ucyIsCisgICAgICAmRGVzY3JpcHRvcjo6ZXh0ZW5zaW9uX2NvdW50LCAmRGVzY3JpcHRvcjo6ZXh0ZW5zaW9uKTsKK30KKworYm9vbCBHZW5lcmF0b3I6OkdlbmVyYXRpbmdEZXNjcmlwdG9yUHJvdG8oKSBjb25zdCB7CisgIHJldHVybiBmaWxlXy0+bmFtZSgpID09ICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byI7Cit9CisKKy8vIFJldHVybnMgdGhlIHVuaXF1ZSBQeXRob24gbW9kdWxlLWxldmVsIGlkZW50aWZpZXIgZ2l2ZW4gdG8gYSBkZXNjcmlwdG9yLgorLy8gVGhpcyBuYW1lIGlzIG1vZHVsZS1xdWFsaWZpZWQgaWZmIHRoZSBnaXZlbiBkZXNjcmlwdG9yIGRlc2NyaWJlcyBhbgorLy8gZW50aXR5IHRoYXQgZG9lc24ndCBjb21lIGZyb20gdGhlIGN1cnJlbnQgZmlsZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBEZXNjcmlwdG9yVD4KK3N0cmluZyBHZW5lcmF0b3I6Ok1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoCisgICAgY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgLy8gRklYTUUocm9iaW5zb24pOgorICAvLyBXZSBjdXJyZW50bHkgZG9uJ3Qgd29ycnkgYWJvdXQgY29sbGlzaW9ucyB3aXRoIHVuZGVyc2NvcmVzIGluIHRoZSB0eXBlCisgIC8vIG5hbWVzLCBzbyB0aGVzZSB3b3VsZCBjb2xsaWRlIGluIG5hc3R5IHdheXMgaWYgZm91bmQgaW4gdGhlIHNhbWUgZmlsZToKKyAgLy8gICBPdXRlclByb3RvLlByb3RvQS5Qcm90b0IKKyAgLy8gICBPdXRlclByb3RvX1Byb3RvQS5Qcm90b0IgICMgVW5kZXJzY29yZSBpbnN0ZWFkIG9mIHBlcmlvZC4KKyAgLy8gQXMgd291bGQgdGhlc2U6CisgIC8vICAgT3V0ZXJQcm90by5Qcm90b0FfLlByb3RvQgorICAvLyAgIE91dGVyUHJvdG8uUHJvdG9BLl9Qcm90b0IgICMgTGVhZGluZyB2cy4gdHJhaWxpbmcgdW5kZXJzY29yZS4KKyAgLy8gKENvbnRyaXZlZCwgYnV0IGNlcnRhaW5seSBwb3NzaWJsZSkuCisgIC8vCisgIC8vIFRoZSBDKysgaW1wbGVtZW50YXRpb24gZG9lc24ndCBndWFyZCBhZ2FpbnN0IHRoaXMgZWl0aGVyLiAgTGVhdmluZworICAvLyBpdCBmb3Igbm93Li4uCisgIHN0cmluZyBuYW1lID0gTmFtZVByZWZpeGVkV2l0aE5lc3RlZFR5cGVzKGRlc2NyaXB0b3IsICJfIik7CisgIFVwcGVyU3RyaW5nKCZuYW1lKTsKKyAgLy8gTW9kdWxlLXByaXZhdGUgZm9yIG5vdy4gIEVhc3kgdG8gbWFrZSBwdWJsaWMgbGF0ZXI7IGFsbW9zdCBpbXBvc3NpYmxlCisgIC8vIHRvIG1ha2UgcHJpdmF0ZSBsYXRlci4KKyAgbmFtZSA9ICJfIiArIG5hbWU7CisgIC8vIFdlIG5vdyBoYXZlIHRoZSBuYW1lIHJlbGF0aXZlIHRvIGl0cyBvd24gbW9kdWxlLiAgQWxzbyBxdWFsaWZ5IHdpdGgKKyAgLy8gdGhlIG1vZHVsZSBuYW1lIGlmZiB0aGlzIGRlc2NyaXB0b3IgaXMgZnJvbSBhIGRpZmZlcmVudCAucHJvdG8gZmlsZS4KKyAgaWYgKGRlc2NyaXB0b3IuZmlsZSgpICE9IGZpbGVfKSB7CisgICAgbmFtZSA9IE1vZHVsZUFsaWFzKGRlc2NyaXB0b3IuZmlsZSgpLT5uYW1lKCkpICsgIi4iICsgbmFtZTsKKyAgfQorICByZXR1cm4gbmFtZTsKK30KKworLy8gUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBjbGFzcyBpdHNlbGYsIG5vdCB0aGUgZGVzY3JpcHRvci4KKy8vIExpa2UgTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgpLCBtb2R1bGUtcXVhbGlmaWVzIHRoZSBuYW1lIGlmZgorLy8gdGhlIGdpdmVuIGRlc2NyaXB0b3IgZGVzY3JpYmVzIGFuIGVudGl0eSB0aGF0IGRvZXNuJ3QgY29tZSBmcm9tCisvLyB0aGUgY3VycmVudCBmaWxlLgorc3RyaW5nIEdlbmVyYXRvcjo6TW9kdWxlTGV2ZWxNZXNzYWdlTmFtZShjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIHN0cmluZyBuYW1lID0gTmFtZVByZWZpeGVkV2l0aE5lc3RlZFR5cGVzKGRlc2NyaXB0b3IsICIuIik7CisgIGlmIChkZXNjcmlwdG9yLmZpbGUoKSAhPSBmaWxlXykgeworICAgIG5hbWUgPSBNb2R1bGVBbGlhcyhkZXNjcmlwdG9yLmZpbGUoKS0+bmFtZSgpKSArICIuIiArIG5hbWU7CisgIH0KKyAgcmV0dXJuIG5hbWU7Cit9CisKKy8vIFJldHVybnMgdGhlIHVuaXF1ZSBQeXRob24gbW9kdWxlLWxldmVsIGlkZW50aWZpZXIgZ2l2ZW4gdG8gYSBzZXJ2aWNlCisvLyBkZXNjcmlwdG9yLgorc3RyaW5nIEdlbmVyYXRvcjo6TW9kdWxlTGV2ZWxTZXJ2aWNlRGVzY3JpcHRvck5hbWUoCisgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgc3RyaW5nIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWUoKTsKKyAgVXBwZXJTdHJpbmcoJm5hbWUpOworICBuYW1lID0gIl8iICsgbmFtZTsKKyAgaWYgKGRlc2NyaXB0b3IuZmlsZSgpICE9IGZpbGVfKSB7CisgICAgbmFtZSA9IE1vZHVsZUFsaWFzKGRlc2NyaXB0b3IuZmlsZSgpLT5uYW1lKCkpICsgIi4iICsgbmFtZTsKKyAgfQorICByZXR1cm4gbmFtZTsKK30KKworLy8gUHJpbnRzIHN0YW5kYXJkIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBzZXJpYWxpemVkX3N0YXJ0IGFuZCBzZXJpYWxpemVkX2VuZC4KKy8vIEFyZ3M6CisvLyAgIGRlc2NyaXB0b3I6IFRoZSBjcHAgZGVzY3JpcHRvciB0byBoYXZlIGEgc2VyaWFsaXplZCByZWZlcmVuY2UuCisvLyAgIHByb3RvOiBBIHByb3RvCisvLyBFeGFtcGxlIHByaW50ZXIgb3V0cHV0OgorLy8gc2VyaWFsaXplZF9zdGFydD00MSwKKy8vIHNlcmlhbGl6ZWRfZW5kPTQzLAorLy8KK3RlbXBsYXRlIDx0eXBlbmFtZSBEZXNjcmlwdG9yVCwgdHlwZW5hbWUgRGVzY3JpcHRvclByb3RvVD4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludFNlcmlhbGl6ZWRQYkludGVydmFsKAorICAgIGNvbnN0IERlc2NyaXB0b3JUJiBkZXNjcmlwdG9yLCBEZXNjcmlwdG9yUHJvdG9UJiBwcm90bykgY29uc3QgeworICBkZXNjcmlwdG9yLkNvcHlUbygmcHJvdG8pOworICBzdHJpbmcgc3A7CisgIHByb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCZzcCk7CisgIGludCBvZmZzZXQgPSBmaWxlX2Rlc2NyaXB0b3Jfc2VyaWFsaXplZF8uZmluZChzcCk7CisgIEdPT0dMRV9DSEVDS19HRShvZmZzZXQsIDApOworCisgIHByaW50ZXJfLT5QcmludCgic2VyaWFsaXplZF9zdGFydD0kc2VyaWFsaXplZF9zdGFydCQsXG4iCisgICAgICAgICAgICAgICAgICAic2VyaWFsaXplZF9lbmQ9JHNlcmlhbGl6ZWRfZW5kJCxcbiIsCisgICAgICAgICAgICAgICAgICAic2VyaWFsaXplZF9zdGFydCIsIFNpbXBsZUl0b2Eob2Zmc2V0KSwKKyAgICAgICAgICAgICAgICAgICJzZXJpYWxpemVkX2VuZCIsIFNpbXBsZUl0b2Eob2Zmc2V0ICsgc3Auc2l6ZSgpKSk7Cit9CisKK25hbWVzcGFjZSB7Cit2b2lkIFByaW50RGVzY3JpcHRvck9wdGlvbnNGaXhpbmdDb2RlKGNvbnN0IHN0cmluZyYgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBUT0RPKHhpYW9mZW5nKTogSSBoYXZlIGFkZGVkIGEgbWV0aG9kIF9TZXRPcHRpb25zKCkgdG8gRGVzY3JpcHRvckJhc2UKKyAgLy8gaW4gcHJvdG8yIHB5dGhvbiBydW50aW1lIGJ1dCBpdCBjb3VsZG4ndCBiZSB1c2VkIGhlcmUgYmVjYXVzZSBhcHBlbmdpbmUKKyAgLy8gdXNlcyBhIHNuYXBzaG90IHZlcnNpb24gb2YgdGhlIGxpYnJhcnkgaW4gd2hpY2ggdGhlIG5ldyBtZXRob2QgaXMgbm90CisgIC8vIHlldCBwcmVzZW50LiBBZnRlciBhcHBlbmdpbmUgaGFzIHN5bmNlZCB0aGVpciBydW50aW1lIGxpYnJhcnksIHRoZSBjb2RlCisgIC8vIGJlbG93IHNob3VsZCBiZSBjbGVhbmVkIHVwIHRvIHVzZSBfU2V0T3B0aW9ucygpLgorICBwcmludGVyLT5QcmludCgKKyAgICAgICIkZGVzY3JpcHRvciQuaGFzX29wdGlvbnMgPSBUcnVlXG4iCisgICAgICAiJGRlc2NyaXB0b3IkLl9vcHRpb25zID0gJG9wdGlvbnMkXG4iLAorICAgICAgImRlc2NyaXB0b3IiLCBkZXNjcmlwdG9yLCAib3B0aW9ucyIsIG9wdGlvbnMpOworfQorfSAgLy8gbmFtZXNwYWNlCisKKy8vIFByaW50cyBleHByZXNzaW9ucyB0aGF0IHNldCB0aGUgb3B0aW9ucyBmaWVsZCBvZiBhbGwgZGVzY3JpcHRvcnMuCit2b2lkIEdlbmVyYXRvcjo6Rml4QWxsRGVzY3JpcHRvck9wdGlvbnMoKSBjb25zdCB7CisgIC8vIFByaW50cyBhbiBleHByZXNzaW9uIHRoYXQgc2V0cyB0aGUgZmlsZSBkZXNjcmlwdG9yJ3Mgb3B0aW9ucy4KKyAgc3RyaW5nIGZpbGVfb3B0aW9ucyA9IE9wdGlvbnNWYWx1ZSgKKyAgICAgICJGaWxlT3B0aW9ucyIsIGZpbGVfLT5vcHRpb25zKCkuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIGlmIChmaWxlX29wdGlvbnMgIT0gIk5vbmUiKSB7CisgICAgUHJpbnREZXNjcmlwdG9yT3B0aW9uc0ZpeGluZ0NvZGUoa0Rlc2NyaXB0b3JLZXksIGZpbGVfb3B0aW9ucywgcHJpbnRlcl8pOworICB9CisgIC8vIFByaW50cyBleHByZXNzaW9ucyB0aGF0IHNldCB0aGUgb3B0aW9ucyBmb3IgYWxsIHRvcCBsZXZlbCBlbnVtcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yJiBlbnVtX2Rlc2NyaXB0b3IgPSAqZmlsZV8tPmVudW1fdHlwZShpKTsKKyAgICBGaXhPcHRpb25zRm9yRW51bShlbnVtX2Rlc2NyaXB0b3IpOworICB9CisgIC8vIFByaW50cyBleHByZXNzaW9ucyB0aGF0IHNldCB0aGUgb3B0aW9ucyBmb3IgYWxsIHRvcCBsZXZlbCBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBmaWVsZCA9ICpmaWxlXy0+ZXh0ZW5zaW9uKGkpOworICAgIEZpeE9wdGlvbnNGb3JGaWVsZChmaWVsZCk7CisgIH0KKyAgLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZvciBhbGwgbWVzc2FnZXMsIG5lc3RlZCBlbnVtcywKKyAgLy8gbmVzdGVkIGV4dGVuc2lvbnMgYW5kIG1lc3NhZ2UgZmllbGRzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgRml4T3B0aW9uc0Zvck1lc3NhZ2UoKmZpbGVfLT5tZXNzYWdlX3R5cGUoaSkpOworICB9Cit9CisKKy8vIFByaW50cyBleHByZXNzaW9ucyB0aGF0IHNldCB0aGUgb3B0aW9ucyBmb3IgYW4gZW51bSBkZXNjcmlwdG9yIGFuZCBpdHMKKy8vIHZhbHVlIGRlc2NyaXB0b3JzLgordm9pZCBHZW5lcmF0b3I6OkZpeE9wdGlvbnNGb3JFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yJiBlbnVtX2Rlc2NyaXB0b3IpIGNvbnN0IHsKKyAgc3RyaW5nIGRlc2NyaXB0b3JfbmFtZSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZW51bV9kZXNjcmlwdG9yKTsKKyAgc3RyaW5nIGVudW1fb3B0aW9ucyA9IE9wdGlvbnNWYWx1ZSgKKyAgICAgICJFbnVtT3B0aW9ucyIsIGVudW1fZGVzY3JpcHRvci5vcHRpb25zKCkuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIGlmIChlbnVtX29wdGlvbnMgIT0gIk5vbmUiKSB7CisgICAgUHJpbnREZXNjcmlwdG9yT3B0aW9uc0ZpeGluZ0NvZGUoZGVzY3JpcHRvcl9uYW1lLCBlbnVtX29wdGlvbnMsIHByaW50ZXJfKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1fZGVzY3JpcHRvci52YWx1ZV9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yJiB2YWx1ZV9kZXNjcmlwdG9yID0gKmVudW1fZGVzY3JpcHRvci52YWx1ZShpKTsKKyAgICBzdHJpbmcgdmFsdWVfb3B0aW9ucyA9IE9wdGlvbnNWYWx1ZSgKKyAgICAgICAgIkVudW1WYWx1ZU9wdGlvbnMiLCB2YWx1ZV9kZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgICBpZiAodmFsdWVfb3B0aW9ucyAhPSAiTm9uZSIpIHsKKyAgICAgIFByaW50RGVzY3JpcHRvck9wdGlvbnNGaXhpbmdDb2RlKAorICAgICAgICAgIFN0cmluZ1ByaW50ZigiJXMudmFsdWVzX2J5X25hbWVbXCIlc1wiXSIsIGRlc2NyaXB0b3JfbmFtZS5jX3N0cigpLAorICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yLm5hbWUoKS5jX3N0cigpKSwKKyAgICAgICAgICB2YWx1ZV9vcHRpb25zLCBwcmludGVyXyk7CisgICAgfQorICB9Cit9CisKKy8vIFByaW50cyBleHByZXNzaW9ucyB0aGF0IHNldCB0aGUgb3B0aW9ucyBmb3IgZmllbGQgZGVzY3JpcHRvcnMgKGluY2x1ZGluZworLy8gZXh0ZW5zaW9ucykuCit2b2lkIEdlbmVyYXRvcjo6Rml4T3B0aW9uc0ZvckZpZWxkKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQpIGNvbnN0IHsKKyAgc3RyaW5nIGZpZWxkX29wdGlvbnMgPSBPcHRpb25zVmFsdWUoCisgICAgICAiRmllbGRPcHRpb25zIiwgZmllbGQub3B0aW9ucygpLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBpZiAoZmllbGRfb3B0aW9ucyAhPSAiTm9uZSIpIHsKKyAgICBzdHJpbmcgZmllbGRfbmFtZTsKKyAgICBpZiAoZmllbGQuaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIGlmIChmaWVsZC5leHRlbnNpb25fc2NvcGUoKSA9PSBOVUxMKSB7CisgICAgICAgIC8vIFRvcCBsZXZlbCBleHRlbnNpb25zLgorICAgICAgICBmaWVsZF9uYW1lID0gZmllbGQubmFtZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZmllbGRfbmFtZSA9IEZpZWxkUmVmZXJlbmNpbmdFeHByZXNzaW9uKAorICAgICAgICAgICAgZmllbGQuZXh0ZW5zaW9uX3Njb3BlKCksIGZpZWxkLCAiZXh0ZW5zaW9uc19ieV9uYW1lIik7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGZpZWxkX25hbWUgPSBGaWVsZFJlZmVyZW5jaW5nRXhwcmVzc2lvbigKKyAgICAgICAgICBmaWVsZC5jb250YWluaW5nX3R5cGUoKSwgZmllbGQsICJmaWVsZHNfYnlfbmFtZSIpOworICAgIH0KKyAgICBQcmludERlc2NyaXB0b3JPcHRpb25zRml4aW5nQ29kZShmaWVsZF9uYW1lLCBmaWVsZF9vcHRpb25zLCBwcmludGVyXyk7CisgIH0KK30KKworLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZvciBhIG1lc3NhZ2UgYW5kIGFsbCBpdHMgaW5uZXIKKy8vIHR5cGVzIChuZXN0ZWQgbWVzc2FnZXMsIG5lc3RlZCBlbnVtcywgZXh0ZW5zaW9ucywgZmllbGRzKS4KK3ZvaWQgR2VuZXJhdG9yOjpGaXhPcHRpb25zRm9yTWVzc2FnZShjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIC8vIE5lc3RlZCBtZXNzYWdlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEZpeE9wdGlvbnNGb3JNZXNzYWdlKCpkZXNjcmlwdG9yLm5lc3RlZF90eXBlKGkpKTsKKyAgfQorICAvLyBFbnVtcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLmVudW1fdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBGaXhPcHRpb25zRm9yRW51bSgqZGVzY3JpcHRvci5lbnVtX3R5cGUoaSkpOworICB9CisgIC8vIEZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQgPSAqZGVzY3JpcHRvci5maWVsZChpKTsKKyAgICBGaXhPcHRpb25zRm9yRmllbGQoZmllbGQpOworICB9CisgIC8vIEV4dGVuc2lvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5leHRlbnNpb25fY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBmaWVsZCA9ICpkZXNjcmlwdG9yLmV4dGVuc2lvbihpKTsKKyAgICBGaXhPcHRpb25zRm9yRmllbGQoZmllbGQpOworICB9CisgIC8vIE1lc3NhZ2Ugb3B0aW9uIGZvciB0aGlzIG1lc3NhZ2UuCisgIHN0cmluZyBtZXNzYWdlX29wdGlvbnMgPSBPcHRpb25zVmFsdWUoCisgICAgICAiTWVzc2FnZU9wdGlvbnMiLCBkZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgaWYgKG1lc3NhZ2Vfb3B0aW9ucyAhPSAiTm9uZSIpIHsKKyAgICBzdHJpbmcgZGVzY3JpcHRvcl9uYW1lID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZShkZXNjcmlwdG9yKTsKKyAgICBQcmludERlc2NyaXB0b3JPcHRpb25zRml4aW5nQ29kZShkZXNjcmlwdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZV9vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZXJfKTsKKyAgfQorfQorCisvLyBJZiBhIGRlcGVuZGVuY3kgZm9yd2FyZHMgb3RoZXIgZmlsZXMgdGhyb3VnaCBwdWJsaWMgZGVwZW5kZW5jaWVzLCBsZXQncworLy8gY29weSBvdmVyIHRoZSBjb3JyZXNwb25kaW5nIG1vZHVsZSBhbGlhc2VzLgordm9pZCBHZW5lcmF0b3I6OkNvcHlQdWJsaWNEZXBlbmRlbmNpZXNBbGlhc2VzKAorICAgIGNvbnN0IHN0cmluZyYgY29weV9mcm9tLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7ICsraSkgeworICAgIHN0cmluZyBtb2R1bGVfYWxpYXMgPSBNb2R1bGVBbGlhcyhmaWxlLT5wdWJsaWNfZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIiRhbGlhcyQgPSAkY29weV9mcm9tJC4kYWxpYXMkXG4iLCAiYWxpYXMiLCBtb2R1bGVfYWxpYXMsCisgICAgICAgICAgICAgICAgICAgICJjb3B5X2Zyb20iLCBjb3B5X2Zyb20pOworICAgIENvcHlQdWJsaWNEZXBlbmRlbmNpZXNBbGlhc2VzKGNvcHlfZnJvbSwgZmlsZS0+cHVibGljX2RlcGVuZGVuY3koaSkpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRkYWM2MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDE3MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogcm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbikKKy8vCisvLyBHZW5lcmF0ZXMgUHl0aG9uIGNvZGUgZm9yIGEgZ2l2ZW4gLnByb3RvIGZpbGUuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1BZVEhPTl9HRU5FUkFUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9QWVRIT05fR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIERlc2NyaXB0b3I7CitjbGFzcyBFbnVtRGVzY3JpcHRvcjsKK2NsYXNzIEVudW1WYWx1ZURlc2NyaXB0b3I7CitjbGFzcyBGaWVsZERlc2NyaXB0b3I7CitjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcjsKKworbmFtZXNwYWNlIGlvIHsgY2xhc3MgUHJpbnRlcjsgfQorCituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIHB5dGhvbiB7CisKKy8vIENvZGVHZW5lcmF0b3IgaW1wbGVtZW50YXRpb24gZm9yIGdlbmVyYXRlZCBQeXRob24gcHJvdG9jb2wgYnVmZmVyIGNsYXNzZXMuCisvLyBJZiB5b3UgY3JlYXRlIHlvdXIgb3duIHByb3RvY29sIGNvbXBpbGVyIGJpbmFyeSBhbmQgeW91IHdhbnQgaXQgdG8gc3VwcG9ydAorLy8gUHl0aG9uIG91dHB1dCwgeW91IGNhbiBkbyBzbyBieSByZWdpc3RlcmluZyBhbiBpbnN0YW5jZSBvZiB0aGlzCisvLyBDb2RlR2VuZXJhdG9yIHdpdGggdGhlIENvbW1hbmRMaW5lSW50ZXJmYWNlIGluIHlvdXIgbWFpbigpIGZ1bmN0aW9uLgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBHZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBHZW5lcmF0b3IoKTsKKyAgdmlydHVhbCB+R2VuZXJhdG9yKCk7CisKKyAgLy8gQ29kZUdlbmVyYXRvciBtZXRob2RzLgorICB2aXJ0dWFsIGJvb2wgR2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3Q7CisKKyBwcml2YXRlOgorICB2b2lkIFByaW50SW1wb3J0cygpIGNvbnN0OworICB2b2lkIFByaW50RmlsZURlc2NyaXB0b3IoKSBjb25zdDsKKyAgdm9pZCBQcmludFRvcExldmVsRW51bXMoKSBjb25zdDsKKyAgdm9pZCBQcmludEFsbE5lc3RlZEVudW1zSW5GaWxlKCkgY29uc3Q7CisgIHZvaWQgUHJpbnROZXN0ZWRFbnVtcyhjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBQcmludEVudW0oY29uc3QgRW51bURlc2NyaXB0b3ImIGVudW1fZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdm9pZCBQcmludFRvcExldmVsRXh0ZW5zaW9ucygpIGNvbnN0OworCisgIHZvaWQgUHJpbnRGaWVsZERlc2NyaXB0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLCBib29sIGlzX2V4dGVuc2lvbikgY29uc3Q7CisgIHZvaWQgUHJpbnRGaWVsZERlc2NyaXB0b3JzSW5EZXNjcmlwdG9yKAorICAgICAgY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yLAorICAgICAgYm9vbCBpc19leHRlbnNpb24sCisgICAgICBjb25zdCBzdHJpbmcmIGxpc3RfdmFyaWFibGVfbmFtZSwKKyAgICAgIGludCAoRGVzY3JpcHRvcjo6KkNvdW50Rm4pKCkgY29uc3QsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIChEZXNjcmlwdG9yOjoqR2V0dGVyRm4pKGludCkgY29uc3QpIGNvbnN0OworICB2b2lkIFByaW50RmllbGRzSW5EZXNjcmlwdG9yKGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvcikgY29uc3Q7CisgIHZvaWQgUHJpbnRFeHRlbnNpb25zSW5EZXNjcmlwdG9yKGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvcikgY29uc3Q7CisgIHZvaWQgUHJpbnRNZXNzYWdlRGVzY3JpcHRvcnMoKSBjb25zdDsKKyAgdm9pZCBQcmludERlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBQcmludE5lc3RlZERlc2NyaXB0b3JzKGNvbnN0IERlc2NyaXB0b3ImIGNvbnRhaW5pbmdfZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdm9pZCBQcmludE1lc3NhZ2VzKCkgY29uc3Q7CisgIHZvaWQgUHJpbnRNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvciwgY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiB0b19yZWdpc3RlcikgY29uc3Q7CisgIHZvaWQgUHJpbnROZXN0ZWRNZXNzYWdlcyhjb25zdCBEZXNjcmlwdG9yJiBjb250YWluaW5nX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiB0b19yZWdpc3RlcikgY29uc3Q7CisKKyAgdm9pZCBGaXhGb3JlaWduRmllbGRzSW5EZXNjcmlwdG9ycygpIGNvbnN0OworICB2b2lkIEZpeEZvcmVpZ25GaWVsZHNJbkRlc2NyaXB0b3IoCisgICAgICBjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yLAorICAgICAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ19kZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBGaXhGb3JlaWduRmllbGRzSW5GaWVsZChjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHB5dGhvbl9kaWN0X25hbWUpIGNvbnN0OworICB2b2lkIEFkZE1lc3NhZ2VUb0ZpbGVEZXNjcmlwdG9yKGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIEFkZEVudW1Ub0ZpbGVEZXNjcmlwdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBBZGRFeHRlbnNpb25Ub0ZpbGVEZXNjcmlwdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisgIHN0cmluZyBGaWVsZFJlZmVyZW5jaW5nRXhwcmVzc2lvbihjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBweXRob25fZGljdF9uYW1lKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIERlc2NyaXB0b3JUPgorICB2b2lkIEZpeENvbnRhaW5pbmdUeXBlSW5EZXNjcmlwdG9yKAorICAgICAgY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IsCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX2Rlc2NyaXB0b3IpIGNvbnN0OworCisgIHZvaWQgRml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9ucygpIGNvbnN0OworICB2b2lkIEZpeEZvcmVpZ25GaWVsZHNJbkV4dGVuc2lvbigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZXh0ZW5zaW9uX2ZpZWxkKSBjb25zdDsKKyAgdm9pZCBGaXhGb3JlaWduRmllbGRzSW5OZXN0ZWRFeHRlbnNpb25zKGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworCisgIHZvaWQgUHJpbnRTZXJ2aWNlcygpIGNvbnN0OworICB2b2lkIFByaW50U2VydmljZURlc2NyaXB0b3IoY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIFByaW50U2VydmljZUNsYXNzKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBQcmludFNlcnZpY2VTdHViKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBQcmludERlc2NyaXB0b3JLZXlBbmRNb2R1bGVOYW1lKAorICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IDsKKworICB2b2lkIFByaW50RW51bVZhbHVlRGVzY3JpcHRvcihjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgc3RyaW5nIE9wdGlvbnNWYWx1ZShjb25zdCBzdHJpbmcmIGNsYXNzX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBzZXJpYWxpemVkX29wdGlvbnMpIGNvbnN0OworICBib29sIEdlbmVyYXRpbmdEZXNjcmlwdG9yUHJvdG8oKSBjb25zdDsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclQ+CisgIHN0cmluZyBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGNvbnN0IERlc2NyaXB0b3JUJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgc3RyaW5nIE1vZHVsZUxldmVsTWVzc2FnZU5hbWUoY29uc3QgRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisgIHN0cmluZyBNb2R1bGVMZXZlbFNlcnZpY2VEZXNjcmlwdG9yTmFtZSgKKyAgICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclQsIHR5cGVuYW1lIERlc2NyaXB0b3JQcm90b1Q+CisgIHZvaWQgUHJpbnRTZXJpYWxpemVkUGJJbnRlcnZhbCgKKyAgICAgIGNvbnN0IERlc2NyaXB0b3JUJiBkZXNjcmlwdG9yLCBEZXNjcmlwdG9yUHJvdG9UJiBwcm90bykgY29uc3Q7CisKKyAgdm9pZCBGaXhBbGxEZXNjcmlwdG9yT3B0aW9ucygpIGNvbnN0OworICB2b2lkIEZpeE9wdGlvbnNGb3JGaWVsZChjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkKSBjb25zdDsKKyAgdm9pZCBGaXhPcHRpb25zRm9yRW51bShjb25zdCBFbnVtRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisgIHZvaWQgRml4T3B0aW9uc0Zvck1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdm9pZCBDb3B5UHVibGljRGVwZW5kZW5jaWVzQWxpYXNlcygKKyAgICAgIGNvbnN0IHN0cmluZyYgY29weV9mcm9tLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgY29uc3Q7CisKKyAgLy8gVmVyeSBjb2Fyc2UtZ3JhaW5lZCBsb2NrIHRvIGVuc3VyZSB0aGF0IEdlbmVyYXRlKCkgaXMgcmVlbnRyYW50LgorICAvLyBHdWFyZHMgZmlsZV8sIHByaW50ZXJfIGFuZCBmaWxlX2Rlc2NyaXB0b3Jfc2VyaWFsaXplZF8uCisgIG11dGFibGUgTXV0ZXggbXV0ZXhfOworICBtdXRhYmxlIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsgIC8vIFNldCBpbiBHZW5lcmF0ZSgpLiAgVW5kZXIgbXV0ZXhfLgorICBtdXRhYmxlIHN0cmluZyBmaWxlX2Rlc2NyaXB0b3Jfc2VyaWFsaXplZF87CisgIG11dGFibGUgaW86OlByaW50ZXIqIHByaW50ZXJfOyAgLy8gU2V0IGluIEdlbmVyYXRlKCkuICBVbmRlciBtdXRleF8uCisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHl0aG9uCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9QWVRIT05fR0VORVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX3BsdWdpbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9wbHVnaW5fdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTgyYmJhZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9wbHVnaW5fdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMjEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gVE9ETyhrZW50b24pOiAgU2hhcmUgY29kZSB3aXRoIHRoZSB2ZXJzaW9ucyBvZiB0aGlzIHRlc3QgaW4gb3RoZXIgbGFuZ3VhZ2VzPworLy8gICBJdCBzZWVtZWQgbGlrZSBwYXJhbWV0ZXJpemluZyBpdCB3b3VsZCBhZGQgbW9yZSBjb21wbGV4aXR5IHRoYW4gaXQgaXMKKy8vICAgd29ydGguCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBweXRob24geworbmFtZXNwYWNlIHsKKworY2xhc3MgVGVzdEdlbmVyYXRvciA6IHB1YmxpYyBDb2RlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIFRlc3RHZW5lcmF0b3IoKSB7fQorICB+VGVzdEdlbmVyYXRvcigpIHt9CisKKyAgdmlydHVhbCBib29sIEdlbmVyYXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3QgeworICAgIFRyeUluc2VydCgidGVzdF9wYjIucHkiLCAiaW1wb3J0cyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdF9wYjIucHkiLCAibW9kdWxlX3Njb3BlIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0X3BiMi5weSIsICJjbGFzc19zY29wZTpmb28uQmFyIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0X3BiMi5weSIsICJjbGFzc19zY29wZTpmb28uQmFyLkJheiIsIGNvbnRleHQpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgdm9pZCBUcnlJbnNlcnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQsCisgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQpIGNvbnN0IHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICBjb250ZXh0LT5PcGVuRm9ySW5zZXJ0KGZpbGVuYW1lLCBpbnNlcnRpb25fcG9pbnQpKTsKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBwcmludGVyLlByaW50KCIvLyBpbnNlcnRlZCAkbmFtZSRcbiIsICJuYW1lIiwgaW5zZXJ0aW9uX3BvaW50KTsKKyAgfQorfTsKKworLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgYWxsIHRoZSBleHBlY3RlZCBpbnNlcnRpb24gcG9pbnRzIGV4aXN0LiAgSXQgZG9lcworLy8gbm90IHZlcmlmeSB0aGF0IHRoZXkgYXJlIGNvcnJlY3RseS1wbGFjZWQ7IHRoYXQgd291bGQgcmVxdWlyZSBhY3R1YWxseQorLy8gY29tcGlsaW5nIHRoZSBvdXRwdXQgd2hpY2ggaXMgYSBiaXQgbW9yZSB0aGFuIEkgY2FyZSB0byBkbyBmb3IgdGhpcyB0ZXN0LgorVEVTVChQeXRob25QbHVnaW5UZXN0LCBQbHVnaW5UZXN0KSB7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhUZXN0VGVtcERpcigpICsgIi90ZXN0LnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYWNrYWdlIGZvbztcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgbWVzc2FnZSBCYXoge31cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpKTsKKworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29tbWFuZExpbmVJbnRlcmZhY2UgY2xpOworICBjbGkuU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUodHJ1ZSk7CisKKyAgcHl0aG9uOjpHZW5lcmF0b3IgcHl0aG9uX2dlbmVyYXRvcjsKKyAgVGVzdEdlbmVyYXRvciB0ZXN0X2dlbmVyYXRvcjsKKyAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLXB5dGhvbl9vdXQiLCAmcHl0aG9uX2dlbmVyYXRvciwgIiIpOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tdGVzdF9vdXQiLCAmdGVzdF9nZW5lcmF0b3IsICIiKTsKKworICBzdHJpbmcgcHJvdG9fcGF0aCA9ICItSSIgKyBUZXN0VGVtcERpcigpOworICBzdHJpbmcgcHl0aG9uX291dCA9ICItLXB5dGhvbl9vdXQ9IiArIFRlc3RUZW1wRGlyKCk7CisgIHN0cmluZyB0ZXN0X291dCA9ICItLXRlc3Rfb3V0PSIgKyBUZXN0VGVtcERpcigpOworCisgIGNvbnN0IGNoYXIqIGFyZ3ZbXSA9IHsKKyAgICAicHJvdG9jIiwKKyAgICBwcm90b19wYXRoLmNfc3RyKCksCisgICAgcHl0aG9uX291dC5jX3N0cigpLAorICAgIHRlc3Rfb3V0LmNfc3RyKCksCisgICAgInRlc3QucHJvdG8iCisgIH07CisKKyAgRVhQRUNUX0VRKDAsIGNsaS5SdW4oNSwgYXJndikpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTliNjgzNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDM5MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvci5oPgorCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6c2NvcGVkX3B0cjsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBydWJ5IHsKKworLy8gRm9yd2FyZCBkZWNscy4KK3N0ZDo6c3RyaW5nIEludFRvU3RyaW5nKHVpbnQzMiB2YWx1ZSk7CitzdGQ6OnN0cmluZyBTdHJpcERvdFByb3RvKGNvbnN0IHN0ZDo6c3RyaW5nJiBwcm90b19maWxlKTsKK3N0ZDo6c3RyaW5nIExhYmVsRm9yRmllbGQoZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CitzdGQ6OnN0cmluZyBUeXBlTmFtZShnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKK3ZvaWQgR2VuZXJhdGVNZXNzYWdlKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcik7Cit2b2lkIEdlbmVyYXRlRW51bShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogZW4sCisgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcik7Cit2b2lkIEdlbmVyYXRlTWVzc2FnZUFzc2lnbm1lbnQoCisgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHByZWZpeCwKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpQcmludGVyKiBwcmludGVyKTsKK3ZvaWQgR2VuZXJhdGVFbnVtQXNzaWdubWVudCgKKyAgICBjb25zdCBzdGQ6OnN0cmluZyYgcHJlZml4LAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBlbiwKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcik7CisKK3N0ZDo6c3RyaW5nIEludFRvU3RyaW5nKHVpbnQzMiB2YWx1ZSkgeworICBzdGQ6Om9zdHJpbmdzdHJlYW0gb3M7CisgIG9zIDw8IHZhbHVlOworICByZXR1cm4gb3Muc3RyKCk7Cit9CisKK3N0ZDo6c3RyaW5nIFN0cmlwRG90UHJvdG8oY29uc3Qgc3RkOjpzdHJpbmcmIHByb3RvX2ZpbGUpIHsKKyAgaW50IGxhc3RpbmRleCA9IHByb3RvX2ZpbGUuZmluZF9sYXN0X29mKCIuIik7CisgIHJldHVybiBwcm90b19maWxlLnN1YnN0cigwLCBsYXN0aW5kZXgpOworfQorCitzdGQ6OnN0cmluZyBMYWJlbEZvckZpZWxkKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3dpdGNoIChmaWVsZC0+bGFiZWwoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTDogcmV0dXJuICJvcHRpb25hbCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUVVJUkVEOiByZXR1cm4gInJlcXVpcmVkIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQ6IHJldHVybiAicmVwZWF0ZWQiOworICAgIGRlZmF1bHQ6IGFzc2VydChmYWxzZSk7IHJldHVybiAiIjsKKyAgfQorfQorCitzdGQ6OnN0cmluZyBUeXBlTmFtZShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjogcmV0dXJuICJpbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6IHJldHVybiAiaW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjogcmV0dXJuICJ1aW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDogcmV0dXJuICJ1aW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRTogcmV0dXJuICJkb3VibGUiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOiByZXR1cm4gImZsb2F0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOiByZXR1cm4gImJvb2wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06IHJldHVybiAiZW51bSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiByZXR1cm4gInN0cmluZyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRTogcmV0dXJuICJtZXNzYWdlIjsKKyAgICBkZWZhdWx0OiBhc3NlcnQoZmFsc2UpOyByZXR1cm4gIiI7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZUZpZWxkKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKworICBpZiAoZmllbGQtPmlzX21hcCgpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZmllbGQgPQorICAgICAgICBmaWVsZC0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TnVtYmVyKDEpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZmllbGQgPQorICAgICAgICBmaWVsZC0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TnVtYmVyKDIpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAibWFwIDokbmFtZSQsIDoka2V5X3R5cGUkLCA6JHZhbHVlX3R5cGUkLCAkbnVtYmVyJCIsCisgICAgICAibmFtZSIsIGZpZWxkLT5uYW1lKCksCisgICAgICAia2V5X3R5cGUiLCBUeXBlTmFtZShrZXlfZmllbGQpLAorICAgICAgInZhbHVlX3R5cGUiLCBUeXBlTmFtZSh2YWx1ZV9maWVsZCksCisgICAgICAibnVtYmVyIiwgSW50VG9TdHJpbmcoZmllbGQtPm51bWJlcigpKSk7CisKKyAgICBpZiAodmFsdWVfZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLCBcIiRzdWJ0eXBlJFwiXG4iLAorICAgICAgICAic3VidHlwZSIsIHZhbHVlX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICAgIH0gZWxzZSBpZiAodmFsdWVfZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0pIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLCBcIiRzdWJ0eXBlJFwiXG4iLAorICAgICAgICAic3VidHlwZSIsIHZhbHVlX2ZpZWxkLT5lbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIkbGFiZWwkIDokbmFtZSQsICIsCisgICAgICAibGFiZWwiLCBMYWJlbEZvckZpZWxkKGZpZWxkKSwKKyAgICAgICJuYW1lIiwgZmllbGQtPm5hbWUoKSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOiR0eXBlJCwgJG51bWJlciQiLAorICAgICAgInR5cGUiLCBUeXBlTmFtZShmaWVsZCksCisgICAgICAibnVtYmVyIiwgSW50VG9TdHJpbmcoZmllbGQtPm51bWJlcigpKSk7CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLCBcIiRzdWJ0eXBlJFwiXG4iLAorICAgICAgICJzdWJ0eXBlIiwgZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5mdWxsX25hbWUoKSk7CisgICAgfSBlbHNlIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIsIFwiJHN1YnR5cGUkXCJcbiIsCisgICAgICAgICJzdWJ0eXBlIiwgZmllbGQtPmVudW1fdHlwZSgpLT5mdWxsX25hbWUoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIEdlbmVyYXRlT25lb2YoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yKiBvbmVvZiwKKyAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICJvbmVvZiA6JG5hbWUkIGRvXG4iLAorICAgICAgIm5hbWUiLCBvbmVvZi0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvbmVvZi0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG9uZW9mLT5maWVsZChpKTsKKyAgICBHZW5lcmF0ZUZpZWxkKGZpZWxkLCBwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoImVuZFxuIik7Cit9CisKK3ZvaWQgR2VuZXJhdGVNZXNzYWdlKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworCisgIC8vIERvbid0IGdlbmVyYXRlIE1hcEVudHJ5IG1lc3NhZ2VzIC0tIHdlIHVzZSB0aGUgUnVieSBleHRlbnNpb24ncyBuYXRpdmUKKyAgLy8gc3VwcG9ydCBmb3IgbWFwIGZpZWxkcyBpbnN0ZWFkLgorICBpZiAobWVzc2FnZS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImFkZF9tZXNzYWdlIFwiJG5hbWUkXCIgZG9cbiIsCisgICAgIm5hbWUiLCBtZXNzYWdlLT5mdWxsX25hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG1lc3NhZ2UtPmZpZWxkKGkpOworICAgIGlmICghZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgR2VuZXJhdGVGaWVsZChmaWVsZCwgcHJpbnRlcik7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YgPSBtZXNzYWdlLT5vbmVvZl9kZWNsKGkpOworICAgIEdlbmVyYXRlT25lb2Yob25lb2YsIHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgiZW5kXG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlTWVzc2FnZShtZXNzYWdlLT5uZXN0ZWRfdHlwZShpKSwgcHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVFbnVtKG1lc3NhZ2UtPmVudW1fdHlwZShpKSwgcHJpbnRlcik7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZUVudW0oY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIGVuLAorICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImFkZF9lbnVtIFwiJG5hbWUkXCIgZG9cbiIsCisgICAgIm5hbWUiLCBlbi0+ZnVsbF9uYW1lKCkpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGVuLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSA9IGVuLT52YWx1ZShpKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ2YWx1ZSA6JG5hbWUkLCAkbnVtYmVyJFxuIiwKKyAgICAgICJuYW1lIiwgdmFsdWUtPm5hbWUoKSwKKyAgICAgICJudW1iZXIiLCBJbnRUb1N0cmluZyh2YWx1ZS0+bnVtYmVyKCkpKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImVuZFxuIik7Cit9CisKKy8vIE1vZHVsZSBuYW1lcywgY2xhc3MgbmFtZXMsIGFuZCBlbnVtIHZhbHVlIG5hbWVzIG5lZWQgdG8gYmUgUnVieSBjb25zdGFudHMsCisvLyB3aGljaCBtdXN0IHN0YXJ0IHdpdGggYSBjYXBpdGFsIGxldHRlci4KK3N0ZDo6c3RyaW5nIFJ1YmlmeUNvbnN0YW50KGNvbnN0IHN0ZDo6c3RyaW5nJiBuYW1lKSB7CisgIHN0ZDo6c3RyaW5nIHJldCA9IG5hbWU7CisgIGlmICghcmV0LmVtcHR5KCkpIHsKKyAgICBpZiAocmV0WzBdID49ICdhJyAmJiByZXRbMF0gPD0gJ3onKSB7CisgICAgICAvLyBJZiBpdCBzdGFydHMgd2l0aCBhIGxvd2VyY2FzZSBsZXR0ZXIsIGNhcGl0YWxpemUgaXQuCisgICAgICByZXRbMF0gPSByZXRbMF0gLSAnYScgKyAnQSc7CisgICAgfSBlbHNlIGlmIChyZXRbMF0gPCAnQScgfHwgcmV0WzBdID4gJ1onKSB7CisgICAgICAvLyBPdGhlcndpc2UgKGUuZy4gaWYgaXQgYmVnaW5zIHdpdGggYW4gdW5kZXJzY29yZSksIHdlIG5lZWQgdG8gY29tZSB1cAorICAgICAgLy8gd2l0aCBzb21lIHByZWZpeCB0aGF0IHN0YXJ0cyB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuIFdlIGNvdWxkIGJlIHNtYXJ0ZXIKKyAgICAgIC8vIGhlcmUsIGUuZy4gdHJ5IHRvIHN0cmlwIGxlYWRpbmcgdW5kZXJzY29yZXMsIGJ1dCB0aGlzIG1heSBjYXVzZSBvdGhlcgorICAgICAgLy8gcHJvYmxlbXMgaWYgdGhlIHVzZXIgcmVhbGx5IGludGVuZGVkIHRoZSBuYW1lLiBTbyBsZXQncyBqdXN0IHByZXBlbmQgYQorICAgICAgLy8gd2VsbC1rbm93biBzdWZmaXguCisgICAgICByZXQgPSAiUEJfIiArIHJldDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJldDsKK30KKwordm9pZCBHZW5lcmF0ZU1lc3NhZ2VBc3NpZ25tZW50KAorICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBwcmVmaXgsCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogbWVzc2FnZSwKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworCisgIC8vIERvbid0IGdlbmVyYXRlIE1hcEVudHJ5IG1lc3NhZ2VzIC0tIHdlIHVzZSB0aGUgUnVieSBleHRlbnNpb24ncyBuYXRpdmUKKyAgLy8gc3VwcG9ydCBmb3IgbWFwIGZpZWxkcyBpbnN0ZWFkLgorICBpZiAobWVzc2FnZS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRwcmVmaXgkJG5hbWUkID0gIiwKKyAgICAicHJlZml4IiwgcHJlZml4LAorICAgICJuYW1lIiwgUnViaWZ5Q29uc3RhbnQobWVzc2FnZS0+bmFtZSgpKSk7CisgIHByaW50ZXItPlByaW50KAorICAgICJHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5nZW5lcmF0ZWRfcG9vbC4iCisgICAgImxvb2t1cChcIiRmdWxsX25hbWUkXCIpLm1zZ2NsYXNzXG4iLAorICAgICJmdWxsX25hbWUiLCBtZXNzYWdlLT5mdWxsX25hbWUoKSk7CisKKyAgc3RkOjpzdHJpbmcgbmVzdGVkX3ByZWZpeCA9IHByZWZpeCArIG1lc3NhZ2UtPm5hbWUoKSArICI6OiI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVNZXNzYWdlQXNzaWdubWVudChuZXN0ZWRfcHJlZml4LCBtZXNzYWdlLT5uZXN0ZWRfdHlwZShpKSwgcHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVFbnVtQXNzaWdubWVudChuZXN0ZWRfcHJlZml4LCBtZXNzYWdlLT5lbnVtX3R5cGUoaSksIHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVFbnVtQXNzaWdubWVudCgKKyAgICBjb25zdCBzdGQ6OnN0cmluZyYgcHJlZml4LAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBlbiwKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiJHByZWZpeCQkbmFtZSQgPSAiLAorICAgICJwcmVmaXgiLCBwcmVmaXgsCisgICAgIm5hbWUiLCBSdWJpZnlDb25zdGFudChlbi0+bmFtZSgpKSk7CisgIHByaW50ZXItPlByaW50KAorICAgICJHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5nZW5lcmF0ZWRfcG9vbC4iCisgICAgImxvb2t1cChcIiRmdWxsX25hbWUkXCIpLmVudW1tb2R1bGVcbiIsCisgICAgImZ1bGxfbmFtZSIsIGVuLT5mdWxsX25hbWUoKSk7Cit9CisKK2ludCBHZW5lcmF0ZVBhY2thZ2VNb2R1bGVzKAorICAgIHN0ZDo6c3RyaW5nIHBhY2thZ2VfbmFtZSwKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpbnQgbGV2ZWxzID0gMDsKKyAgd2hpbGUgKCFwYWNrYWdlX25hbWUuZW1wdHkoKSkgeworICAgIHNpemVfdCBkb3RfaW5kZXggPSBwYWNrYWdlX25hbWUuZmluZCgiLiIpOworICAgIHN0cmluZyBjb21wb25lbnQ7CisgICAgaWYgKGRvdF9pbmRleCA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIGNvbXBvbmVudCA9IHBhY2thZ2VfbmFtZTsKKyAgICAgIHBhY2thZ2VfbmFtZSA9ICIiOworICAgIH0gZWxzZSB7CisgICAgICBjb21wb25lbnQgPSBwYWNrYWdlX25hbWUuc3Vic3RyKDAsIGRvdF9pbmRleCk7CisgICAgICBwYWNrYWdlX25hbWUgPSBwYWNrYWdlX25hbWUuc3Vic3RyKGRvdF9pbmRleCArIDEpOworICAgIH0KKyAgICBjb21wb25lbnQgPSBSdWJpZnlDb25zdGFudChjb21wb25lbnQpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIm1vZHVsZSAkbmFtZSRcbiIsCisgICAgICAibmFtZSIsIGNvbXBvbmVudCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgbGV2ZWxzKys7CisgIH0KKyAgcmV0dXJuIGxldmVsczsKK30KKwordm9pZCBFbmRQYWNrYWdlTW9kdWxlcygKKyAgICBpbnQgbGV2ZWxzLAorICAgIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHdoaWxlIChsZXZlbHMgPiAwKSB7CisgICAgbGV2ZWxzLS07CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImVuZFxuIik7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZUZpbGUoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiIyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICIjIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICJcbiIsCisgICAgImZpbGVuYW1lIiwgZmlsZS0+bmFtZSgpKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicmVxdWlyZSAnZ29vZ2xlL3Byb3RvYnVmJ1xuXG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUgPSBmaWxlLT5kZXBlbmRlbmN5KGkpLT5uYW1lKCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicmVxdWlyZSAnJG5hbWUkJ1xuIiwgIm5hbWUiLCBTdHJpcERvdFByb3RvKG5hbWUpKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5nZW5lcmF0ZWRfcG9vbC5idWlsZCBkb1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZU1lc3NhZ2UoZmlsZS0+bWVzc2FnZV90eXBlKGkpLCBwcmludGVyKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZUVudW0oZmlsZS0+ZW51bV90eXBlKGkpLCBwcmludGVyKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJlbmRcblxuIik7CisKKyAgaW50IGxldmVscyA9IEdlbmVyYXRlUGFja2FnZU1vZHVsZXMoZmlsZS0+cGFja2FnZSgpLCBwcmludGVyKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVNZXNzYWdlQXNzaWdubWVudCgiIiwgZmlsZS0+bWVzc2FnZV90eXBlKGkpLCBwcmludGVyKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZUVudW1Bc3NpZ25tZW50KCIiLCBmaWxlLT5lbnVtX3R5cGUoaSksIHByaW50ZXIpOworICB9CisgIEVuZFBhY2thZ2VNb2R1bGVzKGxldmVscywgcHJpbnRlcik7Cit9CisKK2Jvb2wgR2VuZXJhdG9yOjpHZW5lcmF0ZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCwKKyAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisKKyAgaWYgKGZpbGUtPnN5bnRheCgpICE9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zKSB7CisgICAgKmVycm9yID0KKyAgICAgICAgIkNhbiBvbmx5IGdlbmVyYXRlIFJ1YnkgY29kZSBmb3IgcHJvdG8zIC5wcm90byBmaWxlcy5cbiIKKyAgICAgICAgIlBsZWFzZSBhZGQgJ3N5bnRheCA9IFwicHJvdG8zXCI7JyB0byB0aGUgdG9wIG9mIHlvdXIgLnByb3RvIGZpbGUuXG4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHN0ZDo6c3RyaW5nIGZpbGVuYW1lID0KKyAgICAgIFN0cmlwRG90UHJvdG8oZmlsZS0+bmFtZSgpKSArICIucmIiOworICBzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgZ2VuZXJhdG9yX2NvbnRleHQtPk9wZW4oZmlsZW5hbWUpKTsKKyAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisKKyAgR2VuZXJhdGVGaWxlKGZpbGUsICZwcmludGVyKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHJ1YnkKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1NTU1YzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDU4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUlVCWV9HRU5FUkFUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9SVUJZX0dFTkVSQVRPUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIHJ1YnkgeworCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIEdlbmVyYXRvcgorICAgIDogcHVibGljIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yIHsKKyAgdmlydHVhbCBib29sIEdlbmVyYXRlKAorICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3Q7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcnVieQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUlVCWV9HRU5FUkFUT1JfSF9fCisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvcl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzVjYTY5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTE5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1lbW9yeT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgcnVieSB7CituYW1lc3BhY2UgeworCitzdHJpbmcgRmluZFJ1YnlUZXN0RGlyKCkgeworICAvLyBJbnNwaXJlZCBieSBUZXN0U291cmNlRGlyKCkgaW4gc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuY2MuCisgIHN0cmluZyBwcmVmaXggPSAiLiI7CisgIHdoaWxlICghRmlsZTo6RXhpc3RzKHByZWZpeCArICIvcnVieS90ZXN0cyIpKSB7CisgICAgaWYgKCFGaWxlOjpFeGlzdHMocHJlZml4KSkgeworICAgICAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICAgICAgICA8PCAiQ291bGQgbm90IGZpbmQgUnVieSB0ZXN0IGRpcmVjdG9yeS4gUGxlYXNlIHJ1biB0ZXN0cyBmcm9tICIKKyAgICAgICAgICAgICAic29tZXdoZXJlIHdpdGhpbiB0aGUgcHJvdG9idWYgc291cmNlIHBhY2thZ2UuIjsKKyAgICB9CisgICAgcHJlZml4ICs9ICIvLi4iOworICB9CisgIHJldHVybiBwcmVmaXggKyAiL3J1YnkvdGVzdHMiOworfQorCisvLyBUaGlzIHRlc3QgaXMgYSBzaW1wbGUgZ29sZGVuLWZpbGUgdGVzdCBvdmVyIHRoZSBvdXRwdXQgb2YgdGhlIFJ1YnkgY29kZQorLy8gZ2VuZXJhdG9yLiBXaGVuIHdlIG1ha2UgY2hhbmdlcyB0byB0aGUgUnVieSBleHRlbnNpb24gYW5kIGFsdGVyIHRoZSBSdWJ5IGNvZGUKKy8vIGdlbmVyYXRvciB0byB1c2UgdGhvc2UgY2hhbmdlcywgd2Ugc2hvdWxkIChpKSBtYW51YWxseSB0ZXN0IHRoZSBvdXRwdXQgb2YgdGhlCisvLyBjb2RlIGdlbmVyYXRvciB3aXRoIHRoZSBleHRlbnNpb24sIGFuZCAoaWkpIHVwZGF0ZSB0aGUgZ29sZGVuIG91dHB1dCBhYm92ZS4KKy8vIFNvbWUgZGF5LCB3ZSBtYXkgaW50ZWdyYXRlIGJ1aWxkIHN5c3RlbXMgYmV0d2VlbiBwcm90b2MgYW5kIHRoZSBsYW5ndWFnZQorLy8gZXh0ZW5zaW9ucyB0byB0aGUgcG9pbnQgd2hlcmUgd2UgY2FuIGRvIHRoaXMgdGVzdCBpbiBhIG1vcmUgYXV0b21hdGVkIHdheS4KKworVEVTVChSdWJ5R2VuZXJhdG9yVGVzdCwgR2VuZXJhdG9yVGVzdCkgeworICBzdHJpbmcgcnVieV90ZXN0cyA9IEZpbmRSdWJ5VGVzdERpcigpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb21tYW5kTGluZUludGVyZmFjZSBjbGk7CisgIGNsaS5TZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZSh0cnVlKTsKKworICBydWJ5OjpHZW5lcmF0b3IgcnVieV9nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1ydWJ5X291dCIsICZydWJ5X2dlbmVyYXRvciwgIiIpOworCisgIC8vIENvcHkgZ2VuZXJhdGVkX2NvZGUucHJvdG8gdG8gdGhlIHRlbXBvcmFyeSB0ZXN0IGRpcmVjdG9yeS4KKyAgc3RyaW5nIHRlc3RfaW5wdXQ7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgIHJ1YnlfdGVzdHMgKyAiL2dlbmVyYXRlZF9jb2RlLnByb3RvIiwKKyAgICAgICZ0ZXN0X2lucHV0LAorICAgICAgdHJ1ZSkpOworICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6U2V0Q29udGVudHMoCisgICAgICBUZXN0VGVtcERpcigpICsgIi9nZW5lcmF0ZWRfY29kZS5wcm90byIsCisgICAgICB0ZXN0X2lucHV0LAorICAgICAgdHJ1ZSkpOworCisgIC8vIEludm9rZSB0aGUgcHJvdG8gY29tcGlsZXIgKHdlIHdpbGwgYmUgaW5zaWRlIFRlc3RUZW1wRGlyKCkgYXQgdGhpcyBwb2ludCkuCisgIHN0cmluZyBydWJ5X291dCA9ICItLXJ1Ynlfb3V0PSIgKyBUZXN0VGVtcERpcigpOworICBzdHJpbmcgcHJvdG9fcGF0aCA9ICItLXByb3RvX3BhdGg9IiArIFRlc3RUZW1wRGlyKCk7CisgIGNvbnN0IGNoYXIqIGFyZ3ZbXSA9IHsKKyAgICAicHJvdG9jIiwKKyAgICBydWJ5X291dC5jX3N0cigpLAorICAgIHByb3RvX3BhdGguY19zdHIoKSwKKyAgICAiZ2VuZXJhdGVkX2NvZGUucHJvdG8iLAorICB9OworCisgIEVYUEVDVF9FUSgwLCBjbGkuUnVuKDQsIGFyZ3YpKTsKKworICAvLyBMb2FkIHRoZSBnZW5lcmF0ZWQgb3V0cHV0IGFuZCBjb21wYXJlIHRvIHRoZSBleHBlY3RlZCByZXN1bHQuCisgIHN0cmluZyBvdXRwdXQ7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgIFRlc3RUZW1wRGlyKCkgKyAiL2dlbmVyYXRlZF9jb2RlLnJiIiwKKyAgICAgICZvdXRwdXQsCisgICAgICB0cnVlKSk7CisgIHN0cmluZyBleHBlY3RlZF9vdXRwdXQ7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgIHJ1YnlfdGVzdHMgKyAiL2dlbmVyYXRlZF9jb2RlLnJiIiwKKyAgICAgICZleHBlY3RlZF9vdXRwdXQsCisgICAgICB0cnVlKSk7CisgIEVYUEVDVF9FUShleHBlY3RlZF9vdXRwdXQsIG91dHB1dCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHJ1YnkKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjFhZTQzOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvc3VicHJvY2Vzcy5jYwpAQCAtMCwwICsxLDQ2MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8aW9zdHJlYW0+CisKKyNpZm5kZWYgX1dJTjMyCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzeXMvc2VsZWN0Lmg+CisjaW5jbHVkZSA8c3lzL3dhaXQuaD4KKyNpbmNsdWRlIDxzaWduYWwuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworI2lmZGVmIF9XSU4zMgorCitzdGF0aWMgdm9pZCBDbG9zZUhhbmRsZU9yRGllKEhBTkRMRSBoYW5kbGUpIHsKKyAgaWYgKCFDbG9zZUhhbmRsZShoYW5kbGUpKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNsb3NlSGFuZGxlOiAiCisgICAgICAgICAgICAgICAgICAgICAgPDwgU3VicHJvY2Vzczo6V2luMzJFcnJvck1lc3NhZ2UoR2V0TGFzdEVycm9yKCkpOworICB9Cit9CisKK1N1YnByb2Nlc3M6OlN1YnByb2Nlc3MoKQorICAgIDogcHJvY2Vzc19zdGFydF9lcnJvcl8oRVJST1JfU1VDQ0VTUyksCisgICAgICBjaGlsZF9oYW5kbGVfKE5VTEwpLCBjaGlsZF9zdGRpbl8oTlVMTCksIGNoaWxkX3N0ZG91dF8oTlVMTCkge30KKworU3VicHJvY2Vzczo6flN1YnByb2Nlc3MoKSB7CisgIGlmIChjaGlsZF9zdGRpbl8gIT0gTlVMTCkgeworICAgIENsb3NlSGFuZGxlT3JEaWUoY2hpbGRfc3RkaW5fKTsKKyAgfQorICBpZiAoY2hpbGRfc3Rkb3V0XyAhPSBOVUxMKSB7CisgICAgQ2xvc2VIYW5kbGVPckRpZShjaGlsZF9zdGRvdXRfKTsKKyAgfQorfQorCit2b2lkIFN1YnByb2Nlc3M6OlN0YXJ0KGNvbnN0IHN0cmluZyYgcHJvZ3JhbSwgU2VhcmNoTW9kZSBzZWFyY2hfbW9kZSkgeworICAvLyBDcmVhdGUgdGhlIHBpcGVzLgorICBIQU5ETEUgc3RkaW5fcGlwZV9yZWFkOworICBIQU5ETEUgc3RkaW5fcGlwZV93cml0ZTsKKyAgSEFORExFIHN0ZG91dF9waXBlX3JlYWQ7CisgIEhBTkRMRSBzdGRvdXRfcGlwZV93cml0ZTsKKworICBpZiAoIUNyZWF0ZVBpcGUoJnN0ZGluX3BpcGVfcmVhZCwgJnN0ZGluX3BpcGVfd3JpdGUsIE5VTEwsIDApKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNyZWF0ZVBpcGU6ICIgPDwgV2luMzJFcnJvck1lc3NhZ2UoR2V0TGFzdEVycm9yKCkpOworICB9CisgIGlmICghQ3JlYXRlUGlwZSgmc3Rkb3V0X3BpcGVfcmVhZCwgJnN0ZG91dF9waXBlX3dyaXRlLCBOVUxMLCAwKSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDcmVhdGVQaXBlOiAiIDw8IFdpbjMyRXJyb3JNZXNzYWdlKEdldExhc3RFcnJvcigpKTsKKyAgfQorCisgIC8vIE1ha2UgY2hpbGQgc2lkZSBvZiB0aGUgcGlwZXMgaW5oZXJpdGFibGUuCisgIGlmICghU2V0SGFuZGxlSW5mb3JtYXRpb24oc3RkaW5fcGlwZV9yZWFkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GTEFHX0lOSEVSSVQsIEhBTkRMRV9GTEFHX0lOSEVSSVQpKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlNldEhhbmRsZUluZm9ybWF0aW9uOiAiCisgICAgICAgICAgICAgICAgICAgICAgPDwgV2luMzJFcnJvck1lc3NhZ2UoR2V0TGFzdEVycm9yKCkpOworICB9CisgIGlmICghU2V0SGFuZGxlSW5mb3JtYXRpb24oc3Rkb3V0X3BpcGVfd3JpdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZMQUdfSU5IRVJJVCwgSEFORExFX0ZMQUdfSU5IRVJJVCkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2V0SGFuZGxlSW5mb3JtYXRpb246ICIKKyAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0KKworICAvLyBTZXR1cCBTVEFSVFVQSU5GTyB0byByZWRpcmVjdCBoYW5kbGVzLgorICBTVEFSVFVQSU5GT0Egc3RhcnR1cF9pbmZvOworICBaZXJvTWVtb3J5KCZzdGFydHVwX2luZm8sIHNpemVvZihzdGFydHVwX2luZm8pKTsKKyAgc3RhcnR1cF9pbmZvLmNiID0gc2l6ZW9mKHN0YXJ0dXBfaW5mbyk7CisgIHN0YXJ0dXBfaW5mby5kd0ZsYWdzID0gU1RBUlRGX1VTRVNUREhBTkRMRVM7CisgIHN0YXJ0dXBfaW5mby5oU3RkSW5wdXQgPSBzdGRpbl9waXBlX3JlYWQ7CisgIHN0YXJ0dXBfaW5mby5oU3RkT3V0cHV0ID0gc3Rkb3V0X3BpcGVfd3JpdGU7CisgIHN0YXJ0dXBfaW5mby5oU3RkRXJyb3IgPSBHZXRTdGRIYW5kbGUoU1REX0VSUk9SX0hBTkRMRSk7CisKKyAgaWYgKHN0YXJ0dXBfaW5mby5oU3RkRXJyb3IgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiR2V0U3RkSGFuZGxlOiAiCisgICAgICAgICAgICAgICAgICAgICAgPDwgV2luMzJFcnJvck1lc3NhZ2UoR2V0TGFzdEVycm9yKCkpOworICB9CisKKyAgLy8gQ3JlYXRlUHJvY2VzcygpIG11dGF0ZXMgaXRzIHNlY29uZCBwYXJhbWV0ZXIuICBXVEY/CisgIGNoYXIqIG5hbWVfY29weSA9IHN0cmR1cChwcm9ncmFtLmNfc3RyKCkpOworCisgIC8vIENyZWF0ZSB0aGUgcHJvY2Vzcy4KKyAgUFJPQ0VTU19JTkZPUk1BVElPTiBwcm9jZXNzX2luZm87CisKKyAgaWYgKENyZWF0ZVByb2Nlc3NBKChzZWFyY2hfbW9kZSA9PSBTRUFSQ0hfUEFUSCkgPyBOVUxMIDogcHJvZ3JhbS5jX3N0cigpLAorICAgICAgICAgICAgICAgICAgICAgKHNlYXJjaF9tb2RlID09IFNFQVJDSF9QQVRIKSA/IG5hbWVfY29weSA6IE5VTEwsCisgICAgICAgICAgICAgICAgICAgICBOVUxMLCAgLy8gcHJvY2VzcyBzZWN1cml0eSBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgICAgICBOVUxMLCAgLy8gdGhyZWFkIHNlY3VyaXR5IGF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgIFRSVUUsICAvLyBpbmhlcml0IGhhbmRsZXM/CisgICAgICAgICAgICAgICAgICAgICAwLCAgICAgLy8gb2JzY3VyZSBjcmVhdGlvbiBmbGFncworICAgICAgICAgICAgICAgICAgICAgTlVMTCwgIC8vIGVudmlyb25tZW50IChpbmhlcml0IGZyb20gcGFyZW50KQorICAgICAgICAgICAgICAgICAgICAgTlVMTCwgIC8vIGN1cnJlbnQgZGlyZWN0b3J5IChpbmhlcml0IGZyb20gcGFyZW50KQorICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0dXBfaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICZwcm9jZXNzX2luZm8pKSB7CisgICAgY2hpbGRfaGFuZGxlXyA9IHByb2Nlc3NfaW5mby5oUHJvY2VzczsKKyAgICBDbG9zZUhhbmRsZU9yRGllKHByb2Nlc3NfaW5mby5oVGhyZWFkKTsKKyAgICBjaGlsZF9zdGRpbl8gPSBzdGRpbl9waXBlX3dyaXRlOworICAgIGNoaWxkX3N0ZG91dF8gPSBzdGRvdXRfcGlwZV9yZWFkOworICB9IGVsc2UgeworICAgIHByb2Nlc3Nfc3RhcnRfZXJyb3JfID0gR2V0TGFzdEVycm9yKCk7CisgICAgQ2xvc2VIYW5kbGVPckRpZShzdGRpbl9waXBlX3dyaXRlKTsKKyAgICBDbG9zZUhhbmRsZU9yRGllKHN0ZG91dF9waXBlX3JlYWQpOworICB9CisKKyAgQ2xvc2VIYW5kbGVPckRpZShzdGRpbl9waXBlX3JlYWQpOworICBDbG9zZUhhbmRsZU9yRGllKHN0ZG91dF9waXBlX3dyaXRlKTsKKyAgZnJlZShuYW1lX2NvcHkpOworfQorCitib29sIFN1YnByb2Nlc3M6OkNvbW11bmljYXRlKGNvbnN0IE1lc3NhZ2UmIGlucHV0LCBNZXNzYWdlKiBvdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIHsKKyAgaWYgKHByb2Nlc3Nfc3RhcnRfZXJyb3JfICE9IEVSUk9SX1NVQ0NFU1MpIHsKKyAgICAqZXJyb3IgPSBXaW4zMkVycm9yTWVzc2FnZShwcm9jZXNzX3N0YXJ0X2Vycm9yXyk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgR09PR0xFX0NIRUNLKGNoaWxkX2hhbmRsZV8gIT0gTlVMTCkgPDwgIk11c3QgY2FsbCBTdGFydCgpIGZpcnN0LiI7CisKKyAgc3RyaW5nIGlucHV0X2RhdGEgPSBpbnB1dC5TZXJpYWxpemVBc1N0cmluZygpOworICBzdHJpbmcgb3V0cHV0X2RhdGE7CisKKyAgaW50IGlucHV0X3BvcyA9IDA7CisKKyAgd2hpbGUgKGNoaWxkX3N0ZG91dF8gIT0gTlVMTCkgeworICAgIEhBTkRMRSBoYW5kbGVzWzJdOworICAgIGludCBoYW5kbGVfY291bnQgPSAwOworCisgICAgaWYgKGNoaWxkX3N0ZGluXyAhPSBOVUxMKSB7CisgICAgICBoYW5kbGVzW2hhbmRsZV9jb3VudCsrXSA9IGNoaWxkX3N0ZGluXzsKKyAgICB9CisgICAgaWYgKGNoaWxkX3N0ZG91dF8gIT0gTlVMTCkgeworICAgICAgaGFuZGxlc1toYW5kbGVfY291bnQrK10gPSBjaGlsZF9zdGRvdXRfOworICAgIH0KKworICAgIERXT1JEIHdhaXRfcmVzdWx0ID0KKyAgICAgICAgV2FpdEZvck11bHRpcGxlT2JqZWN0cyhoYW5kbGVfY291bnQsIGhhbmRsZXMsIEZBTFNFLCBJTkZJTklURSk7CisKKyAgICBIQU5ETEUgc2lnbmFsZWRfaGFuZGxlOworICAgIGlmICh3YWl0X3Jlc3VsdCA+PSBXQUlUX09CSkVDVF8wICYmCisgICAgICAgIHdhaXRfcmVzdWx0IDwgV0FJVF9PQkpFQ1RfMCArIGhhbmRsZV9jb3VudCkgeworICAgICAgc2lnbmFsZWRfaGFuZGxlID0gaGFuZGxlc1t3YWl0X3Jlc3VsdCAtIFdBSVRfT0JKRUNUXzBdOworICAgIH0gZWxzZSBpZiAod2FpdF9yZXN1bHQgPT0gV0FJVF9GQUlMRUQpIHsKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJXYWl0Rm9yTXVsdGlwbGVPYmplY3RzOiAiCisgICAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJXYWl0Rm9yTXVsdGlwbGVPYmplY3RzOiBVbmV4cGVjdGVkIHJldHVybiBjb2RlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICA8PCB3YWl0X3Jlc3VsdDsKKyAgICB9CisKKyAgICBpZiAoc2lnbmFsZWRfaGFuZGxlID09IGNoaWxkX3N0ZGluXykgeworICAgICAgRFdPUkQgbjsKKyAgICAgIGlmICghV3JpdGVGaWxlKGNoaWxkX3N0ZGluXywKKyAgICAgICAgICAgICAgICAgICAgIGlucHV0X2RhdGEuZGF0YSgpICsgaW5wdXRfcG9zLAorICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZGF0YS5zaXplKCkgLSBpbnB1dF9wb3MsCisgICAgICAgICAgICAgICAgICAgICAmbiwgTlVMTCkpIHsKKyAgICAgICAgLy8gQ2hpbGQgY2xvc2VkIHBpcGUuICBQcmVzdW1hYmx5IGl0IHdpbGwgcmVwb3J0IGFuIGVycm9yIGxhdGVyLgorICAgICAgICAvLyBQcmV0ZW5kIHdlJ3JlIGRvbmUgZm9yIG5vdy4KKyAgICAgICAgaW5wdXRfcG9zID0gaW5wdXRfZGF0YS5zaXplKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpbnB1dF9wb3MgKz0gbjsKKyAgICAgIH0KKworICAgICAgaWYgKGlucHV0X3BvcyA9PSBpbnB1dF9kYXRhLnNpemUoKSkgeworICAgICAgICAvLyBXZSdyZSBkb25lIHdyaXRpbmcuICBDbG9zZS4KKyAgICAgICAgQ2xvc2VIYW5kbGVPckRpZShjaGlsZF9zdGRpbl8pOworICAgICAgICBjaGlsZF9zdGRpbl8gPSBOVUxMOworICAgICAgfQorICAgIH0gZWxzZSBpZiAoc2lnbmFsZWRfaGFuZGxlID09IGNoaWxkX3N0ZG91dF8pIHsKKyAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOworICAgICAgRFdPUkQgbjsKKworICAgICAgaWYgKCFSZWFkRmlsZShjaGlsZF9zdGRvdXRfLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmbiwgTlVMTCkpIHsKKyAgICAgICAgLy8gV2UncmUgZG9uZSByZWFkaW5nLiAgQ2xvc2UuCisgICAgICAgIENsb3NlSGFuZGxlT3JEaWUoY2hpbGRfc3Rkb3V0Xyk7CisgICAgICAgIGNoaWxkX3N0ZG91dF8gPSBOVUxMOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgb3V0cHV0X2RhdGEuYXBwZW5kKGJ1ZmZlciwgbik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKGNoaWxkX3N0ZGluXyAhPSBOVUxMKSB7CisgICAgLy8gQ2hpbGQgZGlkIG5vdCBmaW5pc2ggcmVhZGluZyBpbnB1dCBiZWZvcmUgaXQgY2xvc2VkIHRoZSBvdXRwdXQuCisgICAgLy8gUHJlc3VtYWJseSBpdCBleGl0ZWQgd2l0aCBhbiBlcnJvci4KKyAgICBDbG9zZUhhbmRsZU9yRGllKGNoaWxkX3N0ZGluXyk7CisgICAgY2hpbGRfc3RkaW5fID0gTlVMTDsKKyAgfQorCisgIERXT1JEIHdhaXRfcmVzdWx0ID0gV2FpdEZvclNpbmdsZU9iamVjdChjaGlsZF9oYW5kbGVfLCBJTkZJTklURSk7CisKKyAgaWYgKHdhaXRfcmVzdWx0ID09IFdBSVRfRkFJTEVEKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIldhaXRGb3JTaW5nbGVPYmplY3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0gZWxzZSBpZiAod2FpdF9yZXN1bHQgIT0gV0FJVF9PQkpFQ1RfMCkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJXYWl0Rm9yU2luZ2xlT2JqZWN0OiBVbmV4cGVjdGVkIHJldHVybiBjb2RlOiAiCisgICAgICAgICAgICAgICAgICAgICAgPDwgd2FpdF9yZXN1bHQ7CisgIH0KKworICBEV09SRCBleGl0X2NvZGU7CisgIGlmICghR2V0RXhpdENvZGVQcm9jZXNzKGNoaWxkX2hhbmRsZV8sICZleGl0X2NvZGUpKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkdldEV4aXRDb2RlUHJvY2VzczogIgorICAgICAgICAgICAgICAgICAgICAgIDw8IFdpbjMyRXJyb3JNZXNzYWdlKEdldExhc3RFcnJvcigpKTsKKyAgfQorCisgIENsb3NlSGFuZGxlT3JEaWUoY2hpbGRfaGFuZGxlXyk7CisgIGNoaWxkX2hhbmRsZV8gPSBOVUxMOworCisgIGlmIChleGl0X2NvZGUgIT0gMCkgeworICAgICplcnJvciA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICJQbHVnaW4gZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJDAuIiwgZXhpdF9jb2RlKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIW91dHB1dC0+UGFyc2VGcm9tU3RyaW5nKG91dHB1dF9kYXRhKSkgeworICAgICplcnJvciA9ICJQbHVnaW4gb3V0cHV0IGlzIHVucGFyc2VhYmxlOiAiICsgQ0VzY2FwZShvdXRwdXRfZGF0YSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0cmluZyBTdWJwcm9jZXNzOjpXaW4zMkVycm9yTWVzc2FnZShEV09SRCBlcnJvcl9jb2RlKSB7CisgIGNoYXIqIG1lc3NhZ2U7CisKKyAgLy8gV1RGPworICBGb3JtYXRNZXNzYWdlKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8CisgICAgICAgICAgICAgICAgRk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0gfAorICAgICAgICAgICAgICAgIEZPUk1BVF9NRVNTQUdFX0lHTk9SRV9JTlNFUlRTLAorICAgICAgICAgICAgICAgIE5VTEwsIGVycm9yX2NvZGUsIDAsCisgICAgICAgICAgICAgICAgKExQVFNUUikmbWVzc2FnZSwgIC8vIE5PVCBBIEJVRyEKKyAgICAgICAgICAgICAgICAwLCBOVUxMKTsKKworICBzdHJpbmcgcmVzdWx0ID0gbWVzc2FnZTsKKyAgTG9jYWxGcmVlKG1lc3NhZ2UpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNlbHNlICAvLyBfV0lOMzIKKworU3VicHJvY2Vzczo6U3VicHJvY2VzcygpCisgICAgOiBjaGlsZF9waWRfKC0xKSwgY2hpbGRfc3RkaW5fKC0xKSwgY2hpbGRfc3Rkb3V0XygtMSkge30KKworU3VicHJvY2Vzczo6flN1YnByb2Nlc3MoKSB7CisgIGlmIChjaGlsZF9zdGRpbl8gIT0gLTEpIHsKKyAgICBjbG9zZShjaGlsZF9zdGRpbl8pOworICB9CisgIGlmIChjaGlsZF9zdGRvdXRfICE9IC0xKSB7CisgICAgY2xvc2UoY2hpbGRfc3Rkb3V0Xyk7CisgIH0KK30KKwordm9pZCBTdWJwcm9jZXNzOjpTdGFydChjb25zdCBzdHJpbmcmIHByb2dyYW0sIFNlYXJjaE1vZGUgc2VhcmNoX21vZGUpIHsKKyAgLy8gTm90ZSB0aGF0IHdlIGFzc3VtZSB0aGF0IHRoZXJlIGFyZSBubyBvdGhlciB0aHJlYWRzLCB0aHVzIHdlIGRvbid0IGhhdmUgdG8KKyAgLy8gZG8gY3Jhenkgc3R1ZmYgbGlrZSB1c2luZyBzb2NrZXQgcGFpcnMgb3IgYXZvaWRpbmcgbGliYyBsb2Nrcy4KKworICAvLyBbMF0gaXMgcmVhZCBlbmQsIFsxXSBpcyB3cml0ZSBlbmQuCisgIGludCBzdGRpbl9waXBlWzJdOworICBpbnQgc3Rkb3V0X3BpcGVbMl07CisKKyAgR09PR0xFX0NIRUNLKHBpcGUoc3RkaW5fcGlwZSkgIT0gLTEpOworICBHT09HTEVfQ0hFQ0socGlwZShzdGRvdXRfcGlwZSkgIT0gLTEpOworCisgIGNoYXIqIGFyZ3ZbMl0gPSB7IHN0cmR1cChwcm9ncmFtLmNfc3RyKCkpLCBOVUxMIH07CisKKyAgY2hpbGRfcGlkXyA9IGZvcmsoKTsKKyAgaWYgKGNoaWxkX3BpZF8gPT0gLTEpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiZm9yazogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgIH0gZWxzZSBpZiAoY2hpbGRfcGlkXyA9PSAwKSB7CisgICAgLy8gV2UgYXJlIHRoZSBjaGlsZC4KKyAgICBkdXAyKHN0ZGluX3BpcGVbMF0sIFNURElOX0ZJTEVOTyk7CisgICAgZHVwMihzdGRvdXRfcGlwZVsxXSwgU1RET1VUX0ZJTEVOTyk7CisKKyAgICBjbG9zZShzdGRpbl9waXBlWzBdKTsKKyAgICBjbG9zZShzdGRpbl9waXBlWzFdKTsKKyAgICBjbG9zZShzdGRvdXRfcGlwZVswXSk7CisgICAgY2xvc2Uoc3Rkb3V0X3BpcGVbMV0pOworCisgICAgc3dpdGNoIChzZWFyY2hfbW9kZSkgeworICAgICAgY2FzZSBTRUFSQ0hfUEFUSDoKKyAgICAgICAgZXhlY3ZwKGFyZ3ZbMF0sIGFyZ3YpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRVhBQ1RfTkFNRToKKyAgICAgICAgZXhlY3YoYXJndlswXSwgYXJndik7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8vIFdyaXRlIGRpcmVjdGx5IHRvIFNUREVSUl9GSUxFTk8gdG8gYXZvaWQgc3RkaW8gY29kZSBwYXRocyB0aGF0IG1heSBkbworICAgIC8vIHN0dWZmIHRoYXQgaXMgdW5zYWZlIGhlcmUuCisgICAgaW50IGlnbm9yZWQ7CisgICAgaWdub3JlZCA9IHdyaXRlKFNUREVSUl9GSUxFTk8sIGFyZ3ZbMF0sIHN0cmxlbihhcmd2WzBdKSk7CisgICAgY29uc3QgY2hhciogbWVzc2FnZSA9ICI6IHByb2dyYW0gbm90IGZvdW5kIG9yIGlzIG5vdCBleGVjdXRhYmxlXG4iOworICAgIGlnbm9yZWQgPSB3cml0ZShTVERFUlJfRklMRU5PLCBtZXNzYWdlLCBzdHJsZW4obWVzc2FnZSkpOworICAgICh2b2lkKSBpZ25vcmVkOworCisgICAgLy8gTXVzdCB1c2UgX2V4aXQoKSByYXRoZXIgdGhhbiBleGl0KCkgdG8gYXZvaWQgZmx1c2hpbmcgb3V0cHV0IGJ1ZmZlcnMKKyAgICAvLyB0aGF0IHdpbGwgYWxzbyBiZSBmbHVzaGVkIGJ5IHRoZSBwYXJlbnQuCisgICAgX2V4aXQoMSk7CisgIH0gZWxzZSB7CisgICAgZnJlZShhcmd2WzBdKTsKKworICAgIGNsb3NlKHN0ZGluX3BpcGVbMF0pOworICAgIGNsb3NlKHN0ZG91dF9waXBlWzFdKTsKKworICAgIGNoaWxkX3N0ZGluXyA9IHN0ZGluX3BpcGVbMV07CisgICAgY2hpbGRfc3Rkb3V0XyA9IHN0ZG91dF9waXBlWzBdOworICB9Cit9CisKK2Jvb2wgU3VicHJvY2Vzczo6Q29tbXVuaWNhdGUoY29uc3QgTWVzc2FnZSYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgeworCisgIEdPT0dMRV9DSEVDS19ORShjaGlsZF9zdGRpbl8sIC0xKSA8PCAiTXVzdCBjYWxsIFN0YXJ0KCkgZmlyc3QuIjsKKworICAvLyBUaGUgInNpZ2hhbmRsZXJfdCIgdHlwZWRlZiBpcyBHTlUtc3BlY2lmaWMsIHNvIGRlZmluZSBvdXIgb3duLgorICB0eXBlZGVmIHZvaWQgU2lnbmFsSGFuZGxlcihpbnQpOworCisgIC8vIE1ha2Ugc3VyZSBTSUdQSVBFIGlzIGRpc2FibGVkIHNvIHRoYXQgaWYgdGhlIGNoaWxkIGRpZXMgaXQgZG9lc24ndCBraWxsIHVzLgorICBTaWduYWxIYW5kbGVyKiBvbGRfcGlwZV9oYW5kbGVyID0gc2lnbmFsKFNJR1BJUEUsIFNJR19JR04pOworCisgIHN0cmluZyBpbnB1dF9kYXRhID0gaW5wdXQuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgc3RyaW5nIG91dHB1dF9kYXRhOworCisgIGludCBpbnB1dF9wb3MgPSAwOworICBpbnQgbWF4X2ZkID0gbWF4KGNoaWxkX3N0ZGluXywgY2hpbGRfc3Rkb3V0Xyk7CisKKyAgd2hpbGUgKGNoaWxkX3N0ZG91dF8gIT0gLTEpIHsKKyAgICBmZF9zZXQgcmVhZF9mZHM7CisgICAgZmRfc2V0IHdyaXRlX2ZkczsKKyAgICBGRF9aRVJPKCZyZWFkX2Zkcyk7CisgICAgRkRfWkVSTygmd3JpdGVfZmRzKTsKKyAgICBpZiAoY2hpbGRfc3Rkb3V0XyAhPSAtMSkgeworICAgICAgRkRfU0VUKGNoaWxkX3N0ZG91dF8sICZyZWFkX2Zkcyk7CisgICAgfQorICAgIGlmIChjaGlsZF9zdGRpbl8gIT0gLTEpIHsKKyAgICAgIEZEX1NFVChjaGlsZF9zdGRpbl8sICZ3cml0ZV9mZHMpOworICAgIH0KKworICAgIGlmIChzZWxlY3QobWF4X2ZkICsgMSwgJnJlYWRfZmRzLCAmd3JpdGVfZmRzLCBOVUxMLCBOVUxMKSA8IDApIHsKKyAgICAgIGlmIChlcnJubyA9PSBFSU5UUikgeworICAgICAgICAvLyBJbnRlcnJ1cHRlZCBieSBzaWduYWwuICBUcnkgYWdhaW4uCisgICAgICAgIGNvbnRpbnVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInNlbGVjdDogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKGNoaWxkX3N0ZGluXyAhPSAtMSAmJiBGRF9JU1NFVChjaGlsZF9zdGRpbl8sICZ3cml0ZV9mZHMpKSB7CisgICAgICBpbnQgbiA9IHdyaXRlKGNoaWxkX3N0ZGluXywgaW5wdXRfZGF0YS5kYXRhKCkgKyBpbnB1dF9wb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZGF0YS5zaXplKCkgLSBpbnB1dF9wb3MpOworICAgICAgaWYgKG4gPCAwKSB7CisgICAgICAgIC8vIENoaWxkIGNsb3NlZCBwaXBlLiAgUHJlc3VtYWJseSBpdCB3aWxsIHJlcG9ydCBhbiBlcnJvciBsYXRlci4KKyAgICAgICAgLy8gUHJldGVuZCB3ZSdyZSBkb25lIGZvciBub3cuCisgICAgICAgIGlucHV0X3BvcyA9IGlucHV0X2RhdGEuc2l6ZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaW5wdXRfcG9zICs9IG47CisgICAgICB9CisKKyAgICAgIGlmIChpbnB1dF9wb3MgPT0gaW5wdXRfZGF0YS5zaXplKCkpIHsKKyAgICAgICAgLy8gV2UncmUgZG9uZSB3cml0aW5nLiAgQ2xvc2UuCisgICAgICAgIGNsb3NlKGNoaWxkX3N0ZGluXyk7CisgICAgICAgIGNoaWxkX3N0ZGluXyA9IC0xOworICAgICAgfQorICAgIH0KKworICAgIGlmIChjaGlsZF9zdGRvdXRfICE9IC0xICYmIEZEX0lTU0VUKGNoaWxkX3N0ZG91dF8sICZyZWFkX2ZkcykpIHsKKyAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOworICAgICAgaW50IG4gPSByZWFkKGNoaWxkX3N0ZG91dF8sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOworCisgICAgICBpZiAobiA+IDApIHsKKyAgICAgICAgb3V0cHV0X2RhdGEuYXBwZW5kKGJ1ZmZlciwgbik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBXZSdyZSBkb25lIHJlYWRpbmcuICBDbG9zZS4KKyAgICAgICAgY2xvc2UoY2hpbGRfc3Rkb3V0Xyk7CisgICAgICAgIGNoaWxkX3N0ZG91dF8gPSAtMTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoY2hpbGRfc3RkaW5fICE9IC0xKSB7CisgICAgLy8gQ2hpbGQgZGlkIG5vdCBmaW5pc2ggcmVhZGluZyBpbnB1dCBiZWZvcmUgaXQgY2xvc2VkIHRoZSBvdXRwdXQuCisgICAgLy8gUHJlc3VtYWJseSBpdCBleGl0ZWQgd2l0aCBhbiBlcnJvci4KKyAgICBjbG9zZShjaGlsZF9zdGRpbl8pOworICAgIGNoaWxkX3N0ZGluXyA9IC0xOworICB9CisKKyAgaW50IHN0YXR1czsKKyAgd2hpbGUgKHdhaXRwaWQoY2hpbGRfcGlkXywgJnN0YXR1cywgMCkgPT0gLTEpIHsKKyAgICBpZiAoZXJybm8gIT0gRUlOVFIpIHsKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJ3YWl0cGlkOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgICB9CisgIH0KKworICAvLyBSZXN0b3JlIFNJR1BJUEUgaGFuZGxpbmcuCisgIHNpZ25hbChTSUdQSVBFLCBvbGRfcGlwZV9oYW5kbGVyKTsKKworICBpZiAoV0lGRVhJVEVEKHN0YXR1cykpIHsKKyAgICBpZiAoV0VYSVRTVEFUVVMoc3RhdHVzKSAhPSAwKSB7CisgICAgICBpbnQgZXJyb3JfY29kZSA9IFdFWElUU1RBVFVTKHN0YXR1cyk7CisgICAgICAqZXJyb3IgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICJQbHVnaW4gZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJDAuIiwgZXJyb3JfY29kZSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9IGVsc2UgaWYgKFdJRlNJR05BTEVEKHN0YXR1cykpIHsKKyAgICBpbnQgc2lnbmFsID0gV1RFUk1TSUcoc3RhdHVzKTsKKyAgICAqZXJyb3IgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAiUGx1Z2luIGtpbGxlZCBieSBzaWduYWwgJDAuIiwgc2lnbmFsKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgKmVycm9yID0gIk5laXRoZXIgV0VYSVRTVEFUVVMgbm9yIFdURVJNU0lHIGlzIHRydWU/IjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIW91dHB1dC0+UGFyc2VGcm9tU3RyaW5nKG91dHB1dF9kYXRhKSkgeworICAgICplcnJvciA9ICJQbHVnaW4gb3V0cHV0IGlzIHVucGFyc2VhYmxlOiAiICsgQ0VzY2FwZShvdXRwdXRfZGF0YSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKyNlbmRpZiAgLy8gIV9XSU4zMgorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNTEzODYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmgKQEAgLTAsMCArMSwxMDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1NVQlBST0NFU1NfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9TVUJQUk9DRVNTX0hfXworCisjaWZkZWYgX1dJTjMyCisjZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4gICAvLyByaWdodC4uLgorI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbHNlICAvLyBfV0lOMzIKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZiAgLy8gIV9XSU4zMgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2luY2x1ZGUgPHN0cmluZz4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIE1lc3NhZ2U7CisKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIFV0aWxpdHkgY2xhc3MgZm9yIGxhdW5jaGluZyBzdWItcHJvY2Vzc2VzLgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBTdWJwcm9jZXNzIHsKKyBwdWJsaWM6CisgIFN1YnByb2Nlc3MoKTsKKyAgflN1YnByb2Nlc3MoKTsKKworICBlbnVtIFNlYXJjaE1vZGUgeworICAgIFNFQVJDSF9QQVRILCAgIC8vIFVzZSBQQVRIIGVudmlyb25tZW50IHZhcmlhYmxlLgorICAgIEVYQUNUX05BTUUgICAgIC8vIFByb2dyYW0gaXMgYW4gZXhhY3QgZmlsZSBuYW1lOyBkb24ndCB1c2UgdGhlIFBBVEguCisgIH07CisKKyAgLy8gU3RhcnQgdGhlIHN1YnByb2Nlc3MuICBDdXJyZW50bHkgd2UgZG9uJ3QgcHJvdmlkZSBhIHdheSB0byBzcGVjaWZ5CisgIC8vIGFyZ3VtZW50cyBhcyBwcm90b2MgcGx1Z2lucyBkb24ndCBoYXZlIGFueS4KKyAgdm9pZCBTdGFydChjb25zdCBzdHJpbmcmIHByb2dyYW0sIFNlYXJjaE1vZGUgc2VhcmNoX21vZGUpOworCisgIC8vIFNlcmlhbGl6ZSB0aGUgaW5wdXQgbWVzc2FnZSBhbmQgcGlwZSBpdCB0byB0aGUgc3VicHJvY2VzcydzIHN0ZGluLCB0aGVuCisgIC8vIGNsb3NlIHRoZSBwaXBlLiAgTWVhbndoaWxlLCByZWFkIGZyb20gdGhlIHN1YnByb2Nlc3MncyBzdGRvdXQgYW5kIHBhcnNlCisgIC8vIHRoZSBkYXRhIGludG8gKm91dHB1dC4gIEFsbCB0aGlzIGlzIGRvbmUgY2FyZWZ1bGx5IHRvIGF2b2lkIGRlYWRsb2Nrcy4KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHN1Y2Nlc3NmdWwuICBPbiBhbnkgc29ydCBvZiBlcnJvciwgcmV0dXJucyBmYWxzZSBhbmQgc2V0cworICAvLyAqZXJyb3IgdG8gYSBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvYmxlbS4KKyAgYm9vbCBDb21tdW5pY2F0ZShjb25zdCBNZXNzYWdlJiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0LCBzdHJpbmcqIGVycm9yKTsKKworI2lmZGVmIF9XSU4zMgorICAvLyBHaXZlbiBhbiBlcnJvciBjb2RlLCByZXR1cm5zIGEgaHVtYW4tcmVhZGFibGUgZXJyb3IgbWVzc2FnZS4gIFRoaXMgaXMKKyAgLy8gZGVmaW5lZCBoZXJlIHNvIHRoYXQgQ29tbWFuZExpbmVJbnRlcmZhY2UgY2FuIHNoYXJlIGl0LgorICBzdGF0aWMgc3RyaW5nIFdpbjMyRXJyb3JNZXNzYWdlKERXT1JEIGVycm9yX2NvZGUpOworI2VuZGlmCisKKyBwcml2YXRlOgorI2lmZGVmIF9XSU4zMgorICBEV09SRCBwcm9jZXNzX3N0YXJ0X2Vycm9yXzsKKyAgSEFORExFIGNoaWxkX2hhbmRsZV87CisKKyAgLy8gVGhlIGZpbGUgaGFuZGxlcyBmb3Igb3VyIGVuZCBvZiB0aGUgY2hpbGQncyBwaXBlcy4gIFdlIGNsb3NlIGVhY2ggYW5kCisgIC8vIHNldCBpdCB0byBOVUxMIHdoZW4gbm8gbG9uZ2VyIG5lZWRlZC4KKyAgSEFORExFIGNoaWxkX3N0ZGluXzsKKyAgSEFORExFIGNoaWxkX3N0ZG91dF87CisKKyNlbHNlICAvLyBfV0lOMzIKKyAgcGlkX3QgY2hpbGRfcGlkXzsKKworICAvLyBUaGUgZmlsZSBkZXNjcmlwdG9ycyBmb3Igb3VyIGVuZCBvZiB0aGUgY2hpbGQncyBwaXBlcy4gIFdlIGNsb3NlIGVhY2ggYW5kCisgIC8vIHNldCBpdCB0byAtMSB3aGVuIG5vIGxvbmdlciBuZWVkZWQuCisgIGludCBjaGlsZF9zdGRpbl87CisgIGludCBjaGlsZF9zdGRvdXRfOworCisjZW5kaWYgIC8vICFfV0lOMzIKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1NVQlBST0NFU1NfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3Rlc3RfcGx1Z2luLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci90ZXN0X3BsdWdpbi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODMwZmQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci90ZXN0X3BsdWdpbi5jYwpAQCAtMCwwICsxLDUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFRoaXMgaXMgYSBkdW1teSBjb2RlIGdlbmVyYXRvciBwbHVnaW4gdXNlZCBieQorLy8gY29tbWFuZF9saW5lX2ludGVyZmFjZV91bml0dGVzdC4KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCitpbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CisjaWZkZWYgX01TQ19WRVIKKyAgLy8gRG9uJ3QgcHJpbnQgYSBzaWxseSBtZXNzYWdlIG9yIHN0aWNrIGEgbW9kYWwgZGlhbG9nIGJveCBpbiBteSBmYWNlLAorICAvLyBwbGVhc2UuCisgIF9zZXRfYWJvcnRfYmVoYXZpb3IoMCwgfjApOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6TW9ja0NvZGVHZW5lcmF0b3IgZ2VuZXJhdG9yKCJ0ZXN0X3BsdWdpbiIpOworICByZXR1cm4gZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OlBsdWdpbk1haW4oYXJnYywgYXJndiwgJmdlbmVyYXRvcik7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2ggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNmZjNzEzNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX291dHB1dF91bml0dGVzdC5zaApAQCAtMCwwICsxLDkxIEBACisjIS9iaW4vc2gKKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA5IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisjCisjIFRlc3QgcHJvdG9jJ3MgemlwIG91dHB1dCBtb2RlLgorCitmYWlsKCkgeworICBlY2hvICIkQCIgPiYyCisgIGV4aXQgMQorfQorCitURVNUX1RNUERJUj0uCitQUk9UT0M9Li9wcm90b2MKKworZWNobyAnCisgIHN5bnRheCA9ICJwcm90bzIiOworICBvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CisgIG9wdGlvbiBqYXZhX3BhY2thZ2UgPSAidGVzdC5qYXIiOworICBvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiT3V0ZXIiOworICBtZXNzYWdlIEZvbyB7fQorICBtZXNzYWdlIEJhciB7fQorJyA+ICRURVNUX1RNUERJUi90ZXN0emlwLnByb3RvCisKKyRQUk9UT0MgXAorICAgIC0tY3BwX291dD0kVEVTVF9UTVBESVIvdGVzdHppcC56aXAgLS1weXRob25fb3V0PSRURVNUX1RNUERJUi90ZXN0emlwLnppcCBcCisgICAgLS1qYXZhX291dD0kVEVTVF9UTVBESVIvdGVzdHppcC5qYXIgLUkkVEVTVF9UTVBESVIgdGVzdHppcC5wcm90byBcCisgICAgfHwgZmFpbCAncHJvdG9jIGZhaWxlZC4nCisKK2VjaG8gIlRlc3Rpbmcgb3V0cHV0IHRvIHppcC4uLiIKK2lmIHVuemlwIC1oID4gL2Rldi9udWxsOyB0aGVuCisgIHVuemlwIC10ICRURVNUX1RNUERJUi90ZXN0emlwLnppcCA+ICRURVNUX1RNUERJUi90ZXN0emlwLmxpc3QgfHwgZmFpbCAndW56aXAgZmFpbGVkLicKKworICBncmVwICd0ZXN0aW5nOiB0ZXN0emlwXC5wYlwuY2MgKk9LJCcgJFRFU1RfVE1QRElSL3Rlc3R6aXAubGlzdCA+IC9kZXYvbnVsbCBcCisgICAgfHwgZmFpbCAndGVzdHppcC5wYi5jYyBub3QgZm91bmQgaW4gb3V0cHV0IHppcC4nCisgIGdyZXAgJ3Rlc3Rpbmc6IHRlc3R6aXBcLnBiXC5oICpPSyQnICRURVNUX1RNUERJUi90ZXN0emlwLmxpc3QgPiAvZGV2L251bGwgXAorICAgIHx8IGZhaWwgJ3Rlc3R6aXAucGIuaCBub3QgZm91bmQgaW4gb3V0cHV0IHppcC4nCisgIGdyZXAgJ3Rlc3Rpbmc6IHRlc3R6aXBfcGIyXC5weSAqT0skJyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICB8fCBmYWlsICd0ZXN0emlwX3BiMi5weSBub3QgZm91bmQgaW4gb3V0cHV0IHppcC4nCisgIGdyZXAgLWkgJ21hbmlmZXN0JyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICAmJiBmYWlsICdaaXAgZmlsZSBjb250YWluZWQgbWFuaWZlc3QuJworZWxzZQorICBlY2hvICJXYXJuaW5nOiAgJ3VuemlwJyBjb21tYW5kIG5vdCBhdmFpbGFibGUuICBTa2lwcGluZyB0ZXN0LiIKK2ZpCisKK2VjaG8gIlRlc3Rpbmcgb3V0cHV0IHRvIGphci4uLiIKK2lmIGphciBjICRURVNUX1RNUERJUi90ZXN0emlwLnByb3RvID4gL2Rldi9udWxsOyB0aGVuCisgIGphciB0ZiAkVEVTVF9UTVBESVIvdGVzdHppcC5qYXIgPiAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0IHx8IGZhaWwgJ2phciBmYWlsZWQuJworCisgIGdyZXAgJ150ZXN0L2phci9Gb29cLmphdmEkJyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICB8fCBmYWlsICdGb28uamF2YSBub3QgZm91bmQgaW4gb3V0cHV0IGphci4nCisgIGdyZXAgJ150ZXN0L2phci9CYXJcLmphdmEkJyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICB8fCBmYWlsICdCYXIuamF2YSBub3QgZm91bmQgaW4gb3V0cHV0IGphci4nCisgIGdyZXAgJ150ZXN0L2phci9PdXRlclwuamF2YSQnICRURVNUX1RNUERJUi90ZXN0emlwLmxpc3QgPiAvZGV2L251bGwgXAorICAgIHx8IGZhaWwgJ091dGVyLmphdmEgbm90IGZvdW5kIGluIG91dHB1dCBqYXIuJworICBncmVwICdeTUVUQS1JTkYvTUFOSUZFU1RcLk1GJCcgJFRFU1RfVE1QRElSL3Rlc3R6aXAubGlzdCA+IC9kZXYvbnVsbCBcCisgICAgfHwgZmFpbCAnTWFuaWZlc3Qgbm90IGZvdW5kIGluIG91dHB1dCBqYXIuJworZWxzZQorICBlY2hvICJXYXJuaW5nOiAgJ2phcicgY29tbWFuZCBub3QgYXZhaWxhYmxlLiAgU2tpcHBpbmcgdGVzdC4iCitmaQorCitlY2hvIFBBU1MKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NThjY2VkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci96aXBfd3JpdGVyLmNjCkBAIC0wLDAgKzEsMjE4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYW1icm9zZUBnb29nbGUuY29tIChBbWJyb3NlIEZlaW5zdGVpbiksCisvLyAgICAgICAgIGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gQmFzZWQgb24gaHR0cDovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVAorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKK3N0YXRpYyBjb25zdCB1aW50MzIga0NSQzMyVGFibGVbMjU2XSA9IHsKKyAgMHgwMDAwMDAwMCwgMHg3NzA3MzA5NiwgMHhlZTBlNjEyYywgMHg5OTA5NTFiYSwgMHgwNzZkYzQxOSwgMHg3MDZhZjQ4ZiwKKyAgMHhlOTYzYTUzNSwgMHg5ZTY0OTVhMywgMHgwZWRiODgzMiwgMHg3OWRjYjhhNCwgMHhlMGQ1ZTkxZSwgMHg5N2QyZDk4OCwKKyAgMHgwOWI2NGMyYiwgMHg3ZWIxN2NiZCwgMHhlN2I4MmQwNywgMHg5MGJmMWQ5MSwgMHgxZGI3MTA2NCwgMHg2YWIwMjBmMiwKKyAgMHhmM2I5NzE0OCwgMHg4NGJlNDFkZSwgMHgxYWRhZDQ3ZCwgMHg2ZGRkZTRlYiwgMHhmNGQ0YjU1MSwgMHg4M2QzODVjNywKKyAgMHgxMzZjOTg1NiwgMHg2NDZiYThjMCwgMHhmZDYyZjk3YSwgMHg4YTY1YzllYywgMHgxNDAxNWM0ZiwgMHg2MzA2NmNkOSwKKyAgMHhmYTBmM2Q2MywgMHg4ZDA4MGRmNSwgMHgzYjZlMjBjOCwgMHg0YzY5MTA1ZSwgMHhkNTYwNDFlNCwgMHhhMjY3NzE3MiwKKyAgMHgzYzAzZTRkMSwgMHg0YjA0ZDQ0NywgMHhkMjBkODVmZCwgMHhhNTBhYjU2YiwgMHgzNWI1YThmYSwgMHg0MmIyOTg2YywKKyAgMHhkYmJiYzlkNiwgMHhhY2JjZjk0MCwgMHgzMmQ4NmNlMywgMHg0NWRmNWM3NSwgMHhkY2Q2MGRjZiwgMHhhYmQxM2Q1OSwKKyAgMHgyNmQ5MzBhYywgMHg1MWRlMDAzYSwgMHhjOGQ3NTE4MCwgMHhiZmQwNjExNiwgMHgyMWI0ZjRiNSwgMHg1NmIzYzQyMywKKyAgMHhjZmJhOTU5OSwgMHhiOGJkYTUwZiwgMHgyODAyYjg5ZSwgMHg1ZjA1ODgwOCwgMHhjNjBjZDliMiwgMHhiMTBiZTkyNCwKKyAgMHgyZjZmN2M4NywgMHg1ODY4NGMxMSwgMHhjMTYxMWRhYiwgMHhiNjY2MmQzZCwgMHg3NmRjNDE5MCwgMHgwMWRiNzEwNiwKKyAgMHg5OGQyMjBiYywgMHhlZmQ1MTAyYSwgMHg3MWIxODU4OSwgMHgwNmI2YjUxZiwgMHg5ZmJmZTRhNSwgMHhlOGI4ZDQzMywKKyAgMHg3ODA3YzlhMiwgMHgwZjAwZjkzNCwgMHg5NjA5YTg4ZSwgMHhlMTBlOTgxOCwgMHg3ZjZhMGRiYiwgMHgwODZkM2QyZCwKKyAgMHg5MTY0NmM5NywgMHhlNjYzNWMwMSwgMHg2YjZiNTFmNCwgMHgxYzZjNjE2MiwgMHg4NTY1MzBkOCwgMHhmMjYyMDA0ZSwKKyAgMHg2YzA2OTVlZCwgMHgxYjAxYTU3YiwgMHg4MjA4ZjRjMSwgMHhmNTBmYzQ1NywgMHg2NWIwZDljNiwgMHgxMmI3ZTk1MCwKKyAgMHg4YmJlYjhlYSwgMHhmY2I5ODg3YywgMHg2MmRkMWRkZiwgMHgxNWRhMmQ0OSwgMHg4Y2QzN2NmMywgMHhmYmQ0NGM2NSwKKyAgMHg0ZGIyNjE1OCwgMHgzYWI1NTFjZSwgMHhhM2JjMDA3NCwgMHhkNGJiMzBlMiwgMHg0YWRmYTU0MSwgMHgzZGQ4OTVkNywKKyAgMHhhNGQxYzQ2ZCwgMHhkM2Q2ZjRmYiwgMHg0MzY5ZTk2YSwgMHgzNDZlZDlmYywgMHhhZDY3ODg0NiwgMHhkYTYwYjhkMCwKKyAgMHg0NDA0MmQ3MywgMHgzMzAzMWRlNSwgMHhhYTBhNGM1ZiwgMHhkZDBkN2NjOSwgMHg1MDA1NzEzYywgMHgyNzAyNDFhYSwKKyAgMHhiZTBiMTAxMCwgMHhjOTBjMjA4NiwgMHg1NzY4YjUyNSwgMHgyMDZmODViMywgMHhiOTY2ZDQwOSwgMHhjZTYxZTQ5ZiwKKyAgMHg1ZWRlZjkwZSwgMHgyOWQ5Yzk5OCwgMHhiMGQwOTgyMiwgMHhjN2Q3YThiNCwgMHg1OWIzM2QxNywgMHgyZWI0MGQ4MSwKKyAgMHhiN2JkNWMzYiwgMHhjMGJhNmNhZCwgMHhlZGI4ODMyMCwgMHg5YWJmYjNiNiwgMHgwM2I2ZTIwYywgMHg3NGIxZDI5YSwKKyAgMHhlYWQ1NDczOSwgMHg5ZGQyNzdhZiwgMHgwNGRiMjYxNSwgMHg3M2RjMTY4MywgMHhlMzYzMGIxMiwgMHg5NDY0M2I4NCwKKyAgMHgwZDZkNmEzZSwgMHg3YTZhNWFhOCwgMHhlNDBlY2YwYiwgMHg5MzA5ZmY5ZCwgMHgwYTAwYWUyNywgMHg3ZDA3OWViMSwKKyAgMHhmMDBmOTM0NCwgMHg4NzA4YTNkMiwgMHgxZTAxZjI2OCwgMHg2OTA2YzJmZSwgMHhmNzYyNTc1ZCwgMHg4MDY1NjdjYiwKKyAgMHgxOTZjMzY3MSwgMHg2ZTZiMDZlNywgMHhmZWQ0MWI3NiwgMHg4OWQzMmJlMCwgMHgxMGRhN2E1YSwgMHg2N2RkNGFjYywKKyAgMHhmOWI5ZGY2ZiwgMHg4ZWJlZWZmOSwgMHgxN2I3YmU0MywgMHg2MGIwOGVkNSwgMHhkNmQ2YTNlOCwgMHhhMWQxOTM3ZSwKKyAgMHgzOGQ4YzJjNCwgMHg0ZmRmZjI1MiwgMHhkMWJiNjdmMSwgMHhhNmJjNTc2NywgMHgzZmI1MDZkZCwgMHg0OGIyMzY0YiwKKyAgMHhkODBkMmJkYSwgMHhhZjBhMWI0YywgMHgzNjAzNGFmNiwgMHg0MTA0N2E2MCwgMHhkZjYwZWZjMywgMHhhODY3ZGY1NSwKKyAgMHgzMTZlOGVlZiwgMHg0NjY5YmU3OSwgMHhjYjYxYjM4YywgMHhiYzY2ODMxYSwgMHgyNTZmZDJhMCwgMHg1MjY4ZTIzNiwKKyAgMHhjYzBjNzc5NSwgMHhiYjBiNDcwMywgMHgyMjAyMTZiOSwgMHg1NTA1MjYyZiwgMHhjNWJhM2JiZSwgMHhiMmJkMGIyOCwKKyAgMHgyYmI0NWE5MiwgMHg1Y2IzNmEwNCwgMHhjMmQ3ZmZhNywgMHhiNWQwY2YzMSwgMHgyY2Q5OWU4YiwgMHg1YmRlYWUxZCwKKyAgMHg5YjY0YzJiMCwgMHhlYzYzZjIyNiwgMHg3NTZhYTM5YywgMHgwMjZkOTMwYSwgMHg5YzA5MDZhOSwgMHhlYjBlMzYzZiwKKyAgMHg3MjA3Njc4NSwgMHgwNTAwNTcxMywgMHg5NWJmNGE4MiwgMHhlMmI4N2ExNCwgMHg3YmIxMmJhZSwgMHgwY2I2MWIzOCwKKyAgMHg5MmQyOGU5YiwgMHhlNWQ1YmUwZCwgMHg3Y2RjZWZiNywgMHgwYmRiZGYyMSwgMHg4NmQzZDJkNCwgMHhmMWQ0ZTI0MiwKKyAgMHg2OGRkYjNmOCwgMHgxZmRhODM2ZSwgMHg4MWJlMTZjZCwgMHhmNmI5MjY1YiwgMHg2ZmIwNzdlMSwgMHgxOGI3NDc3NywKKyAgMHg4ODA4NWFlNiwgMHhmZjBmNmE3MCwgMHg2NjA2M2JjYSwgMHgxMTAxMGI1YywgMHg4ZjY1OWVmZiwgMHhmODYyYWU2OSwKKyAgMHg2MTZiZmZkMywgMHgxNjZjY2Y0NSwgMHhhMDBhZTI3OCwgMHhkNzBkZDJlZSwgMHg0ZTA0ODM1NCwgMHgzOTAzYjNjMiwKKyAgMHhhNzY3MjY2MSwgMHhkMDYwMTZmNywgMHg0OTY5NDc0ZCwgMHgzZTZlNzdkYiwgMHhhZWQxNmE0YSwgMHhkOWQ2NWFkYywKKyAgMHg0MGRmMGI2NiwgMHgzN2Q4M2JmMCwgMHhhOWJjYWU1MywgMHhkZWJiOWVjNSwgMHg0N2IyY2Y3ZiwgMHgzMGI1ZmZlOSwKKyAgMHhiZGJkZjIxYywgMHhjYWJhYzI4YSwgMHg1M2IzOTMzMCwgMHgyNGI0YTNhNiwgMHhiYWQwMzYwNSwgMHhjZGQ3MDY5MywKKyAgMHg1NGRlNTcyOSwgMHgyM2Q5NjdiZiwgMHhiMzY2N2EyZSwgMHhjNDYxNGFiOCwgMHg1ZDY4MWIwMiwgMHgyYTZmMmI5NCwKKyAgMHhiNDBiYmUzNywgMHhjMzBjOGVhMSwgMHg1YTA1ZGYxYiwgMHgyZDAyZWY4ZAorfTsKKworc3RhdGljIHVpbnQzMiBDb21wdXRlQ1JDMzIoY29uc3Qgc3RyaW5nICZidWYpIHsKKyAgdWludDMyIHggPSB+MFU7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgYnVmLnNpemUoKTsgKytpKSB7CisgICAgdW5zaWduZWQgY2hhciBjID0gYnVmW2ldOworICAgIHggPSBrQ1JDMzJUYWJsZVsoeCBeIGMpICYgMHhmZl0gXiAoeCA+PiA4KTsKKyAgfQorICByZXR1cm4gfng7Cit9CisKK3N0YXRpYyB2b2lkIFdyaXRlU2hvcnQoaW86OkNvZGVkT3V0cHV0U3RyZWFtICpvdXQsIHVpbnQxNiB2YWwpIHsKKyAgdWludDggcFsyXTsKKyAgcFswXSA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWwpOworICBwWzFdID0gc3RhdGljX2Nhc3Q8dWludDg+KHZhbCA+PiA4KTsKKyAgb3V0LT5Xcml0ZVJhdyhwLCAyKTsKK30KKworWmlwV3JpdGVyOjpaaXBXcml0ZXIoaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiByYXdfb3V0cHV0KQorICA6IHJhd19vdXRwdXRfKHJhd19vdXRwdXQpIHt9CitaaXBXcml0ZXI6On5aaXBXcml0ZXIoKSB7fQorCitib29sIFppcFdyaXRlcjo6V3JpdGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBjb250ZW50cykgeworICBGaWxlSW5mbyBpbmZvOworCisgIGluZm8ubmFtZSA9IGZpbGVuYW1lOworICB1aW50MTYgZmlsZW5hbWVfc2l6ZSA9IGZpbGVuYW1lLnNpemUoKTsKKyAgaW5mby5vZmZzZXQgPSByYXdfb3V0cHV0Xy0+Qnl0ZUNvdW50KCk7CisgIGluZm8uc2l6ZSA9IGNvbnRlbnRzLnNpemUoKTsKKyAgaW5mby5jcmMzMiA9IENvbXB1dGVDUkMzMihjb250ZW50cyk7CisKKyAgZmlsZXNfLnB1c2hfYmFjayhpbmZvKTsKKworICAvLyB3cml0ZSBmaWxlIGhlYWRlcgorICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KHJhd19vdXRwdXRfKTsKKyAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoMHgwNDAzNGI1MCk7ICAvLyBtYWdpYworICBXcml0ZVNob3J0KCZvdXRwdXQsIDEwKTsgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGZsYWdzCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBjb21wcmVzc2lvbiBtZXRob2Q6IHN0b3JlZAorICBXcml0ZVNob3J0KCZvdXRwdXQsIDApOyAgLy8gbGFzdCBtb2RpZmllZCB0aW1lCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBsYXN0IG1vZGlmaWVkIGRhdGUKKyAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoaW5mby5jcmMzMik7ICAvLyBjcmMtMzIKKyAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoaW5mby5zaXplKTsgIC8vIGNvbXByZXNzZWQgc2l6ZQorICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihpbmZvLnNpemUpOyAgLy8gdW5jb21wcmVzc2VkIHNpemUKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCBmaWxlbmFtZV9zaXplKTsgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgb3V0cHV0LldyaXRlU3RyaW5nKGZpbGVuYW1lKTsgIC8vIGZpbGUgbmFtZQorICBvdXRwdXQuV3JpdGVTdHJpbmcoY29udGVudHMpOyAgLy8gZmlsZSBkYXRhCisKKyAgcmV0dXJuICFvdXRwdXQuSGFkRXJyb3IoKTsKK30KKworYm9vbCBaaXBXcml0ZXI6OldyaXRlRGlyZWN0b3J5KCkgeworICB1aW50MTYgbnVtX2VudHJpZXMgPSBmaWxlc18uc2l6ZSgpOworICB1aW50MzIgZGlyX29mcyA9IHJhd19vdXRwdXRfLT5CeXRlQ291bnQoKTsKKworICAvLyB3cml0ZSBjZW50cmFsIGRpcmVjdG9yeQorICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KHJhd19vdXRwdXRfKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1fZW50cmllczsgKytpKSB7CisgICAgY29uc3Qgc3RyaW5nICZmaWxlbmFtZSA9IGZpbGVzX1tpXS5uYW1lOworICAgIHVpbnQxNiBmaWxlbmFtZV9zaXplID0gZmlsZW5hbWUuc2l6ZSgpOworICAgIHVpbnQzMiBjcmMzMiA9IGZpbGVzX1tpXS5jcmMzMjsKKyAgICB1aW50MzIgc2l6ZSA9IGZpbGVzX1tpXS5zaXplOworICAgIHVpbnQzMiBvZmZzZXQgPSBmaWxlc19baV0ub2Zmc2V0OworCisgICAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoMHgwMjAxNGI1MCk7ICAvLyBtYWdpYworICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMTApOyAgLy8gdmVyc2lvbiBtYWRlIGJ5CisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAxMCk7ICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGZsYWdzCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGNvbXByZXNzaW9uIG1ldGhvZDogc3RvcmVkCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGxhc3QgbW9kaWZpZWQgdGltZQorICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBsYXN0IG1vZGlmaWVkIGRhdGUKKyAgICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihjcmMzMik7ICAvLyBjcmMtMzIKKyAgICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihzaXplKTsgIC8vIGNvbXByZXNzZWQgc2l6ZQorICAgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKHNpemUpOyAgLy8gdW5jb21wcmVzc2VkIHNpemUKKyAgICBXcml0ZVNob3J0KCZvdXRwdXQsIGZpbGVuYW1lX3NpemUpOyAgLy8gZmlsZSBuYW1lIGxlbmd0aAorICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAgLy8gZXh0cmEgZmllbGQgbGVuZ3RoCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgICAvLyBmaWxlIGNvbW1lbnQgbGVuZ3RoCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgICAvLyBzdGFydGluZyBkaXNrIG51bWJlcgorICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAgLy8gaW50ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzCisgICAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoMCk7ICAvLyBleHRlcm5hbCBmaWxlIGF0dHJpYnV0ZXMKKyAgICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihvZmZzZXQpOyAgLy8gbG9jYWwgaGVhZGVyIG9mZnNldAorICAgIG91dHB1dC5Xcml0ZVN0cmluZyhmaWxlbmFtZSk7ICAvLyBmaWxlIG5hbWUKKyAgfQorICB1aW50MzIgZGlyX2xlbiA9IG91dHB1dC5CeXRlQ291bnQoKTsKKworICAvLyB3cml0ZSBlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkgbWFya2VyCisgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKDB4MDYwNTRiNTApOyAgLy8gbWFnaWMKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGRpc2sgbnVtYmVyCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBkaXNrIHdpdGggc3RhcnQgb2YgY2VudHJhbCBkaXJlY3RvcnkKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCBudW1fZW50cmllcyk7ICAvLyBjZW50cmFsIGRpcmVjdG9yeSBlbnRyaWVzICh0aGlzIGRpc2spCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgbnVtX2VudHJpZXMpOyAgLy8gY2VudHJhbCBkaXJlY3RvcnkgZW50cmllcyAodG90YWwpCisgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKGRpcl9sZW4pOyAgLy8gY2VudHJhbCBkaXJlY3RvcnkgYnl0ZSBzaXplCisgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKGRpcl9vZnMpOyAgLy8gY2VudHJhbCBkaXJlY3Rvcnkgb2Zmc2V0CisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAgLy8gY29tbWVudCBsZW5ndGgKKworICByZXR1cm4gb3V0cHV0LkhhZEVycm9yKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwMmU1MDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaApAQCAtMCwwICsxLDkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworY2xhc3MgWmlwV3JpdGVyIHsKKyBwdWJsaWM6CisgIFppcFdyaXRlcihpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIHJhd19vdXRwdXQpOworICB+WmlwV3JpdGVyKCk7CisKKyAgYm9vbCBXcml0ZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGNvbnRlbnRzKTsKKyAgYm9vbCBXcml0ZURpcmVjdG9yeSgpOworCisgcHJpdmF0ZToKKyAgc3RydWN0IEZpbGVJbmZvIHsKKyAgICBzdHJpbmcgbmFtZTsKKyAgICB1aW50MzIgb2Zmc2V0OworICAgIHVpbnQzMiBzaXplOworICAgIHVpbnQzMiBjcmMzMjsKKyAgfTsKKworICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIHJhd19vdXRwdXRfOworICB2ZWN0b3I8RmlsZUluZm8+IGZpbGVzXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZkYWNkOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5jYwpAQCAtMCwwICsxLDU5NjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHNldD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxsaW1pdHM+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworI3VuZGVmIFBBQ0tBR0UgIC8vIGF1dG9oZWFkZXIgI2RlZmluZXMgdGhpcy4gIDooCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlCitGaWVsZERlc2NyaXB0b3I6OmtUeXBlVG9DcHBUeXBlTWFwW01BWF9UWVBFICsgMV0gPSB7CisgIHN0YXRpY19jYXN0PENwcFR5cGU+KDApLCAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisKKyAgQ1BQVFlQRV9ET1VCTEUsICAgLy8gVFlQRV9ET1VCTEUKKyAgQ1BQVFlQRV9GTE9BVCwgICAgLy8gVFlQRV9GTE9BVAorICBDUFBUWVBFX0lOVDY0LCAgICAvLyBUWVBFX0lOVDY0CisgIENQUFRZUEVfVUlOVDY0LCAgIC8vIFRZUEVfVUlOVDY0CisgIENQUFRZUEVfSU5UMzIsICAgIC8vIFRZUEVfSU5UMzIKKyAgQ1BQVFlQRV9VSU5UNjQsICAgLy8gVFlQRV9GSVhFRDY0CisgIENQUFRZUEVfVUlOVDMyLCAgIC8vIFRZUEVfRklYRUQzMgorICBDUFBUWVBFX0JPT0wsICAgICAvLyBUWVBFX0JPT0wKKyAgQ1BQVFlQRV9TVFJJTkcsICAgLy8gVFlQRV9TVFJJTkcKKyAgQ1BQVFlQRV9NRVNTQUdFLCAgLy8gVFlQRV9HUk9VUAorICBDUFBUWVBFX01FU1NBR0UsICAvLyBUWVBFX01FU1NBR0UKKyAgQ1BQVFlQRV9TVFJJTkcsICAgLy8gVFlQRV9CWVRFUworICBDUFBUWVBFX1VJTlQzMiwgICAvLyBUWVBFX1VJTlQzMgorICBDUFBUWVBFX0VOVU0sICAgICAvLyBUWVBFX0VOVU0KKyAgQ1BQVFlQRV9JTlQzMiwgICAgLy8gVFlQRV9TRklYRUQzMgorICBDUFBUWVBFX0lOVDY0LCAgICAvLyBUWVBFX1NGSVhFRDY0CisgIENQUFRZUEVfSU5UMzIsICAgIC8vIFRZUEVfU0lOVDMyCisgIENQUFRZUEVfSU5UNjQsICAgIC8vIFRZUEVfU0lOVDY0Cit9OworCitjb25zdCBjaGFyICogY29uc3QgRmllbGREZXNjcmlwdG9yOjprVHlwZVRvTmFtZVtNQVhfVFlQRSArIDFdID0geworICAiRVJST1IiLCAgICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisKKyAgImRvdWJsZSIsICAgIC8vIFRZUEVfRE9VQkxFCisgICJmbG9hdCIsICAgICAvLyBUWVBFX0ZMT0FUCisgICJpbnQ2NCIsICAgICAvLyBUWVBFX0lOVDY0CisgICJ1aW50NjQiLCAgICAvLyBUWVBFX1VJTlQ2NAorICAiaW50MzIiLCAgICAgLy8gVFlQRV9JTlQzMgorICAiZml4ZWQ2NCIsICAgLy8gVFlQRV9GSVhFRDY0CisgICJmaXhlZDMyIiwgICAvLyBUWVBFX0ZJWEVEMzIKKyAgImJvb2wiLCAgICAgIC8vIFRZUEVfQk9PTAorICAic3RyaW5nIiwgICAgLy8gVFlQRV9TVFJJTkcKKyAgImdyb3VwIiwgICAgIC8vIFRZUEVfR1JPVVAKKyAgIm1lc3NhZ2UiLCAgIC8vIFRZUEVfTUVTU0FHRQorICAiYnl0ZXMiLCAgICAgLy8gVFlQRV9CWVRFUworICAidWludDMyIiwgICAgLy8gVFlQRV9VSU5UMzIKKyAgImVudW0iLCAgICAgIC8vIFRZUEVfRU5VTQorICAic2ZpeGVkMzIiLCAgLy8gVFlQRV9TRklYRUQzMgorICAic2ZpeGVkNjQiLCAgLy8gVFlQRV9TRklYRUQ2NAorICAic2ludDMyIiwgICAgLy8gVFlQRV9TSU5UMzIKKyAgInNpbnQ2NCIsICAgIC8vIFRZUEVfU0lOVDY0Cit9OworCitjb25zdCBjaGFyICogY29uc3QgRmllbGREZXNjcmlwdG9yOjprQ3BwVHlwZVRvTmFtZVtNQVhfQ1BQVFlQRSArIDFdID0geworICAiRVJST1IiLCAgICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisKKyAgImludDMyIiwgICAgIC8vIENQUFRZUEVfSU5UMzIKKyAgImludDY0IiwgICAgIC8vIENQUFRZUEVfSU5UNjQKKyAgInVpbnQzMiIsICAgIC8vIENQUFRZUEVfVUlOVDMyCisgICJ1aW50NjQiLCAgICAvLyBDUFBUWVBFX1VJTlQ2NAorICAiZG91YmxlIiwgICAgLy8gQ1BQVFlQRV9ET1VCTEUKKyAgImZsb2F0IiwgICAgIC8vIENQUFRZUEVfRkxPQVQKKyAgImJvb2wiLCAgICAgIC8vIENQUFRZUEVfQk9PTAorICAiZW51bSIsICAgICAgLy8gQ1BQVFlQRV9FTlVNCisgICJzdHJpbmciLCAgICAvLyBDUFBUWVBFX1NUUklORworICAibWVzc2FnZSIsICAgLy8gQ1BQVFlQRV9NRVNTQUdFCit9OworCitjb25zdCBjaGFyICogY29uc3QgRmllbGREZXNjcmlwdG9yOjprTGFiZWxUb05hbWVbTUFYX0xBQkVMICsgMV0gPSB7CisgICJFUlJPUiIsICAgICAvLyAwIGlzIHJlc2VydmVkIGZvciBlcnJvcnMKKworICAib3B0aW9uYWwiLCAgLy8gTEFCRUxfT1BUSU9OQUwKKyAgInJlcXVpcmVkIiwgIC8vIExBQkVMX1JFUVVJUkVECisgICJyZXBlYXRlZCIsICAvLyBMQUJFTF9SRVBFQVRFRAorfTsKKworY29uc3QgY2hhciogRmlsZURlc2NyaXB0b3I6OlN5bnRheE5hbWUoRmlsZURlc2NyaXB0b3I6OlN5bnRheCBzeW50YXgpIHsKKyAgc3dpdGNoIChzeW50YXgpIHsKKyAgICBjYXNlIFNZTlRBWF9QUk9UTzI6CisgICAgICByZXR1cm4gInByb3RvMiI7CisgICAgY2FzZSBTWU5UQVhfUFJPVE8zOgorICAgICAgcmV0dXJuICJwcm90bzMiOworICAgIGNhc2UgU1lOVEFYX1VOS05PV046CisgICAgICByZXR1cm4gInVua25vd24iOworICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJjYW4ndCByZWFjaCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGtOb25MaW5rZWRXZWFrTWVzc2FnZVJlcGxhY2VtZW50TmFtZSA9ICJnb29nbGUucHJvdG9idWYuRW1wdHkiOworCisjaWZuZGVmIF9NU0NfVkVSICAvLyBNU1ZDIGRvZXNuJ3QgbmVlZCB0aGVzZSBhbmQgd29uJ3QgZXZlbiBhY2NlcHQgdGhlbS4KK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3I6OmtNYXhOdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yOjprRmlyc3RSZXNlcnZlZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3I6OmtMYXN0UmVzZXJ2ZWROdW1iZXI7CisjZW5kaWYKKworbmFtZXNwYWNlIHsKKworc3RyaW5nIFRvQ2FtZWxDYXNlKGNvbnN0IHN0cmluZyYgaW5wdXQsIGJvb2wgbG93ZXJfZmlyc3QpIHsKKyAgYm9vbCBjYXBpdGFsaXplX25leHQgPSAhbG93ZXJfZmlyc3Q7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNlcnZlKGlucHV0LnNpemUoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgIGlmIChpbnB1dFtpXSA9PSAnXycpIHsKKyAgICAgIGNhcGl0YWxpemVfbmV4dCA9IHRydWU7CisgICAgfSBlbHNlIGlmIChjYXBpdGFsaXplX25leHQpIHsKKyAgICAgIC8vIE5vdGU6ICBJIGRpc3RydXN0IGN0eXBlLmggZHVlIHRvIGxvY2FsZXMuCisgICAgICBpZiAoJ2EnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICd6JykgeworICAgICAgICByZXN1bHQucHVzaF9iYWNrKGlucHV0W2ldIC0gJ2EnICsgJ0EnKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soaW5wdXRbaV0pOworICAgICAgfQorICAgICAgY2FwaXRhbGl6ZV9uZXh0ID0gZmFsc2U7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdC5wdXNoX2JhY2soaW5wdXRbaV0pOworICAgIH0KKyAgfQorCisgIC8vIExvd2VyLWNhc2UgdGhlIGZpcnN0IGxldHRlci4KKyAgaWYgKGxvd2VyX2ZpcnN0ICYmICFyZXN1bHQuZW1wdHkoKSAmJiAnQScgPD0gcmVzdWx0WzBdICYmIHJlc3VsdFswXSA8PSAnWicpIHsKKyAgICAgIHJlc3VsdFswXSA9IHJlc3VsdFswXSAtICdBJyArICdhJzsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEEgRGVzY3JpcHRvclBvb2wgY29udGFpbnMgYSBidW5jaCBvZiBoYXNoX21hcHMgdG8gaW1wbGVtZW50IHRoZQorLy8gdmFyaW91cyBGaW5kKkJ5KigpIG1ldGhvZHMuICBTaW5jZSBoYXNodGFibGUgbG9va3VwcyBhcmUgTygxKSwgaXQncworLy8gbW9zdCBlZmZpY2llbnQgdG8gY29uc3RydWN0IGEgZml4ZWQgc2V0IG9mIGxhcmdlIGhhc2hfbWFwcyB1c2VkIGJ5CisvLyBhbGwgb2JqZWN0cyBpbiB0aGUgcG9vbCByYXRoZXIgdGhhbiBjb25zdHJ1Y3Qgb25lIG9yIG1vcmUgc21hbGwKKy8vIGhhc2hfbWFwcyBmb3IgZWFjaCBvYmplY3QuCisvLworLy8gVGhlIGtleXMgdG8gdGhlc2UgaGFzaF9tYXBzIGFyZSAocGFyZW50LCBuYW1lKSBvciAocGFyZW50LCBudW1iZXIpCisvLyBwYWlycy4gIFVuZm9ydHVuYXRlbHkgU1RMIGRvZXNuJ3QgcHJvdmlkZSBoYXNoIGZ1bmN0aW9ucyBmb3IgcGFpcjw+LAorLy8gc28gd2UgbXVzdCBpbnZlbnQgb3VyIG93bi4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBVc2UgU3RyaW5nUGllY2UgcmF0aGVyIHRoYW4gY29uc3QgY2hhciogaW4ga2V5cz8gIEl0IHdvdWxkCisvLyAgIGJlIGEgbG90IGNsZWFuZXIgYnV0IHdlJ2QganVzdCBoYXZlIHRvIGNvbnZlcnQgaXQgYmFjayB0byBjb25zdCBjaGFyKgorLy8gICBmb3IgdGhlIG9wZW4gc291cmNlIHJlbGVhc2UuCisKK3R5cGVkZWYgcGFpcjxjb25zdCB2b2lkKiwgY29uc3QgY2hhcio+IFBvaW50ZXJTdHJpbmdQYWlyOworCitzdHJ1Y3QgUG9pbnRlclN0cmluZ1BhaXJFcXVhbCB7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYS5maXJzdCA9PSBiLmZpcnN0ICYmIHN0cmNtcChhLnNlY29uZCwgYi5zZWNvbmQpID09IDA7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFBhaXJUeXBlPgorc3RydWN0IFBvaW50ZXJJbnRlZ2VyUGFpckhhc2ggeworICBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBQYWlyVHlwZSYgcCkgY29uc3QgeworICAgIC8vIEZJWE1FKGtlbnRvbik6ICBXaGF0IGlzIHRoZSBiZXN0IHdheSB0byBjb21wdXRlIHRoaXMgaGFzaD8gIEkgaGF2ZQorICAgIC8vIG5vIGlkZWEhICBUaGlzIHNlZW1zIGEgYml0IGJldHRlciB0aGFuIGFuIFhPUi4KKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxpbnRwdHJfdD4ocC5maXJzdCkgKiAoKDEgPDwgMTYpIC0gMSkgKyBwLnNlY29uZDsKKyAgfQorCisjaWZkZWYgX01TQ19WRVIKKyAgLy8gVXNlZCBvbmx5IGJ5IE1TVkMgYW5kIHBsYXRmb3JtcyB3aGVyZSBoYXNoX21hcCBpcyBub3QgYXZhaWxhYmxlLgorICBzdGF0aWMgY29uc3Qgc2l6ZV90IGJ1Y2tldF9zaXplID0gNDsKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBtaW5fYnVja2V0cyA9IDg7CisjZW5kaWYKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBQYWlyVHlwZSYgYSwgY29uc3QgUGFpclR5cGUmIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYS5maXJzdCA8IGIuZmlyc3QgfHwKKyAgICAgICAgICAoYS5maXJzdCA9PSBiLmZpcnN0ICYmIGEuc2Vjb25kIDwgYi5zZWNvbmQpOworICB9Cit9OworCit0eXBlZGVmIHBhaXI8Y29uc3QgRGVzY3JpcHRvciosIGludD4gRGVzY3JpcHRvckludFBhaXI7Cit0eXBlZGVmIHBhaXI8Y29uc3QgRW51bURlc2NyaXB0b3IqLCBpbnQ+IEVudW1JbnRQYWlyOworCitzdHJ1Y3QgUG9pbnRlclN0cmluZ1BhaXJIYXNoIHsKKyAgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIHApIGNvbnN0IHsKKyAgICAvLyBGSVhNRShrZW50b24pOiAgV2hhdCBpcyB0aGUgYmVzdCB3YXkgdG8gY29tcHV0ZSB0aGlzIGhhc2g/ICBJIGhhdmUKKyAgICAvLyBubyBpZGVhISAgVGhpcyBzZWVtcyBhIGJpdCBiZXR0ZXIgdGhhbiBhbiBYT1IuCisgICAgaGFzaDxjb25zdCBjaGFyKj4gY3N0cmluZ19oYXNoOworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGludHB0cl90PihwLmZpcnN0KSAqICgoMSA8PCAxNikgLSAxKSArCisgICAgICAgICAgIGNzdHJpbmdfaGFzaChwLnNlY29uZCk7CisgIH0KKworI2lmZGVmIF9NU0NfVkVSCisgIC8vIFVzZWQgb25seSBieSBNU1ZDIGFuZCBwbGF0Zm9ybXMgd2hlcmUgaGFzaF9tYXAgaXMgbm90IGF2YWlsYWJsZS4KKyAgc3RhdGljIGNvbnN0IHNpemVfdCBidWNrZXRfc2l6ZSA9IDQ7CisgIHN0YXRpYyBjb25zdCBzaXplX3QgbWluX2J1Y2tldHMgPSA4OworI2VuZGlmCisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGIpIGNvbnN0IHsKKyAgICBpZiAoYS5maXJzdCA8IGIuZmlyc3QpIHJldHVybiB0cnVlOworICAgIGlmIChhLmZpcnN0ID4gYi5maXJzdCkgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBzdHJjbXAoYS5zZWNvbmQsIGIuc2Vjb25kKSA8IDA7CisgIH0KK307CisKKworc3RydWN0IFN5bWJvbCB7CisgIGVudW0gVHlwZSB7CisgICAgTlVMTF9TWU1CT0wsIE1FU1NBR0UsIEZJRUxELCBPTkVPRiwgRU5VTSwgRU5VTV9WQUxVRSwgU0VSVklDRSwgTUVUSE9ELAorICAgIFBBQ0tBR0UKKyAgfTsKKyAgVHlwZSB0eXBlOworICB1bmlvbiB7CisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcjsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yOworICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZV9kZXNjcmlwdG9yOworICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHBhY2thZ2VfZmlsZV9kZXNjcmlwdG9yOworICB9OworCisgIGlubGluZSBTeW1ib2woKSA6IHR5cGUoTlVMTF9TWU1CT0wpIHsgZGVzY3JpcHRvciA9IE5VTEw7IH0KKyAgaW5saW5lIGJvb2wgSXNOdWxsKCkgY29uc3QgeyByZXR1cm4gdHlwZSA9PSBOVUxMX1NZTUJPTDsgfQorICBpbmxpbmUgYm9vbCBJc1R5cGUoKSBjb25zdCB7CisgICAgcmV0dXJuIHR5cGUgPT0gTUVTU0FHRSB8fCB0eXBlID09IEVOVU07CisgIH0KKyAgaW5saW5lIGJvb2wgSXNBZ2dyZWdhdGUoKSBjb25zdCB7CisgICAgcmV0dXJuIHR5cGUgPT0gTUVTU0FHRSB8fCB0eXBlID09IFBBQ0tBR0UKKyAgICAgICAgfHwgdHlwZSA9PSBFTlVNIHx8IHR5cGUgPT0gU0VSVklDRTsKKyAgfQorCisjZGVmaW5lIENPTlNUUlVDVE9SKFRZUEUsIFRZUEVfQ09OU1RBTlQsIEZJRUxEKSAgXAorICBpbmxpbmUgZXhwbGljaXQgU3ltYm9sKGNvbnN0IFRZUEUqIHZhbHVlKSB7ICAgIFwKKyAgICB0eXBlID0gVFlQRV9DT05TVEFOVDsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGhpcy0+RklFTEQgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKKyAgQ09OU1RSVUNUT1IoRGVzY3JpcHRvciAgICAgICAgICwgTUVTU0FHRSAgICwgZGVzY3JpcHRvciAgICAgICAgICAgICApCisgIENPTlNUUlVDVE9SKEZpZWxkRGVzY3JpcHRvciAgICAsIEZJRUxEICAgICAsIGZpZWxkX2Rlc2NyaXB0b3IgICAgICAgKQorICBDT05TVFJVQ1RPUihPbmVvZkRlc2NyaXB0b3IgICAgLCBPTkVPRiAgICAgLCBvbmVvZl9kZXNjcmlwdG9yICAgICAgICkKKyAgQ09OU1RSVUNUT1IoRW51bURlc2NyaXB0b3IgICAgICwgRU5VTSAgICAgICwgZW51bV9kZXNjcmlwdG9yICAgICAgICApCisgIENPTlNUUlVDVE9SKEVudW1WYWx1ZURlc2NyaXB0b3IsIEVOVU1fVkFMVUUsIGVudW1fdmFsdWVfZGVzY3JpcHRvciAgKQorICBDT05TVFJVQ1RPUihTZXJ2aWNlRGVzY3JpcHRvciAgLCBTRVJWSUNFICAgLCBzZXJ2aWNlX2Rlc2NyaXB0b3IgICAgICkKKyAgQ09OU1RSVUNUT1IoTWV0aG9kRGVzY3JpcHRvciAgICwgTUVUSE9EICAgICwgbWV0aG9kX2Rlc2NyaXB0b3IgICAgICApCisgIENPTlNUUlVDVE9SKEZpbGVEZXNjcmlwdG9yICAgICAsIFBBQ0tBR0UgICAsIHBhY2thZ2VfZmlsZV9kZXNjcmlwdG9yKQorI3VuZGVmIENPTlNUUlVDVE9SCisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIEdldEZpbGUoKSBjb25zdCB7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIE5VTExfU1lNQk9MOiByZXR1cm4gTlVMTDsKKyAgICAgIGNhc2UgTUVTU0FHRSAgICA6IHJldHVybiBkZXNjcmlwdG9yICAgICAgICAgICAtPmZpbGUoKTsKKyAgICAgIGNhc2UgRklFTEQgICAgICA6IHJldHVybiBmaWVsZF9kZXNjcmlwdG9yICAgICAtPmZpbGUoKTsKKyAgICAgIGNhc2UgT05FT0YgICAgICA6IHJldHVybiBvbmVvZl9kZXNjcmlwdG9yICAgICAtPmNvbnRhaW5pbmdfdHlwZSgpLT5maWxlKCk7CisgICAgICBjYXNlIEVOVU0gICAgICAgOiByZXR1cm4gZW51bV9kZXNjcmlwdG9yICAgICAgLT5maWxlKCk7CisgICAgICBjYXNlIEVOVU1fVkFMVUUgOiByZXR1cm4gZW51bV92YWx1ZV9kZXNjcmlwdG9yLT50eXBlKCktPmZpbGUoKTsKKyAgICAgIGNhc2UgU0VSVklDRSAgICA6IHJldHVybiBzZXJ2aWNlX2Rlc2NyaXB0b3IgICAtPmZpbGUoKTsKKyAgICAgIGNhc2UgTUVUSE9EICAgICA6IHJldHVybiBtZXRob2RfZGVzY3JpcHRvciAgICAtPnNlcnZpY2UoKS0+ZmlsZSgpOworICAgICAgY2FzZSBQQUNLQUdFICAgIDogcmV0dXJuIHBhY2thZ2VfZmlsZV9kZXNjcmlwdG9yOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKworY29uc3QgU3ltYm9sIGtOdWxsU3ltYm9sOworCit0eXBlZGVmIGhhc2hfbWFwPGNvbnN0IGNoYXIqLCBTeW1ib2wsCisgICAgICAgICAgICAgICAgIGhhc2g8Y29uc3QgY2hhcio+LCBzdHJlcT4KKyAgU3ltYm9sc0J5TmFtZU1hcDsKK3R5cGVkZWYgaGFzaF9tYXA8UG9pbnRlclN0cmluZ1BhaXIsIFN5bWJvbCwKKyAgICAgICAgICAgICAgICAgUG9pbnRlclN0cmluZ1BhaXJIYXNoLCBQb2ludGVyU3RyaW5nUGFpckVxdWFsPgorICBTeW1ib2xzQnlQYXJlbnRNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPGNvbnN0IGNoYXIqLCBjb25zdCBGaWxlRGVzY3JpcHRvciosCisgICAgICAgICAgICAgICAgIGhhc2g8Y29uc3QgY2hhcio+LCBzdHJlcT4KKyAgRmlsZXNCeU5hbWVNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPFBvaW50ZXJTdHJpbmdQYWlyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqLAorICAgICAgICAgICAgICAgICBQb2ludGVyU3RyaW5nUGFpckhhc2gsIFBvaW50ZXJTdHJpbmdQYWlyRXF1YWw+CisgIEZpZWxkc0J5TmFtZU1hcDsKK3R5cGVkZWYgaGFzaF9tYXA8RGVzY3JpcHRvckludFBhaXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciosCisgICAgICAgICAgICAgICAgIFBvaW50ZXJJbnRlZ2VyUGFpckhhc2g8RGVzY3JpcHRvckludFBhaXI+ID4KKyAgRmllbGRzQnlOdW1iZXJNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPEVudW1JbnRQYWlyLCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiwKKyAgICAgICAgICAgICAgICAgUG9pbnRlckludGVnZXJQYWlySGFzaDxFbnVtSW50UGFpcj4gPgorICBFbnVtVmFsdWVzQnlOdW1iZXJNYXA7CisvLyBUaGlzIGlzIGEgbWFwIHJhdGhlciB0aGFuIGEgaGFzaF9tYXAsIHNpbmNlIHdlIHVzZSBpdCB0byBpdGVyYXRlCisvLyB0aHJvdWdoIGFsbCB0aGUgZXh0ZW5zaW9ucyB0aGF0IGV4dGVuZCBhIGdpdmVuIERlc2NyaXB0b3IsIGFuZCBhbgorLy8gb3JkZXJlZCBkYXRhIHN0cnVjdHVyZSB0aGF0IGltcGxlbWVudHMgbG93ZXJfYm91bmQgaXMgY29udmVuaWVudAorLy8gZm9yIHRoYXQuCit0eXBlZGVmIG1hcDxEZXNjcmlwdG9ySW50UGFpciwgY29uc3QgRmllbGREZXNjcmlwdG9yKj4KKyAgRXh0ZW5zaW9uc0dyb3VwZWRCeURlc2NyaXB0b3JNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPHN0cmluZywgY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qPiBMb2NhdGlvbnNCeVBhdGhNYXA7CisKK3NldDxzdHJpbmc+KiBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfID0gTlVMTDsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UoYWxsb3dlZF9wcm90bzNfZXh0ZW5kZWVzX2luaXRfKTsKKwordm9pZCBEZWxldGVBbGxvd2VkUHJvdG8zRXh0ZW5kZWUoKSB7CisgIGRlbGV0ZSBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfOworfQorCit2b2lkIEluaXRBbGxvd2VkUHJvdG8zRXh0ZW5kZWUoKSB7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18gPSBuZXcgc2V0PHN0cmluZz47CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyIpOworICBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfLT5pbnNlcnQoImdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyIpOworICBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfLT5pbnNlcnQoImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMiKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJkRlbGV0ZUFsbG93ZWRQcm90bzNFeHRlbmRlZSk7Cit9CisKKy8vIENoZWNrcyB3aGV0aGVyIHRoZSBleHRlbmRlZSB0eXBlIGlzIGFsbG93ZWQgaW4gcHJvdG8zLgorLy8gT25seSBleHRlbnNpb25zIHRvIGRlc2NyaXB0b3Igb3B0aW9ucyBhcmUgYWxsb3dlZC4gV2UgdXNlIG5hbWUgY29tcGFyaXNvbgorLy8gaW5zdGVhZCBvZiBjb21wYXJpbmcgdGhlIGRlc2NyaXB0b3IgZGlyZWN0bHkgYmVjYXVzZSB0aGUgZXh0ZW5zaW9ucyBtYXkgYmUKKy8vIGRlZmluZWQgaW4gYSBkaWZmZXJlbnQgcG9vbC4KK2Jvb2wgQWxsb3dlZEV4dGVuZGVlSW5Qcm90bzMoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc19pbml0XywgJkluaXRBbGxvd2VkUHJvdG8zRXh0ZW5kZWUpOworICByZXR1cm4gYWxsb3dlZF9wcm90bzNfZXh0ZW5kZWVzXy0+ZmluZChuYW1lKSAhPQorICAgICAgICAgYWxsb3dlZF9wcm90bzNfZXh0ZW5kZWVzXy0+ZW5kKCk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGVzY3JpcHRvclBvb2w6OlRhYmxlcworCitjbGFzcyBEZXNjcmlwdG9yUG9vbDo6VGFibGVzIHsKKyBwdWJsaWM6CisgIFRhYmxlcygpOworICB+VGFibGVzKCk7CisKKyAgLy8gUmVjb3JkIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB0YWJsZXMgdG8gdGhlIHN0YWNrIG9mIGNoZWNrcG9pbnRzLgorICAvLyBFYWNoIGNhbGwgdG8gQWRkQ2hlY2twb2ludCgpIG11c3QgYmUgcGFpcmVkIHdpdGggZXhhY3RseSBvbmUgY2FsbCB0byBlaXRoZXIKKyAgLy8gQ2xlYXJMYXN0Q2hlY2twb2ludCgpIG9yIFJvbGxiYWNrVG9MYXN0Q2hlY2twb2ludCgpLgorICAvLworICAvLyBUaGlzIGlzIHVzZWQgd2hlbiBidWlsZGluZyBmaWxlcywgc2luY2Ugc29tZSBraW5kcyBvZiB2YWxpZGF0aW9uIGVycm9ycworICAvLyBjYW5ub3QgYmUgZGV0ZWN0ZWQgdW50aWwgdGhlIGZpbGUncyBkZXNjcmlwdG9ycyBoYXZlIGFscmVhZHkgYmVlbiBhZGRlZCB0bworICAvLyB0aGUgdGFibGVzLgorICAvLworICAvLyBUaGlzIHN1cHBvcnRzIHJlY3Vyc2l2ZSBjaGVja3BvaW50cywgc2luY2UgYnVpbGRpbmcgYSBmaWxlIG1heSB0cmlnZ2VyCisgIC8vIHJlY3Vyc2l2ZSBidWlsZGluZyBvZiBvdGhlciBmaWxlcy4gTm90ZSB0aGF0IHJlY3Vyc2l2ZSBjaGVja3BvaW50cyBhcmUgbm90CisgIC8vIG5vcm1hbGx5IG5lY2Vzc2FyeTsgZXhwbGljaXQgZGVwZW5kZW5jaWVzIGFyZSBidWlsdCBwcmlvciB0byBjaGVja3BvaW50aW5nLgorICAvLyBTbyBhbHRob3VnaCB3ZSByZWN1cnNpdmVseSBidWlsZCB0cmFuc2l0aXZlIGltcG9ydHMsIHRoZXJlIGlzIGF0IG1vc3Qgb25lCisgIC8vIGNoZWNrcG9pbnQgaW4gdGhlIHN0YWNrIGR1cmluZyBkZXBlbmRlbmN5IGJ1aWxkaW5nLgorICAvLworICAvLyBSZWN1cnNpdmUgY2hlY2twb2ludHMgb25seSBhcmlzZSBkdXJpbmcgY3Jvc3MtbGlua2luZyBvZiB0aGUgZGVzY3JpcHRvcnMuCisgIC8vIFN5bWJvbCByZWZlcmVuY2VzIG11c3QgYmUgcmVzb2x2ZWQsIHZpYSBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbCBhbmQKKyAgLy8gZnJpZW5kcy4gSWYgdGhlIHBlbmRpbmcgZmlsZSByZWZlcmVuY2VzIGFuIHVua25vd24gc3ltYm9sCisgIC8vIChlLmcuLCBpdCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgcGVuZGluZyBmaWxlJ3MgZXhwbGljaXQgZGVwZW5kZW5jaWVzKSwgYW5kCisgIC8vIHRoZSBwb29sIGlzIHVzaW5nIGEgZmFsbGJhY2sgZGF0YWJhc2UsIGFuZCB0aGF0IGRhdGFiYXNlIGNvbnRhaW5zIGEgZmlsZQorICAvLyBkZWZpbmluZyB0aGF0IHN5bWJvbCwgYW5kIHRoYXQgZmlsZSBoYXMgbm90IHlldCBiZWVuIGJ1aWx0IGJ5IHRoZSBwb29sLAorICAvLyB0aGUgcG9vbCBidWlsZHMgdGhlIGZpbGUgZHVyaW5nIGNyb3NzLWxpbmtpbmcsIGxlYWRpbmcgdG8gYW5vdGhlcgorICAvLyBjaGVja3BvaW50LgorICB2b2lkIEFkZENoZWNrcG9pbnQoKTsKKworICAvLyBNYXJrIHRoZSBsYXN0IGNoZWNrcG9pbnQgYXMgaGF2aW5nIGNsZWFyZWQgc3VjY2Vzc2Z1bGx5LCByZW1vdmluZyBpdCBmcm9tCisgIC8vIHRoZSBzdGFjay4gSWYgdGhlIHN0YWNrIGlzIGVtcHR5LCBhbGwgcGVuZGluZyBzeW1ib2xzIHdpbGwgYmUgY29tbWl0dGVkLgorICAvLworICAvLyBOb3RlIHRoYXQgdGhpcyBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCB0aGUgc3ltYm9scyBhZGRlZCBzaW5jZSB0aGUgbGFzdAorICAvLyBjaGVja3BvaW50IHdvbid0IGJlIHJvbGxlZCBiYWNrOiBpZiBhIGNoZWNrcG9pbnQgZ2V0cyByb2xsZWQgYmFjaywKKyAgLy8gZXZlcnl0aGluZyBwYXN0IHRoYXQgcG9pbnQgZ2V0cyByb2xsZWQgYmFjaywgaW5jbHVkaW5nIHN5bWJvbHMgYWRkZWQgYWZ0ZXIKKyAgLy8gY2hlY2twb2ludHMgdGhhdCB3ZXJlIHB1c2hlZCBvbnRvIHRoZSBzdGFjayBhZnRlciBpdCBhbmQgbWFya2VkIGFzIGNsZWFyZWQuCisgIHZvaWQgQ2xlYXJMYXN0Q2hlY2twb2ludCgpOworCisgIC8vIFJvbGwgYmFjayB0aGUgVGFibGVzIHRvIHRoZSBzdGF0ZSBvZiB0aGUgY2hlY2twb2ludCBhdCB0aGUgdG9wIG9mIHRoZQorICAvLyBzdGFjaywgcmVtb3ZpbmcgZXZlcnl0aGluZyB0aGF0IHdhcyBhZGRlZCBhZnRlciB0aGF0IHBvaW50LgorICB2b2lkIFJvbGxiYWNrVG9MYXN0Q2hlY2twb2ludCgpOworCisgIC8vIFRoZSBzdGFjayBvZiBmaWxlcyB3aGljaCBhcmUgY3VycmVudGx5IGJlaW5nIGJ1aWx0LiAgVXNlZCB0byBkZXRlY3QKKyAgLy8gY3ljbGljIGRlcGVuZGVuY2llcyB3aGVuIGxvYWRpbmcgZmlsZXMgZnJvbSBhIERlc2NyaXB0b3JEYXRhYmFzZS4gIE5vdAorICAvLyB1c2VkIHdoZW4gZmFsbGJhY2tfZGF0YWJhc2VfID09IE5VTEwuCisgIHZlY3RvcjxzdHJpbmc+IHBlbmRpbmdfZmlsZXNfOworCisgIC8vIEEgc2V0IG9mIGZpbGVzIHdoaWNoIHdlIGhhdmUgdHJpZWQgdG8gbG9hZCBmcm9tIHRoZSBmYWxsYmFjayBkYXRhYmFzZQorICAvLyBhbmQgZW5jb3VudGVyZWQgZXJyb3JzLiAgV2Ugd2lsbCBub3QgYXR0ZW1wdCB0byBsb2FkIHRoZW0gYWdhaW4gZHVyaW5nCisgIC8vIGV4ZWN1dGlvbiBvZiB0aGUgY3VycmVudCBwdWJsaWMgQVBJIGNhbGwsIGJ1dCBmb3IgY29tcGF0aWJpbGl0eSB3aXRoCisgIC8vIGxlZ2FjeSBjbGllbnRzLCB0aGlzIGlzIGNsZWFyZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIHB1YmxpYyBBUEkgY2FsbC4KKyAgLy8gTm90IHVzZWQgd2hlbiBmYWxsYmFja19kYXRhYmFzZV8gPT0gTlVMTC4KKyAgaGFzaF9zZXQ8c3RyaW5nPiBrbm93bl9iYWRfZmlsZXNfOworCisgIC8vIEEgc2V0IG9mIHN5bWJvbHMgd2hpY2ggd2UgaGF2ZSB0cmllZCB0byBsb2FkIGZyb20gdGhlIGZhbGxiYWNrIGRhdGFiYXNlCisgIC8vIGFuZCBlbmNvdW50ZXJlZCBlcnJvcnMuIFdlIHdpbGwgbm90IGF0dGVtcHQgdG8gbG9hZCB0aGVtIGFnYWluIGR1cmluZworICAvLyBleGVjdXRpb24gb2YgdGhlIGN1cnJlbnQgcHVibGljIEFQSSBjYWxsLCBidXQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aAorICAvLyBsZWdhY3kgY2xpZW50cywgdGhpcyBpcyBjbGVhcmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBwdWJsaWMgQVBJIGNhbGwuCisgIGhhc2hfc2V0PHN0cmluZz4ga25vd25fYmFkX3N5bWJvbHNfOworCisgIC8vIFRoZSBzZXQgb2YgZGVzY3JpcHRvcnMgZm9yIHdoaWNoIHdlJ3ZlIGFscmVhZHkgbG9hZGVkIHRoZSBmdWxsCisgIC8vIHNldCBvZiBleHRlbnNpb25zIG51bWJlcnMgZnJvbSBmYWxsYmFja19kYXRhYmFzZV8uCisgIGhhc2hfc2V0PGNvbnN0IERlc2NyaXB0b3IqPiBleHRlbnNpb25zX2xvYWRlZF9mcm9tX2RiXzsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBGaW5kaW5nIGl0ZW1zLgorCisgIC8vIEZpbmQgc3ltYm9scy4gIFRoaXMgcmV0dXJucyBhIG51bGwgU3ltYm9sIChzeW1ib2wuSXNOdWxsKCkgaXMgdHJ1ZSkKKyAgLy8gaWYgbm90IGZvdW5kLgorICBpbmxpbmUgU3ltYm9sIEZpbmRTeW1ib2woY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0OworCisgIC8vIFRoaXMgaW1wbGVtZW50cyB0aGUgYm9keSBvZiBEZXNjcmlwdG9yUG9vbDo6RmluZCpCeU5hbWUoKS4gIEl0IHNob3VsZAorICAvLyByZWFsbHkgYmUgYSBwcml2YXRlIG1ldGhvZCBvZiBEZXNjcmlwdG9yUG9vbCwgYnV0IHRoYXQgd291bGQgcmVxdWlyZQorICAvLyBkZWNsYXJpbmcgU3ltYm9sIGluIGRlc2NyaXB0b3IuaCwgd2hpY2ggd291bGQgZHJhZyBhbGwga2luZHMgb2Ygb3RoZXIKKyAgLy8gc3R1ZmYgaW50byB0aGUgaGVhZGVyLiAgWWF5IEMrKy4KKyAgU3ltYm9sIEZpbmRCeU5hbWVIZWxwZXIoCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsIGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gVGhlc2UgcmV0dXJuIE5VTEwgaWYgbm90IGZvdW5kLgorICBpbmxpbmUgY29uc3QgRmlsZURlc2NyaXB0b3IqIEZpbmRGaWxlKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdDsKKyAgaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbihjb25zdCBEZXNjcmlwdG9yKiBleHRlbmRlZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyKTsKKyAgaW5saW5lIHZvaWQgRmluZEFsbEV4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogb3V0KSBjb25zdDsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBBZGRpbmcgaXRlbXMuCisKKyAgLy8gVGhlc2UgYWRkIGl0ZW1zIHRvIHRoZSBjb3JyZXNwb25kaW5nIHRhYmxlcy4gIFRoZXkgcmV0dXJuIGZhbHNlIGlmCisgIC8vIHRoZSBrZXkgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHRhYmxlLiAgRm9yIEFkZFN5bWJvbCgpLCB0aGUgc3RyaW5nIHBhc3NlZAorICAvLyBpbiBtdXN0IGJlIG9uZSB0aGF0IHdhcyBjb25zdHJ1Y3RlZCB1c2luZyBBbGxvY2F0ZVN0cmluZygpLCBhcyBpdCB3aWxsCisgIC8vIGJlIHVzZWQgYXMgYSBrZXkgaW4gdGhlIHN5bWJvbHNfYnlfbmFtZV8gbWFwIHdpdGhvdXQgY29weWluZy4KKyAgYm9vbCBBZGRTeW1ib2woY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsIFN5bWJvbCBzeW1ib2wpOworICBib29sIEFkZEZpbGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICBib29sIEFkZEV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBBbGxvY2F0aW5nIG1lbW9yeS4KKworICAvLyBBbGxvY2F0ZSBhbiBvYmplY3Qgd2hpY2ggd2lsbCBiZSByZWNsYWltZWQgd2hlbiB0aGUgcG9vbCBpcworICAvLyBkZXN0cm95ZWQuICBOb3RlIHRoYXQgdGhlIG9iamVjdCdzIGRlc3RydWN0b3Igd2lsbCBuZXZlciBiZSBjYWxsZWQsCisgIC8vIHNvIGl0cyBmaWVsZHMgbXVzdCBiZSBwbGFpbiBvbGQgZGF0YSAocHJpbWl0aXZlIGRhdGEgdHlwZXMgYW5kCisgIC8vIHBvaW50ZXJzKS4gIEFsbCBvZiB0aGUgZGVzY3JpcHRvciB0eXBlcyBhcmUgc3VjaCBvYmplY3RzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPiBUeXBlKiBBbGxvY2F0ZSgpOworCisgIC8vIEFsbG9jYXRlIGFuIGFycmF5IG9mIG9iamVjdHMgd2hpY2ggd2lsbCBiZSByZWNsYWltZWQgd2hlbiB0aGUKKyAgLy8gcG9vbCBpbiBkZXN0cm95ZWQuICBBZ2FpbiwgZGVzdHJ1Y3RvcnMgYXJlIG5ldmVyIGNhbGxlZC4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4gVHlwZSogQWxsb2NhdGVBcnJheShpbnQgY291bnQpOworCisgIC8vIEFsbG9jYXRlIGEgc3RyaW5nIHdoaWNoIHdpbGwgYmUgZGVzdHJveWVkIHdoZW4gdGhlIHBvb2wgaXMgZGVzdHJveWVkLgorICAvLyBUaGUgc3RyaW5nIGlzIGluaXRpYWxpemVkIHRvIHRoZSBnaXZlbiB2YWx1ZSBmb3IgY29udmVuaWVuY2UuCisgIHN0cmluZyogQWxsb2NhdGVTdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWx1ZSk7CisKKyAgLy8gQWxsb2NhdGUgYSBwcm90b2NvbCBtZXNzYWdlIG9iamVjdC4gIFNvbWUgb2xkZXIgdmVyc2lvbnMgb2YgR0NDIGhhdmUKKyAgLy8gdHJvdWJsZSB1bmRlcnN0YW5kaW5nIGV4cGxpY2l0IHRlbXBsYXRlIGluc3RhbnRpYXRpb25zIGluIHNvbWUgY2FzZXMsIHNvCisgIC8vIGluIHRob3NlIGNhc2VzIHdlIGhhdmUgdG8gcGFzcyBhIGR1bW15IHBvaW50ZXIgb2YgdGhlIHJpZ2h0IHR5cGUgYXMgdGhlCisgIC8vIHBhcmFtZXRlciBpbnN0ZWFkIG9mIHNwZWNpZnlpbmcgdGhlIHR5cGUgZXhwbGljaXRseS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4gVHlwZSogQWxsb2NhdGVNZXNzYWdlKFR5cGUqIGR1bW15ID0gTlVMTCk7CisKKyAgLy8gQWxsb2NhdGUgYSBGaWxlRGVzY3JpcHRvclRhYmxlcyBvYmplY3QuCisgIEZpbGVEZXNjcmlwdG9yVGFibGVzKiBBbGxvY2F0ZUZpbGVUYWJsZXMoKTsKKworIHByaXZhdGU6CisgIHZlY3RvcjxzdHJpbmcqPiBzdHJpbmdzXzsgICAgLy8gQWxsIHN0cmluZ3MgaW4gdGhlIHBvb2wuCisgIHZlY3RvcjxNZXNzYWdlKj4gbWVzc2FnZXNfOyAgLy8gQWxsIG1lc3NhZ2VzIGluIHRoZSBwb29sLgorICB2ZWN0b3I8RmlsZURlc2NyaXB0b3JUYWJsZXMqPiBmaWxlX3RhYmxlc187ICAvLyBBbGwgZmlsZSB0YWJsZXMgaW4gdGhlIHBvb2wuCisgIHZlY3Rvcjx2b2lkKj4gYWxsb2NhdGlvbnNfOyAgLy8gQWxsIG90aGVyIG1lbW9yeSBhbGxvY2F0ZWQgaW4gdGhlIHBvb2wuCisKKyAgU3ltYm9sc0J5TmFtZU1hcCAgICAgIHN5bWJvbHNfYnlfbmFtZV87CisgIEZpbGVzQnlOYW1lTWFwICAgICAgICBmaWxlc19ieV9uYW1lXzsKKyAgRXh0ZW5zaW9uc0dyb3VwZWRCeURlc2NyaXB0b3JNYXAgZXh0ZW5zaW9uc187CisKKyAgc3RydWN0IENoZWNrUG9pbnQgeworICAgIGV4cGxpY2l0IENoZWNrUG9pbnQoY29uc3QgVGFibGVzKiB0YWJsZXMpCisgICAgICA6IHN0cmluZ3NfYmVmb3JlX2NoZWNrcG9pbnQodGFibGVzLT5zdHJpbmdzXy5zaXplKCkpLAorICAgICAgICBtZXNzYWdlc19iZWZvcmVfY2hlY2twb2ludCh0YWJsZXMtPm1lc3NhZ2VzXy5zaXplKCkpLAorICAgICAgICBmaWxlX3RhYmxlc19iZWZvcmVfY2hlY2twb2ludCh0YWJsZXMtPmZpbGVfdGFibGVzXy5zaXplKCkpLAorICAgICAgICBhbGxvY2F0aW9uc19iZWZvcmVfY2hlY2twb2ludCh0YWJsZXMtPmFsbG9jYXRpb25zXy5zaXplKCkpLAorICAgICAgICBwZW5kaW5nX3N5bWJvbHNfYmVmb3JlX2NoZWNrcG9pbnQoCisgICAgICAgICAgICB0YWJsZXMtPnN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpKSwKKyAgICAgICAgcGVuZGluZ19maWxlc19iZWZvcmVfY2hlY2twb2ludCgKKyAgICAgICAgICAgIHRhYmxlcy0+ZmlsZXNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpKSwKKyAgICAgICAgcGVuZGluZ19leHRlbnNpb25zX2JlZm9yZV9jaGVja3BvaW50KAorICAgICAgICAgICAgdGFibGVzLT5leHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfLnNpemUoKSkgeworICAgIH0KKyAgICBpbnQgc3RyaW5nc19iZWZvcmVfY2hlY2twb2ludDsKKyAgICBpbnQgbWVzc2FnZXNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgICAgaW50IGZpbGVfdGFibGVzX2JlZm9yZV9jaGVja3BvaW50OworICAgIGludCBhbGxvY2F0aW9uc19iZWZvcmVfY2hlY2twb2ludDsKKyAgICBpbnQgcGVuZGluZ19zeW1ib2xzX2JlZm9yZV9jaGVja3BvaW50OworICAgIGludCBwZW5kaW5nX2ZpbGVzX2JlZm9yZV9jaGVja3BvaW50OworICAgIGludCBwZW5kaW5nX2V4dGVuc2lvbnNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgIH07CisgIHZlY3RvcjxDaGVja1BvaW50PiBjaGVja3BvaW50c187CisgIHZlY3Rvcjxjb25zdCBjaGFyKiAgICAgID4gc3ltYm9sc19hZnRlcl9jaGVja3BvaW50XzsKKyAgdmVjdG9yPGNvbnN0IGNoYXIqICAgICAgPiBmaWxlc19hZnRlcl9jaGVja3BvaW50XzsKKyAgdmVjdG9yPERlc2NyaXB0b3JJbnRQYWlyPiBleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfOworCisgIC8vIEFsbG9jYXRlIHNvbWUgYnl0ZXMgd2hpY2ggd2lsbCBiZSByZWNsYWltZWQgd2hlbiB0aGUgcG9vbCBpcworICAvLyBkZXN0cm95ZWQuCisgIHZvaWQqIEFsbG9jYXRlQnl0ZXMoaW50IHNpemUpOworfTsKKworLy8gQ29udGFpbnMgdGFibGVzIHNwZWNpZmljIHRvIGEgcGFydGljdWxhciBmaWxlLiAgVGhlc2UgdGFibGVzIGFyZSBub3QKKy8vIG1vZGlmaWVkIG9uY2UgdGhlIGZpbGUgaGFzIGJlZW4gY29uc3RydWN0ZWQsIHNvIHRoZXkgbmVlZCBub3QgYmUKKy8vIHByb3RlY3RlZCBieSBhIG11dGV4LiAgVGhpcyBtYWtlcyBvcGVyYXRpb25zIHRoYXQgZGVwZW5kIG9ubHkgb24gdGhlCisvLyBjb250ZW50cyBvZiBhIHNpbmdsZSBmaWxlIC0tIGUuZy4gRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlOYW1lKCkgLS0KKy8vIGxvY2stZnJlZS4KKy8vCisvLyBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCB0aGUgZGVmaW5pdGlvbnMgb2YgdGhlIG1ldGhvZHMgb2YKKy8vIEZpbGVEZXNjcmlwdG9yVGFibGVzIGFuZCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzIGFyZSBpbnRlcmxlYXZlZCBiZWxvdy4KKy8vIFRoZXNlIHVzZWQgdG8gYmUgYSBzaW5nbGUgY2xhc3MuCitjbGFzcyBGaWxlRGVzY3JpcHRvclRhYmxlcyB7CisgcHVibGljOgorICBGaWxlRGVzY3JpcHRvclRhYmxlcygpOworICB+RmlsZURlc2NyaXB0b3JUYWJsZXMoKTsKKworICAvLyBFbXB0eSB0YWJsZSwgdXNlZCB3aXRoIHBsYWNlaG9sZGVyIGZpbGVzLgorICBzdGF0aWMgY29uc3QgRmlsZURlc2NyaXB0b3JUYWJsZXMga0VtcHR5OworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEZpbmRpbmcgaXRlbXMuCisKKyAgLy8gRmluZCBzeW1ib2xzLiAgVGhlc2UgcmV0dXJuIGEgbnVsbCBTeW1ib2wgKHN5bWJvbC5Jc051bGwoKSBpcyB0cnVlKQorICAvLyBpZiBub3QgZm91bmQuCisgIGlubGluZSBTeW1ib2wgRmluZE5lc3RlZFN5bWJvbChjb25zdCB2b2lkKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBpbmxpbmUgU3ltYm9sIEZpbmROZXN0ZWRTeW1ib2xPZlR5cGUoY29uc3Qgdm9pZCogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3ltYm9sOjpUeXBlIHR5cGUpIGNvbnN0OworCisgIC8vIFRoZXNlIHJldHVybiBOVUxMIGlmIG5vdCBmb3VuZC4KKyAgaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEZpZWxkQnlOdW1iZXIoCisgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LCBpbnQgbnVtYmVyKSBjb25zdDsKKyAgaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKAorICAgIGNvbnN0IHZvaWQqIHBhcmVudCwgY29uc3Qgc3RyaW5nJiBsb3dlcmNhc2VfbmFtZSkgY29uc3Q7CisgIGlubGluZSBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgKKyAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgY2FtZWxjYXNlX25hbWUpIGNvbnN0OworICBpbmxpbmUgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZEVudW1WYWx1ZUJ5TnVtYmVyKAorICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBwYXJlbnQsIGludCBudW1iZXIpIGNvbnN0OworICAvLyBUaGlzIGNyZWF0ZXMgYSBuZXcgRW51bVZhbHVlRGVzY3JpcHRvciBpZiBub3QgZm91bmQsIGluIGEgdGhyZWFkLXNhZmUgd2F5LgorICBpbmxpbmUgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZEVudW1WYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oCisgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogcGFyZW50LCBpbnQgbnVtYmVyKSBjb25zdDsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBBZGRpbmcgaXRlbXMuCisKKyAgLy8gVGhlc2UgYWRkIGl0ZW1zIHRvIHRoZSBjb3JyZXNwb25kaW5nIHRhYmxlcy4gIFRoZXkgcmV0dXJuIGZhbHNlIGlmCisgIC8vIHRoZSBrZXkgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHRhYmxlLiAgRm9yIEFkZEFsaWFzVW5kZXJQYXJlbnQoKSwgdGhlCisgIC8vIHN0cmluZyBwYXNzZWQgaW4gbXVzdCBiZSBvbmUgdGhhdCB3YXMgY29uc3RydWN0ZWQgdXNpbmcgQWxsb2NhdGVTdHJpbmcoKSwKKyAgLy8gYXMgaXQgd2lsbCBiZSB1c2VkIGFzIGEga2V5IGluIHRoZSBzeW1ib2xzX2J5X3BhcmVudF8gbWFwIHdpdGhvdXQgY29weWluZy4KKyAgYm9vbCBBZGRBbGlhc1VuZGVyUGFyZW50KGNvbnN0IHZvaWQqIHBhcmVudCwgY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIHN5bWJvbCk7CisgIGJvb2wgQWRkRmllbGRCeU51bWJlcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKyAgYm9vbCBBZGRFbnVtVmFsdWVCeU51bWJlcihjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSk7CisKKyAgLy8gQWRkcyB0aGUgZmllbGQgdG8gdGhlIGxvd2VyY2FzZV9uYW1lIGFuZCBjYW1lbGNhc2VfbmFtZSBtYXBzLiAgTmV2ZXIKKyAgLy8gZmFpbHMgYmVjYXVzZSB3ZSBhbGxvdyBkdXBsaWNhdGVzOyB0aGUgZmlyc3QgZmllbGQgYnkgdGhlIG5hbWUgd2lucy4KKyAgdm9pZCBBZGRGaWVsZEJ5U3R5bGl6ZWROYW1lcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworICAvLyBQb3B1bGF0ZXMgcC0+Zmlyc3QtPmxvY2F0aW9uc19ieV9wYXRoXyBmcm9tIHAtPnNlY29uZC4KKyAgLy8gVW51c3VhbCBzaWduYXR1cmUgZGljdGF0ZWQgYnkgR29vZ2xlT25jZUR5bmFtaWMuCisgIHN0YXRpYyB2b2lkIEJ1aWxkTG9jYXRpb25zQnlQYXRoKAorICAgICAgcGFpcjxjb25zdCBGaWxlRGVzY3JpcHRvclRhYmxlcyosIGNvbnN0IFNvdXJjZUNvZGVJbmZvKj4qIHApOworCisgIC8vIFJldHVybnMgdGhlIGxvY2F0aW9uIGRlbm90ZWQgYnkgdGhlIHNwZWNpZmllZCBwYXRoIHRocm91Z2ggaW5mbywKKyAgLy8gb3IgTlVMTCBpZiBub3QgZm91bmQuCisgIC8vIFRoZSB2YWx1ZSBvZiBpbmZvIG11c3QgYmUgdGhhdCBvZiB0aGUgY29ycmVzcG9uZGluZyBGaWxlRGVzY3JpcHRvci4KKyAgLy8gKENvbmNlcHR1YWxseSBhIHB1cmUgZnVuY3Rpb24sIGJ1dCBzdGF0ZWZ1bCBhcyBhbiBvcHRpbWlzYXRpb24uKQorICBjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogR2V0U291cmNlTG9jYXRpb24oCisgICAgICBjb25zdCB2ZWN0b3I8aW50PiYgcGF0aCwgY29uc3QgU291cmNlQ29kZUluZm8qIGluZm8pIGNvbnN0OworCisgcHJpdmF0ZToKKyAgU3ltYm9sc0J5UGFyZW50TWFwICAgIHN5bWJvbHNfYnlfcGFyZW50XzsKKyAgRmllbGRzQnlOYW1lTWFwICAgICAgIGZpZWxkc19ieV9sb3dlcmNhc2VfbmFtZV87CisgIEZpZWxkc0J5TmFtZU1hcCAgICAgICBmaWVsZHNfYnlfY2FtZWxjYXNlX25hbWVfOworICBGaWVsZHNCeU51bWJlck1hcCAgICAgZmllbGRzX2J5X251bWJlcl87ICAgICAgIC8vIE5vdCBpbmNsdWRpbmcgZXh0ZW5zaW9ucy4KKyAgRW51bVZhbHVlc0J5TnVtYmVyTWFwIGVudW1fdmFsdWVzX2J5X251bWJlcl87CisgIG11dGFibGUgRW51bVZhbHVlc0J5TnVtYmVyTWFwIHVua25vd25fZW51bV92YWx1ZXNfYnlfbnVtYmVyXworICAgICAgR09PR0xFX0dVQVJERURfQlkodW5rbm93bl9lbnVtX3ZhbHVlc19tdV8pOworCisgIC8vIFBvcHVsYXRlZCBvbiBmaXJzdCByZXF1ZXN0IHRvIHNhdmUgc3BhY2UsIGhlbmNlIGNvbnN0bmVzcyBnYW1lcy4KKyAgbXV0YWJsZSBHb29nbGVPbmNlRHluYW1pYyBsb2NhdGlvbnNfYnlfcGF0aF9vbmNlXzsKKyAgbXV0YWJsZSBMb2NhdGlvbnNCeVBhdGhNYXAgbG9jYXRpb25zX2J5X3BhdGhfOworCisgIC8vIE11dGV4IHRvIHByb3RlY3QgdGhlIHVua25vd24tZW51bS12YWx1ZSBtYXAgZHVlIHRvIGR5bmFtaWMKKyAgLy8gRW51bVZhbHVlRGVzY3JpcHRvciBjcmVhdGlvbiBvbiB1bmtub3duIHZhbHVlcy4KKyAgbXV0YWJsZSBNdXRleCB1bmtub3duX2VudW1fdmFsdWVzX211XzsKK307CisKK0Rlc2NyaXB0b3JQb29sOjpUYWJsZXM6OlRhYmxlcygpCisgICAgLy8gU3RhcnQgc29tZSBoYXNoX21hcCBhbmQgaGFzaF9zZXQgb2JqZWN0cyB3aXRoIGEgc21hbGwgIyBvZiBidWNrZXRzCisgICAgOiBrbm93bl9iYWRfZmlsZXNfKDMpLAorICAgICAga25vd25fYmFkX3N5bWJvbHNfKDMpLAorICAgICAgZXh0ZW5zaW9uc19sb2FkZWRfZnJvbV9kYl8oMyksCisgICAgICBzeW1ib2xzX2J5X25hbWVfKDMpLAorICAgICAgZmlsZXNfYnlfbmFtZV8oMykge30KKworCitEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjp+VGFibGVzKCkgeworICBHT09HTEVfRENIRUNLKGNoZWNrcG9pbnRzXy5lbXB0eSgpKTsKKyAgLy8gTm90ZSB0aGF0IHRoZSBkZWxldGlvbiBvcmRlciBpcyBpbXBvcnRhbnQsIHNpbmNlIHRoZSBkZXN0cnVjdG9ycyBvZiBzb21lCisgIC8vIG1lc3NhZ2VzIG1heSByZWZlciB0byBvYmplY3RzIGluIGFsbG9jYXRpb25zXy4KKyAgU1RMRGVsZXRlRWxlbWVudHMoJm1lc3NhZ2VzXyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsb2NhdGlvbnNfLnNpemUoKTsgaSsrKSB7CisgICAgb3BlcmF0b3IgZGVsZXRlKGFsbG9jYXRpb25zX1tpXSk7CisgIH0KKyAgU1RMRGVsZXRlRWxlbWVudHMoJnN0cmluZ3NfKTsKKyAgU1RMRGVsZXRlRWxlbWVudHMoJmZpbGVfdGFibGVzXyk7Cit9CisKK0ZpbGVEZXNjcmlwdG9yVGFibGVzOjpGaWxlRGVzY3JpcHRvclRhYmxlcygpCisgICAgLy8gSW5pdGlhbGl6ZSBhbGwgdGhlIGhhc2ggdGFibGVzIHRvIHN0YXJ0IG91dCB3aXRoIGEgc21hbGwgIyBvZiBidWNrZXRzCisgICAgOiBzeW1ib2xzX2J5X3BhcmVudF8oMyksCisgICAgICBmaWVsZHNfYnlfbG93ZXJjYXNlX25hbWVfKDMpLAorICAgICAgZmllbGRzX2J5X2NhbWVsY2FzZV9uYW1lXygzKSwKKyAgICAgIGZpZWxkc19ieV9udW1iZXJfKDMpLAorICAgICAgZW51bV92YWx1ZXNfYnlfbnVtYmVyXygzKSwKKyAgICAgIHVua25vd25fZW51bV92YWx1ZXNfYnlfbnVtYmVyXygzKSB7Cit9CisKK0ZpbGVEZXNjcmlwdG9yVGFibGVzOjp+RmlsZURlc2NyaXB0b3JUYWJsZXMoKSB7fQorCitjb25zdCBGaWxlRGVzY3JpcHRvclRhYmxlcyBGaWxlRGVzY3JpcHRvclRhYmxlczo6a0VtcHR5OworCit2b2lkIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFkZENoZWNrcG9pbnQoKSB7CisgIGNoZWNrcG9pbnRzXy5wdXNoX2JhY2soQ2hlY2tQb2ludCh0aGlzKSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6Q2xlYXJMYXN0Q2hlY2twb2ludCgpIHsKKyAgR09PR0xFX0RDSEVDSyghY2hlY2twb2ludHNfLmVtcHR5KCkpOworICBjaGVja3BvaW50c18ucG9wX2JhY2soKTsKKyAgaWYgKGNoZWNrcG9pbnRzXy5lbXB0eSgpKSB7CisgICAgLy8gQWxsIGNoZWNrcG9pbnRzIGhhdmUgYmVlbiBjbGVhcmVkOiB3ZSBjYW4gbm93IGNvbW1pdCBhbGwgb2YgdGhlIHBlbmRpbmcKKyAgICAvLyBkYXRhLgorICAgIHN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF8uY2xlYXIoKTsKKyAgICBmaWxlc19hZnRlcl9jaGVja3BvaW50Xy5jbGVhcigpOworICAgIGV4dGVuc2lvbnNfYWZ0ZXJfY2hlY2twb2ludF8uY2xlYXIoKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OlJvbGxiYWNrVG9MYXN0Q2hlY2twb2ludCgpIHsKKyAgR09PR0xFX0RDSEVDSyghY2hlY2twb2ludHNfLmVtcHR5KCkpOworICBjb25zdCBDaGVja1BvaW50JiBjaGVja3BvaW50ID0gY2hlY2twb2ludHNfLmJhY2soKTsKKworICBmb3IgKGludCBpID0gY2hlY2twb2ludC5wZW5kaW5nX3N5bWJvbHNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgICAgICAgaSA8IHN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpOworICAgICAgIGkrKykgeworICAgIHN5bWJvbHNfYnlfbmFtZV8uZXJhc2Uoc3ltYm9sc19hZnRlcl9jaGVja3BvaW50X1tpXSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IGNoZWNrcG9pbnQucGVuZGluZ19maWxlc19iZWZvcmVfY2hlY2twb2ludDsKKyAgICAgICBpIDwgZmlsZXNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpOworICAgICAgIGkrKykgeworICAgIGZpbGVzX2J5X25hbWVfLmVyYXNlKGZpbGVzX2FmdGVyX2NoZWNrcG9pbnRfW2ldKTsKKyAgfQorICBmb3IgKGludCBpID0gY2hlY2twb2ludC5wZW5kaW5nX2V4dGVuc2lvbnNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgICAgICAgaSA8IGV4dGVuc2lvbnNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpOworICAgICAgIGkrKykgeworICAgIGV4dGVuc2lvbnNfLmVyYXNlKGV4dGVuc2lvbnNfYWZ0ZXJfY2hlY2twb2ludF9baV0pOworICB9CisKKyAgc3ltYm9sc19hZnRlcl9jaGVja3BvaW50Xy5yZXNpemUoCisgICAgICBjaGVja3BvaW50LnBlbmRpbmdfc3ltYm9sc19iZWZvcmVfY2hlY2twb2ludCk7CisgIGZpbGVzX2FmdGVyX2NoZWNrcG9pbnRfLnJlc2l6ZShjaGVja3BvaW50LnBlbmRpbmdfZmlsZXNfYmVmb3JlX2NoZWNrcG9pbnQpOworICBleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfLnJlc2l6ZSgKKyAgICAgIGNoZWNrcG9pbnQucGVuZGluZ19leHRlbnNpb25zX2JlZm9yZV9jaGVja3BvaW50KTsKKworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycygKKyAgICAgIHN0cmluZ3NfLmJlZ2luKCkgKyBjaGVja3BvaW50LnN0cmluZ3NfYmVmb3JlX2NoZWNrcG9pbnQsIHN0cmluZ3NfLmVuZCgpKTsKKyAgU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMoCisgICAgICBtZXNzYWdlc18uYmVnaW4oKSArIGNoZWNrcG9pbnQubWVzc2FnZXNfYmVmb3JlX2NoZWNrcG9pbnQsCisgICAgICBtZXNzYWdlc18uZW5kKCkpOworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycygKKyAgICAgIGZpbGVfdGFibGVzXy5iZWdpbigpICsgY2hlY2twb2ludC5maWxlX3RhYmxlc19iZWZvcmVfY2hlY2twb2ludCwKKyAgICAgIGZpbGVfdGFibGVzXy5lbmQoKSk7CisgIGZvciAoaW50IGkgPSBjaGVja3BvaW50LmFsbG9jYXRpb25zX2JlZm9yZV9jaGVja3BvaW50OworICAgICAgIGkgPCBhbGxvY2F0aW9uc18uc2l6ZSgpOworICAgICAgIGkrKykgeworICAgIG9wZXJhdG9yIGRlbGV0ZShhbGxvY2F0aW9uc19baV0pOworICB9CisKKyAgc3RyaW5nc18ucmVzaXplKGNoZWNrcG9pbnQuc3RyaW5nc19iZWZvcmVfY2hlY2twb2ludCk7CisgIG1lc3NhZ2VzXy5yZXNpemUoY2hlY2twb2ludC5tZXNzYWdlc19iZWZvcmVfY2hlY2twb2ludCk7CisgIGZpbGVfdGFibGVzXy5yZXNpemUoY2hlY2twb2ludC5maWxlX3RhYmxlc19iZWZvcmVfY2hlY2twb2ludCk7CisgIGFsbG9jYXRpb25zXy5yZXNpemUoY2hlY2twb2ludC5hbGxvY2F0aW9uc19iZWZvcmVfY2hlY2twb2ludCk7CisgIGNoZWNrcG9pbnRzXy5wb3BfYmFjaygpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2lubGluZSBTeW1ib2wgRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6RmluZFN5bWJvbChjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBjb25zdCBTeW1ib2wqIHJlc3VsdCA9IEZpbmRPck51bGwoc3ltYm9sc19ieV9uYW1lXywga2V5LmNfc3RyKCkpOworICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICByZXR1cm4ga051bGxTeW1ib2w7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuICpyZXN1bHQ7CisgIH0KK30KKworaW5saW5lIFN5bWJvbCBGaWxlRGVzY3JpcHRvclRhYmxlczo6RmluZE5lc3RlZFN5bWJvbCgKKyAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBjb25zdCBTeW1ib2wqIHJlc3VsdCA9CisgICAgRmluZE9yTnVsbChzeW1ib2xzX2J5X3BhcmVudF8sIFBvaW50ZXJTdHJpbmdQYWlyKHBhcmVudCwgbmFtZS5jX3N0cigpKSk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgIHJldHVybiBrTnVsbFN5bWJvbDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gKnJlc3VsdDsKKyAgfQorfQorCitpbmxpbmUgU3ltYm9sIEZpbGVEZXNjcmlwdG9yVGFibGVzOjpGaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKAorICAgIGNvbnN0IHZvaWQqIHBhcmVudCwgY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBTeW1ib2w6OlR5cGUgdHlwZSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gRmluZE5lc3RlZFN5bWJvbChwYXJlbnQsIG5hbWUpOworICBpZiAocmVzdWx0LnR5cGUgIT0gdHlwZSkgcmV0dXJuIGtOdWxsU3ltYm9sOworICByZXR1cm4gcmVzdWx0OworfQorCitTeW1ib2wgRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6RmluZEJ5TmFtZUhlbHBlcigKKyAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIE11dGV4TG9ja01heWJlIGxvY2socG9vbC0+bXV0ZXhfKTsKKyAga25vd25fYmFkX3N5bWJvbHNfLmNsZWFyKCk7CisgIGtub3duX2JhZF9maWxlc18uY2xlYXIoKTsKKyAgU3ltYm9sIHJlc3VsdCA9IEZpbmRTeW1ib2wobmFtZSk7CisKKyAgaWYgKHJlc3VsdC5Jc051bGwoKSAmJiBwb29sLT51bmRlcmxheV8gIT0gTlVMTCkgeworICAgIC8vIFN5bWJvbCBub3QgZm91bmQ7IGNoZWNrIHRoZSB1bmRlcmxheS4KKyAgICByZXN1bHQgPQorICAgICAgcG9vbC0+dW5kZXJsYXlfLT50YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHBvb2wtPnVuZGVybGF5XywgbmFtZSk7CisgIH0KKworICBpZiAocmVzdWx0LklzTnVsbCgpKSB7CisgICAgLy8gU3ltYm9sIHN0aWxsIG5vdCBmb3VuZCwgc28gY2hlY2sgZmFsbGJhY2sgZGF0YWJhc2UuCisgICAgaWYgKHBvb2wtPlRyeUZpbmRTeW1ib2xJbkZhbGxiYWNrRGF0YWJhc2UobmFtZSkpIHsKKyAgICAgIHJlc3VsdCA9IEZpbmRTeW1ib2wobmFtZSk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpGaW5kRmlsZSgKKyAgICBjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICByZXR1cm4gRmluZFB0ck9yTnVsbChmaWxlc19ieV9uYW1lXywga2V5LmNfc3RyKCkpOworfQorCitpbmxpbmUgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclRhYmxlczo6RmluZEZpZWxkQnlOdW1iZXIoCisgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LCBpbnQgbnVtYmVyKSBjb25zdCB7CisgIHJldHVybiBGaW5kUHRyT3JOdWxsKGZpZWxkc19ieV9udW1iZXJfLCBzdGQ6Om1ha2VfcGFpcihwYXJlbnQsIG51bWJlcikpOworfQorCitpbmxpbmUgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclRhYmxlczo6RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKAorICAgIGNvbnN0IHZvaWQqIHBhcmVudCwgY29uc3Qgc3RyaW5nJiBsb3dlcmNhc2VfbmFtZSkgY29uc3QgeworICByZXR1cm4gRmluZFB0ck9yTnVsbChmaWVsZHNfYnlfbG93ZXJjYXNlX25hbWVfLAorICAgICAgICAgICAgICAgICAgICAgICBQb2ludGVyU3RyaW5nUGFpcihwYXJlbnQsIGxvd2VyY2FzZV9uYW1lLmNfc3RyKCkpKTsKK30KKworaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgKKyAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgY2FtZWxjYXNlX25hbWUpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRQdHJPck51bGwoZmllbGRzX2J5X2NhbWVsY2FzZV9uYW1lXywKKyAgICAgICAgICAgICAgICAgICAgICAgUG9pbnRlclN0cmluZ1BhaXIocGFyZW50LCBjYW1lbGNhc2VfbmFtZS5jX3N0cigpKSk7Cit9CisKK2lubGluZSBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclRhYmxlczo6RmluZEVudW1WYWx1ZUJ5TnVtYmVyKAorICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBwYXJlbnQsIGludCBudW1iZXIpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRQdHJPck51bGwoZW51bV92YWx1ZXNfYnlfbnVtYmVyXywgc3RkOjptYWtlX3BhaXIocGFyZW50LCBudW1iZXIpKTsKK30KKworaW5saW5lIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqCitGaWxlRGVzY3JpcHRvclRhYmxlczo6RmluZEVudW1WYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oCisgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIHBhcmVudCwgaW50IG51bWJlcikgY29uc3QgeworICAvLyBGaXJzdCB0cnksIHdpdGggbWFwIG9mIGNvbXBpbGVkLWluIHZhbHVlcy4KKyAgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlc2MgPQorICAgICAgICBGaW5kUHRyT3JOdWxsKGVudW1fdmFsdWVzX2J5X251bWJlcl8sIHN0ZDo6bWFrZV9wYWlyKHBhcmVudCwgbnVtYmVyKSk7CisgICAgaWYgKGRlc2MgIT0gTlVMTCkgeworICAgICAgcmV0dXJuIGRlc2M7CisgICAgfQorICB9CisgIC8vIFNlY29uZCB0cnksIHdpdGggcmVhZGVyIGxvY2sgaGVsZCBvbiB1bmtub3duIGVudW0gdmFsdWVzOiBjb21tb24gY2FzZS4KKyAgeworICAgIFJlYWRlck11dGV4TG9jayBsKCZ1bmtub3duX2VudW1fdmFsdWVzX211Xyk7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZGVzYyA9IEZpbmRQdHJPck51bGwoCisgICAgICAgIHVua25vd25fZW51bV92YWx1ZXNfYnlfbnVtYmVyXywgc3RkOjptYWtlX3BhaXIocGFyZW50LCBudW1iZXIpKTsKKyAgICBpZiAoZGVzYyAhPSBOVUxMKSB7CisgICAgICByZXR1cm4gZGVzYzsKKyAgICB9CisgIH0KKyAgLy8gSWYgbm90IGZvdW5kLCB0cnkgYWdhaW4gd2l0aCB3cml0ZXIgbG9jayBoZWxkLCBhbmQgY3JlYXRlIG5ldyBkZXNjcmlwdG9yIGlmCisgIC8vIG5lY2Vzc2FyeS4KKyAgeworICAgIFdyaXRlck11dGV4TG9jayBsKCZ1bmtub3duX2VudW1fdmFsdWVzX211Xyk7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZGVzYyA9IEZpbmRQdHJPck51bGwoCisgICAgICAgIHVua25vd25fZW51bV92YWx1ZXNfYnlfbnVtYmVyXywgc3RkOjptYWtlX3BhaXIocGFyZW50LCBudW1iZXIpKTsKKyAgICBpZiAoZGVzYyAhPSBOVUxMKSB7CisgICAgICByZXR1cm4gZGVzYzsKKyAgICB9CisKKyAgICAvLyBDcmVhdGUgYW4gRW51bVZhbHVlRGVzY3JpcHRvciBkeW5hbWljYWxseS4gV2UgZG9uJ3QgaW5zZXJ0IGl0IGludG8gdGhlCisgICAgLy8gRW51bURlc2NyaXB0b3IgKGl0J3Mgbm90IGEgcGFydCBvZiB0aGUgZW51bSBhcyBvcmlnaW5hbGx5IGRlZmluZWQpLCBidXQKKyAgICAvLyB3ZSBkbyBpbnNlcnQgaXQgaW50byB0aGUgdGFibGUgc28gdGhhdCB3ZSBjYW4gcmV0dXJuIHRoZSBzYW1lIHBvaW50ZXIKKyAgICAvLyBsYXRlci4KKyAgICBzdHJpbmcgZW51bV92YWx1ZV9uYW1lID0gU3RyaW5nUHJpbnRmKAorICAgICAgICAiVU5LTk9XTl9FTlVNX1ZBTFVFXyVzXyVkIiwgcGFyZW50LT5uYW1lKCkuY19zdHIoKSwgbnVtYmVyKTsKKyAgICBEZXNjcmlwdG9yUG9vbDo6VGFibGVzKiB0YWJsZXMgPQorICAgICAgICBjb25zdF9jYXN0PERlc2NyaXB0b3JQb29sOjpUYWJsZXMqPihEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlc18uZ2V0KCkpOworICAgIEVudW1WYWx1ZURlc2NyaXB0b3IqIHJlc3VsdCA9IHRhYmxlcy0+QWxsb2NhdGU8RW51bVZhbHVlRGVzY3JpcHRvcj4oKTsKKyAgICByZXN1bHQtPm5hbWVfID0gdGFibGVzLT5BbGxvY2F0ZVN0cmluZyhlbnVtX3ZhbHVlX25hbWUpOworICAgIHJlc3VsdC0+ZnVsbF9uYW1lXyA9IHRhYmxlcy0+QWxsb2NhdGVTdHJpbmcocGFyZW50LT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLiIgKyBlbnVtX3ZhbHVlX25hbWUpOworICAgIHJlc3VsdC0+bnVtYmVyXyA9IG51bWJlcjsKKyAgICByZXN1bHQtPnR5cGVfID0gcGFyZW50OworICAgIHJlc3VsdC0+b3B0aW9uc18gPSAmRW51bVZhbHVlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICAgIEluc2VydElmTm90UHJlc2VudCgmdW5rbm93bl9lbnVtX3ZhbHVlc19ieV9udW1iZXJfLAorICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1ha2VfcGFpcihwYXJlbnQsIG51bWJlciksIHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCisKK2lubGluZSBjb25zdCBGaWVsZERlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkZpbmRFeHRlbnNpb24oCisgICAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUsIGludCBudW1iZXIpIHsKKyAgcmV0dXJuIEZpbmRQdHJPck51bGwoZXh0ZW5zaW9uc18sIHN0ZDo6bWFrZV9wYWlyKGV4dGVuZGVlLCBudW1iZXIpKTsKK30KKworaW5saW5lIHZvaWQgRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6RmluZEFsbEV4dGVuc2lvbnMoCisgICAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUsIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogb3V0KSBjb25zdCB7CisgIEV4dGVuc2lvbnNHcm91cGVkQnlEZXNjcmlwdG9yTWFwOjpjb25zdF9pdGVyYXRvciBpdCA9CisgICAgICBleHRlbnNpb25zXy5sb3dlcl9ib3VuZChzdGQ6Om1ha2VfcGFpcihleHRlbmRlZSwgMCkpOworICBmb3IgKDsgaXQgIT0gZXh0ZW5zaW9uc18uZW5kKCkgJiYgaXQtPmZpcnN0LmZpcnN0ID09IGV4dGVuZGVlOyArK2l0KSB7CisgICAgb3V0LT5wdXNoX2JhY2soaXQtPnNlY29uZCk7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitib29sIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFkZFN5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwgU3ltYm9sIHN5bWJvbCkgeworICBpZiAoSW5zZXJ0SWZOb3RQcmVzZW50KCZzeW1ib2xzX2J5X25hbWVfLCBmdWxsX25hbWUuY19zdHIoKSwgc3ltYm9sKSkgeworICAgIHN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF8ucHVzaF9iYWNrKGZ1bGxfbmFtZS5jX3N0cigpKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBGaWxlRGVzY3JpcHRvclRhYmxlczo6QWRkQWxpYXNVbmRlclBhcmVudCgKKyAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSwgU3ltYm9sIHN5bWJvbCkgeworICBQb2ludGVyU3RyaW5nUGFpciBieV9wYXJlbnRfa2V5KHBhcmVudCwgbmFtZS5jX3N0cigpKTsKKyAgcmV0dXJuIEluc2VydElmTm90UHJlc2VudCgmc3ltYm9sc19ieV9wYXJlbnRfLCBieV9wYXJlbnRfa2V5LCBzeW1ib2wpOworfQorCitib29sIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFkZEZpbGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgaWYgKEluc2VydElmTm90UHJlc2VudCgmZmlsZXNfYnlfbmFtZV8sIGZpbGUtPm5hbWUoKS5jX3N0cigpLCBmaWxlKSkgeworICAgIGZpbGVzX2FmdGVyX2NoZWNrcG9pbnRfLnB1c2hfYmFjayhmaWxlLT5uYW1lKCkuY19zdHIoKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkFkZEZpZWxkQnlTdHlsaXplZE5hbWVzKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgY29uc3Qgdm9pZCogcGFyZW50OworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgaWYgKGZpZWxkLT5leHRlbnNpb25fc2NvcGUoKSA9PSBOVUxMKSB7CisgICAgICBwYXJlbnQgPSBmaWVsZC0+ZmlsZSgpOworICAgIH0gZWxzZSB7CisgICAgICBwYXJlbnQgPSBmaWVsZC0+ZXh0ZW5zaW9uX3Njb3BlKCk7CisgICAgfQorICB9IGVsc2UgeworICAgIHBhcmVudCA9IGZpZWxkLT5jb250YWluaW5nX3R5cGUoKTsKKyAgfQorCisgIFBvaW50ZXJTdHJpbmdQYWlyIGxvd2VyY2FzZV9rZXkocGFyZW50LCBmaWVsZC0+bG93ZXJjYXNlX25hbWUoKS5jX3N0cigpKTsKKyAgSW5zZXJ0SWZOb3RQcmVzZW50KCZmaWVsZHNfYnlfbG93ZXJjYXNlX25hbWVfLCBsb3dlcmNhc2Vfa2V5LCBmaWVsZCk7CisKKyAgUG9pbnRlclN0cmluZ1BhaXIgY2FtZWxjYXNlX2tleShwYXJlbnQsIGZpZWxkLT5jYW1lbGNhc2VfbmFtZSgpLmNfc3RyKCkpOworICBJbnNlcnRJZk5vdFByZXNlbnQoJmZpZWxkc19ieV9jYW1lbGNhc2VfbmFtZV8sIGNhbWVsY2FzZV9rZXksIGZpZWxkKTsKK30KKworYm9vbCBGaWxlRGVzY3JpcHRvclRhYmxlczo6QWRkRmllbGRCeU51bWJlcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIERlc2NyaXB0b3JJbnRQYWlyIGtleShmaWVsZC0+Y29udGFpbmluZ190eXBlKCksIGZpZWxkLT5udW1iZXIoKSk7CisgIHJldHVybiBJbnNlcnRJZk5vdFByZXNlbnQoJmZpZWxkc19ieV9udW1iZXJfLCBrZXksIGZpZWxkKTsKK30KKworYm9vbCBGaWxlRGVzY3JpcHRvclRhYmxlczo6QWRkRW51bVZhbHVlQnlOdW1iZXIoCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIHsKKyAgRW51bUludFBhaXIga2V5KHZhbHVlLT50eXBlKCksIHZhbHVlLT5udW1iZXIoKSk7CisgIHJldHVybiBJbnNlcnRJZk5vdFByZXNlbnQoJmVudW1fdmFsdWVzX2J5X251bWJlcl8sIGtleSwgdmFsdWUpOworfQorCitib29sIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFkZEV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIERlc2NyaXB0b3JJbnRQYWlyIGtleShmaWVsZC0+Y29udGFpbmluZ190eXBlKCksIGZpZWxkLT5udW1iZXIoKSk7CisgIGlmIChJbnNlcnRJZk5vdFByZXNlbnQoJmV4dGVuc2lvbnNfLCBrZXksIGZpZWxkKSkgeworICAgIGV4dGVuc2lvbnNfYWZ0ZXJfY2hlY2twb2ludF8ucHVzaF9iYWNrKGtleSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4KK1R5cGUqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFsbG9jYXRlKCkgeworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxUeXBlKj4oQWxsb2NhdGVCeXRlcyhzaXplb2YoVHlwZSkpKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4KK1R5cGUqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFsbG9jYXRlQXJyYXkoaW50IGNvdW50KSB7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PFR5cGUqPihBbGxvY2F0ZUJ5dGVzKHNpemVvZihUeXBlKSAqIGNvdW50KSk7Cit9CisKK3N0cmluZyogRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6QWxsb2NhdGVTdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICBzdHJpbmcqIHJlc3VsdCA9IG5ldyBzdHJpbmcodmFsdWUpOworICBzdHJpbmdzXy5wdXNoX2JhY2socmVzdWx0KTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4KK1R5cGUqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFsbG9jYXRlTWVzc2FnZShUeXBlKiAvKiBkdW1teSAqLykgeworICBUeXBlKiByZXN1bHQgPSBuZXcgVHlwZTsKKyAgbWVzc2FnZXNfLnB1c2hfYmFjayhyZXN1bHQpOworICByZXR1cm4gcmVzdWx0OworfQorCitGaWxlRGVzY3JpcHRvclRhYmxlcyogRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6QWxsb2NhdGVGaWxlVGFibGVzKCkgeworICBGaWxlRGVzY3JpcHRvclRhYmxlcyogcmVzdWx0ID0gbmV3IEZpbGVEZXNjcmlwdG9yVGFibGVzOworICBmaWxlX3RhYmxlc18ucHVzaF9iYWNrKHJlc3VsdCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFsbG9jYXRlQnl0ZXMoaW50IHNpemUpIHsKKyAgLy8gVE9ETyhrZW50b24pOiAgV291bGQgaXQgYmUgd29ydGh3aGlsZSB0byBpbXBsZW1lbnQgdGhpcyBpbiBzb21lIG1vcmUKKyAgLy8gc29waGlzdGljYXRlZCB3YXk/ICBQcm9iYWJseSBub3QgZm9yIHRoZSBvcGVuIHNvdXJjZSByZWxlYXNlLCBidXQgZm9yCisgIC8vIGludGVybmFsIHVzZSB3ZSBjb3VsZCBlYXNpbHkgcGx1ZyBpbiBvbmUgb2Ygb3VyIGV4aXN0aW5nIG1lbW9yeSBwb29sCisgIC8vIGFsbG9jYXRvcnMuLi4KKyAgaWYgKHNpemUgPT0gMCkgcmV0dXJuIE5VTEw7CisKKyAgdm9pZCogcmVzdWx0ID0gb3BlcmF0b3IgbmV3KHNpemUpOworICBhbGxvY2F0aW9uc18ucHVzaF9iYWNrKHJlc3VsdCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkJ1aWxkTG9jYXRpb25zQnlQYXRoKAorICAgIHBhaXI8Y29uc3QgRmlsZURlc2NyaXB0b3JUYWJsZXMqLCBjb25zdCBTb3VyY2VDb2RlSW5mbyo+KiBwKSB7CisgIGZvciAoaW50IGkgPSAwLCBsZW4gPSBwLT5zZWNvbmQtPmxvY2F0aW9uX3NpemUoKTsgaSA8IGxlbjsgKytpKSB7CisgICAgY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIGxvYyA9ICZwLT5zZWNvbmQtPmxvY2F0aW9uKCkuR2V0KGkpOworICAgIHAtPmZpcnN0LT5sb2NhdGlvbnNfYnlfcGF0aF9bSm9pbihsb2MtPnBhdGgoKSwgIiwiKV0gPSBsb2M7CisgIH0KK30KKworY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIEZpbGVEZXNjcmlwdG9yVGFibGVzOjpHZXRTb3VyY2VMb2NhdGlvbigKKyAgICBjb25zdCB2ZWN0b3I8aW50PiYgcGF0aCwgY29uc3QgU291cmNlQ29kZUluZm8qIGluZm8pIGNvbnN0IHsKKyAgcGFpcjxjb25zdCBGaWxlRGVzY3JpcHRvclRhYmxlcyosIGNvbnN0IFNvdXJjZUNvZGVJbmZvKj4gcCgKKyAgICAgIHN0ZDo6bWFrZV9wYWlyKHRoaXMsIGluZm8pKTsKKyAgbG9jYXRpb25zX2J5X3BhdGhfb25jZV8uSW5pdCgmRmlsZURlc2NyaXB0b3JUYWJsZXM6OkJ1aWxkTG9jYXRpb25zQnlQYXRoLCAmcCk7CisgIHJldHVybiBGaW5kUHRyT3JOdWxsKGxvY2F0aW9uc19ieV9wYXRoXywgSm9pbihwYXRoLCAiLCIpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGVzY3JpcHRvclBvb2wKKworRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjp+RXJyb3JDb2xsZWN0b3IoKSB7fQorCitEZXNjcmlwdG9yUG9vbDo6RGVzY3JpcHRvclBvb2woKQorICA6IG11dGV4XyhOVUxMKSwKKyAgICBmYWxsYmFja19kYXRhYmFzZV8oTlVMTCksCisgICAgZGVmYXVsdF9lcnJvcl9jb2xsZWN0b3JfKE5VTEwpLAorICAgIHVuZGVybGF5XyhOVUxMKSwKKyAgICB0YWJsZXNfKG5ldyBUYWJsZXMpLAorICAgIGVuZm9yY2VfZGVwZW5kZW5jaWVzXyh0cnVlKSwKKyAgICBhbGxvd191bmtub3duXyhmYWxzZSksCisgICAgZW5mb3JjZV93ZWFrXyhmYWxzZSkge30KKworRGVzY3JpcHRvclBvb2w6OkRlc2NyaXB0b3JQb29sKERlc2NyaXB0b3JEYXRhYmFzZSogZmFsbGJhY2tfZGF0YWJhc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3RvcikKKyAgOiBtdXRleF8obmV3IE11dGV4KSwKKyAgICBmYWxsYmFja19kYXRhYmFzZV8oZmFsbGJhY2tfZGF0YWJhc2UpLAorICAgIGRlZmF1bHRfZXJyb3JfY29sbGVjdG9yXyhlcnJvcl9jb2xsZWN0b3IpLAorICAgIHVuZGVybGF5XyhOVUxMKSwKKyAgICB0YWJsZXNfKG5ldyBUYWJsZXMpLAorICAgIGVuZm9yY2VfZGVwZW5kZW5jaWVzXyh0cnVlKSwKKyAgICBhbGxvd191bmtub3duXyhmYWxzZSksCisgICAgZW5mb3JjZV93ZWFrXyhmYWxzZSkgeworfQorCitEZXNjcmlwdG9yUG9vbDo6RGVzY3JpcHRvclBvb2woY29uc3QgRGVzY3JpcHRvclBvb2wqIHVuZGVybGF5KQorICA6IG11dGV4XyhOVUxMKSwKKyAgICBmYWxsYmFja19kYXRhYmFzZV8oTlVMTCksCisgICAgZGVmYXVsdF9lcnJvcl9jb2xsZWN0b3JfKE5VTEwpLAorICAgIHVuZGVybGF5Xyh1bmRlcmxheSksCisgICAgdGFibGVzXyhuZXcgVGFibGVzKSwKKyAgICBlbmZvcmNlX2RlcGVuZGVuY2llc18odHJ1ZSksCisgICAgYWxsb3dfdW5rbm93bl8oZmFsc2UpLAorICAgIGVuZm9yY2Vfd2Vha18oZmFsc2UpIHt9CisKK0Rlc2NyaXB0b3JQb29sOjp+RGVzY3JpcHRvclBvb2woKSB7CisgIGlmIChtdXRleF8gIT0gTlVMTCkgZGVsZXRlIG11dGV4XzsKK30KKworLy8gRGVzY3JpcHRvclBvb2w6OkJ1aWxkRmlsZSgpIGRlZmluZWQgbGF0ZXIuCisvLyBEZXNjcmlwdG9yUG9vbDo6QnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycygpIGRlZmluZWQgbGF0ZXIuCisKK3ZvaWQgRGVzY3JpcHRvclBvb2w6OkludGVybmFsRG9udEVuZm9yY2VEZXBlbmRlbmNpZXMoKSB7CisgIGVuZm9yY2VfZGVwZW5kZW5jaWVzXyA9IGZhbHNlOworfQorCit2b2lkIERlc2NyaXB0b3JQb29sOjpBZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpIHsKKyAgdW51c2VkX2ltcG9ydF90cmFja19maWxlc18uaW5zZXJ0KGZpbGVfbmFtZSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclBvb2w6OkNsZWFyVW51c2VkSW1wb3J0VHJhY2tGaWxlcygpIHsKKyAgdW51c2VkX2ltcG9ydF90cmFja19maWxlc18uY2xlYXIoKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxJc0ZpbGVMb2FkZWQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHJldHVybiB0YWJsZXNfLT5GaW5kRmlsZShmaWxlbmFtZSkgIT0gTlVMTDsKK30KKworLy8gZ2VuZXJhdGVkX3Bvb2wgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCituYW1lc3BhY2UgeworCisKK0VuY29kZWREZXNjcmlwdG9yRGF0YWJhc2UqIGdlbmVyYXRlZF9kYXRhYmFzZV8gPSBOVUxMOworRGVzY3JpcHRvclBvb2wqIGdlbmVyYXRlZF9wb29sXyA9IE5VTEw7CitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGdlbmVyYXRlZF9wb29sX2luaXRfKTsKKwordm9pZCBEZWxldGVHZW5lcmF0ZWRQb29sKCkgeworICBkZWxldGUgZ2VuZXJhdGVkX2RhdGFiYXNlXzsKKyAgZ2VuZXJhdGVkX2RhdGFiYXNlXyA9IE5VTEw7CisgIGRlbGV0ZSBnZW5lcmF0ZWRfcG9vbF87CisgIGdlbmVyYXRlZF9wb29sXyA9IE5VTEw7Cit9CisKK3N0YXRpYyB2b2lkIEluaXRHZW5lcmF0ZWRQb29sKCkgeworICBnZW5lcmF0ZWRfZGF0YWJhc2VfID0gbmV3IEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U7CisgIGdlbmVyYXRlZF9wb29sXyA9IG5ldyBEZXNjcmlwdG9yUG9vbChnZW5lcmF0ZWRfZGF0YWJhc2VfKTsKKworICBpbnRlcm5hbDo6T25TaHV0ZG93bigmRGVsZXRlR2VuZXJhdGVkUG9vbCk7Cit9CisKK2lubGluZSB2b2lkIEluaXRHZW5lcmF0ZWRQb29sT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmZ2VuZXJhdGVkX3Bvb2xfaW5pdF8sICZJbml0R2VuZXJhdGVkUG9vbCk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworY29uc3QgRGVzY3JpcHRvclBvb2wqIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpIHsKKyAgSW5pdEdlbmVyYXRlZFBvb2xPbmNlKCk7CisgIHJldHVybiBnZW5lcmF0ZWRfcG9vbF87Cit9CisKK0Rlc2NyaXB0b3JQb29sKiBEZXNjcmlwdG9yUG9vbDo6aW50ZXJuYWxfZ2VuZXJhdGVkX3Bvb2woKSB7CisgIEluaXRHZW5lcmF0ZWRQb29sT25jZSgpOworICByZXR1cm4gZ2VuZXJhdGVkX3Bvb2xfOworfQorCit2b2lkIERlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoCisgICAgY29uc3Qgdm9pZCogZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIGludCBzaXplKSB7CisgIC8vIFNvLCB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiB0aGUgcHJvY2VzcyBvZiBpbml0aWFsaXppbmcgdGhlCisgIC8vIGRlc2NyaXB0b3JzIGZvciBnZW5lcmF0ZWQgcHJvdG8gY2xhc3Nlcy4gIEVhY2ggZ2VuZXJhdGVkIC5wYi5jYyBmaWxlCisgIC8vIGhhcyBhbiBpbnRlcm5hbCBwcm9jZWR1cmUgY2FsbGVkIEFkZERlc2NyaXB0b3JzKCkgd2hpY2ggaXMgY2FsbGVkIGF0CisgIC8vIHByb2Nlc3Mgc3RhcnR1cCwgYW5kIHRoYXQgZnVuY3Rpb24gY2FsbHMgdGhpcyBvbmUgaW4gb3JkZXIgdG8gcmVnaXN0ZXIKKyAgLy8gdGhlIHJhdyBieXRlcyBvZiB0aGUgRmlsZURlc2NyaXB0b3JQcm90byByZXByZXNlbnRpbmcgdGhlIGZpbGUuCisgIC8vCisgIC8vIFdlIGRvIG5vdCBhY3R1YWxseSBjb25zdHJ1Y3QgdGhlIGRlc2NyaXB0b3Igb2JqZWN0cyByaWdodCBhd2F5LiAgV2UganVzdAorICAvLyBoYW5nIG9uIHRvIHRoZSBieXRlcyB1bnRpbCB0aGV5IGFyZSBhY3R1YWxseSBuZWVkZWQuICBXZSBhY3R1YWxseSBjb25zdHJ1Y3QKKyAgLy8gdGhlIGRlc2NyaXB0b3IgdGhlIGZpcnN0IHRpbWUgb25lIG9mIHRoZSBmb2xsb3dpbmcgdGhpbmdzIGhhcHBlbnM6CisgIC8vICogU29tZW9uZSBjYWxscyBhIG1ldGhvZCBsaWtlIGRlc2NyaXB0b3IoKSwgR2V0RGVzY3JpcHRvcigpLCBvcgorICAvLyAgIEdldFJlZmxlY3Rpb24oKSBvbiB0aGUgZ2VuZXJhdGVkIHR5cGVzLCB3aGljaCByZXF1aXJlcyByZXR1cm5pbmcgdGhlCisgIC8vICAgZGVzY3JpcHRvciBvciBhbiBvYmplY3QgYmFzZWQgb24gaXQuCisgIC8vICogU29tZW9uZSBsb29rcyB1cCB0aGUgZGVzY3JpcHRvciBpbiBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS4KKyAgLy8KKyAgLy8gT25jZSBvbmUgb2YgdGhlc2UgaGFwcGVucywgdGhlIERlc2NyaXB0b3JQb29sIGFjdHVhbGx5IHBhcnNlcyB0aGUKKyAgLy8gRmlsZURlc2NyaXB0b3JQcm90byBhbmQgZ2VuZXJhdGVzIGEgRmlsZURlc2NyaXB0b3IgKGFuZCBhbGwgaXRzIGNoaWxkcmVuKQorICAvLyBiYXNlZCBvbiBpdC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IEZpbGVEZXNjcmlwdG9yUHJvdG8gaXMgaXRzZWxmIGEgZ2VuZXJhdGVkIHByb3RvY29sIG1lc3NhZ2UuCisgIC8vIFRoZXJlZm9yZSwgd2hlbiB3ZSBwYXJzZSBvbmUsIHdlIGhhdmUgdG8gYmUgdmVyeSBjYXJlZnVsIHRvIGF2b2lkIHVzaW5nCisgIC8vIGFueSBkZXNjcmlwdG9yLWJhc2VkIG9wZXJhdGlvbnMsIHNpbmNlIHRoaXMgbWlnaHQgY2F1c2UgaW5maW5pdGUgcmVjdXJzaW9uCisgIC8vIG9yIGRlYWRsb2NrLgorICBJbml0R2VuZXJhdGVkUG9vbE9uY2UoKTsKKyAgR09PR0xFX0NIRUNLKGdlbmVyYXRlZF9kYXRhYmFzZV8tPkFkZChlbmNvZGVkX2ZpbGVfZGVzY3JpcHRvciwgc2l6ZSkpOworfQorCisKKy8vIEZpbmQqQnkqIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVE9ETyhrZW50b24pOiAgVGhlcmUncyBhIGxvdCBvZiByZXBlYXRlZCBjb2RlIGhlcmUsIGJ1dCBJJ20gbm90IHN1cmUgaWYKKy8vICAgdGhlcmUncyBhbnkgZ29vZCB3YXkgdG8gZmFjdG9yIGl0IG91dC4gIFRoaW5rIGFib3V0IHRoaXMgc29tZSB0aW1lIHdoZW4KKy8vICAgdGhlcmUncyBub3RoaW5nIG1vcmUgaW1wb3J0YW50IHRvIGRvIChyZWFkOiBuZXZlcikuCisKK2NvbnN0IEZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIE11dGV4TG9ja01heWJlIGxvY2sobXV0ZXhfKTsKKyAgdGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmNsZWFyKCk7CisgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY2xlYXIoKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRGaWxlKG5hbWUpOworICBpZiAocmVzdWx0ICE9IE5VTEwpIHJldHVybiByZXN1bHQ7CisgIGlmICh1bmRlcmxheV8gIT0gTlVMTCkgeworICAgIHJlc3VsdCA9IHVuZGVybGF5Xy0+RmluZEZpbGVCeU5hbWUobmFtZSk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSByZXR1cm4gcmVzdWx0OworICB9CisgIGlmIChUcnlGaW5kRmlsZUluRmFsbGJhY2tEYXRhYmFzZShuYW1lKSkgeworICAgIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRGaWxlKG5hbWUpOworICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgcmV0dXJuIHJlc3VsdDsKKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworY29uc3QgRmlsZURlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSkgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kU3ltYm9sKHN5bWJvbF9uYW1lKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHJldHVybiByZXN1bHQuR2V0RmlsZSgpOworICBpZiAodW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV9yZXN1bHQgPQorICAgICAgdW5kZXJsYXlfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woc3ltYm9sX25hbWUpOworICAgIGlmIChmaWxlX3Jlc3VsdCAhPSBOVUxMKSByZXR1cm4gZmlsZV9yZXN1bHQ7CisgIH0KKyAgaWYgKFRyeUZpbmRTeW1ib2xJbkZhbGxiYWNrRGF0YWJhc2Uoc3ltYm9sX25hbWUpKSB7CisgICAgcmVzdWx0ID0gdGFibGVzXy0+RmluZFN5bWJvbChzeW1ib2xfbmFtZSk7CisgICAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHJldHVybiByZXN1bHQuR2V0RmlsZSgpOworICB9CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gdGFibGVzXy0+RmluZEJ5TmFtZUhlbHBlcih0aGlzLCBuYW1lKTsKKyAgcmV0dXJuIChyZXN1bHQudHlwZSA9PSBTeW1ib2w6Ok1FU1NBR0UpID8gcmVzdWx0LmRlc2NyaXB0b3IgOiBOVUxMOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kRmllbGRCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICBpZiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpGSUVMRCAmJgorICAgICAgIXJlc3VsdC5maWVsZF9kZXNjcmlwdG9yLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiByZXN1bHQuZmllbGRfZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kRXh0ZW5zaW9uQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gdGFibGVzXy0+RmluZEJ5TmFtZUhlbHBlcih0aGlzLCBuYW1lKTsKKyAgaWYgKHJlc3VsdC50eXBlID09IFN5bWJvbDo6RklFTEQgJiYKKyAgICAgIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiByZXN1bHQuZmllbGRfZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBPbmVvZkRlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kT25lb2ZCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICByZXR1cm4gKHJlc3VsdC50eXBlID09IFN5bWJvbDo6T05FT0YpID8gcmVzdWx0Lm9uZW9mX2Rlc2NyaXB0b3IgOiBOVUxMOworfQorCitjb25zdCBFbnVtRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkZpbmRFbnVtVHlwZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRCeU5hbWVIZWxwZXIodGhpcywgbmFtZSk7CisgIHJldHVybiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpFTlVNKSA/IHJlc3VsdC5lbnVtX2Rlc2NyaXB0b3IgOiBOVUxMOworfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZEVudW1WYWx1ZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRCeU5hbWVIZWxwZXIodGhpcywgbmFtZSk7CisgIHJldHVybiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpFTlVNX1ZBTFVFKSA/CisgICAgcmVzdWx0LmVudW1fdmFsdWVfZGVzY3JpcHRvciA6IE5VTEw7Cit9CisKK2NvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZFNlcnZpY2VCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICByZXR1cm4gKHJlc3VsdC50eXBlID09IFN5bWJvbDo6U0VSVklDRSkgPyByZXN1bHQuc2VydmljZV9kZXNjcmlwdG9yIDogTlVMTDsKK30KKworY29uc3QgTWV0aG9kRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkZpbmRNZXRob2RCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICByZXR1cm4gKHJlc3VsdC50eXBlID09IFN5bWJvbDo6TUVUSE9EKSA/IHJlc3VsdC5tZXRob2RfZGVzY3JpcHRvciA6IE5VTEw7Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkZpbmRFeHRlbnNpb25CeU51bWJlcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBleHRlbmRlZSwgaW50IG51bWJlcikgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0gdGFibGVzXy0+RmluZEV4dGVuc2lvbihleHRlbmRlZSwgbnVtYmVyKTsKKyAgaWYgKHJlc3VsdCAhPSBOVUxMKSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorICBpZiAodW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICByZXN1bHQgPSB1bmRlcmxheV8tPkZpbmRFeHRlbnNpb25CeU51bWJlcihleHRlbmRlZSwgbnVtYmVyKTsKKyAgICBpZiAocmVzdWx0ICE9IE5VTEwpIHJldHVybiByZXN1bHQ7CisgIH0KKyAgaWYgKFRyeUZpbmRFeHRlbnNpb25JbkZhbGxiYWNrRGF0YWJhc2UoZXh0ZW5kZWUsIG51bWJlcikpIHsKKyAgICByZXN1bHQgPSB0YWJsZXNfLT5GaW5kRXh0ZW5zaW9uKGV4dGVuZGVlLCBudW1iZXIpOworICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclBvb2w6OkZpbmRBbGxFeHRlbnNpb25zKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlLCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dCkgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisKKyAgLy8gSW5pdGlhbGl6ZSB0YWJsZXNfLT5leHRlbnNpb25zXyBmcm9tIHRoZSBmYWxsYmFjayBkYXRhYmFzZSBmaXJzdAorICAvLyAoYnV0IGRvIHRoaXMgb25seSBvbmNlIHBlciBkZXNjcmlwdG9yKS4KKyAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXyAhPSBOVUxMICYmCisgICAgICB0YWJsZXNfLT5leHRlbnNpb25zX2xvYWRlZF9mcm9tX2RiXy5jb3VudChleHRlbmRlZSkgPT0gMCkgeworICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXy0+RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoZXh0ZW5kZWUtPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1iZXJzKSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1iZXJzLnNpemUoKTsgKytpKSB7CisgICAgICAgIGludCBudW1iZXIgPSBudW1iZXJzW2ldOworICAgICAgICBpZiAodGFibGVzXy0+RmluZEV4dGVuc2lvbihleHRlbmRlZSwgbnVtYmVyKSA9PSBOVUxMKSB7CisgICAgICAgICAgVHJ5RmluZEV4dGVuc2lvbkluRmFsbGJhY2tEYXRhYmFzZShleHRlbmRlZSwgbnVtYmVyKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgdGFibGVzXy0+ZXh0ZW5zaW9uc19sb2FkZWRfZnJvbV9kYl8uaW5zZXJ0KGV4dGVuZGVlKTsKKyAgICB9CisgIH0KKworICB0YWJsZXNfLT5GaW5kQWxsRXh0ZW5zaW9ucyhleHRlbmRlZSwgb3V0KTsKKyAgaWYgKHVuZGVybGF5XyAhPSBOVUxMKSB7CisgICAgdW5kZXJsYXlfLT5GaW5kQWxsRXh0ZW5zaW9ucyhleHRlbmRlZSwgb3V0KTsKKyAgfQorfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlOdW1iZXIoaW50IGtleSkgY29uc3QgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kRmllbGRCeU51bWJlcih0aGlzLCBrZXkpOworICBpZiAocmVzdWx0ID09IE5VTEwgfHwgcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSh0aGlzLCBrZXkpOworICBpZiAocmVzdWx0ID09IE5VTEwgfHwgcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSh0aGlzLCBrZXkpOworICBpZiAocmVzdWx0ID09IE5VTEwgfHwgcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPQorICAgIGZpbGUoKS0+dGFibGVzXy0+RmluZE5lc3RlZFN5bWJvbE9mVHlwZSh0aGlzLCBrZXksIFN5bWJvbDo6RklFTEQpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSAmJiAhcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IE9uZW9mRGVzY3JpcHRvcioKK0Rlc2NyaXB0b3I6OkZpbmRPbmVvZkJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6Ok9ORU9GKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0Lm9uZW9mX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEV4dGVuc2lvbkJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkZJRUxEKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkgJiYgcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvcioKK0Rlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPQorICAgIGZpbGUoKS0+dGFibGVzXy0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKHRoaXMsIGtleSk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCB8fCAhcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUodGhpcywga2V5KTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMIHx8ICFyZXN1bHQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCitjb25zdCBEZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZE5lc3RlZFR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpNRVNTQUdFKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0LmRlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRW51bURlc2NyaXB0b3IqCitEZXNjcmlwdG9yOjpGaW5kRW51bVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpFTlVNKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0LmVudW1fZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEVudW1WYWx1ZUJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkVOVU1fVkFMVUUpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQuZW51bV92YWx1ZV9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqCitFbnVtRGVzY3JpcHRvcjo6RmluZFZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPQorICAgIGZpbGUoKS0+dGFibGVzXy0+RmluZE5lc3RlZFN5bWJvbE9mVHlwZSh0aGlzLCBrZXksIFN5bWJvbDo6RU5VTV9WQUxVRSk7CisgIGlmICghcmVzdWx0LklzTnVsbCgpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5lbnVtX3ZhbHVlX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcioKK0VudW1EZXNjcmlwdG9yOjpGaW5kVmFsdWVCeU51bWJlcihpbnQga2V5KSBjb25zdCB7CisgIHJldHVybiBmaWxlKCktPnRhYmxlc18tPkZpbmRFbnVtVmFsdWVCeU51bWJlcih0aGlzLCBrZXkpOworfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKgorRW51bURlc2NyaXB0b3I6OkZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oaW50IGtleSkgY29uc3QgeworICByZXR1cm4gZmlsZSgpLT50YWJsZXNfLT5GaW5kRW51bVZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih0aGlzLCBrZXkpOworfQorCitjb25zdCBNZXRob2REZXNjcmlwdG9yKgorU2VydmljZURlc2NyaXB0b3I6OkZpbmRNZXRob2RCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpNRVRIT0QpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQubWV0aG9kX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kTWVzc2FnZVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6Ok1FU1NBR0UpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQuZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBFbnVtRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kRW51bVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkVOVU0pOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQuZW51bV9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqCitGaWxlRGVzY3JpcHRvcjo6RmluZEVudW1WYWx1ZUJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICB0YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpFTlVNX1ZBTFVFKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0LmVudW1fdmFsdWVfZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBTZXJ2aWNlRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kU2VydmljZUJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gdGFibGVzXy0+RmluZE5lc3RlZFN5bWJvbE9mVHlwZSh0aGlzLCBrZXksIFN5bWJvbDo6U0VSVklDRSk7CisgIGlmICghcmVzdWx0LklzTnVsbCgpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5zZXJ2aWNlX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRmlsZURlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkZJRUxEKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkgJiYgcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0gdGFibGVzXy0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKHRoaXMsIGtleSk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCB8fCAhcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRmlsZURlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPSB0YWJsZXNfLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUodGhpcywga2V5KTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMIHx8ICFyZXN1bHQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCitjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSoKK0Rlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25SYW5nZUNvbnRhaW5pbmdOdW1iZXIoaW50IG51bWJlcikgY29uc3QgeworICAvLyBMaW5lYXIgc2VhcmNoIHNob3VsZCBiZSBmaW5lIGJlY2F1c2Ugd2UgZG9uJ3QgZXhwZWN0IGEgbWVzc2FnZSB0byBoYXZlCisgIC8vIG1vcmUgdGhhbiBhIGNvdXBsZSBleHRlbnNpb24gcmFuZ2VzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAobnVtYmVyID49IGV4dGVuc2lvbl9yYW5nZShpKS0+c3RhcnQgJiYKKyAgICAgICAgbnVtYmVyIDwgIGV4dGVuc2lvbl9yYW5nZShpKS0+ZW5kKSB7CisgICAgICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlKGkpOworICAgIH0KKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitib29sIERlc2NyaXB0b3JQb29sOjpUcnlGaW5kRmlsZUluRmFsbGJhY2tEYXRhYmFzZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgaWYgKHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY291bnQobmFtZSkgPiAwKSByZXR1cm4gZmFsc2U7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBpZiAoIWZhbGxiYWNrX2RhdGFiYXNlXy0+RmluZEZpbGVCeU5hbWUobmFtZSwgJmZpbGVfcHJvdG8pIHx8CisgICAgICBCdWlsZEZpbGVGcm9tRGF0YWJhc2UoZmlsZV9wcm90bykgPT0gTlVMTCkgeworICAgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uaW5zZXJ0KG5hbWUpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6SXNTdWJTeW1ib2xPZkJ1aWx0VHlwZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeCA9IG5hbWU7CisgIGZvciAoOzspIHsKKyAgICBzdHJpbmc6OnNpemVfdHlwZSBkb3RfcG9zID0gcHJlZml4LmZpbmRfbGFzdF9vZignLicpOworICAgIGlmIChkb3RfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgYnJlYWs7CisgICAgfQorICAgIHByZWZpeCA9IHByZWZpeC5zdWJzdHIoMCwgZG90X3Bvcyk7CisgICAgU3ltYm9sIHN5bWJvbCA9IHRhYmxlc18tPkZpbmRTeW1ib2wocHJlZml4KTsKKyAgICAvLyBJZiB0aGUgc3ltYm9sIHR5cGUgaXMgYW55dGhpbmcgb3RoZXIgdGhhbiBQQUNLQUdFLCB0aGVuIGl0cyBjb21wbGV0ZQorICAgIC8vIGRlZmluaXRpb24gaXMgYWxyZWFkeSBrbm93bi4KKyAgICBpZiAoIXN5bWJvbC5Jc051bGwoKSAmJiBzeW1ib2wudHlwZSAhPSBTeW1ib2w6OlBBQ0tBR0UpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICBpZiAodW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICAvLyBDaGVjayB0byBzZWUgaWYgYW55IHByZWZpeCBvZiB0aGlzIHN5bWJvbCBleGlzdHMgaW4gdGhlIHVuZGVybGF5LgorICAgIHJldHVybiB1bmRlcmxheV8tPklzU3ViU3ltYm9sT2ZCdWlsdFR5cGUobmFtZSk7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIERlc2NyaXB0b3JQb29sOjpUcnlGaW5kU3ltYm9sSW5GYWxsYmFja0RhdGFiYXNlKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBpZiAoZmFsbGJhY2tfZGF0YWJhc2VfID09IE5VTEwpIHJldHVybiBmYWxzZTsKKworICBpZiAodGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmNvdW50KG5hbWUpID4gMCkgcmV0dXJuIGZhbHNlOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgaWYgKC8vIFdlIHNraXAgbG9va2luZyBpbiB0aGUgZmFsbGJhY2sgZGF0YWJhc2UgaWYgdGhlIG5hbWUgaXMgYSBzdWItc3ltYm9sCisgICAgICAvLyBvZiBhbnkgZGVzY3JpcHRvciB0aGF0IGFscmVhZHkgZXhpc3RzIGluIHRoZSBkZXNjcmlwdG9yIHBvb2wgKGV4Y2VwdAorICAgICAgLy8gZm9yIHBhY2thZ2UgZGVzY3JpcHRvcnMpLiAgVGhpcyBpcyB2YWxpZCBiZWNhdXNlIGFsbCBzeW1ib2xzIGV4Y2VwdAorICAgICAgLy8gZm9yIHBhY2thZ2VzIGFyZSBkZWZpbmVkIGluIGEgc2luZ2xlIGZpbGUsIHNvIGlmIHRoZSBzeW1ib2wgZXhpc3RzCisgICAgICAvLyB0aGVuIHdlIHNob3VsZCBhbHJlYWR5IGhhdmUgaXRzIGRlZmluaXRpb24uCisgICAgICAvLworICAgICAgLy8gVGhlIG90aGVyIHJlYXNvbiB0byBkbyB0aGlzIGlzIHRvIHN1cHBvcnQgIm92ZXJyaWRpbmciIHR5cGUKKyAgICAgIC8vIGRlZmluaXRpb25zIGJ5IG1lcmdpbmcgdHdvIGRhdGFiYXNlcyB0aGF0IGRlZmluZSB0aGUgc2FtZSB0eXBlLiAgKFllcywKKyAgICAgIC8vIHBlb3BsZSBkbyB0aGlzLikgIFRoZSBtYWluIGRpZmZpY3VsdHkgd2l0aCBtYWtpbmcgdGhpcyB3b3JrIGlzIHRoYXQKKyAgICAgIC8vIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgpIGlzIGFsbG93ZWQgdG8gcmV0dXJuIGJvdGggZmFsc2UgcG9zaXRpdmVzCisgICAgICAvLyAoZS5nLiwgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlLCBVcGdyYWRlZERlc2NyaXB0b3JEYXRhYmFzZSkgYW5kIGZhbHNlCisgICAgICAvLyBuZWdhdGl2ZXMgKGUuZy4gUHJvdG9GaWxlUGFyc2VyLCBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKS4KKyAgICAgIC8vIFdoZW4gdHdvIHN1Y2ggZGF0YWJhc2VzIGFyZSBtZXJnZWQsIGxvb2tpbmcgdXAgYSBub24tZXhpc3RlbnQKKyAgICAgIC8vIHN1Yi1zeW1ib2wgb2YgYSB0eXBlIHRoYXQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGRlc2NyaXB0b3IgcG9vbCBjYW4KKyAgICAgIC8vIHJlc3VsdCBpbiBhbiBhdHRlbXB0IHRvIGxvYWQgbXVsdGlwbGUgZGVmaW5pdGlvbnMgb2YgdGhlIHNhbWUgdHlwZS4KKyAgICAgIC8vIFRoZSBjaGVjayBiZWxvdyBhdm9pZHMgdGhpcy4KKyAgICAgIElzU3ViU3ltYm9sT2ZCdWlsdFR5cGUobmFtZSkKKworICAgICAgLy8gTG9vayB1cCBmaWxlIGNvbnRhaW5pbmcgdGhpcyBzeW1ib2wgaW4gZmFsbGJhY2sgZGF0YWJhc2UuCisgICAgICB8fCAhZmFsbGJhY2tfZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2wobmFtZSwgJmZpbGVfcHJvdG8pCisKKyAgICAgIC8vIENoZWNrIGlmIHdlJ3ZlIGFscmVhZHkgYnVpbHQgdGhpcyBmaWxlLiBJZiBzbywgaXQgYXBwYXJlbnRseSBkb2Vzbid0CisgICAgICAvLyBjb250YWluIHRoZSBzeW1ib2wgd2UncmUgbG9va2luZyBmb3IuICBTb21lIERlc2NyaXB0b3JEYXRhYmFzZXMKKyAgICAgIC8vIHJldHVybiBmYWxzZSBwb3NpdGl2ZXMuCisgICAgICB8fCB0YWJsZXNfLT5GaW5kRmlsZShmaWxlX3Byb3RvLm5hbWUoKSkgIT0gTlVMTAorCisgICAgICAvLyBCdWlsZCB0aGUgZmlsZS4KKyAgICAgIHx8IEJ1aWxkRmlsZUZyb21EYXRhYmFzZShmaWxlX3Byb3RvKSA9PSBOVUxMKSB7CisgICAgdGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmluc2VydChuYW1lKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6VHJ5RmluZEV4dGVuc2lvbkluRmFsbGJhY2tEYXRhYmFzZSgKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUsIGludCBmaWVsZF9udW1iZXIpIGNvbnN0IHsKKyAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBpZiAoIWZhbGxiYWNrX2RhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgICAgICBjb250YWluaW5nX3R5cGUtPmZ1bGxfbmFtZSgpLCBmaWVsZF9udW1iZXIsICZmaWxlX3Byb3RvKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmICh0YWJsZXNfLT5GaW5kRmlsZShmaWxlX3Byb3RvLm5hbWUoKSkgIT0gTlVMTCkgeworICAgIC8vIFdlJ3ZlIGFscmVhZHkgbG9hZGVkIHRoaXMgZmlsZSwgYW5kIGl0IGFwcGFyZW50bHkgZG9lc24ndCBjb250YWluIHRoZQorICAgIC8vIGV4dGVuc2lvbiB3ZSdyZSBsb29raW5nIGZvci4gIFNvbWUgRGVzY3JpcHRvckRhdGFiYXNlcyByZXR1cm4gZmFsc2UKKyAgICAvLyBwb3NpdGl2ZXMuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaWYgKEJ1aWxkRmlsZUZyb21EYXRhYmFzZShmaWxlX3Byb3RvKSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworYm9vbCBGaWVsZERlc2NyaXB0b3I6OmlzX21hcCgpIGNvbnN0IHsKKyAgcmV0dXJuIHR5cGUoKSA9PSBUWVBFX01FU1NBR0UgJiYgbWVzc2FnZV90eXBlKCktPm9wdGlvbnMoKS5tYXBfZW50cnkoKTsKK30KKworc3RyaW5nIEZpZWxkRGVzY3JpcHRvcjo6RGVmYXVsdFZhbHVlQXNTdHJpbmcoYm9vbCBxdW90ZV9zdHJpbmdfdHlwZSkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soaGFzX2RlZmF1bHRfdmFsdWUoKSkgPDwgIk5vIGRlZmF1bHQgdmFsdWUiOworICBzd2l0Y2ggKGNwcF90eXBlKCkpIHsKKyAgICBjYXNlIENQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZWZhdWx0X3ZhbHVlX2ludDMyKCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZWZhdWx0X3ZhbHVlX3VpbnQzMigpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBTaW1wbGVGdG9hKGRlZmF1bHRfdmFsdWVfZmxvYXQoKSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIENQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIFNpbXBsZUR0b2EoZGVmYXVsdF92YWx1ZV9kb3VibGUoKSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIENQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlX2Jvb2woKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgICAgICBicmVhazsKKyAgICBjYXNlIENQUFRZUEVfU1RSSU5HOgorICAgICAgaWYgKHF1b3RlX3N0cmluZ190eXBlKSB7CisgICAgICAgIHJldHVybiAiXCIiICsgQ0VzY2FwZShkZWZhdWx0X3ZhbHVlX3N0cmluZygpKSArICJcIiI7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAodHlwZSgpID09IFRZUEVfQllURVMpIHsKKyAgICAgICAgICByZXR1cm4gQ0VzY2FwZShkZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gZGVmYXVsdF92YWx1ZV9zdHJpbmcoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBDUFBUWVBFX0VOVU06CisgICAgICByZXR1cm4gZGVmYXVsdF92YWx1ZV9lbnVtKCktPm5hbWUoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9NRVNTQUdFOgorICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzISI7CisgICAgICBicmVhazsKKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmU6IGZhaWxlZCB0byBnZXQgZGVmYXVsdCB2YWx1ZSBhcyBzdHJpbmciOworICByZXR1cm4gIiI7Cit9CisKKy8vIENvcHlUbyBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBGaWxlRGVzY3JpcHRvcjo6Q29weVRvKEZpbGVEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworICBpZiAoIXBhY2thZ2UoKS5lbXB0eSgpKSBwcm90by0+c2V0X3BhY2thZ2UocGFja2FnZSgpKTsKKyAgLy8gVE9ETyhsaXVqaXNpKTogQWxzbyBwb3B1bGF0ZSB3aGVuIHN5bnRheD0icHJvdG8yIi4KKyAgaWYgKHN5bnRheCgpID09IFNZTlRBWF9QUk9UTzMpIHByb3RvLT5zZXRfc3ludGF4KFN5bnRheE5hbWUoc3ludGF4KCkpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgcHJvdG8tPmFkZF9kZXBlbmRlbmN5KGRlcGVuZGVuY3koaSktPm5hbWUoKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IHB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIHByb3RvLT5hZGRfcHVibGljX2RlcGVuZGVuY3kocHVibGljX2RlcGVuZGVuY2llc19baV0pOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB3ZWFrX2RlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgcHJvdG8tPmFkZF93ZWFrX2RlcGVuZGVuY3kod2Vha19kZXBlbmRlbmNpZXNfW2ldKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfdHlwZShpKS0+Q29weVRvKHByb3RvLT5hZGRfbWVzc2FnZV90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fdHlwZShpKS0+Q29weVRvKHByb3RvLT5hZGRfZW51bV90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBzZXJ2aWNlKGkpLT5Db3B5VG8ocHJvdG8tPmFkZF9zZXJ2aWNlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbihpKS0+Q29weVRvKHByb3RvLT5hZGRfZXh0ZW5zaW9uKCkpOworICB9CisKKyAgaWYgKCZvcHRpb25zKCkgIT0gJkZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvcjo6Q29weVNvdXJjZUNvZGVJbmZvVG8oRmlsZURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0IHsKKyAgaWYgKHNvdXJjZV9jb2RlX2luZm9fICYmCisgICAgICBzb3VyY2VfY29kZV9pbmZvXyAhPSAmU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX3NvdXJjZV9jb2RlX2luZm8oKS0+Q29weUZyb20oKnNvdXJjZV9jb2RlX2luZm9fKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3I6OkNvcHlUbyhEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGQoaSktPkNvcHlUbyhwcm90by0+YWRkX2ZpZWxkKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBvbmVvZl9kZWNsKGkpLT5Db3B5VG8ocHJvdG8tPmFkZF9vbmVvZl9kZWNsKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbmVzdGVkX3R5cGUoaSktPkNvcHlUbyhwcm90by0+YWRkX25lc3RlZF90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fdHlwZShpKS0+Q29weVRvKHByb3RvLT5hZGRfZW51bV90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7IGkrKykgeworICAgIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlID0gcHJvdG8tPmFkZF9leHRlbnNpb25fcmFuZ2UoKTsKKyAgICByYW5nZS0+c2V0X3N0YXJ0KGV4dGVuc2lvbl9yYW5nZShpKS0+c3RhcnQpOworICAgIHJhbmdlLT5zZXRfZW5kKGV4dGVuc2lvbl9yYW5nZShpKS0+ZW5kKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb24oaSktPkNvcHlUbyhwcm90by0+YWRkX2V4dGVuc2lvbigpKTsKKyAgfQorCisgIGlmICgmb3B0aW9ucygpICE9ICZNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKSB7CisgICAgcHJvdG8tPm11dGFibGVfb3B0aW9ucygpLT5Db3B5RnJvbShvcHRpb25zKCkpOworICB9Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yOjpDb3B5VG8oRmllbGREZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworICBwcm90by0+c2V0X251bWJlcihudW1iZXIoKSk7CisKKyAgLy8gU29tZSBjb21waWxlcnMgZG8gbm90IGFsbG93IHN0YXRpY19jYXN0IGRpcmVjdGx5IGJldHdlZW4gdHdvIGVudW0gdHlwZXMsCisgIC8vIHNvIHdlIG11c3QgY2FzdCB0byBpbnQgZmlyc3QuCisgIHByb3RvLT5zZXRfbGFiZWwoc3RhdGljX2Nhc3Q8RmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsPigKKyAgICAgICAgICAgICAgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50PihsYWJlbCgpKSkpOworICBwcm90by0+c2V0X3R5cGUoc3RhdGljX2Nhc3Q8RmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGU+KAorICAgICAgICAgICAgICAgICAgICBpbXBsaWNpdF9jYXN0PGludD4odHlwZSgpKSkpOworCisgIGlmIChpc19leHRlbnNpb24oKSkgeworICAgIGlmICghY29udGFpbmluZ190eXBlKCktPmlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXykgeworICAgICAgcHJvdG8tPnNldF9leHRlbmRlZSgiLiIpOworICAgIH0KKyAgICBwcm90by0+bXV0YWJsZV9leHRlbmRlZSgpLT5hcHBlbmQoY29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpKTsKKyAgfQorCisgIGlmIChjcHBfdHlwZSgpID09IENQUFRZUEVfTUVTU0FHRSkgeworICAgIGlmIChtZXNzYWdlX3R5cGUoKS0+aXNfcGxhY2Vob2xkZXJfKSB7CisgICAgICAvLyBXZSBkb24ndCBhY3R1YWxseSBrbm93IGlmIHRoZSB0eXBlIGlzIGEgbWVzc2FnZSB0eXBlLiAgSXQgY291bGQgYmUKKyAgICAgIC8vIGFuIGVudW0uCisgICAgICBwcm90by0+Y2xlYXJfdHlwZSgpOworICAgIH0KKworICAgIGlmICghbWVzc2FnZV90eXBlKCktPmlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXykgeworICAgICAgcHJvdG8tPnNldF90eXBlX25hbWUoIi4iKTsKKyAgICB9CisgICAgcHJvdG8tPm11dGFibGVfdHlwZV9uYW1lKCktPmFwcGVuZChtZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICB9IGVsc2UgaWYgKGNwcF90eXBlKCkgPT0gQ1BQVFlQRV9FTlVNKSB7CisgICAgaWYgKCFlbnVtX3R5cGUoKS0+aXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfKSB7CisgICAgICBwcm90by0+c2V0X3R5cGVfbmFtZSgiLiIpOworICAgIH0KKyAgICBwcm90by0+bXV0YWJsZV90eXBlX25hbWUoKS0+YXBwZW5kKGVudW1fdHlwZSgpLT5mdWxsX25hbWUoKSk7CisgIH0KKworICBpZiAoaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIHByb3RvLT5zZXRfZGVmYXVsdF92YWx1ZShEZWZhdWx0VmFsdWVBc1N0cmluZyhmYWxzZSkpOworICB9CisKKyAgaWYgKGNvbnRhaW5pbmdfb25lb2YoKSAhPSBOVUxMICYmICFpc19leHRlbnNpb24oKSkgeworICAgIHByb3RvLT5zZXRfb25lb2ZfaW5kZXgoY29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpKTsKKyAgfQorCisgIGlmICgmb3B0aW9ucygpICE9ICZGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX29wdGlvbnMoKS0+Q29weUZyb20ob3B0aW9ucygpKTsKKyAgfQorfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvcjo6Q29weVRvKE9uZW9mRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3QgeworICBwcm90by0+c2V0X25hbWUobmFtZSgpKTsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvcjo6Q29weVRvKEVudW1EZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgdmFsdWUoaSktPkNvcHlUbyhwcm90by0+YWRkX3ZhbHVlKCkpOworICB9CisKKyAgaWYgKCZvcHRpb25zKCkgIT0gJkVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yOjpDb3B5VG8oRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3QgeworICBwcm90by0+c2V0X25hbWUobmFtZSgpKTsKKyAgcHJvdG8tPnNldF9udW1iZXIobnVtYmVyKCkpOworCisgIGlmICgmb3B0aW9ucygpICE9ICZFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvcjo6Q29weVRvKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIG1ldGhvZChpKS0+Q29weVRvKHByb3RvLT5hZGRfbWV0aG9kKCkpOworICB9CisKKyAgaWYgKCZvcHRpb25zKCkgIT0gJlNlcnZpY2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yOjpDb3B5VG8oTWV0aG9kRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3QgeworICBwcm90by0+c2V0X25hbWUobmFtZSgpKTsKKworICBpZiAoIWlucHV0X3R5cGUoKS0+aXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfKSB7CisgICAgcHJvdG8tPnNldF9pbnB1dF90eXBlKCIuIik7CisgIH0KKyAgcHJvdG8tPm11dGFibGVfaW5wdXRfdHlwZSgpLT5hcHBlbmQoaW5wdXRfdHlwZSgpLT5mdWxsX25hbWUoKSk7CisKKyAgaWYgKCFvdXRwdXRfdHlwZSgpLT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8pIHsKKyAgICBwcm90by0+c2V0X291dHB1dF90eXBlKCIuIik7CisgIH0KKyAgcHJvdG8tPm11dGFibGVfb3V0cHV0X3R5cGUoKS0+YXBwZW5kKG91dHB1dF90eXBlKCktPmZ1bGxfbmFtZSgpKTsKKworICBpZiAoJm9wdGlvbnMoKSAhPSAmTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKSB7CisgICAgcHJvdG8tPm11dGFibGVfb3B0aW9ucygpLT5Db3B5RnJvbShvcHRpb25zKCkpOworICB9CisKKyAgaWYgKGNsaWVudF9zdHJlYW1pbmdfKSB7CisgICAgcHJvdG8tPnNldF9jbGllbnRfc3RyZWFtaW5nKHRydWUpOworICB9CisgIGlmIChzZXJ2ZXJfc3RyZWFtaW5nXykgeworICAgIHByb3RvLT5zZXRfc2VydmVyX3N0cmVhbWluZyh0cnVlKTsKKyAgfQorfQorCisvLyBEZWJ1Z1N0cmluZyBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK25hbWVzcGFjZSB7CisKKy8vIFVzZWQgYnkgZWFjaCBvZiB0aGUgb3B0aW9uIGZvcm1hdHRlcnMuCitib29sIFJldHJpZXZlT3B0aW9ucyhpbnQgZGVwdGgsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlICZvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4gKm9wdGlvbl9lbnRyaWVzKSB7CisgIG9wdGlvbl9lbnRyaWVzLT5jbGVhcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gb3B0aW9ucy5HZXRSZWZsZWN0aW9uKCk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMob3B0aW9ucywgJmZpZWxkcyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgaW50IGNvdW50ID0gMTsKKyAgICBib29sIHJlcGVhdGVkID0gZmFsc2U7CisgICAgaWYgKGZpZWxkc1tpXS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgY291bnQgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUob3B0aW9ucywgZmllbGRzW2ldKTsKKyAgICAgIHJlcGVhdGVkID0gdHJ1ZTsKKyAgICB9CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CisgICAgICBzdHJpbmcgZmllbGR2YWw7CisgICAgICBpZiAoZmllbGRzW2ldLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICAgIHN0cmluZyB0bXA7CisgICAgICAgIFRleHRGb3JtYXQ6OlByaW50ZXIgcHJpbnRlcjsKKyAgICAgICAgcHJpbnRlci5TZXRJbml0aWFsSW5kZW50TGV2ZWwoZGVwdGggKyAxKTsKKyAgICAgICAgcHJpbnRlci5QcmludEZpZWxkVmFsdWVUb1N0cmluZyhvcHRpb25zLCBmaWVsZHNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWQgPyBqIDogLTEsICZ0bXApOworICAgICAgICBmaWVsZHZhbC5hcHBlbmQoIntcbiIpOworICAgICAgICBmaWVsZHZhbC5hcHBlbmQodG1wKTsKKyAgICAgICAgZmllbGR2YWwuYXBwZW5kKGRlcHRoICogMiwgJyAnKTsKKyAgICAgICAgZmllbGR2YWwuYXBwZW5kKCJ9Iik7CisgICAgICB9IGVsc2UgeworICAgICAgICBUZXh0Rm9ybWF0OjpQcmludEZpZWxkVmFsdWVUb1N0cmluZyhvcHRpb25zLCBmaWVsZHNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkID8gaiA6IC0xLCAmZmllbGR2YWwpOworICAgICAgfQorICAgICAgc3RyaW5nIG5hbWU7CisgICAgICBpZiAoZmllbGRzW2ldLT5pc19leHRlbnNpb24oKSkgeworICAgICAgICBuYW1lID0gIiguIiArIGZpZWxkc1tpXS0+ZnVsbF9uYW1lKCkgKyAiKSI7CisgICAgICB9IGVsc2UgeworICAgICAgICBuYW1lID0gZmllbGRzW2ldLT5uYW1lKCk7CisgICAgICB9CisgICAgICBvcHRpb25fZW50cmllcy0+cHVzaF9iYWNrKG5hbWUgKyAiID0gIiArIGZpZWxkdmFsKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuICFvcHRpb25fZW50cmllcy0+ZW1wdHkoKTsKK30KKworLy8gRm9ybWF0cyBvcHRpb25zIHRoYXQgYWxsIGFwcGVhciB0b2dldGhlciBpbiBicmFja2V0cy4gRG9lcyBub3QgaW5jbHVkZQorLy8gYnJhY2tldHMuCitib29sIEZvcm1hdEJyYWNrZXRlZE9wdGlvbnMoaW50IGRlcHRoLCBjb25zdCBNZXNzYWdlICZvcHRpb25zLCBzdHJpbmcgKm91dHB1dCkgeworICB2ZWN0b3I8c3RyaW5nPiBhbGxfb3B0aW9uczsKKyAgaWYgKFJldHJpZXZlT3B0aW9ucyhkZXB0aCwgb3B0aW9ucywgJmFsbF9vcHRpb25zKSkgeworICAgIG91dHB1dC0+YXBwZW5kKEpvaW4oYWxsX29wdGlvbnMsICIsICIpKTsKKyAgfQorICByZXR1cm4gIWFsbF9vcHRpb25zLmVtcHR5KCk7Cit9CisKKy8vIEZvcm1hdHMgb3B0aW9ucyBvbmUgcGVyIGxpbmUKK2Jvb2wgRm9ybWF0TGluZU9wdGlvbnMoaW50IGRlcHRoLCBjb25zdCBNZXNzYWdlICZvcHRpb25zLCBzdHJpbmcgKm91dHB1dCkgeworICBzdHJpbmcgcHJlZml4KGRlcHRoICogMiwgJyAnKTsKKyAgdmVjdG9yPHN0cmluZz4gYWxsX29wdGlvbnM7CisgIGlmIChSZXRyaWV2ZU9wdGlvbnMoZGVwdGgsIG9wdGlvbnMsICZhbGxfb3B0aW9ucykpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsbF9vcHRpb25zLnNpemUoKTsgaSsrKSB7CisgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKG91dHB1dCwgIiQwb3B0aW9uICQxO1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBhbGxfb3B0aW9uc1tpXSk7CisgICAgfQorICB9CisgIHJldHVybiAhYWxsX29wdGlvbnMuZW1wdHkoKTsKK30KKworY2xhc3MgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlciB7CisgcHVibGljOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBEZXNjVHlwZT4KKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcihjb25zdCBEZXNjVHlwZSogZGVzYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpCisgICAgICA6IG9wdGlvbnNfKG9wdGlvbnMpLCBwcmVmaXhfKHByZWZpeCkgeworICAgIC8vIFBlcmZvcm0gdGhlIFNvdXJjZUxvY2F0aW9uIGxvb2t1cCBvbmx5IGlmIHdlJ3JlIGluY2x1ZGluZyB1c2VyIGNvbW1lbnRzLAorICAgIC8vIGJlY2F1c2UgdGhlIGxvb2t1cCBpcyBmYWlybHkgZXhwZW5zaXZlLgorICAgIGhhdmVfc291cmNlX2xvY18gPSBvcHRpb25zLmluY2x1ZGVfY29tbWVudHMgJiYKKyAgICAgICAgZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJnNvdXJjZV9sb2NfKTsKKyAgfQorICBTb3VyY2VMb2NhdGlvbkNvbW1lbnRQcmludGVyKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3RvcjxpbnQ+JiBwYXRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykKKyAgICAgIDogb3B0aW9uc18ob3B0aW9ucyksIHByZWZpeF8ocHJlZml4KSB7CisgICAgLy8gUGVyZm9ybSB0aGUgU291cmNlTG9jYXRpb24gbG9va3VwIG9ubHkgaWYgd2UncmUgaW5jbHVkaW5nIHVzZXIgY29tbWVudHMsCisgICAgLy8gYmVjYXVzZSB0aGUgbG9va3VwIGlzIGZhaXJseSBleHBlbnNpdmUuCisgICAgaGF2ZV9zb3VyY2VfbG9jXyA9IG9wdGlvbnMuaW5jbHVkZV9jb21tZW50cyAmJgorICAgICAgICBmaWxlLT5HZXRTb3VyY2VMb2NhdGlvbihwYXRoLCAmc291cmNlX2xvY18pOworICB9CisgIHZvaWQgQWRkUHJlQ29tbWVudChzdHJpbmcqIG91dHB1dCkgeworICAgIGlmIChoYXZlX3NvdXJjZV9sb2NfKSB7CisgICAgICAvLyBEZXRhY2hlZCBsZWFkaW5nIGNvbW1lbnRzLgorICAgICAgZm9yIChpbnQgaSA9IDAgOyBpIDwgc291cmNlX2xvY18ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cy5zaXplKCk7ICsraSkgeworICAgICAgICAqb3V0cHV0ICs9IEZvcm1hdENvbW1lbnQoc291cmNlX2xvY18ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50c1tpXSk7CisgICAgICAgICpvdXRwdXQgKz0gIlxuIjsKKyAgICAgIH0KKyAgICAgIC8vIEF0dGFjaGVkIGxlYWRpbmcgY29tbWVudHMuCisgICAgICBpZiAoIXNvdXJjZV9sb2NfLmxlYWRpbmdfY29tbWVudHMuZW1wdHkoKSkgeworICAgICAgICAqb3V0cHV0ICs9IEZvcm1hdENvbW1lbnQoc291cmNlX2xvY18ubGVhZGluZ19jb21tZW50cyk7CisgICAgICB9CisgICAgfQorICB9CisgIHZvaWQgQWRkUG9zdENvbW1lbnQoc3RyaW5nKiBvdXRwdXQpIHsKKyAgICBpZiAoaGF2ZV9zb3VyY2VfbG9jXyAmJiBzb3VyY2VfbG9jXy50cmFpbGluZ19jb21tZW50cy5zaXplKCkgPiAwKSB7CisgICAgICAqb3V0cHV0ICs9IEZvcm1hdENvbW1lbnQoc291cmNlX2xvY18udHJhaWxpbmdfY29tbWVudHMpOworICAgIH0KKyAgfQorCisgIC8vIEZvcm1hdCBjb21tZW50IHN1Y2ggdGhhdCBlYWNoIGxpbmUgYmVjb21lcyBhIGZ1bGwtbGluZSBDKystc3R5bGUgY29tbWVudCBpbgorICAvLyB0aGUgRGVidWdTdHJpbmcoKSBvdXRwdXQuCisgIHN0cmluZyBGb3JtYXRDb21tZW50KGNvbnN0IHN0cmluZyYgY29tbWVudF90ZXh0KSB7CisgICAgc3RyaW5nIHN0cmlwcGVkX2NvbW1lbnQgPSBjb21tZW50X3RleHQ7CisgICAgU3RyaXBXaGl0ZXNwYWNlKCZzdHJpcHBlZF9jb21tZW50KTsKKyAgICB2ZWN0b3I8c3RyaW5nPiBsaW5lcyA9IFNwbGl0KHN0cmlwcGVkX2NvbW1lbnQsICJcbiIpOworICAgIHN0cmluZyBvdXRwdXQ7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaW5lcy5zaXplKCk7ICsraSkgeworICAgICAgY29uc3Qgc3RyaW5nJiBsaW5lID0gbGluZXNbaV07CisgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZvdXRwdXQsICIkMC8vICQxXG4iLCBwcmVmaXhfLCBsaW5lKTsKKyAgICB9CisgICAgcmV0dXJuIG91dHB1dDsKKyAgfQorCisgcHJpdmF0ZToKKyAgYm9vbCBoYXZlX3NvdXJjZV9sb2NfOworICBTb3VyY2VMb2NhdGlvbiBzb3VyY2VfbG9jXzsKKyAgRGVidWdTdHJpbmdPcHRpb25zIG9wdGlvbnNfOworICBzdHJpbmcgcHJlZml4XzsKK307CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworc3RyaW5nIEZpbGVEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgRGVidWdTdHJpbmdPcHRpb25zIG9wdGlvbnM7ICAvLyBkZWZhdWx0IG9wdGlvbnMKKyAgcmV0dXJuIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMob3B0aW9ucyk7Cit9CisKK3N0cmluZyBGaWxlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygKKyAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIGRlYnVnX3N0cmluZ19vcHRpb25zKSBjb25zdCB7CisgIHN0cmluZyBjb250ZW50czsKKyAgeworICAgIHZlY3RvcjxpbnQ+IHBhdGg7CisgICAgcGF0aC5wdXNoX2JhY2soRmlsZURlc2NyaXB0b3JQcm90bzo6a1N5bnRheEZpZWxkTnVtYmVyKTsKKyAgICBTb3VyY2VMb2NhdGlvbkNvbW1lbnRQcmludGVyIHN5bnRheF9jb21tZW50KAorICAgICAgICB0aGlzLCBwYXRoLCAiIiwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICAgIHN5bnRheF9jb21tZW50LkFkZFByZUNvbW1lbnQoJmNvbnRlbnRzKTsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZjb250ZW50cywgInN5bnRheCA9IFwiJDBcIjtcblxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bnRheE5hbWUoc3ludGF4KCkpKTsKKyAgICBzeW50YXhfY29tbWVudC5BZGRQb3N0Q29tbWVudCgmY29udGVudHMpOworICB9CisKKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcgorICAgICAgY29tbWVudF9wcmludGVyKHRoaXMsICIiLCBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIGNvbW1lbnRfcHJpbnRlci5BZGRQcmVDb21tZW50KCZjb250ZW50cyk7CisKKyAgc2V0PGludD4gcHVibGljX2RlcGVuZGVuY2llczsKKyAgc2V0PGludD4gd2Vha19kZXBlbmRlbmNpZXM7CisgIHB1YmxpY19kZXBlbmRlbmNpZXMuaW5zZXJ0KHB1YmxpY19kZXBlbmRlbmNpZXNfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNfZGVwZW5kZW5jaWVzXyArIHB1YmxpY19kZXBlbmRlbmN5X2NvdW50Xyk7CisgIHdlYWtfZGVwZW5kZW5jaWVzLmluc2VydCh3ZWFrX2RlcGVuZGVuY2llc18sCisgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWFrX2RlcGVuZGVuY2llc18gKyB3ZWFrX2RlcGVuZGVuY3lfY291bnRfKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKHB1YmxpY19kZXBlbmRlbmNpZXMuY291bnQoaSkgPiAwKSB7CisgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZjb250ZW50cywgImltcG9ydCBwdWJsaWMgXCIkMFwiO1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgICB9IGVsc2UgaWYgKHdlYWtfZGVwZW5kZW5jaWVzLmNvdW50KGkpID4gMCkgeworICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJpbXBvcnQgd2VhayBcIiQwXCI7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmN5KGkpLT5uYW1lKCkpOworICAgIH0gZWxzZSB7CisgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZjb250ZW50cywgImltcG9ydCBcIiQwXCI7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmN5KGkpLT5uYW1lKCkpOworICAgIH0KKyAgfQorCisgIGlmICghcGFja2FnZSgpLmVtcHR5KCkpIHsKKyAgICB2ZWN0b3I8aW50PiBwYXRoOworICAgIHBhdGgucHVzaF9iYWNrKEZpbGVEZXNjcmlwdG9yUHJvdG86OmtQYWNrYWdlRmllbGROdW1iZXIpOworICAgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIgcGFja2FnZV9jb21tZW50KAorICAgICAgICB0aGlzLCBwYXRoLCAiIiwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICAgIHBhY2thZ2VfY29tbWVudC5BZGRQcmVDb21tZW50KCZjb250ZW50cyk7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJwYWNrYWdlICQwO1xuXG4iLCBwYWNrYWdlKCkpOworICAgIHBhY2thZ2VfY29tbWVudC5BZGRQb3N0Q29tbWVudCgmY29udGVudHMpOworICB9CisKKyAgaWYgKEZvcm1hdExpbmVPcHRpb25zKDAsIG9wdGlvbnMoKSwgJmNvbnRlbnRzKSkgeworICAgIGNvbnRlbnRzLmFwcGVuZCgiXG4iKTsgIC8vIGFkZCBzb21lIHNwYWNlIGlmIHdlIGhhZCBvcHRpb25zCisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX3R5cGUoaSktPkRlYnVnU3RyaW5nKDAsICZjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICAgIGNvbnRlbnRzLmFwcGVuZCgiXG4iKTsKKyAgfQorCisgIC8vIEZpbmQgYWxsIHRoZSAnZ3JvdXAnIHR5cGUgZXh0ZW5zaW9uczsgd2Ugd2lsbCBub3Qgb3V0cHV0IHRoZWlyIG5lc3RlZAorICAvLyBkZWZpbml0aW9ucyAodGhvc2Ugd2lsbCBiZSBkb25lIHdpdGggdGhlaXIgZ3JvdXAgZmllbGQgZGVzY3JpcHRvcikuCisgIHNldDxjb25zdCBEZXNjcmlwdG9yKj4gZ3JvdXBzOworICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZXh0ZW5zaW9uKGkpLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgICBncm91cHMuaW5zZXJ0KGV4dGVuc2lvbihpKS0+bWVzc2FnZV90eXBlKCkpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChncm91cHMuY291bnQobWVzc2FnZV90eXBlKGkpKSA9PSAwKSB7CisgICAgICBtZXNzYWdlX3R5cGUoaSktPkRlYnVnU3RyaW5nKDAsICZjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluY2x1ZGVfb3BlbmluZ19jbGF1c2UgKi8gdHJ1ZSk7CisgICAgICBjb250ZW50cy5hcHBlbmQoIlxuIik7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgIHNlcnZpY2UoaSktPkRlYnVnU3RyaW5nKCZjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICAgIGNvbnRlbnRzLmFwcGVuZCgiXG4iKTsKKyAgfQorCisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSA9IE5VTEw7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGlmIChleHRlbnNpb24oaSktPmNvbnRhaW5pbmdfdHlwZSgpICE9IGNvbnRhaW5pbmdfdHlwZSkgeworICAgICAgaWYgKGkgPiAwKSBjb250ZW50cy5hcHBlbmQoIn1cblxuIik7CisgICAgICBjb250YWluaW5nX3R5cGUgPSBleHRlbnNpb24oaSktPmNvbnRhaW5pbmdfdHlwZSgpOworICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJleHRlbmQgLiQwIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZS0+ZnVsbF9uYW1lKCkpOworICAgIH0KKyAgICBleHRlbnNpb24oaSktPkRlYnVnU3RyaW5nKDEsIEZpZWxkRGVzY3JpcHRvcjo6UFJJTlRfTEFCRUwsICZjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgfQorICBpZiAoZXh0ZW5zaW9uX2NvdW50KCkgPiAwKSBjb250ZW50cy5hcHBlbmQoIn1cblxuIik7CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KCZjb250ZW50cyk7CisKKyAgcmV0dXJuIGNvbnRlbnRzOworfQorCitzdHJpbmcgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zOyAgLy8gZGVmYXVsdCBvcHRpb25zCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygKKyAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIGNvbnRlbnRzOworICBEZWJ1Z1N0cmluZygwLCAmY29udGVudHMsIG9wdGlvbnMsIC8qIGluY2x1ZGVfb3BlbmluZ19jbGF1c2UgKi8gdHJ1ZSk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW5jbHVkZV9vcGVuaW5nX2NsYXVzZSkgY29uc3QgeworICBpZiAob3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgLy8gRG8gbm90IGdlbmVyYXRlIGRlYnVnIHN0cmluZyBmb3IgYXV0by1nZW5lcmF0ZWQgbWFwLWVudHJ5IHR5cGUuCisgICAgcmV0dXJuOworICB9CisgIHN0cmluZyBwcmVmaXgoZGVwdGggKiAyLCAnICcpOworICArK2RlcHRoOworCisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCBwcmVmaXgsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworCisgIGlmIChpbmNsdWRlX29wZW5pbmdfY2xhdXNlKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwbWVzc2FnZSAkMSIsIHByZWZpeCwgbmFtZSgpKTsKKyAgfQorICBjb250ZW50cy0+YXBwZW5kKCIge1xuIik7CisKKyAgRm9ybWF0TGluZU9wdGlvbnMoZGVwdGgsIG9wdGlvbnMoKSwgY29udGVudHMpOworCisgIC8vIEZpbmQgYWxsIHRoZSAnZ3JvdXAnIHR5cGVzIGZvciBmaWVsZHMgYW5kIGV4dGVuc2lvbnM7IHdlIHdpbGwgbm90IG91dHB1dAorICAvLyB0aGVpciBuZXN0ZWQgZGVmaW5pdGlvbnMgKHRob3NlIHdpbGwgYmUgZG9uZSB3aXRoIHRoZWlyIGdyb3VwIGZpZWxkCisgIC8vIGRlc2NyaXB0b3IpLgorICBzZXQ8Y29uc3QgRGVzY3JpcHRvcio+IGdyb3VwczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZmllbGQoaSktPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgIGdyb3Vwcy5pbnNlcnQoZmllbGQoaSktPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICB9CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGV4dGVuc2lvbihpKS0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgICAgZ3JvdXBzLmluc2VydChleHRlbnNpb24oaSktPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IG5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChncm91cHMuY291bnQobmVzdGVkX3R5cGUoaSkpID09IDApIHsKKyAgICAgIG5lc3RlZF90eXBlKGkpLT5EZWJ1Z1N0cmluZyhkZXB0aCwgY29udGVudHMsIGRlYnVnX3N0cmluZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluY2x1ZGVfb3BlbmluZ19jbGF1c2UgKi8gdHJ1ZSk7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fdHlwZShpKS0+RGVidWdTdHJpbmcoZGVwdGgsIGNvbnRlbnRzLCBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMKSB7CisgICAgICBmaWVsZChpKS0+RGVidWdTdHJpbmcoZGVwdGgsIEZpZWxkRGVzY3JpcHRvcjo6UFJJTlRfTEFCRUwsIGNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgICB9IGVsc2UgaWYgKGZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCktPmZpZWxkKDApID09IGZpZWxkKGkpKSB7CisgICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCBmaWVsZCBpbiB0aGlzIG9uZW9mLCBzbyBwcmludCB0aGUgd2hvbGUgb25lb2YuCisgICAgICBmaWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpLT5EZWJ1Z1N0cmluZyhkZXB0aCwgY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25fcmFuZ2VfY291bnQoKTsgaSsrKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwICBleHRlbnNpb25zICQxIHRvICQyO1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbl9yYW5nZShpKS0+c3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25fcmFuZ2UoaSktPmVuZCAtIDEpOworICB9CisKKyAgLy8gR3JvdXAgZXh0ZW5zaW9ucyBieSB3aGF0IHRoZXkgZXh0ZW5kLCBzbyB0aGV5IGNhbiBiZSBwcmludGVkIG91dCB0b2dldGhlci4KKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlID0gTlVMTDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGV4dGVuc2lvbihpKS0+Y29udGFpbmluZ190eXBlKCkgIT0gY29udGFpbmluZ190eXBlKSB7CisgICAgICBpZiAoaSA+IDApIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMCAgfVxuIiwgcHJlZml4KTsKKyAgICAgIGNvbnRhaW5pbmdfdHlwZSA9IGV4dGVuc2lvbihpKS0+Y29udGFpbmluZ190eXBlKCk7CisgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKGNvbnRlbnRzLCAiJDAgIGV4dGVuZCAuJDEge1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBjb250YWluaW5nX3R5cGUtPmZ1bGxfbmFtZSgpKTsKKyAgICB9CisgICAgZXh0ZW5zaW9uKGkpLT5EZWJ1Z1N0cmluZygKKyAgICAgICAgZGVwdGggKyAxLCBGaWVsZERlc2NyaXB0b3I6OlBSSU5UX0xBQkVMLCBjb250ZW50cywKKyAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICB9CisgIGlmIChleHRlbnNpb25fY291bnQoKSA+IDApCisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwICB9XG4iLCBwcmVmaXgpOworCisgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMH1cbiIsIHByZWZpeCk7CisgIGNvbW1lbnRfcHJpbnRlci5BZGRQb3N0Q29tbWVudChjb250ZW50cyk7Cit9CisKK3N0cmluZyBGaWVsZERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBEZWJ1Z1N0cmluZ09wdGlvbnMgb3B0aW9uczsgIC8vIGRlZmF1bHQgb3B0aW9ucworICByZXR1cm4gRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhvcHRpb25zKTsKK30KKworc3RyaW5nIEZpZWxkRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygKKyAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIGRlYnVnX3N0cmluZ19vcHRpb25zKSBjb25zdCB7CisgIHN0cmluZyBjb250ZW50czsKKyAgaW50IGRlcHRoID0gMDsKKyAgaWYgKGlzX2V4dGVuc2lvbigpKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJleHRlbmQgLiQwIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICAgIGRlcHRoID0gMTsKKyAgfQorICBEZWJ1Z1N0cmluZyhkZXB0aCwgUFJJTlRfTEFCRUwsICZjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBpZiAoaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBjb250ZW50cy5hcHBlbmQoIn1cbiIpOworICB9CisgIHJldHVybiBjb250ZW50czsKK30KKworLy8gVGhlIGZpZWxkIHR5cGUgc3RyaW5nIHVzZWQgaW4gRmllbGREZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpCitzdHJpbmcgRmllbGREZXNjcmlwdG9yOjpGaWVsZFR5cGVOYW1lRGVidWdTdHJpbmcoKSBjb25zdCB7CisgIHN3aXRjaCh0eXBlKCkpIHsKKyAgICBjYXNlIFRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiAiLiIgKyBtZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCk7CisgICAgY2FzZSBUWVBFX0VOVU06CisgICAgICByZXR1cm4gIi4iICsgZW51bV90eXBlKCktPmZ1bGxfbmFtZSgpOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4ga1R5cGVUb05hbWVbdHlwZSgpXTsKKyAgfQorfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoaW50IGRlcHRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW50TGFiZWxGbGFnIHByaW50X2xhYmVsX2ZsYWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nICpjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisgIHN0cmluZyBmaWVsZF90eXBlOworCisgIC8vIFNwZWNpYWwgY2FzZSBtYXAgZmllbGRzLgorICBpZiAoaXNfbWFwKCkpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKAorICAgICAgICAmZmllbGRfdHlwZSwgIm1hcDwkMCwgJDE+IiwKKyAgICAgICAgbWVzc2FnZV90eXBlKCktPmZpZWxkKDApLT5GaWVsZFR5cGVOYW1lRGVidWdTdHJpbmcoKSwKKyAgICAgICAgbWVzc2FnZV90eXBlKCktPmZpZWxkKDEpLT5GaWVsZFR5cGVOYW1lRGVidWdTdHJpbmcoKSk7CisgIH0gZWxzZSB7CisgICAgZmllbGRfdHlwZSA9IEZpZWxkVHlwZU5hbWVEZWJ1Z1N0cmluZygpOworICB9CisKKyAgc3RyaW5nIGxhYmVsOworICBpZiAocHJpbnRfbGFiZWxfZmxhZyA9PSBQUklOVF9MQUJFTCAmJiAhaXNfbWFwKCkpIHsKKyAgICBsYWJlbCA9IGtMYWJlbFRvTmFtZVt0aGlzLT5sYWJlbCgpXTsKKyAgICBsYWJlbC5wdXNoX2JhY2soJyAnKTsKKyAgfQorCisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCBwcmVmaXgsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworCisgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMCQxJDIgJDMgPSAkNCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSgpID09IFRZUEVfR1JPVVAgPyBtZXNzYWdlX3R5cGUoKS0+bmFtZSgpIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIoKSk7CisKKyAgYm9vbCBicmFja2V0ZWQgPSBmYWxzZTsKKyAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICBicmFja2V0ZWQgPSB0cnVlOworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIgW2RlZmF1bHQgPSAkMCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0VmFsdWVBc1N0cmluZyh0cnVlKSk7CisgIH0KKworICBzdHJpbmcgZm9ybWF0dGVkX29wdGlvbnM7CisgIGlmIChGb3JtYXRCcmFja2V0ZWRPcHRpb25zKGRlcHRoLCBvcHRpb25zKCksICZmb3JtYXR0ZWRfb3B0aW9ucykpIHsKKyAgICBjb250ZW50cy0+YXBwZW5kKGJyYWNrZXRlZCA/ICIsICIgOiAiIFsiKTsKKyAgICBicmFja2V0ZWQgPSB0cnVlOworICAgIGNvbnRlbnRzLT5hcHBlbmQoZm9ybWF0dGVkX29wdGlvbnMpOworICB9CisKKyAgaWYgKGJyYWNrZXRlZCkgeworICAgIGNvbnRlbnRzLT5hcHBlbmQoIl0iKTsKKyAgfQorCisgIGlmICh0eXBlKCkgPT0gVFlQRV9HUk9VUCkgeworICAgIG1lc3NhZ2VfdHlwZSgpLT5EZWJ1Z1N0cmluZyhkZXB0aCwgY29udGVudHMsIGRlYnVnX3N0cmluZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmNsdWRlX29wZW5pbmdfY2xhdXNlICovIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBjb250ZW50cy0+YXBwZW5kKCI7XG4iKTsKKyAgfQorCisgIGNvbW1lbnRfcHJpbnRlci5BZGRQb3N0Q29tbWVudChjb250ZW50cyk7Cit9CisKK3N0cmluZyBPbmVvZkRlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBEZWJ1Z1N0cmluZ09wdGlvbnMgb3B0aW9uczsgIC8vIGRlZmF1bHQgdmFsdWVzCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgT25lb2ZEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKDAsICZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKGludCBkZXB0aCwgc3RyaW5nKiBjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisgICsrZGVwdGg7CisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCBwcmVmaXgsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKAorICAgICAgY29udGVudHMsICIkMCBvbmVvZiAkMSB7XG4iLCBwcmVmaXgsIG5hbWUoKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGQoaSktPkRlYnVnU3RyaW5nKGRlcHRoLCBGaWVsZERlc2NyaXB0b3I6Ok9NSVRfTEFCRUwsIGNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIH0KKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwfVxuIiwgcHJlZml4KTsKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIEVudW1EZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgRGVidWdTdHJpbmdPcHRpb25zIG9wdGlvbnM7ICAvLyBkZWZhdWx0IHZhbHVlcworICByZXR1cm4gRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhvcHRpb25zKTsKK30KKworc3RyaW5nIEVudW1EZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKDAsICZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisgICsrZGVwdGg7CisKKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcgorICAgICAgY29tbWVudF9wcmludGVyKHRoaXMsIHByZWZpeCwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBjb21tZW50X3ByaW50ZXIuQWRkUHJlQ29tbWVudChjb250ZW50cyk7CisKKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwZW51bSAkMSB7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwgbmFtZSgpKTsKKworICBGb3JtYXRMaW5lT3B0aW9ucyhkZXB0aCwgb3B0aW9ucygpLCBjb250ZW50cyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICB2YWx1ZShpKS0+RGVidWdTdHJpbmcoZGVwdGgsIGNvbnRlbnRzLCBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIH0KKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwfVxuIiwgcHJlZml4KTsKKworICBjb21tZW50X3ByaW50ZXIuQWRkUG9zdENvbW1lbnQoY29udGVudHMpOworfQorCitzdHJpbmcgRW51bVZhbHVlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zOyAgLy8gZGVmYXVsdCB2YWx1ZXMKKyAgcmV0dXJuIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMob3B0aW9ucyk7Cit9CisKK3N0cmluZyBFbnVtVmFsdWVEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKDAsICZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisKKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcgorICAgICAgY29tbWVudF9wcmludGVyKHRoaXMsIHByZWZpeCwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBjb21tZW50X3ByaW50ZXIuQWRkUHJlQ29tbWVudChjb250ZW50cyk7CisKKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwJDEgPSAkMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBuYW1lKCksIG51bWJlcigpKTsKKworICBzdHJpbmcgZm9ybWF0dGVkX29wdGlvbnM7CisgIGlmIChGb3JtYXRCcmFja2V0ZWRPcHRpb25zKGRlcHRoLCBvcHRpb25zKCksICZmb3JtYXR0ZWRfb3B0aW9ucykpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKGNvbnRlbnRzLCAiIFskMF0iLCBmb3JtYXR0ZWRfb3B0aW9ucyk7CisgIH0KKyAgY29udGVudHMtPmFwcGVuZCgiO1xuIik7CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIFNlcnZpY2VEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgRGVidWdTdHJpbmdPcHRpb25zIG9wdGlvbnM7ICAvLyBkZWZhdWx0IHZhbHVlcworICByZXR1cm4gRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhvcHRpb25zKTsKK30KKworc3RyaW5nIFNlcnZpY2VEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKCZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoc3RyaW5nICpjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKSBjb25zdCB7CisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCAvKiBwcmVmaXggKi8gIiIsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworCisgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICJzZXJ2aWNlICQwIHtcbiIsIG5hbWUoKSk7CisKKyAgRm9ybWF0TGluZU9wdGlvbnMoMSwgb3B0aW9ucygpLCBjb250ZW50cyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgbWV0aG9kKGkpLT5EZWJ1Z1N0cmluZygxLCBjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICB9CisKKyAgY29udGVudHMtPmFwcGVuZCgifVxuIik7CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIE1ldGhvZERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBEZWJ1Z1N0cmluZ09wdGlvbnMgb3B0aW9uczsgIC8vIGRlZmF1bHQgdmFsdWVzCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgTWV0aG9kRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygKKyAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIGNvbnRlbnRzOworICBEZWJ1Z1N0cmluZygwLCAmY29udGVudHMsIG9wdGlvbnMpOworICByZXR1cm4gY29udGVudHM7Cit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKSBjb25zdCB7CisgIHN0cmluZyBwcmVmaXgoZGVwdGggKiAyLCAnICcpOworICArK2RlcHRoOworCisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCBwcmVmaXgsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworCisgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMHJwYyAkMSgkNC4kMikgcmV0dXJucyAoJDUuJDMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgsIG5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF90eXBlKCktPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dF90eXBlKCktPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudF9zdHJlYW1pbmcoKSA/ICJzdHJlYW0gIiA6ICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcl9zdHJlYW1pbmcoKSA/ICJzdHJlYW0gIiA6ICIiKTsKKworICBzdHJpbmcgZm9ybWF0dGVkX29wdGlvbnM7CisgIGlmIChGb3JtYXRMaW5lT3B0aW9ucyhkZXB0aCwgb3B0aW9ucygpLCAmZm9ybWF0dGVkX29wdGlvbnMpKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiB7XG4kMCQxfVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZF9vcHRpb25zLCBwcmVmaXgpOworICB9IGVsc2UgeworICAgIGNvbnRlbnRzLT5hcHBlbmQoIjtcbiIpOworICB9CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworCisvLyBMb2NhdGlvbiBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2Jvb2wgRmlsZURlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKGNvbnN0IHZlY3RvcjxpbnQ+JiBwYXRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChvdXRfbG9jYXRpb24pOworICBpZiAoc291cmNlX2NvZGVfaW5mb18pIHsKKyAgICBpZiAoY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIGxvYyA9CisgICAgICAgIHRhYmxlc18tPkdldFNvdXJjZUxvY2F0aW9uKHBhdGgsIHNvdXJjZV9jb2RlX2luZm9fKSkgeworICAgICAgY29uc3QgUmVwZWF0ZWRGaWVsZDxpbnQzMj4mIHNwYW4gPSBsb2MtPnNwYW4oKTsKKyAgICAgIGlmIChzcGFuLnNpemUoKSA9PSAzIHx8IHNwYW4uc2l6ZSgpID09IDQpIHsKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5zdGFydF9saW5lICAgPSBzcGFuLkdldCgwKTsKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5zdGFydF9jb2x1bW4gPSBzcGFuLkdldCgxKTsKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5lbmRfbGluZSAgICAgPSBzcGFuLkdldChzcGFuLnNpemUoKSA9PSAzID8gMCA6IDIpOworICAgICAgICBvdXRfbG9jYXRpb24tPmVuZF9jb2x1bW4gICA9IHNwYW4uR2V0KHNwYW4uc2l6ZSgpIC0gMSk7CisKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5sZWFkaW5nX2NvbW1lbnRzID0gbG9jLT5sZWFkaW5nX2NvbW1lbnRzKCk7CisgICAgICAgIG91dF9sb2NhdGlvbi0+dHJhaWxpbmdfY29tbWVudHMgPSBsb2MtPnRyYWlsaW5nX2NvbW1lbnRzKCk7CisgICAgICAgIG91dF9sb2NhdGlvbi0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cy5hc3NpZ24oCisgICAgICAgICAgICBsb2MtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKS5iZWdpbigpLAorICAgICAgICAgICAgbG9jLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkuZW5kKCkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIEZpbGVEZXNjcmlwdG9yOjpHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdCB7CisgIHZlY3RvcjxpbnQ+IHBhdGg7ICAvLyBlbXB0eSBwYXRoIGZvciByb290IEZpbGVEZXNjcmlwdG9yCisgIHJldHVybiBHZXRTb3VyY2VMb2NhdGlvbihwYXRoLCBvdXRfbG9jYXRpb24pOworfQorCitib29sIEZpZWxkRGVzY3JpcHRvcjo6aXNfcGFja2VkKCkgY29uc3QgeworICByZXR1cm4gaXNfcGFja2FibGUoKSAmJiAob3B0aW9uc18gIT0gTlVMTCkgJiYgb3B0aW9uc18tPnBhY2tlZCgpOworfQorCitib29sIERlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBGaWVsZERlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBPbmVvZkRlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGNvbnRhaW5pbmdfdHlwZSgpLT5maWxlKCktPkdldFNvdXJjZUxvY2F0aW9uKHBhdGgsIG91dF9sb2NhdGlvbik7Cit9CisKK2Jvb2wgRW51bURlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBNZXRob2REZXNjcmlwdG9yOjpHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdCB7CisgIHZlY3RvcjxpbnQ+IHBhdGg7CisgIEdldExvY2F0aW9uUGF0aCgmcGF0aCk7CisgIHJldHVybiBzZXJ2aWNlKCktPmZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvcjo6R2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3QgeworICB2ZWN0b3I8aW50PiBwYXRoOworICBHZXRMb2NhdGlvblBhdGgoJnBhdGgpOworICByZXR1cm4gZmlsZSgpLT5HZXRTb3VyY2VMb2NhdGlvbihwYXRoLCBvdXRfbG9jYXRpb24pOworfQorCitib29sIEVudW1WYWx1ZURlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKAorICAgIFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIHR5cGUoKS0+ZmlsZSgpLT5HZXRTb3VyY2VMb2NhdGlvbihwYXRoLCBvdXRfbG9jYXRpb24pOworfQorCit2b2lkIERlc2NyaXB0b3I6OkdldExvY2F0aW9uUGF0aCh2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdCB7CisgIGlmIChjb250YWluaW5nX3R5cGUoKSkgeworICAgIGNvbnRhaW5pbmdfdHlwZSgpLT5HZXRMb2NhdGlvblBhdGgob3V0cHV0KTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIpOworICAgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworICB9IGVsc2UgeworICAgIG91dHB1dC0+cHVzaF9iYWNrKEZpbGVEZXNjcmlwdG9yUHJvdG86OmtNZXNzYWdlVHlwZUZpZWxkTnVtYmVyKTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKKyAgfQorfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgaWYgKGlzX2V4dGVuc2lvbigpKSB7CisgICAgaWYgKGV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpIHsKKyAgICAgIG91dHB1dC0+cHVzaF9iYWNrKEZpbGVEZXNjcmlwdG9yUHJvdG86OmtFeHRlbnNpb25GaWVsZE51bWJlcik7CisgICAgICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKKyAgICB9IGVsc2UgeworICAgICAgZXh0ZW5zaW9uX3Njb3BlKCktPkdldExvY2F0aW9uUGF0aChvdXRwdXQpOworICAgICAgb3V0cHV0LT5wdXNoX2JhY2soRGVzY3JpcHRvclByb3RvOjprRXh0ZW5zaW9uRmllbGROdW1iZXIpOworICAgICAgb3V0cHV0LT5wdXNoX2JhY2soaW5kZXgoKSk7CisgICAgfQorICB9IGVsc2UgeworICAgIGNvbnRhaW5pbmdfdHlwZSgpLT5HZXRMb2NhdGlvblBhdGgob3V0cHV0KTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhEZXNjcmlwdG9yUHJvdG86OmtGaWVsZEZpZWxkTnVtYmVyKTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKKyAgfQorfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgY29udGFpbmluZ190eXBlKCktPkdldExvY2F0aW9uUGF0aChvdXRwdXQpOworICBvdXRwdXQtPnB1c2hfYmFjayhEZXNjcmlwdG9yUHJvdG86OmtPbmVvZkRlY2xGaWVsZE51bWJlcik7CisgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yOjpHZXRMb2NhdGlvblBhdGgodmVjdG9yPGludD4qIG91dHB1dCkgY29uc3QgeworICBpZiAoY29udGFpbmluZ190eXBlKCkpIHsKKyAgICBjb250YWluaW5nX3R5cGUoKS0+R2V0TG9jYXRpb25QYXRoKG91dHB1dCk7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soRGVzY3JpcHRvclByb3RvOjprRW51bVR5cGVGaWVsZE51bWJlcik7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soaW5kZXgoKSk7CisgIH0gZWxzZSB7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soRmlsZURlc2NyaXB0b3JQcm90bzo6a0VudW1UeXBlRmllbGROdW1iZXIpOworICAgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworICB9Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgdHlwZSgpLT5HZXRMb2NhdGlvblBhdGgob3V0cHV0KTsKKyAgb3V0cHV0LT5wdXNoX2JhY2soRW51bURlc2NyaXB0b3JQcm90bzo6a1ZhbHVlRmllbGROdW1iZXIpOworICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgb3V0cHV0LT5wdXNoX2JhY2soRmlsZURlc2NyaXB0b3JQcm90bzo6a1NlcnZpY2VGaWVsZE51bWJlcik7CisgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3I6OkdldExvY2F0aW9uUGF0aCh2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdCB7CisgIHNlcnZpY2UoKS0+R2V0TG9jYXRpb25QYXRoKG91dHB1dCk7CisgIG91dHB1dC0+cHVzaF9iYWNrKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmtNZXRob2RGaWVsZE51bWJlcik7CisgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK25hbWVzcGFjZSB7CisKKy8vIFJlcHJlc2VudHMgYW4gb3B0aW9ucyBtZXNzYWdlIHRvIGludGVycHJldC4gRXh0ZW5zaW9uIG5hbWVzIGluIHRoZSBvcHRpb24KKy8vIG5hbWUgYXJlIHJlc3BvbHZlZCByZWxhdGl2ZSB0byBuYW1lX3Njb3BlLiBlbGVtZW50X25hbWUgYW5kIG9yaWdfb3B0IGFyZQorLy8gdXNlZCBvbmx5IGZvciBlcnJvciByZXBvcnRpbmcgKHNpbmNlIHRoZSBwYXJzZXIgcmVjb3JkcyBsb2NhdGlvbnMgYWdhaW5zdAorLy8gcG9pbnRlcnMgaW4gdGhlIG9yaWdpbmFsIG9wdGlvbnMsIG5vdCB0aGUgbXV0YWJsZSBjb3B5KS4gVGhlIE1lc3NhZ2UgbXVzdCBiZQorLy8gb25lIG9mIHRoZSBPcHRpb25zIG1lc3NhZ2VzIGluIGRlc2NyaXB0b3IucHJvdG8uCitzdHJ1Y3QgT3B0aW9uc1RvSW50ZXJwcmV0IHsKKyAgT3B0aW9uc1RvSW50ZXJwcmV0KGNvbnN0IHN0cmluZyYgbnMsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVsLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogb3JpZ19vcHQsCisgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBvcHQpCisgICAgICA6IG5hbWVfc2NvcGUobnMpLAorICAgICAgICBlbGVtZW50X25hbWUoZWwpLAorICAgICAgICBvcmlnaW5hbF9vcHRpb25zKG9yaWdfb3B0KSwKKyAgICAgICAgb3B0aW9ucyhvcHQpIHsKKyAgfQorICBzdHJpbmcgbmFtZV9zY29wZTsKKyAgc3RyaW5nIGVsZW1lbnRfbmFtZTsKKyAgY29uc3QgTWVzc2FnZSogb3JpZ2luYWxfb3B0aW9uczsKKyAgTWVzc2FnZSogb3B0aW9uczsKK307CisKK30gIC8vIG5hbWVzcGFjZQorCitjbGFzcyBEZXNjcmlwdG9yQnVpbGRlciB7CisgcHVibGljOgorICBEZXNjcmlwdG9yQnVpbGRlcihjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OlRhYmxlcyogdGFibGVzLAorICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3Rvcik7CisgIH5EZXNjcmlwdG9yQnVpbGRlcigpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBCdWlsZEZpbGUoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworCisgcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIE9wdGlvbkludGVycHJldGVyOworCisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sXzsKKyAgRGVzY3JpcHRvclBvb2w6OlRhYmxlcyogdGFibGVzXzsgIC8vIGZvciBjb252ZW5pZW5jZQorICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3Rvcl87CisKKyAgLy8gQXMgd2UgYnVpbGQgZGVzY3JpcHRvcnMgd2Ugc3RvcmUgY29waWVzIG9mIHRoZSBvcHRpb25zIG1lc3NhZ2VzIGluCisgIC8vIHRoZW0uIFdlIHB1dCBwb2ludGVycyB0byB0aG9zZSBjb3BpZXMgaW4gdGhpcyB2ZWN0b3IsIGFzIHdlIGJ1aWxkLCBzbyB3ZQorICAvLyBjYW4gbGF0ZXIgKGFmdGVyIGNyb3NzLWxpbmtpbmcpIGludGVycHJldCB0aG9zZSBvcHRpb25zLgorICB2ZWN0b3I8T3B0aW9uc1RvSW50ZXJwcmV0PiBvcHRpb25zX3RvX2ludGVycHJldF87CisKKyAgYm9vbCBoYWRfZXJyb3JzXzsKKyAgc3RyaW5nIGZpbGVuYW1lXzsKKyAgRmlsZURlc2NyaXB0b3IqIGZpbGVfOworICBGaWxlRGVzY3JpcHRvclRhYmxlcyogZmlsZV90YWJsZXNfOworICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBkZXBlbmRlbmNpZXNfOworCisgIC8vIHVudXNlZF9kZXBlbmRlbmN5XyBpcyB1c2VkIHRvIHJlY29yZCB0aGUgdW51c2VkIGltcG9ydGVkIGZpbGVzLgorICAvLyBOb3RlOiBwdWJsaWMgaW1wb3J0IGlzIG5vdCBjb25zaWRlcmVkLgorICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiB1bnVzZWRfZGVwZW5kZW5jeV87CisKKyAgLy8gSWYgTG9va3VwU3ltYm9sKCkgZmluZHMgYSBzeW1ib2wgdGhhdCBpcyBpbiBhIGZpbGUgd2hpY2ggaXMgbm90IGEgZGVjbGFyZWQKKyAgLy8gZGVwZW5kZW5jeSBvZiB0aGlzIGZpbGUsIGl0IHdpbGwgZmFpbCwgYnV0IHdpbGwgc2V0CisgIC8vIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV8gdG8gcG9pbnQgYXQgdGhhdCBmaWxlLiAgVGhpcyBpcyBvbmx5IHVzZWQKKyAgLy8gYnkgQWRkTm90RGVmaW5lZEVycm9yKCkgdG8gcmVwb3J0IGEgbW9yZSB1c2VmdWwgZXJyb3IgbWVzc2FnZS4KKyAgLy8gcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5X25hbWVfIGlzIHRoZSBuYW1lIG9mIHRoZSBzeW1ib2wgdGhhdCB3YXMKKyAgLy8gYWN0dWFsbHkgZm91bmQgaW4gcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5Xywgd2hpY2ggbWF5IGJlIGEgcGFyZW50CisgIC8vIG9mIHRoZSBzeW1ib2wgYWN0dWFsbHkgbG9va2VkIGZvci4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV87CisgIHN0cmluZyBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfbmFtZV87CisKKyAgLy8gSWYgTG9va3VwU3ltYm9sKCkgY291bGQgcmVzb2x2ZSBhIHN5bWJvbCB3aGljaCBpcyBub3QgZGVmaW5lZCwKKyAgLy8gcmVjb3JkIHRoZSByZXNvbHZlZCBuYW1lLiAgVGhpcyBpcyBvbmx5IHVzZWQgYnkgQWRkTm90RGVmaW5lZEVycm9yKCkKKyAgLy8gdG8gcmVwb3J0IGEgbW9yZSB1c2VmdWwgZXJyb3IgbWVzc2FnZS4KKyAgc3RyaW5nIHVuZGVmaW5lX3Jlc29sdmVkX25hbWVfOworCisgIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBlcnJvcik7CisgIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXJyb3IpOworICB2b2lkIEFkZFJlY3Vyc2l2ZUltcG9ydEVycm9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLCBpbnQgZnJvbV9oZXJlKTsKKyAgdm9pZCBBZGRUd2ljZUxpc3RlZEVycm9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLCBpbnQgaW5kZXgpOworICB2b2lkIEFkZEltcG9ydEVycm9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLCBpbnQgaW5kZXgpOworCisgIC8vIEFkZHMgYW4gZXJyb3IgaW5kaWNhdGluZyB0aGF0IHVuZGVmaW5lZF9zeW1ib2wgd2FzIG5vdCBkZWZpbmVkLiAgTXVzdAorICAvLyBvbmx5IGJlIGNhbGxlZCBhZnRlciBMb29rdXBTeW1ib2woKSBmYWlscy4KKyAgdm9pZCBBZGROb3REZWZpbmVkRXJyb3IoCisgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgY29uc3Qgc3RyaW5nJiB1bmRlZmluZWRfc3ltYm9sKTsKKworICB2b2lkIEFkZFdhcm5pbmcoY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVycm9yKTsKKworICAvLyBTaWxseSBoZWxwZXIgd2hpY2ggZGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gZmlsZSBpcyBpbiB0aGUgZ2l2ZW4gcGFja2FnZS4KKyAgLy8gSS5lLiwgZWl0aGVyIGZpbGUtPnBhY2thZ2UoKSA9PSBwYWNrYWdlX25hbWUgb3IgZmlsZS0+cGFja2FnZSgpIGlzIGEKKyAgLy8gbmVzdGVkIHBhY2thZ2Ugd2l0aGluIHBhY2thZ2VfbmFtZS4KKyAgYm9vbCBJc0luUGFja2FnZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgY29uc3Qgc3RyaW5nJiBwYWNrYWdlX25hbWUpOworCisgIC8vIEhlbHBlciBmdW5jdGlvbiB3aGljaCBmaW5kcyBhbGwgcHVibGljIGRlcGVuZGVuY2llcyBvZiB0aGUgZ2l2ZW4gZmlsZSwgYW5kCisgIC8vIHN0b3JlcyB0aGUgdGhlbSBpbiB0aGUgZGVwZW5kZW5jaWVzXyBzZXQgaW4gdGhlIGJ1aWxkZXIuCisgIHZvaWQgUmVjb3JkUHVibGljRGVwZW5kZW5jaWVzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworICAvLyBMaWtlIHRhYmxlc18tPkZpbmRTeW1ib2woKSwgYnV0IGFkZGl0aW9uYWxseToKKyAgLy8gLSBTZWFyY2ggdGhlIHBvb2wncyB1bmRlcmxheSBpZiBub3QgZm91bmQgaW4gdGFibGVzXy4KKyAgLy8gLSBJbnN1cmUgdGhhdCB0aGUgcmVzdWx0aW5nIFN5bWJvbCBpcyBmcm9tIG9uZSBvZiB0aGUgZmlsZSdzIGRlY2xhcmVkCisgIC8vICAgZGVwZW5kZW5jaWVzLgorICBTeW1ib2wgRmluZFN5bWJvbChjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIExpa2UgRmluZFN5bWJvbCgpIGJ1dCBkb2VzIG5vdCByZXF1aXJlIHRoYXQgdGhlIHN5bWJvbCBpcyBpbiBvbmUgb2YgdGhlCisgIC8vIGZpbGUncyBkZWNsYXJlZCBkZXBlbmRlbmNpZXMuCisgIFN5bWJvbCBGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwcyhjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIFRoaXMgaW1wbGVtZW50cyB0aGUgYm9keSBvZiBGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwcygpLgorICBTeW1ib2wgRmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHNIZWxwZXIoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIExpa2UgRmluZFN5bWJvbCgpLCBidXQgbG9va3MgdXAgdGhlIG5hbWUgcmVsYXRpdmUgdG8gc29tZSBvdGhlciBzeW1ib2wKKyAgLy8gbmFtZS4gIFRoaXMgZmlyc3Qgc2VhcmNoZXMgc2libGluZ3Mgb2YgcmVsYXRpdmVfdG8sIHRoZW4gc2libGluZ3Mgb2YgaXRzCisgIC8vIHBhcmVudHMsIGV0Yy4gIEZvciBleGFtcGxlLCBMb29rdXBTeW1ib2woImZvby5iYXIiLCAiYmF6LnF1eC5jb3JnZSIpIG1ha2VzCisgIC8vIHRoZSBmb2xsb3dpbmcgY2FsbHMsIHJldHVybmluZyB0aGUgZmlyc3Qgbm9uLW51bGwgcmVzdWx0OgorICAvLyBGaW5kU3ltYm9sKCJiYXoucXV4LmZvby5iYXIiKSwgRmluZFN5bWJvbCgiYmF6LmZvby5iYXIiKSwKKyAgLy8gRmluZFN5bWJvbCgiZm9vLmJhciIpLiAgSWYgQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzKCkgaGFzIGJlZW4gY2FsbGVkCisgIC8vIG9uIHRoZSBEZXNjcmlwdG9yUG9vbCwgdGhpcyB3aWxsIGdlbmVyYXRlIGEgcGxhY2Vob2xkZXIgdHlwZSBpZgorICAvLyB0aGUgbmFtZSBpcyBub3QgZm91bmQgKHVubGVzcyB0aGUgbmFtZSBpdHNlbGYgaXMgbWFsZm9ybWVkKS4gIFRoZQorICAvLyBwbGFjZWhvbGRlcl90eXBlIHBhcmFtZXRlciBpbmRpY2F0ZXMgd2hhdCBraW5kIG9mIHBsYWNlaG9sZGVyIHNob3VsZCBiZQorICAvLyBjb25zdHJ1Y3RlZCBpbiB0aGlzIGNhc2UuICBUaGUgcmVzb2x2ZV9tb2RlIHBhcmFtZXRlciBkZXRlcm1pbmVzIHdoZXRoZXIKKyAgLy8gYW55IHN5bWJvbCBpcyByZXR1cm5lZCwgb3Igb25seSBzeW1ib2xzIHRoYXQgYXJlIHR5cGVzLiAgTm90ZSwgaG93ZXZlciwKKyAgLy8gdGhhdCBMb29rdXBTeW1ib2wgbWF5IHN0aWxsIHJldHVybiBhIG5vbi10eXBlIHN5bWJvbCBpbiBMT09LVVBfVFlQRVMgbW9kZSwKKyAgLy8gaWYgaXQgYmVsaWV2ZXMgdGhhdCdzIGFsbCBpdCBjb3VsZCByZWZlciB0by4gIFRoZSBjYWxsZXIgc2hvdWxkIGFsd2F5cworICAvLyBjaGVjayB0aGF0IGl0IHJlY2VpdmVzIHRoZSB0eXBlIG9mIHN5bWJvbCBpdCB3YXMgZXhwZWN0aW5nLgorICBlbnVtIFBsYWNlaG9sZGVyVHlwZSB7CisgICAgUExBQ0VIT0xERVJfTUVTU0FHRSwKKyAgICBQTEFDRUhPTERFUl9FTlVNLAorICAgIFBMQUNFSE9MREVSX0VYVEVOREFCTEVfTUVTU0FHRQorICB9OworICBlbnVtIFJlc29sdmVNb2RlIHsKKyAgICBMT09LVVBfQUxMLCBMT09LVVBfVFlQRVMKKyAgfTsKKyAgU3ltYm9sIExvb2t1cFN5bWJvbChjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyYgcmVsYXRpdmVfdG8sCisgICAgICAgICAgICAgICAgICAgICAgUGxhY2Vob2xkZXJUeXBlIHBsYWNlaG9sZGVyX3R5cGUgPSBQTEFDRUhPTERFUl9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgIFJlc29sdmVNb2RlIHJlc29sdmVfbW9kZSA9IExPT0tVUF9BTEwpOworCisgIC8vIExpa2UgTG9va3VwU3ltYm9sKCkgYnV0IHdpbGwgbm90IHJldHVybiBhIHBsYWNlaG9sZGVyIGV2ZW4gaWYKKyAgLy8gQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzKCkgaGFzIGJlZW4gdXNlZC4KKyAgU3ltYm9sIExvb2t1cFN5bWJvbE5vUGxhY2Vob2xkZXIoY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHJlbGF0aXZlX3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNvbHZlTW9kZSByZXNvbHZlX21vZGUgPSBMT09LVVBfQUxMKTsKKworICAvLyBDcmVhdGVzIGEgcGxhY2Vob2xkZXIgdHlwZSBzdWl0YWJsZSBmb3IgcmV0dXJuIGZyb20gTG9va3VwU3ltYm9sKCkuICBNYXkKKyAgLy8gcmV0dXJuIGtOdWxsU3ltYm9sIGlmIHRoZSBuYW1lIGlzIG5vdCBhIHZhbGlkIHR5cGUgbmFtZS4KKyAgU3ltYm9sIE5ld1BsYWNlaG9sZGVyKGNvbnN0IHN0cmluZyYgbmFtZSwgUGxhY2Vob2xkZXJUeXBlIHBsYWNlaG9sZGVyX3R5cGUpOworCisgIC8vIENyZWF0ZXMgYSBwbGFjZWhvbGRlciBmaWxlLiAgTmV2ZXIgcmV0dXJucyBOVUxMLiAgVGhpcyBpcyB1c2VkIHdoZW4gYW4KKyAgLy8gaW1wb3J0IGlzIG5vdCBmb3VuZCBhbmQgQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzKCkgaXMgZW5hYmxlZC4KKyAgRmlsZURlc2NyaXB0b3IqIE5ld1BsYWNlaG9sZGVyRmlsZShjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIENhbGxzIHRhYmxlc18tPkFkZFN5bWJvbCgpIGFuZCByZWNvcmRzIGFuIGVycm9yIGlmIGl0IGZhaWxzLiAgUmV0dXJucworICAvLyB0cnVlIGlmIHN1Y2Nlc3NmdWwgb3IgZmFsc2UgaWYgZmFpbGVkLCB0aG91Z2ggbW9zdCBjYWxsZXJzIGNhbiBpZ25vcmUKKyAgLy8gdGhlIHJldHVybiB2YWx1ZSBzaW5jZSBhbiBlcnJvciBoYXMgYWxyZWFkeSBiZWVuIHJlY29yZGVkLgorICBib29sIEFkZFN5bWJvbChjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIHByb3RvLCBTeW1ib2wgc3ltYm9sKTsKKworICAvLyBMaWtlIEFkZFN5bWJvbCgpLCBidXQgc3VjY2VlZHMgaWYgdGhlIHN5bWJvbCBpcyBhbHJlYWR5IGRlZmluZWQgYXMgbG9uZworICAvLyBhcyB0aGUgZXhpc3RpbmcgZGVmaW5pdGlvbiBpcyBhbHNvIGEgcGFja2FnZSAoYmVjYXVzZSBpdCdzIE9LIHRvIGRlZmluZQorICAvLyB0aGUgc2FtZSBwYWNrYWdlIGluIHR3byBkaWZmZXJlbnQgZmlsZXMpLiAgQWxzbyBhZGRzIGFsbCBwYXJlbnRzIG9mIHRoZQorICAvLyBwYWNrZ2FlIHRvIHRoZSBzeW1ib2wgdGFibGUgKGUuZy4gQWRkUGFja2FnZSgiZm9vLmJhciIsIC4uLikgd2lsbCBhZGQKKyAgLy8gImZvby5iYXIiIGFuZCAiZm9vIiB0byB0aGUgdGFibGUpLgorICB2b2lkIEFkZFBhY2thZ2UoY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBNZXNzYWdlJiBwcm90bywKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworICAvLyBDaGVja3MgdGhhdCB0aGUgc3ltYm9sIG5hbWUgY29udGFpbnMgb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQKKyAgLy8gdW5kZXJzY29yZXMuICBSZWNvcmRzIGFuIGVycm9yIG90aGVyd2lzZS4KKyAgdm9pZCBWYWxpZGF0ZVN5bWJvbE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgcHJvdG8pOworCisgIC8vIExpa2UgVmFsaWRhdGVTeW1ib2xOYW1lKCksIGJ1dCB0aGUgbmFtZSBpcyBhbGxvd2VkIHRvIGNvbnRhaW4gcGVyaW9kcyBhbmQKKyAgLy8gYW4gZXJyb3IgaXMgaW5kaWNhdGVkIGJ5IHJldHVybmluZyBmYWxzZSAobm90IHJlY29yZGluZyB0aGUgZXJyb3IpLgorICBib29sIFZhbGlkYXRlUXVhbGlmaWVkTmFtZShjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIFVzZWQgYnkgQlVJTERfQVJSQVkgbWFjcm8gKGJlbG93KSB0byBhdm9pZCBoYXZpbmcgdG8gaGF2ZSB0aGUgdHlwZQorICAvLyBzcGVjaWZpZWQgYXMgYSBtYWNybyBwYXJhbWV0ZXIuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgdm9pZCBBbGxvY2F0ZUFycmF5KGludCBzaXplLCBUeXBlKiogb3V0cHV0KSB7CisgICAgKm91dHB1dCA9IHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8VHlwZT4oc2l6ZSk7CisgIH0KKworICAvLyBBbGxvY2F0ZXMgYSBjb3B5IG9mIG9yaWdfb3B0aW9ucyBpbiB0YWJsZXNfIGFuZCBzdG9yZXMgaXQgaW4gdGhlCisgIC8vIGRlc2NyaXB0b3IuIFJlbWVtYmVycyBpdHMgdW5pbnRlcnByZXRlZCBvcHRpb25zLCB0byBiZSBpbnRlcnByZXRlZAorICAvLyBsYXRlci4gRGVzY3JpcHRvclQgbXVzdCBiZSBvbmUgb2YgdGhlIERlc2NyaXB0b3IgbWVzc2FnZXMgZnJvbQorICAvLyBkZXNjcmlwdG9yLnByb3RvLgorICB0ZW1wbGF0ZTxjbGFzcyBEZXNjcmlwdG9yVD4gdm9pZCBBbGxvY2F0ZU9wdGlvbnMoCisgICAgICBjb25zdCB0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGUmIG9yaWdfb3B0aW9ucywKKyAgICAgIERlc2NyaXB0b3JUKiBkZXNjcmlwdG9yKTsKKyAgLy8gU3BlY2lhbGl6YXRpb24gZm9yIEZpbGVPcHRpb25zLgorICB2b2lkIEFsbG9jYXRlT3B0aW9ucyhjb25zdCBGaWxlT3B0aW9ucyYgb3JpZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKyAgLy8gSW1wbGVtZW50YXRpb24gZm9yIEFsbG9jYXRlT3B0aW9ucygpLiBEb24ndCBjYWxsIHRoaXMgZGlyZWN0bHkuCisgIHRlbXBsYXRlPGNsYXNzIERlc2NyaXB0b3JUPiB2b2lkIEFsbG9jYXRlT3B0aW9uc0ltcGwoCisgICAgICBjb25zdCBzdHJpbmcmIG5hbWVfc2NvcGUsCisgICAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgIGNvbnN0IHR5cGVuYW1lIERlc2NyaXB0b3JUOjpPcHRpb25zVHlwZSYgb3JpZ19vcHRpb25zLAorICAgICAgRGVzY3JpcHRvclQqIGRlc2NyaXB0b3IpOworCisgIC8vIFRoZXNlIG1ldGhvZHMgYWxsIGhhdmUgdGhlIHNhbWUgc2lnbmF0dXJlIGZvciB0aGUgc2FrZSBvZiB0aGUgQlVJTERfQVJSQVkKKyAgLy8gbWFjcm8sIGJlbG93LgorICB2b2lkIEJ1aWxkTWVzc2FnZShjb25zdCBEZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3IqIHJlc3VsdCk7CisgIHZvaWQgQnVpbGRGaWVsZE9yRXh0ZW5zaW9uKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19leHRlbnNpb24pOworICB2b2lkIEJ1aWxkRmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgICBCdWlsZEZpZWxkT3JFeHRlbnNpb24ocHJvdG8sIHBhcmVudCwgcmVzdWx0LCBmYWxzZSk7CisgIH0KKyAgdm9pZCBCdWlsZEV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvciogcmVzdWx0KSB7CisgICAgQnVpbGRGaWVsZE9yRXh0ZW5zaW9uKHByb3RvLCBwYXJlbnQsIHJlc3VsdCwgdHJ1ZSk7CisgIH0KKyAgdm9pZCBCdWlsZEV4dGVuc2lvblJhbmdlKGNvbnN0IERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UmIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJlc3VsdCk7CisgIHZvaWQgQnVpbGRPbmVvZihjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICBPbmVvZkRlc2NyaXB0b3IqIHJlc3VsdCk7CisgIHZvaWQgQnVpbGRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgIEVudW1EZXNjcmlwdG9yKiByZXN1bHQpOworICB2b2lkIEJ1aWxkRW51bVZhbHVlKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yKiByZXN1bHQpOworICB2b2lkIEJ1aWxkU2VydmljZShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogZHVtbXksCisgICAgICAgICAgICAgICAgICAgIFNlcnZpY2VEZXNjcmlwdG9yKiByZXN1bHQpOworICB2b2lkIEJ1aWxkTWV0aG9kKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICBNZXRob2REZXNjcmlwdG9yKiByZXN1bHQpOworCisgIHZvaWQgTG9nVW51c2VkRGVwZW5kZW5jeShjb25zdCBGaWxlRGVzY3JpcHRvciogcmVzdWx0KTsKKworICAvLyBNdXN0IGJlIHJ1biBvbmx5IGFmdGVyIGJ1aWxkaW5nLgorICAvLworICAvLyBOT1RFOiBPcHRpb25zIHdpbGwgbm90IGJlIGF2YWlsYWJsZSBkdXJpbmcgY3Jvc3MtbGlua2luZywgYXMgdGhleQorICAvLyBoYXZlIG5vdCB5ZXQgYmVlbiBpbnRlcnByZXRlZC4gRGVmZXIgYW55IGhhbmRsaW5nIG9mIG9wdGlvbnMgdG8gdGhlCisgIC8vIFZhbGlkYXRlKk9wdGlvbnMgbWV0aG9kcy4KKyAgdm9pZCBDcm9zc0xpbmtGaWxlKEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgQ3Jvc3NMaW5rTWVzc2FnZShEZXNjcmlwdG9yKiBtZXNzYWdlLCBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBDcm9zc0xpbmtGaWVsZChGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgQ3Jvc3NMaW5rRW51bShFbnVtRGVzY3JpcHRvciogZW51bV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIENyb3NzTGlua0VudW1WYWx1ZShFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBDcm9zc0xpbmtTZXJ2aWNlKFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIENyb3NzTGlua01ldGhvZChNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgcHJvdG8pOworCisgIC8vIE11c3QgYmUgcnVuIG9ubHkgYWZ0ZXIgY3Jvc3MtbGlua2luZy4KKyAgdm9pZCBJbnRlcnByZXRPcHRpb25zKCk7CisKKyAgLy8gQSBoZWxwZXIgY2xhc3MgZm9yIGludGVycHJldGluZyBvcHRpb25zLgorICBjbGFzcyBPcHRpb25JbnRlcnByZXRlciB7CisgICBwdWJsaWM6CisgICAgLy8gQ3JlYXRlcyBhbiBpbnRlcnByZXRlciB0aGF0IG9wZXJhdGVzIGluIHRoZSBjb250ZXh0IG9mIHRoZSBwb29sIG9mIHRoZQorICAgIC8vIHNwZWNpZmllZCBidWlsZGVyLCB3aGljaCBtdXN0IG5vdCBiZSBOVUxMLiBXZSBkb24ndCB0YWtlIG93bmVyc2hpcCBvZiB0aGUKKyAgICAvLyBidWlsZGVyLgorICAgIGV4cGxpY2l0IE9wdGlvbkludGVycHJldGVyKERlc2NyaXB0b3JCdWlsZGVyKiBidWlsZGVyKTsKKworICAgIH5PcHRpb25JbnRlcnByZXRlcigpOworCisgICAgLy8gSW50ZXJwcmV0cyB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb25zIGluIHRoZSBzcGVjaWZpZWQgT3B0aW9ucyBtZXNzYWdlLgorICAgIC8vIE9uIGVycm9yLCBjYWxscyBBZGRFcnJvcigpIG9uIHRoZSB1bmRlcmx5aW5nIGJ1aWxkZXIgYW5kIHJldHVybnMgZmFsc2UuCisgICAgLy8gT3RoZXJ3aXNlIHJldHVybnMgdHJ1ZS4KKyAgICBib29sIEludGVycHJldE9wdGlvbnMoT3B0aW9uc1RvSW50ZXJwcmV0KiBvcHRpb25zX3RvX2ludGVycHJldCk7CisKKyAgICBjbGFzcyBBZ2dyZWdhdGVPcHRpb25GaW5kZXI7CisKKyAgIHByaXZhdGU6CisgICAgLy8gSW50ZXJwcmV0cyB1bmludGVycHJldGVkX29wdGlvbl8gb24gdGhlIHNwZWNpZmllZCBtZXNzYWdlLCB3aGljaAorICAgIC8vIG11c3QgYmUgdGhlIG11dGFibGUgY29weSBvZiB0aGUgb3JpZ2luYWwgb3B0aW9ucyBtZXNzYWdlIHRvIHdoaWNoCisgICAgLy8gdW5pbnRlcnByZXRlZF9vcHRpb25fIGJlbG9uZ3MuCisgICAgYm9vbCBJbnRlcnByZXRTaW5nbGVPcHRpb24oTWVzc2FnZSogb3B0aW9ucyk7CisKKyAgICAvLyBBZGRzIHRoZSB1bmludGVycHJldGVkX29wdGlvbiB0byB0aGUgZ2l2ZW4gb3B0aW9ucyBtZXNzYWdlIHZlcmJhdGltLgorICAgIC8vIFVzZWQgd2hlbiBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBpcyBpbiBlZmZlY3QgYW5kIHdlIGNhbid0IGZpbmQKKyAgICAvLyB0aGUgb3B0aW9uJ3MgZGVmaW5pdGlvbi4KKyAgICB2b2lkIEFkZFdpdGhvdXRJbnRlcnByZXRpbmcoY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZF9vcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG9wdGlvbnMpOworCisgICAgLy8gQSByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRoYXQgZHJpbGxzIGludG8gdGhlIGludGVybWVkaWF0ZSBmaWVsZHMKKyAgICAvLyBpbiB1bmtub3duX2ZpZWxkcyB0byBjaGVjayBpZiBmaWVsZCBpbm5lcm1vc3RfZmllbGQgaXMgc2V0IG9uIHRoZQorICAgIC8vIGlubmVybW9zdCBtZXNzYWdlLiBSZXR1cm5zIGZhbHNlIGFuZCBzZXRzIGFuIGVycm9yIGlmIHNvLgorICAgIGJvb2wgRXhhbWluZUlmT3B0aW9uSXNTZXQoCisgICAgICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPjo6Y29uc3RfaXRlcmF0b3IgaW50ZXJtZWRpYXRlX2ZpZWxkc19pdGVyLAorICAgICAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj46OmNvbnN0X2l0ZXJhdG9yIGludGVybWVkaWF0ZV9maWVsZHNfZW5kLAorICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGlubmVybW9zdF9maWVsZCwgY29uc3Qgc3RyaW5nJiBkZWJ1Z19tc2dfbmFtZSwKKyAgICAgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcyk7CisKKyAgICAvLyBWYWxpZGF0ZXMgdGhlIHZhbHVlIGZvciB0aGUgb3B0aW9uIGZpZWxkIG9mIHRoZSBjdXJyZW50bHkgaW50ZXJwcmV0ZWQKKyAgICAvLyBvcHRpb24gYW5kIHRoZW4gc2V0cyBpdCBvbiB0aGUgdW5rbm93bl9maWVsZC4KKyAgICBib29sIFNldE9wdGlvblZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb3B0aW9uX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisKKyAgICAvLyBQYXJzZXMgYW4gYWdncmVnYXRlIHZhbHVlIGZvciBhIENQUFRZUEVfTUVTU0FHRSBvcHRpb24gYW5kCisgICAgLy8gc2F2ZXMgaXQgaW50byAqdW5rbm93bl9maWVsZHMuCisgICAgYm9vbCBTZXRBZ2dyZWdhdGVPcHRpb24oY29uc3QgRmllbGREZXNjcmlwdG9yKiBvcHRpb25fZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisKKyAgICAvLyBDb252ZW5pZW5jZSBmdW5jdGlvbnMgdG8gc2V0IGFuIGludCBmaWVsZCB0aGUgcmlnaHQgd2F5LCBkZXBlbmRpbmcgb24KKyAgICAvLyBpdHMgd2lyZSB0eXBlIChhIHNpbmdsZSBpbnQgQ3BwVHlwZSBjYW4gcmVwcmVzZW50IG11bHRpcGxlIHdpcmUgdHlwZXMpLgorICAgIHZvaWQgU2V0SW50MzIoaW50IG51bWJlciwgaW50MzIgdmFsdWUsIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisgICAgdm9pZCBTZXRJbnQ2NChpbnQgbnVtYmVyLCBpbnQ2NCB2YWx1ZSwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKyAgICB2b2lkIFNldFVJbnQzMihpbnQgbnVtYmVyLCB1aW50MzIgdmFsdWUsIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpOworICAgIHZvaWQgU2V0VUludDY0KGludCBudW1iZXIsIHVpbnQ2NCB2YWx1ZSwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisKKyAgICAvLyBBIGhlbHBlciBmdW5jdGlvbiB0aGF0IGFkZHMgYW4gZXJyb3IgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbiBvZiB0aGUKKyAgICAvLyBvcHRpb24gd2UncmUgY3VycmVudGx5IGludGVycHJldGluZywgYW5kIHJldHVybnMgZmFsc2UuCisgICAgYm9vbCBBZGRPcHRpb25FcnJvcihEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1zZykgeworICAgICAgYnVpbGRlcl8tPkFkZEVycm9yKG9wdGlvbnNfdG9faW50ZXJwcmV0Xy0+ZWxlbWVudF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICp1bmludGVycHJldGVkX29wdGlvbl8sIGxvY2F0aW9uLCBtc2cpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8vIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgYWRkcyBhbiBlcnJvciBhdCB0aGUgbG9jYXRpb24gb2YgdGhlIG9wdGlvbiBuYW1lCisgICAgLy8gYW5kIHJldHVybnMgZmFsc2UuCisgICAgYm9vbCBBZGROYW1lRXJyb3IoY29uc3Qgc3RyaW5nJiBtc2cpIHsKKyAgICAgIHJldHVybiBBZGRPcHRpb25FcnJvcihEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9QVElPTl9OQU1FLCBtc2cpOworICAgIH0KKworICAgIC8vIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgYWRkcyBhbiBlcnJvciBhdCB0aGUgbG9jYXRpb24gb2YgdGhlIG9wdGlvbiBuYW1lCisgICAgLy8gYW5kIHJldHVybnMgZmFsc2UuCisgICAgYm9vbCBBZGRWYWx1ZUVycm9yKGNvbnN0IHN0cmluZyYgbXNnKSB7CisgICAgICByZXR1cm4gQWRkT3B0aW9uRXJyb3IoRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPUFRJT05fVkFMVUUsIG1zZyk7CisgICAgfQorCisgICAgLy8gV2UgaW50ZXJwcmV0IGFnYWluc3QgdGhpcyBidWlsZGVyJ3MgcG9vbC4gSXMgbmV2ZXIgTlVMTC4gV2UgZG9uJ3Qgb3duCisgICAgLy8gdGhpcyBwb2ludGVyLgorICAgIERlc2NyaXB0b3JCdWlsZGVyKiBidWlsZGVyXzsKKworICAgIC8vIFRoZSBvcHRpb25zIHdlJ3JlIGN1cnJlbnRseSBpbnRlcnByZXRpbmcsIG9yIE5VTEwgaWYgd2UncmUgbm90IGluIGEgY2FsbAorICAgIC8vIHRvIEludGVycHJldE9wdGlvbnMuCisgICAgY29uc3QgT3B0aW9uc1RvSW50ZXJwcmV0KiBvcHRpb25zX3RvX2ludGVycHJldF87CisKKyAgICAvLyBUaGUgb3B0aW9uIHdlJ3JlIGN1cnJlbnRseSBpbnRlcnByZXRpbmcgd2l0aGluIG9wdGlvbnNfdG9faW50ZXJwcmV0Xywgb3IKKyAgICAvLyBOVUxMIGlmIHdlJ3JlIG5vdCBpbiBhIGNhbGwgdG8gSW50ZXJwcmV0T3B0aW9ucygpLiBUaGlzIHBvaW50cyB0byBhCisgICAgLy8gc3VibWVzc2FnZSBvZiB0aGUgb3JpZ2luYWwgb3B0aW9uLCBub3QgdGhlIG11dGFibGUgY29weS4gVGhlcmVmb3JlIHdlCisgICAgLy8gY2FuIHVzZSBpdCB0byBmaW5kIGxvY2F0aW9ucyByZWNvcmRlZCBieSB0aGUgcGFyc2VyLgorICAgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24qIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKKworICAgIC8vIEZhY3RvcnkgdXNlZCB0byBjcmVhdGUgdGhlIGR5bmFtaWMgbWVzc2FnZXMgd2UgbmVlZCB0byBwYXJzZQorICAgIC8vIGFueSBhZ2dyZWdhdGUgb3B0aW9uIHZhbHVlcyB3ZSBlbmNvdW50ZXIuCisgICAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGR5bmFtaWNfZmFjdG9yeV87CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoT3B0aW9uSW50ZXJwcmV0ZXIpOworICB9OworCisgIC8vIFdvcmstYXJvdW5kIGZvciBicm9rZW4gY29tcGlsZXJzOiAgQWNjb3JkaW5nIHRvIHRoZSBDKysgc3RhbmRhcmQsCisgIC8vIE9wdGlvbkludGVycHJldGVyIHNob3VsZCBoYXZlIGFjY2VzcyB0byB0aGUgcHJpdmF0ZSBtZW1iZXJzIG9mIGFueSBjbGFzcworICAvLyB3aGljaCBoYXMgZGVjbGFyZWQgRGVzY3JpcHRvckJ1aWxkZXIgYXMgYSBmcmllbmQuICBVbmZvcnR1bmF0ZWx5IHNvbWUgb2xkCisgIC8vIHZlcnNpb25zIG9mIEdDQyBhbmQgb3RoZXIgY29tcGlsZXJzIGRvIG5vdCBpbXBsZW1lbnQgdGhpcyBjb3JyZWN0bHkuICBTbywKKyAgLy8gd2UgaGF2ZSB0byBoYXZlIHRoZXNlIGludGVybWVkaWF0ZSBtZXRob2RzIHRvIHByb3ZpZGUgYWNjZXNzLiAgV2UgYWxzbworICAvLyByZWR1bmRhbnRseSBkZWNsYXJlIE9wdGlvbkludGVycHJldGVyIGEgZnJpZW5kIGp1c3QgdG8gbWFrZSB0aGluZ3MgZXh0cmEKKyAgLy8gY2xlYXIgZm9yIHRoZXNlIGJhZCBjb21waWxlcnMuCisgIGZyaWVuZCBjbGFzcyBPcHRpb25JbnRlcnByZXRlcjsKKyAgZnJpZW5kIGNsYXNzIE9wdGlvbkludGVycHJldGVyOjpBZ2dyZWdhdGVPcHRpb25GaW5kZXI7CisKKyAgc3RhdGljIGlubGluZSBib29sIGdldF9hbGxvd191bmtub3duKGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKSB7CisgICAgcmV0dXJuIHBvb2wtPmFsbG93X3Vua25vd25fOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBnZXRfZW5mb3JjZV93ZWFrKGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKSB7CisgICAgcmV0dXJuIHBvb2wtPmVuZm9yY2Vfd2Vha187CisgIH0KKyAgc3RhdGljIGlubGluZSBib29sIGdldF9pc19wbGFjZWhvbGRlcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgICAgcmV0dXJuIGRlc2NyaXB0b3ItPmlzX3BsYWNlaG9sZGVyXzsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgYXNzZXJ0X211dGV4X2hlbGQoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpIHsKKyAgICBpZiAocG9vbC0+bXV0ZXhfICE9IE5VTEwpIHsKKyAgICAgIHBvb2wtPm11dGV4Xy0+QXNzZXJ0SGVsZCgpOworICAgIH0KKyAgfQorCisgIC8vIE11c3QgYmUgcnVuIG9ubHkgYWZ0ZXIgb3B0aW9ucyBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQuCisgIC8vCisgIC8vIE5PVEU6IFZhbGlkYXRpb24gY29kZSBtdXN0IG9ubHkgcmVmZXJlbmNlIHRoZSBvcHRpb25zIGluIHRoZSBtdXRhYmxlCisgIC8vIGRlc2NyaXB0b3JzLCB3aGljaCBhcmUgdGhlIG9uZXMgdGhhdCBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQuIFRoZSBjb25zdAorICAvLyBwcm90byByZWZlcmVuY2VzIGFyZSBwYXNzZWQgaW4gb25seSBzbyB0aGV5IGNhbiBiZSBwcm92aWRlZCB0byBjYWxscyB0bworICAvLyBBZGRFcnJvcigpLiBEbyBub3QgbG9vayBhdCB0aGVpciBvcHRpb25zLCB3aGljaCBoYXZlIG5vdCBiZWVuIGludGVycHJldGVkLgorICB2b2lkIFZhbGlkYXRlRmlsZU9wdGlvbnMoRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVNZXNzYWdlT3B0aW9ucyhEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVGaWVsZE9wdGlvbnMoRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIFZhbGlkYXRlRW51bU9wdGlvbnMoRW51bURlc2NyaXB0b3IqIGVubSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZUVudW1WYWx1ZU9wdGlvbnMoRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVTZXJ2aWNlT3B0aW9ucyhTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZU1ldGhvZE9wdGlvbnMoTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZVByb3RvMyhGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVQcm90bzNNZXNzYWdlKERlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIFZhbGlkYXRlUHJvdG8zRmllbGQoRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVQcm90bzNFbnVtKEVudW1EZXNjcmlwdG9yKiBlbm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG1hcCBlbnRyeSBtZXNzYWdlIGlzIGNvbXBhdGlibGUgd2l0aCB0aGUKKyAgLy8gYXV0by1nZW5lcmF0ZWQgZW50cnkgbWVzc2FnZSBmcm9tIG1hcCBmaWVsZHMgc3ludGF4LgorICBib29sIFZhbGlkYXRlTWFwRW50cnkoRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisKKyAgLy8gUmVjdXJzaXZlbHkgZGV0ZWN0cyBuYW1pbmcgY29uZmxpY3RzIHdpdGggbWFwIGVudHJ5IHR5cGVzIGZvciBhCisgIC8vIGJldHRlciBlcnJvciBtZXNzYWdlLgorICB2b2lkIERldGVjdE1hcENvbmZsaWN0cyhjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKworfTsKKworY29uc3QgRmlsZURlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpCdWlsZEZpbGUoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgR09PR0xFX0NIRUNLKGZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKQorICAgIDw8ICJDYW5ub3QgY2FsbCBCdWlsZEZpbGUgb24gYSBEZXNjcmlwdG9yUG9vbCB0aGF0IHVzZXMgYSAiCisgICAgICAgIkRlc2NyaXB0b3JEYXRhYmFzZS4gIFlvdSBtdXN0IGluc3RlYWQgZmluZCBhIHdheSB0byBnZXQgeW91ciBmaWxlICIKKyAgICAgICAiaW50byB0aGUgdW5kZXJseWluZyBkYXRhYmFzZS4iOworICBHT09HTEVfQ0hFQ0sobXV0ZXhfID09IE5VTEwpOyAgIC8vIEltcGxpZWQgYnkgdGhlIGFib3ZlIEdPT0dMRV9DSEVDSy4KKyAgdGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmNsZWFyKCk7CisgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY2xlYXIoKTsKKyAgcmV0dXJuIERlc2NyaXB0b3JCdWlsZGVyKHRoaXMsIHRhYmxlc18uZ2V0KCksIE5VTEwpLkJ1aWxkRmlsZShwcm90byk7Cit9CisKK2NvbnN0IEZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6QnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycygKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICBFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKSB7CisgIEdPT0dMRV9DSEVDSyhmYWxsYmFja19kYXRhYmFzZV8gPT0gTlVMTCkKKyAgICA8PCAiQ2Fubm90IGNhbGwgQnVpbGRGaWxlIG9uIGEgRGVzY3JpcHRvclBvb2wgdGhhdCB1c2VzIGEgIgorICAgICAgICJEZXNjcmlwdG9yRGF0YWJhc2UuICBZb3UgbXVzdCBpbnN0ZWFkIGZpbmQgYSB3YXkgdG8gZ2V0IHlvdXIgZmlsZSAiCisgICAgICAgImludG8gdGhlIHVuZGVybHlpbmcgZGF0YWJhc2UuIjsKKyAgR09PR0xFX0NIRUNLKG11dGV4XyA9PSBOVUxMKTsgICAvLyBJbXBsaWVkIGJ5IHRoZSBhYm92ZSBHT09HTEVfQ0hFQ0suCisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisgIHJldHVybiBEZXNjcmlwdG9yQnVpbGRlcih0aGlzLCB0YWJsZXNfLmdldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfY29sbGVjdG9yKS5CdWlsZEZpbGUocHJvdG8pOworfQorCitjb25zdCBGaWxlRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkJ1aWxkRmlsZUZyb21EYXRhYmFzZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bykgY29uc3QgeworICBtdXRleF8tPkFzc2VydEhlbGQoKTsKKyAgaWYgKHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY291bnQocHJvdG8ubmFtZSgpKSA+IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBjb25zdCBGaWxlRGVzY3JpcHRvciogcmVzdWx0ID0KKyAgICAgIERlc2NyaXB0b3JCdWlsZGVyKHRoaXMsIHRhYmxlc18uZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2Vycm9yX2NvbGxlY3Rvcl8pLkJ1aWxkRmlsZShwcm90byk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uaW5zZXJ0KHByb3RvLm5hbWUoKSk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRGVzY3JpcHRvckJ1aWxkZXI6OkRlc2NyaXB0b3JCdWlsZGVyKAorICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgIERlc2NyaXB0b3JQb29sOjpUYWJsZXMqIHRhYmxlcywKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3RvcikKKyAgOiBwb29sXyhwb29sKSwKKyAgICB0YWJsZXNfKHRhYmxlcyksCisgICAgZXJyb3JfY29sbGVjdG9yXyhlcnJvcl9jb2xsZWN0b3IpLAorICAgIGhhZF9lcnJvcnNfKGZhbHNlKSwKKyAgICBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfKE5VTEwpLAorICAgIHVuZGVmaW5lX3Jlc29sdmVkX25hbWVfKCIiKSB7fQorCitEZXNjcmlwdG9yQnVpbGRlcjo6fkRlc2NyaXB0b3JCdWlsZGVyKCkge30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkRXJyb3IoCisgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgY29uc3Qgc3RyaW5nJiBlcnJvcikgeworICBpZiAoZXJyb3JfY29sbGVjdG9yXyA9PSBOVUxMKSB7CisgICAgaWYgKCFoYWRfZXJyb3JzXykgeworICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkludmFsaWQgcHJvdG8gZGVzY3JpcHRvciBmb3IgZmlsZSBcIiIgPDwgZmlsZW5hbWVfCisgICAgICAgICAgICAgICAgIDw8ICJcIjoiOworICAgIH0KKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiICAiIDw8IGVsZW1lbnRfbmFtZSA8PCAiOiAiIDw8IGVycm9yOworICB9IGVsc2UgeworICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGZpbGVuYW1lXywgZWxlbWVudF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXNjcmlwdG9yLCBsb2NhdGlvbiwgZXJyb3IpOworICB9CisgIGhhZF9lcnJvcnNfID0gdHJ1ZTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkRXJyb3IoCisgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgQWRkRXJyb3IoZWxlbWVudF9uYW1lLCBkZXNjcmlwdG9yLCBsb2NhdGlvbiwgc3RyaW5nKGVycm9yKSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZE5vdERlZmluZWRFcnJvcigKKyAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICBjb25zdCBzdHJpbmcmIHVuZGVmaW5lZF9zeW1ib2wpIHsKKyAgaWYgKHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV8gPT0gTlVMTCAmJgorICAgICAgdW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8uZW1wdHkoKSkgeworICAgIEFkZEVycm9yKGVsZW1lbnRfbmFtZSwgZGVzY3JpcHRvciwgbG9jYXRpb24sCisgICAgICAgICAgICAgIlwiIiArIHVuZGVmaW5lZF9zeW1ib2wgKyAiXCIgaXMgbm90IGRlZmluZWQuIik7CisgIH0gZWxzZSB7CisgICAgaWYgKHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV8gIT0gTlVMTCkgeworICAgICAgQWRkRXJyb3IoZWxlbWVudF9uYW1lLCBkZXNjcmlwdG9yLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICJcIiIgKyBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfbmFtZV8gKworICAgICAgICAgICAgICAgIlwiIHNlZW1zIHRvIGJlIGRlZmluZWQgaW4gXCIiICsKKyAgICAgICAgICAgICAgIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV8tPm5hbWUoKSArICJcIiwgd2hpY2ggaXMgbm90ICIKKyAgICAgICAgICAgICAgICJpbXBvcnRlZCBieSBcIiIgKyBmaWxlbmFtZV8gKyAiXCIuICBUbyB1c2UgaXQgaGVyZSwgcGxlYXNlICIKKyAgICAgICAgICAgICAgICJhZGQgdGhlIG5lY2Vzc2FyeSBpbXBvcnQuIik7CisgICAgfQorICAgIGlmICghdW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8uZW1wdHkoKSkgeworICAgICAgQWRkRXJyb3IoZWxlbWVudF9uYW1lLCBkZXNjcmlwdG9yLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICJcIiIgKyB1bmRlZmluZWRfc3ltYm9sICsgIlwiIGlzIHJlc29sdmVkIHRvIFwiIiArCisgICAgICAgICAgICAgICB1bmRlZmluZV9yZXNvbHZlZF9uYW1lXyArICJcIiwgd2hpY2ggaXMgbm90IGRlZmluZWQuICIKKyAgICAgICAgICAgICAgICJUaGUgaW5uZXJtb3N0IHNjb3BlIGlzIHNlYXJjaGVkIGZpcnN0IGluIG5hbWUgcmVzb2x1dGlvbi4gIgorICAgICAgICAgICAgICAgIkNvbnNpZGVyIHVzaW5nIGEgbGVhZGluZyAnLicoaS5lLiwgXCIuIgorICAgICAgICAgICAgICAgKyB1bmRlZmluZWRfc3ltYm9sICsKKyAgICAgICAgICAgICAgICJcIikgdG8gc3RhcnQgZnJvbSB0aGUgb3V0ZXJtb3N0IHNjb3BlLiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpBZGRXYXJuaW5nKAorICAgIGNvbnN0IHN0cmluZyYgZWxlbWVudF9uYW1lLCBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICBjb25zdCBzdHJpbmcmIGVycm9yKSB7CisgIGlmIChlcnJvcl9jb2xsZWN0b3JfID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8IGZpbGVuYW1lXyA8PCAiICIgPDwgZWxlbWVudF9uYW1lIDw8ICI6ICIgPDwgZXJyb3I7CisgIH0gZWxzZSB7CisgICAgZXJyb3JfY29sbGVjdG9yXy0+QWRkV2FybmluZyhmaWxlbmFtZV8sIGVsZW1lbnRfbmFtZSwgJmRlc2NyaXB0b3IsIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IpOworICB9Cit9CisKK2Jvb2wgRGVzY3JpcHRvckJ1aWxkZXI6OklzSW5QYWNrYWdlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYWNrYWdlX25hbWUpIHsKKyAgcmV0dXJuIEhhc1ByZWZpeFN0cmluZyhmaWxlLT5wYWNrYWdlKCksIHBhY2thZ2VfbmFtZSkgJiYKKyAgICAgICAgICAgKGZpbGUtPnBhY2thZ2UoKS5zaXplKCkgPT0gcGFja2FnZV9uYW1lLnNpemUoKSB8fAorICAgICAgICAgICAgZmlsZS0+cGFja2FnZSgpW3BhY2thZ2VfbmFtZS5zaXplKCldID09ICcuJyk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlJlY29yZFB1YmxpY0RlcGVuZGVuY2llcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBpZiAoZmlsZSA9PSBOVUxMIHx8ICFkZXBlbmRlbmNpZXNfLmluc2VydChmaWxlKS5zZWNvbmQpIHJldHVybjsKKyAgZm9yIChpbnQgaSA9IDA7IGZpbGUgIT0gTlVMTCAmJiBpIDwgZmlsZS0+cHVibGljX2RlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgUmVjb3JkUHVibGljRGVwZW5kZW5jaWVzKGZpbGUtPnB1YmxpY19kZXBlbmRlbmN5KGkpKTsKKyAgfQorfQorCitTeW1ib2wgRGVzY3JpcHRvckJ1aWxkZXI6OkZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzSGVscGVyKAorICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgLy8gSWYgd2UgYXJlIGxvb2tpbmcgYXQgYW4gdW5kZXJsYXksIHdlIG11c3QgbG9jayBpdHMgbXV0ZXhfLCBzaW5jZSB3ZSBhcmUKKyAgLy8gYWNjZXNzaW5nIHRoZSB1bmRlcmxheSdzIHRhYmxlc18gZGlyZWN0bHkuCisgIE11dGV4TG9ja01heWJlIGxvY2soKHBvb2wgPT0gcG9vbF8pID8gTlVMTCA6IHBvb2wtPm11dGV4Xyk7CisKKyAgU3ltYm9sIHJlc3VsdCA9IHBvb2wtPnRhYmxlc18tPkZpbmRTeW1ib2wobmFtZSk7CisgIGlmIChyZXN1bHQuSXNOdWxsKCkgJiYgcG9vbC0+dW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICAvLyBTeW1ib2wgbm90IGZvdW5kOyBjaGVjayB0aGUgdW5kZXJsYXkuCisgICAgcmVzdWx0ID0gRmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHNIZWxwZXIocG9vbC0+dW5kZXJsYXlfLCBuYW1lKTsKKyAgfQorCisgIGlmIChyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICAvLyBJbiB0aGVvcnksIHdlIHNob3VsZG4ndCBuZWVkIHRvIGNoZWNrIGZhbGxiYWNrX2RhdGFiYXNlXyBiZWNhdXNlIHRoZQorICAgIC8vIHN5bWJvbCBzaG91bGQgYmUgaW4gb25lIG9mIGl0cyBmaWxlJ3MgZGlyZWN0IGRlcGVuZGVuY2llcywgYW5kIHdlIGhhdmUKKyAgICAvLyBhbHJlYWR5IGxvYWRlZCB0aG9zZSBieSB0aGUgdGltZSB3ZSBnZXQgaGVyZS4gIEJ1dCB3ZSBjaGVjayBhbnl3YXkgc28KKyAgICAvLyB0aGF0IHdlIGNhbiBnZW5lcmF0ZSBiZXR0ZXIgZXJyb3IgbWVzc2FnZSB3aGVuIGRlcGVuZGVuY2llcyBhcmUgbWlzc2luZworICAgIC8vIChpLmUuLCAibWlzc2luZyBkZXBlbmRlbmN5IiByYXRoZXIgdGhhbiAidHlwZSBpcyBub3QgZGVmaW5lZCIpLgorICAgIGlmIChwb29sLT5UcnlGaW5kU3ltYm9sSW5GYWxsYmFja0RhdGFiYXNlKG5hbWUpKSB7CisgICAgICByZXN1bHQgPSBwb29sLT50YWJsZXNfLT5GaW5kU3ltYm9sKG5hbWUpOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK1N5bWJvbCBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHMoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIHJldHVybiBGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwc0hlbHBlcihwb29sXywgbmFtZSk7Cit9CisKK1N5bWJvbCBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbChjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgU3ltYm9sIHJlc3VsdCA9IEZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzKG5hbWUpOworCisgIGlmIChyZXN1bHQuSXNOdWxsKCkpIHJldHVybiByZXN1bHQ7CisKKyAgaWYgKCFwb29sXy0+ZW5mb3JjZV9kZXBlbmRlbmNpZXNfKSB7CisgICAgLy8gSGFjayBmb3IgQ29tcGlsZXJVcGdyYWRlci4KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gT25seSBmaW5kIHN5bWJvbHMgd2hpY2ggd2VyZSBkZWZpbmVkIGluIHRoaXMgZmlsZSBvciBvbmUgb2YgaXRzCisgIC8vIGRlcGVuZGVuY2llcy4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSByZXN1bHQuR2V0RmlsZSgpOworICBpZiAoZmlsZSA9PSBmaWxlXyB8fCBkZXBlbmRlbmNpZXNfLmNvdW50KGZpbGUpID4gMCkgeworICAgIHVudXNlZF9kZXBlbmRlbmN5Xy5lcmFzZShmaWxlKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgaWYgKHJlc3VsdC50eXBlID09IFN5bWJvbDo6UEFDS0FHRSkgeworICAgIC8vIEFyZywgdGhpcyBpcyBvdmVyY29tcGxpY2F0ZWQuICBUaGUgc3ltYm9sIGlzIGEgcGFja2FnZSBuYW1lLiAgSXQgY291bGQKKyAgICAvLyBiZSB0aGF0IHRoZSBwYWNrYWdlIHdhcyBkZWZpbmVkIGluIG11bHRpcGxlIGZpbGVzLiAgcmVzdWx0LkdldEZpbGUoKQorICAgIC8vIHJldHVybnMgdGhlIGZpcnN0IGZpbGUgd2Ugc2F3IHRoYXQgdXNlZCB0aGlzIHBhY2thZ2UuICBXZSd2ZSBkZXRlcm1pbmVkCisgICAgLy8gdGhhdCB0aGF0IGZpbGUgaXMgbm90IGEgZGlyZWN0IGRlcGVuZGVuY3kgb2YgdGhlIGZpbGUgd2UgYXJlIGN1cnJlbnRseQorICAgIC8vIGJ1aWxkaW5nLCBidXQgaXQgY291bGQgYmUgdGhhdCBzb21lIG90aGVyIGZpbGUgd2hpY2ggKmlzKiBhIGRpcmVjdAorICAgIC8vIGRlcGVuZGVuY3kgYWxzbyBkZWZpbmVzIHRoZSBzYW1lIHBhY2thZ2UuICBXZSBjYW4ndCByZWFsbHkgcnVsZSBvdXQgdGhpcworICAgIC8vIHN5bWJvbCB1bmxlc3Mgbm9uZSBvZiB0aGUgZGVwZW5kZW5jaWVzIGRlZmluZSBpdC4KKyAgICBpZiAoSXNJblBhY2thZ2UoZmlsZV8sIG5hbWUpKSByZXR1cm4gcmVzdWx0OworICAgIGZvciAoc2V0PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gZGVwZW5kZW5jaWVzXy5iZWdpbigpOworICAgICAgICAgaXQgIT0gZGVwZW5kZW5jaWVzXy5lbmQoKTsgKytpdCkgeworICAgICAgLy8gTm90ZTogIEEgZGVwZW5kZW5jeSBtYXkgYmUgTlVMTCBpZiBpdCB3YXMgbm90IGZvdW5kIG9yIGhhZCBlcnJvcnMuCisgICAgICBpZiAoKml0ICE9IE5VTEwgJiYgSXNJblBhY2thZ2UoKml0LCBuYW1lKSkgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgIH0KKworICBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfID0gZmlsZTsKKyAgcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5X25hbWVfID0gbmFtZTsKKyAgcmV0dXJuIGtOdWxsU3ltYm9sOworfQorCitTeW1ib2wgRGVzY3JpcHRvckJ1aWxkZXI6Okxvb2t1cFN5bWJvbE5vUGxhY2Vob2xkZXIoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBzdHJpbmcmIHJlbGF0aXZlX3RvLCBSZXNvbHZlTW9kZSByZXNvbHZlX21vZGUpIHsKKyAgcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5XyA9IE5VTEw7CisgIHVuZGVmaW5lX3Jlc29sdmVkX25hbWVfLmNsZWFyKCk7CisKKyAgaWYgKG5hbWUuc2l6ZSgpID4gMCAmJiBuYW1lWzBdID09ICcuJykgeworICAgIC8vIEZ1bGx5LXF1YWxpZmllZCBuYW1lLgorICAgIHJldHVybiBGaW5kU3ltYm9sKG5hbWUuc3Vic3RyKDEpKTsKKyAgfQorCisgIC8vIElmIG5hbWUgaXMgc29tZXRoaW5nIGxpa2UgIkZvby5CYXIuYmF6IiwgYW5kIHN5bWJvbHMgbmFtZWQgIkZvbyIgYXJlCisgIC8vIGRlZmluZWQgaW4gbXVsdGlwbGUgcGFyZW50IHNjb3Blcywgd2Ugb25seSB3YW50IHRvIGZpbmQgIkJhci5iYXoiIGluIHRoZQorICAvLyBpbm5lcm1vc3Qgb25lLiAgRS5nLiwgdGhlIGZvbGxvd2luZyBzaG91bGQgcHJvZHVjZSBhbiBlcnJvcjoKKyAgLy8gICBtZXNzYWdlIEJhciB7IG1lc3NhZ2UgQmF6IHt9IH0KKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBtZXNzYWdlIEJhciB7CisgIC8vICAgICB9CisgIC8vICAgICBvcHRpb25hbCBCYXIuQmF6IGJheiA9IDE7CisgIC8vICAgfQorICAvLyBTbywgd2UgbG9vayBmb3IganVzdCAiRm9vIiBmaXJzdCwgdGhlbiBsb29rIGZvciAiQmFyLmJheiIgd2l0aGluIGl0IGlmCisgIC8vIGZvdW5kLgorICBzdHJpbmc6OnNpemVfdHlwZSBuYW1lX2RvdF9wb3MgPSBuYW1lLmZpbmRfZmlyc3Rfb2YoJy4nKTsKKyAgc3RyaW5nIGZpcnN0X3BhcnRfb2ZfbmFtZTsKKyAgaWYgKG5hbWVfZG90X3BvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICBmaXJzdF9wYXJ0X29mX25hbWUgPSBuYW1lOworICB9IGVsc2UgeworICAgIGZpcnN0X3BhcnRfb2ZfbmFtZSA9IG5hbWUuc3Vic3RyKDAsIG5hbWVfZG90X3Bvcyk7CisgIH0KKworICBzdHJpbmcgc2NvcGVfdG9fdHJ5KHJlbGF0aXZlX3RvKTsKKworICB3aGlsZSAodHJ1ZSkgeworICAgIC8vIENob3Agb2ZmIHRoZSBsYXN0IGNvbXBvbmVudCBvZiB0aGUgc2NvcGUuCisgICAgc3RyaW5nOjpzaXplX3R5cGUgZG90X3BvcyA9IHNjb3BlX3RvX3RyeS5maW5kX2xhc3Rfb2YoJy4nKTsKKyAgICBpZiAoZG90X3BvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIHJldHVybiBGaW5kU3ltYm9sKG5hbWUpOworICAgIH0gZWxzZSB7CisgICAgICBzY29wZV90b190cnkuZXJhc2UoZG90X3Bvcyk7CisgICAgfQorCisgICAgLy8gQXBwZW5kICIuZmlyc3RfcGFydF9vZl9uYW1lIiBhbmQgdHJ5IHRvIGZpbmQuCisgICAgc3RyaW5nOjpzaXplX3R5cGUgb2xkX3NpemUgPSBzY29wZV90b190cnkuc2l6ZSgpOworICAgIHNjb3BlX3RvX3RyeS5hcHBlbmQoMSwgJy4nKTsKKyAgICBzY29wZV90b190cnkuYXBwZW5kKGZpcnN0X3BhcnRfb2ZfbmFtZSk7CisgICAgU3ltYm9sIHJlc3VsdCA9IEZpbmRTeW1ib2woc2NvcGVfdG9fdHJ5KTsKKyAgICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgICAgaWYgKGZpcnN0X3BhcnRfb2ZfbmFtZS5zaXplKCkgPCBuYW1lLnNpemUoKSkgeworICAgICAgICAvLyBuYW1lIGlzIGEgY29tcG91bmQgc3ltYm9sLCBvZiB3aGljaCB3ZSBvbmx5IGZvdW5kIHRoZSBmaXJzdCBwYXJ0LgorICAgICAgICAvLyBOb3cgdHJ5IHRvIGxvb2sgdXAgdGhlIHJlc3Qgb2YgaXQuCisgICAgICAgIGlmIChyZXN1bHQuSXNBZ2dyZWdhdGUoKSkgeworICAgICAgICAgIHNjb3BlX3RvX3RyeS5hcHBlbmQobmFtZSwgZmlyc3RfcGFydF9vZl9uYW1lLnNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuc2l6ZSgpIC0gZmlyc3RfcGFydF9vZl9uYW1lLnNpemUoKSk7CisgICAgICAgICAgcmVzdWx0ID0gRmluZFN5bWJvbChzY29wZV90b190cnkpOworICAgICAgICAgIGlmIChyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICAgICAgICAgIHVuZGVmaW5lX3Jlc29sdmVkX25hbWVfID0gc2NvcGVfdG9fdHJ5OworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFdlIGZvdW5kIGEgc3ltYm9sIGJ1dCBpdCdzIG5vdCBhbiBhZ2dyZWdhdGUuICBDb250aW51ZSB0aGUgbG9vcC4KKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKHJlc29sdmVfbW9kZSA9PSBMT09LVVBfVFlQRVMgJiYgIXJlc3VsdC5Jc1R5cGUoKSkgeworICAgICAgICAgIC8vIFdlIGZvdW5kIGEgc3ltYm9sIGJ1dCBpdCdzIG5vdCBhIHR5cGUuICBDb250aW51ZSB0aGUgbG9vcC4KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gTm90IGZvdW5kLiAgUmVtb3ZlIHRoZSBuYW1lIHNvIHdlIGNhbiB0cnkgYWdhaW4uCisgICAgc2NvcGVfdG9fdHJ5LmVyYXNlKG9sZF9zaXplKTsKKyAgfQorfQorCitTeW1ib2wgRGVzY3JpcHRvckJ1aWxkZXI6Okxvb2t1cFN5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyYgcmVsYXRpdmVfdG8sCisgICAgUGxhY2Vob2xkZXJUeXBlIHBsYWNlaG9sZGVyX3R5cGUsIFJlc29sdmVNb2RlIHJlc29sdmVfbW9kZSkgeworICBTeW1ib2wgcmVzdWx0ID0gTG9va3VwU3ltYm9sTm9QbGFjZWhvbGRlcigKKyAgICAgIG5hbWUsIHJlbGF0aXZlX3RvLCByZXNvbHZlX21vZGUpOworICBpZiAocmVzdWx0LklzTnVsbCgpICYmIHBvb2xfLT5hbGxvd191bmtub3duXykgeworICAgIC8vIE5vdCBmb3VuZCwgYnV0IEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIGlzIGVuYWJsZWQuICBSZXR1cm4gYQorICAgIC8vIHBsYWNlaG9sZGVyIGluc3RlYWQuCisgICAgcmVzdWx0ID0gTmV3UGxhY2Vob2xkZXIobmFtZSwgcGxhY2Vob2xkZXJfdHlwZSk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworU3ltYm9sIERlc2NyaXB0b3JCdWlsZGVyOjpOZXdQbGFjZWhvbGRlcihjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBsYWNlaG9sZGVyVHlwZSBwbGFjZWhvbGRlcl90eXBlKSB7CisgIC8vIENvbXB1dGUgbmFtZXMuCisgIGNvbnN0IHN0cmluZyogcGxhY2Vob2xkZXJfZnVsbF9uYW1lOworICBjb25zdCBzdHJpbmcqIHBsYWNlaG9sZGVyX25hbWU7CisgIGNvbnN0IHN0cmluZyogcGxhY2Vob2xkZXJfcGFja2FnZTsKKworICBpZiAoIVZhbGlkYXRlUXVhbGlmaWVkTmFtZShuYW1lKSkgcmV0dXJuIGtOdWxsU3ltYm9sOworICBpZiAobmFtZVswXSA9PSAnLicpIHsKKyAgICAvLyBGdWxseS1xdWFsaWZpZWQuCisgICAgcGxhY2Vob2xkZXJfZnVsbF9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcobmFtZS5zdWJzdHIoMSkpOworICB9IGVsc2UgeworICAgIHBsYWNlaG9sZGVyX2Z1bGxfbmFtZSA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKG5hbWUpOworICB9CisKKyAgc3RyaW5nOjpzaXplX3R5cGUgZG90cG9zID0gcGxhY2Vob2xkZXJfZnVsbF9uYW1lLT5maW5kX2xhc3Rfb2YoJy4nKTsKKyAgaWYgKGRvdHBvcyAhPSBzdHJpbmc6Om5wb3MpIHsKKyAgICBwbGFjZWhvbGRlcl9wYWNrYWdlID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoCisgICAgICBwbGFjZWhvbGRlcl9mdWxsX25hbWUtPnN1YnN0cigwLCBkb3Rwb3MpKTsKKyAgICBwbGFjZWhvbGRlcl9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoCisgICAgICBwbGFjZWhvbGRlcl9mdWxsX25hbWUtPnN1YnN0cihkb3Rwb3MgKyAxKSk7CisgIH0gZWxzZSB7CisgICAgcGxhY2Vob2xkZXJfcGFja2FnZSA9ICZpbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgICBwbGFjZWhvbGRlcl9uYW1lID0gcGxhY2Vob2xkZXJfZnVsbF9uYW1lOworICB9CisKKyAgLy8gQ3JlYXRlIHRoZSBwbGFjZWhvbGRlcnMuCisgIEZpbGVEZXNjcmlwdG9yKiBwbGFjZWhvbGRlcl9maWxlID0gTmV3UGxhY2Vob2xkZXJGaWxlKAorICAgICAgKnBsYWNlaG9sZGVyX2Z1bGxfbmFtZSArICIucGxhY2Vob2xkZXIucHJvdG8iKTsKKyAgcGxhY2Vob2xkZXJfZmlsZS0+cGFja2FnZV8gPSBwbGFjZWhvbGRlcl9wYWNrYWdlOworCisgIGlmIChwbGFjZWhvbGRlcl90eXBlID09IFBMQUNFSE9MREVSX0VOVU0pIHsKKyAgICBwbGFjZWhvbGRlcl9maWxlLT5lbnVtX3R5cGVfY291bnRfID0gMTsKKyAgICBwbGFjZWhvbGRlcl9maWxlLT5lbnVtX3R5cGVzXyA9CisgICAgICB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PEVudW1EZXNjcmlwdG9yPigxKTsKKworICAgIEVudW1EZXNjcmlwdG9yKiBwbGFjZWhvbGRlcl9lbnVtID0gJnBsYWNlaG9sZGVyX2ZpbGUtPmVudW1fdHlwZXNfWzBdOworICAgIG1lbXNldChwbGFjZWhvbGRlcl9lbnVtLCAwLCBzaXplb2YoKnBsYWNlaG9sZGVyX2VudW0pKTsKKworICAgIHBsYWNlaG9sZGVyX2VudW0tPmZ1bGxfbmFtZV8gPSBwbGFjZWhvbGRlcl9mdWxsX25hbWU7CisgICAgcGxhY2Vob2xkZXJfZW51bS0+bmFtZV8gPSBwbGFjZWhvbGRlcl9uYW1lOworICAgIHBsYWNlaG9sZGVyX2VudW0tPmZpbGVfID0gcGxhY2Vob2xkZXJfZmlsZTsKKyAgICBwbGFjZWhvbGRlcl9lbnVtLT5vcHRpb25zXyA9ICZFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICAgIHBsYWNlaG9sZGVyX2VudW0tPmlzX3BsYWNlaG9sZGVyXyA9IHRydWU7CisgICAgcGxhY2Vob2xkZXJfZW51bS0+aXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfID0gKG5hbWVbMF0gIT0gJy4nKTsKKworICAgIC8vIEVudW1zIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgdmFsdWUuCisgICAgcGxhY2Vob2xkZXJfZW51bS0+dmFsdWVfY291bnRfID0gMTsKKyAgICBwbGFjZWhvbGRlcl9lbnVtLT52YWx1ZXNfID0gdGFibGVzXy0+QWxsb2NhdGVBcnJheTxFbnVtVmFsdWVEZXNjcmlwdG9yPigxKTsKKworICAgIEVudW1WYWx1ZURlc2NyaXB0b3IqIHBsYWNlaG9sZGVyX3ZhbHVlID0gJnBsYWNlaG9sZGVyX2VudW0tPnZhbHVlc19bMF07CisgICAgbWVtc2V0KHBsYWNlaG9sZGVyX3ZhbHVlLCAwLCBzaXplb2YoKnBsYWNlaG9sZGVyX3ZhbHVlKSk7CisKKyAgICBwbGFjZWhvbGRlcl92YWx1ZS0+bmFtZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZygiUExBQ0VIT0xERVJfVkFMVUUiKTsKKyAgICAvLyBOb3RlIHRoYXQgZW51bSB2YWx1ZSBuYW1lcyBhcmUgc2libGluZ3Mgb2YgdGhlaXIgdHlwZSwgbm90IGNoaWxkcmVuLgorICAgIHBsYWNlaG9sZGVyX3ZhbHVlLT5mdWxsX25hbWVfID0KKyAgICAgIHBsYWNlaG9sZGVyX3BhY2thZ2UtPmVtcHR5KCkgPyBwbGFjZWhvbGRlcl92YWx1ZS0+bmFtZV8gOgorICAgICAgICB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZygqcGxhY2Vob2xkZXJfcGFja2FnZSArICIuUExBQ0VIT0xERVJfVkFMVUUiKTsKKworICAgIHBsYWNlaG9sZGVyX3ZhbHVlLT5udW1iZXJfID0gMDsKKyAgICBwbGFjZWhvbGRlcl92YWx1ZS0+dHlwZV8gPSBwbGFjZWhvbGRlcl9lbnVtOworICAgIHBsYWNlaG9sZGVyX3ZhbHVlLT5vcHRpb25zXyA9ICZFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgICByZXR1cm4gU3ltYm9sKHBsYWNlaG9sZGVyX2VudW0pOworICB9IGVsc2UgeworICAgIHBsYWNlaG9sZGVyX2ZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudF8gPSAxOworICAgIHBsYWNlaG9sZGVyX2ZpbGUtPm1lc3NhZ2VfdHlwZXNfID0KKyAgICAgIHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8RGVzY3JpcHRvcj4oMSk7CisKKyAgICBEZXNjcmlwdG9yKiBwbGFjZWhvbGRlcl9tZXNzYWdlID0gJnBsYWNlaG9sZGVyX2ZpbGUtPm1lc3NhZ2VfdHlwZXNfWzBdOworICAgIG1lbXNldChwbGFjZWhvbGRlcl9tZXNzYWdlLCAwLCBzaXplb2YoKnBsYWNlaG9sZGVyX21lc3NhZ2UpKTsKKworICAgIHBsYWNlaG9sZGVyX21lc3NhZ2UtPmZ1bGxfbmFtZV8gPSBwbGFjZWhvbGRlcl9mdWxsX25hbWU7CisgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+bmFtZV8gPSBwbGFjZWhvbGRlcl9uYW1lOworICAgIHBsYWNlaG9sZGVyX21lc3NhZ2UtPmZpbGVfID0gcGxhY2Vob2xkZXJfZmlsZTsKKyAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5vcHRpb25zXyA9ICZNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICAgIHBsYWNlaG9sZGVyX21lc3NhZ2UtPmlzX3BsYWNlaG9sZGVyXyA9IHRydWU7CisgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+aXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfID0gKG5hbWVbMF0gIT0gJy4nKTsKKworICAgIGlmIChwbGFjZWhvbGRlcl90eXBlID09IFBMQUNFSE9MREVSX0VYVEVOREFCTEVfTUVTU0FHRSkgeworICAgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50XyA9IDE7CisgICAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VzXyA9CisgICAgICAgIHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8RGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2U+KDEpOworICAgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+ZXh0ZW5zaW9uX3Jhbmdlc18tPnN0YXJ0ID0gMTsKKyAgICAgIC8vIGtNYXhOdW1iZXIgKyAxIGJlY2F1c2UgRXh0ZW5zaW9uUmFuZ2U6OmVuZCBpcyBleGNsdXNpdmUuCisgICAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VzXy0+ZW5kID0KKyAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyICsgMTsKKyAgICB9CisKKyAgICByZXR1cm4gU3ltYm9sKHBsYWNlaG9sZGVyX21lc3NhZ2UpOworICB9Cit9CisKK0ZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yQnVpbGRlcjo6TmV3UGxhY2Vob2xkZXJGaWxlKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBGaWxlRGVzY3JpcHRvciogcGxhY2Vob2xkZXIgPSB0YWJsZXNfLT5BbGxvY2F0ZTxGaWxlRGVzY3JpcHRvcj4oKTsKKyAgbWVtc2V0KHBsYWNlaG9sZGVyLCAwLCBzaXplb2YoKnBsYWNlaG9sZGVyKSk7CisKKyAgcGxhY2Vob2xkZXItPm5hbWVfID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcobmFtZSk7CisgIHBsYWNlaG9sZGVyLT5wYWNrYWdlXyA9ICZpbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgcGxhY2Vob2xkZXItPnBvb2xfID0gcG9vbF87CisgIHBsYWNlaG9sZGVyLT5vcHRpb25zXyA9ICZGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICBwbGFjZWhvbGRlci0+dGFibGVzXyA9ICZGaWxlRGVzY3JpcHRvclRhYmxlczo6a0VtcHR5OworICBwbGFjZWhvbGRlci0+c291cmNlX2NvZGVfaW5mb18gPSAmU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgcGxhY2Vob2xkZXItPmlzX3BsYWNlaG9sZGVyXyA9IHRydWU7CisgIHBsYWNlaG9sZGVyLT5zeW50YXhfID0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzI7CisgIC8vIEFsbCBvdGhlciBmaWVsZHMgYXJlIHplcm8gb3IgTlVMTC4KKworICByZXR1cm4gcGxhY2Vob2xkZXI7Cit9CisKK2Jvb2wgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZFN5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwgY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgY29uc3QgTWVzc2FnZSYgcHJvdG8sIFN5bWJvbCBzeW1ib2wpIHsKKyAgLy8gSWYgdGhlIGNhbGxlciBwYXNzZWQgTlVMTCBmb3IgdGhlIHBhcmVudCwgdGhlIHN5bWJvbCBpcyBhdCBmaWxlIHNjb3BlLgorICAvLyBVc2UgaXRzIGZpbGUgYXMgdGhlIHBhcmVudCBpbnN0ZWFkLgorICBpZiAocGFyZW50ID09IE5VTEwpIHBhcmVudCA9IGZpbGVfOworCisgIGlmICh0YWJsZXNfLT5BZGRTeW1ib2woZnVsbF9uYW1lLCBzeW1ib2wpKSB7CisgICAgaWYgKCFmaWxlX3RhYmxlc18tPkFkZEFsaWFzVW5kZXJQYXJlbnQocGFyZW50LCBuYW1lLCBzeW1ib2wpKSB7CisgICAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIlwiIiA8PCBmdWxsX25hbWUgPDwgIlwiIG5vdCBwcmV2aW91c2x5IGRlZmluZWQgaW4gIgorICAgICAgICAgICAgICAgICAgICAgInN5bWJvbHNfYnlfbmFtZV8sIGJ1dCB3YXMgZGVmaW5lZCBpbiBzeW1ib2xzX2J5X3BhcmVudF87ICIKKyAgICAgICAgICAgICAgICAgICAgICJ0aGlzIHNob3VsZG4ndCBiZSBwb3NzaWJsZS4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogb3RoZXJfZmlsZSA9IHRhYmxlc18tPkZpbmRTeW1ib2woZnVsbF9uYW1lKS5HZXRGaWxlKCk7CisgICAgaWYgKG90aGVyX2ZpbGUgPT0gZmlsZV8pIHsKKyAgICAgIHN0cmluZzo6c2l6ZV90eXBlIGRvdF9wb3MgPSBmdWxsX25hbWUuZmluZF9sYXN0X29mKCcuJyk7CisgICAgICBpZiAoZG90X3BvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgICAgQWRkRXJyb3IoZnVsbF9uYW1lLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgICAiXCIiICsgZnVsbF9uYW1lICsgIlwiIGlzIGFscmVhZHkgZGVmaW5lZC4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEFkZEVycm9yKGZ1bGxfbmFtZSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAgICAgIlwiIiArIGZ1bGxfbmFtZS5zdWJzdHIoZG90X3BvcyArIDEpICsKKyAgICAgICAgICAgICAgICAgIlwiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiBcIiIgKworICAgICAgICAgICAgICAgICBmdWxsX25hbWUuc3Vic3RyKDAsIGRvdF9wb3MpICsgIlwiLiIpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBTeW1ib2wgc2VlbXMgdG8gaGF2ZSBiZWVuIGRlZmluZWQgaW4gYSBkaWZmZXJlbnQgZmlsZS4KKyAgICAgIEFkZEVycm9yKGZ1bGxfbmFtZSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAgICJcIiIgKyBmdWxsX25hbWUgKyAiXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluIGZpbGUgXCIiICsKKyAgICAgICAgICAgICAgIG90aGVyX2ZpbGUtPm5hbWUoKSArICJcIi4iKTsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZFBhY2thZ2UoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBNZXNzYWdlJiBwcm90bywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgaWYgKHRhYmxlc18tPkFkZFN5bWJvbChuYW1lLCBTeW1ib2woZmlsZSkpKSB7CisgICAgLy8gU3VjY2Vzcy4gIEFsc28gYWRkIHBhcmVudCBwYWNrYWdlLCBpZiBhbnkuCisgICAgc3RyaW5nOjpzaXplX3R5cGUgZG90X3BvcyA9IG5hbWUuZmluZF9sYXN0X29mKCcuJyk7CisgICAgaWYgKGRvdF9wb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICAvLyBObyBwYXJlbnRzLgorICAgICAgVmFsaWRhdGVTeW1ib2xOYW1lKG5hbWUsIG5hbWUsIHByb3RvKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gSGFzIHBhcmVudC4KKyAgICAgIHN0cmluZyogcGFyZW50X25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhuYW1lLnN1YnN0cigwLCBkb3RfcG9zKSk7CisgICAgICBBZGRQYWNrYWdlKCpwYXJlbnRfbmFtZSwgcHJvdG8sIGZpbGUpOworICAgICAgVmFsaWRhdGVTeW1ib2xOYW1lKG5hbWUuc3Vic3RyKGRvdF9wb3MgKyAxKSwgbmFtZSwgcHJvdG8pOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBTeW1ib2wgZXhpc3Rpbmdfc3ltYm9sID0gdGFibGVzXy0+RmluZFN5bWJvbChuYW1lKTsKKyAgICAvLyBJdCdzIE9LIHRvIHJlZGVmaW5lIGEgcGFja2FnZS4KKyAgICBpZiAoZXhpc3Rpbmdfc3ltYm9sLnR5cGUgIT0gU3ltYm9sOjpQQUNLQUdFKSB7CisgICAgICAvLyBTeW1ib2wgc2VlbXMgdG8gaGF2ZSBiZWVuIGRlZmluZWQgaW4gYSBkaWZmZXJlbnQgZmlsZS4KKyAgICAgIEFkZEVycm9yKG5hbWUsIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiXCIiICsgbmFtZSArICJcIiBpcyBhbHJlYWR5IGRlZmluZWQgKGFzIHNvbWV0aGluZyBvdGhlciB0aGFuICIKKyAgICAgICAgICAgICAgICJhIHBhY2thZ2UpIGluIGZpbGUgXCIiICsgZXhpc3Rpbmdfc3ltYm9sLkdldEZpbGUoKS0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICJcIi4iKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVTeW1ib2xOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsIGNvbnN0IE1lc3NhZ2UmIHByb3RvKSB7CisgIGlmIChuYW1lLmVtcHR5KCkpIHsKKyAgICBBZGRFcnJvcihmdWxsX25hbWUsIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgIk1pc3NpbmcgbmFtZS4iKTsKKyAgfSBlbHNlIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWUuc2l6ZSgpOyBpKyspIHsKKyAgICAgIC8vIEkgZG9uJ3QgdHJ1c3QgaXNhbG51bSgpIGR1ZSB0byBsb2NhbGVzLiAgOigKKyAgICAgIGlmICgobmFtZVtpXSA8ICdhJyB8fCAneicgPCBuYW1lW2ldKSAmJgorICAgICAgICAgIChuYW1lW2ldIDwgJ0EnIHx8ICdaJyA8IG5hbWVbaV0pICYmCisgICAgICAgICAgKG5hbWVbaV0gPCAnMCcgfHwgJzknIDwgbmFtZVtpXSkgJiYKKyAgICAgICAgICAobmFtZVtpXSAhPSAnXycpKSB7CisgICAgICAgIEFkZEVycm9yKGZ1bGxfbmFtZSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAgICAgIlwiIiArIG5hbWUgKyAiXCIgaXMgbm90IGEgdmFsaWQgaWRlbnRpZmllci4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVRdWFsaWZpZWROYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBib29sIGxhc3Rfd2FzX3BlcmlvZCA9IGZhbHNlOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZS5zaXplKCk7IGkrKykgeworICAgIC8vIEkgZG9uJ3QgdHJ1c3QgaXNhbG51bSgpIGR1ZSB0byBsb2NhbGVzLiAgOigKKyAgICBpZiAoKCdhJyA8PSBuYW1lW2ldICYmIG5hbWVbaV0gPD0gJ3onKSB8fAorICAgICAgICAoJ0EnIDw9IG5hbWVbaV0gJiYgbmFtZVtpXSA8PSAnWicpIHx8CisgICAgICAgICgnMCcgPD0gbmFtZVtpXSAmJiBuYW1lW2ldIDw9ICc5JykgfHwKKyAgICAgICAgKG5hbWVbaV0gPT0gJ18nKSkgeworICAgICAgbGFzdF93YXNfcGVyaW9kID0gZmFsc2U7CisgICAgfSBlbHNlIGlmIChuYW1lW2ldID09ICcuJykgeworICAgICAgaWYgKGxhc3Rfd2FzX3BlcmlvZCkgcmV0dXJuIGZhbHNlOworICAgICAgbGFzdF93YXNfcGVyaW9kID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHJldHVybiAhbmFtZS5lbXB0eSgpICYmICFsYXN0X3dhc19wZXJpb2Q7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gVGhpcyBnZW5lcmljIGltcGxlbWVudGF0aW9uIGlzIGdvb2QgZm9yIGFsbCBkZXNjcmlwdG9ycyBleGNlcHQKKy8vIEZpbGVEZXNjcmlwdG9yLgordGVtcGxhdGU8Y2xhc3MgRGVzY3JpcHRvclQ+IHZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFsbG9jYXRlT3B0aW9ucygKKyAgICBjb25zdCB0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGUmIG9yaWdfb3B0aW9ucywKKyAgICBEZXNjcmlwdG9yVCogZGVzY3JpcHRvcikgeworICBBbGxvY2F0ZU9wdGlvbnNJbXBsKGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBvcmlnX29wdGlvbnMsIGRlc2NyaXB0b3IpOworfQorCisvLyBXZSBzcGVjaWFsaXplIGZvciBGaWxlRGVzY3JpcHRvci4KK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFsbG9jYXRlT3B0aW9ucyhjb25zdCBGaWxlT3B0aW9ucyYgb3JpZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIC8vIFdlIGFkZCB0aGUgZHVtbXkgdG9rZW4gc28gdGhhdCBMb29rdXBTeW1ib2wgZG9lcyB0aGUgcmlnaHQgdGhpbmcuCisgIEFsbG9jYXRlT3B0aW9uc0ltcGwoZGVzY3JpcHRvci0+cGFja2FnZSgpICsgIi5kdW1teSIsIGRlc2NyaXB0b3ItPm5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBvcmlnX29wdGlvbnMsIGRlc2NyaXB0b3IpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBEZXNjcmlwdG9yVD4gdm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWxsb2NhdGVPcHRpb25zSW1wbCgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWVfc2NvcGUsCisgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgY29uc3QgdHlwZW5hbWUgRGVzY3JpcHRvclQ6Ok9wdGlvbnNUeXBlJiBvcmlnX29wdGlvbnMsCisgICAgRGVzY3JpcHRvclQqIGRlc2NyaXB0b3IpIHsKKyAgLy8gV2UgbmVlZCB0byB1c2UgYSBkdW1teSBwb2ludGVyIHRvIHdvcmsgYXJvdW5kIGEgYnVnIGluIG9sZGVyIHZlcnNpb25zIG9mCisgIC8vIEdDQy4gIE90aGVyd2lzZSwgdGhlIGZvbGxvd2luZyB0d28gbGluZXMgY291bGQgYmUgcmVwbGFjZWQgd2l0aDoKKyAgLy8gICB0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGUqIG9wdGlvbnMgPQorICAvLyAgICAgICB0YWJsZXNfLT5BbGxvY2F0ZU1lc3NhZ2U8dHlwZW5hbWUgRGVzY3JpcHRvclQ6Ok9wdGlvbnNUeXBlPigpOworICB0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGUqIGNvbnN0IGR1bW15ID0gTlVMTDsKKyAgdHlwZW5hbWUgRGVzY3JpcHRvclQ6Ok9wdGlvbnNUeXBlKiBvcHRpb25zID0gdGFibGVzXy0+QWxsb2NhdGVNZXNzYWdlKGR1bW15KTsKKyAgLy8gQXZvaWQgdXNpbmcgTWVyZ2VGcm9tKCkvQ29weUZyb20oKSBpbiB0aGlzIGNsYXNzIHRvIG1ha2UgaXQgLWZuby1ydHRpCisgIC8vIGZyaWVuZGx5LiBXaXRob3V0IFJUVEksIE1lcmdlRnJvbSgpIGFuZCBDb3B5RnJvbSgpIHdpbGwgZmFsbGJhY2sgdG8gdGhlCisgIC8vIHJlZmxlY3Rpb24gYmFzZWQgbWV0aG9kLCB3aGljaCByZXF1aXJlcyB0aGUgRGVzY3JpcHRvci4gSG93ZXZlciwgd2UgYXJlIGluCisgIC8vIHRoZSBtaWRkbGUgb2YgYnVpbGRpbmcgdGhlIGRlc2NyaXB0b3JzLCB0aHVzIHRoZSBkZWFkbG9jay4KKyAgb3B0aW9ucy0+UGFyc2VGcm9tU3RyaW5nKG9yaWdfb3B0aW9ucy5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgZGVzY3JpcHRvci0+b3B0aW9uc18gPSBvcHRpb25zOworCisgIC8vIERvbid0IGFkZCB0byBvcHRpb25zX3RvX2ludGVycHJldF8gdW5sZXNzIHRoZXJlIHdlcmUgdW5pbnRlcnByZXRlZAorICAvLyBvcHRpb25zLiAgVGhpcyBub3Qgb25seSBhdm9pZHMgdW5uZWNlc3Nhcnkgd29yaywgYnV0IHByZXZlbnRzIGEKKyAgLy8gYm9vdHN0cmFwcGluZyBwcm9ibGVtIHdoZW4gYnVpbGRpbmcgZGVzY3JpcHRvcnMgZm9yIGRlc2NyaXB0b3IucHJvdG8uCisgIC8vIGRlc2NyaXB0b3IucHJvdG8gZG9lcyBub3QgY29udGFpbiBhbnkgdW5pbnRlcnByZXRlZCBvcHRpb25zLCBidXQKKyAgLy8gYXR0ZW1wdGluZyB0byBpbnRlcnByZXQgb3B0aW9ucyBhbnl3YXkgd2lsbCBjYXVzZQorICAvLyBPcHRpb25zVHlwZTo6R2V0RGVzY3JpcHRvcigpIHRvIGJlIGNhbGxlZCB3aGljaCBtYXkgdGhlbiBkZWFkbG9jayBzaW5jZQorICAvLyB3ZSdyZSBzdGlsbCB0cnlpbmcgdG8gYnVpbGQgaXQuCisgIGlmIChvcHRpb25zLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgPiAwKSB7CisgICAgb3B0aW9uc190b19pbnRlcnByZXRfLnB1c2hfYmFjaygKKyAgICAgICAgT3B0aW9uc1RvSW50ZXJwcmV0KG5hbWVfc2NvcGUsIGVsZW1lbnRfbmFtZSwgJm9yaWdfb3B0aW9ucywgb3B0aW9ucykpOworICB9Cit9CisKKworLy8gQSBjb21tb24gcGF0dGVybjogIFdlIHdhbnQgdG8gY29udmVydCBhIHJlcGVhdGVkIGZpZWxkIGluIHRoZSBkZXNjcmlwdG9yCisvLyB0byBhbiBhcnJheSBvZiB2YWx1ZXMsIGNhbGxpbmcgc29tZSBtZXRob2QgdG8gYnVpbGQgZWFjaCB2YWx1ZS4KKyNkZWZpbmUgQlVJTERfQVJSQVkoSU5QVVQsIE9VVFBVVCwgTkFNRSwgTUVUSE9ELCBQQVJFTlQpICAgICAgICAgICAgIFwKKyAgT1VUUFVULT5OQU1FIyNfY291bnRfID0gSU5QVVQuTkFNRSMjX3NpemUoKTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgQWxsb2NhdGVBcnJheShJTlBVVC5OQU1FIyNfc2l6ZSgpLCAmT1VUUFVULT5OQU1FIyNzXyk7ICAgICAgICAgICAgIFwKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBJTlBVVC5OQU1FIyNfc2l6ZSgpOyBpKyspIHsgICAgICAgICAgICAgICAgICAgIFwKKyAgICBNRVRIT0QoSU5QVVQuTkFNRShpKSwgUEFSRU5ULCBPVVRQVVQtPk5BTUUjI3NfICsgaSk7ICAgICAgICAgICAgIFwKKyAgfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpBZGRSZWN1cnNpdmVJbXBvcnRFcnJvcigKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywgaW50IGZyb21faGVyZSkgeworICBzdHJpbmcgZXJyb3JfbWVzc2FnZSgiRmlsZSByZWN1cnNpdmVseSBpbXBvcnRzIGl0c2VsZjogIik7CisgIGZvciAoaW50IGkgPSBmcm9tX2hlcmU7IGkgPCB0YWJsZXNfLT5wZW5kaW5nX2ZpbGVzXy5zaXplKCk7IGkrKykgeworICAgIGVycm9yX21lc3NhZ2UuYXBwZW5kKHRhYmxlc18tPnBlbmRpbmdfZmlsZXNfW2ldKTsKKyAgICBlcnJvcl9tZXNzYWdlLmFwcGVuZCgiIC0+ICIpOworICB9CisgIGVycm9yX21lc3NhZ2UuYXBwZW5kKHByb3RvLm5hbWUoKSk7CisKKyAgQWRkRXJyb3IocHJvdG8ubmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgZXJyb3JfbWVzc2FnZSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZFR3aWNlTGlzdGVkRXJyb3IoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgeworICBBZGRFcnJvcihwcm90by5uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAiSW1wb3J0IFwiIiArIHByb3RvLmRlcGVuZGVuY3koaW5kZXgpICsgIlwiIHdhcyBsaXN0ZWQgdHdpY2UuIik7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZEltcG9ydEVycm9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgIHN0cmluZyBtZXNzYWdlOworICBpZiAocG9vbF8tPmZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKSB7CisgICAgbWVzc2FnZSA9ICJJbXBvcnQgXCIiICsgcHJvdG8uZGVwZW5kZW5jeShpbmRleCkgKworICAgICAgICAgICAgICAiXCIgaGFzIG5vdCBiZWVuIGxvYWRlZC4iOworICB9IGVsc2UgeworICAgIG1lc3NhZ2UgPSAiSW1wb3J0IFwiIiArIHByb3RvLmRlcGVuZGVuY3koaW5kZXgpICsKKyAgICAgICAgICAgICAgIlwiIHdhcyBub3QgZm91bmQgb3IgaGFkIGVycm9ycy4iOworICB9CisgIEFkZEVycm9yKHByb3RvLm5hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsIG1lc3NhZ2UpOworfQorCitzdGF0aWMgYm9vbCBFeGlzdGluZ0ZpbGVNYXRjaGVzUHJvdG8oY29uc3QgRmlsZURlc2NyaXB0b3IqIGV4aXN0aW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBleGlzdGluZ19wcm90bzsKKyAgZXhpc3RpbmdfZmlsZS0+Q29weVRvKCZleGlzdGluZ19wcm90byk7CisgIHJldHVybiBleGlzdGluZ19wcm90by5TZXJpYWxpemVBc1N0cmluZygpID09IHByb3RvLlNlcmlhbGl6ZUFzU3RyaW5nKCk7Cit9CisKK2NvbnN0IEZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRGaWxlKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGZpbGVuYW1lXyA9IHByb3RvLm5hbWUoKTsKKworICAvLyBDaGVjayBpZiB0aGUgZmlsZSBhbHJlYWR5IGV4aXN0cyBhbmQgaXMgaWRlbnRpY2FsIHRvIHRoZSBvbmUgYmVpbmcgYnVpbHQuCisgIC8vIE5vdGU6ICBUaGlzIG9ubHkgd29ya3MgaWYgdGhlIGlucHV0IGlzIGNhbm9uaWNhbCAtLSB0aGF0IGlzLCBpdAorICAvLyAgIGZ1bGx5LXF1YWxpZmllcyBhbGwgdHlwZSBuYW1lcywgaGFzIG5vIFVuaW50ZXJwcmV0ZWRPcHRpb25zLCBldGMuCisgIC8vICAgVGhpcyBpcyBmaW5lLCBiZWNhdXNlIHRoaXMgaWRlbXBvdGVuY3kgImZlYXR1cmUiIHJlYWxseSBvbmx5IGV4aXN0cyB0bworICAvLyAgIGFjY29tbW9kYXRlIG9uZSBoYWNrIGluIHRoZSBwcm90bzEtPnByb3RvMiBtaWdyYXRpb24gbGF5ZXIuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBleGlzdGluZ19maWxlID0gdGFibGVzXy0+RmluZEZpbGUoZmlsZW5hbWVfKTsKKyAgaWYgKGV4aXN0aW5nX2ZpbGUgIT0gTlVMTCkgeworICAgIC8vIEZpbGUgYWxyZWFkeSBpbiBwb29sLiAgQ29tcGFyZSB0aGUgZXhpc3Rpbmcgb25lIHRvIHRoZSBpbnB1dC4KKyAgICBpZiAoRXhpc3RpbmdGaWxlTWF0Y2hlc1Byb3RvKGV4aXN0aW5nX2ZpbGUsIHByb3RvKSkgeworICAgICAgLy8gVGhleSdyZSBpZGVudGljYWwuICBSZXR1cm4gdGhlIGV4aXN0aW5nIGRlc2NyaXB0b3IuCisgICAgICByZXR1cm4gZXhpc3RpbmdfZmlsZTsKKyAgICB9CisKKyAgICAvLyBOb3QgYSBtYXRjaC4gIFRoZSBlcnJvciB3aWxsIGJlIGRldGVjdGVkIGFuZCBoYW5kbGVkIGxhdGVyLgorICB9CisKKyAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoaXMgZmlsZSBpcyBhbHJlYWR5IG9uIHRoZSBwZW5kaW5nIGZpbGVzIGxpc3QuCisgIC8vIFRPRE8oa2VudG9uKTogIEFsbG93IHJlY3Vyc2l2ZSBpbXBvcnRzPyAgSXQgbWF5IG5vdCB3b3JrIHdpdGggc29tZQorICAvLyAgIChtb3N0PykgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLiAgRS5nLiwgaW4gQysrLCBhIGZvcndhcmQgZGVjbGFyYXRpb24KKyAgLy8gICBvZiBhIHR5cGUgaXMgbm90IHN1ZmZpY2llbnQgdG8gYWxsb3cgaXQgdG8gYmUgdXNlZCBldmVuIGluIGEKKyAgLy8gICBnZW5lcmF0ZWQgaGVhZGVyIGZpbGUgZHVlIHRvIGlubGluaW5nLiAgVGhpcyBjb3VsZCBwZXJoYXBzIGJlCisgIC8vICAgd29ya2VkIGFyb3VuZCB1c2luZyB0cmlja3MgaW52b2x2aW5nIGluc2VydGluZyAjaW5jbHVkZSBzdGF0ZW1lbnRzCisgIC8vICAgbWlkLWZpbGUsIGJ1dCB0aGF0J3MgcHJldHR5IHVnbHksIGFuZCBJJ20gcHJldHR5IHN1cmUgdGhlcmUgYXJlCisgIC8vICAgc29tZSBsYW5ndWFnZXMgb3V0IHRoZXJlIHRoYXQgZG8gbm90IGFsbG93IHJlY3Vyc2l2ZSBkZXBlbmRlbmNpZXMKKyAgLy8gICBhdCBhbGwuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVzXy0+cGVuZGluZ19maWxlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAodGFibGVzXy0+cGVuZGluZ19maWxlc19baV0gPT0gcHJvdG8ubmFtZSgpKSB7CisgICAgICBBZGRSZWN1cnNpdmVJbXBvcnRFcnJvcihwcm90bywgaSk7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgIH0KKworICAvLyBJZiB3ZSBoYXZlIGEgZmFsbGJhY2tfZGF0YWJhc2VfLCBhdHRlbXB0IHRvIGxvYWQgYWxsIGRlcGVuZGVuY2llcyBub3csCisgIC8vIGJlZm9yZSBjaGVja3BvaW50aW5nIHRhYmxlc18uICBUaGlzIGF2b2lkcyBjb25mdXNpb24gd2l0aCByZWN1cnNpdmUKKyAgLy8gY2hlY2twb2ludHMuCisgIGlmIChwb29sXy0+ZmFsbGJhY2tfZGF0YWJhc2VfICE9IE5VTEwpIHsKKyAgICB0YWJsZXNfLT5wZW5kaW5nX2ZpbGVzXy5wdXNoX2JhY2socHJvdG8ubmFtZSgpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmRlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICAgIGlmICh0YWJsZXNfLT5GaW5kRmlsZShwcm90by5kZXBlbmRlbmN5KGkpKSA9PSBOVUxMICYmCisgICAgICAgICAgKHBvb2xfLT51bmRlcmxheV8gPT0gTlVMTCB8fAorICAgICAgICAgICBwb29sXy0+dW5kZXJsYXlfLT5GaW5kRmlsZUJ5TmFtZShwcm90by5kZXBlbmRlbmN5KGkpKSA9PSBOVUxMKSkgeworICAgICAgICAvLyBXZSBkb24ndCBjYXJlIHdoYXQgdGhpcyByZXR1cm5zIHNpbmNlIHdlJ2xsIGZpbmQgb3V0IGJlbG93IGFueXdheS4KKyAgICAgICAgcG9vbF8tPlRyeUZpbmRGaWxlSW5GYWxsYmFja0RhdGFiYXNlKHByb3RvLmRlcGVuZGVuY3koaSkpOworICAgICAgfQorICAgIH0KKyAgICB0YWJsZXNfLT5wZW5kaW5nX2ZpbGVzXy5wb3BfYmFjaygpOworICB9CisKKyAgLy8gQ2hlY2twb2ludCB0aGUgdGFibGVzIHNvIHRoYXQgd2UgY2FuIHJvbGwgYmFjayBpZiBzb21ldGhpbmcgZ29lcyB3cm9uZy4KKyAgdGFibGVzXy0+QWRkQ2hlY2twb2ludCgpOworCisgIEZpbGVEZXNjcmlwdG9yKiByZXN1bHQgPSB0YWJsZXNfLT5BbGxvY2F0ZTxGaWxlRGVzY3JpcHRvcj4oKTsKKyAgZmlsZV8gPSByZXN1bHQ7CisKKyAgcmVzdWx0LT5pc19wbGFjZWhvbGRlcl8gPSBmYWxzZTsKKyAgaWYgKHByb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpIHsKKyAgICBTb3VyY2VDb2RlSW5mbyAqaW5mbyA9IHRhYmxlc18tPkFsbG9jYXRlTWVzc2FnZTxTb3VyY2VDb2RlSW5mbz4oKTsKKyAgICBpbmZvLT5Db3B5RnJvbShwcm90by5zb3VyY2VfY29kZV9pbmZvKCkpOworICAgIHJlc3VsdC0+c291cmNlX2NvZGVfaW5mb18gPSBpbmZvOworICB9IGVsc2UgeworICAgIHJlc3VsdC0+c291cmNlX2NvZGVfaW5mb18gPSAmU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgfQorCisgIGZpbGVfdGFibGVzXyA9IHRhYmxlc18tPkFsbG9jYXRlRmlsZVRhYmxlcygpOworICBmaWxlXy0+dGFibGVzXyA9IGZpbGVfdGFibGVzXzsKKworICBpZiAoIXByb3RvLmhhc19uYW1lKCkpIHsKKyAgICBBZGRFcnJvcigiIiwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgIk1pc3NpbmcgZmllbGQ6IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZS4iKTsKKyAgfQorCisgIC8vIFRPRE8obGl1amlzaSk6IFJlcG9ydCBlcnJvciB3aGVuIHRoZSBzeW50YXggaXMgZW1wdHkgYWZ0ZXIgYWxsIHRoZSBwcm90b3MKKyAgLy8gaGF2ZSBhZGRlZCB0aGUgc3ludGF4IHN0YXRlbWVudC4KKyAgaWYgKHByb3RvLnN5bnRheCgpLmVtcHR5KCkgfHwgcHJvdG8uc3ludGF4KCkgPT0gInByb3RvMiIpIHsKKyAgICBmaWxlXy0+c3ludGF4XyA9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8yOworICB9IGVsc2UgaWYgKHByb3RvLnN5bnRheCgpID09ICJwcm90bzMiKSB7CisgICAgZmlsZV8tPnN5bnRheF8gPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKKyAgfSBlbHNlIHsKKyAgICBmaWxlXy0+c3ludGF4XyA9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfVU5LTk9XTjsKKyAgICBBZGRFcnJvcihwcm90by5uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICJVbnJlY29nbml6ZWQgc3ludGF4OiAiICsgcHJvdG8uc3ludGF4KCkpOworICB9CisKKyAgcmVzdWx0LT5uYW1lXyA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLm5hbWUoKSk7CisgIGlmIChwcm90by5oYXNfcGFja2FnZSgpKSB7CisgICAgcmVzdWx0LT5wYWNrYWdlXyA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLnBhY2thZ2UoKSk7CisgIH0gZWxzZSB7CisgICAgLy8gV2UgY2Fubm90IHJlbHkgb24gcHJvdG8ucGFja2FnZSgpIHJldHVybmluZyBhIHZhbGlkIHN0cmluZyBpZgorICAgIC8vIHByb3RvLmhhc19wYWNrYWdlKCkgaXMgZmFsc2UsIGJlY2F1c2Ugd2UgbWlnaHQgYmUgcnVubmluZyBhdCBzdGF0aWMKKyAgICAvLyBpbml0aWFsaXphdGlvbiB0aW1lLCBpbiB3aGljaCBjYXNlIGRlZmF1bHQgdmFsdWVzIGhhdmUgbm90IHlldCBiZWVuCisgICAgLy8gaW5pdGlhbGl6ZWQuCisgICAgcmVzdWx0LT5wYWNrYWdlXyA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKCIiKTsKKyAgfQorICByZXN1bHQtPnBvb2xfID0gcG9vbF87CisKKyAgLy8gQWRkIHRvIHRhYmxlcy4KKyAgaWYgKCF0YWJsZXNfLT5BZGRGaWxlKHJlc3VsdCkpIHsKKyAgICBBZGRFcnJvcihwcm90by5uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICJBIGZpbGUgd2l0aCB0aGlzIG5hbWUgaXMgYWxyZWFkeSBpbiB0aGUgcG9vbC4iKTsKKyAgICAvLyBCYWlsIG91dCBlYXJseSBzbyB0aGF0IGlmIHRoaXMgaXMgYWN0dWFsbHkgdGhlIGV4YWN0IHNhbWUgZmlsZSwgd2UKKyAgICAvLyBkb24ndCBlbmQgdXAgcmVwb3J0aW5nIHRoYXQgZXZlcnkgc2luZ2xlIHN5bWJvbCBpcyBhbHJlYWR5IGRlZmluZWQuCisgICAgdGFibGVzXy0+Um9sbGJhY2tUb0xhc3RDaGVja3BvaW50KCk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaWYgKCFyZXN1bHQtPnBhY2thZ2UoKS5lbXB0eSgpKSB7CisgICAgQWRkUGFja2FnZShyZXN1bHQtPnBhY2thZ2UoKSwgcHJvdG8sIHJlc3VsdCk7CisgIH0KKworICAvLyBNYWtlIHN1cmUgYWxsIGRlcGVuZGVuY2llcyBhcmUgbG9hZGVkLgorICBzZXQ8c3RyaW5nPiBzZWVuX2RlcGVuZGVuY2llczsKKyAgcmVzdWx0LT5kZXBlbmRlbmN5X2NvdW50XyA9IHByb3RvLmRlcGVuZGVuY3lfc2l6ZSgpOworICByZXN1bHQtPmRlcGVuZGVuY2llc18gPQorICAgIHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8Y29uc3QgRmlsZURlc2NyaXB0b3IqPihwcm90by5kZXBlbmRlbmN5X3NpemUoKSk7CisgIHVudXNlZF9kZXBlbmRlbmN5Xy5jbGVhcigpOworICBzZXQ8aW50PiB3ZWFrX2RlcHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ud2Vha19kZXBlbmRlbmN5X3NpemUoKTsgKytpKSB7CisgICAgd2Vha19kZXBzLmluc2VydChwcm90by53ZWFrX2RlcGVuZGVuY3koaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8uZGVwZW5kZW5jeV9zaXplKCk7IGkrKykgeworICAgIGlmICghc2Vlbl9kZXBlbmRlbmNpZXMuaW5zZXJ0KHByb3RvLmRlcGVuZGVuY3koaSkpLnNlY29uZCkgeworICAgICAgQWRkVHdpY2VMaXN0ZWRFcnJvcihwcm90bywgaSk7CisgICAgfQorCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlcGVuZGVuY3kgPSB0YWJsZXNfLT5GaW5kRmlsZShwcm90by5kZXBlbmRlbmN5KGkpKTsKKyAgICBpZiAoZGVwZW5kZW5jeSA9PSBOVUxMICYmIHBvb2xfLT51bmRlcmxheV8gIT0gTlVMTCkgeworICAgICAgZGVwZW5kZW5jeSA9IHBvb2xfLT51bmRlcmxheV8tPkZpbmRGaWxlQnlOYW1lKHByb3RvLmRlcGVuZGVuY3koaSkpOworICAgIH0KKworICAgIGlmIChkZXBlbmRlbmN5ID09IE5VTEwpIHsKKyAgICAgIGlmIChwb29sXy0+YWxsb3dfdW5rbm93bl8gfHwKKyAgICAgICAgICAoIXBvb2xfLT5lbmZvcmNlX3dlYWtfICYmIHdlYWtfZGVwcy5maW5kKGkpICE9IHdlYWtfZGVwcy5lbmQoKSkpIHsKKyAgICAgICAgZGVwZW5kZW5jeSA9IE5ld1BsYWNlaG9sZGVyRmlsZShwcm90by5kZXBlbmRlbmN5KGkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEFkZEltcG9ydEVycm9yKHByb3RvLCBpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gQWRkIHRvIHVudXNlZF9kZXBlbmRlbmN5XyB0byB0cmFjayB1bnVzZWQgaW1wb3J0ZWQgZmlsZXMuCisgICAgICAvLyBOb3RlOiBkbyBub3QgdHJhY2sgdW51c2VkIGltcG9ydGVkIGZpbGVzIGZvciBwdWJsaWMgaW1wb3J0LgorICAgICAgaWYgKHBvb2xfLT5lbmZvcmNlX2RlcGVuZGVuY2llc18gJiYKKyAgICAgICAgICAocG9vbF8tPnVudXNlZF9pbXBvcnRfdHJhY2tfZmlsZXNfLmZpbmQocHJvdG8ubmFtZSgpKSAhPQorICAgICAgICAgICBwb29sXy0+dW51c2VkX2ltcG9ydF90cmFja19maWxlc18uZW5kKCkpICYmCisgICAgICAgICAgKGRlcGVuZGVuY3ktPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCkgPT0gMCkpIHsKKyAgICAgICAgdW51c2VkX2RlcGVuZGVuY3lfLmluc2VydChkZXBlbmRlbmN5KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXN1bHQtPmRlcGVuZGVuY2llc19baV0gPSBkZXBlbmRlbmN5OworICB9CisKKyAgLy8gQ2hlY2sgcHVibGljIGRlcGVuZGVuY2llcy4KKyAgaW50IHB1YmxpY19kZXBlbmRlbmN5X2NvdW50ID0gMDsKKyAgcmVzdWx0LT5wdWJsaWNfZGVwZW5kZW5jaWVzXyA9IHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8aW50PigKKyAgICAgIHByb3RvLnB1YmxpY19kZXBlbmRlbmN5X3NpemUoKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ucHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICAvLyBPbmx5IHB1dCB2YWxpZCBwdWJsaWMgZGVwZW5kZW5jeSBpbmRleGVzLgorICAgIGludCBpbmRleCA9IHByb3RvLnB1YmxpY19kZXBlbmRlbmN5KGkpOworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgcHJvdG8uZGVwZW5kZW5jeV9zaXplKCkpIHsKKyAgICAgIHJlc3VsdC0+cHVibGljX2RlcGVuZGVuY2llc19bcHVibGljX2RlcGVuZGVuY3lfY291bnQrK10gPSBpbmRleDsKKyAgICAgIC8vIERvIG5vdCB0cmFjayB1bnVzZWQgaW1wb3J0ZWQgZmlsZXMgZm9yIHB1YmxpYyBpbXBvcnQuCisgICAgICB1bnVzZWRfZGVwZW5kZW5jeV8uZXJhc2UocmVzdWx0LT5kZXBlbmRlbmN5KGluZGV4KSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEFkZEVycm9yKHByb3RvLm5hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICAgIkludmFsaWQgcHVibGljIGRlcGVuZGVuY3kgaW5kZXguIik7CisgICAgfQorICB9CisgIHJlc3VsdC0+cHVibGljX2RlcGVuZGVuY3lfY291bnRfID0gcHVibGljX2RlcGVuZGVuY3lfY291bnQ7CisKKyAgLy8gQnVpbGQgZGVwZW5kZW5jeSBzZXQKKyAgZGVwZW5kZW5jaWVzXy5jbGVhcigpOworICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBSZWNvcmRQdWJsaWNEZXBlbmRlbmNpZXMocmVzdWx0LT5kZXBlbmRlbmN5KGkpKTsKKyAgfQorCisgIC8vIENoZWNrIHdlYWsgZGVwZW5kZW5jaWVzLgorICBpbnQgd2Vha19kZXBlbmRlbmN5X2NvdW50ID0gMDsKKyAgcmVzdWx0LT53ZWFrX2RlcGVuZGVuY2llc18gPSB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PGludD4oCisgICAgICBwcm90by53ZWFrX2RlcGVuZGVuY3lfc2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by53ZWFrX2RlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICBpbnQgaW5kZXggPSBwcm90by53ZWFrX2RlcGVuZGVuY3koaSk7CisgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBwcm90by5kZXBlbmRlbmN5X3NpemUoKSkgeworICAgICAgcmVzdWx0LT53ZWFrX2RlcGVuZGVuY2llc19bd2Vha19kZXBlbmRlbmN5X2NvdW50KytdID0gaW5kZXg7CisgICAgfSBlbHNlIHsKKyAgICAgIEFkZEVycm9yKHByb3RvLm5hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICAgIkludmFsaWQgd2VhayBkZXBlbmRlbmN5IGluZGV4LiIpOworICAgIH0KKyAgfQorICByZXN1bHQtPndlYWtfZGVwZW5kZW5jeV9jb3VudF8gPSB3ZWFrX2RlcGVuZGVuY3lfY291bnQ7CisKKyAgLy8gQ29udmVydCBjaGlsZHJlbi4KKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgbWVzc2FnZV90eXBlLCBCdWlsZE1lc3NhZ2UgICwgTlVMTCk7CisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIGVudW1fdHlwZSAgICwgQnVpbGRFbnVtICAgICAsIE5VTEwpOworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBzZXJ2aWNlICAgICAsIEJ1aWxkU2VydmljZSAgLCBOVUxMKTsKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgZXh0ZW5zaW9uICAgLCBCdWlsZEV4dGVuc2lvbiwgTlVMTCk7CisKKyAgLy8gQ29weSBvcHRpb25zLgorICBpZiAoIXByb3RvLmhhc19vcHRpb25zKCkpIHsKKyAgICByZXN1bHQtPm9wdGlvbnNfID0gTlVMTDsgIC8vIFdpbGwgc2V0IHRvIGRlZmF1bHRfaW5zdGFuY2UgbGF0ZXIuCisgIH0gZWxzZSB7CisgICAgQWxsb2NhdGVPcHRpb25zKHByb3RvLm9wdGlvbnMoKSwgcmVzdWx0KTsKKyAgfQorCisgIC8vIE5vdGUgdGhhdCB0aGUgZm9sbG93aW5nIHN0ZXBzIG11c3Qgb2NjdXIgaW4gZXhhY3RseSB0aGUgc3BlY2lmaWVkIG9yZGVyLgorCisgIC8vIENyb3NzLWxpbmsuCisgIENyb3NzTGlua0ZpbGUocmVzdWx0LCBwcm90byk7CisKKyAgLy8gSW50ZXJwcmV0IGFueSByZW1haW5pbmcgdW5pbnRlcnByZXRlZCBvcHRpb25zIGdhdGhlcmVkIGludG8KKyAgLy8gb3B0aW9uc190b19pbnRlcnByZXRfIGR1cmluZyBkZXNjcmlwdG9yIGJ1aWxkaW5nLiAgQ3Jvc3MtbGlua2luZyBoYXMgbWFkZQorICAvLyBleHRlbnNpb24gb3B0aW9ucyBrbm93biwgc28gYWxsIGludGVycHJldGF0aW9ucyBzaG91bGQgbm93IHN1Y2NlZWQuCisgIGlmICghaGFkX2Vycm9yc18pIHsKKyAgICBPcHRpb25JbnRlcnByZXRlciBvcHRpb25faW50ZXJwcmV0ZXIodGhpcyk7CisgICAgZm9yICh2ZWN0b3I8T3B0aW9uc1RvSW50ZXJwcmV0Pjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgICAgICAgb3B0aW9uc190b19pbnRlcnByZXRfLmJlZ2luKCk7CisgICAgICAgICBpdGVyICE9IG9wdGlvbnNfdG9faW50ZXJwcmV0Xy5lbmQoKTsgKytpdGVyKSB7CisgICAgICBvcHRpb25faW50ZXJwcmV0ZXIuSW50ZXJwcmV0T3B0aW9ucygmKCppdGVyKSk7CisgICAgfQorICAgIG9wdGlvbnNfdG9faW50ZXJwcmV0Xy5jbGVhcigpOworICB9CisKKyAgLy8gVmFsaWRhdGUgb3B0aW9ucy4KKyAgaWYgKCFoYWRfZXJyb3JzXykgeworICAgIFZhbGlkYXRlRmlsZU9wdGlvbnMocmVzdWx0LCBwcm90byk7CisgIH0KKworICAvLyBBZGRpdGlvbmFsIG5hbWluZyBjb25mbGljdCBjaGVjayBmb3IgbWFwIGVudHJ5IHR5cGVzLiBPbmx5IG5lZWQgdG8gY2hlY2sKKyAgLy8gdGhpcyBpZiB0aGVyZSBhcmUgYWxyZWFkeSBlcnJvcnMuCisgIGlmIChoYWRfZXJyb3JzXykgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ubWVzc2FnZV90eXBlX3NpemUoKTsgKytpKSB7CisgICAgICBEZXRlY3RNYXBDb25mbGljdHMocmVzdWx0LT5tZXNzYWdlX3R5cGUoaSksIHByb3RvLm1lc3NhZ2VfdHlwZShpKSk7CisgICAgfQorICB9CisKKworICBpZiAoIXVudXNlZF9kZXBlbmRlbmN5Xy5lbXB0eSgpKSB7CisgICAgTG9nVW51c2VkRGVwZW5kZW5jeShyZXN1bHQpOworICB9CisKKyAgaWYgKGhhZF9lcnJvcnNfKSB7CisgICAgdGFibGVzXy0+Um9sbGJhY2tUb0xhc3RDaGVja3BvaW50KCk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgdGFibGVzXy0+Q2xlYXJMYXN0Q2hlY2twb2ludCgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3IqIHJlc3VsdCkgeworICBjb25zdCBzdHJpbmcmIHNjb3BlID0gKHBhcmVudCA9PSBOVUxMKSA/CisgICAgZmlsZV8tPnBhY2thZ2UoKSA6IHBhcmVudC0+ZnVsbF9uYW1lKCk7CisgIHN0cmluZyogZnVsbF9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoc2NvcGUpOworICBpZiAoIWZ1bGxfbmFtZS0+ZW1wdHkoKSkgZnVsbF9uYW1lLT5hcHBlbmQoMSwgJy4nKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQocHJvdG8ubmFtZSgpKTsKKworICBWYWxpZGF0ZVN5bWJvbE5hbWUocHJvdG8ubmFtZSgpLCAqZnVsbF9uYW1lLCBwcm90byk7CisKKyAgcmVzdWx0LT5uYW1lXyAgICAgICAgICAgID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocHJvdG8ubmFtZSgpKTsKKyAgcmVzdWx0LT5mdWxsX25hbWVfICAgICAgID0gZnVsbF9uYW1lOworICByZXN1bHQtPmZpbGVfICAgICAgICAgICAgPSBmaWxlXzsKKyAgcmVzdWx0LT5jb250YWluaW5nX3R5cGVfID0gcGFyZW50OworICByZXN1bHQtPmlzX3BsYWNlaG9sZGVyXyAgPSBmYWxzZTsKKyAgcmVzdWx0LT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8gPSBmYWxzZTsKKworICAvLyBCdWlsZCBvbmVvZnMgZmlyc3Qgc28gdGhhdCBmaWVsZHMgYW5kIGV4dGVuc2lvbiByYW5nZXMgY2FuIHJlZmVyIHRvIHRoZW0uCisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIG9uZW9mX2RlY2wgICAgICwgQnVpbGRPbmVvZiAgICAgICAgICwgcmVzdWx0KTsKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgZmllbGQgICAgICAgICAgLCBCdWlsZEZpZWxkICAgICAgICAgLCByZXN1bHQpOworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBuZXN0ZWRfdHlwZSAgICAsIEJ1aWxkTWVzc2FnZSAgICAgICAsIHJlc3VsdCk7CisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIGVudW1fdHlwZSAgICAgICwgQnVpbGRFbnVtICAgICAgICAgICwgcmVzdWx0KTsKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgZXh0ZW5zaW9uX3JhbmdlLCBCdWlsZEV4dGVuc2lvblJhbmdlLCByZXN1bHQpOworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBleHRlbnNpb24gICAgICAsIEJ1aWxkRXh0ZW5zaW9uICAgICAsIHJlc3VsdCk7CisKKyAgLy8gQ29weSBvcHRpb25zLgorICBpZiAoIXByb3RvLmhhc19vcHRpb25zKCkpIHsKKyAgICByZXN1bHQtPm9wdGlvbnNfID0gTlVMTDsgIC8vIFdpbGwgc2V0IHRvIGRlZmF1bHRfaW5zdGFuY2UgbGF0ZXIuCisgIH0gZWxzZSB7CisgICAgQWxsb2NhdGVPcHRpb25zKHByb3RvLm9wdGlvbnMoKSwgcmVzdWx0KTsKKyAgfQorCisgIEFkZFN5bWJvbChyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwYXJlbnQsIHJlc3VsdC0+bmFtZSgpLAorICAgICAgICAgICAgcHJvdG8sIFN5bWJvbChyZXN1bHQpKTsKKworICAvLyBDaGVjayB0aGF0IG5vIGZpZWxkcyBoYXZlIG51bWJlcnMgaW4gZXh0ZW5zaW9uIHJhbmdlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXN1bHQtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSByZXN1bHQtPmZpZWxkKGkpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgcmVzdWx0LT5leHRlbnNpb25fcmFuZ2VfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmFuZ2UgPSByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZShqKTsKKyAgICAgIGlmIChyYW5nZS0+c3RhcnQgPD0gZmllbGQtPm51bWJlcigpICYmIGZpZWxkLT5udW1iZXIoKSA8IHJhbmdlLT5lbmQpIHsKKyAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90by5leHRlbnNpb25fcmFuZ2UoaiksCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgICAgICAgICJFeHRlbnNpb24gcmFuZ2UgJDAgdG8gJDEgaW5jbHVkZXMgZmllbGQgXCIkMlwiICgkMykuIiwKKyAgICAgICAgICAgICAgICAgICByYW5nZS0+c3RhcnQsIHJhbmdlLT5lbmQgLSAxLAorICAgICAgICAgICAgICAgICAgIGZpZWxkLT5uYW1lKCksIGZpZWxkLT5udW1iZXIoKSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIENoZWNrIHRoYXQgZXh0ZW5zaW9uIHJhbmdlcyBkb24ndCBvdmVybGFwLgorICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZTEgPSByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZShpKTsKKyAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyBqKyspIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZTIgPSByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZShqKTsKKyAgICAgIGlmIChyYW5nZTEtPmVuZCA+IHJhbmdlMi0+c3RhcnQgJiYgcmFuZ2UyLT5lbmQgPiByYW5nZTEtPnN0YXJ0KSB7CisgICAgICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLmV4dGVuc2lvbl9yYW5nZShqKSwKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkV4dGVuc2lvbiByYW5nZSAkMCB0byAkMSBvdmVybGFwcyB3aXRoICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxyZWFkeS1kZWZpbmVkIHJhbmdlICQyIHRvICQzLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UyLT5zdGFydCwgcmFuZ2UyLT5lbmQgLSAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlMS0+c3RhcnQsIHJhbmdlMS0+ZW5kIC0gMSkpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpCdWlsZEZpZWxkT3JFeHRlbnNpb24oY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2V4dGVuc2lvbikgeworICBjb25zdCBzdHJpbmcmIHNjb3BlID0gKHBhcmVudCA9PSBOVUxMKSA/CisgICAgZmlsZV8tPnBhY2thZ2UoKSA6IHBhcmVudC0+ZnVsbF9uYW1lKCk7CisgIHN0cmluZyogZnVsbF9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoc2NvcGUpOworICBpZiAoIWZ1bGxfbmFtZS0+ZW1wdHkoKSkgZnVsbF9uYW1lLT5hcHBlbmQoMSwgJy4nKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQocHJvdG8ubmFtZSgpKTsKKworICBWYWxpZGF0ZVN5bWJvbE5hbWUocHJvdG8ubmFtZSgpLCAqZnVsbF9uYW1lLCBwcm90byk7CisKKyAgcmVzdWx0LT5uYW1lXyAgICAgICAgID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocHJvdG8ubmFtZSgpKTsKKyAgcmVzdWx0LT5mdWxsX25hbWVfICAgID0gZnVsbF9uYW1lOworICByZXN1bHQtPmZpbGVfICAgICAgICAgPSBmaWxlXzsKKyAgcmVzdWx0LT5udW1iZXJfICAgICAgID0gcHJvdG8ubnVtYmVyKCk7CisgIHJlc3VsdC0+aXNfZXh0ZW5zaW9uXyA9IGlzX2V4dGVuc2lvbjsKKworICAvLyBJZiAucHJvdG8gZmlsZXMgZm9sbG93IHRoZSBzdHlsZSBndWlkZSB0aGVuIHRoZSBuYW1lIHNob3VsZCBhbHJlYWR5IGJlCisgIC8vIGxvd2VyLWNhc2VkLiAgSWYgdGhhdCdzIHRoZSBjYXNlIHdlIGNhbiBqdXN0IHJldXNlIHRoZSBzdHJpbmcgd2UgYWxyZWFkeQorICAvLyBhbGxvY2F0ZWQgcmF0aGVyIHRoYW4gYWxsb2NhdGUgYSBuZXcgb25lLgorICBzdHJpbmcgbG93ZXJjYXNlX25hbWUocHJvdG8ubmFtZSgpKTsKKyAgTG93ZXJTdHJpbmcoJmxvd2VyY2FzZV9uYW1lKTsKKyAgaWYgKGxvd2VyY2FzZV9uYW1lID09IHByb3RvLm5hbWUoKSkgeworICAgIHJlc3VsdC0+bG93ZXJjYXNlX25hbWVfID0gcmVzdWx0LT5uYW1lXzsKKyAgfSBlbHNlIHsKKyAgICByZXN1bHQtPmxvd2VyY2FzZV9uYW1lXyA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKGxvd2VyY2FzZV9uYW1lKTsKKyAgfQorCisgIC8vIERvbid0IGJvdGhlciB3aXRoIHRoZSBhYm92ZSBvcHRpbWl6YXRpb24gZm9yIGNhbWVsLWNhc2UgbmFtZXMgc2luY2UKKyAgLy8gLnByb3RvIGZpbGVzIHRoYXQgZm9sbG93IHRoZSBndWlkZSBzaG91bGRuJ3QgYmUgdXNpbmcgbmFtZXMgaW4gdGhpcworICAvLyBmb3JtYXQsIHNvIHRoZSBvcHRpbWl6YXRpb24gd291bGRuJ3QgaGVscCBtdWNoLgorICByZXN1bHQtPmNhbWVsY2FzZV9uYW1lXyA9CisgICAgICB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhUb0NhbWVsQ2FzZShwcm90by5uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBsb3dlcl9maXJzdCA9ICovIHRydWUpKTsKKworICAvLyBTb21lIGNvbXBpbGVycyBkbyBub3QgYWxsb3cgc3RhdGljX2Nhc3QgZGlyZWN0bHkgYmV0d2VlbiB0d28gZW51bSB0eXBlcywKKyAgLy8gc28gd2UgbXVzdCBjYXN0IHRvIGludCBmaXJzdC4KKyAgcmVzdWx0LT50eXBlXyAgPSBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OlR5cGU+KAorICAgICAgICAgICAgICAgICAgICAgaW1wbGljaXRfY2FzdDxpbnQ+KHByb3RvLnR5cGUoKSkpOworICByZXN1bHQtPmxhYmVsXyA9IHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvcjo6TGFiZWw+KAorICAgICAgICAgICAgICAgICAgICAgaW1wbGljaXRfY2FzdDxpbnQ+KHByb3RvLmxhYmVsKCkpKTsKKworICAvLyBBbiBleHRlbnNpb24gY2Fubm90IGhhdmUgYSByZXF1aXJlZCBmaWVsZCAoYi8xMzM2NTgzNikuCisgIGlmIChyZXN1bHQtPmlzX2V4dGVuc2lvbl8gJiYKKyAgICAgIHJlc3VsdC0+bGFiZWxfID09IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVRVUlSRUQpIHsKKyAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAvLyBFcnJvciBsb2NhdGlvbiBgVFlQRWA6IHdlIHdvdWxkIHJlYWxseSBsaWtlIHRvIGluZGljYXRlCisgICAgICAgICAgICAgLy8gYExBQkVMYCwgYnV0IHRoZSBgRXJyb3JMb2NhdGlvbmAgZW51bSBoYXMgbm8gZW50cnkgZm9yIHRoaXMsIGFuZAorICAgICAgICAgICAgIC8vIHdlIGRvbid0IG5lY2Vzc2FyaWx5IGtub3cgYWJvdXQgYWxsIGltcGxlbWVudGF0aW9ucyBvZiB0aGUKKyAgICAgICAgICAgICAvLyBgRXJyb3JDb2xsZWN0b3JgIGludGVyZmFjZSB0byBleHRlbmQgdGhlbSB0byBoYW5kbGUgdGhlIG5ldworICAgICAgICAgICAgIC8vIGVycm9yIGxvY2F0aW9uIHR5cGUgcHJvcGVybHkuCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICJNZXNzYWdlIGV4dGVuc2lvbnMgY2Fubm90IGhhdmUgcmVxdWlyZWQgZmllbGRzLiIpOworICB9CisKKyAgLy8gU29tZSBvZiB0aGVzZSBtYXkgYmUgZmlsbGVkIGluIHdoZW4gY3Jvc3MtbGlua2luZy4KKyAgcmVzdWx0LT5jb250YWluaW5nX3R5cGVfID0gTlVMTDsKKyAgcmVzdWx0LT5leHRlbnNpb25fc2NvcGVfID0gTlVMTDsKKyAgcmVzdWx0LT5tZXNzYWdlX3R5cGVfID0gTlVMTDsKKyAgcmVzdWx0LT5lbnVtX3R5cGVfID0gTlVMTDsKKworICByZXN1bHQtPmhhc19kZWZhdWx0X3ZhbHVlXyA9IHByb3RvLmhhc19kZWZhdWx0X3ZhbHVlKCk7CisgIGlmIChwcm90by5oYXNfZGVmYXVsdF92YWx1ZSgpICYmIHJlc3VsdC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6REVGQVVMVF9WQUxVRSwKKyAgICAgICAgICAgICAiUmVwZWF0ZWQgZmllbGRzIGNhbid0IGhhdmUgZGVmYXVsdCB2YWx1ZXMuIik7CisgIH0KKworICBpZiAocHJvdG8uaGFzX3R5cGUoKSkgeworICAgIGlmIChwcm90by5oYXNfZGVmYXVsdF92YWx1ZSgpKSB7CisgICAgICBjaGFyKiBlbmRfcG9zID0gTlVMTDsKKyAgICAgIHN3aXRjaCAocmVzdWx0LT5jcHBfdHlwZSgpKSB7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9pbnQzMl8gPQorICAgICAgICAgICAgc3RydG9sKHByb3RvLmRlZmF1bHRfdmFsdWUoKS5jX3N0cigpLCAmZW5kX3BvcywgMCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NF8gPQorICAgICAgICAgICAgc3RydG82NChwcm90by5kZWZhdWx0X3ZhbHVlKCkuY19zdHIoKSwgJmVuZF9wb3MsIDApOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3VpbnQzMl8gPQorICAgICAgICAgICAgc3RydG91bChwcm90by5kZWZhdWx0X3ZhbHVlKCkuY19zdHIoKSwgJmVuZF9wb3MsIDApOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NF8gPQorICAgICAgICAgICAgc3RydG91NjQocHJvdG8uZGVmYXVsdF92YWx1ZSgpLmNfc3RyKCksICZlbmRfcG9zLCAwKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICAgICAgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKSA9PSAiaW5mIikgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2Zsb2F0XyA9IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKTsKKyAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKSA9PSAiLWluZiIpIHsKKyAgICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9mbG9hdF8gPSAtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpOworICAgICAgICAgIH0gZWxzZSBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJuYW4iKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZmxvYXRfID0gbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjpxdWlldF9OYU4oKTsKKyAgICAgICAgICB9IGVsc2UgIHsKKyAgICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9mbG9hdF8gPQorICAgICAgICAgICAgICBpbzo6Tm9Mb2NhbGVTdHJ0b2QocHJvdG8uZGVmYXVsdF92YWx1ZSgpLmNfc3RyKCksICZlbmRfcG9zKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRToKKyAgICAgICAgICBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJpbmYiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZG91YmxlXyA9IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgICAgICAgfSBlbHNlIGlmIChwcm90by5kZWZhdWx0X3ZhbHVlKCkgPT0gIi1pbmYiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZG91YmxlXyA9IC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpOworICAgICAgICAgIH0gZWxzZSBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJuYW4iKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZG91YmxlXyA9IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OnF1aWV0X05hTigpOworICAgICAgICAgIH0gZWxzZSAgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2RvdWJsZV8gPQorICAgICAgICAgICAgICAgIGlvOjpOb0xvY2FsZVN0cnRvZChwcm90by5kZWZhdWx0X3ZhbHVlKCkuY19zdHIoKSwgJmVuZF9wb3MpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgICBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJ0cnVlIikgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2Jvb2xfID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKSA9PSAiZmFsc2UiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfYm9vbF8gPSBmYWxzZTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgICAiQm9vbGVhbiBkZWZhdWx0IG11c3QgYmUgdHJ1ZSBvciBmYWxzZS4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICAgICAgLy8gVGhpcyB3aWxsIGJlIGZpbGxlZCBpbiB3aGVuIGNyb3NzLWxpbmtpbmcuCisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2VudW1fID0gTlVMTDsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIGlmIChyZXN1bHQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmdfID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoCisgICAgICAgICAgICAgIFVuZXNjYXBlQ0VzY2FwZVN0cmluZyhwcm90by5kZWZhdWx0X3ZhbHVlKCkpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3N0cmluZ18gPQorICAgICAgICAgICAgICAgIHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLmRlZmF1bHRfdmFsdWUoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6REVGQVVMVF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAiTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0IHZhbHVlcy4iKTsKKyAgICAgICAgICByZXN1bHQtPmhhc19kZWZhdWx0X3ZhbHVlXyA9IGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBpZiAoZW5kX3BvcyAhPSBOVUxMKSB7CisgICAgICAgIC8vIGVuZF9wb3MgaXMgb25seSBzZXQgbm9uLU5VTEwgYnkgdGhlIHBhcnNlcnMgZm9yIG51bWVyaWMgdHlwZXMsIGFib3ZlLgorICAgICAgICAvLyBUaGlzIGNoZWNrcyB0aGF0IHRoZSBkZWZhdWx0IHdhcyBub24tZW1wdHkgYW5kIGhhZCBubyBleHRyYSBqdW5rCisgICAgICAgIC8vIGFmdGVyIHRoZSBlbmQgb2YgdGhlIG51bWJlci4KKyAgICAgICAgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKS5lbXB0eSgpIHx8ICplbmRfcG9zICE9ICdcMCcpIHsKKyAgICAgICAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgIkNvdWxkbid0IHBhcnNlIGRlZmF1bHQgdmFsdWUgXCIiICsgcHJvdG8uZGVmYXVsdF92YWx1ZSgpICsKKyAgICAgICAgICAgICAgICAgICAiXCIuIik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gTm8gZXhwbGljaXQgZGVmYXVsdCB2YWx1ZQorICAgICAgc3dpdGNoIChyZXN1bHQtPmNwcF90eXBlKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2ludDMyXyA9IDA7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NF8gPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3VpbnQzMl8gPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NF8gPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZmxvYXRfID0gMC4wZjsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9kb3VibGVfID0gMC4wOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9ib29sXyA9IGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICAgIC8vIFRoaXMgd2lsbCBiZSBmaWxsZWQgaW4gd2hlbiBjcm9zcy1saW5raW5nLgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9lbnVtXyA9IE5VTEw7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nXyA9ICZpbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAocmVzdWx0LT5udW1iZXIoKSA8PSAwKSB7CisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICJGaWVsZCBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuIik7CisgIH0gZWxzZSBpZiAoIWlzX2V4dGVuc2lvbiAmJiByZXN1bHQtPm51bWJlcigpID4gRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKSB7CisgICAgLy8gT25seSB2YWxpZGF0ZSB0aGF0IHRoZSBudW1iZXIgaXMgd2l0aGluIHRoZSB2YWxpZCBmaWVsZCByYW5nZSBpZiBpdCBpcworICAgIC8vIG5vdCBhbiBleHRlbnNpb24uIFNpbmNlIGV4dGVuc2lvbiBudW1iZXJzIGFyZSB2YWxpZGF0ZWQgd2l0aCB0aGUKKyAgICAvLyBleHRlbmRlZSdzIHZhbGlkIHNldCBvZiBleHRlbnNpb24gbnVtYmVycywgYW5kIHRob3NlIGFyZSBpbiB0dXJuCisgICAgLy8gdmFsaWRhdGVkIGFnYWluc3QgdGhlIG1heCBhbGxvd2VkIG51bWJlciwgdGhlIGNoZWNrIGlzIHVubmVjZXNzYXJ5IGZvcgorICAgIC8vIGV4dGVuc2lvbiBmaWVsZHMuCisgICAgLy8gVGhpcyBhdm9pZHMgY3Jvc3MtbGlua2luZyBpc3N1ZXMgdGhhdCBhcmlzZSB3aGVuIGF0dGVtcHRpbmcgdG8gY2hlY2sgaWYKKyAgICAvLyB0aGUgZXh0ZW5kZWUgaXMgYSBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCBtZXNzYWdlLCB3aGljaCBoYXMgYSBoaWdoZXIgbWF4CisgICAgLy8gb24gZXh0ZW5zaW9uIG51bWJlcnMuCisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkZpZWxkIG51bWJlcnMgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiAkMC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKSk7CisgIH0gZWxzZSBpZiAocmVzdWx0LT5udW1iZXIoKSA+PSBGaWVsZERlc2NyaXB0b3I6OmtGaXJzdFJlc2VydmVkTnVtYmVyICYmCisgICAgICAgICAgICAgcmVzdWx0LT5udW1iZXIoKSA8PSBGaWVsZERlc2NyaXB0b3I6OmtMYXN0UmVzZXJ2ZWROdW1iZXIpIHsKKyAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAgICAgICJGaWVsZCBudW1iZXJzICQwIHRocm91Z2ggJDEgYXJlIHJlc2VydmVkIGZvciB0aGUgcHJvdG9jb2wgIgorICAgICAgICAgICAgICAgImJ1ZmZlciBsaWJyYXJ5IGltcGxlbWVudGF0aW9uLiIsCisgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3I6OmtGaXJzdFJlc2VydmVkTnVtYmVyLAorICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTGFzdFJlc2VydmVkTnVtYmVyKSk7CisgIH0KKworICBpZiAoaXNfZXh0ZW5zaW9uKSB7CisgICAgaWYgKCFwcm90by5oYXNfZXh0ZW5kZWUoKSkgeworICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlIG5vdCBzZXQgZm9yIGV4dGVuc2lvbiBmaWVsZC4iKTsKKyAgICB9CisKKyAgICByZXN1bHQtPmV4dGVuc2lvbl9zY29wZV8gPSBwYXJlbnQ7CisKKyAgICBpZiAocHJvdG8uaGFzX29uZW9mX2luZGV4KCkpIHsKKyAgICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAgICJGaWVsZERlc2NyaXB0b3JQcm90by5vbmVvZl9pbmRleCBzaG91bGQgbm90IGJlIHNldCBmb3IgIgorICAgICAgICAgICAgICAgImV4dGVuc2lvbnMuIik7CisgICAgfQorCisgICAgLy8gRmlsbCBpbiBsYXRlciAobWF5YmUpLgorICAgIHJlc3VsdC0+Y29udGFpbmluZ19vbmVvZl8gPSBOVUxMOworICB9IGVsc2UgeworICAgIGlmIChwcm90by5oYXNfZXh0ZW5kZWUoKSkgeworICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlIHNldCBmb3Igbm9uLWV4dGVuc2lvbiBmaWVsZC4iKTsKKyAgICB9CisKKyAgICByZXN1bHQtPmNvbnRhaW5pbmdfdHlwZV8gPSBwYXJlbnQ7CisKKyAgICBpZiAocHJvdG8uaGFzX29uZW9mX2luZGV4KCkpIHsKKyAgICAgIGlmIChwcm90by5vbmVvZl9pbmRleCgpIDwgMCB8fAorICAgICAgICAgIHByb3RvLm9uZW9mX2luZGV4KCkgPj0gcGFyZW50LT5vbmVvZl9kZWNsX2NvdW50KCkpIHsKKyAgICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4ICQwIGlzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3V0IG9mIHJhbmdlIGZvciB0eXBlIFwiJDFcIi4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLm9uZW9mX2luZGV4KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LT5uYW1lKCkpKTsKKyAgICAgICAgcmVzdWx0LT5jb250YWluaW5nX29uZW9mXyA9IE5VTEw7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQtPmNvbnRhaW5pbmdfb25lb2ZfID0gcGFyZW50LT5vbmVvZl9kZWNsKHByb3RvLm9uZW9mX2luZGV4KCkpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQtPmNvbnRhaW5pbmdfb25lb2ZfID0gTlVMTDsKKyAgICB9CisgIH0KKworICAvLyBDb3B5IG9wdGlvbnMuCisgIGlmICghcHJvdG8uaGFzX29wdGlvbnMoKSkgeworICAgIHJlc3VsdC0+b3B0aW9uc18gPSBOVUxMOyAgLy8gV2lsbCBzZXQgdG8gZGVmYXVsdF9pbnN0YW5jZSBsYXRlci4KKyAgfSBlbHNlIHsKKyAgICBBbGxvY2F0ZU9wdGlvbnMocHJvdG8ub3B0aW9ucygpLCByZXN1bHQpOworICB9CisKKyAgQWRkU3ltYm9sKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHBhcmVudCwgcmVzdWx0LT5uYW1lKCksCisgICAgICAgICAgICBwcm90bywgU3ltYm9sKHJlc3VsdCkpOworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpCdWlsZEV4dGVuc2lvblJhbmdlKAorICAgIGNvbnN0IERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UmIHByb3RvLAorICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwKKyAgICBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmVzdWx0KSB7CisgIHJlc3VsdC0+c3RhcnQgPSBwcm90by5zdGFydCgpOworICByZXN1bHQtPmVuZCA9IHByb3RvLmVuZCgpOworICBpZiAocmVzdWx0LT5zdGFydCA8PSAwKSB7CisgICAgQWRkRXJyb3IocGFyZW50LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgIkV4dGVuc2lvbiBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuIik7CisgIH0KKworICAvLyBDaGVja2luZyBvZiB0aGUgdXBwZXIgYm91bmQgb2YgdGhlIGV4dGVuc2lvbiByYW5nZSBpcyBkZWZlcnJlZCB1bnRpbCBhZnRlcgorICAvLyBvcHRpb25zIGludGVycHJldGluZy4gVGhpcyBhbGxvd3MgbWVzc2FnZXMgd2l0aCBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCB0bworICAvLyBoYXZlIGV4dGVuc2lvbnMgYmV5b25kIEZpZWxkRGVzY3JpcHRvcjo6a01heE51bWJlciwgc2luY2UgdGhlIGV4dGVuc2lvbgorICAvLyBudW1iZXJzIGFyZSBhY3R1YWxseSB1c2VkIGFzIGludDMycyBpbiB0aGUgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQuCisKKyAgaWYgKHJlc3VsdC0+c3RhcnQgPj0gcmVzdWx0LT5lbmQpIHsKKyAgICBBZGRFcnJvcihwYXJlbnQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5VTUJFUiwKKyAgICAgICAgICAgICAiRXh0ZW5zaW9uIHJhbmdlIGVuZCBudW1iZXIgbXVzdCBiZSBncmVhdGVyIHRoYW4gc3RhcnQgbnVtYmVyLiIpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkJ1aWxkT25lb2YoY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9uZW9mRGVzY3JpcHRvciogcmVzdWx0KSB7CisgIHN0cmluZyogZnVsbF9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocGFyZW50LT5mdWxsX25hbWUoKSk7CisgIGZ1bGxfbmFtZS0+YXBwZW5kKDEsICcuJyk7CisgIGZ1bGxfbmFtZS0+YXBwZW5kKHByb3RvLm5hbWUoKSk7CisKKyAgVmFsaWRhdGVTeW1ib2xOYW1lKHByb3RvLm5hbWUoKSwgKmZ1bGxfbmFtZSwgcHJvdG8pOworCisgIHJlc3VsdC0+bmFtZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5uYW1lKCkpOworICByZXN1bHQtPmZ1bGxfbmFtZV8gPSBmdWxsX25hbWU7CisKKyAgcmVzdWx0LT5jb250YWluaW5nX3R5cGVfID0gcGFyZW50OworCisgIC8vIFdlIG5lZWQgdG8gZmlsbCB0aGVzZSBpbiBsYXRlci4KKyAgcmVzdWx0LT5maWVsZF9jb3VudF8gPSAwOworICByZXN1bHQtPmZpZWxkc18gPSBOVUxMOworCisgIEFkZFN5bWJvbChyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwYXJlbnQsIHJlc3VsdC0+bmFtZSgpLAorICAgICAgICAgICAgcHJvdG8sIFN5bWJvbChyZXN1bHQpKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtRGVzY3JpcHRvciogcmVzdWx0KSB7CisgIGNvbnN0IHN0cmluZyYgc2NvcGUgPSAocGFyZW50ID09IE5VTEwpID8KKyAgICBmaWxlXy0+cGFja2FnZSgpIDogcGFyZW50LT5mdWxsX25hbWUoKTsKKyAgc3RyaW5nKiBmdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhzY29wZSk7CisgIGlmICghZnVsbF9uYW1lLT5lbXB0eSgpKSBmdWxsX25hbWUtPmFwcGVuZCgxLCAnLicpOworICBmdWxsX25hbWUtPmFwcGVuZChwcm90by5uYW1lKCkpOworCisgIFZhbGlkYXRlU3ltYm9sTmFtZShwcm90by5uYW1lKCksICpmdWxsX25hbWUsIHByb3RvKTsKKworICByZXN1bHQtPm5hbWVfICAgICAgICAgICAgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5uYW1lKCkpOworICByZXN1bHQtPmZ1bGxfbmFtZV8gICAgICAgPSBmdWxsX25hbWU7CisgIHJlc3VsdC0+ZmlsZV8gICAgICAgICAgICA9IGZpbGVfOworICByZXN1bHQtPmNvbnRhaW5pbmdfdHlwZV8gPSBwYXJlbnQ7CisgIHJlc3VsdC0+aXNfcGxhY2Vob2xkZXJfICA9IGZhbHNlOworICByZXN1bHQtPmlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXyA9IGZhbHNlOworCisgIGlmIChwcm90by52YWx1ZV9zaXplKCkgPT0gMCkgeworICAgIC8vIFdlIGNhbm5vdCBhbGxvdyBlbnVtcyB3aXRoIG5vIHZhbHVlcyBiZWNhdXNlIHRoaXMgd291bGQgbWVhbiB0aGVyZQorICAgIC8vIHdvdWxkIGJlIG5vIHZhbGlkIGRlZmF1bHQgdmFsdWUgZm9yIGZpZWxkcyBvZiB0aGlzIHR5cGUuCisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICJFbnVtcyBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIHZhbHVlLiIpOworICB9CisKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgdmFsdWUsIEJ1aWxkRW51bVZhbHVlLCByZXN1bHQpOworCisgIC8vIENvcHkgb3B0aW9ucy4KKyAgaWYgKCFwcm90by5oYXNfb3B0aW9ucygpKSB7CisgICAgcmVzdWx0LT5vcHRpb25zXyA9IE5VTEw7ICAvLyBXaWxsIHNldCB0byBkZWZhdWx0X2luc3RhbmNlIGxhdGVyLgorICB9IGVsc2UgeworICAgIEFsbG9jYXRlT3B0aW9ucyhwcm90by5vcHRpb25zKCksIHJlc3VsdCk7CisgIH0KKworICBBZGRTeW1ib2wocmVzdWx0LT5mdWxsX25hbWUoKSwgcGFyZW50LCByZXN1bHQtPm5hbWUoKSwKKyAgICAgICAgICAgIHByb3RvLCBTeW1ib2wocmVzdWx0KSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkJ1aWxkRW51bVZhbHVlKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVZhbHVlRGVzY3JpcHRvciogcmVzdWx0KSB7CisgIHJlc3VsdC0+bmFtZV8gICA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLm5hbWUoKSk7CisgIHJlc3VsdC0+bnVtYmVyXyA9IHByb3RvLm51bWJlcigpOworICByZXN1bHQtPnR5cGVfICAgPSBwYXJlbnQ7CisKKyAgLy8gTm90ZTogIGZ1bGxfbmFtZSBmb3IgZW51bSB2YWx1ZXMgaXMgYSBzaWJsaW5nIHRvIHRoZSBwYXJlbnQncyBuYW1lLCBub3QgYQorICAvLyAgIGNoaWxkIG9mIGl0LgorICBzdHJpbmcqIGZ1bGxfbmFtZSA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKCpwYXJlbnQtPmZ1bGxfbmFtZV8pOworICBmdWxsX25hbWUtPnJlc2l6ZShmdWxsX25hbWUtPnNpemUoKSAtIHBhcmVudC0+bmFtZV8tPnNpemUoKSk7CisgIGZ1bGxfbmFtZS0+YXBwZW5kKCpyZXN1bHQtPm5hbWVfKTsKKyAgcmVzdWx0LT5mdWxsX25hbWVfID0gZnVsbF9uYW1lOworCisgIFZhbGlkYXRlU3ltYm9sTmFtZShwcm90by5uYW1lKCksICpmdWxsX25hbWUsIHByb3RvKTsKKworICAvLyBDb3B5IG9wdGlvbnMuCisgIGlmICghcHJvdG8uaGFzX29wdGlvbnMoKSkgeworICAgIHJlc3VsdC0+b3B0aW9uc18gPSBOVUxMOyAgLy8gV2lsbCBzZXQgdG8gZGVmYXVsdF9pbnN0YW5jZSBsYXRlci4KKyAgfSBlbHNlIHsKKyAgICBBbGxvY2F0ZU9wdGlvbnMocHJvdG8ub3B0aW9ucygpLCByZXN1bHQpOworICB9CisKKyAgLy8gQWdhaW4sIGVudW0gdmFsdWVzIGFyZSB3ZWlyZCBiZWNhdXNlIHdlIG1ha2VzIHRoZW0gYXBwZWFyIGFzIHNpYmxpbmdzCisgIC8vIG9mIHRoZSBlbnVtIHR5cGUgaW5zdGVhZCBvZiBjaGlsZHJlbiBvZiBpdC4gIFNvLCB3ZSB1c2UKKyAgLy8gcGFyZW50LT5jb250YWluaW5nX3R5cGUoKSBhcyB0aGUgdmFsdWUncyBwYXJlbnQuCisgIGJvb2wgYWRkZWRfdG9fb3V0ZXJfc2NvcGUgPQorICAgIEFkZFN5bWJvbChyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwYXJlbnQtPmNvbnRhaW5pbmdfdHlwZSgpLCByZXN1bHQtPm5hbWUoKSwKKyAgICAgICAgICAgICAgcHJvdG8sIFN5bWJvbChyZXN1bHQpKTsKKworICAvLyBIb3dldmVyLCB3ZSBhbHNvIHdhbnQgdG8gYmUgYWJsZSB0byBzZWFyY2ggZm9yIHZhbHVlcyB3aXRoaW4gYSBzaW5nbGUKKyAgLy8gZW51bSB0eXBlLCBzbyB3ZSBhZGQgaXQgYXMgYSBjaGlsZCBvZiB0aGUgZW51bSB0eXBlIGl0c2VsZiwgdG9vLgorICAvLyBOb3RlOiAgVGhpcyBjb3VsZCBmYWlsLCBidXQgaWYgaXQgZG9lcywgdGhlIGVycm9yIGhhcyBhbHJlYWR5IGJlZW4KKyAgLy8gICByZXBvcnRlZCBieSB0aGUgYWJvdmUgQWRkU3ltYm9sKCkgY2FsbCwgc28gd2UgaWdub3JlIHRoZSByZXR1cm4gY29kZS4KKyAgYm9vbCBhZGRlZF90b19pbm5lcl9zY29wZSA9CisgICAgZmlsZV90YWJsZXNfLT5BZGRBbGlhc1VuZGVyUGFyZW50KHBhcmVudCwgcmVzdWx0LT5uYW1lKCksIFN5bWJvbChyZXN1bHQpKTsKKworICBpZiAoYWRkZWRfdG9faW5uZXJfc2NvcGUgJiYgIWFkZGVkX3RvX291dGVyX3Njb3BlKSB7CisgICAgLy8gVGhpcyB2YWx1ZSBkaWQgbm90IGNvbmZsaWN0IHdpdGggYW55IHZhbHVlcyBkZWZpbmVkIGluIHRoZSBzYW1lIGVudW0sCisgICAgLy8gYnV0IGl0IGRpZCBjb25mbGljdCB3aXRoIHNvbWUgb3RoZXIgc3ltYm9sIGRlZmluZWQgaW4gdGhlIGVudW0gdHlwZSdzCisgICAgLy8gc2NvcGUuICBMZXQncyBwcmludCBhbiBhZGRpdGlvbmFsIGVycm9yIHRvIGV4cGxhaW4gdGhpcy4KKyAgICBzdHJpbmcgb3V0ZXJfc2NvcGU7CisgICAgaWYgKHBhcmVudC0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgICAgb3V0ZXJfc2NvcGUgPSBmaWxlXy0+cGFja2FnZSgpOworICAgIH0gZWxzZSB7CisgICAgICBvdXRlcl9zY29wZSA9IHBhcmVudC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpOworICAgIH0KKworICAgIGlmIChvdXRlcl9zY29wZS5lbXB0eSgpKSB7CisgICAgICBvdXRlcl9zY29wZSA9ICJ0aGUgZ2xvYmFsIHNjb3BlIjsKKyAgICB9IGVsc2UgeworICAgICAgb3V0ZXJfc2NvcGUgPSAiXCIiICsgb3V0ZXJfc2NvcGUgKyAiXCIiOworICAgIH0KKworICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAiTm90ZSB0aGF0IGVudW0gdmFsdWVzIHVzZSBDKysgc2NvcGluZyBydWxlcywgbWVhbmluZyB0aGF0ICIKKyAgICAgICAgICAgICAiZW51bSB2YWx1ZXMgYXJlIHNpYmxpbmdzIG9mIHRoZWlyIHR5cGUsIG5vdCBjaGlsZHJlbiBvZiBpdC4gICIKKyAgICAgICAgICAgICAiVGhlcmVmb3JlLCBcIiIgKyByZXN1bHQtPm5hbWUoKSArICJcIiBtdXN0IGJlIHVuaXF1ZSB3aXRoaW4gIgorICAgICAgICAgICAgICsgb3V0ZXJfc2NvcGUgKyAiLCBub3QganVzdCB3aXRoaW4gXCIiICsgcGFyZW50LT5uYW1lKCkgKyAiXCIuIik7CisgIH0KKworICAvLyBBbiBlbnVtIGlzIGFsbG93ZWQgdG8gZGVmaW5lIHR3byBudW1iZXJzIHRoYXQgcmVmZXIgdG8gdGhlIHNhbWUgdmFsdWUuCisgIC8vIEZpbmRWYWx1ZUJ5TnVtYmVyKCkgc2hvdWxkIHJldHVybiB0aGUgZmlyc3Qgc3VjaCB2YWx1ZSwgc28gd2Ugc2ltcGx5CisgIC8vIGlnbm9yZSBBZGRFbnVtVmFsdWVCeU51bWJlcigpJ3MgcmV0dXJuIGNvZGUuCisgIGZpbGVfdGFibGVzXy0+QWRkRW51bVZhbHVlQnlOdW1iZXIocmVzdWx0KTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRTZXJ2aWNlKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIC8qIGR1bW15ICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZpY2VEZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgc3RyaW5nKiBmdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhmaWxlXy0+cGFja2FnZSgpKTsKKyAgaWYgKCFmdWxsX25hbWUtPmVtcHR5KCkpIGZ1bGxfbmFtZS0+YXBwZW5kKDEsICcuJyk7CisgIGZ1bGxfbmFtZS0+YXBwZW5kKHByb3RvLm5hbWUoKSk7CisKKyAgVmFsaWRhdGVTeW1ib2xOYW1lKHByb3RvLm5hbWUoKSwgKmZ1bGxfbmFtZSwgcHJvdG8pOworCisgIHJlc3VsdC0+bmFtZV8gICAgICA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLm5hbWUoKSk7CisgIHJlc3VsdC0+ZnVsbF9uYW1lXyA9IGZ1bGxfbmFtZTsKKyAgcmVzdWx0LT5maWxlXyAgICAgID0gZmlsZV87CisKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgbWV0aG9kLCBCdWlsZE1ldGhvZCwgcmVzdWx0KTsKKworICAvLyBDb3B5IG9wdGlvbnMuCisgIGlmICghcHJvdG8uaGFzX29wdGlvbnMoKSkgeworICAgIHJlc3VsdC0+b3B0aW9uc18gPSBOVUxMOyAgLy8gV2lsbCBzZXQgdG8gZGVmYXVsdF9pbnN0YW5jZSBsYXRlci4KKyAgfSBlbHNlIHsKKyAgICBBbGxvY2F0ZU9wdGlvbnMocHJvdG8ub3B0aW9ucygpLCByZXN1bHQpOworICB9CisKKyAgQWRkU3ltYm9sKHJlc3VsdC0+ZnVsbF9uYW1lKCksIE5VTEwsIHJlc3VsdC0+bmFtZSgpLAorICAgICAgICAgICAgcHJvdG8sIFN5bWJvbChyZXN1bHQpKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRNZXRob2QoY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2REZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgcmVzdWx0LT5uYW1lXyAgICA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLm5hbWUoKSk7CisgIHJlc3VsdC0+c2VydmljZV8gPSBwYXJlbnQ7CisKKyAgc3RyaW5nKiBmdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwYXJlbnQtPmZ1bGxfbmFtZSgpKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQoMSwgJy4nKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQoKnJlc3VsdC0+bmFtZV8pOworICByZXN1bHQtPmZ1bGxfbmFtZV8gPSBmdWxsX25hbWU7CisKKyAgVmFsaWRhdGVTeW1ib2xOYW1lKHByb3RvLm5hbWUoKSwgKmZ1bGxfbmFtZSwgcHJvdG8pOworCisgIC8vIFRoZXNlIHdpbGwgYmUgZmlsbGVkIGluIHdoZW4gY3Jvc3MtbGlua2luZy4KKyAgcmVzdWx0LT5pbnB1dF90eXBlXyA9IE5VTEw7CisgIHJlc3VsdC0+b3V0cHV0X3R5cGVfID0gTlVMTDsKKworICAvLyBDb3B5IG9wdGlvbnMuCisgIGlmICghcHJvdG8uaGFzX29wdGlvbnMoKSkgeworICAgIHJlc3VsdC0+b3B0aW9uc18gPSBOVUxMOyAgLy8gV2lsbCBzZXQgdG8gZGVmYXVsdF9pbnN0YW5jZSBsYXRlci4KKyAgfSBlbHNlIHsKKyAgICBBbGxvY2F0ZU9wdGlvbnMocHJvdG8ub3B0aW9ucygpLCByZXN1bHQpOworICB9CisKKyAgcmVzdWx0LT5jbGllbnRfc3RyZWFtaW5nXyA9IHByb3RvLmNsaWVudF9zdHJlYW1pbmcoKTsKKyAgcmVzdWx0LT5zZXJ2ZXJfc3RyZWFtaW5nXyA9IHByb3RvLnNlcnZlcl9zdHJlYW1pbmcoKTsKKworICBBZGRTeW1ib2wocmVzdWx0LT5mdWxsX25hbWUoKSwgcGFyZW50LCByZXN1bHQtPm5hbWUoKSwKKyAgICAgICAgICAgIHByb3RvLCBTeW1ib2wocmVzdWx0KSk7Cit9CisKKyN1bmRlZiBCVUlMRF9BUlJBWQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkNyb3NzTGlua0ZpbGUoCisgICAgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGlmIChmaWxlLT5vcHRpb25zXyA9PSBOVUxMKSB7CisgICAgZmlsZS0+b3B0aW9uc18gPSAmRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIENyb3NzTGlua01lc3NhZ2UoJmZpbGUtPm1lc3NhZ2VfdHlwZXNfW2ldLCBwcm90by5tZXNzYWdlX3R5cGUoaSkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rRmllbGQoJmZpbGUtPmV4dGVuc2lvbnNfW2ldLCBwcm90by5leHRlbnNpb24oaSkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rRW51bSgmZmlsZS0+ZW51bV90eXBlc19baV0sIHByb3RvLmVudW1fdHlwZShpKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPnNlcnZpY2VfY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rU2VydmljZSgmZmlsZS0+c2VydmljZXNfW2ldLCBwcm90by5zZXJ2aWNlKGkpKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpDcm9zc0xpbmtNZXNzYWdlKAorICAgIERlc2NyaXB0b3IqIG1lc3NhZ2UsIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKG1lc3NhZ2UtPm9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBtZXNzYWdlLT5vcHRpb25zXyA9ICZNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtNZXNzYWdlKCZtZXNzYWdlLT5uZXN0ZWRfdHlwZXNfW2ldLCBwcm90by5uZXN0ZWRfdHlwZShpKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtFbnVtKCZtZXNzYWdlLT5lbnVtX3R5cGVzX1tpXSwgcHJvdG8uZW51bV90eXBlKGkpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rRmllbGQoJm1lc3NhZ2UtPmZpZWxkc19baV0sIHByb3RvLmZpZWxkKGkpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIENyb3NzTGlua0ZpZWxkKCZtZXNzYWdlLT5leHRlbnNpb25zX1tpXSwgcHJvdG8uZXh0ZW5zaW9uKGkpKTsKKyAgfQorCisgIC8vIFNldCB1cCBmaWVsZCBhcnJheSBmb3IgZWFjaCBvbmVvZi4KKworICAvLyBGaXJzdCBjb3VudCB0aGUgbnVtYmVyIG9mIGZpZWxkcyBwZXIgb25lb2YuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZWNsID0gbWVzc2FnZS0+ZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKTsKKyAgICBpZiAob25lb2ZfZGVjbCAhPSBOVUxMKSB7CisgICAgICAvLyBNdXN0IGdvIHRocm91Z2ggb25lb2ZfZGVjbHNfIGFycmF5IHRvIGdldCBhIG5vbi1jb25zdCB2ZXJzaW9uIG9mIHRoZQorICAgICAgLy8gT25lb2ZEZXNjcmlwdG9yLgorICAgICAgKyttZXNzYWdlLT5vbmVvZl9kZWNsc19bb25lb2ZfZGVjbC0+aW5kZXgoKV0uZmllbGRfY291bnRfOworICAgIH0KKyAgfQorCisgIC8vIFRoZW4gYWxsb2NhdGUgdGhlIGFycmF5cy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVjbCA9ICZtZXNzYWdlLT5vbmVvZl9kZWNsc19baV07CisKKyAgICBpZiAob25lb2ZfZGVjbC0+ZmllbGRfY291bnQoKSA9PSAwKSB7CisgICAgICBBZGRFcnJvcihtZXNzYWdlLT5mdWxsX25hbWUoKSArICIuIiArIG9uZW9mX2RlY2wtPm5hbWUoKSwKKyAgICAgICAgICAgICAgIHByb3RvLm9uZW9mX2RlY2woaSksCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiT25lb2YgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBmaWVsZC4iKTsKKyAgICB9CisKKyAgICBvbmVvZl9kZWNsLT5maWVsZHNfID0KKyAgICAgIHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4ob25lb2ZfZGVjbC0+ZmllbGRfY291bnRfKTsKKyAgICBvbmVvZl9kZWNsLT5maWVsZF9jb3VudF8gPSAwOworICB9CisKKyAgLy8gVGhlbiBmaWxsIHRoZW0gaW4uCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZWNsID0gbWVzc2FnZS0+ZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKTsKKyAgICBpZiAob25lb2ZfZGVjbCAhPSBOVUxMKSB7CisgICAgICBPbmVvZkRlc2NyaXB0b3IqIG11dGFibGVfb25lb2ZfZGVjbCA9CisgICAgICAgICAgJm1lc3NhZ2UtPm9uZW9mX2RlY2xzX1tvbmVvZl9kZWNsLT5pbmRleCgpXTsKKyAgICAgIG1lc3NhZ2UtPmZpZWxkc19baV0uaW5kZXhfaW5fb25lb2ZfID0gbXV0YWJsZV9vbmVvZl9kZWNsLT5maWVsZF9jb3VudF87CisgICAgICBtdXRhYmxlX29uZW9mX2RlY2wtPmZpZWxkc19bbXV0YWJsZV9vbmVvZl9kZWNsLT5maWVsZF9jb3VudF8rK10gPQorICAgICAgICAgIG1lc3NhZ2UtPmZpZWxkKGkpOworICAgIH0KKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpDcm9zc0xpbmtGaWVsZCgKKyAgICBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKGZpZWxkLT5vcHRpb25zXyA9PSBOVUxMKSB7CisgICAgZmllbGQtPm9wdGlvbnNfID0gJkZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICB9CisKKyAgaWYgKHByb3RvLmhhc19leHRlbmRlZSgpKSB7CisgICAgU3ltYm9sIGV4dGVuZGVlID0gTG9va3VwU3ltYm9sKHByb3RvLmV4dGVuZGVlKCksIGZpZWxkLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUExBQ0VIT0xERVJfRVhURU5EQUJMRV9NRVNTQUdFKTsKKyAgICBpZiAoZXh0ZW5kZWUuSXNOdWxsKCkpIHsKKyAgICAgIEFkZE5vdERlZmluZWRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RVhURU5ERUUsCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8uZXh0ZW5kZWUoKSk7CisgICAgICByZXR1cm47CisgICAgfSBlbHNlIGlmIChleHRlbmRlZS50eXBlICE9IFN5bWJvbDo6TUVTU0FHRSkgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RVhURU5ERUUsCisgICAgICAgICAgICAgICAiXCIiICsgcHJvdG8uZXh0ZW5kZWUoKSArICJcIiBpcyBub3QgYSBtZXNzYWdlIHR5cGUuIik7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGVfID0gZXh0ZW5kZWUuZGVzY3JpcHRvcjsKKworICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiBleHRlbnNpb25fcmFuZ2UgPSBmaWVsZC0+Y29udGFpbmluZ190eXBlKCkKKyAgICAgICAgLT5GaW5kRXh0ZW5zaW9uUmFuZ2VDb250YWluaW5nTnVtYmVyKGZpZWxkLT5udW1iZXIoKSk7CisKKyAgICBpZiAoZXh0ZW5zaW9uX3JhbmdlID09IE5VTEwpIHsKKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5VTUJFUiwKKyAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIlwiJDBcIiBkb2VzIG5vdCBkZWNsYXJlICQxIGFzIGFuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImV4dGVuc2lvbiBudW1iZXIuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpKSk7CisgICAgfQorICB9CisKKyAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgIGlmIChmaWVsZC0+bGFiZWwoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMKSB7CisgICAgICAvLyBOb3RlIHRoYXQgdGhpcyBlcnJvciB3aWxsIG5ldmVyIGhhcHBlbiB3aGVuIHBhcnNpbmcgLnByb3RvIGZpbGVzLgorICAgICAgLy8gSXQgY2FuIG9ubHkgaGFwcGVuIGlmIHlvdSBtYW51YWxseSBjb25zdHJ1Y3QgYSBGaWxlRGVzY3JpcHRvclByb3RvCisgICAgICAvLyB0aGF0IGlzIGluY29ycmVjdC4KKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiRmllbGRzIG9mIG9uZW9mcyBtdXN0IHRoZW1zZWx2ZXMgaGF2ZSBsYWJlbCBMQUJFTF9PUFRJT05BTC4iKTsKKyAgICB9CisgIH0KKworICBpZiAocHJvdG8uaGFzX3R5cGVfbmFtZSgpKSB7CisgICAgLy8gQXNzdW1lIHdlIGFyZSBleHBlY3RpbmcgYSBtZXNzYWdlIHR5cGUgdW5sZXNzIHRoZSBwcm90byBjb250YWlucyBzb21lCisgICAgLy8gZXZpZGVuY2UgdGhhdCBpdCBleHBlY3RzIGFuIGVudW0gdHlwZS4gIFRoaXMgb25seSBtYWtlcyBhIGRpZmZlcmVuY2UgaWYKKyAgICAvLyB3ZSBlbmQgdXAgY3JlYXRpbmcgYSBwbGFjZWhvbGRlci4KKyAgICBib29sIGV4cGVjdGluZ19lbnVtID0gKHByb3RvLnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9FTlVNKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90by5oYXNfZGVmYXVsdF92YWx1ZSgpOworCisgICAgU3ltYm9sIHR5cGUgPQorICAgICAgTG9va3VwU3ltYm9sKHByb3RvLnR5cGVfbmFtZSgpLCBmaWVsZC0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgZXhwZWN0aW5nX2VudW0gPyBQTEFDRUhPTERFUl9FTlVNIDogUExBQ0VIT0xERVJfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICBMT09LVVBfVFlQRVMpOworCisgICAgLy8gSWYgdGhlIHR5cGUgaXMgYSB3ZWFrIHR5cGUsIHdlIGNoYW5nZSB0aGUgdHlwZSB0byBhIGdvb2dsZS5wcm90b2J1Zi5FbXB0eSBmaWVsZC4KKyAgICBpZiAodHlwZS5Jc051bGwoKSAmJiAhcG9vbF8tPmVuZm9yY2Vfd2Vha18gJiYgcHJvdG8ub3B0aW9ucygpLndlYWsoKSkgeworICAgICAgdHlwZSA9IEZpbmRTeW1ib2woa05vbkxpbmtlZFdlYWtNZXNzYWdlUmVwbGFjZW1lbnROYW1lKTsKKyAgICB9CisKKyAgICBpZiAodHlwZS5Jc051bGwoKSkgeworICAgICAgQWRkTm90RGVmaW5lZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLnR5cGVfbmFtZSgpKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoIXByb3RvLmhhc190eXBlKCkpIHsKKyAgICAgIC8vIENob29zZSBmaWVsZCB0eXBlIGJhc2VkIG9uIHN5bWJvbC4KKyAgICAgIGlmICh0eXBlLnR5cGUgPT0gU3ltYm9sOjpNRVNTQUdFKSB7CisgICAgICAgIGZpZWxkLT50eXBlXyA9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOworICAgICAgfSBlbHNlIGlmICh0eXBlLnR5cGUgPT0gU3ltYm9sOjpFTlVNKSB7CisgICAgICAgIGZpZWxkLT50eXBlXyA9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICAgICAiXCIiICsgcHJvdG8udHlwZV9uYW1lKCkgKyAiXCIgaXMgbm90IGEgdHlwZS4iKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgIH0KKworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgaWYgKHR5cGUudHlwZSAhPSBTeW1ib2w6Ok1FU1NBR0UpIHsKKyAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICAgICAiXCIiICsgcHJvdG8udHlwZV9uYW1lKCkgKyAiXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLiIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBmaWVsZC0+bWVzc2FnZV90eXBlXyA9IHR5cGUuZGVzY3JpcHRvcjsKKworICAgICAgaWYgKGZpZWxkLT5oYXNfZGVmYXVsdF92YWx1ZSgpKSB7CisgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6REVGQVVMVF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgIk1lc3NhZ2VzIGNhbid0IGhhdmUgZGVmYXVsdCB2YWx1ZXMuIik7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSkgeworICAgICAgaWYgKHR5cGUudHlwZSAhPSBTeW1ib2w6OkVOVU0pIHsKKyAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICAgICAiXCIiICsgcHJvdG8udHlwZV9uYW1lKCkgKyAiXCIgaXMgbm90IGFuIGVudW0gdHlwZS4iKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgZmllbGQtPmVudW1fdHlwZV8gPSB0eXBlLmVudW1fZGVzY3JpcHRvcjsKKworICAgICAgaWYgKGZpZWxkLT5lbnVtX3R5cGUoKS0+aXNfcGxhY2Vob2xkZXJfKSB7CisgICAgICAgIC8vIFdlIGNhbid0IGxvb2sgdXAgZGVmYXVsdCB2YWx1ZXMgZm9yIHBsYWNlaG9sZGVyIHR5cGVzLiAgV2UnbGwgaGF2ZQorICAgICAgICAvLyB0byBqdXN0IGRyb3AgdGhlbS4KKyAgICAgICAgZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlXyA9IGZhbHNlOworICAgICAgfQorCisgICAgICBpZiAoZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhlIGRlZmF1bHQgdmFsdWUgaXMgYW4gaWRlbnRpZmllci4gUGFyc2VyIGNhbm5vdCBhbHdheXMKKyAgICAgICAgLy8gdmVyaWZ5IHRoaXMgYmVjYXVzZSBpdCBkb2VzIG5vdCBoYXZlIGNvbXBsZXRlIHR5cGUgaW5mb3JtYXRpb24uCisgICAgICAgIC8vIE4uQi4gdGhhdCB0aGlzIGNoZWNrIHlpZWxkcyBiZXR0ZXIgZXJyb3IgbWVzc2FnZXMgYnV0IGlzIG5vdAorICAgICAgICAvLyBuZWNlc3NhcnkgZm9yIGNvcnJlY3RuZXNzIChhbiBlbnVtIHN5bWJvbCBtdXN0IGJlIGEgdmFsaWQgaWRlbnRpZmllcgorICAgICAgICAvLyBhbnl3YXkpLCBvbmx5IGZvciBiZXR0ZXIgZXJyb3JzLgorICAgICAgICBpZiAoIWlvOjpUb2tlbml6ZXI6OklzSWRlbnRpZmllcihwcm90by5kZWZhdWx0X3ZhbHVlKCkpKSB7CisgICAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgIkRlZmF1bHQgdmFsdWUgZm9yIGFuIGVudW0gZmllbGQgbXVzdCBiZSBhbiBpZGVudGlmaWVyLiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFdlIGNhbid0IGp1c3QgdXNlIGZpZWxkLT5lbnVtX3R5cGUoKS0+RmluZFZhbHVlQnlOYW1lKCkgaGVyZQorICAgICAgICAgIC8vIGJlY2F1c2UgdGhhdCBsb2NrcyB0aGUgcG9vbCdzIG11dGV4LCB3aGljaCB3ZSBoYXZlIGFscmVhZHkgbG9ja2VkCisgICAgICAgICAgLy8gYXQgdGhpcyBwb2ludC4KKyAgICAgICAgICBTeW1ib2wgZGVmYXVsdF92YWx1ZSA9CisgICAgICAgICAgICBMb29rdXBTeW1ib2xOb1BsYWNlaG9sZGVyKHByb3RvLmRlZmF1bHRfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5mdWxsX25hbWUoKSk7CisKKyAgICAgICAgICBpZiAoZGVmYXVsdF92YWx1ZS50eXBlID09IFN5bWJvbDo6RU5VTV9WQUxVRSAmJgorICAgICAgICAgICAgICBkZWZhdWx0X3ZhbHVlLmVudW1fdmFsdWVfZGVzY3JpcHRvci0+dHlwZSgpID09CisgICAgICAgICAgICAgIGZpZWxkLT5lbnVtX3R5cGUoKSkgeworICAgICAgICAgICAgZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bV8gPSBkZWZhdWx0X3ZhbHVlLmVudW1fdmFsdWVfZGVzY3JpcHRvcjsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6REVGQVVMVF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgICJFbnVtIHR5cGUgXCIiICsgZmllbGQtPmVudW1fdHlwZSgpLT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAiXCIgaGFzIG5vIHZhbHVlIG5hbWVkIFwiIiArIHByb3RvLmRlZmF1bHRfdmFsdWUoKSArCisgICAgICAgICAgICAgICAgICAgICAiXCIuIik7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKGZpZWxkLT5lbnVtX3R5cGUoKS0+dmFsdWVfY291bnQoKSA+IDApIHsKKyAgICAgICAgLy8gQWxsIGVudW1zIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgdmFsdWUsIG9yIHdlIHdvdWxkIGhhdmUgcmVwb3J0ZWQKKyAgICAgICAgLy8gYW4gZXJyb3IgZWxzZXdoZXJlLiAgV2UgdXNlIHRoZSBmaXJzdCBkZWZpbmVkIHZhbHVlIGFzIHRoZSBkZWZhdWx0CisgICAgICAgIC8vIGlmIGEgZGVmYXVsdCBpcyBub3QgZXhwbGljaXRseSBkZWZpbmVkLgorICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtXyA9IGZpZWxkLT5lbnVtX3R5cGUoKS0+dmFsdWUoMCk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICJGaWVsZCB3aXRoIHByaW1pdGl2ZSB0eXBlIGhhcyB0eXBlX25hbWUuIik7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSB8fAorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSkgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICAgIkZpZWxkIHdpdGggbWVzc2FnZSBvciBlbnVtIHR5cGUgbWlzc2luZyB0eXBlX25hbWUuIik7CisgICAgfQorICB9CisKKyAgLy8gQWRkIHRoZSBmaWVsZCB0byB0aGUgZmllbGRzLWJ5LW51bWJlciB0YWJsZS4KKyAgLy8gTm90ZTogIFdlIGhhdmUgdG8gZG8gdGhpcyAqYWZ0ZXIqIGNyb3NzLWxpbmtpbmcgYmVjYXVzZSBleHRlbnNpb25zIGRvIG5vdAorICAvLyAgIGtub3cgdGhlaXIgY29udGFpbmluZyB0eXBlIHVudGlsIG5vdy4KKyAgaWYgKCFmaWxlX3RhYmxlc18tPkFkZEZpZWxkQnlOdW1iZXIoZmllbGQpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBjb25mbGljdGluZ19maWVsZCA9CisgICAgICBmaWxlX3RhYmxlc18tPkZpbmRGaWVsZEJ5TnVtYmVyKGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpKTsKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKCJFeHRlbnNpb24gbnVtYmVyICQwIGhhcyBhbHJlYWR5IGJlZW4gdXNlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbiBcIiQxXCIgYnkgZXh0ZW5zaW9uIFwiJDJcIi4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZsaWN0aW5nX2ZpZWxkLT5mdWxsX25hbWUoKSkpOworICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKCJGaWVsZCBudW1iZXIgJDAgaGFzIGFscmVhZHkgYmVlbiB1c2VkIGluICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiJDFcIiBieSBmaWVsZCBcIiQyXCIuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mbGljdGluZ19maWVsZC0+bmFtZSgpKSk7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIGlmICghdGFibGVzXy0+QWRkRXh0ZW5zaW9uKGZpZWxkKSkgeworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGNvbmZsaWN0aW5nX2ZpZWxkID0KKyAgICAgICAgICAgIHRhYmxlc18tPkZpbmRFeHRlbnNpb24oZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBmaWVsZC0+bnVtYmVyKCkpOworICAgICAgICBzdHJpbmcgZXJyb3JfbXNnID0gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAgICJFeHRlbnNpb24gbnVtYmVyICQwIGhhcyBhbHJlYWR5IGJlZW4gdXNlZCBpbiBcIiQxXCIgYnkgZXh0ZW5zaW9uICIKKyAgICAgICAgICAgICJcIiQyXCIgZGVmaW5lZCBpbiAkMy4iLAorICAgICAgICAgICAgZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgIGNvbmZsaWN0aW5nX2ZpZWxkLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgIGNvbmZsaWN0aW5nX2ZpZWxkLT5maWxlKCktPm5hbWUoKSk7CisgICAgICAgIC8vIENvbmZsaWN0aW5nIGV4dGVuc2lvbiBudW1iZXJzIHNob3VsZCBiZSBhbiBlcnJvci4gSG93ZXZlciwgYmVmb3JlCisgICAgICAgIC8vIHR1cm5pbmcgdGhpcyBpbnRvIGFuIGVycm9yIHdlIG5lZWQgdG8gZml4IGFsbCBleGlzdGluZyBicm9rZW4KKyAgICAgICAgLy8gcHJvdG9zIGZpcnN0LgorICAgICAgICAvLyBUT0RPKHhpYW9mZW5nKTogQ2hhbmdlIHRoaXMgdG8gYW4gZXJyb3IuCisgICAgICAgIEFkZFdhcm5pbmcoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5VTUJFUiwgZXJyb3JfbXNnKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBBZGQgdGhlIGZpZWxkIHRvIHRoZSBsb3dlcmNhc2UtbmFtZSBhbmQgY2FtZWxjYXNlLW5hbWUgdGFibGVzLgorICBmaWxlX3RhYmxlc18tPkFkZEZpZWxkQnlTdHlsaXplZE5hbWVzKGZpZWxkKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6Q3Jvc3NMaW5rRW51bSgKKyAgICBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlLCBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBpZiAoZW51bV90eXBlLT5vcHRpb25zXyA9PSBOVUxMKSB7CisgICAgZW51bV90eXBlLT5vcHRpb25zXyA9ICZFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtX3R5cGUtPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIENyb3NzTGlua0VudW1WYWx1ZSgmZW51bV90eXBlLT52YWx1ZXNfW2ldLCBwcm90by52YWx1ZShpKSk7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6Q3Jvc3NMaW5rRW51bVZhbHVlKAorICAgIEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUsCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiAvKiBwcm90byAqLykgeworICBpZiAoZW51bV92YWx1ZS0+b3B0aW9uc18gPT0gTlVMTCkgeworICAgIGVudW1fdmFsdWUtPm9wdGlvbnNfID0gJkVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpDcm9zc0xpbmtTZXJ2aWNlKAorICAgIFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlLCBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBpZiAoc2VydmljZS0+b3B0aW9uc18gPT0gTlVMTCkgeworICAgIHNlcnZpY2UtPm9wdGlvbnNfID0gJlNlcnZpY2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2UtPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtNZXRob2QoJnNlcnZpY2UtPm1ldGhvZHNfW2ldLCBwcm90by5tZXRob2QoaSkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkNyb3NzTGlua01ldGhvZCgKKyAgICBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsIGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKG1ldGhvZC0+b3B0aW9uc18gPT0gTlVMTCkgeworICAgIG1ldGhvZC0+b3B0aW9uc18gPSAmTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICB9CisKKyAgU3ltYm9sIGlucHV0X3R5cGUgPSBMb29rdXBTeW1ib2wocHJvdG8uaW5wdXRfdHlwZSgpLCBtZXRob2QtPmZ1bGxfbmFtZSgpKTsKKyAgaWYgKGlucHV0X3R5cGUuSXNOdWxsKCkpIHsKKyAgICBBZGROb3REZWZpbmVkRXJyb3IobWV0aG9kLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6SU5QVVRfVFlQRSwKKyAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8uaW5wdXRfdHlwZSgpKTsKKyAgfSBlbHNlIGlmIChpbnB1dF90eXBlLnR5cGUgIT0gU3ltYm9sOjpNRVNTQUdFKSB7CisgICAgQWRkRXJyb3IobWV0aG9kLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpJTlBVVF9UWVBFLAorICAgICAgICAgICAgICJcIiIgKyBwcm90by5pbnB1dF90eXBlKCkgKyAiXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLiIpOworICB9IGVsc2UgeworICAgIG1ldGhvZC0+aW5wdXRfdHlwZV8gPSBpbnB1dF90eXBlLmRlc2NyaXB0b3I7CisgIH0KKworICBTeW1ib2wgb3V0cHV0X3R5cGUgPSBMb29rdXBTeW1ib2wocHJvdG8ub3V0cHV0X3R5cGUoKSwgbWV0aG9kLT5mdWxsX25hbWUoKSk7CisgIGlmIChvdXRwdXRfdHlwZS5Jc051bGwoKSkgeworICAgIEFkZE5vdERlZmluZWRFcnJvcihtZXRob2QtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVVRQVVRfVFlQRSwKKyAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8ub3V0cHV0X3R5cGUoKSk7CisgIH0gZWxzZSBpZiAob3V0cHV0X3R5cGUudHlwZSAhPSBTeW1ib2w6Ok1FU1NBR0UpIHsKKyAgICBBZGRFcnJvcihtZXRob2QtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9VVFBVVF9UWVBFLAorICAgICAgICAgICAgICJcIiIgKyBwcm90by5vdXRwdXRfdHlwZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4iKTsKKyAgfSBlbHNlIHsKKyAgICBtZXRob2QtPm91dHB1dF90eXBlXyA9IG91dHB1dF90eXBlLmRlc2NyaXB0b3I7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShkZXNjcmlwdG9yLCBhcnJheV9uYW1lLCB0eXBlKSAgXAorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmFycmF5X25hbWUjI19jb3VudCgpOyArK2kpIHsgICAgIFwKKyAgICBWYWxpZGF0ZSMjdHlwZSMjT3B0aW9ucyhkZXNjcmlwdG9yLT5hcnJheV9uYW1lIyNzXyArIGksICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8uYXJyYXlfbmFtZShpKSk7ICAgICAgICAgICAgICAgICAgXAorICB9CisKKy8vIERldGVybWluZSBpZiB0aGUgZmlsZSB1c2VzIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRSwgYmVpbmcgY2FyZWZ1bCB0bworLy8gYXZvaWQgcHJvYmxlbXMgdGhhdCBleGlzdCBhdCBpbml0IHRpbWUuCitzdGF0aWMgYm9vbCBJc0xpdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgLy8gVE9ETyhrZW50b24pOiAgSSBkb24ndCBldmVuIHJlbWVtYmVyIGhvdyBtYW55IG9mIHRoZXNlIGNvbmRpdGlvbnMgYXJlCisgIC8vICAgYWN0dWFsbHkgcG9zc2libGUuICBJJ20ganVzdCBiZWluZyBzdXBlci1zYWZlLgorICByZXR1cm4gZmlsZSAhPSBOVUxMICYmCisgICAgICAgICAmZmlsZS0+b3B0aW9ucygpICE9ICZGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpICYmCisgICAgICAgICBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgPT0gRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVGaWxlT3B0aW9ucyhGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgVkFMSURBVEVfT1BUSU9OU19GUk9NX0FSUkFZKGZpbGUsIG1lc3NhZ2VfdHlwZSwgTWVzc2FnZSk7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShmaWxlLCBlbnVtX3R5cGUsIEVudW0pOworICBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkoZmlsZSwgc2VydmljZSwgU2VydmljZSk7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShmaWxlLCBleHRlbnNpb24sIEZpZWxkKTsKKworICAvLyBMaXRlIGZpbGVzIGNhbiBvbmx5IGJlIGltcG9ydGVkIGJ5IG90aGVyIExpdGUgZmlsZXMuCisgIGlmICghSXNMaXRlKGZpbGUpKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKElzTGl0ZShmaWxlLT5kZXBlbmRlbmN5KGkpKSkgeworICAgICAgICBBZGRFcnJvcigKKyAgICAgICAgICBmaWxlLT5uYW1lKCksIHByb3RvLAorICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgIkZpbGVzIHRoYXQgZG8gbm90IHVzZSBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUgY2Fubm90IGltcG9ydCAiCisgICAgICAgICAgImZpbGVzIHdoaWNoIGRvIHVzZSB0aGlzIG9wdGlvbi4gIFRoaXMgZmlsZSBpcyBub3QgbGl0ZSwgYnV0IGl0ICIKKyAgICAgICAgICAiaW1wb3J0cyBcIiIgKyBmaWxlLT5kZXBlbmRlbmN5KGkpLT5uYW1lKCkgKyAiXCIgd2hpY2ggaXMuIik7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorICBpZiAoZmlsZS0+c3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzMpIHsKKyAgICBWYWxpZGF0ZVByb3RvMyhmaWxlLCBwcm90byk7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVQcm90bzMoCisgICAgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIFZhbGlkYXRlUHJvdG8zRmllbGQoZmlsZS0+ZXh0ZW5zaW9uc18gKyBpLCBwcm90by5leHRlbnNpb24oaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIFZhbGlkYXRlUHJvdG8zTWVzc2FnZShmaWxlLT5tZXNzYWdlX3R5cGVzXyArIGksIHByb3RvLm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgVmFsaWRhdGVQcm90bzNFbnVtKGZpbGUtPmVudW1fdHlwZXNfICsgaSwgcHJvdG8uZW51bV90eXBlKGkpKTsKKyAgfQorICBpZiAoSXNMaXRlKGZpbGUpKSB7CisgICAgQWRkRXJyb3IoZmlsZS0+bmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICJMaXRlIHJ1bnRpbWUgaXMgbm90IHN1cHBvcnRlZCBpbiBwcm90bzMuIik7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVQcm90bzNNZXNzYWdlKAorICAgIERlc2NyaXB0b3IqIG1lc3NhZ2UsIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBWYWxpZGF0ZVByb3RvM01lc3NhZ2UobWVzc2FnZS0+bmVzdGVkX3R5cGVzXyArIGksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90by5uZXN0ZWRfdHlwZShpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgVmFsaWRhdGVQcm90bzNFbnVtKG1lc3NhZ2UtPmVudW1fdHlwZXNfICsgaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLmVudW1fdHlwZShpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICBWYWxpZGF0ZVByb3RvM0ZpZWxkKG1lc3NhZ2UtPmZpZWxkc18gKyBpLCBwcm90by5maWVsZChpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5leHRlbnNpb25fY291bnQoKTsgKytpKSB7CisgICAgVmFsaWRhdGVQcm90bzNGaWVsZChtZXNzYWdlLT5leHRlbnNpb25zXyAraSwgcHJvdG8uZXh0ZW5zaW9uKGkpKTsKKyAgfQorICBpZiAobWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgQWRkRXJyb3IobWVzc2FnZS0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgIkV4dGVuc2lvbiByYW5nZXMgYXJlIG5vdCBhbGxvd2VkIGluIHByb3RvMy4iKTsKKyAgfQorICBpZiAobWVzc2FnZS0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAvLyBVc2luZyBNZXNzYWdlU2V0IGRvZXNuJ3QgbWFrZSBzZW5zZSBzaW5jZSB3ZSBkaXNhbGxvdyBleHRlbnNpb25zLgorICAgIEFkZEVycm9yKG1lc3NhZ2UtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICJNZXNzYWdlU2V0IGlzIG5vdCBzdXBwb3J0ZWQgaW4gcHJvdG8zLiIpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlUHJvdG8zRmllbGQoCisgICAgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkgJiYKKyAgICAgICFBbGxvd2VkRXh0ZW5kZWVJblByb3RvMyhmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpKSkgeworICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAiRXh0ZW5zaW9ucyBpbiBwcm90bzMgYXJlIG9ubHkgYWxsb3dlZCBmb3IgZGVmaW5pbmcgb3B0aW9ucy4iKTsKKyAgfQorICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgIlJlcXVpcmVkIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQgaW4gcHJvdG8zLiIpOworICB9CisgIGlmIChmaWVsZC0+aGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIEFkZEVycm9yKAorICAgICAgICBmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAiRXhwbGljaXQgZGVmYXVsdCB2YWx1ZXMgYXJlIG5vdCBhbGxvd2VkIGluIHByb3RvMy4iKTsKKyAgfQorICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gJiYKKyAgICAgIGZpZWxkLT5lbnVtX3R5cGUoKSAmJgorICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5maWxlKCktPnN5bnRheCgpICE9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zKSB7CisgICAgLy8gUHJvdG8zIG1lc3NhZ2VzIGNhbiBvbmx5IHVzZSBQcm90bzMgZW51bSB0eXBlczsgb3RoZXJ3aXNlIHdlIGNhbid0CisgICAgLy8gZ3VhcmFudGVlIHRoYXQgdGhlIGRlZmF1bHQgdmFsdWUgaXMgemVyby4KKyAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAiRW51bSB0eXBlIFwiIiArIGZpZWxkLT5lbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICJcIiBpcyBub3QgYSBwcm90bzMgZW51bSwgYnV0IGlzIHVzZWQgaW4gXCIiICsKKyAgICAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICAiXCIgd2hpY2ggaXMgYSBwcm90bzMgbWVzc2FnZSB0eXBlLiIpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlUHJvdG8zRW51bSgKKyAgICBFbnVtRGVzY3JpcHRvciogZW5tLCBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBpZiAoZW5tLT52YWx1ZV9jb3VudCgpID4gMCAmJiBlbm0tPnZhbHVlKDApLT5udW1iZXIoKSAhPSAwKSB7CisgICAgQWRkRXJyb3IoCisgICAgICAgIGVubS0+ZnVsbF9uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAiVGhlIGZpcnN0IGVudW0gdmFsdWUgbXVzdCBiZSB6ZXJvIGluIHByb3RvMy4iKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZU1lc3NhZ2VPcHRpb25zKERlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgVkFMSURBVEVfT1BUSU9OU19GUk9NX0FSUkFZKG1lc3NhZ2UsIGZpZWxkLCBGaWVsZCk7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShtZXNzYWdlLCBuZXN0ZWRfdHlwZSwgTWVzc2FnZSk7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShtZXNzYWdlLCBlbnVtX3R5cGUsIEVudW0pOworICBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkobWVzc2FnZSwgZXh0ZW5zaW9uLCBGaWVsZCk7CisKKyAgY29uc3QgaW50NjQgbWF4X2V4dGVuc2lvbl9yYW5nZSA9CisgICAgICBzdGF0aWNfY2FzdDxpbnQ2ND4obWVzc2FnZS0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgPworICAgICAgICAgICAgICAgICAgICAgICAgIGtpbnQzMm1heCA6CisgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKTsgKytpKSB7CisgICAgaWYgKG1lc3NhZ2UtPmV4dGVuc2lvbl9yYW5nZShpKS0+ZW5kID4gbWF4X2V4dGVuc2lvbl9yYW5nZSArIDEpIHsKKyAgICAgIEFkZEVycm9yKAorICAgICAgICAgIG1lc3NhZ2UtPmZ1bGxfbmFtZSgpLCBwcm90by5leHRlbnNpb25fcmFuZ2UoaSksCisgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZSgiRXh0ZW5zaW9uIG51bWJlcnMgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiAkMC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4X2V4dGVuc2lvbl9yYW5nZSkpOworICAgIH0KKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZUZpZWxkT3B0aW9ucyhGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICAvLyBPbmx5IG1lc3NhZ2UgdHlwZSBmaWVsZHMgbWF5IGJlIGxhenkuCisgIGlmIChmaWVsZC0+b3B0aW9ucygpLmxhenkoKSkgeworICAgIGlmIChmaWVsZC0+dHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFKSB7CisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICAgIltsYXp5ID0gdHJ1ZV0gY2FuIG9ubHkgYmUgc3BlY2lmaWVkIGZvciBzdWJtZXNzYWdlIGZpZWxkcy4iKTsKKyAgICB9CisgIH0KKworICAvLyBPbmx5IHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZHMgbWF5IGJlIHBhY2tlZC4KKyAgaWYgKGZpZWxkLT5vcHRpb25zKCkucGFja2VkKCkgJiYgIWZpZWxkLT5pc19wYWNrYWJsZSgpKSB7CisgICAgQWRkRXJyb3IoCisgICAgICBmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgIltwYWNrZWQgPSB0cnVlXSBjYW4gb25seSBiZSBzcGVjaWZpZWQgZm9yIHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZHMuIik7CisgIH0KKworICAvLyBOb3RlOiAgRGVmYXVsdCBpbnN0YW5jZSBtYXkgbm90IHlldCBiZSBpbml0aWFsaXplZCBoZXJlLCBzbyB3ZSBoYXZlIHRvCisgIC8vICAgYXZvaWQgcmVhZGluZyBmcm9tIGl0LgorICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfdHlwZV8gIT0gTlVMTCAmJgorICAgICAgJmZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+b3B0aW9ucygpICE9CisgICAgICAmTWVzc2FnZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSAmJgorICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIGlmICghZmllbGQtPmlzX29wdGlvbmFsKCkgfHwKKyAgICAgICAgICBmaWVsZC0+dHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFKSB7CisgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICAgIkV4dGVuc2lvbnMgb2YgTWVzc2FnZVNldHMgbXVzdCBiZSBvcHRpb25hbCBtZXNzYWdlcy4iKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAgICJNZXNzYWdlU2V0cyBjYW5ub3QgaGF2ZSBmaWVsZHMsIG9ubHkgZXh0ZW5zaW9ucy4iKTsKKyAgICB9CisgIH0KKworICAvLyBMaXRlIGV4dGVuc2lvbnMgY2FuIG9ubHkgYmUgb2YgTGl0ZSB0eXBlcy4KKyAgaWYgKElzTGl0ZShmaWVsZC0+ZmlsZSgpKSAmJgorICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZV8gIT0gTlVMTCAmJgorICAgICAgIUlzTGl0ZShmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZpbGUoKSkpIHsKKyAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RVhURU5ERUUsCisgICAgICAgICAgICAgIkV4dGVuc2lvbnMgdG8gbm9uLWxpdGUgdHlwZXMgY2FuIG9ubHkgYmUgZGVjbGFyZWQgaW4gbm9uLWxpdGUgIgorICAgICAgICAgICAgICJmaWxlcy4gIE5vdGUgdGhhdCB5b3UgY2Fubm90IGV4dGVuZCBhIG5vbi1saXRlIHR5cGUgdG8gY29udGFpbiAiCisgICAgICAgICAgICAgImEgbGl0ZSB0eXBlLCBidXQgdGhlIHJldmVyc2UgaXMgYWxsb3dlZC4iKTsKKyAgfQorCisgIC8vIFZhbGlkYXRlIG1hcCB0eXBlcy4KKyAgaWYgKGZpZWxkLT5pc19tYXAoKSkgeworICAgIGlmICghVmFsaWRhdGVNYXBFbnRyeShmaWVsZCwgcHJvdG8pKSB7CisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAgICJtYXBfZW50cnkgc2hvdWxkIG5vdCBiZSBzZXQgZXhwbGljaXRseS4gVXNlIG1hcDxLZXlUeXBlLCAiCisgICAgICAgICAgICAgICAiVmFsdWVUeXBlPiBpbnN0ZWFkLiIpOworICAgIH0KKyAgfQorCit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlRW51bU9wdGlvbnMoRW51bURlc2NyaXB0b3IqIGVubSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgVkFMSURBVEVfT1BUSU9OU19GUk9NX0FSUkFZKGVubSwgdmFsdWUsIEVudW1WYWx1ZSk7CisgIGlmICghZW5tLT5vcHRpb25zKCkuaGFzX2FsbG93X2FsaWFzKCkgfHwgIWVubS0+b3B0aW9ucygpLmFsbG93X2FsaWFzKCkpIHsKKyAgICBtYXA8aW50LCBzdHJpbmc+IHVzZWRfdmFsdWVzOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW5tLT52YWx1ZV9jb3VudCgpOyArK2kpIHsKKyAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPSBlbm0tPnZhbHVlKGkpOworICAgICAgaWYgKHVzZWRfdmFsdWVzLmZpbmQoZW51bV92YWx1ZS0+bnVtYmVyKCkpICE9IHVzZWRfdmFsdWVzLmVuZCgpKSB7CisgICAgICAgIHN0cmluZyBlcnJvciA9CisgICAgICAgICAgICAiXCIiICsgZW51bV92YWx1ZS0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgIlwiIHVzZXMgdGhlIHNhbWUgZW51bSB2YWx1ZSBhcyBcIiIgKworICAgICAgICAgICAgdXNlZF92YWx1ZXNbZW51bV92YWx1ZS0+bnVtYmVyKCldICsgIlwiLiBJZiB0aGlzIGlzIGludGVuZGVkLCBzZXQgIgorICAgICAgICAgICAgIidvcHRpb24gYWxsb3dfYWxpYXMgPSB0cnVlOycgdG8gdGhlIGVudW0gZGVmaW5pdGlvbi4iOworICAgICAgICBpZiAoIWVubS0+b3B0aW9ucygpLmFsbG93X2FsaWFzKCkpIHsKKyAgICAgICAgICAvLyBHZW5lcmF0ZSBlcnJvciBpZiBkdXBsaWNhdGVkIGVudW0gdmFsdWVzIGFyZSBleHBsaWNpdGx5IGRpc2FsbG93ZWQuCisgICAgICAgICAgQWRkRXJyb3IoZW5tLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICAgICAgZXJyb3IpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIEdlbmVyYXRlIHdhcm5pbmcgaWYgZHVwbGljYXRlZCB2YWx1ZXMgYXJlIGZvdW5kIGJ1dCB0aGUgb3B0aW9uCisgICAgICAgICAgLy8gaXNuJ3Qgc2V0LgorICAgICAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8IGVycm9yOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICB1c2VkX3ZhbHVlc1tlbnVtX3ZhbHVlLT5udW1iZXIoKV0gPSBlbnVtX3ZhbHVlLT5mdWxsX25hbWUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVFbnVtVmFsdWVPcHRpb25zKAorICAgIEVudW1WYWx1ZURlc2NyaXB0b3IqIC8qIGVudW1fdmFsdWUgKi8sCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiAvKiBwcm90byAqLykgeworICAvLyBOb3RoaW5nIHRvIGRvIHNvIGZhci4KK30KK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlU2VydmljZU9wdGlvbnMoU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UsCisgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKElzTGl0ZShzZXJ2aWNlLT5maWxlKCkpICYmCisgICAgICAoc2VydmljZS0+ZmlsZSgpLT5vcHRpb25zKCkuY2NfZ2VuZXJpY19zZXJ2aWNlcygpIHx8CisgICAgICAgc2VydmljZS0+ZmlsZSgpLT5vcHRpb25zKCkuamF2YV9nZW5lcmljX3NlcnZpY2VzKCkpKSB7CisgICAgQWRkRXJyb3Ioc2VydmljZS0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAiRmlsZXMgd2l0aCBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUgY2Fubm90IGRlZmluZSBzZXJ2aWNlcyAiCisgICAgICAgICAgICAgInVubGVzcyB5b3Ugc2V0IGJvdGggb3B0aW9ucyBjY19nZW5lcmljX3NlcnZpY2VzIGFuZCAiCisgICAgICAgICAgICAgImphdmFfZ2VuZXJpY19zZXZpY2VzIHRvIGZhbHNlLiIpOworICB9CisKKyAgVkFMSURBVEVfT1BUSU9OU19GUk9NX0FSUkFZKHNlcnZpY2UsIG1ldGhvZCwgTWV0aG9kKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVNZXRob2RPcHRpb25zKE1ldGhvZERlc2NyaXB0b3IqIC8qIG1ldGhvZCAqLywKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIC8qIHByb3RvICovKSB7CisgIC8vIE5vdGhpbmcgdG8gZG8gc28gZmFyLgorfQorCitib29sIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZU1hcEVudHJ5KEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpOworICBpZiAoLy8gTXVzdCBub3QgY29udGFpbiBleHRlbnNpb25zLCBleHRlbnNpb24gcmFuZ2Ugb3IgbmVzdGVkIG1lc3NhZ2Ugb3IKKyAgICAgIC8vIGVudW1zCisgICAgICBtZXNzYWdlLT5leHRlbnNpb25fY291bnQoKSAhPSAwIHx8CisgICAgICBmaWVsZC0+bGFiZWwoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEIHx8CisgICAgICBtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSAhPSAwIHx8CisgICAgICBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9jb3VudCgpICE9IDAgfHwgbWVzc2FnZS0+ZW51bV90eXBlX2NvdW50KCkgIT0gMCB8fAorICAgICAgLy8gTXVzdCBjb250YWluIGV4YWN0bHkgdHdvIGZpZWxkcworICAgICAgbWVzc2FnZS0+ZmllbGRfY291bnQoKSAhPSAyIHx8CisgICAgICAvLyBGaWVsZCBuYW1lIGFuZCBtZXNzYWdlIG5hbWUgbXVzdCBtYXRjaAorICAgICAgbWVzc2FnZS0+bmFtZSgpICE9IFRvQ2FtZWxDYXNlKGZpZWxkLT5uYW1lKCksIGZhbHNlKSArICJFbnRyeSIgfHwKKyAgICAgIC8vIEVudHJ5IG1lc3NhZ2UgbXVzdCBiZSBpbiB0aGUgc2FtZSBjb250YWluaW5nIHR5cGUgb2YgdGhlIGZpZWxkLgorICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpICE9IG1lc3NhZ2UtPmNvbnRhaW5pbmdfdHlwZSgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPSBtZXNzYWdlLT5maWVsZCgwKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9IG1lc3NhZ2UtPmZpZWxkKDEpOworICBpZiAoa2V5LT5sYWJlbCgpICE9IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwgfHwga2V5LT5udW1iZXIoKSAhPSAxIHx8CisgICAgICBrZXktPm5hbWUoKSAhPSAia2V5IikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAodmFsdWUtPmxhYmVsKCkgIT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTCB8fAorICAgICAgdmFsdWUtPm51bWJlcigpICE9IDIgfHwgdmFsdWUtPm5hbWUoKSAhPSAidmFsdWUiKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gQ2hlY2sga2V5IHR5cGVzIGFyZSBsZWdhbC4KKyAgc3dpdGNoIChrZXktPnR5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06CisgICAgICBBZGRFcnJvcigKKyAgICAgICAgICBmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OlRZUEUsCisgICAgICAgICAgIktleSBpbiBtYXAgZmllbGRzIGNhbm5vdCBiZSBlbnVtIHR5cGVzLiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0U6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVA6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6CisgICAgICBBZGRFcnJvcigKKyAgICAgICAgICBmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OlRZUEUsCisgICAgICAgICAgIktleSBpbiBtYXAgZmllbGRzIGNhbm5vdCBiZSBmbG9hdC9kb3VibGUsIGJ5dGVzIG9yIG1lc3NhZ2UgdHlwZXMuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OgorICAgICAgLy8gTGVnYWwgY2FzZXMKKyAgICAgIGJyZWFrOworICAgIC8vIERvIG5vdCBhZGQgYSBkZWZhdWx0LCBzbyB0aGF0IHRoZSBjb21waWxlciB3aWxsIGNvbXBsYWluIHdoZW4gbmV3IHR5cGVzCisgICAgLy8gYXJlIGFkZGVkLgorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkRldGVjdE1hcENvbmZsaWN0cyhjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgbWFwPHN0cmluZywgY29uc3QgRGVzY3JpcHRvcio+IHNlZW5fdHlwZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRGVzY3JpcHRvciogbmVzdGVkID0gbWVzc2FnZS0+bmVzdGVkX3R5cGUoaSk7CisgICAgcGFpcjxtYXA8c3RyaW5nLCBjb25zdCBEZXNjcmlwdG9yKj46Oml0ZXJhdG9yLCBib29sPiByZXN1bHQgPQorICAgICAgICBzZWVuX3R5cGVzLmluc2VydChzdGQ6Om1ha2VfcGFpcihuZXN0ZWQtPm5hbWUoKSwgbmVzdGVkKSk7CisgICAgaWYgKCFyZXN1bHQuc2Vjb25kKSB7CisgICAgICBpZiAocmVzdWx0LmZpcnN0LT5zZWNvbmQtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSB8fAorICAgICAgICAgIG5lc3RlZC0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgICAgIEFkZEVycm9yKG1lc3NhZ2UtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgICAiRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgIiArIG5lc3RlZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICAgIiBjb25mbGljdHMgd2l0aCBhbiBleGlzdGluZyBuZXN0ZWQgbWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgIH0KKyAgICAvLyBSZWN1cnNpdmVseSB0ZXN0IG9uIHRoZSBuZXN0ZWQgdHlwZXMuCisgICAgRGV0ZWN0TWFwQ29uZmxpY3RzKG1lc3NhZ2UtPm5lc3RlZF90eXBlKGkpLCBwcm90by5uZXN0ZWRfdHlwZShpKSk7CisgIH0KKyAgLy8gQ2hlY2sgZm9yIGNvbmZsaWN0ZWQgZmllbGQgbmFtZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG1lc3NhZ2UtPmZpZWxkKGkpOworICAgIG1hcDxzdHJpbmcsIGNvbnN0IERlc2NyaXB0b3IqPjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgIHNlZW5fdHlwZXMuZmluZChmaWVsZC0+bmFtZSgpKTsKKyAgICBpZiAoaXRlciAhPSBzZWVuX3R5cGVzLmVuZCgpICYmIGl0ZXItPnNlY29uZC0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgICBBZGRFcnJvcihtZXNzYWdlLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgIiArIGl0ZXItPnNlY29uZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICIgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgZmllbGQuIik7CisgICAgfQorICB9CisgIC8vIENoZWNrIGZvciBjb25mbGljdGVkIGVudW0gbmFtZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2MgPSBtZXNzYWdlLT5lbnVtX3R5cGUoaSk7CisgICAgbWFwPHN0cmluZywgY29uc3QgRGVzY3JpcHRvcio+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgc2Vlbl90eXBlcy5maW5kKGVudW1fZGVzYy0+bmFtZSgpKTsKKyAgICBpZiAoaXRlciAhPSBzZWVuX3R5cGVzLmVuZCgpICYmIGl0ZXItPnNlY29uZC0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgICBBZGRFcnJvcihtZXNzYWdlLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgIiArIGl0ZXItPnNlY29uZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICIgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgZW51bSB0eXBlLiIpOworICAgIH0KKyAgfQorICAvLyBDaGVjayBmb3IgY29uZmxpY3RlZCBvbmVvZiBuYW1lcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzYyA9IG1lc3NhZ2UtPm9uZW9mX2RlY2woaSk7CisgICAgbWFwPHN0cmluZywgY29uc3QgRGVzY3JpcHRvcio+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgc2Vlbl90eXBlcy5maW5kKG9uZW9mX2Rlc2MtPm5hbWUoKSk7CisgICAgaWYgKGl0ZXIgIT0gc2Vlbl90eXBlcy5lbmQoKSAmJiBpdGVyLT5zZWNvbmQtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSkgeworICAgICAgQWRkRXJyb3IobWVzc2FnZS0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgIkV4cGFuZGVkIG1hcCBlbnRyeSB0eXBlICIgKyBpdGVyLT5zZWNvbmQtPm5hbWUoKSArCisgICAgICAgICAgICAgICAiIGNvbmZsaWN0cyB3aXRoIGFuIGV4aXN0aW5nIG9uZW9mIHR5cGUuIik7CisgICAgfQorICB9Cit9CisKKworI3VuZGVmIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0Rlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6T3B0aW9uSW50ZXJwcmV0ZXIoCisgICAgRGVzY3JpcHRvckJ1aWxkZXIqIGJ1aWxkZXIpIDogYnVpbGRlcl8oYnVpbGRlcikgeworICBHT09HTEVfQ0hFQ0soYnVpbGRlcl8pOworfQorCitEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6On5PcHRpb25JbnRlcnByZXRlcigpIHsKK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OkludGVycHJldE9wdGlvbnMoCisgICAgT3B0aW9uc1RvSW50ZXJwcmV0KiBvcHRpb25zX3RvX2ludGVycHJldCkgeworICAvLyBOb3RlIHRoYXQgdGhlc2UgbWF5IGJlIGluIGRpZmZlcmVudCBwb29scywgc28gd2UgY2FuJ3QgdXNlIHRoZSBzYW1lCisgIC8vIGRlc2NyaXB0b3IgYW5kIHJlZmxlY3Rpb24gb2JqZWN0cyBvbiBib3RoLgorICBNZXNzYWdlKiBvcHRpb25zID0gb3B0aW9uc190b19pbnRlcnByZXQtPm9wdGlvbnM7CisgIGNvbnN0IE1lc3NhZ2UqIG9yaWdpbmFsX29wdGlvbnMgPSBvcHRpb25zX3RvX2ludGVycHJldC0+b3JpZ2luYWxfb3B0aW9uczsKKworICBib29sIGZhaWxlZCA9IGZhbHNlOworICBvcHRpb25zX3RvX2ludGVycHJldF8gPSBvcHRpb25zX3RvX2ludGVycHJldDsKKworICAvLyBGaW5kIHRoZSB1bmludGVycHJldGVkX29wdGlvbiBmaWVsZCBpbiB0aGUgbXV0YWJsZSBjb3B5IG9mIHRoZSBvcHRpb25zCisgIC8vIGFuZCBjbGVhciB0aGVtLCBzaW5jZSB3ZSdyZSBhYm91dCB0byBpbnRlcnByZXQgdGhlbS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB1bmludGVycHJldGVkX29wdGlvbnNfZmllbGQgPQorICAgICAgb3B0aW9ucy0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInVuaW50ZXJwcmV0ZWRfb3B0aW9uIik7CisgIEdPT0dMRV9DSEVDSyh1bmludGVycHJldGVkX29wdGlvbnNfZmllbGQgIT0gTlVMTCkKKyAgICAgIDw8ICJObyBmaWVsZCBuYW1lZCBcInVuaW50ZXJwcmV0ZWRfb3B0aW9uXCIgaW4gdGhlIE9wdGlvbnMgcHJvdG8uIjsKKyAgb3B0aW9ucy0+R2V0UmVmbGVjdGlvbigpLT5DbGVhckZpZWxkKG9wdGlvbnMsIHVuaW50ZXJwcmV0ZWRfb3B0aW9uc19maWVsZCk7CisKKyAgLy8gRmluZCB0aGUgdW5pbnRlcnByZXRlZF9vcHRpb24gZmllbGQgaW4gdGhlIG9yaWdpbmFsIG9wdGlvbnMuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb3JpZ2luYWxfdW5pbnRlcnByZXRlZF9vcHRpb25zX2ZpZWxkID0KKyAgICAgIG9yaWdpbmFsX29wdGlvbnMtPkdldERlc2NyaXB0b3IoKS0+CisgICAgICAgICAgRmluZEZpZWxkQnlOYW1lKCJ1bmludGVycHJldGVkX29wdGlvbiIpOworICBHT09HTEVfQ0hFQ0sob3JpZ2luYWxfdW5pbnRlcnByZXRlZF9vcHRpb25zX2ZpZWxkICE9IE5VTEwpCisgICAgICA8PCAiTm8gZmllbGQgbmFtZWQgXCJ1bmludGVycHJldGVkX29wdGlvblwiIGluIHRoZSBPcHRpb25zIHByb3RvLiI7CisKKyAgY29uc3QgaW50IG51bV91bmludGVycHJldGVkX29wdGlvbnMgPSBvcmlnaW5hbF9vcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgRmllbGRTaXplKCpvcmlnaW5hbF9vcHRpb25zLCBvcmlnaW5hbF91bmludGVycHJldGVkX29wdGlvbnNfZmllbGQpOworICBmb3IgKGludCBpID0gMDsgaSA8IG51bV91bmludGVycHJldGVkX29wdGlvbnM7ICsraSkgeworICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXyA9IGRvd25fY2FzdDxjb25zdCBVbmludGVycHJldGVkT3B0aW9uKj4oCisgICAgICAgICZvcmlnaW5hbF9vcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICAgICAgICAgICpvcmlnaW5hbF9vcHRpb25zLCBvcmlnaW5hbF91bmludGVycHJldGVkX29wdGlvbnNfZmllbGQsIGkpKTsKKyAgICBpZiAoIUludGVycHJldFNpbmdsZU9wdGlvbihvcHRpb25zKSkgeworICAgICAgLy8gRXJyb3IgYWxyZWFkeSBhZGRlZCBieSBJbnRlcnByZXRTaW5nbGVPcHRpb24oKS4KKyAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgLy8gUmVzZXQgdGhlc2UsIHNvIHdlIGRvbid0IGhhdmUgYW55IGRhbmdsaW5nIHBvaW50ZXJzLgorICB1bmludGVycHJldGVkX29wdGlvbl8gPSBOVUxMOworICBvcHRpb25zX3RvX2ludGVycHJldF8gPSBOVUxMOworCisgIGlmICghZmFpbGVkKSB7CisgICAgLy8gSW50ZXJwcmV0U2luZ2xlT3B0aW9uKCkgYWRkZWQgdGhlIGludGVycHJldGVkIG9wdGlvbnMgaW4gdGhlCisgICAgLy8gVW5rbm93bkZpZWxkU2V0LCBpbiBjYXNlIHRoZSBvcHRpb24gaXNuJ3QgeWV0IGtub3duIHRvIHVzLiAgTm93IHdlCisgICAgLy8gc2VyaWFsaXplIHRoZSBvcHRpb25zIG1lc3NhZ2UgYW5kIGRlc2VyaWFsaXplIGl0IGJhY2suICBUaGF0IHdheSwgYW55CisgICAgLy8gb3B0aW9uIGZpZWxkcyB0aGF0IHdlIGRvIGhhcHBlbiB0byBrbm93IGFib3V0IHdpbGwgZ2V0IG1vdmVkIGZyb20gdGhlCisgICAgLy8gVW5rbm93bkZpZWxkU2V0IGludG8gdGhlIHJlYWwgZmllbGRzLCBhbmQgdGh1cyBiZSBhdmFpbGFibGUgcmlnaHQgYXdheS4KKyAgICAvLyBJZiB0aGV5IGFyZSBub3Qga25vd24sIHRoYXQncyBPSyB0b28uIFRoZXkgd2lsbCBnZXQgcmVwYXJzZWQgaW50byB0aGUKKyAgICAvLyBVbmtub3duRmllbGRTZXQgYW5kIHdhaXQgdGhlcmUgdW50aWwgdGhlIG1lc3NhZ2UgaXMgcGFyc2VkIGJ5IHNvbWV0aGluZworICAgIC8vIHRoYXQgZG9lcyBrbm93IGFib3V0IHRoZSBvcHRpb25zLgorICAgIHN0cmluZyBidWY7CisgICAgb3B0aW9ucy0+QXBwZW5kVG9TdHJpbmcoJmJ1Zik7CisgICAgR09PR0xFX0NIRUNLKG9wdGlvbnMtPlBhcnNlRnJvbVN0cmluZyhidWYpKQorICAgICAgICA8PCAiUHJvdG9jb2wgbWVzc2FnZSBzZXJpYWxpemVkIGl0c2VsZiBpbiBpbnZhbGlkIGZhc2hpb24uIjsKKyAgfQorCisgIHJldHVybiAhZmFpbGVkOworfQorCitib29sIERlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6SW50ZXJwcmV0U2luZ2xlT3B0aW9uKAorICAgIE1lc3NhZ2UqIG9wdGlvbnMpIHsKKyAgLy8gRmlyc3QgZG8gc29tZSBiYXNpYyB2YWxpZGF0aW9uLgorICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5uYW1lX3NpemUoKSA9PSAwKSB7CisgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuIHVubGVzcyB0aGUgcGFyc2VyIGhhcyBnb25lIHNlcmlvdXNseSBhd3J5IG9yCisgICAgLy8gc29tZW9uZSBoYXMgbWFudWFsbHkgY3JlYXRlZCB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb24gYmFkbHkuCisgICAgcmV0dXJuIEFkZE5hbWVFcnJvcigiT3B0aW9uIG11c3QgaGF2ZSBhIG5hbWUuIik7CisgIH0KKyAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmFtZSgwKS5uYW1lX3BhcnQoKSA9PSAidW5pbnRlcnByZXRlZF9vcHRpb24iKSB7CisgICAgcmV0dXJuIEFkZE5hbWVFcnJvcigiT3B0aW9uIG11c3Qgbm90IHVzZSByZXNlcnZlZCBuYW1lICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJcInVuaW50ZXJwcmV0ZWRfb3B0aW9uXCIuIik7CisgIH0KKworICBjb25zdCBEZXNjcmlwdG9yKiBvcHRpb25zX2Rlc2NyaXB0b3IgPSBOVUxMOworICAvLyBHZXQgdGhlIG9wdGlvbnMgbWVzc2FnZSdzIGRlc2NyaXB0b3IgZnJvbSB0aGUgYnVpbGRlcidzIHBvb2wsIHNvIHRoYXQgd2UKKyAgLy8gZ2V0IHRoZSB2ZXJzaW9uIHRoYXQga25vd3MgYWJvdXQgYW55IGV4dGVuc2lvbiBvcHRpb25zIGRlY2xhcmVkIGluIHRoZQorICAvLyBmaWxlIHdlJ3JlIGN1cnJlbnRseSBidWlsZGluZy4gVGhlIGRlc2NyaXB0b3Igc2hvdWxkIGJlIHRoZXJlIGFzIGxvbmcgYXMKKyAgLy8gdGhlIGZpbGUgd2UncmUgYnVpbGRpbmcgaW1wb3J0ZWQgImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9ycy5wcm90byIuCisKKyAgLy8gTm90ZSB0aGF0IHdlIHVzZSBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHMoKSwgbm90CisgIC8vIERlc2NyaXB0b3JQb29sOjpGaW5kTWVzc2FnZVR5cGVCeU5hbWUoKSBiZWNhdXNlIHdlJ3JlIGFscmVhZHkgaG9sZGluZyB0aGUKKyAgLy8gcG9vbCdzIG11dGV4LCBhbmQgdGhlIGxhdHRlciBtZXRob2QgbG9ja3MgaXQgYWdhaW4uICBXZSBkb24ndCB1c2UKKyAgLy8gRmluZFN5bWJvbCgpIGJlY2F1c2UgZmlsZXMgdGhhdCB1c2UgY3VzdG9tIG9wdGlvbnMgb25seSBuZWVkIHRvIGRlcGVuZCBvbgorICAvLyB0aGUgZmlsZSB0aGF0IGRlZmluZXMgdGhlIG9wdGlvbiwgbm90IGRlc2NyaXB0b3IucHJvdG8gaXRzZWxmLgorICBTeW1ib2wgc3ltYm9sID0gYnVpbGRlcl8tPkZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzKAorICAgIG9wdGlvbnMtPkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkpOworICBpZiAoIXN5bWJvbC5Jc051bGwoKSAmJiBzeW1ib2wudHlwZSA9PSBTeW1ib2w6Ok1FU1NBR0UpIHsKKyAgICBvcHRpb25zX2Rlc2NyaXB0b3IgPSBzeW1ib2wuZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICAvLyBUaGUgb3B0aW9ucyBtZXNzYWdlJ3MgZGVzY3JpcHRvciB3YXMgbm90IGluIHRoZSBidWlsZGVyJ3MgcG9vbCwgc28gdXNlCisgICAgLy8gdGhlIHN0YW5kYXJkIHZlcnNpb24gZnJvbSB0aGUgZ2VuZXJhdGVkIHBvb2wuIFdlJ3JlIG5vdCBob2xkaW5nIHRoZQorICAgIC8vIGdlbmVyYXRlZCBwb29sJ3MgbXV0ZXgsIHNvIHdlIGNhbiBzZWFyY2ggaXQgdGhlIHN0cmFpZ2h0Zm9yd2FyZCB3YXkuCisgICAgb3B0aW9uc19kZXNjcmlwdG9yID0gb3B0aW9ucy0+R2V0RGVzY3JpcHRvcigpOworICB9CisgIEdPT0dMRV9DSEVDSyhvcHRpb25zX2Rlc2NyaXB0b3IpOworCisgIC8vIFdlIGl0ZXJhdGUgb3ZlciB0aGUgbmFtZSBwYXJ0cyB0byBkcmlsbCBpbnRvIHRoZSBzdWJtZXNzYWdlcyB1bnRpbCB3ZSBmaW5kCisgIC8vIHRoZSBsZWFmIGZpZWxkIGZvciB0aGUgb3B0aW9uLiBBcyB3ZSBkcmlsbCBkb3duIHdlIHJlbWVtYmVyIHRoZSBjdXJyZW50CisgIC8vIHN1Ym1lc3NhZ2UncyBkZXNjcmlwdG9yIGluIHxkZXNjcmlwdG9yfCBhbmQgdGhlIG5leHQgZmllbGQgaW4gdGhhdAorICAvLyBzdWJtZXNzYWdlIGluIHxmaWVsZHwuIFdlIGFsc28gdHJhY2sgdGhlIGZpZWxkcyB3ZSdyZSBkcmlsbGluZyBkb3duCisgIC8vIHRocm91Z2ggaW4gfGludGVybWVkaWF0ZV9maWVsZHN8LiBBcyB3ZSBnbywgd2UgcmVjb25zdHJ1Y3QgdGhlIGZ1bGwgb3B0aW9uCisgIC8vIG5hbWUgaW4gfGRlYnVnX21zZ19uYW1lfCwgZm9yIHVzZSBpbiBlcnJvciBtZXNzYWdlcy4KKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG9wdGlvbnNfZGVzY3JpcHRvcjsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IE5VTEw7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBpbnRlcm1lZGlhdGVfZmllbGRzOworICBzdHJpbmcgZGVidWdfbXNnX25hbWUgPSAiIjsKKworICBmb3IgKGludCBpID0gMDsgaSA8IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmFtZV9zaXplKCk7ICsraSkgeworICAgIGNvbnN0IHN0cmluZyYgbmFtZV9wYXJ0ID0gdW5pbnRlcnByZXRlZF9vcHRpb25fLT5uYW1lKGkpLm5hbWVfcGFydCgpOworICAgIGlmIChkZWJ1Z19tc2dfbmFtZS5zaXplKCkgPiAwKSB7CisgICAgICBkZWJ1Z19tc2dfbmFtZSArPSAiLiI7CisgICAgfQorICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPm5hbWUoaSkuaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIGRlYnVnX21zZ19uYW1lICs9ICIoIiArIG5hbWVfcGFydCArICIpIjsKKyAgICAgIC8vIFNlYXJjaCBmb3IgdGhlIGV4dGVuc2lvbidzIGRlc2NyaXB0b3IgYXMgYW4gZXh0ZW5zaW9uIGluIHRoZSBidWlsZGVyJ3MKKyAgICAgIC8vIHBvb2wuIE5vdGUgdGhhdCB3ZSB1c2UgRGVzY3JpcHRvckJ1aWxkZXI6Okxvb2t1cFN5bWJvbCgpLCBub3QKKyAgICAgIC8vIERlc2NyaXB0b3JQb29sOjpGaW5kRXh0ZW5zaW9uQnlOYW1lKCksIGZvciB0d28gcmVhc29uczogMSkgSXQgYWxsb3dzCisgICAgICAvLyByZWxhdGl2ZSBsb29rdXBzLCBhbmQgMikgYmVjYXVzZSB3ZSdyZSBhbHJlYWR5IGhvbGRpbmcgdGhlIHBvb2wncworICAgICAgLy8gbXV0ZXgsIGFuZCB0aGUgbGF0dGVyIG1ldGhvZCBsb2NrcyBpdCBhZ2Fpbi4KKyAgICAgIHN5bWJvbCA9IGJ1aWxkZXJfLT5Mb29rdXBTeW1ib2wobmFtZV9wYXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zX3RvX2ludGVycHJldF8tPm5hbWVfc2NvcGUpOworICAgICAgaWYgKCFzeW1ib2wuSXNOdWxsKCkgJiYgc3ltYm9sLnR5cGUgPT0gU3ltYm9sOjpGSUVMRCkgeworICAgICAgICBmaWVsZCA9IHN5bWJvbC5maWVsZF9kZXNjcmlwdG9yOworICAgICAgfQorICAgICAgLy8gSWYgd2UgZG9uJ3QgZmluZCB0aGUgZmllbGQgdGhlbiB0aGUgZmllbGQncyBkZXNjcmlwdG9yIHdhcyBub3QgaW4gdGhlCisgICAgICAvLyBidWlsZGVyJ3MgcG9vbCwgYnV0IHRoZXJlJ3Mgbm8gcG9pbnQgaW4gbG9va2luZyBpbiB0aGUgZ2VuZXJhdGVkCisgICAgICAvLyBwb29sLiBXZSByZXF1aXJlIHRoYXQgeW91IGltcG9ydCB0aGUgZmlsZSB0aGF0IGRlZmluZXMgYW55IGV4dGVuc2lvbnMKKyAgICAgIC8vIHlvdSB1c2UsIHNvIHRoZXkgbXVzdCBiZSBwcmVzZW50IGluIHRoZSBidWlsZGVyJ3MgcG9vbC4KKyAgICB9IGVsc2UgeworICAgICAgZGVidWdfbXNnX25hbWUgKz0gbmFtZV9wYXJ0OworICAgICAgLy8gU2VhcmNoIGZvciB0aGUgZmllbGQncyBkZXNjcmlwdG9yIGFzIGEgcmVndWxhciBmaWVsZC4KKyAgICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKG5hbWVfcGFydCk7CisgICAgfQorCisgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgIGlmIChnZXRfYWxsb3dfdW5rbm93bihidWlsZGVyXy0+cG9vbF8pKSB7CisgICAgICAgIC8vIFdlIGNhbid0IGZpbmQgdGhlIG9wdGlvbiwgYnV0IEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIGlzIGVuYWJsZWQsCisgICAgICAgIC8vIHNvIHdlIHdpbGwganVzdCBsZWF2ZSBpdCBhcyB1bmludGVycHJldGVkLgorICAgICAgICBBZGRXaXRob3V0SW50ZXJwcmV0aW5nKCp1bmludGVycHJldGVkX29wdGlvbl8sIG9wdGlvbnMpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gZWxzZSBpZiAoIShidWlsZGVyXy0+dW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8pLmVtcHR5KCkpIHsKKyAgICAgICAgLy8gT3B0aW9uIGlzIHJlc29sdmVkIHRvIGEgbmFtZSB3aGljaCBpcyBub3QgZGVmaW5lZC4KKyAgICAgICAgcmV0dXJuIEFkZE5hbWVFcnJvcigKKyAgICAgICAgICAgICJPcHRpb24gXCIiICsgZGVidWdfbXNnX25hbWUgKyAiXCIgaXMgcmVzb2x2ZWQgdG8gXCIoIiArCisgICAgICAgICAgICBidWlsZGVyXy0+dW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8gKworICAgICAgICAgICAgIilcIiwgd2hpY2ggaXMgbm90IGRlZmluZWQuIFRoZSBpbm5lcm1vc3Qgc2NvcGUgaXMgc2VhcmNoZWQgZmlyc3QgIgorICAgICAgICAgICAgImluIG5hbWUgcmVzb2x1dGlvbi4gQ29uc2lkZXIgdXNpbmcgYSBsZWFkaW5nICcuJyhpLmUuLCBcIiguIiArCisgICAgICAgICAgICBkZWJ1Z19tc2dfbmFtZS5zdWJzdHIoMSkgKworICAgICAgICAgICAgIlwiKSB0byBzdGFydCBmcm9tIHRoZSBvdXRlcm1vc3Qgc2NvcGUuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQWRkTmFtZUVycm9yKCJPcHRpb24gXCIiICsgZGVidWdfbXNnX25hbWUgKyAiXCIgdW5rbm93bi4iKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSAhPSBkZXNjcmlwdG9yKSB7CisgICAgICBpZiAoZ2V0X2lzX3BsYWNlaG9sZGVyKGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICAgICAgLy8gVGhlIGZpZWxkIGlzIGFuIGV4dGVuc2lvbiBvZiBhIHBsYWNlaG9sZGVyIHR5cGUsIHNvIHdlIGNhbid0CisgICAgICAgIC8vIHJlbGlhYmx5IHZlcmlmeSB3aGV0aGVyIGl0IGlzIGEgdmFsaWQgZXh0ZW5zaW9uIHRvIHVzZSBoZXJlIChlLmcuCisgICAgICAgIC8vIHdlIGRvbid0IGtub3cgaWYgaXQgaXMgYW4gZXh0ZW5zaW9uIG9mIHRoZSBjb3JyZWN0ICpPcHRpb25zIG1lc3NhZ2UsCisgICAgICAgIC8vIG9yIGlmIGl0IGhhcyBhIHZhbGlkIGZpZWxkIG51bWJlciwgZXRjLikuICBKdXN0IGxlYXZlIGl0IGFzCisgICAgICAgIC8vIHVuaW50ZXJwcmV0ZWQgaW5zdGVhZC4KKyAgICAgICAgQWRkV2l0aG91dEludGVycHJldGluZygqdW5pbnRlcnByZXRlZF9vcHRpb25fLCBvcHRpb25zKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBUaGlzIGNhbiBvbmx5IGhhcHBlbiBpZiwgZHVlIHRvIHNvbWUgaW5zYW5lIG1pc2NvbmZpZ3VyYXRpb24gb2YgdGhlCisgICAgICAgIC8vIHBvb2xzLCB3ZSBmaW5kIHRoZSBvcHRpb25zIG1lc3NhZ2UgaW4gb25lIHBvb2wgYnV0IHRoZSBmaWVsZCBpbgorICAgICAgICAvLyBhbm90aGVyLiBUaGlzIHdvdWxkIHByb2JhYmx5IGltcGx5IGEgaGVmdHkgYnVnIHNvbWV3aGVyZS4KKyAgICAgICAgcmV0dXJuIEFkZE5hbWVFcnJvcigiT3B0aW9uIGZpZWxkIFwiIiArIGRlYnVnX21zZ19uYW1lICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXCIgaXMgbm90IGEgZmllbGQgb3IgZXh0ZW5zaW9uIG9mIG1lc3NhZ2UgXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChpIDwgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5uYW1lX3NpemUoKSAtIDEpIHsKKyAgICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgICByZXR1cm4gQWRkTmFtZUVycm9yKCJPcHRpb24gXCIiICsgIGRlYnVnX21zZ19uYW1lICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXCIgaXMgYW4gYXRvbWljIHR5cGUsIG5vdCBhIG1lc3NhZ2UuIik7CisgICAgICB9IGVsc2UgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIHJldHVybiBBZGROYW1lRXJyb3IoIk9wdGlvbiBmaWVsZCBcIiIgKyBkZWJ1Z19tc2dfbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIGlzIGEgcmVwZWF0ZWQgbWVzc2FnZS4gUmVwZWF0ZWQgbWVzc2FnZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbnMgbXVzdCBiZSBpbml0aWFsaXplZCB1c2luZyBhbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFnZ3JlZ2F0ZSB2YWx1ZS4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIERyaWxsIGRvd24gaW50byB0aGUgc3VibWVzc2FnZS4KKyAgICAgICAgaW50ZXJtZWRpYXRlX2ZpZWxkcy5wdXNoX2JhY2soZmllbGQpOworICAgICAgICBkZXNjcmlwdG9yID0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFdlJ3ZlIGZvdW5kIHRoZSBsZWFmIGZpZWxkLiBOb3cgd2UgdXNlIFVua25vd25GaWVsZFNldHMgdG8gc2V0IGl0cyB2YWx1ZQorICAvLyBvbiB0aGUgb3B0aW9ucyBtZXNzYWdlLiBXZSBkbyBzbyBiZWNhdXNlIHRoZSBtZXNzYWdlIG1heSBub3QgeWV0IGtub3cKKyAgLy8gYWJvdXQgaXRzIGV4dGVuc2lvbiBmaWVsZHMsIHNvIHdlIG1heSBub3QgYmUgYWJsZSB0byBzZXQgdGhlIGZpZWxkcworICAvLyBkaXJlY3RseS4gQnV0IHRoZSBVbmtub3duRmllbGRTZXRzIHdpbGwgc2VyaWFsaXplIHRvIHRoZSBzYW1lIHdpcmUtZm9ybWF0CisgIC8vIG1lc3NhZ2UsIHNvIHJlYWRpbmcgdGhhdCBtZXNzYWdlIGJhY2sgaW4gb25jZSB0aGUgZXh0ZW5zaW9uIGZpZWxkcyBhcmUKKyAgLy8ga25vd24gd2lsbCBwb3B1bGF0ZSB0aGVtIGNvcnJlY3RseS4KKworICAvLyBGaXJzdCBzZWUgaWYgdGhlIG9wdGlvbiBpcyBhbHJlYWR5IHNldC4KKyAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiAhRXhhbWluZUlmT3B0aW9uSXNTZXQoCisgICAgICAgICAgaW50ZXJtZWRpYXRlX2ZpZWxkcy5iZWdpbigpLAorICAgICAgICAgIGludGVybWVkaWF0ZV9maWVsZHMuZW5kKCksCisgICAgICAgICAgZmllbGQsIGRlYnVnX21zZ19uYW1lLAorICAgICAgICAgIG9wdGlvbnMtPkdldFJlZmxlY3Rpb24oKS0+R2V0VW5rbm93bkZpZWxkcygqb3B0aW9ucykpKSB7CisgICAgcmV0dXJuIGZhbHNlOyAgLy8gRXhhbWluZUlmT3B0aW9uSXNTZXQoKSBhbHJlYWR5IGFkZGVkIHRoZSBlcnJvci4KKyAgfQorCisKKyAgLy8gRmlyc3Qgc2V0IHRoZSB2YWx1ZSBvbiB0aGUgVW5rbm93bkZpZWxkU2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhlCisgIC8vIGlubmVybW9zdCBtZXNzYWdlLgorICBzY29wZWRfcHRyPFVua25vd25GaWVsZFNldD4gdW5rbm93bl9maWVsZHMobmV3IFVua25vd25GaWVsZFNldCgpKTsKKyAgaWYgKCFTZXRPcHRpb25WYWx1ZShmaWVsZCwgdW5rbm93bl9maWVsZHMuZ2V0KCkpKSB7CisgICAgcmV0dXJuIGZhbHNlOyAgLy8gU2V0T3B0aW9uVmFsdWUoKSBhbHJlYWR5IGFkZGVkIHRoZSBlcnJvci4KKyAgfQorCisgIC8vIE5vdyB3cmFwIHRoZSBVbmtub3duRmllbGRTZXQgd2l0aCBVbmtub3duRmllbGRTZXRzIGNvcnJlc3BvbmRpbmcgdG8gYWxsCisgIC8vIHRoZSBpbnRlcm1lZGlhdGUgbWVzc2FnZXMuCisgIGZvciAodmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+OjpyZXZlcnNlX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICBpbnRlcm1lZGlhdGVfZmllbGRzLnJiZWdpbigpOworICAgICAgIGl0ZXIgIT0gaW50ZXJtZWRpYXRlX2ZpZWxkcy5yZW5kKCk7ICsraXRlcikgeworICAgIHNjb3BlZF9wdHI8VW5rbm93bkZpZWxkU2V0PiBwYXJlbnRfdW5rbm93bl9maWVsZHMobmV3IFVua25vd25GaWVsZFNldCgpKTsKKyAgICBzd2l0Y2ggKCgqaXRlciktPnR5cGUoKSkgeworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRTogeworICAgICAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIG91dHN0cigKKyAgICAgICAgICAgIHBhcmVudF91bmtub3duX2ZpZWxkcy0+QWRkTGVuZ3RoRGVsaW1pdGVkKCgqaXRlciktPm51bWJlcigpKSk7CisgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXQoJm91dHN0cik7CisgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKCp1bmtub3duX2ZpZWxkcywgJm91dCk7CisgICAgICAgIEdPT0dMRV9DSEVDSyghb3V0LkhhZEVycm9yKCkpCisgICAgICAgICAgICA8PCAiVW5leHBlY3RlZCBmYWlsdXJlIHdoaWxlIHNlcmlhbGl6aW5nIG9wdGlvbiBzdWJtZXNzYWdlICIKKyAgICAgICAgICAgIDw8IGRlYnVnX21zZ19uYW1lIDw8ICJcIi4iOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVA6IHsKKyAgICAgICAgIHBhcmVudF91bmtub3duX2ZpZWxkcy0+QWRkR3JvdXAoKCppdGVyKS0+bnVtYmVyKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPk1lcmdlRnJvbSgqdW5rbm93bl9maWVsZHMpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkludmFsaWQgd2lyZSB0eXBlIGZvciBDUFBUWVBFX01FU1NBR0U6ICIKKyAgICAgICAgICAgICAgICAgICA8PCAoKml0ZXIpLT50eXBlKCk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgdW5rbm93bl9maWVsZHMucmVzZXQocGFyZW50X3Vua25vd25fZmllbGRzLnJlbGVhc2UoKSk7CisgIH0KKworICAvLyBOb3cgbWVyZ2UgdGhlIFVua25vd25GaWVsZFNldCBjb3JyZXNwb25kaW5nIHRvIHRoZSB0b3AtbGV2ZWwgbWVzc2FnZSBpbnRvCisgIC8vIHRoZSBvcHRpb25zIG1lc3NhZ2UuCisgIG9wdGlvbnMtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMob3B0aW9ucyktPk1lcmdlRnJvbSgKKyAgICAgICp1bmtub3duX2ZpZWxkcyk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpBZGRXaXRob3V0SW50ZXJwcmV0aW5nKAorICAgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLCBNZXNzYWdlKiBvcHRpb25zKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgIG9wdGlvbnMtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJ1bmludGVycHJldGVkX29wdGlvbiIpOworICBHT09HTEVfQ0hFQ0soZmllbGQgIT0gTlVMTCk7CisKKyAgb3B0aW9ucy0+R2V0UmVmbGVjdGlvbigpLT5BZGRNZXNzYWdlKG9wdGlvbnMsIGZpZWxkKQorICAgIC0+Q29weUZyb20odW5pbnRlcnByZXRlZF9vcHRpb24pOworfQorCitib29sIERlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6RXhhbWluZUlmT3B0aW9uSXNTZXQoCisgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+Ojpjb25zdF9pdGVyYXRvciBpbnRlcm1lZGlhdGVfZmllbGRzX2l0ZXIsCisgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+Ojpjb25zdF9pdGVyYXRvciBpbnRlcm1lZGlhdGVfZmllbGRzX2VuZCwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGlubmVybW9zdF9maWVsZCwgY29uc3Qgc3RyaW5nJiBkZWJ1Z19tc2dfbmFtZSwKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKSB7CisgIC8vIFdlIGRvIGxpbmVhciBzZWFyY2hlcyBvZiB0aGUgVW5rbm93bkZpZWxkU2V0IGFuZCBpdHMgc3ViLWdyb3Vwcy4gIFRoaXMKKyAgLy8gc2hvdWxkIGJlIGZpbmUgc2luY2UgaXQncyB1bmxpa2VseSB0aGF0IGFueSBvbmUgb3B0aW9ucyBzdHJ1Y3R1cmUgd2lsbAorICAvLyBjb250YWluIG1vcmUgdGhhbiBhIGhhbmRmdWwgb2Ygb3B0aW9ucy4KKworICBpZiAoaW50ZXJtZWRpYXRlX2ZpZWxkc19pdGVyID09IGludGVybWVkaWF0ZV9maWVsZHNfZW5kKSB7CisgICAgLy8gV2UncmUgYXQgdGhlIGlubmVybW9zdCBzdWJtZXNzYWdlLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBpZiAodW5rbm93bl9maWVsZHMuZmllbGQoaSkubnVtYmVyKCkgPT0gaW5uZXJtb3N0X2ZpZWxkLT5udW1iZXIoKSkgeworICAgICAgICByZXR1cm4gQWRkTmFtZUVycm9yKCJPcHRpb24gXCIiICsgZGVidWdfbXNnX25hbWUgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiB3YXMgYWxyZWFkeSBzZXQuIik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAodW5rbm93bl9maWVsZHMuZmllbGQoaSkubnVtYmVyKCkgPT0KKyAgICAgICAgKCppbnRlcm1lZGlhdGVfZmllbGRzX2l0ZXIpLT5udW1iZXIoKSkgeworICAgICAgY29uc3QgVW5rbm93bkZpZWxkKiB1bmtub3duX2ZpZWxkID0gJnVua25vd25fZmllbGRzLmZpZWxkKGkpOworICAgICAgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUgPSAoKmludGVybWVkaWF0ZV9maWVsZHNfaXRlciktPnR5cGUoKTsKKyAgICAgIC8vIFJlY3Vyc2UgaW50byB0aGUgbmV4dCBzdWJtZXNzYWdlLgorICAgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKHVua25vd25fZmllbGQtPnR5cGUoKSA9PSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRCkgeworICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0IGludGVybWVkaWF0ZV91bmtub3duX2ZpZWxkczsKKyAgICAgICAgICAgIGlmIChpbnRlcm1lZGlhdGVfdW5rbm93bl9maWVsZHMuUGFyc2VGcm9tU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICB1bmtub3duX2ZpZWxkLT5sZW5ndGhfZGVsaW1pdGVkKCkpICYmCisgICAgICAgICAgICAgICAgIUV4YW1pbmVJZk9wdGlvbklzU2V0KGludGVybWVkaWF0ZV9maWVsZHNfaXRlciArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZV9maWVsZHNfZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbm5lcm1vc3RfZmllbGQsIGRlYnVnX21zZ19uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm1lZGlhdGVfdW5rbm93bl9maWVsZHMpKSB7CisgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIEVycm9yIGFscmVhZHkgYWRkZWQuCisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgICAgICAgIGlmICh1bmtub3duX2ZpZWxkLT50eXBlKCkgPT0gVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQKSB7CisgICAgICAgICAgICBpZiAoIUV4YW1pbmVJZk9wdGlvbklzU2V0KGludGVybWVkaWF0ZV9maWVsZHNfaXRlciArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZV9maWVsZHNfZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbm5lcm1vc3RfZmllbGQsIGRlYnVnX21zZ19uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duX2ZpZWxkLT5ncm91cCgpKSkgeworICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAvLyBFcnJvciBhbHJlYWR5IGFkZGVkLgorICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJJbnZhbGlkIHdpcmUgdHlwZSBmb3IgQ1BQVFlQRV9NRVNTQUdFOiAiIDw8IHR5cGU7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OlNldE9wdGlvblZhbHVlKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb3B0aW9uX2ZpZWxkLAorICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgLy8gV2Ugc3dpdGNoIG9uIHRoZSBDcHBUeXBlIHRvIHZhbGlkYXRlLgorICBzd2l0Y2ggKG9wdGlvbl9maWVsZC0+Y3BwX3R5cGUoKSkgeworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+cG9zaXRpdmVfaW50X3ZhbHVlKCkgPgorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8dWludDY0PihraW50MzJtYXgpKSB7CisgICAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG91dCBvZiByYW5nZSBmb3IgaW50MzIgb3B0aW9uIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBTZXRJbnQzMihvcHRpb25fZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+cG9zaXRpdmVfaW50X3ZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT50eXBlKCksIHVua25vd25fZmllbGRzKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKSA8CisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ2ND4oa2ludDMybWluKSkgeworICAgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIGludDMyIG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgU2V0SW50MzIob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbl8tPm5lZ2F0aXZlX2ludF92YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+dHlwZSgpLCB1bmtub3duX2ZpZWxkcyk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIGludGVnZXIgZm9yIGludDMyIG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSA+CisgICAgICAgICAgICBzdGF0aWNfY2FzdDx1aW50NjQ+KGtpbnQ2NG1heCkpIHsKKyAgICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgb3V0IG9mIHJhbmdlIGZvciBpbnQ2NCBvcHRpb24gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFNldEludDY0KG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPnR5cGUoKSwgdW5rbm93bl9maWVsZHMpOworICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIFNldEludDY0KG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmVnYXRpdmVfaW50X3ZhbHVlKCksCisgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+dHlwZSgpLCB1bmtub3duX2ZpZWxkcyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgbXVzdCBiZSBpbnRlZ2VyIGZvciBpbnQ2NCBvcHRpb24gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPnBvc2l0aXZlX2ludF92YWx1ZSgpID4ga3VpbnQzMm1heCkgeworICAgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIHVpbnQzMiBvcHRpb24gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPm5hbWUoKSArICJcIi4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBTZXRVSW50MzIob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT50eXBlKCksIHVua25vd25fZmllbGRzKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG11c3QgYmUgbm9uLW5lZ2F0aXZlIGludGVnZXIgZm9yIHVpbnQzMiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb24gXCIiICsgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIFNldFVJbnQ2NChvcHRpb25fZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+dHlwZSgpLCB1bmtub3duX2ZpZWxkcyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgbXVzdCBiZSBub24tbmVnYXRpdmUgaW50ZWdlciBmb3IgdWludDY0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbiBcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDogeworICAgICAgZmxvYXQgdmFsdWU7CisgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfZG91YmxlX3ZhbHVlKCkpIHsKKyAgICAgICAgdmFsdWUgPSB1bmludGVycHJldGVkX29wdGlvbl8tPmRvdWJsZV92YWx1ZSgpOworICAgICAgfSBlbHNlIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgICB2YWx1ZSA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+cG9zaXRpdmVfaW50X3ZhbHVlKCk7CisgICAgICB9IGVsc2UgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIHZhbHVlID0gdW5pbnRlcnByZXRlZF9vcHRpb25fLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIG51bWJlciBmb3IgZmxvYXQgb3B0aW9uIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQzMihvcHRpb25fZmllbGQtPm51bWJlcigpLAorICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RW5jb2RlRmxvYXQodmFsdWUpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRTogeworICAgICAgZG91YmxlIHZhbHVlOworICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX2RvdWJsZV92YWx1ZSgpKSB7CisgICAgICAgIHZhbHVlID0gdW5pbnRlcnByZXRlZF9vcHRpb25fLT5kb3VibGVfdmFsdWUoKTsKKyAgICAgIH0gZWxzZSBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgICAgdmFsdWUgPSB1bmludGVycHJldGVkX29wdGlvbl8tPnBvc2l0aXZlX2ludF92YWx1ZSgpOworICAgICAgfSBlbHNlIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgICB2YWx1ZSA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmVnYXRpdmVfaW50X3ZhbHVlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgbXVzdCBiZSBudW1iZXIgZm9yIGRvdWJsZSBvcHRpb24gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgIH0KKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDY0KG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbmNvZGVEb3VibGUodmFsdWUpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICB1aW50NjQgdmFsdWU7CisgICAgICBpZiAoIXVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX2lkZW50aWZpZXJfdmFsdWUoKSkgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgbXVzdCBiZSBpZGVudGlmaWVyIGZvciBib29sZWFuIG9wdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aWRlbnRpZmllcl92YWx1ZSgpID09ICJ0cnVlIikgeworICAgICAgICB2YWx1ZSA9IDE7CisgICAgICB9IGVsc2UgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aWRlbnRpZmllcl92YWx1ZSgpID09ICJmYWxzZSIpIHsKKyAgICAgICAgdmFsdWUgPSAwOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG11c3QgYmUgXCJ0cnVlXCIgb3IgXCJmYWxzZVwiIGZvciBib29sZWFuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbiBcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChvcHRpb25fZmllbGQtPm51bWJlcigpLCB2YWx1ZSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06IHsKKyAgICAgIGlmICghdW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfaWRlbnRpZmllcl92YWx1ZSgpKSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIGlkZW50aWZpZXIgZm9yIGVudW0tdmFsdWVkIG9wdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZSA9IG9wdGlvbl9maWVsZC0+ZW51bV90eXBlKCk7CisgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlX25hbWUgPSB1bmludGVycHJldGVkX29wdGlvbl8tPmlkZW50aWZpZXJfdmFsdWUoKTsKKyAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPSBOVUxMOworCisgICAgICBpZiAoZW51bV90eXBlLT5maWxlKCktPnBvb2woKSAhPSBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkgeworICAgICAgICAvLyBOb3RlIHRoYXQgdGhlIGVudW0gdmFsdWUncyBmdWxseS1xdWFsaWZpZWQgbmFtZSBpcyBhIHNpYmxpbmcgb2YgdGhlCisgICAgICAgIC8vIGVudW0ncyBuYW1lLCBub3QgYSBjaGlsZCBvZiBpdC4KKyAgICAgICAgc3RyaW5nIGZ1bGx5X3F1YWxpZmllZF9uYW1lID0gZW51bV90eXBlLT5mdWxsX25hbWUoKTsKKyAgICAgICAgZnVsbHlfcXVhbGlmaWVkX25hbWUucmVzaXplKGZ1bGx5X3F1YWxpZmllZF9uYW1lLnNpemUoKSAtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtX3R5cGUtPm5hbWUoKS5zaXplKCkpOworICAgICAgICBmdWxseV9xdWFsaWZpZWRfbmFtZSArPSB2YWx1ZV9uYW1lOworCisgICAgICAgIC8vIFNlYXJjaCBmb3IgdGhlIGVudW0gdmFsdWUncyBkZXNjcmlwdG9yIGluIHRoZSBidWlsZGVyJ3MgcG9vbC4gTm90ZQorICAgICAgICAvLyB0aGF0IHdlIHVzZSBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHMoKSwgbm90CisgICAgICAgIC8vIERlc2NyaXB0b3JQb29sOjpGaW5kRW51bVZhbHVlQnlOYW1lKCkgYmVjYXVzZSB3ZSdyZSBhbHJlYWR5IGhvbGRpbmcKKyAgICAgICAgLy8gdGhlIHBvb2wncyBtdXRleCwgYW5kIHRoZSBsYXR0ZXIgbWV0aG9kIGxvY2tzIGl0IGFnYWluLgorICAgICAgICBTeW1ib2wgc3ltYm9sID0KKyAgICAgICAgICBidWlsZGVyXy0+RmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHMoZnVsbHlfcXVhbGlmaWVkX25hbWUpOworICAgICAgICBpZiAoIXN5bWJvbC5Jc051bGwoKSAmJiBzeW1ib2wudHlwZSA9PSBTeW1ib2w6OkVOVU1fVkFMVUUpIHsKKyAgICAgICAgICBpZiAoc3ltYm9sLmVudW1fdmFsdWVfZGVzY3JpcHRvci0+dHlwZSgpICE9IGVudW1fdHlwZSkgeworICAgICAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIkVudW0gdHlwZSBcIiIgKyBlbnVtX3R5cGUtPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICAgICAiXCIgaGFzIG5vIHZhbHVlIG5hbWVkIFwiIiArIHZhbHVlX25hbWUgKyAiXCIgZm9yIG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICAgICJcIi4gVGhpcyBhcHBlYXJzIHRvIGJlIGEgdmFsdWUgZnJvbSBhIHNpYmxpbmcgdHlwZS4iKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZW51bV92YWx1ZSA9IHN5bWJvbC5lbnVtX3ZhbHVlX2Rlc2NyaXB0b3I7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBUaGUgZW51bSB0eXBlIGlzIGluIHRoZSBnZW5lcmF0ZWQgcG9vbCwgc28gd2UgY2FuIHNlYXJjaCBmb3IgdGhlCisgICAgICAgIC8vIHZhbHVlIHRoZXJlLgorICAgICAgICBlbnVtX3ZhbHVlID0gZW51bV90eXBlLT5GaW5kVmFsdWVCeU5hbWUodmFsdWVfbmFtZSk7CisgICAgICB9CisKKyAgICAgIGlmIChlbnVtX3ZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIkVudW0gdHlwZSBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPmVudW1fdHlwZSgpLT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiBoYXMgbm8gdmFsdWUgbmFtZWQgXCIiICsgdmFsdWVfbmFtZSArICJcIiBmb3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0aW9uIFwiIiArIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBTaWduLWV4dGVuc2lvbiBpcyBub3QgYSBwcm9ibGVtLCBzaW5jZSB3ZSBjYXN0IGRpcmVjdGx5IGZyb20gaW50MzIgdG8KKyAgICAgICAgLy8gdWludDY0LCB3aXRob3V0IGZpcnN0IGdvaW5nIHRocm91Z2ggdWludDMyLgorICAgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgc3RhdGljX2Nhc3Q8dWludDY0PihzdGF0aWNfY2FzdDxpbnQ2ND4oZW51bV92YWx1ZS0+bnVtYmVyKCkpKSk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBpZiAoIXVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIHF1b3RlZCBzdHJpbmcgZm9yIHN0cmluZyBvcHRpb24gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXCIiICsgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgIH0KKyAgICAgIC8vIFRoZSBzdHJpbmcgaGFzIGFscmVhZHkgYmVlbiB1bnF1b3RlZCBhbmQgdW5lc2NhcGVkIGJ5IHRoZSBwYXJzZXIuCisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkTGVuZ3RoRGVsaW1pdGVkKG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5zdHJpbmdfdmFsdWUoKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICBpZiAoIVNldEFnZ3JlZ2F0ZU9wdGlvbihvcHRpb25fZmllbGQsIHVua25vd25fZmllbGRzKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBicmVhazsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OkFnZ3JlZ2F0ZU9wdGlvbkZpbmRlcgorICAgIDogcHVibGljIFRleHRGb3JtYXQ6OkZpbmRlciB7CisgcHVibGljOgorICBEZXNjcmlwdG9yQnVpbGRlciogYnVpbGRlcl87CisKKyAgdmlydHVhbCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb24oCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgICBhc3NlcnRfbXV0ZXhfaGVsZChidWlsZGVyXy0+cG9vbF8pOworICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgICAgU3ltYm9sIHJlc3VsdCA9IGJ1aWxkZXJfLT5Mb29rdXBTeW1ib2xOb1BsYWNlaG9sZGVyKAorICAgICAgICBuYW1lLCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSk7CisgICAgaWYgKHJlc3VsdC50eXBlID09IFN5bWJvbDo6RklFTEQgJiYKKyAgICAgICAgcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgICByZXR1cm4gcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3I7CisgICAgfSBlbHNlIGlmIChyZXN1bHQudHlwZSA9PSBTeW1ib2w6Ok1FU1NBR0UgJiYKKyAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBmb3JlaWduX3R5cGUgPSByZXN1bHQuZGVzY3JpcHRvcjsKKyAgICAgIC8vIFRoZSB0ZXh0IGZvcm1hdCBhbGxvd3MgTWVzc2FnZVNldCBpdGVtcyB0byBiZSBzcGVjaWZpZWQgdXNpbmcKKyAgICAgIC8vIHRoZSB0eXBlIG5hbWUsIHJhdGhlciB0aGFuIHRoZSBleHRlbnNpb24gaWRlbnRpZmllci4gSWYgdGhlIHN5bWJvbAorICAgICAgLy8gbG9va3VwIHJldHVybmVkIGEgTWVzc2FnZSwgYW5kIHRoZSBlbmNsb3NpbmcgTWVzc2FnZSBoYXMKKyAgICAgIC8vIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gdHJ1ZSwgdGhlbiByZXR1cm4gdGhlIG1lc3NhZ2Ugc2V0CisgICAgICAvLyBleHRlbnNpb24sIGlmIG9uZSBleGlzdHMuCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZvcmVpZ25fdHlwZS0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9IGZvcmVpZ25fdHlwZS0+ZXh0ZW5zaW9uKGkpOworICAgICAgICBpZiAoZXh0ZW5zaW9uLT5jb250YWluaW5nX3R5cGUoKSA9PSBkZXNjcmlwdG9yICYmCisgICAgICAgICAgICBleHRlbnNpb24tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSAmJgorICAgICAgICAgICAgZXh0ZW5zaW9uLT5pc19vcHRpb25hbCgpICYmCisgICAgICAgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdHlwZSgpID09IGZvcmVpZ25fdHlwZSkgeworICAgICAgICAgIC8vIEZvdW5kIGl0LgorICAgICAgICAgIHJldHVybiBleHRlbnNpb247CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK307CisKKy8vIEEgY3VzdG9tIGVycm9yIGNvbGxlY3RvciB0byByZWNvcmQgYW55IHRleHQtZm9ybWF0IHBhcnNpbmcgZXJyb3JzCituYW1lc3BhY2UgeworY2xhc3MgQWdncmVnYXRlRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgaW86OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIHN0cmluZyBlcnJvcl87CisKKyAgdmlydHVhbCB2b2lkIEFkZEVycm9yKGludCAvKiBsaW5lICovLCBpbnQgLyogY29sdW1uICovLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgaWYgKCFlcnJvcl8uZW1wdHkoKSkgeworICAgICAgZXJyb3JfICs9ICI7ICI7CisgICAgfQorICAgIGVycm9yXyArPSBtZXNzYWdlOworICB9CisKKyAgdmlydHVhbCB2b2lkIEFkZFdhcm5pbmcoaW50IC8qIGxpbmUgKi8sIGludCAvKiBjb2x1bW4gKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgLyogbWVzc2FnZSAqLykgeworICAgIC8vIElnbm9yZSB3YXJuaW5ncworICB9Cit9OworfQorCisvLyBXZSBjb25zdHJ1Y3QgYSBkeW5hbWljIG1lc3NhZ2Ugb2YgdGhlIHR5cGUgY29ycmVzcG9uZGluZyB0bworLy8gb3B0aW9uX2ZpZWxkLCBwYXJzZSB0aGUgc3VwcGxpZWQgdGV4dC1mb3JtYXQgc3RyaW5nIGludG8gdGhpcworLy8gbWVzc2FnZSwgYW5kIHNlcmlhbGl6ZSB0aGUgcmVzdWx0aW5nIG1lc3NhZ2UgdG8gcHJvZHVjZSB0aGUgdmFsdWUuCitib29sIERlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6U2V0QWdncmVnYXRlT3B0aW9uKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb3B0aW9uX2ZpZWxkLAorICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgaWYgKCF1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19hZ2dyZWdhdGVfdmFsdWUoKSkgeworICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJPcHRpb24gXCIiICsgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIGlzIGEgbWVzc2FnZS4gVG8gc2V0IHRoZSBlbnRpcmUgbWVzc2FnZSwgdXNlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAic3ludGF4IGxpa2UgXCIiICsgb3B0aW9uX2ZpZWxkLT5uYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICIgPSB7IDxwcm90byB0ZXh0IGZvcm1hdD4gfVwiLiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIlRvIHNldCBmaWVsZHMgd2l0aGluIGl0LCB1c2UgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJzeW50YXggbGlrZSBcIiIgKyBvcHRpb25fZmllbGQtPm5hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgIi5mb28gPSB2YWx1ZVwiLiIpOworICB9CisKKyAgY29uc3QgRGVzY3JpcHRvciogdHlwZSA9IG9wdGlvbl9maWVsZC0+bWVzc2FnZV90eXBlKCk7CisgIHNjb3BlZF9wdHI8TWVzc2FnZT4gZHluYW1pYyhkeW5hbWljX2ZhY3RvcnlfLkdldFByb3RvdHlwZSh0eXBlKS0+TmV3KCkpOworICBHT09HTEVfQ0hFQ0soZHluYW1pYy5nZXQoKSAhPSBOVUxMKQorICAgICAgPDwgIkNvdWxkIG5vdCBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgIiA8PCBvcHRpb25fZmllbGQtPkRlYnVnU3RyaW5nKCk7CisKKyAgQWdncmVnYXRlRXJyb3JDb2xsZWN0b3IgY29sbGVjdG9yOworICBBZ2dyZWdhdGVPcHRpb25GaW5kZXIgZmluZGVyOworICBmaW5kZXIuYnVpbGRlcl8gPSBidWlsZGVyXzsKKyAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgcGFyc2VyLlJlY29yZEVycm9yc1RvKCZjb2xsZWN0b3IpOworICBwYXJzZXIuU2V0RmluZGVyKCZmaW5kZXIpOworICBpZiAoIXBhcnNlci5QYXJzZUZyb21TdHJpbmcodW5pbnRlcnByZXRlZF9vcHRpb25fLT5hZ2dyZWdhdGVfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR5bmFtaWMuZ2V0KCkpKSB7CisgICAgQWRkVmFsdWVFcnJvcigiRXJyb3Igd2hpbGUgcGFyc2luZyBvcHRpb24gdmFsdWUgZm9yIFwiIiArCisgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPm5hbWUoKSArICJcIjogIiArIGNvbGxlY3Rvci5lcnJvcl8pOworICAgIHJldHVybiBmYWxzZTsKKyAgfSBlbHNlIHsKKyAgICBzdHJpbmcgc2VyaWFsOworICAgIGR5bmFtaWMtPlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWwpOyAgLy8gTmV2ZXIgZmFpbHMKKyAgICBpZiAob3B0aW9uX2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRMZW5ndGhEZWxpbWl0ZWQob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwgc2VyaWFsKTsKKyAgICB9IGVsc2UgeworICAgICAgR09PR0xFX0NIRUNLX0VRKG9wdGlvbl9maWVsZC0+dHlwZSgpLCAgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKTsKKyAgICAgIFVua25vd25GaWVsZFNldCogZ3JvdXAgPSB1bmtub3duX2ZpZWxkcy0+QWRkR3JvdXAob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSk7CisgICAgICBncm91cC0+UGFyc2VGcm9tU3RyaW5nKHNlcmlhbCk7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpTZXRJbnQzMihpbnQgbnVtYmVyLCBpbnQzMiB2YWx1ZSwKKyAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSwgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMjoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQobnVtYmVyLAorICAgICAgICBzdGF0aWNfY2FzdDx1aW50NjQ+KHN0YXRpY19jYXN0PGludDY0Pih2YWx1ZSkpKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQzMihudW1iZXIsIHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUpKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOgorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChudW1iZXIsCisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpaaWdaYWdFbmNvZGUzMih2YWx1ZSkpOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkludmFsaWQgd2lyZSB0eXBlIGZvciBDUFBUWVBFX0lOVDMyOiAiIDw8IHR5cGU7CisgICAgICBicmVhazsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6U2V0SW50NjQoaW50IG51bWJlciwgaW50NjQgdmFsdWUsCisgICAgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQ6CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KG51bWJlciwgc3RhdGljX2Nhc3Q8dWludDY0Pih2YWx1ZSkpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDY0KG51bWJlciwgc3RhdGljX2Nhc3Q8dWludDY0Pih2YWx1ZSkpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KG51bWJlciwKKyAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlppZ1phZ0VuY29kZTY0KHZhbHVlKSk7CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiSW52YWxpZCB3aXJlIHR5cGUgZm9yIENQUFRZUEVfSU5UNjQ6ICIgPDwgdHlwZTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpTZXRVSW50MzIoaW50IG51bWJlciwgdWludDMyIHZhbHVlLAorICAgIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlLCBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQobnVtYmVyLCBzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzI6CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQzMihudW1iZXIsIHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUpKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJJbnZhbGlkIHdpcmUgdHlwZSBmb3IgQ1BQVFlQRV9VSU5UMzI6ICIgPDwgdHlwZTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpTZXRVSW50NjQoaW50IG51bWJlciwgdWludDY0IHZhbHVlLAorICAgIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlLCBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NDoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQobnVtYmVyLCB2YWx1ZSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQ2NChudW1iZXIsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJJbnZhbGlkIHdpcmUgdHlwZSBmb3IgQ1BQVFlQRV9VSU5UNjQ6ICIgPDwgdHlwZTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkxvZ1VudXNlZERlcGVuZGVuY3koY29uc3QgRmlsZURlc2NyaXB0b3IqIHJlc3VsdCkgeworCisgIGlmICghdW51c2VkX2RlcGVuZGVuY3lfLmVtcHR5KCkpIHsKKyAgICBzdGQ6OnNldDxzdHJpbmc+IGFubm90YXRpb25fZXh0ZW5zaW9uczsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIik7CisgICAgYW5ub3RhdGlvbl9leHRlbnNpb25zLmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIik7CisgICAgYW5ub3RhdGlvbl9leHRlbnNpb25zLmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyIpOworICAgIGFubm90YXRpb25fZXh0ZW5zaW9ucy5pbnNlcnQoImdvb2dsZS5wcm90b2J1Zi5TdHJlYW1PcHRpb25zIik7CisgICAgZm9yIChzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPjo6Y29uc3RfaXRlcmF0b3IKKyAgICAgICAgICAgICBpdCA9IHVudXNlZF9kZXBlbmRlbmN5Xy5iZWdpbigpOworICAgICAgICAgaXQgIT0gdW51c2VkX2RlcGVuZGVuY3lfLmVuZCgpOyArK2l0KSB7CisgICAgICAvLyBEbyBub3QgbG9nIHdhcm5pbmdzIGZvciBwcm90byBmaWxlcyB3aGljaCBleHRlbmQgYW5ub3RhdGlvbnMuCisgICAgICBpbnQgaTsKKyAgICAgIGZvciAoaSA9IDAgOyBpIDwgKCppdCktPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICAgICAgaWYgKGFubm90YXRpb25fZXh0ZW5zaW9ucy5maW5kKAorICAgICAgICAgICAgICAgICgqaXQpLT5leHRlbnNpb24oaSktPmNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSkKKyAgICAgICAgICAgICE9IGFubm90YXRpb25fZXh0ZW5zaW9ucy5lbmQoKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICAvLyBMb2cgd2FybmluZ3MgZm9yIHVudXNlZCBpbXBvcnRlZCBmaWxlcy4KKyAgICAgIGlmIChpID09ICgqaXQpLT5leHRlbnNpb25fY291bnQoKSkgeworICAgICAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJXYXJuaW5nOiBVbnVzZWQgaW1wb3J0OiBcIiIgPDwgcmVzdWx0LT5uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgIDw8ICJcIiBpbXBvcnRzIFwiIiA8PCAoKml0KS0+bmFtZSgpCisgICAgICAgICAgICAgICAgICAgICA8PCAiXCIgd2hpY2ggaXMgbm90IHVzZWQuIjsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlMjY0ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaApAQCAtMCwwICsxLDE3ODQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgY2xhc3NlcyB3aGljaCBkZXNjcmliZSBhIHR5cGUgb2YgcHJvdG9jb2wgbWVzc2FnZS4KKy8vIFlvdSBjYW4gdXNlIGEgbWVzc2FnZSdzIGRlc2NyaXB0b3IgdG8gbGVhcm4gYXQgcnVudGltZSB3aGF0IGZpZWxkcworLy8gaXQgY29udGFpbnMgYW5kIHdoYXQgdGhlIHR5cGVzIG9mIHRob3NlIGZpZWxkcyBhcmUuICBUaGUgTWVzc2FnZQorLy8gaW50ZXJmYWNlIGFsc28gYWxsb3dzIHlvdSB0byBkeW5hbWljYWxseSBhY2Nlc3MgYW5kIG1vZGlmeSBpbmRpdmlkdWFsCisvLyBmaWVsZHMgYnkgcGFzc2luZyB0aGUgRmllbGREZXNjcmlwdG9yIG9mIHRoZSBmaWVsZCB5b3UgYXJlIGludGVyZXN0ZWQKKy8vIGluLgorLy8KKy8vIE1vc3QgdXNlcnMgd2lsbCBub3QgY2FyZSBhYm91dCBkZXNjcmlwdG9ycywgYmVjYXVzZSB0aGV5IHdpbGwgd3JpdGUKKy8vIGNvZGUgc3BlY2lmaWMgdG8gY2VydGFpbiBwcm90b2NvbCB0eXBlcyBhbmQgd2lsbCBzaW1wbHkgdXNlIHRoZSBjbGFzc2VzCisvLyBnZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGNvbXBpbGVyIGRpcmVjdGx5LiAgQWR2YW5jZWQgdXNlcnMgd2hvIHdhbnQKKy8vIHRvIG9wZXJhdGUgb24gYXJiaXRyYXJ5IHR5cGVzIChub3Qga25vd24gYXQgY29tcGlsZSB0aW1lKSBtYXkgd2FudCB0bworLy8gcmVhZCBkZXNjcmlwdG9ycyBpbiBvcmRlciB0byBsZWFybiBhYm91dCB0aGUgY29udGVudHMgb2YgYSBtZXNzYWdlLgorLy8gQSB2ZXJ5IHNtYWxsIG51bWJlciBvZiB1c2VycyB3aWxsIHdhbnQgdG8gY29uc3RydWN0IHRoZWlyIG93bgorLy8gRGVzY3JpcHRvcnMsIGVpdGhlciBiZWNhdXNlIHRoZXkgYXJlIGltcGxlbWVudGluZyBNZXNzYWdlIG1hbnVhbGx5IG9yCisvLyBiZWNhdXNlIHRoZXkgYXJlIHdyaXRpbmcgc29tZXRoaW5nIGxpa2UgdGhlIHByb3RvY29sIGNvbXBpbGVyLgorLy8KKy8vIEZvciBhbiBleGFtcGxlIG9mIGhvdyB5b3UgbWlnaHQgdXNlIGRlc2NyaXB0b3JzLCBzZWUgdGhlIGNvZGUgZXhhbXBsZQorLy8gYXQgdGhlIHRvcCBvZiBtZXNzYWdlLmguCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SX0hfXworCisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBEZXNjcmlwdG9yOworY2xhc3MgRmllbGREZXNjcmlwdG9yOworY2xhc3MgT25lb2ZEZXNjcmlwdG9yOworY2xhc3MgRW51bURlc2NyaXB0b3I7CitjbGFzcyBFbnVtVmFsdWVEZXNjcmlwdG9yOworY2xhc3MgU2VydmljZURlc2NyaXB0b3I7CitjbGFzcyBNZXRob2REZXNjcmlwdG9yOworY2xhc3MgRmlsZURlc2NyaXB0b3I7CitjbGFzcyBEZXNjcmlwdG9yRGF0YWJhc2U7CitjbGFzcyBEZXNjcmlwdG9yUG9vbDsKKworLy8gRGVmaW5lZCBpbiBkZXNjcmlwdG9yLnByb3RvCitjbGFzcyBEZXNjcmlwdG9yUHJvdG87CitjbGFzcyBGaWVsZERlc2NyaXB0b3JQcm90bzsKK2NsYXNzIE9uZW9mRGVzY3JpcHRvclByb3RvOworY2xhc3MgRW51bURlc2NyaXB0b3JQcm90bzsKK2NsYXNzIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzsKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG87CitjbGFzcyBNZXRob2REZXNjcmlwdG9yUHJvdG87CitjbGFzcyBGaWxlRGVzY3JpcHRvclByb3RvOworY2xhc3MgTWVzc2FnZU9wdGlvbnM7CitjbGFzcyBGaWVsZE9wdGlvbnM7CitjbGFzcyBFbnVtT3B0aW9uczsKK2NsYXNzIEVudW1WYWx1ZU9wdGlvbnM7CitjbGFzcyBTZXJ2aWNlT3B0aW9uczsKK2NsYXNzIE1ldGhvZE9wdGlvbnM7CitjbGFzcyBGaWxlT3B0aW9uczsKK2NsYXNzIFVuaW50ZXJwcmV0ZWRPcHRpb247CitjbGFzcyBTb3VyY2VDb2RlSW5mbzsKKworLy8gRGVmaW5lZCBpbiBtZXNzYWdlLmgKK2NsYXNzIE1lc3NhZ2U7CisKKy8vIERlZmluZWQgaW4gZGVzY3JpcHRvci5jYworY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CitjbGFzcyBGaWxlRGVzY3JpcHRvclRhYmxlczsKKworLy8gRGVmaW5lZCBpbiB1bmtub3duX2ZpZWxkX3NldC5oLgorY2xhc3MgVW5rbm93bkZpZWxkOworCisvLyBEZWZpbmVkIGluIGdlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaC4KK25hbWVzcGFjZSBpbnRlcm5hbCB7CisgIGNsYXNzIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworfQorCisvLyBOQiwgYWxsIGluZGljZXMgYXJlIHplcm8tYmFzZWQuCitzdHJ1Y3QgU291cmNlTG9jYXRpb24geworICBpbnQgc3RhcnRfbGluZTsKKyAgaW50IGVuZF9saW5lOworICBpbnQgc3RhcnRfY29sdW1uOworICBpbnQgZW5kX2NvbHVtbjsKKworICAvLyBEb2MgY29tbWVudHMgZm91bmQgYXQgdGhlIHNvdXJjZSBsb2NhdGlvbi4KKyAgLy8gU2VlIHRoZSBjb21tZW50cyBpbiBTb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiAoZGVzY3JpcHRvci5wcm90bykgZm9yIGRldGFpbHMuCisgIHN0cmluZyBsZWFkaW5nX2NvbW1lbnRzOworICBzdHJpbmcgdHJhaWxpbmdfY29tbWVudHM7CisgIHZlY3RvcjxzdHJpbmc+IGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHM7Cit9OworCisvLyBPcHRpb25zIHdoZW4gZ2VuZXJhdGluZyBtYWNoaW5lLXBhcnNhYmxlIG91dHB1dCBmcm9tIGEgZGVzY3JpcHRvciB3aXRoCisvLyBEZWJ1Z1N0cmluZygpLgorc3RydWN0IERlYnVnU3RyaW5nT3B0aW9ucyB7CisgIC8vIGluY2x1ZGUgb3JpZ2luYWwgdXNlciBjb21tZW50cyBhcyByZWNvcmRlZCBpbiBTb3VyY2VMb2NhdGlvbiBlbnRyaWVzLiBOLkIuCisgIC8vIHRoYXQgdGhpcyBtdXN0IGJlIHxmYWxzZXwgYnkgZGVmYXVsdDogc2V2ZXJhbCBvdGhlciBwaWVjZXMgb2YgY29kZSAoZm9yCisgIC8vIGV4YW1wbGUsIHRoZSBDKysgY29kZSBnZW5lcmF0aW9uIGZvciBmaWVsZHMgaW4gdGhlIHByb3RvIGNvbXBpbGVyKSByZWx5IG9uCisgIC8vIERlYnVnU3RyaW5nKCkgb3V0cHV0IGJlaW5nIHVub2JzdHJ1Y3RlZCBieSB1c2VyIGNvbW1lbnRzLgorICBib29sIGluY2x1ZGVfY29tbWVudHM7CisKKyAgRGVidWdTdHJpbmdPcHRpb25zKCkKKyAgICAgIDogaW5jbHVkZV9jb21tZW50cyhmYWxzZSkKKyAge30KK307CisKKy8vIERlc2NyaWJlcyBhIHR5cGUgb2YgcHJvdG9jb2wgbWVzc2FnZSwgb3IgYSBwYXJ0aWN1bGFyIGdyb3VwIHdpdGhpbiBhCisvLyBtZXNzYWdlLiAgVG8gb2J0YWluIHRoZSBEZXNjcmlwdG9yIGZvciBhIGdpdmVuIG1lc3NhZ2Ugb2JqZWN0LCBjYWxsCisvLyBNZXNzYWdlOjpHZXREZXNjcmlwdG9yKCkuICBHZW5lcmF0ZWQgbWVzc2FnZSBjbGFzc2VzIGFsc28gaGF2ZSBhCisvLyBzdGF0aWMgbWV0aG9kIGNhbGxlZCBkZXNjcmlwdG9yKCkgd2hpY2ggcmV0dXJucyB0aGUgdHlwZSdzIGRlc2NyaXB0b3IuCisvLyBVc2UgRGVzY3JpcHRvclBvb2wgdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIERlc2NyaXB0b3IgeworIHB1YmxpYzoKKyAgLy8gVGhlIG5hbWUgb2YgdGhlIG1lc3NhZ2UgdHlwZSwgbm90IGluY2x1ZGluZyBpdHMgc2NvcGUuCisgIGNvbnN0IHN0cmluZyYgbmFtZSgpIGNvbnN0OworCisgIC8vIFRoZSBmdWxseS1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgbWVzc2FnZSB0eXBlLCBzY29wZSBkZWxpbWl0ZWQgYnkKKyAgLy8gcGVyaW9kcy4gIEZvciBleGFtcGxlLCBtZXNzYWdlIHR5cGUgIkZvbyIgd2hpY2ggaXMgZGVjbGFyZWQgaW4gcGFja2FnZQorICAvLyAiYmFyIiBoYXMgZnVsbCBuYW1lICJiYXIuRm9vIi4gIElmIGEgdHlwZSAiQmF6IiBpcyBuZXN0ZWQgd2l0aGluCisgIC8vIEZvbywgQmF6J3MgZnVsbF9uYW1lIGlzICJiYXIuRm9vLkJheiIuICBUbyBnZXQgb25seSB0aGUgcGFydCB0aGF0CisgIC8vIGNvbWVzIGFmdGVyIHRoZSBsYXN0ICcuJywgdXNlIG5hbWUoKS4KKyAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUoKSBjb25zdDsKKworICAvLyBJbmRleCBvZiB0aGlzIGRlc2NyaXB0b3Igd2l0aGluIHRoZSBmaWxlIG9yIGNvbnRhaW5pbmcgdHlwZSdzIG1lc3NhZ2UKKyAgLy8gdHlwZSBhcnJheS4KKyAgaW50IGluZGV4KCkgY29uc3Q7CisKKyAgLy8gVGhlIC5wcm90byBmaWxlIGluIHdoaWNoIHRoaXMgbWVzc2FnZSB0eXBlIHdhcyBkZWZpbmVkLiAgTmV2ZXIgTlVMTC4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUoKSBjb25zdDsKKworICAvLyBJZiB0aGlzIERlc2NyaXB0b3IgZGVzY3JpYmVzIGEgbmVzdGVkIHR5cGUsIHRoaXMgcmV0dXJucyB0aGUgdHlwZQorICAvLyBpbiB3aGljaCBpdCBpcyBuZXN0ZWQuICBPdGhlcndpc2UsIHJldHVybnMgTlVMTC4KKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlKCkgY29uc3Q7CisKKyAgLy8gR2V0IG9wdGlvbnMgZm9yIHRoaXMgbWVzc2FnZSB0eXBlLiAgVGhlc2UgYXJlIHNwZWNpZmllZCBpbiB0aGUgLnByb3RvIGZpbGUKKyAgLy8gYnkgcGxhY2luZyBsaW5lcyBsaWtlICJvcHRpb24gZm9vID0gMTIzNDsiIGluIHRoZSBtZXNzYWdlIGRlZmluaXRpb24uCisgIC8vIEFsbG93ZWQgb3B0aW9ucyBhcmUgZGVmaW5lZCBieSBNZXNzYWdlT3B0aW9ucyBpbgorICAvLyBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bywgYW5kIGFueSBhdmFpbGFibGUgZXh0ZW5zaW9ucyBvZiB0aGF0CisgIC8vIG1lc3NhZ2UuCisgIGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gV3JpdGUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgRGVzY3JpcHRvciBpbnRvIHRoZSBnaXZlbiBEZXNjcmlwdG9yUHJvdG8uCisgIC8vIFRoZSB0YXJnZXQgRGVzY3JpcHRvclByb3RvIG11c3QgYmUgY2xlYXIgYmVmb3JlIGNhbGxpbmcgdGhpczsgaWYgaXQKKyAgLy8gaXNuJ3QsIHRoZSByZXN1bHQgbWF5IGJlIGdhcmJhZ2UuCisgIHZvaWQgQ29weVRvKERlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0OworCisgIC8vIFdyaXRlIHRoZSBjb250ZW50cyBvZiB0aGlzIGRlY3JpcHRvciBpbiBhIGh1bWFuLXJlYWRhYmxlIGZvcm0uIE91dHB1dAorICAvLyB3aWxsIGJlIHN1aXRhYmxlIGZvciByZS1wYXJzaW5nLgorICBzdHJpbmcgRGVidWdTdHJpbmcoKSBjb25zdDsKKworICAvLyBTaW1pbGFyIHRvIERlYnVnU3RyaW5nKCksIGJ1dCBhZGRpdGlvbmFsbHkgdGFrZXMgb3B0aW9ucyAoZS5nLiwKKyAgLy8gaW5jbHVkZSBvcmlnaW5hbCB1c2VyIGNvbW1lbnRzIGluIG91dHB1dCkuCisgIHN0cmluZyBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBwbGFjZWhvbGRlciBmb3IgYW4gdW5rbm93biB0eXBlLiBUaGlzIHdpbGwKKyAgLy8gb25seSBiZSB0aGUgY2FzZSBpZiB0aGlzIGRlc2NyaXB0b3IgY29tZXMgZnJvbSBhIERlc2NyaXB0b3JQb29sCisgIC8vIHdpdGggQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzKCkgc2V0LgorICBib29sIGlzX3BsYWNlaG9sZGVyKCkgY29uc3Q7CisKKyAgLy8gRmllbGQgc3R1ZmYgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBUaGUgbnVtYmVyIG9mIGZpZWxkcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IGZpZWxkX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSBmaWVsZCBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IGZpZWxkX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gTG9va3MgdXAgYSBmaWVsZCBieSBkZWNsYXJlZCB0YWcgbnVtYmVyLiAgUmV0dXJucyBOVUxMIGlmIG5vIHN1Y2ggZmllbGQKKyAgLy8gZXhpc3RzLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5TnVtYmVyKGludCBudW1iZXIpIGNvbnN0OworICAvLyBMb29rcyB1cCBhIGZpZWxkIGJ5IG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm8gc3VjaCBmaWVsZCBleGlzdHMuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEZpZWxkQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gTG9va3MgdXAgYSBmaWVsZCBieSBsb3dlcmNhc2VkIG5hbWUgKGFzIHJldHVybmVkIGJ5IGxvd2VyY2FzZV9uYW1lKCkpLgorICAvLyBUaGlzIGxvb2t1cCBtYXkgYmUgYW1iaWd1b3VzIGlmIG11bHRpcGxlIGZpZWxkIG5hbWVzIGRpZmZlciBvbmx5IGJ5IGNhc2UsCisgIC8vIGluIHdoaWNoIGNhc2UgdGhlIGZpZWxkIHJldHVybmVkIGlzIGNob3NlbiBhcmJpdHJhcmlseSBmcm9tIHRoZSBtYXRjaGVzLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgKKyAgICAgIGNvbnN0IHN0cmluZyYgbG93ZXJjYXNlX25hbWUpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgZmllbGQgYnkgY2FtZWwtY2FzZSBuYW1lIChhcyByZXR1cm5lZCBieSBjYW1lbGNhc2VfbmFtZSgpKS4KKyAgLy8gVGhpcyBsb29rdXAgbWF5IGJlIGFtYmlndW91cyBpZiBtdWx0aXBsZSBmaWVsZCBuYW1lcyBkaWZmZXIgaW4gYSB3YXkgdGhhdAorICAvLyBsZWFkcyB0aGVtIHRvIGhhdmUgaWRlbnRpY2FsIGNhbWVsLWNhc2UgbmFtZXMsIGluIHdoaWNoIGNhc2UgdGhlIGZpZWxkCisgIC8vIHJldHVybmVkIGlzIGNob3NlbiBhcmJpdHJhcmlseSBmcm9tIHRoZSBtYXRjaGVzLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgKKyAgICAgIGNvbnN0IHN0cmluZyYgY2FtZWxjYXNlX25hbWUpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2Ygb25lb2ZzIGluIHRoaXMgbWVzc2FnZSB0eXBlLgorICBpbnQgb25lb2ZfZGVjbF9jb3VudCgpIGNvbnN0OworICAvLyBHZXQgYSBvbmVvZiBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IG9uZW9mX2RlY2xfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVjbChpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgb25lb2YgYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBubyBzdWNoIG9uZW9mIGV4aXN0cy4KKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBGaW5kT25lb2ZCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBOZXN0ZWQgdHlwZSBzdHVmZiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFRoZSBudW1iZXIgb2YgbmVzdGVkIHR5cGVzIGluIHRoaXMgbWVzc2FnZSB0eXBlLgorICBpbnQgbmVzdGVkX3R5cGVfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhIG5lc3RlZCB0eXBlIGJ5IGluZGV4LCB3aGVyZSAwIDw9IGluZGV4IDwgbmVzdGVkX3R5cGVfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IERlc2NyaXB0b3IqIG5lc3RlZF90eXBlKGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gTG9va3MgdXAgYSBuZXN0ZWQgdHlwZSBieSBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vIHN1Y2ggbmVzdGVkIHR5cGUKKyAgLy8gZXhpc3RzLgorICBjb25zdCBEZXNjcmlwdG9yKiBGaW5kTmVzdGVkVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworCisgIC8vIEVudW0gc3R1ZmYgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVGhlIG51bWJlciBvZiBlbnVtIHR5cGVzIGluIHRoaXMgbWVzc2FnZSB0eXBlLgorICBpbnQgZW51bV90eXBlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYW4gZW51bSB0eXBlIGJ5IGluZGV4LCB3aGVyZSAwIDw9IGluZGV4IDwgZW51bV90eXBlX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlKGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gTG9va3MgdXAgYW4gZW51bSB0eXBlIGJ5IG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm8gc3VjaCBlbnVtIHR5cGUgZXhpc3RzLgorICBjb25zdCBFbnVtRGVzY3JpcHRvciogRmluZEVudW1UeXBlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gTG9va3MgdXAgYW4gZW51bSB2YWx1ZSBieSBuYW1lLCBhbW9uZyBhbGwgZW51bSB0eXBlcyBpbiB0aGlzIG1lc3NhZ2UuCisgIC8vIFJldHVybnMgTlVMTCBpZiBubyBzdWNoIHZhbHVlIGV4aXN0cy4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZEVudW1WYWx1ZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworCisgIC8vIEV4dGVuc2lvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gQSByYW5nZSBvZiBmaWVsZCBudW1iZXJzIHdoaWNoIGFyZSBkZXNpZ25hdGVkIGZvciB0aGlyZC1wYXJ0eQorICAvLyBleHRlbnNpb25zLgorICBzdHJ1Y3QgRXh0ZW5zaW9uUmFuZ2UgeworICAgIGludCBzdGFydDsgIC8vIGluY2x1c2l2ZQorICAgIGludCBlbmQ7ICAgIC8vIGV4Y2x1c2l2ZQorICB9OworCisgIC8vIFRoZSBudW1iZXIgb2YgZXh0ZW5zaW9uIHJhbmdlcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IGV4dGVuc2lvbl9yYW5nZV9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGFuIGV4dGVuc2lvbiByYW5nZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8CisgIC8vIGV4dGVuc2lvbl9yYW5nZV9jb3VudCgpLiBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkCisgIC8vIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRXh0ZW5zaW9uUmFuZ2UqIGV4dGVuc2lvbl9yYW5nZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgbnVtYmVyIGlzIGluIG9uZSBvZiB0aGUgZXh0ZW5zaW9uIHJhbmdlcy4KKyAgYm9vbCBJc0V4dGVuc2lvbk51bWJlcihpbnQgbnVtYmVyKSBjb25zdDsKKworICAvLyBSZXR1cm5zIE5VTEwgaWYgbm8gZXh0ZW5zaW9uIHJhbmdlIGNvbnRhaW5zIHRoZSBnaXZlbiBudW1iZXIuCisgIGNvbnN0IEV4dGVuc2lvblJhbmdlKiBGaW5kRXh0ZW5zaW9uUmFuZ2VDb250YWluaW5nTnVtYmVyKGludCBudW1iZXIpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2YgZXh0ZW5zaW9ucyAtLSBleHRlbmRpbmcgKm90aGVyKiBtZXNzYWdlcyAtLSB0aGF0IHdlcmUKKyAgLy8gZGVmaW5lZCBuZXN0ZWQgd2l0aGluIHRoaXMgbWVzc2FnZSB0eXBlJ3Mgc2NvcGUuCisgIGludCBleHRlbnNpb25fY291bnQoKSBjb25zdDsKKyAgLy8gR2V0IGFuIGV4dGVuc2lvbiBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IGV4dGVuc2lvbl9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24oaW50IGluZGV4KSBjb25zdDsKKworICAvLyBMb29rcyB1cCBhIG5hbWVkIGV4dGVuc2lvbiAod2hpY2ggZXh0ZW5kcyBzb21lICpvdGhlciogbWVzc2FnZSB0eXBlKQorICAvLyBkZWZpbmVkIHdpdGhpbiB0aGlzIG1lc3NhZ2UgdHlwZSdzIHNjb3BlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBTaW1pbGFyIHRvIEZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgpLCBidXQgZmluZHMgZXh0ZW5zaW9ucyBkZWZpbmVkIHdpdGhpbgorICAvLyB0aGlzIG1lc3NhZ2UgdHlwZSdzIHNjb3BlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBTaW1pbGFyIHRvIEZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgpLCBidXQgZmluZHMgZXh0ZW5zaW9ucyBkZWZpbmVkIHdpdGhpbgorICAvLyB0aGlzIG1lc3NhZ2UgdHlwZSdzIHNjb3BlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBTb3VyY2UgTG9jYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVXBkYXRlcyB8Km91dF9sb2NhdGlvbnwgdG8gdGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgY29tcGxldGUKKyAgLy8gZXh0ZW50IG9mIHRoaXMgbWVzc2FnZSBkZWNsYXJhdGlvbi4gIFJldHVybnMgZmFsc2UgYW5kIGxlYXZlcworICAvLyB8Km91dF9sb2NhdGlvbnwgdW5jaGFuZ2VkIGlmZiBsb2NhdGlvbiBpbmZvcm1hdGlvbiB3YXMgbm90IGF2YWlsYWJsZS4KKyAgYm9vbCBHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdDsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgTWVzc2FnZU9wdGlvbnMgT3B0aW9uc1R5cGU7CisKKyAgLy8gSW50ZXJuYWwgdmVyc2lvbiBvZiBEZWJ1Z1N0cmluZzsgY29udHJvbHMgdGhlIGxldmVsIG9mIGluZGVudGluZyBmb3IKKyAgLy8gY29ycmVjdCBkZXB0aC4gVGFrZXMgfG9wdGlvbnN8IHRvIGNvbnRyb2wgZGVidWctc3RyaW5nIG9wdGlvbnMsIGFuZAorICAvLyB8aW5jbHVkZV9vcGVuaW5nX2NsYXVzZXwgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgIm1lc3NhZ2UgLi4uICIgcGFydCBvZiB0aGUKKyAgLy8gY2xhdXNlIGhhcyBhbHJlYWR5IGJlZW4gZ2VuZXJhdGVkICh0aGlzIHZhcmllcyBkZXBlbmRpbmcgb24gY29udGV4dCkuCisgIHZvaWQgRGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICBib29sIGluY2x1ZGVfb3BlbmluZ19jbGF1c2UpIGNvbnN0OworCisgIC8vIFdhbGtzIHVwIHRoZSBkZXNjcmlwdG9yIHRyZWUgdG8gZ2VuZXJhdGUgdGhlIHNvdXJjZSBsb2NhdGlvbiBwYXRoCisgIC8vIHRvIHRoaXMgZGVzY3JpcHRvciBmcm9tIHRoZSBmaWxlIHJvb3QuCisgIHZvaWQgR2V0TG9jYXRpb25QYXRoKHN0ZDo6dmVjdG9yPGludD4qIG91dHB1dCkgY29uc3Q7CisKKyAgY29uc3Qgc3RyaW5nKiBuYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBmdWxsX25hbWVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZV87CisgIGNvbnN0IE1lc3NhZ2VPcHRpb25zKiBvcHRpb25zXzsKKworICAvLyBUcnVlIGlmIHRoaXMgaXMgYSBwbGFjZWhvbGRlciBmb3IgYW4gdW5rbm93biB0eXBlLgorICBib29sIGlzX3BsYWNlaG9sZGVyXzsKKyAgLy8gVHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgYW5kIHRoZSB0eXBlIG5hbWUgd2Fzbid0IGZ1bGx5LXF1YWxpZmllZC4KKyAgYm9vbCBpc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl87CisKKyAgaW50IGZpZWxkX2NvdW50XzsKKyAgRmllbGREZXNjcmlwdG9yKiBmaWVsZHNfOworICBpbnQgb25lb2ZfZGVjbF9jb3VudF87CisgIE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVjbHNfOworICBpbnQgbmVzdGVkX3R5cGVfY291bnRfOworICBEZXNjcmlwdG9yKiBuZXN0ZWRfdHlwZXNfOworICBpbnQgZW51bV90eXBlX2NvdW50XzsKKyAgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZXNfOworICBpbnQgZXh0ZW5zaW9uX3JhbmdlX2NvdW50XzsKKyAgRXh0ZW5zaW9uUmFuZ2UqIGV4dGVuc2lvbl9yYW5nZXNfOworICBpbnQgZXh0ZW5zaW9uX2NvdW50XzsKKyAgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb25zXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxEZXNjcmlwdG9yPigpIGFuZCBBbGxvY2F0ZUFycmF5PERlc2NyaXB0b3I+KCkgaW4gZGVzY3JpcHRvci5jYworICAvLyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIEVudW1EZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgT25lb2ZEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgTWV0aG9kRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGVzY3JpcHRvcik7Cit9OworCisvLyBEZXNjcmliZXMgYSBzaW5nbGUgZmllbGQgb2YgYSBtZXNzYWdlLiAgVG8gZ2V0IHRoZSBkZXNjcmlwdG9yIGZvciBhIGdpdmVuCisvLyBmaWVsZCwgZmlyc3QgZ2V0IHRoZSBEZXNjcmlwdG9yIGZvciB0aGUgbWVzc2FnZSBpbiB3aGljaCBpdCBpcyBkZWZpbmVkLAorLy8gdGhlbiBjYWxsIERlc2NyaXB0b3I6OkZpbmRGaWVsZEJ5TmFtZSgpLiAgVG8gZ2V0IGEgRmllbGREZXNjcmlwdG9yIGZvcgorLy8gYW4gZXh0ZW5zaW9uLCBkbyBvbmUgb2YgdGhlIGZvbGxvd2luZzoKKy8vIC0gR2V0IHRoZSBEZXNjcmlwdG9yIG9yIEZpbGVEZXNjcmlwdG9yIGZvciBpdHMgY29udGFpbmluZyBzY29wZSwgdGhlbgorLy8gICBjYWxsIERlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeU5hbWUoKSBvcgorLy8gICBGaWxlRGVzY3JpcHRvcjo6RmluZEV4dGVuc2lvbkJ5TmFtZSgpLgorLy8gLSBHaXZlbiBhIERlc2NyaXB0b3JQb29sLCBjYWxsIERlc2NyaXB0b3JQb29sOjpGaW5kRXh0ZW5zaW9uQnlOdW1iZXIoKS4KKy8vIC0gR2l2ZW4gYSBSZWZsZWN0aW9uIGZvciBhIG1lc3NhZ2Ugb2JqZWN0LCBjYWxsCisvLyAgIFJlZmxlY3Rpb246OkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgpIG9yCisvLyAgIFJlZmxlY3Rpb246OkZpbmRLbm93bkV4dGVuc2lvbkJ5TnVtYmVyKCkuCisvLyBVc2UgRGVzY3JpcHRvclBvb2wgdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkRGVzY3JpcHRvciB7CisgcHVibGljOgorICAvLyBJZGVudGlmaWVzIGEgZmllbGQgdHlwZS4gIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycy4gIFRoZSBvcmRlciBpcyB3ZWlyZAorICAvLyBmb3IgaGlzdG9yaWNhbCByZWFzb25zLiAgVHlwZXMgMTIgYW5kIHVwIGFyZSBuZXcgaW4gcHJvdG8yLgorICBlbnVtIFR5cGUgeworICAgIFRZUEVfRE9VQkxFICAgICAgICAgPSAxLCAgIC8vIGRvdWJsZSwgZXhhY3RseSBlaWdodCBieXRlcyBvbiB0aGUgd2lyZS4KKyAgICBUWVBFX0ZMT0FUICAgICAgICAgID0gMiwgICAvLyBmbG9hdCwgZXhhY3RseSBmb3VyIGJ5dGVzIG9uIHRoZSB3aXJlLgorICAgIFRZUEVfSU5UNjQgICAgICAgICAgPSAzLCAgIC8vIGludDY0LCB2YXJpbnQgb24gdGhlIHdpcmUuICBOZWdhdGl2ZSBudW1iZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSAxMCBieXRlcy4gIFVzZSBUWVBFX1NJTlQ2NCBpZiBuZWdhdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBhcmUgbGlrZWx5LgorICAgIFRZUEVfVUlOVDY0ICAgICAgICAgPSA0LCAgIC8vIHVpbnQ2NCwgdmFyaW50IG9uIHRoZSB3aXJlLgorICAgIFRZUEVfSU5UMzIgICAgICAgICAgPSA1LCAgIC8vIGludDMyLCB2YXJpbnQgb24gdGhlIHdpcmUuICBOZWdhdGl2ZSBudW1iZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSAxMCBieXRlcy4gIFVzZSBUWVBFX1NJTlQzMiBpZiBuZWdhdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBhcmUgbGlrZWx5LgorICAgIFRZUEVfRklYRUQ2NCAgICAgICAgPSA2LCAgIC8vIHVpbnQ2NCwgZXhhY3RseSBlaWdodCBieXRlcyBvbiB0aGUgd2lyZS4KKyAgICBUWVBFX0ZJWEVEMzIgICAgICAgID0gNywgICAvLyB1aW50MzIsIGV4YWN0bHkgZm91ciBieXRlcyBvbiB0aGUgd2lyZS4KKyAgICBUWVBFX0JPT0wgICAgICAgICAgID0gOCwgICAvLyBib29sLCB2YXJpbnQgb24gdGhlIHdpcmUuCisgICAgVFlQRV9TVFJJTkcgICAgICAgICA9IDksICAgLy8gVVRGLTggdGV4dC4KKyAgICBUWVBFX0dST1VQICAgICAgICAgID0gMTAsICAvLyBUYWctZGVsaW1pdGVkIG1lc3NhZ2UuICBEZXByZWNhdGVkLgorICAgIFRZUEVfTUVTU0FHRSAgICAgICAgPSAxMSwgIC8vIExlbmd0aC1kZWxpbWl0ZWQgbWVzc2FnZS4KKworICAgIFRZUEVfQllURVMgICAgICAgICAgPSAxMiwgIC8vIEFyYml0cmFyeSBieXRlIGFycmF5LgorICAgIFRZUEVfVUlOVDMyICAgICAgICAgPSAxMywgIC8vIHVpbnQzMiwgdmFyaW50IG9uIHRoZSB3aXJlCisgICAgVFlQRV9FTlVNICAgICAgICAgICA9IDE0LCAgLy8gRW51bSwgdmFyaW50IG9uIHRoZSB3aXJlCisgICAgVFlQRV9TRklYRUQzMiAgICAgICA9IDE1LCAgLy8gaW50MzIsIGV4YWN0bHkgZm91ciBieXRlcyBvbiB0aGUgd2lyZQorICAgIFRZUEVfU0ZJWEVENjQgICAgICAgPSAxNiwgIC8vIGludDY0LCBleGFjdGx5IGVpZ2h0IGJ5dGVzIG9uIHRoZSB3aXJlCisgICAgVFlQRV9TSU5UMzIgICAgICAgICA9IDE3LCAgLy8gaW50MzIsIFppZ1phZy1lbmNvZGVkIHZhcmludCBvbiB0aGUgd2lyZQorICAgIFRZUEVfU0lOVDY0ICAgICAgICAgPSAxOCwgIC8vIGludDY0LCBaaWdaYWctZW5jb2RlZCB2YXJpbnQgb24gdGhlIHdpcmUKKworICAgIE1BWF9UWVBFICAgICAgICAgICAgPSAxOCwgIC8vIENvbnN0YW50IHVzZWZ1bCBmb3IgZGVmaW5pbmcgbG9va3VwIHRhYmxlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluZGV4ZWQgYnkgVHlwZS4KKyAgfTsKKworICAvLyBTcGVjaWZpZXMgdGhlIEMrKyBkYXRhIHR5cGUgdXNlZCB0byByZXByZXNlbnQgdGhlIGZpZWxkLiAgVGhlcmUgaXMgYQorICAvLyBmaXhlZCBtYXBwaW5nIGZyb20gVHlwZSB0byBDcHBUeXBlIHdoZXJlIGVhY2ggVHlwZSBtYXBzIHRvIGV4YWN0bHkgb25lCisgIC8vIENwcFR5cGUuICAwIGlzIHJlc2VydmVkIGZvciBlcnJvcnMuCisgIGVudW0gQ3BwVHlwZSB7CisgICAgQ1BQVFlQRV9JTlQzMiAgICAgICA9IDEsICAgICAvLyBUWVBFX0lOVDMyLCBUWVBFX1NJTlQzMiwgVFlQRV9TRklYRUQzMgorICAgIENQUFRZUEVfSU5UNjQgICAgICAgPSAyLCAgICAgLy8gVFlQRV9JTlQ2NCwgVFlQRV9TSU5UNjQsIFRZUEVfU0ZJWEVENjQKKyAgICBDUFBUWVBFX1VJTlQzMiAgICAgID0gMywgICAgIC8vIFRZUEVfVUlOVDMyLCBUWVBFX0ZJWEVEMzIKKyAgICBDUFBUWVBFX1VJTlQ2NCAgICAgID0gNCwgICAgIC8vIFRZUEVfVUlOVDY0LCBUWVBFX0ZJWEVENjQKKyAgICBDUFBUWVBFX0RPVUJMRSAgICAgID0gNSwgICAgIC8vIFRZUEVfRE9VQkxFCisgICAgQ1BQVFlQRV9GTE9BVCAgICAgICA9IDYsICAgICAvLyBUWVBFX0ZMT0FUCisgICAgQ1BQVFlQRV9CT09MICAgICAgICA9IDcsICAgICAvLyBUWVBFX0JPT0wKKyAgICBDUFBUWVBFX0VOVU0gICAgICAgID0gOCwgICAgIC8vIFRZUEVfRU5VTQorICAgIENQUFRZUEVfU1RSSU5HICAgICAgPSA5LCAgICAgLy8gVFlQRV9TVFJJTkcsIFRZUEVfQllURVMKKyAgICBDUFBUWVBFX01FU1NBR0UgICAgID0gMTAsICAgIC8vIFRZUEVfTUVTU0FHRSwgVFlQRV9HUk9VUAorCisgICAgTUFYX0NQUFRZUEUgICAgICAgICA9IDEwLCAgICAvLyBDb25zdGFudCB1c2VmdWwgZm9yIGRlZmluaW5nIGxvb2t1cCB0YWJsZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluZGV4ZWQgYnkgQ3BwVHlwZS4KKyAgfTsKKworICAvLyBJZGVudGlmaWVzIHdoZXRoZXIgdGhlIGZpZWxkIGlzIG9wdGlvbmFsLCByZXF1aXJlZCwgb3IgcmVwZWF0ZWQuICAwIGlzCisgIC8vIHJlc2VydmVkIGZvciBlcnJvcnMuCisgIGVudW0gTGFiZWwgeworICAgIExBQkVMX09QVElPTkFMICAgICAgPSAxLCAgICAvLyBvcHRpb25hbAorICAgIExBQkVMX1JFUVVJUkVEICAgICAgPSAyLCAgICAvLyByZXF1aXJlZAorICAgIExBQkVMX1JFUEVBVEVEICAgICAgPSAzLCAgICAvLyByZXBlYXRlZAorCisgICAgTUFYX0xBQkVMICAgICAgICAgICA9IDMsICAgIC8vIENvbnN0YW50IHVzZWZ1bCBmb3IgZGVmaW5pbmcgbG9va3VwIHRhYmxlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRleGVkIGJ5IExhYmVsLgorICB9OworCisgIC8vIFZhbGlkIGZpZWxkIG51bWJlcnMgYXJlIHBvc2l0aXZlIGludGVnZXJzIHVwIHRvIGtNYXhOdW1iZXIuCisgIHN0YXRpYyBjb25zdCBpbnQga01heE51bWJlciA9ICgxIDw8IDI5KSAtIDE7CisKKyAgLy8gRmlyc3QgZmllbGQgbnVtYmVyIHJlc2VydmVkIGZvciB0aGUgcHJvdG9jb2wgYnVmZmVyIGxpYnJhcnkgaW1wbGVtZW50YXRpb24uCisgIC8vIFVzZXJzIG1heSBub3QgZGVjbGFyZSBmaWVsZHMgdGhhdCB1c2UgcmVzZXJ2ZWQgbnVtYmVycy4KKyAgc3RhdGljIGNvbnN0IGludCBrRmlyc3RSZXNlcnZlZE51bWJlciA9IDE5MDAwOworICAvLyBMYXN0IGZpZWxkIG51bWJlciByZXNlcnZlZCBmb3IgdGhlIHByb3RvY29sIGJ1ZmZlciBsaWJyYXJ5IGltcGxlbWVudGF0aW9uLgorICAvLyBVc2VycyBtYXkgbm90IGRlY2xhcmUgZmllbGRzIHRoYXQgdXNlIHJlc2VydmVkIG51bWJlcnMuCisgIHN0YXRpYyBjb25zdCBpbnQga0xhc3RSZXNlcnZlZE51bWJlciAgPSAxOTk5OTsKKworICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsgICAgICAgIC8vIE5hbWUgb2YgdGhpcyBmaWVsZCB3aXRoaW4gdGhlIG1lc3NhZ2UuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7ICAgLy8gRnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGZpZWxkLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSgpIGNvbnN0Oy8vIEZpbGUgaW4gd2hpY2ggdGhpcyBmaWVsZCB3YXMgZGVmaW5lZC4KKyAgYm9vbCBpc19leHRlbnNpb24oKSBjb25zdDsgICAgICAgICAvLyBJcyB0aGlzIGFuIGV4dGVuc2lvbiBmaWVsZD8KKyAgaW50IG51bWJlcigpIGNvbnN0OyAgICAgICAgICAgICAgICAvLyBEZWNsYXJlZCB0YWcgbnVtYmVyLgorCisgIC8vIFNhbWUgYXMgbmFtZSgpIGV4Y2VwdCBjb252ZXJ0ZWQgdG8gbG93ZXItY2FzZS4gIFRoaXMgKGFuZCBlc3BlY2lhbGx5IHRoZQorICAvLyBGaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoKSBtZXRob2QpIGNhbiBiZSB1c2VmdWwgd2hlbiBwYXJzaW5nIGZvcm1hdHMKKyAgLy8gd2hpY2ggcHJlZmVyIHRvIHVzZSBsb3dlcmNhc2UgbmFtaW5nIHN0eWxlLiAgKEFsdGhvdWdoLCB0ZWNobmljYWxseQorICAvLyBmaWVsZCBuYW1lcyBzaG91bGQgYmUgbG93ZXJjYXNlZCBhbnl3YXkgYWNjb3JkaW5nIHRvIHRoZSBwcm90b2J1ZiBzdHlsZQorICAvLyBndWlkZSwgc28gdGhpcyBvbmx5IG1ha2VzIGEgZGlmZmVyZW5jZSB3aGVuIGRlYWxpbmcgd2l0aCBvbGQgLnByb3RvIGZpbGVzCisgIC8vIHdoaWNoIGRvIG5vdCBmb2xsb3cgdGhlIGd1aWRlLikKKyAgY29uc3Qgc3RyaW5nJiBsb3dlcmNhc2VfbmFtZSgpIGNvbnN0OworCisgIC8vIFNhbWUgYXMgbmFtZSgpIGV4Y2VwdCBjb252ZXJ0ZWQgdG8gY2FtZWwtY2FzZS4gIEluIHRoaXMgY29udmVyc2lvbiwgYW55CisgIC8vIHRpbWUgYW4gdW5kZXJzY29yZSBhcHBlYXJzIGluIHRoZSBuYW1lLCBpdCBpcyByZW1vdmVkIGFuZCB0aGUgbmV4dAorICAvLyBsZXR0ZXIgaXMgY2FwaXRhbGl6ZWQuICBGdXJ0aGVybW9yZSwgdGhlIGZpcnN0IGxldHRlciBvZiB0aGUgbmFtZSBpcworICAvLyBsb3dlci1jYXNlZC4gIEV4YW1wbGVzOgorICAvLyAgIEZvb0JhciAtPiBmb29CYXIKKyAgLy8gICBmb29fYmFyIC0+IGZvb0JhcgorICAvLyAgIGZvb0JhciAtPiBmb29CYXIKKyAgLy8gVGhpcyAoYW5kIGVzcGVjaWFsbHkgdGhlIEZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgpIG1ldGhvZCkgY2FuIGJlIHVzZWZ1bAorICAvLyB3aGVuIHBhcnNpbmcgZm9ybWF0cyB3aGljaCBwcmVmZXIgdG8gdXNlIGNhbWVsLWNhc2UgbmFtaW5nIHN0eWxlLgorICBjb25zdCBzdHJpbmcmIGNhbWVsY2FzZV9uYW1lKCkgY29uc3Q7CisKKyAgVHlwZSB0eXBlKCkgY29uc3Q7ICAgICAgICAgICAgICAgICAgLy8gRGVjbGFyZWQgdHlwZSBvZiB0aGlzIGZpZWxkLgorICBjb25zdCBjaGFyKiB0eXBlX25hbWUoKSBjb25zdDsgICAgICAvLyBOYW1lIG9mIHRoZSBkZWNsYXJlZCB0eXBlLgorICBDcHBUeXBlIGNwcF90eXBlKCkgY29uc3Q7ICAgICAgICAgICAvLyBDKysgdHlwZSBvZiB0aGlzIGZpZWxkLgorICBjb25zdCBjaGFyKiBjcHBfdHlwZV9uYW1lKCkgY29uc3Q7ICAvLyBOYW1lIG9mIHRoZSBDKysgdHlwZS4KKyAgTGFiZWwgbGFiZWwoKSBjb25zdDsgICAgICAgICAgICAgICAgLy8gb3B0aW9uYWwvcmVxdWlyZWQvcmVwZWF0ZWQKKworICBib29sIGlzX3JlcXVpcmVkKCkgY29uc3Q7ICAgICAgLy8gc2hvcnRoYW5kIGZvciBsYWJlbCgpID09IExBQkVMX1JFUVVJUkVECisgIGJvb2wgaXNfb3B0aW9uYWwoKSBjb25zdDsgICAgICAvLyBzaG9ydGhhbmQgZm9yIGxhYmVsKCkgPT0gTEFCRUxfT1BUSU9OQUwKKyAgYm9vbCBpc19yZXBlYXRlZCgpIGNvbnN0OyAgICAgIC8vIHNob3J0aGFuZCBmb3IgbGFiZWwoKSA9PSBMQUJFTF9SRVBFQVRFRAorICBib29sIGlzX3BhY2thYmxlKCkgY29uc3Q7ICAgICAgLy8gc2hvcnRoYW5kIGZvciBpc19yZXBlYXRlZCgpICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgIElzVHlwZVBhY2thYmxlKHR5cGUoKSkKKyAgYm9vbCBpc19wYWNrZWQoKSBjb25zdDsgICAgICAgIC8vIHNob3J0aGFuZCBmb3IgaXNfcGFja2FibGUoKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICBvcHRpb25zKCkucGFja2VkKCkKKyAgYm9vbCBpc19tYXAoKSBjb25zdDsgICAgICAgICAgIC8vIHNob3J0aGFuZCBmb3IgdHlwZSgpID09IFRZUEVfTUVTU0FHRSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZV90eXBlKCktPm9wdGlvbnMoKS5tYXBfZW50cnkoKQorCisgIC8vIEluZGV4IG9mIHRoaXMgZmllbGQgd2l0aGluIHRoZSBtZXNzYWdlJ3MgZmllbGQgYXJyYXksIG9yIHRoZSBmaWxlIG9yCisgIC8vIGV4dGVuc2lvbiBzY29wZSdzIGV4dGVuc2lvbnMgYXJyYXkuCisgIGludCBpbmRleCgpIGNvbnN0OworCisgIC8vIERvZXMgdGhpcyBmaWVsZCBoYXZlIGFuIGV4cGxpY2l0bHktZGVjbGFyZWQgZGVmYXVsdCB2YWx1ZT8KKyAgYm9vbCBoYXNfZGVmYXVsdF92YWx1ZSgpIGNvbnN0OworCisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfSU5UMzIuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLgorICBpbnQzMiBkZWZhdWx0X3ZhbHVlX2ludDMyKCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfSU5UNjQuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLgorICBpbnQ2NCBkZWZhdWx0X3ZhbHVlX2ludDY0KCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfVUlOVDMyLiAgSWYgbm8KKyAgLy8gZXhwbGljaXQgZGVmYXVsdCB3YXMgZGVmaW5lZCwgdGhlIGRlZmF1bHQgaXMgMC4KKyAgdWludDMyIGRlZmF1bHRfdmFsdWVfdWludDMyKCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfVUlOVDY0LiAgSWYgbm8KKyAgLy8gZXhwbGljaXQgZGVmYXVsdCB3YXMgZGVmaW5lZCwgdGhlIGRlZmF1bHQgaXMgMC4KKyAgdWludDY0IGRlZmF1bHRfdmFsdWVfdWludDY0KCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfRkxPQVQuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLjAuCisgIGZsb2F0IGRlZmF1bHRfdmFsdWVfZmxvYXQoKSBjb25zdDsKKyAgLy8gR2V0IHRoZSBmaWVsZCBkZWZhdWx0IHZhbHVlIGlmIGNwcF90eXBlKCkgPT0gQ1BQVFlQRV9ET1VCTEUuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLjAuCisgIGRvdWJsZSBkZWZhdWx0X3ZhbHVlX2RvdWJsZSgpIGNvbnN0OworICAvLyBHZXQgdGhlIGZpZWxkIGRlZmF1bHQgdmFsdWUgaWYgY3BwX3R5cGUoKSA9PSBDUFBUWVBFX0JPT0wuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyBmYWxzZS4KKyAgYm9vbCBkZWZhdWx0X3ZhbHVlX2Jvb2woKSBjb25zdDsKKyAgLy8gR2V0IHRoZSBmaWVsZCBkZWZhdWx0IHZhbHVlIGlmIGNwcF90eXBlKCkgPT0gQ1BQVFlQRV9FTlVNLiAgSWYgbm8KKyAgLy8gZXhwbGljaXQgZGVmYXVsdCB3YXMgZGVmaW5lZCwgdGhlIGRlZmF1bHQgaXMgdGhlIGZpcnN0IHZhbHVlIGRlZmluZWQKKyAgLy8gaW4gdGhlIGVudW0gdHlwZSAoYWxsIGVudW0gdHlwZXMgYXJlIHJlcXVpcmVkIHRvIGhhdmUgYXQgbGVhc3Qgb25lIHZhbHVlKS4KKyAgLy8gVGhpcyBuZXZlciByZXR1cm5zIE5VTEwuCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlZmF1bHRfdmFsdWVfZW51bSgpIGNvbnN0OworICAvLyBHZXQgdGhlIGZpZWxkIGRlZmF1bHQgdmFsdWUgaWYgY3BwX3R5cGUoKSA9PSBDUFBUWVBFX1NUUklORy4gIElmIG5vCisgIC8vIGV4cGxpY2l0IGRlZmF1bHQgd2FzIGRlZmluZWQsIHRoZSBkZWZhdWx0IGlzIHRoZSBlbXB0eSBzdHJpbmcuCisgIGNvbnN0IHN0cmluZyYgZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSBjb25zdDsKKworICAvLyBUaGUgRGVzY3JpcHRvciBmb3IgdGhlIG1lc3NhZ2Ugb2Ygd2hpY2ggdGhpcyBpcyBhIGZpZWxkLiAgRm9yIGV4dGVuc2lvbnMsCisgIC8vIHRoaXMgaXMgdGhlIGV4dGVuZGVkIHR5cGUuICBOZXZlciBOVUxMLgorICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUoKSBjb25zdDsKKworICAvLyBJZiB0aGUgZmllbGQgaXMgYSBtZW1iZXIgb2YgYSBvbmVvZiwgdGhpcyBpcyB0aGUgb25lLCBvdGhlcndpc2UgdGhpcyBpcworICAvLyBOVUxMLgorICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGNvbnRhaW5pbmdfb25lb2YoKSBjb25zdDsKKworICAvLyBJZiB0aGUgZmllbGQgaXMgYSBtZW1iZXIgb2YgYSBvbmVvZiwgcmV0dXJucyB0aGUgaW5kZXggaW4gdGhhdCBvbmVvZi4KKyAgaW50IGluZGV4X2luX29uZW9mKCkgY29uc3Q7CisKKyAgLy8gQW4gZXh0ZW5zaW9uIG1heSBiZSBkZWNsYXJlZCB3aXRoaW4gdGhlIHNjb3BlIG9mIGFub3RoZXIgbWVzc2FnZS4gIElmIHRoaXMKKyAgLy8gZmllbGQgaXMgYW4gZXh0ZW5zaW9uIChpc19leHRlbnNpb24oKSBpcyB0cnVlKSwgdGhlbiBleHRlbnNpb25fc2NvcGUoKQorICAvLyByZXR1cm5zIHRoYXQgbWVzc2FnZSwgb3IgTlVMTCBpZiB0aGUgZXh0ZW5zaW9uIHdhcyBkZWNsYXJlZCBhdCBnbG9iYWwKKyAgLy8gc2NvcGUuICBJZiB0aGlzIGlzIG5vdCBhbiBleHRlbnNpb24sIGV4dGVuc2lvbl9zY29wZSgpIGlzIHVuZGVmaW5lZCAobWF5CisgIC8vIGFzc2VydC1mYWlsKS4KKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5zaW9uX3Njb3BlKCkgY29uc3Q7CisKKyAgLy8gSWYgdHlwZSBpcyBUWVBFX01FU1NBR0Ugb3IgVFlQRV9HUk9VUCwgcmV0dXJucyBhIGRlc2NyaXB0b3IgZm9yIHRoZQorICAvLyBtZXNzYWdlIG9yIHRoZSBncm91cCB0eXBlLiAgT3RoZXJ3aXNlLCByZXR1cm5zIG51bGwuCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSgpIGNvbnN0OworICAvLyBJZiB0eXBlIGlzIFRZUEVfRU5VTSwgcmV0dXJucyBhIGRlc2NyaXB0b3IgZm9yIHRoZSBlbnVtLiAgT3RoZXJ3aXNlLAorICAvLyByZXR1cm5zIG51bGwuCisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUoKSBjb25zdDsKKworICAvLyBHZXQgdGhlIEZpZWxkT3B0aW9ucyBmb3IgdGhpcyBmaWVsZC4gIFRoaXMgaW5jbHVkZXMgdGhpbmdzIGxpc3RlZCBpbgorICAvLyBzcXVhcmUgYnJhY2tldHMgYWZ0ZXIgdGhlIGZpZWxkIGRlZmluaXRpb24uICBFLmcuLCB0aGUgZmllbGQ6CisgIC8vICAgb3B0aW9uYWwgc3RyaW5nIHRleHQgPSAxIFtjdHlwZT1DT1JEXTsKKyAgLy8gaGFzIHRoZSAiY3R5cGUiIG9wdGlvbiBzZXQuICBBbGxvd2VkIG9wdGlvbnMgYXJlIGRlZmluZWQgYnkgRmllbGRPcHRpb25zCisgIC8vIGluIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLCBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQKKyAgLy8gbWVzc2FnZS4KKyAgY29uc3QgRmllbGRPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkNvcHlUbygpLgorICB2b2lkIENvcHlUbyhGaWVsZERlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICBzdHJpbmcgRGVidWdTdHJpbmcoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygpLgorICBzdHJpbmcgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSBDcHBUeXBlIGZvciBhIHBhcnRpY3VsYXIgVHlwZS4KKyAgc3RhdGljIENwcFR5cGUgVHlwZVRvQ3BwVHlwZShUeXBlIHR5cGUpOworCisgIC8vIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSBuYW1lIG9mIGEgVHlwZS4KKyAgc3RhdGljIGNvbnN0IGNoYXIqIFR5cGVOYW1lKFR5cGUgdHlwZSk7CisKKyAgLy8gSGVscGVyIG1ldGhvZCB0byBnZXQgdGhlIG5hbWUgb2YgYSBDcHBUeXBlLgorICBzdGF0aWMgY29uc3QgY2hhciogQ3BwVHlwZU5hbWUoQ3BwVHlwZSBjcHBfdHlwZSk7CisKKyAgLy8gUmV0dXJuIHRydWUgaWZmIFtwYWNrZWQgPSB0cnVlXSBpcyB2YWxpZCBmb3IgZmllbGRzIG9mIHRoaXMgdHlwZS4KKyAgc3RhdGljIGlubGluZSBib29sIElzVHlwZVBhY2thYmxlKFR5cGUgZmllbGRfdHlwZSk7CisKKyAgLy8gU291cmNlIExvY2F0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlCisgIC8vIGV4dGVudCBvZiB0aGlzIGZpZWxkIGRlY2xhcmF0aW9uLiAgUmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzCisgIC8vIHwqb3V0X2xvY2F0aW9ufCB1bmNoYW5nZWQgaWZmIGxvY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBub3QgYXZhaWxhYmxlLgorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiBGaWVsZE9wdGlvbnMgT3B0aW9uc1R5cGU7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkuCisgIGVudW0gUHJpbnRMYWJlbEZsYWcgeyBQUklOVF9MQUJFTCwgT01JVF9MQUJFTCB9OworICB2b2lkIERlYnVnU3RyaW5nKGludCBkZXB0aCwgUHJpbnRMYWJlbEZsYWcgcHJpbnRfbGFiZWxfZmxhZywKKyAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGNvbnRlbnRzLCBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIGZvcm1hdHMgdGhlIGRlZmF1bHQgdmFsdWUgYXBwcm9wcmlhdGVseSBhbmQgcmV0dXJucyBpdCBhcyBhIHN0cmluZy4KKyAgLy8gTXVzdCBoYXZlIGEgZGVmYXVsdCB2YWx1ZSB0byBjYWxsIHRoaXMuIElmIHF1b3RlX3N0cmluZ190eXBlIGlzIHRydWUsIHRoZW4KKyAgLy8gdHlwZXMgb2YgQ1BQVFlQRV9TVFJJTkcgd2hpbGwgYmUgc3Vycm91bmRlZCBieSBxdW90ZXMgYW5kIENFc2NhcGVkLgorICBzdHJpbmcgRGVmYXVsdFZhbHVlQXNTdHJpbmcoYm9vbCBxdW90ZV9zdHJpbmdfdHlwZSkgY29uc3Q7CisKKyAgLy8gSGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgZmllbGQgdHlwZSBuYW1lIGZvciBEZWJ1Z1N0cmluZy4KKyAgc3RyaW5nIEZpZWxkVHlwZU5hbWVEZWJ1Z1N0cmluZygpIGNvbnN0OworCisgIC8vIFdhbGtzIHVwIHRoZSBkZXNjcmlwdG9yIHRyZWUgdG8gZ2VuZXJhdGUgdGhlIHNvdXJjZSBsb2NhdGlvbiBwYXRoCisgIC8vIHRvIHRoaXMgZGVzY3JpcHRvciBmcm9tIHRoZSBmaWxlIHJvb3QuCisgIHZvaWQgR2V0TG9jYXRpb25QYXRoKHN0ZDo6dmVjdG9yPGludD4qIG91dHB1dCkgY29uc3Q7CisKKyAgY29uc3Qgc3RyaW5nKiBuYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBmdWxsX25hbWVfOworICBjb25zdCBzdHJpbmcqIGxvd2VyY2FzZV9uYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBjYW1lbGNhc2VfbmFtZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgaW50IG51bWJlcl87CisgIFR5cGUgdHlwZV87CisgIExhYmVsIGxhYmVsXzsKKyAgYm9vbCBpc19leHRlbnNpb25fOworICBpbnQgaW5kZXhfaW5fb25lb2ZfOworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGVfOworICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGNvbnRhaW5pbmdfb25lb2ZfOworICBjb25zdCBEZXNjcmlwdG9yKiBleHRlbnNpb25fc2NvcGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGVfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlXzsKKyAgY29uc3QgRmllbGRPcHRpb25zKiBvcHRpb25zXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxGaWVsZERlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8RmllbGREZXNjcmlwdG9yPigpIGluCisgIC8vIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIGJvb2wgaGFzX2RlZmF1bHRfdmFsdWVfOworICB1bmlvbiB7CisgICAgaW50MzIgIGRlZmF1bHRfdmFsdWVfaW50MzJfOworICAgIGludDY0ICBkZWZhdWx0X3ZhbHVlX2ludDY0XzsKKyAgICB1aW50MzIgZGVmYXVsdF92YWx1ZV91aW50MzJfOworICAgIHVpbnQ2NCBkZWZhdWx0X3ZhbHVlX3VpbnQ2NF87CisgICAgZmxvYXQgIGRlZmF1bHRfdmFsdWVfZmxvYXRfOworICAgIGRvdWJsZSBkZWZhdWx0X3ZhbHVlX2RvdWJsZV87CisgICAgYm9vbCAgIGRlZmF1bHRfdmFsdWVfYm9vbF87CisKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZWZhdWx0X3ZhbHVlX2VudW1fOworICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF92YWx1ZV9zdHJpbmdfOworICB9OworCisgIHN0YXRpYyBjb25zdCBDcHBUeXBlIGtUeXBlVG9DcHBUeXBlTWFwW01BWF9UWVBFICsgMV07CisKKyAgc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBrVHlwZVRvTmFtZVtNQVhfVFlQRSArIDFdOworCisgIHN0YXRpYyBjb25zdCBjaGFyICogY29uc3Qga0NwcFR5cGVUb05hbWVbTUFYX0NQUFRZUEUgKyAxXTsKKworICBzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGtMYWJlbFRvTmFtZVtNQVhfTEFCRUwgKyAxXTsKKworICAvLyBNdXN0IGJlIGNvbnN0cnVjdGVkIHVzaW5nIERlc2NyaXB0b3JQb29sLgorICBGaWVsZERlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBGaWxlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIERlc2NyaXB0b3I7CisgIGZyaWVuZCBjbGFzcyBPbmVvZkRlc2NyaXB0b3I7CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWVsZERlc2NyaXB0b3IpOworfTsKKworLy8gRGVzY3JpYmVzIGEgb25lb2YgZGVmaW5lZCBpbiBhIG1lc3NhZ2UgdHlwZS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBPbmVvZkRlc2NyaXB0b3IgeworIHB1YmxpYzoKKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3Q7ICAgICAgIC8vIE5hbWUgb2YgdGhpcyBvbmVvZi4KKyAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUoKSBjb25zdDsgIC8vIEZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoZSBvbmVvZi4KKworICAvLyBJbmRleCBvZiB0aGlzIG9uZW9mIHdpdGhpbiB0aGUgbWVzc2FnZSdzIG9uZW9mIGFycmF5LgorICBpbnQgaW5kZXgoKSBjb25zdDsKKworICAvLyBUaGUgRGVzY3JpcHRvciBmb3IgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGlzIG9uZW9mLgorICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUoKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIChub24tZXh0ZW5zaW9uKSBmaWVsZHMgd2hpY2ggYXJlIG1lbWJlcnMgb2YgdGhpcyBvbmVvZi4KKyAgaW50IGZpZWxkX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldCBhIG1lbWJlciBvZiB0aGlzIG9uZW9mLCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlIGRlY2xhcmVkIGluIHRoZQorICAvLyAucHJvdG8gZmlsZS4gIERvZXMgbm90IGluY2x1ZGUgZXh0ZW5zaW9ucy4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZChpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpDb3B5VG8oKS4KKyAgdm9pZCBDb3B5VG8oT25lb2ZEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBTb3VyY2UgTG9jYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVXBkYXRlcyB8Km91dF9sb2NhdGlvbnwgdG8gdGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgY29tcGxldGUKKyAgLy8gZXh0ZW50IG9mIHRoaXMgb25lb2YgZGVjbGFyYXRpb24uICBSZXR1cm5zIGZhbHNlIGFuZCBsZWF2ZXMKKyAgLy8gfCpvdXRfbG9jYXRpb258IHVuY2hhbmdlZCBpZmYgbG9jYXRpb24gaW5mb3JtYXRpb24gd2FzIG5vdCBhdmFpbGFibGUuCisgIGJvb2wgR2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3Q7CisKKyBwcml2YXRlOgorICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyogY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlXzsKKyAgYm9vbCBpc19leHRlbmRhYmxlXzsKKyAgaW50IGZpZWxkX2NvdW50XzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiogZmllbGRzXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxPbmVvZkRlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8T25lb2ZEZXNjcmlwdG9yPigpCisgIC8vIGluIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIC8vIE11c3QgYmUgY29uc3RydWN0ZWQgdXNpbmcgRGVzY3JpcHRvclBvb2wuCisgIE9uZW9mRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIERlc2NyaXB0b3I7CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhPbmVvZkRlc2NyaXB0b3IpOworfTsKKworLy8gRGVzY3JpYmVzIGFuIGVudW0gdHlwZSBkZWZpbmVkIGluIGEgLnByb3RvIGZpbGUuICBUbyBnZXQgdGhlIEVudW1EZXNjcmlwdG9yCisvLyBmb3IgYSBnZW5lcmF0ZWQgZW51bSB0eXBlLCBjYWxsIFR5cGVOYW1lX2Rlc2NyaXB0b3IoKS4gIFVzZSBEZXNjcmlwdG9yUG9vbAorLy8gdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1EZXNjcmlwdG9yIHsKKyBwdWJsaWM6CisgIC8vIFRoZSBuYW1lIG9mIHRoaXMgZW51bSB0eXBlIGluIHRoZSBjb250YWluaW5nIHNjb3BlLgorICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsKKworICAvLyBUaGUgZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVudW0gdHlwZSwgc2NvcGUgZGVsaW1pdGVkIGJ5IHBlcmlvZHMuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7CisKKyAgLy8gSW5kZXggb2YgdGhpcyBlbnVtIHdpdGhpbiB0aGUgZmlsZSBvciBjb250YWluaW5nIG1lc3NhZ2UncyBlbnVtIGFycmF5LgorICBpbnQgaW5kZXgoKSBjb25zdDsKKworICAvLyBUaGUgLnByb3RvIGZpbGUgaW4gd2hpY2ggdGhpcyBlbnVtIHR5cGUgd2FzIGRlZmluZWQuICBOZXZlciBOVUxMLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSgpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2YgdmFsdWVzIGZvciB0aGlzIEVudW1EZXNjcmlwdG9yLiAgR3VhcmFudGVlZCB0byBiZSBncmVhdGVyCisgIC8vIHRoYW4gemVyby4KKyAgaW50IHZhbHVlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSB2YWx1ZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IHZhbHVlX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgdmFsdWUgYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBubyBzdWNoIHZhbHVlIGV4aXN0cy4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZFZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIC8vIExvb2tzIHVwIGEgdmFsdWUgYnkgbnVtYmVyLiAgUmV0dXJucyBOVUxMIGlmIG5vIHN1Y2ggdmFsdWUgZXhpc3RzLiAgSWYKKyAgLy8gbXVsdGlwbGUgdmFsdWVzIGhhdmUgdGhpcyBudW1iZXIsIHRoZSBmaXJzdCBvbmUgZGVmaW5lZCBpcyByZXR1cm5lZC4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgY29uc3Q7CisKKyAgLy8gSWYgdGhpcyBlbnVtIHR5cGUgaXMgbmVzdGVkIGluIGEgbWVzc2FnZSB0eXBlLCB0aGlzIGlzIHRoYXQgbWVzc2FnZSB0eXBlLgorICAvLyBPdGhlcndpc2UsIE5VTEwuCisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSgpIGNvbnN0OworCisgIC8vIEdldCBvcHRpb25zIGZvciB0aGlzIGVudW0gdHlwZS4gIFRoZXNlIGFyZSBzcGVjaWZpZWQgaW4gdGhlIC5wcm90byBmaWxlIGJ5CisgIC8vIHBsYWNpbmcgbGluZXMgbGlrZSAib3B0aW9uIGZvbyA9IDEyMzQ7IiBpbiB0aGUgZW51bSBkZWZpbml0aW9uLiAgQWxsb3dlZAorICAvLyBvcHRpb25zIGFyZSBkZWZpbmVkIGJ5IEVudW1PcHRpb25zIGluIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLAorICAvLyBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQgbWVzc2FnZS4KKyAgY29uc3QgRW51bU9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6Q29weVRvKCkuCisgIHZvaWQgQ29weVRvKEVudW1EZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGFuIHVua25vd24gZW51bS4gVGhpcyB3aWxsCisgIC8vIG9ubHkgYmUgdGhlIGNhc2UgaWYgdGhpcyBkZXNjcmlwdG9yIGNvbWVzIGZyb20gYSBEZXNjcmlwdG9yUG9vbAorICAvLyB3aXRoIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIHNldC4KKyAgYm9vbCBpc19wbGFjZWhvbGRlcigpIGNvbnN0OworCisgIC8vIFNvdXJjZSBMb2NhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBVcGRhdGVzIHwqb3V0X2xvY2F0aW9ufCB0byB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjb21wbGV0ZQorICAvLyBleHRlbnQgb2YgdGhpcyBlbnVtIGRlY2xhcmF0aW9uLiAgUmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzCisgIC8vIHwqb3V0X2xvY2F0aW9ufCB1bmNoYW5nZWQgaWZmIGxvY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBub3QgYXZhaWxhYmxlLgorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiBFbnVtT3B0aW9ucyBPcHRpb25zVHlwZTsKKworICAvLyBMb29rcyB1cCBhIHZhbHVlIGJ5IG51bWJlci4gIElmIHRoZSB2YWx1ZSBkb2VzIG5vdCBleGlzdCwgZHluYW1pY2FsbHkKKyAgLy8gY3JlYXRlcyBhIG5ldyBFbnVtVmFsdWVEZXNjcmlwdG9yIGZvciB0aGF0IHZhbHVlLCBhc3N1bWluZyB0aGF0IGl0IHdhcworICAvLyB1bmtub3duLiBJZiBhIG5ldyBkZXNjcmlwdG9yIGlzIGNyZWF0ZWQsIHRoaXMgaXMgZG9uZSBpbiBhIHRocmVhZC1zYWZlIHdheSwKKyAgLy8gYW5kIGZ1dHVyZSBjYWxscyB3aWxsIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBkZXNjcmlwdG9yIHBvaW50ZXIuCisgIC8vCisgIC8vIFRoaXMgaXMgcHJpdmF0ZSBidXQgaXMgdXNlZCBieSBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiAod2hpY2ggaXMKKyAgLy8gZnJpZW5kZWQgYmVsb3cpIHRvIHJldHVybiBhIHZhbGlkIEVudW1WYWx1ZURlc2NyaXB0b3IgZnJvbSBHZXRFbnVtKCkgd2hlbgorICAvLyB0aGlzIGZlYXR1cmUgaXMgZW5hYmxlZC4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcioKKyAgICAgIEZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oaW50IG51bWJlcikgY29uc3Q7CisKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGVfOworICBjb25zdCBFbnVtT3B0aW9ucyogb3B0aW9uc187CisKKyAgLy8gVHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGFuIHVua25vd24gdHlwZS4KKyAgYm9vbCBpc19wbGFjZWhvbGRlcl87CisgIC8vIFRydWUgaWYgdGhpcyBpcyBhIHBsYWNlaG9sZGVyIGFuZCB0aGUgdHlwZSBuYW1lIHdhc24ndCBmdWxseS1xdWFsaWZpZWQuCisgIGJvb2wgaXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfOworCisgIGludCB2YWx1ZV9jb3VudF87CisgIEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlc187CisgIC8vIElNUE9SVEFOVDogIElmIHlvdSBhZGQgYSBuZXcgZmllbGQsIG1ha2Ugc3VyZSB0byBzZWFyY2ggZm9yIGFsbCBpbnN0YW5jZXMKKyAgLy8gb2YgQWxsb2NhdGU8RW51bURlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8RW51bURlc2NyaXB0b3I+KCkgaW4KKyAgLy8gZGVzY3JpcHRvci5jYyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgRW51bURlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIGludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVudW1EZXNjcmlwdG9yKTsKK307CisKKy8vIERlc2NyaWJlcyBhbiBpbmRpdmlkdWFsIGVudW0gY29uc3RhbnQgb2YgYSBwYXJ0aWN1bGFyIHR5cGUuICBUbyBnZXQgdGhlCisvLyBFbnVtVmFsdWVEZXNjcmlwdG9yIGZvciBhIGdpdmVuIGVudW0gdmFsdWUsIGZpcnN0IGdldCB0aGUgRW51bURlc2NyaXB0b3IKKy8vIGZvciBpdHMgdHlwZSwgdGhlbiB1c2UgRW51bURlc2NyaXB0b3I6OkZpbmRWYWx1ZUJ5TmFtZSgpIG9yCisvLyBFbnVtRGVzY3JpcHRvcjo6RmluZFZhbHVlQnlOdW1iZXIoKS4gIFVzZSBEZXNjcmlwdG9yUG9vbCB0byBjb25zdHJ1Y3QKKy8vIHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1WYWx1ZURlc2NyaXB0b3IgeworIHB1YmxpYzoKKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3Q7ICAvLyBOYW1lIG9mIHRoaXMgZW51bSBjb25zdGFudC4KKyAgaW50IGluZGV4KCkgY29uc3Q7ICAgICAgICAgICAvLyBJbmRleCB3aXRoaW4gdGhlIGVudW1zJ3MgRGVzY3JpcHRvci4KKyAgaW50IG51bWJlcigpIGNvbnN0OyAgICAgICAgICAvLyBOdW1lcmljIHZhbHVlIG9mIHRoaXMgZW51bSBjb25zdGFudC4KKworICAvLyBUaGUgZnVsbF9uYW1lIG9mIGFuIGVudW0gdmFsdWUgaXMgYSBzaWJsaW5nIHN5bWJvbCBvZiB0aGUgZW51bSB0eXBlLgorICAvLyBlLmcuIHRoZSBmdWxsIG5hbWUgb2YgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIgaXMgYWN0dWFsbHkKKyAgLy8gImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5UWVBFX0lOVDMyIiwgTk9UCisgIC8vICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZS5UWVBFX0lOVDMyIi4gIFRoaXMgaXMgdG8gY29uZm9ybQorICAvLyB3aXRoIEMrKyBzY29waW5nIHJ1bGVzIGZvciBlbnVtcy4KKyAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUoKSBjb25zdDsKKworICAvLyBUaGUgdHlwZSBvZiB0aGlzIHZhbHVlLiAgTmV2ZXIgTlVMTC4KKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIHR5cGUoKSBjb25zdDsKKworICAvLyBHZXQgb3B0aW9ucyBmb3IgdGhpcyBlbnVtIHZhbHVlLiAgVGhlc2UgYXJlIHNwZWNpZmllZCBpbiB0aGUgLnByb3RvIGZpbGUKKyAgLy8gYnkgYWRkaW5nIHRleHQgbGlrZSAiW2ZvbyA9IDEyMzRdIiBhZnRlciBhbiBlbnVtIHZhbHVlIGRlZmluaXRpb24uCisgIC8vIEFsbG93ZWQgb3B0aW9ucyBhcmUgZGVmaW5lZCBieSBFbnVtVmFsdWVPcHRpb25zIGluCisgIC8vIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLCBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQKKyAgLy8gbWVzc2FnZS4KKyAgY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpDb3B5VG8oKS4KKyAgdm9pZCBDb3B5VG8oRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkuCisgIHN0cmluZyBEZWJ1Z1N0cmluZygpIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKCkuCisgIHN0cmluZyBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3Q7CisKKworICAvLyBTb3VyY2UgTG9jYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVXBkYXRlcyB8Km91dF9sb2NhdGlvbnwgdG8gdGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgY29tcGxldGUKKyAgLy8gZXh0ZW50IG9mIHRoaXMgZW51bSB2YWx1ZSBkZWNsYXJhdGlvbi4gIFJldHVybnMgZmFsc2UgYW5kIGxlYXZlcworICAvLyB8Km91dF9sb2NhdGlvbnwgdW5jaGFuZ2VkIGlmZiBsb2NhdGlvbiBpbmZvcm1hdGlvbiB3YXMgbm90IGF2YWlsYWJsZS4KKyAgYm9vbCBHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdDsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgRW51bVZhbHVlT3B0aW9ucyBPcHRpb25zVHlwZTsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgaW50IG51bWJlcl87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiB0eXBlXzsKKyAgY29uc3QgRW51bVZhbHVlT3B0aW9ucyogb3B0aW9uc187CisgIC8vIElNUE9SVEFOVDogIElmIHlvdSBhZGQgYSBuZXcgZmllbGQsIG1ha2Ugc3VyZSB0byBzZWFyY2ggZm9yIGFsbCBpbnN0YW5jZXMKKyAgLy8gb2YgQWxsb2NhdGU8RW51bVZhbHVlRGVzY3JpcHRvcj4oKSBhbmQgQWxsb2NhdGVBcnJheTxFbnVtVmFsdWVEZXNjcmlwdG9yPigpCisgIC8vIGluIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIC8vIE11c3QgYmUgY29uc3RydWN0ZWQgdXNpbmcgRGVzY3JpcHRvclBvb2wuCisgIEVudW1WYWx1ZURlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBFbnVtRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yVGFibGVzOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bVZhbHVlRGVzY3JpcHRvcik7Cit9OworCisvLyBEZXNjcmliZXMgYW4gUlBDIHNlcnZpY2UuICBUbyBnZXQgdGhlIFNlcnZpY2VEZXNjcmlwdG9yIGZvciBhIHNlcnZpY2UsCisvLyBjYWxsIFNlcnZpY2U6OkdldERlc2NyaXB0b3IoKS4gIEdlbmVyYXRlZCBzZXJ2aWNlIGNsYXNzZXMgYWxzbyBoYXZlIGEKKy8vIHN0YXRpYyBtZXRob2QgY2FsbGVkIGRlc2NyaXB0b3IoKSB3aGljaCByZXR1cm5zIHRoZSB0eXBlJ3MKKy8vIFNlcnZpY2VEZXNjcmlwdG9yLiAgVXNlIERlc2NyaXB0b3JQb29sIHRvIGNvbnN0cnVjdCB5b3VyIG93biBkZXNjcmlwdG9ycy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTZXJ2aWNlRGVzY3JpcHRvciB7CisgcHVibGljOgorICAvLyBUaGUgbmFtZSBvZiB0aGUgc2VydmljZSwgbm90IGluY2x1ZGluZyBpdHMgY29udGFpbmluZyBzY29wZS4KKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIC8vIFRoZSBmdWxseS1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgc2VydmljZSwgc2NvcGUgZGVsaW1pdGVkIGJ5IHBlcmlvZHMuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7CisgIC8vIEluZGV4IG9mIHRoaXMgc2VydmljZSB3aXRoaW4gdGhlIGZpbGUncyBzZXJ2aWNlcyBhcnJheS4KKyAgaW50IGluZGV4KCkgY29uc3Q7CisKKyAgLy8gVGhlIC5wcm90byBmaWxlIGluIHdoaWNoIHRoaXMgc2VydmljZSB3YXMgZGVmaW5lZC4gIE5ldmVyIE5VTEwuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKCkgY29uc3Q7CisKKyAgLy8gR2V0IG9wdGlvbnMgZm9yIHRoaXMgc2VydmljZSB0eXBlLiAgVGhlc2UgYXJlIHNwZWNpZmllZCBpbiB0aGUgLnByb3RvIGZpbGUKKyAgLy8gYnkgcGxhY2luZyBsaW5lcyBsaWtlICJvcHRpb24gZm9vID0gMTIzNDsiIGluIHRoZSBzZXJ2aWNlIGRlZmluaXRpb24uCisgIC8vIEFsbG93ZWQgb3B0aW9ucyBhcmUgZGVmaW5lZCBieSBTZXJ2aWNlT3B0aW9ucyBpbgorICAvLyBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bywgYW5kIGFueSBhdmFpbGFibGUgZXh0ZW5zaW9ucyBvZiB0aGF0CisgIC8vIG1lc3NhZ2UuCisgIGNvbnN0IFNlcnZpY2VPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gVGhlIG51bWJlciBvZiBtZXRob2RzIHRoaXMgc2VydmljZSBkZWZpbmVzLgorICBpbnQgbWV0aG9kX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSBNZXRob2REZXNjcmlwdG9yIGJ5IGluZGV4LCB3aGVyZSAwIDw9IGluZGV4IDwgbWV0aG9kX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QoaW50IGluZGV4KSBjb25zdDsKKworICAvLyBMb29rIHVwIGEgTWV0aG9kRGVzY3JpcHRvciBieSBuYW1lLgorICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBGaW5kTWV0aG9kQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIC8vIFNlZSBEZXNjcmlwdG9yOjpDb3B5VG8oKS4KKyAgdm9pZCBDb3B5VG8oU2VydmljZURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICBzdHJpbmcgRGVidWdTdHJpbmcoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygpLgorICBzdHJpbmcgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisKKyAgLy8gU291cmNlIExvY2F0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlCisgIC8vIGV4dGVudCBvZiB0aGlzIHNlcnZpY2UgZGVjbGFyYXRpb24uICBSZXR1cm5zIGZhbHNlIGFuZCBsZWF2ZXMKKyAgLy8gfCpvdXRfbG9jYXRpb258IHVuY2hhbmdlZCBpZmYgbG9jYXRpb24gaW5mb3JtYXRpb24gd2FzIG5vdCBhdmFpbGFibGUuCisgIGJvb2wgR2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3Q7CisKKyBwcml2YXRlOgorICB0eXBlZGVmIFNlcnZpY2VPcHRpb25zIE9wdGlvbnNUeXBlOworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICB2b2lkIERlYnVnU3RyaW5nKHN0cmluZyAqY29udGVudHMsIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3Q7CisKKyAgLy8gV2Fsa3MgdXAgdGhlIGRlc2NyaXB0b3IgdHJlZSB0byBnZW5lcmF0ZSB0aGUgc291cmNlIGxvY2F0aW9uIHBhdGgKKyAgLy8gdG8gdGhpcyBkZXNjcmlwdG9yIGZyb20gdGhlIGZpbGUgcm9vdC4KKyAgdm9pZCBHZXRMb2NhdGlvblBhdGgoc3RkOjp2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdDsKKworICBjb25zdCBzdHJpbmcqIG5hbWVfOworICBjb25zdCBzdHJpbmcqIGZ1bGxfbmFtZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgY29uc3QgU2VydmljZU9wdGlvbnMqIG9wdGlvbnNfOworICBpbnQgbWV0aG9kX2NvdW50XzsKKyAgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kc187CisgIC8vIElNUE9SVEFOVDogIElmIHlvdSBhZGQgYSBuZXcgZmllbGQsIG1ha2Ugc3VyZSB0byBzZWFyY2ggZm9yIGFsbCBpbnN0YW5jZXMKKyAgLy8gb2YgQWxsb2NhdGU8U2VydmljZURlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8U2VydmljZURlc2NyaXB0b3I+KCkgaW4KKyAgLy8gZGVzY3JpcHRvci5jYyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgU2VydmljZURlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBGaWxlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIE1ldGhvZERlc2NyaXB0b3I7CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTZXJ2aWNlRGVzY3JpcHRvcik7Cit9OworCisvLyBEZXNjcmliZXMgYW4gaW5kaXZpZHVhbCBzZXJ2aWNlIG1ldGhvZC4gIFRvIG9idGFpbiBhIE1ldGhvZERlc2NyaXB0b3IgZ2l2ZW4KKy8vIGEgc2VydmljZSwgZmlyc3QgZ2V0IGl0cyBTZXJ2aWNlRGVzY3JpcHRvciwgdGhlbiBjYWxsCisvLyBTZXJ2aWNlRGVzY3JpcHRvcjo6RmluZE1ldGhvZEJ5TmFtZSgpLiAgVXNlIERlc2NyaXB0b3JQb29sIHRvIGNvbnN0cnVjdCB5b3VyCisvLyBvd24gZGVzY3JpcHRvcnMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWV0aG9kRGVzY3JpcHRvciB7CisgcHVibGljOgorICAvLyBOYW1lIG9mIHRoaXMgbWV0aG9kLCBub3QgaW5jbHVkaW5nIGNvbnRhaW5pbmcgc2NvcGUuCisgIGNvbnN0IHN0cmluZyYgbmFtZSgpIGNvbnN0OworICAvLyBUaGUgZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIG1ldGhvZCwgc2NvcGUgZGVsaW1pdGVkIGJ5IHBlcmlvZHMuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7CisgIC8vIEluZGV4IHdpdGhpbiB0aGUgc2VydmljZSdzIERlc2NyaXB0b3IuCisgIGludCBpbmRleCgpIGNvbnN0OworCisgIC8vIEdldHMgdGhlIHNlcnZpY2UgdG8gd2hpY2ggdGhpcyBtZXRob2QgYmVsb25ncy4gIE5ldmVyIE5VTEwuCisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlKCkgY29uc3Q7CisKKyAgLy8gR2V0cyB0aGUgdHlwZSBvZiBwcm90b2NvbCBtZXNzYWdlIHdoaWNoIHRoaXMgbWV0aG9kIGFjY2VwdHMgYXMgaW5wdXQuCisgIGNvbnN0IERlc2NyaXB0b3IqIGlucHV0X3R5cGUoKSBjb25zdDsKKyAgLy8gR2V0cyB0aGUgdHlwZSBvZiBwcm90b2NvbCBtZXNzYWdlIHdoaWNoIHRoaXMgbWVzc2FnZSBwcm9kdWNlcyBhcyBvdXRwdXQuCisgIGNvbnN0IERlc2NyaXB0b3IqIG91dHB1dF90eXBlKCkgY29uc3Q7CisKKyAgLy8gR2V0cyB3aGV0aGVyIHRoZSBjbGllbnQgc3RyZWFtcyBtdWx0aXBsZSByZXF1ZXN0cy4KKyAgYm9vbCBjbGllbnRfc3RyZWFtaW5nKCkgY29uc3Q7CisgIC8vIEdldHMgd2hldGhlciB0aGUgc2VydmVyIHN0cmVhbXMgbXVsdGlwbGUgcmVzcG9uc2VzLgorICBib29sIHNlcnZlcl9zdHJlYW1pbmcoKSBjb25zdDsKKworICAvLyBHZXQgb3B0aW9ucyBmb3IgdGhpcyBtZXRob2QuICBUaGVzZSBhcmUgc3BlY2lmaWVkIGluIHRoZSAucHJvdG8gZmlsZSBieQorICAvLyBwbGFjaW5nIGxpbmVzIGxpa2UgIm9wdGlvbiBmb28gPSAxMjM0OyIgaW4gY3VybHktYnJhY2VzIGFmdGVyIGEgbWV0aG9kCisgIC8vIGRlY2xhcmF0aW9uLiAgQWxsb3dlZCBvcHRpb25zIGFyZSBkZWZpbmVkIGJ5IE1ldGhvZE9wdGlvbnMgaW4KKyAgLy8gZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8sIGFuZCBhbnkgYXZhaWxhYmxlIGV4dGVuc2lvbnMgb2YgdGhhdAorICAvLyBtZXNzYWdlLgorICBjb25zdCBNZXRob2RPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkNvcHlUbygpLgorICB2b2lkIENvcHlUbyhNZXRob2REZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworCisgIC8vIFNvdXJjZSBMb2NhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBVcGRhdGVzIHwqb3V0X2xvY2F0aW9ufCB0byB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjb21wbGV0ZQorICAvLyBleHRlbnQgb2YgdGhpcyBtZXRob2QgZGVjbGFyYXRpb24uICBSZXR1cm5zIGZhbHNlIGFuZCBsZWF2ZXMKKyAgLy8gfCpvdXRfbG9jYXRpb258IHVuY2hhbmdlZCBpZmYgbG9jYXRpb24gaW5mb3JtYXRpb24gd2FzIG5vdCBhdmFpbGFibGUuCisgIGJvb2wgR2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3Q7CisKKyBwcml2YXRlOgorICB0eXBlZGVmIE1ldGhvZE9wdGlvbnMgT3B0aW9uc1R5cGU7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkuCisgIHZvaWQgRGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3Q7CisKKyAgLy8gV2Fsa3MgdXAgdGhlIGRlc2NyaXB0b3IgdHJlZSB0byBnZW5lcmF0ZSB0aGUgc291cmNlIGxvY2F0aW9uIHBhdGgKKyAgLy8gdG8gdGhpcyBkZXNjcmlwdG9yIGZyb20gdGhlIGZpbGUgcm9vdC4KKyAgdm9pZCBHZXRMb2NhdGlvblBhdGgoc3RkOjp2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdDsKKworICBjb25zdCBzdHJpbmcqIG5hbWVfOworICBjb25zdCBzdHJpbmcqIGZ1bGxfbmFtZV87CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogaW5wdXRfdHlwZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIG91dHB1dF90eXBlXzsKKyAgY29uc3QgTWV0aG9kT3B0aW9ucyogb3B0aW9uc187CisgIGJvb2wgY2xpZW50X3N0cmVhbWluZ187CisgIGJvb2wgc2VydmVyX3N0cmVhbWluZ187CisgIC8vIElNUE9SVEFOVDogIElmIHlvdSBhZGQgYSBuZXcgZmllbGQsIG1ha2Ugc3VyZSB0byBzZWFyY2ggZm9yIGFsbCBpbnN0YW5jZXMKKyAgLy8gb2YgQWxsb2NhdGU8TWV0aG9kRGVzY3JpcHRvcj4oKSBhbmQgQWxsb2NhdGVBcnJheTxNZXRob2REZXNjcmlwdG9yPigpIGluCisgIC8vIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIC8vIE11c3QgYmUgY29uc3RydWN0ZWQgdXNpbmcgRGVzY3JpcHRvclBvb2wuCisgIE1ldGhvZERlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcjsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1ldGhvZERlc2NyaXB0b3IpOworfTsKKworCisvLyBEZXNjcmliZXMgYSB3aG9sZSAucHJvdG8gZmlsZS4gIFRvIGdldCB0aGUgRmlsZURlc2NyaXB0b3IgZm9yIGEgY29tcGlsZWQtaW4KKy8vIGZpbGUsIGdldCB0aGUgZGVzY3JpcHRvciBmb3Igc29tZXRoaW5nIGRlZmluZWQgaW4gdGhhdCBmaWxlIGFuZCBjYWxsCisvLyBkZXNjcmlwdG9yLT5maWxlKCkuICBVc2UgRGVzY3JpcHRvclBvb2wgdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpbGVEZXNjcmlwdG9yIHsKKyBwdWJsaWM6CisgIC8vIFRoZSBmaWxlbmFtZSwgcmVsYXRpdmUgdG8gdGhlIHNvdXJjZSB0cmVlLgorICAvLyBlLmcuICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIKKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3Q7CisKKyAgLy8gVGhlIHBhY2thZ2UsIGUuZy4gImdvb2dsZS5wcm90b2J1Zi5jb21waWxlciIuCisgIGNvbnN0IHN0cmluZyYgcGFja2FnZSgpIGNvbnN0OworCisgIC8vIFRoZSBEZXNjcmlwdG9yUG9vbCBpbiB3aGljaCB0aGlzIEZpbGVEZXNjcmlwdG9yIGFuZCBhbGwgaXRzIGNvbnRlbnRzIHdlcmUKKyAgLy8gYWxsb2NhdGVkLiAgTmV2ZXIgTlVMTC4KKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2woKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIGZpbGVzIGltcG9ydGVkIGJ5IHRoaXMgb25lLgorICBpbnQgZGVwZW5kZW5jeV9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGFuIGltcG9ydGVkIGZpbGUgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPCBkZXBlbmRlbmN5X2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2YgZmlsZXMgcHVibGljIGltcG9ydGVkIGJ5IHRoaXMgb25lLgorICAvLyBUaGUgcHVibGljIGRlcGVuZGVuY3kgbGlzdCBpcyBhIHN1YnNldCBvZiB0aGUgZGVwZW5kZW5jeSBsaXN0LgorICBpbnQgcHVibGljX2RlcGVuZGVuY3lfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhIHB1YmxpYyBpbXBvcnRlZCBmaWxlIGJ5IGluZGV4LCB3aGVyZSAwIDw9IGluZGV4IDwKKyAgLy8gcHVibGljX2RlcGVuZGVuY3lfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBwdWJsaWNfZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2YgZmlsZXMgdGhhdCBhcmUgaW1wb3J0ZWQgZm9yIHdlYWsgZmllbGRzLgorICAvLyBUaGUgd2VhayBkZXBlbmRlbmN5IGxpc3QgaXMgYSBzdWJzZXQgb2YgdGhlIGRlcGVuZGVuY3kgbGlzdC4KKyAgaW50IHdlYWtfZGVwZW5kZW5jeV9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGEgd2VhayBpbXBvcnRlZCBmaWxlIGJ5IGluZGV4LCB3aGVyZSAwIDw9IGluZGV4IDwKKyAgLy8gd2Vha19kZXBlbmRlbmN5X2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogd2Vha19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gTnVtYmVyIG9mIHRvcC1sZXZlbCBtZXNzYWdlIHR5cGVzIGRlZmluZWQgaW4gdGhpcyBmaWxlLiAgKFRoaXMgZG9lcyBub3QKKyAgLy8gaW5jbHVkZSBuZXN0ZWQgdHlwZXMuKQorICBpbnQgbWVzc2FnZV90eXBlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSB0b3AtbGV2ZWwgbWVzc2FnZSB0eXBlLCB3aGVyZSAwIDw9IGluZGV4IDwgbWVzc2FnZV90eXBlX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUoaW50IGluZGV4KSBjb25zdDsKKworICAvLyBOdW1iZXIgb2YgdG9wLWxldmVsIGVudW0gdHlwZXMgZGVmaW5lZCBpbiB0aGlzIGZpbGUuICAoVGhpcyBkb2VzIG5vdAorICAvLyBpbmNsdWRlIG5lc3RlZCB0eXBlcy4pCisgIGludCBlbnVtX3R5cGVfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhIHRvcC1sZXZlbCBlbnVtIHR5cGUsIHdoZXJlIDAgPD0gaW5kZXggPCBlbnVtX3R5cGVfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUoaW50IGluZGV4KSBjb25zdDsKKworICAvLyBOdW1iZXIgb2Ygc2VydmljZXMgZGVmaW5lZCBpbiB0aGlzIGZpbGUuCisgIGludCBzZXJ2aWNlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSBzZXJ2aWNlLCB3aGVyZSAwIDw9IGluZGV4IDwgc2VydmljZV9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UoaW50IGluZGV4KSBjb25zdDsKKworICAvLyBOdW1iZXIgb2YgZXh0ZW5zaW9ucyBkZWZpbmVkIGF0IGZpbGUgc2NvcGUuICAoVGhpcyBkb2VzIG5vdCBpbmNsdWRlCisgIC8vIGV4dGVuc2lvbnMgbmVzdGVkIHdpdGhpbiBtZXNzYWdlIHR5cGVzLikKKyAgaW50IGV4dGVuc2lvbl9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGFuIGV4dGVuc2lvbidzIGRlc2NyaXB0b3IsIHdoZXJlIDAgPD0gaW5kZXggPCBleHRlbnNpb25fY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uKGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gR2V0IG9wdGlvbnMgZm9yIHRoaXMgZmlsZS4gIFRoZXNlIGFyZSBzcGVjaWZpZWQgaW4gdGhlIC5wcm90byBmaWxlIGJ5CisgIC8vIHBsYWNpbmcgbGluZXMgbGlrZSAib3B0aW9uIGZvbyA9IDEyMzQ7IiBhdCB0aGUgdG9wIGxldmVsLCBvdXRzaWRlIG9mIGFueQorICAvLyBvdGhlciBkZWZpbml0aW9ucy4gIEFsbG93ZWQgb3B0aW9ucyBhcmUgZGVmaW5lZCBieSBGaWxlT3B0aW9ucyBpbgorICAvLyBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bywgYW5kIGFueSBhdmFpbGFibGUgZXh0ZW5zaW9ucyBvZiB0aGF0CisgIC8vIG1lc3NhZ2UuCisgIGNvbnN0IEZpbGVPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gU3ludGF4IG9mIHRoaXMgZmlsZS4KKyAgZW51bSBTeW50YXggeworICAgIFNZTlRBWF9VTktOT1dOID0gMCwKKyAgICBTWU5UQVhfUFJPVE8yICA9IDIsCisgICAgU1lOVEFYX1BST1RPMyAgPSAzLAorICB9OworICBTeW50YXggc3ludGF4KCkgY29uc3Q7CisgIHN0YXRpYyBjb25zdCBjaGFyKiBTeW50YXhOYW1lKFN5bnRheCBzeW50YXgpOworCisgIC8vIEZpbmQgYSB0b3AtbGV2ZWwgbWVzc2FnZSB0eXBlIGJ5IG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm90IGZvdW5kLgorICBjb25zdCBEZXNjcmlwdG9yKiBGaW5kTWVzc2FnZVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgLy8gRmluZCBhIHRvcC1sZXZlbCBlbnVtIHR5cGUgYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBub3QgZm91bmQuCisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBGaW5kRW51bVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgLy8gRmluZCBhbiBlbnVtIHZhbHVlIGRlZmluZWQgaW4gYW55IHRvcC1sZXZlbCBlbnVtIGJ5IG5hbWUuICBSZXR1cm5zIE5VTEwgaWYKKyAgLy8gbm90IGZvdW5kLgorICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBGaW5kRW51bVZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIC8vIEZpbmQgYSBzZXJ2aWNlIGRlZmluaXRpb24gYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBub3QgZm91bmQuCisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBGaW5kU2VydmljZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICAvLyBGaW5kIGEgdG9wLWxldmVsIGV4dGVuc2lvbiBkZWZpbml0aW9uIGJ5IG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm90IGZvdW5kLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgLy8gU2ltaWxhciB0byBGaW5kRXh0ZW5zaW9uQnlOYW1lKCksIGJ1dCBzZWFyY2hlcyBieSBsb3dlcmNhc2VkLW5hbWUuICBTZWUKKyAgLy8gRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKCkuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICAvLyBTaW1pbGFyIHRvIEZpbmRFeHRlbnNpb25CeU5hbWUoKSwgYnV0IHNlYXJjaGVzIGJ5IGNhbWVsY2FzZWQtbmFtZS4gIFNlZQorICAvLyBEZXNjcmlwdG9yOjpGaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoKS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkNvcHlUbygpLgorICAvLyBOb3RlczoKKyAgLy8gLSBUaGlzIG1ldGhvZCBkb2VzIE5PVCBjb3B5IHNvdXJjZSBjb2RlIGluZm9ybWF0aW9uIHNpbmNlIGl0IGlzIHJlbGF0aXZlbHkKKyAgLy8gICBsYXJnZSBhbmQgcmFyZWx5IG5lZWRlZC4gIFNlZSBDb3B5U291cmNlQ29kZUluZm9UbygpIGJlbG93LgorICB2b2lkIENvcHlUbyhGaWxlRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3Q7CisgIC8vIFdyaXRlIHRoZSBzb3VyY2UgY29kZSBpbmZvcm1hdGlvbiBvZiB0aGlzIEZpbGVEZXNjcmlwdG9yIGludG8gdGhlIGdpdmVuCisgIC8vIEZpbGVEZXNjcmlwdG9yUHJvdG8uICBTZWUgQ29weVRvKCkgYWJvdmUuCisgIHZvaWQgQ29weVNvdXJjZUNvZGVJbmZvVG8oRmlsZURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICBzdHJpbmcgRGVidWdTdHJpbmcoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygpLgorICBzdHJpbmcgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGFuIHVua25vd24gZmlsZS4gVGhpcyB3aWxsCisgIC8vIG9ubHkgYmUgdGhlIGNhc2UgaWYgdGhpcyBkZXNjcmlwdG9yIGNvbWVzIGZyb20gYSBEZXNjcmlwdG9yUG9vbAorICAvLyB3aXRoIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIHNldC4KKyAgYm9vbCBpc19wbGFjZWhvbGRlcigpIGNvbnN0OworCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlIGV4dGVudCBvZgorICAvLyB0aGlzIGZpbGUgZGVjbGFyYXRpb24gKG5hbWVseSwgdGhlIGVtcHR5IHBhdGgpLgorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0OworCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlCisgIC8vIGV4dGVudCBvZiB0aGUgZGVjbGFyYXRpb24gb3IgZGVjbGFyYXRpb24tcGFydCBkZW5vdGVkIGJ5IHxwYXRofC4KKyAgLy8gUmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzIHwqb3V0X2xvY2F0aW9ufCB1bmNoYW5nZWQgaWZmIGxvY2F0aW9uCisgIC8vIGluZm9ybWF0aW9uIHdhcyBub3QgYXZhaWxhYmxlLiAgKFNlZSBTb3VyY2VDb2RlSW5mbyBmb3IKKyAgLy8gZGVzY3JpcHRpb24gb2YgcGF0aCBlbmNvZGluZy4pCisgIGJvb2wgR2V0U291cmNlTG9jYXRpb24oY29uc3Qgc3RkOjp2ZWN0b3I8aW50PiYgcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdDsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgRmlsZU9wdGlvbnMgT3B0aW9uc1R5cGU7CisKKyAgY29uc3Qgc3RyaW5nKiBuYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBwYWNrYWdlXzsKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2xfOworICBpbnQgZGVwZW5kZW5jeV9jb3VudF87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiogZGVwZW5kZW5jaWVzXzsKKyAgaW50IHB1YmxpY19kZXBlbmRlbmN5X2NvdW50XzsKKyAgaW50KiBwdWJsaWNfZGVwZW5kZW5jaWVzXzsKKyAgaW50IHdlYWtfZGVwZW5kZW5jeV9jb3VudF87CisgIGludCogd2Vha19kZXBlbmRlbmNpZXNfOworICBpbnQgbWVzc2FnZV90eXBlX2NvdW50XzsKKyAgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlc187CisgIGludCBlbnVtX3R5cGVfY291bnRfOworICBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlc187CisgIGludCBzZXJ2aWNlX2NvdW50XzsKKyAgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2VzXzsKKyAgaW50IGV4dGVuc2lvbl9jb3VudF87CisgIFN5bnRheCBzeW50YXhfOworICBib29sIGlzX3BsYWNlaG9sZGVyXzsKKyAgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb25zXzsKKyAgY29uc3QgRmlsZU9wdGlvbnMqIG9wdGlvbnNfOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yVGFibGVzKiB0YWJsZXNfOworICBjb25zdCBTb3VyY2VDb2RlSW5mbyogc291cmNlX2NvZGVfaW5mb187CisgIC8vIElNUE9SVEFOVDogIElmIHlvdSBhZGQgYSBuZXcgZmllbGQsIG1ha2Ugc3VyZSB0byBzZWFyY2ggZm9yIGFsbCBpbnN0YW5jZXMKKyAgLy8gb2YgQWxsb2NhdGU8RmlsZURlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8RmlsZURlc2NyaXB0b3I+KCkgaW4KKyAgLy8gZGVzY3JpcHRvci5jYyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgRmlsZURlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgT25lb2ZEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRW51bURlc2NyaXB0b3I7CisgIGZyaWVuZCBjbGFzcyBFbnVtVmFsdWVEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgTWV0aG9kRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmlsZURlc2NyaXB0b3IpOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBVc2VkIHRvIGNvbnN0cnVjdCBkZXNjcmlwdG9ycy4KKy8vCisvLyBOb3JtYWxseSB5b3Ugd29uJ3Qgd2FudCB0byBidWlsZCB5b3VyIG93biBkZXNjcmlwdG9ycy4gIE1lc3NhZ2UgY2xhc3NlcworLy8gY29uc3RydWN0ZWQgYnkgdGhlIHByb3RvY29sIGNvbXBpbGVyIHdpbGwgcHJvdmlkZSB0aGVtIGZvciB5b3UuICBIb3dldmVyLAorLy8gaWYgeW91IGFyZSBpbXBsZW1lbnRpbmcgTWVzc2FnZSBvbiB5b3VyIG93biwgb3IgaWYgeW91IGFyZSB3cml0aW5nIGEKKy8vIHByb2dyYW0gd2hpY2ggY2FuIG9wZXJhdGUgb24gdG90YWxseSBhcmJpdHJhcnkgdHlwZXMgYW5kIG5lZWRzIHRvIGxvYWQKKy8vIHRoZW0gZnJvbSBzb21lIHNvcnQgb2YgZGF0YWJhc2UsIHlvdSBtaWdodCBuZWVkIHRvLgorLy8KKy8vIFNpbmNlIERlc2NyaXB0b3JzIGFyZSBjb21wb3NlZCBvZiBhIHdob2xlIGxvdCBvZiBjcm9zcy1saW5rZWQgYml0cyBvZgorLy8gZGF0YSB0aGF0IHdvdWxkIGJlIGEgcGFpbiB0byBwdXQgdG9nZXRoZXIgbWFudWFsbHksIHRoZQorLy8gRGVzY3JpcHRvclBvb2wgY2xhc3MgaXMgcHJvdmlkZWQgdG8gbWFrZSB0aGUgcHJvY2VzcyBlYXNpZXIuICBJdCBjYW4KKy8vIHRha2UgYSBGaWxlRGVzY3JpcHRvclByb3RvIChkZWZpbmVkIGluIGRlc2NyaXB0b3IucHJvdG8pLCB2YWxpZGF0ZSBpdCwKKy8vIGFuZCBjb252ZXJ0IGl0IHRvIGEgc2V0IG9mIG5pY2VseSBjcm9zcy1saW5rZWQgRGVzY3JpcHRvcnMuCisvLworLy8gRGVzY3JpcHRvclBvb2wgYWxzbyBoZWxwcyB3aXRoIG1lbW9yeSBtYW5hZ2VtZW50LiAgRGVzY3JpcHRvcnMgYXJlCisvLyBjb21wb3NlZCBvZiBtYW55IG9iamVjdHMgY29udGFpbmluZyBzdGF0aWMgZGF0YSBhbmQgcG9pbnRlcnMgdG8gZWFjaAorLy8gb3RoZXIuICBJbiBhbGwgbGlrZWxpaG9vZCwgd2hlbiBpdCBjb21lcyB0aW1lIHRvIGRlbGV0ZSB0aGlzIGRhdGEsCisvLyB5b3UnbGwgd2FudCB0byBkZWxldGUgaXQgYWxsIGF0IG9uY2UuICBJbiBmYWN0LCBpdCBpcyBub3QgdW5jb21tb24gdG8KKy8vIGhhdmUgYSB3aG9sZSBwb29sIG9mIGRlc2NyaXB0b3JzIGFsbCBjcm9zcy1saW5rZWQgd2l0aCBlYWNoIG90aGVyIHdoaWNoCisvLyB5b3Ugd2lzaCB0byBkZWxldGUgYWxsIGF0IG9uY2UuICBUaGlzIGNsYXNzIHJlcHJlc2VudHMgc3VjaCBhIHBvb2wsIGFuZAorLy8gaGFuZGxlcyB0aGUgbWVtb3J5IG1hbmFnZW1lbnQgZm9yIHlvdS4KKy8vCisvLyBZb3UgY2FuIGFsc28gc2VhcmNoIGZvciBkZXNjcmlwdG9ycyB3aXRoaW4gYSBEZXNjcmlwdG9yUG9vbCBieSBuYW1lLCBhbmQKKy8vIGV4dGVuc2lvbnMgYnkgbnVtYmVyLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIERlc2NyaXB0b3JQb29sIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZSBhIG5vcm1hbCwgZW1wdHkgRGVzY3JpcHRvclBvb2wuCisgIERlc2NyaXB0b3JQb29sKCk7CisKKyAgLy8gQ29uc3RydWN0cyBhIERlc2NyaXB0b3JQb29sIHRoYXQsIHdoZW4gaXQgY2FuJ3QgZmluZCBzb21ldGhpbmcgYW1vbmcgdGhlCisgIC8vIGRlc2NyaXB0b3JzIGFscmVhZHkgaW4gdGhlIHBvb2wsIGxvb2tzIGZvciBpdCBpbiB0aGUgZ2l2ZW4KKyAgLy8gRGVzY3JpcHRvckRhdGFiYXNlLgorICAvLyBOb3RlczoKKyAgLy8gLSBJZiBhIERlc2NyaXB0b3JQb29sIGlzIGNvbnN0cnVjdGVkIHRoaXMgd2F5LCBpdHMgQnVpbGRGaWxlKigpIG1ldGhvZHMKKyAgLy8gICBtdXN0IG5vdCBiZSBjYWxsZWQgKHRoZXkgd2lsbCBhc3NlcnQtZmFpbCkuICBUaGUgb25seSB3YXkgdG8gcG9wdWxhdGUKKyAgLy8gICB0aGUgcG9vbCB3aXRoIGRlc2NyaXB0b3JzIGlzIHRvIGNhbGwgdGhlIEZpbmQqQnkqKCkgbWV0aG9kcy4KKyAgLy8gLSBUaGUgRmluZCpCeSooKSBtZXRob2RzIG1heSBibG9jayB0aGUgY2FsbGluZyB0aHJlYWQgaWYgdGhlCisgIC8vICAgRGVzY3JpcHRvckRhdGFiYXNlIGJsb2Nrcy4gIFRoaXMgaW4gdHVybiBtZWFucyB0aGF0IHBhcnNpbmcgbWVzc2FnZXMKKyAgLy8gICBtYXkgYmxvY2sgaWYgdGhleSBuZWVkIHRvIGxvb2sgdXAgZXh0ZW5zaW9ucy4KKyAgLy8gLSBUaGUgRmluZCpCeSooKSBtZXRob2RzIHdpbGwgdXNlIG11dGV4ZXMgZm9yIHRocmVhZC1zYWZldHksIHRodXMgbWFraW5nCisgIC8vICAgdGhlbSBzbG93ZXIgZXZlbiB3aGVuIHRoZXkgZG9uJ3QgaGF2ZSB0byBmYWxsIGJhY2sgdG8gdGhlIGRhdGFiYXNlLgorICAvLyAgIEluIGZhY3QsIGV2ZW4gdGhlIEZpbmQqQnkqKCkgbWV0aG9kcyBvZiBkZXNjcmlwdG9yIG9iamVjdHMgb3duZWQgYnkKKyAgLy8gICB0aGlzIHBvb2wgd2lsbCBiZSBzbG93ZXIsIHNpbmNlIHRoZXkgd2lsbCBoYXZlIHRvIG9idGFpbiBsb2NrcyB0b28uCisgIC8vIC0gQW4gRXJyb3JDb2xsZWN0b3IgbWF5IG9wdGlvbmFsbHkgYmUgZ2l2ZW4gdG8gY29sbGVjdCB2YWxpZGF0aW9uIGVycm9ycworICAvLyAgIGluIGZpbGVzIGxvYWRlZCBmcm9tIHRoZSBkYXRhYmFzZS4gIElmIG5vdCBnaXZlbiwgZXJyb3JzIHdpbGwgYmUgcHJpbnRlZAorICAvLyAgIHRvIEdPT0dMRV9MT0coRVJST1IpLiAgUmVtZW1iZXIgdGhhdCBmaWxlcyBhcmUgYnVpbHQgb24tZGVtYW5kLCBzbyB0aGlzCisgIC8vICAgRXJyb3JDb2xsZWN0b3IgbWF5IGJlIGNhbGxlZCBmcm9tIGFueSB0aHJlYWQgdGhhdCBjYWxscyBvbmUgb2YgdGhlCisgIC8vICAgRmluZCpCeSooKSBtZXRob2RzLgorICAvLyAtIFRoZSBEZXNjcmlwdG9yRGF0YWJhc2UgbXVzdCBub3QgYmUgbXV0YXRlZCBkdXJpbmcgdGhlIGxpZmV0aW1lIG9mCisgIC8vICAgdGhlIERlc2NyaXB0b3JQb29sLiBFdmVuIGlmIHRoZSBjbGllbnQgdGFrZXMgY2FyZSB0byBhdm9pZCBkYXRhIHJhY2VzLAorICAvLyAgIGNoYW5nZXMgdG8gdGhlIGNvbnRlbnQgb2YgdGhlIERlc2NyaXB0b3JEYXRhYmFzZSBtYXkgbm90IGJlIHJlZmxlY3RlZAorICAvLyAgIGluIHN1YnNlcXVlbnQgbG9va3VwcyBpbiB0aGUgRGVzY3JpcHRvclBvb2wuCisgIGNsYXNzIEVycm9yQ29sbGVjdG9yOworICBleHBsaWNpdCBEZXNjcmlwdG9yUG9vbChEZXNjcmlwdG9yRGF0YWJhc2UqIGZhbGxiYWNrX2RhdGFiYXNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yID0gTlVMTCk7CisKKyAgfkRlc2NyaXB0b3JQb29sKCk7CisKKyAgLy8gR2V0IGEgcG9pbnRlciB0byB0aGUgZ2VuZXJhdGVkIHBvb2wuICBHZW5lcmF0ZWQgcHJvdG9jb2wgbWVzc2FnZSBjbGFzc2VzCisgIC8vIHdoaWNoIGFyZSBjb21waWxlZCBpbnRvIHRoZSBiaW5hcnkgd2lsbCBhbGxvY2F0ZSB0aGVpciBkZXNjcmlwdG9ycyBpbgorICAvLyB0aGlzIHBvb2wuICBEbyBub3QgYWRkIHlvdXIgb3duIGRlc2NyaXB0b3JzIHRvIHRoaXMgcG9vbC4KKyAgc3RhdGljIGNvbnN0IERlc2NyaXB0b3JQb29sKiBnZW5lcmF0ZWRfcG9vbCgpOworCisgIC8vIEZpbmQgYSBGaWxlRGVzY3JpcHRvciBpbiB0aGUgcG9vbCBieSBmaWxlIG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm90CisgIC8vIGZvdW5kLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBGaW5kIHRoZSBGaWxlRGVzY3JpcHRvciBpbiB0aGUgcG9vbCB3aGljaCBkZWZpbmVzIHRoZSBnaXZlbiBzeW1ib2wuCisgIC8vIElmIGFueSBvZiB0aGUgRmluZCpCeU5hbWUoKSBtZXRob2RzIGJlbG93IHdvdWxkIHN1Y2NlZWQsIHRoZW4gdGhpcyBpcworICAvLyBlcXVpdmFsZW50IHRvIGNhbGxpbmcgdGhhdCBtZXRob2QgYW5kIGNhbGxpbmcgdGhlIHJlc3VsdCdzIGZpbGUoKSBtZXRob2QuCisgIC8vIE90aGVyd2lzZSB0aGlzIHJldHVybnMgTlVMTC4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUpIGNvbnN0OworCisgIC8vIExvb2tpbmcgdXAgZGVzY3JpcHRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGZpbmQgZGVzY3JpcHRvcnMgYnkgZnVsbHktcXVhbGlmaWVkIG5hbWUuICBUaGVzZSB3aWxsIGZpbmQgYm90aAorICAvLyB0b3AtbGV2ZWwgZGVzY3JpcHRvcnMgYW5kIG5lc3RlZCBkZXNjcmlwdG9ycy4gIFRoZXkgcmV0dXJuIE5VTEwgaWYgbm90CisgIC8vIGZvdW5kLgorCisgIGNvbnN0IERlc2NyaXB0b3IqIEZpbmRNZXNzYWdlVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBGaW5kT25lb2ZCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIEZpbmRFbnVtVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBGaW5kRW51bVZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBGaW5kU2VydmljZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBGaW5kTWV0aG9kQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gRmluZHMgYW4gZXh0ZW5zaW9uIG9mIHRoZSBnaXZlbiB0eXBlIGJ5IG51bWJlci4gIFRoZSBleHRlbmRlZSBtdXN0IGJlCisgIC8vIGEgbWVtYmVyIG9mIHRoaXMgRGVzY3JpcHRvclBvb2wgb3Igb25lIG9mIGl0cyB1bmRlcmxheXMuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyKSBjb25zdDsKKworICAvLyBGaW5kcyBleHRlbnNpb25zIG9mIGV4dGVuZGVlLiBUaGUgZXh0ZW5zaW9ucyB3aWxsIGJlIGFwcGVuZGVkIHRvCisgIC8vIG91dCBpbiBhbiB1bmRlZmluZWQgb3JkZXIuIE9ubHkgZXh0ZW5zaW9ucyBkZWZpbmVkIGRpcmVjdGx5IGluCisgIC8vIHRoaXMgRGVzY3JpcHRvclBvb2wgb3Igb25lIG9mIGl0cyB1bmRlcmxheXMgYXJlIGd1YXJhbnRlZWQgdG8gYmUKKyAgLy8gZm91bmQ6IGV4dGVuc2lvbnMgZGVmaW5lZCBpbiB0aGUgZmFsbGJhY2sgZGF0YWJhc2UgbWlnaHQgbm90IGJlIGZvdW5kCisgIC8vIGRlcGVuZGluZyBvbiB0aGUgZGF0YWJhc2UgaW1wbGVtZW50YXRpb24uCisgIHZvaWQgRmluZEFsbEV4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dCkgY29uc3Q7CisKKyAgLy8gQnVpbGRpbmcgZGVzY3JpcHRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBXaGVuIGNvbnZlcnRpbmcgYSBGaWxlRGVzY3JpcHRvclByb3RvIHRvIGEgRmlsZURlc2NyaXB0b3IsIHZhcmlvdXMKKyAgLy8gZXJyb3JzIG1pZ2h0IGJlIGRldGVjdGVkIGluIHRoZSBpbnB1dC4gIFRoZSBjYWxsZXIgbWF5IGhhbmRsZSB0aGVzZQorICAvLyBwcm9ncmFtbWF0aWNhbGx5IGJ5IGltcGxlbWVudGluZyBhbiBFcnJvckNvbGxlY3Rvci4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVycm9yQ29sbGVjdG9yIHsKKyAgIHB1YmxpYzoKKyAgICBpbmxpbmUgRXJyb3JDb2xsZWN0b3IoKSB7fQorICAgIHZpcnR1YWwgfkVycm9yQ29sbGVjdG9yKCk7CisKKyAgICAvLyBUaGVzZSBjb25zdGFudHMgc3BlY2lmeSB3aGF0IGV4YWN0IHBhcnQgb2YgdGhlIGNvbnN0cnVjdCBpcyBicm9rZW4uCisgICAgLy8gVGhpcyBpcyB1c2VmdWwgZS5nLiBmb3IgbWFwcGluZyB0aGUgZXJyb3IgYmFjayB0byBhbiBleGFjdCBsb2NhdGlvbgorICAgIC8vIGluIGEgLnByb3RvIGZpbGUuCisgICAgZW51bSBFcnJvckxvY2F0aW9uIHsKKyAgICAgIE5BTUUsICAgICAgICAgICAgICAvLyB0aGUgc3ltYm9sIG5hbWUsIG9yIHRoZSBwYWNrYWdlIG5hbWUgZm9yIGZpbGVzCisgICAgICBOVU1CRVIsICAgICAgICAgICAgLy8gZmllbGQgb3IgZXh0ZW5zaW9uIHJhbmdlIG51bWJlcgorICAgICAgVFlQRSwgICAgICAgICAgICAgIC8vIGZpZWxkIHR5cGUKKyAgICAgIEVYVEVOREVFLCAgICAgICAgICAvLyBmaWVsZCBleHRlbmRlZQorICAgICAgREVGQVVMVF9WQUxVRSwgICAgIC8vIGZpZWxkIGRlZmF1bHQgdmFsdWUKKyAgICAgIElOUFVUX1RZUEUsICAgICAgICAvLyBtZXRob2QgaW5wdXQgdHlwZQorICAgICAgT1VUUFVUX1RZUEUsICAgICAgIC8vIG1ldGhvZCBvdXRwdXQgdHlwZQorICAgICAgT1BUSU9OX05BTUUsICAgICAgIC8vIG5hbWUgaW4gYXNzaWdubWVudAorICAgICAgT1BUSU9OX1ZBTFVFLCAgICAgIC8vIHZhbHVlIGluIG9wdGlvbiBhc3NpZ25tZW50CisgICAgICBPVEhFUiAgICAgICAgICAgICAgLy8gc29tZSBvdGhlciBwcm9ibGVtCisgICAgfTsKKworICAgIC8vIFJlcG9ydHMgYW4gZXJyb3IgaW4gdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8uIFVzZSB0aGlzIGZ1bmN0aW9uIGlmIHRoZQorICAgIC8vIHByb2JsZW0gb2NjdXJyZWQgc2hvdWxkIGludGVycnVwdCBidWlsZGluZyB0aGUgRmlsZURlc2NyaXB0b3JQcm90by4KKyAgICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoCisgICAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCAgICAgIC8vIEZpbGUgbmFtZSBpbiB3aGljaCB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwgIC8vIEZ1bGwgbmFtZSBvZiB0aGUgZXJyb25lb3VzIGVsZW1lbnQuCisgICAgICBjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLCAgIC8vIERlc2NyaXB0b3Igb2YgdGhlIGVycm9uZW91cyBlbGVtZW50LgorICAgICAgRXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwgICAgICAvLyBPbmUgb2YgdGhlIGxvY2F0aW9uIGNvbnN0YW50cywgYWJvdmUuCisgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UgICAgICAgIC8vIEh1bWFuLXJlYWRhYmxlIGVycm9yIG1lc3NhZ2UuCisgICAgICApID0gMDsKKworICAgIC8vIFJlcG9ydHMgYSB3YXJuaW5nIGluIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvLiBVc2UgdGhpcyBmdW5jdGlvbiBpZiB0aGUKKyAgICAvLyBwcm9ibGVtIG9jY3VycmVkIHNob3VsZCBOT1QgaW50ZXJydXB0IGJ1aWxkaW5nIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvLgorICAgIHZpcnR1YWwgdm9pZCBBZGRXYXJuaW5nKAorICAgICAgY29uc3Qgc3RyaW5nJiAvKmZpbGVuYW1lKi8sICAgICAgLy8gRmlsZSBuYW1lIGluIHdoaWNoIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgIGNvbnN0IHN0cmluZyYgLyplbGVtZW50X25hbWUqLywgIC8vIEZ1bGwgbmFtZSBvZiB0aGUgZXJyb25lb3VzIGVsZW1lbnQuCisgICAgICBjb25zdCBNZXNzYWdlKiAvKmRlc2NyaXB0b3IqLywgICAvLyBEZXNjcmlwdG9yIG9mIHRoZSBlcnJvbmVvdXMgZWxlbWVudC4KKyAgICAgIEVycm9yTG9jYXRpb24gLypsb2NhdGlvbiovLCAgICAgIC8vIE9uZSBvZiB0aGUgbG9jYXRpb24gY29uc3RhbnRzLCBhYm92ZS4KKyAgICAgIGNvbnN0IHN0cmluZyYgLyptZXNzYWdlKi8gICAgICAgIC8vIEh1bWFuLXJlYWRhYmxlIGVycm9yIG1lc3NhZ2UuCisgICAgICApIHt9CisKKyAgIHByaXZhdGU6CisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVycm9yQ29sbGVjdG9yKTsKKyAgfTsKKworICAvLyBDb252ZXJ0IHRoZSBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHJlYWwgZGVzY3JpcHRvcnMgYW5kIHBsYWNlIHRoZW0gaW4KKyAgLy8gdGhpcyBEZXNjcmlwdG9yUG9vbC4gIEFsbCBkZXBlbmRlbmNpZXMgb2YgdGhlIGZpbGUgbXVzdCBhbHJlYWR5IGJlIGluCisgIC8vIHRoZSBwb29sLiAgUmV0dXJucyB0aGUgcmVzdWx0aW5nIEZpbGVEZXNjcmlwdG9yLCBvciBOVUxMIGlmIHRoZXJlIHdlcmUKKyAgLy8gcHJvYmxlbXMgd2l0aCB0aGUgaW5wdXQgKGUuZy4gdGhlIG1lc3NhZ2Ugd2FzIGludmFsaWQsIG9yIGRlcGVuZGVuY2llcworICAvLyB3ZXJlIG1pc3NpbmcpLiAgRGV0YWlscyBhYm91dCB0aGUgZXJyb3JzIGFyZSB3cml0dGVuIHRvIEdPT0dMRV9MT0coRVJST1IpLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKworICAvLyBTYW1lIGFzIEJ1aWxkRmlsZSgpIGV4Y2VwdCBlcnJvcnMgYXJlIHNlbnQgdG8gdGhlIGdpdmVuIEVycm9yQ29sbGVjdG9yLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycygKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICBFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKTsKKworICAvLyBCeSBkZWZhdWx0LCBpdCBpcyBhbiBlcnJvciBpZiBhIEZpbGVEZXNjcmlwdG9yUHJvdG8gY29udGFpbnMgcmVmZXJlbmNlcworICAvLyB0byB0eXBlcyBvciBvdGhlciBmaWxlcyB0aGF0IGFyZSBub3QgZm91bmQgaW4gdGhlIERlc2NyaXB0b3JQb29sIChvciBpdHMKKyAgLy8gYmFja2luZyBEZXNjcmlwdG9yRGF0YWJhc2UsIGlmIGFueSkuICBJZiB5b3UgY2FsbAorICAvLyBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSwgaG93ZXZlciwgdGhlbiB1bmtub3duIHR5cGVzIGFuZCBmaWxlcworICAvLyB3aWxsIGJlIHJlcGxhY2VkIGJ5IHBsYWNlaG9sZGVyIGRlc2NyaXB0b3JzICh3aGljaCBjYW4gYmUgaWRlbnRpZmllZCBieQorICAvLyB0aGUgaXNfcGxhY2Vob2xkZXIoKSBtZXRob2QpLiAgVGhpcyBjYW4gYWxsb3cgeW91IHRvCisgIC8vIHBlcmZvcm0gc29tZSB1c2VmdWwgb3BlcmF0aW9ucyB3aXRoIGEgLnByb3RvIGZpbGUgZXZlbiBpZiB5b3UgZG8gbm90CisgIC8vIGhhdmUgYWNjZXNzIHRvIG90aGVyIC5wcm90byBmaWxlcyBvbiB3aGljaCBpdCBkZXBlbmRzLiAgSG93ZXZlciwgc29tZQorICAvLyBoZXVyaXN0aWNzIG11c3QgYmUgdXNlZCB0byBmaWxsIGluIHRoZSBnYXBzIGluIGluZm9ybWF0aW9uLCBhbmQgdGhlc2UKKyAgLy8gY2FuIGxlYWQgdG8gZGVzY3JpcHRvcnMgd2hpY2ggYXJlIGluYWNjdXJhdGUuICBGb3IgZXhhbXBsZSwgdGhlCisgIC8vIERlc2NyaXB0b3JQb29sIG1heSBiZSBmb3JjZWQgdG8gZ3Vlc3Mgd2hldGhlciBhbiB1bmtub3duIHR5cGUgaXMgYSBtZXNzYWdlCisgIC8vIG9yIGFuIGVudW0sIGFzIHdlbGwgYXMgd2hhdCBwYWNrYWdlIGl0IHJlc2lkZXMgaW4uICBGdXJ0aGVybW9yZSwKKyAgLy8gcGxhY2Vob2xkZXIgdHlwZXMgd2lsbCBub3QgYmUgZGlzY292ZXJhYmxlIHZpYSBGaW5kTWVzc2FnZVR5cGVCeU5hbWUoKQorICAvLyBhbmQgc2ltaWxhciBtZXRob2RzLCB3aGljaCBjb3VsZCBjb25mdXNlIHNvbWUgZGVzY3JpcHRvci1iYXNlZCBhbGdvcml0aG1zLgorICAvLyBHZW5lcmFsbHksIHRoZSByZXN1bHRzIG9mIHRoaXMgb3B0aW9uIHNob3VsZCBiZSBoYW5kbGVkIHdpdGggZXh0cmVtZSBjYXJlLgorICB2b2lkIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIHsgYWxsb3dfdW5rbm93bl8gPSB0cnVlOyB9CisKKyAgLy8gQnkgZGVmYXVsdCwgd2VhayBpbXBvcnRzIGFyZSBhbGxvd2VkIHRvIGJlIG1pc3NpbmcsIGluIHdoaWNoIGNhc2Ugd2Ugd2lsbAorICAvLyB1c2UgYSBwbGFjZWhvbGRlciBmb3IgdGhlIGRlcGVuZGVuY3kgYW5kIGNvbnZlcnQgdGhlIGZpZWxkIHRvIGJlIGFuIEVtcHR5CisgIC8vIG1lc3NhZ2UgZmllbGQuIElmIHlvdSBjYWxsIEVuZm9yY2VXZWFrRGVwZW5kZW5jaWVzKHRydWUpLCBob3dldmVyLCB0aGUKKyAgLy8gRGVzY3JpcHRvclBvb2wgd2lsbCByZXBvcnQgYSBpbXBvcnQgbm90IGZvdW5kIGVycm9yLgorICB2b2lkIEVuZm9yY2VXZWFrRGVwZW5kZW5jaWVzKGJvb2wgZW5mb3JjZSkgeyBlbmZvcmNlX3dlYWtfID0gZW5mb3JjZTsgfQorCisgIC8vIEludGVybmFsIHN0dWZmIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIG1ldGhvZHMgTVVTVCBOT1QgYmUgY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgcHJvdG8yIGxpYnJhcnkuCisgIC8vIFRoZXNlIG1ldGhvZHMgbWF5IGNvbnRhaW4gaGlkZGVuIHBpdGZhbGxzIGFuZCBtYXkgYmUgcmVtb3ZlZCBpbiBhCisgIC8vIGZ1dHVyZSBsaWJyYXJ5IHZlcnNpb24uCisKKyAgLy8gQ3JlYXRlIGEgRGVzY3JpcHRvclBvb2wgd2hpY2ggaXMgb3ZlcmxhaWQgb24gdG9wIG9mIHNvbWUgb3RoZXIgcG9vbC4KKyAgLy8gSWYgeW91IHNlYXJjaCBmb3IgYSBkZXNjcmlwdG9yIGluIHRoZSBvdmVybGF5IGFuZCBpdCBpcyBub3QgZm91bmQsIHRoZQorICAvLyB1bmRlcmxheSB3aWxsIGJlIHNlYXJjaGVkIGFzIGEgYmFja3VwLiAgSWYgdGhlIHVuZGVybGF5IGhhcyBpdHMgb3duCisgIC8vIHVuZGVybGF5LCB0aGF0IHdpbGwgYmUgc2VhcmNoZWQgbmV4dCwgYW5kIHNvIG9uLiAgVGhpcyBhbHNvIG1lYW5zIHRoYXQKKyAgLy8gZmlsZXMgYnVpbHQgaW4gdGhlIG92ZXJsYXkgd2lsbCBiZSBjcm9zcy1saW5rZWQgd2l0aCB0aGUgdW5kZXJsYXkncworICAvLyBkZXNjcmlwdG9ycyBpZiBuZWNlc3NhcnkuICBUaGUgdW5kZXJsYXkgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgY2FsbGVyOworICAvLyBpdCBtdXN0IHJlbWFpbiB2YWxpZCBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBuZXdseS1jb25zdHJ1Y3RlZCBwb29sLgorICAvLworICAvLyBFeGFtcGxlOiAgU2F5IHlvdSB3YW50IHRvIHBhcnNlIGEgLnByb3RvIGZpbGUgYXQgcnVudGltZSBpbiBvcmRlciB0byB1c2UKKyAgLy8gaXRzIHR5cGUgd2l0aCBhIER5bmFtaWNNZXNzYWdlLiAgU2F5IHRoaXMgLnByb3RvIGZpbGUgaGFzIGRlcGVuZGVuY2llcywKKyAgLy8gYnV0IHlvdSBrbm93IHRoYXQgYWxsIHRoZSBkZXBlbmRlbmNpZXMgd2lsbCBiZSB0aGluZ3MgdGhhdCBhcmUgYWxyZWFkeQorICAvLyBjb21waWxlZCBpbnRvIHRoZSBiaW5hcnkuICBGb3IgZWFzZSBvZiB1c2UsIHlvdSdkIGxpa2UgdG8gbG9hZCB0aGUgdHlwZXMKKyAgLy8gcmlnaHQgb3V0IG9mIGdlbmVyYXRlZF9wb29sKCkgcmF0aGVyIHRoYW4gaGF2ZSB0byBwYXJzZSByZWR1bmRhbnQgY29waWVzCisgIC8vIG9mIGFsbCB0aGVzZSAucHJvdG9zIGFuZCBydW50aW1lLiAgQnV0LCB5b3UgZG9uJ3Qgd2FudCB0byBhZGQgdGhlIHBhcnNlZAorICAvLyB0eXBlcyBkaXJlY3RseSBpbnRvIGdlbmVyYXRlZF9wb29sKCk6IHRoaXMgaXMgbm90IGFsbG93ZWQsIGFuZCB3b3VsZCBiZQorICAvLyBiYWQgZGVzaWduIGFueXdheS4gIFNvLCBpbnN0ZWFkLCB5b3UgY291bGQgdXNlIGdlbmVyYXRlZF9wb29sKCkgYXMgYW4KKyAgLy8gdW5kZXJsYXkgZm9yIGEgbmV3IERlc2NyaXB0b3JQb29sIGluIHdoaWNoIHlvdSBhZGQgb25seSB0aGUgbmV3IGZpbGUuCisgIC8vCisgIC8vIFdBUk5JTkc6ICBVc2Ugb2YgdW5kZXJsYXlzIGNhbiBsZWFkIHRvIG1hbnkgc3VidGxlIGdvdGNoYXMuICBJbnN0ZWFkLAorICAvLyAgIHRyeSB0byBmb3JtdWxhdGUgd2hhdCB5b3Ugd2FudCB0byBkbyBpbiB0ZXJtcyBvZiBEZXNjcmlwdG9yRGF0YWJhc2VzLgorICBleHBsaWNpdCBEZXNjcmlwdG9yUG9vbChjb25zdCBEZXNjcmlwdG9yUG9vbCogdW5kZXJsYXkpOworCisgIC8vIENhbGxlZCBieSBnZW5lcmF0ZWQgY2xhc3NlcyBhdCBpbml0IHRpbWUgdG8gYWRkIHRoZWlyIGRlc2NyaXB0b3JzIHRvCisgIC8vIGdlbmVyYXRlZF9wb29sLiAgRG8gTk9UIGNhbGwgdGhpcyBpbiB5b3VyIG93biBjb2RlISAgZmlsZW5hbWUgbXVzdCBiZSBhCisgIC8vIHBlcm1hbmVudCBzdHJpbmcgKGUuZy4gYSBzdHJpbmcgbGl0ZXJhbCkuCisgIHN0YXRpYyB2b2lkIEludGVybmFsQWRkR2VuZXJhdGVkRmlsZSgKKyAgICAgIGNvbnN0IHZvaWQqIGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBpbnQgc2l6ZSk7CisKKworICAvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHk6ICBHZXRzIGEgbm9uLWNvbnN0IHBvaW50ZXIgdG8gdGhlIGdlbmVyYXRlZCBwb29sLgorICAvLyBUaGlzIGlzIGNhbGxlZCBhdCBzdGF0aWMtaW5pdGlhbGl6YXRpb24gdGltZSBvbmx5LCBzbyB0aHJlYWQtc2FmZXR5IGlzCisgIC8vIG5vdCBhIGNvbmNlcm4uICBJZiBib3RoIGFuIHVuZGVybGF5IGFuZCBhIGZhbGxiYWNrIGRhdGFiYXNlIGFyZSBwcmVzZW50LAorICAvLyB0aGUgdW5kZXJsYXkgdGFrZXMgcHJlY2VkZW5jZS4KKyAgc3RhdGljIERlc2NyaXB0b3JQb29sKiBpbnRlcm5hbF9nZW5lcmF0ZWRfcG9vbCgpOworCisgIC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seTogIENoYW5nZXMgdGhlIGJlaGF2aW9yIG9mIEJ1aWxkRmlsZSgpIHN1Y2ggdGhhdCBpdAorICAvLyBhbGxvd3MgdGhlIGZpbGUgdG8gbWFrZSByZWZlcmVuY2UgdG8gbWVzc2FnZSB0eXBlcyBkZWNsYXJlZCBpbiBvdGhlciBmaWxlcworICAvLyB3aGljaCBpdCBkaWQgbm90IG9mZmljaWFsbHkgZGVjbGFyZSBhcyBkZXBlbmRlbmNpZXMuCisgIHZvaWQgSW50ZXJuYWxEb250RW5mb3JjZURlcGVuZGVuY2llcygpOworCisgIC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS4KKyAgdm9pZCBpbnRlcm5hbF9zZXRfdW5kZXJsYXkoY29uc3QgRGVzY3JpcHRvclBvb2wqIHVuZGVybGF5KSB7CisgICAgdW5kZXJsYXlfID0gdW5kZXJsYXk7CisgIH0KKworICAvLyBGb3IgaW50ZXJuYWwgKHVuaXQgdGVzdCkgdXNlIG9ubHk6ICBSZXR1cm5zIHRydWUgaWYgYSBGaWxlRGVzY3JpcHRvciBoYXMKKyAgLy8gYmVlbiBjb25zdHJ1Y3RlZCBmb3IgdGhlIGdpdmVuIGZpbGUsIGZhbHNlIG90aGVyd2lzZS4gIFVzZWZ1bCBmb3IgdGVzdGluZworICAvLyBsYXp5IGRlc2NyaXB0b3IgaW5pdGlhbGl6YXRpb24gYmVoYXZpb3IuCisgIGJvb2wgSW50ZXJuYWxJc0ZpbGVMb2FkZWQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgY29uc3Q7CisKKworICAvLyBBZGQgYSBmaWxlIHRvIHVudXNlZF9pbXBvcnRfdHJhY2tfZmlsZXNfLiBEZXNjcmlwdG9yQnVpbGRlciB3aWxsIGxvZworICAvLyB3YXJuaW5ncyBmb3IgdGhvc2UgZmlsZXMgaWYgdGhlcmUgaXMgYW55IHVudXNlZCBpbXBvcnQuCisgIHZvaWQgQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKTsKKyAgdm9pZCBDbGVhclVudXNlZEltcG9ydFRyYWNrRmlsZXMoKTsKKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRW51bURlc2NyaXB0b3I7CisgIGZyaWVuZCBjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBGaWxlRGVzY3JpcHRvclRhYmxlczsKKworICAvLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbmFtZSBpcyBhIHN1Yi1zeW1ib2wgb2YgYW55IG5vbi1wYWNrYWdlCisgIC8vIGRlc2NyaXB0b3IgdGhhdCBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgZGVzY3JpcHRvciBwb29sLiAgKFRoZSBmdWxsCisgIC8vIGRlZmluaXRpb24gb2Ygc3VjaCB0eXBlcyBpcyBhbHJlYWR5IGtub3duLikKKyAgYm9vbCBJc1N1YlN5bWJvbE9mQnVpbHRUeXBlKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gVHJpZXMgdG8gZmluZCBzb21ldGhpbmcgaW4gdGhlIGZhbGxiYWNrIGRhdGFiYXNlIGFuZCBsaW5rIGluIHRoZQorICAvLyBjb3JyZXNwb25kaW5nIHByb3RvIGZpbGUuICBSZXR1cm5zIHRydWUgaWYgc3VjY2Vzc2Z1bCwgaW4gd2hpY2ggY2FzZQorICAvLyB0aGUgY2FsbGVyIHNob3VsZCBzZWFyY2ggZm9yIHRoZSB0aGluZyBhZ2Fpbi4gIFRoZXNlIGFyZSBkZWNsYXJlZAorICAvLyBjb25zdCBiZWNhdXNlIHRoZXkgYXJlIGNhbGxlZCBieSAoc2VtYW50aWNhbGx5KSBjb25zdCBtZXRob2RzLgorICBib29sIFRyeUZpbmRGaWxlSW5GYWxsYmFja0RhdGFiYXNlKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIGJvb2wgVHJ5RmluZFN5bWJvbEluRmFsbGJhY2tEYXRhYmFzZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBib29sIFRyeUZpbmRFeHRlbnNpb25JbkZhbGxiYWNrRGF0YWJhc2UoY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlcikgY29uc3Q7CisKKyAgLy8gTGlrZSBCdWlsZEZpbGUoKSBidXQgY2FsbGVkIGludGVybmFsbHkgd2hlbiB0aGUgZmlsZSBoYXMgYmVlbiBsb2FkZWQgZnJvbQorICAvLyBmYWxsYmFja19kYXRhYmFzZV8uICBEZWNsYXJlZCBjb25zdCBiZWNhdXNlIGl0IGlzIGNhbGxlZCBieSAoc2VtYW50aWNhbGx5KQorICAvLyBjb25zdCBtZXRob2RzLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlRnJvbURhdGFiYXNlKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSBjb25zdDsKKworICAvLyBJZiBmYWxsYmFja19kYXRhYmFzZV8gaXMgTlVMTCwgdGhpcyBpcyBOVUxMLiAgT3RoZXJ3aXNlLCB0aGlzIGlzIGEgbXV0ZXgKKyAgLy8gd2hpY2ggbXVzdCBiZSBsb2NrZWQgd2hpbGUgYWNjZXNzaW5nIHRhYmxlc18uCisgIE11dGV4KiBtdXRleF87CisKKyAgLy8gU2VlIGNvbnN0cnVjdG9yLgorICBEZXNjcmlwdG9yRGF0YWJhc2UqIGZhbGxiYWNrX2RhdGFiYXNlXzsKKyAgRXJyb3JDb2xsZWN0b3IqIGRlZmF1bHRfZXJyb3JfY29sbGVjdG9yXzsKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHVuZGVybGF5XzsKKworICAvLyBUaGlzIGNsYXNzIGNvbnRhaW5zIGEgbG90IG9mIGhhc2ggbWFwcyB3aXRoIGNvbXBsaWNhdGVkIHR5cGVzIHRoYXQKKyAgLy8gd2UnZCBsaWtlIHRvIGtlZXAgb3V0IG9mIHRoZSBoZWFkZXIuCisgIGNsYXNzIFRhYmxlczsKKyAgc2NvcGVkX3B0cjxUYWJsZXM+IHRhYmxlc187CisKKyAgYm9vbCBlbmZvcmNlX2RlcGVuZGVuY2llc187CisgIGJvb2wgYWxsb3dfdW5rbm93bl87CisgIGJvb2wgZW5mb3JjZV93ZWFrXzsKKyAgc3RkOjpzZXQ8c3RyaW5nPiB1bnVzZWRfaW1wb3J0X3RyYWNrX2ZpbGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGVzY3JpcHRvclBvb2wpOworfTsKKworLy8gaW5saW5lIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUaGVzZSBtYWNyb3MgbWFrZXMgdGhpcyByZXBldGl0aXZlIGNvZGUgbW9yZSByZWFkYWJsZS4KKyNkZWZpbmUgUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKENMQVNTLCBGSUVMRCwgVFlQRSkgXAorICBpbmxpbmUgVFlQRSBDTEFTUzo6RklFTEQoKSBjb25zdCB7IHJldHVybiBGSUVMRCMjXzsgfQorCisvLyBTdHJpbmdzIGZpZWxkcyBhcmUgc3RvcmVkIGFzIHBvaW50ZXJzIGJ1dCByZXR1cm5lZCBhcyBjb25zdCByZWZlcmVuY2VzLgorI2RlZmluZSBQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKENMQVNTLCBGSUVMRCkgXAorICBpbmxpbmUgY29uc3Qgc3RyaW5nJiBDTEFTUzo6RklFTEQoKSBjb25zdCB7IHJldHVybiAqRklFTEQjI187IH0KKworLy8gQXJyYXlzIHRha2UgYW4gaW5kZXggcGFyYW1ldGVyLCBvYnZpb3VzbHkuCisjZGVmaW5lIFBST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihDTEFTUywgRklFTEQsIFRZUEUpIFwKKyAgaW5saW5lIFRZUEUgQ0xBU1M6OkZJRUxEKGludCBpbmRleCkgY29uc3QgeyByZXR1cm4gRklFTEQjI3NfICsgaW5kZXg7IH0KKworI2RlZmluZSBQUk9UT0JVRl9ERUZJTkVfT1BUSU9OU19BQ0NFU1NPUihDTEFTUywgVFlQRSkgXAorICBpbmxpbmUgY29uc3QgVFlQRSYgQ0xBU1M6Om9wdGlvbnMoKSBjb25zdCB7IHJldHVybiAqb3B0aW9uc187IH0KKworUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihEZXNjcmlwdG9yLCBuYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihEZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRGVzY3JpcHRvciwgZmlsZSwgY29uc3QgRmlsZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIGNvbnRhaW5pbmdfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCisKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBmaWVsZF9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIG9uZW9mX2RlY2xfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBuZXN0ZWRfdHlwZV9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIGVudW1fdHlwZV9jb3VudCwgaW50KQorCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRGVzY3JpcHRvciwgZmllbGQsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRGVzY3JpcHRvciwgb25lb2ZfZGVjbCwgY29uc3QgT25lb2ZEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBuZXN0ZWRfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRGVzY3JpcHRvciwgZW51bV90eXBlLCBjb25zdCBFbnVtRGVzY3JpcHRvciopCisKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBleHRlbnNpb25fcmFuZ2VfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBleHRlbnNpb25fY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBleHRlbnNpb25fcmFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqKQorUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SKERlc2NyaXB0b3IsIGV4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX09QVElPTlNfQUNDRVNTT1IoRGVzY3JpcHRvciwgTWVzc2FnZU9wdGlvbnMpOworUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIGlzX3BsYWNlaG9sZGVyLCBib29sKQorCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgbG93ZXJjYXNlX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgY2FtZWxjYXNlX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBmaWxlLCBjb25zdCBGaWxlRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBudW1iZXIsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGlzX2V4dGVuc2lvbiwgYm9vbCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIHR5cGUsIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGxhYmVsLCBGaWVsZERlc2NyaXB0b3I6OkxhYmVsKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgY29udGFpbmluZ190eXBlLCBjb25zdCBEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGNvbnRhaW5pbmdfb25lb2YsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGluZGV4X2luX29uZW9mLCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBleHRlbnNpb25fc2NvcGUsIGNvbnN0IERlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgbWVzc2FnZV90eXBlLCBjb25zdCBEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGVudW1fdHlwZSwgY29uc3QgRW51bURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX09QVElPTlNfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBGaWVsZE9wdGlvbnMpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBoYXNfZGVmYXVsdF92YWx1ZSwgYm9vbCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGRlZmF1bHRfdmFsdWVfaW50MzIgLCBpbnQzMiApCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBkZWZhdWx0X3ZhbHVlX2ludDY0ICwgaW50NjQgKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZGVmYXVsdF92YWx1ZV91aW50MzIsIHVpbnQzMikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGRlZmF1bHRfdmFsdWVfdWludDY0LCB1aW50NjQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBkZWZhdWx0X3ZhbHVlX2Zsb2F0ICwgZmxvYXQgKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZGVmYXVsdF92YWx1ZV9kb3VibGUsIGRvdWJsZSkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGRlZmF1bHRfdmFsdWVfYm9vbCAgLCBib29sICApCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBkZWZhdWx0X3ZhbHVlX2VudW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZGVmYXVsdF92YWx1ZV9zdHJpbmcpCisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoT25lb2ZEZXNjcmlwdG9yLCBuYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihPbmVvZkRlc2NyaXB0b3IsIGZ1bGxfbmFtZSkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihPbmVvZkRlc2NyaXB0b3IsIGNvbnRhaW5pbmdfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoT25lb2ZEZXNjcmlwdG9yLCBmaWVsZF9jb3VudCwgaW50KQorCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEVudW1EZXNjcmlwdG9yLCBuYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihFbnVtRGVzY3JpcHRvciwgZnVsbF9uYW1lKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1EZXNjcmlwdG9yLCBmaWxlLCBjb25zdCBGaWxlRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRW51bURlc2NyaXB0b3IsIGNvbnRhaW5pbmdfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRW51bURlc2NyaXB0b3IsIHZhbHVlX2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRW51bURlc2NyaXB0b3IsIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX09QVElPTlNfQUNDRVNTT1IoRW51bURlc2NyaXB0b3IsIEVudW1PcHRpb25zKTsKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihFbnVtRGVzY3JpcHRvciwgaXNfcGxhY2Vob2xkZXIsIGJvb2wpCisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRW51bVZhbHVlRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRW51bVZhbHVlRGVzY3JpcHRvciwgZnVsbF9uYW1lKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1WYWx1ZURlc2NyaXB0b3IsIG51bWJlciwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1WYWx1ZURlc2NyaXB0b3IsIHR5cGUsIGNvbnN0IEVudW1EZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKEVudW1WYWx1ZURlc2NyaXB0b3IsIEVudW1WYWx1ZU9wdGlvbnMpCisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoU2VydmljZURlc2NyaXB0b3IsIG5hbWUpCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKFNlcnZpY2VEZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoU2VydmljZURlc2NyaXB0b3IsIGZpbGUsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihTZXJ2aWNlRGVzY3JpcHRvciwgbWV0aG9kX2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoU2VydmljZURlc2NyaXB0b3IsIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKFNlcnZpY2VEZXNjcmlwdG9yLCBTZXJ2aWNlT3B0aW9ucyk7CisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoTWV0aG9kRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoTWV0aG9kRGVzY3JpcHRvciwgZnVsbF9uYW1lKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKE1ldGhvZERlc2NyaXB0b3IsIHNlcnZpY2UsIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBpbnB1dF90eXBlLCBjb25zdCBEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBvdXRwdXRfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfT1BUSU9OU19BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBNZXRob2RPcHRpb25zKTsKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBjbGllbnRfc3RyZWFtaW5nLCBib29sKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKE1ldGhvZERlc2NyaXB0b3IsIHNlcnZlcl9zdHJlYW1pbmcsIGJvb2wpCisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIG5hbWUpCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBwYWNrYWdlKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBwb29sLCBjb25zdCBEZXNjcmlwdG9yUG9vbCopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIGRlcGVuZGVuY3lfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgcHVibGljX2RlcGVuZGVuY3lfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgd2Vha19kZXBlbmRlbmN5X2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIG1lc3NhZ2VfdHlwZV9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBlbnVtX3R5cGVfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgc2VydmljZV9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBleHRlbnNpb25fY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBGaWxlT3B0aW9ucyk7CitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIGlzX3BsYWNlaG9sZGVyLCBib29sKQorCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIG1lc3NhZ2VfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIGVudW1fdHlwZSwgY29uc3QgRW51bURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciopCisKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SCisjdW5kZWYgUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SCisKKy8vIEEgZmV3IGFjY2Vzc29ycyBkaWZmZXIgZnJvbSB0aGUgbWFjcm9zLi4uCisKK2lubGluZSBib29sIERlc2NyaXB0b3I6OklzRXh0ZW5zaW9uTnVtYmVyKGludCBudW1iZXIpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRFeHRlbnNpb25SYW5nZUNvbnRhaW5pbmdOdW1iZXIobnVtYmVyKSAhPSBOVUxMOworfQorCitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3I6OmlzX3JlcXVpcmVkKCkgY29uc3QgeworICByZXR1cm4gbGFiZWwoKSA9PSBMQUJFTF9SRVFVSVJFRDsKK30KKworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yOjppc19vcHRpb25hbCgpIGNvbnN0IHsKKyAgcmV0dXJuIGxhYmVsKCkgPT0gTEFCRUxfT1BUSU9OQUw7Cit9CisKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvcjo6aXNfcmVwZWF0ZWQoKSBjb25zdCB7CisgIHJldHVybiBsYWJlbCgpID09IExBQkVMX1JFUEVBVEVEOworfQorCitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3I6OmlzX3BhY2thYmxlKCkgY29uc3QgeworICByZXR1cm4gaXNfcmVwZWF0ZWQoKSAmJiBJc1R5cGVQYWNrYWJsZSh0eXBlKCkpOworfQorCisvLyBUbyBzYXZlIHNwYWNlLCBpbmRleCgpIGlzIGNvbXB1dGVkIGJ5IGxvb2tpbmcgYXQgdGhlIGRlc2NyaXB0b3IncyBwb3NpdGlvbgorLy8gaW4gdGhlIHBhcmVudCdzIGFycmF5IG9mIGNoaWxkcmVuLgoraW5saW5lIGludCBGaWVsZERlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICBpZiAoIWlzX2V4dGVuc2lvbl8pIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gY29udGFpbmluZ190eXBlXy0+ZmllbGRzXyk7CisgIH0gZWxzZSBpZiAoZXh0ZW5zaW9uX3Njb3BlXyAhPSBOVUxMKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGV4dGVuc2lvbl9zY29wZV8tPmV4dGVuc2lvbnNfKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gZmlsZV8tPmV4dGVuc2lvbnNfKTsKKyAgfQorfQorCitpbmxpbmUgaW50IERlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICBpZiAoY29udGFpbmluZ190eXBlXyA9PSBOVUxMKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGZpbGVfLT5tZXNzYWdlX3R5cGVzXyk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGNvbnRhaW5pbmdfdHlwZV8tPm5lc3RlZF90eXBlc18pOworICB9Cit9CisKK2lubGluZSBpbnQgT25lb2ZEZXNjcmlwdG9yOjppbmRleCgpIGNvbnN0IHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGNvbnRhaW5pbmdfdHlwZV8tPm9uZW9mX2RlY2xzXyk7Cit9CisKK2lubGluZSBpbnQgRW51bURlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICBpZiAoY29udGFpbmluZ190eXBlXyA9PSBOVUxMKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGZpbGVfLT5lbnVtX3R5cGVzXyk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGNvbnRhaW5pbmdfdHlwZV8tPmVudW1fdHlwZXNfKTsKKyAgfQorfQorCitpbmxpbmUgaW50IEVudW1WYWx1ZURlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gdHlwZV8tPnZhbHVlc18pOworfQorCitpbmxpbmUgaW50IFNlcnZpY2VEZXNjcmlwdG9yOjppbmRleCgpIGNvbnN0IHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGhpcyAtIGZpbGVfLT5zZXJ2aWNlc18pOworfQorCitpbmxpbmUgaW50IE1ldGhvZERlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gc2VydmljZV8tPm1ldGhvZHNfKTsKK30KKworaW5saW5lIGNvbnN0IGNoYXIqIEZpZWxkRGVzY3JpcHRvcjo6dHlwZV9uYW1lKCkgY29uc3QgeworICByZXR1cm4ga1R5cGVUb05hbWVbdHlwZV9dOworfQorCitpbmxpbmUgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIEZpZWxkRGVzY3JpcHRvcjo6Y3BwX3R5cGUoKSBjb25zdCB7CisgIHJldHVybiBrVHlwZVRvQ3BwVHlwZU1hcFt0eXBlX107Cit9CisKK2lubGluZSBjb25zdCBjaGFyKiBGaWVsZERlc2NyaXB0b3I6OmNwcF90eXBlX25hbWUoKSBjb25zdCB7CisgIHJldHVybiBrQ3BwVHlwZVRvTmFtZVtrVHlwZVRvQ3BwVHlwZU1hcFt0eXBlX11dOworfQorCitpbmxpbmUgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIEZpZWxkRGVzY3JpcHRvcjo6VHlwZVRvQ3BwVHlwZShUeXBlIHR5cGUpIHsKKyAgcmV0dXJuIGtUeXBlVG9DcHBUeXBlTWFwW3R5cGVdOworfQorCitpbmxpbmUgY29uc3QgY2hhciogRmllbGREZXNjcmlwdG9yOjpUeXBlTmFtZShUeXBlIHR5cGUpIHsKKyAgcmV0dXJuIGtUeXBlVG9OYW1lW3R5cGVdOworfQorCitpbmxpbmUgY29uc3QgY2hhciogRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlTmFtZShDcHBUeXBlIGNwcF90eXBlKSB7CisgIHJldHVybiBrQ3BwVHlwZVRvTmFtZVtjcHBfdHlwZV07Cit9CisKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvcjo6SXNUeXBlUGFja2FibGUoVHlwZSBmaWVsZF90eXBlKSB7CisgIHJldHVybiAoZmllbGRfdHlwZSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICYmCisgICAgICAgICAgZmllbGRfdHlwZSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgJiYKKyAgICAgICAgICBmaWVsZF90eXBlICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFICYmCisgICAgICAgICAgZmllbGRfdHlwZSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpOworfQorCitpbmxpbmUgY29uc3QgRmlsZURlc2NyaXB0b3IqIEZpbGVEZXNjcmlwdG9yOjpkZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICByZXR1cm4gZGVwZW5kZW5jaWVzX1tpbmRleF07Cit9CisKK2lubGluZSBjb25zdCBGaWxlRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3I6OnB1YmxpY19kZXBlbmRlbmN5KAorICAgIGludCBpbmRleCkgY29uc3QgeworICByZXR1cm4gZGVwZW5kZW5jaWVzX1twdWJsaWNfZGVwZW5kZW5jaWVzX1tpbmRleF1dOworfQorCitpbmxpbmUgY29uc3QgRmlsZURlc2NyaXB0b3IqIEZpbGVEZXNjcmlwdG9yOjp3ZWFrX2RlcGVuZGVuY3koCisgICAgaW50IGluZGV4KSBjb25zdCB7CisgIHJldHVybiBkZXBlbmRlbmNpZXNfW3dlYWtfZGVwZW5kZW5jaWVzX1tpbmRleF1dOworfQorCitpbmxpbmUgRmlsZURlc2NyaXB0b3I6OlN5bnRheCBGaWxlRGVzY3JpcHRvcjo6c3ludGF4KCkgY29uc3QgeworICByZXR1cm4gc3ludGF4XzsKK30KKworLy8gQ2FuJ3QgdXNlIFBST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUiBiZWNhdXNlIGZpZWxkc18gaXMgYWN0dWFsbHkgYW4gYXJyYXkKKy8vIG9mIHBvaW50ZXJzIHJhdGhlciB0aGFuIHRoZSB1c3VhbCBhcnJheSBvZiBvYmplY3RzLgoraW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogT25lb2ZEZXNjcmlwdG9yOjpmaWVsZChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpZWxkc19baW5kZXhdOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTU2MjA2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjCkBAIC0wLDAgKzEsMTMwODAgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvCisKKyNkZWZpbmUgSU5URVJOQUxfU1VQUFJFU1NfUFJPVE9CVUZfRklFTERfREVQUkVDQVRJT04KKyNpbmNsdWRlICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oIgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEZpbGVEZXNjcmlwdG9yU2V0X2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBGaWxlRGVzY3JpcHRvclNldF9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEZpbGVEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEZpbGVEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBFbnVtRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBFbnVtRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogTWV0aG9kRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBNZXRob2REZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWxlT3B0aW9uc19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRmlsZU9wdGlvbnNfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIE1lc3NhZ2VPcHRpb25zX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmllbGRPcHRpb25zX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBGaWVsZE9wdGlvbnNfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bU9wdGlvbnNfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEVudW1PcHRpb25zX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRW51bVZhbHVlT3B0aW9uc19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTZXJ2aWNlT3B0aW9uc19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1ldGhvZE9wdGlvbnNfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIE1ldGhvZE9wdGlvbnNfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBVbmludGVycHJldGVkT3B0aW9uX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBVbmludGVycHJldGVkT3B0aW9uX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNvdXJjZUNvZGVJbmZvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTb3VyY2VDb2RlSW5mb19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9yZWZsZWN0aW9uXyA9IE5VTEw7CisKK30gIC8vIG5hbWVzcGFjZQorCisKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpIHsKKyAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLT5GaW5kRmlsZUJ5TmFtZSgKKyAgICAgICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIpOworICBHT09HTEVfQ0hFQ0soZmlsZSAhPSBOVUxMKTsKKyAgRmlsZURlc2NyaXB0b3JTZXRfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JTZXRfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclNldCwgZmlsZV8pLAorICB9OworICBGaWxlRGVzY3JpcHRvclNldF9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRmlsZURlc2NyaXB0b3JTZXRfZGVzY3JpcHRvcl8sCisgICAgICBGaWxlRGVzY3JpcHRvclNldDo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBGaWxlRGVzY3JpcHRvclNldF9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JTZXQsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihGaWxlRGVzY3JpcHRvclNldCksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yU2V0LCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgxKTsKKyAgc3RhdGljIGNvbnN0IGludCBGaWxlRGVzY3JpcHRvclByb3RvX29mZnNldHNfWzEyXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIHBhY2thZ2VfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIGRlcGVuZGVuY3lfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIHB1YmxpY19kZXBlbmRlbmN5XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCB3ZWFrX2RlcGVuZGVuY3lfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIG1lc3NhZ2VfdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JQcm90bywgZW51bV90eXBlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBzZXJ2aWNlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBleHRlbnNpb25fKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIG9wdGlvbnNfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIHNvdXJjZV9jb2RlX2luZm9fKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIHN5bnRheF8pLAorICB9OworICBGaWxlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLAorICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRmlsZURlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMik7CisgIHN0YXRpYyBjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvX29mZnNldHNfWzhdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIGZpZWxkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIGV4dGVuc2lvbl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvLCBuZXN0ZWRfdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvLCBlbnVtX3R5cGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgZXh0ZW5zaW9uX3JhbmdlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIG9uZW9mX2RlY2xfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgb3B0aW9uc18pLAorICB9OworICBEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBEZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKERlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9kZXNjcmlwdG9yXyA9IERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX29mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlLCBzdGFydF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlLCBlbmRfKSwKKyAgfTsKKyAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZGVzY3JpcHRvcl8sCisgICAgICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBGaWVsZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgzKTsKKyAgc3RhdGljIGNvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90b19vZmZzZXRzX1s5XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgbnVtYmVyXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgbGFiZWxfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkRGVzY3JpcHRvclByb3RvLCB0eXBlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgdHlwZV9uYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgZXh0ZW5kZWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkRGVzY3JpcHRvclByb3RvLCBkZWZhdWx0X3ZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgb25lb2ZfaW5kZXhfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkRGVzY3JpcHRvclByb3RvLCBvcHRpb25zXyksCisgIH07CisgIEZpZWxkRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBGaWVsZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEZpZWxkRGVzY3JpcHRvclByb3RvKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX2Rlc2NyaXB0b3JfID0gRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgwKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfZGVzY3JpcHRvcl8gPSBGaWVsZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXy0+ZW51bV90eXBlKDEpOworICBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg0KTsKKyAgc3RhdGljIGNvbnN0IGludCBPbmVvZkRlc2NyaXB0b3JQcm90b19vZmZzZXRzX1sxXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE9uZW9mRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgIH07CisgIE9uZW9mRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIE9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIE9uZW9mRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChPbmVvZkRlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKE9uZW9mRGVzY3JpcHRvclByb3RvKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoT25lb2ZEZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBFbnVtRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDUpOworICBzdGF0aWMgY29uc3QgaW50IEVudW1EZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c19bM10gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtRGVzY3JpcHRvclByb3RvLCB2YWx1ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bURlc2NyaXB0b3JQcm90bywgb3B0aW9uc18pLAorICB9OworICBFbnVtRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBFbnVtRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLAorICAgICAgRW51bURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBFbnVtRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtRGVzY3JpcHRvclByb3RvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRW51bURlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1EZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoNik7CisgIHN0YXRpYyBjb25zdCBpbnQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX29mZnNldHNfWzNdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8sIG51bWJlcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLCBvcHRpb25zXyksCisgIH07CisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLAorICAgICAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgU2VydmljZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg3KTsKKyAgc3RhdGljIGNvbnN0IGludCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX29mZnNldHNfWzNdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU2VydmljZURlc2NyaXB0b3JQcm90bywgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU2VydmljZURlc2NyaXB0b3JQcm90bywgbWV0aG9kXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTZXJ2aWNlRGVzY3JpcHRvclByb3RvLCBvcHRpb25zXyksCisgIH07CisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sCisgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihTZXJ2aWNlRGVzY3JpcHRvclByb3RvKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU2VydmljZURlc2NyaXB0b3JQcm90bywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIE1ldGhvZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg4KTsKKyAgc3RhdGljIGNvbnN0IGludCBNZXRob2REZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c19bNl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2REZXNjcmlwdG9yUHJvdG8sIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZERlc2NyaXB0b3JQcm90bywgaW5wdXRfdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kRGVzY3JpcHRvclByb3RvLCBvdXRwdXRfdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kRGVzY3JpcHRvclByb3RvLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2REZXNjcmlwdG9yUHJvdG8sIGNsaWVudF9zdHJlYW1pbmdfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZERlc2NyaXB0b3JQcm90bywgc2VydmVyX3N0cmVhbWluZ18pLAorICB9OworICBNZXRob2REZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIE1ldGhvZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZERlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKE1ldGhvZERlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZERlc2NyaXB0b3JQcm90bywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIEZpbGVPcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDkpOworICBzdGF0aWMgY29uc3QgaW50IEZpbGVPcHRpb25zX29mZnNldHNfWzE0XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhX3BhY2thZ2VfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhX291dGVyX2NsYXNzbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIGphdmFfbXVsdGlwbGVfZmlsZXNfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBvcHRpbWl6ZV9mb3JfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBnb19wYWNrYWdlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgY2NfZ2VuZXJpY19zZXJ2aWNlc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIGphdmFfZ2VuZXJpY19zZXJ2aWNlc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIHB5X2dlbmVyaWNfc2VydmljZXNfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBkZXByZWNhdGVkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgY2NfZW5hYmxlX2FyZW5hc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIG9iamNfY2xhc3NfcHJlZml4XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fKSwKKyAgfTsKKyAgRmlsZU9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEZpbGVPcHRpb25zX2Rlc2NyaXB0b3JfLAorICAgICAgRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRmlsZU9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgX2V4dGVuc2lvbnNfKSwKKyAgICAgIHNpemVvZihGaWxlT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3JfID0gRmlsZU9wdGlvbnNfZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgwKTsKKyAgTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMTApOworICBzdGF0aWMgY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zX29mZnNldHNfWzVdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXNzYWdlT3B0aW9ucywgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1lc3NhZ2VPcHRpb25zLCBtYXBfZW50cnlfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1lc3NhZ2VPcHRpb25zLCB1bmludGVycHJldGVkX29wdGlvbl8pLAorICB9OworICBNZXNzYWdlT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl8sCisgICAgICBNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBNZXNzYWdlT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1lc3NhZ2VPcHRpb25zLCBfZXh0ZW5zaW9uc18pLAorICAgICAgc2l6ZW9mKE1lc3NhZ2VPcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBGaWVsZE9wdGlvbnNfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMTEpOworICBzdGF0aWMgY29uc3QgaW50IEZpZWxkT3B0aW9uc19vZmZzZXRzX1s2XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgY3R5cGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgcGFja2VkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE9wdGlvbnMsIGxhenlfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgZGVwcmVjYXRlZF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGRPcHRpb25zLCB3ZWFrXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE9wdGlvbnMsIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXyksCisgIH07CisgIEZpZWxkT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRmllbGRPcHRpb25zX2Rlc2NyaXB0b3JfLAorICAgICAgRmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEZpZWxkT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGRPcHRpb25zLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE9wdGlvbnMsIF9leHRlbnNpb25zXyksCisgICAgICBzaXplb2YoRmllbGRPcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGRPcHRpb25zLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3JfID0gRmllbGRPcHRpb25zX2Rlc2NyaXB0b3JfLT5lbnVtX3R5cGUoMCk7CisgIEVudW1PcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDEyKTsKKyAgc3RhdGljIGNvbnN0IGludCBFbnVtT3B0aW9uc19vZmZzZXRzX1szXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1PcHRpb25zLCBhbGxvd19hbGlhc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bU9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1PcHRpb25zLCB1bmludGVycHJldGVkX29wdGlvbl8pLAorICB9OworICBFbnVtT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW51bU9wdGlvbnNfZGVzY3JpcHRvcl8sCisgICAgICBFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBFbnVtT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bU9wdGlvbnMsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1PcHRpb25zLCBfZXh0ZW5zaW9uc18pLAorICAgICAgc2l6ZW9mKEVudW1PcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bU9wdGlvbnMsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBFbnVtVmFsdWVPcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDEzKTsKKyAgc3RhdGljIGNvbnN0IGludCBFbnVtVmFsdWVPcHRpb25zX29mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgZGVwcmVjYXRlZF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fKSwKKyAgfTsKKyAgRW51bVZhbHVlT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXywKKyAgICAgIEVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRW51bVZhbHVlT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgX2V4dGVuc2lvbnNfKSwKKyAgICAgIHNpemVvZihFbnVtVmFsdWVPcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDE0KTsKKyAgc3RhdGljIGNvbnN0IGludCBTZXJ2aWNlT3B0aW9uc19vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VPcHRpb25zLCBkZXByZWNhdGVkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTZXJ2aWNlT3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fKSwKKyAgfTsKKyAgU2VydmljZU9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfLAorICAgICAgU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgU2VydmljZU9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VPcHRpb25zLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTZXJ2aWNlT3B0aW9ucywgX2V4dGVuc2lvbnNfKSwKKyAgICAgIHNpemVvZihTZXJ2aWNlT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VPcHRpb25zLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgxNSk7CisgIHN0YXRpYyBjb25zdCBpbnQgTWV0aG9kT3B0aW9uc19vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXyksCisgIH07CisgIE1ldGhvZE9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIE1ldGhvZE9wdGlvbnNfZGVzY3JpcHRvcl8sCisgICAgICBNZXRob2RPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIE1ldGhvZE9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIF9leHRlbnNpb25zXyksCisgICAgICBzaXplb2YoTWV0aG9kT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBVbmludGVycHJldGVkT3B0aW9uX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDE2KTsKKyAgc3RhdGljIGNvbnN0IGludCBVbmludGVycHJldGVkT3B0aW9uX29mZnNldHNfWzddID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgaWRlbnRpZmllcl92YWx1ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgcG9zaXRpdmVfaW50X3ZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uLCBuZWdhdGl2ZV9pbnRfdmFsdWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVuaW50ZXJwcmV0ZWRPcHRpb24sIGRvdWJsZV92YWx1ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgc3RyaW5nX3ZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uLCBhZ2dyZWdhdGVfdmFsdWVfKSwKKyAgfTsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9kZXNjcmlwdG9yXywKKyAgICAgIFVuaW50ZXJwcmV0ZWRPcHRpb246OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKFVuaW50ZXJwcmV0ZWRPcHRpb24pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXyA9IFVuaW50ZXJwcmV0ZWRPcHRpb25fZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnRfb2Zmc2V0c19bMl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0LCBuYW1lX3BhcnRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQsIGlzX2V4dGVuc2lvbl8pLAorICB9OworICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X2Rlc2NyaXB0b3JfLAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0LCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBTb3VyY2VDb2RlSW5mb19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgxNyk7CisgIHN0YXRpYyBjb25zdCBpbnQgU291cmNlQ29kZUluZm9fb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mbywgbG9jYXRpb25fKSwKKyAgfTsKKyAgU291cmNlQ29kZUluZm9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFNvdXJjZUNvZGVJbmZvX2Rlc2NyaXB0b3JfLAorICAgICAgU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgU291cmNlQ29kZUluZm9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvZGVJbmZvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoU291cmNlQ29kZUluZm8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mbywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX2Rlc2NyaXB0b3JfID0gU291cmNlQ29kZUluZm9fZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX29mZnNldHNfWzVdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29kZUluZm9fTG9jYXRpb24sIHBhdGhfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uLCBzcGFuXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiwgbGVhZGluZ19jb21tZW50c18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29kZUluZm9fTG9jYXRpb24sIHRyYWlsaW5nX2NvbW1lbnRzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiwgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18pLAorICB9OworICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgU291cmNlQ29kZUluZm9fTG9jYXRpb25fZGVzY3JpcHRvcl8sCisgICAgICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29kZUluZm9fTG9jYXRpb24sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKK30KKworbmFtZXNwYWNlIHsKKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXyk7CitpbmxpbmUgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJnByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfLAorICAgICAgICAgICAgICAgICAmcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90byk7Cit9CisKK3ZvaWQgcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyhjb25zdCA6OnN0ZDo6c3RyaW5nJikgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBGaWxlRGVzY3JpcHRvclNldF9kZXNjcmlwdG9yXywgJkZpbGVEZXNjcmlwdG9yU2V0OjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywgJkRlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZGVzY3JpcHRvcl8sICZEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZGaWVsZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywgJk9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEVudW1EZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZFbnVtRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywgJkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLCAmU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmlsZU9wdGlvbnNfZGVzY3JpcHRvcl8sICZGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBNZXNzYWdlT3B0aW9uc19kZXNjcmlwdG9yXywgJk1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXywgJkZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBFbnVtT3B0aW9uc19kZXNjcmlwdG9yXywgJkVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEVudW1WYWx1ZU9wdGlvbnNfZGVzY3JpcHRvcl8sICZFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfLCAmU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXywgJk1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9kZXNjcmlwdG9yXywgJlVuaW50ZXJwcmV0ZWRPcHRpb246OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXywgJlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgU291cmNlQ29kZUluZm9fZGVzY3JpcHRvcl8sICZTb3VyY2VDb2RlSW5mbzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9kZXNjcmlwdG9yXywgJlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKSB7CisgIGRlbGV0ZSBGaWxlRGVzY3JpcHRvclNldDo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBGaWxlRGVzY3JpcHRvclNldF9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRmlsZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX3JlZmxlY3Rpb25fOworICBkZWxldGUgRmllbGREZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRmllbGREZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBPbmVvZkRlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBPbmVvZkRlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEVudW1EZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRW51bURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgTWV0aG9kRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICBkZWxldGUgRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRmlsZU9wdGlvbnNfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBNZXNzYWdlT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBGaWVsZE9wdGlvbnNfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBFbnVtT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRW51bVZhbHVlT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIFNlcnZpY2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIFNlcnZpY2VPcHRpb25zX3JlZmxlY3Rpb25fOworICBkZWxldGUgTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBNZXRob2RPcHRpb25zX3JlZmxlY3Rpb25fOworICBkZWxldGUgVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBVbmludGVycHJldGVkT3B0aW9uX3JlZmxlY3Rpb25fOworICBkZWxldGUgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X3JlZmxlY3Rpb25fOworICBkZWxldGUgU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgU291cmNlQ29kZUluZm9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9yZWZsZWN0aW9uXzsKK30KKwordm9pZCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcbiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wwMjJcMDE3Z29vZyIKKyAgICAibGUucHJvdG9idWZcIkdcblwwMjFGaWxlRGVzY3JpcHRvclNldFwwMjIyXG5cMDA0ZmlsZSIKKyAgICAiXDAzMFwwMDEgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUCIKKyAgICAicm90b1wiXDMzM1wwMDNcblwwMjNGaWxlRGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMSIKKyAgICAiKFx0XDAyMlwwMTdcblwwMDdwYWNrYWdlXDAzMFwwMDIgXDAwMShcdFwwMjJcMDIyXG5cbmRlcGVuZGVuY3lcMDMwXDAwMyBcMDAzKFx0XDAyMiIKKyAgICAiXDAzMVxuXDAyMXB1YmxpY19kZXBlbmRlbmN5XDAzMFxuIFwwMDMoXDAwNVwwMjJcMDI3XG5cMDE3d2Vha19kZXBlbiIKKyAgICAiZGVuY3lcMDMwXDAxMyBcMDAzKFwwMDVcMDIyNlxuXDAxNG1lc3NhZ2VfdHlwZVwwMzBcMDA0IFwwMDMoXDAxMzIgLmdvb2ciCisgICAgImxlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b1wwMjI3XG5cdGVudW1fdHlwZSIKKyAgICAiXDAzMFwwMDUgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUCIKKyAgICAicm90b1wwMjI4XG5cMDA3c2VydmljZVwwMzBcMDA2IFwwMDMoXDAxMzJcJy5nb29nbGUucHJvdG9idWYuIgorICAgICJTZXJ2aWNlRGVzY3JpcHRvclByb3RvXDAyMjhcblx0ZXh0ZW5zaW9uXDAzMFwwMDcgXDAwMygiCisgICAgIlwwMTMyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8iCisgICAgIlwwMjItXG5cMDA3b3B0aW9uc1wwMzBcMDEwIFwwMDEoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5GaWxlIgorICAgICJPcHRpb25zXDAyMjlcblwwMjBzb3VyY2VfY29kZV9pbmZvXDAzMFx0IFwwMDEoXDAxMzJcMDM3Lmdvb2ciCisgICAgImxlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvXDAyMlwwMTZcblwwMDZzeW50YXhcMDMwXDAxNCBcMDAxIgorICAgICIoXHRcIlwzNDRcMDAzXG5cMDE3RGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjI0XG5cMDA1IgorICAgICJmaWVsZFwwMzBcMDAyIFwwMDMoXDAxMzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyIgorICAgICJpcHRvclByb3RvXDAyMjhcblx0ZXh0ZW5zaW9uXDAzMFwwMDYgXDAwMyhcMDEzMiUuZ29vZ2xlLnAiCisgICAgInJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9cMDIyNVxuXDAxM25lc3RlZF90IgorICAgICJ5cGVcMDMwXDAwMyBcMDAzKFwwMTMyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByIgorICAgICJvdG9cMDIyN1xuXHRlbnVtX3R5cGVcMDMwXDAwNCBcMDAzKFwwMTMyJC5nb29nbGUucHJvdG9idWYiCisgICAgIi5FbnVtRGVzY3JpcHRvclByb3RvXDAyMkhcblwwMTdleHRlbnNpb25fcmFuZ2VcMDMwIgorICAgICJcMDA1IFwwMDMoXDAxMzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uIgorICAgICJFeHRlbnNpb25SYW5nZVwwMjI5XG5cbm9uZW9mX2RlY2xcMDMwXDAxMCBcMDAzKFwwMTMyJS5nb28iCisgICAgImdsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90b1wwMjIwXG5cMDA3b3B0IgorICAgICJpb25zXDAzMFwwMDcgXDAwMShcMDEzMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpIgorICAgICJvbnNcMDMyLFxuXDAxNkV4dGVuc2lvblJhbmdlXDAyMlxyXG5cMDA1c3RhcnRcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXDAxM1xuXDAwMyIKKyAgICAiZW5kXDAzMFwwMDIgXDAwMShcMDA1XCJcMjUxXDAwNVxuXDAyNEZpZWxkRGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYSIKKyAgICAibWVcMDMwXDAwMSBcMDAxKFx0XDAyMlwwMTZcblwwMDZudW1iZXJcMDMwXDAwMyBcMDAxKFwwMDVcMDIyOlxuXDAwNWxhYmVsXDAzMFwwMDQgXDAwMShcMDE2MiIKKyAgICAiKy5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTCIKKyAgICAiYWJlbFwwMjI4XG5cMDA0dHlwZVwwMzBcMDA1IFwwMDEoXDAxNjIqLmdvb2dsZS5wcm90b2J1Zi5GaWUiCisgICAgImxkRGVzY3JpcHRvclByb3RvLlR5cGVcMDIyXDAyMVxuXHR0eXBlX25hbWVcMDMwXDAwNiBcMDAxKCIKKyAgICAiXHRcMDIyXDAyMFxuXDAxMGV4dGVuZGVlXDAzMFwwMDIgXDAwMShcdFwwMjJcMDI1XG5ccmRlZmF1bHRfdmFsdWVcMDMwXDAwNyBcMDAxIgorICAgICIoXHRcMDIyXDAyM1xuXDAxM29uZW9mX2luZGV4XDAzMFx0IFwwMDEoXDAwNVwwMjIuXG5cMDA3b3B0aW9uc1wwMzBcMDEwIFwwMDEoXDAxMyIKKyAgICAiMlwwMzUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1wiXDI2NlwwMDJcblwwMDRUeXBlIgorICAgICJcMDIyXDAxN1xuXDAxM1RZUEVfRE9VQkxFXDAyMFwwMDFcMDIyXDAxNlxuXG5UWVBFX0ZMT0FUXDAyMFwwMDJcMDIyXDAxNlxuXG5UWVAiCisgICAgIkVfSU5UNjRcMDIwXDAwM1wwMjJcMDE3XG5cMDEzVFlQRV9VSU5UNjRcMDIwXDAwNFwwMjJcMDE2XG5cblRZUEVfSU5UMzIiCisgICAgIlwwMjBcMDA1XDAyMlwwMjBcblwwMTRUWVBFX0ZJWEVENjRcMDIwXDAwNlwwMjJcMDIwXG5cMDE0VFlQRV9GSVhFRDMyXDAyMFwwMDdcMDIyXHIiCisgICAgIlxuXHRUWVBFX0JPT0xcMDIwXDAxMFwwMjJcMDE3XG5cMDEzVFlQRV9TVFJJTkdcMDIwXHRcMDIyXDAxNlxuXG5UWVBFX0ciCisgICAgIlJPVVBcMDIwXG5cMDIyXDAyMFxuXDAxNFRZUEVfTUVTU0FHRVwwMjBcMDEzXDAyMlwwMTZcblxuVFlQRV9CWVRFU1wwMjBcMDE0IgorICAgICJcMDIyXDAxN1xuXDAxM1RZUEVfVUlOVDMyXDAyMFxyXDAyMlxyXG5cdFRZUEVfRU5VTVwwMjBcMDE2XDAyMlwwMjFcblxyVFlQRSIKKyAgICAiX1NGSVhFRDMyXDAyMFwwMTdcMDIyXDAyMVxuXHJUWVBFX1NGSVhFRDY0XDAyMFwwMjBcMDIyXDAxN1xuXDAxM1RZUEVfUyIKKyAgICAiSU5UMzJcMDIwXDAyMVwwMjJcMDE3XG5cMDEzVFlQRV9TSU5UNjRcMDIwXDAyMlwiQ1xuXDAwNUxhYmVsXDAyMlwwMjJcblwwMTZMQUIiCisgICAgIkVMX09QVElPTkFMXDAyMFwwMDFcMDIyXDAyMlxuXDAxNkxBQkVMX1JFUVVJUkVEXDAyMFwwMDJcMDIyXDAyMlxuXDAxNkxBQiIKKyAgICAiRUxfUkVQRUFURURcMDIwXDAwM1wiJFxuXDAyNE9uZW9mRGVzY3JpcHRvclByb3RvXDAyMlwwMTRcbiIKKyAgICAiXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0XCJcMjE0XDAwMVxuXDAyM0VudW1EZXNjcmlwdG9yUHJvdG9cMDIyXDAxNFxuXDAwNG4iCisgICAgImFtZVwwMzBcMDAxIFwwMDEoXHRcMDIyOFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMyhcMDEzMikuZ29vZ2xlLnByb3RvYiIKKyAgICAidWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvXDAyMi1cblwwMDdvcHRpb25zXDAzMFwwMDMiCisgICAgIiBcMDAxKFwwMTMyXDAzNC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnNcImxcblwwMzBFbiIKKyAgICAidW1WYWx1ZURlc2NyaXB0b3JQcm90b1wwMjJcMDE0XG5cMDA0bmFtZVwwMzBcMDAxIFwwMDEoXHRcMDIyXDAxNlxuXDAwNiIKKyAgICAibnVtYmVyXDAzMFwwMDIgXDAwMShcMDA1XDAyMjJcblwwMDdvcHRpb25zXDAzMFwwMDMgXDAwMShcMDEzMiEuZ29vZ2xlLnAiCisgICAgInJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1wiXDIyMFwwMDFcblwwMjZTZXJ2aWNlRGVzYyIKKyAgICAicmlwdG9yUHJvdG9cMDIyXDAxNFxuXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0XDAyMjZcblwwMDZtZXRob2RcMDMwXDAwMiBcMDAzKCIKKyAgICAiXDAxMzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdCIKKyAgICAib1wwMjIwXG5cMDA3b3B0aW9uc1wwMzBcMDAzIFwwMDEoXDAxMzJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5TZXIiCisgICAgInZpY2VPcHRpb25zXCJcMzAxXDAwMVxuXDAyNU1ldGhvZERlc2NyaXB0b3JQcm90b1wwMjJcMDE0XG4iCisgICAgIlwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjJcMDIyXG5cbmlucHV0X3R5cGVcMDMwXDAwMiBcMDAxKFx0XDAyMlwwMjNcblwwMTNvdXRwdSIKKyAgICAidF90eXBlXDAzMFwwMDMgXDAwMShcdFwwMjIvXG5cMDA3b3B0aW9uc1wwMzBcMDA0IFwwMDEoXDAxMzJcMDM2Lmdvb2dsZS5wIgorICAgICJyb3RvYnVmLk1ldGhvZE9wdGlvbnNcMDIyXDAzN1xuXDAyMGNsaWVudF9zdHJlYW1pbiIKKyAgICAiZ1wwMzBcMDA1IFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyXDAzN1xuXDAyMHNlcnZlcl9zdHJlYW1pbmdcMDMwXDAwNiBcMDAxKFwwMTAiCisgICAgIjpcMDA1ZmFsc2VcIlwzNDdcMDA0XG5cMDEzRmlsZU9wdGlvbnNcMDIyXDAyNFxuXDAxNGphdmFfcGFja2FnZVwwMzAiCisgICAgIlwwMDEgXDAwMShcdFwwMjJcMDM0XG5cMDI0amF2YV9vdXRlcl9jbGFzc25hbWVcMDMwXDAxMCBcMDAxKFx0XDAyMlwiXG5cMDIzaiIKKyAgICAiYXZhX211bHRpcGxlX2ZpbGVzXDAzMFxuIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyLFxuXDAzNWphdmFfIgorICAgICJnZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2hcMDMwXDAyNCBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMiVcbiIKKyAgICAiXDAyNmphdmFfc3RyaW5nX2NoZWNrX3V0ZjhcMDMwXDAzMyBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMkZcblwwMTQiCisgICAgIm9wdGltaXplX2ZvclwwMzBcdCBcMDAxKFwwMTYyKS5nb29nbGUucHJvdG9idWYuRmlsIgorICAgICJlT3B0aW9ucy5PcHRpbWl6ZU1vZGU6XDAwNVNQRUVEXDAyMlwwMjJcblxuZ29fcGFja2EiCisgICAgImdlXDAzMFwwMTMgXDAwMShcdFwwMjJcIlxuXDAyM2NjX2dlbmVyaWNfc2VydmljZXNcMDMwXDAyMCBcMDAxKFwwMTA6XDAwNWYiCisgICAgImFsc2VcMDIyJFxuXDAyNWphdmFfZ2VuZXJpY19zZXJ2aWNlc1wwMzBcMDIxIFwwMDEoXDAxMDpcMDA1ZmFsIgorICAgICJzZVwwMjJcIlxuXDAyM3B5X2dlbmVyaWNfc2VydmljZXNcMDMwXDAyMiBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMlwwMzEiCisgICAgIlxuXG5kZXByZWNhdGVkXDAzMFwwMjcgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJcMDM3XG5cMDIwY2NfZW5hYmxlX2EiCisgICAgInJlbmFzXDAzMFwwMzcgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJcMDMxXG5cMDIxb2JqY19jbGFzc19wcmVmaXhcMDMwIgorICAgICIkIFwwMDEoXHRcMDIyQ1xuXDAyNHVuaW50ZXJwcmV0ZWRfb3B0aW9uXDAzMFwzNDdcMDA3IFwwMDMoXDAxMzIkLmciCisgICAgIm9vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25cIjpcblwwMTRPcCIKKyAgICAidGltaXplTW9kZVwwMjJcdFxuXDAwNVNQRUVEXDAyMFwwMDFcMDIyXHJcblx0Q09ERV9TSVpFXDAyMFwwMDJcMDIyXDAyMFxuXDAxNCIKKyAgICAiTElURV9SVU5USU1FXDAyMFwwMDMqXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIlwzNDZcMDAxXG5cMDE2TWVzc2FnZU9wdCIKKyAgICAiaW9uc1wwMjImXG5cMDI3bWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRcMDMwXDAwMSBcMDAxKFwwMTA6XDAwNWYiCisgICAgImFsc2VcMDIyLlxuXDAzN25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JcMDMwIgorICAgICJcMDAyIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyXDAzMVxuXG5kZXByZWNhdGVkXDAzMFwwMDMgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjIiCisgICAgIlwwMjFcblx0bWFwX2VudHJ5XDAzMFwwMDcgXDAwMShcMDEwXDAyMkNcblwwMjR1bmludGVycHJldGVkX29wdGkiCisgICAgIm9uXDAzMFwzNDdcMDA3IFwwMDMoXDAxMzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGUiCisgICAgImRPcHRpb24qXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIlwyNDBcMDAyXG5cMDE0RmllbGRPcHRpb25zXDAyMjpcblwwMDVjIgorICAgICJ0eXBlXDAzMFwwMDEgXDAwMShcMDE2MiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uIgorICAgICJzLkNUeXBlOlwwMDZTVFJJTkdcMDIyXDAxNlxuXDAwNnBhY2tlZFwwMzBcMDAyIFwwMDEoXDAxMFwwMjJcMDIzXG5cMDA0bGF6eVwwMzAiCisgICAgIlwwMDUgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJcMDMxXG5cbmRlcHJlY2F0ZWRcMDMwXDAwMyBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMiIKKyAgICAiXDAyM1xuXDAwNHdlYWtcMDMwXG4gXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJDXG5cMDI0dW5pbnRlcnByZXRlZF9vcCIKKyAgICAidGlvblwwMzBcMzQ3XDAwNyBcMDAzKFwwMTMyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZSIKKyAgICAidGVkT3B0aW9uXCIvXG5cMDA1Q1R5cGVcMDIyXG5cblwwMDZTVFJJTkdcMDIwXDAwMFwwMjJcMDEwXG5cMDA0Q09SRFwwMjBcMDAxIgorICAgICJcMDIyXDAyMFxuXDAxNFNUUklOR19QSUVDRVwwMjBcMDAyKlx0XDAxMFwzNTBcMDA3XDAyMFwyMDBcMjAwXDIwMFwyMDBcMDAyXCJcMjE1XDAwMVxuXDAxM0VudW1PcCIKKyAgICAidGlvbnNcMDIyXDAyM1xuXDAxM2FsbG93X2FsaWFzXDAzMFwwMDIgXDAwMShcMDEwXDAyMlwwMzFcblxuZGVwcmVjYXRlZCIKKyAgICAiXDAzMFwwMDMgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJDXG5cMDI0dW5pbnRlcnByZXRlZF9vcHRpb25cMDMwXDM0N1wwMDciCisgICAgIiBcMDAzKFwwMTMyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGkiCisgICAgIm9uKlx0XDAxMFwzNTBcMDA3XDAyMFwyMDBcMjAwXDIwMFwyMDBcMDAyXCJ9XG5cMDIwRW51bVZhbHVlT3B0aW9uc1wwMjJcMDMxXG5cbmRlcCIKKyAgICAicmVjYXRlZFwwMzBcMDAxIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyQ1xuXDAyNHVuaW50ZXJwcmV0ZWRfb3AiCisgICAgInRpb25cMDMwXDM0N1wwMDcgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmUiCisgICAgInRlZE9wdGlvbipcdFwwMTBcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwie1xuXDAxNlNlcnZpY2VPcHRpb25zXDAyMlwwMzEiCisgICAgIlxuXG5kZXByZWNhdGVkXDAzMCEgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJDXG5cMDI0dW5pbnRlcnByZXQiCisgICAgImVkX29wdGlvblwwMzBcMzQ3XDAwNyBcMDAzKFwwMTMyJC5nb29nbGUucHJvdG9idWYuVW5pbnQiCisgICAgImVycHJldGVkT3B0aW9uKlx0XDAxMFwzNTBcMDA3XDAyMFwyMDBcMjAwXDIwMFwyMDBcMDAyXCJ6XG5cck1ldGhvZE9wdGlvIgorICAgICJuc1wwMjJcMDMxXG5cbmRlcHJlY2F0ZWRcMDMwISBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMkNcblwwMjR1bmludGVyIgorICAgICJwcmV0ZWRfb3B0aW9uXDAzMFwzNDdcMDA3IFwwMDMoXDAxMzIkLmdvb2dsZS5wcm90b2J1Zi5VIgorICAgICJuaW50ZXJwcmV0ZWRPcHRpb24qXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIlwyMzZcMDAyXG5cMDIzVW5pbnRlIgorICAgICJycHJldGVkT3B0aW9uXDAyMjtcblwwMDRuYW1lXDAzMFwwMDIgXDAwMyhcMDEzMi0uZ29vZ2xlLnBybyIKKyAgICAidG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydFwwMjJcMDMwXG5cMDIwaWQiCisgICAgImVudGlmaWVyX3ZhbHVlXDAzMFwwMDMgXDAwMShcdFwwMjJcMDMyXG5cMDIycG9zaXRpdmVfaW50X3ZhbCIKKyAgICAidWVcMDMwXDAwNCBcMDAxKFwwMDRcMDIyXDAzMlxuXDAyMm5lZ2F0aXZlX2ludF92YWx1ZVwwMzBcMDA1IFwwMDEoXDAwM1wwMjJcMDI0XG5cMDE0IgorICAgICJkb3VibGVfdmFsdWVcMDMwXDAwNiBcMDAxKFwwMDFcMDIyXDAyNFxuXDAxNHN0cmluZ192YWx1ZVwwMzBcMDA3IFwwMDEoXDAxNCIKKyAgICAiXDAyMlwwMjdcblwwMTdhZ2dyZWdhdGVfdmFsdWVcMDMwXDAxMCBcMDAxKFx0XDAzMjNcblwwMTBOYW1lUGFydFwwMjJcMDIxXG4iCisgICAgIlx0bmFtZV9wYXJ0XDAzMFwwMDEgXDAwMihcdFwwMjJcMDI0XG5cMDE0aXNfZXh0ZW5zaW9uXDAzMFwwMDIgXDAwMihcMDEwXCJcMzI1IgorICAgICJcMDAxXG5cMDE2U291cmNlQ29kZUluZm9cMDIyOlxuXDAxMGxvY2F0aW9uXDAzMFwwMDEgXDAwMyhcMDEzMiguZ28iCisgICAgIm9nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25cMDMyXDIwNlwwMDEiCisgICAgIlxuXDAxMExvY2F0aW9uXDAyMlwwMjBcblwwMDRwYXRoXDAzMFwwMDEgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjJcMDIwXG5cMDA0c3BhblwwMzBcMDAyIFwwMDMiCisgICAgIihcMDA1QlwwMDJcMDIwXDAwMVwwMjJcMDMwXG5cMDIwbGVhZGluZ19jb21tZW50c1wwMzBcMDAzIFwwMDEoXHRcMDIyXDAzMVxuXDAyMXRyYWkiCisgICAgImxpbmdfY29tbWVudHNcMDMwXDAwNCBcMDAxKFx0XDAyMiFcblwwMzFsZWFkaW5nX2RldGFjaGVkXyIKKyAgICAiY29tbWVudHNcMDMwXDAwNiBcMDAzKFx0QilcblwwMjNjb20uZ29vZ2xlLnByb3RvYnVmQlwwMjBEIgorICAgICJlc2NyaXB0b3JQcm90b3NIXDAwMSIsIDQ2MTcpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkRmlsZSgKKyAgICAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIEZpbGVEZXNjcmlwdG9yU2V0OjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBGaWxlRGVzY3JpcHRvclNldCgpOworICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBGaWxlRGVzY3JpcHRvclByb3RvKCk7CisgIERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRGVzY3JpcHRvclByb3RvKCk7CisgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKCk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBGaWVsZERlc2NyaXB0b3JQcm90bygpOworICBPbmVvZkRlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgT25lb2ZEZXNjcmlwdG9yUHJvdG8oKTsKKyAgRW51bURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRW51bURlc2NyaXB0b3JQcm90bygpOworICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bygpOworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKCk7CisgIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgTWV0aG9kRGVzY3JpcHRvclByb3RvKCk7CisgIEZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBGaWxlT3B0aW9ucygpOworICBNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgTWVzc2FnZU9wdGlvbnMoKTsKKyAgRmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBGaWVsZE9wdGlvbnMoKTsKKyAgRW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEVudW1PcHRpb25zKCk7CisgIEVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEVudW1WYWx1ZU9wdGlvbnMoKTsKKyAgU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IFNlcnZpY2VPcHRpb25zKCk7CisgIE1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IE1ldGhvZE9wdGlvbnMoKTsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgVW5pbnRlcnByZXRlZE9wdGlvbigpOworICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KCk7CisgIFNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBTb3VyY2VDb2RlSW5mbygpOworICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgU291cmNlQ29kZUluZm9fTG9jYXRpb24oKTsKKyAgRmlsZURlc2NyaXB0b3JTZXQ6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIE9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEVudW1EZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIE1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFNlcnZpY2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIE1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJnByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90byB7CisgIFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpIHsKKyAgICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG9fOworCituYW1lc3BhY2UgeworCitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSBHT09HTEVfQVRUUklCVVRFX0NPTEQ7CitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSB7CisgIEdPT0dMRV9DSEVDSyhmYWxzZSkgPDwgX19GSUxFX18gPDwgIjoiIDw8IGxpbmU7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yU2V0OjprRmlsZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworRmlsZURlc2NyaXB0b3JTZXQ6OkZpbGVEZXNjcmlwdG9yU2V0KCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0ZpbGVEZXNjcmlwdG9yU2V0OjpGaWxlRGVzY3JpcHRvclNldChjb25zdCBGaWxlRGVzY3JpcHRvclNldCYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0ZpbGVEZXNjcmlwdG9yU2V0Ojp+RmlsZURlc2NyaXB0b3JTZXQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclNldDo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWxlRGVzY3JpcHRvclNldF9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIEZpbGVEZXNjcmlwdG9yU2V0OjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitGaWxlRGVzY3JpcHRvclNldCogRmlsZURlc2NyaXB0b3JTZXQ6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRmlsZURlc2NyaXB0b3JTZXQqIEZpbGVEZXNjcmlwdG9yU2V0OjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRmlsZURlc2NyaXB0b3JTZXQqIG4gPSBuZXcgRmlsZURlc2NyaXB0b3JTZXQ7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6Q2xlYXIoKSB7CisgIGZpbGVfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIEZpbGVEZXNjcmlwdG9yU2V0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBmaWxlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICBwYXJzZV9maWxlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9maWxlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDEwKSkgZ290byBwYXJzZV9maWxlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQpCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBmaWxlID0gMTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5maWxlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAxLCB0aGlzLT5maWxlKGkpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEZpbGVEZXNjcmlwdG9yU2V0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpbGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+ZmlsZShpKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEZpbGVEZXNjcmlwdG9yU2V0OjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBmaWxlID0gMTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZmlsZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZmlsZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+ZmlsZShpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3JTZXQqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBGaWxlRGVzY3JpcHRvclNldCo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6TWVyZ2VGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yU2V0JiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGZpbGVfLk1lcmdlRnJvbShmcm9tLmZpbGVfKTsKKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OkNvcHlGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yU2V0JiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBGaWxlRGVzY3JpcHRvclNldDo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPmZpbGUoKSkpIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OlN3YXAoRmlsZURlc2NyaXB0b3JTZXQqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpJbnRlcm5hbFN3YXAoRmlsZURlc2NyaXB0b3JTZXQqIG90aGVyKSB7CisgIGZpbGVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmZpbGVfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRmlsZURlc2NyaXB0b3JTZXQ6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEZpbGVEZXNjcmlwdG9yU2V0X2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRmlsZURlc2NyaXB0b3JTZXRfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRmlsZURlc2NyaXB0b3JTZXQKKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworIGludCBGaWxlRGVzY3JpcHRvclNldDo6ZmlsZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZmlsZV8uc2l6ZSgpOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OmNsZWFyX2ZpbGUoKSB7CisgIGZpbGVfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclNldDo6ZmlsZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuIGZpbGVfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclNldDo6bXV0YWJsZV9maWxlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuIGZpbGVfLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JTZXQ6OmFkZF9maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiYKK0ZpbGVEZXNjcmlwdG9yU2V0OjpmaWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuIGZpbGVfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclNldDo6bXV0YWJsZV9maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gJmZpbGVfOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IGludCBGaWxlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtQYWNrYWdlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a0RlcGVuZGVuY3lGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlRGVzY3JpcHRvclByb3RvOjprUHVibGljRGVwZW5kZW5jeUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtXZWFrRGVwZW5kZW5jeUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtNZXNzYWdlVHlwZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtFbnVtVHlwZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtTZXJ2aWNlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvbkZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a1NvdXJjZUNvZGVJbmZvRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a1N5bnRheEZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworRmlsZURlc2NyaXB0b3JQcm90bzo6RmlsZURlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIHNvdXJjZV9jb2RlX2luZm9fID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitGaWxlRGVzY3JpcHRvclByb3RvOjpGaWxlRGVzY3JpcHRvclByb3RvKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBwYWNrYWdlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgc291cmNlX2NvZGVfaW5mb18gPSBOVUxMOworICBzeW50YXhfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRmlsZURlc2NyaXB0b3JQcm90bzo6fkZpbGVEZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcGFja2FnZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgc3ludGF4Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgIGRlbGV0ZSBvcHRpb25zXzsKKyAgICBkZWxldGUgc291cmNlX2NvZGVfaW5mb187CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWxlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitGaWxlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0ZpbGVEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBGaWxlRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IEZpbGVEZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpDbGVhcigpIHsKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDMpIHsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX3BhY2thZ2UoKSkgeworICAgICAgcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgfQorICBpZiAoX2hhc19iaXRzX1s4IC8gMzJdICYgMzU4NCkgeworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnM6OkNsZWFyKCk7CisgICAgfQorICAgIGlmIChoYXNfc291cmNlX2NvZGVfaW5mbygpKSB7CisgICAgICBpZiAoc291cmNlX2NvZGVfaW5mb18gIT0gTlVMTCkgc291cmNlX2NvZGVfaW5mb18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm86OkNsZWFyKCk7CisgICAgfQorICAgIGlmIChoYXNfc3ludGF4KCkpIHsKKyAgICAgIHN5bnRheF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgfQorICBkZXBlbmRlbmN5Xy5DbGVhcigpOworICBwdWJsaWNfZGVwZW5kZW5jeV8uQ2xlYXIoKTsKKyAgd2Vha19kZXBlbmRlbmN5Xy5DbGVhcigpOworICBtZXNzYWdlX3R5cGVfLkNsZWFyKCk7CisgIGVudW1fdHlwZV8uQ2xlYXIoKTsKKyAgc2VydmljZV8uQ2xlYXIoKTsKKyAgZXh0ZW5zaW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfcGFja2FnZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9wYWNrYWdlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9wYWNrYWdlKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnBhY2thZ2UoKS5kYXRhKCksIHRoaXMtPnBhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9kZXBlbmRlbmN5OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgc3RyaW5nIGRlcGVuZGVuY3kgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX2RlcGVuZGVuY3k6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5hZGRfZGVwZW5kZW5jeSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5kZXBlbmRlbmN5KHRoaXMtPmRlcGVuZGVuY3lfc2l6ZSgpIC0gMSkuZGF0YSgpLAorICAgICAgICAgICAgdGhpcy0+ZGVwZW5kZW5jeSh0aGlzLT5kZXBlbmRlbmN5X3NpemUoKSAtIDEpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX2RlcGVuZGVuY3k7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDM0KSkgZ290byBwYXJzZV9tZXNzYWdlX3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBtZXNzYWdlX3R5cGUgPSA0OworICAgICAgY2FzZSA0OiB7CisgICAgICAgIGlmICh0YWcgPT0gMzQpIHsKKyAgICAgICAgIHBhcnNlX21lc3NhZ2VfdHlwZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfbWVzc2FnZV90eXBlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDM0KSkgZ290byBwYXJzZV9tZXNzYWdlX3R5cGU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQyKSkgZ290byBwYXJzZV9lbnVtX3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQyKSB7CisgICAgICAgICBwYXJzZV9lbnVtX3R5cGU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2VudW1fdHlwZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg0MikpIGdvdG8gcGFyc2VfZW51bV90eXBlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2Vfc2VydmljZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byBzZXJ2aWNlID0gNjsKKyAgICAgIGNhc2UgNjogeworICAgICAgICBpZiAodGFnID09IDUwKSB7CisgICAgICAgICBwYXJzZV9zZXJ2aWNlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9zZXJ2aWNlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDUwKSkgZ290byBwYXJzZV9zZXJ2aWNlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1OCkpIGdvdG8gcGFyc2VfZXh0ZW5zaW9uOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA3OworICAgICAgY2FzZSA3OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTgpIHsKKyAgICAgICAgIHBhcnNlX2V4dGVuc2lvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfZXh0ZW5zaW9uKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDU4KSkgZ290byBwYXJzZV9leHRlbnNpb247CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDY2KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgICAgIGNhc2UgODogeworICAgICAgICBpZiAodGFnID09IDY2KSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDc0KSkgZ290byBwYXJzZV9zb3VyY2VfY29kZV9pbmZvOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKKyAgICAgIGNhc2UgOTogeworICAgICAgICBpZiAodGFnID09IDc0KSB7CisgICAgICAgICBwYXJzZV9zb3VyY2VfY29kZV9pbmZvOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9zb3VyY2VfY29kZV9pbmZvKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDgwKSkgZ290byBwYXJzZV9wdWJsaWNfZGVwZW5kZW5jeTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIGludDMyIHB1YmxpY19kZXBlbmRlbmN5ID0gMTA7CisgICAgICBjYXNlIDEwOiB7CisgICAgICAgIGlmICh0YWcgPT0gODApIHsKKyAgICAgICAgIHBhcnNlX3B1YmxpY19kZXBlbmRlbmN5OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRSZXBlYXRlZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIDEsIDgwLCBpbnB1dCwgdGhpcy0+bXV0YWJsZV9wdWJsaWNfZGVwZW5kZW5jeSgpKSkpOworICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSA4MikgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRQcmltaXRpdmVOb0lubGluZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3B1YmxpY19kZXBlbmRlbmN5KCkpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MCkpIGdvdG8gcGFyc2VfcHVibGljX2RlcGVuZGVuY3k7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDg4KSkgZ290byBwYXJzZV93ZWFrX2RlcGVuZGVuY3k7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCBpbnQzMiB3ZWFrX2RlcGVuZGVuY3kgPSAxMTsKKyAgICAgIGNhc2UgMTE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4OCkgeworICAgICAgICAgcGFyc2Vfd2Vha19kZXBlbmRlbmN5OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRSZXBlYXRlZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIDEsIDg4LCBpbnB1dCwgdGhpcy0+bXV0YWJsZV93ZWFrX2RlcGVuZGVuY3koKSkpKTsKKyAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gOTApIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUGFja2VkUHJpbWl0aXZlTm9JbmxpbmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV93ZWFrX2RlcGVuZGVuY3koKSkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDg4KSkgZ290byBwYXJzZV93ZWFrX2RlcGVuZGVuY3k7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDk4KSkgZ290byBwYXJzZV9zeW50YXg7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgc3ludGF4ID0gMTI7CisgICAgICBjYXNlIDEyOiB7CisgICAgICAgIGlmICh0YWcgPT0gOTgpIHsKKyAgICAgICAgIHBhcnNlX3N5bnRheDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfc3ludGF4KCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnN5bnRheCgpLmRhdGEoKSwgdGhpcy0+c3ludGF4KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKKyAgaWYgKGhhc19wYWNrYWdlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPnBhY2thZ2UoKS5kYXRhKCksIHRoaXMtPnBhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wYWNrYWdlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+cGFja2FnZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGRlcGVuZGVuY3kgPSAzOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmRlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgdGhpcy0+ZGVwZW5kZW5jeShpKS5kYXRhKCksIHRoaXMtPmRlcGVuZGVuY3koaSkubGVuZ3RoKCksCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5Iik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nKAorICAgICAgMywgdGhpcy0+ZGVwZW5kZW5jeShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bWVzc2FnZV90eXBlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA0LCB0aGlzLT5tZXNzYWdlX3R5cGUoaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDUsIHRoaXMtPmVudW1fdHlwZShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byBzZXJ2aWNlID0gNjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5zZXJ2aWNlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA2LCB0aGlzLT5zZXJ2aWNlKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA3OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmV4dGVuc2lvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNywgdGhpcy0+ZXh0ZW5zaW9uKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOCwgKnRoaXMtPm9wdGlvbnNfLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKKyAgaWYgKGhhc19zb3VyY2VfY29kZV9pbmZvKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOSwgKnRoaXMtPnNvdXJjZV9jb2RlX2luZm9fLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgcHVibGljX2RlcGVuZGVuY3kgPSAxMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5wdWJsaWNfZGVwZW5kZW5jeV9zaXplKCk7IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKAorICAgICAgMTAsIHRoaXMtPnB1YmxpY19kZXBlbmRlbmN5KGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgd2Vha19kZXBlbmRlbmN5ID0gMTE7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+d2Vha19kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoCisgICAgICAxMSwgdGhpcy0+d2Vha19kZXBlbmRlbmN5KGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICBpZiAoaGFzX3N5bnRheCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5zeW50YXgoKS5kYXRhKCksIHRoaXMtPnN5bnRheCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEyLCB0aGlzLT5zeW50YXgoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEZpbGVEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKKyAgaWYgKGhhc19wYWNrYWdlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPnBhY2thZ2UoKS5kYXRhKCksIHRoaXMtPnBhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wYWNrYWdlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPnBhY2thZ2UoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBkZXBlbmRlbmN5ID0gMzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5kZXBlbmRlbmN5KGkpLmRhdGEoKSwgdGhpcy0+ZGVwZW5kZW5jeShpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5Iik7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVTdHJpbmdUb0FycmF5KDMsIHRoaXMtPmRlcGVuZGVuY3koaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBtZXNzYWdlX3R5cGUgPSA0OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm1lc3NhZ2VfdHlwZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA0LCB0aGlzLT5tZXNzYWdlX3R5cGUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNSwgdGhpcy0+ZW51bV90eXBlKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnNlcnZpY2Vfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNiwgdGhpcy0+c2VydmljZShpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNzsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5leHRlbnNpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNywgdGhpcy0+ZXh0ZW5zaW9uKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA4LCAqdGhpcy0+b3B0aW9uc18sIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvIHNvdXJjZV9jb2RlX2luZm8gPSA5OworICBpZiAoaGFzX3NvdXJjZV9jb2RlX2luZm8oKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDksICp0aGlzLT5zb3VyY2VfY29kZV9pbmZvXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIGludDMyIHB1YmxpY19kZXBlbmRlbmN5ID0gMTA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyVG9BcnJheSgxMCwgdGhpcy0+cHVibGljX2RlcGVuZGVuY3koaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiB3ZWFrX2RlcGVuZGVuY3kgPSAxMTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT53ZWFrX2RlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyVG9BcnJheSgxMSwgdGhpcy0+d2Vha19kZXBlbmRlbmN5KGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICBpZiAoaGFzX3N5bnRheCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5zeW50YXgoKS5kYXRhKCksIHRoaXMtPnN5bnRheCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxMiwgdGhpcy0+c3ludGF4KCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDMpIHsKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHBhY2thZ2UgPSAyOworICAgIGlmIChoYXNfcGFja2FnZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5wYWNrYWdlKCkpOworICAgIH0KKworICB9CisgIGlmIChfaGFzX2JpdHNfWzkgLyAzMl0gJiAzNTg0KSB7CisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKKyAgICBpZiAoaGFzX3NvdXJjZV9jb2RlX2luZm8oKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5zb3VyY2VfY29kZV9pbmZvXyk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICAgIGlmIChoYXNfc3ludGF4KCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPnN5bnRheCgpKTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCBzdHJpbmcgZGVwZW5kZW5jeSA9IDM7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmRlcGVuZGVuY3lfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmRlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgdGhpcy0+ZGVwZW5kZW5jeShpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiBwdWJsaWNfZGVwZW5kZW5jeSA9IDEwOworICB7CisgICAgaW50IGRhdGFfc2l6ZSA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5wdWJsaWNfZGVwZW5kZW5jeV9zaXplKCk7IGkrKykgeworICAgICAgZGF0YV9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgICAgSW50MzJTaXplKHRoaXMtPnB1YmxpY19kZXBlbmRlbmN5KGkpKTsKKyAgICB9CisgICAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+cHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpICsgZGF0YV9zaXplOworICB9CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgd2Vha19kZXBlbmRlbmN5ID0gMTE7CisgIHsKKyAgICBpbnQgZGF0YV9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPndlYWtfZGVwZW5kZW5jeV9zaXplKCk7IGkrKykgeworICAgICAgZGF0YV9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgICAgSW50MzJTaXplKHRoaXMtPndlYWtfZGVwZW5kZW5jeShpKSk7CisgICAgfQorICAgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPndlYWtfZGVwZW5kZW5jeV9zaXplKCkgKyBkYXRhX3NpemU7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBtZXNzYWdlX3R5cGUgPSA0OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5tZXNzYWdlX3R5cGVfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPm1lc3NhZ2VfdHlwZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+bWVzc2FnZV90eXBlKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA1OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmVudW1fdHlwZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+ZW51bV90eXBlKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byBzZXJ2aWNlID0gNjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+c2VydmljZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+c2VydmljZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+c2VydmljZShpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDc7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmV4dGVuc2lvbl9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZXh0ZW5zaW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5leHRlbnNpb24oaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgZGVwZW5kZW5jeV8uTWVyZ2VGcm9tKGZyb20uZGVwZW5kZW5jeV8pOworICBwdWJsaWNfZGVwZW5kZW5jeV8uTWVyZ2VGcm9tKGZyb20ucHVibGljX2RlcGVuZGVuY3lfKTsKKyAgd2Vha19kZXBlbmRlbmN5Xy5NZXJnZUZyb20oZnJvbS53ZWFrX2RlcGVuZGVuY3lfKTsKKyAgbWVzc2FnZV90eXBlXy5NZXJnZUZyb20oZnJvbS5tZXNzYWdlX3R5cGVfKTsKKyAgZW51bV90eXBlXy5NZXJnZUZyb20oZnJvbS5lbnVtX3R5cGVfKTsKKyAgc2VydmljZV8uTWVyZ2VGcm9tKGZyb20uc2VydmljZV8pOworICBleHRlbnNpb25fLk1lcmdlRnJvbShmcm9tLmV4dGVuc2lvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfcGFja2FnZSgpKSB7CisgICAgICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgICAgIHBhY2thZ2VfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5wYWNrYWdlXyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9oYXNfYml0c19bOSAvIDMyXSAmICgweGZmdSA8PCAoOSAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfb3B0aW9ucygpKSB7CisgICAgICBtdXRhYmxlX29wdGlvbnMoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSkgeworICAgICAgbXV0YWJsZV9zb3VyY2VfY29kZV9pbmZvKCktPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm86Ok1lcmdlRnJvbShmcm9tLnNvdXJjZV9jb2RlX2luZm8oKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19zeW50YXgoKSkgeworICAgICAgc2V0X2hhc19zeW50YXgoKTsKKyAgICAgIHN5bnRheF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnN5bnRheF8pOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEZpbGVEZXNjcmlwdG9yUHJvdG86OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5tZXNzYWdlX3R5cGUoKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5lbnVtX3R5cGUoKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5zZXJ2aWNlKCkpKSByZXR1cm4gZmFsc2U7CisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+ZXh0ZW5zaW9uKCkpKSByZXR1cm4gZmFsc2U7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgaWYgKCF0aGlzLT5vcHRpb25zXy0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6U3dhcChGaWxlRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoRmlsZURlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgcGFja2FnZV8uU3dhcCgmb3RoZXItPnBhY2thZ2VfKTsKKyAgZGVwZW5kZW5jeV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZGVwZW5kZW5jeV8pOworICBwdWJsaWNfZGVwZW5kZW5jeV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+cHVibGljX2RlcGVuZGVuY3lfKTsKKyAgd2Vha19kZXBlbmRlbmN5Xy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT53ZWFrX2RlcGVuZGVuY3lfKTsKKyAgbWVzc2FnZV90eXBlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5tZXNzYWdlX3R5cGVfKTsKKyAgZW51bV90eXBlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5lbnVtX3R5cGVfKTsKKyAgc2VydmljZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+c2VydmljZV8pOworICBleHRlbnNpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmV4dGVuc2lvbl8pOworICBzdGQ6OnN3YXAob3B0aW9uc18sIG90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChzb3VyY2VfY29kZV9pbmZvXywgb3RoZXItPnNvdXJjZV9jb2RlX2luZm9fKTsKKyAgc3ludGF4Xy5Td2FwKCZvdGhlci0+c3ludGF4Xyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEZpbGVEZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEZpbGVEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBGaWxlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEZpbGVEZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHBhY2thZ2UgPSAyOworIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfcGFja2FnZSgpIHsKKyAgcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfcGFja2FnZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OnBhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKKyAgcmV0dXJuIHBhY2thZ2VfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2FnZSgpOworICBwYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19wYWNrYWdlKCk7CisgIHBhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9wYWNrYWdlKCkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKKyAgcmV0dXJuIHBhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9wYWNrYWdlKCkgeworICBjbGVhcl9oYXNfcGFja2FnZSgpOworICByZXR1cm4gcGFja2FnZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBwYWNrYWdlKSB7CisgIGlmIChwYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfcGFja2FnZSgpOworICB9CisgIHBhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBwYWNrYWdlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKK30KKworLy8gcmVwZWF0ZWQgc3RyaW5nIGRlcGVuZGVuY3kgPSAzOworIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXBlbmRlbmN5X3NpemUoKSBjb25zdCB7CisgIHJldHVybiBkZXBlbmRlbmN5Xy5zaXplKCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9kZXBlbmRlbmN5KCkgeworICBkZXBlbmRlbmN5Xy5DbGVhcigpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuIGRlcGVuZGVuY3lfLkdldChpbmRleCk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9kZXBlbmRlbmN5KGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorICByZXR1cm4gZGVwZW5kZW5jeV8uTXV0YWJsZShpbmRleCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgZGVwZW5kZW5jeV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGRlcGVuZGVuY3lfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9kZXBlbmRlbmN5KGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGRlcGVuZGVuY3lfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2RlcGVuZGVuY3koKSB7CisgIHJldHVybiBkZXBlbmRlbmN5Xy5BZGQoKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9kZXBlbmRlbmN5KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIGRlcGVuZGVuY3lfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZGVwZW5kZW5jeShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBkZXBlbmRlbmN5Xy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZGVwZW5kZW5jeShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgZGVwZW5kZW5jeV8uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVwZW5kZW5jeSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuIGRlcGVuZGVuY3lfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2RlcGVuZGVuY3koKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuICZkZXBlbmRlbmN5XzsKK30KKworLy8gcmVwZWF0ZWQgaW50MzIgcHVibGljX2RlcGVuZGVuY3kgPSAxMDsKKyBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6cHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5Xy5zaXplKCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9wdWJsaWNfZGVwZW5kZW5jeSgpIHsKKyAgcHVibGljX2RlcGVuZGVuY3lfLkNsZWFyKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWxlRGVzY3JpcHRvclByb3RvOjpwdWJsaWNfZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5Xy5HZXQoaW5kZXgpOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3B1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwdWJsaWNfZGVwZW5kZW5jeV8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucHVibGljX2RlcGVuZGVuY3kpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfcHVibGljX2RlcGVuZGVuY3koOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwdWJsaWNfZGVwZW5kZW5jeV8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86OnB1YmxpY19kZXBlbmRlbmN5KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5XzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfcHVibGljX2RlcGVuZGVuY3koKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucHVibGljX2RlcGVuZGVuY3kpCisgIHJldHVybiAmcHVibGljX2RlcGVuZGVuY3lfOworfQorCisvLyByZXBlYXRlZCBpbnQzMiB3ZWFrX2RlcGVuZGVuY3kgPSAxMTsKKyBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6d2Vha19kZXBlbmRlbmN5X3NpemUoKSBjb25zdCB7CisgIHJldHVybiB3ZWFrX2RlcGVuZGVuY3lfLnNpemUoKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3dlYWtfZGVwZW5kZW5jeSgpIHsKKyAgd2Vha19kZXBlbmRlbmN5Xy5DbGVhcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRmlsZURlc2NyaXB0b3JQcm90bzo6d2Vha19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV8uR2V0KGluZGV4KTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF93ZWFrX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHdlYWtfZGVwZW5kZW5jeV8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ud2Vha19kZXBlbmRlbmN5KQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX3dlYWtfZGVwZW5kZW5jeSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHdlYWtfZGVwZW5kZW5jeV8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjp3ZWFrX2RlcGVuZGVuY3koKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3dlYWtfZGVwZW5kZW5jeSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCisgIHJldHVybiAmd2Vha19kZXBlbmRlbmN5XzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKKyBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6bWVzc2FnZV90eXBlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBtZXNzYWdlX3R5cGVfLnNpemUoKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX21lc3NhZ2VfdHlwZSgpIHsKKyAgbWVzc2FnZV90eXBlXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjptZXNzYWdlX3R5cGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXy5HZXQoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX21lc3NhZ2VfdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX21lc3NhZ2VfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfLkFkZCgpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om1lc3NhZ2VfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX21lc3NhZ2VfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiAmbWVzc2FnZV90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDU7CisgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZW51bV90eXBlXy5zaXplKCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9lbnVtX3R5cGUoKSB7CisgIGVudW1fdHlwZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiAmZW51bV90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBzZXJ2aWNlXy5zaXplKCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9zZXJ2aWNlKCkgeworICBzZXJ2aWNlXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byYgRmlsZURlc2NyaXB0b3JQcm90bzo6c2VydmljZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfc2VydmljZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX3NlcnZpY2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfLkFkZCgpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfc2VydmljZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gJnNlcnZpY2VfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDc7CisgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gZXh0ZW5zaW9uXy5zaXplKCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbnNpb24oKSB7CisgIGV4dGVuc2lvbl8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5HZXQoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9leHRlbnNpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuICZleHRlbnNpb25fOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIG9wdGlvbnMgPSA4OworIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAyMDB1KSAhPSAwOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAyMDB1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAyMDB1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMmIEZpbGVEZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8gc291cmNlX2NvZGVfaW5mbyA9IDk7CisgYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpoYXNfc291cmNlX2NvZGVfaW5mbygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDQwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDQwMHU7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfc291cmNlX2NvZGVfaW5mbygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDQwMHU7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9zb3VyY2VfY29kZV9pbmZvKCkgeworICBpZiAoc291cmNlX2NvZGVfaW5mb18gIT0gTlVMTCkgc291cmNlX2NvZGVfaW5mb18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm86OkNsZWFyKCk7CisgIGNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyYgRmlsZURlc2NyaXB0b3JQcm90bzo6c291cmNlX2NvZGVfaW5mbygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zb3VyY2VfY29kZV9pbmZvKQorICByZXR1cm4gc291cmNlX2NvZGVfaW5mb18gIT0gTlVMTCA/ICpzb3VyY2VfY29kZV9pbmZvXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+c291cmNlX2NvZGVfaW5mb187Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zb3VyY2VfY29kZV9pbmZvKCkgeworICBzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgaWYgKHNvdXJjZV9jb2RlX2luZm9fID09IE5VTEwpIHsKKyAgICBzb3VyY2VfY29kZV9pbmZvXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNvdXJjZV9jb2RlX2luZm8pCisgIHJldHVybiBzb3VyY2VfY29kZV9pbmZvXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIGNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIHRlbXAgPSBzb3VyY2VfY29kZV9pbmZvXzsKKyAgc291cmNlX2NvZGVfaW5mb18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfc291cmNlX2NvZGVfaW5mbyg6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBzb3VyY2VfY29kZV9pbmZvKSB7CisgIGRlbGV0ZSBzb3VyY2VfY29kZV9pbmZvXzsKKyAgc291cmNlX2NvZGVfaW5mb18gPSBzb3VyY2VfY29kZV9pbmZvOworICBpZiAoc291cmNlX2NvZGVfaW5mbykgeworICAgIHNldF9oYXNfc291cmNlX2NvZGVfaW5mbygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc291cmNlX2NvZGVfaW5mbykKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX3N5bnRheCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDgwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3N5bnRheCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwODAwdTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19zeW50YXgoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDA4MDB1OworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfc3ludGF4KCkgeworICBzeW50YXhfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3N5bnRheCgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCisgIHJldHVybiBzeW50YXhfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9zeW50YXgoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9zeW50YXgoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4KQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3N5bnRheChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zeW50YXgoKSB7CisgIHNldF9oYXNfc3ludGF4KCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKKyAgcmV0dXJuIHN5bnRheF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3N5bnRheCgpIHsKKyAgY2xlYXJfaGFzX3N5bnRheCgpOworICByZXR1cm4gc3ludGF4Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9zeW50YXgoOjpzdGQ6OnN0cmluZyogc3ludGF4KSB7CisgIGlmIChzeW50YXggIT0gTlVMTCkgeworICAgIHNldF9oYXNfc3ludGF4KCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3N5bnRheCgpOworICB9CisgIHN5bnRheF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHN5bnRheCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjprU3RhcnRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmtFbmRGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK0Rlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UoY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBzdGFydF8gPSAwOworICBlbmRfID0gMDsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjp+RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0Rlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0Rlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBuID0gbmV3IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Q2xlYXIoKSB7CisjZGVmaW5lIFpSX0hFTFBFUl8oZikgcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oXAorICAmcmVpbnRlcnByZXRfY2FzdDxEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgWlJfKHN0YXJ0XywgZW5kXyk7CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmc3RhcnRfKSkpOworICAgICAgICAgIHNldF9oYXNfc3RhcnQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9lbmQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTYpIHsKKyAgICAgICAgIHBhcnNlX2VuZDoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZlbmRfKSkpOworICAgICAgICAgIHNldF9oYXNfZW5kKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgIGlmIChoYXNfc3RhcnQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKDEsIHRoaXMtPnN0YXJ0KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworICBpZiAoaGFzX2VuZCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoMiwgdGhpcy0+ZW5kKCksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgIGlmIChoYXNfc3RhcnQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgxLCB0aGlzLT5zdGFydCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gMjsKKyAgaWYgKGhhc19lbmQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgyLCB0aGlzLT5lbmQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDMpIHsKKyAgICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgICAgaWYgKGhhc19zdGFydCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICAgIHRoaXMtPnN0YXJ0KCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgICAgaWYgKGhhc19lbmQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgICB0aGlzLT5lbmQoKSk7CisgICAgfQorCisgIH0KKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpNZXJnZUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfc3RhcnQoKSkgeworICAgICAgc2V0X3N0YXJ0KGZyb20uc3RhcnQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19lbmQoKSkgeworICAgICAgc2V0X2VuZChmcm9tLmVuZCgpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Q29weUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpTd2FwKERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpJbnRlcm5hbFN3YXAoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBvdGhlcikgeworICBzdGQ6OnN3YXAoc3RhcnRfLCBvdGhlci0+c3RhcnRfKTsKKyAgc3RkOjpzd2FwKGVuZF8sIG90aGVyLT5lbmRfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvOjprRmllbGRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtFeHRlbnNpb25GaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvOjprRW51bVR5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtFeHRlbnNpb25SYW5nZUZpZWxkTnVtYmVyOworY29uc3QgaW50IERlc2NyaXB0b3JQcm90bzo6a09uZW9mRGVjbEZpZWxkTnVtYmVyOworY29uc3QgaW50IERlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK0Rlc2NyaXB0b3JQcm90bzo6RGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK0Rlc2NyaXB0b3JQcm90bzo6RGVzY3JpcHRvclByb3RvKGNvbnN0IERlc2NyaXB0b3JQcm90byYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBvcHRpb25zXyA9IE5VTEw7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0Rlc2NyaXB0b3JQcm90bzo6fkRlc2NyaXB0b3JQcm90bygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgICBkZWxldGUgb3B0aW9uc187CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBEZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBEZXNjcmlwdG9yUHJvdG8qIG4gPSBuZXcgRGVzY3JpcHRvclByb3RvOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpDbGVhcigpIHsKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDEyOSkgeworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnM6OkNsZWFyKCk7CisgICAgfQorICB9CisgIGZpZWxkXy5DbGVhcigpOworICBleHRlbnNpb25fLkNsZWFyKCk7CisgIG5lc3RlZF90eXBlXy5DbGVhcigpOworICBlbnVtX3R5cGVfLkNsZWFyKCk7CisgIGV4dGVuc2lvbl9yYW5nZV8uQ2xlYXIoKTsKKyAgb25lb2ZfZGVjbF8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2ZpZWxkOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfZmllbGQ6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2ZpZWxkKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9maWVsZDsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX25lc3RlZF90eXBlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX25lc3RlZF90eXBlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9uZXN0ZWRfdHlwZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2VfbmVzdGVkX3R5cGU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDM0KSkgZ290byBwYXJzZV9lbnVtX3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNDsKKyAgICAgIGNhc2UgNDogeworICAgICAgICBpZiAodGFnID09IDM0KSB7CisgICAgICAgICBwYXJzZV9lbnVtX3R5cGU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2VudW1fdHlwZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfZW51bV90eXBlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg0MikpIGdvdG8gcGFyc2VfZXh0ZW5zaW9uX3JhbmdlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQyKSB7CisgICAgICAgICBwYXJzZV9leHRlbnNpb25fcmFuZ2U6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2V4dGVuc2lvbl9yYW5nZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg0MikpIGdvdG8gcGFyc2VfZXh0ZW5zaW9uX3JhbmdlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2VfZXh0ZW5zaW9uOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA2OworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTApIHsKKyAgICAgICAgIHBhcnNlX2V4dGVuc2lvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfZXh0ZW5zaW9uKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDUwKSkgZ290byBwYXJzZV9leHRlbnNpb247CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDU4KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyBvcHRpb25zID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU4KSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDY2KSkgZ290byBwYXJzZV9vbmVvZl9kZWNsOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKyAgICAgIGNhc2UgODogeworICAgICAgICBpZiAodGFnID09IDY2KSB7CisgICAgICAgICBwYXJzZV9vbmVvZl9kZWNsOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9vbmVvZl9kZWNsKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDY2KSkgZ290byBwYXJzZV9vbmVvZl9kZWNsOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZmllbGRfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDIsIHRoaXMtPmZpZWxkKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm5lc3RlZF90eXBlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAzLCB0aGlzLT5uZXN0ZWRfdHlwZShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA0OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmVudW1fdHlwZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNCwgdGhpcy0+ZW51bV90eXBlKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5leHRlbnNpb25fcmFuZ2Vfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDUsIHRoaXMtPmV4dGVuc2lvbl9yYW5nZShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5leHRlbnNpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDYsIHRoaXMtPmV4dGVuc2lvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgb3B0aW9ucyA9IDc7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDcsICp0aGlzLT5vcHRpb25zXywgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8gb25lb2ZfZGVjbCA9IDg7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+b25lb2ZfZGVjbF9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOCwgdGhpcy0+b25lb2ZfZGVjbChpKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+bmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZmllbGRfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+ZmllbGQoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBuZXN0ZWRfdHlwZSA9IDM7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bmVzdGVkX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMywgdGhpcy0+bmVzdGVkX3R5cGUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNDsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNCwgdGhpcy0+ZW51bV90eXBlKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5leHRlbnNpb25fcmFuZ2Vfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNSwgdGhpcy0+ZXh0ZW5zaW9uX3JhbmdlKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA2OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmV4dGVuc2lvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA2LCB0aGlzLT5leHRlbnNpb24oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDcsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8gb25lb2ZfZGVjbCA9IDg7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+b25lb2ZfZGVjbF9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA4LCB0aGlzLT5vbmVvZl9kZWNsKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IERlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMTI5KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5uYW1lKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgb3B0aW9ucyA9IDc7CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgICAqdGhpcy0+b3B0aW9uc18pOworICAgIH0KKworICB9CisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5maWVsZF9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZmllbGRfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmZpZWxkKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZXh0ZW5zaW9uX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5leHRlbnNpb25fc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmV4dGVuc2lvbihpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBuZXN0ZWRfdHlwZSA9IDM7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm5lc3RlZF90eXBlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5uZXN0ZWRfdHlwZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+bmVzdGVkX3R5cGUoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmVudW1fdHlwZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZW51bV90eXBlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5lbnVtX3R5cGUoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZXh0ZW5zaW9uX3JhbmdlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5leHRlbnNpb25fcmFuZ2Vfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmV4dGVuc2lvbl9yYW5nZShpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvIG9uZW9mX2RlY2wgPSA4OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5vbmVvZl9kZWNsX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5vbmVvZl9kZWNsX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5vbmVvZl9kZWNsKGkpKTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgRGVzY3JpcHRvclByb3RvKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBmaWVsZF8uTWVyZ2VGcm9tKGZyb20uZmllbGRfKTsKKyAgZXh0ZW5zaW9uXy5NZXJnZUZyb20oZnJvbS5leHRlbnNpb25fKTsKKyAgbmVzdGVkX3R5cGVfLk1lcmdlRnJvbShmcm9tLm5lc3RlZF90eXBlXyk7CisgIGVudW1fdHlwZV8uTWVyZ2VGcm9tKGZyb20uZW51bV90eXBlXyk7CisgIGV4dGVuc2lvbl9yYW5nZV8uTWVyZ2VGcm9tKGZyb20uZXh0ZW5zaW9uX3JhbmdlXyk7CisgIG9uZW9mX2RlY2xfLk1lcmdlRnJvbShmcm9tLm9uZW9mX2RlY2xfKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19uYW1lKCkpIHsKKyAgICAgIHNldF9oYXNfbmFtZSgpOworICAgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX29wdGlvbnMoKSkgeworICAgICAgbXV0YWJsZV9vcHRpb25zKCktPjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnM6Ok1lcmdlRnJvbShmcm9tLm9wdGlvbnMoKSk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRGVzY3JpcHRvclByb3RvOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+ZmllbGQoKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5leHRlbnNpb24oKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5uZXN0ZWRfdHlwZSgpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPmVudW1fdHlwZSgpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6U3dhcChEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKERlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgZmllbGRfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmZpZWxkXyk7CisgIGV4dGVuc2lvbl8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZXh0ZW5zaW9uXyk7CisgIG5lc3RlZF90eXBlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5uZXN0ZWRfdHlwZV8pOworICBlbnVtX3R5cGVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmVudW1fdHlwZV8pOworICBleHRlbnNpb25fcmFuZ2VfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmV4dGVuc2lvbl9yYW5nZV8pOworICBvbmVvZl9kZWNsXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5vbmVvZl9kZWNsXyk7CisgIHN0ZDo6c3dhcChvcHRpb25zXywgb3RoZXItPm9wdGlvbnNfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRGVzY3JpcHRvclByb3RvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlCisKKy8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyBib29sIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6aGFzX3N0YXJ0KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X2hhc19zdGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Y2xlYXJfaGFzX3N0YXJ0KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Y2xlYXJfc3RhcnQoKSB7CisgIHN0YXJ0XyA9IDA7CisgIGNsZWFyX2hhc19zdGFydCgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpzdGFydCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLnN0YXJ0KQorICByZXR1cm4gc3RhcnRfOworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpzZXRfc3RhcnQoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzZXRfaGFzX3N0YXJ0KCk7CisgIHN0YXJ0XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2Uuc3RhcnQpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6Omhhc19lbmQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpzZXRfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Y2xlYXJfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX2VuZCgpIHsKKyAgZW5kXyA9IDA7CisgIGNsZWFyX2hhc19lbmQoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6ZW5kKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UuZW5kKQorICByZXR1cm4gZW5kXzsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X2VuZCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfZW5kKCk7CisgIGVuZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLmVuZCkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBEZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworIGJvb2wgRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOworIGludCBEZXNjcmlwdG9yUHJvdG86OmZpZWxkX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBmaWVsZF8uc2l6ZSgpOworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9maWVsZCgpIHsKKyAgZmllbGRfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byYgRGVzY3JpcHRvclByb3RvOjpmaWVsZChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmZpZWxkKQorICByZXR1cm4gZmllbGRfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2ZpZWxkKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmZpZWxkKQorICByZXR1cm4gZmllbGRfLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6YWRkX2ZpZWxkKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiBmaWVsZF8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4mCitEZXNjcmlwdG9yUHJvdG86OmZpZWxkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmZpZWxkKQorICByZXR1cm4gZmllbGRfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2ZpZWxkKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiAmZmllbGRfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDY7CisgaW50IERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBleHRlbnNpb25fLnNpemUoKTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZXh0ZW5zaW9uKCkgeworICBleHRlbnNpb25fLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byYgRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuc2lvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6YWRkX2V4dGVuc2lvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4mCitEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuc2lvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuICZleHRlbnNpb25fOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBuZXN0ZWRfdHlwZSA9IDM7CisgaW50IERlc2NyaXB0b3JQcm90bzo6bmVzdGVkX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5zaXplKCk7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25lc3RlZF90eXBlKCkgeworICBuZXN0ZWRfdHlwZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byYgRGVzY3JpcHRvclByb3RvOjpuZXN0ZWRfdHlwZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5lc3RlZF90eXBlKQorICByZXR1cm4gbmVzdGVkX3R5cGVfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uZXN0ZWRfdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uZXN0ZWRfdHlwZSkKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjphZGRfbmVzdGVkX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uZXN0ZWRfdHlwZSkKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4mCitEZXNjcmlwdG9yUHJvdG86Om5lc3RlZF90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5lc3RlZF90eXBlKQorICByZXR1cm4gbmVzdGVkX3R5cGVfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uZXN0ZWRfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5lc3RlZF90eXBlKQorICByZXR1cm4gJm5lc3RlZF90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CisgaW50IERlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBlbnVtX3R5cGVfLnNpemUoKTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZW51bV90eXBlKCkgeworICBlbnVtX3R5cGVfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9lbnVtX3R5cGUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6YWRkX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiAmZW51bV90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKyBpbnQgRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb25fcmFuZ2Vfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV8uc2l6ZSgpOworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbnNpb25fcmFuZ2UoKSB7CisgIGV4dGVuc2lvbl9yYW5nZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb25fcmFuZ2UoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb25fcmFuZ2UpCisgIHJldHVybiBleHRlbnNpb25fcmFuZ2VfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb25fcmFuZ2UoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uX3JhbmdlKQorICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogRGVzY3JpcHRvclByb3RvOjphZGRfZXh0ZW5zaW9uX3JhbmdlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uX3JhbmdlKQorICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlID4mCitEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9yYW5nZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb25fcmFuZ2UpCisgIHJldHVybiBleHRlbnNpb25fcmFuZ2VfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb25fcmFuZ2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb25fcmFuZ2UpCisgIHJldHVybiAmZXh0ZW5zaW9uX3JhbmdlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKyBpbnQgRGVzY3JpcHRvclByb3RvOjpvbmVvZl9kZWNsX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBvbmVvZl9kZWNsXy5zaXplKCk7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX29uZW9mX2RlY2woKSB7CisgIG9uZW9mX2RlY2xfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byYgRGVzY3JpcHRvclByb3RvOjpvbmVvZl9kZWNsKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub25lb2ZfZGVjbCkKKyAgcmV0dXJuIG9uZW9mX2RlY2xfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29uZW9mX2RlY2woaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub25lb2ZfZGVjbCkKKyAgcmV0dXJuIG9uZW9mX2RlY2xfLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6YWRkX29uZW9mX2RlY2woKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gb25lb2ZfZGVjbF8uQWRkKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4mCitEZXNjcmlwdG9yUHJvdG86Om9uZW9mX2RlY2woKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub25lb2ZfZGVjbCkKKyAgcmV0dXJuIG9uZW9mX2RlY2xfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29uZW9mX2RlY2woKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gJm9uZW9mX2RlY2xfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworIGJvb2wgRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDA4MHUpICE9IDA7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDgwdTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwODB1OworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyYgRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vcHRpb25zKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX0lzVmFsaWQoaW50IHZhbHVlKSB7CisgIHN3aXRjaCh2YWx1ZSkgeworICAgIGNhc2UgMToKKyAgICBjYXNlIDI6CisgICAgY2FzZSAzOgorICAgIGNhc2UgNDoKKyAgICBjYXNlIDU6CisgICAgY2FzZSA2OgorICAgIGNhc2UgNzoKKyAgICBjYXNlIDg6CisgICAgY2FzZSA5OgorICAgIGNhc2UgMTA6CisgICAgY2FzZSAxMToKKyAgICBjYXNlIDEyOgorICAgIGNhc2UgMTM6CisgICAgY2FzZSAxNDoKKyAgICBjYXNlIDE1OgorICAgIGNhc2UgMTY6CisgICAgY2FzZSAxNzoKKyAgICBjYXNlIDE4OgorICAgICAgcmV0dXJuIHRydWU7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0RPVUJMRTsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRkxPQVQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDY0OworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UNjQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GSVhFRDY0OworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GSVhFRDMyOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9CT09MOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TVFJJTkc7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9CWVRFUzsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfVUlOVDMyOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9FTlVNOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TRklYRUQzMjsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0ZJWEVENjQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NJTlQzMjsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDY0OworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZV9NSU47Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlX01BWDsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZV9BUlJBWVNJWkU7CisjZW5kaWYgIC8vIF9NU0NfVkVSCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICBzd2l0Y2godmFsdWUpIHsKKyAgICBjYXNlIDE6CisgICAgY2FzZSAyOgorICAgIGNhc2UgMzoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUVVJUkVEOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUEVBVEVEOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsX01JTjsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMYWJlbF9NQVg7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsX0FSUkFZU0laRTsKKyNlbmRpZiAgLy8gX01TQ19WRVIKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a051bWJlckZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkRGVzY3JpcHRvclByb3RvOjprTGFiZWxGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a1R5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a1R5cGVOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtFeHRlbmRlZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkRGVzY3JpcHRvclByb3RvOjprRGVmYXVsdFZhbHVlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtPbmVvZkluZGV4RmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorCitGaWVsZERlc2NyaXB0b3JQcm90bzo6RmllbGREZXNjcmlwdG9yUHJvdG8oKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpICwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSAgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKworRmllbGREZXNjcmlwdG9yUHJvdG86OkZpZWxkRGVzY3JpcHRvclByb3RvKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBudW1iZXJfID0gMDsKKyAgbGFiZWxfID0gMTsKKyAgdHlwZV8gPSAxOworICB0eXBlX25hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgZXh0ZW5kZWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgZGVmYXVsdF92YWx1ZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBvbmVvZl9pbmRleF8gPSAwOworICBvcHRpb25zXyA9IE5VTEw7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0ZpZWxkRGVzY3JpcHRvclByb3RvOjp+RmllbGREZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB0eXBlX25hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGV4dGVuZGVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBkZWZhdWx0X3ZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgIGRlbGV0ZSBvcHRpb25zXzsKKyAgfQorfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmllbGREZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRmllbGREZXNjcmlwdG9yUHJvdG8qIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0ZpZWxkRGVzY3JpcHRvclByb3RvKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IEZpZWxkRGVzY3JpcHRvclByb3RvOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OkNsZWFyKCkgeworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMjU1KSB7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgbnVtYmVyXyA9IDA7CisgICAgbGFiZWxfID0gMTsKKyAgICB0eXBlXyA9IDE7CisgICAgaWYgKGhhc190eXBlX25hbWUoKSkgeworICAgICAgdHlwZV9uYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfZXh0ZW5kZWUoKSkgeworICAgICAgZXh0ZW5kZWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgIGRlZmF1bHRfdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgb25lb2ZfaW5kZXhfID0gMDsKKyAgfQorICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnM6OkNsZWFyKCk7CisgIH0KKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2V4dGVuZGVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGV4dGVuZGVlID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9leHRlbmRlZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfZXh0ZW5kZWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+ZXh0ZW5kZWUoKS5kYXRhKCksIHRoaXMtPmV4dGVuZGVlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI0KSkgZ290byBwYXJzZV9udW1iZXI7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX251bWJlcjoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZudW1iZXJfKSkpOworICAgICAgICAgIHNldF9oYXNfbnVtYmVyKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMikpIGdvdG8gcGFyc2VfbGFiZWw7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsIGxhYmVsID0gNDsKKyAgICAgIGNhc2UgNDogeworICAgICAgICBpZiAodGFnID09IDMyKSB7CisgICAgICAgICBwYXJzZV9sYWJlbDoKKyAgICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkpOworICAgICAgICAgIGlmICg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0lzVmFsaWQodmFsdWUpKSB7CisgICAgICAgICAgICBzZXRfbGFiZWwoc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgPih2YWx1ZSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCg0LCB2YWx1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDApKSBnb3RvIHBhcnNlX3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MCkgeworICAgICAgICAgcGFyc2VfdHlwZToKKyAgICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkpOworICAgICAgICAgIGlmICg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfSXNWYWxpZCh2YWx1ZSkpIHsKKyAgICAgICAgICAgIHNldF90eXBlKHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgPih2YWx1ZSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCg1LCB2YWx1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX3R5cGVfbmFtZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX25hbWUgPSA2OworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTApIHsKKyAgICAgICAgIHBhcnNlX3R5cGVfbmFtZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfdHlwZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnR5cGVfbmFtZSgpLmRhdGEoKSwgdGhpcy0+dHlwZV9uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1OCkpIGdvdG8gcGFyc2VfZGVmYXVsdF92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU4KSB7CisgICAgICAgICBwYXJzZV9kZWZhdWx0X3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5kYXRhKCksIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg2NikpIGdvdG8gcGFyc2Vfb3B0aW9uczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworICAgICAgY2FzZSA4OiB7CisgICAgICAgIGlmICh0YWcgPT0gNjYpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzIpKSBnb3RvIHBhcnNlX29uZW9mX2luZGV4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA5OworICAgICAgY2FzZSA5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzIpIHsKKyAgICAgICAgIHBhcnNlX29uZW9mX2luZGV4OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm9uZW9mX2luZGV4XykpKTsKKyAgICAgICAgICBzZXRfaGFzX29uZW9mX2luZGV4KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBleHRlbmRlZSA9IDI7CisgIGlmIChoYXNfZXh0ZW5kZWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+ZXh0ZW5kZWUoKS5kYXRhKCksIHRoaXMtPmV4dGVuZGVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+ZXh0ZW5kZWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgIGlmIChoYXNfbnVtYmVyKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigzLCB0aGlzLT5udW1iZXIoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwgbGFiZWwgPSA0OworICBpZiAoaGFzX2xhYmVsKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKAorICAgICAgNCwgdGhpcy0+bGFiZWwoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSB0eXBlID0gNTsKKyAgaWYgKGhhc190eXBlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKAorICAgICAgNSwgdGhpcy0+dHlwZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHR5cGVfbmFtZSA9IDY7CisgIGlmIChoYXNfdHlwZV9uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPnR5cGVfbmFtZSgpLmRhdGEoKSwgdGhpcy0+dHlwZV9uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDYsIHRoaXMtPnR5cGVfbmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworICBpZiAoaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgNywgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgb3B0aW9ucyA9IDg7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDgsICp0aGlzLT5vcHRpb25zXywgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKKyAgaWYgKGhhc19vbmVvZl9pbmRleCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoOSwgdGhpcy0+b25lb2ZfaW5kZXgoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBGaWVsZERlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworICBpZiAoaGFzX2V4dGVuZGVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmV4dGVuZGVlKCkuZGF0YSgpLCB0aGlzLT5leHRlbmRlZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT5leHRlbmRlZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMzsKKyAgaWYgKGhhc19udW1iZXIoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgzLCB0aGlzLT5udW1iZXIoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwgbGFiZWwgPSA0OworICBpZiAoaGFzX2xhYmVsKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheSgKKyAgICAgIDQsIHRoaXMtPmxhYmVsKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgIGlmIChoYXNfdHlwZSgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bVRvQXJyYXkoCisgICAgICA1LCB0aGlzLT50eXBlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKKyAgaWYgKGhhc190eXBlX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+dHlwZV9uYW1lKCkuZGF0YSgpLCB0aGlzLT50eXBlX25hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDYsIHRoaXMtPnR5cGVfbmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworICBpZiAoaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDcsIHRoaXMtPmRlZmF1bHRfdmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDgsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKKyAgaWYgKGhhc19vbmVvZl9pbmRleCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDksIHRoaXMtPm9uZW9mX2luZGV4KCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMjU1KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5uYW1lKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgICAgaWYgKGhhc19udW1iZXIoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgICB0aGlzLT5udW1iZXIoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbCBsYWJlbCA9IDQ7CisgICAgaWYgKGhhc19sYWJlbCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RW51bVNpemUodGhpcy0+bGFiZWwoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5UeXBlIHR5cGUgPSA1OworICAgIGlmIChoYXNfdHlwZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RW51bVNpemUodGhpcy0+dHlwZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKKyAgICBpZiAoaGFzX3R5cGVfbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT50eXBlX25hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGV4dGVuZGVlID0gMjsKKyAgICBpZiAoaGFzX2V4dGVuZGVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmV4dGVuZGVlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gNzsKKyAgICBpZiAoaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBpbnQzMiBvbmVvZl9pbmRleCA9IDk7CisgICAgaWYgKGhhc19vbmVvZl9pbmRleCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICAgIHRoaXMtPm9uZW9mX2luZGV4KCkpOworICAgIH0KKworICB9CisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8qIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX25hbWUoKTsKKyAgICAgIG5hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5uYW1lXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19udW1iZXIoKSkgeworICAgICAgc2V0X251bWJlcihmcm9tLm51bWJlcigpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2xhYmVsKCkpIHsKKyAgICAgIHNldF9sYWJlbChmcm9tLmxhYmVsKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfdHlwZSgpKSB7CisgICAgICBzZXRfdHlwZShmcm9tLnR5cGUoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc190eXBlX25hbWUoKSkgeworICAgICAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgICAgIHR5cGVfbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnR5cGVfbmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZXh0ZW5kZWUoKSkgeworICAgICAgc2V0X2hhc19leHRlbmRlZSgpOworICAgICAgZXh0ZW5kZWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5leHRlbmRlZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZGVmYXVsdF92YWx1ZSgpKSB7CisgICAgICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgICAgIGRlZmF1bHRfdmFsdWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5kZWZhdWx0X3ZhbHVlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vbmVvZl9pbmRleCgpKSB7CisgICAgICBzZXRfb25lb2ZfaW5kZXgoZnJvbS5vbmVvZl9pbmRleCgpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2hhc19iaXRzX1s4IC8gMzJdICYgKDB4ZmZ1IDw8ICg4ICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpTd2FwKEZpZWxkRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKEZpZWxkRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBzdGQ6OnN3YXAobnVtYmVyXywgb3RoZXItPm51bWJlcl8pOworICBzdGQ6OnN3YXAobGFiZWxfLCBvdGhlci0+bGFiZWxfKTsKKyAgc3RkOjpzd2FwKHR5cGVfLCBvdGhlci0+dHlwZV8pOworICB0eXBlX25hbWVfLlN3YXAoJm90aGVyLT50eXBlX25hbWVfKTsKKyAgZXh0ZW5kZWVfLlN3YXAoJm90aGVyLT5leHRlbmRlZV8pOworICBkZWZhdWx0X3ZhbHVlXy5Td2FwKCZvdGhlci0+ZGVmYXVsdF92YWx1ZV8pOworICBzdGQ6OnN3YXAob25lb2ZfaW5kZXhfLCBvdGhlci0+b25lb2ZfaW5kZXhfKTsKKyAgc3RkOjpzd2FwKG9wdGlvbnNfLCBvdGhlci0+b3B0aW9uc18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBGaWVsZERlc2NyaXB0b3JQcm90bzo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBGaWVsZERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBGaWVsZERlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX251bWJlcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19udW1iZXIoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX251bWJlcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbnVtYmVyKCkgeworICBudW1iZXJfID0gMDsKKyAgY2xlYXJfaGFzX251bWJlcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRmllbGREZXNjcmlwdG9yUHJvdG86Om51bWJlcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubnVtYmVyKQorICByZXR1cm4gbnVtYmVyXzsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19udW1iZXIoKTsKKyAgbnVtYmVyXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5udW1iZXIpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwgbGFiZWwgPSA0OworIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19sYWJlbCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19sYWJlbCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbGFiZWwoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2xhYmVsKCkgeworICBsYWJlbF8gPSAxOworICBjbGVhcl9oYXNfbGFiZWwoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIEZpZWxkRGVzY3JpcHRvclByb3RvOjpsYWJlbCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubGFiZWwpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCA+KGxhYmVsXyk7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2xhYmVsKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX2xhYmVsKCk7CisgIGxhYmVsXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5sYWJlbCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5UeXBlIHR5cGUgPSA1OworIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc190eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX3R5cGUoKSB7CisgIHR5cGVfID0gMTsKKyAgY2xlYXJfaGFzX3R5cGUoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OnR5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGUpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlID4odHlwZV8pOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc190eXBlKCk7CisgIHR5cGVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX25hbWUgPSA2OworIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc190eXBlX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfdHlwZV9uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMTB1OworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc190eXBlX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX3R5cGVfbmFtZSgpIHsKKyAgdHlwZV9uYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc190eXBlX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6dHlwZV9uYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCisgIHJldHVybiB0eXBlX25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfdHlwZV9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfdHlwZV9uYW1lKCk7CisgIHR5cGVfbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgdHlwZV9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICB0eXBlX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfdHlwZV9uYW1lKCkgeworICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorICByZXR1cm4gdHlwZV9uYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3R5cGVfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX3R5cGVfbmFtZSgpOworICByZXR1cm4gdHlwZV9uYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfdHlwZV9uYW1lKDo6c3RkOjpzdHJpbmcqIHR5cGVfbmFtZSkgeworICBpZiAodHlwZV9uYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc190eXBlX25hbWUoKTsKKyAgfQorICB0eXBlX25hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB0eXBlX25hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19leHRlbmRlZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19leHRlbmRlZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfZXh0ZW5kZWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMjB1OworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2V4dGVuZGVlKCkgeworICBleHRlbmRlZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZXh0ZW5kZWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5kZWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorICByZXR1cm4gZXh0ZW5kZWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfZXh0ZW5kZWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19leHRlbmRlZSgpOworICBleHRlbmRlZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2V4dGVuZGVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgZXh0ZW5kZWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2V4dGVuZGVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIGV4dGVuZGVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5kZWUoKSB7CisgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorICByZXR1cm4gZXh0ZW5kZWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfZXh0ZW5kZWUoKSB7CisgIGNsZWFyX2hhc19leHRlbmRlZSgpOworICByZXR1cm4gZXh0ZW5kZWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9leHRlbmRlZSg6OnN0ZDo6c3RyaW5nKiBleHRlbmRlZSkgeworICBpZiAoZXh0ZW5kZWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZXh0ZW5kZWUoKTsKKyAgfQorICBleHRlbmRlZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGV4dGVuZGVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF92YWx1ZSA9IDc7CisgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX2RlZmF1bHRfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfZGVmYXVsdF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDQwdTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA0MHU7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZGVmYXVsdF92YWx1ZSgpIHsKKyAgZGVmYXVsdF92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZGVmYXVsdF92YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkgeworICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2RlZmF1bHRfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19kZWZhdWx0X3ZhbHVlKCk7CisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfZGVmYXVsdF92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlKSB7CisgIGlmIChkZWZhdWx0X3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworICB9CisgIGRlZmF1bHRfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBkZWZhdWx0X3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKKyBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfb25lb2ZfaW5kZXgoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwODB1KSAhPSAwOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb25lb2ZfaW5kZXgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29uZW9mX2luZGV4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDgwdTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vbmVvZl9pbmRleCgpIHsKKyAgb25lb2ZfaW5kZXhfID0gMDsKKyAgY2xlYXJfaGFzX29uZW9mX2luZGV4KCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWVsZERlc2NyaXB0b3JQcm90bzo6b25lb2ZfaW5kZXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4KQorICByZXR1cm4gb25lb2ZfaW5kZXhfOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9vbmVvZl9pbmRleCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfb25lb2ZfaW5kZXgoKTsKKyAgb25lb2ZfaW5kZXhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4KQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyBvcHRpb25zID0gODsKKyBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDEwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAxMDB1OworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMTAwdTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogdGVtcCA9IG9wdGlvbnNfOworICBvcHRpb25zXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IGludCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK09uZW9mRGVzY3JpcHRvclByb3RvOjpPbmVvZkRlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitPbmVvZkRlc2NyaXB0b3JQcm90bzo6T25lb2ZEZXNjcmlwdG9yUHJvdG8oY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK09uZW9mRGVzY3JpcHRvclByb3RvOjp+T25lb2ZEZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIE9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitPbmVvZkRlc2NyaXB0b3JQcm90byogT25lb2ZEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworT25lb2ZEZXNjcmlwdG9yUHJvdG8qIE9uZW9mRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG4gPSBuZXcgT25lb2ZEZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIE9uZW9mRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX25hbWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE9uZW9mRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE9uZW9mRGVzY3JpcHRvclByb3RvOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8qIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX25hbWUoKTsKKyAgICAgIG5hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5uYW1lXyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgT25lb2ZEZXNjcmlwdG9yUHJvdG86OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OlN3YXAoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIE9uZW9mRGVzY3JpcHRvclByb3RvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE9uZW9mRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIE9uZW9mRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyBib29sIE9uZW9mRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cisgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgT25lb2ZEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIDo6c3RkOjpzdHJpbmcqIE9uZW9mRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogT25lb2ZEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX25hbWUoKTsKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgRW51bURlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBFbnVtRGVzY3JpcHRvclByb3RvOjprVmFsdWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBFbnVtRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworRW51bURlc2NyaXB0b3JQcm90bzo6RW51bURlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK0VudW1EZXNjcmlwdG9yUHJvdG86OkVudW1EZXNjcmlwdG9yUHJvdG8oY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRW51bURlc2NyaXB0b3JQcm90bzo6fkVudW1EZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgICBkZWxldGUgb3B0aW9uc187CisgIH0KK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBFbnVtRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBFbnVtRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitFbnVtRGVzY3JpcHRvclByb3RvKiBFbnVtRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0VudW1EZXNjcmlwdG9yUHJvdG8qIEVudW1EZXNjcmlwdG9yUHJvdG86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBFbnVtRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IEVudW1EZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpDbGVhcigpIHsKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDUpIHsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zOjpDbGVhcigpOworICAgIH0KKyAgfQorICB2YWx1ZV8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRW51bURlc2NyaXB0b3JQcm90bzo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX25hbWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF92YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfdmFsdWU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgICAgIGNhc2UgMzogeworICAgICAgICBpZiAodGFnID09IDI2KSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHZhbHVlID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT52YWx1ZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgdGhpcy0+dmFsdWUoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAzLCAqdGhpcy0+b3B0aW9uc18sIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byB2YWx1ZSA9IDI7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dmFsdWVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+dmFsdWUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRW51bURlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgICAgKnRoaXMtPm9wdGlvbnNfKTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byB2YWx1ZSA9IDI7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPnZhbHVlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT52YWx1ZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+dmFsdWUoaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8qPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgdmFsdWVfLk1lcmdlRnJvbShmcm9tLnZhbHVlXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX25hbWUoKTsKKyAgICAgIG5hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5uYW1lXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zOjpNZXJnZUZyb20oZnJvbS5vcHRpb25zKCkpOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEVudW1EZXNjcmlwdG9yUHJvdG86OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT52YWx1ZSgpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OlN3YXAoRW51bURlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKEVudW1EZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIHZhbHVlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT52YWx1ZV8pOworICBzdGQ6OnN3YXAob3B0aW9uc18sIG90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEVudW1EZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEVudW1EZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBFbnVtRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEVudW1EZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworIGJvb2wgRW51bURlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQorIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEVudW1EZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRW51bURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworIGludCBFbnVtRGVzY3JpcHRvclByb3RvOjp2YWx1ZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gdmFsdWVfLnNpemUoKTsKK30KKyB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgRW51bURlc2NyaXB0b3JQcm90bzo6dmFsdWUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV92YWx1ZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIEVudW1EZXNjcmlwdG9yUHJvdG86OmFkZF92YWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4mCitFbnVtRGVzY3JpcHRvclByb3RvOjp2YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byA+KgorRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV92YWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuICZ2YWx1ZV87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgYm9vbCBFbnVtRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyYgRW51bURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBFbnVtRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KKyB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6a051bWJlckZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK0VudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqPigmOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byhjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIG5hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgbnVtYmVyXyA9IDA7CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjp+RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgIGRlbGV0ZSBvcHRpb25zXzsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogbiA9IG5ldyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkNsZWFyKCkgeworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNykgeworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIG51bWJlcl8gPSAwOworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgIH0KKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTYpKSBnb3RvIHBhcnNlX251bWJlcjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgcGFyc2VfbnVtYmVyOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm51bWJlcl8pKSk7CisgICAgICAgICAgc2V0X2hhc19udW1iZXIoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIG9wdGlvbnMgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgIGlmIChoYXNfbnVtYmVyKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigyLCB0aGlzLT5udW1iZXIoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMywgKnRoaXMtPm9wdGlvbnNfLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAyOworICBpZiAoaGFzX251bWJlcigpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDIsIHRoaXMtPm51bWJlcigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDcpIHsKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKKyAgICBpZiAoaGFzX251bWJlcigpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICAgIHRoaXMtPm51bWJlcigpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgICAqdGhpcy0+b3B0aW9uc18pOworICAgIH0KKworICB9CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfbnVtYmVyKCkpIHsKKyAgICAgIHNldF9udW1iZXIoZnJvbS5udW1iZXIoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnM6Ok1lcmdlRnJvbShmcm9tLm9wdGlvbnMoKSk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgaWYgKCF0aGlzLT5vcHRpb25zXy0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpTd2FwKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBzdGQ6OnN3YXAobnVtYmVyXywgb3RoZXItPm51bWJlcl8pOworICBzdGQ6OnN3YXAob3B0aW9uc18sIG90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgYm9vbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cisgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKKyBib29sIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6aGFzX251bWJlcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cisgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KKyB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbnVtYmVyKCkgeworICBudW1iZXJfID0gMDsKKyAgY2xlYXJfaGFzX251bWJlcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpudW1iZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5udW1iZXIpCisgIHJldHVybiBudW1iZXJfOworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19udW1iZXIoKTsKKyAgbnVtYmVyXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubnVtYmVyKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgYm9vbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KKyB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyYgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KKyB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjprTWV0aG9kRmllbGROdW1iZXI7Citjb25zdCBpbnQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK1NlcnZpY2VEZXNjcmlwdG9yUHJvdG86OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpICwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSAgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIG9wdGlvbnNfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBvcHRpb25zXyA9IE5VTEw7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK1NlcnZpY2VEZXNjcmlwdG9yUHJvdG86On5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIG9wdGlvbnNfOworICB9Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gU2VydmljZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworU2VydmljZURlc2NyaXB0b3JQcm90byogU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgU2VydmljZURlc2NyaXB0b3JQcm90byogbiA9IG5ldyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiA1KSB7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgIH0KKyAgbWV0aG9kXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbWV0aG9kOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9tZXRob2Q6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX21ldGhvZCgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbWV0aG9kOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2Vfb3B0aW9uczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgcGFyc2Vfb3B0aW9uczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfb3B0aW9ucygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90byBtZXRob2QgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm1ldGhvZF9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgdGhpcy0+bWV0aG9kKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMywgKnRoaXMtPm9wdGlvbnNfLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VydmljZURlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+bmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5tZXRob2Rfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+bWV0aG9kKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAzLCAqdGhpcy0+b3B0aW9uc18sIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDUpIHsKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+bWV0aG9kX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5tZXRob2Rfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm1ldGhvZChpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBtZXRob2RfLk1lcmdlRnJvbShmcm9tLm1ldGhvZF8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfb3B0aW9ucygpKSB7CisgICAgICBtdXRhYmxlX29wdGlvbnMoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+bWV0aG9kKCkpKSByZXR1cm4gZmFsc2U7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgaWYgKCF0aGlzLT5vcHRpb25zXy0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6U3dhcChTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoU2VydmljZURlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgbWV0aG9kXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5tZXRob2RfKTsKKyAgc3RkOjpzd2FwKG9wdGlvbnNfLCBvdGhlci0+b3B0aW9uc18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gU2VydmljZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyBib29sIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIDo6c3RkOjpzdHJpbmcqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX25hbWUoKTsKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvIG1ldGhvZCA9IDI7CisgaW50IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om1ldGhvZF9zaXplKCkgY29uc3QgeworICByZXR1cm4gbWV0aG9kXy5zaXplKCk7Cit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9tZXRob2QoKSB7CisgIG1ldGhvZF8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byYgU2VydmljZURlc2NyaXB0b3JQcm90bzo6bWV0aG9kKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byogU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9tZXRob2QoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8qIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmFkZF9tZXRob2QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gbWV0aG9kXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvID4mCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjptZXRob2QoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+KgorU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9tZXRob2QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gJm1ldGhvZF87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyYgU2VydmljZURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KKyB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a0lucHV0VHlwZUZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a091dHB1dFR5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXI7Citjb25zdCBpbnQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprQ2xpZW50U3RyZWFtaW5nRmllbGROdW1iZXI7Citjb25zdCBpbnQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprU2VydmVyU3RyZWFtaW5nRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorCitNZXRob2REZXNjcmlwdG9yUHJvdG86Ok1ldGhvZERlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIG9wdGlvbnNfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKworTWV0aG9kRGVzY3JpcHRvclByb3RvOjpNZXRob2REZXNjcmlwdG9yUHJvdG8oY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlucHV0X3R5cGVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgb3V0cHV0X3R5cGVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgb3B0aW9uc18gPSBOVUxMOworICBjbGllbnRfc3RyZWFtaW5nXyA9IGZhbHNlOworICBzZXJ2ZXJfc3RyZWFtaW5nXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitNZXRob2REZXNjcmlwdG9yUHJvdG86On5NZXRob2REZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlucHV0X3R5cGVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG91dHB1dF90eXBlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgIGRlbGV0ZSBvcHRpb25zXzsKKyAgfQorfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBNZXRob2REZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitNZXRob2REZXNjcmlwdG9yUHJvdG8qIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitNZXRob2REZXNjcmlwdG9yUHJvdG8qIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIE1ldGhvZERlc2NyaXB0b3JQcm90byogbiA9IG5ldyBNZXRob2REZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OkNsZWFyKCkgeworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8TWV0aG9kRGVzY3JpcHRvclByb3RvKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiA2MykgeworICAgIFpSXyhjbGllbnRfc3RyZWFtaW5nXywgc2VydmVyX3N0cmVhbWluZ18pOworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfaW5wdXRfdHlwZSgpKSB7CisgICAgICBpbnB1dF90eXBlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfb3V0cHV0X3R5cGUoKSkgeworICAgICAgb3V0cHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zOjpDbGVhcigpOworICAgIH0KKyAgfQorCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9pbnB1dF90eXBlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGlucHV0X3R5cGUgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX2lucHV0X3R5cGU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2lucHV0X3R5cGUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+aW5wdXRfdHlwZSgpLmRhdGEoKSwgdGhpcy0+aW5wdXRfdHlwZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2Vfb3V0cHV0X3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgb3V0cHV0X3R5cGUgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX291dHB1dF90eXBlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9vdXRwdXRfdHlwZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5vdXRwdXRfdHlwZSgpLmRhdGEoKSwgdGhpcy0+b3V0cHV0X3R5cGUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDM0KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIG9wdGlvbnMgPSA0OworICAgICAgY2FzZSA0OiB7CisgICAgICAgIGlmICh0YWcgPT0gMzQpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDApKSBnb3RvIHBhcnNlX2NsaWVudF9zdHJlYW1pbmc7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGNsaWVudF9zdHJlYW1pbmcgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSA1OiB7CisgICAgICAgIGlmICh0YWcgPT0gNDApIHsKKyAgICAgICAgIHBhcnNlX2NsaWVudF9zdHJlYW1pbmc6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZjbGllbnRfc3RyZWFtaW5nXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2NsaWVudF9zdHJlYW1pbmcoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQ4KSkgZ290byBwYXJzZV9zZXJ2ZXJfc3RyZWFtaW5nOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgNjogeworICAgICAgICBpZiAodGFnID09IDQ4KSB7CisgICAgICAgICBwYXJzZV9zZXJ2ZXJfc3RyZWFtaW5nOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmc2VydmVyX3N0cmVhbWluZ18pKSk7CisgICAgICAgICAgc2V0X2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGlucHV0X3R5cGUgPSAyOworICBpZiAoaGFzX2lucHV0X3R5cGUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+aW5wdXRfdHlwZSgpLmRhdGEoKSwgdGhpcy0+aW5wdXRfdHlwZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDIsIHRoaXMtPmlucHV0X3R5cGUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBvdXRwdXRfdHlwZSA9IDM7CisgIGlmIChoYXNfb3V0cHV0X3R5cGUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+b3V0cHV0X3R5cGUoKS5kYXRhKCksIHRoaXMtPm91dHB1dF90eXBlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDMsIHRoaXMtPm91dHB1dF90eXBlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMgb3B0aW9ucyA9IDQ7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDQsICp0aGlzLT5vcHRpb25zXywgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgY2xpZW50X3N0cmVhbWluZyA9IDUgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfY2xpZW50X3N0cmVhbWluZygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCg1LCB0aGlzLT5jbGllbnRfc3RyZWFtaW5nKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHNlcnZlcl9zdHJlYW1pbmcgPSA2IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woNiwgdGhpcy0+c2VydmVyX3N0cmVhbWluZygpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBNZXRob2REZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgIGlmIChoYXNfaW5wdXRfdHlwZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5pbnB1dF90eXBlKCkuZGF0YSgpLCB0aGlzLT5pbnB1dF90eXBlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPmlucHV0X3R5cGUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBvdXRwdXRfdHlwZSA9IDM7CisgIGlmIChoYXNfb3V0cHV0X3R5cGUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+b3V0cHV0X3R5cGUoKS5kYXRhKCksIHRoaXMtPm91dHB1dF90eXBlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAzLCB0aGlzLT5vdXRwdXRfdHlwZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIG9wdGlvbnMgPSA0OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDQsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgY2xpZW50X3N0cmVhbWluZyA9IDUgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfY2xpZW50X3N0cmVhbWluZygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoNSwgdGhpcy0+Y2xpZW50X3N0cmVhbWluZygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19zZXJ2ZXJfc3RyZWFtaW5nKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSg2LCB0aGlzLT5zZXJ2ZXJfc3RyZWFtaW5nKCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiA2MykgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgICAgaWYgKGhhc19pbnB1dF90eXBlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmlucHV0X3R5cGUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKKyAgICBpZiAoaGFzX291dHB1dF90eXBlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm91dHB1dF90eXBlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2NsaWVudF9zdHJlYW1pbmcoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIHNlcnZlcl9zdHJlYW1pbmcgPSA2IFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfc2VydmVyX3N0cmVhbWluZygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICB9CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfaW5wdXRfdHlwZSgpKSB7CisgICAgICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgICAgIGlucHV0X3R5cGVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5pbnB1dF90eXBlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vdXRwdXRfdHlwZSgpKSB7CisgICAgICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgICAgICBvdXRwdXRfdHlwZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm91dHB1dF90eXBlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnM6Ok1lcmdlRnJvbShmcm9tLm9wdGlvbnMoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jbGllbnRfc3RyZWFtaW5nKCkpIHsKKyAgICAgIHNldF9jbGllbnRfc3RyZWFtaW5nKGZyb20uY2xpZW50X3N0cmVhbWluZygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSkgeworICAgICAgc2V0X3NlcnZlcl9zdHJlYW1pbmcoZnJvbS5zZXJ2ZXJfc3RyZWFtaW5nKCkpOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6U3dhcChNZXRob2REZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKE1ldGhvZERlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgaW5wdXRfdHlwZV8uU3dhcCgmb3RoZXItPmlucHV0X3R5cGVfKTsKKyAgb3V0cHV0X3R5cGVfLlN3YXAoJm90aGVyLT5vdXRwdXRfdHlwZV8pOworICBzdGQ6OnN3YXAob3B0aW9uc18sIG90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChjbGllbnRfc3RyZWFtaW5nXywgb3RoZXItPmNsaWVudF9zdHJlYW1pbmdfKTsKKyAgc3RkOjpzd2FwKHNlcnZlcl9zdHJlYW1pbmdfLCBvdGhlci0+c2VydmVyX3N0cmVhbWluZ18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBNZXRob2REZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IE1ldGhvZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1ldGhvZERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBNZXRob2REZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBpbnB1dF90eXBlID0gMjsKKyBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX2lucHV0X3R5cGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX2lucHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19pbnB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaW5wdXRfdHlwZSgpIHsKKyAgaW5wdXRfdHlwZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaW5wdXRfdHlwZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aW5wdXRfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUpCisgIHJldHVybiBpbnB1dF90eXBlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9pbnB1dF90eXBlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaW5wdXRfdHlwZSgpOworICBpbnB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2lucHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIGlucHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUpCit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9pbnB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgaW5wdXRfdHlwZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorfQorIDo6c3RkOjpzdHJpbmcqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9pbnB1dF90eXBlKCkgeworICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorICByZXR1cm4gaW5wdXRfdHlwZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfaW5wdXRfdHlwZSgpIHsKKyAgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKKyAgcmV0dXJuIGlucHV0X3R5cGVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfaW5wdXRfdHlwZSg6OnN0ZDo6c3RyaW5nKiBpbnB1dF90eXBlKSB7CisgIGlmIChpbnB1dF90eXBlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaW5wdXRfdHlwZSgpOworICB9CisgIGlucHV0X3R5cGVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpbnB1dF90eXBlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgb3V0cHV0X3R5cGUgPSAzOworIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfb3V0cHV0X3R5cGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX291dHB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3V0cHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vdXRwdXRfdHlwZSgpIHsKKyAgb3V0cHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX291dHB1dF90eXBlKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpvdXRwdXRfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorICByZXR1cm4gb3V0cHV0X3R5cGVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSkKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfb3V0cHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX291dHB1dF90eXBlKCkgeworICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCisgIHJldHVybiBvdXRwdXRfdHlwZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3V0cHV0X3R5cGUoKSB7CisgIGNsZWFyX2hhc19vdXRwdXRfdHlwZSgpOworICByZXR1cm4gb3V0cHV0X3R5cGVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3V0cHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogb3V0cHV0X3R5cGUpIHsKKyAgaWYgKG91dHB1dF90eXBlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX291dHB1dF90eXBlKCk7CisgIH0KKyAgb3V0cHV0X3R5cGVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBvdXRwdXRfdHlwZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKyBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zJiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogdGVtcCA9IG9wdGlvbnNfOworICBvcHRpb25zXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorfQorCisvLyBvcHRpb25hbCBib29sIGNsaWVudF9zdHJlYW1pbmcgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfY2xpZW50X3N0cmVhbWluZygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2NsaWVudF9zdHJlYW1pbmcoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9jbGllbnRfc3RyZWFtaW5nKCkgeworICBjbGllbnRfc3RyZWFtaW5nXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2xpZW50X3N0cmVhbWluZygpOworfQorIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGllbnRfc3RyZWFtaW5nKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uY2xpZW50X3N0cmVhbWluZykKKyAgcmV0dXJuIGNsaWVudF9zdHJlYW1pbmdfOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfY2xpZW50X3N0cmVhbWluZyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpOworICBjbGllbnRfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uY2xpZW50X3N0cmVhbWluZykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX3NlcnZlcl9zdHJlYW1pbmcoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMjB1KSAhPSAwOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDIwdTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfc2VydmVyX3N0cmVhbWluZygpIHsKKyAgc2VydmVyX3N0cmVhbWluZ18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKK30KKyBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2VydmVyX3N0cmVhbWluZygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLnNlcnZlcl9zdHJlYW1pbmcpCisgIHJldHVybiBzZXJ2ZXJfc3RyZWFtaW5nXzsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X3NlcnZlcl9zdHJlYW1pbmcoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKKyAgc2VydmVyX3N0cmVhbWluZ18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLnNlcnZlcl9zdHJlYW1pbmcpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgc3dpdGNoKHZhbHVlKSB7CisgICAgY2FzZSAxOgorICAgIGNhc2UgMjoKKyAgICBjYXNlIDM6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IEZpbGVPcHRpb25zX09wdGltaXplTW9kZSBGaWxlT3B0aW9uczo6U1BFRUQ7Citjb25zdCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgRmlsZU9wdGlvbnM6OkNPREVfU0laRTsKK2NvbnN0IEZpbGVPcHRpb25zX09wdGltaXplTW9kZSBGaWxlT3B0aW9uczo6TElURV9SVU5USU1FOworY29uc3QgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIEZpbGVPcHRpb25zOjpPcHRpbWl6ZU1vZGVfTUlOOworY29uc3QgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIEZpbGVPcHRpb25zOjpPcHRpbWl6ZU1vZGVfTUFYOworY29uc3QgaW50IEZpbGVPcHRpb25zOjpPcHRpbWl6ZU1vZGVfQVJSQVlTSVpFOworI2VuZGlmICAvLyBfTVNDX1ZFUgorI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IEZpbGVPcHRpb25zOjprSmF2YVBhY2thZ2VGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0phdmFPdXRlckNsYXNzbmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprSmF2YU11bHRpcGxlRmlsZXNGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0phdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2hGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0phdmFTdHJpbmdDaGVja1V0ZjhGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a09wdGltaXplRm9yRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtHb1BhY2thZ2VGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0NjR2VuZXJpY1NlcnZpY2VzRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtKYXZhR2VuZXJpY1NlcnZpY2VzRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtQeUdlbmVyaWNTZXJ2aWNlc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprQ2NFbmFibGVBcmVuYXNGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a09iamNDbGFzc1ByZWZpeEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworRmlsZU9wdGlvbnM6OkZpbGVPcHRpb25zKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorfQorCit2b2lkIEZpbGVPcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0ZpbGVPcHRpb25zOjpGaWxlT3B0aW9ucyhjb25zdCBGaWxlT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucykKK30KKwordm9pZCBGaWxlT3B0aW9uczo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGphdmFfcGFja2FnZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IGZhbHNlOworICBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF8gPSBmYWxzZTsKKyAgamF2YV9zdHJpbmdfY2hlY2tfdXRmOF8gPSBmYWxzZTsKKyAgb3B0aW1pemVfZm9yXyA9IDE7CisgIGdvX3BhY2thZ2VfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2NfZ2VuZXJpY19zZXJ2aWNlc18gPSBmYWxzZTsKKyAgamF2YV9nZW5lcmljX3NlcnZpY2VzXyA9IGZhbHNlOworICBweV9nZW5lcmljX3NlcnZpY2VzXyA9IGZhbHNlOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjY19lbmFibGVfYXJlbmFzXyA9IGZhbHNlOworICBvYmpjX2NsYXNzX3ByZWZpeF8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitGaWxlT3B0aW9uczo6fkZpbGVPcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBGaWxlT3B0aW9uczo6U2hhcmVkRHRvcigpIHsKKyAgamF2YV9wYWNrYWdlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgZ29fcGFja2FnZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgb2JqY19jbGFzc19wcmVmaXhfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBGaWxlT3B0aW9uczo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEZpbGVPcHRpb25zOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEZpbGVPcHRpb25zX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBGaWxlT3B0aW9ucyYgRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0ZpbGVPcHRpb25zKiBGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitGaWxlT3B0aW9ucyogRmlsZU9wdGlvbnM6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBGaWxlT3B0aW9ucyogbiA9IG5ldyBGaWxlT3B0aW9uczsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEZpbGVPcHRpb25zOjpDbGVhcigpIHsKKyAgX2V4dGVuc2lvbnNfLkNsZWFyKCk7CisjZGVmaW5lIFpSX0hFTFBFUl8oZikgcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oXAorICAmcmVpbnRlcnByZXRfY2FzdDxGaWxlT3B0aW9ucyo+KDE2KS0+ZikKKworI2RlZmluZSBaUl8oZmlyc3QsIGxhc3QpIGRvIHtcCisgIDo6bWVtc2V0KCZmaXJzdCwgMCxcCisgICAgICAgICAgIFpSX0hFTFBFUl8obGFzdCkgLSBaUl9IRUxQRVJfKGZpcnN0KSArIHNpemVvZihsYXN0KSk7XAorfSB3aGlsZSAoMCkKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMjU1KSB7CisgICAgWlJfKGphdmFfbXVsdGlwbGVfZmlsZXNfLCBjY19nZW5lcmljX3NlcnZpY2VzXyk7CisgICAgaWYgKGhhc19qYXZhX3BhY2thZ2UoKSkgeworICAgICAgamF2YV9wYWNrYWdlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkgeworICAgICAgamF2YV9vdXRlcl9jbGFzc25hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgb3B0aW1pemVfZm9yXyA9IDE7CisgICAgaWYgKGhhc19nb19wYWNrYWdlKCkpIHsKKyAgICAgIGdvX3BhY2thZ2VfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKyAgaWYgKF9oYXNfYml0c19bOCAvIDMyXSAmIDc5MzYpIHsKKyAgICBaUl8oamF2YV9nZW5lcmljX3NlcnZpY2VzXywgY2NfZW5hYmxlX2FyZW5hc18pOworICAgIGlmIChoYXNfb2JqY19jbGFzc19wcmVmaXgoKSkgeworICAgICAgb2JqY19jbGFzc19wcmVmaXhfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKworI3VuZGVmIFpSX0hFTFBFUl8KKyN1bmRlZiBaUl8KKworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRmlsZU9wdGlvbnM6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTYzODMpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9wYWNrYWdlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2phdmFfcGFja2FnZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5qYXZhX3BhY2thZ2UoKS5kYXRhKCksIHRoaXMtPmphdmFfcGFja2FnZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNjYpKSBnb3RvIHBhcnNlX2phdmFfb3V0ZXJfY2xhc3NuYW1lOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gODsKKyAgICAgIGNhc2UgODogeworICAgICAgICBpZiAodGFnID09IDY2KSB7CisgICAgICAgICBwYXJzZV9qYXZhX291dGVyX2NsYXNzbmFtZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKS5kYXRhKCksIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDcyKSkgZ290byBwYXJzZV9vcHRpbWl6ZV9mb3I7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworICAgICAgY2FzZSA5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzIpIHsKKyAgICAgICAgIHBhcnNlX29wdGltaXplX2ZvcjoKKyAgICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkpOworICAgICAgICAgIGlmICg6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zX09wdGltaXplTW9kZV9Jc1ZhbGlkKHZhbHVlKSkgeworICAgICAgICAgICAgc2V0X29wdGltaXplX2ZvcihzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgPih2YWx1ZSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCg5LCB2YWx1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoODApKSBnb3RvIHBhcnNlX2phdmFfbXVsdGlwbGVfZmlsZXM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGphdmFfbXVsdGlwbGVfZmlsZXMgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMTA6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4MCkgeworICAgICAgICAgcGFyc2VfamF2YV9tdWx0aXBsZV9maWxlczoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmphdmFfbXVsdGlwbGVfZmlsZXNfKSkpOworICAgICAgICAgIHNldF9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoOTApKSBnb3RvIHBhcnNlX2dvX3BhY2thZ2U7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgZ29fcGFja2FnZSA9IDExOworICAgICAgY2FzZSAxMTogeworICAgICAgICBpZiAodGFnID09IDkwKSB7CisgICAgICAgICBwYXJzZV9nb19wYWNrYWdlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9nb19wYWNrYWdlKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmdvX3BhY2thZ2UoKS5kYXRhKCksIHRoaXMtPmdvX3BhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjgpKSBnb3RvIHBhcnNlX2NjX2dlbmVyaWNfc2VydmljZXM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGNjX2dlbmVyaWNfc2VydmljZXMgPSAxNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMTY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMjgpIHsKKyAgICAgICAgIHBhcnNlX2NjX2dlbmVyaWNfc2VydmljZXM6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZjY19nZW5lcmljX3NlcnZpY2VzXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDEzNikpIGdvdG8gcGFyc2VfamF2YV9nZW5lcmljX3NlcnZpY2VzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSAxNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMTc6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMzYpIHsKKyAgICAgICAgIHBhcnNlX2phdmFfZ2VuZXJpY19zZXJ2aWNlczoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmphdmFfZ2VuZXJpY19zZXJ2aWNlc18pKSk7CisgICAgICAgICAgc2V0X2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE0NCkpIGdvdG8gcGFyc2VfcHlfZ2VuZXJpY19zZXJ2aWNlczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IDE4IFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAxODogeworICAgICAgICBpZiAodGFnID09IDE0NCkgeworICAgICAgICAgcGFyc2VfcHlfZ2VuZXJpY19zZXJ2aWNlczoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnB5X2dlbmVyaWNfc2VydmljZXNfKSkpOworICAgICAgICAgIHNldF9oYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTYwKSkgZ290byBwYXJzZV9qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSAyMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMjA6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNjApIHsKKyAgICAgICAgIHBhcnNlX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2hfKSkpOworICAgICAgICAgIHNldF9oYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4NCkpIGdvdG8gcGFyc2VfZGVwcmVjYXRlZDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDIzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAyMzogeworICAgICAgICBpZiAodGFnID09IDE4NCkgeworICAgICAgICAgcGFyc2VfZGVwcmVjYXRlZDoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjE2KSkgZ290byBwYXJzZV9qYXZhX3N0cmluZ19jaGVja191dGY4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX3N0cmluZ19jaGVja191dGY4ID0gMjcgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDI3OiB7CisgICAgICAgIGlmICh0YWcgPT0gMjE2KSB7CisgICAgICAgICBwYXJzZV9qYXZhX3N0cmluZ19jaGVja191dGY4OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmamF2YV9zdHJpbmdfY2hlY2tfdXRmOF8pKSk7CisgICAgICAgICAgc2V0X2hhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNDgpKSBnb3RvIHBhcnNlX2NjX2VuYWJsZV9hcmVuYXM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMzE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNDgpIHsKKyAgICAgICAgIHBhcnNlX2NjX2VuYWJsZV9hcmVuYXM6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZjY19lbmFibGVfYXJlbmFzXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI5MCkpIGdvdG8gcGFyc2Vfb2JqY19jbGFzc19wcmVmaXg7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKyAgICAgIGNhc2UgMzY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyOTApIHsKKyAgICAgICAgIHBhcnNlX29iamNfY2xhc3NfcHJlZml4OgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9vYmpjX2NsYXNzX3ByZWZpeCgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5vYmpjX2NsYXNzX3ByZWZpeCgpLmRhdGEoKSwgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgICAgICBjYXNlIDk5OTogeworICAgICAgICBpZiAodGFnID09IDc5OTQpIHsKKyAgICAgICAgIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF91bmludGVycHJldGVkX29wdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBpZiAoKDgwMDB1IDw9IHRhZykpIHsKKyAgICAgICAgICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBGaWxlT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworICBpZiAoaGFzX2phdmFfcGFja2FnZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5qYXZhX3BhY2thZ2UoKS5kYXRhKCksIHRoaXMtPmphdmFfcGFja2FnZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5qYXZhX3BhY2thZ2UoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX291dGVyX2NsYXNzbmFtZSA9IDg7CisgIGlmIChoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKS5kYXRhKCksIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgOCwgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvciA9IDkgW2RlZmF1bHQgPSBTUEVFRF07CisgIGlmIChoYXNfb3B0aW1pemVfZm9yKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKAorICAgICAgOSwgdGhpcy0+b3B0aW1pemVfZm9yKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFfbXVsdGlwbGVfZmlsZXMgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDEwLCB0aGlzLT5qYXZhX211bHRpcGxlX2ZpbGVzKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZ29fcGFja2FnZSA9IDExOworICBpZiAoaGFzX2dvX3BhY2thZ2UoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+Z29fcGFja2FnZSgpLmRhdGEoKSwgdGhpcy0+Z29fcGFja2FnZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMTEsIHRoaXMtPmdvX3BhY2thZ2UoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IDE2IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMTYsIHRoaXMtPmNjX2dlbmVyaWNfc2VydmljZXMoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzID0gMTcgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDE3LCB0aGlzLT5qYXZhX2dlbmVyaWNfc2VydmljZXMoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IDE4IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMTgsIHRoaXMtPnB5X2dlbmVyaWNfc2VydmljZXMoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSAyMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgyMCwgdGhpcy0+amF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDIzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMjMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IDI3IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMjcsIHRoaXMtPmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgY2NfZW5hYmxlX2FyZW5hcyA9IDMxIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2NjX2VuYWJsZV9hcmVuYXMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMzEsIHRoaXMtPmNjX2VuYWJsZV9hcmVuYXMoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBvYmpjX2NsYXNzX3ByZWZpeCA9IDM2OworICBpZiAoaGFzX29iamNfY2xhc3NfcHJlZml4KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm9iamNfY2xhc3NfcHJlZml4KCkuZGF0YSgpLCB0aGlzLT5vYmpjX2NsYXNzX3ByZWZpeCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDM2LCB0aGlzLT5vYmpjX2NsYXNzX3ByZWZpeCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA5OTksIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gRXh0ZW5zaW9uIHJhbmdlIFsxMDAwLCA1MzY4NzA5MTIpCisgIF9leHRlbnNpb25zXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIG91dHB1dCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEZpbGVPcHRpb25zOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfcGFja2FnZSA9IDE7CisgIGlmIChoYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmphdmFfcGFja2FnZSgpLmRhdGEoKSwgdGhpcy0+amF2YV9wYWNrYWdlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5qYXZhX3BhY2thZ2UoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX291dGVyX2NsYXNzbmFtZSA9IDg7CisgIGlmIChoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKS5kYXRhKCksIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDgsIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworICBpZiAoaGFzX29wdGltaXplX2ZvcigpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bVRvQXJyYXkoCisgICAgICA5LCB0aGlzLT5vcHRpbWl6ZV9mb3IoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9tdWx0aXBsZV9maWxlcyA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDEwLCB0aGlzLT5qYXZhX211bHRpcGxlX2ZpbGVzKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZ29fcGFja2FnZSA9IDExOworICBpZiAoaGFzX2dvX3BhY2thZ2UoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+Z29fcGFja2FnZSgpLmRhdGEoKSwgdGhpcy0+Z29fcGFja2FnZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDExLCB0aGlzLT5nb19wYWNrYWdlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGNjX2dlbmVyaWNfc2VydmljZXMgPSAxNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19jY19nZW5lcmljX3NlcnZpY2VzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgxNiwgdGhpcy0+Y2NfZ2VuZXJpY19zZXJ2aWNlcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSAxNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDE3LCB0aGlzLT5qYXZhX2dlbmVyaWNfc2VydmljZXMoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IDE4IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDE4LCB0aGlzLT5weV9nZW5lcmljX3NlcnZpY2VzKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDIwLCB0aGlzLT5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMjMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMjMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IDI3IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDI3LCB0aGlzLT5qYXZhX3N0cmluZ19jaGVja191dGY4KCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19jY19lbmFibGVfYXJlbmFzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgzMSwgdGhpcy0+Y2NfZW5hYmxlX2FyZW5hcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG9iamNfY2xhc3NfcHJlZml4ID0gMzY7CisgIGlmIChoYXNfb2JqY19jbGFzc19wcmVmaXgoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKS5kYXRhKCksIHRoaXMtPm9iamNfY2xhc3NfcHJlZml4KCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4Iik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDM2LCB0aGlzLT5vYmpjX2NsYXNzX3ByZWZpeCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgdGFyZ2V0ID0gX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIHRhcmdldCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRmlsZU9wdGlvbnM6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDI1NSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworICAgIGlmIChoYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmphdmFfcGFja2FnZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworICAgIGlmIChoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IDIwIFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjggPSAyNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworICAgIGlmIChoYXNfb3B0aW1pemVfZm9yKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5vcHRpbWl6ZV9mb3IoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKKyAgICBpZiAoaGFzX2dvX3BhY2thZ2UoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+Z29fcGFja2FnZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGNjX2dlbmVyaWNfc2VydmljZXMgPSAxNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgfQorICBpZiAoX2hhc19iaXRzX1s4IC8gMzJdICYgNzkzNikgeworICAgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzID0gMTcgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2NjX2VuYWJsZV9hcmVuYXMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKyAgICBpZiAoaGFzX29iamNfY2xhc3NfcHJlZml4KCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMiArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm9iamNfY2xhc3NfcHJlZml4KCkpOworICAgIH0KKworICB9CisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGaWxlT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWxlT3B0aW9ucyogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IEZpbGVPcHRpb25zKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZpbGVPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgRmlsZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLk1lcmdlRnJvbShmcm9tLnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICAgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgICAgICBqYXZhX3BhY2thZ2VfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5qYXZhX3BhY2thZ2VfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkpIHsKKyAgICAgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgICAgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uamF2YV9vdXRlcl9jbGFzc25hbWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKSkgeworICAgICAgc2V0X2phdmFfbXVsdGlwbGVfZmlsZXMoZnJvbS5qYXZhX211bHRpcGxlX2ZpbGVzKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSkgeworICAgICAgc2V0X2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKGZyb20uamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCkpIHsKKyAgICAgIHNldF9qYXZhX3N0cmluZ19jaGVja191dGY4KGZyb20uamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX29wdGltaXplX2ZvcigpKSB7CisgICAgICBzZXRfb3B0aW1pemVfZm9yKGZyb20ub3B0aW1pemVfZm9yKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZ29fcGFja2FnZSgpKSB7CisgICAgICBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgICAgIGdvX3BhY2thZ2VfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5nb19wYWNrYWdlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jY19nZW5lcmljX3NlcnZpY2VzKCkpIHsKKyAgICAgIHNldF9jY19nZW5lcmljX3NlcnZpY2VzKGZyb20uY2NfZ2VuZXJpY19zZXJ2aWNlcygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2hhc19iaXRzX1s4IC8gMzJdICYgKDB4ZmZ1IDw8ICg4ICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgc2V0X2phdmFfZ2VuZXJpY19zZXJ2aWNlcyhmcm9tLmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgc2V0X3B5X2dlbmVyaWNfc2VydmljZXMoZnJvbS5weV9nZW5lcmljX3NlcnZpY2VzKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICBzZXRfZGVwcmVjYXRlZChmcm9tLmRlcHJlY2F0ZWQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jY19lbmFibGVfYXJlbmFzKCkpIHsKKyAgICAgIHNldF9jY19lbmFibGVfYXJlbmFzKGZyb20uY2NfZW5hYmxlX2FyZW5hcygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX29iamNfY2xhc3NfcHJlZml4KCkpIHsKKyAgICAgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgICAgIG9iamNfY2xhc3NfcHJlZml4Xy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ub2JqY19jbGFzc19wcmVmaXhfKTsKKyAgICB9CisgIH0KKyAgX2V4dGVuc2lvbnNfLk1lcmdlRnJvbShmcm9tLl9leHRlbnNpb25zXyk7CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEZpbGVPcHRpb25zOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEZpbGVPcHRpb25zOjpDb3B5RnJvbShjb25zdCBGaWxlT3B0aW9ucyYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRmlsZU9wdGlvbnM6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT51bmludGVycHJldGVkX29wdGlvbigpKSkgcmV0dXJuIGZhbHNlOworCisgIGlmICghX2V4dGVuc2lvbnNfLklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRmlsZU9wdGlvbnM6OlN3YXAoRmlsZU9wdGlvbnMqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpJbnRlcm5hbFN3YXAoRmlsZU9wdGlvbnMqIG90aGVyKSB7CisgIGphdmFfcGFja2FnZV8uU3dhcCgmb3RoZXItPmphdmFfcGFja2FnZV8pOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU3dhcCgmb3RoZXItPmphdmFfb3V0ZXJfY2xhc3NuYW1lXyk7CisgIHN0ZDo6c3dhcChqYXZhX211bHRpcGxlX2ZpbGVzXywgb3RoZXItPmphdmFfbXVsdGlwbGVfZmlsZXNfKTsKKyAgc3RkOjpzd2FwKGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXywgb3RoZXItPmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXyk7CisgIHN0ZDo6c3dhcChqYXZhX3N0cmluZ19jaGVja191dGY4Xywgb3RoZXItPmphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfKTsKKyAgc3RkOjpzd2FwKG9wdGltaXplX2Zvcl8sIG90aGVyLT5vcHRpbWl6ZV9mb3JfKTsKKyAgZ29fcGFja2FnZV8uU3dhcCgmb3RoZXItPmdvX3BhY2thZ2VfKTsKKyAgc3RkOjpzd2FwKGNjX2dlbmVyaWNfc2VydmljZXNfLCBvdGhlci0+Y2NfZ2VuZXJpY19zZXJ2aWNlc18pOworICBzdGQ6OnN3YXAoamF2YV9nZW5lcmljX3NlcnZpY2VzXywgb3RoZXItPmphdmFfZ2VuZXJpY19zZXJ2aWNlc18pOworICBzdGQ6OnN3YXAocHlfZ2VuZXJpY19zZXJ2aWNlc18sIG90aGVyLT5weV9nZW5lcmljX3NlcnZpY2VzXyk7CisgIHN0ZDo6c3dhcChkZXByZWNhdGVkXywgb3RoZXItPmRlcHJlY2F0ZWRfKTsKKyAgc3RkOjpzd2FwKGNjX2VuYWJsZV9hcmVuYXNfLCBvdGhlci0+Y2NfZW5hYmxlX2FyZW5hc18pOworICBvYmpjX2NsYXNzX3ByZWZpeF8uU3dhcCgmb3RoZXItPm9iamNfY2xhc3NfcHJlZml4Xyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEZpbGVPcHRpb25zOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBGaWxlT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZpbGVPcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEZpbGVPcHRpb25zCisKKy8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfamF2YV9wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfcGFja2FnZSgpIHsKKyAgamF2YV9wYWNrYWdlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uczo6amF2YV9wYWNrYWdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCisgIHJldHVybiBqYXZhX3BhY2thZ2VfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIGphdmFfcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX3BhY2thZ2UoKTsKKyAgamF2YV9wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSkKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICBqYXZhX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6Om11dGFibGVfamF2YV9wYWNrYWdlKCkgeworICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorICByZXR1cm4gamF2YV9wYWNrYWdlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX2phdmFfcGFja2FnZSgpIHsKKyAgY2xlYXJfaGFzX2phdmFfcGFja2FnZSgpOworICByZXR1cm4gamF2YV9wYWNrYWdlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfamF2YV9wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIGphdmFfcGFja2FnZSkgeworICBpZiAoamF2YV9wYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKTsKKyAgfQorICBqYXZhX3BhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBqYXZhX3BhY2thZ2UpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkgeworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uczo6amF2YV9vdXRlcl9jbGFzc25hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6Om11dGFibGVfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIGNsZWFyX2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9qYXZhX291dGVyX2NsYXNzbmFtZSg6OnN0ZDo6c3RyaW5nKiBqYXZhX291dGVyX2NsYXNzbmFtZSkgeworICBpZiAoamF2YV9vdXRlcl9jbGFzc25hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgfQorICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGphdmFfb3V0ZXJfY2xhc3NuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorfQorCisvLyBvcHRpb25hbCBib29sIGphdmFfbXVsdGlwbGVfZmlsZXMgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9tdWx0aXBsZV9maWxlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfbXVsdGlwbGVfZmlsZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfbXVsdGlwbGVfZmlsZXMpCisgIHJldHVybiBqYXZhX211bHRpcGxlX2ZpbGVzXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9tdWx0aXBsZV9maWxlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX211bHRpcGxlX2ZpbGVzKQorfQorCisvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07CisgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSB7CisgIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKTsKK30KKyBib29sIEZpbGVPcHRpb25zOjpqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2gpCisgIHJldHVybiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF87Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworICBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2gpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IDI3IFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDEwdSkgIT0gMDsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCk7Cit9CisgYm9vbCBGaWxlT3B0aW9uczo6amF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9zdHJpbmdfY2hlY2tfdXRmOCkKKyAgcmV0dXJuIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3N0cmluZ19jaGVja191dGY4KGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCk7CisgIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvciA9IDkgW2RlZmF1bHQgPSBTUEVFRF07CisgYm9vbCBGaWxlT3B0aW9uczo6aGFzX29wdGltaXplX2ZvcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19vcHRpbWl6ZV9mb3IoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX29wdGltaXplX2ZvcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfb3B0aW1pemVfZm9yKCkgeworICBvcHRpbWl6ZV9mb3JfID0gMTsKKyAgY2xlYXJfaGFzX29wdGltaXplX2ZvcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIEZpbGVPcHRpb25zOjpvcHRpbWl6ZV9mb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9wdGltaXplX2ZvcikKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zX09wdGltaXplTW9kZSA+KG9wdGltaXplX2Zvcl8pOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vcHRpbWl6ZV9mb3IoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19vcHRpbWl6ZV9mb3IoKTsKKyAgb3B0aW1pemVfZm9yXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vcHRpbWl6ZV9mb3IpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBnb19wYWNrYWdlID0gMTE7CisgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2dvX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfZ29fcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDQwdTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfZ29fcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA0MHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfZ29fcGFja2FnZSgpIHsKKyAgZ29fcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZ29fcGFja2FnZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zOjpnb19wYWNrYWdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlKQorICByZXR1cm4gZ29fcGFja2FnZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9nb19wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICBnb19wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlKQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9nb19wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICBnb19wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2dvX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICBnb19wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6bXV0YWJsZV9nb19wYWNrYWdlKCkgeworICBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCisgIHJldHVybiBnb19wYWNrYWdlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX2dvX3BhY2thZ2UoKSB7CisgIGNsZWFyX2hhc19nb19wYWNrYWdlKCk7CisgIHJldHVybiBnb19wYWNrYWdlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfZ29fcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBnb19wYWNrYWdlKSB7CisgIGlmIChnb19wYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZ29fcGFja2FnZSgpOworICB9CisgIGdvX3BhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBnb19wYWNrYWdlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IDE2IFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19jY19nZW5lcmljX3NlcnZpY2VzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDgwdSkgIT0gMDsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwODB1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIGNjX2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7Cit9CisgYm9vbCBGaWxlT3B0aW9uczo6Y2NfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY2NfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIGNjX2dlbmVyaWNfc2VydmljZXNfOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9jY19nZW5lcmljX3NlcnZpY2VzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIGNjX2dlbmVyaWNfc2VydmljZXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2dlbmVyaWNfc2VydmljZXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzID0gMTcgW2RlZmF1bHQgPSBmYWxzZV07CisgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDEwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDEwMHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDEwMHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBqYXZhX2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKK30KKyBib29sIEZpbGVPcHRpb25zOjpqYXZhX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIGphdmFfZ2VuZXJpY19zZXJ2aWNlc187Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGphdmFfZ2VuZXJpY19zZXJ2aWNlc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmljX3NlcnZpY2VzKQorfQorCisvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIEZpbGVPcHRpb25zOjpoYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDIwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAyMDB1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMjAwdTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBweV9nZW5lcmljX3NlcnZpY2VzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OnB5X2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnB5X2dlbmVyaWNfc2VydmljZXMpCisgIHJldHVybiBweV9nZW5lcmljX3NlcnZpY2VzXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfcHlfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpOworICBweV9nZW5lcmljX3NlcnZpY2VzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5weV9nZW5lcmljX3NlcnZpY2VzKQorfQorCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIEZpbGVPcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDQwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA0MDB1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwNDAwdTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIEZpbGVPcHRpb25zOjpoYXNfY2NfZW5hYmxlX2FyZW5hcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDgwMHUpICE9IDA7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19jY19lbmFibGVfYXJlbmFzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA4MDB1OworfQorIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19jY19lbmFibGVfYXJlbmFzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwODAwdTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9jY19lbmFibGVfYXJlbmFzKCkgeworICBjY19lbmFibGVfYXJlbmFzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2NfZW5hYmxlX2FyZW5hcygpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmNjX2VuYWJsZV9hcmVuYXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2VuYWJsZV9hcmVuYXMpCisgIHJldHVybiBjY19lbmFibGVfYXJlbmFzXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfY2NfZW5hYmxlX2FyZW5hcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2NfZW5hYmxlX2FyZW5hcygpOworICBjY19lbmFibGVfYXJlbmFzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jY19lbmFibGVfYXJlbmFzKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKyBib29sIEZpbGVPcHRpb25zOjpoYXNfb2JqY19jbGFzc19wcmVmaXgoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDEwMDB1KSAhPSAwOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMTAwMHU7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAxMDAwdTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9vYmpjX2NsYXNzX3ByZWZpeCgpIHsKKyAgb2JqY19jbGFzc19wcmVmaXhfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZU9wdGlvbnM6Om9iamNfY2xhc3NfcHJlZml4KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCkKKyAgcmV0dXJuIG9iamNfY2xhc3NfcHJlZml4Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgb2JqY19jbGFzc19wcmVmaXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vYmpjX2NsYXNzX3ByZWZpeChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIG9iamNfY2xhc3NfcHJlZml4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vYmpjX2NsYXNzX3ByZWZpeChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICBvYmpjX2NsYXNzX3ByZWZpeF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjptdXRhYmxlX29iamNfY2xhc3NfcHJlZml4KCkgeworICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCkKKyAgcmV0dXJuIG9iamNfY2xhc3NfcHJlZml4Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX29iamNfY2xhc3NfcHJlZml4KCkgeworICBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgcmV0dXJuIG9iamNfY2xhc3NfcHJlZml4Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfb2JqY19jbGFzc19wcmVmaXgoOjpzdGQ6OnN0cmluZyogb2JqY19jbGFzc19wcmVmaXgpIHsKKyAgaWYgKG9iamNfY2xhc3NfcHJlZml4ICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIH0KKyAgb2JqY19jbGFzc19wcmVmaXhfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBvYmpjX2NsYXNzX3ByZWZpeCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworIGludCBGaWxlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRmlsZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRmlsZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEZpbGVPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitGaWxlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorRmlsZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgTWVzc2FnZU9wdGlvbnM6OmtNZXNzYWdlU2V0V2lyZUZvcm1hdEZpZWxkTnVtYmVyOworY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zOjprTm9TdGFuZGFyZERlc2NyaXB0b3JBY2Nlc3NvckZpZWxkTnVtYmVyOworY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zOjprTWFwRW50cnlGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNZXNzYWdlT3B0aW9uczo6a1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK01lc3NhZ2VPcHRpb25zOjpNZXNzYWdlT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitNZXNzYWdlT3B0aW9uczo6TWVzc2FnZU9wdGlvbnMoY29uc3QgTWVzc2FnZU9wdGlvbnMmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8gPSBmYWxzZTsKKyAgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8gPSBmYWxzZTsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgbWFwX2VudHJ5XyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitNZXNzYWdlT3B0aW9uczo6fk1lc3NhZ2VPcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VPcHRpb25zOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogTWVzc2FnZU9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IE1lc3NhZ2VPcHRpb25zJiBNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworTWVzc2FnZU9wdGlvbnMqIE1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK01lc3NhZ2VPcHRpb25zKiBNZXNzYWdlT3B0aW9uczo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIE1lc3NhZ2VPcHRpb25zKiBuID0gbmV3IE1lc3NhZ2VPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OkNsZWFyKCkgeworICBfZXh0ZW5zaW9uc18uQ2xlYXIoKTsKKyNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcCisgICZyZWludGVycHJldF9jYXN0PE1lc3NhZ2VPcHRpb25zKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIFpSXyhtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8sIG1hcF9lbnRyeV8pOworCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBNZXNzYWdlT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxNjM4Myk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfKSkpOworICAgICAgICAgIHNldF9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yID0gMiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8pKSk7CisgICAgICAgICAgc2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNCkpIGdvdG8gcGFyc2VfZGVwcmVjYXRlZDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNCkgeworICAgICAgICAgcGFyc2VfZGVwcmVjYXRlZDoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTYpKSBnb3RvIHBhcnNlX21hcF9lbnRyeTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU2KSB7CisgICAgICAgICBwYXJzZV9tYXBfZW50cnk6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZtYXBfZW50cnlfKSkpOworICAgICAgICAgIHNldF9oYXNfbWFwX2VudHJ5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgICAgIGNhc2UgOTk5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzk5NCkgeworICAgICAgICAgcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDc5OTQpKSBnb3RvIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIGlmICgoODAwMHUgPD0gdGFnKSkgeworICAgICAgICAgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCBkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIE1lc3NhZ2VPcHRpb25zOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKKyAgLy8gb3B0aW9uYWwgYm9vbCBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMSwgdGhpcy0+bWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IDIgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgyLCB0aGlzLT5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMywgdGhpcy0+ZGVwcmVjYXRlZCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBtYXBfZW50cnkgPSA3OworICBpZiAoaGFzX21hcF9lbnRyeSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCg3LCB0aGlzLT5tYXBfZW50cnkoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBNZXNzYWdlT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgxLCB0aGlzLT5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yID0gMiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgyLCB0aGlzLT5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgaWYgKGhhc19tYXBfZW50cnkoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDcsIHRoaXMtPm1hcF9lbnRyeSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgdGFyZ2V0ID0gX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIHRhcmdldCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgTWVzc2FnZU9wdGlvbnM6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDE1KSB7CisgICAgLy8gb3B0aW9uYWwgYm9vbCBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IDIgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIG1hcF9lbnRyeSA9IDc7CisgICAgaWYgKGhhc19tYXBfZW50cnkoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIHRvdGFsX3NpemUgKz0gMiAqIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSkpOworICB9CisKKyAgdG90YWxfc2l6ZSArPSBfZXh0ZW5zaW9uc18uQnl0ZVNpemUoKTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBNZXNzYWdlT3B0aW9ucyo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIHNldF9tZXNzYWdlX3NldF93aXJlX2Zvcm1hdChmcm9tLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpKSB7CisgICAgICBzZXRfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcihmcm9tLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19kZXByZWNhdGVkKCkpIHsKKyAgICAgIHNldF9kZXByZWNhdGVkKGZyb20uZGVwcmVjYXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX21hcF9lbnRyeSgpKSB7CisgICAgICBzZXRfbWFwX2VudHJ5KGZyb20ubWFwX2VudHJ5KCkpOworICAgIH0KKyAgfQorICBfZXh0ZW5zaW9uc18uTWVyZ2VGcm9tKGZyb20uX2V4dGVuc2lvbnNfKTsKKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OkNvcHlGcm9tKGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBNZXNzYWdlT3B0aW9uczo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkpKSByZXR1cm4gZmFsc2U7CisKKyAgaWYgKCFfZXh0ZW5zaW9uc18uSXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7ICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6U3dhcChNZXNzYWdlT3B0aW9ucyogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OkludGVybmFsU3dhcChNZXNzYWdlT3B0aW9ucyogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0Xywgb3RoZXItPm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0Xyk7CisgIHN0ZDo6c3dhcChub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXywgb3RoZXItPm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfKTsKKyAgc3RkOjpzd2FwKGRlcHJlY2F0ZWRfLCBvdGhlci0+ZGVwcmVjYXRlZF8pOworICBzdGQ6OnN3YXAobWFwX2VudHJ5Xywgb3RoZXItPm1hcF9lbnRyeV8pOworICB1bmludGVycHJldGVkX29wdGlvbl8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+dW5pbnRlcnByZXRlZF9vcHRpb25fKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7CisgIF9leHRlbnNpb25zXy5Td2FwKCZvdGhlci0+X2V4dGVuc2lvbnNfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBNZXNzYWdlT3B0aW9uczo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBNZXNzYWdlT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBNZXNzYWdlT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIE1lc3NhZ2VPcHRpb25zOjpoYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQorIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cisgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIHsKKyAgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpOworfQorIGJvb2wgTWVzc2FnZU9wdGlvbnM6Om1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCkKKyAgcmV0dXJuIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XzsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCk7CisgIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yID0gMiBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIE1lc3NhZ2VPcHRpb25zOjpoYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cisgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkgeworICBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXyA9IGZhbHNlOworICBjbGVhcl9oYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpOworfQorIGJvb2wgTWVzc2FnZU9wdGlvbnM6Om5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IpCisgIHJldHVybiBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXzsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcihib29sIHZhbHVlKSB7CisgIHNldF9oYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpOworICBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKQorfQorCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQorIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CisgYm9vbCBNZXNzYWdlT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQorIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyBib29sIE1lc3NhZ2VPcHRpb25zOjpoYXNfbWFwX2VudHJ5KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfaGFzX21hcF9lbnRyeSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfbWFwX2VudHJ5KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9tYXBfZW50cnkoKSB7CisgIG1hcF9lbnRyeV8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX21hcF9lbnRyeSgpOworfQorIGJvb2wgTWVzc2FnZU9wdGlvbnM6Om1hcF9lbnRyeSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubWFwX2VudHJ5KQorICByZXR1cm4gbWFwX2VudHJ5XzsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfbWFwX2VudHJ5KGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19tYXBfZW50cnkoKTsKKyAgbWFwX2VudHJ5XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5tYXBfZW50cnkpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyBpbnQgTWVzc2FnZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQorIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIE1lc3NhZ2VPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1lc3NhZ2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBNZXNzYWdlT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorTWVzc2FnZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK01lc3NhZ2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWVsZE9wdGlvbnNfQ1R5cGVfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgc3dpdGNoKHZhbHVlKSB7CisgICAgY2FzZSAwOgorICAgIGNhc2UgMToKKyAgICBjYXNlIDI6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnM6OlNUUklORzsKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnM6OkNPUkQ7Citjb25zdCBGaWVsZE9wdGlvbnNfQ1R5cGUgRmllbGRPcHRpb25zOjpTVFJJTkdfUElFQ0U7Citjb25zdCBGaWVsZE9wdGlvbnNfQ1R5cGUgRmllbGRPcHRpb25zOjpDVHlwZV9NSU47Citjb25zdCBGaWVsZE9wdGlvbnNfQ1R5cGUgRmllbGRPcHRpb25zOjpDVHlwZV9NQVg7Citjb25zdCBpbnQgRmllbGRPcHRpb25zOjpDVHlwZV9BUlJBWVNJWkU7CisjZW5kaWYgIC8vIF9NU0NfVkVSCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgRmllbGRPcHRpb25zOjprQ3R5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtQYWNrZWRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtMYXp5RmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGRPcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkT3B0aW9uczo6a1dlYWtGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorCitGaWVsZE9wdGlvbnM6OkZpZWxkT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0ZpZWxkT3B0aW9uczo6RmllbGRPcHRpb25zKGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpTaGFyZWRDdG9yKCkgeworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgY3R5cGVfID0gMDsKKyAgcGFja2VkXyA9IGZhbHNlOworICBsYXp5XyA9IGZhbHNlOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICB3ZWFrXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitGaWVsZE9wdGlvbnM6On5GaWVsZE9wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBGaWVsZE9wdGlvbnM6OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBGaWVsZE9wdGlvbnM6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWVsZE9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGRPcHRpb25zX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBGaWVsZE9wdGlvbnMmIEZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRmllbGRPcHRpb25zKiBGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRmllbGRPcHRpb25zKiBGaWVsZE9wdGlvbnM6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBGaWVsZE9wdGlvbnMqIG4gPSBuZXcgRmllbGRPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpDbGVhcigpIHsKKyAgX2V4dGVuc2lvbnNfLkNsZWFyKCk7CisjZGVmaW5lIFpSX0hFTFBFUl8oZikgcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oXAorICAmcmVpbnRlcnByZXRfY2FzdDxGaWVsZE9wdGlvbnMqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDMxKSB7CisgICAgWlJfKGN0eXBlXywgd2Vha18pOworICB9CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIEZpZWxkT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTYzODMpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZSBjdHlwZSA9IDEgW2RlZmF1bHQgPSBTVFJJTkddOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIGludCB2YWx1ZTsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGludCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSk7CisgICAgICAgICAgaWYgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlX0lzVmFsaWQodmFsdWUpKSB7CisgICAgICAgICAgICBzZXRfY3R5cGUoc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlID4odmFsdWUpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMSwgdmFsdWUpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9wYWNrZWQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIHBhY2tlZCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgcGFyc2VfcGFja2VkOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmcGFja2VkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX3BhY2tlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjQpKSBnb3RvIHBhcnNlX2RlcHJlY2F0ZWQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX2RlcHJlY2F0ZWQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZkZXByZWNhdGVkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQwKSkgZ290byBwYXJzZV9sYXp5OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQwKSB7CisgICAgICAgICBwYXJzZV9sYXp5OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbGF6eV8pKSk7CisgICAgICAgICAgc2V0X2hhc19sYXp5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MCkpIGdvdG8gcGFyc2Vfd2VhazsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgd2VhayA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAxMDogeworICAgICAgICBpZiAodGFnID09IDgwKSB7CisgICAgICAgICBwYXJzZV93ZWFrOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmd2Vha18pKSk7CisgICAgICAgICAgc2V0X2hhc193ZWFrKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgICAgIGNhc2UgOTk5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzk5NCkgeworICAgICAgICAgcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDc5OTQpKSBnb3RvIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIGlmICgoODAwMHUgPD0gdGFnKSkgeworICAgICAgICAgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCBkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlIGN0eXBlID0gMSBbZGVmYXVsdCA9IFNUUklOR107CisgIGlmIChoYXNfY3R5cGUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW0oCisgICAgICAxLCB0aGlzLT5jdHlwZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSAyOworICBpZiAoaGFzX3BhY2tlZCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgyLCB0aGlzLT5wYWNrZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgzLCB0aGlzLT5kZXByZWNhdGVkKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2xhenkoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woNSwgdGhpcy0+bGF6eSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCB3ZWFrID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfd2VhaygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgxMCwgdGhpcy0+d2VhaygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA5OTksIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gRXh0ZW5zaW9uIHJhbmdlIFsxMDAwLCA1MzY4NzA5MTIpCisgIF9leHRlbnNpb25zXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIG91dHB1dCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBGaWVsZE9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucykKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKKyAgaWYgKGhhc19jdHlwZSgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bVRvQXJyYXkoCisgICAgICAxLCB0aGlzLT5jdHlwZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSAyOworICBpZiAoaGFzX3BhY2tlZCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMiwgdGhpcy0+cGFja2VkKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbGF6eSA9IDUgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfbGF6eSgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoNSwgdGhpcy0+bGF6eSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCB3ZWFrID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfd2VhaygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMTAsIHRoaXMtPndlYWsoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA5OTksIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gRXh0ZW5zaW9uIHJhbmdlIFsxMDAwLCA1MzY4NzA5MTIpCisgIHRhcmdldCA9IF9leHRlbnNpb25zXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCB0YXJnZXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBGaWVsZE9wdGlvbnM6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDMxKSB7CisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKKyAgICBpZiAoaGFzX2N0eXBlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5jdHlwZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIHBhY2tlZCA9IDI7CisgICAgaWYgKGhhc19wYWNrZWQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfbGF6eSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCB3ZWFrID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc193ZWFrKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICB0b3RhbF9zaXplICs9IDIgKiB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpKTsKKyAgfQorCisgIHRvdGFsX3NpemUgKz0gX2V4dGVuc2lvbnNfLkJ5dGVTaXplKCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEZpZWxkT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWVsZE9wdGlvbnMqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBGaWVsZE9wdGlvbnMqPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgRmllbGRPcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2N0eXBlKCkpIHsKKyAgICAgIHNldF9jdHlwZShmcm9tLmN0eXBlKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfcGFja2VkKCkpIHsKKyAgICAgIHNldF9wYWNrZWQoZnJvbS5wYWNrZWQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19sYXp5KCkpIHsKKyAgICAgIHNldF9sYXp5KGZyb20ubGF6eSgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgc2V0X2RlcHJlY2F0ZWQoZnJvbS5kZXByZWNhdGVkKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfd2VhaygpKSB7CisgICAgICBzZXRfd2Vhayhmcm9tLndlYWsoKSk7CisgICAgfQorICB9CisgIF9leHRlbnNpb25zXy5NZXJnZUZyb20oZnJvbS5fZXh0ZW5zaW9uc18pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBGaWVsZE9wdGlvbnM6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpDb3B5RnJvbShjb25zdCBGaWVsZE9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEZpZWxkT3B0aW9uczo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkpKSByZXR1cm4gZmFsc2U7CisKKyAgaWYgKCFfZXh0ZW5zaW9uc18uSXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7ICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBGaWVsZE9wdGlvbnM6OlN3YXAoRmllbGRPcHRpb25zKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBGaWVsZE9wdGlvbnM6OkludGVybmFsU3dhcChGaWVsZE9wdGlvbnMqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChjdHlwZV8sIG90aGVyLT5jdHlwZV8pOworICBzdGQ6OnN3YXAocGFja2VkXywgb3RoZXItPnBhY2tlZF8pOworICBzdGQ6OnN3YXAobGF6eV8sIG90aGVyLT5sYXp5Xyk7CisgIHN0ZDo6c3dhcChkZXByZWNhdGVkXywgb3RoZXItPmRlcHJlY2F0ZWRfKTsKKyAgc3RkOjpzd2FwKHdlYWtfLCBvdGhlci0+d2Vha18pOworICB1bmludGVycHJldGVkX29wdGlvbl8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+dW5pbnRlcnByZXRlZF9vcHRpb25fKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7CisgIF9leHRlbnNpb25zXy5Td2FwKCZvdGhlci0+X2V4dGVuc2lvbnNfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBGaWVsZE9wdGlvbnM6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZpZWxkT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBGaWVsZE9wdGlvbnMKKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKKyBib29sIEZpZWxkT3B0aW9uczo6aGFzX2N0eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19jdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX2N0eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfY3R5cGUoKSB7CisgIGN0eXBlXyA9IDA7CisgIGNsZWFyX2hhc19jdHlwZSgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlIEZpZWxkT3B0aW9uczo6Y3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5jdHlwZSkKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSA+KGN0eXBlXyk7Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9jdHlwZSg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGVfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX2N0eXBlKCk7CisgIGN0eXBlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuY3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gMjsKKyBib29sIEZpZWxkT3B0aW9uczo6aGFzX3BhY2tlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfcGFja2VkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfcGFja2VkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfcGFja2VkKCkgeworICBwYWNrZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19wYWNrZWQoKTsKK30KKyBib29sIEZpZWxkT3B0aW9uczo6cGFja2VkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMucGFja2VkKQorICByZXR1cm4gcGFja2VkXzsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X3BhY2tlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2VkKCk7CisgIHBhY2tlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnBhY2tlZCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIEZpZWxkT3B0aW9uczo6aGFzX2xhenkoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQorIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfaGFzX2xhenkoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc19sYXp5KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfbGF6eSgpIHsKKyAgbGF6eV8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2xhenkoKTsKK30KKyBib29sIEZpZWxkT3B0aW9uczo6bGF6eSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmxhenkpCisgIHJldHVybiBsYXp5XzsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2xhenkoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2xhenkoKTsKKyAgbGF6eV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmxhenkpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgYm9vbCBGaWVsZE9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQorIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CisgYm9vbCBGaWVsZE9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyBvcHRpb25hbCBib29sIHdlYWsgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIEZpZWxkT3B0aW9uczo6aGFzX3dlYWsoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQorIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfaGFzX3dlYWsoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc193ZWFrKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfd2VhaygpIHsKKyAgd2Vha18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX3dlYWsoKTsKK30KKyBib29sIEZpZWxkT3B0aW9uczo6d2VhaygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLndlYWspCisgIHJldHVybiB3ZWFrXzsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X3dlYWsoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX3dlYWsoKTsKKyAgd2Vha18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLndlYWspCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyBpbnQgRmllbGRPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRmllbGRPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWVsZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWVsZE9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitGaWVsZE9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitGaWVsZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IEVudW1PcHRpb25zOjprQWxsb3dBbGlhc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW1PcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW1PcHRpb25zOjprVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworRW51bU9wdGlvbnM6OkVudW1PcHRpb25zKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorfQorCit2b2lkIEVudW1PcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0VudW1PcHRpb25zOjpFbnVtT3B0aW9ucyhjb25zdCBFbnVtT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucykKK30KKwordm9pZCBFbnVtT3B0aW9uczo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGFsbG93X2FsaWFzXyA9IGZhbHNlOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitFbnVtT3B0aW9uczo6fkVudW1PcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBFbnVtT3B0aW9uczo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIEVudW1PcHRpb25zOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bU9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRW51bU9wdGlvbnNfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEVudW1PcHRpb25zJiBFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRW51bU9wdGlvbnMqIEVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0VudW1PcHRpb25zKiBFbnVtT3B0aW9uczo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIEVudW1PcHRpb25zKiBuID0gbmV3IEVudW1PcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRW51bU9wdGlvbnM6OkNsZWFyKCkgeworICBfZXh0ZW5zaW9uc18uQ2xlYXIoKTsKKyNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcCisgICZyZWludGVycHJldF9jYXN0PEVudW1PcHRpb25zKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIFpSXyhhbGxvd19hbGlhc18sIGRlcHJlY2F0ZWRfKTsKKworI3VuZGVmIFpSX0hFTFBFUl8KKyN1bmRlZiBaUl8KKworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRW51bU9wdGlvbnM6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTYzODMpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBib29sIGFsbG93X2FsaWFzID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZhbGxvd19hbGlhc18pKSk7CisgICAgICAgICAgc2V0X2hhc19hbGxvd19hbGlhcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjQpKSBnb3RvIHBhcnNlX2RlcHJlY2F0ZWQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX2RlcHJlY2F0ZWQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZkZXByZWNhdGVkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDc5OTQpKSBnb3RvIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICAgICAgY2FzZSA5OTk6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA3OTk0KSB7CisgICAgICAgICBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRW51bU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorICAvLyBvcHRpb25hbCBib29sIGFsbG93X2FsaWFzID0gMjsKKyAgaWYgKGhhc19hbGxvd19hbGlhcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgyLCB0aGlzLT5hbGxvd19hbGlhcygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworICBpZiAoaGFzX2FsbG93X2FsaWFzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgyLCB0aGlzLT5hbGxvd19hbGlhcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICB0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgdGFyZ2V0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBFbnVtT3B0aW9uczo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMykgeworICAgIC8vIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworICAgIGlmIChoYXNfYWxsb3dfYWxpYXMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICB9CisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBFbnVtT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBFbnVtT3B0aW9ucyogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IEVudW1PcHRpb25zKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEVudW1PcHRpb25zOjpNZXJnZUZyb20oY29uc3QgRW51bU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLk1lcmdlRnJvbShmcm9tLnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfYWxsb3dfYWxpYXMoKSkgeworICAgICAgc2V0X2FsbG93X2FsaWFzKGZyb20uYWxsb3dfYWxpYXMoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19kZXByZWNhdGVkKCkpIHsKKyAgICAgIHNldF9kZXByZWNhdGVkKGZyb20uZGVwcmVjYXRlZCgpKTsKKyAgICB9CisgIH0KKyAgX2V4dGVuc2lvbnNfLk1lcmdlRnJvbShmcm9tLl9leHRlbnNpb25zXyk7CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEVudW1PcHRpb25zOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEVudW1PcHRpb25zOjpDb3B5RnJvbShjb25zdCBFbnVtT3B0aW9ucyYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRW51bU9wdGlvbnM6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT51bmludGVycHJldGVkX29wdGlvbigpKSkgcmV0dXJuIGZhbHNlOworCisgIGlmICghX2V4dGVuc2lvbnNfLklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRW51bU9wdGlvbnM6OlN3YXAoRW51bU9wdGlvbnMqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEVudW1PcHRpb25zOjpJbnRlcm5hbFN3YXAoRW51bU9wdGlvbnMqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChhbGxvd19hbGlhc18sIG90aGVyLT5hbGxvd19hbGlhc18pOworICBzdGQ6OnN3YXAoZGVwcmVjYXRlZF8sIG90aGVyLT5kZXByZWNhdGVkXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEVudW1PcHRpb25zOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBFbnVtT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEVudW1PcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEVudW1PcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworIGJvb2wgRW51bU9wdGlvbnM6Omhhc19hbGxvd19hbGlhcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cisgdm9pZCBFbnVtT3B0aW9uczo6c2V0X2hhc19hbGxvd19hbGlhcygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIEVudW1PcHRpb25zOjpjbGVhcl9oYXNfYWxsb3dfYWxpYXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX2FsbG93X2FsaWFzKCkgeworICBhbGxvd19hbGlhc18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2FsbG93X2FsaWFzKCk7Cit9CisgYm9vbCBFbnVtT3B0aW9uczo6YWxsb3dfYWxpYXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLmFsbG93X2FsaWFzKQorICByZXR1cm4gYWxsb3dfYWxpYXNfOworfQorIHZvaWQgRW51bU9wdGlvbnM6OnNldF9hbGxvd19hbGlhcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfYWxsb3dfYWxpYXMoKTsKKyAgYWxsb3dfYWxpYXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLmFsbG93X2FsaWFzKQorfQorCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgRW51bU9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KKyB2b2lkIEVudW1PcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cisgdm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQorIHZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CisgYm9vbCBFbnVtT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQorIHZvaWQgRW51bU9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyBpbnQgRW51bU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQorIHZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIEVudW1PcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEVudW1PcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBFbnVtT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorRW51bU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK0VudW1PcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IEVudW1WYWx1ZU9wdGlvbnM6OmtEZXByZWNhdGVkRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bVZhbHVlT3B0aW9uczo6a1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK0VudW1WYWx1ZU9wdGlvbnM6OkVudW1WYWx1ZU9wdGlvbnMoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpICwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSAgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucykKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0VudW1WYWx1ZU9wdGlvbnM6OkVudW1WYWx1ZU9wdGlvbnMoY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorfQorCit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitFbnVtVmFsdWVPcHRpb25zOjp+RW51bVZhbHVlT3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEVudW1WYWx1ZU9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgRW51bVZhbHVlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRW51bVZhbHVlT3B0aW9ucyogRW51bVZhbHVlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitFbnVtVmFsdWVPcHRpb25zKiBFbnVtVmFsdWVPcHRpb25zOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRW51bVZhbHVlT3B0aW9ucyogbiA9IG5ldyBFbnVtVmFsdWVPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6Q2xlYXIoKSB7CisgIF9leHRlbnNpb25zXy5DbGVhcigpOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRW51bVZhbHVlT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDE2MzgzKTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDgpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgICAgICBjYXNlIDk5OTogeworICAgICAgICBpZiAodGFnID09IDc5OTQpIHsKKyAgICAgICAgIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF91bmludGVycHJldGVkX29wdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBpZiAoKDgwMDB1IDw9IHRhZykpIHsKKyAgICAgICAgICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucykKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDEsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEVudW1WYWx1ZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMSwgdGhpcy0+ZGVwcmVjYXRlZCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgdGFyZ2V0ID0gX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIHRhcmdldCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBFbnVtVmFsdWVPcHRpb25zOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEVudW1WYWx1ZU9wdGlvbnMqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBFbnVtVmFsdWVPcHRpb25zKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6Ok1lcmdlRnJvbShjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgc2V0X2RlcHJlY2F0ZWQoZnJvbS5kZXByZWNhdGVkKCkpOworICAgIH0KKyAgfQorICBfZXh0ZW5zaW9uc18uTWVyZ2VGcm9tKGZyb20uX2V4dGVuc2lvbnNfKTsKKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpDb3B5RnJvbShjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBFbnVtVmFsdWVPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OlN3YXAoRW51bVZhbHVlT3B0aW9ucyogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6SW50ZXJuYWxTd2FwKEVudW1WYWx1ZU9wdGlvbnMqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChkZXByZWNhdGVkXywgb3RoZXItPmRlcHJlY2F0ZWRfKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworICBfZXh0ZW5zaW9uc18uU3dhcCgmb3RoZXItPl9leHRlbnNpb25zXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRW51bVZhbHVlT3B0aW9uczo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEVudW1WYWx1ZU9wdGlvbnNfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRW51bVZhbHVlT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgRW51bVZhbHVlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQorIHZvaWQgRW51bVZhbHVlT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgRW51bVZhbHVlT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgRW51bVZhbHVlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIEVudW1WYWx1ZU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQorIHZvaWQgRW51bVZhbHVlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgaW50IEVudW1WYWx1ZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQorIHZvaWQgRW51bVZhbHVlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRW51bVZhbHVlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEVudW1WYWx1ZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRW51bVZhbHVlT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitFbnVtVmFsdWVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK0VudW1WYWx1ZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZm5kZWYgX01TQ19WRVIKK2NvbnN0IGludCBTZXJ2aWNlT3B0aW9uczo6a0RlcHJlY2F0ZWRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBTZXJ2aWNlT3B0aW9uczo6a1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK1NlcnZpY2VPcHRpb25zOjpTZXJ2aWNlT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucykKK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitTZXJ2aWNlT3B0aW9uczo6U2VydmljZU9wdGlvbnMoY29uc3QgU2VydmljZU9wdGlvbnMmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitTZXJ2aWNlT3B0aW9uczo6flNlcnZpY2VPcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogU2VydmljZU9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gU2VydmljZU9wdGlvbnNfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IFNlcnZpY2VPcHRpb25zJiBTZXJ2aWNlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworU2VydmljZU9wdGlvbnMqIFNlcnZpY2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK1NlcnZpY2VPcHRpb25zKiBTZXJ2aWNlT3B0aW9uczo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIFNlcnZpY2VPcHRpb25zKiBuID0gbmV3IFNlcnZpY2VPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6OkNsZWFyKCkgeworICBfZXh0ZW5zaW9uc18uQ2xlYXIoKTsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIFNlcnZpY2VPcHRpb25zOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDE2MzgzKTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDMzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjY0KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZkZXByZWNhdGVkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDc5OTQpKSBnb3RvIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICAgICAgY2FzZSA5OTk6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA3OTk0KSB7CisgICAgICAgICBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDMzLCB0aGlzLT5kZXByZWNhdGVkKCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIG91dHB1dCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgb3V0cHV0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucykKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VydmljZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgzMywgdGhpcy0+ZGVwcmVjYXRlZCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgdGFyZ2V0ID0gX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIHRhcmdldCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgU2VydmljZU9wdGlvbnM6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBTZXJ2aWNlT3B0aW9ucyogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IFNlcnZpY2VPcHRpb25zKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgU2VydmljZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLk1lcmdlRnJvbShmcm9tLnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICBzZXRfZGVwcmVjYXRlZChmcm9tLmRlcHJlY2F0ZWQoKSk7CisgICAgfQorICB9CisgIF9leHRlbnNpb25zXy5NZXJnZUZyb20oZnJvbS5fZXh0ZW5zaW9uc18pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6Q29weUZyb20oY29uc3QgU2VydmljZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFNlcnZpY2VPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpTd2FwKFNlcnZpY2VPcHRpb25zKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBTZXJ2aWNlT3B0aW9uczo6SW50ZXJuYWxTd2FwKFNlcnZpY2VPcHRpb25zKiBvdGhlcikgeworICBzdGQ6OnN3YXAoZGVwcmVjYXRlZF8sIG90aGVyLT5kZXByZWNhdGVkXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFNlcnZpY2VPcHRpb25zOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBTZXJ2aWNlT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IFNlcnZpY2VPcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFNlcnZpY2VPcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworIGJvb2wgU2VydmljZU9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIFNlcnZpY2VPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cisgdm9pZCBTZXJ2aWNlT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQorIHZvaWQgU2VydmljZU9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CisgYm9vbCBTZXJ2aWNlT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQorIHZvaWQgU2VydmljZU9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyBpbnQgU2VydmljZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQorIHZvaWQgU2VydmljZU9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIFNlcnZpY2VPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIFNlcnZpY2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBTZXJ2aWNlT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorU2VydmljZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK1NlcnZpY2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IE1ldGhvZE9wdGlvbnM6OmtEZXByZWNhdGVkRmllbGROdW1iZXI7Citjb25zdCBpbnQgTWV0aG9kT3B0aW9uczo6a1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIV9NU0NfVkVSCisKK01ldGhvZE9wdGlvbnM6Ok1ldGhvZE9wdGlvbnMoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpICwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSAgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK01ldGhvZE9wdGlvbnM6Ok1ldGhvZE9wdGlvbnMoY29uc3QgTWV0aG9kT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zKQorfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitNZXRob2RPcHRpb25zOjp+TWV0aG9kT3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgTWV0aG9kT3B0aW9uczo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1ldGhvZE9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgTWV0aG9kT3B0aW9ucyYgTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworTWV0aG9kT3B0aW9ucyogTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitNZXRob2RPcHRpb25zKiBNZXRob2RPcHRpb25zOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgTWV0aG9kT3B0aW9ucyogbiA9IG5ldyBNZXRob2RPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgTWV0aG9kT3B0aW9uczo6Q2xlYXIoKSB7CisgIF9leHRlbnNpb25zXy5DbGVhcigpOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgTWV0aG9kT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDE2MzgzKTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDMzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjY0KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZkZXByZWNhdGVkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDc5OTQpKSBnb3RvIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICAgICAgY2FzZSA5OTk6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA3OTk0KSB7CisgICAgICAgICBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMzMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE1ldGhvZE9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDMzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICB0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgdGFyZ2V0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE1ldGhvZE9wdGlvbnM6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IE1ldGhvZE9wdGlvbnMqIHNvdXJjZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBNZXRob2RPcHRpb25zKj4oCisgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6Ok1lcmdlRnJvbShjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgc2V0X2RlcHJlY2F0ZWQoZnJvbS5kZXByZWNhdGVkKCkpOworICAgIH0KKyAgfQorICBfZXh0ZW5zaW9uc18uTWVyZ2VGcm9tKGZyb20uX2V4dGVuc2lvbnNfKTsKKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgTWV0aG9kT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpDb3B5RnJvbShjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBNZXRob2RPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OlN3YXAoTWV0aG9kT3B0aW9ucyogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgTWV0aG9kT3B0aW9uczo6SW50ZXJuYWxTd2FwKE1ldGhvZE9wdGlvbnMqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChkZXByZWNhdGVkXywgb3RoZXItPmRlcHJlY2F0ZWRfKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworICBfZXh0ZW5zaW9uc18uU3dhcCgmb3RoZXItPl9leHRlbnNpb25zXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgTWV0aG9kT3B0aW9uczo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1ldGhvZE9wdGlvbnNfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gTWV0aG9kT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyBib29sIE1ldGhvZE9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIE1ldGhvZE9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KKyB2b2lkIE1ldGhvZE9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KKyB2b2lkIE1ldGhvZE9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CisgYm9vbCBNZXRob2RPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KKyB2b2lkIE1ldGhvZE9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworIGludCBNZXRob2RPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KKyB2b2lkIE1ldGhvZE9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIE1ldGhvZE9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBNZXRob2RPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1ldGhvZE9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorTWV0aG9kT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitNZXRob2RPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6a05hbWVQYXJ0RmllbGROdW1iZXI7Citjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6a0lzRXh0ZW5zaW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorCitVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKK30KKwordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV9wYXJ0Xy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlzX2V4dGVuc2lvbl8gPSBmYWxzZTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6flVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0KQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV9wYXJ0Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogbiA9IG5ldyBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAzKSB7CisgICAgaWYgKGhhc19uYW1lX3BhcnQoKSkgeworICAgICAgbmFtZV9wYXJ0Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlzX2V4dGVuc2lvbl8gPSBmYWxzZTsKKyAgfQorICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lX3BhcnQoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+bmFtZV9wYXJ0KCkuZGF0YSgpLCB0aGlzLT5uYW1lX3BhcnQoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTYpKSBnb3RvIHBhcnNlX2lzX2V4dGVuc2lvbjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcXVpcmVkIGJvb2wgaXNfZXh0ZW5zaW9uID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9pc19leHRlbnNpb246CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZpc19leHRlbnNpb25fKSkpOworICAgICAgICAgIHNldF9oYXNfaXNfZXh0ZW5zaW9uKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0KQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0KQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKKyAgLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgIGlmIChoYXNfbmFtZV9wYXJ0KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWVfcGFydCgpLmRhdGEoKSwgdGhpcy0+bmFtZV9wYXJ0KCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0Iik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZV9wYXJ0KCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CisgIGlmIChoYXNfaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDIsIHRoaXMtPmlzX2V4dGVuc2lvbigpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKKyAgLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgIGlmIChoYXNfbmFtZV9wYXJ0KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWVfcGFydCgpLmRhdGEoKSwgdGhpcy0+bmFtZV9wYXJ0KCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0Iik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWVfcGFydCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVxdWlyZWQgYm9vbCBpc19leHRlbnNpb24gPSAyOworICBpZiAoaGFzX2lzX2V4dGVuc2lvbigpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMiwgdGhpcy0+aXNfZXh0ZW5zaW9uKCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OlJlcXVpcmVkRmllbGRzQnl0ZVNpemVGYWxsYmFjaygpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmIChoYXNfbmFtZV9wYXJ0KCkpIHsKKyAgICAvLyByZXF1aXJlZCBzdHJpbmcgbmFtZV9wYXJ0ID0gMTsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPm5hbWVfcGFydCgpKTsKKyAgfQorCisgIGlmIChoYXNfaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CisgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgfQorCisgIHJldHVybiB0b3RhbF9zaXplOworfQoraW50IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKCgoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDMpIF4gMHgwMDAwMDAwMykgPT0gMCkgeyAgLy8gQWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudC4KKyAgICAvLyByZXF1aXJlZCBzdHJpbmcgbmFtZV9wYXJ0ID0gMTsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPm5hbWVfcGFydCgpKTsKKworICAgIC8vIHJlcXVpcmVkIGJvb2wgaXNfZXh0ZW5zaW9uID0gMjsKKyAgICB0b3RhbF9zaXplICs9IDEgKyAxOworCisgIH0gZWxzZSB7CisgICAgdG90YWxfc2l6ZSArPSBSZXF1aXJlZEZpZWxkc0J5dGVTaXplRmFsbGJhY2soKTsKKyAgfQorICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCo+KAorICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpNZXJnZUZyb20oY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWVfcGFydCgpKSB7CisgICAgICBzZXRfaGFzX25hbWVfcGFydCgpOworICAgICAgbmFtZV9wYXJ0Xy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV9wYXJ0Xyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19pc19leHRlbnNpb24oKSkgeworICAgICAgc2V0X2lzX2V4dGVuc2lvbihmcm9tLmlzX2V4dGVuc2lvbigpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpDb3B5RnJvbShjb25zdCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0JiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworICBpZiAoKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAzKSAhPSAweDAwMDAwMDAzKSByZXR1cm4gZmFsc2U7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U3dhcChVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpJbnRlcm5hbFN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogb3RoZXIpIHsKKyAgbmFtZV9wYXJ0Xy5Td2FwKCZvdGhlci0+bmFtZV9wYXJ0Xyk7CisgIHN0ZDo6c3dhcChpc19leHRlbnNpb25fLCBvdGhlci0+aXNfZXh0ZW5zaW9uXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnRfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbjo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBVbmludGVycHJldGVkT3B0aW9uOjprSWRlbnRpZmllclZhbHVlRmllbGROdW1iZXI7Citjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbjo6a1Bvc2l0aXZlSW50VmFsdWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBVbmludGVycHJldGVkT3B0aW9uOjprTmVnYXRpdmVJbnRWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246OmtEb3VibGVWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246OmtTdHJpbmdWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246OmtBZ2dyZWdhdGVWYWx1ZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworVW5pbnRlcnByZXRlZE9wdGlvbjo6VW5pbnRlcnByZXRlZE9wdGlvbigpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCkgLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpICB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKQorfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbjo6VW5pbnRlcnByZXRlZE9wdGlvbihjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGlkZW50aWZpZXJfdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcG9zaXRpdmVfaW50X3ZhbHVlXyA9IEdPT0dMRV9VTE9OR0xPTkcoMCk7CisgIG5lZ2F0aXZlX2ludF92YWx1ZV8gPSBHT09HTEVfTE9OR0xPTkcoMCk7CisgIGRvdWJsZV92YWx1ZV8gPSAwOworICBzdHJpbmdfdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK1VuaW50ZXJwcmV0ZWRPcHRpb246On5VbmludGVycHJldGVkT3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OlNoYXJlZER0b3IoKSB7CisgIGlkZW50aWZpZXJfdmFsdWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHN0cmluZ192YWx1ZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFVuaW50ZXJwcmV0ZWRPcHRpb246OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVW5pbnRlcnByZXRlZE9wdGlvbl9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbiogVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitVbmludGVycHJldGVkT3B0aW9uKiBVbmludGVycHJldGVkT3B0aW9uOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbiogbiA9IG5ldyBVbmludGVycHJldGVkT3B0aW9uOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Q2xlYXIoKSB7CisjZGVmaW5lIFpSX0hFTFBFUl8oZikgcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oXAorICAmcmVpbnRlcnByZXRfY2FzdDxVbmludGVycHJldGVkT3B0aW9uKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAxMjYpIHsKKyAgICBaUl8ocG9zaXRpdmVfaW50X3ZhbHVlXywgZG91YmxlX3ZhbHVlXyk7CisgICAgaWYgKGhhc19pZGVudGlmaWVyX3ZhbHVlKCkpIHsKKyAgICAgIGlkZW50aWZpZXJfdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgICAgc3RyaW5nX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfYWdncmVnYXRlX3ZhbHVlKCkpIHsKKyAgICAgIGFnZ3JlZ2F0ZV92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgfQorCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCisgIG5hbWVfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQgbmFtZSA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfbmFtZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfbmFtZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbmFtZTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX2lkZW50aWZpZXJfdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgcGFyc2VfaWRlbnRpZmllcl92YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfaWRlbnRpZmllcl92YWx1ZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5pZGVudGlmaWVyX3ZhbHVlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMikpIGdvdG8gcGFyc2VfcG9zaXRpdmVfaW50X3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzMikgeworICAgICAgICAgcGFyc2VfcG9zaXRpdmVfaW50X3ZhbHVlOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX1VJTlQ2ND4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmcG9zaXRpdmVfaW50X3ZhbHVlXykpKTsKKyAgICAgICAgICBzZXRfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDApKSBnb3RvIHBhcnNlX25lZ2F0aXZlX2ludF92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MCkgeworICAgICAgICAgcGFyc2VfbmVnYXRpdmVfaW50X3ZhbHVlOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UNjQ+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm5lZ2F0aXZlX2ludF92YWx1ZV8pKSk7CisgICAgICAgICAgc2V0X2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQ5KSkgZ290byBwYXJzZV9kb3VibGVfdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBkb3VibGUgZG91YmxlX3ZhbHVlID0gNjsKKyAgICAgIGNhc2UgNjogeworICAgICAgICBpZiAodGFnID09IDQ5KSB7CisgICAgICAgICBwYXJzZV9kb3VibGVfdmFsdWU6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBkb3VibGUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0RPVUJMRT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmZG91YmxlX3ZhbHVlXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RvdWJsZV92YWx1ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTgpKSBnb3RvIHBhcnNlX3N0cmluZ192YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7CisgICAgICBjYXNlIDc6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1OCkgeworICAgICAgICAgcGFyc2Vfc3RyaW5nX3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZEJ5dGVzKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3N0cmluZ192YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg2NikpIGdvdG8gcGFyc2VfYWdncmVnYXRlX3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGFnZ3JlZ2F0ZV92YWx1ZSA9IDg7CisgICAgICBjYXNlIDg6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA2NikgeworICAgICAgICAgcGFyc2VfYWdncmVnYXRlX3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9hZ2dyZWdhdGVfdmFsdWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+YWdncmVnYXRlX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5uYW1lX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAyLCB0aGlzLT5uYW1lKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZpZXJfdmFsdWUgPSAzOworICBpZiAoaGFzX2lkZW50aWZpZXJfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+aWRlbnRpZmllcl92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+aWRlbnRpZmllcl92YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAzLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKKyAgaWYgKGhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NCg0LCB0aGlzLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgIGlmIChoYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQ2NCg1LCB0aGlzLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGRvdWJsZSBkb3VibGVfdmFsdWUgPSA2OworICBpZiAoaGFzX2RvdWJsZV92YWx1ZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRG91YmxlKDYsIHRoaXMtPmRvdWJsZV92YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYnl0ZXMgc3RyaW5nX3ZhbHVlID0gNzsKKyAgaWYgKGhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJ5dGVzTWF5YmVBbGlhc2VkKAorICAgICAgNywgdGhpcy0+c3RyaW5nX3ZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgYWdncmVnYXRlX3ZhbHVlID0gODsKKyAgaWYgKGhhc19hZ2dyZWdhdGVfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+YWdncmVnYXRlX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICA4LCB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFVuaW50ZXJwcmV0ZWRPcHRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5uYW1lX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPm5hbWUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CisgIGlmIChoYXNfaWRlbnRpZmllcl92YWx1ZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAzLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKKyAgaWYgKGhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NFRvQXJyYXkoNCwgdGhpcy0+cG9zaXRpdmVfaW50X3ZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQ2NCBuZWdhdGl2ZV9pbnRfdmFsdWUgPSA1OworICBpZiAoaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjRUb0FycmF5KDUsIHRoaXMtPm5lZ2F0aXZlX2ludF92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDY7CisgIGlmIChoYXNfZG91YmxlX3ZhbHVlKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGVUb0FycmF5KDYsIHRoaXMtPmRvdWJsZV92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYnl0ZXMgc3RyaW5nX3ZhbHVlID0gNzsKKyAgaWYgKGhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlc1RvQXJyYXkoCisgICAgICAgIDcsIHRoaXMtPnN0cmluZ192YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGFnZ3JlZ2F0ZV92YWx1ZSA9IDg7CisgIGlmIChoYXNfYWdncmVnYXRlX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmFnZ3JlZ2F0ZV92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+YWdncmVnYXRlX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDgsIHRoaXMtPmFnZ3JlZ2F0ZV92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBVbmludGVycHJldGVkT3B0aW9uOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmIChfaGFzX2JpdHNfWzEgLyAzMl0gJiAxMjYpIHsKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CisgICAgaWYgKGhhc19pZGVudGlmaWVyX3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmlkZW50aWZpZXJfdmFsdWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7CisgICAgaWYgKGhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlVJbnQ2NFNpemUoCisgICAgICAgICAgdGhpcy0+cG9zaXRpdmVfaW50X3ZhbHVlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgICAgaWYgKGhhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDY0U2l6ZSgKKyAgICAgICAgICB0aGlzLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDY7CisgICAgaWYgKGhhc19kb3VibGVfdmFsdWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgODsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBieXRlcyBzdHJpbmdfdmFsdWUgPSA3OworICAgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpCeXRlc1NpemUoCisgICAgICAgICAgdGhpcy0+c3RyaW5nX3ZhbHVlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBhZ2dyZWdhdGVfdmFsdWUgPSA4OworICAgIGlmIChoYXNfYWdncmVnYXRlX3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmFnZ3JlZ2F0ZV92YWx1ZSgpKTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQgbmFtZSA9IDI7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm5hbWVfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPm5hbWVfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm5hbWUoaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiogc291cmNlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlPGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24qPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6TWVyZ2VGcm9tKGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgbmFtZV8uTWVyZ2VGcm9tKGZyb20ubmFtZV8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzEgLyAzMl0gJiAoMHhmZnUgPDwgKDEgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2lkZW50aWZpZXJfdmFsdWUoKSkgeworICAgICAgc2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgICAgICBpZGVudGlmaWVyX3ZhbHVlXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uaWRlbnRpZmllcl92YWx1ZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgIHNldF9wb3NpdGl2ZV9pbnRfdmFsdWUoZnJvbS5wb3NpdGl2ZV9pbnRfdmFsdWUoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgc2V0X25lZ2F0aXZlX2ludF92YWx1ZShmcm9tLm5lZ2F0aXZlX2ludF92YWx1ZSgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2RvdWJsZV92YWx1ZSgpKSB7CisgICAgICBzZXRfZG91YmxlX3ZhbHVlKGZyb20uZG91YmxlX3ZhbHVlKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAgICBzdHJpbmdfdmFsdWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5zdHJpbmdfdmFsdWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpKSB7CisgICAgICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICAgICAgYWdncmVnYXRlX3ZhbHVlXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uYWdncmVnYXRlX3ZhbHVlXyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Q29weUZyb20oY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPm5hbWUoKSkpIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6U3dhcChVbmludGVycHJldGVkT3B0aW9uKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpJbnRlcm5hbFN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbiogb3RoZXIpIHsKKyAgbmFtZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+bmFtZV8pOworICBpZGVudGlmaWVyX3ZhbHVlXy5Td2FwKCZvdGhlci0+aWRlbnRpZmllcl92YWx1ZV8pOworICBzdGQ6OnN3YXAocG9zaXRpdmVfaW50X3ZhbHVlXywgb3RoZXItPnBvc2l0aXZlX2ludF92YWx1ZV8pOworICBzdGQ6OnN3YXAobmVnYXRpdmVfaW50X3ZhbHVlXywgb3RoZXItPm5lZ2F0aXZlX2ludF92YWx1ZV8pOworICBzdGQ6OnN3YXAoZG91YmxlX3ZhbHVlXywgb3RoZXItPmRvdWJsZV92YWx1ZV8pOworICBzdHJpbmdfdmFsdWVfLlN3YXAoJm90aGVyLT5zdHJpbmdfdmFsdWVfKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5Td2FwKCZvdGhlci0+YWdncmVnYXRlX3ZhbHVlXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFVuaW50ZXJwcmV0ZWRPcHRpb246OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IFVuaW50ZXJwcmV0ZWRPcHRpb25fZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBVbmludGVycHJldGVkT3B0aW9uX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQKKworLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpoYXNfbmFtZV9wYXJ0KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9oYXNfbmFtZV9wYXJ0KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Y2xlYXJfaGFzX25hbWVfcGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9uYW1lX3BhcnQoKSB7CisgIG5hbWVfcGFydF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6bmFtZV9wYXJ0KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKKyAgcmV0dXJuIG5hbWVfcGFydF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X25hbWVfcGFydChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X25hbWVfcGFydChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfbmFtZV9wYXJ0KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKK30KKyA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjptdXRhYmxlX25hbWVfcGFydCgpIHsKKyAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorICByZXR1cm4gbmFtZV9wYXJ0Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnJlbGVhc2VfbmFtZV9wYXJ0KCkgeworICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7CisgIHJldHVybiBuYW1lX3BhcnRfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfYWxsb2NhdGVkX25hbWVfcGFydCg6OnN0ZDo6c3RyaW5nKiBuYW1lX3BhcnQpIHsKKyAgaWYgKG5hbWVfcGFydCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7CisgIH0KKyAgbmFtZV9wYXJ0Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZV9wYXJ0KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQorCisvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CisgYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpoYXNfaXNfZXh0ZW5zaW9uKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9oYXNfaXNfZXh0ZW5zaW9uKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Y2xlYXJfaGFzX2lzX2V4dGVuc2lvbigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9pc19leHRlbnNpb24oKSB7CisgIGlzX2V4dGVuc2lvbl8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2lzX2V4dGVuc2lvbigpOworfQorIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6aXNfZXh0ZW5zaW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0LmlzX2V4dGVuc2lvbikKKyAgcmV0dXJuIGlzX2V4dGVuc2lvbl87Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfaXNfZXh0ZW5zaW9uKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19pc19leHRlbnNpb24oKTsKKyAgaXNfZXh0ZW5zaW9uXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0LmlzX2V4dGVuc2lvbikKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBVbmludGVycHJldGVkT3B0aW9uCisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKKyBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gbmFtZV8uc2l6ZSgpOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIFVuaW50ZXJwcmV0ZWRPcHRpb246Om5hbWUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldChpbmRleCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX25hbWUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlKGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIFVuaW50ZXJwcmV0ZWRPcHRpb246OmFkZF9uYW1lKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5hbWUpCisgIHJldHVybiBuYW1lXy5BZGQoKTsKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCA+JgorVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4qCitVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX25hbWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuICZuYW1lXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZpZXJfdmFsdWUgPSAzOworIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2lkZW50aWZpZXJfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX2lkZW50aWZpZXJfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaWRlbnRpZmllcl92YWx1ZSgpIHsKKyAgaWRlbnRpZmllcl92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFVuaW50ZXJwcmV0ZWRPcHRpb246OmlkZW50aWZpZXJfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKKyAgcmV0dXJuIGlkZW50aWZpZXJfdmFsdWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICBpZGVudGlmaWVyX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgaWRlbnRpZmllcl92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9CisgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6bXV0YWJsZV9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKKyAgcmV0dXJuIGlkZW50aWZpZXJfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICByZXR1cm4gaWRlbnRpZmllcl92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfaWRlbnRpZmllcl92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBpZGVudGlmaWVyX3ZhbHVlKSB7CisgIGlmIChpZGVudGlmaWVyX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICB9CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpZGVudGlmaWVyX3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7CisgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9wb3NpdGl2ZV9pbnRfdmFsdWUoKSB7CisgIHBvc2l0aXZlX2ludF92YWx1ZV8gPSBHT09HTEVfVUxPTkdMT05HKDApOworICBjbGVhcl9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgVW5pbnRlcnByZXRlZE9wdGlvbjo6cG9zaXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnBvc2l0aXZlX2ludF92YWx1ZSkKKyAgcmV0dXJuIHBvc2l0aXZlX2ludF92YWx1ZV87Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfcG9zaXRpdmVfaW50X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDY0IHZhbHVlKSB7CisgIHNldF9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCk7CisgIHBvc2l0aXZlX2ludF92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5wb3NpdGl2ZV9pbnRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9uZWdhdGl2ZV9pbnRfdmFsdWUoKSB7CisgIG5lZ2F0aXZlX2ludF92YWx1ZV8gPSBHT09HTEVfTE9OR0xPTkcoMCk7CisgIGNsZWFyX2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IFVuaW50ZXJwcmV0ZWRPcHRpb246Om5lZ2F0aXZlX2ludF92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uZWdhdGl2ZV9pbnRfdmFsdWUpCisgIHJldHVybiBuZWdhdGl2ZV9pbnRfdmFsdWVfOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X25lZ2F0aXZlX2ludF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKSB7CisgIHNldF9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCk7CisgIG5lZ2F0aXZlX2ludF92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uZWdhdGl2ZV9pbnRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGRvdWJsZSBkb3VibGVfdmFsdWUgPSA2OworIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2RvdWJsZV92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX2RvdWJsZV92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2hhc19kb3VibGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfZG91YmxlX3ZhbHVlKCkgeworICBkb3VibGVfdmFsdWVfID0gMDsKKyAgY2xlYXJfaGFzX2RvdWJsZV92YWx1ZSgpOworfQorIGRvdWJsZSBVbmludGVycHJldGVkT3B0aW9uOjpkb3VibGVfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uZG91YmxlX3ZhbHVlKQorICByZXR1cm4gZG91YmxlX3ZhbHVlXzsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9kb3VibGVfdmFsdWUoZG91YmxlIHZhbHVlKSB7CisgIHNldF9oYXNfZG91YmxlX3ZhbHVlKCk7CisgIGRvdWJsZV92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5kb3VibGVfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7CisgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfc3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDIwdSkgIT0gMDsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfc3RyaW5nX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMjB1OworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX3N0cmluZ192YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9zdHJpbmdfdmFsdWUoKSB7CisgIHN0cmluZ192YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbjo6c3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnN0cmluZ192YWx1ZSkKKyAgcmV0dXJuIHN0cmluZ192YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X3N0cmluZ192YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBzdHJpbmdfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBzdHJpbmdfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfc3RyaW5nX3ZhbHVlKGNvbnN0IHZvaWQqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBzdHJpbmdfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnN0cmluZ192YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX3N0cmluZ192YWx1ZSgpIHsKKyAgc2V0X2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorICByZXR1cm4gc3RyaW5nX3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246OnJlbGVhc2Vfc3RyaW5nX3ZhbHVlKCkgeworICBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHJldHVybiBzdHJpbmdfdmFsdWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWxsb2NhdGVkX3N0cmluZ192YWx1ZSg6OnN0ZDo6c3RyaW5nKiBzdHJpbmdfdmFsdWUpIHsKKyAgaWYgKHN0cmluZ192YWx1ZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIH0KKyAgc3RyaW5nX3ZhbHVlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgc3RyaW5nX3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgYWdncmVnYXRlX3ZhbHVlID0gODsKKyBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19hZ2dyZWdhdGVfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA0MHU7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfYWdncmVnYXRlX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDQwdTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2FnZ3JlZ2F0ZV92YWx1ZSgpIHsKKyAgYWdncmVnYXRlX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBVbmludGVycHJldGVkT3B0aW9uOjphZ2dyZWdhdGVfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorICByZXR1cm4gYWdncmVnYXRlX3ZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWdncmVnYXRlX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWdncmVnYXRlX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorfQorIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246Om11dGFibGVfYWdncmVnYXRlX3ZhbHVlKCkgeworICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCisgIHJldHVybiBhZ2dyZWdhdGVfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgcmV0dXJuIGFnZ3JlZ2F0ZV92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfYWdncmVnYXRlX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIGFnZ3JlZ2F0ZV92YWx1ZSkgeworICBpZiAoYWdncmVnYXRlX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgfQorICBhZ2dyZWdhdGVfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBhZ2dyZWdhdGVfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmbmRlZiBfTVNDX1ZFUgorY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjprUGF0aEZpZWxkTnVtYmVyOworY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjprU3BhbkZpZWxkTnVtYmVyOworY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjprTGVhZGluZ0NvbW1lbnRzRmllbGROdW1iZXI7Citjb25zdCBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmtUcmFpbGluZ0NvbW1lbnRzRmllbGROdW1iZXI7Citjb25zdCBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmtMZWFkaW5nRGV0YWNoZWRDb21tZW50c0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGxlYWRpbmdfY29tbWVudHNfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworU291cmNlQ29kZUluZm9fTG9jYXRpb246On5Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNoYXJlZER0b3IoKSB7CisgIGxlYWRpbmdfY29tbWVudHNfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogU291cmNlQ29kZUluZm9fTG9jYXRpb246OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworU291cmNlQ29kZUluZm9fTG9jYXRpb24qIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIG4gPSBuZXcgU291cmNlQ29kZUluZm9fTG9jYXRpb247CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAxMikgeworICAgIGlmIChoYXNfbGVhZGluZ19jb21tZW50cygpKSB7CisgICAgICBsZWFkaW5nX2NvbW1lbnRzXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfdHJhaWxpbmdfY29tbWVudHMoKSkgeworICAgICAgdHJhaWxpbmdfY29tbWVudHNfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKyAgcGF0aF8uQ2xlYXIoKTsKKyAgc3Bhbl8uQ2xlYXIoKTsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgU291cmNlQ29kZUluZm9fTG9jYXRpb246Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZCA9IHRydWVdOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUGFja2VkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfcGF0aCgpKSkpOworICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFJlcGVhdGVkUHJpbWl0aXZlTm9JbmxpbmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICAxLCAxMCwgaW5wdXQsIHRoaXMtPm11dGFibGVfcGF0aCgpKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3NwYW47CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCBpbnQzMiBzcGFuID0gMiBbcGFja2VkID0gdHJ1ZV07CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2Vfc3BhbjoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUGFja2VkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfc3BhbigpKSkpOworICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRSZXBlYXRlZFByaW1pdGl2ZU5vSW5saW5lPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgMSwgMTgsIGlucHV0LCB0aGlzLT5tdXRhYmxlX3NwYW4oKSkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9sZWFkaW5nX2NvbW1lbnRzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGxlYWRpbmdfY29tbWVudHMgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX2xlYWRpbmdfY29tbWVudHM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2xlYWRpbmdfY29tbWVudHMoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLmRhdGEoKSwgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDM0KSkgZ290byBwYXJzZV90cmFpbGluZ19jb21tZW50czsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyB0cmFpbGluZ19jb21tZW50cyA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzNCkgeworICAgICAgICAgcGFyc2VfdHJhaWxpbmdfY29tbWVudHM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3RyYWlsaW5nX2NvbW1lbnRzKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnRyYWlsaW5nX2NvbW1lbnRzKCkuZGF0YSgpLCB0aGlzLT50cmFpbGluZ19jb21tZW50cygpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2VfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50czsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIHN0cmluZyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID0gNjsKKyAgICAgIGNhc2UgNjogeworICAgICAgICBpZiAodGFnID09IDUwKSB7CisgICAgICAgICBwYXJzZV9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyh0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKSAtIDEpLmRhdGEoKSwKKyAgICAgICAgICAgIHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHModGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50c19zaXplKCkgLSAxKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2VfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50czsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5wYXRoX3NpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoMSwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKF9wYXRoX2NhY2hlZF9ieXRlX3NpemVfKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhfc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMk5vVGFnKAorICAgICAgdGhpcy0+cGF0aChpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIGludDMyIHNwYW4gPSAyIFtwYWNrZWQgPSB0cnVlXTsKKyAgaWYgKHRoaXMtPnNwYW5fc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZygyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoX3NwYW5fY2FjaGVkX2J5dGVfc2l6ZV8pOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+c3Bhbl9zaXplKCk7IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyTm9UYWcoCisgICAgICB0aGlzLT5zcGFuKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGxlYWRpbmdfY29tbWVudHMgPSAzOworICBpZiAoaGFzX2xlYWRpbmdfY29tbWVudHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLmRhdGEoKSwgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMywgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKKyAgaWYgKGhhc190cmFpbGluZ19jb21tZW50cygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT50cmFpbGluZ19jb21tZW50cygpLmRhdGEoKSwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICA0LCB0aGlzLT50cmFpbGluZ19jb21tZW50cygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgPSA2OworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfc2l6ZSgpOyBpKyspIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpKS5kYXRhKCksIHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaSkubGVuZ3RoKCksCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZygKKyAgICAgIDYsIHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaSksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5wYXRoX3NpemUoKSA+IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgMSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgdGFyZ2V0KTsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICBfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXywgdGFyZ2V0KTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyTm9UYWdUb0FycmF5KHRoaXMtPnBhdGgoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiBzcGFuID0gMiBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5zcGFuX3NpemUoKSA+IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgMiwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgdGFyZ2V0KTsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICBfc3Bhbl9jYWNoZWRfYnl0ZV9zaXplXywgdGFyZ2V0KTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnNwYW5fc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyTm9UYWdUb0FycmF5KHRoaXMtPnNwYW4oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbGVhZGluZ19jb21tZW50cyA9IDM7CisgIGlmIChoYXNfbGVhZGluZ19jb21tZW50cygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5sZWFkaW5nX2NvbW1lbnRzKCkuZGF0YSgpLCB0aGlzLT5sZWFkaW5nX2NvbW1lbnRzKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMywgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKKyAgaWYgKGhhc190cmFpbGluZ19jb21tZW50cygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT50cmFpbGluZ19jb21tZW50cygpLmRhdGEoKSwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgNCwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID0gNjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGkpLmRhdGEoKSwgdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyIpOworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlU3RyaW5nVG9BcnJheSg2LCB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMiAvIDMyXSAmIDEyKSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGxlYWRpbmdfY29tbWVudHMgPSAzOworICAgIGlmIChoYXNfbGVhZGluZ19jb21tZW50cygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5sZWFkaW5nX2NvbW1lbnRzKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyB0cmFpbGluZ19jb21tZW50cyA9IDQ7CisgICAgaWYgKGhhc190cmFpbGluZ19jb21tZW50cygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT50cmFpbGluZ19jb21tZW50cygpKTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIHsKKyAgICBpbnQgZGF0YV9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhfc2l6ZSgpOyBpKyspIHsKKyAgICAgIGRhdGFfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICAgIEludDMyU2l6ZSh0aGlzLT5wYXRoKGkpKTsKKyAgICB9CisgICAgaWYgKGRhdGFfc2l6ZSA+IDApIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoZGF0YV9zaXplKTsKKyAgICB9CisgICAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgICBfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXyA9IGRhdGFfc2l6ZTsKKyAgICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgICB0b3RhbF9zaXplICs9IGRhdGFfc2l6ZTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIGludDMyIHNwYW4gPSAyIFtwYWNrZWQgPSB0cnVlXTsKKyAgeworICAgIGludCBkYXRhX3NpemUgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+c3Bhbl9zaXplKCk7IGkrKykgeworICAgICAgZGF0YV9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgICAgSW50MzJTaXplKHRoaXMtPnNwYW4oaSkpOworICAgIH0KKyAgICBpZiAoZGF0YV9zaXplID4gMCkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZShkYXRhX3NpemUpOworICAgIH0KKyAgICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICAgIF9zcGFuX2NhY2hlZF9ieXRlX3NpemVfID0gZGF0YV9zaXplOworICAgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICAgIHRvdGFsX3NpemUgKz0gZGF0YV9zaXplOworICB9CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgPSA2OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgIHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246Ok1lcmdlRnJvbShjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBwYXRoXy5NZXJnZUZyb20oZnJvbS5wYXRoXyk7CisgIHNwYW5fLk1lcmdlRnJvbShmcm9tLnNwYW5fKTsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTWVyZ2VGcm9tKGZyb20ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzIgLyAzMl0gJiAoMHhmZnUgPDwgKDIgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2xlYWRpbmdfY29tbWVudHMoKSkgeworICAgICAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgICAgICBsZWFkaW5nX2NvbW1lbnRzXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubGVhZGluZ19jb21tZW50c18pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfdHJhaWxpbmdfY29tbWVudHMoKSkgeworICAgICAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICAgICAgdHJhaWxpbmdfY29tbWVudHNfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS50cmFpbGluZ19jb21tZW50c18pOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Q29weUZyb20oY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpTd2FwKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6SW50ZXJuYWxTd2FwKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBvdGhlcikgeworICBwYXRoXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5wYXRoXyk7CisgIHNwYW5fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPnNwYW5fKTsKKyAgbGVhZGluZ19jb21tZW50c18uU3dhcCgmb3RoZXItPmxlYWRpbmdfY29tbWVudHNfKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlN3YXAoJm90aGVyLT50cmFpbGluZ19jb21tZW50c18pOworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBpbnQgU291cmNlQ29kZUluZm86OmtMb2NhdGlvbkZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworU291cmNlQ29kZUluZm86OlNvdXJjZUNvZGVJbmZvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSAsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvKQorfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK1NvdXJjZUNvZGVJbmZvOjpTb3VyY2VDb2RlSW5mbyhjb25zdCBTb3VyY2VDb2RlSW5mbyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK1NvdXJjZUNvZGVJbmZvOjp+U291cmNlQ29kZUluZm8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBTb3VyY2VDb2RlSW5mbzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBTb3VyY2VDb2RlSW5mb19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgU291cmNlQ29kZUluZm8mIFNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTb3VyY2VDb2RlSW5mbyogU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworU291cmNlQ29kZUluZm8qIFNvdXJjZUNvZGVJbmZvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgU291cmNlQ29kZUluZm8qIG4gPSBuZXcgU291cmNlQ29kZUluZm87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6Q2xlYXIoKSB7CisgIGxvY2F0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBTb3VyY2VDb2RlSW5mbzo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIGxvY2F0aW9uID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICBwYXJzZV9sb2NhdGlvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfbG9jYXRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTApKSBnb3RvIHBhcnNlX2xvY2F0aW9uOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24gbG9jYXRpb24gPSAxOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmxvY2F0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAxLCB0aGlzLT5sb2NhdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTb3VyY2VDb2RlSW5mbzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24gbG9jYXRpb24gPSAxOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmxvY2F0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPmxvY2F0aW9uKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgU291cmNlQ29kZUluZm86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiBsb2NhdGlvbiA9IDE7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmxvY2F0aW9uX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5sb2NhdGlvbl9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+bG9jYXRpb24oaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IFNvdXJjZUNvZGVJbmZvKiBzb3VyY2UgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgU291cmNlQ29kZUluZm8qPigKKyAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm86Ok1lcmdlRnJvbShjb25zdCBTb3VyY2VDb2RlSW5mbyYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBsb2NhdGlvbl8uTWVyZ2VGcm9tKGZyb20ubG9jYXRpb25fKTsKKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm86OkNvcHlGcm9tKGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBTb3VyY2VDb2RlSW5mbzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6U3dhcChTb3VyY2VDb2RlSW5mbyogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgU291cmNlQ29kZUluZm86OkludGVybmFsU3dhcChTb3VyY2VDb2RlSW5mbyogb3RoZXIpIHsKKyAgbG9jYXRpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmxvY2F0aW9uXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFNvdXJjZUNvZGVJbmZvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBTb3VyY2VDb2RlSW5mb19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IFNvdXJjZUNvZGVJbmZvX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uCisKKy8vIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQgPSB0cnVlXTsKKyBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnBhdGhfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHBhdGhfLnNpemUoKTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9wYXRoKCkgeworICBwYXRoXy5DbGVhcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnBhdGgoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCisgIHJldHVybiBwYXRoXy5HZXQoaW5kZXgpOworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9wYXRoKGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwYXRoXy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ucGF0aCkKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfcGF0aCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHBhdGhfLkFkZCh2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6cGF0aCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCisgIHJldHVybiBwYXRoXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX3BhdGgoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCisgIHJldHVybiAmcGF0aF87Cit9CisKKy8vIHJlcGVhdGVkIGludDMyIHNwYW4gPSAyIFtwYWNrZWQgPSB0cnVlXTsKKyBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNwYW5fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHNwYW5fLnNpemUoKTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9zcGFuKCkgeworICBzcGFuXy5DbGVhcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNwYW4oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnNwYW4pCisgIHJldHVybiBzcGFuXy5HZXQoaW5kZXgpOworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9zcGFuKGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzcGFuXy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24uc3BhbikKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfc3Bhbig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNwYW5fLkFkZCh2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnNwYW4pCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c3BhbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnNwYW4pCisgIHJldHVybiBzcGFuXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX3NwYW4oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnNwYW4pCisgIHJldHVybiAmc3Bhbl87Cit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBsZWFkaW5nX2NvbW1lbnRzID0gMzsKKyBib29sIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpoYXNfbGVhZGluZ19jb21tZW50cygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9sZWFkaW5nX2NvbW1lbnRzKCkgeworICBsZWFkaW5nX2NvbW1lbnRzXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfY29tbWVudHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2NvbW1lbnRzXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGxlYWRpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGxlYWRpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGxlYWRpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorfQorIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfY29tbWVudHNfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246OnJlbGVhc2VfbGVhZGluZ19jb21tZW50cygpIHsKKyAgY2xlYXJfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgcmV0dXJuIGxlYWRpbmdfY29tbWVudHNfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2FsbG9jYXRlZF9sZWFkaW5nX2NvbW1lbnRzKDo6c3RkOjpzdHJpbmcqIGxlYWRpbmdfY29tbWVudHMpIHsKKyAgaWYgKGxlYWRpbmdfY29tbWVudHMgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIH0KKyAgbGVhZGluZ19jb21tZW50c18uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGxlYWRpbmdfY29tbWVudHMpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKKyBib29sIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpoYXNfdHJhaWxpbmdfY29tbWVudHMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl90cmFpbGluZ19jb21tZW50cygpIHsKKyAgdHJhaWxpbmdfY29tbWVudHNfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnRyYWlsaW5nX2NvbW1lbnRzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cykKKyAgcmV0dXJuIHRyYWlsaW5nX2NvbW1lbnRzXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF90cmFpbGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF90cmFpbGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICB0cmFpbGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorfQorIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICBzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cykKKyAgcmV0dXJuIHRyYWlsaW5nX2NvbW1lbnRzXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpyZWxlYXNlX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICBjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgcmV0dXJuIHRyYWlsaW5nX2NvbW1lbnRzXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9hbGxvY2F0ZWRfdHJhaWxpbmdfY29tbWVudHMoOjpzdGQ6OnN0cmluZyogdHJhaWxpbmdfY29tbWVudHMpIHsKKyAgaWYgKHRyYWlsaW5nX2NvbW1lbnRzICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIH0KKyAgdHJhaWxpbmdfY29tbWVudHNfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB0cmFpbGluZ19jb21tZW50cyk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cykKK30KKworLy8gcmVwZWF0ZWQgc3RyaW5nIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgPSA2OworIGludCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bGVhZGluZ19kZXRhY2hlZF9jb21tZW50c19zaXplKCkgY29uc3QgeworICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uc2l6ZSgpOworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5HZXQoaW5kZXgpOworfQorIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTXV0YWJsZShpbmRleCk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTXV0YWJsZShpbmRleCktPmFzc2lnbigKKyAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9CisgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgeworICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICByZXR1cm4gJmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFNvdXJjZUNvZGVJbmZvCisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24gbG9jYXRpb24gPSAxOworIGludCBTb3VyY2VDb2RlSW5mbzo6bG9jYXRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGxvY2F0aW9uXy5zaXplKCk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mbzo6Y2xlYXJfbG9jYXRpb24oKSB7CisgIGxvY2F0aW9uXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24mIFNvdXJjZUNvZGVJbmZvOjpsb2NhdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl8uR2V0KGluZGV4KTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBTb3VyY2VDb2RlSW5mbzo6bXV0YWJsZV9sb2NhdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLmxvY2F0aW9uKQorICByZXR1cm4gbG9jYXRpb25fLk11dGFibGUoaW5kZXgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24qIFNvdXJjZUNvZGVJbmZvOjphZGRfbG9jYXRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLmxvY2F0aW9uKQorICByZXR1cm4gbG9jYXRpb25fLkFkZCgpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiA+JgorU291cmNlQ29kZUluZm86OmxvY2F0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uID4qCitTb3VyY2VDb2RlSW5mbzo6bXV0YWJsZV9sb2NhdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiAmbG9jYXRpb25fOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDhjYmE2NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oCkBAIC0wLDAgKzEsNjcxOCBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90b19fSU5DTFVERUQKKyNkZWZpbmUgUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG9fX0lOQ0xVREVECisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IDMwMDAwMDAKKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZSB1cGRhdGUKKyNlcnJvciB5b3VyIGhlYWRlcnMuCisjZW5kaWYKKyNpZiAzMDAwMDAwIDwgR09PR0xFX1BST1RPQlVGX01JTl9QUk9UT0NfVkVSU0lPTgorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZQorI2Vycm9yIHJlZ2VuZXJhdGUgdGhpcyBmaWxlIHdpdGggYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYy4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKK2NsYXNzIEZpbGVEZXNjcmlwdG9yU2V0OworY2xhc3MgRmlsZURlc2NyaXB0b3JQcm90bzsKK2NsYXNzIERlc2NyaXB0b3JQcm90bzsKK2NsYXNzIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTsKK2NsYXNzIEZpZWxkRGVzY3JpcHRvclByb3RvOworY2xhc3MgT25lb2ZEZXNjcmlwdG9yUHJvdG87CitjbGFzcyBFbnVtRGVzY3JpcHRvclByb3RvOworY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOworY2xhc3MgU2VydmljZURlc2NyaXB0b3JQcm90bzsKK2NsYXNzIE1ldGhvZERlc2NyaXB0b3JQcm90bzsKK2NsYXNzIEZpbGVPcHRpb25zOworY2xhc3MgTWVzc2FnZU9wdGlvbnM7CitjbGFzcyBGaWVsZE9wdGlvbnM7CitjbGFzcyBFbnVtT3B0aW9uczsKK2NsYXNzIEVudW1WYWx1ZU9wdGlvbnM7CitjbGFzcyBTZXJ2aWNlT3B0aW9uczsKK2NsYXNzIE1ldGhvZE9wdGlvbnM7CitjbGFzcyBVbmludGVycHJldGVkT3B0aW9uOworY2xhc3MgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDsKK2NsYXNzIFNvdXJjZUNvZGVJbmZvOworY2xhc3MgU291cmNlQ29kZUluZm9fTG9jYXRpb247CisKK2VudW0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9ET1VCTEUgPSAxLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRkxPQVQgPSAyLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfSU5UNjQgPSAzLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfVUlOVDY0ID0gNCwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0lOVDMyID0gNSwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0ZJWEVENjQgPSA2LAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRklYRUQzMiA9IDcsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9CT09MID0gOCwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1NUUklORyA9IDksCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9HUk9VUCA9IDEwLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfTUVTU0FHRSA9IDExLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfQllURVMgPSAxMiwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1VJTlQzMiA9IDEzLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRU5VTSA9IDE0LAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfU0ZJWEVEMzIgPSAxNSwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1NGSVhFRDY0ID0gMTYsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TSU5UMzIgPSAxNywKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1NJTlQ2NCA9IDE4Cit9OworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9Jc1ZhbGlkKGludCB2YWx1ZSk7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVHlwZV9NSU4gPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRE9VQkxFOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfTUFYID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1NJTlQ2NDsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfQVJSQVlTSVpFID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UeXBlX01BWCArIDE7CisKK0xJQlBST1RPQlVGX0VYUE9SVCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX05hbWUoRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmFtZU9mRW51bSgKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9QYXJzZSgKKyAgICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlKiB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UGFyc2VOYW1lZEVudW08RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZT4oCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yKCksIG5hbWUsIHZhbHVlKTsKK30KK2VudW0gRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgeworICBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MQUJFTF9PUFRJT05BTCA9IDEsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX1JFUVVJUkVEID0gMiwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfUkVQRUFURUQgPSAzCit9OworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfSXNWYWxpZChpbnQgdmFsdWUpOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTGFiZWxfTUlOID0gRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfT1BUSU9OQUw7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MYWJlbF9NQVggPSBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MQUJFTF9SRVBFQVRFRDsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MYWJlbF9BUlJBWVNJWkUgPSBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MYWJlbF9NQVggKyAxOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfZGVzY3JpcHRvcigpOworaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX05hbWUoRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hbWVPZkVudW0oCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfZGVzY3JpcHRvcigpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9QYXJzZSgKKyAgICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCogdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlBhcnNlTmFtZWRFbnVtPEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsPigKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCksIG5hbWUsIHZhbHVlKTsKK30KK2VudW0gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIHsKKyAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX1NQRUVEID0gMSwKKyAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0NPREVfU0laRSA9IDIsCisgIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9MSVRFX1JVTlRJTUUgPSAzCit9OworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0lzVmFsaWQoaW50IHZhbHVlKTsKK2NvbnN0IEZpbGVPcHRpb25zX09wdGltaXplTW9kZSBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfT3B0aW1pemVNb2RlX01JTiA9IEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9TUEVFRDsKK2NvbnN0IEZpbGVPcHRpb25zX09wdGltaXplTW9kZSBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfT3B0aW1pemVNb2RlX01BWCA9IEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9MSVRFX1JVTlRJTUU7Citjb25zdCBpbnQgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9BUlJBWVNJWkUgPSBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfT3B0aW1pemVNb2RlX01BWCArIDE7CisKK0xJQlBST1RPQlVGX0VYUE9SVCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfZGVzY3JpcHRvcigpOworaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9OYW1lKEZpbGVPcHRpb25zX09wdGltaXplTW9kZSB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmFtZU9mRW51bSgKKyAgICBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfZGVzY3JpcHRvcigpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfUGFyc2UoCisgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlKiB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UGFyc2VOYW1lZEVudW08RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlPigKKyAgICBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7Cit9CitlbnVtIEZpZWxkT3B0aW9uc19DVHlwZSB7CisgIEZpZWxkT3B0aW9uc19DVHlwZV9TVFJJTkcgPSAwLAorICBGaWVsZE9wdGlvbnNfQ1R5cGVfQ09SRCA9IDEsCisgIEZpZWxkT3B0aW9uc19DVHlwZV9TVFJJTkdfUElFQ0UgPSAyCit9OworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgRmllbGRPcHRpb25zX0NUeXBlX0lzVmFsaWQoaW50IHZhbHVlKTsKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnNfQ1R5cGVfQ1R5cGVfTUlOID0gRmllbGRPcHRpb25zX0NUeXBlX1NUUklORzsKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnNfQ1R5cGVfQ1R5cGVfTUFYID0gRmllbGRPcHRpb25zX0NUeXBlX1NUUklOR19QSUVDRTsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnNfQ1R5cGVfQ1R5cGVfQVJSQVlTSVpFID0gRmllbGRPcHRpb25zX0NUeXBlX0NUeXBlX01BWCArIDE7CisKK0xJQlBST1RPQlVGX0VYUE9SVCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZE9wdGlvbnNfQ1R5cGVfZGVzY3JpcHRvcigpOworaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkT3B0aW9uc19DVHlwZV9OYW1lKEZpZWxkT3B0aW9uc19DVHlwZSB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmFtZU9mRW51bSgKKyAgICBGaWVsZE9wdGlvbnNfQ1R5cGVfZGVzY3JpcHRvcigpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZE9wdGlvbnNfQ1R5cGVfUGFyc2UoCisgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwgRmllbGRPcHRpb25zX0NUeXBlKiB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UGFyc2VOYW1lZEVudW08RmllbGRPcHRpb25zX0NUeXBlPigKKyAgICBGaWVsZE9wdGlvbnNfQ1R5cGVfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7Cit9CisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWxlRGVzY3JpcHRvclNldCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRmlsZURlc2NyaXB0b3JTZXQoKTsKKyAgdmlydHVhbCB+RmlsZURlc2NyaXB0b3JTZXQoKTsKKworICBGaWxlRGVzY3JpcHRvclNldChjb25zdCBGaWxlRGVzY3JpcHRvclNldCYgZnJvbSk7CisKKyAgaW5saW5lIEZpbGVEZXNjcmlwdG9yU2V0JiBvcGVyYXRvcj0oY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRmlsZURlc2NyaXB0b3JTZXQqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBGaWxlRGVzY3JpcHRvclNldCogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRmlsZURlc2NyaXB0b3JTZXQqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBGaWxlRGVzY3JpcHRvclNldCYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yU2V0JiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRmlsZURlc2NyaXB0b3JTZXQqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBmaWxlID0gMTsKKyAgaW50IGZpbGVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2ZpbGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmlsZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvJiBmaWxlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogbXV0YWJsZV9maWxlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogYWRkX2ZpbGUoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGZpbGUoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfZmlsZSgpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQpCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4gZmlsZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEZpbGVEZXNjcmlwdG9yU2V0KiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWxlRGVzY3JpcHRvclByb3RvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBGaWxlRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgfkZpbGVEZXNjcmlwdG9yUHJvdG8oKTsKKworICBGaWxlRGVzY3JpcHRvclByb3RvKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBGaWxlRGVzY3JpcHRvclByb3RvJiBvcGVyYXRvcj0oY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEZpbGVEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBGaWxlRGVzY3JpcHRvclByb3RvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWxlRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWxlRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHBhY2thZ2UgPSAyOworICBib29sIGhhc19wYWNrYWdlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfcGFja2FnZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtQYWNrYWdlRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBwYWNrYWdlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3BhY2thZ2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3BhY2thZ2UoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9wYWNrYWdlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIHBhY2thZ2UpOworCisgIC8vIHJlcGVhdGVkIHN0cmluZyBkZXBlbmRlbmN5ID0gMzsKKyAgaW50IGRlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcGVuZGVuY3koKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwZW5kZW5jeUZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0OworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2RlcGVuZGVuY3koaW50IGluZGV4KTsKKyAgdm9pZCBzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIGFkZF9kZXBlbmRlbmN5KCk7CisgIHZvaWQgYWRkX2RlcGVuZGVuY3koY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIGFkZF9kZXBlbmRlbmN5KGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBhZGRfZGVwZW5kZW5jeShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JiBkZXBlbmRlbmN5KCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qIG11dGFibGVfZGVwZW5kZW5jeSgpOworCisgIC8vIHJlcGVhdGVkIGludDMyIHB1YmxpY19kZXBlbmRlbmN5ID0gMTA7CisgIGludCBwdWJsaWNfZGVwZW5kZW5jeV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfcHVibGljX2RlcGVuZGVuY3koKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUHVibGljRGVwZW5kZW5jeUZpZWxkTnVtYmVyID0gMTA7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgcHVibGljX2RlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdDsKKyAgdm9pZCBzZXRfcHVibGljX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgdm9pZCBhZGRfcHVibGljX2RlcGVuZGVuY3koOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorICAgICAgcHVibGljX2RlcGVuZGVuY3koKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCisgICAgICBtdXRhYmxlX3B1YmxpY19kZXBlbmRlbmN5KCk7CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgd2Vha19kZXBlbmRlbmN5ID0gMTE7CisgIGludCB3ZWFrX2RlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3dlYWtfZGVwZW5kZW5jeSgpOworICBzdGF0aWMgY29uc3QgaW50IGtXZWFrRGVwZW5kZW5jeUZpZWxkTnVtYmVyID0gMTE7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgd2Vha19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3Q7CisgIHZvaWQgc2V0X3dlYWtfZGVwZW5kZW5jeShpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworICB2b2lkIGFkZF93ZWFrX2RlcGVuZGVuY3koOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorICAgICAgd2Vha19kZXBlbmRlbmN5KCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorICAgICAgbXV0YWJsZV93ZWFrX2RlcGVuZGVuY3koKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBtZXNzYWdlX3R5cGUgPSA0OworICBpbnQgbWVzc2FnZV90eXBlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9tZXNzYWdlX3R5cGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVR5cGVGaWVsZE51bWJlciA9IDQ7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvJiBtZXNzYWdlX3R5cGUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfbWVzc2FnZV90eXBlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBhZGRfbWVzc2FnZV90eXBlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIG1lc3NhZ2VfdHlwZSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX21lc3NhZ2VfdHlwZSgpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA1OworICBpbnQgZW51bV90eXBlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9lbnVtX3R5cGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRW51bVR5cGVGaWVsZE51bWJlciA9IDU7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byYgZW51bV90eXBlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogbXV0YWJsZV9lbnVtX3R5cGUoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBhZGRfZW51bV90eXBlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4mCisgICAgICBlbnVtX3R5cGUoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfZW51bV90eXBlKCk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworICBpbnQgc2VydmljZV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc2VydmljZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtTZXJ2aWNlRmllbGROdW1iZXIgPSA2OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIHNlcnZpY2UoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX3NlcnZpY2UoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBhZGRfc2VydmljZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byA+JgorICAgICAgc2VydmljZSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byA+KgorICAgICAgbXV0YWJsZV9zZXJ2aWNlKCk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA3OworICBpbnQgZXh0ZW5zaW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9leHRlbnNpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXh0ZW5zaW9uRmllbGROdW1iZXIgPSA3OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBleHRlbnNpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogbXV0YWJsZV9leHRlbnNpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogYWRkX2V4dGVuc2lvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGV4dGVuc2lvbigpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfZXh0ZW5zaW9uKCk7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gODsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKiBtdXRhYmxlX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIG9wdGlvbnMpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8gc291cmNlX2NvZGVfaW5mbyA9IDk7CisgIGJvb2wgaGFzX3NvdXJjZV9jb2RlX2luZm8oKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zb3VyY2VfY29kZV9pbmZvKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1NvdXJjZUNvZGVJbmZvRmllbGROdW1iZXIgPSA5OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvJiBzb3VyY2VfY29kZV9pbmZvKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIG11dGFibGVfc291cmNlX2NvZGVfaW5mbygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiByZWxlYXNlX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX3NvdXJjZV9jb2RlX2luZm8oOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogc291cmNlX2NvZGVfaW5mbyk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICBib29sIGhhc19zeW50YXgoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zeW50YXgoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU3ludGF4RmllbGROdW1iZXIgPSAxMjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgc3ludGF4KCkgY29uc3Q7CisgIHZvaWQgc2V0X3N5bnRheChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3N5bnRheChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3N5bnRheChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3N5bnRheCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3N5bnRheCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfc3ludGF4KDo6c3RkOjpzdHJpbmcqIHN5bnRheCk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3BhY2thZ2UoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfc291cmNlX2NvZGVfaW5mbygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfc291cmNlX2NvZGVfaW5mbygpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3N5bnRheCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfc3ludGF4KCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgcGFja2FnZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4gZGVwZW5kZW5jeV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+IHB1YmxpY19kZXBlbmRlbmN5XzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4gd2Vha19kZXBlbmRlbmN5XzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+IG1lc3NhZ2VfdHlwZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4gZW51bV90eXBlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gPiBzZXJ2aWNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4gZXh0ZW5zaW9uXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogb3B0aW9uc187CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIHNvdXJjZV9jb2RlX2luZm9fOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBzeW50YXhfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGaWxlRGVzY3JpcHRvclByb3RvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSgpOworICB2aXJ0dWFsIH5EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UoKTsKKworICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UoY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKTsKKworICBpbmxpbmUgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBvcGVyYXRvcj0oY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworICBib29sIGhhc19zdGFydCgpIGNvbnN0OworICB2b2lkIGNsZWFyX3N0YXJ0KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1N0YXJ0RmllbGROdW1iZXIgPSAxOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHN0YXJ0KCkgY29uc3Q7CisgIHZvaWQgc2V0X3N0YXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgIGJvb2wgaGFzX2VuZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2VuZCgpOworICBzdGF0aWMgY29uc3QgaW50IGtFbmRGaWVsZE51bWJlciA9IDI7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgZW5kKCkgY29uc3Q7CisgIHZvaWQgc2V0X2VuZCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX3N0YXJ0KCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19zdGFydCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2VuZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZW5kKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHN0YXJ0XzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBlbmRfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIERlc2NyaXB0b3JQcm90byA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgfkRlc2NyaXB0b3JQcm90bygpOworCisgIERlc2NyaXB0b3JQcm90byhjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBEZXNjcmlwdG9yUHJvdG8mIG9wZXJhdG9yPShjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKERlc2NyaXB0b3JQcm90byogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIERlc2NyaXB0b3JQcm90byogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgdHlwZWRlZiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgRXh0ZW5zaW9uUmFuZ2U7CisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CisgIGludCBmaWVsZF9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZmllbGQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmllbGRGaWVsZE51bWJlciA9IDI7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfZmllbGQoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogYWRkX2ZpZWxkKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+JgorICAgICAgZmllbGQoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX2ZpZWxkKCk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA2OworICBpbnQgZXh0ZW5zaW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9leHRlbnNpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXh0ZW5zaW9uRmllbGROdW1iZXIgPSA2OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBleHRlbnNpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogbXV0YWJsZV9leHRlbnNpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogYWRkX2V4dGVuc2lvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGV4dGVuc2lvbigpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfZXh0ZW5zaW9uKCk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICBpbnQgbmVzdGVkX3R5cGVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX25lc3RlZF90eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05lc3RlZFR5cGVGaWVsZE51bWJlciA9IDM7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvJiBuZXN0ZWRfdHlwZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogbXV0YWJsZV9uZXN0ZWRfdHlwZShpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogYWRkX25lc3RlZF90eXBlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIG5lc3RlZF90eXBlKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfbmVzdGVkX3R5cGUoKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNDsKKyAgaW50IGVudW1fdHlwZV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZW51bV90eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0VudW1UeXBlRmllbGROdW1iZXIgPSA0OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8mIGVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfZW51bV90eXBlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogYWRkX2VudW1fdHlwZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+JgorICAgICAgZW51bV90eXBlKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX2VudW1fdHlwZSgpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlIGV4dGVuc2lvbl9yYW5nZSA9IDU7CisgIGludCBleHRlbnNpb25fcmFuZ2Vfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2V4dGVuc2lvbl9yYW5nZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtFeHRlbnNpb25SYW5nZUZpZWxkTnVtYmVyID0gNTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIGV4dGVuc2lvbl9yYW5nZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogbXV0YWJsZV9leHRlbnNpb25fcmFuZ2UoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIGFkZF9leHRlbnNpb25fcmFuZ2UoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSA+JgorICAgICAgZXh0ZW5zaW9uX3JhbmdlKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPioKKyAgICAgIG11dGFibGVfZXh0ZW5zaW9uX3JhbmdlKCk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKyAgaW50IG9uZW9mX2RlY2xfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX29uZW9mX2RlY2woKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT25lb2ZEZWNsRmllbGROdW1iZXIgPSA4OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvJiBvbmVvZl9kZWNsKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfb25lb2ZfZGVjbChpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvKiBhZGRfb25lb2ZfZGVjbCgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIG9uZW9mX2RlY2woKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX29uZW9mX2RlY2woKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworICBib29sIGhhc19vcHRpb25zKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfb3B0aW9ucygpOworICBzdGF0aWMgY29uc3QgaW50IGtPcHRpb25zRmllbGROdW1iZXIgPSA3OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIG11dGFibGVfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiByZWxlYXNlX29wdGlvbnMoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogb3B0aW9ucyk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfb3B0aW9ucygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb3B0aW9ucygpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+IGZpZWxkXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4gZXh0ZW5zaW9uXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+IG5lc3RlZF90eXBlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPiBlbnVtX3R5cGVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlID4gZXh0ZW5zaW9uX3JhbmdlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4gb25lb2ZfZGVjbF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIG9wdGlvbnNfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBEZXNjcmlwdG9yUHJvdG8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkRGVzY3JpcHRvclByb3RvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBGaWVsZERlc2NyaXB0b3JQcm90bygpOworICB2aXJ0dWFsIH5GaWVsZERlc2NyaXB0b3JQcm90bygpOworCisgIEZpZWxkRGVzY3JpcHRvclByb3RvKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKworICBpbmxpbmUgRmllbGREZXNjcmlwdG9yUHJvdG8mIG9wZXJhdG9yPShjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChGaWVsZERlc2NyaXB0b3JQcm90byogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEZpZWxkRGVzY3JpcHRvclByb3RvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWVsZERlc2NyaXB0b3JQcm90byogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWVsZERlc2NyaXB0b3JQcm90byogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBUeXBlOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0RPVUJMRSA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9ET1VCTEU7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfRkxPQVQgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRkxPQVQ7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfSU5UNjQgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfSU5UNjQ7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfVUlOVDY0ID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1VJTlQ2NDsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9JTlQzMiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9JTlQzMjsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9GSVhFRDY0ID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0ZJWEVENjQ7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfRklYRUQzMiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9GSVhFRDMyOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0JPT0wgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfQk9PTDsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TVFJJTkcgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfU1RSSU5HOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0dST1VQID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0dST1VQOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX01FU1NBR0UgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfTUVTU0FHRTsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9CWVRFUyA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9CWVRFUzsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9VSU5UMzIgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfVUlOVDMyOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0VOVU0gPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRU5VTTsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TRklYRUQzMiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TRklYRUQzMjsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TRklYRUQ2NCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TRklYRUQ2NDsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TSU5UMzIgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfU0lOVDMyOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX1NJTlQ2NCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TSU5UNjQ7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBUeXBlX0lzVmFsaWQoaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfSXNWYWxpZCh2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGNvbnN0IFR5cGUgVHlwZV9NSU4gPQorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVHlwZV9NSU47CisgIHN0YXRpYyBjb25zdCBUeXBlIFR5cGVfTUFYID0KKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfTUFYOworICBzdGF0aWMgY29uc3QgaW50IFR5cGVfQVJSQVlTSVpFID0KKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfQVJSQVlTSVpFOworICBzdGF0aWMgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqCisgIFR5cGVfZGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBUeXBlX05hbWUoVHlwZSB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX05hbWUodmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBUeXBlX1BhcnNlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsCisgICAgICBUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgTGFiZWw7CisgIHN0YXRpYyBjb25zdCBMYWJlbCBMQUJFTF9PUFRJT05BTCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX09QVElPTkFMOworICBzdGF0aWMgY29uc3QgTGFiZWwgTEFCRUxfUkVRVUlSRUQgPSBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MQUJFTF9SRVFVSVJFRDsKKyAgc3RhdGljIGNvbnN0IExhYmVsIExBQkVMX1JFUEVBVEVEID0gRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfUkVQRUFURUQ7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBMYWJlbF9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9Jc1ZhbGlkKHZhbHVlKTsKKyAgfQorICBzdGF0aWMgY29uc3QgTGFiZWwgTGFiZWxfTUlOID0KKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MYWJlbF9NSU47CisgIHN0YXRpYyBjb25zdCBMYWJlbCBMYWJlbF9NQVggPQorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xhYmVsX01BWDsKKyAgc3RhdGljIGNvbnN0IGludCBMYWJlbF9BUlJBWVNJWkUgPQorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xhYmVsX0FSUkFZU0laRTsKKyAgc3RhdGljIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKgorICBMYWJlbF9kZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBMYWJlbF9OYW1lKExhYmVsIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX05hbWUodmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBMYWJlbF9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLAorICAgICAgTGFiZWwqIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgIGJvb2wgaGFzX251bWJlcigpIGNvbnN0OworICB2b2lkIGNsZWFyX251bWJlcigpOworICBzdGF0aWMgY29uc3QgaW50IGtOdW1iZXJGaWVsZE51bWJlciA9IDM7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbnVtYmVyKCkgY29uc3Q7CisgIHZvaWQgc2V0X251bWJlcig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsIGxhYmVsID0gNDsKKyAgYm9vbCBoYXNfbGFiZWwoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9sYWJlbCgpOworICBzdGF0aWMgY29uc3QgaW50IGtMYWJlbEZpZWxkTnVtYmVyID0gNDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBsYWJlbCgpIGNvbnN0OworICB2b2lkIHNldF9sYWJlbCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgIGJvb2wgaGFzX3R5cGUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl90eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1R5cGVGaWVsZE51bWJlciA9IDU7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB0eXBlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3R5cGUoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKKyAgYm9vbCBoYXNfdHlwZV9uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdHlwZV9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1R5cGVOYW1lRmllbGROdW1iZXIgPSA2OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB0eXBlX25hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfdHlwZV9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfdHlwZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfdHlwZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF90eXBlX25hbWUoOjpzdGQ6OnN0cmluZyogdHlwZV9uYW1lKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworICBib29sIGhhc19leHRlbmRlZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2V4dGVuZGVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0V4dGVuZGVlRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBleHRlbmRlZSgpIGNvbnN0OworICB2b2lkIHNldF9leHRlbmRlZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2V4dGVuZGVlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfZXh0ZW5kZWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9leHRlbmRlZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2V4dGVuZGVlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9leHRlbmRlZSg6OnN0ZDo6c3RyaW5nKiBleHRlbmRlZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworICBib29sIGhhc19kZWZhdWx0X3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZGVmYXVsdF92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtEZWZhdWx0VmFsdWVGaWVsZE51bWJlciA9IDc7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGRlZmF1bHRfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVmYXVsdF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfZGVmYXVsdF92YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2RlZmF1bHRfdmFsdWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2RlZmF1bHRfdmFsdWUoOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA5OworICBib29sIGhhc19vbmVvZl9pbmRleCgpIGNvbnN0OworICB2b2lkIGNsZWFyX29uZW9mX2luZGV4KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09uZW9mSW5kZXhGaWVsZE51bWJlciA9IDk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgb25lb2ZfaW5kZXgoKSBjb25zdDsKKyAgdm9pZCBzZXRfb25lb2ZfaW5kZXgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgb3B0aW9ucyA9IDg7CisgIGJvb2wgaGFzX29wdGlvbnMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vcHRpb25zKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09wdGlvbnNGaWVsZE51bWJlciA9IDg7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiBtdXRhYmxlX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIHJlbGVhc2Vfb3B0aW9ucygpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogb3B0aW9ucyk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19udW1iZXIoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX251bWJlcigpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2xhYmVsKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19sYWJlbCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3R5cGVfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19leHRlbmRlZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vbmVvZl9pbmRleCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb25lb2ZfaW5kZXgoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vcHRpb25zKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBudW1iZXJfOworICBpbnQgbGFiZWxfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciB0eXBlX25hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBleHRlbmRlZV87CisgIGludCB0eXBlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBvbmVvZl9pbmRleF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGRlZmF1bHRfdmFsdWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogb3B0aW9uc187CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEZpZWxkRGVzY3JpcHRvclByb3RvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBPbmVvZkRlc2NyaXB0b3JQcm90byA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG8oKTsKKyAgdmlydHVhbCB+T25lb2ZEZXNjcmlwdG9yUHJvdG8oKTsKKworICBPbmVvZkRlc2NyaXB0b3JQcm90byhjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgZnJvbSk7CisKKyAgaW5saW5lIE9uZW9mRGVzY3JpcHRvclByb3RvJiBvcGVyYXRvcj0oY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBPbmVvZkRlc2NyaXB0b3JQcm90byogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG8qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgYm9vbCBoYXNfbmFtZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSgpIGNvbnN0OworICB2b2lkIHNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIE9uZW9mRGVzY3JpcHRvclByb3RvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBFbnVtRGVzY3JpcHRvclByb3RvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBFbnVtRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgfkVudW1EZXNjcmlwdG9yUHJvdG8oKTsKKworICBFbnVtRGVzY3JpcHRvclByb3RvKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBFbnVtRGVzY3JpcHRvclByb3RvJiBvcGVyYXRvcj0oY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEVudW1EZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBFbnVtRGVzY3JpcHRvclByb3RvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBFbnVtRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChFbnVtRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworICBpbnQgdmFsdWVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1ZhbHVlRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgdmFsdWUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfdmFsdWUoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIGFkZF92YWx1ZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4mCisgICAgICB2YWx1ZSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX3ZhbHVlKCk7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBtdXRhYmxlX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIG9wdGlvbnMpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90bykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vcHRpb25zKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byA+IHZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogb3B0aW9uc187CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEVudW1EZXNjcmlwdG9yUHJvdG8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgfkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bygpOworCisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byhjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIG9wZXJhdG9yPShjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKKyAgYm9vbCBoYXNfbnVtYmVyKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbnVtYmVyKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga051bWJlckZpZWxkTnVtYmVyID0gMjsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBudW1iZXIoKSBjb25zdDsKKyAgdm9pZCBzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogbXV0YWJsZV9vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogb3B0aW9ucyk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfbnVtYmVyKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19udW1iZXIoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vcHRpb25zKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zKiBvcHRpb25zXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBudW1iZXJfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oKTsKKyAgdmlydHVhbCB+U2VydmljZURlc2NyaXB0b3JQcm90bygpOworCisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisKKyAgaW5saW5lIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIG9wZXJhdG9yPShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoU2VydmljZURlc2NyaXB0b3JQcm90byogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgYm9vbCBoYXNfbmFtZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSgpIGNvbnN0OworICB2b2lkIHNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90byBtZXRob2QgPSAyOworICBpbnQgbWV0aG9kX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9tZXRob2QoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTWV0aG9kRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byYgbWV0aG9kKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX21ldGhvZChpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byogYWRkX21ldGhvZCgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvID4mCisgICAgICBtZXRob2QoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+KgorICAgICAgbXV0YWJsZV9tZXRob2QoKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworICBib29sIGhhc19vcHRpb25zKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfb3B0aW9ucygpOworICBzdGF0aWMgY29uc3QgaW50IGtPcHRpb25zRmllbGROdW1iZXIgPSAzOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIG11dGFibGVfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiByZWxlYXNlX29wdGlvbnMoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogb3B0aW9ucyk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX29wdGlvbnMoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvID4gbWV0aG9kXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogb3B0aW9uc187CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1ldGhvZERlc2NyaXB0b3JQcm90byA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgfk1ldGhvZERlc2NyaXB0b3JQcm90bygpOworCisgIE1ldGhvZERlc2NyaXB0b3JQcm90byhjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBNZXRob2REZXNjcmlwdG9yUHJvdG8mIG9wZXJhdG9yPShjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKE1ldGhvZERlc2NyaXB0b3JQcm90byogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIE1ldGhvZERlc2NyaXB0b3JQcm90byogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoTWV0aG9kRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGlucHV0X3R5cGUgPSAyOworICBib29sIGhhc19pbnB1dF90eXBlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfaW5wdXRfdHlwZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtJbnB1dFR5cGVGaWVsZE51bWJlciA9IDI7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGlucHV0X3R5cGUoKSBjb25zdDsKKyAgdm9pZCBzZXRfaW5wdXRfdHlwZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2lucHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9pbnB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfaW5wdXRfdHlwZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2lucHV0X3R5cGUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2lucHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogaW5wdXRfdHlwZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKKyAgYm9vbCBoYXNfb3V0cHV0X3R5cGUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vdXRwdXRfdHlwZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtPdXRwdXRUeXBlRmllbGROdW1iZXIgPSAzOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBvdXRwdXRfdHlwZSgpIGNvbnN0OworICB2b2lkIHNldF9vdXRwdXRfdHlwZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X291dHB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfb3V0cHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9vdXRwdXRfdHlwZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX291dHB1dF90eXBlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vdXRwdXRfdHlwZSg6OnN0ZDo6c3RyaW5nKiBvdXRwdXRfdHlwZSk7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIG9wdGlvbnMgPSA0OworICBib29sIGhhc19vcHRpb25zKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfb3B0aW9ucygpOworICBzdGF0aWMgY29uc3QgaW50IGtPcHRpb25zRmllbGROdW1iZXIgPSA0OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBtdXRhYmxlX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiByZWxlYXNlX29wdGlvbnMoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBvcHRpb25zKTsKKworICAvLyBvcHRpb25hbCBib29sIGNsaWVudF9zdHJlYW1pbmcgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19jbGllbnRfc3RyZWFtaW5nKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfY2xpZW50X3N0cmVhbWluZygpOworICBzdGF0aWMgY29uc3QgaW50IGtDbGllbnRTdHJlYW1pbmdGaWVsZE51bWJlciA9IDU7CisgIGJvb2wgY2xpZW50X3N0cmVhbWluZygpIGNvbnN0OworICB2b2lkIHNldF9jbGllbnRfc3RyZWFtaW5nKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgc2VydmVyX3N0cmVhbWluZyA9IDYgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zZXJ2ZXJfc3RyZWFtaW5nKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1NlcnZlclN0cmVhbWluZ0ZpZWxkTnVtYmVyID0gNjsKKyAgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nKCkgY29uc3Q7CisgIHZvaWQgc2V0X3NlcnZlcl9zdHJlYW1pbmcoYm9vbCB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfaW5wdXRfdHlwZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfaW5wdXRfdHlwZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vdXRwdXRfdHlwZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19jbGllbnRfc3RyZWFtaW5nKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19jbGllbnRfc3RyZWFtaW5nKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfc2VydmVyX3N0cmVhbWluZygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfc2VydmVyX3N0cmVhbWluZygpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGlucHV0X3R5cGVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBvdXRwdXRfdHlwZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogb3B0aW9uc187CisgIGJvb2wgY2xpZW50X3N0cmVhbWluZ187CisgIGJvb2wgc2VydmVyX3N0cmVhbWluZ187CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIE1ldGhvZERlc2NyaXB0b3JQcm90byogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmlsZU9wdGlvbnMgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEZpbGVPcHRpb25zKCk7CisgIHZpcnR1YWwgfkZpbGVPcHRpb25zKCk7CisKKyAgRmlsZU9wdGlvbnMoY29uc3QgRmlsZU9wdGlvbnMmIGZyb20pOworCisgIGlubGluZSBGaWxlT3B0aW9ucyYgb3BlcmF0b3I9KGNvbnN0IEZpbGVPcHRpb25zJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEZpbGVPcHRpb25zJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEZpbGVPcHRpb25zKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRmlsZU9wdGlvbnMqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEZpbGVPcHRpb25zKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRmlsZU9wdGlvbnMmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBGaWxlT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEZpbGVPcHRpb25zKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgdHlwZWRlZiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgT3B0aW1pemVNb2RlOworICBzdGF0aWMgY29uc3QgT3B0aW1pemVNb2RlIFNQRUVEID0gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX1NQRUVEOworICBzdGF0aWMgY29uc3QgT3B0aW1pemVNb2RlIENPREVfU0laRSA9IEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9DT0RFX1NJWkU7CisgIHN0YXRpYyBjb25zdCBPcHRpbWl6ZU1vZGUgTElURV9SVU5USU1FID0gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0xJVEVfUlVOVElNRTsKKyAgc3RhdGljIGlubGluZSBib29sIE9wdGltaXplTW9kZV9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICAgIHJldHVybiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfSXNWYWxpZCh2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGNvbnN0IE9wdGltaXplTW9kZSBPcHRpbWl6ZU1vZGVfTUlOID0KKyAgICBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfT3B0aW1pemVNb2RlX01JTjsKKyAgc3RhdGljIGNvbnN0IE9wdGltaXplTW9kZSBPcHRpbWl6ZU1vZGVfTUFYID0KKyAgICBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfT3B0aW1pemVNb2RlX01BWDsKKyAgc3RhdGljIGNvbnN0IGludCBPcHRpbWl6ZU1vZGVfQVJSQVlTSVpFID0KKyAgICBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfT3B0aW1pemVNb2RlX0FSUkFZU0laRTsKKyAgc3RhdGljIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKgorICBPcHRpbWl6ZU1vZGVfZGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE9wdGltaXplTW9kZV9OYW1lKE9wdGltaXplTW9kZSB2YWx1ZSkgeworICAgIHJldHVybiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfTmFtZSh2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSBib29sIE9wdGltaXplTW9kZV9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLAorICAgICAgT3B0aW1pemVNb2RlKiB2YWx1ZSkgeworICAgIHJldHVybiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfUGFyc2UobmFtZSwgdmFsdWUpOworICB9CisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9wYWNrYWdlID0gMTsKKyAgYm9vbCBoYXNfamF2YV9wYWNrYWdlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfamF2YV9wYWNrYWdlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0phdmFQYWNrYWdlRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBqYXZhX3BhY2thZ2UoKSBjb25zdDsKKyAgdm9pZCBzZXRfamF2YV9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfamF2YV9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfamF2YV9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfamF2YV9wYWNrYWdlKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfamF2YV9wYWNrYWdlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9qYXZhX3BhY2thZ2UoOjpzdGQ6OnN0cmluZyogamF2YV9wYWNrYWdlKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworICBib29sIGhhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0phdmFPdXRlckNsYXNzbmFtZUZpZWxkTnVtYmVyID0gODsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgamF2YV9vdXRlcl9jbGFzc25hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfamF2YV9vdXRlcl9jbGFzc25hbWUoOjpzdGQ6OnN0cmluZyogamF2YV9vdXRlcl9jbGFzc25hbWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9tdWx0aXBsZV9maWxlcyA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBzdGF0aWMgY29uc3QgaW50IGtKYXZhTXVsdGlwbGVGaWxlc0ZpZWxkTnVtYmVyID0gMTA7CisgIGJvb2wgamF2YV9tdWx0aXBsZV9maWxlcygpIGNvbnN0OworICB2b2lkIHNldF9qYXZhX211bHRpcGxlX2ZpbGVzKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSAyMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworICBzdGF0aWMgY29uc3QgaW50IGtKYXZhR2VuZXJhdGVFcXVhbHNBbmRIYXNoRmllbGROdW1iZXIgPSAyMDsKKyAgYm9vbCBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIGNvbnN0OworICB2b2lkIHNldF9qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaChib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjggPSAyNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSmF2YVN0cmluZ0NoZWNrVXRmOEZpZWxkTnVtYmVyID0gMjc7CisgIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIGNvbnN0OworICB2b2lkIHNldF9qYXZhX3N0cmluZ19jaGVja191dGY4KGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvciA9IDkgW2RlZmF1bHQgPSBTUEVFRF07CisgIGJvb2wgaGFzX29wdGltaXplX2ZvcigpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGltaXplX2ZvcigpOworICBzdGF0aWMgY29uc3QgaW50IGtPcHRpbWl6ZUZvckZpZWxkTnVtYmVyID0gOTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgb3B0aW1pemVfZm9yKCkgY29uc3Q7CisgIHZvaWQgc2V0X29wdGltaXplX2Zvcig6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zX09wdGltaXplTW9kZSB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKKyAgYm9vbCBoYXNfZ29fcGFja2FnZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2dvX3BhY2thZ2UoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrR29QYWNrYWdlRmllbGROdW1iZXIgPSAxMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgZ29fcGFja2FnZSgpIGNvbnN0OworICB2b2lkIHNldF9nb19wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfZ29fcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2dvX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9nb19wYWNrYWdlKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfZ29fcGFja2FnZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfZ29fcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBnb19wYWNrYWdlKTsKKworICAvLyBvcHRpb25hbCBib29sIGNjX2dlbmVyaWNfc2VydmljZXMgPSAxNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0OworICB2b2lkIGNsZWFyX2NjX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQ2NHZW5lcmljU2VydmljZXNGaWVsZE51bWJlciA9IDE2OworICBib29sIGNjX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdDsKKyAgdm9pZCBzZXRfY2NfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IDE3IFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSmF2YUdlbmVyaWNTZXJ2aWNlc0ZpZWxkTnVtYmVyID0gMTc7CisgIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgY29uc3Q7CisgIHZvaWQgc2V0X2phdmFfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0OworICB2b2lkIGNsZWFyX3B5X2dlbmVyaWNfc2VydmljZXMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUHlHZW5lcmljU2VydmljZXNGaWVsZE51bWJlciA9IDE4OworICBib29sIHB5X2dlbmVyaWNfc2VydmljZXMoKSBjb25zdDsKKyAgdm9pZCBzZXRfcHlfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcHJlY2F0ZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwcmVjYXRlZEZpZWxkTnVtYmVyID0gMjM7CisgIGJvb2wgZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIHNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgY2NfZW5hYmxlX2FyZW5hcyA9IDMxIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19jY19lbmFibGVfYXJlbmFzKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfY2NfZW5hYmxlX2FyZW5hcygpOworICBzdGF0aWMgY29uc3QgaW50IGtDY0VuYWJsZUFyZW5hc0ZpZWxkTnVtYmVyID0gMzE7CisgIGJvb2wgY2NfZW5hYmxlX2FyZW5hcygpIGNvbnN0OworICB2b2lkIHNldF9jY19lbmFibGVfYXJlbmFzKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBvYmpjX2NsYXNzX3ByZWZpeCA9IDM2OworICBib29sIGhhc19vYmpjX2NsYXNzX3ByZWZpeCgpIGNvbnN0OworICB2b2lkIGNsZWFyX29iamNfY2xhc3NfcHJlZml4KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09iamNDbGFzc1ByZWZpeEZpZWxkTnVtYmVyID0gMzY7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG9iamNfY2xhc3NfcHJlZml4KCkgY29uc3Q7CisgIHZvaWQgc2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfb2JqY19jbGFzc19wcmVmaXgoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9vYmpjX2NsYXNzX3ByZWZpeChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX29iamNfY2xhc3NfcHJlZml4KCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2Vfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX29iamNfY2xhc3NfcHJlZml4KDo6c3RkOjpzdHJpbmcqIG9iamNfY2xhc3NfcHJlZml4KTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGludCB1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyID0gOTk5OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIGFkZF91bmludGVycHJldGVkX29wdGlvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKKyAgICAgIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKworICBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhGaWxlT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfamF2YV9wYWNrYWdlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpbWl6ZV9mb3IoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX29wdGltaXplX2ZvcigpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2dvX3BhY2thZ2UoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQgX2V4dGVuc2lvbnNfOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgamF2YV9wYWNrYWdlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgamF2YV9vdXRlcl9jbGFzc25hbWVfOworICBib29sIGphdmFfbXVsdGlwbGVfZmlsZXNfOworICBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXzsKKyAgYm9vbCBqYXZhX3N0cmluZ19jaGVja191dGY4XzsKKyAgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzXzsKKyAgaW50IG9wdGltaXplX2Zvcl87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGdvX3BhY2thZ2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBvYmpjX2NsYXNzX3ByZWZpeF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworICBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlc187CisgIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlc187CisgIGJvb2wgZGVwcmVjYXRlZF87CisgIGJvb2wgY2NfZW5hYmxlX2FyZW5hc187CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEZpbGVPcHRpb25zKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXNzYWdlT3B0aW9ucyA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgTWVzc2FnZU9wdGlvbnMoKTsKKyAgdmlydHVhbCB+TWVzc2FnZU9wdGlvbnMoKTsKKworICBNZXNzYWdlT3B0aW9ucyhjb25zdCBNZXNzYWdlT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIE1lc3NhZ2VPcHRpb25zJiBvcGVyYXRvcj0oY29uc3QgTWVzc2FnZU9wdGlvbnMmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgTWVzc2FnZU9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoTWVzc2FnZU9wdGlvbnMqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBNZXNzYWdlT3B0aW9ucyogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgTWVzc2FnZU9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNZXNzYWdlT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoTWVzc2FnZU9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIGNvbnN0OworICB2b2lkIGNsZWFyX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VTZXRXaXJlRm9ybWF0RmllbGROdW1iZXIgPSAxOworICBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgY29uc3Q7CisgIHZvaWQgc2V0X21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IDIgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3JGaWVsZE51bWJlciA9IDI7CisgIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIGNvbnN0OworICB2b2lkIHNldF9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2RlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9kZXByZWNhdGVkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlcHJlY2F0ZWRGaWVsZE51bWJlciA9IDM7CisgIGJvb2wgZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIHNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgYm9vbCBoYXNfbWFwX2VudHJ5KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbWFwX2VudHJ5KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01hcEVudHJ5RmllbGROdW1iZXIgPSA3OworICBib29sIG1hcF9lbnRyeSgpIGNvbnN0OworICB2b2lkIHNldF9tYXBfZW50cnkoYm9vbCB2YWx1ZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBpbnQgdW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlciA9IDk5OTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiB1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKKyAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCisgICAgICBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisKKyAgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9BQ0NFU1NPUlMoTWVzc2FnZU9wdGlvbnMpCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX21hcF9lbnRyeSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbWFwX2VudHJ5KCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0IF9leHRlbnNpb25zXzsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworICBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XzsKKyAgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgYm9vbCBtYXBfZW50cnlfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBNZXNzYWdlT3B0aW9ucyogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmllbGRPcHRpb25zIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBGaWVsZE9wdGlvbnMoKTsKKyAgdmlydHVhbCB+RmllbGRPcHRpb25zKCk7CisKKyAgRmllbGRPcHRpb25zKGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIEZpZWxkT3B0aW9ucyYgb3BlcmF0b3I9KGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWVsZE9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRmllbGRPcHRpb25zKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRmllbGRPcHRpb25zKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWVsZE9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBGaWVsZE9wdGlvbnMmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBGaWVsZE9wdGlvbnMmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWVsZE9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICB0eXBlZGVmIEZpZWxkT3B0aW9uc19DVHlwZSBDVHlwZTsKKyAgc3RhdGljIGNvbnN0IENUeXBlIFNUUklORyA9IEZpZWxkT3B0aW9uc19DVHlwZV9TVFJJTkc7CisgIHN0YXRpYyBjb25zdCBDVHlwZSBDT1JEID0gRmllbGRPcHRpb25zX0NUeXBlX0NPUkQ7CisgIHN0YXRpYyBjb25zdCBDVHlwZSBTVFJJTkdfUElFQ0UgPSBGaWVsZE9wdGlvbnNfQ1R5cGVfU1RSSU5HX1BJRUNFOworICBzdGF0aWMgaW5saW5lIGJvb2wgQ1R5cGVfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gRmllbGRPcHRpb25zX0NUeXBlX0lzVmFsaWQodmFsdWUpOworICB9CisgIHN0YXRpYyBjb25zdCBDVHlwZSBDVHlwZV9NSU4gPQorICAgIEZpZWxkT3B0aW9uc19DVHlwZV9DVHlwZV9NSU47CisgIHN0YXRpYyBjb25zdCBDVHlwZSBDVHlwZV9NQVggPQorICAgIEZpZWxkT3B0aW9uc19DVHlwZV9DVHlwZV9NQVg7CisgIHN0YXRpYyBjb25zdCBpbnQgQ1R5cGVfQVJSQVlTSVpFID0KKyAgICBGaWVsZE9wdGlvbnNfQ1R5cGVfQ1R5cGVfQVJSQVlTSVpFOworICBzdGF0aWMgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqCisgIENUeXBlX2Rlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIEZpZWxkT3B0aW9uc19DVHlwZV9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDVHlwZV9OYW1lKENUeXBlIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkT3B0aW9uc19DVHlwZV9OYW1lKHZhbHVlKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGJvb2wgQ1R5cGVfUGFyc2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwKKyAgICAgIENUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZE9wdGlvbnNfQ1R5cGVfUGFyc2UobmFtZSwgdmFsdWUpOworICB9CisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZSBjdHlwZSA9IDEgW2RlZmF1bHQgPSBTVFJJTkddOworICBib29sIGhhc19jdHlwZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2N0eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0N0eXBlRmllbGROdW1iZXIgPSAxOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSBjdHlwZSgpIGNvbnN0OworICB2b2lkIHNldF9jdHlwZSg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSAyOworICBib29sIGhhc19wYWNrZWQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9wYWNrZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUGFja2VkRmllbGROdW1iZXIgPSAyOworICBib29sIHBhY2tlZCgpIGNvbnN0OworICB2b2lkIHNldF9wYWNrZWQoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfbGF6eSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2xhenkoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTGF6eUZpZWxkTnVtYmVyID0gNTsKKyAgYm9vbCBsYXp5KCkgY29uc3Q7CisgIHZvaWQgc2V0X2xhenkoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcHJlY2F0ZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwcmVjYXRlZEZpZWxkTnVtYmVyID0gMzsKKyAgYm9vbCBkZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgc2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCB3ZWFrID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX3dlYWsoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl93ZWFrKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1dlYWtGaWVsZE51bWJlciA9IDEwOworICBib29sIHdlYWsoKSBjb25zdDsKKyAgdm9pZCBzZXRfd2Vhayhib29sIHZhbHVlKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGludCB1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyID0gOTk5OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIGFkZF91bmludGVycHJldGVkX29wdGlvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKKyAgICAgIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKworICBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhGaWVsZE9wdGlvbnMpCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfY3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2N0eXBlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfcGFja2VkKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19wYWNrZWQoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19sYXp5KCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19sYXp5KCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3dlYWsoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3dlYWsoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQgX2V4dGVuc2lvbnNfOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgaW50IGN0eXBlXzsKKyAgYm9vbCBwYWNrZWRfOworICBib29sIGxhenlfOworICBib29sIGRlcHJlY2F0ZWRfOworICBib29sIHdlYWtfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgRmllbGRPcHRpb25zKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBFbnVtT3B0aW9ucyA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRW51bU9wdGlvbnMoKTsKKyAgdmlydHVhbCB+RW51bU9wdGlvbnMoKTsKKworICBFbnVtT3B0aW9ucyhjb25zdCBFbnVtT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIEVudW1PcHRpb25zJiBvcGVyYXRvcj0oY29uc3QgRW51bU9wdGlvbnMmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRW51bU9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRW51bU9wdGlvbnMqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBFbnVtT3B0aW9ucyogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRW51bU9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBFbnVtT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEVudW1PcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRW51bU9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworICBib29sIGhhc19hbGxvd19hbGlhcygpIGNvbnN0OworICB2b2lkIGNsZWFyX2FsbG93X2FsaWFzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0FsbG93QWxpYXNGaWVsZE51bWJlciA9IDI7CisgIGJvb2wgYWxsb3dfYWxpYXMoKSBjb25zdDsKKyAgdm9pZCBzZXRfYWxsb3dfYWxpYXMoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcHJlY2F0ZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwcmVjYXRlZEZpZWxkTnVtYmVyID0gMzsKKyAgYm9vbCBkZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgc2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBpbnQgdW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlciA9IDk5OTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiB1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKKyAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCisgICAgICBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisKKyAgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9BQ0NFU1NPUlMoRW51bU9wdGlvbnMpCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19hbGxvd19hbGlhcygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfYWxsb3dfYWxpYXMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0IF9leHRlbnNpb25zXzsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworICBib29sIGFsbG93X2FsaWFzXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgRW51bU9wdGlvbnMqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1WYWx1ZU9wdGlvbnMgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEVudW1WYWx1ZU9wdGlvbnMoKTsKKyAgdmlydHVhbCB+RW51bVZhbHVlT3B0aW9ucygpOworCisgIEVudW1WYWx1ZU9wdGlvbnMoY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIEVudW1WYWx1ZU9wdGlvbnMmIG9wZXJhdG9yPShjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEVudW1WYWx1ZU9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRW51bVZhbHVlT3B0aW9ucyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEVudW1WYWx1ZU9wdGlvbnMqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEVudW1WYWx1ZU9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEVudW1WYWx1ZU9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2RlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9kZXByZWNhdGVkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlcHJlY2F0ZWRGaWVsZE51bWJlciA9IDE7CisgIGJvb2wgZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIHNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgaW50IHVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXIgPSA5OTk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogYWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCisgICAgICB1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorICAgICAgbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpOworCisgIEdPT0dMRV9QUk9UT0JVRl9FWFRFTlNJT05fQUNDRVNTT1JTKEVudW1WYWx1ZU9wdGlvbnMpCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQgX2V4dGVuc2lvbnNfOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiB1bmludGVycHJldGVkX29wdGlvbl87CisgIGJvb2wgZGVwcmVjYXRlZF87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEVudW1WYWx1ZU9wdGlvbnMqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFNlcnZpY2VPcHRpb25zIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBTZXJ2aWNlT3B0aW9ucygpOworICB2aXJ0dWFsIH5TZXJ2aWNlT3B0aW9ucygpOworCisgIFNlcnZpY2VPcHRpb25zKGNvbnN0IFNlcnZpY2VPcHRpb25zJiBmcm9tKTsKKworICBpbmxpbmUgU2VydmljZU9wdGlvbnMmIG9wZXJhdG9yPShjb25zdCBTZXJ2aWNlT3B0aW9ucyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBTZXJ2aWNlT3B0aW9ucyYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChTZXJ2aWNlT3B0aW9ucyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFNlcnZpY2VPcHRpb25zKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBTZXJ2aWNlT3B0aW9ucyogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFNlcnZpY2VPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgU2VydmljZU9wdGlvbnMmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChTZXJ2aWNlT3B0aW9ucyogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2RlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9kZXByZWNhdGVkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlcHJlY2F0ZWRGaWVsZE51bWJlciA9IDMzOworICBib29sIGRlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGludCB1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyID0gOTk5OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIGFkZF91bmludGVycHJldGVkX29wdGlvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKKyAgICAgIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKworICBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhTZXJ2aWNlT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQgX2V4dGVuc2lvbnNfOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiB1bmludGVycHJldGVkX29wdGlvbl87CisgIGJvb2wgZGVwcmVjYXRlZF87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIFNlcnZpY2VPcHRpb25zKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXRob2RPcHRpb25zIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBNZXRob2RPcHRpb25zKCk7CisgIHZpcnR1YWwgfk1ldGhvZE9wdGlvbnMoKTsKKworICBNZXRob2RPcHRpb25zKGNvbnN0IE1ldGhvZE9wdGlvbnMmIGZyb20pOworCisgIGlubGluZSBNZXRob2RPcHRpb25zJiBvcGVyYXRvcj0oY29uc3QgTWV0aG9kT3B0aW9ucyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBNZXRob2RPcHRpb25zJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKE1ldGhvZE9wdGlvbnMqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBNZXRob2RPcHRpb25zKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBNZXRob2RPcHRpb25zKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgTWV0aG9kT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1ldGhvZE9wdGlvbnMmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChNZXRob2RPcHRpb25zKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcHJlY2F0ZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwcmVjYXRlZEZpZWxkTnVtYmVyID0gMzM7CisgIGJvb2wgZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIHNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgaW50IHVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXIgPSA5OTk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogYWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCisgICAgICB1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorICAgICAgbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpOworCisgIEdPT0dMRV9QUk9UT0JVRl9FWFRFTlNJT05fQUNDRVNTT1JTKE1ldGhvZE9wdGlvbnMpCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQgX2V4dGVuc2lvbnNfOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiB1bmludGVycHJldGVkX29wdGlvbl87CisgIGJvb2wgZGVwcmVjYXRlZF87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIE1ldGhvZE9wdGlvbnMqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoKTsKKyAgdmlydHVhbCB+VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCgpOworCisgIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgZnJvbSk7CisKKyAgaW5saW5lIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIG9wZXJhdG9yPShjb25zdCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0JiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0JiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcXVpcmVkIHN0cmluZyBuYW1lX3BhcnQgPSAxOworICBib29sIGhhc19uYW1lX3BhcnQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lX3BhcnQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZVBhcnRGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWVfcGFydCgpIGNvbnN0OworICB2b2lkIHNldF9uYW1lX3BhcnQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lX3BhcnQoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lX3BhcnQoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9uYW1lX3BhcnQoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lX3BhcnQoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWVfcGFydCg6OnN0ZDo6c3RyaW5nKiBuYW1lX3BhcnQpOworCisgIC8vIHJlcXVpcmVkIGJvb2wgaXNfZXh0ZW5zaW9uID0gMjsKKyAgYm9vbCBoYXNfaXNfZXh0ZW5zaW9uKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfaXNfZXh0ZW5zaW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0lzRXh0ZW5zaW9uRmllbGROdW1iZXIgPSAyOworICBib29sIGlzX2V4dGVuc2lvbigpIGNvbnN0OworICB2b2lkIHNldF9pc19leHRlbnNpb24oYm9vbCB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0KQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZV9wYXJ0KCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19uYW1lX3BhcnQoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19pc19leHRlbnNpb24oKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2lzX2V4dGVuc2lvbigpOworCisgIC8vIGhlbHBlciBmb3IgQnl0ZVNpemUoKQorICBpbnQgUmVxdWlyZWRGaWVsZHNCeXRlU2l6ZUZhbGxiYWNrKCkgY29uc3Q7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lX3BhcnRfOworICBib29sIGlzX2V4dGVuc2lvbl87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVuaW50ZXJwcmV0ZWRPcHRpb24gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFVuaW50ZXJwcmV0ZWRPcHRpb24oKTsKKyAgdmlydHVhbCB+VW5pbnRlcnByZXRlZE9wdGlvbigpOworCisgIFVuaW50ZXJwcmV0ZWRPcHRpb24oY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgZnJvbSk7CisKKyAgaW5saW5lIFVuaW50ZXJwcmV0ZWRPcHRpb24mIG9wZXJhdG9yPShjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbiogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFVuaW50ZXJwcmV0ZWRPcHRpb24qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFVuaW50ZXJwcmV0ZWRPcHRpb24qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFVuaW50ZXJwcmV0ZWRPcHRpb24qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICB0eXBlZGVmIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQgTmFtZVBhcnQ7CisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQgbmFtZSA9IDI7CisgIGludCBuYW1lX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDI7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgbmFtZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIG11dGFibGVfbmFtZShpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIGFkZF9uYW1lKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4mCisgICAgICBuYW1lKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4qCisgICAgICBtdXRhYmxlX25hbWUoKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CisgIGJvb2wgaGFzX2lkZW50aWZpZXJfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9pZGVudGlmaWVyX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0lkZW50aWZpZXJWYWx1ZUZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgaWRlbnRpZmllcl92YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2lkZW50aWZpZXJfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9pZGVudGlmaWVyX3ZhbHVlKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfaWRlbnRpZmllcl92YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfaWRlbnRpZmllcl92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBpZGVudGlmaWVyX3ZhbHVlKTsKKworICAvLyBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKKyAgYm9vbCBoYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfcG9zaXRpdmVfaW50X3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Bvc2l0aXZlSW50VmFsdWVGaWVsZE51bWJlciA9IDQ7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9wb3NpdGl2ZV9pbnRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgIGJvb2wgaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX25lZ2F0aXZlX2ludF92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOZWdhdGl2ZUludFZhbHVlRmllbGROdW1iZXIgPSA1OworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9uZWdhdGl2ZV9pbnRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDY7CisgIGJvb2wgaGFzX2RvdWJsZV92YWx1ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RvdWJsZV92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtEb3VibGVWYWx1ZUZpZWxkTnVtYmVyID0gNjsKKyAgZG91YmxlIGRvdWJsZV92YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9kb3VibGVfdmFsdWUoZG91YmxlIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBieXRlcyBzdHJpbmdfdmFsdWUgPSA3OworICBib29sIGhhc19zdHJpbmdfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zdHJpbmdfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU3RyaW5nVmFsdWVGaWVsZE51bWJlciA9IDc7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHN0cmluZ192YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9zdHJpbmdfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9zdHJpbmdfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9zdHJpbmdfdmFsdWUoY29uc3Qgdm9pZCogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9zdHJpbmdfdmFsdWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9zdHJpbmdfdmFsdWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX3N0cmluZ192YWx1ZSg6OnN0ZDo6c3RyaW5nKiBzdHJpbmdfdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBhZ2dyZWdhdGVfdmFsdWUgPSA4OworICBib29sIGhhc19hZ2dyZWdhdGVfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQWdncmVnYXRlVmFsdWVGaWVsZE51bWJlciA9IDg7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGFnZ3JlZ2F0ZV92YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2FnZ3JlZ2F0ZV92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBhZ2dyZWdhdGVfdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZG91YmxlX3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19kb3VibGVfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3N0cmluZ192YWx1ZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCA+IG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBpZGVudGlmaWVyX3ZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCBuZWdhdGl2ZV9pbnRfdmFsdWVfOworICBkb3VibGUgZG91YmxlX3ZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgc3RyaW5nX3ZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgYWdncmVnYXRlX3ZhbHVlXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgVW5pbnRlcnByZXRlZE9wdGlvbiogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU291cmNlQ29kZUluZm9fTG9jYXRpb24gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKCk7CisgIHZpcnR1YWwgflNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKCk7CisKKyAgU291cmNlQ29kZUluZm9fTG9jYXRpb24oY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIGZyb20pOworCisgIGlubGluZSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgb3BlcmF0b3I9KGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIGludCBwYXRoX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9wYXRoKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1BhdGhGaWVsZE51bWJlciA9IDE7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgcGF0aChpbnQgaW5kZXgpIGNvbnN0OworICB2b2lkIHNldF9wYXRoKGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisgIHZvaWQgYWRkX3BhdGgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorICAgICAgcGF0aCgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKKyAgICAgIG11dGFibGVfcGF0aCgpOworCisgIC8vIHJlcGVhdGVkIGludDMyIHNwYW4gPSAyIFtwYWNrZWQgPSB0cnVlXTsKKyAgaW50IHNwYW5fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3NwYW4oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU3BhbkZpZWxkTnVtYmVyID0gMjsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBzcGFuKGludCBpbmRleCkgY29uc3Q7CisgIHZvaWQgc2V0X3NwYW4oaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgdm9pZCBhZGRfc3Bhbig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCisgICAgICBzcGFuKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorICAgICAgbXV0YWJsZV9zcGFuKCk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGxlYWRpbmdfY29tbWVudHMgPSAzOworICBib29sIGhhc19sZWFkaW5nX2NvbW1lbnRzKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbGVhZGluZ19jb21tZW50cygpOworICBzdGF0aWMgY29uc3QgaW50IGtMZWFkaW5nQ29tbWVudHNGaWVsZE51bWJlciA9IDM7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGxlYWRpbmdfY29tbWVudHMoKSBjb25zdDsKKyAgdm9pZCBzZXRfbGVhZGluZ19jb21tZW50cyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9sZWFkaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbGVhZGluZ19jb21tZW50cygpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2xlYWRpbmdfY29tbWVudHMoOjpzdGQ6OnN0cmluZyogbGVhZGluZ19jb21tZW50cyk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKKyAgYm9vbCBoYXNfdHJhaWxpbmdfY29tbWVudHMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl90cmFpbGluZ19jb21tZW50cygpOworICBzdGF0aWMgY29uc3QgaW50IGtUcmFpbGluZ0NvbW1lbnRzRmllbGROdW1iZXIgPSA0OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB0cmFpbGluZ19jb21tZW50cygpIGNvbnN0OworICB2b2lkIHNldF90cmFpbGluZ19jb21tZW50cyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHJhaWxpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV90cmFpbGluZ19jb21tZW50cygpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF90cmFpbGluZ19jb21tZW50cyg6OnN0ZDo6c3RyaW5nKiB0cmFpbGluZ19jb21tZW50cyk7CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgPSA2OworICBpbnQgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c19zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cygpOworICBzdGF0aWMgY29uc3QgaW50IGtMZWFkaW5nRGV0YWNoZWRDb21tZW50c0ZpZWxkTnVtYmVyID0gNjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgpIGNvbnN0OworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4KTsKKyAgdm9pZCBzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIGFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCk7CisgIHZvaWQgYWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIGFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBhZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qIG11dGFibGVfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cygpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24pCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiBwYXRoXzsKKyAgbXV0YWJsZSBpbnQgX3BhdGhfY2FjaGVkX2J5dGVfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+IHNwYW5fOworICBtdXRhYmxlIGludCBfc3Bhbl9jYWNoZWRfYnl0ZV9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbGVhZGluZ19jb21tZW50c187CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHRyYWlsaW5nX2NvbW1lbnRzXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFNvdXJjZUNvZGVJbmZvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBTb3VyY2VDb2RlSW5mbygpOworICB2aXJ0dWFsIH5Tb3VyY2VDb2RlSW5mbygpOworCisgIFNvdXJjZUNvZGVJbmZvKGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBmcm9tKTsKKworICBpbmxpbmUgU291cmNlQ29kZUluZm8mIG9wZXJhdG9yPShjb25zdCBTb3VyY2VDb2RlSW5mbyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBTb3VyY2VDb2RlSW5mbyYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChTb3VyY2VDb2RlSW5mbyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFNvdXJjZUNvZGVJbmZvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBTb3VyY2VDb2RlSW5mbyogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgU291cmNlQ29kZUluZm8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChTb3VyY2VDb2RlSW5mbyogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgU291cmNlQ29kZUluZm9fTG9jYXRpb24gTG9jYXRpb247CisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIGxvY2F0aW9uID0gMTsKKyAgaW50IGxvY2F0aW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9sb2NhdGlvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtMb2NhdGlvbkZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgbG9jYXRpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogbXV0YWJsZV9sb2NhdGlvbihpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBhZGRfbG9jYXRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uID4mCisgICAgICBsb2NhdGlvbigpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24gPioKKyAgICAgIG11dGFibGVfbG9jYXRpb24oKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24gPiBsb2NhdGlvbl87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIFNvdXJjZUNvZGVJbmZvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRmlsZURlc2NyaXB0b3JTZXQKKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworaW5saW5lIGludCBGaWxlRGVzY3JpcHRvclNldDo6ZmlsZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZmlsZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OmNsZWFyX2ZpbGUoKSB7CisgIGZpbGVfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclNldDo6ZmlsZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuIGZpbGVfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclNldDo6bXV0YWJsZV9maWxlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuIGZpbGVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JTZXQ6OmFkZF9maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV8uQWRkKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiYKK0ZpbGVEZXNjcmlwdG9yU2V0OjpmaWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuIGZpbGVfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclNldDo6bXV0YWJsZV9maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gJmZpbGVfOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEZpbGVEZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHBhY2thZ2UgPSAyOworaW5saW5lIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfcGFja2FnZSgpIHsKKyAgcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfcGFja2FnZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OnBhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKKyAgcmV0dXJuIHBhY2thZ2VfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2FnZSgpOworICBwYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19wYWNrYWdlKCk7CisgIHBhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9wYWNrYWdlKCkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKKyAgcmV0dXJuIHBhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9wYWNrYWdlKCkgeworICBjbGVhcl9oYXNfcGFja2FnZSgpOworICByZXR1cm4gcGFja2FnZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBwYWNrYWdlKSB7CisgIGlmIChwYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfcGFja2FnZSgpOworICB9CisgIHBhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBwYWNrYWdlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKK30KKworLy8gcmVwZWF0ZWQgc3RyaW5nIGRlcGVuZGVuY3kgPSAzOworaW5saW5lIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXBlbmRlbmN5X3NpemUoKSBjb25zdCB7CisgIHJldHVybiBkZXBlbmRlbmN5Xy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9kZXBlbmRlbmN5KCkgeworICBkZXBlbmRlbmN5Xy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuIGRlcGVuZGVuY3lfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9kZXBlbmRlbmN5KGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorICByZXR1cm4gZGVwZW5kZW5jeV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgZGVwZW5kZW5jeV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGRlcGVuZGVuY3lfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9kZXBlbmRlbmN5KGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGRlcGVuZGVuY3lfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2RlcGVuZGVuY3koKSB7CisgIHJldHVybiBkZXBlbmRlbmN5Xy5BZGQoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9kZXBlbmRlbmN5KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIGRlcGVuZGVuY3lfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZGVwZW5kZW5jeShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBkZXBlbmRlbmN5Xy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZGVwZW5kZW5jeShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgZGVwZW5kZW5jeV8uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVwZW5kZW5jeSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuIGRlcGVuZGVuY3lfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2RlcGVuZGVuY3koKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuICZkZXBlbmRlbmN5XzsKK30KKworLy8gcmVwZWF0ZWQgaW50MzIgcHVibGljX2RlcGVuZGVuY3kgPSAxMDsKK2lubGluZSBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6cHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5Xy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9wdWJsaWNfZGVwZW5kZW5jeSgpIHsKKyAgcHVibGljX2RlcGVuZGVuY3lfLkNsZWFyKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWxlRGVzY3JpcHRvclByb3RvOjpwdWJsaWNfZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5Xy5HZXQoaW5kZXgpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3B1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwdWJsaWNfZGVwZW5kZW5jeV8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucHVibGljX2RlcGVuZGVuY3kpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfcHVibGljX2RlcGVuZGVuY3koOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwdWJsaWNfZGVwZW5kZW5jeV8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86OnB1YmxpY19kZXBlbmRlbmN5KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5XzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfcHVibGljX2RlcGVuZGVuY3koKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucHVibGljX2RlcGVuZGVuY3kpCisgIHJldHVybiAmcHVibGljX2RlcGVuZGVuY3lfOworfQorCisvLyByZXBlYXRlZCBpbnQzMiB3ZWFrX2RlcGVuZGVuY3kgPSAxMTsKK2lubGluZSBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6d2Vha19kZXBlbmRlbmN5X3NpemUoKSBjb25zdCB7CisgIHJldHVybiB3ZWFrX2RlcGVuZGVuY3lfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3dlYWtfZGVwZW5kZW5jeSgpIHsKKyAgd2Vha19kZXBlbmRlbmN5Xy5DbGVhcigpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRmlsZURlc2NyaXB0b3JQcm90bzo6d2Vha19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV8uR2V0KGluZGV4KTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF93ZWFrX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHdlYWtfZGVwZW5kZW5jeV8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ud2Vha19kZXBlbmRlbmN5KQorfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX3dlYWtfZGVwZW5kZW5jeSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHdlYWtfZGVwZW5kZW5jeV8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjp3ZWFrX2RlcGVuZGVuY3koKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3dlYWtfZGVwZW5kZW5jeSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCisgIHJldHVybiAmd2Vha19kZXBlbmRlbmN5XzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKK2lubGluZSBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6bWVzc2FnZV90eXBlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBtZXNzYWdlX3R5cGVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX21lc3NhZ2VfdHlwZSgpIHsKKyAgbWVzc2FnZV90eXBlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjptZXNzYWdlX3R5cGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX21lc3NhZ2VfdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX21lc3NhZ2VfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om1lc3NhZ2VfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX21lc3NhZ2VfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiAmbWVzc2FnZV90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDU7CitpbmxpbmUgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZW51bV90eXBlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9lbnVtX3R5cGUoKSB7CisgIGVudW1fdHlwZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiAmZW51bV90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworaW5saW5lIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBzZXJ2aWNlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9zZXJ2aWNlKCkgeworICBzZXJ2aWNlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byYgRmlsZURlc2NyaXB0b3JQcm90bzo6c2VydmljZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfc2VydmljZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX3NlcnZpY2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfc2VydmljZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gJnNlcnZpY2VfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDc7CitpbmxpbmUgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gZXh0ZW5zaW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbnNpb24oKSB7CisgIGV4dGVuc2lvbl8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9leHRlbnNpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuICZleHRlbnNpb25fOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIG9wdGlvbnMgPSA4OworaW5saW5lIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAyMDB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAyMDB1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAyMDB1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMmIEZpbGVEZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8gc291cmNlX2NvZGVfaW5mbyA9IDk7CitpbmxpbmUgYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpoYXNfc291cmNlX2NvZGVfaW5mbygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDQwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDQwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfc291cmNlX2NvZGVfaW5mbygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDQwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9zb3VyY2VfY29kZV9pbmZvKCkgeworICBpZiAoc291cmNlX2NvZGVfaW5mb18gIT0gTlVMTCkgc291cmNlX2NvZGVfaW5mb18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm86OkNsZWFyKCk7CisgIGNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyYgRmlsZURlc2NyaXB0b3JQcm90bzo6c291cmNlX2NvZGVfaW5mbygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zb3VyY2VfY29kZV9pbmZvKQorICByZXR1cm4gc291cmNlX2NvZGVfaW5mb18gIT0gTlVMTCA/ICpzb3VyY2VfY29kZV9pbmZvXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+c291cmNlX2NvZGVfaW5mb187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zb3VyY2VfY29kZV9pbmZvKCkgeworICBzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgaWYgKHNvdXJjZV9jb2RlX2luZm9fID09IE5VTEwpIHsKKyAgICBzb3VyY2VfY29kZV9pbmZvXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNvdXJjZV9jb2RlX2luZm8pCisgIHJldHVybiBzb3VyY2VfY29kZV9pbmZvXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIGNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIHRlbXAgPSBzb3VyY2VfY29kZV9pbmZvXzsKKyAgc291cmNlX2NvZGVfaW5mb18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfc291cmNlX2NvZGVfaW5mbyg6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBzb3VyY2VfY29kZV9pbmZvKSB7CisgIGRlbGV0ZSBzb3VyY2VfY29kZV9pbmZvXzsKKyAgc291cmNlX2NvZGVfaW5mb18gPSBzb3VyY2VfY29kZV9pbmZvOworICBpZiAoc291cmNlX2NvZGVfaW5mbykgeworICAgIHNldF9oYXNfc291cmNlX2NvZGVfaW5mbygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc291cmNlX2NvZGVfaW5mbykKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworaW5saW5lIGJvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX3N5bnRheCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDgwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3N5bnRheCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwODAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19zeW50YXgoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDA4MDB1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfc3ludGF4KCkgeworICBzeW50YXhfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3N5bnRheCgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCisgIHJldHVybiBzeW50YXhfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9zeW50YXgoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9zeW50YXgoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4KQorfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3N5bnRheChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zeW50YXgoKSB7CisgIHNldF9oYXNfc3ludGF4KCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKKyAgcmV0dXJuIHN5bnRheF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3N5bnRheCgpIHsKKyAgY2xlYXJfaGFzX3N5bnRheCgpOworICByZXR1cm4gc3ludGF4Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9zeW50YXgoOjpzdGQ6OnN0cmluZyogc3ludGF4KSB7CisgIGlmIChzeW50YXggIT0gTlVMTCkgeworICAgIHNldF9oYXNfc3ludGF4KCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3N5bnRheCgpOworICB9CisgIHN5bnRheF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHN5bnRheCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UKKworLy8gb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworaW5saW5lIGJvb2wgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpoYXNfc3RhcnQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpzZXRfaGFzX3N0YXJ0KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpjbGVhcl9oYXNfc3RhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpjbGVhcl9zdGFydCgpIHsKKyAgc3RhcnRfID0gMDsKKyAgY2xlYXJfaGFzX3N0YXJ0KCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OnN0YXJ0KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2Uuc3RhcnQpCisgIHJldHVybiBzdGFydF87Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OnNldF9zdGFydCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfc3RhcnQoKTsKKyAgc3RhcnRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZS5zdGFydCkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gMjsKK2lubGluZSBib29sIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6aGFzX2VuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OnNldF9oYXNfZW5kKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpjbGVhcl9oYXNfZW5kKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Y2xlYXJfZW5kKCkgeworICBlbmRfID0gMDsKKyAgY2xlYXJfaGFzX2VuZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjplbmQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZS5lbmQpCisgIHJldHVybiBlbmRfOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpzZXRfZW5kKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19lbmQoKTsKKyAgZW5kXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UuZW5kKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIERlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CitpbmxpbmUgaW50IERlc2NyaXB0b3JQcm90bzo6ZmllbGRfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpZWxkXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2ZpZWxkKCkgeworICBmaWVsZF8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86OmZpZWxkKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiBmaWVsZF8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZmllbGQoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiBmaWVsZF8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjphZGRfZmllbGQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5maWVsZCkKKyAgcmV0dXJuIGZpZWxkXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZmllbGQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiBmaWVsZF87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4qCitEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZmllbGQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5maWVsZCkKKyAgcmV0dXJuICZmaWVsZF87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKK2lubGluZSBpbnQgRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGV4dGVuc2lvbl8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbnNpb24oKSB7CisgIGV4dGVuc2lvbl8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjphZGRfZXh0ZW5zaW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4qCitEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gJmV4dGVuc2lvbl87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG5lc3RlZF90eXBlID0gMzsKK2lubGluZSBpbnQgRGVzY3JpcHRvclByb3RvOjpuZXN0ZWRfdHlwZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gbmVzdGVkX3R5cGVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmVzdGVkX3R5cGUoKSB7CisgIG5lc3RlZF90eXBlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86Om5lc3RlZF90eXBlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiBuZXN0ZWRfdHlwZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25lc3RlZF90eXBlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5lc3RlZF90eXBlKQorICByZXR1cm4gbmVzdGVkX3R5cGVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9uZXN0ZWRfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5lc3RlZF90eXBlKQorICByZXR1cm4gbmVzdGVkX3R5cGVfLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6bmVzdGVkX3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiBuZXN0ZWRfdHlwZV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25lc3RlZF90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiAmbmVzdGVkX3R5cGVfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNDsKK2lubGluZSBpbnQgRGVzY3JpcHRvclByb3RvOjplbnVtX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGVudW1fdHlwZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9lbnVtX3R5cGUoKSB7CisgIGVudW1fdHlwZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjphZGRfZW51bV90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+JgorRGVzY3JpcHRvclByb3RvOjplbnVtX3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuICZlbnVtX3R5cGVfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSBleHRlbnNpb25fcmFuZ2UgPSA1OworaW5saW5lIGludCBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9yYW5nZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2V4dGVuc2lvbl9yYW5nZSgpIHsKKyAgZXh0ZW5zaW9uX3JhbmdlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9yYW5nZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuc2lvbl9yYW5nZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb25fcmFuZ2UpCisgIHJldHVybiBleHRlbnNpb25fcmFuZ2VfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9leHRlbnNpb25fcmFuZ2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb25fcmFuZ2UpCisgIHJldHVybiBleHRlbnNpb25fcmFuZ2VfLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3JhbmdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuc2lvbl9yYW5nZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuICZleHRlbnNpb25fcmFuZ2VfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvIG9uZW9mX2RlY2wgPSA4OworaW5saW5lIGludCBEZXNjcmlwdG9yUHJvdG86Om9uZW9mX2RlY2xfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9uZW9mX2RlY2xfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb25lb2ZfZGVjbCgpIHsKKyAgb25lb2ZfZGVjbF8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86Om9uZW9mX2RlY2woaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gb25lb2ZfZGVjbF8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb25lb2ZfZGVjbChpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gb25lb2ZfZGVjbF8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjphZGRfb25lb2ZfZGVjbCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiBvbmVvZl9kZWNsXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6b25lb2ZfZGVjbCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gb25lb2ZfZGVjbF87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4qCitEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb25lb2ZfZGVjbCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiAmb25lb2ZfZGVjbF87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgb3B0aW9ucyA9IDc7CitpbmxpbmUgYm9vbCBEZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDgwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwODB1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA4MHU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zJiBEZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnM7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIG9wdGlvbnMpIHsKKyAgZGVsZXRlIG9wdGlvbnNfOworICBvcHRpb25zXyA9IG9wdGlvbnM7CisgIGlmIChvcHRpb25zKSB7CisgICAgc2V0X2hhc19vcHRpb25zKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRmllbGREZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19udW1iZXIoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19udW1iZXIoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX251bWJlcigpIHsKKyAgbnVtYmVyXyA9IDA7CisgIGNsZWFyX2hhc19udW1iZXIoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEZpZWxkRGVzY3JpcHRvclByb3RvOjpudW1iZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm51bWJlcikKKyAgcmV0dXJuIG51bWJlcl87Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X251bWJlcig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfbnVtYmVyKCk7CisgIG51bWJlcl8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubnVtYmVyKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsIGxhYmVsID0gNDsKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfbGFiZWwoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbGFiZWwoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2xhYmVsKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9sYWJlbCgpIHsKKyAgbGFiZWxfID0gMTsKKyAgY2xlYXJfaGFzX2xhYmVsKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6bGFiZWwoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmxhYmVsKQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgPihsYWJlbF8pOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9sYWJlbCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIHZhbHVlKSB7CisgIGFzc2VydCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19sYWJlbCgpOworICBsYWJlbF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubGFiZWwpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSB0eXBlID0gNTsKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfdHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc190eXBlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc190eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl90eXBlKCkgeworICB0eXBlXyA9IDE7CisgIGNsZWFyX2hhc190eXBlKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjp0eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlKQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSA+KHR5cGVfKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfdHlwZSg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9Jc1ZhbGlkKHZhbHVlKSk7CisgIHNldF9oYXNfdHlwZSgpOworICB0eXBlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfdHlwZV9uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDEwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3R5cGVfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfdHlwZV9uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl90eXBlX25hbWUoKSB7CisgIHR5cGVfbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfdHlwZV9uYW1lKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmllbGREZXNjcmlwdG9yUHJvdG86OnR5cGVfbmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorICByZXR1cm4gdHlwZV9uYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X3R5cGVfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICB0eXBlX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfdHlwZV9uYW1lKCk7CisgIHR5cGVfbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X3R5cGVfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgdHlwZV9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3R5cGVfbmFtZSgpIHsKKyAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKKyAgcmV0dXJuIHR5cGVfbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV90eXBlX25hbWUoKSB7CisgIGNsZWFyX2hhc190eXBlX25hbWUoKTsKKyAgcmV0dXJuIHR5cGVfbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX3R5cGVfbmFtZSg6OnN0ZDo6c3RyaW5nKiB0eXBlX25hbWUpIHsKKyAgaWYgKHR5cGVfbmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfdHlwZV9uYW1lKCk7CisgIH0KKyAgdHlwZV9uYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdHlwZV9uYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGV4dGVuZGVlID0gMjsKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfZXh0ZW5kZWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMjB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfZXh0ZW5kZWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2V4dGVuZGVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbmRlZSgpIHsKKyAgZXh0ZW5kZWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2V4dGVuZGVlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmllbGREZXNjcmlwdG9yUHJvdG86OmV4dGVuZGVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSkKKyAgcmV0dXJuIGV4dGVuZGVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2V4dGVuZGVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgZXh0ZW5kZWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9leHRlbmRlZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIGV4dGVuZGVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9leHRlbmRlZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19leHRlbmRlZSgpOworICBleHRlbmRlZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuZGVlKCkgeworICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSkKKyAgcmV0dXJuIGV4dGVuZGVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2V4dGVuZGVlKCkgeworICBjbGVhcl9oYXNfZXh0ZW5kZWUoKTsKKyAgcmV0dXJuIGV4dGVuZGVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfZXh0ZW5kZWUoOjpzdGQ6OnN0cmluZyogZXh0ZW5kZWUpIHsKKyAgaWYgKGV4dGVuZGVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2V4dGVuZGVlKCk7CisgIH0KKyAgZXh0ZW5kZWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBleHRlbmRlZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19kZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDQwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA0MHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2RlZmF1bHRfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwNDB1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2RlZmF1bHRfdmFsdWUoKSB7CisgIGRlZmF1bHRfdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2RlZmF1bHRfdmFsdWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZGVmYXVsdF92YWx1ZSkKKyAgcmV0dXJuIGRlZmF1bHRfdmFsdWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfZGVmYXVsdF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgZGVmYXVsdF92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZGVmYXVsdF92YWx1ZSkKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfZGVmYXVsdF92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgZGVmYXVsdF92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgZGVmYXVsdF92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZGVmYXVsdF92YWx1ZSgpIHsKKyAgc2V0X2hhc19kZWZhdWx0X3ZhbHVlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9kZWZhdWx0X3ZhbHVlKCkgeworICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX2RlZmF1bHRfdmFsdWUoOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSkgeworICBpZiAoZGVmYXVsdF92YWx1ZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19kZWZhdWx0X3ZhbHVlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgfQorICBkZWZhdWx0X3ZhbHVlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZGVmYXVsdF92YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBvbmVvZl9pbmRleCA9IDk7CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX29uZW9mX2luZGV4KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDgwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29uZW9mX2luZGV4KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwODB1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vbmVvZl9pbmRleCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA4MHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb25lb2ZfaW5kZXgoKSB7CisgIG9uZW9mX2luZGV4XyA9IDA7CisgIGNsZWFyX2hhc19vbmVvZl9pbmRleCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRmllbGREZXNjcmlwdG9yUHJvdG86Om9uZW9mX2luZGV4KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5vbmVvZl9pbmRleCkKKyAgcmV0dXJuIG9uZW9mX2luZGV4XzsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfb25lb2ZfaW5kZXgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzZXRfaGFzX29uZW9mX2luZGV4KCk7CisgIG9uZW9mX2luZGV4XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5vbmVvZl9pbmRleCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgb3B0aW9ucyA9IDg7CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAxMDB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMTAwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDEwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyYgRmllbGREZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnM7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogRmllbGREZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIG9wdGlvbnMpIHsKKyAgZGVsZXRlIG9wdGlvbnNfOworICBvcHRpb25zXyA9IG9wdGlvbnM7CisgIGlmIChvcHRpb25zKSB7CisgICAgc2V0X2hhc19vcHRpb25zKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBPbmVvZkRlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE9uZW9mRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE9uZW9mRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRW51bURlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBFbnVtRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRW51bURlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBFbnVtRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byB2YWx1ZSA9IDI7CitpbmxpbmUgaW50IEVudW1EZXNjcmlwdG9yUHJvdG86OnZhbHVlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB2YWx1ZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBFbnVtRGVzY3JpcHRvclByb3RvOjp2YWx1ZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3ZhbHVlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogRW51bURlc2NyaXB0b3JQcm90bzo6YWRkX3ZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLnZhbHVlKQorICByZXR1cm4gdmFsdWVfLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gPiYKK0VudW1EZXNjcmlwdG9yUHJvdG86OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4qCitFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3ZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLnZhbHVlKQorICByZXR1cm4gJnZhbHVlXzsKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyBvcHRpb25zID0gMzsKK2lubGluZSBib29sIEVudW1EZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zJiBFbnVtRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnM7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIEVudW1EZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogdGVtcCA9IG9wdGlvbnNfOworICBvcHRpb25zXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIG9wdGlvbnMpIHsKKyAgZGVsZXRlIG9wdGlvbnNfOworICBvcHRpb25zXyA9IG9wdGlvbnM7CisgIGlmIChvcHRpb25zKSB7CisgICAgc2V0X2hhc19vcHRpb25zKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKK2lubGluZSBib29sIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6aGFzX251bWJlcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbnVtYmVyKCkgeworICBudW1iZXJfID0gMDsKKyAgY2xlYXJfaGFzX251bWJlcigpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpudW1iZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5udW1iZXIpCisgIHJldHVybiBudW1iZXJfOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19udW1iZXIoKTsKKyAgbnVtYmVyXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubnVtYmVyKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgb3B0aW9ucyA9IDM7CitpbmxpbmUgYm9vbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyYgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSBib29sIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX25hbWUoKTsKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvIG1ldGhvZCA9IDI7CitpbmxpbmUgaW50IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om1ldGhvZF9zaXplKCkgY29uc3QgeworICByZXR1cm4gbWV0aG9kXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9tZXRob2QoKSB7CisgIG1ldGhvZF8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byYgU2VydmljZURlc2NyaXB0b3JQcm90bzo6bWV0aG9kKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byogU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9tZXRob2QoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8qIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmFkZF9tZXRob2QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gbWV0aG9kXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvID4mCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjptZXRob2QoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+KgorU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9tZXRob2QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gJm1ldGhvZF87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMgb3B0aW9ucyA9IDM7CitpbmxpbmUgYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyYgU2VydmljZURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBNZXRob2REZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBpbnB1dF90eXBlID0gMjsKK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX2lucHV0X3R5cGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX2lucHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19pbnB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaW5wdXRfdHlwZSgpIHsKKyAgaW5wdXRfdHlwZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaW5wdXRfdHlwZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aW5wdXRfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUpCisgIHJldHVybiBpbnB1dF90eXBlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9pbnB1dF90eXBlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaW5wdXRfdHlwZSgpOworICBpbnB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2lucHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIGlucHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUpCit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9pbnB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgaW5wdXRfdHlwZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9pbnB1dF90eXBlKCkgeworICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorICByZXR1cm4gaW5wdXRfdHlwZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfaW5wdXRfdHlwZSgpIHsKKyAgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKKyAgcmV0dXJuIGlucHV0X3R5cGVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfaW5wdXRfdHlwZSg6OnN0ZDo6c3RyaW5nKiBpbnB1dF90eXBlKSB7CisgIGlmIChpbnB1dF90eXBlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaW5wdXRfdHlwZSgpOworICB9CisgIGlucHV0X3R5cGVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpbnB1dF90eXBlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgb3V0cHV0X3R5cGUgPSAzOworaW5saW5lIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfb3V0cHV0X3R5cGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX291dHB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3V0cHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vdXRwdXRfdHlwZSgpIHsKKyAgb3V0cHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX291dHB1dF90eXBlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpvdXRwdXRfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorICByZXR1cm4gb3V0cHV0X3R5cGVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSkKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfb3V0cHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX291dHB1dF90eXBlKCkgeworICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCisgIHJldHVybiBvdXRwdXRfdHlwZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3V0cHV0X3R5cGUoKSB7CisgIGNsZWFyX2hhc19vdXRwdXRfdHlwZSgpOworICByZXR1cm4gb3V0cHV0X3R5cGVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3V0cHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogb3V0cHV0X3R5cGUpIHsKKyAgaWYgKG91dHB1dF90eXBlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX291dHB1dF90eXBlKCk7CisgIH0KKyAgb3V0cHV0X3R5cGVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBvdXRwdXRfdHlwZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zJiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogdGVtcCA9IG9wdGlvbnNfOworICBvcHRpb25zXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorfQorCisvLyBvcHRpb25hbCBib29sIGNsaWVudF9zdHJlYW1pbmcgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfY2xpZW50X3N0cmVhbWluZygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2NsaWVudF9zdHJlYW1pbmcoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9jbGllbnRfc3RyZWFtaW5nKCkgeworICBjbGllbnRfc3RyZWFtaW5nXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2xpZW50X3N0cmVhbWluZygpOworfQoraW5saW5lIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGllbnRfc3RyZWFtaW5nKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uY2xpZW50X3N0cmVhbWluZykKKyAgcmV0dXJuIGNsaWVudF9zdHJlYW1pbmdfOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfY2xpZW50X3N0cmVhbWluZyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpOworICBjbGllbnRfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uY2xpZW50X3N0cmVhbWluZykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX3NlcnZlcl9zdHJlYW1pbmcoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMjB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfc2VydmVyX3N0cmVhbWluZygpIHsKKyAgc2VydmVyX3N0cmVhbWluZ18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKK30KK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2VydmVyX3N0cmVhbWluZygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLnNlcnZlcl9zdHJlYW1pbmcpCisgIHJldHVybiBzZXJ2ZXJfc3RyZWFtaW5nXzsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X3NlcnZlcl9zdHJlYW1pbmcoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKKyAgc2VydmVyX3N0cmVhbWluZ18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLnNlcnZlcl9zdHJlYW1pbmcpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRmlsZU9wdGlvbnMKKworLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfcGFja2FnZSA9IDE7CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9wYWNrYWdlKCkgeworICBqYXZhX3BhY2thZ2VfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2phdmFfcGFja2FnZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zOjpqYXZhX3BhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSkKKyAgcmV0dXJuIGphdmFfcGFja2FnZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3BhY2thZ2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX3BhY2thZ2UoKTsKKyAgamF2YV9wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICBqYXZhX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIGphdmFfcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6bXV0YWJsZV9qYXZhX3BhY2thZ2UoKSB7CisgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCisgIHJldHVybiBqYXZhX3BhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfamF2YV9wYWNrYWdlKCkgeworICBjbGVhcl9oYXNfamF2YV9wYWNrYWdlKCk7CisgIHJldHVybiBqYXZhX3BhY2thZ2VfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9qYXZhX3BhY2thZ2UoOjpzdGQ6OnN0cmluZyogamF2YV9wYWNrYWdlKSB7CisgIGlmIChqYXZhX3BhY2thZ2UgIT0gTlVMTCkgeworICAgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2phdmFfcGFja2FnZSgpOworICB9CisgIGphdmFfcGFja2FnZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGphdmFfcGFja2FnZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX291dGVyX2NsYXNzbmFtZSA9IDg7CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zOjpqYXZhX291dGVyX2NsYXNzbmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCisgIHJldHVybiBqYXZhX291dGVyX2NsYXNzbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSkKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSkKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6bXV0YWJsZV9qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgc2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCisgIHJldHVybiBqYXZhX291dGVyX2NsYXNzbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6cmVsZWFzZV9qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgY2xlYXJfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIHJldHVybiBqYXZhX291dGVyX2NsYXNzbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfYWxsb2NhdGVkX2phdmFfb3V0ZXJfY2xhc3NuYW1lKDo6c3RkOjpzdHJpbmcqIGphdmFfb3V0ZXJfY2xhc3NuYW1lKSB7CisgIGlmIChqYXZhX291dGVyX2NsYXNzbmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICB9CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgamF2YV9vdXRlcl9jbGFzc25hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YV9tdWx0aXBsZV9maWxlcyA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfbXVsdGlwbGVfZmlsZXMoKSB7CisgIGphdmFfbXVsdGlwbGVfZmlsZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX211bHRpcGxlX2ZpbGVzKCk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6amF2YV9tdWx0aXBsZV9maWxlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9tdWx0aXBsZV9maWxlcykKKyAgcmV0dXJuIGphdmFfbXVsdGlwbGVfZmlsZXNfOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX211bHRpcGxlX2ZpbGVzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX211bHRpcGxlX2ZpbGVzKCk7CisgIGphdmFfbXVsdGlwbGVfZmlsZXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfbXVsdGlwbGVfZmlsZXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSAyMCBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIHsKKyAgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2hfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCkKKyAgcmV0dXJuIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCk7CisgIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBqYXZhX3N0cmluZ19jaGVja191dGY4ID0gMjcgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAxMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIHsKKyAgamF2YV9zdHJpbmdfY2hlY2tfdXRmOF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKK30KK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpqYXZhX3N0cmluZ19jaGVja191dGY4KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3N0cmluZ19jaGVja191dGY4KQorICByZXR1cm4gamF2YV9zdHJpbmdfY2hlY2tfdXRmOF87Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKKyAgamF2YV9zdHJpbmdfY2hlY2tfdXRmOF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9zdHJpbmdfY2hlY2tfdXRmOCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5PcHRpbWl6ZU1vZGUgb3B0aW1pemVfZm9yID0gOSBbZGVmYXVsdCA9IFNQRUVEXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfb3B0aW1pemVfZm9yKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDIwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX29wdGltaXplX2ZvcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfb3B0aW1pemVfZm9yKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9vcHRpbWl6ZV9mb3IoKSB7CisgIG9wdGltaXplX2Zvcl8gPSAxOworICBjbGVhcl9oYXNfb3B0aW1pemVfZm9yKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgRmlsZU9wdGlvbnM6Om9wdGltaXplX2ZvcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub3B0aW1pemVfZm9yKQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlID4ob3B0aW1pemVfZm9yXyk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29wdGltaXplX2Zvcig6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zX09wdGltaXplTW9kZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX29wdGltaXplX2ZvcigpOworICBvcHRpbWl6ZV9mb3JfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9wdGltaXplX2ZvcikKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfZ29fcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDA0MHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19nb19wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwNDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19nb19wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDQwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9nb19wYWNrYWdlKCkgeworICBnb19wYWNrYWdlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19nb19wYWNrYWdlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZU9wdGlvbnM6OmdvX3BhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCisgIHJldHVybiBnb19wYWNrYWdlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2dvX3BhY2thZ2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19nb19wYWNrYWdlKCk7CisgIGdvX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2dvX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19nb19wYWNrYWdlKCk7CisgIGdvX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfZ29fcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19nb19wYWNrYWdlKCk7CisgIGdvX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjptdXRhYmxlX2dvX3BhY2thZ2UoKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKKyAgcmV0dXJuIGdvX3BhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfZ29fcGFja2FnZSgpIHsKKyAgY2xlYXJfaGFzX2dvX3BhY2thZ2UoKTsKKyAgcmV0dXJuIGdvX3BhY2thZ2VfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9nb19wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIGdvX3BhY2thZ2UpIHsKKyAgaWYgKGdvX3BhY2thZ2UgIT0gTlVMTCkgeworICAgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19nb19wYWNrYWdlKCk7CisgIH0KKyAgZ29fcGFja2FnZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGdvX3BhY2thZ2UpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzID0gMTYgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwODB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDgwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA4MHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfY2NfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgY2NfZ2VuZXJpY19zZXJ2aWNlc18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKTsKK30KK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpjY19nZW5lcmljX3NlcnZpY2VzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jY19nZW5lcmljX3NlcnZpY2VzKQorICByZXR1cm4gY2NfZ2VuZXJpY19zZXJ2aWNlc187Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2NjX2dlbmVyaWNfc2VydmljZXMoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgY2NfZ2VuZXJpY19zZXJ2aWNlc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY2NfZ2VuZXJpY19zZXJ2aWNlcykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSAxNyBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMTAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMTAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMTAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIGphdmFfZ2VuZXJpY19zZXJ2aWNlc18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmljX3NlcnZpY2VzKQorICByZXR1cm4gamF2YV9nZW5lcmljX3NlcnZpY2VzXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9nZW5lcmljX3NlcnZpY2VzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgamF2YV9nZW5lcmljX3NlcnZpY2VzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX2dlbmVyaWNfc2VydmljZXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IDE4IFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMjAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDIwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAyMDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX3B5X2dlbmVyaWNfc2VydmljZXMoKSB7CisgIHB5X2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6cHlfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMucHlfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIHB5X2dlbmVyaWNfc2VydmljZXNfOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9weV9nZW5lcmljX3NlcnZpY2VzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIHB5X2dlbmVyaWNfc2VydmljZXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnB5X2dlbmVyaWNfc2VydmljZXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDIzIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwNDAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDQwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDA0MDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgY2NfZW5hYmxlX2FyZW5hcyA9IDMxIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19jY19lbmFibGVfYXJlbmFzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwODAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDgwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDA4MDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2NjX2VuYWJsZV9hcmVuYXMoKSB7CisgIGNjX2VuYWJsZV9hcmVuYXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19jY19lbmFibGVfYXJlbmFzKCk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6Y2NfZW5hYmxlX2FyZW5hcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY2NfZW5hYmxlX2FyZW5hcykKKyAgcmV0dXJuIGNjX2VuYWJsZV9hcmVuYXNfOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9jY19lbmFibGVfYXJlbmFzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19jY19lbmFibGVfYXJlbmFzKCk7CisgIGNjX2VuYWJsZV9hcmVuYXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2VuYWJsZV9hcmVuYXMpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBvYmpjX2NsYXNzX3ByZWZpeCA9IDM2OworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19vYmpjX2NsYXNzX3ByZWZpeCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMTAwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAxMDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDEwMDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX29iamNfY2xhc3NfcHJlZml4KCkgeworICBvYmpjX2NsYXNzX3ByZWZpeF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uczo6b2JqY19jbGFzc19wcmVmaXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorICByZXR1cm4gb2JqY19jbGFzc19wcmVmaXhfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfb2JqY19jbGFzc19wcmVmaXgoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICBvYmpjX2NsYXNzX3ByZWZpeF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgb2JqY19jbGFzc19wcmVmaXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIG9iamNfY2xhc3NfcHJlZml4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6Om11dGFibGVfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorICByZXR1cm4gb2JqY19jbGFzc19wcmVmaXhfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2Vfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIGNsZWFyX2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICByZXR1cm4gb2JqY19jbGFzc19wcmVmaXhfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9vYmpjX2NsYXNzX3ByZWZpeCg6OnN0ZDo6c3RyaW5nKiBvYmpjX2NsYXNzX3ByZWZpeCkgeworICBpZiAob2JqY19jbGFzc19wcmVmaXggIT0gTlVMTCkgeworICAgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgfQorICBvYmpjX2NsYXNzX3ByZWZpeF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG9iamNfY2xhc3NfcHJlZml4KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbmxpbmUgaW50IEZpbGVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBGaWxlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWxlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRmlsZU9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0ZpbGVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitGaWxlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE1lc3NhZ2VPcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2hhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgeworICBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6bWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KQorICByZXR1cm4gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9tZXNzYWdlX3NldF93aXJlX2Zvcm1hdChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKKyAgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KQorfQorCisvLyBvcHRpb25hbCBib29sIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IgPSAyIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfID0gZmFsc2U7CisgIGNsZWFyX2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6bm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcikKKyAgcmV0dXJuIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KK2lubGluZSBib29sIE1lc3NhZ2VPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBtYXBfZW50cnkgPSA3OworaW5saW5lIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19tYXBfZW50cnkoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9oYXNfbWFwX2VudHJ5KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX2hhc19tYXBfZW50cnkoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX21hcF9lbnRyeSgpIHsKKyAgbWFwX2VudHJ5XyA9IGZhbHNlOworICBjbGVhcl9oYXNfbWFwX2VudHJ5KCk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6bWFwX2VudHJ5KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5tYXBfZW50cnkpCisgIHJldHVybiBtYXBfZW50cnlfOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9tYXBfZW50cnkoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX21hcF9lbnRyeSgpOworICBtYXBfZW50cnlfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1hcF9lbnRyeSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW5saW5lIGludCBNZXNzYWdlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgTWVzc2FnZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogTWVzc2FnZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1lc3NhZ2VPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitNZXNzYWdlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorTWVzc2FnZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBGaWVsZE9wdGlvbnMKKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX2N0eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19jdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX2N0eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfY3R5cGUoKSB7CisgIGN0eXBlXyA9IDA7CisgIGNsZWFyX2hhc19jdHlwZSgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlIEZpZWxkT3B0aW9uczo6Y3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5jdHlwZSkKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSA+KGN0eXBlXyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9jdHlwZSg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGVfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX2N0eXBlKCk7CisgIGN0eXBlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuY3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gMjsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX3BhY2tlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfcGFja2VkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfcGFja2VkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfcGFja2VkKCkgeworICBwYWNrZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19wYWNrZWQoKTsKK30KK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6cGFja2VkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMucGFja2VkKQorICByZXR1cm4gcGFja2VkXzsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X3BhY2tlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2VkKCk7CisgIHBhY2tlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnBhY2tlZCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX2xhenkoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfaGFzX2xhenkoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc19sYXp5KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfbGF6eSgpIHsKKyAgbGF6eV8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2xhenkoKTsKK30KK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6bGF6eSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmxhenkpCisgIHJldHVybiBsYXp5XzsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2xhenkoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2xhenkoKTsKKyAgbGF6eV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmxhenkpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBGaWVsZE9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZE9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyBvcHRpb25hbCBib29sIHdlYWsgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX3dlYWsoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfaGFzX3dlYWsoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc193ZWFrKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfd2VhaygpIHsKKyAgd2Vha18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX3dlYWsoKTsKK30KK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6d2VhaygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLndlYWspCisgIHJldHVybiB3ZWFrXzsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X3dlYWsoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX3dlYWsoKTsKKyAgd2Vha18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLndlYWspCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKK2lubGluZSBpbnQgRmllbGRPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRmllbGRPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWVsZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWVsZE9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitGaWVsZE9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitGaWVsZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRW51bU9wdGlvbnMKKworLy8gb3B0aW9uYWwgYm9vbCBhbGxvd19hbGlhcyA9IDI7CitpbmxpbmUgYm9vbCBFbnVtT3B0aW9uczo6aGFzX2FsbG93X2FsaWFzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpzZXRfaGFzX2FsbG93X2FsaWFzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX2hhc19hbGxvd19hbGlhcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfYWxsb3dfYWxpYXMoKSB7CisgIGFsbG93X2FsaWFzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfYWxsb3dfYWxpYXMoKTsKK30KK2lubGluZSBib29sIEVudW1PcHRpb25zOjphbGxvd19hbGlhcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMuYWxsb3dfYWxpYXMpCisgIHJldHVybiBhbGxvd19hbGlhc187Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6c2V0X2FsbG93X2FsaWFzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19hbGxvd19hbGlhcygpOworICBhbGxvd19hbGlhc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMuYWxsb3dfYWxpYXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBFbnVtT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRW51bU9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KK2lubGluZSBib29sIEVudW1PcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW5saW5lIGludCBFbnVtT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRW51bU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRW51bU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEVudW1PcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitFbnVtT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorRW51bU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBFbnVtVmFsdWVPcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBFbnVtVmFsdWVPcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVPcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQoraW5saW5lIGJvb2wgRW51bVZhbHVlT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVPcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKK2lubGluZSBpbnQgRW51bVZhbHVlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBFbnVtVmFsdWVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRW51bVZhbHVlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBFbnVtVmFsdWVPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0VudW1WYWx1ZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorRW51bVZhbHVlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gU2VydmljZU9wdGlvbnMKKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBTZXJ2aWNlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgU2VydmljZU9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KK2lubGluZSBib29sIFNlcnZpY2VPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW5saW5lIGludCBTZXJ2aWNlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgU2VydmljZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogU2VydmljZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIFNlcnZpY2VPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitTZXJ2aWNlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorU2VydmljZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBNZXRob2RPcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgTWV0aG9kT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgTWV0aG9kT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgTWV0aG9kT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KK2lubGluZSBib29sIE1ldGhvZE9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQoraW5saW5lIHZvaWQgTWV0aG9kT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbmxpbmUgaW50IE1ldGhvZE9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgTWV0aG9kT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgTWV0aG9kT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1ldGhvZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogTWV0aG9kT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitNZXRob2RPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK01ldGhvZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQKKworLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpoYXNfbmFtZV9wYXJ0KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9oYXNfbmFtZV9wYXJ0KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Y2xlYXJfaGFzX25hbWVfcGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9uYW1lX3BhcnQoKSB7CisgIG5hbWVfcGFydF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6bmFtZV9wYXJ0KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKKyAgcmV0dXJuIG5hbWVfcGFydF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X25hbWVfcGFydChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X25hbWVfcGFydChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfbmFtZV9wYXJ0KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjptdXRhYmxlX25hbWVfcGFydCgpIHsKKyAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorICByZXR1cm4gbmFtZV9wYXJ0Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnJlbGVhc2VfbmFtZV9wYXJ0KCkgeworICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7CisgIHJldHVybiBuYW1lX3BhcnRfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfYWxsb2NhdGVkX25hbWVfcGFydCg6OnN0ZDo6c3RyaW5nKiBuYW1lX3BhcnQpIHsKKyAgaWYgKG5hbWVfcGFydCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7CisgIH0KKyAgbmFtZV9wYXJ0Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZV9wYXJ0KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQorCisvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpoYXNfaXNfZXh0ZW5zaW9uKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9oYXNfaXNfZXh0ZW5zaW9uKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Y2xlYXJfaGFzX2lzX2V4dGVuc2lvbigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9pc19leHRlbnNpb24oKSB7CisgIGlzX2V4dGVuc2lvbl8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2lzX2V4dGVuc2lvbigpOworfQoraW5saW5lIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6aXNfZXh0ZW5zaW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0LmlzX2V4dGVuc2lvbikKKyAgcmV0dXJuIGlzX2V4dGVuc2lvbl87Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfaXNfZXh0ZW5zaW9uKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19pc19leHRlbnNpb24oKTsKKyAgaXNfZXh0ZW5zaW9uXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0LmlzX2V4dGVuc2lvbikKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBVbmludGVycHJldGVkT3B0aW9uCisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKK2lubGluZSBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gbmFtZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIFVuaW50ZXJwcmV0ZWRPcHRpb246Om5hbWUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX25hbWUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIFVuaW50ZXJwcmV0ZWRPcHRpb246OmFkZF9uYW1lKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5hbWUpCisgIHJldHVybiBuYW1lXy5BZGQoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCA+JgorVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4qCitVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX25hbWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuICZuYW1lXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZpZXJfdmFsdWUgPSAzOworaW5saW5lIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2lkZW50aWZpZXJfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX2lkZW50aWZpZXJfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaWRlbnRpZmllcl92YWx1ZSgpIHsKKyAgaWRlbnRpZmllcl92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFVuaW50ZXJwcmV0ZWRPcHRpb246OmlkZW50aWZpZXJfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKKyAgcmV0dXJuIGlkZW50aWZpZXJfdmFsdWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICBpZGVudGlmaWVyX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgaWRlbnRpZmllcl92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6bXV0YWJsZV9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKKyAgcmV0dXJuIGlkZW50aWZpZXJfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICByZXR1cm4gaWRlbnRpZmllcl92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfaWRlbnRpZmllcl92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBpZGVudGlmaWVyX3ZhbHVlKSB7CisgIGlmIChpZGVudGlmaWVyX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICB9CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpZGVudGlmaWVyX3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9wb3NpdGl2ZV9pbnRfdmFsdWUoKSB7CisgIHBvc2l0aXZlX2ludF92YWx1ZV8gPSBHT09HTEVfVUxPTkdMT05HKDApOworICBjbGVhcl9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgVW5pbnRlcnByZXRlZE9wdGlvbjo6cG9zaXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnBvc2l0aXZlX2ludF92YWx1ZSkKKyAgcmV0dXJuIHBvc2l0aXZlX2ludF92YWx1ZV87Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfcG9zaXRpdmVfaW50X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDY0IHZhbHVlKSB7CisgIHNldF9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCk7CisgIHBvc2l0aXZlX2ludF92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5wb3NpdGl2ZV9pbnRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9uZWdhdGl2ZV9pbnRfdmFsdWUoKSB7CisgIG5lZ2F0aXZlX2ludF92YWx1ZV8gPSBHT09HTEVfTE9OR0xPTkcoMCk7CisgIGNsZWFyX2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IFVuaW50ZXJwcmV0ZWRPcHRpb246Om5lZ2F0aXZlX2ludF92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uZWdhdGl2ZV9pbnRfdmFsdWUpCisgIHJldHVybiBuZWdhdGl2ZV9pbnRfdmFsdWVfOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X25lZ2F0aXZlX2ludF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKSB7CisgIHNldF9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCk7CisgIG5lZ2F0aXZlX2ludF92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uZWdhdGl2ZV9pbnRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGRvdWJsZSBkb3VibGVfdmFsdWUgPSA2OworaW5saW5lIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2RvdWJsZV92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX2RvdWJsZV92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2hhc19kb3VibGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfZG91YmxlX3ZhbHVlKCkgeworICBkb3VibGVfdmFsdWVfID0gMDsKKyAgY2xlYXJfaGFzX2RvdWJsZV92YWx1ZSgpOworfQoraW5saW5lIGRvdWJsZSBVbmludGVycHJldGVkT3B0aW9uOjpkb3VibGVfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uZG91YmxlX3ZhbHVlKQorICByZXR1cm4gZG91YmxlX3ZhbHVlXzsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9kb3VibGVfdmFsdWUoZG91YmxlIHZhbHVlKSB7CisgIHNldF9oYXNfZG91YmxlX3ZhbHVlKCk7CisgIGRvdWJsZV92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5kb3VibGVfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfc3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDIwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfc3RyaW5nX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMjB1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX3N0cmluZ192YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9zdHJpbmdfdmFsdWUoKSB7CisgIHN0cmluZ192YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbjo6c3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnN0cmluZ192YWx1ZSkKKyAgcmV0dXJuIHN0cmluZ192YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X3N0cmluZ192YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBzdHJpbmdfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBzdHJpbmdfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfc3RyaW5nX3ZhbHVlKGNvbnN0IHZvaWQqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBzdHJpbmdfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnN0cmluZ192YWx1ZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX3N0cmluZ192YWx1ZSgpIHsKKyAgc2V0X2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorICByZXR1cm4gc3RyaW5nX3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246OnJlbGVhc2Vfc3RyaW5nX3ZhbHVlKCkgeworICBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHJldHVybiBzdHJpbmdfdmFsdWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWxsb2NhdGVkX3N0cmluZ192YWx1ZSg6OnN0ZDo6c3RyaW5nKiBzdHJpbmdfdmFsdWUpIHsKKyAgaWYgKHN0cmluZ192YWx1ZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIH0KKyAgc3RyaW5nX3ZhbHVlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgc3RyaW5nX3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgYWdncmVnYXRlX3ZhbHVlID0gODsKK2lubGluZSBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19hZ2dyZWdhdGVfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA0MHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfYWdncmVnYXRlX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDQwdTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2FnZ3JlZ2F0ZV92YWx1ZSgpIHsKKyAgYWdncmVnYXRlX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBVbmludGVycHJldGVkT3B0aW9uOjphZ2dyZWdhdGVfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorICByZXR1cm4gYWdncmVnYXRlX3ZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWdncmVnYXRlX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWdncmVnYXRlX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246Om11dGFibGVfYWdncmVnYXRlX3ZhbHVlKCkgeworICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCisgIHJldHVybiBhZ2dyZWdhdGVfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgcmV0dXJuIGFnZ3JlZ2F0ZV92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfYWdncmVnYXRlX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIGFnZ3JlZ2F0ZV92YWx1ZSkgeworICBpZiAoYWdncmVnYXRlX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgfQorICBhZ2dyZWdhdGVfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBhZ2dyZWdhdGVfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gU291cmNlQ29kZUluZm9fTG9jYXRpb24KKworLy8gcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZCA9IHRydWVdOworaW5saW5lIGludCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6cGF0aF9zaXplKCkgY29uc3QgeworICByZXR1cm4gcGF0aF8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX3BhdGgoKSB7CisgIHBhdGhfLkNsZWFyKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6cGF0aChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ucGF0aCkKKyAgcmV0dXJuIHBhdGhfLkdldChpbmRleCk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3BhdGgoaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHBhdGhfLlNldChpbmRleCwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9wYXRoKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgcGF0aF8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ucGF0aCkKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpwYXRoKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ucGF0aCkKKyAgcmV0dXJuIHBhdGhfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfcGF0aCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ucGF0aCkKKyAgcmV0dXJuICZwYXRoXzsKK30KKworLy8gcmVwZWF0ZWQgaW50MzIgc3BhbiA9IDIgW3BhY2tlZCA9IHRydWVdOworaW5saW5lIGludCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c3Bhbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gc3Bhbl8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX3NwYW4oKSB7CisgIHNwYW5fLkNsZWFyKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c3BhbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24uc3BhbikKKyAgcmV0dXJuIHNwYW5fLkdldChpbmRleCk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3NwYW4oaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNwYW5fLlNldChpbmRleCwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9zcGFuKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc3Bhbl8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24uc3BhbikKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzcGFuKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24uc3BhbikKKyAgcmV0dXJuIHNwYW5fOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfc3BhbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24uc3BhbikKKyAgcmV0dXJuICZzcGFuXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGxlYWRpbmdfY29tbWVudHMgPSAzOworaW5saW5lIGJvb2wgU291cmNlQ29kZUluZm9fTG9jYXRpb246Omhhc19sZWFkaW5nX2NvbW1lbnRzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfaGFzX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIGxlYWRpbmdfY29tbWVudHNfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bGVhZGluZ19jb21tZW50cygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfY29tbWVudHNfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19jb21tZW50cyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgbGVhZGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgbGVhZGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9sZWFkaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgbGVhZGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfbGVhZGluZ19jb21tZW50cygpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorICByZXR1cm4gbGVhZGluZ19jb21tZW50c18uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6cmVsZWFzZV9sZWFkaW5nX2NvbW1lbnRzKCkgeworICBjbGVhcl9oYXNfbGVhZGluZ19jb21tZW50cygpOworICByZXR1cm4gbGVhZGluZ19jb21tZW50c18uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfYWxsb2NhdGVkX2xlYWRpbmdfY29tbWVudHMoOjpzdGQ6OnN0cmluZyogbGVhZGluZ19jb21tZW50cykgeworICBpZiAobGVhZGluZ19jb21tZW50cyAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgfQorICBsZWFkaW5nX2NvbW1lbnRzXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbGVhZGluZ19jb21tZW50cyk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgdHJhaWxpbmdfY29tbWVudHMgPSA0OworaW5saW5lIGJvb2wgU291cmNlQ29kZUluZm9fTG9jYXRpb246Omhhc190cmFpbGluZ19jb21tZW50cygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2hhc190cmFpbGluZ19jb21tZW50cygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICB0cmFpbGluZ19jb21tZW50c18uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6dHJhaWxpbmdfY29tbWVudHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorICByZXR1cm4gdHJhaWxpbmdfY29tbWVudHNfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfdHJhaWxpbmdfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICB0cmFpbGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorICByZXR1cm4gdHJhaWxpbmdfY29tbWVudHNfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246OnJlbGVhc2VfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIGNsZWFyX2hhc190cmFpbGluZ19jb21tZW50cygpOworICByZXR1cm4gdHJhaWxpbmdfY29tbWVudHNfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2FsbG9jYXRlZF90cmFpbGluZ19jb21tZW50cyg6OnN0ZDo6c3RyaW5nKiB0cmFpbGluZ19jb21tZW50cykgeworICBpZiAodHJhaWxpbmdfY29tbWVudHMgIT0gTlVMTCkgeworICAgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgfQorICB0cmFpbGluZ19jb21tZW50c18uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHRyYWlsaW5nX2NvbW1lbnRzKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorfQorCisvLyByZXBlYXRlZCBzdHJpbmcgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyA9IDY7CitpbmxpbmUgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cygpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSB7CisgIHJldHVybiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5BZGQoKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSkgeworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JgorU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCisgIHJldHVybiAmbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c187Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gU291cmNlQ29kZUluZm8KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiBsb2NhdGlvbiA9IDE7CitpbmxpbmUgaW50IFNvdXJjZUNvZGVJbmZvOjpsb2NhdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gbG9jYXRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvOjpjbGVhcl9sb2NhdGlvbigpIHsKKyAgbG9jYXRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgU291cmNlQ29kZUluZm86OmxvY2F0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuIGxvY2F0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24qIFNvdXJjZUNvZGVJbmZvOjptdXRhYmxlX2xvY2F0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogU291cmNlQ29kZUluZm86OmFkZF9sb2NhdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uID4mCitTb3VyY2VDb2RlSW5mbzo6bG9jYXRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuIGxvY2F0aW9uXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24gPioKK1NvdXJjZUNvZGVJbmZvOjptdXRhYmxlX2xvY2F0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuICZsb2NhdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2lmbmRlZiBTV0lHCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBpc19wcm90b19lbnVtPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGU+IDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHt9OwordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZT4oKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfZGVzY3JpcHRvcigpOworfQordGVtcGxhdGUgPD4gc3RydWN0IGlzX3Byb3RvX2VudW08IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWw+IDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHt9OwordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWw+KCkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCk7Cit9Cit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgaXNfcHJvdG9fZW51bTwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGU+IDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHt9OwordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlPigpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKTsKK30KK3RlbXBsYXRlIDw+IHN0cnVjdCBpc19wcm90b19lbnVtPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZT4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUge307Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcjwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGU+KCkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGVfZGVzY3JpcHRvcigpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gU1dJRworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQorCisjZW5kaWYgIC8vIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvX19JTkNMVURFRApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2N2IxNmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KQEAgLTAsMCArMSw3MjkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGUgbWVzc2FnZXMgaW4gdGhpcyBmaWxlIGRlc2NyaWJlIHRoZSBkZWZpbml0aW9ucyBmb3VuZCBpbiAucHJvdG8gZmlsZXMuCisvLyBBIHZhbGlkIC5wcm90byBmaWxlIGNhbiBiZSB0cmFuc2xhdGVkIGRpcmVjdGx5IHRvIGEgRmlsZURlc2NyaXB0b3JQcm90bworLy8gd2l0aG91dCBhbnkgb3RoZXIgaW5mb3JtYXRpb24gKGUuZy4gd2l0aG91dCByZWFkaW5nIGl0cyBpbXBvcnRzKS4KKworCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIkRlc2NyaXB0b3JQcm90b3MiOworCisvLyBkZXNjcmlwdG9yLnByb3RvIG11c3QgYmUgb3B0aW1pemVkIGZvciBzcGVlZCBiZWNhdXNlIHJlZmxlY3Rpb24tYmFzZWQKKy8vIGFsZ29yaXRobXMgZG9uJ3Qgd29yayBkdXJpbmcgYm9vdHN0cmFwcGluZy4KK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworLy8gVGhlIHByb3RvY29sIGNvbXBpbGVyIGNhbiBvdXRwdXQgYSBGaWxlRGVzY3JpcHRvclNldCBjb250YWluaW5nIHRoZSAucHJvdG8KKy8vIGZpbGVzIGl0IHBhcnNlcy4KK21lc3NhZ2UgRmlsZURlc2NyaXB0b3JTZXQgeworICByZXBlYXRlZCBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworfQorCisvLyBEZXNjcmliZXMgYSBjb21wbGV0ZSAucHJvdG8gZmlsZS4KK21lc3NhZ2UgRmlsZURlc2NyaXB0b3JQcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsgICAgICAgLy8gZmlsZSBuYW1lLCByZWxhdGl2ZSB0byByb290IG9mIHNvdXJjZSB0cmVlCisgIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsgICAgLy8gZS5nLiAiZm9vIiwgImZvby5iYXIiLCBldGMuCisKKyAgLy8gTmFtZXMgb2YgZmlsZXMgaW1wb3J0ZWQgYnkgdGhpcyBmaWxlLgorICByZXBlYXRlZCBzdHJpbmcgZGVwZW5kZW5jeSA9IDM7CisgIC8vIEluZGV4ZXMgb2YgdGhlIHB1YmxpYyBpbXBvcnRlZCBmaWxlcyBpbiB0aGUgZGVwZW5kZW5jeSBsaXN0IGFib3ZlLgorICByZXBlYXRlZCBpbnQzMiBwdWJsaWNfZGVwZW5kZW5jeSA9IDEwOworICAvLyBJbmRleGVzIG9mIHRoZSB3ZWFrIGltcG9ydGVkIGZpbGVzIGluIHRoZSBkZXBlbmRlbmN5IGxpc3QuCisgIC8vIEZvciBHb29nbGUtaW50ZXJuYWwgbWlncmF0aW9uIG9ubHkuIERvIG5vdCB1c2UuCisgIHJlcGVhdGVkIGludDMyIHdlYWtfZGVwZW5kZW5jeSA9IDExOworCisgIC8vIEFsbCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhpcyBmaWxlLgorICByZXBlYXRlZCBEZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKKyAgcmVwZWF0ZWQgRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA1OworICByZXBlYXRlZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworICByZXBlYXRlZCBGaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA3OworCisgIG9wdGlvbmFsIEZpbGVPcHRpb25zIG9wdGlvbnMgPSA4OworCisgIC8vIFRoaXMgZmllbGQgY29udGFpbnMgb3B0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9yaWdpbmFsIHNvdXJjZSBjb2RlLgorICAvLyBZb3UgbWF5IHNhZmVseSByZW1vdmUgdGhpcyBlbnRpcmUgZmllbGQgd2l0aG91dCBoYXJtaW5nIHJ1bnRpbWUKKyAgLy8gZnVuY3Rpb25hbGl0eSBvZiB0aGUgZGVzY3JpcHRvcnMgLS0gdGhlIGluZm9ybWF0aW9uIGlzIG5lZWRlZCBvbmx5IGJ5CisgIC8vIGRldmVsb3BtZW50IHRvb2xzLgorICBvcHRpb25hbCBTb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKKworICAvLyBUaGUgc3ludGF4IG9mIHRoZSBwcm90byBmaWxlLgorICAvLyBUaGUgc3VwcG9ydGVkIHZhbHVlcyBhcmUgInByb3RvMiIgYW5kICJwcm90bzMiLgorICBvcHRpb25hbCBzdHJpbmcgc3ludGF4ID0gMTI7Cit9CisKKy8vIERlc2NyaWJlcyBhIG1lc3NhZ2UgdHlwZS4KK21lc3NhZ2UgRGVzY3JpcHRvclByb3RvIHsKKyAgb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworCisgIHJlcGVhdGVkIEZpZWxkRGVzY3JpcHRvclByb3RvIGZpZWxkID0gMjsKKyAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKKworICByZXBlYXRlZCBEZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICByZXBlYXRlZCBFbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CisKKyAgbWVzc2FnZSBFeHRlbnNpb25SYW5nZSB7CisgICAgb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworICAgIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgIH0KKyAgcmVwZWF0ZWQgRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKworICByZXBlYXRlZCBPbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKworICBvcHRpb25hbCBNZXNzYWdlT3B0aW9ucyBvcHRpb25zID0gNzsKK30KKworLy8gRGVzY3JpYmVzIGEgZmllbGQgd2l0aGluIGEgbWVzc2FnZS4KK21lc3NhZ2UgRmllbGREZXNjcmlwdG9yUHJvdG8geworICBlbnVtIFR5cGUgeworICAgIC8vIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycy4KKyAgICAvLyBPcmRlciBpcyB3ZWlyZCBmb3IgaGlzdG9yaWNhbCByZWFzb25zLgorICAgIFRZUEVfRE9VQkxFICAgICAgICAgPSAxOworICAgIFRZUEVfRkxPQVQgICAgICAgICAgPSAyOworICAgIC8vIE5vdCBaaWdaYWcgZW5jb2RlZC4gIE5lZ2F0aXZlIG51bWJlcnMgdGFrZSAxMCBieXRlcy4gIFVzZSBUWVBFX1NJTlQ2NCBpZgorICAgIC8vIG5lZ2F0aXZlIHZhbHVlcyBhcmUgbGlrZWx5LgorICAgIFRZUEVfSU5UNjQgICAgICAgICAgPSAzOworICAgIFRZUEVfVUlOVDY0ICAgICAgICAgPSA0OworICAgIC8vIE5vdCBaaWdaYWcgZW5jb2RlZC4gIE5lZ2F0aXZlIG51bWJlcnMgdGFrZSAxMCBieXRlcy4gIFVzZSBUWVBFX1NJTlQzMiBpZgorICAgIC8vIG5lZ2F0aXZlIHZhbHVlcyBhcmUgbGlrZWx5LgorICAgIFRZUEVfSU5UMzIgICAgICAgICAgPSA1OworICAgIFRZUEVfRklYRUQ2NCAgICAgICAgPSA2OworICAgIFRZUEVfRklYRUQzMiAgICAgICAgPSA3OworICAgIFRZUEVfQk9PTCAgICAgICAgICAgPSA4OworICAgIFRZUEVfU1RSSU5HICAgICAgICAgPSA5OworICAgIFRZUEVfR1JPVVAgICAgICAgICAgPSAxMDsgIC8vIFRhZy1kZWxpbWl0ZWQgYWdncmVnYXRlLgorICAgIFRZUEVfTUVTU0FHRSAgICAgICAgPSAxMTsgIC8vIExlbmd0aC1kZWxpbWl0ZWQgYWdncmVnYXRlLgorCisgICAgLy8gTmV3IGluIHZlcnNpb24gMi4KKyAgICBUWVBFX0JZVEVTICAgICAgICAgID0gMTI7CisgICAgVFlQRV9VSU5UMzIgICAgICAgICA9IDEzOworICAgIFRZUEVfRU5VTSAgICAgICAgICAgPSAxNDsKKyAgICBUWVBFX1NGSVhFRDMyICAgICAgID0gMTU7CisgICAgVFlQRV9TRklYRUQ2NCAgICAgICA9IDE2OworICAgIFRZUEVfU0lOVDMyICAgICAgICAgPSAxNzsgIC8vIFVzZXMgWmlnWmFnIGVuY29kaW5nLgorICAgIFRZUEVfU0lOVDY0ICAgICAgICAgPSAxODsgIC8vIFVzZXMgWmlnWmFnIGVuY29kaW5nLgorICB9OworCisgIGVudW0gTGFiZWwgeworICAgIC8vIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycworICAgIExBQkVMX09QVElPTkFMICAgICAgPSAxOworICAgIExBQkVMX1JFUVVJUkVEICAgICAgPSAyOworICAgIExBQkVMX1JFUEVBVEVEICAgICAgPSAzOworICAgIC8vIFRPRE8oc2FuamF5KTogU2hvdWxkIHdlIGFkZCBMQUJFTF9NQVA/CisgIH07CisKKyAgb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICBvcHRpb25hbCBMYWJlbCBsYWJlbCA9IDQ7CisKKyAgLy8gSWYgdHlwZV9uYW1lIGlzIHNldCwgdGhpcyBuZWVkIG5vdCBiZSBzZXQuICBJZiBib3RoIHRoaXMgYW5kIHR5cGVfbmFtZQorICAvLyBhcmUgc2V0LCB0aGlzIG11c3QgYmUgb25lIG9mIFRZUEVfRU5VTSwgVFlQRV9NRVNTQUdFIG9yIFRZUEVfR1JPVVAuCisgIG9wdGlvbmFsIFR5cGUgdHlwZSA9IDU7CisKKyAgLy8gRm9yIG1lc3NhZ2UgYW5kIGVudW0gdHlwZXMsIHRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHR5cGUuICBJZiB0aGUgbmFtZQorICAvLyBzdGFydHMgd2l0aCBhICcuJywgaXQgaXMgZnVsbHktcXVhbGlmaWVkLiAgT3RoZXJ3aXNlLCBDKystbGlrZSBzY29waW5nCisgIC8vIHJ1bGVzIGFyZSB1c2VkIHRvIGZpbmQgdGhlIHR5cGUgKGkuZS4gZmlyc3QgdGhlIG5lc3RlZCB0eXBlcyB3aXRoaW4gdGhpcworICAvLyBtZXNzYWdlIGFyZSBzZWFyY2hlZCwgdGhlbiB3aXRoaW4gdGhlIHBhcmVudCwgb24gdXAgdG8gdGhlIHJvb3QKKyAgLy8gbmFtZXNwYWNlKS4KKyAgb3B0aW9uYWwgc3RyaW5nIHR5cGVfbmFtZSA9IDY7CisKKyAgLy8gRm9yIGV4dGVuc2lvbnMsIHRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHR5cGUgYmVpbmcgZXh0ZW5kZWQuICBJdCBpcworICAvLyByZXNvbHZlZCBpbiB0aGUgc2FtZSBtYW5uZXIgYXMgdHlwZV9uYW1lLgorICBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworCisgIC8vIEZvciBudW1lcmljIHR5cGVzLCBjb250YWlucyB0aGUgb3JpZ2luYWwgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWUuCisgIC8vIEZvciBib29sZWFucywgInRydWUiIG9yICJmYWxzZSIuCisgIC8vIEZvciBzdHJpbmdzLCBjb250YWlucyB0aGUgZGVmYXVsdCB0ZXh0IGNvbnRlbnRzIChub3QgZXNjYXBlZCBpbiBhbnkgd2F5KS4KKyAgLy8gRm9yIGJ5dGVzLCBjb250YWlucyB0aGUgQyBlc2NhcGVkIHZhbHVlLiAgQWxsIGJ5dGVzID49IDEyOCBhcmUgZXNjYXBlZC4KKyAgLy8gVE9ETyhrZW50b24pOiAgQmFzZS02NCBlbmNvZGU/CisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gNzsKKworICAvLyBJZiBzZXQsIGdpdmVzIHRoZSBpbmRleCBvZiBhIG9uZW9mIGluIHRoZSBjb250YWluaW5nIHR5cGUncyBvbmVvZl9kZWNsCisgIC8vIGxpc3QuICBUaGlzIGZpZWxkIGlzIGEgbWVtYmVyIG9mIHRoYXQgb25lb2YuCisgIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKKworICBvcHRpb25hbCBGaWVsZE9wdGlvbnMgb3B0aW9ucyA9IDg7Cit9CisKKy8vIERlc2NyaWJlcyBhIG9uZW9mLgorbWVzc2FnZSBPbmVvZkRlc2NyaXB0b3JQcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK30KKworLy8gRGVzY3JpYmVzIGFuIGVudW0gdHlwZS4KK21lc3NhZ2UgRW51bURlc2NyaXB0b3JQcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKworICByZXBlYXRlZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworCisgIG9wdGlvbmFsIEVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworfQorCisvLyBEZXNjcmliZXMgYSB2YWx1ZSB3aXRoaW4gYW4gZW51bS4KK21lc3NhZ2UgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHsKKyAgb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAyOworCisgIG9wdGlvbmFsIEVudW1WYWx1ZU9wdGlvbnMgb3B0aW9ucyA9IDM7Cit9CisKKy8vIERlc2NyaWJlcyBhIHNlcnZpY2UuCittZXNzYWdlIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8geworICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIHJlcGVhdGVkIE1ldGhvZERlc2NyaXB0b3JQcm90byBtZXRob2QgPSAyOworCisgIG9wdGlvbmFsIFNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworfQorCisvLyBEZXNjcmliZXMgYSBtZXRob2Qgb2YgYSBzZXJ2aWNlLgorbWVzc2FnZSBNZXRob2REZXNjcmlwdG9yUHJvdG8geworICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisKKyAgLy8gSW5wdXQgYW5kIG91dHB1dCB0eXBlIG5hbWVzLiAgVGhlc2UgYXJlIHJlc29sdmVkIGluIHRoZSBzYW1lIHdheSBhcworICAvLyBGaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUsIGJ1dCBtdXN0IHJlZmVyIHRvIGEgbWVzc2FnZSB0eXBlLgorICBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgIG9wdGlvbmFsIHN0cmluZyBvdXRwdXRfdHlwZSA9IDM7CisKKyAgb3B0aW9uYWwgTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKworICAvLyBJZGVudGlmaWVzIGlmIGNsaWVudCBzdHJlYW1zIG11bHRpcGxlIGNsaWVudCBtZXNzYWdlcworICBvcHRpb25hbCBib29sIGNsaWVudF9zdHJlYW1pbmcgPSA1IFtkZWZhdWx0PWZhbHNlXTsKKyAgLy8gSWRlbnRpZmllcyBpZiBzZXJ2ZXIgc3RyZWFtcyBtdWx0aXBsZSBzZXJ2ZXIgbWVzc2FnZXMKKyAgb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdD1mYWxzZV07Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gT3B0aW9ucworCisvLyBFYWNoIG9mIHRoZSBkZWZpbml0aW9ucyBhYm92ZSBtYXkgaGF2ZSAib3B0aW9ucyIgYXR0YWNoZWQuICBUaGVzZSBhcmUKKy8vIGp1c3QgYW5ub3RhdGlvbnMgd2hpY2ggbWF5IGNhdXNlIGNvZGUgdG8gYmUgZ2VuZXJhdGVkIHNsaWdodGx5IGRpZmZlcmVudGx5CisvLyBvciBtYXkgY29udGFpbiBoaW50cyBmb3IgY29kZSB0aGF0IG1hbmlwdWxhdGVzIHByb3RvY29sIG1lc3NhZ2VzLgorLy8KKy8vIENsaWVudHMgbWF5IGRlZmluZSBjdXN0b20gb3B0aW9ucyBhcyBleHRlbnNpb25zIG9mIHRoZSAqT3B0aW9ucyBtZXNzYWdlcy4KKy8vIFRoZXNlIGV4dGVuc2lvbnMgbWF5IG5vdCB5ZXQgYmUga25vd24gYXQgcGFyc2luZyB0aW1lLCBzbyB0aGUgcGFyc2VyIGNhbm5vdAorLy8gc3RvcmUgdGhlIHZhbHVlcyBpbiB0aGVtLiAgSW5zdGVhZCBpdCBzdG9yZXMgdGhlbSBpbiBhIGZpZWxkIGluIHRoZSAqT3B0aW9ucworLy8gbWVzc2FnZSBjYWxsZWQgdW5pbnRlcnByZXRlZF9vcHRpb24uIFRoaXMgZmllbGQgbXVzdCBoYXZlIHRoZSBzYW1lIG5hbWUKKy8vIGFjcm9zcyBhbGwgKk9wdGlvbnMgbWVzc2FnZXMuIFdlIHRoZW4gdXNlIHRoaXMgZmllbGQgdG8gcG9wdWxhdGUgdGhlCisvLyBleHRlbnNpb25zIHdoZW4gd2UgYnVpbGQgYSBkZXNjcmlwdG9yLCBhdCB3aGljaCBwb2ludCBhbGwgcHJvdG9zIGhhdmUgYmVlbgorLy8gcGFyc2VkIGFuZCBzbyBhbGwgZXh0ZW5zaW9ucyBhcmUga25vd24uCisvLworLy8gRXh0ZW5zaW9uIG51bWJlcnMgZm9yIGN1c3RvbSBvcHRpb25zIG1heSBiZSBjaG9zZW4gYXMgZm9sbG93czoKKy8vICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBvbmx5IGJlIHVzZWQgd2l0aGluIGEgc2luZ2xlIGFwcGxpY2F0aW9uIG9yCisvLyAgIG9yZ2FuaXphdGlvbiwgb3IgZm9yIGV4cGVyaW1lbnRhbCBvcHRpb25zLCB1c2UgZmllbGQgbnVtYmVycyA1MDAwMAorLy8gICB0aHJvdWdoIDk5OTk5LiAgSXQgaXMgdXAgdG8geW91IHRvIGVuc3VyZSB0aGF0IHlvdSBkbyBub3QgdXNlIHRoZQorLy8gICBzYW1lIG51bWJlciBmb3IgbXVsdGlwbGUgb3B0aW9ucy4KKy8vICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBiZSBwdWJsaXNoZWQgYW5kIHVzZWQgcHVibGljbHkgYnkgbXVsdGlwbGUKKy8vICAgaW5kZXBlbmRlbnQgZW50aXRpZXMsIGUtbWFpbCBwcm90b2J1Zi1nbG9iYWwtZXh0ZW5zaW9uLXJlZ2lzdHJ5QGdvb2dsZS5jb20KKy8vICAgdG8gcmVzZXJ2ZSBleHRlbnNpb24gbnVtYmVycy4gU2ltcGx5IHByb3ZpZGUgeW91ciBwcm9qZWN0IG5hbWUgKGUuZy4KKy8vICAgT2JqZWN0LUMgcGx1Z2luKSBhbmQgeW91ciBwb3JqZWN0IHdlYnNpdGUgKGlmIGF2YWlsYWJsZSkgLS0gdGhlcmUncyBubyBuZWVkCisvLyAgIHRvIGV4cGxhaW4gaG93IHlvdSBpbnRlbmQgdG8gdXNlIHRoZW0uIFVzdWFsbHkgeW91IG9ubHkgbmVlZCBvbmUgZXh0ZW5zaW9uCisvLyAgIG51bWJlci4gWW91IGNhbiBkZWNsYXJlIG11bHRpcGxlIG9wdGlvbnMgd2l0aCBvbmx5IG9uZSBleHRlbnNpb24gbnVtYmVyIGJ5CisvLyAgIHB1dHRpbmcgdGhlbSBpbiBhIHN1Yi1tZXNzYWdlLiBTZWUgdGhlIEN1c3RvbSBPcHRpb25zIHNlY3Rpb24gb2YgdGhlIGRvY3MKKy8vICAgZm9yIGV4YW1wbGVzOgorLy8gICBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzL2RvY3MvcHJvdG8jb3B0aW9ucworLy8gICBJZiB0aGlzIHR1cm5zIG91dCB0byBiZSBwb3B1bGFyLCBhIHdlYiBzZXJ2aWNlIHdpbGwgYmUgc2V0IHVwCisvLyAgIHRvIGF1dG9tYXRpY2FsbHkgYXNzaWduIG9wdGlvbiBudW1iZXJzLgorCisKK21lc3NhZ2UgRmlsZU9wdGlvbnMgeworCisgIC8vIFNldHMgdGhlIEphdmEgcGFja2FnZSB3aGVyZSBjbGFzc2VzIGdlbmVyYXRlZCBmcm9tIHRoaXMgLnByb3RvIHdpbGwgYmUKKyAgLy8gcGxhY2VkLiAgQnkgZGVmYXVsdCwgdGhlIHByb3RvIHBhY2thZ2UgaXMgdXNlZCwgYnV0IHRoaXMgaXMgb2Z0ZW4KKyAgLy8gaW5hcHByb3ByaWF0ZSBiZWNhdXNlIHByb3RvIHBhY2thZ2VzIGRvIG5vdCBub3JtYWxseSBzdGFydCB3aXRoIGJhY2t3YXJkcworICAvLyBkb21haW4gbmFtZXMuCisgIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworCisKKyAgLy8gSWYgc2V0LCBhbGwgdGhlIGNsYXNzZXMgZnJvbSB0aGUgLnByb3RvIGZpbGUgYXJlIHdyYXBwZWQgaW4gYSBzaW5nbGUKKyAgLy8gb3V0ZXIgY2xhc3Mgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gIFRoaXMgYXBwbGllcyB0byBib3RoIFByb3RvMQorICAvLyAoZXF1aXZhbGVudCB0byB0aGUgb2xkICItLW9uZV9qYXZhX2ZpbGUiIG9wdGlvbikgYW5kIFByb3RvMiAod2hlcmUKKyAgLy8gYSAucHJvdG8gYWx3YXlzIHRyYW5zbGF0ZXMgdG8gYSBzaW5nbGUgY2xhc3MsIGJ1dCB5b3UgbWF5IHdhbnQgdG8KKyAgLy8gZXhwbGljaXRseSBjaG9vc2UgdGhlIGNsYXNzIG5hbWUpLgorICBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworCisgIC8vIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhIGNvZGUgZ2VuZXJhdG9yIHdpbGwgZ2VuZXJhdGUgYSBzZXBhcmF0ZSAuamF2YQorICAvLyBmaWxlIGZvciBlYWNoIHRvcC1sZXZlbCBtZXNzYWdlLCBlbnVtLCBhbmQgc2VydmljZSBkZWZpbmVkIGluIHRoZSAucHJvdG8KKyAgLy8gZmlsZS4gIFRodXMsIHRoZXNlIHR5cGVzIHdpbGwgKm5vdCogYmUgbmVzdGVkIGluc2lkZSB0aGUgb3V0ZXIgY2xhc3MKKyAgLy8gbmFtZWQgYnkgamF2YV9vdXRlcl9jbGFzc25hbWUuICBIb3dldmVyLCB0aGUgb3V0ZXIgY2xhc3Mgd2lsbCBzdGlsbCBiZQorICAvLyBnZW5lcmF0ZWQgdG8gY29udGFpbiB0aGUgZmlsZSdzIGdldERlc2NyaXB0b3IoKSBtZXRob2QgYXMgd2VsbCBhcyBhbnkKKyAgLy8gdG9wLWxldmVsIGV4dGVuc2lvbnMgZGVmaW5lZCBpbiB0aGUgZmlsZS4KKyAgb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhIGNvZGUgZ2VuZXJhdG9yIHdpbGwgZ2VuZXJhdGUgZXF1YWxzKCkgYW5kCisgIC8vIGhhc2hDb2RlKCkgbWV0aG9kcyBmb3IgYWxsIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICAvLyAtIEluIHRoZSBmdWxsIHJ1bnRpbWUsIHRoaXMgaXMgcHVyZWx5IGEgc3BlZWQgb3B0aW1pemF0aW9uLCBhcyB0aGUKKyAgLy8gQWJzdHJhY3RNZXNzYWdlIGJhc2UgY2xhc3MgaW5jbHVkZXMgcmVmbGVjdGlvbi1iYXNlZCBpbXBsZW1lbnRhdGlvbnMgb2YKKyAgLy8gdGhlc2UgbWV0aG9kcy4KKyAgLy8tIEluIHRoZSBsaXRlIHJ1bnRpbWUsIHNldHRpbmcgdGhpcyBvcHRpb24gY2hhbmdlcyB0aGUgc2VtYW50aWNzIG9mCisgIC8vIGVxdWFscygpIGFuZCBoYXNoQ29kZSgpIHRvIG1vcmUgY2xvc2VseSBtYXRjaCB0aG9zZSBvZiB0aGUgZnVsbCBydW50aW1lOworICAvLyB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMgY29tcHV0ZSB0aGVpciByZXN1bHRzIGJhc2VkIG9uIGZpZWxkIHZhbHVlcyByYXRoZXIKKyAgLy8gdGhhbiBvYmplY3QgaWRlbnRpdHkuIChJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCBhc3N1bWUgdGhhdCBoYXNoY29kZXMKKyAgLy8gd2lsbCBiZSBjb25zaXN0ZW50IGFjcm9zcyBydW50aW1lcyBvciB2ZXJzaW9ucyBvZiB0aGUgcHJvdG9jb2wgY29tcGlsZXIuKQorICBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhMiBjb2RlIGdlbmVyYXRvciB3aWxsIGdlbmVyYXRlIGNvZGUgdGhhdAorICAvLyB0aHJvd3MgYW4gZXhjZXB0aW9uIHdoZW5ldmVyIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBhc3NpZ24gYSBub24tVVRGLTgKKyAgLy8gYnl0ZSBzZXF1ZW5jZSB0byBhIHN0cmluZyBmaWVsZC4KKyAgLy8gTWVzc2FnZSByZWZsZWN0aW9uIHdpbGwgZG8gdGhlIHNhbWUuCisgIC8vIEhvd2V2ZXIsIGFuIGV4dGVuc2lvbiBmaWVsZCBzdGlsbCBhY2NlcHRzIG5vbi1VVEYtOCBieXRlIHNlcXVlbmNlcy4KKyAgLy8gVGhpcyBvcHRpb24gaGFzIG5vIGVmZmVjdCBvbiB3aGVuIHVzZWQgd2l0aCB0aGUgbGl0ZSBydW50aW1lLgorICBvcHRpb25hbCBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjggPSAyNyBbZGVmYXVsdD1mYWxzZV07CisKKworICAvLyBHZW5lcmF0ZWQgY2xhc3NlcyBjYW4gYmUgb3B0aW1pemVkIGZvciBzcGVlZCBvciBjb2RlIHNpemUuCisgIGVudW0gT3B0aW1pemVNb2RlIHsKKyAgICBTUEVFRCA9IDE7ICAgICAgICAvLyBHZW5lcmF0ZSBjb21wbGV0ZSBjb2RlIGZvciBwYXJzaW5nLCBzZXJpYWxpemF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgIC8vIGV0Yy4KKyAgICBDT0RFX1NJWkUgPSAyOyAgICAvLyBVc2UgUmVmbGVjdGlvbk9wcyB0byBpbXBsZW1lbnQgdGhlc2UgbWV0aG9kcy4KKyAgICBMSVRFX1JVTlRJTUUgPSAzOyAvLyBHZW5lcmF0ZSBjb2RlIHVzaW5nIE1lc3NhZ2VMaXRlIGFuZCB0aGUgbGl0ZSBydW50aW1lLgorICB9CisgIG9wdGlvbmFsIE9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0PVNQRUVEXTsKKworICAvLyBTZXRzIHRoZSBHbyBwYWNrYWdlIHdoZXJlIHN0cnVjdHMgZ2VuZXJhdGVkIGZyb20gdGhpcyAucHJvdG8gd2lsbCBiZQorICAvLyBwbGFjZWQuIElmIG9taXR0ZWQsIHRoZSBHbyBwYWNrYWdlIHdpbGwgYmUgZGVyaXZlZCBmcm9tIHRoZSBmb2xsb3dpbmc6CisgIC8vICAgLSBUaGUgYmFzZW5hbWUgb2YgdGhlIHBhY2thZ2UgaW1wb3J0IHBhdGgsIGlmIHByb3ZpZGVkLgorICAvLyAgIC0gT3RoZXJ3aXNlLCB0aGUgcGFja2FnZSBzdGF0ZW1lbnQgaW4gdGhlIC5wcm90byBmaWxlLCBpZiBwcmVzZW50LgorICAvLyAgIC0gT3RoZXJ3aXNlLCB0aGUgYmFzZW5hbWUgb2YgdGhlIC5wcm90byBmaWxlLCB3aXRob3V0IGV4dGVuc2lvbi4KKyAgb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKKworCisKKyAgLy8gU2hvdWxkIGdlbmVyaWMgc2VydmljZXMgYmUgZ2VuZXJhdGVkIGluIGVhY2ggbGFuZ3VhZ2U/ICAiR2VuZXJpYyIgc2VydmljZXMKKyAgLy8gYXJlIG5vdCBzcGVjaWZpYyB0byBhbnkgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhleSBhcmUgZ2VuZXJhdGVkIGJ5IHRoZQorICAvLyBtYWluIGNvZGUgZ2VuZXJhdG9ycyBpbiBlYWNoIGxhbmd1YWdlICh3aXRob3V0IGFkZGl0aW9uYWwgcGx1Z2lucykuCisgIC8vIEdlbmVyaWMgc2VydmljZXMgd2VyZSB0aGUgb25seSBraW5kIG9mIHNlcnZpY2UgZ2VuZXJhdGlvbiBzdXBwb3J0ZWQgYnkKKyAgLy8gZWFybHkgdmVyc2lvbnMgb2YgZ29vZ2xlLnByb3RvYnVmLgorICAvLworICAvLyBHZW5lcmljIHNlcnZpY2VzIGFyZSBub3cgY29uc2lkZXJlZCBkZXByZWNhdGVkIGluIGZhdm9yIG9mIHVzaW5nIHBsdWdpbnMKKyAgLy8gdGhhdCBnZW5lcmF0ZSBjb2RlIHNwZWNpZmljIHRvIHlvdXIgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhlcmVmb3JlLAorICAvLyB0aGVzZSBkZWZhdWx0IHRvIGZhbHNlLiAgT2xkIGNvZGUgd2hpY2ggZGVwZW5kcyBvbiBnZW5lcmljIHNlcnZpY2VzIHNob3VsZAorICAvLyBleHBsaWNpdGx5IHNldCB0aGVtIHRvIHRydWUuCisgIG9wdGlvbmFsIGJvb2wgY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IDE2IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSAxNyBbZGVmYXVsdD1mYWxzZV07CisgIG9wdGlvbmFsIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IDE4IFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBJcyB0aGlzIGZpbGUgZGVwcmVjYXRlZD8KKyAgLy8gRGVwZW5kaW5nIG9uIHRoZSB0YXJnZXQgcGxhdGZvcm0sIHRoaXMgY2FuIGVtaXQgRGVwcmVjYXRlZCBhbm5vdGF0aW9ucworICAvLyBmb3IgZXZlcnl0aGluZyBpbiB0aGUgZmlsZSwgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5CisgIC8vIGxlYXN0LCB0aGlzIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgZmlsZXMuCisgIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDIzIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBFbmFibGVzIHRoZSB1c2Ugb2YgYXJlbmFzIGZvciB0aGUgcHJvdG8gbWVzc2FnZXMgaW4gdGhpcyBmaWxlLiBUaGlzIGFwcGxpZXMKKyAgLy8gb25seSB0byBnZW5lcmF0ZWQgY2xhc3NlcyBmb3IgQysrLgorICBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdD1mYWxzZV07CisKKworICAvLyBTZXRzIHRoZSBvYmplY3RpdmUgYyBjbGFzcyBwcmVmaXggd2hpY2ggaXMgcHJlcGVuZGVkIHRvIGFsbCBvYmplY3RpdmUgYworICAvLyBnZW5lcmF0ZWQgY2xhc3NlcyBmcm9tIHRoaXMgLnByb3RvLiBUaGVyZSBpcyBubyBkZWZhdWx0LgorICBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKworICAvLyBUaGUgcGFyc2VyIHN0b3JlcyBvcHRpb25zIGl0IGRvZXNuJ3QgcmVjb2duaXplIGhlcmUuIFNlZSBhYm92ZS4KKyAgcmVwZWF0ZWQgVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKworICAvLyBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KKworbWVzc2FnZSBNZXNzYWdlT3B0aW9ucyB7CisgIC8vIFNldCB0cnVlIHRvIHVzZSB0aGUgb2xkIHByb3RvMSBNZXNzYWdlU2V0IHdpcmUgZm9ybWF0IGZvciBleHRlbnNpb25zLgorICAvLyBUaGlzIGlzIHByb3ZpZGVkIGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSB3aXRoIHRoZSBNZXNzYWdlU2V0IHdpcmUKKyAgLy8gZm9ybWF0LiAgWW91IHNob3VsZCBub3QgdXNlIHRoaXMgZm9yIGFueSBvdGhlciByZWFzb246ICBJdCdzIGxlc3MKKyAgLy8gZWZmaWNpZW50LCBoYXMgZmV3ZXIgZmVhdHVyZXMsIGFuZCBpcyBtb3JlIGNvbXBsaWNhdGVkLgorICAvLworICAvLyBUaGUgbWVzc2FnZSBtdXN0IGJlIGRlZmluZWQgZXhhY3RseSBhcyBmb2xsb3dzOgorICAvLyAgIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICAgIG9wdGlvbiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IHRydWU7CisgIC8vICAgICBleHRlbnNpb25zIDQgdG8gbWF4OworICAvLyAgIH0KKyAgLy8gTm90ZSB0aGF0IHRoZSBtZXNzYWdlIGNhbm5vdCBoYXZlIGFueSBkZWZpbmVkIGZpZWxkczsgTWVzc2FnZVNldHMgb25seQorICAvLyBoYXZlIGV4dGVuc2lvbnMuCisgIC8vCisgIC8vIEFsbCBleHRlbnNpb25zIG9mIHlvdXIgdHlwZSBtdXN0IGJlIHNpbmd1bGFyIG1lc3NhZ2VzOyBlLmcuIHRoZXkgY2Fubm90CisgIC8vIGJlIGludDMycywgZW51bXMsIG9yIHJlcGVhdGVkIG1lc3NhZ2VzLgorICAvLworICAvLyBCZWNhdXNlIHRoaXMgaXMgYW4gb3B0aW9uLCB0aGUgYWJvdmUgdHdvIHJlc3RyaWN0aW9ucyBhcmUgbm90IGVuZm9yY2VkIGJ5CisgIC8vIHRoZSBwcm90b2NvbCBjb21waWxlci4KKyAgb3B0aW9uYWwgYm9vbCBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IDEgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIERpc2FibGVzIHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBzdGFuZGFyZCAiZGVzY3JpcHRvcigpIiBhY2Nlc3Nvciwgd2hpY2ggY2FuCisgIC8vIGNvbmZsaWN0IHdpdGggYSBmaWVsZCBvZiB0aGUgc2FtZSBuYW1lLiAgVGhpcyBpcyBtZWFudCB0byBtYWtlIG1pZ3JhdGlvbgorICAvLyBmcm9tIHByb3RvMSBlYXNpZXI7IG5ldyBjb2RlIHNob3VsZCBhdm9pZCBmaWVsZHMgbmFtZWQgImRlc2NyaXB0b3IiLgorICBvcHRpb25hbCBib29sIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IgPSAyIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBJcyB0aGlzIG1lc3NhZ2UgZGVwcmVjYXRlZD8KKyAgLy8gRGVwZW5kaW5nIG9uIHRoZSB0YXJnZXQgcGxhdGZvcm0sIHRoaXMgY2FuIGVtaXQgRGVwcmVjYXRlZCBhbm5vdGF0aW9ucworICAvLyBmb3IgdGhlIG1lc3NhZ2UsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwKKyAgLy8gdGhpcyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIG1lc3NhZ2VzLgorICBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBXaGV0aGVyIHRoZSBtZXNzYWdlIGlzIGFuIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIG1hcCBlbnRyeSB0eXBlIGZvciB0aGUKKyAgLy8gbWFwcyBmaWVsZC4KKyAgLy8KKyAgLy8gRm9yIG1hcHMgZmllbGRzOgorICAvLyAgICAgbWFwPEtleVR5cGUsIFZhbHVlVHlwZT4gbWFwX2ZpZWxkID0gMTsKKyAgLy8gVGhlIHBhcnNlZCBkZXNjcmlwdG9yIGxvb2tzIGxpa2U6CisgIC8vICAgICBtZXNzYWdlIE1hcEZpZWxkRW50cnkgeworICAvLyAgICAgICAgIG9wdGlvbiBtYXBfZW50cnkgPSB0cnVlOworICAvLyAgICAgICAgIG9wdGlvbmFsIEtleVR5cGUga2V5ID0gMTsKKyAgLy8gICAgICAgICBvcHRpb25hbCBWYWx1ZVR5cGUgdmFsdWUgPSAyOworICAvLyAgICAgfQorICAvLyAgICAgcmVwZWF0ZWQgTWFwRmllbGRFbnRyeSBtYXBfZmllbGQgPSAxOworICAvLworICAvLyBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gZ2VuZXJhdGUgdGhlIG1hcF9lbnRyeT10cnVlIG1lc3NhZ2UsIGJ1dAorICAvLyB1c2UgYSBuYXRpdmUgbWFwIGluIHRoZSB0YXJnZXQgbGFuZ3VhZ2UgdG8gaG9sZCB0aGUga2V5cyBhbmQgdmFsdWVzLgorICAvLyBUaGUgcmVmbGVjdGlvbiBBUElzIGluIHN1Y2ggaW1wbGVtZW50aW9ucyBzdGlsbCBuZWVkIHRvIHdvcmsgYXMKKyAgLy8gaWYgdGhlIGZpZWxkIGlzIGEgcmVwZWF0ZWQgbWVzc2FnZSBmaWVsZC4KKyAgLy8KKyAgLy8gTk9URTogRG8gbm90IHNldCB0aGUgb3B0aW9uIGluIC5wcm90byBmaWxlcy4gQWx3YXlzIHVzZSB0aGUgbWFwcyBzeW50YXgKKyAgLy8gaW5zdGVhZC4gVGhlIG9wdGlvbiBzaG91bGQgb25seSBiZSBpbXBsaWNpdGx5IHNldCBieSB0aGUgcHJvdG8gY29tcGlsZXIKKyAgLy8gcGFyc2VyLgorICBvcHRpb25hbCBib29sIG1hcF9lbnRyeSA9IDc7CisKKyAgLy8gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCisgIHJlcGVhdGVkIFVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisKKyAgLy8gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKK21lc3NhZ2UgRmllbGRPcHRpb25zIHsKKyAgLy8gVGhlIGN0eXBlIG9wdGlvbiBpbnN0cnVjdHMgdGhlIEMrKyBjb2RlIGdlbmVyYXRvciB0byB1c2UgYSBkaWZmZXJlbnQKKyAgLy8gcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpZWxkIHRoYW4gaXQgbm9ybWFsbHkgd291bGQuICBTZWUgdGhlIHNwZWNpZmljCisgIC8vIG9wdGlvbnMgYmVsb3cuICBUaGlzIG9wdGlvbiBpcyBub3QgeWV0IGltcGxlbWVudGVkIGluIHRoZSBvcGVuIHNvdXJjZQorICAvLyByZWxlYXNlIC0tIHNvcnJ5LCB3ZSdsbCB0cnkgdG8gaW5jbHVkZSBpdCBpbiBhIGZ1dHVyZSB2ZXJzaW9uIQorICBvcHRpb25hbCBDVHlwZSBjdHlwZSA9IDEgW2RlZmF1bHQgPSBTVFJJTkddOworICBlbnVtIENUeXBlIHsKKyAgICAvLyBEZWZhdWx0IG1vZGUuCisgICAgU1RSSU5HID0gMDsKKworICAgIENPUkQgPSAxOworCisgICAgU1RSSU5HX1BJRUNFID0gMjsKKyAgfQorICAvLyBUaGUgcGFja2VkIG9wdGlvbiBjYW4gYmUgZW5hYmxlZCBmb3IgcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkcyB0byBlbmFibGUKKyAgLy8gYSBtb3JlIGVmZmljaWVudCByZXByZXNlbnRhdGlvbiBvbiB0aGUgd2lyZS4gUmF0aGVyIHRoYW4gcmVwZWF0ZWRseQorICAvLyB3cml0aW5nIHRoZSB0YWcgYW5kIHR5cGUgZm9yIGVhY2ggZWxlbWVudCwgdGhlIGVudGlyZSBhcnJheSBpcyBlbmNvZGVkIGFzCisgIC8vIGEgc2luZ2xlIGxlbmd0aC1kZWxpbWl0ZWQgYmxvYi4KKyAgb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSAyOworCisKKworICAvLyBTaG91bGQgdGhpcyBmaWVsZCBiZSBwYXJzZWQgbGF6aWx5PyAgTGF6eSBhcHBsaWVzIG9ubHkgdG8gbWVzc2FnZS10eXBlCisgIC8vIGZpZWxkcy4gIEl0IG1lYW5zIHRoYXQgd2hlbiB0aGUgb3V0ZXIgbWVzc2FnZSBpcyBpbml0aWFsbHkgcGFyc2VkLCB0aGUKKyAgLy8gaW5uZXIgbWVzc2FnZSdzIGNvbnRlbnRzIHdpbGwgbm90IGJlIHBhcnNlZCBidXQgaW5zdGVhZCBzdG9yZWQgaW4gZW5jb2RlZAorICAvLyBmb3JtLiAgVGhlIGlubmVyIG1lc3NhZ2Ugd2lsbCBhY3R1YWxseSBiZSBwYXJzZWQgd2hlbiBpdCBpcyBmaXJzdCBhY2Nlc3NlZC4KKyAgLy8KKyAgLy8gVGhpcyBpcyBvbmx5IGEgaGludC4gIEltcGxlbWVudGF0aW9ucyBhcmUgZnJlZSB0byBjaG9vc2Ugd2hldGhlciB0byB1c2UKKyAgLy8gZWFnZXIgb3IgbGF6eSBwYXJzaW5nIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlIG9mIHRoaXMgb3B0aW9uLiAgSG93ZXZlciwKKyAgLy8gc2V0dGluZyB0aGlzIG9wdGlvbiB0cnVlIHN1Z2dlc3RzIHRoYXQgdGhlIHByb3RvY29sIGF1dGhvciBiZWxpZXZlcyB0aGF0CisgIC8vIHVzaW5nIGxhenkgcGFyc2luZyBvbiB0aGlzIGZpZWxkIGlzIHdvcnRoIHRoZSBhZGRpdGlvbmFsIGJvb2trZWVwaW5nCisgIC8vIG92ZXJoZWFkIHR5cGljYWxseSBuZWVkZWQgdG8gaW1wbGVtZW50IGl0LgorICAvLworICAvLyBUaGlzIG9wdGlvbiBkb2VzIG5vdCBhZmZlY3QgdGhlIHB1YmxpYyBpbnRlcmZhY2Ugb2YgYW55IGdlbmVyYXRlZCBjb2RlOworICAvLyBhbGwgbWV0aG9kIHNpZ25hdHVyZXMgcmVtYWluIHRoZSBzYW1lLiAgRnVydGhlcm1vcmUsIHRocmVhZC1zYWZldHkgb2YgdGhlCisgIC8vIGludGVyZmFjZSBpcyBub3QgYWZmZWN0ZWQgYnkgdGhpcyBvcHRpb247IGNvbnN0IG1ldGhvZHMgcmVtYWluIHNhZmUgdG8KKyAgLy8gY2FsbCBmcm9tIG11bHRpcGxlIHRocmVhZHMgY29uY3VycmVudGx5LCB3aGlsZSBub24tY29uc3QgbWV0aG9kcyBjb250aW51ZQorICAvLyB0byByZXF1aXJlIGV4Y2x1c2l2ZSBhY2Nlc3MuCisgIC8vCisgIC8vCisgIC8vIE5vdGUgdGhhdCBpbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gY2hlY2sgcmVxdWlyZWQgZmllbGRzIHdpdGhpbgorICAvLyBhIGxhenkgc3ViLW1lc3NhZ2UuICBUaGF0IGlzLCBjYWxsaW5nIElzSW5pdGlhbGl6ZWQoKSBvbiB0aGUgb3V0aGVyIG1lc3NhZ2UKKyAgLy8gbWF5IHJldHVybiB0cnVlIGV2ZW4gaWYgdGhlIGlubmVyIG1lc3NhZ2UgaGFzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIG90aGVyd2lzZSB0aGUgaW5uZXIgbWVzc2FnZSB3b3VsZCBoYXZlIHRvIGJlCisgIC8vIHBhcnNlZCBpbiBvcmRlciB0byBwZXJmb3JtIHRoZSBjaGVjaywgZGVmZWF0aW5nIHRoZSBwdXJwb3NlIG9mIGxhenkKKyAgLy8gcGFyc2luZy4gIEFuIGltcGxlbWVudGF0aW9uIHdoaWNoIGNob29zZXMgbm90IHRvIGNoZWNrIHJlcXVpcmVkIGZpZWxkcworICAvLyBtdXN0IGJlIGNvbnNpc3RlbnQgYWJvdXQgaXQuICBUaGF0IGlzLCBmb3IgYW55IHBhcnRpY3VsYXIgc3ViLW1lc3NhZ2UsIHRoZQorICAvLyBpbXBsZW1lbnRhdGlvbiBtdXN0IGVpdGhlciAqYWx3YXlzKiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCBvciAqbmV2ZXIqCisgIC8vIGNoZWNrIGl0cyByZXF1aXJlZCBmaWVsZHMsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciBvciBub3QgdGhlIG1lc3NhZ2UgaGFzCisgIC8vIGJlZW4gcGFyc2VkLgorICBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBJcyB0aGlzIGZpZWxkIGRlcHJlY2F0ZWQ/CisgIC8vIERlcGVuZGluZyBvbiB0aGUgdGFyZ2V0IHBsYXRmb3JtLCB0aGlzIGNhbiBlbWl0IERlcHJlY2F0ZWQgYW5ub3RhdGlvbnMKKyAgLy8gZm9yIGFjY2Vzc29ycywgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5IGxlYXN0LCB0aGlzCisgIC8vIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgZmllbGRzLgorICBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBGb3IgR29vZ2xlLWludGVybmFsIG1pZ3JhdGlvbiBvbmx5LiBEbyBub3QgdXNlLgorICBvcHRpb25hbCBib29sIHdlYWsgPSAxMCBbZGVmYXVsdD1mYWxzZV07CisKKworCisgIC8vIFRoZSBwYXJzZXIgc3RvcmVzIG9wdGlvbnMgaXQgZG9lc24ndCByZWNvZ25pemUgaGVyZS4gU2VlIGFib3ZlLgorICByZXBlYXRlZCBVbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworCisgIC8vIENsaWVudHMgY2FuIGRlZmluZSBjdXN0b20gb3B0aW9ucyBpbiBleHRlbnNpb25zIG9mIHRoaXMgbWVzc2FnZS4gU2VlIGFib3ZlLgorICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworfQorCittZXNzYWdlIEVudW1PcHRpb25zIHsKKworICAvLyBTZXQgdGhpcyBvcHRpb24gdG8gdHJ1ZSB0byBhbGxvdyBtYXBwaW5nIGRpZmZlcmVudCB0YWcgbmFtZXMgdG8gdGhlIHNhbWUKKyAgLy8gdmFsdWUuCisgIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworCisgIC8vIElzIHRoaXMgZW51bSBkZXByZWNhdGVkPworICAvLyBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCisgIC8vIGZvciB0aGUgZW51bSwgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5IGxlYXN0LCB0aGlzCisgIC8vIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgZW51bXMuCisgIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIFRoZSBwYXJzZXIgc3RvcmVzIG9wdGlvbnMgaXQgZG9lc24ndCByZWNvZ25pemUgaGVyZS4gU2VlIGFib3ZlLgorICByZXBlYXRlZCBVbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworCisgIC8vIENsaWVudHMgY2FuIGRlZmluZSBjdXN0b20gb3B0aW9ucyBpbiBleHRlbnNpb25zIG9mIHRoaXMgbWVzc2FnZS4gU2VlIGFib3ZlLgorICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworfQorCittZXNzYWdlIEVudW1WYWx1ZU9wdGlvbnMgeworICAvLyBJcyB0aGlzIGVudW0gdmFsdWUgZGVwcmVjYXRlZD8KKyAgLy8gRGVwZW5kaW5nIG9uIHRoZSB0YXJnZXQgcGxhdGZvcm0sIHRoaXMgY2FuIGVtaXQgRGVwcmVjYXRlZCBhbm5vdGF0aW9ucworICAvLyBmb3IgdGhlIGVudW0gdmFsdWUsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwKKyAgLy8gdGhpcyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIGVudW0gdmFsdWVzLgorICBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAxIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBUaGUgcGFyc2VyIHN0b3JlcyBvcHRpb25zIGl0IGRvZXNuJ3QgcmVjb2duaXplIGhlcmUuIFNlZSBhYm92ZS4KKyAgcmVwZWF0ZWQgVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKworICAvLyBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KKworbWVzc2FnZSBTZXJ2aWNlT3B0aW9ucyB7CisKKyAgLy8gTm90ZTogIEZpZWxkIG51bWJlcnMgMSB0aHJvdWdoIDMyIGFyZSByZXNlcnZlZCBmb3IgR29vZ2xlJ3MgaW50ZXJuYWwgUlBDCisgIC8vICAgZnJhbWV3b3JrLiAgV2UgYXBvbG9naXplIGZvciBob2FyZGluZyB0aGVzZSBudW1iZXJzIHRvIG91cnNlbHZlcywgYnV0CisgIC8vICAgd2Ugd2VyZSBhbHJlYWR5IHVzaW5nIHRoZW0gbG9uZyBiZWZvcmUgd2UgZGVjaWRlZCB0byByZWxlYXNlIFByb3RvY29sCisgIC8vICAgQnVmZmVycy4KKworICAvLyBJcyB0aGlzIHNlcnZpY2UgZGVwcmVjYXRlZD8KKyAgLy8gRGVwZW5kaW5nIG9uIHRoZSB0YXJnZXQgcGxhdGZvcm0sIHRoaXMgY2FuIGVtaXQgRGVwcmVjYXRlZCBhbm5vdGF0aW9ucworICAvLyBmb3IgdGhlIHNlcnZpY2UsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwKKyAgLy8gdGhpcyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIHNlcnZpY2VzLgorICBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCisgIHJlcGVhdGVkIFVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisKKyAgLy8gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKK21lc3NhZ2UgTWV0aG9kT3B0aW9ucyB7CisKKyAgLy8gTm90ZTogIEZpZWxkIG51bWJlcnMgMSB0aHJvdWdoIDMyIGFyZSByZXNlcnZlZCBmb3IgR29vZ2xlJ3MgaW50ZXJuYWwgUlBDCisgIC8vICAgZnJhbWV3b3JrLiAgV2UgYXBvbG9naXplIGZvciBob2FyZGluZyB0aGVzZSBudW1iZXJzIHRvIG91cnNlbHZlcywgYnV0CisgIC8vICAgd2Ugd2VyZSBhbHJlYWR5IHVzaW5nIHRoZW0gbG9uZyBiZWZvcmUgd2UgZGVjaWRlZCB0byByZWxlYXNlIFByb3RvY29sCisgIC8vICAgQnVmZmVycy4KKworICAvLyBJcyB0aGlzIG1ldGhvZCBkZXByZWNhdGVkPworICAvLyBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCisgIC8vIGZvciB0aGUgbWV0aG9kLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkgbGVhc3QsCisgIC8vIHRoaXMgaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBtZXRob2RzLgorICBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCisgIHJlcGVhdGVkIFVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisKKyAgLy8gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKKworLy8gQSBtZXNzYWdlIHJlcHJlc2VudGluZyBhIG9wdGlvbiB0aGUgcGFyc2VyIGRvZXMgbm90IHJlY29nbml6ZS4gVGhpcyBvbmx5CisvLyBhcHBlYXJzIGluIG9wdGlvbnMgcHJvdG9zIGNyZWF0ZWQgYnkgdGhlIGNvbXBpbGVyOjpQYXJzZXIgY2xhc3MuCisvLyBEZXNjcmlwdG9yUG9vbCByZXNvbHZlcyB0aGVzZSB3aGVuIGJ1aWxkaW5nIERlc2NyaXB0b3Igb2JqZWN0cy4gVGhlcmVmb3JlLAorLy8gb3B0aW9ucyBwcm90b3MgaW4gZGVzY3JpcHRvciBvYmplY3RzIChlLmcuIHJldHVybmVkIGJ5IERlc2NyaXB0b3I6Om9wdGlvbnMoKSwKKy8vIG9yIHByb2R1Y2VkIGJ5IERlc2NyaXB0b3I6OkNvcHlUbygpKSB3aWxsIG5ldmVyIGhhdmUgVW5pbnRlcnByZXRlZE9wdGlvbnMKKy8vIGluIHRoZW0uCittZXNzYWdlIFVuaW50ZXJwcmV0ZWRPcHRpb24geworICAvLyBUaGUgbmFtZSBvZiB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb24uICBFYWNoIHN0cmluZyByZXByZXNlbnRzIGEgc2VnbWVudCBpbgorICAvLyBhIGRvdC1zZXBhcmF0ZWQgbmFtZS4gIGlzX2V4dGVuc2lvbiBpcyB0cnVlIGlmZiBhIHNlZ21lbnQgcmVwcmVzZW50cyBhbgorICAvLyBleHRlbnNpb24gKGRlbm90ZWQgd2l0aCBwYXJlbnRoZXNlcyBpbiBvcHRpb25zIHNwZWNzIGluIC5wcm90byBmaWxlcykuCisgIC8vIEUuZy4seyBbImZvbyIsIGZhbHNlXSwgWyJiYXIuYmF6IiwgdHJ1ZV0sIFsicXV4IiwgZmFsc2VdIH0gcmVwcmVzZW50cworICAvLyAiZm9vLihiYXIuYmF6KS5xdXgiLgorICBtZXNzYWdlIE5hbWVQYXJ0IHsKKyAgICByZXF1aXJlZCBzdHJpbmcgbmFtZV9wYXJ0ID0gMTsKKyAgICByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CisgIH0KKyAgcmVwZWF0ZWQgTmFtZVBhcnQgbmFtZSA9IDI7CisKKyAgLy8gVGhlIHZhbHVlIG9mIHRoZSB1bmludGVycHJldGVkIG9wdGlvbiwgaW4gd2hhdGV2ZXIgdHlwZSB0aGUgdG9rZW5pemVyCisgIC8vIGlkZW50aWZpZWQgaXQgYXMgZHVyaW5nIHBhcnNpbmcuIEV4YWN0bHkgb25lIG9mIHRoZXNlIHNob3VsZCBiZSBzZXQuCisgIG9wdGlvbmFsIHN0cmluZyBpZGVudGlmaWVyX3ZhbHVlID0gMzsKKyAgb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7CisgIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgIG9wdGlvbmFsIGRvdWJsZSBkb3VibGVfdmFsdWUgPSA2OworICBvcHRpb25hbCBieXRlcyBzdHJpbmdfdmFsdWUgPSA3OworICBvcHRpb25hbCBzdHJpbmcgYWdncmVnYXRlX3ZhbHVlID0gODsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gT3B0aW9uYWwgc291cmNlIGNvZGUgaW5mbworCisvLyBFbmNhcHN1bGF0ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9yaWdpbmFsIHNvdXJjZSBmaWxlIGZyb20gd2hpY2ggYQorLy8gRmlsZURlc2NyaXB0b3JQcm90byB3YXMgZ2VuZXJhdGVkLgorbWVzc2FnZSBTb3VyY2VDb2RlSW5mbyB7CisgIC8vIEEgTG9jYXRpb24gaWRlbnRpZmllcyBhIHBpZWNlIG9mIHNvdXJjZSBjb2RlIGluIGEgLnByb3RvIGZpbGUgd2hpY2gKKyAgLy8gY29ycmVzcG9uZHMgdG8gYSBwYXJ0aWN1bGFyIGRlZmluaXRpb24uICBUaGlzIGluZm9ybWF0aW9uIGlzIGludGVuZGVkCisgIC8vIHRvIGJlIHVzZWZ1bCB0byBJREVzLCBjb2RlIGluZGV4ZXJzLCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcnMsIGFuZCBzaW1pbGFyCisgIC8vIHRvb2xzLgorICAvLworICAvLyBGb3IgZXhhbXBsZSwgc2F5IHdlIGhhdmUgYSBmaWxlIGxpa2U6CisgIC8vICAgbWVzc2FnZSBGb28geworICAvLyAgICAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDE7CisgIC8vICAgfQorICAvLyBMZXQncyBsb29rIGF0IGp1c3QgdGhlIGZpZWxkIGRlZmluaXRpb246CisgIC8vICAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDE7CisgIC8vICAgXiAgICAgICBeXiAgICAgXl4gIF4gIF5eXgorICAvLyAgIGEgICAgICAgYmMgICAgIGRlICBmICBnaGkKKyAgLy8gV2UgaGF2ZSB0aGUgZm9sbG93aW5nIGxvY2F0aW9uczoKKyAgLy8gICBzcGFuICAgcGF0aCAgICAgICAgICAgICAgIHJlcHJlc2VudHMKKyAgLy8gICBbYSxpKSAgWyA0LCAwLCAyLCAwIF0gICAgIFRoZSB3aG9sZSBmaWVsZCBkZWZpbml0aW9uLgorICAvLyAgIFthLGIpICBbIDQsIDAsIDIsIDAsIDQgXSAgVGhlIGxhYmVsIChvcHRpb25hbCkuCisgIC8vICAgW2MsZCkgIFsgNCwgMCwgMiwgMCwgNSBdICBUaGUgdHlwZSAoc3RyaW5nKS4KKyAgLy8gICBbZSxmKSAgWyA0LCAwLCAyLCAwLCAxIF0gIFRoZSBuYW1lIChmb28pLgorICAvLyAgIFtnLGgpICBbIDQsIDAsIDIsIDAsIDMgXSAgVGhlIG51bWJlciAoMSkuCisgIC8vCisgIC8vIE5vdGVzOgorICAvLyAtIEEgbG9jYXRpb24gbWF5IHJlZmVyIHRvIGEgcmVwZWF0ZWQgZmllbGQgaXRzZWxmIChpLmUuIG5vdCB0byBhbnkKKyAgLy8gICBwYXJ0aWN1bGFyIGluZGV4IHdpdGhpbiBpdCkuICBUaGlzIGlzIHVzZWQgd2hlbmV2ZXIgYSBzZXQgb2YgZWxlbWVudHMgYXJlCisgIC8vICAgbG9naWNhbGx5IGVuY2xvc2VkIGluIGEgc2luZ2xlIGNvZGUgc2VnbWVudC4gIEZvciBleGFtcGxlLCBhbiBlbnRpcmUKKyAgLy8gICBleHRlbmQgYmxvY2sgKHBvc3NpYmx5IGNvbnRhaW5pbmcgbXVsdGlwbGUgZXh0ZW5zaW9uIGRlZmluaXRpb25zKSB3aWxsCisgIC8vICAgaGF2ZSBhbiBvdXRlciBsb2NhdGlvbiB3aG9zZSBwYXRoIHJlZmVycyB0byB0aGUgImV4dGVuc2lvbnMiIHJlcGVhdGVkCisgIC8vICAgZmllbGQgd2l0aG91dCBhbiBpbmRleC4KKyAgLy8gLSBNdWx0aXBsZSBsb2NhdGlvbnMgbWF5IGhhdmUgdGhlIHNhbWUgcGF0aC4gIFRoaXMgaGFwcGVucyB3aGVuIGEgc2luZ2xlCisgIC8vICAgbG9naWNhbCBkZWNsYXJhdGlvbiBpcyBzcHJlYWQgb3V0IGFjcm9zcyBtdWx0aXBsZSBwbGFjZXMuICBUaGUgbW9zdAorICAvLyAgIG9idmlvdXMgZXhhbXBsZSBpcyB0aGUgImV4dGVuZCIgYmxvY2sgYWdhaW4gLS0gdGhlcmUgbWF5IGJlIG11bHRpcGxlCisgIC8vICAgZXh0ZW5kIGJsb2NrcyBpbiB0aGUgc2FtZSBzY29wZSwgZWFjaCBvZiB3aGljaCB3aWxsIGhhdmUgdGhlIHNhbWUgcGF0aC4KKyAgLy8gLSBBIGxvY2F0aW9uJ3Mgc3BhbiBpcyBub3QgYWx3YXlzIGEgc3Vic2V0IG9mIGl0cyBwYXJlbnQncyBzcGFuLiAgRm9yCisgIC8vICAgZXhhbXBsZSwgdGhlICJleHRlbmRlZSIgb2YgYW4gZXh0ZW5zaW9uIGRlY2xhcmF0aW9uIGFwcGVhcnMgYXQgdGhlCisgIC8vICAgYmVnaW5uaW5nIG9mIHRoZSAiZXh0ZW5kIiBibG9jayBhbmQgaXMgc2hhcmVkIGJ5IGFsbCBleHRlbnNpb25zIHdpdGhpbgorICAvLyAgIHRoZSBibG9jay4KKyAgLy8gLSBKdXN0IGJlY2F1c2UgYSBsb2NhdGlvbidzIHNwYW4gaXMgYSBzdWJzZXQgb2Ygc29tZSBvdGhlciBsb2NhdGlvbidzIHNwYW4KKyAgLy8gICBkb2VzIG5vdCBtZWFuIHRoYXQgaXQgaXMgYSBkZXNjZW5kZW50LiAgRm9yIGV4YW1wbGUsIGEgImdyb3VwIiBkZWZpbmVzCisgIC8vICAgYm90aCBhIHR5cGUgYW5kIGEgZmllbGQgaW4gYSBzaW5nbGUgZGVjbGFyYXRpb24uICBUaHVzLCB0aGUgbG9jYXRpb25zCisgIC8vICAgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZSBhbmQgZmllbGQgYW5kIHRoZWlyIGNvbXBvbmVudHMgd2lsbCBvdmVybGFwLgorICAvLyAtIENvZGUgd2hpY2ggdHJpZXMgdG8gaW50ZXJwcmV0IGxvY2F0aW9ucyBzaG91bGQgcHJvYmFibHkgYmUgZGVzaWduZWQgdG8KKyAgLy8gICBpZ25vcmUgdGhvc2UgdGhhdCBpdCBkb2Vzbid0IHVuZGVyc3RhbmQsIGFzIG1vcmUgdHlwZXMgb2YgbG9jYXRpb25zIGNvdWxkCisgIC8vICAgYmUgcmVjb3JkZWQgaW4gdGhlIGZ1dHVyZS4KKyAgcmVwZWF0ZWQgTG9jYXRpb24gbG9jYXRpb24gPSAxOworICBtZXNzYWdlIExvY2F0aW9uIHsKKyAgICAvLyBJZGVudGlmaWVzIHdoaWNoIHBhcnQgb2YgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2FzIGRlZmluZWQgYXQgdGhpcworICAgIC8vIGxvY2F0aW9uLgorICAgIC8vCisgICAgLy8gRWFjaCBlbGVtZW50IGlzIGEgZmllbGQgbnVtYmVyIG9yIGFuIGluZGV4LiAgVGhleSBmb3JtIGEgcGF0aCBmcm9tCisgICAgLy8gdGhlIHJvb3QgRmlsZURlc2NyaXB0b3JQcm90byB0byB0aGUgcGxhY2Ugd2hlcmUgdGhlIGRlZmluaXRpb24uICBGb3IKKyAgICAvLyBleGFtcGxlLCB0aGlzIHBhdGg6CisgICAgLy8gICBbIDQsIDMsIDIsIDcsIDEgXQorICAgIC8vIHJlZmVycyB0bzoKKyAgICAvLyAgIGZpbGUubWVzc2FnZV90eXBlKDMpICAvLyA0LCAzCisgICAgLy8gICAgICAgLmZpZWxkKDcpICAgICAgICAgLy8gMiwgNworICAgIC8vICAgICAgIC5uYW1lKCkgICAgICAgICAgIC8vIDEKKyAgICAvLyBUaGlzIGlzIGJlY2F1c2UgRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUgaGFzIGZpZWxkIG51bWJlciA0OgorICAgIC8vICAgcmVwZWF0ZWQgRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CisgICAgLy8gYW5kIERlc2NyaXB0b3JQcm90by5maWVsZCBoYXMgZmllbGQgbnVtYmVyIDI6CisgICAgLy8gICByZXBlYXRlZCBGaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CisgICAgLy8gYW5kIEZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUgaGFzIGZpZWxkIG51bWJlciAxOgorICAgIC8vICAgb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgIC8vCisgICAgLy8gVGh1cywgdGhlIGFib3ZlIHBhdGggZ2l2ZXMgdGhlIGxvY2F0aW9uIG9mIGEgZmllbGQgbmFtZS4gIElmIHdlIHJlbW92ZWQKKyAgICAvLyB0aGUgbGFzdCBlbGVtZW50OgorICAgIC8vICAgWyA0LCAzLCAyLCA3IF0KKyAgICAvLyB0aGlzIHBhdGggcmVmZXJzIHRvIHRoZSB3aG9sZSBmaWVsZCBkZWNsYXJhdGlvbiAoZnJvbSB0aGUgYmVnaW5uaW5nCisgICAgLy8gb2YgdGhlIGxhYmVsIHRvIHRoZSB0ZXJtaW5hdGluZyBzZW1pY29sb24pLgorICAgIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQ9dHJ1ZV07CisKKyAgICAvLyBBbHdheXMgaGFzIGV4YWN0bHkgdGhyZWUgb3IgZm91ciBlbGVtZW50czogc3RhcnQgbGluZSwgc3RhcnQgY29sdW1uLAorICAgIC8vIGVuZCBsaW5lIChvcHRpb25hbCwgb3RoZXJ3aXNlIGFzc3VtZWQgc2FtZSBhcyBzdGFydCBsaW5lKSwgZW5kIGNvbHVtbi4KKyAgICAvLyBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQorICAgIC8vIGFuZCBjb2x1bW4gbnVtYmVycyBhcmUgemVyby1iYXNlZCAtLSB0eXBpY2FsbHkgeW91IHdpbGwgd2FudCB0byBhZGQKKyAgICAvLyAxIHRvIGVhY2ggYmVmb3JlIGRpc3BsYXlpbmcgdG8gYSB1c2VyLgorICAgIHJlcGVhdGVkIGludDMyIHNwYW4gPSAyIFtwYWNrZWQ9dHJ1ZV07CisKKyAgICAvLyBJZiB0aGlzIFNvdXJjZUNvZGVJbmZvIHJlcHJlc2VudHMgYSBjb21wbGV0ZSBkZWNsYXJhdGlvbiwgdGhlc2UgYXJlIGFueQorICAgIC8vIGNvbW1lbnRzIGFwcGVhcmluZyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBkZWNsYXJhdGlvbiB3aGljaCBhcHBlYXIgdG8gYmUKKyAgICAvLyBhdHRhY2hlZCB0byB0aGUgZGVjbGFyYXRpb24uCisgICAgLy8KKyAgICAvLyBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgorICAgIC8vIHRva2VucyBhcHBlYXJpbmcgb24gdGhvc2UgbGluZXMsIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHNpbmdsZSBjb21tZW50LgorICAgIC8vCisgICAgLy8gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyB3aWxsIGtlZXAgcGFyYWdyYXBocyBvZiBjb21tZW50cyB0aGF0IGFwcGVhcgorICAgIC8vIGJlZm9yZSAoYnV0IG5vdCBjb25uZWN0ZWQgdG8pIHRoZSBjdXJyZW50IGVsZW1lbnQuIEVhY2ggcGFyYWdyYXBoLAorICAgIC8vIHNlcGFyYXRlZCBieSBlbXB0eSBsaW5lcywgd2lsbCBiZSBvbmUgY29tbWVudCBlbGVtZW50IGluIHRoZSByZXBlYXRlZAorICAgIC8vIGZpZWxkLgorICAgIC8vCisgICAgLy8gT25seSB0aGUgY29tbWVudCBjb250ZW50IGlzIHByb3ZpZGVkOyBjb21tZW50IG1hcmtlcnMgKGUuZy4gLy8pIGFyZQorICAgIC8vIHN0cmlwcGVkIG91dC4gIEZvciBibG9jayBjb21tZW50cywgbGVhZGluZyB3aGl0ZXNwYWNlIGFuZCBhbiBhc3RlcmlzaworICAgIC8vIHdpbGwgYmUgc3RyaXBwZWQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggbGluZSBvdGhlciB0aGFuIHRoZSBmaXJzdC4KKyAgICAvLyBOZXdsaW5lcyBhcmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dC4KKyAgICAvLworICAgIC8vIEV4YW1wbGVzOgorICAgIC8vCisgICAgLy8gICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCisgICAgLy8gICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGJhci4KKyAgICAvLyAgIG9wdGlvbmFsIGludDMyIGJhciA9IDI7CisgICAgLy8KKyAgICAvLyAgIG9wdGlvbmFsIHN0cmluZyBiYXogPSAzOworICAgIC8vICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBiYXouCisgICAgLy8gICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgorICAgIC8vCisgICAgLy8gICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIHF1eC4KKyAgICAvLyAgIC8vCisgICAgLy8gICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gcXV4LgorICAgIC8vICAgb3B0aW9uYWwgZG91YmxlIHF1eCA9IDQ7CisgICAgLy8KKyAgICAvLyAgIC8vIERldGFjaGVkIGNvbW1lbnQgZm9yIGNvcmdlLiBUaGlzIGlzIG5vdCBsZWFkaW5nIG9yIHRyYWlsaW5nIGNvbW1lbnRzCisgICAgLy8gICAvLyB0byBxdXggb3IgY29yZ2UgYmVjYXVzZSB0aGVyZSBhcmUgYmxhbmsgbGluZXMgc2VwYXJhdGluZyBpdCBmcm9tCisgICAgLy8gICAvLyBib3RoLgorICAgIC8vCisgICAgLy8gICAvLyBEZXRhY2hlZCBjb21tZW50IGZvciBjb3JnZSBwYXJhZ3JhcGggMi4KKyAgICAvLworICAgIC8vICAgb3B0aW9uYWwgc3RyaW5nIGNvcmdlID0gNTsKKyAgICAvLyAgIC8qIEJsb2NrIGNvbW1lbnQgYXR0YWNoZWQKKyAgICAvLyAgICAqIHRvIGNvcmdlLiAgTGVhZGluZyBhc3Rlcmlza3MKKyAgICAvLyAgICAqIHdpbGwgYmUgcmVtb3ZlZC4gKi8KKyAgICAvLyAgIC8qIEJsb2NrIGNvbW1lbnQgYXR0YWNoZWQgdG8KKyAgICAvLyAgICAqIGdyYXVsdC4gKi8KKyAgICAvLyAgIG9wdGlvbmFsIGludDMyIGdyYXVsdCA9IDY7CisgICAgLy8KKyAgICAvLyAgIC8vIGlnbm9yZWQgZGV0YWNoZWQgY29tbWVudHMuCisgICAgb3B0aW9uYWwgc3RyaW5nIGxlYWRpbmdfY29tbWVudHMgPSAzOworICAgIG9wdGlvbmFsIHN0cmluZyB0cmFpbGluZ19jb21tZW50cyA9IDQ7CisgICAgcmVwZWF0ZWQgc3RyaW5nIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgPSA2OworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjExN2MwMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5jYwpAQCAtMCwwICsxLDU0MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuaD4KKworI2luY2x1ZGUgPHNldD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitEZXNjcmlwdG9yRGF0YWJhc2U6On5EZXNjcmlwdG9yRGF0YWJhc2UoKSB7fQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8VmFsdWU+OjpBZGRGaWxlKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZpbGUsCisgICAgVmFsdWUgdmFsdWUpIHsKKyAgaWYgKCFJbnNlcnRJZk5vdFByZXNlbnQoJmJ5X25hbWVfLCBmaWxlLm5hbWUoKSwgdmFsdWUpKSB7CisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkZpbGUgYWxyZWFkeSBleGlzdHMgaW4gZGF0YWJhc2U6ICIgPDwgZmlsZS5uYW1lKCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gV2UgbXVzdCBiZSBjYXJlZnVsIGhlcmUgLS0gY2FsbGluZyBmaWxlLnBhY2thZ2UoKSBpZiBmaWxlLmhhc19wYWNrYWdlKCkgaXMKKyAgLy8gZmFsc2UgY291bGQgYWNjZXNzIGFuIHVuaW5pdGlhbGl6ZWQgc3RhdGljLXN0b3JhZ2UgdmFyaWFibGUgaWYgd2UgYXJlIGJlaW5nCisgIC8vIHJ1biBhdCBzdGFydHVwIHRpbWUuCisgIHN0cmluZyBwYXRoID0gZmlsZS5oYXNfcGFja2FnZSgpID8gZmlsZS5wYWNrYWdlKCkgOiBzdHJpbmcoKTsKKyAgaWYgKCFwYXRoLmVtcHR5KCkpIHBhdGggKz0gJy4nOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS5tZXNzYWdlX3R5cGVfc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoIUFkZFN5bWJvbChwYXRoICsgZmlsZS5tZXNzYWdlX3R5cGUoaSkubmFtZSgpLCB2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICBpZiAoIUFkZE5lc3RlZEV4dGVuc2lvbnMoZmlsZS5tZXNzYWdlX3R5cGUoaSksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS5lbnVtX3R5cGVfc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoIUFkZFN5bWJvbChwYXRoICsgZmlsZS5lbnVtX3R5cGUoaSkubmFtZSgpLCB2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUuZXh0ZW5zaW9uX3NpemUoKTsgaSsrKSB7CisgICAgaWYgKCFBZGRTeW1ib2wocGF0aCArIGZpbGUuZXh0ZW5zaW9uKGkpLm5hbWUoKSwgdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgaWYgKCFBZGRFeHRlbnNpb24oZmlsZS5leHRlbnNpb24oaSksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS5zZXJ2aWNlX3NpemUoKTsgaSsrKSB7CisgICAgaWYgKCFBZGRTeW1ib2wocGF0aCArIGZpbGUuc2VydmljZShpKS5uYW1lKCksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8VmFsdWU+OjpBZGRTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBWYWx1ZSB2YWx1ZSkgeworICAvLyBXZSBuZWVkIHRvIG1ha2Ugc3VyZSBub3QgdG8gdmlvbGF0ZSBvdXIgbWFwIGludmFyaWFudC4KKworICAvLyBJZiB0aGUgc3ltYm9sIG5hbWUgaXMgaW52YWxpZCBpdCBjb3VsZCBicmVhayBvdXIgbG9va3VwIGFsZ29yaXRobSAod2hpY2gKKyAgLy8gcmVsaWVzIG9uIHRoZSBmYWN0IHRoYXQgJy4nIHNvcnRzIGJlZm9yZSBhbGwgb3RoZXIgY2hhcmFjdGVycyB0aGF0IGFyZQorICAvLyB2YWxpZCBpbiBzeW1ib2wgbmFtZXMpLgorICBpZiAoIVZhbGlkYXRlU3ltYm9sTmFtZShuYW1lKSkgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJJbnZhbGlkIHN5bWJvbCBuYW1lOiAiIDw8IG5hbWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gVHJ5IHRvIGxvb2sgdXAgdGhlIHN5bWJvbCB0byBtYWtlIHN1cmUgYSBzdXBlci1zeW1ib2wgZG9lc24ndCBhbHJlYWR5CisgIC8vIGV4aXN0LgorICB0eXBlbmFtZSBtYXA8c3RyaW5nLCBWYWx1ZT46Oml0ZXJhdG9yIGl0ZXIgPSBGaW5kTGFzdExlc3NPckVxdWFsKG5hbWUpOworCisgIGlmIChpdGVyID09IGJ5X3N5bWJvbF8uZW5kKCkpIHsKKyAgICAvLyBBcHBhcmVudGx5IHRoZSBtYXAgaXMgY3VycmVudGx5IGVtcHR5LiAgSnVzdCBpbnNlcnQgYW5kIGJlIGRvbmUgd2l0aCBpdC4KKyAgICBieV9zeW1ib2xfLmluc2VydCh0eXBlbmFtZSBtYXA8c3RyaW5nLCBWYWx1ZT46OnZhbHVlX3R5cGUobmFtZSwgdmFsdWUpKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGlmIChJc1N1YlN5bWJvbChpdGVyLT5maXJzdCwgbmFtZSkpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiU3ltYm9sIG5hbWUgXCIiIDw8IG5hbWUgPDwgIlwiIGNvbmZsaWN0cyB3aXRoIHRoZSBleGlzdGluZyAiCisgICAgICAgICAgICAgICAgICAic3ltYm9sIFwiIiA8PCBpdGVyLT5maXJzdCA8PCAiXCIuIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBPSywgdGhhdCB3b3JrZWQuICBOb3cgd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCBubyBzeW1ib2wgaW4gdGhlIG1hcCBpcworICAvLyBhIHN1Yi1zeW1ib2wgb2YgdGhlIG9uZSB3ZSBhcmUgaW5zZXJ0aW5nLiAgVGhlIG9ubHkgc3ltYm9sIHdoaWNoIGNvdWxkCisgIC8vIGJlIHNvIGlzIHRoZSBmaXJzdCBzeW1ib2wgdGhhdCBpcyBncmVhdGVyIHRoYW4gdGhlIG5ldyBzeW1ib2wuICBTaW5jZQorICAvLyB8aXRlcnwgcG9pbnRzIGF0IHRoZSBsYXN0IHN5bWJvbCB0aGF0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCwgd2UganVzdCBoYXZlCisgIC8vIHRvIGluY3JlbWVudCBpdC4KKyAgKytpdGVyOworCisgIGlmIChpdGVyICE9IGJ5X3N5bWJvbF8uZW5kKCkgJiYgSXNTdWJTeW1ib2wobmFtZSwgaXRlci0+Zmlyc3QpKSB7CisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIlN5bWJvbCBuYW1lIFwiIiA8PCBuYW1lIDw8ICJcIiBjb25mbGljdHMgd2l0aCB0aGUgZXhpc3RpbmcgIgorICAgICAgICAgICAgICAgICAgInN5bWJvbCBcIiIgPDwgaXRlci0+Zmlyc3QgPDwgIlwiLiI7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gT0ssIG5vIGNvbmZsaWN0cy4KKworICAvLyBJbnNlcnQgdGhlIG5ldyBzeW1ib2wgdXNpbmcgdGhlIGl0ZXJhdG9yIGFzIGEgaGludCwgdGhlIG5ldyBlbnRyeSB3aWxsCisgIC8vIGFwcGVhciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIG9uZSB0aGUgaXRlcmF0b3IgaXMgcG9pbnRpbmcgYXQuCisgIGJ5X3N5bWJvbF8uaW5zZXJ0KGl0ZXIsIHR5cGVuYW1lIG1hcDxzdHJpbmcsIFZhbHVlPjo6dmFsdWVfdHlwZShuYW1lLCB2YWx1ZSkpOworCisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+Citib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6QWRkTmVzdGVkRXh0ZW5zaW9ucygKKyAgICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIG1lc3NhZ2VfdHlwZSwKKyAgICBWYWx1ZSB2YWx1ZSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VfdHlwZS5uZXN0ZWRfdHlwZV9zaXplKCk7IGkrKykgeworICAgIGlmICghQWRkTmVzdGVkRXh0ZW5zaW9ucyhtZXNzYWdlX3R5cGUubmVzdGVkX3R5cGUoaSksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlLmV4dGVuc2lvbl9zaXplKCk7IGkrKykgeworICAgIGlmICghQWRkRXh0ZW5zaW9uKG1lc3NhZ2VfdHlwZS5leHRlbnNpb24oaSksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+Citib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6QWRkRXh0ZW5zaW9uKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZCwKKyAgICBWYWx1ZSB2YWx1ZSkgeworICBpZiAoIWZpZWxkLmV4dGVuZGVlKCkuZW1wdHkoKSAmJiBmaWVsZC5leHRlbmRlZSgpWzBdID09ICcuJykgeworICAgIC8vIFRoZSBleHRlbnNpb24gaXMgZnVsbHktcXVhbGlmaWVkLiAgV2UgY2FuIHVzZSBpdCBhcyBhIGxvb2t1cCBrZXkgaW4KKyAgICAvLyB0aGUgYnlfc3ltYm9sXyB0YWJsZS4KKyAgICBpZiAoIUluc2VydElmTm90UHJlc2VudCgKKyAgICAgICAgICAgICZieV9leHRlbnNpb25fLAorICAgICAgICAgICAgc3RkOjptYWtlX3BhaXIoZmllbGQuZXh0ZW5kZWUoKS5zdWJzdHIoMSksIGZpZWxkLm51bWJlcigpKSwKKyAgICAgICAgICAgIHZhbHVlKSkgeworICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkV4dGVuc2lvbiBjb25mbGljdHMgd2l0aCBleHRlbnNpb24gYWxyZWFkeSBpbiBkYXRhYmFzZTogIgorICAgICAgICAgICAgICAgICAgICAiZXh0ZW5kICIgPDwgZmllbGQuZXh0ZW5kZWUoKSA8PCAiIHsgIgorICAgICAgICAgICAgICAgICA8PCBmaWVsZC5uYW1lKCkgPDwgIiA9ICIgPDwgZmllbGQubnVtYmVyKCkgPDwgIiB9IjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gTm90IGZ1bGx5LXF1YWxpZmllZC4gIFdlIGNhbid0IHJlYWxseSBkbyBhbnl0aGluZyBoZXJlLCB1bmZvcnR1bmF0ZWx5LgorICAgIC8vIFdlIGRvbid0IGNvbnNpZGVyIHRoaXMgYW4gZXJyb3IsIHRob3VnaCwgYmVjYXVzZSB0aGUgZGVzY3JpcHRvciBpcworICAgIC8vIHZhbGlkLgorICB9CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+CitWYWx1ZSBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OkZpbmRGaWxlKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuIEZpbmRXaXRoRGVmYXVsdChieV9uYW1lXywgZmlsZW5hbWUsIFZhbHVlKCkpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+CitWYWx1ZSBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OkZpbmRTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIHR5cGVuYW1lIG1hcDxzdHJpbmcsIFZhbHVlPjo6aXRlcmF0b3IgaXRlciA9IEZpbmRMYXN0TGVzc09yRXF1YWwobmFtZSk7CisKKyAgcmV0dXJuIChpdGVyICE9IGJ5X3N5bWJvbF8uZW5kKCkgJiYgSXNTdWJTeW1ib2woaXRlci0+Zmlyc3QsIG5hbWUpKSA/CisgICAgICAgICBpdGVyLT5zZWNvbmQgOiBWYWx1ZSgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+CitWYWx1ZSBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OkZpbmRFeHRlbnNpb24oCisgICAgY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgaW50IGZpZWxkX251bWJlcikgeworICByZXR1cm4gRmluZFdpdGhEZWZhdWx0KAorICAgICAgYnlfZXh0ZW5zaW9uXywgc3RkOjptYWtlX3BhaXIoY29udGFpbmluZ190eXBlLCBmaWVsZF9udW1iZXIpLCBWYWx1ZSgpKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlPgorYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKAorICAgIGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgIHZlY3RvcjxpbnQ+KiBvdXRwdXQpIHsKKyAgdHlwZW5hbWUgbWFwPHBhaXI8c3RyaW5nLCBpbnQ+LCBWYWx1ZT46OmNvbnN0X2l0ZXJhdG9yIGl0ID0KKyAgICAgIGJ5X2V4dGVuc2lvbl8ubG93ZXJfYm91bmQoc3RkOjptYWtlX3BhaXIoY29udGFpbmluZ190eXBlLCAwKSk7CisgIGJvb2wgc3VjY2VzcyA9IGZhbHNlOworCisgIGZvciAoOyBpdCAhPSBieV9leHRlbnNpb25fLmVuZCgpICYmIGl0LT5maXJzdC5maXJzdCA9PSBjb250YWluaW5nX3R5cGU7CisgICAgICAgKytpdCkgeworICAgIG91dHB1dC0+cHVzaF9iYWNrKGl0LT5maXJzdC5zZWNvbmQpOworICAgIHN1Y2Nlc3MgPSB0cnVlOworICB9CisKKyAgcmV0dXJuIHN1Y2Nlc3M7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK3R5cGVuYW1lIG1hcDxzdHJpbmcsIFZhbHVlPjo6aXRlcmF0b3IKK1NpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6RmluZExhc3RMZXNzT3JFcXVhbCgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgLy8gRmluZCB0aGUgbGFzdCBrZXkgaW4gdGhlIG1hcCB3aGljaCBzb3J0cyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlCisgIC8vIHN5bWJvbCBuYW1lLiAgU2luY2UgdXBwZXJfYm91bmQoKSByZXR1cm5zIHRoZSAqZmlyc3QqIGtleSB0aGF0IHNvcnRzCisgIC8vICpncmVhdGVyKiB0aGFuIHRoZSBpbnB1dCwgd2Ugd2FudCB0aGUgZWxlbWVudCBpbW1lZGlhdGVseSBiZWZvcmUgdGhhdC4KKyAgdHlwZW5hbWUgbWFwPHN0cmluZywgVmFsdWU+OjppdGVyYXRvciBpdGVyID0gYnlfc3ltYm9sXy51cHBlcl9ib3VuZChuYW1lKTsKKyAgaWYgKGl0ZXIgIT0gYnlfc3ltYm9sXy5iZWdpbigpKSAtLWl0ZXI7CisgIHJldHVybiBpdGVyOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+Citib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6SXNTdWJTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBzdWJfc3ltYm9sLCBjb25zdCBzdHJpbmcmIHN1cGVyX3N5bWJvbCkgeworICByZXR1cm4gc3ViX3N5bWJvbCA9PSBzdXBlcl9zeW1ib2wgfHwKKyAgICAgICAgIChIYXNQcmVmaXhTdHJpbmcoc3VwZXJfc3ltYm9sLCBzdWJfc3ltYm9sKSAmJgorICAgICAgICAgICAgIHN1cGVyX3N5bWJvbFtzdWJfc3ltYm9sLnNpemUoKV0gPT0gJy4nKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlPgorYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OlZhbGlkYXRlU3ltYm9sTmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lLnNpemUoKTsgaSsrKSB7CisgICAgLy8gSSBkb24ndCB0cnVzdCBjdHlwZS5oIGR1ZSB0byBsb2NhbGVzLiAgOigKKyAgICBpZiAobmFtZVtpXSAhPSAnLicgJiYgbmFtZVtpXSAhPSAnXycgJiYKKyAgICAgICAgKG5hbWVbaV0gPCAnMCcgfHwgbmFtZVtpXSA+ICc5JykgJiYKKyAgICAgICAgKG5hbWVbaV0gPCAnQScgfHwgbmFtZVtpXSA+ICdaJykgJiYKKyAgICAgICAgKG5hbWVbaV0gPCAnYScgfHwgbmFtZVtpXSA+ICd6JykpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UoKSB7fQorU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjp+U2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlKCkgeworICBTVExEZWxldGVFbGVtZW50cygmZmlsZXNfdG9fZGVsZXRlXyk7Cit9CisKK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpBZGQoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvKiBuZXdfZmlsZSA9IG5ldyBGaWxlRGVzY3JpcHRvclByb3RvOworICBuZXdfZmlsZS0+Q29weUZyb20oZmlsZSk7CisgIHJldHVybiBBZGRBbmRPd24obmV3X2ZpbGUpOworfQorCitib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6QWRkQW5kT3duKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUpIHsKKyAgZmlsZXNfdG9fZGVsZXRlXy5wdXNoX2JhY2soZmlsZSk7CisgIHJldHVybiBpbmRleF8uQWRkRmlsZSgqZmlsZSwgZmlsZSk7Cit9CisKK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gTWF5YmVDb3B5KGluZGV4Xy5GaW5kRmlsZShmaWxlbmFtZSksIG91dHB1dCk7Cit9CisKK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgcmV0dXJuIE1heWJlQ29weShpbmRleF8uRmluZFN5bWJvbChzeW1ib2xfbmFtZSksIG91dHB1dCk7Cit9CisKK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oCisgICAgY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgaW50IGZpZWxkX251bWJlciwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgcmV0dXJuIE1heWJlQ29weShpbmRleF8uRmluZEV4dGVuc2lvbihjb250YWluaW5nX3R5cGUsIGZpZWxkX251bWJlciksIG91dHB1dCk7Cit9CisKK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygKKyAgICBjb25zdCBzdHJpbmcmIGV4dGVuZGVlX3R5cGUsCisgICAgdmVjdG9yPGludD4qIG91dHB1dCkgeworICByZXR1cm4gaW5kZXhfLkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGV4dGVuZGVlX3R5cGUsIG91dHB1dCk7Cit9CisKKworYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6Ok1heWJlQ29weShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgaWYgKGZpbGUgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworICBvdXRwdXQtPkNvcHlGcm9tKCpmaWxlKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6RW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CitFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjp+RW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSgpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlc190b19kZWxldGVfLnNpemUoKTsgaSsrKSB7CisgICAgb3BlcmF0b3IgZGVsZXRlKGZpbGVzX3RvX2RlbGV0ZV9baV0pOworICB9Cit9CisKK2Jvb2wgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6QWRkKAorICAgIGNvbnN0IHZvaWQqIGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBpbnQgc2l6ZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgIGlmIChmaWxlLlBhcnNlRnJvbUFycmF5KGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBzaXplKSkgeworICAgIHJldHVybiBpbmRleF8uQWRkRmlsZShmaWxlLCBzdGQ6Om1ha2VfcGFpcihlbmNvZGVkX2ZpbGVfZGVzY3JpcHRvciwgc2l6ZSkpOworICB9IGVsc2UgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJJbnZhbGlkIGZpbGUgZGVzY3JpcHRvciBkYXRhIHBhc3NlZCB0byAiCisgICAgICAgICAgICAgICAgICAiRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6QWRkKCkuIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpBZGRDb3B5KAorICAgIGNvbnN0IHZvaWQqIGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBpbnQgc2l6ZSkgeworICB2b2lkKiBjb3B5ID0gb3BlcmF0b3IgbmV3KHNpemUpOworICBtZW1jcHkoY29weSwgZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIHNpemUpOworICBmaWxlc190b19kZWxldGVfLnB1c2hfYmFjayhjb3B5KTsKKyAgcmV0dXJuIEFkZChjb3B5LCBzaXplKTsKK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gTWF5YmVQYXJzZShpbmRleF8uRmluZEZpbGUoZmlsZW5hbWUpLCBvdXRwdXQpOworfQorCitib29sIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gTWF5YmVQYXJzZShpbmRleF8uRmluZFN5bWJvbChzeW1ib2xfbmFtZSksIG91dHB1dCk7Cit9CisKK2Jvb2wgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6RmluZE5hbWVPZkZpbGVDb250YWluaW5nU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgc3RyaW5nKiBvdXRwdXQpIHsKKyAgcGFpcjxjb25zdCB2b2lkKiwgaW50PiBlbmNvZGVkX2ZpbGUgPSBpbmRleF8uRmluZFN5bWJvbChzeW1ib2xfbmFtZSk7CisgIGlmIChlbmNvZGVkX2ZpbGUuZmlyc3QgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworCisgIC8vIE9wdGltaXphdGlvbjogIFRoZSBuYW1lIHNob3VsZCBiZSB0aGUgZmlyc3QgZmllbGQgaW4gdGhlIGVuY29kZWQgbWVzc2FnZS4KKyAgLy8gICBUcnkgdG8ganVzdCByZWFkIGl0IGRpcmVjdGx5LgorICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZW5jb2RlZF9maWxlLmZpcnN0KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RlZF9maWxlLnNlY29uZCk7CisKKyAgY29uc3QgdWludDMyIGtOYW1lVGFnID0gaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlciwKKyAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisKKyAgaWYgKGlucHV0LlJlYWRUYWcoKSA9PSBrTmFtZVRhZykgeworICAgIC8vIFN1Y2Nlc3MhCisgICAgcmV0dXJuIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygmaW5wdXQsIG91dHB1dCk7CisgIH0gZWxzZSB7CisgICAgLy8gU2xvdyBwYXRoLiAgUGFyc2Ugd2hvbGUgbWVzc2FnZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgaWYgKCFmaWxlX3Byb3RvLlBhcnNlRnJvbUFycmF5KGVuY29kZWRfZmlsZS5maXJzdCwgZW5jb2RlZF9maWxlLnNlY29uZCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgKm91dHB1dCA9IGZpbGVfcHJvdG8ubmFtZSgpOworICAgIHJldHVybiB0cnVlOworICB9Cit9CisKK2Jvb2wgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgIGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgIGludCBmaWVsZF9udW1iZXIsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIHJldHVybiBNYXliZVBhcnNlKGluZGV4Xy5GaW5kRXh0ZW5zaW9uKGNvbnRhaW5pbmdfdHlwZSwgZmllbGRfbnVtYmVyKSwKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0KTsKK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygKKyAgICBjb25zdCBzdHJpbmcmIGV4dGVuZGVlX3R5cGUsCisgICAgdmVjdG9yPGludD4qIG91dHB1dCkgeworICByZXR1cm4gaW5kZXhfLkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGV4dGVuZGVlX3R5cGUsIG91dHB1dCk7Cit9CisKK2Jvb2wgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6TWF5YmVQYXJzZSgKKyAgICBwYWlyPGNvbnN0IHZvaWQqLCBpbnQ+IGVuY29kZWRfZmlsZSwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgaWYgKGVuY29kZWRfZmlsZS5maXJzdCA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiBvdXRwdXQtPlBhcnNlRnJvbUFycmF5KGVuY29kZWRfZmlsZS5maXJzdCwgZW5jb2RlZF9maWxlLnNlY29uZCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworRGVzY3JpcHRvclBvb2xEYXRhYmFzZTo6RGVzY3JpcHRvclBvb2xEYXRhYmFzZShjb25zdCBEZXNjcmlwdG9yUG9vbCYgcG9vbCkKKyAgOiBwb29sXyhwb29sKSB7fQorRGVzY3JpcHRvclBvb2xEYXRhYmFzZTo6fkRlc2NyaXB0b3JQb29sRGF0YWJhc2UoKSB7fQorCitib29sIERlc2NyaXB0b3JQb29sRGF0YWJhc2U6OkZpbmRGaWxlQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbF8uRmluZEZpbGVCeU5hbWUoZmlsZW5hbWUpOworICBpZiAoZmlsZSA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisgIG91dHB1dC0+Q2xlYXIoKTsKKyAgZmlsZS0+Q29weVRvKG91dHB1dCk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIERlc2NyaXB0b3JQb29sRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2xfLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChzeW1ib2xfbmFtZSk7CisgIGlmIChmaWxlID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgb3V0cHV0LT5DbGVhcigpOworICBmaWxlLT5Db3B5VG8ob3V0cHV0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgRGVzY3JpcHRvclBvb2xEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgIGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgIGludCBmaWVsZF9udW1iZXIsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlID0gcG9vbF8uRmluZE1lc3NhZ2VUeXBlQnlOYW1lKGNvbnRhaW5pbmdfdHlwZSk7CisgIGlmIChleHRlbmRlZSA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24gPQorICAgIHBvb2xfLkZpbmRFeHRlbnNpb25CeU51bWJlcihleHRlbmRlZSwgZmllbGRfbnVtYmVyKTsKKyAgaWYgKGV4dGVuc2lvbiA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgb3V0cHV0LT5DbGVhcigpOworICBleHRlbnNpb24tPmZpbGUoKS0+Q29weVRvKG91dHB1dCk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIERlc2NyaXB0b3JQb29sRGF0YWJhc2U6OkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKAorICAgIGNvbnN0IHN0cmluZyYgZXh0ZW5kZWVfdHlwZSwKKyAgICB2ZWN0b3I8aW50Piogb3V0cHV0KSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlID0gcG9vbF8uRmluZE1lc3NhZ2VUeXBlQnlOYW1lKGV4dGVuZGVlX3R5cGUpOworICBpZiAoZXh0ZW5kZWUgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBleHRlbnNpb25zOworICBwb29sXy5GaW5kQWxsRXh0ZW5zaW9ucyhleHRlbmRlZSwgJmV4dGVuc2lvbnMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9ucy5zaXplKCk7ICsraSkgeworICAgIG91dHB1dC0+cHVzaF9iYWNrKGV4dGVuc2lvbnNbaV0tPm51bWJlcigpKTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lcmdlZERlc2NyaXB0b3JEYXRhYmFzZTo6TWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlKAorICAgIERlc2NyaXB0b3JEYXRhYmFzZSogc291cmNlMSwKKyAgICBEZXNjcmlwdG9yRGF0YWJhc2UqIHNvdXJjZTIpIHsKKyAgc291cmNlc18ucHVzaF9iYWNrKHNvdXJjZTEpOworICBzb3VyY2VzXy5wdXNoX2JhY2soc291cmNlMik7Cit9CitNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2U6Ok1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSgKKyAgICBjb25zdCB2ZWN0b3I8RGVzY3JpcHRvckRhdGFiYXNlKj4mIHNvdXJjZXMpCisgIDogc291cmNlc18oc291cmNlcykge30KK01lcmdlZERlc2NyaXB0b3JEYXRhYmFzZTo6fk1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CisKK2Jvb2wgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHNvdXJjZXNfLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKHNvdXJjZXNfW2ldLT5GaW5kRmlsZUJ5TmFtZShmaWxlbmFtZSwgb3V0cHV0KSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHNvdXJjZXNfLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKHNvdXJjZXNfW2ldLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woc3ltYm9sX25hbWUsIG91dHB1dCkpIHsKKyAgICAgIC8vIFRoZSBzeW1ib2wgd2FzIGZvdW5kIGluIHNvdXJjZSBpLiAgSG93ZXZlciwgaWYgb25lIG9mIHRoZSBwcmV2aW91cworICAgICAgLy8gc291cmNlcyBkZWZpbmVzIGEgZmlsZSB3aXRoIHRoZSBzYW1lIG5hbWUgKHdoaWNoIHByZXN1bWFibHkgZG9lc24ndAorICAgICAgLy8gY29udGFpbiB0aGUgc3ltYm9sLCBzaW5jZSBpdCB3YXNuJ3QgZm91bmQgaW4gdGhhdCBzb3VyY2UpLCB0aGVuIHdlCisgICAgICAvLyBtdXN0IGhpZGUgaXQgZnJvbSB0aGUgY2FsbGVyLgorICAgICAgRmlsZURlc2NyaXB0b3JQcm90byB0ZW1wOworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgICAgaWYgKHNvdXJjZXNfW2pdLT5GaW5kRmlsZUJ5TmFtZShvdXRwdXQtPm5hbWUoKSwgJnRlbXApKSB7CisgICAgICAgICAgLy8gRm91bmQgY29uZmxpY3RpbmcgZmlsZSBpbiBhIHByZXZpb3VzIHNvdXJjZS4KKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oCisgICAgY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgaW50IGZpZWxkX251bWJlciwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2VzXy5zaXplKCk7IGkrKykgeworICAgIGlmIChzb3VyY2VzX1tpXS0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZSwgZmllbGRfbnVtYmVyLCBvdXRwdXQpKSB7CisgICAgICAvLyBUaGUgc3ltYm9sIHdhcyBmb3VuZCBpbiBzb3VyY2UgaS4gIEhvd2V2ZXIsIGlmIG9uZSBvZiB0aGUgcHJldmlvdXMKKyAgICAgIC8vIHNvdXJjZXMgZGVmaW5lcyBhIGZpbGUgd2l0aCB0aGUgc2FtZSBuYW1lICh3aGljaCBwcmVzdW1hYmx5IGRvZXNuJ3QKKyAgICAgIC8vIGNvbnRhaW4gdGhlIHN5bWJvbCwgc2luY2UgaXQgd2Fzbid0IGZvdW5kIGluIHRoYXQgc291cmNlKSwgdGhlbiB3ZQorICAgICAgLy8gbXVzdCBoaWRlIGl0IGZyb20gdGhlIGNhbGxlci4KKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gdGVtcDsKKyAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaTsgaisrKSB7CisgICAgICAgIGlmIChzb3VyY2VzX1tqXS0+RmluZEZpbGVCeU5hbWUob3V0cHV0LT5uYW1lKCksICZ0ZW1wKSkgeworICAgICAgICAgIC8vIEZvdW5kIGNvbmZsaWN0aW5nIGZpbGUgaW4gYSBwcmV2aW91cyBzb3VyY2UuCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoCisgICAgY29uc3Qgc3RyaW5nJiBleHRlbmRlZV90eXBlLAorICAgIHZlY3RvcjxpbnQ+KiBvdXRwdXQpIHsKKyAgc2V0PGludD4gbWVyZ2VkX3Jlc3VsdHM7CisgIHZlY3RvcjxpbnQ+IHJlc3VsdHM7CisgIGJvb2wgc3VjY2VzcyA9IGZhbHNlOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgc291cmNlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoc291cmNlc19baV0tPkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGV4dGVuZGVlX3R5cGUsICZyZXN1bHRzKSkgeworICAgICAgc3RkOjpjb3B5KAorICAgICAgICAgIHJlc3VsdHMuYmVnaW4oKSwgcmVzdWx0cy5lbmQoKSwKKyAgICAgICAgICBpbnNlcnRfaXRlcmF0b3I8c2V0PGludD4gPihtZXJnZWRfcmVzdWx0cywgbWVyZ2VkX3Jlc3VsdHMuYmVnaW4oKSkpOworICAgICAgc3VjY2VzcyA9IHRydWU7CisgICAgfQorICAgIHJlc3VsdHMuY2xlYXIoKTsKKyAgfQorCisgIHN0ZDo6Y29weShtZXJnZWRfcmVzdWx0cy5iZWdpbigpLCBtZXJnZWRfcmVzdWx0cy5lbmQoKSwKKyAgICAgICAgICAgIGluc2VydF9pdGVyYXRvcjx2ZWN0b3I8aW50PiA+KCpvdXRwdXQsIG91dHB1dC0+ZW5kKCkpKTsKKworICByZXR1cm4gc3VjY2VzczsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTM0ZTQwMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oCkBAIC0wLDAgKzEsMzY5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gSW50ZXJmYWNlIGZvciBtYW5pcHVsYXRpbmcgZGF0YWJhc2VzIG9mIGRlc2NyaXB0b3JzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SX0RBVEFCQVNFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUl9EQVRBQkFTRV9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBEZXNjcmlwdG9yRGF0YWJhc2U7CitjbGFzcyBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U7CitjbGFzcyBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOworY2xhc3MgRGVzY3JpcHRvclBvb2xEYXRhYmFzZTsKK2NsYXNzIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZTsKKworLy8gQWJzdHJhY3QgaW50ZXJmYWNlIGZvciBhIGRhdGFiYXNlIG9mIGRlc2NyaXB0b3JzLgorLy8KKy8vIFRoaXMgaXMgdXNlZnVsIGlmIHlvdSB3YW50IHRvIGNyZWF0ZSBhIERlc2NyaXB0b3JQb29sIHdoaWNoIGxvYWRzCisvLyBkZXNjcmlwdG9ycyBvbi1kZW1hbmQgZnJvbSBzb21lIHNvcnQgb2YgbGFyZ2UgZGF0YWJhc2UuICBJZiB0aGUgZGF0YWJhc2UKKy8vIGlzIGxhcmdlLCBpdCBtYXkgYmUgaW5lZmZpY2llbnQgdG8gZW51bWVyYXRlIGV2ZXJ5IC5wcm90byBmaWxlIGluc2lkZSBpdAorLy8gY2FsbGluZyBEZXNjcmlwdG9yUG9vbDo6QnVpbGRGaWxlKCkgZm9yIGVhY2ggb25lLiAgSW5zdGVhZCwgYSBEZXNjcmlwdG9yUG9vbAorLy8gY2FuIGJlIGNyZWF0ZWQgd2hpY2ggd3JhcHMgYSBEZXNjcmlwdG9yRGF0YWJhc2UgYW5kIG9ubHkgYnVpbGRzIHBhcnRpY3VsYXIKKy8vIGRlc2NyaXB0b3JzIHdoZW4gdGhleSBhcmUgbmVlZGVkLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgcHVibGljOgorICBpbmxpbmUgRGVzY3JpcHRvckRhdGFiYXNlKCkge30KKyAgdmlydHVhbCB+RGVzY3JpcHRvckRhdGFiYXNlKCk7CisKKyAgLy8gRmluZCBhIGZpbGUgYnkgZmlsZSBuYW1lLiAgRmlsbHMgaW4gaW4gKm91dHB1dCBhbmQgcmV0dXJucyB0cnVlIGlmIGZvdW5kLgorICAvLyBPdGhlcndpc2UsIHJldHVybnMgZmFsc2UsIGxlYXZpbmcgdGhlIGNvbnRlbnRzIG9mICpvdXRwdXQgdW5kZWZpbmVkLgorICB2aXJ0dWFsIGJvb2wgRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgPSAwOworCisgIC8vIEZpbmQgdGhlIGZpbGUgdGhhdCBkZWNsYXJlcyB0aGUgZ2l2ZW4gZnVsbHktcXVhbGlmaWVkIHN5bWJvbCBuYW1lLgorICAvLyBJZiBmb3VuZCwgZmlsbHMgaW4gKm91dHB1dCBhbmQgcmV0dXJucyB0cnVlLCBvdGhlcndpc2UgcmV0dXJucyBmYWxzZQorICAvLyBhbmQgbGVhdmVzICpvdXRwdXQgdW5kZWZpbmVkLgorICB2aXJ0dWFsIGJvb2wgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSA9IDA7CisKKyAgLy8gRmluZCB0aGUgZmlsZSB3aGljaCBkZWZpbmVzIGFuIGV4dGVuc2lvbiBleHRlbmRpbmcgdGhlIGdpdmVuIG1lc3NhZ2UgdHlwZQorICAvLyB3aXRoIHRoZSBnaXZlbiBmaWVsZCBudW1iZXIuICBJZiBmb3VuZCwgZmlsbHMgaW4gKm91dHB1dCBhbmQgcmV0dXJucyB0cnVlLAorICAvLyBvdGhlcndpc2UgcmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzICpvdXRwdXQgdW5kZWZpbmVkLiAgY29udGFpbmluZ190eXBlCisgIC8vIG11c3QgYmUgYSBmdWxseS1xdWFsaWZpZWQgdHlwZSBuYW1lLgorICB2aXJ0dWFsIGJvb2wgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSA9IDA7CisKKyAgLy8gRmluZHMgdGhlIHRhZyBudW1iZXJzIHVzZWQgYnkgYWxsIGtub3duIGV4dGVuc2lvbnMgb2YKKyAgLy8gZXh0ZW5kZWVfdHlwZSwgYW5kIGFwcGVuZHMgdGhlbSB0byBvdXRwdXQgaW4gYW4gdW5kZWZpbmVkCisgIC8vIG9yZGVyLiBUaGlzIG1ldGhvZCBpcyBiZXN0LWVmZm9ydDogaXQncyBub3QgZ3VhcmFudGVlZCB0aGF0IHRoZQorICAvLyBkYXRhYmFzZSB3aWxsIGZpbmQgYWxsIGV4dGVuc2lvbnMsIGFuZCBpdCdzIG5vdCBndWFyYW50ZWVkIHRoYXQKKyAgLy8gRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uIHdpbGwgcmV0dXJuIHRydWUgb24gYWxsIG9mIHRoZSBmb3VuZAorICAvLyBudW1iZXJzLiBSZXR1cm5zIHRydWUgaWYgdGhlIHNlYXJjaCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlCisgIC8vIHJldHVybnMgZmFsc2UgYW5kIGxlYXZlcyBvdXRwdXQgdW5jaGFuZ2VkLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBoYXMgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRoYXQgYWx3YXlzIHJldHVybnMKKyAgLy8gZmFsc2UuCisgIHZpcnR1YWwgYm9vbCBGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycyhjb25zdCBzdHJpbmcmIC8qIGV4dGVuZGVlX3R5cGUgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8aW50PiogLyogb3V0cHV0ICovKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhEZXNjcmlwdG9yRGF0YWJhc2UpOworfTsKKworLy8gQSBEZXNjcmlwdG9yRGF0YWJhc2UgaW50byB3aGljaCB5b3UgY2FuIGluc2VydCBmaWxlcyBtYW51YWxseS4KKy8vCisvLyBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woKSBpcyBmdWxseS1pbXBsZW1lbnRlZC4gIFdoZW4geW91IGFkZCBhIGZpbGUsIGl0cworLy8gc3ltYm9scyB3aWxsIGJlIGluZGV4ZWQgZm9yIHRoaXMgcHVycG9zZS4gIE5vdGUgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24KKy8vIG1heSByZXR1cm4gZmFsc2UgcG9zaXRpdmVzLCBidXQgb25seSBpZiBpdCBpc24ndCBwb3NzaWJsZSBmb3IgdGhlIHN5bWJvbAorLy8gdG8gYmUgZGVmaW5lZCBpbiBhbnkgb3RoZXIgZmlsZS4gIEluIHBhcnRpY3VsYXIsIGlmIGEgZmlsZSBkZWZpbmVzIGEgc3ltYm9sCisvLyAiRm9vIiwgdGhlbiBzZWFyY2hpbmcgZm9yICJGb28uW2FueXRoaW5nXSIgd2lsbCBtYXRjaCB0aGF0IGZpbGUuICBUaGlzIHdheSwKKy8vIHRoZSBkYXRhYmFzZSBkb2VzIG5vdCBuZWVkIHRvIGFnZ3Jlc3NpdmVseSBpbmRleCBhbGwgY2hpbGRyZW4gb2YgYSBzeW1ib2wuCisvLworLy8gRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCkgaXMgbW9zdGx5LWltcGxlbWVudGVkLiAgSXQgd29ya3MgaWYgYW5kIG9ubHkKKy8vIGlmIHRoZSBvcmlnaW5hbCBGaWVsZERlc2NyaXB0b3JQcm90byBkZWZpbmluZyB0aGUgZXh0ZW5zaW9uIGhhcyBhCisvLyBmdWxseS1xdWFsaWZpZWQgdHlwZSBuYW1lIGluIGl0cyAiZXh0ZW5kZWUiIGZpZWxkIChpLmUuIHN0YXJ0cyB3aXRoIGEgJy4nKS4KKy8vIElmIHRoZSBleHRlbmRlZSBpcyBhIHJlbGF0aXZlIG5hbWUsIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSB3aWxsIG5vdAorLy8gYXR0ZW1wdCB0byByZXNvbHZlIHRoZSB0eXBlLCBzbyBpdCB3aWxsIG5vdCBrbm93IHdoYXQgdHlwZSB0aGUgZXh0ZW5zaW9uIGlzCisvLyBleHRlbmRpbmcuICBUaGVyZWZvcmUsIGNhbGxpbmcgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCkgd2l0aCB0aGUKKy8vIGV4dGVuc2lvbidzIGNvbnRhaW5pbmcgdHlwZSB3aWxsIG5ldmVyIGFjdHVhbGx5IGZpbmQgdGhhdCBleHRlbnNpb24uICBOb3RlCisvLyB0aGF0IHRoaXMgaXMgYW4gdW5saWtlbHkgcHJvYmxlbSwgYXMgYWxsIEZpbGVEZXNjcmlwdG9yUHJvdG9zIGNyZWF0ZWQgYnkgdGhlCisvLyBwcm90b2NvbCBjb21waWxlciAoYXMgd2VsbCBhcyBvbmVzIGNyZWF0ZWQgYnkgY2FsbGluZworLy8gRmlsZURlc2NyaXB0b3I6OkNvcHlUbygpKSB3aWxsIGFsd2F5cyB1c2UgZnVsbHktcXVhbGlmaWVkIG5hbWVzIGZvciBhbGwKKy8vIHR5cGVzLiAgWW91IG9ubHkgbmVlZCB0byB3b3JyeSBpZiB5b3UgYXJlIGNvbnN0cnVjdGluZyBGaWxlRGVzY3JpcHRvclByb3RvcworLy8geW91cnNlbGYsIG9yIGFyZSBjYWxsaW5nIGNvbXBpbGVyOjpQYXJzZXIgZGlyZWN0bHkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgcHVibGljOgorICBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UoKTsKKyAgflNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSgpOworCisgIC8vIEFkZHMgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gdGhlIGRhdGFiYXNlLCBtYWtpbmcgYSBjb3B5LiAgVGhlIG9iamVjdAorICAvLyBjYW4gYmUgZGVsZXRlZCBhZnRlciBBZGQoKSByZXR1cm5zLiAgUmV0dXJucyBmYWxzZSBpZiB0aGUgZmlsZSBjb25mbGljdGVkCisgIC8vIHdpdGggYSBmaWxlIGFscmVhZHkgaW4gdGhlIGRhdGFiYXNlLCBpbiB3aGljaCBjYXNlIGFuIGVycm9yIHdpbGwgaGF2ZQorICAvLyBiZWVuIHdyaXR0ZW4gdG8gR09PR0xFX0xPRyhFUlJPUikuCisgIGJvb2wgQWRkKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZpbGUpOworCisgIC8vIEFkZHMgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gdGhlIGRhdGFiYXNlIGFuZCB0YWtlcyBvd25lcnNoaXAgb2YgaXQuCisgIGJvb2wgQWRkQW5kT3duKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUpOworCisgIC8vIGltcGxlbWVudHMgRGVzY3JpcHRvckRhdGFiYXNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycyhjb25zdCBzdHJpbmcmIGV4dGVuZGVlX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4qIG91dHB1dCk7CisKKyBwcml2YXRlOgorICAvLyBTbyB0aGF0IGl0IGNhbiB1c2UgRGVzY3JpcHRvckluZGV4LgorICBmcmllbmQgY2xhc3MgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTsKKworICAvLyBBbiBpbmRleCBtYXBwaW5nIGZpbGUgbmFtZXMsIHN5bWJvbCBuYW1lcywgYW5kIGV4dGVuc2lvbiBudW1iZXJzIHRvCisgIC8vIHNvbWUgc29ydCBvZiB2YWx1ZXMuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KKyAgY2xhc3MgRGVzY3JpcHRvckluZGV4IHsKKyAgIHB1YmxpYzoKKyAgICAvLyBIZWxwZXJzIHRvIHJlY3Vyc2l2ZWx5IGFkZCBwYXJ0aWN1bGFyIGRlc2NyaXB0b3JzIGFuZCBhbGwgdGhlaXIgY29udGVudHMKKyAgICAvLyB0byB0aGUgaW5kZXguCisgICAgYm9vbCBBZGRGaWxlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZpbGUsCisgICAgICAgICAgICAgICAgIFZhbHVlIHZhbHVlKTsKKyAgICBib29sIEFkZFN5bWJvbChjb25zdCBzdHJpbmcmIG5hbWUsIFZhbHVlIHZhbHVlKTsKKyAgICBib29sIEFkZE5lc3RlZEV4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvclByb3RvJiBtZXNzYWdlX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlIHZhbHVlKTsKKyAgICBib29sIEFkZEV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgdmFsdWUpOworCisgICAgVmFsdWUgRmluZEZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisgICAgVmFsdWUgRmluZFN5bWJvbChjb25zdCBzdHJpbmcmIG5hbWUpOworICAgIFZhbHVlIEZpbmRFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsIGludCBmaWVsZF9udW1iZXIpOworICAgIGJvb2wgRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8aW50Piogb3V0cHV0KTsKKworICAgcHJpdmF0ZToKKyAgICBtYXA8c3RyaW5nLCBWYWx1ZT4gYnlfbmFtZV87CisgICAgbWFwPHN0cmluZywgVmFsdWU+IGJ5X3N5bWJvbF87CisgICAgbWFwPHBhaXI8c3RyaW5nLCBpbnQ+LCBWYWx1ZT4gYnlfZXh0ZW5zaW9uXzsKKworICAgIC8vIEludmFyaWFudDogIFRoZSBieV9zeW1ib2xfIG1hcCBkb2VzIG5vdCBjb250YWluIGFueSBzeW1ib2xzIHdoaWNoIGFyZQorICAgIC8vIHByZWZpeGVzIG9mIG90aGVyIHN5bWJvbHMgaW4gdGhlIG1hcC4gIEZvciBleGFtcGxlLCAiZm9vLmJhciIgaXMgYQorICAgIC8vIHByZWZpeCBvZiAiZm9vLmJhci5iYXoiIChidXQgaXMgbm90IGEgcHJlZml4IG9mICJmb28uYmFyYmF6IikuCisgICAgLy8KKyAgICAvLyBUaGlzIGludmFyaWFudCBpcyBpbXBvcnRhbnQgYmVjYXVzZSBpdCBtZWFucyB0aGF0IGdpdmVuIGEgc3ltYm9sIG5hbWUsCisgICAgLy8gd2UgY2FuIGZpbmQgYSBrZXkgaW4gdGhlIG1hcCB3aGljaCBpcyBhIHByZWZpeCBvZiB0aGUgc3ltYm9sIGluIE8obGcgbikKKyAgICAvLyB0aW1lLCBhbmQgd2Uga25vdyB0aGF0IHRoZXJlIGlzIGF0IG1vc3Qgb25lIHN1Y2gga2V5LgorICAgIC8vCisgICAgLy8gVGhlIHByZWZpeCBsb29rdXAgYWxnb3JpdGhtIHdvcmtzIGxpa2Ugc286CisgICAgLy8gMSkgRmluZCB0aGUgbGFzdCBrZXkgaW4gdGhlIG1hcCB3aGljaCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlCisgICAgLy8gICAgc2VhcmNoIGtleS4KKyAgICAvLyAyKSBJZiB0aGUgZm91bmQga2V5IGlzIGEgcHJlZml4IG9mIHRoZSBzZWFyY2gga2V5LCB0aGVuIHJldHVybiBpdC4KKyAgICAvLyAgICBPdGhlcndpc2UsIHRoZXJlIGlzIG5vIG1hdGNoLgorICAgIC8vCisgICAgLy8gSSBhbSBzdXJlIHRoaXMgYWxnb3JpdGhtIGhhcyBiZWVuIGRlc2NyaWJlZCBlbHNld2hlcmUsIGJ1dCBzaW5jZSBJCisgICAgLy8gd2Fzbid0IGFibGUgdG8gZmluZCBpdCBxdWlja2x5IEkgd2lsbCBpbnN0ZWFkIHByb3ZlIHRoYXQgaXQgd29ya3MKKyAgICAvLyBteXNlbGYuICBUaGUga2V5IHRvIHRoZSBhbGdvcml0aG0gaXMgdGhhdCBpZiBhIG1hdGNoIGV4aXN0cywgc3RlcCAoMSkKKyAgICAvLyB3aWxsIGZpbmQgaXQuICBQcm9vZjoKKyAgICAvLyAxKSBEZWZpbmUgdGhlICJzZWFyY2gga2V5IiB0byBiZSB0aGUga2V5IHdlIGFyZSBsb29raW5nIGZvciwgdGhlICJmb3VuZAorICAgIC8vICAgIGtleSIgdG8gYmUgdGhlIGtleSBmb3VuZCBpbiBzdGVwICgxKSwgYW5kIHRoZSAibWF0Y2gga2V5IiB0byBiZSB0aGUKKyAgICAvLyAgICBrZXkgd2hpY2ggYWN0dWFsbHkgbWF0Y2hlcyB0aGUgc2VyYWNoIGtleSAoaS5lLiB0aGUga2V5IHdlJ3JlIHRyeWluZworICAgIC8vICAgIHRvIGZpbmQpLgorICAgIC8vIDIpIFRoZSBmb3VuZCBrZXkgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHNlYXJjaCBrZXkgYnkKKyAgICAvLyAgICBkZWZpbml0aW9uLgorICAgIC8vIDMpIFRoZSBtYXRjaCBrZXkgbXVzdCBhbHNvIGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgc2VhcmNoIGtleQorICAgIC8vICAgIChiZWNhdXNlIGl0IGlzIGEgcHJlZml4KS4KKyAgICAvLyA0KSBUaGUgbWF0Y2gga2V5IGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gdGhlIGZvdW5kIGtleSwgYmVjYXVzZSBpZiBpdAorICAgIC8vICAgIHdlcmUsIHRoZW4gc3RlcCAoMSkgb2YgdGhlIGFsZ29yaXRobSB3b3VsZCBoYXZlIHJldHVybmVkIHRoZSBtYXRjaAorICAgIC8vICAgIGtleSBpbnN0ZWFkIChzaW5jZSBpdCBmaW5kcyB0aGUgKmdyZWF0ZXN0KiBrZXkgd2hpY2ggaXMgbGVzcyB0aGFuIG9yCisgICAgLy8gICAgZXF1YWwgdG8gdGhlIHNlYXJjaCBrZXkpLgorICAgIC8vIDUpIFRoZXJlZm9yZSwgdGhlIGZvdW5kIGtleSBtdXN0IGJlIGJldHdlZW4gdGhlIG1hdGNoIGtleSBhbmQgdGhlIHNlYXJjaAorICAgIC8vICAgIGtleSwgaW5jbHVzaXZlLgorICAgIC8vIDYpIFNpbmNlIHRoZSBzZWFyY2gga2V5IG11c3QgYmUgYSBzdWItc3ltYm9sIG9mIHRoZSBtYXRjaCBrZXksIGlmIGl0IGlzCisgICAgLy8gICAgbm90IGVxdWFsIHRvIHRoZSBtYXRjaCBrZXksIHRoZW4gc2VhcmNoX2tleVttYXRjaF9rZXkuc2l6ZSgpXSBtdXN0CisgICAgLy8gICAgYmUgJy4nLgorICAgIC8vIDcpIFNpbmNlICcuJyBzb3J0cyBiZWZvcmUgYW55IG90aGVyIGNoYXJhY3RlciB0aGF0IGlzIHZhbGlkIGluIGEgc3ltYm9sCisgICAgLy8gICAgbmFtZSwgdGhlbiBpZiB0aGUgZm91bmQga2V5IGlzIG5vdCBlcXVhbCB0byB0aGUgbWF0Y2gga2V5LCB0aGVuCisgICAgLy8gICAgZm91bmRfa2V5W21hdGNoX2tleS5zaXplKCldIG11c3QgYWxzbyBiZSAnLicsIGJlY2F1c2UgYW55IG90aGVyIHZhbHVlCisgICAgLy8gICAgd291bGQgbWFrZSBpdCBzb3J0IGFmdGVyIHRoZSBzZWFyY2gga2V5LgorICAgIC8vIDgpIFRoZXJlZm9yZSwgaWYgdGhlIGZvdW5kIGtleSBpcyBub3QgZXF1YWwgdG8gdGhlIG1hdGNoIGtleSwgdGhlbiB0aGUKKyAgICAvLyAgICBmb3VuZCBrZXkgbXVzdCBiZSBhIHN1Yi1zeW1ib2wgb2YgdGhlIG1hdGNoIGtleS4gIEhvd2V2ZXIsIHRoaXMgd291bGQKKyAgICAvLyAgICBjb250cmFkaWN0IG91ciBtYXAgaW52YXJpYW50IHdoaWNoIHNheXMgdGhhdCBubyBzeW1ib2wgaW4gdGhlIG1hcCBpcworICAgIC8vICAgIGEgc3ViLXN5bWJvbCBvZiBhbnkgb3RoZXIuCisgICAgLy8gOSkgVGhlcmVmb3JlLCB0aGUgZm91bmQga2V5IG11c3QgbWF0Y2ggdGhlIG1hdGNoIGtleS4KKyAgICAvLworICAgIC8vIFRoZSBhYm92ZSBwcm9vZiBhc3N1bWVzIHRoZSBtYXRjaCBrZXkgZXhpc3RzLiAgSW4gdGhlIGNhc2UgdGhhdCB0aGUKKyAgICAvLyBtYXRjaCBrZXkgZG9lcyBub3QgZXhpc3QsIHRoZW4gc3RlcCAoMSkgd2lsbCByZXR1cm4gc29tZSBvdGhlciBzeW1ib2wuCisgICAgLy8gVGhhdCBzeW1ib2wgY2Fubm90IGJlIGEgc3VwZXItc3ltYm9sIG9mIHRoZSBzZWFyY2gga2V5IHNpbmNlIGlmIGl0IHdlcmUsCisgICAgLy8gdGhlbiBpdCB3b3VsZCBiZSBhIG1hdGNoLCBhbmQgd2UncmUgYXNzdW1pbmcgdGhlIG1hdGNoIGtleSBkb2Vzbid0IGV4aXN0LgorICAgIC8vIFRoZXJlZm9yZSwgc3RlcCAyIHdpbGwgY29ycmVjdGx5IHJldHVybiBubyBtYXRjaC4KKworICAgIC8vIEZpbmQgdGhlIGxhc3QgZW50cnkgaW4gdGhlIGJ5X3N5bWJvbF8gbWFwIHdob3NlIGtleSBpcyBsZXNzIHRoYW4gb3IKKyAgICAvLyBlcXVhbCB0byB0aGUgZ2l2ZW4gbmFtZS4KKyAgICB0eXBlbmFtZSBtYXA8c3RyaW5nLCBWYWx1ZT46Oml0ZXJhdG9yIEZpbmRMYXN0TGVzc09yRXF1YWwoCisgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgICAvLyBUcnVlIGlmIGVpdGhlciB0aGUgYXJndW1lbnRzIGFyZSBlcXVhbCBvciBzdXBlcl9zeW1ib2wgaWRlbnRpZmllcyBhCisgICAgLy8gcGFyZW50IHN5bWJvbCBvZiBzdWJfc3ltYm9sIChlLmcuICJmb28uYmFyIiBpcyBhIHBhcmVudCBvZgorICAgIC8vICJmb28uYmFyLmJheiIsIGJ1dCBub3QgYSBwYXJlbnQgb2YgImZvby5iYXJiYXoiKS4KKyAgICBib29sIElzU3ViU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ViX3N5bWJvbCwgY29uc3Qgc3RyaW5nJiBzdXBlcl9zeW1ib2wpOworCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGFuZCBvbmx5IGlmIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBuYW1lIGFyZSBhbHBoYW51bWVyaWNzLAorICAgIC8vIHVuZGVyc2NvcmVzLCBvciBwZXJpb2RzLgorICAgIGJvb2wgVmFsaWRhdGVTeW1ib2xOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSk7CisgIH07CisKKworICBEZXNjcmlwdG9ySW5kZXg8Y29uc3QgRmlsZURlc2NyaXB0b3JQcm90byo+IGluZGV4XzsKKyAgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qPiBmaWxlc190b19kZWxldGVfOworCisgIC8vIElmIGZpbGUgaXMgbm9uLU5VTEwsIGNvcHkgaXQgaW50byAqb3V0cHV0IGFuZCByZXR1cm4gdHJ1ZSwgb3RoZXJ3aXNlCisgIC8vIHJldHVybiBmYWxzZS4KKyAgYm9vbCBNYXliZUNvcHkoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwKKyAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlKTsKK307CisKKy8vIFZlcnkgc2ltaWxhciB0byBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UsIGJ1dCBzdG9yZXMgYWxsIHRoZSBkZXNjcmlwdG9ycworLy8gYXMgcmF3IGJ5dGVzIGFuZCBnZW5lcmFsbHkgdHJpZXMgdG8gdXNlIGFzIGxpdHRsZSBtZW1vcnkgYXMgcG9zc2libGUuCisvLworLy8gVGhlIHNhbWUgY2F2ZWF0cyByZWdhcmRpbmcgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCkgYXBwbHkgYXMgd2l0aAorLy8gU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2UgOiBwdWJsaWMgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyBwdWJsaWM6CisgIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2UoKTsKKyAgfkVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2UoKTsKKworICAvLyBBZGRzIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBkYXRhYmFzZS4gIFRoZSBkZXNjcmlwdG9yIGlzIHByb3ZpZGVkCisgIC8vIGluIGVuY29kZWQgZm9ybS4gIFRoZSBkYXRhYmFzZSBkb2VzIG5vdCBtYWtlIGEgY29weSBvZiB0aGUgYnl0ZXMsIG5vcgorICAvLyBkb2VzIGl0IHRha2Ugb3duZXJzaGlwOyBpdCdzIHVwIHRvIHRoZSBjYWxsZXIgdG8gbWFrZSBzdXJlIHRoZSBieXRlcworICAvLyByZW1haW4gdmFsaWQgZm9yIHRoZSBsaWZlIG9mIHRoZSBkYXRhYmFzZS4gIFJldHVybnMgZmFsc2UgYW5kIGxvZ3MgYW4gZXJyb3IKKyAgLy8gaWYgdGhlIGJ5dGVzIGFyZSBub3QgYSB2YWxpZCBGaWxlRGVzY3JpcHRvclByb3RvIG9yIGlmIHRoZSBmaWxlIGNvbmZsaWN0ZWQKKyAgLy8gd2l0aCBhIGZpbGUgYWxyZWFkeSBpbiB0aGUgZGF0YWJhc2UuCisgIGJvb2wgQWRkKGNvbnN0IHZvaWQqIGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBpbnQgc2l6ZSk7CisKKyAgLy8gTGlrZSBBZGQoKSwgYnV0IG1ha2VzIGEgY29weSBvZiB0aGUgZGF0YSwgc28gdGhhdCB0aGUgY2FsbGVyIGRvZXMgbm90CisgIC8vIG5lZWQgdG8ga2VlcCBpdCBhcm91bmQuCisgIGJvb2wgQWRkQ29weShjb25zdCB2b2lkKiBlbmNvZGVkX2ZpbGVfZGVzY3JpcHRvciwgaW50IHNpemUpOworCisgIC8vIExpa2UgRmluZEZpbGVDb250YWluaW5nU3ltYm9sIGJ1dCByZXR1cm5zIG9ubHkgdGhlIG5hbWUgb2YgdGhlIGZpbGUuCisgIGJvb2wgRmluZE5hbWVPZkZpbGVDb250YWluaW5nU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoY29uc3Qgc3RyaW5nJiBleHRlbmRlZV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQ+KiBvdXRwdXQpOworCisgcHJpdmF0ZToKKyAgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8cGFpcjxjb25zdCB2b2lkKiwgaW50PiA+IGluZGV4XzsKKyAgdmVjdG9yPHZvaWQqPiBmaWxlc190b19kZWxldGVfOworCisgIC8vIElmIGVuY29kZWRfZmlsZS5maXJzdCBpcyBub24tTlVMTCwgcGFyc2UgdGhlIGRhdGEgaW50byAqb3V0cHV0IGFuZCByZXR1cm4KKyAgLy8gdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4KKyAgYm9vbCBNYXliZVBhcnNlKHBhaXI8Y29uc3Qgdm9pZCosIGludD4gZW5jb2RlZF9maWxlLAorICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSk7Cit9OworCisvLyBBIERlc2NyaXB0b3JEYXRhYmFzZSB0aGF0IGZldGNoZXMgZmlsZXMgZnJvbSBhIGdpdmVuIHBvb2wuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGVzY3JpcHRvclBvb2xEYXRhYmFzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2UgeworIHB1YmxpYzoKKyAgRGVzY3JpcHRvclBvb2xEYXRhYmFzZShjb25zdCBEZXNjcmlwdG9yUG9vbCYgcG9vbCk7CisgIH5EZXNjcmlwdG9yUG9vbERhdGFiYXNlKCk7CisKKyAgLy8gaW1wbGVtZW50cyBEZXNjcmlwdG9yRGF0YWJhc2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBGaW5kRmlsZUJ5TmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGNvbnN0IHN0cmluZyYgZXh0ZW5kZWVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8aW50Piogb3V0cHV0KTsKKworIHByaXZhdGU6CisgIGNvbnN0IERlc2NyaXB0b3JQb29sJiBwb29sXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKERlc2NyaXB0b3JQb29sRGF0YWJhc2UpOworfTsKKworLy8gQSBEZXNjcmlwdG9yRGF0YWJhc2UgdGhhdCB3cmFwcyB0d28gb3IgbW9yZSBvdGhlcnMuICBJdCBmaXJzdCBzZWFyY2hlcyB0aGUKKy8vIGZpcnN0IGRhdGFiYXNlIGFuZCwgaWYgdGhhdCBmYWlscywgdHJpZXMgdGhlIHNlY29uZCwgYW5kIHNvIG9uLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2UgeworIHB1YmxpYzoKKyAgLy8gTWVyZ2UganVzdCB0d28gZGF0YWJhc2VzLiAgVGhlIHNvdXJjZXMgcmVtYWluIHByb3BlcnR5IG9mIHRoZSBjYWxsZXIuCisgIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZShEZXNjcmlwdG9yRGF0YWJhc2UqIHNvdXJjZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yRGF0YWJhc2UqIHNvdXJjZTIpOworICAvLyBNZXJnZSBtb3JlIHRoYW4gdHdvIGRhdGFiYXNlcy4gIFRoZSBzb3VyY2VzIHJlbWFpbiBwcm9wZXJ0eSBvZiB0aGUgY2FsbGVyLgorICAvLyBUaGUgdmVjdG9yIG1heSBiZSBkZWxldGVkIGFmdGVyIHRoZSBjb25zdHJ1Y3RvciByZXR1cm5zIGJ1dCB0aGUKKyAgLy8gRGVzY3JpcHRvckRhdGFiYXNlcyBuZWVkIHRvIHN0aWNrIGFyb3VuZC4KKyAgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlKGNvbnN0IHZlY3RvcjxEZXNjcmlwdG9yRGF0YWJhc2UqPiYgc291cmNlcyk7CisgIH5NZXJnZWREZXNjcmlwdG9yRGF0YWJhc2UoKTsKKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIC8vIE1lcmdlcyB0aGUgcmVzdWx0cyBvZiBjYWxsaW5nIGFsbCBkYXRhYmFzZXMuIFJldHVybnMgdHJ1ZSBpZmYgYW55CisgIC8vIG9mIHRoZSBkYXRhYmFzZXMgcmV0dXJuZWQgdHJ1ZS4KKyAgYm9vbCBGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycyhjb25zdCBzdHJpbmcmIGV4dGVuZGVlX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4qIG91dHB1dCk7CisKKworIHByaXZhdGU6CisgIHZlY3RvcjxEZXNjcmlwdG9yRGF0YWJhc2UqPiBzb3VyY2VzXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUl9EQVRBQkFTRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzAzYzQ0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNzQ4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIG1ha2VzIGV4dGVuc2l2ZSB1c2Ugb2YgUkZDIDMwOTIuICA6KQorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworc3RhdGljIHZvaWQgQWRkVG9EYXRhYmFzZShTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UqIGRhdGFiYXNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBmaWxlX3RleHQpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoZmlsZV90ZXh0LCAmZmlsZV9wcm90bykpOworICBkYXRhYmFzZS0+QWRkKGZpbGVfcHJvdG8pOworfQorCitzdGF0aWMgdm9pZCBFeHBlY3RDb250YWluc1R5cGUoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB0eXBlX25hbWUpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by5tZXNzYWdlX3R5cGVfc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAocHJvdG8ubWVzc2FnZV90eXBlKGkpLm5hbWUoKSA9PSB0eXBlX25hbWUpIHJldHVybjsKKyAgfQorICBBRERfRkFJTFVSRSgpIDw8ICJcIiIgPDwgcHJvdG8ubmFtZSgpCisgICAgICAgICAgICAgICAgPDwgIlwiIGRpZCBub3QgY29udGFpbiBleHBlY3RlZCB0eXBlIFwiIgorICAgICAgICAgICAgICAgIDw8IHR5cGVfbmFtZSA8PCAiXCIuIjsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgR1RFU1RfSEFTX1BBUkFNX1RFU1QKKworLy8gU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlLCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlLCBhbmQKKy8vIERlc2NyaXB0b3JQb29sRGF0YWJhc2UgY2FsbCBmb3IgdmVyeSBzaW1pbGFyIHRlc3RzLiAgSW5zdGVhZCBvZiB3cml0aW5nCisvLyB0aHJlZSBuZWFybHktaWRlbnRpY2FsIHNldHMgb2YgdGVzdHMsIHdlIHVzZSBwYXJhbWV0ZXJpemVkIHRlc3RzIHRvIGFwcGx5CisvLyB0aGUgc2FtZSBjb2RlIHRvIGFsbCB0aHJlZS4KKworLy8gVGhlIHBhcmFtZXRlcml6ZWQgdGVzdCBydW5zIGFnYWluc3QgYSBEZXNjcmlwdGFyRGF0YWJhc2VUZXN0Q2FzZS4gIFdlIGhhdmUKKy8vIGltcGxlbWVudGF0aW9ucyBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgY2xhc3NlcyB3ZSB3YW50IHRvIHRlc3QuCitjbGFzcyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSB7CisgcHVibGljOgorICB2aXJ0dWFsIH5EZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSgpIHt9CisKKyAgdmlydHVhbCBEZXNjcmlwdG9yRGF0YWJhc2UqIEdldERhdGFiYXNlKCkgPSAwOworICB2aXJ0dWFsIGJvb2wgQWRkVG9EYXRhYmFzZShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmaWxlKSA9IDA7Cit9OworCisvLyBGYWN0b3J5IGZ1bmN0aW9uIHR5cGUuCit0eXBlZGVmIERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlKiBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZUZhY3RvcnkoKTsKKworLy8gU3BlY2lhbGl6YXRpb24gZm9yIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZS4KK2NsYXNzIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSogTmV3KCkgeworICAgIHJldHVybiBuZXcgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2U7CisgIH0KKworICB2aXJ0dWFsIH5TaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSgpIHt9CisKKyAgdmlydHVhbCBEZXNjcmlwdG9yRGF0YWJhc2UqIEdldERhdGFiYXNlKCkgeworICAgIHJldHVybiAmZGF0YWJhc2VfOworICB9CisgIHZpcnR1YWwgYm9vbCBBZGRUb0RhdGFiYXNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZpbGUpIHsKKyAgICByZXR1cm4gZGF0YWJhc2VfLkFkZChmaWxlKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlIGRhdGFiYXNlXzsKK307CisKKy8vIFNwZWNpYWxpemF0aW9uIGZvciBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlLgorY2xhc3MgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSogTmV3KCkgeworICAgIHJldHVybiBuZXcgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlOworICB9CisKKyAgdmlydHVhbCB+RW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlKCkge30KKworICB2aXJ0dWFsIERlc2NyaXB0b3JEYXRhYmFzZSogR2V0RGF0YWJhc2UoKSB7CisgICAgcmV0dXJuICZkYXRhYmFzZV87CisgIH0KKyAgdmlydHVhbCBib29sIEFkZFRvRGF0YWJhc2UoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSkgeworICAgIHN0cmluZyBkYXRhOworICAgIGZpbGUuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICAgIHJldHVybiBkYXRhYmFzZV8uQWRkQ29weShkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICB9CisKKyBwcml2YXRlOgorICBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlIGRhdGFiYXNlXzsKK307CisKKy8vIFNwZWNpYWxpemF0aW9uIGZvciBEZXNjcmlwdG9yUG9vbERhdGFiYXNlLgorY2xhc3MgRGVzY3JpcHRvclBvb2xEYXRhYmFzZVRlc3RDYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSogTmV3KCkgeworICAgIHJldHVybiBuZXcgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlOworICB9CisKKyAgRGVzY3JpcHRvclBvb2xEYXRhYmFzZVRlc3RDYXNlKCkgOiBkYXRhYmFzZV8ocG9vbF8pIHt9CisgIHZpcnR1YWwgfkRlc2NyaXB0b3JQb29sRGF0YWJhc2VUZXN0Q2FzZSgpIHt9CisKKyAgdmlydHVhbCBEZXNjcmlwdG9yRGF0YWJhc2UqIEdldERhdGFiYXNlKCkgeworICAgIHJldHVybiAmZGF0YWJhc2VfOworICB9CisgIHZpcnR1YWwgYm9vbCBBZGRUb0RhdGFiYXNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZpbGUpIHsKKyAgICByZXR1cm4gcG9vbF8uQnVpbGRGaWxlKGZpbGUpOworICB9CisKKyBwcml2YXRlOgorICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKyAgRGVzY3JpcHRvclBvb2xEYXRhYmFzZSBkYXRhYmFzZV87Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIERlc2NyaXB0b3JEYXRhYmFzZVRlc3QKKyAgICA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0V2l0aFBhcmFtPERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlRmFjdG9yeSo+IHsKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICB0ZXN0X2Nhc2VfLnJlc2V0KEdldFBhcmFtKCkoKSk7CisgICAgZGF0YWJhc2VfID0gdGVzdF9jYXNlXy0+R2V0RGF0YWJhc2UoKTsKKyAgfQorCisgIHZvaWQgQWRkVG9EYXRhYmFzZShjb25zdCBjaGFyKiBmaWxlX2Rlc2NyaXB0b3JfdGV4dCkgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoZmlsZV9kZXNjcmlwdG9yX3RleHQsICZmaWxlX3Byb3RvKSk7CisgICAgRVhQRUNUX1RSVUUodGVzdF9jYXNlXy0+QWRkVG9EYXRhYmFzZShmaWxlX3Byb3RvKSk7CisgIH0KKworICB2b2lkIEFkZFRvRGF0YWJhc2VXaXRoRXJyb3IoY29uc3QgY2hhciogZmlsZV9kZXNjcmlwdG9yX3RleHQpIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfZGVzY3JpcHRvcl90ZXh0LCAmZmlsZV9wcm90bykpOworICAgIEVYUEVDVF9GQUxTRSh0ZXN0X2Nhc2VfLT5BZGRUb0RhdGFiYXNlKGZpbGVfcHJvdG8pKTsKKyAgfQorCisgIHNjb3BlZF9wdHI8RGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2U+IHRlc3RfY2FzZV87CisgIERlc2NyaXB0b3JEYXRhYmFzZSogZGF0YWJhc2VfOworfTsKKworVEVTVF9QKERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIEZpbmRGaWxlQnlOYW1lKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOlwiRm9vXCIgfSIpOworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTpcIkJhclwiIH0iKTsKKworICB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVCeU5hbWUoImZvby5wcm90byIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJGb28iKTsKKyAgfQorCisgIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUJ5TmFtZSgiYmFyLnByb3RvIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkJhciIpOworICB9CisKKyAgeworICAgIC8vIEZhaWxzIHRvIGZpbmQgdW5kZWZpbmVkIGZpbGVzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoZGF0YWJhc2VfLT5GaW5kRmlsZUJ5TmFtZSgiYmF6LnByb3RvIiwgJmZpbGUpKTsKKyAgfQorfQorCitURVNUX1AoRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIiAgZmllbGQgeyBuYW1lOlwicXV4XCIgfSIKKyAgICAiICBuZXN0ZWRfdHlwZSB7IG5hbWU6IFwiR3JhdWx0XCIgfSAiCisgICAgIiAgZW51bV90eXBlIHsgbmFtZTogXCJHYXJwbHlcIiB9ICIKKyAgICAifSAiCisgICAgImVudW1fdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIldhbGRvXCIgIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkZSRURcIiB9ICIKKyAgICAifSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwicGx1Z2hcIiB9ICIKKyAgICAic2VydmljZSB7ICIKKyAgICAiICBuYW1lOiBcIlh5enp5XCIgIgorICAgICIgIG1ldGhvZCB7IG5hbWU6IFwiVGh1ZFwiIH0gIgorICAgICJ9IgorICAgICk7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImNvcmdlXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhclwiIH0iKTsKKworICB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIGZpZWxkcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZvby5xdXgiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIG5lc3RlZCB0eXBlcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZvby5HcmF1bHQiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIG5lc3RlZCBlbnVtcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZvby5HYXJwbHkiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIGVudW0gdHlwZXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJXYWxkbyIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuIGZpbmQgZW51bSB2YWx1ZXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJXYWxkby5GUkVEIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBleHRlbnNpb25zLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgicGx1Z2giLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIHNlcnZpY2VzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiWHl6enkiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIG1ldGhvZHMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJYeXp6eS5UaHVkIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCB0aGluZ3MgaW4gcGFja2FnZXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJjb3JnZS5CYXIiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIEZhaWxzIHRvIGZpbmQgdW5kZWZpbmVkIHN5bWJvbHMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9GQUxTRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiQmF6IiwgJmZpbGUpKTsKKyAgfQorCisgIHsKKyAgICAvLyBOYW1lcyBtdXN0IGJlIGZ1bGx5LXF1YWxpZmllZC4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJCYXIiLCAmZmlsZSkpOworICB9Cit9CisKK1RFU1RfUChEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24pIHsKKyAgQWRkVG9EYXRhYmFzZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkZvb1wiICIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMDAgfSAiCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTpcInF1eFwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6NSAiCisgICAgIiAgICAgICAgICAgICAgZXh0ZW5kZWU6IFwiLkZvb1wiIH0iCisgICAgIn0iKTsKKyAgQWRkVG9EYXRhYmFzZSgKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwiY29yZ2VcIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJCYXJcIiAiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAwIH0gIgorICAgICJ9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImdyYXVsdFwiIGV4dGVuZGVlOiBcIi5Gb29cIiAgICAgICBudW1iZXI6MzIgfSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJnYXJwbHlcIiBleHRlbmRlZTogXCIuY29yZ2UuQmFyXCIgbnVtYmVyOjcwIH0gIgorICAgICJleHRlbnNpb24geyBuYW1lOlwid2FsZG9cIiAgZXh0ZW5kZWU6IFwiQmFyXCIgICAgICAgIG51bWJlcjo1NiB9ICIpOworCisgIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkZvbyIsIDUsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgIH0KKworICB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJGb28iLCAzMiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBleHRlbnNpb25zIGZvciBxdWFsaWZpZWQgdHlwZSBuYW1lcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oImNvcmdlLkJhciIsIDcwLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbid0IGZpbmQgZXh0ZW5zaW9ucyB3aG9zZSBleHRlbmRlZSB3YXMgbm90IGZ1bGx5LXF1YWxpZmllZCBpbiB0aGUKKyAgICAvLyBGaWxlRGVzY3JpcHRvclByb3RvLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJhciIsIDU2LCAmZmlsZSkpOworICAgIEVYUEVDVF9GQUxTRSgKKyAgICAgICAgZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oImNvcmdlLkJhciIsIDU2LCAmZmlsZSkpOworICB9CisKKyAgeworICAgIC8vIENhbid0IGZpbmQgbm9uLWV4aXN0ZW50IGV4dGVuc2lvbiBudW1iZXJzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkZvbyIsIDEyLCAmZmlsZSkpOworICB9CisKKyAgeworICAgIC8vIENhbid0IGZpbmQgZXh0ZW5zaW9ucyBmb3Igbm9uLWV4aXN0ZW50IHR5cGVzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoCisgICAgICAgIGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJOb1N1Y2hUeXBlIiwgNSwgJmZpbGUpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIGV4dGVuc2lvbnMgZm9yIHVucXVhbGlmaWVkIHR5cGUgbmFtZXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9GQUxTRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiQmFyIiwgNzAsICZmaWxlKSk7CisgIH0KK30KKworVEVTVF9QKERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIEZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAwIH0gIgorICAgICIgIGV4dGVuc2lvbiB7IG5hbWU6XCJxdXhcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjUgIgorICAgICIgICAgICAgICAgICAgIGV4dGVuZGVlOiBcIi5Gb29cIiB9IgorICAgICJ9Iik7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImNvcmdlXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiQmFyXCIgIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAwMCB9ICIKKyAgICAifSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJncmF1bHRcIiBleHRlbmRlZTogXCIuRm9vXCIgICAgICAgbnVtYmVyOjMyIH0gIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiZ2FycGx5XCIgZXh0ZW5kZWU6IFwiLmNvcmdlLkJhclwiIG51bWJlcjo3MCB9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcIndhbGRvXCIgIGV4dGVuZGVlOiBcIkJhclwiICAgICAgICBudW1iZXI6NTYgfSAiKTsKKworICB7CisgICAgdmVjdG9yPGludD4gbnVtYmVyczsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJGb28iLCAmbnVtYmVycykpOworICAgIEFTU0VSVF9FUSgyLCBudW1iZXJzLnNpemUoKSk7CisgICAgc3RkOjpzb3J0KG51bWJlcnMuYmVnaW4oKSwgbnVtYmVycy5lbmQoKSk7CisgICAgRVhQRUNUX0VRKDUsIG51bWJlcnNbMF0pOworICAgIEVYUEVDVF9FUSgzMiwgbnVtYmVyc1sxXSk7CisgIH0KKworICB7CisgICAgdmVjdG9yPGludD4gbnVtYmVyczsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJjb3JnZS5CYXIiLCAmbnVtYmVycykpOworICAgIC8vIE5vdGU6IHdvbid0IGZpbmQgZXh0ZW5zaW9uIDU2IGR1ZSB0byB0aGUgbmFtZSBub3QgYmVpbmcgZnVsbHkgcXVhbGlmaWVkLgorICAgIEFTU0VSVF9FUSgxLCBudW1iZXJzLnNpemUoKSk7CisgICAgRVhQRUNUX0VRKDcwLCBudW1iZXJzWzBdKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIGV4dGVuc2lvbnMgZm9yIG5vbi1leGlzdGVudCB0eXBlcy4KKyAgICB2ZWN0b3I8aW50PiBudW1iZXJzOworICAgIEVYUEVDVF9GQUxTRShkYXRhYmFzZV8tPkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJOb1N1Y2hUeXBlIiwgJm51bWJlcnMpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIGV4dGVuc2lvbnMgZm9yIHVucXVhbGlmaWVkIHR5cGVzLgorICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgRVhQRUNUX0ZBTFNFKGRhdGFiYXNlXy0+RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoIkJhciIsICZudW1iZXJzKSk7CisgIH0KK30KKworVEVTVF9QKERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIENvbmZsaWN0aW5nRmlsZUVycm9yKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIn0iKTsKKyAgQWRkVG9EYXRhYmFzZVdpdGhFcnJvcigKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkJhclwiICIKKyAgICAifSIpOworfQorCitURVNUX1AoRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgQ29uZmxpY3RpbmdUeXBlRXJyb3IpIHsKKyAgQWRkVG9EYXRhYmFzZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkZvb1wiICIKKyAgICAifSIpOworICBBZGRUb0RhdGFiYXNlV2l0aEVycm9yKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiRm9vXCIgIgorICAgICJ9Iik7Cit9CisKK1RFU1RfUChEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBDb25mbGljdGluZ0V4dGVuc2lvbkVycm9yKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjo1ICIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiLkZvb1wiIH0iKTsKKyAgQWRkVG9EYXRhYmFzZVdpdGhFcnJvcigKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJiYXJcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjUgIgorICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCIuRm9vXCIgfSIpOworfQorCitJTlNUQU5USUFURV9URVNUX0NBU0VfUChTaW1wbGUsIERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsCisgICAgdGVzdGluZzo6VmFsdWVzKCZTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZTo6TmV3KSk7CitJTlNUQU5USUFURV9URVNUX0NBU0VfUChNZW1vcnlDb25zZXJ2aW5nLCBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LAorICAgIHRlc3Rpbmc6OlZhbHVlcygmRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlOjpOZXcpKTsKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKFBvb2wsIERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsCisgICAgdGVzdGluZzo6VmFsdWVzKCZEZXNjcmlwdG9yUG9vbERhdGFiYXNlVGVzdENhc2U6Ok5ldykpOworCisjZW5kaWYgIC8vIEdURVNUX0hBU19QQVJBTV9URVNUCisKK1RFU1QoRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZUV4dHJhVGVzdCwgRmluZE5hbWVPZkZpbGVDb250YWluaW5nU3ltYm9sKSB7CisgIC8vIENyZWF0ZSB0d28gZmlsZXMsIG9uZSBvZiB3aGljaCBpcyBpbiB0d28gcGFydHMuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTEsIGZpbGUyYSwgZmlsZTJiOworICBmaWxlMS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIGZpbGUxLnNldF9wYWNrYWdlKCJmb28iKTsKKyAgZmlsZTEuYWRkX21lc3NhZ2VfdHlwZSgpLT5zZXRfbmFtZSgiRm9vIik7CisgIGZpbGUyYS5zZXRfbmFtZSgiYmFyLnByb3RvIik7CisgIGZpbGUyYi5zZXRfcGFja2FnZSgiYmFyIik7CisgIGZpbGUyYi5hZGRfbWVzc2FnZV90eXBlKCktPnNldF9uYW1lKCJCYXIiKTsKKworICAvLyBOb3JtYWwgc2VyaWFsaXphdGlvbiBhbGxvd3Mgb3VyIG9wdGltaXphdGlvbiB0byBraWNrIGluLgorICBzdHJpbmcgZGF0YTEgPSBmaWxlMS5TZXJpYWxpemVBc1N0cmluZygpOworCisgIC8vIEZvcmNlIG91dC1vZi1vcmRlciBzZXJpYWxpemF0aW9uIHRvIHRlc3Qgc2xvdyBwYXRoLgorICBzdHJpbmcgZGF0YTIgPSBmaWxlMmIuU2VyaWFsaXplQXNTdHJpbmcoKSArIGZpbGUyYS5TZXJpYWxpemVBc1N0cmluZygpOworCisgIC8vIENyZWF0ZSBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlIGNvbnRhaW5pbmcgYm90aCBmaWxlcy4KKyAgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSBkYjsKKyAgZGIuQWRkKGRhdGExLmRhdGEoKSwgZGF0YTEuc2l6ZSgpKTsKKyAgZGIuQWRkKGRhdGEyLmRhdGEoKSwgZGF0YTIuc2l6ZSgpKTsKKworICAvLyBUZXN0IQorICBzdHJpbmcgZmlsZW5hbWU7CisgIEVYUEVDVF9UUlVFKGRiLkZpbmROYW1lT2ZGaWxlQ29udGFpbmluZ1N5bWJvbCgiZm9vLkZvbyIsICZmaWxlbmFtZSkpOworICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGVuYW1lKTsKKyAgRVhQRUNUX1RSVUUoZGIuRmluZE5hbWVPZkZpbGVDb250YWluaW5nU3ltYm9sKCJmb28uRm9vLkJsYWgiLCAmZmlsZW5hbWUpKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlbmFtZSk7CisgIEVYUEVDVF9UUlVFKGRiLkZpbmROYW1lT2ZGaWxlQ29udGFpbmluZ1N5bWJvbCgiYmFyLkJhciIsICZmaWxlbmFtZSkpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGVuYW1lKTsKKyAgRVhQRUNUX0ZBTFNFKGRiLkZpbmROYW1lT2ZGaWxlQ29udGFpbmluZ1N5bWJvbCgiZm9vIiwgJmZpbGVuYW1lKSk7CisgIEVYUEVDVF9GQUxTRShkYi5GaW5kTmFtZU9mRmlsZUNvbnRhaW5pbmdTeW1ib2woImJhciIsICZmaWxlbmFtZSkpOworICBFWFBFQ1RfRkFMU0UoZGIuRmluZE5hbWVPZkZpbGVDb250YWluaW5nU3ltYm9sKCJiYXouQmF6IiwgJmZpbGVuYW1lKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3QoKQorICAgIDogZm9yd2FyZF9tZXJnZWRfKCZkYXRhYmFzZTFfLCAmZGF0YWJhc2UyXyksCisgICAgICByZXZlcnNlX21lcmdlZF8oJmRhdGFiYXNlMl8sICZkYXRhYmFzZTFfKSB7fQorCisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZTFfLAorICAgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6XCJGb29cIiBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMCB9IH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJmb29fZXh0XCIgZXh0ZW5kZWU6IFwiLkZvb1wiIG51bWJlcjozICIKKyAgICAgICIgICAgICAgICAgICBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSAiKTsKKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZTJfLAorICAgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6XCJCYXJcIiBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMCB9IH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJiYXJfZXh0XCIgZXh0ZW5kZWU6IFwiLkJhclwiIG51bWJlcjo1ICIKKyAgICAgICIgICAgICAgICAgICBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSAiKTsKKworICAgIC8vIGJhei5wcm90byBleGlzdHMgaW4gYm90aCBwb29scywgd2l0aCBkaWZmZXJlbnQgZGVmaW5pdGlvbnMuCisgICAgQWRkVG9EYXRhYmFzZSgmZGF0YWJhc2UxXywKKyAgICAgICJuYW1lOiBcImJhei5wcm90b1wiICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOlwiQmF6XCIgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAgfSB9ICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOlwiRnJvbVBvb2wxXCIgfSAiCisgICAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImJhel9leHRcIiBleHRlbmRlZTogXCIuQmF6XCIgbnVtYmVyOjEyICIKKyAgICAgICIgICAgICAgICAgICBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSAiCisgICAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImRhdGFiYXNlMV9vbmx5X2V4dFwiIGV4dGVuZGVlOiBcIi5CYXpcIiBudW1iZXI6MTMgIgorICAgICAgIiAgICAgICAgICAgIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9ICIpOworICAgIEFkZFRvRGF0YWJhc2UoJmRhdGFiYXNlMl8sCisgICAgICAibmFtZTogXCJiYXoucHJvdG9cIiAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTpcIkJhelwiIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAwIH0gfSAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTpcIkZyb21Qb29sMlwiIH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJiYXpfZXh0XCIgZXh0ZW5kZWU6IFwiLkJhelwiIG51bWJlcjoxMiAiCisgICAgICAiICAgICAgICAgICAgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0gIik7CisgIH0KKworICBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UgZGF0YWJhc2UxXzsKKyAgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlIGRhdGFiYXNlMl87CisKKyAgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlIGZvcndhcmRfbWVyZ2VkXzsKKyAgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlIHJldmVyc2VfbWVyZ2VkXzsKK307CisKK1RFU1RfRihNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBGaW5kRmlsZUJ5TmFtZSkgeworICB7CisgICAgLy8gQ2FuIGZpbmQgZmlsZSB0aGF0IGlzIG9ubHkgaW4gZGF0YWJhc2UxXy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRm9vIik7CisgIH0KKworICB7CisgICAgLy8gQ2FuIGZpbmQgZmlsZSB0aGF0IGlzIG9ubHkgaW4gZGF0YWJhc2UyXy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQnlOYW1lKCJiYXIucHJvdG8iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiQmFyIik7CisgIH0KKworICB7CisgICAgLy8gSW4gZm9yd2FyZF9tZXJnZWRfLCBkYXRhYmFzZTFfJ3MgYmF6LnByb3RvIHRha2VzIHByZWNlZGVuY2UuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUJ5TmFtZSgiYmF6LnByb3RvIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhei5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkZyb21Qb29sMSIpOworICB9CisKKyAgeworICAgIC8vIEluIHJldmVyc2VfbWVyZ2VkXywgZGF0YWJhc2UyXydzIGJhei5wcm90byB0YWtlcyBwcmVjZWRlbmNlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShyZXZlcnNlX21lcmdlZF8uRmluZEZpbGVCeU5hbWUoImJhei5wcm90byIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXoucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJGcm9tUG9vbDIiKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIG5vbi1leGlzdGVudCBmaWxlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQnlOYW1lKCJub19zdWNoLnByb3RvIiwgJmZpbGUpKTsKKyAgfQorfQorCitURVNUX0YoTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKSB7CisgIHsKKyAgICAvLyBDYW4gZmluZCBmaWxlIHRoYXQgaXMgb25seSBpbiBkYXRhYmFzZTFfLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShmb3J3YXJkX21lcmdlZF8uRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRm9vIik7CisgIH0KKworICB7CisgICAgLy8gQ2FuIGZpbmQgZmlsZSB0aGF0IGlzIG9ubHkgaW4gZGF0YWJhc2UyXy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiQmFyIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkJhciIpOworICB9CisKKyAgeworICAgIC8vIEluIGZvcndhcmRfbWVyZ2VkXywgZGF0YWJhc2UxXydzIGJhei5wcm90byB0YWtlcyBwcmVjZWRlbmNlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShmb3J3YXJkX21lcmdlZF8uRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJCYXoiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRnJvbVBvb2wxIik7CisgIH0KKworICB7CisgICAgLy8gSW4gcmV2ZXJzZV9tZXJnZWRfLCBkYXRhYmFzZTJfJ3MgYmF6LnByb3RvIHRha2VzIHByZWNlZGVuY2UuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKHJldmVyc2VfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkJheiIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXoucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJGcm9tUG9vbDIiKTsKKyAgfQorCisgIHsKKyAgICAvLyBGcm9tUG9vbDEgb25seSBzaG93cyB1cCBpbiBmb3J3YXJkX21lcmdlZF8gYmVjYXVzZSBpdCBpcyBtYXNrZWQgYnkKKyAgICAvLyBkYXRhYmFzZTJfJ3MgYmF6LnByb3RvIGluIHJldmVyc2VfbWVyZ2VkXy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiRnJvbVBvb2wxIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRkFMU0UocmV2ZXJzZV9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiRnJvbVBvb2wxIiwgJmZpbGUpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIG5vbi1leGlzdGVudCBzeW1ib2wuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9GQUxTRSgKKyAgICAgIGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIk5vU3VjaFR5cGUiLCAmZmlsZSkpOworICB9Cit9CisKK1RFU1RfRihNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24pIHsKKyAgeworICAgIC8vIENhbiBmaW5kIGZpbGUgdGhhdCBpcyBvbmx5IGluIGRhdGFiYXNlMV8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKAorICAgICAgZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiRm9vIiwgMywgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkZvbyIpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIGZpbGUgdGhhdCBpcyBvbmx5IGluIGRhdGFiYXNlMl8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKAorICAgICAgZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiQmFyIiwgNSwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkJhciIpOworICB9CisKKyAgeworICAgIC8vIEluIGZvcndhcmRfbWVyZ2VkXywgZGF0YWJhc2UxXydzIGJhei5wcm90byB0YWtlcyBwcmVjZWRlbmNlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRSgKKyAgICAgIGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJheiIsIDEyLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRnJvbVBvb2wxIik7CisgIH0KKworICB7CisgICAgLy8gSW4gcmV2ZXJzZV9tZXJnZWRfLCBkYXRhYmFzZTJfJ3MgYmF6LnByb3RvIHRha2VzIHByZWNlZGVuY2UuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKAorICAgICAgcmV2ZXJzZV9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiQmF6IiwgMTIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXoucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJGcm9tUG9vbDIiKTsKKyAgfQorCisgIHsKKyAgICAvLyBCYXoncyBleHRlbnNpb24gMTMgb25seSBzaG93cyB1cCBpbiBmb3J3YXJkX21lcmdlZF8gYmVjYXVzZSBpdCBpcworICAgIC8vIG1hc2tlZCBieSBkYXRhYmFzZTJfJ3MgYmF6LnByb3RvIGluIHJldmVyc2VfbWVyZ2VkXy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiQmF6IiwgMTMsICZmaWxlKSk7CisgICAgRVhQRUNUX0ZBTFNFKHJldmVyc2VfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJheiIsIDEzLCAmZmlsZSkpOworICB9CisKKyAgeworICAgIC8vIENhbid0IGZpbmQgbm9uLWV4aXN0ZW50IGV4dGVuc2lvbi4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKAorICAgICAgZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiRm9vIiwgNiwgJmZpbGUpKTsKKyAgfQorfQorCitURVNUX0YoTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgRmluZEFsbEV4dGVuc2lvbk51bWJlcnMpIHsKKyAgeworICAgIC8vIE1lc3NhZ2Ugb25seSBoYXMgZXh0ZW5zaW9uIGluIGRhdGFiYXNlMV8KKyAgICB2ZWN0b3I8aW50PiBudW1iZXJzOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygiRm9vIiwgJm51bWJlcnMpKTsKKyAgICBBU1NFUlRfRVEoMSwgbnVtYmVycy5zaXplKCkpOworICAgIEVYUEVDVF9FUSgzLCBudW1iZXJzWzBdKTsKKyAgfQorCisgIHsKKyAgICAvLyBNZXNzYWdlIG9ubHkgaGFzIGV4dGVuc2lvbiBpbiBkYXRhYmFzZTJfCisgICAgdmVjdG9yPGludD4gbnVtYmVyczsKKyAgICBFWFBFQ1RfVFJVRShmb3J3YXJkX21lcmdlZF8uRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoIkJhciIsICZudW1iZXJzKSk7CisgICAgQVNTRVJUX0VRKDEsIG51bWJlcnMuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfRVEoNSwgbnVtYmVyc1swXSk7CisgIH0KKworICB7CisgICAgLy8gTWVyZ2UgcmVzdWx0cyBmcm9tIHRoZSB0d28gZGF0YWJhc2VzLgorICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJCYXoiLCAmbnVtYmVycykpOworICAgIEFTU0VSVF9FUSgyLCBudW1iZXJzLnNpemUoKSk7CisgICAgc3RkOjpzb3J0KG51bWJlcnMuYmVnaW4oKSwgbnVtYmVycy5lbmQoKSk7CisgICAgRVhQRUNUX0VRKDEyLCBudW1iZXJzWzBdKTsKKyAgICBFWFBFQ1RfRVEoMTMsIG51bWJlcnNbMV0pOworICB9CisKKyAgeworICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgRVhQRUNUX1RSVUUocmV2ZXJzZV9tZXJnZWRfLkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJCYXoiLCAmbnVtYmVycykpOworICAgIEFTU0VSVF9FUSgyLCBudW1iZXJzLnNpemUoKSk7CisgICAgc3RkOjpzb3J0KG51bWJlcnMuYmVnaW4oKSwgbnVtYmVycy5lbmQoKSk7CisgICAgRVhQRUNUX0VRKDEyLCBudW1iZXJzWzBdKTsKKyAgICBFWFBFQ1RfRVEoMTMsIG51bWJlcnNbMV0pOworICB9CisKKyAgeworICAgIC8vIENhbid0IGZpbmQgZXh0ZW5zaW9ucyBmb3IgYSBub24tZXhpc3RlbnQgbWVzc2FnZS4KKyAgICB2ZWN0b3I8aW50PiBudW1iZXJzOworICAgIEVYUEVDVF9GQUxTRShyZXZlcnNlX21lcmdlZF8uRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoIkJsYWgiLCAmbnVtYmVycykpOworICB9Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkY2UzZDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw2MTI0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIG1ha2VzIGV4dGVuc2l2ZSB1c2Ugb2YgUkZDIDMwOTIuICA6KQorCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gQ2FuJ3QgdXNlIGFuIGFub255bW91cyBuYW1lc3BhY2UgaGVyZSBkdWUgdG8gYnJva2VubmVzcyBvZiBUcnU2NCBjb21waWxlci4KK25hbWVzcGFjZSBkZXNjcmlwdG9yX3VuaXR0ZXN0IHsKKworLy8gU29tZSBoZWxwZXJzIHRvIG1ha2UgYXNzZW1ibGluZyBkZXNjcmlwdG9ycyBmYXN0ZXIuCitEZXNjcmlwdG9yUHJvdG8qIEFkZE1lc3NhZ2UoRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIERlc2NyaXB0b3JQcm90byogcmVzdWx0ID0gZmlsZS0+YWRkX21lc3NhZ2VfdHlwZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitEZXNjcmlwdG9yUHJvdG8qIEFkZE5lc3RlZE1lc3NhZ2UoRGVzY3JpcHRvclByb3RvKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBEZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHBhcmVudC0+YWRkX25lc3RlZF90eXBlKCk7CisgIHJlc3VsdC0+c2V0X25hbWUobmFtZSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK0VudW1EZXNjcmlwdG9yUHJvdG8qIEFkZEVudW0oRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEVudW1EZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IGZpbGUtPmFkZF9lbnVtX3R5cGUoKTsKKyAgcmVzdWx0LT5zZXRfbmFtZShuYW1lKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRW51bURlc2NyaXB0b3JQcm90byogQWRkTmVzdGVkRW51bShEZXNjcmlwdG9yUHJvdG8qIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEVudW1EZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHBhcmVudC0+YWRkX2VudW1fdHlwZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBBZGRTZXJ2aWNlKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBmaWxlLT5hZGRfc2VydmljZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitGaWVsZERlc2NyaXB0b3JQcm90byogQWRkRmllbGQoRGVzY3JpcHRvclByb3RvKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMYWJlbCBsYWJlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZSB0eXBlKSB7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBwYXJlbnQtPmFkZF9maWVsZCgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXN1bHQtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgcmVzdWx0LT5zZXRfbGFiZWwobGFiZWwpOworICByZXN1bHQtPnNldF90eXBlKHR5cGUpOworICByZXR1cm4gcmVzdWx0OworfQorCitGaWVsZERlc2NyaXB0b3JQcm90byogQWRkRXh0ZW5zaW9uKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZXh0ZW5kZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsIGxhYmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZSB0eXBlKSB7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBmaWxlLT5hZGRfZXh0ZW5zaW9uKCk7CisgIHJlc3VsdC0+c2V0X25hbWUobmFtZSk7CisgIHJlc3VsdC0+c2V0X251bWJlcihudW1iZXIpOworICByZXN1bHQtPnNldF9sYWJlbChsYWJlbCk7CisgIHJlc3VsdC0+c2V0X3R5cGUodHlwZSk7CisgIHJlc3VsdC0+c2V0X2V4dGVuZGVlKGV4dGVuZGVlKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRmllbGREZXNjcmlwdG9yUHJvdG8qIEFkZE5lc3RlZEV4dGVuc2lvbihEZXNjcmlwdG9yUHJvdG8qIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBleHRlbmRlZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWwgbGFiZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlIHR5cGUpIHsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHBhcmVudC0+YWRkX2V4dGVuc2lvbigpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXN1bHQtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgcmVzdWx0LT5zZXRfbGFiZWwobGFiZWwpOworICByZXN1bHQtPnNldF90eXBlKHR5cGUpOworICByZXN1bHQtPnNldF9leHRlbmRlZShleHRlbmRlZSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK0Rlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIEFkZEV4dGVuc2lvblJhbmdlKERlc2NyaXB0b3JQcm90byogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIHJlc3VsdCA9IHBhcmVudC0+YWRkX2V4dGVuc2lvbl9yYW5nZSgpOworICByZXN1bHQtPnNldF9zdGFydChzdGFydCk7CisgIHJlc3VsdC0+c2V0X2VuZChlbmQpOworICByZXR1cm4gcmVzdWx0OworfQorCitFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIEFkZEVudW1WYWx1ZShFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3Byb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbnVtYmVyKSB7CisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogcmVzdWx0ID0gZW51bV9wcm90by0+YWRkX3ZhbHVlKCk7CisgIHJlc3VsdC0+c2V0X25hbWUobmFtZSk7CisgIHJlc3VsdC0+c2V0X251bWJlcihudW1iZXIpOworICByZXR1cm4gcmVzdWx0OworfQorCitNZXRob2REZXNjcmlwdG9yUHJvdG8qIEFkZE1ldGhvZChTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBpbnB1dF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBvdXRwdXRfdHlwZSkgeworICBNZXRob2REZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHNlcnZpY2UtPmFkZF9tZXRob2QoKTsKKyAgcmVzdWx0LT5zZXRfbmFtZShuYW1lKTsKKyAgcmVzdWx0LT5zZXRfaW5wdXRfdHlwZShpbnB1dF90eXBlKTsKKyAgcmVzdWx0LT5zZXRfb3V0cHV0X3R5cGUob3V0cHV0X3R5cGUpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBFbXB0eSBlbnVtcyB0ZWNobmljYWxseSBhcmVuJ3QgYWxsb3dlZC4gIFdlIG5lZWQgdG8gaW5zZXJ0IGEgZHVtbXkgdmFsdWUKKy8vIGludG8gdGhlbS4KK3ZvaWQgQWRkRW1wdHlFbnVtKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBBZGRFbnVtVmFsdWUoQWRkRW51bShmaWxlLCBuYW1lKSwgbmFtZSArICJfRFVNTVkiLCAxKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUZXN0IHNpbXBsZSBmaWxlcy4KK2NsYXNzIEZpbGVEZXNjcmlwdG9yVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICAvLyBCdWlsZCBkZXNjcmlwdG9ycyBmb3IgdGhlIGZvbGxvd2luZyBkZWZpbml0aW9uczoKKyAgICAvLworICAgIC8vICAgLy8gaW4gImZvby5wcm90byIKKyAgICAvLyAgIG1lc3NhZ2UgRm9vTWVzc2FnZSB7IGV4dGVuc2lvbnMgMTsgfQorICAgIC8vICAgZW51bSBGb29FbnVtIHtGT09fRU5VTV9WQUxVRSA9IDE7fQorICAgIC8vICAgc2VydmljZSBGb29TZXJ2aWNlIHt9CisgICAgLy8gICBleHRlbmQgRm9vTWVzc2FnZSB7IG9wdGlvbmFsIGludDMyIGZvb19leHRlbnNpb24gPSAxOyB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJiYXIucHJvdG8iCisgICAgLy8gICBwYWNrYWdlIGJhcl9wYWNrYWdlOworICAgIC8vICAgbWVzc2FnZSBCYXJNZXNzYWdlIHsgZXh0ZW5zaW9ucyAxOyB9CisgICAgLy8gICBlbnVtIEJhckVudW0ge0JBUl9FTlVNX1ZBTFVFID0gMTt9CisgICAgLy8gICBzZXJ2aWNlIEJhclNlcnZpY2Uge30KKyAgICAvLyAgIGV4dGVuZCBCYXJNZXNzYWdlIHsgb3B0aW9uYWwgaW50MzIgYmFyX2V4dGVuc2lvbiA9IDE7IH0KKyAgICAvLworICAgIC8vIEFsc28sIHdlIGhhdmUgYW4gZW1wdHkgZmlsZSAiYmF6LnByb3RvIi4gIFRoaXMgZmlsZSdzIHB1cnBvc2UgaXMgdG8KKyAgICAvLyBtYWtlIHN1cmUgdGhhdCBldmVuIHRob3VnaCBpdCBoYXMgdGhlIHNhbWUgcGFja2FnZSBhcyBmb28ucHJvdG8sCisgICAgLy8gc2VhcmNoaW5nIGl0IGZvciBtZW1iZXJzIG9mIGZvby5wcm90byB3b24ndCB3b3JrLgorCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fZmlsZTsKKyAgICBmb29fZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgICAgQWRkRXh0ZW5zaW9uUmFuZ2UoQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJGb29NZXNzYWdlIiksIDEsIDIpOworICAgIEFkZEVudW1WYWx1ZShBZGRFbnVtKCZmb29fZmlsZSwgIkZvb0VudW0iKSwgIkZPT19FTlVNX1ZBTFVFIiwgMSk7CisgICAgQWRkU2VydmljZSgmZm9vX2ZpbGUsICJGb29TZXJ2aWNlIik7CisgICAgQWRkRXh0ZW5zaW9uKCZmb29fZmlsZSwgIkZvb01lc3NhZ2UiLCAiZm9vX2V4dGVuc2lvbiIsIDEsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBiYXJfZmlsZTsKKyAgICBiYXJfZmlsZS5zZXRfbmFtZSgiYmFyLnByb3RvIik7CisgICAgYmFyX2ZpbGUuc2V0X3BhY2thZ2UoImJhcl9wYWNrYWdlIik7CisgICAgYmFyX2ZpbGUuYWRkX2RlcGVuZGVuY3koImZvby5wcm90byIpOworICAgIEFkZEV4dGVuc2lvblJhbmdlKEFkZE1lc3NhZ2UoJmJhcl9maWxlLCAiQmFyTWVzc2FnZSIpLCAxLCAyKTsKKyAgICBBZGRFbnVtVmFsdWUoQWRkRW51bSgmYmFyX2ZpbGUsICJCYXJFbnVtIiksICJCQVJfRU5VTV9WQUxVRSIsIDEpOworICAgIEFkZFNlcnZpY2UoJmJhcl9maWxlLCAiQmFyU2VydmljZSIpOworICAgIEFkZEV4dGVuc2lvbigmYmFyX2ZpbGUsICJiYXJfcGFja2FnZS5CYXJNZXNzYWdlIiwgImJhcl9leHRlbnNpb24iLCAxLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmF6X2ZpbGU7CisgICAgYmF6X2ZpbGUuc2V0X25hbWUoImJhei5wcm90byIpOworCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIGZvb19maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmb29fZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmFyX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhcl9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBiYXpfZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoYmF6X2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGJhel9maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBmb29fbWVzc2FnZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgZm9vX2VudW1fID0gZm9vX2ZpbGVfLT5lbnVtX3R5cGUoMCk7CisgICAgQVNTRVJUX0VRKDEsIGZvb19lbnVtXy0+dmFsdWVfY291bnQoKSk7CisgICAgZm9vX2VudW1fdmFsdWVfID0gZm9vX2VudW1fLT52YWx1ZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5zZXJ2aWNlX2NvdW50KCkpOworICAgIGZvb19zZXJ2aWNlXyA9IGZvb19maWxlXy0+c2VydmljZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5leHRlbnNpb25fY291bnQoKSk7CisgICAgZm9vX2V4dGVuc2lvbl8gPSBmb29fZmlsZV8tPmV4dGVuc2lvbigwKTsKKworICAgIEFTU0VSVF9FUSgxLCBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBiYXJfbWVzc2FnZV8gPSBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgYmFyX2VudW1fID0gYmFyX2ZpbGVfLT5lbnVtX3R5cGUoMCk7CisgICAgQVNTRVJUX0VRKDEsIGJhcl9lbnVtXy0+dmFsdWVfY291bnQoKSk7CisgICAgYmFyX2VudW1fdmFsdWVfID0gYmFyX2VudW1fLT52YWx1ZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5zZXJ2aWNlX2NvdW50KCkpOworICAgIGJhcl9zZXJ2aWNlXyA9IGJhcl9maWxlXy0+c2VydmljZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5leHRlbnNpb25fY291bnQoKSk7CisgICAgYmFyX2V4dGVuc2lvbl8gPSBiYXJfZmlsZV8tPmV4dGVuc2lvbigwKTsKKyAgfQorCisgIERlc2NyaXB0b3JQb29sIHBvb2xfOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb29fZmlsZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXJfZmlsZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXpfZmlsZV87CisKKyAgY29uc3QgRGVzY3JpcHRvciogICAgICAgICAgZm9vX21lc3NhZ2VfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogICAgICBmb29fZW51bV87CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGZvb19lbnVtX3ZhbHVlXzsKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqICAgZm9vX3NlcnZpY2VfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqICAgICBmb29fZXh0ZW5zaW9uXzsKKworICBjb25zdCBEZXNjcmlwdG9yKiAgICAgICAgICBiYXJfbWVzc2FnZV87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiAgICAgIGJhcl9lbnVtXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYmFyX2VudW1fdmFsdWVfOworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogICBiYXJfc2VydmljZV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogICAgIGJhcl9leHRlbnNpb25fOworfTsKKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgTmFtZSkgeworICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZvb19maWxlXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBiYXJfZmlsZV8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgYmF6X2ZpbGVfLT5uYW1lKCkpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBQYWNrYWdlKSB7CisgIEVYUEVDVF9FUSgiIiwgZm9vX2ZpbGVfLT5wYWNrYWdlKCkpOworICBFWFBFQ1RfRVEoImJhcl9wYWNrYWdlIiwgYmFyX2ZpbGVfLT5wYWNrYWdlKCkpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBEZXBlbmRlbmNpZXMpIHsKKyAgRVhQRUNUX0VRKDAsIGZvb19maWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDEsIGJhcl9maWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKGZvb19maWxlXywgYmFyX2ZpbGVfLT5kZXBlbmRlbmN5KDApKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgRmluZE1lc3NhZ2VUeXBlQnlOYW1lKSB7CisgIEVYUEVDVF9FUShmb29fbWVzc2FnZV8sIGZvb19maWxlXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJGb29NZXNzYWdlIikpOworICBFWFBFQ1RfRVEoYmFyX21lc3NhZ2VfLCBiYXJfZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmFyTWVzc2FnZSIpKTsKKworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmFyTWVzc2FnZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXJfZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vTWVzc2FnZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXpfZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vTWVzc2FnZSIpID09IE5VTEwpOworCisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJOb1N1Y2hNZXNzYWdlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJGb29FbnVtIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIEZpbmRFbnVtVHlwZUJ5TmFtZSkgeworICBFWFBFQ1RfRVEoZm9vX2VudW1fLCBmb29fZmlsZV8tPkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vRW51bSIpKTsKKyAgRVhQRUNUX0VRKGJhcl9lbnVtXywgYmFyX2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIkJhckVudW0iKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIkJhckVudW0iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmFyX2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIkZvb0VudW0iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmF6X2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIkZvb0VudW0iKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRFbnVtVHlwZUJ5TmFtZSgiTm9TdWNoRW51bSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vTWVzc2FnZSIpID09IE5VTEwpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBGaW5kRW51bVZhbHVlQnlOYW1lKSB7CisgIEVYUEVDVF9FUShmb29fZW51bV92YWx1ZV8sIGZvb19maWxlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiRk9PX0VOVU1fVkFMVUUiKSk7CisgIEVYUEVDVF9FUShiYXJfZW51bV92YWx1ZV8sIGJhcl9maWxlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiQkFSX0VOVU1fVkFMVUUiKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJCQVJfRU5VTV9WQUxVRSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXJfZmlsZV8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkZPT19FTlVNX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGJhel9maWxlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiRk9PX0VOVU1fVkFMVUUiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIk5PX1NVQ0hfVkFMVUUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJGb29NZXNzYWdlIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIEZpbmRTZXJ2aWNlQnlOYW1lKSB7CisgIEVYUEVDVF9FUShmb29fc2VydmljZV8sIGZvb19maWxlXy0+RmluZFNlcnZpY2VCeU5hbWUoIkZvb1NlcnZpY2UiKSk7CisgIEVYUEVDVF9FUShiYXJfc2VydmljZV8sIGJhcl9maWxlXy0+RmluZFNlcnZpY2VCeU5hbWUoIkJhclNlcnZpY2UiKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kU2VydmljZUJ5TmFtZSgiQmFyU2VydmljZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXJfZmlsZV8tPkZpbmRTZXJ2aWNlQnlOYW1lKCJGb29TZXJ2aWNlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGJhel9maWxlXy0+RmluZFNlcnZpY2VCeU5hbWUoIkZvb1NlcnZpY2UiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRTZXJ2aWNlQnlOYW1lKCJOb1N1Y2hTZXJ2aWNlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZFNlcnZpY2VCeU5hbWUoIkZvb01lc3NhZ2UiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgRmluZEV4dGVuc2lvbkJ5TmFtZSkgeworICBFWFBFQ1RfRVEoZm9vX2V4dGVuc2lvbl8sIGZvb19maWxlXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiZm9vX2V4dGVuc2lvbiIpKTsKKyAgRVhQRUNUX0VRKGJhcl9leHRlbnNpb25fLCBiYXJfZmlsZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoImJhcl9leHRlbnNpb24iKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJiYXJfZXh0ZW5zaW9uIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGJhcl9maWxlXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiZm9vX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXpfZmlsZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoImZvb19leHRlbnNpb24iKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoIm5vX3N1Y2hfZXh0ZW5zaW9uIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiRm9vTWVzc2FnZSIpID09IE5VTEwpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBGaW5kRXh0ZW5zaW9uQnlOdW1iZXIpIHsKKyAgRVhQRUNUX0VRKGZvb19leHRlbnNpb25fLCBwb29sXy5GaW5kRXh0ZW5zaW9uQnlOdW1iZXIoZm9vX21lc3NhZ2VfLCAxKSk7CisgIEVYUEVDVF9FUShiYXJfZXh0ZW5zaW9uXywgcG9vbF8uRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGJhcl9tZXNzYWdlXywgMSkpOworCisgIEVYUEVDVF9UUlVFKHBvb2xfLkZpbmRFeHRlbnNpb25CeU51bWJlcihmb29fbWVzc2FnZV8sIDIpID09IE5VTEwpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBCdWlsZEFnYWluKSB7CisgIC8vIFRlc3QgdGhhdCBpZiB0ZSBjYWxsIEJ1aWxkRmlsZSBhZ2FpbiBvbiB0aGUgc2FtZSBpbnB1dCB3ZSBnZXQgdGhlIHNhbWUKKyAgLy8gRmlsZURlc2NyaXB0b3IgYmFjay4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICBmb29fZmlsZV8tPkNvcHlUbygmZmlsZSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIHBvb2xfLkJ1aWxkRmlsZShmaWxlKSk7CisKKyAgLy8gQnV0IGlmIHdlIGNoYW5nZSB0aGUgZmlsZSB0aGVuIGl0IHdvbid0IHdvcmsuCisgIGZpbGUuc2V0X3BhY2thZ2UoInNvbWUub3RoZXIucGFja2FnZSIpOworICBFWFBFQ1RfVFJVRShwb29sXy5CdWlsZEZpbGUoZmlsZSkgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIFN5bnRheCkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvOworICBwcm90by5zZXRfbmFtZSgiZm9vIik7CisgIC8vIEVuYWJsZSB0aGUgdGVzdCB3aGVuIHdlIGFsc28gcG9wdWxhdGUgdGhlIHN5bnRheCBmb3IgcHJvdG8yLgorI2lmIDAKKyAgeworICAgIHByb3RvLnNldF9zeW50YXgoInByb3RvMiIpOworICAgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShwcm90byk7CisgICAgRVhQRUNUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzIsIGZpbGUtPnN5bnRheCgpKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIG90aGVyOworICAgIGZpbGUtPkNvcHlUbygmb3RoZXIpOworICAgIEVYUEVDVF9FUSgicHJvdG8yIiwgb3RoZXIuc3ludGF4KCkpOworICB9CisjZW5kaWYKKyAgeworICAgIHByb3RvLnNldF9zeW50YXgoInByb3RvMyIpOworICAgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShwcm90byk7CisgICAgRVhQRUNUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzMsIGZpbGUtPnN5bnRheCgpKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIG90aGVyOworICAgIGZpbGUtPkNvcHlUbygmb3RoZXIpOworICAgIEVYUEVDVF9FUSgicHJvdG8zIiwgb3RoZXIuc3ludGF4KCkpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBzaW1wbGUgZmxhdCBtZXNzYWdlcyBhbmQgZmllbGRzLgorY2xhc3MgRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIFRlc3RGb3JlaWduIHt9CisgICAgLy8gICBlbnVtIFRlc3RFbnVtIHt9CisgICAgLy8KKyAgICAvLyAgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UgeworICAgIC8vICAgICByZXF1aXJlZCBzdHJpbmcgICAgICBmb28gPSAxOworICAgIC8vICAgICBvcHRpb25hbCBUZXN0RW51bSAgICBiYXIgPSA2OworICAgIC8vICAgICByZXBlYXRlZCBUZXN0Rm9yZWlnbiBiYXogPSA1MDAwMDAwMDA7CisgICAgLy8gICAgIG9wdGlvbmFsIGdyb3VwICAgICAgIHF1eCA9IDE1IHt9CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJiYXIucHJvdG8iCisgICAgLy8gICBwYWNrYWdlIGNvcmdlLmdyYXVsdDsKKyAgICAvLyAgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UyIHsKKyAgICAvLyAgICAgcmVxdWlyZWQgc3RyaW5nIGZvbyA9IDE7CisgICAgLy8gICAgIHJlcXVpcmVkIHN0cmluZyBiYXIgPSAyOworICAgIC8vICAgICByZXF1aXJlZCBzdHJpbmcgcXV1eCA9IDY7CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJtYXAucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIFRlc3RNZXNzYWdlMyB7CisgICAgLy8gICAgIG1hcDxpbnQzMiwgaW50MzI+IG1hcF9pbnQzMl9pbnQzMiA9IDE7CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyBXZSBjaGVhdCBhbmQgdXNlIFRlc3RGb3JlaWduIGFzIHRoZSB0eXBlIGZvciBxdXggcmF0aGVyIHRoYW4gY3JlYXRlCisgICAgLy8gYW4gYWN0dWFsIG5lc3RlZCB0eXBlLgorICAgIC8vCisgICAgLy8gU2luY2UgYWxsIHByaW1pdGl2ZSB0eXBlcyAoaW5jbHVkaW5nIHN0cmluZykgdXNlIHRoZSBzYW1lIGJ1aWxkaW5nCisgICAgLy8gY29kZSwgdGhlcmUncyBubyBuZWVkIHRvIHRlc3QgZWFjaCBvbmUgaW5kaXZpZHVhbGx5LgorICAgIC8vCisgICAgLy8gVGVzdE1lc3NhZ2UyIGlzIHByaW1hcmlseSBoZXJlIHRvIHRlc3QgRmluZEZpZWxkQnlOYW1lIGFuZCBmcmllbmRzLgorICAgIC8vIEFsbCBtZXNzYWdlcyBjcmVhdGVkIGZyb20gdGhlIHNhbWUgRGVzY3JpcHRvclBvb2wgc2hhcmUgdGhlIHNhbWUgbG9va3VwCisgICAgLy8gdGFibGUsIHNvIHdlIG5lZWQgdG8gaW5zdXJlIHRoYXQgdGhleSBkb24ndCBpbnRlcmZlcmUuCisKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZvb19maWxlOworICAgIGZvb19maWxlLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgICBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIlRlc3RGb3JlaWduIik7CisgICAgQWRkRW1wdHlFbnVtKCZmb29fZmlsZSwgIlRlc3RFbnVtIik7CisKKyAgICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UgPSBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIlRlc3RNZXNzYWdlIik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgImZvbyIsIDEsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUVVJUkVELAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NUUklORyk7CisgICAgQWRkRmllbGQobWVzc2FnZSwgImJhciIsIDYsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0VOVU0pCisgICAgICAtPnNldF90eXBlX25hbWUoIlRlc3RFbnVtIik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgImJheiIsIDUwMDAwMDAwMCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfTUVTU0FHRSkKKyAgICAgIC0+c2V0X3R5cGVfbmFtZSgiVGVzdEZvcmVpZ24iKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlLCAicXV4IiwgMTUsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQKQorICAgICAgLT5zZXRfdHlwZV9uYW1lKCJUZXN0Rm9yZWlnbiIpOworCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBiYXJfZmlsZTsKKyAgICBiYXJfZmlsZS5zZXRfbmFtZSgiYmFyLnByb3RvIik7CisgICAgYmFyX2ZpbGUuc2V0X3BhY2thZ2UoImNvcmdlLmdyYXVsdCIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlMiA9IEFkZE1lc3NhZ2UoJmJhcl9maWxlLCAiVGVzdE1lc3NhZ2UyIik7CisgICAgQWRkRmllbGQobWVzc2FnZTIsICJmb28iLCAxLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVFVSVJFRCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TVFJJTkcpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UyLCAiYmFyIiwgMiwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU1RSSU5HKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlMiwgInF1dXgiLCA2LAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVFVSVJFRCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TVFJJTkcpOworCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBtYXBfZmlsZTsKKyAgICBtYXBfZmlsZS5zZXRfbmFtZSgibWFwLnByb3RvIik7CisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlMyA9IEFkZE1lc3NhZ2UoJm1hcF9maWxlLCAiVGVzdE1lc3NhZ2UzIik7CisKKyAgICBEZXNjcmlwdG9yUHJvdG8qIGVudHJ5ID0gQWRkTmVzdGVkTWVzc2FnZShtZXNzYWdlMywgIk1hcEludDMySW50MzJFbnRyeSIpOworICAgIEFkZEZpZWxkKGVudHJ5LCAia2V5IiwgMSwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKGVudHJ5LCAidmFsdWUiLCAyLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgZW50cnktPm11dGFibGVfb3B0aW9ucygpLT5zZXRfbWFwX2VudHJ5KHRydWUpOworCisgICAgQWRkRmllbGQobWVzc2FnZTMsICJtYXBfaW50MzJfaW50MzIiLCAxLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVBFQVRFRCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFKQorICAgICAgICAtPnNldF90eXBlX25hbWUoIk1hcEludDMySW50MzJFbnRyeSIpOworCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIGZvb19maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmb29fZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmFyX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhcl9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBtYXBfZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUobWFwX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKG1hcF9maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpKTsKKyAgICBlbnVtXyA9IGZvb19maWxlXy0+ZW51bV90eXBlKDApOworCisgICAgQVNTRVJUX0VRKDIsIGZvb19maWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICAgIGZvcmVpZ25fID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMCk7CisgICAgbWVzc2FnZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgxKTsKKworICAgIEFTU0VSVF9FUSg0LCBtZXNzYWdlXy0+ZmllbGRfY291bnQoKSk7CisgICAgZm9vXyA9IG1lc3NhZ2VfLT5maWVsZCgwKTsKKyAgICBiYXJfID0gbWVzc2FnZV8tPmZpZWxkKDEpOworICAgIGJhel8gPSBtZXNzYWdlXy0+ZmllbGQoMik7CisgICAgcXV4XyA9IG1lc3NhZ2VfLT5maWVsZCgzKTsKKworICAgIEFTU0VSVF9FUSgxLCBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBtZXNzYWdlMl8gPSBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgzLCBtZXNzYWdlMl8tPmZpZWxkX2NvdW50KCkpOworICAgIGZvbzJfICA9IG1lc3NhZ2UyXy0+ZmllbGQoMCk7CisgICAgYmFyMl8gID0gbWVzc2FnZTJfLT5maWVsZCgxKTsKKyAgICBxdXV4Ml8gPSBtZXNzYWdlMl8tPmZpZWxkKDIpOworCisgICAgQVNTRVJUX0VRKDEsIG1hcF9maWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICAgIG1lc3NhZ2UzXyA9IG1hcF9maWxlXy0+bWVzc2FnZV90eXBlKDApOworCisgICAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UzXy0+ZmllbGRfY291bnQoKSk7CisgICAgbWFwXyAgPSBtZXNzYWdlM18tPmZpZWxkKDApOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZvb19maWxlXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhcl9maWxlXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIG1hcF9maWxlXzsKKworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZTJfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlM187CisgIGNvbnN0IERlc2NyaXB0b3IqIGZvcmVpZ25fOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV87CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmb29fOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJhcl87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYmF6XzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBxdXhfOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZm9vMl87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYmFyMl87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcXV1eDJfOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwXzsKK307CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgTmFtZSkgeworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlIiwgbWVzc2FnZV8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdE1lc3NhZ2UiLCBtZXNzYWdlXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoZm9vX2ZpbGVfLCBtZXNzYWdlXy0+ZmlsZSgpKTsKKworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlMiIsIG1lc3NhZ2UyXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdE1lc3NhZ2UyIiwgbWVzc2FnZTJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUShiYXJfZmlsZV8sIG1lc3NhZ2UyXy0+ZmlsZSgpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBDb250YWluaW5nVHlwZSkgeworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRzQnlJbmRleCkgeworICBBU1NFUlRfRVEoNCwgbWVzc2FnZV8tPmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPmZpZWxkKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5maWVsZCgxKSk7CisgIEVYUEVDVF9FUShiYXpfLCBtZXNzYWdlXy0+ZmllbGQoMikpOworICBFWFBFQ1RfRVEocXV4XywgbWVzc2FnZV8tPmZpZWxkKDMpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaW5kRmllbGRCeU5hbWUpIHsKKyAgLy8gQWxsIG1lc3NhZ2VzIGluIHRoZSBzYW1lIERlc2NyaXB0b3JQb29sIHNoYXJlIGEgc2luZ2xlIGxvb2t1cCB0YWJsZSBmb3IKKyAgLy8gZmllbGRzLiAgU28sIGluIGFkZGl0aW9uIHRvIHRlc3RpbmcgdGhhdCBGaW5kRmllbGRCeU5hbWUgZmluZHMgdGhlIGZpZWxkcworICAvLyBvZiB0aGUgbWVzc2FnZSwgd2UgbmVlZCB0byB0ZXN0IHRoYXQgaXQgZG9lcyAqbm90KiBmaW5kIHRoZSBmaWVsZHMgb2YKKyAgLy8gKm90aGVyKiBtZXNzYWdlcy4KKworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TmFtZSgiZm9vIikpOworICBFWFBFQ1RfRVEoYmFyXywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TmFtZSgiYmFyIikpOworICBFWFBFQ1RfRVEoYmF6XywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TmFtZSgiYmF6IikpOworICBFWFBFQ1RfRVEocXV4XywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TmFtZSgicXV4IikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlOYW1lKCJub19zdWNoX2ZpZWxkIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoInF1dXgiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZm9vMl8gLCBtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TmFtZSgiZm9vIiApKTsKKyAgRVhQRUNUX0VRKGJhcjJfICwgbWVzc2FnZTJfLT5GaW5kRmllbGRCeU5hbWUoImJhciIgKSk7CisgIEVYUEVDVF9FUShxdXV4Ml8sIG1lc3NhZ2UyXy0+RmluZEZpZWxkQnlOYW1lKCJxdXV4IikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TmFtZSgiYmF6IikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+RmluZEZpZWxkQnlOYW1lKCJxdXgiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaW5kRmllbGRCeU51bWJlcikgeworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TnVtYmVyKDEpKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5GaW5kRmllbGRCeU51bWJlcig2KSk7CisgIEVYUEVDVF9FUShiYXpfLCBtZXNzYWdlXy0+RmluZEZpZWxkQnlOdW1iZXIoNTAwMDAwMDAwKSk7CisgIEVYUEVDVF9FUShxdXhfLCBtZXNzYWdlXy0+RmluZEZpZWxkQnlOdW1iZXIoMTUpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRGaWVsZEJ5TnVtYmVyKDgzNzU5MikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeU51bWJlcigyKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZm9vMl8gLCBtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TnVtYmVyKDEpKTsKKyAgRVhQRUNUX0VRKGJhcjJfICwgbWVzc2FnZTJfLT5GaW5kRmllbGRCeU51bWJlcigyKSk7CisgIEVYUEVDVF9FUShxdXV4Ml8sIG1lc3NhZ2UyXy0+RmluZEZpZWxkQnlOdW1iZXIoNikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TnVtYmVyKDE1KSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTJfLT5GaW5kRmllbGRCeU51bWJlcig1MDAwMDAwMDApID09IE5VTEwpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkTmFtZSkgeworICBFWFBFQ1RfRVEoImZvbyIsIGZvb18tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyIiwgYmFyXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCBiYXpfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoInF1eCIsIHF1eF8tPm5hbWUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRGdWxsTmFtZSkgeworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLmZvbyIsIGZvb18tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZS5iYXIiLCBiYXJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdE1lc3NhZ2UuYmF6IiwgYmF6Xy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLnF1eCIsIHF1eF8tPmZ1bGxfbmFtZSgpKTsKKworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5UZXN0TWVzc2FnZTIuZm9vIiwgZm9vMl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdE1lc3NhZ2UyLmJhciIsIGJhcjJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5xdXV4IiwgcXV1eDJfLT5mdWxsX25hbWUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRGaWxlKSB7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGZvb18tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGJhcl8tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGJhel8tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIHF1eF8tPmZpbGUoKSk7CisKKyAgRVhQRUNUX0VRKGJhcl9maWxlXywgZm9vMl8tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShiYXJfZmlsZV8sIGJhcjJfLT5maWxlKCkpOworICBFWFBFQ1RfRVEoYmFyX2ZpbGVfLCBxdXV4Ml8tPmZpbGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRJbmRleCkgeworICBFWFBFQ1RfRVEoMCwgZm9vXy0+aW5kZXgoKSk7CisgIEVYUEVDVF9FUSgxLCBiYXJfLT5pbmRleCgpKTsKKyAgRVhQRUNUX0VRKDIsIGJhel8tPmluZGV4KCkpOworICBFWFBFQ1RfRVEoMywgcXV4Xy0+aW5kZXgoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGROdW1iZXIpIHsKKyAgRVhQRUNUX0VRKCAgICAgICAgMSwgZm9vXy0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoICAgICAgICA2LCBiYXJfLT5udW1iZXIoKSk7CisgIEVYUEVDVF9FUSg1MDAwMDAwMDAsIGJhel8tPm51bWJlcigpKTsKKyAgRVhQRUNUX0VRKCAgICAgICAxNSwgcXV4Xy0+bnVtYmVyKCkpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkVHlwZSkgeworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAsIGZvb18tPnR5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICwgYmFyXy0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBiYXpfLT50eXBlKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAsIHF1eF8tPnR5cGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRMYWJlbCkgeworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVFVSVJFRCwgZm9vXy0+bGFiZWwoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMLCBiYXJfLT5sYWJlbCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQsIGJhel8tPmxhYmVsKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTCwgcXV4Xy0+bGFiZWwoKSk7CisKKyAgRVhQRUNUX1RSVUUgKGZvb18tPmlzX3JlcXVpcmVkKCkpOworICBFWFBFQ1RfRkFMU0UoZm9vXy0+aXNfb3B0aW9uYWwoKSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5pc19yZXBlYXRlZCgpKTsKKworICBFWFBFQ1RfRkFMU0UoYmFyXy0+aXNfcmVxdWlyZWQoKSk7CisgIEVYUEVDVF9UUlVFIChiYXJfLT5pc19vcHRpb25hbCgpKTsKKyAgRVhQRUNUX0ZBTFNFKGJhcl8tPmlzX3JlcGVhdGVkKCkpOworCisgIEVYUEVDVF9GQUxTRShiYXpfLT5pc19yZXF1aXJlZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKGJhel8tPmlzX29wdGlvbmFsKCkpOworICBFWFBFQ1RfVFJVRSAoYmF6Xy0+aXNfcmVwZWF0ZWQoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgSXNNYXApIHsKKyAgRVhQRUNUX1RSVUUobWFwXy0+aXNfbWFwKCkpOworICBFWFBFQ1RfRkFMU0UoYmF6Xy0+aXNfbWFwKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLT5tZXNzYWdlX3R5cGUoKS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaWVsZEhhc0RlZmF1bHQpIHsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBFWFBFQ1RfRkFMU0UoYmFyXy0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEVYUEVDVF9GQUxTRShiYXpfLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHF1eF8tPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkQ29udGFpbmluZ1R5cGUpIHsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLCBmb29fLT5jb250YWluaW5nX3R5cGUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlXywgYmFyXy0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV8sIGJhel8tPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLCBxdXhfLT5jb250YWluaW5nX3R5cGUoKSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyXywgZm9vMl8gLT5jb250YWluaW5nX3R5cGUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMl8sIGJhcjJfIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTJfLCBxdXV4Ml8tPmNvbnRhaW5pbmdfdHlwZSgpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaWVsZE1lc3NhZ2VUeXBlKSB7CisgIEVYUEVDVF9UUlVFKGZvb18tPm1lc3NhZ2VfdHlwZSgpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXJfLT5tZXNzYWdlX3R5cGUoKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZm9yZWlnbl8sIGJhel8tPm1lc3NhZ2VfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fLCBxdXhfLT5tZXNzYWdlX3R5cGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRFbnVtVHlwZSkgeworICBFWFBFQ1RfVFJVRShmb29fLT5lbnVtX3R5cGUoKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmF6Xy0+ZW51bV90eXBlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHF1eF8tPmVudW1fdHlwZSgpID09IE5VTEwpOworCisgIEVYUEVDVF9FUShlbnVtXywgYmFyXy0+ZW51bV90eXBlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRlc3Qgc2ltcGxlIGZsYXQgbWVzc2FnZXMgYW5kIGZpZWxkcy4KK2NsYXNzIE9uZW9mRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIHBhY2thZ2UgZ2FycGx5OworICAgIC8vICAgbWVzc2FnZSBUZXN0T25lb2YgeworICAgIC8vICAgICBvcHRpb25hbCBpbnQzMiBhID0gMTsKKyAgICAvLyAgICAgb25lb2YgZm9vIHsKKyAgICAvLyAgICAgICBzdHJpbmcgYiA9IDI7CisgICAgLy8gICAgICAgVGVzdE9uZW9mIGMgPSAzOworICAgIC8vICAgICB9CisgICAgLy8gICAgIG9uZW9mIGJhciB7CisgICAgLy8gICAgICAgZmxvYXQgZCA9IDQ7CisgICAgLy8gICAgIH0KKyAgICAvLyAgIH0KKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmF6X2ZpbGU7CisgICAgYmF6X2ZpbGUuc2V0X25hbWUoImJhei5wcm90byIpOworICAgIGJhel9maWxlLnNldF9wYWNrYWdlKCJnYXJwbHkiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogb25lb2ZfbWVzc2FnZSA9IEFkZE1lc3NhZ2UoJmJhel9maWxlLCAiVGVzdE9uZW9mIik7CisgICAgb25lb2ZfbWVzc2FnZS0+YWRkX29uZW9mX2RlY2woKS0+c2V0X25hbWUoImZvbyIpOworICAgIG9uZW9mX21lc3NhZ2UtPmFkZF9vbmVvZl9kZWNsKCktPnNldF9uYW1lKCJiYXIiKTsKKworICAgIEFkZEZpZWxkKG9uZW9mX21lc3NhZ2UsICJhIiwgMSwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKG9uZW9mX21lc3NhZ2UsICJiIiwgMiwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU1RSSU5HKTsKKyAgICBvbmVvZl9tZXNzYWdlLT5tdXRhYmxlX2ZpZWxkKDEpLT5zZXRfb25lb2ZfaW5kZXgoMCk7CisgICAgQWRkRmllbGQob25lb2ZfbWVzc2FnZSwgImMiLCAzLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFKTsKKyAgICBvbmVvZl9tZXNzYWdlLT5tdXRhYmxlX2ZpZWxkKDIpLT5zZXRfb25lb2ZfaW5kZXgoMCk7CisgICAgb25lb2ZfbWVzc2FnZS0+bXV0YWJsZV9maWVsZCgyKS0+c2V0X3R5cGVfbmFtZSgiVGVzdE9uZW9mIik7CisKKyAgICBBZGRGaWVsZChvbmVvZl9tZXNzYWdlLCAiZCIsIDQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZMT0FUKTsKKyAgICBvbmVvZl9tZXNzYWdlLT5tdXRhYmxlX2ZpZWxkKDMpLT5zZXRfb25lb2ZfaW5kZXgoMSk7CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgYmF6X2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhel9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXpfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmF6X2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgb25lb2ZfbWVzc2FnZV8gPSBiYXpfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBvbmVvZl9tZXNzYWdlXy0+b25lb2ZfZGVjbF9jb3VudCgpKTsKKyAgICBvbmVvZl8gPSBvbmVvZl9tZXNzYWdlXy0+b25lb2ZfZGVjbCgwKTsKKyAgICBvbmVvZjJfID0gb25lb2ZfbWVzc2FnZV8tPm9uZW9mX2RlY2woMSk7CisKKyAgICBBU1NFUlRfRVEoNCwgb25lb2ZfbWVzc2FnZV8tPmZpZWxkX2NvdW50KCkpOworICAgIGFfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDApOworICAgIGJfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDEpOworICAgIGNfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDIpOworICAgIGRfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDMpOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhel9maWxlXzsKKworICBjb25zdCBEZXNjcmlwdG9yKiBvbmVvZl9tZXNzYWdlXzsKKworICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mXzsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZjJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGFfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGNfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGVfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZfOworfTsKKworVEVTVF9GKE9uZW9mRGVzY3JpcHRvclRlc3QsIE5vcm1hbCkgeworICBFWFBFQ1RfRVEoImZvbyIsIG9uZW9mXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJnYXJwbHkuVGVzdE9uZW9mLmZvbyIsIG9uZW9mXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoMCwgb25lb2ZfLT5pbmRleCgpKTsKKyAgQVNTRVJUX0VRKDIsIG9uZW9mXy0+ZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUShiXywgb25lb2ZfLT5maWVsZCgwKSk7CisgIEVYUEVDVF9FUShjXywgb25lb2ZfLT5maWVsZCgxKSk7CisgIEVYUEVDVF9UUlVFKGFfLT5jb250YWluaW5nX29uZW9mKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9FUShvbmVvZl8sIGJfLT5jb250YWluaW5nX29uZW9mKCkpOworICBFWFBFQ1RfRVEob25lb2ZfLCBjXy0+Y29udGFpbmluZ19vbmVvZigpKTsKK30KKworVEVTVF9GKE9uZW9mRGVzY3JpcHRvclRlc3QsIEZpbmRCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKG9uZW9mXywgb25lb2ZfbWVzc2FnZV8tPkZpbmRPbmVvZkJ5TmFtZSgiZm9vIikpOworICBFWFBFQ1RfRVEob25lb2YyXywgb25lb2ZfbWVzc2FnZV8tPkZpbmRPbmVvZkJ5TmFtZSgiYmFyIikpOworICBFWFBFQ1RfVFJVRShvbmVvZl9tZXNzYWdlXy0+RmluZE9uZW9mQnlOYW1lKCJub19zdWNoX29uZW9mIikgPT0gTlVMTCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgU3R5bGl6ZWRGaWVsZE5hbWVzVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgU2V0VXAoKSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIGZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgQWRkRXh0ZW5zaW9uUmFuZ2UoQWRkTWVzc2FnZSgmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiksIDEsIDEwMDApOworCisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlID0gQWRkTWVzc2FnZSgmZmlsZSwgIlRlc3RNZXNzYWdlIik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgImZvb19mb28iLCAxLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgIkZvb0JhciIsIDIsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlLCAiZm9vQmF6IiwgMywKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UsICJmb29Gb28iLCA0LCAgLy8gQ2FtZWwtY2FzZSBjb25mbGljdCB3aXRoIGZvb19mb28uCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlLCAiZm9vYmFyIiwgNSwgIC8vIExvd2VyLWNhc2UgY29uZmxpY3Qgd2l0aCBGb29CYXIuCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKworICAgIEFkZE5lc3RlZEV4dGVuc2lvbihtZXNzYWdlLCAiRXh0ZW5kYWJsZU1lc3NhZ2UiLCAiYmFyX2ZvbyIsIDEsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZE5lc3RlZEV4dGVuc2lvbihtZXNzYWdlLCAiRXh0ZW5kYWJsZU1lc3NhZ2UiLCAiQmFyQmFyIiwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkTmVzdGVkRXh0ZW5zaW9uKG1lc3NhZ2UsICJFeHRlbmRhYmxlTWVzc2FnZSIsICJCYXJCYXoiLCAzLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGROZXN0ZWRFeHRlbnNpb24obWVzc2FnZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhckZvbyIsIDQsICAvLyBDb25mbGljdAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGROZXN0ZWRFeHRlbnNpb24obWVzc2FnZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhcmJhciIsIDUsICAvLyBDb25mbGljdAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKworICAgIEFkZEV4dGVuc2lvbigmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhel9mb28iLCAxMSwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRXh0ZW5zaW9uKCZmaWxlLCAiRXh0ZW5kYWJsZU1lc3NhZ2UiLCAiQmF6QmFyIiwgMTIsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEV4dGVuc2lvbigmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgIkJhekJheiIsIDEzLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRFeHRlbnNpb24oJmZpbGUsICJFeHRlbmRhYmxlTWVzc2FnZSIsICJiYXpGb28iLCAxNCwgIC8vIENvbmZsaWN0CisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEV4dGVuc2lvbigmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhemJhciIsIDE1LCAgLy8gQ29uZmxpY3QKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisKKyAgICBmaWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmaWxlKTsKKyAgICBBU1NFUlRfVFJVRShmaWxlXyAhPSBOVUxMKTsKKyAgICBBU1NFUlRfRVEoMiwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBtZXNzYWdlXyA9IGZpbGVfLT5tZXNzYWdlX3R5cGUoMSk7CisgICAgQVNTRVJUX0VRKCJUZXN0TWVzc2FnZSIsIG1lc3NhZ2VfLT5uYW1lKCkpOworICAgIEFTU0VSVF9FUSg1LCBtZXNzYWdlXy0+ZmllbGRfY291bnQoKSk7CisgICAgQVNTRVJUX0VRKDUsIG1lc3NhZ2VfLT5leHRlbnNpb25fY291bnQoKSk7CisgICAgQVNTRVJUX0VRKDUsIGZpbGVfLT5leHRlbnNpb25fY291bnQoKSk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlXzsKK307CisKK1RFU1RfRihTdHlsaXplZEZpZWxkTmFtZXNUZXN0LCBMb3dlcmNhc2VOYW1lKSB7CisgIEVYUEVDVF9FUSgiZm9vX2ZvbyIsIG1lc3NhZ2VfLT5maWVsZCgwKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vYmFyIiAsIG1lc3NhZ2VfLT5maWVsZCgxKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vYmF6IiAsIG1lc3NhZ2VfLT5maWVsZCgyKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vZm9vIiAsIG1lc3NhZ2VfLT5maWVsZCgzKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vYmFyIiAsIG1lc3NhZ2VfLT5maWVsZCg0KS0+bG93ZXJjYXNlX25hbWUoKSk7CisKKyAgRVhQRUNUX0VRKCJiYXJfZm9vIiwgbWVzc2FnZV8tPmV4dGVuc2lvbigwKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyYmFyIiAsIG1lc3NhZ2VfLT5leHRlbnNpb24oMSktPmxvd2VyY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhcmJheiIgLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDIpLT5sb3dlcmNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJmb28iICwgbWVzc2FnZV8tPmV4dGVuc2lvbigzKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyYmFyIiAsIG1lc3NhZ2VfLT5leHRlbnNpb24oNCktPmxvd2VyY2FzZV9uYW1lKCkpOworCisgIEVYUEVDVF9FUSgiYmF6X2ZvbyIsIGZpbGVfLT5leHRlbnNpb24oMCktPmxvd2VyY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhemJhciIgLCBmaWxlXy0+ZXh0ZW5zaW9uKDEpLT5sb3dlcmNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXpiYXoiICwgZmlsZV8tPmV4dGVuc2lvbigyKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmF6Zm9vIiAsIGZpbGVfLT5leHRlbnNpb24oMyktPmxvd2VyY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhemJhciIgLCBmaWxlXy0+ZXh0ZW5zaW9uKDQpLT5sb3dlcmNhc2VfbmFtZSgpKTsKK30KKworVEVTVF9GKFN0eWxpemVkRmllbGROYW1lc1Rlc3QsIENhbWVsY2FzZU5hbWUpIHsKKyAgRVhQRUNUX0VRKCJmb29Gb28iLCBtZXNzYWdlXy0+ZmllbGQoMCktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb0JhciIsIG1lc3NhZ2VfLT5maWVsZCgxKS0+Y2FtZWxjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vQmF6IiwgbWVzc2FnZV8tPmZpZWxkKDIpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmb29Gb28iLCBtZXNzYWdlXy0+ZmllbGQoMyktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb2JhciIsIG1lc3NhZ2VfLT5maWVsZCg0KS0+Y2FtZWxjYXNlX25hbWUoKSk7CisKKyAgRVhQRUNUX0VRKCJiYXJGb28iLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDApLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJCYXIiLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDEpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJCYXoiLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDIpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJGb28iLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDMpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJiYXIiLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDQpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKworICBFWFBFQ1RfRVEoImJhekZvbyIsIGZpbGVfLT5leHRlbnNpb24oMCktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhekJhciIsIGZpbGVfLT5leHRlbnNpb24oMSktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhekJheiIsIGZpbGVfLT5leHRlbnNpb24oMiktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhekZvbyIsIGZpbGVfLT5leHRlbnNpb24oMyktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhemJhciIsIGZpbGVfLT5leHRlbnNpb24oNCktPmNhbWVsY2FzZV9uYW1lKCkpOworfQorCitURVNUX0YoU3R5bGl6ZWRGaWVsZE5hbWVzVGVzdCwgRmluZEJ5TG93ZXJjYXNlTmFtZSkgeworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDApLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgiZm9vX2ZvbyIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5maWVsZCgxKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoImZvb2JhciIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5maWVsZCgyKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoImZvb2JheiIpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgiRm9vQmFyIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoImZvb0JheiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKCJiYXJfZm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoIm5vc3VjaGZpZWxkIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5leHRlbnNpb24oMCksCisgICAgICAgICAgICBtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiYmFyX2ZvbyIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5leHRlbnNpb24oMSksCisgICAgICAgICAgICBtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiYmFyYmFyIikpOworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmV4dGVuc2lvbigyKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJiYXJiYXoiKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJCYXJCYXIiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoImJhckJheiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiZm9vX2ZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgibm9zdWNoZmllbGQiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZmlsZV8tPmV4dGVuc2lvbigwKSwKKyAgICAgICAgICAgIGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJiYXpfZm9vIikpOworICBFWFBFQ1RfRVEoZmlsZV8tPmV4dGVuc2lvbigxKSwKKyAgICAgICAgICAgIGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJiYXpiYXIiKSk7CisgIEVYUEVDVF9FUShmaWxlXy0+ZXh0ZW5zaW9uKDIpLAorICAgICAgICAgICAgZmlsZV8tPkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoImJhemJheiIpKTsKKyAgRVhQRUNUX1RSVUUoZmlsZV8tPkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoIkJhekJhciIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmaWxlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiYmF6QmF6IikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJub3N1Y2hmaWVsZCIpID09IE5VTEwpOworfQorCitURVNUX0YoU3R5bGl6ZWRGaWVsZE5hbWVzVGVzdCwgRmluZEJ5Q2FtZWxjYXNlTmFtZSkgeworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDApLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgiZm9vRm9vIikpOworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDEpLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgiZm9vQmFyIikpOworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDIpLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgiZm9vQmF6IikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKCJmb29fZm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoIkZvb0JhciIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKCJiYXJGb28iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgibm9zdWNoZmllbGQiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmV4dGVuc2lvbigwKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKCJiYXJGb28iKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlXy0+ZXh0ZW5zaW9uKDEpLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoImJhckJhciIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5leHRlbnNpb24oMiksCisgICAgICAgICAgICBtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiYmFyQmF6IikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiYmFyX2ZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiQmFyQmFyIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKCJmb29Gb28iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoIm5vc3VjaGZpZWxkIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX0VRKGZpbGVfLT5leHRlbnNpb24oMCksCisgICAgICAgICAgICBmaWxlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiYmF6Rm9vIikpOworICBFWFBFQ1RfRVEoZmlsZV8tPmV4dGVuc2lvbigxKSwKKyAgICAgICAgICAgIGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKCJiYXpCYXIiKSk7CisgIEVYUEVDVF9FUShmaWxlXy0+ZXh0ZW5zaW9uKDIpLAorICAgICAgICAgICAgZmlsZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoImJhekJheiIpKTsKKyAgRVhQRUNUX1RSVUUoZmlsZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoImJhel9mb28iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZmlsZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoIkJhekJhciIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmaWxlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgibm9zdWNoZmllbGQiKSA9PSBOVUxMKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUZXN0IGVudW0gZGVzY3JpcHRvcnMuCitjbGFzcyBFbnVtRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBlbnVtIFRlc3RFbnVtIHsKKyAgICAvLyAgICAgRk9PID0gMTsKKyAgICAvLyAgICAgQkFSID0gMjsKKyAgICAvLyAgIH0KKyAgICAvLworICAgIC8vICAgLy8gaW4gImJhci5wcm90byIKKyAgICAvLyAgIHBhY2thZ2UgY29yZ2UuZ3JhdWx0OworICAgIC8vICAgZW51bSBUZXN0RW51bTIgeworICAgIC8vICAgICBGT08gPSAxOworICAgIC8vICAgICBCQVogPSAzOworICAgIC8vICAgfQorICAgIC8vCisgICAgLy8gVGVzdEVudW0yIGlzIHByaW1hcmlseSBoZXJlIHRvIHRlc3QgRmluZFZhbHVlQnlOYW1lIGFuZCBmcmllbmRzLgorICAgIC8vIEFsbCBlbnVtcyBjcmVhdGVkIGZyb20gdGhlIHNhbWUgRGVzY3JpcHRvclBvb2wgc2hhcmUgdGhlIHNhbWUgbG9va3VwCisgICAgLy8gdGFibGUsIHNvIHdlIG5lZWQgdG8gaW5zdXJlIHRoYXQgdGhleSBkb24ndCBpbnRlcmZlcmUuCisKKyAgICAvLyBUZXN0RW51bQorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vX2ZpbGU7CisgICAgZm9vX2ZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgRW51bURlc2NyaXB0b3JQcm90byogZW51bV9wcm90byA9IEFkZEVudW0oJmZvb19maWxlLCAiVGVzdEVudW0iKTsKKyAgICBBZGRFbnVtVmFsdWUoZW51bV9wcm90bywgIkZPTyIsIDEpOworICAgIEFkZEVudW1WYWx1ZShlbnVtX3Byb3RvLCAiQkFSIiwgMik7CisKKyAgICAvLyBUZXN0RW51bTIKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhcl9maWxlOworICAgIGJhcl9maWxlLnNldF9uYW1lKCJiYXIucHJvdG8iKTsKKyAgICBiYXJfZmlsZS5zZXRfcGFja2FnZSgiY29yZ2UuZ3JhdWx0Iik7CisKKyAgICBFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtMl9wcm90byA9IEFkZEVudW0oJmJhcl9maWxlLCAiVGVzdEVudW0yIik7CisgICAgQWRkRW51bVZhbHVlKGVudW0yX3Byb3RvLCAiRk9PIiwgMSk7CisgICAgQWRkRW51bVZhbHVlKGVudW0yX3Byb3RvLCAiQkFaIiwgMyk7CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgZm9vX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGZvb19maWxlKTsKKyAgICBBU1NFUlRfVFJVRShmb29fZmlsZV8gIT0gTlVMTCk7CisKKyAgICBiYXJfZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoYmFyX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGJhcl9maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpKTsKKyAgICBlbnVtXyA9IGZvb19maWxlXy0+ZW51bV90eXBlKDApOworCisgICAgQVNTRVJUX0VRKDIsIGVudW1fLT52YWx1ZV9jb3VudCgpKTsKKyAgICBmb29fID0gZW51bV8tPnZhbHVlKDApOworICAgIGJhcl8gPSBlbnVtXy0+dmFsdWUoMSk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgZW51bTJfID0gYmFyX2ZpbGVfLT5lbnVtX3R5cGUoMCk7CisKKyAgICBBU1NFUlRfRVEoMiwgZW51bTJfLT52YWx1ZV9jb3VudCgpKTsKKyAgICBmb28yXyA9IGVudW0yXy0+dmFsdWUoMCk7CisgICAgYmF6Ml8gPSBlbnVtMl8tPnZhbHVlKDEpOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZvb19maWxlXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhcl9maWxlXzsKKworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtMl87CisKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZm9vXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYmFyXzsKKworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBmb28yXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYmF6Ml87Cit9OworCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBOYW1lKSB7CisgIEVYUEVDVF9FUSgiVGVzdEVudW0iLCBlbnVtXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJUZXN0RW51bSIsIGVudW1fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGVudW1fLT5maWxlKCkpOworCisgIEVYUEVDVF9FUSgiVGVzdEVudW0yIiwgZW51bTJfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5UZXN0RW51bTIiLCBlbnVtMl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl9maWxlXywgZW51bTJfLT5maWxlKCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBDb250YWluaW5nVHlwZSkgeworICBFWFBFQ1RfVFJVRShlbnVtXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGVudW0yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihFbnVtRGVzY3JpcHRvclRlc3QsIFZhbHVlc0J5SW5kZXgpIHsKKyAgQVNTRVJUX0VRKDIsIGVudW1fLT52YWx1ZV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKGZvb18sIGVudW1fLT52YWx1ZSgwKSk7CisgIEVYUEVDVF9FUShiYXJfLCBlbnVtXy0+dmFsdWUoMSkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBGaW5kVmFsdWVCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKGZvb18gLCBlbnVtXyAtPkZpbmRWYWx1ZUJ5TmFtZSgiRk9PIikpOworICBFWFBFQ1RfRVEoYmFyXyAsIGVudW1fIC0+RmluZFZhbHVlQnlOYW1lKCJCQVIiKSk7CisgIEVYUEVDVF9FUShmb28yXywgZW51bTJfLT5GaW5kVmFsdWVCeU5hbWUoIkZPTyIpKTsKKyAgRVhQRUNUX0VRKGJhejJfLCBlbnVtMl8tPkZpbmRWYWx1ZUJ5TmFtZSgiQkFaIikpOworCisgIEVYUEVDVF9UUlVFKGVudW1fIC0+RmluZFZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGVudW1fIC0+RmluZFZhbHVlQnlOYW1lKCJCQVoiICAgICAgICAgICkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGVudW0yXy0+RmluZFZhbHVlQnlOYW1lKCJCQVIiICAgICAgICAgICkgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihFbnVtRGVzY3JpcHRvclRlc3QsIEZpbmRWYWx1ZUJ5TnVtYmVyKSB7CisgIEVYUEVDVF9FUShmb29fICwgZW51bV8gLT5GaW5kVmFsdWVCeU51bWJlcigxKSk7CisgIEVYUEVDVF9FUShiYXJfICwgZW51bV8gLT5GaW5kVmFsdWVCeU51bWJlcigyKSk7CisgIEVYUEVDVF9FUShmb28yXywgZW51bTJfLT5GaW5kVmFsdWVCeU51bWJlcigxKSk7CisgIEVYUEVDVF9FUShiYXoyXywgZW51bTJfLT5GaW5kVmFsdWVCeU51bWJlcigzKSk7CisKKyAgRVhQRUNUX1RSVUUoZW51bV8gLT5GaW5kVmFsdWVCeU51bWJlcig0MTYpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShlbnVtXyAtPkZpbmRWYWx1ZUJ5TnVtYmVyKDMpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShlbnVtMl8tPkZpbmRWYWx1ZUJ5TnVtYmVyKDIpID09IE5VTEwpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZU5hbWUpIHsKKyAgRVhQRUNUX0VRKCJGT08iLCBmb29fLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJBUiIsIGJhcl8tPm5hbWUoKSk7Cit9CisKK1RFU1RfRihFbnVtRGVzY3JpcHRvclRlc3QsIFZhbHVlRnVsbE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJGT08iLCBmb29fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiQkFSIiwgYmFyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5GT08iLCBmb28yXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5CQVoiLCBiYXoyXy0+ZnVsbF9uYW1lKCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZUluZGV4KSB7CisgIEVYUEVDVF9FUSgwLCBmb29fLT5pbmRleCgpKTsKKyAgRVhQRUNUX0VRKDEsIGJhcl8tPmluZGV4KCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZU51bWJlcikgeworICBFWFBFQ1RfRVEoMSwgZm9vXy0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMiwgYmFyXy0+bnVtYmVyKCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZVR5cGUpIHsKKyAgRVhQRUNUX0VRKGVudW1fICwgZm9vXyAtPnR5cGUoKSk7CisgIEVYUEVDVF9FUShlbnVtXyAsIGJhcl8gLT50eXBlKCkpOworICBFWFBFQ1RfRVEoZW51bTJfLCBmb28yXy0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGVudW0yXywgYmF6Ml8tPnR5cGUoKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBzZXJ2aWNlIGRlc2NyaXB0b3JzLgorY2xhc3MgU2VydmljZURlc2NyaXB0b3JUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIC8vIEJ1aWxkIGRlc2NyaXB0b3JzIGZvciB0aGUgZm9sbG93aW5nIG1lc3NhZ2VzIGFuZCBzZXJ2aWNlOgorICAgIC8vICAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICAgbWVzc2FnZSBGb29SZXF1ZXN0ICB7fQorICAgIC8vICAgIG1lc3NhZ2UgRm9vUmVzcG9uc2Uge30KKyAgICAvLyAgICBtZXNzYWdlIEJhclJlcXVlc3QgIHt9CisgICAgLy8gICAgbWVzc2FnZSBCYXJSZXNwb25zZSB7fQorICAgIC8vICAgIG1lc3NhZ2UgQmF6UmVxdWVzdCAge30KKyAgICAvLyAgICBtZXNzYWdlIEJhelJlc3BvbnNlIHt9CisgICAgLy8KKyAgICAvLyAgICBzZXJ2aWNlIFRlc3RTZXJ2aWNlIHsKKyAgICAvLyAgICAgIHJwYyBGb28oRm9vUmVxdWVzdCkgcmV0dXJucyAoRm9vUmVzcG9uc2UpOworICAgIC8vICAgICAgcnBjIEJhcihCYXJSZXF1ZXN0KSByZXR1cm5zIChCYXJSZXNwb25zZSk7CisgICAgLy8gICAgfQorICAgIC8vCisgICAgLy8gICAgLy8gaW4gImJhci5wcm90byIKKyAgICAvLyAgICBwYWNrYWdlIGNvcmdlLmdyYXVsdAorICAgIC8vICAgIHNlcnZpY2UgVGVzdFNlcnZpY2UyIHsKKyAgICAvLyAgICAgIHJwYyBGb28oRm9vUmVxdWVzdCkgcmV0dXJucyAoRm9vUmVzcG9uc2UpOworICAgIC8vICAgICAgcnBjIEJheihCYXpSZXF1ZXN0KSByZXR1cm5zIChCYXpSZXNwb25zZSk7CisgICAgLy8gICAgfQorCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fZmlsZTsKKyAgICBmb29fZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisKKyAgICBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkZvb1JlcXVlc3QiKTsKKyAgICBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkZvb1Jlc3BvbnNlIik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJCYXJSZXF1ZXN0Iik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJCYXJSZXNwb25zZSIpOworICAgIEFkZE1lc3NhZ2UoJmZvb19maWxlLCAiQmF6UmVxdWVzdCIpOworICAgIEFkZE1lc3NhZ2UoJmZvb19maWxlLCAiQmF6UmVzcG9uc2UiKTsKKworICAgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHNlcnZpY2UgPSBBZGRTZXJ2aWNlKCZmb29fZmlsZSwgIlRlc3RTZXJ2aWNlIik7CisgICAgQWRkTWV0aG9kKHNlcnZpY2UsICJGb28iLCAiRm9vUmVxdWVzdCIsICJGb29SZXNwb25zZSIpOworICAgIEFkZE1ldGhvZChzZXJ2aWNlLCAiQmFyIiwgIkJhclJlcXVlc3QiLCAiQmFyUmVzcG9uc2UiKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyX2ZpbGU7CisgICAgYmFyX2ZpbGUuc2V0X25hbWUoImJhci5wcm90byIpOworICAgIGJhcl9maWxlLnNldF9wYWNrYWdlKCJjb3JnZS5ncmF1bHQiKTsKKyAgICBiYXJfZmlsZS5hZGRfZGVwZW5kZW5jeSgiZm9vLnByb3RvIik7CisKKyAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzZXJ2aWNlMiA9IEFkZFNlcnZpY2UoJmJhcl9maWxlLCAiVGVzdFNlcnZpY2UyIik7CisgICAgQWRkTWV0aG9kKHNlcnZpY2UyLCAiRm9vIiwgIkZvb1JlcXVlc3QiLCAiRm9vUmVzcG9uc2UiKTsKKyAgICBBZGRNZXRob2Qoc2VydmljZTIsICJCYXoiLCAiQmF6UmVxdWVzdCIsICJCYXpSZXNwb25zZSIpOworCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIGZvb19maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmb29fZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmFyX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhcl9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoNiwgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgZm9vX3JlcXVlc3RfICA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworICAgIGZvb19yZXNwb25zZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgxKTsKKyAgICBiYXJfcmVxdWVzdF8gID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMik7CisgICAgYmFyX3Jlc3BvbnNlXyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDMpOworICAgIGJhel9yZXF1ZXN0XyAgPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSg0KTsKKyAgICBiYXpfcmVzcG9uc2VfID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoNSk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5zZXJ2aWNlX2NvdW50KCkpOworICAgIHNlcnZpY2VfID0gZm9vX2ZpbGVfLT5zZXJ2aWNlKDApOworCisgICAgQVNTRVJUX0VRKDIsIHNlcnZpY2VfLT5tZXRob2RfY291bnQoKSk7CisgICAgZm9vXyA9IHNlcnZpY2VfLT5tZXRob2QoMCk7CisgICAgYmFyXyA9IHNlcnZpY2VfLT5tZXRob2QoMSk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5zZXJ2aWNlX2NvdW50KCkpOworICAgIHNlcnZpY2UyXyA9IGJhcl9maWxlXy0+c2VydmljZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBzZXJ2aWNlMl8tPm1ldGhvZF9jb3VudCgpKTsKKyAgICBmb28yXyA9IHNlcnZpY2UyXy0+bWV0aG9kKDApOworICAgIGJhejJfID0gc2VydmljZTJfLT5tZXRob2QoMSk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFyX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb19yZXF1ZXN0XzsKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vX3Jlc3BvbnNlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogYmFyX3JlcXVlc3RfOworICBjb25zdCBEZXNjcmlwdG9yKiBiYXJfcmVzcG9uc2VfOworICBjb25zdCBEZXNjcmlwdG9yKiBiYXpfcmVxdWVzdF87CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhel9yZXNwb25zZV87CisKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2VfOworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZTJfOworCisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIGZvb187CisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIGJhcl87CisKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogZm9vMl87CisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIGJhejJfOworfTsKKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTmFtZSkgeworICBFWFBFQ1RfRVEoIlRlc3RTZXJ2aWNlIiwgc2VydmljZV8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdFNlcnZpY2UiLCBzZXJ2aWNlXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoZm9vX2ZpbGVfLCBzZXJ2aWNlXy0+ZmlsZSgpKTsKKworICBFWFBFQ1RfRVEoIlRlc3RTZXJ2aWNlMiIsIHNlcnZpY2UyXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdFNlcnZpY2UyIiwgc2VydmljZTJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUShiYXJfZmlsZV8sIHNlcnZpY2UyXy0+ZmlsZSgpKTsKK30KKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTWV0aG9kc0J5SW5kZXgpIHsKKyAgQVNTRVJUX0VRKDIsIHNlcnZpY2VfLT5tZXRob2RfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb29fLCBzZXJ2aWNlXy0+bWV0aG9kKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIHNlcnZpY2VfLT5tZXRob2QoMSkpOworfQorCitURVNUX0YoU2VydmljZURlc2NyaXB0b3JUZXN0LCBGaW5kTWV0aG9kQnlOYW1lKSB7CisgIEVYUEVDVF9FUShmb29fICwgc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKSk7CisgIEVYUEVDVF9FUShiYXJfICwgc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXIiKSk7CisgIEVYUEVDVF9FUShmb28yXywgc2VydmljZTJfLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKSk7CisgIEVYUEVDVF9FUShiYXoyXywgc2VydmljZTJfLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXoiKSk7CisKKyAgRVhQRUNUX1RSVUUoc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJOb1N1Y2hNZXRob2QiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXoiICAgICAgICAgKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoc2VydmljZTJfLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXIiICAgICAgICAgKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTWV0aG9kTmFtZSkgeworICBFWFBFQ1RfRVEoIkZvbyIsIGZvb18tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiQmFyIiwgYmFyXy0+bmFtZSgpKTsKK30KKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTWV0aG9kRnVsbE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJUZXN0U2VydmljZS5Gb28iLCBmb29fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdFNlcnZpY2UuQmFyIiwgYmFyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5UZXN0U2VydmljZTIuRm9vIiwgZm9vMl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdFNlcnZpY2UyLkJheiIsIGJhejJfLT5mdWxsX25hbWUoKSk7Cit9CisKK1RFU1RfRihTZXJ2aWNlRGVzY3JpcHRvclRlc3QsIE1ldGhvZEluZGV4KSB7CisgIEVYUEVDVF9FUSgwLCBmb29fLT5pbmRleCgpKTsKKyAgRVhQRUNUX0VRKDEsIGJhcl8tPmluZGV4KCkpOworfQorCitURVNUX0YoU2VydmljZURlc2NyaXB0b3JUZXN0LCBNZXRob2RQYXJlbnQpIHsKKyAgRVhQRUNUX0VRKHNlcnZpY2VfLCBmb29fLT5zZXJ2aWNlKCkpOworICBFWFBFQ1RfRVEoc2VydmljZV8sIGJhcl8tPnNlcnZpY2UoKSk7Cit9CisKK1RFU1RfRihTZXJ2aWNlRGVzY3JpcHRvclRlc3QsIE1ldGhvZElucHV0VHlwZSkgeworICBFWFBFQ1RfRVEoZm9vX3JlcXVlc3RfLCBmb29fLT5pbnB1dF90eXBlKCkpOworICBFWFBFQ1RfRVEoYmFyX3JlcXVlc3RfLCBiYXJfLT5pbnB1dF90eXBlKCkpOworfQorCitURVNUX0YoU2VydmljZURlc2NyaXB0b3JUZXN0LCBNZXRob2RPdXRwdXRUeXBlKSB7CisgIEVYUEVDVF9FUShmb29fcmVzcG9uc2VfLCBmb29fLT5vdXRwdXRfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl9yZXNwb25zZV8sIGJhcl8tPm91dHB1dF90eXBlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRlc3QgbmVzdGVkIHR5cGVzLgorY2xhc3MgTmVzdGVkRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIFRlc3RNZXNzYWdlIHsKKyAgICAvLyAgICAgbWVzc2FnZSBGb28ge30KKyAgICAvLyAgICAgbWVzc2FnZSBCYXIge30KKyAgICAvLyAgICAgZW51bSBCYXogeyBBID0gMTsgfQorICAgIC8vICAgICBlbnVtIFF1eCB7IEIgPSAxOyB9CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJiYXIucHJvdG8iCisgICAgLy8gICBwYWNrYWdlIGNvcmdlLmdyYXVsdDsKKyAgICAvLyAgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UyIHsKKyAgICAvLyAgICAgbWVzc2FnZSBGb28ge30KKyAgICAvLyAgICAgbWVzc2FnZSBCYXoge30KKyAgICAvLyAgICAgZW51bSBRdXggIHsgQSA9IDE7IH0KKyAgICAvLyAgICAgZW51bSBRdXV4IHsgQyA9IDE7IH0KKyAgICAvLyAgIH0KKyAgICAvLworICAgIC8vIFRlc3RNZXNzYWdlMiBpcyBwcmltYXJpbHkgaGVyZSB0byB0ZXN0IEZpbmROZXN0ZWRUeXBlQnlOYW1lIGFuZCBmcmllbmRzLgorICAgIC8vIEFsbCBtZXNzYWdlcyBjcmVhdGVkIGZyb20gdGhlIHNhbWUgRGVzY3JpcHRvclBvb2wgc2hhcmUgdGhlIHNhbWUgbG9va3VwCisgICAgLy8gdGFibGUsIHNvIHdlIG5lZWQgdG8gaW5zdXJlIHRoYXQgdGhleSBkb24ndCBpbnRlcmZlcmUuCisgICAgLy8KKyAgICAvLyBXZSBhZGQgZW51bSB2YWx1ZXMgdG8gdGhlIGVudW1zIGluIG9yZGVyIHRvIHRlc3Qgc2VhcmNoaW5nIGZvciBlbnVtCisgICAgLy8gdmFsdWVzIGFjcm9zcyBhIG1lc3NhZ2UncyBzY29wZS4KKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vX2ZpbGU7CisgICAgZm9vX2ZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlID0gQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJUZXN0TWVzc2FnZSIpOworICAgIEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZSwgIkZvbyIpOworICAgIEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZSwgIkJhciIpOworICAgIEVudW1EZXNjcmlwdG9yUHJvdG8qIGJheiA9IEFkZE5lc3RlZEVudW0obWVzc2FnZSwgIkJheiIpOworICAgIEFkZEVudW1WYWx1ZShiYXosICJBIiwgMSk7CisgICAgRW51bURlc2NyaXB0b3JQcm90byogcXV4ID0gQWRkTmVzdGVkRW51bShtZXNzYWdlLCAiUXV4Iik7CisgICAgQWRkRW51bVZhbHVlKHF1eCwgIkIiLCAxKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyX2ZpbGU7CisgICAgYmFyX2ZpbGUuc2V0X25hbWUoImJhci5wcm90byIpOworICAgIGJhcl9maWxlLnNldF9wYWNrYWdlKCJjb3JnZS5ncmF1bHQiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZTIgPSBBZGRNZXNzYWdlKCZiYXJfZmlsZSwgIlRlc3RNZXNzYWdlMiIpOworICAgIEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZTIsICJGb28iKTsKKyAgICBBZGROZXN0ZWRNZXNzYWdlKG1lc3NhZ2UyLCAiQmF6Iik7CisgICAgRW51bURlc2NyaXB0b3JQcm90byogcXV4MiA9IEFkZE5lc3RlZEVudW0obWVzc2FnZTIsICJRdXgiKTsKKyAgICBBZGRFbnVtVmFsdWUocXV4MiwgIkEiLCAxKTsKKyAgICBFbnVtRGVzY3JpcHRvclByb3RvKiBxdXV4MiA9IEFkZE5lc3RlZEVudW0obWVzc2FnZTIsICJRdXV4Iik7CisgICAgQWRkRW51bVZhbHVlKHF1dXgyLCAiQyIsIDEpOworCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIGZvb19maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmb29fZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmFyX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhcl9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgbWVzc2FnZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBtZXNzYWdlXy0+bmVzdGVkX3R5cGVfY291bnQoKSk7CisgICAgZm9vXyA9IG1lc3NhZ2VfLT5uZXN0ZWRfdHlwZSgwKTsKKyAgICBiYXJfID0gbWVzc2FnZV8tPm5lc3RlZF90eXBlKDEpOworCisgICAgQVNTRVJUX0VRKDIsIG1lc3NhZ2VfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgYmF6XyA9IG1lc3NhZ2VfLT5lbnVtX3R5cGUoMCk7CisgICAgcXV4XyA9IG1lc3NhZ2VfLT5lbnVtX3R5cGUoMSk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmF6Xy0+dmFsdWVfY291bnQoKSk7CisgICAgYV8gPSBiYXpfLT52YWx1ZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgcXV4Xy0+dmFsdWVfY291bnQoKSk7CisgICAgYl8gPSBxdXhfLT52YWx1ZSgwKTsKKworICAgIEFTU0VSVF9FUSgxLCBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBtZXNzYWdlMl8gPSBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMl8tPm5lc3RlZF90eXBlX2NvdW50KCkpOworICAgIGZvbzJfID0gbWVzc2FnZTJfLT5uZXN0ZWRfdHlwZSgwKTsKKyAgICBiYXoyXyA9IG1lc3NhZ2UyXy0+bmVzdGVkX3R5cGUoMSk7CisKKyAgICBBU1NFUlRfRVEoMiwgbWVzc2FnZTJfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgcXV4Ml8gPSBtZXNzYWdlMl8tPmVudW1fdHlwZSgwKTsKKyAgICBxdXV4Ml8gPSBtZXNzYWdlMl8tPmVudW1fdHlwZSgxKTsKKworICAgIEFTU0VSVF9FUSgxLCBxdXgyXy0+dmFsdWVfY291bnQoKSk7CisgICAgYTJfID0gcXV4Ml8tPnZhbHVlKDApOworICAgIEFTU0VSVF9FUSgxLCBxdXV4Ml8tPnZhbHVlX2NvdW50KCkpOworICAgIGMyXyA9IHF1dXgyXy0+dmFsdWUoMCk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFyX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlMl87CisKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vXzsKKyAgY29uc3QgRGVzY3JpcHRvciogYmFyXzsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGJhel87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBxdXhfOworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBhXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYl87CisKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vMl87CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhejJfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogcXV4Ml87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBxdXV4Ml87CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGEyXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYzJfOworfTsKKworVEVTVF9GKE5lc3RlZERlc2NyaXB0b3JUZXN0LCBNZXNzYWdlTmFtZSkgeworICBFWFBFQ1RfRVEoIkZvbyIsIGZvb18gLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJhciIsIGJhcl8gLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkZvbyIsIGZvbzJfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJheiIsIGJhejJfLT5uYW1lKCkpOworCisgIEVYUEVDVF9FUSgiVGVzdE1lc3NhZ2UuRm9vIiwgZm9vXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLkJhciIsIGJhcl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdE1lc3NhZ2UyLkZvbyIsIGZvbzJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5CYXoiLCBiYXoyXy0+ZnVsbF9uYW1lKCkpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIE1lc3NhZ2VDb250YWluaW5nVHlwZSkgeworICBFWFBFQ1RfRVEobWVzc2FnZV8gLCBmb29fIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV8gLCBiYXJfIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTJfLCBmb28yXy0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTJfLCBiYXoyXy0+Y29udGFpbmluZ190eXBlKCkpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIE5lc3RlZE1lc3NhZ2VzQnlJbmRleCkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZV8tPm5lc3RlZF90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPm5lc3RlZF90eXBlKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5uZXN0ZWRfdHlwZSgxKSk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZEZpZWxkQnlOYW1lRG9lc250RmluZE5lc3RlZFR5cGVzKSB7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlOYW1lKCJRdXgiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiUXV4IikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZE5lc3RlZFR5cGVCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKGZvb18gLCBtZXNzYWdlXyAtPkZpbmROZXN0ZWRUeXBlQnlOYW1lKCJGb28iKSk7CisgIEVYUEVDVF9FUShiYXJfICwgbWVzc2FnZV8gLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZSgiQmFyIikpOworICBFWFBFQ1RfRVEoZm9vMl8sIG1lc3NhZ2UyXy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIkZvbyIpKTsKKyAgRVhQRUNUX0VRKGJhejJfLCBtZXNzYWdlMl8tPkZpbmROZXN0ZWRUeXBlQnlOYW1lKCJCYXoiKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8gLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZSgiTm9TdWNoVHlwZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXyAtPkZpbmROZXN0ZWRUeXBlQnlOYW1lKCJCYXoiICAgICAgICkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIkJhciIgICAgICAgKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIlF1eCIpID09IE5VTEwpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIEVudW1OYW1lKSB7CisgIEVYUEVDVF9FUSgiQmF6IiAsIGJhel8gLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIlF1eCIgLCBxdXhfIC0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJRdXgiICwgcXV4Ml8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiUXV1eCIsIHF1dXgyXy0+bmFtZSgpKTsKKworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLkJheiIsIGJhel8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZS5RdXgiLCBxdXhfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5RdXgiICwgcXV4Ml8gLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5RdXV4IiwgcXV1eDJfLT5mdWxsX25hbWUoKSk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRW51bUNvbnRhaW5pbmdUeXBlKSB7CisgIEVYUEVDVF9FUShtZXNzYWdlXyAsIGJhel8gIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV8gLCBxdXhfICAtPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyXywgcXV4Ml8gLT5jb250YWluaW5nX3R5cGUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMl8sIHF1dXgyXy0+Y29udGFpbmluZ190eXBlKCkpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIE5lc3RlZEVudW1zQnlJbmRleCkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZV8tPm5lc3RlZF90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPm5lc3RlZF90eXBlKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5uZXN0ZWRfdHlwZSgxKSk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZEVudW1UeXBlQnlOYW1lKSB7CisgIEVYUEVDVF9FUShiYXpfICAsIG1lc3NhZ2VfIC0+RmluZEVudW1UeXBlQnlOYW1lKCJCYXoiICkpOworICBFWFBFQ1RfRVEocXV4XyAgLCBtZXNzYWdlXyAtPkZpbmRFbnVtVHlwZUJ5TmFtZSgiUXV4IiApKTsKKyAgRVhQRUNUX0VRKHF1eDJfICwgbWVzc2FnZTJfLT5GaW5kRW51bVR5cGVCeU5hbWUoIlF1eCIgKSk7CisgIEVYUEVDVF9FUShxdXV4Ml8sIG1lc3NhZ2UyXy0+RmluZEVudW1UeXBlQnlOYW1lKCJRdXV4IikpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfIC0+RmluZEVudW1UeXBlQnlOYW1lKCJOb1N1Y2hUeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfIC0+RmluZEVudW1UeXBlQnlOYW1lKCJRdXV4IiAgICAgICkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+RmluZEVudW1UeXBlQnlOYW1lKCJCYXoiICAgICAgICkgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZEVudW1WYWx1ZUJ5TmFtZSkgeworICBFWFBFQ1RfRVEoYV8gLCBtZXNzYWdlXyAtPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkEiKSk7CisgIEVYUEVDVF9FUShiXyAsIG1lc3NhZ2VfIC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiQiIpKTsKKyAgRVhQRUNUX0VRKGEyXywgbWVzc2FnZTJfLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJBIikpOworICBFWFBFQ1RfRVEoYzJfLCBtZXNzYWdlMl8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkMiKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8gLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfIC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiQyIgICAgICAgICAgICApID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMl8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkIiICAgICAgICAgICAgKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBleHRlbnNpb25zLgorY2xhc3MgRXh0ZW5zaW9uRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIGVudW0gQmF6IHt9CisgICAgLy8gICBtZXNzYWdlIFF1eCB7fQorICAgIC8vCisgICAgLy8gICBtZXNzYWdlIEZvbyB7CisgICAgLy8gICAgIGV4dGVuc2lvbnMgMTAgdG8gMTk7CisgICAgLy8gICAgIGV4dGVuc2lvbnMgMzAgdG8gMzk7CisgICAgLy8gICB9CisgICAgLy8gICBleHRlbmRzIEZvbyB3aXRoIG9wdGlvbmFsIGludDMyIGZvb19pbnQzMiA9IDEwOworICAgIC8vICAgZXh0ZW5kcyBGb28gd2l0aCByZXBlYXRlZCBUZXN0RW51bSBmb29fZW51bSA9IDE5OworICAgIC8vICAgbWVzc2FnZSBCYXIgeworICAgIC8vICAgICBleHRlbmRzIEZvbyB3aXRoIG9wdGlvbmFsIFF1eCBmb29fbWVzc2FnZSA9IDMwOworICAgIC8vICAgICAvLyAodXNpbmcgUXV4IGFzIHRoZSBncm91cCB0eXBlKQorICAgIC8vICAgICBleHRlbmRzIEZvbyB3aXRoIHJlcGVhdGVkIGdyb3VwIGZvb19ncm91cCA9IDM5OworICAgIC8vICAgfQorCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fZmlsZTsKKyAgICBmb29fZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisKKyAgICBBZGRFbXB0eUVudW0oJmZvb19maWxlLCAiQmF6Iik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJRdXgiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogZm9vID0gQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJGb28iKTsKKyAgICBBZGRFeHRlbnNpb25SYW5nZShmb28sIDEwLCAyMCk7CisgICAgQWRkRXh0ZW5zaW9uUmFuZ2UoZm9vLCAzMCwgNDApOworCisgICAgQWRkRXh0ZW5zaW9uKCZmb29fZmlsZSwgIkZvbyIsICJmb29faW50MzIiLCAxMCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRXh0ZW5zaW9uKCZmb29fZmlsZSwgIkZvbyIsICJmb29fZW51bSIsIDE5LAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0VOVU0pCisgICAgICAtPnNldF90eXBlX25hbWUoIkJheiIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBiYXIgPSBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkJhciIpOworICAgIEFkZE5lc3RlZEV4dGVuc2lvbihiYXIsICJGb28iLCAiZm9vX21lc3NhZ2UiLCAzMCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFKQorICAgICAgLT5zZXRfdHlwZV9uYW1lKCJRdXgiKTsKKyAgICBBZGROZXN0ZWRFeHRlbnNpb24oYmFyLCAiRm9vIiwgImZvb19ncm91cCIsIDM5LAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQKQorICAgICAgLT5zZXRfdHlwZV9uYW1lKCJRdXgiKTsKKworICAgIC8vIEJ1aWxkIHRoZSBkZXNjcmlwdG9ycyBhbmQgZ2V0IHRoZSBwb2ludGVycy4KKyAgICBmb29fZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoZm9vX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGZvb19maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpKTsKKyAgICBiYXpfID0gZm9vX2ZpbGVfLT5lbnVtX3R5cGUoMCk7CisKKyAgICBBU1NFUlRfRVEoMywgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgcXV4XyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworICAgIGZvb18gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgxKTsKKyAgICBiYXJfID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMik7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb187CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhcl87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBiYXpfOworICBjb25zdCBEZXNjcmlwdG9yKiBxdXhfOworfTsKKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBFeHRlbnNpb25SYW5nZXMpIHsKKyAgRVhQRUNUX0VRKDAsIGJhcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKDIsIGZvb18tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpKTsKKworICBFWFBFQ1RfRVEoMTAsIGZvb18tPmV4dGVuc2lvbl9yYW5nZSgwKS0+c3RhcnQpOworICBFWFBFQ1RfRVEoMzAsIGZvb18tPmV4dGVuc2lvbl9yYW5nZSgxKS0+c3RhcnQpOworCisgIEVYUEVDVF9FUSgyMCwgZm9vXy0+ZXh0ZW5zaW9uX3JhbmdlKDApLT5lbmQpOworICBFWFBFQ1RfRVEoNDAsIGZvb18tPmV4dGVuc2lvbl9yYW5nZSgxKS0+ZW5kKTsKK307CisKK1RFU1RfRihFeHRlbnNpb25EZXNjcmlwdG9yVGVzdCwgRXh0ZW5zaW9ucykgeworICBFWFBFQ1RfRVEoMCwgZm9vXy0+ZXh0ZW5zaW9uX2NvdW50KCkpOworICBBU1NFUlRfRVEoMiwgZm9vX2ZpbGVfLT5leHRlbnNpb25fY291bnQoKSk7CisgIEFTU0VSVF9FUSgyLCBiYXJfLT5leHRlbnNpb25fY291bnQoKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPmlzX2V4dGVuc2lvbigpKTsKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPmlzX2V4dGVuc2lvbigpKTsKKyAgRVhQRUNUX1RSVUUoYmFyXy0+ZXh0ZW5zaW9uKDApLT5pc19leHRlbnNpb24oKSk7CisgIEVYUEVDVF9UUlVFKGJhcl8tPmV4dGVuc2lvbigxKS0+aXNfZXh0ZW5zaW9uKCkpOworCisgIEVYUEVDVF9FUSgiZm9vX2ludDMyIiAgLCBmb29fZmlsZV8tPmV4dGVuc2lvbigwKS0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmb29fZW51bSIgICAsIGZvb19maWxlXy0+ZXh0ZW5zaW9uKDEpLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb19tZXNzYWdlIiwgYmFyXy0+ZXh0ZW5zaW9uKDApLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb19ncm91cCIgICwgYmFyXy0+ZXh0ZW5zaW9uKDEpLT5uYW1lKCkpOworCisgIEVYUEVDVF9FUSgxMCwgZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPm51bWJlcigpKTsKKyAgRVhQRUNUX0VRKDE5LCBmb29fZmlsZV8tPmV4dGVuc2lvbigxKS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMzAsIGJhcl8tPmV4dGVuc2lvbigwKS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMzksIGJhcl8tPmV4dGVuc2lvbigxKS0+bnVtYmVyKCkpOworCisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICwgZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPnR5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICwgZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPnR5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgYmFyXy0+ZXh0ZW5zaW9uKDApLT50eXBlKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAsIGJhcl8tPmV4dGVuc2lvbigxKS0+dHlwZSgpKTsKKworICBFWFBFQ1RfRVEoYmF6XywgZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPmVudW1fdHlwZSgpKTsKKyAgRVhQRUNUX0VRKHF1eF8sIGJhcl8tPmV4dGVuc2lvbigwKS0+bWVzc2FnZV90eXBlKCkpOworICBFWFBFQ1RfRVEocXV4XywgYmFyXy0+ZXh0ZW5zaW9uKDEpLT5tZXNzYWdlX3R5cGUoKSk7CisKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwsIGZvb19maWxlXy0+ZXh0ZW5zaW9uKDApLT5sYWJlbCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQsIGZvb19maWxlXy0+ZXh0ZW5zaW9uKDEpLT5sYWJlbCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwsIGJhcl8tPmV4dGVuc2lvbigwKS0+bGFiZWwoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVELCBiYXJfLT5leHRlbnNpb24oMSktPmxhYmVsKCkpOworCisgIEVYUEVDVF9FUShmb29fLCBmb29fZmlsZV8tPmV4dGVuc2lvbigwKS0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEoZm9vXywgZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKGZvb18sIGJhcl8tPmV4dGVuc2lvbigwKS0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEoZm9vXywgYmFyXy0+ZXh0ZW5zaW9uKDEpLT5jb250YWluaW5nX3R5cGUoKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPmV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPmV4dGVuc2lvbigxKS0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9FUShiYXJfLCBiYXJfLT5leHRlbnNpb24oMCktPmV4dGVuc2lvbl9zY29wZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl8sIGJhcl8tPmV4dGVuc2lvbigxKS0+ZXh0ZW5zaW9uX3Njb3BlKCkpOworfTsKKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBJc0V4dGVuc2lvbk51bWJlcikgeworICBFWFBFQ1RfRkFMU0UoZm9vXy0+SXNFeHRlbnNpb25OdW1iZXIoIDkpKTsKKyAgRVhQRUNUX1RSVUUgKGZvb18tPklzRXh0ZW5zaW9uTnVtYmVyKDEwKSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc0V4dGVuc2lvbk51bWJlcigxOSkpOworICBFWFBFQ1RfRkFMU0UoZm9vXy0+SXNFeHRlbnNpb25OdW1iZXIoMjApKTsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzRXh0ZW5zaW9uTnVtYmVyKDI5KSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc0V4dGVuc2lvbk51bWJlcigzMCkpOworICBFWFBFQ1RfVFJVRSAoZm9vXy0+SXNFeHRlbnNpb25OdW1iZXIoMzkpKTsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzRXh0ZW5zaW9uTnVtYmVyKDQwKSk7Cit9CisKK1RFU1RfRihFeHRlbnNpb25EZXNjcmlwdG9yVGVzdCwgRmluZEV4dGVuc2lvbkJ5TmFtZSkgeworICAvLyBOb3RlIHRoYXQgRmlsZURlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeU5hbWUoKSBpcyB0ZXN0ZWQgYnkKKyAgLy8gRmlsZURlc2NyaXB0b3JUZXN0LgorICBBU1NFUlRfRVEoMiwgYmFyXy0+ZXh0ZW5zaW9uX2NvdW50KCkpOworCisgIEVYUEVDVF9FUShiYXJfLT5leHRlbnNpb24oMCksIGJhcl8tPkZpbmRFeHRlbnNpb25CeU5hbWUoImZvb19tZXNzYWdlIikpOworICBFWFBFQ1RfRVEoYmFyXy0+ZXh0ZW5zaW9uKDEpLCBiYXJfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJmb29fZ3JvdXAiICApKTsKKworICBFWFBFQ1RfVFJVRShiYXJfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJub19zdWNoX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJmb29faW50MzIiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiZm9vX21lc3NhZ2UiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBGaW5kQWxsRXh0ZW5zaW9ucykgeworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZXh0ZW5zaW9uczsKKyAgcG9vbF8uRmluZEFsbEV4dGVuc2lvbnMoZm9vXywgJmV4dGVuc2lvbnMpOworICBBU1NFUlRfRVEoNCwgZXh0ZW5zaW9ucy5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIGV4dGVuc2lvbnNbMF0tPm51bWJlcigpKTsKKyAgRVhQRUNUX0VRKDE5LCBleHRlbnNpb25zWzFdLT5udW1iZXIoKSk7CisgIEVYUEVDVF9FUSgzMCwgZXh0ZW5zaW9uc1syXS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMzksIGV4dGVuc2lvbnNbM10tPm51bWJlcigpKTsKK30KKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBEdXBsaWNhdGVGaWVsZE51bWJlcikgeworICBEZXNjcmlwdG9yUG9vbCBwb29sOworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIC8vIEFkZCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iLgorICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisgIC8vIEFkZCAiZm9vLnByb3RvIjoKKyAgLy8gICBpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIjsKKyAgLy8gICBleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyB7CisgIC8vICAgICBvcHRpb25hbCBpbnQzMiBvcHRpb24xID0gMTAwMDsKKyAgLy8gICB9CisgIGZpbGVfcHJvdG8uQ2xlYXIoKTsKKyAgZmlsZV9wcm90by5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIGZpbGVfcHJvdG8uYWRkX2RlcGVuZGVuY3koImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIik7CisgIEFkZEV4dGVuc2lvbigmZmlsZV9wcm90bywgImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMiLCAib3B0aW9uMSIsIDEwMDAsCisgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworICAvLyBBZGQgImJhci5wcm90byI6CisgIC8vICAgaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byI7CisgIC8vICAgZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgeworICAvLyAgICAgb3B0aW9uYWwgaW50MzIgb3B0aW9uMiA9IDEwMDA7CisgIC8vICAgfQorICBmaWxlX3Byb3RvLkNsZWFyKCk7CisgIGZpbGVfcHJvdG8uc2V0X25hbWUoImJhci5wcm90byIpOworICBmaWxlX3Byb3RvLmFkZF9kZXBlbmRlbmN5KCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIpOworICBBZGRFeHRlbnNpb24oJmZpbGVfcHJvdG8sICJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIiwgIm9wdGlvbjIiLCAxMDAwLAorICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAvLyBDdXJyZW50bHkgd2Ugb25seSBnZW5lcmF0ZSBhIHdhcm5pbmcgZm9yIGNvbmZsaWN0aW5nIGV4dGVuc2lvbiBudW1iZXJzLgorICAvLyBUT0RPKHhpYW9mZW5nKTogQ2hhbmdlIGl0IHRvIGFuIGVycm9yLgorICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBNaXNjVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIC8vIEZ1bmN0aW9uIHdoaWNoIG1ha2VzIGEgZmllbGQgZGVzY3JpcHRvciBvZiB0aGUgZ2l2ZW4gdHlwZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZXRGaWVsZERlc2NyaXB0b3JPZlR5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgZmlsZV9wcm90by5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgICAgQWRkRW1wdHlFbnVtKCZmaWxlX3Byb3RvLCAiRHVtbXlFbnVtIik7CisKKyAgICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UgPSBBZGRNZXNzYWdlKCZmaWxlX3Byb3RvLCAiVGVzdE1lc3NhZ2UiKTsKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQgPQorICAgICAgQWRkRmllbGQobWVzc2FnZSwgImZvbyIsIDEsIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlPihzdGF0aWNfY2FzdDxpbnQ+KHR5cGUpKSk7CisKKyAgICBpZiAodHlwZSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSB8fAorICAgICAgICB0eXBlID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgICAgZmllbGQtPnNldF90eXBlX25hbWUoIlRlc3RNZXNzYWdlIik7CisgICAgfSBlbHNlIGlmICh0eXBlID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNKSB7CisgICAgICBmaWVsZC0+c2V0X3R5cGVfbmFtZSgiRHVtbXlFbnVtIik7CisgICAgfQorCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIHBvb2xfLnJlc2V0KG5ldyBEZXNjcmlwdG9yUG9vbCgpKTsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2xfLT5CdWlsZEZpbGUoZmlsZV9wcm90byk7CisKKyAgICBpZiAoZmlsZSAhPSBOVUxMICYmCisgICAgICAgIGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpID09IDEgJiYKKyAgICAgICAgZmlsZS0+bWVzc2FnZV90eXBlKDApLT5maWVsZF9jb3VudCgpID09IDEpIHsKKyAgICAgIHJldHVybiBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPmZpZWxkKDApOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgIH0KKworICBjb25zdCBjaGFyKiBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBHZXRGaWVsZERlc2NyaXB0b3JPZlR5cGUodHlwZSk7CisgICAgcmV0dXJuIGZpZWxkICE9IE5VTEwgPyBmaWVsZC0+dHlwZV9uYW1lKCkgOiAiIjsKKyAgfQorCisgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IEdldEZpZWxkRGVzY3JpcHRvck9mVHlwZSh0eXBlKTsKKyAgICByZXR1cm4gZmllbGQgIT0gTlVMTCA/IGZpZWxkLT5jcHBfdHlwZSgpIDoKKyAgICAgICAgc3RhdGljX2Nhc3Q8RmllbGREZXNjcmlwdG9yOjpDcHBUeXBlPigwKTsKKyAgfQorCisgIGNvbnN0IGNoYXIqIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IEdldEZpZWxkRGVzY3JpcHRvck9mVHlwZSh0eXBlKTsKKyAgICByZXR1cm4gZmllbGQgIT0gTlVMTCA/IGZpZWxkLT5jcHBfdHlwZV9uYW1lKCkgOiAiIjsKKyAgfQorCisgIGNvbnN0IERlc2NyaXB0b3IqIEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKAorICAgICAgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gR2V0RmllbGREZXNjcmlwdG9yT2ZUeXBlKHR5cGUpOworICAgIHJldHVybiBmaWVsZCAhPSBOVUxMID8gZmllbGQtPm1lc3NhZ2VfdHlwZSgpIDogTlVMTDsKKyAgfQorCisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZSgKKyAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBHZXRGaWVsZERlc2NyaXB0b3JPZlR5cGUodHlwZSk7CisgICAgcmV0dXJuIGZpZWxkICE9IE5VTEwgPyBmaWVsZC0+ZW51bV90eXBlKCkgOiBOVUxMOworICB9CisKKyAgc2NvcGVkX3B0cjxEZXNjcmlwdG9yUG9vbD4gcG9vbF87Cit9OworCitURVNUX0YoTWlzY1Rlc3QsIFR5cGVOYW1lcykgeworICAvLyBUZXN0IHRoYXQgY29ycmVjdCB0eXBlIG5hbWVzIGFyZSByZXR1cm5lZC4KKworICB0eXBlZGVmIEZpZWxkRGVzY3JpcHRvciBGRDsgIC8vIGF2b2lkIHVnbHkgbGluZSB3cmFwcGluZworCisgIEVYUEVDVF9TVFJFUSgiZG91YmxlIiAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9ET1VCTEUgICkpOworICBFWFBFQ1RfU1RSRVEoImZsb2F0IiAgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRkxPQVQgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJpbnQ2NCIgICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDY0ICAgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDY0IiAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UNjQgICkpOworICBFWFBFQ1RfU1RSRVEoImludDMyIiAgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfSU5UMzIgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJmaXhlZDY0IiAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVENjQgKSk7CisgIEVYUEVDVF9TVFJFUSgiZml4ZWQzMiIgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDMyICkpOworICBFWFBFQ1RfU1RSRVEoImJvb2wiICAgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfQk9PTCAgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJzdHJpbmciICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NUUklORyAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZ3JvdXAiICAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9HUk9VUCAgICkpOworICBFWFBFQ1RfU1RSRVEoIm1lc3NhZ2UiICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfTUVTU0FHRSApKTsKKyAgRVhQRUNUX1NUUkVRKCJieXRlcyIgICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JZVEVTICAgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDMyIiAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UMzIgICkpOworICBFWFBFQ1RfU1RSRVEoImVudW0iICAgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRU5VTSAgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJzZml4ZWQzMiIsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDMyKSk7CisgIEVYUEVDVF9TVFJFUSgic2ZpeGVkNjQiLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQ2NCkpOworICBFWFBFQ1RfU1RSRVEoInNpbnQzMiIgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0lOVDMyICApKTsKKyAgRVhQRUNUX1NUUkVRKCJzaW50NjQiICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQ2NCAgKSk7Cit9CisKK1RFU1RfRihNaXNjVGVzdCwgU3RhdGljVHlwZU5hbWVzKSB7CisgIC8vIFRlc3QgdGhhdCBjb3JyZWN0IHR5cGUgbmFtZXMgYXJlIHJldHVybmVkLgorCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yIEZEOyAgLy8gYXZvaWQgdWdseSBsaW5lIHdyYXBwaW5nCisKKyAgRVhQRUNUX1NUUkVRKCJkb3VibGUiICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9ET1VCTEUgICkpOworICBFWFBFQ1RfU1RSRVEoImZsb2F0IiAgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0ZMT0FUICAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50NjQiICAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfSU5UNjQgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJ1aW50NjQiICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9VSU5UNjQgICkpOworICBFWFBFQ1RfU1RSRVEoImludDMyIiAgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0lOVDMyICAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZml4ZWQ2NCIgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfRklYRUQ2NCApKTsKKyAgRVhQRUNUX1NUUkVRKCJmaXhlZDMyIiAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9GSVhFRDMyICkpOworICBFWFBFQ1RfU1RSRVEoImJvb2wiICAgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0JPT0wgICAgKSk7CisgIEVYUEVDVF9TVFJFUSgic3RyaW5nIiAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfU1RSSU5HICApKTsKKyAgRVhQRUNUX1NUUkVRKCJncm91cCIgICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9HUk9VUCAgICkpOworICBFWFBFQ1RfU1RSRVEoIm1lc3NhZ2UiICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX01FU1NBR0UgKSk7CisgIEVYUEVDVF9TVFJFUSgiYnl0ZXMiICAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfQllURVMgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJ1aW50MzIiICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9VSU5UMzIgICkpOworICBFWFBFQ1RfU1RSRVEoImVudW0iICAgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0VOVU0gICAgKSk7CisgIEVYUEVDVF9TVFJFUSgic2ZpeGVkMzIiLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfU0ZJWEVEMzIpKTsKKyAgRVhQRUNUX1NUUkVRKCJzZml4ZWQ2NCIsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9TRklYRUQ2NCkpOworICBFWFBFQ1RfU1RSRVEoInNpbnQzMiIgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX1NJTlQzMiAgKSk7CisgIEVYUEVDVF9TVFJFUSgic2ludDY0IiAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfU0lOVDY0ICApKTsKK30KKworVEVTVF9GKE1pc2NUZXN0LCBDcHBUeXBlcykgeworICAvLyBUZXN0IHRoYXQgQ1BQIHR5cGVzIGFyZSBhc3NpZ25lZCBjb3JyZWN0bHkuCisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCB1Z2x5IGxpbmUgd3JhcHBpbmcKKworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfRE9VQkxFICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9ET1VCTEUgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfRkxPQVQgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GTE9BVCAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfSU5UNjQgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQ2NCAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfVUlOVDY0ICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UNjQgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfSU5UMzIgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQzMiAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfVUlOVDY0ICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDY0ICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfVUlOVDMyICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDMyICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfQk9PTCAgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9CT09MICAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfU1RSSU5HICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TVFJJTkcgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfTUVTU0FHRSwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9HUk9VUCAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfTUVTU0FHRSwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9NRVNTQUdFICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfU1RSSU5HICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9CWVRFUyAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfVUlOVDMyICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UMzIgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfRU5VTSAgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9FTlVNICAgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfSU5UMzIgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQzMikpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfSU5UNjQgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQ2NCkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfSU5UMzIgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UMzIgICkpOworICBFWFBFQ1RfRVEoRkQ6OkNQUFRZUEVfSU5UNjQgICwgR2V0Q3BwVHlwZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UNjQgICkpOworfQorCitURVNUX0YoTWlzY1Rlc3QsIENwcFR5cGVOYW1lcykgeworICAvLyBUZXN0IHRoYXQgY29ycmVjdCBDUFAgdHlwZSBuYW1lcyBhcmUgcmV0dXJuZWQuCisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCB1Z2x5IGxpbmUgd3JhcHBpbmcKKworICBFWFBFQ1RfU1RSRVEoImRvdWJsZSIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9ET1VCTEUgICkpOworICBFWFBFQ1RfU1RSRVEoImZsb2F0IiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GTE9BVCAgICkpOworICBFWFBFQ1RfU1RSRVEoImludDY0IiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQ2NCAgICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQ2NCIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UNjQgICkpOworICBFWFBFQ1RfU1RSRVEoImludDMyIiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQzMiAgICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQ2NCIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDY0ICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQzMiIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDMyICkpOworICBFWFBFQ1RfU1RSRVEoImJvb2wiICAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9CT09MICAgICkpOworICBFWFBFQ1RfU1RSRVEoInN0cmluZyIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TVFJJTkcgICkpOworICBFWFBFQ1RfU1RSRVEoIm1lc3NhZ2UiLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9HUk9VUCAgICkpOworICBFWFBFQ1RfU1RSRVEoIm1lc3NhZ2UiLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9NRVNTQUdFICkpOworICBFWFBFQ1RfU1RSRVEoInN0cmluZyIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9CWVRFUyAgICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQzMiIgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UMzIgICkpOworICBFWFBFQ1RfU1RSRVEoImVudW0iICAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9FTlVNICAgICkpOworICBFWFBFQ1RfU1RSRVEoImludDMyIiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQzMikpOworICBFWFBFQ1RfU1RSRVEoImludDY0IiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQ2NCkpOworICBFWFBFQ1RfU1RSRVEoImludDMyIiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UMzIgICkpOworICBFWFBFQ1RfU1RSRVEoImludDY0IiAgLCBHZXRDcHBUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UNjQgICkpOworfQorCitURVNUX0YoTWlzY1Rlc3QsIFN0YXRpY0NwcFR5cGVOYW1lcykgeworICAvLyBUZXN0IHRoYXQgY29ycmVjdCBDUFAgdHlwZSBuYW1lcyBhcmUgcmV0dXJuZWQuCisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCB1Z2x5IGxpbmUgd3JhcHBpbmcKKworICBFWFBFQ1RfU1RSRVEoImludDMyIiAgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfSU5UMzIgICkpOworICBFWFBFQ1RfU1RSRVEoImludDY0IiAgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfSU5UNjQgICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQzMiIgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfVUlOVDMyICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQ2NCIgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfVUlOVDY0ICkpOworICBFWFBFQ1RfU1RSRVEoImRvdWJsZSIgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfRE9VQkxFICkpOworICBFWFBFQ1RfU1RSRVEoImZsb2F0IiAgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfRkxPQVQgICkpOworICBFWFBFQ1RfU1RSRVEoImJvb2wiICAgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfQk9PTCAgICkpOworICBFWFBFQ1RfU1RSRVEoImVudW0iICAgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfRU5VTSAgICkpOworICBFWFBFQ1RfU1RSRVEoInN0cmluZyIgLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfU1RSSU5HICkpOworICBFWFBFQ1RfU1RSRVEoIm1lc3NhZ2UiLCBGRDo6Q3BwVHlwZU5hbWUoRkQ6OkNQUFRZUEVfTUVTU0FHRSkpOworfQorCitURVNUX0YoTWlzY1Rlc3QsIE1lc3NhZ2VUeXBlKSB7CisgIC8vIFRlc3QgdGhhdCBtZXNzYWdlX3R5cGUoKSBpcyBOVUxMIGZvciBub24tYWdncmVnYXRlIGZpZWxkcworCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yIEZEOyAgLy8gYXZvaWQgdWdseSBsaW5lIHdyYXBwaW5nCisKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9ET1VCTEUgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZMT0FUICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfSU5UNjQgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UNjQgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDMyICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRklYRUQ2NCApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDMyICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JPT0wgICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU1RSSU5HICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCAhPSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9HUk9VUCAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMICE9IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX01FU1NBR0UgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfQllURVMgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9VSU5UMzIgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0VOVU0gICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0ZJWEVEMzIpKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQ2NCkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQzMiAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0lOVDY0ICApKTsKK30KKworVEVTVF9GKE1pc2NUZXN0LCBFbnVtVHlwZSkgeworICAvLyBUZXN0IHRoYXQgZW51bV90eXBlKCkgaXMgTlVMTCBmb3Igbm9uLWVudW0gZmllbGRzCisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCB1Z2x5IGxpbmUgd3JhcHBpbmcKKworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0RPVUJMRSAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRkxPQVQgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQ2NCAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQ2NCAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfSU5UMzIgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDY0ICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVEMzIgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfQk9PTCAgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TVFJJTkcgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0dST1VQICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfTUVTU0FHRSApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9CWVRFUyAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQzMiAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgIT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRU5VTSAgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQzMikpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDY0KSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0lOVDMyICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UNjQgICkpOworfQorCisKK1RFU1RfRihNaXNjVGVzdCwgRGVmYXVsdFZhbHVlcykgeworICAvLyBUZXN0IHRoYXQgc2V0dGluZyBkZWZhdWx0IHZhbHVlcyB3b3Jrcy4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlX3Byb3RvLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKworICBFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3R5cGVfcHJvdG8gPSBBZGRFbnVtKCZmaWxlX3Byb3RvLCAiRHVtbXlFbnVtIik7CisgIEFkZEVudW1WYWx1ZShlbnVtX3R5cGVfcHJvdG8sICJBIiwgMSk7CisgIEFkZEVudW1WYWx1ZShlbnVtX3R5cGVfcHJvdG8sICJCIiwgMik7CisKKyAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlX3Byb3RvID0gQWRkTWVzc2FnZSgmZmlsZV9wcm90bywgIlRlc3RNZXNzYWdlIik7CisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3JQcm90byBGRDsgIC8vIGF2b2lkIHVnbHkgbGluZSB3cmFwcGluZworICBjb25zdCBGRDo6TGFiZWwgbGFiZWwgPSBGRDo6TEFCRUxfT1BUSU9OQUw7CisKKyAgLy8gQ3JlYXRlIGZpZWxkcyBvZiBldmVyeSBDUFAgdHlwZSB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiaW50MzIiICwgMSwgbGFiZWwsIEZEOjpUWVBFX0lOVDMyICkKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCItMSIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiaW50NjQiICwgMiwgbGFiZWwsIEZEOjpUWVBFX0lOVDY0ICkKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCItMTAwMDAwMDAwMDAwMCIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAidWludDMyIiwgMywgbGFiZWwsIEZEOjpUWVBFX1VJTlQzMikKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCI0MiIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAidWludDY0IiwgNCwgbGFiZWwsIEZEOjpUWVBFX1VJTlQ2NCkKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCIyMDAwMDAwMDAwMDAwIik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJmbG9hdCIgLCA1LCBsYWJlbCwgRkQ6OlRZUEVfRkxPQVQgKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIjQuNSIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiZG91YmxlIiwgNiwgbGFiZWwsIEZEOjpUWVBFX0RPVUJMRSkKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCIxMGUxMDAiKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImJvb2wiICAsIDcsIGxhYmVsLCBGRDo6VFlQRV9CT09MICApCisgICAgLT5zZXRfZGVmYXVsdF92YWx1ZSgidHJ1ZSIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAic3RyaW5nIiwgOCwgbGFiZWwsIEZEOjpUWVBFX1NUUklORykKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCJoZWxsbyIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiZGF0YSIgICwgOSwgbGFiZWwsIEZEOjpUWVBFX0JZVEVTICkKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCJcXDAwMVxcMDAyXFwwMDMiKTsKKworICBGaWVsZERlc2NyaXB0b3JQcm90byogZW51bV9maWVsZCA9CisgICAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImVudW0iLCAxMCwgbGFiZWwsIEZEOjpUWVBFX0VOVU0pOworICBlbnVtX2ZpZWxkLT5zZXRfdHlwZV9uYW1lKCJEdW1teUVudW0iKTsKKyAgZW51bV9maWVsZC0+c2V0X2RlZmF1bHRfdmFsdWUoIkIiKTsKKworICAvLyBTdHJpbmdzIGFyZSBhbGxvd2VkIHRvIGhhdmUgZW1wdHkgZGVmYXVsdHMuICAoQXQgb25lIHBvaW50LCBkdWUgdG8KKyAgLy8gYSBidWcsIGVtcHR5IGRlZmF1bHRzIGZvciBzdHJpbmdzIHdlcmUgcmVqZWN0ZWQuICBPb3BzLikKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImVtcHR5X3N0cmluZyIsIDExLCBsYWJlbCwgRkQ6OlRZUEVfU1RSSU5HKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIiIpOworCisgIC8vIEFkZCBhIHNlY29uZCBzZXQgb2YgZmllbGRzIHdpdGggaW1wbGljaXQgZGVmYWx1dCB2YWx1ZXMuCisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9pbnQzMiIgLCAyMSwgbGFiZWwsIEZEOjpUWVBFX0lOVDMyICk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9pbnQ2NCIgLCAyMiwgbGFiZWwsIEZEOjpUWVBFX0lOVDY0ICk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF91aW50MzIiLCAyMywgbGFiZWwsIEZEOjpUWVBFX1VJTlQzMik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF91aW50NjQiLCAyNCwgbGFiZWwsIEZEOjpUWVBFX1VJTlQ2NCk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9mbG9hdCIgLCAyNSwgbGFiZWwsIEZEOjpUWVBFX0ZMT0FUICk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9kb3VibGUiLCAyNiwgbGFiZWwsIEZEOjpUWVBFX0RPVUJMRSk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9ib29sIiAgLCAyNywgbGFiZWwsIEZEOjpUWVBFX0JPT0wgICk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9zdHJpbmciLCAyOCwgbGFiZWwsIEZEOjpUWVBFX1NUUklORyk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9kYXRhIiAgLCAyOSwgbGFiZWwsIEZEOjpUWVBFX0JZVEVTICk7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbXBsaWNpdF9lbnVtIiAgLCAzMCwgbGFiZWwsIEZEOjpUWVBFX0VOVU0pCisgICAgLT5zZXRfdHlwZV9uYW1lKCJEdW1teUVudW0iKTsKKworICAvLyBCdWlsZCBpdC4KKyAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKworICBBU1NFUlRfRVEoMSwgZmlsZS0+ZW51bV90eXBlX2NvdW50KCkpOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlID0gZmlsZS0+ZW51bV90eXBlKDApOworICBBU1NFUlRfRVEoMiwgZW51bV90eXBlLT52YWx1ZV9jb3VudCgpKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZV9hID0gZW51bV90eXBlLT52YWx1ZSgwKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZV9iID0gZW51bV90eXBlLT52YWx1ZSgxKTsKKworICBBU1NFUlRfRVEoMSwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworCisgIEFTU0VSVF9FUSgyMSwgbWVzc2FnZS0+ZmllbGRfY291bnQoKSk7CisKKyAgLy8gQ2hlY2sgdGhlIGRlZmF1bHQgdmFsdWVzLgorICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCgwKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDEpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoMiktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCgzKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDQpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoNSktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCg2KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDcpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoOCktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCg5KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDEwKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisKKyAgRVhQRUNUX0VRKC0xICAgICAgICAgICAgICAsIG1lc3NhZ2UtPmZpZWxkKDApLT5kZWZhdWx0X3ZhbHVlX2ludDMyICgpKTsKKyAgRVhQRUNUX0VRKC1HT09HTEVfVUxPTkdMT05HKDEwMDAwMDAwMDAwMDApLAorICAgICAgICAgICAgbWVzc2FnZS0+ZmllbGQoMSktPmRlZmF1bHRfdmFsdWVfaW50NjQgKCkpOworICBFWFBFQ1RfRVEoNDIgICAgICAgICAgICAgICwgbWVzc2FnZS0+ZmllbGQoMiktPmRlZmF1bHRfdmFsdWVfdWludDMyKCkpOworICBFWFBFQ1RfRVEoR09PR0xFX1VMT05HTE9ORygyMDAwMDAwMDAwMDAwKSwKKyAgICAgICAgICAgIG1lc3NhZ2UtPmZpZWxkKDMpLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKDQuNSAgICAgICAgICAgICAsIG1lc3NhZ2UtPmZpZWxkKDQpLT5kZWZhdWx0X3ZhbHVlX2Zsb2F0ICgpKTsKKyAgRVhQRUNUX0VRKDEwZTEwMCAgICAgICAgICAsIG1lc3NhZ2UtPmZpZWxkKDUpLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpKTsKKyAgRVhQRUNUX1RSVUUoICAgICAgICAgICAgICAgIG1lc3NhZ2UtPmZpZWxkKDYpLT5kZWZhdWx0X3ZhbHVlX2Jvb2wgICgpKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIgICAgICAgICAsIG1lc3NhZ2UtPmZpZWxkKDcpLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCJcMDAxXDAwMlwwMDMiICAsIG1lc3NhZ2UtPmZpZWxkKDgpLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWVfYiAgICAsIG1lc3NhZ2UtPmZpZWxkKDkpLT5kZWZhdWx0X3ZhbHVlX2VudW0gICgpKTsKKyAgRVhQRUNUX0VRKCIiICAgICAgICAgICAgICAsIG1lc3NhZ2UtPmZpZWxkKDEwKS0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSk7CisKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDExKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9GQUxTRShtZXNzYWdlLT5maWVsZCgxMiktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMTMpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDE0KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9GQUxTRShtZXNzYWdlLT5maWVsZCgxNSktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMTYpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDE3KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9GQUxTRShtZXNzYWdlLT5maWVsZCgxOCktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMTkpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDIwKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLT5maWVsZCgxMSktPmRlZmF1bHRfdmFsdWVfaW50MzIgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UtPmZpZWxkKDEyKS0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS0+ZmllbGQoMTMpLT5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLT5maWVsZCgxNCktPmRlZmF1bHRfdmFsdWVfdWludDY0KCkpOworICBFWFBFQ1RfRVEoMC4wZiAsIG1lc3NhZ2UtPmZpZWxkKDE1KS0+ZGVmYXVsdF92YWx1ZV9mbG9hdCAoKSk7CisgIEVYUEVDVF9FUSgwLjAgICwgbWVzc2FnZS0+ZmllbGQoMTYpLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLT5maWVsZCgxNyktPmRlZmF1bHRfdmFsdWVfYm9vbCAgKCkpOworICBFWFBFQ1RfRVEoIiIgICAsIG1lc3NhZ2UtPmZpZWxkKDE4KS0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS0+ZmllbGQoMTkpLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWVfYSwgbWVzc2FnZS0+ZmllbGQoMjApLT5kZWZhdWx0X3ZhbHVlX2VudW0oKSk7Cit9CisKK1RFU1RfRihNaXNjVGVzdCwgRmllbGRPcHRpb25zKSB7CisgIC8vIFRyeSBzZXR0aW5nIGZpZWxkIG9wdGlvbnMuCisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlX3Byb3RvLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKworICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2VfcHJvdG8gPSBBZGRNZXNzYWdlKCZmaWxlX3Byb3RvLCAiVGVzdE1lc3NhZ2UiKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImZvbyIsIDEsCisgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICBGaWVsZERlc2NyaXB0b3JQcm90byogYmFyX3Byb3RvID0KKyAgICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiYmFyIiwgMiwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworCisgIEZpZWxkT3B0aW9ucyogb3B0aW9ucyA9IGJhcl9wcm90by0+bXV0YWJsZV9vcHRpb25zKCk7CisgIG9wdGlvbnMtPnNldF9jdHlwZShGaWVsZE9wdGlvbnM6OkNPUkQpOworCisgIC8vIEJ1aWxkIHRoZSBkZXNjcmlwdG9ycyBhbmQgZ2V0IHRoZSBwb2ludGVycy4KKyAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKworICBBU1NFUlRfRVEoMSwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLT5maWVsZF9jb3VudCgpKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmb28gPSBtZXNzYWdlLT5maWVsZCgwKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiYXIgPSBtZXNzYWdlLT5maWVsZCgxKTsKKworICAvLyAiZm9vIiBoYWQgbm8gb3B0aW9ucyBzZXQsIHNvIGl0IHNob3VsZCByZXR1cm4gdGhlIGRlZmF1bHQgb3B0aW9ucy4KKyAgRVhQRUNUX0VRKCZGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSwgJmZvby0+b3B0aW9ucygpKTsKKworICAvLyAiYmFyIiBoYWQgb3B0aW9ucyBzZXQuCisgIEVYUEVDVF9ORSgmRmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCksIG9wdGlvbnMpOworICBFWFBFQ1RfVFJVRShiYXItPm9wdGlvbnMoKS5oYXNfY3R5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZE9wdGlvbnM6OkNPUkQsIGJhci0+b3B0aW9ucygpLmN0eXBlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitlbnVtIERlc2NyaXB0b3JQb29sTW9kZSB7CisgIE5PX0RBVEFCQVNFLAorICBGQUxMQkFDS19EQVRBQkFTRQorfTsKKworY2xhc3MgQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdAorICAgIDogcHVibGljIHRlc3Rpbmc6OlRlc3RXaXRoUGFyYW08RGVzY3JpcHRvclBvb2xNb2RlPiB7CisgcHJvdGVjdGVkOgorICBEZXNjcmlwdG9yUG9vbE1vZGUgbW9kZSgpIHsKKyAgICByZXR1cm4gR2V0UGFyYW0oKTsKKyAgIH0KKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fcHJvdG8sIGJhcl9wcm90bzsKKworICAgIHN3aXRjaCAobW9kZSgpKSB7CisgICAgICBjYXNlIE5PX0RBVEFCQVNFOgorICAgICAgICBwb29sXy5yZXNldChuZXcgRGVzY3JpcHRvclBvb2wpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRkFMTEJBQ0tfREFUQUJBU0U6CisgICAgICAgIHBvb2xfLnJlc2V0KG5ldyBEZXNjcmlwdG9yUG9vbCgmZGJfKSk7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIHBvb2xfLT5BbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKTsKKworICAgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyIKKyAgICAgICJkZXBlbmRlbmN5OiAnYmFyLnByb3RvJyIKKyAgICAgICJkZXBlbmRlbmN5OiAnYmF6LnByb3RvJyIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAgICIgIG5hbWU6ICdGb28nIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidiYXInIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTonQmFyJyB9IgorICAgICAgIiAgZmllbGQgeyBuYW1lOidiYXonIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTonQmF6JyB9IgorICAgICAgIiAgZmllbGQgeyBuYW1lOidxdXgnIG51bWJlcjozIGxhYmVsOkxBQkVMX09QVElPTkFMIgorICAgICAgIiAgICB0eXBlX25hbWU6ICcuY29yZ2UuUXV4JyIKKyAgICAgICIgICAgdHlwZTogVFlQRV9FTlVNIgorICAgICAgIiAgICBvcHRpb25zIHsiCisgICAgICAiICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyIKKyAgICAgICIgICAgICAgIG5hbWUgeyIKKyAgICAgICIgICAgICAgICAgbmFtZV9wYXJ0OiAnZ3JhdWx0JyIKKyAgICAgICIgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIgorICAgICAgIiAgICAgICAgfSIKKyAgICAgICIgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIzNCIKKyAgICAgICIgICAgICB9IgorICAgICAgIiAgICB9IgorICAgICAgIiAgfSIKKyAgICAgICJ9IiwKKyAgICAgICZmb29fcHJvdG8pKTsKKyAgICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgICAibmFtZTogJ2Jhci5wcm90byciCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogJ0JhcicgfSIsCisgICAgICAmYmFyX3Byb3RvKSk7CisKKyAgICAvLyBDb2xsZWN0IHBvaW50ZXJzIHRvIHN0dWZmLgorICAgIGJhcl9maWxlXyA9IEJ1aWxkRmlsZShiYXJfcHJvdG8pOworICAgIEFTU0VSVF9UUlVFKGJhcl9maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBiYXJfdHlwZV8gPSBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIGZvb19maWxlXyA9IEJ1aWxkRmlsZShmb29fcHJvdG8pOworICAgIEFTU0VSVF9UUlVFKGZvb19maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBmb29fdHlwZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgzLCBmb29fdHlwZV8tPmZpZWxkX2NvdW50KCkpOworICAgIGJhcl9maWVsZF8gPSBmb29fdHlwZV8tPmZpZWxkKDApOworICAgIGJhel9maWVsZF8gPSBmb29fdHlwZV8tPmZpZWxkKDEpOworICAgIHF1eF9maWVsZF8gPSBmb29fdHlwZV8tPmZpZWxkKDIpOworICB9CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIEJ1aWxkRmlsZShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICAgIHN3aXRjaCAobW9kZSgpKSB7CisgICAgICBjYXNlIE5PX0RBVEFCQVNFOgorICAgICAgICByZXR1cm4gcG9vbF8tPkJ1aWxkRmlsZShwcm90byk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGQUxMQkFDS19EQVRBQkFTRTogeworICAgICAgICBFWFBFQ1RfVFJVRShkYl8uQWRkKHByb3RvKSk7CisgICAgICAgIHJldHVybiBwb29sXy0+RmluZEZpbGVCeU5hbWUocHJvdG8ubmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFyX2ZpbGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBiYXJfdHlwZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb29fZmlsZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb190eXBlXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiYXJfZmllbGRfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJhel9maWVsZF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcXV4X2ZpZWxkXzsKKworICBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UgZGJfOyAgICAgICAgLy8gdXNlZCBpZiBpbiBGQUxMQkFDS19EQVRBQkFTRSBtb2RlLgorICBzY29wZWRfcHRyPERlc2NyaXB0b3JQb29sPiBwb29sXzsKK307CisKK1RFU1RfUChBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0LCBQbGFjZWhvbGRlckZpbGUpIHsKKyAgQVNTRVJUX0VRKDIsIGZvb19maWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKGJhcl9maWxlXywgZm9vX2ZpbGVfLT5kZXBlbmRlbmN5KDApKTsKKyAgRVhQRUNUX0ZBTFNFKGJhcl9maWxlXy0+aXNfcGxhY2Vob2xkZXIoKSk7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhel9maWxlID0gZm9vX2ZpbGVfLT5kZXBlbmRlbmN5KDEpOworICBFWFBFQ1RfRVEoImJhei5wcm90byIsIGJhel9maWxlLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoMCwgYmF6X2ZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgRVhQRUNUX1RSVUUoYmF6X2ZpbGUtPmlzX3BsYWNlaG9sZGVyKCkpOworCisgIC8vIFBsYWNlaG9sZGVyIGZpbGVzIHNob3VsZCBub3QgYmUgZmluZGFibGUuCisgIEVYUEVDVF9FUShiYXJfZmlsZV8sIHBvb2xfLT5GaW5kRmlsZUJ5TmFtZShiYXJfZmlsZV8tPm5hbWUoKSkpOworICBFWFBFQ1RfVFJVRShwb29sXy0+RmluZEZpbGVCeU5hbWUoYmF6X2ZpbGUtPm5hbWUoKSkgPT0gTlVMTCk7CisKKyAgLy8gQ29weSpUbyBzaG91bGQgbm90IGNyYXNoIGZvciBwbGFjZWhvbGRlciBmaWxlcy4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBiYXpfZmlsZV9wcm90bzsKKyAgYmF6X2ZpbGUtPkNvcHlUbygmYmF6X2ZpbGVfcHJvdG8pOworICBiYXpfZmlsZS0+Q29weVNvdXJjZUNvZGVJbmZvVG8oJmJhel9maWxlX3Byb3RvKTsKKyAgRVhQRUNUX0ZBTFNFKGJhel9maWxlX3Byb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworfQorCitURVNUX1AoQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdCwgUGxhY2Vob2xkZXJUeXBlcykgeworICBBU1NFUlRfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIGJhcl9maWVsZF8tPnR5cGUoKSk7CisgIEVYUEVDVF9FUShiYXJfdHlwZV8sIGJhcl9maWVsZF8tPm1lc3NhZ2VfdHlwZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKGJhcl90eXBlXy0+aXNfcGxhY2Vob2xkZXIoKSk7CisKKyAgQVNTRVJUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBiYXpfZmllbGRfLT50eXBlKCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBiYXpfdHlwZSA9IGJhel9maWVsZF8tPm1lc3NhZ2VfdHlwZSgpOworICBFWFBFQ1RfRVEoIkJheiIsIGJhel90eXBlLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJheiIsIGJhel90eXBlLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgwLCBiYXpfdHlwZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkpOworICBFWFBFQ1RfVFJVRShiYXpfdHlwZS0+aXNfcGxhY2Vob2xkZXIoKSk7CisKKyAgQVNTRVJUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNLCBxdXhfZmllbGRfLT50eXBlKCkpOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogcXV4X3R5cGUgPSBxdXhfZmllbGRfLT5lbnVtX3R5cGUoKTsKKyAgRVhQRUNUX0VRKCJRdXgiLCBxdXhfdHlwZS0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5RdXgiLCBxdXhfdHlwZS0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfVFJVRShxdXhfdHlwZS0+aXNfcGxhY2Vob2xkZXIoKSk7CisKKyAgLy8gUGxhY2Vob2xkZXIgdHlwZXMgc2hvdWxkIG5vdCBiZSBmaW5kYWJsZS4KKyAgRVhQRUNUX0VRKGJhcl90eXBlXywgcG9vbF8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZShiYXJfdHlwZV8tPmZ1bGxfbmFtZSgpKSk7CisgIEVYUEVDVF9UUlVFKHBvb2xfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoYmF6X3R5cGUtPmZ1bGxfbmFtZSgpKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocG9vbF8tPkZpbmRFbnVtVHlwZUJ5TmFtZShxdXhfdHlwZS0+ZnVsbF9uYW1lKCkpID09IE5VTEwpOworfQorCitURVNUX1AoQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdCwgQ29weVRvKSB7CisgIC8vIEZpZWxkRGVzY3JpcHRvcjo6Q29weVRvKCkgc2hvdWxkIHdyaXRlIG5vbi1mdWxseS1xdWFsaWZpZWQgdHlwZSBuYW1lcworICAvLyBmb3IgcGxhY2Vob2xkZXIgdHlwZXMgd2hpY2ggd2VyZSBub3Qgb3JpZ2luYWxseSBmdWxseS1xdWFsaWZpZWQuCisgIEZpZWxkRGVzY3JpcHRvclByb3RvIHByb3RvOworCisgIC8vIEJhciBpcyBub3QgYSBwbGFjZWhvbGRlciwgc28gaXQgaXMgZnVsbHktcXVhbGlmaWVkLgorICBiYXJfZmllbGRfLT5Db3B5VG8oJnByb3RvKTsKKyAgRVhQRUNUX0VRKCIuQmFyIiwgcHJvdG8udHlwZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfTUVTU0FHRSwgcHJvdG8udHlwZSgpKTsKKworICAvLyBCYXogaXMgYW4gdW5xdWFsaWZpZWQgcGxhY2Vob2xkZXIuCisgIHByb3RvLkNsZWFyKCk7CisgIGJhel9maWVsZF8tPkNvcHlUbygmcHJvdG8pOworICBFWFBFQ1RfRVEoIkJheiIsIHByb3RvLnR5cGVfbmFtZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHByb3RvLmhhc190eXBlKCkpOworCisgIC8vIFF1eCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBwbGFjZWhvbGRlci4KKyAgcHJvdG8uQ2xlYXIoKTsKKyAgcXV4X2ZpZWxkXy0+Q29weVRvKCZwcm90byk7CisgIEVYUEVDVF9FUSgiLmNvcmdlLlF1eCIsIHByb3RvLnR5cGVfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0VOVU0sIHByb3RvLnR5cGUoKSk7Cit9CisKK1RFU1RfUChBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0LCBDdXN0b21PcHRpb25zKSB7CisgIC8vIFF1eCBzaG91bGQgc3RpbGwgaGF2ZSB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb24gYXR0YWNoZWQuCisgIEFTU0VSVF9FUSgxLCBxdXhfZmllbGRfLT5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpKTsKKyAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgb3B0aW9uID0KKyAgICBxdXhfZmllbGRfLT5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCk7CisgIEFTU0VSVF9FUSgxLCBvcHRpb24ubmFtZV9zaXplKCkpOworICBFWFBFQ1RfRVEoImdyYXVsdCIsIG9wdGlvbi5uYW1lKDApLm5hbWVfcGFydCgpKTsKK30KKworVEVTVF9QKEFsbG93VW5rbm93bkRlcGVuZGVuY2llc1Rlc3QsIFVua25vd25FeHRlbmRlZSkgeworICAvLyBUZXN0IHRoYXQgd2UgY2FuIGV4dGVuZCBhbiB1bmtub3duIHR5cGUuICBUaGlzIGlzIHNsaWdodGx5IHRyaWNreSBiZWNhdXNlCisgIC8vIGl0IG1lYW5zIHRoYXQgdGhlIHBsYWNlaG9sZGVyIHR5cGUgbXVzdCBoYXZlIGFuIGV4dGVuc2lvbiByYW5nZS4KKworICBGaWxlRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbl9wcm90bzsKKworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6ICdleHRlbnNpb24ucHJvdG8nIgorICAgICJleHRlbnNpb24geyBleHRlbmRlZTogJ1Vua25vd25UeXBlJyBuYW1lOidzb21lX2V4dGVuc2lvbicgbnVtYmVyOjEyMyIKKyAgICAiICAgICAgICAgICAgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iLAorICAgICZleHRlbnNpb25fcHJvdG8pKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBCdWlsZEZpbGUoZXh0ZW5zaW9uX3Byb3RvKTsKKworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworCisgIEFTU0VSVF9FUSgxLCBmaWxlLT5leHRlbnNpb25fY291bnQoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlID0gZmlsZS0+ZXh0ZW5zaW9uKDApLT5jb250YWluaW5nX3R5cGUoKTsKKyAgRVhQRUNUX0VRKCJVbmtub3duVHlwZSIsIGV4dGVuZGVlLT5uYW1lKCkpOworICBFWFBFQ1RfVFJVRShleHRlbmRlZS0+aXNfcGxhY2Vob2xkZXIoKSk7CisgIEFTU0VSVF9FUSgxLCBleHRlbmRlZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgZXh0ZW5kZWUtPmV4dGVuc2lvbl9yYW5nZSgwKS0+c3RhcnQpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyICsgMSwgZXh0ZW5kZWUtPmV4dGVuc2lvbl9yYW5nZSgwKS0+ZW5kKTsKK30KKworVEVTVF9QKEFsbG93VW5rbm93bkRlcGVuZGVuY2llc1Rlc3QsIEN1c3RvbU9wdGlvbikgeworICAvLyBUZXN0IHRoYXQgd2UgY2FuIHVzZSBhIGN1c3RvbSBvcHRpb24gd2l0aG91dCBoYXZpbmcgcGFyc2VkCisgIC8vIGRlc2NyaXB0b3IucHJvdG8uCisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBvcHRpb25fcHJvdG87CisKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcInVua25vd25fY3VzdG9tX29wdGlvbnMucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7ICIKKyAgICAiICBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiAiCisgICAgIiAgbmFtZTogXCJzb21lX29wdGlvblwiICIKKyAgICAiICBudW1iZXI6IDEyMzQ1NiAiCisgICAgIiAgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICB0eXBlOiBUWVBFX0lOVDMyICIKKyAgICAifSAiCisgICAgIm9wdGlvbnMgeyAiCisgICAgIiAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICBuYW1lIHsgIgorICAgICIgICAgICBuYW1lX3BhcnQ6IFwic29tZV9vcHRpb25cIiAiCisgICAgIiAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIzNCAiCisgICAgIiAgfSAiCisgICAgIiAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICBuYW1lIHsgIgorICAgICIgICAgICBuYW1lX3BhcnQ6IFwidW5rbm93bl9vcHRpb25cIiAiCisgICAgIiAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIzNCAiCisgICAgIiAgfSAiCisgICAgIiAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICBuYW1lIHsgIgorICAgICIgICAgICBuYW1lX3BhcnQ6IFwib3B0aW1pemVfZm9yXCIgIgorICAgICIgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgIH0gIgorICAgICIgICAgaWRlbnRpZmllcl92YWx1ZTogXCJTUEVFRFwiICIKKyAgICAiICB9ICIKKyAgICAifSIsCisgICAgJm9wdGlvbl9wcm90bykpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gQnVpbGRGaWxlKG9wdGlvbl9wcm90byk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgbm8gZXh0ZW5zaW9uIG9wdGlvbnMgd2VyZSBzZXQsIGJ1dCB0aGV5IHdlcmUgbGVmdCBhcworICAvLyB1bmludGVycHJldGVkX29wdGlvbnMuCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGZpbGUtPm9wdGlvbnMoKS5HZXRSZWZsZWN0aW9uKCktPkxpc3RGaWVsZHMoZmlsZS0+b3B0aW9ucygpLCAmZmllbGRzKTsKKyAgQVNTRVJUX0VRKDIsIGZpZWxkcy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShmaWxlLT5vcHRpb25zKCkuaGFzX29wdGltaXplX2ZvcigpKTsKKyAgRVhQRUNUX0VRKDIsIGZpbGUtPm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbl9zaXplKCkpOworfQorCitURVNUX1AoQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdCwKKyAgICAgICBVbmRlY2xhcmVkRGVwZW5kZW5jeVRyaWdnZXJzQnVpbGRPZkRlcGVuZGVuY3kpIHsKKyAgLy8gQ3JhenkgY2FzZTogc3VwcG9zZSBmb28ucHJvdG8gcmVmZXJzIHRvIGEgc3ltYm9sIHdpdGhvdXQgZGVjbGFyaW5nIHRoZQorICAvLyBkZXBlbmRlbmN5IHRoYXQgZmluZHMgaXQuIEluIHRoZSBldmVudCB0aGF0IHRoZSBwb29sIGlzIGJhY2tlZCBieSBhCisgIC8vIERlc2NyaXB0b3JEYXRhYmFzZSwgdGhlIHBvb2wgd2lsbCBhdHRlbXB0IHRvIGZpbmQgdGhlIHN5bWJvbCBpbiB0aGUKKyAgLy8gZGF0YWJhc2UuIElmIHN1Y2Nlc3NmdWwsIGl0IHdpbGwgYnVpbGQgdGhlIHVuZGVjbGFyZWQgZGVwZW5kZW5jeSB0byB2ZXJpZnkKKyAgLy8gdGhhdCB0aGUgZmlsZSBkb2VzIGluZGVlZCBjb250YWluIHRoZSBzeW1ib2wuIElmIHRoYXQgZmlsZSBmYWlscyB0byBidWlsZCwKKyAgLy8gdGhlbiBpdHMgZGVzY3JpcHRvcnMgbXVzdCBiZSByb2xsZWQgYmFjay4gSG93ZXZlciwgd2Ugc3RpbGwgd2FudCBmb28ucHJvdG8KKyAgLy8gdG8gYnVpbGQgc3VjY2Vzc2Z1bGx5LCBzaW5jZSB3ZSBhcmUgYWxsb3dpbmcgdW5rbm93biBkZXBlbmRlbmNpZXMuCisKKyAgRmlsZURlc2NyaXB0b3JQcm90byB1bmRlY2xhcmVkX2RlcF9wcm90bzsKKyAgLy8gV2UgbWFrZSB0aGlzIGZpbGUgZmFpbCB0byBidWlsZCBieSBnaXZpbmcgaXQgdHdvIGZpZWxkcyB3aXRoIHRhZyAxLgorICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6IFwiaW52YWxpZF9maWxlX2FzX3VuZGVjbGFyZWRfZGVwLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcInVuZGVjbGFyZWRcIiAiCisgICAgIm1lc3NhZ2VfdHlwZTogeyAgIgorICAgICIgIG5hbWU6IFwiUXV1eFwiICAiCisgICAgIiAgZmllbGQgeyAiCisgICAgIiAgICBuYW1lOidxdXgnIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6IFRZUEVfSU5UMzIgIgorICAgICIgIH0iCisgICAgIiAgZmllbGQgeyAiCisgICAgIiAgICBuYW1lOidxdXV4JyBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOiBUWVBFX0lOVDY0ICIKKyAgICAiICB9IgorICAgICJ9IiwKKyAgICAmdW5kZWNsYXJlZF9kZXBfcHJvdG8pKTsKKyAgLy8gV2UgY2FuJ3QgdXNlIHRoZSBCdWlsZEZpbGUoKSBoZWxwZXIgYmVjYXVzZSB3ZSBkb24ndCBhY3R1YWxseSB3YW50IHRvIGJ1aWxkCisgIC8vIGl0IGludG8gdGhlIGRlc2NyaXB0b3IgcG9vbCBpbiB0aGUgZmFsbGJhY2sgZGF0YWJhc2UgY2FzZTogaXQganVzdCBuZWVkcyB0bworICAvLyBiZSBzaXR0aW5nIGluIHRoZSBkYXRhYmFzZSBzbyB0aGF0IGl0IGdldHMgYnVpbHQgZHVyaW5nIHRoZSBidWlsZGluZyBvZgorICAvLyB0ZXN0LnByb3RvIGJlbG93LgorICBzd2l0Y2ggKG1vZGUoKSkgeworICAgIGNhc2UgTk9fREFUQUJBU0U6IHsKKyAgICAgIEFTU0VSVF9UUlVFKHBvb2xfLT5CdWlsZEZpbGUodW5kZWNsYXJlZF9kZXBfcHJvdG8pID09IE5VTEwpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRkFMTEJBQ0tfREFUQUJBU0U6IHsKKyAgICAgIEFTU0VSVF9UUlVFKGRiXy5BZGQodW5kZWNsYXJlZF9kZXBfcHJvdG8pKTsKKyAgICB9CisgIH0KKworICBGaWxlRGVzY3JpcHRvclByb3RvIHRlc3RfcHJvdG87CisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAibmFtZTogXCJ0ZXN0LnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGU6IHsgIgorICAgICIgIG5hbWU6IFwiQ29yZ2VcIiAiCisgICAgIiAgZmllbGQgeyAiCisgICAgIiAgICBuYW1lOidxdXV4JyBudW1iZXI6MSBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgdHlwZV9uYW1lOid1bmRlY2xhcmVkLlF1dXgnIHR5cGU6IFRZUEVfTUVTU0FHRSAiCisgICAgIiAgfSIKKyAgICAifSIsCisgICAgJnRlc3RfcHJvdG8pKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IEJ1aWxkRmlsZSh0ZXN0X3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgR09PR0xFX0xPRyhJTkZPKSA8PCBmaWxlLT5EZWJ1Z1N0cmluZygpOworCisgIEVYUEVDVF9FUSgwLCBmaWxlLT5kZXBlbmRlbmN5X2NvdW50KCkpOworICBBU1NFUlRfRVEoMSwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBjb3JnZV9kZXNjID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBBU1NFUlRfRVEoIkNvcmdlIiwgY29yZ2VfZGVzYy0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGNvcmdlX2Rlc2MtPmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRkFMU0UoY29yZ2VfZGVzYy0+aXNfcGxhY2Vob2xkZXIoKSk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBxdXV4X2ZpZWxkID0gY29yZ2VfZGVzYy0+ZmllbGQoMCk7CisgIEFTU0VSVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgcXV1eF9maWVsZC0+dHlwZSgpKTsKKyAgQVNTRVJUX0VRKCJRdXV4IiwgcXV1eF9maWVsZC0+bWVzc2FnZV90eXBlKCktPm5hbWUoKSk7CisgIEFTU0VSVF9FUSgidW5kZWNsYXJlZC5RdXV4IiwgcXV1eF9maWVsZC0+bWVzc2FnZV90eXBlKCktPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX1RSVUUocXV1eF9maWVsZC0+bWVzc2FnZV90eXBlKCktPmlzX3BsYWNlaG9sZGVyKCkpOworICAvLyBUaGUgcGxhY2UgaG9sZGVyIHR5cGUgc2hvdWxkIG5vdCBiZSBmaW5kYWJsZS4KKyAgQVNTRVJUX1RSVUUocG9vbF8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgidW5kZWNsYXJlZC5RdXV4IikgPT0gTlVMTCk7Cit9CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERhdGFiYXNlU291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlZhbHVlcyhOT19EQVRBQkFTRSwgRkFMTEJBQ0tfREFUQUJBU0UpKTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEN1c3RvbU9wdGlvbnMsIE9wdGlvbkxvY2F0aW9ucykgeworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0KKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zOjpkZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gbWVzc2FnZS0+ZmlsZSgpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gbWVzc2FnZS0+RmluZEZpZWxkQnlOYW1lKCJmaWVsZDEiKTsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVubSA9IG1lc3NhZ2UtPkZpbmRFbnVtVHlwZUJ5TmFtZSgiQW5FbnVtIik7CisgIC8vIFRPRE8oYmVuankpOiBTdXBwb3J0IEVudW1WYWx1ZSBvcHRpb25zLCBvbmNlIHRoZSBjb21waWxlciBkb2VzLgorICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZSA9CisgICAgICBmaWxlLT5GaW5kU2VydmljZUJ5TmFtZSgiVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucyIpOworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBzZXJ2aWNlLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKTsKKworICBFWFBFQ1RfRVEoR09PR0xFX0xPTkdMT05HKDk4NzY1NDMyMTApLAorICAgICAgICAgICAgZmlsZS0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmlsZV9vcHQxKSk7CisgIEVYUEVDVF9FUSgtNTYsCisgICAgICAgICAgICBtZXNzYWdlLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjptZXNzYWdlX29wdDEpKTsKKyAgRVhQRUNUX0VRKEdPT0dMRV9MT05HTE9ORyg4NzY1NDMyMTA5KSwKKyAgICAgICAgICAgIGZpZWxkLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaWVsZF9vcHQxKSk7CisgIEVYUEVDVF9FUSg0MiwgIC8vIENoZWNrIHRoYXQgd2UgZ2V0IHRoZSBkZWZhdWx0IGZvciBhbiBvcHRpb24gd2UgZG9uJ3Qgc2V0LgorICAgICAgICAgICAgZmllbGQtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmZpZWxkX29wdDIpKTsKKyAgRVhQRUNUX0VRKC03ODksCisgICAgICAgICAgICBlbm0tPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmVudW1fb3B0MSkpOworICBFWFBFQ1RfRVEoMTIzLAorICAgICAgICAgICAgZW5tLT52YWx1ZSgxKS0+b3B0aW9ucygpLkdldEV4dGVuc2lvbigKKyAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OmVudW1fdmFsdWVfb3B0MSkpOworICBFWFBFQ1RfRVEoR09PR0xFX0xPTkdMT05HKC05ODc2NTQzMjEwKSwKKyAgICAgICAgICAgIHNlcnZpY2UtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnNlcnZpY2Vfb3B0MSkpOworICBFWFBFQ1RfRVEocHJvdG9idWZfdW5pdHRlc3Q6Ok1FVEhPRE9QVDFfVkFMMiwKKyAgICAgICAgICAgIG1ldGhvZC0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6bWV0aG9kX29wdDEpKTsKKworICAvLyBTZWUgdGhhdCB0aGUgcmVndWxhciBvcHRpb25zIHdlbnQgdGhyb3VnaCB1bnNjYXRoZWQuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPm9wdGlvbnMoKS5oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSk7CisgIEVYUEVDVF9FUShGaWVsZE9wdGlvbnM6OkNPUkQsIGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSk7Cit9CisKK1RFU1QoQ3VzdG9tT3B0aW9ucywgT3B0aW9uVHlwZXMpIHsKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMqIG9wdGlvbnMgPSBOVUxMOworCisgIG9wdGlvbnMgPQorICAgICAgJnByb3RvYnVmX3VuaXR0ZXN0OjpDdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzOjpkZXNjcmlwdG9yKCktPm9wdGlvbnMoKTsKKyAgRVhQRUNUX0VRKGZhbHNlICAgICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpib29sX29wdCkpOworICBFWFBFQ1RfRVEoa2ludDMybWluLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmludDMyX29wdCkpOworICBFWFBFQ1RfRVEoa2ludDY0bWluLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmludDY0X29wdCkpOworICBFWFBFQ1RfRVEoMCAgICAgICAgLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnVpbnQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKDAgICAgICAgICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojp1aW50NjRfb3B0KSk7CisgIEVYUEVDVF9FUShraW50MzJtaW4sIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ludDMyX29wdCkpOworICBFWFBFQ1RfRVEoa2ludDY0bWluLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnNpbnQ2NF9vcHQpKTsKKyAgRVhQRUNUX0VRKDAgICAgICAgICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaXhlZDMyX29wdCkpOworICBFWFBFQ1RfRVEoMCAgICAgICAgLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmZpeGVkNjRfb3B0KSk7CisgIEVYUEVDVF9FUShraW50MzJtaW4sIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ZpeGVkMzJfb3B0KSk7CisgIEVYUEVDVF9FUShraW50NjRtaW4sIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ZpeGVkNjRfb3B0KSk7CisKKyAgb3B0aW9ucyA9CisgICAgICAmcHJvdG9idWZfdW5pdHRlc3Q6OkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXM6OmRlc2NyaXB0b3IoKS0+b3B0aW9ucygpOworICBFWFBFQ1RfRVEodHJ1ZSAgICAgICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpib29sX29wdCkpOworICBFWFBFQ1RfRVEoa2ludDMybWF4ICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjppbnQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQ2NG1heCAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6aW50NjRfb3B0KSk7CisgIEVYUEVDVF9FUShrdWludDMybWF4LCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnVpbnQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKGt1aW50NjRtYXgsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6dWludDY0X29wdCkpOworICBFWFBFQ1RfRVEoa2ludDMybWF4ICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpzaW50MzJfb3B0KSk7CisgIEVYUEVDVF9FUShraW50NjRtYXggLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnNpbnQ2NF9vcHQpKTsKKyAgRVhQRUNUX0VRKGt1aW50MzJtYXgsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Zml4ZWQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKGt1aW50NjRtYXgsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Zml4ZWQ2NF9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQzMm1heCAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ZpeGVkMzJfb3B0KSk7CisgIEVYUEVDVF9FUShraW50NjRtYXggLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnNmaXhlZDY0X29wdCkpOworCisgIG9wdGlvbnMgPQorICAgICAgJnByb3RvYnVmX3VuaXR0ZXN0OjpDdXN0b21PcHRpb25PdGhlclZhbHVlczo6ZGVzY3JpcHRvcigpLT5vcHRpb25zKCk7CisgIEVYUEVDVF9FUSgtMTAwLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmludDMyX29wdCkpOworICBFWFBFQ1RfRkxPQVRfRVEoMTIuMzQ1Njc4OSwKKyAgICAgICAgICAgICAgICAgIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmxvYXRfb3B0KSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMS4yMzQ1Njc4OTAxMjM0NTY3ODksCisgICAgICAgICAgICAgICAgICAgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpkb3VibGVfb3B0KSk7CisgIEVYUEVDVF9FUSgiSGVsbG8sIFwiV29ybGRcIiIsCisgICAgICAgICAgICBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnN0cmluZ19vcHQpKTsKKworICBFWFBFQ1RfRVEoc3RyaW5nKCJIZWxsb1wwV29ybGQiLCAxMSksCisgICAgICAgICAgICBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmJ5dGVzX29wdCkpOworCisgIEVYUEVDVF9FUShwcm90b2J1Zl91bml0dGVzdDo6RHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW06OlRFU1RfT1BUSU9OX0VOVU1fVFlQRTIsCisgICAgICAgICAgICBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmVudW1fb3B0KSk7CisKKyAgb3B0aW9ucyA9CisgICAgICAmcHJvdG9idWZfdW5pdHRlc3Q6OlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHM6OmRlc2NyaXB0b3IoKS0+b3B0aW9ucygpOworICBFWFBFQ1RfRkxPQVRfRVEoMTIsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmxvYXRfb3B0KSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMTU0LCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmRvdWJsZV9vcHQpKTsKKworICBvcHRpb25zID0KKyAgICAgICZwcm90b2J1Zl91bml0dGVzdDo6U2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50czo6ZGVzY3JpcHRvcigpLT5vcHRpb25zKCk7CisgIEVYUEVDVF9GTE9BVF9FUSgtMTIsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmxvYXRfb3B0KSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLTE1NCwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpkb3VibGVfb3B0KSk7Cit9CisKK1RFU1QoQ3VzdG9tT3B0aW9ucywgQ29tcGxleEV4dGVuc2lvbk9wdGlvbnMpIHsKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMqIG9wdGlvbnMgPQorICAgICAgJnByb3RvYnVmX3VuaXR0ZXN0OjpWYXJpb3VzQ29tcGxleE9wdGlvbnM6OmRlc2NyaXB0b3IoKS0+b3B0aW9ucygpOworICBFWFBFQ1RfRVEob3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDEpLmZvbygpLCA0Mik7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MSkuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnF1dXgpLCAzMjQpOworICBFWFBFQ1RfRVEob3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDEpLgorICAgICAgICAgICAgR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb3JnZSkucXV4KCksIDg3Nik7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmF6KCksIDk4Nyk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmdyYXVsdCksIDY1NCk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFyKCkuZm9vKCksCisgICAgICAgICAgICA3NDMpOworICBFWFBFQ1RfRVEob3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDIpLmJhcigpLgorICAgICAgICAgICAgR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpxdXV4KSwgMTk5OSk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFyKCkuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvcmdlKS5xdXgoKSwgMjAwOCk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmdhcnBseSkuZm9vKCksIDc0MSk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmdhcnBseSkuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnF1dXgpLCAxOTk4KTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Z2FycGx5KS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29yZ2UpLnF1eCgpLCAyMTIxKTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpDb21wbGV4T3B0aW9uVHlwZTI6OkNvbXBsZXhPcHRpb25UeXBlNDo6Y29tcGxleF9vcHQ0KS4KKyAgICAgICAgICAgIHdhbGRvKCksIDE5NzEpOworICBFWFBFQ1RfRVEob3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDIpLgorICAgICAgICAgICAgZnJlZCgpLndhbGRvKCksIDMyMSk7CisgIEVYUEVDVF9FUSg5LCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MykucXV4KCkpOworICBFWFBFQ1RfRVEoMjIsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQzKS4KKyAgICAgICAgICAgICAgICBjb21wbGV4b3B0aW9udHlwZTUoKS5wbHVnaCgpKTsKKyAgRVhQRUNUX0VRKDI0LCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhvcHQ2KS54eXp6eSgpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBPcHRpb25zRnJvbU90aGVyRmlsZSkgeworICAvLyBUZXN0IHRoYXQgdG8gdXNlIGEgY3VzdG9tIG9wdGlvbiwgd2Ugb25seSBuZWVkIHRvIGltcG9ydCB0aGUgZmlsZQorICAvLyBkZWZpbmluZyB0aGUgb3B0aW9uOyB3ZSBkbyBub3QgYWxzbyBoYXZlIHRvIGltcG9ydCBkZXNjcmlwdG9yLnByb3RvLgorICBEZXNjcmlwdG9yUG9vbCBwb29sOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zOjpkZXNjcmlwdG9yKCkKKyAgICAtPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcImN1c3RvbV9vcHRpb25zX2ltcG9ydC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJwcm90b2J1Zl91bml0dGVzdFwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG9cIiAiCisgICAgIm9wdGlvbnMgeyAiCisgICAgIiAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICBuYW1lIHsgIgorICAgICIgICAgICBuYW1lX3BhcnQ6IFwiZmlsZV9vcHQxXCIgIgorICAgICIgICAgICBpc19leHRlbnNpb246IHRydWUgIgorICAgICIgICAgfSAiCisgICAgIiAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEyMzQgIgorICAgICIgIH0gIgorICAgIC8vIFRlc3QgYSBub24tZXh0ZW5zaW9uIG9wdGlvbiB0b28uICAoQXQgb25lIHBvaW50IHRoaXMgZmFpbGVkIGR1ZSB0byBhCisgICAgLy8gYnVnLikKKyAgICAiICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgIG5hbWUgeyAiCisgICAgIiAgICAgIG5hbWVfcGFydDogXCJqYXZhX3BhY2thZ2VcIiAiCisgICAgIiAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgfSAiCisgICAgIiAgICBzdHJpbmdfdmFsdWU6IFwiZm9vXCIgIgorICAgICIgIH0gIgorICAgIC8vIFRlc3QgdGhhdCBlbnVtLXR5cGVkIG9wdGlvbnMgc3RpbGwgd29yayB0b28uICAoQXQgb25lIHBvaW50IHRoaXMgYWxzbworICAgIC8vIGZhaWxlZCBkdWUgdG8gYSBidWcuKQorICAgICIgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgbmFtZSB7ICIKKyAgICAiICAgICAgbmFtZV9wYXJ0OiBcIm9wdGltaXplX2ZvclwiICIKKyAgICAiICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiU1BFRURcIiAiCisgICAgIiAgfSAiCisgICAgIn0iCisgICAgLAorICAgICZmaWxlX3Byb3RvKSk7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKDEyMzQsIGZpbGUtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmZpbGVfb3B0MSkpOworICBFWFBFQ1RfVFJVRShmaWxlLT5vcHRpb25zKCkuaGFzX2phdmFfcGFja2FnZSgpKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBmaWxlLT5vcHRpb25zKCkuamF2YV9wYWNrYWdlKCkpOworICBFWFBFQ1RfVFJVRShmaWxlLT5vcHRpb25zKCkuaGFzX29wdGltaXplX2ZvcigpKTsKKyAgRVhQRUNUX0VRKEZpbGVPcHRpb25zOjpTUEVFRCwgZmlsZS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBNZXNzYWdlT3B0aW9uVGhyZWVGaWVsZHNTZXQpIHsKKyAgLy8gVGhpcyB0ZXN0cyBhIGJ1ZyB3aGljaCBwcmV2aW91c2x5IGV4aXN0ZWQgaW4gY3VzdG9tIG9wdGlvbnMgcGFyc2luZy4gIFRoZQorICAvLyBidWcgb2NjdXJyZWQgd2hlbiB5b3UgZGVmaW5lZCBhIGN1c3RvbSBvcHRpb24gd2l0aCBtZXNzYWdlIHR5cGUgYW5kIHRoZW4KKyAgLy8gc2V0IHRocmVlIGZpZWxkcyBvZiB0aGF0IG9wdGlvbiBvbiBhIHNpbmdsZSBkZWZpbml0aW9uIChzZWUgdGhlIGV4YW1wbGUKKyAgLy8gYmVsb3cpLiAgVGhlIGJ1ZyBpcyBhIGJpdCBoYXJkIHRvIGV4cGxhaW4sIHNvIGNoZWNrIHRoZSBjaGFuZ2UgaGlzdG9yeSBpZgorICAvLyB5b3Ugd2FudCB0byBrbm93IG1vcmUuCisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnM6OmRlc2NyaXB0b3IoKQorICAgIC0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworICAvLyBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgdGhlIGRlZmluaXRpb246CisgIC8vCisgIC8vICAgaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8iCisgIC8vICAgcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MSkuZm9vICA9IDEyMzQ7CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MSkuZm9vMiA9IDEyMzQ7CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MSkuZm9vMyA9IDEyMzQ7CisgIC8vICAgfQorICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6IFwiY3VzdG9tX29wdGlvbnNfaW1wb3J0LnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcInByb3RvYnVmX3VuaXR0ZXN0XCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiRm9vXCIgIgorICAgICIgIG9wdGlvbnMgeyAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQxXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEyMzQgIgorICAgICIgICAgfSAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQxXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJmb28yXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxMjM0ICIKKyAgICAiICAgIH0gIgorICAgICIgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImNvbXBsZXhfb3B0MVwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IHRydWUgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiZm9vM1wiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIzNCAiCisgICAgIiAgICB9ICIKKyAgICAiICB9ICIKKyAgICAifSIsCisgICAgJmZpbGVfcHJvdG8pKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBBU1NFUlRfRVEoMSwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworCisgIGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBvcHRpb25zID0gZmlsZS0+bWVzc2FnZV90eXBlKDApLT5vcHRpb25zKCk7CisgIEVYUEVDVF9FUSgxMjM0LCBvcHRpb25zLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQxKS5mb28oKSk7Cit9CisKK1RFU1QoQ3VzdG9tT3B0aW9ucywgTWVzc2FnZU9wdGlvblJlcGVhdGVkTGVhZkZpZWxkU2V0KSB7CisgIC8vIFRoaXMgdGVzdCB2ZXJpZmllcyB0aGF0IHJlcGVhdGVkIGZpZWxkcyBpbiBjdXN0b20gb3B0aW9ucyBjYW4gYmUKKyAgLy8gZ2l2ZW4gbXVsdGlwbGUgdmFsdWVzIGJ5IHJlcGVhdGluZyB0aGUgb3B0aW9uIHdpdGggYSBkaWZmZXJlbnQgdmFsdWUuCisgIC8vIFRoaXMgdGVzdCBjaGVja3MgcmVwZWF0ZWQgbGVhZiB2YWx1ZXMuIEVhY2ggcmVwZWF0ZWQgY3VzdG9tIHZhbHVlCisgIC8vIGFwcGVhcnMgaW4gYSBkaWZmZXJlbnQgdW5pbnRlcnByZXRlZF9vcHRpb24sIHdoaWNoIHdpbGwgYmUgY29uY2F0ZW5hdGVkCisgIC8vIHdoZW4gdGhleSBhcmUgbWVyZ2VkIGludG8gdGhlIGZpbmFsIG9wdGlvbiB2YWx1ZS4KKyAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uczo6ZGVzY3JpcHRvcigpCisgICAgLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIC8vIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyB0aGUgZGVmaW5pdGlvbjoKKyAgLy8KKyAgLy8gICBpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byIKKyAgLy8gICBwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworICAvLyAgIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQxKS5mb280ID0gMTI7CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MSkuZm9vNCA9IDM0OworICAvLyAgICAgb3B0aW9uIChjb21wbGV4X29wdDEpLmZvbzQgPSA1NjsKKyAgLy8gICB9CisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAibmFtZTogXCJjdXN0b21fb3B0aW9uc19pbXBvcnQucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwicHJvdG9idWZfdW5pdHRlc3RcIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIiAgb3B0aW9ucyB7ICIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJjb21wbGV4X29wdDFcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImZvbzRcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEyICIKKyAgICAiICAgIH0gIgorICAgICIgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImNvbXBsZXhfb3B0MVwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IHRydWUgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiZm9vNFwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMzQgIgorICAgICIgICAgfSAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQxXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJmb280XCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiA1NiAiCisgICAgIiAgICB9ICIKKyAgICAiICB9ICIKKyAgICAifSIsCisgICAgJmZpbGVfcHJvdG8pKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBBU1NFUlRfRVEoMSwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworCisgIGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBvcHRpb25zID0gZmlsZS0+bWVzc2FnZV90eXBlKDApLT5vcHRpb25zKCk7CisgIEVYUEVDVF9FUSgzLCBvcHRpb25zLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQxKS5mb280X3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMiwgb3B0aW9ucy5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MSkuZm9vNCgwKSk7CisgIEVYUEVDVF9FUSgzNCwgb3B0aW9ucy5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MSkuZm9vNCgxKSk7CisgIEVYUEVDVF9FUSg1Niwgb3B0aW9ucy5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MSkuZm9vNCgyKSk7Cit9CisKK1RFU1QoQ3VzdG9tT3B0aW9ucywgTWVzc2FnZU9wdGlvblJlcGVhdGVkTXNnRmllbGRTZXQpIHsKKyAgLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgcmVwZWF0ZWQgZmllbGRzIGluIGN1c3RvbSBvcHRpb25zIGNhbiBiZQorICAvLyBnaXZlbiBtdWx0aXBsZSB2YWx1ZXMgYnkgcmVwZWF0aW5nIHRoZSBvcHRpb24gd2l0aCBhIGRpZmZlcmVudCB2YWx1ZS4KKyAgLy8gVGhpcyB0ZXN0IGNoZWNrcyByZXBlYXRlZCBtZXNzYWdlIHZhbHVlcy4gRWFjaCByZXBlYXRlZCBjdXN0b20gdmFsdWUKKyAgLy8gYXBwZWFycyBpbiBhIGRpZmZlcmVudCB1bmludGVycHJldGVkX29wdGlvbiwgd2hpY2ggd2lsbCBiZSBjb25jYXRlbmF0ZWQKKyAgLy8gd2hlbiB0aGV5IGFyZSBtZXJnZWQgaW50byB0aGUgZmluYWwgb3B0aW9uIHZhbHVlLgorICBEZXNjcmlwdG9yUG9vbCBwb29sOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zOjpkZXNjcmlwdG9yKCkKKyAgICAtPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgLy8gVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIHRoZSBkZWZpbml0aW9uOgorICAvLworICAvLyAgIGltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIgorICAvLyAgIHBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisgIC8vICAgbWVzc2FnZSBGb28geworICAvLyAgICAgb3B0aW9uIChjb21wbGV4X29wdDIpLmJhcm5leSA9IHt3YWxkbzogMX07CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFybmV5ID0ge3dhbGRvOiAxMH07CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFybmV5ID0ge3dhbGRvOiAxMDB9OworICAvLyAgIH0KKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcImN1c3RvbV9vcHRpb25zX2ltcG9ydC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJwcm90b2J1Zl91bml0dGVzdFwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkZvb1wiICIKKyAgICAiICBvcHRpb25zIHsgIgorICAgICIgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImNvbXBsZXhfb3B0MlwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IHRydWUgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiYmFybmV5XCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgYWdncmVnYXRlX3ZhbHVlOiBcIndhbGRvOiAxXCIgIgorICAgICIgICAgfSAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQyXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJiYXJuZXlcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBhZ2dyZWdhdGVfdmFsdWU6IFwid2FsZG86IDEwXCIgIgorICAgICIgICAgfSAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQyXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJiYXJuZXlcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBhZ2dyZWdhdGVfdmFsdWU6IFwid2FsZG86IDEwMFwiICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICJ9IiwKKyAgICAmZmlsZV9wcm90bykpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgxLCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMgPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm9wdGlvbnMoKTsKKyAgRVhQRUNUX0VRKDMsIG9wdGlvbnMuR2V0RXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFybmV5X3NpemUoKSk7CisgIEVYUEVDVF9FUSgxLG9wdGlvbnMuR2V0RXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFybmV5KDApLndhbGRvKCkpOworICBFWFBFQ1RfRVEoMTAsIG9wdGlvbnMuR2V0RXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFybmV5KDEpLndhbGRvKCkpOworICBFWFBFQ1RfRVEoMTAwLCBvcHRpb25zLkdldEV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDIpLmJhcm5leSgyKS53YWxkbygpKTsKK30KKworLy8gQ2hlY2sgdGhhdCBhZ2dyZWdhdGUgb3B0aW9ucyB3ZXJlIHBhcnNlZCBhbmQgc2F2ZWQgY29ycmVjdGx5IGluCisvLyB0aGUgYXBwcm9wcmlhdGUgZGVzY3JpcHRvcnMuCitURVNUKEN1c3RvbU9wdGlvbnMsIEFnZ3JlZ2F0ZU9wdGlvbnMpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogbXNnID0gcHJvdG9idWZfdW5pdHRlc3Q6OkFnZ3JlZ2F0ZU1lc3NhZ2U6OmRlc2NyaXB0b3IoKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBtc2ctPmZpbGUoKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG1zZy0+RmluZEZpZWxkQnlOYW1lKCJmaWVsZG5hbWUiKTsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1kID0gZmlsZS0+RmluZEVudW1UeXBlQnlOYW1lKCJBZ2dyZWdhdGVFbnVtIik7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW12ID0gZW51bWQtPkZpbmRWYWx1ZUJ5TmFtZSgiVkFMVUUiKTsKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UgPSBmaWxlLT5GaW5kU2VydmljZUJ5TmFtZSgKKyAgICAgICJBZ2dyZWdhdGVTZXJ2aWNlIik7CisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IHNlcnZpY2UtPkZpbmRNZXRob2RCeU5hbWUoIk1ldGhvZCIpOworCisgIC8vIFRlc3RzIGZvciB0aGUgZGlmZmVyZW50IHR5cGVzIG9mIGRhdGEgZW1iZWRkZWQgaW4gZmlsZW9wdAorICBjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6QWdncmVnYXRlJiBmaWxlX29wdGlvbnMgPQorICAgICAgZmlsZS0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmlsZW9wdCk7CisgIEVYUEVDVF9FUSgxMDAsIGZpbGVfb3B0aW9ucy5pKCkpOworICBFWFBFQ1RfRVEoIkZpbGVBbm5vdGF0aW9uIiwgZmlsZV9vcHRpb25zLnMoKSk7CisgIEVYUEVDVF9FUSgiTmVzdGVkRmlsZUFubm90YXRpb24iLCBmaWxlX29wdGlvbnMuc3ViKCkucygpKTsKKyAgRVhQRUNUX0VRKCJGaWxlRXh0ZW5zaW9uQW5ub3RhdGlvbiIsCisgICAgICAgICAgICBmaWxlX29wdGlvbnMuZmlsZSgpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmlsZW9wdCkucygpKTsKKyAgRVhQRUNUX0VRKCJFbWJlZGRlZE1lc3NhZ2VTZXRFbGVtZW50IiwKKyAgICAgICAgICAgIGZpbGVfb3B0aW9ucy5tc2V0KCkuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudAorICAgICAgICAgICAgICAgIDo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS5zKCkpOworCisgIC8vIFNpbXBsZSB0ZXN0cyBmb3IgYWxsIHRoZSBvdGhlciB0eXBlcyBvZiBhbm5vdGF0aW9ucworICBFWFBFQ1RfRVEoIk1lc3NhZ2VBbm5vdGF0aW9uIiwKKyAgICAgICAgICAgIG1zZy0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6bXNnb3B0KS5zKCkpOworICBFWFBFQ1RfRVEoIkZpZWxkQW5ub3RhdGlvbiIsCisgICAgICAgICAgICBmaWVsZC0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmllbGRvcHQpLnMoKSk7CisgIEVYUEVDVF9FUSgiRW51bUFubm90YXRpb24iLAorICAgICAgICAgICAgZW51bWQtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmVudW1vcHQpLnMoKSk7CisgIEVYUEVDVF9FUSgiRW51bVZhbHVlQW5ub3RhdGlvbiIsCisgICAgICAgICAgICBlbnVtdi0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZW51bXZhbG9wdCkucygpKTsKKyAgRVhQRUNUX0VRKCJTZXJ2aWNlQW5ub3RhdGlvbiIsCisgICAgICAgICAgICBzZXJ2aWNlLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpzZXJ2aWNlb3B0KS5zKCkpOworICBFWFBFQ1RfRVEoIk1ldGhvZEFubm90YXRpb24iLAorICAgICAgICAgICAgbWV0aG9kLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjptZXRob2RvcHQpLnMoKSk7Cit9CisKK1RFU1QoQ3VzdG9tT3B0aW9ucywgVW51c2VkSW1wb3J0V2FybmluZykgeworICBEZXNjcmlwdG9yUG9vbCBwb29sOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zOjpkZXNjcmlwdG9yKCkKKyAgICAgIC0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworCisgIHBvb2wuQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJjdXN0b21fb3B0aW9uc19pbXBvcnQucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcImN1c3RvbV9vcHRpb25zX2ltcG9ydC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJwcm90b2J1Zl91bml0dGVzdFwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG9cIiAiLAorICAgICZmaWxlX3Byb3RvKSk7CisgIHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRoZSB0ZXN0cyBiZWxvdyB0cmlnZ2VyIGV2ZXJ5IHVuaXF1ZSBjYWxsIHRvIEFkZEVycm9yKCkgaW4gZGVzY3JpcHRvci5jYywKKy8vIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IGFwcGVhciBpbiB0aGF0IGZpbGUuICBJJ20gdXNpbmcgVGV4dEZvcm1hdCBoZXJlCisvLyB0byBzcGVjaWZ5IHRoZSBpbnB1dCBkZXNjcmlwdG9ycyBiZWNhdXNlIGJ1aWxkaW5nIHRoZW0gdXNpbmcgY29kZSB3b3VsZAorLy8gYmUgdG9vIGJ1bGt5LgorCitjbGFzcyBNb2NrRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIE1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisgIH5Nb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHN0cmluZyB0ZXh0XzsKKyAgc3RyaW5nIHdhcm5pbmdfdGV4dF87CisKKyAgLy8gaW1wbGVtZW50cyBFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZWxlbWVudF9uYW1lLCBjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgIEVycm9yTG9jYXRpb24gbG9jYXRpb24sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIGNvbnN0IGNoYXIqIGxvY2F0aW9uX25hbWUgPSBOVUxMOworICAgIHN3aXRjaCAobG9jYXRpb24pIHsKKyAgICAgIGNhc2UgTkFNRSAgICAgICAgIDogbG9jYXRpb25fbmFtZSA9ICJOQU1FIiAgICAgICAgIDsgYnJlYWs7CisgICAgICBjYXNlIE5VTUJFUiAgICAgICA6IGxvY2F0aW9uX25hbWUgPSAiTlVNQkVSIiAgICAgICA7IGJyZWFrOworICAgICAgY2FzZSBUWVBFICAgICAgICAgOiBsb2NhdGlvbl9uYW1lID0gIlRZUEUiICAgICAgICAgOyBicmVhazsKKyAgICAgIGNhc2UgRVhURU5ERUUgICAgIDogbG9jYXRpb25fbmFtZSA9ICJFWFRFTkRFRSIgICAgIDsgYnJlYWs7CisgICAgICBjYXNlIERFRkFVTFRfVkFMVUU6IGxvY2F0aW9uX25hbWUgPSAiREVGQVVMVF9WQUxVRSI7IGJyZWFrOworICAgICAgY2FzZSBPUFRJT05fTkFNRSAgOiBsb2NhdGlvbl9uYW1lID0gIk9QVElPTl9OQU1FIiAgOyBicmVhazsKKyAgICAgIGNhc2UgT1BUSU9OX1ZBTFVFIDogbG9jYXRpb25fbmFtZSA9ICJPUFRJT05fVkFMVUUiIDsgYnJlYWs7CisgICAgICBjYXNlIElOUFVUX1RZUEUgICA6IGxvY2F0aW9uX25hbWUgPSAiSU5QVVRfVFlQRSIgICA7IGJyZWFrOworICAgICAgY2FzZSBPVVRQVVRfVFlQRSAgOiBsb2NhdGlvbl9uYW1lID0gIk9VVFBVVF9UWVBFIiAgOyBicmVhazsKKyAgICAgIGNhc2UgT1RIRVIgICAgICAgIDogbG9jYXRpb25fbmFtZSA9ICJPVEhFUiIgICAgICAgIDsgYnJlYWs7CisgICAgfQorCisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgKKyAgICAgICZ0ZXh0XywgIiQwOiAkMTogJDI6ICQzXG4iLAorICAgICAgZmlsZW5hbWUsIGVsZW1lbnRfbmFtZSwgbG9jYXRpb25fbmFtZSwgbWVzc2FnZSk7CisgIH0KKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZFdhcm5pbmcoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLCBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgY29uc3QgY2hhciogbG9jYXRpb25fbmFtZSA9IE5VTEw7CisgICAgc3dpdGNoIChsb2NhdGlvbikgeworICAgICAgY2FzZSBOQU1FICAgICAgICAgOiBsb2NhdGlvbl9uYW1lID0gIk5BTUUiICAgICAgICAgOyBicmVhazsKKyAgICAgIGNhc2UgTlVNQkVSICAgICAgIDogbG9jYXRpb25fbmFtZSA9ICJOVU1CRVIiICAgICAgIDsgYnJlYWs7CisgICAgICBjYXNlIFRZUEUgICAgICAgICA6IGxvY2F0aW9uX25hbWUgPSAiVFlQRSIgICAgICAgICA7IGJyZWFrOworICAgICAgY2FzZSBFWFRFTkRFRSAgICAgOiBsb2NhdGlvbl9uYW1lID0gIkVYVEVOREVFIiAgICAgOyBicmVhazsKKyAgICAgIGNhc2UgREVGQVVMVF9WQUxVRTogbG9jYXRpb25fbmFtZSA9ICJERUZBVUxUX1ZBTFVFIjsgYnJlYWs7CisgICAgICBjYXNlIE9QVElPTl9OQU1FICA6IGxvY2F0aW9uX25hbWUgPSAiT1BUSU9OX05BTUUiICA7IGJyZWFrOworICAgICAgY2FzZSBPUFRJT05fVkFMVUUgOiBsb2NhdGlvbl9uYW1lID0gIk9QVElPTl9WQUxVRSIgOyBicmVhazsKKyAgICAgIGNhc2UgSU5QVVRfVFlQRSAgIDogbG9jYXRpb25fbmFtZSA9ICJJTlBVVF9UWVBFIiAgIDsgYnJlYWs7CisgICAgICBjYXNlIE9VVFBVVF9UWVBFICA6IGxvY2F0aW9uX25hbWUgPSAiT1VUUFVUX1RZUEUiICA7IGJyZWFrOworICAgICAgY2FzZSBPVEhFUiAgICAgICAgOiBsb2NhdGlvbl9uYW1lID0gIk9USEVSIiAgICAgICAgOyBicmVhazsKKyAgICB9CisKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKAorICAgICAgJndhcm5pbmdfdGV4dF8sICIkMDogJDE6ICQyOiAkM1xuIiwKKyAgICAgIGZpbGVuYW1lLCBlbGVtZW50X25hbWUsIGxvY2F0aW9uX25hbWUsIG1lc3NhZ2UpOworICB9Cit9OworCitjbGFzcyBWYWxpZGF0aW9uRXJyb3JUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgLy8gUGFyc2UgZmlsZV90ZXh0IGFzIGEgRmlsZURlc2NyaXB0b3JQcm90byBpbiB0ZXh0IGZvcm1hdCBhbmQgYWRkIGl0CisgIC8vIHRvIHRoZSBEZXNjcmlwdG9yUG9vbC4gIEV4cGVjdCBubyBlcnJvcnMuCisgIHZvaWQgQnVpbGRGaWxlKGNvbnN0IHN0cmluZyYgZmlsZV90ZXh0KSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICAgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhmaWxlX3RleHQsICZmaWxlX3Byb3RvKSk7CisgICAgQVNTRVJUX1RSVUUocG9vbF8uQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworICB9CisKKyAgLy8gUGFyc2UgZmlsZV90ZXh0IGFzIGEgRmlsZURlc2NyaXB0b3JQcm90byBpbiB0ZXh0IGZvcm1hdCBhbmQgYWRkIGl0CisgIC8vIHRvIHRoZSBEZXNjcmlwdG9yUG9vbC4gIEV4cGVjdCBlcnJvcnMgdG8gYmUgcHJvZHVjZWQgd2hpY2ggbWF0Y2ggdGhlCisgIC8vIGdpdmVuIGVycm9yIHRleHQuCisgIHZvaWQgQnVpbGRGaWxlV2l0aEVycm9ycyhjb25zdCBzdHJpbmcmIGZpbGVfdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfZXJyb3JzKSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICAgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhmaWxlX3RleHQsICZmaWxlX3Byb3RvKSk7CisKKyAgICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICAgIEVYUEVDVF9UUlVFKAorICAgICAgcG9vbF8uQnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycyhmaWxlX3Byb3RvLCAmZXJyb3JfY29sbGVjdG9yKSA9PSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoZXhwZWN0ZWRfZXJyb3JzLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworICB9CisKKyAgLy8gUGFyc2UgZmlsZV90ZXh0IGFzIGEgRmlsZURlc2NyaXB0b3JQcm90byBpbiB0ZXh0IGZvcm1hdCBhbmQgYWRkIGl0CisgIC8vIHRvIHRoZSBEZXNjcmlwdG9yUG9vbC4gIEV4cGVjdCBlcnJvcnMgdG8gYmUgcHJvZHVjZWQgd2hpY2ggbWF0Y2ggdGhlCisgIC8vIGdpdmVuIHdhcm5pbmcgdGV4dC4KKyAgdm9pZCBCdWlsZEZpbGVXaXRoV2FybmluZ3MoY29uc3Qgc3RyaW5nJiBmaWxlX3RleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfd2FybmluZ3MpIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfdGV4dCwgJmZpbGVfcHJvdG8pKTsKKworICAgIE1vY2tFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgICAgRVhQRUNUX1RSVUUocG9vbF8uQnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycyhmaWxlX3Byb3RvLCAmZXJyb3JfY29sbGVjdG9yKSk7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3dhcm5pbmdzLCBlcnJvcl9jb2xsZWN0b3Iud2FybmluZ190ZXh0Xyk7CisgIH0KKworICAvLyBCdWlsZHMgc29tZSBhbHJlYWR5LXBhcnNlZCBmaWxlIGluIG91ciB0ZXN0IHBvb2wuCisgIHZvaWQgQnVpbGRGaWxlSW5UZXN0UG9vbChjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgICBmaWxlLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICAgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKyAgfQorCisgIC8vIEJ1aWxkIGRlc2NyaXB0b3IucHJvdG8gaW4gb3VyIHRlc3QgcG9vbC4gVGhpcyBhbGxvd3MgdXMgdG8gZXh0ZW5kIGl0IGluCisgIC8vIHRoZSB0ZXN0IHBvb2wsIHNvIHdlIGNhbiB0ZXN0IGN1c3RvbSBvcHRpb25zLgorICB2b2lkIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpIHsKKyAgICBCdWlsZEZpbGVJblRlc3RQb29sKERlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpLT5maWxlKCkpOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87Cit9OworCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQWxyZWFkeURlZmluZWQpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9IiwKKworICAgICJmb28ucHJvdG86IEZvbzogTkFNRTogXCJGb29cIiBpcyBhbHJlYWR5IGRlZmluZWQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEFscmVhZHlEZWZpbmVkSW5QYWNrYWdlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImZvby5iYXJcIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5iYXIuRm9vOiBOQU1FOiBcIkZvb1wiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiAiCisgICAgICAiXCJmb28uYmFyXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEFscmVhZHlEZWZpbmVkSW5PdGhlckZpbGUpIHsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9Iik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSIsCisKKyAgICAiYmFyLnByb3RvOiBGb286IE5BTUU6IFwiRm9vXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluIGZpbGUgIgorICAgICAgIlwiZm9vLnByb3RvXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFBhY2thZ2VBbHJlYWR5RGVmaW5lZCkgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcImZvb1wiIH0iKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwiZm9vLmJhclwiIiwKKworICAgICJiYXIucHJvdG86IGZvbzogTkFNRTogXCJmb29cIiBpcyBhbHJlYWR5IGRlZmluZWQgKGFzIHNvbWV0aGluZyBvdGhlciAiCisgICAgICAidGhhbiBhIHBhY2thZ2UpIGluIGZpbGUgXCJmb28ucHJvdG9cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW51bVZhbHVlQWxyZWFkeURlZmluZWRJblBhcmVudCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJGb29cIiB2YWx1ZSB7IG5hbWU6IFwiRk9PXCIgbnVtYmVyOiAxIH0gfSAiCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiQmFyXCIgdmFsdWUgeyBuYW1lOiBcIkZPT1wiIG51bWJlcjogMSB9IH0gIiwKKworICAgICJmb28ucHJvdG86IEZPTzogTkFNRTogXCJGT09cIiBpcyBhbHJlYWR5IGRlZmluZWQuXG4iCisgICAgImZvby5wcm90bzogRk9POiBOQU1FOiBOb3RlIHRoYXQgZW51bSB2YWx1ZXMgdXNlIEMrKyBzY29waW5nIHJ1bGVzLCAiCisgICAgICAibWVhbmluZyB0aGF0IGVudW0gdmFsdWVzIGFyZSBzaWJsaW5ncyBvZiB0aGVpciB0eXBlLCBub3QgY2hpbGRyZW4gb2YgIgorICAgICAgIml0LiAgVGhlcmVmb3JlLCBcIkZPT1wiIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgZ2xvYmFsIHNjb3BlLCBub3QgIgorICAgICAgImp1c3Qgd2l0aGluIFwiQmFyXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1WYWx1ZUFscmVhZHlEZWZpbmVkSW5QYXJlbnROb25HbG9iYWwpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwicGtnXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb1wiIHZhbHVlIHsgbmFtZTogXCJGT09cIiBudW1iZXI6IDEgfSB9ICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB2YWx1ZSB7IG5hbWU6IFwiRk9PXCIgbnVtYmVyOiAxIH0gfSAiLAorCisgICAgImZvby5wcm90bzogcGtnLkZPTzogTkFNRTogXCJGT09cIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gXCJwa2dcIi5cbiIKKyAgICAiZm9vLnByb3RvOiBwa2cuRk9POiBOQU1FOiBOb3RlIHRoYXQgZW51bSB2YWx1ZXMgdXNlIEMrKyBzY29waW5nIHJ1bGVzLCAiCisgICAgICAibWVhbmluZyB0aGF0IGVudW0gdmFsdWVzIGFyZSBzaWJsaW5ncyBvZiB0aGVpciB0eXBlLCBub3QgY2hpbGRyZW4gb2YgIgorICAgICAgIml0LiAgVGhlcmVmb3JlLCBcIkZPT1wiIG11c3QgYmUgdW5pcXVlIHdpdGhpbiBcInBrZ1wiLCBub3QganVzdCB3aXRoaW4gIgorICAgICAgIlwiQmFyXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1pc3NpbmdOYW1lKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyB9IiwKKworICAgICJmb28ucHJvdG86IDogTkFNRTogTWlzc2luZyBuYW1lLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnZhbGlkTmFtZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCIkXCIgfSIsCisKKyAgICAiZm9vLnByb3RvOiAkOiBOQU1FOiBcIiRcIiBpcyBub3QgYSB2YWxpZCBpZGVudGlmaWVyLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnZhbGlkUGFja2FnZU5hbWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwiZm9vLiRcIiIsCisKKyAgICAiZm9vLnByb3RvOiBmb28uJDogTkFNRTogXCIkXCIgaXMgbm90IGEgdmFsaWQgaWRlbnRpZmllci5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWlzc2luZ0ZpbGVOYW1lKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIiIsCisKKyAgICAiOiA6IE9USEVSOiBNaXNzaW5nIGZpZWxkOiBGaWxlRGVzY3JpcHRvclByb3RvLm5hbWUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIER1cGVEZXBlbmRlbmN5KSB7CisgIEJ1aWxkRmlsZSgibmFtZTogXCJmb28ucHJvdG9cIiIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZm9vLnByb3RvXCIgIiwKKworICAgICJiYXIucHJvdG86IGJhci5wcm90bzogT1RIRVI6IEltcG9ydCBcImZvby5wcm90b1wiIHdhcyBsaXN0ZWQgdHdpY2UuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFVua25vd25EZXBlbmRlbmN5KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvby5wcm90b1wiICIsCisKKyAgICAiYmFyLnByb3RvOiBiYXIucHJvdG86IE9USEVSOiBJbXBvcnQgXCJmb28ucHJvdG9cIiBoYXMgbm90IGJlZW4gbG9hZGVkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnZhbGlkUHVibGljRGVwZW5kZW5jeUluZGV4KSB7CisgIEJ1aWxkRmlsZSgibmFtZTogXCJmb28ucHJvdG9cIiIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiAiCisgICAgInB1YmxpY19kZXBlbmRlbmN5OiAxIiwKKyAgICAiYmFyLnByb3RvOiBiYXIucHJvdG86IE9USEVSOiBJbnZhbGlkIHB1YmxpYyBkZXBlbmRlbmN5IGluZGV4LlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBGb3JlaWduVW5pbXBvcnRlZFBhY2thZ2VOb0NyYXNoKSB7CisgIC8vIFVzZWQgdG8gY3Jhc2g6ICBJZiB3ZSBkZXBlbmQgb24gYSBub24tZXhpc3RlbnQgZmlsZSBhbmQgdGhlbiByZWZlciB0byBhCisgIC8vIHBhY2thZ2UgZGVmaW5lZCBpbiBhIGZpbGUgdGhhdCB3ZSBkaWRuJ3QgaW1wb3J0LCBhbmQgdGhhdCBwYWNrYWdlIGlzCisgIC8vIG5lc3RlZCB3aXRoaW4gYSBwYXJlbnQgcGFja2FnZSB3aGljaCB0aGlzIGZpbGUgaXMgYWxzbyBpbiwgYW5kIHdlIGRvbid0CisgIC8vIGluY2x1ZGUgdGhhdCBwYXJlbnQgcGFja2FnZSBpbiB0aGUgbmFtZSAoaS5lLiB3ZSBkbyBhIHJlbGF0aXZlIGxvb2t1cCkuLi4KKyAgLy8gWWVzLCByZWFsbHkuCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICJwYWNrYWdlOiAnb3V0ZXIuZm9vJyAiKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogJ2Jhci5wcm90bycgIgorICAgICJkZXBlbmRlbmN5OiAnYmF6LnByb3RvJyAiCisgICAgInBhY2thZ2U6ICdvdXRlci5iYXInICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6ICdCYXInICIKKyAgICAiICBmaWVsZCB7IG5hbWU6J2JhcicgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOidmb28uRm9vJyB9IgorICAgICJ9IiwKKworICAgICJiYXIucHJvdG86IGJhci5wcm90bzogT1RIRVI6IEltcG9ydCBcImJhei5wcm90b1wiIGhhcyBub3QgYmVlbiBsb2FkZWQuXG4iCisgICAgImJhci5wcm90bzogb3V0ZXIuYmFyLkJhci5iYXI6IFRZUEU6IFwib3V0ZXIuZm9vXCIgc2VlbXMgdG8gYmUgZGVmaW5lZCBpbiAiCisgICAgICAiXCJmb28ucHJvdG9cIiwgd2hpY2ggaXMgbm90IGltcG9ydGVkIGJ5IFwiYmFyLnByb3RvXCIuICBUbyB1c2UgaXQgaGVyZSwgIgorICAgICAgInBsZWFzZSBhZGQgdGhlIG5lY2Vzc2FyeSBpbXBvcnQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIER1cGVGaWxlKSB7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSIpOworICAvLyBOb3RlOiAgV2Ugc2hvdWxkICpub3QqIGdldCByZWR1bmRhbnQgZXJyb3JzIGFib3V0ICJGb28iIGFscmVhZHkgYmVpbmcKKyAgLy8gICBkZWZpbmVkLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9ICIKKyAgICAvLyBBZGQgYW5vdGhlciB0eXBlIHNvIHRoYXQgdGhlIGZpbGVzIGFyZW4ndCBpZGVudGljYWwgKGluIHdoaWNoIGNhc2UgdGhlcmUKKyAgICAvLyB3b3VsZCBiZSBubyBlcnJvcikuCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiQmFyXCIgfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9USEVSOiBBIGZpbGUgd2l0aCB0aGlzIG5hbWUgaXMgYWxyZWFkeSBpbiB0aGUgIgorICAgICAgInBvb2wuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkSW5FeHRlbnNpb25SYW5nZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAgOSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiYmFyXCIgbnVtYmVyOiAxMCBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiYmF6XCIgbnVtYmVyOiAxOSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwicXV4XCIgbnVtYmVyOiAyMCBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMTAgZW5kOiAyMCB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5iYXI6IE5VTUJFUjogRXh0ZW5zaW9uIHJhbmdlIDEwIHRvIDE5IGluY2x1ZGVzIGZpZWxkICIKKyAgICAgICJcImJhclwiICgxMCkuXG4iCisgICAgImZvby5wcm90bzogRm9vLmJhejogTlVNQkVSOiBFeHRlbnNpb24gcmFuZ2UgMTAgdG8gMTkgaW5jbHVkZXMgZmllbGQgIgorICAgICAgIlwiYmF6XCIgKDE5KS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgT3ZlcmxhcHBpbmdFeHRlbnNpb25SYW5nZXMpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEwIGVuZDogMjAgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMjAgZW5kOiAzMCB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxOSBlbmQ6IDIxIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vOiBOVU1CRVI6IEV4dGVuc2lvbiByYW5nZSAxOSB0byAyMCBvdmVybGFwcyB3aXRoICIKKyAgICAgICJhbHJlYWR5LWRlZmluZWQgcmFuZ2UgMTAgdG8gMTkuXG4iCisgICAgImZvby5wcm90bzogRm9vOiBOVU1CRVI6IEV4dGVuc2lvbiByYW5nZSAxOSB0byAyMCBvdmVybGFwcyB3aXRoICIKKyAgICAgICJhbHJlYWR5LWRlZmluZWQgcmFuZ2UgMjAgdG8gMjkuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludmFsaWREZWZhdWx0cykgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKworICAgIC8vIEludmFsaWQgbnVtYmVyLgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDEgbGFiZWw6IExBQkVMX09QVElPTkFMIHR5cGU6IFRZUEVfSU5UMzIiCisgICAgIiAgICAgICAgICBkZWZhdWx0X3ZhbHVlOiBcImFiY1wiIH0iCisKKyAgICAvLyBFbXB0eSBkZWZhdWx0IHZhbHVlLgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJiYXJcIiBudW1iZXI6IDIgbGFiZWw6IExBQkVMX09QVElPTkFMIHR5cGU6IFRZUEVfSU5UMzIiCisgICAgIiAgICAgICAgICBkZWZhdWx0X3ZhbHVlOiBcIlwiIH0iCisKKyAgICAvLyBJbnZhbGlkIGJvb2xlYW4uCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImJhelwiIG51bWJlcjogMyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9CT09MIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogXCJhYmNcIiB9IgorCisgICAgLy8gTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0cy4KKyAgICAiICBmaWVsZCB7IG5hbWU6IFwicXV4XCIgbnVtYmVyOiA0IGxhYmVsOiBMQUJFTF9PUFRJT05BTCB0eXBlOiBUWVBFX01FU1NBR0UiCisgICAgIiAgICAgICAgICBkZWZhdWx0X3ZhbHVlOiBcImFiY1wiIHR5cGVfbmFtZTogXCJGb29cIiB9IgorCisgICAgLy8gU2FtZSB0aGluZywgYnV0IHdlIGRvbid0IGtub3cgdGhhdCB0aGlzIGZpZWxkIGhhcyBtZXNzYWdlIHR5cGUgdW50aWwKKyAgICAvLyB3ZSBsb29rIHVwIHRoZSB0eXBlIG5hbWUuCisgICAgIiAgZmllbGQgeyBuYW1lOiBcInF1dXhcIiBudW1iZXI6IDUgbGFiZWw6IExBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogXCJhYmNcIiB0eXBlX25hbWU6IFwiRm9vXCIgfSIKKworICAgIC8vIFJlcGVhdGVkcyBjYW4ndCBoYXZlIGRlZmF1bHRzLgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJjb3JnZVwiIG51bWJlcjogNiBsYWJlbDogTEFCRUxfUkVQRUFURUQgdHlwZTogVFlQRV9JTlQzMiIKKyAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6IFwiMVwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogREVGQVVMVF9WQUxVRTogQ291bGRuJ3QgcGFyc2UgZGVmYXVsdCB2YWx1ZSBcImFiY1wiLlxuIgorICAgICJmb28ucHJvdG86IEZvby5iYXI6IERFRkFVTFRfVkFMVUU6IENvdWxkbid0IHBhcnNlIGRlZmF1bHQgdmFsdWUgXCJcIi5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28uYmF6OiBERUZBVUxUX1ZBTFVFOiBCb29sZWFuIGRlZmF1bHQgbXVzdCBiZSB0cnVlIG9yICIKKyAgICAgICJmYWxzZS5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28ucXV4OiBERUZBVUxUX1ZBTFVFOiBNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzLlxuIgorICAgICJmb28ucHJvdG86IEZvby5jb3JnZTogREVGQVVMVF9WQUxVRTogUmVwZWF0ZWQgZmllbGRzIGNhbid0IGhhdmUgZGVmYXVsdCAiCisgICAgICAidmFsdWVzLlxuIgorICAgIC8vIFRoaXMgZW5kcyB1cCBiZWluZyByZXBvcnRlZCBsYXRlciBiZWNhdXNlIHRoZSBlcnJvciBpcyBkZXRlY3RlZCBhdAorICAgIC8vIGNyb3NzLWxpbmtpbmcgdGltZS4KKyAgICAiZm9vLnByb3RvOiBGb28ucXV1eDogREVGQVVMVF9WQUxVRTogTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0ICIKKyAgICAgICJ2YWx1ZXMuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5lZ2F0aXZlRmllbGROdW1iZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImZvb1wiIG51bWJlcjogLTEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogTlVNQkVSOiBGaWVsZCBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEh1Z2VGaWVsZE51bWJlcikgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAweDcwMDAwMDAwICIKKyAgICAiICAgICAgICAgIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IE5VTUJFUjogRmllbGQgbnVtYmVycyBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuICIKKyAgICAgICI1MzY4NzA5MTEuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFJlc2VydmVkRmllbGROdW1iZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQge25hbWU6XCJmb29cIiBudW1iZXI6IDE4OTk5IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGZpZWxkIHtuYW1lOlwiYmFyXCIgbnVtYmVyOiAxOTAwMCBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7bmFtZTpcImJhelwiIG51bWJlcjogMTk5OTkgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgIiAgZmllbGQge25hbWU6XCJxdXhcIiBudW1iZXI6IDIwMDAwIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5iYXI6IE5VTUJFUjogRmllbGQgbnVtYmVycyAxOTAwMCB0aHJvdWdoIDE5OTk5IGFyZSAiCisgICAgICAicmVzZXJ2ZWQgZm9yIHRoZSBwcm90b2NvbCBidWZmZXIgbGlicmFyeSBpbXBsZW1lbnRhdGlvbi5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28uYmF6OiBOVU1CRVI6IEZpZWxkIG51bWJlcnMgMTkwMDAgdGhyb3VnaCAxOTk5OSBhcmUgIgorICAgICAgInJlc2VydmVkIGZvciB0aGUgcHJvdG9jb2wgYnVmZmVyIGxpYnJhcnkgaW1wbGVtZW50YXRpb24uXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEV4dGVuc2lvbk1pc3NpbmdFeHRlbmRlZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogMSBsYWJlbDogTEFCRUxfT1BUSU9OQUwiCisgICAgIiAgICAgICAgICAgICAgdHlwZV9uYW1lOiBcIkZvb1wiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogRVhURU5ERUU6IEZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlIG5vdCBzZXQgZm9yICIKKyAgICAgICJleHRlbnNpb24gZmllbGQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5vbkV4dGVuc2lvbldpdGhFeHRlbmRlZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDIgfSIKKyAgICAifSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAxIGxhYmVsOiBMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTogXCJGb29cIiBleHRlbmRlZTogXCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IEVYVEVOREVFOiBGaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSBzZXQgZm9yICIKKyAgICAgICJub24tZXh0ZW5zaW9uIGZpZWxkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZE9uZW9mSW5kZXhUb29MYXJnZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6IDEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJkdW1teVwiIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogMCB9IgorICAgICIgIG9uZW9mX2RlY2wgeyBuYW1lOlwiYmFyXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBPVEhFUjogRmllbGREZXNjcmlwdG9yUHJvdG8ub25lb2ZfaW5kZXggMSBpcyBvdXQgb2YgIgorICAgICAgInJhbmdlIGZvciB0eXBlIFwiRm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkT25lb2ZJbmRleE5lZ2F0aXZlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogLTEgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJkdW1teVwiIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogMCB9IgorICAgICIgIG9uZW9mX2RlY2wgeyBuYW1lOlwiYmFyXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBPVEhFUjogRmllbGREZXNjcmlwdG9yUHJvdG8ub25lb2ZfaW5kZXggLTEgaXMgb3V0IG9mICIKKyAgICAgICJyYW5nZSBmb3IgdHlwZSBcIkZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZE51bWJlckNvbmZsaWN0KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImJhclwiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uYmFyOiBOVU1CRVI6IEZpZWxkIG51bWJlciAxIGhhcyBhbHJlYWR5IGJlZW4gdXNlZCBpbiAiCisgICAgICAiXCJGb29cIiBieSBmaWVsZCBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBCYWRNZXNzYWdlU2V0RXh0ZW5zaW9uVHlwZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJNZXNzYWdlU2V0XCIiCisgICAgIiAgb3B0aW9ucyB7IG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0OiB0cnVlIH0iCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDQgZW5kOiA1IH0iCisgICAgIn0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIG51bWJlcjo0IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgICAgICAgICAgICBleHRlbmRlZTogXCJNZXNzYWdlU2V0XCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBUWVBFOiBFeHRlbnNpb25zIG9mIE1lc3NhZ2VTZXRzIG11c3QgYmUgb3B0aW9uYWwgIgorICAgICAgIm1lc3NhZ2VzLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBCYWRNZXNzYWdlU2V0RXh0ZW5zaW9uTGFiZWwpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiTWVzc2FnZVNldFwiIgorICAgICIgIG9wdGlvbnMgeyBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdDogdHJ1ZSB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiA0IGVuZDogNSB9IgorICAgICJ9IgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGV4dGVuc2lvbiB7IG5hbWU6XCJmb29cIiBudW1iZXI6NCBsYWJlbDpMQUJFTF9SRVBFQVRFRCB0eXBlOlRZUEVfTUVTU0FHRSIKKyAgICAiICAgICAgICAgICAgICB0eXBlX25hbWU6IFwiRm9vXCIgZXh0ZW5kZWU6IFwiTWVzc2FnZVNldFwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogRXh0ZW5zaW9ucyBvZiBNZXNzYWdlU2V0cyBtdXN0IGJlIG9wdGlvbmFsICIKKyAgICAgICJtZXNzYWdlcy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRJbk1lc3NhZ2VTZXQpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgb3B0aW9ucyB7IG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0OiB0cnVlIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImZvb1wiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBOQU1FOiBNZXNzYWdlU2V0cyBjYW5ub3QgaGF2ZSBmaWVsZHMsIG9ubHkgIgorICAgICAgImV4dGVuc2lvbnMuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5lZ2F0aXZlRXh0ZW5zaW9uUmFuZ2VOdW1iZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IC0xMCBlbmQ6IC0xIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vOiBOVU1CRVI6IEV4dGVuc2lvbiBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEh1Z2VFeHRlbnNpb25SYW5nZU51bWJlcikgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDB4NzAwMDAwMDAgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb286IE5VTUJFUjogRXh0ZW5zaW9uIG51bWJlcnMgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiAiCisgICAgICAiNTM2ODcwOTExLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBFeHRlbnNpb25SYW5nZUVuZEJlZm9yZVN0YXJ0KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxMCBlbmQ6IDEwIH0iCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEwIGVuZDogNSB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvbzogTlVNQkVSOiBFeHRlbnNpb24gcmFuZ2UgZW5kIG51bWJlciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAiCisgICAgICAic3RhcnQgbnVtYmVyLlxuIgorICAgICJmb28ucHJvdG86IEZvbzogTlVNQkVSOiBFeHRlbnNpb24gcmFuZ2UgZW5kIG51bWJlciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAiCisgICAgICAic3RhcnQgbnVtYmVyLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBFbXB0eUVudW0pIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSIKKyAgICAvLyBBbHNvIHVzZSB0aGUgZW1wdHkgZW51bSBpbiBhIG1lc3NhZ2UgdG8gbWFrZSBzdXJlIHRoZXJlIGFyZSBubyBjcmFzaGVzCisgICAgLy8gZHVyaW5nIHZhbGlkYXRpb24gKHBvc3NpYmxlIGlmIHRoZSBjb2RlIGF0dGVtcHRzIHRvIGRlcml2ZSBhIGRlZmF1bHQKKyAgICAvLyB2YWx1ZSBmb3IgdGhlIGZpZWxkKS4KKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkZvb1wiIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImJhclwiIG51bWJlcjogMiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJGb29cIiAiCisgICAgIiAgICAgICAgICBkZWZhdWx0X3ZhbHVlOiBcIk5PX1NVQ0hfVkFMVUVcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvbzogTkFNRTogRW51bXMgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSB2YWx1ZS5cbiIKKyAgICAiZm9vLnByb3RvOiBCYXIuYmFyOiBERUZBVUxUX1ZBTFVFOiBFbnVtIHR5cGUgXCJGb29cIiBoYXMgbm8gdmFsdWUgbmFtZWQgIgorICAgICAgIlwiTk9fU1VDSF9WQUxVRVwiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVbmRlZmluZWRFeHRlbmRlZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIgorICAgICIgICAgICAgICAgICAgIGV4dGVuZGVlOiBcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogRVhURU5ERUU6IFwiQmFyXCIgaXMgbm90IGRlZmluZWQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5vbk1lc3NhZ2VFeHRlbmRlZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB2YWx1ZSB7IG5hbWU6XCJEVU1NWVwiIG51bWJlcjowIH0gfSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIgorICAgICIgICAgICAgICAgICAgIGV4dGVuZGVlOiBcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogRVhURU5ERUU6IFwiQmFyXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBOb3RBbkV4dGVuc2lvbk51bWJlcikgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAifSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIgorICAgICIgICAgICAgICAgICAgIGV4dGVuZGVlOiBcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogTlVNQkVSOiBcIkJhclwiIGRvZXMgbm90IGRlY2xhcmUgMSBhcyBhbiBleHRlbnNpb24gIgorICAgICAgIm51bWJlci5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVxdWlyZWRFeHRlbnNpb24pIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEwMDAgZW5kOiAxMDAwMCB9IgorICAgICJ9IgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGV4dGVuc2lvbiB7IgorICAgICIgICAgbmFtZTpcImZvb1wiIgorICAgICIgICAgbnVtYmVyOjEwMDAiCisgICAgIiAgICBsYWJlbDpMQUJFTF9SRVFVSVJFRCIKKyAgICAiICAgIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgIGV4dGVuZGVlOiBcIkJhclwiIgorICAgICIgIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogTWVzc2FnZSBleHRlbnNpb25zIGNhbm5vdCBoYXZlIHJlcXVpcmVkICIKKyAgICAiZmllbGRzLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVbmRlZmluZWRGaWVsZFR5cGUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBUWVBFOiBcIkJhclwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVbmRlZmluZWRGaWVsZFR5cGVXaXRoRGVmYXVsdCkgeworICAvLyBTZWUgYi8xMjUzMzU4Mi4gUHJldmlvdXNseSB0aGlzIGZhaWxlZCBiZWNhdXNlIHRoZSBkZWZhdWx0IHZhbHVlIHdhcyBub3QKKyAgLy8gYWNjZXB0ZWQgYnkgdGhlIHBhcnNlciwgd2hpY2ggYXNzdW1lZCBhbiBlbnVtIHR5cGUsIGxlYWRpbmcgdG8gYW4gdW5jbGVhcgorICAvLyBlcnJvciBtZXNzYWdlLiBXZSB3YW50IHRoaXMgaW5wdXQgdG8geWllbGQgYSB2YWxpZGF0aW9uIGVycm9yIGluc3RlYWQsCisgIC8vIHNpbmNlIHRoZSB1bmtub3duIHR5cGUgaXMgdGhlIHByaW1hcnkgcHJvYmxlbS4KKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiaW50XCIgIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTpcIjFcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiaW50XCIgaXMgbm90IGRlZmluZWQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFVuZGVmaW5lZE5lc3RlZEZpZWxkVHlwZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBuZXN0ZWRfdHlwZSB7IG5hbWU6XCJCYXpcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIgorICAgICIgICAgICAgICAgbGFiZWw6TEFCRUxfT1BUSU9OQUwiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6XCJGb28uQmF6LkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJGb28uQmF6LkJhclwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZFR5cGVEZWZpbmVkSW5VbmRlY2xhcmVkRGVwZW5kZW5jeSkgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhclwiIH0gIik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIsCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXJcIiBzZWVtcyB0byBiZSBkZWZpbmVkIGluIFwiYmFyLnByb3RvXCIsICIKKyAgICAgICJ3aGljaCBpcyBub3QgaW1wb3J0ZWQgYnkgXCJmb28ucHJvdG9cIi4gIFRvIHVzZSBpdCBoZXJlLCBwbGVhc2UgYWRkIHRoZSAiCisgICAgICAibmVjZXNzYXJ5IGltcG9ydC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlRGVmaW5lZEluSW5kaXJlY3REZXBlbmRlbmN5KSB7CisgIC8vIFRlc3QgZm9yIGhpZGRlbiBkZXBlbmRlbmNpZXMuCisgIC8vCisgIC8vIC8vIGJhci5wcm90bworICAvLyBtZXNzYWdlIEJhcnt9CisgIC8vCisgIC8vIC8vIGZvcndhcmQucHJvdG8KKyAgLy8gaW1wb3J0ICJiYXIucHJvdG8iCisgIC8vCisgIC8vIC8vIGZvby5wcm90bworICAvLyBpbXBvcnQgImZvcndhcmQucHJvdG8iCisgIC8vIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICBvcHRpb25hbCBCYXIgZm9vID0gMTsgIC8vIEVycm9yLCBuZWVkcyB0byBpbXBvcnQgYmFyLnByb3RvIGV4cGxpY2l0bHkuCisgIC8vIH0KKyAgLy8KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9Iik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvcndhcmQucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvcndhcmQucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIsCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXJcIiBzZWVtcyB0byBiZSBkZWZpbmVkIGluIFwiYmFyLnByb3RvXCIsICIKKyAgICAgICJ3aGljaCBpcyBub3QgaW1wb3J0ZWQgYnkgXCJmb28ucHJvdG9cIi4gIFRvIHVzZSBpdCBoZXJlLCBwbGVhc2UgYWRkIHRoZSAiCisgICAgICAibmVjZXNzYXJ5IGltcG9ydC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlRGVmaW5lZEluUHVibGljRGVwZW5kZW5jeSkgeworICAvLyBUZXN0IGZvciBwdWJsaWMgZGVwZW5kZW5jaWVzLgorICAvLworICAvLyAvLyBiYXIucHJvdG8KKyAgLy8gbWVzc2FnZSBCYXJ7fQorICAvLworICAvLyAvLyBmb3J3YXJkLnByb3RvCisgIC8vIGltcG9ydCBwdWJsaWMgImJhci5wcm90byIKKyAgLy8KKyAgLy8gLy8gZm9vLnByb3RvCisgIC8vIGltcG9ydCAiZm9yd2FyZC5wcm90byIKKyAgLy8gbWVzc2FnZSBGb28geworICAvLyAgIG9wdGlvbmFsIEJhciBmb28gPSAxOyAgLy8gQ29ycmVjdC4gImJhci5wcm90byIgaXMgcHVibGljIGltcG9ydGVkIGludG8KKyAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvcndhcmQucHJvdG8sIHNvIHdoZW4gImZvby5wcm90byIgaW1wb3J0cworICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gImZvcndhcmQucHJvdG8iLCBpdCBpbXBvcnRzICJiYXIucHJvdG8iIHRvby4KKyAgLy8gfQorICAvLworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhclwiIH0iKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9yd2FyZC5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcImJhci5wcm90b1wiICIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDAiKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvcndhcmQucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlRGVmaW5lZEluVHJhbnNpdGl2ZVB1YmxpY0RlcGVuZGVuY3kpIHsKKyAgLy8gVGVzdCBmb3IgcHVibGljIGRlcGVuZGVuY2llcy4KKyAgLy8KKyAgLy8gLy8gYmFyLnByb3RvCisgIC8vIG1lc3NhZ2UgQmFye30KKyAgLy8KKyAgLy8gLy8gZm9yd2FyZC5wcm90bworICAvLyBpbXBvcnQgcHVibGljICJiYXIucHJvdG8iCisgIC8vCisgIC8vIC8vIGZvcndhcmQyLnByb3RvCisgIC8vIGltcG9ydCBwdWJsaWMgImZvcndhcmQucHJvdG8iCisgIC8vCisgIC8vIC8vIGZvby5wcm90bworICAvLyBpbXBvcnQgImZvcndhcmQyLnByb3RvIgorICAvLyBtZXNzYWdlIEZvbyB7CisgIC8vICAgb3B0aW9uYWwgQmFyIGZvbyA9IDE7ICAvLyBDb3JyZWN0LCBwdWJsaWMgaW1wb3J0cyBhcmUgdHJhbnNpdGl2ZS4KKyAgLy8gfQorICAvLworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhclwiIH0iKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9yd2FyZC5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcImJhci5wcm90b1wiICIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDAiKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9yd2FyZDIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJmb3J3YXJkLnByb3RvXCIgIgorICAgICJwdWJsaWNfZGVwZW5kZW5jeTogMCIpOworCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZm9yd2FyZDIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwKKyAgICAgICBGaWVsZFR5cGVEZWZpbmVkSW5Qcml2YXRlRGVwZW5kZW5jeU9mUHVibGljRGVwZW5kZW5jeSkgeworICAvLyBUZXN0IGZvciBwdWJsaWMgZGVwZW5kZW5jaWVzLgorICAvLworICAvLyAvLyBiYXIucHJvdG8KKyAgLy8gbWVzc2FnZSBCYXJ7fQorICAvLworICAvLyAvLyBmb3J3YXJkLnByb3RvCisgIC8vIGltcG9ydCAiYmFyLnByb3RvIgorICAvLworICAvLyAvLyBmb3J3YXJkMi5wcm90bworICAvLyBpbXBvcnQgcHVibGljICJmb3J3YXJkLnByb3RvIgorICAvLworICAvLyAvLyBmb28ucHJvdG8KKyAgLy8gaW1wb3J0ICJmb3J3YXJkMi5wcm90byIKKyAgLy8gbWVzc2FnZSBGb28geworICAvLyAgIG9wdGlvbmFsIEJhciBmb28gPSAxOyAgLy8gRXJyb3IsIHRoZSAiYmFyLnByb3RvIiBpcyBub3QgcHVibGljIGltcG9ydGVkCisgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRvICJmb3J3YXJkLnByb3RvIiwgc28gd2lsbCBub3QgYmUgaW1wb3J0ZWQKKyAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludG8gZWl0aGVyICJmb3J3YXJkMi5wcm90byIgb3IgImZvby5wcm90byIuCisgIC8vIH0KKyAgLy8KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9Iik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvcndhcmQucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIpOworCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb3J3YXJkMi5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcImZvcndhcmQucHJvdG9cIiAiCisgICAgInB1YmxpY19kZXBlbmRlbmN5OiAwIik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZm9yd2FyZDIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIsCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXJcIiBzZWVtcyB0byBiZSBkZWZpbmVkIGluIFwiYmFyLnByb3RvXCIsICIKKyAgICAgICJ3aGljaCBpcyBub3QgaW1wb3J0ZWQgYnkgXCJmb28ucHJvdG9cIi4gIFRvIHVzZSBpdCBoZXJlLCBwbGVhc2UgYWRkIHRoZSAiCisgICAgICAibmVjZXNzYXJ5IGltcG9ydC5cbiIpOworfQorCisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBTZWFyY2hNb3N0TG9jYWxGaXJzdCkgeworICAvLyBUaGUgZm9sbG93aW5nIHNob3VsZCBwcm9kdWNlIGFuIGVycm9yIHRoYXQgQmFyLkJheiBpcyByZXNvbHZlZCBidXQKKyAgLy8gbm90IGRlZmluZWQ6CisgIC8vICAgbWVzc2FnZSBCYXIgeyBtZXNzYWdlIEJheiB7fSB9CisgIC8vICAgbWVzc2FnZSBGb28geworICAvLyAgICAgbWVzc2FnZSBCYXIgeworICAvLyAgICAgICAvLyBQbGFjaW5nICJtZXNzYWdlIEJhent9IiBoZXJlLCBvciByZW1vdmluZyBGb28uQmFyIGFsdG9nZXRoZXIsCisgIC8vICAgICAgIC8vIHdvdWxkIGZpeCB0aGUgZXJyb3IuCisgIC8vICAgICB9CisgIC8vICAgICBvcHRpb25hbCBCYXIuQmF6IGJheiA9IDE7CisgIC8vICAgfQorICAvLyBBbiBvbmUgcG9pbnQgdGhlIGxvb2t1cCBjb2RlIGluY29ycmVjdGx5IGRpZCBub3QgcHJvZHVjZSBhbiBlcnJvciBpbiB0aGlzCisgIC8vIGNhc2UsIGJlY2F1c2Ugd2hlbiBsb29raW5nIGZvciBCYXIuQmF6LCBpdCB3b3VsZCB0cnkgIkZvby5CYXIuQmF6IiBmaXJzdCwKKyAgLy8gZmFpbCwgYW5kIHRlbiB0cnkgIkJhci5CYXoiIGFuZCBzdWNjZWVkLCBldmVuIHRob3VnaCAiQmFyIiBzaG91bGQgYWN0dWFsbHkKKyAgLy8gcmVmZXIgdG8gdGhlIGlubmVyIEJhciwgbm90IHRoZSBvdXRlciBvbmUuCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkJhclwiIgorICAgICIgIG5lc3RlZF90eXBlIHsgbmFtZTogXCJCYXpcIiB9IgorICAgICJ9IgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIG5lc3RlZF90eXBlIHsgbmFtZTogXCJCYXJcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImJhelwiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiQmFyLkJhelwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmJhejogVFlQRTogXCJCYXIuQmF6XCIgaXMgcmVzb2x2ZWQgdG8gXCJGb28uQmFyLkJhelwiLCIKKyAgICAiIHdoaWNoIGlzIG5vdCBkZWZpbmVkLiBUaGUgaW5uZXJtb3N0IHNjb3BlIGlzIHNlYXJjaGVkIGZpcnN0IGluIG5hbWUgIgorICAgICJyZXNvbHV0aW9uLiBDb25zaWRlciB1c2luZyBhIGxlYWRpbmcgJy4nKGkuZS4sIFwiLkJhci5CYXpcIikgdG8gc3RhcnQgIgorICAgICJmcm9tIHRoZSBvdXRlcm1vc3Qgc2NvcGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFNlYXJjaE1vc3RMb2NhbEZpcnN0MikgeworICAvLyBUaGlzIHRlc3Qgd291bGQgZmluZCB0aGUgbW9zdCBsb2NhbCAiQmFyIiBmaXJzdCwgYW5kIGRvZXMsIGJ1dAorICAvLyBwcm9jZWVkcyB0byBmaW5kIHRoZSBvdXRlciBvbmUgYmVjYXVzZSB0aGUgaW5uZXIgb25lJ3Mgbm90IGFuCisgIC8vIGFnZ3JlZ2F0ZS4KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAiICBuZXN0ZWRfdHlwZSB7IG5hbWU6IFwiQmF6XCIgfSIKKyAgICAifSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiQmFyXCIgbnVtYmVyOjEgdHlwZTpUWVBFX0JZVEVTIH0gIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImJhelwiIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiQmFyLkJhelwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFBhY2thZ2VPcmlnaW5hbGx5RGVjbGFyZWRJblRyYW5zaXRpdmVEZXBlbmRlbnQpIHsKKyAgLy8gSW1hZ2luZSB3ZSBoYXZlIHRoZSBmb2xsb3dpbmc6CisgIC8vCisgIC8vIGZvby5wcm90bzoKKyAgLy8gICBwYWNrYWdlIGZvby5iYXI7CisgIC8vIGJhci5wcm90bzoKKyAgLy8gICBwYWNrYWdlIGZvby5iYXI7CisgIC8vICAgaW1wb3J0ICJmb28ucHJvdG8iOworICAvLyAgIG1lc3NhZ2UgQmFyIHt9CisgIC8vIGJhei5wcm90bzoKKyAgLy8gICBwYWNrYWdlIGZvbzsKKyAgLy8gICBpbXBvcnQgImJhci5wcm90byIKKyAgLy8gICBtZXNzYWdlIEJheiB7IG9wdGlvbmFsIGJhci5CYXIgcXV4ID0gMTsgfQorICAvLworICAvLyBXaGVuIHZhbGlkYXRpbmcgYmF6LnByb3RvLCB3ZSB3aWxsIGxvb2sgdXAgImJhci5CYXIiLiAgQXMgcGFydCBvZiB0aGlzCisgIC8vIGxvb2t1cCwgd2UgZmlyc3QgbG9va3VwICJiYXIiIHRoZW4gdHJ5IHRvIGZpbmQgIkJhciIgd2l0aGluIGl0LiAgImJhciIKKyAgLy8gc2hvdWxkIHJlc29sdmUgdG8gImZvby5iYXIiLiAgTm90ZSwgdGhvdWdoLCB0aGF0ICJmb28uYmFyIiB3YXMgb3JpZ2luYWxseQorICAvLyBkZWZpbmVkIGluIGZvby5wcm90bywgd2hpY2ggaXMgbm90IGEgZGlyZWN0IGRlcGVuZGVuY3kgb2YgYmF6LnByb3RvLiAgVGhlCisgIC8vIGltcGxlbWVudGF0aW9uIG9mIEZpbmRTeW1ib2woKSBub3JtYWxseSBvbmx5IHJldHVybnMgc3ltYm9scyBpbiBkaXJlY3QKKyAgLy8gZGVwZW5kZW5jaWVzLCBub3QgaW5kaXJlY3Qgb25lcy4gIFRoaXMgdGVzdCBpbnN1cmVzIHRoYXQgdGhpcyBkb2VzIG5vdAorICAvLyBwcmV2ZW50IGl0IGZyb20gZmluZGluZyAiZm9vLmJhciIuCisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJmb28uYmFyXCIgIik7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwiZm9vLmJhclwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiQmFyXCIgfSIpOworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmF6LnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImZvb1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkJhelwiICIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJxdXhcIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6XCJiYXIuQmFyXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlTm90QVR5cGUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiLkZvby5iYXJcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImJhclwiIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiLkZvby5iYXJcIiBpcyBub3QgYSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZWxhdGl2ZUZpZWxkVHlwZU5vdEFUeXBlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuZXN0ZWRfdHlwZSB7IgorICAgICIgICAgbmFtZTogXCJCYXJcIiIKKyAgICAiICAgIGZpZWxkIHsgbmFtZTpcIkJhelwiIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIH0iCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6XCJCYXIuQmF6XCIgfSIKKyAgICAifSIsCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXIuQmF6XCIgaXMgbm90IGEgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlTWF5QmVJdHNOYW1lKSB7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIn0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiQmFyXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFyXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW51bUZpZWxkVHlwZUlzTWVzc2FnZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9ICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfRU5VTSIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXJcIiBpcyBub3QgYW4gZW51bSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNZXNzYWdlRmllbGRUeXBlSXNFbnVtKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkJhclwiIHZhbHVlIHsgbmFtZTpcIkRVTU1ZXCIgbnVtYmVyOjAgfSB9ICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfTUVTU0FHRSIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXJcIiBpcyBub3QgYSBtZXNzYWdlIHR5cGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEJhZEVudW1EZWZhdWx0VmFsdWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiQmFyXCIgdmFsdWUgeyBuYW1lOlwiRFVNTVlcIiBudW1iZXI6MCB9IH0gIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTpcIk5PX1NVQ0hfVkFMVUVcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IERFRkFVTFRfVkFMVUU6IEVudW0gdHlwZSBcIkJhclwiIGhhcyBubyB2YWx1ZSBuYW1lZCAiCisgICAgICAiXCJOT19TVUNIX1ZBTFVFXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1EZWZhdWx0VmFsdWVJc0ludGVnZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiQmFyXCIgdmFsdWUgeyBuYW1lOlwiRFVNTVlcIiBudW1iZXI6MCB9IH0gIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTpcIjBcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IERFRkFVTFRfVkFMVUU6IERlZmF1bHQgdmFsdWUgZm9yIGFuIGVudW0gZmllbGQgbXVzdCAiCisgICAgImJlIGFuIGlkZW50aWZpZXIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFByaW1pdGl2ZVdpdGhUeXBlTmFtZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6XCJGb29cIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IEZpZWxkIHdpdGggcHJpbWl0aXZlIHR5cGUgaGFzIHR5cGVfbmFtZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTm9uUHJpbWl0aXZlV2l0aG91dFR5cGVOYW1lKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9NRVNTQUdFIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogRmllbGQgd2l0aCBtZXNzYWdlIG9yIGVudW0gdHlwZSBtaXNzaW5nICIKKyAgICAgICJ0eXBlX25hbWUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE9uZW9mV2l0aE5vRmllbGRzKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIG9uZW9mX2RlY2wgeyBuYW1lOlwiYmFyXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uYmFyOiBOQU1FOiBPbmVvZiBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGZpZWxkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBPbmVvZkxhYmVsTWlzbWF0Y2gpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfUkVQRUFURUQgdHlwZTpUWVBFX0lOVDMyICIKKyAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OjAgfSIKKyAgICAiICBvbmVvZl9kZWNsIHsgbmFtZTpcImJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogTkFNRTogRmllbGRzIG9mIG9uZW9mcyBtdXN0IHRoZW1zZWx2ZXMgaGF2ZSBsYWJlbCAiCisgICAgICAiTEFCRUxfT1BUSU9OQUwuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIElucHV0VHlwZU5vdERlZmluZWQpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSAiCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTogXCJBXCIgaW5wdXRfdHlwZTogXCJCYXJcIiBvdXRwdXRfdHlwZTogXCJGb29cIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IFRlc3RTZXJ2aWNlLkE6IElOUFVUX1RZUEU6IFwiQmFyXCIgaXMgbm90IGRlZmluZWQuXG4iCisgICAgKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIElucHV0VHlwZU5vdEFNZXNzYWdlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkJhclwiIHZhbHVlIHsgbmFtZTpcIkRVTU1ZXCIgbnVtYmVyOjAgfSB9ICIKKyAgICAic2VydmljZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdFNlcnZpY2VcIiIKKyAgICAiICBtZXRob2QgeyBuYW1lOiBcIkFcIiBpbnB1dF90eXBlOiBcIkJhclwiIG91dHB1dF90eXBlOiBcIkZvb1wiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogVGVzdFNlcnZpY2UuQTogSU5QVVRfVFlQRTogXCJCYXJcIiBpcyBub3QgYSBtZXNzYWdlIHR5cGUuXG4iCisgICAgKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE91dHB1dFR5cGVOb3REZWZpbmVkKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIgorICAgICJzZXJ2aWNlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0U2VydmljZVwiIgorICAgICIgIG1ldGhvZCB7IG5hbWU6IFwiQVwiIGlucHV0X3R5cGU6IFwiRm9vXCIgb3V0cHV0X3R5cGU6IFwiQmFyXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBUZXN0U2VydmljZS5BOiBPVVRQVVRfVFlQRTogXCJCYXJcIiBpcyBub3QgZGVmaW5lZC5cbiIKKyAgICApOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgT3V0cHV0VHlwZU5vdEFNZXNzYWdlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkJhclwiIHZhbHVlIHsgbmFtZTpcIkRVTU1ZXCIgbnVtYmVyOjAgfSB9ICIKKyAgICAic2VydmljZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdFNlcnZpY2VcIiIKKyAgICAiICBtZXRob2QgeyBuYW1lOiBcIkFcIiBpbnB1dF90eXBlOiBcIkZvb1wiIG91dHB1dF90eXBlOiBcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogVGVzdFNlcnZpY2UuQTogT1VUUFVUX1RZUEU6IFwiQmFyXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLlxuIgorICAgICk7Cit9CisKKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIElsbGVnYWxQYWNrZWRGaWVsZCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHtcbiIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcInBhY2tlZF9zdHJpbmdcIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9SRVBFQVRFRCAiCisgICAgIiAgICAgICAgICB0eXBlOlRZUEVfU1RSSU5HICIKKyAgICAiICAgICAgICAgIG9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IgorICAgICIgICAgICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcInBhY2tlZFwiIGlzX2V4dGVuc2lvbjogZmFsc2UgfSIKKyAgICAiICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJ0cnVlXCIgfX19XG4iCisgICAgIiAgZmllbGQgeyBuYW1lOlwicGFja2VkX21lc3NhZ2VcIiBudW1iZXI6MyBsYWJlbDpMQUJFTF9SRVBFQVRFRCAiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6IFwiRm9vXCIiCisgICAgIiAgICAgICAgICBvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyIKKyAgICAiICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJwYWNrZWRcIiBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwidHJ1ZVwiIH19fVxuIgorICAgICIgIGZpZWxkIHsgbmFtZTpcIm9wdGlvbmFsX2ludDMyXCIgbnVtYmVyOiA0IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICB0eXBlOlRZUEVfSU5UMzIgIgorICAgICIgICAgICAgICAgb3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsiCisgICAgIiAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwicGFja2VkXCIgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcInRydWVcIiB9fX1cbiIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28ucGFja2VkX3N0cmluZzogVFlQRTogW3BhY2tlZCA9IHRydWVdIGNhbiBvbmx5IGJlICIKKyAgICAgICAgInNwZWNpZmllZCBmb3IgcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkcy5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28ucGFja2VkX21lc3NhZ2U6IFRZUEU6IFtwYWNrZWQgPSB0cnVlXSBjYW4gb25seSBiZSAiCisgICAgICAgICJzcGVjaWZpZWQgZm9yIHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZHMuXG4iCisgICAgImZvby5wcm90bzogRm9vLm9wdGlvbmFsX2ludDMyOiBUWVBFOiBbcGFja2VkID0gdHJ1ZV0gY2FuIG9ubHkgYmUgIgorICAgICAgICAic3BlY2lmaWVkIGZvciByZXBlYXRlZCBwcmltaXRpdmUgZmllbGRzLlxuIgorICAgICAgICApOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgT3B0aW9uV3JvbmdUeXBlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiICIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfU1RSSU5HICIKKyAgICAiICAgICAgICAgIG9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiY3R5cGVcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxIH0iCisgICAgIiAgICAgICAgICB9IgorICAgICIgIH0iCisgICAgIn1cbiIsCisKKyAgICAiZm9vLnByb3RvOiBUZXN0TWVzc2FnZS5mb286IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBpZGVudGlmaWVyIGZvciAiCisgICAgImVudW0tdmFsdWVkIG9wdGlvbiBcImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuY3R5cGVcIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgT3B0aW9uRXh0ZW5kc0F0b21pY1R5cGUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIgIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9TVFJJTkcgIgorICAgICIgICAgICAgICAgb3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJjdHlwZVwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMSB9IgorICAgICIgICAgICAgICAgfSIKKyAgICAiICB9IgorICAgICJ9XG4iLAorCisgICAgImZvby5wcm90bzogVGVzdE1lc3NhZ2UuZm9vOiBPUFRJT05fTkFNRTogT3B0aW9uIFwiY3R5cGVcIiBpcyBhbiAiCisgICAgImF0b21pYyB0eXBlLCBub3QgYSBtZXNzYWdlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBEdXBPcHRpb24pIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIgIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9VSU5UMzIgIgorICAgICIgICAgICAgICAgb3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJjdHlwZVwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcIkNPUkRcIiB9IgorICAgICIgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJjdHlwZVwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcIkNPUkRcIiB9IgorICAgICIgICAgICAgICAgfSIKKyAgICAiICB9IgorICAgICJ9XG4iLAorCisgICAgImZvby5wcm90bzogVGVzdE1lc3NhZ2UuZm9vOiBPUFRJT05fTkFNRTogT3B0aW9uIFwiY3R5cGVcIiB3YXMgIgorICAgICJhbHJlYWR5IHNldC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgSW52YWxpZE9wdGlvbk5hbWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIgIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9CT09MICIKKyAgICAiICAgICAgICAgIG9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwidW5pbnRlcnByZXRlZF9vcHRpb25cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxICIKKyAgICAiICAgICAgICAgICAgICAgICAgICB9IgorICAgICIgICAgICAgICAgfSIKKyAgICAiICB9IgorICAgICJ9XG4iLAorCisgICAgImZvby5wcm90bzogVGVzdE1lc3NhZ2UuZm9vOiBPUFRJT05fTkFNRTogT3B0aW9uIG11c3Qgbm90IHVzZSAiCisgICAgInJlc2VydmVkIG5hbWUgXCJ1bmludGVycHJldGVkX29wdGlvblwiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZXBlYXRlZE1lc3NhZ2VPcHRpb24pIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZTogeyBuYW1lOiBcIkJhclwiIGZpZWxkOiB7ICIKKyAgICAiICBuYW1lOiBcImZvb1wiIG51bWJlcjogMSBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9JTlQzMiB9ICIKKyAgICAifSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiYmFyXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9SRVBFQVRFRCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfTUVTU0FHRSB0eXBlX25hbWU6IFwiQmFyXCIgIgorICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImJhclwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEgfSB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX05BTUU6IE9wdGlvbiBmaWVsZCBcIihiYXIpXCIgaXMgYSAiCisgICAgInJlcGVhdGVkIG1lc3NhZ2UuIFJlcGVhdGVkIG1lc3NhZ2Ugb3B0aW9ucyBtdXN0IGJlIGluaXRpYWxpemVkICIKKyAgICAidXNpbmcgYW4gYWdncmVnYXRlIHZhbHVlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZXNvbHZlVW5kZWZpbmVkT3B0aW9uKSB7CisgIC8vIFRoZSBmb2xsb3dpbmcgc2hvdWxkIHByb2R1Y2UgYW4gZXJvciB0aGF0IGJhei5iYXIgaXMgcmVzb2x2ZWQgYnV0IG5vdAorICAvLyBkZWZpbmVkLgorICAvLyBmb28ucHJvdG86CisgIC8vICAgcGFja2FnZSBiYXoKKyAgLy8gICBpbXBvcnQgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KKyAgLy8gICBtZXNzYWdlIEJhciB7IG9wdGlvbmFsIGludDMyIGZvbyA9IDE7IH0KKyAgLy8gICBleHRlbmQgRmlsZU9wdGlvbnMgeyBvcHRpb25hbCBCYXIgYmFyID0gNzY3Mjc1NzsgfQorICAvLworICAvLyBxdXgucHJvdG86CisgIC8vICAgcGFja2FnZSBxdXguYmF6CisgIC8vICAgb3B0aW9uIChiYXouYmFyKS5mb28gPSAxOworICAvLworICAvLyBBbHRob3VnaCAiYmF6LmJhciIgaXMgYWxyZWFkeSBkZWZpbmVkLCB0aGUgbG9va3VwIGNvZGUgd2lsbCB0cnkKKyAgLy8gInF1eC5iYXouYmFyIiwgc2luY2UgaXQncyB0aGUgbWF0Y2ggZnJvbSB0aGUgaW5uZXJtb3N0IHNjb3BlLCB3aGljaCB3aWxsCisgIC8vIGNhdXNlIGEgc3ltYm9sIG5vdCBkZWZpbmVkIGVycm9yLgorICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImJhelwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlOiB7IG5hbWU6IFwiQmFyXCIgZmllbGQ6IHsgIgorICAgICIgIG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAxIGxhYmVsOiBMQUJFTF9PUFRJT05BTCB0eXBlOiBUWVBFX0lOVDMyIH0gIgorICAgICJ9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJiYXJcIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9NRVNTQUdFIHR5cGVfbmFtZTogXCJCYXJcIiAiCisgICAgIiAgICAgICAgICAgIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcInF1eC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJxdXguYmF6XCIgIgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImJhei5iYXJcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxIH0gfSIsCisKKyAgICAicXV4LnByb3RvOiBxdXgucHJvdG86IE9QVElPTl9OQU1FOiBPcHRpb24gXCIoYmF6LmJhcilcIiBpcyByZXNvbHZlZCB0byAiCisgICAgIlwiKHF1eC5iYXouYmFyKVwiLCIKKyAgICAiIHdoaWNoIGlzIG5vdCBkZWZpbmVkLiBUaGUgaW5uZXJtb3N0IHNjb3BlIGlzIHNlYXJjaGVkIGZpcnN0IGluIG5hbWUgIgorICAgICJyZXNvbHV0aW9uLiBDb25zaWRlciB1c2luZyBhIGxlYWRpbmcgJy4nKGkuZS4sIFwiKC5iYXouYmFyKVwiKSB0byBzdGFydCAiCisgICAgImZyb20gdGhlIG91dGVybW9zdCBzY29wZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVW5rbm93bk9wdGlvbikgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcInF1eC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJxdXguYmF6XCIgIgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImJhYXouYmFyXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMSB9IH0iLAorCisgICAgInF1eC5wcm90bzogcXV4LnByb3RvOiBPUFRJT05fTkFNRTogT3B0aW9uIFwiKGJhYXouYmFyKVwiIHVua25vd24uXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEN1c3RvbU9wdGlvbkNvbmZsaWN0aW5nRmllbGROdW1iZXIpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vMVwiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0lOVDMyIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnNcIiB9IgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvbzJcIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zXCIgfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28yOiBOVU1CRVI6IEV4dGVuc2lvbiBudW1iZXIgNzY3Mjc1NyBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgIgorICAgICJpbiBcImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnNcIiBieSBleHRlbnNpb24gXCJmb28xXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludDMyT3B0aW9uVmFsdWVPdXRPZlBvc2l0aXZlUmFuZ2UpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfSU5UMzIgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMHg4MDAwMDAwMCB9ICIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgb3V0IG9mIHJhbmdlICIKKyAgICAiZm9yIGludDMyIG9wdGlvbiBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnQzMk9wdGlvblZhbHVlT3V0T2ZOZWdhdGl2ZVJhbmdlKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0lOVDMyIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZV9pbnRfdmFsdWU6IC0weDgwMDAwMDAxIH0gIgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBWYWx1ZSBvdXQgb2YgcmFuZ2UgIgorICAgICJmb3IgaW50MzIgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludDMyT3B0aW9uVmFsdWVJc05vdFBvc2l0aXZlSW50KSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0lOVDMyIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdfdmFsdWU6IFwiNVwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBpbnRlZ2VyICIKKyAgICAiZm9yIGludDMyIG9wdGlvbiBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnQ2NE9wdGlvblZhbHVlT3V0T2ZSYW5nZSkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQ2NCBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAweDgwMDAwMDAwMDAwMDAwMDAgfSAiCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG91dCBvZiByYW5nZSAiCisgICAgImZvciBpbnQ2NCBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgSW50NjRPcHRpb25WYWx1ZUlzTm90UG9zaXRpdmVJbnQpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfSU5UNjQgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiNVwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBpbnRlZ2VyICIKKyAgICAiZm9yIGludDY0IG9wdGlvbiBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVSW50MzJPcHRpb25WYWx1ZU91dE9mUmFuZ2UpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfVUlOVDMyIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDB4MTAwMDAwMDAwIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgb3V0IG9mIHJhbmdlICIKKyAgICAiZm9yIHVpbnQzMiBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVUludDMyT3B0aW9uVmFsdWVJc05vdFBvc2l0aXZlSW50KSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX1VJTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlX3ZhbHVlOiAtNS42IH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBub24tbmVnYXRpdmUgaW50ZWdlciAiCisgICAgImZvciB1aW50MzIgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFVJbnQ2NE9wdGlvblZhbHVlSXNOb3RQb3NpdGl2ZUludCkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9VSU5UNjQgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlX2ludF92YWx1ZTogLTUgfSB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBWYWx1ZSBtdXN0IGJlIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyICIKKyAgICAiZm9yIHVpbnQ2NCBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmxvYXRPcHRpb25WYWx1ZUlzTm90TnVtYmVyKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0ZMT0FUIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdfdmFsdWU6IFwiYmFyXCIgfSB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBWYWx1ZSBtdXN0IGJlIG51bWJlciAiCisgICAgImZvciBmbG9hdCBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRG91YmxlT3B0aW9uVmFsdWVJc05vdE51bWJlcikgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9ET1VCTEUgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ192YWx1ZTogXCJiYXJcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgbnVtYmVyICIKKyAgICAiZm9yIGRvdWJsZSBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQm9vbE9wdGlvblZhbHVlSXNOb3RUcnVlT3JGYWxzZSkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9CT09MIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcImJhclwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBcInRydWVcIiBvciBcImZhbHNlXCIgIgorICAgICJmb3IgYm9vbGVhbiBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW51bU9wdGlvblZhbHVlSXNOb3RJZGVudGlmaWVyKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb0VudW1cIiB2YWx1ZSB7IG5hbWU6IFwiQkFSXCIgbnVtYmVyOiAxIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB7IG5hbWU6IFwiQkFaXCIgbnVtYmVyOiAyIH0gfSIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9FTlVNIHR5cGVfbmFtZTogXCJGb29FbnVtXCIgIgorICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nX3ZhbHVlOiBcIlFVVVhcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgaWRlbnRpZmllciBmb3IgIgorICAgICJlbnVtLXZhbHVlZCBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW51bU9wdGlvblZhbHVlSXNOb3RFbnVtVmFsdWVOYW1lKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb0VudW1cIiB2YWx1ZSB7IG5hbWU6IFwiQkFSXCIgbnVtYmVyOiAxIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB7IG5hbWU6IFwiQkFaXCIgbnVtYmVyOiAyIH0gfSIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9FTlVNIHR5cGVfbmFtZTogXCJGb29FbnVtXCIgIgorICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJRVVVYXCIgfSB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBFbnVtIHR5cGUgXCJGb29FbnVtXCIgaGFzIG5vIHZhbHVlICIKKyAgICAibmFtZWQgXCJRVVVYXCIgZm9yIG9wdGlvbiBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBFbnVtT3B0aW9uVmFsdWVJc1NpYmxpbmdFbnVtVmFsdWVOYW1lKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb0VudW0xXCIgdmFsdWUgeyBuYW1lOiBcIkJBUlwiIG51bWJlcjogMSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIHsgbmFtZTogXCJCQVpcIiBudW1iZXI6IDIgfSB9IgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb0VudW0yXCIgdmFsdWUgeyBuYW1lOiBcIlFVWFwiIG51bWJlcjogMSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIHsgbmFtZTogXCJRVVVYXCIgbnVtYmVyOiAyIH0gfSIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9FTlVNIHR5cGVfbmFtZTogXCJGb29FbnVtMVwiICIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiUVVVWFwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogRW51bSB0eXBlIFwiRm9vRW51bTFcIiBoYXMgbm8gdmFsdWUgIgorICAgICJuYW1lZCBcIlFVVVhcIiBmb3Igb3B0aW9uIFwiZm9vXCIuIFRoaXMgYXBwZWFycyB0byBiZSBhIHZhbHVlIGZyb20gYSAiCisgICAgInNpYmxpbmcgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgU3RyaW5nT3B0aW9uVmFsdWVJc05vdFN0cmluZykgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9TVFJJTkcgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiUVVVWFwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBxdW90ZWQgc3RyaW5nIGZvciAiCisgICAgInN0cmluZyBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRHVwbGljYXRlRXh0ZW5zaW9uRmllbGROdW1iZXIpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlKAorICAgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJvcHRpb24xXCIgbnVtYmVyOiAxMDAwIGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9Iik7CisKKyAgQnVpbGRGaWxlV2l0aFdhcm5pbmdzKAorICAgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJvcHRpb24yXCIgbnVtYmVyOiAxMDAwIGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IiwKKyAgICAgICJiYXIucHJvdG86IG9wdGlvbjI6IE5VTUJFUjogRXh0ZW5zaW9uIG51bWJlciAxMDAwIGhhcyBhbHJlYWR5IGJlZW4gdXNlZCAiCisgICAgICAiaW4gXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiBieSBleHRlbnNpb24gXCJvcHRpb24xXCIgZGVmaW5lZCBpbiAiCisgICAgICAiZm9vLnByb3RvLlxuIik7Cit9CisKKy8vIEhlbHBlciBmdW5jdGlvbiBmb3IgdGVzdHMgdGhhdCBjaGVjayBmb3IgYWdncmVnYXRlIHZhbHVlIHBhcnNpbmcKKy8vIGVycm9ycy4gIFRoZSAidmFsdWUiIGFyZ3VtZW50IGlzIGVtYmVkZGVkIGluc2lkZSB0aGUKKy8vICJ1bmludGVycHJldGVkX29wdGlvbiIgcG9ydGlvbiBvZiB0aGUgcmVzdWx0Lgorc3RhdGljIHN0cmluZyBFbWJlZEFnZ3JlZ2F0ZVZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHJldHVybiBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9ICIKKyAgICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfTUVTU0FHRSB0eXBlX25hbWU6IFwiRm9vXCIgIgorICAgICAgIiAgICAgICAgICAgIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkMCB9IH0iLAorICAgICAgdmFsdWUpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQWdncmVnYXRlVmFsdWVOb3RGb3VuZCkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgRW1iZWRBZ2dyZWdhdGVWYWx1ZSgic3RyaW5nX3ZhbHVlOiBcIlwiIiksCisgICAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogT3B0aW9uIFwiZm9vXCIgaXMgYSBtZXNzYWdlLiAiCisgICAgICAiVG8gc2V0IHRoZSBlbnRpcmUgbWVzc2FnZSwgdXNlIHN5bnRheCBsaWtlICIKKyAgICAgICJcImZvbyA9IHsgPHByb3RvIHRleHQgZm9ybWF0PiB9XCIuIFRvIHNldCBmaWVsZHMgd2l0aGluIGl0LCB1c2UgIgorICAgICAgInN5bnRheCBsaWtlIFwiZm9vLmZvbyA9IHZhbHVlXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEFnZ3JlZ2F0ZVZhbHVlUGFyc2VFcnJvcikgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgRW1iZWRBZ2dyZWdhdGVWYWx1ZSgiYWdncmVnYXRlX3ZhbHVlOiBcIjErMlwiIiksCisgICAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogRXJyb3Igd2hpbGUgcGFyc2luZyBvcHRpb24gIgorICAgICAgInZhbHVlIGZvciBcImZvb1wiOiBFeHBlY3RlZCBpZGVudGlmaWVyLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBBZ2dyZWdhdGVWYWx1ZVVua25vd25GaWVsZHMpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgIEVtYmVkQWdncmVnYXRlVmFsdWUoImFnZ3JlZ2F0ZV92YWx1ZTogXCJ4OjEwMFwiIiksCisgICAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogRXJyb3Igd2hpbGUgcGFyc2luZyBvcHRpb24gIgorICAgICAgInZhbHVlIGZvciBcImZvb1wiOiBNZXNzYWdlIHR5cGUgXCJGb29cIiBoYXMgbm8gZmllbGQgbmFtZWQgXCJ4XCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5vdExpdGVJbXBvcnRzTGl0ZSkgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJvcHRpb25zIHsgb3B0aW1pemVfZm9yOiBMSVRFX1JVTlRJTUUgfSAiKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiAiLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPVEhFUjogRmlsZXMgdGhhdCBkbyBub3QgdXNlIG9wdGltaXplX2ZvciA9ICIKKyAgICAgICJMSVRFX1JVTlRJTUUgY2Fubm90IGltcG9ydCBmaWxlcyB3aGljaCBkbyB1c2UgdGhpcyBvcHRpb24uICBUaGlzIGZpbGUgIgorICAgICAgImlzIG5vdCBsaXRlLCBidXQgaXQgaW1wb3J0cyBcImJhci5wcm90b1wiIHdoaWNoIGlzLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBMaXRlRXh0ZW5kc05vdExpdGUpIHsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlOiB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAwIH0iCisgICAgIn0iKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiAiCisgICAgIm9wdGlvbnMgeyBvcHRpbWl6ZV9mb3I6IExJVEVfUlVOVElNRSB9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJleHRcIiBudW1iZXI6IDEyMyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0lOVDMyIGV4dGVuZGVlOiBcIkJhclwiIH0iLAorCisgICAgImZvby5wcm90bzogZXh0OiBFWFRFTkRFRTogRXh0ZW5zaW9ucyB0byBub24tbGl0ZSB0eXBlcyBjYW4gb25seSBiZSAiCisgICAgICAiZGVjbGFyZWQgaW4gbm9uLWxpdGUgZmlsZXMuICBOb3RlIHRoYXQgeW91IGNhbm5vdCBleHRlbmQgYSBub24tbGl0ZSAiCisgICAgICAidHlwZSB0byBjb250YWluIGEgbGl0ZSB0eXBlLCBidXQgdGhlIHJldmVyc2UgaXMgYWxsb3dlZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTm9MaXRlU2VydmljZXMpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm9wdGlvbnMgeyIKKyAgICAiICBvcHRpbWl6ZV9mb3I6IExJVEVfUlVOVElNRSIKKyAgICAiICBjY19nZW5lcmljX3NlcnZpY2VzOiB0cnVlIgorICAgICIgIGphdmFfZ2VuZXJpY19zZXJ2aWNlczogdHJ1ZSIKKyAgICAifSAiCisgICAgInNlcnZpY2UgeyBuYW1lOiBcIkZvb1wiIH0iLAorCisgICAgImZvby5wcm90bzogRm9vOiBOQU1FOiBGaWxlcyB3aXRoIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRSBjYW5ub3QgIgorICAgICJkZWZpbmUgc2VydmljZXMgdW5sZXNzIHlvdSBzZXQgYm90aCBvcHRpb25zIGNjX2dlbmVyaWNfc2VydmljZXMgYW5kICIKKyAgICAiamF2YV9nZW5lcmljX3NldmljZXMgdG8gZmFsc2UuXG4iKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJvcHRpb25zIHsiCisgICAgIiAgb3B0aW1pemVfZm9yOiBMSVRFX1JVTlRJTUUiCisgICAgIiAgY2NfZ2VuZXJpY19zZXJ2aWNlczogZmFsc2UiCisgICAgIiAgamF2YV9nZW5lcmljX3NlcnZpY2VzOiBmYWxzZSIKKyAgICAifSAiCisgICAgInNlcnZpY2UgeyBuYW1lOiBcIkJhclwiIH0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFJvbGxiYWNrQWZ0ZXJFcnJvcikgeworICAvLyBCdWlsZCBhIGZpbGUgd2hpY2ggY29udGFpbnMgZXZlcnkga2luZCBvZiBjb25zdHJ1Y3QgYnV0IHJlZmVyZW5jZXMgYW4KKyAgLy8gdW5kZWZpbmVkIHR5cGUuICBBbGwgdGhlc2UgY29uc3RydWN0cyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBzeW1ib2wgdGFibGUKKyAgLy8gYmVmb3JlIHRoZSB1bmRlZmluZWQgdHlwZSBlcnJvciBpcyBub3RpY2VkLiAgVGhlIERlc2NyaXB0b3JQb29sIHdpbGwgdGhlbgorICAvLyBoYXZlIHRvIHJvbGwgZXZlcnl0aGluZyBiYWNrLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICJ9ICIKKyAgICAiZW51bV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0RW51bVwiIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkJBUlwiIG51bWJlcjoxIH0iCisgICAgIn0gIgorICAgICJzZXJ2aWNlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0U2VydmljZVwiIgorICAgICIgIG1ldGhvZCB7IgorICAgICIgICAgbmFtZTogXCJCYXpcIiIKKyAgICAiICAgIGlucHV0X3R5cGU6IFwiTm9TdWNoVHlwZVwiIiAgICAvLyBlcnJvcgorICAgICIgICAgb3V0cHV0X3R5cGU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IFRlc3RTZXJ2aWNlLkJhejogSU5QVVRfVFlQRTogXCJOb1N1Y2hUeXBlXCIgaXMgbm90IGRlZmluZWQuXG4iCisgICAgKTsKKworICAvLyBNYWtlIHN1cmUgdGhhdCBpZiB3ZSBidWlsZCB0aGUgc2FtZSBmaWxlIGFnYWluIHdpdGggdGhlIGVycm9yIGZpeGVkLAorICAvLyBpdCB3b3Jrcy4gIElmIHRoZSBhYm92ZSByb2xsYmFjayB3YXMgaW5jb21wbGV0ZSwgdGhlbiBzb21lIHN5bWJvbHMgd2lsbAorICAvLyBiZSBsZWZ0IGRlZmluZWQsIGFuZCB0aGlzIHNlY29uZCBhdHRlbXB0IHdpbGwgZmFpbCBzaW5jZSBpdCB0cmllcyB0bworICAvLyByZS1kZWZpbmUgdGhlIHNhbWUgc3ltYm9scy4KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICJ9ICIKKyAgICAiZW51bV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0RW51bVwiIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkJBUlwiIG51bWJlcjoxIH0iCisgICAgIn0gIgorICAgICJzZXJ2aWNlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0U2VydmljZVwiIgorICAgICIgIG1ldGhvZCB7IG5hbWU6XCJCYXpcIiIKKyAgICAiICAgICAgICAgICBpbnB1dF90eXBlOlwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICAgICAgICAgICBvdXRwdXRfdHlwZTpcIlRlc3RNZXNzYWdlXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRXJyb3JzUmVwb3J0ZWRUb0xvZ0Vycm9yKSB7CisgIC8vIFRlc3QgdGhhdCBlcnJvcnMgYXJlIHJlcG9ydGVkIHRvIEdPT0dMRV9MT0coRVJST1IpIGlmIG5vIGVycm9yIGNvbGxlY3RvciBpcworICAvLyBwcm92aWRlZC4KKworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSAiLAorICAgICZmaWxlX3Byb3RvKSk7CisKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworCisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIEVYUEVDVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSA9PSBOVUxMKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgQVNTRVJUX0VRKDIsIGVycm9ycy5zaXplKCkpOworCisgIEVYUEVDVF9FUSgiSW52YWxpZCBwcm90byBkZXNjcmlwdG9yIGZvciBmaWxlIFwiZm9vLnByb3RvXCI6IiwgZXJyb3JzWzBdKTsKKyAgRVhQRUNUX0VRKCIgIEZvbzogXCJGb29cIiBpcyBhbHJlYWR5IGRlZmluZWQuIiwgZXJyb3JzWzFdKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIERpc2FsbG93RW51bUFsaWFzKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkJhclwiIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkVOVU1fQVwiIG51bWJlcjowIH0iCisgICAgIiAgdmFsdWUgeyBuYW1lOlwiRU5VTV9CXCIgbnVtYmVyOjAgfSIKKyAgICAifSIsCisgICAgImZvby5wcm90bzogQmFyOiBOVU1CRVI6ICIKKyAgICAiXCJFTlVNX0JcIiB1c2VzIHRoZSBzYW1lIGVudW0gdmFsdWUgYXMgXCJFTlVNX0FcIi4gIgorICAgICJJZiB0aGlzIGlzIGludGVuZGVkLCBzZXQgJ29wdGlvbiBhbGxvd19hbGlhcyA9IHRydWU7JyB0byB0aGUgZW51bSAiCisgICAgImRlZmluaXRpb24uXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEFsbG93RW51bUFsaWFzKSB7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImVudW1fdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgdmFsdWUgeyBuYW1lOlwiRU5VTV9BXCIgbnVtYmVyOjAgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJFTlVNX0JcIiBudW1iZXI6MCB9IgorICAgICIgIG9wdGlvbnMgeyBhbGxvd19hbGlhczogdHJ1ZSB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVbnVzZWRJbXBvcnRXYXJuaW5nKSB7CisKKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJiYXIucHJvdG8iKTsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9Iik7CisKKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJiYXNlLnByb3RvIik7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJiYXNlLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhc2VcIiB9Iik7CisKKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJiYXoucHJvdG8iKTsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhei5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXpcIiB9Iik7CisKKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJwdWJsaWMucHJvdG8iKTsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcInB1YmxpYy5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDAiKTsKKworICAvLyAvLyBmb3J3YXJkLnByb3RvCisgIC8vIGltcG9ydCAiYmFzZS5wcm90byIgICAgICAgLy8gTm8gd2FybmluZzogQmFzZSBtZXNzYWdlIGlzIHVzZWQuCisgIC8vIGltcG9ydCAiYmFyLnByb3RvIiAgICAgICAgLy8gV2lsbCBsb2cgYSB3YXJuaW5nLgorICAvLyBpbXBvcnQgcHVibGljICJiYXoucHJvdG8iIC8vIE5vIHdhcm5pbmc6IERvIG5vdCB0cmFjayBpbXBvcnQgcHVibGljLgorICAvLyBpbXBvcnQgInB1YmxpYy5wcm90byIgICAgIC8vIE5vIHdhcm5pbmc6IHB1YmxpYy5wcm90byBoYXMgaW1wb3J0IHB1YmxpYy4KKyAgLy8gbWVzc2FnZSBGb3J3YXJkIHsKKyAgLy8gICBvcHRpb25hbCBCYXNlIGJhc2UgPSAxOworICAvLyB9CisgIC8vCisgIHBvb2xfLkFkZFVudXNlZEltcG9ydFRyYWNrRmlsZSgiZm9yd2FyZC5wcm90byIpOworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9yd2FyZC5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcImJhc2UucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXoucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJwdWJsaWMucHJvdG9cIiIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvcndhcmRcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXNlXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiQmFzZVwiIH0iCisgICAgIn0iKTsKK30KKworbmFtZXNwYWNlIHsKK3ZvaWQgRmlsbFZhbGlkTWFwRW50cnkoRmlsZURlc2NyaXB0b3JQcm90byogZmlsZV9wcm90bykgeworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIGZpZWxkIHsgIgorICAgICAgIiAgICBuYW1lOiAnZm9vX21hcCcgbnVtYmVyOiAxIGxhYmVsOkxBQkVMX1JFUEVBVEVEICIKKyAgICAgICIgICAgdHlwZV9uYW1lOiAnRm9vTWFwRW50cnknICIKKyAgICAgICIgIH0gIgorICAgICAgIiAgbmVzdGVkX3R5cGUgeyAiCisgICAgICAiICAgIG5hbWU6ICdGb29NYXBFbnRyeScgIgorICAgICAgIiAgICBvcHRpb25zIHsgIG1hcF9lbnRyeTogdHJ1ZSB9ICIKKyAgICAgICIgICAgZmllbGQgeyAiCisgICAgICAiICAgICAgbmFtZTogJ2tleScgbnVtYmVyOiAxIHR5cGU6VFlQRV9JTlQzMiBsYWJlbDpMQUJFTF9PUFRJT05BTCAiCisgICAgICAiICAgIH0gIgorICAgICAgIiAgICBmaWVsZCB7ICIKKyAgICAgICIgICAgICBuYW1lOiAndmFsdWUnIG51bWJlcjogMiB0eXBlOlRZUEVfSU5UMzIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgICB9ICIKKyAgICAgICIgIH0gIgorICAgICAgIn0gIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdCYXInICIKKyAgICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAgfSIKKyAgICAgICJ9ICIsCisgICAgICBmaWxlX3Byb3RvKSk7Cit9CitzdGF0aWMgY29uc3QgY2hhcioga01hcEVudHJ5RXJyb3JNZXNzYWdlID0KKyAgICAiZm9vLnByb3RvOiBGb28uZm9vX21hcDogT1RIRVI6IG1hcF9lbnRyeSBzaG91bGQgbm90IGJlIHNldCBleHBsaWNpdGx5LiAiCisgICAgIlVzZSBtYXA8S2V5VHlwZSwgVmFsdWVUeXBlPiBpbnN0ZWFkLlxuIjsKK3N0YXRpYyBjb25zdCBjaGFyKiBrTWFwRW50cnlLZXlUeXBlRXJyb3JNZXNzYWdlID0KKyAgICAiZm9vLnByb3RvOiBGb28uZm9vX21hcDogVFlQRTogS2V5IGluIG1hcCBmaWVsZHMgY2Fubm90IGJlIGZsb2F0L2RvdWJsZSwgIgorICAgICJieXRlcyBvciBtZXNzYWdlIHR5cGVzLlxuIjsKKworfSAgLy8gbmFtZXNwYWNlCisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUJhc2UpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEJ1aWxkRmlsZShmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlFeHRlbnNpb25SYW5nZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKAorICAgICAgImV4dGVuc2lvbl9yYW5nZSB7ICIKKyAgICAgICIgIHN0YXJ0OiAxMCBlbmQ6IDIwICIKKyAgICAgICJ9ICIsCisgICAgICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX25lc3RlZF90eXBlKDApKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUV4dGVuc2lvbikgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKAorICAgICAgImV4dGVuc2lvbiB7ICIKKyAgICAgICIgIG5hbWU6ICdmb29fZXh0JyBleHRlbmRlZTogJy5CYXInIG51bWJlcjogNSIKKyAgICAgICJ9ICIsCisgICAgICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX25lc3RlZF90eXBlKDApKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeU5lc3RlZFR5cGUpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJuZXN0ZWRfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdCYXInICIKKyAgICAgICJ9ICIsCisgICAgICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX25lc3RlZF90eXBlKDApKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUVudW1UeXBlcykgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKAorICAgICAgImVudW1fdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdCYXJFbnVtJyAiCisgICAgICAiICB2YWx1ZSB7IG5hbWU6ICdCQVJfQkFSJyBudW1iZXI6MCB9ICIKKyAgICAgICJ9ICIsCisgICAgICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX25lc3RlZF90eXBlKDApKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUV4dHJhRmllbGQpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJmaWVsZCB7ICIKKyAgICAgICIgIG5hbWU6ICdvdGhlcl9maWVsZCcgIgorICAgICAgIiAgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAgICIgIHR5cGU6IFRZUEVfSU5UMzIgIgorICAgICAgIiAgbnVtYmVyOiAzICIKKyAgICAgICJ9ICIsCisgICAgICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX25lc3RlZF90eXBlKDApKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeU1lc3NhZ2VOYW1lKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX25lc3RlZF90eXBlKDApLT5zZXRfbmFtZSgKKyAgICAgICJPdGhlck1hcEVudHJ5Iik7CisgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCktPm11dGFibGVfZmllbGQoMCktPnNldF90eXBlX25hbWUoCisgICAgICAiT3RoZXJNYXBFbnRyeSIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5RXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5Tm9uZVJlcGVhdGVkTWFwRW50cnkpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCktPm11dGFibGVfZmllbGQoMCktPnNldF9sYWJlbCgKKyAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlEaWZmZXJlbnRDb250YWluaW5nVHlwZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgLy8gTW92ZSB0aGUgbmVzdGVkIE1hcEVudHJ5IG1lc3NhZ2UgaW50byB0aGUgdG9wIGxldmVsLCB3aGljaCBzaG91bGQgbm90IHBhc3MKKyAgLy8gdGhlIHZhbGlkYXRpb24uCisgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoKS0+QWRkQWxsb2NhdGVkKAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLT5SZWxlYXNlTGFzdCgpKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUtleU5hbWUpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBrZXkgPSBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApCisgICAgICAtPm11dGFibGVfbmVzdGVkX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9maWVsZCgwKTsKKyAga2V5LT5zZXRfbmFtZSgiS2V5Iik7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlLZXlMYWJlbCkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGtleSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDApOworICBrZXktPnNldF9sYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5RXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5S2V5TnVtYmVyKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBGaWVsZERlc2NyaXB0b3JQcm90byoga2V5ID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMCk7CisgIGtleS0+c2V0X251bWJlcigzKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeVZhbHVlTmFtZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIHZhbHVlID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMSk7CisgIHZhbHVlLT5zZXRfbmFtZSgiVmFsdWUiKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeVZhbHVlTGFiZWwpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiB2YWx1ZSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDEpOworICB2YWx1ZS0+c2V0X2xhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVFVSVJFRCk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlWYWx1ZU51bWJlcikgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIHZhbHVlID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMSk7CisgIHZhbHVlLT5zZXRfbnVtYmVyKDMpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5RXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5S2V5VHlwZUZsb2F0KSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBGaWVsZERlc2NyaXB0b3JQcm90byoga2V5ID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMCk7CisgIGtleS0+c2V0X3R5cGUoRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRkxPQVQpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5S2V5VHlwZUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUtleVR5cGVEb3VibGUpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBrZXkgPSBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApCisgICAgICAtPm11dGFibGVfbmVzdGVkX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9maWVsZCgwKTsKKyAga2V5LT5zZXRfdHlwZShGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9ET1VCTEUpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5S2V5VHlwZUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUtleVR5cGVCeXRlcykgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGtleSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDApOworICBrZXktPnNldF90eXBlKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0JZVEVTKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUtleVR5cGVFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlLZXlUeXBlRW51bSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGtleSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDApOworICBrZXktPmNsZWFyX3R5cGUoKTsKKyAga2V5LT5zZXRfdHlwZV9uYW1lKCJCYXJFbnVtIik7CisgIEVudW1EZXNjcmlwdG9yUHJvdG8qIGVudW1fcHJvdG8gPSBmaWxlX3Byb3RvLmFkZF9lbnVtX3R5cGUoKTsKKyAgZW51bV9wcm90by0+c2V0X25hbWUoIkJhckVudW0iKTsKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBlbnVtX3ZhbHVlX3Byb3RvID0gZW51bV9wcm90by0+YWRkX3ZhbHVlKCk7CisgIGVudW1fdmFsdWVfcHJvdG8tPnNldF9uYW1lKCJCQVJfVkFMVUUwIik7CisgIGVudW1fdmFsdWVfcHJvdG8tPnNldF9udW1iZXIoMCk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICJmb28ucHJvdG86IEZvby5mb29fbWFwOiBUWVBFOiBLZXkgaW4gbWFwIGZpZWxkcyBjYW5ub3QgIgorICAgICAgICAgICAgICAgICAgICAgICJiZSBlbnVtIHR5cGVzLlxuIik7CisgIC8vIEVudW0ga2V5cyBhcmUgbm90IGFsbG93ZWQgaW4gcHJvdG8zIGFzIHdlbGwuCisgIC8vIEdldCByaWQgb2YgZXh0ZW5zaW9ucyBmb3IgcHJvdG8zIHRvIG1ha2UgaXQgcHJvdG8zIGNvbXBhdGlibGUuCisgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoKS0+UmVtb3ZlTGFzdCgpOworICBmaWxlX3Byb3RvLnNldF9zeW50YXgoInByb3RvMyIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAiZm9vLnByb3RvOiBGb28uZm9vX21hcDogVFlQRTogS2V5IGluIG1hcCBmaWVsZHMgY2Fubm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAiYmUgZW51bSB0eXBlcy5cbiIpOworfQorCisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUtleVR5cGVNZXNzYWdlKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBGaWVsZERlc2NyaXB0b3JQcm90byoga2V5ID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMCk7CisgIGtleS0+Y2xlYXJfdHlwZSgpOworICBrZXktPnNldF90eXBlX25hbWUoIi5CYXIiKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUtleVR5cGVFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlDb25mbGljdHNXaXRoRmllbGQpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJmaWVsZCB7ICIKKyAgICAgICIgIG5hbWU6ICdGb29NYXBFbnRyeScgIgorICAgICAgIiAgdHlwZTogVFlQRV9JTlQzMiAiCisgICAgICAiICBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgbnVtYmVyOiAxMDAgIgorICAgICAgIn0iLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICBmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAiZm9vLnByb3RvOiBGb28uRm9vTWFwRW50cnk6IE5BTUU6IFwiRm9vTWFwRW50cnlcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gIgorICAgICAgIlwiRm9vXCIuXG4iCisgICAgICAiZm9vLnByb3RvOiBGb28uZm9vX21hcDogVFlQRTogXCJGb29NYXBFbnRyeVwiIGlzIG5vdCBkZWZpbmVkLlxuIgorICAgICAgImZvby5wcm90bzogRm9vOiBOQU1FOiBFeHBhbmRlZCBtYXAgZW50cnkgdHlwZSBGb29NYXBFbnRyeSBjb25mbGljdHMgIgorICAgICAgIndpdGggYW4gZXhpc3RpbmcgZmllbGQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5Q29uZmxpY3RzV2l0aE1lc3NhZ2UpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJuZXN0ZWRfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb29NYXBFbnRyeScgIgorICAgICAgIn0iLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICBmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAiZm9vLnByb3RvOiBGb28uRm9vTWFwRW50cnk6IE5BTUU6IFwiRm9vTWFwRW50cnlcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gIgorICAgICAgIlwiRm9vXCIuXG4iCisgICAgICAiZm9vLnByb3RvOiBGb286IE5BTUU6IEV4cGFuZGVkIG1hcCBlbnRyeSB0eXBlIEZvb01hcEVudHJ5IGNvbmZsaWN0cyAiCisgICAgICAid2l0aCBhbiBleGlzdGluZyBuZXN0ZWQgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUNvbmZsaWN0c1dpdGhFbnVtKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoCisgICAgICAiZW51bV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0Zvb01hcEVudHJ5JyAiCisgICAgICAiICB2YWx1ZSB7IG5hbWU6ICdFTlRSWV9GT08nIG51bWJlcjogMCB9IgorICAgICAgIn0iLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICBmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAiZm9vLnByb3RvOiBGb28uRm9vTWFwRW50cnk6IE5BTUU6IFwiRm9vTWFwRW50cnlcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gIgorICAgICAgIlwiRm9vXCIuXG4iCisgICAgICAiZm9vLnByb3RvOiBGb286IE5BTUU6IEV4cGFuZGVkIG1hcCBlbnRyeSB0eXBlIEZvb01hcEVudHJ5IGNvbmZsaWN0cyAiCisgICAgICAid2l0aCBhbiBleGlzdGluZyBlbnVtIHR5cGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5Q29uZmxpY3RzV2l0aE9uZW9mKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoCisgICAgICAib25lb2ZfZGVjbCB7ICIKKyAgICAgICIgIG5hbWU6ICdGb29NYXBFbnRyeScgIgorICAgICAgIn0iCisgICAgICAiZmllbGQgeyAiCisgICAgICAiICBuYW1lOiAnaW50X2ZpZWxkJyAiCisgICAgICAiICB0eXBlOiBUWVBFX0lOVDMyICIKKyAgICAgICIgIGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgICAiICBvbmVvZl9pbmRleDogMCAiCisgICAgICAiICBudW1iZXI6IDEwMCAiCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICBmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAiZm9vLnByb3RvOiBGb28uRm9vTWFwRW50cnk6IE5BTUU6IFwiRm9vTWFwRW50cnlcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gIgorICAgICAgIlwiRm9vXCIuXG4iCisgICAgICAiZm9vLnByb3RvOiBGb28uZm9vX21hcDogVFlQRTogXCJGb29NYXBFbnRyeVwiIGlzIG5vdCBkZWZpbmVkLlxuIgorICAgICAgImZvby5wcm90bzogRm9vOiBOQU1FOiBFeHBhbmRlZCBtYXAgZW50cnkgdHlwZSBGb29NYXBFbnRyeSBjb25mbGljdHMgIgorICAgICAgIndpdGggYW4gZXhpc3Rpbmcgb25lb2YgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUHJvdG8zUmVxdWlyZWRGaWVsZHMpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb28nIG51bWJlcjoxIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvby5mb286IE9USEVSOiBSZXF1aXJlZCBmaWVsZHMgYXJlIG5vdCBhbGxvd2VkIGluICIKKyAgICAgICJwcm90bzMuXG4iKTsKKworICAvLyBhcHBsaWVkIHRvIG5lc3RlZCB0eXBlcyBhcyB3ZWxsLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vJyAiCisgICAgICAiICBuZXN0ZWRfdHlwZSB7ICIKKyAgICAgICIgICAgbmFtZSA6ICdCYXInICIKKyAgICAgICIgICAgZmllbGQgeyBuYW1lOidiYXInIG51bWJlcjoxIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiB9ICIKKyAgICAgICIgIH0gIgorICAgICAgIn0iLAorICAgICAgImZvby5wcm90bzogRm9vLkJhci5iYXI6IE9USEVSOiBSZXF1aXJlZCBmaWVsZHMgYXJlIG5vdCBhbGxvd2VkIGluICIKKyAgICAgICJwcm90bzMuXG4iKTsKKworICAvLyBvcHRpb25hbCBhbmQgcmVwZWF0ZWQgZmllbGRzIGFyZSBPSy4KKyAgQnVpbGRGaWxlKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vJyAiCisgICAgICAiICBmaWVsZCB7IG5hbWU6J2ZvbycgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0gIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidiYXInIG51bWJlcjoyIGxhYmVsOkxBQkVMX1JFUEVBVEVEIHR5cGU6VFlQRV9JTlQzMiB9ICIKKyAgICAgICJ9Iik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBWYWxpZGF0ZVByb3RvM0RlZmF1bHRWYWx1ZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vJyAiCisgICAgICAiICBmaWVsZCB7IG5hbWU6J2ZvbycgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyICIKKyAgICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogJzEnIH0iCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBPVEhFUjogRXhwbGljaXQgZGVmYXVsdCB2YWx1ZXMgYXJlIG5vdCBhbGxvd2VkIGluICIKKyAgICAgICJwcm90bzMuXG4iKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vJyAiCisgICAgICAiICBuZXN0ZWRfdHlwZSB7ICIKKyAgICAgICIgICAgbmFtZSA6ICdCYXInICIKKyAgICAgICIgICAgZmllbGQgeyBuYW1lOidiYXInIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgICAgZGVmYXVsdF92YWx1ZTogJzEnIH0iCisgICAgICAiICB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvby5CYXIuYmFyOiBPVEhFUjogRXhwbGljaXQgZGVmYXVsdCB2YWx1ZXMgYXJlIG5vdCBhbGxvd2VkICIKKyAgICAgICJpbiBwcm90bzMuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFZhbGlkYXRlUHJvdG8zRXh0ZW5zaW9uUmFuZ2UpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb28nIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9ICIKKyAgICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjEwIGVuZDoxMDAgfSAiCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb286IE9USEVSOiBFeHRlbnNpb24gcmFuZ2VzIGFyZSBub3QgYWxsb3dlZCBpbiAiCisgICAgICAicHJvdG8zLlxuIik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgbmVzdGVkX3R5cGUgeyAiCisgICAgICAiICAgIG5hbWUgOiAnQmFyJyAiCisgICAgICAiICAgIGZpZWxkIHsgbmFtZTonYmFyJyBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSAiCisgICAgICAiICAgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjEwIGVuZDoxMDAgfSAiCisgICAgICAiICB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvby5CYXI6IE9USEVSOiBFeHRlbnNpb24gcmFuZ2VzIGFyZSBub3QgYWxsb3dlZCBpbiAiCisgICAgICAicHJvdG8zLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBWYWxpZGF0ZVByb3RvM01lc3NhZ2VTZXRXaXJlRm9ybWF0KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIG9wdGlvbnMgeyBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdDogdHJ1ZSB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvbzogT1RIRVI6IE1lc3NhZ2VTZXQgaXMgbm90IHN1cHBvcnRlZCAiCisgICAgICAiaW4gcHJvdG8zLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBWYWxpZGF0ZVByb3RvM0VudW0pIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAiZW51bV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0Zvb0VudW0nICIKKyAgICAgICIgIHZhbHVlIHsgbmFtZTogJ0ZPT19GT08nIG51bWJlcjoxIH0gIgorICAgICAgIn0iLAorICAgICAgImZvby5wcm90bzogRm9vRW51bTogT1RIRVI6IFRoZSBmaXJzdCBlbnVtIHZhbHVlIG11c3QgYmUgIgorICAgICAgInplcm8gaW4gcHJvdG8zLlxuIik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgZW51bV90eXBlIHsgIgorICAgICAgIiAgICBuYW1lOiAnRm9vRW51bScgIgorICAgICAgIiAgICB2YWx1ZSB7IG5hbWU6ICdGT09fRk9PJyBudW1iZXI6MSB9ICIKKyAgICAgICIgIH0gIgorICAgICAgIn0iLAorICAgICAgImZvby5wcm90bzogRm9vLkZvb0VudW06IE9USEVSOiBUaGUgZmlyc3QgZW51bSB2YWx1ZSBtdXN0IGJlICIKKyAgICAgICJ6ZXJvIGluIHByb3RvMy5cbiIpOworCisgIC8vIHZhbGlkIGNhc2UuCisgIEJ1aWxkRmlsZSgKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAiZW51bV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0Zvb0VudW0nICIKKyAgICAgICIgIHZhbHVlIHsgbmFtZTogJ0ZPT19GT08nIG51bWJlcjowIH0gIgorICAgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFZhbGlkYXRlUHJvdG8zTGl0ZVJ1bnRpbWUpIHsKKyAgLy8gTGl0ZSBydW50aW1lIGlzIG5vdCBzdXBwb3J0ZWQgaW4gcHJvdG8zLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJvcHRpb25zIHsgIgorICAgICAgIiAgb3B0aW1pemVfZm9yOiBMSVRFX1JVTlRJTUUgIgorICAgICAgIn0gIiwKKyAgICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1RIRVI6IExpdGUgcnVudGltZSBpcyBub3Qgc3VwcG9ydGVkICIKKyAgICAgICJpbiBwcm90bzMuXG4iKTsKK30KKworCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNFbnVtRnJvbVByb3RvMikgeworICAvLyBEZWZpbmUgYW4gZW51bSBpbiBhIHByb3RvMiBmaWxlLgorICBCdWlsZEZpbGUoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInBhY2thZ2U6ICdmb28nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzInICIKKyAgICAgICJlbnVtX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vRW51bScgIgorICAgICAgIiAgdmFsdWUgeyBuYW1lOiAnREVGQVVMVF9PUFRJT04nIG51bWJlcjowIH0gIgorICAgICAgIn0iKTsKKworICAvLyBOb3cgdHJ5IHRvIHJlZmVyIHRvIGl0LiAoQWxsIHRlc3RzIGluIHRoZSBmaXh0dXJlIHVzZSB0aGUgc2FtZSBwb29sLCBzbyB3ZQorICAvLyBjYW4gcmVmZXIgdG8gdGhlIGVudW0gYWJvdmUgaW4gdGhpcyBkZWZpbml0aW9uLikKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnYmFyLnByb3RvJyAiCisgICAgICAiZGVwZW5kZW5jeTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgICAgZmllbGQgeyBuYW1lOidiYXInIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9FTlVNICIKKyAgICAgICIgICAgICAgICAgICB0eXBlX25hbWU6ICdmb28uRm9vRW51bScgfSIKKyAgICAgICJ9IiwKKyAgICAgICJiYXIucHJvdG86IEZvby5iYXI6IFRZUEU6IEVudW0gdHlwZSBcImZvby5Gb29FbnVtXCIgaXMgbm90IGEgcHJvdG8zICIKKyAgICAgICJlbnVtLCBidXQgaXMgdXNlZCBpbiBcIkZvb1wiIHdoaWNoIGlzIGEgcHJvdG8zIG1lc3NhZ2UgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNFeHRlbnNpb24pIHsKKyAgLy8gVmFsaWQgZm9yIG9wdGlvbnMuCisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgLy8gQWRkICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKyAgLy8gQWRkICJmb28ucHJvdG8iOgorICAvLyAgIGltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iOworICAvLyAgIGV4dGVuZCBnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsKKyAgLy8gICAgIG9wdGlvbmFsIGludDMyIG9wdGlvbjEgPSAxMDAwOworICAvLyAgIH0KKyAgZmlsZV9wcm90by5DbGVhcigpOworICBmaWxlX3Byb3RvLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgZmlsZV9wcm90by5zZXRfc3ludGF4KCJwcm90bzMiKTsKKyAgZmlsZV9wcm90by5hZGRfZGVwZW5kZW5jeSgiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iKTsKKyAgQWRkRXh0ZW5zaW9uKCZmaWxlX3Byb3RvLCAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyIsICJvcHRpb24xIiwgMTAwMCwKKyAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgLy8gQ29weSBhbmQgY2hhbmdlIHRoZSBwYWNrYWdlIG9mIHRoZSBkZXNjcmlwdG9yLnByb3RvCisgIEJ1aWxkRmlsZSgKKyAgICAgICJuYW1lOiAnZ29vZ2xlLnByb3RvYnVmLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8yJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0NvbnRhaW5lcicgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAwIH0gIgorICAgICAgIn0iKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnYmFyLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAiZGVwZW5kZW5jeTogJ2dvb2dsZS5wcm90b2J1Zi5wcm90bycgIgorICAgICAgImV4dGVuc2lvbiB7ICIKKyAgICAgICIgIG5hbWU6ICdiYXInIG51bWJlcjogMSBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9JTlQzMiAiCisgICAgICAiICBleHRlbmRlZTogJ0NvbnRhaW5lcicgIgorICAgICAgIn0iLAorICAgICAgImJhci5wcm90bzogYmFyOiBPVEhFUjogRXh0ZW5zaW9ucyBpbiBwcm90bzMgYXJlIG9ubHkgYWxsb3dlZCBmb3IgIgorICAgICAgImRlZmluaW5nIG9wdGlvbnMuXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGVzY3JpcHRvckRhdGFiYXNlCisKK3N0YXRpYyB2b2lkIEFkZFRvRGF0YWJhc2UoU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlKiBkYXRhYmFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmlsZV90ZXh0KSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfdGV4dCwgJmZpbGVfcHJvdG8pKTsKKyAgZGF0YWJhc2UtPkFkZChmaWxlX3Byb3RvKTsKK30KKworY2xhc3MgRGF0YWJhc2VCYWNrZWRQb29sVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIERhdGFiYXNlQmFja2VkUG9vbFRlc3QoKSB7fQorCisgIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSBkYXRhYmFzZV87CisKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIEFkZFRvRGF0YWJhc2UoJmRhdGFiYXNlXywKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTonRm9vJyBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMCB9IH0gIgorICAgICAgImVudW1fdHlwZSB7IG5hbWU6J1Rlc3RFbnVtJyB2YWx1ZSB7IG5hbWU6J0RVTU1ZJyBudW1iZXI6MCB9IH0gIgorICAgICAgInNlcnZpY2UgeyBuYW1lOidUZXN0U2VydmljZScgfSAiKTsKKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZV8sCisgICAgICAibmFtZTogJ2Jhci5wcm90bycgIgorICAgICAgImRlcGVuZGVuY3k6ICdmb28ucHJvdG8nICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOidCYXInIH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6J2Zvb19leHQnIGV4dGVuZGVlOiAnLkZvbycgbnVtYmVyOjUgIgorICAgICAgIiAgICAgICAgICAgIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9ICIpOworICAgIC8vIEJheiBoYXMgYW4gdW5kZWNsYXJlZCBkZXBlbmRlbmN5IG9uIEZvby4KKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZV8sCisgICAgICAibmFtZTogJ2Jhei5wcm90bycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6J0JheicgIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb28nIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTonRm9vJyB9ICIKKyAgICAgICJ9Iik7CisgIH0KKworICAvLyBXZSBjYW4ndCBpbmplY3QgYSBmaWxlIGNvbnRhaW5pbmcgZXJyb3JzIGludG8gYSBEZXNjcmlwdG9yUG9vbCwgc28gd2UKKyAgLy8gbmVlZCBhbiBhY3R1YWwgbW9jayBEZXNjcmlwdG9yRGF0YWJhc2UgdG8gdGVzdCBlcnJvcnMuCisgIGNsYXNzIEVycm9yRGVzY3JpcHRvckRhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgICBwdWJsaWM6CisgICAgRXJyb3JEZXNjcmlwdG9yRGF0YWJhc2UoKSB7fQorICAgIH5FcnJvckRlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CisKKyAgICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIC8vIGVycm9yLnByb3RvIGFuZCBlcnJvcjIucHJvdG8gY3ljbGljYWxseSBpbXBvcnQgZWFjaCBvdGhlci4KKyAgICAgIGlmIChmaWxlbmFtZSA9PSAiZXJyb3IucHJvdG8iKSB7CisgICAgICAgIG91dHB1dC0+Q2xlYXIoKTsKKyAgICAgICAgb3V0cHV0LT5zZXRfbmFtZSgiZXJyb3IucHJvdG8iKTsKKyAgICAgICAgb3V0cHV0LT5hZGRfZGVwZW5kZW5jeSgiZXJyb3IyLnByb3RvIik7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfSBlbHNlIGlmIChmaWxlbmFtZSA9PSAiZXJyb3IyLnByb3RvIikgeworICAgICAgICBvdXRwdXQtPkNsZWFyKCk7CisgICAgICAgIG91dHB1dC0+c2V0X25hbWUoImVycm9yMi5wcm90byIpOworICAgICAgICBvdXRwdXQtPmFkZF9kZXBlbmRlbmN5KCJlcnJvci5wcm90byIpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH07CisKKyAgLy8gQSBEZXNjcmlwdG9yRGF0YWJhc2UgdGhhdCBjb3VudHMgaG93IG1hbnkgdGltZXMgZWFjaCBtZXRob2QgaGFzIGJlZW4KKyAgLy8gY2FsbGVkIGFuZCBmb3J3YXJkcyB0byBzb21lIG90aGVyIERlc2NyaXB0b3JEYXRhYmFzZS4KKyAgY2xhc3MgQ2FsbENvdW50aW5nRGF0YWJhc2UgOiBwdWJsaWMgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyAgIHB1YmxpYzoKKyAgICBDYWxsQ291bnRpbmdEYXRhYmFzZShEZXNjcmlwdG9yRGF0YWJhc2UqIHdyYXBwZWRfZGIpCisgICAgICA6IHdyYXBwZWRfZGJfKHdyYXBwZWRfZGIpIHsKKyAgICAgIENsZWFyKCk7CisgICAgfQorICAgIH5DYWxsQ291bnRpbmdEYXRhYmFzZSgpIHt9CisKKyAgICBEZXNjcmlwdG9yRGF0YWJhc2UqIHdyYXBwZWRfZGJfOworCisgICAgaW50IGNhbGxfY291bnRfOworCisgICAgdm9pZCBDbGVhcigpIHsKKyAgICAgIGNhbGxfY291bnRfID0gMDsKKyAgICB9CisKKyAgICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgICsrY2FsbF9jb3VudF87CisgICAgICByZXR1cm4gd3JhcHBlZF9kYl8tPkZpbmRGaWxlQnlOYW1lKGZpbGVuYW1lLCBvdXRwdXQpOworICAgIH0KKyAgICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgICAgKytjYWxsX2NvdW50XzsKKyAgICAgIHJldHVybiB3cmFwcGVkX2RiXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKHN5bWJvbF9uYW1lLCBvdXRwdXQpOworICAgIH0KKyAgICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgICAgKytjYWxsX2NvdW50XzsKKyAgICAgIHJldHVybiB3cmFwcGVkX2RiXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgICAgICBjb250YWluaW5nX3R5cGUsIGZpZWxkX251bWJlciwgb3V0cHV0KTsKKyAgICB9CisgIH07CisKKyAgLy8gQSBEZXNjcmlwdG9yRGF0YWJhc2Ugd2hpY2ggZmFsc2VseSBhbHdheXMgcmV0dXJucyBmb28ucHJvdG8gd2hlbiBzZWFyY2hpbmcKKyAgLy8gZm9yIGFueSBzeW1ib2wgb3IgZXh0ZW5zaW9uIG51bWJlci4gIFRoaXMgc2hvdWxkbid0IGNhdXNlIHRoZQorICAvLyBEZXNjcmlwdG9yUG9vbCB0byByZWxvYWQgZm9vLnByb3RvIGlmIGl0IGlzIGFscmVhZHkgbG9hZGVkLgorICBjbGFzcyBGYWxzZVBvc2l0aXZlRGF0YWJhc2UgOiBwdWJsaWMgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyAgIHB1YmxpYzoKKyAgICBGYWxzZVBvc2l0aXZlRGF0YWJhc2UoRGVzY3JpcHRvckRhdGFiYXNlKiB3cmFwcGVkX2RiKQorICAgICAgOiB3cmFwcGVkX2RiXyh3cmFwcGVkX2RiKSB7fQorICAgIH5GYWxzZVBvc2l0aXZlRGF0YWJhc2UoKSB7fQorCisgICAgRGVzY3JpcHRvckRhdGFiYXNlKiB3cmFwcGVkX2RiXzsKKworICAgIC8vIGltcGxlbWVudHMgRGVzY3JpcHRvckRhdGFiYXNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIGJvb2wgRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRfZGJfLT5GaW5kRmlsZUJ5TmFtZShmaWxlbmFtZSwgb3V0cHV0KTsKKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBGaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIiwgb3V0cHV0KTsKKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBGaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIiwgb3V0cHV0KTsKKyAgICB9CisgIH07Cit9OworCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgRmluZEZpbGVCeU5hbWUpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZGF0YWJhc2VfKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vID0gcG9vbC5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmb28tPm5hbWUoKSk7CisgIEFTU0VSVF9FUSgxLCBmb28tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKCJGb28iLCBmb28tPm1lc3NhZ2VfdHlwZSgwKS0+bmFtZSgpKTsKKworICBFWFBFQ1RfRVEoZm9vLCBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKSk7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgibm9fc3VjaF9maWxlLnByb3RvIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRGVwZW5kZW5jeUJlZm9yZURlcGVuZGVudCkgeworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoZm9vICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZvby0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGZvby0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoIkZvbyIsIGZvby0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXIgPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJiYXIucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoYmFyICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGJhci0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGJhci0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoIkJhciIsIGJhci0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIEFTU0VSVF9FUSgxLCBiYXItPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb28sIGJhci0+ZGVwZW5kZW5jeSgwKSk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRGVwZW5kZW50QmVmb3JlRGVwZW5kZW5jeSkgeworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXIgPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJiYXIucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoYmFyICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGJhci0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGJhci0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBBU1NFUlRfRVEoIkJhciIsIGJhci0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoZm9vICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZvby0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGZvby0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBBU1NFUlRfRVEoIkZvbyIsIGZvby0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIEFTU0VSVF9FUSgxLCBiYXItPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb28sIGJhci0+ZGVwZW5kZW5jeSgwKSk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2wpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZGF0YWJhc2VfKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28iKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoZmlsZSwgcG9vbC5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIikpOworCisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJOb1N1Y2hTeW1ib2wiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIEZpbmRNZXNzYWdlVHlwZUJ5TmFtZSkgeworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworCisgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUgPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKHR5cGUgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgiRm9vIiwgdHlwZS0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKHR5cGUtPmZpbGUoKSwgcG9vbC5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIikpOworCisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJOb1N1Y2hUeXBlIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRXh0ZW5zaW9uQnlOdW1iZXIpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZGF0YWJhc2VfKTsKKworICBjb25zdCBEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9IHBvb2wuRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGZvbywgNSk7CisgIEFTU0VSVF9UUlVFKGV4dGVuc2lvbiAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJmb29fZXh0IiwgZXh0ZW5zaW9uLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uLT5maWxlKCksIHBvb2wuRmluZEZpbGVCeU5hbWUoImJhci5wcm90byIpKTsKKworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFeHRlbnNpb25CeU51bWJlcihmb28sIDEyKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIEZpbmRBbGxFeHRlbnNpb25zKSB7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmRhdGFiYXNlXyk7CisKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vID0gcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkZvbyIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgKytpKSB7CisgICAgLy8gUmVwZWF0IHRoZSBsb29rdXAgdHdpY2UsIHRvIGNoZWNrIHRoYXQgd2UgZ2V0IGNvbnNpc3RlbnQKKyAgICAvLyByZXN1bHRzIGRlc3BpdGUgdGhlIGZhbGxiYWNrIGRhdGFiYXNlIGxvb2t1cCBtdXRhdGluZyB0aGUgcG9vbC4KKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZXh0ZW5zaW9uczsKKyAgICBwb29sLkZpbmRBbGxFeHRlbnNpb25zKGZvbywgJmV4dGVuc2lvbnMpOworICAgIEFTU0VSVF9FUSgxLCBleHRlbnNpb25zLnNpemUoKSk7CisgICAgRVhQRUNUX0VRKDUsIGV4dGVuc2lvbnNbMF0tPm51bWJlcigpKTsKKyAgfQorfQorCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgRXJyb3JXaXRob3V0RXJyb3JDb2xsZWN0b3IpIHsKKyAgRXJyb3JEZXNjcmlwdG9yRGF0YWJhc2UgZXJyb3JfZGF0YWJhc2U7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmVycm9yX2RhdGFiYXNlKTsKKworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgiZXJyb3IucHJvdG8iKSA9PSBOVUxMKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgRVhQRUNUX0ZBTFNFKGVycm9ycy5lbXB0eSgpKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIEVycm9yV2l0aEVycm9yQ29sbGVjdG9yKSB7CisgIEVycm9yRGVzY3JpcHRvckRhdGFiYXNlIGVycm9yX2RhdGFiYXNlOworICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZlcnJvcl9kYXRhYmFzZSwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgiZXJyb3IucHJvdG8iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX0VRKAorICAgICJlcnJvci5wcm90bzogZXJyb3IucHJvdG86IE9USEVSOiBGaWxlIHJlY3Vyc2l2ZWx5IGltcG9ydHMgaXRzZWxmOiAiCisgICAgICAiZXJyb3IucHJvdG8gLT4gZXJyb3IyLnByb3RvIC0+IGVycm9yLnByb3RvXG4iCisgICAgImVycm9yMi5wcm90bzogZXJyb3IyLnByb3RvOiBPVEhFUjogSW1wb3J0IFwiZXJyb3IucHJvdG9cIiB3YXMgbm90ICIKKyAgICAgICJmb3VuZCBvciBoYWQgZXJyb3JzLlxuIgorICAgICJlcnJvci5wcm90bzogZXJyb3IucHJvdG86IE9USEVSOiBJbXBvcnQgXCJlcnJvcjIucHJvdG9cIiB3YXMgbm90ICIKKyAgICAgICJmb3VuZCBvciBoYWQgZXJyb3JzLlxuIiwKKyAgICBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworfQorCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgVW5kZWNsYXJlZERlcGVuZGVuY3lPblVuYnVpbHRUeXBlKSB7CisgIC8vIENoZWNrIHRoYXQgd2UgZmluZCBhbmQgcmVwb3J0IHVuZGVjbGFyZWQgZGVwZW5kZW5jaWVzIG9uIHR5cGVzIHRoYXQgZXhpc3QKKyAgLy8gaW4gdGhlIGRlc2NyaXB0b3IgZGF0YWJhc2UgYnV0IHRoYXQgaGF2ZSBub3Qgbm90IGJlZW4gYnVpbHQgeWV0LgorICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8sICZlcnJvcl9jb2xsZWN0b3IpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmF6IikgPT0gTlVMTCk7CisgIEVYUEVDVF9FUSgKKyAgICAiYmF6LnByb3RvOiBCYXouZm9vOiBUWVBFOiBcIkZvb1wiIHNlZW1zIHRvIGJlIGRlZmluZWQgaW4gXCJmb28ucHJvdG9cIiwgIgorICAgICJ3aGljaCBpcyBub3QgaW1wb3J0ZWQgYnkgXCJiYXoucHJvdG9cIi4gIFRvIHVzZSBpdCBoZXJlLCBwbGVhc2UgYWRkICIKKyAgICAidGhlIG5lY2Vzc2FyeSBpbXBvcnQuXG4iLAorICAgIGVycm9yX2NvbGxlY3Rvci50ZXh0Xyk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBSb2xsYmFja0FmdGVyRXJyb3IpIHsKKyAgLy8gTWFrZSBzdXJlIHRoYXQgYWxsIHRyYWNlcyBvZiBiYWQgdHlwZXMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgcG9vbC4gVGhpcyB1c2VkCisgIC8vIHRvIGJlIGIvNDUyOTQzNiwgZHVlIHRvIHRoZSBmYWN0IHRoYXQgYSBzeW1ib2wgcmVzb2x1dGlvbiBmYWlsdXJlIGNvdWxkCisgIC8vIHBvdGVudGlhbGx5IGNhdXNlIGFub3RoZXIgZmlsZSB0byBiZSByZWN1cnNpdmVseSBidWlsdCwgd2hpY2ggd291bGQgdHJpZ2dlcgorICAvLyBhIGNoZWNrcG9pbnQgX3Bhc3RfIHBvc3NpYmx5IGludmFsaWQgc3ltYm9scy4KKyAgLy8gQmF6IGlzIGRlZmluZWQgaW4gdGhlIGRhdGFiYXNlLCBidXQgdGhlIGZpbGUgaXMgaW52YWxpZCBiZWNhdXNlIGl0IGlzCisgIC8vIG1pc3NpbmcgYSBuZWNlc3NhcnkgaW1wb3J0LgorICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmF6IikgPT0gTlVMTCk7CisgIC8vIE1ha2Ugc3VyZSB0aGF0IHNlYXJjaGluZyBhZ2FpbiBmb3IgdGhlIGZpbGUgb3IgdGhlIHR5cGUgZmFpbHMuCisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpbGVCeU5hbWUoImJhei5wcm90byIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmF6IikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBVbml0dGVzdFByb3RvKSB7CisgIC8vIFRyeSB0byBsb2FkIGFsbCBvZiB1bml0dGVzdC5wcm90byBmcm9tIGEgRGVzY3JpcHRvckRhdGFiYXNlLiAgVGhpcyBzaG91bGQKKyAgLy8gdGhvcm91Z2hseSB0ZXN0IGFsbCBwYXRocyB0aHJvdWdoIERlc2NyaXB0b3JCdWlsZGVyIHRvIGluc3VyZSB0aGF0IHRoZXJlCisgIC8vIGFyZSBubyBkZWFkbG9ja2luZyBwcm9ibGVtcyB3aGVuIHBvb2xfLT5tdXRleF8gaXMgbm9uLU5VTEwuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBvcmlnaW5hbF9maWxlID0KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCktPmZpbGUoKTsKKworICBEZXNjcmlwdG9yUG9vbERhdGFiYXNlIGRhdGFiYXNlKCpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSk7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmRhdGFiYXNlKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfZnJvbV9kYXRhYmFzZSA9CisgICAgcG9vbC5GaW5kRmlsZUJ5TmFtZShvcmlnaW5hbF9maWxlLT5uYW1lKCkpOworCisgIEFTU0VSVF9UUlVFKGZpbGVfZnJvbV9kYXRhYmFzZSAhPSBOVUxMKTsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIG9yaWdpbmFsX2ZpbGVfcHJvdG87CisgIG9yaWdpbmFsX2ZpbGUtPkNvcHlUbygmb3JpZ2luYWxfZmlsZV9wcm90byk7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX2Zyb21fZGF0YWJhc2VfcHJvdG87CisgIGZpbGVfZnJvbV9kYXRhYmFzZS0+Q29weVRvKCZmaWxlX2Zyb21fZGF0YWJhc2VfcHJvdG8pOworCisgIEVYUEVDVF9FUShvcmlnaW5hbF9maWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAgICAgICBmaWxlX2Zyb21fZGF0YWJhc2VfcHJvdG8uRGVidWdTdHJpbmcoKSk7CisKKyAgLy8gQWxzbyB2ZXJpZnkgdGhhdCBDb3B5VG8oKSBkaWQgbm90IG9taXQgYW55IGluZm9ybWF0aW9uLgorICBFWFBFQ1RfRVEob3JpZ2luYWxfZmlsZS0+RGVidWdTdHJpbmcoKSwKKyAgICAgICAgICAgIGZpbGVfZnJvbV9kYXRhYmFzZS0+RGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBEb2VzbnRSZXRyeURiVW5uZWNlc3NhcmlseSkgeworICAvLyBTZWFyY2hpbmcgZm9yIGEgY2hpbGQgb2YgYW4gZXhpc3RpbmcgZGVzY3JpcHRvciBzaG91bGQgbmV2ZXIgZmFsbCBiYWNrCisgIC8vIHRvIHRoZSBEZXNjcmlwdG9yRGF0YWJhc2UgZXZlbiBpZiBpdCBpc24ndCBmb3VuZCwgYmVjYXVzZSB3ZSBrbm93IGFsbAorICAvLyBjaGlsZHJlbiBhcmUgYWxyZWFkeSBsb2FkZWQuCisgIENhbGxDb3VudGluZ0RhdGFiYXNlIGNhbGxfY291bnRlcigmZGF0YWJhc2VfKTsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmY2FsbF9jb3VudGVyKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuRmluZEZpbGVCeU5hbWUoImZvby5wcm90byIpOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBjb25zdCBEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIHRlc3RfZW51bSA9IHBvb2wuRmluZEVudW1UeXBlQnlOYW1lKCJUZXN0RW51bSIpOworICBBU1NFUlRfVFJVRSh0ZXN0X2VudW0gIT0gTlVMTCk7CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiB0ZXN0X3NlcnZpY2UgPSBwb29sLkZpbmRTZXJ2aWNlQnlOYW1lKCJUZXN0U2VydmljZSIpOworICBBU1NFUlRfVFJVRSh0ZXN0X3NlcnZpY2UgIT0gTlVMTCk7CisKKyAgRVhQRUNUX05FKDAsIGNhbGxfY291bnRlci5jYWxsX2NvdW50Xyk7CisgIGNhbGxfY291bnRlci5DbGVhcigpOworCisgIEVYUEVDVF9UUlVFKGZvby0+RmluZEZpZWxkQnlOYW1lKCJub19zdWNoX2ZpZWxkIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvby0+RmluZEV4dGVuc2lvbkJ5TmFtZSgibm9fc3VjaF9leHRlbnNpb24iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZSgiTm9TdWNoTWVzc2FnZVR5cGUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vLT5GaW5kRW51bVR5cGVCeU5hbWUoIk5vU3VjaEVudW1UeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvby0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiTk9fU1VDSF9WQUxVRSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRSh0ZXN0X2VudW0tPkZpbmRWYWx1ZUJ5TmFtZSgiTk9fU1VDSF9WQUxVRSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRSh0ZXN0X3NlcnZpY2UtPkZpbmRNZXRob2RCeU5hbWUoIk5vU3VjaE1ldGhvZCIpID09IE5VTEwpOworCisgIEVYUEVDVF9UUlVFKGZpbGUtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiTm9TdWNoTWVzc2FnZVR5cGUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZmlsZS0+RmluZEVudW1UeXBlQnlOYW1lKCJOb1N1Y2hFbnVtVHlwZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmaWxlLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPkZpbmRTZXJ2aWNlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPkZpbmRFeHRlbnNpb25CeU5hbWUoIm5vX3N1Y2hfZXh0ZW5zaW9uIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZvby5uby5zdWNoLmZpZWxkIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28ubm9fc3VjaF9maWVsZCIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vLk5vU3VjaE1lc3NhZ2VUeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpZWxkQnlOYW1lKCJGb28ubm9fc3VjaF9maWVsZCIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvby5ub19zdWNoX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vLk5vU3VjaEVudW1UeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vLk5PX1NVQ0hfVkFMVUUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kTWV0aG9kQnlOYW1lKCJUZXN0U2VydmljZS5Ob1N1Y2hNZXRob2QiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoMCwgY2FsbF9jb3VudGVyLmNhbGxfY291bnRfKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIERvZXNudFJlbG9hZEZpbGVzVW5jZXNlc3NhcmlseSkgeworICAvLyBJZiBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woKSBvciBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oKSByZXR1cm4gYQorICAvLyBmaWxlIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgRGVzY3JpcHRvclBvb2wsIGl0IHNob3VsZCBub3QgYXR0ZW1wdCB0bworICAvLyByZWxvYWQgdGhlIGZpbGUuCisgIEZhbHNlUG9zaXRpdmVEYXRhYmFzZSBmYWxzZV9wb3NpdGl2ZV9kYXRhYmFzZSgmZGF0YWJhc2VfKTsKKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZmFsc2VfcG9zaXRpdmVfZGF0YWJhc2UsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIC8vIEZpcnN0IG1ha2Ugc3VyZSBmb28ucHJvdG8gaXMgbG9hZGVkLgorICBjb25zdCBEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKworICAvLyBUcnkgaW5kdWNpbmcgZmFsc2UgcG9zaXRpdmVzLgorICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiTm9TdWNoU3ltYm9sIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGZvbywgMjIpID09IE5VTEwpOworCisgIC8vIE5vIGVycm9ycyBzaG91bGQgaGF2ZSBiZWVuIHJlcG9ydGVkLiAgKElmIGZvby5wcm90byB3YXMgaW5jb3JyZWN0bHkKKyAgLy8gbG9hZGVkIG11bHRpcGxlIHRpbWVzLCBlcnJvcnMgd291bGQgaGF2ZSBiZWVuIHJlcG9ydGVkLikKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworfQorCisvLyBEZXNjcmlwdG9yRGF0YWJhc2UgdGhhdCBhdHRlbXB0cyB0byBpbmR1Y2UgZXhwb25lbnRpYWxseS1iYWQgcGVyZm9ybWFuY2UKKy8vIGluIERlc2NyaXB0b3JQb29sLiBGb3IgZXZlcnkgcG9zaXRpdmUgTiwgdGhlIGRhdGFiYXNlIGNvbnRhaW5zIGEgZmlsZQorLy8gZmlsZU4ucHJvdG8sIHdoaWNoIGRlZmluZXMgYSBtZXNzYWdlIE1lc3NhZ2VOLCB3aGljaCBjb250YWlucyBmaWVsZHMgb2YKKy8vIHR5cGUgTWVzc2FnZUsgZm9yIGFsbCBLIGluIFswLE4pLiBNZXNzYWdlMCBpcyBub3QgZGVmaW5lZCBhbnl3aGVyZQorLy8gKGZpbGUwLnByb3RvIGV4aXN0cywgYnV0IGlzIGVtcHR5KSwgc28gZXZlcnkgb3RoZXIgZmlsZSBhbmQgbWVzc2FnZSB0eXBlCisvLyB3aWxsIGZhaWwgdG8gYnVpbGQuCisvLworLy8gSWYgdGhlIERlc2NyaXB0b3JQb29sIGlzIG5vdCBjYXJlZnVsIHRvIG1lbW9pemUgZXJyb3JzLCBhbiBhdHRlbXB0IHRvCisvLyBidWlsZCBhIGRlc2NyaXB0b3IgZm9yIE1lc3NhZ2VOIGNhbiByZXF1aXJlIE8oMl5OKSB0aW1lLgorY2xhc3MgRXhwb25lbnRpYWxFcnJvckRhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgcHVibGljOgorICBFeHBvbmVudGlhbEVycm9yRGF0YWJhc2UoKSB7fQorICB+RXhwb25lbnRpYWxFcnJvckRhdGFiYXNlKCkge30KKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBGaW5kRmlsZUJ5TmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgIGludCBmaWxlX251bSA9IC0xOworICAgIEZ1bGxNYXRjaChmaWxlbmFtZSwgImZpbGUiLCAiLnByb3RvIiwgJmZpbGVfbnVtKTsKKyAgICBpZiAoZmlsZV9udW0gPiAtMSkgeworICAgICAgcmV0dXJuIFBvcHVsYXRlRmlsZShmaWxlX251bSwgb3V0cHV0KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICBpbnQgZmlsZV9udW0gPSAtMTsKKyAgICBGdWxsTWF0Y2goc3ltYm9sX25hbWUsICJNZXNzYWdlIiwgIiIsICZmaWxlX251bSk7CisgICAgaWYgKGZpbGVfbnVtID4gMCkgeworICAgICAgcmV0dXJuIFBvcHVsYXRlRmlsZShmaWxlX251bSwgb3V0cHV0KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyBwcml2YXRlOgorICB2b2lkIEZ1bGxNYXRjaChjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgYmVnaW5fd2l0aCwKKyAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBlbmRfd2l0aCwKKyAgICAgICAgICAgICAgICAgaW50KiBmaWxlX251bSkgeworICAgIGludCBiZWdpbl9zaXplID0gYmVnaW5fd2l0aC5zaXplKCk7CisgICAgaW50IGVuZF9zaXplID0gZW5kX3dpdGguc2l6ZSgpOworICAgIGlmIChuYW1lLnN1YnN0cigwLCBiZWdpbl9zaXplKSAhPSBiZWdpbl93aXRoIHx8CisgICAgICAgIG5hbWUuc3Vic3RyKG5hbWUuc2l6ZSgpLSBlbmRfc2l6ZSwgZW5kX3NpemUpICE9IGVuZF93aXRoKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIHNhZmVfc3RydG8zMihuYW1lLnN1YnN0cihiZWdpbl9zaXplLCBuYW1lLnNpemUoKSAtIGVuZF9zaXplIC0gYmVnaW5fc2l6ZSksCisgICAgICAgICAgICAgICAgIGZpbGVfbnVtKTsKKyAgfQorCisgIGJvb2wgUG9wdWxhdGVGaWxlKGludCBmaWxlX251bSwgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgICAgdXNpbmcgc3RyaW5nczo6U3Vic3RpdHV0ZTsKKyAgICBHT09HTEVfQ0hFQ0tfR0UoZmlsZV9udW0sIDApOworICAgIG91dHB1dC0+Q2xlYXIoKTsKKyAgICBvdXRwdXQtPnNldF9uYW1lKFN1YnN0aXR1dGUoImZpbGUkMC5wcm90byIsIGZpbGVfbnVtKSk7CisgICAgLy8gZmlsZTAucHJvdG8gZG9lc24ndCBkZWZpbmUgTWVzc2FnZTAKKyAgICBpZiAoZmlsZV9udW0gPiAwKSB7CisgICAgICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UgPSBvdXRwdXQtPmFkZF9tZXNzYWdlX3R5cGUoKTsKKyAgICAgIG1lc3NhZ2UtPnNldF9uYW1lKFN1YnN0aXR1dGUoIk1lc3NhZ2UkMCIsIGZpbGVfbnVtKSk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfbnVtOyArK2kpIHsKKyAgICAgICAgb3V0cHV0LT5hZGRfZGVwZW5kZW5jeShTdWJzdGl0dXRlKCJmaWxlJDAucHJvdG8iLCBpKSk7CisgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBmaWVsZCA9IG1lc3NhZ2UtPmFkZF9maWVsZCgpOworICAgICAgICBmaWVsZC0+c2V0X25hbWUoU3Vic3RpdHV0ZSgiZmllbGQkMCIsIGkpKTsKKyAgICAgICAgZmllbGQtPnNldF9udW1iZXIoaSk7CisgICAgICAgIGZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAgICAgICAgZmllbGQtPnNldF90eXBlKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX01FU1NBR0UpOworICAgICAgICBmaWVsZC0+c2V0X3R5cGVfbmFtZShTdWJzdGl0dXRlKCJNZXNzYWdlJDAiLCBpKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9Cit9OworCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgRG9lc250UmVsb2FkS25vd25CYWRGaWxlcykgeworICBFeHBvbmVudGlhbEVycm9yRGF0YWJhc2UgZXJyb3JfZGF0YWJhc2U7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmVycm9yX2RhdGFiYXNlKTsKKworICBHT09HTEVfTE9HKElORk8pIDw8ICJBIHRpbWVvdXQgaW4gdGhpcyB0ZXN0IHByb2JhYmx5IGluZGljYXRlcyBhIHJlYWwgYnVnLiI7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgiZmlsZTQwLnByb3RvIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJNZXNzYWdlNDAiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIERvZXNudEZhbGxiYWNrT25Xcm9uZ1R5cGUpIHsKKyAgLy8gSWYgYSBsb29rdXAgZmluZHMgYSBzeW1ib2wgb2YgdGhlIHdyb25nIHR5cGUgKGUuZy4gd2UgcGFzcyBhIHR5cGUgbmFtZQorICAvLyB0byBGaW5kRmllbGRCeU5hbWUoKSksIHdlIHNob3VsZCBmYWlsIGZhc3QsIHdpdGhvdXQgY2hlY2tpbmcgdGhlIGZhbGxiYWNrCisgIC8vIGRhdGFiYXNlLgorICBDYWxsQ291bnRpbmdEYXRhYmFzZSBjYWxsX2NvdW50ZXIoJmRhdGFiYXNlXyk7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmNhbGxfY291bnRlcik7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vID0gcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkZvbyIpOworICBBU1NFUlRfVFJVRShmb28gIT0gTlVMTCk7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiB0ZXN0X2VudW0gPSBwb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgiVGVzdEVudW0iKTsKKyAgQVNTRVJUX1RSVUUodGVzdF9lbnVtICE9IE5VTEwpOworCisgIEVYUEVDVF9ORSgwLCBjYWxsX2NvdW50ZXIuY2FsbF9jb3VudF8pOworICBjYWxsX2NvdW50ZXIuQ2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiVGVzdEVudW0iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmllbGRCeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZFNlcnZpY2VCeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXRob2RCeU5hbWUoIkZvbyIpID09IE5VTEwpOworCisgIEVYUEVDVF9FUSgwLCBjYWxsX2NvdW50ZXIuY2FsbF9jb3VudF8pOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIEFib3J0aW5nRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIEFib3J0aW5nRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHZpcnR1YWwgdm9pZCBBZGRFcnJvcigKKyAgICAgIGNvbnN0IHN0cmluZyAmZmlsZW5hbWUsCisgICAgICBjb25zdCBzdHJpbmcgJmVsZW1lbnRfbmFtZSwKKyAgICAgIGNvbnN0IE1lc3NhZ2UgKm1lc3NhZ2UsCisgICAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgY29uc3Qgc3RyaW5nICZlcnJvcl9tZXNzYWdlKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkFkZEVycm9yKCkgY2FsbGVkIHVuZXhwZWN0ZWRseTogIiA8PCBmaWxlbmFtZSA8PCAiIFsiCisgICAgICAgICAgICAgICA8PCBlbGVtZW50X25hbWUgPDwgIl06ICIgPDwgZXJyb3JfbWVzc2FnZTsKKyAgfQorIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhBYm9ydGluZ0Vycm9yQ29sbGVjdG9yKTsKK307CisKKy8vIEEgc291cmNlIHRyZWUgY29udGFpbmluZyBvbmx5IG9uZSBmaWxlLgorY2xhc3MgU2luZ2xldG9uU291cmNlVHJlZSA6IHB1YmxpYyBjb21waWxlcjo6U291cmNlVHJlZSB7CisgcHVibGljOgorICBTaW5nbGV0b25Tb3VyY2VUcmVlKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGNvbnN0IHN0cmluZyYgY29udGVudHMpCisgICAgICA6IGZpbGVuYW1lXyhmaWxlbmFtZSksIGNvbnRlbnRzXyhjb250ZW50cykge30KKworICB2aXJ0dWFsIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gZmlsZW5hbWUgPT0gZmlsZW5hbWVfID8KKyAgICAgICAgbmV3IGlvOjpBcnJheUlucHV0U3RyZWFtKGNvbnRlbnRzXy5kYXRhKCksIGNvbnRlbnRzXy5zaXplKCkpIDogTlVMTDsKKyAgfQorCisgcHJpdmF0ZToKKyAgY29uc3Qgc3RyaW5nIGZpbGVuYW1lXzsKKyAgY29uc3Qgc3RyaW5nIGNvbnRlbnRzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU2luZ2xldG9uU291cmNlVHJlZSk7Cit9OworCitjb25zdCBjaGFyICpjb25zdCBrU291cmNlTG9jYXRpb25UZXN0SW5wdXQgPQorICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgIm1lc3NhZ2UgQSB7XG4iCisgICIgIG9wdGlvbmFsIGludDMyIGEgPSAxO1xuIgorICAiICBtZXNzYWdlIEIge1xuIgorICAiICAgIHJlcXVpcmVkIGRvdWJsZSBiID0gMTtcbiIKKyAgIiAgfVxuIgorICAifVxuIgorICAiZW51bSBJbmRlY2lzaW9uIHtcbiIKKyAgIiAgWUVTICAgPSAxO1xuIgorICAiICBOTyAgICA9IDI7XG4iCisgICIgIE1BWUJFID0gMztcbiIKKyAgIn1cbiIKKyAgInNlcnZpY2UgUyB7XG4iCisgICIgIHJwYyBNZXRob2QoQSkgcmV0dXJucyAoQS5CKTtcbiIKKyAgLy8gUHV0IGFuIGVtcHR5IGxpbmUgaGVyZSB0byBtYWtlIHRoZSBzb3VyY2UgbG9jYXRpb24gcmFuZ2UgbWF0Y2guCisgICJcbiIKKyAgIn1cbiIKKyAgIm1lc3NhZ2UgTWVzc2FnZVdpdGhFeHRlbnNpb25zIHtcbiIKKyAgIiAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDtcbiIKKyAgIn1cbiIKKyAgImV4dGVuZCBNZXNzYWdlV2l0aEV4dGVuc2lvbnMge1xuIgorICAiICBvcHRpb25hbCBpbnQzMiBpbnQzMl9leHRlbnNpb24gPSAxMDAxO1xuIgorICAifVxuIgorICAibWVzc2FnZSBDIHtcbiIKKyAgIiAgZXh0ZW5kIE1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7XG4iCisgICIgICAgb3B0aW9uYWwgQyBtZXNzYWdlX2V4dGVuc2lvbiA9IDEwMDI7XG4iCisgICIgIH1cbiIKKyAgIn1cbiI7CisKK2NsYXNzIFNvdXJjZUxvY2F0aW9uVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwdWJsaWM6CisgIFNvdXJjZUxvY2F0aW9uVGVzdCgpCisgICAgICA6IHNvdXJjZV90cmVlXygiL3Rlc3QvdGVzdC5wcm90byIsIGtTb3VyY2VMb2NhdGlvblRlc3RJbnB1dCksCisgICAgICAgIGRiXygmc291cmNlX3RyZWVfKSwKKyAgICAgICAgcG9vbF8oJmRiXywgJmNvbGxlY3Rvcl8pIHt9CisKKyAgc3RhdGljIHN0cmluZyBQcmludFNvdXJjZUxvY2F0aW9uKGNvbnN0IFNvdXJjZUxvY2F0aW9uICZsb2MpIHsKKyAgICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgiJDA6JDEtJDI6JDMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKyBsb2Muc3RhcnRfbGluZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxICsgbG9jLnN0YXJ0X2NvbHVtbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxICsgbG9jLmVuZF9saW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKyBsb2MuZW5kX2NvbHVtbik7CisgIH0KKworIHByaXZhdGU6CisgIEFib3J0aW5nRXJyb3JDb2xsZWN0b3IgY29sbGVjdG9yXzsKKyAgU2luZ2xldG9uU291cmNlVHJlZSBzb3VyY2VfdHJlZV87CisgIGNvbXBpbGVyOjpTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlIGRiXzsKKworIHByb3RlY3RlZDoKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87Cit9OworCisvLyBUT0RPKGFkb25vdmFuKTogaW1wbGVtZW50IHN1cHBvcnQgZm9yIG9wdGlvbiBmaWVsZHMgYW5kIGZvcgorLy8gc3VicGFydHMgb2YgZGVjbGFyYXRpb25zLgorCitURVNUX0YoU291cmNlTG9jYXRpb25UZXN0LCBHZXRTb3VyY2VMb2NhdGlvbikgeworICBTb3VyY2VMb2NhdGlvbiBsb2M7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IgKmZpbGVfZGVzYyA9CisgICAgICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChwb29sXy5GaW5kRmlsZUJ5TmFtZSgiL3Rlc3QvdGVzdC5wcm90byIpKTsKKworICBjb25zdCBEZXNjcmlwdG9yICphX2Rlc2MgPSBmaWxlX2Rlc2MtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQSIpOworICBFWFBFQ1RfVFJVRShhX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyOjEtNzoyIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBEZXNjcmlwdG9yICphX2JfZGVzYyA9IGFfZGVzYy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIkIiKTsKKyAgRVhQRUNUX1RSVUUoYV9iX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCI0OjMtNjo0IiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBFbnVtRGVzY3JpcHRvciAqZV9kZXNjID0gZmlsZV9kZXNjLT5GaW5kRW51bVR5cGVCeU5hbWUoIkluZGVjaXNpb24iKTsKKyAgRVhQRUNUX1RSVUUoZV9kZXNjLT5HZXRTb3VyY2VMb2NhdGlvbigmbG9jKSk7CisgIEVYUEVDVF9FUSgiODoxLTEyOjIiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IgKnllc19kZXNjID0gZV9kZXNjLT5GaW5kVmFsdWVCeU5hbWUoIllFUyIpOworICBFWFBFQ1RfVFJVRSh5ZXNfZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJmxvYykpOworICBFWFBFQ1RfRVEoIjk6My05OjEzIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciAqc19kZXNjID0gZmlsZV9kZXNjLT5GaW5kU2VydmljZUJ5TmFtZSgiUyIpOworICBFWFBFQ1RfVFJVRShzX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIxMzoxLTE2OjIiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IgKm1fZGVzYyA9IHNfZGVzYy0+RmluZE1ldGhvZEJ5TmFtZSgiTWV0aG9kIik7CisgIEVYUEVDVF9UUlVFKG1fZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJmxvYykpOworICBFWFBFQ1RfRVEoIjE0OjMtMTQ6MzEiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCit9CisKK1RFU1RfRihTb3VyY2VMb2NhdGlvblRlc3QsIEV4dGVuc2lvblNvdXJjZUxvY2F0aW9uKSB7CisgIFNvdXJjZUxvY2F0aW9uIGxvYzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciAqZmlsZV9kZXNjID0KKyAgICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKHBvb2xfLkZpbmRGaWxlQnlOYW1lKCIvdGVzdC90ZXN0LnByb3RvIikpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqaW50MzJfZXh0ZW5zaW9uX2Rlc2MgPQorICAgICAgZmlsZV9kZXNjLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJpbnQzMl9leHRlbnNpb24iKTsKKyAgRVhQRUNUX1RSVUUoaW50MzJfZXh0ZW5zaW9uX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyMTozLTIxOjQxIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBEZXNjcmlwdG9yICpjX2Rlc2MgPSBmaWxlX2Rlc2MtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQyIpOworICBFWFBFQ1RfVFJVRShjX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyMzoxLTI3OjIiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqbWVzc2FnZV9leHRlbnNpb25fZGVzYyA9CisgICAgICBjX2Rlc2MtPkZpbmRFeHRlbnNpb25CeU5hbWUoIm1lc3NhZ2VfZXh0ZW5zaW9uIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfZXh0ZW5zaW9uX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyNTo1LTI1OjQxIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKK30KKworLy8gTWlzc2luZyBTb3VyY2VDb2RlSW5mbyBkb2Vzbid0IGNhdXNlIGNyYXNoOgorVEVTVF9GKFNvdXJjZUxvY2F0aW9uVGVzdCwgR2V0U291cmNlTG9jYXRpb25fTWlzc2luZ1NvdXJjZUNvZGVJbmZvKSB7CisgIFNvdXJjZUxvY2F0aW9uIGxvYzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciAqZmlsZV9kZXNjID0KKyAgICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKHBvb2xfLkZpbmRGaWxlQnlOYW1lKCIvdGVzdC90ZXN0LnByb3RvIikpOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG87CisgIGZpbGVfZGVzYy0+Q29weVRvKCZwcm90byk7ICAvLyBOb3RlLCB0aGlzIGRpc2NhcmRzIHRoZSBTb3VyY2VDb2RlSW5mby4KKyAgRVhQRUNUX0ZBTFNFKHByb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworCisgIERlc2NyaXB0b3JQb29sIGJhZDFfcG9vbCgmcG9vbF8pOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFkMV9maWxlX2Rlc2MgPQorICAgICAgR09PR0xFX0NIRUNLX05PVE5VTEwoYmFkMV9wb29sLkJ1aWxkRmlsZShwcm90bykpOworICBjb25zdCBEZXNjcmlwdG9yICpiYWQxX2FfZGVzYyA9IGJhZDFfZmlsZV9kZXNjLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkEiKTsKKyAgRVhQRUNUX0ZBTFNFKGJhZDFfYV9kZXNjLT5HZXRTb3VyY2VMb2NhdGlvbigmbG9jKSk7Cit9CisKKy8vIENvcnJ1cHQgU291cmNlQ29kZUluZm8gZG9lc24ndCBjYXVzZSBjcmFzaDoKK1RFU1RfRihTb3VyY2VMb2NhdGlvblRlc3QsIEdldFNvdXJjZUxvY2F0aW9uX0JvZ3VzU291cmNlQ29kZUluZm8pIHsKKyAgU291cmNlTG9jYXRpb24gbG9jOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yICpmaWxlX2Rlc2MgPQorICAgICAgR09PR0xFX0NIRUNLX05PVE5VTEwocG9vbF8uRmluZEZpbGVCeU5hbWUoIi90ZXN0L3Rlc3QucHJvdG8iKSk7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBwcm90bzsKKyAgZmlsZV9kZXNjLT5Db3B5VG8oJnByb3RvKTsgIC8vIE5vdGUsIHRoaXMgZGlzY2FyZHMgdGhlIFNvdXJjZUNvZGVJbmZvLgorICBFWFBFQ1RfRkFMU0UocHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uICpsb2NfbXNnID0KKyAgICAgIHByb3RvLm11dGFibGVfc291cmNlX2NvZGVfaW5mbygpLT5hZGRfbG9jYXRpb24oKTsKKyAgbG9jX21zZy0+YWRkX3BhdGgoMSk7CisgIGxvY19tc2ctPmFkZF9wYXRoKDIpOworICBsb2NfbXNnLT5hZGRfcGF0aCgzKTsKKyAgbG9jX21zZy0+YWRkX3NwYW4oNCk7CisgIGxvY19tc2ctPmFkZF9zcGFuKDUpOworICBsb2NfbXNnLT5hZGRfc3Bhbig2KTsKKworICBEZXNjcmlwdG9yUG9vbCBiYWQyX3Bvb2woJnBvb2xfKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhZDJfZmlsZV9kZXNjID0KKyAgICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKGJhZDJfcG9vbC5CdWlsZEZpbGUocHJvdG8pKTsKKyAgY29uc3QgRGVzY3JpcHRvciAqYmFkMl9hX2Rlc2MgPSBiYWQyX2ZpbGVfZGVzYy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJBIik7CisgIEVYUEVDVF9GQUxTRShiYWQyX2FfZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJmxvYykpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NvbnN0IGNoYXIqIGNvbnN0IGtDb3B5U291cmNlQ29kZUluZm9Ub1Rlc3RJbnB1dCA9CisgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAibWVzc2FnZSBGb28ge31cbiI7CisKKy8vIFJlcXVpcmVkIHNpbmNlIHNvdXJjZSBjb2RlIGluZm9ybWF0aW9uIGlzIG5vdCBwcmVzZXJ2ZWQgYnkKKy8vIEZpbGVEZXNjcmlwdG9yVGVzdC4KK2NsYXNzIENvcHlTb3VyY2VDb2RlSW5mb1RvVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwdWJsaWM6CisgIENvcHlTb3VyY2VDb2RlSW5mb1RvVGVzdCgpCisgICAgICA6IHNvdXJjZV90cmVlXygiL3Rlc3QvdGVzdC5wcm90byIsIGtDb3B5U291cmNlQ29kZUluZm9Ub1Rlc3RJbnB1dCksCisgICAgICAgIGRiXygmc291cmNlX3RyZWVfKSwKKyAgICAgICAgcG9vbF8oJmRiXywgJmNvbGxlY3Rvcl8pIHt9CisKKyBwcml2YXRlOgorICBBYm9ydGluZ0Vycm9yQ29sbGVjdG9yIGNvbGxlY3Rvcl87CisgIFNpbmdsZXRvblNvdXJjZVRyZWUgc291cmNlX3RyZWVfOworICBjb21waWxlcjo6U291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSBkYl87CisKKyBwcm90ZWN0ZWQ6CisgIERlc2NyaXB0b3JQb29sIHBvb2xfOworfTsKKworVEVTVF9GKENvcHlTb3VyY2VDb2RlSW5mb1RvVGVzdCwgQ29weVRvX0RvZXNOb3RDb3B5U291cmNlQ29kZUluZm8pIHsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfZGVzYyA9CisgICAgICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChwb29sXy5GaW5kRmlsZUJ5TmFtZSgiL3Rlc3QvdGVzdC5wcm90byIpKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX2Rlc2NfcHJvdG87CisgIEFTU0VSVF9GQUxTRShmaWxlX2Rlc2NfcHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisKKyAgZmlsZV9kZXNjLT5Db3B5VG8oJmZpbGVfZGVzY19wcm90byk7CisgIEVYUEVDVF9GQUxTRShmaWxlX2Rlc2NfcHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7Cit9CisKK1RFU1RfRihDb3B5U291cmNlQ29kZUluZm9Ub1Rlc3QsIENvcHlTb3VyY2VDb2RlSW5mb1RvKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlX2Rlc2MgPQorICAgICAgR09PR0xFX0NIRUNLX05PVE5VTEwocG9vbF8uRmluZEZpbGVCeU5hbWUoIi90ZXN0L3Rlc3QucHJvdG8iKSk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9kZXNjX3Byb3RvOworICBBU1NFUlRfRkFMU0UoZmlsZV9kZXNjX3Byb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworCisgIGZpbGVfZGVzYy0+Q29weVNvdXJjZUNvZGVJbmZvVG8oJmZpbGVfZGVzY19wcm90byk7CisgIGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBpbmZvID0gZmlsZV9kZXNjX3Byb3RvLnNvdXJjZV9jb2RlX2luZm8oKTsKKyAgQVNTRVJUX0VRKDQsIGluZm8ubG9jYXRpb25fc2l6ZSgpKTsKKyAgLy8gR2V0IHRoZSBGb28gbWVzc2FnZSBsb2NhdGlvbgorICBjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZm9vX2xvY2F0aW9uID0gaW5mby5sb2NhdGlvbigyKTsKKyAgQVNTRVJUX0VRKDIsIGZvb19sb2NhdGlvbi5wYXRoX3NpemUoKSk7CisgIEVYUEVDVF9FUShGaWxlRGVzY3JpcHRvclByb3RvOjprTWVzc2FnZVR5cGVGaWVsZE51bWJlciwgZm9vX2xvY2F0aW9uLnBhdGgoMCkpOworICBFWFBFQ1RfRVEoMCwgZm9vX2xvY2F0aW9uLnBhdGgoMSkpOyAgICAgIC8vIEZvbyBpcyB0aGUgZmlyc3QgbWVzc2FnZSBkZWZpbmVkCisgIEFTU0VSVF9FUSgzLCBmb29fbG9jYXRpb24uc3Bhbl9zaXplKCkpOyAgLy8gRm9vIHNwYW5zIG9uZSBsaW5lCisgIEVYUEVDVF9FUSgxLCBmb29fbG9jYXRpb24uc3BhbigwKSk7ICAgICAgLy8gRm9vIGlzIGRlY2xhcmVkIG9uIGxpbmUgMQorICBFWFBFQ1RfRVEoMCwgZm9vX2xvY2F0aW9uLnNwYW4oMSkpOyAgICAgIC8vIEZvbyBzdGFydHMgYXQgY29sdW1uIDAKKyAgRVhQRUNUX0VRKDE0LCBmb29fbG9jYXRpb24uc3BhbigyKSk7ICAgICAvLyBGb28gZW5kcyBvbiBjb2x1bW4gMTQKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKK30gIC8vIG5hbWVzcGFjZSBkZXNjcmlwdG9yX3VuaXR0ZXN0Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZHJvcF91bmtub3duX2ZpZWxkc190ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kcm9wX3Vua25vd25fZmllbGRzX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmYxNmRjNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHJvcF91bmtub3duX2ZpZWxkc190ZXN0LmNjCkBAIC0wLDAgKzEsODggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Ryb3BfdW5rbm93bl9maWVsZHMucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyB1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzOjpGb287Cit1c2luZyB1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzOjpGb29XaXRoRXh0cmFGaWVsZHM7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK1RFU1QoRHJvcFVua25vd25GaWVsZHNUZXN0LCBHZW5lcmF0ZWRNZXNzYWdlKSB7CisgIEZvb1dpdGhFeHRyYUZpZWxkcyBmb29fd2l0aF9leHRyYV9maWVsZHM7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfaW50MzJfdmFsdWUoMSk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZW51bV92YWx1ZShGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZXh0cmFfaW50MzJfdmFsdWUoMik7CisKKyAgRm9vIGZvbzsKKyAgQVNTRVJUX1RSVUUoZm9vLlBhcnNlRnJvbVN0cmluZyhmb29fd2l0aF9leHRyYV9maWVsZHMuU2VyaWFsaXplQXNTdHJpbmcoKSkpOworICBFWFBFQ1RfRVEoMSwgZm9vLmludDMyX3ZhbHVlKCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PihGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KGZvby5lbnVtX3ZhbHVlKCkpKTsKKyAgLy8gV2UgZG9uJ3QgZ2VuZXJhdGUgdW5rbm93biBmaWVsZCBhY2Nlc3NvcnMgYnV0IHRoZSBVbmtub3duRmllbGRTZXQgaXMKKyAgLy8gc3RpbGwgZXhwb3NlZCB0aHJvdWdoIHJlZmxlY3Rpb24gQVBJLgorICBFWFBFQ1RfVFJVRShmb28uR2V0UmVmbGVjdGlvbigpLT5HZXRVbmtub3duRmllbGRzKGZvbykuZW1wdHkoKSk7CisKKyAgQVNTRVJUX1RSVUUoZm9vX3dpdGhfZXh0cmFfZmllbGRzLlBhcnNlRnJvbVN0cmluZyhmb28uU2VyaWFsaXplQXNTdHJpbmcoKSkpOworICBFWFBFQ1RfRVEoMSwgZm9vX3dpdGhfZXh0cmFfZmllbGRzLmludDMyX3ZhbHVlKCkpOworICBFWFBFQ1RfRVEoRm9vV2l0aEV4dHJhRmllbGRzOjpRVVgsIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5lbnVtX3ZhbHVlKCkpOworICAvLyBUaGUgImV4dHJhX2ludDMyX3ZhbHVlIiBmaWVsZCBzaG91bGQgYmUgbG9zdC4KKyAgRVhQRUNUX0VRKDAsIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5leHRyYV9pbnQzMl92YWx1ZSgpKTsKK30KKworVEVTVChEcm9wVW5rbm93bkZpZWxkc1Rlc3QsIER5bmFtaWNNZXNzYWdlKSB7CisgIEZvb1dpdGhFeHRyYUZpZWxkcyBmb29fd2l0aF9leHRyYV9maWVsZHM7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfaW50MzJfdmFsdWUoMSk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZW51bV92YWx1ZShGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZXh0cmFfaW50MzJfdmFsdWUoMik7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6RHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZT4gZm9vKAorICAgICAgZmFjdG9yeS5HZXRQcm90b3R5cGUoRm9vOjpkZXNjcmlwdG9yKCkpLT5OZXcoKSk7CisgIEFTU0VSVF9UUlVFKGZvby0+UGFyc2VGcm9tU3RyaW5nKGZvb193aXRoX2V4dHJhX2ZpZWxkcy5TZXJpYWxpemVBc1N0cmluZygpKSk7CisgIEVYUEVDVF9UUlVFKGZvby0+R2V0UmVmbGVjdGlvbigpLT5HZXRVbmtub3duRmllbGRzKCpmb28pLmVtcHR5KCkpOworCisgIEFTU0VSVF9UUlVFKGZvb193aXRoX2V4dHJhX2ZpZWxkcy5QYXJzZUZyb21TdHJpbmcoZm9vLT5TZXJpYWxpemVBc1N0cmluZygpKSk7CisgIEVYUEVDVF9FUSgxLCBmb29fd2l0aF9leHRyYV9maWVsZHMuaW50MzJfdmFsdWUoKSk7CisgIEVYUEVDVF9FUShGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCwgZm9vX3dpdGhfZXh0cmFfZmllbGRzLmVudW1fdmFsdWUoKSk7CisgIC8vIFRoZSAiZXh0cmFfaW50MzJfdmFsdWUiIGZpZWxkIHNob3VsZCBiZSBsb3N0LgorICBFWFBFQ1RfRVEoMCwgZm9vX3dpdGhfZXh0cmFfZmllbGRzLmV4dHJhX2ludDMyX3ZhbHVlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2OGM3MzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvCkBAIC0wLDAgKzEsOTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIkR1cmF0aW9uUHJvdG8iOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKKworCisvLyBBIER1cmF0aW9uIHJlcHJlc2VudHMgYSBzaWduZWQsIGZpeGVkLWxlbmd0aCBzcGFuIG9mIHRpbWUgcmVwcmVzZW50ZWQKKy8vIGFzIGEgY291bnQgb2Ygc2Vjb25kcyBhbmQgZnJhY3Rpb25zIG9mIHNlY29uZHMgYXQgbmFub3NlY29uZAorLy8gcmVzb2x1dGlvbi4gSXQgaXMgaW5kZXBlbmRlbnQgb2YgYW55IGNhbGVuZGFyIGFuZCBjb25jZXB0cyBsaWtlICJkYXkiCisvLyBvciAibW9udGgiLiBJdCBpcyByZWxhdGVkIHRvIFRpbWVzdGFtcCBpbiB0aGF0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4KKy8vIHR3byBUaW1lc3RhbXAgdmFsdWVzIGlzIGEgRHVyYXRpb24gYW5kIGl0IGNhbiBiZSBhZGRlZCBvciBzdWJ0cmFjdGVkCisvLyBmcm9tIGEgVGltZXN0YW1wLiBSYW5nZSBpcyBhcHByb3hpbWF0ZWx5ICstMTAsMDAwIHllYXJzLgorLy8KKy8vIEV4YW1wbGUgMTogY29tcHV0ZSBEdXJhdGlvbiBmcm9tIHR3byBUaW1lc3RhbXBzIGluIHBzZXVkbyBjb2RlLgorLy8KKy8vICAgICBUaW1lc3RhbXAgc3RhcnQgPSAuLi47CisvLyAgICAgVGltZXN0YW1wIGVuZCA9IC4uLjsKKy8vICAgICBEdXJhdGlvbiBkdXJhdGlvbiA9IC4uLjsKKy8vCisvLyAgICAgZHVyYXRpb24uc2Vjb25kcyA9IGVuZC5zZWNvbmRzIC0gc3RhcnQuc2Vjb25kczsKKy8vICAgICBkdXJhdGlvbi5uYW5vcyA9IGVuZC5uYW5vcyAtIHN0YXJ0Lm5hbm9zOworLy8KKy8vICAgICBpZiAoZHVyYXRpb24uc2Vjb25kcyA8IDAgJiYgZHVyYXRpb24ubmFub3MgPiAwKSB7CisvLyAgICAgICBkdXJhdGlvbi5zZWNvbmRzICs9IDE7CisvLyAgICAgICBkdXJhdGlvbi5uYW5vcyAtPSAxMDAwMDAwMDAwOworLy8gICAgIH0gZWxzZSBpZiAoZHVyYXRpb25zLnNlY29uZHMgPiAwICYmIGR1cmF0aW9uLm5hbm9zIDwgMCkgeworLy8gICAgICAgZHVyYXRpb24uc2Vjb25kcyAtPSAxOworLy8gICAgICAgZHVyYXRpb24ubmFub3MgKz0gMTAwMDAwMDAwMDsKKy8vICAgICB9CisvLworLy8gRXhhbXBsZSAyOiBjb21wdXRlIFRpbWVzdGFtcCBmcm9tIFRpbWVzdGFtcCArIER1cmF0aW9uIGluIHBzZXVkbyBjb2RlLgorLy8KKy8vICAgICBUaW1lc3RhbXAgc3RhcnQgPSAuLi47CisvLyAgICAgRHVyYXRpb24gZHVyYXRpb24gPSAuLi47CisvLyAgICAgVGltZXN0YW1wIGVuZCA9IC4uLjsKKy8vCisvLyAgICAgZW5kLnNlY29uZHMgPSBzdGFydC5zZWNvbmRzICsgZHVyYXRpb24uc2Vjb25kczsKKy8vICAgICBlbmQubmFub3MgPSBzdGFydC5uYW5vcyArIGR1cmF0aW9uLm5hbm9zOworLy8KKy8vICAgICBpZiAoZW5kLm5hbm9zIDwgMCkgeworLy8gICAgICAgZW5kLnNlY29uZHMgLT0gMTsKKy8vICAgICAgIGVuZC5uYW5vcyArPSAxMDAwMDAwMDAwOworLy8gICAgIH0gZWxzZSBpZiAoZW5kLm5hbm9zID49IDEwMDAwMDAwMDApIHsKKy8vICAgICAgIGVuZC5zZWNvbmRzICs9IDE7CisvLyAgICAgICBlbmQubmFub3MgLT0gMTAwMDAwMDAwMDsKKy8vICAgICB9CisvLworbWVzc2FnZSBEdXJhdGlvbiB7CisgIC8vIFNpZ25lZCBzZWNvbmRzIG9mIHRoZSBzcGFuIG9mIHRpbWUuIE11c3QgYmUgZnJvbSAtMzE1LDU3NiwwMDAsMDAwCisgIC8vIHRvICszMTUsNTc2LDAwMCwwMDAgaW5jbHVzaXZlLgorICBpbnQ2NCBzZWNvbmRzID0gMTsKKworICAvLyBTaWduZWQgZnJhY3Rpb25zIG9mIGEgc2Vjb25kIGF0IG5hbm9zZWNvbmQgcmVzb2x1dGlvbiBvZiB0aGUgc3BhbgorICAvLyBvZiB0aW1lLiBEdXJhdGlvbnMgbGVzcyB0aGFuIG9uZSBzZWNvbmQgYXJlIHJlcHJlc2VudGVkIHdpdGggYSAwCisgIC8vIHNlY29uZHMgZmllbGQgYW5kIGEgcG9zaXRpdmUgb3IgbmVnYXRpdmUgbmFub3MgZmllbGQuIEZvciBkdXJhdGlvbnMKKyAgLy8gb2Ygb25lIHNlY29uZCBvciBtb3JlLCBhIG5vbi16ZXJvIHZhbHVlIGZvciB0aGUgbmFub3MgZmllbGQgbXVzdCBiZQorICAvLyBvZiB0aGUgc2FtZSBzaWduIGFzIHRoZSBzZWNvbmRzIGZpZWxkLiBNdXN0IGJlIGZyb20gLTk5OSw5OTksOTk5CisgIC8vIHRvICs5OTksOTk5LDk5OSBpbmNsdXNpdmUuCisgIGludDMyIG5hbm9zID0gMjsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzE4Y2U2ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmNjCkBAIC0wLDAgKzEsODQ5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gRHluYW1pY01lc3NhZ2UgaXMgaW1wbGVtZW50ZWQgYnkgY29uc3RydWN0aW5nIGEgZGF0YSBzdHJ1Y3R1cmUgd2hpY2gKKy8vIGhhcyByb3VnaGx5IHRoZSBzYW1lIG1lbW9yeSBsYXlvdXQgYXMgYSBnZW5lcmF0ZWQgbWVzc2FnZSB3b3VsZCBoYXZlLgorLy8gVGhlbiwgd2UgdXNlIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uIHRvIGltcGxlbWVudCBvdXIgcmVmbGVjdGlvbgorLy8gaW50ZXJmYWNlLiAgQWxsIHRoZSBvdGhlciBvcGVyYXRpb25zIHdlIG5lZWQgdG8gaW1wbGVtZW50IChlLmcuCisvLyBwYXJzaW5nLCBjb3B5aW5nLCBldGMuKSBhcmUgYWxyZWFkeSBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZgorLy8gUmVmbGVjdGlvbiwgc28gdGhlIHJlc3QgaXMgZWFzeS4KKy8vCisvLyBUaGUgdXAgc2lkZSBvZiB0aGlzIHN0cmF0ZWd5IGlzIHRoYXQgaXQncyB2ZXJ5IGVmZmljaWVudC4gIFdlIGRvbid0CisvLyBuZWVkIHRvIHVzZSBoYXNoX21hcHMgb3IgZ2VuZXJpYyByZXByZXNlbnRhdGlvbnMgb2YgZmllbGRzLiAgVGhlCisvLyBkb3duIHNpZGUgaXMgdGhhdCB0aGlzIGlzIGEgbG93LWxldmVsIG1lbW9yeSBtYW5hZ2VtZW50IGhhY2sgd2hpY2gKKy8vIGNhbiBiZSB0cmlja3kgdG8gZ2V0IHJpZ2h0LgorLy8KKy8vIEFzIG1lbnRpb25lZCBpbiB0aGUgaGVhZGVyLCB3ZSBvbmx5IGV4cG9zZSBhIER5bmFtaWNNZXNzYWdlRmFjdG9yeQorLy8gcHVibGljbHksIG5vdCB0aGUgRHluYW1pY01lc3NhZ2UgY2xhc3MgaXRzZWxmLiAgVGhpcyBpcyBiZWNhdXNlCisvLyBHZW5lcmljTWVzc2FnZVJlZmxlY3Rpb24gd2FudHMgdG8gaGF2ZSBhIHBvaW50ZXIgdG8gYSAiZGVmYXVsdCIKKy8vIGNvcHkgb2YgdGhlIGNsYXNzLCB3aXRoIGFsbCBmaWVsZHMgaW5pdGlhbGl6ZWQgdG8gdGhlaXIgZGVmYXVsdAorLy8gdmFsdWVzLiAgV2Ugb25seSB3YW50IHRvIGNvbnN0cnVjdCBvbmUgb2YgdGhlc2UgcGVyIG1lc3NhZ2UgdHlwZSwKKy8vIHNvIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBzdG9yZXMgYSBjYWNoZSBvZiBkZWZhdWx0IG1lc3NhZ2VzIGZvcgorLy8gZWFjaCB0eXBlIGl0IHNlZXMgKGVhY2ggdW5pcXVlIERlc2NyaXB0b3IgcG9pbnRlcikuICBUaGUgY29kZQorLy8gcmVmZXJzIHRvIHRoZSAiZGVmYXVsdCIgY29weSBvZiB0aGUgY2xhc3MgYXMgdGhlICJwcm90b3R5cGUiLgorLy8KKy8vIE5vdGUgb24gbWVtb3J5IGFsbG9jYXRpb246ICBUaGlzIG1vZHVsZSBvZnRlbiBjYWxscyAib3BlcmF0b3IgbmV3KCkiCisvLyB0byBhbGxvY2F0ZSB1bnR5cGVkIG1lbW9yeSwgcmF0aGVyIHRoYW4gY2FsbGluZyBzb21ldGhpbmcgbGlrZQorLy8gIm5ldyB1aW50OFtdIi4gIFRoaXMgaXMgYmVjYXVzZSAib3BlcmF0b3IgbmV3KCkiIG1lYW5zICJHaXZlIG1lIHNvbWUKKy8vIHNwYWNlIHdoaWNoIEkgY2FuIHVzZSBhcyBJIHBsZWFzZS4iIHdoaWxlICJuZXcgdWludDhbXSIgbWVhbnMgIkdpdmUKKy8vIG1lIGFuIGFycmF5IG9mIDgtYml0IGludGVnZXJzLiIuICBJbiBwcmFjdGljZSwgdGhlIGxhdGVyIG1heSByZXR1cm4KKy8vIGEgcG9pbnRlciB0aGF0IGlzIG5vdCBhbGlnbmVkIGNvcnJlY3RseSBmb3IgZ2VuZXJhbCB1c2UuICBJIGJlbGlldmUKKy8vIEl0ZW0gOCBvZiAiTW9yZSBFZmZlY3RpdmUgQysrIiBkaXNjdXNzZXMgdGhpcyBpbiBtb3JlIGRldGFpbCwgdGhvdWdoCisvLyBJIGRvbid0IGhhdmUgdGhlIGJvb2sgb24gbWUgcmlnaHQgbm93IHNvIEknbSBub3Qgc3VyZS4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXQ7Cit1c2luZyBpbnRlcm5hbDo6RXh0ZW5zaW9uU2V0OwordXNpbmcgaW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOwordXNpbmcgaW50ZXJuYWw6Ok1hcEZpZWxkOwordXNpbmcgaW50ZXJuYWw6Ok1hcEZpZWxkQmFzZTsKKworCit1c2luZyBpbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHI7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFNvbWUgaGVscGVyIHRhYmxlcyBhbmQgZnVuY3Rpb25zLi4uCisKK25hbWVzcGFjZSB7CisKK2Jvb2wgSXNNYXBGaWVsZEluQXBpKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIGZpZWxkLT5pc19tYXAoKTsKK30KKworLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIHRoZSBpbi1tZW1vcnkgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpZWxkLgoraW50IEZpZWxkU3BhY2VVc2VkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCBsaW5lIHdyYXBwaW5nCisgIGlmIChmaWVsZC0+bGFiZWwoKSA9PSBGRDo6TEFCRUxfUkVQRUFURUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0lOVDMyICA6IHJldHVybiBzaXplb2YoUmVwZWF0ZWRGaWVsZDxpbnQzMiAgID4pOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9JTlQ2NCAgOiByZXR1cm4gc2l6ZW9mKFJlcGVhdGVkRmllbGQ8aW50NjQgICA+KTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfVUlOVDMyIDogcmV0dXJuIHNpemVvZihSZXBlYXRlZEZpZWxkPHVpbnQzMiAgPik7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiBzaXplb2YoUmVwZWF0ZWRGaWVsZDx1aW50NjQgID4pOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9ET1VCTEUgOiByZXR1cm4gc2l6ZW9mKFJlcGVhdGVkRmllbGQ8ZG91YmxlICA+KTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfRkxPQVQgIDogcmV0dXJuIHNpemVvZihSZXBlYXRlZEZpZWxkPGZsb2F0ICAgPik7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0JPT0wgICA6IHJldHVybiBzaXplb2YoUmVwZWF0ZWRGaWVsZDxib29sICAgID4pOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9FTlVNICAgOiByZXR1cm4gc2l6ZW9mKFJlcGVhdGVkRmllbGQ8aW50ICAgICA+KTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICByZXR1cm4gc2l6ZW9mKE1hcEZpZWxkQmFzZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIHNpemVvZihSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KTsKKyAgICAgICAgfQorCisgICAgICBjYXNlIEZEOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICAgICAgcmV0dXJuIHNpemVvZihSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4pOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0lOVDMyICA6IHJldHVybiBzaXplb2YoaW50MzIgICApOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9JTlQ2NCAgOiByZXR1cm4gc2l6ZW9mKGludDY0ICAgKTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfVUlOVDMyIDogcmV0dXJuIHNpemVvZih1aW50MzIgICk7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiBzaXplb2YodWludDY0ICApOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9ET1VCTEUgOiByZXR1cm4gc2l6ZW9mKGRvdWJsZSAgKTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfRkxPQVQgIDogcmV0dXJuIHNpemVvZihmbG9hdCAgICk7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0JPT0wgICA6IHJldHVybiBzaXplb2YoYm9vbCAgICApOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9FTlVNICAgOiByZXR1cm4gc2l6ZW9mKGludCAgICAgKTsKKworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gc2l6ZW9mKE1lc3NhZ2UqKTsKKworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIHJldHVybiBzaXplb2YoQXJlbmFTdHJpbmdQdHIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIDA7Cit9CisKKy8vIENvbXB1dGUgdGhlIGJ5dGUgc2l6ZSBvZiBpbi1tZW1vcnkgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9uZW9mIGZpZWxkcworLy8gaW4gZGVmYXVsdCBvbmVvZiBpbnN0YW5jZS4KK2ludCBPbmVvZkZpZWxkU3BhY2VVc2VkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCBsaW5lIHdyYXBwaW5nCisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZEOjpDUFBUWVBFX0lOVDMyICA6IHJldHVybiBzaXplb2YoaW50MzIgICApOworICAgIGNhc2UgRkQ6OkNQUFRZUEVfSU5UNjQgIDogcmV0dXJuIHNpemVvZihpbnQ2NCAgICk7CisgICAgY2FzZSBGRDo6Q1BQVFlQRV9VSU5UMzIgOiByZXR1cm4gc2l6ZW9mKHVpbnQzMiAgKTsKKyAgICBjYXNlIEZEOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiBzaXplb2YodWludDY0ICApOworICAgIGNhc2UgRkQ6OkNQUFRZUEVfRE9VQkxFIDogcmV0dXJuIHNpemVvZihkb3VibGUgICk7CisgICAgY2FzZSBGRDo6Q1BQVFlQRV9GTE9BVCAgOiByZXR1cm4gc2l6ZW9mKGZsb2F0ICAgKTsKKyAgICBjYXNlIEZEOjpDUFBUWVBFX0JPT0wgICA6IHJldHVybiBzaXplb2YoYm9vbCAgICApOworICAgIGNhc2UgRkQ6OkNQUFRZUEVfRU5VTSAgIDogcmV0dXJuIHNpemVvZihpbnQgICAgICk7CisKKyAgICBjYXNlIEZEOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gc2l6ZW9mKE1lc3NhZ2UqKTsKKworICAgIGNhc2UgRkQ6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICByZXR1cm4gc2l6ZW9mKEFyZW5hU3RyaW5nUHRyKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICB9CisKKyAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gMDsKK30KKworaW5saW5lIGludCBEaXZpZGVSb3VuZGluZ1VwKGludCBpLCBpbnQgaikgeworICByZXR1cm4gKGkgKyAoaiAtIDEpKSAvIGo7Cit9CisKK3N0YXRpYyBjb25zdCBpbnQga1NhZmVBbGlnbm1lbnQgPSBzaXplb2YodWludDY0KTsKK3N0YXRpYyBjb25zdCBpbnQga01heE9uZW9mVW5pb25TaXplID0gc2l6ZW9mKHVpbnQ2NCk7CisKK2lubGluZSBpbnQgQWxpZ25UbyhpbnQgb2Zmc2V0LCBpbnQgYWxpZ25tZW50KSB7CisgIHJldHVybiBEaXZpZGVSb3VuZGluZ1VwKG9mZnNldCwgYWxpZ25tZW50KSAqIGFsaWdubWVudDsKK30KKworLy8gUm91bmRzIHRoZSBnaXZlbiBieXRlIG9mZnNldCB1cCB0byB0aGUgbmV4dCBvZmZzZXQgYWxpZ25lZCBzdWNoIHRoYXQgYW55CisvLyB0eXBlIG1heSBiZSBzdG9yZWQgYXQgaXQuCitpbmxpbmUgaW50IEFsaWduT2Zmc2V0KGludCBvZmZzZXQpIHsKKyAgcmV0dXJuIEFsaWduVG8ob2Zmc2V0LCBrU2FmZUFsaWdubWVudCk7Cit9CisKKyNkZWZpbmUgYml0c2l6ZW9mKFQpIChzaXplb2YoVCkgKiA4KQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBEeW5hbWljTWVzc2FnZSA6IHB1YmxpYyBNZXNzYWdlIHsKKyBwdWJsaWM6CisgIHN0cnVjdCBUeXBlSW5mbyB7CisgICAgaW50IHNpemU7CisgICAgaW50IGhhc19iaXRzX29mZnNldDsKKyAgICBpbnQgb25lb2ZfY2FzZV9vZmZzZXQ7CisgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldDsKKyAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQ7CisgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0OworCisgICAgLy8gTm90IG93bmVkIGJ5IHRoZSBUeXBlSW5mby4KKyAgICBEeW5hbWljTWVzc2FnZUZhY3RvcnkqIGZhY3Rvcnk7ICAvLyBUaGUgZmFjdG9yeSB0aGF0IGNyZWF0ZWQgdGhpcyBvYmplY3QuCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2w7ICAgICAgLy8gVGhlIGZhY3RvcnkncyBEZXNjcmlwdG9yUG9vbC4KKyAgICBjb25zdCBEZXNjcmlwdG9yKiB0eXBlOyAgICAgICAgICAvLyBUeXBlIG9mIHRoaXMgRHluYW1pY01lc3NhZ2UuCisKKyAgICAvLyBXYXJuaW5nOiAgVGhlIG9yZGVyIGluIHdoaWNoIHRoZSBmb2xsb3dpbmcgcG9pbnRlcnMgYXJlIGRlZmluZWQgaXMKKyAgICAvLyAgIGltcG9ydGFudCAodGhlIHByb3RvdHlwZSBtdXN0IGJlIGRlbGV0ZWQgKmJlZm9yZSogdGhlIG9mZnNldHMpLgorICAgIHNjb3BlZF9hcnJheTxpbnQ+IG9mZnNldHM7CisgICAgc2NvcGVkX3B0cjxjb25zdCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbj4gcmVmbGVjdGlvbjsKKyAgICAvLyBEb24ndCB1c2UgYSBzY29wZWRfcHRyIHRvIGhvbGQgdGhlIHByb3RvdHlwZTogdGhlIGRlc3RydWN0b3IgZm9yCisgICAgLy8gRHluYW1pY01lc3NhZ2UgbmVlZHMgdG8ga25vdyB3aGV0aGVyIGl0IGlzIHRoZSBwcm90b3R5cGUsIGFuZCBkb2VzIHNvIGJ5CisgICAgLy8gbG9va2luZyBiYWNrIGF0IHRoaXMgZmllbGQuIFRoaXMgd291bGQgYXNzdW1lIGRldGFpbHMgYWJvdXQgdGhlCisgICAgLy8gaW1wbGVtZW50YXRpb24gb2Ygc2NvcGVkX3B0ci4KKyAgICBjb25zdCBEeW5hbWljTWVzc2FnZSogcHJvdG90eXBlOworICAgIHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2U7CisKKyAgICBUeXBlSW5mbygpIDogcHJvdG90eXBlKE5VTEwpLCBkZWZhdWx0X29uZW9mX2luc3RhbmNlKE5VTEwpIHt9CisKKyAgICB+VHlwZUluZm8oKSB7CisgICAgICBkZWxldGUgcHJvdG90eXBlOworICAgICAgb3BlcmF0b3IgZGVsZXRlKGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpOworICAgIH0KKyAgfTsKKworICBEeW5hbWljTWVzc2FnZShjb25zdCBUeXBlSW5mbyogdHlwZV9pbmZvKTsKKyAgfkR5bmFtaWNNZXNzYWdlKCk7CisKKyAgLy8gQ2FsbGVkIG9uIHRoZSBwcm90b3R5cGUgYWZ0ZXIgY29uc3RydWN0aW9uIHRvIGluaXRpYWxpemUgbWVzc2FnZSBmaWVsZHMuCisgIHZvaWQgQ3Jvc3NMaW5rUHJvdG90eXBlcygpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgTWVzc2FnZSogTmV3KCkgY29uc3Q7CisgIE1lc3NhZ2UqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gTlVMTDsgfTsKKworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0OworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworCisgIE1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhEeW5hbWljTWVzc2FnZSk7CisgIER5bmFtaWNNZXNzYWdlKGNvbnN0IFR5cGVJbmZvKiB0eXBlX2luZm8sIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisKKyAgaW5saW5lIGJvb2wgaXNfcHJvdG90eXBlKCkgY29uc3QgeworICAgIHJldHVybiB0eXBlX2luZm9fLT5wcm90b3R5cGUgPT0gdGhpcyB8fAorICAgICAgICAgICAvLyBJZiB0eXBlX2luZm9fLT5wcm90b3R5cGUgaXMgTlVMTCwgdGhlbiB3ZSBtdXN0IGJlIGNvbnN0cnVjdGluZworICAgICAgICAgICAvLyB0aGUgcHJvdG90eXBlIG5vdywgd2hpY2ggbWVhbnMgd2UgbXVzdCBiZSB0aGUgcHJvdG90eXBlLgorICAgICAgICAgICB0eXBlX2luZm9fLT5wcm90b3R5cGUgPT0gTlVMTDsKKyAgfQorCisgIGlubGluZSB2b2lkKiBPZmZzZXRUb1BvaW50ZXIoaW50IG9mZnNldCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4odGhpcykgKyBvZmZzZXQ7CisgIH0KKyAgaW5saW5lIGNvbnN0IHZvaWQqIE9mZnNldFRvUG9pbnRlcihpbnQgb2Zmc2V0KSBjb25zdCB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPih0aGlzKSArIG9mZnNldDsKKyAgfQorCisgIGNvbnN0IFR5cGVJbmZvKiB0eXBlX2luZm9fOworICAvLyBUT0RPKGtlbnRvbik6ICBNYWtlIHRoaXMgYW4gYXRvbWljPGludD4gd2hlbiBDKysgc3VwcG9ydHMgaXQuCisgIG11dGFibGUgaW50IGNhY2hlZF9ieXRlX3NpemVfOworfTsKKworRHluYW1pY01lc3NhZ2U6OkR5bmFtaWNNZXNzYWdlKGNvbnN0IFR5cGVJbmZvKiB0eXBlX2luZm8pCisgIDogdHlwZV9pbmZvXyh0eXBlX2luZm8pLAorICAgIGNhY2hlZF9ieXRlX3NpemVfKDApIHsKKyAgU2hhcmVkQ3RvcigpOworfQorCitEeW5hbWljTWVzc2FnZTo6RHluYW1pY01lc3NhZ2UoY29uc3QgVHlwZUluZm8qIHR5cGVfaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkKKyAgOiB0eXBlX2luZm9fKHR5cGVfaW5mbyksCisgICAgY2FjaGVkX2J5dGVfc2l6ZV8oMCkgeworICBTaGFyZWRDdG9yKCk7Cit9CisKK3ZvaWQgRHluYW1pY01lc3NhZ2U6OlNoYXJlZEN0b3IoKSB7CisgIC8vIFdlIG5lZWQgdG8gY2FsbCBjb25zdHJ1Y3RvcnMgZm9yIHZhcmlvdXMgZmllbGRzIG1hbnVhbGx5IGFuZCBzZXQKKyAgLy8gZGVmYXVsdCB2YWx1ZXMgd2hlcmUgYXBwcm9wcmlhdGUuICBXZSB1c2UgcGxhY2VtZW50IG5ldyB0byBjYWxsCisgIC8vIGNvbnN0cnVjdG9ycy4gIElmIHlvdSBoYXZlbid0IGhlYXJkIG9mIHBsYWNlbWVudCBuZXcsIEkgc3VnZ2VzdCBHb29nbGluZworICAvLyBpdCBub3cuICBXZSB1c2UgcGxhY2VtZW50IG5ldyBldmVuIGZvciBwcmltaXRpdmUgdHlwZXMgdGhhdCBkb24ndCBoYXZlCisgIC8vIGNvbnN0cnVjdG9ycyBmb3IgY29uc2lzdGVuY3kuICAoSW4gdGhlb3J5LCBwbGFjZW1lbnQgbmV3IHNob3VsZCBiZSB1c2VkCisgIC8vIGFueSB0aW1lIHlvdSBhcmUgdHJ5aW5nIHRvIGNvbnZlcnQgdW50eXBlZCBtZW1vcnkgdG8gdHlwZWQgbWVtb3J5LCB0aG91Z2gKKyAgLy8gaW4gcHJhY3RpY2UgdGhhdCdzIG5vdCBzdHJpY3RseSBuZWNlc3NhcnkgZm9yIHR5cGVzIHRoYXQgZG9uJ3QgaGF2ZSBhCisgIC8vIGNvbnN0cnVjdG9yLikKKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gdHlwZV9pbmZvXy0+dHlwZTsKKworICAvLyBJbml0aWFsaXplIG9uZW9mIGNhc2VzLgorICBmb3IgKGludCBpID0gMCA7IGkgPCBkZXNjcmlwdG9yLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIG5ldyhPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+b25lb2ZfY2FzZV9vZmZzZXQgKyBzaXplb2YodWludDMyKSAqIGkpKQorICAgICAgICB1aW50MzIoMCk7CisgIH0KKworICBpZiAodHlwZV9pbmZvXy0+aXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQgIT0gLTEpIHsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDxib29sKj4oCisgICAgICAgIE9mZnNldFRvUG9pbnRlcih0eXBlX2luZm9fLT5pc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkpID0gZmFsc2U7CisgIH0KKworICBuZXcoT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPnVua25vd25fZmllbGRzX29mZnNldCkpIFVua25vd25GaWVsZFNldDsKKworICBpZiAodHlwZV9pbmZvXy0+ZXh0ZW5zaW9uc19vZmZzZXQgIT0gLTEpIHsKKyAgICBuZXcoT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPmV4dGVuc2lvbnNfb2Zmc2V0KSkgRXh0ZW5zaW9uU2V0OworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgICAgdm9pZCogZmllbGRfcHRyID0gT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPm9mZnNldHNbaV0pOworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIFRZUEUoZmllbGQtPmRlZmF1bHRfdmFsdWVfIyNUWVBFKCkpOyAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBSZXBlYXRlZEZpZWxkPFRZUEU+KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOworCisgICAgICBIQU5ETEVfVFlQRShJTlQzMiAsIGludDMyICk7CisgICAgICBIQU5ETEVfVFlQRShJTlQ2NCAsIGludDY0ICk7CisgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRShGTE9BVCAsIGZsb2F0ICk7CisgICAgICBIQU5ETEVfVFlQRShCT09MICAsIGJvb2wgICk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIGludChmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBSZXBlYXRlZEZpZWxkPGludD4oKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF92YWx1ZTsKKyAgICAgICAgICAgICAgaWYgKGlzX3Byb3RvdHlwZSgpKSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdF92YWx1ZSA9ICZmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKTsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0X3ZhbHVlID0KKyAgICAgICAgICAgICAgICAgICYocmVpbnRlcnByZXRfY2FzdDxjb25zdCBBcmVuYVN0cmluZ1B0cio+KAorICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm9fLT5wcm90b3R5cGUtPk9mZnNldFRvUG9pbnRlcigKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm9fLT5vZmZzZXRzW2ldKSktPkdldChOVUxMKSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgQXJlbmFTdHJpbmdQdHIqIGFzcCA9IG5ldyhmaWVsZF9wdHIpIEFyZW5hU3RyaW5nUHRyKCk7CisgICAgICAgICAgICAgIGFzcC0+VW5zYWZlU2V0RGVmYXVsdChkZWZhdWx0X3ZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIE1lc3NhZ2UqKE5VTEwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgICBuZXcgKGZpZWxkX3B0cikgTWFwRmllbGRCYXNlKCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG5ldyAoZmllbGRfcHRyKSBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitEeW5hbWljTWVzc2FnZTo6fkR5bmFtaWNNZXNzYWdlKCkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gdHlwZV9pbmZvXy0+dHlwZTsKKworICByZWludGVycHJldF9jYXN0PFVua25vd25GaWVsZFNldCo+KAorICAgIE9mZnNldFRvUG9pbnRlcih0eXBlX2luZm9fLT51bmtub3duX2ZpZWxkc19vZmZzZXQpKS0+flVua25vd25GaWVsZFNldCgpOworCisgIGlmICh0eXBlX2luZm9fLT5leHRlbnNpb25zX29mZnNldCAhPSAtMSkgeworICAgIHJlaW50ZXJwcmV0X2Nhc3Q8RXh0ZW5zaW9uU2V0Kj4oCisgICAgICBPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+ZXh0ZW5zaW9uc19vZmZzZXQpKS0+fkV4dGVuc2lvblNldCgpOworICB9CisKKyAgLy8gV2UgbmVlZCB0byBtYW51YWxseSBydW4gdGhlIGRlc3RydWN0b3JzIGZvciByZXBlYXRlZCBmaWVsZHMgYW5kIHN0cmluZ3MsCisgIC8vIGp1c3QgYXMgd2UgcmFuIHRoZWlyIGNvbnN0cnVjdG9ycyBpbiB0aGUgdGhlIER5bmFtaWNNZXNzYWdlIGNvbnN0cnVjdG9yLgorICAvLyBXZSBhbHNvIG5lZWQgdG8gbWFudWFsbHkgZGVsZXRlIG9uZW9mIGZpZWxkcyBpZiBpdCBpcyBzZXQgYW5kIGlzIHN0cmluZworICAvLyBvciBtZXNzYWdlLgorICAvLyBBZGRpdGlvbmFsbHksIGlmIGFueSBzaW5ndWxhciBlbWJlZGRlZCBtZXNzYWdlcyBoYXZlIGJlZW4gYWxsb2NhdGVkLCB3ZQorICAvLyBuZWVkIHRvIGRlbGV0ZSB0aGVtLCBVTkxFU1Mgd2UgYXJlIHRoZSBwcm90b3R5cGUgbWVzc2FnZSBvZiB0aGlzIHR5cGUsCisgIC8vIGluIHdoaWNoIGNhc2UgYW55IGVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBvdGhlciBwcm90b3R5cGVzIGFuZCBzaG91bGRuJ3QKKyAgLy8gYmUgdG91Y2hlZC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIHZvaWQqIGZpZWxkX3B0ciA9IE9mZnNldFRvUG9pbnRlcigKKyAgICAgICAgICB0eXBlX2luZm9fLT5vbmVvZl9jYXNlX29mZnNldAorICAgICAgICAgICsgc2l6ZW9mKHVpbnQzMikgKiBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpKTsKKyAgICAgIGlmICgqKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyKj4oZmllbGRfcHRyKSkgPT0KKyAgICAgICAgICBmaWVsZC0+bnVtYmVyKCkpIHsKKyAgICAgICAgZmllbGRfcHRyID0gT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPm9mZnNldHNbCisgICAgICAgICAgICBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpICsgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKV0pOworICAgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORykgeworICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzogeworICAgICAgICAgICAgICBjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlID0KKyAgICAgICAgICAgICAgICAgICYocmVpbnRlcnByZXRfY2FzdDxjb25zdCBBcmVuYVN0cmluZ1B0cio+KAorICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5mb18tPnByb3RvdHlwZS0+T2Zmc2V0VG9Qb2ludGVyKAorICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm9fLT5vZmZzZXRzW2ldKSktPkdldChOVUxMKSk7CisgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8QXJlbmFTdHJpbmdQdHIqPihmaWVsZF9wdHIpLT5EZXN0cm95KGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgICAgICAgIGRlbGV0ZSAqcmVpbnRlcnByZXRfY2FzdDxNZXNzYWdlKio+KGZpZWxkX3B0cik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICB2b2lkKiBmaWVsZF9wdHIgPSBPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+b2Zmc2V0c1tpXSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0UgOiAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGQ8TE9XRVJDQVNFPio+KGZpZWxkX3B0cikgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgLT5+UmVwZWF0ZWRGaWVsZDxMT1dFUkNBU0U+KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggRkxPQVQsICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgICBpbnQpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Kj4oZmllbGRfcHRyKQorICAgICAgICAgICAgICAgICAgLT5+UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KCk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgICByZWludGVycHJldF9jYXN0PE1hcEZpZWxkQmFzZSo+KGZpZWxkX3B0ciktPn5NYXBGaWVsZEJhc2UoKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+Kj4oZmllbGRfcHRyKQorICAgICAgICAgICAgICAgIC0+flJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOiB7CisgICAgICAgICAgY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSA9CisgICAgICAgICAgICAgICYocmVpbnRlcnByZXRfY2FzdDxjb25zdCBBcmVuYVN0cmluZ1B0cio+KAorICAgICAgICAgICAgICAgICAgdHlwZV9pbmZvXy0+cHJvdG90eXBlLT5PZmZzZXRUb1BvaW50ZXIoCisgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmZvXy0+b2Zmc2V0c1tpXSkpLT5HZXQoTlVMTCkpOworICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8QXJlbmFTdHJpbmdQdHIqPihmaWVsZF9wdHIpLT5EZXN0cm95KGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBpZiAoIWlzX3Byb3RvdHlwZSgpKSB7CisgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UgPSAqcmVpbnRlcnByZXRfY2FzdDxNZXNzYWdlKio+KGZpZWxkX3B0cik7CisgICAgICAgIGlmIChtZXNzYWdlICE9IE5VTEwpIHsKKyAgICAgICAgICBkZWxldGUgbWVzc2FnZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIER5bmFtaWNNZXNzYWdlOjpDcm9zc0xpbmtQcm90b3R5cGVzKCkgeworICAvLyBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiB0aGUgcHJvdG90eXBlIG1lc3NhZ2UuCisgIEdPT0dMRV9DSEVDSyhpc19wcm90b3R5cGUoKSk7CisKKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5ID0gdHlwZV9pbmZvXy0+ZmFjdG9yeTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHR5cGVfaW5mb18tPnR5cGU7CisKKyAgLy8gQ3Jvc3MtbGluayBkZWZhdWx0IG1lc3NhZ2VzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yLT5maWVsZChpKTsKKyAgICB2b2lkKiBmaWVsZF9wdHIgPSBPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+b2Zmc2V0c1tpXSk7CisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkX3B0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPigKKyAgICAgICAgICB0eXBlX2luZm9fLT5kZWZhdWx0X29uZW9mX2luc3RhbmNlKSArIHR5cGVfaW5mb18tPm9mZnNldHNbaV07CisgICAgfQorCisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFICYmCisgICAgICAgICFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgLy8gRm9yIGZpZWxkcyB3aXRoIG1lc3NhZ2UgdHlwZXMsIHdlIG5lZWQgdG8gY3Jvc3MtbGluayB3aXRoIHRoZQorICAgICAgLy8gcHJvdG90eXBlIGZvciB0aGUgZmllbGQncyB0eXBlLgorICAgICAgLy8gRm9yIHNpbmd1bGFyIGZpZWxkcywgdGhlIGZpZWxkIGlzIGp1c3QgYSBwb2ludGVyIHdoaWNoIHNob3VsZAorICAgICAgLy8gcG9pbnQgdG8gdGhlIHByb3RvdHlwZS4KKyAgICAgICpyZWludGVycHJldF9jYXN0PGNvbnN0IE1lc3NhZ2UqKj4oZmllbGRfcHRyKSA9CisgICAgICAgIGZhY3RvcnktPkdldFByb3RvdHlwZU5vTG9jayhmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICAgIH0KKyAgfQorCisgIC8vIFNldCBhcyB0aGUgZGVmYXVsdCBpbnN0YW5jZSAtLSB0aGlzIGFmZmVjdHMgZmllbGQtcHJlc2VuY2Ugc2VtYW50aWNzIGZvcgorICAvLyBwcm90bzMuCisgIGlmICh0eXBlX2luZm9fLT5pc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCAhPSAtMSkgeworICAgIHZvaWQqIGlzX2RlZmF1bHRfaW5zdGFuY2VfcHRyID0KKyAgICAgICAgT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPmlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KTsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDxib29sKj4oaXNfZGVmYXVsdF9pbnN0YW5jZV9wdHIpID0gdHJ1ZTsKKyAgfQorfQorCitNZXNzYWdlKiBEeW5hbWljTWVzc2FnZTo6TmV3KCkgY29uc3QgeworICB2b2lkKiBuZXdfYmFzZSA9IG9wZXJhdG9yIG5ldyh0eXBlX2luZm9fLT5zaXplKTsKKyAgbWVtc2V0KG5ld19iYXNlLCAwLCB0eXBlX2luZm9fLT5zaXplKTsKKyAgcmV0dXJuIG5ldyhuZXdfYmFzZSkgRHluYW1pY01lc3NhZ2UodHlwZV9pbmZvXyk7Cit9CisKK01lc3NhZ2UqIER5bmFtaWNNZXNzYWdlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBNZXNzYWdlKiBtZXNzYWdlID0gTmV3KCk7CisgICAgYXJlbmEtPk93bihtZXNzYWdlKTsKKyAgICByZXR1cm4gbWVzc2FnZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTmV3KCk7CisgIH0KK30KKworaW50IER5bmFtaWNNZXNzYWdlOjpHZXRDYWNoZWRTaXplKCkgY29uc3QgeworICByZXR1cm4gY2FjaGVkX2J5dGVfc2l6ZV87Cit9CisKK3ZvaWQgRHluYW1pY01lc3NhZ2U6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgLy8gVGhpcyBpcyB0aGVvcmV0aWNhbGx5IG5vdCB0aHJlYWQtY29tcGF0aWJsZSwgYnV0IGluIHByYWN0aWNlIGl0IHdvcmtzCisgIC8vIGJlY2F1c2UgaWYgbXVsdGlwbGUgdGhyZWFkcyB3cml0ZSB0aGlzIHNpbXVsdGFuZW91c2x5LCB0aGV5IHdpbGwgYmUKKyAgLy8gd3JpdGluZyB0aGUgZXhhY3Qgc2FtZSB2YWx1ZS4KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgY2FjaGVkX2J5dGVfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KKworTWV0YWRhdGEgRHluYW1pY01lc3NhZ2U6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IHR5cGVfaW5mb18tPnR5cGU7CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSB0eXBlX2luZm9fLT5yZWZsZWN0aW9uLmdldCgpOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworc3RydWN0IER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6UHJvdG90eXBlTWFwIHsKKyAgdHlwZWRlZiBoYXNoX21hcDxjb25zdCBEZXNjcmlwdG9yKiwgY29uc3QgRHluYW1pY01lc3NhZ2U6OlR5cGVJbmZvKj4gTWFwOworICBNYXAgbWFwXzsKK307CisKK0R5bmFtaWNNZXNzYWdlRmFjdG9yeTo6RHluYW1pY01lc3NhZ2VGYWN0b3J5KCkKKyAgOiBwb29sXyhOVUxMKSwgZGVsZWdhdGVfdG9fZ2VuZXJhdGVkX2ZhY3RvcnlfKGZhbHNlKSwKKyAgICBwcm90b3R5cGVzXyhuZXcgUHJvdG90eXBlTWFwKSB7Cit9CisKK0R5bmFtaWNNZXNzYWdlRmFjdG9yeTo6RHluYW1pY01lc3NhZ2VGYWN0b3J5KGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKQorICA6IHBvb2xfKHBvb2wpLCBkZWxlZ2F0ZV90b19nZW5lcmF0ZWRfZmFjdG9yeV8oZmFsc2UpLAorICAgIHByb3RvdHlwZXNfKG5ldyBQcm90b3R5cGVNYXApIHsKK30KKworRHluYW1pY01lc3NhZ2VGYWN0b3J5Ojp+RHluYW1pY01lc3NhZ2VGYWN0b3J5KCkgeworICBmb3IgKFByb3RvdHlwZU1hcDo6TWFwOjppdGVyYXRvciBpdGVyID0gcHJvdG90eXBlc18tPm1hcF8uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IHByb3RvdHlwZXNfLT5tYXBfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBEZWxldGVEZWZhdWx0T25lb2ZJbnN0YW5jZShpdGVyLT5zZWNvbmQtPnR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlci0+c2Vjb25kLT5vZmZzZXRzLmdldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXItPnNlY29uZC0+ZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSk7CisgICAgZGVsZXRlIGl0ZXItPnNlY29uZDsKKyAgfQorfQorCitjb25zdCBNZXNzYWdlKiBEeW5hbWljTWVzc2FnZUZhY3Rvcnk6OkdldFByb3RvdHlwZShjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSB7CisgIE11dGV4TG9jayBsb2NrKCZwcm90b3R5cGVzX211dGV4Xyk7CisgIHJldHVybiBHZXRQcm90b3R5cGVOb0xvY2sodHlwZSk7Cit9CisKK2NvbnN0IE1lc3NhZ2UqIER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6R2V0UHJvdG90eXBlTm9Mb2NrKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUpIHsKKyAgaWYgKGRlbGVnYXRlX3RvX2dlbmVyYXRlZF9mYWN0b3J5XyAmJgorICAgICAgdHlwZS0+ZmlsZSgpLT5wb29sKCkgPT0gRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkpIHsKKyAgICByZXR1cm4gTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZSh0eXBlKTsKKyAgfQorCisgIGNvbnN0IER5bmFtaWNNZXNzYWdlOjpUeXBlSW5mbyoqIHRhcmdldCA9ICZwcm90b3R5cGVzXy0+bWFwX1t0eXBlXTsKKyAgaWYgKCp0YXJnZXQgIT0gTlVMTCkgeworICAgIC8vIEFscmVhZHkgZXhpc3RzLgorICAgIHJldHVybiAoKnRhcmdldCktPnByb3RvdHlwZTsKKyAgfQorCisgIER5bmFtaWNNZXNzYWdlOjpUeXBlSW5mbyogdHlwZV9pbmZvID0gbmV3IER5bmFtaWNNZXNzYWdlOjpUeXBlSW5mbzsKKyAgKnRhcmdldCA9IHR5cGVfaW5mbzsKKworICB0eXBlX2luZm8tPnR5cGUgPSB0eXBlOworICB0eXBlX2luZm8tPnBvb2wgPSAocG9vbF8gPT0gTlVMTCkgPyB0eXBlLT5maWxlKCktPnBvb2woKSA6IHBvb2xfOworICB0eXBlX2luZm8tPmZhY3RvcnkgPSB0aGlzOworCisgIC8vIFdlIG5lZWQgdG8gY29uc3RydWN0IGFsbCB0aGUgc3RydWN0dXJlcyBwYXNzZWQgdG8KKyAgLy8gR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24ncyBjb25zdHJ1Y3Rvci4gIFRoaXMgaW5jbHVkZXM6CisgIC8vIC0gQSBibG9jayBvZiBtZW1vcnkgdGhhdCBjb250YWlucyBzcGFjZSBmb3IgYWxsIHRoZSBtZXNzYWdlJ3MgZmllbGRzLgorICAvLyAtIEFuIGFycmF5IG9mIGludGVnZXJzIGluZGljYXRpbmcgdGhlIGJ5dGUgb2Zmc2V0IG9mIGVhY2ggZmllbGQgd2l0aGluCisgIC8vICAgdGhpcyBibG9jay4KKyAgLy8gLSBBIGJpZyBiaXRmaWVsZCBjb250YWluaW5nIGEgYml0IGZvciBlYWNoIGZpZWxkIGluZGljYXRpbmcgd2hldGhlcgorICAvLyAgIG9yIG5vdCB0aGF0IGZpZWxkIGlzIHNldC4KKworICAvLyBDb21wdXRlIHNpemUgYW5kIG9mZnNldHMuCisgIGludCogb2Zmc2V0cyA9IG5ldyBpbnRbdHlwZS0+ZmllbGRfY291bnQoKSArIHR5cGUtPm9uZW9mX2RlY2xfY291bnQoKV07CisgIHR5cGVfaW5mby0+b2Zmc2V0cy5yZXNldChvZmZzZXRzKTsKKworICAvLyBEZWNpZGUgYWxsIGZpZWxkIG9mZnNldHMgYnkgcGFja2luZyBpbiBvcmRlci4KKyAgLy8gV2UgcGxhY2UgdGhlIER5bmFtaWNNZXNzYWdlIG9iamVjdCBpdHNlbGYgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYWxsb2NhdGVkCisgIC8vIHNwYWNlLgorICBpbnQgc2l6ZSA9IHNpemVvZihEeW5hbWljTWVzc2FnZSk7CisgIHNpemUgPSBBbGlnbk9mZnNldChzaXplKTsKKworICAvLyBOZXh0IHRoZSBoYXNfYml0cywgd2hpY2ggaXMgYW4gYXJyYXkgb2YgdWludDMycy4KKyAgaWYgKHR5cGUtPmZpbGUoKS0+c3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzMpIHsKKyAgICB0eXBlX2luZm8tPmhhc19iaXRzX29mZnNldCA9IC0xOworICB9IGVsc2UgeworICAgIHR5cGVfaW5mby0+aGFzX2JpdHNfb2Zmc2V0ID0gc2l6ZTsKKyAgICBpbnQgaGFzX2JpdHNfYXJyYXlfc2l6ZSA9CisgICAgICBEaXZpZGVSb3VuZGluZ1VwKHR5cGUtPmZpZWxkX2NvdW50KCksIGJpdHNpemVvZih1aW50MzIpKTsKKyAgICBzaXplICs9IGhhc19iaXRzX2FycmF5X3NpemUgKiBzaXplb2YodWludDMyKTsKKyAgICBzaXplID0gQWxpZ25PZmZzZXQoc2l6ZSk7CisgIH0KKworICAvLyBUaGUgaXNfZGVmYXVsdF9pbnN0YW5jZSBtZW1iZXIsIGlmIGFueS4KKyAgaWYgKHR5cGUtPmZpbGUoKS0+c3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzMpIHsKKyAgICB0eXBlX2luZm8tPmlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ID0gc2l6ZTsKKyAgICBzaXplICs9IHNpemVvZihib29sKTsKKyAgICBzaXplID0gQWxpZ25PZmZzZXQoc2l6ZSk7CisgIH0gZWxzZSB7CisgICAgdHlwZV9pbmZvLT5pc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCA9IC0xOworICB9CisKKyAgLy8gVGhlIG9uZW9mX2Nhc2UsIGlmIGFueS4gSXQgaXMgYW4gYXJyYXkgb2YgdWludDMycy4KKyAgaWYgKHR5cGUtPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICB0eXBlX2luZm8tPm9uZW9mX2Nhc2Vfb2Zmc2V0ID0gc2l6ZTsKKyAgICBzaXplICs9IHR5cGUtPm9uZW9mX2RlY2xfY291bnQoKSAqIHNpemVvZih1aW50MzIpOworICAgIHNpemUgPSBBbGlnbk9mZnNldChzaXplKTsKKyAgfQorCisgIC8vIFRoZSBFeHRlbnNpb25TZXQsIGlmIGFueS4KKyAgaWYgKHR5cGUtPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHR5cGVfaW5mby0+ZXh0ZW5zaW9uc19vZmZzZXQgPSBzaXplOworICAgIHNpemUgKz0gc2l6ZW9mKEV4dGVuc2lvblNldCk7CisgICAgc2l6ZSA9IEFsaWduT2Zmc2V0KHNpemUpOworICB9IGVsc2UgeworICAgIC8vIE5vIGV4dGVuc2lvbnMuCisgICAgdHlwZV9pbmZvLT5leHRlbnNpb25zX29mZnNldCA9IC0xOworICB9CisKKyAgLy8gQWxsIHRoZSBmaWVsZHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZS0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgLy8gTWFrZSBzdXJlIGZpZWxkIGlzIGFsaWduZWQgdG8gYXZvaWQgYnVzIGVycm9ycy4KKyAgICAvLyBPbmVvZiBmaWVsZHMgZG8gbm90IHVzZSBhbnkgc3BhY2UuCisgICAgaWYgKCF0eXBlLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBpbnQgZmllbGRfc2l6ZSA9IEZpZWxkU3BhY2VVc2VkKHR5cGUtPmZpZWxkKGkpKTsKKyAgICAgIHNpemUgPSBBbGlnblRvKHNpemUsIG1pbihrU2FmZUFsaWdubWVudCwgZmllbGRfc2l6ZSkpOworICAgICAgb2Zmc2V0c1tpXSA9IHNpemU7CisgICAgICBzaXplICs9IGZpZWxkX3NpemU7CisgICAgfQorICB9CisKKyAgLy8gVGhlIG9uZW9mcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHNpemUgPSBBbGlnblRvKHNpemUsIGtTYWZlQWxpZ25tZW50KTsKKyAgICBvZmZzZXRzW3R5cGUtPmZpZWxkX2NvdW50KCkgKyBpXSA9IHNpemU7CisgICAgc2l6ZSArPSBrTWF4T25lb2ZVbmlvblNpemU7CisgIH0KKworICAvLyBBZGQgdGhlIFVua25vd25GaWVsZFNldCB0byB0aGUgZW5kLgorICBzaXplID0gQWxpZ25PZmZzZXQoc2l6ZSk7CisgIHR5cGVfaW5mby0+dW5rbm93bl9maWVsZHNfb2Zmc2V0ID0gc2l6ZTsKKyAgc2l6ZSArPSBzaXplb2YoVW5rbm93bkZpZWxkU2V0KTsKKworICAvLyBBbGlnbiB0aGUgZmluYWwgc2l6ZSB0byBtYWtlIHN1cmUgbm8gY2xldmVyIGFsbG9jYXRvcnMgdGhpbmsgdGhhdAorICAvLyBhbGlnbm1lbnQgaXMgbm90IG5lY2Vzc2FyeS4KKyAgc2l6ZSA9IEFsaWduT2Zmc2V0KHNpemUpOworICB0eXBlX2luZm8tPnNpemUgPSBzaXplOworCisgIC8vIEFsbG9jYXRlIHRoZSBwcm90b3R5cGUuCisgIHZvaWQqIGJhc2UgPSBvcGVyYXRvciBuZXcoc2l6ZSk7CisgIG1lbXNldChiYXNlLCAwLCBzaXplKTsKKyAgRHluYW1pY01lc3NhZ2UqIHByb3RvdHlwZSA9IG5ldyhiYXNlKSBEeW5hbWljTWVzc2FnZSh0eXBlX2luZm8pOworICB0eXBlX2luZm8tPnByb3RvdHlwZSA9IHByb3RvdHlwZTsKKworICAvLyBDb25zdHJ1Y3QgdGhlIHJlZmxlY3Rpb24gb2JqZWN0LgorICBpZiAodHlwZS0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgeworICAgIC8vIENvbXB1dGUgdGhlIHNpemUgb2YgZGVmYXVsdCBvbmVvZiBpbnN0YW5jZSBhbmQgb2Zmc2V0cyBvZiBkZWZhdWx0CisgICAgLy8gb25lb2YgZmllbGRzLgorICAgIGludCBvbmVvZl9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHR5cGUtPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICAgIGludCBmaWVsZF9zaXplID0gT25lb2ZGaWVsZFNwYWNlVXNlZChmaWVsZCk7CisgICAgICAgIG9uZW9mX3NpemUgPSBBbGlnblRvKG9uZW9mX3NpemUsIG1pbihrU2FmZUFsaWdubWVudCwgZmllbGRfc2l6ZSkpOworICAgICAgICBvZmZzZXRzW2ZpZWxkLT5pbmRleCgpXSA9IG9uZW9mX3NpemU7CisgICAgICAgIG9uZW9mX3NpemUgKz0gZmllbGRfc2l6ZTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gQ29uc3RydWN0IGRlZmF1bHQgb25lb2YgaW5zdGFuY2UuCisgICAgdHlwZV9pbmZvLT5kZWZhdWx0X29uZW9mX2luc3RhbmNlID0gOjpvcGVyYXRvciBuZXcob25lb2Zfc2l6ZSk7CisgICAgQ29uc3RydWN0RGVmYXVsdE9uZW9mSW5zdGFuY2UodHlwZV9pbmZvLT50eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5mby0+b2Zmc2V0cy5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm8tPmRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpOworICAgIHR5cGVfaW5mby0+cmVmbGVjdGlvbi5yZXNldCgKKyAgICAgICAgbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgICAgICAgdHlwZV9pbmZvLT50eXBlLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5wcm90b3R5cGUsCisgICAgICAgICAgICB0eXBlX2luZm8tPm9mZnNldHMuZ2V0KCksCisgICAgICAgICAgICB0eXBlX2luZm8tPmhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+dW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgICAgICAgICAgdHlwZV9pbmZvLT5leHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+ZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+b25lb2ZfY2FzZV9vZmZzZXQsCisgICAgICAgICAgICB0eXBlX2luZm8tPnBvb2wsCisgICAgICAgICAgICB0aGlzLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5zaXplLAorICAgICAgICAgICAgLTEgLyogYXJlbmFfb2Zmc2V0ICovLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5pc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkpOworICB9IGVsc2UgeworICAgIHR5cGVfaW5mby0+cmVmbGVjdGlvbi5yZXNldCgKKyAgICAgICAgbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgICAgICAgdHlwZV9pbmZvLT50eXBlLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5wcm90b3R5cGUsCisgICAgICAgICAgICB0eXBlX2luZm8tPm9mZnNldHMuZ2V0KCksCisgICAgICAgICAgICB0eXBlX2luZm8tPmhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+dW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgICAgICAgICAgdHlwZV9pbmZvLT5leHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+cG9vbCwKKyAgICAgICAgICAgIHRoaXMsCisgICAgICAgICAgICB0eXBlX2luZm8tPnNpemUsCisgICAgICAgICAgICAtMSAvKiBhcmVuYV9vZmZzZXQgKi8sCisgICAgICAgICAgICB0eXBlX2luZm8tPmlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KSk7CisgIH0KKyAgLy8gQ3Jvc3MgbGluayBwcm90b3R5cGVzLgorICBwcm90b3R5cGUtPkNyb3NzTGlua1Byb3RvdHlwZXMoKTsKKworICByZXR1cm4gcHJvdG90eXBlOworfQorCit2b2lkIER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6Q29uc3RydWN0RGVmYXVsdE9uZW9mSW5zdGFuY2UoCisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgIHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICB2b2lkKiBmaWVsZF9wdHIgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oCisgICAgICAgICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSkgKyBvZmZzZXRzW2ZpZWxkLT5pbmRleCgpXTsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoQ1BQVFlQRSwgVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBUWVBFKGZpZWxkLT5kZWZhdWx0X3ZhbHVlXyMjVFlQRSgpKTsgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBIQU5ETEVfVFlQRShJTlQzMiAsIGludDMyICk7CisgICAgICAgIEhBTkRMRV9UWVBFKElOVDY0ICwgaW50NjQgKTsKKyAgICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgICAgSEFORExFX1RZUEUoRkxPQVQgLCBmbG9hdCApOworICAgICAgICBIQU5ETEVfVFlQRShCT09MICAsIGJvb2wgICk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIGludChmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgICAgQXJlbmFTdHJpbmdQdHIqIGFzcCA9IG5ldyAoZmllbGRfcHRyKSBBcmVuYVN0cmluZ1B0cigpOworICAgICAgICAgICAgICBhc3AtPlVuc2FmZVNldERlZmF1bHQoJmZpZWxkLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBNZXNzYWdlKihOVUxMKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6RGVsZXRlRGVmYXVsdE9uZW9mSW5zdGFuY2UoCisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgIHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORykgeworICAgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjU5MjhhNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmgKQEAgLTAsMCArMSwxNTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBEZWZpbmVzIGFuIGltcGxlbWVudGF0aW9uIG9mIE1lc3NhZ2Ugd2hpY2ggY2FuIGVtdWxhdGUgdHlwZXMgd2hpY2ggYXJlIG5vdAorLy8ga25vd24gYXQgY29tcGlsZS10aW1lLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9EWU5BTUlDX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9EWU5BTUlDX01FU1NBR0VfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBEZWZpbmVkIGluIG90aGVyIGZpbGVzLgorY2xhc3MgRGVzY3JpcHRvcjsgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorY2xhc3MgRGVzY3JpcHRvclBvb2w7ICAgIC8vIGRlc2NyaXB0b3IuaAorCisvLyBDb25zdHJ1Y3RzIGltcGxlbWVudGF0aW9ucyBvZiBNZXNzYWdlIHdoaWNoIGNhbiBlbXVsYXRlIHR5cGVzIHdoaWNoIGFyZSBub3QKKy8vIGtub3duIGF0IGNvbXBpbGUtdGltZS4KKy8vCisvLyBTb21ldGltZXMgeW91IHdhbnQgdG8gYmUgYWJsZSB0byBtYW5pcHVsYXRlIHByb3RvY29sIHR5cGVzIHRoYXQgeW91IGRvbid0CisvLyBrbm93IGFib3V0IGF0IGNvbXBpbGUgdGltZS4gIEl0IHdvdWxkIGJlIG5pY2UgdG8gYmUgYWJsZSB0byBjb25zdHJ1Y3QKKy8vIGEgTWVzc2FnZSBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgbWVzc2FnZSB0eXBlIGdpdmVuIGJ5IGFueSBhcmJpdHJhcnkKKy8vIERlc2NyaXB0b3IuICBEeW5hbWljTWVzc2FnZSBwcm92aWRlcyB0aGlzLgorLy8KKy8vIEFzIGl0IHR1cm5zIG91dCwgYSBEeW5hbWljTWVzc2FnZSBuZWVkcyB0byBjb25zdHJ1Y3QgZXh0cmEKKy8vIGluZm9ybWF0aW9uIGFib3V0IGl0cyB0eXBlIGluIG9yZGVyIHRvIG9wZXJhdGUuICBNb3N0IG9mIHRoaXMgaW5mb3JtYXRpb24KKy8vIGNhbiBiZSBzaGFyZWQgYmV0d2VlbiBhbGwgRHluYW1pY01lc3NhZ2VzIG9mIHRoZSBzYW1lIHR5cGUuICBCdXQsIGNhY2hpbmcKKy8vIHRoaXMgaW5mb3JtYXRpb24gaW4gc29tZSBzb3J0IG9mIGdsb2JhbCBtYXAgd291bGQgYmUgYSBiYWQgaWRlYSwgc2luY2UKKy8vIHRoZSBjYWNoZWQgaW5mb3JtYXRpb24gZm9yIGEgcGFydGljdWxhciBkZXNjcmlwdG9yIGNvdWxkIG91dGxpdmUgdGhlCisvLyBkZXNjcmlwdG9yIGl0c2VsZi4gIFRvIGF2b2lkIHRoaXMgcHJvYmxlbSwgRHluYW1pY01lc3NhZ2VGYWN0b3J5CisvLyBlbmNhcHN1bGF0ZXMgdGhpcyAiY2FjaGUiLiAgQWxsIER5bmFtaWNNZXNzYWdlcyBvZiB0aGUgc2FtZSB0eXBlIGNyZWF0ZWQKKy8vIGZyb20gdGhlIHNhbWUgZmFjdG9yeSB3aWxsIHNoYXJlIHRoZSBzYW1lIHN1cHBvcnQgZGF0YS4gIEFueSBEZXNjcmlwdG9ycworLy8gdXNlZCB3aXRoIGEgcGFydGljdWxhciBmYWN0b3J5IG11c3Qgb3V0bGl2ZSB0aGUgZmFjdG9yeS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEeW5hbWljTWVzc2FnZUZhY3RvcnkgOiBwdWJsaWMgTWVzc2FnZUZhY3RvcnkgeworIHB1YmxpYzoKKyAgLy8gQ29uc3RydWN0IGEgRHluYW1pY01lc3NhZ2VGYWN0b3J5IHRoYXQgd2lsbCBzZWFyY2ggZm9yIGV4dGVuc2lvbnMgaW4KKyAgLy8gdGhlIERlc2NyaXB0b3JQb29sIGluIHdoaWNoIHRoZSBleHRlbmRlZSBpcyBkZWZpbmVkLgorICBEeW5hbWljTWVzc2FnZUZhY3RvcnkoKTsKKworICAvLyBDb25zdHJ1Y3QgYSBEeW5hbWljTWVzc2FnZUZhY3RvcnkgdGhhdCB3aWxsIHNlYXJjaCBmb3IgZXh0ZW5zaW9ucyBpbgorICAvLyB0aGUgZ2l2ZW4gRGVzY3JpcHRvclBvb2wuCisgIC8vCisgIC8vIERFUFJFQ0FURUQ6ICBVc2UgQ29kZWRJbnB1dFN0cmVhbTo6U2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSB0byB0ZWxsIHRoZQorICAvLyAgIHBhcnNlciB0byBsb29rIGZvciBleHRlbnNpb25zIGluIGFuIGFsdGVybmF0ZSBwb29sLiAgSG93ZXZlciwgbm90ZSB0aGF0CisgIC8vICAgdGhpcyBpcyBhbG1vc3QgbmV2ZXIgd2hhdCB5b3Ugd2FudCB0byBkby4gIEFsbW9zdCBhbGwgdXNlcnMgc2hvdWxkIHVzZQorICAvLyAgIHRoZSB6ZXJvLWFyZyBjb25zdHJ1Y3Rvci4KKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5KGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKTsKKworICB+RHluYW1pY01lc3NhZ2VGYWN0b3J5KCk7CisKKyAgLy8gQ2FsbCB0aGlzIHRvIHRlbGwgdGhlIER5bmFtaWNNZXNzYWdlRmFjdG9yeSB0aGF0IGlmIGl0IGlzIGdpdmVuIGEKKyAgLy8gRGVzY3JpcHRvciBkIGZvciB3aGljaDoKKyAgLy8gICBkLT5maWxlKCktPnBvb2woKSA9PSBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSwKKyAgLy8gdGhlbiBpdCBzaG91bGQgZGVsZWdhdGUgdG8gTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCkgaW5zdGVhZAorICAvLyBvZiBjb25zdHJ1Y3RpbmcgYSBkeW5hbWljIGltcGxlbWVudGF0aW9uIG9mIHRoZSBtZXNzYWdlLiAgSW4gdGhlb3J5IHRoZXJlCisgIC8vIGlzIG5vIGRvd24gc2lkZSB0byBkb2luZyB0aGlzLCBzbyBpdCBtYXkgYmVjb21lIHRoZSBkZWZhdWx0IGluIHRoZSBmdXR1cmUuCisgIHZvaWQgU2V0RGVsZWdhdGVUb0dlbmVyYXRlZEZhY3RvcnkoYm9vbCBlbmFibGUpIHsKKyAgICBkZWxlZ2F0ZV90b19nZW5lcmF0ZWRfZmFjdG9yeV8gPSBlbmFibGU7CisgIH0KKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2VGYWN0b3J5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEdpdmVuIGEgRGVzY3JpcHRvciwgY29uc3RydWN0cyB0aGUgZGVmYXVsdCAocHJvdG90eXBlKSBNZXNzYWdlIG9mIHRoYXQKKyAgLy8gdHlwZS4gIFlvdSBjYW4gdGhlbiBjYWxsIHRoYXQgbWVzc2FnZSdzIE5ldygpIG1ldGhvZCB0byBjb25zdHJ1Y3QgYQorICAvLyBtdXRhYmxlIG1lc3NhZ2Ugb2YgdGhhdCB0eXBlLgorICAvLworICAvLyBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIHdpdGggdGhlIHNhbWUgRGVzY3JpcHRvciByZXR1cm5zIHRoZSBzYW1lCisgIC8vIG9iamVjdC4gIFRoZSByZXR1cm5lZCBvYmplY3QgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgZmFjdG9yeSBhbmQgd2lsbAorICAvLyBiZSBkZXN0cm95ZWQgd2hlbiB0aGUgZmFjdG9yeSBpcyBkZXN0cm95ZWQuICBBbHNvLCBhbnkgb2JqZWN0cyBjcmVhdGVkCisgIC8vIGJ5IGNhbGxpbmcgdGhlIHByb3RvdHlwZSdzIE5ldygpIG1ldGhvZCBzaGFyZSBzb21lIGRhdGEgd2l0aCB0aGUKKyAgLy8gcHJvdG90eXBlLCBzbyB0aGVzZSBtdXN0IGJlIGRlc3Ryb3llZCBiZWZvcmUgdGhlIER5bmFtaWNNZXNzYWdlRmFjdG9yeQorICAvLyBpcyBkZXN0cm95ZWQuCisgIC8vCisgIC8vIFRoZSBnaXZlbiBkZXNjcmlwdG9yIG11c3Qgb3V0bGl2ZSB0aGUgcmV0dXJuZWQgbWVzc2FnZSwgYW5kIGhlbmNlIG11c3QKKyAgLy8gb3V0bGl2ZSB0aGUgRHluYW1pY01lc3NhZ2VGYWN0b3J5LgorICAvLworICAvLyBUaGUgbWV0aG9kIGlzIHRocmVhZC1zYWZlLgorICBjb25zdCBNZXNzYWdlKiBHZXRQcm90b3R5cGUoY29uc3QgRGVzY3JpcHRvciogdHlwZSk7CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbF87CisgIGJvb2wgZGVsZWdhdGVfdG9fZ2VuZXJhdGVkX2ZhY3RvcnlfOworCisgIC8vIFRoaXMgc3RydWN0IGp1c3QgY29udGFpbnMgYSBoYXNoX21hcC4gIFdlIGNhbid0ICNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPiBmcm9tCisgIC8vIHRoaXMgaGVhZGVyIGR1ZSB0byBoYWNrcyBuZWVkZWQgZm9yIGhhc2hfbWFwIHBvcnRhYmlsaXR5IGluIHRoZSBvcGVuIHNvdXJjZQorICAvLyByZWxlYXNlLiAgTmFtZWx5LCBzdHVicy9oYXNoLmgsIHdoaWNoIGRlZmluZXMgaGFzaF9tYXAgcG9ydGFibHksIGlzIG5vdCBhCisgIC8vIHB1YmxpYyBoZWFkZXIgKGZvciBnb29kIHJlYXNvbiksIGJ1dCBkeW5hbWljX21lc3NhZ2UuaCBpcywgYW5kIHB1YmxpYworICAvLyBoZWFkZXJzIG1heSBvbmx5ICNpbmNsdWRlIG90aGVyIHB1YmxpYyBoZWFkZXJzLgorICBzdHJ1Y3QgUHJvdG90eXBlTWFwOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFByb3RvdHlwZU1hcD4gcHJvdG90eXBlc187CisgIG11dGFibGUgTXV0ZXggcHJvdG90eXBlc19tdXRleF87CisKKyAgZnJpZW5kIGNsYXNzIER5bmFtaWNNZXNzYWdlOworICBjb25zdCBNZXNzYWdlKiBHZXRQcm90b3R5cGVOb0xvY2soY29uc3QgRGVzY3JpcHRvciogdHlwZSk7CisKKyAgLy8gQ29uc3RydWN0IGRlZmF1bHQgb25lb2YgaW5zdGFuY2UgZm9yIHJlZmxlY3Rpb24gdXNhZ2UgaWYgb25lb2YKKyAgLy8gaXMgZGVmaW5lZC4KKyAgc3RhdGljIHZvaWQgQ29uc3RydWN0RGVmYXVsdE9uZW9mSW5zdGFuY2UoY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSk7CisgIC8vIERlbGV0ZSBkZWZhdWx0IG9uZW9mIGluc3RhbmNlLiBDYWxsZWQgYnkgfkR5bmFtaWNNZXNzYWdlRmFjdG9yeS4KKyAgc3RhdGljIHZvaWQgRGVsZXRlRGVmYXVsdE9uZW9mSW5zdGFuY2UoY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSk7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKER5bmFtaWNNZXNzYWdlRmFjdG9yeSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfRFlOQU1JQ19NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2VfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjJhMDkyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2VfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwyODUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBTaW5jZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UgZm9yIER5bmFtaWNNZXNzYWdlIGlzIGltcGxlbWVudGVkIGJ5CisvLyBHZW5lcmljTWVzc2FnZVJlZmxlY3Rpb24sIHRoZSBvbmx5IHRoaW5nIHdlIHJlYWxseSBoYXZlIHRvIHRlc3QgaXMKKy8vIHRoYXQgRHluYW1pY01lc3NhZ2UgY29ycmVjdGx5IHNldHMgdXAgdGhlIGluZm9ybWF0aW9uIHRoYXQKKy8vIEdlbmVyaWNNZXNzYWdlUmVmbGVjdGlvbiBuZWVkcyB0byB1c2UuICBTbywgd2UgZm9jdXMgb24gdGhhdCBpbiB0aGlzCisvLyB0ZXN0LiAgT3RoZXIgdGVzdHMsIHN1Y2ggYXMgZ2VuZXJpY19tZXNzYWdlX3JlZmxlY3Rpb25fdW5pdHRlc3QgYW5kCisvLyByZWZsZWN0aW9uX29wc191bml0dGVzdCwgY292ZXIgdGhlIHJlc3Qgb2YgdGhlIGZ1bmN0aW9uYWxpdHkgdXNlZCBieQorLy8gRHluYW1pY01lc3NhZ2UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2ZpZWxkX3ByZXNlbmNlLnBiLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBEeW5hbWljTWVzc2FnZVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3RvcnlfOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogcHJvdG90eXBlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5zaW9uc19kZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogZXh0ZW5zaW9uc19wcm90b3R5cGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBwYWNrZWRfZGVzY3JpcHRvcl87CisgIGNvbnN0IE1lc3NhZ2UqIHBhY2tlZF9wcm90b3R5cGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogb25lb2ZfcHJvdG90eXBlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogcHJvdG8zX2Rlc2NyaXB0b3JfOworICBjb25zdCBNZXNzYWdlKiBwcm90bzNfcHJvdG90eXBlXzsKKworICBEeW5hbWljTWVzc2FnZVRlc3QoKTogZmFjdG9yeV8oJnBvb2xfKSB7fQorCisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICAvLyBXZSB3YW50IHRvIG1ha2Ugc3VyZSB0aGF0IER5bmFtaWNNZXNzYWdlIHdvcmtzIChwYXJ0aWN1bGFybHkgd2l0aAorICAgIC8vIGV4dGVuc2lvbnMpIGV2ZW4gaWYgd2UgdXNlIGRlc2NyaXB0b3JzIHRoYXQgYXJlICpub3QqIGZyb20gY29tcGlsZWQtaW4KKyAgICAvLyB0eXBlcywgc28gd2UgbWFrZSBjb3BpZXMgb2YgdGhlIGRlc2NyaXB0b3JzIGZvciB1bml0dGVzdC5wcm90byBhbmQKKyAgICAvLyB1bml0dGVzdF9pbXBvcnQucHJvdG8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byB1bml0dGVzdF9maWxlOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gdW5pdHRlc3RfaW1wb3J0X2ZpbGU7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byB1bml0dGVzdF9pbXBvcnRfcHVibGljX2ZpbGU7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byB1bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZV9maWxlOworCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkNvcHlUbygmdW5pdHRlc3RfZmlsZSk7CisgICAgdW5pdHRlc3RfaW1wb3J0OjpJbXBvcnRNZXNzYWdlOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKAorICAgICAgJnVuaXR0ZXN0X2ltcG9ydF9maWxlKTsKKyAgICB1bml0dGVzdF9pbXBvcnQ6OlB1YmxpY0ltcG9ydE1lc3NhZ2U6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oCisgICAgICAmdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19maWxlKTsKKyAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKS0+CisgICAgICAgIGZpbGUoKS0+Q29weVRvKCZ1bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZV9maWxlKTsKKworICAgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZSh1bml0dGVzdF9pbXBvcnRfcHVibGljX2ZpbGUpICE9IE5VTEwpOworICAgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZSh1bml0dGVzdF9pbXBvcnRfZmlsZSkgIT0gTlVMTCk7CisgICAgQVNTRVJUX1RSVUUocG9vbF8uQnVpbGRGaWxlKHVuaXR0ZXN0X2ZpbGUpICE9IE5VTEwpOworICAgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZSh1bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZV9maWxlKSAhPSBOVUxMKTsKKworICAgIGRlc2NyaXB0b3JfID0gcG9vbF8uRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMiKTsKKyAgICBBU1NFUlRfVFJVRShkZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgICBwcm90b3R5cGVfID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKGRlc2NyaXB0b3JfKTsKKworICAgIGV4dGVuc2lvbnNfZGVzY3JpcHRvcl8gPQorICAgICAgcG9vbF8uRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyIpOworICAgIEFTU0VSVF9UUlVFKGV4dGVuc2lvbnNfZGVzY3JpcHRvcl8gIT0gTlVMTCk7CisgICAgZXh0ZW5zaW9uc19wcm90b3R5cGVfID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKGV4dGVuc2lvbnNfZGVzY3JpcHRvcl8pOworCisgICAgcGFja2VkX2Rlc2NyaXB0b3JfID0KKyAgICAgIHBvb2xfLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIik7CisgICAgQVNTRVJUX1RSVUUocGFja2VkX2Rlc2NyaXB0b3JfICE9IE5VTEwpOworICAgIHBhY2tlZF9wcm90b3R5cGVfID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKHBhY2tlZF9kZXNjcmlwdG9yXyk7CisKKyAgICBvbmVvZl9kZXNjcmlwdG9yXyA9CisgICAgICBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIiKTsKKyAgICBBU1NFUlRfVFJVRShvbmVvZl9kZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgICBvbmVvZl9wcm90b3R5cGVfID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKG9uZW9mX2Rlc2NyaXB0b3JfKTsKKworICAgIHByb3RvM19kZXNjcmlwdG9yXyA9CisgICAgICBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoCisgICAgICAgICAgInByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIik7CisgICAgQVNTRVJUX1RSVUUocHJvdG8zX2Rlc2NyaXB0b3JfICE9IE5VTEwpOworICAgIHByb3RvM19wcm90b3R5cGVfID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKHByb3RvM19kZXNjcmlwdG9yXyk7CisgIH0KK307CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIERlc2NyaXB0b3IpIHsKKyAgLy8gQ2hlY2sgdGhhdCB0aGUgZGVzY3JpcHRvciBvbiB0aGUgRHluYW1pY01lc3NhZ2UgbWF0Y2hlcyB0aGUgZGVzY3JpcHRvcgorICAvLyBwYXNzZWQgdG8gR2V0UHJvdG90eXBlKCkuCisgIEVYUEVDVF9FUShwcm90b3R5cGVfLT5HZXREZXNjcmlwdG9yKCksIGRlc2NyaXB0b3JfKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgT25lUHJvdG90eXBlKSB7CisgIC8vIENoZWNrIHRoYXQgcmVxdWVzdGluZyB0aGUgc2FtZSBwcm90b3R5cGUgdHdpY2UgcHJvZHVjZXMgdGhlIHNhbWUgb2JqZWN0LgorICBFWFBFQ1RfRVEocHJvdG90eXBlXywgZmFjdG9yeV8uR2V0UHJvdG90eXBlKGRlc2NyaXB0b3JfKSk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIERlZmF1bHRzKSB7CisgIC8vIENoZWNrIHRoYXQgYWxsIGRlZmF1bHQgdmFsdWVzIGFyZSBzZXQgY29ycmVjdGx5IGluIHRoZSBpbml0aWFsIG1lc3NhZ2UuCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKGRlc2NyaXB0b3JfKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uKCpwcm90b3R5cGVfKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgSW5kZXBlbmRlbnRPZmZzZXRzKSB7CisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIGluZGVwZW5kZW50IG9mZnNldHMgYnkgc2V0dGluZyBlYWNoCisgIC8vIG9uZSB0byBhIHVuaXF1ZSB2YWx1ZSB0aGVuIGNoZWNraW5nIHRoYXQgdGhleSBhbGwgc3RpbGwgaGF2ZSB0aG9zZQorICAvLyB1bmlxdWUgdmFsdWVzIChpLmUuIHRoZXkgZG9uJ3Qgc3RvbXAgZWFjaCBvdGhlcikuCisgIHNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShwcm90b3R5cGVfLT5OZXcoKSk7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKGRlc2NyaXB0b3JfKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UuZ2V0KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgRXh0ZW5zaW9ucykgeworICAvLyBDaGVjayB0aGF0IGV4dGVuc2lvbnMgd29yay4KKyAgc2NvcGVkX3B0cjxNZXNzYWdlPiBtZXNzYWdlKGV4dGVuc2lvbnNfcHJvdG90eXBlXy0+TmV3KCkpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihleHRlbnNpb25zX2Rlc2NyaXB0b3JfKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UuZ2V0KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgUGFja2VkRmllbGRzKSB7CisgIC8vIENoZWNrIHRoYXQgcGFja2VkIGZpZWxkcyB3b3JrIHByb3Blcmx5LgorICBzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UocGFja2VkX3Byb3RvdHlwZV8tPk5ldygpKTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIocGFja2VkX2Rlc2NyaXB0b3JfKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRQYWNrZWRGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UuZ2V0KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RQYWNrZWRGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgT25lb2YpIHsKKyAgLy8gQ2hlY2sgdGhhdCBvbmVvZiBmaWVsZHMgd29yayBwcm9wZXJseS4KKyAgc2NvcGVkX3B0cjxNZXNzYWdlPiBtZXNzYWdlKG9uZW9mX3Byb3RvdHlwZV8tPk5ldygpKTsKKworICAvLyBDaGVjayBkZWZhdWx0IHZhbHVlcy4KKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2ludCIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX3N0cmluZyIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19zdHJpbmdfcGllY2UiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19ieXRlcyIpKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PLCByZWZsZWN0aW9uLT5HZXRFbnVtKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2VudW0iKSktPm51bWJlcigpKTsKKyAgY29uc3QgRGVzY3JpcHRvciogbmVzdGVkX2Rlc2NyaXB0b3I7CisgIGNvbnN0IE1lc3NhZ2UqIG5lc3RlZF9wcm90b3R5cGU7CisgIG5lc3RlZF9kZXNjcmlwdG9yID0KKyAgICAgIHBvb2xfLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIik7CisgIG5lc3RlZF9wcm90b3R5cGUgPSBmYWN0b3J5Xy5HZXRQcm90b3R5cGUobmVzdGVkX2Rlc2NyaXB0b3IpOworICBFWFBFQ1RfRVEobmVzdGVkX3Byb3RvdHlwZSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgICAgICAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19tZXNzYWdlIikpKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vZ3JvdXBfZGVzY3JpcHRvcjsKKyAgY29uc3QgTWVzc2FnZSogZm9vZ3JvdXBfcHJvdG90eXBlOworICBmb29ncm91cF9kZXNjcmlwdG9yID0KKyAgICAgIHBvb2xfLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5Gb29Hcm91cCIpOworICBmb29ncm91cF9wcm90b3R5cGUgPSBmYWN0b3J5Xy5HZXRQcm90b3R5cGUoZm9vZ3JvdXBfZGVzY3JpcHRvcik7CisgIEVYUEVDVF9FUShmb29ncm91cF9wcm90b3R5cGUsCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29ncm91cCIpKSk7CisgIEVYUEVDVF9ORShmb29ncm91cF9wcm90b3R5cGUsCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKDUsIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX2ludCIpKSk7CisgIEVYUEVDVF9FUSgiU1RSSU5HIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX3N0cmluZyIpKSk7CisgIEVYUEVDVF9FUSgiQ09SRCIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIikpKTsKKyAgRVhQRUNUX0VRKCJTUElFQ0UiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCJCWVRFUyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9ieXRlcyIpKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFSLCByZWZsZWN0aW9uLT5HZXRFbnVtKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX2VudW0iKSktPm51bWJlcigpKTsKKworICAvLyBDaGVjayBzZXQgZnVuY3Rpb25zLgorICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihvbmVvZl9kZXNjcmlwdG9yXyk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE9uZW9mVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0T25lb2ZTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgU3BhY2VVc2VkKSB7CisgIC8vIFRlc3QgdGhhdCBTcGFjZVVzZWQoKSB3b3JrcyBwcm9wZXJseQorCisgIC8vIFNpbmNlIHdlIHNoYXJlIHRoZSBpbXBsZW1lbnRhdGlvbiB3aXRoIGdlbmVyYXRlZCBtZXNzYWdlcywgd2UgZG9uJ3QgbmVlZAorICAvLyB0byB0ZXN0IHZlcnkgbXVjaCBoZXJlLiAgSnVzdCBtYWtlIHN1cmUgaXQgYXBwZWFycyB0byBiZSB3b3JraW5nLgorCisgIHNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShwcm90b3R5cGVfLT5OZXcoKSk7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKGRlc2NyaXB0b3JfKTsKKworICBpbnQgaW5pdGlhbF9zcGFjZV91c2VkID0gbWVzc2FnZS0+U3BhY2VVc2VkKCk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgRVhQRUNUX0xUKGluaXRpYWxfc3BhY2VfdXNlZCwgbWVzc2FnZS0+U3BhY2VVc2VkKCkpOworfQorCitURVNUX0YoRHluYW1pY01lc3NhZ2VUZXN0LCBBcmVuYSkgeworICBBcmVuYSBhcmVuYTsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHByb3RvdHlwZV8tPk5ldygmYXJlbmEpOworICAodm9pZCltZXNzYWdlOyAgLy8gYXZvaWQgdW51c2VkLXZhcmlhYmxlIGVycm9yLgorICAvLyBSZXR1cm4gd2l0aG91dCBmcmVlaW5nOiBzaG91bGQgbm90IGxlYWsuCit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIFByb3RvMykgeworICBNZXNzYWdlKiBtZXNzYWdlID0gcHJvdG8zX3Byb3RvdHlwZV8tPk5ldygpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworCisgIC8vIEp1c3QgdGVzdCBhIHNpbmdsZSBwcmltdGl2ZSBhbmQgc2luZ2xlIG1lc3NhZ2UgZmllbGQgaGVyZSB0byBtYWtlIHN1cmUgd2UKKyAgLy8gYXJlIGdldHRpbmcgdGhlIG5vLWZpZWxkLXByZXNlbmNlIHNlbWFudGljcyBlbHNld2hlcmUuIER5bmFtaWNNZXNzYWdlIHVzZXMKKyAgLy8gR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24gdW5kZXIgdGhlIGhvb2QsIHNvIHRoZSByZXN0IHNob3VsZCBiZSBmaW5lIGFzCisgIC8vIGxvbmcgYXMgR01SIHJlY29nbml6ZXMgdGhhdCB3ZSdyZSB1c2luZyBhIHByb3RvMyBtZXNzYWdlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG9wdGlvbmFsX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBvcHRpb25hbF9tc2cgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICBFWFBFQ1RfVFJVRShvcHRpb25hbF9pbnQzMiAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUob3B0aW9uYWxfbXNnICE9IE5VTEwpOworCisgIEVYUEVDVF9FUShmYWxzZSwgcmVmbC0+SGFzRmllbGQoKm1lc3NhZ2UsIG9wdGlvbmFsX2ludDMyKSk7CisgIHJlZmwtPlNldEludDMyKG1lc3NhZ2UsIG9wdGlvbmFsX2ludDMyLCA0Mik7CisgIEVYUEVDVF9FUSh0cnVlLCByZWZsLT5IYXNGaWVsZCgqbWVzc2FnZSwgb3B0aW9uYWxfaW50MzIpKTsKKyAgcmVmbC0+U2V0SW50MzIobWVzc2FnZSwgb3B0aW9uYWxfaW50MzIsIDApOworICBFWFBFQ1RfRVEoZmFsc2UsIHJlZmwtPkhhc0ZpZWxkKCptZXNzYWdlLCBvcHRpb25hbF9pbnQzMikpOworCisgIEVYUEVDVF9FUShmYWxzZSwgcmVmbC0+SGFzRmllbGQoKm1lc3NhZ2UsIG9wdGlvbmFsX21zZykpOworICByZWZsLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBvcHRpb25hbF9tc2cpOworICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbC0+SGFzRmllbGQoKm1lc3NhZ2UsIG9wdGlvbmFsX21zZykpOworICBkZWxldGUgcmVmbC0+UmVsZWFzZU1lc3NhZ2UobWVzc2FnZSwgb3B0aW9uYWxfbXNnKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByZWZsLT5IYXNGaWVsZCgqbWVzc2FnZSwgb3B0aW9uYWxfbXNnKSk7CisKKyAgLy8gQWxzbyBlbnN1cmUgdGhhdCB0aGUgZGVmYXVsdCBpbnN0YW5jZSBoYW5kbGVzIGZpZWxkIHByZXNlbmNlIHByb3Blcmx5LgorICBFWFBFQ1RfRVEoZmFsc2UsIHJlZmwtPkhhc0ZpZWxkKCpwcm90bzNfcHJvdG90eXBlXywgb3B0aW9uYWxfbXNnKSk7CisKKyAgZGVsZXRlIG1lc3NhZ2U7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDNiMzhkZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5jYwpAQCAtMCwwICsxLDE3ODMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCituYW1lc3BhY2UgeworCitpbmxpbmUgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSByZWFsX3R5cGUoRmllbGRUeXBlIHR5cGUpIHsKKyAgR09PR0xFX0RDSEVDSyh0eXBlID4gMCAmJiB0eXBlIDw9IFdpcmVGb3JtYXRMaXRlOjpNQVhfRklFTERfVFlQRSk7CisgIHJldHVybiBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlPih0eXBlKTsKK30KKworaW5saW5lIFdpcmVGb3JtYXRMaXRlOjpDcHBUeXBlIGNwcF90eXBlKEZpZWxkVHlwZSB0eXBlKSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlVG9DcHBUeXBlKHJlYWxfdHlwZSh0eXBlKSk7Cit9CisKK2lubGluZSBib29sIGlzX3BhY2thYmxlKFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVDoKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0OgorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzI6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1NUQVJUX0dST1VQOgorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUDoKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIC8vIERvIG5vdCBhZGQgYSBkZWZhdWx0IHN0YXRlbWVudC4gTGV0IHRoZSBjb21waWxlciBjb21wbGFpbiB3aGVuIHNvbWVvbmUKKyAgICAvLyBhZGRzIGEgbmV3IHdpcmUgdHlwZS4KKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiY2FuJ3QgcmVhY2ggaGVyZS4iOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIFJlZ2lzdHJ5IHN0dWZmLgordHlwZWRlZiBoYXNoX21hcDxwYWlyPGNvbnN0IE1lc3NhZ2VMaXRlKiwgaW50PiwKKyAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uSW5mbz4gRXh0ZW5zaW9uUmVnaXN0cnk7CitFeHRlbnNpb25SZWdpc3RyeSogcmVnaXN0cnlfID0gTlVMTDsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocmVnaXN0cnlfaW5pdF8pOworCit2b2lkIERlbGV0ZVJlZ2lzdHJ5KCkgeworICBkZWxldGUgcmVnaXN0cnlfOworICByZWdpc3RyeV8gPSBOVUxMOworfQorCit2b2lkIEluaXRSZWdpc3RyeSgpIHsKKyAgcmVnaXN0cnlfID0gbmV3IEV4dGVuc2lvblJlZ2lzdHJ5OworICBPblNodXRkb3duKCZEZWxldGVSZWdpc3RyeSk7Cit9CisKKy8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgYXQgc3RhcnR1cCwgc28gdGhlcmUgaXMgbm8gbmVlZCBmb3IgdGhyZWFkLQorLy8gc2FmZXR5Lgordm9pZCBSZWdpc3Rlcihjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICBpbnQgbnVtYmVyLCBFeHRlbnNpb25JbmZvIGluZm8pIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcmVnaXN0cnlfaW5pdF8sICZJbml0UmVnaXN0cnkpOworCisgIGlmICghSW5zZXJ0SWZOb3RQcmVzZW50KHJlZ2lzdHJ5Xywgc3RkOjptYWtlX3BhaXIoY29udGFpbmluZ190eXBlLCBudW1iZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvKSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJNdWx0aXBsZSBleHRlbnNpb24gcmVnaXN0cmF0aW9ucyBmb3IgdHlwZSBcIiIKKyAgICAgICAgICAgICAgIDw8IGNvbnRhaW5pbmdfdHlwZS0+R2V0VHlwZU5hbWUoKQorICAgICAgICAgICAgICAgPDwgIlwiLCBmaWVsZCBudW1iZXIgIiA8PCBudW1iZXIgPDwgIi4iOworICB9Cit9CisKK2NvbnN0IEV4dGVuc2lvbkluZm8qIEZpbmRSZWdpc3RlcmVkRXh0ZW5zaW9uKAorICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsIGludCBudW1iZXIpIHsKKyAgcmV0dXJuIChyZWdpc3RyeV8gPT0gTlVMTCkKKyAgICAgICAgICAgICA/IE5VTEwKKyAgICAgICAgICAgICA6IEZpbmRPck51bGwoKnJlZ2lzdHJ5Xywgc3RkOjptYWtlX3BhaXIoY29udGFpbmluZ190eXBlLCBudW1iZXIpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0V4dGVuc2lvbkZpbmRlcjo6fkV4dGVuc2lvbkZpbmRlcigpIHt9CisKK2Jvb2wgR2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyOjpGaW5kKGludCBudW1iZXIsIEV4dGVuc2lvbkluZm8qIG91dHB1dCkgeworICBjb25zdCBFeHRlbnNpb25JbmZvKiBleHRlbnNpb24gPQorICAgICAgRmluZFJlZ2lzdGVyZWRFeHRlbnNpb24oY29udGFpbmluZ190eXBlXywgbnVtYmVyKTsKKyAgaWYgKGV4dGVuc2lvbiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgICpvdXRwdXQgPSAqZXh0ZW5zaW9uOworICAgIHJldHVybiB0cnVlOworICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpSZWdpc3RlckV4dGVuc2lvbihjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcmVwZWF0ZWQsIGJvb2wgaXNfcGFja2VkKSB7CisgIEdPT0dMRV9DSEVDS19ORSh0eXBlLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNKTsKKyAgR09PR0xFX0NIRUNLX05FKHR5cGUsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UpOworICBHT09HTEVfQ0hFQ0tfTkUodHlwZSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfR1JPVVApOworICBFeHRlbnNpb25JbmZvIGluZm8odHlwZSwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk7CisgIFJlZ2lzdGVyKGNvbnRhaW5pbmdfdHlwZSwgbnVtYmVyLCBpbmZvKTsKK30KKworc3RhdGljIGJvb2wgQ2FsbE5vQXJnVmFsaWRpdHlGdW5jKGNvbnN0IHZvaWQqIGFyZywgaW50IG51bWJlcikgeworICAvLyBOb3RlOiAgTXVzdCB1c2UgQy1zdHlsZSBjYXN0IGhlcmUgcmF0aGVyIHRoYW4gcmVpbnRlcnByZXRfY2FzdCBiZWNhdXNlCisgIC8vICAgdGhlIEMrKyBzdGFuZGFyZCBhdCBvbmUgcG9pbnQgZGlkIG5vdCBhbGxvdyBjYXN0cyBiZXR3ZWVuIGZ1bmN0aW9uIGFuZAorICAvLyAgIGRhdGEgcG9pbnRlcnMgYW5kIHNvbWUgY29tcGlsZXJzIGVuZm9yY2UgdGhpcyBmb3IgQysrLXN0eWxlIGNhc3RzLiAgTm8KKyAgLy8gICBjb21waWxlciBlbmZvcmNlcyBpdCBmb3IgQy1zdHlsZSBjYXN0cyBzaW5jZSBsb3RzIG9mIEMtc3R5bGUgY29kZSBoYXMKKyAgLy8gICByZWxpZWQgb24gdGhlc2Uga2luZHMgb2YgY2FzdHMgZm9yIGEgbG9uZyB0aW1lLCBkZXNwaXRlIGJlaW5nCisgIC8vICAgdGVjaG5pY2FsbHkgdW5kZWZpbmVkLiAgU2VlOgorICAvLyAgICAgaHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRjMS9zYzIyL3dnMjEvZG9jcy9jd2dfZGVmZWN0cy5odG1sIzE5NQorICAvLyBBbHNvIG5vdGU6ICBTb21lIGNvbXBpbGVycyBkbyBub3QgYWxsb3cgZnVuY3Rpb24gcG9pbnRlcnMgdG8gYmUgImNvbnN0Ii4KKyAgLy8gICBXaGljaCBtYWtlcyBzZW5zZSwgSSBzdXBwb3NlLCBiZWNhdXNlIGl0J3MgbWVhbmluZ2xlc3MuCisgIHJldHVybiAoKEVudW1WYWxpZGl0eUZ1bmMqKWFyZykobnVtYmVyKTsKK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlJlZ2lzdGVyRW51bUV4dGVuc2lvbihjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19yZXBlYXRlZCwgYm9vbCBpc19wYWNrZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1WYWxpZGl0eUZ1bmMqIGlzX3ZhbGlkKSB7CisgIEdPT0dMRV9DSEVDS19FUSh0eXBlLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNKTsKKyAgRXh0ZW5zaW9uSW5mbyBpbmZvKHR5cGUsIGlzX3JlcGVhdGVkLCBpc19wYWNrZWQpOworICBpbmZvLmVudW1fdmFsaWRpdHlfY2hlY2suZnVuYyA9IENhbGxOb0FyZ1ZhbGlkaXR5RnVuYzsKKyAgLy8gU2VlIGNvbW1lbnQgaW4gQ2FsbE5vQXJnVmFsaWRpdHlGdW5jKCkgYWJvdXQgd2h5IHdlIHVzZSBhIGMtc3R5bGUgY2FzdC4KKyAgaW5mby5lbnVtX3ZhbGlkaXR5X2NoZWNrLmFyZyA9ICh2b2lkKilpc192YWxpZDsKKyAgUmVnaXN0ZXIoY29udGFpbmluZ190eXBlLCBudW1iZXIsIGluZm8pOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6UmVnaXN0ZXJNZXNzYWdlRXh0ZW5zaW9uKGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3JlcGVhdGVkLCBib29sIGlzX3BhY2tlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIHByb3RvdHlwZSkgeworICBHT09HTEVfQ0hFQ0sodHlwZSA9PSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFIHx8CisgICAgICAgIHR5cGUgPT0gV2lyZUZvcm1hdExpdGU6OlRZUEVfR1JPVVApOworICBFeHRlbnNpb25JbmZvIGluZm8odHlwZSwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk7CisgIGluZm8ubWVzc2FnZV9wcm90b3R5cGUgPSBwcm90b3R5cGU7CisgIFJlZ2lzdGVyKGNvbnRhaW5pbmdfdHlwZSwgbnVtYmVyLCBpbmZvKTsKK30KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBDb25zdHJ1Y3RvcnMgYW5kIGJhc2ljIG1ldGhvZHMuCisKK0V4dGVuc2lvblNldDo6RXh0ZW5zaW9uU2V0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSA6IGFyZW5hXyhhcmVuYSkgeworICBpZiAoYXJlbmFfICE9IE5VTEwpIHsKKyAgICBhcmVuYV8tPk93bkRlc3RydWN0b3IoJmV4dGVuc2lvbnNfKTsKKyAgfQorfQorCitFeHRlbnNpb25TZXQ6OkV4dGVuc2lvblNldCgpIDogYXJlbmFfKE5VTEwpIHt9CisKK0V4dGVuc2lvblNldDo6fkV4dGVuc2lvblNldCgpIHsKKyAgLy8gRGVsZXRlcyBhbGwgYWxsb2NhdGVkIGV4dGVuc2lvbnMuCisgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgIGl0ZXItPnNlY29uZC5GcmVlKCk7CisgICAgfQorICB9Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIHZvaWQgRXh0ZW5zaW9uU2V0OjpBcHBlbmRUb0xpc3QoY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KiBvdXRwdXQpIGNvbnN0CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpIYXMoaW50IG51bWJlcikgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgcmV0dXJuIGZhbHNlOworICBHT09HTEVfRENIRUNLKCFpdGVyLT5zZWNvbmQuaXNfcmVwZWF0ZWQpOworICByZXR1cm4gIWl0ZXItPnNlY29uZC5pc19jbGVhcmVkOworfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpOdW1FeHRlbnNpb25zKCkgY29uc3QgeworICBpbnQgcmVzdWx0ID0gMDsKKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBpZiAoIWl0ZXItPnNlY29uZC5pc19jbGVhcmVkKSB7CisgICAgICArK3Jlc3VsdDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW50IEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uU2l6ZShpbnQgbnVtYmVyKSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIGlmIChpdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiBpdGVyLT5zZWNvbmQuR2V0U2l6ZSgpOworfQorCitGaWVsZFR5cGUgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb25UeXBlKGludCBudW1iZXIpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkRvbid0IGxvb2t1cCBleHRlbnNpb24gdHlwZXMgaWYgdGhleSBhcmVuJ3QgcHJlc2VudCAoMSkuICI7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKGl0ZXItPnNlY29uZC5pc19jbGVhcmVkKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJEb24ndCBsb29rdXAgZXh0ZW5zaW9uIHR5cGVzIGlmIHRoZXkgYXJlbid0IHByZXNlbnQgKDIpLiAiOworICB9CisgIHJldHVybiBpdGVyLT5zZWNvbmQudHlwZTsKK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OkNsZWFyRXh0ZW5zaW9uKGludCBudW1iZXIpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkpIHJldHVybjsKKyAgaXRlci0+c2Vjb25kLkNsZWFyKCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEZpZWxkIGFjY2Vzc29ycworCituYW1lc3BhY2UgeworCitlbnVtIENhcmRpbmFsaXR5IHsKKyAgUkVQRUFURUQsCisgIE9QVElPTkFMCit9OworCit9ICAvLyBuYW1lc3BhY2UKKworI2RlZmluZSBHT09HTEVfRENIRUNLX1RZUEUoRVhURU5TSU9OLCBMQUJFTCwgQ1BQVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgR09PR0xFX0RDSEVDS19FUSgoRVhURU5TSU9OKS5pc19yZXBlYXRlZCA/IFJFUEVBVEVEIDogT1BUSU9OQUwsIExBQkVMKTsgICAgICAgICBcCisgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoKEVYVEVOU0lPTikudHlwZSksIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFXyMjQ1BQVFlQRSkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUHJpbWl0aXZlcworCisjZGVmaW5lIFBSSU1JVElWRV9BQ0NFU1NPUlMoVVBQRVJDQVNFLCBMT1dFUkNBU0UsIENBTUVMQ0FTRSkgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK0xPV0VSQ0FTRSBFeHRlbnNpb25TZXQ6OkdldCMjQ0FNRUxDQVNFKGludCBudW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dFUkNBU0UgZGVmYXVsdF92YWx1ZSkgY29uc3QgeyAgICAgICAgXAorICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOyAgICAgICAgIFwKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkgfHwgaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQpIHsgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBPUFRJT05BTCwgVVBQRVJDQVNFKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBpdGVyLT5zZWNvbmQuTE9XRVJDQVNFIyNfdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpTZXQjI0NBTUVMQ0FTRShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XRVJDQVNFIHZhbHVlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeyAgICAgICAgIFwKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihudW1iZXIsIGRlc2NyaXB0b3IsICZleHRlbnNpb24pKSB7ICAgICAgICAgICAgICAgICAgICAgXAorICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfRENIRUNLX0VRKGNwcF90eXBlKGV4dGVuc2lvbi0+dHlwZSksIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFXyMjVVBQRVJDQVNFKTsgXAorICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSBmYWxzZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIE9QVElPTkFMLCBVUFBFUkNBU0UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGV4dGVuc2lvbi0+aXNfY2xlYXJlZCA9IGZhbHNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBleHRlbnNpb24tPkxPV0VSQ0FTRSMjX3ZhbHVlID0gdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorTE9XRVJDQVNFIEV4dGVuc2lvblNldDo6R2V0UmVwZWF0ZWQjI0NBTUVMQ0FTRShpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0IHsgIFwKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsgICAgICAgICBcCisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7IFwKKyAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgUkVQRUFURUQsIFVQUEVSQ0FTRSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICByZXR1cm4gaXRlci0+c2Vjb25kLnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkdldChpbmRleCk7ICAgICAgICAgICAgICAgIFwKK30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordm9pZCBFeHRlbnNpb25TZXQ6OlNldFJlcGVhdGVkIyNDQU1FTENBU0UoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIExPV0VSQ0FTRSB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7ICAgICAgICAgICAgICAgXAorICBHT09HTEVfQ0hFQ0soaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkluZGV4IG91dC1vZi1ib3VuZHMgKGZpZWxkIGlzIGVtcHR5KS4iOyBcCisgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIFJFUEVBVEVELCBVUFBFUkNBU0UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaXRlci0+c2Vjb25kLnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPlNldChpbmRleCwgdmFsdWUpOyAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpBZGQjI0NBTUVMQ0FTRShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBwYWNrZWQsIExPV0VSQ0FTRSB2YWx1ZSwgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeyAgICAgICAgIFwKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihudW1iZXIsIGRlc2NyaXB0b3IsICZleHRlbnNpb24pKSB7ICAgICAgICAgICAgICAgICAgICAgXAorICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfRENIRUNLX0VRKGNwcF90eXBlKGV4dGVuc2lvbi0+dHlwZSksIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFXyMjVVBQRVJDQVNFKTsgXAorICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBleHRlbnNpb24tPmlzX3BhY2tlZCA9IHBhY2tlZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihhcmVuYV8sIGFyZW5hXyk7ICAgICAgICAgICAgICAgIFwKKyAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIFJFUEVBVEVELCBVUFBFUkNBU0UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfRENIRUNLX0VRKGV4dGVuc2lvbi0+aXNfcGFja2VkLCBwYWNrZWQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZXh0ZW5zaW9uLT5yZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5BZGQodmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICAgICBcCit9CisKK1BSSU1JVElWRV9BQ0NFU1NPUlMoIElOVDMyLCAgaW50MzIsICBJbnQzMikKK1BSSU1JVElWRV9BQ0NFU1NPUlMoIElOVDY0LCAgaW50NjQsICBJbnQ2NCkKK1BSSU1JVElWRV9BQ0NFU1NPUlMoVUlOVDMyLCB1aW50MzIsIFVJbnQzMikKK1BSSU1JVElWRV9BQ0NFU1NPUlMoVUlOVDY0LCB1aW50NjQsIFVJbnQ2NCkKK1BSSU1JVElWRV9BQ0NFU1NPUlMoIEZMT0FULCAgZmxvYXQsICBGbG9hdCkKK1BSSU1JVElWRV9BQ0NFU1NPUlMoRE9VQkxFLCBkb3VibGUsIERvdWJsZSkKK1BSSU1JVElWRV9BQ0NFU1NPUlMoICBCT09MLCAgIGJvb2wsICAgQm9vbCkKKworI3VuZGVmIFBSSU1JVElWRV9BQ0NFU1NPUlMKKworY29uc3Qgdm9pZCogRXh0ZW5zaW9uU2V0OjpHZXRSYXdSZXBlYXRlZEZpZWxkKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogZGVmYXVsdF92YWx1ZSkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9CisgIC8vIFdlIGFzc3VtZSB0aGF0IGFsbCB0aGUgUmVwZWF0ZWRGaWVsZDw+KiBwb2ludGVycyBoYXZlIHRoZSBzYW1lCisgIC8vIHNpemUgYW5kIGFsaWdubWVudCB3aXRoaW4gdGhlIGFub255bW91cyB1bmlvbiBpbiBFeHRlbnNpb24uCisgIHJldHVybiBpdGVyLT5zZWNvbmQucmVwZWF0ZWRfaW50MzJfdmFsdWU7Cit9CisKK3ZvaWQqIEV4dGVuc2lvblNldDo6TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcGFja2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisKKyAgLy8gV2UgaW5zdGFudGlhdGUgYW4gZW1wdHkgUmVwZWF0ZWR7LFB0cn1GaWVsZCBpZiBvbmUgZG9lc24ndCBleGlzdCBmb3IgdGhpcworICAvLyBleHRlbnNpb24uCisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihudW1iZXIsIGRlc2MsICZleHRlbnNpb24pKSB7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IHRydWU7CisgICAgZXh0ZW5zaW9uLT50eXBlID0gZmllbGRfdHlwZTsKKyAgICBleHRlbnNpb24tPmlzX3BhY2tlZCA9IHBhY2tlZDsKKworICAgIHN3aXRjaCAoV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZVRvQ3BwVHlwZSgKKyAgICAgICAgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZT4oZmllbGRfdHlwZSkpKSB7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0lOVDMyOgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2ludDMyX3ZhbHVlID0KKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGU8UmVwZWF0ZWRGaWVsZDxpbnQzMj4gPihhcmVuYV8sIGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9pbnQ2NF92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlPFJlcGVhdGVkRmllbGQ8aW50NjQ+ID4oYXJlbmFfLCBhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3VpbnQzMl92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlPFJlcGVhdGVkRmllbGQ8dWludDMyPiA+KGFyZW5hXywgYXJlbmFfKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF91aW50NjRfdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZEZpZWxkPHVpbnQ2ND4gPihhcmVuYV8sIGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZG91YmxlX3ZhbHVlID0KKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGU8UmVwZWF0ZWRGaWVsZDxkb3VibGU+ID4oYXJlbmFfLCBhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRkxPQVQ6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZmxvYXRfdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZEZpZWxkPGZsb2F0PiA+KGFyZW5hXywgYXJlbmFfKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0JPT0w6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfYm9vbF92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlPFJlcGVhdGVkRmllbGQ8Ym9vbD4gPihhcmVuYV8sIGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9FTlVNOgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2VudW1fdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZEZpZWxkPGludD4gPihhcmVuYV8sIGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlID0KKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGU8UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4gPihhcmVuYV8sIGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiA+KGFyZW5hXywgYXJlbmFfKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgLy8gV2UgYXNzdW1lIHRoYXQgYWxsIHRoZSBSZXBlYXRlZEZpZWxkPD4qIHBvaW50ZXJzIGhhdmUgdGhlIHNhbWUKKyAgLy8gc2l6ZSBhbmQgYWxpZ25tZW50IHdpdGhpbiB0aGUgYW5vbnltb3VzIHVuaW9uIGluIEV4dGVuc2lvbi4KKyAgcmV0dXJuIGV4dGVuc2lvbi0+cmVwZWF0ZWRfaW50MzJfdmFsdWU7Cit9CisKKy8vIENvbXBhdGlibGUgdmVyc2lvbiB1c2luZyBvbGQgY2FsbCBzaWduYXR1cmUuIERvZXMgbm90IGNyZWF0ZSBleHRlbnNpb25zIHdoZW4KKy8vIHRoZSBkb24ndCBhbHJlYWR5IGV4aXN0OyBpbnN0ZWFkLCBqdXN0IEdPT0dMRV9DSEVDSy1mYWlscy4KK3ZvaWQqIEV4dGVuc2lvblNldDo6TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlcikgeworICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBHT09HTEVfQ0hFQ0soaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkV4dGVuc2lvbiBub3QgZm91bmQuIjsKKyAgLy8gV2UgYXNzdW1lIHRoYXQgYWxsIHRoZSBSZXBlYXRlZEZpZWxkPD4qIHBvaW50ZXJzIGhhdmUgdGhlIHNhbWUKKyAgLy8gc2l6ZSBhbmQgYWxpZ25tZW50IHdpdGhpbiB0aGUgYW5vbnltb3VzIHVuaW9uIGluIEV4dGVuc2lvbi4KKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5yZXBlYXRlZF9pbnQzMl92YWx1ZTsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBFbnVtcworCitpbnQgRXh0ZW5zaW9uU2V0OjpHZXRFbnVtKGludCBudW1iZXIsIGludCBkZWZhdWx0X3ZhbHVlKSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIGlmIChpdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpIHx8IGl0ZXItPnNlY29uZC5pc19jbGVhcmVkKSB7CisgICAgLy8gTm90IHByZXNlbnQuICBSZXR1cm4gdGhlIGRlZmF1bHQgdmFsdWUuCisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWU7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgT1BUSU9OQUwsIEVOVU0pOworICAgIHJldHVybiBpdGVyLT5zZWNvbmQuZW51bV92YWx1ZTsKKyAgfQorfQorCit2b2lkIEV4dGVuc2lvblNldDo6U2V0RW51bShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgaW50IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBkZXNjcmlwdG9yLCAmZXh0ZW5zaW9uKSkgeworICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9FTlVNKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIE9QVElPTkFMLCBFTlVNKTsKKyAgfQorICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKKyAgZXh0ZW5zaW9uLT5lbnVtX3ZhbHVlID0gdmFsdWU7Cit9CisKK2ludCBFeHRlbnNpb25TZXQ6OkdldFJlcGVhdGVkRW51bShpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsKKyAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgUkVQRUFURUQsIEVOVU0pOworICByZXR1cm4gaXRlci0+c2Vjb25kLnJlcGVhdGVkX2VudW1fdmFsdWUtPkdldChpbmRleCk7Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpTZXRSZXBlYXRlZEVudW0oaW50IG51bWJlciwgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsKKyAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgUkVQRUFURUQsIEVOVU0pOworICBpdGVyLT5zZWNvbmQucmVwZWF0ZWRfZW51bV92YWx1ZS0+U2V0KGluZGV4LCB2YWx1ZSk7Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpBZGRFbnVtKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBwYWNrZWQsIGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRU5VTSk7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IHRydWU7CisgICAgZXh0ZW5zaW9uLT5pc19wYWNrZWQgPSBwYWNrZWQ7CisgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9lbnVtX3ZhbHVlID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZEZpZWxkPGludD4gPihhcmVuYV8sIGFyZW5hXyk7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIFJFUEVBVEVELCBFTlVNKTsKKyAgICBHT09HTEVfRENIRUNLX0VRKGV4dGVuc2lvbi0+aXNfcGFja2VkLCBwYWNrZWQpOworICB9CisgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZW51bV92YWx1ZS0+QWRkKHZhbHVlKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyaW5ncworCitjb25zdCBzdHJpbmcmIEV4dGVuc2lvblNldDo6R2V0U3RyaW5nKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZGVmYXVsdF92YWx1ZSkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSB8fCBpdGVyLT5zZWNvbmQuaXNfY2xlYXJlZCkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBTVFJJTkcpOworICAgIHJldHVybiAqaXRlci0+c2Vjb25kLnN0cmluZ192YWx1ZTsKKyAgfQorfQorCitzdHJpbmcqIEV4dGVuc2lvblNldDo6TXV0YWJsZVN0cmluZyhpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5zdHJpbmdfdmFsdWUgPSBBcmVuYTo6Q3JlYXRlPHN0cmluZz4oYXJlbmFfKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgT1BUSU9OQUwsIFNUUklORyk7CisgIH0KKyAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgIHJldHVybiBleHRlbnNpb24tPnN0cmluZ192YWx1ZTsKK30KKworY29uc3Qgc3RyaW5nJiBFeHRlbnNpb25TZXQ6OkdldFJlcGVhdGVkU3RyaW5nKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBHT09HTEVfQ0hFQ0soaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkluZGV4IG91dC1vZi1ib3VuZHMgKGZpZWxkIGlzIGVtcHR5KS4iOworICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBSRVBFQVRFRCwgU1RSSU5HKTsKKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5yZXBlYXRlZF9zdHJpbmdfdmFsdWUtPkdldChpbmRleCk7Cit9CisKK3N0cmluZyogRXh0ZW5zaW9uU2V0OjpNdXRhYmxlUmVwZWF0ZWRTdHJpbmcoaW50IG51bWJlciwgaW50IGluZGV4KSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIFJFUEVBVEVELCBTVFJJTkcpOworICByZXR1cm4gaXRlci0+c2Vjb25kLnJlcGVhdGVkX3N0cmluZ192YWx1ZS0+TXV0YWJsZShpbmRleCk7Cit9CisKK3N0cmluZyogRXh0ZW5zaW9uU2V0OjpBZGRTdHJpbmcoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gdHJ1ZTsKKyAgICBleHRlbnNpb24tPmlzX3BhY2tlZCA9IGZhbHNlOworICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZTxSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gPihhcmVuYV8sIGFyZW5hXyk7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIFJFUEVBVEVELCBTVFJJTkcpOworICB9CisgIHJldHVybiBleHRlbnNpb24tPnJlcGVhdGVkX3N0cmluZ192YWx1ZS0+QWRkKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1lc3NhZ2VzCisKK2NvbnN0IE1lc3NhZ2VMaXRlJiBFeHRlbnNpb25TZXQ6OkdldE1lc3NhZ2UoCisgICAgaW50IG51bWJlciwgY29uc3QgTWVzc2FnZUxpdGUmIGRlZmF1bHRfdmFsdWUpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkpIHsKKyAgICAvLyBOb3QgcHJlc2VudC4gIFJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICByZXR1cm4gZGVmYXVsdF92YWx1ZTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBPUFRJT05BTCwgTUVTU0FHRSk7CisgICAgaWYgKGl0ZXItPnNlY29uZC5pc19sYXp5KSB7CisgICAgICByZXR1cm4gaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlLT5HZXRNZXNzYWdlKGRlZmF1bHRfdmFsdWUpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gKml0ZXItPnNlY29uZC5tZXNzYWdlX3ZhbHVlOworICAgIH0KKyAgfQorfQorCisvLyBEZWZpbmVkIGluIGV4dGVuc2lvbl9zZXRfaGVhdnkuY2MuCisvLyBjb25zdCBNZXNzYWdlTGl0ZSYgRXh0ZW5zaW9uU2V0OjpHZXRNZXNzYWdlKGludCBudW1iZXIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIGNvbnN0CisKK01lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6Ok11dGFibGVNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IGZhbHNlOworICAgIGV4dGVuc2lvbi0+aXNfbGF6eSA9IGZhbHNlOworICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9IHByb3RvdHlwZS5OZXcoYXJlbmFfKTsKKyAgICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKKyAgICByZXR1cm4gZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRSgqZXh0ZW5zaW9uLCBPUFRJT05BTCwgTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgICAgaWYgKGV4dGVuc2lvbi0+aXNfbGF6eSkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPk11dGFibGVNZXNzYWdlKHByb3RvdHlwZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWU7CisgICAgfQorICB9Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIE1lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6Ok11dGFibGVNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpCisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpTZXRBbGxvY2F0ZWRNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpIHsKKyAgaWYgKG1lc3NhZ2UgPT0gTlVMTCkgeworICAgIENsZWFyRXh0ZW5zaW9uKG51bWJlcik7CisgICAgcmV0dXJuOworICB9CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBkZXNjcmlwdG9yLCAmZXh0ZW5zaW9uKSkgeworICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgaWYgKG1lc3NhZ2UtPkdldEFyZW5hKCkgPT0gYXJlbmFfKSB7CisgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUgPSBtZXNzYWdlOworICAgIH0gZWxzZSB7CisgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUgPSBtZXNzYWdlLT5OZXcoYXJlbmFfKTsKKyAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZS0+Q2hlY2tUeXBlQW5kTWVyZ2VGcm9tKCptZXNzYWdlKTsKKyAgICAgIGlmIChtZXNzYWdlLT5HZXRBcmVuYSgpID09IE5VTEwpIHsKKyAgICAgICAgZGVsZXRlIG1lc3NhZ2U7CisgICAgICB9CisgICAgfQorICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRSgqZXh0ZW5zaW9uLCBPUFRJT05BTCwgTUVTU0FHRSk7CisgICAgaWYgKGV4dGVuc2lvbi0+aXNfbGF6eSkgeworICAgICAgZXh0ZW5zaW9uLT5sYXp5bWVzc2FnZV92YWx1ZS0+U2V0QWxsb2NhdGVkTWVzc2FnZShtZXNzYWdlKTsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgICAgIGRlbGV0ZSBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWU7CisgICAgICB9CisgICAgICBpZiAobWVzc2FnZS0+R2V0QXJlbmEoKSA9PSBhcmVuYV8pIHsKKyAgICAgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlID0gbWVzc2FnZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9IG1lc3NhZ2UtPk5ldyhhcmVuYV8pOworICAgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgqbWVzc2FnZSk7CisgICAgICAgIGlmIChtZXNzYWdlLT5HZXRBcmVuYSgpID09IE5VTEwpIHsKKyAgICAgICAgICBkZWxldGUgbWVzc2FnZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6UmVsZWFzZU1lc3NhZ2UoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkpIHsKKyAgICAvLyBOb3QgcHJlc2VudC4gIFJldHVybiBOVUxMLgorICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBNRVNTQUdFKTsKKyAgICBNZXNzYWdlTGl0ZSogcmV0ID0gTlVMTDsKKyAgICBpZiAoaXRlci0+c2Vjb25kLmlzX2xhenkpIHsKKyAgICAgIHJldCA9IGl0ZXItPnNlY29uZC5sYXp5bWVzc2FnZV92YWx1ZS0+UmVsZWFzZU1lc3NhZ2UocHJvdG90eXBlKTsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgICBkZWxldGUgaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgICAgcmV0ID0gaXRlci0+c2Vjb25kLm1lc3NhZ2VfdmFsdWU7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBSZWxlYXNlTWVzc2FnZSgpIGFsd2F5cyByZXR1cm5zIGEgaGVhcC1hbGxvY2F0ZWQgbWVzc2FnZSwgYW5kIHdlIGFyZQorICAgICAgICAvLyBvbiBhbiBhcmVuYSwgc28gd2UgbmVlZCB0byBtYWtlIGEgY29weSBvZiB0aGlzIG1lc3NhZ2UgdG8gcmV0dXJuLgorICAgICAgICByZXQgPSAoaXRlci0+c2Vjb25kLm1lc3NhZ2VfdmFsdWUpLT5OZXcoKTsKKyAgICAgICAgcmV0LT5DaGVja1R5cGVBbmRNZXJnZUZyb20oKml0ZXItPnNlY29uZC5tZXNzYWdlX3ZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgZXh0ZW5zaW9uc18uZXJhc2UobnVtYmVyKTsKKyAgICByZXR1cm4gcmV0OworICB9Cit9CisKK01lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6OlVuc2FmZUFyZW5hUmVsZWFzZU1lc3NhZ2UoCisgICAgaW50IG51bWJlciwgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSkgeworICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIE5VTEwuCisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgT1BUSU9OQUwsIE1FU1NBR0UpOworICAgIE1lc3NhZ2VMaXRlKiByZXQgPSBOVUxMOworICAgIGlmIChpdGVyLT5zZWNvbmQuaXNfbGF6eSkgeworICAgICAgcmV0ID0KKyAgICAgICAgaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlLT5VbnNhZmVBcmVuYVJlbGVhc2VNZXNzYWdlKHByb3RvdHlwZSk7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgICAgZGVsZXRlIGl0ZXItPnNlY29uZC5sYXp5bWVzc2FnZV92YWx1ZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgcmV0ID0gaXRlci0+c2Vjb25kLm1lc3NhZ2VfdmFsdWU7CisgICAgfQorICAgIGV4dGVuc2lvbnNfLmVyYXNlKG51bWJlcik7CisgICAgcmV0dXJuIHJldDsKKyAgfQorfQorCisvLyBEZWZpbmVkIGluIGV4dGVuc2lvbl9zZXRfaGVhdnkuY2MuCisvLyBNZXNzYWdlTGl0ZSogRXh0ZW5zaW9uU2V0OjpSZWxlYXNlTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSk7CisKK2NvbnN0IE1lc3NhZ2VMaXRlJiBFeHRlbnNpb25TZXQ6OkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsKKyAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgUkVQRUFURUQsIE1FU1NBR0UpOworICByZXR1cm4gaXRlci0+c2Vjb25kLnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkdldChpbmRleCk7Cit9CisKK01lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6Ok11dGFibGVSZXBlYXRlZE1lc3NhZ2UoaW50IG51bWJlciwgaW50IGluZGV4KSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIFJFUEVBVEVELCBNRVNTQUdFKTsKKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5NdXRhYmxlKGluZGV4KTsKK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6QWRkTWVzc2FnZShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBkZXNjcmlwdG9yLCAmZXh0ZW5zaW9uKSkgeworICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gdHJ1ZTsKKyAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlPFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+ID4oYXJlbmFfLCBhcmVuYV8pOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRSgqZXh0ZW5zaW9uLCBSRVBFQVRFRCwgTUVTU0FHRSk7CisgIH0KKworICAvLyBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiBkb2VzIG5vdCBrbm93IGhvdyB0byBBZGQoKSBzaW5jZSBpdCBjYW5ub3QKKyAgLy8gYWxsb2NhdGUgYW4gYWJzdHJhY3Qgb2JqZWN0LCBzbyB3ZSBoYXZlIHRvIGJlIHRyaWNreS4KKyAgTWVzc2FnZUxpdGUqIHJlc3VsdCA9IGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZQorICAgICAgLT5BZGRGcm9tQ2xlYXJlZDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+ID4oKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgcmVzdWx0ID0gcHJvdG90eXBlLk5ldyhhcmVuYV8pOworICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+QWRkQWxsb2NhdGVkKHJlc3VsdCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6QWRkTWVzc2FnZShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkKKworI3VuZGVmIEdPT0dMRV9EQ0hFQ0tfVFlQRQorCit2b2lkIEV4dGVuc2lvblNldDo6UmVtb3ZlTGFzdChpbnQgbnVtYmVyKSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb24gPSAmaXRlci0+c2Vjb25kOworICBHT09HTEVfRENIRUNLKGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQpOworCisgIHN3aXRjaChjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpKSB7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfaW50MzJfdmFsdWUtPlJlbW92ZUxhc3QoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UNjQ6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2ludDY0X3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfdWludDMyX3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfdWludDY0X3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9mbG9hdF92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2RvdWJsZV92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9CT09MOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9ib29sX3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0VOVU06CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2VudW1fdmFsdWUtPlJlbW92ZUxhc3QoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9zdHJpbmdfdmFsdWUtPlJlbW92ZUxhc3QoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6UmVsZWFzZUxhc3QoaW50IG51bWJlcikgeworICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBHT09HTEVfQ0hFQ0soaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkluZGV4IG91dC1vZi1ib3VuZHMgKGZpZWxkIGlzIGVtcHR5KS4iOworCisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uID0gJml0ZXItPnNlY29uZDsKKyAgR09PR0xFX0RDSEVDSyhleHRlbnNpb24tPmlzX3JlcGVhdGVkKTsKKyAgR09PR0xFX0RDSEVDSyhjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpID09IFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0UpOworICByZXR1cm4gZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5SZWxlYXNlTGFzdCgpOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6U3dhcEVsZW1lbnRzKGludCBudW1iZXIsIGludCBpbmRleDEsIGludCBpbmRleDIpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsKKworICBFeHRlbnNpb24qIGV4dGVuc2lvbiA9ICZpdGVyLT5zZWNvbmQ7CisgIEdPT0dMRV9EQ0hFQ0soZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCk7CisKKyAgc3dpdGNoKGNwcF90eXBlKGV4dGVuc2lvbi0+dHlwZSkpIHsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0lOVDMyOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9pbnQzMl92YWx1ZS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UNjQ6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2ludDY0X3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3VpbnQzMl92YWx1ZS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF91aW50NjRfdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9mbG9hdF92YWx1ZS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9kb3VibGVfdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0JPT0w6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2Jvb2xfdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0VOVU06CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2VudW1fdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgIH0KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEV4dGVuc2lvblNldDo6Q2xlYXIoKSB7CisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKTsgKytpdGVyKSB7CisgICAgaXRlci0+c2Vjb25kLkNsZWFyKCk7CisgIH0KK30KKwordm9pZCBFeHRlbnNpb25TZXQ6Ok1lcmdlRnJvbShjb25zdCBFeHRlbnNpb25TZXQmIG90aGVyKSB7CisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IG90aGVyLmV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBvdGhlci5leHRlbnNpb25zXy5lbmQoKTsgKytpdGVyKSB7CisgICAgY29uc3QgRXh0ZW5zaW9uJiBvdGhlcl9leHRlbnNpb24gPSBpdGVyLT5zZWNvbmQ7CisgICAgSW50ZXJuYWxFeHRlbnNpb25NZXJnZUZyb20oaXRlci0+Zmlyc3QsIG90aGVyX2V4dGVuc2lvbik7CisgIH0KK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OkludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKAorICBpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb24mIG90aGVyX2V4dGVuc2lvbikgeworICBpZiAob3RoZXJfZXh0ZW5zaW9uLmlzX3JlcGVhdGVkKSB7CisgICAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisgICAgYm9vbCBpc19uZXcgPSBNYXliZU5ld0V4dGVuc2lvbihudW1iZXIsIG90aGVyX2V4dGVuc2lvbi5kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmV4dGVuc2lvbik7CisgICAgaWYgKGlzX25ldykgeworICAgICAgLy8gRXh0ZW5zaW9uIGRpZCBub3QgYWxyZWFkeSBleGlzdCBpbiBzZXQuCisgICAgICBleHRlbnNpb24tPnR5cGUgPSBvdGhlcl9leHRlbnNpb24udHlwZTsKKyAgICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gb3RoZXJfZXh0ZW5zaW9uLmlzX3BhY2tlZDsKKyAgICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBHT09HTEVfRENIRUNLX0VRKGV4dGVuc2lvbi0+dHlwZSwgb3RoZXJfZXh0ZW5zaW9uLnR5cGUpOworICAgICAgR09PR0xFX0RDSEVDS19FUShleHRlbnNpb24tPmlzX3BhY2tlZCwgb3RoZXJfZXh0ZW5zaW9uLmlzX3BhY2tlZCk7CisgICAgICBHT09HTEVfRENIRUNLKGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQpOworICAgIH0KKworICAgIHN3aXRjaCAoY3BwX3R5cGUob3RoZXJfZXh0ZW5zaW9uLnR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgTE9XRVJDQVNFLCBSRVBFQVRFRF9UWVBFKSAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKGlzX25ldykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlID0gICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZTxSRVBFQVRFRF9UWVBFID4oYXJlbmFfLCBhcmVuYV8pOyAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+TWVyZ2VGcm9tKCAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ucmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZSk7ICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UMzIsICAgaW50MzIsIFJlcGVhdGVkRmllbGQgICA8ICBpbnQzMj4pOworICAgICAgSEFORExFX1RZUEUoICBJTlQ2NCwgICBpbnQ2NCwgUmVwZWF0ZWRGaWVsZCAgIDwgIGludDY0Pik7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDMyLCAgdWludDMyLCBSZXBlYXRlZEZpZWxkICAgPCB1aW50MzI+KTsKKyAgICAgIEhBTkRMRV9UWVBFKCBVSU5UNjQsICB1aW50NjQsIFJlcGVhdGVkRmllbGQgICA8IHVpbnQ2ND4pOworICAgICAgSEFORExFX1RZUEUoICBGTE9BVCwgICBmbG9hdCwgUmVwZWF0ZWRGaWVsZCAgIDwgIGZsb2F0Pik7CisgICAgICBIQU5ETEVfVFlQRSggRE9VQkxFLCAgZG91YmxlLCBSZXBlYXRlZEZpZWxkICAgPCBkb3VibGU+KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEJPT0wsICAgIGJvb2wsIFJlcGVhdGVkRmllbGQgICA8ICAgYm9vbD4pOworICAgICAgSEFORExFX1RZUEUoICAgRU5VTSwgICAgZW51bSwgUmVwZWF0ZWRGaWVsZCAgIDwgICAgaW50Pik7CisgICAgICBIQU5ETEVfVFlQRSggU1RSSU5HLCAgc3RyaW5nLCBSZXBlYXRlZFB0ckZpZWxkPCBzdHJpbmc+KTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIChpc19uZXcpIHsKKyAgICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUgPQorICAgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlPFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+ID4oYXJlbmFfLCBhcmVuYV8pOworICAgICAgICB9CisgICAgICAgIC8vIFdlIGNhbid0IGNhbGwgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT46Ok1lcmdlRnJvbSgpIGJlY2F1c2UKKyAgICAgICAgLy8gaXQgd291bGQgYXR0ZW1wdCB0byBhbGxvY2F0ZSBuZXcgb2JqZWN0cy4KKyAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT4qIG90aGVyX3JlcGVhdGVkX21lc3NhZ2UgPQorICAgICAgICAgICAgb3RoZXJfZXh0ZW5zaW9uLnJlcGVhdGVkX21lc3NhZ2VfdmFsdWU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb3RoZXJfcmVwZWF0ZWRfbWVzc2FnZS0+c2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgb3RoZXJfbWVzc2FnZSA9IG90aGVyX3JlcGVhdGVkX21lc3NhZ2UtPkdldChpKTsKKyAgICAgICAgICBNZXNzYWdlTGl0ZSogdGFyZ2V0ID0gZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlCisgICAgICAgICAgICAgICAgICAgLT5BZGRGcm9tQ2xlYXJlZDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+ID4oKTsKKyAgICAgICAgICBpZiAodGFyZ2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIHRhcmdldCA9IG90aGVyX21lc3NhZ2UuTmV3KGFyZW5hXyk7CisgICAgICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkFkZEFsbG9jYXRlZCh0YXJnZXQpOworICAgICAgICAgIH0KKyAgICAgICAgICB0YXJnZXQtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbShvdGhlcl9tZXNzYWdlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKCFvdGhlcl9leHRlbnNpb24uaXNfY2xlYXJlZCkgeworICAgICAgc3dpdGNoIChjcHBfdHlwZShvdGhlcl9leHRlbnNpb24udHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UsIENBTUVMQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBTZXQjI0NBTUVMQ0FTRShudW1iZXIsIG90aGVyX2V4dGVuc2lvbi50eXBlLCAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24uTE9XRVJDQVNFIyNfdmFsdWUsICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24uZGVzY3JpcHRvcik7ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBpbnQzMiwgIEludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQsICBJbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyLCBVSW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCwgVUludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoIEZMT0FULCAgZmxvYXQsICBGbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggIEJPT0wsICAgYm9vbCwgICBCb29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgIGVudW0sICAgRW51bSk7CisjdW5kZWYgSEFORExFX1RZUEUKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgICAgU2V0U3RyaW5nKG51bWJlciwgb3RoZXJfZXh0ZW5zaW9uLnR5cGUsCisgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24uc3RyaW5nX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgICAgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICAgICAgICAgIGJvb2wgaXNfbmV3ID0gTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfZXh0ZW5zaW9uLmRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZXh0ZW5zaW9uKTsKKyAgICAgICAgICBpZiAoaXNfbmV3KSB7CisgICAgICAgICAgICBleHRlbnNpb24tPnR5cGUgPSBvdGhlcl9leHRlbnNpb24udHlwZTsKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gb3RoZXJfZXh0ZW5zaW9uLmlzX3BhY2tlZDsKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmIChvdGhlcl9leHRlbnNpb24uaXNfbGF6eSkgeworICAgICAgICAgICAgICBleHRlbnNpb24tPmlzX2xhenkgPSB0cnVlOworICAgICAgICAgICAgICBleHRlbnNpb24tPmxhenltZXNzYWdlX3ZhbHVlID0KKyAgICAgICAgICAgICAgICAgIG90aGVyX2V4dGVuc2lvbi5sYXp5bWVzc2FnZV92YWx1ZS0+TmV3KGFyZW5hXyk7CisgICAgICAgICAgICAgIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPk1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubGF6eW1lc3NhZ2VfdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgICAgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9CisgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZS0+TmV3KGFyZW5hXyk7CisgICAgICAgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZS0+Q2hlY2tUeXBlQW5kTWVyZ2VGcm9tKAorICAgICAgICAgICAgICAgICAgKm90aGVyX2V4dGVuc2lvbi5tZXNzYWdlX3ZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgR09PR0xFX0RDSEVDS19FUShleHRlbnNpb24tPnR5cGUsIG90aGVyX2V4dGVuc2lvbi50eXBlKTsKKyAgICAgICAgICAgIEdPT0dMRV9EQ0hFQ0tfRVEoZXh0ZW5zaW9uLT5pc19wYWNrZWQsb3RoZXJfZXh0ZW5zaW9uLmlzX3BhY2tlZCk7CisgICAgICAgICAgICBHT09HTEVfRENIRUNLKCFleHRlbnNpb24tPmlzX3JlcGVhdGVkKTsKKyAgICAgICAgICAgIGlmIChvdGhlcl9leHRlbnNpb24uaXNfbGF6eSkgeworICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLT5pc19sYXp5KSB7CisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5sYXp5bWVzc2FnZV92YWx1ZS0+TWVyZ2VGcm9tKAorICAgICAgICAgICAgICAgICAgICAqb3RoZXJfZXh0ZW5zaW9uLmxhenltZXNzYWdlX3ZhbHVlKTsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgICAgICAgb3RoZXJfZXh0ZW5zaW9uLmxhenltZXNzYWdlX3ZhbHVlLT5HZXRNZXNzYWdlKAorICAgICAgICAgICAgICAgICAgICAgICAgKmV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLT5pc19sYXp5KSB7CisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5sYXp5bWVzc2FnZV92YWx1ZS0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZSktPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZSk7CisgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlLT5DaGVja1R5cGVBbmRNZXJnZUZyb20oCisgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlN3YXAoRXh0ZW5zaW9uU2V0KiB4KSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IHgtPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICBleHRlbnNpb25zXy5zd2FwKHgtPmV4dGVuc2lvbnNfKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBUT0RPKGNmYWxsaW4sIHJvaGFuYW5pbCk6IFdlIG1heWJlIGFibGUgdG8gb3B0aW1pemUgYSBjYXNlIHdoZXJlIHdlIGFyZQorICAgIC8vIHN3YXBwaW5nIGZyb20gaGVhcCB0byBhcmVuYS1hbGxvY2F0ZWQgZXh0ZW5zaW9uIHNldCwgYnkganVzdCBPd24oKSdpbmcKKyAgICAvLyB0aGUgZXh0ZW5zaW9ucy4KKyAgICBFeHRlbnNpb25TZXQgZXh0ZW5zaW9uX3NldDsKKyAgICBleHRlbnNpb25fc2V0Lk1lcmdlRnJvbSgqeCk7CisgICAgeC0+Q2xlYXIoKTsKKyAgICB4LT5NZXJnZUZyb20oKnRoaXMpOworICAgIENsZWFyKCk7CisgICAgTWVyZ2VGcm9tKGV4dGVuc2lvbl9zZXQpOworICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpTd2FwRXh0ZW5zaW9uKEV4dGVuc2lvblNldCogb3RoZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyKSB7CisgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm47CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIHRoaXNfaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3Igb3RoZXJfaXRlciA9IG90aGVyLT5leHRlbnNpb25zXy5maW5kKG51bWJlcik7CisKKyAgaWYgKHRoaXNfaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSAmJgorICAgICAgb3RoZXJfaXRlciA9PSBvdGhlci0+ZXh0ZW5zaW9uc18uZW5kKCkpIHsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAodGhpc19pdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpICYmCisgICAgICBvdGhlcl9pdGVyICE9IG90aGVyLT5leHRlbnNpb25zXy5lbmQoKSkgeworICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgICB1c2luZyBzdGQ6OnN3YXA7CisgICAgICBzd2FwKHRoaXNfaXRlci0+c2Vjb25kLCBvdGhlcl9pdGVyLT5zZWNvbmQpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBUT0RPKGNmYWxsaW4sIHJvaGFuYW5pbCk6IFdlIGNvdWxkIGZ1cnRoZXIgb3B0aW1pemUgdGhlc2UgY2FzZXMsCisgICAgICAvLyBlc3BlY2lhbGx5IGF2b2lkIGNyZWF0aW9uIG9mIEV4dGVuc2lvblNldCwgYW5kIG1vdmUgTWVyZ2VGcm9tIGxvZ2ljCisgICAgICAvLyBpbnRvIEV4dGVuc2lvbnMgaXRzZWxmICh3aGljaCB0YWtlcyBhcmVuYSBhcyBhbiBhcmd1bWVudCkuCisgICAgICAvLyBXZSBkbyBpdCB0aGlzIHdheSB0byByZXVzZSB0aGUgY29weS1hY3Jvc3MtYXJlbmFzIGxvZ2ljIGFscmVhZHkKKyAgICAgIC8vIGltcGxlbWVudGVkIGluIEV4dGVuc2lvblNldCdzIE1lcmdlRnJvbS4KKyAgICAgIEV4dGVuc2lvblNldCB0ZW1wOworICAgICAgdGVtcC5JbnRlcm5hbEV4dGVuc2lvbk1lcmdlRnJvbShudW1iZXIsIG90aGVyX2l0ZXItPnNlY29uZCk7CisgICAgICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciB0ZW1wX2l0ZXIgPSB0ZW1wLmV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgICAgIG90aGVyX2l0ZXItPnNlY29uZC5DbGVhcigpOworICAgICAgb3RoZXItPkludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKG51bWJlciwgdGhpc19pdGVyLT5zZWNvbmQpOworICAgICAgdGhpc19pdGVyLT5zZWNvbmQuQ2xlYXIoKTsKKyAgICAgIEludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKG51bWJlciwgdGVtcF9pdGVyLT5zZWNvbmQpOworICAgIH0KKyAgICByZXR1cm47CisgIH0KKworICBpZiAodGhpc19pdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpKSB7CisgICAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICAgIGV4dGVuc2lvbnNfLmluc2VydChzdGQ6Om1ha2VfcGFpcihudW1iZXIsIG90aGVyX2l0ZXItPnNlY29uZCkpOworICAgIH0gZWxzZSB7CisgICAgICBJbnRlcm5hbEV4dGVuc2lvbk1lcmdlRnJvbShudW1iZXIsIG90aGVyX2l0ZXItPnNlY29uZCk7CisgICAgfQorICAgIG90aGVyLT5leHRlbnNpb25zXy5lcmFzZShudW1iZXIpOworICAgIHJldHVybjsKKyAgfQorCisgIGlmIChvdGhlcl9pdGVyID09IG90aGVyLT5leHRlbnNpb25zXy5lbmQoKSkgeworICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgICBvdGhlci0+ZXh0ZW5zaW9uc18uaW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKG51bWJlciwgdGhpc19pdGVyLT5zZWNvbmQpKTsKKyAgICB9IGVsc2UgeworICAgICAgb3RoZXItPkludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKG51bWJlciwgdGhpc19pdGVyLT5zZWNvbmQpOworICAgIH0KKyAgICBleHRlbnNpb25zXy5lcmFzZShudW1iZXIpOworICAgIHJldHVybjsKKyAgfQorfQorCitib29sIEV4dGVuc2lvblNldDo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKyAgLy8gRXh0ZW5zaW9ucyBhcmUgbmV2ZXIgcmVxdWlyZWQuICBIb3dldmVyLCB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgYWxsCisgIC8vIGVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBpbml0aWFsaXplZC4KKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBjb25zdCBFeHRlbnNpb24mIGV4dGVuc2lvbiA9IGl0ZXItPnNlY29uZDsKKyAgICBpZiAoY3BwX3R5cGUoZXh0ZW5zaW9uLnR5cGUpID09IFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChleHRlbnNpb24uaXNfcmVwZWF0ZWQpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb24ucmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+c2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICBpZiAoIWV4dGVuc2lvbi5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5HZXQoaSkuSXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoIWV4dGVuc2lvbi5pc19jbGVhcmVkKSB7CisgICAgICAgICAgaWYgKGV4dGVuc2lvbi5pc19sYXp5KSB7CisgICAgICAgICAgICBpZiAoIWV4dGVuc2lvbi5sYXp5bWVzc2FnZV92YWx1ZS0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICghZXh0ZW5zaW9uLm1lc3NhZ2VfdmFsdWUtPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIEV4dGVuc2lvblNldDo6RmluZEV4dGVuc2lvbkluZm9Gcm9tVGFnKAorICAgIHVpbnQzMiB0YWcsIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwgaW50KiBmaWVsZF9udW1iZXIsCisgICAgRXh0ZW5zaW9uSW5mbyogZXh0ZW5zaW9uLCBib29sKiB3YXNfcGFja2VkX29uX3dpcmUpIHsKKyAgKmZpZWxkX251bWJlciA9IFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpOworICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZV90eXBlID0gV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZyk7CisgIHJldHVybiBGaW5kRXh0ZW5zaW9uSW5mb0Zyb21GaWVsZE51bWJlcih3aXJlX3R5cGUsICpmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25fZmluZGVyLCBleHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXNfcGFja2VkX29uX3dpcmUpOworfQorCitib29sIEV4dGVuc2lvblNldDo6RmluZEV4dGVuc2lvbkluZm9Gcm9tRmllbGROdW1iZXIoCisgICAgaW50IHdpcmVfdHlwZSwgaW50IGZpZWxkX251bWJlciwgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgIEV4dGVuc2lvbkluZm8qIGV4dGVuc2lvbiwgYm9vbCogd2FzX3BhY2tlZF9vbl93aXJlKSB7CisgIGlmICghZXh0ZW5zaW9uX2ZpbmRlci0+RmluZChmaWVsZF9udW1iZXIsIGV4dGVuc2lvbikpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgZXhwZWN0ZWRfd2lyZV90eXBlID0KKyAgICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZUZvckZpZWxkVHlwZShyZWFsX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSk7CisKKyAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIHBhY2tlZCBmaWVsZC4KKyAgKndhc19wYWNrZWRfb25fd2lyZSA9IGZhbHNlOworICBpZiAoZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCAmJgorICAgICAgd2lyZV90eXBlID09IFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEICYmCisgICAgICBpc19wYWNrYWJsZShleHBlY3RlZF93aXJlX3R5cGUpKSB7CisgICAgKndhc19wYWNrZWRfb25fd2lyZSA9IHRydWU7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgLy8gT3RoZXJ3aXNlIHRoZSB3aXJlIHR5cGUgbXVzdCBtYXRjaC4KKyAgcmV0dXJuIGV4cGVjdGVkX3dpcmVfdHlwZSA9PSB3aXJlX3R5cGU7Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkU2tpcHBlciogZmllbGRfc2tpcHBlcikgeworICBpbnQgbnVtYmVyOworICBib29sIHdhc19wYWNrZWRfb25fd2lyZTsKKyAgRXh0ZW5zaW9uSW5mbyBleHRlbnNpb247CisgIGlmICghRmluZEV4dGVuc2lvbkluZm9Gcm9tVGFnKAorICAgICAgdGFnLCBleHRlbnNpb25fZmluZGVyLCAmbnVtYmVyLCAmZXh0ZW5zaW9uLCAmd2FzX3BhY2tlZF9vbl93aXJlKSkgeworICAgIHJldHVybiBmaWVsZF9za2lwcGVyLT5Ta2lwRmllbGQoaW5wdXQsIHRhZyk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFBhcnNlRmllbGRXaXRoRXh0ZW5zaW9uSW5mbygKKyAgICAgICAgbnVtYmVyLCB3YXNfcGFja2VkX29uX3dpcmUsIGV4dGVuc2lvbiwgaW5wdXQsIGZpZWxkX3NraXBwZXIpOworICB9Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkV2l0aEV4dGVuc2lvbkluZm8oCisgICAgaW50IG51bWJlciwgYm9vbCB3YXNfcGFja2VkX29uX3dpcmUsIGNvbnN0IEV4dGVuc2lvbkluZm8mIGV4dGVuc2lvbiwKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgRmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKSB7CisgIC8vIEV4cGxpY2l0bHkgbm90IHJlYWQgZXh0ZW5zaW9uLmlzX3BhY2tlZCwgaW5zdGVhZCBjaGVjayB3aGV0aGVyIHRoZSBmaWVsZAorICAvLyB3YXMgZW5jb2RlZCBpbiBwYWNrZWQgZm9ybSBvbiB0aGUgd2lyZS4KKyAgaWYgKHdhc19wYWNrZWRfb25fd2lyZSkgeworICAgIHVpbnQzMiBzaXplOworICAgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmc2l6ZSkpIHJldHVybiBmYWxzZTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBpbnB1dC0+UHVzaExpbWl0KHNpemUpOworCisgICAgc3dpdGNoIChleHRlbnNpb24udHlwZSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENQUF9DQU1FTENBU0UsIENQUF9MT1dFUkNBU0UpICAgICAgICBcCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICB3aGlsZSAoaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBDUFBfTE9XRVJDQVNFIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgaWYgKCFXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgQ1BQX0xPV0VSQ0FTRSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U+KCAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgQWRkIyNDUFBfQ0FNRUxDQVNFKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0UsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uaXNfcGFja2VkLCB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgIEludDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgSW50NjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgVUludDY0LCAgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgSW50MzIsICAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgVUludDMyLCAgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCBVSW50NjQsICB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoU0ZJWEVEMzIsICBJbnQzMiwgICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgIEludDY0LCAgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgRmxvYXQsICAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoICBET1VCTEUsIERvdWJsZSwgIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICBCb29sLCAgICBib29sKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU06CisgICAgICAgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKGV4dGVuc2lvbi5lbnVtX3ZhbGlkaXR5X2NoZWNrLmZ1bmMoCisgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZW51bV92YWxpZGl0eV9jaGVjay5hcmcsIHZhbHVlKSkgeworICAgICAgICAgICAgQWRkRW51bShudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0sIGV4dGVuc2lvbi5pc19wYWNrZWQsCisgICAgICAgICAgICAgICAgICAgIHZhbHVlLCBleHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIEludmFsaWQgdmFsdWUuICBUcmVhdCBhcyB1bmtub3duLgorICAgICAgICAgICAgZmllbGRfc2tpcHBlci0+U2tpcFVua25vd25FbnVtKG51bWJlciwgdmFsdWUpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkc6CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTOgorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUDoKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vbi1wcmltaXRpdmUgdHlwZXMgY2FuJ3QgYmUgcGFja2VkLiI7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGlucHV0LT5Qb3BMaW1pdChsaW1pdCk7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChleHRlbnNpb24udHlwZSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENQUF9DQU1FTENBU0UsIENQUF9MT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENQUF9MT1dFUkNBU0UgdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBDUFBfTE9XRVJDQVNFLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI1VQUEVSQ0FTRT4oICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZXh0ZW5zaW9uLmlzX3JlcGVhdGVkKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBBZGQjI0NQUF9DQU1FTENBU0UobnVtYmVyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI1VQUEVSQ0FTRSwgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbi5pc19wYWNrZWQsIHZhbHVlLCAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgU2V0IyNDUFBfQ0FNRUxDQVNFKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0UsIHZhbHVlLCAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICB9IGJyZWFrCisKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgSW50MzIsICAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoICAgSU5UNjQsICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQzMiwgVUludDMyLCAgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCBVSW50NjQsICB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UMzIsICBJbnQzMiwgICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggIFNJTlQ2NCwgIEludDY0LCAgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCBVSW50MzIsICB1aW50MzIpOworICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgIEludDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCAgSW50NjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICBGbG9hdCwgICBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgRG91YmxlLCAgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgIEJvb2wsICAgIGJvb2wpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTTogeworICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworCisgICAgICAgIGlmICghZXh0ZW5zaW9uLmVudW1fdmFsaWRpdHlfY2hlY2suZnVuYygKKyAgICAgICAgICAgICAgICBleHRlbnNpb24uZW51bV92YWxpZGl0eV9jaGVjay5hcmcsIHZhbHVlKSkgeworICAgICAgICAgIC8vIEludmFsaWQgdmFsdWUuICBUcmVhdCBhcyB1bmtub3duLgorICAgICAgICAgIGZpZWxkX3NraXBwZXItPlNraXBVbmtub3duRW51bShudW1iZXIsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChleHRlbnNpb24uaXNfcmVwZWF0ZWQpIHsKKyAgICAgICAgICBBZGRFbnVtKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTSwgZXh0ZW5zaW9uLmlzX3BhY2tlZCwgdmFsdWUsCisgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgU2V0RW51bShudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0sIHZhbHVlLAorICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX1NUUklORzogIHsKKyAgICAgICAgc3RyaW5nKiB2YWx1ZSA9IGV4dGVuc2lvbi5pc19yZXBlYXRlZCA/CisgICAgICAgICAgQWRkU3RyaW5nKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU1RSSU5HLCBleHRlbnNpb24uZGVzY3JpcHRvcikgOgorICAgICAgICAgIE11dGFibGVTdHJpbmcobnVtYmVyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkcsCisgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CWVRFUzogIHsKKyAgICAgICAgc3RyaW5nKiB2YWx1ZSA9IGV4dGVuc2lvbi5pc19yZXBlYXRlZCA/CisgICAgICAgICAgQWRkU3RyaW5nKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfQllURVMsIGV4dGVuc2lvbi5kZXNjcmlwdG9yKSA6CisgICAgICAgICAgTXV0YWJsZVN0cmluZyhudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTLAorICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpOworICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUDogeworICAgICAgICBNZXNzYWdlTGl0ZSogdmFsdWUgPSBleHRlbnNpb24uaXNfcmVwZWF0ZWQgPworICAgICAgICAgICAgQWRkTWVzc2FnZShudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0dST1VQLAorICAgICAgICAgICAgICAgICAgICAgICAqZXh0ZW5zaW9uLm1lc3NhZ2VfcHJvdG90eXBlLCBleHRlbnNpb24uZGVzY3JpcHRvcikgOgorICAgICAgICAgICAgTXV0YWJsZU1lc3NhZ2UobnVtYmVyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICpleHRlbnNpb24ubWVzc2FnZV9wcm90b3R5cGUsIGV4dGVuc2lvbi5kZXNjcmlwdG9yKTsKKyAgICAgICAgaWYgKCFXaXJlRm9ybWF0TGl0ZTo6UmVhZEdyb3VwKG51bWJlciwgaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFOiB7CisgICAgICAgIE1lc3NhZ2VMaXRlKiB2YWx1ZSA9IGV4dGVuc2lvbi5pc19yZXBlYXRlZCA/CisgICAgICAgICAgICBBZGRNZXNzYWdlKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgKmV4dGVuc2lvbi5tZXNzYWdlX3Byb3RvdHlwZSwgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpIDoKKyAgICAgICAgICAgIE11dGFibGVNZXNzYWdlKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICpleHRlbnNpb24ubWVzc2FnZV9wcm90b3R5cGUsIGV4dGVuc2lvbi5kZXNjcmlwdG9yKTsKKyAgICAgICAgaWYgKCFXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2UoaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSkgeworICBGaWVsZFNraXBwZXIgc2tpcHBlcjsKKyAgR2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyIGZpbmRlcihjb250YWluaW5nX3R5cGUpOworICByZXR1cm4gUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZmluZGVyLCAmc2tpcHBlcik7Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHVua25vd25fZmllbGRzKSB7CisgIENvZGVkT3V0cHV0U3RyZWFtRmllbGRTa2lwcGVyIHNraXBwZXIodW5rbm93bl9maWVsZHMpOworICBHZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXIgZmluZGVyKGNvbnRhaW5pbmdfdHlwZSk7CisgIHJldHVybiBQYXJzZUZpZWxkKHRhZywgaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpCisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIGJvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZU1lc3NhZ2VTZXQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKwordm9pZCBFeHRlbnNpb25TZXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICBpbnQgc3RhcnRfZmllbGRfbnVtYmVyLCBpbnQgZW5kX2ZpZWxkX251bWJlciwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyOworICBmb3IgKGl0ZXIgPSBleHRlbnNpb25zXy5sb3dlcl9ib3VuZChzdGFydF9maWVsZF9udW1iZXIpOworICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkgJiYgaXRlci0+Zmlyc3QgPCBlbmRfZmllbGRfbnVtYmVyOworICAgICAgICsraXRlcikgeworICAgIGl0ZXItPnNlY29uZC5TZXJpYWxpemVGaWVsZFdpdGhDYWNoZWRTaXplcyhpdGVyLT5maXJzdCwgb3V0cHV0KTsKKyAgfQorfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKTsgKytpdGVyKSB7CisgICAgdG90YWxfc2l6ZSArPSBpdGVyLT5zZWNvbmQuQnl0ZVNpemUoaXRlci0+Zmlyc3QpOworICB9CisKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIGludCBFeHRlbnNpb25TZXQ6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdAorCitib29sIEV4dGVuc2lvblNldDo6TWF5YmVOZXdFeHRlbnNpb24oaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uKiogcmVzdWx0KSB7CisgIHBhaXI8bWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IsIGJvb2w+IGluc2VydF9yZXN1bHQgPQorICAgICAgZXh0ZW5zaW9uc18uaW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKG51bWJlciwgRXh0ZW5zaW9uKCkpKTsKKyAgKnJlc3VsdCA9ICZpbnNlcnRfcmVzdWx0LmZpcnN0LT5zZWNvbmQ7CisgICgqcmVzdWx0KS0+ZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgIHJldHVybiBpbnNlcnRfcmVzdWx0LnNlY29uZDsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gTWV0aG9kcyBvZiBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbgorCit2b2lkIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpDbGVhcigpIHsKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgc3dpdGNoIChjcHBfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkNsZWFyKCk7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggIElOVDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UNjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoIFVJTlQzMiwgIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDY0LCAgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRkxPQVQsICAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoIERPVUJMRSwgIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBCT09MLCAgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEVOVU0sICAgIGVudW0pOworICAgICAgSEFORExFX1RZUEUoIFNUUklORywgIHN0cmluZyk7CisgICAgICBIQU5ETEVfVFlQRShNRVNTQUdFLCBtZXNzYWdlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoIWlzX2NsZWFyZWQpIHsKKyAgICAgIHN3aXRjaCAoY3BwX3R5cGUodHlwZSkpIHsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgICAgc3RyaW5nX3ZhbHVlLT5jbGVhcigpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKGlzX2xhenkpIHsKKyAgICAgICAgICAgIGxhenltZXNzYWdlX3ZhbHVlLT5DbGVhcigpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtZXNzYWdlX3ZhbHVlLT5DbGVhcigpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAvLyBObyBuZWVkIHRvIGRvIGFueXRoaW5nLiAgR2V0KigpIHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlCisgICAgICAgICAgLy8gYXMgbG9uZyBhcyBpc19jbGVhcmVkIGlzIHRydWUgYW5kIFNldCooKSB3aWxsIG92ZXJ3cml0ZSB0aGUKKyAgICAgICAgICAvLyBwcmV2aW91cyB2YWx1ZS4KKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgaXNfY2xlYXJlZCA9IHRydWU7CisgICAgfQorICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OlNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzKAorICAgIGludCBudW1iZXIsCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgaWYgKGlzX3BhY2tlZCkgeworICAgICAgaWYgKGNhY2hlZF9zaXplID09IDApIHJldHVybjsKKworICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlVGFnKG51bWJlciwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihjYWNoZWRfc2l6ZSk7CisKKyAgICAgIHN3aXRjaCAocmVhbF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPnNpemUoKTsgaSsrKSB7ICBcCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI0NBTUVMQ0FTRSMjTm9UYWcoICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5HZXQoaSksIG91dHB1dCk7ICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWsKKworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQ2NCwgICAgSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQzMiwgICBVSW50MzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQzMiwgICBTSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQ2NCwgICBTSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICAgZmxvYXQpOworICAgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgICBEb3VibGUsICBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgIGJvb2wpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgIGVudW0pOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkc6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfQllURVM6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfR1JPVVA6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm9uLXByaW1pdGl2ZSB0eXBlcyBjYW4ndCBiZSBwYWNrZWQuIjsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgc3dpdGNoIChyZWFsX3R5cGUodHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyBpKyspIHsgIFwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjQ0FNRUxDQVNFKG51bWJlciwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkdldChpKSwgb3V0cHV0KTsgICAgICAgICAgICAgICAgXAorICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgICBJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDMyLCAgIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCAgIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDY0LCAgIFNJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCAgRml4ZWQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCBTRml4ZWQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgICBGbG9hdCwgICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSwgIGRvdWJsZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgICAgQm9vbCwgICAgYm9vbCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU1RSSU5HLCAgIFN0cmluZywgIHN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEJZVEVTLCAgICBCeXRlcywgIHN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBFTlVNLCAgICAgRW51bSwgICAgZW51bSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEdST1VQLCAgICBHcm91cCwgbWVzc2FnZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCBNRVNTQUdFLCAgTWVzc2FnZSwgbWVzc2FnZSk7CisjdW5kZWYgSEFORExFX1RZUEUKKyAgICAgIH0KKyAgICB9CisgIH0gZWxzZSBpZiAoIWlzX2NsZWFyZWQpIHsKKyAgICBzd2l0Y2ggKHJlYWxfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENBTUVMQ0FTRSwgVkFMVUUpICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlIyNDQU1FTENBU0UobnVtYmVyLCBWQUxVRSwgb3V0cHV0KTsgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgIGludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICAgaW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgIHVpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICAgdWludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICAgaW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgICBpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICAgdWludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCwgICB1aW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoU0ZJWEVEMzIsIFNGaXhlZDMyLCAgICBpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgIGludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgICBGbG9hdCwgICAgZmxvYXRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBET1VCTEUsICAgRG91YmxlLCAgIGRvdWJsZV92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgICBib29sX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU1RSSU5HLCAgIFN0cmluZywgICpzdHJpbmdfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgQllURVMsICAgIEJ5dGVzLCAgKnN0cmluZ192YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgICBlbnVtX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEdST1VQLCAgICBHcm91cCwgKm1lc3NhZ2VfdmFsdWUpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIChpc19sYXp5KSB7CisgICAgICAgICAgbGF6eW1lc3NhZ2VfdmFsdWUtPldyaXRlTWVzc2FnZShudW1iZXIsIG91dHB1dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZShudW1iZXIsICptZXNzYWdlX3ZhbHVlLCBvdXRwdXQpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OkJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0IHsKKyAgaW50IHJlc3VsdCA9IDA7CisKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgaWYgKGlzX3BhY2tlZCkgeworICAgICAgc3dpdGNoIChyZWFsX3R5cGUodHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyBpKyspIHsgIFwKKyAgICAgICAgICAgIHJlc3VsdCArPSBXaXJlRm9ybWF0TGl0ZTo6Q0FNRUxDQVNFIyNTaXplKCAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkdldChpKSk7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgICBJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDMyLCAgIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCAgIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDY0LCAgIFNJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBFTlVNLCAgICAgRW51bSwgICAgZW51bSk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgICAvLyBTdHVmZiB3aXRoIGZpeGVkIHNpemUuCisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZXN1bHQgKz0gV2lyZUZvcm1hdExpdGU6OmsjI0NBTUVMQ0FTRSMjU2l6ZSAqICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPnNpemUoKTsgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGJyZWFrCisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCAgRml4ZWQzMiwgdWludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsICBGaXhlZDY0LCB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIsICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCBTRml4ZWQ2NCwgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICAgIEZsb2F0LCAgZmxvYXQpOworICAgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgICBEb3VibGUsIGRvdWJsZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgICAgQm9vbCwgICBib29sKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfU1RSSU5HOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0dST1VQOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0U6CisgICAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vbi1wcmltaXRpdmUgdHlwZXMgY2FuJ3QgYmUgcGFja2VkLiI7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhY2hlZF9zaXplID0gcmVzdWx0OworICAgICAgaWYgKHJlc3VsdCA+IDApIHsKKyAgICAgICAgcmVzdWx0ICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKG51bWJlciwKKyAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpbnQgdGFnX3NpemUgPSBXaXJlRm9ybWF0TGl0ZTo6VGFnU2l6ZShudW1iZXIsIHJlYWxfdHlwZSh0eXBlKSk7CisKKyAgICAgIHN3aXRjaCAocmVhbF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZXN1bHQgKz0gdGFnX3NpemUgKiByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCk7ICAgICAgICBcCisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCk7IGkrKykgeyAgXAorICAgICAgICAgICAgcmVzdWx0ICs9IFdpcmVGb3JtYXRMaXRlOjpDQU1FTENBU0UjI1NpemUoICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+R2V0KGkpKTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGJyZWFrCisKKyAgICAgICAgSEFORExFX1RZUEUoICAgSU5UMzIsICAgIEludDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgSU5UNjQsICAgIEludDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgdWludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBVSU5UNjQsICAgVUludDY0LCAgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTSU5UMzIsICAgU0ludDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTVFJJTkcsICAgU3RyaW5nLCAgc3RyaW5nKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgQllURVMsICAgIEJ5dGVzLCAgc3RyaW5nKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgIEVOVU0sICAgICBFbnVtLCAgICBlbnVtKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgR1JPVVAsICAgIEdyb3VwLCBtZXNzYWdlKTsKKyAgICAgICAgSEFORExFX1RZUEUoIE1FU1NBR0UsICBNZXNzYWdlLCBtZXNzYWdlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICAgIC8vIFN0dWZmIHdpdGggZml4ZWQgc2l6ZS4KKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlc3VsdCArPSAodGFnX3NpemUgKyBXaXJlRm9ybWF0TGl0ZTo6ayMjQ0FNRUxDQVNFIyNTaXplKSAqICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWsKKyAgICAgICAgSEFORExFX1RZUEUoIEZJWEVEMzIsICBGaXhlZDMyLCB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMiwgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoU0ZJWEVENjQsIFNGaXhlZDY0LCAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSwgZG91YmxlKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgIEJPT0wsICAgICBCb29sLCAgIGJvb2wpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICB9CisgICAgfQorICB9IGVsc2UgaWYgKCFpc19jbGVhcmVkKSB7CisgICAgcmVzdWx0ICs9IFdpcmVGb3JtYXRMaXRlOjpUYWdTaXplKG51bWJlciwgcmVhbF90eXBlKHR5cGUpKTsKKyAgICBzd2l0Y2ggKHJlYWxfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENBTUVMQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgcmVzdWx0ICs9IFdpcmVGb3JtYXRMaXRlOjpDQU1FTENBU0UjI1NpemUoTE9XRVJDQVNFKTsgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgIGludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICAgaW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgIHVpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICAgdWludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICAgaW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgICBpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFNUUklORywgICBTdHJpbmcsICAqc3RyaW5nX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEJZVEVTLCAgICBCeXRlcywgICpzdHJpbmdfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgIEVOVU0sICAgICBFbnVtLCAgICAgZW51bV92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBHUk9VUCwgICAgR3JvdXAsICptZXNzYWdlX3ZhbHVlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFOiB7CisgICAgICAgIGlmIChpc19sYXp5KSB7CisgICAgICAgICAgaW50IHNpemUgPSBsYXp5bWVzc2FnZV92YWx1ZS0+Qnl0ZVNpemUoKTsKKyAgICAgICAgICByZXN1bHQgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoc2l6ZSkgKyBzaXplOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdCArPSBXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemUoKm1lc3NhZ2VfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBTdHVmZiB3aXRoIGZpeGVkIHNpemUuCisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICByZXN1bHQgKz0gV2lyZUZvcm1hdExpdGU6OmsjI0NBTUVMQ0FTRSMjU2l6ZTsgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrCisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIpOworICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsICBGaXhlZDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMik7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQpOworICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICAgIEZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW50IEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpHZXRTaXplKCkgY29uc3QgeworICBHT09HTEVfRENIRUNLKGlzX3JlcGVhdGVkKTsKKyAgc3dpdGNoIChjcHBfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCkKKworICAgIEhBTkRMRV9UWVBFKCAgSU5UMzIsICAgaW50MzIpOworICAgIEhBTkRMRV9UWVBFKCAgSU5UNjQsICAgaW50NjQpOworICAgIEhBTkRMRV9UWVBFKCBVSU5UMzIsICB1aW50MzIpOworICAgIEhBTkRMRV9UWVBFKCBVSU5UNjQsICB1aW50NjQpOworICAgIEhBTkRMRV9UWVBFKCAgRkxPQVQsICAgZmxvYXQpOworICAgIEhBTkRMRV9UWVBFKCBET1VCTEUsICBkb3VibGUpOworICAgIEhBTkRMRV9UWVBFKCAgIEJPT0wsICAgIGJvb2wpOworICAgIEhBTkRMRV9UWVBFKCAgIEVOVU0sICAgIGVudW0pOworICAgIEhBTkRMRV9UWVBFKCBTVFJJTkcsICBzdHJpbmcpOworICAgIEhBTkRMRV9UWVBFKE1FU1NBR0UsIG1lc3NhZ2UpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIDA7Cit9CisKKy8vIFRoaXMgZnVuY3Rpb24gZGVsZXRlcyBhbGwgYWxsb2NhdGVkIG9iamVjdHMuIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIG9ubHkKKy8vIGNhbGxlZCBpZiB0aGUgRXh0ZW5zaW9uIHdhcyBjcmVhdGVkIHdpdGggYW4gYXJlbmEuCit2b2lkIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpGcmVlKCkgeworICBpZiAoaXNfcmVwZWF0ZWQpIHsKKyAgICBzd2l0Y2ggKGNwcF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZGVsZXRlIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrCisKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UMzIsICAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoICBJTlQ2NCwgICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDMyLCAgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBVSU5UNjQsICB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoICBGTE9BVCwgICBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRSggRE9VQkxFLCAgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEJPT0wsICAgIGJvb2wpOworICAgICAgSEFORExFX1RZUEUoICAgRU5VTSwgICAgZW51bSk7CisgICAgICBIQU5ETEVfVFlQRSggU1RSSU5HLCAgc3RyaW5nKTsKKyAgICAgIEhBTkRMRV9UWVBFKE1FU1NBR0UsIG1lc3NhZ2UpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoY3BwX3R5cGUodHlwZSkpIHsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICBkZWxldGUgc3RyaW5nX3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKGlzX2xhenkpIHsKKyAgICAgICAgICBkZWxldGUgbGF6eW1lc3NhZ2VfdmFsdWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZGVsZXRlIG1lc3NhZ2VfdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gaW50IEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBEZWZhdWx0IHJlcGVhdGVkIGZpZWxkIGluc3RhbmNlcyBmb3IgaXRlcmF0b3ItY29tcGF0aWJsZSBhY2Nlc3NvcnMKKworY29uc3QgUmVwZWF0ZWRTdHJpbmdUeXBlVHJhaXRzOjpSZXBlYXRlZEZpZWxkVHlwZSoKK1JlcGVhdGVkU3RyaW5nVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF8gPSBOVUxMOworCitjb25zdCBSZXBlYXRlZE1lc3NhZ2VHZW5lcmljVHlwZVRyYWl0czo6UmVwZWF0ZWRGaWVsZFR5cGUqCitSZXBlYXRlZE1lc3NhZ2VHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF8gPSBOVUxMOworCisjZGVmaW5lIFBST1RPQlVGX0RFRklORV9ERUZBVUxUX1JFUEVBVEVEKFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNvbnN0IFJlcGVhdGVkRmllbGQ8VFlQRT4qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXyMjVFlQRSMjXyA9IE5VTEw7CisKK1BST1RPQlVGX0RFRklORV9ERUZBVUxUX1JFUEVBVEVEKGludDMyKQorUFJPVE9CVUZfREVGSU5FX0RFRkFVTFRfUkVQRUFURUQoaW50NjQpCitQUk9UT0JVRl9ERUZJTkVfREVGQVVMVF9SRVBFQVRFRCh1aW50MzIpCitQUk9UT0JVRl9ERUZJTkVfREVGQVVMVF9SRVBFQVRFRCh1aW50NjQpCitQUk9UT0JVRl9ERUZJTkVfREVGQVVMVF9SRVBFQVRFRChkb3VibGUpCitQUk9UT0JVRl9ERUZJTkVfREVGQVVMVF9SRVBFQVRFRChmbG9hdCkKK1BST1RPQlVGX0RFRklORV9ERUZBVUxUX1JFUEVBVEVEKGJvb2wpCisKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfREVGQVVMVF9SRVBFQVRFRAorCitzdHJ1Y3QgU3RhdGljRGVmYXVsdFJlcGVhdGVkRmllbGRzSW5pdGlhbGl6ZXIgeworICBTdGF0aWNEZWZhdWx0UmVwZWF0ZWRGaWVsZHNJbml0aWFsaXplcigpIHsKKyAgICBJbml0aWFsaXplRGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgICAgT25TaHV0ZG93bigmRGVzdHJveURlZmF1bHRSZXBlYXRlZEZpZWxkcyk7CisgIH0KK30gc3RhdGljX3JlcGVhdGVkX2ZpZWxkc19pbml0aWFsaXplcjsKKwordm9pZCBJbml0aWFsaXplRGVmYXVsdFJlcGVhdGVkRmllbGRzKCkgeworICBSZXBlYXRlZFN0cmluZ1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfID0KKyAgICAgIG5ldyBSZXBlYXRlZFN0cmluZ1R5cGVUcmFpdHM6OlJlcGVhdGVkRmllbGRUeXBlOworICBSZXBlYXRlZE1lc3NhZ2VHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF8gPQorICAgICAgbmV3IFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpSZXBlYXRlZEZpZWxkVHlwZTsKKyAgUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQzMl8gPQorICAgICAgbmV3IFJlcGVhdGVkRmllbGQ8aW50MzI+OworICBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2ludDY0XyA9CisgICAgICBuZXcgUmVwZWF0ZWRGaWVsZDxpbnQ2ND47CisgIFJlcGVhdGVkUHJpbWl0aXZlR2VuZXJpY1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfdWludDMyXyA9CisgICAgICBuZXcgUmVwZWF0ZWRGaWVsZDx1aW50MzI+OworICBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQ2NF8gPQorICAgICAgbmV3IFJlcGVhdGVkRmllbGQ8dWludDY0PjsKKyAgUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9kb3VibGVfID0KKyAgICAgIG5ldyBSZXBlYXRlZEZpZWxkPGRvdWJsZT47CisgIFJlcGVhdGVkUHJpbWl0aXZlR2VuZXJpY1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfZmxvYXRfID0KKyAgICAgIG5ldyBSZXBlYXRlZEZpZWxkPGZsb2F0PjsKKyAgUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9ib29sXyA9CisgICAgICBuZXcgUmVwZWF0ZWRGaWVsZDxib29sPjsKK30KKwordm9pZCBEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCkgeworICBkZWxldGUgUmVwZWF0ZWRTdHJpbmdUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXzsKKyAgZGVsZXRlIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXzsKKyAgZGVsZXRlIFJlcGVhdGVkUHJpbWl0aXZlR2VuZXJpY1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfaW50MzJfOworICBkZWxldGUgUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQ2NF87CisgIGRlbGV0ZSBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQzMl87CisgIGRlbGV0ZSBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQ2NF87CisgIGRlbGV0ZSBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2RvdWJsZV87CisgIGRlbGV0ZSBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2Zsb2F0XzsKKyAgZGVsZXRlIFJlcGVhdGVkUHJpbWl0aXZlR2VuZXJpY1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfYm9vbF87Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkNjcwMmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaApAQCAtMCwwICsxLDEyNDQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGhlYWRlciBpcyBsb2dpY2FsbHkgaW50ZXJuYWwsIGJ1dCBpcyBtYWRlIHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQKKy8vIGZyb20gcHJvdG9jb2wtY29tcGlsZXItZ2VuZXJhdGVkIGNvZGUsIHdoaWNoIG1heSByZXNpZGUgaW4gb3RoZXIgY29tcG9uZW50cy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX1NFVF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9TRVRfSF9fCisKKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8c3RyaW5nPgorCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIGNsYXNzIEFyZW5hOworICBjbGFzcyBEZXNjcmlwdG9yOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBjbGFzcyBGaWVsZERlc2NyaXB0b3I7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBjbGFzcyBEZXNjcmlwdG9yUG9vbDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBjbGFzcyBNZXNzYWdlTGl0ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1lc3NhZ2VfbGl0ZS5oCisgIGNsYXNzIE1lc3NhZ2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZS5oCisgIGNsYXNzIE1lc3NhZ2VGYWN0b3J5OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZS5oCisgIGNsYXNzIFVua25vd25GaWVsZFNldDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdW5rbm93bl9maWVsZF9zZXQuaAorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIENvZGVkSW5wdXRTdHJlYW07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29kZWRfc3RyZWFtLmgKKyAgICBjbGFzcyBDb2RlZE91dHB1dFN0cmVhbTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCisgIH0KKyAgbmFtZXNwYWNlIGludGVybmFsIHsKKyAgICBjbGFzcyBGaWVsZFNraXBwZXI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpcmVfZm9ybWF0X2xpdGUuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBVc2VkIHRvIHN0b3JlIHZhbHVlcyBvZiB0eXBlIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgd2l0aG91dCBoYXZpbmcgdG8KKy8vICNpbmNsdWRlIHdpcmVfZm9ybWF0X2xpdGUuaC4gIEFsc28sIGVuc3VyZXMgdGhhdCB3ZSB1c2Ugb25seSBvbmUgYnl0ZSB0bworLy8gc3RvcmUgdGhlc2UgdmFsdWVzLCB3aGljaCBpcyBpbXBvcnRhbnQgdG8ga2VlcCB0aGUgbGF5b3V0IG9mCisvLyBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbiBzbWFsbC4KK3R5cGVkZWYgdWludDggRmllbGRUeXBlOworCisvLyBBIGZ1bmN0aW9uIHdoaWNoLCBnaXZlbiBhbiBpbnRlZ2VyIHZhbHVlLCByZXR1cm5zIHRydWUgaWYgdGhlIG51bWJlcgorLy8gbWF0Y2hlcyBvbmUgb2YgdGhlIGRlZmluZWQgdmFsdWVzIGZvciB0aGUgY29ycmVzcG9uZGluZyBlbnVtIHR5cGUuICBUaGlzCisvLyBpcyB1c2VkIHdpdGggUmVnaXN0ZXJFbnVtRXh0ZW5zaW9uLCBiZWxvdy4KK3R5cGVkZWYgYm9vbCBFbnVtVmFsaWRpdHlGdW5jKGludCBudW1iZXIpOworCisvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aGljaCB0YWtlcyBhbiBhcmd1bWVudC4gIFRoaXMgaXMgbmVlZGVkIHRvIGRlYWwgd2l0aAorLy8gZXh0ZW5zaW9ucyB0aGF0IGFyZSBub3QgY29tcGlsZWQgaW4uCit0eXBlZGVmIGJvb2wgRW51bVZhbGlkaXR5RnVuY1dpdGhBcmcoY29uc3Qgdm9pZCogYXJnLCBpbnQgbnVtYmVyKTsKKworLy8gSW5mb3JtYXRpb24gYWJvdXQgYSByZWdpc3RlcmVkIGV4dGVuc2lvbi4KK3N0cnVjdCBFeHRlbnNpb25JbmZvIHsKKyAgaW5saW5lIEV4dGVuc2lvbkluZm8oKSB7fQorICBpbmxpbmUgRXh0ZW5zaW9uSW5mbyhGaWVsZFR5cGUgdHlwZV9wYXJhbSwgYm9vbCBpc3JlcGVhdGVkLCBib29sIGlzcGFja2VkKQorICAgICAgOiB0eXBlKHR5cGVfcGFyYW0pLCBpc19yZXBlYXRlZChpc3JlcGVhdGVkKSwgaXNfcGFja2VkKGlzcGFja2VkKSwKKyAgICAgICAgZGVzY3JpcHRvcihOVUxMKSB7fQorCisgIEZpZWxkVHlwZSB0eXBlOworICBib29sIGlzX3JlcGVhdGVkOworICBib29sIGlzX3BhY2tlZDsKKworICBzdHJ1Y3QgRW51bVZhbGlkaXR5Q2hlY2sgeworICAgIEVudW1WYWxpZGl0eUZ1bmNXaXRoQXJnKiBmdW5jOworICAgIGNvbnN0IHZvaWQqIGFyZzsKKyAgfTsKKworICB1bmlvbiB7CisgICAgRW51bVZhbGlkaXR5Q2hlY2sgZW51bV92YWxpZGl0eV9jaGVjazsKKyAgICBjb25zdCBNZXNzYWdlTGl0ZSogbWVzc2FnZV9wcm90b3R5cGU7CisgIH07CisKKyAgLy8gVGhlIGRlc2NyaXB0b3IgZm9yIHRoaXMgZXh0ZW5zaW9uLCBpZiBvbmUgZXhpc3RzIGFuZCBpcyBrbm93bi4gIE1heSBiZQorICAvLyBOVUxMLiAgTXVzdCBub3QgYmUgTlVMTCBpZiB0aGUgZGVzY3JpcHRvciBmb3IgdGhlIGV4dGVuc2lvbiBkb2VzIG5vdAorICAvLyBsaXZlIGluIHRoZSBzYW1lIHBvb2wgYXMgdGhlIGRlc2NyaXB0b3IgZm9yIHRoZSBjb250YWluaW5nIHR5cGUuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcjsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYW4gb2JqZWN0IHdoaWNoIGxvb2tzIHVwIGV4dGVuc2lvbiBkZWZpbml0aW9ucy4gIFVzZWQKKy8vIHdoZW4gcGFyc2luZy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBFeHRlbnNpb25GaW5kZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+RXh0ZW5zaW9uRmluZGVyKCk7CisKKyAgLy8gRmluZCB0aGUgZXh0ZW5zaW9uIHdpdGggdGhlIGdpdmVuIGNvbnRhaW5pbmcgdHlwZSBhbmQgbnVtYmVyLgorICB2aXJ0dWFsIGJvb2wgRmluZChpbnQgbnVtYmVyLCBFeHRlbnNpb25JbmZvKiBvdXRwdXQpID0gMDsKK307CisKKy8vIEltcGxlbWVudGF0aW9uIG9mIEV4dGVuc2lvbkZpbmRlciB3aGljaCBmaW5kcyBleHRlbnNpb25zIGRlZmluZWQgaW4gLnByb3RvCisvLyBmaWxlcyB3aGljaCBoYXZlIGJlZW4gY29tcGlsZWQgaW50byB0aGUgYmluYXJ5LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEdlbmVyYXRlZEV4dGVuc2lvbkZpbmRlciA6IHB1YmxpYyBFeHRlbnNpb25GaW5kZXIgeworIHB1YmxpYzoKKyAgR2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyKGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUpCisgICAgICA6IGNvbnRhaW5pbmdfdHlwZV8oY29udGFpbmluZ190eXBlKSB7fQorICB2aXJ0dWFsIH5HZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXIoKSB7fQorCisgIC8vIFJldHVybnMgdHJ1ZSBhbmQgZmlsbHMgaW4gKm91dHB1dCBpZiBmb3VuZCwgb3RoZXJ3aXNlIHJldHVybnMgZmFsc2UuCisgIHZpcnR1YWwgYm9vbCBGaW5kKGludCBudW1iZXIsIEV4dGVuc2lvbkluZm8qIG91dHB1dCk7CisKKyBwcml2YXRlOgorICBjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlXzsKK307CisKKy8vIEEgRmllbGRTa2lwcGVyIHVzZWQgZm9yIHBhcnNpbmcgTWVzc2FnZVNldC4KK2NsYXNzIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXI7CisKKy8vIE5vdGU6ICBleHRlbnNpb25fc2V0X2hlYXZ5LmNjIGRlZmluZXMgRGVzY3JpcHRvclBvb2xFeHRlbnNpb25GaW5kZXIgZm9yCisvLyBmaW5kaW5nIGV4dGVuc2lvbnMgZnJvbSBhIERlc2NyaXB0b3JQb29sLgorCisvLyBUaGlzIGlzIGFuIGludGVybmFsIGhlbHBlciBjbGFzcyBpbnRlbmRlZCBmb3IgdXNlIHdpdGhpbiB0aGUgcHJvdG9jb2wgYnVmZmVyCisvLyBsaWJyYXJ5IGFuZCBnZW5lcmF0ZWQgY2xhc3Nlcy4gIENsaWVudHMgc2hvdWxkIG5vdCB1c2UgaXQgZGlyZWN0bHkuICBJbnN0ZWFkLAorLy8gdXNlIHRoZSBnZW5lcmF0ZWQgYWNjZXNzb3JzIHN1Y2ggYXMgR2V0RXh0ZW5zaW9uKCkgb2YgdGhlIGNsYXNzIGJlaW5nCisvLyBleHRlbmRlZC4KKy8vCisvLyBUaGlzIGNsYXNzIG1hbmFnZXMgZXh0ZW5zaW9ucyBmb3IgYSBwcm90b2NvbCBtZXNzYWdlIG9iamVjdC4gIFRoZQorLy8gbWVzc2FnZSdzIEhhc0V4dGVuc2lvbigpLCBHZXRFeHRlbnNpb24oKSwgTXV0YWJsZUV4dGVuc2lvbigpLCBhbmQKKy8vIENsZWFyRXh0ZW5zaW9uKCkgbWV0aG9kcyBhcmUganVzdCB0aGluIHdyYXBwZXJzIGFyb3VuZCB0aGUgZW1iZWRkZWQKKy8vIEV4dGVuc2lvblNldC4gIFdoZW4gcGFyc2luZywgaWYgYSB0YWcgbnVtYmVyIGlzIGVuY291bnRlcmVkIHdoaWNoIGlzCisvLyBpbnNpZGUgb25lIG9mIHRoZSBtZXNzYWdlIHR5cGUncyBleHRlbnNpb24gcmFuZ2VzLCB0aGUgdGFnIGlzIHBhc3NlZAorLy8gb2ZmIHRvIHRoZSBFeHRlbnNpb25TZXQgZm9yIHBhcnNpbmcuICBFdGMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRXh0ZW5zaW9uU2V0IHsKKyBwdWJsaWM6CisgIEV4dGVuc2lvblNldCgpOworICBleHBsaWNpdCBFeHRlbnNpb25TZXQoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworICB+RXh0ZW5zaW9uU2V0KCk7CisKKyAgLy8gVGhlc2UgYXJlIGNhbGxlZCBhdCBzdGFydHVwIGJ5IHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZCBjb2RlIHRvCisgIC8vIHJlZ2lzdGVyIGtub3duIGV4dGVuc2lvbnMuICBUaGUgcmVnaXN0cmF0aW9ucyBhcmUgdXNlZCBieSBQYXJzZUZpZWxkKCkKKyAgLy8gdG8gbG9vayB1cCBleHRlbnNpb25zIGZvciBwYXJzZWQgZmllbGQgbnVtYmVycy4gIE5vdGUgdGhhdCBkeW5hbWljIHBhcnNpbmcKKyAgLy8gZG9lcyBub3QgdXNlIFBhcnNlRmllbGQoKTsgb25seSBwcm90b2NvbC1jb21waWxlci1nZW5lcmF0ZWQgcGFyc2luZworICAvLyBtZXRob2RzIGRvLgorICBzdGF0aWMgdm9pZCBSZWdpc3RlckV4dGVuc2lvbihjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19yZXBlYXRlZCwgYm9vbCBpc19wYWNrZWQpOworICBzdGF0aWMgdm9pZCBSZWdpc3RlckVudW1FeHRlbnNpb24oY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19yZXBlYXRlZCwgYm9vbCBpc19wYWNrZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsaWRpdHlGdW5jKiBpc192YWxpZCk7CisgIHN0YXRpYyB2b2lkIFJlZ2lzdGVyTWVzc2FnZUV4dGVuc2lvbihjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3JlcGVhdGVkLCBib29sIGlzX3BhY2tlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBwcm90b3R5cGUpOworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgLy8gQWRkIGFsbCBmaWVsZHMgd2hpY2ggYXJlIGN1cnJlbnRseSBwcmVzZW50IHRvIHRoZSBnaXZlbiB2ZWN0b3IuICBUaGlzCisgIC8vIGlzIHVzZWZ1bCB0byBpbXBsZW1lbnQgUmVmbGVjdGlvbjo6TGlzdEZpZWxkcygpLgorICB2b2lkIEFwcGVuZFRvTGlzdChjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogb3V0cHV0KSBjb25zdDsKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBBY2Nlc3NvcnMKKyAgLy8KKyAgLy8gR2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3NlcyBpbmNsdWRlIHR5cGUtc2FmZSB0ZW1wbGF0ZWQgd3JhcHBlcnMgYXJvdW5kCisgIC8vIHRoZXNlIG1ldGhvZHMuICBHZW5lcmFsbHkgeW91IHNob3VsZCB1c2UgdGhvc2UgcmF0aGVyIHRoYW4gY2FsbCB0aGVzZQorICAvLyBkaXJlY3RseSwgdW5sZXNzIHlvdSBhcmUgZG9pbmcgbG93LWxldmVsIG1lbW9yeSBtYW5hZ2VtZW50LgorICAvLworICAvLyBXaGVuIGNhbGxpbmcgYW55IG9mIHRoZXNlIGFjY2Vzc29ycywgdGhlIGV4dGVuc2lvbiBudW1iZXIgcmVxdWVzdGVkCisgIC8vIE1VU1QgZXhpc3QgaW4gdGhlIERlc2NyaXB0b3JQb29sIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci4gIE90aGVyaXdzZSwKKyAgLy8gdGhlIG1ldGhvZCB3aWxsIGZhaWwgYW4gYXNzZXJ0LiAgTm9ybWFsbHksIHRob3VnaCwgeW91IHdvdWxkIG5vdCBjYWxsCisgIC8vIHRoZXNlIGRpcmVjdGx5OyB5b3Ugd291bGQgZWl0aGVyIGNhbGwgdGhlIGdlbmVyYXRlZCBhY2Nlc3NvcnMgb2YgeW91cgorICAvLyBtZXNzYWdlIGNsYXNzIChlLmcuIEdldEV4dGVuc2lvbigpKSBvciB5b3Ugd291bGQgY2FsbCB0aGUgYWNjZXNzb3JzCisgIC8vIG9mIHRoZSByZWZsZWN0aW9uIGludGVyZmFjZS4gIEluIGJvdGggY2FzZXMsIGl0IGlzIGltcG9zc2libGUgdG8KKyAgLy8gdHJpZ2dlciB0aGlzIGFzc2VydCBmYWlsdXJlOiAgdGhlIGdlbmVyYXRlZCBhY2Nlc3NvcnMgb25seSBhY2NlcHQKKyAgLy8gbGlua2VkLWluIGV4dGVuc2lvbiB0eXBlcyBhcyBwYXJhbWV0ZXJzLCB3aGlsZSB0aGUgUmVmbGVjdGlvbiBpbnRlcmZhY2UKKyAgLy8gcmVxdWlyZXMgeW91IHRvIHByb3ZpZGUgdGhlIEZpZWxkRGVzY3JpcHRvciBkZXNjcmliaW5nIHRoZSBleHRlbnNpb24uCisgIC8vCisgIC8vIFdoZW4gY2FsbGluZyBhbnkgb2YgdGhlc2UgYWNjZXNzb3JzLCBhIHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZAorICAvLyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgZXh0ZW5zaW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG51bWJlciBNVVNUCisgIC8vIGJlIGxpbmtlZCBpbiwgYW5kIHRoZSBGaWVsZERlc2NyaXB0b3IgdXNlZCB0byByZWZlciB0byBpdCBNVVNUIGJlCisgIC8vIHRoZSBvbmUgZ2VuZXJhdGVkIGJ5IHRoYXQgbGlua2VkLWluIGNvZGUuICBPdGhlcndpc2UsIHRoZSBtZXRob2Qgd2lsbAorICAvLyBkaWUgb24gYW4gYXNzZXJ0IGZhaWx1cmUuICBUaGUgbWVzc2FnZSBvYmplY3RzIHJldHVybmVkIGJ5IHRoZSBtZXNzYWdlCisgIC8vIGFjY2Vzc29ycyBhcmUgZ3VhcmFudGVlZCB0byBiZSBvZiB0aGUgY29ycmVjdCBsaW5rZWQtaW4gdHlwZS4KKyAgLy8KKyAgLy8gVGhlc2UgbWV0aG9kcyBwcmV0dHkgbXVjaCBtYXRjaCBSZWZsZWN0aW9uIGV4Y2VwdCB0aGF0OgorICAvLyAtIFRoZXkncmUgbm90IHZpcnR1YWwuCisgIC8vIC0gVGhleSBpZGVudGlmeSBmaWVsZHMgYnkgbnVtYmVyIHJhdGhlciB0aGFuIEZpZWxkRGVzY3JpcHRvcnMuCisgIC8vIC0gVGhleSBpZGVudGlmeSBlbnVtIHZhbHVlcyB1c2luZyBpbnRlZ2VycyByYXRoZXIgdGhhbiBkZXNjcmlwdG9ycy4KKyAgLy8gLSBTdHJpbmdzIHByb3ZpZGUgTXV0YWJsZSgpIGluIGFkZGl0aW9uIHRvIFNldCgpIGFjY2Vzc29ycy4KKworICBib29sIEhhcyhpbnQgbnVtYmVyKSBjb25zdDsKKyAgaW50IEV4dGVuc2lvblNpemUoaW50IG51bWJlcikgY29uc3Q7ICAgLy8gU2l6ZSBvZiBhIHJlcGVhdGVkIGV4dGVuc2lvbi4KKyAgaW50IE51bUV4dGVuc2lvbnMoKSBjb25zdDsgIC8vIFRoZSBudW1iZXIgb2YgZXh0ZW5zaW9ucworICBGaWVsZFR5cGUgRXh0ZW5zaW9uVHlwZShpbnQgbnVtYmVyKSBjb25zdDsKKyAgdm9pZCBDbGVhckV4dGVuc2lvbihpbnQgbnVtYmVyKTsKKworICAvLyBzaW5ndWxhciBmaWVsZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGludDMyICBHZXRJbnQzMiAoaW50IG51bWJlciwgaW50MzIgIGRlZmF1bHRfdmFsdWUpIGNvbnN0OworICBpbnQ2NCAgR2V0SW50NjQgKGludCBudW1iZXIsIGludDY0ICBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgdWludDMyIEdldFVJbnQzMihpbnQgbnVtYmVyLCB1aW50MzIgZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIHVpbnQ2NCBHZXRVSW50NjQoaW50IG51bWJlciwgdWludDY0IGRlZmF1bHRfdmFsdWUpIGNvbnN0OworICBmbG9hdCAgR2V0RmxvYXQgKGludCBudW1iZXIsIGZsb2F0ICBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgZG91YmxlIEdldERvdWJsZShpbnQgbnVtYmVyLCBkb3VibGUgZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIGJvb2wgICBHZXRCb29sICAoaW50IG51bWJlciwgYm9vbCAgIGRlZmF1bHRfdmFsdWUpIGNvbnN0OworICBpbnQgICAgR2V0RW51bSAgKGludCBudW1iZXIsIGludCAgICBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgY29uc3Qgc3RyaW5nICYgR2V0U3RyaW5nIChpbnQgbnVtYmVyLCBjb25zdCBzdHJpbmcmICBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZUxpdGUmIEdldE1lc3NhZ2UoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIGRlZmF1bHRfdmFsdWUpIGNvbnN0OworICBjb25zdCBNZXNzYWdlTGl0ZSYgR2V0TWVzc2FnZShpbnQgbnVtYmVyLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KSBjb25zdDsKKworICAvLyB8ZGVzY3JpcHRvcnwgbWF5IGJlIE5VTEwgc28gbG9uZyBhcyBpdCBpcyBrbm93biB0aGF0IHRoZSBkZXNjcmlwdG9yIGZvcgorICAvLyB0aGUgZXh0ZW5zaW9uIGxpdmVzIGluIHRoZSBzYW1lIHBvb2wgYXMgdGhlIGRlc2NyaXB0b3IgZm9yIHRoZSBjb250YWluaW5nCisgIC8vIHR5cGUuCisjZGVmaW5lIGRlc2MgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yICAvLyBhdm9pZCBsaW5lIHdyYXBwaW5nCisgIHZvaWQgU2V0SW50MzIgKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBpbnQzMiAgdmFsdWUsIGRlc2MpOworICB2b2lkIFNldEludDY0IChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgaW50NjQgIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBTZXRVSW50MzIoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIHVpbnQzMiB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgU2V0VUludDY0KGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCB1aW50NjQgdmFsdWUsIGRlc2MpOworICB2b2lkIFNldEZsb2F0IChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgZmxvYXQgIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBTZXREb3VibGUoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGRvdWJsZSB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgU2V0Qm9vbCAgKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBib29sICAgdmFsdWUsIGRlc2MpOworICB2b2lkIFNldEVudW0gIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgaW50ICAgIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBTZXRTdHJpbmcoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGNvbnN0IHN0cmluZyYgdmFsdWUsIGRlc2MpOworICBzdHJpbmcgKiBNdXRhYmxlU3RyaW5nIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgZGVzYyk7CisgIE1lc3NhZ2VMaXRlKiBNdXRhYmxlTWVzc2FnZShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUsIGRlc2MpOworICBNZXNzYWdlTGl0ZSogTXV0YWJsZU1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZWNzcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpOworICAvLyBBZGRzIHRoZSBnaXZlbiBtZXNzYWdlIHRvIHRoZSBFeHRlbnNpb25TZXQsIHRha2luZyBvd25lcnNoaXAgb2YgdGhlCisgIC8vIG1lc3NhZ2Ugb2JqZWN0LiBFeGlzdGluZyBtZXNzYWdlIHdpdGggdGhlIHNhbWUgbnVtYmVyIHdpbGwgYmUgZGVsZXRlZC4KKyAgLy8gSWYgIm1lc3NhZ2UiIGlzIE5VTEwsIHRoaXMgaXMgZXF1aXZhbGVudCB0byAiQ2xlYXJFeHRlbnNpb24obnVtYmVyKSIuCisgIHZvaWQgU2V0QWxsb2NhdGVkTWVzc2FnZShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKTsKKyAgTWVzc2FnZUxpdGUqIFJlbGVhc2VNZXNzYWdlKGludCBudW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpOworICBNZXNzYWdlTGl0ZSogVW5zYWZlQXJlbmFSZWxlYXNlTWVzc2FnZSgKKyAgICAgIGludCBudW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpOworCisgIE1lc3NhZ2VMaXRlKiBSZWxlYXNlTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSk7CisjdW5kZWYgZGVzYworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsgcmV0dXJuIGFyZW5hXzsgfQorCisgIC8vIHJlcGVhdGVkIGZpZWxkcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gRmV0Y2hlcyBhIFJlcGVhdGVkRmllbGQgZXh0ZW5zaW9uIGJ5IG51bWJlcjsgcmV0dXJucyB8ZGVmYXVsdF92YWx1ZXwKKyAgLy8gaWYgbm8gc3VjaCBleHRlbnNpb24gZXhpc3RzLiBVc2VyIHNob3VsZCBub3QgdG91Y2ggdGhpcyBkaXJlY3RseTsgaXQgaXMKKyAgLy8gdXNlZCBieSB0aGUgR2V0UmVwZWF0ZWRFeHRlbnNpb24oKSBtZXRob2QuCisgIGNvbnN0IHZvaWQqIEdldFJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlciwgY29uc3Qgdm9pZCogZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIC8vIEZldGNoZXMgYSBtdXRhYmxlIHZlcnNpb24gb2YgYSBSZXBlYXRlZEZpZWxkIGV4dGVuc2lvbiBieSBudW1iZXIsCisgIC8vIGluc3RhbnRpYXRpbmcgb25lIGlmIG5vbmUgZXhpc3RzLiBTaW1pbGFyIHRvIGFib3ZlLCB1c2VyIHNob3VsZCBub3QgdXNlCisgIC8vIHRoaXMgZGlyZWN0bHk7IGl0IHVuZGVybGllcyBNdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oKS4KKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcGFja2VkLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2MpOworCisgIC8vIFRoaXMgaXMgYW4gb3ZlcmxvYWQgb2YgTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQgdG8gbWFpbnRhaW4gY29tcGF0aWJpbGl0eQorICAvLyB3aXRoIG9sZCBjb2RlIHVzaW5nIGEgcHJldmlvdXMgQVBJLiBUaGlzIHZlcnNpb24gb2YKKyAgLy8gTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoKSB3aWxsIEdPT0dMRV9DSEVDSy1mYWlsIG9uIGEgbWlzc2luZyBleHRlbnNpb24uCisgIC8vIChFLmcuOiBib3JnL2NsaWVudHMvaW50ZXJuYWwvcHJvdG8xL3Byb3RvMl9yZWZsZWN0aW9uLmNjLikKKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlcik7CisKKyAgaW50MzIgIEdldFJlcGVhdGVkSW50MzIgKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3Q7CisgIGludDY0ICBHZXRSZXBlYXRlZEludDY0IChpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworICB1aW50MzIgR2V0UmVwZWF0ZWRVSW50MzIoaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdDsKKyAgdWludDY0IEdldFJlcGVhdGVkVUludDY0KGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3Q7CisgIGZsb2F0ICBHZXRSZXBlYXRlZEZsb2F0IChpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworICBkb3VibGUgR2V0UmVwZWF0ZWREb3VibGUoaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdDsKKyAgYm9vbCAgIEdldFJlcGVhdGVkQm9vbCAgKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3Q7CisgIGludCAgICBHZXRSZXBlYXRlZEVudW0gIChpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworICBjb25zdCBzdHJpbmcgJiBHZXRSZXBlYXRlZFN0cmluZyAoaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZUxpdGUmIEdldFJlcGVhdGVkTWVzc2FnZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworCisgIHZvaWQgU2V0UmVwZWF0ZWRJbnQzMiAoaW50IG51bWJlciwgaW50IGluZGV4LCBpbnQzMiAgdmFsdWUpOworICB2b2lkIFNldFJlcGVhdGVkSW50NjQgKGludCBudW1iZXIsIGludCBpbmRleCwgaW50NjQgIHZhbHVlKTsKKyAgdm9pZCBTZXRSZXBlYXRlZFVJbnQzMihpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIHVpbnQzMiB2YWx1ZSk7CisgIHZvaWQgU2V0UmVwZWF0ZWRVSW50NjQoaW50IG51bWJlciwgaW50IGluZGV4LCB1aW50NjQgdmFsdWUpOworICB2b2lkIFNldFJlcGVhdGVkRmxvYXQgKGludCBudW1iZXIsIGludCBpbmRleCwgZmxvYXQgIHZhbHVlKTsKKyAgdm9pZCBTZXRSZXBlYXRlZERvdWJsZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSk7CisgIHZvaWQgU2V0UmVwZWF0ZWRCb29sICAoaW50IG51bWJlciwgaW50IGluZGV4LCBib29sICAgdmFsdWUpOworICB2b2lkIFNldFJlcGVhdGVkRW51bSAgKGludCBudW1iZXIsIGludCBpbmRleCwgaW50ICAgIHZhbHVlKTsKKyAgdm9pZCBTZXRSZXBlYXRlZFN0cmluZyhpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIGNvbnN0IHN0cmluZyYgdmFsdWUpOworICBzdHJpbmcgKiBNdXRhYmxlUmVwZWF0ZWRTdHJpbmcgKGludCBudW1iZXIsIGludCBpbmRleCk7CisgIE1lc3NhZ2VMaXRlKiBNdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKGludCBudW1iZXIsIGludCBpbmRleCk7CisKKyNkZWZpbmUgZGVzYyBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgIC8vIGF2b2lkIGxpbmUgd3JhcHBpbmcKKyAgdm9pZCBBZGRJbnQzMiAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGJvb2wgcGFja2VkLCBpbnQzMiAgdmFsdWUsIGRlc2MpOworICB2b2lkIEFkZEludDY0IChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCBwYWNrZWQsIGludDY0ICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgQWRkVUludDMyKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBib29sIHBhY2tlZCwgdWludDMyIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBBZGRVSW50NjQoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGJvb2wgcGFja2VkLCB1aW50NjQgdmFsdWUsIGRlc2MpOworICB2b2lkIEFkZEZsb2F0IChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCBwYWNrZWQsIGZsb2F0ICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgQWRkRG91YmxlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBib29sIHBhY2tlZCwgZG91YmxlIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBBZGRCb29sICAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGJvb2wgcGFja2VkLCBib29sICAgdmFsdWUsIGRlc2MpOworICB2b2lkIEFkZEVudW0gIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCBwYWNrZWQsIGludCAgICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgQWRkU3RyaW5nKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBkZXNjKTsKKyAgc3RyaW5nICogQWRkU3RyaW5nIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgZGVzYyk7CisgIE1lc3NhZ2VMaXRlKiBBZGRNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlLCBkZXNjKTsKKyAgTWVzc2FnZUxpdGUqIEFkZE1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSk7CisjdW5kZWYgZGVzYworCisgIHZvaWQgUmVtb3ZlTGFzdChpbnQgbnVtYmVyKTsKKyAgTWVzc2FnZUxpdGUqIFJlbGVhc2VMYXN0KGludCBudW1iZXIpOworICB2b2lkIFN3YXBFbGVtZW50cyhpbnQgbnVtYmVyLCBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUT0RPKGtlbnRvbik6ICBIYXJkY29yZSBtZW1vcnkgbWFuYWdlbWVudCBhY2Nlc3NvcnMKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAvLyBjb252ZW5pZW5jZSBtZXRob2RzIGZvciBpbXBsZW1lbnRpbmcgbWV0aG9kcyBvZiBNZXNzYWdlCisgIC8vCisgIC8vIFRoZXNlIGNvdWxkIGFsbCBiZSBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiB0aGUgb3RoZXIgbWV0aG9kcyBvZiB0aGlzCisgIC8vIGNsYXNzLCBidXQgcHJvdmlkaW5nIHRoZW0gaGVyZSBoZWxwcyBrZWVwIHRoZSBnZW5lcmF0ZWQgY29kZSBzaXplIGRvd24uCisKKyAgdm9pZCBDbGVhcigpOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBFeHRlbnNpb25TZXQmIG90aGVyKTsKKyAgdm9pZCBTd2FwKEV4dGVuc2lvblNldCogb3RoZXIpOworICB2b2lkIFN3YXBFeHRlbnNpb24oRXh0ZW5zaW9uU2V0KiBvdGhlciwgaW50IG51bWJlcik7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIC8vIFBhcnNlcyBhIHNpbmdsZSBleHRlbnNpb24gZnJvbSB0aGUgaW5wdXQuIFRoZSBpbnB1dCBzaG91bGQgc3RhcnQgb3V0CisgIC8vIHBvc2l0aW9uZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIHRhZy4KKyAgYm9vbCBQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwKKyAgICAgICAgICAgICAgICAgIEZpZWxkU2tpcHBlciogZmllbGRfc2tpcHBlcik7CisKKyAgLy8gU3BlY2lmaWMgdmVyc2lvbnMgZm9yIGxpdGUgb3IgZnVsbCBtZXNzYWdlcyAoY29uc3RydWN0cyB0aGUgYXBwcm9wcmlhdGUKKyAgLy8gRmllbGRTa2lwcGVyIGF1dG9tYXRpY2FsbHkpLiAgfGNvbnRhaW5pbmdfdHlwZXwgaXMgdGhlIGRlZmF1bHQKKyAgLy8gaW5zdGFuY2UgZm9yIHRoZSBjb250YWluaW5nIG1lc3NhZ2U7IGl0IGlzIHVzZWQgb25seSB0byBsb29rIHVwIHRoZQorICAvLyBleHRlbnNpb24gYnkgbnVtYmVyLiAgU2VlIFJlZ2lzdGVyRXh0ZW5zaW9uKCksIGFib3ZlLiAgVW5saWtlIHRoZSBvdGhlcgorICAvLyBtZXRob2RzIG9mIEV4dGVuc2lvblNldCwgdGhpcyBvbmx5IHdvcmtzIGZvciBnZW5lcmF0ZWQgbWVzc2FnZSB0eXBlcyAtLQorICAvLyBpdCBsb29rcyB1cCBleHRlbnNpb25zIHJlZ2lzdGVyZWQgdXNpbmcgUmVnaXN0ZXJFeHRlbnNpb24oKS4KKyAgYm9vbCBQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUpOworICBib29sIFBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisgIGJvb2wgUGFyc2VGaWVsZCh1aW50MzIgdGFnLCBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiB1bmtub3duX2ZpZWxkcyk7CisKKyAgLy8gUGFyc2UgYW4gZW50aXJlIG1lc3NhZ2UgaW4gTWVzc2FnZVNldCBmb3JtYXQuICBTdWNoIG1lc3NhZ2VzIGhhdmUgbm8KKyAgLy8gZmllbGRzLCBvbmx5IGV4dGVuc2lvbnMuCisgIGJvb2wgUGFyc2VNZXNzYWdlU2V0KGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBTcGVjaWZpYyB2ZXJzaW9ucyBmb3IgbGl0ZSBvciBmdWxsIG1lc3NhZ2VzIChjb25zdHJ1Y3RzIHRoZSBhcHByb3ByaWF0ZQorICAvLyBGaWVsZFNraXBwZXIgYXV0b21hdGljYWxseSkuCisgIGJvb2wgUGFyc2VNZXNzYWdlU2V0KGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSk7CisgIGJvb2wgUGFyc2VNZXNzYWdlU2V0KGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKworICAvLyBXcml0ZSBhbGwgZXh0ZW5zaW9uIGZpZWxkcyB3aXRoIGZpZWxkIG51bWJlcnMgaW4gdGhlIHJhbmdlCisgIC8vICAgW3N0YXJ0X2ZpZWxkX251bWJlciwgZW5kX2ZpZWxkX251bWJlcikKKyAgLy8gdG8gdGhlIG91dHB1dCBzdHJlYW0sIHVzaW5nIHRoZSBjYWNoZWQgc2l6ZXMgY29tcHV0ZWQgd2hlbiBCeXRlU2l6ZSgpIHdhcworICAvLyBsYXN0IGNhbGxlZC4gIE5vdGUgdGhhdCB0aGUgcmFuZ2UgYm91bmRzIGFyZSBpbmNsdXNpdmUtZXhjbHVzaXZlLgorICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbnQgc3RhcnRfZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZW5kX2ZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworCisgIC8vIFNhbWUgYXMgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzLCBidXQgd2l0aG91dCBhbnkgYm91bmRzIGNoZWNraW5nLgorICAvLyBUaGUgY2FsbGVyIG11c3QgZW5zdXJlIHRoYXQgdGFyZ2V0IGhhcyBzdWZmaWNpZW50IGNhcGFjaXR5IGZvciB0aGUKKyAgLy8gc2VyaWFsaXplZCBleHRlbnNpb25zLgorICAvLworICAvLyBSZXR1cm5zIGEgcG9pbnRlciBwYXN0IHRoZSBsYXN0IHdyaXR0ZW4gYnl0ZS4KKyAgdWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW50IHN0YXJ0X2ZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVuZF9maWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIGNvbnN0OworCisgIC8vIExpa2UgYWJvdmUgYnV0IHNlcmlhbGl6ZXMgaW4gTWVzc2FnZVNldCBmb3JtYXQuCisgIHZvaWQgU2VyaWFsaXplTWVzc2FnZVNldFdpdGhDYWNoZWRTaXplcyhpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIHVpbnQ4KiBTZXJpYWxpemVNZXNzYWdlU2V0V2l0aENhY2hlZFNpemVzVG9BcnJheSh1aW50OCogdGFyZ2V0KSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBzZXJpYWxpemVkIHNpemUgb2YgYWxsIHRoZSBleHRlbnNpb25zLgorICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKworICAvLyBMaWtlIEJ5dGVTaXplKCkgYnV0IHVzZXMgTWVzc2FnZVNldCBmb3JtYXQuCisgIGludCBNZXNzYWdlU2V0Qnl0ZVNpemUoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIChhbiBlc3RpbWF0ZSBvZikgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyB1c2VkIGZvciBzdG9yaW5nIHRoZQorICAvLyBleHRlbnNpb25zIGluIG1lbW9yeSwgZXhjbHVkaW5nIHNpemVvZigqdGhpcykuICBJZiB0aGUgRXh0ZW5zaW9uU2V0IGlzCisgIC8vIGZvciBhIGxpdGUgbWVzc2FnZSAoYW5kIHRodXMgcG9zc2libHkgY29udGFpbnMgbGl0ZSBtZXNzYWdlcyksIHRoZSByZXN1bHRzCisgIC8vIGFyZSB1bmRlZmluZWQgKG1pZ2h0IHdvcmssIG1pZ2h0IGNyYXNoLCBtaWdodCBjb3JydXB0IGRhdGEsIG1pZ2h0IG5vdCBldmVuCisgIC8vIGJlIGxpbmtlZCBpbikuICBJdCdzIHVwIHRvIHRoZSBwcm90b2NvbCBjb21waWxlciB0byBhdm9pZCBjYWxsaW5nIHRoaXMgb24KKyAgLy8gc3VjaCBFeHRlbnNpb25TZXRzIChlYXN5IGVub3VnaCBzaW5jZSBsaXRlIG1lc3NhZ2VzIGRvbid0IGltcGxlbWVudAorICAvLyBTcGFjZVVzZWQoKSkuCisgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3Q7CisKKyBwcml2YXRlOgorCisgIC8vIEludGVyZmFjZSBvZiBhIGxhemlseSBwYXJzZWQgc2luZ3VsYXIgbWVzc2FnZSBleHRlbnNpb24uCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMYXp5TWVzc2FnZUV4dGVuc2lvbiB7CisgICBwdWJsaWM6CisgICAgTGF6eU1lc3NhZ2VFeHRlbnNpb24oKSB7fQorICAgIHZpcnR1YWwgfkxhenlNZXNzYWdlRXh0ZW5zaW9uKCkge30KKworICAgIHZpcnR1YWwgTGF6eU1lc3NhZ2VFeHRlbnNpb24qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgY29uc3QgTWVzc2FnZUxpdGUmIEdldE1lc3NhZ2UoCisgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIE1lc3NhZ2VMaXRlKiBNdXRhYmxlTWVzc2FnZShjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlKSA9IDA7CisgICAgdmlydHVhbCB2b2lkIFNldEFsbG9jYXRlZE1lc3NhZ2UoTWVzc2FnZUxpdGUgKm1lc3NhZ2UpID0gMDsKKyAgICB2aXJ0dWFsIE1lc3NhZ2VMaXRlKiBSZWxlYXNlTWVzc2FnZShjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlKSA9IDA7CisgICAgdmlydHVhbCBNZXNzYWdlTGl0ZSogVW5zYWZlQXJlbmFSZWxlYXNlTWVzc2FnZSgKKyAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSkgPSAwOworCisgICAgdmlydHVhbCBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCBpbnQgQnl0ZVNpemUoKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCBpbnQgU3BhY2VVc2VkKCkgY29uc3QgPSAwOworCisgICAgdmlydHVhbCB2b2lkIE1lcmdlRnJvbShjb25zdCBMYXp5TWVzc2FnZUV4dGVuc2lvbiYgb3RoZXIpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgQ2xlYXIoKSA9IDA7CisKKyAgICB2aXJ0dWFsIGJvb2wgUmVhZE1lc3NhZ2UoY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSA9IDA7CisgICAgdmlydHVhbCB2b2lkIFdyaXRlTWVzc2FnZShpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIHVpbnQ4KiBXcml0ZU1lc3NhZ2VUb0FycmF5KGludCBudW1iZXIsIHVpbnQ4KiB0YXJnZXQpIGNvbnN0ID0gMDsKKyAgIHByaXZhdGU6CisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKExhenlNZXNzYWdlRXh0ZW5zaW9uKTsKKyAgfTsKKyAgc3RydWN0IEV4dGVuc2lvbiB7CisgICAgLy8gVGhlIG9yZGVyIG9mIHRoZXNlIGZpZWxkcyBwYWNrcyBFeHRlbnNpb24gaW50byAyNCBieXRlcyB3aGVuIHVzaW5nIDgKKyAgICAvLyBieXRlIGFsaWdubWVudC4gQ29uc2lkZXIgdGhpcyB3aGVuIGFkZGluZyBvciByZW1vdmluZyBmaWVsZHMgaGVyZS4KKyAgICB1bmlvbiB7CisgICAgICBpbnQzMiAgICAgICAgICAgICAgICAgaW50MzJfdmFsdWU7CisgICAgICBpbnQ2NCAgICAgICAgICAgICAgICAgaW50NjRfdmFsdWU7CisgICAgICB1aW50MzIgICAgICAgICAgICAgICAgdWludDMyX3ZhbHVlOworICAgICAgdWludDY0ICAgICAgICAgICAgICAgIHVpbnQ2NF92YWx1ZTsKKyAgICAgIGZsb2F0ICAgICAgICAgICAgICAgICBmbG9hdF92YWx1ZTsKKyAgICAgIGRvdWJsZSAgICAgICAgICAgICAgICBkb3VibGVfdmFsdWU7CisgICAgICBib29sICAgICAgICAgICAgICAgICAgYm9vbF92YWx1ZTsKKyAgICAgIGludCAgICAgICAgICAgICAgICAgICBlbnVtX3ZhbHVlOworICAgICAgc3RyaW5nKiAgICAgICAgICAgICAgIHN0cmluZ192YWx1ZTsKKyAgICAgIE1lc3NhZ2VMaXRlKiAgICAgICAgICBtZXNzYWdlX3ZhbHVlOworICAgICAgTGF6eU1lc3NhZ2VFeHRlbnNpb24qIGxhenltZXNzYWdlX3ZhbHVlOworCisgICAgICBSZXBlYXRlZEZpZWxkICAgPGludDMyICAgICAgPiogcmVwZWF0ZWRfaW50MzJfdmFsdWU7CisgICAgICBSZXBlYXRlZEZpZWxkICAgPGludDY0ICAgICAgPiogcmVwZWF0ZWRfaW50NjRfdmFsdWU7CisgICAgICBSZXBlYXRlZEZpZWxkICAgPHVpbnQzMiAgICAgPiogcmVwZWF0ZWRfdWludDMyX3ZhbHVlOworICAgICAgUmVwZWF0ZWRGaWVsZCAgIDx1aW50NjQgICAgID4qIHJlcGVhdGVkX3VpbnQ2NF92YWx1ZTsKKyAgICAgIFJlcGVhdGVkRmllbGQgICA8ZmxvYXQgICAgICA+KiByZXBlYXRlZF9mbG9hdF92YWx1ZTsKKyAgICAgIFJlcGVhdGVkRmllbGQgICA8ZG91YmxlICAgICA+KiByZXBlYXRlZF9kb3VibGVfdmFsdWU7CisgICAgICBSZXBlYXRlZEZpZWxkICAgPGJvb2wgICAgICAgPiogcmVwZWF0ZWRfYm9vbF92YWx1ZTsKKyAgICAgIFJlcGVhdGVkRmllbGQgICA8aW50ICAgICAgICA+KiByZXBlYXRlZF9lbnVtX3ZhbHVlOworICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmcgICAgID4qIHJlcGVhdGVkX3N0cmluZ192YWx1ZTsKKyAgICAgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+KiByZXBlYXRlZF9tZXNzYWdlX3ZhbHVlOworICAgIH07CisKKyAgICBGaWVsZFR5cGUgdHlwZTsKKyAgICBib29sIGlzX3JlcGVhdGVkOworCisgICAgLy8gRm9yIHNpbmd1bGFyIHR5cGVzLCBpbmRpY2F0ZXMgaWYgdGhlIGV4dGVuc2lvbiBpcyAiY2xlYXJlZCIuICBUaGlzCisgICAgLy8gaGFwcGVucyB3aGVuIGFuIGV4dGVuc2lvbiBpcyBzZXQgYW5kIHRoZW4gbGF0ZXIgY2xlYXJlZCBieSB0aGUgY2FsbGVyLgorICAgIC8vIFdlIHdhbnQgdG8ga2VlcCB0aGUgRXh0ZW5zaW9uIG9iamVjdCBhcm91bmQgZm9yIHJldXNlLCBzbyBpbnN0ZWFkIG9mCisgICAgLy8gcmVtb3ZpbmcgaXQgZnJvbSB0aGUgbWFwLCB3ZSBqdXN0IHNldCBpc19jbGVhcmVkID0gdHJ1ZS4gIFRoaXMgaGFzIG5vCisgICAgLy8gbWVhbmluZyBmb3IgcmVwZWF0ZWQgdHlwZXM7IGZvciB0aG9zZSwgdGhlIHNpemUgb2YgdGhlIFJlcGVhdGVkRmllbGQKKyAgICAvLyBzaW1wbHkgYmVjb21lcyB6ZXJvIHdoZW4gY2xlYXJlZC4KKyAgICBib29sIGlzX2NsZWFyZWQgOiA0OworCisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2UgdHlwZXMsIGluZGljYXRlcyB3aGV0aGVyIGxhenkgcGFyc2luZyBpcyBlbmFibGVkCisgICAgLy8gZm9yIHRoaXMgZXh0ZW5zaW9uLiBUaGlzIGZpZWxkIGlzIG9ubHkgdmFsaWQgd2hlbiB0eXBlID09IFRZUEVfTUVTU0FHRQorICAgIC8vIGFuZCAhaXNfcmVwZWF0ZWQgYmVjYXVzZSB3ZSBvbmx5IHN1cHBvcnQgbGF6eSBwYXJzaW5nIGZvciBzaW5ndWxhcgorICAgIC8vIG1lc3NhZ2UgdHlwZXMgY3VycmVudGx5LiBJZiBpc19sYXp5ID0gdHJ1ZSwgdGhlIGV4dGVuc2lvbiBpcyBzdG9yZWQgaW4KKyAgICAvLyBsYXp5bWVzc2FnZV92YWx1ZS4gT3RoZXJ3aXNlLCB0aGUgZXh0ZW5zaW9uIHdpbGwgYmUgbWVzc2FnZV92YWx1ZS4KKyAgICBib29sIGlzX2xhenkgOiA0OworCisgICAgLy8gRm9yIHJlcGVhdGVkIHR5cGVzLCB0aGlzIGluZGljYXRlcyBpZiB0aGUgW3BhY2tlZD10cnVlXSBvcHRpb24gaXMgc2V0LgorICAgIGJvb2wgaXNfcGFja2VkOworCisgICAgLy8gRm9yIHBhY2tlZCBmaWVsZHMsIHRoZSBzaXplIG9mIHRoZSBwYWNrZWQgZGF0YSBpcyByZWNvcmRlZCBoZXJlIHdoZW4KKyAgICAvLyBCeXRlU2l6ZSgpIGlzIGNhbGxlZCB0aGVuIHVzZWQgZHVyaW5nIHNlcmlhbGl6YXRpb24uCisgICAgLy8gVE9ETyhrZW50b24pOiAgVXNlIGF0b21pYzxpbnQ+IHdoZW4gQysrIHN1cHBvcnRzIGl0LgorICAgIG11dGFibGUgaW50IGNhY2hlZF9zaXplOworCisgICAgLy8gVGhlIGRlc2NyaXB0b3IgZm9yIHRoaXMgZXh0ZW5zaW9uLCBpZiBvbmUgZXhpc3RzIGFuZCBpcyBrbm93bi4gIE1heSBiZQorICAgIC8vIE5VTEwuICBNdXN0IG5vdCBiZSBOVUxMIGlmIHRoZSBkZXNjcmlwdG9yIGZvciB0aGUgZXh0ZW5zaW9uIGRvZXMgbm90CisgICAgLy8gbGl2ZSBpbiB0aGUgc2FtZSBwb29sIGFzIHRoZSBkZXNjcmlwdG9yIGZvciB0aGUgY29udGFpbmluZyB0eXBlLgorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcjsKKworICAgIC8vIFNvbWUgaGVscGVyIG1ldGhvZHMgZm9yIG9wZXJhdGlvbnMgb24gYSBzaW5nbGUgRXh0ZW5zaW9uLgorICAgIHZvaWQgU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICAgIGludCBudW1iZXIsCisgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgICB1aW50OCogU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgICAgICBpbnQgbnVtYmVyLAorICAgICAgICB1aW50OCogdGFyZ2V0KSBjb25zdDsKKyAgICB2b2lkIFNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzKAorICAgICAgICBpbnQgbnVtYmVyLAorICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgICAgdWludDgqIFNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgICAgaW50IG51bWJlciwKKyAgICAgICAgdWludDgqIHRhcmdldCkgY29uc3Q7CisgICAgaW50IEJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0OworICAgIGludCBNZXNzYWdlU2V0SXRlbUJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0OworICAgIHZvaWQgQ2xlYXIoKTsKKyAgICBpbnQgR2V0U2l6ZSgpIGNvbnN0OworICAgIHZvaWQgRnJlZSgpOworICAgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3Q7CisgIH07CisKKworICAvLyBNZXJnZXMgZXhpc3RpbmcgRXh0ZW5zaW9uIGZyb20gb3RoZXJfZXh0ZW5zaW9uCisgIHZvaWQgSW50ZXJuYWxFeHRlbnNpb25NZXJnZUZyb20oaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uJiBvdGhlcl9leHRlbnNpb24pOworCisgIC8vIFJldHVybnMgdHJ1ZSBhbmQgZmlsbHMgZmllbGRfbnVtYmVyIGFuZCBleHRlbnNpb24gaWYgZXh0ZW5zaW9uIGlzIGZvdW5kLgorICAvLyBOb3RlIHRvIHN1cHBvcnQgcGFja2VkIHJlcGVhdGVkIGZpZWxkIGNvbXBhdGliaWxpdHksIGl0IGFsc28gZmlsbHMgd2hldGhlcgorICAvLyB0aGUgdGFnIG9uIHdpcmUgaXMgcGFja2VkLCB3aGljaCBjYW4gYmUgZGlmZmVyZW50IGZyb20KKyAgLy8gZXh0ZW5zaW9uLT5pc19wYWNrZWQgKHdoZXRoZXIgcGFja2VkPXRydWUgaXMgc3BlY2lmaWVkKS4KKyAgYm9vbCBGaW5kRXh0ZW5zaW9uSW5mb0Zyb21UYWcodWludDMyIHRhZywgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQqIGZpZWxkX251bWJlciwgRXh0ZW5zaW9uSW5mbyogZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sKiB3YXNfcGFja2VkX29uX3dpcmUpOworCisgIC8vIFJldHVybnMgdHJ1ZSBhbmQgZmlsbHMgZXh0ZW5zaW9uIGlmIGV4dGVuc2lvbiBpcyBmb3VuZC4KKyAgLy8gTm90ZSB0byBzdXBwb3J0IHBhY2tlZCByZXBlYXRlZCBmaWVsZCBjb21wYXRpYmlsaXR5LCBpdCBhbHNvIGZpbGxzIHdoZXRoZXIKKyAgLy8gdGhlIHRhZyBvbiB3aXJlIGlzIHBhY2tlZCwgd2hpY2ggY2FuIGJlIGRpZmZlcmVudCBmcm9tCisgIC8vIGV4dGVuc2lvbi0+aXNfcGFja2VkICh3aGV0aGVyIHBhY2tlZD10cnVlIGlzIHNwZWNpZmllZCkuCisgIGJvb2wgRmluZEV4dGVuc2lvbkluZm9Gcm9tRmllbGROdW1iZXIoaW50IHdpcmVfdHlwZSwgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uSW5mbyogZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wqIHdhc19wYWNrZWRfb25fd2lyZSk7CisKKyAgLy8gUGFyc2VzIGEgc2luZ2xlIGV4dGVuc2lvbiBmcm9tIHRoZSBpbnB1dC4gVGhlIGlucHV0IHNob3VsZCBzdGFydCBvdXQKKyAgLy8gcG9zaXRpb25lZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgd2lyZSB0YWcuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBpbgorICAvLyBQYXJzZUZpZWxkKCkgYWZ0ZXIgZmllbGQgbnVtYmVyIGFuZCB3YXNfcGFja2VkX29uX3dpcmUgaXMgZXh0cmFjdGVkIGZyb20KKyAgLy8gdGhlIHdpcmUgdGFnIGFuZCBFeHRlbnNpb25JbmZvIGlzIGZvdW5kIGJ5IHRoZSBmaWVsZCBudW1iZXIuCisgIGJvb2wgUGFyc2VGaWVsZFdpdGhFeHRlbnNpb25JbmZvKGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgd2FzX3BhY2tlZF9vbl93aXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFeHRlbnNpb25JbmZvJiBleHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBMaWtlIFBhcnNlRmllbGQoKSwgYnV0IHRoaXMgbWV0aG9kIG1heSBwYXJzZSBzaW5ndWxhciBtZXNzYWdlIGV4dGVuc2lvbnMKKyAgLy8gbGF6aWx5IGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgRkxBR1NfZWFnZXJseV9wYXJzZV9tZXNzYWdlX3NldHMuCisgIGJvb2wgUGFyc2VGaWVsZE1heWJlTGF6aWx5KGludCB3aXJlX3R5cGUsIGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBHZXRzIHRoZSBleHRlbnNpb24gd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLCBjcmVhdGluZyBpdCBpZiBpdCBkb2VzIG5vdAorICAvLyBhbHJlYWR5IGV4aXN0LiAgUmV0dXJucyB0cnVlIGlmIHRoZSBleHRlbnNpb24gZGlkIG5vdCBhbHJlYWR5IGV4aXN0LgorICBib29sIE1heWJlTmV3RXh0ZW5zaW9uKGludCBudW1iZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb24qKiByZXN1bHQpOworCisgIC8vIFBhcnNlIGEgc2luZ2xlIE1lc3NhZ2VTZXQgaXRlbSAtLSBjYWxsZWQganVzdCBhZnRlciB0aGUgaXRlbSBncm91cCBzdGFydAorICAvLyB0YWcgaGFzIGJlZW4gcmVhZC4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VTZXRJdGVtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXIqIGZpZWxkX3NraXBwZXIpOworCisgIC8vIEhhY2s6ICBSZXBlYXRlZFB0ckZpZWxkQmFzZSBkZWNsYXJlcyBFeHRlbnNpb25TZXQgYXMgYSBmcmllbmQuICBUaGlzCisgIC8vICAgZnJpZW5kc2hpcCBzaG91bGQgYXV0b21hdGljYWxseSBleHRlbmQgdG8gRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb24sIGJ1dAorICAvLyAgIHVuZm9ydHVuYXRlbHkgc29tZSBvbGRlciBjb21waWxlcnMgKGUuZy4gR0NDIDMuNC40KSBkbyBub3QgaW1wbGVtZW50IHRoaXMKKyAgLy8gICBjb3JyZWN0bHkuICBTbywgd2UgbXVzdCBwcm92aWRlIGhlbHBlcnMgZm9yIGNhbGxpbmcgbWV0aG9kcyBvZiB0aGF0CisgIC8vICAgY2xhc3MuCisKKyAgLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorICBzdGF0aWMgaW5saW5lIGludCBSZXBlYXRlZE1lc3NhZ2VfU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigKKyAgICAgIFJlcGVhdGVkUHRyRmllbGRCYXNlKiBmaWVsZCk7CisKKyAgLy8gVGhlIEV4dGVuc2lvbiBzdHJ1Y3QgaXMgc21hbGwgZW5vdWdoIHRvIGJlIHBhc3NlZCBieSB2YWx1ZSwgc28gd2UgdXNlIGl0CisgIC8vIGRpcmVjdGx5IGFzIHRoZSB2YWx1ZSB0eXBlIGluIHRoZSBtYXAgcmF0aGVyIHRoYW4gdXNlIHBvaW50ZXJzLiAgV2UgdXNlCisgIC8vIGEgbWFwIHJhdGhlciB0aGFuIGhhc2hfbWFwIGhlcmUgYmVjYXVzZSB3ZSBleHBlY3QgbW9zdCBFeHRlbnNpb25TZXRzIHdpbGwKKyAgLy8gb25seSBjb250YWluIGEgc21hbGwgbnVtYmVyIG9mIGV4dGVuc2lvbnMgd2hlcmVhcyBoYXNoX21hcCBpcyBvcHRpbWl6ZWQKKyAgLy8gZm9yIDEwMCBlbGVtZW50cyBvciBtb3JlLiAgQWxzbywgd2Ugd2FudCBBcHBlbmRUb0xpc3QoKSB0byBvcmRlciBmaWVsZHMKKyAgLy8gYnkgZmllbGQgbnVtYmVyLgorICBzdGQ6Om1hcDxpbnQsIEV4dGVuc2lvbj4gZXh0ZW5zaW9uc187CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEV4dGVuc2lvblNldCk7Cit9OworCisvLyBUaGVzZSBhcmUganVzdCBmb3IgY29udmVuaWVuY2UuLi4KK2lubGluZSB2b2lkIEV4dGVuc2lvblNldDo6U2V0U3RyaW5nKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBNdXRhYmxlU3RyaW5nKG51bWJlciwgdHlwZSwgZGVzY3JpcHRvciktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBFeHRlbnNpb25TZXQ6OlNldFJlcGVhdGVkU3RyaW5nKGludCBudW1iZXIsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICBNdXRhYmxlUmVwZWF0ZWRTdHJpbmcobnVtYmVyLCBpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBFeHRlbnNpb25TZXQ6OkFkZFN0cmluZyhpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgQWRkU3RyaW5nKG51bWJlciwgdHlwZSwgZGVzY3JpcHRvciktPmFzc2lnbih2YWx1ZSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEdsdWUgZm9yIGdlbmVyYXRlZCBleHRlbnNpb24gYWNjZXNzb3JzCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFRlbXBsYXRlIG1hZ2ljCisKKy8vIEZpcnN0IHdlIGhhdmUgYSBzZXQgb2YgY2xhc3NlcyByZXByZXNlbnRpbmcgInR5cGUgdHJhaXRzIiBmb3IgZGlmZmVyZW50CisvLyBmaWVsZCB0eXBlcy4gIEEgdHlwZSB0cmFpdHMgY2xhc3Mga25vd3MgaG93IHRvIGltcGxlbWVudCBiYXNpYyBhY2Nlc3NvcnMKKy8vIGZvciBleHRlbnNpb25zIG9mIGEgcGFydGljdWxhciB0eXBlIGdpdmVuIGFuIEV4dGVuc2lvblNldC4gIFRoZSBzaWduYXR1cmUKKy8vIGZvciBhIHR5cGUgdHJhaXRzIGNsYXNzIGxvb2tzIGxpa2UgdGhpczoKKy8vCisvLyAgIGNsYXNzIFR5cGVUcmFpdHMgeworLy8gICAgcHVibGljOgorLy8gICAgIHR5cGVkZWYgPyBDb25zdFR5cGU7CisvLyAgICAgdHlwZWRlZiA/IE11dGFibGVUeXBlOworLy8gICAgIC8vIFR5cGVUcmFpdHMgZm9yIHNpbmd1bGFyIGZpZWxkcyBhbmQgcmVwZWF0ZWQgZmllbGRzIHdpbGwgZGVmaW5lIHRoZQorLy8gICAgIC8vIHN5bWJvbCAiU2luZ3VsYXIiIG9yICJSZXBlYXRlZCIgcmVzcGVjdGl2ZWx5LiBUaGVzZSB0d28gc3ltYm9scyB3aWxsCisvLyAgICAgLy8gYmUgdXNlZCBpbiBleHRlbnNpb24gYWNjZXNzb3JzIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gc2luZ3VsYXIKKy8vICAgICAvLyBleHRlbnNpb25zIGFuZCByZXBlYXRlZCBleHRlbnNpb25zLiBJZiB0aGUgVHlwZVRyYWl0cyBmb3IgdGhlIHBhc3NlZAorLy8gICAgIC8vIGluIGV4dGVuc2lvbiBkb2Vzbid0IGhhdmUgdGhlIGV4cGVjdGVkIHN5bWJvbCBkZWZpbmVkLCBpdCBtZWFucyB0aGUKKy8vICAgICAvLyB1c2VyIGlzIHBhc3NpbmcgYSByZXBlYXRlZCBleHRlbnNpb24gdG8gYSBzaW5ndWxhciBhY2Nlc3Nvciwgb3IgdGhlCisvLyAgICAgLy8gb3Bwb3NpdGUuIEluIHRoYXQgY2FzZSB0aGUgQysrIGNvbXBpbGVyIHdpbGwgZ2VuZXJhdGUgYW4gZXJyb3IKKy8vICAgICAvLyBtZXNzYWdlICJubyBtYXRjaGluZyBtZW1iZXIgZnVuY3Rpb24iIHRvIGluZm9ybSB0aGUgdXNlci4KKy8vICAgICB0eXBlZGVmID8gU2luZ3VsYXIKKy8vICAgICB0eXBlZGVmID8gUmVwZWF0ZWQKKy8vCisvLyAgICAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0KTsKKy8vICAgICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0KGludCBudW1iZXIsIENvbnN0VHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpOworLy8gICAgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgTXV0YWJsZShpbnQgbnVtYmVyLCBFeHRlbnNpb25TZXQqIHNldCk7CisvLworLy8gICAgIC8vIFZhcmlhbnRzIGZvciByZXBlYXRlZCBmaWVsZHMuCisvLyAgICAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpOworLy8gICAgIHN0YXRpYyBpbmxpbmUgdm9pZCBTZXQoaW50IG51bWJlciwgaW50IGluZGV4LAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RUeXBlIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCk7CisvLyAgICAgc3RhdGljIGlubGluZSBNdXRhYmxlVHlwZSBNdXRhYmxlKGludCBudW1iZXIsIGludCBpbmRleCwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpOworLy8gICAgIHN0YXRpYyBpbmxpbmUgdm9pZCBBZGQoaW50IG51bWJlciwgQ29uc3RUeXBlIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCk7CisvLyAgICAgc3RhdGljIGlubGluZSBNdXRhYmxlVHlwZSBBZGQoaW50IG51bWJlciwgRXh0ZW5zaW9uU2V0KiBzZXQpOworLy8gICB9OworLy8KKy8vIE5vdCBhbGwgb2YgdGhlc2UgbWV0aG9kcyBtYWtlIHNlbnNlIGZvciBhbGwgZmllbGQgdHlwZXMuICBGb3IgZXhhbXBsZSwgdGhlCisvLyAiTXV0YWJsZSIgbWV0aG9kcyBvbmx5IG1ha2Ugc2Vuc2UgZm9yIHN0cmluZ3MgYW5kIG1lc3NhZ2VzLCBhbmQgdGhlCisvLyByZXBlYXRlZCBtZXRob2RzIG9ubHkgbWFrZSBzZW5zZSBmb3IgcmVwZWF0ZWQgdHlwZXMuICBTbywgZWFjaCB0eXBlCisvLyB0cmFpdHMgY2xhc3MgaW1wbGVtZW50cyBvbmx5IHRoZSBzZXQgb2YgbWV0aG9kcyBmcm9tIHRoaXMgc2lnbmF0dXJlIHRoYXQgaXQKKy8vIGFjdHVhbGx5IHN1cHBvcnRzLiAgVGhpcyB3aWxsIGNhdXNlIGEgY29tcGlsZXIgZXJyb3IgaWYgdGhlIHVzZXIgdHJpZXMgdG8KKy8vIGFjY2VzcyBhbiBleHRlbnNpb24gdXNpbmcgYSBtZXRob2QgdGhhdCBkb2Vzbid0IG1ha2Ugc2Vuc2UgZm9yIGl0cyB0eXBlLgorLy8gRm9yIGV4YW1wbGUsIGlmICJmb28iIGlzIGFuIGV4dGVuc2lvbiBvZiB0eXBlICJvcHRpb25hbCBpbnQzMiIsIHRoZW4gaWYgeW91CisvLyB0cnkgdG8gd3JpdGUgY29kZSBsaWtlOgorLy8gICBteV9tZXNzYWdlLk11dGFibGVFeHRlbnNpb24oZm9vKQorLy8geW91IHdpbGwgZ2V0IGEgY29tcGlsZSBlcnJvciBiZWNhdXNlIFByaW1pdGl2ZVR5cGVUcmFpdHM8aW50MzI+IGRvZXMgbm90CisvLyBoYXZlIGEgIk11dGFibGUoKSIgbWV0aG9kLgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBQcmltaXRpdmVUeXBlVHJhaXRzCisKKy8vIFNpbmNlIHRoZSBFeHRlbnNpb25TZXQgaGFzIGRpZmZlcmVudCBtZXRob2RzIGZvciBlYWNoIHByaW1pdGl2ZSB0eXBlLAorLy8gd2UgbXVzdCBleHBsaWNpdGx5IGRlZmluZSB0aGUgbWV0aG9kcyBvZiB0aGUgdHlwZSB0cmFpdHMgY2xhc3MgZm9yIGVhY2gKKy8vIGtub3duIHR5cGUuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2NsYXNzIFByaW1pdGl2ZVR5cGVUcmFpdHMgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBUeXBlIENvbnN0VHlwZTsKKyAgdHlwZWRlZiBUeXBlIE11dGFibGVUeXBlOworICB0eXBlZGVmIFByaW1pdGl2ZVR5cGVUcmFpdHM8VHlwZT4gU2luZ3VsYXI7CisKKyAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RUeXBlIGRlZmF1bHRfdmFsdWUpOworICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0KGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0VHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBSZXBlYXRlZFByaW1pdGl2ZVR5cGVUcmFpdHMgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBUeXBlIENvbnN0VHlwZTsKKyAgdHlwZWRlZiBUeXBlIE11dGFibGVUeXBlOworICB0eXBlZGVmIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUeXBlPiBSZXBlYXRlZDsKKworICB0eXBlZGVmIFJlcGVhdGVkRmllbGQ8VHlwZT4gUmVwZWF0ZWRGaWVsZFR5cGU7CisKKyAgc3RhdGljIGlubGluZSBUeXBlIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCwgaW50IGluZGV4KTsKKyAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KTsKKyAgc3RhdGljIGlubGluZSB2b2lkIEFkZChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3BhY2tlZCwgVHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpOworCisgIHN0YXRpYyBpbmxpbmUgY29uc3QgUmVwZWF0ZWRGaWVsZDxDb25zdFR5cGU+JgorICAgICAgR2V0UmVwZWF0ZWQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQpOworICBzdGF0aWMgaW5saW5lIFJlcGVhdGVkRmllbGQ8VHlwZT4qCisgICAgICBNdXRhYmxlUmVwZWF0ZWQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wYWNrZWQsIEV4dGVuc2lvblNldCogc2V0KTsKKworICBzdGF0aWMgY29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqIEdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCk7Cit9OworCisvLyBEZWNsYXJlZCBoZXJlIHNvIHRoYXQgdGhpcyBjYW4gYmUgZnJpZW5kZWQgYmVsb3cuCit2b2lkIEluaXRpYWxpemVEZWZhdWx0UmVwZWF0ZWRGaWVsZHMoKTsKK3ZvaWQgRGVzdHJveURlZmF1bHRSZXBlYXRlZEZpZWxkcygpOworCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0cyB7CisgcHJpdmF0ZToKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4gZnJpZW5kIGNsYXNzIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czsKKyAgZnJpZW5kIHZvaWQgSW5pdGlhbGl6ZURlZmF1bHRSZXBlYXRlZEZpZWxkcygpOworICBmcmllbmQgdm9pZCBEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkPGludDMyPiogZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQzMl87CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkPGludDY0PiogZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQ2NF87CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkPHVpbnQzMj4qIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfdWludDMyXzsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGQ8dWludDY0PiogZGVmYXVsdF9yZXBlYXRlZF9maWVsZF91aW50NjRfOworICBzdGF0aWMgY29uc3QgUmVwZWF0ZWRGaWVsZDxkb3VibGU+KiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2RvdWJsZV87CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkPGZsb2F0PiogZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9mbG9hdF87CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkPGJvb2w+KiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2Jvb2xfOworfTsKKworI2RlZmluZSBQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoVFlQRSwgTUVUSE9EKSAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgVFlQRSBQcmltaXRpdmVUeXBlVHJhaXRzPFRZUEU+OjpHZXQoICAgICAgICAgICAgICAgICAgICAgXAorICAgIGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LCBUWVBFIGRlZmF1bHRfdmFsdWUpIHsgICAgICAgICAgICAgXAorICByZXR1cm4gc2V0LkdldCMjTUVUSE9EKG51bWJlciwgZGVmYXVsdF92YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgdm9pZCBQcmltaXRpdmVUeXBlVHJhaXRzPFRZUEU+OjpTZXQoICAgICAgICAgICAgICAgICAgICAgXAorICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLCBUWVBFIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCkgeyAgICAgXAorICBzZXQtPlNldCMjTUVUSE9EKG51bWJlciwgZmllbGRfdHlwZSwgdmFsdWUsIE5VTEwpOyAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgVFlQRSBSZXBlYXRlZFByaW1pdGl2ZVR5cGVUcmFpdHM8VFlQRT46OkdldCggICAgICAgICAgICAgXAorICAgIGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LCBpbnQgaW5kZXgpIHsgICAgICAgICAgICAgICAgICAgICAgXAorICByZXR1cm4gc2V0LkdldFJlcGVhdGVkIyNNRVRIT0QobnVtYmVyLCBpbmRleCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgdm9pZCBSZXBlYXRlZFByaW1pdGl2ZVR5cGVUcmFpdHM8VFlQRT46OlNldCggICAgICAgICAgICAgXAorICAgIGludCBudW1iZXIsIGludCBpbmRleCwgVFlQRSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpIHsgICAgICAgICAgICAgICAgXAorICBzZXQtPlNldFJlcGVhdGVkIyNNRVRIT0QobnVtYmVyLCBpbmRleCwgdmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgdm9pZCBSZXBlYXRlZFByaW1pdGl2ZVR5cGVUcmFpdHM8VFlQRT46OkFkZCggICAgICAgICAgICAgXAorICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLCBib29sIGlzX3BhY2tlZCwgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFRZUEUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBzZXQtPkFkZCMjTUVUSE9EKG51bWJlciwgZmllbGRfdHlwZSwgaXNfcGFja2VkLCB2YWx1ZSwgTlVMTCk7ICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6R2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKSB7ICAgICAgICAgXAorICByZXR1cm4gUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF8jI1RZUEUjI187ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6R2V0UmVwZWF0ZWQoaW50IG51bWJlciwgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFeHRlbnNpb25TZXQmIHNldCkgeyAgXAorICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPio+KCAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldC5HZXRSYXdSZXBlYXRlZEZpZWxkKCAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIsIEdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkpKTsgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgUmVwZWF0ZWRGaWVsZDxUWVBFPiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6TXV0YWJsZVJlcGVhdGVkKGludCBudW1iZXIsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRUeXBlIGZpZWxkX3R5cGUsICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wYWNrZWQsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsgICAgXAorICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZEZpZWxkPFRZUEU+Kj4oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgc2V0LT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChudW1iZXIsIGZpZWxkX3R5cGUsIGlzX3BhY2tlZCwgTlVMTCkpOyAgXAorfQorCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoIGludDMyLCAgSW50MzIpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoIGludDY0LCAgSW50NjQpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUodWludDMyLCBVSW50MzIpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUodWludDY0LCBVSW50NjQpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoIGZsb2F0LCAgRmxvYXQpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoZG91YmxlLCBEb3VibGUpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoICBib29sLCAgIEJvb2wpCisKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyaW5nVHlwZVRyYWl0cworCisvLyBTdHJpbmdzIHN1cHBvcnQgYm90aCBTZXQoKSBhbmQgTXV0YWJsZSgpLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmluZ1R5cGVUcmFpdHMgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBjb25zdCBzdHJpbmcmIENvbnN0VHlwZTsKKyAgdHlwZWRlZiBzdHJpbmcqIE11dGFibGVUeXBlOworICB0eXBlZGVmIFN0cmluZ1R5cGVUcmFpdHMgU2luZ3VsYXI7CisKKyAgc3RhdGljIGlubGluZSBjb25zdCBzdHJpbmcmIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgZGVmYXVsdF92YWx1ZSkgeworICAgIHJldHVybiBzZXQuR2V0U3RyaW5nKG51bWJlciwgZGVmYXVsdF92YWx1ZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHNldC0+U2V0U3RyaW5nKG51bWJlciwgZmllbGRfdHlwZSwgdmFsdWUsIE5VTEwpOworICB9CisgIHN0YXRpYyBpbmxpbmUgc3RyaW5nKiBNdXRhYmxlKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiBzZXQtPk11dGFibGVTdHJpbmcobnVtYmVyLCBmaWVsZF90eXBlLCBOVUxMKTsKKyAgfQorfTsKKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJlcGVhdGVkU3RyaW5nVHlwZVRyYWl0cyB7CisgcHVibGljOgorICB0eXBlZGVmIGNvbnN0IHN0cmluZyYgQ29uc3RUeXBlOworICB0eXBlZGVmIHN0cmluZyogTXV0YWJsZVR5cGU7CisgIHR5cGVkZWYgUmVwZWF0ZWRTdHJpbmdUeXBlVHJhaXRzIFJlcGVhdGVkOworCisgIHR5cGVkZWYgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IFJlcGVhdGVkRmllbGRUeXBlOworCisgIHN0YXRpYyBpbmxpbmUgY29uc3Qgc3RyaW5nJiBHZXQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgcmV0dXJuIHNldC5HZXRSZXBlYXRlZFN0cmluZyhudW1iZXIsIGluZGV4KTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0KGludCBudW1iZXIsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHNldC0+U2V0UmVwZWF0ZWRTdHJpbmcobnVtYmVyLCBpbmRleCwgdmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgc3RyaW5nKiBNdXRhYmxlKGludCBudW1iZXIsIGludCBpbmRleCwgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gc2V0LT5NdXRhYmxlUmVwZWF0ZWRTdHJpbmcobnVtYmVyLCBpbmRleCk7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIEFkZChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBib29sIC8qaXNfcGFja2VkKi8sIGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICBzZXQtPkFkZFN0cmluZyhudW1iZXIsIGZpZWxkX3R5cGUsIHZhbHVlLCBOVUxMKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHN0cmluZyogQWRkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgcmV0dXJuIHNldC0+QWRkU3RyaW5nKG51bWJlciwgZmllbGRfdHlwZSwgTlVMTCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4mCisgICAgICBHZXRSZXBlYXRlZChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCkgeworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qPigKKyAgICAgICAgc2V0LkdldFJhd1JlcGVhdGVkRmllbGQobnVtYmVyLCBHZXREZWZhdWx0UmVwZWF0ZWRGaWVsZCgpKSk7CisgIH0KKworICBzdGF0aWMgaW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPioKKyAgICAgIE11dGFibGVSZXBlYXRlZChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3BhY2tlZCwgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qPigKKyAgICAgICAgc2V0LT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChudW1iZXIsIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfcGFja2VkLCBOVUxMKSk7CisgIH0KKworICBzdGF0aWMgY29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqIEdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkgeworICAgIHJldHVybiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXzsKKyAgfQorCisgcHJpdmF0ZToKKyAgZnJpZW5kIHZvaWQgSW5pdGlhbGl6ZURlZmF1bHRSZXBlYXRlZEZpZWxkcygpOworICBmcmllbmQgdm9pZCBEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSAqZGVmYXVsdF9yZXBlYXRlZF9maWVsZF87Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBFbnVtVHlwZVRyYWl0cworCisvLyBFeHRlbnNpb25TZXQgcmVwcmVzZW50cyBlbnVtcyB1c2luZyBpbnRlZ2VycyBpbnRlcm5hbGx5LCBzbyB3ZSBoYXZlIHRvCisvLyBzdGF0aWNfY2FzdCBhcm91bmQuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZSwgYm9vbCBJc1ZhbGlkKGludCk+CitjbGFzcyBFbnVtVHlwZVRyYWl0cyB7CisgcHVibGljOgorICB0eXBlZGVmIFR5cGUgQ29uc3RUeXBlOworICB0eXBlZGVmIFR5cGUgTXV0YWJsZVR5cGU7CisgIHR5cGVkZWYgRW51bVR5cGVUcmFpdHM8VHlwZSwgSXNWYWxpZD4gU2luZ3VsYXI7CisKKyAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RUeXBlIGRlZmF1bHRfdmFsdWUpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VHlwZT4oc2V0LkdldEVudW0obnVtYmVyLCBkZWZhdWx0X3ZhbHVlKSk7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgR09PR0xFX0RDSEVDSyhJc1ZhbGlkKHZhbHVlKSk7CisgICAgc2V0LT5TZXRFbnVtKG51bWJlciwgZmllbGRfdHlwZSwgdmFsdWUsIE5VTEwpOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZSwgYm9vbCBJc1ZhbGlkKGludCk+CitjbGFzcyBSZXBlYXRlZEVudW1UeXBlVHJhaXRzIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVHlwZSBDb25zdFR5cGU7CisgIHR5cGVkZWYgVHlwZSBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBSZXBlYXRlZEVudW1UeXBlVHJhaXRzPFR5cGUsIElzVmFsaWQ+IFJlcGVhdGVkOworCisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZDxUeXBlPiBSZXBlYXRlZEZpZWxkVHlwZTsKKworICBzdGF0aWMgaW5saW5lIENvbnN0VHlwZSBHZXQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsIGludCBpbmRleCkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUeXBlPihzZXQuR2V0UmVwZWF0ZWRFbnVtKG51bWJlciwgaW5kZXgpKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0KGludCBudW1iZXIsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgR09PR0xFX0RDSEVDSyhJc1ZhbGlkKHZhbHVlKSk7CisgICAgc2V0LT5TZXRSZXBlYXRlZEVudW0obnVtYmVyLCBpbmRleCwgdmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBBZGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wYWNrZWQsIENvbnN0VHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICBHT09HTEVfRENIRUNLKElzVmFsaWQodmFsdWUpKTsKKyAgICBzZXQtPkFkZEVudW0obnVtYmVyLCBmaWVsZF90eXBlLCBpc19wYWNrZWQsIHZhbHVlLCBOVUxMKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGNvbnN0IFJlcGVhdGVkRmllbGQ8VHlwZT4mIEdldFJlcGVhdGVkKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRXh0ZW5zaW9uU2V0JgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldCkgeworICAgIC8vIEhhY2s6IHRoZSBgRXh0ZW5zaW9uYCBzdHJ1Y3Qgc3RvcmVzIGEgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZvciBlbnVtcy4KKyAgICAvLyBSZXBlYXRlZEZpZWxkPGludD4gY2Fubm90IGltcGxpY2l0bHkgY29udmVydCB0byBSZXBlYXRlZEZpZWxkPEVudW1UeXBlPgorICAgIC8vIHNvIHdlIG5lZWQgdG8gZG8gc29tZSBjYXN0aW5nIG1hZ2ljLiBTZWUgbWVzc2FnZS5oIGZvciBzaW1pbGFyCisgICAgLy8gY29udG9ydGlvbnMgZm9yIG5vbi1leHRlbnNpb24gZmllbGRzLgorICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZEZpZWxkPFR5cGU+Kj4oCisgICAgICAgIHNldC5HZXRSYXdSZXBlYXRlZEZpZWxkKG51bWJlciwgR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKSkpOworICB9CisKKyAgc3RhdGljIGlubGluZSBSZXBlYXRlZEZpZWxkPFR5cGU+KiBNdXRhYmxlUmVwZWF0ZWQoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcGFja2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGQ8VHlwZT4qPigKKyAgICAgICAgc2V0LT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChudW1iZXIsIGZpZWxkX3R5cGUsIGlzX3BhY2tlZCwgTlVMTCkpOworICB9CisKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKiBHZXREZWZhdWx0UmVwZWF0ZWRGaWVsZCgpIHsKKyAgICAvLyBIYWNrOiBhcyBub3RlZCBhYm92ZSwgcmVwZWF0ZWQgZW51bSBmaWVsZHMgYXJlIGludGVybmFsbHkgc3RvcmVkIGFzIGEKKyAgICAvLyBSZXBlYXRlZEZpZWxkPGludD4uIFdlIG5lZWQgdG8gYmUgYWJsZSB0byBpbnN0YW50aWF0ZSBnbG9iYWwgc3RhdGljCisgICAgLy8gb2JqZWN0cyB0byByZXR1cm4gYXMgZGVmYXVsdCAoZW1wdHkpIHJlcGVhdGVkIGZpZWxkcyBvbiBub24tZXhpc3RlbnQKKyAgICAvLyBleHRlbnNpb25zLiBXZSB3b3VsZCBub3QgYmUgYWJsZSB0byBrbm93IGEtcHJpb3JpIGFsbCBvZiB0aGUgZW51bSB0eXBlcworICAgIC8vICh2YWx1ZXMgb2YgfFR5cGV8KSB0byBpbnN0YW50aWF0ZSBhbGwgb2YgdGhlc2UsIHNvIHdlIGp1c3QgcmUtdXNlIGludDMyJ3MKKyAgICAvLyBkZWZhdWx0IHJlcGVhdGVkIGZpZWxkIG9iamVjdC4KKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZEZpZWxkPFR5cGU+Kj4oCisgICAgICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxpbnQzMj46OkdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkpOworICB9Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNZXNzYWdlVHlwZVRyYWl0cworCisvLyBFeHRlbnNpb25TZXQgZ3VhcmFudGVlcyB0aGF0IHdoZW4gbWFuaXB1bGF0aW5nIGV4dGVuc2lvbnMgd2l0aCBtZXNzYWdlCisvLyB0eXBlcywgdGhlIGltcGxlbWVudGF0aW9uIHVzZWQgd2lsbCBiZSB0aGUgY29tcGlsZWQtaW4gY2xhc3MgcmVwcmVzZW50aW5nCisvLyB0aGF0IHR5cGUuICBTbywgd2UgY2FuIHN0YXRpY19jYXN0IGRvd24gdG8gdGhlIGV4YWN0IHR5cGUgd2UgZXhwZWN0LgordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNZXNzYWdlVHlwZVRyYWl0cyB7CisgcHVibGljOgorICB0eXBlZGVmIGNvbnN0IFR5cGUmIENvbnN0VHlwZTsKKyAgdHlwZWRlZiBUeXBlKiBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBNZXNzYWdlVHlwZVRyYWl0czxUeXBlPiBTaW5ndWxhcjsKKworICBzdGF0aWMgaW5saW5lIENvbnN0VHlwZSBHZXQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgZGVmYXVsdF92YWx1ZSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBUeXBlJj4oCisgICAgICAgIHNldC5HZXRNZXNzYWdlKG51bWJlciwgZGVmYXVsdF92YWx1ZSkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgTXV0YWJsZShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFR5cGUqPigKKyAgICAgIHNldC0+TXV0YWJsZU1lc3NhZ2UobnVtYmVyLCBmaWVsZF90eXBlLCBUeXBlOjpkZWZhdWx0X2luc3RhbmNlKCksIE5VTEwpKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11dGFibGVUeXBlIG1lc3NhZ2UsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgc2V0LT5TZXRBbGxvY2F0ZWRNZXNzYWdlKG51bWJlciwgZmllbGRfdHlwZSwgTlVMTCwgbWVzc2FnZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSBNdXRhYmxlVHlwZSBSZWxlYXNlKGludCBudW1iZXIsIEZpZWxkVHlwZSAvKiBmaWVsZF90eXBlICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VHlwZSo+KHNldC0+UmVsZWFzZU1lc3NhZ2UoCisgICAgICAgIG51bWJlciwgVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKSk7CisgIH0KK307CisKKy8vIGZvcndhcmQgZGVjbGFyYXRpb24KK2NsYXNzIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2NsYXNzIFJlcGVhdGVkTWVzc2FnZVR5cGVUcmFpdHMgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBjb25zdCBUeXBlJiBDb25zdFR5cGU7CisgIHR5cGVkZWYgVHlwZSogTXV0YWJsZVR5cGU7CisgIHR5cGVkZWYgUmVwZWF0ZWRNZXNzYWdlVHlwZVRyYWl0czxUeXBlPiBSZXBlYXRlZDsKKworICB0eXBlZGVmIFJlcGVhdGVkUHRyRmllbGQ8VHlwZT4gUmVwZWF0ZWRGaWVsZFR5cGU7CisKKyAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LCBpbnQgaW5kZXgpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVHlwZSY+KHNldC5HZXRSZXBlYXRlZE1lc3NhZ2UobnVtYmVyLCBpbmRleCkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgTXV0YWJsZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFR5cGUqPihzZXQtPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobnVtYmVyLCBpbmRleCkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgQWRkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUeXBlKj4oCisgICAgICAgIHNldC0+QWRkTWVzc2FnZShudW1iZXIsIGZpZWxkX3R5cGUsIFR5cGU6OmRlZmF1bHRfaW5zdGFuY2UoKSwgTlVMTCkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiYgR2V0UmVwZWF0ZWQoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFeHRlbnNpb25TZXQmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0KSB7CisgICAgLy8gU2VlIG5vdGVzIGFib3ZlIGluIFJlcGVhdGVkRW51bVR5cGVUcmFpdHM6OkdldFJlcGVhdGVkKCk6IHNhbWUKKyAgICAvLyBjYXN0aW5nIGhhY2sgYXBwbGllcyBoZXJlLCBiZWNhdXNlIGEgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT4KKyAgICAvLyBjYW5ub3QgbmF0dXJhbGx5IGJlY29tZSBhIFJlcGVhdGVkUHRyVHlwZTxUeXBlPiBldmVuIHRob3VnaCBUeXBlIGlzCisgICAgLy8gcHJlc3VtYWJseSBhIG1lc3NhZ2UuIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgZ29lcyB0aHJvdWdoIHNpbWlsYXIgY29udG9ydGlvbnMKKyAgICAvLyB3aXRoIGEgcmVpbnRlcnByZXRfY2FzdDw+LgorICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZFB0ckZpZWxkPFR5cGU+Kj4oCisgICAgICAgIHNldC5HZXRSYXdSZXBlYXRlZEZpZWxkKG51bWJlciwgR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKSkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiogTXV0YWJsZVJlcGVhdGVkKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3BhY2tlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPFR5cGU+Kj4oCisgICAgICAgIHNldC0+TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQobnVtYmVyLCBmaWVsZF90eXBlLCBpc19wYWNrZWQsIE5VTEwpKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKTsKK307CisKKy8vIFRoaXMgY2xhc3MgZXhpc3RzIG9ubHkgdG8gaG9sZCBhIGdlbmVyaWMgZGVmYXVsdCBlbXB0eSByZXBlYXRlZCBmaWVsZCBmb3IgYWxsCisvLyBtZXNzYWdlLXR5cGUgcmVwZWF0ZWQgZmllbGQgZXh0ZW5zaW9ucy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZXBlYXRlZE1lc3NhZ2VHZW5lcmljVHlwZVRyYWl0cyB7CisgcHVibGljOgorICB0eXBlZGVmIFJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUxpdGUqPiBSZXBlYXRlZEZpZWxkVHlwZTsKKyBwcml2YXRlOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPiBmcmllbmQgY2xhc3MgUmVwZWF0ZWRNZXNzYWdlVHlwZVRyYWl0czsKKyAgZnJpZW5kIHZvaWQgSW5pdGlhbGl6ZURlZmF1bHRSZXBlYXRlZEZpZWxkcygpOworICBmcmllbmQgdm9pZCBEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogZGVmYXVsdF9yZXBlYXRlZF9maWVsZF87Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPiBpbmxpbmUKKyAgICBjb25zdCB0eXBlbmFtZSBSZXBlYXRlZE1lc3NhZ2VUeXBlVHJhaXRzPFR5cGU+OjpSZXBlYXRlZEZpZWxkVHlwZSoKKyAgICBSZXBlYXRlZE1lc3NhZ2VUeXBlVHJhaXRzPFR5cGU+OjpHZXREZWZhdWx0UmVwZWF0ZWRGaWVsZCgpIHsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqPigKKyAgICAgIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEV4dGVuc2lvbklkZW50aWZpZXIKKworLy8gVGhpcyBpcyB0aGUgdHlwZSBvZiBhY3R1YWwgZXh0ZW5zaW9uIG9iamVjdHMuICBFLmcuIGlmIHlvdSBoYXZlOgorLy8gICBleHRlbmRzIEZvbyB3aXRoIG9wdGlvbmFsIGludDMyIGJhciA9IDEyMzQ7CisvLyB0aGVuICJiYXIiIHdpbGwgYmUgZGVmaW5lZCBpbiBDKysgYXM6CisvLyAgIEV4dGVuc2lvbklkZW50aWZpZXI8Rm9vLCBQcmltaXRpdmVUeXBlVHJhaXRzPGludDMyPiwgMSwgZmFsc2U+IGJhcigxMjM0KTsKKy8vCisvLyBOb3RlIHRoYXQgd2UgY291bGQsIGluIHRoZW9yeSwgc3VwcGx5IHRoZSBmaWVsZCBudW1iZXIgYXMgYSB0ZW1wbGF0ZQorLy8gcGFyYW1ldGVyLCBhbmQgdGh1cyBtYWtlIGFuIGluc3RhbmNlIG9mIEV4dGVuc2lvbklkZW50aWZpZXIgaGF2ZSBubworLy8gYWN0dWFsIGNvbnRlbnRzLiAgSG93ZXZlciwgaWYgd2UgZGlkIHRoYXQsIHRoZW4gdXNpbmcgYXQgZXh0ZW5zaW9uCisvLyBpZGVudGlmaWVyIHdvdWxkIG5vdCBuZWNlc3NhcmlseSBjYXVzZSB0aGUgY29tcGlsZXIgdG8gb3V0cHV0IGFueSBzb3J0CisvLyBvZiByZWZlcmVuY2UgdG8gYW55IHNpbXBsZSBkZWZpbmVkIGluIHRoZSBleHRlbnNpb24ncyAucGIubyBmaWxlLiAgU29tZQorLy8gbGlua2VycyB3aWxsIGFjdHVhbGx5IGRyb3Agb2JqZWN0IGZpbGVzIHRoYXQgYXJlIG5vdCBleHBsaWNpdGx5IHJlZmVyZW5jZWQsCisvLyBidXQgdGhhdCB3b3VsZCBiZSBiYWQgYmVjYXVzZSBpdCB3b3VsZCBjYXVzZSB0aGlzIGV4dGVuc2lvbiB0byBub3QgYmUKKy8vIHJlZ2lzdGVyZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uLCBhbmQgdGhlcmVmb3JlIHVzaW5nIGl0IHdvdWxkIGNyYXNoLgorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRXh0ZW5kZWVUeXBlLCB0eXBlbmFtZSBUeXBlVHJhaXRzVHlwZSwKKyAgICAgICAgICBGaWVsZFR5cGUgZmllbGRfdHlwZSwgYm9vbCBpc19wYWNrZWQ+CitjbGFzcyBFeHRlbnNpb25JZGVudGlmaWVyIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVHlwZVRyYWl0c1R5cGUgVHlwZVRyYWl0czsKKyAgdHlwZWRlZiBFeHRlbmRlZVR5cGUgRXh0ZW5kZWU7CisKKyAgRXh0ZW5zaW9uSWRlbnRpZmllcihpbnQgbnVtYmVyLCB0eXBlbmFtZSBUeXBlVHJhaXRzOjpDb25zdFR5cGUgZGVmYXVsdF92YWx1ZSkKKyAgICAgIDogbnVtYmVyXyhudW1iZXIpLCBkZWZhdWx0X3ZhbHVlXyhkZWZhdWx0X3ZhbHVlKSB7fQorICBpbmxpbmUgaW50IG51bWJlcigpIGNvbnN0IHsgcmV0dXJuIG51bWJlcl87IH0KKyAgdHlwZW5hbWUgVHlwZVRyYWl0czo6Q29uc3RUeXBlIGRlZmF1bHRfdmFsdWUoKSBjb25zdCB7CisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWVfOworICB9CisKKyBwcml2YXRlOgorICBjb25zdCBpbnQgbnVtYmVyXzsKKyAgdHlwZW5hbWUgVHlwZVRyYWl0czo6Q29uc3RUeXBlIGRlZmF1bHRfdmFsdWVfOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gR2VuZXJhdGVkIGFjY2Vzc29ycworCisvLyBUaGlzIG1hY3JvIHNob3VsZCBiZSBleHBhbmRlZCBpbiB0aGUgY29udGV4dCBvZiBhIGdlbmVyYXRlZCB0eXBlIHdoaWNoCisvLyBoYXMgZXh0ZW5zaW9ucy4KKy8vCisvLyBXZSB1c2UgIl9wcm90b19UeXBlVHJhaXRzIiBhcyBhIHR5cGUgbmFtZSBiZWxvdyBiZWNhdXNlICJUeXBlVHJhaXRzIgorLy8gY2F1c2VzIHByb2JsZW1zIGlmIHRoZSBjbGFzcyBoYXMgYSBuZXN0ZWQgbWVzc2FnZSBvciBlbnVtIHR5cGUgd2l0aCB0aGF0CisvLyBuYW1lIGFuZCAiX1R5cGVUcmFpdHMiIGlzIHRlY2huaWNhbGx5IHJlc2VydmVkIGZvciB0aGUgQysrIGxpYnJhcnkgc2luY2UKKy8vIGl0IHN0YXJ0cyB3aXRoIGFuIHVuZGVyc2NvcmUgZm9sbG93ZWQgYnkgYSBjYXBpdGFsIGxldHRlci4KKy8vCisvLyBGb3Igc2ltaWxhciByZWFzb24sIHdlIHVzZSAiX2ZpZWxkX3R5cGUiIGFuZCAiX2lzX3BhY2tlZCIgYXMgcGFyYW1ldGVyIG5hbWVzCisvLyBiZWxvdywgc28gdGhhdCAiZmllbGRfdHlwZSIgYW5kICJpc19wYWNrZWQiIGNhbiBiZSB1c2VkIGFzIGZpZWxkIG5hbWVzLgorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhDTEFTU05BTUUpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAvKiBIYXMsIFNpemUsIENsZWFyICovICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGJvb2wgSGFzRXh0ZW5zaW9uKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQpIGNvbnN0IHsgICBcCisgICAgcmV0dXJuIF9leHRlbnNpb25zXy5IYXMoaWQubnVtYmVyKCkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdm9pZCBDbGVhckV4dGVuc2lvbiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCkgeyAgICAgICAgIFwKKyAgICBfZXh0ZW5zaW9uc18uQ2xlYXJFeHRlbnNpb24oaWQubnVtYmVyKCkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBpbnQgRXh0ZW5zaW9uU2l6ZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkKSBjb25zdCB7ICAgXAorICAgIHJldHVybiBfZXh0ZW5zaW9uc18uRXh0ZW5zaW9uU2l6ZShpZC5udW1iZXIoKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAvKiBTaW5ndWxhciBhY2Nlc3NvcnMgKi8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzOjpTaW5ndWxhcjo6Q29uc3RUeXBlIEdldEV4dGVuc2lvbiggICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQpIGNvbnN0IHsgICBcCisgICAgcmV0dXJuIF9wcm90b19UeXBlVHJhaXRzOjpHZXQoaWQubnVtYmVyKCksIF9leHRlbnNpb25zXywgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQuZGVmYXVsdF92YWx1ZSgpKTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlNpbmd1bGFyOjpNdXRhYmxlVHlwZSBNdXRhYmxlRXh0ZW5zaW9uKCAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCkgeyAgICAgICAgIFwKKyAgICByZXR1cm4gX3Byb3RvX1R5cGVUcmFpdHM6Ok11dGFibGUoaWQubnVtYmVyKCksIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIFNldEV4dGVuc2lvbiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkLCAgICAgICAgICAgXAorICAgICAgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlNpbmd1bGFyOjpDb25zdFR5cGUgdmFsdWUpIHsgICAgICAgICAgICAgICAgXAorICAgIF9wcm90b19UeXBlVHJhaXRzOjpTZXQoaWQubnVtYmVyKCksIF9maWVsZF90eXBlLCB2YWx1ZSwgJl9leHRlbnNpb25zXyk7ICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQsICAgICAgICAgICBcCisgICAgICB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6U2luZ3VsYXI6Ok11dGFibGVUeXBlIHZhbHVlKSB7ICAgICAgICAgICAgICBcCisgICAgX3Byb3RvX1R5cGVUcmFpdHM6OlNldEFsbG9jYXRlZChpZC5udW1iZXIoKSwgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlNpbmd1bGFyOjpNdXRhYmxlVHlwZSBSZWxlYXNlRXh0ZW5zaW9uKCAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCkgeyAgICAgICAgIFwKKyAgICByZXR1cm4gX3Byb3RvX1R5cGVUcmFpdHM6OlJlbGVhc2UoaWQubnVtYmVyKCksIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgLyogUmVwZWF0ZWQgYWNjZXNzb3JzICovICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6OkNvbnN0VHlwZSBHZXRFeHRlbnNpb24oICAgICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkLCAgICAgICAgICAgXAorICAgICAgaW50IGluZGV4KSBjb25zdCB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBfcHJvdG9fVHlwZVRyYWl0czo6R2V0KGlkLm51bWJlcigpLCBfZXh0ZW5zaW9uc18sIGluZGV4KTsgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzOjpSZXBlYXRlZDo6TXV0YWJsZVR5cGUgTXV0YWJsZUV4dGVuc2lvbiggIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQsICAgICAgICAgICBcCisgICAgICBpbnQgaW5kZXgpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIF9wcm90b19UeXBlVHJhaXRzOjpNdXRhYmxlKGlkLm51bWJlcigpLCBpbmRleCwgJl9leHRlbnNpb25zXyk7ICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdm9pZCBTZXRFeHRlbnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCwgICAgICAgICAgIFwKKyAgICAgIGludCBpbmRleCwgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlJlcGVhdGVkOjpDb25zdFR5cGUgdmFsdWUpIHsgICAgIFwKKyAgICBfcHJvdG9fVHlwZVRyYWl0czo6U2V0KGlkLm51bWJlcigpLCBpbmRleCwgdmFsdWUsICZfZXh0ZW5zaW9uc18pOyAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6Ok11dGFibGVUeXBlIEFkZEV4dGVuc2lvbiggICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkKSB7ICAgICAgICAgXAorICAgIHJldHVybiBfcHJvdG9fVHlwZVRyYWl0czo6QWRkKGlkLm51bWJlcigpLCBfZmllbGRfdHlwZSwgJl9leHRlbnNpb25zXyk7ICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgQWRkRXh0ZW5zaW9uKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQsICAgICAgICAgICBcCisgICAgICB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6OkNvbnN0VHlwZSB2YWx1ZSkgeyAgICAgICAgICAgICAgICBcCisgICAgX3Byb3RvX1R5cGVUcmFpdHM6OkFkZChpZC5udW1iZXIoKSwgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQsICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgY29uc3QgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlJlcGVhdGVkOjpSZXBlYXRlZEZpZWxkVHlwZSYgICAgICAgXAorICAgICAgR2V0UmVwZWF0ZWRFeHRlbnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIF9pc19wYWNrZWQ+JiBpZCkgY29uc3QgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gX3Byb3RvX1R5cGVUcmFpdHM6OkdldFJlcGVhdGVkKGlkLm51bWJlcigpLCBfZXh0ZW5zaW9uc18pOyAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6OlJlcGVhdGVkRmllbGRUeXBlKiAgICAgICAgICAgICBcCisgICAgICBNdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICBfaXNfcGFja2VkPiYgaWQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBfcHJvdG9fVHlwZVRyYWl0czo6TXV0YWJsZVJlcGVhdGVkKGlkLm51bWJlcigpLCBfZmllbGRfdHlwZSwgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pc19wYWNrZWQsICZfZXh0ZW5zaW9uc18pOyAgICAgXAorICB9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9TRVRfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfaGVhdnkuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfaGVhdnkuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzk2ZTdhNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldF9oZWF2eS5jYwpAQCAtMCwwICsxLDc0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIENvbnRhaW5zIG1ldGhvZHMgZGVmaW5lZCBpbiBleHRlbnNpb25fc2V0Lmggd2hpY2ggY2Fubm90IGJlIHBhcnQgb2YgdGhlCisvLyBsaXRlIGxpYnJhcnkgYmVjYXVzZSB0aGV5IHVzZSBkZXNjcmlwdG9ycyBvciByZWZsZWN0aW9uLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQSBGaWVsZFNraXBwZXIgdXNlZCB0byBzdG9yZSB1bmtub3duIE1lc3NhZ2VTZXQgZmllbGRzIGludG8gVW5rbm93bkZpZWxkU2V0LgorY2xhc3MgTWVzc2FnZVNldEZpZWxkU2tpcHBlcgorICAgIDogcHVibGljIFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpCisgICAgICA6IFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlcih1bmtub3duX2ZpZWxkcykge30KKyAgdmlydHVhbCB+TWVzc2FnZVNldEZpZWxkU2tpcHBlcigpIHt9CisKKyAgdmlydHVhbCBib29sIFNraXBNZXNzYWdlU2V0RmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyKTsKK307Citib29sIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXI6OlNraXBNZXNzYWdlU2V0RmllbGQoCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBpbnQgZmllbGRfbnVtYmVyKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBpZiAodW5rbm93bl9maWVsZHNfID09IE5VTEwpIHsKKyAgICByZXR1cm4gaW5wdXQtPlNraXAobGVuZ3RoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gaW5wdXQtPlJlYWRTdHJpbmcoCisgICAgICAgIHVua25vd25fZmllbGRzXy0+QWRkTGVuZ3RoRGVsaW1pdGVkKGZpZWxkX251bWJlciksIGxlbmd0aCk7CisgIH0KK30KKworCisvLyBJbXBsZW1lbnRhdGlvbiBvZiBFeHRlbnNpb25GaW5kZXIgd2hpY2ggZmluZHMgZXh0ZW5zaW9ucyBpbiBhIGdpdmVuCisvLyBEZXNjcmlwdG9yUG9vbCwgdXNpbmcgdGhlIGdpdmVuIE1lc3NhZ2VGYWN0b3J5IHRvIGNvbnN0cnVjdCBzdWItb2JqZWN0cy4KKy8vIFRoaXMgY2xhc3MgaXMgaW1wbGVtZW50ZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KK2NsYXNzIERlc2NyaXB0b3JQb29sRXh0ZW5zaW9uRmluZGVyIDogcHVibGljIEV4dGVuc2lvbkZpbmRlciB7CisgcHVibGljOgorICBEZXNjcmlwdG9yUG9vbEV4dGVuc2lvbkZpbmRlcihjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSkKKyAgICAgIDogcG9vbF8ocG9vbCksIGZhY3RvcnlfKGZhY3RvcnkpLCBjb250YWluaW5nX3R5cGVfKGNvbnRhaW5pbmdfdHlwZSkge30KKyAgdmlydHVhbCB+RGVzY3JpcHRvclBvb2xFeHRlbnNpb25GaW5kZXIoKSB7fQorCisgIHZpcnR1YWwgYm9vbCBGaW5kKGludCBudW1iZXIsIEV4dGVuc2lvbkluZm8qIG91dHB1dCk7CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbF87CisgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5XzsKKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlXzsKK307CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpBcHBlbmRUb0xpc3QoCisgICAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgIHN0ZDo6dmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KiBvdXRwdXQpIGNvbnN0IHsKKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBib29sIGhhcyA9IGZhbHNlOworICAgIGlmIChpdGVyLT5zZWNvbmQuaXNfcmVwZWF0ZWQpIHsKKyAgICAgIGhhcyA9IGl0ZXItPnNlY29uZC5HZXRTaXplKCkgPiAwOworICAgIH0gZWxzZSB7CisgICAgICBoYXMgPSAhaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQ7CisgICAgfQorCisgICAgaWYgKGhhcykgeworICAgICAgLy8gVE9ETyhrZW50b24pOiBMb29raW5nIHVwIGVhY2ggZmllbGQgYnkgbnVtYmVyIGlzIHNvbWV3aGF0IHVuZm9ydHVuYXRlLgorICAgICAgLy8gICBJcyB0aGVyZSBhIGJldHRlciB3YXk/ICBUaGUgcHJvYmxlbSBpcyB0aGF0IGRlc2NyaXB0b3JzIGFyZSBsYXppbHktCisgICAgICAvLyAgIGluaXRpYWxpemVkLCBzbyB0aGV5IG1pZ2h0IG5vdCBldmVuIGJlIGNvbnN0cnVjdGVkIHVudGlsCisgICAgICAvLyAgIEFwcGVuZFRvTGlzdCgpIGlzIGNhbGxlZC4KKworICAgICAgaWYgKGl0ZXItPnNlY29uZC5kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2socG9vbC0+RmluZEV4dGVuc2lvbkJ5TnVtYmVyKAorICAgICAgICAgICAgY29udGFpbmluZ190eXBlLCBpdGVyLT5maXJzdCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soaXRlci0+c2Vjb25kLmRlc2NyaXB0b3IpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitpbmxpbmUgRmllbGREZXNjcmlwdG9yOjpUeXBlIHJlYWxfdHlwZShGaWVsZFR5cGUgdHlwZSkgeworICBHT09HTEVfRENIRUNLKHR5cGUgPiAwICYmIHR5cGUgPD0gRmllbGREZXNjcmlwdG9yOjpNQVhfVFlQRSk7CisgIHJldHVybiBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OlR5cGU+KHR5cGUpOworfQorCitpbmxpbmUgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlKEZpZWxkVHlwZSB0eXBlKSB7CisgIHJldHVybiBGaWVsZERlc2NyaXB0b3I6OlR5cGVUb0NwcFR5cGUoCisgICAgICBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OlR5cGU+KHR5cGUpKTsKK30KKworaW5saW5lIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgZmllbGRfdHlwZShGaWVsZFR5cGUgdHlwZSkgeworICBHT09HTEVfRENIRUNLKHR5cGUgPiAwICYmIHR5cGUgPD0gV2lyZUZvcm1hdExpdGU6Ok1BWF9GSUVMRF9UWVBFKTsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGU+KHR5cGUpOworfQorCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfVFlQRShFWFRFTlNJT04sIExBQkVMLCBDUFBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIEdPT0dMRV9EQ0hFQ0tfRVEoKEVYVEVOU0lPTikuaXNfcmVwZWF0ZWQgPyBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMLCAgICAgIFwKKyAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfIyNMQUJFTCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBHT09HTEVfRENIRUNLX0VRKGNwcF90eXBlKChFWFRFTlNJT04pLnR5cGUpLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFKQorCitjb25zdCBNZXNzYWdlTGl0ZSYgRXh0ZW5zaW9uU2V0OjpHZXRNZXNzYWdlKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkgfHwgaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQpIHsKKyAgICAvLyBOb3QgcHJlc2VudC4gIFJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICByZXR1cm4gKmZhY3RvcnktPkdldFByb3RvdHlwZShtZXNzYWdlX3R5cGUpOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBNRVNTQUdFKTsKKyAgICBpZiAoaXRlci0+c2Vjb25kLmlzX2xhenkpIHsKKyAgICAgIHJldHVybiBpdGVyLT5zZWNvbmQubGF6eW1lc3NhZ2VfdmFsdWUtPkdldE1lc3NhZ2UoCisgICAgICAgICAgKmZhY3RvcnktPkdldFByb3RvdHlwZShtZXNzYWdlX3R5cGUpKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuICppdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZTsKKyAgICB9CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6TXV0YWJsZU1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihkZXNjcmlwdG9yLT5udW1iZXIoKSwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSBkZXNjcmlwdG9yLT50eXBlKCk7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IGZhbHNlOworICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gZmFsc2U7CisgICAgY29uc3QgTWVzc2FnZUxpdGUqIHByb3RvdHlwZSA9CisgICAgICAgIGZhY3RvcnktPkdldFByb3RvdHlwZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlID0gcHJvdG90eXBlLT5OZXcoYXJlbmFfKTsKKyAgICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKKyAgICByZXR1cm4gZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRSgqZXh0ZW5zaW9uLCBPUFRJT05BTCwgTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgICAgaWYgKGV4dGVuc2lvbi0+aXNfbGF6eSkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPk11dGFibGVNZXNzYWdlKAorICAgICAgICAgICpmYWN0b3J5LT5HZXRQcm90b3R5cGUoZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCkpKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZTsKKyAgICB9CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6UmVsZWFzZU1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIE5VTEwuCisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgT1BUSU9OQUwsIE1FU1NBR0UpOworICAgIE1lc3NhZ2VMaXRlKiByZXQgPSBOVUxMOworICAgIGlmIChpdGVyLT5zZWNvbmQuaXNfbGF6eSkgeworICAgICAgcmV0ID0gaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlLT5SZWxlYXNlTWVzc2FnZSgKKyAgICAgICAgICAqZmFjdG9yeS0+R2V0UHJvdG90eXBlKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKSk7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgICAgZGVsZXRlIGl0ZXItPnNlY29uZC5sYXp5bWVzc2FnZV92YWx1ZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKGFyZW5hXyAhPSBOVUxMKSB7CisgICAgICAgIHJldCA9IChpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZSktPk5ldygpOworICAgICAgICByZXQtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgqKGl0ZXItPnNlY29uZC5tZXNzYWdlX3ZhbHVlKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXQgPSBpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgZXh0ZW5zaW9uc18uZXJhc2UoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAgIHJldHVybiByZXQ7CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6QWRkTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KSB7CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24oZGVzY3JpcHRvci0+bnVtYmVyKCksIGRlc2NyaXB0b3IsICZleHRlbnNpb24pKSB7CisgICAgZXh0ZW5zaW9uLT50eXBlID0gZGVzY3JpcHRvci0+dHlwZSgpOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpOworICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSB0cnVlOworICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZSA9CisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZTxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiA+KGFyZW5hXywgYXJlbmFfKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgUkVQRUFURUQsIE1FU1NBR0UpOworICB9CisKKyAgLy8gUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiBkb2VzIG5vdCBrbm93IGhvdyB0byBBZGQoKSBzaW5jZSBpdCBjYW5ub3QKKyAgLy8gYWxsb2NhdGUgYW4gYWJzdHJhY3Qgb2JqZWN0LCBzbyB3ZSBoYXZlIHRvIGJlIHRyaWNreS4KKyAgTWVzc2FnZUxpdGUqIHJlc3VsdCA9IGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZQorICAgICAgLT5BZGRGcm9tQ2xlYXJlZDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+ID4oKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgY29uc3QgTWVzc2FnZUxpdGUqIHByb3RvdHlwZTsKKyAgICBpZiAoZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5zaXplKCkgPT0gMCkgeworICAgICAgcHJvdG90eXBlID0gZmFjdG9yeS0+R2V0UHJvdG90eXBlKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICAgIEdPT0dMRV9DSEVDSyhwcm90b3R5cGUgIT0gTlVMTCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHByb3RvdHlwZSA9ICZleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkdldCgwKTsKKyAgICB9CisgICAgcmVzdWx0ID0gcHJvdG90eXBlLT5OZXcoYXJlbmFfKTsKKyAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkFkZEFsbG9jYXRlZChyZXN1bHQpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBib29sIFZhbGlkYXRlRW51bVVzaW5nRGVzY3JpcHRvcihjb25zdCB2b2lkKiBhcmcsIGludCBudW1iZXIpIHsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgRW51bURlc2NyaXB0b3IqPihhcmcpCisgICAgICAtPkZpbmRWYWx1ZUJ5TnVtYmVyKG51bWJlcikgIT0gTlVMTDsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbEV4dGVuc2lvbkZpbmRlcjo6RmluZChpbnQgbnVtYmVyLCBFeHRlbnNpb25JbmZvKiBvdXRwdXQpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24gPQorICAgICAgcG9vbF8tPkZpbmRFeHRlbnNpb25CeU51bWJlcihjb250YWluaW5nX3R5cGVfLCBudW1iZXIpOworICBpZiAoZXh0ZW5zaW9uID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgb3V0cHV0LT50eXBlID0gZXh0ZW5zaW9uLT50eXBlKCk7CisgICAgb3V0cHV0LT5pc19yZXBlYXRlZCA9IGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQoKTsKKyAgICBvdXRwdXQtPmlzX3BhY2tlZCA9IGV4dGVuc2lvbi0+b3B0aW9ucygpLnBhY2tlZCgpOworICAgIG91dHB1dC0+ZGVzY3JpcHRvciA9IGV4dGVuc2lvbjsKKyAgICBpZiAoZXh0ZW5zaW9uLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBvdXRwdXQtPm1lc3NhZ2VfcHJvdG90eXBlID0KKyAgICAgICAgICBmYWN0b3J5Xy0+R2V0UHJvdG90eXBlKGV4dGVuc2lvbi0+bWVzc2FnZV90eXBlKCkpOworICAgICAgR09PR0xFX0NIRUNLKG91dHB1dC0+bWVzc2FnZV9wcm90b3R5cGUgIT0gTlVMTCkKKyAgICAgICAgICA8PCAiRXh0ZW5zaW9uIGZhY3RvcnkncyBHZXRQcm90b3R5cGUoKSByZXR1cm5lZCBOVUxMIGZvciBleHRlbnNpb246ICIKKyAgICAgICAgICA8PCBleHRlbnNpb24tPmZ1bGxfbmFtZSgpOworICAgIH0gZWxzZSBpZiAoZXh0ZW5zaW9uLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNKSB7CisgICAgICBvdXRwdXQtPmVudW1fdmFsaWRpdHlfY2hlY2suZnVuYyA9IFZhbGlkYXRlRW51bVVzaW5nRGVzY3JpcHRvcjsKKyAgICAgIG91dHB1dC0+ZW51bV92YWxpZGl0eV9jaGVjay5hcmcgPSBleHRlbnNpb24tPmVudW1fdHlwZSgpOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgVW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyIHNraXBwZXIodW5rbm93bl9maWVsZHMpOworICBpZiAoaW5wdXQtPkdldEV4dGVuc2lvblBvb2woKSA9PSBOVUxMKSB7CisgICAgR2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyIGZpbmRlcihjb250YWluaW5nX3R5cGUpOworICAgIHJldHVybiBQYXJzZUZpZWxkKHRhZywgaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKKyAgfSBlbHNlIHsKKyAgICBEZXNjcmlwdG9yUG9vbEV4dGVuc2lvbkZpbmRlciBmaW5kZXIoaW5wdXQtPkdldEV4dGVuc2lvblBvb2woKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtPkdldEV4dGVuc2lvbkZhY3RvcnkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ190eXBlLT5HZXREZXNjcmlwdG9yKCkpOworICAgIHJldHVybiBQYXJzZUZpZWxkKHRhZywgaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKKyAgfQorfQorCitib29sIEV4dGVuc2lvblNldDo6UGFyc2VNZXNzYWdlU2V0KGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXIgc2tpcHBlcih1bmtub3duX2ZpZWxkcyk7CisgIGlmIChpbnB1dC0+R2V0RXh0ZW5zaW9uUG9vbCgpID09IE5VTEwpIHsKKyAgICBHZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXIgZmluZGVyKGNvbnRhaW5pbmdfdHlwZSk7CisgICAgcmV0dXJuIFBhcnNlTWVzc2FnZVNldChpbnB1dCwgJmZpbmRlciwgJnNraXBwZXIpOworICB9IGVsc2UgeworICAgIERlc2NyaXB0b3JQb29sRXh0ZW5zaW9uRmluZGVyIGZpbmRlcihpbnB1dC0+R2V0RXh0ZW5zaW9uUG9vbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGUtPkdldERlc2NyaXB0b3IoKSk7CisgICAgcmV0dXJuIFBhcnNlTWVzc2FnZVNldChpbnB1dCwgJmZpbmRlciwgJnNraXBwZXIpOworICB9Cit9CisKK2ludCBFeHRlbnNpb25TZXQ6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0KKyAgICAgIGV4dGVuc2lvbnNfLnNpemUoKSAqIHNpemVvZihtYXA8aW50LCBFeHRlbnNpb24+Ojp2YWx1ZV90eXBlKTsKKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKSwKKyAgICAgICBlbmQgPSBleHRlbnNpb25zXy5lbmQoKTsKKyAgICAgICBpdGVyICE9IGVuZDsKKyAgICAgICArK2l0ZXIpIHsKKyAgICB0b3RhbF9zaXplICs9IGl0ZXItPnNlY29uZC5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7CisgIH0KKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK2lubGluZSBpbnQgRXh0ZW5zaW9uU2V0OjpSZXBlYXRlZE1lc3NhZ2VfU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigKKyAgICBSZXBlYXRlZFB0ckZpZWxkQmFzZSogZmllbGQpIHsKKyAgcmV0dXJuIGZpZWxkLT5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7Cit9CisKK2ludCBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbjo6U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworICBpZiAoaXNfcmVwZWF0ZWQpIHsKKyAgICBzd2l0Y2ggKGNwcF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgdG90YWxfc2l6ZSArPSBzaXplb2YoKnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUpICsgICAgICBcCisgICAgICAgICAgICByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7XAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggIElOVDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UNjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoIFVJTlQzMiwgIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDY0LCAgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRkxPQVQsICAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoIERPVUJMRSwgIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBCT09MLCAgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEVOVU0sICAgIGVudW0pOworICAgICAgSEFORExFX1RZUEUoIFNUUklORywgIHN0cmluZyk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgLy8gcmVwZWF0ZWRfbWVzc2FnZV92YWx1ZSBpcyBhY3R1YWxseSBhIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+LAorICAgICAgICAvLyBidXQgTWVzc2FnZUxpdGUgaGFzIG5vIFNwYWNlVXNlZCgpLCBzbyB3ZSBtdXN0IGRpcmVjdGx5IGNhbGwKKyAgICAgICAgLy8gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSB3aXRoIGEgZGlmZmVyZW50IHR5cGUKKyAgICAgICAgLy8gaGFuZGxlci4KKyAgICAgICAgdG90YWxfc2l6ZSArPSBzaXplb2YoKnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUpICsKKyAgICAgICAgICAgIFJlcGVhdGVkTWVzc2FnZV9TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKHJlcGVhdGVkX21lc3NhZ2VfdmFsdWUpOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChjcHBfdHlwZSh0eXBlKSkgeworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICB0b3RhbF9zaXplICs9IHNpemVvZigqc3RyaW5nX3ZhbHVlKSArCisgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigqc3RyaW5nX3ZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoaXNfbGF6eSkgeworICAgICAgICAgIHRvdGFsX3NpemUgKz0gbGF6eW1lc3NhZ2VfdmFsdWUtPlNwYWNlVXNlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHRvdGFsX3NpemUgKz0gZG93bl9jYXN0PE1lc3NhZ2UqPihtZXNzYWdlX3ZhbHVlKS0+U3BhY2VVc2VkKCk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICAvLyBObyBleHRyYSBzdG9yYWdlIGNvc3RzIGZvciBwcmltaXRpdmUgdHlwZXMuCisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKworLy8gVGhlIFNlcmlhbGl6ZSpUb0FycmF5IG1ldGhvZHMgYXJlIG9ubHkgbmVlZGVkIGluIHRoZSBoZWF2eSBsaWJyYXJ5LCBhcworLy8gdGhlIGxpdGUgbGlicmFyeSBvbmx5IGdlbmVyYXRlcyBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMuCit1aW50OCogRXh0ZW5zaW9uU2V0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIGludCBzdGFydF9maWVsZF9udW1iZXIsIGludCBlbmRfZmllbGRfbnVtYmVyLAorICAgIHVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlcjsKKyAgZm9yIChpdGVyID0gZXh0ZW5zaW9uc18ubG93ZXJfYm91bmQoc3RhcnRfZmllbGRfbnVtYmVyKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpICYmIGl0ZXItPmZpcnN0IDwgZW5kX2ZpZWxkX251bWJlcjsKKyAgICAgICArK2l0ZXIpIHsKKyAgICB0YXJnZXQgPSBpdGVyLT5zZWNvbmQuU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGl0ZXItPmZpcnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0KTsKKyAgfQorICByZXR1cm4gdGFyZ2V0OworfQorCit1aW50OCogRXh0ZW5zaW9uU2V0OjpTZXJpYWxpemVNZXNzYWdlU2V0V2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICB1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXI7CisgIGZvciAoaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7IGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCk7ICsraXRlcikgeworICAgIHRhcmdldCA9IGl0ZXItPnNlY29uZC5TZXJpYWxpemVNZXNzYWdlU2V0SXRlbVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAgIGl0ZXItPmZpcnN0LCB0YXJnZXQpOworICB9CisgIHJldHVybiB0YXJnZXQ7Cit9CisKK3VpbnQ4KiBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbjo6U2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIGludCBudW1iZXIsIHVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgaWYgKGlzX3BhY2tlZCkgeworICAgICAgaWYgKGNhY2hlZF9zaXplID09IDApIHJldHVybiB0YXJnZXQ7CisKKyAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZ1RvQXJyYXkobnVtYmVyLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELCB0YXJnZXQpOworICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJOb1RhZ1RvQXJyYXkoY2FjaGVkX3NpemUsIHRhcmdldCk7CisKKyAgICAgIHN3aXRjaCAocmVhbF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPnNpemUoKTsgaSsrKSB7ICBcCisgICAgICAgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI0NBTUVMQ0FTRSMjTm9UYWdUb0FycmF5KCAgICAgICAgXAorICAgICAgICAgICAgICByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5HZXQoaSksIHRhcmdldCk7ICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWsKKworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQ2NCwgICAgSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQzMiwgICBVSW50MzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQzMiwgICBTSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQ2NCwgICBTSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICAgZmxvYXQpOworICAgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgICBEb3VibGUsICBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgIGJvb2wpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgIGVudW0pOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkc6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfQllURVM6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfR1JPVVA6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm9uLXByaW1pdGl2ZSB0eXBlcyBjYW4ndCBiZSBwYWNrZWQuIjsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgc3dpdGNoIChyZWFsX3R5cGUodHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyBpKyspIHsgIFwKKyAgICAgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjQ0FNRUxDQVNFIyNUb0FycmF5KG51bWJlciwgICAgICBcCisgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkdldChpKSwgdGFyZ2V0KTsgICAgICAgICAgICAgICAgXAorICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgICBJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDMyLCAgIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCAgIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDY0LCAgIFNJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCAgRml4ZWQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCBTRml4ZWQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgICBGbG9hdCwgICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSwgIGRvdWJsZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgICAgQm9vbCwgICAgYm9vbCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU1RSSU5HLCAgIFN0cmluZywgIHN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEJZVEVTLCAgICBCeXRlcywgIHN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBFTlVNLCAgICAgRW51bSwgICAgZW51bSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEdST1VQLCAgICBHcm91cCwgbWVzc2FnZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCBNRVNTQUdFLCAgTWVzc2FnZSwgbWVzc2FnZSk7CisjdW5kZWYgSEFORExFX1RZUEUKKyAgICAgIH0KKyAgICB9CisgIH0gZWxzZSBpZiAoIWlzX2NsZWFyZWQpIHsKKyAgICBzd2l0Y2ggKHJlYWxfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENBTUVMQ0FTRSwgVkFMVUUpICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlIyNDQU1FTENBU0UjI1RvQXJyYXkoICAgICAgXAorICAgICAgICAgICAgbnVtYmVyLCBWQUxVRSwgdGFyZ2V0KTsgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgIGludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICAgaW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgIHVpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICAgdWludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICAgaW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgICBpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICAgdWludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCwgICB1aW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoU0ZJWEVEMzIsIFNGaXhlZDMyLCAgICBpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgIGludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgICBGbG9hdCwgICAgZmxvYXRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBET1VCTEUsICAgRG91YmxlLCAgIGRvdWJsZV92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgICBib29sX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU1RSSU5HLCAgIFN0cmluZywgICpzdHJpbmdfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgQllURVMsICAgIEJ5dGVzLCAgKnN0cmluZ192YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgICBlbnVtX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEdST1VQLCAgICBHcm91cCwgKm1lc3NhZ2VfdmFsdWUpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoaXNfbGF6eSkgeworICAgICAgICAgIHRhcmdldCA9IGxhenltZXNzYWdlX3ZhbHVlLT5Xcml0ZU1lc3NhZ2VUb0FycmF5KG51bWJlciwgdGFyZ2V0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlVG9BcnJheSgKKyAgICAgICAgICAgICAgbnVtYmVyLCAqbWVzc2FnZV92YWx1ZSwgdGFyZ2V0KTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRhcmdldDsKK30KKwordWludDgqIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpTZXJpYWxpemVNZXNzYWdlU2V0SXRlbVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgaW50IG51bWJlciwKKyAgICB1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIGlmICh0eXBlICE9IFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UgfHwgaXNfcmVwZWF0ZWQpIHsKKyAgICAvLyBOb3QgYSB2YWxpZCBNZXNzYWdlU2V0IGV4dGVuc2lvbiwgYnV0IHNlcmlhbGl6ZSBpdCB0aGUgbm9ybWFsIHdheS4KKyAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJJbnZhbGlkIG1lc3NhZ2Ugc2V0IGV4dGVuc2lvbi4iOworICAgIHJldHVybiBTZXJpYWxpemVGaWVsZFdpdGhDYWNoZWRTaXplc1RvQXJyYXkobnVtYmVyLCB0YXJnZXQpOworICB9CisKKyAgaWYgKGlzX2NsZWFyZWQpIHJldHVybiB0YXJnZXQ7CisKKyAgLy8gU3RhcnQgZ3JvdXAuCisgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnLCB0YXJnZXQpOworICAvLyBXcml0ZSB0eXBlIElELgorICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzJUb0FycmF5KAorICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0VHlwZUlkTnVtYmVyLCBudW1iZXIsIHRhcmdldCk7CisgIC8vIFdyaXRlIG1lc3NhZ2UuCisgIGlmIChpc19sYXp5KSB7CisgICAgdGFyZ2V0ID0gbGF6eW1lc3NhZ2VfdmFsdWUtPldyaXRlTWVzc2FnZVRvQXJyYXkoCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldE1lc3NhZ2VOdW1iZXIsIHRhcmdldCk7CisgIH0gZWxzZSB7CisgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZVRvQXJyYXkoCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldE1lc3NhZ2VOdW1iZXIsICptZXNzYWdlX3ZhbHVlLCB0YXJnZXQpOworICB9CisgIC8vIEVuZCBncm91cC4KKyAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnLCB0YXJnZXQpOworICByZXR1cm4gdGFyZ2V0OworfQorCisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkTWF5YmVMYXppbHkoCisgICAgaW50IHdpcmVfdHlwZSwgaW50IGZpZWxkX251bWJlciwgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwKKyAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKSB7CisgIHJldHVybiBQYXJzZUZpZWxkKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgZmllbGRfbnVtYmVyLCBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGU+KHdpcmVfdHlwZSkpLAorICAgICAgICAgICAgICAgICAgICBpbnB1dCwgZXh0ZW5zaW9uX2ZpbmRlciwgZmllbGRfc2tpcHBlcik7Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZU1lc3NhZ2VTZXQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXIqIGZpZWxkX3NraXBwZXIpIHsKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBjb25zdCB1aW50MzIgdGFnID0gaW5wdXQtPlJlYWRUYWcoKTsKKyAgICBzd2l0Y2ggKHRhZykgeworICAgICAgY2FzZSAwOgorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnOgorICAgICAgICBpZiAoIVBhcnNlTWVzc2FnZVNldEl0ZW0oaW5wdXQsIGV4dGVuc2lvbl9maW5kZXIsIGZpZWxkX3NraXBwZXIpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgaWYgKCFQYXJzZUZpZWxkKHRhZywgaW5wdXQsIGV4dGVuc2lvbl9maW5kZXIsIGZpZWxkX3NraXBwZXIpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCitib29sIEV4dGVuc2lvblNldDo6UGFyc2VNZXNzYWdlU2V0KGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSkgeworICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyIHNraXBwZXIoTlVMTCk7CisgIEdlbmVyYXRlZEV4dGVuc2lvbkZpbmRlciBmaW5kZXIoY29udGFpbmluZ190eXBlKTsKKyAgcmV0dXJuIFBhcnNlTWVzc2FnZVNldChpbnB1dCwgJmZpbmRlciwgJnNraXBwZXIpOworfQorCitib29sIEV4dGVuc2lvblNldDo6UGFyc2VNZXNzYWdlU2V0SXRlbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKSB7CisgIC8vIFRPRE8oa2VudG9uKTogIEl0IHdvdWxkIGJlIG5pY2UgdG8gc2hhcmUgY29kZSBiZXR3ZWVuIHRoaXMgYW5kCisgIC8vIFdpcmVGb3JtYXRMaXRlOjpQYXJzZUFuZE1lcmdlTWVzc2FnZVNldEl0ZW0oKSwgYnV0IEkgdGhpbmsgdGhlCisgIC8vIGRpZmZlcmVuY2VzIHdvdWxkIGJlIGhhcmQgdG8gZmFjdG9yIG91dC4KKworICAvLyBUaGlzIG1ldGhvZCBwYXJzZXMgYSBncm91cCB3aGljaCBzaG91bGQgY29udGFpbiB0d28gZmllbGRzOgorICAvLyAgIHJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOworICAvLyAgIHJlcXVpcmVkIGRhdGEgbWVzc2FnZSA9IDM7CisKKyAgdWludDMyIGxhc3RfdHlwZV9pZCA9IDA7CisKKyAgLy8gSWYgd2Ugc2VlIG1lc3NhZ2UgZGF0YSBiZWZvcmUgdGhlIHR5cGVfaWQsIHdlJ2xsIGFwcGVuZCBpdCB0byB0aGlzIHNvCisgIC8vIHdlIGNhbiBwYXJzZSBpdCBsYXRlci4KKyAgc3RyaW5nIG1lc3NhZ2VfZGF0YTsKKworICB3aGlsZSAodHJ1ZSkgeworICAgIGNvbnN0IHVpbnQzMiB0YWcgPSBpbnB1dC0+UmVhZFRhZygpOworICAgIGlmICh0YWcgPT0gMCkgcmV0dXJuIGZhbHNlOworCisgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0VHlwZUlkVGFnOiB7CisgICAgICAgIHVpbnQzMiB0eXBlX2lkOworICAgICAgICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJnR5cGVfaWQpKSByZXR1cm4gZmFsc2U7CisgICAgICAgIGxhc3RfdHlwZV9pZCA9IHR5cGVfaWQ7CisKKyAgICAgICAgaWYgKCFtZXNzYWdlX2RhdGEuZW1wdHkoKSkgeworICAgICAgICAgIC8vIFdlIHNhdyBzb21lIG1lc3NhZ2UgZGF0YSBiZWZvcmUgdGhlIHR5cGVfaWQuICBIYXZlIHRvIHBhcnNlIGl0CisgICAgICAgICAgLy8gbm93LgorICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIHN1Yl9pbnB1dCgKKyAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KG1lc3NhZ2VfZGF0YS5kYXRhKCkpLAorICAgICAgICAgICAgICBtZXNzYWdlX2RhdGEuc2l6ZSgpKTsKKyAgICAgICAgICBpZiAoIVBhcnNlRmllbGRNYXliZUxhemlseShXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0X3R5cGVfaWQsICZzdWJfaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX2ZpbmRlciwgZmllbGRfc2tpcHBlcikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgICAgbWVzc2FnZV9kYXRhLmNsZWFyKCk7CisgICAgICAgIH0KKworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlVGFnOiB7CisgICAgICAgIGlmIChsYXN0X3R5cGVfaWQgPT0gMCkgeworICAgICAgICAgIC8vIFdlIGhhdmVuJ3Qgc2VlbiBhIHR5cGVfaWQgeWV0LiAgQXBwZW5kIHRoaXMgZGF0YSB0byBtZXNzYWdlX2RhdGEuCisgICAgICAgICAgc3RyaW5nIHRlbXA7CisgICAgICAgICAgdWludDMyIGxlbmd0aDsKKyAgICAgICAgICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgICAgICAgICBpZiAoIWlucHV0LT5SZWFkU3RyaW5nKCZ0ZW1wLCBsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZtZXNzYWdlX2RhdGEpOworICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQoJm91dHB1dF9zdHJlYW0pOworICAgICAgICAgIGNvZGVkX291dHB1dC5Xcml0ZVZhcmludDMyKGxlbmd0aCk7CisgICAgICAgICAgY29kZWRfb3V0cHV0LldyaXRlU3RyaW5nKHRlbXApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIEFscmVhZHkgc2F3IHR5cGVfaWQsIHNvIHdlIGNhbiBwYXJzZSB0aGlzIGRpcmVjdGx5LgorICAgICAgICAgIGlmICghUGFyc2VGaWVsZE1heWJlTGF6aWx5KFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RfdHlwZV9pZCwgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX2ZpbmRlciwgZmllbGRfc2tpcHBlcikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnOiB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICAgIGlmICghZmllbGRfc2tpcHBlci0+U2tpcEZpZWxkKGlucHV0LCB0YWcpKSByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OlNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzKAorICAgIGludCBudW1iZXIsCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaWYgKHR5cGUgIT0gV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSB8fCBpc19yZXBlYXRlZCkgeworICAgIC8vIE5vdCBhIHZhbGlkIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uLCBidXQgc2VyaWFsaXplIGl0IHRoZSBub3JtYWwgd2F5LgorICAgIFNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzKG51bWJlciwgb3V0cHV0KTsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAoaXNfY2xlYXJlZCkgcmV0dXJuOworCisgIC8vIFN0YXJ0IGdyb3VwLgorICBvdXRwdXQtPldyaXRlVGFnKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZyk7CisKKyAgLy8gV3JpdGUgdHlwZSBJRC4KKyAgV2lyZUZvcm1hdExpdGU6OldyaXRlVUludDMyKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCk7CisgIC8vIFdyaXRlIG1lc3NhZ2UuCisgIGlmIChpc19sYXp5KSB7CisgICAgbGF6eW1lc3NhZ2VfdmFsdWUtPldyaXRlTWVzc2FnZSgKKyAgICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZU51bWJlciwgb3V0cHV0KTsKKyAgfSBlbHNlIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlTnVtYmVyLAorICAgICAgICAqbWVzc2FnZV92YWx1ZSwKKyAgICAgICAgb3V0cHV0KTsKKyAgfQorCisgIC8vIEVuZCBncm91cC4KKyAgb3V0cHV0LT5Xcml0ZVRhZyhXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnKTsKK30KKworaW50IEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpNZXNzYWdlU2V0SXRlbUJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0IHsKKyAgaWYgKHR5cGUgIT0gV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSB8fCBpc19yZXBlYXRlZCkgeworICAgIC8vIE5vdCBhIHZhbGlkIE1lc3NhZ2VTZXQgZXh0ZW5zaW9uLCBidXQgY29tcHV0ZSB0aGUgYnl0ZSBzaXplIGZvciBpdCB0aGUKKyAgICAvLyBub3JtYWwgd2F5LgorICAgIHJldHVybiBCeXRlU2l6ZShudW1iZXIpOworICB9CisKKyAgaWYgKGlzX2NsZWFyZWQpIHJldHVybiAwOworCisgIGludCBvdXJfc2l6ZSA9IFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1UYWdzU2l6ZTsKKworICAvLyB0eXBlX2lkCisgIG91cl9zaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKG51bWJlcik7CisKKyAgLy8gbWVzc2FnZQorICBpbnQgbWVzc2FnZV9zaXplID0gMDsKKyAgaWYgKGlzX2xhenkpIHsKKyAgICBtZXNzYWdlX3NpemUgPSBsYXp5bWVzc2FnZV92YWx1ZS0+Qnl0ZVNpemUoKTsKKyAgfSBlbHNlIHsKKyAgICBtZXNzYWdlX3NpemUgPSBtZXNzYWdlX3ZhbHVlLT5CeXRlU2l6ZSgpOworICB9CisKKyAgb3VyX3NpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIobWVzc2FnZV9zaXplKTsKKyAgb3VyX3NpemUgKz0gbWVzc2FnZV9zaXplOworCisgIHJldHVybiBvdXJfc2l6ZTsKK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlNlcmlhbGl6ZU1lc3NhZ2VTZXRXaXRoQ2FjaGVkU2l6ZXMoCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBpdGVyLT5zZWNvbmQuU2VyaWFsaXplTWVzc2FnZVNldEl0ZW1XaXRoQ2FjaGVkU2l6ZXMoaXRlci0+Zmlyc3QsIG91dHB1dCk7CisgIH0KK30KKworaW50IEV4dGVuc2lvblNldDo6TWVzc2FnZVNldEJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICB0b3RhbF9zaXplICs9IGl0ZXItPnNlY29uZC5NZXNzYWdlU2V0SXRlbUJ5dGVTaXplKGl0ZXItPmZpcnN0KTsKKyAgfQorCisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0X3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0X3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4NGNlMDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMjA3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CituYW1lc3BhY2UgeworCisvLyBUaGlzIHRlc3QgY2xvc2VseSBtaXJyb3JzIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvdW5pdHRlc3QuY2MKKy8vIGV4Y2VwdCB0aGF0IGl0IHVzZXMgZXh0ZW5zaW9ucyByYXRoZXIgdGhhbiByZWd1bGFyIGZpZWxkcy4KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBEZWZhdWx0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBkZWZhdWx0IHZhbHVlcyBhcmUgc2V0IGNvcnJlY3RseSBpbiB0aGUgaW5pdGlhbCBtZXNzYWdlLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UpOworCisgIC8vIE1lc3NhZ2VzIHNob3VsZCByZXR1cm4gcG9pbnRlcnMgdG8gZGVmYXVsdCBpbnN0YW5jZXMgdW50aWwgZmlyc3QgdXNlLgorICAvLyAoVGhpcyBpcyBub3QgY2hlY2tlZCBieSBFeHBlY3RDbGVhcigpIHNpbmNlIGl0IGlzIG5vdCBhY3R1YWxseSB0cnVlIGFmdGVyCisgIC8vIHRoZSBmaWVsZHMgaGF2ZSBiZWVuIHNldCBhbmQgdGhlbiBjbGVhcmVkLikKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6T3B0aW9uYWxHcm91cF9leHRlbnNpb246OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24pKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBBY2Nlc3NvcnMpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlIHRoZW4gZ28gYmFjayBhbmQgY2hlY2sgYWxsIHRob3NlCisgIC8vIHZhbHVlcy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKworICBUZXN0VXRpbDo6TW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRXh0ZW5zaW9uc01vZGlmaWVkKG1lc3NhZ2UpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIENsZWFyKSB7CisgIC8vIFNldCBldmVyeSBmaWVsZCB0byBhIHVuaXF1ZSB2YWx1ZSwgY2xlYXIgdGhlIG1lc3NhZ2UsIHRoZW4gY2hlY2sgdGhhdAorICAvLyBpdCBpcyBjbGVhcmVkLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKworICAvLyBVbmxpa2Ugd2l0aCB0aGUgZGVmYXVsdHMgdGVzdCwgd2UgZG8gTk9UIGV4cGVjdCB0aGF0IHJlcXVlc3RpbmcgZW1iZWRkZWQKKyAgLy8gbWVzc2FnZXMgd2lsbCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBkZWZhdWx0IGluc3RhbmNlLiAgSW5zdGVhZCwgdGhleQorICAvLyBzaG91bGQgcmV0dXJuIHRoZSBvYmplY3RzIHRoYXQgd2VyZSBjcmVhdGVkIHdoZW4gbXV0YWJsZV9ibGFoKCkgd2FzCisgIC8vIGNhbGxlZC4KKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6T3B0aW9uYWxHcm91cF9leHRlbnNpb246OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24pKTsKKworICAvLyBNYWtlIHN1cmUgc2V0dGluZyBzdHVmZiBhZ2FpbiBhZnRlciBjbGVhcmluZyB3b3Jrcy4gIChUaGlzIHRha2VzIHNsaWdodGx5CisgIC8vIGRpZmZlcmVudCBjb2RlIHBhdGhzIHNpbmNlIHRoZSBvYmplY3RzIGFyZSByZXVzZWQuKQorICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIENsZWFyT25lRmllbGQpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlLCB0aGVuIGNsZWFyIG9uZSB2YWx1ZSBhbmQgaW5zdXJlIHRoYXQKKyAgLy8gb25seSB0aGF0IG9uZSB2YWx1ZSBpcyBjbGVhcmVkLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIGludDY0IG9yaWdpbmFsX3ZhbHVlID0KKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uKTsKKworICAvLyBDbGVhciB0aGUgZmllbGQgYW5kIG1ha2Ugc3VyZSBpdCBzaG93cyB1cCBhcyBjbGVhcmVkLgorICBtZXNzYWdlLkNsZWFyRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24pOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbikpOworCisgIC8vIE90aGVyIGFkamFjZW50IGZpZWxkcyBzaG91bGQgbm90IGJlIGNsZWFyZWQuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb24pKTsKKworICAvLyBNYWtlIHN1cmUgaWYgd2Ugc2V0IGl0IGFnYWluLCB0aGVuIGFsbCBmaWVsZHMgYXJlIHNldC4KKyAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbiwgb3JpZ2luYWxfdmFsdWUpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTZXRBbGxvY2F0ZWRFeHRlbnNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIC8vIEFkZCBhIGV4dGVuc2lvbiB1c2luZyBTZXRBbGxvY2F0ZWRFeHRlbnNpb24KKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiBmb3JlaWduX21lc3NhZ2UgPSBuZXcgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKCk7CisgIG1lc3NhZ2UuU2V0QWxsb2NhdGVkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlaWduX21lc3NhZ2UpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUShmb3JlaWduX21lc3NhZ2UsCisgICAgICAgICAgICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24oCisgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fbWVzc2FnZSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbigKKyAgICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworCisgIC8vIFNldEFsbG9jYXRlZEV4dGVuc2lvbiBzaG91bGQgZGVsZXRlIHRoZSBwcmV2aW91c2x5IGV4aXN0aW5nIGV4dGVuc2lvbi4KKyAgLy8gKFdlIHJlcGx5IG9uIHVuaXR0ZXN0IHRvIGNoZWNrIG1lbW9yeSBsZWFrcyBmb3IgdGhpcyBjYXNlKQorICBtZXNzYWdlLlNldEFsbG9jYXRlZEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSgpKTsKKworICAvLyBTZXRBbGxvY2F0ZWRFeHRlbnNpb24gd2l0aCBhIE5VTEwgcGFyYW1ldGVyIGlzIGVxdWl2YWxlbnQgdG8gQ2xlYXJFeHRlbmlvbi4KKyAgbWVzc2FnZS5TZXRBbGxvY2F0ZWRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFJlbGVhc2VFeHRlbnNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbikpOworICAvLyBBZGQgYSBleHRlbnNpb24gdXNpbmcgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEqIGV4dGVuc2lvbiA9CisgICAgICBuZXcgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSgpOworICBtZXNzYWdlLlNldEFsbG9jYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiwKKyAgICAgIGV4dGVuc2lvbik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKSk7CisgIC8vIFJlbGVhc2UgdGhlIGV4dGVuc2lvbiB1c2luZyBSZWxlYXNlRXh0ZW5zaW9uCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEqIHJlbGVhc2VkX2V4dGVuc2lvbiA9CisgICAgICBtZXNzYWdlLlJlbGVhc2VFeHRlbnNpb24oCisgICAgICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKTsKKyAgRVhQRUNUX0VRKGV4dGVuc2lvbiwgcmVsZWFzZWRfZXh0ZW5zaW9uKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKSk7CisgIC8vIFJlbGVhc2VFeHRlbnNpb24gd2lsbCByZXR1cm4gdGhlIHVuZGVybHlpbmcgb2JqZWN0IGV2ZW4gYWZ0ZXIKKyAgLy8gQ2xlYXJFeHRlbnNpb24gaXMgY2FsbGVkLgorICBtZXNzYWdlLlNldEFsbG9jYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiwKKyAgICAgIGV4dGVuc2lvbik7CisgIG1lc3NhZ2UuQ2xlYXJFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pOworICByZWxlYXNlZF9leHRlbnNpb24gPSBtZXNzYWdlLlJlbGVhc2VFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pOworICBFWFBFQ1RfVFJVRShyZWxlYXNlZF9leHRlbnNpb24gIT0gTlVMTCk7CisgIGRlbGV0ZSByZWxlYXNlZF9leHRlbnNpb247Cit9CisKKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBDb3B5RnJvbSkgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlMSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMSk7ICAvLyBleGVyY2lzZSBjb3B5IHdoZW4gZmllbGRzIGFscmVhZHkgZXhpc3QKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEV4dGVuc2lvU2V0VGVzdCwgQ29weUZyb21QYWNrZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0UGFja2VkRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTEpOyAgLy8gZXhlcmNpc2UgY29weSB3aGVuIGZpZWxkcyBhbHJlYWR5IGV4aXN0CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBDb3B5RnJvbVVwY2FzdGVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIGNvbnN0IE1lc3NhZ2UmIHVwY2FzdGVkX21lc3NhZ2UgPSBtZXNzYWdlMTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworICBtZXNzYWdlMi5Db3B5RnJvbSh1cGNhc3RlZF9tZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICAvLyBleGVyY2lzZSBjb3B5IHdoZW4gZmllbGRzIGFscmVhZHkgZXhpc3QKKyAgbWVzc2FnZTIuQ29weUZyb20odXBjYXN0ZWRfbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwV2l0aEVtcHR5KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlMSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UyKTsKKyAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZTEpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFN3YXBXaXRoU2VsZikgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworICBtZXNzYWdlLlN3YXAoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRXh0ZW5zaW9uKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlMSk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisKKyAgLy8gU3dhcCBlbXB0eSBmaWVsZHMuCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXBGaWVsZHMoJm1lc3NhZ2UxLCAmbWVzc2FnZTIsIGZpZWxkcyk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlMik7CisKKyAgLy8gU3dhcCB0d28gZXh0ZW5zaW9ucy4KKyAgZmllbGRzLnB1c2hfYmFjaygKKyAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TnVtYmVyKDEyKSk7CisgIGZpZWxkcy5wdXNoX2JhY2soCisgICAgICByZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU51bWJlcigyNSkpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UxLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UxLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfY29yZF9leHRlbnNpb24pKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZTIuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfY29yZF9leHRlbnNpb24pKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRXh0ZW5zaW9uV2l0aEVtcHR5KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTM7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UzKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTMuR2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UzLCAmZmllbGRzKTsKKworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRXh0ZW5zaW9uQm90aEZ1bGwpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UyKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UxLCAmZmllbGRzKTsKKworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIEFyZW5hU2V0QWxsRXh0ZW5zaW9uKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmExOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UxID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmExKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTEpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIEFyZW5hQ29weUNvbnN0cnVjdG9yKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmExOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UxID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmExKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTEpOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTIoKm1lc3NhZ2UxKTsKKyAgYXJlbmExLlJlc2V0KCk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBBcmVuYU1lcmdlRnJvbSkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hIGFyZW5hMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlMSA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKG1lc3NhZ2UxKTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworICBtZXNzYWdlMi5NZXJnZUZyb20oKm1lc3NhZ2UxKTsKKyAgYXJlbmExLlJlc2V0KCk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBBcmVuYVNldEFsbG9jYXRlZE1lc3NhZ2VBbmRSZWxlYXNlKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZSA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIC8vIEFkZCBhIGV4dGVuc2lvbiB1c2luZyBTZXRBbGxvY2F0ZWRFeHRlbnNpb24KKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiBmb3JlaWduX21lc3NhZ2UgPSBuZXcgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKCk7CisgIG1lc3NhZ2UtPlNldEFsbG9jYXRlZEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVpZ25fbWVzc2FnZSk7CisgIC8vIGZvcmVpZ25fbWVzc2FnZSBpcyBjb3BpZWQgdW5kZXJuZWF0aCwgYXMgZm9yZWlnbl9tZXNzYWdlIGlzIG9uIGhlYXAKKyAgLy8gYW5kIGV4dGVuc2lvbl9zZXQgaXMgb24gYW4gYXJlbmEuCisgIEVYUEVDVF9ORShmb3JlaWduX21lc3NhZ2UsCisgICAgICAgICAgICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKAorICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisKKyAgLy8gVW5kZXJseWluZyBtZXNzYWdlIGlzIGNvcGllZCwgYW5kIHJldHVybmVkLgorICB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UqIHJlbGVhc2VkX21lc3NhZ2UgPSBtZXNzYWdlLT5SZWxlYXNlRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pOworICBkZWxldGUgcmVsZWFzZWRfbWVzc2FnZTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgU3dhcEV4dGVuc2lvbkJvdGhGdWxsV2l0aEFyZW5hKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmExOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hPiBhcmVuYTIobmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEoKSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlMSA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM+KCZhcmVuYTEpOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UyID0KKyAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oYXJlbmEyLmdldCgpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKG1lc3NhZ2UyKTsKKyAgbWVzc2FnZTEtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uLCAxKTsKKyAgbWVzc2FnZTItPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uLCAyKTsKKyAgbWVzc2FnZTEtPlN3YXAobWVzc2FnZTIpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZTEtPkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlMi0+R2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pKTsKKyAgLy8gUmUtc2V0IHRoZSBvcmlnaW5hbCB2YWx1ZXMgc28gRXhwZWN0QWxsRXh0ZW5zaW9uc1NldCBpcyBoYXBweS4KKyAgbWVzc2FnZTEtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uLCAxMDEpOworICBtZXNzYWdlMi0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sIDEwMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlMik7CisgIGFyZW5hMi5yZXNldChOVUxMKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQoKm1lc3NhZ2UxKTsKKyAgLy8gVGVzdCBjb3JuZXIgY2FzZXMsIHdoZW4gb25lIGlzIGVtcHR5IGFuZCBvdGhlciBpcyBub3QuCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmEzLCBhcmVuYTQ7CisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlMyA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM+KCZhcmVuYTMpOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2U0ID0KKyAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hNCk7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKG1lc3NhZ2UzKTsKKyAgbWVzc2FnZTMtPlN3YXAobWVzc2FnZTQpOworICBhcmVuYTMuUmVzZXQoKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQoKm1lc3NhZ2U0KTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRmllbGRzT2ZFeHRlbnNpb25Cb3RoRnVsbFdpdGhBcmVuYSkgeworICBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTE7CisgIGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYTIgPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSgpOworCisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZTEgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmExKTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlMiA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM+KGFyZW5hMik7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTEpOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlMik7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLT5HZXRSZWZsZWN0aW9uKCk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMoKm1lc3NhZ2UxLCAmZmllbGRzKTsKKyAgcmVmbGVjdGlvbi0+U3dhcEZpZWxkcyhtZXNzYWdlMSwgbWVzc2FnZTIsIGZpZWxkcyk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlMik7CisgIGRlbGV0ZSBhcmVuYTI7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlMSk7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgU3dhcEV4dGVuc2lvbldpdGhTZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZTEsICZmaWVsZHMpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UxLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UxKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTZXJpYWxpemF0aW9uVG9BcnJheSkgeworICAvLyBTZXJpYWxpemUgYXMgVGVzdEFsbEV4dGVuc2lvbnMgYW5kIHBhcnNlIGFzIFRlc3RBbGxUeXBlcyB0byBpbnN1cmUgd2lyZQorICAvLyBjb21wYXRpYmlsaXR5IG9mIGV4dGVuc2lvbnMuCisgIC8vCisgIC8vIFRoaXMgY2hlY2tzIHNlcmlhbGl6YXRpb24gdG8gYSBmbGF0IGFycmF5IGJ5IGV4cGxpY2l0bHkgcmVzZXJ2aW5nIHNwYWNlIGluCisgIC8vIHRoZSBzdHJpbmcgYW5kIGNhbGxpbmcgdGhlIGdlbmVyYXRlZCBtZXNzYWdlJ3MKKyAgLy8gU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheS4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBkZXN0aW5hdGlvbjsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJnNvdXJjZSk7CisgIGludCBzaXplID0gc291cmNlLkJ5dGVTaXplKCk7CisgIHN0cmluZyBkYXRhOworICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgdWludDgqIHRhcmdldCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgdWludDgqIGVuZCA9IHNvdXJjZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7CisgIEVYUEVDVF9FUShzaXplLCBlbmQgLSB0YXJnZXQpOworICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KGRlc3RpbmF0aW9uKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgLy8gU2VyaWFsaXplIGFzIFRlc3RBbGxFeHRlbnNpb25zIGFuZCBwYXJzZSBhcyBUZXN0QWxsVHlwZXMgdG8gaW5zdXJlIHdpcmUKKyAgLy8gY29tcGF0aWJpbGl0eSBvZiBleHRlbnNpb25zLgorICAvLworICAvLyBUaGlzIGNoZWNrcyBzZXJpYWxpemF0aW9uIHRvIGFuIG91dHB1dCBzdHJlYW0gYnkgY3JlYXRpbmcgYW4gYXJyYXkgb3V0cHV0CisgIC8vIHN0cmVhbSB0aGF0IGNhbiBvbmx5IGJ1ZmZlciAxIGJ5dGUgYXQgYSB0aW1lIC0gdGhpcyBwcmV2ZW50cyB0aGUgbWVzc2FnZQorICAvLyBmcm9tIGV2ZXIganVtcGluZyB0byB0aGUgZmFzdCBwYXRoLCBlbnN1cmluZyB0aGF0IHNlcmlhbGl6YXRpb24gaGFwcGVucyB2aWEKKyAgLy8gdGhlIENvZGVkT3V0cHV0U3RyZWFtLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgc291cmNlOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIGRlc3RpbmF0aW9uOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmc291cmNlKTsKKyAgaW50IHNpemUgPSBzb3VyY2UuQnl0ZVNpemUoKTsKKyAgc3RyaW5nIGRhdGE7CisgIGRhdGEucmVzaXplKHNpemUpOworICB7CisgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICBzb3VyY2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgfQorICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KGRlc3RpbmF0aW9uKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBQYWNrZWRTZXJpYWxpemF0aW9uVG9BcnJheSkgeworICAvLyBTZXJpYWxpemUgYXMgVGVzdFBhY2tlZEV4dGVuc2lvbnMgYW5kIHBhcnNlIGFzIFRlc3RQYWNrZWRUeXBlcyB0byBpbnN1cmUKKyAgLy8gd2lyZSBjb21wYXRpYmlsaXR5IG9mIGV4dGVuc2lvbnMuCisgIC8vCisgIC8vIFRoaXMgY2hlY2tzIHNlcmlhbGl6YXRpb24gdG8gYSBmbGF0IGFycmF5IGJ5IGV4cGxpY2l0bHkgcmVzZXJ2aW5nIHNwYWNlIGluCisgIC8vIHRoZSBzdHJpbmcgYW5kIGNhbGxpbmcgdGhlIGdlbmVyYXRlZCBtZXNzYWdlJ3MKKyAgLy8gU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheS4KKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBkZXN0aW5hdGlvbjsKKyAgVGVzdFV0aWw6OlNldFBhY2tlZEV4dGVuc2lvbnMoJnNvdXJjZSk7CisgIGludCBzaXplID0gc291cmNlLkJ5dGVTaXplKCk7CisgIHN0cmluZyBkYXRhOworICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgdWludDgqIHRhcmdldCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgdWludDgqIGVuZCA9IHNvdXJjZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7CisgIEVYUEVDVF9FUShzaXplLCBlbmQgLSB0YXJnZXQpOworICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRmllbGRzU2V0KGRlc3RpbmF0aW9uKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBQYWNrZWRTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgLy8gU2VyaWFsaXplIGFzIFRlc3RQYWNrZWRFeHRlbnNpb25zIGFuZCBwYXJzZSBhcyBUZXN0UGFja2VkVHlwZXMgdG8gaW5zdXJlCisgIC8vIHdpcmUgY29tcGF0aWJpbGl0eSBvZiBleHRlbnNpb25zLgorICAvLworICAvLyBUaGlzIGNoZWNrcyBzZXJpYWxpemF0aW9uIHRvIGFuIG91dHB1dCBzdHJlYW0gYnkgY3JlYXRpbmcgYW4gYXJyYXkgb3V0cHV0CisgIC8vIHN0cmVhbSB0aGF0IGNhbiBvbmx5IGJ1ZmZlciAxIGJ5dGUgYXQgYSB0aW1lIC0gdGhpcyBwcmV2ZW50cyB0aGUgbWVzc2FnZQorICAvLyBmcm9tIGV2ZXIganVtcGluZyB0byB0aGUgZmFzdCBwYXRoLCBlbnN1cmluZyB0aGF0IHNlcmlhbGl6YXRpb24gaGFwcGVucyB2aWEKKyAgLy8gdGhlIENvZGVkT3V0cHV0U3RyZWFtLgorICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMgc291cmNlOworICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIGRlc3RpbmF0aW9uOworICBUZXN0VXRpbDo6U2V0UGFja2VkRXh0ZW5zaW9ucygmc291cmNlKTsKKyAgaW50IHNpemUgPSBzb3VyY2UuQnl0ZVNpemUoKTsKKyAgc3RyaW5nIGRhdGE7CisgIGRhdGEucmVzaXplKHNpemUpOworICB7CisgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICBzb3VyY2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgfQorICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRmllbGRzU2V0KGRlc3RpbmF0aW9uKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBQYXJzaW5nKSB7CisgIC8vIFNlcmlhbGl6ZSBhcyBUZXN0QWxsVHlwZXMgYW5kIHBhcnNlIGFzIFRlc3RBbGxFeHRlbnNpb25zLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIGRlc3RpbmF0aW9uOworICBzdHJpbmcgZGF0YTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6U2V0T25lb2ZGaWVsZHMoJmRlc3RpbmF0aW9uKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQoZGVzdGluYXRpb24pOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFBhY2tlZFBhcnNpbmcpIHsKKyAgLy8gU2VyaWFsaXplIGFzIFRlc3RQYWNrZWRUeXBlcyBhbmQgcGFyc2UgYXMgVGVzdFBhY2tlZEV4dGVuc2lvbnMuCisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgc291cmNlOworICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMgZGVzdGluYXRpb247CisgIHN0cmluZyBkYXRhOworCisgIFRlc3RVdGlsOjpTZXRQYWNrZWRGaWVsZHMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisgIEVYUEVDVF9UUlVFKGRlc3RpbmF0aW9uLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KGRlc3RpbmF0aW9uKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBQYWNrZWRUb1VucGFja2VkUGFyc2luZykgeworICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgZGVzdGluYXRpb247CisgIHN0cmluZyBkYXRhOworCisgIFRlc3RVdGlsOjpTZXRQYWNrZWRGaWVsZHMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisgIEVYUEVDVF9UUlVFKGRlc3RpbmF0aW9uLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RVbnBhY2tlZEV4dGVuc2lvbnNTZXQoZGVzdGluYXRpb24pOworCisgIC8vIFJlc2VyaWFsaXplCisgIHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRUeXBlcyB1bnBhY2tlZDsKKyAgVGVzdFV0aWw6OlNldFVucGFja2VkRmllbGRzKCZ1bnBhY2tlZCk7CisgIEVYUEVDVF9UUlVFKHVucGFja2VkLlNlcmlhbGl6ZUFzU3RyaW5nKCkgPT0gZGVzdGluYXRpb24uU2VyaWFsaXplQXNTdHJpbmcoKSk7CisKKyAgLy8gTWFrZSBzdXJlIHdlIGNhbiBhZGQgZXh0ZW5zaW9ucy4KKyAgZGVzdGluYXRpb24uQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQzMl9leHRlbnNpb24sIDEpOworICBkZXN0aW5hdGlvbi5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX2VudW1fZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OkZPUkVJR05fQkFSKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBVbnBhY2tlZFRvUGFja2VkUGFyc2luZykgeworICB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMgc291cmNlOworICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMgZGVzdGluYXRpb247CisgIHN0cmluZyBkYXRhOworCisgIFRlc3RVdGlsOjpTZXRVbnBhY2tlZEZpZWxkcygmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgRVhQRUNUX1RSVUUoZGVzdGluYXRpb24uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQoZGVzdGluYXRpb24pOworCisgIC8vIFJlc2VyaWFsaXplCisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgcGFja2VkOworICBUZXN0VXRpbDo6U2V0UGFja2VkRmllbGRzKCZwYWNrZWQpOworICBFWFBFQ1RfVFJVRShwYWNrZWQuU2VyaWFsaXplQXNTdHJpbmcoKSA9PSBkZXN0aW5hdGlvbi5TZXJpYWxpemVBc1N0cmluZygpKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIGFkZCBleHRlbnNpb25zLgorICBkZXN0aW5hdGlvbi5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24sIDEpOworICBkZXN0aW5hdGlvbi5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpGT1JFSUdOX0JBUik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgSXNJbml0aWFsaXplZCkgeworICAvLyBUZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpIHJldHVybnMgZmFsc2UgaWYgcmVxdWlyZWQgZmllbGRzIGluIG5lc3RlZAorICAvLyBleHRlbnNpb25zIGFyZSBtaXNzaW5nLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSktPnNldF9hKDEpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6c2luZ2xlKS0+c2V0X2IoMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjpzaW5nbGUpLT5zZXRfYygzKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6bXVsdGksIDApLT5zZXRfYSgxKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpLCAwKS0+c2V0X2IoMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjptdWx0aSwgMCktPnNldF9jKDMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgTXV0YWJsZVN0cmluZykgeworICAvLyBUZXN0IHRoZSBtdXRhYmxlIHN0cmluZyBhY2Nlc3NvcnMuCisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworCisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiktPmFzc2lnbigiZm9vIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgiZm9vIiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb24pKTsKKworICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbiktPmFzc2lnbigiYmFyIik7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCJiYXIiLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24sIDApKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKSB7CisgIC8vIFNjYWxhciBwcmltaXRpdmUgZXh0ZW5zaW9ucyBzaG91bGQgaW5jcmVhc2UgdGhlIGV4dGVuc2lvbiBzZXQgc2l6ZSBieSBhCisgIC8vIG1pbmltdW0gb2YgdGhlIHNpemUgb2YgdGhlIHByaW1pdGl2ZSB0eXBlLgorI2RlZmluZSBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQodHlwZSwgdmFsdWUpICAgICAgICAgICAgICAgICAgICAgICAgXAorICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNvbnN0IGludCBiYXNlX3NpemUgPSBtZXNzYWdlLlNwYWNlVXNlZCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIG1lc3NhZ2UuU2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF8jI3R5cGUjI19leHRlbnNpb24sIHZhbHVlKTsgICAgICAgXAorICAgIGludCBtaW5fZXhwZWN0ZWRfc2l6ZSA9IGJhc2Vfc2l6ZSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBzaXplb2YobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsXyMjdHlwZSMjX2V4dGVuc2lvbikpOyAgXAorICAgIEVYUEVDVF9MRShtaW5fZXhwZWN0ZWRfc2l6ZSwgbWVzc2FnZS5TcGFjZVVzZWQoKSk7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9IHdoaWxlICgwKQorCisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChpbnQzMiAgICwgMTAxKTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKGludDY0ICAgLCAxMDIpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQodWludDMyICAsIDEwMyk7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRCh1aW50NjQgICwgMTA0KTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNpbnQzMiAgLCAxMDUpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoc2ludDY0ICAsIDEwNik7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChmaXhlZDMyICwgMTA3KTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKGZpeGVkNjQgLCAxMDgpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoc2ZpeGVkMzIsIDEwOSk7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChzZml4ZWQ2NCwgMTEwKTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKGZsb2F0ICAgLCAxMTEpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoZG91YmxlICAsIDExMik7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChib29sICAgICwgdHJ1ZSk7CisjdW5kZWYgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VECisgIHsKKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgICBjb25zdCBpbnQgYmFzZV9zaXplID0gbWVzc2FnZS5TcGFjZVVzZWQoKTsKKyAgICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgICAgaW50IG1pbl9leHBlY3RlZF9zaXplID0gYmFzZV9zaXplICsKKyAgICAgICAgc2l6ZW9mKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24pKTsKKyAgICBFWFBFQ1RfTEUobWluX2V4cGVjdGVkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpOworICB9CisgIHsKKyAgICAvLyBTdHJpbmdzIG1heSBjYXVzZSBleHRyYSBhbGxvY2F0aW9ucyBkZXBlbmRpbmcgb24gdGhlaXIgbGVuZ3RoOyBlbnN1cmUKKyAgICAvLyB0aGF0IGdldHMgaW5jbHVkZWQgYXMgd2VsbC4KKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgICBjb25zdCBpbnQgYmFzZV9zaXplID0gbWVzc2FnZS5TcGFjZVVzZWQoKTsKKyAgICBjb25zdCBzdHJpbmcgcygidGhpcyBpcyBhIGZhaXJseSBsYXJnZSBzdHJpbmcgdGhhdCB3aWxsIGNhdXNlIHNvbWUgIgorICAgICAgICAgICAgICAgICAgICJhbGxvY2F0aW9uIGluIG9yZGVyIHRvIHN0b3JlIGl0IGluIHRoZSBleHRlbnNpb24iKTsKKyAgICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiwgcyk7CisgICAgaW50IG1pbl9leHBlY3RlZF9zaXplID0gYmFzZV9zaXplICsgcy5sZW5ndGgoKTsKKyAgICBFWFBFQ1RfTEUobWluX2V4cGVjdGVkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpOworICB9CisgIHsKKyAgICAvLyBNZXNzYWdlcyBhbHNvIGhhdmUgYWRkaXRpb25hbCBhbGxvY2F0aW9uIHRoYXQgbmVlZCB0byBiZSBjb3VudGVkLgorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICAgIGNvbnN0IGludCBiYXNlX3NpemUgPSBtZXNzYWdlLlNwYWNlVXNlZCgpOworICAgIHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSBmb3JlaWduOworICAgIGZvcmVpZ24uc2V0X2MoNDIpOworICAgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiktPgorICAgICAgICBDb3B5RnJvbShmb3JlaWduKTsKKyAgICBpbnQgbWluX2V4cGVjdGVkX3NpemUgPSBiYXNlX3NpemUgKyBmb3JlaWduLlNwYWNlVXNlZCgpOworICAgIEVYUEVDVF9MRShtaW5fZXhwZWN0ZWRfc2l6ZSwgbWVzc2FnZS5TcGFjZVVzZWQoKSk7CisgIH0KKworICAvLyBSZXBlYXRlZCBwcmltaXRpdmUgZXh0ZW5zaW9ucyB3aWxsIGluY3JlYXNlIHNwYWNlIHVzZWQgYnkgYXQgbGVhc3QgYQorICAvLyBSZXBlYXRlZEZpZWxkPFQ+LCBhbmQgd2lsbCBjYXVzZSBhZGRpdGlvbmFsIGFsbG9jYXRpb25zIHdoZW4gdGhlIGFycmF5CisgIC8vIGdldHMgdG9vIGJpZyBmb3IgdGhlIGluaXRpYWwgc3BhY2UuCisgIC8vIFRoaXMgbWFjcm86CisgIC8vICAgLSBBZGRzIGEgdmFsdWUgdG8gdGhlIHJlcGVhdGVkIGV4dGVuc2lvbiwgdGhlbiBjbGVhcnMgaXQsIGVzdGFibGlzaGluZworICAvLyAgICAgdGhlIGJhc2Ugc2l6ZS4KKyAgLy8gICAtIEFkZHMgYSBzbWFsbCBudW1iZXIgb2YgdmFsdWVzLCB0ZXN0aW5nIHRoYXQgaXQgZG9lc24ndCBpbmNyZWFzZSB0aGUKKyAgLy8gICAgIFNwYWNlVXNlZCgpCisgIC8vICAgLSBBZGRzIGEgbGFyZ2UgbnVtYmVyIG9mIHZhbHVlcyAocmVxdWlyaW5nIGFsbG9jYXRpb24gaW4gdGhlIHJlcGVhdGVkCisgIC8vICAgICBmaWVsZCksIGFuZCBlbnN1cmVzIHRoYXQgdGhhdCBhbGxvY2F0aW9uIGlzIGluY2x1ZGVkIGluIFNwYWNlVXNlZCgpCisjZGVmaW5lIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHR5cGUsIGNwcHR5cGUsIHZhbHVlKSAgICAgICAgICAgICAgXAorICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY29uc3QgaW50IGJhc2Vfc2l6ZSA9IG1lc3NhZ2UuU3BhY2VVc2VkKCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGludCBtaW5fZXhwZWN0ZWRfc2l6ZSA9IHNpemVvZihSZXBlYXRlZEZpZWxkPGNwcHR5cGU+KSArIGJhc2Vfc2l6ZTsgICAgICAgIFwKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfIyN0eXBlIyNfZXh0ZW5zaW9uLCB2YWx1ZSk7ICAgICAgICBcCisgICAgbWVzc2FnZS5DbGVhckV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfIyN0eXBlIyNfZXh0ZW5zaW9uKTsgICAgICAgICAgICAgXAorICAgIGNvbnN0IGludCBlbXB0eV9yZXBlYXRlZF9maWVsZF9zaXplID0gbWVzc2FnZS5TcGFjZVVzZWQoKTsgICAgICAgICAgICAgICAgIFwKKyAgICBFWFBFQ1RfTEUobWluX2V4cGVjdGVkX3NpemUsIGVtcHR5X3JlcGVhdGVkX2ZpZWxkX3NpemUpIDw8ICN0eXBlOyAgICAgICAgICBcCisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkXyMjdHlwZSMjX2V4dGVuc2lvbiwgdmFsdWUpOyAgICAgICAgXAorICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF8jI3R5cGUjI19leHRlbnNpb24sIHZhbHVlKTsgICAgICAgIFwKKyAgICBFWFBFQ1RfRVEoZW1wdHlfcmVwZWF0ZWRfZmllbGRfc2l6ZSwgbWVzc2FnZS5TcGFjZVVzZWQoKSkgPDwgI3R5cGU7ICAgICAgICBcCisgICAgbWVzc2FnZS5DbGVhckV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfIyN0eXBlIyNfZXh0ZW5zaW9uKTsgICAgICAgICAgICAgXAorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7ICsraSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF8jI3R5cGUjI19leHRlbnNpb24sIHZhbHVlKTsgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGludCBleHBlY3RlZF9zaXplID0gc2l6ZW9mKGNwcHR5cGUpICogKDE2IC0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAga01pblJlcGVhdGVkRmllbGRBbGxvY2F0aW9uU2l6ZSkgKyBlbXB0eV9yZXBlYXRlZF9maWVsZF9zaXplOyAgICAgICAgICBcCisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpIDw8ICN0eXBlOyAgICAgICAgICAgICAgICAgICAgXAorICB9IHdoaWxlICgwKQorCisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGludDMyICAgLCBpbnQzMiAsIDEwMSk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGludDY0ICAgLCBpbnQ2NCAsIDEwMik7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHVpbnQzMiAgLCB1aW50MzIsIDEwMyk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHVpbnQ2NCAgLCB1aW50NjQsIDEwNCk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNpbnQzMiAgLCBpbnQzMiAsIDEwNSk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNpbnQ2NCAgLCBpbnQ2NCAsIDEwNik7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGZpeGVkMzIgLCB1aW50MzIsIDEwNyk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGZpeGVkNjQgLCB1aW50NjQsIDEwOCk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNmaXhlZDMyLCBpbnQzMiAsIDEwOSk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNmaXhlZDY0LCBpbnQ2NCAsIDExMCk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGZsb2F0ICAgLCBmbG9hdCAsIDExMSk7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGRvdWJsZSAgLCBkb3VibGUsIDExMik7CisgIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VEKGJvb2wgICAgLCBib29sICAsIHRydWUpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChuZXN0ZWRfZW51bSwgaW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08pOworI3VuZGVmIFRFU1RfUkVQRUFURURfRVhURU5TSU9OU19TUEFDRV9VU0VECisgIC8vIFJlcGVhdGVkIHN0cmluZ3MKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICAgIGNvbnN0IGludCBiYXNlX3NpemUgPSBtZXNzYWdlLlNwYWNlVXNlZCgpOworICAgIGludCBtaW5fZXhwZWN0ZWRfc2l6ZSA9IHNpemVvZihSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4pICsgYmFzZV9zaXplOworICAgIGNvbnN0IHN0cmluZyB2YWx1ZSgyNTYsICd4Jyk7CisgICAgLy8gT25jZSBpdGVtcyBhcmUgYWxsb2NhdGVkLCB0aGV5IG1heSBzdGljayBhcm91bmQgZXZlbiB3aGVuIGNsZWFyZWQgc28KKyAgICAvLyB3aXRob3V0IHRoZSBoYXJkY29yZSBtZW1vcnkgbWFuYWdlbWVudCBhY2Nlc3NvcnMgdGhlcmUgaXNuJ3QgYSBub3Rpb24gb2YKKyAgICAvLyB0aGUgZW1wdHkgcmVwZWF0ZWQgZmllbGQgbWVtb3J5IHVzYWdlIGFzIHRoZXJlIGlzIHdpdGggcHJpbWl0aXZlIHR5cGVzLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7ICsraSkgeworICAgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24sIHZhbHVlKTsKKyAgICB9CisgICAgbWluX2V4cGVjdGVkX3NpemUgKz0gKHNpemVvZih2YWx1ZSkgKyB2YWx1ZS5zaXplKCkpICoKKyAgICAgICAgKDE2IC0ga01pblJlcGVhdGVkRmllbGRBbGxvY2F0aW9uU2l6ZSk7CisgICAgRVhQRUNUX0xFKG1pbl9leHBlY3RlZF9zaXplLCBtZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgfQorICAvLyBSZXBlYXRlZCBtZXNzYWdlcworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgICAgY29uc3QgaW50IGJhc2Vfc2l6ZSA9IG1lc3NhZ2UuU3BhY2VVc2VkKCk7CisgICAgaW50IG1pbl9leHBlY3RlZF9zaXplID0gc2l6ZW9mKFJlcGVhdGVkUHRyRmllbGQ8dW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlPikgKworICAgICAgICBiYXNlX3NpemU7CisgICAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlIHByb3RvdHlwZTsKKyAgICBwcm90b3R5cGUuc2V0X2MoMik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgKytpKSB7CisgICAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiktPgorICAgICAgICAgIENvcHlGcm9tKHByb3RvdHlwZSk7CisgICAgfQorICAgIG1pbl9leHBlY3RlZF9zaXplICs9CisgICAgICAgICgxNiAtIGtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUpICogcHJvdG90eXBlLlNwYWNlVXNlZCgpOworICAgIEVYUEVDVF9MRShtaW5fZXhwZWN0ZWRfc2l6ZSwgbWVzc2FnZS5TcGFjZVVzZWQoKSk7CisgIH0KK30KKworLy8gTi5CLjogV2UgZG8gbm90IHRlc3QgcmFuZ2UtYmFzZWQgZm9yIGhlcmUgYmVjYXVzZSB3ZSByZW1haW4gQysrMDMgY29tcGF0aWJsZS4KK3RlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIE0sIHR5cGVuYW1lIElEPgoraW5saW5lIFQgU3VtQWxsRXh0ZW5zaW9ucyhjb25zdCBNJiBtZXNzYWdlLCBJRCBleHRlbnNpb24sIFQgemVybykgeworICBUIHN1bSA9IHplcm87CisgIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8VD46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbihleHRlbnNpb24pLmJlZ2luKCk7CisgIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8VD46OmNvbnN0X2l0ZXJhdG9yIGVuZCA9CisgICAgICBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKGV4dGVuc2lvbikuZW5kKCk7CisgIGZvciAoOyBpdGVyICE9IGVuZDsgKytpdGVyKSB7CisgICAgc3VtICs9ICppdGVyOworICB9CisgIHJldHVybiBzdW07Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIE0sIHR5cGVuYW1lIElEPgoraW5saW5lIHZvaWQgSW5jQWxsRXh0ZW5zaW9ucyhNKiBtZXNzYWdlLCBJRCBleHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgIFQgdmFsKSB7CisgIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8VD46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgbWVzc2FnZS0+TXV0YWJsZVJlcGVhdGVkRXh0ZW5zaW9uKGV4dGVuc2lvbiktPmJlZ2luKCk7CisgIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8VD46Oml0ZXJhdG9yIGVuZCAgPQorICAgICAgbWVzc2FnZS0+TXV0YWJsZVJlcGVhdGVkRXh0ZW5zaW9uKGV4dGVuc2lvbiktPmVuZCgpOworICBmb3IgKDsgaXRlciAhPSBlbmQ7ICsraXRlcikgeworICAgICppdGVyICs9IHZhbDsKKyAgfQorfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFJlcGVhdGVkRmllbGRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworCisgIC8vIFRlc3QgZW1wdHkgcmVwZWF0ZWQtZmllbGQgY2FzZSAoYi8xMjkyNjE2MykKKyAgQVNTRVJUX0VRKDAsIG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uKS5zaXplKCkpOworICBBU1NFUlRfRVEoMCwgbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24pLnNpemUoKSk7CisgIEFTU0VSVF9FUSgwLCBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pLnNpemUoKSk7CisgIEFTU0VSVF9FUSgwLCBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuc2l6ZSgpKTsKKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlOworICBuZXN0ZWRfbWVzc2FnZS5zZXRfYmIoNDIpOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUlOOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24sIDEpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24sIDIpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uLCAzKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiwgNCk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24sIDUpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uLCA2KTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24sIDcpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiwgOCk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbiwgNyk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgOCk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiwgOS4wKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiwgMTAuMCk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uLCB0cnVlKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uLCBuZXN0ZWRfZW51bSk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgOjpzdGQ6OnN0cmluZygidGVzdCIpKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIDo6c3RkOjpzdHJpbmcoInRlc3RceEZGIikpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKAorICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKS0+Q29weUZyb20obmVzdGVkX21lc3NhZ2UpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgbmVzdGVkX2VudW0pOworICB9CisKKyAgQVNTRVJUX0VRKDEwLCBTdW1BbGxFeHRlbnNpb25zPGludDMyPigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczxpbnQzMj4oCisgICAgICAmbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiwgMSk7CisgIEFTU0VSVF9FUSgyMCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDIwLCBTdW1BbGxFeHRlbnNpb25zPGludDY0PigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczxpbnQ2ND4oCisgICAgICAmbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiwgMSk7CisgIEFTU0VSVF9FUSgzMCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDMwLCBTdW1BbGxFeHRlbnNpb25zPHVpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiwgMCkpOworICBJbmNBbGxFeHRlbnNpb25zPHVpbnQzMj4oCisgICAgICAmbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoNDAsIFN1bUFsbEV4dGVuc2lvbnM8dWludDMyPigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDQwLCBTdW1BbGxFeHRlbnNpb25zPHVpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiwgMCkpOworICBJbmNBbGxFeHRlbnNpb25zPHVpbnQ2ND4oCisgICAgICAmbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoNTAsIFN1bUFsbEV4dGVuc2lvbnM8dWludDY0PigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDUwLCBTdW1BbGxFeHRlbnNpb25zPGludDMyPigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8aW50MzI+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uLCAxKTsKKyAgQVNTRVJUX0VRKDYwLCBTdW1BbGxFeHRlbnNpb25zPGludDMyPigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDYwLCBTdW1BbGxFeHRlbnNpb25zPGludDY0PigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8aW50NjQ+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uLCAxKTsKKyAgQVNTRVJUX0VRKDcwLCBTdW1BbGxFeHRlbnNpb25zPGludDY0PigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDcwLCBTdW1BbGxFeHRlbnNpb25zPHVpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczx1aW50MzI+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbiwgMSk7CisgIEFTU0VSVF9FUSg4MCwgU3VtQWxsRXh0ZW5zaW9uczx1aW50MzI+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDgwLCBTdW1BbGxFeHRlbnNpb25zPHVpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczx1aW50NjQ+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiwgMSk7CisgIEFTU0VSVF9FUSg5MCwgU3VtQWxsRXh0ZW5zaW9uczx1aW50NjQ+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgLy8gVXN1YWxseSwgZmxvYXRpbmctcG9pbnQgYXJpdGhtZXRpYyBjYW5ub3QgYmUgdHJ1c3RlZCB0byBiZSBleGFjdCwgc28gaXQgaXMKKyAgLy8gYSBCYWQgSWRlYSB0byBhc3NlcnQgZXF1YWxpdHkgaW4gYSB0ZXN0IGxpa2UgdGhpcy4gSG93ZXZlciwgd2UncmUgZGVhbGluZworICAvLyB3aXRoIGludGVnZXJzIHdpdGggYSBzbWFsbCBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgbWFudGlzc2EgYml0cywgc28gd2UKKyAgLy8gc2hvdWxkIGFjdHVhbGx5IGhhdmUgZXhhY3QgcHJlY2lzaW9uIGhlcmUuCisgIEFTU0VSVF9FUSg5MCwgU3VtQWxsRXh0ZW5zaW9uczxmbG9hdD4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8ZmxvYXQ+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoMTAwLCBTdW1BbGxFeHRlbnNpb25zPGZsb2F0PigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24sIDApKTsKKworICBBU1NFUlRfRVEoMTAwLCBTdW1BbGxFeHRlbnNpb25zPGRvdWJsZT4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiwgMCkpOworICBJbmNBbGxFeHRlbnNpb25zPGRvdWJsZT4oCisgICAgICAmbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoMTEwLCBTdW1BbGxFeHRlbnNpb25zPGRvdWJsZT4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiwgMCkpOworCisgIFJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+OjppdGVyYXRvciBzdHJpbmdfaXRlcjsKKyAgUmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz46Oml0ZXJhdG9yIHN0cmluZ19lbmQ7CisgIGZvciAoc3RyaW5nX2l0ZXIgPSBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbiktPmJlZ2luKCksCisgICAgICAgc3RyaW5nX2VuZCAgPSBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pLT5lbmQoKTsKKyAgICAgICBzdHJpbmdfaXRlciAhPSBzdHJpbmdfZW5kOyArK3N0cmluZ19pdGVyKSB7CisgICAgKnN0cmluZ19pdGVyICs9ICJ0ZXN0IjsKKyAgfQorICBSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3Igc3RyaW5nX2NvbnN0X2l0ZXI7CisgIFJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBzdHJpbmdfY29uc3RfZW5kOworICBmb3IgKHN0cmluZ19jb25zdF9pdGVyID0gbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pLmJlZ2luKCksCisgICAgICAgc3RyaW5nX2NvbnN0X2VuZCAgPSBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbikuZW5kKCk7CisgICAgICAgc3RyaW5nX2l0ZXIgIT0gc3RyaW5nX2VuZDsgKytzdHJpbmdfaXRlcikgeworICAgIEFTU0VSVF9UUlVFKCpzdHJpbmdfaXRlciA9PSAidGVzdHRlc3QiKTsKKyAgfQorCisgIFJlcGVhdGVkRmllbGQ8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtPjo6aXRlcmF0b3IgZW51bV9pdGVyOworICBSZXBlYXRlZEZpZWxkPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bT46Oml0ZXJhdG9yIGVudW1fZW5kOworICBmb3IgKGVudW1faXRlciA9IG1lc3NhZ2UuTXV0YWJsZVJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uKS0+YmVnaW4oKSwKKyAgICAgICBlbnVtX2VuZCAgPSBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiktPmVuZCgpOworICAgICAgIGVudW1faXRlciAhPSBlbnVtX2VuZDsgKytlbnVtX2l0ZXIpIHsKKyAgICAqZW51bV9pdGVyID0gdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9NQVg7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZDx1bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW0+Ojpjb25zdF9pdGVyYXRvcgorICAgICAgZW51bV9jb25zdF9pdGVyOworICBSZXBlYXRlZEZpZWxkPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bT46OmNvbnN0X2l0ZXJhdG9yCisgICAgICBlbnVtX2NvbnN0X2VuZDsKKyAgZm9yIChlbnVtX2NvbnN0X2l0ZXIgPSBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uKS5iZWdpbigpLAorICAgICAgIGVudW1fY29uc3RfZW5kICA9IG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24pLmVuZCgpOworICAgICAgIGVudW1faXRlciAhPSBlbnVtX2VuZDsgKytlbnVtX2l0ZXIpIHsKKyAgICBBU1NFUlRfRVEoKmVudW1fY29uc3RfaXRlciwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9NQVgpOworICB9CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDx1bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2U+OjppdGVyYXRvcgorICAgICAgbXNnX2l0ZXI7CisgIFJlcGVhdGVkUHRyRmllbGQ8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlPjo6aXRlcmF0b3IKKyAgICAgIG1zZ19lbmQ7CisgIGZvciAobXNnX2l0ZXIgPSBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPmJlZ2luKCksCisgICAgICAgbXNnX2VuZCAgPSBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPmVuZCgpOworICAgICAgIG1zZ19pdGVyICE9IG1zZ19lbmQ7ICsrbXNnX2l0ZXIpIHsKKyAgICBtc2dfaXRlci0+c2V0X2JiKDEyMzQpOworICB9CisgIFJlcGVhdGVkUHRyRmllbGQ8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlPjo6CisgICAgICBjb25zdF9pdGVyYXRvciBtc2dfY29uc3RfaXRlcjsKKyAgUmVwZWF0ZWRQdHJGaWVsZDx1bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2U+OjoKKyAgICAgIGNvbnN0X2l0ZXJhdG9yIG1zZ19jb25zdF9lbmQ7CisgIGZvciAobXNnX2NvbnN0X2l0ZXIgPSBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKS5iZWdpbigpLAorICAgICAgIG1zZ19jb25zdF9lbmQgID0gbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuZW5kKCk7CisgICAgICAgbXNnX2NvbnN0X2l0ZXIgIT0gbXNnX2NvbnN0X2VuZDsgKyttc2dfY29uc3RfaXRlcikgeworICAgIEFTU0VSVF9FUShtc2dfY29uc3RfaXRlci0+YmIoKSwgMTIzNCk7CisgIH0KKworICAvLyBUZXN0IHJhbmdlLWJhc2VkIGZvciBhcyB3ZWxsLCBidXQgb25seSBpZiBjb21waWxlZCBhcyBDKysxMS4KKyNpZiBfX2NwbHVzcGx1cyA+PSAyMDExMDNMCisgIC8vIFRlc3Qgb25lIHByaW1pdGl2ZSBmaWVsZC4KKyAgZm9yIChhdXRvJiB4IDogKm1lc3NhZ2UuTXV0YWJsZVJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24pKSB7CisgICAgeCA9IDQzMjE7CisgIH0KKyAgZm9yIChjb25zdCBhdXRvJiB4IDogbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uKSkgeworICAgIEFTU0VSVF9FUSh4LCA0MzIxKTsKKyAgfQorICAvLyBUZXN0IG9uZSBzdHJpbmcgZmllbGQuCisgIGZvciAoYXV0byYgeCA6ICptZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbikpIHsKKyAgICB4ID0gInRlc3RfcmFuZ2VfYmFzZWRfZm9yIjsKKyAgfQorICBmb3IgKGNvbnN0IGF1dG8mIHggOiBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uKSkgeworICAgIEFTU0VSVF9UUlVFKHggPT0gInRlc3RfcmFuZ2VfYmFzZWRfZm9yIik7CisgIH0KKyAgLy8gVGVzdCBvbmUgbWVzc2FnZSBmaWVsZC4KKyAgZm9yIChhdXRvJiB4IDogKm1lc3NhZ2UuTXV0YWJsZVJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pKSB7CisgICAgeC5zZXRfYmIoNDMyMSk7CisgIH0KKyAgZm9yIChjb25zdCBhdXRvJiB4IDogKm1lc3NhZ2UuTXV0YWJsZVJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pKSB7CisgICAgQVNTRVJUX0VRKHguYmIoKSwgNDMyMSk7CisgIH0KKyNlbmRpZgorfQorCisvLyBGcm9tIGIvMTI5MjYxNjMKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgQWJzZW50RXh0ZW5zaW9uKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKQorICAgICAgLT5BZGQoKS0+c2V0X2JiKDEyMyk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUoCisgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgKKyAgICAgIDEyMywgbWVzc2FnZS5HZXRFeHRlbnNpb24oCisgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiwgMCkuYmIoKSk7Cit9CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIEludmFsaWRFbnVtRGVhdGgpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIEVYUEVDVF9ERUJVR19ERUFUSCgKKyAgICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDx1bml0dGVzdDo6Rm9yZWlnbkVudW0+KDUzKSksCisgICAgIklzVmFsaWQiKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIER5bmFtaWNFeHRlbnNpb25zKSB7CisgIC8vIFRlc3QgYWRkaW5nIGEgZHluYW1pYyBleHRlbnNpb24gdG8gYSBjb21waWxlZC1pbiBtZXNzYWdlIG9iamVjdC4KKworICBGaWxlRGVzY3JpcHRvclByb3RvIGR5bmFtaWNfcHJvdG87CisgIGR5bmFtaWNfcHJvdG8uc2V0X25hbWUoImR5bmFtaWNfZXh0ZW5zaW9uc190ZXN0LnByb3RvIik7CisgIGR5bmFtaWNfcHJvdG8uYWRkX2RlcGVuZGVuY3koCisgICAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5uYW1lKCkpOworICBkeW5hbWljX3Byb3RvLnNldF9wYWNrYWdlKCJkeW5hbWljX2V4dGVuc2lvbnMiKTsKKworICAvLyBDb3B5IHRoZSBmaWVsZHMgYW5kIG5lc3RlZCB0eXBlcyBmcm9tIFRlc3REeW5hbWljRXh0ZW5zaW9ucyBpbnRvIG91ciBuZXcKKyAgLy8gcHJvdG8sIGNvbnZlcnRpbmcgdGhlIGZpZWxkcyBpbnRvIGV4dGVuc2lvbnMuCisgIGNvbnN0IERlc2NyaXB0b3IqIHRlbXBsYXRlX2Rlc2NyaXB0b3IgPQorICAgICAgdW5pdHRlc3Q6OlRlc3REeW5hbWljRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpOworICBEZXNjcmlwdG9yUHJvdG8gdGVtcGxhdGVfZGVzY3JpcHRvcl9wcm90bzsKKyAgdGVtcGxhdGVfZGVzY3JpcHRvci0+Q29weVRvKCZ0ZW1wbGF0ZV9kZXNjcmlwdG9yX3Byb3RvKTsKKyAgZHluYW1pY19wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgpLT5NZXJnZUZyb20oCisgICAgICB0ZW1wbGF0ZV9kZXNjcmlwdG9yX3Byb3RvLm5lc3RlZF90eXBlKCkpOworICBkeW5hbWljX3Byb3RvLm11dGFibGVfZW51bV90eXBlKCktPk1lcmdlRnJvbSgKKyAgICAgIHRlbXBsYXRlX2Rlc2NyaXB0b3JfcHJvdG8uZW51bV90eXBlKCkpOworICBkeW5hbWljX3Byb3RvLm11dGFibGVfZXh0ZW5zaW9uKCktPk1lcmdlRnJvbSgKKyAgICAgIHRlbXBsYXRlX2Rlc2NyaXB0b3JfcHJvdG8uZmllbGQoKSk7CisKKyAgLy8gRm9yIGVhY2ggZXh0ZW5zaW9uIHRoYXQgd2UgYWRkZWQuLi4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkeW5hbWljX3Byb3RvLmV4dGVuc2lvbl9zaXplKCk7IGkrKykgeworICAgIC8vIFNldCBpdHMgZXh0ZW5kZWUgdG8gVGVzdEFsbEV4dGVuc2lvbnMuCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGV4dGVuc2lvbiA9IGR5bmFtaWNfcHJvdG8ubXV0YWJsZV9leHRlbnNpb24oaSk7CisgICAgZXh0ZW5zaW9uLT5zZXRfZXh0ZW5kZWUoCisgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKSk7CisKKyAgICAvLyBJZiB0aGUgZmllbGQgcmVmZXJzIHRvIG9uZSBvZiB0aGUgdHlwZXMgbmVzdGVkIGluIFRlc3REeW5hbWljRXh0ZW5zaW9ucywKKyAgICAvLyBtYWtlIGl0IHJlZmVyIHRvIHRoZSB0eXBlIGluIG91ciBkeW5hbWljIHByb3RvIGluc3RlYWQuCisgICAgc3RyaW5nIHByZWZpeCA9ICIuIiArIHRlbXBsYXRlX2Rlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpICsgIi4iOworICAgIGlmIChleHRlbnNpb24tPmhhc190eXBlX25hbWUoKSkgeworICAgICAgc3RyaW5nKiB0eXBlX25hbWUgPSBleHRlbnNpb24tPm11dGFibGVfdHlwZV9uYW1lKCk7CisgICAgICBpZiAoSGFzUHJlZml4U3RyaW5nKCp0eXBlX25hbWUsIHByZWZpeCkpIHsKKyAgICAgICAgdHlwZV9uYW1lLT5yZXBsYWNlKDAsIHByZWZpeC5zaXplKCksICIuZHluYW1pY19leHRlbnNpb25zLiIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIE5vdyBidWlsZCB0aGUgZmlsZSwgdXNpbmcgdGhlIGdlbmVyYXRlZCBwb29sIGFzIGFuIHVuZGVybGF5LgorICBEZXNjcmlwdG9yUG9vbCBkeW5hbWljX3Bvb2woRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkpOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IGR5bmFtaWNfcG9vbC5CdWlsZEZpbGUoZHluYW1pY19wcm90byk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBkeW5hbWljX2ZhY3RvcnkoJmR5bmFtaWNfcG9vbCk7CisgIGR5bmFtaWNfZmFjdG9yeS5TZXREZWxlZ2F0ZVRvR2VuZXJhdGVkRmFjdG9yeSh0cnVlKTsKKworICAvLyBDb25zdHJ1Y3QgYSBtZXNzYWdlIHRoYXQgd2UgY2FuIHBhcnNlIHdpdGggdGhlIGV4dGVuc2lvbnMgd2UgZGVmaW5lZC4KKyAgLy8gU2luY2UgdGhlIGV4dGVuc2lvbnMgd2VyZSBiYXNlZCBvZmYgb2YgdGhlIGZpZWxkcyBvZiBUZXN0RHluYW1pY0V4dGVuc2lvbnMsCisgIC8vIHdlIGNhbiB1c2UgdGhhdCBtZXNzYWdlIHRvIGNyZWF0ZSB0aGlzIHRlc3QgbWVzc2FnZS4KKyAgc3RyaW5nIGRhdGE7CisgIHsKKyAgICB1bml0dGVzdDo6VGVzdER5bmFtaWNFeHRlbnNpb25zIG1lc3NhZ2U7CisgICAgbWVzc2FnZS5zZXRfc2NhbGFyX2V4dGVuc2lvbigxMjMpOworICAgIG1lc3NhZ2Uuc2V0X2VudW1fZXh0ZW5zaW9uKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUik7CisgICAgbWVzc2FnZS5zZXRfZHluYW1pY19lbnVtX2V4dGVuc2lvbigKKyAgICAgICAgdW5pdHRlc3Q6OlRlc3REeW5hbWljRXh0ZW5zaW9uczo6RFlOQU1JQ19CQVopOworICAgIG1lc3NhZ2UubXV0YWJsZV9tZXNzYWdlX2V4dGVuc2lvbigpLT5zZXRfYyg0NTYpOworICAgIG1lc3NhZ2UubXV0YWJsZV9keW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uKCktPnNldF9keW5hbWljX2ZpZWxkKDc4OSk7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZXh0ZW5zaW9uKCJmb28iKTsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9leHRlbnNpb24oImJhciIpOworICAgIG1lc3NhZ2UuYWRkX3BhY2tlZF9leHRlbnNpb24oMTIpOworICAgIG1lc3NhZ2UuYWRkX3BhY2tlZF9leHRlbnNpb24oLTM0KTsKKyAgICBtZXNzYWdlLmFkZF9wYWNrZWRfZXh0ZW5zaW9uKDU2KTsKKyAgICBtZXNzYWdlLmFkZF9wYWNrZWRfZXh0ZW5zaW9uKC03OCk7CisKKyAgICAvLyBBbHNvIGFkZCBzb21lIHVua25vd24gZmllbGRzLgorCisgICAgLy8gQW4gdW5rbm93biBlbnVtIHZhbHVlIChmb3IgYSBrbm93biBmaWVsZCkuCisgICAgbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgKKyAgICAgIHVuaXR0ZXN0OjpUZXN0RHluYW1pY0V4dGVuc2lvbnM6OmtEeW5hbWljRW51bUV4dGVuc2lvbkZpZWxkTnVtYmVyLAorICAgICAgMTIzNDUpOworICAgIC8vIEEgcmVndWxhciB1bmtub3duIGZpZWxkLgorICAgIG1lc3NhZ2UubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRMZW5ndGhEZWxpbWl0ZWQoNTQzMjEsICJ1bmtub3duIik7CisKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgfQorCisgIC8vIE5vdyB3ZSBjYW4gcGFyc2UgdGhpcyB1c2luZyBvdXIgZHluYW1pYyBleHRlbnNpb24gZGVmaW5pdGlvbnMuLi4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIHsKKyAgICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgICBpbnB1dC5TZXRFeHRlbnNpb25SZWdpc3RyeSgmZHluYW1pY19wb29sLCAmZHluYW1pY19mYWN0b3J5KTsKKyAgICBBU1NFUlRfVFJVRShtZXNzYWdlLlBhcnNlRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCkpOworICAgIEFTU0VSVF9UUlVFKGlucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKKyAgfQorCisgIC8vIENhbiB3ZSBwcmludCBpdD8KKyAgRVhQRUNUX0VRKAorICAgICJbZHluYW1pY19leHRlbnNpb25zLnNjYWxhcl9leHRlbnNpb25dOiAxMjNcbiIKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5lbnVtX2V4dGVuc2lvbl06IEZPUkVJR05fQkFSXG4iCisgICAgIltkeW5hbWljX2V4dGVuc2lvbnMuZHluYW1pY19lbnVtX2V4dGVuc2lvbl06IERZTkFNSUNfQkFaXG4iCisgICAgIltkeW5hbWljX2V4dGVuc2lvbnMubWVzc2FnZV9leHRlbnNpb25dIHtcbiIKKyAgICAiICBjOiA0NTZcbiIKKyAgICAifVxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLmR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb25dIHtcbiIKKyAgICAiICBkeW5hbWljX2ZpZWxkOiA3ODlcbiIKKyAgICAifVxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLnJlcGVhdGVkX2V4dGVuc2lvbl06IFwiZm9vXCJcbiIKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5yZXBlYXRlZF9leHRlbnNpb25dOiBcImJhclwiXG4iCisgICAgIltkeW5hbWljX2V4dGVuc2lvbnMucGFja2VkX2V4dGVuc2lvbl06IDEyXG4iCisgICAgIltkeW5hbWljX2V4dGVuc2lvbnMucGFja2VkX2V4dGVuc2lvbl06IC0zNFxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLnBhY2tlZF9leHRlbnNpb25dOiA1NlxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLnBhY2tlZF9leHRlbnNpb25dOiAtNzhcbiIKKyAgICAiMjAwMjogMTIzNDVcbiIKKyAgICAiNTQzMjE6IFwidW5rbm93blwiXG4iLAorICAgIG1lc3NhZ2UuRGVidWdTdHJpbmcoKSk7CisKKyAgLy8gQ2FuIHdlIHNlcmlhbGl6ZSBpdD8KKyAgLy8gKERvbid0IHVzZSBFWFBFQ1RfRVEgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIGR1bXAgcmF3IGJpbmFyeSBkYXRhIHRvIHRoZQorICAvLyB0ZXJtaW5hbCBvbiBmYWlsdXJlLikKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpID09IGRhdGEpOworCisgIC8vIFdoYXQgaWYgd2UgcGFyc2UgdXNpbmcgdGhlIHJlZmxlY3Rpb24tYmFzZWQgcGFyc2VyPworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICAgIGlucHV0LlNldEV4dGVuc2lvblJlZ2lzdHJ5KCZkeW5hbWljX3Bvb2wsICZkeW5hbWljX2ZhY3RvcnkpOworICAgIEFTU0VSVF9UUlVFKFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJm1lc3NhZ2UyKSk7CisgICAgQVNTRVJUX1RSVUUoaW5wdXQuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLkRlYnVnU3RyaW5nKCksIG1lc3NhZ2UyLkRlYnVnU3RyaW5nKCkpOworICB9CisKKyAgLy8gQXJlIHRoZSBlbWJlZGRlZCBnZW5lcmF0ZWQgdHlwZXMgYWN0dWFsbHkgdXNpbmcgdGhlIGdlbmVyYXRlZCBvYmplY3RzPworICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtZXNzYWdlX2V4dGVuc2lvbiA9CisgICAgICAgIGZpbGUtPkZpbmRFeHRlbnNpb25CeU5hbWUoIm1lc3NhZ2VfZXh0ZW5zaW9uIik7CisgICAgQVNTRVJUX1RSVUUobWVzc2FnZV9leHRlbnNpb24gIT0gTlVMTCk7CisgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPQorICAgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0TWVzc2FnZShtZXNzYWdlLCBtZXNzYWdlX2V4dGVuc2lvbik7CisgICAgY29uc3QgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiB0eXBlZF9zdWJfbWVzc2FnZSA9CisjaWZkZWYgR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKyAgICAgICAgc3RhdGljX2Nhc3Q8Y29uc3QgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKj4oJnN1Yl9tZXNzYWdlKTsKKyNlbHNlCisgICAgICAgIGR5bmFtaWNfY2FzdDxjb25zdCB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UqPigmc3ViX21lc3NhZ2UpOworI2VuZGlmCisgICAgQVNTRVJUX1RSVUUodHlwZWRfc3ViX21lc3NhZ2UgIT0gTlVMTCk7CisgICAgRVhQRUNUX0VRKDQ1NiwgdHlwZWRfc3ViX21lc3NhZ2UtPmMoKSk7CisgIH0KKworICAvLyBXaGF0IGRvZXMgR2V0TWVzc2FnZSgpIHJldHVybiBmb3IgdGhlIGVtYmVkZGVkIGR5bmFtaWMgdHlwZSBpZiBpdCBpc24ndAorICAvLyBwcmVzZW50PworICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0KKyAgICAgICAgZmlsZS0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiIpOworICAgIEFTU0VSVF9UUlVFKGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gIT0gTlVMTCk7CisgICAgY29uc3QgTWVzc2FnZSYgcGFyZW50ID0gdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPQorICAgICAgICBwYXJlbnQuR2V0UmVmbGVjdGlvbigpLT5HZXRNZXNzYWdlKHBhcmVudCwgZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHluYW1pY19mYWN0b3J5KTsKKyAgICBjb25zdCBNZXNzYWdlKiBwcm90b3R5cGUgPQorICAgICAgICBkeW5hbWljX2ZhY3RvcnkuR2V0UHJvdG90eXBlKGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24tPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICBFWFBFQ1RfRVEocHJvdG90eXBlLCAmc3ViX21lc3NhZ2UpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTJkNGIwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnByb3RvCkBAIC0wLDAgKzEsMTYxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1ZjsKKworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIkZpZWxkTWFza1Byb3RvIjsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKKworLy8gYEZpZWxkTWFza2AgcmVwcmVzZW50cyBhIHNldCBvZiBzeW1ib2xpYyBmaWVsZCBwYXRocywgZm9yIGV4YW1wbGU6CisvLworLy8gICAgIHBhdGhzOiAiZi5hIgorLy8gICAgIHBhdGhzOiAiZi5iLmQiCisvLworLy8gSGVyZSBgZmAgcmVwcmVzZW50cyBhIGZpZWxkIGluIHNvbWUgcm9vdCBtZXNzYWdlLCBgYWAgYW5kIGBiYAorLy8gZmllbGRzIGluIHRoZSBtZXNzYWdlIGZvdW5kIGluIGBmYCwgYW5kIGBkYCBhIGZpZWxkIGZvdW5kIGluIHRoZQorLy8gbWVzc2FnZSBpbiBgZi5iYC4KKy8vCisvLyBGaWVsZCBtYXNrcyBhcmUgdXNlZCB0byBzcGVjaWZ5IGEgc3Vic2V0IG9mIGZpZWxkcyB0aGF0IHNob3VsZCBiZQorLy8gcmV0dXJuZWQgYnkgYSBnZXQgb3BlcmF0aW9uIG9yIG1vZGlmaWVkIGJ5IGFuIHVwZGF0ZSBvcGVyYXRpb24uCisvLyBGaWVsZCBtYXNrcyBhbHNvIGhhdmUgYSBjdXN0b20gSlNPTiBlbmNvZGluZyAoc2VlIGJlbG93KS4KKy8vCisvLyAjIEZpZWxkIE1hc2tzIGluIFByb2plY3Rpb25zCisvLyBXaGVuIHVzZWQgaW4gdGhlIGNvbnRleHQgb2YgYSBwcm9qZWN0aW9uLCBhIHJlc3BvbnNlIG1lc3NhZ2Ugb3IKKy8vIHN1Yi1tZXNzYWdlIGlzIGZpbHRlcmVkIGJ5IHRoZSBBUEkgdG8gb25seSBjb250YWluIHRob3NlIGZpZWxkcyBhcworLy8gc3BlY2lmaWVkIGluIHRoZSBtYXNrLiBGb3IgZXhhbXBsZSwgaWYgdGhlIG1hc2sgaW4gdGhlIHByZXZpb3VzCisvLyBleGFtcGxlIGlzIGFwcGxpZWQgdG8gYSByZXNwb25zZSBtZXNzYWdlIGFzIGZvbGxvd3M6CisvLworLy8gICAgIGYgeworLy8gICAgICAgYSA6IDIyCisvLyAgICAgICBiIHsKKy8vICAgICAgICAgZCA6IDEKKy8vICAgICAgICAgeCA6IDIKKy8vICAgICAgIH0KKy8vICAgICAgIHkgOiAxMworLy8gICAgIH0KKy8vICAgICB6OiA4CisvLworLy8gVGhlIHJlc3VsdCB3aWxsIG5vdCBjb250YWluIHNwZWNpZmljIHZhbHVlcyBmb3IgZmllbGRzIHgseSBhbmQgegorLy8gKHRoZXJlIHZhbHVlIHdpbGwgYmUgc2V0IHRvIHRoZSBkZWZhdWx0LCBhbmQgb21pdHRlZCBpbiBwcm90byB0ZXh0CisvLyBvdXRwdXQpOgorLy8KKy8vCisvLyAgICAgZiB7CisvLyAgICAgICBhIDogMjIKKy8vICAgICAgIGIgeworLy8gICAgICAgICBkIDogMQorLy8gICAgICAgfQorLy8gICAgIH0KKy8vCisvLyBBIHJlcGVhdGVkIGZpZWxkIGlzIG5vdCBhbGxvd2VkIGV4Y2VwdCBhdCB0aGUgbGFzdCBwb3NpdGlvbiBvZiBhCisvLyBmaWVsZCBtYXNrLgorLy8KKy8vIElmIGEgRmllbGRNYXNrIG9iamVjdCBpcyBub3QgcHJlc2VudCBpbiBhIGdldCBvcGVyYXRpb24sIHRoZQorLy8gb3BlcmF0aW9uIGFwcGxpZXMgdG8gYWxsIGZpZWxkcyAoYXMgaWYgYSBGaWVsZE1hc2sgb2YgYWxsIGZpZWxkcworLy8gaGFkIGJlZW4gc3BlY2lmaWVkKS4KKy8vCisvLyBOb3RlIHRoYXQgYSBmaWVsZCBtYXNrIGRvZXMgbm90IG5lY2Vzc2FyaWx5IGFwcGxpZXMgdG8gdGhlCisvLyB0b3AtbGV2ZWwgcmVzcG9uc2UgbWVzc2FnZS4gSW4gY2FzZSBvZiBhIFJFU1QgZ2V0IG9wZXJhdGlvbiwgdGhlCisvLyBmaWVsZCBtYXNrIGFwcGxpZXMgZGlyZWN0bHkgdG8gdGhlIHJlc3BvbnNlLCBidXQgaW4gY2FzZSBvZiBhIFJFU1QKKy8vIGxpc3Qgb3BlcmF0aW9uLCB0aGUgbWFzayBpbnN0ZWFkIGFwcGxpZXMgdG8gZWFjaCBpbmRpdmlkdWFsIG1lc3NhZ2UKKy8vIGluIHRoZSByZXR1cm5lZCByZXNvdXJjZSBsaXN0LiBJbiBjYXNlIG9mIGEgUkVTVCBjdXN0b20gbWV0aG9kLAorLy8gb3RoZXIgZGVmaW5pdGlvbnMgbWF5IGJlIHVzZWQuIFdoZXJlIHRoZSBtYXNrIGFwcGxpZXMgd2lsbCBiZQorLy8gY2xlYXJseSBkb2N1bWVudGVkIHRvZ2V0aGVyIHdpdGggaXRzIGRlY2xhcmF0aW9uIGluIHRoZSBBUEkuICBJbgorLy8gYW55IGNhc2UsIHRoZSBlZmZlY3Qgb24gdGhlIHJldHVybmVkIHJlc291cmNlL3Jlc291cmNlcyBpcyByZXF1aXJlZAorLy8gYmVoYXZpb3IgZm9yIEFQSXMuCisvLworLy8gIyBGaWVsZCBNYXNrcyBpbiBVcGRhdGUgT3BlcmF0aW9ucworLy8gQSBmaWVsZCBtYXNrIGluIHVwZGF0ZSBvcGVyYXRpb25zIHNwZWNpZmllcyB3aGljaCBmaWVsZHMgb2YgdGhlCisvLyB0YXJnZXRlZCByZXNvdXJjZSBhcmUgZ29pbmcgdG8gYmUgdXBkYXRlZC4gVGhlIEFQSSBpcyByZXF1aXJlZAorLy8gdG8gb25seSBjaGFuZ2UgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzIGFzIHNwZWNpZmllZCBpbiB0aGUgbWFzaworLy8gYW5kIGxlYXZlIHRoZSBvdGhlcnMgdW50b3VjaGVkLiBJZiBhIHJlc291cmNlIGlzIHBhc3NlZCBpbiB0bworLy8gZGVzY3JpYmUgdGhlIHVwZGF0ZWQgdmFsdWVzLCB0aGUgQVBJIGlnbm9yZXMgdGhlIHZhbHVlcyBvZiBhbGwKKy8vIGZpZWxkcyBub3QgY292ZXJlZCBieSB0aGUgbWFzay4KKy8vCisvLyBJbiBvcmRlciB0byByZXNldCBhIGZpZWxkJ3MgdmFsdWUgdG8gdGhlIGRlZmF1bHQsIHRoZSBmaWVsZCBtdXN0CisvLyBiZSBpbiB0aGUgbWFzayBhbmQgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlIGluIHRoZSBwcm92aWRlZCByZXNvdXJjZS4KKy8vIEhlbmNlLCBpbiBvcmRlciB0byByZXNldCBhbGwgZmllbGRzIG9mIGEgcmVzb3VyY2UsIHByb3ZpZGUgYSBkZWZhdWx0CisvLyBpbnN0YW5jZSBvZiB0aGUgcmVzb3VyY2UgYW5kIHNldCBhbGwgZmllbGRzIGluIHRoZSBtYXNrLCBvciBkbworLy8gbm90IHByb3ZpZGUgYSBtYXNrIGFzIGRlc2NyaWJlZCBiZWxvdy4KKy8vCisvLyBJZiBhIGZpZWxkIG1hc2sgaXMgbm90IHByZXNlbnQgb24gdXBkYXRlLCB0aGUgb3BlcmF0aW9uIGFwcGxpZXMgdG8KKy8vIGFsbCBmaWVsZHMgKGFzIGlmIGEgZmllbGQgbWFzayBvZiBhbGwgZmllbGRzIGhhcyBiZWVuIHNwZWNpZmllZCkuCisvLyBOb3RlIHRoYXQgaW4gdGhlIHByZXNlbmNlIG9mIHNjaGVtYSBldm9sdXRpb24sIHRoaXMgbWF5IG1lYW4gdGhhdAorLy8gZmllbGRzIHRoZSBjbGllbnQgZG9lcyBub3Qga25vdyBhbmQgaGFzIHRoZXJlZm9yZSBub3QgZmlsbGVkIGludG8KKy8vIHRoZSByZXF1ZXN0IHdpbGwgYmUgcmVzZXQgdG8gdGhlaXIgZGVmYXVsdC4gSWYgdGhpcyBpcyB1bndhbnRlZAorLy8gYmVoYXZpb3IsIGEgc3BlY2lmaWMgc2VydmljZSBtYXkgcmVxdWlyZSBhIGNsaWVudCB0byBhbHdheXMgc3BlY2lmeQorLy8gYSBmaWVsZCBtYXNrLCBwcm9kdWNpbmcgYW4gZXJyb3IgaWYgbm90LgorLy8KKy8vIEFzIHdpdGggZ2V0IG9wZXJhdGlvbnMsIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmVzb3VyY2Ugd2hpY2gKKy8vIGRlc2NyaWJlcyB0aGUgdXBkYXRlZCB2YWx1ZXMgaW4gdGhlIHJlcXVlc3QgbWVzc2FnZSBkZXBlbmRzIG9uIHRoZQorLy8gb3BlcmF0aW9uIGtpbmQuIEluIGFueSBjYXNlLCB0aGUgZWZmZWN0IG9mIHRoZSBmaWVsZCBtYXNrIGlzCisvLyByZXF1aXJlZCB0byBiZSBob25vcmVkIGJ5IHRoZSBBUEkuCisvLworLy8gIyMgQ29uc2lkZXJhdGlvbnMgZm9yIEhUVFAgUkVTVAorLy8gVGhlIEhUVFAga2luZCBvZiBhbiB1cGRhdGUgb3BlcmF0aW9uIHdoaWNoIHVzZXMgYSBmaWVsZCBtYXNrIG11c3QKKy8vIGJlIHNldCB0byBQQVRDSCBpbnN0ZWFkIG9mIFBVVCBpbiBvcmRlciB0byBzYXRpc2Z5IEhUVFAgc2VtYW50aWNzCisvLyAoUFVUIG11c3Qgb25seSBiZSB1c2VkIGZvciBmdWxsIHVwZGF0ZXMpLgorLy8KKy8vICMgSlNPTiBFbmNvZGluZyBvZiBGaWVsZCBNYXNrcworLy8gSW4gSlNPTiwgYSBmaWVsZCBtYXNrIGlzIGVuY29kZWQgYXMgYSBzaW5nbGUgc3RyaW5nIHdoZXJlIHBhdGhzIGFyZQorLy8gc2VwYXJhdGVkIGJ5IGEgY29tbWEuIEZpZWxkcyBuYW1lIGluIGVhY2ggcGF0aCBhcmUgY29udmVydGVkCisvLyB0by9mcm9tIGxvd2VyLWNhbWVsIG5hbWluZyBjb252ZW50aW9ucy4KKy8vCisvLyBBcyBhbiBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVjbGFyYXRpb25zOgorLy8KKy8vICAgICBtZXNzYWdlIFByb2ZpbGUgeworLy8gICAgICAgVXNlciB1c2VyID0gMTsKKy8vICAgICAgIFBob3RvIHBob3RvID0gMjsKKy8vICAgICB9CisvLyAgICAgbWVzc2FnZSBVc2VyIHsKKy8vICAgICAgIHN0cmluZyBkaXNwbGF5X25hbWUgPSAxOworLy8gICAgICAgc3RyaW5nIGFkZHJlc3MgPSAyOworLy8gICAgIH0KKy8vCisvLyBJbiBwcm90byBhIGZpZWxkIG1hc2sgZm9yIGBQcm9maWxlYCBtYXkgbG9vayBhcyBzdWNoOgorLy8KKy8vICAgICBtYXNrIHsKKy8vICAgICAgIHBhdGhzOiAidXNlci5kaXNwbGF5X25hbWUiCisvLyAgICAgICBwYXRoczogInBob3RvIgorLy8gICAgIH0KKy8vCisvLyBJbiBKU09OLCB0aGUgc2FtZSBtYXNrIGlzIHJlcHJlc2VudGVkIGFzIGJlbG93OgorLy8KKy8vICAgICB7CisvLyAgICAgICBtYXNrOiAidXNlci5kaXNwbGF5TmFtZSxwaG90byIKKy8vICAgICB9CisvLworbWVzc2FnZSBGaWVsZE1hc2sgeworICAvLyBUaGUgc2V0IG9mIGZpZWxkIG1hc2sgcGF0aHMuCisgIHJlcGVhdGVkIHN0cmluZyBwYXRocyA9IDE7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkY2RjMjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaApAQCAtMCwwICsxLDg4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBqYXNvbmhAZ29vZ2xlLmNvbSAoSmFzb24gSHN1ZWgpCisvLworLy8gVGhpcyBoZWFkZXIgaXMgbG9naWNhbGx5IGludGVybmFsLCBidXQgaXMgbWFkZSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCisvLyBmcm9tIHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZCBjb2RlLCB3aGljaCBtYXkgcmVzaWRlIGluIG90aGVyIGNvbXBvbmVudHMuCisvLyBJdCBwcm92aWRlcyByZWZsZWN0aW9uIHN1cHBvcnQgZm9yIGdlbmVyYXRlZCBlbnVtcywgYW5kIGlzIGluY2x1ZGVkIGluCisvLyBnZW5lcmF0ZWQgLnBiLmggZmlsZXMgYW5kIHNob3VsZCBoYXZlIG1pbmltYWwgZGVwZW5kZW5jaWVzLiBUaGUgbWV0aG9kcyBhcmUKKy8vIGltcGxlbWVudGVkIGluIGdlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9FTlVNX1JFRkxFQ1RJT05fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfRU5VTV9SRUZMRUNUSU9OX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIGNsYXNzIEVudW1EZXNjcmlwdG9yOworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIFJldHVybnMgdGhlIEVudW1EZXNjcmlwdG9yIGZvciBlbnVtIHR5cGUgRSwgd2hpY2ggbXVzdCBiZSBhCisvLyBwcm90by1kZWNsYXJlZCBlbnVtIHR5cGUuICBDb2RlIGdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgY29tcGlsZXIKKy8vIHdpbGwgaW5jbHVkZSBzcGVjaWFsaXphdGlvbnMgb2YgdGhpcyB0ZW1wbGF0ZSBmb3IgZWFjaCBlbnVtIHR5cGUgZGVjbGFyZWQuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRT4KK2NvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcigpOworCituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBIZWxwZXIgZm9yIEVudW1UeXBlX1BhcnNlIGZ1bmN0aW9uczogdHJ5IHRvIHBhcnNlIHRoZSBzdHJpbmcgJ25hbWUnIGFzIGFuCisvLyBlbnVtIG5hbWUgb2YgdGhlIGdpdmVuIHR5cGUsIHJldHVybmluZyB0cnVlIGFuZCBmaWxsaW5nIGluIHZhbHVlIG9uIHN1Y2Nlc3MsCisvLyBvciByZXR1cm5pbmcgZmFsc2UgYW5kIGxlYXZpbmcgdmFsdWUgdW5jaGFuZ2VkIG9uIGZhaWx1cmUuCitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBQYXJzZU5hbWVkRW51bShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICBpbnQqIHZhbHVlKTsKKwordGVtcGxhdGU8dHlwZW5hbWUgRW51bVR5cGU+Citib29sIFBhcnNlTmFtZWRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgIEVudW1UeXBlKiB2YWx1ZSkgeworICBpbnQgdG1wOworICBpZiAoIVBhcnNlTmFtZWRFbnVtKGRlc2NyaXB0b3IsIG5hbWUsICZ0bXApKSByZXR1cm4gZmFsc2U7CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PEVudW1UeXBlPih0bXApOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gSnVzdCBhIHdyYXBwZXIgYXJvdW5kIHByaW50aW5nIHRoZSBuYW1lIG9mIGEgdmFsdWUuIFRoZSBtYWluIHBvaW50IG9mIHRoaXMKKy8vIGZ1bmN0aW9uIGlzIG5vdCB0byBiZSBpbmxpbmVkLCBzbyB0aGF0IHlvdSBjYW4gZG8gdGhpcyB3aXRob3V0IGluY2x1ZGluZworLy8gZGVzY3JpcHRvci5oLgorTElCUFJPVE9CVUZfRVhQT1JUIGNvbnN0IHN0cmluZyYgTmFtZU9mRW51bShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IHZhbHVlKTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX0VOVU1fUkVGTEVDVElPTl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQyNDIwNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fdXRpbC5oCkBAIC0wLDAgKzEsNDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfRU5VTV9VVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX0VOVU1fVVRJTF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gVGhpcyB0eXBlIHRyYWl0IGNhbiBiZSB1c2VkIHRvIGNhdXNlIHRlbXBsYXRlcyB0byBvbmx5IG1hdGNoIHByb3RvMiBlbnVtCisvLyB0eXBlcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPiBzdHJ1Y3QgaXNfcHJvdG9fZW51bSA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUge307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfRU5VTV9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxMmM0OGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MKQEAgLTAsMCArMSwyMTU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8c2V0PgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisKKworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTX09ORU9GCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK25hbWVzcGFjZSB7Citib29sIElzTWFwRmllbGRJbkFwaShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBmaWVsZC0+aXNfbWFwKCk7Cit9Cit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK2ludCBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIGNvbnN0IHZvaWQqIHN0YXJ0ID0gJnN0cjsKKyAgY29uc3Qgdm9pZCogZW5kID0gJnN0ciArIDE7CisKKyAgaWYgKHN0YXJ0IDw9IHN0ci5kYXRhKCkgJiYgc3RyLmRhdGEoKSA8IGVuZCkgeworICAgIC8vIFRoZSBzdHJpbmcncyBkYXRhIGlzIHN0b3JlZCBpbnNpZGUgdGhlIHN0cmluZyBvYmplY3QgaXRzZWxmLgorICAgIHJldHVybiAwOworICB9IGVsc2UgeworICAgIHJldHVybiBzdHIuY2FwYWNpdHkoKTsKKyAgfQorfQorCitib29sIFBhcnNlTmFtZWRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgIGludCogdmFsdWUpIHsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZCA9IGRlc2NyaXB0b3ItPkZpbmRWYWx1ZUJ5TmFtZShuYW1lKTsKKyAgaWYgKGQgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBkLT5udW1iZXIoKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NvbnN0IHN0cmluZyYgTmFtZU9mRW51bShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IHZhbHVlKSB7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGQgPSBkZXNjcmlwdG9yLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgIHJldHVybiAoZCA9PSBOVUxMID8gR2V0RW1wdHlTdHJpbmcoKSA6IGQtPm5hbWUoKSk7Cit9CisKK25hbWVzcGFjZSB7CitpbmxpbmUgYm9vbCBTdXBwb3J0c0FyZW5hcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5jY19lbmFibGVfYXJlbmFzKCk7Cit9Cit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEhlbHBlcnMgZm9yIHJlcG9ydGluZyB1c2FnZSBlcnJvcnMgKGUuZy4gdHJ5aW5nIHRvIHVzZSBHZXRJbnQzMigpIG9uCisvLyBhIHN0cmluZyBmaWVsZCkuCisKK25hbWVzcGFjZSB7CisKK3ZvaWQgUmVwb3J0UmVmbGVjdGlvblVzYWdlRXJyb3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBjaGFyKiBtZXRob2QsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uKSB7CisgIEdPT0dMRV9MT0coRkFUQUwpCisgICAgPDwgIlByb3RvY29sIEJ1ZmZlciByZWZsZWN0aW9uIHVzYWdlIGVycm9yOlxuIgorICAgICAgICIgIE1ldGhvZCAgICAgIDogZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbjo6IiA8PCBtZXRob2QgPDwgIlxuIgorICAgICAgICIgIE1lc3NhZ2UgdHlwZTogIiA8PCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSA8PCAiXG4iCisgICAgICAgIiAgRmllbGQgICAgICAgOiAiIDw8IGZpZWxkLT5mdWxsX25hbWUoKSA8PCAiXG4iCisgICAgICAgIiAgUHJvYmxlbSAgICAgOiAiIDw8IGRlc2NyaXB0aW9uOworfQorCitjb25zdCBjaGFyKiBjcHB0eXBlX25hbWVzX1tGaWVsZERlc2NyaXB0b3I6Ok1BWF9DUFBUWVBFICsgMV0gPSB7CisgICJJTlZBTElEX0NQUFRZUEUiLAorICAiQ1BQVFlQRV9JTlQzMiIsCisgICJDUFBUWVBFX0lOVDY0IiwKKyAgIkNQUFRZUEVfVUlOVDMyIiwKKyAgIkNQUFRZUEVfVUlOVDY0IiwKKyAgIkNQUFRZUEVfRE9VQkxFIiwKKyAgIkNQUFRZUEVfRkxPQVQiLAorICAiQ1BQVFlQRV9CT09MIiwKKyAgIkNQUFRZUEVfRU5VTSIsCisgICJDUFBUWVBFX1NUUklORyIsCisgICJDUFBUWVBFX01FU1NBR0UiCit9OworCitzdGF0aWMgdm9pZCBSZXBvcnRSZWZsZWN0aW9uVXNhZ2VUeXBlRXJyb3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBjaGFyKiBtZXRob2QsCisgICAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGV4cGVjdGVkX3R5cGUpIHsKKyAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICA8PCAiUHJvdG9jb2wgQnVmZmVyIHJlZmxlY3Rpb24gdXNhZ2UgZXJyb3I6XG4iCisgICAgICAgIiAgTWV0aG9kICAgICAgOiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uOjoiIDw8IG1ldGhvZCA8PCAiXG4iCisgICAgICAgIiAgTWVzc2FnZSB0eXBlOiAiIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBGaWVsZCAgICAgICA6ICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBQcm9ibGVtICAgICA6IEZpZWxkIGlzIG5vdCB0aGUgcmlnaHQgdHlwZSBmb3IgdGhpcyBtZXNzYWdlOlxuIgorICAgICAgICIgICAgRXhwZWN0ZWQgIDogIiA8PCBjcHB0eXBlX25hbWVzX1tleHBlY3RlZF90eXBlXSA8PCAiXG4iCisgICAgICAgIiAgICBGaWVsZCB0eXBlOiAiIDw8IGNwcHR5cGVfbmFtZXNfW2ZpZWxkLT5jcHBfdHlwZSgpXTsKK30KKworc3RhdGljIHZvaWQgUmVwb3J0UmVmbGVjdGlvblVzYWdlRW51bVR5cGVFcnJvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IGNoYXIqIG1ldGhvZCwgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIHsKKyAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICA8PCAiUHJvdG9jb2wgQnVmZmVyIHJlZmxlY3Rpb24gdXNhZ2UgZXJyb3I6XG4iCisgICAgICAgIiAgTWV0aG9kICAgICAgOiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uOjoiIDw8IG1ldGhvZCA8PCAiXG4iCisgICAgICAgIiAgTWVzc2FnZSB0eXBlOiAiIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBGaWVsZCAgICAgICA6ICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBQcm9ibGVtICAgICA6IEVudW0gdmFsdWUgZGlkIG5vdCBtYXRjaCBmaWVsZCB0eXBlOlxuIgorICAgICAgICIgICAgRXhwZWN0ZWQgIDogIiA8PCBmaWVsZC0+ZW51bV90eXBlKCktPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICAgIEFjdHVhbCAgICA6ICIgPDwgdmFsdWUtPmZ1bGxfbmFtZSgpOworfQorCisjZGVmaW5lIFVTQUdFX0NIRUNLKENPTkRJVElPTiwgTUVUSE9ELCBFUlJPUl9ERVNDUklQVElPTikgICAgICAgICAgICAgICAgICAgICAgXAorICBpZiAoIShDT05ESVRJT04pKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBSZXBvcnRSZWZsZWN0aW9uVXNhZ2VFcnJvcihkZXNjcmlwdG9yXywgZmllbGQsICNNRVRIT0QsIEVSUk9SX0RFU0NSSVBUSU9OKQorI2RlZmluZSBVU0FHRV9DSEVDS19FUShBLCBCLCBNRVRIT0QsIEVSUk9SX0RFU0NSSVBUSU9OKSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVVNBR0VfQ0hFQ0soKEEpID09IChCKSwgTUVUSE9ELCBFUlJPUl9ERVNDUklQVElPTikKKyNkZWZpbmUgVVNBR0VfQ0hFQ0tfTkUoQSwgQiwgTUVUSE9ELCBFUlJPUl9ERVNDUklQVElPTikgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFVTQUdFX0NIRUNLKChBKSAhPSAoQiksIE1FVEhPRCwgRVJST1JfREVTQ1JJUFRJT04pCisKKyNkZWZpbmUgVVNBR0VfQ0hFQ0tfVFlQRShNRVRIT0QsIENQUFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFKSAgICAgICAgICAgICAgICAgXAorICAgIFJlcG9ydFJlZmxlY3Rpb25Vc2FnZVR5cGVFcnJvcihkZXNjcmlwdG9yXywgZmllbGQsICNNRVRIT0QsICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjQ1BQVFlQRSkKKworI2RlZmluZSBVU0FHRV9DSEVDS19FTlVNX1ZBTFVFKE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaWYgKHZhbHVlLT50eXBlKCkgIT0gZmllbGQtPmVudW1fdHlwZSgpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgUmVwb3J0UmVmbGVjdGlvblVzYWdlRW51bVR5cGVFcnJvcihkZXNjcmlwdG9yXywgZmllbGQsICNNRVRIT0QsIHZhbHVlKQorCisjZGVmaW5lIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVU0FHRV9DSEVDS19FUShmaWVsZC0+Y29udGFpbmluZ190eXBlKCksIGRlc2NyaXB0b3JfLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgTUVUSE9ELCAiRmllbGQgZG9lcyBub3QgbWF0Y2ggbWVzc2FnZSB0eXBlLiIpOworI2RlZmluZSBVU0FHRV9DSEVDS19TSU5HVUxBUihNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVVNBR0VfQ0hFQ0tfTkUoZmllbGQtPmxhYmVsKCksIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQsIE1FVEhPRCwgICAgICBcCisgICAgICAgICAgICAgICAgICJGaWVsZCBpcyByZXBlYXRlZDsgdGhlIG1ldGhvZCByZXF1aXJlcyBhIHNpbmd1bGFyIGZpZWxkLiIpCisjZGVmaW5lIFVTQUdFX0NIRUNLX1JFUEVBVEVEKE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVU0FHRV9DSEVDS19FUShmaWVsZC0+bGFiZWwoKSwgRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCwgTUVUSE9ELCAgICAgIFwKKyAgICAgICAgICAgICAgICAgIkZpZWxkIGlzIHNpbmd1bGFyOyB0aGUgbWV0aG9kIHJlcXVpcmVzIGEgcmVwZWF0ZWQgZmllbGQuIikKKworI2RlZmluZSBVU0FHRV9DSEVDS19BTEwoTUVUSE9ELCBMQUJFTCwgQ1BQVFlQRSkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBVU0FHRV9DSEVDS19NRVNTQUdFX1RZUEUoTUVUSE9EKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfIyNMQUJFTChNRVRIT0QpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX1RZUEUoTUVUSE9ELCBDUFBUWVBFKQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2luc3RhbmNlLAorICAgIGNvbnN0IGludCBvZmZzZXRzW10sCisgICAgaW50IGhhc19iaXRzX29mZnNldCwKKyAgICBpbnQgdW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgIGludCBleHRlbnNpb25zX29mZnNldCwKKyAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogZGVzY3JpcHRvcl9wb29sLAorICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5LAorICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgIGludCBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkKKyAgOiBkZXNjcmlwdG9yXyAgICAgICAoZGVzY3JpcHRvciksCisgICAgZGVmYXVsdF9pbnN0YW5jZV8gKGRlZmF1bHRfaW5zdGFuY2UpLAorICAgIG9mZnNldHNfICAgICAgICAgIChvZmZzZXRzKSwKKyAgICBoYXNfYml0c19vZmZzZXRfICAoaGFzX2JpdHNfb2Zmc2V0KSwKKyAgICB1bmtub3duX2ZpZWxkc19vZmZzZXRfKHVua25vd25fZmllbGRzX29mZnNldCksCisgICAgZXh0ZW5zaW9uc19vZmZzZXRfKGV4dGVuc2lvbnNfb2Zmc2V0KSwKKyAgICBhcmVuYV9vZmZzZXRfICAgICAoYXJlbmFfb2Zmc2V0KSwKKyAgICBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldF8oaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQpLAorICAgIG9iamVjdF9zaXplXyAgICAgIChvYmplY3Rfc2l6ZSksCisgICAgZGVzY3JpcHRvcl9wb29sXyAgKChkZXNjcmlwdG9yX3Bvb2wgPT0gTlVMTCkgPworICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yX3Bvb2wpLAorICAgIG1lc3NhZ2VfZmFjdG9yeV8gIChmYWN0b3J5KSB7Cit9CisKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0LAorICAgIGNvbnN0IHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UsCisgICAgaW50IG9uZW9mX2Nhc2Vfb2Zmc2V0LAorICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBkZXNjcmlwdG9yX3Bvb2wsCisgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnksCisgICAgaW50IG9iamVjdF9zaXplLAorICAgIGludCBhcmVuYV9vZmZzZXQsCisgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KQorICA6IGRlc2NyaXB0b3JfICAgICAgIChkZXNjcmlwdG9yKSwKKyAgICBkZWZhdWx0X2luc3RhbmNlXyAoZGVmYXVsdF9pbnN0YW5jZSksCisgICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8gKGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpLAorICAgIG9mZnNldHNfICAgICAgICAgIChvZmZzZXRzKSwKKyAgICBoYXNfYml0c19vZmZzZXRfICAoaGFzX2JpdHNfb2Zmc2V0KSwKKyAgICBvbmVvZl9jYXNlX29mZnNldF8ob25lb2ZfY2FzZV9vZmZzZXQpLAorICAgIHVua25vd25fZmllbGRzX29mZnNldF8odW5rbm93bl9maWVsZHNfb2Zmc2V0KSwKKyAgICBleHRlbnNpb25zX29mZnNldF8oZXh0ZW5zaW9uc19vZmZzZXQpLAorICAgIGFyZW5hX29mZnNldF8gICAgIChhcmVuYV9vZmZzZXQpLAorICAgIGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0Xyhpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCksCisgICAgb2JqZWN0X3NpemVfICAgICAgKG9iamVjdF9zaXplKSwKKyAgICBkZXNjcmlwdG9yX3Bvb2xfICAoKGRlc2NyaXB0b3JfcG9vbCA9PSBOVUxMKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkgOgorICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfcG9vbCksCisgICAgbWVzc2FnZV9mYWN0b3J5XyAgKGZhY3RvcnkpIHsKK30KKworR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246On5HZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigpIHt9CisKK25hbWVzcGFjZSB7CitVbmtub3duRmllbGRTZXQqIGVtcHR5X3Vua25vd25fZmllbGRfc2V0XyA9IE5VTEw7CitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGVtcHR5X3Vua25vd25fZmllbGRfc2V0X29uY2VfKTsKKwordm9pZCBEZWxldGVFbXB0eVVua25vd25GaWVsZFNldCgpIHsKKyAgZGVsZXRlIGVtcHR5X3Vua25vd25fZmllbGRfc2V0XzsKKyAgZW1wdHlfdW5rbm93bl9maWVsZF9zZXRfID0gTlVMTDsKK30KKwordm9pZCBJbml0RW1wdHlVbmtub3duRmllbGRTZXQoKSB7CisgIGVtcHR5X3Vua25vd25fZmllbGRfc2V0XyA9IG5ldyBVbmtub3duRmllbGRTZXQ7CisgIGludGVybmFsOjpPblNodXRkb3duKCZEZWxldGVFbXB0eVVua25vd25GaWVsZFNldCk7Cit9CisKK2NvbnN0IFVua25vd25GaWVsZFNldCYgR2V0RW1wdHlVbmtub3duRmllbGRTZXQoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmVtcHR5X3Vua25vd25fZmllbGRfc2V0X29uY2VfLCAmSW5pdEVtcHR5VW5rbm93bkZpZWxkU2V0KTsKKyAgcmV0dXJuICplbXB0eV91bmtub3duX2ZpZWxkX3NldF87Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworY29uc3QgVW5rbm93bkZpZWxkU2V0JiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0VW5rbm93bkZpZWxkcygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+ZmlsZSgpLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgIHJldHVybiBHZXRFbXB0eVVua25vd25GaWVsZFNldCgpOworICB9CisgIGlmICh1bmtub3duX2ZpZWxkc19vZmZzZXRfID09IGtVbmtub3duRmllbGRTZXRJbk1ldGFkYXRhKSB7CisgICAgcmV0dXJuIEdldEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEobWVzc2FnZSkudW5rbm93bl9maWVsZHMoKTsKKyAgfQorICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsKKyAgICAgICAgICAgICAgICAgICAgdW5rbm93bl9maWVsZHNfb2Zmc2V0XzsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IFVua25vd25GaWVsZFNldCo+KHB0cik7Cit9CisKK1Vua25vd25GaWVsZFNldCogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVVbmtub3duRmllbGRzKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0IHsKKyAgaWYgKHVua25vd25fZmllbGRzX29mZnNldF8gPT0ga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEpIHsKKyAgICByZXR1cm4gTXV0YWJsZUludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEobWVzc2FnZSktPgorICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKyAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgdW5rbm93bl9maWVsZHNfb2Zmc2V0XzsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VW5rbm93bkZpZWxkU2V0Kj4ocHRyKTsKK30KKworaW50IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTcGFjZVVzZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgeworICAvLyBvYmplY3Rfc2l6ZV8gYWxyZWFkeSBpbmNsdWRlcyB0aGUgaW4tbWVtb3J5IHJlcHJlc2VudGF0aW9uIG9mIGVhY2ggZmllbGQKKyAgLy8gaW4gdGhlIG1lc3NhZ2UsIHNvIHdlIG9ubHkgbmVlZCB0byBhY2NvdW50IGZvciBhZGRpdGlvbmFsIG1lbW9yeSB1c2VkIGJ5CisgIC8vIHRoZSBmaWVsZHMuCisgIGludCB0b3RhbF9zaXplID0gb2JqZWN0X3NpemVfOworCisgIHRvdGFsX3NpemUgKz0gR2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKS5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7CisKKyAgaWYgKGV4dGVuc2lvbnNfb2Zmc2V0XyAhPSAtMSkgeworICAgIHRvdGFsX3NpemUgKz0gR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0UgOiAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB0b3RhbF9zaXplICs9IEdldFJhdzxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihtZXNzYWdlLCBmaWVsZCkgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggRkxPQVQsICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgICBpbnQpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICAgIHRvdGFsX3NpemUgKz0gR2V0UmF3PFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiA+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICAgIHRvdGFsX3NpemUgKz0KKyAgICAgICAgICAgICAgICBHZXRSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBXZSBkb24ndCBrbm93IHdoaWNoIHN1YmNsYXNzIG9mIFJlcGVhdGVkUHRyRmllbGRCYXNlIHRoZSB0eXBlIGlzLAorICAgICAgICAgICAgLy8gc28gd2UgdXNlIFJlcGVhdGVkUHRyRmllbGRCYXNlIGRpcmVjdGx5LgorICAgICAgICAgICAgdG90YWxfc2l6ZSArPQorICAgICAgICAgICAgICAgIEdldFJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAgICAgICAuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZjxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgICAgICAgIH0KKworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAmJiAhSGFzT25lb2ZGaWVsZChtZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyIDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQgOgorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVCA6CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0wgIDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSAgOgorICAgICAgICAgIC8vIEZpZWxkIGlzIGlubGluZSwgc28gd2UndmUgYWxyZWFkeSBjb3VudGVkIGl0LgorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgICAgICAgLy8gSW5pdGlhbGx5LCB0aGUgc3RyaW5nIHBvaW50cyB0byB0aGUgZGVmYXVsdCB2YWx1ZSBzdG9yZWQgaW4KKyAgICAgICAgICAgICAgLy8gdGhlIHByb3RvdHlwZS4gT25seSBjb3VudCB0aGUgc3RyaW5nIGlmIGl0IGhhcyBiZWVuIGNoYW5nZWQKKyAgICAgICAgICAgICAgLy8gZnJvbSB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBwdHIgPQorICAgICAgICAgICAgICAgICAgJkdldEZpZWxkPEFyZW5hU3RyaW5nUHRyPihtZXNzYWdlLCBmaWVsZCkuR2V0KGRlZmF1bHRfcHRyKTsKKworICAgICAgICAgICAgICBpZiAocHRyICE9IGRlZmF1bHRfcHRyKSB7CisgICAgICAgICAgICAgICAgLy8gc3RyaW5nIGZpZWxkcyBhcmUgcmVwcmVzZW50ZWQgYnkganVzdCBhIHBvaW50ZXIsIHNvIGFsc28KKyAgICAgICAgICAgICAgICAvLyBpbmNsdWRlIHNpemVvZihzdHJpbmcpIGFzIHdlbGwuCisgICAgICAgICAgICAgICAgdG90YWxfc2l6ZSArPSBzaXplb2YoKnB0cikgKyBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCpwdHIpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKCZtZXNzYWdlID09IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgICAgICAgICAvLyBGb3Igc2luZ3VsYXIgZmllbGRzLCB0aGUgcHJvdG90eXBlIGp1c3Qgc3RvcmVzIGEgcG9pbnRlciB0byB0aGUKKyAgICAgICAgICAgIC8vIGV4dGVybmFsIHR5cGUncyBwcm90b3R5cGUsIHNvIHRoZXJlIGlzIG5vIGV4dHJhIG1lbW9yeSB1c2FnZS4KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2UgPSBHZXRSYXc8Y29uc3QgTWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgICAgICAgIGlmIChzdWJfbWVzc2FnZSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgIHRvdGFsX3NpemUgKz0gc3ViX21lc3NhZ2UtPlNwYWNlVXNlZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcEZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UyLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTV0FQX0FSUkFZUyhDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkRmllbGQ8VFlQRT4gPihtZXNzYWdlMSwgZmllbGQpLT5Td2FwKCAgICAgICAgXAorICAgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZEZpZWxkPFRZUEU+ID4obWVzc2FnZTIsIGZpZWxkKSk7ICAgICAgICAgXAorICAgICAgICBicmVhazsKKworICAgICAgU1dBUF9BUlJBWVMoSU5UMzIgLCBpbnQzMiApOworICAgICAgU1dBUF9BUlJBWVMoSU5UNjQgLCBpbnQ2NCApOworICAgICAgU1dBUF9BUlJBWVMoVUlOVDMyLCB1aW50MzIpOworICAgICAgU1dBUF9BUlJBWVMoVUlOVDY0LCB1aW50NjQpOworICAgICAgU1dBUF9BUlJBWVMoRkxPQVQgLCBmbG9hdCApOworICAgICAgU1dBUF9BUlJBWVMoRE9VQkxFLCBkb3VibGUpOworICAgICAgU1dBUF9BUlJBWVMoQk9PTCAgLCBib29sICApOworICAgICAgU1dBUF9BUlJBWVMoRU5VTSAgLCBpbnQgICApOworI3VuZGVmIFNXQVBfQVJSQVlTCisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UxLCBmaWVsZCktPgorICAgICAgICAgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoKS0+CisgICAgICAgICAgICAgIFN3YXA8R2VuZXJpY1R5cGVIYW5kbGVyPGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2U+ID4oCisgICAgICAgICAgICAgICAgTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UyLCBmaWVsZCktPgorICAgICAgICAgICAgICAgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZTEsIGZpZWxkKS0+CisgICAgICAgICAgICBTd2FwPEdlbmVyaWNUeXBlSGFuZGxlcjxnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlPiA+KAorICAgICAgICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlMiwgZmllbGQpKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgdHlwZTogIiA8PCBmaWVsZC0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTV0FQX1ZBTFVFUyhDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBzdGQ6OnN3YXAoKk11dGFibGVSYXc8VFlQRT4obWVzc2FnZTEsIGZpZWxkKSwgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgKk11dGFibGVSYXc8VFlQRT4obWVzc2FnZTIsIGZpZWxkKSk7ICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsKKworICAgICAgU1dBUF9WQUxVRVMoSU5UMzIgLCBpbnQzMiApOworICAgICAgU1dBUF9WQUxVRVMoSU5UNjQgLCBpbnQ2NCApOworICAgICAgU1dBUF9WQUxVRVMoVUlOVDMyLCB1aW50MzIpOworICAgICAgU1dBUF9WQUxVRVMoVUlOVDY0LCB1aW50NjQpOworICAgICAgU1dBUF9WQUxVRVMoRkxPQVQgLCBmbG9hdCApOworICAgICAgU1dBUF9WQUxVRVMoRE9VQkxFLCBkb3VibGUpOworICAgICAgU1dBUF9WQUxVRVMoQk9PTCAgLCBib29sICApOworICAgICAgU1dBUF9WQUxVRVMoRU5VTSAgLCBpbnQgICApOworI3VuZGVmIFNXQVBfVkFMVUVTCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBzdGQ6OnN3YXAoKk11dGFibGVSYXc8TWVzc2FnZSo+KG1lc3NhZ2UxLCBmaWVsZCksCisgICAgICAgICAgICAgICAgICAqTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZTIsIGZpZWxkKSk7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIE11dGFibGVSYXc8QXJlbmFTdHJpbmdQdHI+KG1lc3NhZ2UxLCBmaWVsZCktPlN3YXAoCisgICAgICAgICAgICAgICAgTXV0YWJsZVJhdzxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZTIsIGZpZWxkKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgdHlwZTogIiA8PCBmaWVsZC0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcE9uZW9mRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZTEsCisgICAgTWVzc2FnZSogbWVzc2FnZTIsCisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdCB7CisgIHVpbnQzMiBvbmVvZl9jYXNlMSA9IEdldE9uZW9mQ2FzZSgqbWVzc2FnZTEsIG9uZW9mX2Rlc2NyaXB0b3IpOworICB1aW50MzIgb25lb2ZfY2FzZTIgPSBHZXRPbmVvZkNhc2UoKm1lc3NhZ2UyLCBvbmVvZl9kZXNjcmlwdG9yKTsKKworICBpbnQzMiB0ZW1wX2ludDMyOworICBpbnQ2NCB0ZW1wX2ludDY0OworICB1aW50MzIgdGVtcF91aW50MzI7CisgIHVpbnQ2NCB0ZW1wX3VpbnQ2NDsKKyAgZmxvYXQgdGVtcF9mbG9hdDsKKyAgZG91YmxlIHRlbXBfZG91YmxlOworICBib29sIHRlbXBfYm9vbDsKKyAgaW50IHRlbXBfaW50OworICBNZXNzYWdlKiB0ZW1wX21lc3NhZ2UgPSBOVUxMOworICBzdHJpbmcgdGVtcF9zdHJpbmc7CisKKyAgLy8gU3RvcmVzIG1lc3NhZ2UxJ3Mgb25lb2YgZmllbGQgdG8gYSB0ZW1wIHZhcmlhYmxlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMSA9IE5VTEw7CisgIGlmIChvbmVvZl9jYXNlMSA+IDApIHsKKyAgICBmaWVsZDEgPSBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOdW1iZXIob25lb2ZfY2FzZTEpOworICAgIC8vb25lb2ZfZGVzY3JpcHRvci0+ZmllbGQob25lb2ZfY2FzZTEpOworICAgIHN3aXRjaCAoZmllbGQxLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEdFVF9URU1QX1ZBTFVFKENQUFRZUEUsIFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHRlbXBfIyNUWVBFID0gR2V0RmllbGQ8VFlQRT4oKm1lc3NhZ2UxLCBmaWVsZDEpOyAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOworCisgICAgICBHRVRfVEVNUF9WQUxVRShJTlQzMiAsIGludDMyICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShJTlQ2NCAsIGludDY0ICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBHRVRfVEVNUF9WQUxVRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBHRVRfVEVNUF9WQUxVRShGTE9BVCAsIGZsb2F0ICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBHRVRfVEVNUF9WQUxVRShCT09MICAsIGJvb2wgICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShFTlVNICAsIGludCAgICk7CisjdW5kZWYgR0VUX1RFTVBfVkFMVUUKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHRlbXBfbWVzc2FnZSA9IFJlbGVhc2VNZXNzYWdlKG1lc3NhZ2UxLCBmaWVsZDEpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICB0ZW1wX3N0cmluZyA9IEdldFN0cmluZygqbWVzc2FnZTEsIGZpZWxkMSk7CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5pbXBsZW1lbnRlZCB0eXBlOiAiIDw8IGZpZWxkMS0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0KKworICAvLyBTZXRzIG1lc3NhZ2UxJ3Mgb25lb2YgZmllbGQgZnJvbSB0aGUgbWVzc2FnZTIncyBvbmVvZiBmaWVsZC4KKyAgaWYgKG9uZW9mX2Nhc2UyID4gMCkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQyID0KKyAgICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TnVtYmVyKG9uZW9mX2Nhc2UyKTsKKyAgICBzd2l0Y2ggKGZpZWxkMi0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTRVRfT05FT0ZfVkFMVUUxKENQUFRZUEUsIFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTZXRGaWVsZDxUWVBFPihtZXNzYWdlMSwgZmllbGQyLCBHZXRGaWVsZDxUWVBFPigqbWVzc2FnZTIsIGZpZWxkMikpOyBcCisgICAgICAgIGJyZWFrOworCisgICAgICBTRVRfT05FT0ZfVkFMVUUxKElOVDMyICwgaW50MzIgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTEoSU5UNjQgLCBpbnQ2NCApOworICAgICAgU0VUX09ORU9GX1ZBTFVFMShVSU5UMzIsIHVpbnQzMik7CisgICAgICBTRVRfT05FT0ZfVkFMVUUxKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTEoRkxPQVQgLCBmbG9hdCApOworICAgICAgU0VUX09ORU9GX1ZBTFVFMShET1VCTEUsIGRvdWJsZSk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUxKEJPT0wgICwgYm9vbCAgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTEoRU5VTSAgLCBpbnQgICApOworI3VuZGVmIFNFVF9PTkVPRl9WQUxVRTEKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIFNldEFsbG9jYXRlZE1lc3NhZ2UobWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVsZWFzZU1lc3NhZ2UobWVzc2FnZTIsIGZpZWxkMiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQyKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgU2V0U3RyaW5nKG1lc3NhZ2UxLCBmaWVsZDIsIEdldFN0cmluZygqbWVzc2FnZTIsIGZpZWxkMikpOworICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgdHlwZTogIiA8PCBmaWVsZDItPmNwcF90eXBlKCk7CisgICAgfQorICB9IGVsc2UgeworICAgIENsZWFyT25lb2YobWVzc2FnZTEsIG9uZW9mX2Rlc2NyaXB0b3IpOworICB9CisKKyAgLy8gU2V0cyBtZXNzYWdlMidzIG9uZW9mIGZpZWxkIGZyb20gdGhlIHRlbXAgdmFyaWFibGUuCisgIGlmIChvbmVvZl9jYXNlMSA+IDApIHsKKyAgICBzd2l0Y2ggKGZpZWxkMS0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTRVRfT05FT0ZfVkFMVUUyKENQUFRZUEUsIFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTZXRGaWVsZDxUWVBFPihtZXNzYWdlMiwgZmllbGQxLCB0ZW1wXyMjVFlQRSk7ICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsKKworICAgICAgU0VUX09ORU9GX1ZBTFVFMihJTlQzMiAsIGludDMyICk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUyKElOVDY0ICwgaW50NjQgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTIoVUlOVDMyLCB1aW50MzIpOworICAgICAgU0VUX09ORU9GX1ZBTFVFMihVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUyKEZMT0FUICwgZmxvYXQgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTIoRE9VQkxFLCBkb3VibGUpOworICAgICAgU0VUX09ORU9GX1ZBTFVFMihCT09MICAsIGJvb2wgICk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUyKEVOVU0gICwgaW50ICAgKTsKKyN1bmRlZiBTRVRfT05FT0ZfVkFMVUUyCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBTZXRBbGxvY2F0ZWRNZXNzYWdlKG1lc3NhZ2UyLCB0ZW1wX21lc3NhZ2UsIGZpZWxkMSk7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIFNldFN0cmluZyhtZXNzYWdlMiwgZmllbGQxLCB0ZW1wX3N0cmluZyk7CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5pbXBsZW1lbnRlZCB0eXBlOiAiIDw8IGZpZWxkMS0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgQ2xlYXJPbmVvZihtZXNzYWdlMiwgb25lb2ZfZGVzY3JpcHRvcik7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlMSwKKyAgICBNZXNzYWdlKiBtZXNzYWdlMikgY29uc3QgeworICBpZiAobWVzc2FnZTEgPT0gbWVzc2FnZTIpIHJldHVybjsKKworICAvLyBUT0RPKGtlbnRvbik6ICBPdGhlciBSZWZsZWN0aW9uIG1ldGhvZHMgc2hvdWxkIHByb2JhYmx5IGNoZWNrIHRoaXMgdG9vLgorICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiRmlyc3QgYXJndW1lbnQgdG8gU3dhcCgpIChvZiB0eXBlIFwiIgorICAgIDw8IG1lc3NhZ2UxLT5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpCisgICAgPDwgIlwiKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoaXMgcmVmbGVjdGlvbiBvYmplY3QgKHdoaWNoIGlzIGZvciB0eXBlIFwiIgorICAgIDw8IGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikuICBOb3RlIHRoYXQgdGhlIGV4YWN0IHNhbWUgY2xhc3MgaXMgcmVxdWlyZWQ7IG5vdCBqdXN0IHRoZSBzYW1lICIKKyAgICAgICAiZGVzY3JpcHRvci4iOworICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTItPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiU2Vjb25kIGFyZ3VtZW50IHRvIFN3YXAoKSAob2YgdHlwZSBcIiIKKyAgICA8PCBtZXNzYWdlMi0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzIHJlZmxlY3Rpb24gb2JqZWN0ICh3aGljaCBpcyBmb3IgdHlwZSBcIiIKKyAgICA8PCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkKKyAgICA8PCAiXCIpLiAgTm90ZSB0aGF0IHRoZSBleGFjdCBzYW1lIGNsYXNzIGlzIHJlcXVpcmVkOyBub3QganVzdCB0aGUgc2FtZSAiCisgICAgICAgImRlc2NyaXB0b3IuIjsKKworICAvLyBDaGVjayB0aGF0IGJvdGggbWVzc2FnZXMgYXJlIGluIHRoZSBzYW1lIGFyZW5hIChvciBib3RoIG9uIHRoZSBoZWFwKS4gV2UKKyAgLy8gbmVlZCB0byBjb3B5IGFsbCBkYXRhIGlmIG5vdCwgZHVlIHRvIG93bmVyc2hpcCBzZW1hbnRpY3MuCisgIGlmIChHZXRBcmVuYShtZXNzYWdlMSkgIT0gR2V0QXJlbmEobWVzc2FnZTIpKSB7CisgICAgLy8gU2xvdyBjb3B5IHBhdGguCisgICAgLy8gVXNlIG91ciBhcmVuYSBhcyB0ZW1wIHNwYWNlLCBpZiBhdmFpbGFibGUuCisgICAgTWVzc2FnZSogdGVtcCA9IG1lc3NhZ2UxLT5OZXcoR2V0QXJlbmEobWVzc2FnZTEpKTsKKyAgICB0ZW1wLT5NZXJnZUZyb20oKm1lc3NhZ2UxKTsKKyAgICBtZXNzYWdlMS0+Q29weUZyb20oKm1lc3NhZ2UyKTsKKyAgICBtZXNzYWdlMi0+Q29weUZyb20oKnRlbXApOworICAgIGlmIChHZXRBcmVuYShtZXNzYWdlMSkgPT0gTlVMTCkgeworICAgICAgZGVsZXRlIHRlbXA7CisgICAgfQorICAgIHJldHVybjsKKyAgfQorCisgIGlmIChoYXNfYml0c19vZmZzZXRfICE9IC0xKSB7CisgICAgdWludDMyKiBoYXNfYml0czEgPSBNdXRhYmxlSGFzQml0cyhtZXNzYWdlMSk7CisgICAgdWludDMyKiBoYXNfYml0czIgPSBNdXRhYmxlSGFzQml0cyhtZXNzYWdlMik7CisgICAgaW50IGhhc19iaXRzX3NpemUgPSAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyAzMSkgLyAzMjsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFzX2JpdHNfc2l6ZTsgaSsrKSB7CisgICAgICBzdGQ6OnN3YXAoaGFzX2JpdHMxW2ldLCBoYXNfYml0czJbaV0pOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgaWYgKCFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBTd2FwRmllbGQobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZCk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBTd2FwT25lb2ZGaWVsZChtZXNzYWdlMSwgbWVzc2FnZTIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKTsKKyAgfQorCisgIGlmIChleHRlbnNpb25zX29mZnNldF8gIT0gLTEpIHsKKyAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UxKS0+U3dhcChNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UyKSk7CisgIH0KKworICBNdXRhYmxlVW5rbm93bkZpZWxkcyhtZXNzYWdlMSktPlN3YXAoTXV0YWJsZVVua25vd25GaWVsZHMobWVzc2FnZTIpKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcEZpZWxkcygKKyAgICBNZXNzYWdlKiBtZXNzYWdlMSwKKyAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcykgY29uc3QgeworICBpZiAobWVzc2FnZTEgPT0gbWVzc2FnZTIpIHJldHVybjsKKworICAvLyBUT0RPKGtlbnRvbik6ICBPdGhlciBSZWZsZWN0aW9uIG1ldGhvZHMgc2hvdWxkIHByb2JhYmx5IGNoZWNrIHRoaXMgdG9vLgorICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiRmlyc3QgYXJndW1lbnQgdG8gU3dhcEZpZWxkcygpIChvZiB0eXBlIFwiIgorICAgIDw8IG1lc3NhZ2UxLT5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpCisgICAgPDwgIlwiKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoaXMgcmVmbGVjdGlvbiBvYmplY3QgKHdoaWNoIGlzIGZvciB0eXBlIFwiIgorICAgIDw8IGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikuICBOb3RlIHRoYXQgdGhlIGV4YWN0IHNhbWUgY2xhc3MgaXMgcmVxdWlyZWQ7IG5vdCBqdXN0IHRoZSBzYW1lICIKKyAgICAgICAiZGVzY3JpcHRvci4iOworICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTItPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiU2Vjb25kIGFyZ3VtZW50IHRvIFN3YXBGaWVsZHMoKSAob2YgdHlwZSBcIiIKKyAgICA8PCBtZXNzYWdlMi0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzIHJlZmxlY3Rpb24gb2JqZWN0ICh3aGljaCBpcyBmb3IgdHlwZSBcIiIKKyAgICA8PCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkKKyAgICA8PCAiXCIpLiAgTm90ZSB0aGF0IHRoZSBleGFjdCBzYW1lIGNsYXNzIGlzIHJlcXVpcmVkOyBub3QganVzdCB0aGUgc2FtZSAiCisgICAgICAgImRlc2NyaXB0b3IuIjsKKworICBzdGQ6OnNldDxpbnQ+IHN3YXBwZWRfb25lb2Y7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworICAgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZTEpLT5Td2FwRXh0ZW5zaW9uKAorICAgICAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZTIpLAorICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgIGludCBvbmVvZl9pbmRleCA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCk7CisgICAgICAgIC8vIE9ubHkgc3dhcCB0aGUgb25lb2YgZmllbGQgb25jZS4KKyAgICAgICAgaWYgKHN3YXBwZWRfb25lb2YuZmluZChvbmVvZl9pbmRleCkgIT0gc3dhcHBlZF9vbmVvZi5lbmQoKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHN3YXBwZWRfb25lb2YuaW5zZXJ0KG9uZW9mX2luZGV4KTsKKyAgICAgICAgU3dhcE9uZW9mRmllbGQobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFN3YXAgaGFzIGJpdC4KKyAgICAgICAgU3dhcEJpdChtZXNzYWdlMSwgbWVzc2FnZTIsIGZpZWxkKTsKKyAgICAgICAgLy8gU3dhcCBmaWVsZC4KKyAgICAgICAgU3dhcEZpZWxkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2Jvb2wgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Okhhc0ZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShIYXNGaWVsZCk7CisgIFVTQUdFX0NIRUNLX1NJTkdVTEFSKEhhc0ZpZWxkKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5IYXMoZmllbGQtPm51bWJlcigpKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgcmV0dXJuIEhhc09uZW9mRmllbGQobWVzc2FnZSwgZmllbGQpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gSGFzQml0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICB9CisgIH0KK30KKworaW50IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpGaWVsZFNpemUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfTUVTU0FHRV9UWVBFKEZpZWxkU2l6ZSk7CisgIFVTQUdFX0NIRUNLX1JFUEVBVEVEKEZpZWxkU2l6ZSk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuRXh0ZW5zaW9uU2l6ZShmaWVsZC0+bnVtYmVyKCkpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjVVBQRVJDQVNFIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgcmV0dXJuIEdldFJhdzxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihtZXNzYWdlLCBmaWVsZCkuc2l6ZSgpCisKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQ2NCwgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGTE9BVCwgIGZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRU5VTSwgICAgaW50KTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgICAgIHJldHVybiBHZXRSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkuR2V0UmVwZWF0ZWRGaWVsZCgpLnNpemUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gR2V0UmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkuc2l6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIDA7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6Q2xlYXJGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShDbGVhckZpZWxkKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+Q2xlYXJFeHRlbnNpb24oZmllbGQtPm51bWJlcigpKTsKKyAgfSBlbHNlIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgQ2xlYXJPbmVvZkZpZWxkKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoSGFzQml0KCptZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgIENsZWFyQml0KG1lc3NhZ2UsIGZpZWxkKTsKKworICAgICAgLy8gV2UgbmVlZCB0byBzZXQgdGhlIGZpZWxkIGJhY2sgdG8gaXRzIGRlZmF1bHQgdmFsdWUuCisgICAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIENMRUFSX1RZUEUoQ1BQVFlQRSwgVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICpNdXRhYmxlUmF3PFRZUEU+KG1lc3NhZ2UsIGZpZWxkKSA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV8jI1RZUEUoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBDTEVBUl9UWVBFKElOVDMyICwgaW50MzIgKTsKKyAgICAgICAgQ0xFQVJfVFlQRShJTlQ2NCAsIGludDY0ICk7CisgICAgICAgIENMRUFSX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgICBDTEVBUl9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgICAgQ0xFQVJfVFlQRShGTE9BVCAsIGZsb2F0ICk7CisgICAgICAgIENMRUFSX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgICBDTEVBUl9UWVBFKEJPT0wgICwgYm9vbCAgKTsKKyN1bmRlZiBDTEVBUl9UWVBFCisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgICAqTXV0YWJsZVJhdzxpbnQ+KG1lc3NhZ2UsIGZpZWxkKSA9CisgICAgICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgICAgICAgTXV0YWJsZVJhdzxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLT5EZXN0cm95KGRlZmF1bHRfcHRyLAorICAgICAgICAgICAgICAgICAgR2V0QXJlbmEobWVzc2FnZSkpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgICgqTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpKS0+Q2xlYXIoKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0UgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkRmllbGQ8TE9XRVJDQVNFPiA+KG1lc3NhZ2UsIGZpZWxkKS0+Q2xlYXIoKTsgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggSU5UNjQsICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggRkxPQVQsICBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRSggIEJPT0wsICAgYm9vbCk7CisgICAgICBIQU5ETEVfVFlQRSggIEVOVU0sICAgIGludCk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+ID4obWVzc2FnZSwgZmllbGQpLT5DbGVhcigpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICBNdXRhYmxlUmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAgIC0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKQorICAgICAgICAgICAgICAtPkNsZWFyPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB3aGljaCBzdWJjbGFzcyBvZiBSZXBlYXRlZFB0ckZpZWxkQmFzZSB0aGUgdHlwZSBpcywKKyAgICAgICAgICAvLyBzbyB3ZSB1c2UgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgZGlyZWN0bHkuCisgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAgIC0+Q2xlYXI8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6UmVtb3ZlTGFzdCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfTUVTU0FHRV9UWVBFKFJlbW92ZUxhc3QpOworICBVU0FHRV9DSEVDS19SRVBFQVRFRChSZW1vdmVMYXN0KTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+UmVtb3ZlTGFzdChmaWVsZC0+bnVtYmVyKCkpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjVVBQRVJDQVNFIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihtZXNzYWdlLCBmaWVsZCktPlJlbW92ZUxhc3QoKTsgIFwKKyAgICAgICAgYnJlYWsKKworICAgICAgSEFORExFX1RZUEUoIElOVDMyLCAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgSEFORExFX1RZUEUoVUlOVDY0LCB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgSEFORExFX1RZUEUoIEZMT0FULCAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoICBCT09MLCAgIGJvb2wpOworICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgICBpbnQpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gPihtZXNzYWdlLCBmaWVsZCktPlJlbW92ZUxhc3QoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgICAgIE11dGFibGVSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpCisgICAgICAgICAgICAgIC0+UmVtb3ZlTGFzdDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgICAgLT5SZW1vdmVMYXN0PEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CisKK01lc3NhZ2UqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpSZWxlYXNlTGFzdCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKFJlbGVhc2VMYXN0LCBSRVBFQVRFRCwgTUVTU0FHRSk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxNZXNzYWdlKj4oCisgICAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlJlbGVhc2VMYXN0KGZpZWxkLT5udW1iZXIoKSkpOworICB9IGVsc2UgeworICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICByZXR1cm4gTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgIC0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKQorICAgICAgICAgIC0+UmVsZWFzZUxhc3Q8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAtPlJlbGVhc2VMYXN0PEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlN3YXBFbGVtZW50cygKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IGluZGV4MSwKKyAgICBpbnQgaW5kZXgyKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShTd2FwKTsKKyAgVVNBR0VfQ0hFQ0tfUkVQRUFURUQoU3dhcCk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlN3YXBFbGVtZW50cyhmaWVsZC0+bnVtYmVyKCksIGluZGV4MSwgaW5kZXgyKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI1VQUEVSQ0FTRSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIE11dGFibGVSYXc8UmVwZWF0ZWRGaWVsZDxMT1dFUkNBU0U+ID4obWVzc2FnZSwgZmllbGQpICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrCisKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQ2NCwgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGTE9BVCwgIGZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRU5VTSwgICAgaW50KTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgICAgIE11dGFibGVSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpCisgICAgICAgICAgICAgIC0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAgIC0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHsKKy8vIENvbXBhcmlzb24gZnVuY3RvciBmb3Igc29ydGluZyBGaWVsZERlc2NyaXB0b3JzIGJ5IGZpZWxkIG51bWJlci4KK3N0cnVjdCBGaWVsZE51bWJlclNvcnRlciB7CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGxlZnQsCisgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJpZ2h0KSBjb25zdCB7CisgICAgcmV0dXJuIGxlZnQtPm51bWJlcigpIDwgcmlnaHQtPm51bWJlcigpOworICB9Cit9OworfSAgLy8gbmFtZXNwYWNlCisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Okxpc3RGaWVsZHMoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dHB1dCkgY29uc3QgeworICBvdXRwdXQtPmNsZWFyKCk7CisKKyAgLy8gT3B0aW1pemF0aW9uOiAgVGhlIGRlZmF1bHQgaW5zdGFuY2UgbmV2ZXIgaGFzIGFueSBmaWVsZHMgc2V0LgorICBpZiAoJm1lc3NhZ2UgPT0gZGVmYXVsdF9pbnN0YW5jZV8pIHJldHVybjsKKworICBvdXRwdXQtPnJlc2VydmUoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgaWYgKEZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZCkgPiAwKSB7CisgICAgICAgIG91dHB1dC0+cHVzaF9iYWNrKGZpZWxkKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgaWYgKEhhc09uZW9mRmllbGQobWVzc2FnZSwgZmllbGQpKSB7CisgICAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soZmllbGQpOworICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKEhhc0JpdChtZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soZmllbGQpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChleHRlbnNpb25zX29mZnNldF8gIT0gLTEpIHsKKyAgICBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuQXBwZW5kVG9MaXN0KGRlc2NyaXB0b3JfLCBkZXNjcmlwdG9yX3Bvb2xfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0KTsKKyAgfQorCisgIC8vIExpc3RGaWVsZHMoKSBtdXN0IHNvcnQgb3V0cHV0IGJ5IGZpZWxkIG51bWJlci4KKyAgc3RkOjpzb3J0KG91dHB1dC0+YmVnaW4oKSwgb3V0cHV0LT5lbmQoKSwgRmllbGROdW1iZXJTb3J0ZXIoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI3VuZGVmIERFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTCisjZGVmaW5lIERFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKFRZUEVOQU1FLCBUWVBFLCBQQVNTVFlQRSwgQ1BQVFlQRSkgICAgICAgIFwKKyAgUEFTU1RZUEUgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeyAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfQUxMKEdldCMjVFlQRU5BTUUsIFNJTkdVTEFSLCBDUFBUWVBFKTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPmRlZmF1bHRfdmFsdWVfIyNQQVNTVFlQRSgpKTsgICAgICAgICAgICAgICAgIFwKKyAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIEdldEZpZWxkPFRZUEU+KG1lc3NhZ2UsIGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgUEFTU1RZUEUgdmFsdWUpIGNvbnN0IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfQUxMKFNldCMjVFlQRU5BTUUsIFNJTkdVTEFSLCBDUFBUWVBFKTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlNldCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSwgdmFsdWUsIGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgU2V0RmllbGQ8VFlQRT4obWVzc2FnZSwgZmllbGQsIHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFBBU1NUWVBFIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfQUxMKEdldFJlcGVhdGVkIyNUWVBFTkFNRSwgUkVQRUFURUQsIENQUFRZUEUpOyAgICAgICAgICAgICAgIFwKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRSZXBlYXRlZCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICBcCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgaW5kZXgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIEdldFJlcGVhdGVkRmllbGQ8VFlQRT4obWVzc2FnZSwgZmllbGQsIGluZGV4KTsgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldFJlcGVhdGVkIyNUWVBFTkFNRSggICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgaW50IGluZGV4LCBQQVNTVFlQRSB2YWx1ZSkgY29uc3QgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfQUxMKFNldFJlcGVhdGVkIyNUWVBFTkFNRSwgUkVQRUFURUQsIENQUFRZUEUpOyAgICAgICAgICAgICAgIFwKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+U2V0UmVwZWF0ZWQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgaW5kZXgsIHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgU2V0UmVwZWF0ZWRGaWVsZDxUWVBFPihtZXNzYWdlLCBmaWVsZCwgaW5kZXgsIHZhbHVlKTsgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkFkZCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgUEFTU1RZUEUgdmFsdWUpIGNvbnN0IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfQUxMKEFkZCMjVFlQRU5BTUUsIFJFUEVBVEVELCBDUFBUWVBFKTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+QWRkIyNUWVBFTkFNRSggICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSwgZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKSwgdmFsdWUsICAgIFwKKyAgICAgICAgZmllbGQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBBZGRGaWVsZDxUWVBFPihtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKEludDMyICwgaW50MzIgLCBpbnQzMiAsIElOVDMyICkKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKEludDY0ICwgaW50NjQgLCBpbnQ2NCAsIElOVDY0ICkKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKFVJbnQzMiwgdWludDMyLCB1aW50MzIsIFVJTlQzMikKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKFVJbnQ2NCwgdWludDY0LCB1aW50NjQsIFVJTlQ2NCkKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKEZsb2F0ICwgZmxvYXQgLCBmbG9hdCAsIEZMT0FUICkKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKERvdWJsZSwgZG91YmxlLCBkb3VibGUsIERPVUJMRSkKK0RFRklORV9QUklNSVRJVkVfQUNDRVNTT1JTKEJvb2wgICwgYm9vbCAgLCBib29sICAsIEJPT0wgICkKKyN1bmRlZiBERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cmluZyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0U3RyaW5nKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKEdldFN0cmluZywgU0lOR1VMQVIsIFNUUklORyk7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLkdldFN0cmluZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgcmV0dXJuIEdldEZpZWxkPEFyZW5hU3RyaW5nUHRyPihtZXNzYWdlLCBmaWVsZCkuR2V0KGRlZmF1bHRfcHRyKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICByZXR1cm4gR2V0RW1wdHlTdHJpbmcoKTsgIC8vIE1ha2UgY29tcGlsZXIgaGFwcHkuCisgIH0KK30KKworY29uc3Qgc3RyaW5nJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0U3RyaW5nUmVmZXJlbmNlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgc3RyaW5nKiBzY3JhdGNoKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChHZXRTdHJpbmdSZWZlcmVuY2UsIFNJTkdVTEFSLCBTVFJJTkcpOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRTdHJpbmcoZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOiB7CisgICAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF9wdHIgPQorICAgICAgICAgICAgJkRlZmF1bHRSYXc8QXJlbmFTdHJpbmdQdHI+KGZpZWxkKS5HZXQoTlVMTCk7CisgICAgICAgIHJldHVybiBHZXRGaWVsZDxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLkdldChkZWZhdWx0X3B0cik7CisgICAgICB9CisgICAgfQorCisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIEdldEVtcHR5U3RyaW5nKCk7ICAvLyBNYWtlIGNvbXBpbGVyIGhhcHB5LgorICB9Cit9CisKKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0U3RyaW5nKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoU2V0U3RyaW5nLCBTSU5HVUxBUiwgU1RSSU5HKTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5TZXRTdHJpbmcoZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPnR5cGUoKSwgdmFsdWUsIGZpZWxkKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOiB7CisgICAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF9wdHIgPQorICAgICAgICAgICAgJkRlZmF1bHRSYXc8QXJlbmFTdHJpbmdQdHI+KGZpZWxkKS5HZXQoTlVMTCk7CisgICAgICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICYmICFIYXNPbmVvZkZpZWxkKCptZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgICAgICBDbGVhck9uZW9mKG1lc3NhZ2UsIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpOworICAgICAgICAgIE11dGFibGVGaWVsZDxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLT5VbnNhZmVTZXREZWZhdWx0KAorICAgICAgICAgICAgICBkZWZhdWx0X3B0cik7CisgICAgICAgIH0KKyAgICAgICAgTXV0YWJsZUZpZWxkPEFyZW5hU3RyaW5nUHRyPihtZXNzYWdlLCBmaWVsZCktPlNldChkZWZhdWx0X3B0ciwKKyAgICAgICAgICAgIHZhbHVlLCBHZXRBcmVuYShtZXNzYWdlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisKK3N0cmluZyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRTdHJpbmcoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChHZXRSZXBlYXRlZFN0cmluZywgUkVQRUFURUQsIFNUUklORyk7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLkdldFJlcGVhdGVkU3RyaW5nKGZpZWxkLT5udW1iZXIoKSwgaW5kZXgpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgIHJldHVybiBHZXRSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4obWVzc2FnZSwgZmllbGQsIGluZGV4KTsKKyAgICB9CisKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICByZXR1cm4gR2V0RW1wdHlTdHJpbmcoKTsgIC8vIE1ha2UgY29tcGlsZXIgaGFwcHkuCisgIH0KK30KKworY29uc3Qgc3RyaW5nJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgaW5kZXgsIHN0cmluZyogc2NyYXRjaCkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoR2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UsIFJFUEVBVEVELCBTVFJJTkcpOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRSZXBlYXRlZFN0cmluZyhmaWVsZC0+bnVtYmVyKCksIGluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICByZXR1cm4gR2V0UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KG1lc3NhZ2UsIGZpZWxkLCBpbmRleCk7CisgICAgfQorCisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIEdldEVtcHR5U3RyaW5nKCk7ICAvLyBNYWtlIGNvbXBpbGVyIGhhcHB5LgorICB9Cit9CisKKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0UmVwZWF0ZWRTdHJpbmcoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgaW5kZXgsIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKFNldFJlcGVhdGVkU3RyaW5nLCBSRVBFQVRFRCwgU1RSSU5HKTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlNldFJlcGVhdGVkU3RyaW5nKAorICAgICAgZmllbGQtPm51bWJlcigpLCBpbmRleCwgdmFsdWUpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICpNdXRhYmxlUmVwZWF0ZWRGaWVsZDxzdHJpbmc+KG1lc3NhZ2UsIGZpZWxkLCBpbmRleCkgPSB2YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CisKKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkU3RyaW5nKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoQWRkU3RyaW5nLCBSRVBFQVRFRCwgU1RSSU5HKTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPkFkZFN0cmluZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT50eXBlKCksIHZhbHVlLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgKkFkZEZpZWxkPHN0cmluZz4obWVzc2FnZSwgZmllbGQpID0gdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworaW5saW5lIGJvb2wgQ3JlYXRlVW5rbm93bkVudW1WYWx1ZXMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0RW51bSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIC8vIFVzYWdlIGNoZWNrZWQgYnkgR2V0RW51bVZhbHVlLgorICBpbnQgdmFsdWUgPSBHZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQpOworICByZXR1cm4gZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKHZhbHVlKTsKK30KKworaW50IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRFbnVtVmFsdWUoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoR2V0RW51bVZhbHVlLCBTSU5HVUxBUiwgRU5VTSk7CisKKyAgaW50MzIgdmFsdWU7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICB2YWx1ZSA9IEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRFbnVtKAorICAgICAgZmllbGQtPm51bWJlcigpLCBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpKTsKKyAgfSBlbHNlIHsKKyAgICB2YWx1ZSA9IEdldEZpZWxkPGludD4obWVzc2FnZSwgZmllbGQpOworICB9CisgIHJldHVybiB2YWx1ZTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0RW51bSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCB7CisgIC8vIFVzYWdlIGNoZWNrZWQgYnkgU2V0RW51bVZhbHVlLgorICBVU0FHRV9DSEVDS19FTlVNX1ZBTFVFKFNldEVudW0pOworICBTZXRFbnVtVmFsdWVJbnRlcm5hbChtZXNzYWdlLCBmaWVsZCwgdmFsdWUtPm51bWJlcigpKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0RW51bVZhbHVlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChTZXRFbnVtVmFsdWUsIFNJTkdVTEFSLCBFTlVNKTsKKyAgaWYgKCFDcmVhdGVVbmtub3duRW51bVZhbHVlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIENoZWNrIHRoYXQgdGhlIHZhbHVlIGlzIHZhbGlkIGlmIHdlIGRvbid0IHN1cHBvcnQgZGlyZWN0IHN0b3JhZ2Ugb2YKKyAgICAvLyB1bmtub3duIGVudW0gdmFsdWVzLgorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlX2Rlc2MgPQorICAgICAgICBmaWVsZC0+ZW51bV90eXBlKCktPkZpbmRWYWx1ZUJ5TnVtYmVyKHZhbHVlKTsKKyAgICBpZiAodmFsdWVfZGVzYyA9PSBOVUxMKSB7CisgICAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIlNldEVudW1WYWx1ZSBhY2NlcHRzIG9ubHkgdmFsaWQgaW50ZWdlciB2YWx1ZXM6IHZhbHVlICIKKyAgICAgICAgICAgICAgICAgIDw8IHZhbHVlIDw8ICIgdW5leHBlY3RlZCBmb3IgZmllbGQgIiA8PCBmaWVsZC0+ZnVsbF9uYW1lKCk7CisgICAgICAvLyBJbiBwcm9kdWN0aW9uIGJ1aWxkcywgREZBVEFMIHdpbGwgbm90IHRlcm1pbmF0ZSB0aGUgcHJvZ3JhbSwgc28gd2UgaGF2ZQorICAgICAgLy8gdG8gZG8gc29tZXRoaW5nIHJlYXNvbmFibGU6IGp1c3Qgc2V0IHRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpOworICAgIH0KKyAgfQorICBTZXRFbnVtVmFsdWVJbnRlcm5hbChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOworfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRFbnVtVmFsdWVJbnRlcm5hbCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGludCB2YWx1ZSkgY29uc3QgeworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+U2V0RW51bShmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgZmllbGQpOworICB9IGVsc2UgeworICAgIFNldEZpZWxkPGludD4obWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgfQorfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRFbnVtKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeworICAvLyBVc2FnZSBjaGVja2VkIGJ5IEdldFJlcGVhdGVkRW51bVZhbHVlLgorICBpbnQgdmFsdWUgPSBHZXRSZXBlYXRlZEVudW1WYWx1ZShtZXNzYWdlLCBmaWVsZCwgaW5kZXgpOworICByZXR1cm4gZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKHZhbHVlKTsKK30KKworaW50IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZEVudW1WYWx1ZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKEdldFJlcGVhdGVkRW51bVZhbHVlLCBSRVBFQVRFRCwgRU5VTSk7CisKKyAgaW50IHZhbHVlOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgdmFsdWUgPSBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0UmVwZWF0ZWRFbnVtKGZpZWxkLT5udW1iZXIoKSwgaW5kZXgpOworICB9IGVsc2UgeworICAgIHZhbHVlID0gR2V0UmVwZWF0ZWRGaWVsZDxpbnQ+KG1lc3NhZ2UsIGZpZWxkLCBpbmRleCk7CisgIH0KKyAgcmV0dXJuIHZhbHVlOworfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRSZXBlYXRlZEVudW0oCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgsCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIGNvbnN0IHsKKyAgLy8gVXNhZ2UgY2hlY2tlZCBieSBTZXRSZXBlYXRlZEVudW1WYWx1ZS4KKyAgVVNBR0VfQ0hFQ0tfRU5VTV9WQUxVRShTZXRSZXBlYXRlZEVudW0pOworICBTZXRSZXBlYXRlZEVudW1WYWx1ZUludGVybmFsKG1lc3NhZ2UsIGZpZWxkLCBpbmRleCwgdmFsdWUtPm51bWJlcigpKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0UmVwZWF0ZWRFbnVtVmFsdWUoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgsCisgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChTZXRSZXBlYXRlZEVudW0sIFJFUEVBVEVELCBFTlVNKTsKKyAgaWYgKCFDcmVhdGVVbmtub3duRW51bVZhbHVlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIENoZWNrIHRoYXQgdGhlIHZhbHVlIGlzIHZhbGlkIGlmIHdlIGRvbid0IHN1cHBvcnQgZGlyZWN0IHN0b3JhZ2Ugb2YKKyAgICAvLyB1bmtub3duIGVudW0gdmFsdWVzLgorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlX2Rlc2MgPQorICAgICAgICBmaWVsZC0+ZW51bV90eXBlKCktPkZpbmRWYWx1ZUJ5TnVtYmVyKHZhbHVlKTsKKyAgICBpZiAodmFsdWVfZGVzYyA9PSBOVUxMKSB7CisgICAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIlNldFJlcGVhdGVkRW51bVZhbHVlIGFjY2VwdHMgb25seSB2YWxpZCBpbnRlZ2VyIHZhbHVlczogIgorICAgICAgICAgICAgICAgICAgPDwgInZhbHVlICIgPDwgdmFsdWUgPDwgIiB1bmV4cGVjdGVkIGZvciBmaWVsZCAiCisgICAgICAgICAgICAgICAgICA8PCBmaWVsZC0+ZnVsbF9uYW1lKCk7CisgICAgICAvLyBJbiBwcm9kdWN0aW9uIGJ1aWxkcywgREZBVEFMIHdpbGwgbm90IHRlcm1pbmF0ZSB0aGUgcHJvZ3JhbSwgc28gd2UgaGF2ZQorICAgICAgLy8gdG8gZG8gc29tZXRoaW5nIHJlYXNvbmFibGU6IGp1c3Qgc2V0IHRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpOworICAgIH0KKyAgfQorICBTZXRSZXBlYXRlZEVudW1WYWx1ZUludGVybmFsKG1lc3NhZ2UsIGZpZWxkLCBpbmRleCwgdmFsdWUpOworfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRSZXBlYXRlZEVudW1WYWx1ZUludGVybmFsKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgIGludCB2YWx1ZSkgY29uc3QgeworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+U2V0UmVwZWF0ZWRFbnVtKAorICAgICAgZmllbGQtPm51bWJlcigpLCBpbmRleCwgdmFsdWUpOworICB9IGVsc2UgeworICAgIFNldFJlcGVhdGVkRmllbGQ8aW50PihtZXNzYWdlLCBmaWVsZCwgaW5kZXgsIHZhbHVlKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGRFbnVtKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIGNvbnN0IHsKKyAgLy8gVXNhZ2UgY2hlY2tlZCBieSBBZGRFbnVtVmFsdWUuCisgIFVTQUdFX0NIRUNLX0VOVU1fVkFMVUUoQWRkRW51bSk7CisgIEFkZEVudW1WYWx1ZUludGVybmFsKG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZS0+bnVtYmVyKCkpOworfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGRFbnVtVmFsdWUoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgdmFsdWUpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKEFkZEVudW0sIFJFUEVBVEVELCBFTlVNKTsKKyAgaWYgKCFDcmVhdGVVbmtub3duRW51bVZhbHVlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIENoZWNrIHRoYXQgdGhlIHZhbHVlIGlzIHZhbGlkIGlmIHdlIGRvbid0IHN1cHBvcnQgZGlyZWN0IHN0b3JhZ2Ugb2YKKyAgICAvLyB1bmtub3duIGVudW0gdmFsdWVzLgorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlX2Rlc2MgPQorICAgICAgICBmaWVsZC0+ZW51bV90eXBlKCktPkZpbmRWYWx1ZUJ5TnVtYmVyKHZhbHVlKTsKKyAgICBpZiAodmFsdWVfZGVzYyA9PSBOVUxMKSB7CisgICAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkFkZEVudW1WYWx1ZSBhY2NlcHRzIG9ubHkgdmFsaWQgaW50ZWdlciB2YWx1ZXM6IHZhbHVlICIKKyAgICAgICAgICAgICAgICAgIDw8IHZhbHVlIDw8ICIgdW5leHBlY3RlZCBmb3IgZmllbGQgIiA8PCBmaWVsZC0+ZnVsbF9uYW1lKCk7CisgICAgICAvLyBJbiBwcm9kdWN0aW9uIGJ1aWxkcywgREZBVEFMIHdpbGwgbm90IHRlcm1pbmF0ZSB0aGUgcHJvZ3JhbSwgc28gd2UgaGF2ZQorICAgICAgLy8gdG8gZG8gc29tZXRoaW5nIHJlYXNvbmFibGU6IGp1c3Qgc2V0IHRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpOworICAgIH0KKyAgfQorICBBZGRFbnVtVmFsdWVJbnRlcm5hbChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOworfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGRFbnVtVmFsdWVJbnRlcm5hbCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGludCB2YWx1ZSkgY29uc3QgeworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+QWRkRW51bShmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsIGZpZWxkKTsKKyAgfSBlbHNlIHsKKyAgICBBZGRGaWVsZDxpbnQ+KG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZSk7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCBNZXNzYWdlJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0TWVzc2FnZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChHZXRNZXNzYWdlLCBTSU5HVUxBUiwgTUVTU0FHRSk7CisKKyAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgZmFjdG9yeSA9IG1lc3NhZ2VfZmFjdG9yeV87CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBNZXNzYWdlJj4oCisgICAgICAgIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRNZXNzYWdlKAorICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCBmYWN0b3J5KSk7CisgIH0gZWxzZSB7CisgICAgY29uc3QgTWVzc2FnZSogcmVzdWx0OworICAgIHJlc3VsdCA9IEdldFJhdzxjb25zdCBNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgcmVzdWx0ID0gRGVmYXVsdFJhdzxjb25zdCBNZXNzYWdlKj4oZmllbGQpOworICAgIH0KKyAgICByZXR1cm4gKnJlc3VsdDsKKyAgfQorfQorCitNZXNzYWdlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZU1lc3NhZ2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoTXV0YWJsZU1lc3NhZ2UsIFNJTkdVTEFSLCBNRVNTQUdFKTsKKworICBpZiAoZmFjdG9yeSA9PSBOVUxMKSBmYWN0b3J5ID0gbWVzc2FnZV9mYWN0b3J5XzsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PE1lc3NhZ2UqPigKKyAgICAgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+TXV0YWJsZU1lc3NhZ2UoZmllbGQsIGZhY3RvcnkpKTsKKyAgfSBlbHNlIHsKKyAgICBNZXNzYWdlKiByZXN1bHQ7CisgICAgTWVzc2FnZSoqIHJlc3VsdF9ob2xkZXIgPSBNdXRhYmxlUmF3PE1lc3NhZ2UqPihtZXNzYWdlLCBmaWVsZCk7CisKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgaWYgKCFIYXNPbmVvZkZpZWxkKCptZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgICAgQ2xlYXJPbmVvZihtZXNzYWdlLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgICAgICAgcmVzdWx0X2hvbGRlciA9IE11dGFibGVGaWVsZDxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpOworICAgICAgICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X21lc3NhZ2UgPSBEZWZhdWx0UmF3PGNvbnN0IE1lc3NhZ2UqPihmaWVsZCk7CisgICAgICAgICpyZXN1bHRfaG9sZGVyID0gZGVmYXVsdF9tZXNzYWdlLT5OZXcobWVzc2FnZS0+R2V0QXJlbmEoKSk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIFNldEJpdChtZXNzYWdlLCBmaWVsZCk7CisgICAgfQorCisgICAgaWYgKCpyZXN1bHRfaG9sZGVyID09IE5VTEwpIHsKKyAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfbWVzc2FnZSA9IERlZmF1bHRSYXc8Y29uc3QgTWVzc2FnZSo+KGZpZWxkKTsKKyAgICAgICpyZXN1bHRfaG9sZGVyID0gZGVmYXVsdF9tZXNzYWdlLT5OZXcobWVzc2FnZS0+R2V0QXJlbmEoKSk7CisgICAgfQorICAgIHJlc3VsdCA9ICpyZXN1bHRfaG9sZGVyOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6VW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWRNZXNzYWdlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoU2V0QWxsb2NhdGVkTWVzc2FnZSwgU0lOR1VMQVIsIE1FU1NBR0UpOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5TZXRBbGxvY2F0ZWRNZXNzYWdlKAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCksIGZpZWxkLCBzdWJfbWVzc2FnZSk7CisgIH0gZWxzZSB7CisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGlmIChzdWJfbWVzc2FnZSA9PSBOVUxMKSB7CisgICAgICAgIENsZWFyT25lb2YobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgICAgQ2xlYXJPbmVvZihtZXNzYWdlLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgICAgICAgKk11dGFibGVSYXc8TWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKSA9IHN1Yl9tZXNzYWdlOworICAgICAgU2V0T25lb2ZDYXNlKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoc3ViX21lc3NhZ2UgPT0gTlVMTCkgeworICAgICAgQ2xlYXJCaXQobWVzc2FnZSwgZmllbGQpOworICAgIH0gZWxzZSB7CisgICAgICBTZXRCaXQobWVzc2FnZSwgZmllbGQpOworICAgIH0KKyAgICBNZXNzYWdlKiogc3ViX21lc3NhZ2VfaG9sZGVyID0gTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpOworICAgIGlmIChHZXRBcmVuYShtZXNzYWdlKSA9PSBOVUxMKSB7CisgICAgICBkZWxldGUgKnN1Yl9tZXNzYWdlX2hvbGRlcjsKKyAgICB9CisgICAgKnN1Yl9tZXNzYWdlX2hvbGRlciA9IHN1Yl9tZXNzYWdlOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldEFsbG9jYXRlZE1lc3NhZ2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIC8vIElmIG1lc3NhZ2UgYW5kIHN1Yi1tZXNzYWdlIGFyZSBpbiBkaWZmZXJlbnQgbWVtb3J5IG93bmVyc2hpcCBkb21haW5zCisgIC8vIChkaWZmZXJlbnQgYXJlbmFzLCBvciBvbmUgaXMgb24gaGVhcCBhbmQgb25lIGlzIG5vdCksIHRoZW4gd2UgbWF5IG5lZWQgdG8KKyAgLy8gZG8gYSBjb3B5LgorICBpZiAoc3ViX21lc3NhZ2UgIT0gTlVMTCAmJgorICAgICAgc3ViX21lc3NhZ2UtPkdldEFyZW5hKCkgIT0gbWVzc2FnZS0+R2V0QXJlbmEoKSkgeworICAgIGlmIChzdWJfbWVzc2FnZS0+R2V0QXJlbmEoKSA9PSBOVUxMICYmIG1lc3NhZ2UtPkdldEFyZW5hKCkgIT0gTlVMTCkgeworICAgICAgLy8gQ2FzZSAxOiBwYXJlbnQgaXMgb24gYW4gYXJlbmEgYW5kIGNoaWxkIGlzIGhlYXAtYWxsb2NhdGVkLiBXZSBjYW4gYWRkCisgICAgICAvLyB0aGUgY2hpbGQgdG8gdGhlIGFyZW5hJ3MgT3duKCkgbGlzdCB0byBmcmVlIG9uIGFyZW5hIGRlc3RydWN0aW9uLCB0aGVuCisgICAgICAvLyBzZXQgb3VyIHBvaW50ZXIuCisgICAgICBtZXNzYWdlLT5HZXRBcmVuYSgpLT5Pd24oc3ViX21lc3NhZ2UpOworICAgICAgVW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWRNZXNzYWdlKG1lc3NhZ2UsIHN1Yl9tZXNzYWdlLCBmaWVsZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIENhc2UgMjogYWxsIG90aGVyIGNhc2VzLiBXZSBuZWVkIHRvIG1ha2UgYSBjb3B5LiBNdXRhYmxlTWVzc2FnZSgpIHdpbGwKKyAgICAgIC8vIGVpdGhlciBnZXQgdGhlIGV4aXN0aW5nIG1lc3NhZ2Ugb2JqZWN0LCBvciBpbnN0YW50aWF0ZSBhIG5ldyBvbmUgYXMKKyAgICAgIC8vIGFwcHJvcHJpYXRlIHcuci50LiBvdXIgYXJlbmEuCisgICAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZV9jb3B5ID0gTXV0YWJsZU1lc3NhZ2UobWVzc2FnZSwgZmllbGQpOworICAgICAgc3ViX21lc3NhZ2VfY29weS0+Q29weUZyb20oKnN1Yl9tZXNzYWdlKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gU2FtZSBtZW1vcnkgb3duZXJzaGlwIGRvbWFpbnMuCisgICAgVW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWRNZXNzYWdlKG1lc3NhZ2UsIHN1Yl9tZXNzYWdlLCBmaWVsZCk7CisgIH0KK30KKworTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlVuc2FmZUFyZW5hUmVsZWFzZU1lc3NhZ2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChSZWxlYXNlTWVzc2FnZSwgU0lOR1VMQVIsIE1FU1NBR0UpOworCisgIGlmIChmYWN0b3J5ID09IE5VTEwpIGZhY3RvcnkgPSBtZXNzYWdlX2ZhY3RvcnlfOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8TWVzc2FnZSo+KAorICAgICAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5SZWxlYXNlTWVzc2FnZShmaWVsZCwgZmFjdG9yeSkpOworICB9IGVsc2UgeworICAgIENsZWFyQml0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgaWYgKEhhc09uZW9mRmllbGQoKm1lc3NhZ2UsIGZpZWxkKSkgeworICAgICAgICAqTXV0YWJsZU9uZW9mQ2FzZShtZXNzYWdlLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSA9IDA7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICB9CisgICAgTWVzc2FnZSoqIHJlc3VsdCA9IE11dGFibGVSYXc8TWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBNZXNzYWdlKiByZXQgPSAqcmVzdWx0OworICAgICpyZXN1bHQgPSBOVUxMOworICAgIHJldHVybiByZXQ7CisgIH0KK30KKworTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlJlbGVhc2VNZXNzYWdlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3QgeworICBNZXNzYWdlKiByZWxlYXNlZCA9IFVuc2FmZUFyZW5hUmVsZWFzZU1lc3NhZ2UobWVzc2FnZSwgZmllbGQsIGZhY3RvcnkpOworICBpZiAoR2V0QXJlbmEobWVzc2FnZSkgIT0gTlVMTCAmJiByZWxlYXNlZCAhPSBOVUxMKSB7CisgICAgTWVzc2FnZSogY29weV9mcm9tX2FyZW5hID0gcmVsZWFzZWQtPk5ldygpOworICAgIGNvcHlfZnJvbV9hcmVuYS0+Q29weUZyb20oKnJlbGVhc2VkKTsKKyAgICByZWxlYXNlZCA9IGNvcHlfZnJvbV9hcmVuYTsKKyAgfQorICByZXR1cm4gcmVsZWFzZWQ7Cit9CisKK2NvbnN0IE1lc3NhZ2UmIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChHZXRSZXBlYXRlZE1lc3NhZ2UsIFJFUEVBVEVELCBNRVNTQUdFKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbnN0IE1lc3NhZ2UmPigKKyAgICAgICAgR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLkdldFJlcGVhdGVkTWVzc2FnZShmaWVsZC0+bnVtYmVyKCksIGluZGV4KSk7CisgIH0gZWxzZSB7CisgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgIHJldHVybiBHZXRSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAuR2V0UmVwZWF0ZWRGaWVsZCgpCisgICAgICAgICAgLkdldDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPihpbmRleCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBHZXRSYXc8UmVwZWF0ZWRQdHJGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgIC5HZXQ8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oaW5kZXgpOworICAgIH0KKyAgfQorfQorCitNZXNzYWdlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZVJlcGVhdGVkTWVzc2FnZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKE11dGFibGVSZXBlYXRlZE1lc3NhZ2UsIFJFUEVBVEVELCBNRVNTQUdFKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PE1lc3NhZ2UqPigKKyAgICAgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZSgKKyAgICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGluZGV4KSk7CisgIH0gZWxzZSB7CisgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgIHJldHVybiBNdXRhYmxlUmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpCisgICAgICAgICAgLT5NdXRhYmxlPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KGluZGV4KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAtPk11dGFibGU8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oaW5kZXgpOworICAgIH0KKyAgfQorfQorCitNZXNzYWdlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkTWVzc2FnZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChBZGRNZXNzYWdlLCBSRVBFQVRFRCwgTUVTU0FHRSk7CisKKyAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgZmFjdG9yeSA9IG1lc3NhZ2VfZmFjdG9yeV87CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxNZXNzYWdlKj4oCisgICAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPkFkZE1lc3NhZ2UoZmllbGQsIGZhY3RvcnkpKTsKKyAgfSBlbHNlIHsKKyAgICBNZXNzYWdlKiByZXN1bHQgPSBOVUxMOworCisgICAgLy8gV2UgY2FuJ3QgdXNlIEFkZEZpZWxkPE1lc3NhZ2U+KCkgYmVjYXVzZSBSZXBlYXRlZFB0ckZpZWxkQmFzZSBkb2Vzbid0CisgICAgLy8ga25vdyBob3cgdG8gYWxsb2NhdGUgb25lLgorICAgIFJlcGVhdGVkUHRyRmllbGRCYXNlKiByZXBlYXRlZCA9IE5VTEw7CisgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgIHJlcGVhdGVkID0KKyAgICAgICAgICBNdXRhYmxlUmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpOworICAgIH0gZWxzZSB7CisgICAgICByZXBlYXRlZCA9IE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICB9CisgICAgcmVzdWx0ID0gcmVwZWF0ZWQtPkFkZEZyb21DbGVhcmVkPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAvLyBXZSBtdXN0IGFsbG9jYXRlIGEgbmV3IG9iamVjdC4KKyAgICAgIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZTsKKyAgICAgIGlmIChyZXBlYXRlZC0+c2l6ZSgpID09IDApIHsKKyAgICAgICAgcHJvdG90eXBlID0gZmFjdG9yeS0+R2V0UHJvdG90eXBlKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcm90b3R5cGUgPSAmcmVwZWF0ZWQtPkdldDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigwKTsKKyAgICAgIH0KKyAgICAgIHJlc3VsdCA9IHByb3RvdHlwZS0+TmV3KG1lc3NhZ2UtPkdldEFyZW5hKCkpOworICAgICAgLy8gV2UgY2FuIGd1YXJhbnRlZSBoZXJlIHRoYXQgcmVwZWF0ZWQgYW5kIHJlc3VsdCBhcmUgZWl0aGVyIGJvdGggaGVhcAorICAgICAgLy8gYWxsb2NhdGVkIG9yIGFyZW5hIG93bmVkLiBTbyBpdCBpcyBzYWZlIHRvIGNhbGwgdGhlIHVuc2FmZSB2ZXJzaW9uCisgICAgICAvLyBvZiBBZGRBbGxvY2F0ZWQuCisgICAgICByZXBlYXRlZC0+VW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQ8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4ocmVzdWx0KTsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKK3ZvaWQqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHB0eXBlLAorICAgIGludCBjdHlwZSwgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3QgeworICBVU0FHRV9DSEVDS19SRVBFQVRFRCgiTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQiKTsKKyAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpICE9IGNwcHR5cGUpCisgICAgUmVwb3J0UmVmbGVjdGlvblVzYWdlVHlwZUVycm9yKGRlc2NyaXB0b3JfLAorICAgICAgICBmaWVsZCwgIk11dGFibGVSYXdSZXBlYXRlZEZpZWxkIiwgY3BwdHlwZSk7CisgIGlmIChjdHlwZSA+PSAwKQorICAgIEdPT0dMRV9DSEVDS19FUShmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCksIGN0eXBlKSA8PCAic3VidHlwZSBtaXNtYXRjaCI7CisgIGlmIChkZXNjICE9IE5VTEwpCisgICAgR09PR0xFX0NIRUNLX0VRKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgZGVzYykgPDwgIndyb25nIHN1Ym1lc3NhZ2UgdHlwZSI7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSwgZmllbGQtPmlzX3BhY2tlZCgpLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgLy8gVHJpZ2dlciB0cmFuc2Zvcm0gZm9yIE1hcEZpZWxkCisgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgIHJldHVybiByZWludGVycHJldF9jYXN0PE1hcEZpZWxkQmFzZSo+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzX1tmaWVsZC0+aW5kZXgoKV0pCisgICAgICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpOworICAgIH0KKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgb2Zmc2V0c19bZmllbGQtPmluZGV4KCldOworICB9Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldE9uZW9mRmllbGREZXNjcmlwdG9yKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdCB7CisgIHVpbnQzMiBmaWVsZF9udW1iZXIgPSBHZXRPbmVvZkNhc2UobWVzc2FnZSwgb25lb2ZfZGVzY3JpcHRvcik7CisgIGlmIChmaWVsZF9udW1iZXIgPT0gMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHJldHVybiBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOdW1iZXIoZmllbGRfbnVtYmVyKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6RmluZEtub3duRXh0ZW5zaW9uQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBpZiAoZXh0ZW5zaW9uc19vZmZzZXRfID09IC0xKSByZXR1cm4gTlVMTDsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9IGRlc2NyaXB0b3JfcG9vbF8tPkZpbmRFeHRlbnNpb25CeU5hbWUobmFtZSk7CisgIGlmIChyZXN1bHQgIT0gTlVMTCAmJiByZXN1bHQtPmNvbnRhaW5pbmdfdHlwZSgpID09IGRlc2NyaXB0b3JfKSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAvLyBNZXNzYWdlU2V0IGV4dGVuc2lvbnMgbWF5IGJlIGlkZW50aWZpZWQgYnkgdHlwZSBuYW1lLgorICAgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUgPSBkZXNjcmlwdG9yX3Bvb2xfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUobmFtZSk7CisgICAgaWYgKHR5cGUgIT0gTlVMTCkgeworICAgICAgLy8gTG9vayBmb3IgYSBtYXRjaGluZyBleHRlbnNpb24gaW4gdGhlIGZvcmVpZ24gdHlwZSdzIHNjb3BlLgorICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uID0gdHlwZS0+ZXh0ZW5zaW9uKGkpOworICAgICAgICBpZiAoZXh0ZW5zaW9uLT5jb250YWluaW5nX3R5cGUoKSA9PSBkZXNjcmlwdG9yXyAmJgorICAgICAgICAgICAgZXh0ZW5zaW9uLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+aXNfb3B0aW9uYWwoKSAmJgorICAgICAgICAgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3R5cGUoKSA9PSB0eXBlKSB7CisgICAgICAgICAgLy8gRm91bmQgaXQuCisgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbjsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcigKKyAgICBpbnQgbnVtYmVyKSBjb25zdCB7CisgIGlmIChleHRlbnNpb25zX29mZnNldF8gPT0gLTEpIHJldHVybiBOVUxMOworICByZXR1cm4gZGVzY3JpcHRvcl9wb29sXy0+RmluZEV4dGVuc2lvbkJ5TnVtYmVyKGRlc2NyaXB0b3JfLCBudW1iZXIpOworfQorCitib29sIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTdXBwb3J0c1Vua25vd25FbnVtVmFsdWVzKCkgY29uc3QgeworICByZXR1cm4gQ3JlYXRlVW5rbm93bkVudW1WYWx1ZXMoZGVzY3JpcHRvcl8tPmZpbGUoKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFNvbWUgcHJpdmF0ZSBoZWxwZXJzLgorCisvLyBUaGVzZSBzaW1wbGUgdGVtcGxhdGUgYWNjZXNzb3JzIG9idGFpbiBwb2ludGVycyAob3IgcmVmZXJlbmNlcykgdG8KKy8vIHRoZSBnaXZlbiBmaWVsZC4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGNvbnN0IFR5cGUmIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRSYXcoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAmJiAhSGFzT25lb2ZGaWVsZChtZXNzYWdlLCBmaWVsZCkpIHsKKyAgICByZXR1cm4gRGVmYXVsdFJhdzxUeXBlPihmaWVsZCk7CisgIH0KKyAgaW50IGluZGV4ID0gZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/CisgICAgICBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSArIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCkgOgorICAgICAgZmllbGQtPmluZGV4KCk7CisgIGNvbnN0IHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPigmbWVzc2FnZSkgKworICAgICAgb2Zmc2V0c19baW5kZXhdOworICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgVHlwZSo+KHB0cik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIFR5cGUqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlUmF3KAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaW50IGluZGV4ID0gZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/CisgICAgICBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSArIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCkgOgorICAgICAgZmllbGQtPmluZGV4KCk7CisgIHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArIG9mZnNldHNfW2luZGV4XTsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VHlwZSo+KHB0cik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGNvbnN0IFR5cGUmIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpEZWZhdWx0UmF3KAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgY29uc3Qgdm9pZCogcHRyID0gZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/CisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8pICsKKyAgICAgIG9mZnNldHNfW2ZpZWxkLT5pbmRleCgpXSA6CisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGVmYXVsdF9pbnN0YW5jZV8pICsKKyAgICAgIG9mZnNldHNfW2ZpZWxkLT5pbmRleCgpXTsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IFR5cGUqPihwdHIpOworfQorCitpbmxpbmUgY29uc3QgdWludDMyKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0SGFzQml0cygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdCB7CisgIGlmIChoYXNfYml0c19vZmZzZXRfID09IC0xKSB7ICAvLyBwcm90bzMgd2l0aCBubyBoYXMtYml0cy4KKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsgaGFzX2JpdHNfb2Zmc2V0XzsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyKj4ocHRyKTsKK30KK2lubGluZSB1aW50MzIqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlSGFzQml0cygKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7CisgIGlmIChoYXNfYml0c19vZmZzZXRfID09IC0xKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgaGFzX2JpdHNfb2Zmc2V0XzsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dWludDMyKj4ocHRyKTsKK30KKworaW5saW5lIHVpbnQzMiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0T25lb2ZDYXNlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGNvbnN0IHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPigmbWVzc2FnZSkKKyAgICAgICsgb25lb2ZfY2FzZV9vZmZzZXRfOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50MzIqPihwdHIpW29uZW9mX2Rlc2NyaXB0b3ItPmluZGV4KCldOworfQorCitpbmxpbmUgdWludDMyKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZU9uZW9mQ2FzZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3QgeworICB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4obWVzc2FnZSkgKyBvbmVvZl9jYXNlX29mZnNldF87CisgIHJldHVybiAmKHJlaW50ZXJwcmV0X2Nhc3Q8dWludDMyKj4ocHRyKVtvbmVvZl9kZXNjcmlwdG9yLT5pbmRleCgpXSk7Cit9CisKK2lubGluZSBjb25zdCBFeHRlbnNpb25TZXQmIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRFeHRlbnNpb25TZXQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgeworICBHT09HTEVfRENIRUNLX05FKGV4dGVuc2lvbnNfb2Zmc2V0XywgLTEpOworICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsKKyAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uc19vZmZzZXRfOworICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgRXh0ZW5zaW9uU2V0Kj4ocHRyKTsKK30KK2lubGluZSBFeHRlbnNpb25TZXQqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlRXh0ZW5zaW9uU2V0KAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDS19ORShleHRlbnNpb25zX29mZnNldF8sIC0xKTsKKyAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgZXh0ZW5zaW9uc19vZmZzZXRfOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxFeHRlbnNpb25TZXQqPihwdHIpOworfQorCitpbmxpbmUgQXJlbmEqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRBcmVuYShNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7CisgIGlmIChhcmVuYV9vZmZzZXRfID09IGtOb0FyZW5hUG9pbnRlcikgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgaWYgKHVua25vd25fZmllbGRzX29mZnNldF8gPT0ga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEpIHsKKyAgICAvLyB6ZXJvLW92ZXJoZWFkIGFyZW5hIHBvaW50ZXIgb3ZlcmxvYWRpbmcgVW5rbm93bkZpZWxkcworICAgIHJldHVybiBHZXRJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKCptZXNzYWdlKS5hcmVuYSgpOworICB9CisKKyAgLy8gQmFzZWxpbmUgY2FzZTogbWVzc2FnZSBjbGFzcyBoYXMgYSBkZWRpY2F0ZWQgYXJlbmEgcG9pbnRlci4KKyAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgYXJlbmFfb2Zmc2V0XzsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PEFyZW5hKio+KHB0cik7Cit9CisKK2lubGluZSBjb25zdCBJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hJgorR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgeworICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsgYXJlbmFfb2Zmc2V0XzsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEqPihwdHIpOworfQorCitpbmxpbmUgSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSoKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7CisgIHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArIGFyZW5hX29mZnNldF87CisgIHJldHVybiByZWludGVycHJldF9jYXN0PEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEqPihwdHIpOworfQorCitpbmxpbmUgYm9vbAorR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldElzRGVmYXVsdEluc3RhbmNlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0IHsKKyAgaWYgKGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0XyA9PSBrSGFzTm9EZWZhdWx0SW5zdGFuY2VGaWVsZCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsKKyAgICAgIGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0XzsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IGJvb2wqPihwdHIpOworfQorCisvLyBTaW1wbGUgYWNjZXNzb3JzIGZvciBtYW5pcHVsYXRpbmcgaGFzX2JpdHNfLgoraW5saW5lIGJvb2wgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Okhhc0JpdCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGlmIChoYXNfYml0c19vZmZzZXRfID09IC0xKSB7CisgICAgLy8gcHJvdG8zOiBubyBoYXMtYml0cy4gQWxsIGZpZWxkcyBwcmVzZW50IGV4Y2VwdCBtZXNzYWdlcywgd2hpY2ggYXJlCisgICAgLy8gcHJlc2VudCBvbmx5IGlmIHRoZWlyIG1lc3NhZ2UtZmllbGQgcG9pbnRlciBpcyBub24tTlVMTC4KKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIHJldHVybiAhR2V0SXNEZWZhdWx0SW5zdGFuY2UobWVzc2FnZSkgJiYKKyAgICAgICAgICBHZXRSYXc8Y29uc3QgTWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKSAhPSBOVUxMOworICAgIH0gZWxzZSB7CisgICAgICAvLyBOb24tbWVzc2FnZSBmaWVsZCAoYW5kIG5vbi1vbmVvZiwgc2luY2UgdGhhdCB3YXMgaGFuZGxlZCBpbiBIYXNGaWVsZCgpCisgICAgICAvLyBiZWZvcmUgY2FsbGluZyB1cyksIGFuZCBzaW5ndWxhciAoYWdhaW4sIGNoZWNrZWQgaW4gSGFzRmllbGQpLiBTbywgdGhpcworICAgICAgLy8gZmllbGQgbXVzdCBiZSBhIHNjYWxhci4KKworICAgICAgLy8gU2NhbGFyIHByaW1pdGl2ZSAobnVtZXJpYyBvciBzdHJpbmcvYnl0ZXMpIGZpZWxkcyBhcmUgcHJlc2VudCBpZgorICAgICAgLy8gdGhlaXIgdmFsdWUgaXMgbm9uLXplcm8gKG51bWVyaWMpIG9yIG5vbi1lbXB0eSAoc3RyaW5nL2J5dGVzKS4gIE4uQi46CisgICAgICAvLyB3ZSBtdXN0IHVzZSB0aGlzIGRlZmluaXRpb24gaGVyZSwgcmF0aGVyIHRoYW4gdGhlICJzY2FsYXIgZmllbGRzCisgICAgICAvLyBhbHdheXMgcHJlc2VudCIgaW4gdGhlIHByb3RvMyBkb2NzLCBiZWNhdXNlIE1lcmdlRnJvbSgpIHNlbWFudGljcworICAgICAgLy8gcmVxdWlyZSBwcmVzZW5jZSBhcyAicHJlc2VudCBvbiB3aXJlIiwgYW5kIHJlZmxlY3Rpb24tYmFzZWQgbWVyZ2UKKyAgICAgIC8vICh3aGljaCB1c2VzIEhhc0ZpZWxkKCkpIG5lZWRzIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCB0aGlzLgorICAgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICAgIGRlZmF1bHQ6IHsKKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgICAgICAgcmV0dXJuIEdldEZpZWxkPEFyZW5hU3RyaW5nUHRyPihtZXNzYWdlLCBmaWVsZCkuR2V0KAorICAgICAgICAgICAgICAgICAgZGVmYXVsdF9wdHIpLnNpemUoKSA+IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgICByZXR1cm4gR2V0UmF3PGJvb2w+KG1lc3NhZ2UsIGZpZWxkKSAhPSBmYWxzZTsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgICAgcmV0dXJuIEdldFJhdzxpbnQzMj4obWVzc2FnZSwgZmllbGQpICE9IDA7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICAgIHJldHVybiBHZXRSYXc8aW50NjQ+KG1lc3NhZ2UsIGZpZWxkKSAhPSAwOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgICAgcmV0dXJuIEdldFJhdzx1aW50MzI+KG1lc3NhZ2UsIGZpZWxkKSAhPSAwOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICAgICAgcmV0dXJuIEdldFJhdzx1aW50NjQ+KG1lc3NhZ2UsIGZpZWxkKSAhPSAwOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgICAgICByZXR1cm4gR2V0UmF3PGZsb2F0PihtZXNzYWdlLCBmaWVsZCkgIT0gMC4wOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICAgICAgcmV0dXJuIEdldFJhdzxkb3VibGU+KG1lc3NhZ2UsIGZpZWxkKSAhPSAwLjA7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICAgICAgcmV0dXJuIEdldFJhdzxpbnQ+KG1lc3NhZ2UsIGZpZWxkKSAhPSAwOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIC8vIGhhbmRsZWQgYWJvdmU7IGF2b2lkIHdhcm5pbmcKKyAgICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiUmVhY2hlZCBpbXBvc3NpYmxlIGNhc2UgaW4gSGFzQml0KCkuIjsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIEdldEhhc0JpdHMobWVzc2FnZSlbZmllbGQtPmluZGV4KCkgLyAzMl0gJgorICAgICgxIDw8IChmaWVsZC0+aW5kZXgoKSAlIDMyKSk7Cit9CisKK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRCaXQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoaGFzX2JpdHNfb2Zmc2V0XyA9PSAtMSkgeworICAgIHJldHVybjsKKyAgfQorICBNdXRhYmxlSGFzQml0cyhtZXNzYWdlKVtmaWVsZC0+aW5kZXgoKSAvIDMyXSB8PSAoMSA8PCAoZmllbGQtPmluZGV4KCkgJSAzMikpOworfQorCitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6Q2xlYXJCaXQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoaGFzX2JpdHNfb2Zmc2V0XyA9PSAtMSkgeworICAgIHJldHVybjsKKyAgfQorICBNdXRhYmxlSGFzQml0cyhtZXNzYWdlKVtmaWVsZC0+aW5kZXgoKSAvIDMyXSAmPSB+KDEgPDwgKGZpZWxkLT5pbmRleCgpICUgMzIpKTsKK30KKworaW5saW5lIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlN3YXBCaXQoCisgICAgTWVzc2FnZSogbWVzc2FnZTEsIE1lc3NhZ2UqIG1lc3NhZ2UyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGlmIChoYXNfYml0c19vZmZzZXRfID09IC0xKSB7CisgICAgcmV0dXJuOworICB9CisgIGJvb2wgdGVtcF9oYXNfYml0ID0gSGFzQml0KCptZXNzYWdlMSwgZmllbGQpOworICBpZiAoSGFzQml0KCptZXNzYWdlMiwgZmllbGQpKSB7CisgICAgU2V0Qml0KG1lc3NhZ2UxLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgQ2xlYXJCaXQobWVzc2FnZTEsIGZpZWxkKTsKKyAgfQorICBpZiAodGVtcF9oYXNfYml0KSB7CisgICAgU2V0Qml0KG1lc3NhZ2UyLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgQ2xlYXJCaXQobWVzc2FnZTIsIGZpZWxkKTsKKyAgfQorfQorCitpbmxpbmUgYm9vbCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6SGFzT25lb2YoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdCB7CisgIHJldHVybiAoR2V0T25lb2ZDYXNlKG1lc3NhZ2UsIG9uZW9mX2Rlc2NyaXB0b3IpID4gMCk7Cit9CisKK2lubGluZSBib29sIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpIYXNPbmVvZkZpZWxkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgcmV0dXJuIChHZXRPbmVvZkNhc2UobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgPT0gZmllbGQtPm51bWJlcigpKTsKK30KKworaW5saW5lIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldE9uZW9mQ2FzZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgICpNdXRhYmxlT25lb2ZDYXNlKG1lc3NhZ2UsIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpID0gZmllbGQtPm51bWJlcigpOworfQorCitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6Q2xlYXJPbmVvZkZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKEhhc09uZW9mRmllbGQoKm1lc3NhZ2UsIGZpZWxkKSkgeworICAgIENsZWFyT25lb2YobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgIH0KK30KKworaW5saW5lIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkNsZWFyT25lb2YoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdCB7CisgIC8vIFRPRE8oamllbHVvKTogQ29uc2lkZXIgdG8gY2FjaGUgdGhlIHVudXNlZCBvYmplY3QgaW5zdGVhZCBvZiBkZWxldGluZworICAvLyBpdC4gSXQgd2lsbCBiZSBtdWNoIGZhc3RlciBpZiBhbiBhcGxpY2F0aW9uIHN3aXRjaGVzIGEgbG90IGZyb20KKyAgLy8gYSBmZXcgb25lb2YgZmllbGRzLiAgVGltZS9zcGFjZSB0cmFkZW9mZgorICB1aW50MzIgb25lb2ZfY2FzZSA9IEdldE9uZW9mQ2FzZSgqbWVzc2FnZSwgb25lb2ZfZGVzY3JpcHRvcik7CisgIGlmIChvbmVvZl9jYXNlID4gMCkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOdW1iZXIob25lb2ZfY2FzZSk7CisgICAgaWYgKEdldEFyZW5hKG1lc3NhZ2UpID09IE5VTEwpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzogeworICAgICAgICAgICAgICBjb25zdCBzdHJpbmcqIGRlZmF1bHRfcHRyID0KKyAgICAgICAgICAgICAgICAgICZEZWZhdWx0UmF3PEFyZW5hU3RyaW5nUHRyPihmaWVsZCkuR2V0KE5VTEwpOworICAgICAgICAgICAgICBNdXRhYmxlRmllbGQ8QXJlbmFTdHJpbmdQdHI+KG1lc3NhZ2UsIGZpZWxkKS0+CisgICAgICAgICAgICAgICAgICBEZXN0cm95KGRlZmF1bHRfcHRyLCBHZXRBcmVuYShtZXNzYWdlKSk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgZGVsZXRlICpNdXRhYmxlUmF3PE1lc3NhZ2UqPihtZXNzYWdlLCBmaWVsZCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorCisgICAgKk11dGFibGVPbmVvZkNhc2UobWVzc2FnZSwgb25lb2ZfZGVzY3JpcHRvcikgPSAwOworICB9Cit9CisKKy8vIFRlbXBsYXRlIGltcGxlbWVudGF0aW9ucyBvZiBiYXNpYyBhY2Nlc3NvcnMuICBJbmxpbmUgYmVjYXVzZSBlYWNoCisvLyB0ZW1wbGF0ZSBpbnN0YW5jZSBpcyBvbmx5IGNhbGxlZCBmcm9tIG9uZSBsb2NhdGlvbi4gIFRoZXNlIGFyZQorLy8gdXNlZCBmb3IgYWxsIHR5cGVzIGV4Y2VwdCBtZXNzYWdlcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGNvbnN0IFR5cGUmIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiBHZXRSYXc8VHlwZT4obWVzc2FnZSwgZmllbGQpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBjb25zdCBUeXBlJiB2YWx1ZSkgY29uc3QgeworICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAmJiAhSGFzT25lb2ZGaWVsZCgqbWVzc2FnZSwgZmllbGQpKSB7CisgICAgQ2xlYXJPbmVvZihtZXNzYWdlLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgfQorICAqTXV0YWJsZVJhdzxUeXBlPihtZXNzYWdlLCBmaWVsZCkgPSB2YWx1ZTsKKyAgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/CisgICAgICBTZXRPbmVvZkNhc2UobWVzc2FnZSwgZmllbGQpIDogU2V0Qml0KG1lc3NhZ2UsIGZpZWxkKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgVHlwZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPworICAgICAgU2V0T25lb2ZDYXNlKG1lc3NhZ2UsIGZpZWxkKSA6IFNldEJpdChtZXNzYWdlLCBmaWVsZCk7CisgIHJldHVybiBNdXRhYmxlUmF3PFR5cGU+KG1lc3NhZ2UsIGZpZWxkKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgY29uc3QgVHlwZSYgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFJlcGVhdGVkRmllbGQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIHJldHVybiBHZXRSYXc8UmVwZWF0ZWRGaWVsZDxUeXBlPiA+KG1lc3NhZ2UsIGZpZWxkKS5HZXQoaW5kZXgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBjb25zdCBUeXBlJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgcmV0dXJuIEdldFJhdzxSZXBlYXRlZFB0ckZpZWxkPFR5cGU+ID4obWVzc2FnZSwgZmllbGQpLkdldChpbmRleCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldFJlcGVhdGVkRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIGNvbnN0IHsKKyAgTXV0YWJsZVJhdzxSZXBlYXRlZEZpZWxkPFR5cGU+ID4obWVzc2FnZSwgZmllbGQpLT5TZXQoaW5kZXgsIHZhbHVlKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgVHlwZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVSZXBlYXRlZEZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeworICBSZXBlYXRlZFB0ckZpZWxkPFR5cGU+KiByZXBlYXRlZCA9CisgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkPFR5cGU+ID4obWVzc2FnZSwgZmllbGQpOworICByZXR1cm4gcmVwZWF0ZWQtPk11dGFibGUoaW5kZXgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGRGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBjb25zdCBUeXBlJiB2YWx1ZSkgY29uc3QgeworICBNdXRhYmxlUmF3PFJlcGVhdGVkRmllbGQ8VHlwZT4gPihtZXNzYWdlLCBmaWVsZCktPkFkZCh2YWx1ZSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIFR5cGUqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGRGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFJlcGVhdGVkUHRyRmllbGQ8VHlwZT4qIHJlcGVhdGVkID0KKyAgICBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGQ8VHlwZT4gPihtZXNzYWdlLCBmaWVsZCk7CisgIHJldHVybiByZXBlYXRlZC0+QWRkKCk7Cit9CisKK01lc3NhZ2VGYWN0b3J5KiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0TWVzc2FnZUZhY3RvcnkoKSBjb25zdCB7CisgIHJldHVybiBtZXNzYWdlX2ZhY3RvcnlfOworfQorCit2b2lkKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6UmVwZWF0ZWRGaWVsZERhdGEoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUsCisgICAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDSyhmaWVsZC0+aXNfcmVwZWF0ZWQoKSk7CisgIEdPT0dMRV9DSEVDSyhmaWVsZC0+Y3BwX3R5cGUoKSA9PSBjcHBfdHlwZSB8fAorICAgICAgICAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gJiYKKyAgICAgICAgIGNwcF90eXBlID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMikpCisgICAgICA8PCAiVGhlIHR5cGUgcGFyYW1ldGVyIFQgaW4gUmVwZWF0ZWRGaWVsZFJlZjxUPiBBUEkgZG9lc24ndCBtYXRjaCAiCisgICAgICA8PCAidGhlIGFjdHVhbCBmaWVsZCB0eXBlIChmb3IgZW51bXMgVCBzaG91bGQgYmUgdGhlIGdlbmVyYXRlZCBlbnVtICIKKyAgICAgIDw8ICJ0eXBlIG9yIGludDMyKS4iOworICBpZiAobWVzc2FnZV90eXBlICE9IE5VTEwpIHsKKyAgICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZV90eXBlLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICB9CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoCisgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSwgZmllbGQtPmlzX3BhY2tlZCgpLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArIG9mZnNldHNfW2ZpZWxkLT5pbmRleCgpXTsKKyAgfQorfQorCitHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0LAorICAgIGNvbnN0IHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UsCisgICAgaW50IG9uZW9mX2Nhc2Vfb2Zmc2V0LAorICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgIGludCBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkgeworICByZXR1cm4gbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9pbnN0YW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVvZl9jYXNlX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3Rfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVuYV9vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQpOworfQorCitHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0LAorICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgIGludCBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkgeworICByZXR1cm4gbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9pbnN0YW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0X3NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlbmFfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGRkZGY2YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oCkBAIC0wLDAgKzEsNjA0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBoZWFkZXIgaXMgbG9naWNhbGx5IGludGVybmFsLCBidXQgaXMgbWFkZSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCisvLyBmcm9tIHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZCBjb2RlLCB3aGljaCBtYXkgcmVzaWRlIGluIG90aGVyIGNvbXBvbmVudHMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX1JFRkxFQ1RJT05fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9SRUZMRUNUSU9OX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisvLyBUT0RPKGphc29uaCk6IFJlbW92ZSB0aGlzIG9uY2UgdGhlIGNvbXBpbGVyIGNoYW5nZSB0byBkaXJlY3RseSBpbmNsdWRlIHRoaXMKKy8vIGlzIHJlbGVhc2VkIHRvIGNvbXBvbmVudHMuCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHVwYiB7CituYW1lc3BhY2UgZ29vZ2xlX29wZW5zb3VyY2UgeworY2xhc3MgR01SX0hhbmRsZXJzOworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZV9vcGVuc291cmNlCit9ICAvLyBuYW1lc3BhY2UgdXBiCisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIGNsYXNzIERlc2NyaXB0b3JQb29sOworfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK2NsYXNzIERlZmF1bHRFbXB0eU9uZW9mOworCisvLyBEZWZpbmVkIGluIHRoaXMgZmlsZS4KK2NsYXNzIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworCisvLyBEZWZpbmVkIGluIG90aGVyIGZpbGVzLgorY2xhc3MgRXh0ZW5zaW9uU2V0OyAgICAgICAgICAgICAvLyBleHRlbnNpb25fc2V0LmgKKworLy8gVEhJUyBDTEFTUyBJUyBOT1QgSU5URU5ERUQgRk9SIERJUkVDVCBVU0UuICBJdCBpcyBpbnRlbmRlZCBmb3IgdXNlCisvLyBieSBnZW5lcmF0ZWQgY29kZS4gIFRoaXMgY2xhc3MgaXMganVzdCBhIGJpZyBoYWNrIHRoYXQgcmVkdWNlcyBjb2RlCisvLyBzaXplLgorLy8KKy8vIEEgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24gaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgUmVmbGVjdGlvbgorLy8gd2hpY2ggZXhwZWN0cyBhbGwgZmllbGRzIHRvIGJlIGJhY2tlZCBieSBzaW1wbGUgdmFyaWFibGVzIGxvY2F0ZWQgaW4KKy8vIG1lbW9yeS4gIFRoZSBsb2NhdGlvbnMgYXJlIGdpdmVuIHVzaW5nIGEgYmFzZSBwb2ludGVyIGFuZCBhIHNldCBvZgorLy8gb2Zmc2V0cy4KKy8vCisvLyBJdCBpcyByZXF1aXJlZCB0aGF0IHRoZSB1c2VyIHJlcHJlc2VudHMgZmllbGRzIG9mIGVhY2ggdHlwZSBpbiBhIHN0YW5kYXJkCisvLyB3YXksIHNvIHRoYXQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24gY2FuIGNhc3QgdGhlIHZvaWQqIHBvaW50ZXIgdG8KKy8vIHRoZSBhcHByb3ByaWF0ZSB0eXBlLiAgRm9yIHByaW1pdGl2ZSBmaWVsZHMgYW5kIHN0cmluZyBmaWVsZHMsIGVhY2ggZmllbGQKKy8vIHNob3VsZCBiZSByZXByZXNlbnRlZCB1c2luZyB0aGUgb2J2aW91cyBDKysgcHJpbWl0aXZlIHR5cGUuICBFbnVtcyBhbmQKKy8vIE1lc3NhZ2VzIGFyZSBkaWZmZXJlbnQ6CisvLyAgLSBTaW5ndWxhciBNZXNzYWdlIGZpZWxkcyBhcmUgc3RvcmVkIGFzIGEgcG9pbnRlciB0byBhIE1lc3NhZ2UuICBUaGVzZQorLy8gICAgc2hvdWxkIHN0YXJ0IG91dCBOVUxMLCBleGNlcHQgZm9yIGluIHRoZSBkZWZhdWx0IGluc3RhbmNlIHdoZXJlIHRoZXkKKy8vICAgIHNob3VsZCBzdGFydCBvdXQgcG9pbnRpbmcgdG8gb3RoZXIgZGVmYXVsdCBpbnN0YW5jZXMuCisvLyAgLSBFbnVtIGZpZWxkcyBhcmUgc3RvcmVkIGFzIGFuIGludC4gIFRoaXMgaW50IG11c3QgYWx3YXlzIGNvbnRhaW4KKy8vICAgIGEgdmFsaWQgdmFsdWUsIHN1Y2ggdGhhdCBFbnVtRGVzY3JpcHRvcjo6RmluZFZhbHVlQnlOdW1iZXIoKSB3b3VsZAorLy8gICAgbm90IHJldHVybiBOVUxMLgorLy8gIC0gUmVwZWF0ZWQgZmllbGRzIGFyZSBzdG9yZWQgYXMgUmVwZWF0ZWRGaWVsZHMgb3IgUmVwZWF0ZWRQdHJGaWVsZHMKKy8vICAgIG9mIHdoYXRldmVyIHR5cGUgdGhlIGluZGl2aWR1YWwgZmllbGQgd291bGQgYmUuICBTdHJpbmdzIGFuZAorLy8gICAgTWVzc2FnZXMgdXNlIFJlcGVhdGVkUHRyRmllbGRzIHdoaWxlIGV2ZXJ5dGhpbmcgZWxzZSB1c2VzCisvLyAgICBSZXBlYXRlZEZpZWxkcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiA6IHB1YmxpYyBSZWZsZWN0aW9uIHsKKyBwdWJsaWM6CisgIC8vIENvbnN0cnVjdHMgYSBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbi4KKyAgLy8gUGFyYW1ldGVyczoKKyAgLy8gICBkZXNjcmlwdG9yOiAgICBUaGUgZGVzY3JpcHRvciBmb3IgdGhlIG1lc3NhZ2UgdHlwZSBiZWluZyBpbXBsZW1lbnRlZC4KKyAgLy8gICBkZWZhdWx0X2luc3RhbmNlOiAgVGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhlIG1lc3NhZ2UuICBUaGlzIGlzIG9ubHkKKyAgLy8gICAgICAgICAgICAgICAgICB1c2VkIHRvIG9idGFpbiBwb2ludGVycyB0byBkZWZhdWx0IGluc3RhbmNlcyBvZiBlbWJlZGRlZAorICAvLyAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzLCB3aGljaCBHZXRNZXNzYWdlKCkgd2lsbCByZXR1cm4gaWYgdGhlIHBhcnRpY3VsYXIKKyAgLy8gICAgICAgICAgICAgICAgICBzdWItbWVzc2FnZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0LiAgKFRodXMsIGFsbAorICAvLyAgICAgICAgICAgICAgICAgIGVtYmVkZGVkIG1lc3NhZ2UgZmllbGRzICptdXN0KiBoYXZlIG5vbi1OVUxMIHBvaW50ZXJzCisgIC8vICAgICAgICAgICAgICAgICAgaW4gdGhlIGRlZmF1bHQgaW5zdGFuY2UuKQorICAvLyAgIG9mZnNldHM6ICAgICAgIEFuIGFycmF5IG9mIGludHMgZ2l2aW5nIHRoZSBieXRlIG9mZnNldHMsIHJlbGF0aXZlIHRvCisgIC8vICAgICAgICAgICAgICAgICAgdGhlIHN0YXJ0IG9mIHRoZSBtZXNzYWdlIG9iamVjdCwgb2YgZWFjaCBmaWVsZC4gIFRoZXNlIGNhbgorICAvLyAgICAgICAgICAgICAgICAgIGJlIGNvbXB1dGVkIGF0IGNvbXBpbGUgdGltZSB1c2luZyB0aGUKKyAgLy8gICAgICAgICAgICAgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKCkgbWFjcm8sIGRlZmluZWQKKyAgLy8gICAgICAgICAgICAgICAgICBiZWxvdy4KKyAgLy8gICBoYXNfYml0c19vZmZzZXQ6ICBPZmZzZXQgaW4gdGhlIG1lc3NhZ2Ugb2YgYW4gYXJyYXkgb2YgdWludDMycyBvZiBzaXplCisgIC8vICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKS8zMiwgcm91bmRlZCB1cC4gIFRoaXMgaXMgYQorICAvLyAgICAgICAgICAgICAgICAgIGJpdGZpZWxkIHdoZXJlIGVhY2ggYml0IGluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUKKyAgLy8gICAgICAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIGZpZWxkIG9mIHRoZSBtZXNzYWdlIGhhcyBiZWVuIGluaXRpYWxpemVkLgorICAvLyAgICAgICAgICAgICAgICAgIFRoZSBiaXQgZm9yIGZpZWxkIGluZGV4IGkgaXMgb2J0YWluZWQgYnkgdGhlIGV4cHJlc3Npb246CisgIC8vICAgICAgICAgICAgICAgICAgICBoYXNfYml0c1tpIC8gMzJdICYgKDEgPDwgKGkgJSAzMikpCisgIC8vICAgdW5rbm93bl9maWVsZHNfb2Zmc2V0OiAgT2Zmc2V0IGluIHRoZSBtZXNzYWdlIG9mIHRoZSBVbmtub3duRmllbGRTZXQgZm9yCisgIC8vICAgICAgICAgICAgICAgICAgdGhlIG1lc3NhZ2UuCisgIC8vICAgZXh0ZW5zaW9uc19vZmZzZXQ6ICBPZmZzZXQgaW4gdGhlIG1lc3NhZ2Ugb2YgdGhlIEV4dGVuc2lvblNldCBmb3IgdGhlCisgIC8vICAgICAgICAgICAgICAgICAgbWVzc2FnZSwgb3IgLTEgaWYgdGhlIG1lc3NhZ2UgdHlwZSBoYXMgbm8gZXh0ZW5zaW9uCisgIC8vICAgICAgICAgICAgICAgICAgcmFuZ2VzLgorICAvLyAgIHBvb2w6ICAgICAgICAgIERlc2NyaXB0b3JQb29sIHRvIHNlYXJjaCBmb3IgZXh0ZW5zaW9uIGRlZmluaXRpb25zLiAgT25seQorICAvLyAgICAgICAgICAgICAgICAgIHVzZWQgYnkgRmluZEtub3duRXh0ZW5zaW9uQnlOYW1lKCkgYW5kCisgIC8vICAgICAgICAgICAgICAgICAgRmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIoKS4KKyAgLy8gICBmYWN0b3J5OiAgICAgICBNZXNzYWdlRmFjdG9yeSB0byB1c2UgdG8gY29uc3RydWN0IGV4dGVuc2lvbiBtZXNzYWdlcy4KKyAgLy8gICBvYmplY3Rfc2l6ZTogICBUaGUgc2l6ZSBvZiBhIG1lc3NhZ2Ugb2JqZWN0IG9mIHRoaXMgdHlwZSwgYXMgbWVhc3VyZWQKKyAgLy8gICAgICAgICAgICAgICAgICBieSBzaXplb2YoKS4KKyAgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFyZW5hX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ID0gLTEpOworCisgIC8vIFNpbWlsYXIgd2l0aCB0aGUgY29uc3RydWN0aW9uIGFib3ZlLiBDYWxsIHRoaXMgY29uc3RydWN0aW9uIGlmIHRoZQorICAvLyBtZXNzYWdlIGhhcyBvbmVvZiBkZWZpbml0aW9uLgorICAvLyBQYXJhbWV0ZXJzOgorICAvLyAgIG9mZnNldHM6ICAgICAgIEFuIGFycmF5IG9mIGludHMgZ2l2aW5nIHRoZSBieXRlIG9mZnNldHMuCisgIC8vICAgICAgICAgICAgICAgICAgRm9yIGVhY2ggb25lb2YgZmllbGQsIHRoZSBvZmZzZXQgaXMgcmVsYXRpdmUgdG8gdGhlCisgIC8vICAgICAgICAgICAgICAgICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZS4gVGhlc2UgY2FuIGJlIGNvbXB1dGVkIGF0IGNvbXBpbGUKKyAgLy8gICAgICAgICAgICAgICAgICB0aW1lIHVzaW5nIHRoZQorICAvLyAgICAgICAgICAgICAgICAgIFBST1RPMl9HRU5FUkFURURfREVGQVVMVF9PTkVPRl9GSUVMRF9PRkZTRVQoKSBtYWNyby4KKyAgLy8gICAgICAgICAgICAgICAgICBGb3IgZWFjaCBub25lIG9uZW9mIGZpZWxkLCB0aGUgb2Zmc2V0IGlzIHJlbGF0ZWQgdG8KKyAgLy8gICAgICAgICAgICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIG1lc3NhZ2Ugb2JqZWN0LiAgVGhlc2UgY2FuIGJlIGNvbXB1dGVkCisgIC8vICAgICAgICAgICAgICAgICAgYXQgY29tcGlsZSB0aW1lIHVzaW5nIHRoZQorICAvLyAgICAgICAgICAgICAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoKSBtYWNyby4KKyAgLy8gICAgICAgICAgICAgICAgICBCZXNpZGVzIG9mZnNldHMgZm9yIGFsbCBmaWVsZHMsIHRoaXMgYXJyYXkgYWxzbyBjb250YWlucworICAvLyAgICAgICAgICAgICAgICAgIG9mZnNldHMgZm9yIG9uZW9mIHVuaW9ucy4gVGhlIG9mZnNldCBvZiB0aGUgaS10aCBvbmVvZgorICAvLyAgICAgICAgICAgICAgICAgIHVuaW9uIGlzIG9mZnNldHNbZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKSArIGldLgorICAvLyAgIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2U6IFRoZSBkZWZhdWx0IGluc3RhbmNlIG9mIHRoZSBvbmVvZnMuIEl0IGlzIGEKKyAgLy8gICAgICAgICAgICAgICAgICBzdHJ1Y3QgaG9sZGluZyB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBhbGwgb25lb2YgZmllbGRzCisgIC8vICAgICAgICAgICAgICAgICAgZm9yIHRoaXMgbWVzc2FnZS4gSXQgaXMgb25seSB1c2VkIHRvIG9idGFpbiBwb2ludGVycworICAvLyAgICAgICAgICAgICAgICAgIHRvIGRlZmF1bHQgaW5zdGFuY2VzIG9mIG9uZW9mIGZpZWxkcywgd2hpY2ggR2V0CisgIC8vICAgICAgICAgICAgICAgICAgbWV0aG9kcyB3aWxsIHJldHVybiBpZiB0aGUgZmllbGQgaXMgbm90IHNldC4KKyAgLy8gICBvbmVvZl9jYXNlX29mZnNldDogIE9mZnNldCBpbiB0aGUgbWVzc2FnZSBvZiBhbiBhcnJheSBvZiB1aW50MzJzIG9mCisgIC8vICAgICAgICAgICAgICAgICAgc2l6ZSBkZXNjcmlwdG9yLT5vbmVvZl9kZWNsX2NvdW50KCkuICBFYWNoIHVpbnQzMgorICAvLyAgICAgICAgICAgICAgICAgIGluZGljYXRlcyB3aGF0IGZpZWxkIGlzIHNldCBmb3IgZWFjaCBvbmVvZi4KKyAgLy8gICBvdGhlciBwYXJhbWV0ZXJzIGFyZSB0aGUgc2FtZSB3aXRoIHRoZSBjb25zdHJ1Y3Rpb24gYWJvdmUuCisgIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBvZmZzZXRzW10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBoYXNfYml0c19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBleHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9uZW9mX2Nhc2Vfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFyZW5hX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ID0gLTEpOworICB+R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oKTsKKworICAvLyBTaG9ydGVyLXRvLWNhbGwgaGVscGVycyBmb3IgdGhlIGFib3ZlIHR3byBjb25zdHJ1Y3Rpb25zIHRoYXQgd29yayBpZiB0aGUKKyAgLy8gcG9vbCBhbmQgZmFjdG9yeSBhcmUgdGhlIHVzdWFsLCBuYW1lbHksIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpCisgIC8vIGFuZCBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS4KKworICBzdGF0aWMgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qIE5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgICAgaW50IGhhc19iaXRzX29mZnNldCwKKyAgICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgICBjb25zdCB2b2lkKiBkZWZhdWx0X29uZW9mX2luc3RhbmNlLAorICAgICAgaW50IG9uZW9mX2Nhc2Vfb2Zmc2V0LAorICAgICAgaW50IG9iamVjdF9zaXplLAorICAgICAgaW50IGFyZW5hX29mZnNldCwKKyAgICAgIGludCBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCA9IC0xKTsKKworICBzdGF0aWMgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qIE5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgICAgaW50IGhhc19iaXRzX29mZnNldCwKKyAgICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgICBpbnQgb2JqZWN0X3NpemUsCisgICAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ID0gLTEpOworCisgIC8vIGltcGxlbWVudHMgUmVmbGVjdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiBHZXRVbmtub3duRmllbGRzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0OworICBVbmtub3duRmllbGRTZXQqIE11dGFibGVVbmtub3duRmllbGRzKE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0OworCisgIGludCBTcGFjZVVzZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3Q7CisKKyAgYm9vbCBIYXNGaWVsZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgaW50IEZpZWxkU2l6ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgdm9pZCBDbGVhckZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBib29sIEhhc09uZW9mKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBDbGVhck9uZW9mKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB2b2lkIFJlbW92ZUxhc3QoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIE1lc3NhZ2UqIFJlbGVhc2VMYXN0KE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB2b2lkIFN3YXAoTWVzc2FnZSogbWVzc2FnZTEsIE1lc3NhZ2UqIG1lc3NhZ2UyKSBjb25zdDsKKyAgdm9pZCBTd2FwRmllbGRzKE1lc3NhZ2UqIG1lc3NhZ2UxLCBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgZmllbGRzKSBjb25zdDsKKyAgdm9pZCBTd2FwRWxlbWVudHMoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4MSwgaW50IGluZGV4MikgY29uc3Q7CisgIHZvaWQgTGlzdEZpZWxkcyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KiBvdXRwdXQpIGNvbnN0OworCisgIGludDMyICBHZXRJbnQzMiAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgaW50NjQgIEdldEludDY0IChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB1aW50MzIgR2V0VUludDMyKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHVpbnQ2NCBHZXRVSW50NjQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgZmxvYXQgIEdldEZsb2F0IChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBkb3VibGUgR2V0RG91YmxlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGJvb2wgICBHZXRCb29sICAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgc3RyaW5nIEdldFN0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBjb25zdCBzdHJpbmcmIEdldFN0cmluZ1JlZmVyZW5jZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHNjcmF0Y2gpIGNvbnN0OworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBHZXRFbnVtKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGludCBHZXRFbnVtVmFsdWUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZSYgR2V0TWVzc2FnZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdDsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEdldE9uZW9mRmllbGREZXNjcmlwdG9yKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3Q7CisKKyBwdWJsaWM6CisgIHZvaWQgU2V0SW50MzIgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludDMyICB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0SW50NjQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludDY0ICB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0VUludDMyKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHVpbnQzMiB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0VUludDY0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHVpbnQ2NCB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0RmxvYXQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGZsb2F0ICB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0RG91YmxlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGRvdWJsZSB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0Qm9vbCAgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgICB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0U3RyaW5nKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldEVudW0gIChNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0RW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSkgY29uc3Q7CisgIE1lc3NhZ2UqIE11dGFibGVNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5ID0gTlVMTCkgY29uc3Q7CisgIHZvaWQgU2V0QWxsb2NhdGVkTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgTWVzc2FnZSogUmVsZWFzZU1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdDsKKworICBpbnQzMiAgR2V0UmVwZWF0ZWRJbnQzMiAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIGludDY0ICBHZXRSZXBlYXRlZEludDY0IChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdDsKKyAgdWludDMyIEdldFJlcGVhdGVkVUludDMyKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworICB1aW50NjQgR2V0UmVwZWF0ZWRVSW50NjQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIGZsb2F0ICBHZXRSZXBlYXRlZEZsb2F0IChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdDsKKyAgZG91YmxlIEdldFJlcGVhdGVkRG91YmxlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworICBib29sICAgR2V0UmVwZWF0ZWRCb29sICAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIHN0cmluZyBHZXRSZXBlYXRlZFN0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdDsKKyAgY29uc3Qgc3RyaW5nJiBHZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LCBzdHJpbmcqIHNjcmF0Y2gpIGNvbnN0OworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBHZXRSZXBlYXRlZEVudW0oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0OworICBpbnQgR2V0UmVwZWF0ZWRFbnVtVmFsdWUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0OworICBjb25zdCBNZXNzYWdlJiBHZXRSZXBlYXRlZE1lc3NhZ2UoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIFNldCB0aGUgdmFsdWUgb2YgYSBmaWVsZC4KKyAgdm9pZCBTZXRSZXBlYXRlZEludDMyIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgaW50MzIgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZEludDY0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgaW50NjQgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZFVJbnQzMihNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgdWludDMyIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZFVJbnQ2NChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgdWludDY0IHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZEZsb2F0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgZmxvYXQgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZERvdWJsZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZEJvb2wgIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwgYm9vbCAgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZFN0cmluZyhNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZEVudW0oTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0UmVwZWF0ZWRFbnVtVmFsdWUoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgY29uc3Q7CisgIC8vIEdldCBhIG11dGFibGUgcG9pbnRlciB0byBhIGZpZWxkIHdpdGggYSBtZXNzYWdlIHR5cGUuCisgIE1lc3NhZ2UqIE11dGFibGVSZXBlYXRlZE1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisKKyAgdm9pZCBBZGRJbnQzMiAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50MzIgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRJbnQ2NCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50NjQgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRVSW50MzIoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgdWludDMyIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRVSW50NjQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgdWludDY0IHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRGbG9hdCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZmxvYXQgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGREb3VibGUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZG91YmxlIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRCb29sICAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCAgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRTdHJpbmcoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgQWRkRW51bShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRFbnVtVmFsdWUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKyAgTWVzc2FnZSogQWRkTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5ID0gTlVMTCkgY29uc3Q7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kS25vd25FeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihpbnQgbnVtYmVyKSBjb25zdDsKKworICBib29sIFN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZXMoKSBjb25zdDsKKworICAvLyBUaGlzIHZhbHVlIGZvciBhcmVuYV9vZmZzZXRfIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIG5vIGFyZW5hIHBvaW50ZXIgaW4KKyAgLy8gdGhpcyBtZXNzYWdlIChlLmcuLCBvbGQgZ2VuZXJhdGVkIGNvZGUpLgorICBzdGF0aWMgY29uc3QgaW50IGtOb0FyZW5hUG9pbnRlciA9IC0xOworCisgIC8vIFRoaXMgdmFsdWUgZm9yIHVua25vd25fZmllbGRfb2Zmc2V0XyBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBubworICAvLyBVbmtub3duRmllbGRTZXQgaW4gdGhpcyBtZXNzYWdlLCBhbmQgdGhhdCBpbnN0ZWFkLCB3ZSBhcmUgdXNpbmcgdGhlCisgIC8vIFplcm8tT3ZlcmhlYWQgQXJlbmEgUG9pbnRlciB0cmljay4gV2hlbiB0aGlzIGlzIHRoZSBjYXNlLCBhcmVuYV9vZmZzZXRfCisgIC8vIGFjdHVhbGx5IGluZGV4ZXMgdG8gYW4gSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBpbnN0YW5jZSwgd2hpY2ggY2FuIHJldHVybgorICAvLyBlaXRoZXIgYW4gYXJlbmEgcG9pbnRlciBvciBhbiBVbmtub3duRmllbGRTZXQgb3IgYm90aC4gSXQgaXMgbmV2ZXIgdGhlIGNhc2UKKyAgLy8gdGhhdCB1bmtub3duX2ZpZWxkX29mZnNldF8gPT0ga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEgJiYgYXJlbmFfb2Zmc2V0XworICAvLyA9PSBrTm9BcmVuYVBvaW50ZXIuCisgIHN0YXRpYyBjb25zdCBpbnQga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEgPSAtMTsKKworIHByb3RlY3RlZDoKKyAgdmlydHVhbCB2b2lkKiBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZCgKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSwKKyAgICAgIGludCBjdHlwZSwgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3Q7CisKKyAgdmlydHVhbCBNZXNzYWdlRmFjdG9yeSogR2V0TWVzc2FnZUZhY3RvcnkoKSBjb25zdDsKKworICB2aXJ0dWFsIHZvaWQqIFJlcGVhdGVkRmllbGREYXRhKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSwKKyAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSkgY29uc3Q7CisKKyBwcml2YXRlOgorICBmcmllbmQgY2xhc3MgR2VuZXJhdGVkTWVzc2FnZTsKKworICAvLyBUbyBwYXJzZSBkaXJlY3RseSBpbnRvIGEgcHJvdG8yIGdlbmVyYXRlZCBjbGFzcywgdGhlIGNsYXNzIEdNUl9IYW5kbGVycworICAvLyBuZWVkcyBhY2Nlc3MgdG8gbWVtYmVyIG9mZnNldHMgYW5kIGhhc2JpdHMuCisgIGZyaWVuZCBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgdXBiOjpnb29nbGVfb3BlbnNvdXJjZTo6R01SX0hhbmRsZXJzOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2luc3RhbmNlXzsKKyAgY29uc3Qgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV87CisgIGNvbnN0IGludCogb2Zmc2V0c187CisKKyAgaW50IGhhc19iaXRzX29mZnNldF87CisgIGludCBvbmVvZl9jYXNlX29mZnNldF87CisgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXRfOworICBpbnQgZXh0ZW5zaW9uc19vZmZzZXRfOworICBpbnQgYXJlbmFfb2Zmc2V0XzsKKyAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0XzsKKyAgaW50IG9iamVjdF9zaXplXzsKKworICBzdGF0aWMgY29uc3QgaW50IGtIYXNOb0RlZmF1bHRJbnN0YW5jZUZpZWxkID0gLTE7CisKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIGRlc2NyaXB0b3JfcG9vbF87CisgIE1lc3NhZ2VGYWN0b3J5KiBtZXNzYWdlX2ZhY3RvcnlfOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgY29uc3QgVHlwZSYgR2V0UmF3KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgVHlwZSogTXV0YWJsZVJhdyhNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBjb25zdCBUeXBlJiBEZWZhdWx0UmF3KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIGNvbnN0IFR5cGUmIERlZmF1bHRPbmVvZlJhdyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICBpbmxpbmUgY29uc3QgdWludDMyKiBHZXRIYXNCaXRzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0OworICBpbmxpbmUgdWludDMyKiBNdXRhYmxlSGFzQml0cyhNZXNzYWdlKiBtZXNzYWdlKSBjb25zdDsKKyAgaW5saW5lIHVpbnQzMiBHZXRPbmVvZkNhc2UoCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdDsKKyAgaW5saW5lIHVpbnQzMiogTXV0YWJsZU9uZW9mQ2FzZSgKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2NyaXB0b3IpIGNvbnN0OworICBpbmxpbmUgY29uc3QgRXh0ZW5zaW9uU2V0JiBHZXRFeHRlbnNpb25TZXQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3Q7CisgIGlubGluZSBFeHRlbnNpb25TZXQqIE11dGFibGVFeHRlbnNpb25TZXQoTWVzc2FnZSogbWVzc2FnZSkgY29uc3Q7CisgIGlubGluZSBBcmVuYSogR2V0QXJlbmEoTWVzc2FnZSogbWVzc2FnZSkgY29uc3Q7CisgIGlubGluZSBjb25zdCBpbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSYKKyAgICAgIEdldEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3Q7CisgIGlubGluZSBpbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSoKKyAgICAgIE11dGFibGVJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0OworCisgIGlubGluZSBib29sIEdldElzRGVmYXVsdEluc3RhbmNlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0OworCisgIGlubGluZSBib29sIEhhc0JpdChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGlubGluZSB2b2lkIFNldEJpdChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGlubGluZSB2b2lkIENsZWFyQml0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbmxpbmUgdm9pZCBTd2FwQml0KE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIC8vIFRoaXMgZnVuY3Rpb24gb25seSBzd2FwcyB0aGUgZmllbGQuIFNob3VsZCBzd2FwIGNvcnJlc3BvbmRpbmcgaGFzX2JpdAorICAvLyBiZWZvcmUgb3IgYWZ0ZXIgdXNpbmcgdGhpcyBmdW5jdGlvbi4KKyAgdm9pZCBTd2FwRmllbGQoTWVzc2FnZSogbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICB2b2lkIFN3YXBPbmVvZkZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgaW5saW5lIGJvb2wgSGFzT25lb2ZGaWVsZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbmxpbmUgdm9pZCBTZXRPbmVvZkNhc2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbmxpbmUgdm9pZCBDbGVhck9uZW9mRmllbGQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgY29uc3QgVHlwZSYgR2V0RmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIHZvaWQgU2V0RmllbGQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgVHlwZSYgdmFsdWUpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIFR5cGUqIE11dGFibGVGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIGNvbnN0IFR5cGUmIEdldFJlcGVhdGVkRmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBjb25zdCBUeXBlJiBHZXRSZXBlYXRlZFB0ckZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgdm9pZCBTZXRSZXBlYXRlZEZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgdmFsdWUpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIFR5cGUqIE11dGFibGVSZXBlYXRlZEZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSB2b2lkIEFkZEZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGNvbnN0IFR5cGUmIHZhbHVlKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBUeXBlKiBBZGRGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgaW50IEdldEV4dGVuc2lvbk51bWJlck9yRGllKGNvbnN0IERlc2NyaXB0b3IqIHR5cGUpIGNvbnN0OworCisgIC8vIEludGVybmFsIHZlcnNpb25zIG9mIEVudW1WYWx1ZSBBUEkgcGVyZm9ybSBubyBjaGVja2luZy4gQ2FsbGVkIGFmdGVyIGNoZWNrcworICAvLyBieSBwdWJsaWMgbWV0aG9kcy4KKyAgdm9pZCBTZXRFbnVtVmFsdWVJbnRlcm5hbChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZEVudW1WYWx1ZUludGVybmFsKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRFbnVtVmFsdWVJbnRlcm5hbChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKworCisgIE1lc3NhZ2UqIFVuc2FmZUFyZW5hUmVsZWFzZU1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5ID0gTlVMTCkgY29uc3Q7CisKKyAgdm9pZCBVbnNhZmVBcmVuYVNldEFsbG9jYXRlZE1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbik7Cit9OworCisvLyBSZXR1cm5zIHRoZSBvZmZzZXQgb2YgdGhlIGdpdmVuIGZpZWxkIHdpdGhpbiB0aGUgZ2l2ZW4gYWdncmVnYXRlIHR5cGUuCisvLyBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gdGhlIEFOU0kgQyBvZmZzZXRvZigpIG1hY3JvLiAgSG93ZXZlciwgYWNjb3JkaW5nCisvLyB0byB0aGUgQysrIHN0YW5kYXJkLCBvZmZzZXRvZigpIG9ubHkgd29ya3Mgb24gUE9EIHR5cGVzLCBhbmQgR0NDCisvLyBlbmZvcmNlcyB0aGlzIHJlcXVpcmVtZW50IHdpdGggYSB3YXJuaW5nLiAgSW4gcHJhY3RpY2UsIHRoaXMgcnVsZSBpcworLy8gdW5uZWNlc3NhcmlseSBzdHJpY3Q7IHRoZXJlIGlzIHByb2JhYmx5IG5vIGNvbXBpbGVyIG9yIHBsYXRmb3JtIG9uCisvLyB3aGljaCB0aGUgb2Zmc2V0cyBvZiB0aGUgZGlyZWN0IGZpZWxkcyBvZiBhIGNsYXNzIGFyZSBub24tY29uc3RhbnQuCisvLyBGaWVsZHMgaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzICpjYW4qIGhhdmUgbm9uLWNvbnN0YW50IG9mZnNldHMsCisvLyBidXQgdGhhdCdzIG5vdCB3aGF0IHRoaXMgbWFjcm8gd2lsbCBiZSB1c2VkIGZvci4KKy8vCisvLyBOb3RlIHRoYXQgd2UgY2FsY3VsYXRlIHJlbGF0aXZlIHRvIHRoZSBwb2ludGVyIHZhbHVlIDE2IGhlcmUgc2luY2UgaWYgd2UKKy8vIGp1c3QgdXNlIHplcm8sIEdDQyBjb21wbGFpbnMgYWJvdXQgZGVyZWZlcmVuY2luZyBhIE5VTEwgcG9pbnRlci4gIFdlCisvLyBjaG9vc2UgMTYgcmF0aGVyIHRoYW4gc29tZSBvdGhlciBudW1iZXIganVzdCBpbiBjYXNlIHRoZSBjb21waWxlciB3b3VsZAorLy8gYmUgY29uZnVzZWQgYnkgYW4gdW5hbGlnbmVkIHBvaW50ZXIuCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVFlQRSwgRklFTEQpICAgIFwKKyAgc3RhdGljX2Nhc3Q8aW50PiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgJnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgVFlQRSo+KDE2KS0+RklFTEQpIC0gICAgICAgIFwKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KDE2KSkKKworI2RlZmluZSBQUk9UTzJfR0VORVJBVEVEX0RFRkFVTFRfT05FT0ZfRklFTERfT0ZGU0VUKE9ORU9GLCBGSUVMRCkgICAgIFwKKyAgc3RhdGljX2Nhc3Q8aW50PiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPigmKE9ORU9GLT5GSUVMRCkpICAgICAgICAgICAgICAgICAgXAorICAgICAgLSByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihPTkVPRikpCisKKy8vIFRoZXJlIGFyZSBzb21lIHBsYWNlcyBpbiBwcm90bzIgd2hlcmUgZHluYW1pY19jYXN0IHdvdWxkIGJlIHVzZWZ1bCBhcyBhbgorLy8gb3B0aW1pemF0aW9uLiAgRm9yIGV4YW1wbGUsIHRha2UgTWVzc2FnZTo6TWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2UmIG90aGVyKS4KKy8vIEZvciBhIGdpdmVuIGdlbmVyYXRlZCBtZXNzYWdlIEZvb01lc3NhZ2UsIHdlIGdlbmVyYXRlIHRoZXNlIHR3byBtZXRob2RzOgorLy8gICB2b2lkIE1lcmdlRnJvbShjb25zdCBGb29NZXNzYWdlJiBvdGhlcik7CisvLyAgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2UmIG90aGVyKTsKKy8vIFRoZSBmb3JtZXIgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBkaXJlY3RseSBpbiB0ZXJtcyBvZiBGb29NZXNzYWdlJ3MKKy8vIGlubGluZSBhY2Nlc3NvcnMsIGJ1dCB0aGUgbGF0dGVyIG1ldGhvZCBtdXN0IHdvcmsgd2l0aCB0aGUgcmVmbGVjdGlvbgorLy8gaW50ZXJmYWNlLiAgSG93ZXZlciwgaWYgdGhlIHBhcmFtZXRlciB0byB0aGUgbGF0dGVyIG1ldGhvZCBpcyBhY3R1YWxseSBvZgorLy8gdHlwZSBGb29NZXNzYWdlLCB0aGVuIHdlJ2QgbGlrZSB0byBiZSBhYmxlIHRvIGp1c3QgY2FsbCB0aGUgb3RoZXIgbWV0aG9kCisvLyBhcyBhbiBvcHRpbWl6YXRpb24uICBTbywgd2UgdXNlIGR5bmFtaWNfY2FzdCB0byBjaGVjayB0aGlzLgorLy8KKy8vIFRoYXQgc2FpZCwgZHluYW1pY19jYXN0IHJlcXVpcmVzIFJUVEksIHdoaWNoIG1hbnkgcGVvcGxlIGxpa2UgdG8gZGlzYWJsZQorLy8gZm9yIHBlcmZvcm1hbmNlIGFuZCBjb2RlIHNpemUgcmVhc29ucy4gIFdoZW4gUlRUSSBpcyBub3QgYXZhaWxhYmxlLCB3ZQorLy8gc3RpbGwgbmVlZCB0byBwcm9kdWNlIGNvcnJlY3QgcmVzdWx0cy4gIFNvLCBpbiB0aGlzIGNhc2Ugd2UgaGF2ZSB0byBmYWxsCisvLyBiYWNrIHRvIHVzaW5nIHJlZmxlY3Rpb24sIHdoaWNoIGlzIHdoYXQgd2Ugd291bGQgaGF2ZSBkb25lIGFueXdheSBpZiB0aGUKKy8vIG9iamVjdHMgd2VyZSBub3Qgb2YgdGhlIGV4YWN0IHNhbWUgY2xhc3MuCisvLworLy8gZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZSgpIGltcGxlbWVudHMgdGhpcyBsb2dpYy4gIElmIFJUVEkgaXMKKy8vIGVuYWJsZWQsIGl0IGRvZXMgYSBkeW5hbWljX2Nhc3QuICBJZiBSVFRJIGlzIGRpc2FibGVkLCBpdCBqdXN0IHJldHVybnMKKy8vIE5VTEwuCisvLworLy8gSWYgeW91IG5lZWQgdG8gY29tcGlsZSB3aXRob3V0IFJUVEksIHNpbXBseSAjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9OT19SVFRJLgorLy8gT24gTVNWQywgdGhpcyBzaG91bGQgYmUgZGV0ZWN0ZWQgYXV0b21hdGljYWxseS4KK3RlbXBsYXRlPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgoraW5saW5lIFRvIGR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGUoRnJvbSBmcm9tKSB7CisjaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSkgfHwgKGRlZmluZWQoX01TQ19WRVIpJiYhZGVmaW5lZChfQ1BQUlRUSSkpCisgIHJldHVybiBOVUxMOworI2Vsc2UKKyAgcmV0dXJuIGR5bmFtaWNfY2FzdDxUbz4oZnJvbSk7CisjZW5kaWYKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfUkVGTEVDVElPTl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYTFhMjkxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNzk1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVG8gdGVzdCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiwgd2UgYWN0dWFsbHkgbGV0IHRoZSBwcm90b2NvbCBjb21waWxlcgorLy8gZ2VuZXJhdGUgYSBmdWxsIHByb3RvY29sIG1lc3NhZ2UgaW1wbGVtZW50YXRpb24gYW5kIHRoZW4gdGVzdCBpdHMKKy8vIHJlZmxlY3Rpb24gaW50ZXJmYWNlLiAgVGhpcyBpcyBtdWNoIGVhc2llciBhbmQgbW9yZSBtYWludGFpbmFibGUgdGhhbgorLy8gdHJ5aW5nIHRvIGNyZWF0ZSBvdXIgb3duIE1lc3NhZ2UgY2xhc3MgZm9yIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uCisvLyB0byB3cmFwLgorLy8KKy8vIFRoZSB0ZXN0cyBoZXJlIGNsb3NlbHkgbWlycm9yIHNvbWUgb2YgdGhlIHRlc3RzIGluCisvLyBjb21waWxlci9jcHAvdW5pdHRlc3QsIGV4Y2VwdCB1c2luZyB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UKKy8vIHJhdGhlciB0aGFuIGdlbmVyYXRlZCBhY2Nlc3NvcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSB7CisKKy8vIFNob3J0aGFuZCB0byBnZXQgYSBGaWVsZERlc2NyaXB0b3IgZm9yIGEgZmllbGQgb2YgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcy4KK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogRihjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKG5hbWUpOworICBHT09HTEVfQ0hFQ0socmVzdWx0ICE9IE5VTEwpOworICByZXR1cm4gcmVzdWx0OworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgRGVmYXVsdHMpIHsKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZGVmYXVsdCB2YWx1ZXMgYXJlIHNldCBjb3JyZWN0bHkgaW4gdGhlIGluaXRpYWwgbWVzc2FnZS4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdENsZWFyVmlhUmVmbGVjdGlvbihtZXNzYWdlKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisKKyAgLy8gTWVzc2FnZXMgc2hvdWxkIHJldHVybiBwb2ludGVycyB0byBkZWZhdWx0IGluc3RhbmNlcyB1bnRpbCBmaXJzdCB1c2UuCisgIC8vIChUaGlzIGlzIG5vdCBjaGVja2VkIGJ5IEV4cGVjdENsZWFyKCkgc2luY2UgaXQgaXMgbm90IGFjdHVhbGx5IHRydWUgYWZ0ZXIKKyAgLy8gdGhlIGZpZWxkcyBoYXZlIGJlZW4gc2V0IGFuZCB0aGVuIGNsZWFyZWQuKQorICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok9wdGlvbmFsR3JvdXA6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsZ3JvdXAiKSkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9FUSgmdW5pdHRlc3RfaW1wb3J0OjpJbXBvcnRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBBY2Nlc3NvcnMpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlIHRoZW4gZ28gYmFjayBhbmQgY2hlY2sgYWxsIHRob3NlCisgIC8vIHZhbHVlcy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLk1vZGlmeVJlcGVhdGVkRmllbGRzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RSZXBlYXRlZEZpZWxkc01vZGlmaWVkKG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgR2V0U3RyaW5nUmVmZXJlbmNlKSB7CisgIC8vIFRlc3QgdGhhdCBHZXRTdHJpbmdSZWZlcmVuY2UoKSByZXR1cm5zIHRoZSB1bmRlcmx5aW5nIHN0cmluZyB3aGVuIGl0IGlzCisgIC8vIGEgbm9ybWFsIHN0cmluZyBmaWVsZC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zdHJpbmcoImZvbyIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoImZvbyIpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgc3RyaW5nIHNjcmF0Y2g7CisKKyAgRVhQRUNUX0VRKCZtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpLAorICAgICAgJnJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciKSwgJnNjcmF0Y2gpKQorICAgIDw8ICJGb3Igc2ltcGxlIHN0cmluZyBmaWVsZHMsIEdldFN0cmluZ1JlZmVyZW5jZSgpIHNob3VsZCByZXR1cm4gYSAiCisgICAgICAgInJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBzdHJpbmcuIjsKKyAgRVhQRUNUX0VRKCZtZXNzYWdlLnJlcGVhdGVkX3N0cmluZygwKSwKKyAgICAgICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAmc2NyYXRjaCkpCisgICAgPDwgIkZvciBzaW1wbGUgc3RyaW5nIGZpZWxkcywgR2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoKSBzaG91bGQgcmV0dXJuICIKKyAgICAgICAiYSByZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgc3RyaW5nLiI7Cit9CisKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIERlZmF1bHRzQWZ0ZXJDbGVhcikgeworICAvLyBDaGVjayB0aGF0IGFmdGVyIHNldHRpbmcgYWxsIGZpZWxkcyBhbmQgdGhlbiBjbGVhcmluZywgZ2V0dGluZyBhbgorICAvLyBlbWJlZGRlZCBtZXNzYWdlIGRvZXMgTk9UIHJldHVybiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIEVYUEVDVF9ORSgmdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6T3B0aW9uYWxHcm91cDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxncm91cCIpKSk7CisgIEVYUEVDVF9ORSgmdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdF9pbXBvcnQ6OkltcG9ydE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIikpKTsKK30KKworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFN3YXBXaXRoQm90aFNldCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6TW9kaWZ5UmVwZWF0ZWRGaWVsZHMoJm1lc3NhZ2UyKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZChtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworCisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF9pbnQzMig1MzI4MTkpOworCisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIEVYUEVDVF9FUSg1MzI4MTksIG1lc3NhZ2UyLm9wdGlvbmFsX2ludDMyKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcEV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UxKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcFVua25vd24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIG1lc3NhZ2UxLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEyMzQsIDEpOworCisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlMS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZTIudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+U3dhcCgmbWVzc2FnZTEsICZtZXNzYWdlMik7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlMS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTIudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFN3YXBGaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF9kb3VibGUoMTIuMyk7CisgIG1lc3NhZ2UxLm11dGFibGVfcmVwZWF0ZWRfaW50MzIoKS0+QWRkKDEwKTsKKyAgbWVzc2FnZTEubXV0YWJsZV9yZXBlYXRlZF9pbnQzMigpLT5BZGQoMjApOworCisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9zdHJpbmcoImhlbGxvIik7CisgIG1lc3NhZ2UyLm11dGFibGVfcmVwZWF0ZWRfaW50NjQoKS0+QWRkKDMwKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZTEuR2V0RGVzY3JpcHRvcigpOworICBmaWVsZHMucHVzaF9iYWNrKGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfZG91YmxlIikpOworICBmaWVsZHMucHVzaF9iYWNrKGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW50MzIiKSk7CisgIGZpZWxkcy5wdXNoX2JhY2soZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9zdHJpbmciKSk7CisgIGZpZWxkcy5wdXNoX2JhY2soZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF91aW50NjQiKSk7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+U3dhcEZpZWxkcygmbWVzc2FnZTEsICZtZXNzYWdlMiwgZmllbGRzKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZTEuaGFzX29wdGlvbmFsX2RvdWJsZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UxLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UxLmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBtZXNzYWdlMS5vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlMS5yZXBlYXRlZF9pbnQ2NF9zaXplKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZTEuaGFzX29wdGlvbmFsX3VpbnQ2NCgpKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfb3B0aW9uYWxfZG91YmxlKCkpOworICBFWFBFQ1RfRVEoMTIuMywgbWVzc2FnZTIub3B0aW9uYWxfZG91YmxlKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZTIucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtZXNzYWdlMi5yZXBlYXRlZF9pbnQzMigwKSk7CisgIEVYUEVDVF9FUSgyMCwgbWVzc2FnZTIucmVwZWF0ZWRfaW50MzIoMSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZTIuaGFzX29wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UyLnJlcGVhdGVkX2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMi5oYXNfb3B0aW9uYWxfdWludDY0KCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcEZpZWxkc0FsbCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UyKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UyLCAmZmllbGRzKTsKKyAgcmVmbGVjdGlvbi0+U3dhcEZpZWxkcygmbWVzc2FnZTEsICZtZXNzYWdlMiwgZmllbGRzKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdENsZWFyKG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFN3YXBGaWVsZHNBbGxFeHRlbnNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UxKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UxLCAmZmllbGRzKTsKKyAgcmVmbGVjdGlvbi0+U3dhcEZpZWxkcygmbWVzc2FnZTEsICZtZXNzYWdlMiwgZmllbGRzKTsKKworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcE9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZTEpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZkNsZWFyKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MShtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwT25lb2ZCb3RoU2V0KSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZTEpOworICBUZXN0VXRpbDo6U2V0T25lb2YyKCZtZXNzYWdlMik7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+U3dhcCgmbWVzc2FnZTEsICZtZXNzYWdlMik7CisKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZlNldDEobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcEZpZWxkc09uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZTEpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRzLnB1c2hfYmFjayhkZXNjcmlwdG9yLT5maWVsZChpKSk7CisgIH0KKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+U3dhcEZpZWxkcygmbWVzc2FnZTEsICZtZXNzYWdlMiwgZmllbGRzKTsKKworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZDbGVhcihtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZlNldDEobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgUmVtb3ZlTGFzdCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuUmVtb3ZlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RMYXN0UmVwZWF0ZWRzUmVtb3ZlZChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFJlbW92ZUxhc3RFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM6OmRlc2NyaXB0b3IoKSk7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlJlbW92ZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKworICBUZXN0VXRpbDo6RXhwZWN0TGFzdFJlcGVhdGVkRXh0ZW5zaW9uc1JlbW92ZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBSZWxlYXNlTGFzdCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoZGVzY3JpcHRvcik7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuUmVsZWFzZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlLCBmYWxzZSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZHNSZWxlYXNlZChtZXNzYWdlKTsKKworICAvLyBOb3cgdGVzdCB0aGF0IHdlIGFjdHVhbGx5IHJlbGVhc2UgdGhlIHJpZ2h0IG1lc3NhZ2UuCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworICBjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UqIGV4cGVjdGVkID0KKyAgICAgIG1lc3NhZ2UubXV0YWJsZV9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMSk7CisgIHNjb3BlZF9wdHI8TWVzc2FnZT4gcmVsZWFzZWQobWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgICAgJm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLCByZWxlYXNlZC5nZXQoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBSZWxlYXNlTGFzdEV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoZGVzY3JpcHRvcik7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlJlbGVhc2VMYXN0UmVwZWF0ZWRzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSwgdHJ1ZSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZEV4dGVuc2lvbnNSZWxlYXNlZChtZXNzYWdlKTsKKworICAvLyBOb3cgdGVzdCB0aGF0IHdlIGFjdHVhbGx5IHJlbGVhc2UgdGhlIHJpZ2h0IG1lc3NhZ2UuCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKAorICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgY29uc3QgcHJvdG9idWZfdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiBleHBlY3RlZCA9IG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLCAxKTsKKyAgc2NvcGVkX3B0cjxNZXNzYWdlPiByZWxlYXNlZChtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgICAmbWVzc2FnZSwgZGVzY3JpcHRvci0+ZmlsZSgpLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKAorICAgICAgICAgICJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uIikpKTsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLCByZWxlYXNlZC5nZXQoKSk7CisKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFN3YXBSZXBlYXRlZEVsZW1lbnRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKworICAvLyBTd2FwIGFuZCB0ZXN0IHRoYXQgZmllbGRzIGFyZSBhbGwgc3dhcHBlZC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU3dhcFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRzU3dhcHBlZChtZXNzYWdlKTsKKworICAvLyBTd2FwIGJhY2sgYW5kIHRlc3QgdGhhdCBmaWVsZHMgYXJlIGFsbCBiYWNrIHRvIG9yaWdpbmFsIHZhbHVlcy4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU3dhcFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcFJlcGVhdGVkRWxlbWVudHNFeHRlbnNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgLy8gU3dhcCBhbmQgdGVzdCB0aGF0IGZpZWxkcyBhcmUgYWxsIHN3YXBwZWQuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlN3YXBSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRXh0ZW5zaW9uc1N3YXBwZWQobWVzc2FnZSk7CisKKyAgLy8gU3dhcCBiYWNrIGFuZCB0ZXN0IHRoYXQgZmllbGRzIGFyZSBhbGwgYmFjayB0byBvcmlnaW5hbCB2YWx1ZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlN3YXBSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBFeHRlbnNpb25zKSB7CisgIC8vIFNldCBldmVyeSBleHRlbnNpb24gdG8gYSB1bmlxdWUgdmFsdWUgdGhlbiBnbyBiYWNrIGFuZCBjaGVjayBhbGwgdGhvc2UKKyAgLy8gdmFsdWVzLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCkpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbihtZXNzYWdlKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5Nb2RpZnlSZXBlYXRlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBGaW5kRXh0ZW5zaW9uVHlwZUJ5TnVtYmVyKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpLkdldFJlZmxlY3Rpb24oKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbjEgPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUoCisgICAgICAib3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uMiA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+RmluZEV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgICJyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uIik7CisKKyAgRVhQRUNUX0VRKGV4dGVuc2lvbjEsCisgICAgICAgICAgICByZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihleHRlbnNpb24xLT5udW1iZXIoKSkpOworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uMiwKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TnVtYmVyKGV4dGVuc2lvbjItPm51bWJlcigpKSk7CisKKyAgLy8gTm9uLWV4aXN0ZW50IGV4dGVuc2lvbi4KKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIoNjIzNDEpID09IE5VTEwpOworCisgIC8vIEV4dGVuc2lvbnMgb2YgVGVzdEFsbEV4dGVuc2lvbnMgc2hvdWxkIG5vdCBzaG93IHVwIGFzIGV4dGVuc2lvbnMgb2YKKyAgLy8gb3RoZXIgdHlwZXMuCisgIEVYUEVDVF9UUlVFKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgICAgICAgICBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihleHRlbnNpb24xLT5udW1iZXIoKSkgPT0gTlVMTCk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBGaW5kS25vd25FeHRlbnNpb25CeU5hbWUpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0UmVmbGVjdGlvbigpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uMSA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+RmluZEV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgICJvcHRpb25hbF9pbnQzMl9leHRlbnNpb24iKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24yID0KKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKAorICAgICAgInJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24iKTsKKworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uMSwKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZShleHRlbnNpb24xLT5mdWxsX25hbWUoKSkpOworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uMiwKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZShleHRlbnNpb24yLT5mdWxsX25hbWUoKSkpOworCisgIC8vIE5vbi1leGlzdGVudCBleHRlbnNpb24uCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgibm9fc3VjaF9leHQiKSA9PSBOVUxMKTsKKworICAvLyBFeHRlbnNpb25zIG9mIFRlc3RBbGxFeHRlbnNpb25zIHNob3VsZCBub3Qgc2hvdyB1cCBhcyBleHRlbnNpb25zIG9mCisgIC8vIG90aGVyIHR5cGVzLgorICBFWFBFQ1RfVFJVRSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0UmVmbGVjdGlvbigpLT4KKyAgICAgICAgICAgICAgRmluZEtub3duRXh0ZW5zaW9uQnlOYW1lKGV4dGVuc2lvbjEtPmZ1bGxfbmFtZSgpKSA9PSBOVUxMKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFNldEFsbG9jYXRlZE1lc3NhZ2VUZXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgZnJvbV9tZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBmcm9tX21lc3NhZ2UyOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHRvX21lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJmZyb21fbWVzc2FnZTEpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKCZmcm9tX21lc3NhZ2UyKTsKKworICAvLyBCZWZvcmUgbW92aW5nIGZpZWxkcywgd2UgZXhwZWN0IHRoZSBuZXN0ZWQgbWVzc2FnZXMgdG8gYmUgTlVMTC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmdG9fbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworCisgIC8vIEFmdGVyIGZpZWxkcyBhcmUgbW92ZWQgd2Ugc2hvdWxkIGdldCBub24tTlVMTCByZWxlYXNlcy4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICAgICZmcm9tX21lc3NhZ2UxLCAmdG9fbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpOT1RfTlVMTCk7CisKKyAgLy8gQW5vdGhlciBtb3ZlIHRvIG1ha2Ugc3VyZSB0aGF0IHdlIGNhbiBTZXRBbGxvY2F0ZWQgc2V2ZXJhbCB0aW1lcy4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICAgICZmcm9tX21lc3NhZ2UyLCAmdG9fbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpOT1RfTlVMTCk7CisKKyAgLy8gQWZ0ZXIgU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9OdWxsVmlhUmVmbGVjdGlvbigpIHdlIGV4cGVjdCB0aGUKKyAgLy8gcmVsZWFzZXMgdG8gYmUgTlVMTCBhZ2Fpbi4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9OdWxsVmlhUmVmbGVjdGlvbigKKyAgICAgICZ0b19tZXNzYWdlKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmdG9fbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uTWVzc2FnZVRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIGZyb21fbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBmcm9tX21lc3NhZ2UyOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgdG9fbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKCZmcm9tX21lc3NhZ2UxKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbigmZnJvbV9tZXNzYWdlMik7CisKKyAgLy8gQmVmb3JlIG1vdmluZyBmaWVsZHMsIHdlIGV4cGVjdCB0aGUgbmVzdGVkIG1lc3NhZ2VzIHRvIGJlIE5VTEwuCisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpJU19OVUxMKTsKKworICAvLyBBZnRlciBmaWVsZHMgYXJlIG1vdmVkIHdlIHNob3VsZCBnZXQgbm9uLU5VTEwgcmVsZWFzZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAmZnJvbV9tZXNzYWdlMSwgJnRvX21lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZ0b19tZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFub3RoZXIgbW92ZSB0byBtYWtlIHN1cmUgdGhhdCB3ZSBjYW4gU2V0QWxsb2NhdGVkIHNldmVyYWwgdGltZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAmZnJvbV9tZXNzYWdlMiwgJnRvX21lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZ0b19tZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFmdGVyIFNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oKSB3ZSBleHBlY3QgdGhlCisgIC8vIHJlbGVhc2VzIHRvIGJlIE5VTEwgYWdhaW4uCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oCisgICAgICAmdG9fbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpJU19OVUxMKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIExpc3RGaWVsZHNPbmVPZikgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZSwgJmZpZWxkcyk7CisgIEVYUEVDVF9FUSg0LCBmaWVsZHMuc2l6ZSgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIE9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIENoZWNrIGRlZmF1bHQgdmFsdWVzLgorICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+R2V0SW50MzIoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX3N0cmluZyIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCIiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19ieXRlcyIpKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PLCByZWZsZWN0aW9uLT5HZXRFbnVtKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fZW51bSIpKS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpUZXN0T25lb2YyOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rm9vR3JvdXA6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgICAgICAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vZ3JvdXAiKSkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGb29Hcm91cDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKDUsIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfaW50IikpKTsKKyAgRVhQRUNUX0VRKCJTVFJJTkciLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoIkNPUkQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIikpKTsKKyAgRVhQRUNUX0VRKCJTUElFQ0UiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmdfcGllY2UiKSkpOworICBFWFBFQ1RfRVEoIkJZVEVTIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfYnl0ZXMiKSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkJBUiwgcmVmbGVjdGlvbi0+R2V0RW51bSgKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX2VudW0iKSktPm51bWJlcigpKTsKKworICAvLyBDaGVjayBTZXQgZnVuY3Rpb25zLgorICByZWZsZWN0aW9uLT5TZXRJbnQzMigKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSwgMTIzKTsKKyAgRVhQRUNUX0VRKDEyMywgcmVmbGVjdGlvbi0+R2V0SW50MzIoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSkpOworICByZWZsZWN0aW9uLT5TZXRTdHJpbmcoCisgICAgICAmbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fc3RyaW5nIiksICJhYmMiKTsKKyAgRVhQRUNUX0VRKCJhYmMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19zdHJpbmciKSkpOworICByZWZsZWN0aW9uLT5TZXRTdHJpbmcoCisgICAgICAmbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fYnl0ZXMiKSwgImJ5dGVzIik7CisgIEVYUEVDVF9FUSgiYnl0ZXMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19ieXRlcyIpKSk7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZygKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIiksICJjaGFuZ2VfY29yZCIpOworICBFWFBFQ1RfRVEoImNoYW5nZV9jb3JkIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZygKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmdfcGllY2UiKSwKKyAgICAgICJjaGFuZ2Vfc3BpZWNlIik7CisgIEVYUEVDVF9FUSgiY2hhbmdlX3NwaWVjZSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX3N0cmluZ19waWVjZSIpKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTZXRBbGxvY2F0ZWRPbmVvZk1lc3NhZ2VUZXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIGZyb21fbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIGZyb21fbWVzc2FnZTI7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIHRvX21lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6ZGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gdG9fbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisKKyAgTWVzc2FnZSogcmVsZWFzZWQgPSByZWZsZWN0aW9uLT5SZWxlYXNlTWVzc2FnZSgKKyAgICAgICZ0b19tZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkID09IE5VTEwpOworICByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJnRvX21lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkID09IE5VTEwpOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTZXRPbmVvZlZpYVJlZmxlY3Rpb24oJmZyb21fbWVzc2FnZTEpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0T25lb2ZTZXRWaWFSZWZsZWN0aW9uKGZyb21fbWVzc2FnZTEpOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjoKKyAgICAgIFNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAgICAgJmZyb21fbWVzc2FnZTEsICZ0b19tZXNzYWdlKTsKKyAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgdG9fbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpOworICByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJnRvX21lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX1RSVUUocmVsZWFzZWQgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgmc3ViX21lc3NhZ2UsIHJlbGVhc2VkKTsKKyAgZGVsZXRlIHJlbGVhc2VkOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTZXRPbmVvZlZpYVJlZmxlY3Rpb24oJmZyb21fbWVzc2FnZTIpOworCisgIHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKAorICAgICAgJmZyb21fbWVzc2FnZTIsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX21lc3NhZ2UiKSk7CisKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OgorICAgICAgU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICAgICAgICAmZnJvbV9tZXNzYWdlMiwgJnRvX21lc3NhZ2UpOworCisgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlMiA9IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICB0b19tZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19tZXNzYWdlIikpOworICByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJnRvX21lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkICE9IE5VTEwpOworICBFWFBFQ1RfRVEoJnN1Yl9tZXNzYWdlMiwgcmVsZWFzZWQpOworICBkZWxldGUgcmVsZWFzZWQ7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBSZWxlYXNlTWVzc2FnZVRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpOworCisgIC8vIFdoZW4gbm90aGluZyBpcyBzZXQsIHdlIGV4cGVjdCBhbGwgcmVsZWFzZWQgbWVzc2FnZXMgdG8gYmUgTlVMTC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworCisgIC8vIEFmdGVyIGZpZWxkcyBhcmUgc2V0IHdlIHNob3VsZCBnZXQgbm9uLU5VTEwgcmVsZWFzZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZtZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFmdGVyIENsZWFyKCkgd2UgbWF5IG9yIG1heSBub3QgZ2V0IGEgbWVzc2FnZSBmcm9tIFJlbGVhc2VNZXNzYWdlKCkuCisgIC8vIFRoaXMgaXMgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJm1lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpDQU5fQkVfTlVMTCk7CisKKyAgLy8gVGVzdCBhIGRpZmZlcmVudCBjb2RlIHBhdGggZm9yIHNldHRpbmcgYWZ0ZXIgcmVsZWFzaW5nLgorICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFJlbGVhc2VFeHRlbnNpb25NZXNzYWdlVGVzdCkgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCkpOworCisgIC8vIFdoZW4gbm90aGluZyBpcyBzZXQsIHdlIGV4cGVjdCBhbGwgcmVsZWFzZWQgbWVzc2FnZXMgdG8gYmUgTlVMTC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworCisgIC8vIEFmdGVyIGZpZWxkcyBhcmUgc2V0IHdlIHNob3VsZCBnZXQgbm9uLU5VTEwgcmVsZWFzZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZtZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFmdGVyIENsZWFyKCkgd2UgbWF5IG9yIG1heSBub3QgZ2V0IGEgbWVzc2FnZSBmcm9tIFJlbGVhc2VNZXNzYWdlKCkuCisgIC8vIFRoaXMgaXMgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJm1lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpDQU5fQkVfTlVMTCk7CisKKyAgLy8gVGVzdCBhIGRpZmZlcmVudCBjb2RlIHBhdGggZm9yIHNldHRpbmcgYWZ0ZXIgcmVsZWFzaW5nLgorICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgUmVsZWFzZU9uZW9mTWVzc2FnZVRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OlNldE9uZW9mVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpkZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpOworICBNZXNzYWdlKiByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKTsKKworICBFWFBFQ1RfVFJVRShyZWxlYXNlZCAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCZzdWJfbWVzc2FnZSwgcmVsZWFzZWQpOworICBkZWxldGUgcmVsZWFzZWQ7CisKKyAgcmVsZWFzZWQgPSByZWZsZWN0aW9uLT5SZWxlYXNlTWVzc2FnZSgKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkID09IE5VTEwpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFVzYWdlRXJyb3JzKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyNkZWZpbmUgZihOQU1FKSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoTkFNRSkKKworICAvLyBUZXN0aW5nIGV2ZXJ5IHNpbmdsZSBmYWlsdXJlIG1vZGUgd291bGQgYmUgdG9vIG11Y2ggd29yay4gIExldCdzIGp1c3QKKyAgLy8gY2hlY2sgYSBmZXcuCisgIEVYUEVDVF9ERUFUSCgKKyAgICByZWZsZWN0aW9uLT5HZXRJbnQzMigKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50NjQiKSksCisgICAgIlByb3RvY29sIEJ1ZmZlciByZWZsZWN0aW9uIHVzYWdlIGVycm9yOlxuIgorICAgICIgIE1ldGhvZCAgICAgIDogZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbjo6R2V0SW50MzJcbiIKKyAgICAiICBNZXNzYWdlIHR5cGU6IHByb3RvYnVmX3VuaXR0ZXN0XFwuVGVzdEFsbFR5cGVzXG4iCisgICAgIiAgRmllbGQgICAgICAgOiBwcm90b2J1Zl91bml0dGVzdFxcLlRlc3RBbGxUeXBlc1xcLm9wdGlvbmFsX2ludDY0XG4iCisgICAgIiAgUHJvYmxlbSAgICAgOiBGaWVsZCBpcyBub3QgdGhlIHJpZ2h0IHR5cGUgZm9yIHRoaXMgbWVzc2FnZTpcbiIKKyAgICAiICAgIEV4cGVjdGVkICA6IENQUFRZUEVfSU5UMzJcbiIKKyAgICAiICAgIEZpZWxkIHR5cGU6IENQUFRZUEVfSU5UNjQiKTsKKyAgRVhQRUNUX0RFQVRIKAorICAgIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpKSwKKyAgICAiUHJvdG9jb2wgQnVmZmVyIHJlZmxlY3Rpb24gdXNhZ2UgZXJyb3I6XG4iCisgICAgIiAgTWV0aG9kICAgICAgOiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uOjpHZXRJbnQzMlxuIgorICAgICIgIE1lc3NhZ2UgdHlwZTogcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXG4iCisgICAgIiAgRmllbGQgICAgICAgOiBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMucmVwZWF0ZWRfaW50MzJcbiIKKyAgICAiICBQcm9ibGVtICAgICA6IEZpZWxkIGlzIHJlcGVhdGVkOyB0aGUgbWV0aG9kIHJlcXVpcmVzIGEgc2luZ3VsYXIgZmllbGQuIik7CisgIEVYUEVDVF9ERUFUSCgKKyAgICByZWZsZWN0aW9uLT5HZXRJbnQzMigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImMiKSksCisgICAgIlByb3RvY29sIEJ1ZmZlciByZWZsZWN0aW9uIHVzYWdlIGVycm9yOlxuIgorICAgICIgIE1ldGhvZCAgICAgIDogZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbjo6R2V0SW50MzJcbiIKKyAgICAiICBNZXNzYWdlIHR5cGU6IHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1xuIgorICAgICIgIEZpZWxkICAgICAgIDogcHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UuY1xuIgorICAgICIgIFByb2JsZW0gICAgIDogRmllbGQgZG9lcyBub3QgbWF0Y2ggbWVzc2FnZSB0eXBlLiIpOworICBFWFBFQ1RfREVBVEgoCisgICAgcmVmbGVjdGlvbi0+SGFzRmllbGQoCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJjIikpLAorICAgICJQcm90b2NvbCBCdWZmZXIgcmVmbGVjdGlvbiB1c2FnZSBlcnJvcjpcbiIKKyAgICAiICBNZXRob2QgICAgICA6IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb246Okhhc0ZpZWxkXG4iCisgICAgIiAgTWVzc2FnZSB0eXBlOiBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcbiIKKyAgICAiICBGaWVsZCAgICAgICA6IHByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlLmNcbiIKKyAgICAiICBQcm9ibGVtICAgICA6IEZpZWxkIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKworI3VuZGVmIGYKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTNjYWU4YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5jYwpAQCAtMCwwICsxLDY2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorCisjaW5jbHVkZSA8bGltaXRzPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2RvdWJsZSBJbmZpbml0eSgpIHsKKyAgcmV0dXJuIHN0ZDo6bnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKTsKK30KK2RvdWJsZSBOYU4oKSB7CisgIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OnF1aWV0X05hTigpOworfQorCitjb25zdCA6OnN0ZDo6c3RyaW5nKiBlbXB0eV9zdHJpbmdfOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShlbXB0eV9zdHJpbmdfb25jZV9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlRW1wdHlTdHJpbmcoKSB7CisgIGRlbGV0ZSBlbXB0eV9zdHJpbmdfOworfQorCit2b2lkIEluaXRFbXB0eVN0cmluZygpIHsKKyAgZW1wdHlfc3RyaW5nXyA9IG5ldyBzdHJpbmc7CisgIE9uU2h1dGRvd24oJkRlbGV0ZUVtcHR5U3RyaW5nKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzhmOTJhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmgKQEAgLTAsMCArMSwxMTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgbWlzY2VsbGFuZW91cyBoZWxwZXIgY29kZSB1c2VkIGJ5IGdlbmVyYXRlZCBjb2RlIC0tCisvLyBpbmNsdWRpbmcgbGl0ZSB0eXBlcyAtLSBidXQgd2hpY2ggc2hvdWxkIG5vdCBiZSB1c2VkIGRpcmVjdGx5IGJ5IHVzZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9VVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfVVRJTF9IX18KKworI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKworLy8gQW5ub3RhdGlvbiBmb3IgdGhlIGNvbXBpbGVyIHRvIGVtaXQgYSBkZXByZWNhdGlvbiBtZXNzYWdlIGlmIGEgZmllbGQgbWFya2VkCisvLyB3aXRoIG9wdGlvbiAnZGVwcmVjYXRlZD10cnVlJyBpcyB1c2VkIGluIHRoZSBjb2RlLCBvciBmb3Igb3RoZXIgdGhpbmdzIGluCisvLyBnZW5lcmF0ZWQgY29kZSB3aGljaCBhcmUgZGVwcmVjYXRlZC4KKy8vCisvLyBGb3IgaW50ZXJuYWwgdXNlIGluIHRoZSBwYi5jYyBmaWxlcywgZGVwcmVjYXRpb24gd2FybmluZ3MgYXJlIHN1cHByZXNzZWQKKy8vIHRoZXJlLgorI3VuZGVmIERFUFJFQ0FURURfUFJPVE9CVUZfRklFTEQKKyNkZWZpbmUgUFJPVE9CVUZfREVQUkVDQVRFRAorCisKKy8vIENvbnN0YW50cyBmb3Igc3BlY2lhbCBmbG9hdGluZyBwb2ludCB2YWx1ZXMuCitMSUJQUk9UT0JVRl9FWFBPUlQgZG91YmxlIEluZmluaXR5KCk7CitMSUJQUk9UT0JVRl9FWFBPUlQgZG91YmxlIE5hTigpOworCisvLyBUT0RPKGppZWx1byk6IENoYW5nZSB0byB0ZW1wbGF0ZS4gV2UgaGF2ZSB0cmllZCB0byB1c2UgdGVtcGxhdGUsCisvLyBidXQgaXQgY2F1c2VzIG5ldC9ycGMvcHl0aG9uOnJwY3V0aWxfdGVzdCBmYWlsICh0aGUgZW1wdHkgc3RyaW5nIHdpbGwKKy8vIGluaXQgdHdpY2UpLiBJdCBtYXkgcmVsYXRlZCB0byBzd2lnLiBDaGFuZ2UgdG8gdGVtcGxhdGUgYWZ0ZXIgd2UKKy8vIGZvdW5kIHRoZSBzb2x1dGlvbi4KKworLy8gRGVmYXVsdCBlbXB0eSBzdHJpbmcgb2JqZWN0LiBEb24ndCB1c2UgdGhlIHBvaW50ZXIgZGlyZWN0bHkuIEluc3RlYWQsIGNhbGwKKy8vIEdldEVtcHR5U3RyaW5nKCkgdG8gZ2V0IHRoZSByZWZlcmVuY2UuCitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIGNvbnN0IDo6c3RkOjpzdHJpbmcqIGVtcHR5X3N0cmluZ187CitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIFByb3RvYnVmT25jZVR5cGUgZW1wdHlfc3RyaW5nX29uY2VfaW5pdF87CitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBJbml0RW1wdHlTdHJpbmcoKTsKKworCitMSUJQUk9UT0JVRl9FWFBPUlQgaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpIHsKKyAgYXNzZXJ0KGVtcHR5X3N0cmluZ18gIT0gTlVMTCk7CisgIHJldHVybiAqZW1wdHlfc3RyaW5nXzsKK30KK0xJQlBST1RPQlVGX0VYUE9SVCBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgR2V0RW1wdHlTdHJpbmcoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmVtcHR5X3N0cmluZ19vbmNlX2luaXRfLCAmSW5pdEVtcHR5U3RyaW5nKTsKKyAgcmV0dXJuIEdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpOworfQorCisvLyBEZWZpbmVkIGluIGdlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MgLS0gbm90IGFjdHVhbGx5IHBhcnQgb2YgdGhlIGxpdGUKKy8vIGxpYnJhcnkuCisvLworLy8gVE9ETyhqYXNvbmgpOiBUaGUgdmFyaW91cyBjYWxsZXJzIGdldCB0aGlzIGRlY2xhcmF0aW9uIGZyb20gYSB2YXJpZXR5IG9mCisvLyBwbGFjZXM6IHByb2JhYmx5IGluIG1vc3QgY2FzZXMgcmVwZWF0ZWRfZmllbGQuaC4gQ2xlYW4gdGhlc2UgdXAgc28gdGhleSBhbGwKKy8vIGdldCB0aGUgZGVjbGFyYXRpb24gZnJvbSB0aGlzIGZpbGUuCitMSUJQUk9UT0JVRl9FWFBPUlQgaW50IFN0cmluZ1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoY29uc3Qgc3RyaW5nJiBzdHIpOworCisKKy8vIFRydWUgaWYgSXNJbml0aWFsaXplZCgpIGlzIHRydWUgZm9yIGFsbCBlbGVtZW50cyBvZiB0LiAgVHlwZSBpcyBleHBlY3RlZAorLy8gdG8gYmUgYSBSZXBlYXRlZFB0ckZpZWxkPHNvbWUgbWVzc2FnZSB0eXBlPi4gIEl0J3MgdXNlZnVsIHRvIGhhdmUgdGhpcworLy8gaGVscGVyIGhlcmUgdG8ga2VlcCB0aGUgcHJvdG9idWYgY29tcGlsZXIgZnJvbSBldmVyIGhhdmluZyB0byBlbWl0IGxvb3BzIGluCisvLyBJc0luaXRpYWxpemVkKCkgbWV0aG9kcy4gIFdlIHdhbnQgdGhlIEMrKyBjb21waWxlciB0byBpbmxpbmUgdGhpcyBvciBub3QKKy8vIGFzIGl0IHNlZXMgZml0LgordGVtcGxhdGUgPGNsYXNzIFR5cGU+IGJvb2wgQWxsQXJlSW5pdGlhbGl6ZWQoY29uc3QgVHlwZSYgdCkgeworICBmb3IgKGludCBpID0gdC5zaXplKCk7IC0taSA+PSAwOyApIHsKKyAgICBpZiAoIXQuR2V0KGkpLklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2UxYTIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2MKQEAgLTAsMCArMSw4ODIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGhlYXZpbHkgb3B0aW1pemVkIHRvIG1ha2UgcmVhZHMgYW5kIHdyaXRlcworLy8gb2Ygc21hbGwgdmFsdWVzIChlc3BlY2lhbGx5IHZhcmludHMpIGFzIGZhc3QgYXMgcG9zc2libGUuICBJbgorLy8gcGFydGljdWxhciwgd2Ugb3B0aW1pemUgZm9yIHRoZSBjb21tb24gY2FzZSB0aGF0IGEgcmVhZCBvciBhIHdyaXRlCisvLyB3aWxsIG5vdCBjcm9zcyB0aGUgZW5kIG9mIHRoZSBidWZmZXIsIHNpbmNlIHdlIGNhbiBhdm9pZCBhIGxvdAorLy8gb2YgYnJhbmNoaW5nIGluIHRoaXMgY2FzZS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmg+CisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8bGltaXRzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworbmFtZXNwYWNlIHsKKworc3RhdGljIGNvbnN0IGludCBrTWF4VmFyaW50Qnl0ZXMgPSAxMDsKK3N0YXRpYyBjb25zdCBpbnQga01heFZhcmludDMyQnl0ZXMgPSA1OworCisKK2lubGluZSBib29sIE5leHROb25FbXB0eShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGJvb2wgc3VjY2VzczsKKyAgZG8geworICAgIHN1Y2Nlc3MgPSBpbnB1dC0+TmV4dChkYXRhLCBzaXplKTsKKyAgfSB3aGlsZSAoc3VjY2VzcyAmJiAqc2l6ZSA9PSAwKTsKKyAgcmV0dXJuIHN1Y2Nlc3M7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyBDb2RlZElucHV0U3RyZWFtID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvZGVkSW5wdXRTdHJlYW06On5Db2RlZElucHV0U3RyZWFtKCkgeworICBpZiAoaW5wdXRfICE9IE5VTEwpIHsKKyAgICBCYWNrVXBJbnB1dFRvQ3VycmVudFBvc2l0aW9uKCk7CisgIH0KKworICBpZiAodG90YWxfYnl0ZXNfd2FybmluZ190aHJlc2hvbGRfID09IC0yKSB7CisgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyByZWFkIHdhcyAiIDw8IHRvdGFsX2J5dGVzX3JlYWRfOworICB9Cit9CisKKy8vIFN0YXRpYy4KK2ludCBDb2RlZElucHV0U3RyZWFtOjpkZWZhdWx0X3JlY3Vyc2lvbl9saW1pdF8gPSAxMDA7CisKKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6RW5hYmxlQWxpYXNpbmcoYm9vbCBlbmFibGVkKSB7CisgIGFsaWFzaW5nX2VuYWJsZWRfID0gZW5hYmxlZCAmJiBvdXRwdXRfLT5BbGxvd3NBbGlhc2luZygpOworfQorCit2b2lkIENvZGVkSW5wdXRTdHJlYW06OkJhY2tVcElucHV0VG9DdXJyZW50UG9zaXRpb24oKSB7CisgIGludCBiYWNrdXBfYnl0ZXMgPSBCdWZmZXJTaXplKCkgKyBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gKyBvdmVyZmxvd19ieXRlc187CisgIGlmIChiYWNrdXBfYnl0ZXMgPiAwKSB7CisgICAgaW5wdXRfLT5CYWNrVXAoYmFja3VwX2J5dGVzKTsKKworICAgIC8vIHRvdGFsX2J5dGVzX3JlYWRfIGRvZXNuJ3QgaW5jbHVkZSBvdmVyZmxvd19ieXRlc18uCisgICAgdG90YWxfYnl0ZXNfcmVhZF8gLT0gQnVmZmVyU2l6ZSgpICsgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfOworICAgIGJ1ZmZlcl9lbmRfID0gYnVmZmVyXzsKKyAgICBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gPSAwOworICAgIG92ZXJmbG93X2J5dGVzXyA9IDA7CisgIH0KK30KKworaW5saW5lIHZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6UmVjb21wdXRlQnVmZmVyTGltaXRzKCkgeworICBidWZmZXJfZW5kXyArPSBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF87CisgIGludCBjbG9zZXN0X2xpbWl0ID0gbWluKGN1cnJlbnRfbGltaXRfLCB0b3RhbF9ieXRlc19saW1pdF8pOworICBpZiAoY2xvc2VzdF9saW1pdCA8IHRvdGFsX2J5dGVzX3JlYWRfKSB7CisgICAgLy8gVGhlIGxpbWl0IHBvc2l0aW9uIGlzIGluIHRoZSBjdXJyZW50IGJ1ZmZlci4gIFdlIG11c3QgYWRqdXN0CisgICAgLy8gdGhlIGJ1ZmZlciBzaXplIGFjY29yZGluZ2x5LgorICAgIGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XyA9IHRvdGFsX2J5dGVzX3JlYWRfIC0gY2xvc2VzdF9saW1pdDsKKyAgICBidWZmZXJfZW5kXyAtPSBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF87CisgIH0gZWxzZSB7CisgICAgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfID0gMDsKKyAgfQorfQorCitDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBDb2RlZElucHV0U3RyZWFtOjpQdXNoTGltaXQoaW50IGJ5dGVfbGltaXQpIHsKKyAgLy8gQ3VycmVudCBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJlYW0uCisgIGludCBjdXJyZW50X3Bvc2l0aW9uID0gQ3VycmVudFBvc2l0aW9uKCk7CisKKyAgTGltaXQgb2xkX2xpbWl0ID0gY3VycmVudF9saW1pdF87CisKKyAgLy8gc2VjdXJpdHk6IGJ5dGVfbGltaXQgaXMgcG9zc2libHkgZXZpbCwgc28gY2hlY2sgZm9yIG5lZ2F0aXZlIHZhbHVlcworICAvLyBhbmQgb3ZlcmZsb3cuCisgIGlmIChieXRlX2xpbWl0ID49IDAgJiYKKyAgICAgIGJ5dGVfbGltaXQgPD0gSU5UX01BWCAtIGN1cnJlbnRfcG9zaXRpb24pIHsKKyAgICBjdXJyZW50X2xpbWl0XyA9IGN1cnJlbnRfcG9zaXRpb24gKyBieXRlX2xpbWl0OworICB9IGVsc2UgeworICAgIC8vIE5lZ2F0aXZlIG9yIG92ZXJmbG93LgorICAgIGN1cnJlbnRfbGltaXRfID0gSU5UX01BWDsKKyAgfQorCisgIC8vIFdlIG5lZWQgdG8gZW5mb3JjZSBhbGwgbGltaXRzLCBub3QganVzdCB0aGUgbmV3IG9uZSwgc28gaWYgdGhlIHByZXZpb3VzCisgIC8vIGxpbWl0IHdhcyBiZWZvcmUgdGhlIG5ldyByZXF1ZXN0ZWQgbGltaXQsIHdlIGNvbnRpbnVlIHRvIGVuZm9yY2UgdGhlCisgIC8vIHByZXZpb3VzIGxpbWl0LgorICBjdXJyZW50X2xpbWl0XyA9IG1pbihjdXJyZW50X2xpbWl0Xywgb2xkX2xpbWl0KTsKKworICBSZWNvbXB1dGVCdWZmZXJMaW1pdHMoKTsKKyAgcmV0dXJuIG9sZF9saW1pdDsKK30KKwordm9pZCBDb2RlZElucHV0U3RyZWFtOjpQb3BMaW1pdChMaW1pdCBsaW1pdCkgeworICAvLyBUaGUgbGltaXQgcGFzc2VkIGluIGlzIGFjdHVhbGx5IHRoZSAqb2xkKiBsaW1pdCwgd2hpY2ggd2UgcmV0dXJuZWQgZnJvbQorICAvLyBQdXNoTGltaXQoKS4KKyAgY3VycmVudF9saW1pdF8gPSBsaW1pdDsKKyAgUmVjb21wdXRlQnVmZmVyTGltaXRzKCk7CisKKyAgLy8gV2UgbWF5IG5vIGxvbmdlciBiZSBhdCBhIGxlZ2l0aW1hdGUgbWVzc2FnZSBlbmQuICBSZWFkVGFnKCkgbmVlZHMgdG8gYmUKKyAgLy8gY2FsbGVkIGFnYWluIHRvIGZpbmQgb3V0LgorICBsZWdpdGltYXRlX21lc3NhZ2VfZW5kXyA9IGZhbHNlOworfQorCitzdGQ6OnBhaXI8Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQsIGludD4KK0NvZGVkSW5wdXRTdHJlYW06OkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoQW5kUHVzaExpbWl0KGludCBieXRlX2xpbWl0KSB7CisgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihQdXNoTGltaXQoYnl0ZV9saW1pdCksIC0tcmVjdXJzaW9uX2J1ZGdldF8pOworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoQW5kUG9wTGltaXQoTGltaXQgbGltaXQpIHsKKyAgYm9vbCByZXN1bHQgPSBDb25zdW1lZEVudGlyZU1lc3NhZ2UoKTsKKyAgUG9wTGltaXQobGltaXQpOworICBHT09HTEVfRENIRUNLX0xUKHJlY3Vyc2lvbl9idWRnZXRfLCByZWN1cnNpb25fbGltaXRfKTsKKyAgKytyZWN1cnNpb25fYnVkZ2V0XzsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW50IENvZGVkSW5wdXRTdHJlYW06OkJ5dGVzVW50aWxMaW1pdCgpIGNvbnN0IHsKKyAgaWYgKGN1cnJlbnRfbGltaXRfID09IElOVF9NQVgpIHJldHVybiAtMTsKKyAgaW50IGN1cnJlbnRfcG9zaXRpb24gPSBDdXJyZW50UG9zaXRpb24oKTsKKworICByZXR1cm4gY3VycmVudF9saW1pdF8gLSBjdXJyZW50X3Bvc2l0aW9uOworfQorCit2b2lkIENvZGVkSW5wdXRTdHJlYW06OlNldFRvdGFsQnl0ZXNMaW1pdCgKKyAgICBpbnQgdG90YWxfYnl0ZXNfbGltaXQsIGludCB3YXJuaW5nX3RocmVzaG9sZCkgeworICAvLyBNYWtlIHN1cmUgdGhlIGxpbWl0IGlzbid0IGFscmVhZHkgcGFzdCwgc2luY2UgdGhpcyBjb3VsZCBjb25mdXNlIG90aGVyCisgIC8vIGNvZGUuCisgIGludCBjdXJyZW50X3Bvc2l0aW9uID0gQ3VycmVudFBvc2l0aW9uKCk7CisgIHRvdGFsX2J5dGVzX2xpbWl0XyA9IG1heChjdXJyZW50X3Bvc2l0aW9uLCB0b3RhbF9ieXRlc19saW1pdCk7CisgIGlmICh3YXJuaW5nX3RocmVzaG9sZCA+PSAwKSB7CisgICAgdG90YWxfYnl0ZXNfd2FybmluZ190aHJlc2hvbGRfID0gd2FybmluZ190aHJlc2hvbGQ7CisgIH0gZWxzZSB7CisgICAgLy8gd2FybmluZ190aHJlc2hvbGQgaXMgbmVnYXRpdmUKKyAgICB0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8gPSAtMTsKKyAgfQorICBSZWNvbXB1dGVCdWZmZXJMaW1pdHMoKTsKK30KKworaW50IENvZGVkSW5wdXRTdHJlYW06OkJ5dGVzVW50aWxUb3RhbEJ5dGVzTGltaXQoKSBjb25zdCB7CisgIGlmICh0b3RhbF9ieXRlc19saW1pdF8gPT0gSU5UX01BWCkgcmV0dXJuIC0xOworICByZXR1cm4gdG90YWxfYnl0ZXNfbGltaXRfIC0gQ3VycmVudFBvc2l0aW9uKCk7Cit9CisKK3ZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6UHJpbnRUb3RhbEJ5dGVzTGltaXRFcnJvcigpIHsKKyAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkEgcHJvdG9jb2wgbWVzc2FnZSB3YXMgcmVqZWN0ZWQgYmVjYXVzZSBpdCB3YXMgdG9vICIKKyAgICAgICAgICAgICAgICAiYmlnIChtb3JlIHRoYW4gIiA8PCB0b3RhbF9ieXRlc19saW1pdF8KKyAgICAgICAgICAgICA8PCAiIGJ5dGVzKS4gIFRvIGluY3JlYXNlIHRoZSBsaW1pdCAob3IgdG8gZGlzYWJsZSB0aGVzZSAiCisgICAgICAgICAgICAgICAgIndhcm5pbmdzKSwgc2VlIENvZGVkSW5wdXRTdHJlYW06OlNldFRvdGFsQnl0ZXNMaW1pdCgpICIKKyAgICAgICAgICAgICAgICAiaW4gZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oLiI7Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgaWYgKGNvdW50IDwgMCkgcmV0dXJuIGZhbHNlOyAgLy8gc2VjdXJpdHk6IGNvdW50IGlzIG9mdGVuIHVzZXItc3VwcGxpZWQKKworICBjb25zdCBpbnQgb3JpZ2luYWxfYnVmZmVyX3NpemUgPSBCdWZmZXJTaXplKCk7CisKKyAgaWYgKGNvdW50IDw9IG9yaWdpbmFsX2J1ZmZlcl9zaXplKSB7CisgICAgLy8gSnVzdCBza2lwcGluZyB3aXRoaW4gdGhlIGN1cnJlbnQgYnVmZmVyLiAgRWFzeS4KKyAgICBBZHZhbmNlKGNvdW50KTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGlmIChidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gPiAwKSB7CisgICAgLy8gV2UgaGl0IGEgbGltaXQgaW5zaWRlIHRoaXMgYnVmZmVyLiAgQWR2YW5jZSB0byB0aGUgbGltaXQgYW5kIGZhaWwuCisgICAgQWR2YW5jZShvcmlnaW5hbF9idWZmZXJfc2l6ZSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgY291bnQgLT0gb3JpZ2luYWxfYnVmZmVyX3NpemU7CisgIGJ1ZmZlcl8gPSBOVUxMOworICBidWZmZXJfZW5kXyA9IGJ1ZmZlcl87CisKKyAgLy8gTWFrZSBzdXJlIHRoaXMgc2tpcCBkb2Vzbid0IHRyeSB0byBza2lwIHBhc3QgdGhlIGN1cnJlbnQgbGltaXQuCisgIGludCBjbG9zZXN0X2xpbWl0ID0gbWluKGN1cnJlbnRfbGltaXRfLCB0b3RhbF9ieXRlc19saW1pdF8pOworICBpbnQgYnl0ZXNfdW50aWxfbGltaXQgPSBjbG9zZXN0X2xpbWl0IC0gdG90YWxfYnl0ZXNfcmVhZF87CisgIGlmIChieXRlc191bnRpbF9saW1pdCA8IGNvdW50KSB7CisgICAgLy8gV2UgaGl0IHRoZSBsaW1pdC4gIFNraXAgdXAgdG8gaXQgdGhlbiBmYWlsLgorICAgIGlmIChieXRlc191bnRpbF9saW1pdCA+IDApIHsKKyAgICAgIHRvdGFsX2J5dGVzX3JlYWRfID0gY2xvc2VzdF9saW1pdDsKKyAgICAgIGlucHV0Xy0+U2tpcChieXRlc191bnRpbF9saW1pdCk7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHRvdGFsX2J5dGVzX3JlYWRfICs9IGNvdW50OworICByZXR1cm4gaW5wdXRfLT5Ta2lwKGNvdW50KTsKK30KKworYm9vbCBDb2RlZElucHV0U3RyZWFtOjpHZXREaXJlY3RCdWZmZXJQb2ludGVyKGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgaWYgKEJ1ZmZlclNpemUoKSA9PSAwICYmICFSZWZyZXNoKCkpIHJldHVybiBmYWxzZTsKKworICAqZGF0YSA9IGJ1ZmZlcl87CisgICpzaXplID0gQnVmZmVyU2l6ZSgpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb2RlZElucHV0U3RyZWFtOjpSZWFkUmF3KHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgaW50IGN1cnJlbnRfYnVmZmVyX3NpemU7CisgIHdoaWxlICgoY3VycmVudF9idWZmZXJfc2l6ZSA9IEJ1ZmZlclNpemUoKSkgPCBzaXplKSB7CisgICAgLy8gUmVhZGluZyBwYXN0IGVuZCBvZiBidWZmZXIuICBDb3B5IHdoYXQgd2UgaGF2ZSwgdGhlbiByZWZyZXNoLgorICAgIG1lbWNweShidWZmZXIsIGJ1ZmZlcl8sIGN1cnJlbnRfYnVmZmVyX3NpemUpOworICAgIGJ1ZmZlciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihidWZmZXIpICsgY3VycmVudF9idWZmZXJfc2l6ZTsKKyAgICBzaXplIC09IGN1cnJlbnRfYnVmZmVyX3NpemU7CisgICAgQWR2YW5jZShjdXJyZW50X2J1ZmZlcl9zaXplKTsKKyAgICBpZiAoIVJlZnJlc2goKSkgcmV0dXJuIGZhbHNlOworICB9CisKKyAgbWVtY3B5KGJ1ZmZlciwgYnVmZmVyXywgc2l6ZSk7CisgIEFkdmFuY2Uoc2l6ZSk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFN0cmluZyhzdHJpbmcqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgaWYgKHNpemUgPCAwKSByZXR1cm4gZmFsc2U7ICAvLyBzZWN1cml0eTogc2l6ZSBpcyBvZnRlbiB1c2VyLXN1cHBsaWVkCisgIHJldHVybiBJbnRlcm5hbFJlYWRTdHJpbmdJbmxpbmUoYnVmZmVyLCBzaXplKTsKK30KKworYm9vbCBDb2RlZElucHV0U3RyZWFtOjpSZWFkU3RyaW5nRmFsbGJhY2soc3RyaW5nKiBidWZmZXIsIGludCBzaXplKSB7CisgIGlmICghYnVmZmVyLT5lbXB0eSgpKSB7CisgICAgYnVmZmVyLT5jbGVhcigpOworICB9CisKKyAgaW50IGNsb3Nlc3RfbGltaXQgPSBtaW4oY3VycmVudF9saW1pdF8sIHRvdGFsX2J5dGVzX2xpbWl0Xyk7CisgIGlmIChjbG9zZXN0X2xpbWl0ICE9IElOVF9NQVgpIHsKKyAgICBpbnQgYnl0ZXNfdG9fbGltaXQgPSBjbG9zZXN0X2xpbWl0IC0gQ3VycmVudFBvc2l0aW9uKCk7CisgICAgaWYgKGJ5dGVzX3RvX2xpbWl0ID4gMCAmJiBzaXplID4gMCAmJiBzaXplIDw9IGJ5dGVzX3RvX2xpbWl0KSB7CisgICAgICBidWZmZXItPnJlc2VydmUoc2l6ZSk7CisgICAgfQorICB9CisKKyAgaW50IGN1cnJlbnRfYnVmZmVyX3NpemU7CisgIHdoaWxlICgoY3VycmVudF9idWZmZXJfc2l6ZSA9IEJ1ZmZlclNpemUoKSkgPCBzaXplKSB7CisgICAgLy8gU29tZSBTVEwgaW1wbGVtZW50YXRpb25zICJoZWxwZnVsbHkiIGNyYXNoIG9uIGJ1ZmZlci0+YXBwZW5kKE5VTEwsIDApLgorICAgIGlmIChjdXJyZW50X2J1ZmZlcl9zaXplICE9IDApIHsKKyAgICAgIC8vIE5vdGU6ICBzdHJpbmcxLmFwcGVuZChzdHJpbmcyKSBpcyBPKHN0cmluZzIuc2l6ZSgpKSAoYXMgb3Bwb3NlZCB0bworICAgICAgLy8gICBPKHN0cmluZzEuc2l6ZSgpICsgc3RyaW5nMi5zaXplKCkpLCB3aGljaCB3b3VsZCBiZSBiYWQpLgorICAgICAgYnVmZmVyLT5hcHBlbmQocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oYnVmZmVyXyksCisgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2J1ZmZlcl9zaXplKTsKKyAgICB9CisgICAgc2l6ZSAtPSBjdXJyZW50X2J1ZmZlcl9zaXplOworICAgIEFkdmFuY2UoY3VycmVudF9idWZmZXJfc2l6ZSk7CisgICAgaWYgKCFSZWZyZXNoKCkpIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGJ1ZmZlci0+YXBwZW5kKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KGJ1ZmZlcl8pLCBzaXplKTsKKyAgQWR2YW5jZShzaXplKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW4zMkZhbGxiYWNrKHVpbnQzMiogdmFsdWUpIHsKKyAgdWludDggYnl0ZXNbc2l6ZW9mKCp2YWx1ZSldOworCisgIGNvbnN0IHVpbnQ4KiBwdHI7CisgIGlmIChCdWZmZXJTaXplKCkgPj0gc2l6ZW9mKCp2YWx1ZSkpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBFbm91Z2ggYnl0ZXMgaW4gdGhlIGJ1ZmZlciB0byByZWFkIGRpcmVjdGx5LgorICAgIHB0ciA9IGJ1ZmZlcl87CisgICAgQWR2YW5jZShzaXplb2YoKnZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgLy8gU2xvdyBwYXRoOiAgSGFkIHRvIHJlYWQgcGFzdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIuCisgICAgaWYgKCFSZWFkUmF3KGJ5dGVzLCBzaXplb2YoKnZhbHVlKSkpIHJldHVybiBmYWxzZTsKKyAgICBwdHIgPSBieXRlczsKKyAgfQorICBSZWFkTGl0dGxlRW5kaWFuMzJGcm9tQXJyYXkocHRyLCB2YWx1ZSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZhbGxiYWNrKHVpbnQ2NCogdmFsdWUpIHsKKyAgdWludDggYnl0ZXNbc2l6ZW9mKCp2YWx1ZSldOworCisgIGNvbnN0IHVpbnQ4KiBwdHI7CisgIGlmIChCdWZmZXJTaXplKCkgPj0gc2l6ZW9mKCp2YWx1ZSkpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBFbm91Z2ggYnl0ZXMgaW4gdGhlIGJ1ZmZlciB0byByZWFkIGRpcmVjdGx5LgorICAgIHB0ciA9IGJ1ZmZlcl87CisgICAgQWR2YW5jZShzaXplb2YoKnZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgLy8gU2xvdyBwYXRoOiAgSGFkIHRvIHJlYWQgcGFzdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIuCisgICAgaWYgKCFSZWFkUmF3KGJ5dGVzLCBzaXplb2YoKnZhbHVlKSkpIHJldHVybiBmYWxzZTsKKyAgICBwdHIgPSBieXRlczsKKyAgfQorICBSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXkocHRyLCB2YWx1ZSk7CisgIHJldHVybiB0cnVlOworfQorCituYW1lc3BhY2UgeworCitpbmxpbmUgY29uc3QgdWludDgqIFJlYWRWYXJpbnQzMkZyb21BcnJheSgKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLCB1aW50MzIqIHZhbHVlKSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkU7CitpbmxpbmUgY29uc3QgdWludDgqIFJlYWRWYXJpbnQzMkZyb21BcnJheShjb25zdCB1aW50OCogYnVmZmVyLCB1aW50MzIqIHZhbHVlKSB7CisgIC8vIEZhc3QgcGF0aDogIFdlIGhhdmUgZW5vdWdoIGJ5dGVzIGxlZnQgaW4gdGhlIGJ1ZmZlciB0byBndWFyYW50ZWUgdGhhdAorICAvLyB0aGlzIHJlYWQgd29uJ3QgY3Jvc3MgdGhlIGVuZCwgc28gd2UgY2FuIHNraXAgdGhlIGNoZWNrcy4KKyAgY29uc3QgdWludDgqIHB0ciA9IGJ1ZmZlcjsKKyAgdWludDMyIGI7CisgIHVpbnQzMiByZXN1bHQ7CisKKyAgYiA9ICoocHRyKyspOyByZXN1bHQgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgIHJlc3VsdCAtPSAweDgwOworICBiID0gKihwdHIrKyk7IHJlc3VsdCArPSBiIDw8ICA3OyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgcmVzdWx0IC09IDB4ODAgPDwgNzsKKyAgYiA9ICoocHRyKyspOyByZXN1bHQgKz0gYiA8PCAxNDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgIHJlc3VsdCAtPSAweDgwIDw8IDE0OworICBiID0gKihwdHIrKyk7IHJlc3VsdCArPSBiIDw8IDIxOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgcmVzdWx0IC09IDB4ODAgPDwgMjE7CisgIGIgPSAqKHB0cisrKTsgcmVzdWx0ICs9IGIgPDwgMjg7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAvLyAicmVzdWx0IC09IDB4ODAgPDwgMjgiIGlzIGlycmV2ZWxhbnQuCisKKyAgLy8gSWYgdGhlIGlucHV0IGlzIGxhcmdlciB0aGFuIDMyIGJpdHMsIHdlIHN0aWxsIG5lZWQgdG8gcmVhZCBpdCBhbGwKKyAgLy8gYW5kIGRpc2NhcmQgdGhlIGhpZ2gtb3JkZXIgYml0cy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrTWF4VmFyaW50Qnl0ZXMgLSBrTWF4VmFyaW50MzJCeXRlczsgaSsrKSB7CisgICAgYiA9ICoocHRyKyspOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgfQorCisgIC8vIFdlIGhhdmUgb3ZlcnJ1biB0aGUgbWF4aW11bSBzaXplIG9mIGEgdmFyaW50ICgxMCBieXRlcykuICBBc3N1bWUKKyAgLy8gdGhlIGRhdGEgaXMgY29ycnVwdC4KKyAgcmV0dXJuIE5VTEw7CisKKyBkb25lOgorICAqdmFsdWUgPSByZXN1bHQ7CisgIHJldHVybiBwdHI7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRWYXJpbnQzMlNsb3codWludDMyKiB2YWx1ZSkgeworICB1aW50NjQgcmVzdWx0OworICAvLyBEaXJlY3RseSBpbnZva2UgUmVhZFZhcmludDY0RmFsbGJhY2ssIHNpbmNlIHdlIGFscmVhZHkgdHJpZWQgdG8gb3B0aW1pemUKKyAgLy8gZm9yIG9uZS1ieXRlIHZhcmludHMuCisgIGlmICghUmVhZFZhcmludDY0RmFsbGJhY2soJnJlc3VsdCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gKHVpbnQzMilyZXN1bHQ7CisgIHJldHVybiB0cnVlOworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRWYXJpbnQzMkZhbGxiYWNrKHVpbnQzMiogdmFsdWUpIHsKKyAgaWYgKEJ1ZmZlclNpemUoKSA+PSBrTWF4VmFyaW50Qnl0ZXMgfHwKKyAgICAgIC8vIE9wdGltaXphdGlvbjogIFdlJ3JlIGFsc28gc2FmZSBpZiB0aGUgYnVmZmVyIGlzIG5vbi1lbXB0eSBhbmQgaXQgZW5kcworICAgICAgLy8gd2l0aCBhIGJ5dGUgdGhhdCB3b3VsZCB0ZXJtaW5hdGUgYSB2YXJpbnQuCisgICAgICAoYnVmZmVyX2VuZF8gPiBidWZmZXJfICYmICEoYnVmZmVyX2VuZF9bLTFdICYgMHg4MCkpKSB7CisgICAgY29uc3QgdWludDgqIGVuZCA9IFJlYWRWYXJpbnQzMkZyb21BcnJheShidWZmZXJfLCB2YWx1ZSk7CisgICAgaWYgKGVuZCA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisgICAgYnVmZmVyXyA9IGVuZDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICAvLyBSZWFsbHkgc2xvdyBjYXNlOiB3ZSB3aWxsIGluY3VyIHRoZSBjb3N0IG9mIGFuIGV4dHJhIGZ1bmN0aW9uIGNhbGwgaGVyZSwKKyAgICAvLyBidXQgbW92aW5nIHRoaXMgb3V0IG9mIGxpbmUgcmVkdWNlcyB0aGUgc2l6ZSBvZiB0aGlzIGZ1bmN0aW9uLCB3aGljaAorICAgIC8vIGltcHJvdmVzIHRoZSBjb21tb24gY2FzZS4gSW4gbWljcm8gYmVuY2htYXJrcywgdGhpcyBpcyB3b3J0aCBhYm91dCAxMC0xNSUKKyAgICByZXR1cm4gUmVhZFZhcmludDMyU2xvdyh2YWx1ZSk7CisgIH0KK30KKwordWludDMyIENvZGVkSW5wdXRTdHJlYW06OlJlYWRUYWdTbG93KCkgeworICBpZiAoYnVmZmVyXyA9PSBidWZmZXJfZW5kXykgeworICAgIC8vIENhbGwgcmVmcmVzaC4KKyAgICBpZiAoIVJlZnJlc2goKSkgeworICAgICAgLy8gUmVmcmVzaCBmYWlsZWQuICBNYWtlIHN1cmUgdGhhdCBpdCBmYWlsZWQgZHVlIHRvIEVPRiwgbm90IGJlY2F1c2UKKyAgICAgIC8vIHdlIGhpdCB0b3RhbF9ieXRlc19saW1pdF8sIHdoaWNoLCB1bmxpa2Ugbm9ybWFsIGxpbWl0cywgaXMgbm90IGEKKyAgICAgIC8vIHZhbGlkIHBsYWNlIHRvIGVuZCBhIG1lc3NhZ2UuCisgICAgICBpbnQgY3VycmVudF9wb3NpdGlvbiA9IHRvdGFsX2J5dGVzX3JlYWRfIC0gYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfOworICAgICAgaWYgKGN1cnJlbnRfcG9zaXRpb24gPj0gdG90YWxfYnl0ZXNfbGltaXRfKSB7CisgICAgICAgIC8vIEhpdCB0b3RhbF9ieXRlc19saW1pdF8uICBCdXQgaWYgd2UgYWxzbyBoaXQgdGhlIG5vcm1hbCBsaW1pdCwKKyAgICAgICAgLy8gd2UncmUgc3RpbGwgT0suCisgICAgICAgIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfID0gY3VycmVudF9saW1pdF8gPT0gdG90YWxfYnl0ZXNfbGltaXRfOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF8gPSB0cnVlOworICAgICAgfQorICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisKKyAgLy8gRm9yIHRoZSBzbG93IHBhdGgsIGp1c3QgZG8gYSA2NC1iaXQgcmVhZC4gVHJ5IHRvIG9wdGltaXplIGZvciBvbmUtYnl0ZSB0YWdzCisgIC8vIGFnYWluLCBzaW5jZSB3ZSBoYXZlIG5vdyByZWZyZXNoZWQgdGhlIGJ1ZmZlci4KKyAgdWludDY0IHJlc3VsdCA9IDA7CisgIGlmICghUmVhZFZhcmludDY0KCZyZXN1bHQpKSByZXR1cm4gMDsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHVpbnQzMj4ocmVzdWx0KTsKK30KKwordWludDMyIENvZGVkSW5wdXRTdHJlYW06OlJlYWRUYWdGYWxsYmFjaygpIHsKKyAgY29uc3QgaW50IGJ1Zl9zaXplID0gQnVmZmVyU2l6ZSgpOworICBpZiAoYnVmX3NpemUgPj0ga01heFZhcmludEJ5dGVzIHx8CisgICAgICAvLyBPcHRpbWl6YXRpb246ICBXZSdyZSBhbHNvIHNhZmUgaWYgdGhlIGJ1ZmZlciBpcyBub24tZW1wdHkgYW5kIGl0IGVuZHMKKyAgICAgIC8vIHdpdGggYSBieXRlIHRoYXQgd291bGQgdGVybWluYXRlIGEgdmFyaW50LgorICAgICAgKGJ1Zl9zaXplID4gMCAmJiAhKGJ1ZmZlcl9lbmRfWy0xXSAmIDB4ODApKSkgeworICAgIHVpbnQzMiB0YWc7CisgICAgY29uc3QgdWludDgqIGVuZCA9IFJlYWRWYXJpbnQzMkZyb21BcnJheShidWZmZXJfLCAmdGFnKTsKKyAgICBpZiAoZW5kID09IE5VTEwpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBidWZmZXJfID0gZW5kOworICAgIHJldHVybiB0YWc7CisgIH0gZWxzZSB7CisgICAgLy8gV2UgYXJlIGNvbW1vbmx5IGF0IGEgbGltaXQgd2hlbiBhdHRlbXB0aW5nIHRvIHJlYWQgdGFncy4gVHJ5IHRvIHF1aWNrbHkKKyAgICAvLyBkZXRlY3QgdGhpcyBjYXNlIHdpdGhvdXQgbWFraW5nIGFub3RoZXIgZnVuY3Rpb24gY2FsbC4KKyAgICBpZiAoKGJ1Zl9zaXplID09IDApICYmCisgICAgICAgICgoYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfID4gMCkgfHwKKyAgICAgICAgICh0b3RhbF9ieXRlc19yZWFkXyA9PSBjdXJyZW50X2xpbWl0XykpICYmCisgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBsaW1pdCB3ZSBoaXQgaXMgbm90IHRvdGFsX2J5dGVzX2xpbWl0Xywgc2luY2UKKyAgICAgICAgLy8gaW4gdGhhdCBjYXNlIHdlIHN0aWxsIG5lZWQgdG8gY2FsbCBSZWZyZXNoKCkgc28gdGhhdCBpdCBwcmludHMgYW4KKyAgICAgICAgLy8gZXJyb3IuCisgICAgICAgIHRvdGFsX2J5dGVzX3JlYWRfIC0gYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfIDwgdG90YWxfYnl0ZXNfbGltaXRfKSB7CisgICAgICAvLyBXZSBoaXQgYSBieXRlIGxpbWl0LgorICAgICAgbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF8gPSB0cnVlOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiBSZWFkVGFnU2xvdygpOworICB9Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDY0U2xvdyh1aW50NjQqIHZhbHVlKSB7CisgIC8vIFNsb3cgcGF0aDogIFRoaXMgcmVhZCBtaWdodCBjcm9zcyB0aGUgZW5kIG9mIHRoZSBidWZmZXIsIHNvIHdlCisgIC8vIG5lZWQgdG8gY2hlY2sgYW5kIHJlZnJlc2ggdGhlIGJ1ZmZlciBpZiBhbmQgd2hlbiBpdCBkb2VzLgorCisgIHVpbnQ2NCByZXN1bHQgPSAwOworICBpbnQgY291bnQgPSAwOworICB1aW50MzIgYjsKKworICBkbyB7CisgICAgaWYgKGNvdW50ID09IGtNYXhWYXJpbnRCeXRlcykgcmV0dXJuIGZhbHNlOworICAgIHdoaWxlIChidWZmZXJfID09IGJ1ZmZlcl9lbmRfKSB7CisgICAgICBpZiAoIVJlZnJlc2goKSkgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBiID0gKmJ1ZmZlcl87CisgICAgcmVzdWx0IHw9IHN0YXRpY19jYXN0PHVpbnQ2ND4oYiAmIDB4N0YpIDw8ICg3ICogY291bnQpOworICAgIEFkdmFuY2UoMSk7CisgICAgKytjb3VudDsKKyAgfSB3aGlsZSAoYiAmIDB4ODApOworCisgICp2YWx1ZSA9IHJlc3VsdDsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDY0RmFsbGJhY2sodWludDY0KiB2YWx1ZSkgeworICBpZiAoQnVmZmVyU2l6ZSgpID49IGtNYXhWYXJpbnRCeXRlcyB8fAorICAgICAgLy8gT3B0aW1pemF0aW9uOiAgV2UncmUgYWxzbyBzYWZlIGlmIHRoZSBidWZmZXIgaXMgbm9uLWVtcHR5IGFuZCBpdCBlbmRzCisgICAgICAvLyB3aXRoIGEgYnl0ZSB0aGF0IHdvdWxkIHRlcm1pbmF0ZSBhIHZhcmludC4KKyAgICAgIChidWZmZXJfZW5kXyA+IGJ1ZmZlcl8gJiYgIShidWZmZXJfZW5kX1stMV0gJiAweDgwKSkpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBXZSBoYXZlIGVub3VnaCBieXRlcyBsZWZ0IGluIHRoZSBidWZmZXIgdG8gZ3VhcmFudGVlIHRoYXQKKyAgICAvLyB0aGlzIHJlYWQgd29uJ3QgY3Jvc3MgdGhlIGVuZCwgc28gd2UgY2FuIHNraXAgdGhlIGNoZWNrcy4KKworICAgIGNvbnN0IHVpbnQ4KiBwdHIgPSBidWZmZXJfOworICAgIHVpbnQzMiBiOworCisgICAgLy8gU3BsaXR0aW5nIGludG8gMzItYml0IHBpZWNlcyBnaXZlcyBiZXR0ZXIgcGVyZm9ybWFuY2Ugb24gMzItYml0CisgICAgLy8gcHJvY2Vzc29ycy4KKyAgICB1aW50MzIgcGFydDAgPSAwLCBwYXJ0MSA9IDAsIHBhcnQyID0gMDsKKworICAgIGIgPSAqKHB0cisrKTsgcGFydDAgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgICAgcGFydDAgLT0gMHg4MDsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQwICs9IGIgPDwgIDc7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQwIC09IDB4ODAgPDwgNzsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQwICs9IGIgPDwgMTQ7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQwIC09IDB4ODAgPDwgMTQ7CisgICAgYiA9ICoocHRyKyspOyBwYXJ0MCArPSBiIDw8IDIxOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgICBwYXJ0MCAtPSAweDgwIDw8IDIxOworICAgIGIgPSAqKHB0cisrKTsgcGFydDEgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgICAgcGFydDEgLT0gMHg4MDsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQxICs9IGIgPDwgIDc7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQxIC09IDB4ODAgPDwgNzsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQxICs9IGIgPDwgMTQ7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQxIC09IDB4ODAgPDwgMTQ7CisgICAgYiA9ICoocHRyKyspOyBwYXJ0MSArPSBiIDw8IDIxOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgICBwYXJ0MSAtPSAweDgwIDw8IDIxOworICAgIGIgPSAqKHB0cisrKTsgcGFydDIgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgICAgcGFydDIgLT0gMHg4MDsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQyICs9IGIgPDwgIDc7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIC8vICJwYXJ0MiAtPSAweDgwIDw8IDciIGlzIGlycmVsZXZhbnQgYmVjYXVzZSAoMHg4MCA8PCA3KSA8PCA1NiBpcyAwLgorCisgICAgLy8gV2UgaGF2ZSBvdmVycnVuIHRoZSBtYXhpbXVtIHNpemUgb2YgYSB2YXJpbnQgKDEwIGJ5dGVzKS4gIFRoZSBkYXRhCisgICAgLy8gbXVzdCBiZSBjb3JydXB0LgorICAgIHJldHVybiBmYWxzZTsKKworICAgZG9uZToKKyAgICBBZHZhbmNlKHB0ciAtIGJ1ZmZlcl8pOworICAgICp2YWx1ZSA9IChzdGF0aWNfY2FzdDx1aW50NjQ+KHBhcnQwKSAgICAgICkgfAorICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50NjQ+KHBhcnQxKSA8PCAyOCkgfAorICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50NjQ+KHBhcnQyKSA8PCA1Nik7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFJlYWRWYXJpbnQ2NFNsb3codmFsdWUpOworICB9Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVmcmVzaCgpIHsKKyAgR09PR0xFX0RDSEVDS19FUSgwLCBCdWZmZXJTaXplKCkpOworCisgIGlmIChidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gPiAwIHx8IG92ZXJmbG93X2J5dGVzXyA+IDAgfHwKKyAgICAgIHRvdGFsX2J5dGVzX3JlYWRfID09IGN1cnJlbnRfbGltaXRfKSB7CisgICAgLy8gV2UndmUgaGl0IGEgbGltaXQuICBTdG9wLgorICAgIGludCBjdXJyZW50X3Bvc2l0aW9uID0gdG90YWxfYnl0ZXNfcmVhZF8gLSBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF87CisKKyAgICBpZiAoY3VycmVudF9wb3NpdGlvbiA+PSB0b3RhbF9ieXRlc19saW1pdF8gJiYKKyAgICAgICAgdG90YWxfYnl0ZXNfbGltaXRfICE9IGN1cnJlbnRfbGltaXRfKSB7CisgICAgICAvLyBIaXQgdG90YWxfYnl0ZXNfbGltaXRfLgorICAgICAgUHJpbnRUb3RhbEJ5dGVzTGltaXRFcnJvcigpOworICAgIH0KKworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmICh0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8gPj0gMCAmJgorICAgICAgdG90YWxfYnl0ZXNfcmVhZF8gPj0gdG90YWxfYnl0ZXNfd2FybmluZ190aHJlc2hvbGRfKSB7CisgICAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJSZWFkaW5nIGRhbmdlcm91c2x5IGxhcmdlIHByb3RvY29sIG1lc3NhZ2UuICBJZiB0aGUgIgorICAgICAgICAgICAgICAgICAgICAgICJtZXNzYWdlIHR1cm5zIG91dCB0byBiZSBsYXJnZXIgdGhhbiAiCisgICAgICAgICAgICAgICAgICAgPDwgdG90YWxfYnl0ZXNfbGltaXRfIDw8ICIgYnl0ZXMsIHBhcnNpbmcgd2lsbCBiZSBoYWx0ZWQgIgorICAgICAgICAgICAgICAgICAgICAgICJmb3Igc2VjdXJpdHkgcmVhc29ucy4gIFRvIGluY3JlYXNlIHRoZSBsaW1pdCAob3IgdG8gIgorICAgICAgICAgICAgICAgICAgICAgICJkaXNhYmxlIHRoZXNlIHdhcm5pbmdzKSwgc2VlICIKKyAgICAgICAgICAgICAgICAgICAgICAiQ29kZWRJbnB1dFN0cmVhbTo6U2V0VG90YWxCeXRlc0xpbWl0KCkgaW4gIgorICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmguIjsKKworICAgIC8vIERvbid0IHdhcm4gYWdhaW4gZm9yIHRoaXMgc3RyZWFtLCBhbmQgcHJpbnQgdG90YWwgc2l6ZSBhdCB0aGUgZW5kLgorICAgIHRvdGFsX2J5dGVzX3dhcm5pbmdfdGhyZXNob2xkXyA9IC0yOworICB9CisKKyAgY29uc3Qgdm9pZCogdm9pZF9idWZmZXI7CisgIGludCBidWZmZXJfc2l6ZTsKKyAgaWYgKE5leHROb25FbXB0eShpbnB1dF8sICZ2b2lkX2J1ZmZlciwgJmJ1ZmZlcl9zaXplKSkgeworICAgIGJ1ZmZlcl8gPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4odm9pZF9idWZmZXIpOworICAgIGJ1ZmZlcl9lbmRfID0gYnVmZmVyXyArIGJ1ZmZlcl9zaXplOworICAgIEdPT0dMRV9DSEVDS19HRShidWZmZXJfc2l6ZSwgMCk7CisKKyAgICBpZiAodG90YWxfYnl0ZXNfcmVhZF8gPD0gSU5UX01BWCAtIGJ1ZmZlcl9zaXplKSB7CisgICAgICB0b3RhbF9ieXRlc19yZWFkXyArPSBidWZmZXJfc2l6ZTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gT3ZlcmZsb3cuICBSZXNldCBidWZmZXJfZW5kXyB0byBub3QgaW5jbHVkZSB0aGUgYnl0ZXMgYmV5b25kIElOVF9NQVguCisgICAgICAvLyBXZSBjYW4ndCBnZXQgdGhhdCBmYXIgYW55d2F5LCBiZWNhdXNlIHRvdGFsX2J5dGVzX2xpbWl0XyBpcyBndWFyYW50ZWVkCisgICAgICAvLyB0byBiZSBsZXNzIHRoYW4gaXQuICBXZSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBieXRlcworICAgICAgLy8gd2UgZGlzY2FyZGVkLCB0aG91Z2gsIHNvIHRoYXQgd2UgY2FuIGNhbGwgaW5wdXRfLT5CYWNrVXAoKSB0byBiYWNrCisgICAgICAvLyB1cCBvdmVyIHRoZW0gb24gZGVzdHJ1Y3Rpb24uCisKKyAgICAgIC8vIFRoZSBmb2xsb3dpbmcgbGluZSBpcyBlcXVpdmFsZW50IHRvOgorICAgICAgLy8gICBvdmVyZmxvd19ieXRlc18gPSB0b3RhbF9ieXRlc19yZWFkXyArIGJ1ZmZlcl9zaXplIC0gSU5UX01BWDsKKyAgICAgIC8vIGV4Y2VwdCB0aGF0IGl0IGF2b2lkcyBvdmVyZmxvd3MuICBTaWduZWQgaW50ZWdlciBvdmVyZmxvdyBoYXMKKyAgICAgIC8vIHVuZGVmaW5lZCByZXN1bHRzIGFjY29yZGluZyB0byB0aGUgQyBzdGFuZGFyZC4KKyAgICAgIG92ZXJmbG93X2J5dGVzXyA9IHRvdGFsX2J5dGVzX3JlYWRfIC0gKElOVF9NQVggLSBidWZmZXJfc2l6ZSk7CisgICAgICBidWZmZXJfZW5kXyAtPSBvdmVyZmxvd19ieXRlc187CisgICAgICB0b3RhbF9ieXRlc19yZWFkXyA9IElOVF9NQVg7CisgICAgfQorCisgICAgUmVjb21wdXRlQnVmZmVyTGltaXRzKCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgYnVmZmVyXyA9IE5VTEw7CisgICAgYnVmZmVyX2VuZF8gPSBOVUxMOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisvLyBDb2RlZE91dHB1dFN0cmVhbSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvZGVkT3V0cHV0U3RyZWFtOjpDb2RlZE91dHB1dFN0cmVhbShaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KQorICA6IG91dHB1dF8ob3V0cHV0KSwKKyAgICBidWZmZXJfKE5VTEwpLAorICAgIGJ1ZmZlcl9zaXplXygwKSwKKyAgICB0b3RhbF9ieXRlc18oMCksCisgICAgaGFkX2Vycm9yXyhmYWxzZSksCisgICAgYWxpYXNpbmdfZW5hYmxlZF8oZmFsc2UpIHsKKyAgLy8gRWFnZXJseSBSZWZyZXNoKCkgc28gYnVmZmVyIHNwYWNlIGlzIGltbWVkaWF0ZWx5IGF2YWlsYWJsZS4KKyAgUmVmcmVzaCgpOworICAvLyBUaGUgUmVmcmVzaCgpIG1heSBoYXZlIGZhaWxlZC4gSWYgdGhlIGNsaWVudCBkb2Vzbid0IHdyaXRlIGFueSBkYXRhLAorICAvLyB0aG91Z2gsIGRvbid0IGNvbnNpZGVyIHRoaXMgYW4gZXJyb3IuIElmIHRoZSBjbGllbnQgZG9lcyB3cml0ZSBkYXRhLCB0aGVuCisgIC8vIGFub3RoZXIgUmVmcmVzaCgpIHdpbGwgYmUgYXR0ZW1wdGVkIGFuZCBpdCB3aWxsIHNldCB0aGUgZXJyb3Igb25jZSBhZ2Fpbi4KKyAgaGFkX2Vycm9yXyA9IGZhbHNlOworfQorCitDb2RlZE91dHB1dFN0cmVhbTo6fkNvZGVkT3V0cHV0U3RyZWFtKCkgeworICBUcmltKCk7Cit9CisKK3ZvaWQgQ29kZWRPdXRwdXRTdHJlYW06OlRyaW0oKSB7CisgIGlmIChidWZmZXJfc2l6ZV8gPiAwKSB7CisgICAgb3V0cHV0Xy0+QmFja1VwKGJ1ZmZlcl9zaXplXyk7CisgICAgdG90YWxfYnl0ZXNfIC09IGJ1ZmZlcl9zaXplXzsKKyAgICBidWZmZXJfc2l6ZV8gPSAwOworICAgIGJ1ZmZlcl8gPSBOVUxMOworICB9Cit9CisKK2Jvb2wgQ29kZWRPdXRwdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIGlmIChjb3VudCA8IDApIHJldHVybiBmYWxzZTsKKworICB3aGlsZSAoY291bnQgPiBidWZmZXJfc2l6ZV8pIHsKKyAgICBjb3VudCAtPSBidWZmZXJfc2l6ZV87CisgICAgaWYgKCFSZWZyZXNoKCkpIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEFkdmFuY2UoY291bnQpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb2RlZE91dHB1dFN0cmVhbTo6R2V0RGlyZWN0QnVmZmVyUG9pbnRlcih2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChidWZmZXJfc2l6ZV8gPT0gMCAmJiAhUmVmcmVzaCgpKSByZXR1cm4gZmFsc2U7CisKKyAgKmRhdGEgPSBidWZmZXJfOworICAqc2l6ZSA9IGJ1ZmZlcl9zaXplXzsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlUmF3KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKSB7CisgIHdoaWxlIChidWZmZXJfc2l6ZV8gPCBzaXplKSB7CisgICAgbWVtY3B5KGJ1ZmZlcl8sIGRhdGEsIGJ1ZmZlcl9zaXplXyk7CisgICAgc2l6ZSAtPSBidWZmZXJfc2l6ZV87CisgICAgZGF0YSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhKSArIGJ1ZmZlcl9zaXplXzsKKyAgICBpZiAoIVJlZnJlc2goKSkgcmV0dXJuOworICB9CisKKyAgbWVtY3B5KGJ1ZmZlcl8sIGRhdGEsIHNpemUpOworICBBZHZhbmNlKHNpemUpOworfQorCit1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlUmF3VG9BcnJheSgKKyAgICBjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSwgdWludDgqIHRhcmdldCkgeworICBtZW1jcHkodGFyZ2V0LCBkYXRhLCBzaXplKTsKKyAgcmV0dXJuIHRhcmdldCArIHNpemU7Cit9CisKKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVBbGlhc2VkUmF3KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKSB7CisgIGlmIChzaXplIDwgYnVmZmVyX3NpemVfCisgICAgICApIHsKKyAgICBXcml0ZVJhdyhkYXRhLCBzaXplKTsKKyAgfSBlbHNlIHsKKyAgICBUcmltKCk7CisKKyAgICB0b3RhbF9ieXRlc18gKz0gc2l6ZTsKKyAgICBoYWRfZXJyb3JfIHw9ICFvdXRwdXRfLT5Xcml0ZUFsaWFzZWRSYXcoZGF0YSwgc2l6ZSk7CisgIH0KK30KKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW4zMih1aW50MzIgdmFsdWUpIHsKKyAgdWludDggYnl0ZXNbc2l6ZW9mKHZhbHVlKV07CisKKyAgYm9vbCB1c2VfZmFzdCA9IGJ1ZmZlcl9zaXplXyA+PSBzaXplb2YodmFsdWUpOworICB1aW50OCogcHRyID0gdXNlX2Zhc3QgPyBidWZmZXJfIDogYnl0ZXM7CisKKyAgV3JpdGVMaXR0bGVFbmRpYW4zMlRvQXJyYXkodmFsdWUsIHB0cik7CisKKyAgaWYgKHVzZV9mYXN0KSB7CisgICAgQWR2YW5jZShzaXplb2YodmFsdWUpKTsKKyAgfSBlbHNlIHsKKyAgICBXcml0ZVJhdyhieXRlcywgc2l6ZW9mKHZhbHVlKSk7CisgIH0KK30KKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW42NCh1aW50NjQgdmFsdWUpIHsKKyAgdWludDggYnl0ZXNbc2l6ZW9mKHZhbHVlKV07CisKKyAgYm9vbCB1c2VfZmFzdCA9IGJ1ZmZlcl9zaXplXyA+PSBzaXplb2YodmFsdWUpOworICB1aW50OCogcHRyID0gdXNlX2Zhc3QgPyBidWZmZXJfIDogYnl0ZXM7CisKKyAgV3JpdGVMaXR0bGVFbmRpYW42NFRvQXJyYXkodmFsdWUsIHB0cik7CisKKyAgaWYgKHVzZV9mYXN0KSB7CisgICAgQWR2YW5jZShzaXplb2YodmFsdWUpKTsKKyAgfSBlbHNlIHsKKyAgICBXcml0ZVJhdyhieXRlcywgc2l6ZW9mKHZhbHVlKSk7CisgIH0KK30KKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlNsb3dQYXRoKHVpbnQzMiB2YWx1ZSkgeworICB1aW50OCBieXRlc1trTWF4VmFyaW50MzJCeXRlc107CisgIHVpbnQ4KiB0YXJnZXQgPSAmYnl0ZXNbMF07CisgIHVpbnQ4KiBlbmQgPSBXcml0ZVZhcmludDMyVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKKyAgaW50IHNpemUgPSBlbmQgLSB0YXJnZXQ7CisgIFdyaXRlUmF3KGJ5dGVzLCBzaXplKTsKK30KKworaW5saW5lIHVpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQ2NFRvQXJyYXlJbmxpbmUoCisgICAgdWludDY0IHZhbHVlLCB1aW50OCogdGFyZ2V0KSB7CisgIC8vIFNwbGl0dGluZyBpbnRvIDMyLWJpdCBwaWVjZXMgZ2l2ZXMgYmV0dGVyIHBlcmZvcm1hbmNlIG9uIDMyLWJpdAorICAvLyBwcm9jZXNzb3JzLgorICB1aW50MzIgcGFydDAgPSBzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlICAgICAgKTsKKyAgdWludDMyIHBhcnQxID0gc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSA+PiAyOCk7CisgIHVpbnQzMiBwYXJ0MiA9IHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUgPj4gNTYpOworCisgIGludCBzaXplOworCisgIC8vIEhlcmUgd2UgY2FuJ3QgcmVhbGx5IG9wdGltaXplIGZvciBzbWFsbCBudW1iZXJzLCBzaW5jZSB0aGUgdmFsdWUgaXMKKyAgLy8gc3BsaXQgaW50byB0aHJlZSBwYXJ0cy4gIENoZWtpbmcgZm9yIG51bWJlcnMgPCAxMjgsIGZvciBpbnN0YW5jZSwKKyAgLy8gd291bGQgcmVxdWlyZSB0aHJlZSBjb21wYXJpc29ucywgc2luY2UgeW91J2QgaGF2ZSB0byBtYWtlIHN1cmUgcGFydDEKKyAgLy8gYW5kIHBhcnQyIGFyZSB6ZXJvLiAgSG93ZXZlciwgaWYgdGhlIGNhbGxlciBpcyB1c2luZyA2NC1iaXQgaW50ZWdlcnMsCisgIC8vIGl0IGlzIGxpa2VseSB0aGF0IHRoZXkgZXhwZWN0IHRoZSBudW1iZXJzIHRvIG9mdGVuIGJlIHZlcnkgbGFyZ2UsIHNvCisgIC8vIHdlIHByb2JhYmx5IGRvbid0IHdhbnQgdG8gb3B0aW1pemUgZm9yIHNtYWxsIG51bWJlcnMgYW55d2F5LiAgVGh1cywKKyAgLy8gd2UgZW5kIHVwIHdpdGggYSBoYXJkY29kZWQgYmluYXJ5IHNlYXJjaCB0cmVlLi4uCisgIGlmIChwYXJ0MiA9PSAwKSB7CisgICAgaWYgKHBhcnQxID09IDApIHsKKyAgICAgIGlmIChwYXJ0MCA8ICgxIDw8IDE0KSkgeworICAgICAgICBpZiAocGFydDAgPCAoMSA8PCA3KSkgeworICAgICAgICAgIHNpemUgPSAxOyBnb3RvIHNpemUxOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNpemUgPSAyOyBnb3RvIHNpemUyOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAocGFydDAgPCAoMSA8PCAyMSkpIHsKKyAgICAgICAgICBzaXplID0gMzsgZ290byBzaXplMzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzaXplID0gNDsgZ290byBzaXplNDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAocGFydDEgPCAoMSA8PCAxNCkpIHsKKyAgICAgICAgaWYgKHBhcnQxIDwgKDEgPDwgNykpIHsKKyAgICAgICAgICBzaXplID0gNTsgZ290byBzaXplNTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzaXplID0gNjsgZ290byBzaXplNjsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKHBhcnQxIDwgKDEgPDwgMjEpKSB7CisgICAgICAgICAgc2l6ZSA9IDc7IGdvdG8gc2l6ZTc7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2l6ZSA9IDg7IGdvdG8gc2l6ZTg7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKHBhcnQyIDwgKDEgPDwgNykpIHsKKyAgICAgIHNpemUgPSA5OyBnb3RvIHNpemU5OworICAgIH0gZWxzZSB7CisgICAgICBzaXplID0gMTA7IGdvdG8gc2l6ZTEwOworICAgIH0KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworCisgIHNpemUxMDogdGFyZ2V0WzldID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MiA+PiAgNykgfCAweDgwKTsKKyAgc2l6ZTkgOiB0YXJnZXRbOF0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQyICAgICAgKSB8IDB4ODApOworICBzaXplOCA6IHRhcmdldFs3XSA9IHN0YXRpY19jYXN0PHVpbnQ4PigocGFydDEgPj4gMjEpIHwgMHg4MCk7CisgIHNpemU3IDogdGFyZ2V0WzZdID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MSA+PiAxNCkgfCAweDgwKTsKKyAgc2l6ZTYgOiB0YXJnZXRbNV0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQxID4+ICA3KSB8IDB4ODApOworICBzaXplNSA6IHRhcmdldFs0XSA9IHN0YXRpY19jYXN0PHVpbnQ4PigocGFydDEgICAgICApIHwgMHg4MCk7CisgIHNpemU0IDogdGFyZ2V0WzNdID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MCA+PiAyMSkgfCAweDgwKTsKKyAgc2l6ZTMgOiB0YXJnZXRbMl0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQwID4+IDE0KSB8IDB4ODApOworICBzaXplMiA6IHRhcmdldFsxXSA9IHN0YXRpY19jYXN0PHVpbnQ4PigocGFydDAgPj4gIDcpIHwgMHg4MCk7CisgIHNpemUxIDogdGFyZ2V0WzBdID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MCAgICAgICkgfCAweDgwKTsKKworICB0YXJnZXRbc2l6ZS0xXSAmPSAweDdGOworICByZXR1cm4gdGFyZ2V0ICsgc2l6ZTsKK30KKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQ2NCh1aW50NjQgdmFsdWUpIHsKKyAgaWYgKGJ1ZmZlcl9zaXplXyA+PSBrTWF4VmFyaW50Qnl0ZXMpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBXZSBoYXZlIGVub3VnaCBieXRlcyBsZWZ0IGluIHRoZSBidWZmZXIgdG8gZ3VhcmFudGVlIHRoYXQKKyAgICAvLyB0aGlzIHdyaXRlIHdvbid0IGNyb3NzIHRoZSBlbmQsIHNvIHdlIGNhbiBza2lwIHRoZSBjaGVja3MuCisgICAgdWludDgqIHRhcmdldCA9IGJ1ZmZlcl87CisKKyAgICB1aW50OCogZW5kID0gV3JpdGVWYXJpbnQ2NFRvQXJyYXlJbmxpbmUodmFsdWUsIHRhcmdldCk7CisgICAgaW50IHNpemUgPSBlbmQgLSB0YXJnZXQ7CisgICAgQWR2YW5jZShzaXplKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBTbG93IHBhdGg6ICBUaGlzIHdyaXRlIG1pZ2h0IGNyb3NzIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciwgc28gd2UKKyAgICAvLyBjb21wb3NlIHRoZSBieXRlcyBmaXJzdCB0aGVuIHVzZSBXcml0ZVJhdygpLgorICAgIHVpbnQ4IGJ5dGVzW2tNYXhWYXJpbnRCeXRlc107CisgICAgaW50IHNpemUgPSAwOworICAgIHdoaWxlICh2YWx1ZSA+IDB4N0YpIHsKKyAgICAgIGJ5dGVzW3NpemUrK10gPSAoc3RhdGljX2Nhc3Q8dWludDg+KHZhbHVlKSAmIDB4N0YpIHwgMHg4MDsKKyAgICAgIHZhbHVlID4+PSA3OworICAgIH0KKyAgICBieXRlc1tzaXplKytdID0gc3RhdGljX2Nhc3Q8dWludDg+KHZhbHVlKSAmIDB4N0Y7CisgICAgV3JpdGVSYXcoYnl0ZXMsIHNpemUpOworICB9Cit9CisKK3VpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQ2NFRvQXJyYXkoCisgICAgdWludDY0IHZhbHVlLCB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBXcml0ZVZhcmludDY0VG9BcnJheUlubGluZSh2YWx1ZSwgdGFyZ2V0KTsKK30KKworYm9vbCBDb2RlZE91dHB1dFN0cmVhbTo6UmVmcmVzaCgpIHsKKyAgdm9pZCogdm9pZF9idWZmZXI7CisgIGlmIChvdXRwdXRfLT5OZXh0KCZ2b2lkX2J1ZmZlciwgJmJ1ZmZlcl9zaXplXykpIHsKKyAgICBidWZmZXJfID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHZvaWRfYnVmZmVyKTsKKyAgICB0b3RhbF9ieXRlc18gKz0gYnVmZmVyX3NpemVfOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIGJ1ZmZlcl8gPSBOVUxMOworICAgIGJ1ZmZlcl9zaXplXyA9IDA7CisgICAgaGFkX2Vycm9yXyA9IHRydWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2ludCBDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyRmFsbGJhY2sodWludDMyIHZhbHVlKSB7CisgIGlmICh2YWx1ZSA8ICgxIDw8IDcpKSB7CisgICAgcmV0dXJuIDE7CisgIH0gZWxzZSBpZiAodmFsdWUgPCAoMSA8PCAxNCkpIHsKKyAgICByZXR1cm4gMjsKKyAgfSBlbHNlIGlmICh2YWx1ZSA8ICgxIDw8IDIxKSkgeworICAgIHJldHVybiAzOworICB9IGVsc2UgaWYgKHZhbHVlIDwgKDEgPDwgMjgpKSB7CisgICAgcmV0dXJuIDQ7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIDU7CisgIH0KK30KKworaW50IENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQodWludDY0IHZhbHVlKSB7CisgIGlmICh2YWx1ZSA8ICgxdWxsIDw8IDM1KSkgeworICAgIGlmICh2YWx1ZSA8ICgxdWxsIDw8IDcpKSB7CisgICAgICByZXR1cm4gMTsKKyAgICB9IGVsc2UgaWYgKHZhbHVlIDwgKDF1bGwgPDwgMTQpKSB7CisgICAgICByZXR1cm4gMjsKKyAgICB9IGVsc2UgaWYgKHZhbHVlIDwgKDF1bGwgPDwgMjEpKSB7CisgICAgICByZXR1cm4gMzsKKyAgICB9IGVsc2UgaWYgKHZhbHVlIDwgKDF1bGwgPDwgMjgpKSB7CisgICAgICByZXR1cm4gNDsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIDU7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmICh2YWx1ZSA8ICgxdWxsIDw8IDQyKSkgeworICAgICAgcmV0dXJuIDY7CisgICAgfSBlbHNlIGlmICh2YWx1ZSA8ICgxdWxsIDw8IDQ5KSkgeworICAgICAgcmV0dXJuIDc7CisgICAgfSBlbHNlIGlmICh2YWx1ZSA8ICgxdWxsIDw8IDU2KSkgeworICAgICAgcmV0dXJuIDg7CisgICAgfSBlbHNlIGlmICh2YWx1ZSA8ICgxdWxsIDw8IDYzKSkgeworICAgICAgcmV0dXJuIDk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAxMDsKKyAgICB9CisgIH0KK30KKwordWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVN0cmluZ1dpdGhTaXplVG9BcnJheShjb25zdCBzdHJpbmcmIHN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICBHT09HTEVfRENIRUNLX0xFKHN0ci5zaXplKCksIGt1aW50MzJtYXgpOworICB0YXJnZXQgPSBXcml0ZVZhcmludDMyVG9BcnJheShzdHIuc2l6ZSgpLCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVTdHJpbmdUb0FycmF5KHN0ciwgdGFyZ2V0KTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlYTRiNjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oCkBAIC0wLDAgKzEsMTI1MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyB0aGUgQ29kZWRJbnB1dFN0cmVhbSBhbmQgQ29kZWRPdXRwdXRTdHJlYW0gY2xhc3NlcywKKy8vIHdoaWNoIHdyYXAgYSBaZXJvQ29weUlucHV0U3RyZWFtIG9yIFplcm9Db3B5T3V0cHV0U3RyZWFtLCByZXNwZWN0aXZlbHksCisvLyBhbmQgYWxsb3cgeW91IHRvIHJlYWQgb3Igd3JpdGUgaW5kaXZpZHVhbCBwaWVjZXMgb2YgZGF0YSBpbiB2YXJpb3VzCisvLyBmb3JtYXRzLiAgSW4gcGFydGljdWxhciwgdGhlc2UgaW1wbGVtZW50IHRoZSB2YXJpbnQgZW5jb2RpbmcgZm9yCisvLyBpbnRlZ2VycywgYSBzaW1wbGUgdmFyaWFibGUtbGVuZ3RoIGVuY29kaW5nIGluIHdoaWNoIHNtYWxsZXIgbnVtYmVycworLy8gdGFrZSBmZXdlciBieXRlcy4KKy8vCisvLyBUeXBpY2FsbHkgdGhlc2UgY2xhc3NlcyB3aWxsIG9ubHkgYmUgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBwcm90b2NvbAorLy8gYnVmZmVyIGxpYnJhcnkgaW4gb3JkZXIgdG8gZW5jb2RlIGFuZCBkZWNvZGUgcHJvdG9jb2wgYnVmZmVycy4gIENsaWVudHMKKy8vIG9mIHRoZSBsaWJyYXJ5IG9ubHkgbmVlZCB0byBrbm93IGFib3V0IHRoaXMgY2xhc3MgaWYgdGhleSB3aXNoIHRvIHdyaXRlCisvLyBjdXN0b20gbWVzc2FnZSBwYXJzaW5nIG9yIHNlcmlhbGl6YXRpb24gcHJvY2VkdXJlcy4KKy8vCisvLyBDb2RlZE91dHB1dFN0cmVhbSBleGFtcGxlOgorLy8gICAvLyBXcml0ZSBzb21lIGRhdGEgdG8gIm15ZmlsZSIuICBGaXJzdCB3ZSB3cml0ZSBhIDQtYnl0ZSAibWFnaWMgbnVtYmVyIgorLy8gICAvLyB0byBpZGVudGlmeSB0aGUgZmlsZSB0eXBlLCB0aGVuIHdyaXRlIGEgbGVuZ3RoLWRlbGltaXRlZCBzdHJpbmcuICBUaGUKKy8vICAgLy8gc3RyaW5nIGlzIGNvbXBvc2VkIG9mIGEgdmFyaW50IGdpdmluZyB0aGUgbGVuZ3RoIGZvbGxvd2VkIGJ5IHRoZSByYXcKKy8vICAgLy8gYnl0ZXMuCisvLyAgIGludCBmZCA9IG9wZW4oIm15ZmlsZSIsIE9fQ1JFQVQgfCBPX1dST05MWSk7CisvLyAgIFplcm9Db3B5T3V0cHV0U3RyZWFtKiByYXdfb3V0cHV0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmQpOworLy8gICBDb2RlZE91dHB1dFN0cmVhbSogY29kZWRfb3V0cHV0ID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKHJhd19vdXRwdXQpOworLy8KKy8vICAgaW50IG1hZ2ljX251bWJlciA9IDEyMzQ7CisvLyAgIGNoYXIgdGV4dFtdID0gIkhlbGxvIHdvcmxkISI7CisvLyAgIGNvZGVkX291dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW4zMihtYWdpY19udW1iZXIpOworLy8gICBjb2RlZF9vdXRwdXQtPldyaXRlVmFyaW50MzIoc3RybGVuKHRleHQpKTsKKy8vICAgY29kZWRfb3V0cHV0LT5Xcml0ZVJhdyh0ZXh0LCBzdHJsZW4odGV4dCkpOworLy8KKy8vICAgZGVsZXRlIGNvZGVkX291dHB1dDsKKy8vICAgZGVsZXRlIHJhd19vdXRwdXQ7CisvLyAgIGNsb3NlKGZkKTsKKy8vCisvLyBDb2RlZElucHV0U3RyZWFtIGV4YW1wbGU6CisvLyAgIC8vIFJlYWQgYSBmaWxlIGNyZWF0ZWQgYnkgdGhlIGFib3ZlIGNvZGUuCisvLyAgIGludCBmZCA9IG9wZW4oIm15ZmlsZSIsIE9fUkRPTkxZKTsKKy8vICAgWmVyb0NvcHlJbnB1dFN0cmVhbSogcmF3X2lucHV0ID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmZCk7CisvLyAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQgPSBuZXcgQ29kZWRJbnB1dFN0cmVhbShyYXdfaW5wdXQpOworLy8KKy8vICAgY29kZWRfaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW4zMigmbWFnaWNfbnVtYmVyKTsKKy8vICAgaWYgKG1hZ2ljX251bWJlciAhPSAxMjM0KSB7CisvLyAgICAgY2VyciA8PCAiRmlsZSBub3QgaW4gZXhwZWN0ZWQgZm9ybWF0LiIgPDwgZW5kbDsKKy8vICAgICByZXR1cm47CisvLyAgIH0KKy8vCisvLyAgIHVpbnQzMiBzaXplOworLy8gICBjb2RlZF9pbnB1dC0+UmVhZFZhcmludDMyKCZzaXplKTsKKy8vCisvLyAgIGNoYXIqIHRleHQgPSBuZXcgY2hhcltzaXplICsgMV07CisvLyAgIGNvZGVkX2lucHV0LT5SZWFkUmF3KGJ1ZmZlciwgc2l6ZSk7CisvLyAgIHRleHRbc2l6ZV0gPSAnXDAnOworLy8KKy8vICAgZGVsZXRlIGNvZGVkX2lucHV0OworLy8gICBkZWxldGUgcmF3X2lucHV0OworLy8gICBjbG9zZShmZCk7CisvLworLy8gICBjb3V0IDw8ICJUZXh0IGlzOiAiIDw8IHRleHQgPDwgZW5kbDsKKy8vICAgZGVsZXRlIFtdIHRleHQ7CisvLworLy8gRm9yIHRob3NlIHdobyBhcmUgaW50ZXJlc3RlZCwgdmFyaW50IGVuY29kaW5nIGlzIGRlZmluZWQgYXMgZm9sbG93czoKKy8vCisvLyBUaGUgZW5jb2Rpbmcgb3BlcmF0ZXMgb24gdW5zaWduZWQgaW50ZWdlcnMgb2YgdXAgdG8gNjQgYml0cyBpbiBsZW5ndGguCisvLyBFYWNoIGJ5dGUgb2YgdGhlIGVuY29kZWQgdmFsdWUgaGFzIHRoZSBmb3JtYXQ6CisvLyAqIGJpdHMgMC02OiBTZXZlbiBiaXRzIG9mIHRoZSBudW1iZXIgYmVpbmcgZW5jb2RlZC4KKy8vICogYml0IDc6IFplcm8gaWYgdGhpcyBpcyB0aGUgbGFzdCBieXRlIGluIHRoZSBlbmNvZGluZyAoaW4gd2hpY2gKKy8vICAgY2FzZSBhbGwgcmVtYWluaW5nIGJpdHMgb2YgdGhlIG51bWJlciBhcmUgemVybykgb3IgMSBpZgorLy8gICBtb3JlIGJ5dGVzIGZvbGxvdy4KKy8vIFRoZSBmaXJzdCBieXRlIGNvbnRhaW5zIHRoZSBsZWFzdC1zaWduaWZpY2FudCA3IGJpdHMgb2YgdGhlIG51bWJlciwgdGhlCisvLyBzZWNvbmQgYnl0ZSAoaWYgcHJlc2VudCkgY29udGFpbnMgdGhlIG5leHQtbGVhc3Qtc2lnbmlmaWNhbnQgNyBiaXRzLAorLy8gYW5kIHNvIG9uLiAgU28sIHRoZSBiaW5hcnkgbnVtYmVyIDEwMTEwMDAxMDEwMTEgd291bGQgYmUgZW5jb2RlZCBpbiB0d28KKy8vIGJ5dGVzIGFzICIxMDEwMTAxMSAwMDEwMTEwMCIuCisvLworLy8gSW4gdGhlb3J5LCB2YXJpbnQgY291bGQgYmUgdXNlZCB0byBlbmNvZGUgaW50ZWdlcnMgb2YgYW55IGxlbmd0aC4KKy8vIEhvd2V2ZXIsIGZvciBwcmFjdGljYWxpdHkgd2Ugc2V0IGEgbGltaXQgYXQgNjQgYml0cy4gIFRoZSBtYXhpbXVtIGVuY29kZWQKKy8vIGxlbmd0aCBvZiBhIG51bWJlciBpcyB0aHVzIDEwIGJ5dGVzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19DT0RFRF9TVFJFQU1fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9JT19DT0RFRF9TVFJFQU1fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpZmRlZiBfTVNDX1ZFUgorICAjaWYgZGVmaW5lZChfTV9JWDg2KSAmJiBcCisgICAgICAhZGVmaW5lZChQUk9UT0JVRl9ESVNBQkxFX0xJVFRMRV9FTkRJQU5fT1BUX0ZPUl9URVNUKQorICAgICNkZWZpbmUgUFJPVE9CVUZfTElUVExFX0VORElBTiAxCisgICNlbmRpZgorICAjaWYgX01TQ19WRVIgPj0gMTMwMAorICAgIC8vIElmIE1TVkMgaGFzICIvUlRDYyIgc2V0LCBpdCB3aWxsIGNvbXBsYWluIGFib3V0IHRydW5jYXRpbmcgY2FzdHMgYXQKKyAgICAvLyBydW50aW1lLiAgVGhpcyBmaWxlIGNvbnRhaW5zIHNvbWUgaW50ZW50aW9uYWwgdHJ1bmNhdGluZyBjYXN0cy4KKyAgICAjcHJhZ21hIHJ1bnRpbWVfY2hlY2tzKCJjIiwgb2ZmKQorICAjZW5kaWYKKyNlbHNlCisgICNpbmNsdWRlIDxzeXMvcGFyYW0uaD4gICAvLyBfX0JZVEVfT1JERVIKKyAgI2lmICgoZGVmaW5lZChfX0xJVFRMRV9FTkRJQU5fXykgJiYgIWRlZmluZWQoX19CSUdfRU5ESUFOX18pKSB8fCBcCisgICAgICAgICAoZGVmaW5lZChfX0JZVEVfT1JERVIpICYmIF9fQllURV9PUkRFUiA9PSBfX0xJVFRMRV9FTkRJQU4pKSAmJiBcCisgICAgICAhZGVmaW5lZChQUk9UT0JVRl9ESVNBQkxFX0xJVFRMRV9FTkRJQU5fT1BUX0ZPUl9URVNUKQorICAgICNkZWZpbmUgUFJPVE9CVUZfTElUVExFX0VORElBTiAxCisgICNlbmRpZgorI2VuZGlmCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRGVzY3JpcHRvclBvb2w7CitjbGFzcyBNZXNzYWdlRmFjdG9yeTsKKworbmFtZXNwYWNlIGlvIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBDb2RlZElucHV0U3RyZWFtOworY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07CisKKy8vIERlZmluZWQgaW4gb3RoZXIgZmlsZXMuCitjbGFzcyBaZXJvQ29weUlucHV0U3RyZWFtOyAgICAgICAgICAgLy8gemVyb19jb3B5X3N0cmVhbS5oCitjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsgICAgICAgICAgLy8gemVyb19jb3B5X3N0cmVhbS5oCisKKy8vIENsYXNzIHdoaWNoIHJlYWRzIGFuZCBkZWNvZGVzIGJpbmFyeSBkYXRhIHdoaWNoIGlzIGNvbXBvc2VkIG9mIHZhcmludC0KKy8vIGVuY29kZWQgaW50ZWdlcnMgYW5kIGZpeGVkLXdpZHRoIHBpZWNlcy4gIFdyYXBzIGEgWmVyb0NvcHlJbnB1dFN0cmVhbS4KKy8vIE1vc3QgdXNlcnMgd2lsbCBub3QgbmVlZCB0byBkZWFsIHdpdGggQ29kZWRJbnB1dFN0cmVhbS4KKy8vCisvLyBNb3N0IG1ldGhvZHMgb2YgQ29kZWRJbnB1dFN0cmVhbSB0aGF0IHJldHVybiBhIGJvb2wgcmV0dXJuIGZhbHNlIGlmIGFuCisvLyB1bmRlcmx5aW5nIEkvTyBlcnJvciBvY2N1cnMgb3IgaWYgdGhlIGRhdGEgaXMgbWFsZm9ybWVkLiAgT25jZSBzdWNoIGEKKy8vIGZhaWx1cmUgb2NjdXJzLCB0aGUgQ29kZWRJbnB1dFN0cmVhbSBpcyBicm9rZW4gYW5kIGlzIG5vIGxvbmdlciB1c2VmdWwuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29kZWRJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBDb2RlZElucHV0U3RyZWFtIHRoYXQgcmVhZHMgZnJvbSB0aGUgZ2l2ZW4gWmVyb0NvcHlJbnB1dFN0cmVhbS4KKyAgZXhwbGljaXQgQ29kZWRJbnB1dFN0cmVhbShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCk7CisKKyAgLy8gQ3JlYXRlIGEgQ29kZWRJbnB1dFN0cmVhbSB0aGF0IHJlYWRzIGZyb20gdGhlIGdpdmVuIGZsYXQgYXJyYXkuICBUaGlzIGlzCisgIC8vIGZhc3RlciB0aGFuIHVzaW5nIGFuIEFycmF5SW5wdXRTdHJlYW0uICBQdXNoTGltaXQoc2l6ZSkgaXMgaW1wbGllZCBieQorICAvLyB0aGlzIGNvbnN0cnVjdG9yLgorICBleHBsaWNpdCBDb2RlZElucHV0U3RyZWFtKGNvbnN0IHVpbnQ4KiBidWZmZXIsIGludCBzaXplKTsKKworICAvLyBEZXN0cm95IHRoZSBDb2RlZElucHV0U3RyZWFtIGFuZCBwb3NpdGlvbiB0aGUgdW5kZXJseWluZworICAvLyBaZXJvQ29weUlucHV0U3RyZWFtIGF0IHRoZSBmaXJzdCB1bnJlYWQgYnl0ZS4gIElmIGFuIGVycm9yIG9jY3VycmVkIHdoaWxlCisgIC8vIHJlYWRpbmcgKGNhdXNpbmcgYSBtZXRob2QgdG8gcmV0dXJuIGZhbHNlKSwgdGhlbiB0aGUgZXhhY3QgcG9zaXRpb24gb2YKKyAgLy8gdGhlIGlucHV0IHN0cmVhbSBtYXkgYmUgYW55d2hlcmUgYmV0d2VlbiB0aGUgbGFzdCB2YWx1ZSB0aGF0IHdhcyByZWFkCisgIC8vIHN1Y2Nlc3NmdWxseSBhbmQgdGhlIHN0cmVhbSdzIGJ5dGUgbGltaXQuCisgIH5Db2RlZElucHV0U3RyZWFtKCk7CisKKyAgLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBDb2RlZElucHV0U3RyZWFtIHJlYWRzIGZyb20gYSBmbGF0IGFycmF5IGluc3RlYWQgb2YKKyAgLy8gYSBaZXJvQ29weUlucHV0U3RyZWFtLgorICBpbmxpbmUgYm9vbCBJc0ZsYXQoKSBjb25zdDsKKworICAvLyBTa2lwcyBhIG51bWJlciBvZiBieXRlcy4gIFJldHVybnMgZmFsc2UgaWYgYW4gdW5kZXJseWluZyByZWFkIGVycm9yCisgIC8vIG9jY3Vycy4KKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisKKyAgLy8gU2V0cyAqZGF0YSB0byBwb2ludCBkaXJlY3RseSBhdCB0aGUgdW5yZWFkIHBhcnQgb2YgdGhlIENvZGVkSW5wdXRTdHJlYW0ncworICAvLyB1bmRlcmx5aW5nIGJ1ZmZlciwgYW5kICpzaXplIHRvIHRoZSBzaXplIG9mIHRoYXQgYnVmZmVyLCBidXQgZG9lcyBub3QKKyAgLy8gYWR2YW5jZSB0aGUgc3RyZWFtJ3MgY3VycmVudCBwb3NpdGlvbi4gIFRoaXMgd2lsbCBhbHdheXMgZWl0aGVyIHByb2R1Y2UKKyAgLy8gYSBub24tZW1wdHkgYnVmZmVyIG9yIHJldHVybiBmYWxzZS4gIElmIHRoZSBjYWxsZXIgY29uc3VtZXMgYW55IG9mCisgIC8vIHRoaXMgZGF0YSwgaXQgc2hvdWxkIHRoZW4gY2FsbCBTa2lwKCkgdG8gc2tpcCBvdmVyIHRoZSBjb25zdW1lZCBieXRlcy4KKyAgLy8gVGhpcyBtYXkgYmUgdXNlZnVsIGZvciBpbXBsZW1lbnRpbmcgZXh0ZXJuYWwgZmFzdCBwYXJzaW5nIHJvdXRpbmVzIGZvcgorICAvLyB0eXBlcyBvZiBkYXRhIG5vdCBjb3ZlcmVkIGJ5IHRoZSBDb2RlZElucHV0U3RyZWFtIGludGVyZmFjZS4KKyAgYm9vbCBHZXREaXJlY3RCdWZmZXJQb2ludGVyKGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworCisgIC8vIExpa2UgR2V0RGlyZWN0QnVmZmVyUG9pbnRlciwgYnV0IHRoaXMgbWV0aG9kIGlzIGlubGluZWQsIGFuZCBkb2VzIG5vdAorICAvLyBhdHRlbXB0IHRvIFJlZnJlc2goKSBpZiB0aGUgYnVmZmVyIGlzIGN1cnJlbnRseSBlbXB0eS4KKyAgaW5saW5lIHZvaWQgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZShjb25zdCB2b2lkKiogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQqIHNpemUpIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORTsKKworICAvLyBSZWFkIHJhdyBieXRlcywgY29weWluZyB0aGVtIGludG8gdGhlIGdpdmVuIGJ1ZmZlci4KKyAgYm9vbCBSZWFkUmF3KHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpOworCisgIC8vIExpa2UgUmVhZFJhdywgYnV0IHJlYWRzIGludG8gYSBzdHJpbmcuCisgIC8vCisgIC8vIEltcGxlbWVudGF0aW9uIE5vdGU6ICBSZWFkU3RyaW5nKCkgZ3Jvd3MgdGhlIHN0cmluZyBncmFkdWFsbHkgYXMgaXQKKyAgLy8gcmVhZHMgaW4gdGhlIGRhdGEsIHJhdGhlciB0aGFuIGFsbG9jYXRpbmcgdGhlIGVudGlyZSByZXF1ZXN0ZWQgc2l6ZQorICAvLyB1cGZyb250LiAgVGhpcyBwcmV2ZW50cyBkZW5pYWwtb2Ytc2VydmljZSBhdHRhY2tzIGluIHdoaWNoIGEgY2xpZW50CisgIC8vIGNvdWxkIGNsYWltIHRoYXQgYSBzdHJpbmcgaXMgZ29pbmcgdG8gYmUgTUFYX0lOVCBieXRlcyBsb25nIGluIG9yZGVyIHRvCisgIC8vIGNyYXNoIHRoZSBzZXJ2ZXIgYmVjYXVzZSBpdCBjYW4ndCBhbGxvY2F0ZSB0aGlzIG11Y2ggc3BhY2UgYXQgb25jZS4KKyAgYm9vbCBSZWFkU3RyaW5nKHN0cmluZyogYnVmZmVyLCBpbnQgc2l6ZSk7CisgIC8vIExpa2UgdGhlIGFib3ZlLCB3aXRoIGlubGluZWQgb3B0aW1pemF0aW9ucy4gVGhpcyBzaG91bGQgb25seSBiZSB1c2VkCisgIC8vIGJ5IHRoZSBwcm90b2J1ZiBpbXBsZW1lbnRhdGlvbi4KKyAgaW5saW5lIGJvb2wgSW50ZXJuYWxSZWFkU3RyaW5nSW5saW5lKHN0cmluZyogYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUpIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORTsKKworCisgIC8vIFJlYWQgYSAzMi1iaXQgbGl0dGxlLWVuZGlhbiBpbnRlZ2VyLgorICBib29sIFJlYWRMaXR0bGVFbmRpYW4zMih1aW50MzIqIHZhbHVlKTsKKyAgLy8gUmVhZCBhIDY0LWJpdCBsaXR0bGUtZW5kaWFuIGludGVnZXIuCisgIGJvb2wgUmVhZExpdHRsZUVuZGlhbjY0KHVpbnQ2NCogdmFsdWUpOworCisgIC8vIFRoZXNlIG1ldGhvZHMgcmVhZCBmcm9tIGFuIGV4dGVybmFsbHkgcHJvdmlkZWQgYnVmZmVyLiBUaGUgY2FsbGVyIGlzCisgIC8vIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGF0IHRoZSBidWZmZXIgaGFzIHN1ZmZpY2llbnQgc3BhY2UuCisgIC8vIFJlYWQgYSAzMi1iaXQgbGl0dGxlLWVuZGlhbiBpbnRlZ2VyLgorICBzdGF0aWMgY29uc3QgdWludDgqIFJlYWRMaXR0bGVFbmRpYW4zMkZyb21BcnJheShjb25zdCB1aW50OCogYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyKiB2YWx1ZSk7CisgIC8vIFJlYWQgYSA2NC1iaXQgbGl0dGxlLWVuZGlhbiBpbnRlZ2VyLgorICBzdGF0aWMgY29uc3QgdWludDgqIFJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheShjb25zdCB1aW50OCogYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0KiB2YWx1ZSk7CisKKyAgLy8gUmVhZCBhbiB1bnNpZ25lZCBpbnRlZ2VyIHdpdGggVmFyaW50IGVuY29kaW5nLCB0cnVuY2F0aW5nIHRvIDMyIGJpdHMuCisgIC8vIFJlYWRpbmcgYSAzMi1iaXQgdmFsdWUgaXMgZXF1aXZhbGVudCB0byByZWFkaW5nIGEgNjQtYml0IG9uZSBhbmQgY2FzdGluZworICAvLyBpdCB0byB1aW50MzIsIGJ1dCBtYXkgYmUgbW9yZSBlZmZpY2llbnQuCisgIGJvb2wgUmVhZFZhcmludDMyKHVpbnQzMiogdmFsdWUpOworICAvLyBSZWFkIGFuIHVuc2lnbmVkIGludGVnZXIgd2l0aCBWYXJpbnQgZW5jb2RpbmcuCisgIGJvb2wgUmVhZFZhcmludDY0KHVpbnQ2NCogdmFsdWUpOworCisgIC8vIFJlYWQgYSB0YWcuICBUaGlzIGNhbGxzIFJlYWRWYXJpbnQzMigpIGFuZCByZXR1cm5zIHRoZSByZXN1bHQsIG9yIHJldHVybnMKKyAgLy8gemVybyAod2hpY2ggaXMgbm90IGEgdmFsaWQgdGFnKSBpZiBSZWFkVmFyaW50MzIoKSBmYWlscy4gIEFsc28sIGl0IHVwZGF0ZXMKKyAgLy8gdGhlIGxhc3QgdGFnIHZhbHVlLCB3aGljaCBjYW4gYmUgY2hlY2tlZCB3aXRoIExhc3RUYWdXYXMoKS4KKyAgLy8gQWx3YXlzIGlubGluZSBiZWNhdXNlIHRoaXMgaXMgb25seSBjYWxsZWQgaW4gb25lIHBsYWNlIHBlciBwYXJzZSBsb29wCisgIC8vIGJ1dCBpdCBpcyBjYWxsZWQgZm9yIGV2ZXJ5IGl0ZXJhdGlvbiBvZiBzYWlkIGxvb3AsIHNvIGl0IHNob3VsZCBiZSBmYXN0LgorICAvLyBHQ0MgZG9lc24ndCB3YW50IHRvIGlubGluZSB0aGlzIGJ5IGRlZmF1bHQuCisgIHVpbnQzMiBSZWFkVGFnKCkgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworCisgIC8vIFRoaXMgdXN1YWxseSBhIGZhc3RlciBhbHRlcm5hdGl2ZSB0byBSZWFkVGFnKCkgd2hlbiBjdXRvZmYgaXMgYSBtYW5pZmVzdAorICAvLyBjb25zdGFudC4gIEl0IGRvZXMgcGFydGljdWxhcmx5IHdlbGwgZm9yIGN1dG9mZiA+PSAxMjcuICBUaGUgZmlyc3QgcGFydAorICAvLyBvZiB0aGUgcmV0dXJuIHZhbHVlIGlzIHRoZSB0YWcgdGhhdCB3YXMgcmVhZCwgdGhvdWdoIGl0IGNhbiBhbHNvIGJlIDAgaW4KKyAgLy8gdGhlIGNhc2VzIHdoZXJlIFJlYWRUYWcoKSB3b3VsZCByZXR1cm4gMC4gIElmIHRoZSBzZWNvbmQgcGFydCBpcyB0cnVlCisgIC8vIHRoZW4gdGhlIHRhZyBpcyBrbm93biB0byBiZSBpbiBbMCwgY3V0b2ZmXS4gIElmIG5vdCwgdGhlIHRhZyBlaXRoZXIgaXMKKyAgLy8gYWJvdmUgY3V0b2ZmIG9yIGlzIDAuICAoVGhlcmUncyBpbnRlbnRpb25hbCB3aWdnbGUgcm9vbSB3aGVuIHRhZyBpcyAwLAorICAvLyBiZWNhdXNlIHRoYXQgY2FuIGFyaXNlIGluIHNldmVyYWwgd2F5cywgYW5kIGZvciBiZXN0IHBlcmZvcm1hbmNlIHdlIHdhbnQKKyAgLy8gdG8gYXZvaWQgYW4gZXh0cmEgImlzIHRhZyA9PSAwPyIgY2hlY2sgaGVyZS4pCisgIGlubGluZSBzdGQ6OnBhaXI8dWludDMyLCBib29sPiBSZWFkVGFnV2l0aEN1dG9mZih1aW50MzIgY3V0b2ZmKQorICAgICAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworCisgIC8vIFVzdWFsbHkgcmV0dXJucyB0cnVlIGlmIGNhbGxpbmcgUmVhZFZhcmludDMyKCkgbm93IHdvdWxkIHByb2R1Y2UgdGhlIGdpdmVuCisgIC8vIHZhbHVlLiAgV2lsbCBhbHdheXMgcmV0dXJuIGZhbHNlIGlmIFJlYWRWYXJpbnQzMigpIHdvdWxkIG5vdCByZXR1cm4gdGhlCisgIC8vIGdpdmVuIHZhbHVlLiAgSWYgRXhwZWN0VGFnKCkgcmV0dXJucyB0cnVlLCBpdCBhbHNvIGFkdmFuY2VzIHBhc3QKKyAgLy8gdGhlIHZhcmludC4gIEZvciBiZXN0IHBlcmZvcm1hbmNlLCB1c2UgYSBjb21waWxlLXRpbWUgY29uc3RhbnQgYXMgdGhlCisgIC8vIHBhcmFtZXRlci4KKyAgLy8gQWx3YXlzIGlubGluZSBiZWNhdXNlIHRoaXMgY29sbGFwc2VzIHRvIGEgc21hbGwgbnVtYmVyIG9mIGluc3RydWN0aW9ucworICAvLyB3aGVuIGdpdmVuIGEgY29uc3RhbnQgcGFyYW1ldGVyLCBidXQgR0NDIGRvZXNuJ3Qgd2FudCB0byBpbmxpbmUgYnkgZGVmYXVsdC4KKyAgYm9vbCBFeHBlY3RUYWcodWludDMyIGV4cGVjdGVkKSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkU7CisKKyAgLy8gTGlrZSBhYm92ZSwgZXhjZXB0IHRoaXMgcmVhZHMgZnJvbSB0aGUgc3BlY2lmaWVkIGJ1ZmZlci4gVGhlIGNhbGxlciBpcworICAvLyByZXNwb25zaWJsZSBmb3IgZW5zdXJpbmcgdGhhdCB0aGUgYnVmZmVyIGlzIGxhcmdlIGVub3VnaCB0byByZWFkIGEgdmFyaW50CisgIC8vIG9mIHRoZSBleHBlY3RlZCBzaXplLiBGb3IgYmVzdCBwZXJmb3JtYW5jZSwgdXNlIGEgY29tcGlsZS10aW1lIGNvbnN0YW50IGFzCisgIC8vIHRoZSBleHBlY3RlZCB0YWcgcGFyYW1ldGVyLgorICAvLworICAvLyBSZXR1cm5zIGEgcG9pbnRlciBiZXlvbmQgdGhlIGV4cGVjdGVkIHRhZyBpZiBpdCB3YXMgZm91bmQsIG9yIE5VTEwgaWYgaXQKKyAgLy8gd2FzIG5vdC4KKyAgc3RhdGljIGNvbnN0IHVpbnQ4KiBFeHBlY3RUYWdGcm9tQXJyYXkoCisgICAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgICAgdWludDMyIGV4cGVjdGVkKSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkU7CisKKyAgLy8gVXN1YWxseSByZXR1cm5zIHRydWUgaWYgbm8gbW9yZSBieXRlcyBjYW4gYmUgcmVhZC4gIEFsd2F5cyByZXR1cm5zIGZhbHNlCisgIC8vIGlmIG1vcmUgYnl0ZXMgY2FuIGJlIHJlYWQuICBJZiBFeHBlY3RBdEVuZCgpIHJldHVybnMgdHJ1ZSwgYSBzdWJzZXF1ZW50CisgIC8vIGNhbGwgdG8gTGFzdFRhZ1dhcygpIHdpbGwgYWN0IGFzIGlmIFJlYWRUYWcoKSBoYWQgYmVlbiBjYWxsZWQgYW5kIHJldHVybmVkCisgIC8vIHplcm8sIGFuZCBDb25zdW1lZEVudGlyZU1lc3NhZ2UoKSB3aWxsIHJldHVybiB0cnVlLgorICBib29sIEV4cGVjdEF0RW5kKCk7CisKKyAgLy8gSWYgdGhlIGxhc3QgY2FsbCB0byBSZWFkVGFnKCkgb3IgUmVhZFRhZ1dpdGhDdXRvZmYoKSByZXR1cm5lZCB0aGUKKyAgLy8gZ2l2ZW4gdmFsdWUsIHJldHVybnMgdHJ1ZS4gIE90aGVyd2lzZSwgcmV0dXJucyBmYWxzZTsKKyAgLy8KKyAgLy8gVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBwYXJzZXJzIGZvciBzb21lIHR5cGVzIG9mIGVtYmVkZGVkIG1lc3NhZ2VzCisgIC8vICh3aXRoIGZpZWxkIHR5cGUgVFlQRV9HUk9VUCkgZG9uJ3QgYWN0dWFsbHkga25vdyB0aGF0IHRoZXkndmUgcmVhY2hlZCB0aGUKKyAgLy8gZW5kIG9mIGEgbWVzc2FnZSB1bnRpbCB0aGV5IHNlZSBhbiBFTkRHUk9VUCB0YWcsIHdoaWNoIHdhcyBhY3R1YWxseSBwYXJ0CisgIC8vIG9mIHRoZSBlbmNsb3NpbmcgbWVzc2FnZS4gIFRoZSBlbmNsb3NpbmcgbWVzc2FnZSB3b3VsZCBsaWtlIHRvIGNoZWNrIHRoYXQKKyAgLy8gdGFnIHRvIG1ha2Ugc3VyZSBpdCBoYWQgdGhlIHJpZ2h0IG51bWJlciwgc28gaXQgY2FsbHMgTGFzdFRhZ1dhcygpIG9uCisgIC8vIHJldHVybiBmcm9tIHRoZSBlbWJlZGRlZCBwYXJzZXIgdG8gY2hlY2suCisgIGJvb2wgTGFzdFRhZ1dhcyh1aW50MzIgZXhwZWN0ZWQpOworCisgIC8vIFdoZW4gcGFyc2luZyBtZXNzYWdlIChidXQgTk9UIGEgZ3JvdXApLCB0aGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZAorICAvLyBpbW1lZGlhdGVseSBhZnRlciBNZXJnZUZyb21Db2RlZFN0cmVhbSgpIHJldHVybnMgKGlmIGl0IHJldHVybnMgdHJ1ZSkKKyAgLy8gdG8gZnVydGhlciB2ZXJpZnkgdGhhdCB0aGUgbWVzc2FnZSBlbmRlZCBpbiBhIGxlZ2l0aW1hdGUgd2F5LiAgRm9yCisgIC8vIGV4YW1wbGUsIHRoaXMgdmVyaWZpZXMgdGhhdCBwYXJzaW5nIGRpZCBub3QgZW5kIG9uIGFuIGVuZC1ncm91cCB0YWcuCisgIC8vIEl0IGFsc28gY2hlY2tzIGZvciBzb21lIGNhc2VzIHdoZXJlLCBkdWUgdG8gb3B0aW1pemF0aW9ucywKKyAgLy8gTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSBjYW4gaW5jb3JyZWN0bHkgcmV0dXJuIHRydWUuCisgIGJvb2wgQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCk7CisKKyAgLy8gTGltaXRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gTGltaXRzIGFyZSB1c2VkIHdoZW4gcGFyc2luZyBsZW5ndGgtZGVsaW1pdGVkIGVtYmVkZGVkIG1lc3NhZ2VzLgorICAvLyBBZnRlciB0aGUgbWVzc2FnZSdzIGxlbmd0aCBpcyByZWFkLCBQdXNoTGltaXQoKSBpcyB1c2VkIHRvIHByZXZlbnQKKyAgLy8gdGhlIENvZGVkSW5wdXRTdHJlYW0gZnJvbSByZWFkaW5nIGJleW9uZCB0aGF0IGxlbmd0aC4gIE9uY2UgdGhlCisgIC8vIGVtYmVkZGVkIG1lc3NhZ2UgaGFzIGJlZW4gcGFyc2VkLCBQb3BMaW1pdCgpIGlzIGNhbGxlZCB0byB1bmRvIHRoZQorICAvLyBsaW1pdC4KKworICAvLyBPcGFxdWUgdHlwZSB1c2VkIHdpdGggUHVzaExpbWl0KCkgYW5kIFBvcExpbWl0KCkuICBEbyBub3QgbW9kaWZ5CisgIC8vIHZhbHVlcyBvZiB0aGlzIHR5cGUgeW91cnNlbGYuICBUaGUgb25seSByZWFzb24gdGhhdCB0aGlzIGlzbid0IGEKKyAgLy8gc3RydWN0IHdpdGggcHJpdmF0ZSBpbnRlcm5hbHMgaXMgZm9yIGVmZmljaWVuY3kuCisgIHR5cGVkZWYgaW50IExpbWl0OworCisgIC8vIFBsYWNlcyBhIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB0aGUgc3RyZWFtIG1heSByZWFkLAorICAvLyBzdGFydGluZyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uLiAgT25jZSB0aGUgc3RyZWFtIGhpdHMgdGhpcyBsaW1pdCwKKyAgLy8gaXQgd2lsbCBhY3QgbGlrZSB0aGUgZW5kIG9mIHRoZSBpbnB1dCBoYXMgYmVlbiByZWFjaGVkIHVudGlsIFBvcExpbWl0KCkKKyAgLy8gaXMgY2FsbGVkLgorICAvLworICAvLyBBcyB0aGUgbmFtZXMgaW1wbHksIHRoZSBzdHJlYW0gY29uY2VwdHVhbGx5IGhhcyBhIHN0YWNrIG9mIGxpbWl0cy4gIFRoZQorICAvLyBzaG9ydGVzdCBsaW1pdCBvbiB0aGUgc3RhY2sgaXMgYWx3YXlzIGVuZm9yY2VkLCBldmVuIGlmIGl0IGlzIG5vdCB0aGUKKyAgLy8gdG9wIGxpbWl0LgorICAvLworICAvLyBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgUHVzaExpbWl0KCkgaXMgb3BhcXVlIHRvIHRoZSBjYWxsZXIsIGFuZCBtdXN0CisgIC8vIGJlIHBhc3NlZCB1bmNoYW5nZWQgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY2FsbCB0byBQb3BMaW1pdCgpLgorICBMaW1pdCBQdXNoTGltaXQoaW50IGJ5dGVfbGltaXQpOworCisgIC8vIFBvcHMgdGhlIGxhc3QgbGltaXQgcHVzaGVkIGJ5IFB1c2hMaW1pdCgpLiAgVGhlIGlucHV0IG11c3QgYmUgdGhlIHZhbHVlCisgIC8vIHJldHVybmVkIGJ5IHRoYXQgY2FsbCB0byBQdXNoTGltaXQoKS4KKyAgdm9pZCBQb3BMaW1pdChMaW1pdCBsaW1pdCk7CisKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGxlZnQgdW50aWwgdGhlIG5lYXJlc3QgbGltaXQgb24gdGhlCisgIC8vIHN0YWNrIGlzIGhpdCwgb3IgLTEgaWYgbm8gbGltaXRzIGFyZSBpbiBwbGFjZS4KKyAgaW50IEJ5dGVzVW50aWxMaW1pdCgpIGNvbnN0OworCisgIC8vIFJldHVybnMgY3VycmVudCBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBpbnB1dCBzdHJlYW0uCisgIGludCBDdXJyZW50UG9zaXRpb24oKSBjb25zdDsKKworICAvLyBUb3RhbCBCeXRlcyBMaW1pdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUbyBwcmV2ZW50IG1hbGljaW91cyB1c2VycyBmcm9tIHNlbmRpbmcgZXhjZXNzaXZlbHkgbGFyZ2UgbWVzc2FnZXMKKyAgLy8gYW5kIGNhdXNpbmcgaW50ZWdlciBvdmVyZmxvd3Mgb3IgbWVtb3J5IGV4aGF1c3Rpb24sIENvZGVkSW5wdXRTdHJlYW0KKyAgLy8gaW1wb3NlcyBhIGhhcmQgbGltaXQgb24gdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyBpdCB3aWxsIHJlYWQuCisKKyAgLy8gU2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB0aGlzIENvZGVkSW5wdXRTdHJlYW0gd2lsbCByZWFkCisgIC8vIGJlZm9yZSByZWZ1c2luZyB0byBjb250aW51ZS4gIFRvIHByZXZlbnQgaW50ZWdlciBvdmVyZmxvd3MgaW4gdGhlCisgIC8vIHByb3RvY29sIGJ1ZmZlcnMgaW1wbGVtZW50YXRpb24sIGFzIHdlbGwgYXMgdG8gcHJldmVudCBzZXJ2ZXJzIGZyb20KKyAgLy8gYWxsb2NhdGluZyBlbm9ybW91cyBhbW91bnRzIG9mIG1lbW9yeSB0byBob2xkIHBhcnNlZCBtZXNzYWdlcywgdGhlCisgIC8vIG1heGltdW0gbWVzc2FnZSBsZW5ndGggc2hvdWxkIGJlIGxpbWl0ZWQgdG8gdGhlIHNob3J0ZXN0IGxlbmd0aCB0aGF0CisgIC8vIHdpbGwgbm90IGhhcm0gdXNhYmlsaXR5LiAgVGhlIHRoZW9yZXRpY2FsIHNob3J0ZXN0IG1lc3NhZ2UgdGhhdCBjb3VsZAorICAvLyBjYXVzZSBpbnRlZ2VyIG92ZXJmbG93cyBpcyA1MTJNQi4gIFRoZSBkZWZhdWx0IGxpbWl0IGlzIDY0TUIuICBBcHBzCisgIC8vIHNob3VsZCBzZXQgc2hvcnRlciBsaW1pdHMgaWYgcG9zc2libGUuICBJZiB3YXJuaW5nX3RocmVzaG9sZCBpcyBub3QgLTEsCisgIC8vIGEgd2FybmluZyB3aWxsIGJlIHByaW50ZWQgdG8gc3RkZXJyIGFmdGVyIHdhcm5pbmdfdGhyZXNob2xkIGJ5dGVzIGFyZQorICAvLyByZWFkLiAgRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGFsbCBuZWdhdGl2ZSB2YWx1ZXMgZ2V0IHNxdWFzaGVkIHRvIC0xLAorICAvLyBhcyBvdGhlciBuZWdhdGl2ZSB2YWx1ZXMgbWlnaHQgaGF2ZSBzcGVjaWFsIGludGVybmFsIG1lYW5pbmdzLgorICAvLyBBbiBlcnJvciB3aWxsIGFsd2F5cyBiZSBwcmludGVkIHRvIHN0ZGVyciBpZiB0aGUgbGltaXQgaXMgcmVhY2hlZC4KKyAgLy8KKyAgLy8gVGhpcyBpcyB1bnJlbGF0ZWQgdG8gUHVzaExpbWl0KCkvUG9wTGltaXQoKS4KKyAgLy8KKyAgLy8gSGludDogIElmIHlvdSBhcmUgcmVhZGluZyB0aGlzIGJlY2F1c2UgeW91ciBwcm9ncmFtIGlzIHByaW50aW5nIGEKKyAgLy8gICB3YXJuaW5nIGFib3V0IGRhbmdlcm91c2x5IGxhcmdlIHByb3RvY29sIG1lc3NhZ2VzLCB5b3UgbWF5IGJlCisgIC8vICAgY29uZnVzZWQgYWJvdXQgd2hhdCB0byBkbyBuZXh0LiAgVGhlIGJlc3Qgb3B0aW9uIGlzIHRvIGNoYW5nZSB5b3VyCisgIC8vICAgZGVzaWduIHN1Y2ggdGhhdCBleGNlc3NpdmVseSBsYXJnZSBtZXNzYWdlcyBhcmUgbm90IG5lY2Vzc2FyeS4KKyAgLy8gICBGb3IgZXhhbXBsZSwgdHJ5IHRvIGRlc2lnbiBmaWxlIGZvcm1hdHMgdG8gY29uc2lzdCBvZiBtYW55IHNtYWxsCisgIC8vICAgbWVzc2FnZXMgcmF0aGVyIHRoYW4gYSBzaW5nbGUgbGFyZ2Ugb25lLiAgSWYgdGhpcyBpcyBpbmZlYXNpYmxlLAorICAvLyAgIHlvdSB3aWxsIG5lZWQgdG8gaW5jcmVhc2UgdGhlIGxpbWl0LiAgQ2hhbmNlcyBhcmUsIHRob3VnaCwgdGhhdAorICAvLyAgIHlvdXIgY29kZSBuZXZlciBjb25zdHJ1Y3RzIGEgQ29kZWRJbnB1dFN0cmVhbSBvbiB3aGljaCB0aGUgbGltaXQKKyAgLy8gICBjYW4gYmUgc2V0LiAgWW91IHByb2JhYmx5IHBhcnNlIG1lc3NhZ2VzIGJ5IGNhbGxpbmcgdGhpbmdzIGxpa2UKKyAgLy8gICBNZXNzYWdlOjpQYXJzZUZyb21TdHJpbmcoKS4gIEluIHRoaXMgY2FzZSwgeW91IHdpbGwgbmVlZCB0byBjaGFuZ2UKKyAgLy8gICB5b3VyIGNvZGUgdG8gaW5zdGVhZCBjb25zdHJ1Y3Qgc29tZSBzb3J0IG9mIFplcm9Db3B5SW5wdXRTdHJlYW0KKyAgLy8gICAoZS5nLiBhbiBBcnJheUlucHV0U3RyZWFtKSwgY29uc3RydWN0IGEgQ29kZWRJbnB1dFN0cmVhbSBhcm91bmQKKyAgLy8gICB0aGF0LCB0aGVuIGNhbGwgTWVzc2FnZTo6UGFyc2VGcm9tQ29kZWRTdHJlYW0oKSBpbnN0ZWFkLiAgVGhlbgorICAvLyAgIHlvdSBjYW4gYWRqdXN0IHRoZSBsaW1pdC4gIFllcywgaXQncyBtb3JlIHdvcmssIGJ1dCB5b3UncmUgZG9pbmcKKyAgLy8gICBzb21ldGhpbmcgdW51c3VhbC4KKyAgdm9pZCBTZXRUb3RhbEJ5dGVzTGltaXQoaW50IHRvdGFsX2J5dGVzX2xpbWl0LCBpbnQgd2FybmluZ190aHJlc2hvbGQpOworCisgIC8vIFRoZSBUb3RhbCBCeXRlcyBMaW1pdCBtaW51cyB0aGUgQ3VycmVudCBQb3NpdGlvbiwgb3IgLTEgaWYgdGhlcmUKKyAgLy8gaXMgbm8gVG90YWwgQnl0ZXMgTGltaXQuCisgIGludCBCeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCkgY29uc3Q7CisKKyAgLy8gUmVjdXJzaW9uIExpbWl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVG8gcHJldmVudCBjb3JydXB0IG9yIG1hbGljaW91cyBtZXNzYWdlcyBmcm9tIGNhdXNpbmcgc3RhY2sgb3ZlcmZsb3dzLAorICAvLyB3ZSBtdXN0IGtlZXAgdHJhY2sgb2YgdGhlIGRlcHRoIG9mIHJlY3Vyc2lvbiB3aGVuIHBhcnNpbmcgZW1iZWRkZWQKKyAgLy8gbWVzc2FnZXMgYW5kIGdyb3Vwcy4gIENvZGVkSW5wdXRTdHJlYW0ga2VlcHMgdHJhY2sgb2YgdGhpcyBiZWNhdXNlIGl0CisgIC8vIGlzIHRoZSBvbmx5IG9iamVjdCB0aGF0IGlzIHBhc3NlZCBkb3duIHRoZSBzdGFjayBkdXJpbmcgcGFyc2luZy4KKworICAvLyBTZXRzIHRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC4gIFRoZSBkZWZhdWx0IGlzIDEwMC4KKyAgdm9pZCBTZXRSZWN1cnNpb25MaW1pdChpbnQgbGltaXQpOworCisKKyAgLy8gSW5jcmVtZW50cyB0aGUgY3VycmVudCByZWN1cnNpb24gZGVwdGguICBSZXR1cm5zIHRydWUgaWYgdGhlIGRlcHRoIGlzCisgIC8vIHVuZGVyIHRoZSBsaW1pdCwgZmFsc2UgaWYgaXQgaGFzIGdvbmUgb3Zlci4KKyAgYm9vbCBJbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworCisgIC8vIERlY3JlbWVudHMgdGhlIHJlY3Vyc2lvbiBkZXB0aC4KKyAgdm9pZCBEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworCisgIC8vIFNob3J0aGFuZCBmb3IgbWFrZV9wYWlyKFB1c2hMaW1pdChieXRlX2xpbWl0KSwgLS1yZWN1cnNpb25fYnVkZ2V0XykuCisgIC8vIFVzaW5nIHRoaXMgY2FuIHJlZHVjZSBjb2RlIHNpemUgYW5kIGNvbXBsZXhpdHkgaW4gc29tZSBjYXNlcy4gIFRoZSBjYWxsZXIKKyAgLy8gaXMgZXhwZWN0ZWQgdG8gY2hlY2sgdGhhdCB0aGUgc2Vjb25kIHBhcnQgb2YgdGhlIHJlc3VsdCBpcyBub24tbmVnYXRpdmUgKHRvCisgIC8vIGJhaWwgb3V0IGlmIHRoZSBkZXB0aCBvZiByZWN1cnNpb24gaXMgdG9vIGhpZ2gpIGFuZCwgaWYgYWxsIGlzIHdlbGwsIHRvCisgIC8vIGxhdGVyIHBhc3MgdGhlIGZpcnN0IHBhcnQgb2YgdGhlIHJlc3VsdCB0byBQb3BMaW1pdCgpIG9yIHNpbWlsYXIuCisgIHN0ZDo6cGFpcjxDb2RlZElucHV0U3RyZWFtOjpMaW1pdCwgaW50PiBJbmNyZW1lbnRSZWN1cnNpb25EZXB0aEFuZFB1c2hMaW1pdCgKKyAgICAgIGludCBieXRlX2xpbWl0KTsKKworICAvLyBIZWxwZXIgdGhhdCBpcyBlcXVpdmFsZW50IHRvOiB7CisgIC8vICBib29sIHJlc3VsdCA9IENvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworICAvLyAgUG9wTGltaXQobGltaXQpOworICAvLyAgRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgLy8gIHJldHVybiByZXN1bHQ7IH0KKyAgLy8gVXNpbmcgdGhpcyBjYW4gcmVkdWNlIGNvZGUgc2l6ZSBhbmQgY29tcGxleGl0eSBpbiBzb21lIGNhc2VzLgorICAvLyBEbyBub3QgdXNlIHVubGVzcyB0aGUgY3VycmVudCByZWN1cnNpb24gZGVwdGggaXMgZ3JlYXRlciB0aGFuIHplcm8uCisgIGJvb2wgRGVjcmVtZW50UmVjdXJzaW9uRGVwdGhBbmRQb3BMaW1pdChMaW1pdCBsaW1pdCk7CisKKyAgLy8gRXh0ZW5zaW9uIFJlZ2lzdHJ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gQURWQU5DRUQgVVNBR0U6ICA5OS45JSBvZiBwZW9wbGUgY2FuIGlnbm9yZSB0aGlzIHNlY3Rpb24uCisgIC8vCisgIC8vIEJ5IGRlZmF1bHQsIHdoZW4gcGFyc2luZyBleHRlbnNpb25zLCB0aGUgcGFyc2VyIGxvb2tzIGZvciBleHRlbnNpb24KKyAgLy8gZGVmaW5pdGlvbnMgaW4gdGhlIHBvb2wgd2hpY2ggb3ducyB0aGUgb3V0ZXIgbWVzc2FnZSdzIERlc2NyaXB0b3IuCisgIC8vIEhvd2V2ZXIsIHlvdSBtYXkgY2FsbCBTZXRFeHRlbnNpb25SZWdpc3RyeSgpIHRvIHByb3ZpZGUgYW4gYWx0ZXJuYXRpdmUKKyAgLy8gcG9vbCBpbnN0ZWFkLiAgVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSwgZm9yIGV4YW1wbGUsIHRvIHBhcnNlIGEgbWVzc2FnZQorICAvLyB1c2luZyBhIGdlbmVyYXRlZCBjbGFzcywgYnV0IHJlcHJlc2VudCBzb21lIGV4dGVuc2lvbnMgdXNpbmcKKyAgLy8gRHluYW1pY01lc3NhZ2UuCisKKyAgLy8gU2V0IHRoZSBwb29sIHVzZWQgdG8gbG9vayB1cCBleHRlbnNpb25zLiAgTW9zdCB1c2VycyBkbyBub3QgbmVlZCB0byBjYWxsCisgIC8vIHRoaXMgYXMgdGhlIGNvcnJlY3QgcG9vbCB3aWxsIGJlIGNob3NlbiBhdXRvbWF0aWNhbGx5LgorICAvLworICAvLyBXQVJOSU5HOiAgSXQgaXMgdmVyeSBlYXN5IHRvIG1pc3VzZSB0aGlzLiAgQ2FyZWZ1bGx5IHJlYWQgdGhlIHJlcXVpcmVtZW50cworICAvLyAgIGJlbG93LiAgRG8gbm90IHVzZSB0aGlzIHVubGVzcyB5b3UgYXJlIHN1cmUgeW91IG5lZWQgaXQuICBBbG1vc3Qgbm8gb25lCisgIC8vICAgZG9lcy4KKyAgLy8KKyAgLy8gTGV0J3Mgc2F5IHlvdSBhcmUgcGFyc2luZyBhIG1lc3NhZ2UgaW50byBtZXNzYWdlIG9iamVjdCBtLCBhbmQgeW91IHdhbnQKKyAgLy8gdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgU2V0RXh0ZW5zaW9uUmVnaXN0cnkoKS4gIFlvdSBtdXN0IGZvbGxvdyB0aGVzZQorICAvLyByZXF1aXJlbWVudHM6CisgIC8vCisgIC8vIFRoZSBnaXZlbiBEZXNjcmlwdG9yUG9vbCBtdXN0IGNvbnRhaW4gbS0+R2V0RGVzY3JpcHRvcigpLiAgSXQgaXMgbm90CisgIC8vIHN1ZmZpY2llbnQgZm9yIGl0IHRvIHNpbXBseSBjb250YWluIGEgZGVzY3JpcHRvciB0aGF0IGhhcyB0aGUgc2FtZSBuYW1lCisgIC8vIGFuZCBjb250ZW50IC0tIGl0IG11c3QgYmUgdGhlICpleGFjdCBvYmplY3QqLiAgSW4gb3RoZXIgd29yZHM6CisgIC8vICAgYXNzZXJ0KHBvb2wtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZShtLT5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpKSA9PQorICAvLyAgICAgICAgICBtLT5HZXREZXNjcmlwdG9yKCkpOworICAvLyBUaGVyZSBhcmUgdHdvIHdheXMgdG8gc2F0aXNmeSB0aGlzIHJlcXVpcmVtZW50OgorICAvLyAxKSBVc2UgbS0+R2V0RGVzY3JpcHRvcigpLT5wb29sKCkgYXMgdGhlIHBvb2wuICBUaGlzIGlzIGdlbmVyYWxseSB1c2VsZXNzCisgIC8vICAgIGJlY2F1c2UgdGhpcyBpcyB0aGUgcG9vbCB0aGF0IHdvdWxkIGJlIHVzZWQgYW55d2F5IGlmIHlvdSBkaWRuJ3QgY2FsbAorICAvLyAgICBTZXRFeHRlbnNpb25SZWdpc3RyeSgpIGF0IGFsbC4KKyAgLy8gMikgVXNlIGEgRGVzY3JpcHRvclBvb2wgd2hpY2ggaGFzIG0tPkdldERlc2NyaXB0b3IoKS0+cG9vbCgpIGFzIGFuCisgIC8vICAgICJ1bmRlcmxheSIuICBSZWFkIHRoZSBkb2N1bWVudGF0aW9uIGZvciBEZXNjcmlwdG9yUG9vbCBmb3IgbW9yZQorICAvLyAgICBpbmZvcm1hdGlvbiBhYm91dCB1bmRlcmxheXMuCisgIC8vCisgIC8vIFlvdSBtdXN0IGFsc28gcHJvdmlkZSBhIE1lc3NhZ2VGYWN0b3J5LiAgVGhpcyBmYWN0b3J5IHdpbGwgYmUgdXNlZCB0bworICAvLyBjb25zdHJ1Y3QgTWVzc2FnZSBvYmplY3RzIHJlcHJlc2VudGluZyBleHRlbnNpb25zLiAgVGhlIGZhY3RvcnkncworICAvLyBHZXRQcm90b3R5cGUoKSBNVVNUIHJldHVybiBub24tTlVMTCBmb3IgYW55IERlc2NyaXB0b3Igd2hpY2ggY2FuIGJlIGZvdW5kCisgIC8vIHRocm91Z2ggdGhlIHByb3ZpZGVkIHBvb2wuCisgIC8vCisgIC8vIElmIHRoZSBwcm92aWRlZCBmYWN0b3J5IG1pZ2h0IHJldHVybiBpbnN0YW5jZXMgb2YgcHJvdG9jb2wtY29tcGlsZXItCisgIC8vIGdlbmVyYXRlZCAoaS5lLiBjb21waWxlZC1pbikgdHlwZXMsIG9yIGlmIHRoZSBvdXRlciBtZXNzYWdlIG9iamVjdCBtIGlzCisgIC8vIGEgZ2VuZXJhdGVkIHR5cGUsIHRoZW4gdGhlIGdpdmVuIGZhY3RvcnkgTVVTVCBoYXZlIHRoaXMgcHJvcGVydHk6ICBJZgorICAvLyBHZXRQcm90b3R5cGUoKSBpcyBnaXZlbiBhIERlc2NyaXB0b3Igd2hpY2ggcmVzaWRlcyBpbgorICAvLyBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSwgdGhlIGZhY3RvcnkgTVVTVCByZXR1cm4gdGhlIHNhbWUKKyAgLy8gcHJvdG90eXBlIHdoaWNoIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpIHdvdWxkIHJldHVybi4gIFRoYXQKKyAgLy8gaXMsIGdpdmVuIGEgZGVzY3JpcHRvciBmb3IgYSBnZW5lcmF0ZWQgdHlwZSwgdGhlIGZhY3RvcnkgbXVzdCByZXR1cm4gYW4KKyAgLy8gaW5zdGFuY2Ugb2YgdGhlIGdlbmVyYXRlZCBjbGFzcyAoTk9UIER5bmFtaWNNZXNzYWdlKS4gIEhvd2V2ZXIsIHdoZW4KKyAgLy8gZ2l2ZW4gYSBkZXNjcmlwdG9yIGZvciBhIHR5cGUgdGhhdCBpcyBOT1QgaW4gZ2VuZXJhdGVkX3Bvb2wsIHRoZSBmYWN0b3J5CisgIC8vIGlzIGZyZWUgdG8gcmV0dXJuIGFueSBpbXBsZW1lbnRhdGlvbi4KKyAgLy8KKyAgLy8gVGhlIHJlYXNvbiBmb3IgdGhpcyByZXF1aXJlbWVudCBpcyB0aGF0IGdlbmVyYXRlZCBzdWItb2JqZWN0cyBtYXkgYmUKKyAgLy8gYWNjZXNzZWQgdmlhIHRoZSBzdGFuZGFyZCAobm9uLXJlZmxlY3Rpb24pIGV4dGVuc2lvbiBhY2Nlc3NvciBtZXRob2RzLAorICAvLyBhbmQgdGhlc2UgbWV0aG9kcyB3aWxsIGRvd24tY2FzdCB0aGUgb2JqZWN0IHRvIHRoZSBnZW5lcmF0ZWQgY2xhc3MgdHlwZS4KKyAgLy8gSWYgdGhlIG9iamVjdCBpcyBub3QgYWN0dWFsbHkgb2YgdGhhdCB0eXBlLCB0aGUgcmVzdWx0cyB3b3VsZCBiZSB1bmRlZmluZWQuCisgIC8vIE9uIHRoZSBvdGhlciBoYW5kLCBpZiBhbiBleHRlbnNpb24gaXMgbm90IGNvbXBpbGVkIGluLCB0aGVuIHRoZXJlIGlzIG5vCisgIC8vIHdheSB0aGUgY29kZSBjb3VsZCBlbmQgdXAgYWNjZXNzaW5nIGl0IHZpYSB0aGUgc3RhbmRhcmQgYWNjZXNzb3JzIC0tIHRoZQorICAvLyBvbmx5IHdheSB0byBhY2Nlc3MgdGhlIGV4dGVuc2lvbiBpcyB2aWEgcmVmbGVjdGlvbi4gIFdoZW4gdXNpbmcgcmVmbGVjdGlvbiwKKyAgLy8gRHluYW1pY01lc3NhZ2UgYW5kIGdlbmVyYXRlZCBtZXNzYWdlcyBhcmUgaW5kaXN0aW5ndWlzaGFibGUsIHNvIGl0J3MgZmluZQorICAvLyBpZiB0aGVzZSBvYmplY3RzIGFyZSByZXByZXNlbnRlZCB1c2luZyBEeW5hbWljTWVzc2FnZS4KKyAgLy8KKyAgLy8gVXNpbmcgRHluYW1pY01lc3NhZ2VGYWN0b3J5IG9uIHdoaWNoIHlvdSBoYXZlIGNhbGxlZAorICAvLyBTZXREZWxlZ2F0ZVRvR2VuZXJhdGVkRmFjdG9yeSh0cnVlKSBzaG91bGQgYmUgc3VmZmljaWVudCB0byBzYXRpc2Z5IHRoZQorICAvLyBhYm92ZSByZXF1aXJlbWVudC4KKyAgLy8KKyAgLy8gSWYgZWl0aGVyIHBvb2wgb3IgZmFjdG9yeSBpcyBOVUxMLCBib3RoIG11c3QgYmUgTlVMTC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IHRoaXMgZmVhdHVyZSBpcyBpZ25vcmVkIHdoZW4gcGFyc2luZyAibGl0ZSIgbWVzc2FnZXMgYXMgdGhleSBkbworICAvLyBub3QgaGF2ZSBkZXNjcmlwdG9ycy4KKyAgdm9pZCBTZXRFeHRlbnNpb25SZWdpc3RyeShjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSk7CisKKyAgLy8gR2V0IHRoZSBEZXNjcmlwdG9yUG9vbCBzZXQgdmlhIFNldEV4dGVuc2lvblJlZ2lzdHJ5KCksIG9yIE5VTEwgaWYgbm8gcG9vbAorICAvLyBoYXMgYmVlbiBwcm92aWRlZC4KKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIEdldEV4dGVuc2lvblBvb2woKTsKKworICAvLyBHZXQgdGhlIE1lc3NhZ2VGYWN0b3J5IHNldCB2aWEgU2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSwgb3IgTlVMTCBpZiBubworICAvLyBmYWN0b3J5IGhhcyBiZWVuIHByb3ZpZGVkLgorICBNZXNzYWdlRmFjdG9yeSogR2V0RXh0ZW5zaW9uRmFjdG9yeSgpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvZGVkSW5wdXRTdHJlYW0pOworCisgIGNvbnN0IHVpbnQ4KiBidWZmZXJfOworICBjb25zdCB1aW50OCogYnVmZmVyX2VuZF87ICAgICAvLyBwb2ludGVyIHRvIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci4KKyAgWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXRfOworICBpbnQgdG90YWxfYnl0ZXNfcmVhZF87ICAvLyB0b3RhbCBieXRlcyByZWFkIGZyb20gaW5wdXRfLCBpbmNsdWRpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgYnVmZmVyCisKKyAgLy8gSWYgdG90YWxfYnl0ZXNfcmVhZF8gc3VycGFzc2VzIElOVF9NQVgsIHdlIHJlY29yZCB0aGUgZXh0cmEgYnl0ZXMgaGVyZQorICAvLyBzbyB0aGF0IHdlIGNhbiBCYWNrVXAoKSBvbiBkZXN0cnVjdGlvbi4KKyAgaW50IG92ZXJmbG93X2J5dGVzXzsKKworICAvLyBMYXN0VGFnV2FzKCkgc3R1ZmYuCisgIHVpbnQzMiBsYXN0X3RhZ187ICAgICAgICAgLy8gcmVzdWx0IG9mIGxhc3QgUmVhZFRhZygpIG9yIFJlYWRUYWdXaXRoQ3V0b2ZmKCkuCisKKyAgLy8gVGhpcyBpcyBzZXQgdHJ1ZSBieSBSZWFkVGFne0ZhbGxiYWNrL1Nsb3d9KCkgaWYgaXQgaXMgY2FsbGVkIHdoZW4gZXhhY3RseQorICAvLyBhdCBFT0YsIG9yIGJ5IEV4cGVjdEF0RW5kKCkgd2hlbiBpdCByZXR1cm5zIHRydWUuICBUaGlzIGhhcHBlbnMgd2hlbiB3ZQorICAvLyByZWFjaCB0aGUgZW5kIG9mIGEgbWVzc2FnZSBhbmQgYXR0ZW1wdCB0byByZWFkIGFub3RoZXIgdGFnLgorICBib29sIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfOworCisgIC8vIFNlZSBFbmFibGVBbGlhc2luZygpLgorICBib29sIGFsaWFzaW5nX2VuYWJsZWRfOworCisgIC8vIExpbWl0cworICBMaW1pdCBjdXJyZW50X2xpbWl0XzsgICAvLyBpZiBwb3NpdGlvbiA9IC0xLCBubyBsaW1pdCBpcyBhcHBsaWVkCisKKyAgLy8gRm9yIHNpbXBsaWNpdHksIGlmIHRoZSBjdXJyZW50IGJ1ZmZlciBjcm9zc2VzIGEgbGltaXQgKGVpdGhlciBhIG5vcm1hbAorICAvLyBsaW1pdCBjcmVhdGVkIGJ5IFB1c2hMaW1pdCgpIG9yIHRoZSB0b3RhbCBieXRlcyBsaW1pdCksIGJ1ZmZlcl9zaXplXworICAvLyBvbmx5IHRyYWNrcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGJlZm9yZSB0aGF0IGxpbWl0LiAgVGhpcyBmaWVsZAorICAvLyBjb250YWlucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFmdGVyIGl0LiAgTm90ZSB0aGF0IHRoaXMgaW1wbGllcyB0aGF0IGlmCisgIC8vIGJ1ZmZlcl9zaXplXyA9PSAwIGFuZCBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gPiAwLCB3ZSBrbm93IHdlJ3ZlCisgIC8vIGhpdCBhIGxpbWl0LiAgSG93ZXZlciwgaWYgYm90aCBhcmUgemVybywgaXQgZG9lc24ndCBuZWNlc3NhcmlseSBtZWFuCisgIC8vIHdlIGFyZW4ndCBhdCBhIGxpbWl0IC0tIHRoZSBidWZmZXIgbWF5IGhhdmUgZW5kZWQgZXhhY3RseSBhdCB0aGUgbGltaXQuCisgIGludCBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF87CisKKyAgLy8gTWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCwgcGVyaW9kLiAgVGhpcyBpcyB1bnJlbGF0ZWQgdG8KKyAgLy8gY3VycmVudF9saW1pdF8uICBTZXQgdXNpbmcgU2V0VG90YWxCeXRlc0xpbWl0KCkuCisgIGludCB0b3RhbF9ieXRlc19saW1pdF87CisKKyAgLy8gSWYgcG9zaXRpdmUvMDogTGltaXQgZm9yIGJ5dGVzIHJlYWQgYWZ0ZXIgd2hpY2ggYSB3YXJuaW5nIGR1ZSB0byBzaXplCisgIC8vIHNob3VsZCBiZSBsb2dnZWQuCisgIC8vIElmIC0xOiBQcmludGluZyBvZiB3YXJuaW5nIGRpc2FibGVkLiBDYW4gYmUgc2V0IGJ5IGNsaWVudC4KKyAgLy8gSWYgLTI6IEludGVybmFsOiBMaW1pdCBoYXMgYmVlbiByZWFjaGVkLCBwcmludCBmdWxsIHNpemUgd2hlbiBkZXN0cnVjdGluZy4KKyAgaW50IHRvdGFsX2J5dGVzX3dhcm5pbmdfdGhyZXNob2xkXzsKKworICAvLyBDdXJyZW50IHJlY3Vyc2lvbiBidWRnZXQsIGNvbnRyb2xsZWQgYnkgSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSBhbmQKKyAgLy8gc2ltaWxhci4gIFN0YXJ0cyBhdCByZWN1cnNpb25fbGltaXRfIGFuZCBnb2VzIGRvd246IGlmIHRoaXMgcmVhY2hlcworICAvLyAtMSB3ZSBhcmUgb3ZlciBidWRnZXQuCisgIGludCByZWN1cnNpb25fYnVkZ2V0XzsKKyAgLy8gUmVjdXJzaW9uIGRlcHRoIGxpbWl0LCBzZXQgYnkgU2V0UmVjdXJzaW9uTGltaXQoKS4KKyAgaW50IHJlY3Vyc2lvbl9saW1pdF87CisKKyAgLy8gU2VlIFNldEV4dGVuc2lvblJlZ2lzdHJ5KCkuCisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBleHRlbnNpb25fcG9vbF87CisgIE1lc3NhZ2VGYWN0b3J5KiBleHRlbnNpb25fZmFjdG9yeV87CisKKyAgLy8gUHJpdmF0ZSBtZW1iZXIgZnVuY3Rpb25zLgorCisgIC8vIEFkdmFuY2UgdGhlIGJ1ZmZlciBieSBhIGdpdmVuIG51bWJlciBvZiBieXRlcy4KKyAgdm9pZCBBZHZhbmNlKGludCBhbW91bnQpOworCisgIC8vIEJhY2sgdXAgaW5wdXRfIHRvIHRoZSBjdXJyZW50IGJ1ZmZlciBwb3NpdGlvbi4KKyAgdm9pZCBCYWNrVXBJbnB1dFRvQ3VycmVudFBvc2l0aW9uKCk7CisKKyAgLy8gUmVjb21wdXRlcyB0aGUgdmFsdWUgb2YgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfLiAgTXVzdCBiZSBjYWxsZWQgYWZ0ZXIKKyAgLy8gY3VycmVudF9saW1pdF8gb3IgdG90YWxfYnl0ZXNfbGltaXRfIGNoYW5nZXMuCisgIHZvaWQgUmVjb21wdXRlQnVmZmVyTGltaXRzKCk7CisKKyAgLy8gV3JpdGVzIGFuIGVycm9yIG1lc3NhZ2Ugc2F5aW5nIHRoYXQgd2UgaGl0IHRvdGFsX2J5dGVzX2xpbWl0Xy4KKyAgdm9pZCBQcmludFRvdGFsQnl0ZXNMaW1pdEVycm9yKCk7CisKKyAgLy8gQ2FsbGVkIHdoZW4gdGhlIGJ1ZmZlciBydW5zIG91dCB0byByZXF1ZXN0IG1vcmUgZGF0YS4gIEltcGxpZXMgYW4KKyAgLy8gQWR2YW5jZShCdWZmZXJTaXplKCkpLgorICBib29sIFJlZnJlc2goKTsKKworICAvLyBXaGVuIHBhcnNpbmcgdmFyaW50cywgd2Ugb3B0aW1pemUgZm9yIHRoZSBjb21tb24gY2FzZSBvZiBzbWFsbCB2YWx1ZXMsIGFuZAorICAvLyB0aGVuIG9wdGltaXplIGZvciB0aGUgY2FzZSB3aGVuIHRoZSB2YXJpbnQgZml0cyB3aXRoaW4gdGhlIGN1cnJlbnQgYnVmZmVyCisgIC8vIHBpZWNlLiBUaGUgRmFsbGJhY2sgbWV0aG9kIGlzIHVzZWQgd2hlbiB3ZSBjYW4ndCB1c2UgdGhlIG9uZS1ieXRlCisgIC8vIG9wdGltaXphdGlvbi4gVGhlIFNsb3cgbWV0aG9kIGlzIHlldCBhbm90aGVyIGZhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcworICAvLyBub3QgbGFyZ2UgZW5vdWdoLiBNYWtpbmcgdGhlIHNsb3cgcGF0aCBvdXQtb2YtbGluZSBzcGVlZHMgdXAgdGhlIGNvbW1vbgorICAvLyBjYXNlIGJ5IDEwLTE1JS4gVGhlIHNsb3cgcGF0aCBpcyBmYWlybHkgdW5jb21tb246IGl0IG9ubHkgdHJpZ2dlcnMgd2hlbiBhCisgIC8vIG1lc3NhZ2UgY3Jvc3NlcyBtdWx0aXBsZSBidWZmZXJzLgorICBib29sIFJlYWRWYXJpbnQzMkZhbGxiYWNrKHVpbnQzMiogdmFsdWUpOworICBib29sIFJlYWRWYXJpbnQ2NEZhbGxiYWNrKHVpbnQ2NCogdmFsdWUpOworICBib29sIFJlYWRWYXJpbnQzMlNsb3codWludDMyKiB2YWx1ZSk7CisgIGJvb2wgUmVhZFZhcmludDY0U2xvdyh1aW50NjQqIHZhbHVlKTsKKyAgYm9vbCBSZWFkTGl0dGxlRW5kaWFuMzJGYWxsYmFjayh1aW50MzIqIHZhbHVlKTsKKyAgYm9vbCBSZWFkTGl0dGxlRW5kaWFuNjRGYWxsYmFjayh1aW50NjQqIHZhbHVlKTsKKyAgLy8gRmFsbGJhY2svc2xvdyBtZXRob2RzIGZvciByZWFkaW5nIHRhZ3MuIFRoZXNlIGRvIG5vdCB1cGRhdGUgbGFzdF90YWdfLAorICAvLyBidXQgd2lsbCBzZXQgbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF8gaWYgd2UgYXJlIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0CisgIC8vIHN0cmVhbS4KKyAgdWludDMyIFJlYWRUYWdGYWxsYmFjaygpOworICB1aW50MzIgUmVhZFRhZ1Nsb3coKTsKKyAgYm9vbCBSZWFkU3RyaW5nRmFsbGJhY2soc3RyaW5nKiBidWZmZXIsIGludCBzaXplKTsKKworICAvLyBSZXR1cm4gdGhlIHNpemUgb2YgdGhlIGJ1ZmZlci4KKyAgaW50IEJ1ZmZlclNpemUoKSBjb25zdDsKKworICBzdGF0aWMgY29uc3QgaW50IGtEZWZhdWx0VG90YWxCeXRlc0xpbWl0ID0gNjQgPDwgMjA7ICAvLyA2NE1CCisKKyAgc3RhdGljIGNvbnN0IGludCBrRGVmYXVsdFRvdGFsQnl0ZXNXYXJuaW5nVGhyZXNob2xkID0gMzIgPDwgMjA7ICAvLyAzMk1CCisKKyAgc3RhdGljIGludCBkZWZhdWx0X3JlY3Vyc2lvbl9saW1pdF87ICAvLyAxMDAgYnkgZGVmYXVsdC4KK307CisKKy8vIENsYXNzIHdoaWNoIGVuY29kZXMgYW5kIHdyaXRlcyBiaW5hcnkgZGF0YSB3aGljaCBpcyBjb21wb3NlZCBvZiB2YXJpbnQtCisvLyBlbmNvZGVkIGludGVnZXJzIGFuZCBmaXhlZC13aWR0aCBwaWVjZXMuICBXcmFwcyBhIFplcm9Db3B5T3V0cHV0U3RyZWFtLgorLy8gTW9zdCB1c2VycyB3aWxsIG5vdCBuZWVkIHRvIGRlYWwgd2l0aCBDb2RlZE91dHB1dFN0cmVhbS4KKy8vCisvLyBNb3N0IG1ldGhvZHMgb2YgQ29kZWRPdXRwdXRTdHJlYW0gd2hpY2ggcmV0dXJuIGEgYm9vbCByZXR1cm4gZmFsc2UgaWYgYW4KKy8vIHVuZGVybHlpbmcgSS9PIGVycm9yIG9jY3Vycy4gIE9uY2Ugc3VjaCBhIGZhaWx1cmUgb2NjdXJzLCB0aGUKKy8vIENvZGVkT3V0cHV0U3RyZWFtIGlzIGJyb2tlbiBhbmQgaXMgbm8gbG9uZ2VyIHVzZWZ1bC4gVGhlIFdyaXRlKiBtZXRob2RzIGRvCisvLyBub3QgcmV0dXJuIHRoZSBzdHJlYW0gc3RhdHVzLCBidXQgd2lsbCBpbnZhbGlkYXRlIHRoZSBzdHJlYW0gaWYgYW4gZXJyb3IKKy8vIG9jY3Vycy4gVGhlIGNsaWVudCBjYW4gcHJvYmUgSGFkRXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIHN0YXR1cy4KKy8vCisvLyBOb3RlIHRoYXQgZXZlcnkgbWV0aG9kIG9mIENvZGVkT3V0cHV0U3RyZWFtIHdoaWNoIHdyaXRlcyBzb21lIGRhdGEgaGFzCisvLyBhIGNvcnJlc3BvbmRpbmcgc3RhdGljICJUb0FycmF5IiB2ZXJzaW9uLiBUaGVzZSB2ZXJzaW9ucyB3cml0ZSBkaXJlY3RseQorLy8gdG8gdGhlIHByb3ZpZGVkIGJ1ZmZlciwgcmV0dXJuaW5nIGEgcG9pbnRlciBwYXN0IHRoZSBsYXN0IHdyaXR0ZW4gYnl0ZS4KKy8vIFRoZXkgcmVxdWlyZSB0aGF0IHRoZSBidWZmZXIgaGFzIHN1ZmZpY2llbnQgY2FwYWNpdHkgZm9yIHRoZSBlbmNvZGVkIGRhdGEuCisvLyBUaGlzIGFsbG93cyBhbiBvcHRpbWl6YXRpb24gd2hlcmUgd2UgY2hlY2sgaWYgYW4gb3V0cHV0IHN0cmVhbSBoYXMgZW5vdWdoCisvLyBzcGFjZSBmb3IgYW4gZW50aXJlIG1lc3NhZ2UgYmVmb3JlIHdlIHN0YXJ0IHdyaXRpbmcgYW5kLCBpZiB0aGVyZSBpcywgd2UKKy8vIGNhbGwgb25seSB0aGUgVG9BcnJheSBtZXRob2RzIHRvIGF2b2lkIGRvaW5nIGJvdW5kIGNoZWNrcyBmb3IgZWFjaAorLy8gaW5kaXZpZHVhbCB2YWx1ZS4KKy8vIGkuZS4sIGluIHRoZSBleGFtcGxlIGFib3ZlOgorLy8KKy8vICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0ID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKHJhd19vdXRwdXQpOworLy8gICBpbnQgbWFnaWNfbnVtYmVyID0gMTIzNDsKKy8vICAgY2hhciB0ZXh0W10gPSAiSGVsbG8gd29ybGQhIjsKKy8vCisvLyAgIGludCBjb2RlZF9zaXplID0gc2l6ZW9mKG1hZ2ljX251bWJlcikgKworLy8gICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoc3RybGVuKHRleHQpKSArCisvLyAgICAgICAgICAgICAgICAgICAgc3RybGVuKHRleHQpOworLy8KKy8vICAgdWludDgqIGJ1ZmZlciA9CisvLyAgICAgICBjb2RlZF9vdXRwdXQtPkdldERpcmVjdEJ1ZmZlckZvck5CeXRlc0FuZEFkdmFuY2UoY29kZWRfc2l6ZSk7CisvLyAgIGlmIChidWZmZXIgIT0gTlVMTCkgeworLy8gICAgIC8vIFRoZSBvdXRwdXQgc3RyZWFtIGhhcyBlbm91Z2ggc3BhY2UgaW4gdGhlIGJ1ZmZlcjogd3JpdGUgZGlyZWN0bHkgdG8KKy8vICAgICAvLyB0aGUgYXJyYXkuCisvLyAgICAgYnVmZmVyID0gQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlTGl0dGxlRW5kaWFuMzJUb0FycmF5KG1hZ2ljX251bWJlciwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyKTsKKy8vICAgICBidWZmZXIgPSBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoc3RybGVuKHRleHQpLCBidWZmZXIpOworLy8gICAgIGJ1ZmZlciA9IENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVJhd1RvQXJyYXkodGV4dCwgc3RybGVuKHRleHQpLCBidWZmZXIpOworLy8gICB9IGVsc2UgeworLy8gICAgIC8vIE1ha2UgYm91bmQtY2hlY2tlZCB3cml0ZXMsIHdoaWNoIHdpbGwgYXNrIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBmb3IKKy8vICAgICAvLyBtb3JlIHNwYWNlIGFzIG5lZWRlZC4KKy8vICAgICBjb2RlZF9vdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuMzIobWFnaWNfbnVtYmVyKTsKKy8vICAgICBjb2RlZF9vdXRwdXQtPldyaXRlVmFyaW50MzIoc3RybGVuKHRleHQpKTsKKy8vICAgICBjb2RlZF9vdXRwdXQtPldyaXRlUmF3KHRleHQsIHN0cmxlbih0ZXh0KSk7CisvLyAgIH0KKy8vCisvLyAgIGRlbGV0ZSBjb2RlZF9vdXRwdXQ7CitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29kZWRPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgLy8gQ3JlYXRlIGFuIENvZGVkT3V0cHV0U3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBaZXJvQ29weU91dHB1dFN0cmVhbS4KKyAgZXhwbGljaXQgQ29kZWRPdXRwdXRTdHJlYW0oWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gRGVzdHJveSB0aGUgQ29kZWRPdXRwdXRTdHJlYW0gYW5kIHBvc2l0aW9uIHRoZSB1bmRlcmx5aW5nCisgIC8vIFplcm9Db3B5T3V0cHV0U3RyZWFtIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBsYXN0IGJ5dGUgd3JpdHRlbi4KKyAgfkNvZGVkT3V0cHV0U3RyZWFtKCk7CisKKyAgLy8gVHJpbXMgYW55IHVudXNlZCBzcGFjZSBpbiB0aGUgdW5kZXJseWluZyBidWZmZXIgc28gdGhhdCBpdHMgc2l6ZSBtYXRjaGVzCisgIC8vIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBieSB0aGlzIHN0cmVhbS4gVGhlIHVuZGVybHlpbmcgYnVmZmVyIHdpbGwKKyAgLy8gYXV0b21hdGljYWxseSBiZSB0cmltbWVkIHdoZW4gdGhpcyBzdHJlYW0gaXMgZGVzdHJveWVkOyB0aGlzIGNhbGwgaXMgb25seQorICAvLyBuZWNlc3NhcnkgaWYgdGhlIHVuZGVybHlpbmcgYnVmZmVyIGlzIGFjY2Vzc2VkICpiZWZvcmUqIHRoZSBzdHJlYW0gaXMKKyAgLy8gZGVzdHJveWVkLgorICB2b2lkIFRyaW0oKTsKKworICAvLyBTa2lwcyBhIG51bWJlciBvZiBieXRlcywgbGVhdmluZyB0aGUgYnl0ZXMgdW5tb2RpZmllZCBpbiB0aGUgdW5kZXJseWluZworICAvLyBidWZmZXIuICBSZXR1cm5zIGZhbHNlIGlmIGFuIHVuZGVybHlpbmcgd3JpdGUgZXJyb3Igb2NjdXJzLiAgVGhpcyBpcworICAvLyBtYWlubHkgdXNlZnVsIHdpdGggR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigpLgorICBib29sIFNraXAoaW50IGNvdW50KTsKKworICAvLyBTZXRzICpkYXRhIHRvIHBvaW50IGRpcmVjdGx5IGF0IHRoZSB1bndyaXR0ZW4gcGFydCBvZiB0aGUKKyAgLy8gQ29kZWRPdXRwdXRTdHJlYW0ncyB1bmRlcmx5aW5nIGJ1ZmZlciwgYW5kICpzaXplIHRvIHRoZSBzaXplIG9mIHRoYXQKKyAgLy8gYnVmZmVyLCBidXQgZG9lcyBub3QgYWR2YW5jZSB0aGUgc3RyZWFtJ3MgY3VycmVudCBwb3NpdGlvbi4gIFRoaXMgd2lsbAorICAvLyBhbHdheXMgZWl0aGVyIHByb2R1Y2UgYSBub24tZW1wdHkgYnVmZmVyIG9yIHJldHVybiBmYWxzZS4gIElmIHRoZSBjYWxsZXIKKyAgLy8gd3JpdGVzIGFueSBkYXRhIHRvIHRoaXMgYnVmZmVyLCBpdCBzaG91bGQgdGhlbiBjYWxsIFNraXAoKSB0byBza2lwIG92ZXIKKyAgLy8gdGhlIGNvbnN1bWVkIGJ5dGVzLiAgVGhpcyBtYXkgYmUgdXNlZnVsIGZvciBpbXBsZW1lbnRpbmcgZXh0ZXJuYWwgZmFzdAorICAvLyBzZXJpYWxpemF0aW9uIHJvdXRpbmVzIGZvciB0eXBlcyBvZiBkYXRhIG5vdCBjb3ZlcmVkIGJ5IHRoZQorICAvLyBDb2RlZE91dHB1dFN0cmVhbSBpbnRlcmZhY2UuCisgIGJvb2wgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcih2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKworICAvLyBJZiB0aGVyZSBhcmUgYXQgbGVhc3QgInNpemUiIGJ5dGVzIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBidWZmZXIsCisgIC8vIHJldHVybnMgYSBwb2ludGVyIGRpcmVjdGx5IGludG8gdGhlIGJ1ZmZlciBhbmQgYWR2YW5jZXMgb3ZlciB0aGVzZSBieXRlcy4KKyAgLy8gVGhlIGNhbGxlciBtYXkgdGhlbiB3cml0ZSBkaXJlY3RseSBpbnRvIHRoaXMgYnVmZmVyIChlLmcuIHVzaW5nIHRoZQorICAvLyAqVG9BcnJheSBzdGF0aWMgbWV0aG9kcykgcmF0aGVyIHRoYW4gZ28gdGhyb3VnaCBDb2RlZE91dHB1dFN0cmVhbS4gIElmCisgIC8vIHRoZXJlIGFyZSBub3QgZW5vdWdoIGJ5dGVzIGF2YWlsYWJsZSwgcmV0dXJucyBOVUxMLiAgVGhlIHJldHVybiBwb2ludGVyIGlzCisgIC8vIGludmFsaWRhdGVkIGFzIHNvb24gYXMgYW55IG90aGVyIG5vbi1jb25zdCBtZXRob2Qgb2YgQ29kZWRPdXRwdXRTdHJlYW0KKyAgLy8gaXMgY2FsbGVkLgorICBpbmxpbmUgdWludDgqIEdldERpcmVjdEJ1ZmZlckZvck5CeXRlc0FuZEFkdmFuY2UoaW50IHNpemUpOworCisgIC8vIFdyaXRlIHJhdyBieXRlcywgY29weWluZyB0aGVtIGZyb20gdGhlIGdpdmVuIGJ1ZmZlci4KKyAgdm9pZCBXcml0ZVJhdyhjb25zdCB2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKyAgLy8gTGlrZSBXcml0ZVJhdygpICBidXQgd2lsbCB0cnkgdG8gd3JpdGUgYWxpYXNlZCBkYXRhIGlmIGFsaWFzaW5nIGlzCisgIC8vIHR1cm5lZCBvbi4KKyAgdm9pZCBXcml0ZVJhd01heWJlQWxpYXNlZChjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSk7CisgIC8vIExpa2UgV3JpdGVSYXcoKSAgYnV0IHdyaXRpbmcgZGlyZWN0bHkgdG8gdGhlIHRhcmdldCBhcnJheS4KKyAgLy8gVGhpcyBpcyBfbm90XyBpbmxpbmVkLCBhcyB0aGUgY29tcGlsZXIgb2Z0ZW4gb3B0aW1pemVzIG1lbWNweSBpbnRvIGlubGluZQorICAvLyBjb3B5IGxvb3BzLiBTaW5jZSB0aGlzIGdldHMgY2FsbGVkIGJ5IGV2ZXJ5IGZpZWxkIHdpdGggc3RyaW5nIG9yIGJ5dGVzCisgIC8vIHR5cGUsIGlubGluaW5nIG1heSBsZWFkIHRvIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIGNvZGUgYmxvYXQsIHdpdGggb25seSBhCisgIC8vIG1pbm9yIHBlcmZvcm1hbmNlIGdhaW4uCisgIHN0YXRpYyB1aW50OCogV3JpdGVSYXdUb0FycmF5KGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUsIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIEVxdWl2YWxlbnQgdG8gV3JpdGVSYXcoc3RyLmRhdGEoKSwgc3RyLnNpemUoKSkuCisgIHZvaWQgV3JpdGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzdHIpOworICAvLyBMaWtlIFdyaXRlU3RyaW5nKCkgIGJ1dCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSB0YXJnZXQgYXJyYXkuCisgIHN0YXRpYyB1aW50OCogV3JpdGVTdHJpbmdUb0FycmF5KGNvbnN0IHN0cmluZyYgc3RyLCB1aW50OCogdGFyZ2V0KTsKKyAgLy8gV3JpdGUgdGhlIHZhcmludC1lbmNvZGVkIHNpemUgb2Ygc3RyIGZvbGxvd2VkIGJ5IHN0ci4KKyAgc3RhdGljIHVpbnQ4KiBXcml0ZVN0cmluZ1dpdGhTaXplVG9BcnJheShjb25zdCBzdHJpbmcmIHN0ciwgdWludDgqIHRhcmdldCk7CisKKworICAvLyBJbnN0cnVjdHMgdGhlIENvZGVkT3V0cHV0U3RyZWFtIHRvIGFsbG93IHRoZSB1bmRlcmx5aW5nCisgIC8vIFplcm9Db3B5T3V0cHV0U3RyZWFtIHRvIGhvbGQgcG9pbnRlcnMgdG8gdGhlIG9yaWdpbmFsIHN0cnVjdHVyZSBpbnN0ZWFkIG9mCisgIC8vIGNvcHlpbmcsIGlmIGl0IHN1cHBvcnRzIGl0IChpLmUuIG91dHB1dC0+QWxsb3dzQWxpYXNpbmcoKSBpcyB0cnVlKS4gIElmIHRoZQorICAvLyB1bmRlcmx5aW5nIHN0cmVhbSBkb2VzIG5vdCBzdXBwb3J0IGFsaWFzaW5nLCB0aGVuIGVuYWJsaW5nIGl0IGhhcyBubworICAvLyBhZmZlY3QuICBGb3Igbm93LCB0aGlzIG9ubHkgYWZmZWN0cyB0aGUgYmVoYXZpb3Igb2YKKyAgLy8gV3JpdGVSYXdNYXliZUFsaWFzZWQoKS4KKyAgLy8KKyAgLy8gTk9URTogSXQgaXMgY2FsbGVyJ3MgcmVzcG9uc2liaWxpdHkgdG8gZW5zdXJlIHRoYXQgdGhlIGNodW5rIG9mIG1lbW9yeQorICAvLyByZW1haW5zIGxpdmUgdW50aWwgYWxsIG9mIHRoZSBkYXRhIGhhcyBiZWVuIGNvbnN1bWVkIGZyb20gdGhlIHN0cmVhbS4KKyAgdm9pZCBFbmFibGVBbGlhc2luZyhib29sIGVuYWJsZWQpOworCisgIC8vIFdyaXRlIGEgMzItYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlci4KKyAgdm9pZCBXcml0ZUxpdHRsZUVuZGlhbjMyKHVpbnQzMiB2YWx1ZSk7CisgIC8vIExpa2UgV3JpdGVMaXR0bGVFbmRpYW4zMigpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICBzdGF0aWMgdWludDgqIFdyaXRlTGl0dGxlRW5kaWFuMzJUb0FycmF5KHVpbnQzMiB2YWx1ZSwgdWludDgqIHRhcmdldCk7CisgIC8vIFdyaXRlIGEgNjQtYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlci4KKyAgdm9pZCBXcml0ZUxpdHRsZUVuZGlhbjY0KHVpbnQ2NCB2YWx1ZSk7CisgIC8vIExpa2UgV3JpdGVMaXR0bGVFbmRpYW42NCgpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICBzdGF0aWMgdWludDgqIFdyaXRlTGl0dGxlRW5kaWFuNjRUb0FycmF5KHVpbnQ2NCB2YWx1ZSwgdWludDgqIHRhcmdldCk7CisKKyAgLy8gV3JpdGUgYW4gdW5zaWduZWQgaW50ZWdlciB3aXRoIFZhcmludCBlbmNvZGluZy4gIFdyaXRpbmcgYSAzMi1iaXQgdmFsdWUKKyAgLy8gaXMgZXF1aXZhbGVudCB0byBjYXN0aW5nIGl0IHRvIHVpbnQ2NCBhbmQgd3JpdGluZyBpdCBhcyBhIDY0LWJpdCB2YWx1ZSwKKyAgLy8gYnV0IG1heSBiZSBtb3JlIGVmZmljaWVudC4KKyAgdm9pZCBXcml0ZVZhcmludDMyKHVpbnQzMiB2YWx1ZSk7CisgIC8vIExpa2UgV3JpdGVWYXJpbnQzMigpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICBzdGF0aWMgdWludDgqIFdyaXRlVmFyaW50MzJUb0FycmF5KHVpbnQzMiB2YWx1ZSwgdWludDgqIHRhcmdldCk7CisgIC8vIFdyaXRlIGFuIHVuc2lnbmVkIGludGVnZXIgd2l0aCBWYXJpbnQgZW5jb2RpbmcuCisgIHZvaWQgV3JpdGVWYXJpbnQ2NCh1aW50NjQgdmFsdWUpOworICAvLyBMaWtlIFdyaXRlVmFyaW50NjQoKSAgYnV0IHdyaXRpbmcgZGlyZWN0bHkgdG8gdGhlIHRhcmdldCBhcnJheS4KKyAgc3RhdGljIHVpbnQ4KiBXcml0ZVZhcmludDY0VG9BcnJheSh1aW50NjQgdmFsdWUsIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIEVxdWl2YWxlbnQgdG8gV3JpdGVWYXJpbnQzMigpIGV4Y2VwdCB3aGVuIHRoZSB2YWx1ZSBpcyBuZWdhdGl2ZSwKKyAgLy8gaW4gd2hpY2ggY2FzZSBpdCBtdXN0IGJlIHNpZ24tZXh0ZW5kZWQgdG8gYSBmdWxsIDEwIGJ5dGVzLgorICB2b2lkIFdyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWQoaW50MzIgdmFsdWUpOworICAvLyBMaWtlIFdyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWQoKSAgYnV0IHdyaXRpbmcgZGlyZWN0bHkgdG8gdGhlIHRhcmdldCBhcnJheS4KKyAgc3RhdGljIHVpbnQ4KiBXcml0ZVZhcmludDMyU2lnbkV4dGVuZGVkVG9BcnJheShpbnQzMiB2YWx1ZSwgdWludDgqIHRhcmdldCk7CisKKyAgLy8gVGhpcyBpcyBpZGVudGljYWwgdG8gV3JpdGVWYXJpbnQzMigpLCBidXQgb3B0aW1pemVkIGZvciB3cml0aW5nIHRhZ3MuCisgIC8vIEluIHBhcnRpY3VsYXIsIGlmIHRoZSBpbnB1dCBpcyBhIGNvbXBpbGUtdGltZSBjb25zdGFudCwgdGhpcyBtZXRob2QKKyAgLy8gY29tcGlsZXMgZG93biB0byBhIGNvdXBsZSBpbnN0cnVjdGlvbnMuCisgIC8vIEFsd2F5cyBpbmxpbmUgYmVjYXVzZSBvdGhlcndpc2UgdGhlIGFmb3JtZW50aW9uZWQgb3B0aW1pemF0aW9uIGNhbid0IHdvcmssCisgIC8vIGJ1dCBHQ0MgYnkgZGVmYXVsdCBkb2Vzbid0IHdhbnQgdG8gaW5saW5lIHRoaXMuCisgIHZvaWQgV3JpdGVUYWcodWludDMyIHZhbHVlKTsKKyAgLy8gTGlrZSBXcml0ZVRhZygpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICBzdGF0aWMgdWludDgqIFdyaXRlVGFnVG9BcnJheSgKKyAgICAgIHVpbnQzMiB2YWx1ZSwgdWludDgqIHRhcmdldCkgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworCisgIC8vIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gZW5jb2RlIHRoZSBnaXZlbiB2YWx1ZSBhcyBhIHZhcmludC4KKyAgc3RhdGljIGludCBWYXJpbnRTaXplMzIodWludDMyIHZhbHVlKTsKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCB0byBlbmNvZGUgdGhlIGdpdmVuIHZhbHVlIGFzIGEgdmFyaW50LgorICBzdGF0aWMgaW50IFZhcmludFNpemU2NCh1aW50NjQgdmFsdWUpOworCisgIC8vIElmIG5lZ2F0aXZlLCAxMCBieXRlcy4gIE90aGVyaXdzZSwgc2FtZSBhcyBWYXJpbnRTaXplMzIoKS4KKyAgc3RhdGljIGludCBWYXJpbnRTaXplMzJTaWduRXh0ZW5kZWQoaW50MzIgdmFsdWUpOworCisgIC8vIENvbXBpbGUtdGltZSBlcXVpdmFsZW50IG9mIFZhcmludFNpemUzMigpLgorICB0ZW1wbGF0ZSA8dWludDMyIFZhbHVlPgorICBzdHJ1Y3QgU3RhdGljVmFyaW50U2l6ZTMyIHsKKyAgICBzdGF0aWMgY29uc3QgaW50IHZhbHVlID0KKyAgICAgICAgKFZhbHVlIDwgKDEgPDwgNykpCisgICAgICAgICAgICA/IDEKKyAgICAgICAgICAgIDogKFZhbHVlIDwgKDEgPDwgMTQpKQorICAgICAgICAgICAgICAgID8gMgorICAgICAgICAgICAgICAgIDogKFZhbHVlIDwgKDEgPDwgMjEpKQorICAgICAgICAgICAgICAgICAgICA/IDMKKyAgICAgICAgICAgICAgICAgICAgOiAoVmFsdWUgPCAoMSA8PCAyOCkpCisgICAgICAgICAgICAgICAgICAgICAgICA/IDQKKyAgICAgICAgICAgICAgICAgICAgICAgIDogNTsKKyAgfTsKKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBzaW5jZSB0aGlzIG9iamVjdCB3YXMgY3JlYXRlZC4KKyAgaW5saW5lIGludCBCeXRlQ291bnQoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlcmUgd2FzIGFuIHVuZGVybHlpbmcgSS9PIGVycm9yIHNpbmNlIHRoaXMgb2JqZWN0IHdhcworICAvLyBjcmVhdGVkLgorICBib29sIEhhZEVycm9yKCkgY29uc3QgeyByZXR1cm4gaGFkX2Vycm9yXzsgfQorCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvZGVkT3V0cHV0U3RyZWFtKTsKKworICBaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0XzsKKyAgdWludDgqIGJ1ZmZlcl87CisgIGludCBidWZmZXJfc2l6ZV87CisgIGludCB0b3RhbF9ieXRlc187ICAvLyBTdW0gb2Ygc2l6ZXMgb2YgYWxsIGJ1ZmZlcnMgc2VlbiBzbyBmYXIuCisgIGJvb2wgaGFkX2Vycm9yXzsgICAvLyBXaGV0aGVyIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyBvdXRwdXQuCisgIGJvb2wgYWxpYXNpbmdfZW5hYmxlZF87ICAvLyBTZWUgRW5hYmxlQWxpYXNpbmcoKS4KKworICAvLyBBZHZhbmNlIHRoZSBidWZmZXIgYnkgYSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMuCisgIHZvaWQgQWR2YW5jZShpbnQgYW1vdW50KTsKKworICAvLyBDYWxsZWQgd2hlbiB0aGUgYnVmZmVyIHJ1bnMgb3V0IHRvIHJlcXVlc3QgbW9yZSBkYXRhLiAgSW1wbGllcyBhbgorICAvLyBBZHZhbmNlKGJ1ZmZlcl9zaXplXykuCisgIGJvb2wgUmVmcmVzaCgpOworCisgIC8vIExpa2UgV3JpdGVSYXcoKSBidXQgbWF5IGF2b2lkIGNvcHlpbmcgaWYgdGhlIHVuZGVybHlpbmcKKyAgLy8gWmVyb0NvcHlPdXRwdXRTdHJlYW0gc3VwcG9ydHMgaXQuCisgIHZvaWQgV3JpdGVBbGlhc2VkUmF3KGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpOworCisgIC8vIElmIHRoaXMgd3JpdGUgbWlnaHQgY3Jvc3MgdGhlIGVuZCBvZiB0aGUgYnVmZmVyLCB3ZSBjb21wb3NlIHRoZSBieXRlcyBmaXJzdAorICAvLyB0aGVuIHVzZSBXcml0ZVJhdygpLgorICB2b2lkIFdyaXRlVmFyaW50MzJTbG93UGF0aCh1aW50MzIgdmFsdWUpOworCisgIC8vIEFsd2F5cy1pbmxpbmVkIHZlcnNpb25zIG9mIFdyaXRlVmFyaW50KiBmdW5jdGlvbnMgc28gdGhhdCBjb2RlIGNhbiBiZQorICAvLyByZXVzZWQsIHdoaWxlIHN0aWxsIGNvbnRyb2xsaW5nIHNpemUuIEZvciBpbnN0YW5jZSwgV3JpdGVWYXJpbnQzMlRvQXJyYXkoKQorICAvLyBzaG91bGQgbm90IGRpcmVjdGx5IGNhbGwgdGhpczogc2luY2UgaXQgaXMgaW5saW5lZCBpdHNlbGYsIGRvaW5nIHNvCisgIC8vIHdvdWxkIGdyZWF0bHkgaW5jcmVhc2UgdGhlIHNpemUgb2YgZ2VuZXJhdGVkIGNvZGUuIEluc3RlYWQsIGl0IHNob3VsZCBjYWxsCisgIC8vIFdyaXRlVmFyaW50MzJGYWxsYmFja1RvQXJyYXkuICBNZWFud2hpbGUsIFdyaXRlVmFyaW50MzIoKSBpcyBhbHJlYWR5CisgIC8vIG91dC1vZi1saW5lLCBzbyBpdCBzaG91bGQganVzdCBpbnZva2UgdGhpcyBkaXJlY3RseSB0byBhdm9pZCBhbnkgZXh0cmEKKyAgLy8gZnVuY3Rpb24gY2FsbCBvdmVyaGVhZC4KKyAgc3RhdGljIHVpbnQ4KiBXcml0ZVZhcmludDY0VG9BcnJheUlubGluZSgKKyAgICAgIHVpbnQ2NCB2YWx1ZSwgdWludDgqIHRhcmdldCkgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworCisgIHN0YXRpYyBpbnQgVmFyaW50U2l6ZTMyRmFsbGJhY2sodWludDMyIHZhbHVlKTsKK307CisKKy8vIGlubGluZSBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFRoZSB2YXN0IG1ham9yaXR5IG9mIHZhcmludHMgYXJlIG9ubHkgb25lIGJ5dGUuICBUaGVzZSBpbmxpbmUKKy8vIG1ldGhvZHMgb3B0aW1pemUgZm9yIHRoYXQgY2FzZS4KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDMyKHVpbnQzMiogdmFsdWUpIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX1RSVUUoYnVmZmVyXyA8IGJ1ZmZlcl9lbmRfKSAmJiAqYnVmZmVyXyA8IDB4ODApIHsKKyAgICAqdmFsdWUgPSAqYnVmZmVyXzsKKyAgICBBZHZhbmNlKDEpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBSZWFkVmFyaW50MzJGYWxsYmFjayh2YWx1ZSk7CisgIH0KK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDY0KHVpbnQ2NCogdmFsdWUpIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX1RSVUUoYnVmZmVyXyA8IGJ1ZmZlcl9lbmRfKSAmJiAqYnVmZmVyXyA8IDB4ODApIHsKKyAgICAqdmFsdWUgPSAqYnVmZmVyXzsKKyAgICBBZHZhbmNlKDEpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBSZWFkVmFyaW50NjRGYWxsYmFjayh2YWx1ZSk7CisgIH0KK30KKworLy8gc3RhdGljCitpbmxpbmUgY29uc3QgdWludDgqIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW4zMkZyb21BcnJheSgKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgIHVpbnQzMiogdmFsdWUpIHsKKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgIG1lbWNweSh2YWx1ZSwgYnVmZmVyLCBzaXplb2YoKnZhbHVlKSk7CisgIHJldHVybiBidWZmZXIgKyBzaXplb2YoKnZhbHVlKTsKKyNlbHNlCisgICp2YWx1ZSA9IChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlclswXSkgICAgICApIHwKKyAgICAgICAgICAgKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzFdKSA8PCAgOCkgfAorICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbMl0pIDw8IDE2KSB8CisgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlclszXSkgPDwgMjQpOworICByZXR1cm4gYnVmZmVyICsgc2l6ZW9mKCp2YWx1ZSk7CisjZW5kaWYKK30KKy8vIHN0YXRpYworaW5saW5lIGNvbnN0IHVpbnQ4KiBDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXkoCisgICAgY29uc3QgdWludDgqIGJ1ZmZlciwKKyAgICB1aW50NjQqIHZhbHVlKSB7CisjaWYgZGVmaW5lZChQUk9UT0JVRl9MSVRUTEVfRU5ESUFOKQorICBtZW1jcHkodmFsdWUsIGJ1ZmZlciwgc2l6ZW9mKCp2YWx1ZSkpOworICByZXR1cm4gYnVmZmVyICsgc2l6ZW9mKCp2YWx1ZSk7CisjZWxzZQorICB1aW50MzIgcGFydDAgPSAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbMF0pICAgICAgKSB8CisgICAgICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlclsxXSkgPDwgIDgpIHwKKyAgICAgICAgICAgICAgICAgKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzJdKSA8PCAxNikgfAorICAgICAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbM10pIDw8IDI0KTsKKyAgdWludDMyIHBhcnQxID0gKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzRdKSAgICAgICkgfAorICAgICAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbNV0pIDw8ICA4KSB8CisgICAgICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlcls2XSkgPDwgMTYpIHwKKyAgICAgICAgICAgICAgICAgKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzddKSA8PCAyNCk7CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PHVpbnQ2ND4ocGFydDApIHwKKyAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDY0PihwYXJ0MSkgPDwgMzIpOworICByZXR1cm4gYnVmZmVyICsgc2l6ZW9mKCp2YWx1ZSk7CisjZW5kaWYKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZExpdHRsZUVuZGlhbjMyKHVpbnQzMiogdmFsdWUpIHsKKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKEJ1ZmZlclNpemUoKSA+PSBzdGF0aWNfY2FzdDxpbnQ+KHNpemVvZigqdmFsdWUpKSkpIHsKKyAgICBtZW1jcHkodmFsdWUsIGJ1ZmZlcl8sIHNpemVvZigqdmFsdWUpKTsKKyAgICBBZHZhbmNlKHNpemVvZigqdmFsdWUpKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gUmVhZExpdHRsZUVuZGlhbjMyRmFsbGJhY2sodmFsdWUpOworICB9CisjZWxzZQorICByZXR1cm4gUmVhZExpdHRsZUVuZGlhbjMyRmFsbGJhY2sodmFsdWUpOworI2VuZGlmCit9CisKK2lubGluZSBib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NCh1aW50NjQqIHZhbHVlKSB7CisjaWYgZGVmaW5lZChQUk9UT0JVRl9MSVRUTEVfRU5ESUFOKQorICBpZiAoR09PR0xFX1BSRURJQ1RfVFJVRShCdWZmZXJTaXplKCkgPj0gc3RhdGljX2Nhc3Q8aW50PihzaXplb2YoKnZhbHVlKSkpKSB7CisgICAgbWVtY3B5KHZhbHVlLCBidWZmZXJfLCBzaXplb2YoKnZhbHVlKSk7CisgICAgQWR2YW5jZShzaXplb2YoKnZhbHVlKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFJlYWRMaXR0bGVFbmRpYW42NEZhbGxiYWNrKHZhbHVlKTsKKyAgfQorI2Vsc2UKKyAgcmV0dXJuIFJlYWRMaXR0bGVFbmRpYW42NEZhbGxiYWNrKHZhbHVlKTsKKyNlbmRpZgorfQorCitpbmxpbmUgdWludDMyIENvZGVkSW5wdXRTdHJlYW06OlJlYWRUYWcoKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKGJ1ZmZlcl8gPCBidWZmZXJfZW5kXykgJiYgYnVmZmVyX1swXSA8IDB4ODApIHsKKyAgICBsYXN0X3RhZ18gPSBidWZmZXJfWzBdOworICAgIEFkdmFuY2UoMSk7CisgICAgcmV0dXJuIGxhc3RfdGFnXzsKKyAgfSBlbHNlIHsKKyAgICBsYXN0X3RhZ18gPSBSZWFkVGFnRmFsbGJhY2soKTsKKyAgICByZXR1cm4gbGFzdF90YWdfOworICB9Cit9CisKK2lubGluZSBzdGQ6OnBhaXI8dWludDMyLCBib29sPiBDb2RlZElucHV0U3RyZWFtOjpSZWFkVGFnV2l0aEN1dG9mZigKKyAgICB1aW50MzIgY3V0b2ZmKSB7CisgIC8vIEluIHBlcmZvcm1hbmNlLXNlbnNpdGl2ZSBjb2RlIHdlIGNhbiBleHBlY3QgY3V0b2ZmIHRvIGJlIGEgY29tcGlsZS10aW1lCisgIC8vIGNvbnN0YW50LCBhbmQgdGhpbmdzIGxpa2UgImN1dG9mZiA+PSBrTWF4MUJ5dGVWYXJpbnQiIHRvIGJlIGV2YWx1YXRlZCBhdAorICAvLyBjb21waWxlIHRpbWUuCisgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKGJ1ZmZlcl8gPCBidWZmZXJfZW5kXykpIHsKKyAgICAvLyBIb3QgY2FzZTogYnVmZmVyXyBub25fZW1wdHksIGJ1ZmZlcl9bMF0gaW4gWzEsIDEyOCkuCisgICAgLy8gVE9ETyhncGlrZSk6IElzIGl0IHdvcnRoIHJlYXJyYW5naW5nIHRoaXM/IEUuZy4sIGlmIHRoZSBudW1iZXIgb2YgZmllbGRzCisgICAgLy8gaXMgbGFyZ2UgZW5vdWdoIHRoZW4gaXMgaXQgYmV0dGVyIHRvIGNoZWNrIGZvciB0aGUgdHdvLWJ5dGUgY2FzZSBmaXJzdD8KKyAgICBpZiAoc3RhdGljX2Nhc3Q8aW50OD4oYnVmZmVyX1swXSkgPiAwKSB7CisgICAgICBjb25zdCB1aW50MzIga01heDFCeXRlVmFyaW50ID0gMHg3ZjsKKyAgICAgIHVpbnQzMiB0YWcgPSBsYXN0X3RhZ18gPSBidWZmZXJfWzBdOworICAgICAgQWR2YW5jZSgxKTsKKyAgICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcih0YWcsIGN1dG9mZiA+PSBrTWF4MUJ5dGVWYXJpbnQgfHwgdGFnIDw9IGN1dG9mZik7CisgICAgfQorICAgIC8vIE90aGVyIGhvdCBjYXNlOiBjdXRvZmYgPj0gMHg4MCwgYnVmZmVyXyBoYXMgYXQgbGVhc3QgdHdvIGJ5dGVzIGF2YWlsYWJsZSwKKyAgICAvLyBhbmQgdGFnIGlzIHR3byBieXRlcy4gIFRoZSBsYXR0ZXIgaXMgdGVzdGVkIGJ5IGJpdHdpc2UtYW5kLW5vdCBvZiB0aGUKKyAgICAvLyBmaXJzdCBieXRlIGFuZCB0aGUgc2Vjb25kIGJ5dGUuCisgICAgaWYgKGN1dG9mZiA+PSAweDgwICYmCisgICAgICAgIEdPT0dMRV9QUkVESUNUX1RSVUUoYnVmZmVyXyArIDEgPCBidWZmZXJfZW5kXykgJiYKKyAgICAgICAgR09PR0xFX1BSRURJQ1RfVFJVRSgoYnVmZmVyX1swXSAmIH5idWZmZXJfWzFdKSA+PSAweDgwKSkgeworICAgICAgY29uc3QgdWludDMyIGtNYXgyQnl0ZVZhcmludCA9ICgweDdmIDw8IDcpICsgMHg3ZjsKKyAgICAgIHVpbnQzMiB0YWcgPSBsYXN0X3RhZ18gPSAoMXUgPDwgNykgKiBidWZmZXJfWzFdICsgKGJ1ZmZlcl9bMF0gLSAweDgwKTsKKyAgICAgIEFkdmFuY2UoMik7CisgICAgICAvLyBJdCBtaWdodCBtYWtlIHNlbnNlIHRvIHRlc3QgZm9yIHRhZyA9PSAwIG5vdywgYnV0IGl0IGlzIHNvIHJhcmUgdGhhdAorICAgICAgLy8gdGhhdCB3ZSBkb24ndCBib3RoZXIuICBBIHZhcmludC1lbmNvZGVkIDAgc2hvdWxkIGJlIG9uZSBieXRlIHVubGVzcworICAgICAgLy8gdGhlIGVuY29kZXIgbG9zdCBpdHMgbWluZC4gIFRoZSBzZWNvbmQgcGFydCBvZiB0aGUgcmV0dXJuIHZhbHVlIG9mCisgICAgICAvLyB0aGlzIGZ1bmN0aW9uIGlzIGFsbG93ZWQgdG8gYmUgZWl0aGVyIHRydWUgb3IgZmFsc2UgaWYgdGhlIHRhZyBpcyAwLAorICAgICAgLy8gc28gd2UgZG9uJ3QgaGF2ZSB0byBjaGVjayBmb3IgdGFnID09IDAuICBXZSBtYXkgbmVlZCB0byBjaGVjayB3aGV0aGVyCisgICAgICAvLyBpdCBleGNlZWRzIGN1dG9mZi4KKyAgICAgIGJvb2wgYXRfb3JfYmVsb3dfY3V0b2ZmID0gY3V0b2ZmID49IGtNYXgyQnl0ZVZhcmludCB8fCB0YWcgPD0gY3V0b2ZmOworICAgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKHRhZywgYXRfb3JfYmVsb3dfY3V0b2ZmKTsKKyAgICB9CisgIH0KKyAgLy8gU2xvdyBwYXRoCisgIGxhc3RfdGFnXyA9IFJlYWRUYWdGYWxsYmFjaygpOworICByZXR1cm4gc3RkOjptYWtlX3BhaXIobGFzdF90YWdfLCBzdGF0aWNfY2FzdDx1aW50MzI+KGxhc3RfdGFnXyAtIDEpIDwgY3V0b2ZmKTsKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6TGFzdFRhZ1dhcyh1aW50MzIgZXhwZWN0ZWQpIHsKKyAgcmV0dXJuIGxhc3RfdGFnXyA9PSBleHBlY3RlZDsKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6Q29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgeworICByZXR1cm4gbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF87Cit9CisKK2lubGluZSBib29sIENvZGVkSW5wdXRTdHJlYW06OkV4cGVjdFRhZyh1aW50MzIgZXhwZWN0ZWQpIHsKKyAgaWYgKGV4cGVjdGVkIDwgKDEgPDwgNykpIHsKKyAgICBpZiAoR09PR0xFX1BSRURJQ1RfVFJVRShidWZmZXJfIDwgYnVmZmVyX2VuZF8pICYmIGJ1ZmZlcl9bMF0gPT0gZXhwZWN0ZWQpIHsKKyAgICAgIEFkdmFuY2UoMSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIGlmIChleHBlY3RlZCA8ICgxIDw8IDE0KSkgeworICAgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKEJ1ZmZlclNpemUoKSA+PSAyKSAmJgorICAgICAgICBidWZmZXJfWzBdID09IHN0YXRpY19jYXN0PHVpbnQ4PihleHBlY3RlZCB8IDB4ODApICYmCisgICAgICAgIGJ1ZmZlcl9bMV0gPT0gc3RhdGljX2Nhc3Q8dWludDg+KGV4cGVjdGVkID4+IDcpKSB7CisgICAgICBBZHZhbmNlKDIpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gRG9uJ3QgYm90aGVyIG9wdGltaXppbmcgZm9yIGxhcmdlciB2YWx1ZXMuCisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2lubGluZSBjb25zdCB1aW50OCogQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0VGFnRnJvbUFycmF5KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsIHVpbnQzMiBleHBlY3RlZCkgeworICBpZiAoZXhwZWN0ZWQgPCAoMSA8PCA3KSkgeworICAgIGlmIChidWZmZXJbMF0gPT0gZXhwZWN0ZWQpIHsKKyAgICAgIHJldHVybiBidWZmZXIgKyAxOworICAgIH0KKyAgfSBlbHNlIGlmIChleHBlY3RlZCA8ICgxIDw8IDE0KSkgeworICAgIGlmIChidWZmZXJbMF0gPT0gc3RhdGljX2Nhc3Q8dWludDg+KGV4cGVjdGVkIHwgMHg4MCkgJiYKKyAgICAgICAgYnVmZmVyWzFdID09IHN0YXRpY19jYXN0PHVpbnQ4PihleHBlY3RlZCA+PiA3KSkgeworICAgICAgcmV0dXJuIGJ1ZmZlciArIDI7CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCitpbmxpbmUgdm9pZCBDb2RlZElucHV0U3RyZWFtOjpHZXREaXJlY3RCdWZmZXJQb2ludGVySW5saW5lKGNvbnN0IHZvaWQqKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQqIHNpemUpIHsKKyAgKmRhdGEgPSBidWZmZXJfOworICAqc2l6ZSA9IGJ1ZmZlcl9lbmRfIC0gYnVmZmVyXzsKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0QXRFbmQoKSB7CisgIC8vIElmIHdlIGFyZSBhdCBhIGxpbWl0IHdlIGtub3cgbm8gbW9yZSBieXRlcyBjYW4gYmUgcmVhZC4gIE90aGVyd2lzZSwgaXQncworICAvLyBoYXJkIHRvIHNheSB3aXRob3V0IGNhbGxpbmcgUmVmcmVzaCgpLCBhbmQgd2UnZCByYXRoZXIgbm90IGRvIHRoYXQuCisKKyAgaWYgKGJ1ZmZlcl8gPT0gYnVmZmVyX2VuZF8gJiYKKyAgICAgICgoYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfICE9IDApIHx8CisgICAgICAgKHRvdGFsX2J5dGVzX3JlYWRfID09IGN1cnJlbnRfbGltaXRfKSkpIHsKKyAgICBsYXN0X3RhZ18gPSAwOyAgICAgICAgICAgICAgICAgICAvLyBQcmV0ZW5kIHdlIGNhbGxlZCBSZWFkVGFnKCkuLi4KKyAgICBsZWdpdGltYXRlX21lc3NhZ2VfZW5kXyA9IHRydWU7ICAvLyAuLi4gYW5kIGl0IGhpdCBFT0YuCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2lubGluZSBpbnQgQ29kZWRJbnB1dFN0cmVhbTo6Q3VycmVudFBvc2l0aW9uKCkgY29uc3QgeworICByZXR1cm4gdG90YWxfYnl0ZXNfcmVhZF8gLSAoQnVmZmVyU2l6ZSgpICsgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfKTsKK30KKworaW5saW5lIHVpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6R2V0RGlyZWN0QnVmZmVyRm9yTkJ5dGVzQW5kQWR2YW5jZShpbnQgc2l6ZSkgeworICBpZiAoYnVmZmVyX3NpemVfIDwgc2l6ZSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHVpbnQ4KiByZXN1bHQgPSBidWZmZXJfOworICAgIEFkdmFuY2Uoc2l6ZSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCitpbmxpbmUgdWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSh1aW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHdoaWxlICh2YWx1ZSA+PSAweDgwKSB7CisgICAgKnRhcmdldCA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWx1ZSB8IDB4ODApOworICAgIHZhbHVlID4+PSA3OworICAgICsrdGFyZ2V0OworICB9CisgICp0YXJnZXQgPSBzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUpOworICByZXR1cm4gdGFyZ2V0ICsgMTsKK30KKworaW5saW5lIHZvaWQgQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWQoaW50MzIgdmFsdWUpIHsKKyAgaWYgKHZhbHVlIDwgMCkgeworICAgIFdyaXRlVmFyaW50NjQoc3RhdGljX2Nhc3Q8dWludDY0Pih2YWx1ZSkpOworICB9IGVsc2UgeworICAgIFdyaXRlVmFyaW50MzIoc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSkpOworICB9Cit9CisKK2lubGluZSB1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWRUb0FycmF5KAorICAgIGludDMyIHZhbHVlLCB1aW50OCogdGFyZ2V0KSB7CisgIGlmICh2YWx1ZSA8IDApIHsKKyAgICByZXR1cm4gV3JpdGVWYXJpbnQ2NFRvQXJyYXkoc3RhdGljX2Nhc3Q8dWludDY0Pih2YWx1ZSksIHRhcmdldCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFdyaXRlVmFyaW50MzJUb0FycmF5KHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUpLCB0YXJnZXQpOworICB9Cit9CisKK2lubGluZSB1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlTGl0dGxlRW5kaWFuMzJUb0FycmF5KHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgIG1lbWNweSh0YXJnZXQsICZ2YWx1ZSwgc2l6ZW9mKHZhbHVlKSk7CisjZWxzZQorICB0YXJnZXRbMF0gPSBzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUpOworICB0YXJnZXRbMV0gPSBzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUgPj4gIDgpOworICB0YXJnZXRbMl0gPSBzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUgPj4gMTYpOworICB0YXJnZXRbM10gPSBzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUgPj4gMjQpOworI2VuZGlmCisgIHJldHVybiB0YXJnZXQgKyBzaXplb2YodmFsdWUpOworfQorCitpbmxpbmUgdWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjY0VG9BcnJheSh1aW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisjaWYgZGVmaW5lZChQUk9UT0JVRl9MSVRUTEVfRU5ESUFOKQorICBtZW1jcHkodGFyZ2V0LCAmdmFsdWUsIHNpemVvZih2YWx1ZSkpOworI2Vsc2UKKyAgdWludDMyIHBhcnQwID0gc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSk7CisgIHVpbnQzMiBwYXJ0MSA9IHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUgPj4gMzIpOworCisgIHRhcmdldFswXSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MCk7CisgIHRhcmdldFsxXSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MCA+PiAgOCk7CisgIHRhcmdldFsyXSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MCA+PiAxNik7CisgIHRhcmdldFszXSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MCA+PiAyNCk7CisgIHRhcmdldFs0XSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MSk7CisgIHRhcmdldFs1XSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MSA+PiAgOCk7CisgIHRhcmdldFs2XSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MSA+PiAxNik7CisgIHRhcmdldFs3XSA9IHN0YXRpY19jYXN0PHVpbnQ4PihwYXJ0MSA+PiAyNCk7CisjZW5kaWYKKyAgcmV0dXJuIHRhcmdldCArIHNpemVvZih2YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyKHVpbnQzMiB2YWx1ZSkgeworICBpZiAoYnVmZmVyX3NpemVfID49IDUpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBXZSBoYXZlIGVub3VnaCBieXRlcyBsZWZ0IGluIHRoZSBidWZmZXIgdG8gZ3VhcmFudGVlIHRoYXQKKyAgICAvLyB0aGlzIHdyaXRlIHdvbid0IGNyb3NzIHRoZSBlbmQsIHNvIHdlIGNhbiBza2lwIHRoZSBjaGVja3MuCisgICAgdWludDgqIHRhcmdldCA9IGJ1ZmZlcl87CisgICAgdWludDgqIGVuZCA9IFdyaXRlVmFyaW50MzJUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworICAgIGludCBzaXplID0gZW5kIC0gdGFyZ2V0OworICAgIEFkdmFuY2Uoc2l6ZSk7CisgIH0gZWxzZSB7CisgICAgV3JpdGVWYXJpbnQzMlNsb3dQYXRoKHZhbHVlKTsKKyAgfQorfQorCitpbmxpbmUgdm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWcodWludDMyIHZhbHVlKSB7CisgIFdyaXRlVmFyaW50MzIodmFsdWUpOworfQorCitpbmxpbmUgdWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgdWludDMyIHZhbHVlLCB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBXcml0ZVZhcmludDMyVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KKworaW5saW5lIGludCBDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKHVpbnQzMiB2YWx1ZSkgeworICBpZiAodmFsdWUgPCAoMSA8PCA3KSkgeworICAgIHJldHVybiAxOworICB9IGVsc2UgIHsKKyAgICByZXR1cm4gVmFyaW50U2l6ZTMyRmFsbGJhY2sodmFsdWUpOworICB9Cit9CisKK2lubGluZSBpbnQgQ29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMlNpZ25FeHRlbmRlZChpbnQzMiB2YWx1ZSkgeworICBpZiAodmFsdWUgPCAwKSB7CisgICAgcmV0dXJuIDEwOyAgICAgLy8gVE9ETyhrZW50b24pOiAgTWFrZSB0aGlzIGEgc3ltYm9saWMgY29uc3RhbnQuCisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFZhcmludFNpemUzMihzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlKSk7CisgIH0KK30KKworaW5saW5lIHZvaWQgQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIFdyaXRlUmF3KHN0ci5kYXRhKCksIHN0YXRpY19jYXN0PGludD4oc3RyLnNpemUoKSkpOworfQorCitpbmxpbmUgdm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVSYXdNYXliZUFsaWFzZWQoCisgICAgY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpIHsKKyAgaWYgKGFsaWFzaW5nX2VuYWJsZWRfKSB7CisgICAgV3JpdGVBbGlhc2VkUmF3KGRhdGEsIHNpemUpOworICB9IGVsc2UgeworICAgIFdyaXRlUmF3KGRhdGEsIHNpemUpOworICB9Cit9CisKK2lubGluZSB1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICBjb25zdCBzdHJpbmcmIHN0ciwgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gV3JpdGVSYXdUb0FycmF5KHN0ci5kYXRhKCksIHN0YXRpY19jYXN0PGludD4oc3RyLnNpemUoKSksIHRhcmdldCk7Cit9CisKK2lubGluZSBpbnQgQ29kZWRPdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHRvdGFsX2J5dGVzXyAtIGJ1ZmZlcl9zaXplXzsKK30KKworaW5saW5lIHZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6QWR2YW5jZShpbnQgYW1vdW50KSB7CisgIGJ1ZmZlcl8gKz0gYW1vdW50OworfQorCitpbmxpbmUgdm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6QWR2YW5jZShpbnQgYW1vdW50KSB7CisgIGJ1ZmZlcl8gKz0gYW1vdW50OworICBidWZmZXJfc2l6ZV8gLT0gYW1vdW50OworfQorCitpbmxpbmUgdm9pZCBDb2RlZElucHV0U3RyZWFtOjpTZXRSZWN1cnNpb25MaW1pdChpbnQgbGltaXQpIHsKKyAgcmVjdXJzaW9uX2J1ZGdldF8gKz0gbGltaXQgLSByZWN1cnNpb25fbGltaXRfOworICByZWN1cnNpb25fbGltaXRfID0gbGltaXQ7Cit9CisKK2lubGluZSBib29sIENvZGVkSW5wdXRTdHJlYW06OkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkgeworICAtLXJlY3Vyc2lvbl9idWRnZXRfOworICByZXR1cm4gcmVjdXJzaW9uX2J1ZGdldF8gPj0gMDsKK30KKworaW5saW5lIHZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6RGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKSB7CisgIGlmIChyZWN1cnNpb25fYnVkZ2V0XyA8IHJlY3Vyc2lvbl9saW1pdF8pICsrcmVjdXJzaW9uX2J1ZGdldF87Cit9CisKK2lubGluZSB2b2lkIENvZGVkSW5wdXRTdHJlYW06OlNldEV4dGVuc2lvblJlZ2lzdHJ5KGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIHsKKyAgZXh0ZW5zaW9uX3Bvb2xfID0gcG9vbDsKKyAgZXh0ZW5zaW9uX2ZhY3RvcnlfID0gZmFjdG9yeTsKK30KKworaW5saW5lIGNvbnN0IERlc2NyaXB0b3JQb29sKiBDb2RlZElucHV0U3RyZWFtOjpHZXRFeHRlbnNpb25Qb29sKCkgeworICByZXR1cm4gZXh0ZW5zaW9uX3Bvb2xfOworfQorCitpbmxpbmUgTWVzc2FnZUZhY3RvcnkqIENvZGVkSW5wdXRTdHJlYW06OkdldEV4dGVuc2lvbkZhY3RvcnkoKSB7CisgIHJldHVybiBleHRlbnNpb25fZmFjdG9yeV87Cit9CisKK2lubGluZSBpbnQgQ29kZWRJbnB1dFN0cmVhbTo6QnVmZmVyU2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGJ1ZmZlcl9lbmRfIC0gYnVmZmVyXzsKK30KKworaW5saW5lIENvZGVkSW5wdXRTdHJlYW06OkNvZGVkSW5wdXRTdHJlYW0oWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQpCisgIDogYnVmZmVyXyhOVUxMKSwKKyAgICBidWZmZXJfZW5kXyhOVUxMKSwKKyAgICBpbnB1dF8oaW5wdXQpLAorICAgIHRvdGFsX2J5dGVzX3JlYWRfKDApLAorICAgIG92ZXJmbG93X2J5dGVzXygwKSwKKyAgICBsYXN0X3RhZ18oMCksCisgICAgbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF8oZmFsc2UpLAorICAgIGFsaWFzaW5nX2VuYWJsZWRfKGZhbHNlKSwKKyAgICBjdXJyZW50X2xpbWl0XyhraW50MzJtYXgpLAorICAgIGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XygwKSwKKyAgICB0b3RhbF9ieXRlc19saW1pdF8oa0RlZmF1bHRUb3RhbEJ5dGVzTGltaXQpLAorICAgIHRvdGFsX2J5dGVzX3dhcm5pbmdfdGhyZXNob2xkXyhrRGVmYXVsdFRvdGFsQnl0ZXNXYXJuaW5nVGhyZXNob2xkKSwKKyAgICByZWN1cnNpb25fYnVkZ2V0XyhkZWZhdWx0X3JlY3Vyc2lvbl9saW1pdF8pLAorICAgIHJlY3Vyc2lvbl9saW1pdF8oZGVmYXVsdF9yZWN1cnNpb25fbGltaXRfKSwKKyAgICBleHRlbnNpb25fcG9vbF8oTlVMTCksCisgICAgZXh0ZW5zaW9uX2ZhY3RvcnlfKE5VTEwpIHsKKyAgLy8gRWFnZXJseSBSZWZyZXNoKCkgc28gYnVmZmVyIHNwYWNlIGlzIGltbWVkaWF0ZWx5IGF2YWlsYWJsZS4KKyAgUmVmcmVzaCgpOworfQorCitpbmxpbmUgQ29kZWRJbnB1dFN0cmVhbTo6Q29kZWRJbnB1dFN0cmVhbShjb25zdCB1aW50OCogYnVmZmVyLCBpbnQgc2l6ZSkKKyAgOiBidWZmZXJfKGJ1ZmZlciksCisgICAgYnVmZmVyX2VuZF8oYnVmZmVyICsgc2l6ZSksCisgICAgaW5wdXRfKE5VTEwpLAorICAgIHRvdGFsX2J5dGVzX3JlYWRfKHNpemUpLAorICAgIG92ZXJmbG93X2J5dGVzXygwKSwKKyAgICBsYXN0X3RhZ18oMCksCisgICAgbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF8oZmFsc2UpLAorICAgIGFsaWFzaW5nX2VuYWJsZWRfKGZhbHNlKSwKKyAgICBjdXJyZW50X2xpbWl0XyhzaXplKSwKKyAgICBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8oMCksCisgICAgdG90YWxfYnl0ZXNfbGltaXRfKGtEZWZhdWx0VG90YWxCeXRlc0xpbWl0KSwKKyAgICB0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8oa0RlZmF1bHRUb3RhbEJ5dGVzV2FybmluZ1RocmVzaG9sZCksCisgICAgcmVjdXJzaW9uX2J1ZGdldF8oZGVmYXVsdF9yZWN1cnNpb25fbGltaXRfKSwKKyAgICByZWN1cnNpb25fbGltaXRfKGRlZmF1bHRfcmVjdXJzaW9uX2xpbWl0XyksCisgICAgZXh0ZW5zaW9uX3Bvb2xfKE5VTEwpLAorICAgIGV4dGVuc2lvbl9mYWN0b3J5XyhOVUxMKSB7CisgIC8vIE5vdGUgdGhhdCBzZXR0aW5nIGN1cnJlbnRfbGltaXRfID09IHNpemUgaXMgaW1wb3J0YW50IHRvIHByZXZlbnQgc29tZQorICAvLyBjb2RlIHBhdGhzIGZyb20gdHJ5aW5nIHRvIGFjY2VzcyBpbnB1dF8gYW5kIHNlZ2ZhdWx0aW5nLgorfQorCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpJc0ZsYXQoKSBjb25zdCB7CisgIHJldHVybiBpbnB1dF8gPT0gTlVMTDsKK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCisjaWYgZGVmaW5lZChfTVNDX1ZFUikgJiYgX01TQ19WRVIgPj0gMTMwMAorICAjcHJhZ21hIHJ1bnRpbWVfY2hlY2tzKCJjIiwgcmVzdG9yZSkKKyNlbmRpZiAgLy8gX01TQ19WRVIKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfSU9fQ09ERURfU1RSRUFNX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbV9pbmwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZDhkMTc0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmgKQEAgLTAsMCArMSw3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogamFzb25oQGdvb2dsZS5jb20gKEphc29uIEhzdWVoKQorLy8KKy8vIEltcGxlbWVudHMgbWV0aG9kcyBvZiBjb2RlZF9zdHJlYW0uaCB0aGF0IG5lZWQgdG8gYmUgaW5saW5lZCBmb3IgcGVyZm9ybWFuY2UKKy8vIHJlYXNvbnMsIGJ1dCBzaG91bGQgbm90IGJlIGRlZmluZWQgaW4gYSBwdWJsaWMgaGVhZGVyLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19DT0RFRF9TVFJFQU1fSU5MX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fQ09ERURfU1RSRUFNX0lOTF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpJbnRlcm5hbFJlYWRTdHJpbmdJbmxpbmUoc3RyaW5nKiBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUpIHsKKyAgaWYgKHNpemUgPCAwKSByZXR1cm4gZmFsc2U7ICAvLyBzZWN1cml0eTogc2l6ZSBpcyBvZnRlbiB1c2VyLXN1cHBsaWVkCisKKyAgaWYgKEJ1ZmZlclNpemUoKSA+PSBzaXplKSB7CisgICAgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZChidWZmZXIsIHNpemUpOworICAgIHN0ZDo6cGFpcjxjaGFyKiwgYm9vbD4geiA9IGFzX3N0cmluZ19kYXRhKGJ1ZmZlcik7CisgICAgaWYgKHouc2Vjb25kKSB7CisgICAgICAvLyBPZGRseSBlbm91Z2gsIG1lbWNweSgpIHJlcXVpcmVzIGl0cyBmaXJzdCB0d28gYXJncyB0byBiZSBub24tTlVMTCBldmVuCisgICAgICAvLyBpZiB3ZSBjb3B5IDAgYnl0ZXMuICBTbywgd2UgaGF2ZSBlbnN1cmVkIHRoYXQgei5maXJzdCBpcyBub24tTlVMTCBoZXJlLgorICAgICAgR09PR0xFX0RDSEVDSyh6LmZpcnN0ICE9IE5VTEwpOworICAgICAgbWVtY3B5KHouZmlyc3QsIGJ1ZmZlcl8sIHNpemUpOworICAgICAgQWR2YW5jZShzaXplKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICByZXR1cm4gUmVhZFN0cmluZ0ZhbGxiYWNrKGJ1ZmZlciwgc2l6ZSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9JT19DT0RFRF9TVFJFQU1fSU5MX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1fdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMmQ1YmFkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1fdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMzc5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRlc3RzIGFuZCBiZW5jaG1hcmtzLgorCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorCisjaW5jbHVkZSA8bGltaXRzLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorCisKKy8vIFRoaXMgZGVjbGFyZXMgYW4gdW5zaWduZWQgbG9uZyBsb25nIGludGVnZXIgbGl0ZXJhbCBpbiBhIHBvcnRhYmxlIHdheS4KKy8vIChUaGUgb3JpZ2luYWwgbWFjcm8gaXMgd2F5IHRvbyBiaWcgYW5kIHJ1aW5zIG15IGZvcm1hdHRpbmcuKQorI3VuZGVmIFVMTAorI2RlZmluZSBVTEwoeCkgR09PR0xFX1VMT05HTE9ORyh4KQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworbmFtZXNwYWNlIHsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGF0YS1Ecml2ZW4gVGVzdCBJbmZyYXN0cnVjdHVyZQorCisvLyBURVNUXzFEIGFuZCBURVNUXzJEIGFyZSBtYWNyb3MgSSdkIGV2ZW50dWFsbHkgbGlrZSB0byBzZWUgYWRkZWQgdG8KKy8vIGdUZXN0LiAgVGhlc2UgbWFjcm9zIGNhbiBiZSB1c2VkIHRvIGRlY2xhcmUgdGVzdHMgd2hpY2ggc2hvdWxkIGJlCisvLyBydW4gbXVsdGlwbGUgdGltZXMsIG9uY2UgZm9yIGVhY2ggaXRlbSBpbiBzb21lIGlucHV0IGFycmF5LiAgVEVTVF8xRAorLy8gdGVzdHMgYWxsIGNhc2VzIGluIGEgc2luZ2xlIGlucHV0IGFycmF5LiAgVEVTVF8yRCB0ZXN0cyBhbGwKKy8vIGNvbWJpbmF0aW9ucyBvZiBjYXNlcyBmcm9tIHR3byBhcnJheXMuICBUaGUgYXJyYXlzIG11c3QgYmUgc3RhdGljYWxseQorLy8gZGVmaW5lZCBzdWNoIHRoYXQgdGhlIEdPT0dMRV9BUlJBWVNJWkUoKSBtYWNybyB3b3JrcyBvbiB0aGVtLiAgRXhhbXBsZToKKy8vCisvLyBpbnQga0Nhc2VzW10gPSB7MSwgMiwgMywgNH0KKy8vIFRFU1RfMUQoTXlGaXh0dXJlLCBNeVRlc3QsIGtDYXNlcykgeworLy8gICBFWFBFQ1RfR1Qoa0Nhc2VzX2Nhc2UsIDApOworLy8gfQorLy8KKy8vIFRoaXMgdGVzdCBpdGVyYXRlcyB0aHJvdWdoIHRoZSBudW1iZXJzIDEsIDIsIDMsIGFuZCA0IGFuZCB0ZXN0cyB0aGF0CisvLyB0aGV5IGFyZSBhbGwgZ3JhdGVyIHRoYW4gemVyby4gIEluIGNhc2Ugb2YgZmFpbHVyZSwgdGhlIGV4YWN0IGNhc2UKKy8vIHdoaWNoIGZhaWxlZCB3aWxsIGJlIHByaW50ZWQuICBUaGUgY2FzZSB0eXBlIG11c3QgYmUgcHJpbnRhYmxlIHVzaW5nCisvLyBvc3RyZWFtOjpvcGVyYXRvcjw8LgorCisvLyBUT0RPKGtlbnRvbik6ICBnVGVzdCBub3cgc3VwcG9ydHMgInBhcmFtZXRlcml6ZWQgdGVzdHMiIHdoaWNoIHdvdWxkIGJlCisvLyAgIGEgYmV0dGVyIHdheSB0byBhY2NvbXBsaXNoIHRoaXMuICBSZXdyaXRlIHdoZW4gdGltZSBwZXJtaXRzLgorCisjZGVmaW5lIFRFU1RfMUQoRklYVFVSRSwgTkFNRSwgQ0FTRVMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIEZJWFRVUkUjI18jI05BTUUjI19ERCA6IHB1YmxpYyBGSVhUVVJFIHsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICBwcm90ZWN0ZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIENhc2VUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdm9pZCBEb1NpbmdsZUNhc2UoY29uc3QgQ2FzZVR5cGUmIENBU0VTIyNfY2FzZSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFRFU1RfRihGSVhUVVJFIyNfIyNOQU1FIyNfREQsIE5BTUUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKENBU0VTKTsgaSsrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgU0NPUEVEX1RSQUNFKHRlc3Rpbmc6Ok1lc3NhZ2UoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCAjQ0FTRVMgIiBjYXNlICMiIDw8IGkgPDwgIjogIiA8PCBDQVNFU1tpXSk7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgRG9TaW5nbGVDYXNlKENBU0VTW2ldKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEZJWFRVUkUjI18jI05BTUUjI19ERDo6RG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlJiBDQVNFUyMjX2Nhc2UpCisKKyNkZWZpbmUgVEVTVF8yRChGSVhUVVJFLCBOQU1FLCBDQVNFUzEsIENBU0VTMikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2xhc3MgRklYVFVSRSMjXyMjTkFNRSMjX0REIDogcHVibGljIEZJWFRVUkUgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgIHByb3RlY3RlZDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGUxLCB0eXBlbmFtZSBDYXNlVHlwZTI+ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB2b2lkIERvU2luZ2xlQ2FzZShjb25zdCBDYXNlVHlwZTEmIENBU0VTMSMjX2Nhc2UsICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDYXNlVHlwZTImIENBU0VTMiMjX2Nhc2UpOyAgICAgICAgICAgICAgICAgICAgIFwKKyAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVEVTVF9GKEZJWFRVUkUjI18jI05BTUUjI19ERCwgTkFNRSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoQ0FTRVMxKTsgaSsrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IEdPT0dMRV9BUlJBWVNJWkUoQ0FTRVMyKTsgaisrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTQ09QRURfVFJBQ0UodGVzdGluZzo6TWVzc2FnZSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIDw8ICNDQVNFUzEgIiBjYXNlICMiIDw8IGkgPDwgIjogIiA8PCBDQVNFUzFbaV0gPDwgIiwgIiAgICAgICAgICAgXAorICAgICAgICAgIDw8ICNDQVNFUzIgIiBjYXNlICMiIDw8IGogPDwgIjogIiA8PCBDQVNFUzJbal0pOyAgICAgICAgICAgICAgICAgXAorICAgICAgICBEb1NpbmdsZUNhc2UoQ0FTRVMxW2ldLCBDQVNFUzJbal0pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGUxLCB0eXBlbmFtZSBDYXNlVHlwZTI+ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEZJWFRVUkUjI18jI05BTUUjI19ERDo6RG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlMSYgQ0FTRVMxIyNfY2FzZSwgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENhc2VUeXBlMiYgQ0FTRVMyIyNfY2FzZSkKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBDb2RlZFN0cmVhbVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBIZWxwZXIgbWV0aG9kIHVzZWQgYnkgdGVzdHMgZm9yIGJ5dGVzIHdhcm5pbmcuIFNlZSBpbXBsZW1lbnRhdGlvbiBjb21tZW50CisgIC8vIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICBzdGF0aWMgdm9pZCBTZXR1cFRvdGFsQnl0ZXNMaW1pdFdhcm5pbmdUZXN0KAorICAgICAgaW50IHRvdGFsX2J5dGVzX2xpbWl0LCBpbnQgd2FybmluZ190aHJlc2hvbGQsCisgICAgICB2ZWN0b3I8c3RyaW5nPiogb3V0X2Vycm9ycywgdmVjdG9yPHN0cmluZz4qIG91dF93YXJuaW5ncyk7CisKKyAgLy8gQnVmZmVyIHVzZWQgZHVyaW5nIG1vc3Qgb2YgdGhlIHRlc3RzLiBUaGlzIGFzc3VtZXMgdGVzdHMgcnVuIHNlcXVlbnRpYWxseS4KKyAgc3RhdGljIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDEwMjQgKiA2NDsKKyAgc3RhdGljIHVpbnQ4IGJ1ZmZlcl9ba0J1ZmZlclNpemVdOworfTsKKwordWludDggQ29kZWRTdHJlYW1UZXN0OjpidWZmZXJfW0NvZGVkU3RyZWFtVGVzdDo6a0J1ZmZlclNpemVdOworCisvLyBXZSB0ZXN0IGVhY2ggb3BlcmF0aW9uIG92ZXIgYSB2YXJpZXR5IG9mIGJsb2NrIHNpemVzIHRvIGluc3VyZSB0aGF0CisvLyB3ZSB0ZXN0IGNhc2VzIHdoZXJlIHJlYWRzIG9yIHdyaXRlcyBjcm9zcyBidWZmZXIgYm91bmRhcmllcywgY2FzZXMKKy8vIHdoZXJlIHRoZXkgZG9uJ3QsIGFuZCBjYXNlcyB3aGVyZSB0aGVyZSBpcyBzbyBtdWNoIGJ1ZmZlciBsZWZ0IHRoYXQKKy8vIHdlIGNhbiB1c2Ugc3BlY2lhbCBvcHRpbWl6ZWQgcGF0aHMgdGhhdCBkb24ndCB3b3JyeSBhYm91dCBib3VuZHMKKy8vIGNoZWNrcy4KK2NvbnN0IGludCBrQmxvY2tTaXplc1tdID0gezEsIDIsIDMsIDUsIDcsIDEzLCAzMiwgMTAyNH07CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVmFyaW50IHRlc3RzLgorCitzdHJ1Y3QgVmFyaW50Q2FzZSB7CisgIHVpbnQ4IGJ5dGVzWzEwXTsgICAgICAgICAgLy8gRW5jb2RlZCBieXRlcy4KKyAgaW50IHNpemU7ICAgICAgICAgICAgICAgICAvLyBFbmNvZGVkIHNpemUsIGluIGJ5dGVzLgorICB1aW50NjQgdmFsdWU7ICAgICAgICAgICAgIC8vIFBhcnNlZCB2YWx1ZS4KK307CisKK2lubGluZSBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvcywgY29uc3QgVmFyaW50Q2FzZSYgYykgeworICByZXR1cm4gb3MgPDwgYy52YWx1ZTsKK30KKworVmFyaW50Q2FzZSBrVmFyaW50Q2FzZXNbXSA9IHsKKyAgLy8gMzItYml0IHZhbHVlcworICB7ezB4MDB9ICAgICAgLCAxLCAwfSwKKyAge3sweDAxfSAgICAgICwgMSwgMX0sCisgIHt7MHg3Zn0gICAgICAsIDEsIDEyN30sCisgIHt7MHhhMiwgMHg3NH0sIDIsICgweDIyIDw8IDApIHwgKDB4NzQgPDwgNyl9LCAgICAgICAgICAvLyAxNDg4MgorICB7ezB4YmUsIDB4ZjcsIDB4OTIsIDB4ODQsIDB4MGJ9LCA1LCAgICAgICAgICAgICAgICAgICAgLy8gMjk2MTQ4ODgzMAorICAgICgweDNlIDw8IDApIHwgKDB4NzcgPDwgNykgfCAoMHgxMiA8PCAxNCkgfCAoMHgwNCA8PCAyMSkgfAorICAgIChVTEwoMHgwYikgPDwgMjgpfSwKKworICAvLyA2NC1iaXQKKyAge3sweGJlLCAweGY3LCAweDkyLCAweDg0LCAweDFifSwgNSwgICAgICAgICAgICAgICAgICAgIC8vIDcyNTY0NTYxMjYKKyAgICAoMHgzZSA8PCAwKSB8ICgweDc3IDw8IDcpIHwgKDB4MTIgPDwgMTQpIHwgKDB4MDQgPDwgMjEpIHwKKyAgICAoVUxMKDB4MWIpIDw8IDI4KX0sCisgIHt7MHg4MCwgMHhlNiwgMHhlYiwgMHg5YywgMHhjMywgMHhjOSwgMHhhNCwgMHg0OX0sIDgsICAvLyA0MTI1NjIwMjU4MDcxODMzNgorICAgICgweDAwIDw8IDApIHwgKDB4NjYgPDwgNykgfCAoMHg2YiA8PCAxNCkgfCAoMHgxYyA8PCAyMSkgfAorICAgIChVTEwoMHg0MykgPDwgMjgpIHwgKFVMTCgweDQ5KSA8PCAzNSkgfCAoVUxMKDB4MjQpIDw8IDQyKSB8CisgICAgKFVMTCgweDQ5KSA8PCA0OSl9LAorICAvLyAxMTk2NDM3ODMzMDk3ODczNTEzMQorICB7ezB4OWIsIDB4YTgsIDB4ZjksIDB4YzIsIDB4YmIsIDB4ZDYsIDB4ODAsIDB4ODUsIDB4YTYsIDB4MDF9LCAxMCwKKyAgICAoMHgxYiA8PCAwKSB8ICgweDI4IDw8IDcpIHwgKDB4NzkgPDwgMTQpIHwgKDB4NDIgPDwgMjEpIHwKKyAgICAoVUxMKDB4M2IpIDw8IDI4KSB8IChVTEwoMHg1NikgPDwgMzUpIHwgKFVMTCgweDAwKSA8PCA0MikgfAorICAgIChVTEwoMHgwNSkgPDwgNDkpIHwgKFVMTCgweDI2KSA8PCA1NikgfCAoVUxMKDB4MDEpIDw8IDYzKX0sCit9OworCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFZhcmludDMyLCBrVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgdWludDMyIHZhbHVlOworICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRWYXJpbnQzMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSksIHZhbHVlKTsKKyAgfQorCisgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS5zaXplLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkVGFnLCBrVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgdWludDMyIGV4cGVjdGVkX3ZhbHVlID0gc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSk7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3ZhbHVlLCBjb2RlZF9pbnB1dC5SZWFkVGFnKCkpOworCisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuTGFzdFRhZ1dhcyhleHBlY3RlZF92YWx1ZSkpOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5MYXN0VGFnV2FzKGV4cGVjdGVkX3ZhbHVlICsgMSkpOworICB9CisKKyAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworLy8gVGhpcyBpcyB0aGUgcmVncmVzc2lvbiB0ZXN0IHRoYXQgdmVyaWZpZXMgdGhhdCB0aGVyZSBpcyBubyBpc3N1ZXMKKy8vIHdpdGggdGhlIGVtcHR5IGlucHV0IGJ1ZmZlcnMgaGFuZGxpbmcuCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBFbXB0eUlucHV0QmVmb3JlRW9zKSB7CisgIGNsYXNzIEluIDogcHVibGljIFplcm9Db3B5SW5wdXRTdHJlYW0geworICAgcHVibGljOgorICAgIEluKCkgOiBjb3VudF8oMCkge30KKyAgIHByaXZhdGU6CisgICAgdmlydHVhbCBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICAgICAgKmRhdGEgPSBOVUxMOworICAgICAgKnNpemUgPSAwOworICAgICAgcmV0dXJuIGNvdW50XysrIDwgMjsKKyAgICB9CisgICAgdmlydHVhbCB2b2lkIEJhY2tVcChpbnQgY291bnQpICB7CisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGVzdHMgbmV2ZXIgY2FsbCB0aGlzLiI7CisgICAgfQorICAgIHZpcnR1YWwgYm9vbCBTa2lwKGludCBjb3VudCkgeworICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlRlc3RzIG5ldmVyIGNhbGwgdGhpcy4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB2aXJ0dWFsIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0IHsgcmV0dXJuIDA7IH0KKyAgICBpbnQgY291bnRfOworICB9IGluOworICBDb2RlZElucHV0U3RyZWFtIGlucHV0KCZpbik7CisgIGlucHV0LlJlYWRUYWcoKTsKKyAgRVhQRUNUX1RSVUUoaW5wdXQuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkpOworfQorCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgRXhwZWN0VGFnLCBrVmFyaW50Q2FzZXMpIHsKKyAgLy8gTGVhdmUgb25lIGJ5dGUgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyIHNvIHdlIGNhbiByZWFkIGl0CisgIC8vIHRvIGZvcmNlIHRoZSBmaXJzdCBidWZmZXIgdG8gYmUgbG9hZGVkLgorICBidWZmZXJfWzBdID0gJ1wwJzsKKyAgbWVtY3B5KGJ1ZmZlcl8gKyAxLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgLy8gUmVhZCBvbmUgYnl0ZSB0byBmb3JjZSBjb2RlZF9pbnB1dC5SZWZpbGwoKSB0byBiZSBjYWxsZWQuICBPdGhlcndpc2UsCisgICAgLy8gRXhwZWN0VGFnKCkgd2lsbCByZXR1cm4gYSBmYWxzZSBuZWdhdGl2ZS4KKyAgICB1aW50OCBkdW1teTsKKyAgICBjb2RlZF9pbnB1dC5SZWFkUmF3KCZkdW1teSwgMSk7CisgICAgRVhQRUNUX0VRKCh1aW50KSdcMCcsICh1aW50KWR1bW15KTsKKworICAgIHVpbnQzMiBleHBlY3RlZF92YWx1ZSA9IHN0YXRpY19jYXN0PHVpbnQzMj4oa1ZhcmludENhc2VzX2Nhc2UudmFsdWUpOworCisgICAgLy8gRXhwZWN0VGFnKCkgcHJvZHVjZXMgZmFsc2UgbmVnYXRpdmVzIGZvciBsYXJnZSB2YWx1ZXMuCisgICAgaWYgKGtWYXJpbnRDYXNlc19jYXNlLnNpemUgPD0gMikgeworICAgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LkV4cGVjdFRhZyhleHBlY3RlZF92YWx1ZSArIDEpKTsKKyAgICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkV4cGVjdFRhZyhleHBlY3RlZF92YWx1ZSkpOworICAgIH0gZWxzZSB7CisgICAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuRXhwZWN0VGFnKGV4cGVjdGVkX3ZhbHVlKSk7CisgICAgfQorICB9CisKKyAgaWYgKGtWYXJpbnRDYXNlc19jYXNlLnNpemUgPD0gMikgeworICAgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS5zaXplICsgMSwgaW5wdXQuQnl0ZUNvdW50KCkpOworICB9IGVsc2UgeworICAgIEVYUEVDVF9FUSgxLCBpbnB1dC5CeXRlQ291bnQoKSk7CisgIH0KK30KKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIEV4cGVjdFRhZ0Zyb21BcnJheSwga1ZhcmludENhc2VzKSB7CisgIG1lbWNweShidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisKKyAgY29uc3QgdWludDMyIGV4cGVjdGVkX3ZhbHVlID0gc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSk7CisKKyAgLy8gSWYgdGhlIGV4cGVjdGF0aW9uIHN1Y2NlZWRzLCBpdCBzaG91bGQgcmV0dXJuIGEgcG9pbnRlciBwYXN0IHRoZSB0YWcuCisgIGlmIChrVmFyaW50Q2FzZXNfY2FzZS5zaXplIDw9IDIpIHsKKyAgICBFWFBFQ1RfVFJVRShOVUxMID09CisgICAgICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0VGFnRnJvbUFycmF5KGJ1ZmZlcl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkX3ZhbHVlICsgMSkpOworICAgIEVYUEVDVF9UUlVFKGJ1ZmZlcl8gKyBrVmFyaW50Q2FzZXNfY2FzZS5zaXplID09CisgICAgICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0VGFnRnJvbUFycmF5KGJ1ZmZlcl8sIGV4cGVjdGVkX3ZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgRVhQRUNUX1RSVUUoTlVMTCA9PQorICAgICAgICAgICAgICAgIENvZGVkSW5wdXRTdHJlYW06OkV4cGVjdFRhZ0Zyb21BcnJheShidWZmZXJfLCBleHBlY3RlZF92YWx1ZSkpOworICB9Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkVmFyaW50NjQsIGtWYXJpbnRDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtWYXJpbnRDYXNlc19jYXNlLmJ5dGVzLCBrVmFyaW50Q2FzZXNfY2FzZS5zaXplKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICB1aW50NjQgdmFsdWU7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFZhcmludDY0KCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSwgdmFsdWUpOworICB9CisKKyAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworVEVTVF8yRChDb2RlZFN0cmVhbVRlc3QsIFdyaXRlVmFyaW50MzIsIGtWYXJpbnRDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgaWYgKGtWYXJpbnRDYXNlc19jYXNlLnZhbHVlID4gVUxMKDB4MDAwMDAwMDBGRkZGRkZGRikpIHsKKyAgICAvLyBTa2lwIHRoaXMgdGVzdCBmb3IgdGhlIDY0LWJpdCB2YWx1ZXMuCisgICAgcmV0dXJuOworICB9CisKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dHB1dCgmb3V0cHV0KTsKKworICAgIGNvZGVkX291dHB1dC5Xcml0ZVZhcmludDMyKHN0YXRpY19jYXN0PHVpbnQzMj4oa1ZhcmludENhc2VzX2Nhc2UudmFsdWUpKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfb3V0cHV0LkhhZEVycm9yKCkpOworCisgICAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIGNvZGVkX291dHB1dC5CeXRlQ291bnQoKSk7CisgIH0KKworICBFWFBFQ1RfRVEoa1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsCisgICAgbWVtY21wKGJ1ZmZlcl8sIGtWYXJpbnRDYXNlc19jYXNlLmJ5dGVzLCBrVmFyaW50Q2FzZXNfY2FzZS5zaXplKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBXcml0ZVZhcmludDY0LCBrVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQoJm91dHB1dCk7CisKKyAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQ2NChrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX291dHB1dC5IYWRFcnJvcigpKTsKKworICAgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS5zaXplLCBjb2RlZF9vdXRwdXQuQnl0ZUNvdW50KCkpOworICB9CisKKyAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIG91dHB1dC5CeXRlQ291bnQoKSk7CisgIEVYUEVDVF9FUSgwLAorICAgIG1lbWNtcChidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSkpOworfQorCisvLyBUaGlzIHRlc3QgY2F1c2VzIGdjYyAzLjMuNSAoYW5kIGVhcmxpZXI/KSB0byBnaXZlIHRoZSBjcnlwdGljIGVycm9yOgorLy8gICAic29ycnksIHVuaW1wbGVtZW50ZWQ6IGBtZXRob2RfY2FsbF9leHByJyBub3Qgc3VwcG9ydGVkIGJ5IGR1bXBfZXhwciIKKyNpZiAhZGVmaW5lZChfX0dOVUNfXykgfHwgX19HTlVDX18gPiAzIHx8IChfX0dOVUNfXyA9PSAzICYmIF9fR05VQ19NSU5PUl9fID4gMykKKworaW50MzIga1NpZ25FeHRlbmRlZFZhcmludENhc2VzW10gPSB7CisgIDAsIDEsIC0xLCAxMjM3ODk0LCAtMzc4OTUxMzgKK307CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBXcml0ZVZhcmludDMyU2lnbkV4dGVuZGVkLAorICAgICAgICBrU2lnbkV4dGVuZGVkVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQoJm91dHB1dCk7CisKKyAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZChrU2lnbkV4dGVuZGVkVmFyaW50Q2FzZXNfY2FzZSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX291dHB1dC5IYWRFcnJvcigpKTsKKworICAgIGlmIChrU2lnbkV4dGVuZGVkVmFyaW50Q2FzZXNfY2FzZSA8IDApIHsKKyAgICAgIEVYUEVDVF9FUSgxMCwgY29kZWRfb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgICB9IGVsc2UgeworICAgICAgRVhQRUNUX0xFKGNvZGVkX291dHB1dC5CeXRlQ291bnQoKSwgNSk7CisgICAgfQorICB9CisKKyAgaWYgKGtTaWduRXh0ZW5kZWRWYXJpbnRDYXNlc19jYXNlIDwgMCkgeworICAgIEVYUEVDVF9FUSgxMCwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgfSBlbHNlIHsKKyAgICBFWFBFQ1RfTEUob3V0cHV0LkJ5dGVDb3VudCgpLCA1KTsKKyAgfQorCisgIC8vIFJlYWQgdmFsdWUgYmFjayBpbiBhcyBhIHZhcmludDY0IGFuZCBpbnN1cmUgaXQgbWF0Y2hlcy4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXykpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICB1aW50NjQgdmFsdWU7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFZhcmludDY0KCZ2YWx1ZSkpOworCisgICAgRVhQRUNUX0VRKGtTaWduRXh0ZW5kZWRWYXJpbnRDYXNlc19jYXNlLCBzdGF0aWNfY2FzdDxpbnQ2ND4odmFsdWUpKTsKKyAgfQorCisgIEVYUEVDVF9FUShvdXRwdXQuQnl0ZUNvdW50KCksIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworI2VuZGlmCisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVmFyaW50IGZhaWx1cmUgdGVzdC4KKworc3RydWN0IFZhcmludEVycm9yQ2FzZSB7CisgIHVpbnQ4IGJ5dGVzWzEyXTsKKyAgaW50IHNpemU7CisgIGJvb2wgY2FuX3BhcnNlOworfTsKKworaW5saW5lIHN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBWYXJpbnRFcnJvckNhc2UmIGMpIHsKKyAgcmV0dXJuIG9zIDw8ICJzaXplICIgPDwgYy5zaXplOworfQorCitjb25zdCBWYXJpbnRFcnJvckNhc2Uga1ZhcmludEVycm9yQ2FzZXNbXSA9IHsKKyAgLy8gQ29udHJvbCBjYXNlLiAgKEluc3VyZXMgdGhhdCB0aGVyZSBpc24ndCBzb21ldGhpbmcgZWxzZSB3cm9uZyB0aGF0CisgIC8vIG1ha2VzIHBhcnNpbmcgYWx3YXlzIGZhaWwuKQorICB7ezB4MDB9LCAxLCB0cnVlfSwKKworICAvLyBObyBpbnB1dCBkYXRhLgorICB7e30sIDAsIGZhbHNlfSwKKworICAvLyBJbnB1dCBlbmRzIHVuZXhwZWN0ZWRseS4KKyAge3sweGYwLCAweGFifSwgMiwgZmFsc2V9LAorCisgIC8vIElucHV0IGVuZHMgdW5leHBlY3RlZGx5IGFmdGVyIDMyIGJpdHMuCisgIHt7MHhmMCwgMHhhYiwgMHhjOSwgMHg5YSwgMHhmOCwgMHhiMn0sIDYsIGZhbHNlfSwKKworICAvLyBMb25nZXIgdGhhbiAxMCBieXRlcy4KKyAge3sweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweDAxfSwKKyAgIDExLCBmYWxzZX0sCit9OworCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFZhcmludDMyRXJyb3IsIGtWYXJpbnRFcnJvckNhc2VzLCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5ieXRlcywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5zaXplKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBrVmFyaW50RXJyb3JDYXNlc19jYXNlLnNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICB1aW50MzIgdmFsdWU7CisgIEVYUEVDVF9FUShrVmFyaW50RXJyb3JDYXNlc19jYXNlLmNhbl9wYXJzZSwgY29kZWRfaW5wdXQuUmVhZFZhcmludDMyKCZ2YWx1ZSkpOworfQorCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFZhcmludDY0RXJyb3IsIGtWYXJpbnRFcnJvckNhc2VzLCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5ieXRlcywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5zaXplKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBrVmFyaW50RXJyb3JDYXNlc19jYXNlLnNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICB1aW50NjQgdmFsdWU7CisgIEVYUEVDVF9FUShrVmFyaW50RXJyb3JDYXNlc19jYXNlLmNhbl9wYXJzZSwgY29kZWRfaW5wdXQuUmVhZFZhcmludDY0KCZ2YWx1ZSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBWYXJpbnRTaXplCisKK3N0cnVjdCBWYXJpbnRTaXplQ2FzZSB7CisgIHVpbnQ2NCB2YWx1ZTsKKyAgaW50IHNpemU7Cit9OworCitpbmxpbmUgc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3MsIGNvbnN0IFZhcmludFNpemVDYXNlJiBjKSB7CisgIHJldHVybiBvcyA8PCBjLnZhbHVlOworfQorCitWYXJpbnRTaXplQ2FzZSBrVmFyaW50U2l6ZUNhc2VzW10gPSB7CisgIHswdSwgMX0sCisgIHsxdSwgMX0sCisgIHsxMjd1LCAxfSwKKyAgezEyOHUsIDJ9LAorICB7NzU4OTIzdSwgM30sCisgIHs0MDAwMDAwMDAwdSwgNX0sCisgIHtVTEwoNDEyNTYyMDI1ODA3MTgzMzYpLCA4fSwKKyAge1VMTCgxMTk2NDM3ODMzMDk3ODczNTEzMSksIDEwfSwKK307CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBWYXJpbnRTaXplMzIsIGtWYXJpbnRTaXplQ2FzZXMpIHsKKyAgaWYgKGtWYXJpbnRTaXplQ2FzZXNfY2FzZS52YWx1ZSA+IDB4ZmZmZmZmZmZ1KSB7CisgICAgLy8gU2tpcCA2NC1iaXQgdmFsdWVzLgorICAgIHJldHVybjsKKyAgfQorCisgIEVYUEVDVF9FUShrVmFyaW50U2l6ZUNhc2VzX2Nhc2Uuc2l6ZSwKKyAgICBDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50U2l6ZUNhc2VzX2Nhc2UudmFsdWUpKSk7Cit9CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBWYXJpbnRTaXplNjQsIGtWYXJpbnRTaXplQ2FzZXMpIHsKKyAgRVhQRUNUX0VRKGtWYXJpbnRTaXplQ2FzZXNfY2FzZS5zaXplLAorICAgIENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQoa1ZhcmludFNpemVDYXNlc19jYXNlLnZhbHVlKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEZpeGVkLXNpemUgaW50IHRlc3RzCisKK3N0cnVjdCBGaXhlZDMyQ2FzZSB7CisgIHVpbnQ4IGJ5dGVzW3NpemVvZih1aW50MzIpXTsgICAgICAgICAgLy8gRW5jb2RlZCBieXRlcy4KKyAgdWludDMyIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZWQgdmFsdWUuCit9OworCitzdHJ1Y3QgRml4ZWQ2NENhc2UgeworICB1aW50OCBieXRlc1tzaXplb2YodWludDY0KV07ICAgICAgICAgIC8vIEVuY29kZWQgYnl0ZXMuCisgIHVpbnQ2NCB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2VkIHZhbHVlLgorfTsKKworaW5saW5lIHN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBGaXhlZDMyQ2FzZSYgYykgeworICByZXR1cm4gb3MgPDwgIjB4IiA8PCBzdGQ6OmhleCA8PCBjLnZhbHVlIDw8IHN0ZDo6ZGVjOworfQorCitpbmxpbmUgc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3MsIGNvbnN0IEZpeGVkNjRDYXNlJiBjKSB7CisgIHJldHVybiBvcyA8PCAiMHgiIDw8IHN0ZDo6aGV4IDw8IGMudmFsdWUgPDwgc3RkOjpkZWM7Cit9CisKK0ZpeGVkMzJDYXNlIGtGaXhlZDMyQ2FzZXNbXSA9IHsKKyAge3sweGVmLCAweGNkLCAweGFiLCAweDkwfSwgMHg5MGFiY2RlZnV9LAorICB7ezB4MTIsIDB4MzQsIDB4NTYsIDB4Nzh9LCAweDc4NTYzNDEydX0sCit9OworCitGaXhlZDY0Q2FzZSBrRml4ZWQ2NENhc2VzW10gPSB7CisgIHt7MHhlZiwgMHhjZCwgMHhhYiwgMHg5MCwgMHgxMiwgMHgzNCwgMHg1NiwgMHg3OH0sIFVMTCgweDc4NTYzNDEyOTBhYmNkZWYpfSwKKyAge3sweDExLCAweDIyLCAweDMzLCAweDQ0LCAweDU1LCAweDY2LCAweDc3LCAweDg4fSwgVUxMKDB4ODg3NzY2NTU0NDMzMjIxMSl9LAorfTsKKworVEVTVF8yRChDb2RlZFN0cmVhbVRlc3QsIFJlYWRMaXR0bGVFbmRpYW4zMiwga0ZpeGVkMzJDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtGaXhlZDMyQ2FzZXNfY2FzZS5ieXRlcywgc2l6ZW9mKGtGaXhlZDMyQ2FzZXNfY2FzZS5ieXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHVpbnQzMiB2YWx1ZTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkTGl0dGxlRW5kaWFuMzIoJnZhbHVlKSk7CisgICAgRVhQRUNUX0VRKGtGaXhlZDMyQ2FzZXNfY2FzZS52YWx1ZSwgdmFsdWUpOworICB9CisKKyAgRVhQRUNUX0VRKHNpemVvZih1aW50MzIpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkTGl0dGxlRW5kaWFuNjQsIGtGaXhlZDY0Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrRml4ZWQ2NENhc2VzX2Nhc2UuYnl0ZXMsIHNpemVvZihrRml4ZWQ2NENhc2VzX2Nhc2UuYnl0ZXMpKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICB1aW50NjQgdmFsdWU7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjY0KCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUShrRml4ZWQ2NENhc2VzX2Nhc2UudmFsdWUsIHZhbHVlKTsKKyAgfQorCisgIEVYUEVDVF9FUShzaXplb2YodWludDY0KSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgV3JpdGVMaXR0bGVFbmRpYW4zMiwga0ZpeGVkMzJDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dHB1dCgmb3V0cHV0KTsKKworICAgIGNvZGVkX291dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKGtGaXhlZDMyQ2FzZXNfY2FzZS52YWx1ZSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX291dHB1dC5IYWRFcnJvcigpKTsKKworICAgIEVYUEVDVF9FUShzaXplb2YodWludDMyKSwgY29kZWRfb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgfQorCisgIEVYUEVDVF9FUShzaXplb2YodWludDMyKSwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lbWNtcChidWZmZXJfLCBrRml4ZWQzMkNhc2VzX2Nhc2UuYnl0ZXMsIHNpemVvZih1aW50MzIpKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBXcml0ZUxpdHRsZUVuZGlhbjY0LCBrRml4ZWQ2NENhc2VzLCBrQmxvY2tTaXplcykgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXQpOworCisgICAgY29kZWRfb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuNjQoa0ZpeGVkNjRDYXNlc19jYXNlLnZhbHVlKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfb3V0cHV0LkhhZEVycm9yKCkpOworCisgICAgRVhQRUNUX0VRKHNpemVvZih1aW50NjQpLCBjb2RlZF9vdXRwdXQuQnl0ZUNvdW50KCkpOworICB9CisKKyAgRVhQRUNUX0VRKHNpemVvZih1aW50NjQpLCBvdXRwdXQuQnl0ZUNvdW50KCkpOworICBFWFBFQ1RfRVEoMCwgbWVtY21wKGJ1ZmZlcl8sIGtGaXhlZDY0Q2FzZXNfY2FzZS5ieXRlcywgc2l6ZW9mKHVpbnQ2NCkpKTsKK30KKworLy8gVGVzdHMgdXNpbmcgdGhlIHN0YXRpYyBtZXRob2RzIHRvIHJlYWQgZml4ZWQtc2l6ZSB2YWx1ZXMgZnJvbSByYXcgYXJyYXlzLgorCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgUmVhZExpdHRsZUVuZGlhbjMyRnJvbUFycmF5LCBrRml4ZWQzMkNhc2VzKSB7CisgIG1lbWNweShidWZmZXJfLCBrRml4ZWQzMkNhc2VzX2Nhc2UuYnl0ZXMsIHNpemVvZihrRml4ZWQzMkNhc2VzX2Nhc2UuYnl0ZXMpKTsKKworICB1aW50MzIgdmFsdWU7CisgIGNvbnN0IHVpbnQ4KiBlbmQgPSBDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuMzJGcm9tQXJyYXkoCisgICAgICBidWZmZXJfLCAmdmFsdWUpOworICBFWFBFQ1RfRVEoa0ZpeGVkMzJDYXNlc19jYXNlLnZhbHVlLCB2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGVuZCA9PSBidWZmZXJfICsgc2l6ZW9mKHZhbHVlKSk7Cit9CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXksIGtGaXhlZDY0Q2FzZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtGaXhlZDY0Q2FzZXNfY2FzZS5ieXRlcywgc2l6ZW9mKGtGaXhlZDY0Q2FzZXNfY2FzZS5ieXRlcykpOworCisgIHVpbnQ2NCB2YWx1ZTsKKyAgY29uc3QgdWludDgqIGVuZCA9IENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheSgKKyAgICAgIGJ1ZmZlcl8sICZ2YWx1ZSk7CisgIEVYUEVDVF9FUShrRml4ZWQ2NENhc2VzX2Nhc2UudmFsdWUsIHZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoZW5kID09IGJ1ZmZlcl8gKyBzaXplb2YodmFsdWUpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUmF3IHJlYWRzIGFuZCB3cml0ZXMKKworY29uc3QgY2hhciBrUmF3Qnl0ZXNbXSA9ICJTb21lIGJ5dGVzIHdoaWNoIHdpbGwgYmUgd3JpdHRlbiBhbmQgcmVhZCByYXcuIjsKKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFJlYWRSYXcsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworICBjaGFyIHJlYWRfYnVmZmVyW3NpemVvZihrUmF3Qnl0ZXMpXTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFJhdyhyZWFkX2J1ZmZlciwgc2l6ZW9mKGtSYXdCeXRlcykpKTsKKyAgICBFWFBFQ1RfRVEoMCwgbWVtY21wKGtSYXdCeXRlcywgcmVhZF9idWZmZXIsIHNpemVvZihrUmF3Qnl0ZXMpKSk7CisgIH0KKworICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFdyaXRlUmF3LCBrQmxvY2tTaXplcykgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXQpOworCisgICAgY29kZWRfb3V0cHV0LldyaXRlUmF3KGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9vdXRwdXQuSGFkRXJyb3IoKSk7CisKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIGNvZGVkX291dHB1dC5CeXRlQ291bnQoKSk7CisgIH0KKworICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIG91dHB1dC5CeXRlQ291bnQoKSk7CisgIEVYUEVDVF9FUSgwLCBtZW1jbXAoYnVmZmVyXywga1Jhd0J5dGVzLCBzaXplb2Yoa1Jhd0J5dGVzKSkpOworfQorCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFN0cmluZywga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIEVYUEVDVF9FUShrUmF3Qnl0ZXMsIHN0cik7CisgIH0KKworICBFWFBFQ1RfRVEoc3RybGVuKGtSYXdCeXRlcyksIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworLy8gQ2hlY2sgdG8gbWFrZSBzdXJlIFJlYWRTdHJpbmcgZG9lc24ndCBjcmFzaCBvbiBpbXBvc3NpYmx5IGxhcmdlIHN0cmluZ3MuCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFN0cmluZ0ltcG9zc2libHlMYXJnZSwga0Jsb2NrU2l6ZXMpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICBzdHJpbmcgc3RyOworICAgIC8vIFRyeSB0byByZWFkIGEgZ2lnYWJ5dGUuCisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSA8PCAzMCkpOworICB9Cit9CisKK1RFU1RfRihDb2RlZFN0cmVhbVRlc3QsIFJlYWRTdHJpbmdJbXBvc3NpYmx5TGFyZ2VGcm9tU3RyaW5nT25TdGFjaykgeworICAvLyBTYW1lIHRlc3QgYXMgYWJvdmUsIGV4Y2VwdCBkaXJlY3RseSB1c2UgYSBidWZmZXIuIFRoaXMgdXNlZCB0byBjYXVzZQorICAvLyBjcmFzaGVzIHdoaWxlIHRoZSBhYm92ZSBkaWQgbm90LgorICB1aW50OCBidWZmZXJbOF07CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoYnVmZmVyLCA4KTsKKyAgc3RyaW5nIHN0cjsKKyAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSA8PCAzMCkpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nSW1wb3NzaWJseUxhcmdlRnJvbVN0cmluZ09uSGVhcCkgeworICBzY29wZWRfYXJyYXk8dWludDg+IGJ1ZmZlcihuZXcgdWludDhbOF0pOworICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KGJ1ZmZlci5nZXQoKSwgOCk7CisgIHN0cmluZyBzdHI7CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIDEgPDwgMzApKTsKK30KKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFJlYWRTdHJpbmdSZXNlcnZlc01lbW9yeU9uVG90YWxMaW1pdCwga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgICBjb2RlZF9pbnB1dC5TZXRUb3RhbEJ5dGVzTGltaXQoc2l6ZW9mKGtSYXdCeXRlcyksIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxUb3RhbEJ5dGVzTGltaXQoKSk7CisKKyAgICBzdHJpbmcgc3RyOworICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgc3RybGVuKGtSYXdCeXRlcykpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcykgLSBzdHJsZW4oa1Jhd0J5dGVzKSwKKyAgICAgICAgICAgICAgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKKyAgICBFWFBFQ1RfRVEoa1Jhd0J5dGVzLCBzdHIpOworICAgIC8vIFRPRE8obGl1amlzaSk6IFJlcGxhY2Ugd2l0aCBhIG1vcmUgbWVhbmluZ2Z1bCB0ZXN0IChzZWUgY2wvNjA5NjYwMjMpLgorICAgIEVYUEVDVF9HRShzdHIuY2FwYWNpdHkoKSwgc3RybGVuKGtSYXdCeXRlcykpOworICB9CisKKyAgRVhQRUNUX0VRKHN0cmxlbihrUmF3Qnl0ZXMpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nUmVzZXJ2ZXNNZW1vcnlPblB1c2hlZExpbWl0LCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1Jhd0J5dGVzLCBzaXplb2Yoa1Jhd0J5dGVzKSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlB1c2hMaW1pdChzaXplb2YoYnVmZmVyXykpOworCisgICAgc3RyaW5nIHN0cjsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbihrUmF3Qnl0ZXMpKSk7CisgICAgRVhQRUNUX0VRKGtSYXdCeXRlcywgc3RyKTsKKyAgICAvLyBUT0RPKGxpdWppc2kpOiBSZXBsYWNlIHdpdGggYSBtb3JlIG1lYW5pbmdmdWwgdGVzdCAoc2VlIGNsLzYwOTY2MDIzKS4KKyAgICBFWFBFQ1RfR0Uoc3RyLmNhcGFjaXR5KCksIHN0cmxlbihrUmF3Qnl0ZXMpKTsKKyAgfQorCisgIEVYUEVDVF9FUShzdHJsZW4oa1Jhd0J5dGVzKSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvbklmTGltaXRzTm90U2V0KSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgLy8gQnVmZmVyIHNpemUgaW4gdGhlIGlucHV0IG11c3QgYmUgc21hbGxlciB0aGFuIHNpemVvZihrUmF3Qnl0ZXMpLAorICAvLyBvdGhlcndpc2UgY2hlY2sgYWdhaW5zdCBjYXBhY2l0eSB3aWxsIGZhaWwgYXMgUmVhZFN0cmluZ0lubGluZSgpCisgIC8vIHdpbGwgaGFuZGxlIHRoZSByZWFkaW5nIGFuZCB3aWxsIHJlc2VydmUgdGhlIG1lbW9yeSBhcyBuZWVkZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCAzMik7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIEVYUEVDVF9FUShrUmF3Qnl0ZXMsIHN0cik7CisgICAgLy8gTm90ZTogdGhpcyBjaGVjayBkZXBlbmRzIG9uIHN0cmluZyBjbGFzcyBpbXBsZW1lbnRhdGlvbi4gSXQKKyAgICAvLyBleHBlY3RzIHRoYXQgc3RyaW5nIHdpbGwgYWxsb2NhdGUgbW9yZSB0aGFuIHN0cmxlbihrUmF3Qnl0ZXMpCisgICAgLy8gaWYgdGhlIGNvbnRlbnQgb2Yga1Jhd0J5dGVzIGlzIGFwcGVuZGVkIHRvIHN0cmluZyBpbiBzbWFsbAorICAgIC8vIGNodW5rcy4KKyAgICAvLyBUT0RPKGxpdWppc2kpOiBSZXBsYWNlIHdpdGggYSBtb3JlIG1lYW5pbmdmdWwgdGVzdCAoc2VlIGNsLzYwOTY2MDIzKS4KKyAgICBFWFBFQ1RfR0Uoc3RyLmNhcGFjaXR5KCksIHN0cmxlbihrUmF3Qnl0ZXMpKTsKKyAgfQorCisgIEVYUEVDVF9FUShzdHJsZW4oa1Jhd0J5dGVzKSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc05lZ2F0aXZlKSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgLy8gQnVmZmVyIHNpemUgaW4gdGhlIGlucHV0IG11c3QgYmUgc21hbGxlciB0aGFuIHNpemVvZihrUmF3Qnl0ZXMpLAorICAvLyBvdGhlcndpc2UgY2hlY2sgYWdhaW5zdCBjYXBhY2l0eSB3aWxsIGZhaWwgYXMgUmVhZFN0cmluZ0lubGluZSgpCisgIC8vIHdpbGwgaGFuZGxlIHRoZSByZWFkaW5nIGFuZCB3aWxsIHJlc2VydmUgdGhlIG1lbW9yeSBhcyBuZWVkZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCAzMik7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgICBjb2RlZF9pbnB1dC5QdXNoTGltaXQoc2l6ZW9mKGJ1ZmZlcl8pKTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgLTEpKTsKKyAgICAvLyBOb3RlOiB0aGlzIGNoZWNrIGRlcGVuZHMgb24gc3RyaW5nIGNsYXNzIGltcGxlbWVudGF0aW9uLiBJdAorICAgIC8vIGV4cGVjdHMgdGhhdCBzdHJpbmcgd2lsbCBhbHdheXMgYWxsb2NhdGUgdGhlIHNhbWUgYW1vdW50IG9mCisgICAgLy8gbWVtb3J5IGZvciBhbiBlbXB0eSBzdHJpbmcuCisgICAgRVhQRUNUX0VRKHN0cmluZygpLmNhcGFjaXR5KCksIHN0ci5jYXBhY2l0eSgpKTsKKyAgfQorfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc0xhcmdlKSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgLy8gQnVmZmVyIHNpemUgaW4gdGhlIGlucHV0IG11c3QgYmUgc21hbGxlciB0aGFuIHNpemVvZihrUmF3Qnl0ZXMpLAorICAvLyBvdGhlcndpc2UgY2hlY2sgYWdhaW5zdCBjYXBhY2l0eSB3aWxsIGZhaWwgYXMgUmVhZFN0cmluZ0lubGluZSgpCisgIC8vIHdpbGwgaGFuZGxlIHRoZSByZWFkaW5nIGFuZCB3aWxsIHJlc2VydmUgdGhlIG1lbW9yeSBhcyBuZWVkZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCAzMik7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgICBjb2RlZF9pbnB1dC5QdXNoTGltaXQoc2l6ZW9mKGJ1ZmZlcl8pKTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSA8PCAzMCkpOworICAgIEVYUEVDVF9HVCgxIDw8IDMwLCBzdHIuY2FwYWNpdHkoKSk7CisgIH0KK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgUmVhZFN0cmluZ05vUmVzZXJ2YXRpb25TaXplSXNPdmVyVGhlTGltaXQpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAvLyBCdWZmZXIgc2l6ZSBpbiB0aGUgaW5wdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW4gc2l6ZW9mKGtSYXdCeXRlcyksCisgIC8vIG90aGVyd2lzZSBjaGVjayBhZ2FpbnN0IGNhcGFjaXR5IHdpbGwgZmFpbCBhcyBSZWFkU3RyaW5nSW5saW5lKCkKKyAgLy8gd2lsbCBoYW5kbGUgdGhlIHJlYWRpbmcgYW5kIHdpbGwgcmVzZXJ2ZSB0aGUgbWVtb3J5IGFzIG5lZWRlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDMyKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlB1c2hMaW1pdCgxNik7CisKKyAgICBzdHJpbmcgc3RyOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbihrUmF3Qnl0ZXMpKSk7CisgICAgLy8gTm90ZTogdGhpcyBjaGVjayBkZXBlbmRzIG9uIHN0cmluZyBjbGFzcyBpbXBsZW1lbnRhdGlvbi4gSXQKKyAgICAvLyBleHBlY3RzIHRoYXQgc3RyaW5nIHdpbGwgYWxsb2NhdGUgbGVzcyB0aGFuIHN0cmxlbihrUmF3Qnl0ZXMpCisgICAgLy8gZm9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICBFWFBFQ1RfR1Qoc3RybGVuKGtSYXdCeXRlcyksIHN0ci5jYXBhY2l0eSgpKTsKKyAgfQorfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc092ZXJUaGVUb3RhbEJ5dGVzTGltaXQpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAvLyBCdWZmZXIgc2l6ZSBpbiB0aGUgaW5wdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW4gc2l6ZW9mKGtSYXdCeXRlcyksCisgIC8vIG90aGVyd2lzZSBjaGVjayBhZ2FpbnN0IGNhcGFjaXR5IHdpbGwgZmFpbCBhcyBSZWFkU3RyaW5nSW5saW5lKCkKKyAgLy8gd2lsbCBoYW5kbGUgdGhlIHJlYWRpbmcgYW5kIHdpbGwgcmVzZXJ2ZSB0aGUgbWVtb3J5IGFzIG5lZWRlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDMyKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlNldFRvdGFsQnl0ZXNMaW1pdCgxNiwgMTYpOworCisgICAgc3RyaW5nIHN0cjsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIC8vIE5vdGU6IHRoaXMgY2hlY2sgZGVwZW5kcyBvbiBzdHJpbmcgY2xhc3MgaW1wbGVtZW50YXRpb24uIEl0CisgICAgLy8gZXhwZWN0cyB0aGF0IHN0cmluZyB3aWxsIGFsbG9jYXRlIGxlc3MgdGhhbiBzdHJsZW4oa1Jhd0J5dGVzKQorICAgIC8vIGZvciBhbiBlbXB0eSBzdHJpbmcuCisgICAgRVhQRUNUX0dUKHN0cmxlbihrUmF3Qnl0ZXMpLCBzdHIuY2FwYWNpdHkoKSk7CisgIH0KK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwKKyAgICAgICBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc092ZXJUaGVDbG9zZXN0TGltaXRfR2xvYmFsTGltaXRJc0Nsb3NlcikgeworICBtZW1jcHkoYnVmZmVyXywga1Jhd0J5dGVzLCBzaXplb2Yoa1Jhd0J5dGVzKSk7CisgIC8vIEJ1ZmZlciBzaXplIGluIHRoZSBpbnB1dCBtdXN0IGJlIHNtYWxsZXIgdGhhbiBzaXplb2Yoa1Jhd0J5dGVzKSwKKyAgLy8gb3RoZXJ3aXNlIGNoZWNrIGFnYWluc3QgY2FwYWNpdHkgd2lsbCBmYWlsIGFzIFJlYWRTdHJpbmdJbmxpbmUoKQorICAvLyB3aWxsIGhhbmRsZSB0aGUgcmVhZGluZyBhbmQgd2lsbCByZXNlcnZlIHRoZSBtZW1vcnkgYXMgbmVlZGVkLgorICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwgMzIpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisgICAgY29kZWRfaW5wdXQuUHVzaExpbWl0KHNpemVvZihidWZmZXJfKSk7CisgICAgY29kZWRfaW5wdXQuU2V0VG90YWxCeXRlc0xpbWl0KDE2LCAxNik7CisKKyAgICBzdHJpbmcgc3RyOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbihrUmF3Qnl0ZXMpKSk7CisgICAgLy8gTm90ZTogdGhpcyBjaGVjayBkZXBlbmRzIG9uIHN0cmluZyBjbGFzcyBpbXBsZW1lbnRhdGlvbi4gSXQKKyAgICAvLyBleHBlY3RzIHRoYXQgc3RyaW5nIHdpbGwgYWxsb2NhdGUgbGVzcyB0aGFuIHN0cmxlbihrUmF3Qnl0ZXMpCisgICAgLy8gZm9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICBFWFBFQ1RfR1Qoc3RybGVuKGtSYXdCeXRlcyksIHN0ci5jYXBhY2l0eSgpKTsKKyAgfQorfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LAorICAgICAgIFJlYWRTdHJpbmdOb1Jlc2VydmF0aW9uU2l6ZUlzT3ZlclRoZUNsb3Nlc3RMaW1pdF9Mb2NhbExpbWl0SXNDbG9zZXIpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAvLyBCdWZmZXIgc2l6ZSBpbiB0aGUgaW5wdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW4gc2l6ZW9mKGtSYXdCeXRlcyksCisgIC8vIG90aGVyd2lzZSBjaGVjayBhZ2FpbnN0IGNhcGFjaXR5IHdpbGwgZmFpbCBhcyBSZWFkU3RyaW5nSW5saW5lKCkKKyAgLy8gd2lsbCBoYW5kbGUgdGhlIHJlYWRpbmcgYW5kIHdpbGwgcmVzZXJ2ZSB0aGUgbWVtb3J5IGFzIG5lZWRlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDMyKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlB1c2hMaW1pdCgxNik7CisgICAgY29kZWRfaW5wdXQuU2V0VG90YWxCeXRlc0xpbWl0KHNpemVvZihidWZmZXJfKSwgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGJ1ZmZlcl8pLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCkpOworCisgICAgc3RyaW5nIHN0cjsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIC8vIE5vdGU6IHRoaXMgY2hlY2sgZGVwZW5kcyBvbiBzdHJpbmcgY2xhc3MgaW1wbGVtZW50YXRpb24uIEl0CisgICAgLy8gZXhwZWN0cyB0aGF0IHN0cmluZyB3aWxsIGFsbG9jYXRlIGxlc3MgdGhhbiBzdHJsZW4oa1Jhd0J5dGVzKQorICAgIC8vIGZvciBhbiBlbXB0eSBzdHJpbmcuCisgICAgRVhQRUNUX0dUKHN0cmxlbihrUmF3Qnl0ZXMpLCBzdHIuY2FwYWNpdHkoKSk7CisgIH0KK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTa2lwCisKK2NvbnN0IGNoYXIga1NraXBUZXN0Qnl0ZXNbXSA9CisgICI8QmVmb3JlIHNraXBwaW5nPjxUbyBiZSBza2lwcGVkPjxBZnRlciBza2lwcGluZz4iOworCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgU2tpcElucHV0LCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1NraXBUZXN0Qnl0ZXMsIHNpemVvZihrU2tpcFRlc3RCeXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oIjxCZWZvcmUgc2tpcHBpbmc+IikpKTsKKyAgICBFWFBFQ1RfRVEoIjxCZWZvcmUgc2tpcHBpbmc+Iiwgc3RyKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKHN0cmxlbigiPFRvIGJlIHNraXBwZWQ+IikpKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbigiPEFmdGVyIHNraXBwaW5nPiIpKSk7CisgICAgRVhQRUNUX0VRKCI8QWZ0ZXIgc2tpcHBpbmc+Iiwgc3RyKTsKKyAgfQorCisgIEVYUEVDVF9FUShzdHJsZW4oa1NraXBUZXN0Qnl0ZXMpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEdldERpcmVjdEJ1ZmZlclBvaW50ZXIKKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklucHV0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCA4KTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgIGNvbnN0IHZvaWQqIHB0cjsKKyAgaW50IHNpemU7CisKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXywgcHRyKTsKKyAgRVhQRUNUX0VRKDgsIHNpemUpOworCisgIC8vIFBlZWtpbmcgYWdhaW4gc2hvdWxkIHJldHVybiB0aGUgc2FtZSBwb2ludGVyLgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5HZXREaXJlY3RCdWZmZXJQb2ludGVyKCZwdHIsICZzaXplKSk7CisgIEVYUEVDVF9FUShidWZmZXJfLCBwdHIpOworICBFWFBFQ1RfRVEoOCwgc2l6ZSk7CisKKyAgLy8gU2tpcCBmb3J3YXJkIGluIHRoZSBzYW1lIGJ1ZmZlciB0aGVuIHBlZWsgYWdhaW4uCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlNraXAoMykpOworICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5HZXREaXJlY3RCdWZmZXJQb2ludGVyKCZwdHIsICZzaXplKSk7CisgIEVYUEVDVF9FUShidWZmZXJfICsgMywgcHRyKTsKKyAgRVhQRUNUX0VRKDUsIHNpemUpOworCisgIC8vIFNraXAgdG8gZW5kIG9mIGJ1ZmZlciBhbmQgcGVlayAtLSBzaG91bGQgZ2V0IG5leHQgYnVmZmVyLgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKDUpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDgsIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZUlucHV0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCA4KTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgIGNvbnN0IHZvaWQqIHB0cjsKKyAgaW50IHNpemU7CisKKyAgY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZSgmcHRyLCAmc2l6ZSk7CisgIEVYUEVDVF9FUShidWZmZXJfLCBwdHIpOworICBFWFBFQ1RfRVEoOCwgc2l6ZSk7CisKKyAgLy8gUGVla2luZyBhZ2FpbiBzaG91bGQgcmV0dXJuIHRoZSBzYW1lIHBvaW50ZXIuCisgIGNvZGVkX2lucHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXJJbmxpbmUoJnB0ciwgJnNpemUpOworICBFWFBFQ1RfRVEoYnVmZmVyXywgcHRyKTsKKyAgRVhQRUNUX0VRKDgsIHNpemUpOworCisgIC8vIFNraXAgZm9yd2FyZCBpbiB0aGUgc2FtZSBidWZmZXIgdGhlbiBwZWVrIGFnYWluLgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKDMpKTsKKyAgY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZSgmcHRyLCAmc2l6ZSk7CisgIEVYUEVDVF9FUShidWZmZXJfICsgMywgcHRyKTsKKyAgRVhQRUNUX0VRKDUsIHNpemUpOworCisgIC8vIFNraXAgdG8gZW5kIG9mIGJ1ZmZlciBhbmQgcGVlayAtLSBzaG91bGQgcmV0dXJuIGZhbHNlIGFuZCBwcm92aWRlIGFuIGVtcHR5CisgIC8vIGJ1ZmZlci4gSXQgZG9lcyBub3QgdHJ5IHRvIFJlZnJlc2goKS4KKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuU2tpcCg1KSk7CisgIGNvZGVkX2lucHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXJJbmxpbmUoJnB0ciwgJnNpemUpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDgsIHB0cik7CisgIEVYUEVDVF9FUSgwLCBzaXplKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgR2V0RGlyZWN0QnVmZmVyUG9pbnRlck91dHB1dCkgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCA4KTsKKyAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXQpOworCisgIHZvaWQqIHB0cjsKKyAgaW50IHNpemU7CisKKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoJnB0ciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGJ1ZmZlcl8sIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKKworICAvLyBQZWVraW5nIGFnYWluIHNob3VsZCByZXR1cm4gdGhlIHNhbWUgcG9pbnRlci4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoJnB0ciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGJ1ZmZlcl8sIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKKworICAvLyBTa2lwIGZvcndhcmQgaW4gdGhlIHNhbWUgYnVmZmVyIHRoZW4gcGVlayBhZ2Fpbi4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LlNraXAoMykpOworICBFWFBFQ1RfVFJVRShjb2RlZF9vdXRwdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDMsIHB0cik7CisgIEVYUEVDVF9FUSg1LCBzaXplKTsKKworICAvLyBTa2lwIHRvIGVuZCBvZiBidWZmZXIgYW5kIHBlZWsgLS0gc2hvdWxkIGdldCBuZXh0IGJ1ZmZlci4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LlNraXAoNSkpOworICBFWFBFQ1RfVFJVRShjb2RlZF9vdXRwdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDgsIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKKworICAvLyBTa2lwIG92ZXIgbXVsdGlwbGUgYnVmZmVycy4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LlNraXAoMjIpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoJnB0ciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGJ1ZmZlcl8gKyAzMCwgcHRyKTsKKyAgRVhQRUNUX0VRKDIsIHNpemUpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBMaW1pdHMKKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIEJhc2ljTGltaXQsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoOCk7CisKKyAgICAvLyBSZWFkIHVudGlsIHdlIGhpdCB0aGUgbGltaXQuCisgICAgdWludDMyIHZhbHVlOworICAgIEVYUEVDVF9FUSg4LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSg0LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworCisgICAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQpOworCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICB9CisKKyAgRVhQRUNUX0VRKDEyLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKy8vIFRlc3Qgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcHVzaCB0d28gbGltaXRzIHdoZXJlIHRoZSBzZWNvbmQgKHRvcCkgb25lIGlzCisvLyBzaG9ydGVyLgorVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFNtYWxsTGltaXRPblRvcE9mQmlnTGltaXQsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQxID0gY29kZWRfaW5wdXQuUHVzaExpbWl0KDgpOworICAgIEVYUEVDVF9FUSg4LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQyID0gY29kZWRfaW5wdXQuUHVzaExpbWl0KDQpOworCisgICAgdWludDMyIHZhbHVlOworCisgICAgLy8gUmVhZCB1bnRpbCB3ZSBoaXQgbGltaXQyLCB0aGUgdG9wIGFuZCBzaG9ydGVzdCBsaW1pdC4KKyAgICBFWFBFQ1RfRVEoNCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkTGl0dGxlRW5kaWFuMzIoJnZhbHVlKSk7CisgICAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKworICAgIGNvZGVkX2lucHV0LlBvcExpbWl0KGxpbWl0Mik7CisKKyAgICAvLyBSZWFkIHVudGlsIHdlIGhpdCBsaW1pdDEuCisgICAgRVhQRUNUX0VRKDQsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkTGl0dGxlRW5kaWFuMzIoJnZhbHVlKSk7CisgICAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisKKyAgICBjb2RlZF9pbnB1dC5Qb3BMaW1pdChsaW1pdDEpOworCisgICAgLy8gTm8gbW9yZSBsaW1pdHMuCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICB9CisKKyAgRVhQRUNUX0VRKDEyLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKy8vIFRlc3Qgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcHVzaCB0d28gbGltaXRzIHdoZXJlIHRoZSBzZWNvbmQgKHRvcCkgb25lIGlzCisvLyBsb25nZXIuICBJbiB0aGlzIGNhc2UsIHRoZSB0b3AgbGltaXQgaXMgc2hvcnRlbmVkIHRvIG1hdGNoIHRoZSBwcmV2aW91cworLy8gbGltaXQuCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgQmlnTGltaXRPblRvcE9mU21hbGxMaW1pdCwga0Jsb2NrU2l6ZXMpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICBFWFBFQ1RfRVEoLTEsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdDEgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoNCk7CisgICAgRVhQRUNUX0VRKDQsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdDIgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoOCk7CisKKyAgICB1aW50MzIgdmFsdWU7CisKKyAgICAvLyBSZWFkIHVudGlsIHdlIGhpdCBsaW1pdDIuICBFeGNlcHQsIHdhaXQhICBsaW1pdDEgaXMgc2hvcnRlciwgc28KKyAgICAvLyB3ZSBlbmQgdXAgaGl0dGluZyB0aGF0IGZpcnN0LCBkZXNwaXRlIGhhdmluZyA0IGJ5dGVzIHRvIGdvIG9uCisgICAgLy8gbGltaXQyLgorICAgIEVYUEVDVF9FUSg0LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworCisgICAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQyKTsKKworICAgIC8vIE9LLCBwb3BwZWQgbGltaXQyLCBub3cgbGltaXQxIGlzIG9uIHRvcCwgd2hpY2ggd2UndmUgYWxyZWFkeSBoaXQuCisgICAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisKKyAgICBjb2RlZF9pbnB1dC5Qb3BMaW1pdChsaW1pdDEpOworCisgICAgLy8gTm8gbW9yZSBsaW1pdHMuCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICB9CisKKyAgRVhQRUNUX0VRKDgsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgRXhwZWN0QXRFbmQpIHsKKyAgLy8gVGVzdCBFeHBlY3RBdEVuZCgpLCB3aGljaCBpcyBiYXNlZCBvbiBsaW1pdHMuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5FeHBlY3RBdEVuZCgpKTsKKworICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGNvZGVkX2lucHV0LlB1c2hMaW1pdCg0KTsKKworICB1aW50MzIgdmFsdWU7CisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuRXhwZWN0QXRFbmQoKSk7CisKKyAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQpOworICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuRXhwZWN0QXRFbmQoKSk7Cit9CisKK1RFU1RfRihDb2RlZFN0cmVhbVRlc3QsIE5lZ2F0aXZlTGltaXQpIHsKKyAgLy8gQ2hlY2sgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcHVzaCBhIG5lZ2F0aXZlIGxpbWl0LgorICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGNvZGVkX2lucHV0LlB1c2hMaW1pdCgtMTIzNCk7CisgIC8vIEJ5dGVzVW50aWxMaW1pdCgpIHJldHVybnMgLTEgdG8gbWVhbiAibm8gbGltaXQiLCB3aGljaCBhY3R1YWxseSBtZWFucworICAvLyAidGhlIGxpbWl0IGlzIElOVF9NQVggcmVsYXRpdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyZWFtIi4KKyAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgIGNvZGVkX2lucHV0LlBvcExpbWl0KGxpbWl0KTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgTmVnYXRpdmVMaW1pdEFmdGVyUmVhZGluZykgeworICAvLyBDaGVjayB3aGF0IGhhcHBlbnMgd2hlbiB3ZSBwdXNoIGEgbmVnYXRpdmUgbGltaXQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICBBU1NFUlRfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKDEyOCkpOworCisgIENvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gY29kZWRfaW5wdXQuUHVzaExpbWl0KC02NCk7CisgIC8vIEJ5dGVzVW50aWxMaW1pdCgpIHJldHVybnMgLTEgdG8gbWVhbiAibm8gbGltaXQiLCB3aGljaCBhY3R1YWxseSBtZWFucworICAvLyAidGhlIGxpbWl0IGlzIElOVF9NQVggcmVsYXRpdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyZWFtIi4KKyAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgIGNvZGVkX2lucHV0LlBvcExpbWl0KGxpbWl0KTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgT3ZlcmZsb3dMaW1pdCkgeworICAvLyBDaGVjayB3aGF0IGhhcHBlbnMgd2hlbiB3ZSBwdXNoIGEgbGltaXQgbGFyZ2UgZW5vdWdoIHRoYXQgaXRzIGFic29sdXRlCisgIC8vIHBvc2l0aW9uIGlzIG1vcmUgdGhhbiAyR0IgaW50byB0aGUgc3RyZWFtLgorICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgQVNTRVJUX1RSVUUoY29kZWRfaW5wdXQuU2tpcCgxMjgpKTsKKworICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGNvZGVkX2lucHV0LlB1c2hMaW1pdChJTlRfTUFYKTsKKyAgLy8gQnl0ZXNVbnRpbExpbWl0KCkgcmV0dXJucyAtMSB0byBtZWFuICJubyBsaW1pdCIsIHdoaWNoIGFjdHVhbGx5IG1lYW5zCisgIC8vICJ0aGUgbGltaXQgaXMgSU5UX01BWCByZWxhdGl2ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJlYW0iLgorICBFWFBFQ1RfRVEoLTEsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBUb3RhbEJ5dGVzTGltaXQpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXykpOworICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisgIGNvZGVkX2lucHV0LlNldFRvdGFsQnl0ZXNMaW1pdCgxNiwgLTEpOworICBFWFBFQ1RfRVEoMTYsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxUb3RhbEJ5dGVzTGltaXQoKSk7CisKKyAgc3RyaW5nIHN0cjsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCAxNikpOworICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKKworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBlcnJvcl9sb2c7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSkpOworICAgIGVycm9ycyA9IGVycm9yX2xvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKworICBBU1NFUlRfRVEoMSwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9QUkVEX0ZPUk1BVDIodGVzdGluZzo6SXNTdWJzdHJpbmcsCisgICAgIkEgcHJvdG9jb2wgbWVzc2FnZSB3YXMgcmVqZWN0ZWQgYmVjYXVzZSBpdCB3YXMgdG9vIGJpZyIsIGVycm9yc1swXSk7CisKKyAgY29kZWRfaW5wdXQuU2V0VG90YWxCeXRlc0xpbWl0KDMyLCAtMSk7CisgIEVYUEVDVF9FUSgxNiwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCAxNikpOworICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgVG90YWxCeXRlc0xpbWl0Tm90VmFsaWRNZXNzYWdlRW5kKSB7CisgIC8vIHRvdGFsX2J5dGVzX2xpbWl0XyBpcyBub3QgYSB2YWxpZCBwbGFjZSBmb3IgYSBtZXNzYWdlIHRvIGVuZC4KKworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAvLyBTZXQgYm90aCB0b3RhbF9ieXRlc19saW1pdCBhbmQgYSByZWd1bGFyIGxpbWl0IGF0IDE2IGJ5dGVzLgorICBjb2RlZF9pbnB1dC5TZXRUb3RhbEJ5dGVzTGltaXQoMTYsIC0xKTsKKyAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoMTYpOworCisgIC8vIFJlYWQgMTYgYnl0ZXMuCisgIHN0cmluZyBzdHI7CisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMTYpKTsKKworICAvLyBSZWFkIGEgdGFnLiAgU2hvdWxkIGZhaWwsIGJ1dCByZXBvcnQgYmVpbmcgYSB2YWxpZCBlbmRwb2ludCBzaW5jZSBpdCdzCisgIC8vIGEgcmVndWxhciBsaW1pdC4KKyAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LlJlYWRUYWcoKSk7CisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKKworICAvLyBQb3AgdGhlIGxpbWl0LgorICBjb2RlZF9pbnB1dC5Qb3BMaW1pdChsaW1pdCk7CisKKyAgLy8gUmVhZCBhIHRhZy4gIFNob3VsZCBmYWlsLCBhbmQgcmVwb3J0ICpub3QqIGJlaW5nIGEgdmFsaWQgZW5kcG9pbnQsIHNpbmNlCisgIC8vIHRoaXMgdGltZSB3ZSdyZSBoaXR0aW5nIHRoZSB0b3RhbCBieXRlcyBsaW1pdC4KKyAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LlJlYWRUYWcoKSk7CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKSk7Cit9CisKKy8vIFRoaXMgbWV0aG9kIGlzIHVzZWQgYnkgdGhlIHRlc3RzIGJlbG93LgorLy8gSXQgY29uc3RydWN0cyBhIENvZGVkSW5wdXRTdHJlYW0gd2l0aCB0aGUgZ2l2ZW4gbGltaXRzIGFuZCB0cmllcyB0byByZWFkIDJLaUIKKy8vIG9mIGRhdGEgZnJvbSBpdC4gVGhlbiBpdCByZXR1cm5zIHRoZSBsb2dnZWQgZXJyb3JzIGFuZCB3YXJuaW5ncyBpbiB0aGUgZ2l2ZW4KKy8vIHZlY3RvcnMuCit2b2lkIENvZGVkU3RyZWFtVGVzdDo6U2V0dXBUb3RhbEJ5dGVzTGltaXRXYXJuaW5nVGVzdCgKKyAgICBpbnQgdG90YWxfYnl0ZXNfbGltaXQsIGludCB3YXJuaW5nX3RocmVzaG9sZCwKKyAgICB2ZWN0b3I8c3RyaW5nPiogb3V0X2Vycm9ycywgdmVjdG9yPHN0cmluZz4qIG91dF93YXJuaW5ncykgeworICBBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDEyOCk7CisKKyAgU2NvcGVkTWVtb3J5TG9nIHNjb3BlZF9sb2c7CisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICAgIGlucHV0LlNldFRvdGFsQnl0ZXNMaW1pdCh0b3RhbF9ieXRlc19saW1pdCwgd2FybmluZ190aHJlc2hvbGQpOworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoaW5wdXQuUmVhZFN0cmluZygmc3RyLCAyMDQ4KSk7CisgIH0KKworICAqb3V0X2Vycm9ycyA9IHNjb3BlZF9sb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICAqb3V0X3dhcm5pbmdzID0gc2NvcGVkX2xvZy5HZXRNZXNzYWdlcyhXQVJOSU5HKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgVG90YWxCeXRlc0xpbWl0V2FybmluZykgeworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHZlY3RvcjxzdHJpbmc+IHdhcm5pbmdzOworICBTZXR1cFRvdGFsQnl0ZXNMaW1pdFdhcm5pbmdUZXN0KDEwMjQwLCAxMDI0LCAmZXJyb3JzLCAmd2FybmluZ3MpOworCisgIEVYUEVDVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKworICBBU1NFUlRfRVEoMiwgd2FybmluZ3Muc2l6ZSgpKTsKKyAgRVhQRUNUX1BSRURfRk9STUFUMih0ZXN0aW5nOjpJc1N1YnN0cmluZywKKyAgICAiUmVhZGluZyBkYW5nZXJvdXNseSBsYXJnZSBwcm90b2NvbCBtZXNzYWdlLiAgSWYgdGhlIG1lc3NhZ2UgdHVybnMgb3V0IHRvICIKKyAgICAiYmUgbGFyZ2VyIHRoYW4gMTAyNDAgYnl0ZXMsIHBhcnNpbmcgd2lsbCBiZSBoYWx0ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIiwKKyAgICB3YXJuaW5nc1swXSk7CisgIEVYUEVDVF9QUkVEX0ZPUk1BVDIodGVzdGluZzo6SXNTdWJzdHJpbmcsCisgICAgIlRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCB3YXMgMjA0OCIsCisgICAgd2FybmluZ3NbMV0pOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBUb3RhbEJ5dGVzTGltaXRXYXJuaW5nRGlzYWJsZWQpIHsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB2ZWN0b3I8c3RyaW5nPiB3YXJuaW5nczsKKworICAvLyBUZXN0IHdpdGggLTEKKyAgU2V0dXBUb3RhbEJ5dGVzTGltaXRXYXJuaW5nVGVzdCgxMDI0MCwgLTEsICZlcnJvcnMsICZ3YXJuaW5ncyk7CisgIEVYUEVDVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIHdhcm5pbmdzLnNpemUoKSk7CisKKyAgLy8gVGVzdCBhZ2FpbiB3aXRoIC0yLCBleHBlY3RpbmcgdGhlIHNhbWUgcmVzdWx0CisgIFNldHVwVG90YWxCeXRlc0xpbWl0V2FybmluZ1Rlc3QoMTAyNDAsIC0yLCAmZXJyb3JzLCAmd2FybmluZ3MpOworICBFWFBFQ1RfRVEoMCwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCB3YXJuaW5ncy5zaXplKCkpOworfQorCisKK1RFU1RfRihDb2RlZFN0cmVhbVRlc3QsIFJlY3Vyc2lvbkxpbWl0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICBjb2RlZF9pbnB1dC5TZXRSZWN1cnNpb25MaW1pdCg0KTsKKworICAvLyBUaGlzIGlzIHdheSB0b28gbXVjaCB0ZXN0aW5nIGZvciBhIGNvdW50ZXIuCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgIC8vIDEKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAgLy8gMgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyAzCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgIC8vIDQKKyAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgLy8gNQorICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAvLyA2CisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDUKKyAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgLy8gNgorICBjb2RlZF9pbnB1dC5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOyAgICAgICAgICAgICAgICAgICAvLyA1CisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDQKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gMworICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyA0CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgIC8vIDUKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gNAorICBjb2RlZF9pbnB1dC5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOyAgICAgICAgICAgICAgICAgICAvLyAzCisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDIKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gMQorICBjb2RlZF9pbnB1dC5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOyAgICAgICAgICAgICAgICAgICAvLyAwCisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDAKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gMAorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyAxCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgIC8vIDIKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAgLy8gMworICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyA0CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgIC8vIDUKKworICBjb2RlZF9pbnB1dC5TZXRSZWN1cnNpb25MaW1pdCg2KTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAgLy8gNgorICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAvLyA3Cit9CisKKworY2xhc3MgUmVhbGx5QmlnSW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICBSZWFsbHlCaWdJbnB1dFN0cmVhbSgpIDogYmFja3VwX2Ftb3VudF8oMCksIGJ1ZmZlcl9jb3VudF8oMCkge30KKyAgflJlYWxseUJpZ0lucHV0U3RyZWFtKCkge30KKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5SW5wdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICAgIC8vIFdlIG9ubHkgZXhwZWN0IEJhY2tVcCgpIHRvIGJlIGNhbGxlZCBhdCB0aGUgZW5kLgorICAgIEVYUEVDVF9FUSgwLCBiYWNrdXBfYW1vdW50Xyk7CisKKyAgICBzd2l0Y2ggKGJ1ZmZlcl9jb3VudF8rKykgeworICAgICAgY2FzZSAwOgorICAgICAgICAqZGF0YSA9IGJ1ZmZlcl87CisgICAgICAgICpzaXplID0gc2l6ZW9mKGJ1ZmZlcl8pOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgMToKKyAgICAgICAgLy8gUmV0dXJuIGFuIGVub3Jtb3VzbHkgbGFyZ2UgYnVmZmVyIHRoYXQsIHdoZW4gY29tYmluZWQgd2l0aCB0aGUgMWsKKyAgICAgICAgLy8gcmV0dXJuZWQgYWxyZWFkeSwgc2hvdWxkIG92ZXJmbG93IHRoZSB0b3RhbF9ieXRlc19yZWFkXyBjb3VudGVyIGluCisgICAgICAgIC8vIENvZGVkSW5wdXRTdHJlYW0uICBOb3RlIHRoYXQgd2UnbGwgb25seSByZWFkIHRoZSBmaXJzdCAxMDI0IGJ5dGVzCisgICAgICAgIC8vIG9mIHRoaXMgYnVmZmVyIHNvIGl0J3MgT0sgdGhhdCB3ZSBoYXZlIGl0IHBvaW50IGF0IGJ1ZmZlcl8uCisgICAgICAgICpkYXRhID0gYnVmZmVyXzsKKyAgICAgICAgKnNpemUgPSBJTlRfTUFYOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICB2b2lkIEJhY2tVcChpbnQgY291bnQpIHsKKyAgICBiYWNrdXBfYW1vdW50XyA9IGNvdW50OworICB9CisKKyAgYm9vbCBTa2lwKGludCBjb3VudCkgICAgeyBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm90IGltcGxlbWVudGVkLiI7IHJldHVybiBmYWxzZTsgfQorICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCB7IEdPT0dMRV9MT0coRkFUQUwpIDw8ICJOb3QgaW1wbGVtZW50ZWQuIjsgcmV0dXJuIDA7IH0KKworICBpbnQgYmFja3VwX2Ftb3VudF87CisKKyBwcml2YXRlOgorICBjaGFyIGJ1ZmZlcl9bMTAyNF07CisgIGludDY0IGJ1ZmZlcl9jb3VudF87Cit9OworCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBJbnB1dE92ZXIyRykgeworICAvLyBDb2RlZElucHV0U3RyZWFtIHNob3VsZCBncmFjZWZ1bGx5IGhhbmRsZSBpbnB1dCBvdmVyIDJHIGFuZCBjYWxsCisgIC8vIGlucHV0LkJhY2tVcCgpIHdpdGggdGhlIGNvcnJlY3QgbnVtYmVyIG9mIGJ5dGVzIG9uIGRlc3RydWN0aW9uLgorICBSZWFsbHlCaWdJbnB1dFN0cmVhbSBpbnB1dDsKKworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBlcnJvcl9sb2c7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCA1MTIpKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIDEwMjQpKTsKKyAgICBlcnJvcnMgPSBlcnJvcl9sb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgRVhQRUNUX0VRKElOVF9NQVggLSA1MTIsIGlucHV0LmJhY2t1cF9hbW91bnRfKTsKKyAgRVhQRUNUX0VRKDAsIGVycm9ycy5zaXplKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzlmNGNhNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uY2MKQEAgLTAsMCArMSwzMzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGJyaWFub2xzb25AZ29vZ2xlLmNvbSAoQnJpYW4gT2xzb24pCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBjbGFzc2VzIEd6aXBJbnB1dFN0cmVhbSBhbmQKKy8vIEd6aXBPdXRwdXRTdHJlYW0uCisKKyNpbmNsdWRlICJjb25maWcuaCIKKworI2lmIEhBVkVfWkxJQgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitzdGF0aWMgY29uc3QgaW50IGtEZWZhdWx0QnVmZmVyU2l6ZSA9IDY1NTM2OworCitHemlwSW5wdXRTdHJlYW06Okd6aXBJbnB1dFN0cmVhbSgKKyAgICBaZXJvQ29weUlucHV0U3RyZWFtKiBzdWJfc3RyZWFtLCBGb3JtYXQgZm9ybWF0LCBpbnQgYnVmZmVyX3NpemUpCisgICAgOiBmb3JtYXRfKGZvcm1hdCksIHN1Yl9zdHJlYW1fKHN1Yl9zdHJlYW0pLCB6ZXJyb3JfKFpfT0spLCBieXRlX2NvdW50XygwKSB7CisgIHpjb250ZXh0Xy5zdGF0ZSA9IFpfTlVMTDsKKyAgemNvbnRleHRfLnphbGxvYyA9IFpfTlVMTDsKKyAgemNvbnRleHRfLnpmcmVlID0gWl9OVUxMOworICB6Y29udGV4dF8ub3BhcXVlID0gWl9OVUxMOworICB6Y29udGV4dF8udG90YWxfb3V0ID0gMDsKKyAgemNvbnRleHRfLm5leHRfaW4gPSBOVUxMOworICB6Y29udGV4dF8uYXZhaWxfaW4gPSAwOworICB6Y29udGV4dF8udG90YWxfaW4gPSAwOworICB6Y29udGV4dF8ubXNnID0gTlVMTDsKKyAgaWYgKGJ1ZmZlcl9zaXplID09IC0xKSB7CisgICAgb3V0cHV0X2J1ZmZlcl9sZW5ndGhfID0ga0RlZmF1bHRCdWZmZXJTaXplOworICB9IGVsc2UgeworICAgIG91dHB1dF9idWZmZXJfbGVuZ3RoXyA9IGJ1ZmZlcl9zaXplOworICB9CisgIG91dHB1dF9idWZmZXJfID0gb3BlcmF0b3IgbmV3KG91dHB1dF9idWZmZXJfbGVuZ3RoXyk7CisgIEdPT0dMRV9DSEVDSyhvdXRwdXRfYnVmZmVyXyAhPSBOVUxMKTsKKyAgemNvbnRleHRfLm5leHRfb3V0ID0gc3RhdGljX2Nhc3Q8Qnl0ZWYqPihvdXRwdXRfYnVmZmVyXyk7CisgIHpjb250ZXh0Xy5hdmFpbF9vdXQgPSBvdXRwdXRfYnVmZmVyX2xlbmd0aF87CisgIG91dHB1dF9wb3NpdGlvbl8gPSBvdXRwdXRfYnVmZmVyXzsKK30KK0d6aXBJbnB1dFN0cmVhbTo6fkd6aXBJbnB1dFN0cmVhbSgpIHsKKyAgb3BlcmF0b3IgZGVsZXRlKG91dHB1dF9idWZmZXJfKTsKKyAgemVycm9yXyA9IGluZmxhdGVFbmQoJnpjb250ZXh0Xyk7Cit9CisKK3N0YXRpYyBpbmxpbmUgaW50IGludGVybmFsSW5mbGF0ZUluaXQyKAorICAgIHpfc3RyZWFtKiB6Y29udGV4dCwgR3ppcElucHV0U3RyZWFtOjpGb3JtYXQgZm9ybWF0KSB7CisgIGludCB3aW5kb3dCaXRzRm9ybWF0ID0gMDsKKyAgc3dpdGNoIChmb3JtYXQpIHsKKyAgICBjYXNlIEd6aXBJbnB1dFN0cmVhbTo6R1pJUDogd2luZG93Qml0c0Zvcm1hdCA9IDE2OyBicmVhazsKKyAgICBjYXNlIEd6aXBJbnB1dFN0cmVhbTo6QVVUTzogd2luZG93Qml0c0Zvcm1hdCA9IDMyOyBicmVhazsKKyAgICBjYXNlIEd6aXBJbnB1dFN0cmVhbTo6WkxJQjogd2luZG93Qml0c0Zvcm1hdCA9IDA7IGJyZWFrOworICB9CisgIHJldHVybiBpbmZsYXRlSW5pdDIoemNvbnRleHQsIC8qIHdpbmRvd0JpdHMgKi8xNSB8IHdpbmRvd0JpdHNGb3JtYXQpOworfQorCitpbnQgR3ppcElucHV0U3RyZWFtOjpJbmZsYXRlKGludCBmbHVzaCkgeworICBpZiAoKHplcnJvcl8gPT0gWl9PSykgJiYgKHpjb250ZXh0Xy5hdmFpbF9vdXQgPT0gMCkpIHsKKyAgICAvLyBwcmV2aW91cyBpbmZsYXRlIGZpbGxlZCBvdXRwdXQgYnVmZmVyLiBkb24ndCBjaGFuZ2UgaW5wdXQgcGFyYW1zIHlldC4KKyAgfSBlbHNlIGlmICh6Y29udGV4dF8uYXZhaWxfaW4gPT0gMCkgeworICAgIGNvbnN0IHZvaWQqIGluOworICAgIGludCBpbl9zaXplOworICAgIGJvb2wgZmlyc3QgPSB6Y29udGV4dF8ubmV4dF9pbiA9PSBOVUxMOworICAgIGJvb2wgb2sgPSBzdWJfc3RyZWFtXy0+TmV4dCgmaW4sICZpbl9zaXplKTsKKyAgICBpZiAoIW9rKSB7CisgICAgICB6Y29udGV4dF8ubmV4dF9vdXQgPSBOVUxMOworICAgICAgemNvbnRleHRfLmF2YWlsX291dCA9IDA7CisgICAgICByZXR1cm4gWl9TVFJFQU1fRU5EOworICAgIH0KKyAgICB6Y29udGV4dF8ubmV4dF9pbiA9IHN0YXRpY19jYXN0PEJ5dGVmKj4oY29uc3RfY2FzdDx2b2lkKj4oaW4pKTsKKyAgICB6Y29udGV4dF8uYXZhaWxfaW4gPSBpbl9zaXplOworICAgIGlmIChmaXJzdCkgeworICAgICAgaW50IGVycm9yID0gaW50ZXJuYWxJbmZsYXRlSW5pdDIoJnpjb250ZXh0XywgZm9ybWF0Xyk7CisgICAgICBpZiAoZXJyb3IgIT0gWl9PSykgeworICAgICAgICByZXR1cm4gZXJyb3I7CisgICAgICB9CisgICAgfQorICB9CisgIHpjb250ZXh0Xy5uZXh0X291dCA9IHN0YXRpY19jYXN0PEJ5dGVmKj4ob3V0cHV0X2J1ZmZlcl8pOworICB6Y29udGV4dF8uYXZhaWxfb3V0ID0gb3V0cHV0X2J1ZmZlcl9sZW5ndGhfOworICBvdXRwdXRfcG9zaXRpb25fID0gb3V0cHV0X2J1ZmZlcl87CisgIGludCBlcnJvciA9IGluZmxhdGUoJnpjb250ZXh0XywgZmx1c2gpOworICByZXR1cm4gZXJyb3I7Cit9CisKK3ZvaWQgR3ppcElucHV0U3RyZWFtOjpEb05leHRPdXRwdXQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICAqZGF0YSA9IG91dHB1dF9wb3NpdGlvbl87CisgICpzaXplID0gKCh1aW50cHRyX3QpemNvbnRleHRfLm5leHRfb3V0KSAtICgodWludHB0cl90KW91dHB1dF9wb3NpdGlvbl8pOworICBvdXRwdXRfcG9zaXRpb25fID0gemNvbnRleHRfLm5leHRfb3V0OworfQorCisvLyBpbXBsZW1lbnRzIFplcm9Db3B5SW5wdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorYm9vbCBHemlwSW5wdXRTdHJlYW06Ok5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICBib29sIG9rID0gKHplcnJvcl8gPT0gWl9PSykgfHwgKHplcnJvcl8gPT0gWl9TVFJFQU1fRU5EKQorICAgICAgfHwgKHplcnJvcl8gPT0gWl9CVUZfRVJST1IpOworICBpZiAoKCFvaykgfHwgKHpjb250ZXh0Xy5uZXh0X291dCA9PSBOVUxMKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoemNvbnRleHRfLm5leHRfb3V0ICE9IG91dHB1dF9wb3NpdGlvbl8pIHsKKyAgICBEb05leHRPdXRwdXQoZGF0YSwgc2l6ZSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgaWYgKHplcnJvcl8gPT0gWl9TVFJFQU1fRU5EKSB7CisgICAgaWYgKHpjb250ZXh0Xy5uZXh0X291dCAhPSBOVUxMKSB7CisgICAgICAvLyBzdWJfc3RyZWFtXyBtYXkgaGF2ZSBjb25jYXRlbmF0ZWQgc3RyZWFtcyB0byBmb2xsb3cKKyAgICAgIHplcnJvcl8gPSBpbmZsYXRlRW5kKCZ6Y29udGV4dF8pOworICAgICAgYnl0ZV9jb3VudF8gKz0gemNvbnRleHRfLnRvdGFsX291dDsKKyAgICAgIGlmICh6ZXJyb3JfICE9IFpfT0spIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgemVycm9yXyA9IGludGVybmFsSW5mbGF0ZUluaXQyKCZ6Y29udGV4dF8sIGZvcm1hdF8pOworICAgICAgaWYgKHplcnJvcl8gIT0gWl9PSykgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICpkYXRhID0gTlVMTDsKKyAgICAgICpzaXplID0gMDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgemVycm9yXyA9IEluZmxhdGUoWl9OT19GTFVTSCk7CisgIGlmICgoemVycm9yXyA9PSBaX1NUUkVBTV9FTkQpICYmICh6Y29udGV4dF8ubmV4dF9vdXQgPT0gTlVMTCkpIHsKKyAgICAvLyBUaGUgdW5kZXJseWluZyBzdHJlYW0ncyBOZXh0IHJldHVybmVkIGZhbHNlIGluc2lkZSBJbmZsYXRlLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBvayA9ICh6ZXJyb3JfID09IFpfT0spIHx8ICh6ZXJyb3JfID09IFpfU1RSRUFNX0VORCkKKyAgICAgIHx8ICh6ZXJyb3JfID09IFpfQlVGX0VSUk9SKTsKKyAgaWYgKCFvaykgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBEb05leHRPdXRwdXQoZGF0YSwgc2l6ZSk7CisgIHJldHVybiB0cnVlOworfQordm9pZCBHemlwSW5wdXRTdHJlYW06OkJhY2tVcChpbnQgY291bnQpIHsKKyAgb3V0cHV0X3Bvc2l0aW9uXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KG91dHB1dF9wb3NpdGlvbl8pIC0gY291bnQpOworfQorYm9vbCBHemlwSW5wdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIGNvbnN0IHZvaWQqIGRhdGE7CisgIGludCBzaXplOworICBib29sIG9rID0gTmV4dCgmZGF0YSwgJnNpemUpOworICB3aGlsZSAob2sgJiYgKHNpemUgPCBjb3VudCkpIHsKKyAgICBjb3VudCAtPSBzaXplOworICAgIG9rID0gTmV4dCgmZGF0YSwgJnNpemUpOworICB9CisgIGlmIChzaXplID4gY291bnQpIHsKKyAgICBCYWNrVXAoc2l6ZSAtIGNvdW50KTsKKyAgfQorICByZXR1cm4gb2s7Cit9CitpbnQ2NCBHemlwSW5wdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgaW50NjQgcmV0ID0gYnl0ZV9jb3VudF8gKyB6Y29udGV4dF8udG90YWxfb3V0OworICBpZiAoemNvbnRleHRfLm5leHRfb3V0ICE9IE5VTEwgJiYgb3V0cHV0X3Bvc2l0aW9uXyAhPSBOVUxMKSB7CisgICAgcmV0ICs9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90Pih6Y29udGV4dF8ubmV4dF9vdXQpIC0KKyAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KG91dHB1dF9wb3NpdGlvbl8pOworICB9CisgIHJldHVybiByZXQ7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9uczo6T3B0aW9ucygpCisgICAgOiBmb3JtYXQoR1pJUCksCisgICAgICBidWZmZXJfc2l6ZShrRGVmYXVsdEJ1ZmZlclNpemUpLAorICAgICAgY29tcHJlc3Npb25fbGV2ZWwoWl9ERUZBVUxUX0NPTVBSRVNTSU9OKSwKKyAgICAgIGNvbXByZXNzaW9uX3N0cmF0ZWd5KFpfREVGQVVMVF9TVFJBVEVHWSkge30KKworR3ppcE91dHB1dFN0cmVhbTo6R3ppcE91dHB1dFN0cmVhbShaZXJvQ29weU91dHB1dFN0cmVhbSogc3ViX3N0cmVhbSkgeworICBJbml0KHN1Yl9zdHJlYW0sIE9wdGlvbnMoKSk7Cit9CisKK0d6aXBPdXRwdXRTdHJlYW06Okd6aXBPdXRwdXRTdHJlYW0oWmVyb0NvcHlPdXRwdXRTdHJlYW0qIHN1Yl9zdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpIHsKKyAgSW5pdChzdWJfc3RyZWFtLCBvcHRpb25zKTsKK30KKwordm9pZCBHemlwT3V0cHV0U3RyZWFtOjpJbml0KFplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdWJfc3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpIHsKKyAgc3ViX3N0cmVhbV8gPSBzdWJfc3RyZWFtOworICBzdWJfZGF0YV8gPSBOVUxMOworICBzdWJfZGF0YV9zaXplXyA9IDA7CisKKyAgaW5wdXRfYnVmZmVyX2xlbmd0aF8gPSBvcHRpb25zLmJ1ZmZlcl9zaXplOworICBpbnB1dF9idWZmZXJfID0gb3BlcmF0b3IgbmV3KGlucHV0X2J1ZmZlcl9sZW5ndGhfKTsKKyAgR09PR0xFX0NIRUNLKGlucHV0X2J1ZmZlcl8gIT0gTlVMTCk7CisKKyAgemNvbnRleHRfLnphbGxvYyA9IFpfTlVMTDsKKyAgemNvbnRleHRfLnpmcmVlID0gWl9OVUxMOworICB6Y29udGV4dF8ub3BhcXVlID0gWl9OVUxMOworICB6Y29udGV4dF8ubmV4dF9vdXQgPSBOVUxMOworICB6Y29udGV4dF8uYXZhaWxfb3V0ID0gMDsKKyAgemNvbnRleHRfLnRvdGFsX291dCA9IDA7CisgIHpjb250ZXh0Xy5uZXh0X2luID0gTlVMTDsKKyAgemNvbnRleHRfLmF2YWlsX2luID0gMDsKKyAgemNvbnRleHRfLnRvdGFsX2luID0gMDsKKyAgemNvbnRleHRfLm1zZyA9IE5VTEw7CisgIC8vIGRlZmF1bHQgdG8gR1pJUCBmb3JtYXQKKyAgaW50IHdpbmRvd0JpdHNGb3JtYXQgPSAxNjsKKyAgaWYgKG9wdGlvbnMuZm9ybWF0ID09IFpMSUIpIHsKKyAgICB3aW5kb3dCaXRzRm9ybWF0ID0gMDsKKyAgfQorICB6ZXJyb3JfID0gZGVmbGF0ZUluaXQyKAorICAgICAgJnpjb250ZXh0XywKKyAgICAgIG9wdGlvbnMuY29tcHJlc3Npb25fbGV2ZWwsCisgICAgICBaX0RFRkxBVEVELAorICAgICAgLyogd2luZG93Qml0cyAqLzE1IHwgd2luZG93Qml0c0Zvcm1hdCwKKyAgICAgIC8qIG1lbUxldmVsIChkZWZhdWx0KSAqLzgsCisgICAgICBvcHRpb25zLmNvbXByZXNzaW9uX3N0cmF0ZWd5KTsKK30KKworR3ppcE91dHB1dFN0cmVhbTo6fkd6aXBPdXRwdXRTdHJlYW0oKSB7CisgIENsb3NlKCk7CisgIGlmIChpbnB1dF9idWZmZXJfICE9IE5VTEwpIHsKKyAgICBvcGVyYXRvciBkZWxldGUoaW5wdXRfYnVmZmVyXyk7CisgIH0KK30KKworLy8gcHJpdmF0ZQoraW50IEd6aXBPdXRwdXRTdHJlYW06OkRlZmxhdGUoaW50IGZsdXNoKSB7CisgIGludCBlcnJvciA9IFpfT0s7CisgIGRvIHsKKyAgICBpZiAoKHN1Yl9kYXRhXyA9PSBOVUxMKSB8fCAoemNvbnRleHRfLmF2YWlsX291dCA9PSAwKSkgeworICAgICAgYm9vbCBvayA9IHN1Yl9zdHJlYW1fLT5OZXh0KCZzdWJfZGF0YV8sICZzdWJfZGF0YV9zaXplXyk7CisgICAgICBpZiAoIW9rKSB7CisgICAgICAgIHN1Yl9kYXRhXyA9IE5VTEw7CisgICAgICAgIHN1Yl9kYXRhX3NpemVfID0gMDsKKyAgICAgICAgcmV0dXJuIFpfQlVGX0VSUk9SOworICAgICAgfQorICAgICAgR09PR0xFX0NIRUNLX0dUKHN1Yl9kYXRhX3NpemVfLCAwKTsKKyAgICAgIHpjb250ZXh0Xy5uZXh0X291dCA9IHN0YXRpY19jYXN0PEJ5dGVmKj4oc3ViX2RhdGFfKTsKKyAgICAgIHpjb250ZXh0Xy5hdmFpbF9vdXQgPSBzdWJfZGF0YV9zaXplXzsKKyAgICB9CisgICAgZXJyb3IgPSBkZWZsYXRlKCZ6Y29udGV4dF8sIGZsdXNoKTsKKyAgfSB3aGlsZSAoZXJyb3IgPT0gWl9PSyAmJiB6Y29udGV4dF8uYXZhaWxfb3V0ID09IDApOworICBpZiAoKGZsdXNoID09IFpfRlVMTF9GTFVTSCkgfHwgKGZsdXNoID09IFpfRklOSVNIKSkgeworICAgIC8vIE5vdGlmeSBsb3dlciBsYXllciBvZiBkYXRhLgorICAgIHN1Yl9zdHJlYW1fLT5CYWNrVXAoemNvbnRleHRfLmF2YWlsX291dCk7CisgICAgLy8gV2UgZG9uJ3Qgb3duIHRoZSBidWZmZXIgYW55bW9yZS4KKyAgICBzdWJfZGF0YV8gPSBOVUxMOworICAgIHN1Yl9kYXRhX3NpemVfID0gMDsKKyAgfQorICByZXR1cm4gZXJyb3I7Cit9CisKKy8vIGltcGxlbWVudHMgWmVyb0NvcHlPdXRwdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitib29sIEd6aXBPdXRwdXRTdHJlYW06Ok5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICBpZiAoKHplcnJvcl8gIT0gWl9PSykgJiYgKHplcnJvcl8gIT0gWl9CVUZfRVJST1IpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmICh6Y29udGV4dF8uYXZhaWxfaW4gIT0gMCkgeworICAgIHplcnJvcl8gPSBEZWZsYXRlKFpfTk9fRkxVU0gpOworICAgIGlmICh6ZXJyb3JfICE9IFpfT0spIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgaWYgKHpjb250ZXh0Xy5hdmFpbF9pbiA9PSAwKSB7CisgICAgLy8gYWxsIGlucHV0IHdhcyBjb25zdW1lZC4gcmVzZXQgdGhlIGJ1ZmZlci4KKyAgICB6Y29udGV4dF8ubmV4dF9pbiA9IHN0YXRpY19jYXN0PEJ5dGVmKj4oaW5wdXRfYnVmZmVyXyk7CisgICAgemNvbnRleHRfLmF2YWlsX2luID0gaW5wdXRfYnVmZmVyX2xlbmd0aF87CisgICAgKmRhdGEgPSBpbnB1dF9idWZmZXJfOworICAgICpzaXplID0gaW5wdXRfYnVmZmVyX2xlbmd0aF87CisgIH0gZWxzZSB7CisgICAgLy8gVGhlIGxvb3AgaW4gRGVmbGF0ZSBzaG91bGQgY29uc3VtZSBhbGwgYXZhaWxfaW4KKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkRlZmxhdGUgbGVmdCBieXRlcyB1bmNvbnN1bWVkIjsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KK3ZvaWQgR3ppcE91dHB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR0UoemNvbnRleHRfLmF2YWlsX2luLCBjb3VudCk7CisgIHpjb250ZXh0Xy5hdmFpbF9pbiAtPSBjb3VudDsKK30KK2ludDY0IEd6aXBPdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHpjb250ZXh0Xy50b3RhbF9pbiArIHpjb250ZXh0Xy5hdmFpbF9pbjsKK30KKworYm9vbCBHemlwT3V0cHV0U3RyZWFtOjpGbHVzaCgpIHsKKyAgemVycm9yXyA9IERlZmxhdGUoWl9GVUxMX0ZMVVNIKTsKKyAgLy8gUmV0dXJuIHRydWUgaWYgdGhlIGZsdXNoIHN1Y2NlZWRlZCBvciBpZiBpdCB3YXMgYSBuby1vcC4KKyAgcmV0dXJuICAoemVycm9yXyA9PSBaX09LKSB8fAorICAgICAgKHplcnJvcl8gPT0gWl9CVUZfRVJST1IgJiYgemNvbnRleHRfLmF2YWlsX2luID09IDAgJiYKKyAgICAgICB6Y29udGV4dF8uYXZhaWxfb3V0ICE9IDApOworfQorCitib29sIEd6aXBPdXRwdXRTdHJlYW06OkNsb3NlKCkgeworICBpZiAoKHplcnJvcl8gIT0gWl9PSykgJiYgKHplcnJvcl8gIT0gWl9CVUZfRVJST1IpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGRvIHsKKyAgICB6ZXJyb3JfID0gRGVmbGF0ZShaX0ZJTklTSCk7CisgIH0gd2hpbGUgKHplcnJvcl8gPT0gWl9PSyk7CisgIHplcnJvcl8gPSBkZWZsYXRlRW5kKCZ6Y29udGV4dF8pOworICBib29sIG9rID0gemVycm9yXyA9PSBaX09LOworICB6ZXJyb3JfID0gWl9TVFJFQU1fRU5EOworICByZXR1cm4gb2s7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gSEFWRV9aTElCCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODI0NDUwMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaApAQCAtMCwwICsxLDIxMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYnJpYW5vbHNvbkBnb29nbGUuY29tIChCcmlhbiBPbHNvbikKKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgdGhlIGRlZmluaXRpb24gZm9yIGNsYXNzZXMgR3ppcElucHV0U3RyZWFtIGFuZAorLy8gR3ppcE91dHB1dFN0cmVhbS4KKy8vCisvLyBHemlwSW5wdXRTdHJlYW0gZGVjb21wcmVzc2VzIGRhdGEgZnJvbSBhbiB1bmRlcmx5aW5nCisvLyBaZXJvQ29weUlucHV0U3RyZWFtIGFuZCBwcm92aWRlcyB0aGUgZGVjb21wcmVzc2VkIGRhdGEgYXMgYQorLy8gWmVyb0NvcHlJbnB1dFN0cmVhbS4KKy8vCisvLyBHemlwT3V0cHV0U3RyZWFtIGlzIGFuIFplcm9Db3B5T3V0cHV0U3RyZWFtIHRoYXQgY29tcHJlc3NlcyBkYXRhIHRvCisvLyBhbiB1bmRlcmx5aW5nIFplcm9Db3B5T3V0cHV0U3RyZWFtLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19HWklQX1NUUkVBTV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0lPX0daSVBfU1RSRUFNX0hfXworCisjaW5jbHVkZSA8emxpYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKKy8vIEEgWmVyb0NvcHlJbnB1dFN0cmVhbSB0aGF0IHJlYWRzIGNvbXByZXNzZWQgZGF0YSB0aHJvdWdoIHpsaWIKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBHemlwSW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBGb3JtYXQga2V5IGZvciBjb25zdHJ1Y3RvcgorICBlbnVtIEZvcm1hdCB7CisgICAgLy8gemxpYiB3aWxsIGF1dG9kZXRlY3QgZ3ppcCBoZWFkZXIgb3IgZGVmbGF0ZSBzdHJlYW0KKyAgICBBVVRPID0gMCwKKworICAgIC8vIEdaSVAgc3RyZWFtcyBoYXZlIHNvbWUgZXh0cmEgaGVhZGVyIGRhdGEgZm9yIGZpbGUgYXR0cmlidXRlcy4KKyAgICBHWklQID0gMSwKKworICAgIC8vIFNpbXBsZXIgemxpYiBzdHJlYW0gZm9ybWF0LgorICAgIFpMSUIgPSAyLAorICB9OworCisgIC8vIGJ1ZmZlcl9zaXplIGFuZCBmb3JtYXQgbWF5IGJlIC0xIGZvciBkZWZhdWx0IG9mIDY0a0IgYW5kIEdaSVAgZm9ybWF0CisgIGV4cGxpY2l0IEd6aXBJbnB1dFN0cmVhbSgKKyAgICAgIFplcm9Db3B5SW5wdXRTdHJlYW0qIHN1Yl9zdHJlYW0sCisgICAgICBGb3JtYXQgZm9ybWF0ID0gQVVUTywKKyAgICAgIGludCBidWZmZXJfc2l6ZSA9IC0xKTsKKyAgdmlydHVhbCB+R3ppcElucHV0U3RyZWFtKCk7CisKKyAgLy8gUmV0dXJuIGxhc3QgZXJyb3IgbWVzc2FnZSBvciBOVUxMIGlmIG5vIGVycm9yLgorICBpbmxpbmUgY29uc3QgY2hhciogWmxpYkVycm9yTWVzc2FnZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gemNvbnRleHRfLm1zZzsKKyAgfQorICBpbmxpbmUgaW50IFpsaWJFcnJvckNvZGUoKSBjb25zdCB7CisgICAgcmV0dXJuIHplcnJvcl87CisgIH0KKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5SW5wdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGJvb2wgU2tpcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIEZvcm1hdCBmb3JtYXRfOworCisgIFplcm9Db3B5SW5wdXRTdHJlYW0qIHN1Yl9zdHJlYW1fOworCisgIHpfc3RyZWFtIHpjb250ZXh0XzsKKyAgaW50IHplcnJvcl87CisKKyAgdm9pZCogb3V0cHV0X2J1ZmZlcl87CisgIHZvaWQqIG91dHB1dF9wb3NpdGlvbl87CisgIHNpemVfdCBvdXRwdXRfYnVmZmVyX2xlbmd0aF87CisgIGludDY0IGJ5dGVfY291bnRfOworCisgIGludCBJbmZsYXRlKGludCBmbHVzaCk7CisgIHZvaWQgRG9OZXh0T3V0cHV0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhHemlwSW5wdXRTdHJlYW0pOworfTsKKworCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgR3ppcE91dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBGb3JtYXQga2V5IGZvciBjb25zdHJ1Y3RvcgorICBlbnVtIEZvcm1hdCB7CisgICAgLy8gR1pJUCBzdHJlYW1zIGhhdmUgc29tZSBleHRyYSBoZWFkZXIgZGF0YSBmb3IgZmlsZSBhdHRyaWJ1dGVzLgorICAgIEdaSVAgPSAxLAorCisgICAgLy8gU2ltcGxlciB6bGliIHN0cmVhbSBmb3JtYXQuCisgICAgWkxJQiA9IDIsCisgIH07CisKKyAgc3RydWN0IE9wdGlvbnMgeworICAgIC8vIERlZmF1bHRzIHRvIEdaSVAuCisgICAgRm9ybWF0IGZvcm1hdDsKKworICAgIC8vIFdoYXQgc2l6ZSBidWZmZXIgdG8gdXNlIGludGVybmFsbHkuICBEZWZhdWx0cyB0byA2NGtCLgorICAgIGludCBidWZmZXJfc2l6ZTsKKworICAgIC8vIEEgbnVtYmVyIGJldHdlZW4gMCBhbmQgOSwgd2hlcmUgMCBpcyBubyBjb21wcmVzc2lvbiBhbmQgOSBpcyBiZXN0CisgICAgLy8gY29tcHJlc3Npb24uICBEZWZhdWx0cyB0byBaX0RFRkFVTFRfQ09NUFJFU1NJT04gKHNlZSB6bGliLmgpLgorICAgIGludCBjb21wcmVzc2lvbl9sZXZlbDsKKworICAgIC8vIERlZmF1bHRzIHRvIFpfREVGQVVMVF9TVFJBVEVHWS4gIENhbiBhbHNvIGJlIHNldCB0byBaX0ZJTFRFUkVELAorICAgIC8vIFpfSFVGRk1BTl9PTkxZLCBvciBaX1JMRS4gIFNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgZGVmbGF0ZUluaXQyIGluCisgICAgLy8gemxpYi5oIGZvciBkZWZpbml0aW9ucyBvZiB0aGVzZSBjb25zdGFudHMuCisgICAgaW50IGNvbXByZXNzaW9uX3N0cmF0ZWd5OworCisgICAgT3B0aW9ucygpOyAgLy8gSW5pdGlhbGl6ZXMgd2l0aCBkZWZhdWx0IHZhbHVlcy4KKyAgfTsKKworICAvLyBDcmVhdGUgYSBHemlwT3V0cHV0U3RyZWFtIHdpdGggZGVmYXVsdCBvcHRpb25zLgorICBleHBsaWNpdCBHemlwT3V0cHV0U3RyZWFtKFplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdWJfc3RyZWFtKTsKKworICAvLyBDcmVhdGUgYSBHemlwT3V0cHV0U3RyZWFtIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuCisgIEd6aXBPdXRwdXRTdHJlYW0oCisgICAgICBaZXJvQ29weU91dHB1dFN0cmVhbSogc3ViX3N0cmVhbSwKKyAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworCisgIHZpcnR1YWwgfkd6aXBPdXRwdXRTdHJlYW0oKTsKKworICAvLyBSZXR1cm4gbGFzdCBlcnJvciBtZXNzYWdlIG9yIE5VTEwgaWYgbm8gZXJyb3IuCisgIGlubGluZSBjb25zdCBjaGFyKiBabGliRXJyb3JNZXNzYWdlKCkgY29uc3QgeworICAgIHJldHVybiB6Y29udGV4dF8ubXNnOworICB9CisgIGlubGluZSBpbnQgWmxpYkVycm9yQ29kZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gemVycm9yXzsKKyAgfQorCisgIC8vIEZsdXNoZXMgZGF0YSB3cml0dGVuIHNvIGZhciB0byB6aXBwZWQgZGF0YSBpbiB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgIC8vIEl0IGlzIHRoZSBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBmbHVzaCB0aGUgdW5kZXJseWluZyBzdHJlYW0gaWYKKyAgLy8gbmVjZXNzYXJ5LgorICAvLyBDb21wcmVzc2lvbiBtYXkgYmUgbGVzcyBlZmZpY2llbnQgc3RvcHBpbmcgYW5kIHN0YXJ0aW5nIGFyb3VuZCBmbHVzaGVzLgorICAvLyBSZXR1cm5zIHRydWUgaWYgbm8gZXJyb3IuCisgIC8vCisgIC8vIFBsZWFzZSBlbnN1cmUgdGhhdCBibG9jayBzaXplIGlzID4gNi4gSGVyZSBpcyBhbiBleGNlcnB0IGZyb20gdGhlIHpsaWIKKyAgLy8gZG9jIHRoYXQgZXhwbGFpbnMgd2h5OgorICAvLworICAvLyBJbiB0aGUgY2FzZSBvZiBhIFpfRlVMTF9GTFVTSCBvciBaX1NZTkNfRkxVU0gsIG1ha2Ugc3VyZSB0aGF0IGF2YWlsX291dAorICAvLyBpcyBncmVhdGVyIHRoYW4gc2l4IHRvIGF2b2lkIHJlcGVhdGVkIGZsdXNoIG1hcmtlcnMgZHVlIHRvCisgIC8vIGF2YWlsX291dCA9PSAwIG9uIHJldHVybi4KKyAgYm9vbCBGbHVzaCgpOworCisgIC8vIFdyaXRlcyBvdXQgYWxsIGRhdGEgYW5kIGNsb3NlcyB0aGUgZ3ppcCBzdHJlYW0uCisgIC8vIEl0IGlzIHRoZSBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBjbG9zZSB0aGUgdW5kZXJseWluZyBzdHJlYW0gaWYKKyAgLy8gbmVjZXNzYXJ5LgorICAvLyBSZXR1cm5zIHRydWUgaWYgbm8gZXJyb3IuCisgIGJvb2wgQ2xvc2UoKTsKKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5T3V0cHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgWmVyb0NvcHlPdXRwdXRTdHJlYW0qIHN1Yl9zdHJlYW1fOworICAvLyBSZXN1bHQgZnJvbSBjYWxsaW5nIE5leHQoKSBvbiBzdWJfc3RyZWFtXworICB2b2lkKiBzdWJfZGF0YV87CisgIGludCBzdWJfZGF0YV9zaXplXzsKKworICB6X3N0cmVhbSB6Y29udGV4dF87CisgIGludCB6ZXJyb3JfOworICB2b2lkKiBpbnB1dF9idWZmZXJfOworICBzaXplX3QgaW5wdXRfYnVmZmVyX2xlbmd0aF87CisKKyAgLy8gU2hhcmVkIGNvbnN0cnVjdG9yIGNvZGUuCisgIHZvaWQgSW5pdChaZXJvQ29weU91dHB1dFN0cmVhbSogc3ViX3N0cmVhbSwgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisKKyAgLy8gRG8gc29tZSBjb21wcmVzc2lvbi4KKyAgLy8gVGFrZXMgemxpYiBmbHVzaCBtb2RlLgorICAvLyBSZXR1cm5zIHpsaWIgZXJyb3IgY29kZS4KKyAgaW50IERlZmxhdGUoaW50IGZsdXNoKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoR3ppcE91dHB1dFN0cmVhbSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9JT19HWklQX1NUUkVBTV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW1fdW5pdHRlc3Quc2ggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtX3VuaXR0ZXN0LnNoCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjE2MjUxYTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtX3VuaXR0ZXN0LnNoCkBAIC0wLDAgKzEsNDQgQEAKKyMhL2Jpbi9zaCAteAorIworIyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKyMgQ29weXJpZ2h0IDIwMDkgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisjCisjIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisjIG1ldDoKKyMKKyMgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisjIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKyMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorIyBkaXN0cmlidXRpb24uCisjICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKyMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKyMgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyMKKyMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworIyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKyMgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyMgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisjIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisjIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorIyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisjIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorIyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorIworIyBBdXRob3I6IGJyaWFub2xzb25AZ29vZ2xlLmNvbSAoQnJpYW4gT2xzb24pCisjCisjIFRlc3QgY29tcGF0aWJpbGl0eSBiZXR3ZWVuIGNvbW1hbmQgbGluZSBnemlwL2d1bnppcCBiaW5hcmllcyBhbmQKKyMgWmVyb0NvcHlTdHJlYW0gdmVyc2lvbnMuCisKK1RFU1RGSUxFPU1ha2VmaWxlCisKKyguL3pjZ3ppcCA8ICR7VEVTVEZJTEV9IHwgZ3VuemlwIHwgY21wIC0gJHtURVNURklMRX0pICYmIFwKKyhnemlwIDwgJHtURVNURklMRX0gfCAuL3pjZ3VuemlwIHwgY21wIC0gJHtURVNURklMRX0pCisKKyMgUmVzdWx0IG9mICIoY21kKSAmJiAoY21kKSIgaW1wbGljaXRseSBiZWNvbWVzIHJlc3VsdCBvZiB0aGlzIHNjcmlwdAorIyBhbmQgdGh1cyB0aGUgdGVzdC4KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcGFja2FnZV9pbmZvLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3BhY2thZ2VfaW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjMWZjOTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3BhY2thZ2VfaW5mby5oCkBAIC0wLDAgKzEsNTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgZXhpc3RzIHNvbGVseSB0byBkb2N1bWVudCB0aGUgZ29vZ2xlOjpwcm90b2J1Zjo6aW8gbmFtZXNwYWNlLgorLy8gSXQgaXMgbm90IGNvbXBpbGVkIGludG8gYW55dGhpbmcsIGJ1dCBpdCBtYXkgYmUgcmVhZCBieSBhbiBhdXRvbWF0ZWQKKy8vIGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yLgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gQXV4aWxpYXJ5IGNsYXNzZXMgdXNlZCBmb3IgSS9PLgorLy8KKy8vIFRoZSBQcm90b2NvbCBCdWZmZXIgbGlicmFyeSB1c2VzIHRoZSBjbGFzc2VzIGluIHRoaXMgcGFja2FnZSB0byBkZWFsIHdpdGgKKy8vIEkvTyBhbmQgZW5jb2RpbmcvZGVjb2RpbmcgcmF3IGJ5dGVzLiAgTW9zdCB1c2VycyB3aWxsIG5vdCBuZWVkIHRvCisvLyBkZWFsIHdpdGggdGhpcyBwYWNrYWdlLiAgSG93ZXZlciwgdXNlcnMgd2hvIHdhbnQgdG8gYWRhcHQgdGhlIHN5c3RlbSB0bworLy8gd29yayB3aXRoIHRoZWlyIG93biBJL08gYWJzdHJhY3Rpb25zIC0tIGUuZy4sIHRvIGFsbG93IFByb3RvY29sIEJ1ZmZlcnMKKy8vIHRvIGJlIHJlYWQgZnJvbSBhIGRpZmZlcmVudCBraW5kIG9mIGlucHV0IHN0cmVhbSB3aXRob3V0IHRoZSBuZWVkIGZvciBhCisvLyB0ZW1wb3JhcnkgYnVmZmVyIC0tIHNob3VsZCB0YWtlIGEgY2xvc2VyIGxvb2suCituYW1lc3BhY2UgaW8ge30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTYyMWJhMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5jYwpAQCAtMCwwICsxLDIxMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworUHJpbnRlcjo6UHJpbnRlcihaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0LCBjaGFyIHZhcmlhYmxlX2RlbGltaXRlcikKKyAgOiB2YXJpYWJsZV9kZWxpbWl0ZXJfKHZhcmlhYmxlX2RlbGltaXRlciksCisgICAgb3V0cHV0XyhvdXRwdXQpLAorICAgIGJ1ZmZlcl8oTlVMTCksCisgICAgYnVmZmVyX3NpemVfKDApLAorICAgIGF0X3N0YXJ0X29mX2xpbmVfKHRydWUpLAorICAgIGZhaWxlZF8oZmFsc2UpIHsKK30KKworUHJpbnRlcjo6flByaW50ZXIoKSB7CisgIC8vIE9ubHkgQmFja1VwKCkgaWYgd2UgaGF2ZSBjYWxsZWQgTmV4dCgpIGF0IGxlYXN0IG9uY2UgYW5kIG5ldmVyIGZhaWxlZC4KKyAgaWYgKGJ1ZmZlcl9zaXplXyA+IDAgJiYgIWZhaWxlZF8pIHsKKyAgICBvdXRwdXRfLT5CYWNrVXAoYnVmZmVyX3NpemVfKTsKKyAgfQorfQorCit2b2lkIFByaW50ZXI6OlByaW50KGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcmlhYmxlcywgY29uc3QgY2hhciogdGV4dCkgeworICBpbnQgc2l6ZSA9IHN0cmxlbih0ZXh0KTsKKyAgaW50IHBvcyA9IDA7ICAvLyBUaGUgbnVtYmVyIG9mIGJ5dGVzIHdlJ3ZlIHdyaXR0ZW4gc28gZmFyLgorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgaWYgKHRleHRbaV0gPT0gJ1xuJykgeworICAgICAgLy8gU2F3IG5ld2xpbmUuICBJZiB0aGVyZSBpcyBtb3JlIHRleHQsIHdlIG1heSBuZWVkIHRvIGluc2VydCBhbiBpbmRlbnQKKyAgICAgIC8vIGhlcmUuICBTbywgd3JpdGUgd2hhdCB3ZSBoYXZlIHNvIGZhciwgaW5jbHVkaW5nIHRoZSAnXG4nLgorICAgICAgV3JpdGVSYXcodGV4dCArIHBvcywgaSAtIHBvcyArIDEpOworICAgICAgcG9zID0gaSArIDE7CisKKyAgICAgIC8vIFNldHRpbmcgdGhpcyB0cnVlIHdpbGwgY2F1c2UgdGhlIG5leHQgV3JpdGVSYXcoKSB0byBpbnNlcnQgYW4gaW5kZW50CisgICAgICAvLyBmaXJzdC4KKyAgICAgIGF0X3N0YXJ0X29mX2xpbmVfID0gdHJ1ZTsKKworICAgIH0gZWxzZSBpZiAodGV4dFtpXSA9PSB2YXJpYWJsZV9kZWxpbWl0ZXJfKSB7CisgICAgICAvLyBTYXcgdGhlIHN0YXJ0IG9mIGEgdmFyaWFibGUgbmFtZS4KKworICAgICAgLy8gV3JpdGUgd2hhdCB3ZSBoYXZlIHNvIGZhci4KKyAgICAgIFdyaXRlUmF3KHRleHQgKyBwb3MsIGkgLSBwb3MpOworICAgICAgcG9zID0gaSArIDE7CisKKyAgICAgIC8vIEZpbmQgY2xvc2luZyBkZWxpbWl0ZXIuCisgICAgICBjb25zdCBjaGFyKiBlbmQgPSBzdHJjaHIodGV4dCArIHBvcywgdmFyaWFibGVfZGVsaW1pdGVyXyk7CisgICAgICBpZiAoZW5kID09IE5VTEwpIHsKKyAgICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICIgVW5jbG9zZWQgdmFyaWFibGUgbmFtZS4iOworICAgICAgICBlbmQgPSB0ZXh0ICsgcG9zOworICAgICAgfQorICAgICAgaW50IGVuZHBvcyA9IGVuZCAtIHRleHQ7CisKKyAgICAgIHN0cmluZyB2YXJuYW1lKHRleHQgKyBwb3MsIGVuZHBvcyAtIHBvcyk7CisgICAgICBpZiAodmFybmFtZS5lbXB0eSgpKSB7CisgICAgICAgIC8vIFR3byBkZWxpbWl0ZXJzIGluIGEgcm93IHJlZHVjZSB0byBhIGxpdGVyYWwgZGVsaW1pdGVyIGNoYXJhY3Rlci4KKyAgICAgICAgV3JpdGVSYXcoJnZhcmlhYmxlX2RlbGltaXRlcl8sIDEpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gUmVwbGFjZSB3aXRoIHRoZSB2YXJpYWJsZSdzIHZhbHVlLgorICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gdmFyaWFibGVzLmZpbmQodmFybmFtZSk7CisgICAgICAgIGlmIChpdGVyID09IHZhcmlhYmxlcy5lbmQoKSkgeworICAgICAgICAgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiIFVuZGVmaW5lZCB2YXJpYWJsZTogIiA8PCB2YXJuYW1lOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFdyaXRlUmF3KGl0ZXItPnNlY29uZC5kYXRhKCksIGl0ZXItPnNlY29uZC5zaXplKCkpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIEFkdmFuY2UgcGFzdCB0aGlzIHZhcmlhYmxlLgorICAgICAgaSA9IGVuZHBvczsKKyAgICAgIHBvcyA9IGVuZHBvcyArIDE7CisgICAgfQorICB9CisKKyAgLy8gV3JpdGUgdGhlIHJlc3QuCisgIFdyaXRlUmF3KHRleHQgKyBwb3MsIHNpemUgLSBwb3MpOworfQorCit2b2lkIFByaW50ZXI6OlByaW50KGNvbnN0IGNoYXIqIHRleHQpIHsKKyAgc3RhdGljIG1hcDxzdHJpbmcsIHN0cmluZz4gZW1wdHk7CisgIFByaW50KGVtcHR5LCB0ZXh0KTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZSwgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbdmFyaWFibGVdID0gdmFsdWU7CisgIFByaW50KHZhcnMsIHRleHQpOworfQorCit2b2lkIFByaW50ZXI6OlByaW50KGNvbnN0IGNoYXIqIHRleHQsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMiwgY29uc3Qgc3RyaW5nJiB2YWx1ZTIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzW3ZhcmlhYmxlMV0gPSB2YWx1ZTE7CisgIHZhcnNbdmFyaWFibGUyXSA9IHZhbHVlMjsKKyAgUHJpbnQodmFycywgdGV4dCk7Cit9CisKK3ZvaWQgUHJpbnRlcjo6UHJpbnQoY29uc3QgY2hhciogdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUxLCBjb25zdCBzdHJpbmcmIHZhbHVlMSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUzLCBjb25zdCBzdHJpbmcmIHZhbHVlMykgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbdmFyaWFibGUxXSA9IHZhbHVlMTsKKyAgdmFyc1t2YXJpYWJsZTJdID0gdmFsdWUyOworICB2YXJzW3ZhcmlhYmxlM10gPSB2YWx1ZTM7CisgIFByaW50KHZhcnMsIHRleHQpOworfQorCit2b2lkIFByaW50ZXI6OlByaW50KGNvbnN0IGNoYXIqIHRleHQsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMiwgY29uc3Qgc3RyaW5nJiB2YWx1ZTIsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMywgY29uc3Qgc3RyaW5nJiB2YWx1ZTMsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNCwgY29uc3Qgc3RyaW5nJiB2YWx1ZTQpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzW3ZhcmlhYmxlMV0gPSB2YWx1ZTE7CisgIHZhcnNbdmFyaWFibGUyXSA9IHZhbHVlMjsKKyAgdmFyc1t2YXJpYWJsZTNdID0gdmFsdWUzOworICB2YXJzW3ZhcmlhYmxlNF0gPSB2YWx1ZTQ7CisgIFByaW50KHZhcnMsIHRleHQpOworfQorCit2b2lkIFByaW50ZXI6OkluZGVudCgpIHsKKyAgaW5kZW50XyArPSAiICAiOworfQorCit2b2lkIFByaW50ZXI6Ok91dGRlbnQoKSB7CisgIGlmIChpbmRlbnRfLmVtcHR5KCkpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIiBPdXRkZW50KCkgd2l0aG91dCBtYXRjaGluZyBJbmRlbnQoKS4iOworICAgIHJldHVybjsKKyAgfQorCisgIGluZGVudF8ucmVzaXplKGluZGVudF8uc2l6ZSgpIC0gMik7Cit9CisKK3ZvaWQgUHJpbnRlcjo6UHJpbnRSYXcoY29uc3Qgc3RyaW5nJiBkYXRhKSB7CisgIFdyaXRlUmF3KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7Cit9CisKK3ZvaWQgUHJpbnRlcjo6UHJpbnRSYXcoY29uc3QgY2hhciogZGF0YSkgeworICBpZiAoZmFpbGVkXykgcmV0dXJuOworICBXcml0ZVJhdyhkYXRhLCBzdHJsZW4oZGF0YSkpOworfQorCit2b2lkIFByaW50ZXI6OldyaXRlUmF3KGNvbnN0IGNoYXIqIGRhdGEsIGludCBzaXplKSB7CisgIGlmIChmYWlsZWRfKSByZXR1cm47CisgIGlmIChzaXplID09IDApIHJldHVybjsKKworICBpZiAoYXRfc3RhcnRfb2ZfbGluZV8gJiYgKHNpemUgPiAwKSAmJiAoZGF0YVswXSAhPSAnXG4nKSkgeworICAgIC8vIEluc2VydCBhbiBpbmRlbnQuCisgICAgYXRfc3RhcnRfb2ZfbGluZV8gPSBmYWxzZTsKKyAgICBXcml0ZVJhdyhpbmRlbnRfLmRhdGEoKSwgaW5kZW50Xy5zaXplKCkpOworICAgIGlmIChmYWlsZWRfKSByZXR1cm47CisgIH0KKworICB3aGlsZSAoc2l6ZSA+IGJ1ZmZlcl9zaXplXykgeworICAgIC8vIERhdGEgZXhjZWVkcyBzcGFjZSBpbiB0aGUgYnVmZmVyLiAgQ29weSB3aGF0IHdlIGNhbiBhbmQgcmVxdWVzdCBhCisgICAgLy8gbmV3IGJ1ZmZlci4KKyAgICBtZW1jcHkoYnVmZmVyXywgZGF0YSwgYnVmZmVyX3NpemVfKTsKKyAgICBkYXRhICs9IGJ1ZmZlcl9zaXplXzsKKyAgICBzaXplIC09IGJ1ZmZlcl9zaXplXzsKKyAgICB2b2lkKiB2b2lkX2J1ZmZlcjsKKyAgICBmYWlsZWRfID0gIW91dHB1dF8tPk5leHQoJnZvaWRfYnVmZmVyLCAmYnVmZmVyX3NpemVfKTsKKyAgICBpZiAoZmFpbGVkXykgcmV0dXJuOworICAgIGJ1ZmZlcl8gPSByZWludGVycHJldF9jYXN0PGNoYXIqPih2b2lkX2J1ZmZlcik7CisgIH0KKworICAvLyBCdWZmZXIgaXMgYmlnIGVub3VnaCB0byByZWNlaXZlIHRoZSBkYXRhOyBjb3B5IGl0LgorICBtZW1jcHkoYnVmZmVyXywgZGF0YSwgc2l6ZSk7CisgIGJ1ZmZlcl8gKz0gc2l6ZTsKKyAgYnVmZmVyX3NpemVfIC09IHNpemU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyY2UzNDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaApAQCAtMCwwICsxLDE0MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFV0aWxpdHkgY2xhc3MgZm9yIHdyaXRpbmcgdGV4dCB0byBhIFplcm9Db3B5T3V0cHV0U3RyZWFtLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19QUklOVEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fUFJJTlRFUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsgICAgIC8vIHplcm9fY29weV9zdHJlYW0uaAorCisvLyBUaGlzIHNpbXBsZSB1dGlsaXR5IGNsYXNzIGFzc2lzdHMgaW4gY29kZSBnZW5lcmF0aW9uLiAgSXQgYmFzaWNhbGx5CisvLyBhbGxvd3MgdGhlIGNhbGxlciB0byBkZWZpbmUgYSBzZXQgb2YgdmFyaWFibGVzIGFuZCB0aGVuIG91dHB1dCBzb21lCisvLyB0ZXh0IHdpdGggdmFyaWFibGUgc3Vic3RpdHV0aW9ucy4gIEV4YW1wbGUgdXNhZ2U6CisvLworLy8gICBQcmludGVyIHByaW50ZXIob3V0cHV0LCAnJCcpOworLy8gICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisvLyAgIHZhcnNbIm5hbWUiXSA9ICJCb2IiOworLy8gICBwcmludGVyLlByaW50KHZhcnMsICJNeSBuYW1lIGlzICRuYW1lJC4iKTsKKy8vCisvLyBUaGUgYWJvdmUgd3JpdGVzICJNeSBuYW1lIGlzIEJvYi4iIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorLy8KKy8vIFByaW50ZXIgYWdncmVzc2l2ZWx5IGVuZm9yY2VzIGNvcnJlY3QgdXNhZ2UsIGNyYXNoaW5nICh3aXRoIGFzc2VydCBmYWlsdXJlcykKKy8vIGluIHRoZSBjYXNlIG9mIHVuZGVmaW5lZCB2YXJpYWJsZXMgaW4gZGVidWcgYnVpbGRzLiBUaGlzIGhlbHBzIGdyZWF0bHkgaW4KKy8vIGRlYnVnZ2luZyBjb2RlIHdoaWNoIHVzZXMgaXQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUHJpbnRlciB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBwcmludGVyIHRoYXQgd3JpdGVzIHRleHQgdG8gdGhlIGdpdmVuIG91dHB1dCBzdHJlYW0uICBVc2UgdGhlCisgIC8vIGdpdmVuIGNoYXJhY3RlciBhcyB0aGUgZGVsaW1pdGVyIGZvciB2YXJpYWJsZXMuCisgIFByaW50ZXIoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgY2hhciB2YXJpYWJsZV9kZWxpbWl0ZXIpOworICB+UHJpbnRlcigpOworCisgIC8vIFByaW50IHNvbWUgdGV4dCBhZnRlciBhcHBseWluZyB2YXJpYWJsZSBzdWJzdGl0dXRpb25zLiAgSWYgYSBwYXJ0aWN1bGFyCisgIC8vIHZhcmlhYmxlIGluIHRoZSB0ZXh0IGlzIG5vdCBkZWZpbmVkLCB0aGlzIHdpbGwgY3Jhc2guICBWYXJpYWJsZXMgdG8gYmUKKyAgLy8gc3Vic3RpdHV0ZWQgYXJlIGlkZW50aWZpZWQgYnkgdGhlaXIgbmFtZXMgc3Vycm91bmRlZCBieSBkZWxpbWl0ZXIKKyAgLy8gY2hhcmFjdGVycyAoYXMgZ2l2ZW4gdG8gdGhlIGNvbnN0cnVjdG9yKS4gIFRoZSB2YXJpYWJsZSBiaW5kaW5ncyBhcmUKKyAgLy8gZGVmaW5lZCBieSB0aGUgZ2l2ZW4gbWFwLgorICB2b2lkIFByaW50KGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcmlhYmxlcywgY29uc3QgY2hhciogdGV4dCk7CisKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQpOworICAvLyBMaWtlIHRoZSBmaXJzdCBQcmludCgpLCBleGNlcHQgdGhlIHN1YnN0aXR1dGlvbnMgYXJlIGdpdmVuIGFzIHBhcmFtZXRlcnMuCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogdmFyaWFibGUsIGNvbnN0IHN0cmluZyYgdmFsdWUpOworICAvLyBMaWtlIHRoZSBmaXJzdCBQcmludCgpLCBleGNlcHQgdGhlIHN1YnN0aXR1dGlvbnMgYXJlIGdpdmVuIGFzIHBhcmFtZXRlcnMuCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogdmFyaWFibGUxLCBjb25zdCBzdHJpbmcmIHZhbHVlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyKTsKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzKTsKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNCwgY29uc3Qgc3RyaW5nJiB2YWx1ZTQpOworICAvLyBUT0RPKGtlbnRvbik6ICBPdmVybG9hZGVkIHZlcnNpb25zIHdpdGggbW9yZSB2YXJpYWJsZXM/ICBUaHJlZSBzZWVtcworICAvLyAgIHRvIGJlIGVub3VnaC4KKworICAvLyBJbmRlbnQgdGV4dCBieSB0d28gc3BhY2VzLiAgQWZ0ZXIgY2FsbGluZyBJbmRlbnQoKSwgdHdvIHNwYWNlcyB3aWxsIGJlCisgIC8vIGluc2VydGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG9mIHRleHQuICBJbmRlbnQoKSBtYXkgYmUgY2FsbGVkCisgIC8vIG11bHRpcGxlIHRpbWVzIHRvIHByb2R1Y2UgZGVlcGVyIGluZGVudHMuCisgIHZvaWQgSW5kZW50KCk7CisKKyAgLy8gUmVkdWNlcyB0aGUgY3VycmVudCBpbmRlbnQgbGV2ZWwgYnkgdHdvIHNwYWNlcywgb3IgY3Jhc2hlcyBpZiB0aGUgaW5kZW50CisgIC8vIGxldmVsIGlzIHplcm8uCisgIHZvaWQgT3V0ZGVudCgpOworCisgIC8vIFdyaXRlIGEgc3RyaW5nIHRvIHRoZSBvdXRwdXQgYnVmZmVyLgorICAvLyBUaGlzIG1ldGhvZCBkb2VzIG5vdCBsb29rIGZvciBuZXdsaW5lcyB0byBhZGQgaW5kZW50YXRpb24uCisgIHZvaWQgUHJpbnRSYXcoY29uc3Qgc3RyaW5nJiBkYXRhKTsKKworICAvLyBXcml0ZSBhIHplcm8tZGVsaW1pdGVkIHN0cmluZyB0byBvdXRwdXQgYnVmZmVyLgorICAvLyBUaGlzIG1ldGhvZCBkb2VzIG5vdCBsb29rIGZvciBuZXdsaW5lcyB0byBhZGQgaW5kZW50YXRpb24uCisgIHZvaWQgUHJpbnRSYXcoY29uc3QgY2hhciogZGF0YSk7CisKKyAgLy8gV3JpdGUgc29tZSBieXRlcyB0byB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgLy8gVGhpcyBtZXRob2QgZG9lcyBub3QgbG9vayBmb3IgbmV3bGluZXMgdG8gYWRkIGluZGVudGF0aW9uLgorICB2b2lkIFdyaXRlUmF3KGNvbnN0IGNoYXIqIGRhdGEsIGludCBzaXplKTsKKworICAvLyBUcnVlIGlmIGFueSB3cml0ZSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0gZmFpbGVkLiAgKFdlIGRvbid0IGp1c3QKKyAgLy8gY3Jhc2ggaW4gdGhpcyBjYXNlIGJlY2F1c2UgdGhpcyBpcyBhbiBJL08gZmFpbHVyZSwgbm90IGEgcHJvZ3JhbW1pbmcKKyAgLy8gZXJyb3IuKQorICBib29sIGZhaWxlZCgpIGNvbnN0IHsgcmV0dXJuIGZhaWxlZF87IH0KKworIHByaXZhdGU6CisgIGNvbnN0IGNoYXIgdmFyaWFibGVfZGVsaW1pdGVyXzsKKworICBaZXJvQ29weU91dHB1dFN0cmVhbSogY29uc3Qgb3V0cHV0XzsKKyAgY2hhciogYnVmZmVyXzsKKyAgaW50IGJ1ZmZlcl9zaXplXzsKKworICBzdHJpbmcgaW5kZW50XzsKKyAgYm9vbCBhdF9zdGFydF9vZl9saW5lXzsKKyAgYm9vbCBmYWlsZWRfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQcmludGVyKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1BSSU5URVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXJfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXJfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMzMWE4ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlcl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDI4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CituYW1lc3BhY2UgeworCisvLyBFYWNoIHRlc3QgcmVwZWF0cyBvdmVyIHNldmVyYWwgYmxvY2sgc2l6ZXMgaW4gb3JkZXIgdG8gdGVzdCBib3RoIGNhc2VzCisvLyB3aGVyZSBwYXJ0aWN1bGFyIHdyaXRlcyBjcm9zcyBhIGJ1ZmZlciBib3VuZGFyeSBhbmQgY2FzZXMgd2hlcmUgdGhleSBkbworLy8gbm90LgorCitURVNUKFByaW50ZXIsIEVtcHR5UHJpbnRlcikgeworICBjaGFyIGJ1ZmZlcls4MTkyXTsKKyAgY29uc3QgaW50IGJsb2NrX3NpemUgPSAxMDA7CisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIEdPT0dMRV9BUlJBWVNJWkUoYnVmZmVyKSwgYmxvY2tfc2l6ZSk7CisgIFByaW50ZXIgcHJpbnRlcigmb3V0cHV0LCAnXDAnKTsKKyAgRVhQRUNUX1RSVUUoIXByaW50ZXIuZmFpbGVkKCkpOworfQorCitURVNUKFByaW50ZXIsIEJhc2ljUHJpbnRpbmcpIHsKKyAgY2hhciBidWZmZXJbODE5Ml07CisKKyAgZm9yIChpbnQgYmxvY2tfc2l6ZSA9IDE7IGJsb2NrX3NpemUgPCA1MTI7IGJsb2NrX3NpemUgKj0gMikgeworICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpLCBibG9ja19zaXplKTsKKworICAgIHsKKyAgICAgIFByaW50ZXIgcHJpbnRlcigmb3V0cHV0LCAnXDAnKTsKKworICAgICAgcHJpbnRlci5QcmludCgiSGVsbG8gV29ybGQhIik7CisgICAgICBwcmludGVyLlByaW50KCIgIFRoaXMgaXMgdGhlIHNhbWUgbGluZS5cbiIpOworICAgICAgcHJpbnRlci5QcmludCgiQnV0IHRoaXMgaXMgYSBuZXcgb25lLlxuQW5kIHRoaXMgaXMgYW5vdGhlciBvbmUuIik7CisKKyAgICAgIEVYUEVDVF9GQUxTRShwcmludGVyLmZhaWxlZCgpKTsKKyAgICB9CisKKyAgICBidWZmZXJbb3V0cHV0LkJ5dGVDb3VudCgpXSA9ICdcMCc7CisKKyAgICBFWFBFQ1RfU1RSRVEoIkhlbGxvIFdvcmxkISAgVGhpcyBpcyB0aGUgc2FtZSBsaW5lLlxuIgorICAgICAgICAgICAgICAgICAiQnV0IHRoaXMgaXMgYSBuZXcgb25lLlxuIgorICAgICAgICAgICAgICAgICAiQW5kIHRoaXMgaXMgYW5vdGhlciBvbmUuIiwKKyAgICAgICAgICAgICAgICAgYnVmZmVyKTsKKyAgfQorfQorCitURVNUKFByaW50ZXIsIFdyaXRlUmF3KSB7CisgIGNoYXIgYnVmZmVyWzgxOTJdOworCisgIGZvciAoaW50IGJsb2NrX3NpemUgPSAxOyBibG9ja19zaXplIDwgNTEyOyBibG9ja19zaXplICo9IDIpIHsKKyAgICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgYmxvY2tfc2l6ZSk7CisKKyAgICB7CisgICAgICBzdHJpbmcgc3RyaW5nX29iaiA9ICJGcm9tIGFuIG9iamVjdFxuIjsKKyAgICAgIFByaW50ZXIgcHJpbnRlcigmb3V0cHV0LCAnJCcpOworICAgICAgcHJpbnRlci5Xcml0ZVJhdygiSGVsbG8gV29ybGQhIiwgMTIpOworICAgICAgcHJpbnRlci5QcmludFJhdygiICBUaGlzIGlzIHRoZSBzYW1lIGxpbmUuXG4iKTsKKyAgICAgIHByaW50ZXIuUHJpbnRSYXcoIkJ1dCB0aGlzIGlzIGEgbmV3IG9uZS5cbkFuZCB0aGlzIGlzIGFub3RoZXIgb25lLiIpOworICAgICAgcHJpbnRlci5Xcml0ZVJhdygiXG4iLCAxKTsKKyAgICAgIHByaW50ZXIuUHJpbnRSYXcoc3RyaW5nX29iaik7CisgICAgICBFWFBFQ1RfRkFMU0UocHJpbnRlci5mYWlsZWQoKSk7CisgICAgfQorCisgICAgYnVmZmVyW291dHB1dC5CeXRlQ291bnQoKV0gPSAnXDAnOworCisgICAgRVhQRUNUX1NUUkVRKCJIZWxsbyBXb3JsZCEgIFRoaXMgaXMgdGhlIHNhbWUgbGluZS5cbiIKKyAgICAgICAgICAgICAgICAgIkJ1dCB0aGlzIGlzIGEgbmV3IG9uZS5cbiIKKyAgICAgICAgICAgICAgICAgIkFuZCB0aGlzIGlzIGFub3RoZXIgb25lLiIKKyAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAiRnJvbSBhbiBvYmplY3RcbiIsCisgICAgICAgICAgICAgICAgIGJ1ZmZlcik7CisgIH0KK30KKworVEVTVChQcmludGVyLCBWYXJpYWJsZVN1YnN0aXR1dGlvbikgeworICBjaGFyIGJ1ZmZlcls4MTkyXTsKKworICBmb3IgKGludCBibG9ja19zaXplID0gMTsgYmxvY2tfc2l6ZSA8IDUxMjsgYmxvY2tfc2l6ZSAqPSAyKSB7CisgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksIGJsb2NrX3NpemUpOworCisgICAgeworICAgICAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisKKyAgICAgIHZhcnNbImZvbyJdID0gIldvcmxkIjsKKyAgICAgIHZhcnNbImJhciJdID0gIiRmb28kIjsKKyAgICAgIHZhcnNbImFiY2RlZmciXSA9ICIxMjM0IjsKKworICAgICAgcHJpbnRlci5QcmludCh2YXJzLCAiSGVsbG8gJGZvbyQhXG5iYXIgPSAkYmFyJFxuIik7CisgICAgICBwcmludGVyLlByaW50UmF3KCJSYXdCaXRcbiIpOworICAgICAgcHJpbnRlci5QcmludCh2YXJzLCAiJGFiY2RlZmckXG5BIGxpdGVyYWwgZG9sbGFyIHNpZ246ICAkJCIpOworCisgICAgICB2YXJzWyJmb28iXSA9ICJibGFoIjsKKyAgICAgIHByaW50ZXIuUHJpbnQodmFycywgIlxuTm93IGZvbyA9ICRmb28kLiIpOworCisgICAgICBFWFBFQ1RfRkFMU0UocHJpbnRlci5mYWlsZWQoKSk7CisgICAgfQorCisgICAgYnVmZmVyW291dHB1dC5CeXRlQ291bnQoKV0gPSAnXDAnOworCisgICAgRVhQRUNUX1NUUkVRKCJIZWxsbyBXb3JsZCFcbiIKKyAgICAgICAgICAgICAgICAgImJhciA9ICRmb28kXG4iCisgICAgICAgICAgICAgICAgICJSYXdCaXRcbiIKKyAgICAgICAgICAgICAgICAgIjEyMzRcbiIKKyAgICAgICAgICAgICAgICAgIkEgbGl0ZXJhbCBkb2xsYXIgc2lnbjogICRcbiIKKyAgICAgICAgICAgICAgICAgIk5vdyBmb28gPSBibGFoLiIsCisgICAgICAgICAgICAgICAgIGJ1ZmZlcik7CisgIH0KK30KKworVEVTVChQcmludGVyLCBJbmxpbmVWYXJpYWJsZVN1YnN0aXR1dGlvbikgeworICBjaGFyIGJ1ZmZlcls4MTkyXTsKKworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSk7CisKKyAgeworICAgIFByaW50ZXIgcHJpbnRlcigmb3V0cHV0LCAnJCcpOworICAgIHByaW50ZXIuUHJpbnQoIkhlbGxvICRmb28kIVxuIiwgImZvbyIsICJXb3JsZCIpOworICAgIHByaW50ZXIuUHJpbnRSYXcoIlJhd0JpdFxuIik7CisgICAgcHJpbnRlci5QcmludCgiJGZvbyQgJGJhciRcbiIsICJmb28iLCAib25lIiwgImJhciIsICJ0d28iKTsKKyAgICBFWFBFQ1RfRkFMU0UocHJpbnRlci5mYWlsZWQoKSk7CisgIH0KKworICBidWZmZXJbb3V0cHV0LkJ5dGVDb3VudCgpXSA9ICdcMCc7CisKKyAgRVhQRUNUX1NUUkVRKCJIZWxsbyBXb3JsZCFcbiIKKyAgICAgICAgICAgICAgICJSYXdCaXRcbiIKKyAgICAgICAgICAgICAgICJvbmUgdHdvXG4iLAorICAgICAgICAgICAgICAgYnVmZmVyKTsKK30KKworVEVTVChQcmludGVyLCBJbmRlbnRpbmcpIHsKKyAgY2hhciBidWZmZXJbODE5Ml07CisKKyAgZm9yIChpbnQgYmxvY2tfc2l6ZSA9IDE7IGJsb2NrX3NpemUgPCA1MTI7IGJsb2NrX3NpemUgKj0gMikgeworICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpLCBibG9ja19zaXplKTsKKworICAgIHsKKyAgICAgIFByaW50ZXIgcHJpbnRlcigmb3V0cHV0LCAnJCcpOworICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworCisgICAgICB2YXJzWyJuZXdsaW5lIl0gPSAiXG4iOworCisgICAgICBwcmludGVyLlByaW50KCJUaGlzIGlzIG5vdCBpbmRlbnRlZC5cbiIpOworICAgICAgcHJpbnRlci5JbmRlbnQoKTsKKyAgICAgIHByaW50ZXIuUHJpbnQoIlRoaXMgaXMgaW5kZW50ZWRcbkFuZCBzbyBpcyB0aGlzXG4iKTsKKyAgICAgIHByaW50ZXIuT3V0ZGVudCgpOworICAgICAgcHJpbnRlci5QcmludCgiQnV0IHRoaXMgaXMgbm90LiIpOworICAgICAgcHJpbnRlci5JbmRlbnQoKTsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiAgQW5kIHRoaXMgaXMgc3RpbGwgdGhlIHNhbWUgbGluZS5cbiIKKyAgICAgICAgICAgICAgICAgICAgIkJ1dCB0aGlzIGlzIGluZGVudGVkLlxuIik7CisgICAgICBwcmludGVyLlByaW50UmF3KCJSYXdCaXQgaGFzIGluZGVudCBhdCBzdGFydFxuIik7CisgICAgICBwcmludGVyLlByaW50UmF3KCJidXQgbm90IGFmdGVyIGEgcmF3IG5ld2xpbmVcbiIpOworICAgICAgcHJpbnRlci5QcmludCh2YXJzLCAiTm90ZSB0aGF0IGEgbmV3bGluZSBpbiBhIHZhcmlhYmxlIHdpbGwgYnJlYWsgIgorICAgICAgICAgICAgICAgICAgICAiaW5kZW50aW5nLCBhcyB3ZSBzZWUkbmV3bGluZSRoZXJlLlxuIik7CisgICAgICBwcmludGVyLkluZGVudCgpOworICAgICAgcHJpbnRlci5QcmludCgiQW5kIHRoaXMiKTsKKyAgICAgIHByaW50ZXIuT3V0ZGVudCgpOworICAgICAgcHJpbnRlci5PdXRkZW50KCk7CisgICAgICBwcmludGVyLlByaW50KCIgaXMgZG91YmxlLWluZGVudGVkXG5CYWNrIHRvIG5vcm1hbC4iKTsKKworICAgICAgRVhQRUNUX0ZBTFNFKHByaW50ZXIuZmFpbGVkKCkpOworICAgIH0KKworICAgIGJ1ZmZlcltvdXRwdXQuQnl0ZUNvdW50KCldID0gJ1wwJzsKKworICAgIEVYUEVDVF9TVFJFUSgKKyAgICAgICJUaGlzIGlzIG5vdCBpbmRlbnRlZC5cbiIKKyAgICAgICIgIFRoaXMgaXMgaW5kZW50ZWRcbiIKKyAgICAgICIgIEFuZCBzbyBpcyB0aGlzXG4iCisgICAgICAiQnV0IHRoaXMgaXMgbm90LiAgQW5kIHRoaXMgaXMgc3RpbGwgdGhlIHNhbWUgbGluZS5cbiIKKyAgICAgICIgIEJ1dCB0aGlzIGlzIGluZGVudGVkLlxuIgorICAgICAgIiAgUmF3Qml0IGhhcyBpbmRlbnQgYXQgc3RhcnRcbiIKKyAgICAgICJidXQgbm90IGFmdGVyIGEgcmF3IG5ld2xpbmVcbiIKKyAgICAgICJOb3RlIHRoYXQgYSBuZXdsaW5lIGluIGEgdmFyaWFibGUgd2lsbCBicmVhayBpbmRlbnRpbmcsIGFzIHdlIHNlZVxuIgorICAgICAgImhlcmUuXG4iCisgICAgICAiICAgIEFuZCB0aGlzIGlzIGRvdWJsZS1pbmRlbnRlZFxuIgorICAgICAgIkJhY2sgdG8gbm9ybWFsLiIsCisgICAgICBidWZmZXIpOworICB9Cit9CisKKy8vIERlYXRoIHRlc3RzIGRvIG5vdCB3b3JrIG9uIFdpbmRvd3MgYXMgb2YgeWV0LgorI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCitURVNUKFByaW50ZXIsIERlYXRoKSB7CisgIGNoYXIgYnVmZmVyWzgxOTJdOworCisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpKTsKKyAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKHByaW50ZXIuUHJpbnQoIiRub3N1Y2h2YXIkIiksICJVbmRlZmluZWQgdmFyaWFibGUiKTsKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKHByaW50ZXIuUHJpbnQoIiR1bmNsb3NlZCIpLCAiVW5jbG9zZWQgdmFyaWFibGUgbmFtZSIpOworICBFWFBFQ1RfREVCVUdfREVBVEgocHJpbnRlci5PdXRkZW50KCksICJ3aXRob3V0IG1hdGNoaW5nIEluZGVudCIpOworfQorI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKFByaW50ZXIsIFdyaXRlRmFpbHVyZVBhcnRpYWwpIHsKKyAgY2hhciBidWZmZXJbMTddOworCisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpKTsKKyAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisKKyAgLy8gUHJpbnQgMTYgYnl0ZXMgdG8gYWxtb3N0IGZpbGwgdGhlIGJ1ZmZlciAoc2hvdWxkIG5vdCBmYWlsKS4KKyAgcHJpbnRlci5QcmludCgiMDEyMzQ1Njc4OWFiY2RlZiIpOworICBFWFBFQ1RfRkFMU0UocHJpbnRlci5mYWlsZWQoKSk7CisKKyAgLy8gVHJ5IHRvIHByaW50IDIgY2hhcnMuIE9ubHkgb25lIGZpdHMuCisgIHByaW50ZXIuUHJpbnQoIjw+Iik7CisgIEVYUEVDVF9UUlVFKHByaW50ZXIuZmFpbGVkKCkpOworCisgIC8vIEFueXRoaW5nIGVsc2Ugc2hvdWxkIGZhaWwgdG9vLgorICBwcmludGVyLlByaW50KCIgIik7CisgIEVYUEVDVF9UUlVFKHByaW50ZXIuZmFpbGVkKCkpOworICBwcmludGVyLlByaW50KCJibGFoIik7CisgIEVYUEVDVF9UUlVFKHByaW50ZXIuZmFpbGVkKCkpOworCisgIC8vIEJ1ZmZlciBzaG91bGQgY29udGFpbiB0aGUgZmlyc3QgMTcgYnl0ZXMgd3JpdHRlbi4KKyAgRVhQRUNUX0VRKCIwMTIzNDU2Nzg5YWJjZGVmPCIsIHN0cmluZyhidWZmZXIsIHNpemVvZihidWZmZXIpKSk7Cit9CisKK1RFU1QoUHJpbnRlciwgV3JpdGVGYWlsdXJlRXhhY3QpIHsKKyAgY2hhciBidWZmZXJbMTZdOworCisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpKTsKKyAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisKKyAgLy8gUHJpbnQgMTYgYnl0ZXMgdG8gZmlsbCB0aGUgYnVmZmVyIGV4YWN0bHkgKHNob3VsZCBub3QgZmFpbCkuCisgIHByaW50ZXIuUHJpbnQoIjAxMjM0NTY3ODlhYmNkZWYiKTsKKyAgRVhQRUNUX0ZBTFNFKHByaW50ZXIuZmFpbGVkKCkpOworCisgIC8vIFRyeSB0byBwcmludCBvbmUgbW9yZSBieXRlIChzaG91bGQgZmFpbCkuCisgIHByaW50ZXIuUHJpbnQoIiAiKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5mYWlsZWQoKSk7CisKKyAgLy8gU2hvdWxkIG5vdCBjcmFzaAorICBwcmludGVyLlByaW50KCJibGFoIik7CisgIEVYUEVDVF9UUlVFKHByaW50ZXIuZmFpbGVkKCkpOworCisgIC8vIEJ1ZmZlciBzaG91bGQgY29udGFpbiB0aGUgZmlyc3QgMTYgYnl0ZXMgd3JpdHRlbi4KKyAgRVhQRUNUX0VRKCIwMTIzNDU2Nzg5YWJjZGVmIiwgc3RyaW5nKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9zdHJ0b2QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Njk3MzQzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9zdHJ0b2QuY2MKQEAgLTAsMCArMSwxMTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oPgorCisjaW5jbHVkZSA8Y3N0ZGlvPgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBOb0xvY2FsZVN0cnRvZCgpCisvLyAgIFRoaXMgY29kZSB3aWxsIG1ha2UgeW91IGNyeS4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIHsKKworLy8gUmV0dXJucyBhIHN0cmluZyBpZGVudGljYWwgdG8gKmlucHV0IGV4Y2VwdCB0aGF0IHRoZSBjaGFyYWN0ZXIgcG9pbnRlZCB0bworLy8gYnkgcmFkaXhfcG9zICh3aGljaCBzaG91bGQgYmUgJy4nKSBpcyByZXBsYWNlZCB3aXRoIHRoZSBsb2NhbGUtc3BlY2lmaWMKKy8vIHJhZGl4IGNoYXJhY3Rlci4KK3N0cmluZyBMb2NhbGl6ZVJhZGl4KGNvbnN0IGNoYXIqIGlucHV0LCBjb25zdCBjaGFyKiByYWRpeF9wb3MpIHsKKyAgLy8gRGV0ZXJtaW5lIHRoZSBsb2NhbGUtc3BlY2lmaWMgcmFkaXggY2hhcmFjdGVyIGJ5IGNhbGxpbmcgc3ByaW50ZigpIHRvCisgIC8vIHByaW50IHRoZSBudW1iZXIgMS41LCB0aGVuIHN0cmlwcGluZyBvZmYgdGhlIGRpZ2l0cy4gIEFzIGZhciBhcyBJIGNhbgorICAvLyB0ZWxsLCB0aGlzIGlzIHRoZSBvbmx5IHBvcnRhYmxlLCB0aHJlYWQtc2FmZSB3YXkgdG8gZ2V0IHRoZSBDIGxpYnJhcnkKKyAgLy8gdG8gZGl2dWxkZ2UgdGhlIGxvY2FsZSdzIHJhZGl4IGNoYXJhY3Rlci4gIE5vLCBsb2NhbGVjb252KCkgaXMgTk9UCisgIC8vIHRocmVhZC1zYWZlLgorICBjaGFyIHRlbXBbMTZdOworICBpbnQgc2l6ZSA9IHNwcmludGYodGVtcCwgIiUuMWYiLCAxLjUpOworICBHT09HTEVfQ0hFQ0tfRVEodGVtcFswXSwgJzEnKTsKKyAgR09PR0xFX0NIRUNLX0VRKHRlbXBbc2l6ZS0xXSwgJzUnKTsKKyAgR09PR0xFX0NIRUNLX0xFKHNpemUsIDYpOworCisgIC8vIE5vdyByZXBsYWNlIHRoZSAnLicgaW4gdGhlIGlucHV0IHdpdGggaXQuCisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNlcnZlKHN0cmxlbihpbnB1dCkgKyBzaXplIC0gMyk7CisgIHJlc3VsdC5hcHBlbmQoaW5wdXQsIHJhZGl4X3Bvcyk7CisgIHJlc3VsdC5hcHBlbmQodGVtcCArIDEsIHNpemUgLSAyKTsKKyAgcmVzdWx0LmFwcGVuZChyYWRpeF9wb3MgKyAxKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK2RvdWJsZSBOb0xvY2FsZVN0cnRvZChjb25zdCBjaGFyKiB0ZXh0LCBjaGFyKiogb3JpZ2luYWxfZW5kcHRyKSB7CisgIC8vIFdlIGNhbm5vdCBzaW1wbHkgc2V0IHRoZSBsb2NhbGUgdG8gIkMiIHRlbXBvcmFyaWx5IHdpdGggc2V0bG9jYWxlKCkKKyAgLy8gYXMgdGhpcyBpcyBub3QgdGhyZWFkLXNhZmUuICBJbnN0ZWFkLCB3ZSB0cnkgdG8gcGFyc2UgaW4gdGhlIGN1cnJlbnQKKyAgLy8gbG9jYWxlIGZpcnN0LiAgSWYgcGFyc2luZyBzdG9wcyBhdCBhICcuJyBjaGFyYWN0ZXIsIHRoZW4gdGhpcyBpcyBhCisgIC8vIHByZXR0eSBnb29kIGhpbnQgdGhhdCB3ZSdyZSBhY3R1YWxseSBpbiBzb21lIG90aGVyIGxvY2FsZSBpbiB3aGljaAorICAvLyAnLicgaXMgbm90IHRoZSByYWRpeCBjaGFyYWN0ZXIuCisKKyAgY2hhciogdGVtcF9lbmRwdHI7CisgIGRvdWJsZSByZXN1bHQgPSBzdHJ0b2QodGV4dCwgJnRlbXBfZW5kcHRyKTsKKyAgaWYgKG9yaWdpbmFsX2VuZHB0ciAhPSBOVUxMKSAqb3JpZ2luYWxfZW5kcHRyID0gdGVtcF9lbmRwdHI7CisgIGlmICgqdGVtcF9lbmRwdHIgIT0gJy4nKSByZXR1cm4gcmVzdWx0OworCisgIC8vIFBhcnNpbmcgaGFsdGVkIG9uIGEgJy4nLiAgUGVyaGFwcyB3ZSdyZSBpbiBhIGRpZmZlcmVudCBsb2NhbGU/ICBMZXQncworICAvLyB0cnkgdG8gcmVwbGFjZSB0aGUgJy4nIHdpdGggYSBsb2NhbGUtc3BlY2lmaWMgcmFkaXggY2hhcmFjdGVyIGFuZAorICAvLyB0cnkgYWdhaW4uCisgIHN0cmluZyBsb2NhbGl6ZWQgPSBMb2NhbGl6ZVJhZGl4KHRleHQsIHRlbXBfZW5kcHRyKTsKKyAgY29uc3QgY2hhciogbG9jYWxpemVkX2NzdHIgPSBsb2NhbGl6ZWQuY19zdHIoKTsKKyAgY2hhciogbG9jYWxpemVkX2VuZHB0cjsKKyAgcmVzdWx0ID0gc3RydG9kKGxvY2FsaXplZF9jc3RyLCAmbG9jYWxpemVkX2VuZHB0cik7CisgIGlmICgobG9jYWxpemVkX2VuZHB0ciAtIGxvY2FsaXplZF9jc3RyKSA+CisgICAgICAodGVtcF9lbmRwdHIgLSB0ZXh0KSkgeworICAgIC8vIFRoaXMgYXR0ZW1wdCBnb3QgZnVydGhlciwgc28gcmVwbGFjaW5nIHRoZSBkZWNpbWFsIG11c3QgaGF2ZSBoZWxwZWQuCisgICAgLy8gVXBkYXRlIG9yaWdpbmFsX2VuZHB0ciB0byBwb2ludCBhdCB0aGUgcmlnaHQgbG9jYXRpb24uCisgICAgaWYgKG9yaWdpbmFsX2VuZHB0ciAhPSBOVUxMKSB7CisgICAgICAvLyBzaXplX2RpZmYgaXMgbm9uLXplcm8gaWYgdGhlIGxvY2FsaXplZCByYWRpeCBoYXMgbXVsdGlwbGUgYnl0ZXMuCisgICAgICBpbnQgc2l6ZV9kaWZmID0gbG9jYWxpemVkLnNpemUoKSAtIHN0cmxlbih0ZXh0KTsKKyAgICAgIC8vIGNvbnN0X2Nhc3QgaXMgbmVjZXNzYXJ5IHRvIG1hdGNoIHRoZSBzdHJ0b2QoKSBpbnRlcmZhY2UuCisgICAgICAqb3JpZ2luYWxfZW5kcHRyID0gY29uc3RfY2FzdDxjaGFyKj4oCisgICAgICAgIHRleHQgKyAobG9jYWxpemVkX2VuZHB0ciAtIGxvY2FsaXplZF9jc3RyIC0gc2l6ZV9kaWZmKSk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyZWZjOGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oCkBAIC0wLDAgKzEsNTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBIGxvY2FsZS1pbmRlcGVuZGVudCB2ZXJzaW9uIG9mIHN0cnRvZCgpLCB1c2VkIHRvIHBhcnNlIGZsb2F0aW5nCisvLyBwb2ludCBkZWZhdWx0IHZhbHVlcyBpbiAucHJvdG8gZmlsZXMsIHdoZXJlIHRoZSBkZWNpbWFsIHNlcGFyYXRvcgorLy8gaXMgYWx3YXlzIGEgZG90LgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19TVFJUT0RfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9JT19TVFJUT0RfSF9fCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKKy8vIEEgbG9jYWxlLWluZGVwZW5kZW50IHZlcnNpb24gb2YgdGhlIHN0YW5kYXJkIHN0cnRvZCgpLCB3aGljaCBhbHdheXMKKy8vIHVzZXMgYSBkb3QgYXMgdGhlIGRlY2ltYWwgc2VwYXJhdG9yLgorZG91YmxlIE5vTG9jYWxlU3RydG9kKGNvbnN0IGNoYXIqIHN0ciwgY2hhcioqIGVuZHB0cik7CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1NUUlRPRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWYyZGUzMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmNjCkBAIC0wLDAgKzEsMTEyNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEhlcmUgd2UgaGF2ZSBhIGhhbmQtd3JpdHRlbiBsZXhlci4gIEF0IGZpcnN0IHlvdSBtaWdodCBhc2sgeW91cnNlbGYsCisvLyAiSGFuZC13cml0dGVuIHRleHQgcHJvY2Vzc2luZz8gIElzIEtlbnRvbiBjcmF6eT8hIiAgV2VsbCwgZmlyc3Qgb2YgYWxsLAorLy8geWVzIEkgYW0gY3JhenksIGJ1dCB0aGF0J3MgYmVzaWRlIHRoZSBwb2ludC4gIFRoZXJlIGFyZSBhY3R1YWxseSByZWFzb25zCisvLyB3aHkgSSBlbmRlZCB1cCB3cml0aW5nIHRoaXMgdGhpcyB3YXkuCisvLworLy8gVGhlIHRyYWRpdGlvbmFsIGFwcHJvYWNoIHRvIGxleGluZyBpcyB0byB1c2UgbGV4IHRvIGdlbmVyYXRlIGEgbGV4ZXIgZm9yCisvLyB5b3UuICBVbmZvcnR1bmF0ZWx5LCBsZXgncyBvdXRwdXQgaXMgcmlkaWN1bG91c2x5IHVnbHkgYW5kIGRpZmZpY3VsdCB0bworLy8gaW50ZWdyYXRlIGNsZWFubHkgd2l0aCBDKysgY29kZSwgZXNwZWNpYWxseSBhYnN0cmFjdCBjb2RlIG9yIGNvZGUgbWVhbnQKKy8vIGFzIGEgbGlicmFyeS4gIEJldHRlciBwYXJzZXItZ2VuZXJhdG9ycyBleGlzdCBidXQgd291bGQgYWRkIGRlcGVuZGVuY2llcworLy8gd2hpY2ggbW9zdCB1c2VycyB3b24ndCBhbHJlYWR5IGhhdmUsIHdoaWNoIHdlJ2QgbGlrZSB0byBhdm9pZC4gIChHTlUgZmxleAorLy8gaGFzIGEgQysrIG91dHB1dCBvcHRpb24sIGJ1dCBpdCdzIHN0aWxsIHJpZGljdWxvdXNseSB1Z2x5LCBub24tYWJzdHJhY3QsCisvLyBhbmQgbm90IGxpYnJhcnktZnJpZW5kbHkuKQorLy8KKy8vIFRoZSBuZXh0IGFwcHJvYWNoIHRoYXQgYW55IGdvb2Qgc29mdHdhcmUgZW5naW5lZXIgc2hvdWxkIGxvb2sgYXQgaXMgdG8KKy8vIHVzZSByZWd1bGFyIGV4cHJlc3Npb25zLiAgQW5kLCBpbmRlZWQsIEkgZGlkLiAgSSBoYXZlIGNvZGUgd2hpY2gKKy8vIGltcGxlbWVudHMgdGhpcyBzYW1lIGNsYXNzIHVzaW5nIHJlZ3VsYXIgZXhwcmVzc2lvbnMuICBJdCdzIGFib3V0IDIwMAorLy8gbGluZXMgc2hvcnRlci4gIEhvd2V2ZXI6CisvLyAtIFJhdGhlciB0aGFuIGVycm9yIG1lc3NhZ2VzIHRlbGxpbmcgeW91ICJUaGlzIHN0cmluZyBoYXMgYW4gaW52YWxpZAorLy8gICBlc2NhcGUgc2VxdWVuY2UgYXQgbGluZSA1LCBjb2x1bW4gNDUiLCB5b3UgZ2V0IGVycm9yIG1lc3NhZ2VzIGxpa2UKKy8vICAgIlBhcnNlIGVycm9yIG9uIGxpbmUgNSIuICBHaXZpbmcgbW9yZSBwcmVjaXNlIGVycm9ycyByZXF1aXJlcyBhZGRpbmcKKy8vICAgYSBsb3Qgb2YgY29kZSB0aGF0IGVuZHMgdXAgYmFzaWNhbGx5IGFzIGNvbXBsZXggYXMgdGhlIGhhbmQtY29kZWQKKy8vICAgdmVyc2lvbiBhbnl3YXkuCisvLyAtIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWF0Y2ggYSBzdHJpbmcgbGl0ZXJhbCBsb29rcyBsaWtlIHRoaXM6CisvLyAgICAga1N0cmluZyAgPSBuZXcgUkUoIihcIihbXlwiXFxcXF18IiAgICAgICAgICAgICAgLy8gbm9uLWVzY2FwZWQKKy8vICAgICAgICAgICAgICAgICAgICAgICAiXFxcXFthYmZucnR2P1wiJ1xcXFwwLTddfCIgICAvLyBub3JtYWwgZXNjYXBlCisvLyAgICAgICAgICAgICAgICAgICAgICAgIlxcXFx4WzAtOWEtZkEtRl0pKlwifCIgICAgICAgLy8gaGV4IGVzY2FwZQorLy8gICAgICAgICAgICAgICAgICAgICAgICJcJyhbXlwnXFxcXF18IiAgICAgICAgLy8gQWxzbyBzdXBwb3J0IHNpbmdsZS1xdW90ZXMuCisvLyAgICAgICAgICAgICAgICAgICAgICAgIlxcXFxbYWJmbnJ0dj9cIidcXFxcMC03XXwiCisvLyAgICAgICAgICAgICAgICAgICAgICAgIlxcXFx4WzAtOWEtZkEtRl0pKlwnKSIpOworLy8gICBWZXJpZnlpbmcgdGhlIGNvcnJlY3RuZXNzIG9mIHRoaXMgbGluZSBub2lzZSBpcyBhY3R1YWxseSBoYXJkZXIgdGhhbgorLy8gICB2ZXJpZnlpbmcgdGhlIGNvcnJlY3RuZXNzIG9mIENvbnN1bWVTdHJpbmcoKSwgZGVmaW5lZCBiZWxvdy4gIEknbSBub3QKKy8vICAgZXZlbiBjb25maWRlbnQgdGhhdCB0aGUgYWJvdmUgaXMgY29ycmVjdCwgYWZ0ZXIgc3RhcmluZyBhdCBpdCBmb3Igc29tZQorLy8gICB0aW1lLgorLy8gLSBQQ1JFIGlzIGZhc3QsIGJ1dCB0aGVyZSdzIHN0aWxsIG1vcmUgb3ZlcmhlYWQgaW52b2x2ZWQgdGhhbiB0aGUgY29kZQorLy8gICBiZWxvdy4KKy8vIC0gU2FkbHksIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXJlIG5vdCBwYXJ0IG9mIHRoZSBDIHN0YW5kYXJkIGxpYnJhcnksIHNvCisvLyAgIHVzaW5nIHRoZW0gd291bGQgcmVxdWlyZSBkZXBlbmRpbmcgb24gc29tZSBvdGhlciBsaWJyYXJ5LiAgRm9yIHRoZQorLy8gICBvcGVuIHNvdXJjZSByZWxlYXNlLCB0aGlzIGNvdWxkIGJlIHJlYWxseSBhbm5veWluZy4gIE5vYm9keSBsaWtlcworLy8gICBkb3dubG9hZGluZyBvbmUgcGllY2Ugb2Ygc29mdHdhcmUganVzdCB0byBmaW5kIHRoYXQgdGhleSBuZWVkIHRvCisvLyAgIGRvd25sb2FkIHNvbWV0aGluZyBlbHNlIHRvIG1ha2UgaXQgd29yaywgYW5kIGluIGFsbCBsaWtlbGlob29kCisvLyAgIHBlb3BsZSBkb3dubG9hZGluZyBQcm90b2NvbCBCdWZmZXJzIHdpbGwgYWxyZWFkeSBiZSBkb2luZyBzbyBqdXN0CisvLyAgIHRvIG1ha2Ugc29tZXRoaW5nIGVsc2Ugd29yay4gIFdlIGNvdWxkIGluY2x1ZGUgYSBjb3B5IG9mIFBDUkUgd2l0aAorLy8gICBvdXIgY29kZSwgYnV0IHRoYXQgb2JsaWdhdGVzIHVzIHRvIGtlZXAgaXQgdXAtdG8tZGF0ZSBhbmQganVzdCBzZWVtcworLy8gICBsaWtlIGEgYmlnIHdhc3RlIGp1c3QgdG8gc2F2ZSAyMDAgbGluZXMgb2YgY29kZS4KKy8vCisvLyBPbiBhIHNpbWlsYXIgYnV0IHVucmVsYXRlZCBub3RlLCBJJ20gZXZlbiBzY2FyZWQgdG8gdXNlIGN0eXBlLmguCisvLyBBcHBhcmVudGx5IGZ1bmN0aW9ucyBsaWtlIGlzYWxwaGEoKSBhcmUgbG9jYWxlLWRlcGVuZGVudC4gIFNvLCBpZiB3ZSB1c2VkCisvLyB0aGF0LCB0aGVuIGlmIHRoaXMgY29kZSBpcyBiZWluZyBjYWxsZWQgZnJvbSBzb21lIHByb2dyYW0gdGhhdCBkb2Vzbid0CisvLyBoYXZlIGl0cyBsb2NhbGUgc2V0IHRvICJDIiwgaXQgd291bGQgYmVoYXZlIHN0cmFuZ2VseS4gIFdlIGNhbid0IGp1c3Qgc2V0CisvLyB0aGUgbG9jYWxlIHRvICJDIiBvdXJzZWx2ZXMgc2luY2Ugd2UgbWlnaHQgYnJlYWsgdGhlIGNhbGxpbmcgcHJvZ3JhbSB0aGF0CisvLyB3YXksIHBhcnRpY3VsYXJseSBpZiBpdCBpcyBtdWx0aS10aHJlYWRlZC4gIFdURj8gIFNvbWVvbmUgcGxlYXNlIGxldCBtZQorLy8gKEtlbnRvbikga25vdyBpZiBJJ20gbWlzc2luZyBzb21ldGhpbmcgaGVyZS4uLgorLy8KKy8vIEknZCBsb3ZlIHRvIGhlYXIgYWJvdXQgb3RoZXIgYWx0ZXJuYXRpdmVzLCB0aG91Z2gsIGFzIHRoaXMgY29kZSBpc24ndAorLy8gZXhhY3RseSBwcmV0dHkuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworbmFtZXNwYWNlIHsKKworLy8gQXMgbWVudGlvbmVkIGFib3ZlLCBJIGRvbid0IHRydXN0IGN0eXBlLmggZHVlIHRvIHRoZSBwcmVzZW5jZSBvZiAibG9jYWxlcyIuCisvLyBTbywgSSBoYXZlIHdyaXR0ZW4gcmVwbGFjZW1lbnQgZnVuY3Rpb25zIGhlcmUuICBTb21lb25lIHBsZWFzZSBzbWFjayBtZSBpZgorLy8gdGhpcyBpcyBhIGJhZCBpZGVhIG9yIGlmIHRoZXJlIGlzIHNvbWUgd2F5IGFyb3VuZCB0aGlzLgorLy8KKy8vIFRoZXNlICJjaGFyYWN0ZXIgY2xhc3NlcyIgYXJlIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW4gdGVtcGxhdGUgbWV0aG9kcy4KKy8vIEZvciBpbnN0YW5jZSwgVG9rZW5pemVyOjpDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlPigpIHdpbGwgZWF0CisvLyB3aGl0ZXNwYWNlLgorCisvLyBOb3RlOiAgTm8gY2xhc3MgaXMgYWxsb3dlZCB0byBjb250YWluICdcMCcsIHNpbmNlIHRoaXMgaXMgdXNlZCB0byBtYXJrIGVuZC0KKy8vICAgb2YtaW5wdXQgYW5kIGlzIGhhbmRsZWQgc3BlY2lhbGx5LgorCisjZGVmaW5lIENIQVJBQ1RFUl9DTEFTUyhOQU1FLCBFWFBSRVNTSU9OKSAgICAgIFwKKyAgY2xhc3MgTkFNRSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgcHVibGljOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGlubGluZSBib29sIEluQ2xhc3MoY2hhciBjKSB7ICAgICAgIFwKKyAgICAgIHJldHVybiBFWFBSRVNTSU9OOyAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKworQ0hBUkFDVEVSX0NMQVNTKFdoaXRlc3BhY2UsIGMgPT0gJyAnIHx8IGMgPT0gJ1xuJyB8fCBjID09ICdcdCcgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID09ICdccicgfHwgYyA9PSAnXHYnIHx8IGMgPT0gJ1xmJyk7CitDSEFSQUNURVJfQ0xBU1MoV2hpdGVzcGFjZU5vTmV3bGluZSwgYyA9PSAnICcgfHwgYyA9PSAnXHQnIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyA9PSAnXHInIHx8IGMgPT0gJ1x2JyB8fCBjID09ICdcZicpOworCitDSEFSQUNURVJfQ0xBU1MoVW5wcmludGFibGUsIGMgPCAnICcgJiYgYyA+ICdcMCcpOworCitDSEFSQUNURVJfQ0xBU1MoRGlnaXQsICcwJyA8PSBjICYmIGMgPD0gJzknKTsKK0NIQVJBQ1RFUl9DTEFTUyhPY3RhbERpZ2l0LCAnMCcgPD0gYyAmJiBjIDw9ICc3Jyk7CitDSEFSQUNURVJfQ0xBU1MoSGV4RGlnaXQsICgnMCcgPD0gYyAmJiBjIDw9ICc5JykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKCdhJyA8PSBjICYmIGMgPD0gJ2YnKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAoJ0EnIDw9IGMgJiYgYyA8PSAnRicpKTsKKworQ0hBUkFDVEVSX0NMQVNTKExldHRlciwgKCdhJyA8PSBjICYmIGMgPD0gJ3onKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgKCdBJyA8PSBjICYmIGMgPD0gJ1onKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgKGMgPT0gJ18nKSk7CisKK0NIQVJBQ1RFUl9DTEFTUyhBbHBoYW51bWVyaWMsICgnYScgPD0gYyAmJiBjIDw9ICd6JykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgnQScgPD0gYyAmJiBjIDw9ICdaJykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgnMCcgPD0gYyAmJiBjIDw9ICc5JykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjID09ICdfJykpOworCitDSEFSQUNURVJfQ0xBU1MoRXNjYXBlLCBjID09ICdhJyB8fCBjID09ICdiJyB8fCBjID09ICdmJyB8fCBjID09ICduJyB8fAorICAgICAgICAgICAgICAgICAgICAgICAgYyA9PSAncicgfHwgYyA9PSAndCcgfHwgYyA9PSAndicgfHwgYyA9PSAnXFwnIHx8CisgICAgICAgICAgICAgICAgICAgICAgICBjID09ICc/JyB8fCBjID09ICdcJycgfHwgYyA9PSAnXCInKTsKKworI3VuZGVmIENIQVJBQ1RFUl9DTEFTUworCisvLyBHaXZlbiBhIGNoYXIsIGludGVycHJldCBpdCBhcyBhIG51bWVyaWMgZGlnaXQgYW5kIHJldHVybiBpdHMgdmFsdWUuCisvLyBUaGlzIHN1cHBvcnRzIGFueSBudW1iZXIgYmFzZSB1cCB0byAzNi4KK2lubGluZSBpbnQgRGlnaXRWYWx1ZShjaGFyIGRpZ2l0KSB7CisgIGlmICgnMCcgPD0gZGlnaXQgJiYgZGlnaXQgPD0gJzknKSByZXR1cm4gZGlnaXQgLSAnMCc7CisgIGlmICgnYScgPD0gZGlnaXQgJiYgZGlnaXQgPD0gJ3onKSByZXR1cm4gZGlnaXQgLSAnYScgKyAxMDsKKyAgaWYgKCdBJyA8PSBkaWdpdCAmJiBkaWdpdCA8PSAnWicpIHJldHVybiBkaWdpdCAtICdBJyArIDEwOworICByZXR1cm4gLTE7Cit9CisKKy8vIElubGluZSBiZWNhdXNlIGl0J3Mgb25seSB1c2VkIGluIG9uZSBwbGFjZS4KK2lubGluZSBjaGFyIFRyYW5zbGF0ZUVzY2FwZShjaGFyIGMpIHsKKyAgc3dpdGNoIChjKSB7CisgICAgY2FzZSAnYSc6ICByZXR1cm4gJ1xhJzsKKyAgICBjYXNlICdiJzogIHJldHVybiAnXGInOworICAgIGNhc2UgJ2YnOiAgcmV0dXJuICdcZic7CisgICAgY2FzZSAnbic6ICByZXR1cm4gJ1xuJzsKKyAgICBjYXNlICdyJzogIHJldHVybiAnXHInOworICAgIGNhc2UgJ3QnOiAgcmV0dXJuICdcdCc7CisgICAgY2FzZSAndic6ICByZXR1cm4gJ1x2JzsKKyAgICBjYXNlICdcXCc6IHJldHVybiAnXFwnOworICAgIGNhc2UgJz8nOiAgcmV0dXJuICdcPyc7ICAgIC8vIFRyaWdyYXBocyA9IDooCisgICAgY2FzZSAnXCcnOiByZXR1cm4gJ1wnJzsKKyAgICBjYXNlICciJzogIHJldHVybiAnXCInOworCisgICAgLy8gV2UgZXhwZWN0IGVzY2FwZSBzZXF1ZW5jZXMgdG8gaGF2ZSBiZWVuIHZhbGlkYXRlZCBzZXBhcmF0ZWx5LgorICAgIGRlZmF1bHQ6ICAgcmV0dXJuICc/JzsKKyAgfQorfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK0Vycm9yQ29sbGVjdG9yOjp+RXJyb3JDb2xsZWN0b3IoKSB7fQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1Rva2VuaXplcjo6VG9rZW5pemVyKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3RvcikKKyAgOiBpbnB1dF8oaW5wdXQpLAorICAgIGVycm9yX2NvbGxlY3Rvcl8oZXJyb3JfY29sbGVjdG9yKSwKKyAgICBidWZmZXJfKE5VTEwpLAorICAgIGJ1ZmZlcl9zaXplXygwKSwKKyAgICBidWZmZXJfcG9zXygwKSwKKyAgICByZWFkX2Vycm9yXyhmYWxzZSksCisgICAgbGluZV8oMCksCisgICAgY29sdW1uXygwKSwKKyAgICByZWNvcmRfdGFyZ2V0XyhOVUxMKSwKKyAgICByZWNvcmRfc3RhcnRfKC0xKSwKKyAgICBhbGxvd19mX2FmdGVyX2Zsb2F0XyhmYWxzZSksCisgICAgY29tbWVudF9zdHlsZV8oQ1BQX0NPTU1FTlRfU1RZTEUpLAorICAgIHJlcXVpcmVfc3BhY2VfYWZ0ZXJfbnVtYmVyXyh0cnVlKSwKKyAgICBhbGxvd19tdWx0aWxpbmVfc3RyaW5nc18oZmFsc2UpIHsKKworICBjdXJyZW50Xy5saW5lID0gMDsKKyAgY3VycmVudF8uY29sdW1uID0gMDsKKyAgY3VycmVudF8uZW5kX2NvbHVtbiA9IDA7CisgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NUQVJUOworCisgIFJlZnJlc2goKTsKK30KKworVG9rZW5pemVyOjp+VG9rZW5pemVyKCkgeworICAvLyBJZiB3ZSBoYWQgYW55IGJ1ZmZlciBsZWZ0IHVucmVhZCwgcmV0dXJuIGl0IHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbQorICAvLyBzbyB0aGF0IHNvbWVvbmUgZWxzZSBjYW4gcmVhZCBpdC4KKyAgaWYgKGJ1ZmZlcl9zaXplXyA+IGJ1ZmZlcl9wb3NfKSB7CisgICAgaW5wdXRfLT5CYWNrVXAoYnVmZmVyX3NpemVfIC0gYnVmZmVyX3Bvc18pOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEludGVybmFsIGhlbHBlcnMuCisKK3ZvaWQgVG9rZW5pemVyOjpOZXh0Q2hhcigpIHsKKyAgLy8gVXBkYXRlIG91ciBsaW5lIGFuZCBjb2x1bW4gY291bnRlcnMgYmFzZWQgb24gdGhlIGNoYXJhY3RlciBiZWluZworICAvLyBjb25zdW1lZC4KKyAgaWYgKGN1cnJlbnRfY2hhcl8gPT0gJ1xuJykgeworICAgICsrbGluZV87CisgICAgY29sdW1uXyA9IDA7CisgIH0gZWxzZSBpZiAoY3VycmVudF9jaGFyXyA9PSAnXHQnKSB7CisgICAgY29sdW1uXyArPSBrVGFiV2lkdGggLSBjb2x1bW5fICUga1RhYldpZHRoOworICB9IGVsc2UgeworICAgICsrY29sdW1uXzsKKyAgfQorCisgIC8vIEFkdmFuY2UgdG8gdGhlIG5leHQgY2hhcmFjdGVyLgorICArK2J1ZmZlcl9wb3NfOworICBpZiAoYnVmZmVyX3Bvc18gPCBidWZmZXJfc2l6ZV8pIHsKKyAgICBjdXJyZW50X2NoYXJfID0gYnVmZmVyX1tidWZmZXJfcG9zX107CisgIH0gZWxzZSB7CisgICAgUmVmcmVzaCgpOworICB9Cit9CisKK3ZvaWQgVG9rZW5pemVyOjpSZWZyZXNoKCkgeworICBpZiAocmVhZF9lcnJvcl8pIHsKKyAgICBjdXJyZW50X2NoYXJfID0gJ1wwJzsKKyAgICByZXR1cm47CisgIH0KKworICAvLyBJZiB3ZSdyZSBpbiBhIHRva2VuLCBhcHBlbmQgdGhlIHJlc3Qgb2YgdGhlIGJ1ZmZlciB0byBpdC4KKyAgaWYgKHJlY29yZF90YXJnZXRfICE9IE5VTEwgJiYgcmVjb3JkX3N0YXJ0XyA8IGJ1ZmZlcl9zaXplXykgeworICAgIHJlY29yZF90YXJnZXRfLT5hcHBlbmQoYnVmZmVyXyArIHJlY29yZF9zdGFydF8sIGJ1ZmZlcl9zaXplXyAtIHJlY29yZF9zdGFydF8pOworICAgIHJlY29yZF9zdGFydF8gPSAwOworICB9CisKKyAgY29uc3Qgdm9pZCogZGF0YSA9IE5VTEw7CisgIGJ1ZmZlcl8gPSBOVUxMOworICBidWZmZXJfcG9zXyA9IDA7CisgIGRvIHsKKyAgICBpZiAoIWlucHV0Xy0+TmV4dCgmZGF0YSwgJmJ1ZmZlcl9zaXplXykpIHsKKyAgICAgIC8vIGVuZCBvZiBzdHJlYW0gKG9yIHJlYWQgZXJyb3IpCisgICAgICBidWZmZXJfc2l6ZV8gPSAwOworICAgICAgcmVhZF9lcnJvcl8gPSB0cnVlOworICAgICAgY3VycmVudF9jaGFyXyA9ICdcMCc7CisgICAgICByZXR1cm47CisgICAgfQorICB9IHdoaWxlIChidWZmZXJfc2l6ZV8gPT0gMCk7CisKKyAgYnVmZmVyXyA9IHN0YXRpY19jYXN0PGNvbnN0IGNoYXIqPihkYXRhKTsKKworICBjdXJyZW50X2NoYXJfID0gYnVmZmVyX1swXTsKK30KKworaW5saW5lIHZvaWQgVG9rZW5pemVyOjpSZWNvcmRUbyhzdHJpbmcqIHRhcmdldCkgeworICByZWNvcmRfdGFyZ2V0XyA9IHRhcmdldDsKKyAgcmVjb3JkX3N0YXJ0XyA9IGJ1ZmZlcl9wb3NfOworfQorCitpbmxpbmUgdm9pZCBUb2tlbml6ZXI6OlN0b3BSZWNvcmRpbmcoKSB7CisgIC8vIE5vdGU6ICBUaGUgaWYoKSBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzb21lIFNUTCBpbXBsZW1lbnRhdGlvbnMgY3Jhc2ggd2hlbgorICAvLyAgIHlvdSBjYWxsIHN0cmluZzo6YXBwZW5kKE5VTEwsIDApLCBwcmVzdW1hYmx5IGJlY2F1c2UgdGhleSBhcmUgdHJ5aW5nIHRvCisgIC8vICAgYmUgaGVscGZ1bCBieSBkZXRlY3RpbmcgdGhlIE5VTEwgcG9pbnRlciwgZXZlbiB0aG91Z2ggdGhlcmUncyBub3RoaW5nCisgIC8vICAgd3Jvbmcgd2l0aCByZWFkaW5nIHplcm8gYnl0ZXMgZnJvbSBOVUxMLgorICBpZiAoYnVmZmVyX3Bvc18gIT0gcmVjb3JkX3N0YXJ0XykgeworICAgIHJlY29yZF90YXJnZXRfLT5hcHBlbmQoYnVmZmVyXyArIHJlY29yZF9zdGFydF8sIGJ1ZmZlcl9wb3NfIC0gcmVjb3JkX3N0YXJ0Xyk7CisgIH0KKyAgcmVjb3JkX3RhcmdldF8gPSBOVUxMOworICByZWNvcmRfc3RhcnRfID0gLTE7Cit9CisKK2lubGluZSB2b2lkIFRva2VuaXplcjo6U3RhcnRUb2tlbigpIHsKKyAgY3VycmVudF8udHlwZSA9IFRZUEVfU1RBUlQ7ICAgIC8vIEp1c3QgZm9yIHRoZSBzYWtlIG9mIGluaXRpYWxpemluZyBpdC4KKyAgY3VycmVudF8udGV4dC5jbGVhcigpOworICBjdXJyZW50Xy5saW5lID0gbGluZV87CisgIGN1cnJlbnRfLmNvbHVtbiA9IGNvbHVtbl87CisgIFJlY29yZFRvKCZjdXJyZW50Xy50ZXh0KTsKK30KKworaW5saW5lIHZvaWQgVG9rZW5pemVyOjpFbmRUb2tlbigpIHsKKyAgU3RvcFJlY29yZGluZygpOworICBjdXJyZW50Xy5lbmRfY29sdW1uID0gY29sdW1uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gSGVscGVyIG1ldGhvZHMgdGhhdCBjb25zdW1lIGNoYXJhY3RlcnMuCisKK3RlbXBsYXRlPHR5cGVuYW1lIENoYXJhY3RlckNsYXNzPgoraW5saW5lIGJvb2wgVG9rZW5pemVyOjpMb29raW5nQXQoKSB7CisgIHJldHVybiBDaGFyYWN0ZXJDbGFzczo6SW5DbGFzcyhjdXJyZW50X2NoYXJfKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgQ2hhcmFjdGVyQ2xhc3M+CitpbmxpbmUgYm9vbCBUb2tlbml6ZXI6OlRyeUNvbnN1bWVPbmUoKSB7CisgIGlmIChDaGFyYWN0ZXJDbGFzczo6SW5DbGFzcyhjdXJyZW50X2NoYXJfKSkgeworICAgIE5leHRDaGFyKCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2lubGluZSBib29sIFRva2VuaXplcjo6VHJ5Q29uc3VtZShjaGFyIGMpIHsKKyAgaWYgKGN1cnJlbnRfY2hhcl8gPT0gYykgeworICAgIE5leHRDaGFyKCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIENoYXJhY3RlckNsYXNzPgoraW5saW5lIHZvaWQgVG9rZW5pemVyOjpDb25zdW1lWmVyb09yTW9yZSgpIHsKKyAgd2hpbGUgKENoYXJhY3RlckNsYXNzOjpJbkNsYXNzKGN1cnJlbnRfY2hhcl8pKSB7CisgICAgTmV4dENoYXIoKTsKKyAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KK2lubGluZSB2b2lkIFRva2VuaXplcjo6Q29uc3VtZU9uZU9yTW9yZShjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoIUNoYXJhY3RlckNsYXNzOjpJbkNsYXNzKGN1cnJlbnRfY2hhcl8pKSB7CisgICAgQWRkRXJyb3IoZXJyb3IpOworICB9IGVsc2UgeworICAgIGRvIHsKKyAgICAgIE5leHRDaGFyKCk7CisgICAgfSB3aGlsZSAoQ2hhcmFjdGVyQ2xhc3M6OkluQ2xhc3MoY3VycmVudF9jaGFyXykpOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1ldGhvZHMgdGhhdCByZWFkIHdob2xlIHBhdHRlcm5zIG1hdGNoaW5nIGNlcnRhaW4ga2luZHMgb2YgdG9rZW5zCisvLyBvciBjb21tZW50cy4KKwordm9pZCBUb2tlbml6ZXI6OkNvbnN1bWVTdHJpbmcoY2hhciBkZWxpbWl0ZXIpIHsKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBzd2l0Y2ggKGN1cnJlbnRfY2hhcl8pIHsKKyAgICAgIGNhc2UgJ1wwJzoKKyAgICAgICAgQWRkRXJyb3IoIlVuZXhwZWN0ZWQgZW5kIG9mIHN0cmluZy4iKTsKKyAgICAgICAgcmV0dXJuOworCisgICAgICBjYXNlICdcbic6IHsKKyAgICAgICAgaWYgKCFhbGxvd19tdWx0aWxpbmVfc3RyaW5nc18pIHsKKyAgICAgICAgICBBZGRFcnJvcigiU3RyaW5nIGxpdGVyYWxzIGNhbm5vdCBjcm9zcyBsaW5lIGJvdW5kYXJpZXMuIik7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlICdcXCc6IHsKKyAgICAgICAgLy8gQW4gZXNjYXBlIHNlcXVlbmNlLgorICAgICAgICBOZXh0Q2hhcigpOworICAgICAgICBpZiAoVHJ5Q29uc3VtZU9uZTxFc2NhcGU+KCkpIHsKKyAgICAgICAgICAvLyBWYWxpZCBlc2NhcGUgc2VxdWVuY2UuCisgICAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZU9uZTxPY3RhbERpZ2l0PigpKSB7CisgICAgICAgICAgLy8gUG9zc2libHkgZm9sbG93ZWQgYnkgdHdvIG1vcmUgb2N0YWwgZGlnaXRzLCBidXQgdGhlc2Ugd2lsbAorICAgICAgICAgIC8vIGp1c3QgYmUgY29uc3VtZWQgYnkgdGhlIG1haW4gbG9vcCBhbnl3YXkgc28gd2UgZG9uJ3QgbmVlZAorICAgICAgICAgIC8vIHRvIGRvIHNvIGV4cGxpY2l0bHkgaGVyZS4KKyAgICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCd4JykgfHwgVHJ5Q29uc3VtZSgnWCcpKSB7CisgICAgICAgICAgaWYgKCFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpKSB7CisgICAgICAgICAgICBBZGRFcnJvcigiRXhwZWN0ZWQgaGV4IGRpZ2l0cyBmb3IgZXNjYXBlIHNlcXVlbmNlLiIpOworICAgICAgICAgIH0KKyAgICAgICAgICAvLyBQb3NzaWJseSBmb2xsb3dlZCBieSBhbm90aGVyIGhleCBkaWdpdCwgYnV0IGFnYWluIHdlIGRvbid0IGNhcmUuCisgICAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgndScpKSB7CisgICAgICAgICAgaWYgKCFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpIHx8CisgICAgICAgICAgICAgICFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpIHx8CisgICAgICAgICAgICAgICFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpIHx8CisgICAgICAgICAgICAgICFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpKSB7CisgICAgICAgICAgICBBZGRFcnJvcigiRXhwZWN0ZWQgZm91ciBoZXggZGlnaXRzIGZvciBcXHUgZXNjYXBlIHNlcXVlbmNlLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCdVJykpIHsKKyAgICAgICAgICAvLyBXZSBleHBlY3QgOCBoZXggZGlnaXRzOyBidXQgb25seSB0aGUgcmFuZ2UgdXAgdG8gMHgxMGZmZmYgaXMKKyAgICAgICAgICAvLyBsZWdhbC4KKyAgICAgICAgICBpZiAoIVRyeUNvbnN1bWUoJzAnKSB8fAorICAgICAgICAgICAgICAhVHJ5Q29uc3VtZSgnMCcpIHx8CisgICAgICAgICAgICAgICEoVHJ5Q29uc3VtZSgnMCcpIHx8IFRyeUNvbnN1bWUoJzEnKSkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkpIHsKKyAgICAgICAgICAgIEFkZEVycm9yKCJFeHBlY3RlZCBlaWdodCBoZXggZGlnaXRzIHVwIHRvIDEwZmZmZiBmb3IgXFxVIGVzY2FwZSAiCisgICAgICAgICAgICAgICAgICAgICAic2VxdWVuY2UiKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgQWRkRXJyb3IoIkludmFsaWQgZXNjYXBlIHNlcXVlbmNlIGluIHN0cmluZyBsaXRlcmFsLiIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICAgIGlmIChjdXJyZW50X2NoYXJfID09IGRlbGltaXRlcikgeworICAgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitUb2tlbml6ZXI6OlRva2VuVHlwZSBUb2tlbml6ZXI6OkNvbnN1bWVOdW1iZXIoYm9vbCBzdGFydGVkX3dpdGhfemVybywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHN0YXJ0ZWRfd2l0aF9kb3QpIHsKKyAgYm9vbCBpc19mbG9hdCA9IGZhbHNlOworCisgIGlmIChzdGFydGVkX3dpdGhfemVybyAmJiAoVHJ5Q29uc3VtZSgneCcpIHx8IFRyeUNvbnN1bWUoJ1gnKSkpIHsKKyAgICAvLyBBIGhleCBudW1iZXIgKHN0YXJ0ZWQgd2l0aCAiMHgiKS4KKyAgICBDb25zdW1lT25lT3JNb3JlPEhleERpZ2l0PigiXCIweFwiIG11c3QgYmUgZm9sbG93ZWQgYnkgaGV4IGRpZ2l0cy4iKTsKKworICB9IGVsc2UgaWYgKHN0YXJ0ZWRfd2l0aF96ZXJvICYmIExvb2tpbmdBdDxEaWdpdD4oKSkgeworICAgIC8vIEFuIG9jdGFsIG51bWJlciAoaGFkIGEgbGVhZGluZyB6ZXJvKS4KKyAgICBDb25zdW1lWmVyb09yTW9yZTxPY3RhbERpZ2l0PigpOworICAgIGlmIChMb29raW5nQXQ8RGlnaXQ+KCkpIHsKKyAgICAgIEFkZEVycm9yKCJOdW1iZXJzIHN0YXJ0aW5nIHdpdGggbGVhZGluZyB6ZXJvIG11c3QgYmUgaW4gb2N0YWwuIik7CisgICAgICBDb25zdW1lWmVyb09yTW9yZTxEaWdpdD4oKTsKKyAgICB9CisKKyAgfSBlbHNlIHsKKyAgICAvLyBBIGRlY2ltYWwgbnVtYmVyLgorICAgIGlmIChzdGFydGVkX3dpdGhfZG90KSB7CisgICAgICBpc19mbG9hdCA9IHRydWU7CisgICAgICBDb25zdW1lWmVyb09yTW9yZTxEaWdpdD4oKTsKKyAgICB9IGVsc2UgeworICAgICAgQ29uc3VtZVplcm9Pck1vcmU8RGlnaXQ+KCk7CisKKyAgICAgIGlmIChUcnlDb25zdW1lKCcuJykpIHsKKyAgICAgICAgaXNfZmxvYXQgPSB0cnVlOworICAgICAgICBDb25zdW1lWmVyb09yTW9yZTxEaWdpdD4oKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoVHJ5Q29uc3VtZSgnZScpIHx8IFRyeUNvbnN1bWUoJ0UnKSkgeworICAgICAgaXNfZmxvYXQgPSB0cnVlOworICAgICAgVHJ5Q29uc3VtZSgnLScpIHx8IFRyeUNvbnN1bWUoJysnKTsKKyAgICAgIENvbnN1bWVPbmVPck1vcmU8RGlnaXQ+KCJcImVcIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGV4cG9uZW50LiIpOworICAgIH0KKworICAgIGlmIChhbGxvd19mX2FmdGVyX2Zsb2F0XyAmJiAoVHJ5Q29uc3VtZSgnZicpIHx8IFRyeUNvbnN1bWUoJ0YnKSkpIHsKKyAgICAgIGlzX2Zsb2F0ID0gdHJ1ZTsKKyAgICB9CisgIH0KKworICBpZiAoTG9va2luZ0F0PExldHRlcj4oKSAmJiByZXF1aXJlX3NwYWNlX2FmdGVyX251bWJlcl8pIHsKKyAgICBBZGRFcnJvcigiTmVlZCBzcGFjZSBiZXR3ZWVuIG51bWJlciBhbmQgaWRlbnRpZmllci4iKTsKKyAgfSBlbHNlIGlmIChjdXJyZW50X2NoYXJfID09ICcuJykgeworICAgIGlmIChpc19mbG9hdCkgeworICAgICAgQWRkRXJyb3IoCisgICAgICAgICJBbHJlYWR5IHNhdyBkZWNpbWFsIHBvaW50IG9yIGV4cG9uZW50OyBjYW4ndCBoYXZlIGFub3RoZXIgb25lLiIpOworICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcigiSGV4IGFuZCBvY3RhbCBudW1iZXJzIG11c3QgYmUgaW50ZWdlcnMuIik7CisgICAgfQorICB9CisKKyAgcmV0dXJuIGlzX2Zsb2F0ID8gVFlQRV9GTE9BVCA6IFRZUEVfSU5URUdFUjsKK30KKwordm9pZCBUb2tlbml6ZXI6OkNvbnN1bWVMaW5lQ29tbWVudChzdHJpbmcqIGNvbnRlbnQpIHsKKyAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgUmVjb3JkVG8oY29udGVudCk7CisKKyAgd2hpbGUgKGN1cnJlbnRfY2hhcl8gIT0gJ1wwJyAmJiBjdXJyZW50X2NoYXJfICE9ICdcbicpIHsKKyAgICBOZXh0Q2hhcigpOworICB9CisgIFRyeUNvbnN1bWUoJ1xuJyk7CisKKyAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgU3RvcFJlY29yZGluZygpOworfQorCit2b2lkIFRva2VuaXplcjo6Q29uc3VtZUJsb2NrQ29tbWVudChzdHJpbmcqIGNvbnRlbnQpIHsKKyAgaW50IHN0YXJ0X2xpbmUgPSBsaW5lXzsKKyAgaW50IHN0YXJ0X2NvbHVtbiA9IGNvbHVtbl8gLSAyOworCisgIGlmIChjb250ZW50ICE9IE5VTEwpIFJlY29yZFRvKGNvbnRlbnQpOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgd2hpbGUgKGN1cnJlbnRfY2hhcl8gIT0gJ1wwJyAmJgorICAgICAgICAgICBjdXJyZW50X2NoYXJfICE9ICcqJyAmJgorICAgICAgICAgICBjdXJyZW50X2NoYXJfICE9ICcvJyAmJgorICAgICAgICAgICBjdXJyZW50X2NoYXJfICE9ICdcbicpIHsKKyAgICAgIE5leHRDaGFyKCk7CisgICAgfQorCisgICAgaWYgKFRyeUNvbnN1bWUoJ1xuJykpIHsKKyAgICAgIGlmIChjb250ZW50ICE9IE5VTEwpIFN0b3BSZWNvcmRpbmcoKTsKKworICAgICAgLy8gQ29uc3VtZSBsZWFkaW5nIHdoaXRlc3BhY2UgYW5kIGFzdGVyaXNrOworICAgICAgQ29uc3VtZVplcm9Pck1vcmU8V2hpdGVzcGFjZU5vTmV3bGluZT4oKTsKKyAgICAgIGlmIChUcnlDb25zdW1lKCcqJykpIHsKKyAgICAgICAgaWYgKFRyeUNvbnN1bWUoJy8nKSkgeworICAgICAgICAgIC8vIEVuZCBvZiBjb21tZW50LgorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChjb250ZW50ICE9IE5VTEwpIFJlY29yZFRvKGNvbnRlbnQpOworICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgnKicpICYmIFRyeUNvbnN1bWUoJy8nKSkgeworICAgICAgLy8gRW5kIG9mIGNvbW1lbnQuCisgICAgICBpZiAoY29udGVudCAhPSBOVUxMKSB7CisgICAgICAgIFN0b3BSZWNvcmRpbmcoKTsKKyAgICAgICAgLy8gU3RyaXAgdHJhaWxpbmcgIiovIi4KKyAgICAgICAgY29udGVudC0+ZXJhc2UoY29udGVudC0+c2l6ZSgpIC0gMik7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoJy8nKSAmJiBjdXJyZW50X2NoYXJfID09ICcqJykgeworICAgICAgLy8gTm90ZTogIFdlIGRpZG4ndCBjb25zdW1lIHRoZSAnKicgYmVjYXVzZSBpZiB0aGVyZSBpcyBhICcvJyBhZnRlciBpdAorICAgICAgLy8gICB3ZSB3YW50IHRvIGludGVycHJldCB0aGF0IGFzIHRoZSBlbmQgb2YgdGhlIGNvbW1lbnQuCisgICAgICBBZGRFcnJvcigKKyAgICAgICAgIlwiLypcIiBpbnNpZGUgYmxvY2sgY29tbWVudC4gIEJsb2NrIGNvbW1lbnRzIGNhbm5vdCBiZSBuZXN0ZWQuIik7CisgICAgfSBlbHNlIGlmIChjdXJyZW50X2NoYXJfID09ICdcMCcpIHsKKyAgICAgIEFkZEVycm9yKCJFbmQtb2YtZmlsZSBpbnNpZGUgYmxvY2sgY29tbWVudC4iKTsKKyAgICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKAorICAgICAgICBzdGFydF9saW5lLCBzdGFydF9jb2x1bW4sICIgIENvbW1lbnQgc3RhcnRlZCBoZXJlLiIpOworICAgICAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgU3RvcFJlY29yZGluZygpOworICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CisKK1Rva2VuaXplcjo6TmV4dENvbW1lbnRTdGF0dXMgVG9rZW5pemVyOjpUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCkgeworICBpZiAoY29tbWVudF9zdHlsZV8gPT0gQ1BQX0NPTU1FTlRfU1RZTEUgJiYgVHJ5Q29uc3VtZSgnLycpKSB7CisgICAgaWYgKFRyeUNvbnN1bWUoJy8nKSkgeworICAgICAgcmV0dXJuIExJTkVfQ09NTUVOVDsKKyAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoJyonKSkgeworICAgICAgcmV0dXJuIEJMT0NLX0NPTU1FTlQ7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE9vcHMsIGl0IHdhcyBqdXN0IGEgc2xhc2guICBSZXR1cm4gaXQuCisgICAgICBjdXJyZW50Xy50eXBlID0gVFlQRV9TWU1CT0w7CisgICAgICBjdXJyZW50Xy50ZXh0ID0gIi8iOworICAgICAgY3VycmVudF8ubGluZSA9IGxpbmVfOworICAgICAgY3VycmVudF8uY29sdW1uID0gY29sdW1uXyAtIDE7CisgICAgICBjdXJyZW50Xy5lbmRfY29sdW1uID0gY29sdW1uXzsKKyAgICAgIHJldHVybiBTTEFTSF9OT1RfQ09NTUVOVDsKKyAgICB9CisgIH0gZWxzZSBpZiAoY29tbWVudF9zdHlsZV8gPT0gU0hfQ09NTUVOVF9TVFlMRSAmJiBUcnlDb25zdW1lKCcjJykpIHsKKyAgICByZXR1cm4gTElORV9DT01NRU5UOworICB9IGVsc2UgeworICAgIHJldHVybiBOT19DT01NRU5UOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworYm9vbCBUb2tlbml6ZXI6Ok5leHQoKSB7CisgIHByZXZpb3VzXyA9IGN1cnJlbnRfOworCisgIHdoaWxlICghcmVhZF9lcnJvcl8pIHsKKyAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlPigpOworCisgICAgc3dpdGNoIChUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCkpIHsKKyAgICAgIGNhc2UgTElORV9DT01NRU5UOgorICAgICAgICBDb25zdW1lTGluZUNvbW1lbnQoTlVMTCk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgY2FzZSBCTE9DS19DT01NRU5UOgorICAgICAgICBDb25zdW1lQmxvY2tDb21tZW50KE5VTEwpOworICAgICAgICBjb250aW51ZTsKKyAgICAgIGNhc2UgU0xBU0hfTk9UX0NPTU1FTlQ6CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgY2FzZSBOT19DT01NRU5UOgorICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICAvLyBDaGVjayBmb3IgRU9GIGJlZm9yZSBjb250aW51aW5nLgorICAgIGlmIChyZWFkX2Vycm9yXykgYnJlYWs7CisKKyAgICBpZiAoTG9va2luZ0F0PFVucHJpbnRhYmxlPigpIHx8IGN1cnJlbnRfY2hhcl8gPT0gJ1wwJykgeworICAgICAgQWRkRXJyb3IoIkludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuIik7CisgICAgICBOZXh0Q2hhcigpOworICAgICAgLy8gU2tpcCBtb3JlIHVucHJpbnRhYmxlIGNoYXJhY3RlcnMsIHRvby4gIEJ1dCwgcmVtZW1iZXIgdGhhdCAnXDAnIGlzCisgICAgICAvLyBhbHNvIHdoYXQgY3VycmVudF9jaGFyXyBpcyBzZXQgdG8gYWZ0ZXIgRU9GIC8gcmVhZCBlcnJvci4gIFdlIGhhdmUKKyAgICAgIC8vIHRvIGJlIGNhcmVmdWwgbm90IHRvIGdvIGludG8gYW4gaW5maW5pdGUgbG9vcCBvZiB0cnlpbmcgdG8gY29uc3VtZQorICAgICAgLy8gaXQsIHNvIG1ha2Ugc3VyZSB0byBjaGVjayByZWFkX2Vycm9yXyBleHBsaWNpdGx5IGJlZm9yZSBjb25zdW1pbmcKKyAgICAgIC8vICdcMCcuCisgICAgICB3aGlsZSAoVHJ5Q29uc3VtZU9uZTxVbnByaW50YWJsZT4oKSB8fAorICAgICAgICAgICAgICghcmVhZF9lcnJvcl8gJiYgVHJ5Q29uc3VtZSgnXDAnKSkpIHsKKyAgICAgICAgLy8gSWdub3JlLgorICAgICAgfQorCisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFJlYWRpbmcgc29tZSBzb3J0IG9mIHRva2VuLgorICAgICAgU3RhcnRUb2tlbigpOworCisgICAgICBpZiAoVHJ5Q29uc3VtZU9uZTxMZXR0ZXI+KCkpIHsKKyAgICAgICAgQ29uc3VtZVplcm9Pck1vcmU8QWxwaGFudW1lcmljPigpOworICAgICAgICBjdXJyZW50Xy50eXBlID0gVFlQRV9JREVOVElGSUVSOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCcwJykpIHsKKyAgICAgICAgY3VycmVudF8udHlwZSA9IENvbnN1bWVOdW1iZXIodHJ1ZSwgZmFsc2UpOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCcuJykpIHsKKyAgICAgICAgLy8gVGhpcyBjb3VsZCBiZSB0aGUgYmVnaW5uaW5nIG9mIGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyLCBvciBpdCBjb3VsZAorICAgICAgICAvLyBqdXN0IGJlIGEgJy4nIHN5bWJvbC4KKworICAgICAgICBpZiAoVHJ5Q29uc3VtZU9uZTxEaWdpdD4oKSkgeworICAgICAgICAgIC8vIEl0J3MgYSBmbG9hdGluZy1wb2ludCBudW1iZXIuCisgICAgICAgICAgaWYgKHByZXZpb3VzXy50eXBlID09IFRZUEVfSURFTlRJRklFUiAmJgorICAgICAgICAgICAgICBjdXJyZW50Xy5saW5lID09IHByZXZpb3VzXy5saW5lICYmCisgICAgICAgICAgICAgIGN1cnJlbnRfLmNvbHVtbiA9PSBwcmV2aW91c18uZW5kX2NvbHVtbikgeworICAgICAgICAgICAgLy8gV2UgZG9uJ3QgYWNjZXB0IHN5bnRheCBsaWtlICJibGFoLjEyMyIuCisgICAgICAgICAgICBlcnJvcl9jb2xsZWN0b3JfLT5BZGRFcnJvcihsaW5lXywgY29sdW1uXyAtIDIsCisgICAgICAgICAgICAgICJOZWVkIHNwYWNlIGJldHdlZW4gaWRlbnRpZmllciBhbmQgZGVjaW1hbCBwb2ludC4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgY3VycmVudF8udHlwZSA9IENvbnN1bWVOdW1iZXIoZmFsc2UsIHRydWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NZTUJPTDsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lT25lPERpZ2l0PigpKSB7CisgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBDb25zdW1lTnVtYmVyKGZhbHNlLCBmYWxzZSk7CisgICAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoJ1wiJykpIHsKKyAgICAgICAgQ29uc3VtZVN0cmluZygnXCInKTsKKyAgICAgICAgY3VycmVudF8udHlwZSA9IFRZUEVfU1RSSU5HOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCdcJycpKSB7CisgICAgICAgIENvbnN1bWVTdHJpbmcoJ1wnJyk7CisgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NUUklORzsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIENoZWNrIGlmIHRoZSBoaWdoIG9yZGVyIGJpdCBpcyBzZXQuCisgICAgICAgIGlmIChjdXJyZW50X2NoYXJfICYgMHg4MCkgeworICAgICAgICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGxpbmVfLCBjb2x1bW5fLAorICAgICAgICAgICAgICBTdHJpbmdQcmludGYoIkludGVycHJldGluZyBub24gYXNjaWkgY29kZXBvaW50ICVkLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihjdXJyZW50X2NoYXJfKSkpOworICAgICAgICB9CisgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NZTUJPTDsKKyAgICAgIH0KKworICAgICAgRW5kVG9rZW4oKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorCisgIC8vIEVPRgorICBjdXJyZW50Xy50eXBlID0gVFlQRV9FTkQ7CisgIGN1cnJlbnRfLnRleHQuY2xlYXIoKTsKKyAgY3VycmVudF8ubGluZSA9IGxpbmVfOworICBjdXJyZW50Xy5jb2x1bW4gPSBjb2x1bW5fOworICBjdXJyZW50Xy5lbmRfY29sdW1uID0gY29sdW1uXzsKKyAgcmV0dXJuIGZhbHNlOworfQorCituYW1lc3BhY2UgeworCisvLyBIZWxwZXIgY2xhc3MgZm9yIGNvbGxlY3RpbmcgY29tbWVudHMgYW5kIHB1dHRpbmcgdGhlbSBpbiB0aGUgcmlnaHQgcGxhY2VzLgorLy8KKy8vIFRoaXMgYmFzaWNhbGx5IGp1c3QgYnVmZmVycyB0aGUgbW9zdCByZWNlbnQgY29tbWVudCB1bnRpbCBpdCBjYW4gYmUgZGVjaWRlZAorLy8gZXhhY3RseSB3aGVyZSB0aGF0IGNvbW1lbnQgc2hvdWxkIGJlIHBsYWNlZC4gIFdoZW4gRmx1c2goKSBpcyBjYWxsZWQsIHRoZQorLy8gY3VycmVudCBjb21tZW50IGdvZXMgaW50byBlaXRoZXIgcHJldl90cmFpbGluZ19jb21tZW50cyBvciBkZXRhY2hlZF9jb21tZW50cy4KKy8vIFdoZW4gdGhlIENvbW1lbnRDb2xsZWN0b3IgaXMgZGVzdHJveWVkLCB0aGUgbGFzdCBidWZmZXJlZCBjb21tZW50IGdvZXMgaW50bworLy8gbmV4dF9sZWFkaW5nX2NvbW1lbnRzLgorY2xhc3MgQ29tbWVudENvbGxlY3RvciB7CisgcHVibGljOgorICBDb21tZW50Q29sbGVjdG9yKHN0cmluZyogcHJldl90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZGV0YWNoZWRfY29tbWVudHMsCisgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBuZXh0X2xlYWRpbmdfY29tbWVudHMpCisgICAgICA6IHByZXZfdHJhaWxpbmdfY29tbWVudHNfKHByZXZfdHJhaWxpbmdfY29tbWVudHMpLAorICAgICAgICBkZXRhY2hlZF9jb21tZW50c18oZGV0YWNoZWRfY29tbWVudHMpLAorICAgICAgICBuZXh0X2xlYWRpbmdfY29tbWVudHNfKG5leHRfbGVhZGluZ19jb21tZW50cyksCisgICAgICAgIGhhc19jb21tZW50XyhmYWxzZSksCisgICAgICAgIGlzX2xpbmVfY29tbWVudF8oZmFsc2UpLAorICAgICAgICBjYW5fYXR0YWNoX3RvX3ByZXZfKHRydWUpIHsKKyAgICBpZiAocHJldl90cmFpbGluZ19jb21tZW50cyAhPSBOVUxMKSBwcmV2X3RyYWlsaW5nX2NvbW1lbnRzLT5jbGVhcigpOworICAgIGlmIChkZXRhY2hlZF9jb21tZW50cyAhPSBOVUxMKSBkZXRhY2hlZF9jb21tZW50cy0+Y2xlYXIoKTsKKyAgICBpZiAobmV4dF9sZWFkaW5nX2NvbW1lbnRzICE9IE5VTEwpIG5leHRfbGVhZGluZ19jb21tZW50cy0+Y2xlYXIoKTsKKyAgfQorCisgIH5Db21tZW50Q29sbGVjdG9yKCkgeworICAgIC8vIFdoYXRldmVyIGlzIGluIHRoZSBidWZmZXIgaXMgYSBsZWFkaW5nIGNvbW1lbnQuCisgICAgaWYgKG5leHRfbGVhZGluZ19jb21tZW50c18gIT0gTlVMTCAmJiBoYXNfY29tbWVudF8pIHsKKyAgICAgIGNvbW1lbnRfYnVmZmVyXy5zd2FwKCpuZXh0X2xlYWRpbmdfY29tbWVudHNfKTsKKyAgICB9CisgIH0KKworICAvLyBBYm91dCB0byByZWFkIGEgbGluZSBjb21tZW50LiAgR2V0IHRoZSBjb21tZW50IGJ1ZmZlciBwb2ludGVyIGluIG9yZGVyIHRvCisgIC8vIHJlYWQgaW50byBpdC4KKyAgc3RyaW5nKiBHZXRCdWZmZXJGb3JMaW5lQ29tbWVudCgpIHsKKyAgICAvLyBXZSB3YW50IHRvIGNvbWJpbmUgd2l0aCBwcmV2aW91cyBsaW5lIGNvbW1lbnRzLCBidXQgbm90IGJsb2NrIGNvbW1lbnRzLgorICAgIGlmIChoYXNfY29tbWVudF8gJiYgIWlzX2xpbmVfY29tbWVudF8pIHsKKyAgICAgIEZsdXNoKCk7CisgICAgfQorICAgIGhhc19jb21tZW50XyA9IHRydWU7CisgICAgaXNfbGluZV9jb21tZW50XyA9IHRydWU7CisgICAgcmV0dXJuICZjb21tZW50X2J1ZmZlcl87CisgIH0KKworICAvLyBBYm91dCB0byByZWFkIGEgYmxvY2sgY29tbWVudC4gIEdldCB0aGUgY29tbWVudCBidWZmZXIgcG9pbnRlciBpbiBvcmRlciB0bworICAvLyByZWFkIGludG8gaXQuCisgIHN0cmluZyogR2V0QnVmZmVyRm9yQmxvY2tDb21tZW50KCkgeworICAgIGlmIChoYXNfY29tbWVudF8pIHsKKyAgICAgIEZsdXNoKCk7CisgICAgfQorICAgIGhhc19jb21tZW50XyA9IHRydWU7CisgICAgaXNfbGluZV9jb21tZW50XyA9IGZhbHNlOworICAgIHJldHVybiAmY29tbWVudF9idWZmZXJfOworICB9CisKKyAgdm9pZCBDbGVhckJ1ZmZlcigpIHsKKyAgICBjb21tZW50X2J1ZmZlcl8uY2xlYXIoKTsKKyAgICBoYXNfY29tbWVudF8gPSBmYWxzZTsKKyAgfQorCisgIC8vIENhbGxlZCBvbmNlIHdlIGtub3cgdGhhdCB0aGUgY29tbWVudCBidWZmZXIgaXMgY29tcGxldGUgYW5kIGlzICpub3QqCisgIC8vIGNvbm5lY3RlZCB0byB0aGUgbmV4dCB0b2tlbi4KKyAgdm9pZCBGbHVzaCgpIHsKKyAgICBpZiAoaGFzX2NvbW1lbnRfKSB7CisgICAgICBpZiAoY2FuX2F0dGFjaF90b19wcmV2XykgeworICAgICAgICBpZiAocHJldl90cmFpbGluZ19jb21tZW50c18gIT0gTlVMTCkgeworICAgICAgICAgIHByZXZfdHJhaWxpbmdfY29tbWVudHNfLT5hcHBlbmQoY29tbWVudF9idWZmZXJfKTsKKyAgICAgICAgfQorICAgICAgICBjYW5fYXR0YWNoX3RvX3ByZXZfID0gZmFsc2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoZGV0YWNoZWRfY29tbWVudHNfICE9IE5VTEwpIHsKKyAgICAgICAgICBkZXRhY2hlZF9jb21tZW50c18tPnB1c2hfYmFjayhjb21tZW50X2J1ZmZlcl8pOworICAgICAgICB9CisgICAgICB9CisgICAgICBDbGVhckJ1ZmZlcigpOworICAgIH0KKyAgfQorCisgIHZvaWQgRGV0YWNoRnJvbVByZXYoKSB7CisgICAgY2FuX2F0dGFjaF90b19wcmV2XyA9IGZhbHNlOworICB9CisKKyBwcml2YXRlOgorICBzdHJpbmcqIHByZXZfdHJhaWxpbmdfY29tbWVudHNfOworICB2ZWN0b3I8c3RyaW5nPiogZGV0YWNoZWRfY29tbWVudHNfOworICBzdHJpbmcqIG5leHRfbGVhZGluZ19jb21tZW50c187CisKKyAgc3RyaW5nIGNvbW1lbnRfYnVmZmVyXzsKKworICAvLyBUcnVlIGlmIGFueSBjb21tZW50cyB3ZXJlIHJlYWQgaW50byBjb21tZW50X2J1ZmZlcl8uICBUaGlzIGNhbiBiZSB0cnVlIGV2ZW4KKyAgLy8gaWYgY29tbWVudF9idWZmZXJfIGlzIGVtcHR5LCBuYW1lbHkgaWYgdGhlIGNvbW1lbnQgd2FzICIvKiovIi4KKyAgYm9vbCBoYXNfY29tbWVudF87CisKKyAgLy8gSXMgdGhlIGNvbW1lbnQgaW4gdGhlIGNvbW1lbnQgYnVmZmVyIGEgbGluZSBjb21tZW50PworICBib29sIGlzX2xpbmVfY29tbWVudF87CisKKyAgLy8gSXMgaXQgc3RpbGwgcG9zc2libGUgdGhhdCB3ZSBjb3VsZCBiZSByZWFkaW5nIGEgY29tbWVudCBhdHRhY2hlZCB0byB0aGUKKyAgLy8gcHJldmlvdXMgdG9rZW4/CisgIGJvb2wgY2FuX2F0dGFjaF90b19wcmV2XzsKK307CisKK30gLy8gbmFtZXNwYWNlCisKK2Jvb2wgVG9rZW5pemVyOjpOZXh0V2l0aENvbW1lbnRzKHN0cmluZyogcHJldl90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBkZXRhY2hlZF9jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogbmV4dF9sZWFkaW5nX2NvbW1lbnRzKSB7CisgIENvbW1lbnRDb2xsZWN0b3IgY29sbGVjdG9yKHByZXZfdHJhaWxpbmdfY29tbWVudHMsIGRldGFjaGVkX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0X2xlYWRpbmdfY29tbWVudHMpOworCisgIGlmIChjdXJyZW50Xy50eXBlID09IFRZUEVfU1RBUlQpIHsKKyAgICBjb2xsZWN0b3IuRGV0YWNoRnJvbVByZXYoKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBBIGNvbW1lbnQgYXBwZWFyaW5nIG9uIHRoZSBzYW1lIGxpbmUgbXVzdCBiZSBhdHRhY2hlZCB0byB0aGUgcHJldmlvdXMKKyAgICAvLyBkZWNsYXJhdGlvbi4KKyAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlTm9OZXdsaW5lPigpOworICAgIHN3aXRjaCAoVHJ5Q29uc3VtZUNvbW1lbnRTdGFydCgpKSB7CisgICAgICBjYXNlIExJTkVfQ09NTUVOVDoKKyAgICAgICAgQ29uc3VtZUxpbmVDb21tZW50KGNvbGxlY3Rvci5HZXRCdWZmZXJGb3JMaW5lQ29tbWVudCgpKTsKKworICAgICAgICAvLyBEb24ndCBhbGxvdyBjb21tZW50cyBvbiBzdWJzZXF1ZW50IGxpbmVzIHRvIGJlIGF0dGFjaGVkIHRvIGEgdHJhaWxpbmcKKyAgICAgICAgLy8gY29tbWVudC4KKyAgICAgICAgY29sbGVjdG9yLkZsdXNoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBCTE9DS19DT01NRU5UOgorICAgICAgICBDb25zdW1lQmxvY2tDb21tZW50KGNvbGxlY3Rvci5HZXRCdWZmZXJGb3JCbG9ja0NvbW1lbnQoKSk7CisKKyAgICAgICAgQ29uc3VtZVplcm9Pck1vcmU8V2hpdGVzcGFjZU5vTmV3bGluZT4oKTsKKyAgICAgICAgaWYgKCFUcnlDb25zdW1lKCdcbicpKSB7CisgICAgICAgICAgLy8gT29wcywgdGhlIG5leHQgdG9rZW4gaXMgb24gdGhlIHNhbWUgbGluZS4gIElmIHdlIHJlY29yZGVkIGEgY29tbWVudAorICAgICAgICAgIC8vIHdlIHJlYWxseSBoYXZlIG5vIGlkZWEgd2hpY2ggdG9rZW4gaXQgc2hvdWxkIGJlIGF0dGFjaGVkIHRvLgorICAgICAgICAgIGNvbGxlY3Rvci5DbGVhckJ1ZmZlcigpOworICAgICAgICAgIHJldHVybiBOZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBEb24ndCBhbGxvdyBjb21tZW50cyBvbiBzdWJzZXF1ZW50IGxpbmVzIHRvIGJlIGF0dGFjaGVkIHRvIGEgdHJhaWxpbmcKKyAgICAgICAgLy8gY29tbWVudC4KKyAgICAgICAgY29sbGVjdG9yLkZsdXNoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBTTEFTSF9OT1RfQ09NTUVOVDoKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBjYXNlIE5PX0NPTU1FTlQ6CisgICAgICAgIGlmICghVHJ5Q29uc3VtZSgnXG4nKSkgeworICAgICAgICAgIC8vIFRoZSBuZXh0IHRva2VuIGlzIG9uIHRoZSBzYW1lIGxpbmUuICBUaGVyZSBhcmUgbm8gY29tbWVudHMuCisgICAgICAgICAgcmV0dXJuIE5leHQoKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICAvLyBPSywgd2UgYXJlIG5vdyBvbiB0aGUgbGluZSAqYWZ0ZXIqIHRoZSBwcmV2aW91cyB0b2tlbi4KKyAgd2hpbGUgKHRydWUpIHsKKyAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlTm9OZXdsaW5lPigpOworCisgICAgc3dpdGNoIChUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCkpIHsKKyAgICAgIGNhc2UgTElORV9DT01NRU5UOgorICAgICAgICBDb25zdW1lTGluZUNvbW1lbnQoY29sbGVjdG9yLkdldEJ1ZmZlckZvckxpbmVDb21tZW50KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgQkxPQ0tfQ09NTUVOVDoKKyAgICAgICAgQ29uc3VtZUJsb2NrQ29tbWVudChjb2xsZWN0b3IuR2V0QnVmZmVyRm9yQmxvY2tDb21tZW50KCkpOworCisgICAgICAgIC8vIENvbnN1bWUgdGhlIHJlc3Qgb2YgdGhlIGxpbmUgc28gdGhhdCB3ZSBkb24ndCBpbnRlcnByZXQgaXQgYXMgYQorICAgICAgICAvLyBibGFuayBsaW5lIHRoZSBuZXh0IHRpbWUgYXJvdW5kIHRoZSBsb29wLgorICAgICAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlTm9OZXdsaW5lPigpOworICAgICAgICBUcnlDb25zdW1lKCdcbicpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU0xBU0hfTk9UX0NPTU1FTlQ6CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgY2FzZSBOT19DT01NRU5UOgorICAgICAgICBpZiAoVHJ5Q29uc3VtZSgnXG4nKSkgeworICAgICAgICAgIC8vIENvbXBsZXRlbHkgYmxhbmsgbGluZS4KKyAgICAgICAgICBjb2xsZWN0b3IuRmx1c2goKTsKKyAgICAgICAgICBjb2xsZWN0b3IuRGV0YWNoRnJvbVByZXYoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBib29sIHJlc3VsdCA9IE5leHQoKTsKKyAgICAgICAgICBpZiAoIXJlc3VsdCB8fAorICAgICAgICAgICAgICBjdXJyZW50Xy50ZXh0ID09ICJ9IiB8fAorICAgICAgICAgICAgICBjdXJyZW50Xy50ZXh0ID09ICJdIiB8fAorICAgICAgICAgICAgICBjdXJyZW50Xy50ZXh0ID09ICIpIikgeworICAgICAgICAgICAgLy8gSXQgbG9va3MgbGlrZSB3ZSdyZSBhdCB0aGUgZW5kIG9mIGEgc2NvcGUuICBJbiB0aGlzIGNhc2UgaXQKKyAgICAgICAgICAgIC8vIG1ha2VzIG5vIHNlbnNlIHRvIGF0dGFjaCBhIGNvbW1lbnQgdG8gdGhlIGZvbGxvd2luZyB0b2tlbi4KKyAgICAgICAgICAgIGNvbGxlY3Rvci5GbHVzaCgpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBUb2tlbi1wYXJzaW5nIGhlbHBlcnMuICBSZW1lbWJlciB0aGF0IHRoZXNlIGRvbid0IG5lZWQgdG8gcmVwb3J0CisvLyBlcnJvcnMgc2luY2UgYW55IGVycm9ycyBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4gcmVwb3J0ZWQgd2hpbGUKKy8vIHRva2VuaXppbmcuICBBbHNvLCB0aGVzZSBjYW4gYXNzdW1lIHRoYXQgd2hhdGV2ZXIgdGV4dCB0aGV5CisvLyBhcmUgZ2l2ZW4gaXMgdGV4dCB0aGF0IHRoZSB0b2tlbml6ZXIgYWN0dWFsbHkgcGFyc2VkIGFzIGEgdG9rZW4KKy8vIG9mIHRoZSBnaXZlbiB0eXBlLgorCitib29sIFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKGNvbnN0IHN0cmluZyYgdGV4dCwgdWludDY0IG1heF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0KiBvdXRwdXQpIHsKKyAgLy8gU2FkbHksIHdlIGNhbid0IGp1c3QgdXNlIHN0cnRvdWwoKSBzaW5jZSBpdCBpcyBvbmx5IDMyLWJpdCBhbmQgc3RydG91bGwoKQorICAvLyBpcyBub24tc3RhbmRhcmQuICBJIGhhdGUgdGhlIEMgc3RhbmRhcmQgbGlicmFyeS4gIDooCisKKy8vICByZXR1cm4gc3RydG91bGwodGV4dC5jX3N0cigpLCBOVUxMLCAwKTsKKworICBjb25zdCBjaGFyKiBwdHIgPSB0ZXh0LmNfc3RyKCk7CisgIGludCBiYXNlID0gMTA7CisgIGlmIChwdHJbMF0gPT0gJzAnKSB7CisgICAgaWYgKHB0clsxXSA9PSAneCcgfHwgcHRyWzFdID09ICdYJykgeworICAgICAgLy8gVGhpcyBpcyBoZXguCisgICAgICBiYXNlID0gMTY7CisgICAgICBwdHIgKz0gMjsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVGhpcyBpcyBvY3RhbC4KKyAgICAgIGJhc2UgPSA4OworICAgIH0KKyAgfQorCisgIHVpbnQ2NCByZXN1bHQgPSAwOworICBmb3IgKDsgKnB0ciAhPSAnXDAnOyBwdHIrKykgeworICAgIGludCBkaWdpdCA9IERpZ2l0VmFsdWUoKnB0cik7CisgICAgR09PR0xFX0xPR19JRihERkFUQUwsIGRpZ2l0IDwgMCB8fCBkaWdpdCA+PSBiYXNlKQorICAgICAgPDwgIiBUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigpIHBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiIKKyAgICAgICAgICIgdG9rZW5pemVkIGFzIGFuIGludGVnZXI6ICIgPDwgQ0VzY2FwZSh0ZXh0KTsKKyAgICBpZiAoZGlnaXQgPiBtYXhfdmFsdWUgfHwgcmVzdWx0ID4gKG1heF92YWx1ZSAtIGRpZ2l0KSAvIGJhc2UpIHsKKyAgICAgIC8vIE92ZXJmbG93LgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXN1bHQgPSByZXN1bHQgKiBiYXNlICsgZGlnaXQ7CisgIH0KKworICAqb3V0cHV0ID0gcmVzdWx0OworICByZXR1cm4gdHJ1ZTsKK30KKworZG91YmxlIFRva2VuaXplcjo6UGFyc2VGbG9hdChjb25zdCBzdHJpbmcmIHRleHQpIHsKKyAgY29uc3QgY2hhciogc3RhcnQgPSB0ZXh0LmNfc3RyKCk7CisgIGNoYXIqIGVuZDsKKyAgZG91YmxlIHJlc3VsdCA9IE5vTG9jYWxlU3RydG9kKHN0YXJ0LCAmZW5kKTsKKworICAvLyAiMWUiIGlzIG5vdCBhIHZhbGlkIGZsb2F0LCBidXQgaWYgdGhlIHRva2VuaXplciByZWFkcyBpdCwgaXQgd2lsbAorICAvLyByZXBvcnQgYW4gZXJyb3IgYnV0IHN0aWxsIHJldHVybiBpdCBhcyBhIHZhbGlkIHRva2VuLiAgV2UgbmVlZCB0bworICAvLyBhY2NlcHQgYW55dGhpbmcgdGhlIHRva2VuaXplciBjb3VsZCBwb3NzaWJseSByZXR1cm4sIGVycm9yIG9yIG5vdC4KKyAgaWYgKCplbmQgPT0gJ2UnIHx8ICplbmQgPT0gJ0UnKSB7CisgICAgKytlbmQ7CisgICAgaWYgKCplbmQgPT0gJy0nIHx8ICplbmQgPT0gJysnKSArK2VuZDsKKyAgfQorCisgIC8vIElmIHRoZSBUb2tlbml6ZXIgaGFkIGFsbG93X2ZfYWZ0ZXJfZmxvYXRfIGVuYWJsZWQsIHRoZSBmbG9hdCBtYXkgYmUKKyAgLy8gc3VmZml4ZWQgd2l0aCB0aGUgbGV0dGVyICdmJy4KKyAgaWYgKCplbmQgPT0gJ2YnIHx8ICplbmQgPT0gJ0YnKSB7CisgICAgKytlbmQ7CisgIH0KKworICBHT09HTEVfTE9HX0lGKERGQVRBTCwgZW5kIC0gc3RhcnQgIT0gdGV4dC5zaXplKCkgfHwgKnN0YXJ0ID09ICctJykKKyAgICA8PCAiIFRva2VuaXplcjo6UGFyc2VGbG9hdCgpIHBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiIKKyAgICAgICAiIHRva2VuaXplZCBhcyBhIGZsb2F0OiAiIDw8IENFc2NhcGUodGV4dCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEhlbHBlciB0byBhcHBlbmQgYSBVbmljb2RlIGNvZGUgcG9pbnQgdG8gYSBzdHJpbmcgYXMgVVRGOCwgd2l0aG91dCBicmluZ2luZworLy8gaW4gYW55IGV4dGVybmFsIGRlcGVuZGVuY2llcy4KK3N0YXRpYyB2b2lkIEFwcGVuZFVURjgodWludDMyIGNvZGVfcG9pbnQsIHN0cmluZyogb3V0cHV0KSB7CisgIHVpbnQzMiB0bXAgPSAwOworICBpbnQgbGVuID0gMDsKKyAgaWYgKGNvZGVfcG9pbnQgPD0gMHg3ZikgeworICAgIHRtcCA9IGNvZGVfcG9pbnQ7CisgICAgbGVuID0gMTsKKyAgfSBlbHNlIGlmIChjb2RlX3BvaW50IDw9IDB4MDdmZikgeworICAgIHRtcCA9IDB4MDAwMGMwODAgfAorICAgICAgICAoKGNvZGVfcG9pbnQgJiAweDA3YzApIDw8IDIpIHwKKyAgICAgICAgKGNvZGVfcG9pbnQgJiAweDAwM2YpOworICAgIGxlbiA9IDI7CisgIH0gZWxzZSBpZiAoY29kZV9wb2ludCA8PSAweGZmZmYpIHsKKyAgICB0bXAgPSAweDAwZTA4MDgwIHwKKyAgICAgICAgKChjb2RlX3BvaW50ICYgMHhmMDAwKSA8PCA0KSB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MGZjMCkgPDwgMikgfAorICAgICAgICAoY29kZV9wb2ludCAmIDB4MDAzZik7CisgICAgbGVuID0gMzsKKyAgfSBlbHNlIGlmIChjb2RlX3BvaW50IDw9IDB4MWZmZmZmKSB7CisgICAgdG1wID0gMHhmMDgwODA4MCB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MWMwMDAwKSA8PCA2KSB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MDNmMDAwKSA8PCA0KSB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MDAwZmMwKSA8PCAyKSB8CisgICAgICAgIChjb2RlX3BvaW50ICYgMHgwMDNmKTsKKyAgICBsZW4gPSA0OworICB9IGVsc2UgeworICAgIC8vIFVURi0xNiBpcyBvbmx5IGRlZmluZWQgZm9yIGNvZGUgcG9pbnRzIHVwIHRvIDB4MTBGRkZGLCBhbmQgVVRGLTggaXMKKyAgICAvLyBub3JtYWxseSBvbmx5IGRlZmluZWQgdXAgdG8gdGhlcmUgYXMgd2VsbC4KKyAgICBTdHJpbmdBcHBlbmRGKG91dHB1dCwgIlxcVSUwOHgiLCBjb2RlX3BvaW50KTsKKyAgICByZXR1cm47CisgIH0KKyAgdG1wID0gZ2h0b25sKHRtcCk7CisgIG91dHB1dC0+YXBwZW5kKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KCZ0bXApICsgc2l6ZW9mKHRtcCkgLSBsZW4sIGxlbik7Cit9CisKKy8vIFRyeSB0byByZWFkIDxsZW4+IGhleCBkaWdpdHMgZnJvbSBwdHIsIGFuZCBzdHVmZiB0aGUgbnVtZXJpYyByZXN1bHQgaW50bworLy8gKnJlc3VsdC4gUmV0dXJucyB0cnVlIGlmIHRoYXQgbWFueSBkaWdpdHMgd2VyZSBzdWNjZXNzZnVsbHkgY29uc3VtZWQuCitzdGF0aWMgYm9vbCBSZWFkSGV4RGlnaXRzKGNvbnN0IGNoYXIqIHB0ciwgaW50IGxlbiwgdWludDMyKiByZXN1bHQpIHsKKyAgKnJlc3VsdCA9IDA7CisgIGlmIChsZW4gPT0gMCkgcmV0dXJuIGZhbHNlOworICBmb3IgKGNvbnN0IGNoYXIqIGVuZCA9IHB0ciArIGxlbjsgcHRyIDwgZW5kOyArK3B0cikgeworICAgIGlmICgqcHRyID09ICdcMCcpIHJldHVybiBmYWxzZTsKKyAgICAqcmVzdWx0ID0gKCpyZXN1bHQgPDwgNCkgKyBEaWdpdFZhbHVlKCpwdHIpOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBIYW5kbGluZyBVVEYtMTYgc3Vycm9nYXRlIHBhaXJzLiBVVEYtMTYgZW5jb2RlcyBjb2RlIHBvaW50cyBpbiB0aGUgcmFuZ2UKKy8vIDB4MTAwMDAuLi4weDEwZmZmZiBhcyBhIHBhaXIgb2YgbnVtYmVycywgYSBoZWFkIHN1cnJvZ2F0ZSBmb2xsb3dlZCBieSBhIHRyYWlsCisvLyBzdXJyb2dhdGUuIFRoZXNlIG51bWJlcnMgYXJlIGluIGEgcmVzZXJ2ZWQgcmFuZ2Ugb2YgVW5pY29kZSBjb2RlIHBvaW50cywgc28KKy8vIGlmIHdlIGVuY291bnRlciBzdWNoIGEgcGFpciB3ZSBrbm93IGhvdyB0byBwYXJzZSBpdCBhbmQgY29udmVydCBpdCBpbnRvIGEKKy8vIHNpbmdsZSBjb2RlIHBvaW50Lgorc3RhdGljIGNvbnN0IHVpbnQzMiBrTWluSGVhZFN1cnJvZ2F0ZSA9IDB4ZDgwMDsKK3N0YXRpYyBjb25zdCB1aW50MzIga01heEhlYWRTdXJyb2dhdGUgPSAweGRjMDA7CitzdGF0aWMgY29uc3QgdWludDMyIGtNaW5UcmFpbFN1cnJvZ2F0ZSA9IDB4ZGMwMDsKK3N0YXRpYyBjb25zdCB1aW50MzIga01heFRyYWlsU3Vycm9nYXRlID0gMHhlMDAwOworCitzdGF0aWMgaW5saW5lIGJvb2wgSXNIZWFkU3Vycm9nYXRlKHVpbnQzMiBjb2RlX3BvaW50KSB7CisgIHJldHVybiAoY29kZV9wb2ludCA+PSBrTWluSGVhZFN1cnJvZ2F0ZSkgJiYgKGNvZGVfcG9pbnQgPCBrTWF4SGVhZFN1cnJvZ2F0ZSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgYm9vbCBJc1RyYWlsU3Vycm9nYXRlKHVpbnQzMiBjb2RlX3BvaW50KSB7CisgIHJldHVybiAoY29kZV9wb2ludCA+PSBrTWluVHJhaWxTdXJyb2dhdGUpICYmCisgICAgICAoY29kZV9wb2ludCA8IGtNYXhUcmFpbFN1cnJvZ2F0ZSk7Cit9CisKKy8vIENvbWJpbmUgYSBoZWFkIGFuZCB0cmFpbCBzdXJyb2dhdGUgaW50byBhIHNpbmdsZSBVbmljb2RlIGNvZGUgcG9pbnQuCitzdGF0aWMgdWludDMyIEFzc2VtYmxlVVRGMTYodWludDMyIGhlYWRfc3Vycm9nYXRlLCB1aW50MzIgdHJhaWxfc3Vycm9nYXRlKSB7CisgIEdPT0dMRV9EQ0hFQ0soSXNIZWFkU3Vycm9nYXRlKGhlYWRfc3Vycm9nYXRlKSk7CisgIEdPT0dMRV9EQ0hFQ0soSXNUcmFpbFN1cnJvZ2F0ZSh0cmFpbF9zdXJyb2dhdGUpKTsKKyAgcmV0dXJuIDB4MTAwMDAgKyAoKChoZWFkX3N1cnJvZ2F0ZSAtIGtNaW5IZWFkU3Vycm9nYXRlKSA8PCAxMCkgfAorICAgICAgKHRyYWlsX3N1cnJvZ2F0ZSAtIGtNaW5UcmFpbFN1cnJvZ2F0ZSkpOworfQorCisvLyBDb252ZXJ0IHRoZSBlc2NhcGUgc2VxdWVuY2UgcGFyYW1ldGVyIHRvIGEgbnVtYmVyIG9mIGV4cGVjdGVkIGhleCBkaWdpdHMuCitzdGF0aWMgaW5saW5lIGludCBVbmljb2RlTGVuZ3RoKGNoYXIga2V5KSB7CisgIGlmIChrZXkgPT0gJ3UnKSByZXR1cm4gNDsKKyAgaWYgKGtleSA9PSAnVScpIHJldHVybiA4OworICByZXR1cm4gMDsKK30KKworLy8gR2l2ZW4gYSBwb2ludGVyIHRvIHRoZSAndScgb3IgJ1UnIHN0YXJ0aW5nIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UsIGF0dGVtcHQKKy8vIHRvIHBhcnNlIHRoYXQgc2VxdWVuY2UuIE9uIHN1Y2Nlc3MsIHJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBmaXJzdCBjaGFyCisvLyBiZXlvbmQgdGhhdCBzZXF1ZW5jZSwgYW5kIGZpbGxzIGluICpjb2RlX3BvaW50LiBPbiBmYWlsdXJlLCByZXR1cm5zIHB0cgorLy8gaXRzZWxmLgorc3RhdGljIGNvbnN0IGNoYXIqIEZldGNoVW5pY29kZVBvaW50KGNvbnN0IGNoYXIqIHB0ciwgdWludDMyKiBjb2RlX3BvaW50KSB7CisgIGNvbnN0IGNoYXIqIHAgPSBwdHI7CisgIC8vIEZldGNoIHRoZSBjb2RlIHBvaW50LgorICBjb25zdCBpbnQgbGVuID0gVW5pY29kZUxlbmd0aCgqcCsrKTsKKyAgaWYgKCFSZWFkSGV4RGlnaXRzKHAsIGxlbiwgY29kZV9wb2ludCkpCisgICAgcmV0dXJuIHB0cjsKKyAgcCArPSBsZW47CisKKyAgLy8gQ2hlY2sgaWYgdGhlIGNvZGUgcG9pbnQgd2UgcmVhZCBpcyBhICJoZWFkIHN1cnJvZ2F0ZS4iIElmIHNvLCB0aGVuIHdlCisgIC8vIGV4cGVjdCBpdCB0byBiZSBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhbm90aGVyIGNvZGUgcG9pbnQgd2hpY2ggaXMgYSB2YWxpZAorICAvLyAidHJhaWwgc3Vycm9nYXRlLCIgYW5kIHRvZ2V0aGVyIHRoZXkgZm9ybSBhIFVURi0xNiBwYWlyIHdoaWNoIGRlY29kZXMgaW50bworICAvLyBhIHNpbmdsZSBVbmljb2RlIHBvaW50LiBUcmFpbCBzdXJyb2dhdGVzIG1heSBvbmx5IHVzZSBcdSwgbm90IFxVLgorICBpZiAoSXNIZWFkU3Vycm9nYXRlKCpjb2RlX3BvaW50KSAmJiAqcCA9PSAnXFwnICYmICoocCArIDEpID09ICd1JykgeworICAgIHVpbnQzMiB0cmFpbF9zdXJyb2dhdGU7CisgICAgaWYgKFJlYWRIZXhEaWdpdHMocCArIDIsIDQsICZ0cmFpbF9zdXJyb2dhdGUpICYmCisgICAgICAgIElzVHJhaWxTdXJyb2dhdGUodHJhaWxfc3Vycm9nYXRlKSkgeworICAgICAgKmNvZGVfcG9pbnQgPSBBc3NlbWJsZVVURjE2KCpjb2RlX3BvaW50LCB0cmFpbF9zdXJyb2dhdGUpOworICAgICAgcCArPSA2OworICAgIH0KKyAgICAvLyBJZiB0aGlzIGZhaWxlZCwgdGhlbiB3ZSBqdXN0IGVtaXQgdGhlIGhlYWQgc3Vycm9nYXRlIGFzIGEgY29kZSBwb2ludC4KKyAgICAvLyBJdCdzIGJvZ3VzLCBidXQgc28gaXMgdGhlIHN0cmluZy4KKyAgfQorCisgIHJldHVybiBwOworfQorCisvLyBUaGUgdGV4dCBzdHJpbmcgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggc2luZ2xlIG9yIGRvdWJsZSBxdW90ZQorLy8gY2hhcmFjdGVycy4KK3ZvaWQgVG9rZW5pemVyOjpQYXJzZVN0cmluZ0FwcGVuZChjb25zdCBzdHJpbmcmIHRleHQsIHN0cmluZyogb3V0cHV0KSB7CisgIC8vIFJlbWluZGVyOiB0ZXh0WzBdIGlzIGFsd2F5cyBhIHF1b3RlIGNoYXJhY3Rlci4gIChJZiB0ZXh0IGlzCisgIC8vIGVtcHR5LCBpdCdzIGludmFsaWQsIHNvIHdlJ2xsIGp1c3QgcmV0dXJuKS4KKyAgY29uc3Qgc2l6ZV90IHRleHRfc2l6ZSA9IHRleHQuc2l6ZSgpOworICBpZiAodGV4dF9zaXplID09IDApIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkKKyAgICAgIDw8ICIgVG9rZW5pemVyOjpQYXJzZVN0cmluZ0FwcGVuZCgpIHBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IgorICAgICAgICAgIiBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGEgc3RyaW5nOiAiIDw8IENFc2NhcGUodGV4dCk7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gUmVzZXJ2ZSByb29tIGZvciBuZXcgc3RyaW5nLiBUaGUgYnJhbmNoIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGlmCisgIC8vIHRoZXJlIGlzIGFscmVhZHkgc3BhY2UgYXZhaWxhYmxlIHRoZSByZXNlcnZlKCkgY2FsbCBtaWdodAorICAvLyBkb3duc2l6ZSB0aGUgb3V0cHV0LgorICBjb25zdCBzaXplX3QgbmV3X2xlbiA9IHRleHRfc2l6ZSArIG91dHB1dC0+c2l6ZSgpOworICBpZiAobmV3X2xlbiA+IG91dHB1dC0+Y2FwYWNpdHkoKSkgeworICAgIG91dHB1dC0+cmVzZXJ2ZShuZXdfbGVuKTsKKyAgfQorCisgIC8vIExvb3AgdGhyb3VnaCB0aGUgc3RyaW5nIGNvcHlpbmcgY2hhcmFjdGVycyB0byAib3V0cHV0IiBhbmQKKyAgLy8gaW50ZXJwcmV0aW5nIGVzY2FwZSBzZXF1ZW5jZXMuICBOb3RlIHRoYXQgYW55IGludmFsaWQgZXNjYXBlCisgIC8vIHNlcXVlbmNlcyBvciBvdGhlciBlcnJvcnMgd2VyZSBhbHJlYWR5IHJlcG9ydGVkIHdoaWxlIHRva2VuaXppbmcuCisgIC8vIEluIHRoaXMgY2FzZSB3ZSBkbyBub3QgbmVlZCB0byBwcm9kdWNlIHZhbGlkIHJlc3VsdHMuCisgIGZvciAoY29uc3QgY2hhciogcHRyID0gdGV4dC5jX3N0cigpICsgMTsgKnB0ciAhPSAnXDAnOyBwdHIrKykgeworICAgIGlmICgqcHRyID09ICdcXCcgJiYgcHRyWzFdICE9ICdcMCcpIHsKKyAgICAgIC8vIEFuIGVzY2FwZSBzZXF1ZW5jZS4KKyAgICAgICsrcHRyOworCisgICAgICBpZiAoT2N0YWxEaWdpdDo6SW5DbGFzcygqcHRyKSkgeworICAgICAgICAvLyBBbiBvY3RhbCBlc2NhcGUuICBNYXkgb25lLCB0d28sIG9yIHRocmVlIGRpZ2l0cy4KKyAgICAgICAgaW50IGNvZGUgPSBEaWdpdFZhbHVlKCpwdHIpOworICAgICAgICBpZiAoT2N0YWxEaWdpdDo6SW5DbGFzcyhwdHJbMV0pKSB7CisgICAgICAgICAgKytwdHI7CisgICAgICAgICAgY29kZSA9IGNvZGUgKiA4ICsgRGlnaXRWYWx1ZSgqcHRyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoT2N0YWxEaWdpdDo6SW5DbGFzcyhwdHJbMV0pKSB7CisgICAgICAgICAgKytwdHI7CisgICAgICAgICAgY29kZSA9IGNvZGUgKiA4ICsgRGlnaXRWYWx1ZSgqcHRyKTsKKyAgICAgICAgfQorICAgICAgICBvdXRwdXQtPnB1c2hfYmFjayhzdGF0aWNfY2FzdDxjaGFyPihjb2RlKSk7CisKKyAgICAgIH0gZWxzZSBpZiAoKnB0ciA9PSAneCcpIHsKKyAgICAgICAgLy8gQSBoZXggZXNjYXBlLiAgTWF5IHplcm8sIG9uZSwgb3IgdHdvIGRpZ2l0cy4gIChUaGUgemVybyBjYXNlCisgICAgICAgIC8vIHdpbGwgaGF2ZSBiZWVuIGNhdWdodCBhcyBhbiBlcnJvciBlYXJsaWVyLikKKyAgICAgICAgaW50IGNvZGUgPSAwOworICAgICAgICBpZiAoSGV4RGlnaXQ6OkluQ2xhc3MocHRyWzFdKSkgeworICAgICAgICAgICsrcHRyOworICAgICAgICAgIGNvZGUgPSBEaWdpdFZhbHVlKCpwdHIpOworICAgICAgICB9CisgICAgICAgIGlmIChIZXhEaWdpdDo6SW5DbGFzcyhwdHJbMV0pKSB7CisgICAgICAgICAgKytwdHI7CisgICAgICAgICAgY29kZSA9IGNvZGUgKiAxNiArIERpZ2l0VmFsdWUoKnB0cik7CisgICAgICAgIH0KKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soc3RhdGljX2Nhc3Q8Y2hhcj4oY29kZSkpOworCisgICAgICB9IGVsc2UgaWYgKCpwdHIgPT0gJ3UnIHx8ICpwdHIgPT0gJ1UnKSB7CisgICAgICAgIHVpbnQzMiB1bmljb2RlOworICAgICAgICBjb25zdCBjaGFyKiBlbmQgPSBGZXRjaFVuaWNvZGVQb2ludChwdHIsICZ1bmljb2RlKTsKKyAgICAgICAgaWYgKGVuZCA9PSBwdHIpIHsKKyAgICAgICAgICAvLyBGYWlsdXJlOiBKdXN0IGR1bXAgb3V0IHdoYXQgd2Ugc2F3LCBkb24ndCB0cnkgdG8gcGFyc2UgaXQuCisgICAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soKnB0cik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgQXBwZW5kVVRGOCh1bmljb2RlLCBvdXRwdXQpOworICAgICAgICAgIHB0ciA9IGVuZCAtIDE7ICAvLyBCZWNhdXNlIHdlJ3JlIGFib3V0IHRvICsrcHRyLgorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBTb21lIG90aGVyIGVzY2FwZSBjb2RlLgorICAgICAgICBvdXRwdXQtPnB1c2hfYmFjayhUcmFuc2xhdGVFc2NhcGUoKnB0cikpOworICAgICAgfQorCisgICAgfSBlbHNlIGlmICgqcHRyID09IHRleHRbMF0gJiYgcHRyWzFdID09ICdcMCcpIHsKKyAgICAgIC8vIElnbm9yZSBmaW5hbCBxdW90ZSBtYXRjaGluZyB0aGUgc3RhcnRpbmcgcXVvdGUuCisgICAgfSBlbHNlIHsKKyAgICAgIG91dHB1dC0+cHVzaF9iYWNrKCpwdHIpOworICAgIH0KKyAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KK3N0YXRpYyBib29sIEFsbEluQ2xhc3MoY29uc3Qgc3RyaW5nJiBzKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5zaXplKCk7ICsraSkgeworICAgIGlmICghQ2hhcmFjdGVyQ2xhc3M6OkluQ2xhc3Moc1tpXSkpCisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgVG9rZW5pemVyOjpJc0lkZW50aWZpZXIoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisgIC8vIE1pcnJvcnMgSURFTlRJRklFUiBkZWZpbml0aW9uIGluIFRva2VuaXplcjo6TmV4dCgpIGFib3ZlLgorICBpZiAodGV4dC5zaXplKCkgPT0gMCkKKyAgICByZXR1cm4gZmFsc2U7CisgIGlmICghTGV0dGVyOjpJbkNsYXNzKHRleHQuYXQoMCkpKQorICAgIHJldHVybiBmYWxzZTsKKyAgaWYgKCFBbGxJbkNsYXNzPEFscGhhbnVtZXJpYz4odGV4dC5zdWJzdHIoMSkpKQorICAgIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ODU3NmY1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaApAQCAtMCwwICsxLDQwMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIENsYXNzIGZvciBwYXJzaW5nIHRva2VuaXplZCB0ZXh0IGZyb20gYSBaZXJvQ29weUlucHV0U3RyZWFtLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19UT0tFTklaRVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9JT19UT0tFTklaRVJfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworY2xhc3MgWmVyb0NvcHlJbnB1dFN0cmVhbTsgICAgIC8vIHplcm9fY29weV9zdHJlYW0uaAorCisvLyBEZWZpbmVkIGluIHRoaXMgZmlsZS4KK2NsYXNzIEVycm9yQ29sbGVjdG9yOworY2xhc3MgVG9rZW5pemVyOworCisvLyBBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIGFuIG9iamVjdCB3aGljaCBjb2xsZWN0cyB0aGUgZXJyb3JzIHRoYXQgb2NjdXIKKy8vIGR1cmluZyBwYXJzaW5nLiAgQSB0eXBpY2FsIGltcGxlbWVudGF0aW9uIG1pZ2h0IHNpbXBseSBwcmludCB0aGUgZXJyb3JzCisvLyB0byBzdGRvdXQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgaW5saW5lIEVycm9yQ29sbGVjdG9yKCkge30KKyAgdmlydHVhbCB+RXJyb3JDb2xsZWN0b3IoKTsKKworICAvLyBJbmRpY2F0ZXMgdGhhdCB0aGVyZSB3YXMgYW4gZXJyb3IgaW4gdGhlIGlucHV0IGF0IHRoZSBnaXZlbiBsaW5lIGFuZAorICAvLyBjb2x1bW4gbnVtYmVycy4gIFRoZSBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkLCBzbyB5b3UgbWF5IHdhbnQgdG8gYWRkCisgIC8vIDEgdG8gZWFjaCBiZWZvcmUgcHJpbnRpbmcgdGhlbS4KKyAgdmlydHVhbCB2b2lkIEFkZEVycm9yKGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpID0gMDsKKworICAvLyBJbmRpY2F0ZXMgdGhhdCB0aGVyZSB3YXMgYSB3YXJuaW5nIGluIHRoZSBpbnB1dCBhdCB0aGUgZ2l2ZW4gbGluZSBhbmQKKyAgLy8gY29sdW1uIG51bWJlcnMuICBUaGUgbnVtYmVycyBhcmUgemVyby1iYXNlZCwgc28geW91IG1heSB3YW50IHRvIGFkZAorICAvLyAxIHRvIGVhY2ggYmVmb3JlIHByaW50aW5nIHRoZW0uCisgIHZpcnR1YWwgdm9pZCBBZGRXYXJuaW5nKGludCAvKiBsaW5lICovLCBpbnQgLyogY29sdW1uICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIC8qIG1lc3NhZ2UgKi8pIHsgfQorCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVycm9yQ29sbGVjdG9yKTsKK307CisKKy8vIFRoaXMgY2xhc3MgY29udmVydHMgYSBzdHJlYW0gb2YgcmF3IHRleHQgaW50byBhIHN0cmVhbSBvZiB0b2tlbnMgZm9yCisvLyB0aGUgcHJvdG9jb2wgZGVmaW5pdGlvbiBwYXJzZXIgdG8gcGFyc2UuICBUaGUgdG9rZW5zIHJlY29nbml6ZWQgYXJlCisvLyBzaW1pbGFyIHRvIHRob3NlIHRoYXQgbWFrZSB1cCB0aGUgQyBsYW5ndWFnZTsgc2VlIHRoZSBUb2tlblR5cGUgZW51bSBmb3IKKy8vIHByZWNpc2UgZGVzY3JpcHRpb25zLiAgV2hpdGVzcGFjZSBhbmQgY29tbWVudHMgYXJlIHNraXBwZWQuICBCeSBkZWZhdWx0LAorLy8gQy0gYW5kIEMrKy1zdHlsZSBjb21tZW50cyBhcmUgcmVjb2duaXplZCwgYnV0IG90aGVyIHN0eWxlcyBjYW4gYmUgdXNlZCBieQorLy8gY2FsbGluZyBzZXRfY29tbWVudF9zdHlsZSgpLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFRva2VuaXplciB7CisgcHVibGljOgorICAvLyBDb25zdHJ1Y3QgYSBUb2tlbml6ZXIgdGhhdCByZWFkcyBhbmQgdG9rZW5pemVzIHRleHQgZnJvbSB0aGUgZ2l2ZW4KKyAgLy8gaW5wdXQgc3RyZWFtIGFuZCB3cml0ZXMgZXJyb3JzIHRvIHRoZSBnaXZlbiBlcnJvcl9jb2xsZWN0b3IuCisgIC8vIFRoZSBjYWxsZXIga2VlcHMgb3duZXJzaGlwIG9mIGlucHV0IGFuZCBlcnJvcl9jb2xsZWN0b3IuCisgIFRva2VuaXplcihaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3Rvcik7CisgIH5Ub2tlbml6ZXIoKTsKKworICBlbnVtIFRva2VuVHlwZSB7CisgICAgVFlQRV9TVEFSVCwgICAgICAgLy8gTmV4dCgpIGhhcyBub3QgeWV0IGJlZW4gY2FsbGVkLgorICAgIFRZUEVfRU5ELCAgICAgICAgIC8vIEVuZCBvZiBpbnB1dCByZWFjaGVkLiAgInRleHQiIGlzIGVtcHR5LgorCisgICAgVFlQRV9JREVOVElGSUVSLCAgLy8gQSBzZXF1ZW5jZSBvZiBsZXR0ZXJzLCBkaWdpdHMsIGFuZCB1bmRlcnNjb3Jlcywgbm90CisgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnRpbmcgd2l0aCBhIGRpZ2l0LiAgSXQgaXMgYW4gZXJyb3IgZm9yIGEgbnVtYmVyCisgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYmUgZm9sbG93ZWQgYnkgYW4gaWRlbnRpZmllciB3aXRoIG5vIHNwYWNlIGluCisgICAgICAgICAgICAgICAgICAgICAgLy8gYmV0d2Vlbi4KKyAgICBUWVBFX0lOVEVHRVIsICAgICAvLyBBIHNlcXVlbmNlIG9mIGRpZ2l0cyByZXByZXNlbnRpbmcgYW4gaW50ZWdlci4gIE5vcm1hbGx5CisgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGRpZ2l0cyBhcmUgZGVjaW1hbCwgYnV0IGEgcHJlZml4IG9mICIweCIgaW5kaWNhdGVzCisgICAgICAgICAgICAgICAgICAgICAgLy8gYSBoZXggbnVtYmVyIGFuZCBhIGxlYWRpbmcgemVybyBpbmRpY2F0ZXMgb2N0YWwsIGp1c3QKKyAgICAgICAgICAgICAgICAgICAgICAvLyBsaWtlIHdpdGggQyBudW1lcmljIGxpdGVyYWxzLiAgQSBsZWFkaW5nIG5lZ2F0aXZlIHNpZ24KKyAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBOT1QgaW5jbHVkZWQgaW4gdGhlIHRva2VuOyBpdCdzIHVwIHRvIHRoZSBwYXJzZXIgdG8KKyAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRlcnByZXQgdGhlIHVuYXJ5IG1pbnVzIG9wZXJhdG9yIG9uIGl0cyBvd24uCisgICAgVFlQRV9GTE9BVCwgICAgICAgLy8gQSBmbG9hdGluZyBwb2ludCBsaXRlcmFsLCB3aXRoIGEgZnJhY3Rpb25hbCBwYXJ0IGFuZC9vcgorICAgICAgICAgICAgICAgICAgICAgIC8vIGFuIGV4cG9uZW50LiAgQWx3YXlzIGluIGRlY2ltYWwuICBBZ2FpbiwgbmV2ZXIKKyAgICAgICAgICAgICAgICAgICAgICAvLyBuZWdhdGl2ZS4KKyAgICBUWVBFX1NUUklORywgICAgICAvLyBBIHF1b3RlZCBzZXF1ZW5jZSBvZiBlc2NhcGVkIGNoYXJhY3RlcnMuICBFaXRoZXIgc2luZ2xlCisgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgZG91YmxlIHF1b3RlcyBjYW4gYmUgdXNlZCwgYnV0IHRoZXkgbXVzdCBtYXRjaC4KKyAgICAgICAgICAgICAgICAgICAgICAvLyBBIHN0cmluZyBsaXRlcmFsIGNhbm5vdCBjcm9zcyBhIGxpbmUgYnJlYWsuCisgICAgVFlQRV9TWU1CT0wsICAgICAgLy8gQW55IG90aGVyIHByaW50YWJsZSBjaGFyYWN0ZXIsIGxpa2UgJyEnIG9yICcrJy4KKyAgICAgICAgICAgICAgICAgICAgICAvLyBTeW1ib2xzIGFyZSBhbHdheXMgYSBzaW5nbGUgY2hhcmFjdGVyLCBzbyAiISskJSIgaXMKKyAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VyIHRva2Vucy4KKyAgfTsKKworICAvLyBTdHJ1Y3R1cmUgcmVwcmVzZW50aW5nIGEgdG9rZW4gcmVhZCBmcm9tIHRoZSB0b2tlbiBzdHJlYW0uCisgIHN0cnVjdCBUb2tlbiB7CisgICAgVG9rZW5UeXBlIHR5cGU7CisgICAgc3RyaW5nIHRleHQ7ICAgICAgIC8vIFRoZSBleGFjdCB0ZXh0IG9mIHRoZSB0b2tlbiBhcyBpdCBhcHBlYXJlZCBpbgorICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgaW5wdXQuICBlLmcuIHRva2VucyBvZiBUWVBFX1NUUklORyB3aWxsIHN0aWxsCisgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlIGVzY2FwZWQgYW5kIGluIHF1b3Rlcy4KKworICAgIC8vICJsaW5lIiBhbmQgImNvbHVtbiIgc3BlY2lmeSB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgorICAgIC8vIHRoZSB0b2tlbiB3aXRoaW4gdGhlIGlucHV0IHN0cmVhbS4gIFRoZXkgYXJlIHplcm8tYmFzZWQuCisgICAgaW50IGxpbmU7CisgICAgaW50IGNvbHVtbjsKKyAgICBpbnQgZW5kX2NvbHVtbjsKKyAgfTsKKworICAvLyBHZXQgdGhlIGN1cnJlbnQgdG9rZW4uICBUaGlzIGlzIHVwZGF0ZWQgd2hlbiBOZXh0KCkgaXMgY2FsbGVkLiAgQmVmb3JlCisgIC8vIHRoZSBmaXJzdCBjYWxsIHRvIE5leHQoKSwgY3VycmVudCgpIGhhcyB0eXBlIFRZUEVfU1RBUlQgYW5kIG5vIGNvbnRlbnRzLgorICBjb25zdCBUb2tlbiYgY3VycmVudCgpOworCisgIC8vIFJldHVybiB0aGUgcHJldmlvdXMgdG9rZW4gLS0gaS5lLiB3aGF0IGN1cnJlbnQoKSByZXR1cm5lZCBiZWZvcmUgdGhlCisgIC8vIHByZXZpb3VzIGNhbGwgdG8gTmV4dCgpLgorICBjb25zdCBUb2tlbiYgcHJldmlvdXMoKTsKKworICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IHRva2VuLiAgUmV0dXJucyBmYWxzZSBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcworICAvLyByZWFjaGVkLgorICBib29sIE5leHQoKTsKKworICAvLyBMaWtlIE5leHQoKSwgYnV0IGFsc28gY29sbGVjdHMgY29tbWVudHMgd2hpY2ggYXBwZWFyIGJldHdlZW4gdGhlIHByZXZpb3VzCisgIC8vIGFuZCBuZXh0IHRva2Vucy4KKyAgLy8KKyAgLy8gQ29tbWVudHMgd2hpY2ggYXBwZWFyIHRvIGJlIGF0dGFjaGVkIHRvIHRoZSBwcmV2aW91cyB0b2tlbiBhcmUgc3RvcmVkCisgIC8vIGluICpwcmV2X3RhaWxpbmdfY29tbWVudHMuICBDb21tZW50cyB3aGljaCBhcHBlYXIgdG8gYmUgYXR0YWNoZWQgdG8gdGhlCisgIC8vIG5leHQgdG9rZW4gYXJlIHN0b3JlZCBpbiAqbmV4dF9sZWFkaW5nX2NvbW1lbnRzLiAgQ29tbWVudHMgYXBwZWFyaW5nIGluCisgIC8vIGJldHdlZW4gd2hpY2ggZG8gbm90IGFwcGVhciB0byBiZSBhdHRhY2hlZCB0byBlaXRoZXIgd2lsbCBiZSBhZGRlZCB0bworICAvLyBkZXRhY2hlZF9jb21tZW50cy4gIEFueSBvZiB0aGVzZSBwYXJhbWV0ZXJzIGNhbiBiZSBOVUxMIHRvIHNpbXBseSBkaXNjYXJkCisgIC8vIHRoZSBjb21tZW50cy4KKyAgLy8KKyAgLy8gQSBzZXJpZXMgb2YgbGluZSBjb21tZW50cyBhcHBlYXJpbmcgb24gY29uc2VjdXRpdmUgbGluZXMsIHdpdGggbm8gb3RoZXIKKyAgLy8gdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCisgIC8vCisgIC8vIE9ubHkgdGhlIGNvbW1lbnQgY29udGVudCBpcyByZXR1cm5lZDsgY29tbWVudCBtYXJrZXJzIChlLmcuIC8vKSBhcmUKKyAgLy8gc3RyaXBwZWQgb3V0LiAgRm9yIGJsb2NrIGNvbW1lbnRzLCBsZWFkaW5nIHdoaXRlc3BhY2UgYW5kIGFuIGFzdGVyaXNrIHdpbGwKKyAgLy8gYmUgc3RyaXBwZWQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggbGluZSBvdGhlciB0aGFuIHRoZSBmaXJzdC4gIE5ld2xpbmVzCisgIC8vIGFyZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0LgorICAvLworICAvLyBFeGFtcGxlczoKKyAgLy8KKyAgLy8gICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCisgIC8vICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBiYXIuCisgIC8vICAgb3B0aW9uYWwgaW50MzIgYmFyID0gMjsKKyAgLy8KKyAgLy8gICBvcHRpb25hbCBzdHJpbmcgYmF6ID0gMzsKKyAgLy8gICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGJhei4KKyAgLy8gICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgorICAvLworICAvLyAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gcXV4LgorICAvLyAgIC8vCisgIC8vICAgLy8gQW5vdGhlciBsaW5lIGF0dGFjaGVkIHRvIHF1eC4KKyAgLy8gICBvcHRpb25hbCBkb3VibGUgcXV4ID0gNDsKKyAgLy8KKyAgLy8gICAvLyBEZXRhY2hlZCBjb21tZW50LiAgVGhpcyBpcyBub3QgYXR0YWNoZWQgdG8gcXV4IG9yIGNvcmdlCisgIC8vICAgLy8gYmVjYXVzZSB0aGVyZSBhcmUgYmxhbmsgbGluZXMgc2VwYXJhdGluZyBpdCBmcm9tIGJvdGguCisgIC8vCisgIC8vICAgb3B0aW9uYWwgc3RyaW5nIGNvcmdlID0gNTsKKyAgLy8gICAvKiBCbG9jayBjb21tZW50IGF0dGFjaGVkCisgIC8vICAgICogdG8gY29yZ2UuICBMZWFkaW5nIGFzdGVyaXNrcworICAvLyAgICAqIHdpbGwgYmUgcmVtb3ZlZC4gKi8KKyAgLy8gICAvKiBCbG9jayBjb21tZW50IGF0dGFjaGVkIHRvCisgIC8vICAgICogZ3JhdWx0LiAqLworICAvLyAgIG9wdGlvbmFsIGludDMyIGdyYXVsdCA9IDY7CisgIGJvb2wgTmV4dFdpdGhDb21tZW50cyhzdHJpbmcqIHByZXZfdHJhaWxpbmdfY29tbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZGV0YWNoZWRfY29tbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIG5leHRfbGVhZGluZ19jb21tZW50cyk7CisKKyAgLy8gUGFyc2UgaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBQYXJzZXMgYSBUWVBFX0ZMT0FUIHRva2VuLiAgVGhpcyBuZXZlciBmYWlscywgc28gbG9uZyBhcyB0aGUgdGV4dCBhY3R1YWxseQorICAvLyBjb21lcyBmcm9tIGEgVFlQRV9GTE9BVCB0b2tlbiBwYXJzZWQgYnkgVG9rZW5pemVyLiAgSWYgaXQgZG9lc24ndCwgdGhlCisgIC8vIHJlc3VsdCBpcyB1bmRlZmluZWQgKHBvc3NpYmx5IGFuIGFzc2VydCBmYWlsdXJlKS4KKyAgc3RhdGljIGRvdWJsZSBQYXJzZUZsb2F0KGNvbnN0IHN0cmluZyYgdGV4dCk7CisKKyAgLy8gUGFyc2VzIGEgVFlQRV9TVFJJTkcgdG9rZW4uICBUaGlzIG5ldmVyIGZhaWxzLCBzbyBsb25nIGFzIHRoZSB0ZXh0IGFjdHVhbGx5CisgIC8vIGNvbWVzIGZyb20gYSBUWVBFX1NUUklORyB0b2tlbiBwYXJzZWQgYnkgVG9rZW5pemVyLiAgSWYgaXQgZG9lc24ndCwgdGhlCisgIC8vIHJlc3VsdCBpcyB1bmRlZmluZWQgKHBvc3NpYmx5IGFuIGFzc2VydCBmYWlsdXJlKS4KKyAgc3RhdGljIHZvaWQgUGFyc2VTdHJpbmcoY29uc3Qgc3RyaW5nJiB0ZXh0LCBzdHJpbmcqIG91dHB1dCk7CisKKyAgLy8gSWRlbnRpY2FsIHRvIFBhcnNlU3RyaW5nLCBidXQgYXBwZW5kcyB0byBvdXRwdXQuCisgIHN0YXRpYyB2b2lkIFBhcnNlU3RyaW5nQXBwZW5kKGNvbnN0IHN0cmluZyYgdGV4dCwgc3RyaW5nKiBvdXRwdXQpOworCisgIC8vIFBhcnNlcyBhIFRZUEVfSU5URUdFUiB0b2tlbi4gIFJldHVybnMgZmFsc2UgaWYgdGhlIHJlc3VsdCB3b3VsZCBiZQorICAvLyBncmVhdGVyIHRoYW4gbWF4X3ZhbHVlLiAgT3RoZXJ3aXNlLCByZXR1cm5zIHRydWUgYW5kIHNldHMgKm91dHB1dCB0byB0aGUKKyAgLy8gcmVzdWx0LiAgSWYgdGhlIHRleHQgaXMgbm90IGZyb20gYSBUb2tlbiBvZiB0eXBlIFRZUEVfSU5URUdFUiBvcmlnaW5hbGx5CisgIC8vIHBhcnNlZCBieSBhIFRva2VuaXplciwgdGhlIHJlc3VsdCBpcyB1bmRlZmluZWQgKHBvc3NpYmx5IGFuIGFzc2VydAorICAvLyBmYWlsdXJlKS4KKyAgc3RhdGljIGJvb2wgUGFyc2VJbnRlZ2VyKGNvbnN0IHN0cmluZyYgdGV4dCwgdWludDY0IG1heF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NCogb3V0cHV0KTsKKworICAvLyBPcHRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFNldCB0cnVlIHRvIGFsbG93IGZsb2F0cyB0byBiZSBzdWZmaXhlZCB3aXRoIHRoZSBsZXR0ZXIgJ2YnLiAgVG9rZW5zCisgIC8vIHdoaWNoIHdvdWxkIG90aGVyd2lzZSBiZSBpbnRlZ2VycyBidXQgd2hpY2ggaGF2ZSB0aGUgJ2YnIHN1ZmZpeCB3aWxsIGJlCisgIC8vIGZvcmNlZCB0byBiZSBpbnRlcnByZXRlZCBhcyBmbG9hdHMuICBGb3IgYWxsIG90aGVyIHB1cnBvc2VzLCB0aGUgJ2YnIGlzCisgIC8vIGlnbm9yZWQuCisgIHZvaWQgc2V0X2FsbG93X2ZfYWZ0ZXJfZmxvYXQoYm9vbCB2YWx1ZSkgeyBhbGxvd19mX2FmdGVyX2Zsb2F0XyA9IHZhbHVlOyB9CisKKyAgLy8gVmFsaWQgdmFsdWVzIGZvciBzZXRfY29tbWVudF9zdHlsZSgpLgorICBlbnVtIENvbW1lbnRTdHlsZSB7CisgICAgLy8gTGluZSBjb21tZW50cyBiZWdpbiB3aXRoICIvLyIsIGJsb2NrIGNvbW1lbnRzIGFyZSBkZWxpbWl0ZWQgYnkgIi8qIiBhbmQKKyAgICAvLyAiKi8iLgorICAgIENQUF9DT01NRU5UX1NUWUxFLAorICAgIC8vIExpbmUgY29tbWVudHMgYmVnaW4gd2l0aCAiIyIuICBObyB3YXkgdG8gd3JpdGUgYmxvY2sgY29tbWVudHMuCisgICAgU0hfQ09NTUVOVF9TVFlMRQorICB9OworCisgIC8vIFNldHMgdGhlIGNvbW1lbnQgc3R5bGUuCisgIHZvaWQgc2V0X2NvbW1lbnRfc3R5bGUoQ29tbWVudFN0eWxlIHN0eWxlKSB7IGNvbW1lbnRfc3R5bGVfID0gc3R5bGU7IH0KKworICAvLyBXaGV0aGVyIHRvIHJlcXVpcmUgd2hpdGVzcGFjZSBiZXR3ZWVuIGEgbnVtYmVyIGFuZCBhIGZpZWxkIG5hbWUuCisgIC8vIERlZmF1bHQgaXMgdHJ1ZS4gRG8gbm90IHVzZSB0aGlzOyBmb3IgR29vZ2xlLWludGVybmFsIGNsZWFudXAgb25seS4KKyAgdm9pZCBzZXRfcmVxdWlyZV9zcGFjZV9hZnRlcl9udW1iZXIoYm9vbCByZXF1aXJlKSB7CisgICAgcmVxdWlyZV9zcGFjZV9hZnRlcl9udW1iZXJfID0gcmVxdWlyZTsKKyAgfQorCisgIC8vIFdoZXRoZXIgdG8gYWxsb3cgc3RyaW5nIGxpdGVyYWxzIHRvIHNwYW4gbXVsdGlwbGUgbGluZXMuIERlZmF1bHQgaXMgZmFsc2UuCisgIC8vIERvIG5vdCB1c2UgdGhpczsgZm9yIEdvb2dsZS1pbnRlcm5hbCBjbGVhbnVwIG9ubHkuCisgIHZvaWQgc2V0X2FsbG93X211bHRpbGluZV9zdHJpbmdzKGJvb2wgYWxsb3cpIHsKKyAgICBhbGxvd19tdWx0aWxpbmVfc3RyaW5nc18gPSBhbGxvdzsKKyAgfQorCisgIC8vIEV4dGVybmFsIGhlbHBlcjogdmFsaWRhdGUgYW4gaWRlbnRpZmllci4KKyAgc3RhdGljIGJvb2wgSXNJZGVudGlmaWVyKGNvbnN0IHN0cmluZyYgdGV4dCk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVG9rZW5pemVyKTsKKworICBUb2tlbiBjdXJyZW50XzsgICAgICAgICAgIC8vIFJldHVybmVkIGJ5IGN1cnJlbnQoKS4KKyAgVG9rZW4gcHJldmlvdXNfOyAgICAgICAgICAvLyBSZXR1cm5lZCBieSBwcmV2aW91cygpLgorCisgIFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0XzsKKyAgRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3Rvcl87CisKKyAgY2hhciBjdXJyZW50X2NoYXJfOyAgICAgICAvLyA9PSBidWZmZXJfW2J1ZmZlcl9wb3NfXSwgdXBkYXRlZCBieSBOZXh0Q2hhcigpLgorICBjb25zdCBjaGFyKiBidWZmZXJfOyAgICAgIC8vIEN1cnJlbnQgYnVmZmVyIHJldHVybmVkIGZyb20gaW5wdXRfLgorICBpbnQgYnVmZmVyX3NpemVfOyAgICAgICAgIC8vIFNpemUgb2YgYnVmZmVyXy4KKyAgaW50IGJ1ZmZlcl9wb3NfOyAgICAgICAgICAvLyBDdXJyZW50IHBvc2l0aW9uIHdpdGhpbiB0aGUgYnVmZmVyLgorICBib29sIHJlYWRfZXJyb3JfOyAgICAgICAgIC8vIERpZCB3ZSBwcmV2aW91c2x5IGVuY291bnRlciBhIHJlYWQgZXJyb3I/CisKKyAgLy8gTGluZSBhbmQgY29sdW1uIG51bWJlciBvZiBjdXJyZW50X2NoYXJfIHdpdGhpbiB0aGUgd2hvbGUgaW5wdXQgc3RyZWFtLgorICBpbnQgbGluZV87CisgIGludCBjb2x1bW5fOworCisgIC8vIFN0cmluZyB0byB3aGljaCB0ZXh0IHNob3VsZCBiZSBhcHBlbmRlZCBhcyB3ZSBhZHZhbmNlIHRocm91Z2ggaXQuCisgIC8vIENhbGwgUmVjb3JkVG8oJnN0cikgdG8gc3RhcnQgcmVjb3JkaW5nIGFuZCBTdG9wUmVjb3JkaW5nKCkgdG8gc3RvcC4KKyAgLy8gRS5nLiBTdGFydFRva2VuKCkgY2FsbHMgUmVjb3JkVG8oJmN1cnJlbnRfLnRleHQpLiAgcmVjb3JkX3N0YXJ0XyBpcyB0aGUKKyAgLy8gcG9zaXRpb24gd2l0aGluIHRoZSBjdXJyZW50IGJ1ZmZlciB3aGVyZSByZWNvcmRpbmcgc3RhcnRlZC4KKyAgc3RyaW5nKiByZWNvcmRfdGFyZ2V0XzsKKyAgaW50IHJlY29yZF9zdGFydF87CisKKyAgLy8gT3B0aW9ucy4KKyAgYm9vbCBhbGxvd19mX2FmdGVyX2Zsb2F0XzsKKyAgQ29tbWVudFN0eWxlIGNvbW1lbnRfc3R5bGVfOworICBib29sIHJlcXVpcmVfc3BhY2VfYWZ0ZXJfbnVtYmVyXzsKKyAgYm9vbCBhbGxvd19tdWx0aWxpbmVfc3RyaW5nc187CisKKyAgLy8gU2luY2Ugd2UgY291bnQgY29sdW1ucyB3ZSBuZWVkIHRvIGludGVycHJldCB0YWJzIHNvbWVob3cuICBXZSdsbCB0YWtlCisgIC8vIHRoZSBzdGFuZGFyZCA4LWNoYXJhY3RlciBkZWZpbml0aW9uIGZvciBsYWNrIG9mIGFueSB3YXkgdG8gZG8gYmV0dGVyLgorICBzdGF0aWMgY29uc3QgaW50IGtUYWJXaWR0aCA9IDg7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSGVscGVyIG1ldGhvZHMuCisKKyAgLy8gQ29uc3VtZSB0aGlzIGNoYXJhY3RlciBhbmQgYWR2YW5jZSB0byB0aGUgbmV4dCBvbmUuCisgIHZvaWQgTmV4dENoYXIoKTsKKworICAvLyBSZWFkIGEgbmV3IGJ1ZmZlciBmcm9tIHRoZSBpbnB1dC4KKyAgdm9pZCBSZWZyZXNoKCk7CisKKyAgaW5saW5lIHZvaWQgUmVjb3JkVG8oc3RyaW5nKiB0YXJnZXQpOworICBpbmxpbmUgdm9pZCBTdG9wUmVjb3JkaW5nKCk7CisKKyAgLy8gQ2FsbGVkIHdoZW4gdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGlzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgYSBuZXcKKyAgLy8gdG9rZW4gKG5vdCBpbmNsdWRpbmcgd2hpdGVzcGFjZSBvciBjb21tZW50cykuCisgIGlubGluZSB2b2lkIFN0YXJ0VG9rZW4oKTsKKyAgLy8gQ2FsbGVkIHdoZW4gdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGlzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlCisgIC8vIGVuZCBvZiB0aGUgbGFzdCB0b2tlbi4gIEFmdGVyIHRoaXMgcmV0dXJucywgY3VycmVudF8udGV4dCB3aWxsCisgIC8vIGNvbnRhaW4gYWxsIHRleHQgY29uc3VtZWQgc2luY2UgU3RhcnRUb2tlbigpIHdhcyBjYWxsZWQuCisgIGlubGluZSB2b2lkIEVuZFRva2VuKCk7CisKKyAgLy8gQ29udmVuaWVuY2UgbWV0aG9kIHRvIGFkZCBhbiBlcnJvciBhdCB0aGUgY3VycmVudCBsaW5lIGFuZCBjb2x1bW4uCisgIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IobGluZV8sIGNvbHVtbl8sIG1lc3NhZ2UpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlIGZvbGxvd2luZyBmb3VyIG1ldGhvZHMgYXJlIHVzZWQgdG8gY29uc3VtZSB0b2tlbnMgb2Ygc3BlY2lmaWMKKyAgLy8gdHlwZXMuICBUaGV5IGFyZSBhY3R1YWxseSB1c2VkIHRvIGNvbnN1bWUgYWxsIGNoYXJhY3RlcnMgKmFmdGVyKgorICAvLyB0aGUgZmlyc3QsIHNpbmNlIHRoZSBjYWxsaW5nIGZ1bmN0aW9uIGNvbnN1bWVzIHRoZSBmaXJzdCBjaGFyYWN0ZXIKKyAgLy8gaW4gb3JkZXIgdG8gZGVjaWRlIHdoYXQga2luZCBvZiB0b2tlbiBpcyBiZWluZyByZWFkLgorCisgIC8vIFJlYWQgYW5kIGNvbnN1bWUgYSBzdHJpbmcsIGVuZGluZyB3aGVuIHRoZSBnaXZlbiBkZWxpbWl0ZXIgaXMKKyAgLy8gY29uc3VtZWQuCisgIHZvaWQgQ29uc3VtZVN0cmluZyhjaGFyIGRlbGltaXRlcik7CisKKyAgLy8gUmVhZCBhbmQgY29uc3VtZSBhIG51bWJlciwgcmV0dXJuaW5nIFRZUEVfRkxPQVQgb3IgVFlQRV9JTlRFR0VSCisgIC8vIGRlcGVuZGluZyBvbiB3aGF0IHdhcyByZWFkLiAgVGhpcyBuZWVkcyB0byBrbm93IGlmIHRoZSBmaXJzdAorICAvLyBjaGFyYWN0ZXIgd2FzIGEgemVybyBpbiBvcmRlciB0byBjb3JyZWN0bHkgcmVjb2duaXplIGhleCBhbmQgb2N0YWwKKyAgLy8gbnVtYmVycy4KKyAgLy8gSXQgYWxzbyBuZWVkcyB0byBrbm93IGlmIHRoZSBmaXJzdCBjaGFyYWN0ZWQgd2FzIGEgLiB0byBwYXJzZSBmbG9hdGluZworICAvLyBwb2ludCBjb3JyZWN0bHkuCisgIFRva2VuVHlwZSBDb25zdW1lTnVtYmVyKGJvb2wgc3RhcnRlZF93aXRoX3plcm8sIGJvb2wgc3RhcnRlZF93aXRoX2RvdCk7CisKKyAgLy8gQ29uc3VtZSB0aGUgcmVzdCBvZiBhIGxpbmUuCisgIHZvaWQgQ29uc3VtZUxpbmVDb21tZW50KHN0cmluZyogY29udGVudCk7CisgIC8vIENvbnN1bWUgdW50aWwgIiovIi4KKyAgdm9pZCBDb25zdW1lQmxvY2tDb21tZW50KHN0cmluZyogY29udGVudCk7CisKKyAgZW51bSBOZXh0Q29tbWVudFN0YXR1cyB7CisgICAgLy8gU3RhcnRlZCBhIGxpbmUgY29tbWVudC4KKyAgICBMSU5FX0NPTU1FTlQsCisKKyAgICAvLyBTdGFydGVkIGEgYmxvY2sgY29tbWVudC4KKyAgICBCTE9DS19DT01NRU5ULAorCisgICAgLy8gQ29uc3VtZWQgYSBzbGFzaCwgdGhlbiByZWFsaXplZCBpdCB3YXNuJ3QgYSBjb21tZW50LiAgY3VycmVudF8gaGFzCisgICAgLy8gYmVlbiBmaWxsZWQgaW4gd2l0aCBhIHNsYXNoIHRva2VuLiAgVGhlIGNhbGxlciBzaG91bGQgcmV0dXJuIGl0LgorICAgIFNMQVNIX05PVF9DT01NRU5ULAorCisgICAgLy8gV2UgZG8gbm90IGFwcGVhciB0byBiZSBzdGFydGluZyBhIGNvbW1lbnQgaGVyZS4KKyAgICBOT19DT01NRU5UCisgIH07CisKKyAgLy8gSWYgd2UncmUgYXQgdGhlIHN0YXJ0IG9mIGEgbmV3IGNvbW1lbnQsIGNvbnN1bWUgaXQgYW5kIHJldHVybiB3aGF0IGtpbmQKKyAgLy8gb2YgY29tbWVudCBpdCBpcy4KKyAgTmV4dENvbW1lbnRTdGF0dXMgVHJ5Q29uc3VtZUNvbW1lbnRTdGFydCgpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGhlbHBlciBtZXRob2RzIG1ha2UgdGhlIHBhcnNpbmcgY29kZSBtb3JlIHJlYWRhYmxlLiAgVGhlCisgIC8vICJjaGFyYWN0ZXIgY2xhc3NlcyIgcmVmZXJyZWQgdG8gYXJlIGRlZmluZWQgYXQgdGhlIHRvcCBvZiB0aGUgLmNjIGZpbGUuCisgIC8vIEJhc2ljYWxseSBpdCBpcyBhIEMrKyBjbGFzcyB3aXRoIG9uZSBtZXRob2Q6CisgIC8vICAgc3RhdGljIGJvb2wgSW5DbGFzcyhjaGFyIGMpOworICAvLyBUaGUgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiBjIGlzIGEgbWVtYmVyIG9mIHRoaXMgImNsYXNzIiwgbGlrZSAiTGV0dGVyIgorICAvLyBvciAiRGlnaXQiLgorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaXMgb2YgdGhlIGdpdmVuIGNoYXJhY3RlcgorICAvLyBjbGFzcywgYnV0IGRvZXMgbm90IGNvbnN1bWUgYW55dGhpbmcuCisgIHRlbXBsYXRlPHR5cGVuYW1lIENoYXJhY3RlckNsYXNzPgorICBpbmxpbmUgYm9vbCBMb29raW5nQXQoKTsKKworICAvLyBJZiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaXMgaW4gdGhlIGdpdmVuIGNsYXNzLCBjb25zdW1lIGl0IGFuZCByZXR1cm4KKyAgLy8gdHJ1ZS4gIE90aGVyd2lzZSByZXR1cm4gZmFsc2UuCisgIC8vIGUuZy4gVHJ5Q29uc3VtZU9uZTxMZXR0ZXI+KCkKKyAgdGVtcGxhdGU8dHlwZW5hbWUgQ2hhcmFjdGVyQ2xhc3M+CisgIGlubGluZSBib29sIFRyeUNvbnN1bWVPbmUoKTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgdHJ5IHRvIGNvbnN1bWUgdGhlIHNwZWNpZmljIGNoYXJhY3RlciBpbmRpY2F0ZWQuCisgIGlubGluZSBib29sIFRyeUNvbnN1bWUoY2hhciBjKTsKKworICAvLyBDb25zdW1lIHplcm8gb3IgbW9yZSBvZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGNsYXNzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KKyAgaW5saW5lIHZvaWQgQ29uc3VtZVplcm9Pck1vcmUoKTsKKworICAvLyBDb25zdW1lIG9uZSBvciBtb3JlIG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXIgY2xhc3Mgb3IgbG9nIHRoZSBnaXZlbgorICAvLyBlcnJvciBtZXNzYWdlLgorICAvLyBlLmcuIENvbnN1bWVPbmVPck1vcmU8RGlnaXQ+KCJFeHBlY3RlZCBkaWdpdHMuIik7CisgIHRlbXBsYXRlPHR5cGVuYW1lIENoYXJhY3RlckNsYXNzPgorICBpbmxpbmUgdm9pZCBDb25zdW1lT25lT3JNb3JlKGNvbnN0IGNoYXIqIGVycm9yKTsKK307CisKKy8vIGlubGluZSBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2lubGluZSBjb25zdCBUb2tlbml6ZXI6OlRva2VuJiBUb2tlbml6ZXI6OmN1cnJlbnQoKSB7CisgIHJldHVybiBjdXJyZW50XzsKK30KKworaW5saW5lIGNvbnN0IFRva2VuaXplcjo6VG9rZW4mIFRva2VuaXplcjo6cHJldmlvdXMoKSB7CisgIHJldHVybiBwcmV2aW91c187Cit9CisKK2lubGluZSB2b2lkIFRva2VuaXplcjo6UGFyc2VTdHJpbmcoY29uc3Qgc3RyaW5nJiB0ZXh0LCBzdHJpbmcqIG91dHB1dCkgeworICBvdXRwdXQtPmNsZWFyKCk7CisgIFBhcnNlU3RyaW5nQXBwZW5kKHRleHQsIG91dHB1dCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1RPS0VOSVpFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXJfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGUwOTZmYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsOTk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxsaW1pdHMuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK25hbWVzcGFjZSB7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIERhdGEtRHJpdmVuIFRlc3QgSW5mcmFzdHJ1Y3R1cmUKKworLy8gVE9ETyhrZW50b24pOiAgVGhpcyBpcyBjb3BpZWQgZnJvbSBjb2RlZF9zdHJlYW1fdW5pdHRlc3QuICBUaGlzIGlzCisvLyAgIHRlbXBvcmFyeSB1bnRpbCB0aGVzZSBmZXRhdXJlcyBhcmUgaW50ZWdyYXRlZCBpbnRvIGdUZXN0IGl0c2VsZi4KKworLy8gVEVTVF8xRCBhbmQgVEVTVF8yRCBhcmUgbWFjcm9zIEknZCBldmVudHVhbGx5IGxpa2UgdG8gc2VlIGFkZGVkIHRvCisvLyBnVGVzdC4gIFRoZXNlIG1hY3JvcyBjYW4gYmUgdXNlZCB0byBkZWNsYXJlIHRlc3RzIHdoaWNoIHNob3VsZCBiZQorLy8gcnVuIG11bHRpcGxlIHRpbWVzLCBvbmNlIGZvciBlYWNoIGl0ZW0gaW4gc29tZSBpbnB1dCBhcnJheS4gIFRFU1RfMUQKKy8vIHRlc3RzIGFsbCBjYXNlcyBpbiBhIHNpbmdsZSBpbnB1dCBhcnJheS4gIFRFU1RfMkQgdGVzdHMgYWxsCisvLyBjb21iaW5hdGlvbnMgb2YgY2FzZXMgZnJvbSB0d28gYXJyYXlzLiAgVGhlIGFycmF5cyBtdXN0IGJlIHN0YXRpY2FsbHkKKy8vIGRlZmluZWQgc3VjaCB0aGF0IHRoZSBHT09HTEVfQVJSQVlTSVpFKCkgbWFjcm8gd29ya3Mgb24gdGhlbS4gIEV4YW1wbGU6CisvLworLy8gaW50IGtDYXNlc1tdID0gezEsIDIsIDMsIDR9CisvLyBURVNUXzFEKE15Rml4dHVyZSwgTXlUZXN0LCBrQ2FzZXMpIHsKKy8vICAgRVhQRUNUX0dUKGtDYXNlc19jYXNlLCAwKTsKKy8vIH0KKy8vCisvLyBUaGlzIHRlc3QgaXRlcmF0ZXMgdGhyb3VnaCB0aGUgbnVtYmVycyAxLCAyLCAzLCBhbmQgNCBhbmQgdGVzdHMgdGhhdAorLy8gdGhleSBhcmUgYWxsIGdyYXRlciB0aGFuIHplcm8uICBJbiBjYXNlIG9mIGZhaWx1cmUsIHRoZSBleGFjdCBjYXNlCisvLyB3aGljaCBmYWlsZWQgd2lsbCBiZSBwcmludGVkLiAgVGhlIGNhc2UgdHlwZSBtdXN0IGJlIHByaW50YWJsZSB1c2luZworLy8gb3N0cmVhbTo6b3BlcmF0b3I8PC4KKworI2RlZmluZSBURVNUXzFEKEZJWFRVUkUsIE5BTUUsIENBU0VTKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjbGFzcyBGSVhUVVJFIyNfIyNOQU1FIyNfREQgOiBwdWJsaWMgRklYVFVSRSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgcHJvdGVjdGVkOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBDYXNlVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHZvaWQgRG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlJiBDQVNFUyMjX2Nhc2UpOyAgICAgICAgICAgICAgICAgICAgICAgXAorICB9OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBURVNUX0YoRklYVFVSRSMjXyMjTkFNRSMjX0RELCBOQU1FKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShDQVNFUyk7IGkrKykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIFNDT1BFRF9UUkFDRSh0ZXN0aW5nOjpNZXNzYWdlKCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgPDwgI0NBU0VTICIgY2FzZSAjIiA8PCBpIDw8ICI6ICIgPDwgQ0FTRVNbaV0pOyAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIERvU2luZ2xlQ2FzZShDQVNFU1tpXSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIENhc2VUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdm9pZCBGSVhUVVJFIyNfIyNOQU1FIyNfREQ6OkRvU2luZ2xlQ2FzZShjb25zdCBDYXNlVHlwZSYgQ0FTRVMjI19jYXNlKQorCisjZGVmaW5lIFRFU1RfMkQoRklYVFVSRSwgTkFNRSwgQ0FTRVMxLCBDQVNFUzIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIEZJWFRVUkUjI18jI05BTUUjI19ERCA6IHB1YmxpYyBGSVhUVVJFIHsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICBwcm90ZWN0ZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIENhc2VUeXBlMSwgdHlwZW5hbWUgQ2FzZVR5cGUyPiAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdm9pZCBEb1NpbmdsZUNhc2UoY29uc3QgQ2FzZVR5cGUxJiBDQVNFUzEjI19jYXNlLCAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ2FzZVR5cGUyJiBDQVNFUzIjI19jYXNlKTsgICAgICAgICAgICAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFRFU1RfRihGSVhUVVJFIyNfIyNOQU1FIyNfREQsIE5BTUUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKENBU0VTMSk7IGkrKykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBHT09HTEVfQVJSQVlTSVpFKENBU0VTMik7IGorKykgeyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgU0NPUEVEX1RSQUNFKHRlc3Rpbmc6Ok1lc3NhZ2UoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICA8PCAjQ0FTRVMxICIgY2FzZSAjIiA8PCBpIDw8ICI6ICIgPDwgQ0FTRVMxW2ldIDw8ICIsICIgICAgICAgICAgIFwKKyAgICAgICAgICA8PCAjQ0FTRVMyICIgY2FzZSAjIiA8PCBqIDw8ICI6ICIgPDwgQ0FTRVMyW2pdKTsgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgRG9TaW5nbGVDYXNlKENBU0VTMVtpXSwgQ0FTRVMyW2pdKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIENhc2VUeXBlMSwgdHlwZW5hbWUgQ2FzZVR5cGUyPiAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdm9pZCBGSVhUVVJFIyNfIyNOQU1FIyNfREQ6OkRvU2luZ2xlQ2FzZShjb25zdCBDYXNlVHlwZTEmIENBU0VTMSMjX2Nhc2UsIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDYXNlVHlwZTImIENBU0VTMiMjX2Nhc2UpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gQW4gaW5wdXQgc3RyZWFtIHRoYXQgaXMgYmFzaWNhbGx5IGxpa2UgYW4gQXJyYXlJbnB1dFN0cmVhbSBidXQgc29tZXRpbWVzCisvLyByZXR1cm5zIGVtcHR5IGJ1ZmZlcnMsIGp1c3QgdG8gdGhyb3cgdXMgb2ZmLgorY2xhc3MgVGVzdElucHV0U3RyZWFtIDogcHVibGljIFplcm9Db3B5SW5wdXRTdHJlYW0geworIHB1YmxpYzoKKyAgVGVzdElucHV0U3RyZWFtKGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplLCBpbnQgYmxvY2tfc2l6ZSkKKyAgICA6IGFycmF5X3N0cmVhbV8oZGF0YSwgc2l6ZSwgYmxvY2tfc2l6ZSksIGNvdW50ZXJfKDApIHt9CisgIH5UZXN0SW5wdXRTdHJlYW0oKSB7fQorCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgICAgLy8gV2UnbGwgcmV0dXJuIGVtcHR5IGJ1ZmZlcnMgc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QgYnVmZmVyLCBhbmQgZXZlcnkKKyAgICAvLyAzIGFuZCA1IGJ1ZmZlcnMgYWZ0ZXIgdGhhdC4KKyAgICBpZiAoY291bnRlcl8gJSAzID09IDAgfHwgY291bnRlcl8gJSA1ID09IDApIHsKKyAgICAgICpkYXRhID0gTlVMTDsKKyAgICAgICpzaXplID0gMDsKKyAgICAgICsrY291bnRlcl87CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgKytjb3VudGVyXzsKKyAgICAgIHJldHVybiBhcnJheV9zdHJlYW1fLk5leHQoZGF0YSwgc2l6ZSk7CisgICAgfQorICB9CisKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KSAgeyByZXR1cm4gYXJyYXlfc3RyZWFtXy5CYWNrVXAoY291bnQpOyB9CisgIGJvb2wgU2tpcChpbnQgY291bnQpICAgIHsgcmV0dXJuIGFycmF5X3N0cmVhbV8uU2tpcChjb3VudCk7ICAgfQorICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCB7IHJldHVybiBhcnJheV9zdHJlYW1fLkJ5dGVDb3VudCgpOyAgIH0KKworIHByaXZhdGU6CisgIEFycmF5SW5wdXRTdHJlYW0gYXJyYXlfc3RyZWFtXzsKKyAgaW50IGNvdW50ZXJfOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBBbiBlcnJvciBjb2xsZWN0b3Igd2hpY2ggc2ltcGx5IGNvbmNhdGVuYXRlcyBhbGwgaXRzIGVycm9ycyBpbnRvIGEgYmlnCisvLyBibG9jayBvZiB0ZXh0IHdoaWNoIGNhbiBiZSBjaGVja2VkLgorY2xhc3MgVGVzdEVycm9yQ29sbGVjdG9yIDogcHVibGljIEVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIFRlc3RFcnJvckNvbGxlY3RvcigpIHt9CisgIH5UZXN0RXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHN0cmluZyB0ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZ0ZXh0XywgIiQwOiQxOiAkMlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gV2UgdGVzdCBlYWNoIG9wZXJhdGlvbiBvdmVyIGEgdmFyaWV0eSBvZiBibG9jayBzaXplcyB0byBpbnN1cmUgdGhhdAorLy8gd2UgdGVzdCBjYXNlcyB3aGVyZSByZWFkcyBjcm9zcyBidWZmZXIgYm91bmRhcmllcyBhcyB3ZWxsIGFzIGNhc2VzCisvLyB3aGVyZSB0aGV5IGRvbid0LiAgVGhpcyBpcyBzb3J0IG9mIGEgYnJ1dGUtZm9yY2UgYXBwcm9hY2ggdG8gdGhpcywKKy8vIGJ1dCBpdCdzIGVhc3kgdG8gd3JpdGUgYW5kIGVhc3kgdG8gdW5kZXJzdGFuZC4KK2NvbnN0IGludCBrQmxvY2tTaXplc1tdID0gezEsIDIsIDMsIDUsIDcsIDEzLCAzMiwgMTAyNH07CisKK2NsYXNzIFRva2VuaXplclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBGb3IgZWFzeSB0ZXN0aW5nLgorICB1aW50NjQgUGFyc2VJbnRlZ2VyKGNvbnN0IHN0cmluZyYgdGV4dCkgeworICAgIHVpbnQ2NCByZXN1bHQ7CisgICAgRVhQRUNUX1RSVUUoVG9rZW5pemVyOjpQYXJzZUludGVnZXIodGV4dCwga3VpbnQ2NG1heCwgJnJlc3VsdCkpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGhlc2UgdGVzdHMgY2F1c2VzIGdjYyAzLjMuNSAoYW5kIGVhcmxpZXI/KSB0byBnaXZlIHRoZSBjcnlwdGljIGVycm9yOgorLy8gICAic29ycnksIHVuaW1wbGVtZW50ZWQ6IGBtZXRob2RfY2FsbF9leHByJyBub3Qgc3VwcG9ydGVkIGJ5IGR1bXBfZXhwciIKKyNpZiAhZGVmaW5lZChfX0dOVUNfXykgfHwgX19HTlVDX18gPiAzIHx8IChfX0dOVUNfXyA9PSAzICYmIF9fR05VQ19NSU5PUl9fID4gMykKKworLy8gSW4gZWFjaCB0ZXN0IGNhc2UsIHRoZSBlbnRpcmUgaW5wdXQgdGV4dCBzaG91bGQgcGFyc2UgYXMgYSBzaW5nbGUgdG9rZW4KKy8vIG9mIHRoZSBnaXZlbiB0eXBlLgorc3RydWN0IFNpbXBsZVRva2VuQ2FzZSB7CisgIHN0cmluZyBpbnB1dDsKKyAgVG9rZW5pemVyOjpUb2tlblR5cGUgdHlwZTsKK307CisKK2lubGluZSBvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNpbXBsZVRva2VuQ2FzZSYgdGVzdF9jYXNlKSB7CisgIHJldHVybiBvdXQgPDwgQ0VzY2FwZSh0ZXN0X2Nhc2UuaW5wdXQpOworfQorCitTaW1wbGVUb2tlbkNhc2Uga1NpbXBsZVRva2VuQ2FzZXNbXSA9IHsKKyAgLy8gVGVzdCBpZGVudGlmaWVycy4KKyAgeyAiaGVsbG8iLCAgICAgICBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiB9LAorCisgIC8vIFRlc3QgaW50ZWdlcnMuCisgIHsgIjEyMyIsICAgICAgICAgVG9rZW5pemVyOjpUWVBFX0lOVEVHRVIgfSwKKyAgeyAiMHhhYjYiLCAgICAgICBUb2tlbml6ZXI6OlRZUEVfSU5URUdFUiB9LAorICB7ICIwWEFCNiIsICAgICAgIFRva2VuaXplcjo6VFlQRV9JTlRFR0VSIH0sCisgIHsgIjBYMTIzNDU2NyIsICAgVG9rZW5pemVyOjpUWVBFX0lOVEVHRVIgfSwKKyAgeyAiMHg4OWFiY2RlZiIsICBUb2tlbml6ZXI6OlRZUEVfSU5URUdFUiB9LAorICB7ICIweDg5QUJDREVGIiwgIFRva2VuaXplcjo6VFlQRV9JTlRFR0VSIH0sCisgIHsgIjAxMjM0NTY3IiwgICAgVG9rZW5pemVyOjpUWVBFX0lOVEVHRVIgfSwKKworICAvLyBUZXN0IGZsb2F0cy4KKyAgeyAiMTIzLjQ1IiwgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMS4iLCAgICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMWUzIiwgICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMUUzIiwgICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMWUtMyIsICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMWUrMyIsICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMS5lMyIsICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiMS4yZTMiLCAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiLjEiLCAgICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiLjFlMyIsICAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiLjFlLTMiLCAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKyAgeyAiLjFlKzMiLCAgICAgICBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgfSwKKworICAvLyBUZXN0IHN0cmluZ3MuCisgIHsgIidoZWxsbyciLCAgICAgVG9rZW5pemVyOjpUWVBFX1NUUklORyB9LAorICB7ICJcImZvb1wiIiwgICAgIFRva2VuaXplcjo6VFlQRV9TVFJJTkcgfSwKKyAgeyAiJ2FcImInIiwgICAgICBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HIH0sCisgIHsgIlwiYSdiXCIiLCAgICAgVG9rZW5pemVyOjpUWVBFX1NUUklORyB9LAorICB7ICInYVxcJ2InIiwgICAgIFRva2VuaXplcjo6VFlQRV9TVFJJTkcgfSwKKyAgeyAiXCJhXFxcImJcIiIsICBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HIH0sCisgIHsgIidcXHhmJyIsICAgICAgVG9rZW5pemVyOjpUWVBFX1NUUklORyB9LAorICB7ICInXFwwJyIsICAgICAgIFRva2VuaXplcjo6VFlQRV9TVFJJTkcgfSwKKworICAvLyBUZXN0IHN5bWJvbHMuCisgIHsgIisiLCAgICAgICAgICAgVG9rZW5pemVyOjpUWVBFX1NZTUJPTCB9LAorICB7ICIuIiwgICAgICAgICAgIFRva2VuaXplcjo6VFlQRV9TWU1CT0wgfSwKK307CisKK1RFU1RfMkQoVG9rZW5pemVyVGVzdCwgU2ltcGxlVG9rZW5zLCBrU2ltcGxlVG9rZW5DYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgLy8gU2V0IHVwIHRoZSB0b2tlbml6ZXIuCisgIFRlc3RJbnB1dFN0cmVhbSBpbnB1dChrU2ltcGxlVG9rZW5DYXNlc19jYXNlLmlucHV0LmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtTaW1wbGVUb2tlbkNhc2VzX2Nhc2UuaW5wdXQuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIFRlc3RFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgIFRva2VuaXplciB0b2tlbml6ZXIoJmlucHV0LCAmZXJyb3JfY29sbGVjdG9yKTsKKworICAvLyBCZWZvcmUgTmV4dCgpIGlzIGNhbGxlZCwgdGhlIGluaXRpYWwgdG9rZW4gc2hvdWxkIGFsd2F5cyBiZSBUWVBFX1NUQVJULgorICBFWFBFQ1RfRVEoVG9rZW5pemVyOjpUWVBFX1NUQVJULCB0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUpOworICBFWFBFQ1RfRVEoIiIsIHRva2VuaXplci5jdXJyZW50KCkudGV4dCk7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmxpbmUpOworICBFWFBFQ1RfRVEoMCwgdG9rZW5pemVyLmN1cnJlbnQoKS5jb2x1bW4pOworICBFWFBFQ1RfRVEoMCwgdG9rZW5pemVyLmN1cnJlbnQoKS5lbmRfY29sdW1uKTsKKworICAvLyBQYXJzZSB0aGUgdG9rZW4uCisgIEFTU0VSVF9UUlVFKHRva2VuaXplci5OZXh0KCkpOworCisgIC8vIENoZWNrIHRoYXQgaXQgaGFzIHRoZSByaWdodCB0eXBlLgorICBFWFBFQ1RfRVEoa1NpbXBsZVRva2VuQ2FzZXNfY2FzZS50eXBlLCB0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUpOworICAvLyBDaGVjayB0aGF0IGl0IGNvbnRhaW5zIHRoZSBjb21wbGV0ZSBpbnB1dCB0ZXh0LgorICBFWFBFQ1RfRVEoa1NpbXBsZVRva2VuQ2FzZXNfY2FzZS5pbnB1dCwgdG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0KTsKKyAgLy8gQ2hlY2sgdGhhdCBpdCBpcyBsb2NhdGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGlucHV0CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmxpbmUpOworICBFWFBFQ1RfRVEoMCwgdG9rZW5pemVyLmN1cnJlbnQoKS5jb2x1bW4pOworICBFWFBFQ1RfRVEoa1NpbXBsZVRva2VuQ2FzZXNfY2FzZS5pbnB1dC5zaXplKCksCisgICAgICAgICAgICB0b2tlbml6ZXIuY3VycmVudCgpLmVuZF9jb2x1bW4pOworCisgIC8vIFRoZXJlIHNob3VsZCBiZSBubyBtb3JlIGlucHV0LgorICBFWFBFQ1RfRkFMU0UodG9rZW5pemVyLk5leHQoKSk7CisKKyAgLy8gQWZ0ZXIgTmV4dCgpIHJldHVybnMgZmFsc2UsIHRoZSB0b2tlbiBzaG91bGQgaGF2ZSB0eXBlIFRZUEVfRU5ELgorICBFWFBFQ1RfRVEoVG9rZW5pemVyOjpUWVBFX0VORCwgdG9rZW5pemVyLmN1cnJlbnQoKS50eXBlKTsKKyAgRVhQRUNUX0VRKCIiLCB0b2tlbml6ZXIuY3VycmVudCgpLnRleHQpOworICBFWFBFQ1RfRVEoMCwgdG9rZW5pemVyLmN1cnJlbnQoKS5saW5lKTsKKyAgRVhQRUNUX0VRKGtTaW1wbGVUb2tlbkNhc2VzX2Nhc2UuaW5wdXQuc2l6ZSgpLCB0b2tlbml6ZXIuY3VycmVudCgpLmNvbHVtbik7CisgIEVYUEVDVF9FUShrU2ltcGxlVG9rZW5DYXNlc19jYXNlLmlucHV0LnNpemUoKSwKKyAgICAgICAgICAgIHRva2VuaXplci5jdXJyZW50KCkuZW5kX2NvbHVtbik7CisKKyAgLy8gVGhlcmUgc2hvdWxkIGJlIG5vIGVycm9ycy4KKyAgRVhQRUNUX1RSVUUoZXJyb3JfY29sbGVjdG9yLnRleHRfLmVtcHR5KCkpOworfQorCitURVNUXzFEKFRva2VuaXplclRlc3QsIEZsb2F0U3VmZml4LCBrQmxvY2tTaXplcykgeworICAvLyBUZXN0IHRoZSAiYWxsb3dfZl9hZnRlcl9mbG9hdCIgb3B0aW9uLgorCisgIC8vIFNldCB1cCB0aGUgdG9rZW5pemVyLgorICBjb25zdCBjaGFyKiB0ZXh0ID0gIjFmIDIuNWYgNmUzZiA3RiI7CisgIFRlc3RJbnB1dFN0cmVhbSBpbnB1dCh0ZXh0LCBzdHJsZW4odGV4dCksIGtCbG9ja1NpemVzX2Nhc2UpOworICBUZXN0RXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBUb2tlbml6ZXIgdG9rZW5pemVyKCZpbnB1dCwgJmVycm9yX2NvbGxlY3Rvcik7CisgIHRva2VuaXplci5zZXRfYWxsb3dfZl9hZnRlcl9mbG9hdCh0cnVlKTsKKworICAvLyBBZHZhbmNlIHRocm91Z2ggdG9rZW5zIGFuZCBjaGVjayB0aGF0IHRoZXkgYXJlIHBhcnNlZCBhcyBleHBlY3RlZC4KKyAgQVNTRVJUX1RSVUUodG9rZW5pemVyLk5leHQoKSk7CisgIEVYUEVDVF9FUSh0b2tlbml6ZXIuY3VycmVudCgpLnRleHQsICIxZiIpOworICBFWFBFQ1RfRVEodG9rZW5pemVyLmN1cnJlbnQoKS50eXBlLCBUb2tlbml6ZXI6OlRZUEVfRkxPQVQpOworICBBU1NFUlRfVFJVRSh0b2tlbml6ZXIuTmV4dCgpKTsKKyAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudGV4dCwgIjIuNWYiKTsKKyAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudHlwZSwgVG9rZW5pemVyOjpUWVBFX0ZMT0FUKTsKKyAgQVNTRVJUX1RSVUUodG9rZW5pemVyLk5leHQoKSk7CisgIEVYUEVDVF9FUSh0b2tlbml6ZXIuY3VycmVudCgpLnRleHQsICI2ZTNmIik7CisgIEVYUEVDVF9FUSh0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUsIFRva2VuaXplcjo6VFlQRV9GTE9BVCk7CisgIEFTU0VSVF9UUlVFKHRva2VuaXplci5OZXh0KCkpOworICBFWFBFQ1RfRVEodG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0LCAiN0YiKTsKKyAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudHlwZSwgVG9rZW5pemVyOjpUWVBFX0ZMT0FUKTsKKworICAvLyBUaGVyZSBzaG91bGQgYmUgbm8gbW9yZSBpbnB1dC4KKyAgRVhQRUNUX0ZBTFNFKHRva2VuaXplci5OZXh0KCkpOworICAvLyBUaGVyZSBzaG91bGQgYmUgbm8gZXJyb3JzLgorICBFWFBFQ1RfVFJVRShlcnJvcl9jb2xsZWN0b3IudGV4dF8uZW1wdHkoKSk7Cit9CisKKyNlbmRpZgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEluIGVhY2ggY2FzZSwgdGhlIGlucHV0IGlzIHBhcnNlZCB0byBwcm9kdWNlIGEgbGlzdCBvZiB0b2tlbnMuICBUaGUKKy8vIGxhc3QgdG9rZW4gaW4gIm91dHB1dCIgbXVzdCBoYXZlIHR5cGUgVFlQRV9FTkQuCitzdHJ1Y3QgTXVsdGlUb2tlbkNhc2UgeworICBzdHJpbmcgaW5wdXQ7CisgIFRva2VuaXplcjo6VG9rZW4gb3V0cHV0WzEwXTsgIC8vIFRoZSBjb21waWxlciB3YW50cyBhIGNvbnN0YW50IGFycmF5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgZm9yIGluaXRpYWxpemF0aW9uIHRvIHdvcmsuICBUaGVyZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBubyByZWFzb24gdGhpcyBjYW4ndCBiZSBpbmNyZWFzZWQgaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZGVkLgorfTsKKworaW5saW5lIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTXVsdGlUb2tlbkNhc2UmIHRlc3RfY2FzZSkgeworICByZXR1cm4gb3V0IDw8IENFc2NhcGUodGVzdF9jYXNlLmlucHV0KTsKK30KKworTXVsdGlUb2tlbkNhc2Uga011bHRpVG9rZW5DYXNlc1tdID0geworICAvLyBUZXN0IGVtcHR5IGlucHV0LgorICB7ICIiLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRU5EICAgICAgICwgIiIgICAgICwgMCwgIDAgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCBhbGwgdG9rZW4gdHlwZXMgYXQgdGhlIHNhbWUgdGltZS4KKyAgeyAiZm9vIDEgMS4yICsgJ2JhciciLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImZvbyIgICwgMCwgIDAsICAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSU5URUdFUiAgICwgIjEiICAgICwgMCwgIDQsICA1IH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRkxPQVQgICAgICwgIjEuMiIgICwgMCwgIDYsICA5IH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1lNQk9MICAgICwgIisiICAgICwgMCwgMTAsIDExIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HICAgICwgIidiYXInIiwgMCwgMTIsIDE3IH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRU5EICAgICAgICwgIiIgICAgICwgMCwgMTcsIDE3IH0sCisgIH19LAorCisgIC8vIFRlc3QgdGhhdCBjb25zZWN1dGl2ZSBzeW1ib2xzIGFyZSBwYXJzZWQgYXMgc2VwYXJhdGUgdG9rZW5zLgorICB7ICIhQCslIiwgeworICAgIHsgVG9rZW5pemVyOjpUWVBFX1NZTUJPTCAgICAsICIhIiAgICAsIDAsIDAsIDEgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9TWU1CT0wgICAgLCAiQCIgICAgLCAwLCAxLCAyIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1lNQk9MICAgICwgIisiICAgICwgMCwgMiwgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX1NZTUJPTCAgICAsICIlIiAgICAsIDAsIDMsIDQgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICAgLCAwLCA0LCA0IH0sCisgIH19LAorCisgIC8vIFRlc3QgdGhhdCBuZXdsaW5lcyBhZmZlY3QgbGluZSBudW1iZXJzIGNvcnJlY3RseS4KKyAgeyAiZm9vIGJhclxucmFiIG9vZiIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiZm9vIiwgMCwgIDAsIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmFyIiwgMCwgIDQsIDcgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAicmFiIiwgMSwgIDAsIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAib29mIiwgMSwgIDQsIDcgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICwgMSwgIDcsIDcgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCB0aGF0IHRhYnMgYWZmZWN0IGNvbHVtbiBudW1iZXJzIGNvcnJlY3RseS4KKyAgeyAiZm9vXHRiYXIgIFx0YmF6IiwgeworICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJmb28iLCAwLCAgMCwgIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmFyIiwgMCwgIDgsIDExIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImJheiIsIDAsIDE2LCAxOSB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgLCAwLCAxOSwgMTkgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCB0aGF0IHRhYnMgaW4gc3RyaW5nIGxpdGVyYWxzIGFmZmVjdCBjb2x1bW4gbnVtYmVycyBjb3JyZWN0bHkuCisgIHsgIlwiZm9vXHRiYXJcIiBiYXoiLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HICAgICwgIlwiZm9vXHRiYXJcIiIsIDAsICAwLCAxMiB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJiYXoiICAgICAgICAgLCAwLCAxMywgMTYgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICAgICAgICAgICwgMCwgMTYsIDE2IH0sCisgIH19LAorCisgIC8vIFRlc3QgdGhhdCBsaW5lIGNvbW1lbnRzIGFyZSBpZ25vcmVkLgorICB7ICJmb28gLy8gVGhpcyBpcyBhIGNvbW1lbnRcbiIKKyAgICAiYmFyIC8vIFRoaXMgaXMgYW5vdGhlciBjb21tZW50IiwgeworICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJmb28iLCAwLCAgMCwgIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmFyIiwgMSwgIDAsICAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRU5EICAgICAgICwgIiIgICAsIDEsIDMwLCAzMCB9LAorICB9fSwKKworICAvLyBUZXN0IHRoYXQgYmxvY2sgY29tbWVudHMgYXJlIGlnbm9yZWQuCisgIHsgImZvbyAvKiBUaGlzIGlzIGEgYmxvY2sgY29tbWVudCAqLyBiYXIiLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImZvbyIsIDAsICAwLCAgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJiYXIiLCAwLCAzNCwgMzcgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICwgMCwgMzcsIDM3IH0sCisgIH19LAorCisgIC8vIFRlc3QgdGhhdCBzaC1zdHlsZSBjb21tZW50cyBhcmUgbm90IGlnbm9yZWQgYnkgZGVmYXVsdC4KKyAgeyAiZm9vICMgYmFyXG4iCisgICAgImJheiIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiZm9vIiwgMCwgMCwgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX1NZTUJPTCAgICAsICIjIiAgLCAwLCA0LCA1IH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImJhciIsIDAsIDYsIDkgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmF6IiwgMSwgMCwgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgLCAxLCAzLCAzIH0sCisgIH19LAorCisgIC8vIFRlc3QgYWxsIHdoaXRlc3BhY2UgY2hhcnMKKyAgeyAiZm9vXG5cdFxyXHZcZmJhciIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiZm9vIiwgMCwgIDAsICAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImJhciIsIDEsIDExLCAxNCB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgLCAxLCAxNCwgMTQgfSwKKyAgfX0sCit9OworCitURVNUXzJEKFRva2VuaXplclRlc3QsIE11bHRpcGxlVG9rZW5zLCBrTXVsdGlUb2tlbkNhc2VzLCBrQmxvY2tTaXplcykgeworICAvLyBTZXQgdXAgdGhlIHRva2VuaXplci4KKyAgVGVzdElucHV0U3RyZWFtIGlucHV0KGtNdWx0aVRva2VuQ2FzZXNfY2FzZS5pbnB1dC5kYXRhKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrTXVsdGlUb2tlbkNhc2VzX2Nhc2UuaW5wdXQuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIFRlc3RFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgIFRva2VuaXplciB0b2tlbml6ZXIoJmlucHV0LCAmZXJyb3JfY29sbGVjdG9yKTsKKworICAvLyBCZWZvcmUgTmV4dCgpIGlzIGNhbGxlZCwgdGhlIGluaXRpYWwgdG9rZW4gc2hvdWxkIGFsd2F5cyBiZSBUWVBFX1NUQVJULgorICBFWFBFQ1RfRVEoVG9rZW5pemVyOjpUWVBFX1NUQVJULCB0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUpOworICBFWFBFQ1RfRVEoIiIsIHRva2VuaXplci5jdXJyZW50KCkudGV4dCk7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmxpbmUpOworICBFWFBFQ1RfRVEoMCwgdG9rZW5pemVyLmN1cnJlbnQoKS5jb2x1bW4pOworICBFWFBFQ1RfRVEoMCwgdG9rZW5pemVyLmN1cnJlbnQoKS5lbmRfY29sdW1uKTsKKworICAvLyBMb29wIHRocm91Z2ggYWxsIGV4cGVjdGVkIHRva2Vucy4KKyAgaW50IGkgPSAwOworICBUb2tlbml6ZXI6OlRva2VuIHRva2VuOworICBkbyB7CisgICAgdG9rZW4gPSBrTXVsdGlUb2tlbkNhc2VzX2Nhc2Uub3V0cHV0W2krK107CisKKyAgICBTQ09QRURfVFJBQ0UodGVzdGluZzo6TWVzc2FnZSgpIDw8ICJUb2tlbiAjIiA8PCBpIDw8ICI6ICIgPDwgdG9rZW4udGV4dCk7CisKKyAgICBUb2tlbml6ZXI6OlRva2VuIHByZXZpb3VzID0gdG9rZW5pemVyLmN1cnJlbnQoKTsKKworICAgIC8vIE5leHQoKSBzaG91bGQgb25seSByZXR1cm4gZmFsc2Ugd2hlbiBpdCBoaXRzIHRoZSBlbmQgdG9rZW4uCisgICAgaWYgKHRva2VuLnR5cGUgIT0gVG9rZW5pemVyOjpUWVBFX0VORCkgeworICAgICAgQVNTRVJUX1RSVUUodG9rZW5pemVyLk5leHQoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEFTU0VSVF9GQUxTRSh0b2tlbml6ZXIuTmV4dCgpKTsKKyAgICB9CisKKyAgICAvLyBDaGVjayB0aGF0IHRoZSBwcmV2aW91cyB0b2tlbiBpcyBzZXQgY29ycmVjdGx5LgorICAgIEVYUEVDVF9FUShwcmV2aW91cy50eXBlLCB0b2tlbml6ZXIucHJldmlvdXMoKS50eXBlKTsKKyAgICBFWFBFQ1RfRVEocHJldmlvdXMudGV4dCwgdG9rZW5pemVyLnByZXZpb3VzKCkudGV4dCk7CisgICAgRVhQRUNUX0VRKHByZXZpb3VzLmxpbmUsIHRva2VuaXplci5wcmV2aW91cygpLmxpbmUpOworICAgIEVYUEVDVF9FUShwcmV2aW91cy5jb2x1bW4sIHRva2VuaXplci5wcmV2aW91cygpLmNvbHVtbik7CisgICAgRVhQRUNUX0VRKHByZXZpb3VzLmVuZF9jb2x1bW4sIHRva2VuaXplci5wcmV2aW91cygpLmVuZF9jb2x1bW4pOworCisgICAgLy8gQ2hlY2sgdGhhdCB0aGUgdG9rZW4gbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgb25lLgorICAgIEVYUEVDVF9FUSh0b2tlbi50eXBlLCB0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUpOworICAgIEVYUEVDVF9FUSh0b2tlbi50ZXh0LCB0b2tlbml6ZXIuY3VycmVudCgpLnRleHQpOworICAgIEVYUEVDVF9FUSh0b2tlbi5saW5lLCB0b2tlbml6ZXIuY3VycmVudCgpLmxpbmUpOworICAgIEVYUEVDVF9FUSh0b2tlbi5jb2x1bW4sIHRva2VuaXplci5jdXJyZW50KCkuY29sdW1uKTsKKyAgICBFWFBFQ1RfRVEodG9rZW4uZW5kX2NvbHVtbiwgdG9rZW5pemVyLmN1cnJlbnQoKS5lbmRfY29sdW1uKTsKKworICB9IHdoaWxlICh0b2tlbi50eXBlICE9IFRva2VuaXplcjo6VFlQRV9FTkQpOworCisgIC8vIFRoZXJlIHNob3VsZCBiZSBubyBlcnJvcnMuCisgIEVYUEVDVF9UUlVFKGVycm9yX2NvbGxlY3Rvci50ZXh0Xy5lbXB0eSgpKTsKK30KKworLy8gVGhpcyB0ZXN0IGNhdXNlcyBnY2MgMy4zLjUgKGFuZCBlYXJsaWVyPykgdG8gZ2l2ZSB0aGUgY3J5cHRpYyBlcnJvcjoKKy8vICAgInNvcnJ5LCB1bmltcGxlbWVudGVkOiBgbWV0aG9kX2NhbGxfZXhwcicgbm90IHN1cHBvcnRlZCBieSBkdW1wX2V4cHIiCisjaWYgIWRlZmluZWQoX19HTlVDX18pIHx8IF9fR05VQ19fID4gMyB8fCAoX19HTlVDX18gPT0gMyAmJiBfX0dOVUNfTUlOT1JfXyA+IDMpCisKK1RFU1RfMUQoVG9rZW5pemVyVGVzdCwgU2hDb21tZW50U3R5bGUsIGtCbG9ja1NpemVzKSB7CisgIC8vIFRlc3QgdGhlICJjb21tZW50X3N0eWxlIiBvcHRpb24uCisKKyAgY29uc3QgY2hhciogdGV4dCA9ICJmb28gIyBiYXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICJiYXogLy8gcXV4XG4iCisgICAgICAgICAgICAgICAgICAgICAiY29yZ2UgLyogZ3JhdWx0ICovXG4iCisgICAgICAgICAgICAgICAgICAgICAiZ2FycGx5IjsKKyAgY29uc3QgY2hhciogY29uc3Qga1Rva2Vuc1tdID0geyJmb28iLCAgLy8gIiMgYmFyIiBpcyBpZ25vcmVkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmF6IiwgIi8iLCAiLyIsICJxdXgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvcmdlIiwgIi8iLCAiKiIsICJncmF1bHQiLCAiKiIsICIvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnYXJwbHkifTsKKworICAvLyBTZXQgdXAgdGhlIHRva2VuaXplci4KKyAgVGVzdElucHV0U3RyZWFtIGlucHV0KHRleHQsIHN0cmxlbih0ZXh0KSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIFRlc3RFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgIFRva2VuaXplciB0b2tlbml6ZXIoJmlucHV0LCAmZXJyb3JfY29sbGVjdG9yKTsKKyAgdG9rZW5pemVyLnNldF9jb21tZW50X3N0eWxlKFRva2VuaXplcjo6U0hfQ09NTUVOVF9TVFlMRSk7CisKKyAgLy8gQWR2YW5jZSB0aHJvdWdoIHRva2VucyBhbmQgY2hlY2sgdGhhdCB0aGV5IGFyZSBwYXJzZWQgYXMgZXhwZWN0ZWQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShrVG9rZW5zKTsgaSsrKSB7CisgICAgRVhQRUNUX1RSVUUodG9rZW5pemVyLk5leHQoKSk7CisgICAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudGV4dCwga1Rva2Vuc1tpXSk7CisgIH0KKworICAvLyBUaGVyZSBzaG91bGQgYmUgbm8gbW9yZSBpbnB1dC4KKyAgRVhQRUNUX0ZBTFNFKHRva2VuaXplci5OZXh0KCkpOworICAvLyBUaGVyZSBzaG91bGQgYmUgbm8gZXJyb3JzLgorICBFWFBFQ1RfVFJVRShlcnJvcl9jb2xsZWN0b3IudGV4dF8uZW1wdHkoKSk7Cit9CisKKyNlbmRpZgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEluIGVhY2ggY2FzZSwgdGhlIGlucHV0IGlzIGV4cGVjdGVkIHRvIGhhdmUgdHdvIHRva2VucyBuYW1lZCAicHJldiIgYW5kCisvLyAibmV4dCIgd2l0aCBjb21tZW50cyBpbiBiZXR3ZWVuLgorc3RydWN0IERvY0NvbW1lbnRDYXNlIHsKKyAgc3RyaW5nIGlucHV0OworCisgIGNvbnN0IGNoYXIqIHByZXZfdHJhaWxpbmdfY29tbWVudHM7CisgIGNvbnN0IGNoYXIqIGRldGFjaGVkX2NvbW1lbnRzWzEwXTsKKyAgY29uc3QgY2hhciogbmV4dF9sZWFkaW5nX2NvbW1lbnRzOworfTsKKworaW5saW5lIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRG9jQ29tbWVudENhc2UmIHRlc3RfY2FzZSkgeworICByZXR1cm4gb3V0IDw8IENFc2NhcGUodGVzdF9jYXNlLmlucHV0KTsKK30KKworRG9jQ29tbWVudENhc2Uga0RvY0NvbW1lbnRDYXNlc1tdID0geworICB7CisgICAgInByZXYgbmV4dCIsCisKKyAgICAiIiwKKyAgICB7fSwKKyAgICAiIgorICAgICAgfSwKKworICAgICAgICB7CisgICAgICAicHJldiAvKiBpZ25vcmVkICovIG5leHQiLAorCisgICAgICAiIiwKKyAgICAgIHt9LAorICAgICAgIiIKKyAgICAgICAgfSwKKworICAgICAgICAgIHsKKyAgICAgICAgInByZXYgLy8gdHJhaWxpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgIm5leHQiLAorCisgICAgICAgICAgICAiIHRyYWlsaW5nIGNvbW1lbnRcbiIsCisgICAgICAgICAgICB7fSwKKyAgICAgICAgICAgICIiCisgICAgICAgICAgfSwKKworICAgICAgICAgICAgeworICAgICAgICAgICJwcmV2XG4iCisgICAgICAgICAgICAgICIvLyBsZWFkaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgIi8vIGxpbmUgMlxuIgorICAgICAgICAgICAgICAibmV4dCIsCisKKyAgICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAgIHt9LAorICAgICAgICAgICAgICAiIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAiIGxpbmUgMlxuIgorICAgICAgICAgICAgfSwKKworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAicHJldlxuIgorICAgICAgICAgICAgICAgICIvLyB0cmFpbGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgIi8vIGxpbmUgMlxuIgorICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAibmV4dCIsCisKKyAgICAgICAgICAgICAgICAiIHRyYWlsaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAiIGxpbmUgMlxuIiwKKyAgICAgICAgICAgICAgICB7fSwKKyAgICAgICAgICAgICAgICAiIgorICAgICAgICAgICAgICB9LAorCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAicHJldiAvLyB0cmFpbGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAiLy8gbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAgICAgICAgICAgICAibmV4dCIsCisKKyAgICAgICAgICAgICAgICAgICIgdHJhaWxpbmcgY29tbWVudFxuIiwKKyAgICAgICAgICAgICAgICAgIHt9LAorICAgICAgICAgICAgICAgICAgIiBsZWFkaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICIgbGluZSAyXG4iCisgICAgICAgICAgICAgICAgfSwKKworICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICJwcmV2IC8qIHRyYWlsaW5nIGJsb2NrIGNvbW1lbnQgKi9cbiIKKyAgICAgICAgICAgICAgICAgICAgIi8qIGxlYWRpbmcgYmxvY2sgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAiICogbGluZSAyXG4iCisgICAgICAgICAgICAgICAgICAgICIgKiBsaW5lIDMgKi8iCisgICAgICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICAgICAiIHRyYWlsaW5nIGJsb2NrIGNvbW1lbnQgIiwKKyAgICAgICAgICAgICAgICAgICAge30sCisgICAgICAgICAgICAgICAgICAgICIgbGVhZGluZyBibG9jayBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICIgbGluZSAyXG4iCisgICAgICAgICAgICAgICAgICAgICIgbGluZSAzICIKKyAgICAgICAgICAgICAgICAgIH0sCisKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgInByZXZcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiLyogdHJhaWxpbmcgYmxvY2sgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICIgKiBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiICogbGluZSAzXG4iCisgICAgICAgICAgICAgICAgICAgICAgIiAqL1xuIgorICAgICAgICAgICAgICAgICAgICAgICIvKiBsZWFkaW5nIGJsb2NrIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiICogbGluZSAyXG4iCisgICAgICAgICAgICAgICAgICAgICAgIiAqIGxpbmUgMyAqLyIKKyAgICAgICAgICAgICAgICAgICAgICAibmV4dCIsCisKKyAgICAgICAgICAgICAgICAgICAgICAiIHRyYWlsaW5nIGJsb2NrIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiIGxpbmUgMlxuIgorICAgICAgICAgICAgICAgICAgICAgICIgbGluZSAzXG4iLAorICAgICAgICAgICAgICAgICAgICAgIHt9LAorICAgICAgICAgICAgICAgICAgICAgICIgbGVhZGluZyBibG9jayBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgIiBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiIGxpbmUgMyAiCisgICAgICAgICAgICAgICAgICAgIH0sCisKKyAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICJwcmV2XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAiLy8gdHJhaWxpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIi8vIGRldGFjaGVkIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICIvLyBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICIvLyBzZWNvbmQgZGV0YWNoZWQgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIi8qIHRoaXJkIGRldGFjaGVkIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICIgKiBsaW5lIDIgKi9cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICIvLyBsZWFkaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICAgICAgICAgIiB0cmFpbGluZyBjb21tZW50XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICIgZGV0YWNoZWQgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAiIGxpbmUgMlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiBzZWNvbmQgZGV0YWNoZWQgY29tbWVudFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiB0aGlyZCBkZXRhY2hlZCBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICIgbGluZSAyICIKKyAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICIgbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICB9LAorCisgICAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICJwcmV2IC8qKi9cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi8vIGRldGFjaGVkIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi8vIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiBkZXRhY2hlZCBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcmV2IC8qKi9cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi8vIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmV4dCIsCisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CisKK1RFU1RfMkQoVG9rZW5pemVyVGVzdCwgRG9jQ29tbWVudHMsIGtEb2NDb21tZW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIC8vIFNldCB1cCB0aGUgdG9rZW5pemVyLgorICBUZXN0SW5wdXRTdHJlYW0gaW5wdXQoa0RvY0NvbW1lbnRDYXNlc19jYXNlLmlucHV0LmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtEb2NDb21tZW50Q2FzZXNfY2FzZS5pbnB1dC5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrQmxvY2tTaXplc19jYXNlKTsKKyAgVGVzdEVycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgVG9rZW5pemVyIHRva2VuaXplcigmaW5wdXQsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIC8vIFNldCB1cCBhIHNlY29uZCB0b2tlbml6ZXIgd2hlcmUgd2UnbGwgcGFzcyBhbGwgTlVMTHMgdG8gTmV4dFdpdGhDb21tZW50cygpLgorICBUZXN0SW5wdXRTdHJlYW0gaW5wdXQyKGtEb2NDb21tZW50Q2FzZXNfY2FzZS5pbnB1dC5kYXRhKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrRG9jQ29tbWVudENhc2VzX2Nhc2UuaW5wdXQuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIFRva2VuaXplciB0b2tlbml6ZXIyKCZpbnB1dDIsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIHRva2VuaXplci5OZXh0KCk7CisgIHRva2VuaXplcjIuTmV4dCgpOworCisgIEVYUEVDVF9FUSgicHJldiIsIHRva2VuaXplci5jdXJyZW50KCkudGV4dCk7CisgIEVYUEVDVF9FUSgicHJldiIsIHRva2VuaXplcjIuY3VycmVudCgpLnRleHQpOworCisgIHN0cmluZyBwcmV2X3RyYWlsaW5nX2NvbW1lbnRzOworICB2ZWN0b3I8c3RyaW5nPiBkZXRhY2hlZF9jb21tZW50czsKKyAgc3RyaW5nIG5leHRfbGVhZGluZ19jb21tZW50czsKKyAgdG9rZW5pemVyLk5leHRXaXRoQ29tbWVudHMoJnByZXZfdHJhaWxpbmdfY29tbWVudHMsICZkZXRhY2hlZF9jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5leHRfbGVhZGluZ19jb21tZW50cyk7CisgIHRva2VuaXplcjIuTmV4dFdpdGhDb21tZW50cyhOVUxMLCBOVUxMLCBOVUxMKTsKKyAgRVhQRUNUX0VRKCJuZXh0IiwgdG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0KTsKKyAgRVhQRUNUX0VRKCJuZXh0IiwgdG9rZW5pemVyMi5jdXJyZW50KCkudGV4dCk7CisKKyAgRVhQRUNUX0VRKGtEb2NDb21tZW50Q2FzZXNfY2FzZS5wcmV2X3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgcHJldl90cmFpbGluZ19jb21tZW50cyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXRhY2hlZF9jb21tZW50cy5zaXplKCk7IGkrKykgeworICAgIEFTU0VSVF9MVChpLCBHT09HTEVfQVJSQVlTSVpFKGtEb2NDb21tZW50Q2FzZXMpKTsKKyAgICBBU1NFUlRfVFJVRShrRG9jQ29tbWVudENhc2VzX2Nhc2UuZGV0YWNoZWRfY29tbWVudHNbaV0gIT0gTlVMTCk7CisgICAgRVhQRUNUX0VRKGtEb2NDb21tZW50Q2FzZXNfY2FzZS5kZXRhY2hlZF9jb21tZW50c1tpXSwKKyAgICAgICAgICAgICAgZGV0YWNoZWRfY29tbWVudHNbaV0pOworICB9CisKKyAgLy8gVmVyaWZ5IHRoYXQgd2UgbWF0Y2hlZCBhbGwgdGhlIGRldGFjaGVkIGNvbW1lbnRzLgorICBFWFBFQ1RfRVEoTlVMTCwKKyAgICAgIGtEb2NDb21tZW50Q2FzZXNfY2FzZS5kZXRhY2hlZF9jb21tZW50c1tkZXRhY2hlZF9jb21tZW50cy5zaXplKCldKTsKKworICBFWFBFQ1RfRVEoa0RvY0NvbW1lbnRDYXNlc19jYXNlLm5leHRfbGVhZGluZ19jb21tZW50cywKKyAgICAgICAgICAgIG5leHRfbGVhZGluZ19jb21tZW50cyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gVGVzdCBwYXJzZSBoZWxwZXJzLiAgSXQncyBub3QgcmVhbGx5IHdvcnRoIHNldHRpbmcgdXAgYSBmdWxsIGRhdGEtZHJpdmVuCisvLyB0ZXN0IGhlcmUuCitURVNUX0YoVG9rZW5pemVyVGVzdCwgUGFyc2VJbnRlZ2VyKSB7CisgIEVYUEVDVF9FUSgwLCBQYXJzZUludGVnZXIoIjAiKSk7CisgIEVYUEVDVF9FUSgxMjMsIFBhcnNlSW50ZWdlcigiMTIzIikpOworICBFWFBFQ1RfRVEoMHhhYmNkZWYxMnUsIFBhcnNlSW50ZWdlcigiMHhhYmNkZWYxMiIpKTsKKyAgRVhQRUNUX0VRKDB4YWJjZGVmMTJ1LCBQYXJzZUludGVnZXIoIjB4QUJDREVGMTIiKSk7CisgIEVYUEVDVF9FUShrdWludDY0bWF4LCBQYXJzZUludGVnZXIoIjB4RkZGRkZGRkZGRkZGRkZGRiIpKTsKKyAgRVhQRUNUX0VRKDAxMjM0NTY3LCBQYXJzZUludGVnZXIoIjAxMjM0NTY3IikpOworICBFWFBFQ1RfRVEoMFgxMjMsIFBhcnNlSW50ZWdlcigiMFgxMjMiKSk7CisKKyAgLy8gVGVzdCBpbnZhbGlkIGludGVnZXJzIHRoYXQgbWF5IHN0aWxsIGJlIHRva2VuaXplZCBhcyBpbnRlZ2Vycy4KKyAgRVhQRUNUX0VRKDAsIFBhcnNlSW50ZWdlcigiMHgiKSk7CisKKyAgdWludDY0IGk7CisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QgIC8vIGRlYXRoIHRlc3RzIGRvIG5vdCB3b3JrIG9uIFdpbmRvd3MgeWV0CisgIC8vIFRlc3QgaW52YWxpZCBpbnRlZ2VycyB0aGF0IHdpbGwgbmV2ZXIgYmUgdG9rZW5pemVkIGFzIGludGVnZXJzLgorICBFWFBFQ1RfREVCVUdfREVBVEgoVG9rZW5pemVyOjpQYXJzZUludGVnZXIoInp4eSIsIGt1aW50NjRtYXgsICZpKSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhbiBpbnRlZ2VyIik7CisgIEVYUEVDVF9ERUJVR19ERUFUSChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMS4yIiwga3VpbnQ2NG1heCwgJmkpLAorICAgICJwYXNzZWQgdGV4dCB0aGF0IGNvdWxkIG5vdCBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGFuIGludGVnZXIiKTsKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIwOCIsIGt1aW50NjRtYXgsICZpKSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhbiBpbnRlZ2VyIik7CisgIEVYUEVDVF9ERUJVR19ERUFUSChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMHhnIiwga3VpbnQ2NG1heCwgJmkpLAorICAgICJwYXNzZWQgdGV4dCB0aGF0IGNvdWxkIG5vdCBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGFuIGludGVnZXIiKTsKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCItMSIsIGt1aW50NjRtYXgsICZpKSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhbiBpbnRlZ2VyIik7CisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisKKyAgLy8gVGVzdCBvdmVyZmxvd3MuCisgIEVYUEVDVF9UUlVFIChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMCIsIDAsICZpKSk7CisgIEVYUEVDVF9GQUxTRShUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMSIsIDAsICZpKSk7CisgIEVYUEVDVF9UUlVFIChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMSIsIDEsICZpKSk7CisgIEVYUEVDVF9UUlVFIChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMTIzNDUiLCAxMjM0NSwgJmkpKTsKKyAgRVhQRUNUX0ZBTFNFKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIxMjM0NiIsIDEyMzQ1LCAmaSkpOworICBFWFBFQ1RfVFJVRSAoVG9rZW5pemVyOjpQYXJzZUludGVnZXIoIjB4RkZGRkZGRkZGRkZGRkZGRiIgLCBrdWludDY0bWF4LCAmaSkpOworICBFWFBFQ1RfRkFMU0UoVG9rZW5pemVyOjpQYXJzZUludGVnZXIoIjB4MTAwMDAwMDAwMDAwMDAwMDAiLCBrdWludDY0bWF4LCAmaSkpOworfQorCitURVNUX0YoVG9rZW5pemVyVGVzdCwgUGFyc2VGbG9hdCkgeworICBFWFBFQ1RfRE9VQkxFX0VRKDEgICAgLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjEuIikpOworICBFWFBFQ1RfRE9VQkxFX0VRKDFlMyAgLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjFlMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxZTMgICwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxRTMiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMS41ZTMsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMS41ZTMiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLjEgICAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiLjEiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLjI1ICAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiLjI1IikpOworICBFWFBFQ1RfRE9VQkxFX0VRKC4xZTMgLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIi4xZTMiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLjI1ZTMsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiLjI1ZTMiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLjFlKzMsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiLjFlKzMiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLjFlLTMsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiLjFlLTMiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoNSAgICAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiNSIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSg2ZS0xMiwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCI2ZS0xMiIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLjIgICwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxLjIiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMS5lMiAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMS5lMiIpKTsKKworICAvLyBUZXN0IGludmFsaWQgaW50ZWdlcnMgdGhhdCBtYXkgc3RpbGwgYmUgdG9rZW5pemVkIGFzIGludGVnZXJzLgorICBFWFBFQ1RfRE9VQkxFX0VRKDEsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMWUiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMSwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxZS0iKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMSwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxLmUiKSk7CisKKyAgLy8gVGVzdCAnZicgc3VmZml4LgorICBFWFBFQ1RfRE9VQkxFX0VRKDEsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMWYiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMSwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxLjBmIikpOworICBFWFBFQ1RfRE9VQkxFX0VRKDEsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMUYiKSk7CisKKyAgLy8gVGhlc2Ugc2hvdWxkIHBhcnNlIHN1Y2Nlc3NmdWxseSBldmVuIHRob3VnaCB0aGV5IGFyZSBvdXQgb2YgcmFuZ2UuCisgIC8vIE92ZXJmbG93cyBiZWNvbWUgaW5maW5pdHkgYW5kIHVuZGVyZmxvd3MgYmVjb21lIHplcm8uCisgIEVYUEVDVF9FUSggICAgIDAuMCwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxZS05OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5IikpOworICBFWFBFQ1RfRVEoSFVHRV9WQUwsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMWUrOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OSIpKTsKKworI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUICAvLyBkZWF0aCB0ZXN0cyBkbyBub3Qgd29yayBvbiBXaW5kb3dzIHlldAorICAvLyBUZXN0IGludmFsaWQgaW50ZWdlcnMgdGhhdCB3aWxsIG5ldmVyIGJlIHRva2VuaXplZCBhcyBpbnRlZ2Vycy4KKyAgRVhQRUNUX0RFQlVHX0RFQVRIKFRva2VuaXplcjo6UGFyc2VGbG9hdCgienh5IiksCisgICAgInBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiB0b2tlbml6ZWQgYXMgYSBmbG9hdCIpOworICBFWFBFQ1RfREVCVUdfREVBVEgoVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxLWUwIiksCisgICAgInBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiB0b2tlbml6ZWQgYXMgYSBmbG9hdCIpOworICBFWFBFQ1RfREVCVUdfREVBVEgoVG9rZW5pemVyOjpQYXJzZUZsb2F0KCItMS4wIiksCisgICAgInBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiB0b2tlbml6ZWQgYXMgYSBmbG9hdCIpOworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorfQorCitURVNUX0YoVG9rZW5pemVyVGVzdCwgUGFyc2VTdHJpbmcpIHsKKyAgc3RyaW5nIG91dHB1dDsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ2hlbGxvJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgb3V0cHV0KTsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiXCJibGFoXFxuYmxhaDJcIiIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoImJsYWhcbmJsYWgyIiwgb3V0cHV0KTsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ1xcMXhcXDFcXDEyM1xcNzM5XFw1MlxcMzM0blxcMyciLCAmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKCJcMXhcMVwxMjNcNzM5XDUyXDMzNG5cMyIsIG91dHB1dCk7CisgIFRva2VuaXplcjo6UGFyc2VTdHJpbmcoIidcXHgyMFxceDQnIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgiXHgyMFx4NCIsIG91dHB1dCk7CisKKyAgLy8gVGVzdCBpbnZhbGlkIHN0cmluZ3MgdGhhdCBtYXkgc3RpbGwgYmUgdG9rZW5pemVkIGFzIHN0cmluZ3MuCisgIFRva2VuaXplcjo6UGFyc2VTdHJpbmcoIlwiXFxhXFxsXFx2XFx0IiwgJm91dHB1dCk7ICAvLyBcbCBpcyBpbnZhbGlkCisgIEVYUEVDVF9FUSgiXGE/XHZcdCIsIG91dHB1dCk7CisgIFRva2VuaXplcjo6UGFyc2VTdHJpbmcoIiciLCAmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKCIiLCBvdXRwdXQpOworICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCInXFwiLCAmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKCJcXCIsIG91dHB1dCk7CisKKyAgLy8gRXhwZXJpbWVudCB3aXRoIFVuaWNvZGUgZXNjYXBlcy4gSGVyZSBhcmUgb25lLSwgdHdvLSBhbmQgdGhyZWUtYnl0ZSBVbmljb2RlCisgIC8vIGNoYXJhY3RlcnMuCisgIFRva2VuaXplcjo6UGFyc2VTdHJpbmcoIidcXHUwMDI0XFx1MDBhMlxcdTIwYWNcXFUwMDAyNGI2MlhYJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoIiTCouKCrPCkraJYWCIsIG91dHB1dCk7CisgIC8vIFNhbWUgdGhpbmcgZW5jb2RlZCB1c2luZyBVVEYxNi4KKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ1xcdTAwMjRcXHUwMGEyXFx1MjBhY1xcdWQ4NTJcXHVkZjYyWFgnIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgiJMKi4oKs8KStolhYIiwgb3V0cHV0KTsKKyAgLy8gSGVyZSdzIHNvbWUgYnJva2VuIFVURjE2OyB0aGVyZSdzIGEgaGVhZCBzdXJyb2dhdGUgd2l0aCBubyB0YWlsIHN1cnJvZ2F0ZS4KKyAgLy8gV2UganVzdCBvdXRwdXQgdGhpcyBhcyBpZiBpdCB3ZXJlIFVURjg7IGl0J3Mgbm90IGEgZGVmaW5lZCBjb2RlIHBvaW50LCBidXQKKyAgLy8gaXQgaGFzIGEgZGVmaW5lZCBlbmNvZGluZy4KKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ1xcdWQ4NTJYWCciLCAmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKCJceGVkXHhhMVx4OTJYWCIsIG91dHB1dCk7CisgIC8vIE1hbGZvcm1lZCBlc2NhcGU6IERlbW9ucyBtYXkgZmx5IG91dCBvZiB0aGUgbm9zZS4KKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiXFx1MCIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoInUwIiwgb3V0cHV0KTsKKworICAvLyBUZXN0IGludmFsaWQgc3RyaW5ncyB0aGF0IHdpbGwgbmV2ZXIgYmUgdG9rZW5pemVkIGFzIHN0cmluZ3MuCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QgIC8vIGRlYXRoIHRlc3RzIGRvIG5vdCB3b3JrIG9uIFdpbmRvd3MgeWV0CisgIEVYUEVDVF9ERUJVR19ERUFUSChUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCIiLCAmb3V0cHV0KSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhIHN0cmluZyIpOworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorfQorCitURVNUX0YoVG9rZW5pemVyVGVzdCwgUGFyc2VTdHJpbmdBcHBlbmQpIHsKKyAgLy8gQ2hlY2sgdGhhdCBQYXJzZVN0cmluZyBhbmQgUGFyc2VTdHJpbmdBcHBlbmQgZGlmZmVyLgorICBzdHJpbmcgb3V0cHV0KCJzdHVmZisiKTsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZ0FwcGVuZCgiJ2hlbGxvJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoInN0dWZmK2hlbGxvIiwgb3V0cHV0KTsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ2hlbGxvJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgb3V0cHV0KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBFYWNoIGNhc2UgcGFyc2VzIHNvbWUgaW5wdXQgdGV4dCwgaWdub3JpbmcgdGhlIHRva2VucyBwcm9kdWNlZCwgYW5kCisvLyBjaGVja3MgdGhhdCB0aGUgZXJyb3Igb3V0cHV0IG1hdGNoZXMgd2hhdCBpcyBleHBlY3RlZC4KK3N0cnVjdCBFcnJvckNhc2UgeworICBzdHJpbmcgaW5wdXQ7CisgIGJvb2wgcmVjb3ZlcmFibGU7ICAvLyBUcnVlIGlmIHRoZSB0b2tlbml6ZXIgc2hvdWxkIGJlIGFibGUgdG8gcmVjb3ZlciBhbmQKKyAgICAgICAgICAgICAgICAgICAgIC8vIHBhcnNlIG1vcmUgdG9rZW5zIGFmdGVyIHNlZWluZyB0aGlzIGVycm9yLiAgQ2FzZXMKKyAgICAgICAgICAgICAgICAgICAgIC8vIGZvciB3aGljaCB0aGlzIGlzIHRydWUgbXVzdCBlbmQgd2l0aCAiZm9vIiBhcworICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxhc3QgdG9rZW4sIHdoaWNoIHRoZSB0ZXN0IHdpbGwgY2hlY2sgZm9yLgorICBjb25zdCBjaGFyKiBlcnJvcnM7Cit9OworCitpbmxpbmUgb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtJiBvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFcnJvckNhc2UmIHRlc3RfY2FzZSkgeworICByZXR1cm4gb3V0IDw8IENFc2NhcGUodGVzdF9jYXNlLmlucHV0KTsKK30KKworRXJyb3JDYXNlIGtFcnJvckNhc2VzW10gPSB7CisgIC8vIFN0cmluZyBlcnJvcnMuCisgIHsgIidcXGwnIGZvbyIsIHRydWUsCisgICAgIjA6MjogSW52YWxpZCBlc2NhcGUgc2VxdWVuY2UgaW4gc3RyaW5nIGxpdGVyYWwuXG4iIH0sCisgIHsgIidcXHgnIGZvbyIsIHRydWUsCisgICAgIjA6MzogRXhwZWN0ZWQgaGV4IGRpZ2l0cyBmb3IgZXNjYXBlIHNlcXVlbmNlLlxuIiB9LAorICB7ICInZm9vIiwgZmFsc2UsCisgICAgIjA6NDogVW5leHBlY3RlZCBlbmQgb2Ygc3RyaW5nLlxuIiB9LAorICB7ICInYmFyXG5mb28iLCB0cnVlLAorICAgICIwOjQ6IFN0cmluZyBsaXRlcmFscyBjYW5ub3QgY3Jvc3MgbGluZSBib3VuZGFyaWVzLlxuIiB9LAorICB7ICInXFx1MDEnIGZvbyIsIHRydWUsCisgICAgIjA6NTogRXhwZWN0ZWQgZm91ciBoZXggZGlnaXRzIGZvciBcXHUgZXNjYXBlIHNlcXVlbmNlLlxuIiB9LAorICB7ICInXFx1MDEnIGZvbyIsIHRydWUsCisgICAgIjA6NTogRXhwZWN0ZWQgZm91ciBoZXggZGlnaXRzIGZvciBcXHUgZXNjYXBlIHNlcXVlbmNlLlxuIiB9LAorICB7ICInXFx1WFlaJyBmb28iLCB0cnVlLAorICAgICIwOjM6IEV4cGVjdGVkIGZvdXIgaGV4IGRpZ2l0cyBmb3IgXFx1IGVzY2FwZSBzZXF1ZW5jZS5cbiIgfSwKKworICAvLyBJbnRlZ2VyIGVycm9ycy4KKyAgeyAiMTIzZm9vIiwgdHJ1ZSwKKyAgICAiMDozOiBOZWVkIHNwYWNlIGJldHdlZW4gbnVtYmVyIGFuZCBpZGVudGlmaWVyLlxuIiB9LAorCisgIC8vIEhleC9vY3RhbCBlcnJvcnMuCisgIHsgIjB4IGZvbyIsIHRydWUsCisgICAgIjA6MjogXCIweFwiIG11c3QgYmUgZm9sbG93ZWQgYnkgaGV4IGRpZ2l0cy5cbiIgfSwKKyAgeyAiMDU0MTgyMyBmb28iLCB0cnVlLAorICAgICIwOjQ6IE51bWJlcnMgc3RhcnRpbmcgd2l0aCBsZWFkaW5nIHplcm8gbXVzdCBiZSBpbiBvY3RhbC5cbiIgfSwKKyAgeyAiMHgxMjN6IGZvbyIsIHRydWUsCisgICAgIjA6NTogTmVlZCBzcGFjZSBiZXR3ZWVuIG51bWJlciBhbmQgaWRlbnRpZmllci5cbiIgfSwKKyAgeyAiMHgxMjMuNCBmb28iLCB0cnVlLAorICAgICIwOjU6IEhleCBhbmQgb2N0YWwgbnVtYmVycyBtdXN0IGJlIGludGVnZXJzLlxuIiB9LAorICB7ICIwMTIzLjQgZm9vIiwgdHJ1ZSwKKyAgICAiMDo0OiBIZXggYW5kIG9jdGFsIG51bWJlcnMgbXVzdCBiZSBpbnRlZ2Vycy5cbiIgfSwKKworICAvLyBGbG9hdCBlcnJvcnMuCisgIHsgIjFlIGZvbyIsIHRydWUsCisgICAgIjA6MjogXCJlXCIgbXVzdCBiZSBmb2xsb3dlZCBieSBleHBvbmVudC5cbiIgfSwKKyAgeyAiMWUtIGZvbyIsIHRydWUsCisgICAgIjA6MzogXCJlXCIgbXVzdCBiZSBmb2xsb3dlZCBieSBleHBvbmVudC5cbiIgfSwKKyAgeyAiMS4yLjMgZm9vIiwgdHJ1ZSwKKyAgICAiMDozOiBBbHJlYWR5IHNhdyBkZWNpbWFsIHBvaW50IG9yIGV4cG9uZW50OyBjYW4ndCBoYXZlIGFub3RoZXIgb25lLlxuIiB9LAorICB7ICIxZTIuMyBmb28iLCB0cnVlLAorICAgICIwOjM6IEFscmVhZHkgc2F3IGRlY2ltYWwgcG9pbnQgb3IgZXhwb25lbnQ7IGNhbid0IGhhdmUgYW5vdGhlciBvbmUuXG4iIH0sCisgIHsgImEuMSBmb28iLCB0cnVlLAorICAgICIwOjE6IE5lZWQgc3BhY2UgYmV0d2VlbiBpZGVudGlmaWVyIGFuZCBkZWNpbWFsIHBvaW50LlxuIiB9LAorICAvLyBhbGxvd19mX2FmdGVyX2Zsb2F0IG5vdCBlbmFibGVkLCBzbyB0aGlzIHNob3VsZCBiZSBhbiBlcnJvci4KKyAgeyAiMS4wZiBmb28iLCB0cnVlLAorICAgICIwOjM6IE5lZWQgc3BhY2UgYmV0d2VlbiBudW1iZXIgYW5kIGlkZW50aWZpZXIuXG4iIH0sCisKKyAgLy8gQmxvY2sgY29tbWVudCBlcnJvcnMuCisgIHsgIi8qIiwgZmFsc2UsCisgICAgIjA6MjogRW5kLW9mLWZpbGUgaW5zaWRlIGJsb2NrIGNvbW1lbnQuXG4iCisgICAgIjA6MDogICBDb21tZW50IHN0YXJ0ZWQgaGVyZS5cbiJ9LAorICB7ICIvKi8qLyBmb28iLCB0cnVlLAorICAgICIwOjM6IFwiLypcIiBpbnNpZGUgYmxvY2sgY29tbWVudC4gIEJsb2NrIGNvbW1lbnRzIGNhbm5vdCBiZSBuZXN0ZWQuXG4ifSwKKworICAvLyBDb250cm9sIGNoYXJhY3RlcnMuICBNdWx0aXBsZSBjb25zZWN1dGl2ZSBjb250cm9sIGNoYXJhY3RlcnMgc2hvdWxkIG9ubHkKKyAgLy8gcHJvZHVjZSBvbmUgZXJyb3IuCisgIHsgIlxiIGZvbyIsIHRydWUsCisgICAgIjA6MDogSW52YWxpZCBjb250cm9sIGNoYXJhY3RlcnMgZW5jb3VudGVyZWQgaW4gdGV4dC5cbiIgfSwKKyAgeyAiXGJcYiBmb28iLCB0cnVlLAorICAgICIwOjA6IEludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuXG4iIH0sCisKKyAgLy8gQ2hlY2sgdGhhdCBjb250cm9sIGNoYXJhY3RlcnMgYXQgZW5kIG9mIGlucHV0IGRvbid0IHJlc3VsdCBpbiBhbgorICAvLyBpbmZpbml0ZSBsb29wLgorICB7ICJcYiIsIGZhbHNlLAorICAgICIwOjA6IEludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuXG4iIH0sCisKKyAgLy8gQ2hlY2sgcmVjb3ZlcnkgZnJvbSAnXDAnLiAgV2UgaGF2ZSB0byBleHBsaWNpdGx5IHNwZWNpZnkgdGhlIGxlbmd0aCBvZgorICAvLyB0aGVzZSBzdHJpbmdzIGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBzdHJpbmcgY29uc3RydWN0b3Igd2lsbCBqdXN0IGNhbGwKKyAgLy8gc3RybGVuKCkgd2hpY2ggd2lsbCBzZWUgdGhlIGZpcnN0ICdcMCcgYW5kIHRoaW5rIHRoYXQgaXMgdGhlIGVuZCBvZiB0aGUKKyAgLy8gc3RyaW5nLgorICB7IHN0cmluZygiXDBmb28iLCA0KSwgdHJ1ZSwKKyAgICAiMDowOiBJbnZhbGlkIGNvbnRyb2wgY2hhcmFjdGVycyBlbmNvdW50ZXJlZCBpbiB0ZXh0LlxuIiB9LAorICB7IHN0cmluZygiXDBcMGZvbyIsIDUpLCB0cnVlLAorICAgICIwOjA6IEludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuXG4iIH0sCisKKyAgLy8gQ2hlY2sgZXJyb3IgZnJvbSBoaWdoIG9yZGVyIGJpdHMgc2V0CisgIHsgIlwzMDBmb28iLCB0cnVlLAorICAgICIwOjA6IEludGVycHJldGluZyBub24gYXNjaWkgY29kZXBvaW50IDE5Mi5cbiIgfSwKK307CisKK1RFU1RfMkQoVG9rZW5pemVyVGVzdCwgRXJyb3JzLCBrRXJyb3JDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgLy8gU2V0IHVwIHRoZSB0b2tlbml6ZXIuCisgIFRlc3RJbnB1dFN0cmVhbSBpbnB1dChrRXJyb3JDYXNlc19jYXNlLmlucHV0LmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtFcnJvckNhc2VzX2Nhc2UuaW5wdXQuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIFRlc3RFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgIFRva2VuaXplciB0b2tlbml6ZXIoJmlucHV0LCAmZXJyb3JfY29sbGVjdG9yKTsKKworICAvLyBJZ25vcmUgYWxsIGlucHV0LCBleGNlcHQgcmVtZW1iZXIgaWYgdGhlIGxhc3QgdG9rZW4gd2FzICJmb28iLgorICBib29sIGxhc3Rfd2FzX2ZvbyA9IGZhbHNlOworICB3aGlsZSAodG9rZW5pemVyLk5leHQoKSkgeworICAgIGxhc3Rfd2FzX2ZvbyA9IHRva2VuaXplci5jdXJyZW50KCkudGV4dCA9PSAiZm9vIjsKKyAgfQorCisgIC8vIENoZWNrIHRoYXQgdGhlIGVycm9ycyBtYXRjaCB3aGF0IHdhcyBleHBlY3RlZC4KKyAgRVhQRUNUX0VRKGtFcnJvckNhc2VzX2Nhc2UuZXJyb3JzLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworCisgIC8vIElmIHRoZSBlcnJvciB3YXMgcmVjb3ZlcmFibGUsIG1ha2Ugc3VyZSB3ZSBzYXcgImZvbyIgYWZ0ZXIgaXQuCisgIGlmIChrRXJyb3JDYXNlc19jYXNlLnJlY292ZXJhYmxlKSB7CisgICAgRVhQRUNUX1RSVUUobGFzdF93YXNfZm9vKTsKKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RFU1RfMUQoVG9rZW5pemVyVGVzdCwgQmFja1VwT25EZXN0cnVjdGlvbiwga0Jsb2NrU2l6ZXMpIHsKKyAgc3RyaW5nIHRleHQgPSAiZm9vIGJhciI7CisgIFRlc3RJbnB1dFN0cmVhbSBpbnB1dCh0ZXh0LmRhdGEoKSwgdGV4dC5zaXplKCksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIC8vIENyZWF0ZSBhIHRva2VuaXplciwgcmVhZCBvbmUgdG9rZW4sIHRoZW4gZGVzdHJveSBpdC4KKyAgeworICAgIFRlc3RFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgICAgVG9rZW5pemVyIHRva2VuaXplcigmaW5wdXQsICZlcnJvcl9jb2xsZWN0b3IpOworCisgICAgdG9rZW5pemVyLk5leHQoKTsKKyAgfQorCisgIC8vIE9ubHkgImZvbyIgc2hvdWxkIGhhdmUgYmVlbiByZWFkLgorICBFWFBFQ1RfRVEoc3RybGVuKCJmb28iKSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzdjNzY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmNjCkBAIC0wLDAgKzEsNTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKK1plcm9Db3B5SW5wdXRTdHJlYW06On5aZXJvQ29weUlucHV0U3RyZWFtKCkge30KK1plcm9Db3B5T3V0cHV0U3RyZWFtOjp+WmVyb0NvcHlPdXRwdXRTdHJlYW0oKSB7fQorCisKK2Jvb2wgWmVyb0NvcHlPdXRwdXRTdHJlYW06OldyaXRlQWxpYXNlZFJhdyhjb25zdCB2b2lkKiAvKiBkYXRhICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAvKiBzaXplICovKSB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJUaGlzIFplcm9Db3B5T3V0cHV0U3RyZWFtIGRvZXNuJ3Qgc3VwcG9ydCBhbGlhc2luZy4gIgorICAgICAgICAgICAgICAgICJSZWFjaGluZyBoZXJlIHVzdWFsbHkgbWVhbnMgYSBaZXJvQ29weU91dHB1dFN0cmVhbSAiCisgICAgICAgICAgICAgICAgImltcGxlbWVudGF0aW9uIGJ1Zy4iOworICByZXR1cm4gZmFsc2U7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyNjUwZmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaApAQCAtMCwwICsxLDI0OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyB0aGUgWmVyb0NvcHlJbnB1dFN0cmVhbSBhbmQgWmVyb0NvcHlPdXRwdXRTdHJlYW0KKy8vIGludGVyZmFjZXMsIHdoaWNoIHJlcHJlc2VudCBhYnN0cmFjdCBJL08gc3RyZWFtcyB0byBhbmQgZnJvbSB3aGljaAorLy8gcHJvdG9jb2wgYnVmZmVycyBjYW4gYmUgcmVhZCBhbmQgd3JpdHRlbi4gIEZvciBhIGZldyBzaW1wbGUKKy8vIGltcGxlbWVudGF0aW9ucyBvZiB0aGVzZSBpbnRlcmZhY2VzLCBzZWUgemVyb19jb3B5X3N0cmVhbV9pbXBsLmguCisvLworLy8gVGhlc2UgaW50ZXJmYWNlcyBhcmUgZGlmZmVyZW50IGZyb20gY2xhc3NpYyBJL08gc3RyZWFtcyBpbiB0aGF0IHRoZXkKKy8vIHRyeSB0byBtaW5pbWl6ZSB0aGUgYW1vdW50IG9mIGRhdGEgY29weWluZyB0aGF0IG5lZWRzIHRvIGJlIGRvbmUuCisvLyBUbyBhY2NvbXBsaXNoIHRoaXMsIHJlc3BvbnNpYmlsaXR5IGZvciBhbGxvY2F0aW5nIGJ1ZmZlcnMgaXMgbW92ZWQgdG8KKy8vIHRoZSBzdHJlYW0gb2JqZWN0LCByYXRoZXIgdGhhbiBiZWluZyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIGNhbGxlci4KKy8vIFNvLCB0aGUgc3RyZWFtIGNhbiByZXR1cm4gYSBidWZmZXIgd2hpY2ggYWN0dWFsbHkgcG9pbnRzIGRpcmVjdGx5IGludG8KKy8vIHRoZSBmaW5hbCBkYXRhIHN0cnVjdHVyZSB3aGVyZSB0aGUgYnl0ZXMgYXJlIHRvIGJlIHN0b3JlZCwgYW5kIHRoZSBjYWxsZXIKKy8vIGNhbiBpbnRlcmFjdCBkaXJlY3RseSB3aXRoIHRoYXQgYnVmZmVyLCBlbGltaW5hdGluZyBhbiBpbnRlcm1lZGlhdGUgY29weQorLy8gb3BlcmF0aW9uLgorLy8KKy8vIEFzIGFuIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBjb21tb24gY2FzZSBpbiB3aGljaCB5b3UgYXJlIHJlYWRpbmcgYnl0ZXMKKy8vIGZyb20gYW4gYXJyYXkgdGhhdCBpcyBhbHJlYWR5IGluIG1lbW9yeSAob3IgcGVyaGFwcyBhbiBtbWFwKCllZCBmaWxlKS4KKy8vIFdpdGggY2xhc3NpYyBJL08gc3RyZWFtcywgeW91IHdvdWxkIGRvIHNvbWV0aGluZyBsaWtlOgorLy8gICBjaGFyIGJ1ZmZlcltCVUZGRVJfU0laRV07CisvLyAgIGlucHV0LT5SZWFkKGJ1ZmZlciwgQlVGRkVSX1NJWkUpOworLy8gICBEb1NvbWV0aGluZyhidWZmZXIsIEJVRkZFUl9TSVpFKTsKKy8vIFRoZW4sIHRoZSBzdHJlYW0gYmFzaWNhbGx5IGp1c3QgY2FsbHMgbWVtY3B5KCkgdG8gY29weSB0aGUgZGF0YSBmcm9tCisvLyB0aGUgYXJyYXkgaW50byB5b3VyIGJ1ZmZlci4gIFdpdGggYSBaZXJvQ29weUlucHV0U3RyZWFtLCB5b3Ugd291bGQgZG8KKy8vIHRoaXMgaW5zdGVhZDoKKy8vICAgY29uc3Qgdm9pZCogYnVmZmVyOworLy8gICBpbnQgc2l6ZTsKKy8vICAgaW5wdXQtPk5leHQoJmJ1ZmZlciwgJnNpemUpOworLy8gICBEb1NvbWV0aGluZyhidWZmZXIsIHNpemUpOworLy8gSGVyZSwgbm8gY29weSBpcyBwZXJmb3JtZWQuICBUaGUgaW5wdXQgc3RyZWFtIHJldHVybnMgYSBwb2ludGVyIGRpcmVjdGx5CisvLyBpbnRvIHRoZSBiYWNraW5nIGFycmF5LCBhbmQgdGhlIGNhbGxlciBlbmRzIHVwIHJlYWRpbmcgZGlyZWN0bHkgZnJvbSBpdC4KKy8vCisvLyBJZiB5b3Ugd2FudCB0byBiZSBhYmxlIHRvIHJlYWQgdGhlIG9sZC1mYXNoaW9uIHdheSwgeW91IGNhbiBjcmVhdGUKKy8vIGEgQ29kZWRJbnB1dFN0cmVhbSBvciBDb2RlZE91dHB1dFN0cmVhbSB3cmFwcGluZyB0aGVzZSBvYmplY3RzIGFuZCB1c2UKKy8vIHRoZWlyIFJlYWRSYXcoKS9Xcml0ZVJhdygpIG1ldGhvZHMuICBUaGVzZSB3aWxsLCBvZiBjb3Vyc2UsIGFkZCBhIGNvcHkKKy8vIHN0ZXAsIGJ1dCBDb2RlZCpTdHJlYW0gd2lsbCBoYW5kbGUgYnVmZmVyaW5nIHNvIGF0IGxlYXN0IGl0IHdpbGwgYmUKKy8vIHJlYXNvbmFibHkgZWZmaWNpZW50LgorLy8KKy8vIFplcm9Db3B5SW5wdXRTdHJlYW0gZXhhbXBsZToKKy8vICAgLy8gUmVhZCBpbiBhIGZpbGUgYW5kIHByaW50IGl0cyBjb250ZW50cyB0byBzdGRvdXQuCisvLyAgIGludCBmZCA9IG9wZW4oIm15ZmlsZSIsIE9fUkRPTkxZKTsKKy8vICAgWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZkKTsKKy8vCisvLyAgIGNvbnN0IHZvaWQqIGJ1ZmZlcjsKKy8vICAgaW50IHNpemU7CisvLyAgIHdoaWxlIChpbnB1dC0+TmV4dCgmYnVmZmVyLCAmc2l6ZSkpIHsKKy8vICAgICBjb3V0LndyaXRlKGJ1ZmZlciwgc2l6ZSk7CisvLyAgIH0KKy8vCisvLyAgIGRlbGV0ZSBpbnB1dDsKKy8vICAgY2xvc2UoZmQpOworLy8KKy8vIFplcm9Db3B5T3V0cHV0U3RyZWFtIGV4YW1wbGU6CisvLyAgIC8vIENvcHkgdGhlIGNvbnRlbnRzIG9mICJpbmZpbGUiIHRvICJvdXRmaWxlIiwgdXNpbmcgcGxhaW4gcmVhZCgpIGZvcgorLy8gICAvLyAiaW5maWxlIiBidXQgYSBaZXJvQ29weU91dHB1dFN0cmVhbSBmb3IgIm91dGZpbGUiLgorLy8gICBpbnQgaW5mZCA9IG9wZW4oImluZmlsZSIsIE9fUkRPTkxZKTsKKy8vICAgaW50IG91dGZkID0gb3Blbigib3V0ZmlsZSIsIE9fV1JPTkxZKTsKKy8vICAgWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dGZkKTsKKy8vCisvLyAgIHZvaWQqIGJ1ZmZlcjsKKy8vICAgaW50IHNpemU7CisvLyAgIHdoaWxlIChvdXRwdXQtPk5leHQoJmJ1ZmZlciwgJnNpemUpKSB7CisvLyAgICAgaW50IGJ5dGVzID0gcmVhZChpbmZkLCBidWZmZXIsIHNpemUpOworLy8gICAgIGlmIChieXRlcyA8IHNpemUpIHsKKy8vICAgICAgIC8vIFJlYWNoZWQgRU9GLgorLy8gICAgICAgb3V0cHV0LT5CYWNrVXAoc2l6ZSAtIGJ5dGVzKTsKKy8vICAgICAgIGJyZWFrOworLy8gICAgIH0KKy8vICAgfQorLy8KKy8vICAgZGVsZXRlIG91dHB1dDsKKy8vICAgY2xvc2UoaW5mZCk7CisvLyAgIGNsb3NlKG91dGZkKTsKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgWmVyb0NvcHlJbnB1dFN0cmVhbTsKK2NsYXNzIFplcm9Db3B5T3V0cHV0U3RyZWFtOworCisvLyBBYnN0cmFjdCBpbnRlcmZhY2Ugc2ltaWxhciB0byBhbiBpbnB1dCBzdHJlYW0gYnV0IGRlc2lnbmVkIHRvIG1pbmltaXplCisvLyBjb3B5aW5nLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFplcm9Db3B5SW5wdXRTdHJlYW0geworIHB1YmxpYzoKKyAgaW5saW5lIFplcm9Db3B5SW5wdXRTdHJlYW0oKSB7fQorICB2aXJ0dWFsIH5aZXJvQ29weUlucHV0U3RyZWFtKCk7CisKKyAgLy8gT2J0YWlucyBhIGNodW5rIG9mIGRhdGEgZnJvbSB0aGUgc3RyZWFtLgorICAvLworICAvLyBQcmVjb25kaXRpb25zOgorICAvLyAqICJzaXplIiBhbmQgImRhdGEiIGFyZSBub3QgTlVMTC4KKyAgLy8KKyAgLy8gUG9zdGNvbmRpdGlvbnM6CisgIC8vICogSWYgdGhlIHJldHVybmVkIHZhbHVlIGlzIGZhbHNlLCB0aGVyZSBpcyBubyBtb3JlIGRhdGEgdG8gcmV0dXJuIG9yCisgIC8vICAgYW4gZXJyb3Igb2NjdXJyZWQuICBBbGwgZXJyb3JzIGFyZSBwZXJtYW5lbnQuCisgIC8vICogT3RoZXJ3aXNlLCAic2l6ZSIgcG9pbnRzIHRvIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgYW5kICJkYXRhIgorICAvLyAgIHBvaW50cyB0byBhIHBvaW50ZXIgdG8gYSBidWZmZXIgY29udGFpbmluZyB0aGVzZSBieXRlcy4KKyAgLy8gKiBPd25lcnNoaXAgb2YgdGhpcyBidWZmZXIgcmVtYWlucyB3aXRoIHRoZSBzdHJlYW0sIGFuZCB0aGUgYnVmZmVyCisgIC8vICAgcmVtYWlucyB2YWxpZCBvbmx5IHVudGlsIHNvbWUgb3RoZXIgbWV0aG9kIG9mIHRoZSBzdHJlYW0gaXMgY2FsbGVkCisgIC8vICAgb3IgdGhlIHN0cmVhbSBpcyBkZXN0cm95ZWQuCisgIC8vICogSXQgaXMgbGVnYWwgZm9yIHRoZSByZXR1cm5lZCBidWZmZXIgdG8gaGF2ZSB6ZXJvIHNpemUsIGFzIGxvbmcKKyAgLy8gICBhcyByZXBlYXRlZGx5IGNhbGxpbmcgTmV4dCgpIGV2ZW50dWFsbHkgeWllbGRzIGEgYnVmZmVyIHdpdGggbm9uLXplcm8KKyAgLy8gICBzaXplLgorICB2aXJ0dWFsIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSA9IDA7CisKKyAgLy8gQmFja3MgdXAgYSBudW1iZXIgb2YgYnl0ZXMsIHNvIHRoYXQgdGhlIG5leHQgY2FsbCB0byBOZXh0KCkgcmV0dXJucworICAvLyBkYXRhIGFnYWluIHRoYXQgd2FzIGFscmVhZHkgcmV0dXJuZWQgYnkgdGhlIGxhc3QgY2FsbCB0byBOZXh0KCkuICBUaGlzCisgIC8vIGlzIHVzZWZ1bCB3aGVuIHdyaXRpbmcgcHJvY2VkdXJlcyB0aGF0IGFyZSBvbmx5IHN1cHBvc2VkIHRvIHJlYWQgdXAKKyAgLy8gdG8gYSBjZXJ0YWluIHBvaW50IGluIHRoZSBpbnB1dCwgdGhlbiByZXR1cm4uICBJZiBOZXh0KCkgcmV0dXJucyBhCisgIC8vIGJ1ZmZlciB0aGF0IGdvZXMgYmV5b25kIHdoYXQgeW91IHdhbnRlZCB0byByZWFkLCB5b3UgY2FuIHVzZSBCYWNrVXAoKQorICAvLyB0byByZXR1cm4gdG8gdGhlIHBvaW50IHdoZXJlIHlvdSBpbnRlbmRlZCB0byBmaW5pc2guCisgIC8vCisgIC8vIFByZWNvbmRpdGlvbnM6CisgIC8vICogVGhlIGxhc3QgbWV0aG9kIGNhbGxlZCBtdXN0IGhhdmUgYmVlbiBOZXh0KCkuCisgIC8vICogY291bnQgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHNpemUgb2YgdGhlIGxhc3QgYnVmZmVyCisgIC8vICAgcmV0dXJuZWQgYnkgTmV4dCgpLgorICAvLworICAvLyBQb3N0Y29uZGl0aW9uczoKKyAgLy8gKiBUaGUgbGFzdCAiY291bnQiIGJ5dGVzIG9mIHRoZSBsYXN0IGJ1ZmZlciByZXR1cm5lZCBieSBOZXh0KCkgd2lsbCBiZQorICAvLyAgIHB1c2hlZCBiYWNrIGludG8gdGhlIHN0cmVhbS4gIFN1YnNlcXVlbnQgY2FsbHMgdG8gTmV4dCgpIHdpbGwgcmV0dXJuCisgIC8vICAgdGhlIHNhbWUgZGF0YSBhZ2FpbiBiZWZvcmUgcHJvZHVjaW5nIG5ldyBkYXRhLgorICB2aXJ0dWFsIHZvaWQgQmFja1VwKGludCBjb3VudCkgPSAwOworCisgIC8vIFNraXBzIGEgbnVtYmVyIG9mIGJ5dGVzLiAgUmV0dXJucyBmYWxzZSBpZiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMKKyAgLy8gcmVhY2hlZCBvciBzb21lIGlucHV0IGVycm9yIG9jY3VycmVkLiAgSW4gdGhlIGVuZC1vZi1zdHJlYW0gY2FzZSwgdGhlCisgIC8vIHN0cmVhbSBpcyBhZHZhbmNlZCB0byB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gKHNvIEJ5dGVDb3VudCgpIHdpbGwgcmV0dXJuCisgIC8vIHRoZSB0b3RhbCBzaXplIG9mIHRoZSBzdHJlYW0pLgorICB2aXJ0dWFsIGJvb2wgU2tpcChpbnQgY291bnQpID0gMDsKKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBzaW5jZSB0aGlzIG9iamVjdCB3YXMgY3JlYXRlZC4KKyAgdmlydHVhbCBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCA9IDA7CisKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhaZXJvQ29weUlucHV0U3RyZWFtKTsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBzaW1pbGFyIHRvIGFuIG91dHB1dCBzdHJlYW0gYnV0IGRlc2lnbmVkIHRvIG1pbmltaXplCisvLyBjb3B5aW5nLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFplcm9Db3B5T3V0cHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIGlubGluZSBaZXJvQ29weU91dHB1dFN0cmVhbSgpIHt9CisgIHZpcnR1YWwgflplcm9Db3B5T3V0cHV0U3RyZWFtKCk7CisKKyAgLy8gT2J0YWlucyBhIGJ1ZmZlciBpbnRvIHdoaWNoIGRhdGEgY2FuIGJlIHdyaXR0ZW4uICBBbnkgZGF0YSB3cml0dGVuCisgIC8vIGludG8gdGhpcyBidWZmZXIgd2lsbCBldmVudHVhbGx5IChtYXliZSBpbnN0YW50bHksIG1heWJlIGxhdGVyIG9uKQorICAvLyBiZSB3cml0dGVuIHRvIHRoZSBvdXRwdXQuCisgIC8vCisgIC8vIFByZWNvbmRpdGlvbnM6CisgIC8vICogInNpemUiIGFuZCAiZGF0YSIgYXJlIG5vdCBOVUxMLgorICAvLworICAvLyBQb3N0Y29uZGl0aW9uczoKKyAgLy8gKiBJZiB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgZmFsc2UsIGFuIGVycm9yIG9jY3VycmVkLiAgQWxsIGVycm9ycyBhcmUKKyAgLy8gICBwZXJtYW5lbnQuCisgIC8vICogT3RoZXJ3aXNlLCAic2l6ZSIgcG9pbnRzIHRvIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBidWZmZXIKKyAgLy8gICBhbmQgImRhdGEiIHBvaW50cyB0byB0aGUgYnVmZmVyLgorICAvLyAqIE93bmVyc2hpcCBvZiB0aGlzIGJ1ZmZlciByZW1haW5zIHdpdGggdGhlIHN0cmVhbSwgYW5kIHRoZSBidWZmZXIKKyAgLy8gICByZW1haW5zIHZhbGlkIG9ubHkgdW50aWwgc29tZSBvdGhlciBtZXRob2Qgb2YgdGhlIHN0cmVhbSBpcyBjYWxsZWQKKyAgLy8gICBvciB0aGUgc3RyZWFtIGlzIGRlc3Ryb3llZC4KKyAgLy8gKiBBbnkgZGF0YSB3aGljaCB0aGUgY2FsbGVyIHN0b3JlcyBpbiB0aGlzIGJ1ZmZlciB3aWxsIGV2ZW50dWFsbHkgYmUKKyAgLy8gICB3cml0dGVuIHRvIHRoZSBvdXRwdXQgKHVubGVzcyBCYWNrVXAoKSBpcyBjYWxsZWQpLgorICAvLyAqIEl0IGlzIGxlZ2FsIGZvciB0aGUgcmV0dXJuZWQgYnVmZmVyIHRvIGhhdmUgemVybyBzaXplLCBhcyBsb25nCisgIC8vICAgYXMgcmVwZWF0ZWRseSBjYWxsaW5nIE5leHQoKSBldmVudHVhbGx5IHlpZWxkcyBhIGJ1ZmZlciB3aXRoIG5vbi16ZXJvCisgIC8vICAgc2l6ZS4KKyAgdmlydHVhbCBib29sIE5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgPSAwOworCisgIC8vIEJhY2tzIHVwIGEgbnVtYmVyIG9mIGJ5dGVzLCBzbyB0aGF0IHRoZSBlbmQgb2YgdGhlIGxhc3QgYnVmZmVyIHJldHVybmVkCisgIC8vIGJ5IE5leHQoKSBpcyBub3QgYWN0dWFsbHkgd3JpdHRlbi4gIFRoaXMgaXMgbmVlZGVkIHdoZW4geW91IGZpbmlzaAorICAvLyB3cml0aW5nIGFsbCB0aGUgZGF0YSB5b3Ugd2FudCB0byB3cml0ZSwgYnV0IHRoZSBsYXN0IGJ1ZmZlciB3YXMgYmlnZ2VyCisgIC8vIHRoYW4geW91IG5lZWRlZC4gIFlvdSBkb24ndCB3YW50IHRvIHdyaXRlIGEgYnVuY2ggb2YgZ2FyYmFnZSBhZnRlciB0aGUKKyAgLy8gZW5kIG9mIHlvdXIgZGF0YSwgc28geW91IHVzZSBCYWNrVXAoKSB0byBiYWNrIHVwLgorICAvLworICAvLyBQcmVjb25kaXRpb25zOgorICAvLyAqIFRoZSBsYXN0IG1ldGhvZCBjYWxsZWQgbXVzdCBoYXZlIGJlZW4gTmV4dCgpLgorICAvLyAqIGNvdW50IG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzaXplIG9mIHRoZSBsYXN0IGJ1ZmZlcgorICAvLyAgIHJldHVybmVkIGJ5IE5leHQoKS4KKyAgLy8gKiBUaGUgY2FsbGVyIG11c3Qgbm90IGhhdmUgd3JpdHRlbiBhbnl0aGluZyB0byB0aGUgbGFzdCAiY291bnQiIGJ5dGVzCisgIC8vICAgb2YgdGhhdCBidWZmZXIuCisgIC8vCisgIC8vIFBvc3Rjb25kaXRpb25zOgorICAvLyAqIFRoZSBsYXN0ICJjb3VudCIgYnl0ZXMgb2YgdGhlIGxhc3QgYnVmZmVyIHJldHVybmVkIGJ5IE5leHQoKSB3aWxsIGJlCisgIC8vICAgaWdub3JlZC4KKyAgdmlydHVhbCB2b2lkIEJhY2tVcChpbnQgY291bnQpID0gMDsKKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBzaW5jZSB0aGlzIG9iamVjdCB3YXMgY3JlYXRlZC4KKyAgdmlydHVhbCBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCA9IDA7CisKKyAgLy8gV3JpdGUgYSBnaXZlbiBjaHVuayBvZiBkYXRhIHRvIHRoZSBvdXRwdXQuICBTb21lIG91dHB1dCBzdHJlYW1zIG1heQorICAvLyBpbXBsZW1lbnQgdGhpcyBpbiBhIHdheSB0aGF0IGF2b2lkcyBjb3B5aW5nLiBDaGVjayBBbGxvd3NBbGlhc2luZygpIGJlZm9yZQorICAvLyBjYWxsaW5nIFdyaXRlQWxpYXNlZFJhdygpLiBJdCB3aWxsIEdPT0dMRV9DSEVDSyBmYWlsIGlmIFdyaXRlQWxpYXNlZFJhdygpIGlzCisgIC8vIGNhbGxlZCBvbiBhIHN0cmVhbSB0aGF0IGRvZXMgbm90IGFsbG93IGFsaWFzaW5nLgorICAvLworICAvLyBOT1RFOiBJdCBpcyBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUgdGhhdCB0aGUgY2h1bmsgb2YgbWVtb3J5CisgIC8vIHJlbWFpbnMgbGl2ZSB1bnRpbCBhbGwgb2YgdGhlIGRhdGEgaGFzIGJlZW4gY29uc3VtZWQgZnJvbSB0aGUgc3RyZWFtLgorICB2aXJ0dWFsIGJvb2wgV3JpdGVBbGlhc2VkUmF3KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKTsKKyAgdmlydHVhbCBib29sIEFsbG93c0FsaWFzaW5nKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFplcm9Db3B5T3V0cHV0U3RyZWFtKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3OTAxYjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5jYwpAQCAtMCwwICsxLDQ3MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZkZWYgX01TQ19WRVIKKyNpbmNsdWRlIDxpby5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworI2lmZGVmIF9XSU4zMgorLy8gV2luMzIgbHNlZWsgaXMgYnJva2VuOiAgSWYgaW52b2tlZCBvbiBhIG5vbi1zZWVrYWJsZSBmaWxlIGRlc2NyaXB0b3IsIGl0cworLy8gcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gIFdlIHJlLWRlZmluZSBpdCB0byBhbHdheXMgcHJvZHVjZSBhbiBlcnJvci4KKyNkZWZpbmUgbHNlZWsoZmQsIG9mZnNldCwgb3JpZ2luKSAoKG9mZl90KS0xKQorI2VuZGlmCisKK25hbWVzcGFjZSB7CisKKy8vIEVJTlRSIHN1Y2tzLgoraW50IGNsb3NlX25vX2VpbnRyKGludCBmZCkgeworICBpbnQgcmVzdWx0OworICBkbyB7CisgICAgcmVzdWx0ID0gY2xvc2UoZmQpOworICB9IHdoaWxlIChyZXN1bHQgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitGaWxlSW5wdXRTdHJlYW06OkZpbGVJbnB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX2lucHV0XyhmaWxlX2Rlc2NyaXB0b3IpLAorICAgIGltcGxfKCZjb3B5aW5nX2lucHV0XywgYmxvY2tfc2l6ZSkgeworfQorCitGaWxlSW5wdXRTdHJlYW06On5GaWxlSW5wdXRTdHJlYW0oKSB7fQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIHJldHVybiBjb3B5aW5nX2lucHV0Xy5DbG9zZSgpOworfQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIHJldHVybiBpbXBsXy5OZXh0KGRhdGEsIHNpemUpOworfQorCit2b2lkIEZpbGVJbnB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBpbXBsXy5CYWNrVXAoY291bnQpOworfQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgcmV0dXJuIGltcGxfLlNraXAoY291bnQpOworfQorCitpbnQ2NCBGaWxlSW5wdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIGltcGxfLkJ5dGVDb3VudCgpOworfQorCitGaWxlSW5wdXRTdHJlYW06OkNvcHlpbmdGaWxlSW5wdXRTdHJlYW06OkNvcHlpbmdGaWxlSW5wdXRTdHJlYW0oCisgICAgaW50IGZpbGVfZGVzY3JpcHRvcikKKyAgOiBmaWxlXyhmaWxlX2Rlc2NyaXB0b3IpLAorICAgIGNsb3NlX29uX2RlbGV0ZV8oZmFsc2UpLAorICAgIGlzX2Nsb3NlZF8oZmFsc2UpLAorICAgIGVycm5vXygwKSwKKyAgICBwcmV2aW91c19zZWVrX2ZhaWxlZF8oZmFsc2UpIHsKK30KKworRmlsZUlucHV0U3RyZWFtOjpDb3B5aW5nRmlsZUlucHV0U3RyZWFtOjp+Q29weWluZ0ZpbGVJbnB1dFN0cmVhbSgpIHsKKyAgaWYgKGNsb3NlX29uX2RlbGV0ZV8pIHsKKyAgICBpZiAoIUNsb3NlKCkpIHsKKyAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJjbG9zZSgpIGZhaWxlZDogIiA8PCBzdHJlcnJvcihlcnJub18pOworICAgIH0KKyAgfQorfQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6Q29weWluZ0ZpbGVJbnB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisKKyAgaXNfY2xvc2VkXyA9IHRydWU7CisgIGlmIChjbG9zZV9ub19laW50cihmaWxlXykgIT0gMCkgeworICAgIC8vIFRoZSBkb2NzIG9uIGNsb3NlKCkgZG8gbm90IHNwZWNpZnkgd2hldGhlciBhIGZpbGUgZGVzY3JpcHRvciBpcyBzdGlsbAorICAgIC8vIG9wZW4gYWZ0ZXIgY2xvc2UoKSBmYWlscyB3aXRoIEVJTy4gIEhvd2V2ZXIsIHRoZSBnbGliYyBzb3VyY2UgY29kZQorICAgIC8vIHNlZW1zIHRvIGluZGljYXRlIHRoYXQgaXQgaXMgbm90LgorICAgIGVycm5vXyA9IGVycm5vOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitpbnQgRmlsZUlucHV0U3RyZWFtOjpDb3B5aW5nRmlsZUlucHV0U3RyZWFtOjpSZWFkKHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgR09PR0xFX0NIRUNLKCFpc19jbG9zZWRfKTsKKworICBpbnQgcmVzdWx0OworICBkbyB7CisgICAgcmVzdWx0ID0gcmVhZChmaWxlXywgYnVmZmVyLCBzaXplKTsKKyAgfSB3aGlsZSAocmVzdWx0IDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisKKyAgaWYgKHJlc3VsdCA8IDApIHsKKyAgICAvLyBSZWFkIGVycm9yIChub3QgRU9GKS4KKyAgICBlcnJub18gPSBlcnJubzsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2ludCBGaWxlSW5wdXRTdHJlYW06OkNvcHlpbmdGaWxlSW5wdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisKKyAgaWYgKCFwcmV2aW91c19zZWVrX2ZhaWxlZF8gJiYKKyAgICAgIGxzZWVrKGZpbGVfLCBjb3VudCwgU0VFS19DVVIpICE9IChvZmZfdCktMSkgeworICAgIC8vIFNlZWsgc3VjY2VlZGVkLgorICAgIHJldHVybiBjb3VudDsKKyAgfSBlbHNlIHsKKyAgICAvLyBGYWlsZWQgdG8gc2Vlay4KKworICAgIC8vIE5vdGUgdG8gc2VsZjogIERvbid0IHNlZWsgYWdhaW4uICBUaGlzIGZpbGUgZGVzY3JpcHRvciBkb2Vzbid0CisgICAgLy8gc3VwcG9ydCBpdC4KKyAgICBwcmV2aW91c19zZWVrX2ZhaWxlZF8gPSB0cnVlOworCisgICAgLy8gVXNlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uLgorICAgIHJldHVybiBDb3B5aW5nSW5wdXRTdHJlYW06OlNraXAoY291bnQpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworRmlsZU91dHB1dFN0cmVhbTo6RmlsZU91dHB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX291dHB1dF8oZmlsZV9kZXNjcmlwdG9yKSwKKyAgICBpbXBsXygmY29weWluZ19vdXRwdXRfLCBibG9ja19zaXplKSB7Cit9CisKK0ZpbGVPdXRwdXRTdHJlYW06On5GaWxlT3V0cHV0U3RyZWFtKCkgeworICBpbXBsXy5GbHVzaCgpOworfQorCitib29sIEZpbGVPdXRwdXRTdHJlYW06OkNsb3NlKCkgeworICBib29sIGZsdXNoX3N1Y2NlZWRlZCA9IGltcGxfLkZsdXNoKCk7CisgIHJldHVybiBjb3B5aW5nX291dHB1dF8uQ2xvc2UoKSAmJiBmbHVzaF9zdWNjZWVkZWQ7Cit9CisKK2Jvb2wgRmlsZU91dHB1dFN0cmVhbTo6Rmx1c2goKSB7CisgIHJldHVybiBpbXBsXy5GbHVzaCgpOworfQorCitib29sIEZpbGVPdXRwdXRTdHJlYW06Ok5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICByZXR1cm4gaW1wbF8uTmV4dChkYXRhLCBzaXplKTsKK30KKwordm9pZCBGaWxlT3V0cHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIGltcGxfLkJhY2tVcChjb3VudCk7Cit9CisKK2ludDY0IEZpbGVPdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIGltcGxfLkJ5dGVDb3VudCgpOworfQorCitGaWxlT3V0cHV0U3RyZWFtOjpDb3B5aW5nRmlsZU91dHB1dFN0cmVhbTo6Q29weWluZ0ZpbGVPdXRwdXRTdHJlYW0oCisgICAgaW50IGZpbGVfZGVzY3JpcHRvcikKKyAgOiBmaWxlXyhmaWxlX2Rlc2NyaXB0b3IpLAorICAgIGNsb3NlX29uX2RlbGV0ZV8oZmFsc2UpLAorICAgIGlzX2Nsb3NlZF8oZmFsc2UpLAorICAgIGVycm5vXygwKSB7Cit9CisKK0ZpbGVPdXRwdXRTdHJlYW06OkNvcHlpbmdGaWxlT3V0cHV0U3RyZWFtOjp+Q29weWluZ0ZpbGVPdXRwdXRTdHJlYW0oKSB7CisgIGlmIChjbG9zZV9vbl9kZWxldGVfKSB7CisgICAgaWYgKCFDbG9zZSgpKSB7CisgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiY2xvc2UoKSBmYWlsZWQ6ICIgPDwgc3RyZXJyb3IoZXJybm9fKTsKKyAgICB9CisgIH0KK30KKworYm9vbCBGaWxlT3V0cHV0U3RyZWFtOjpDb3B5aW5nRmlsZU91dHB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisKKyAgaXNfY2xvc2VkXyA9IHRydWU7CisgIGlmIChjbG9zZV9ub19laW50cihmaWxlXykgIT0gMCkgeworICAgIC8vIFRoZSBkb2NzIG9uIGNsb3NlKCkgZG8gbm90IHNwZWNpZnkgd2hldGhlciBhIGZpbGUgZGVzY3JpcHRvciBpcyBzdGlsbAorICAgIC8vIG9wZW4gYWZ0ZXIgY2xvc2UoKSBmYWlscyB3aXRoIEVJTy4gIEhvd2V2ZXIsIHRoZSBnbGliYyBzb3VyY2UgY29kZQorICAgIC8vIHNlZW1zIHRvIGluZGljYXRlIHRoYXQgaXQgaXMgbm90LgorICAgIGVycm5vXyA9IGVycm5vOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIEZpbGVPdXRwdXRTdHJlYW06OkNvcHlpbmdGaWxlT3V0cHV0U3RyZWFtOjpXcml0ZSgKKyAgICBjb25zdCB2b2lkKiBidWZmZXIsIGludCBzaXplKSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisgIGludCB0b3RhbF93cml0dGVuID0gMDsKKworICBjb25zdCB1aW50OCogYnVmZmVyX2Jhc2UgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oYnVmZmVyKTsKKworICB3aGlsZSAodG90YWxfd3JpdHRlbiA8IHNpemUpIHsKKyAgICBpbnQgYnl0ZXM7CisgICAgZG8geworICAgICAgYnl0ZXMgPSB3cml0ZShmaWxlXywgYnVmZmVyX2Jhc2UgKyB0b3RhbF93cml0dGVuLCBzaXplIC0gdG90YWxfd3JpdHRlbik7CisgICAgfSB3aGlsZSAoYnl0ZXMgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKworICAgIGlmIChieXRlcyA8PSAwKSB7CisgICAgICAvLyBXcml0ZSBlcnJvci4KKworICAgICAgLy8gRklYTUUoa2VudG9uKTogIEFjY29yZGluZyB0byB0aGUgbWFuIHBhZ2UsIGlmIHdyaXRlKCkgcmV0dXJucyB6ZXJvLAorICAgICAgLy8gICB0aGVyZSB3YXMgbm8gZXJyb3I7IHdyaXRlKCkgc2ltcGx5IGRpZCBub3Qgd3JpdGUgYW55dGhpbmcuICBJdCdzCisgICAgICAvLyAgIHVuY2xlYXIgdW5kZXIgd2hhdCBjaXJjdW1zdGFuY2VzIHRoaXMgbWlnaHQgaGFwcGVuLCBidXQgcHJlc3VtYWJseQorICAgICAgLy8gICBlcnJubyB3b24ndCBiZSBzZXQgaW4gdGhpcyBjYXNlLiAgSSBhbSBjb25mdXNlZCBhcyB0byBob3cgc3VjaCBhbgorICAgICAgLy8gICBldmVudCBzaG91bGQgYmUgaGFuZGxlZC4gIEZvciBub3cgSSdtIHRyZWF0aW5nIGl0IGFzIGFuIGVycm9yLCBzaW5jZQorICAgICAgLy8gICByZXRyeWluZyBzZWVtcyBsaWtlIGl0IGNvdWxkIGxlYWQgdG8gYW4gaW5maW5pdGUgbG9vcC4gIEkgc3VzcGVjdAorICAgICAgLy8gICB0aGlzIG5ldmVyIGFjdHVhbGx5IGhhcHBlbnMgYW55d2F5LgorCisgICAgICBpZiAoYnl0ZXMgPCAwKSB7CisgICAgICAgIGVycm5vXyA9IGVycm5vOworICAgICAgfQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB0b3RhbF93cml0dGVuICs9IGJ5dGVzOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSXN0cmVhbUlucHV0U3RyZWFtOjpJc3RyZWFtSW5wdXRTdHJlYW0oaXN0cmVhbSogaW5wdXQsIGludCBibG9ja19zaXplKQorICA6IGNvcHlpbmdfaW5wdXRfKGlucHV0KSwKKyAgICBpbXBsXygmY29weWluZ19pbnB1dF8sIGJsb2NrX3NpemUpIHsKK30KKworSXN0cmVhbUlucHV0U3RyZWFtOjp+SXN0cmVhbUlucHV0U3RyZWFtKCkge30KKworYm9vbCBJc3RyZWFtSW5wdXRTdHJlYW06Ok5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICByZXR1cm4gaW1wbF8uTmV4dChkYXRhLCBzaXplKTsKK30KKwordm9pZCBJc3RyZWFtSW5wdXRTdHJlYW06OkJhY2tVcChpbnQgY291bnQpIHsKKyAgaW1wbF8uQmFja1VwKGNvdW50KTsKK30KKworYm9vbCBJc3RyZWFtSW5wdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIHJldHVybiBpbXBsXy5Ta2lwKGNvdW50KTsKK30KKworaW50NjQgSXN0cmVhbUlucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBpbXBsXy5CeXRlQ291bnQoKTsKK30KKworSXN0cmVhbUlucHV0U3RyZWFtOjpDb3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtOjpDb3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtKAorICAgIGlzdHJlYW0qIGlucHV0KQorICA6IGlucHV0XyhpbnB1dCkgeworfQorCitJc3RyZWFtSW5wdXRTdHJlYW06OkNvcHlpbmdJc3RyZWFtSW5wdXRTdHJlYW06On5Db3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtKCkge30KKworaW50IElzdHJlYW1JbnB1dFN0cmVhbTo6Q29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbTo6UmVhZCgKKyAgICB2b2lkKiBidWZmZXIsIGludCBzaXplKSB7CisgIGlucHV0Xy0+cmVhZChyZWludGVycHJldF9jYXN0PGNoYXIqPihidWZmZXIpLCBzaXplKTsKKyAgaW50IHJlc3VsdCA9IGlucHV0Xy0+Z2NvdW50KCk7CisgIGlmIChyZXN1bHQgPT0gMCAmJiBpbnB1dF8tPmZhaWwoKSAmJiAhaW5wdXRfLT5lb2YoKSkgeworICAgIHJldHVybiAtMTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK09zdHJlYW1PdXRwdXRTdHJlYW06Ok9zdHJlYW1PdXRwdXRTdHJlYW0ob3N0cmVhbSogb3V0cHV0LCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX291dHB1dF8ob3V0cHV0KSwKKyAgICBpbXBsXygmY29weWluZ19vdXRwdXRfLCBibG9ja19zaXplKSB7Cit9CisKK09zdHJlYW1PdXRwdXRTdHJlYW06On5Pc3RyZWFtT3V0cHV0U3RyZWFtKCkgeworICBpbXBsXy5GbHVzaCgpOworfQorCitib29sIE9zdHJlYW1PdXRwdXRTdHJlYW06Ok5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICByZXR1cm4gaW1wbF8uTmV4dChkYXRhLCBzaXplKTsKK30KKwordm9pZCBPc3RyZWFtT3V0cHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIGltcGxfLkJhY2tVcChjb3VudCk7Cit9CisKK2ludDY0IE9zdHJlYW1PdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIGltcGxfLkJ5dGVDb3VudCgpOworfQorCitPc3RyZWFtT3V0cHV0U3RyZWFtOjpDb3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbTo6Q29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW0oCisgICAgb3N0cmVhbSogb3V0cHV0KQorICA6IG91dHB1dF8ob3V0cHV0KSB7Cit9CisKK09zdHJlYW1PdXRwdXRTdHJlYW06OkNvcHlpbmdPc3RyZWFtT3V0cHV0U3RyZWFtOjp+Q29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW0oKSB7Cit9CisKK2Jvb2wgT3N0cmVhbU91dHB1dFN0cmVhbTo6Q29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW06OldyaXRlKAorICAgIGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgb3V0cHV0Xy0+d3JpdGUocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oYnVmZmVyKSwgc2l6ZSk7CisgIHJldHVybiBvdXRwdXRfLT5nb29kKCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQ29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtOjpDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0oCisgICAgWmVyb0NvcHlJbnB1dFN0cmVhbSogY29uc3Qgc3RyZWFtc1tdLCBpbnQgY291bnQpCisgIDogc3RyZWFtc18oc3RyZWFtcyksIHN0cmVhbV9jb3VudF8oY291bnQpLCBieXRlc19yZXRpcmVkXygwKSB7Cit9CisKK0NvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbTo6fkNvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSgpIHsKK30KKworYm9vbCBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW06Ok5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICB3aGlsZSAoc3RyZWFtX2NvdW50XyA+IDApIHsKKyAgICBpZiAoc3RyZWFtc19bMF0tPk5leHQoZGF0YSwgc2l6ZSkpIHJldHVybiB0cnVlOworCisgICAgLy8gVGhhdCBzdHJlYW0gaXMgZG9uZS4gIEFkdmFuY2UgdG8gdGhlIG5leHQgb25lLgorICAgIGJ5dGVzX3JldGlyZWRfICs9IHN0cmVhbXNfWzBdLT5CeXRlQ291bnQoKTsKKyAgICArK3N0cmVhbXNfOworICAgIC0tc3RyZWFtX2NvdW50XzsKKyAgfQorCisgIC8vIE5vIG1vcmUgc3RyZWFtcy4KKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBpZiAoc3RyZWFtX2NvdW50XyA+IDApIHsKKyAgICBzdHJlYW1zX1swXS0+QmFja1VwKGNvdW50KTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkNhbid0IEJhY2tVcCgpIGFmdGVyIGZhaWxlZCBOZXh0KCkuIjsKKyAgfQorfQorCitib29sIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgd2hpbGUgKHN0cmVhbV9jb3VudF8gPiAwKSB7CisgICAgLy8gQXNzdW1lIHRoYXQgQnl0ZUNvdW50KCkgY2FuIGJlIHVzZWQgdG8gZmluZCBvdXQgaG93IG11Y2ggd2UgYWN0dWFsbHkKKyAgICAvLyBza2lwcGVkIHdoZW4gU2tpcCgpIGZhaWxzLgorICAgIGludDY0IHRhcmdldF9ieXRlX2NvdW50ID0gc3RyZWFtc19bMF0tPkJ5dGVDb3VudCgpICsgY291bnQ7CisgICAgaWYgKHN0cmVhbXNfWzBdLT5Ta2lwKGNvdW50KSkgcmV0dXJuIHRydWU7CisKKyAgICAvLyBIaXQgdGhlIGVuZCBvZiB0aGUgc3RyZWFtLiAgRmlndXJlIG91dCBob3cgbWFueSBtb3JlIGJ5dGVzIHdlIHN0aWxsIGhhdmUKKyAgICAvLyB0byBza2lwLgorICAgIGludDY0IGZpbmFsX2J5dGVfY291bnQgPSBzdHJlYW1zX1swXS0+Qnl0ZUNvdW50KCk7CisgICAgR09PR0xFX0RDSEVDS19MVChmaW5hbF9ieXRlX2NvdW50LCB0YXJnZXRfYnl0ZV9jb3VudCk7CisgICAgY291bnQgPSB0YXJnZXRfYnl0ZV9jb3VudCAtIGZpbmFsX2J5dGVfY291bnQ7CisKKyAgICAvLyBUaGF0IHN0cmVhbSBpcyBkb25lLiAgQWR2YW5jZSB0byB0aGUgbmV4dCBvbmUuCisgICAgYnl0ZXNfcmV0aXJlZF8gKz0gZmluYWxfYnl0ZV9jb3VudDsKKyAgICArK3N0cmVhbXNfOworICAgIC0tc3RyZWFtX2NvdW50XzsKKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworaW50NjQgQ29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIGlmIChzdHJlYW1fY291bnRfID09IDApIHsKKyAgICByZXR1cm4gYnl0ZXNfcmV0aXJlZF87CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGJ5dGVzX3JldGlyZWRfICsgc3RyZWFtc19bMF0tPkJ5dGVDb3VudCgpOworICB9Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitMaW1pdGluZ0lucHV0U3RyZWFtOjpMaW1pdGluZ0lucHV0U3RyZWFtKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCBsaW1pdCkKKyAgOiBpbnB1dF8oaW5wdXQpLCBsaW1pdF8obGltaXQpIHsKKyAgcHJpb3JfYnl0ZXNfcmVhZF8gPSBpbnB1dF8tPkJ5dGVDb3VudCgpOworfQorCitMaW1pdGluZ0lucHV0U3RyZWFtOjp+TGltaXRpbmdJbnB1dFN0cmVhbSgpIHsKKyAgLy8gSWYgd2Ugb3ZlcnNob3QgdGhlIGxpbWl0LCBiYWNrIHVwLgorICBpZiAobGltaXRfIDwgMCkgaW5wdXRfLT5CYWNrVXAoLWxpbWl0Xyk7Cit9CisKK2Jvb2wgTGltaXRpbmdJbnB1dFN0cmVhbTo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChsaW1pdF8gPD0gMCkgcmV0dXJuIGZhbHNlOworICBpZiAoIWlucHV0Xy0+TmV4dChkYXRhLCBzaXplKSkgcmV0dXJuIGZhbHNlOworCisgIGxpbWl0XyAtPSAqc2l6ZTsKKyAgaWYgKGxpbWl0XyA8IDApIHsKKyAgICAvLyBXZSBvdmVyc2hvdCB0aGUgbGltaXQuICBSZWR1Y2UgKnNpemUgdG8gaGlkZSB0aGUgcmVzdCBvZiB0aGUgYnVmZmVyLgorICAgICpzaXplICs9IGxpbWl0XzsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBMaW1pdGluZ0lucHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIGlmIChsaW1pdF8gPCAwKSB7CisgICAgaW5wdXRfLT5CYWNrVXAoY291bnQgLSBsaW1pdF8pOworICAgIGxpbWl0XyA9IGNvdW50OworICB9IGVsc2UgeworICAgIGlucHV0Xy0+QmFja1VwKGNvdW50KTsKKyAgICBsaW1pdF8gKz0gY291bnQ7CisgIH0KK30KKworYm9vbCBMaW1pdGluZ0lucHV0U3RyZWFtOjpTa2lwKGludCBjb3VudCkgeworICBpZiAoY291bnQgPiBsaW1pdF8pIHsKKyAgICBpZiAobGltaXRfIDwgMCkgcmV0dXJuIGZhbHNlOworICAgIGlucHV0Xy0+U2tpcChsaW1pdF8pOworICAgIGxpbWl0XyA9IDA7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIGlmICghaW5wdXRfLT5Ta2lwKGNvdW50KSkgcmV0dXJuIGZhbHNlOworICAgIGxpbWl0XyAtPSBjb3VudDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitpbnQ2NCBMaW1pdGluZ0lucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIGlmIChsaW1pdF8gPCAwKSB7CisgICAgcmV0dXJuIGlucHV0Xy0+Qnl0ZUNvdW50KCkgKyBsaW1pdF8gLSBwcmlvcl9ieXRlc19yZWFkXzsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gaW5wdXRfLT5CeXRlQ291bnQoKSAtIHByaW9yX2J5dGVzX3JlYWRfOworICB9Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDc0NmZhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmgKQEAgLTAsMCArMSwzNTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgY29tbW9uIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgaW50ZXJmYWNlcyBkZWZpbmVkIGluCisvLyB6ZXJvX2NvcHlfc3RyZWFtLmggd2hpY2ggYXJlIG9ubHkgaW5jbHVkZWQgaW4gdGhlIGZ1bGwgKG5vbi1saXRlKQorLy8gcHJvdG9idWYgbGlicmFyeS4gIFRoZXNlIGltcGxlbWVudGF0aW9ucyBpbmNsdWRlIFVuaXggZmlsZSBkZXNjcmlwdG9ycworLy8gYW5kIEMrKyBpb3N0cmVhbXMuICBTZWUgYWxzbzogIHplcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmgKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9JTVBMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9JTVBMX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGlvc2Z3ZD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBaZXJvQ29weUlucHV0U3RyZWFtIHdoaWNoIHJlYWRzIGZyb20gYSBmaWxlIGRlc2NyaXB0b3IuCisvLworLy8gRmlsZUlucHV0U3RyZWFtIGlzIHByZWZlcnJlZCBvdmVyIHVzaW5nIGFuIGlmc3RyZWFtIHdpdGggSXN0cmVhbUlucHV0U3RyZWFtLgorLy8gVGhlIGxhdHRlciB3aWxsIGludHJvZHVjZSBhbiBleHRyYSBsYXllciBvZiBidWZmZXJpbmcsIGhhcm1pbmcgcGVyZm9ybWFuY2UuCisvLyBBbHNvLCBpdCdzIGNvbmNlaXZhYmxlIHRoYXQgRmlsZUlucHV0U3RyZWFtIGNvdWxkIHNvbWVkYXkgYmUgZW5oYW5jZWQKKy8vIHRvIHVzZSB6ZXJvLWNvcHkgZmlsZSBkZXNjcmlwdG9ycyBvbiBPU3Mgd2hpY2ggc3VwcG9ydCB0aGVtLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpbGVJbnB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZXMgYSBzdHJlYW0gdGhhdCByZWFkcyBmcm9tIHRoZSBnaXZlbiBVbml4IGZpbGUgZGVzY3JpcHRvci4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0CisgIC8vIHNob3VsZCBiZSByZWFkIGFuZCByZXR1cm5lZCB3aXRoIGVhY2ggY2FsbCB0byBOZXh0KCkuICBPdGhlcndpc2UsCisgIC8vIGEgcmVhc29uYWJsZSBkZWZhdWx0IGlzIHVzZWQuCisgIGV4cGxpY2l0IEZpbGVJbnB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yLCBpbnQgYmxvY2tfc2l6ZSA9IC0xKTsKKyAgfkZpbGVJbnB1dFN0cmVhbSgpOworCisgIC8vIEZsdXNoZXMgYW55IGJ1ZmZlcnMgYW5kIGNsb3NlcyB0aGUgdW5kZXJseWluZyBmaWxlLiAgUmV0dXJucyBmYWxzZSBpZgorICAvLyBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBwcm9jZXNzOyB1c2UgR2V0RXJybm8oKSB0byBleGFtaW5lIHRoZSBlcnJvci4KKyAgLy8gRXZlbiBpZiBhbiBlcnJvciBvY2N1cnMsIHRoZSBmaWxlIGRlc2NyaXB0b3IgaXMgY2xvc2VkIHdoZW4gdGhpcyByZXR1cm5zLgorICBib29sIENsb3NlKCk7CisKKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGUgZGVzY3JpcHRvciBpcyBub3QgY2xvc2VkIHdoZW4gdGhlIHN0cmVhbSBpcworICAvLyBkZXN0cm95ZWQuICBDYWxsIFNldENsb3NlT25EZWxldGUodHJ1ZSkgdG8gY2hhbmdlIHRoYXQuICBXQVJOSU5HOgorICAvLyBUaGlzIGxlYXZlcyBubyB3YXkgZm9yIHRoZSBjYWxsZXIgdG8gZGV0ZWN0IGlmIGNsb3NlKCkgZmFpbHMuICBJZgorICAvLyBkZXRlY3RpbmcgY2xvc2UoKSBlcnJvcnMgaXMgaW1wb3J0YW50IHRvIHlvdSwgeW91IHNob3VsZCBhcnJhbmdlCisgIC8vIHRvIGNsb3NlIHRoZSBkZXNjcmlwdG9yIHlvdXJzZWxmLgorICB2b2lkIFNldENsb3NlT25EZWxldGUoYm9vbCB2YWx1ZSkgeyBjb3B5aW5nX2lucHV0Xy5TZXRDbG9zZU9uRGVsZXRlKHZhbHVlKTsgfQorCisgIC8vIElmIGFuIEkvTyBlcnJvciBoYXMgb2NjdXJyZWQgb24gdGhpcyBmaWxlIGRlc2NyaXB0b3IsIHRoaXMgaXMgdGhlCisgIC8vIGVycm5vIGZyb20gdGhhdCBlcnJvci4gIE90aGVyd2lzZSwgdGhpcyBpcyB6ZXJvLiAgT25jZSBhbiBlcnJvcgorICAvLyBvY2N1cnMsIHRoZSBzdHJlYW0gaXMgYnJva2VuIGFuZCBhbGwgc3Vic2VxdWVudCBvcGVyYXRpb25zIHdpbGwKKyAgLy8gZmFpbC4KKyAgaW50IEdldEVycm5vKCkgeyByZXR1cm4gY29weWluZ19pbnB1dF8uR2V0RXJybm8oKTsgfQorCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIENvcHlpbmdGaWxlSW5wdXRTdHJlYW0gOiBwdWJsaWMgQ29weWluZ0lucHV0U3RyZWFtIHsKKyAgIHB1YmxpYzoKKyAgICBDb3B5aW5nRmlsZUlucHV0U3RyZWFtKGludCBmaWxlX2Rlc2NyaXB0b3IpOworICAgIH5Db3B5aW5nRmlsZUlucHV0U3RyZWFtKCk7CisKKyAgICBib29sIENsb3NlKCk7CisgICAgdm9pZCBTZXRDbG9zZU9uRGVsZXRlKGJvb2wgdmFsdWUpIHsgY2xvc2Vfb25fZGVsZXRlXyA9IHZhbHVlOyB9CisgICAgaW50IEdldEVycm5vKCkgeyByZXR1cm4gZXJybm9fOyB9CisKKyAgICAvLyBpbXBsZW1lbnRzIENvcHlpbmdJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBpbnQgUmVhZCh2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKyAgICBpbnQgU2tpcChpbnQgY291bnQpOworCisgICBwcml2YXRlOgorICAgIC8vIFRoZSBmaWxlIGRlc2NyaXB0b3IuCisgICAgY29uc3QgaW50IGZpbGVfOworICAgIGJvb2wgY2xvc2Vfb25fZGVsZXRlXzsKKyAgICBib29sIGlzX2Nsb3NlZF87CisKKyAgICAvLyBUaGUgZXJybm8gb2YgdGhlIEkvTyBlcnJvciwgaWYgb25lIGhhcyBvY2N1cnJlZC4gIE90aGVyd2lzZSwgemVyby4KKyAgICBpbnQgZXJybm9fOworCisgICAgLy8gRGlkIHdlIHRyeSB0byBzZWVrIG9uY2UgYW5kIGZhaWw/ICBJZiBzbywgd2UgYXNzdW1lIHRoaXMgZmlsZSBkZXNjcmlwdG9yCisgICAgLy8gZG9lc24ndCBzdXBwb3J0IHNlZWtpbmcgYW5kIHdvbid0IHRyeSBhZ2Fpbi4KKyAgICBib29sIHByZXZpb3VzX3NlZWtfZmFpbGVkXzsKKworICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhDb3B5aW5nRmlsZUlucHV0U3RyZWFtKTsKKyAgfTsKKworICBDb3B5aW5nRmlsZUlucHV0U3RyZWFtIGNvcHlpbmdfaW5wdXRfOworICBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yIGltcGxfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWxlSW5wdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5T3V0cHV0U3RyZWFtIHdoaWNoIHdyaXRlcyB0byBhIGZpbGUgZGVzY3JpcHRvci4KKy8vCisvLyBGaWxlT3V0cHV0U3RyZWFtIGlzIHByZWZlcnJlZCBvdmVyIHVzaW5nIGFuIG9mc3RyZWFtIHdpdGgKKy8vIE9zdHJlYW1PdXRwdXRTdHJlYW0uICBUaGUgbGF0dGVyIHdpbGwgaW50cm9kdWNlIGFuIGV4dHJhIGxheWVyIG9mIGJ1ZmZlcmluZywKKy8vIGhhcm1pbmcgcGVyZm9ybWFuY2UuICBBbHNvLCBpdCdzIGNvbmNlaXZhYmxlIHRoYXQgRmlsZU91dHB1dFN0cmVhbSBjb3VsZAorLy8gc29tZWRheSBiZSBlbmhhbmNlZCB0byB1c2UgemVyby1jb3B5IGZpbGUgZGVzY3JpcHRvcnMgb24gT1NzIHdoaWNoCisvLyBzdXBwb3J0IHRoZW0uCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmlsZU91dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGEgc3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBVbml4IGZpbGUgZGVzY3JpcHRvci4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlcnMKKyAgLy8gdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQgYnkgTmV4dCgpLiAgT3RoZXJ3aXNlLCBhIHJlYXNvbmFibGUgZGVmYXVsdAorICAvLyBpcyB1c2VkLgorICBleHBsaWNpdCBGaWxlT3V0cHV0U3RyZWFtKGludCBmaWxlX2Rlc2NyaXB0b3IsIGludCBibG9ja19zaXplID0gLTEpOworICB+RmlsZU91dHB1dFN0cmVhbSgpOworCisgIC8vIEZsdXNoZXMgYW55IGJ1ZmZlcnMgYW5kIGNsb3NlcyB0aGUgdW5kZXJseWluZyBmaWxlLiAgUmV0dXJucyBmYWxzZSBpZgorICAvLyBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBwcm9jZXNzOyB1c2UgR2V0RXJybm8oKSB0byBleGFtaW5lIHRoZSBlcnJvci4KKyAgLy8gRXZlbiBpZiBhbiBlcnJvciBvY2N1cnMsIHRoZSBmaWxlIGRlc2NyaXB0b3IgaXMgY2xvc2VkIHdoZW4gdGhpcyByZXR1cm5zLgorICBib29sIENsb3NlKCk7CisKKyAgLy8gRmx1c2hlcyBGaWxlT3V0cHV0U3RyZWFtJ3MgYnVmZmVycyBidXQgZG9lcyBub3QgY2xvc2UgdGhlCisgIC8vIHVuZGVybHlpbmcgZmlsZS4gTm8gc3BlY2lhbCBtZWFzdXJlcyBhcmUgdGFrZW4gdG8gZW5zdXJlIHRoYXQKKyAgLy8gdW5kZXJseWluZyBvcGVyYXRpbmcgc3lzdGVtIGZpbGUgb2JqZWN0IGlzIHN5bmNocm9uaXplZCB0byBkaXNrLgorICBib29sIEZsdXNoKCk7CisKKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGUgZGVzY3JpcHRvciBpcyBub3QgY2xvc2VkIHdoZW4gdGhlIHN0cmVhbSBpcworICAvLyBkZXN0cm95ZWQuICBDYWxsIFNldENsb3NlT25EZWxldGUodHJ1ZSkgdG8gY2hhbmdlIHRoYXQuICBXQVJOSU5HOgorICAvLyBUaGlzIGxlYXZlcyBubyB3YXkgZm9yIHRoZSBjYWxsZXIgdG8gZGV0ZWN0IGlmIGNsb3NlKCkgZmFpbHMuICBJZgorICAvLyBkZXRlY3RpbmcgY2xvc2UoKSBlcnJvcnMgaXMgaW1wb3J0YW50IHRvIHlvdSwgeW91IHNob3VsZCBhcnJhbmdlCisgIC8vIHRvIGNsb3NlIHRoZSBkZXNjcmlwdG9yIHlvdXJzZWxmLgorICB2b2lkIFNldENsb3NlT25EZWxldGUoYm9vbCB2YWx1ZSkgeyBjb3B5aW5nX291dHB1dF8uU2V0Q2xvc2VPbkRlbGV0ZSh2YWx1ZSk7IH0KKworICAvLyBJZiBhbiBJL08gZXJyb3IgaGFzIG9jY3VycmVkIG9uIHRoaXMgZmlsZSBkZXNjcmlwdG9yLCB0aGlzIGlzIHRoZQorICAvLyBlcnJubyBmcm9tIHRoYXQgZXJyb3IuICBPdGhlcndpc2UsIHRoaXMgaXMgemVyby4gIE9uY2UgYW4gZXJyb3IKKyAgLy8gb2NjdXJzLCB0aGUgc3RyZWFtIGlzIGJyb2tlbiBhbmQgYWxsIHN1YnNlcXVlbnQgb3BlcmF0aW9ucyB3aWxsCisgIC8vIGZhaWwuCisgIGludCBHZXRFcnJubygpIHsgcmV0dXJuIGNvcHlpbmdfb3V0cHV0Xy5HZXRFcnJubygpOyB9CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weU91dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nRmlsZU91dHB1dFN0cmVhbSA6IHB1YmxpYyBDb3B5aW5nT3V0cHV0U3RyZWFtIHsKKyAgIHB1YmxpYzoKKyAgICBDb3B5aW5nRmlsZU91dHB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yKTsKKyAgICB+Q29weWluZ0ZpbGVPdXRwdXRTdHJlYW0oKTsKKworICAgIGJvb2wgQ2xvc2UoKTsKKyAgICB2b2lkIFNldENsb3NlT25EZWxldGUoYm9vbCB2YWx1ZSkgeyBjbG9zZV9vbl9kZWxldGVfID0gdmFsdWU7IH0KKyAgICBpbnQgR2V0RXJybm8oKSB7IHJldHVybiBlcnJub187IH0KKworICAgIC8vIGltcGxlbWVudHMgQ29weWluZ091dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIGJvb2wgV3JpdGUoY29uc3Qgdm9pZCogYnVmZmVyLCBpbnQgc2l6ZSk7CisKKyAgIHByaXZhdGU6CisgICAgLy8gVGhlIGZpbGUgZGVzY3JpcHRvci4KKyAgICBjb25zdCBpbnQgZmlsZV87CisgICAgYm9vbCBjbG9zZV9vbl9kZWxldGVfOworICAgIGJvb2wgaXNfY2xvc2VkXzsKKworICAgIC8vIFRoZSBlcnJubyBvZiB0aGUgSS9PIGVycm9yLCBpZiBvbmUgaGFzIG9jY3VycmVkLiAgT3RoZXJ3aXNlLCB6ZXJvLgorICAgIGludCBlcnJub187CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29weWluZ0ZpbGVPdXRwdXRTdHJlYW0pOworICB9OworCisgIENvcHlpbmdGaWxlT3V0cHV0U3RyZWFtIGNvcHlpbmdfb3V0cHV0XzsKKyAgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IgaW1wbF87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpbGVPdXRwdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5SW5wdXRTdHJlYW0gd2hpY2ggcmVhZHMgZnJvbSBhIEMrKyBpc3RyZWFtLgorLy8KKy8vIE5vdGUgdGhhdCBmb3IgcmVhZGluZyBmaWxlcyAob3IgYW55dGhpbmcgcmVwcmVzZW50ZWQgYnkgYSBmaWxlIGRlc2NyaXB0b3IpLAorLy8gRmlsZUlucHV0U3RyZWFtIGlzIG1vcmUgZWZmaWNpZW50LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIElzdHJlYW1JbnB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZXMgYSBzdHJlYW0gdGhhdCByZWFkcyBmcm9tIHRoZSBnaXZlbiBDKysgaXN0cmVhbS4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0CisgIC8vIHNob3VsZCBiZSByZWFkIGFuZCByZXR1cm5lZCB3aXRoIGVhY2ggY2FsbCB0byBOZXh0KCkuICBPdGhlcndpc2UsCisgIC8vIGEgcmVhc29uYWJsZSBkZWZhdWx0IGlzIHVzZWQuCisgIGV4cGxpY2l0IElzdHJlYW1JbnB1dFN0cmVhbShpc3RyZWFtKiBzdHJlYW0sIGludCBibG9ja19zaXplID0gLTEpOworICB+SXN0cmVhbUlucHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weUlucHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBib29sIFNraXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbSA6IHB1YmxpYyBDb3B5aW5nSW5wdXRTdHJlYW0geworICAgcHVibGljOgorICAgIENvcHlpbmdJc3RyZWFtSW5wdXRTdHJlYW0oaXN0cmVhbSogaW5wdXQpOworICAgIH5Db3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtKCk7CisKKyAgICAvLyBpbXBsZW1lbnRzIENvcHlpbmdJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBpbnQgUmVhZCh2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKyAgICAvLyAoV2UgdXNlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIFNraXAoKS4pCisKKyAgIHByaXZhdGU6CisgICAgLy8gVGhlIHN0cmVhbS4KKyAgICBpc3RyZWFtKiBpbnB1dF87CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbSk7CisgIH07CisKKyAgQ29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbSBjb3B5aW5nX2lucHV0XzsKKyAgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvciBpbXBsXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSXN0cmVhbUlucHV0U3RyZWFtKTsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBaZXJvQ29weU91dHB1dFN0cmVhbSB3aGljaCB3cml0ZXMgdG8gYSBDKysgb3N0cmVhbS4KKy8vCisvLyBOb3RlIHRoYXQgZm9yIHdyaXRpbmcgZmlsZXMgKG9yIGFueXRoaW5nIHJlcHJlc2VudGVkIGJ5IGEgZmlsZSBkZXNjcmlwdG9yKSwKKy8vIEZpbGVPdXRwdXRTdHJlYW0gaXMgbW9yZSBlZmZpY2llbnQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgT3N0cmVhbU91dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGEgc3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBDKysgb3N0cmVhbS4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlcnMKKyAgLy8gdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQgYnkgTmV4dCgpLiAgT3RoZXJ3aXNlLCBhIHJlYXNvbmFibGUgZGVmYXVsdAorICAvLyBpcyB1c2VkLgorICBleHBsaWNpdCBPc3RyZWFtT3V0cHV0U3RyZWFtKG9zdHJlYW0qIHN0cmVhbSwgaW50IGJsb2NrX3NpemUgPSAtMSk7CisgIH5Pc3RyZWFtT3V0cHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weU91dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbSA6IHB1YmxpYyBDb3B5aW5nT3V0cHV0U3RyZWFtIHsKKyAgIHB1YmxpYzoKKyAgICBDb3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbShvc3RyZWFtKiBvdXRwdXQpOworICAgIH5Db3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbSgpOworCisgICAgLy8gaW1wbGVtZW50cyBDb3B5aW5nT3V0cHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgYm9vbCBXcml0ZShjb25zdCB2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKworICAgcHJpdmF0ZToKKyAgICAvLyBUaGUgc3RyZWFtLgorICAgIG9zdHJlYW0qIG91dHB1dF87CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW0pOworICB9OworCisgIENvcHlpbmdPc3RyZWFtT3V0cHV0U3RyZWFtIGNvcHlpbmdfb3V0cHV0XzsKKyAgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IgaW1wbF87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE9zdHJlYW1PdXRwdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5SW5wdXRTdHJlYW0gd2hpY2ggcmVhZHMgZnJvbSBzZXZlcmFsIG90aGVyIHN0cmVhbXMgaW4gc2VxdWVuY2UuCisvLyBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gaXMgdW5hYmxlIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gZW5kLW9mLXN0cmVhbQorLy8gYW5kIHJlYWQgZXJyb3JzIGluIHRoZSB1bmRlcmx5aW5nIHN0cmVhbXMsIHNvIGl0IGFzc3VtZXMgYW55IGVycm9ycyBtZWFuCisvLyBlbmQtb2Ytc3RyZWFtLiAgU28sIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbXMgZmFpbCBmb3IgYW55IG90aGVyIHJlYXNvbiwKKy8vIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSBtYXkgZG8gb2RkIHRoaW5ncy4gIEl0IGlzIHN1Z2dlc3RlZCB0aGF0IHlvdSBkbworLy8gbm90IHVzZSBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gb24gc3RyZWFtcyB0aGF0IG1pZ2h0IHByb2R1Y2UgcmVhZCBlcnJvcnMKKy8vIG90aGVyIHRoYW4gZW5kLW9mLXN0cmVhbS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBBbGwgc3RyZWFtcyBwYXNzZWQgaW4gYXMgd2VsbCBhcyB0aGUgYXJyYXkgaXRzZWxmIG11c3QgcmVtYWluIHZhbGlkCisgIC8vIHVudGlsIHRoZSBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gaXMgZGVzdHJveWVkLgorICBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0oWmVyb0NvcHlJbnB1dFN0cmVhbSogY29uc3Qgc3RyZWFtc1tdLCBpbnQgY291bnQpOworICB+Q29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weUlucHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBib29sIFNraXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKworIHByaXZhdGU6CisgIC8vIEFzIHN0cmVhbXMgYXJlIHJldGlyZWQsIHN0cmVhbXNfIGlzIGluY3JlbWVudGVkIGFuZCBjb3VudF8gaXMKKyAgLy8gZGVjcmVtZW50ZWQuCisgIFplcm9Db3B5SW5wdXRTdHJlYW0qIGNvbnN0KiBzdHJlYW1zXzsKKyAgaW50IHN0cmVhbV9jb3VudF87CisgIGludDY0IGJ5dGVzX3JldGlyZWRfOyAgLy8gQnl0ZXMgcmVhZCBmcm9tIHByZXZpb3VzIHN0cmVhbXMuCisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIEEgWmVyb0NvcHlJbnB1dFN0cmVhbSB3aGljaCB3cmFwcyBzb21lIG90aGVyIHN0cmVhbSBhbmQgbGltaXRzIGl0IHRvCisvLyBhIHBhcnRpY3VsYXIgYnl0ZSBjb3VudC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMaW1pdGluZ0lucHV0U3RyZWFtIDogcHVibGljIFplcm9Db3B5SW5wdXRTdHJlYW0geworIHB1YmxpYzoKKyAgTGltaXRpbmdJbnB1dFN0cmVhbShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgaW50NjQgbGltaXQpOworICB+TGltaXRpbmdJbnB1dFN0cmVhbSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisKKyBwcml2YXRlOgorICBaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dF87CisgIGludDY0IGxpbWl0XzsgIC8vIERlY3JlYXNlcyBhcyB3ZSBnbywgYmVjb21lcyBuZWdhdGl2ZSBpZiB3ZSBvdmVyc2hvb3QuCisgIGludDY0IHByaW9yX2J5dGVzX3JlYWRfOyAgLy8gQnl0ZXMgcmVhZCBvbiB1bmRlcmx5aW5nIHN0cmVhbSBhdCBjb25zdHJ1Y3Rpb24KKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTGltaXRpbmdJbnB1dFN0cmVhbSk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSU1QTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3YjczYjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjCkBAIC0wLDAgKzEsNDA2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxsaW1pdHM+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKK25hbWVzcGFjZSB7CisKKy8vIERlZmF1bHQgYmxvY2sgc2l6ZSBmb3IgQ29weWluZ3tJbixPdXR9cHV0U3RyZWFtQWRhcHRvci4KK3N0YXRpYyBjb25zdCBpbnQga0RlZmF1bHRCbG9ja1NpemUgPSA4MTkyOworCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitBcnJheUlucHV0U3RyZWFtOjpBcnJheUlucHV0U3RyZWFtKGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBkYXRhXyhyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGF0YSkpLAorICAgIHNpemVfKHNpemUpLAorICAgIGJsb2NrX3NpemVfKGJsb2NrX3NpemUgPiAwID8gYmxvY2tfc2l6ZSA6IHNpemUpLAorICAgIHBvc2l0aW9uXygwKSwKKyAgICBsYXN0X3JldHVybmVkX3NpemVfKDApIHsKK30KKworQXJyYXlJbnB1dFN0cmVhbTo6fkFycmF5SW5wdXRTdHJlYW0oKSB7Cit9CisKK2Jvb2wgQXJyYXlJbnB1dFN0cmVhbTo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChwb3NpdGlvbl8gPCBzaXplXykgeworICAgIGxhc3RfcmV0dXJuZWRfc2l6ZV8gPSBtaW4oYmxvY2tfc2l6ZV8sIHNpemVfIC0gcG9zaXRpb25fKTsKKyAgICAqZGF0YSA9IGRhdGFfICsgcG9zaXRpb25fOworICAgICpzaXplID0gbGFzdF9yZXR1cm5lZF9zaXplXzsKKyAgICBwb3NpdGlvbl8gKz0gbGFzdF9yZXR1cm5lZF9zaXplXzsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICAvLyBXZSdyZSBhdCB0aGUgZW5kIG9mIHRoZSBhcnJheS4KKyAgICBsYXN0X3JldHVybmVkX3NpemVfID0gMDsgICAvLyBEb24ndCBsZXQgY2FsbGVyIGJhY2sgdXAuCisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK3ZvaWQgQXJyYXlJbnB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR1QobGFzdF9yZXR1cm5lZF9zaXplXywgMCkKKyAgICAgIDw8ICJCYWNrVXAoKSBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIE5leHQoKS4iOworICBHT09HTEVfQ0hFQ0tfTEUoY291bnQsIGxhc3RfcmV0dXJuZWRfc2l6ZV8pOworICBHT09HTEVfQ0hFQ0tfR0UoY291bnQsIDApOworICBwb3NpdGlvbl8gLT0gY291bnQ7CisgIGxhc3RfcmV0dXJuZWRfc2l6ZV8gPSAwOyAgLy8gRG9uJ3QgbGV0IGNhbGxlciBiYWNrIHVwIGZ1cnRoZXIuCit9CisKK2Jvb2wgQXJyYXlJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgR09PR0xFX0NIRUNLX0dFKGNvdW50LCAwKTsKKyAgbGFzdF9yZXR1cm5lZF9zaXplXyA9IDA7ICAgLy8gRG9uJ3QgbGV0IGNhbGxlciBiYWNrIHVwLgorICBpZiAoY291bnQgPiBzaXplXyAtIHBvc2l0aW9uXykgeworICAgIHBvc2l0aW9uXyA9IHNpemVfOworICAgIHJldHVybiBmYWxzZTsKKyAgfSBlbHNlIHsKKyAgICBwb3NpdGlvbl8gKz0gY291bnQ7CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKworaW50NjQgQXJyYXlJbnB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICByZXR1cm4gcG9zaXRpb25fOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQXJyYXlPdXRwdXRTdHJlYW06OkFycmF5T3V0cHV0U3RyZWFtKHZvaWQqIGRhdGEsIGludCBzaXplLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBkYXRhXyhyZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oZGF0YSkpLAorICAgIHNpemVfKHNpemUpLAorICAgIGJsb2NrX3NpemVfKGJsb2NrX3NpemUgPiAwID8gYmxvY2tfc2l6ZSA6IHNpemUpLAorICAgIHBvc2l0aW9uXygwKSwKKyAgICBsYXN0X3JldHVybmVkX3NpemVfKDApIHsKK30KKworQXJyYXlPdXRwdXRTdHJlYW06On5BcnJheU91dHB1dFN0cmVhbSgpIHsKK30KKworYm9vbCBBcnJheU91dHB1dFN0cmVhbTo6TmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChwb3NpdGlvbl8gPCBzaXplXykgeworICAgIGxhc3RfcmV0dXJuZWRfc2l6ZV8gPSBtaW4oYmxvY2tfc2l6ZV8sIHNpemVfIC0gcG9zaXRpb25fKTsKKyAgICAqZGF0YSA9IGRhdGFfICsgcG9zaXRpb25fOworICAgICpzaXplID0gbGFzdF9yZXR1cm5lZF9zaXplXzsKKyAgICBwb3NpdGlvbl8gKz0gbGFzdF9yZXR1cm5lZF9zaXplXzsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICAvLyBXZSdyZSBhdCB0aGUgZW5kIG9mIHRoZSBhcnJheS4KKyAgICBsYXN0X3JldHVybmVkX3NpemVfID0gMDsgICAvLyBEb24ndCBsZXQgY2FsbGVyIGJhY2sgdXAuCisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK3ZvaWQgQXJyYXlPdXRwdXRTdHJlYW06OkJhY2tVcChpbnQgY291bnQpIHsKKyAgR09PR0xFX0NIRUNLX0dUKGxhc3RfcmV0dXJuZWRfc2l6ZV8sIDApCisgICAgICA8PCAiQmFja1VwKCkgY2FuIG9ubHkgYmUgY2FsbGVkIGFmdGVyIGEgc3VjY2Vzc2Z1bCBOZXh0KCkuIjsKKyAgR09PR0xFX0NIRUNLX0xFKGNvdW50LCBsYXN0X3JldHVybmVkX3NpemVfKTsKKyAgR09PR0xFX0NIRUNLX0dFKGNvdW50LCAwKTsKKyAgcG9zaXRpb25fIC09IGNvdW50OworICBsYXN0X3JldHVybmVkX3NpemVfID0gMDsgIC8vIERvbid0IGxldCBjYWxsZXIgYmFjayB1cCBmdXJ0aGVyLgorfQorCitpbnQ2NCBBcnJheU91dHB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICByZXR1cm4gcG9zaXRpb25fOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1N0cmluZ091dHB1dFN0cmVhbTo6U3RyaW5nT3V0cHV0U3RyZWFtKHN0cmluZyogdGFyZ2V0KQorICA6IHRhcmdldF8odGFyZ2V0KSB7Cit9CisKK1N0cmluZ091dHB1dFN0cmVhbTo6flN0cmluZ091dHB1dFN0cmVhbSgpIHsKK30KKworYm9vbCBTdHJpbmdPdXRwdXRTdHJlYW06Ok5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICBpbnQgb2xkX3NpemUgPSB0YXJnZXRfLT5zaXplKCk7CisKKyAgLy8gR3JvdyB0aGUgc3RyaW5nLgorICBpZiAob2xkX3NpemUgPCB0YXJnZXRfLT5jYXBhY2l0eSgpKSB7CisgICAgLy8gUmVzaXplIHRoZSBzdHJpbmcgdG8gbWF0Y2ggaXRzIGNhcGFjaXR5LCBzaW5jZSB3ZSBjYW4gZ2V0IGF3YXkKKyAgICAvLyB3aXRob3V0IGEgbWVtb3J5IGFsbG9jYXRpb24gdGhpcyB3YXkuCisgICAgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZCh0YXJnZXRfLCB0YXJnZXRfLT5jYXBhY2l0eSgpKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBTaXplIGhhcyByZWFjaGVkIGNhcGFjaXR5LCB0cnkgdG8gZG91YmxlIHRoZSBzaXplLgorICAgIGlmIChvbGRfc2l6ZSA+IHN0ZDo6bnVtZXJpY19saW1pdHM8aW50Pjo6bWF4KCkgLyAyKSB7CisgICAgICAvLyBDYW4gbm90IGRvdWJsZSB0aGUgc2l6ZSBvdGhlcndpc2UgaXQgaXMgZ29pbmcgdG8gY2F1c2UgaW50ZWdlcgorICAgICAgLy8gb3ZlcmZsb3cgaW4gdGhlIGV4cHJlc3Npb24gYmVsb3c6IG9sZF9zaXplICogMiAiOworICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkNhbm5vdCBhbGxvY2F0ZSBidWZmZXIgbGFyZ2VyIHRoYW4ga2ludDMybWF4IGZvciAiCisgICAgICAgICAgICAgICAgIDw8ICJTdHJpbmdPdXRwdXRTdHJlYW0uIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgLy8gRG91YmxlIHRoZSBzaXplLCBhbHNvIG1ha2Ugc3VyZSB0aGF0IHRoZSBuZXcgc2l6ZSBpcyBhdCBsZWFzdAorICAgIC8vIGtNaW5pbXVtU2l6ZS4KKyAgICBTVExTdHJpbmdSZXNpemVVbmluaXRpYWxpemVkKAorICAgICAgdGFyZ2V0XywKKyAgICAgIG1heChvbGRfc2l6ZSAqIDIsCisgICAgICAgICAga01pbmltdW1TaXplICsgMCkpOyAgLy8gIisgMCIgd29ya3MgYXJvdW5kIEdDQzQgd2VpcmRuZXNzLgorICB9CisKKyAgKmRhdGEgPSBtdXRhYmxlX3N0cmluZ19kYXRhKHRhcmdldF8pICsgb2xkX3NpemU7CisgICpzaXplID0gdGFyZ2V0Xy0+c2l6ZSgpIC0gb2xkX3NpemU7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFN0cmluZ091dHB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR0UoY291bnQsIDApOworICBHT09HTEVfQ0hFQ0tfTEUoY291bnQsIHRhcmdldF8tPnNpemUoKSk7CisgIHRhcmdldF8tPnJlc2l6ZSh0YXJnZXRfLT5zaXplKCkgLSBjb3VudCk7Cit9CisKK2ludDY0IFN0cmluZ091dHB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICByZXR1cm4gdGFyZ2V0Xy0+c2l6ZSgpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvcHlpbmdJbnB1dFN0cmVhbTo6fkNvcHlpbmdJbnB1dFN0cmVhbSgpIHt9CisKK2ludCBDb3B5aW5nSW5wdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIGNoYXIganVua1s0MDk2XTsKKyAgaW50IHNraXBwZWQgPSAwOworICB3aGlsZSAoc2tpcHBlZCA8IGNvdW50KSB7CisgICAgaW50IGJ5dGVzID0gUmVhZChqdW5rLCBtaW4oY291bnQgLSBza2lwcGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50PihzaXplb2YoanVuaykpKSk7CisgICAgaWYgKGJ5dGVzIDw9IDApIHsKKyAgICAgIC8vIEVPRiBvciByZWFkIGVycm9yLgorICAgICAgcmV0dXJuIHNraXBwZWQ7CisgICAgfQorICAgIHNraXBwZWQgKz0gYnl0ZXM7CisgIH0KKyAgcmV0dXJuIHNraXBwZWQ7Cit9CisKK0NvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6OkNvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3IoCisgICAgQ29weWluZ0lucHV0U3RyZWFtKiBjb3B5aW5nX3N0cmVhbSwgaW50IGJsb2NrX3NpemUpCisgIDogY29weWluZ19zdHJlYW1fKGNvcHlpbmdfc3RyZWFtKSwKKyAgICBvd25zX2NvcHlpbmdfc3RyZWFtXyhmYWxzZSksCisgICAgZmFpbGVkXyhmYWxzZSksCisgICAgcG9zaXRpb25fKDApLAorICAgIGJ1ZmZlcl9zaXplXyhibG9ja19zaXplID4gMCA/IGJsb2NrX3NpemUgOiBrRGVmYXVsdEJsb2NrU2l6ZSksCisgICAgYnVmZmVyX3VzZWRfKDApLAorICAgIGJhY2t1cF9ieXRlc18oMCkgeworfQorCitDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yOjp+Q29weWluZ0lucHV0U3RyZWFtQWRhcHRvcigpIHsKKyAgaWYgKG93bnNfY29weWluZ19zdHJlYW1fKSB7CisgICAgZGVsZXRlIGNvcHlpbmdfc3RyZWFtXzsKKyAgfQorfQorCitib29sIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6Ok5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICBpZiAoZmFpbGVkXykgeworICAgIC8vIEFscmVhZHkgZmFpbGVkIG9uIGEgcHJldmlvdXMgcmVhZC4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBBbGxvY2F0ZUJ1ZmZlcklmTmVlZGVkKCk7CisKKyAgaWYgKGJhY2t1cF9ieXRlc18gPiAwKSB7CisgICAgLy8gV2UgaGF2ZSBkYXRhIGxlZnQgb3ZlciBmcm9tIGEgcHJldmlvdXMgQmFja1VwKCksIHNvIGp1c3QgcmV0dXJuIHRoYXQuCisgICAgKmRhdGEgPSBidWZmZXJfLmdldCgpICsgYnVmZmVyX3VzZWRfIC0gYmFja3VwX2J5dGVzXzsKKyAgICAqc2l6ZSA9IGJhY2t1cF9ieXRlc187CisgICAgYmFja3VwX2J5dGVzXyA9IDA7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBSZWFkIG5ldyBkYXRhIGludG8gdGhlIGJ1ZmZlci4KKyAgYnVmZmVyX3VzZWRfID0gY29weWluZ19zdHJlYW1fLT5SZWFkKGJ1ZmZlcl8uZ2V0KCksIGJ1ZmZlcl9zaXplXyk7CisgIGlmIChidWZmZXJfdXNlZF8gPD0gMCkgeworICAgIC8vIEVPRiBvciByZWFkIGVycm9yLiAgV2UgZG9uJ3QgbmVlZCB0aGUgYnVmZmVyIGFueW1vcmUuCisgICAgaWYgKGJ1ZmZlcl91c2VkXyA8IDApIHsKKyAgICAgIC8vIFJlYWQgZXJyb3IgKG5vdCBFT0YpLgorICAgICAgZmFpbGVkXyA9IHRydWU7CisgICAgfQorICAgIEZyZWVCdWZmZXIoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcG9zaXRpb25fICs9IGJ1ZmZlcl91c2VkXzsKKworICAqc2l6ZSA9IGJ1ZmZlcl91c2VkXzsKKyAgKmRhdGEgPSBidWZmZXJfLmdldCgpOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDSyhiYWNrdXBfYnl0ZXNfID09IDAgJiYgYnVmZmVyXy5nZXQoKSAhPSBOVUxMKQorICAgIDw8ICIgQmFja1VwKCkgY2FuIG9ubHkgYmUgY2FsbGVkIGFmdGVyIE5leHQoKS4iOworICBHT09HTEVfQ0hFQ0tfTEUoY291bnQsIGJ1ZmZlcl91c2VkXykKKyAgICA8PCAiIENhbid0IGJhY2sgdXAgb3ZlciBtb3JlIGJ5dGVzIHRoYW4gd2VyZSByZXR1cm5lZCBieSB0aGUgbGFzdCBjYWxsIgorICAgICAgICIgdG8gTmV4dCgpLiI7CisgIEdPT0dMRV9DSEVDS19HRShjb3VudCwgMCkKKyAgICA8PCAiIFBhcmFtZXRlciB0byBCYWNrVXAoKSBjYW4ndCBiZSBuZWdhdGl2ZS4iOworCisgIGJhY2t1cF9ieXRlc18gPSBjb3VudDsKK30KKworYm9vbCBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yOjpTa2lwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR0UoY291bnQsIDApOworCisgIGlmIChmYWlsZWRfKSB7CisgICAgLy8gQWxyZWFkeSBmYWlsZWQgb24gYSBwcmV2aW91cyByZWFkLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIEZpcnN0IHNraXAgYW55IGJ5dGVzIGxlZnQgb3ZlciBmcm9tIGEgcHJldmlvdXMgQmFja1VwKCkuCisgIGlmIChiYWNrdXBfYnl0ZXNfID49IGNvdW50KSB7CisgICAgLy8gV2UgaGF2ZSBtb3JlIGRhdGEgbGVmdCBvdmVyIHRoYW4gd2UncmUgdHJ5aW5nIHRvIHNraXAuICBKdXN0IGNob3AgaXQuCisgICAgYmFja3VwX2J5dGVzXyAtPSBjb3VudDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGNvdW50IC09IGJhY2t1cF9ieXRlc187CisgIGJhY2t1cF9ieXRlc18gPSAwOworCisgIGludCBza2lwcGVkID0gY29weWluZ19zdHJlYW1fLT5Ta2lwKGNvdW50KTsKKyAgcG9zaXRpb25fICs9IHNraXBwZWQ7CisgIHJldHVybiBza2lwcGVkID09IGNvdW50OworfQorCitpbnQ2NCBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBwb3NpdGlvbl8gLSBiYWNrdXBfYnl0ZXNfOworfQorCit2b2lkIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6OkFsbG9jYXRlQnVmZmVySWZOZWVkZWQoKSB7CisgIGlmIChidWZmZXJfLmdldCgpID09IE5VTEwpIHsKKyAgICBidWZmZXJfLnJlc2V0KG5ldyB1aW50OFtidWZmZXJfc2l6ZV9dKTsKKyAgfQorfQorCit2b2lkIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6OkZyZWVCdWZmZXIoKSB7CisgIEdPT0dMRV9DSEVDS19FUShiYWNrdXBfYnl0ZXNfLCAwKTsKKyAgYnVmZmVyX3VzZWRfID0gMDsKKyAgYnVmZmVyXy5yZXNldCgpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvcHlpbmdPdXRwdXRTdHJlYW06On5Db3B5aW5nT3V0cHV0U3RyZWFtKCkge30KKworQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3I6OkNvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yKAorICAgIENvcHlpbmdPdXRwdXRTdHJlYW0qIGNvcHlpbmdfc3RyZWFtLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX3N0cmVhbV8oY29weWluZ19zdHJlYW0pLAorICAgIG93bnNfY29weWluZ19zdHJlYW1fKGZhbHNlKSwKKyAgICBmYWlsZWRfKGZhbHNlKSwKKyAgICBwb3NpdGlvbl8oMCksCisgICAgYnVmZmVyX3NpemVfKGJsb2NrX3NpemUgPiAwID8gYmxvY2tfc2l6ZSA6IGtEZWZhdWx0QmxvY2tTaXplKSwKKyAgICBidWZmZXJfdXNlZF8oMCkgeworfQorCitDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6fkNvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yKCkgeworICBXcml0ZUJ1ZmZlcigpOworICBpZiAob3duc19jb3B5aW5nX3N0cmVhbV8pIHsKKyAgICBkZWxldGUgY29weWluZ19zdHJlYW1fOworICB9Cit9CisKK2Jvb2wgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3I6OkZsdXNoKCkgeworICByZXR1cm4gV3JpdGVCdWZmZXIoKTsKK30KKworYm9vbCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6TmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChidWZmZXJfdXNlZF8gPT0gYnVmZmVyX3NpemVfKSB7CisgICAgaWYgKCFXcml0ZUJ1ZmZlcigpKSByZXR1cm4gZmFsc2U7CisgIH0KKworICBBbGxvY2F0ZUJ1ZmZlcklmTmVlZGVkKCk7CisKKyAgKmRhdGEgPSBidWZmZXJfLmdldCgpICsgYnVmZmVyX3VzZWRfOworICAqc2l6ZSA9IGJ1ZmZlcl9zaXplXyAtIGJ1ZmZlcl91c2VkXzsKKyAgYnVmZmVyX3VzZWRfID0gYnVmZmVyX3NpemVfOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6QmFja1VwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR0UoY291bnQsIDApOworICBHT09HTEVfQ0hFQ0tfRVEoYnVmZmVyX3VzZWRfLCBidWZmZXJfc2l6ZV8pCisgICAgPDwgIiBCYWNrVXAoKSBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgTmV4dCgpLiI7CisgIEdPT0dMRV9DSEVDS19MRShjb3VudCwgYnVmZmVyX3VzZWRfKQorICAgIDw8ICIgQ2FuJ3QgYmFjayB1cCBvdmVyIG1vcmUgYnl0ZXMgdGhhbiB3ZXJlIHJldHVybmVkIGJ5IHRoZSBsYXN0IGNhbGwiCisgICAgICAgIiB0byBOZXh0KCkuIjsKKworICBidWZmZXJfdXNlZF8gLT0gY291bnQ7Cit9CisKK2ludDY0IENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBwb3NpdGlvbl8gKyBidWZmZXJfdXNlZF87Cit9CisKK2Jvb2wgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3I6OldyaXRlQnVmZmVyKCkgeworICBpZiAoZmFpbGVkXykgeworICAgIC8vIEFscmVhZHkgZmFpbGVkIG9uIGEgcHJldmlvdXMgd3JpdGUuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaWYgKGJ1ZmZlcl91c2VkXyA9PSAwKSByZXR1cm4gdHJ1ZTsKKworICBpZiAoY29weWluZ19zdHJlYW1fLT5Xcml0ZShidWZmZXJfLmdldCgpLCBidWZmZXJfdXNlZF8pKSB7CisgICAgcG9zaXRpb25fICs9IGJ1ZmZlcl91c2VkXzsKKyAgICBidWZmZXJfdXNlZF8gPSAwOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIGZhaWxlZF8gPSB0cnVlOworICAgIEZyZWVCdWZmZXIoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKwordm9pZCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6QWxsb2NhdGVCdWZmZXJJZk5lZWRlZCgpIHsKKyAgaWYgKGJ1ZmZlcl8gPT0gTlVMTCkgeworICAgIGJ1ZmZlcl8ucmVzZXQobmV3IHVpbnQ4W2J1ZmZlcl9zaXplX10pOworICB9Cit9CisKK3ZvaWQgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3I6OkZyZWVCdWZmZXIoKSB7CisgIGJ1ZmZlcl91c2VkXyA9IDA7CisgIGJ1ZmZlcl8ucmVzZXQoKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzNjBiMTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmgKQEAgLTAsMCArMSwzODEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgY29tbW9uIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgaW50ZXJmYWNlcyBkZWZpbmVkIGluCisvLyB6ZXJvX2NvcHlfc3RyZWFtLmggd2hpY2ggYXJlIGluY2x1ZGVkIGluIHRoZSAibGl0ZSIgcHJvdG9idWYgbGlicmFyeS4KKy8vIFRoZXNlIGltcGxlbWVudGF0aW9ucyBjb3ZlciBJL08gb24gcmF3IGFycmF5cyBhbmQgc3RyaW5ncywgYXMgd2VsbCBhcworLy8gYWRhcHRvcnMgd2hpY2ggbWFrZSBpdCBlYXN5IHRvIGltcGxlbWVudCBzdHJlYW1zIGJhc2VkIG9uIHRyYWRpdGlvbmFsCisvLyBzdHJlYW1zLiAgT2YgY291cnNlLCBtYW55IHVzZXJzIHdpbGwgcHJvYmFibHkgd2FudCB0byB3cml0ZSB0aGVpciBvd24KKy8vIGltcGxlbWVudGF0aW9ucyBvZiB0aGVzZSBpbnRlcmZhY2VzIHNwZWNpZmljIHRvIHRoZSBwYXJ0aWN1bGFyIEkvTworLy8gYWJzdHJhY3Rpb25zIHRoZXkgcHJlZmVyIHRvIHVzZSwgYnV0IHRoZXNlIHNob3VsZCBjb3ZlciB0aGUgbW9zdCBjb21tb24KKy8vIGNhc2VzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19aRVJPX0NPUFlfU1RSRUFNX0lNUExfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSU1QTF9MSVRFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGlvc2Z3ZD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIEEgWmVyb0NvcHlJbnB1dFN0cmVhbSBiYWNrZWQgYnkgYW4gaW4tbWVtb3J5IGFycmF5IG9mIGJ5dGVzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEFycmF5SW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYW4gSW5wdXRTdHJlYW0gdGhhdCByZXR1cm5zIHRoZSBieXRlcyBwb2ludGVkIHRvIGJ5ICJkYXRhIi4KKyAgLy8gImRhdGEiIHJlbWFpbnMgdGhlIHByb3BlcnR5IG9mIHRoZSBjYWxsZXIgYnV0IG11c3QgcmVtYWluIHZhbGlkIHVudGlsCisgIC8vIHRoZSBzdHJlYW0gaXMgZGVzdHJveWVkLiAgSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBjYWxscyB0byBOZXh0KCkKKyAgLy8gd2lsbCByZXR1cm4gZGF0YSBibG9ja3Mgbm8gbGFyZ2VyIHRoYW4gdGhlIGdpdmVuIHNpemUuICBPdGhlcndpc2UsIHRoZQorICAvLyBmaXJzdCBjYWxsIHRvIE5leHQoKSByZXR1cm5zIHRoZSBlbnRpcmUgYXJyYXkuICBibG9ja19zaXplIGlzIG1haW5seQorICAvLyB1c2VmdWwgZm9yIHRlc3Rpbmc7IGluIHByb2R1Y3Rpb24geW91IHdvdWxkIHByb2JhYmx5IG5ldmVyIHdhbnQgdG8gc2V0CisgIC8vIGl0LgorICBBcnJheUlucHV0U3RyZWFtKGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplLCBpbnQgYmxvY2tfc2l6ZSA9IC0xKTsKKyAgfkFycmF5SW5wdXRTdHJlYW0oKTsKKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5SW5wdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGJvb2wgU2tpcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworCisgcHJpdmF0ZToKKyAgY29uc3QgdWludDgqIGNvbnN0IGRhdGFfOyAgLy8gVGhlIGJ5dGUgYXJyYXkuCisgIGNvbnN0IGludCBzaXplXzsgICAgICAgICAgIC8vIFRvdGFsIHNpemUgb2YgdGhlIGFycmF5LgorICBjb25zdCBpbnQgYmxvY2tfc2l6ZV87ICAgICAvLyBIb3cgbWFueSBieXRlcyB0byByZXR1cm4gYXQgYSB0aW1lLgorCisgIGludCBwb3NpdGlvbl87CisgIGludCBsYXN0X3JldHVybmVkX3NpemVfOyAgIC8vIEhvdyBtYW55IGJ5dGVzIHdlIHJldHVybmVkIGxhc3QgdGltZSBOZXh0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2FzIGNhbGxlZCAodXNlZCBmb3IgZXJyb3IgY2hlY2tpbmcgb25seSkuCisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEFycmF5SW5wdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5T3V0cHV0U3RyZWFtIGJhY2tlZCBieSBhbiBpbi1tZW1vcnkgYXJyYXkgb2YgYnl0ZXMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQXJyYXlPdXRwdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgLy8gQ3JlYXRlIGFuIE91dHB1dFN0cmVhbSB0aGF0IHdyaXRlcyB0byB0aGUgYnl0ZXMgcG9pbnRlZCB0byBieSAiZGF0YSIuCisgIC8vICJkYXRhIiByZW1haW5zIHRoZSBwcm9wZXJ0eSBvZiB0aGUgY2FsbGVyIGJ1dCBtdXN0IHJlbWFpbiB2YWxpZCB1bnRpbAorICAvLyB0aGUgc3RyZWFtIGlzIGRlc3Ryb3llZC4gIElmIGEgYmxvY2tfc2l6ZSBpcyBnaXZlbiwgY2FsbHMgdG8gTmV4dCgpCisgIC8vIHdpbGwgcmV0dXJuIGRhdGEgYmxvY2tzIG5vIGxhcmdlciB0aGFuIHRoZSBnaXZlbiBzaXplLiAgT3RoZXJ3aXNlLCB0aGUKKyAgLy8gZmlyc3QgY2FsbCB0byBOZXh0KCkgcmV0dXJucyB0aGUgZW50aXJlIGFycmF5LiAgYmxvY2tfc2l6ZSBpcyBtYWlubHkKKyAgLy8gdXNlZnVsIGZvciB0ZXN0aW5nOyBpbiBwcm9kdWN0aW9uIHlvdSB3b3VsZCBwcm9iYWJseSBuZXZlciB3YW50IHRvIHNldAorICAvLyBpdC4KKyAgQXJyYXlPdXRwdXRTdHJlYW0odm9pZCogZGF0YSwgaW50IHNpemUsIGludCBibG9ja19zaXplID0gLTEpOworICB+QXJyYXlPdXRwdXRTdHJlYW0oKTsKKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5T3V0cHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdWludDgqIGNvbnN0IGRhdGFfOyAgICAgICAgLy8gVGhlIGJ5dGUgYXJyYXkuCisgIGNvbnN0IGludCBzaXplXzsgICAgICAgICAgIC8vIFRvdGFsIHNpemUgb2YgdGhlIGFycmF5LgorICBjb25zdCBpbnQgYmxvY2tfc2l6ZV87ICAgICAvLyBIb3cgbWFueSBieXRlcyB0byByZXR1cm4gYXQgYSB0aW1lLgorCisgIGludCBwb3NpdGlvbl87CisgIGludCBsYXN0X3JldHVybmVkX3NpemVfOyAgIC8vIEhvdyBtYW55IGJ5dGVzIHdlIHJldHVybmVkIGxhc3QgdGltZSBOZXh0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2FzIGNhbGxlZCAodXNlZCBmb3IgZXJyb3IgY2hlY2tpbmcgb25seSkuCisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEFycmF5T3V0cHV0U3RyZWFtKTsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBaZXJvQ29weU91dHB1dFN0cmVhbSB3aGljaCBhcHBlbmRzIGJ5dGVzIHRvIGEgc3RyaW5nLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmluZ091dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBTdHJpbmdPdXRwdXRTdHJlYW0gd2hpY2ggYXBwZW5kcyBieXRlcyB0byB0aGUgZ2l2ZW4gc3RyaW5nLgorICAvLyBUaGUgc3RyaW5nIHJlbWFpbnMgcHJvcGVydHkgb2YgdGhlIGNhbGxlciwgYnV0IGl0IGlzIG11dGF0ZWQgaW4gYXJiaXRyYXJ5CisgIC8vIHdheXMgYW5kIE1VU1QgTk9UIGJlIGFjY2Vzc2VkIGluIGFueSB3YXkgdW50aWwgeW91J3JlIGRvbmUgd2l0aCB0aGUKKyAgLy8gc3RyZWFtLiBFaXRoZXIgYmUgc3VyZSB0aGVyZSdzIG5vIGZ1cnRoZXIgdXNhZ2UsIG9yIChzYWZlc3QpIGRlc3Ryb3kgdGhlCisgIC8vIHN0cmVhbSBiZWZvcmUgdXNpbmcgdGhlIGNvbnRlbnRzLgorICAvLworICAvLyBIaW50OiAgSWYgeW91IGNhbGwgdGFyZ2V0LT5yZXNlcnZlKG4pIGJlZm9yZSBjcmVhdGluZyB0aGUgc3RyZWFtLAorICAvLyAgIHRoZSBmaXJzdCBjYWxsIHRvIE5leHQoKSB3aWxsIHJldHVybiBhdCBsZWFzdCBuIGJ5dGVzIG9mIGJ1ZmZlcgorICAvLyAgIHNwYWNlLgorICBleHBsaWNpdCBTdHJpbmdPdXRwdXRTdHJlYW0oc3RyaW5nKiB0YXJnZXQpOworICB+U3RyaW5nT3V0cHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weU91dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIHN0YXRpYyBjb25zdCBpbnQga01pbmltdW1TaXplID0gMTY7CisKKyAgc3RyaW5nKiB0YXJnZXRfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTdHJpbmdPdXRwdXRTdHJlYW0pOworfTsKKworLy8gTm90ZTogIFRoZXJlIGlzIG5vIFN0cmluZ0lucHV0U3RyZWFtLiAgSW5zdGVhZCwganVzdCBjcmVhdGUgYW4KKy8vIEFycmF5SW5wdXRTdHJlYW0gYXMgZm9sbG93czoKKy8vICAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChzdHIuZGF0YSgpLCBzdHIuc2l6ZSgpKTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIGdlbmVyaWMgdHJhZGl0aW9uYWwgaW5wdXQgc3RyZWFtIGludGVyZmFjZS4KKy8vCisvLyBMb3RzIG9mIHRyYWRpdGlvbmFsIGlucHV0IHN0cmVhbXMgKGUuZy4gZmlsZSBkZXNjcmlwdG9ycywgQyBzdGRpbworLy8gc3RyZWFtcywgYW5kIEMrKyBpb3N0cmVhbXMpIGV4cG9zZSBhbiBpbnRlcmZhY2Ugd2hlcmUgZXZlcnkgcmVhZAorLy8gaW52b2x2ZXMgY29weWluZyBieXRlcyBpbnRvIGEgYnVmZmVyLiAgSWYgeW91IHdhbnQgdG8gdGFrZSBzdWNoIGFuCisvLyBpbnRlcmZhY2UgYW5kIG1ha2UgYSBaZXJvQ29weUlucHV0U3RyZWFtIGJhc2VkIG9uIGl0LCBzaW1wbHkgaW1wbGVtZW50CisvLyBDb3B5aW5nSW5wdXRTdHJlYW0gYW5kIHRoZW4gdXNlIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3IuCisvLworLy8gQ29weWluZ0lucHV0U3RyZWFtIGltcGxlbWVudGF0aW9ucyBzaG91bGQgYXZvaWQgYnVmZmVyaW5nIGlmIHBvc3NpYmxlLgorLy8gQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvciBkb2VzIGl0cyBvd24gYnVmZmVyaW5nIGFuZCB3aWxsIHJlYWQgZGF0YQorLy8gaW4gbGFyZ2UgYmxvY2tzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIENvcHlpbmdJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICB2aXJ0dWFsIH5Db3B5aW5nSW5wdXRTdHJlYW0oKTsKKworICAvLyBSZWFkcyB1cCB0byAic2l6ZSIgYnl0ZXMgaW50byB0aGUgZ2l2ZW4gYnVmZmVyLiAgUmV0dXJucyB0aGUgbnVtYmVyIG9mCisgIC8vIGJ5dGVzIHJlYWQuICBSZWFkKCkgd2FpdHMgdW50aWwgYXQgbGVhc3Qgb25lIGJ5dGUgaXMgYXZhaWxhYmxlLCBvcgorICAvLyByZXR1cm5zIHplcm8gaWYgbm8gYnl0ZXMgd2lsbCBldmVyIGJlY29tZSBhdmFpbGFibGUgKEVPRiksIG9yIC0xIGlmIGEKKyAgLy8gcGVybWFuZW50IHJlYWQgZXJyb3Igb2NjdXJyZWQuCisgIHZpcnR1YWwgaW50IFJlYWQodm9pZCogYnVmZmVyLCBpbnQgc2l6ZSkgPSAwOworCisgIC8vIFNraXBzIHRoZSBuZXh0ICJjb3VudCIgYnl0ZXMgb2YgaW5wdXQuICBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMKKyAgLy8gYWN0dWFsbHkgc2tpcHBlZC4gIFRoaXMgd2lsbCBhbHdheXMgYmUgZXhhY3RseSBlcXVhbCB0byAiY291bnQiIHVubGVzcworICAvLyBFT0Ygd2FzIHJlYWNoZWQgb3IgYSBwZXJtYW5lbnQgcmVhZCBlcnJvciBvY2N1cnJlZC4KKyAgLy8KKyAgLy8gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24ganVzdCByZXBlYXRlZGx5IGNhbGxzIFJlYWQoKSBpbnRvIGEgc2NyYXRjaAorICAvLyBidWZmZXIuCisgIHZpcnR1YWwgaW50IFNraXAoaW50IGNvdW50KTsKK307CisKKy8vIEEgWmVyb0NvcHlJbnB1dFN0cmVhbSB3aGljaCByZWFkcyBmcm9tIGEgQ29weWluZ0lucHV0U3RyZWFtLiAgVGhpcyBpcworLy8gdXNlZnVsIGZvciBpbXBsZW1lbnRpbmcgWmVyb0NvcHlJbnB1dFN0cmVhbXMgdGhhdCByZWFkIGZyb20gdHJhZGl0aW9uYWwKKy8vIHN0cmVhbXMuICBOb3RlIHRoYXQgdGhpcyBjbGFzcyBpcyBub3QgcmVhbGx5IHplcm8tY29weS4KKy8vCisvLyBJZiB5b3Ugd2FudCB0byByZWFkIGZyb20gZmlsZSBkZXNjcmlwdG9ycyBvciBDKysgaXN0cmVhbXMsIHRoaXMgaXMKKy8vIGFscmVhZHkgaW1wbGVtZW50ZWQgZm9yIHlvdTogIHVzZSBGaWxlSW5wdXRTdHJlYW0gb3IgSXN0cmVhbUlucHV0U3RyZWFtCisvLyByZXNwZWN0aXZlbHkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvciA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZXMgYSBzdHJlYW0gdGhhdCByZWFkcyBmcm9tIHRoZSBnaXZlbiBDb3B5aW5nSW5wdXRTdHJlYW0uCisgIC8vIElmIGEgYmxvY2tfc2l6ZSBpcyBnaXZlbiwgaXQgc3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdAorICAvLyBzaG91bGQgYmUgcmVhZCBhbmQgcmV0dXJuZWQgd2l0aCBlYWNoIGNhbGwgdG8gTmV4dCgpLiAgT3RoZXJ3aXNlLAorICAvLyBhIHJlYXNvbmFibGUgZGVmYXVsdCBpcyB1c2VkLiAgVGhlIGNhbGxlciByZXRhaW5zIG93bmVyc2hpcCBvZgorICAvLyBjb3B5aW5nX3N0cmVhbSB1bmxlc3MgU2V0T3duc0NvcHlpbmdTdHJlYW0odHJ1ZSkgaXMgY2FsbGVkLgorICBleHBsaWNpdCBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yKENvcHlpbmdJbnB1dFN0cmVhbSogY29weWluZ19zdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJsb2NrX3NpemUgPSAtMSk7CisgIH5Db3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yKCk7CisKKyAgLy8gQ2FsbCBTZXRPd25zQ29weWluZ1N0cmVhbSh0cnVlKSB0byB0ZWxsIHRoZSBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yIHRvCisgIC8vIGRlbGV0ZSB0aGUgdW5kZXJseWluZyBDb3B5aW5nSW5wdXRTdHJlYW0gd2hlbiBpdCBpcyBkZXN0cm95ZWQuCisgIHZvaWQgU2V0T3duc0NvcHlpbmdTdHJlYW0oYm9vbCB2YWx1ZSkgeyBvd25zX2NvcHlpbmdfc3RyZWFtXyA9IHZhbHVlOyB9CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weUlucHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBib29sIFNraXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICAvLyBJbnN1cmVzIHRoYXQgYnVmZmVyXyBpcyBub3QgTlVMTC4KKyAgdm9pZCBBbGxvY2F0ZUJ1ZmZlcklmTmVlZGVkKCk7CisgIC8vIEZyZWVzIHRoZSBidWZmZXIgYW5kIHJlc2V0cyBidWZmZXJfdXNlZF8uCisgIHZvaWQgRnJlZUJ1ZmZlcigpOworCisgIC8vIFRoZSB1bmRlcmx5aW5nIGNvcHlpbmcgc3RyZWFtLgorICBDb3B5aW5nSW5wdXRTdHJlYW0qIGNvcHlpbmdfc3RyZWFtXzsKKyAgYm9vbCBvd25zX2NvcHlpbmdfc3RyZWFtXzsKKworICAvLyBUcnVlIGlmIHdlIGhhdmUgc2VlbiBhIHBlcm1lbmFudCBlcnJvciBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgYm9vbCBmYWlsZWRfOworCisgIC8vIFRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIGNvcHlpbmdfc3RyZWFtXywgcmVsYXRpdmUgdG8gdGhlIHBvaW50IHdoZXJlCisgIC8vIHdlIHN0YXJ0ZWQgcmVhZGluZy4KKyAgaW50NjQgcG9zaXRpb25fOworCisgIC8vIERhdGEgaXMgcmVhZCBpbnRvIHRoaXMgYnVmZmVyLiAgSXQgbWF5IGJlIE5VTEwgaWYgbm8gYnVmZmVyIGlzIGN1cnJlbnRseQorICAvLyBpbiB1c2UuICBPdGhlcndpc2UsIGl0IHBvaW50cyB0byBhbiBhcnJheSBvZiBzaXplIGJ1ZmZlcl9zaXplXy4KKyAgc2NvcGVkX2FycmF5PHVpbnQ4PiBidWZmZXJfOworICBjb25zdCBpbnQgYnVmZmVyX3NpemVfOworCisgIC8vIE51bWJlciBvZiB2YWxpZCBieXRlcyBjdXJyZW50bHkgaW4gdGhlIGJ1ZmZlciAoaS5lLiB0aGUgc2l6ZSBsYXN0CisgIC8vIHJldHVybmVkIGJ5IE5leHQoKSkuICAwIDw9IGJ1ZmZlcl91c2VkXyA8PSBidWZmZXJfc2l6ZV8uCisgIGludCBidWZmZXJfdXNlZF87CisKKyAgLy8gTnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBidWZmZXIgd2hpY2ggd2VyZSBiYWNrZWQgdXAgb3ZlciBieSBhIGNhbGwgdG8KKyAgLy8gQmFja1VwKCkuICBUaGVzZSBuZWVkIHRvIGJlIHJldHVybmVkIGFnYWluLgorICAvLyAwIDw9IGJhY2t1cF9ieXRlc18gPD0gYnVmZmVyX3VzZWRfCisgIGludCBiYWNrdXBfYnl0ZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yKTsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBnZW5lcmljIHRyYWRpdGlvbmFsIG91dHB1dCBzdHJlYW0gaW50ZXJmYWNlLgorLy8KKy8vIExvdHMgb2YgdHJhZGl0aW9uYWwgb3V0cHV0IHN0cmVhbXMgKGUuZy4gZmlsZSBkZXNjcmlwdG9ycywgQyBzdGRpbworLy8gc3RyZWFtcywgYW5kIEMrKyBpb3N0cmVhbXMpIGV4cG9zZSBhbiBpbnRlcmZhY2Ugd2hlcmUgZXZlcnkgd3JpdGUKKy8vIGludm9sdmVzIGNvcHlpbmcgYnl0ZXMgZnJvbSBhIGJ1ZmZlci4gIElmIHlvdSB3YW50IHRvIHRha2Ugc3VjaCBhbgorLy8gaW50ZXJmYWNlIGFuZCBtYWtlIGEgWmVyb0NvcHlPdXRwdXRTdHJlYW0gYmFzZWQgb24gaXQsIHNpbXBseSBpbXBsZW1lbnQKKy8vIENvcHlpbmdPdXRwdXRTdHJlYW0gYW5kIHRoZW4gdXNlIENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yLgorLy8KKy8vIENvcHlpbmdPdXRwdXRTdHJlYW0gaW1wbGVtZW50YXRpb25zIHNob3VsZCBhdm9pZCBidWZmZXJpbmcgaWYgcG9zc2libGUuCisvLyBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvciBkb2VzIGl0cyBvd24gYnVmZmVyaW5nIGFuZCB3aWxsIHdyaXRlIGRhdGEKKy8vIGluIGxhcmdlIGJsb2Nrcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nT3V0cHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgfkNvcHlpbmdPdXRwdXRTdHJlYW0oKTsKKworICAvLyBXcml0ZXMgInNpemUiIGJ5dGVzIGZyb20gdGhlIGdpdmVuIGJ1ZmZlciB0byB0aGUgb3V0cHV0LiAgUmV0dXJucyB0cnVlCisgIC8vIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGEgd3JpdGUgZXJyb3IuCisgIHZpcnR1YWwgYm9vbCBXcml0ZShjb25zdCB2b2lkKiBidWZmZXIsIGludCBzaXplKSA9IDA7Cit9OworCisvLyBBIFplcm9Db3B5T3V0cHV0U3RyZWFtIHdoaWNoIHdyaXRlcyB0byBhIENvcHlpbmdPdXRwdXRTdHJlYW0uICBUaGlzIGlzCisvLyB1c2VmdWwgZm9yIGltcGxlbWVudGluZyBaZXJvQ29weU91dHB1dFN0cmVhbXMgdGhhdCB3cml0ZSB0byB0cmFkaXRpb25hbAorLy8gc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGlzIGNsYXNzIGlzIG5vdCByZWFsbHkgemVyby1jb3B5LgorLy8KKy8vIElmIHlvdSB3YW50IHRvIHdyaXRlIHRvIGZpbGUgZGVzY3JpcHRvcnMgb3IgQysrIG9zdHJlYW1zLCB0aGlzIGlzCisvLyBhbHJlYWR5IGltcGxlbWVudGVkIGZvciB5b3U6ICB1c2UgRmlsZU91dHB1dFN0cmVhbSBvciBPc3RyZWFtT3V0cHV0U3RyZWFtCisvLyByZXNwZWN0aXZlbHkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IgOiBwdWJsaWMgWmVyb0NvcHlPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgLy8gQ3JlYXRlcyBhIHN0cmVhbSB0aGF0IHdyaXRlcyB0byB0aGUgZ2l2ZW4gVW5peCBmaWxlIGRlc2NyaXB0b3IuCisgIC8vIElmIGEgYmxvY2tfc2l6ZSBpcyBnaXZlbiwgaXQgc3BlY2lmaWVzIHRoZSBzaXplIG9mIHRoZSBidWZmZXJzCisgIC8vIHRoYXQgc2hvdWxkIGJlIHJldHVybmVkIGJ5IE5leHQoKS4gIE90aGVyd2lzZSwgYSByZWFzb25hYmxlIGRlZmF1bHQKKyAgLy8gaXMgdXNlZC4KKyAgZXhwbGljaXQgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IoQ29weWluZ091dHB1dFN0cmVhbSogY29weWluZ19zdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBibG9ja19zaXplID0gLTEpOworICB+Q29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IoKTsKKworICAvLyBXcml0ZXMgYWxsIHBlbmRpbmcgZGF0YSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0uICBSZXR1cm5zIGZhbHNlIGlmIGEKKyAgLy8gd3JpdGUgZXJyb3Igb2NjdXJyZWQgb24gdGhlIHVuZGVybHlpbmcgc3RyZWFtLiAgKFRoZSB1bmRlcmx5aW5nCisgIC8vIHN0cmVhbSBpdHNlbGYgaXMgbm90IG5lY2Vzc2FyaWx5IGZsdXNoZWQuKQorICBib29sIEZsdXNoKCk7CisKKyAgLy8gQ2FsbCBTZXRPd25zQ29weWluZ1N0cmVhbSh0cnVlKSB0byB0ZWxsIHRoZSBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvciB0bworICAvLyBkZWxldGUgdGhlIHVuZGVybHlpbmcgQ29weWluZ091dHB1dFN0cmVhbSB3aGVuIGl0IGlzIGRlc3Ryb3llZC4KKyAgdm9pZCBTZXRPd25zQ29weWluZ1N0cmVhbShib29sIHZhbHVlKSB7IG93bnNfY29weWluZ19zdHJlYW1fID0gdmFsdWU7IH0KKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5T3V0cHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgLy8gV3JpdGUgdGhlIGN1cnJlbnQgYnVmZmVyLCBpZiBpdCBpcyBwcmVzZW50LgorICBib29sIFdyaXRlQnVmZmVyKCk7CisgIC8vIEluc3VyZXMgdGhhdCBidWZmZXJfIGlzIG5vdCBOVUxMLgorICB2b2lkIEFsbG9jYXRlQnVmZmVySWZOZWVkZWQoKTsKKyAgLy8gRnJlZXMgdGhlIGJ1ZmZlci4KKyAgdm9pZCBGcmVlQnVmZmVyKCk7CisKKyAgLy8gVGhlIHVuZGVybHlpbmcgY29weWluZyBzdHJlYW0uCisgIENvcHlpbmdPdXRwdXRTdHJlYW0qIGNvcHlpbmdfc3RyZWFtXzsKKyAgYm9vbCBvd25zX2NvcHlpbmdfc3RyZWFtXzsKKworICAvLyBUcnVlIGlmIHdlIGhhdmUgc2VlbiBhIHBlcm1lbmFudCBlcnJvciBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgYm9vbCBmYWlsZWRfOworCisgIC8vIFRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIGNvcHlpbmdfc3RyZWFtXywgcmVsYXRpdmUgdG8gdGhlIHBvaW50IHdoZXJlCisgIC8vIHdlIHN0YXJ0ZWQgd3JpdGluZy4KKyAgaW50NjQgcG9zaXRpb25fOworCisgIC8vIERhdGEgaXMgd3JpdHRlbiBmcm9tIHRoaXMgYnVmZmVyLiAgSXQgbWF5IGJlIE5VTEwgaWYgbm8gYnVmZmVyIGlzCisgIC8vIGN1cnJlbnRseSBpbiB1c2UuICBPdGhlcndpc2UsIGl0IHBvaW50cyB0byBhbiBhcnJheSBvZiBzaXplIGJ1ZmZlcl9zaXplXy4KKyAgc2NvcGVkX2FycmF5PHVpbnQ4PiBidWZmZXJfOworICBjb25zdCBpbnQgYnVmZmVyX3NpemVfOworCisgIC8vIE51bWJlciBvZiB2YWxpZCBieXRlcyBjdXJyZW50bHkgaW4gdGhlIGJ1ZmZlciAoaS5lLiB0aGUgc2l6ZSBsYXN0CisgIC8vIHJldHVybmVkIGJ5IE5leHQoKSkuICBXaGVuIEJhY2tVcCgpIGlzIGNhbGxlZCwgd2UganVzdCByZWR1Y2UgdGhpcy4KKyAgLy8gMCA8PSBidWZmZXJfdXNlZF8gPD0gYnVmZmVyX3NpemVfLgorICBpbnQgYnVmZmVyX3VzZWRfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcik7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIG11dGFibGVfc3RyaW5nX2RhdGEoKSBhbmQgYXNfc3RyaW5nX2RhdGEoKSBhcmUgd29ya2Fyb3VuZHMgdG8gaW1wcm92ZQorLy8gdGhlIHBlcmZvcm1hbmNlIG9mIHdyaXRpbmcgbmV3IGRhdGEgdG8gYW4gZXhpc3Rpbmcgc3RyaW5nLiAgVW5mb3J0dW5hdGVseQorLy8gdGhlIG1ldGhvZHMgcHJvdmlkZWQgYnkgdGhlIHN0cmluZyBjbGFzcyBhcmUgc3Vib3B0aW1hbCwgYW5kIHVzaW5nIG1lbWNweSgpCisvLyBpcyBtaWxkbHkgYW5ub3lpbmcgYmVjYXVzZSBpdCByZXF1aXJlcyBpdHMgcG9pbnRlciBhcmdzIHRvIGJlIG5vbi1OVUxMIGV2ZW4KKy8vIGlmIHdlIGFzayBpdCB0byBjb3B5IDAgYnl0ZXMuICBGdXJ0aGVybW9yZSwgc3RyaW5nX2FzX2FycmF5KCkgaGFzIHRoZQorLy8gcHJvcGVydHkgdGhhdCBpdCBhbHdheXMgcmV0dXJucyBOVUxMIGlmIGl0cyBhcmcgaXMgdGhlIGVtcHR5IHN0cmluZywgZXhhY3RseQorLy8gd2hhdCB3ZSB3YW50IHRvIGF2b2lkIGlmIHdlJ3JlIHVzaW5nIGl0IGluIGNvbmp1bmN0aW9uIHdpdGggbWVtY3B5KCkhCisvLyBXaXRoIEMrKzExLCB0aGUgZGVzaXJlZCBtZW1jcHkoKSBib2lscyBkb3duIHRvIG1lbWNweSguLi4sICYoKnMpWzBdLCBzaXplKSwKKy8vIHdoZXJlIHMgaXMgYSBzdHJpbmcqLiAgV2l0aG91dCBDKysxMSwgJigqcylbMF0gaXMgbm90IGd1YXJhbnRlZWQgdG8gYmUgc2FmZSwKKy8vIHNvIHdlIHVzZSBzdHJpbmdfYXNfYXJyYXkoKSwgYW5kIGxpdmUgd2l0aCB0aGUgZXh0cmEgbG9naWMgdGhhdCB0ZXN0cyB3aGV0aGVyCisvLyAqcyBpcyBlbXB0eS4KKworLy8gUmV0dXJuIGEgcG9pbnRlciB0byBtdXRhYmxlIGNoYXJhY3RlcnMgdW5kZXJseWluZyB0aGUgZ2l2ZW4gc3RyaW5nLiAgVGhlCisvLyByZXR1cm4gdmFsdWUgaXMgdmFsaWQgdW50aWwgdGhlIG5leHQgdGltZSB0aGUgc3RyaW5nIGlzIHJlc2l6ZWQuICBXZQorLy8gdHJ1c3QgdGhlIGNhbGxlciB0byB0cmVhdCB0aGUgcmV0dXJuIHZhbHVlIGFzIGFuIGFycmF5IG9mIGxlbmd0aCBzLT5zaXplKCkuCitpbmxpbmUgY2hhciogbXV0YWJsZV9zdHJpbmdfZGF0YShzdHJpbmcqIHMpIHsKKyNpZmRlZiBMQU5HX0NYWDExCisgIC8vIFRoaXMgc2hvdWxkIGJlIHNpbXBsZXIgJiBmYXN0ZXIgdGhhbiBzdHJpbmdfYXNfYXJyYXkoKSBiZWNhdXNlIHRoZSBsYXR0ZXIKKyAgLy8gaXMgZ3VhcmFudGVlZCB0byByZXR1cm4gTlVMTCB3aGVuICpzIGlzIGVtcHR5LCBzbyBpdCBoYXMgdG8gY2hlY2sgZm9yIHRoYXQuCisgIHJldHVybiAmKCpzKVswXTsKKyNlbHNlCisgIHJldHVybiBzdHJpbmdfYXNfYXJyYXkocyk7CisjZW5kaWYKK30KKworLy8gYXNfc3RyaW5nX2RhdGEocykgaXMgZXF1aXZhbGVudCB0bworLy8gICh7IGNoYXIqIHAgPSBtdXRhYmxlX3N0cmluZ19kYXRhKHMpOyBtYWtlX3BhaXIocCwgcCAhPSBOVUxMKTsgfSkKKy8vIFNvbWV0aW1lcyBpdCdzIGZhc3RlcjogaW4gc29tZSBzY2VuYXJpb3MgcCBjYW5ub3QgYmUgTlVMTCwgYW5kIHRoZW4gdGhlCisvLyBjb2RlIGNhbiBhdm9pZCB0aGF0IGNoZWNrLgoraW5saW5lIHN0ZDo6cGFpcjxjaGFyKiwgYm9vbD4gYXNfc3RyaW5nX2RhdGEoc3RyaW5nKiBzKSB7CisgIGNoYXIgKnAgPSBtdXRhYmxlX3N0cmluZ19kYXRhKHMpOworI2lmZGVmIExBTkdfQ1hYMTEKKyAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKHAsIHRydWUpOworI2Vsc2UKKyAgcmV0dXJuIG1ha2VfcGFpcihwLCBwICE9IE5VTEwpOworI2VuZGlmCit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSU1QTF9MSVRFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkM2QxMjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1fdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMDAyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGVzdGluZyBzdHJhdGVneTogIEZvciBlYWNoIHR5cGUgb2YgSS9PIChhcnJheSwgc3RyaW5nLCBmaWxlLCBldGMuKSB3ZQorLy8gY3JlYXRlIGFuIG91dHB1dCBzdHJlYW0gYW5kIHdyaXRlIHNvbWUgZGF0YSB0byBpdCwgdGhlbiBjcmVhdGUgYQorLy8gY29ycmVzcG9uZGluZyBpbnB1dCBzdHJlYW0gdG8gcmVhZCB0aGUgc2FtZSBkYXRhIGJhY2sgYW5kIGV4cGVjdCBpdCB0bworLy8gbWF0Y2guICBXaGVuIHRoZSBkYXRhIGlzIHdyaXR0ZW4sIGl0IGlzIHdyaXR0ZW4gaW4gc2V2ZXJhbCBzbWFsbCBjaHVua3MKKy8vIG9mIHZhcnlpbmcgc2l6ZXMsIHdpdGggYSBCYWNrVXAoKSBhZnRlciBlYWNoIGNodW5rLiAgSXQgaXMgcmVhZCBiYWNrCisvLyBzaW1pbGFybHksIGJ1dCB3aXRoIGNodW5rcyBzZXBhcmF0ZWQgYXQgZGlmZmVyZW50IHBvaW50cy4gIFRoZSB3aG9sZQorLy8gcHJvY2VzcyBpcyBydW4gd2l0aCBhIHZhcmlldHkgb2YgYmxvY2sgc2l6ZXMgZm9yIGJvdGggdGhlIGlucHV0IGFuZAorLy8gdGhlIG91dHB1dC4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBSZXdyaXRlIHRoaXMgdGVzdCB0byBicmluZyBpdCB1cCB0byB0aGUgc3RhbmRhcmRzIG9mIGFsbAorLy8gICB0aGUgb3RoZXIgcHJvdG8yIHRlc3RzLiAgTWF5IHdhbnQgdG8gd2FpdCBmb3IgZ1Rlc3QgdG8gaW1wbGVtZW50CisvLyAgICJwYXJhbWV0aXplZCB0ZXN0cyIgc28gdGhhdCBvbmUgc2V0IG9mIHRlc3RzIGNhbiBiZSB1c2VkIG9uIGFsbCB0aGUKKy8vICAgaW1wbGVtZW50YXRpb25zLgorCisjaW5jbHVkZSAiY29uZmlnLmgiCisKKyNpZmRlZiBfTVNDX1ZFUgorI2luY2x1ZGUgPGlvLmg+CisjZWxzZQorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisKKyNpZiBIQVZFX1pMSUIKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK25hbWVzcGFjZSB7CisKKyNpZmRlZiBfV0lOMzIKKyNkZWZpbmUgcGlwZShmZHMpIF9waXBlKGZkcywgNDA5NiwgT19CSU5BUlkpCisjZW5kaWYKKworI2lmbmRlZiBPX0JJTkFSWQorI2lmZGVmIF9PX0JJTkFSWQorI2RlZmluZSBPX0JJTkFSWSBfT19CSU5BUlkKKyNlbHNlCisjZGVmaW5lIE9fQklOQVJZIDAgICAgIC8vIElmIHRoaXMgaXNuJ3QgZGVmaW5lZCwgdGhlIHBsYXRmb3JtIGRvZXNuJ3QgbmVlZCBpdC4KKyNlbmRpZgorI2VuZGlmCisKK2NsYXNzIElvVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIC8vIFRlc3QgaGVscGVycy4KKworICAvLyBIZWxwZXIgdG8gd3JpdGUgYW4gYXJyYXkgb2YgZGF0YSB0byBhbiBvdXRwdXQgc3RyZWFtLgorICBib29sIFdyaXRlVG9PdXRwdXQoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpOworICAvLyBIZWxwZXIgdG8gcmVhZCBhIGZpeGVkLWxlbmd0aCBhcnJheSBvZiBkYXRhIGZyb20gYW4gaW5wdXQgc3RyZWFtLgorICBpbnQgUmVhZEZyb21JbnB1dChaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgdm9pZCogZGF0YSwgaW50IHNpemUpOworICAvLyBXcml0ZSBhIHN0cmluZyB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgdm9pZCBXcml0ZVN0cmluZyhaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0LCBjb25zdCBzdHJpbmcmIHN0cik7CisgIC8vIFJlYWQgYSBudW1iZXIgb2YgYnl0ZXMgZXF1YWwgdG8gdGhlIHNpemUgb2YgdGhlIGdpdmVuIHN0cmluZyBhbmQgY2hlY2tzCisgIC8vIHRoYXQgaXQgbWF0Y2hlcyB0aGUgc3RyaW5nLgorICB2b2lkIFJlYWRTdHJpbmcoWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIGNvbnN0IHN0cmluZyYgc3RyKTsKKyAgLy8gV3JpdGVzIHNvbWUgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbSBpbiBhIHBhcnRpY3VsYXIgb3JkZXIuICBSZXR1cm5zCisgIC8vIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiwgaW5jYXNlIHRoZSBjYWxsZXIgbmVlZHMgdGhhdCB0byBzZXQgdXAgYW4KKyAgLy8gaW5wdXQgc3RyZWFtLgorICBpbnQgV3JpdGVTdHVmZihaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KTsKKyAgLy8gUmVhZHMgdGV4dCBmcm9tIGFuIGlucHV0IHN0cmVhbSBhbmQgZXhwZWN0cyBpdCB0byBtYXRjaCB3aGF0CisgIC8vIFdyaXRlU3R1ZmYoKSB3cml0ZXMuCisgIHZvaWQgUmVhZFN0dWZmKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KTsKKworICAvLyBTaW1pbGFyIHRvIFdyaXRlU3R1ZmYsIGJ1dCBwZXJmb3JtcyBtb3JlIHNvcGhpc3RpY2F0ZWQgdGVzdGluZy4KKyAgaW50IFdyaXRlU3R1ZmZMYXJnZShaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KTsKKyAgLy8gUmVhZHMgYW5kIHRlc3RzIGEgc3RyZWFtIHRoYXQgc2hvdWxkIGhhdmUgYmVlbiB3cml0dGVuIHRvCisgIC8vIHZpYSBXcml0ZVN0dWZmTGFyZ2UoKS4KKyAgdm9pZCBSZWFkU3R1ZmZMYXJnZShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCk7CisKKyNpZiBIQVZFX1pMSUIKKyAgc3RyaW5nIENvbXByZXNzKGNvbnN0IHN0cmluZyYgZGF0YSwgY29uc3QgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyYgb3B0aW9ucyk7CisgIHN0cmluZyBVbmNvbXByZXNzKGNvbnN0IHN0cmluZyYgZGF0YSk7CisjZW5kaWYKKworICBzdGF0aWMgY29uc3QgaW50IGtCbG9ja1NpemVzW107CisgIHN0YXRpYyBjb25zdCBpbnQga0Jsb2NrU2l6ZUNvdW50OworfTsKKworY29uc3QgaW50IElvVGVzdDo6a0Jsb2NrU2l6ZXNbXSA9IHstMSwgMSwgMiwgNSwgNywgMTAsIDIzLCA2NH07Citjb25zdCBpbnQgSW9UZXN0OjprQmxvY2tTaXplQ291bnQgPSBHT09HTEVfQVJSQVlTSVpFKElvVGVzdDo6a0Jsb2NrU2l6ZXMpOworCitib29sIElvVGVzdDo6V3JpdGVUb091dHB1dChaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpIHsKKyAgY29uc3QgdWludDgqIGluID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KGRhdGEpOworICBpbnQgaW5fc2l6ZSA9IHNpemU7CisKKyAgdm9pZCogb3V0OworICBpbnQgb3V0X3NpemU7CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBpZiAoIW91dHB1dC0+TmV4dCgmb3V0LCAmb3V0X3NpemUpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIEVYUEVDVF9HVChvdXRfc2l6ZSwgMCk7CisKKyAgICBpZiAoaW5fc2l6ZSA8PSBvdXRfc2l6ZSkgeworICAgICAgbWVtY3B5KG91dCwgaW4sIGluX3NpemUpOworICAgICAgb3V0cHV0LT5CYWNrVXAob3V0X3NpemUgLSBpbl9zaXplKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIG1lbWNweShvdXQsIGluLCBvdXRfc2l6ZSk7CisgICAgaW4gKz0gb3V0X3NpemU7CisgICAgaW5fc2l6ZSAtPSBvdXRfc2l6ZTsKKyAgfQorfQorCisjZGVmaW5lIE1BWF9SRVBFQVRFRF9aRVJPUyAxMDAKKworaW50IElvVGVzdDo6UmVhZEZyb21JbnB1dChaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgdm9pZCogZGF0YSwgaW50IHNpemUpIHsKKyAgdWludDgqIG91dCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihkYXRhKTsKKyAgaW50IG91dF9zaXplID0gc2l6ZTsKKworICBjb25zdCB2b2lkKiBpbjsKKyAgaW50IGluX3NpemUgPSAwOworCisgIGludCByZXBlYXRlZF96ZXJvcyA9IDA7CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBpZiAoIWlucHV0LT5OZXh0KCZpbiwgJmluX3NpemUpKSB7CisgICAgICByZXR1cm4gc2l6ZSAtIG91dF9zaXplOworICAgIH0KKyAgICBFWFBFQ1RfR1QoaW5fc2l6ZSwgLTEpOworICAgIGlmIChpbl9zaXplID09IDApIHsKKyAgICAgIHJlcGVhdGVkX3plcm9zKys7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlcGVhdGVkX3plcm9zID0gMDsKKyAgICB9CisgICAgRVhQRUNUX0xUKHJlcGVhdGVkX3plcm9zLCBNQVhfUkVQRUFURURfWkVST1MpOworCisgICAgaWYgKG91dF9zaXplIDw9IGluX3NpemUpIHsKKyAgICAgIG1lbWNweShvdXQsIGluLCBvdXRfc2l6ZSk7CisgICAgICBpZiAoaW5fc2l6ZSA+IG91dF9zaXplKSB7CisgICAgICAgIGlucHV0LT5CYWNrVXAoaW5fc2l6ZSAtIG91dF9zaXplKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBzaXplOyAgLy8gQ29waWVkIGFsbCBvZiBpdC4KKyAgICB9CisKKyAgICBtZW1jcHkob3V0LCBpbiwgaW5fc2l6ZSk7CisgICAgb3V0ICs9IGluX3NpemU7CisgICAgb3V0X3NpemUgLT0gaW5fc2l6ZTsKKyAgfQorfQorCit2b2lkIElvVGVzdDo6V3JpdGVTdHJpbmcoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgY29uc3Qgc3RyaW5nJiBzdHIpIHsKKyAgRVhQRUNUX1RSVUUoV3JpdGVUb091dHB1dChvdXRwdXQsIHN0ci5jX3N0cigpLCBzdHIuc2l6ZSgpKSk7Cit9CisKK3ZvaWQgSW9UZXN0OjpSZWFkU3RyaW5nKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBjb25zdCBzdHJpbmcmIHN0cikgeworICBzY29wZWRfYXJyYXk8Y2hhcj4gYnVmZmVyKG5ldyBjaGFyW3N0ci5zaXplKCkgKyAxXSk7CisgIGJ1ZmZlcltzdHIuc2l6ZSgpXSA9ICdcMCc7CisgIEVYUEVDVF9FUShSZWFkRnJvbUlucHV0KGlucHV0LCBidWZmZXIuZ2V0KCksIHN0ci5zaXplKCkpLCBzdHIuc2l6ZSgpKTsKKyAgRVhQRUNUX1NUUkVRKHN0ci5jX3N0cigpLCBidWZmZXIuZ2V0KCkpOworfQorCitpbnQgSW9UZXN0OjpXcml0ZVN0dWZmKFplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiSGVsbG8gd29ybGQhXG4iKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiU29tZSB0ZSIpOworICBXcml0ZVN0cmluZyhvdXRwdXQsICJ4dC4gIEJsYWggYmxhaC4iKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiYWJjZGVmZyIpOworICBXcml0ZVN0cmluZyhvdXRwdXQsICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIpOworICBXcml0ZVN0cmluZyhvdXRwdXQsICJmb29iYXIiKTsKKworICBFWFBFQ1RfRVEob3V0cHV0LT5CeXRlQ291bnQoKSwgNjgpOworCisgIGludCByZXN1bHQgPSBvdXRwdXQtPkJ5dGVDb3VudCgpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBSZWFkcyB0ZXh0IGZyb20gYW4gaW5wdXQgc3RyZWFtIGFuZCBleHBlY3RzIGl0IHRvIG1hdGNoIHdoYXQgV3JpdGVTdHVmZigpCisvLyB3cml0ZXMuCit2b2lkIElvVGVzdDo6UmVhZFN0dWZmKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJIZWxsbyB3b3JsZCFcbiIpOworICBSZWFkU3RyaW5nKGlucHV0LCAiU29tZSB0ZXh0LiAgIik7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJCbGFoICIpOworICBSZWFkU3RyaW5nKGlucHV0LCAiYmxhaC4iKTsKKyAgUmVhZFN0cmluZyhpbnB1dCwgImFiY2RlZmciKTsKKyAgRVhQRUNUX1RSVUUoaW5wdXQtPlNraXAoMjApKTsKKyAgUmVhZFN0cmluZyhpbnB1dCwgImZvbyIpOworICBSZWFkU3RyaW5nKGlucHV0LCAiYmFyIik7CisKKyAgRVhQRUNUX0VRKGlucHV0LT5CeXRlQ291bnQoKSwgNjgpOworCisgIHVpbnQ4IGJ5dGU7CisgIEVYUEVDVF9FUShSZWFkRnJvbUlucHV0KGlucHV0LCAmYnl0ZSwgMSksIDApOworfQorCitpbnQgSW9UZXN0OjpXcml0ZVN0dWZmTGFyZ2UoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVN0cmluZyhvdXRwdXQsICJIZWxsbyB3b3JsZCFcbiIpOworICBXcml0ZVN0cmluZyhvdXRwdXQsICJTb21lIHRlIik7CisgIFdyaXRlU3RyaW5nKG91dHB1dCwgInh0LiAgQmxhaCBibGFoLiIpOworICBXcml0ZVN0cmluZyhvdXRwdXQsIHN0cmluZygxMDAwMDAsICd4JykpOyAgLy8gQSB2ZXJ5IGxvbmcgc3RyaW5nCisgIFdyaXRlU3RyaW5nKG91dHB1dCwgc3RyaW5nKDEwMDAwMCwgJ3knKSk7ICAvLyBBIHZlcnkgbG9uZyBzdHJpbmcKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkiKTsKKworICBFWFBFQ1RfRVEob3V0cHV0LT5CeXRlQ291bnQoKSwgMjAwMDU1KTsKKworICBpbnQgcmVzdWx0ID0gb3V0cHV0LT5CeXRlQ291bnQoKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gUmVhZHMgdGV4dCBmcm9tIGFuIGlucHV0IHN0cmVhbSBhbmQgZXhwZWN0cyBpdCB0byBtYXRjaCB3aGF0IFdyaXRlU3R1ZmYoKQorLy8gd3JpdGVzLgordm9pZCBJb1Rlc3Q6OlJlYWRTdHVmZkxhcmdlKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJIZWxsbyB3b3JsZCFcblNvbWUgdGV4dC4gICIpOworICBFWFBFQ1RfVFJVRShpbnB1dC0+U2tpcCg1KSk7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJibGFoLiIpOworICBFWFBFQ1RfVFJVRShpbnB1dC0+U2tpcCgxMDAwMDAgLSAxMCkpOworICBSZWFkU3RyaW5nKGlucHV0LCBzdHJpbmcoMTAsICd4JykgKyBzdHJpbmcoMTAwMDAwIC0gMjAwMDAsICd5JykpOworICBFWFBFQ1RfVFJVRShpbnB1dC0+U2tpcCgyMDAwMCAtIDEwKSk7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJ5eXl5eXl5eXl5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiKTsKKworICBFWFBFQ1RfRVEoaW5wdXQtPkJ5dGVDb3VudCgpLCAyMDAwNTUpOworCisgIHVpbnQ4IGJ5dGU7CisgIEVYUEVDVF9FUShSZWFkRnJvbUlucHV0KGlucHV0LCAmYnl0ZSwgMSksIDApOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RFU1RfRihJb1Rlc3QsIEFycmF5SW8pIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMjU2OworICB1aW50OCBidWZmZXJba0J1ZmZlclNpemVdOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCbG9ja1NpemVDb3VudDsgaisrKSB7CisgICAgICBpbnQgc2l6ZTsKKyAgICAgIHsKKyAgICAgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwga0J1ZmZlclNpemUsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgc2l6ZSA9IFdyaXRlU3R1ZmYoJm91dHB1dCk7CisgICAgICB9CisgICAgICB7CisgICAgICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgIFJlYWRTdHVmZigmaW5wdXQpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitURVNUX0YoSW9UZXN0LCBUd29TZXNzaW9uV3JpdGUpIHsKKyAgLy8gVGVzdCB0aGF0IHR3byBjb25jYXRlbmF0ZWQgd3JpdGUgc2Vzc2lvbnMgcmVhZCBjb3JyZWN0bHkKKworICBzdGF0aWMgY29uc3QgY2hhciogc3RyQSA9ICIwMTIzNDU2Nzg5IjsKKyAgc3RhdGljIGNvbnN0IGNoYXIqIHN0ckIgPSAiV2hpcmxlZFBlYXMiOworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyKjEwMjQ7CisgIHVpbnQ4KiBidWZmZXIgPSBuZXcgdWludDhba0J1ZmZlclNpemVdOworICBjaGFyKiB0ZW1wX2J1ZmZlciA9IG5ldyBjaGFyWzQwXTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgQXJyYXlPdXRwdXRTdHJlYW0qIG91dHB1dCA9CisgICAgICAgICAgbmV3IEFycmF5T3V0cHV0U3RyZWFtKGJ1ZmZlciwga0J1ZmZlclNpemUsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBjb2RlZF9vdXRwdXQgPSBuZXcgQ29kZWRPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVWYXJpbnQzMihzdHJsZW4oc3RyQSkpOworICAgICAgY29kZWRfb3V0cHV0LT5Xcml0ZVJhdyhzdHJBLCBzdHJsZW4oc3RyQSkpOworICAgICAgZGVsZXRlIGNvZGVkX291dHB1dDsgIC8vIGZsdXNoCisgICAgICBpbnQ2NCBwb3MgPSBvdXRwdXQtPkJ5dGVDb3VudCgpOworICAgICAgZGVsZXRlIG91dHB1dDsKKyAgICAgIG91dHB1dCA9IG5ldyBBcnJheU91dHB1dFN0cmVhbSgKKyAgICAgICAgICBidWZmZXIgKyBwb3MsIGtCdWZmZXJTaXplIC0gcG9zLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICBjb2RlZF9vdXRwdXQgPSBuZXcgQ29kZWRPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVWYXJpbnQzMihzdHJsZW4oc3RyQikpOworICAgICAgY29kZWRfb3V0cHV0LT5Xcml0ZVJhdyhzdHJCLCBzdHJsZW4oc3RyQikpOworICAgICAgZGVsZXRlIGNvZGVkX291dHB1dDsgIC8vIGZsdXNoCisgICAgICBpbnQ2NCBzaXplID0gcG9zICsgb3V0cHV0LT5CeXRlQ291bnQoKTsKKyAgICAgIGRlbGV0ZSBvdXRwdXQ7CisKKyAgICAgIEFycmF5SW5wdXRTdHJlYW0qIGlucHV0ID0KKyAgICAgICAgICBuZXcgQXJyYXlJbnB1dFN0cmVhbShidWZmZXIsIHNpemUsIGtCbG9ja1NpemVzW2pdKTsKKyAgICAgIENvZGVkSW5wdXRTdHJlYW0qIGNvZGVkX2lucHV0ID0gbmV3IENvZGVkSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgdWludDMyIGluc2l6ZTsKKyAgICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LT5SZWFkVmFyaW50MzIoJmluc2l6ZSkpOworICAgICAgRVhQRUNUX0VRKHN0cmxlbihzdHJBKSwgaW5zaXplKTsKKyAgICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LT5SZWFkUmF3KHRlbXBfYnVmZmVyLCBpbnNpemUpKTsKKyAgICAgIEVYUEVDVF9FUSgwLCBtZW1jbXAodGVtcF9idWZmZXIsIHN0ckEsIGluc2l6ZSkpOworCisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFZhcmludDMyKCZpbnNpemUpKTsKKyAgICAgIEVYUEVDVF9FUShzdHJsZW4oc3RyQiksIGluc2l6ZSk7CisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFJhdyh0ZW1wX2J1ZmZlciwgaW5zaXplKSk7CisgICAgICBFWFBFQ1RfRVEoMCwgbWVtY21wKHRlbXBfYnVmZmVyLCBzdHJCLCBpbnNpemUpKTsKKworICAgICAgZGVsZXRlIGNvZGVkX2lucHV0OworICAgICAgZGVsZXRlIGlucHV0OworICAgIH0KKyAgfQorCisgIGRlbGV0ZSBbXSB0ZW1wX2J1ZmZlcjsKKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworI2lmIEhBVkVfWkxJQgorVEVTVF9GKElvVGVzdCwgR3ppcElvKSB7CisgIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDIqMTAyNDsKKyAgdWludDgqIGJ1ZmZlciA9IG5ldyB1aW50OFtrQnVmZmVyU2l6ZV07CisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCbG9ja1NpemVDb3VudDsgaisrKSB7CisgICAgICBmb3IgKGludCB6ID0gMDsgeiA8IGtCbG9ja1NpemVDb3VudDsgeisrKSB7CisgICAgICAgIGludCBnemlwX2J1ZmZlcl9zaXplID0ga0Jsb2NrU2l6ZXNbel07CisgICAgICAgIGludCBzaXplOworICAgICAgICB7CisgICAgICAgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwga0J1ZmZlclNpemUsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgICBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zIG9wdGlvbnM7CisgICAgICAgICAgb3B0aW9ucy5mb3JtYXQgPSBHemlwT3V0cHV0U3RyZWFtOjpHWklQOworICAgICAgICAgIGlmIChnemlwX2J1ZmZlcl9zaXplICE9IC0xKSB7CisgICAgICAgICAgICBvcHRpb25zLmJ1ZmZlcl9zaXplID0gZ3ppcF9idWZmZXJfc2l6ZTsKKyAgICAgICAgICB9CisgICAgICAgICAgR3ppcE91dHB1dFN0cmVhbSBnem91dCgmb3V0cHV0LCBvcHRpb25zKTsKKyAgICAgICAgICBXcml0ZVN0dWZmKCZnem91dCk7CisgICAgICAgICAgZ3pvdXQuQ2xvc2UoKTsKKyAgICAgICAgICBzaXplID0gb3V0cHV0LkJ5dGVDb3VudCgpOworICAgICAgICB9CisgICAgICAgIHsKKyAgICAgICAgICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlciwgc2l6ZSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICAgIEd6aXBJbnB1dFN0cmVhbSBnemluKAorICAgICAgICAgICAgICAmaW5wdXQsIEd6aXBJbnB1dFN0cmVhbTo6R1pJUCwgZ3ppcF9idWZmZXJfc2l6ZSk7CisgICAgICAgICAgUmVhZFN0dWZmKCZnemluKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICBkZWxldGUgW10gYnVmZmVyOworfQorCitURVNUX0YoSW9UZXN0LCBHemlwSW9XaXRoRmx1c2gpIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKyAgLy8gV2Ugc3RhcnQgd2l0aCBpID0gNCBhcyB3ZSB3YW50IGEgYmxvY2sgc2l6ZSA+IDYuIFdpdGggYmxvY2sgc2l6ZSA8PSA2CisgIC8vIEZsdXNoKCkgZmlsbHMgdXAgdGhlIGVudGlyZSAySyBidWZmZXIgd2l0aCBmbHVzaCBtYXJrZXJzIGFuZCB0aGUgdGVzdAorICAvLyBmYWlscy4gU2VlIGRvY3VtZW50YXRpb24gZm9yIEZsdXNoKCkgZm9yIG1vcmUgZGV0YWlsLgorICBmb3IgKGludCBpID0gNDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgZm9yIChpbnQgeiA9IDA7IHogPCBrQmxvY2tTaXplQ291bnQ7IHorKykgeworICAgICAgICBpbnQgZ3ppcF9idWZmZXJfc2l6ZSA9IGtCbG9ja1NpemVzW3pdOworICAgICAgICBpbnQgc2l6ZTsKKyAgICAgICAgeworICAgICAgICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIGtCdWZmZXJTaXplLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICAgICAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICAgICAgICAgIG9wdGlvbnMuZm9ybWF0ID0gR3ppcE91dHB1dFN0cmVhbTo6R1pJUDsKKyAgICAgICAgICBpZiAoZ3ppcF9idWZmZXJfc2l6ZSAhPSAtMSkgeworICAgICAgICAgICAgb3B0aW9ucy5idWZmZXJfc2l6ZSA9IGd6aXBfYnVmZmVyX3NpemU7CisgICAgICAgICAgfQorICAgICAgICAgIEd6aXBPdXRwdXRTdHJlYW0gZ3pvdXQoJm91dHB1dCwgb3B0aW9ucyk7CisgICAgICAgICAgV3JpdGVTdHVmZigmZ3pvdXQpOworICAgICAgICAgIEVYUEVDVF9UUlVFKGd6b3V0LkZsdXNoKCkpOworICAgICAgICAgIGd6b3V0LkNsb3NlKCk7CisgICAgICAgICAgc2l6ZSA9IG91dHB1dC5CeXRlQ291bnQoKTsKKyAgICAgICAgfQorICAgICAgICB7CisgICAgICAgICAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXIsIHNpemUsIGtCbG9ja1NpemVzW2pdKTsKKyAgICAgICAgICBHemlwSW5wdXRTdHJlYW0gZ3ppbigKKyAgICAgICAgICAgICAgJmlucHV0LCBHemlwSW5wdXRTdHJlYW06OkdaSVAsIGd6aXBfYnVmZmVyX3NpemUpOworICAgICAgICAgIFJlYWRTdHVmZigmZ3ppbik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworVEVTVF9GKElvVGVzdCwgR3ppcElvQ29udGlndW91c0ZsdXNoZXMpIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKworICBpbnQgYmxvY2tfc2l6ZSA9IGtCbG9ja1NpemVzWzRdOworICBpbnQgZ3ppcF9idWZmZXJfc2l6ZSA9IGJsb2NrX3NpemU7CisgIGludCBzaXplOworCisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIGtCdWZmZXJTaXplLCBibG9ja19zaXplKTsKKyAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICBvcHRpb25zLmZvcm1hdCA9IEd6aXBPdXRwdXRTdHJlYW06OkdaSVA7CisgIGlmIChnemlwX2J1ZmZlcl9zaXplICE9IC0xKSB7CisgICAgb3B0aW9ucy5idWZmZXJfc2l6ZSA9IGd6aXBfYnVmZmVyX3NpemU7CisgIH0KKyAgR3ppcE91dHB1dFN0cmVhbSBnem91dCgmb3V0cHV0LCBvcHRpb25zKTsKKyAgV3JpdGVTdHVmZigmZ3pvdXQpOworICBFWFBFQ1RfVFJVRShnem91dC5GbHVzaCgpKTsKKyAgRVhQRUNUX1RSVUUoZ3pvdXQuRmx1c2goKSk7CisgIGd6b3V0LkNsb3NlKCk7CisgIHNpemUgPSBvdXRwdXQuQnl0ZUNvdW50KCk7CisKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXIsIHNpemUsIGJsb2NrX3NpemUpOworICBHemlwSW5wdXRTdHJlYW0gZ3ppbigKKyAgICAgICZpbnB1dCwgR3ppcElucHV0U3RyZWFtOjpHWklQLCBnemlwX2J1ZmZlcl9zaXplKTsKKyAgUmVhZFN0dWZmKCZnemluKTsKKworICBkZWxldGUgW10gYnVmZmVyOworfQorCitURVNUX0YoSW9UZXN0LCBHemlwSW9SZWFkQWZ0ZXJGbHVzaCkgeworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyKjEwMjQ7CisgIHVpbnQ4KiBidWZmZXIgPSBuZXcgdWludDhba0J1ZmZlclNpemVdOworCisgIGludCBibG9ja19zaXplID0ga0Jsb2NrU2l6ZXNbNF07CisgIGludCBnemlwX2J1ZmZlcl9zaXplID0gYmxvY2tfc2l6ZTsKKyAgaW50IHNpemU7CisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIGtCdWZmZXJTaXplLCBibG9ja19zaXplKTsKKyAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICBvcHRpb25zLmZvcm1hdCA9IEd6aXBPdXRwdXRTdHJlYW06OkdaSVA7CisgIGlmIChnemlwX2J1ZmZlcl9zaXplICE9IC0xKSB7CisgICAgb3B0aW9ucy5idWZmZXJfc2l6ZSA9IGd6aXBfYnVmZmVyX3NpemU7CisgIH0KKworICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQsIG9wdGlvbnMpOworICBXcml0ZVN0dWZmKCZnem91dCk7CisgIEVYUEVDVF9UUlVFKGd6b3V0LkZsdXNoKCkpOworICBzaXplID0gb3V0cHV0LkJ5dGVDb3VudCgpOworCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplLCBibG9ja19zaXplKTsKKyAgR3ppcElucHV0U3RyZWFtIGd6aW4oCisgICAgICAmaW5wdXQsIEd6aXBJbnB1dFN0cmVhbTo6R1pJUCwgZ3ppcF9idWZmZXJfc2l6ZSk7CisgIFJlYWRTdHVmZigmZ3ppbik7CisKKyAgZ3pvdXQuQ2xvc2UoKTsKKworICBkZWxldGUgW10gYnVmZmVyOworfQorCitURVNUX0YoSW9UZXN0LCBabGliSW8pIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIGZvciAoaW50IHogPSAwOyB6IDwga0Jsb2NrU2l6ZUNvdW50OyB6KyspIHsKKyAgICAgICAgaW50IGd6aXBfYnVmZmVyX3NpemUgPSBrQmxvY2tTaXplc1t6XTsKKyAgICAgICAgaW50IHNpemU7CisgICAgICAgIHsKKyAgICAgICAgICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSwga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgICAgIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMgb3B0aW9uczsKKyAgICAgICAgICBvcHRpb25zLmZvcm1hdCA9IEd6aXBPdXRwdXRTdHJlYW06OlpMSUI7CisgICAgICAgICAgaWYgKGd6aXBfYnVmZmVyX3NpemUgIT0gLTEpIHsKKyAgICAgICAgICAgIG9wdGlvbnMuYnVmZmVyX3NpemUgPSBnemlwX2J1ZmZlcl9zaXplOworICAgICAgICAgIH0KKyAgICAgICAgICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQsIG9wdGlvbnMpOworICAgICAgICAgIFdyaXRlU3R1ZmYoJmd6b3V0KTsKKyAgICAgICAgICBnem91dC5DbG9zZSgpOworICAgICAgICAgIHNpemUgPSBvdXRwdXQuQnl0ZUNvdW50KCk7CisgICAgICAgIH0KKyAgICAgICAgeworICAgICAgICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgICAgR3ppcElucHV0U3RyZWFtIGd6aW4oCisgICAgICAgICAgICAgICZpbnB1dCwgR3ppcElucHV0U3RyZWFtOjpaTElCLCBnemlwX2J1ZmZlcl9zaXplKTsKKyAgICAgICAgICBSZWFkU3R1ZmYoJmd6aW4pOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9CisgIGRlbGV0ZSBbXSBidWZmZXI7Cit9CisKK1RFU1RfRihJb1Rlc3QsIFpsaWJJb0lucHV0QXV0b2RldGVjdCkgeworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyKjEwMjQ7CisgIHVpbnQ4KiBidWZmZXIgPSBuZXcgdWludDhba0J1ZmZlclNpemVdOworICBpbnQgc2l6ZTsKKyAgeworICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIGtCdWZmZXJTaXplKTsKKyAgICBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zIG9wdGlvbnM7CisgICAgb3B0aW9ucy5mb3JtYXQgPSBHemlwT3V0cHV0U3RyZWFtOjpaTElCOworICAgIEd6aXBPdXRwdXRTdHJlYW0gZ3pvdXQoJm91dHB1dCwgb3B0aW9ucyk7CisgICAgV3JpdGVTdHVmZigmZ3pvdXQpOworICAgIGd6b3V0LkNsb3NlKCk7CisgICAgc2l6ZSA9IG91dHB1dC5CeXRlQ291bnQoKTsKKyAgfQorICB7CisgICAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXIsIHNpemUpOworICAgIEd6aXBJbnB1dFN0cmVhbSBnemluKCZpbnB1dCwgR3ppcElucHV0U3RyZWFtOjpBVVRPKTsKKyAgICBSZWFkU3R1ZmYoJmd6aW4pOworICB9CisgIHsKKyAgICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSk7CisgICAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICAgIG9wdGlvbnMuZm9ybWF0ID0gR3ppcE91dHB1dFN0cmVhbTo6R1pJUDsKKyAgICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQsIG9wdGlvbnMpOworICAgIFdyaXRlU3R1ZmYoJmd6b3V0KTsKKyAgICBnem91dC5DbG9zZSgpOworICAgIHNpemUgPSBvdXRwdXQuQnl0ZUNvdW50KCk7CisgIH0KKyAgeworICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplKTsKKyAgICBHemlwSW5wdXRTdHJlYW0gZ3ppbigmaW5wdXQsIEd6aXBJbnB1dFN0cmVhbTo6QVVUTyk7CisgICAgUmVhZFN0dWZmKCZnemluKTsKKyAgfQorICBkZWxldGUgW10gYnVmZmVyOworfQorCitzdHJpbmcgSW9UZXN0OjpDb21wcmVzcyhjb25zdCBzdHJpbmcmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zJiBvcHRpb25zKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHsKKyAgICBTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0KCZyZXN1bHQpOworICAgIEd6aXBPdXRwdXRTdHJlYW0gZ3pvdXQoJm91dHB1dCwgb3B0aW9ucyk7CisgICAgV3JpdGVUb091dHB1dCgmZ3pvdXQsIGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIElvVGVzdDo6VW5jb21wcmVzcyhjb25zdCBzdHJpbmcmIGRhdGEpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgeworICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgICBHemlwSW5wdXRTdHJlYW0gZ3ppbigmaW5wdXQpOworICAgIGNvbnN0IHZvaWQqIGJ1ZmZlcjsKKyAgICBpbnQgc2l6ZTsKKyAgICB3aGlsZSAoZ3ppbi5OZXh0KCZidWZmZXIsICZzaXplKSkgeworICAgICAgcmVzdWx0LmFwcGVuZChyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihidWZmZXIpLCBzaXplKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworVEVTVF9GKElvVGVzdCwgQ29tcHJlc3Npb25PcHRpb25zKSB7CisgIC8vIFNvbWUgYWQtaG9jIHRlc3Rpbmcgb2YgY29tcHJlc3Npb24gb3B0aW9ucy4KKworICBzdHJpbmcgZ29sZGVuOworICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6R2V0Q29udGVudHMoCisgICAgICBUZXN0U291cmNlRGlyKCkgKworICAgICAgICAgICIvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlIiwKKyAgICAgICZnb2xkZW4sIHRydWUpKTsKKworICBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zIG9wdGlvbnM7CisgIHN0cmluZyBnemlwX2NvbXByZXNzZWQgPSBDb21wcmVzcyhnb2xkZW4sIG9wdGlvbnMpOworCisgIG9wdGlvbnMuY29tcHJlc3Npb25fbGV2ZWwgPSAwOworICBzdHJpbmcgbm90X2NvbXByZXNzZWQgPSBDb21wcmVzcyhnb2xkZW4sIG9wdGlvbnMpOworCisgIC8vIFRyeSB6bGliIGNvbXByZXNzaW9uIGZvciBmdW4uCisgIG9wdGlvbnMgPSBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zKCk7CisgIG9wdGlvbnMuZm9ybWF0ID0gR3ppcE91dHB1dFN0cmVhbTo6WkxJQjsKKyAgc3RyaW5nIHpsaWJfY29tcHJlc3NlZCA9IENvbXByZXNzKGdvbGRlbiwgb3B0aW9ucyk7CisKKyAgLy8gVW5jb21wcmVzc2VkIHNob3VsZCBiZSBiaWdnZXIgdGhhbiB0aGUgb3JpZ2luYWwgc2luY2UgaXQgc2hvdWxkIGhhdmUgc29tZQorICAvLyBzb3J0IG9mIGhlYWRlci4KKyAgRVhQRUNUX0dUKG5vdF9jb21wcmVzc2VkLnNpemUoKSwgZ29sZGVuLnNpemUoKSk7CisKKyAgLy8gSGlnaGVyIGNvbXByZXNzaW9uIGxldmVscyBzaG91bGQgcmVzdWx0IGluIHNtYWxsZXIgc2l6ZXMuCisgIEVYUEVDVF9MVCh6bGliX2NvbXByZXNzZWQuc2l6ZSgpLCBub3RfY29tcHJlc3NlZC5zaXplKCkpOworCisgIC8vIFpMSUIgZm9ybWF0IHNob3VsZCBkaWZmZXIgZnJvbSBHWklQIGZvcm1hdC4KKyAgRVhQRUNUX1RSVUUoemxpYl9jb21wcmVzc2VkICE9IGd6aXBfY29tcHJlc3NlZCk7CisKKyAgLy8gRXZlcnl0aGluZyBzaG91bGQgZGVjb21wcmVzcyBjb3JyZWN0bHkuCisgIEVYUEVDVF9UUlVFKFVuY29tcHJlc3Mobm90X2NvbXByZXNzZWQpID09IGdvbGRlbik7CisgIEVYUEVDVF9UUlVFKFVuY29tcHJlc3MoZ3ppcF9jb21wcmVzc2VkKSA9PSBnb2xkZW4pOworICBFWFBFQ1RfVFJVRShVbmNvbXByZXNzKHpsaWJfY29tcHJlc3NlZCkgPT0gZ29sZGVuKTsKK30KKworVEVTVF9GKElvVGVzdCwgVHdvU2Vzc2lvbldyaXRlR3ppcCkgeworICAvLyBUZXN0IHRoYXQgdHdvIGNvbmNhdGVuYXRlZCBnemlwIHN0cmVhbXMgY2FuIGJlIHJlYWQgY29ycmVjdGx5CisKKyAgc3RhdGljIGNvbnN0IGNoYXIqIHN0ckEgPSAiMDEyMzQ1Njc4OSI7CisgIHN0YXRpYyBjb25zdCBjaGFyKiBzdHJCID0gIlF1aWNrQnJvd25Gb3giOworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyKjEwMjQ7CisgIHVpbnQ4KiBidWZmZXIgPSBuZXcgdWludDhba0J1ZmZlclNpemVdOworICBjaGFyKiB0ZW1wX2J1ZmZlciA9IG5ldyBjaGFyWzQwXTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgQXJyYXlPdXRwdXRTdHJlYW0qIG91dHB1dCA9CisgICAgICAgICAgbmV3IEFycmF5T3V0cHV0U3RyZWFtKGJ1ZmZlciwga0J1ZmZlclNpemUsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgIEd6aXBPdXRwdXRTdHJlYW0qIGd6b3V0ID0gbmV3IEd6aXBPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBjb2RlZF9vdXRwdXQgPSBuZXcgQ29kZWRPdXRwdXRTdHJlYW0oZ3pvdXQpOworICAgICAgaW50MzIgb3V0bGVuID0gc3RybGVuKHN0ckEpICsgMTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVWYXJpbnQzMihvdXRsZW4pOworICAgICAgY29kZWRfb3V0cHV0LT5Xcml0ZVJhdyhzdHJBLCBvdXRsZW4pOworICAgICAgZGVsZXRlIGNvZGVkX291dHB1dDsgIC8vIGZsdXNoCisgICAgICBkZWxldGUgZ3pvdXQ7ICAvLyBmbHVzaAorICAgICAgaW50NjQgcG9zID0gb3V0cHV0LT5CeXRlQ291bnQoKTsKKyAgICAgIGRlbGV0ZSBvdXRwdXQ7CisgICAgICBvdXRwdXQgPSBuZXcgQXJyYXlPdXRwdXRTdHJlYW0oCisgICAgICAgICAgYnVmZmVyICsgcG9zLCBrQnVmZmVyU2l6ZSAtIHBvcywga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgZ3pvdXQgPSBuZXcgR3ppcE91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgY29kZWRfb3V0cHV0ID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKGd6b3V0KTsKKyAgICAgIG91dGxlbiA9IHN0cmxlbihzdHJCKSArIDE7CisgICAgICBjb2RlZF9vdXRwdXQtPldyaXRlVmFyaW50MzIob3V0bGVuKTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVSYXcoc3RyQiwgb3V0bGVuKTsKKyAgICAgIGRlbGV0ZSBjb2RlZF9vdXRwdXQ7ICAvLyBmbHVzaAorICAgICAgZGVsZXRlIGd6b3V0OyAgLy8gZmx1c2gKKyAgICAgIGludDY0IHNpemUgPSBwb3MgKyBvdXRwdXQtPkJ5dGVDb3VudCgpOworICAgICAgZGVsZXRlIG91dHB1dDsKKworICAgICAgQXJyYXlJbnB1dFN0cmVhbSogaW5wdXQgPQorICAgICAgICAgIG5ldyBBcnJheUlucHV0U3RyZWFtKGJ1ZmZlciwgc2l6ZSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgR3ppcElucHV0U3RyZWFtKiBnemluID0gbmV3IEd6aXBJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICBDb2RlZElucHV0U3RyZWFtKiBjb2RlZF9pbnB1dCA9IG5ldyBDb2RlZElucHV0U3RyZWFtKGd6aW4pOworICAgICAgdWludDMyIGluc2l6ZTsKKyAgICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LT5SZWFkVmFyaW50MzIoJmluc2l6ZSkpOworICAgICAgRVhQRUNUX0VRKHN0cmxlbihzdHJBKSArIDEsIGluc2l6ZSk7CisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFJhdyh0ZW1wX2J1ZmZlciwgaW5zaXplKSk7CisgICAgICBFWFBFQ1RfRVEoMCwgbWVtY21wKHRlbXBfYnVmZmVyLCBzdHJBLCBpbnNpemUpKQorICAgICAgICAgIDw8ICJzdHJBPSIgPDwgc3RyQSA8PCAiIGluPSIgPDwgdGVtcF9idWZmZXI7CisKKyAgICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LT5SZWFkVmFyaW50MzIoJmluc2l6ZSkpOworICAgICAgRVhQRUNUX0VRKHN0cmxlbihzdHJCKSArIDEsIGluc2l6ZSk7CisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFJhdyh0ZW1wX2J1ZmZlciwgaW5zaXplKSk7CisgICAgICBFWFBFQ1RfRVEoMCwgbWVtY21wKHRlbXBfYnVmZmVyLCBzdHJCLCBpbnNpemUpKQorICAgICAgICAgIDw8ICIgb3V0X2Jsb2NrX3NpemU9IiA8PCBrQmxvY2tTaXplc1tpXQorICAgICAgICAgIDw8ICIgaW5fYmxvY2tfc2l6ZT0iIDw8IGtCbG9ja1NpemVzW2pdCisgICAgICAgICAgPDwgIiBwb3M9IiA8PCBwb3MKKyAgICAgICAgICA8PCAiIHNpemU9IiA8PCBzaXplCisgICAgICAgICAgPDwgIiBzdHJCPSIgPDwgc3RyQiA8PCAiIGluPSIgPDwgdGVtcF9idWZmZXI7CisKKyAgICAgIGRlbGV0ZSBjb2RlZF9pbnB1dDsKKyAgICAgIGRlbGV0ZSBnemluOworICAgICAgZGVsZXRlIGlucHV0OworICAgIH0KKyAgfQorCisgIGRlbGV0ZSBbXSB0ZW1wX2J1ZmZlcjsKKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworVEVTVF9GKElvVGVzdCwgR3ppcElucHV0Qnl0ZUNvdW50QWZ0ZXJDbG9zZWQpIHsKKyAgc3RyaW5nIGdvbGRlbiA9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CisgIHN0cmluZyBjb21wcmVzc2VkID0gQ29tcHJlc3MoZ29sZGVuLCBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zKCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBBcnJheUlucHV0U3RyZWFtIGFycl9pbnB1dChjb21wcmVzc2VkLmRhdGEoKSwgY29tcHJlc3NlZC5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNbaV0pOworICAgIEd6aXBJbnB1dFN0cmVhbSBnel9pbnB1dCgmYXJyX2lucHV0KTsKKyAgICBjb25zdCB2b2lkKiBidWZmZXI7CisgICAgaW50IHNpemU7CisgICAgd2hpbGUgKGd6X2lucHV0Lk5leHQoJmJ1ZmZlciwgJnNpemUpKSB7CisgICAgICBFWFBFQ1RfTEUoZ3pfaW5wdXQuQnl0ZUNvdW50KCksIGdvbGRlbi5zaXplKCkpOworICAgIH0KKyAgICBFWFBFQ1RfRVEoZ29sZGVuLnNpemUoKSwgZ3pfaW5wdXQuQnl0ZUNvdW50KCkpOworICB9Cit9CisKK1RFU1RfRihJb1Rlc3QsIEd6aXBJbnB1dEJ5dGVDb3VudEFmdGVyQ2xvc2VkQ29uY2F0ZW5hdGVkU3RyZWFtcykgeworICBzdHJpbmcgZ29sZGVuMSA9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CisgIHN0cmluZyBnb2xkZW4yID0gInRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2ciOworICBjb25zdCBzaXplX3QgdG90YWxfc2l6ZSA9IGdvbGRlbjEuc2l6ZSgpICsgZ29sZGVuMi5zaXplKCk7CisgIHN0cmluZyBjb21wcmVzc2VkID0gQ29tcHJlc3MoZ29sZGVuMSwgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucygpKSArCisgICAgICAgICAgICAgICAgICAgICAgQ29tcHJlc3MoZ29sZGVuMiwgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucygpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgQXJyYXlJbnB1dFN0cmVhbSBhcnJfaW5wdXQoY29tcHJlc3NlZC5kYXRhKCksIGNvbXByZXNzZWQuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtCbG9ja1NpemVzW2ldKTsKKyAgICBHemlwSW5wdXRTdHJlYW0gZ3pfaW5wdXQoJmFycl9pbnB1dCk7CisgICAgY29uc3Qgdm9pZCogYnVmZmVyOworICAgIGludCBzaXplOworICAgIHdoaWxlIChnel9pbnB1dC5OZXh0KCZidWZmZXIsICZzaXplKSkgeworICAgICAgRVhQRUNUX0xFKGd6X2lucHV0LkJ5dGVDb3VudCgpLCB0b3RhbF9zaXplKTsKKyAgICB9CisgICAgRVhQRUNUX0VRKHRvdGFsX3NpemUsIGd6X2lucHV0LkJ5dGVDb3VudCgpKTsKKyAgfQorfQorI2VuZGlmCisKKy8vIFRoZXJlIGlzIG5vIHN0cmluZyBpbnB1dCwgb25seSBzdHJpbmcgb3V0cHV0LiAgQWxzbywgaXQgZG9lc24ndCBzdXBwb3J0CisvLyBleHBsaWNpdCBibG9jayBzaXplcy4gIFNvLCB3ZSdsbCBvbmx5IHJ1biBvbmUgdGVzdCBhbmQgd2UnbGwgdXNlCisvLyBBcnJheUlucHV0IHRvIHJlYWQgYmFjayB0aGUgcmVzdWx0cy4KK1RFU1RfRihJb1Rlc3QsIFN0cmluZ0lvKSB7CisgIHN0cmluZyBzdHI7CisgIHsKKyAgICBTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0KCZzdHIpOworICAgIFdyaXRlU3R1ZmYoJm91dHB1dCk7CisgIH0KKyAgeworICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoc3RyLmRhdGEoKSwgc3RyLnNpemUoKSk7CisgICAgUmVhZFN0dWZmKCZpbnB1dCk7CisgIH0KK30KKworCisvLyBUbyB0ZXN0IGZpbGVzLCB3ZSBjcmVhdGUgYSB0ZW1wb3JhcnkgZmlsZSwgd3JpdGUsIHJlYWQsIHRydW5jYXRlLCByZXBlYXQuCitURVNUX0YoSW9UZXN0LCBGaWxlSW8pIHsKKyAgc3RyaW5nIGZpbGVuYW1lID0gVGVzdFRlbXBEaXIoKSArICIvemVyb19jb3B5X3N0cmVhbV90ZXN0X2ZpbGUiOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCbG9ja1NpemVDb3VudDsgaisrKSB7CisgICAgICAvLyBNYWtlIGEgdGVtcG9yYXJ5IGZpbGUuCisgICAgICBpbnQgZmlsZSA9CisgICAgICAgIG9wZW4oZmlsZW5hbWUuY19zdHIoKSwgT19SRFdSIHwgT19DUkVBVCB8IE9fVFJVTkMgfCBPX0JJTkFSWSwgMDc3Nyk7CisgICAgICBBU1NFUlRfR0UoZmlsZSwgMCk7CisKKyAgICAgIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXRwdXQoZmlsZSwga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgICBXcml0ZVN0dWZmKCZvdXRwdXQpOworICAgICAgICBFWFBFQ1RfRVEoMCwgb3V0cHV0LkdldEVycm5vKCkpOworICAgICAgfQorCisgICAgICAvLyBSZXdpbmQuCisgICAgICBBU1NFUlRfTkUobHNlZWsoZmlsZSwgMCwgU0VFS19TRVQpLCAob2ZmX3QpLTEpOworCisgICAgICB7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBpbnB1dChmaWxlLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgIFJlYWRTdHVmZigmaW5wdXQpOworICAgICAgICBFWFBFQ1RfRVEoMCwgaW5wdXQuR2V0RXJybm8oKSk7CisgICAgICB9CisKKyAgICAgIGNsb3NlKGZpbGUpOworICAgIH0KKyAgfQorfQorCisjaWYgSEFWRV9aTElCCitURVNUX0YoSW9UZXN0LCBHemlwRmlsZUlvKSB7CisgIHN0cmluZyBmaWxlbmFtZSA9IFRlc3RUZW1wRGlyKCkgKyAiL3plcm9fY29weV9zdHJlYW1fdGVzdF9maWxlIjsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgLy8gTWFrZSBhIHRlbXBvcmFyeSBmaWxlLgorICAgICAgaW50IGZpbGUgPQorICAgICAgICBvcGVuKGZpbGVuYW1lLmNfc3RyKCksIE9fUkRXUiB8IE9fQ1JFQVQgfCBPX1RSVU5DIHwgT19CSU5BUlksIDA3NzcpOworICAgICAgQVNTRVJUX0dFKGZpbGUsIDApOworICAgICAgeworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dHB1dChmaWxlLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICAgIEd6aXBPdXRwdXRTdHJlYW0gZ3pvdXQoJm91dHB1dCk7CisgICAgICAgIFdyaXRlU3R1ZmZMYXJnZSgmZ3pvdXQpOworICAgICAgICBnem91dC5DbG9zZSgpOworICAgICAgICBvdXRwdXQuRmx1c2goKTsKKyAgICAgICAgRVhQRUNUX0VRKDAsIG91dHB1dC5HZXRFcnJubygpKTsKKyAgICAgIH0KKworICAgICAgLy8gUmV3aW5kLgorICAgICAgQVNTRVJUX05FKGxzZWVrKGZpbGUsIDAsIFNFRUtfU0VUKSwgKG9mZl90KS0xKTsKKworICAgICAgeworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gaW5wdXQoZmlsZSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICBHemlwSW5wdXRTdHJlYW0gZ3ppbigmaW5wdXQpOworICAgICAgICBSZWFkU3R1ZmZMYXJnZSgmZ3ppbik7CisgICAgICAgIEVYUEVDVF9FUSgwLCBpbnB1dC5HZXRFcnJubygpKTsKKyAgICAgIH0KKworICAgICAgY2xvc2UoZmlsZSk7CisgICAgfQorICB9Cit9CisjZW5kaWYKKworLy8gTVNWQyByYWlzZXMgdmFyaW91cyBkZWJ1Z2dpbmcgZXhjZXB0aW9ucyBpZiB3ZSB0cnkgdG8gdXNlIGEgZmlsZQorLy8gZGVzY3JpcHRvciBvZiAtMSwgZGVmZWF0aW5nIG91ciB0ZXN0cyBiZWxvdy4gIFRoaXMgY2xhc3Mgd2lsbCBkaXNhYmxlCisvLyB0aGVzZSBkZWJ1ZyBhc3NlcnRpb25zIHdoaWxlIGluIHNjb3BlLgorY2xhc3MgTXN2Y0RlYnVnRGlzYWJsZXIgeworIHB1YmxpYzoKKyNpZiBkZWZpbmVkKF9NU0NfVkVSKSAmJiBfTVNDX1ZFUiA+PSAxNDAwCisgIE1zdmNEZWJ1Z0Rpc2FibGVyKCkgeworICAgIG9sZF9oYW5kbGVyXyA9IF9zZXRfaW52YWxpZF9wYXJhbWV0ZXJfaGFuZGxlcihNeUhhbmRsZXIpOworICAgIG9sZF9tb2RlXyA9IF9DcnRTZXRSZXBvcnRNb2RlKF9DUlRfQVNTRVJULCAwKTsKKyAgfQorICB+TXN2Y0RlYnVnRGlzYWJsZXIoKSB7CisgICAgb2xkX2hhbmRsZXJfID0gX3NldF9pbnZhbGlkX3BhcmFtZXRlcl9oYW5kbGVyKG9sZF9oYW5kbGVyXyk7CisgICAgb2xkX21vZGVfID0gX0NydFNldFJlcG9ydE1vZGUoX0NSVF9BU1NFUlQsIG9sZF9tb2RlXyk7CisgIH0KKworICBzdGF0aWMgdm9pZCBNeUhhbmRsZXIoY29uc3Qgd2NoYXJfdCAqZXhwciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdjaGFyX3QgKmZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB3Y2hhcl90ICpmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICAgICB1aW50cHRyX3QgcFJlc2VydmVkKSB7CisgICAgLy8gZG8gbm90aGluZworICB9CisKKyAgX2ludmFsaWRfcGFyYW1ldGVyX2hhbmRsZXIgb2xkX2hhbmRsZXJfOworICBpbnQgb2xkX21vZGVfOworI2Vsc2UKKyAgLy8gRHVtbXkgY29uc3RydWN0b3IgYW5kIGRlc3RydWN0b3IgdG8gZW5zdXJlIHRoYXQgR0NDIGRvZXNuJ3QgY29tcGxhaW4KKyAgLy8gdGhhdCBkZWJ1Z19kaXNhYmxlciBpcyBhbiB1bnVzZWQgdmFyaWFibGUuCisgIE1zdmNEZWJ1Z0Rpc2FibGVyKCkge30KKyAgfk1zdmNEZWJ1Z0Rpc2FibGVyKCkge30KKyNlbmRpZgorfTsKKworLy8gVGVzdCB0aGF0IEZpbGVJbnB1dFN0cmVhbXMgcmVwb3J0IGVycm9ycyBjb3JyZWN0bHkuCitURVNUX0YoSW9UZXN0LCBGaWxlUmVhZEVycm9yKSB7CisgIE1zdmNEZWJ1Z0Rpc2FibGVyIGRlYnVnX2Rpc2FibGVyOworCisgIC8vIC0xID0gaW52YWxpZCBmaWxlIGRlc2NyaXB0b3IuCisgIEZpbGVJbnB1dFN0cmVhbSBpbnB1dCgtMSk7CisKKyAgY29uc3Qgdm9pZCogYnVmZmVyOworICBpbnQgc2l6ZTsKKyAgRVhQRUNUX0ZBTFNFKGlucHV0Lk5leHQoJmJ1ZmZlciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKEVCQURGLCBpbnB1dC5HZXRFcnJubygpKTsKK30KKworLy8gVGVzdCB0aGF0IEZpbGVPdXRwdXRTdHJlYW1zIHJlcG9ydCBlcnJvcnMgY29ycmVjdGx5LgorVEVTVF9GKElvVGVzdCwgRmlsZVdyaXRlRXJyb3IpIHsKKyAgTXN2Y0RlYnVnRGlzYWJsZXIgZGVidWdfZGlzYWJsZXI7CisKKyAgLy8gLTEgPSBpbnZhbGlkIGZpbGUgZGVzY3JpcHRvci4KKyAgRmlsZU91dHB1dFN0cmVhbSBpbnB1dCgtMSk7CisKKyAgdm9pZCogYnVmZmVyOworICBpbnQgc2l6ZTsKKworICAvLyBUaGUgZmlyc3QgY2FsbCB0byBOZXh0KCkgc3VjY2VlZHMgYmVjYXVzZSBpdCBkb2Vzbid0IGhhdmUgYW55dGhpbmcgdG8KKyAgLy8gd3JpdGUgeWV0LgorICBFWFBFQ1RfVFJVRShpbnB1dC5OZXh0KCZidWZmZXIsICZzaXplKSk7CisKKyAgLy8gU2Vjb25kIGNhbGwgZmFpbHMuCisgIEVYUEVDVF9GQUxTRShpbnB1dC5OZXh0KCZidWZmZXIsICZzaXplKSk7CisKKyAgRVhQRUNUX0VRKEVCQURGLCBpbnB1dC5HZXRFcnJubygpKTsKK30KKworLy8gUGlwZXMgYXJlIG5vdCBzZWVrYWJsZSwgc28gRmlsZXtJbnB1dCxPdXRwdXR9U3RyZWFtIGVuZHMgdXAgZG9pbmcgc29tZQorLy8gZGlmZmVyZW50IHRoaW5ncyB0byBoYW5kbGUgdGhlbS4gIFdlJ2xsIHRlc3QgYnkgd3JpdGluZyB0byBhIHBpcGUgYW5kCisvLyByZWFkaW5nIGJhY2sgZnJvbSBpdC4KK1RFU1RfRihJb1Rlc3QsIFBpcGVJbykgeworICBpbnQgZmlsZXNbMl07CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIC8vIE5lZWQgdG8gY3JlYXRlIGEgbmV3IHBpcGUgZWFjaCB0aW1lIGJlY2F1c2UgUmVhZFN0dWZmKCkgZXhwZWN0cworICAgICAgLy8gdG8gc2VlIEVPRiBhdCB0aGUgZW5kLgorICAgICAgQVNTRVJUX0VRKHBpcGUoZmlsZXMpLCAwKTsKKworICAgICAgeworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dHB1dChmaWxlc1sxXSwga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgICBXcml0ZVN0dWZmKCZvdXRwdXQpOworICAgICAgICBFWFBFQ1RfRVEoMCwgb3V0cHV0LkdldEVycm5vKCkpOworICAgICAgfQorICAgICAgY2xvc2UoZmlsZXNbMV0pOyAgLy8gU2VuZCBFT0YuCisKKyAgICAgIHsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGlucHV0KGZpbGVzWzBdLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgIFJlYWRTdHVmZigmaW5wdXQpOworICAgICAgICBFWFBFQ1RfRVEoMCwgaW5wdXQuR2V0RXJybm8oKSk7CisgICAgICB9CisgICAgICBjbG9zZShmaWxlc1swXSk7CisgICAgfQorICB9Cit9CisKKy8vIFRlc3QgdXNpbmcgQysrIGlvc3RyZWFtcy4KK1RFU1RfRihJb1Rlc3QsIElvc3RyZWFtSW8pIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIHsKKyAgICAgICAgc3RyaW5nc3RyZWFtIHN0cmVhbTsKKworICAgICAgICB7CisgICAgICAgICAgT3N0cmVhbU91dHB1dFN0cmVhbSBvdXRwdXQoJnN0cmVhbSwga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgICAgIFdyaXRlU3R1ZmYoJm91dHB1dCk7CisgICAgICAgICAgRVhQRUNUX0ZBTFNFKHN0cmVhbS5mYWlsKCkpOworICAgICAgICB9CisKKyAgICAgICAgeworICAgICAgICAgIElzdHJlYW1JbnB1dFN0cmVhbSBpbnB1dCgmc3RyZWFtLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgICAgUmVhZFN0dWZmKCZpbnB1dCk7CisgICAgICAgICAgRVhQRUNUX1RSVUUoc3RyZWFtLmVvZigpKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICB7CisgICAgICAgIHN0cmluZ3N0cmVhbSBzdHJlYW07CisKKyAgICAgICAgeworICAgICAgICAgIE9zdHJlYW1PdXRwdXRTdHJlYW0gb3V0cHV0KCZzdHJlYW0sIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgICBXcml0ZVN0dWZmTGFyZ2UoJm91dHB1dCk7CisgICAgICAgICAgRVhQRUNUX0ZBTFNFKHN0cmVhbS5mYWlsKCkpOworICAgICAgICB9CisKKyAgICAgICAgeworICAgICAgICAgIElzdHJlYW1JbnB1dFN0cmVhbSBpbnB1dCgmc3RyZWFtLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgICAgUmVhZFN0dWZmTGFyZ2UoJmlucHV0KTsKKyAgICAgICAgICBFWFBFQ1RfVFJVRShzdHJlYW0uZW9mKCkpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKKy8vIFRvIHRlc3QgQ29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtLCB3ZSBjcmVhdGUgc2V2ZXJhbCBBcnJheUlucHV0U3RyZWFtcworLy8gY292ZXJpbmcgYSBidWZmZXIgYW5kIHRoZW4gY29uY2F0ZW5hdGUgdGhlbS4KK1RFU1RfRihJb1Rlc3QsIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSkgeworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyNTY7CisgIHVpbnQ4IGJ1ZmZlcltrQnVmZmVyU2l6ZV07CisKKyAgLy8gRmlsbCB0aGUgYnVmZmVyLgorICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSk7CisgIFdyaXRlU3R1ZmYoJm91dHB1dCk7CisKKyAgLy8gTm93IHNwbGl0IGl0IHVwIGludG8gbXVsdGlwbGUgc3RyZWFtcyBvZiB2YXJ5aW5nIHNpemVzLgorICBBU1NFUlRfRVEoNjgsIG91dHB1dC5CeXRlQ291bnQoKSk7ICAvLyBUZXN0IGRlcGVuZHMgb24gdGhpcy4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDEoYnVmZmVyICAgICAsIDEyKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDIoYnVmZmVyICsgMTIsICA3KTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDMoYnVmZmVyICsgMTksICA2KTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDQoYnVmZmVyICsgMjUsIDE1KTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDUoYnVmZmVyICsgNDAsICAwKTsKKyAgLy8gTm90ZTogIFdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIGhhdmUgYSBzdHJlYW0gYm91bmRhcnkgc29tZXdoZXJlIGJldHdlZW4KKyAgLy8gYnl0ZXMgNDIgYW5kIDYyLCB3aGljaCBpcyB0aGUgcmFuZ2UgdGhhdCBpdCBTa2lwKCllZCBieSBSZWFkU3R1ZmYoKS4gIFRoaXMKKyAgLy8gdGVzdHMgdGhhdCBhIGJ1ZyB0aGF0IGV4aXN0ZWQgaW4gdGhlIG9yaWdpbmFsIGNvZGUgZm9yIFNraXAoKSBpcyBmaXhlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDYoYnVmZmVyICsgNDAsIDEwKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dDcoYnVmZmVyICsgNTAsIDE4KTsgIC8vIFRvdGFsID0gNjggYnl0ZXMuCisKKyAgWmVyb0NvcHlJbnB1dFN0cmVhbSogc3RyZWFtc1tdID0KKyAgICB7JmlucHV0MSwgJmlucHV0MiwgJmlucHV0MywgJmlucHV0NCwgJmlucHV0NSwgJmlucHV0NiwgJmlucHV0N307CisKKyAgLy8gQ3JlYXRlIHRoZSBjb25jYXRlbmF0aW5nIHN0cmVhbSBhbmQgcmVhZC4KKyAgQ29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtIGlucHV0KHN0cmVhbXMsIEdPT0dMRV9BUlJBWVNJWkUoc3RyZWFtcykpOworICBSZWFkU3R1ZmYoJmlucHV0KTsKK30KKworLy8gVG8gdGVzdCBMaW1pdGluZ0lucHV0U3RyZWFtLCB3ZSB3cml0ZSBvdXIgZ29sZGVuIHRleHQgdG8gYSBidWZmZXIsIHRoZW4KKy8vIGNyZWF0ZSBhbiBBcnJheUlucHV0U3RyZWFtIHRoYXQgY29udGFpbnMgdGhlIHdob2xlIGJ1ZmZlciAobm90IGp1c3QgdGhlCisvLyBieXRlcyB3cml0dGVuKSwgdGhlbiB1c2UgYSBMaW1pdGluZ0lucHV0U3RyZWFtIHRvIGxpbWl0IGl0IGp1c3QgdG8gdGhlCisvLyBieXRlcyB3cml0dGVuLgorVEVTVF9GKElvVGVzdCwgTGltaXRpbmdJbnB1dFN0cmVhbSkgeworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyNTY7CisgIHVpbnQ4IGJ1ZmZlcltrQnVmZmVyU2l6ZV07CisKKyAgLy8gRmlsbCB0aGUgYnVmZmVyLgorICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSk7CisgIFdyaXRlU3R1ZmYoJm91dHB1dCk7CisKKyAgLy8gU2V0IHVwIGlucHV0LgorICBBcnJheUlucHV0U3RyZWFtIGFycmF5X2lucHV0KGJ1ZmZlciwga0J1ZmZlclNpemUpOworICBMaW1pdGluZ0lucHV0U3RyZWFtIGlucHV0KCZhcnJheV9pbnB1dCwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKworICBSZWFkU3R1ZmYoJmlucHV0KTsKK30KKworLy8gQ2hlY2tzIHRoYXQgQnl0ZUNvdW50IHdvcmtzIGNvcnJlY3RseSBmb3IgTGltaXRpbmdJbnB1dFN0cmVhbXMgd2hlcmUgdGhlCisvLyB1bmRlcmx5aW5nIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIHJlYWQuCitURVNUX0YoSW9UZXN0LCBMaW1pdGluZ0lucHV0U3RyZWFtQnl0ZUNvdW50KSB7CisgIGNvbnN0IGludCBrSGFsZkJ1ZmZlclNpemUgPSAxMjg7CisgIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IGtIYWxmQnVmZmVyU2l6ZSAqIDI7CisgIHVpbnQ4IGJ1ZmZlcltrQnVmZmVyU2l6ZV07CisKKyAgLy8gU2V0IHVwIGlucHV0LiBPbmx5IGFsbG93IGhhbGYgdG8gYmUgcmVhZCBhdCBvbmNlLgorICBBcnJheUlucHV0U3RyZWFtIGFycmF5X2lucHV0KGJ1ZmZlciwga0J1ZmZlclNpemUsIGtIYWxmQnVmZmVyU2l6ZSk7CisgIGNvbnN0IHZvaWQqIGRhdGE7CisgIGludCBzaXplOworICBFWFBFQ1RfVFJVRShhcnJheV9pbnB1dC5OZXh0KCZkYXRhLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoa0hhbGZCdWZmZXJTaXplLCBhcnJheV9pbnB1dC5CeXRlQ291bnQoKSk7CisgIC8vIGtIYWxmQnVmZmVyU2l6ZSAtIDEgdG8gdGVzdCBsaW1pdGluZyBsb2dpYyBhcyB3ZWxsLgorICBMaW1pdGluZ0lucHV0U3RyZWFtIGlucHV0KCZhcnJheV9pbnB1dCwga0hhbGZCdWZmZXJTaXplIC0gMSk7CisgIEVYUEVDVF9FUSgwLCBpbnB1dC5CeXRlQ291bnQoKSk7CisgIEVYUEVDVF9UUlVFKGlucHV0Lk5leHQoJmRhdGEsICZzaXplKSk7CisgIEVYUEVDVF9FUShrSGFsZkJ1ZmZlclNpemUgLSAxICwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCisvLyBDaGVjayB0aGF0IGEgemVyby1zaXplIGFycmF5IGRvZXNuJ3QgY29uZnVzZSB0aGUgY29kZS4KK1RFU1QoWmVyb1NpemVBcnJheSwgSW5wdXQpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChOVUxMLCAwKTsKKyAgY29uc3Qgdm9pZCogZGF0YTsKKyAgaW50IHNpemU7CisgIEVYUEVDVF9GQUxTRShpbnB1dC5OZXh0KCZkYXRhLCAmc2l6ZSkpOworfQorCitURVNUKFplcm9TaXplQXJyYXksIE91dHB1dCkgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoTlVMTCwgMCk7CisgIHZvaWQqIGRhdGE7CisgIGludCBzaXplOworICBFWFBFQ1RfRkFMU0Uob3V0cHV0Lk5leHQoJmRhdGEsICZzaXplKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbGl0ZV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbGl0ZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWEyMTAwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9saXRlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMzUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGlvc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWxfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisKK3VzaW5nIG5hbWVzcGFjZSBzdGQ7CisKK25hbWVzcGFjZSB7CisvLyBIZWxwZXIgbWV0aG9kcyB0byB0ZXN0IHBhcnNpbmcgbWVyZ2UgYmVoYXZpb3IuCit2b2lkIEV4cGVjdE1lc3NhZ2VNZXJnZWQoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUmIG1lc3NhZ2UpIHsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIoKSA9PSAzKTsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2Uub3B0aW9uYWxfaW50NjQoKSA9PSAyKTsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nKCkgPT0gImhlbGxvIik7Cit9CisKK3ZvaWQgQXNzaWduUGFyc2luZ01lcmdlTWVzc2FnZXMoCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUqIG1zZzEsCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUqIG1zZzIsCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUqIG1zZzMpIHsKKyAgbXNnMS0+c2V0X29wdGlvbmFsX2ludDMyKDEpOworICBtc2cyLT5zZXRfb3B0aW9uYWxfaW50NjQoMik7CisgIG1zZzMtPnNldF9vcHRpb25hbF9pbnQzMigzKTsKKyAgbXNnMy0+c2V0X29wdGlvbmFsX3N0cmluZygiaGVsbG8iKTsKK30KKwordm9pZCBTZXRBbGxUeXBlc0luRW1wdHlNZXNzYWdlVW5rbm93bkZpZWxkcygKKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUqIGVtcHR5X21lc3NhZ2UpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUgbWVzc2FnZTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBzdHJpbmcgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgZW1wdHlfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKGRhdGEpOworfQorCit2b2lkIFNldFNvbWVUeXBlc0luRW1wdHlNZXNzYWdlVW5rbm93bkZpZWxkcygKKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUqIGVtcHR5X21lc3NhZ2UpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUgbWVzc2FnZTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoMTAxKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50NjQoMTAyKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfdWludDMyKDEwMyk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3VpbnQ2NCgxMDQpOworICBzdHJpbmcgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgZW1wdHlfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKGRhdGEpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkgeworICBzdHJpbmcgZGF0YSwgZGF0YTIsIHBhY2tlZF9kYXRhOworCisgIHsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSBtZXNzYWdlLCBtZXNzYWdlMiwgbWVzc2FnZTM7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisgICAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZSk7CisgICAgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBtZXNzYWdlMy5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UzKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6Ok1vZGlmeVJlcGVhdGVkRmllbGRzKCZtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFJlcGVhdGVkRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7CisgICAgbWVzc2FnZS5DbGVhcigpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSBtZXNzYWdlLCBtZXNzYWdlMiwgbWVzc2FnZTM7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlKTsKKyAgICBzdHJpbmcgZXh0ZW5zaW9uc19kYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIG1lc3NhZ2UzLlBhcnNlRnJvbVN0cmluZyhleHRlbnNpb25zX2RhdGEpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMyk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpNb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQobWVzc2FnZSk7CisgICAgbWVzc2FnZS5DbGVhcigpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyLCBtZXNzYWdlMzsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZENsZWFyKG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6U2V0UGFja2VkRmllbGRzKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlKTsKKyAgICBwYWNrZWRfZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBtZXNzYWdlMy5QYXJzZUZyb21TdHJpbmcocGFja2VkX2RhdGEpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChtZXNzYWdlMyk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpNb2RpZnlQYWNrZWRGaWVsZHMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7CisgICAgbWVzc2FnZS5DbGVhcigpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkQ2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSBtZXNzYWdlLCBtZXNzYWdlMiwgbWVzc2FnZTM7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRQYWNrZWRFeHRlbnNpb25zKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlKTsKKyAgICBzdHJpbmcgcGFja2VkX2V4dGVuc2lvbnNfZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBHT09HTEVfQ0hFQ0socGFja2VkX2V4dGVuc2lvbnNfZGF0YSA9PSBwYWNrZWRfZGF0YSk7CisgICAgbWVzc2FnZTMuUGFyc2VGcm9tU3RyaW5nKHBhY2tlZF9leHRlbnNpb25zX2RhdGEpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc1NldChtZXNzYWdlMyk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpNb2RpZnlQYWNrZWRFeHRlbnNpb25zKCZtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNNb2RpZmllZChtZXNzYWdlKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCB0aGF0IGlmIGFuIG9wdGlvbmFsIG9yIHJlcXVpcmVkIG1lc3NhZ2UvZ3JvdXAgZmllbGQgYXBwZWFycyBtdWx0aXBsZQorICAgIC8vIHRpbWVzIGluIHRoZSBpbnB1dCwgdGhleSBuZWVkIHRvIGJlIG1lcmdlZC4KKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdFBhcnNpbmdNZXJnZUxpdGU6OlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIGdlbmVyYXRvcjsKKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSogbXNnMTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSogbXNnMjsKKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSogbXNnMzsKKworI2RlZmluZSBBU1NJR05fUkVQRUFURURfRklFTEQoRklFTEQpICAgICAgICAgICAgICAgIFwKKyAgbXNnMSA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpOyAgICAgICAgICAgICAgICAgICBcCisgIG1zZzIgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKTsgICAgICAgICAgICAgICAgICAgXAorICBtc2czID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCk7ICAgICAgICAgICAgICAgICAgIFwKKyAgQXNzaWduUGFyc2luZ01lcmdlTWVzc2FnZXMobXNnMSwgbXNnMiwgbXNnMykKKworICAgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChmaWVsZDEpOworICAgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChmaWVsZDIpOworICAgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChmaWVsZDMpOworICAgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChleHQxKTsKKyAgICBBU1NJR05fUkVQRUFURURfRklFTEQoZXh0Mik7CisKKyN1bmRlZiBBU1NJR05fUkVQRUFURURfRklFTEQKKyNkZWZpbmUgQVNTSUdOX1JFUEVBVEVEX0dST1VQKEZJRUxEKSAgICAgICAgICAgICAgICBcCisgIG1zZzEgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKS0+bXV0YWJsZV9maWVsZDEoKTsgXAorICBtc2cyID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCktPm11dGFibGVfZmllbGQxKCk7IFwKKyAgbXNnMyA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpLT5tdXRhYmxlX2ZpZWxkMSgpOyBcCisgIEFzc2lnblBhcnNpbmdNZXJnZU1lc3NhZ2VzKG1zZzEsIG1zZzIsIG1zZzMpCisKKyAgICBBU1NJR05fUkVQRUFURURfR1JPVVAoZ3JvdXAxKTsKKyAgICBBU1NJR05fUkVQRUFURURfR1JPVVAoZ3JvdXAyKTsKKworI3VuZGVmIEFTU0lHTl9SRVBFQVRFRF9HUk9VUAorCisgICAgc3RyaW5nIGJ1ZmZlcjsKKyAgICBnZW5lcmF0b3IuU2VyaWFsaXplVG9TdHJpbmcoJmJ1ZmZlcik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RQYXJzaW5nTWVyZ2VMaXRlIHBhcnNpbmdfbWVyZ2U7CisgICAgcGFyc2luZ19tZXJnZS5QYXJzZUZyb21TdHJpbmcoYnVmZmVyKTsKKworICAgIC8vIFJlcXVpcmVkIGFuZCBvcHRpb25hbCBmaWVsZHMgc2hvdWxkIGJlIG1lcmdlZC4KKyAgICBFeHBlY3RNZXNzYWdlTWVyZ2VkKHBhcnNpbmdfbWVyZ2UucmVxdWlyZWRfYWxsX3R5cGVzKCkpOworICAgIEV4cGVjdE1lc3NhZ2VNZXJnZWQocGFyc2luZ19tZXJnZS5vcHRpb25hbF9hbGxfdHlwZXMoKSk7CisgICAgRXhwZWN0TWVzc2FnZU1lcmdlZCgKKyAgICAgICAgcGFyc2luZ19tZXJnZS5vcHRpb25hbGdyb3VwKCkub3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzKCkpOworICAgIEV4cGVjdE1lc3NhZ2VNZXJnZWQocGFyc2luZ19tZXJnZS5HZXRFeHRlbnNpb24oCisgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlTGl0ZTo6b3B0aW9uYWxfZXh0KSk7CisKKyAgICAvLyBSZXBlYXRlZCBmaWVsZHMgc2hvdWxkIG5vdCBiZSBtZXJnZWQuCisgICAgR09PR0xFX0NIRUNLKHBhcnNpbmdfbWVyZ2UucmVwZWF0ZWRfYWxsX3R5cGVzX3NpemUoKSA9PSAzKTsKKyAgICBHT09HTEVfQ0hFQ0socGFyc2luZ19tZXJnZS5yZXBlYXRlZGdyb3VwX3NpemUoKSA9PSAzKTsKKyAgICBHT09HTEVfQ0hFQ0socGFyc2luZ19tZXJnZS5FeHRlbnNpb25TaXplKAorICAgICAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdFBhcnNpbmdNZXJnZUxpdGU6OnJlcGVhdGVkX2V4dCkgPT0gMyk7CisgIH0KKworICAvLyBUZXN0IHVua25vd24gZmllbGRzIHN1cHBvcnQgZm9yIGxpdGUgbWVzc2FnZXMuCisgIHsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSBtZXNzYWdlLCBtZXNzYWdlMjsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlfbWVzc2FnZTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdENsZWFyKG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgICBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGVtcHR5X21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGRhdGEuY2xlYXIoKTsKKyAgICBkYXRhID0gZW1wdHlfbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBkYXRhID0gbWVzc2FnZTIuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisgICAgbWVzc2FnZS5DbGVhcigpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSBtZXNzYWdlLCBtZXNzYWdlMjsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlfbWVzc2FnZTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICAgIGRhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZW1wdHlfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZGF0YS5jbGVhcigpOworICAgIGRhdGEgPSBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgbWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGRhdGEgPSBtZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7CisgICAgbWVzc2FnZS5DbGVhcigpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkQ2xlYXIobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRQYWNrZWRGaWVsZHMoJm1lc3NhZ2UpOworICAgIGRhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZW1wdHlfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZGF0YS5jbGVhcigpOworICAgIGRhdGEgPSBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgbWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGRhdGEgPSBtZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6U2V0UGFja2VkRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgICAgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBkYXRhLmNsZWFyKCk7CisgICAgZGF0YSA9IGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZGF0YSA9IG1lc3NhZ2UyLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBVbmtub3duIGZpZWxkcyBzd2FwCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5X21lc3NhZ2UsIGVtcHR5X21lc3NhZ2UyOworICAgIFNldEFsbFR5cGVzSW5FbXB0eU1lc3NhZ2VVbmtub3duRmllbGRzKCZlbXB0eV9tZXNzYWdlKTsKKyAgICBTZXRTb21lVHlwZXNJbkVtcHR5TWVzc2FnZVVua25vd25GaWVsZHMoJmVtcHR5X21lc3NhZ2UyKTsKKyAgICBkYXRhID0gZW1wdHlfbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGRhdGEyID0gZW1wdHlfbWVzc2FnZTIuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlLlN3YXAoJmVtcHR5X21lc3NhZ2UyKTsKKyAgICBHT09HTEVfQ0hFQ0tfRVEoZGF0YSwgZW1wdHlfbWVzc2FnZTIuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgICAgR09PR0xFX0NIRUNLX0VRKGRhdGEyLCBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgdW5rbm93biBmaWVsZHMgc3dhcCB3aXRoIHNlbGYKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlfbWVzc2FnZTsKKyAgICBTZXRBbGxUeXBlc0luRW1wdHlNZXNzYWdlVW5rbm93bkZpZWxkcygmZW1wdHlfbWVzc2FnZSk7CisgICAgZGF0YSA9IGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlLlN3YXAoJmVtcHR5X21lc3NhZ2UpOworICAgIEdPT0dMRV9DSEVDS19FUShkYXRhLCBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgTWVyZ2VGcm9tIHdpdGggdW5rbm93biBmaWVsZHMKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSBtZXNzYWdlLCBtZXNzYWdlMjsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlfbWVzc2FnZSwgZW1wdHlfbWVzc2FnZTI7CisgICAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoMTAxKTsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9pbnQzMigyMDEpOworICAgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX25lc3RlZF9lbnVtKGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVopOworICAgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9pbnQ2NCgxMDIpOworICAgIG1lc3NhZ2UyLmFkZF9yZXBlYXRlZF9pbnQ2NCgyMDIpOworICAgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9mb3JlaWduX2VudW0oZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVopOworCisgICAgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBkYXRhID0gbWVzc2FnZTIuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgbWVzc2FnZS5NZXJnZUZyb20obWVzc2FnZTIpOworICAgIGVtcHR5X21lc3NhZ2UuTWVyZ2VGcm9tKGVtcHR5X21lc3NhZ2UyKTsKKworICAgIGRhdGEgPSBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgbWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIC8vIFdlIGRvIG5vdCBjb21wYXJlIHRoZSBzZXJpYWxpemVkIG91dHB1dCBvZiBhIG5vcm1hbCBtZXNzYWdlIGFuZCBhIGxpdGUKKyAgICAvLyBtZXNzYWdlIGJlY2F1c2UgdGhlIG9yZGVyIG9mIGZpZWxkcyBkbyBub3QgbWF0Y2guIFdlIGNvbnZlcnQgbGl0ZSBtZXNzYWdlCisgICAgLy8gYmFjayBpbnRvIG5vcm1hbCBtZXNzYWdlLCB0aGVuIGNvbXBhcmUuCisgICAgR09PR0xFX0NIRUNLX0VRKG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKSwgbWVzc2FnZTIuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCB1bmtub3duIGVudW0gdmFsdWUKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSBtZXNzYWdlOworICAgIHN0cmluZyBidWZmZXI7CisgICAgeworICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlN0cmluZ091dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZidWZmZXIpOworICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dHB1dCgmb3V0cHV0X3N0cmVhbSk7CisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlVGFnKAorICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjprT3B0aW9uYWxOZXN0ZWRFbnVtRmllbGROdW1iZXIsCisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQsICZjb2RlZF9vdXRwdXQpOworICAgICAgY29kZWRfb3V0cHV0LldyaXRlVmFyaW50MzIoMTApOworICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZygKKyAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6a1JlcGVhdGVkTmVzdGVkRW51bUZpZWxkTnVtYmVyLAorICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAmY29kZWRfb3V0cHV0KTsKKyAgICAgIGNvZGVkX291dHB1dC5Xcml0ZVZhcmludDMyKDIwKTsKKyAgICB9CisgICAgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoYnVmZmVyKTsKKyAgICBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIEdPT0dMRV9DSEVDS19FUShkYXRhLCBidWZmZXIpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgQ2xlYXIgd2l0aCB1bmtub3duIGZpZWxkcworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlOworICAgIFNldEFsbFR5cGVzSW5FbXB0eU1lc3NhZ2VVbmtub3duRmllbGRzKCZlbXB0eV9tZXNzYWdlKTsKKyAgICBlbXB0eV9tZXNzYWdlLkNsZWFyKCk7CisgICAgR09PR0xFX0NIRUNLX0VRKDAsIGVtcHR5X21lc3NhZ2UudW5rbm93bl9maWVsZHMoKS5zaXplKCkpOworICB9CisKKyAgc3RkOjpjb3V0IDw8ICJQQVNTIiA8PCBzdGQ6OmVuZGw7CisgIHJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXAuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTU2YWYzZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwLmgKQEAgLTAsMCArMSw0MzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQVBfSF9fCisKKyNpbmNsdWRlIDxpdGVyYXRvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CitjbGFzcyBNYXA7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbnVtPiBzdHJ1Y3QgaXNfcHJvdG9fZW51bTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitjbGFzcyBNYXBGaWVsZExpdGU7Cit9CisKKy8vIFRoaXMgaXMgdGhlIGNsYXNzIGZvciBnb29nbGU6OnByb3RvYnVmOjpNYXAncyBpbnRlcm5hbCB2YWx1ZV90eXBlLiBJbnN0ZWFkIG9mIHVzaW5nCisvLyBzdGQ6OnBhaXIgYXMgdmFsdWVfdHlwZSwgd2UgdXNlIHRoaXMgY2xhc3Mgd2hpY2ggcHJvdmlkZXMgdXMgbW9yZSBjb250cm9sIG9mCisvLyBpdHMgcHJvY2VzcyBvZiBjb25zdHJ1Y3Rpb24gYW5kIGRlc3RydWN0aW9uLgordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KK2NsYXNzIE1hcFBhaXIgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBjb25zdCBLZXkgZmlyc3RfdHlwZTsKKyAgdHlwZWRlZiBUIHNlY29uZF90eXBlOworCisgIE1hcFBhaXIoY29uc3QgS2V5JiBvdGhlcl9maXJzdCwgY29uc3QgVCYgb3RoZXJfc2Vjb25kKQorICAgICAgOiBmaXJzdChvdGhlcl9maXJzdCksIHNlY29uZChvdGhlcl9zZWNvbmQpIHt9CisgIGV4cGxpY2l0IE1hcFBhaXIoY29uc3QgS2V5JiBvdGhlcl9maXJzdCkgOiBmaXJzdChvdGhlcl9maXJzdCksIHNlY29uZCgpIHt9CisgIE1hcFBhaXIoY29uc3QgTWFwUGFpciYgb3RoZXIpCisgICAgICA6IGZpcnN0KG90aGVyLmZpcnN0KSwgc2Vjb25kKG90aGVyLnNlY29uZCkge30KKworICB+TWFwUGFpcigpIHt9CisKKyAgLy8gSW1wbGljaXRseSBjb252ZXJ0aWJsZSB0byBzdGQ6OnBhaXIgb2YgY29tcGF0aWJsZSB0eXBlcy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4KKyAgb3BlcmF0b3Igc3RkOjpwYWlyPFQxLCBUMj4oKSBjb25zdCB7CisgICAgcmV0dXJuIHN0ZDo6cGFpcjxUMSwgVDI+KGZpcnN0LCBzZWNvbmQpOworICB9CisKKyAgY29uc3QgS2V5IGZpcnN0OworICBUIHNlY29uZDsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIGZyaWVuZCBjbGFzcyBNYXA8S2V5LCBUPjsKK307CisKKy8vIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBpcyBhbiBhc3NvY2lhdGl2ZSBjb250YWluZXIgdHlwZSB1c2VkIHRvIHN0b3JlIHByb3RvYnVmIG1hcAorLy8gZmllbGRzLiBJdHMgaW50ZXJmYWNlIGlzIHNpbWlsYXIgdG8gc3RkOjp1bm9yZGVyZWRfbWFwLiBVc2VycyBzaG91bGQgdXNlIHRoaXMKKy8vIGludGVyZmFjZSBkaXJlY3RseSB0byB2aXNpdCBvciBjaGFuZ2UgbWFwIGZpZWxkcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CitjbGFzcyBNYXAgeworICB0eXBlZGVmIGludGVybmFsOjpNYXBDcHBUeXBlSGFuZGxlcjxLZXk+IEtleVR5cGVIYW5kbGVyOworICB0eXBlZGVmIGludGVybmFsOjpNYXBDcHBUeXBlSGFuZGxlcjxUPiBWYWx1ZVR5cGVIYW5kbGVyOworCisgcHVibGljOgorICB0eXBlZGVmIEtleSBrZXlfdHlwZTsKKyAgdHlwZWRlZiBUIG1hcHBlZF90eXBlOworICB0eXBlZGVmIE1hcFBhaXI8S2V5LCBUPiB2YWx1ZV90eXBlOworCisgIHR5cGVkZWYgdmFsdWVfdHlwZSogcG9pbnRlcjsKKyAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlKiBjb25zdF9wb2ludGVyOworICB0eXBlZGVmIHZhbHVlX3R5cGUmIHJlZmVyZW5jZTsKKyAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlJiBjb25zdF9yZWZlcmVuY2U7CisKKyAgdHlwZWRlZiBzaXplX3Qgc2l6ZV90eXBlOworICB0eXBlZGVmIGhhc2g8S2V5PiBoYXNoZXI7CisgIHR5cGVkZWYgZXF1YWxfdG88S2V5PiBrZXlfZXF1YWw7CisKKyAgTWFwKCkKKyAgICAgIDogYXJlbmFfKE5VTEwpLAorICAgICAgICBhbGxvY2F0b3JfKGFyZW5hXyksCisgICAgICAgIGVsZW1lbnRzXygwLCBoYXNoZXIoKSwga2V5X2VxdWFsKCksIGFsbG9jYXRvcl8pLAorICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWVfKDApIHt9CisgIGV4cGxpY2l0IE1hcChBcmVuYSogYXJlbmEpCisgICAgICA6IGFyZW5hXyhhcmVuYSksCisgICAgICAgIGFsbG9jYXRvcl8oYXJlbmFfKSwKKyAgICAgICAgZWxlbWVudHNfKDAsIGhhc2hlcigpLCBrZXlfZXF1YWwoKSwgYWxsb2NhdG9yXyksCisgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZV8oMCkge30KKworICBNYXAoY29uc3QgTWFwJiBvdGhlcikKKyAgICAgIDogYXJlbmFfKE5VTEwpLAorICAgICAgICBhbGxvY2F0b3JfKGFyZW5hXyksCisgICAgICAgIGVsZW1lbnRzXygwLCBoYXNoZXIoKSwga2V5X2VxdWFsKCksIGFsbG9jYXRvcl8pLAorICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWVfKG90aGVyLmRlZmF1bHRfZW51bV92YWx1ZV8pIHsKKyAgICBpbnNlcnQob3RoZXIuYmVnaW4oKSwgb3RoZXIuZW5kKCkpOworICB9CisKKyAgfk1hcCgpIHsgY2xlYXIoKTsgfQorCisgcHJpdmF0ZToKKyAgLy8gcmUtaW1wbGVtZW50IHN0ZDo6YWxsb2NhdG9yIHRvIHVzZSBhcmVuYSBhbGxvY2F0b3IgZm9yIG1lbW9yeSBhbGxvY2F0aW9uLgorICAvLyBVc2VkIGZvciBnb29nbGU6OnByb3RvYnVmOjpNYXAgaW1wbGVtZW50YXRpb24uIFVzZXJzIHNob3VsZCBub3QgdXNlIHRoaXMgY2xhc3MKKyAgLy8gZGlyZWN0bHkuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgorICBjbGFzcyBNYXBBbGxvY2F0b3IgeworICAgcHVibGljOgorICAgIHR5cGVkZWYgVSB2YWx1ZV90eXBlOworICAgIHR5cGVkZWYgdmFsdWVfdHlwZSogcG9pbnRlcjsKKyAgICB0eXBlZGVmIGNvbnN0IHZhbHVlX3R5cGUqIGNvbnN0X3BvaW50ZXI7CisgICAgdHlwZWRlZiB2YWx1ZV90eXBlJiByZWZlcmVuY2U7CisgICAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlJiBjb25zdF9yZWZlcmVuY2U7CisgICAgdHlwZWRlZiBzaXplX3Qgc2l6ZV90eXBlOworICAgIHR5cGVkZWYgcHRyZGlmZl90IGRpZmZlcmVuY2VfdHlwZTsKKworICAgIE1hcEFsbG9jYXRvcigpIDogYXJlbmFfKE5VTEwpIHt9CisgICAgZXhwbGljaXQgTWFwQWxsb2NhdG9yKEFyZW5hKiBhcmVuYSkgOiBhcmVuYV8oYXJlbmEpIHt9CisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFg+CisgICAgTWFwQWxsb2NhdG9yKGNvbnN0IE1hcEFsbG9jYXRvcjxYPiYgYWxsb2NhdG9yKQorICAgICAgICA6IGFyZW5hXyhhbGxvY2F0b3IuYXJlbmFfKSB7fQorCisgICAgcG9pbnRlciBhbGxvY2F0ZShzaXplX3R5cGUgbiwgY29uc3RfcG9pbnRlciBoaW50ID0gMCkgeworICAgICAgLy8gSWYgYXJlbmEgaXMgbm90IGdpdmVuLCBtYWxsb2MgbmVlZHMgdG8gYmUgY2FsbGVkIHdoaWNoIGRvZXNuJ3QKKyAgICAgIC8vIGNvbnN0cnVjdCBlbGVtZW50IG9iamVjdC4KKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxwb2ludGVyPihtYWxsb2MobiAqIHNpemVvZih2YWx1ZV90eXBlKSkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8cG9pbnRlcj4oCisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlQXJyYXk8dWludDg+KGFyZW5hXywgbiAqIHNpemVvZih2YWx1ZV90eXBlKSkpOworICAgICAgfQorICAgIH0KKworICAgIHZvaWQgZGVhbGxvY2F0ZShwb2ludGVyIHAsIHNpemVfdHlwZSBuKSB7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgICAgZnJlZShwKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGNvbnN0cnVjdChwb2ludGVyIHAsIGNvbnN0X3JlZmVyZW5jZSB0KSB7IG5ldyAocCkgdmFsdWVfdHlwZSh0KTsgfQorCisgICAgdm9pZCBkZXN0cm95KHBvaW50ZXIgcCkgeworICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSBwLT5+dmFsdWVfdHlwZSgpOworICAgIH0KKworICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBYPgorICAgIHN0cnVjdCByZWJpbmQgeworICAgICAgdHlwZWRlZiBNYXBBbGxvY2F0b3I8WD4gb3RoZXI7CisgICAgfTsKKworICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBYPgorICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYXBBbGxvY2F0b3I8WD4mIG90aGVyKSBjb25zdCB7CisgICAgICByZXR1cm4gYXJlbmFfID09IG90aGVyLmFyZW5hXzsKKyAgICB9CisKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgWD4KKyAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgTWFwQWxsb2NhdG9yPFg+JiBvdGhlcikgY29uc3QgeworICAgICAgcmV0dXJuIGFyZW5hXyAhPSBvdGhlci5hcmVuYV87CisgICAgfQorCisgICBwcml2YXRlOgorICAgIEFyZW5hKiBhcmVuYV87CisKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgWD4KKyAgICBmcmllbmQgY2xhc3MgTWFwQWxsb2NhdG9yOworICB9OworCisgcHVibGljOgorICB0eXBlZGVmIE1hcEFsbG9jYXRvcjxzdGQ6OnBhaXI8Y29uc3QgS2V5LCBNYXBQYWlyPEtleSwgVD4qPiA+IEFsbG9jYXRvcjsKKworICAvLyBJdGVyYXRvcnMKKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIGNvbnN0X2l0ZXJhdG9yCisgICAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIHZhbHVlX3R5cGUsIHB0cmRpZmZfdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVfdHlwZSosIGNvbnN0IHZhbHVlX3R5cGUmPiB7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBoYXNoX21hcDxLZXksIHZhbHVlX3R5cGUqLCBoYXNoPEtleT4sIGVxdWFsX3RvPEtleT4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGxvY2F0b3I+Ojpjb25zdF9pdGVyYXRvciBJbm5lckl0OworCisgICBwdWJsaWM6CisgICAgY29uc3RfaXRlcmF0b3IoKSB7fQorICAgIGV4cGxpY2l0IGNvbnN0X2l0ZXJhdG9yKGNvbnN0IElubmVySXQmIGl0KSA6IGl0XyhpdCkge30KKworICAgIGNvbnN0X3JlZmVyZW5jZSBvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiAqaXRfLT5zZWNvbmQ7IH0KKyAgICBjb25zdF9wb2ludGVyIG9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiBpdF8tPnNlY29uZDsgfQorCisgICAgY29uc3RfaXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7CisgICAgICArK2l0XzsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgY29uc3RfaXRlcmF0b3Igb3BlcmF0b3IrKyhpbnQpIHsgcmV0dXJuIGNvbnN0X2l0ZXJhdG9yKGl0XysrKTsgfQorCisgICAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBjb25zdF9pdGVyYXRvciYgYSwgY29uc3QgY29uc3RfaXRlcmF0b3ImIGIpIHsKKyAgICAgIHJldHVybiBhLml0XyA9PSBiLml0XzsKKyAgICB9CisgICAgZnJpZW5kIGJvb2wgb3BlcmF0b3IhPShjb25zdCBjb25zdF9pdGVyYXRvciYgYSwgY29uc3QgY29uc3RfaXRlcmF0b3ImIGIpIHsKKyAgICAgIHJldHVybiBhLml0XyAhPSBiLml0XzsKKyAgICB9CisKKyAgIHByaXZhdGU6CisgICAgSW5uZXJJdCBpdF87CisgIH07CisKKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIGl0ZXJhdG9yIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywgdmFsdWVfdHlwZT4geworICAgIHR5cGVkZWYgdHlwZW5hbWUgaGFzaF9tYXA8S2V5LCB2YWx1ZV90eXBlKiwgaGFzaGVyLCBlcXVhbF90bzxLZXk+LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxsb2NhdG9yPjo6aXRlcmF0b3IgSW5uZXJJdDsKKworICAgcHVibGljOgorICAgIGl0ZXJhdG9yKCkge30KKyAgICBleHBsaWNpdCBpdGVyYXRvcihjb25zdCBJbm5lckl0JiBpdCkgOiBpdF8oaXQpIHt9CisKKyAgICByZWZlcmVuY2Ugb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gKml0Xy0+c2Vjb25kOyB9CisgICAgcG9pbnRlciBvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gaXRfLT5zZWNvbmQ7IH0KKworICAgIGl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeworICAgICAgKytpdF87CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorICAgIGl0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7IHJldHVybiBpdGVyYXRvcihpdF8rKyk7IH0KKworICAgIC8vIEltcGxpY2l0bHkgY29udmVydGlibGUgdG8gY29uc3RfaXRlcmF0b3IuCisgICAgb3BlcmF0b3IgY29uc3RfaXRlcmF0b3IoKSBjb25zdCB7IHJldHVybiBjb25zdF9pdGVyYXRvcihpdF8pOyB9CisKKyAgICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGl0ZXJhdG9yJiBhLCBjb25zdCBpdGVyYXRvciYgYikgeworICAgICAgcmV0dXJuIGEuaXRfID09IGIuaXRfOworICAgIH0KKyAgICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGl0ZXJhdG9yJiBhLCBjb25zdCBpdGVyYXRvciYgYikgeworICAgICAgcmV0dXJuIGEuaXRfICE9IGIuaXRfOworICAgIH0KKworICAgcHJpdmF0ZToKKyAgICBmcmllbmQgY2xhc3MgTWFwOworICAgIElubmVySXQgaXRfOworICB9OworCisgIGl0ZXJhdG9yIGJlZ2luKCkgeyByZXR1cm4gaXRlcmF0b3IoZWxlbWVudHNfLmJlZ2luKCkpOyB9CisgIGl0ZXJhdG9yIGVuZCgpIHsgcmV0dXJuIGl0ZXJhdG9yKGVsZW1lbnRzXy5lbmQoKSk7IH0KKyAgY29uc3RfaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7IHJldHVybiBjb25zdF9pdGVyYXRvcihlbGVtZW50c18uYmVnaW4oKSk7IH0KKyAgY29uc3RfaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gY29uc3RfaXRlcmF0b3IoZWxlbWVudHNfLmVuZCgpKTsgfQorICBjb25zdF9pdGVyYXRvciBjYmVnaW4oKSBjb25zdCB7IHJldHVybiBiZWdpbigpOyB9CisgIGNvbnN0X2l0ZXJhdG9yIGNlbmQoKSBjb25zdCB7IHJldHVybiBlbmQoKTsgfQorCisgIC8vIENhcGFjaXR5CisgIHNpemVfdHlwZSBzaXplKCkgY29uc3QgeyByZXR1cm4gZWxlbWVudHNfLnNpemUoKTsgfQorICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gZWxlbWVudHNfLmVtcHR5KCk7IH0KKworICAvLyBFbGVtZW50IGFjY2VzcworICBUJiBvcGVyYXRvcltdKGNvbnN0IGtleV90eXBlJiBrZXkpIHsKKyAgICB2YWx1ZV90eXBlKiogdmFsdWUgPSAmZWxlbWVudHNfW2tleV07CisgICAgaWYgKCp2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAqdmFsdWUgPSBDcmVhdGVWYWx1ZVR5cGVJbnRlcm5hbChrZXkpOworICAgICAgaW50ZXJuYWw6Ok1hcFZhbHVlSW5pdGlhbGl6ZXI8Z29vZ2xlOjpwcm90b2J1Zjo6aXNfcHJvdG9fZW51bTxUPjo6dmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUPjo6SW5pdGlhbGl6ZSgoKnZhbHVlKS0+c2Vjb25kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlXyk7CisgICAgfQorICAgIHJldHVybiAoKnZhbHVlKS0+c2Vjb25kOworICB9CisgIGNvbnN0IFQmIGF0KGNvbnN0IGtleV90eXBlJiBrZXkpIGNvbnN0IHsKKyAgICBjb25zdF9pdGVyYXRvciBpdCA9IGZpbmQoa2V5KTsKKyAgICBHT09HTEVfQ0hFQ0soaXQgIT0gZW5kKCkpOworICAgIHJldHVybiBpdC0+c2Vjb25kOworICB9CisgIFQmIGF0KGNvbnN0IGtleV90eXBlJiBrZXkpIHsKKyAgICBpdGVyYXRvciBpdCA9IGZpbmQoa2V5KTsKKyAgICBHT09HTEVfQ0hFQ0soaXQgIT0gZW5kKCkpOworICAgIHJldHVybiBpdC0+c2Vjb25kOworICB9CisKKyAgLy8gTG9va3VwCisgIHNpemVfdHlwZSBjb3VudChjb25zdCBrZXlfdHlwZSYga2V5KSBjb25zdCB7CisgICAgcmV0dXJuIGVsZW1lbnRzXy5jb3VudChrZXkpOworICB9CisgIGNvbnN0X2l0ZXJhdG9yIGZpbmQoY29uc3Qga2V5X3R5cGUmIGtleSkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9pdGVyYXRvcihlbGVtZW50c18uZmluZChrZXkpKTsKKyAgfQorICBpdGVyYXRvciBmaW5kKGNvbnN0IGtleV90eXBlJiBrZXkpIHsKKyAgICByZXR1cm4gaXRlcmF0b3IoZWxlbWVudHNfLmZpbmQoa2V5KSk7CisgIH0KKyAgc3RkOjpwYWlyPGNvbnN0X2l0ZXJhdG9yLCBjb25zdF9pdGVyYXRvcj4gZXF1YWxfcmFuZ2UoCisgICAgICBjb25zdCBrZXlfdHlwZSYga2V5KSBjb25zdCB7CisgICAgY29uc3RfaXRlcmF0b3IgaXQgPSBmaW5kKGtleSk7CisgICAgaWYgKGl0ID09IGVuZCgpKSB7CisgICAgICByZXR1cm4gc3RkOjpwYWlyPGNvbnN0X2l0ZXJhdG9yLCBjb25zdF9pdGVyYXRvcj4oaXQsIGl0KTsKKyAgICB9IGVsc2UgeworICAgICAgY29uc3RfaXRlcmF0b3IgYmVnaW4gPSBpdCsrOworICAgICAgcmV0dXJuIHN0ZDo6cGFpcjxjb25zdF9pdGVyYXRvciwgY29uc3RfaXRlcmF0b3I+KGJlZ2luLCBpdCk7CisgICAgfQorICB9CisgIHN0ZDo6cGFpcjxpdGVyYXRvciwgaXRlcmF0b3I+IGVxdWFsX3JhbmdlKGNvbnN0IGtleV90eXBlJiBrZXkpIHsKKyAgICBpdGVyYXRvciBpdCA9IGZpbmQoa2V5KTsKKyAgICBpZiAoaXQgPT0gZW5kKCkpIHsKKyAgICAgIHJldHVybiBzdGQ6OnBhaXI8aXRlcmF0b3IsIGl0ZXJhdG9yPihpdCwgaXQpOworICAgIH0gZWxzZSB7CisgICAgICBpdGVyYXRvciBiZWdpbiA9IGl0Kys7CisgICAgICByZXR1cm4gc3RkOjpwYWlyPGl0ZXJhdG9yLCBpdGVyYXRvcj4oYmVnaW4sIGl0KTsKKyAgICB9CisgIH0KKworICAvLyBpbnNlcnQKKyAgc3RkOjpwYWlyPGl0ZXJhdG9yLCBib29sPiBpbnNlcnQoY29uc3QgdmFsdWVfdHlwZSYgdmFsdWUpIHsKKyAgICBpdGVyYXRvciBpdCA9IGZpbmQodmFsdWUuZmlyc3QpOworICAgIGlmIChpdCAhPSBlbmQoKSkgeworICAgICAgcmV0dXJuIHN0ZDo6cGFpcjxpdGVyYXRvciwgYm9vbD4oaXQsIGZhbHNlKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIHN0ZDo6cGFpcjxpdGVyYXRvciwgYm9vbD4oCisgICAgICAgICAgaXRlcmF0b3IoZWxlbWVudHNfLmluc2VydChzdGQ6OnBhaXI8S2V5LCB2YWx1ZV90eXBlKj4oCisgICAgICAgICAgICAgIHZhbHVlLmZpcnN0LCBDcmVhdGVWYWx1ZVR5cGVJbnRlcm5hbCh2YWx1ZSkpKS5maXJzdCksIHRydWUpOworICAgIH0KKyAgfQorICB0ZW1wbGF0ZSA8Y2xhc3MgSW5wdXRJdD4KKyAgdm9pZCBpbnNlcnQoSW5wdXRJdCBmaXJzdCwgSW5wdXRJdCBsYXN0KSB7CisgICAgZm9yIChJbnB1dEl0IGl0ID0gZmlyc3Q7IGl0ICE9IGxhc3Q7ICsraXQpIHsKKyAgICAgIGl0ZXJhdG9yIGV4aXN0X2l0ID0gZmluZChpdC0+Zmlyc3QpOworICAgICAgaWYgKGV4aXN0X2l0ID09IGVuZCgpKSB7CisgICAgICAgIG9wZXJhdG9yW10oaXQtPmZpcnN0KSA9IGl0LT5zZWNvbmQ7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gRXJhc2UKKyAgc2l6ZV90eXBlIGVyYXNlKGNvbnN0IGtleV90eXBlJiBrZXkpIHsKKyAgICB0eXBlbmFtZSBoYXNoX21hcDxLZXksIHZhbHVlX3R5cGUqLCBoYXNoPEtleT4sIGVxdWFsX3RvPEtleT4sCisgICAgICAgICAgICAgICAgICAgICAgQWxsb2NhdG9yPjo6aXRlcmF0b3IgaXQgPSBlbGVtZW50c18uZmluZChrZXkpOworICAgIGlmIChpdCA9PSBlbGVtZW50c18uZW5kKCkpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0gZWxzZSB7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIGRlbGV0ZSBpdC0+c2Vjb25kOworICAgICAgZWxlbWVudHNfLmVyYXNlKGl0KTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorICB2b2lkIGVyYXNlKGl0ZXJhdG9yIHBvcykgeworICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgZGVsZXRlIHBvcy5pdF8tPnNlY29uZDsKKyAgICBlbGVtZW50c18uZXJhc2UocG9zLml0Xyk7CisgIH0KKyAgdm9pZCBlcmFzZShpdGVyYXRvciBmaXJzdCwgaXRlcmF0b3IgbGFzdCkgeworICAgIGZvciAoaXRlcmF0b3IgaXQgPSBmaXJzdDsgaXQgIT0gbGFzdDspIHsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgZGVsZXRlIGl0Lml0Xy0+c2Vjb25kOworICAgICAgZWxlbWVudHNfLmVyYXNlKChpdCsrKS5pdF8pOworICAgIH0KKyAgfQorICB2b2lkIGNsZWFyKCkgeworICAgIGZvciAoaXRlcmF0b3IgaXQgPSBiZWdpbigpOyBpdCAhPSBlbmQoKTsgKytpdCkgeworICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSBkZWxldGUgaXQuaXRfLT5zZWNvbmQ7CisgICAgfQorICAgIGVsZW1lbnRzXy5jbGVhcigpOworICB9CisKKyAgLy8gQXNzaWduCisgIE1hcCYgb3BlcmF0b3I9KGNvbnN0IE1hcCYgb3RoZXIpIHsKKyAgICBpZiAodGhpcyAhPSAmb3RoZXIpIHsKKyAgICAgIGNsZWFyKCk7CisgICAgICBpbnNlcnQob3RoZXIuYmVnaW4oKSwgb3RoZXIuZW5kKCkpOworICAgIH0KKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIC8vIFNldCBkZWZhdWx0IGVudW0gdmFsdWUgb25seSBmb3IgcHJvdG8yIG1hcCBmaWVsZCB3aG9zZSB2YWx1ZSBpcyBlbnVtIHR5cGUuCisgIHZvaWQgU2V0RGVmYXVsdEVudW1WYWx1ZShpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKSB7CisgICAgZGVmYXVsdF9lbnVtX3ZhbHVlXyA9IGRlZmF1bHRfZW51bV92YWx1ZTsKKyAgfQorCisgIHZhbHVlX3R5cGUqIENyZWF0ZVZhbHVlVHlwZUludGVybmFsKGNvbnN0IEtleSYga2V5KSB7CisgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IHZhbHVlX3R5cGUoa2V5KTsKKyAgICB9IGVsc2UgeworICAgICAgdmFsdWVfdHlwZSogdmFsdWUgPSByZWludGVycHJldF9jYXN0PHZhbHVlX3R5cGUqPigKKyAgICAgICAgICBBcmVuYTo6Q3JlYXRlQXJyYXk8dWludDg+KGFyZW5hXywgc2l6ZW9mKHZhbHVlX3R5cGUpKSk7CisgICAgICBBcmVuYTo6Q3JlYXRlSW5BcmVuYVN0b3JhZ2UoY29uc3RfY2FzdDxLZXkqPigmdmFsdWUtPmZpcnN0KSwgYXJlbmFfKTsKKyAgICAgIEFyZW5hOjpDcmVhdGVJbkFyZW5hU3RvcmFnZSgmdmFsdWUtPnNlY29uZCwgYXJlbmFfKTsKKyAgICAgIGNvbnN0X2Nhc3Q8S2V5Jj4odmFsdWUtPmZpcnN0KSA9IGtleTsKKyAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisgIH0KKworICB2YWx1ZV90eXBlKiBDcmVhdGVWYWx1ZVR5cGVJbnRlcm5hbChjb25zdCB2YWx1ZV90eXBlJiB2YWx1ZSkgeworICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyB2YWx1ZV90eXBlKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgdmFsdWVfdHlwZSogcCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dmFsdWVfdHlwZSo+KAorICAgICAgICAgIEFyZW5hOjpDcmVhdGVBcnJheTx1aW50OD4oYXJlbmFfLCBzaXplb2YodmFsdWVfdHlwZSkpKTsKKyAgICAgIEFyZW5hOjpDcmVhdGVJbkFyZW5hU3RvcmFnZShjb25zdF9jYXN0PEtleSo+KCZwLT5maXJzdCksIGFyZW5hXyk7CisgICAgICBBcmVuYTo6Q3JlYXRlSW5BcmVuYVN0b3JhZ2UoJnAtPnNlY29uZCwgYXJlbmFfKTsKKyAgICAgIGNvbnN0X2Nhc3Q8S2V5Jj4ocC0+Zmlyc3QpID0gdmFsdWUuZmlyc3Q7CisgICAgICBwLT5zZWNvbmQgPSB2YWx1ZS5zZWNvbmQ7CisgICAgICByZXR1cm4gcDsKKyAgICB9CisgIH0KKworICBBcmVuYSogYXJlbmFfOworICBBbGxvY2F0b3IgYWxsb2NhdG9yXzsKKyAgaGFzaF9tYXA8S2V5LCB2YWx1ZV90eXBlKiwgaGFzaDxLZXk+LCBlcXVhbF90bzxLZXk+LCBBbGxvY2F0b3I+IGVsZW1lbnRzXzsKKyAgaW50IGRlZmF1bHRfZW51bV92YWx1ZV87CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsCisgICAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KKyAgZnJpZW5kIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBpbnRlcm5hbDo6TWFwRmllbGRMaXRlOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01BUF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3OGE0ZjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeS5oCkBAIC0wLDAgKzEsMjk1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5X2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBBcmVuYTsKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBWYWx1ZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NsYXNzIE1hcEZpZWxkOworfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gUmVnaXN0ZXIgYWxsIE1hcEVudHJ5IGRlZmF1bHQgaW5zdGFuY2VzIHNvIHdlIGNhbiBkZWxldGUgdGhlbSBpbgorLy8gU2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKS4KK3ZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIFJlZ2lzdGVyTWFwRW50cnlEZWZhdWx0SW5zdGFuY2UoCisgICAgTWVzc2FnZUxpdGUqIGRlZmF1bHRfaW5zdGFuY2UpOworCisvLyBUaGlzIGlzIHRoZSBjb21tb24gYmFzZSBjbGFzcyBmb3IgTWFwRW50cnkuIEl0IGlzIHVzZWQgYnkgTWFwRmllbGRCYXNlIGluCisvLyByZWZsZWN0aW9uIGFwaSwgaW4gd2hpY2ggdGhlIHN0YXRpYyB0eXBlIG9mIGtleSBhbmQgdmFsdWUgaXMgdW5rbm93bi4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBFbnRyeUJhc2UgOiBwdWJsaWMgTWVzc2FnZSB7CisgcHVibGljOgorICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3QgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgICAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JfOworICAgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSByZWZsZWN0aW9uXzsKKyAgICByZXR1cm4gbWV0YWRhdGE7CisgIH0KKworIHByb3RlY3RlZDoKKyAgTWFwRW50cnlCYXNlKCkgOiBkZXNjcmlwdG9yXyhOVUxMKSwgcmVmbGVjdGlvbl8oTlVMTCkgeyAgfQorICB2aXJ0dWFsIH5NYXBFbnRyeUJhc2UoKSB7fQorCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uXzsKK307CisKKy8vIE1hcEVudHJ5IGlzIHRoZSByZXR1cm5lZCBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHdoZW4gY2FsbGluZyBBZGRNZXNzYWdlIG9mCisvLyBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uLiBJbiBvcmRlciB0byBsZXQgaXQgd29yayB3aXRoIGdlbmVyYXRlZCBtZXNzYWdlCisvLyByZWZsZWN0aW9uLCBpdHMgaW50ZXJuYWwgbGF5b3V0IGlzIHRoZSBzYW1lIGFzIGdlbmVyYXRlZCBtZXNzYWdlIHdpdGggdGhlCisvLyBzYW1lIGZpZWxkcy4gSG93ZXZlciwgaW4gb3JkZXIgdG8gZGVjaWRlIHRoZSBpbnRlcm5hbCBsYXlvdXQgb2Yga2V5L3ZhbHVlLCB3ZQorLy8gbmVlZCB0byBrbm93IGJvdGggdGhlaXIgY3BwIHR5cGUgaW4gZ2VuZXJhdGVkIGFwaSBhbmQgcHJvdG8gdHlwZS4KKy8vCisvLyBjcHAgdHlwZSB8IHByb3RvIHR5cGUgIHwgaW50ZXJuYWwgbGF5b3V0CisvLyBpbnQzMiAgICAgIFRZUEVfSU5UMzIgICAgaW50MzIKKy8vIGludDMyICAgICAgVFlQRV9GSVhFRDMyICBpbnQzMgorLy8gRm9vRW51bSAgICBUWVBFX0VOVU0gICAgIGludAorLy8gRm9vTWVzc2FnZSBUWVBFX01FU1NBR0UgIEZvb01lc3NhZ2UqCisvLworLy8gVGhlIGludGVybmFsIGxheW91dHMgb2YgcHJpbWl0aXZlIHR5cGVzIGNhbiBiZSBpbmZlcnJlZCBmcm9tIGl0cyBwcm90byB0eXBlLAorLy8gd2hpbGUgd2UgbmVlZCB0byBleHBsaWNpdGx5IHRlbGwgY3BwIHR5cGUgaWYgcHJvdG8gdHlwZSBpcyBUWVBFX01FU1NBR0UgdG8KKy8vIGdldCBpbnRlcm5hbCBsYXlvdXQuCisvLyBNb3Jlb3ZlciwgZGVmYXVsdF9lbnVtX3ZhbHVlIGlzIHVzZWQgdG8gaW5pdGlhbGl6ZSBlbnVtIGZpZWxkIGluIHByb3RvMi4KK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFZhbHVlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1hcEVudHJ5IDogcHVibGljIE1hcEVudHJ5QmFzZSB7CisgIC8vIEhhbmRsZXJzIGZvciBrZXkvdmFsdWUgd2lyZSB0eXBlLiBQcm92aWRlIHV0aWxpdGllcyB0byBwYXJzZS9zZXJpYWxpemUKKyAgLy8ga2V5L3ZhbHVlLgorICB0eXBlZGVmIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPGtLZXlGaWVsZFR5cGU+IEtleVdpcmVIYW5kbGVyOworICB0eXBlZGVmIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPGtWYWx1ZUZpZWxkVHlwZT4gVmFsdWVXaXJlSGFuZGxlcjsKKworICAvLyBEZWZpbmUga2V5L3ZhbHVlJ3MgaW50ZXJuYWwgc3RvcmVkIHR5cGUuIE1lc3NhZ2UgaXMgdGhlIG9ubHkgb25lIHdob3NlCisgIC8vIGludGVybmFsIHN0b3JlZCB0eXBlIGNhbm5vdCBiZSBpbmZlcnJlZCBmcm9tIGl0cyBwcm90byB0eXBlLgorICBzdGF0aWMgY29uc3QgYm9vbCBrSXNLZXlNZXNzYWdlID0gS2V5V2lyZUhhbmRsZXI6OmtJc01lc3NhZ2U7CisgIHN0YXRpYyBjb25zdCBib29sIGtJc1ZhbHVlTWVzc2FnZSA9IFZhbHVlV2lyZUhhbmRsZXI6OmtJc01lc3NhZ2U7CisgIHR5cGVkZWYgdHlwZW5hbWUgS2V5V2lyZUhhbmRsZXI6OkNwcFR5cGUgS2V5SW50ZXJuYWxUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIFZhbHVlV2lyZUhhbmRsZXI6OkNwcFR5cGUgVmFsdWVJbnRlcm5hbFR5cGU7CisgIHR5cGVkZWYgdHlwZW5hbWUgTWFwSWY8a0lzS2V5TWVzc2FnZSwgS2V5LCBLZXlJbnRlcm5hbFR5cGU+Ojp0eXBlCisgICAgICBLZXlDcHBUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIE1hcElmPGtJc1ZhbHVlTWVzc2FnZSwgVmFsdWUsIFZhbHVlSW50ZXJuYWxUeXBlPjo6dHlwZQorICAgICAgVmFsQ3BwVHlwZTsKKworICAvLyBBYmJyZXZpYXRpb24gZm9yIE1hcEVudHJ5CisgIHR5cGVkZWYgdHlwZW5hbWUgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok1hcEVudHJ5PAorICAgICAgS2V5LCBWYWx1ZSwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLCBkZWZhdWx0X2VudW1fdmFsdWU+IEVudHJ5VHlwZTsKKworICAvLyBBYmJyZXZpYXRpb24gZm9yIE1hcEVudHJ5TGl0ZQorICB0eXBlZGVmIHR5cGVuYW1lIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpNYXBFbnRyeUxpdGU8CisgICAgICBLZXksIFZhbHVlLCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT4KKyAgICAgIEVudHJ5TGl0ZVR5cGU7CisKKyBwdWJsaWM6CisgIH5NYXBFbnRyeSgpIHsKKyAgICBpZiAodGhpcyA9PSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgICAgZGVsZXRlIHJlZmxlY3Rpb25fOworICAgIH0KKyAgfQorCisgIC8vIGFjY2Vzc29ycyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICB2aXJ0dWFsIGlubGluZSBjb25zdCBLZXlDcHBUeXBlJiBrZXkoKSBjb25zdCB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLmtleSgpOworICB9CisgIGlubGluZSBLZXlDcHBUeXBlKiBtdXRhYmxlX2tleSgpIHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8ubXV0YWJsZV9rZXkoKTsKKyAgfQorICB2aXJ0dWFsIGlubGluZSBjb25zdCBWYWxDcHBUeXBlJiB2YWx1ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8udmFsdWUoKTsKKyAgfQorICBpbmxpbmUgVmFsQ3BwVHlwZSogbXV0YWJsZV92YWx1ZSgpIHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8ubXV0YWJsZV92YWx1ZSgpOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLk1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbnB1dCk7CisgIH0KKworICBpbnQgQnl0ZVNpemUoKSBjb25zdCB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLkJ5dGVTaXplKCk7CisgIH0KKworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyg6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgICAgZW50cnlfbGl0ZV8uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7CisgIH0KKworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3QgeworICAgIHJldHVybiBlbnRyeV9saXRlXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KG91dHB1dCk7CisgIH0KKworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8uR2V0Q2FjaGVkU2l6ZSgpOworICB9CisKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3QgeworICAgIHJldHVybiBlbnRyeV9saXRlXy5Jc0luaXRpYWxpemVkKCk7CisgIH0KKworICBNZXNzYWdlKiBOZXcoKSBjb25zdCB7CisgICAgTWFwRW50cnkqIGVudHJ5ID0gbmV3IE1hcEVudHJ5OworICAgIGVudHJ5LT5kZXNjcmlwdG9yXyA9IGRlc2NyaXB0b3JfOworICAgIGVudHJ5LT5yZWZsZWN0aW9uXyA9IHJlZmxlY3Rpb25fOworICAgIGVudHJ5LT5zZXRfZGVmYXVsdF9pbnN0YW5jZShkZWZhdWx0X2luc3RhbmNlXyk7CisgICAgcmV0dXJuIGVudHJ5OworICB9CisKKyAgTWVzc2FnZSogTmV3KEFyZW5hKiBhcmVuYSkgY29uc3QgeworICAgIE1hcEVudHJ5KiBlbnRyeSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPE1hcEVudHJ5PihhcmVuYSk7CisgICAgZW50cnktPmRlc2NyaXB0b3JfID0gZGVzY3JpcHRvcl87CisgICAgZW50cnktPnJlZmxlY3Rpb25fID0gcmVmbGVjdGlvbl87CisgICAgZW50cnktPnNldF9kZWZhdWx0X2luc3RhbmNlKGRlZmF1bHRfaW5zdGFuY2VfKTsKKyAgICByZXR1cm4gZW50cnk7CisgIH0KKworICBpbnQgU3BhY2VVc2VkKCkgY29uc3QgeworICAgIGludCBzaXplID0gc2l6ZW9mKE1hcEVudHJ5KTsKKyAgICBzaXplICs9IGVudHJ5X2xpdGVfLlNwYWNlVXNlZCgpOworICAgIHJldHVybiBzaXplOworICB9CisKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgICBDbGVhcigpOworICAgIE1lcmdlRnJvbShmcm9tKTsKKyAgfQorCisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICAgIEdPT0dMRV9DSEVDS19ORSgmZnJvbSwgdGhpcyk7CisgICAgY29uc3QgTWFwRW50cnkqIHNvdXJjZSA9IGR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGU8Y29uc3QgTWFwRW50cnkqPigmZnJvbSk7CisgICAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgICBSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgICB9IGVsc2UgeworICAgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICAgIH0KKyAgfQorCisgIHZvaWQgQ29weUZyb20oY29uc3QgTWFwRW50cnkmIGZyb20pIHsKKyAgICBDbGVhcigpOworICAgIE1lcmdlRnJvbShmcm9tKTsKKyAgfQorCisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1hcEVudHJ5JiBmcm9tKSB7CisgICAgZW50cnlfbGl0ZV8uTWVyZ2VGcm9tKGZyb20uZW50cnlfbGl0ZV8pOworICB9CisKKyAgdm9pZCBDbGVhcigpIHsKKyAgICBlbnRyeV9saXRlXy5DbGVhcigpOworICB9CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgZW50cnlfbGl0ZV8uSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIH0KKworICBBcmVuYSogR2V0QXJlbmEoKSBjb25zdCB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLkdldEFyZW5hKCk7CisgIH0KKworICAvLyBDcmVhdGUgZGVmYXVsdCBNYXBFbnRyeSBpbnN0YW5jZSBmb3IgZ2l2ZW4gZGVzY3JpcHRvci4gRGVzY3JpcHRvciBoYXMgdG8gYmUKKyAgLy8gZ2l2ZW4gd2hlbiBjcmVhdGluZyBkZWZhdWx0IE1hcEVudHJ5IGluc3RhbmNlIGJlY2F1c2UgZGlmZmVyZW50IG1hcCBmaWVsZAorICAvLyBtYXkgaGF2ZSB0aGUgc2FtZSB0eXBlIGFuZCBNYXBFbnRyeSBjbGFzcy4gVGhlIGdpdmVuIGRlc2NyaXB0b3IgaXMgbmVlZGVkCisgIC8vIHRvIGRpc3Rpbmd1aXNoIGluc3RhbmNlcyBvZiB0aGUgc2FtZSBNYXBFbnRyeSBjbGFzcy4KKyAgc3RhdGljIE1hcEVudHJ5KiBDcmVhdGVEZWZhdWx0SW5zdGFuY2UoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAgIE1hcEVudHJ5KiBlbnRyeSA9IG5ldyBNYXBFbnRyeTsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgICBkZXNjcmlwdG9yLCBlbnRyeSwgb2Zmc2V0c18sCisgICAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWFwRW50cnksIGVudHJ5X2xpdGVfLl9oYXNfYml0c18pLAorICAgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1hcEVudHJ5LCBfdW5rbm93bl9maWVsZHNfKSwgLTEsCisgICAgICAgIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLAorICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLCBzaXplb2YoTWFwRW50cnkpLCAtMSk7CisgICAgZW50cnktPmRlc2NyaXB0b3JfID0gZGVzY3JpcHRvcjsKKyAgICBlbnRyeS0+cmVmbGVjdGlvbl8gPSByZWZsZWN0aW9uOworICAgIGVudHJ5LT5zZXRfZGVmYXVsdF9pbnN0YW5jZShlbnRyeSk7CisgICAgZW50cnktPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICAgIFJlZ2lzdGVyTWFwRW50cnlEZWZhdWx0SW5zdGFuY2UoZW50cnkpOworICAgIHJldHVybiBlbnRyeTsKKyAgfQorCisgcHJpdmF0ZToKKyAgTWFwRW50cnkoKSA6IGRlZmF1bHRfaW5zdGFuY2VfKE5VTEwpLCBlbnRyeV9saXRlXygpIHt9CisKKyAgZXhwbGljaXQgTWFwRW50cnkoQXJlbmEqIGFyZW5hKQorICAgICAgOiBkZWZhdWx0X2luc3RhbmNlXyhOVUxMKSwgZW50cnlfbGl0ZV8oYXJlbmEpIHt9CisKKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8uR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgfQorCisgIHZvaWQgc2V0X2RlZmF1bHRfaW5zdGFuY2UoTWFwRW50cnkqIGRlZmF1bHRfaW5zdGFuY2UpIHsKKyAgICBkZWZhdWx0X2luc3RhbmNlXyA9IGRlZmF1bHRfaW5zdGFuY2U7CisgICAgZW50cnlfbGl0ZV8uc2V0X2RlZmF1bHRfaW5zdGFuY2UoJmRlZmF1bHRfaW5zdGFuY2UtPmVudHJ5X2xpdGVfKTsKKyAgfQorCisgIHN0YXRpYyBpbnQgb2Zmc2V0c19bMl07CisgIFVua25vd25GaWVsZFNldCBfdW5rbm93bl9maWVsZHNfOworICBNYXBFbnRyeSogZGVmYXVsdF9pbnN0YW5jZV87CisgIEVudHJ5TGl0ZVR5cGUgZW50cnlfbGl0ZV87CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga193aXJlX3R5cGUsCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlLCBpbnQgZGVmYXVsdF9lbnVtPgorICBmcmllbmQgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIGludGVybmFsOjpNYXBGaWVsZDsKKyAgZnJpZW5kIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBpbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb247CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1hcEVudHJ5KTsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFZhbHVlLCBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitpbnQgTWFwRW50cnk8S2V5LCBWYWx1ZSwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Om9mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWFwRW50cnksIGVudHJ5X2xpdGVfLmtleV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWFwRW50cnksIGVudHJ5X2xpdGVfLnZhbHVlXyksCit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQVBfRU5UUllfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeV9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeV9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzA0ZmJhOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5X2xpdGUuaApAQCAtMCwwICsxLDQwOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01BUF9FTlRSWV9MSVRFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0xJVEVfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBBcmVuYTsKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBWYWx1ZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NsYXNzIE1hcEVudHJ5OwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVmFsdWUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitjbGFzcyBNYXBGaWVsZExpdGU7Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gTWFwRW50cnlMaXRlIGlzIHVzZWQgdG8gaW1wbGVtZW50IHBhcnNpbmcgYW5kIHNlcmlhbGl6YXRpb24gb2YgbWFwIGZvciBsaXRlCisvLyBydW50aW1lLgordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVmFsdWUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWFwRW50cnlMaXRlIDogcHVibGljIE1lc3NhZ2VMaXRlIHsKKyAgLy8gSGFuZGxlcnMgZm9yIGtleS92YWx1ZSB3aXJlIHR5cGUuIFByb3ZpZGUgdXRpbGl0aWVzIHRvIHBhcnNlL3NlcmlhbGl6ZQorICAvLyBrZXkvdmFsdWUuCisgIHR5cGVkZWYgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8a0tleUZpZWxkVHlwZT4gS2V5V2lyZUhhbmRsZXI7CisgIHR5cGVkZWYgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8a1ZhbHVlRmllbGRUeXBlPiBWYWx1ZVdpcmVIYW5kbGVyOworCisgIC8vIERlZmluZSBrZXkvdmFsdWUncyBpbnRlcm5hbCBzdG9yZWQgdHlwZS4gTWVzc2FnZSBpcyB0aGUgb25seSBvbmUgd2hvc2UKKyAgLy8gaW50ZXJuYWwgc3RvcmVkIHR5cGUgY2Fubm90IGJlIGluZmVycmVkIGZyb20gaXRzIHByb3RvIHR5cGUKKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzS2V5TWVzc2FnZSA9IEtleVdpcmVIYW5kbGVyOjprSXNNZXNzYWdlOworICBzdGF0aWMgY29uc3QgYm9vbCBrSXNWYWx1ZU1lc3NhZ2UgPSBWYWx1ZVdpcmVIYW5kbGVyOjprSXNNZXNzYWdlOworICB0eXBlZGVmIHR5cGVuYW1lIEtleVdpcmVIYW5kbGVyOjpDcHBUeXBlIEtleUludGVybmFsVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBWYWx1ZVdpcmVIYW5kbGVyOjpDcHBUeXBlIFZhbHVlSW50ZXJuYWxUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIE1hcElmPGtJc0tleU1lc3NhZ2UsIEtleSwgS2V5SW50ZXJuYWxUeXBlPjo6dHlwZQorICAgICAgS2V5Q3BwVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBNYXBJZjxrSXNWYWx1ZU1lc3NhZ2UsIFZhbHVlLCBWYWx1ZUludGVybmFsVHlwZT46OnR5cGUKKyAgICAgIFZhbENwcFR5cGU7CisKKyAgLy8gSGFuZGxlcnMgZm9yIGtleS92YWx1ZSdzIGludGVybmFsIHN0b3JlZCB0eXBlLiBQcm92aWRlIHV0aWxpdGllcyB0bworICAvLyBtYW5pcHVsYXRlIGludGVybmFsIHN0b3JlZCB0eXBlLiBXZSBuZWVkIGl0IGJlY2F1c2Ugc29tZSB0eXBlcyBhcmUgc3RvcmVkCisgIC8vIGFzIHZhbHVlcyBhbmQgb3RoZXJzIGFyZSBzdG9yZWQgYXMgcG9pbnRlcnMgKE1lc3NhZ2UgYW5kIHN0cmluZyksIGJ1dCB3ZQorICAvLyBuZWVkIHRvIGtlZXAgdGhlIGNvZGUgaW4gTWFwRW50cnkgdW5pZmllZCBpbnN0ZWFkIG9mIHByb3ZpZGluZyBkaWZmZXJlbnQKKyAgLy8gY29kZXMgZm9yIGVhY2ggdHlwZS4KKyAgdHlwZWRlZiBNYXBDcHBUeXBlSGFuZGxlcjxLZXlDcHBUeXBlPiBLZXlDcHBIYW5kbGVyOworICB0eXBlZGVmIE1hcENwcFR5cGVIYW5kbGVyPFZhbENwcFR5cGU+IFZhbHVlQ3BwSGFuZGxlcjsKKworICAvLyBEZWZpbmUgaW50ZXJuYWwgbWVtb3J5IGxheW91dC4gU3RyaW5ncyBhbmQgbWVzc2FnZXMgYXJlIHN0b3JlZCBhcworICAvLyBwb2ludGVycywgd2hpbGUgb3RoZXIgdHlwZXMgYXJlIHN0b3JlZCBhcyB2YWx1ZXMuCisgIHN0YXRpYyBjb25zdCBib29sIGtLZXlJc1N0cmluZ09yTWVzc2FnZSA9IEtleUNwcEhhbmRsZXI6OmtJc1N0cmluZ09yTWVzc2FnZTsKKyAgc3RhdGljIGNvbnN0IGJvb2wga1ZhbElzU3RyaW5nT3JNZXNzYWdlID0gVmFsdWVDcHBIYW5kbGVyOjprSXNTdHJpbmdPck1lc3NhZ2U7CisgIHR5cGVkZWYgdHlwZW5hbWUgTWFwSWY8a0tleUlzU3RyaW5nT3JNZXNzYWdlLCBLZXlDcHBUeXBlKiwgS2V5Q3BwVHlwZT46OnR5cGUKKyAgICAgIEtleUJhc2U7CisgIHR5cGVkZWYgdHlwZW5hbWUgTWFwSWY8a1ZhbElzU3RyaW5nT3JNZXNzYWdlLCBWYWxDcHBUeXBlKiwgVmFsQ3BwVHlwZT46OnR5cGUKKyAgICAgIFZhbHVlQmFzZTsKKworICAvLyBDb25zdGFudHMgZm9yIGZpZWxkIG51bWJlci4KKyAgc3RhdGljIGNvbnN0IGludCBrS2V5RmllbGROdW1iZXIgPSAxOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZUZpZWxkTnVtYmVyID0gMjsKKworICAvLyBDb25zdGFudHMgZm9yIGZpZWxkIHRhZy4KKyAgc3RhdGljIGNvbnN0IHVpbnQ4IGtLZXlUYWcgPSBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoCisgICAgICBrS2V5RmllbGROdW1iZXIsIEtleVdpcmVIYW5kbGVyOjprV2lyZVR5cGUpOworICBzdGF0aWMgY29uc3QgdWludDgga1ZhbHVlVGFnID0gR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX01BS0VfVEFHKAorICAgICAga1ZhbHVlRmllbGROdW1iZXIsIFZhbHVlV2lyZUhhbmRsZXI6OmtXaXJlVHlwZSk7CisgIHN0YXRpYyBjb25zdCBpbnQga1RhZ1NpemUgPSAxOworCisgcHVibGljOgorICB+TWFwRW50cnlMaXRlKCkgeworICAgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgICBLZXlDcHBIYW5kbGVyOjpEZWxldGUoa2V5Xyk7CisgICAgICBWYWx1ZUNwcEhhbmRsZXI6OkRlbGV0ZSh2YWx1ZV8pOworICAgIH0KKyAgfQorCisgIC8vIGFjY2Vzc29ycyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICB2aXJ0dWFsIGlubGluZSBjb25zdCBLZXlDcHBUeXBlJiBrZXkoKSBjb25zdCB7CisgICAgcmV0dXJuIEtleUNwcEhhbmRsZXI6OlJlZmVyZW5jZShrZXlfKTsKKyAgfQorICBpbmxpbmUgS2V5Q3BwVHlwZSogbXV0YWJsZV9rZXkoKSB7CisgICAgc2V0X2hhc19rZXkoKTsKKyAgICBLZXlDcHBIYW5kbGVyOjpFbnN1cmVNdXRhYmxlKCZrZXlfLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgICByZXR1cm4gS2V5Q3BwSGFuZGxlcjo6UG9pbnRlcihrZXlfKTsKKyAgfQorICB2aXJ0dWFsIGlubGluZSBjb25zdCBWYWxDcHBUeXBlJiB2YWx1ZSgpIGNvbnN0IHsKKyAgICBHT09HTEVfQ0hFQ0soZGVmYXVsdF9pbnN0YW5jZV8gIT0gTlVMTCk7CisgICAgcmV0dXJuIFZhbHVlQ3BwSGFuZGxlcjo6RGVmYXVsdElmTm90SW5pdGlhbGl6ZWQodmFsdWVfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRfaW5zdGFuY2VfLT52YWx1ZV8pOworICB9CisgIGlubGluZSBWYWxDcHBUeXBlKiBtdXRhYmxlX3ZhbHVlKCkgeworICAgIHNldF9oYXNfdmFsdWUoKTsKKyAgICBWYWx1ZUNwcEhhbmRsZXI6OkVuc3VyZU11dGFibGUoJnZhbHVlXywgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgICAgcmV0dXJuIFZhbHVlQ3BwSGFuZGxlcjo6UG9pbnRlcih2YWx1ZV8pOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlTGl0ZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8vIE1hcEVudHJ5TGl0ZSBpcyBmb3IgaW1wbGVtZW50YXRpb24gb25seSBhbmQgdGhpcyBmdW5jdGlvbiBpc24ndCBjYWxsZWQKKyAgLy8gYW55d2hlcmUuIEp1c3QgcHJvdmlkZSBhIGZha2UgaW1wbGVtZW50YXRpb24gaGVyZSBmb3IgTWVzc2FnZUxpdGUuCisgIHN0cmluZyBHZXRUeXBlTmFtZSgpIGNvbnN0IHsgcmV0dXJuICIiOyB9CisKKyAgdm9pZCBDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgTWVzc2FnZUxpdGUmIG90aGVyKSB7CisgICAgTWVyZ2VGcm9tKCo6Omdvb2dsZTo6cHJvdG9idWY6OmRvd25fY2FzdDxjb25zdCBNYXBFbnRyeUxpdGUqPigmb3RoZXIpKTsKKyAgfQorCisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgICAgdWludDMyIHRhZzsKKworICAgIGZvciAoOzspIHsKKyAgICAgIC8vIDEpIGNvcnJ1cHRlZCBkYXRhOiByZXR1cm4gZmFsc2U7CisgICAgICAvLyAyKSB1bmtub3duIGZpZWxkOiBza2lwIHdpdGhvdXQgcHV0dGluZyBpbnRvIHVua25vd24gZmllbGQgc2V0OworICAgICAgLy8gMykgdW5rbm93biBlbnVtIHZhbHVlOiBrZWVwIGl0IGluIHBhcnNpbmcuIEluIHByb3RvMiwgY2FsbGVyIHNob3VsZAorICAgICAgLy8gY2hlY2sgdGhlIHZhbHVlIGFuZCBwdXQgdGhpcyBlbnRyeSBpbnRvIGNvbnRhaW5pbmcgbWVzc2FnZSdzIHVua25vd24KKyAgICAgIC8vIGZpZWxkIHNldCBpZiB0aGUgdmFsdWUgaXMgYW4gdW5rbm93biBlbnVtLiBJbiBwcm90bzMsIGNhbGxlciBkb2Vzbid0CisgICAgICAvLyBuZWVkIHRvIGNhcmUgd2hldGhlciB0aGUgdmFsdWUgaXMgdW5rbm93biBlbnVtOworICAgICAgLy8gNCkgbWlzc2luZyBrZXkvdmFsdWU6IG1pc3NlZCBrZXkvdmFsdWUgd2lsbCBoYXZlIGRlZmF1bHQgdmFsdWUuIGNhbGxlcgorICAgICAgLy8gc2hvdWxkIHRha2UgdGhpcyBlbnRyeSBhcyBpZiBrZXkvdmFsdWUgaXMgc2V0IHRvIGRlZmF1bHQgdmFsdWUuCisgICAgICB0YWcgPSBpbnB1dC0+UmVhZFRhZygpOworICAgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgICAgY2FzZSBrS2V5VGFnOgorICAgICAgICAgIGlmICghS2V5V2lyZUhhbmRsZXI6OlJlYWQoaW5wdXQsIG11dGFibGVfa2V5KCkpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgc2V0X2hhc19rZXkoKTsKKyAgICAgICAgICBpZiAoIWlucHV0LT5FeHBlY3RUYWcoa1ZhbHVlVGFnKSkgYnJlYWs7CisgICAgICAgICAgR09PR0xFX0ZBTExUSFJPVUdIX0lOVEVOREVEOworCisgICAgICAgIGNhc2Uga1ZhbHVlVGFnOgorICAgICAgICAgIGlmICghVmFsdWVXaXJlSGFuZGxlcjo6UmVhZChpbnB1dCwgbXV0YWJsZV92YWx1ZSgpKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIHNldF9oYXNfdmFsdWUoKTsKKyAgICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIHJldHVybiB0cnVlOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpIHJldHVybiBmYWxzZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpbnQgQnl0ZVNpemUoKSBjb25zdCB7CisgICAgaW50IHNpemUgPSAwOworICAgIHNpemUgKz0gaGFzX2tleSgpID8ga1RhZ1NpemUgKyBLZXlXaXJlSGFuZGxlcjo6Qnl0ZVNpemUoa2V5KCkpIDogMDsKKyAgICBzaXplICs9IGhhc192YWx1ZSgpID8ga1RhZ1NpemUgKyBWYWx1ZVdpcmVIYW5kbGVyOjpCeXRlU2l6ZSh2YWx1ZSgpKSA6IDA7CisgICAgcmV0dXJuIHNpemU7CisgIH0KKworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyg6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgICAgS2V5V2lyZUhhbmRsZXI6OldyaXRlKGtLZXlGaWVsZE51bWJlciwga2V5KCksIG91dHB1dCk7CisgICAgVmFsdWVXaXJlSGFuZGxlcjo6V3JpdGUoa1ZhbHVlRmllbGROdW1iZXIsIHZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3QgeworICAgIG91dHB1dCA9IEtleVdpcmVIYW5kbGVyOjpXcml0ZVRvQXJyYXkoa0tleUZpZWxkTnVtYmVyLCBrZXkoKSwgb3V0cHV0KTsKKyAgICBvdXRwdXQgPQorICAgICAgICBWYWx1ZVdpcmVIYW5kbGVyOjpXcml0ZVRvQXJyYXkoa1ZhbHVlRmllbGROdW1iZXIsIHZhbHVlKCksIG91dHB1dCk7CisgICAgcmV0dXJuIG91dHB1dDsKKyAgfQorCisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeworICAgIGludCBzaXplID0gMDsKKyAgICBzaXplICs9IGhhc19rZXkoKSA/IGtUYWdTaXplICsgS2V5V2lyZUhhbmRsZXI6OkdldENhY2hlZFNpemUoa2V5KCkpIDogMDsKKyAgICBzaXplICs9CisgICAgICAgIGhhc192YWx1ZSgpID8ga1RhZ1NpemUgKyBWYWx1ZVdpcmVIYW5kbGVyOjpHZXRDYWNoZWRTaXplKHZhbHVlKCkpIDogMDsKKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0IHsgcmV0dXJuIFZhbHVlQ3BwSGFuZGxlcjo6SXNJbml0aWFsaXplZCh2YWx1ZV8pOyB9CisKKyAgTWVzc2FnZUxpdGUqIE5ldygpIGNvbnN0IHsKKyAgICBNYXBFbnRyeUxpdGUqIGVudHJ5ID0gbmV3IE1hcEVudHJ5TGl0ZTsKKyAgICBlbnRyeS0+ZGVmYXVsdF9pbnN0YW5jZV8gPSBkZWZhdWx0X2luc3RhbmNlXzsKKyAgICByZXR1cm4gZW50cnk7CisgIH0KKworICBNZXNzYWdlTGl0ZSogTmV3KEFyZW5hKiBhcmVuYSkgY29uc3QgeworICAgIE1hcEVudHJ5TGl0ZSogZW50cnkgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxNYXBFbnRyeUxpdGU+KGFyZW5hKTsKKyAgICBlbnRyeS0+ZGVmYXVsdF9pbnN0YW5jZV8gPSBkZWZhdWx0X2luc3RhbmNlXzsKKyAgICByZXR1cm4gZW50cnk7CisgIH0KKworICBpbnQgU3BhY2VVc2VkKCkgY29uc3QgeworICAgIGludCBzaXplID0gc2l6ZW9mKE1hcEVudHJ5TGl0ZSk7CisgICAgc2l6ZSArPSBLZXlDcHBIYW5kbGVyOjpTcGFjZVVzZWRJbk1hcEVudHJ5KGtleV8pOworICAgIHNpemUgKz0gVmFsdWVDcHBIYW5kbGVyOjpTcGFjZVVzZWRJbk1hcEVudHJ5KHZhbHVlXyk7CisgICAgcmV0dXJuIHNpemU7CisgIH0KKworICB2b2lkIE1lcmdlRnJvbShjb25zdCBNYXBFbnRyeUxpdGUmIGZyb20pIHsKKyAgICBpZiAoZnJvbS5faGFzX2JpdHNfWzBdKSB7CisgICAgICBpZiAoZnJvbS5oYXNfa2V5KCkpIHsKKyAgICAgICAgS2V5Q3BwSGFuZGxlcjo6RW5zdXJlTXV0YWJsZSgma2V5XywgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgICAgICAgIEtleUNwcEhhbmRsZXI6Ok1lcmdlKGZyb20ua2V5KCksICZrZXlfKTsKKyAgICAgICAgc2V0X2hhc19rZXkoKTsKKyAgICAgIH0KKyAgICAgIGlmIChmcm9tLmhhc192YWx1ZSgpKSB7CisgICAgICAgIFZhbHVlQ3BwSGFuZGxlcjo6RW5zdXJlTXV0YWJsZSgmdmFsdWVfLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgICAgICAgVmFsdWVDcHBIYW5kbGVyOjpNZXJnZShmcm9tLnZhbHVlKCksICZ2YWx1ZV8pOworICAgICAgICBzZXRfaGFzX3ZhbHVlKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgdm9pZCBDbGVhcigpIHsKKyAgICBLZXlDcHBIYW5kbGVyOjpDbGVhcigma2V5Xyk7CisgICAgVmFsdWVDcHBIYW5kbGVyOjpDbGVhck1heWJlQnlEZWZhdWx0RW51bSgmdmFsdWVfLCBkZWZhdWx0X2VudW1fdmFsdWUpOworICAgIGNsZWFyX2hhc19rZXkoKTsKKyAgICBjbGVhcl9oYXNfdmFsdWUoKTsKKyAgfQorCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICAgIEtleUNwcEhhbmRsZXI6OkFzc2lnbkRlZmF1bHRWYWx1ZSgma2V5Xyk7CisgICAgVmFsdWVDcHBIYW5kbGVyOjpBc3NpZ25EZWZhdWx0VmFsdWUoJnZhbHVlXyk7CisgIH0KKworICBBcmVuYSogR2V0QXJlbmEoKSBjb25zdCB7CisgICAgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIH0KKworICAvLyBDcmVhdGUgYSBNYXBFbnRyeUxpdGUgZm9yIGdpdmVuIGtleSBhbmQgdmFsdWUgZnJvbSBnb29nbGU6OnByb3RvYnVmOjpNYXAgaW4KKyAgLy8gc2VyaWFsaXphdGlvbi4gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCB3aGVuIHZhbHVlIGlzIGVudW0uIEVudW0gaXMKKyAgLy8gdHJlYXRlZCBkaWZmZXJlbnRseSBiZWNhdXNlIGl0cyB0eXBlIGluIE1hcEVudHJ5IGlzIGludCBhbmQgaXRzIHR5cGUgaW4KKyAgLy8gZ29vZ2xlOjpwcm90b2J1Zjo6TWFwIGlzIGVudW0uIFdlIGNhbm5vdCBjcmVhdGUgYSByZWZlcmVuY2UgdG8gaW50IGZyb20gYW4gZW51bS4KKyAgc3RhdGljIE1hcEVudHJ5TGl0ZSogRW51bVdyYXAoY29uc3QgS2V5JiBrZXksIGNvbnN0IFZhbHVlIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEpIHsKKyAgICByZXR1cm4gQXJlbmE6OkNyZWF0ZTxNYXBFbnVtRW50cnlXcmFwcGVyPAorICAgICAgICBLZXksIFZhbHVlLCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT4gPigKKyAgICAgICAgYXJlbmEsIGtleSwgdmFsdWUsIGFyZW5hKTsKKyAgfQorCisgIC8vIExpa2UgYWJvdmUsIGJ1dCBmb3IgYWxsIHRoZSBvdGhlciB0eXBlcy4gVGhpcyBhdm9pZHMgdmFsdWUgY29weSB0byBjcmVhdGUKKyAgLy8gTWFwRW50cnlMaXRlIGZyb20gZ29vZ2xlOjpwcm90b2J1Zjo6TWFwIGluIHNlcmlhbGl6YXRpb24uCisgIHN0YXRpYyBNYXBFbnRyeUxpdGUqIFdyYXAoY29uc3QgS2V5JiBrZXksIGNvbnN0IFZhbHVlJiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7CisgICAgcmV0dXJuIEFyZW5hOjpDcmVhdGU8TWFwRW50cnlXcmFwcGVyPEtleSwgVmFsdWUsIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPiA+KAorICAgICAgICBhcmVuYSwga2V5LCB2YWx1ZSwgYXJlbmEpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgc2V0X2hhc19rZXkoKSB7IF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7IH0KKyAgYm9vbCBoYXNfa2V5KCkgY29uc3QgeyByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsgfQorICB2b2lkIGNsZWFyX2hhc19rZXkoKSB7IF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OyB9CisgIHZvaWQgc2V0X2hhc192YWx1ZSgpIHsgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsgfQorICBib29sIGhhc192YWx1ZSgpIGNvbnN0IHsgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7IH0KKyAgdm9pZCBjbGVhcl9oYXNfdmFsdWUoKSB7IF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OyB9CisKKyBwcml2YXRlOgorICAvLyBTZXJpYWxpemluZyBhIGdlbmVyYXRlZCBtZXNzYWdlIGNvbnRhaW5pbmcgbWFwIGZpZWxkIGludm9sdmVzIHNlcmlhbGl6aW5nCisgIC8vIGtleS12YWx1ZSBwYWlycyBmcm9tIGdvb2dsZTo6cHJvdG9idWY6Ok1hcC4gVGhlIHdpcmUgZm9ybWF0IG9mIGVhY2gga2V5LXZhbHVlIHBhaXIKKyAgLy8gYWZ0ZXIgc2VyaWFsaXphdGlvbiBzaG91bGQgYmUgdGhlIHNhbWUgYXMgdGhhdCBvZiBhIE1hcEVudHJ5IG1lc3NhZ2UKKyAgLy8gY29udGFpbmluZyB0aGUgc2FtZSBrZXkgYW5kIHZhbHVlIGluc2lkZSBpdC4gIEhvd2V2ZXIsIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBkb2Vzbid0CisgIC8vIHN0b3JlIGtleSBhbmQgdmFsdWUgYXMgTWFwRW50cnkgbWVzc2FnZSwgd2hpY2ggZGlzYWJsZXMgdXMgdG8gdXNlIGV4aXN0aW5nCisgIC8vIGNvZGUgdG8gc2VyaWFsaXplIG1lc3NhZ2UuIEluIG9yZGVyIHRvIHVzZSBleGlzdGluZyBjb2RlIHRvIHNlcmlhbGl6ZQorICAvLyBtZXNzYWdlLCB3ZSBuZWVkIHRvIGNvbnN0cnVjdCBhIE1hcEVudHJ5IGZyb20ga2V5LXZhbHVlIHBhaXIuIEJ1dCBpdAorICAvLyBpbnZvbHZlcyBjb3B5IG9mIGtleSBhbmQgdmFsdWUgdG8gY29uc3RydWN0IGEgTWFwRW50cnkuIEluIG9yZGVyIHRvIGF2b2lkCisgIC8vIHRoaXMgY29weSBpbiBjb25zdHJ1Y3RpbmcgYSBNYXBFbnRyeSwgd2UgbmVlZCB0aGUgZm9sbG93aW5nIGNsYXNzIHdoaWNoCisgIC8vIG9ubHkgdGFrZXMgcmVmZXJlbmNlcyBvZiBnaXZlbiBrZXkgYW5kIHZhbHVlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgViwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrX3dpcmVfdHlwZSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdl93aXJlX3R5cGUsIGludCBkZWZhdWx0X2VudW0+CisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBFbnRyeVdyYXBwZXIKKyAgICAgIDogcHVibGljIE1hcEVudHJ5TGl0ZTxLLCBWLCBrX3dpcmVfdHlwZSwgdl93aXJlX3R5cGUsIGRlZmF1bHRfZW51bT4geworICAgIHR5cGVkZWYgTWFwRW50cnlMaXRlPEssIFYsIGtfd2lyZV90eXBlLCB2X3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtPiBCYXNlOworICAgIHR5cGVkZWYgdHlwZW5hbWUgQmFzZTo6S2V5Q3BwVHlwZSBLZXlDcHBUeXBlOworICAgIHR5cGVkZWYgdHlwZW5hbWUgQmFzZTo6VmFsQ3BwVHlwZSBWYWxDcHBUeXBlOworCisgICBwdWJsaWM6CisgICAgTWFwRW50cnlXcmFwcGVyKGNvbnN0IEsmIGtleSwgY29uc3QgViYgdmFsdWUsIEFyZW5hKiBhcmVuYSkKKyAgICAgICAgOiBNYXBFbnRyeUxpdGU8SywgViwga193aXJlX3R5cGUsIHZfd2lyZV90eXBlLCBkZWZhdWx0X2VudW0+KGFyZW5hKSwKKyAgICAgICAgICBrZXlfKGtleSksCisgICAgICAgICAgdmFsdWVfKHZhbHVlKSB7CisgICAgICBCYXNlOjpzZXRfaGFzX2tleSgpOworICAgICAgQmFzZTo6c2V0X2hhc192YWx1ZSgpOworICAgIH0KKyAgICBpbmxpbmUgY29uc3QgS2V5Q3BwVHlwZSYga2V5KCkgY29uc3QgeyByZXR1cm4ga2V5XzsgfQorICAgIGlubGluZSBjb25zdCBWYWxDcHBUeXBlJiB2YWx1ZSgpIGNvbnN0IHsgcmV0dXJuIHZhbHVlXzsgfQorCisgICBwcml2YXRlOgorICAgIGNvbnN0IEtleSYga2V5XzsKKyAgICBjb25zdCBWYWx1ZSYgdmFsdWVfOworCisgICAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgICAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworICB9OworCisgIC8vIExpa2UgYWJvdmUsIGJ1dCBmb3IgZW51bSB2YWx1ZSBvbmx5LCB3aGljaCBzdG9yZXMgdmFsdWUgaW5zdGVhZCBvZgorICAvLyByZWZlcmVuY2Ugb2YgdmFsdWUgZmllbGQgaW5zaWRlLiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIHRoZSB0eXBlIG9mIHZhbHVlCisgIC8vIGZpZWxkIGluIGNvbnN0cnVjdG9yIGlzIGFuIGVudW0sIHdoaWxlIHdlIG5lZWQgdG8gc3RvcmUgaXQgYXMgYW4gaW50LiBJZiB3ZQorICAvLyBpbml0aWFsaXplIGEgcmVmZXJlbmNlIHRvIGludCB3aXRoIGEgcmVmZXJlbmNlIHRvIGVudW0sIGNvbXBpbGVyIHdpbGwKKyAgLy8gZ2VuZXJhdGUgYSB0ZW1wb3JhcnkgaW50IGZyb20gZW51bSBhbmQgaW5pdGlhbGl6ZSB0aGUgcmVmZXJlbmNlIHRvIGludCB3aXRoCisgIC8vIHRoZSB0ZW1wb3JhcnkuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBLLCB0eXBlbmFtZSBWLCBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtfd2lyZV90eXBlLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2X3dpcmVfdHlwZSwgaW50IGRlZmF1bHRfZW51bT4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1hcEVudW1FbnRyeVdyYXBwZXIKKyAgICAgIDogcHVibGljIE1hcEVudHJ5TGl0ZTxLLCBWLCBrX3dpcmVfdHlwZSwgdl93aXJlX3R5cGUsIGRlZmF1bHRfZW51bT4geworICAgIHR5cGVkZWYgTWFwRW50cnlMaXRlPEssIFYsIGtfd2lyZV90eXBlLCB2X3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtPiBCYXNlOworICAgIHR5cGVkZWYgdHlwZW5hbWUgQmFzZTo6S2V5Q3BwVHlwZSBLZXlDcHBUeXBlOworICAgIHR5cGVkZWYgdHlwZW5hbWUgQmFzZTo6VmFsQ3BwVHlwZSBWYWxDcHBUeXBlOworCisgICBwdWJsaWM6CisgICAgTWFwRW51bUVudHJ5V3JhcHBlcihjb25zdCBLJiBrZXksIGNvbnN0IFYmIHZhbHVlLCBBcmVuYSogYXJlbmEpCisgICAgICAgIDogTWFwRW50cnlMaXRlPEssIFYsIGtfd2lyZV90eXBlLCB2X3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtPihhcmVuYSksCisgICAgICAgICAga2V5XyhrZXkpLAorICAgICAgICAgIHZhbHVlXyh2YWx1ZSkgeworICAgICAgQmFzZTo6c2V0X2hhc19rZXkoKTsKKyAgICAgIEJhc2U6OnNldF9oYXNfdmFsdWUoKTsKKyAgICB9CisgICAgaW5saW5lIGNvbnN0IEtleUNwcFR5cGUmIGtleSgpIGNvbnN0IHsgcmV0dXJuIGtleV87IH0KKyAgICBpbmxpbmUgY29uc3QgVmFsQ3BwVHlwZSYgdmFsdWUoKSBjb25zdCB7IHJldHVybiB2YWx1ZV87IH0KKworICAgcHJpdmF0ZToKKyAgICBjb25zdCBLZXlDcHBUeXBlJiBrZXlfOworICAgIGNvbnN0IFZhbENwcFR5cGUgdmFsdWVfOworCisgICAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgICAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworICB9OworCisgIE1hcEVudHJ5TGl0ZSgpIDogZGVmYXVsdF9pbnN0YW5jZV8oTlVMTCksIGFyZW5hXyhOVUxMKSB7CisgICAgS2V5Q3BwSGFuZGxlcjo6SW5pdGlhbGl6ZSgma2V5XywgTlVMTCk7CisgICAgVmFsdWVDcHBIYW5kbGVyOjpJbml0aWFsaXplTWF5YmVCeURlZmF1bHRFbnVtKAorICAgICAgICAmdmFsdWVfLCBkZWZhdWx0X2VudW1fdmFsdWUsIE5VTEwpOworICAgIF9oYXNfYml0c19bMF0gPSAwOworICB9CisKKyAgZXhwbGljaXQgTWFwRW50cnlMaXRlKEFyZW5hKiBhcmVuYSkKKyAgICAgIDogZGVmYXVsdF9pbnN0YW5jZV8oTlVMTCksIGFyZW5hXyhhcmVuYSkgeworICAgIEtleUNwcEhhbmRsZXI6OkluaXRpYWxpemUoJmtleV8sIGFyZW5hKTsKKyAgICBWYWx1ZUNwcEhhbmRsZXI6OkluaXRpYWxpemVNYXliZUJ5RGVmYXVsdEVudW0oCisgICAgICAgICZ2YWx1ZV8sIGRlZmF1bHRfZW51bV92YWx1ZSwgYXJlbmEpOworICAgIF9oYXNfYml0c19bMF0gPSAwOworICB9CisKKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gYXJlbmFfOworICB9CisKKyAgdm9pZCBzZXRfZGVmYXVsdF9pbnN0YW5jZShNYXBFbnRyeUxpdGUqIGRlZmF1bHRfaW5zdGFuY2UpIHsKKyAgICBkZWZhdWx0X2luc3RhbmNlXyA9IGRlZmF1bHRfaW5zdGFuY2U7CisgIH0KKworICBNYXBFbnRyeUxpdGUqIGRlZmF1bHRfaW5zdGFuY2VfOworCisgIEtleUJhc2Uga2V5XzsKKyAgVmFsdWVCYXNlIHZhbHVlXzsKKyAgQXJlbmEqIGFyZW5hXzsKKyAgdWludDMyIF9oYXNfYml0c19bMV07CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUsCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlLCBpbnQ+CisgIGZyaWVuZCBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgaW50ZXJuYWw6Ok1hcEVudHJ5OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgViwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUsIGludD4KKyAgZnJpZW5kIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBpbnRlcm5hbDo6TWFwRmllbGRMaXRlOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNYXBFbnRyeUxpdGUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkNDBjMGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5jYwpAQCAtMCwwICsxLDE0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmg+CisKKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK1Byb3RvYnVmT25jZVR5cGUgbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzX29uY2VfOworTXV0ZXgqIG1hcF9lbnRyeV9kZWZhdWx0X2luc3RhbmNlc19tdXRleF87Cit2ZWN0b3I8TWVzc2FnZUxpdGUqPiogbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzXzsKKwordm9pZCBEZWxldGVNYXBFbnRyeURlZmF1bHRJbnN0YW5jZXMoKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzXy0+c2l6ZSgpOyArK2kpIHsKKyAgICBkZWxldGUgbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzXy0+YXQoaSk7CisgIH0KKyAgZGVsZXRlIG1hcF9lbnRyeV9kZWZhdWx0X2luc3RhbmNlc19tdXRleF87CisgIGRlbGV0ZSBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfOworfQorCit2b2lkIEluaXRNYXBFbnRyeURlZmF1bHRJbnN0YW5jZXMoKSB7CisgIG1hcF9lbnRyeV9kZWZhdWx0X2luc3RhbmNlc19tdXRleF8gPSBuZXcgTXV0ZXgoKTsKKyAgbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzXyA9IG5ldyB2ZWN0b3I8TWVzc2FnZUxpdGUqPigpOworICBPblNodXRkb3duKCZEZWxldGVNYXBFbnRyeURlZmF1bHRJbnN0YW5jZXMpOworfQorCit2b2lkIFJlZ2lzdGVyTWFwRW50cnlEZWZhdWx0SW5zdGFuY2UoTWVzc2FnZUxpdGUqIGRlZmF1bHRfaW5zdGFuY2UpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzX29uY2VfLAorICAgICAgICAgICAgICAgICAmSW5pdE1hcEVudHJ5RGVmYXVsdEluc3RhbmNlcyk7CisgIE11dGV4TG9jayBsb2NrKG1hcF9lbnRyeV9kZWZhdWx0X2luc3RhbmNlc19tdXRleF8pOworICBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfLT5wdXNoX2JhY2soZGVmYXVsdF9pbnN0YW5jZSk7Cit9CisKK01hcEZpZWxkQmFzZTo6fk1hcEZpZWxkQmFzZSgpIHsKKyAgaWYgKHJlcGVhdGVkX2ZpZWxkXyAhPSBOVUxMICYmIGFyZW5hXyA9PSBOVUxMKSBkZWxldGUgcmVwZWF0ZWRfZmllbGRfOworfQorCitjb25zdCBSZXBlYXRlZFB0ckZpZWxkQmFzZSYgTWFwRmllbGRCYXNlOjpHZXRSZXBlYXRlZEZpZWxkKCkgY29uc3QgeworICBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKTsKKyAgcmV0dXJuICpyZXBlYXRlZF9maWVsZF87Cit9CisKK1JlcGVhdGVkUHRyRmllbGRCYXNlKiBNYXBGaWVsZEJhc2U6Ok11dGFibGVSZXBlYXRlZEZpZWxkKCkgeworICBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKTsKKyAgU2V0UmVwZWF0ZWREaXJ0eSgpOworICByZXR1cm4gcmVwZWF0ZWRfZmllbGRfOworfQorCitpbnQgTWFwRmllbGRCYXNlOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QgeworICBtdXRleF8uTG9jaygpOworICBpbnQgc2l6ZSA9IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGZOb0xvY2soKTsKKyAgbXV0ZXhfLlVubG9jaygpOworICByZXR1cm4gc2l6ZTsKK30KKworaW50IE1hcEZpZWxkQmFzZTo6U3BhY2VVc2VkRXhjbHVkaW5nU2VsZk5vTG9jaygpIGNvbnN0IHsKKyAgaWYgKHJlcGVhdGVkX2ZpZWxkXyAhPSBOVUxMKSB7CisgICAgcmV0dXJuIHJlcGVhdGVkX2ZpZWxkXy0+U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworICB9IGVsc2UgeworICAgIHJldHVybiAwOworICB9Cit9CisKK3ZvaWQgTWFwRmllbGRCYXNlOjpJbml0TWV0YWRhdGFPbmNlKCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soZW50cnlfZGVzY3JpcHRvcl8gIT0gTlVMTCk7CisgIEdPT0dMRV9DSEVDSyhhc3NpZ25fZGVzY3JpcHRvcl9jYWxsYmFja18gIT0gTlVMTCk7CisgICgqYXNzaWduX2Rlc2NyaXB0b3JfY2FsbGJhY2tfKSgpOworfQorCit2b2lkIE1hcEZpZWxkQmFzZTo6U2V0TWFwRGlydHkoKSB7IHN0YXRlXyA9IFNUQVRFX01PRElGSUVEX01BUDsgfQorCit2b2lkIE1hcEZpZWxkQmFzZTo6U2V0UmVwZWF0ZWREaXJ0eSgpIHsgc3RhdGVfID0gU1RBVEVfTU9ESUZJRURfUkVQRUFURUQ7IH0KKwordm9pZCogTWFwRmllbGRCYXNlOjpNdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZCgpIGNvbnN0IHsgcmV0dXJuIHJlcGVhdGVkX2ZpZWxkXzsgfQorCit2b2lkIE1hcEZpZWxkQmFzZTo6U3luY1JlcGVhdGVkRmllbGRXaXRoTWFwKCkgY29uc3QgeworICBBdG9taWMzMiBzdGF0ZSA9IGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOb0JhcnJpZXJfTG9hZCgmc3RhdGVfKTsKKyAgaWYgKHN0YXRlID09IFNUQVRFX01PRElGSUVEX01BUCkgeworICAgIG11dGV4Xy5Mb2NrKCk7CisgICAgLy8gRG91YmxlIGNoZWNrIHN0YXRlLCBiZWNhdXNlIGFub3RoZXIgdGhyZWFkIG1heSBoYXZlIHNlZW4gdGhlIHNhbWUgc3RhdGUKKyAgICAvLyBhbmQgZG9uZSB0aGUgc3luY2hyb25pemF0aW9uIGJlZm9yZSB0aGUgY3VycmVudCB0aHJlYWQuCisgICAgaWYgKHN0YXRlXyA9PSBTVEFURV9NT0RJRklFRF9NQVApIHsKKyAgICAgIFN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcE5vTG9jaygpOworICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vQmFycmllcl9TdG9yZSgmc3RhdGVfLCBDTEVBTik7CisgICAgfQorICAgIG11dGV4Xy5VbmxvY2soKTsKKyAgfQorfQorCit2b2lkIE1hcEZpZWxkQmFzZTo6U3luY1JlcGVhdGVkRmllbGRXaXRoTWFwTm9Mb2NrKCkgY29uc3QgeworICBpZiAocmVwZWF0ZWRfZmllbGRfID09IE5VTEwpIHsKKyAgICByZXBlYXRlZF9maWVsZF8gPSBBcmVuYTo6Q3JlYXRlPFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4gPihhcmVuYV8sIGFyZW5hXyk7CisgIH0KK30KKwordm9pZCBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpIGNvbnN0IHsKKyAgQXRvbWljMzIgc3RhdGUgPSBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX0xvYWQoJnN0YXRlXyk7CisgIGlmIChzdGF0ZSA9PSBTVEFURV9NT0RJRklFRF9SRVBFQVRFRCkgeworICAgIG11dGV4Xy5Mb2NrKCk7CisgICAgLy8gRG91YmxlIGNoZWNrIHN0YXRlLCBiZWNhdXNlIGFub3RoZXIgdGhyZWFkIG1heSBoYXZlIHNlZW4gdGhlIHNhbWUgc3RhdGUKKyAgICAvLyBhbmQgZG9uZSB0aGUgc3luY2hyb25pemF0aW9uIGJlZm9yZSB0aGUgY3VycmVudCB0aHJlYWQuCisgICAgaWYgKHN0YXRlXyA9PSBTVEFURV9NT0RJRklFRF9SRVBFQVRFRCkgeworICAgICAgU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkTm9Mb2NrKCk7CisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX1N0b3JlKCZzdGF0ZV8sIENMRUFOKTsKKyAgICB9CisgICAgbXV0ZXhfLlVubG9jaygpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZDhiNmVjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGQuaApAQCAtMCwwICsxLDIzNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgQ29udGVuZGVkTWFwQ2xlYW5UZXN0OworY2xhc3MgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb247CitjbGFzcyBNYXBGaWVsZEFjY2Vzc29yOworCisvLyBUaGlzIGNsYXNzIHByb3ZpZGVzIGFjY2Vzc3MgdG8gbWFwIGZpZWxkIHVzaW5nIHJlZmxlY3Rpb24sIHdoaWNoIGlzIHRoZSBzYW1lCisvLyBhcyB0aG9zZSBwcm92aWRlZCBmb3IgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPi4gSXQgaXMgdXNlZCBmb3IgaW50ZXJuYWwKKy8vIHJlZmxlY3Rpb24gaW1wbGVudGF0aW9uIG9ubHkuIFVzZXJzIHNob3VsZCBuZXZlciB1c2UgdGhpcyBkaXJlY3RseS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBGaWVsZEJhc2UgeworIHB1YmxpYzoKKyAgTWFwRmllbGRCYXNlKCkKKyAgICAgIDogYXJlbmFfKE5VTEwpLAorICAgICAgICByZXBlYXRlZF9maWVsZF8oTlVMTCksCisgICAgICAgIGVudHJ5X2Rlc2NyaXB0b3JfKE5VTEwpLAorICAgICAgICBhc3NpZ25fZGVzY3JpcHRvcl9jYWxsYmFja18oTlVMTCksCisgICAgICAgIHN0YXRlXyhTVEFURV9NT0RJRklFRF9NQVApIHt9CisgIGV4cGxpY2l0IE1hcEZpZWxkQmFzZShBcmVuYSogYXJlbmEpCisgICAgICA6IGFyZW5hXyhhcmVuYSksCisgICAgICAgIHJlcGVhdGVkX2ZpZWxkXyhOVUxMKSwKKyAgICAgICAgZW50cnlfZGVzY3JpcHRvcl8oTlVMTCksCisgICAgICAgIGFzc2lnbl9kZXNjcmlwdG9yX2NhbGxiYWNrXyhOVUxMKSwKKyAgICAgICAgc3RhdGVfKFNUQVRFX01PRElGSUVEX01BUCkge30KKyAgdmlydHVhbCB+TWFwRmllbGRCYXNlKCk7CisKKyAgLy8gUmV0dXJucyByZWZlcmVuY2UgdG8gaW50ZXJuYWwgcmVwZWF0ZWQgZmllbGQuIERhdGEgd3JpdHRlbiB1c2luZworICAvLyBnb29nbGU6OnByb3RvYnVmOjpNYXAncyBhcGkgcHJpb3IgdG8gY2FsbGluZyB0aGlzIGZ1bmN0aW9uIGlzIGd1YXJhbnR0ZWQgdG8gYmUKKyAgLy8gaW5jbHVkZWQgaW4gcmVwZWF0ZWQgZmllbGQuCisgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGRCYXNlJiBHZXRSZXBlYXRlZEZpZWxkKCkgY29uc3Q7CisKKyAgLy8gTGlrZSBhYm92ZS4gUmV0dXJucyBtdXRhYmxlIHBvaW50ZXIgdG8gdGhlIGludGVybmFsIHJlcGVhdGVkIGZpZWxkLgorICBSZXBlYXRlZFB0ckZpZWxkQmFzZSogTXV0YWJsZVJlcGVhdGVkRmllbGQoKTsKKworICAvLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgdXNlZCBieSB0aGUgcmVwZWF0ZWQgZmllbGQsIGV4Y2x1ZGluZworICAvLyBzaXplb2YoKnRoaXMpCisgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIC8vIEdldHMgdGhlIHNpemUgb2Ygc3BhY2UgdXNlZCBieSBtYXAgZmllbGQuCisgIHZpcnR1YWwgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGZOb0xvY2soKSBjb25zdDsKKworICAvLyBTeW5jaHJvbml6ZXMgdGhlIGNvbnRlbnQgaW4gTWFwIHRvIFJlcGVhdGVkUHRyRmllbGQgaWYgdGhlcmUgaXMgYW55IGNoYW5nZQorICAvLyB0byBNYXAgYWZ0ZXIgbGFzdCBzeW5jaHJvbml6YXRpb24uCisgIHZvaWQgU3luY1JlcGVhdGVkRmllbGRXaXRoTWFwKCkgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXBOb0xvY2soKSBjb25zdDsKKworICAvLyBTeW5jaHJvbml6ZXMgdGhlIGNvbnRlbnQgaW4gUmVwZWF0ZWRQdHJGaWVsZCB0byBNYXAgaWYgdGhlcmUgaXMgYW55IGNoYW5nZQorICAvLyB0byBSZXBlYXRlZFB0ckZpZWxkIGFmdGVyIGxhc3Qgc3luY2hyb25pemF0aW9uLgorICB2b2lkIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkTm9Mb2NrKCkgY29uc3Qge30KKworICAvLyBUZWxscyBNYXBGaWVsZEJhc2UgdGhhdCB0aGVyZSBpcyBuZXcgY2hhbmdlIHRvIE1hcC4KKyAgdm9pZCBTZXRNYXBEaXJ0eSgpOworCisgIC8vIFRlbGxzIE1hcEZpZWxkQmFzZSB0aGF0IHRoZXJlIGlzIG5ldyBjaGFuZ2UgdG8gUmVwZWF0ZWRQVHJGaWVsZC4KKyAgdm9pZCBTZXRSZXBlYXRlZERpcnR5KCk7CisKKyAgLy8gUHJvdmlkZXMgZGVyaXZlZCBjbGFzcyB0aGUgYWNjZXNzIHRvIHJlcGVhdGVkIGZpZWxkLgorICB2b2lkKiBNdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZCgpIGNvbnN0OworCisgIC8vIENyZWF0ZXMgZGVzY3JpcHRvciBmb3Igb25seSBvbmUgdGltZS4KKyAgdm9pZCBJbml0TWV0YWRhdGFPbmNlKCkgY29uc3Q7CisKKyAgZW51bSBTdGF0ZSB7CisgICAgU1RBVEVfTU9ESUZJRURfTUFQID0gMCwgICAgICAgLy8gbWFwIGhhcyBuZXdseSBhZGRlZCBkYXRhIHRoYXQgaGFzIG5vdCBiZWVuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3luY2hyb25pemVkIHRvIHJlcGVhdGVkIGZpZWxkCisgICAgU1RBVEVfTU9ESUZJRURfUkVQRUFURUQgPSAxLCAgLy8gcmVwZWF0ZWQgZmllbGQgaGFzIG5ld2x5IGFkZGVkIGRhdGEgdGhhdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhcyBub3QgYmVlbiBzeW5jaHJvbml6ZWQgdG8gbWFwCisgICAgQ0xFQU4gPSAyLCAgLy8gZGF0YSBpbiBtYXAgYW5kIHJlcGVhdGVkIGZpZWxkIGFyZSBzYW1lCisgIH07CisKKyAgQXJlbmEqIGFyZW5hXzsKKyAgbXV0YWJsZSBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KiByZXBlYXRlZF9maWVsZF87CisgIC8vIE1hcEVudHJ5IGNhbiBvbmx5IGJlIGNyZWF0ZWQgZnJvbSBNYXBGaWVsZC4gVG8gY3JlYXRlIE1hcEVudHJ5LCBNYXBGaWVsZAorICAvLyBuZWVkcyB0byBrbm93IGl0cyBkZXNjcmlwdG9yLCBiZWNhdXNlIE1hcEVudHJ5IGlzIG5vdCBnZW5lcmF0ZWQgY2xhc3Mgd2hpY2gKKyAgLy8gY2Fubm90IGluaXRpYWxpemUgaXRzIG93biBkZXNjcmlwdG9yIGJ5IGNhbGxpbmcgZ2VuZXJhdGVkCisgIC8vIGRlc2NyaXB0b3ItYXNzaWduLWZ1bmN0aW9uLiBUaHVzLCB3ZSBuZWVkIHRvIHJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8KKyAgLy8gaW5pdGlhbGl6ZSBNYXBFbnRyeSdzIGRlc2NyaXB0b3IuCisgIGNvbnN0IERlc2NyaXB0b3IqKiBlbnRyeV9kZXNjcmlwdG9yXzsKKyAgdm9pZCAoKmFzc2lnbl9kZXNjcmlwdG9yX2NhbGxiYWNrXykoKTsKKworICBtdXRhYmxlIE11dGV4IG11dGV4XzsgIC8vIFRoZSB0aHJlYWQgdG8gc3luY2hyb25pemUgbWFwIGFuZCByZXBlYXRlZCBmaWVsZAorICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5lZWRzIHRvIGdldCBsb2NrIGZpcnN0OworICBtdXRhYmxlIHZvbGF0aWxlIEF0b21pYzMyIHN0YXRlXzsgIC8vIDA6IFNUQVRFX01PRElGSUVEX01BUAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDE6IFNUQVRFX01PRElGSUVEX1JFUEVBVEVECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMjogQ0xFQU4KKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBDb250ZW5kZWRNYXBDbGVhblRlc3Q7CisgIGZyaWVuZCBjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjsKKyAgZnJpZW5kIGNsYXNzIE1hcEZpZWxkQWNjZXNzb3I7Cit9OworCisvLyBUaGlzIGNsYXNzIHByb3ZpZGVzIGFjY2Vzc3MgdG8gbWFwIGZpZWxkIHVzaW5nIGdlbmVyYXRlZCBhcGkuIEl0IGlzIHVzZWQgZm9yCisvLyBpbnRlcm5hbCBnZW5lcmF0ZWQgbWVzc2FnZSBpbXBsZW50YXRpb24gb25seS4gVXNlcnMgc2hvdWxkIG5ldmVyIHVzZSB0aGlzCisvLyBkaXJlY3RseS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWUgPSAwPgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1hcEZpZWxkIDogcHVibGljIE1hcEZpZWxkQmFzZSwKKyAgICAgICAgICAgICAgICAgcHVibGljIE1hcEZpZWxkTGl0ZTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+IHsKKyAgLy8gSGFuZGxlcnMgZm9yIGtleS92YWx1ZSB3aXJlIHR5cGUuIFByb3ZpZGUgdXRpbGl0aWVzIHRvIHBhcnNlL3NlcmlhbGl6ZQorICAvLyBrZXkvdmFsdWUuCisgIHR5cGVkZWYgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8a0tleUZpZWxkVHlwZT4gS2V5V2lyZUhhbmRsZXI7CisgIHR5cGVkZWYgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8a1ZhbHVlRmllbGRUeXBlPiBWYWx1ZVdpcmVIYW5kbGVyOworCisgIC8vIERlZmluZSBrZXkvdmFsdWUncyBpbnRlcm5hbCBzdG9yZWQgdHlwZS4KKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzS2V5TWVzc2FnZSA9IEtleVdpcmVIYW5kbGVyOjprSXNNZXNzYWdlOworICBzdGF0aWMgY29uc3QgYm9vbCBrSXNWYWxNZXNzYWdlID0gVmFsdWVXaXJlSGFuZGxlcjo6a0lzTWVzc2FnZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBLZXlXaXJlSGFuZGxlcjo6Q3BwVHlwZSBLZXlJbnRlcm5hbFR5cGU7CisgIHR5cGVkZWYgdHlwZW5hbWUgVmFsdWVXaXJlSGFuZGxlcjo6Q3BwVHlwZSBWYWx1ZUludGVybmFsVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBNYXBJZjxrSXNLZXlNZXNzYWdlLCBLZXksIEtleUludGVybmFsVHlwZT46OnR5cGUgS2V5Q3BwOworICB0eXBlZGVmIHR5cGVuYW1lIE1hcElmPGtJc1ZhbE1lc3NhZ2UsIFQgICwgVmFsdWVJbnRlcm5hbFR5cGU+Ojp0eXBlIFZhbENwcDsKKworICAvLyBIYW5kbGVycyBmb3Iga2V5L3ZhbHVlJ3MgaW50ZXJuYWwgc3RvcmVkIHR5cGUuCisgIHR5cGVkZWYgTWFwQ3BwVHlwZUhhbmRsZXI8S2V5Q3BwPiBLZXlIYW5kbGVyOworICB0eXBlZGVmIE1hcENwcFR5cGVIYW5kbGVyPFZhbENwcD4gVmFsSGFuZGxlcjsKKworICAvLyBEZWZpbmUgbWVzc2FnZSB0eXBlIGZvciBpbnRlcm5hbCByZXBlYXRlZCBmaWVsZC4KKyAgdHlwZWRlZiBNYXBFbnRyeTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPgorICAgICAgRW50cnlUeXBlOworICB0eXBlZGVmIE1hcEVudHJ5TGl0ZTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPiBFbnRyeUxpdGVUeXBlOworCisgIC8vIERlZmluZSBhYmJyZXZpYXRpb24gZm9yIHBhcmVudCBNYXBGaWVsZExpdGUKKyAgdHlwZWRlZiBNYXBGaWVsZExpdGU8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT4gTWFwRmllbGRMaXRlVHlwZTsKKworICAvLyBFbnVtIG5lZWRzIHRvIGJlIGhhbmRsZWQgZGlmZmVyZW50bHkgZnJvbSBvdGhlciB0eXBlcyBiZWNhdXNlIGl0IGhhcworICAvLyBkaWZmZXJlbnQgZXhwb3NlZCB0eXBlIGluIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCdzIGFwaSBhbmQgcmVwZWF0ZWQgZmllbGQncyBhcGkuIEZvcgorICAvLyBkZXRhaWxzIHNlZSB0aGUgY29tbWVudCBpbiB0aGUgaW1wbGVtZW50YXRpb24gb2YKKyAgLy8gU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkTm9Mb2NraS4KKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzVmFsdWVFbnVtID0gVmFsdWVXaXJlSGFuZGxlcjo6a0lzRW51bTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBNYXBJZjxrSXNWYWx1ZUVudW0sIFQsIGNvbnN0IFQmPjo6dHlwZSBDYXN0VmFsdWVUeXBlOworCisgcHVibGljOgorICBNYXBGaWVsZCgpOworICBleHBsaWNpdCBNYXBGaWVsZChBcmVuYSogYXJlbmEpOworICAvLyBNYXBGaWVsZCBkb2Vzbid0IG93biB0aGUgZGVmYXVsdF9lbnRyeSwgd2hpY2ggbWVhbnMgZGVmYXVsdF9lbnRyeSBtdXN0CisgIC8vIG91dGxpdmUgdGhlIGxpZmV0aW1lIG9mIE1hcEZpZWxkLgorICBNYXBGaWVsZChjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5KTsKKyAgLy8gRm9yIHRlc3RzIG9ubHkuCisgIE1hcEZpZWxkKEFyZW5hKiBhcmVuYSwgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9lbnRyeSk7CisgIH5NYXBGaWVsZCgpOworCisgIC8vIEFjY2Vzc29ycworICBjb25zdCBNYXA8S2V5LCBUPiYgR2V0TWFwKCkgY29uc3Q7CisgIE1hcDxLZXksIFQ+KiBNdXRhYmxlTWFwKCk7CisKKyAgLy8gQ29udmVuaWVudCBtZXRob2RzIGZvciBnZW5lcmF0ZWQgbWVzc2FnZSBpbXBsZW1lbnRhdGlvbi4KKyAgaW50IHNpemUoKSBjb25zdDsKKyAgdm9pZCBDbGVhcigpOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBNYXBGaWVsZExpdGVUeXBlJiBvdGhlcik7CisgIHZvaWQgU3dhcChNYXBGaWVsZExpdGVUeXBlKiBvdGhlcik7CisKKyAgLy8gQWxsb2NhdGVzIG1ldGFkYXRhIG9ubHkgaWYgdGhpcyBNYXBGaWVsZCBpcyBwYXJ0IG9mIGEgZ2VuZXJhdGVkIG1lc3NhZ2UuCisgIHZvaWQgU2V0RW50cnlEZXNjcmlwdG9yKGNvbnN0IERlc2NyaXB0b3IqKiBkZXNjcmlwdG9yKTsKKyAgdm9pZCBTZXRBc3NpZ25EZXNjcmlwdG9yQ2FsbGJhY2sodm9pZCAoKmNhbGxiYWNrKSgpKTsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKworICAvLyBNYXBGaWVsZCBuZWVkcyBNYXBFbnRyeSdzIGRlZmF1bHQgaW5zdGFuY2UgdG8gY3JlYXRlIG5ldyBNYXBFbnRyeS4KKyAgdm9pZCBJbml0RGVmYXVsdEVudHJ5T25jZSgpIGNvbnN0OworCisgIC8vIE1hbnVhbGx5IHNldCBkZWZhdWx0IGVudHJ5IGluc3RhbmNlLiBGb3IgdGVzdCBvbmx5LgorICB2b2lkIFNldERlZmF1bHRFbnRyeU9uY2UoY29uc3QgRW50cnlUeXBlKiBkZWZhdWx0X2VudHJ5KSBjb25zdDsKKworICAvLyBDb252ZW5pZW50IG1ldGhvZHMgdG8gZ2V0IGludGVybmFsIGdvb2dsZTo6cHJvdG9idWY6Ok1hcAorICBjb25zdCBNYXA8S2V5LCBUPiYgR2V0SW50ZXJuYWxNYXAoKSBjb25zdDsKKyAgTWFwPEtleSwgVD4qIE11dGFibGVJbnRlcm5hbE1hcCgpOworCisgIC8vIEltcGxlbWVudHMgTWFwRmllbGRCYXNlCisgIHZvaWQgU3luY1JlcGVhdGVkRmllbGRXaXRoTWFwTm9Mb2NrKCkgY29uc3Q7CisgIHZvaWQgU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkTm9Mb2NrKCkgY29uc3Q7CisgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmTm9Mb2NrKCkgY29uc3Q7CisKKyAgbXV0YWJsZSBjb25zdCBFbnRyeVR5cGUqIGRlZmF1bHRfZW50cnlfOworCisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9pbmwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTYzYzcyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmgKQEAgLTAsMCArMSwzMDIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfRklFTERfSU5MX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0lOTF9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT46Ok1hcEZpZWxkKCkKKyAgICA6IGRlZmF1bHRfZW50cnlfKE5VTEwpIHt9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWFwRmllbGQoCisgICAgQXJlbmEqIGFyZW5hKQorICAgIDogTWFwRmllbGRCYXNlKGFyZW5hKSwKKyAgICAgIE1hcEZpZWxkTGl0ZTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPigKKyAgICAgICAgICBhcmVuYSksCisgICAgICBkZWZhdWx0X2VudHJ5XyhOVUxMKSB7fQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT46Ok1hcEZpZWxkKAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfZW50cnkpCisgICAgOiBkZWZhdWx0X2VudHJ5Xyhkb3duX2Nhc3Q8Y29uc3QgRW50cnlUeXBlKj4oZGVmYXVsdF9lbnRyeSkpIHt9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWFwRmllbGQoCisgICAgQXJlbmEqIGFyZW5hLCBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5KQorICAgIDogTWFwRmllbGRCYXNlKGFyZW5hKSwKKyAgICAgIE1hcEZpZWxkTGl0ZTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPigKKyAgICAgICAgICBhcmVuYSksCisgICAgICBkZWZhdWx0X2VudHJ5Xyhkb3duX2Nhc3Q8Y29uc3QgRW50cnlUeXBlKj4oZGVmYXVsdF9lbnRyeSkpIHt9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46On5NYXBGaWVsZCgpIHt9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitpbnQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6c2l6ZSgpIGNvbnN0IHsKKyAgU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkKCk7CisgIHJldHVybiBNYXBGaWVsZExpdGVUeXBlOjpHZXRJbnRlcm5hbE1hcCgpLnNpemUoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6Q2xlYXIoKSB7CisgIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICBNYXBGaWVsZExpdGVUeXBlOjpNdXRhYmxlSW50ZXJuYWxNYXAoKS0+Y2xlYXIoKTsKKyAgU2V0TWFwRGlydHkoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NvbnN0IE1hcDxLZXksIFQ+JgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpHZXRNYXAoKSBjb25zdCB7CisgIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICByZXR1cm4gTWFwRmllbGRMaXRlVHlwZTo6R2V0SW50ZXJuYWxNYXAoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcDxLZXksIFQ+KgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpNdXRhYmxlTWFwKCkgeworICBTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGQoKTsKKyAgTWFwPEtleSwgVD4qIHJlc3VsdCA9IE1hcEZpZWxkTGl0ZVR5cGU6Ok11dGFibGVJbnRlcm5hbE1hcCgpOworICBTZXRNYXBEaXJ0eSgpOworICByZXR1cm4gcmVzdWx0OworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpNZXJnZUZyb20oCisgICAgY29uc3QgTWFwRmllbGRMaXRlVHlwZSYgb3RoZXIpIHsKKyAgY29uc3QgTWFwRmllbGQmIGRvd25fb3RoZXIgPSBkb3duX2Nhc3Q8Y29uc3QgTWFwRmllbGQmPihvdGhlcik7CisgIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICBkb3duX290aGVyLlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICBNYXBGaWVsZExpdGVUeXBlOjpNZXJnZUZyb20ob3RoZXIpOworICBTZXRNYXBEaXJ0eSgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTd2FwKAorICAgIE1hcEZpZWxkTGl0ZVR5cGUqIG90aGVyKSB7CisgIE1hcEZpZWxkKiBkb3duX290aGVyID0gZG93bl9jYXN0PE1hcEZpZWxkKj4ob3RoZXIpOworICBzdGQ6OnN3YXAocmVwZWF0ZWRfZmllbGRfLCBkb3duX290aGVyLT5yZXBlYXRlZF9maWVsZF8pOworICBNYXBGaWVsZExpdGVUeXBlOjpTd2FwKG90aGVyKTsKKyAgc3RkOjpzd2FwKHN0YXRlXywgZG93bl9vdGhlci0+c3RhdGVfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6U2V0RW50cnlEZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3IqKiBkZXNjcmlwdG9yKSB7CisgIGVudHJ5X2Rlc2NyaXB0b3JfID0gZGVzY3JpcHRvcjsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6U2V0QXNzaWduRGVzY3JpcHRvckNhbGxiYWNrKHZvaWQgKCpjYWxsYmFjaykoKSkgeworICBhc3NpZ25fZGVzY3JpcHRvcl9jYWxsYmFja18gPSBjYWxsYmFjazsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NvbnN0IE1hcDxLZXksIFQ+JgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpHZXRJbnRlcm5hbE1hcCgpIGNvbnN0IHsKKyAgcmV0dXJuIE1hcEZpZWxkTGl0ZVR5cGU6OkdldEludGVybmFsTWFwKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXA8S2V5LCBUPioKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TXV0YWJsZUludGVybmFsTWFwKCkgeworICByZXR1cm4gTWFwRmllbGRMaXRlVHlwZTo6TXV0YWJsZUludGVybmFsTWFwKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Cit2b2lkCitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OlN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcE5vTG9jaygpIGNvbnN0IHsKKyAgaWYgKHJlcGVhdGVkX2ZpZWxkXyA9PSBOVUxMKSB7CisgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgICByZXBlYXRlZF9maWVsZF8gPSBuZXcgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigpOworICAgIH0gZWxzZSB7CisgICAgICByZXBlYXRlZF9maWVsZF8gPQorICAgICAgICAgIEFyZW5hOjpDcmVhdGU8UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiA+KGFyZW5hXywgYXJlbmFfKTsKKyAgICB9CisgIH0KKyAgY29uc3QgTWFwPEtleSwgVD4mIG1hcCA9IEdldEludGVybmFsTWFwKCk7CisgIFJlcGVhdGVkUHRyRmllbGQ8RW50cnlUeXBlPiogcmVwZWF0ZWRfZmllbGQgPQorICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPEVudHJ5VHlwZT4qPihyZXBlYXRlZF9maWVsZF8pOworCisgIHJlcGVhdGVkX2ZpZWxkLT5DbGVhcigpOworCisgIGZvciAodHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gbWFwLmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwLmVuZCgpOyArK2l0KSB7CisgICAgSW5pdERlZmF1bHRFbnRyeU9uY2UoKTsKKyAgICBHT09HTEVfQ0hFQ0soZGVmYXVsdF9lbnRyeV8gIT0gTlVMTCk7CisgICAgRW50cnlUeXBlKiBuZXdfZW50cnkgPSBkb3duX2Nhc3Q8RW50cnlUeXBlKj4oZGVmYXVsdF9lbnRyeV8tPk5ldyhhcmVuYV8pKTsKKyAgICByZXBlYXRlZF9maWVsZC0+QWRkQWxsb2NhdGVkKG5ld19lbnRyeSk7CisgICAgKCpuZXdfZW50cnktPm11dGFibGVfa2V5KCkpID0gaXQtPmZpcnN0OworICAgICgqbmV3X2VudHJ5LT5tdXRhYmxlX3ZhbHVlKCkpID0gaXQtPnNlY29uZDsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGROb0xvY2soKSBjb25zdCB7CisgIE1hcDxLZXksIFQ+KiBtYXAgPSBjb25zdF9jYXN0PE1hcEZpZWxkKj4odGhpcyktPk11dGFibGVJbnRlcm5hbE1hcCgpOworICBSZXBlYXRlZFB0ckZpZWxkPEVudHJ5VHlwZT4qIHJlcGVhdGVkX2ZpZWxkID0KKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxFbnRyeVR5cGU+Kj4ocmVwZWF0ZWRfZmllbGRfKTsKKyAgbWFwLT5jbGVhcigpOworICBmb3IgKHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RW50cnlUeXBlPjo6aXRlcmF0b3IgaXQgPQorICAgICAgICAgICByZXBlYXRlZF9maWVsZC0+YmVnaW4oKTsgaXQgIT0gcmVwZWF0ZWRfZmllbGQtPmVuZCgpOyArK2l0KSB7CisgICAgLy8gQ2FzdCBpcyBuZWVkZWQgYmVjYXVzZSBNYXAncyBhcGkgYW5kIGludGVybmFsIHN0b3JhZ2UgaXMgZGlmZmVyZW50IHdoZW4KKyAgICAvLyB2YWx1ZSBpcyBlbnVtLiBGb3IgZW51bSwgd2UgY2Fubm90IGNhc3QgYW4gaW50IHRvIGVudW0uIFRodXMsIHdlIGhhdmUgdG8KKyAgICAvLyBjb3B5IHZhbHVlLiBGb3Igb3RoZXIgdHlwZXMsIHRoZXkgaGF2ZSBzYW1lIGV4cG9zZWQgYXBpIHR5cGUgYW5kIGludGVybmFsCisgICAgLy8gc3RvcmVkIHR5cGUuIFdlIHNob3VsZCBub3QgaW50cm9kdWNlIHZhbHVlIGNvcHkgZm9yIHRoZW0uIFdlIGFjaGlldmUgdGhpcworICAgIC8vIGJ5IGNhc3RpbmcgdG8gdmFsdWUgZm9yIGVudW0gd2hpbGUgY2FzdGluZyB0byByZWZlcmVuY2UgZm9yIG90aGVyIHR5cGVzLgorICAgICgqbWFwKVtpdC0+a2V5KCldID0gc3RhdGljX2Nhc3Q8Q2FzdFZhbHVlVHlwZT4oaXQtPnZhbHVlKCkpOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitpbnQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6U3BhY2VVc2VkRXhjbHVkaW5nU2VsZk5vTG9jaygpIGNvbnN0IHsKKyAgaW50IHNpemUgPSAwOworICBpZiAocmVwZWF0ZWRfZmllbGRfICE9IE5VTEwpIHsKKyAgICBzaXplICs9IHJlcGVhdGVkX2ZpZWxkXy0+U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworICB9CisgIE1hcDxLZXksIFQ+KiBtYXAgPSBjb25zdF9jYXN0PE1hcEZpZWxkKj4odGhpcyktPk11dGFibGVJbnRlcm5hbE1hcCgpOworICBzaXplICs9IHNpemVvZigqbWFwKTsKKyAgZm9yICh0eXBlbmFtZSBNYXA8S2V5LCBUPjo6aXRlcmF0b3IgaXQgPSBtYXAtPmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwLT5lbmQoKTsgKytpdCkgeworICAgIHNpemUgKz0gS2V5SGFuZGxlcjo6U3BhY2VVc2VkSW5NYXAoaXQtPmZpcnN0KTsKKyAgICBzaXplICs9IFZhbEhhbmRsZXI6OlNwYWNlVXNlZEluTWFwKGl0LT5zZWNvbmQpOworICB9CisgIHJldHVybiBzaXplOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpJbml0RGVmYXVsdEVudHJ5T25jZSgpCisgICAgY29uc3QgeworICBpZiAoZGVmYXVsdF9lbnRyeV8gPT0gTlVMTCkgeworICAgIEluaXRNZXRhZGF0YU9uY2UoKTsKKyAgICBHT09HTEVfQ0hFQ0soKmVudHJ5X2Rlc2NyaXB0b3JfICE9IE5VTEwpOworICAgIGRlZmF1bHRfZW50cnlfID0gZG93bl9jYXN0PGNvbnN0IEVudHJ5VHlwZSo+KAorICAgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKCplbnRyeV9kZXNjcmlwdG9yXykpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9JTkxfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQ5ZWNjMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2xpdGUuaApAQCAtMCwwICsxLDI3OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9MSVRFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0xJVEVfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeV9saXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWNjZXNzcyB0byBtYXAgZmllbGQgdXNpbmcgZ2VuZXJhdGVkIGFwaS4gSXQgaXMgdXNlZCBmb3IKKy8vIGludGVybmFsIGdlbmVyYXRlZCBtZXNzYWdlIGltcGxlbnRhdGlvbiBvbmx5LiBVc2VycyBzaG91bGQgbmV2ZXIgdXNlIHRoaXMKKy8vIGRpcmVjdGx5LgordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZSA9IDA+CitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWFwRmllbGRMaXRlIHsKKyAgLy8gRGVmaW5lIG1lc3NhZ2UgdHlwZSBmb3IgaW50ZXJuYWwgcmVwZWF0ZWQgZmllbGQuCisgIHR5cGVkZWYgTWFwRW50cnlMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+IEVudHJ5VHlwZTsKKworIHB1YmxpYzoKKyAgTWFwRmllbGRMaXRlKCk7CisgIGV4cGxpY2l0IE1hcEZpZWxkTGl0ZShBcmVuYSogYXJlbmEpOworICB2aXJ0dWFsIH5NYXBGaWVsZExpdGUoKTsKKworICAvLyBBY2Nlc3NvcnMKKyAgdmlydHVhbCBjb25zdCBNYXA8S2V5LCBUPiYgR2V0TWFwKCkgY29uc3Q7CisgIHZpcnR1YWwgTWFwPEtleSwgVD4qIE11dGFibGVNYXAoKTsKKworICAvLyBDb252ZW5pZW50IG1ldGhvZHMgZm9yIGdlbmVyYXRlZCBtZXNzYWdlIGltcGxlbWVudGF0aW9uLgorICB2aXJ0dWFsIGludCBzaXplKCkgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBDbGVhcigpOworICB2aXJ0dWFsIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1hcEZpZWxkTGl0ZSYgb3RoZXIpOworICB2aXJ0dWFsIHZvaWQgU3dhcChNYXBGaWVsZExpdGUqIG90aGVyKTsKKworICAvLyBTZXQgZGVmYXVsdCBlbnVtIHZhbHVlIG9ubHkgZm9yIHByb3RvMiBtYXAgZmllbGQgd2hvc2UgdmFsdWUgaXMgZW51bSB0eXBlLgorICB2b2lkIFNldERlZmF1bHRFbnVtVmFsdWUoKTsKKworICAvLyBVc2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBwYXJzaW5nLiBDYWxsZXIgc2hvdWxkIHRha2UgdGhlIG93bmVyc2hpcC4KKyAgRW50cnlUeXBlKiBOZXdFbnRyeSgpIGNvbnN0OworICAvLyBVc2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBzZXJpYWxpemluZyBlbnVtIHZhbHVlIHR5cGUuIENhbGxlciBzaG91bGQKKyAgLy8gdGFrZSB0aGUgb3duZXJzaGlwLgorICBFbnRyeVR5cGUqIE5ld0VudW1FbnRyeVdyYXBwZXIoY29uc3QgS2V5JiBrZXksIGNvbnN0IFQgdCkgY29uc3Q7CisgIC8vIFVzZWQgaW4gdGhlIGltcGxlbWVudGF0aW9uIG9mIHNlcmlhbGl6aW5nIG90aGVyIHZhbHVlIHR5cGVzLiBDYWxsZXIgc2hvdWxkCisgIC8vIHRha2UgdGhlIG93bmVyc2hpcC4KKyAgRW50cnlUeXBlKiBOZXdFbnRyeVdyYXBwZXIoY29uc3QgS2V5JiBrZXksIGNvbnN0IFQmIHQpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICAvLyBDb252ZW5pZW50IG1ldGhvZHMgdG8gZ2V0IGludGVybmFsIGdvb2dsZTo6cHJvdG9idWY6Ok1hcAorICB2aXJ0dWFsIGNvbnN0IE1hcDxLZXksIFQ+JiBHZXRJbnRlcm5hbE1hcCgpIGNvbnN0OworICB2aXJ0dWFsIE1hcDxLZXksIFQ+KiBNdXRhYmxlSW50ZXJuYWxNYXAoKTsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKworICBBcmVuYSogYXJlbmFfOworICBNYXA8S2V5LCBUPiogbWFwXzsKKworICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWFwRmllbGRMaXRlKCkKKyAgICA6IGFyZW5hXyhOVUxMKSB7CisgIG1hcF8gPSBuZXcgTWFwPEtleSwgVD47CisgIFNldERlZmF1bHRFbnVtVmFsdWUoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpNYXBGaWVsZExpdGUoQXJlbmEqIGFyZW5hKQorICA6IGFyZW5hXyhhcmVuYSkgeworICBtYXBfID0gQXJlbmE6OkNyZWF0ZTxNYXA8S2V5LCBUPiA+KGFyZW5hLCBhcmVuYSk7CisgIFNldERlZmF1bHRFbnVtVmFsdWUoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+Ojp+TWFwRmllbGRMaXRlKCkgeworICBkZWxldGUgbWFwXzsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NvbnN0IE1hcDxLZXksIFQ+JgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OkdldE1hcCgpIGNvbnN0IHsKKyAgcmV0dXJuICptYXBfOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwPEtleSwgVD4qCitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TXV0YWJsZU1hcCgpIHsKKyAgcmV0dXJuIG1hcF87Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitpbnQKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpzaXplKCkgY29uc3QgeworICByZXR1cm4gbWFwXy0+c2l6ZSgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OkNsZWFyKCkgeworICBtYXBfLT5jbGVhcigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok1lcmdlRnJvbSgKKyAgICBjb25zdCBNYXBGaWVsZExpdGUmIG90aGVyKSB7CisgIGZvciAodHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gb3RoZXIubWFwXy0+YmVnaW4oKTsKKyAgICAgICBpdCAhPSBvdGhlci5tYXBfLT5lbmQoKTsgKytpdCkgeworICAgICgqbWFwXylbaXQtPmZpcnN0XSA9IGl0LT5zZWNvbmQ7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTd2FwKAorICAgIE1hcEZpZWxkTGl0ZSogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKG1hcF8sIG90aGVyLT5tYXBfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTZXREZWZhdWx0RW51bVZhbHVlKCkgeworICBNdXRhYmxlSW50ZXJuYWxNYXAoKS0+U2V0RGVmYXVsdEVudW1WYWx1ZShkZWZhdWx0X2VudW1fdmFsdWUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorY29uc3QgTWFwPEtleSwgVD4mCitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6R2V0SW50ZXJuYWxNYXAoKSBjb25zdCB7CisgIHJldHVybiAqbWFwXzsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcDxLZXksIFQ+KgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok11dGFibGVJbnRlcm5hbE1hcCgpIHsKKyAgcmV0dXJuIG1hcF87Cit9CisKKyNkZWZpbmUgRW50cnlUeXBlIFwKKyAgTWFwRW50cnlMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLCBkZWZhdWx0X2VudW1fdmFsdWU+CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitFbnRyeVR5cGUqCitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TmV3RW50cnkoKSBjb25zdCB7CisgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgIHJldHVybiBuZXcgRW50cnlUeXBlKCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIEFyZW5hOjpDcmVhdGVNZXNzYWdlPEVudHJ5VHlwZT4oYXJlbmFfKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorRW50cnlUeXBlKgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok5ld0VudW1FbnRyeVdyYXBwZXIoY29uc3QgS2V5JiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUIHQpIGNvbnN0IHsKKyAgcmV0dXJuIEVudHJ5VHlwZTo6RW51bVdyYXAoa2V5LCB0LCBhcmVuYV8pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorRW50cnlUeXBlKgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok5ld0VudHJ5V3JhcHBlcihjb25zdCBLZXkmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVCYgdCkgY29uc3QgeworICByZXR1cm4gRW50cnlUeXBlOjpXcmFwKGtleSwgdCwgYXJlbmFfKTsKK30KKworI3VuZGVmIEVudHJ5VHlwZQorCisvLyBUcnVlIGlmIElzSW5pdGlhbGl6ZWQoKSBpcyB0cnVlIGZvciB2YWx1ZSBmaWVsZCBpbiBhbGwgZWxlbWVudHMgb2YgdC4gVCBpcworLy8gZXhwZWN0ZWQgdG8gYmUgbWVzc2FnZS4gIEl0J3MgdXNlZnVsIHRvIGhhdmUgdGhpcyBoZWxwZXIgaGVyZSB0byBrZWVwIHRoZQorLy8gcHJvdG9idWYgY29tcGlsZXIgZnJvbSBldmVyIGhhdmluZyB0byBlbWl0IGxvb3BzIGluIElzSW5pdGlhbGl6ZWQoKSBtZXRob2RzLgorLy8gV2Ugd2FudCB0aGUgQysrIGNvbXBpbGVyIHRvIGlubGluZSB0aGlzIG9yIG5vdCBhcyBpdCBzZWVzIGZpdC4KK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+Citib29sIEFsbEFyZUluaXRpYWxpemVkKGNvbnN0IE1hcDxLZXksIFQ+JiB0KSB7CisgIGZvciAodHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gdC5iZWdpbigpOyBpdCAhPSB0LmVuZCgpOworICAgICAgICsraXQpIHsKKyAgICBpZiAoIWl0LT5zZWNvbmQuSXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9MSVRFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjEzNDRjYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX3Rlc3QuY2MKQEAgLTAsMCArMSw0NjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK3VzaW5nIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM7CisKK2NsYXNzIE1hcEZpZWxkQmFzZVN0dWIgOiBwdWJsaWMgTWFwRmllbGRCYXNlIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgTWFwRmllbGRCYXNlU3R1YigpIHt9CisgIGV4cGxpY2l0IE1hcEZpZWxkQmFzZVN0dWIoQXJlbmEqIGFyZW5hKSA6IE1hcEZpZWxkQmFzZShhcmVuYSkge30KKyAgdm9pZCBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKSBjb25zdCB7CisgICAgTWFwRmllbGRCYXNlOjpTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKTsKKyAgfQorICB2b2lkIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpIGNvbnN0IHsKKyAgICBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICB9CisgIC8vIEdldCB1bmRlcmxpbmVkIHJlcGVhdGVkIGZpZWxkIHdpdGhvdXQgc3luY2hyb25pemluZyBtYXAuCisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIEludGVybmFsUmVwZWF0ZWRGaWVsZCgpIHsKKyAgICByZXR1cm4gcmVwZWF0ZWRfZmllbGRfOworICB9CisgIGJvb2wgSXNNYXBDbGVhbigpIHsgcmV0dXJuIHN0YXRlXyAhPSAwOyB9CisgIGJvb2wgSXNSZXBlYXRlZENsZWFuKCkgeyByZXR1cm4gc3RhdGVfICE9IDE7IH0KKyAgdm9pZCBTZXRNYXBEaXJ0eSgpIHsgc3RhdGVfID0gMDsgfQorICB2b2lkIFNldFJlcGVhdGVkRGlydHkoKSB7IHN0YXRlXyA9IDE7IH0KK307CisKK2NsYXNzIE1hcEZpZWxkQmFzZVByaW1pdGl2ZVRlc3QgOiBwdWJsaWMgOjp0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHR5cGVkZWYgTWFwRmllbGQ8aW50MzIsIGludDMyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMiwKKyAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMiwgZmFsc2U+IE1hcEZpZWxkVHlwZTsKKworICBNYXBGaWVsZEJhc2VQcmltaXRpdmVUZXN0KCkgeworICAgIC8vIEdldCBkZXNjcmlwdG9ycworICAgIG1hcF9kZXNjcmlwdG9yXyA9IHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9pbnQzMiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC0+bWVzc2FnZV90eXBlKCk7CisgICAga2V5X2Rlc2NyaXB0b3JfID0gbWFwX2Rlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIHZhbHVlX2Rlc2NyaXB0b3JfID0gbWFwX2Rlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisKKyAgICAvLyBCdWlsZCBtYXAgZmllbGQKKyAgICBkZWZhdWx0X2VudHJ5XyA9CisgICAgICAgIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLT5HZXRQcm90b3R5cGUobWFwX2Rlc2NyaXB0b3JfKTsKKyAgICBtYXBfZmllbGRfLnJlc2V0KG5ldyBNYXBGaWVsZFR5cGUoZGVmYXVsdF9lbnRyeV8pKTsKKyAgICBtYXBfZmllbGRfYmFzZV8gPSBtYXBfZmllbGRfLmdldCgpOworICAgIG1hcF8gPSBtYXBfZmllbGRfLT5NdXRhYmxlTWFwKCk7CisgICAgaW5pdGlhbF92YWx1ZV9tYXBfWzBdID0gMTAwOworICAgIGluaXRpYWxfdmFsdWVfbWFwX1sxXSA9IDEwMTsKKyAgICBtYXBfLT5pbnNlcnQoaW5pdGlhbF92YWx1ZV9tYXBfLmJlZ2luKCksIGluaXRpYWxfdmFsdWVfbWFwXy5lbmQoKSk7CisgICAgRVhQRUNUX0VRKDIsIG1hcF8tPnNpemUoKSk7CisgIH0KKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1hcEZpZWxkVHlwZT4gbWFwX2ZpZWxkXzsKKyAgTWFwRmllbGRCYXNlKiBtYXBfZmllbGRfYmFzZV87CisgIE1hcDxpbnQzMiwgaW50MzI+KiBtYXBfOworICBjb25zdCBEZXNjcmlwdG9yKiBtYXBfZGVzY3JpcHRvcl87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3JfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3JfOworICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5XzsKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBpbml0aWFsX3ZhbHVlX21hcF87ICAvLyBjb3B5IG9mIGluaXRpYWwgdmFsdWVzIGluc2VydGVkCit9OworCitURVNUX0YoTWFwRmllbGRCYXNlUHJpbWl0aXZlVGVzdCwgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZikgeworICBFWFBFQ1RfTFQoMCwgbWFwX2ZpZWxkX2Jhc2VfLT5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkpOworfQorCitURVNUX0YoTWFwRmllbGRCYXNlUHJpbWl0aXZlVGVzdCwgR2V0UmVwZWF0ZWRGaWVsZCkgeworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+JiByZXBlYXRlZCA9CisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4mPigKKyAgICAgICAgICBtYXBfZmllbGRfYmFzZV8tPkdldFJlcGVhdGVkRmllbGQoKSk7CisgIEVYUEVDVF9FUSgyLCByZXBlYXRlZC5zaXplKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSA9IHJlcGVhdGVkLkdldChpKTsKKyAgICBpbnQga2V5ID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UsIGtleV9kZXNjcmlwdG9yXyk7CisgICAgaW50IHZhbHVlID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UsIHZhbHVlX2Rlc2NyaXB0b3JfKTsKKyAgICBFWFBFQ1RfRVEodmFsdWUsIGluaXRpYWxfdmFsdWVfbWFwX1trZXldKTsKKyAgfQorfQorCitURVNUX0YoTWFwRmllbGRCYXNlUHJpbWl0aXZlVGVzdCwgTXV0YWJsZVJlcGVhdGVkRmllbGQpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiogcmVwZWF0ZWQgPQorICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+Kj4oCisgICAgICAgICAgbWFwX2ZpZWxkX2Jhc2VfLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpKTsKKyAgRVhQRUNUX0VRKDIsIHJlcGVhdGVkLT5zaXplKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkLT5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UgPSByZXBlYXRlZC0+R2V0KGkpOworICAgIGludCBrZXkgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZSwga2V5X2Rlc2NyaXB0b3JfKTsKKyAgICBpbnQgdmFsdWUgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZSwgdmFsdWVfZGVzY3JpcHRvcl8pOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgaW5pdGlhbF92YWx1ZV9tYXBfW2tleV0pOworICB9Cit9CisKK1RFU1RfRihNYXBGaWVsZEJhc2VQcmltaXRpdmVUZXN0LCBBcmVuYSkgeworICAvLyBBbGxvY2F0ZSBhIGxhcmdlIGluaXRpYWwgYmxvY2sgdG8gYXZvaWQgbWFsbG9jcyBkdXJpbmcgaG9va2VkIHRlc3QuCisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEyOCAqIDEwMjQpOworICBBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gYXJlbmFfYmxvY2suZGF0YSgpOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgQXJlbmEgYXJlbmEob3B0aW9ucyk7CisKKyAgeworICAgIE5vSGVhcENoZWNrZXIgbm9faGVhcDsKKworICAgIE1hcEZpZWxkVHlwZSogbWFwX2ZpZWxkID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZTxNYXBGaWVsZFR5cGU+KCZhcmVuYSwgJmFyZW5hLCBkZWZhdWx0X2VudHJ5Xyk7CisKKyAgICAvLyBTZXQgY29udGVudCBpbiBtYXAKKyAgICAoKm1hcF9maWVsZC0+TXV0YWJsZU1hcCgpKVsxMDBdID0gMTAxOworCisgICAgLy8gVHJpZ2dlciBjb252ZXJzaW9uIHRvIHJlcGVhdGVkIGZpZWxkLgorICAgIG1hcF9maWVsZC0+R2V0UmVwZWF0ZWRGaWVsZCgpOworICB9CisKKyAgeworICAgIE5vSGVhcENoZWNrZXIgbm9faGVhcDsKKworICAgIE1hcEZpZWxkQmFzZVN0dWIqIG1hcF9maWVsZCA9CisgICAgICAgIEFyZW5hOjpDcmVhdGU8TWFwRmllbGRCYXNlU3R1Yj4oJmFyZW5hLCAmYXJlbmEpOworCisgICAgLy8gVHJpZ2dlciBjb252ZXJzaW9uIHRvIHJlcGVhdGVkIGZpZWxkLgorICAgIEVYUEVDVF9UUlVFKG1hcF9maWVsZC0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKSAhPSBOVUxMKTsKKyAgfQorfQorCituYW1lc3BhY2UgeworZW51bSBTdGF0ZSB7IENMRUFOLCBNQVBfRElSVFksIFJFUEVBVEVEX0RJUlRZIH07Cit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK2NsYXNzIE1hcEZpZWxkU3RhdGVUZXN0CisgICAgOiBwdWJsaWMgdGVzdGluZzo6VGVzdFdpdGhQYXJhbTxTdGF0ZT4geworIHB1YmxpYzoKKyBwcm90ZWN0ZWQ6CisgIHR5cGVkZWYgTWFwRmllbGQ8aW50MzIsIGludDMyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMiwKKyAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMiwgZmFsc2U+IE1hcEZpZWxkVHlwZTsKKyAgdHlwZWRlZiBNYXBGaWVsZExpdGU8aW50MzIsIGludDMyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMiwKKyAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzIsIGZhbHNlPiBNYXBGaWVsZExpdGVUeXBlOworICBNYXBGaWVsZFN0YXRlVGVzdCgpIDogc3RhdGVfKEdldFBhcmFtKCkpIHsKKyAgICAvLyBCdWlsZCBtYXAgZmllbGQKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtYXBfZGVzY3JpcHRvciA9CisgICAgICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkKKyAgICAgICAgICAgIC0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKQorICAgICAgICAgICAgLT5tZXNzYWdlX3R5cGUoKTsKKyAgICBkZWZhdWx0X2VudHJ5XyA9CisgICAgICAgIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLT5HZXRQcm90b3R5cGUobWFwX2Rlc2NyaXB0b3IpOworICAgIG1hcF9maWVsZF8ucmVzZXQobmV3IE1hcEZpZWxkVHlwZShkZWZhdWx0X2VudHJ5XykpOworICAgIG1hcF9maWVsZF9iYXNlXyA9IG1hcF9maWVsZF8uZ2V0KCk7CisKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAwLCAwLCB0cnVlKTsKKyAgICBzd2l0Y2ggKHN0YXRlXykgeworICAgICAgY2FzZSBDTEVBTjoKKyAgICAgICAgQWRkT25lU3RpbGxDbGVhbihtYXBfZmllbGRfLmdldCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE1BUF9ESVJUWToKKyAgICAgICAgTWFrZU1hcERpcnR5KG1hcF9maWVsZF8uZ2V0KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgUkVQRUFURURfRElSVFk6CisgICAgICAgIE1ha2VSZXBlYXRlZERpcnR5KG1hcF9maWVsZF8uZ2V0KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIHZvaWQgQWRkT25lU3RpbGxDbGVhbihNYXBGaWVsZFR5cGUqIG1hcF9maWVsZCkgeworICAgIE1hcEZpZWxkQmFzZSogbWFwX2ZpZWxkX2Jhc2UgPSBtYXBfZmllbGQ7CisgICAgTWFwPGludDMyLCBpbnQzMj4qIG1hcCA9IG1hcF9maWVsZC0+TXV0YWJsZU1hcCgpOworICAgICgqbWFwKVswXSA9IDA7CisgICAgbWFwX2ZpZWxkX2Jhc2UtPkdldFJlcGVhdGVkRmllbGQoKTsKKyAgICBFeHBlY3QobWFwX2ZpZWxkLCBDTEVBTiwgMSwgMSwgZmFsc2UpOworICB9CisKKyAgdm9pZCBNYWtlTWFwRGlydHkoTWFwRmllbGRUeXBlKiBtYXBfZmllbGQpIHsKKyAgICBNYXA8aW50MzIsIGludDMyPiogbWFwID0gbWFwX2ZpZWxkLT5NdXRhYmxlTWFwKCk7CisgICAgKCptYXApWzBdID0gMDsKKyAgICBFeHBlY3QobWFwX2ZpZWxkLCBNQVBfRElSVFksIDEsIDAsIHRydWUpOworICB9CisKKyAgdm9pZCBNYWtlUmVwZWF0ZWREaXJ0eShNYXBGaWVsZFR5cGUqIG1hcF9maWVsZCkgeworICAgIE1ha2VNYXBEaXJ0eShtYXBfZmllbGQpOworICAgIE1hcEZpZWxkQmFzZSogbWFwX2ZpZWxkX2Jhc2UgPSBtYXBfZmllbGQ7CisgICAgbWFwX2ZpZWxkX2Jhc2UtPk11dGFibGVSZXBlYXRlZEZpZWxkKCk7CisgICAgTWFwPGludDMyLCBpbnQzMj4qIG1hcCA9IGltcGxpY2l0X2Nhc3Q8TWFwRmllbGRMaXRlVHlwZSo+KG1hcF9maWVsZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+TWFwRmllbGRMaXRlVHlwZTo6TXV0YWJsZU1hcCgpOworICAgIG1hcC0+Y2xlYXIoKTsKKworICAgIEV4cGVjdChtYXBfZmllbGQsIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisgIH0KKworICB2b2lkIEV4cGVjdChNYXBGaWVsZFR5cGUqIG1hcF9maWVsZCwgU3RhdGUgc3RhdGUsIGludCBtYXBfc2l6ZSwKKyAgICAgICAgICAgICAgaW50IHJlcGVhdGVkX3NpemUsIGJvb2wgaXNfcmVwZWF0ZWRfbnVsbCkgeworICAgIE1hcEZpZWxkQmFzZSogbWFwX2ZpZWxkX2Jhc2UgPSBtYXBfZmllbGQ7CisgICAgTWFwRmllbGRCYXNlU3R1Yiogc3R1YiA9CisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8TWFwRmllbGRCYXNlU3R1Yio+KG1hcF9maWVsZF9iYXNlKTsKKworICAgIE1hcDxpbnQzMiwgaW50MzI+KiBtYXAgPSBpbXBsaWNpdF9jYXN0PE1hcEZpZWxkTGl0ZVR5cGUqPihtYXBfZmllbGQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPk1hcEZpZWxkTGl0ZVR5cGU6Ok11dGFibGVNYXAoKTsKKyAgICBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KiByZXBlYXRlZF9maWVsZCA9IHN0dWItPkludGVybmFsUmVwZWF0ZWRGaWVsZCgpOworCisgICAgc3dpdGNoIChzdGF0ZSkgeworICAgICAgY2FzZSBNQVBfRElSVFk6CisgICAgICAgIEVYUEVDVF9GQUxTRShzdHViLT5Jc01hcENsZWFuKCkpOworICAgICAgICBFWFBFQ1RfVFJVRShzdHViLT5Jc1JlcGVhdGVkQ2xlYW4oKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBSRVBFQVRFRF9ESVJUWToKKyAgICAgICAgRVhQRUNUX1RSVUUoc3R1Yi0+SXNNYXBDbGVhbigpKTsKKyAgICAgICAgRVhQRUNUX0ZBTFNFKHN0dWItPklzUmVwZWF0ZWRDbGVhbigpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIENMRUFOOgorICAgICAgICBFWFBFQ1RfVFJVRShzdHViLT5Jc01hcENsZWFuKCkpOworICAgICAgICBFWFBFQ1RfVFJVRShzdHViLT5Jc1JlcGVhdGVkQ2xlYW4oKSk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgRkFJTCgpOworICAgIH0KKworICAgIEVYUEVDVF9FUShtYXBfc2l6ZSwgbWFwLT5zaXplKCkpOworICAgIGlmIChpc19yZXBlYXRlZF9udWxsKSB7CisgICAgICBFWFBFQ1RfVFJVRShyZXBlYXRlZF9maWVsZCA9PSBOVUxMKTsKKyAgICB9IGVsc2UgeworICAgICAgRVhQRUNUX0VRKHJlcGVhdGVkX3NpemUsIHJlcGVhdGVkX2ZpZWxkLT5zaXplKCkpOworICAgIH0KKyAgfQorCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWFwRmllbGRUeXBlPiBtYXBfZmllbGRfOworICBNYXBGaWVsZEJhc2UqIG1hcF9maWVsZF9iYXNlXzsKKyAgU3RhdGUgc3RhdGVfOworICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5XzsKK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKE1hcEZpZWxkU3RhdGVUZXN0SW5zdGFuY2UsIE1hcEZpZWxkU3RhdGVUZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgOjp0ZXN0aW5nOjpWYWx1ZXMoQ0xFQU4sIE1BUF9ESVJUWSwgUkVQRUFURURfRElSVFkpKTsKKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBHZXRNYXApIHsKKyAgbWFwX2ZpZWxkXy0+R2V0TWFwKCk7CisgIGlmIChzdGF0ZV8gIT0gTUFQX0RJUlRZKSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIENMRUFOLCAxLCAxLCBmYWxzZSk7CisgIH0gZWxzZSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisgIH0KK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBNdXRhYmxlTWFwKSB7CisgIG1hcF9maWVsZF8tPk11dGFibGVNYXAoKTsKKyAgaWYgKHN0YXRlXyAhPSBNQVBfRElSVFkpIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAxLCBmYWxzZSk7CisgIH0gZWxzZSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisgIH0KK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBNZXJnZUZyb21DbGVhbikgeworICBNYXBGaWVsZFR5cGUgb3RoZXIoZGVmYXVsdF9lbnRyeV8pOworICBBZGRPbmVTdGlsbENsZWFuKCZvdGhlcik7CisKKyAgbWFwX2ZpZWxkXy0+TWVyZ2VGcm9tKG90aGVyKTsKKworICBpZiAoc3RhdGVfICE9IE1BUF9ESVJUWSkgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgfQorCisgIEV4cGVjdCgmb3RoZXIsIENMRUFOLCAxLCAxLCBmYWxzZSk7Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgTWVyZ2VGcm9tTWFwRGlydHkpIHsKKyAgTWFwRmllbGRUeXBlIG90aGVyKGRlZmF1bHRfZW50cnlfKTsKKyAgTWFrZU1hcERpcnR5KCZvdGhlcik7CisKKyAgbWFwX2ZpZWxkXy0+TWVyZ2VGcm9tKG90aGVyKTsKKworICBpZiAoc3RhdGVfICE9IE1BUF9ESVJUWSkgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgfQorCisgIEV4cGVjdCgmb3RoZXIsIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgTWVyZ2VGcm9tUmVwZWF0ZWREaXJ0eSkgeworICBNYXBGaWVsZFR5cGUgb3RoZXIoZGVmYXVsdF9lbnRyeV8pOworICBNYWtlUmVwZWF0ZWREaXJ0eSgmb3RoZXIpOworCisgIG1hcF9maWVsZF8tPk1lcmdlRnJvbShvdGhlcik7CisKKyAgaWYgKHN0YXRlXyAhPSBNQVBfRElSVFkpIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAxLCBmYWxzZSk7CisgIH0gZWxzZSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisgIH0KKworICBFeHBlY3QoJm90aGVyLCBDTEVBTiwgMSwgMSwgZmFsc2UpOworfQorCitURVNUX1AoTWFwRmllbGRTdGF0ZVRlc3QsIFN3YXBDbGVhbikgeworICBNYXBGaWVsZFR5cGUgb3RoZXIoZGVmYXVsdF9lbnRyeV8pOworICBBZGRPbmVTdGlsbENsZWFuKCZvdGhlcik7CisKKyAgbWFwX2ZpZWxkXy0+U3dhcCgmb3RoZXIpOworCisgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBDTEVBTiwgMSwgMSwgZmFsc2UpOworCisgIHN3aXRjaCAoc3RhdGVfKSB7CisgICAgY2FzZSBDTEVBTjoKKyAgICAgIEV4cGVjdCgmb3RoZXIsIENMRUFOLCAxLCAxLCBmYWxzZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIE1BUF9ESVJUWToKKyAgICAgIEV4cGVjdCgmb3RoZXIsIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFJFUEVBVEVEX0RJUlRZOgorICAgICAgRXhwZWN0KCZvdGhlciwgUkVQRUFURURfRElSVFksIDAsIDEsIGZhbHNlKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBicmVhazsKKyAgfQorfQorCitURVNUX1AoTWFwRmllbGRTdGF0ZVRlc3QsIFN3YXBNYXBEaXJ0eSkgeworICBNYXBGaWVsZFR5cGUgb3RoZXIoZGVmYXVsdF9lbnRyeV8pOworICBNYWtlTWFwRGlydHkoJm90aGVyKTsKKworICBtYXBfZmllbGRfLT5Td2FwKCZvdGhlcik7CisKKyAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisKKyAgc3dpdGNoIChzdGF0ZV8pIHsKKyAgICBjYXNlIENMRUFOOgorICAgICAgRXhwZWN0KCZvdGhlciwgQ0xFQU4sIDEsIDEsIGZhbHNlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTUFQX0RJUlRZOgorICAgICAgRXhwZWN0KCZvdGhlciwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgUkVQRUFURURfRElSVFk6CisgICAgICBFeHBlY3QoJm90aGVyLCBSRVBFQVRFRF9ESVJUWSwgMCwgMSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgU3dhcFJlcGVhdGVkRGlydHkpIHsKKyAgTWFwRmllbGRUeXBlIG90aGVyKGRlZmF1bHRfZW50cnlfKTsKKyAgTWFrZVJlcGVhdGVkRGlydHkoJm90aGVyKTsKKworICBtYXBfZmllbGRfLT5Td2FwKCZvdGhlcik7CisKKyAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisKKyAgc3dpdGNoIChzdGF0ZV8pIHsKKyAgICBjYXNlIENMRUFOOgorICAgICAgRXhwZWN0KCZvdGhlciwgQ0xFQU4sIDEsIDEsIGZhbHNlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTUFQX0RJUlRZOgorICAgICAgRXhwZWN0KCZvdGhlciwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgUkVQRUFURURfRElSVFk6CisgICAgICBFeHBlY3QoJm90aGVyLCBSRVBFQVRFRF9ESVJUWSwgMCwgMSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgQ2xlYXIpIHsKKyAgbWFwX2ZpZWxkXy0+Q2xlYXIoKTsKKworICBpZiAoc3RhdGVfICE9IE1BUF9ESVJUWSkgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDAsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAwLCAwLCB0cnVlKTsKKyAgfQorfQorCitURVNUX1AoTWFwRmllbGRTdGF0ZVRlc3QsIFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYpIHsKKyAgbWFwX2ZpZWxkX2Jhc2VfLT5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7CisKKyAgc3dpdGNoIChzdGF0ZV8pIHsKKyAgICBjYXNlIENMRUFOOgorICAgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIENMRUFOLCAxLCAxLCBmYWxzZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIE1BUF9ESVJUWToKKyAgICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDAsIHRydWUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBSRVBFQVRFRF9ESVJUWToKKyAgICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBSRVBFQVRFRF9ESVJUWSwgMCwgMSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgR2V0TWFwRmllbGQpIHsKKyAgbWFwX2ZpZWxkX2Jhc2VfLT5HZXRSZXBlYXRlZEZpZWxkKCk7CisKKyAgaWYgKHN0YXRlXyAhPSBSRVBFQVRFRF9ESVJUWSkgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBDTEVBTiwgMSwgMSwgZmFsc2UpOworICB9IGVsc2UgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBSRVBFQVRFRF9ESVJUWSwgMCwgMSwgZmFsc2UpOworICB9Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgTXV0YWJsZU1hcEZpZWxkKSB7CisgIG1hcF9maWVsZF9iYXNlXy0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKTsKKworICBpZiAoc3RhdGVfICE9IFJFUEVBVEVEX0RJUlRZKSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIFJFUEVBVEVEX0RJUlRZLCAxLCAxLCBmYWxzZSk7CisgIH0gZWxzZSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisgIH0KK30KKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV90ZXN0X3V0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjViNGQ2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV90ZXN0X3V0aWwuY2MKQEAgLTAsMCArMSw5MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWxfaW1wbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RNYXBMaXRlKiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6U2V0TWFwRmllbGRzPHVuaXR0ZXN0OjpNYXBFbnVtTGl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUl9MSVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFaX0xJVEU+KG1lc3NhZ2UpOworfQorCit2b2lkIE1hcExpdGVUZXN0VXRpbDo6U2V0QXJlbmFNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RBcmVuYU1hcExpdGUqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpTZXRBcmVuYU1hcEZpZWxkczx1bml0dGVzdDo6TWFwRW51bUxpdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUl9MSVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVpfTElURT4obWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHNJbml0aWFsaXplZCh1bml0dGVzdDo6VGVzdE1hcExpdGUqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpTZXRNYXBGaWVsZHNJbml0aWFsaXplZChtZXNzYWdlKTsKK30KKwordm9pZCBNYXBMaXRlVGVzdFV0aWw6Ok1vZGlmeU1hcEZpZWxkcyh1bml0dGVzdDo6VGVzdE1hcExpdGUqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpNb2RpZnlNYXBGaWVsZHM8dW5pdHRlc3Q6Ok1hcEVudW1MaXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fRk9PX0xJVEU+KG1lc3NhZ2UpOworfQorCit2b2lkIE1hcExpdGVUZXN0VXRpbDo6RXhwZWN0Q2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXBMaXRlJiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXBMaXRlJiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0TWFwRmllbGRzU2V0PHVuaXR0ZXN0OjpNYXBFbnVtTGl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUl9MSVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFaX0xJVEU+KG1lc3NhZ2UpOworfQorCit2b2lkIE1hcExpdGVUZXN0VXRpbDo6RXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcExpdGUmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RBcmVuYU1hcEZpZWxkc1NldDx1bml0dGVzdDo6TWFwRW51bUxpdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUl9MSVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVpfTElURT4oCisgICAgICBtZXNzYWdlKTsKK30KKwordm9pZCBNYXBMaXRlVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwTGl0ZSYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkPHVuaXR0ZXN0OjpNYXBFbnVtTGl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fRk9PX0xJVEU+KAorICAgICAgbWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdE1hcExpdGUmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RNYXBGaWVsZHNNb2RpZmllZDx1bml0dGVzdDo6TWFwRW51bUxpdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUl9MSVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9GT09fTElURT4oCisgICAgICBtZXNzYWdlKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV90ZXN0X3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2I1MzM2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV90ZXN0X3V0aWwuaApAQCAtMCwwICsxLDgwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTUFQX0xJVEVfVEVTVF9VVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0xJVEVfVEVTVF9VVElMX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3VuaXR0ZXN0LnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgTWFwTGl0ZVRlc3RVdGlsIHsKKyBwdWJsaWM6CisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgVGVzdE1hcExpdGUgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKyAgc3RhdGljIHZvaWQgU2V0TWFwRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSogbWVzc2FnZSk7CisKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBUZXN0QXJlbmFNYXBMaXRlIG1lc3NhZ2UgdG8gYSB1bmlxdWUgdmFsdWUuCisgIHN0YXRpYyB2b2lkIFNldEFyZW5hTWFwRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QXJlbmFNYXBMaXRlKiBtZXNzYWdlKTsKKworICAvLyBTZXQgZXZlcnkgZmllbGQgaW4gdGhlIG1lc3NhZ2UgdG8gYSBkZWZhdWx0IHZhbHVlLgorICBzdGF0aWMgdm9pZCBTZXRNYXBGaWVsZHNJbml0aWFsaXplZChwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUqIG1lc3NhZ2UpOworCisgIC8vIE1vZGlmeSBhbGwgdGhlIG1hcCBmaWVsZHMgb2YgdGhlIG1lc3NzYWdlICh3aGljaCBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4KKyAgLy8gaW5pdGlhbGl6ZWQgd2l0aCBTZXRNYXBGaWVsZHMoKSkuCisgIHN0YXRpYyB2b2lkIE1vZGlmeU1hcEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUqIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIHRoZSB2YWx1ZXMgdGhhdCB0aGV5IHNob3VsZCBoYXZlIGFmdGVyCisgIC8vIFNldE1hcEZpZWxkcygpIGlzIGNhbGxlZC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0TWFwRmllbGRzU2V0KGNvbnN0IHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzKCkgaXMgY2FsbGVkIGZvciBUZXN0QXJlbmFNYXBMaXRlLgorICBzdGF0aWMgdm9pZCBFeHBlY3RBcmVuYU1hcEZpZWxkc1NldCgKKyAgICAgIGNvbnN0IHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QXJlbmFNYXBMaXRlJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXRNYXBGaWVsZHNJbml0aWFsaXplZCgpIGlzIGNhbGxlZC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQoCisgICAgICBjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUmIG1lc3NhZ2UpOworCisgIC8vIEV4cGVjdCB0aGF0IHRoZSBtZXNzYWdlIGlzIG1vZGlmaWVkIGFzIHdvdWxkIGJlIGV4cGVjdGVkIGZyb20KKyAgLy8gTW9kaWZ5TWFwRmllbGRzKCkuCisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc01vZGlmaWVkKAorICAgICAgY29uc3QgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgYXJlIGVtcHR5LgorICBzdGF0aWMgdm9pZCBFeHBlY3RDbGVhcihjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUmIG1lc3NhZ2UpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01BUF9MSVRFX1RFU1RfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3VuaXR0ZXN0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2OWU4ZDkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3VuaXR0ZXN0LnByb3RvCkBAIC0wLDAgKzEsMTMzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucHJvdG8iOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCittZXNzYWdlIFRlc3RNYXBMaXRlIHsKKyAgbWFwPGludDMyICAgLCBpbnQzMiAgID4gbWFwX2ludDMyX2ludDMyICAgICAgID0gMTsKKyAgbWFwPGludDY0ICAgLCBpbnQ2NCAgID4gbWFwX2ludDY0X2ludDY0ICAgICAgID0gMjsKKyAgbWFwPHVpbnQzMiAgLCB1aW50MzIgID4gbWFwX3VpbnQzMl91aW50MzIgICAgID0gMzsKKyAgbWFwPHVpbnQ2NCAgLCB1aW50NjQgID4gbWFwX3VpbnQ2NF91aW50NjQgICAgID0gNDsKKyAgbWFwPHNpbnQzMiAgLCBzaW50MzIgID4gbWFwX3NpbnQzMl9zaW50MzIgICAgID0gNTsKKyAgbWFwPHNpbnQ2NCAgLCBzaW50NjQgID4gbWFwX3NpbnQ2NF9zaW50NjQgICAgID0gNjsKKyAgbWFwPGZpeGVkMzIgLCBmaXhlZDMyID4gbWFwX2ZpeGVkMzJfZml4ZWQzMiAgID0gNzsKKyAgbWFwPGZpeGVkNjQgLCBmaXhlZDY0ID4gbWFwX2ZpeGVkNjRfZml4ZWQ2NCAgID0gODsKKyAgbWFwPHNmaXhlZDMyLCBzZml4ZWQzMj4gbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTsKKyAgbWFwPHNmaXhlZDY0LCBzZml4ZWQ2ND4gbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7CisgIG1hcDxpbnQzMiAgICwgZmxvYXQgICA+IG1hcF9pbnQzMl9mbG9hdCAgICAgICA9IDExOworICBtYXA8aW50MzIgICAsIGRvdWJsZSAgPiBtYXBfaW50MzJfZG91YmxlICAgICAgPSAxMjsKKyAgbWFwPGJvb2wgICAgLCBib29sICAgID4gbWFwX2Jvb2xfYm9vbCAgICAgICAgID0gMTM7CisgIG1hcDxzdHJpbmcgICwgc3RyaW5nICA+IG1hcF9zdHJpbmdfc3RyaW5nICAgICA9IDE0OworICBtYXA8aW50MzIgICAsIGJ5dGVzICAgPiBtYXBfaW50MzJfYnl0ZXMgICAgICAgPSAxNTsKKyAgbWFwPGludDMyICAgLCBNYXBFbnVtTGl0ZT4gbWFwX2ludDMyX2VudW0gICAgID0gMTY7CisgIG1hcDxpbnQzMiAgICwgRm9yZWlnbk1lc3NhZ2VMaXRlPiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7CisgIG1hcDxpbnQzMiwgaW50MzI+IHRlYm9yaW5nID0gMTg7Cit9CisKK21lc3NhZ2UgVGVzdEFyZW5hTWFwTGl0ZSB7CisgIG1hcDxpbnQzMiAgICwgaW50MzIgICA+IG1hcF9pbnQzMl9pbnQzMiAgICAgICA9IDE7CisgIG1hcDxpbnQ2NCAgICwgaW50NjQgICA+IG1hcF9pbnQ2NF9pbnQ2NCAgICAgICA9IDI7CisgIG1hcDx1aW50MzIgICwgdWludDMyICA+IG1hcF91aW50MzJfdWludDMyICAgICA9IDM7CisgIG1hcDx1aW50NjQgICwgdWludDY0ICA+IG1hcF91aW50NjRfdWludDY0ICAgICA9IDQ7CisgIG1hcDxzaW50MzIgICwgc2ludDMyICA+IG1hcF9zaW50MzJfc2ludDMyICAgICA9IDU7CisgIG1hcDxzaW50NjQgICwgc2ludDY0ICA+IG1hcF9zaW50NjRfc2ludDY0ICAgICA9IDY7CisgIG1hcDxmaXhlZDMyICwgZml4ZWQzMiA+IG1hcF9maXhlZDMyX2ZpeGVkMzIgICA9IDc7CisgIG1hcDxmaXhlZDY0ICwgZml4ZWQ2NCA+IG1hcF9maXhlZDY0X2ZpeGVkNjQgICA9IDg7CisgIG1hcDxzZml4ZWQzMiwgc2ZpeGVkMzI+IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7CisgIG1hcDxzZml4ZWQ2NCwgc2ZpeGVkNjQ+IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOworICBtYXA8aW50MzIgICAsIGZsb2F0ICAgPiBtYXBfaW50MzJfZmxvYXQgICAgICAgPSAxMTsKKyAgbWFwPGludDMyICAgLCBkb3VibGUgID4gbWFwX2ludDMyX2RvdWJsZSAgICAgID0gMTI7CisgIG1hcDxib29sICAgICwgYm9vbCAgICA+IG1hcF9ib29sX2Jvb2wgICAgICAgICA9IDEzOworICBtYXA8aW50MzIgICAsIE1hcEVudW1MaXRlPiBtYXBfaW50MzJfZW51bSAgICAgPSAxNDsKKyAgbWFwPGludDMyICAgLCBGb3JlaWduTWVzc2FnZUFyZW5hTGl0ZT4gbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE1OworfQorCisvLyBUZXN0IGVtYmVkZWQgbWVzc2FnZSB3aXRoIHJlcXVpcmVkIGZpZWxkcworbWVzc2FnZSBUZXN0UmVxdWlyZWRNZXNzYWdlTWFwTGl0ZSB7CisgIG1hcDxpbnQzMiwgVGVzdFJlcXVpcmVkTGl0ZT4gbWFwX2ZpZWxkID0gMTsKK30KKworbWVzc2FnZSBUZXN0RW51bVN0YXJ0V2l0aE5vblplcm9NYXBMaXRlIHsKKyAgbWFwPGludDMyLCBQcm90bzJNYXBFbnVtU3RhcnRXaXRoTm9uWmVyb0xpdGU+IG1hcF9maWVsZCA9IDEwMTsKK30KKworbWVzc2FnZSBUZXN0RW51bU1hcExpdGUgeworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW1MaXRlPiBrbm93bl9tYXBfZmllbGQgPSAxMDE7CisgIG1hcDxpbnQzMiwgUHJvdG8yTWFwRW51bUxpdGU+IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOworfQorCittZXNzYWdlIFRlc3RFbnVtTWFwUGx1c0V4dHJhTGl0ZSB7CisgIG1hcDxpbnQzMiwgUHJvdG8yTWFwRW51bVBsdXNFeHRyYUxpdGU+IGtub3duX21hcF9maWVsZCA9IDEwMTsKKyAgbWFwPGludDMyLCBQcm90bzJNYXBFbnVtUGx1c0V4dHJhTGl0ZT4gdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7Cit9CisKK21lc3NhZ2UgVGVzdE1lc3NhZ2VNYXBMaXRlIHsKKyAgbWFwPGludDMyLCBUZXN0QWxsVHlwZXNMaXRlPiBtYXBfaW50MzJfbWVzc2FnZSA9IDE7Cit9CisKK2VudW0gUHJvdG8yTWFwRW51bUxpdGUgeworICBQUk9UTzJfTUFQX0VOVU1fRk9PX0xJVEUgPSAwOworICBQUk9UTzJfTUFQX0VOVU1fQkFSX0xJVEUgPSAxOworICBQUk9UTzJfTUFQX0VOVU1fQkFaX0xJVEUgPSAyOworfQorCitlbnVtIFByb3RvMk1hcEVudW1QbHVzRXh0cmFMaXRlIHsKKyAgRV9QUk9UTzJfTUFQX0VOVU1fRk9PX0xJVEUgICA9IDA7CisgIEVfUFJPVE8yX01BUF9FTlVNX0JBUl9MSVRFICAgPSAxOworICBFX1BST1RPMl9NQVBfRU5VTV9CQVpfTElURSAgID0gMjsKKyAgRV9QUk9UTzJfTUFQX0VOVU1fRVhUUkFfTElURSA9IDM7Cit9CisKK2VudW0gUHJvdG8yTWFwRW51bVN0YXJ0V2l0aE5vblplcm9MaXRlIHsKKyAgUFJPVE8yX05PTl9aRVJPX01BUF9FTlVNX0ZPT19MSVRFID0gMTsKK30KKworZW51bSBNYXBFbnVtTGl0ZSB7CisgIE1BUF9FTlVNX0ZPT19MSVRFID0gMDsKKyAgTUFQX0VOVU1fQkFSX0xJVEUgPSAxOworICBNQVBfRU5VTV9CQVpfTElURSA9IDI7Cit9CisKK21lc3NhZ2UgVGVzdFJlcXVpcmVkTGl0ZSB7CisgIHJlcXVpcmVkIGludDMyIGEgPSAxOworICByZXF1aXJlZCBpbnQzMiBiID0gMjsKKyAgcmVxdWlyZWQgaW50MzIgYyA9IDM7Cit9CisKK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2VBcmVuYUxpdGUgeworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDRhZjI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnByb3RvCkBAIC0wLDAgKzEsNjggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8yIjsKKworCisvLyBXZSBkb24ndCBwdXQgdGhpcyBpbiBhIHBhY2thZ2Ugd2l0aGluIHByb3RvMiBiZWNhdXNlIHdlIG5lZWQgdG8gbWFrZSBzdXJlCisvLyB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZSBkb2Vzbid0IGRlcGVuZCBvbiBiZWluZyBpbiB0aGUgcHJvdG8yIG5hbWVzcGFjZS4KKy8vIEluIG1hcF90ZXN0X3V0aWwuaCB3ZSBkbyAidXNpbmcgbmFtZXNwYWNlIHVuaXR0ZXN0ID0gcHJvdG9idWZfdW5pdHRlc3QiLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworZW51bSBQcm90bzJNYXBFbnVtIHsKKyAgUFJPVE8yX01BUF9FTlVNX0ZPTyAgID0gMDsKKyAgUFJPVE8yX01BUF9FTlVNX0JBUiAgID0gMTsKKyAgUFJPVE8yX01BUF9FTlVNX0JBWiAgID0gMjsKK30KKworZW51bSBQcm90bzJNYXBFbnVtUGx1c0V4dHJhIHsKKyAgRV9QUk9UTzJfTUFQX0VOVU1fRk9PICAgPSAwOworICBFX1BST1RPMl9NQVBfRU5VTV9CQVIgICA9IDE7CisgIEVfUFJPVE8yX01BUF9FTlVNX0JBWiAgID0gMjsKKyAgRV9QUk9UTzJfTUFQX0VOVU1fRVhUUkEgPSAzOworfQorCitlbnVtIFByb3RvMk1hcEVudW1TdGFydFdpdGhOb25aZXJvIHsKKyAgUFJPVE8yX05PTl9aRVJPX01BUF9FTlVNX0ZPTyA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdEVudW1NYXAgeworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW0+IGtub3duX21hcF9maWVsZCA9IDEwMTsKKyAgbWFwPGludDMyLCBQcm90bzJNYXBFbnVtPiB1bmtub3duX21hcF9maWVsZCA9IDEwMjsKK30KKworbWVzc2FnZSBUZXN0RW51bU1hcFBsdXNFeHRyYSB7CisgIG1hcDxpbnQzMiwgUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4ga25vd25fbWFwX2ZpZWxkID0gMTAxOworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOworfQorCittZXNzYWdlIFRlc3RFbnVtU3RhcnRXaXRoTm9uWmVyb01hcCB7CisgIG1hcDxpbnQzMiwgUHJvdG8yTWFwRW51bVN0YXJ0V2l0aE5vblplcm8+IG1hcF9maWVsZCA9IDEwMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4Y2JhMWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LmNjCkBAIC0wLDAgKzEsMjMxMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9wcm90bzJfdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXAuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdEFsbFR5cGVzOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RNYXA7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBNYXAgQVBJIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgTWFwSW1wbFRlc3QgOiBwdWJsaWMgOjp0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIE1hcEltcGxUZXN0KCkKKyAgICAgIDogbWFwX3B0cl8obmV3IE1hcDxpbnQzMiwgaW50MzI+KSwKKyAgICAgICAgbWFwXygqbWFwX3B0cl8pLAorICAgICAgICBjb25zdF9tYXBfKCptYXBfcHRyXykgeworICAgIEVYUEVDVF9UUlVFKG1hcF8uZW1wdHkoKSk7CisgICAgRVhQRUNUX0VRKDAsIG1hcF8uc2l6ZSgpKTsKKyAgfQorICB+TWFwSW1wbFRlc3QoKSB7fQorCisgIHZvaWQgRXhwZWN0U2luZ2xlRWxlbWVudChpbnQzMiBrZXksIGludDMyIHZhbHVlKSB7CisgICAgRVhQRUNUX0ZBTFNFKG1hcF8uZW1wdHkoKSk7CisgICAgRVhQRUNUX0VRKDEsIG1hcF8uc2l6ZSgpKTsKKyAgICBFeHBlY3RFbGVtZW50KGtleSwgdmFsdWUpOworICB9CisKKyAgdm9pZCBFeHBlY3RFbGVtZW50cyhjb25zdCBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+JiBtYXApIHsKKyAgICBFWFBFQ1RfRkFMU0UobWFwXy5lbXB0eSgpKTsKKyAgICBFWFBFQ1RfRVEobWFwLnNpemUoKSwgbWFwXy5zaXplKCkpOworICAgIGZvciAoc3RkOjptYXA8aW50MzIsIGludDMyPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXAuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IG1hcC5lbmQoKTsgKytpdCkgeworICAgICAgRXhwZWN0RWxlbWVudChpdC0+Zmlyc3QsIGl0LT5zZWNvbmQpOworICAgIH0KKyAgfQorCisgIHZvaWQgRXhwZWN0RWxlbWVudChpbnQzMiBrZXksIGludDMyIHZhbHVlKSB7CisgICAgLy8gVGVzdCBtYXAgc2l6ZSBpcyBjb3JyZWN0LgorICAgIEVYUEVDVF9FUSh2YWx1ZSwgbWFwX1trZXldKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWFwXy5jb3VudChrZXkpKTsKKworICAgIC8vIENoZWNrIG11dGFibGUgYXQgYW5kIGZpbmQgd29yayBjb3JyZWN0bHkuCisgICAgRVhQRUNUX0VRKHZhbHVlLCBtYXBfLmF0KGtleSkpOworICAgIE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciBpdCA9IG1hcF8uZmluZChrZXkpOworCisgICAgLy8gaW50ZXJhdG9yIGRlcmVmZXJlbmNlYWJsZQorICAgIEVYUEVDVF9FUShrZXksICAgKCppdCkuZmlyc3QpOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgKCppdCkuc2Vjb25kKTsKKyAgICBFWFBFQ1RfRVEoa2V5LCAgIGl0LT5maXJzdCk7CisgICAgRVhQRUNUX0VRKHZhbHVlLCBpdC0+c2Vjb25kKTsKKworICAgIC8vIGl0ZXJhdG9yIG11dGFibGUKKyAgICAoKCppdCkuc2Vjb25kKSA9IHZhbHVlICsgMTsKKyAgICBFWFBFQ1RfRVEodmFsdWUgKyAxLCBtYXBfW2tleV0pOworICAgICgoKml0KS5zZWNvbmQpID0gdmFsdWU7CisgICAgRVhQRUNUX0VRKHZhbHVlLCBtYXBfW2tleV0pOworCisgICAgaXQtPnNlY29uZCA9IHZhbHVlICsgMTsKKyAgICBFWFBFQ1RfRVEodmFsdWUgKyAxLCBtYXBfW2tleV0pOworICAgIGl0LT5zZWNvbmQgPSB2YWx1ZTsKKyAgICBFWFBFQ1RfRVEodmFsdWUsIG1hcF9ba2V5XSk7CisKKyAgICAvLyBjb3B5IGNvbnN0cnVjdG9yCisgICAgTWFwPGludDMyLCBpbnQzMj46Oml0ZXJhdG9yIGl0X2NvcHkgPSBpdDsKKyAgICBFWFBFQ1RfRVEoa2V5LCBpdF9jb3B5LT5maXJzdCk7CisgICAgRVhQRUNUX0VRKHZhbHVlLCBpdF9jb3B5LT5zZWNvbmQpOworCisgICAgLy8gSW1tdXRhYmxlIEFQSSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICAgIC8vIENoZWNrIGltbXV0YWJsZSBhdCBhbmQgZmluZCB3b3JrIGNvcnJlY3RseS4KKyAgICBFWFBFQ1RfRVEodmFsdWUsIGNvbnN0X21hcF8uYXQoa2V5KSk7CisgICAgTWFwPGludDMyLCBpbnQzMj46OmNvbnN0X2l0ZXJhdG9yIGNvbnN0X2l0ID0gY29uc3RfbWFwXy5maW5kKGtleSk7CisKKyAgICAvLyBpbnRlcmF0b3IgZGVyZWZlcmVuY2VhYmxlCisgICAgRVhQRUNUX0VRKGtleSwgKCpjb25zdF9pdCkuZmlyc3QpOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgKCpjb25zdF9pdCkuc2Vjb25kKTsKKyAgICBFWFBFQ1RfRVEoa2V5LCBjb25zdF9pdC0+Zmlyc3QpOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgY29uc3RfaXQtPnNlY29uZCk7CisKKyAgICAvLyBjb3B5IGNvbnN0cnVjdG9yCisgICAgTWFwPGludDMyLCBpbnQzMj46OmNvbnN0X2l0ZXJhdG9yIGNvbnN0X2l0X2NvcHkgPSBjb25zdF9pdDsKKyAgICBFWFBFQ1RfRVEoa2V5LCBjb25zdF9pdF9jb3B5LT5maXJzdCk7CisgICAgRVhQRUNUX0VRKHZhbHVlLCBjb25zdF9pdF9jb3B5LT5zZWNvbmQpOworICB9CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNYXA8aW50MzIsIGludDMyPiA+IG1hcF9wdHJfOworICBNYXA8aW50MzIsIGludDMyPiYgbWFwXzsKKyAgY29uc3QgTWFwPGludDMyLCBpbnQzMj4mIGNvbnN0X21hcF87Cit9OworCitURVNUX0YoTWFwSW1wbFRlc3QsIE9wZXJhdG9yQnJhY2tldCkgeworICBpbnQzMiBrZXkgPSAwOworICBpbnQzMiB2YWx1ZTEgPSAxMDA7CisgIGludDMyIHZhbHVlMiA9IDEwMTsKKworICBFWFBFQ1RfRVEoMCwgbWFwX1trZXldKTsKKworICBtYXBfW2tleV0gPSB2YWx1ZTE7CisgIEV4cGVjdFNpbmdsZUVsZW1lbnQoa2V5LCB2YWx1ZTEpOworCisgIG1hcF9ba2V5XSA9IHZhbHVlMjsKKyAgRXhwZWN0U2luZ2xlRWxlbWVudChrZXksIHZhbHVlMik7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgT3BlcmF0b3JCcmFja2V0Tm9uRXhpc3QpIHsKKyAgaW50MzIga2V5ID0gMDsKKyAgaW50MzIgZGVmYXVsdF92YWx1ZSA9IDA7CisKKyAgRVhQRUNUX0VRKGRlZmF1bHRfdmFsdWUsIG1hcF9ba2V5XSk7CisgIEV4cGVjdFNpbmdsZUVsZW1lbnQoa2V5LCBkZWZhdWx0X3ZhbHVlKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBNdXRhYmxlQXQpIHsKKyAgaW50MzIga2V5ID0gMDsKKyAgaW50MzIgdmFsdWUxID0gMTAwOworICBpbnQzMiB2YWx1ZTIgPSAxMDE7CisKKyAgbWFwX1trZXldID0gdmFsdWUxOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUxKTsKKworICBtYXBfLmF0KGtleSkgPSB2YWx1ZTI7CisgIEV4cGVjdFNpbmdsZUVsZW1lbnQoa2V5LCB2YWx1ZTIpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVF9GKE1hcEltcGxUZXN0LCBNdXRhYmxlQXROb25FeGlzdERlYXRoVGVzdCkgeworICBFWFBFQ1RfREVBVEgobWFwXy5hdCgwKSwgIiIpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIEltbXV0YWJsZUF0Tm9uRXhpc3REZWF0aFRlc3QpIHsKKyAgRVhQRUNUX0RFQVRIKGNvbnN0X21hcF8uYXQoMCksICIiKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUX0YoTWFwSW1wbFRlc3QsIENvdW50Tm9uRXhpc3QpIHsKKyAgRVhQRUNUX0VRKDAsIG1hcF8uY291bnQoMCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIE11dGFibGVGaW5kTm9uRXhpc3QpIHsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoMCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIEltbXV0YWJsZUZpbmROb25FeGlzdCkgeworICBFWFBFQ1RfVFJVRShjb25zdF9tYXBfLmVuZCgpID09IGNvbnN0X21hcF8uZmluZCgwKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgQ29uc3RFbmQpIHsKKyAgRVhQRUNUX1RSVUUoY29uc3RfbWFwXy5lbmQoKSA9PSBjb25zdF9tYXBfLmNlbmQoKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgR2V0UmVmZXJlbmNlRnJvbUl0ZXJhdG9yKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIG1hcF9baV0gPSBpOworICB9CisKKyAgZm9yIChNYXA8aW50MzIsIGludDMyPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfLmNiZWdpbigpOworICAgICAgIGl0ICE9IG1hcF8uY2VuZCgpOykgeworICAgIE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9yZWZlcmVuY2UgZW50cnkgPSAqaXQrKzsKKyAgICBFWFBFQ1RfRVEoZW50cnkuZmlyc3QsIGVudHJ5LnNlY29uZCk7CisgIH0KKworICBmb3IgKE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvciBpdCA9IGNvbnN0X21hcF8uYmVnaW4oKTsKKyAgICAgICBpdCAhPSBjb25zdF9tYXBfLmVuZCgpOykgeworICAgIE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9yZWZlcmVuY2UgZW50cnkgPSAqaXQrKzsKKyAgICBFWFBFQ1RfRVEoZW50cnkuZmlyc3QsIGVudHJ5LnNlY29uZCk7CisgIH0KKworICBmb3IgKE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciBpdCA9IG1hcF8uYmVnaW4oKTsgaXQgIT0gbWFwXy5lbmQoKTspIHsKKyAgICBNYXA8aW50MzIsIGludDMyPjo6cmVmZXJlbmNlIGVudHJ5ID0gKml0Kys7CisgICAgRVhQRUNUX0VRKGVudHJ5LmZpcnN0ICsgMSwgKytlbnRyeS5zZWNvbmQpOworICB9Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSXRlcmF0b3JCYXNpYykgeworICBtYXBfWzBdID0gMDsKKworICAvLyBEZWZhdWx0IGNvbnN0cnVjdGlibGUgKHBlciBmb3J3YXJkIGl0ZXJhdG9yIHJlcXVpcmVtZW50cykuCisgIE1hcDxpbnQsIGludD46OmNvbnN0X2l0ZXJhdG9yIGNpdDsKKyAgTWFwPGludCwgaW50Pjo6aXRlcmF0b3IgaXQ7CisKKyAgaXQgPSBtYXBfLmJlZ2luKCk7CisgIGNpdCA9IGl0OyAgLy8gQ29udmVydHMgdG8gY29uc3RfaXRlcmF0b3IKKworICAvLyBDYW4gY29tcGFyZSBiZXR3ZWVuIHRoZW0uCisgIEVYUEVDVF9UUlVFKGl0ID09IGNpdCk7CisgIEVYUEVDVF9GQUxTRShjaXQgIT0gaXQpOworCisgIC8vIFByZSBpbmNyZW1lbnQuCisgIEVYUEVDVF9GQUxTRShpdCA9PSArK2NpdCk7CisKKyAgLy8gUG9zdCBpbmNyZW1lbnQuCisgIEVYUEVDVF9GQUxTRShpdCsrID09IGNpdCk7CisgIEVYUEVDVF9UUlVFKGl0ID09IGNpdCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorYm9vbCBJc0NvbnN0SGVscGVyKFQmIC8qdCovKSB7ICAvLyBOT0xJTlQuIFdlIHdhbnQgdG8gY2F0Y2ggbm9uLWNvbnN0IHJlZnMgaGVyZS4KKyAgcmV0dXJuIGZhbHNlOworfQordGVtcGxhdGUgPHR5cGVuYW1lIFQ+Citib29sIElzQ29uc3RIZWxwZXIoY29uc3QgVCYgLyp0Ki8pIHsKKyAgcmV0dXJuIHRydWU7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSXRlcmF0b3JDb25zdG5lc3MpIHsKKyAgbWFwX1swXSA9IDA7CisgIEVYUEVDVF9UUlVFKElzQ29uc3RIZWxwZXIoKm1hcF8uY2JlZ2luKCkpKTsKKyAgRVhQRUNUX1RSVUUoSXNDb25zdEhlbHBlcigqY29uc3RfbWFwXy5iZWdpbigpKSk7CisgIEVYUEVDVF9GQUxTRShJc0NvbnN0SGVscGVyKCptYXBfLmJlZ2luKCkpKTsKK30KKworYm9vbCBJc0ZvcndhcmRJdGVyYXRvckhlbHBlcihzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnIC8qdGFnKi8pIHsgcmV0dXJuIHRydWU7IH0KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorYm9vbCBJc0ZvcndhcmRJdGVyYXRvckhlbHBlcihUIC8qdCovKSB7CisgIHJldHVybiBmYWxzZTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBJdGVyYXRvckNhdGVnb3J5KSB7CisgIEVYUEVDVF9UUlVFKElzRm9yd2FyZEl0ZXJhdG9ySGVscGVyKAorICAgICAgc3RkOjppdGVyYXRvcl90cmFpdHM8TWFwPGludCwgaW50Pjo6aXRlcmF0b3I+OjppdGVyYXRvcl9jYXRlZ29yeSgpKSk7CisgIEVYUEVDVF9UUlVFKElzRm9yd2FyZEl0ZXJhdG9ySGVscGVyKHN0ZDo6aXRlcmF0b3JfdHJhaXRzPAorICAgICAgTWFwPGludCwgaW50Pjo6Y29uc3RfaXRlcmF0b3I+OjppdGVyYXRvcl9jYXRlZ29yeSgpKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSW5zZXJ0U2luZ2xlKSB7CisgIGludDMyIGtleSA9IDA7CisgIGludDMyIHZhbHVlMSA9IDEwMDsKKyAgaW50MzIgdmFsdWUyID0gMTAxOworCisgIC8vIEluc2VydCBhIG5vbi1leGlzdGVkIGtleS4KKyAgc3RkOjpwYWlyPE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciwgYm9vbD4gcmVzdWx0MSA9CisgICAgICBtYXBfLmluc2VydChNYXA8aW50MzIsIGludDMyPjo6dmFsdWVfdHlwZShrZXksIHZhbHVlMSkpOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUxKTsKKworICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQxID0gcmVzdWx0MS5maXJzdDsKKyAgRVhQRUNUX0VRKGtleSwgaXQxLT5maXJzdCk7CisgIEVYUEVDVF9FUSh2YWx1ZTEsIGl0MS0+c2Vjb25kKTsKKyAgRVhQRUNUX1RSVUUocmVzdWx0MS5zZWNvbmQpOworCisgIC8vIEluc2VydCBhbiBleGlzdGVkIGtleS4KKyAgc3RkOjpwYWlyPE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciwgYm9vbD4gcmVzdWx0MiA9CisgICAgICBtYXBfLmluc2VydChNYXA8aW50MzIsIGludDMyPjo6dmFsdWVfdHlwZShrZXksIHZhbHVlMikpOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUxKTsKKworICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQyID0gcmVzdWx0Mi5maXJzdDsKKyAgRVhQRUNUX1RSVUUoaXQxID09IGl0Mik7CisgIEVYUEVDVF9GQUxTRShyZXN1bHQyLnNlY29uZCk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSW5zZXJ0QnlJdGVyYXRvcikgeworICBpbnQzMiBrZXkxID0gMDsKKyAgaW50MzIga2V5MiA9IDE7CisgIGludDMyIHZhbHVlMWEgPSAxMDA7CisgIGludDMyIHZhbHVlMWIgPSAxMDE7CisgIGludDMyIHZhbHVlMmEgPSAyMDA7CisgIGludDMyIHZhbHVlMmIgPSAyMDE7CisKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXAxOworICBtYXAxW2tleTFdID0gdmFsdWUxYTsKKyAgbWFwMVtrZXkyXSA9IHZhbHVlMmE7CisKKyAgbWFwXy5pbnNlcnQobWFwMS5iZWdpbigpLCBtYXAxLmVuZCgpKTsKKyAgRXhwZWN0RWxlbWVudHMobWFwMSk7CisKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXAyOworICBtYXAyW2tleTFdID0gdmFsdWUxYjsKKyAgbWFwMltrZXkyXSA9IHZhbHVlMmI7CisKKyAgbWFwXy5pbnNlcnQobWFwMi5iZWdpbigpLCBtYXAyLmVuZCgpKTsKKyAgRXhwZWN0RWxlbWVudHMobWFwMSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgRXJhc2VTaW5nbGVCeUtleSkgeworICBpbnQzMiBrZXkgPSAwOworICBpbnQzMiB2YWx1ZSA9IDEwMDsKKworICBtYXBfW2tleV0gPSB2YWx1ZTsKKyAgRXhwZWN0U2luZ2xlRWxlbWVudChrZXksIHZhbHVlKTsKKworICAvLyBFcmFzZSBhbiBleGlzdGluZyBrZXkuCisgIEVYUEVDVF9FUSgxLCBtYXBfLmVyYXNlKGtleSkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoMCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChrZXkpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5iZWdpbigpID09IG1hcF8uZW5kKCkpOworCisgIC8vIEVyYXNlIGEgbm9uLWV4aXN0aW5nIGtleS4KKyAgRVhQRUNUX0VRKDAsIG1hcF8uZXJhc2Uoa2V5KSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgRXJhc2VNdXRpcGxlQnlLZXkpIHsKKyAgLy8gZXJhc2UgaW4gb25lIHNwZWNpZmljIG9yZGVyIHRvIHRyaWdnZXIgY29ybmVyIGNhc2VzCisgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgbWFwX1tpXSA9IGk7CisgIH0KKworICBtYXBfLmVyYXNlKDApOworICBFWFBFQ1RfRVEoNCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZCgwKSk7CisKKyAgbWFwXy5lcmFzZSgxKTsKKyAgRVhQRUNUX0VRKDMsIG1hcF8uc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoMSkpOworCisgIG1hcF8uZXJhc2UoMyk7CisgIEVYUEVDVF9FUSgyLCBtYXBfLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gbWFwXy5maW5kKDMpKTsKKworICBtYXBfLmVyYXNlKDQpOworICBFWFBFQ1RfRVEoMSwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZCg0KSk7CisKKyAgbWFwXy5lcmFzZSgyKTsKKyAgRVhQRUNUX0VRKDAsIG1hcF8uc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoMikpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIEVyYXNlU2luZ2xlQnlJdGVyYXRvcikgeworICBpbnQzMiBrZXkgPSAwOworICBpbnQzMiB2YWx1ZSA9IDEwMDsKKworICBtYXBfW2tleV0gPSB2YWx1ZTsKKyAgRXhwZWN0U2luZ2xlRWxlbWVudChrZXksIHZhbHVlKTsKKworICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQgPSBtYXBfLmZpbmQoa2V5KTsKKyAgbWFwXy5lcmFzZShpdCk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW1wdHkoKSk7CisgIEVYUEVDVF9FUSgwLCBtYXBfLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gbWFwXy5maW5kKGtleSkpOworICBFWFBFQ1RfVFJVRShtYXBfLmJlZ2luKCkgPT0gbWFwXy5lbmQoKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgVmFsaWRJdGVyYXRvckFmdGVyRXJhc2UpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgbWFwX1tpXSA9IGk7CisgIH0KKworICBpbnQgY291bnQgPSAwOworCisgIGZvciAoTWFwPGludDMyLCBpbnQzMj46Oml0ZXJhdG9yIGl0ID0gbWFwXy5iZWdpbigpOyBpdCAhPSBtYXBfLmVuZCgpOykgeworICAgIGNvdW50Kys7CisgICAgaWYgKGl0LT5maXJzdCAlIDIgPT0gMSkgeworICAgICAgbWFwXy5lcmFzZShpdCsrKTsKKyAgICB9IGVsc2UgeworICAgICAgKytpdDsKKyAgICB9CisgIH0KKworICBFWFBFQ1RfRVEoMTAsIGNvdW50KTsKKyAgRVhQRUNUX0VRKDUsIG1hcF8uc2l6ZSgpKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBFcmFzZUJ5SXRlcmF0b3IpIHsKKyAgaW50MzIga2V5MSA9IDA7CisgIGludDMyIGtleTIgPSAxOworICBpbnQzMiB2YWx1ZTEgPSAxMDA7CisgIGludDMyIHZhbHVlMiA9IDEwMTsKKworICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgbWFwW2tleTFdID0gdmFsdWUxOworICBtYXBba2V5Ml0gPSB2YWx1ZTI7CisKKyAgbWFwXy5pbnNlcnQobWFwLmJlZ2luKCksIG1hcC5lbmQoKSk7CisgIEV4cGVjdEVsZW1lbnRzKG1hcCk7CisKKyAgbWFwXy5lcmFzZShtYXBfLmJlZ2luKCksIG1hcF8uZW5kKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoMCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChrZXkxKSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gbWFwXy5maW5kKGtleTIpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5iZWdpbigpID09IG1hcF8uZW5kKCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIENsZWFyKSB7CisgIGludDMyIGtleSA9IDA7CisgIGludDMyIHZhbHVlID0gMTAwOworCisgIG1hcF9ba2V5XSA9IHZhbHVlOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUpOworCisgIG1hcF8uY2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoMCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChrZXkpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5iZWdpbigpID09IG1hcF8uZW5kKCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIENvcHlDb25zdHJ1Y3RvcikgeworICBpbnQzMiBrZXkxID0gMDsKKyAgaW50MzIga2V5MiA9IDE7CisgIGludDMyIHZhbHVlMSA9IDEwMDsKKyAgaW50MzIgdmFsdWUyID0gMTAxOworCisgIHN0ZDo6bWFwPGludDMyLCBpbnQzMj4gbWFwOworICBtYXBba2V5MV0gPSB2YWx1ZTE7CisgIG1hcFtrZXkyXSA9IHZhbHVlMjsKKworICBtYXBfLmluc2VydChtYXAuYmVnaW4oKSwgbWFwLmVuZCgpKTsKKworICBNYXA8aW50MzIsIGludDMyPiBvdGhlcihtYXBfKTsKKworICBFWFBFQ1RfRVEoMiwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlMSwgb3RoZXIuYXQoa2V5MSkpOworICBFWFBFQ1RfRVEodmFsdWUyLCBvdGhlci5hdChrZXkyKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgQXNzaWduZXIpIHsKKyAgaW50MzIga2V5MSA9IDA7CisgIGludDMyIGtleTIgPSAxOworICBpbnQzMiB2YWx1ZTEgPSAxMDA7CisgIGludDMyIHZhbHVlMiA9IDEwMTsKKworICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgbWFwW2tleTFdID0gdmFsdWUxOworICBtYXBba2V5Ml0gPSB2YWx1ZTI7CisKKyAgbWFwXy5pbnNlcnQobWFwLmJlZ2luKCksIG1hcC5lbmQoKSk7CisKKyAgTWFwPGludDMyLCBpbnQzMj4gb3RoZXI7CisgIGludDMyIGtleV9vdGhlciA9IDEyMzsKKyAgaW50MzIgdmFsdWVfb3RoZXIgPSAzMjE7CisgIG90aGVyW2tleV9vdGhlcl0gPSB2YWx1ZV9vdGhlcjsKKyAgRVhQRUNUX0VRKDEsIG90aGVyLnNpemUoKSk7CisKKyAgb3RoZXIgPSBtYXBfOworCisgIEVYUEVDVF9FUSgyLCBvdGhlci5zaXplKCkpOworICBFWFBFQ1RfRVEodmFsdWUxLCBvdGhlci5hdChrZXkxKSk7CisgIEVYUEVDVF9FUSh2YWx1ZTIsIG90aGVyLmF0KGtleTIpKTsKKyAgRVhQRUNUX1RSVUUob3RoZXIuZmluZChrZXlfb3RoZXIpID09IG90aGVyLmVuZCgpKTsKKworICAvLyBTZWxmIGFzc2lnbgorICBvdGhlciA9IG90aGVyOworICBFWFBFQ1RfRVEoMiwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlMSwgb3RoZXIuYXQoa2V5MSkpOworICBFWFBFQ1RfRVEodmFsdWUyLCBvdGhlci5hdChrZXkyKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgUmVoYXNoKSB7CisgIGNvbnN0IGludCB0ZXN0X3NpemUgPSA1MDsKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiByZWZlcmVuY2VfbWFwOworICBmb3IgKGludCBpID0gMDsgaSA8IHRlc3Rfc2l6ZTsgaSsrKSB7CisgICAgcmVmZXJlbmNlX21hcFtpXSA9IGk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXN0X3NpemU7IGkrKykgeworICAgIG1hcF9baV0gPSByZWZlcmVuY2VfbWFwW2ldOworICAgIEVYUEVDVF9FUShyZWZlcmVuY2VfbWFwW2ldLCBtYXBfW2ldKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRlc3Rfc2l6ZTsgaSsrKSB7CisgICAgbWFwXy5lcmFzZShpKTsKKyAgICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChpKSk7CisgIH0KKyAgRVhQRUNUX1RSVUUobWFwXy5lbXB0eSgpKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBFcXVhbFJhbmdlKSB7CisgIGludCBrZXkgPSAxMDAsIGtleV9taXNzaW5nID0gMTAxOworICBtYXBfW2tleV0gPSAxMDA7CisKKyAgc3RkOjpwYWlyPGdvb2dsZTo6cHJvdG9idWY6Ok1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciwKKyAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvcj4gcmFuZ2UgPSBtYXBfLmVxdWFsX3JhbmdlKGtleSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZmluZChrZXkpID09IHJhbmdlLmZpcnN0KTsKKyAgRVhQRUNUX1RSVUUoKyttYXBfLmZpbmQoa2V5KSA9PSByYW5nZS5zZWNvbmQpOworCisgIHJhbmdlID0gbWFwXy5lcXVhbF9yYW5nZShrZXlfbWlzc2luZyk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gcmFuZ2UuZmlyc3QpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IHJhbmdlLnNlY29uZCk7CisKKyAgc3RkOjpwYWlyPGdvb2dsZTo6cHJvdG9idWY6Ok1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvciwKKyAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvcj4gY29uc3RfcmFuZ2UgPQorICAgICAgY29uc3RfbWFwXy5lcXVhbF9yYW5nZShrZXkpOworICBFWFBFQ1RfVFJVRShjb25zdF9tYXBfLmZpbmQoa2V5KSA9PSBjb25zdF9yYW5nZS5maXJzdCk7CisgIEVYUEVDVF9UUlVFKCsrY29uc3RfbWFwXy5maW5kKGtleSkgPT0gY29uc3RfcmFuZ2Uuc2Vjb25kKTsKKworICBjb25zdF9yYW5nZSA9IGNvbnN0X21hcF8uZXF1YWxfcmFuZ2Uoa2V5X21pc3NpbmcpOworICBFWFBFQ1RfVFJVRShjb25zdF9tYXBfLmVuZCgpID09IGNvbnN0X3JhbmdlLmZpcnN0KTsKKyAgRVhQRUNUX1RSVUUoY29uc3RfbWFwXy5lbmQoKSA9PSBjb25zdF9yYW5nZS5zZWNvbmQpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIENvbnZlcnRUb1N0ZE1hcCkgeworICBtYXBfWzEwMF0gPSAxMDE7CisgIHN0ZDo6bWFwPGludDMyLCBpbnQzMj4gc3RkX21hcChtYXBfLmJlZ2luKCksIG1hcF8uZW5kKCkpOworICBFWFBFQ1RfRVEoMSwgc3RkX21hcC5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAxLCBzdGRfbWFwWzEwMF0pOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIENvbnZlcnRUb1N0ZFZlY3Rvck9mUGFpcnMpIHsKKyAgbWFwX1sxMDBdID0gMTAxOworICBzdGQ6OnZlY3RvcjxzdGQ6OnBhaXI8aW50MzIsIGludDMyPiA+IHN0ZF92ZWMobWFwXy5iZWdpbigpLCBtYXBfLmVuZCgpKTsKKyAgRVhQRUNUX0VRKDEsIHN0ZF92ZWMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMCwgc3RkX3ZlY1swXS5maXJzdCk7CisgIEVYUEVDVF9FUSgxMDEsIHN0ZF92ZWNbMF0uc2Vjb25kKTsKK30KKworLy8gTWFwIEZpZWxkIFJlZmxlY3Rpb24gVGVzdCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3N0YXRpYyBpbnQgRnVuYyhpbnQgaSwgaW50IGopIHsKKyAgcmV0dXJuIGkgKiBqOworfQorCitzdGF0aWMgc3RyaW5nIFN0ckZ1bmMoaW50IGksIGludCBqKSB7CisgIHN0cmluZyBzdHI7CisgIFNTdHJpbmdQcmludGYoJnN0ciwgIiVkIiwgRnVuYyhpLCBqKSk7CisgIHJldHVybiBzdHI7Cit9CisKK3N0YXRpYyBpbnQgSW50KGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgaW50IHJlc3VsdCA9IDA7CisgIHN0ZDo6aXN0cmluZ3N0cmVhbSh2YWx1ZSkgPj4gcmVzdWx0OworICByZXR1cm4gcmVzdWx0OworfQorCitjbGFzcyBNYXBGaWVsZFJlZmxlY3Rpb25UZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7Cit9OworCitURVNUX0YoTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVndWxhckZpZWxkcykgeworICBUZXN0TWFwIG1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmwgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworCisgIE1hcDxpbnQzMiwgaW50MzI+KiBtYXBfaW50MzJfaW50MzIgPSBtZXNzYWdlLm11dGFibGVfbWFwX2ludDMyX2ludDMyKCk7CisgIE1hcDxpbnQzMiwgZG91YmxlPiogbWFwX2ludDMyX2RvdWJsZSA9IG1lc3NhZ2UubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCk7CisgIE1hcDxzdHJpbmcsIHN0cmluZz4qIG1hcF9zdHJpbmdfc3RyaW5nID0gbWVzc2FnZS5tdXRhYmxlX21hcF9zdHJpbmdfc3RyaW5nKCk7CisgIE1hcDxpbnQzMiwgRm9yZWlnbk1lc3NhZ2U+KiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIG1lc3NhZ2UubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgKCptYXBfaW50MzJfaW50MzIpW2ldID0gRnVuYyhpLCAxKTsKKyAgICAoKm1hcF9pbnQzMl9kb3VibGUpW2ldID0gRnVuYyhpLCAyKTsKKyAgICAoKm1hcF9zdHJpbmdfc3RyaW5nKVtTdHJGdW5jKGksIDEpXSA9IFN0ckZ1bmMoaSwgNSk7CisgICAgKCptYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKVtpXS5zZXRfYyhGdW5jKGksIDYpKTsKKyAgfQorCisgIC8vIEdldCBGaWVsZERlc2NyaXB0b3JzIGZvciBhbGwgdGhlIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfaW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZG91YmxlID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2RvdWJsZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9zdHJpbmdfc3RyaW5nID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3N0cmluZ19zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2luMzJfa2V5ID0KKyAgICAgIGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2luMzJfdmFsdWUgPQorICAgICAgZmRfbWFwX2ludDMyX2ludDMyLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9kb3VibGVfa2V5ID0KKyAgICAgIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUgPQorICAgICAgZmRfbWFwX2ludDMyX2RvdWJsZS0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfc3RyaW5nX3N0cmluZ19rZXkgPQorICAgICAgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlID0KKyAgICAgIGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5ID0KKyAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUgPQorICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKworICAvLyBHZXQgUmVwZWF0ZWRQdHJGaWVsZCBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+JiBtZl9pbnQzMl9pbnQzMiA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KG1lc3NhZ2UsIGZkX21hcF9pbnQzMl9pbnQzMik7CisgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4mIG1mX2ludDMyX2RvdWJsZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KG1lc3NhZ2UsIGZkX21hcF9pbnQzMl9kb3VibGUpOworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+JiBtZl9zdHJpbmdfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4obWVzc2FnZSwgZmRfbWFwX3N0cmluZ19zdHJpbmcpOworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+JgorICAgICAgbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KAorICAgICAgICAgICAgICBtZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKTsKKworICAvLyBHZXQgbXV0YWJsZSBSZXBlYXRlZFB0ckZpZWxkIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIG1tZl9pbnQzMl9pbnQzMiA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigmbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ludDMyKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiogbW1mX2ludDMyX2RvdWJsZSA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigmbWVzc2FnZSwgZmRfbWFwX2ludDMyX2RvdWJsZSk7CisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIG1tZl9zdHJpbmdfc3RyaW5nID0KKyAgICAgIHJlZmwtPk11dGFibGVSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KCZtZXNzYWdlLCBmZF9tYXBfc3RyaW5nX3N0cmluZyk7CisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oCisgICAgICAgICAgJm1lc3NhZ2UsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UpOworCisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gZG8gZ2V0cyB0aHJvdWdoIHRoZSBSZXBlYXRlZFB0ckZpZWxkIG9iamVjdHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIHsKKyAgICAgIC8vIENoZWNrIGdldHMgdGhyb3VnaCBjb25zdCBvYmplY3RzLgorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9pbnQzMiA9IG1mX2ludDMyX2ludDMyLkdldChpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9pbnQzMiA9IG1lc3NhZ2VfaW50MzJfaW50MzIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2ludDMyLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworICAgICAgaW50MzIgdmFsdWVfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2ludDMyLCBGdW5jKGtleV9pbnQzMl9pbnQzMiwgMSkpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2RvdWJsZSA9IG1mX2ludDMyX2RvdWJsZS5HZXQoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfZG91YmxlID0gbWVzc2FnZV9pbnQzMl9kb3VibGUuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZSwgZmRfbWFwX2ludDMyX2RvdWJsZV9rZXkpOworICAgICAgZG91YmxlIHZhbHVlX2ludDMyX2RvdWJsZSA9CisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9kb3VibGUsIEZ1bmMoa2V5X2ludDMyX2RvdWJsZSwgMikpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX3N0cmluZ19zdHJpbmcgPSBtZl9zdHJpbmdfc3RyaW5nLkdldChpKTsKKyAgICAgIHN0cmluZyBrZXlfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX2tleSk7CisgICAgICBzdHJpbmcgdmFsdWVfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9zdHJpbmdfc3RyaW5nLCBTdHJGdW5jKEludChrZXlfc3RyaW5nX3N0cmluZyksIDUpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9tZXNzYWdlID0gbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldChpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9tZXNzYWdlID0gbWVzc2FnZV9pbnQzMl9tZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9tZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleSk7CisgICAgICBjb25zdCBGb3JlaWduTWVzc2FnZSYgdmFsdWVfaW50MzJfbWVzc2FnZSA9CisgICAgICAgICAgZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlX2ludDMyX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX21lc3NhZ2UuYygpLCBGdW5jKGtleV9pbnQzMl9tZXNzYWdlLCA2KSk7CisgICAgfQorCisgICAgeworICAgICAgLy8gQ2hlY2sgZ2V0cyB0aHJvdWdoIG11dGFibGUgb2JqZWN0cy4KKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfaW50MzIgPSBtbWZfaW50MzJfaW50MzItPkdldChpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9pbnQzMiA9IG1lc3NhZ2VfaW50MzJfaW50MzIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2ludDMyLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworICAgICAgaW50MzIgdmFsdWVfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2ludDMyLCBGdW5jKGtleV9pbnQzMl9pbnQzMiwgMSkpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2RvdWJsZSA9IG1tZl9pbnQzMl9kb3VibGUtPkdldChpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9kb3VibGUgPSBtZXNzYWdlX2ludDMyX2RvdWJsZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX2tleSk7CisgICAgICBkb3VibGUgdmFsdWVfaW50MzJfZG91YmxlID0KKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZS5HZXRSZWZsZWN0aW9uKCktPkdldERvdWJsZSgKKyAgICAgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2RvdWJsZSwgRnVuYyhrZXlfaW50MzJfZG91YmxlLCAyKSk7CisKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZyA9IG1tZl9zdHJpbmdfc3RyaW5nLT5HZXQoaSk7CisgICAgICBzdHJpbmcga2V5X3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ19rZXkpOworICAgICAgc3RyaW5nIHZhbHVlX3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfc3RyaW5nX3N0cmluZywgU3RyRnVuYyhJbnQoa2V5X3N0cmluZ19zdHJpbmcpLCA1KSk7CisKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSA9IG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPkdldChpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9tZXNzYWdlID0gbWVzc2FnZV9pbnQzMl9tZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9tZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleSk7CisgICAgICBjb25zdCBGb3JlaWduTWVzc2FnZSYgdmFsdWVfaW50MzJfbWVzc2FnZSA9CisgICAgICAgICAgZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlX2ludDMyX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX21lc3NhZ2UuYygpLCBGdW5jKGtleV9pbnQzMl9tZXNzYWdlLCA2KSk7CisgICAgfQorICB9CisKKyAgLy8gRG8gc2V0cyB0aHJvdWdoIHRoZSBSZXBlYXRlZFB0ckZpZWxkIG9iamVjdHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIHsKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2VfaW50MzJfaW50MzIgPSBtbWZfaW50MzJfaW50MzItPk11dGFibGUoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICptZXNzYWdlX2ludDMyX2ludDMyLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMi0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMihtZXNzYWdlX2ludDMyX2ludDMyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9tYXBfaW50MzJfaW4zMl92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVuYyhrZXlfaW50MzJfaW50MzIsIC0xKSk7CisKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2VfaW50MzJfZG91YmxlID0gbW1mX2ludDMyX2RvdWJsZS0+TXV0YWJsZShpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9kb3VibGUgPSBtZXNzYWdlX2ludDMyX2RvdWJsZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfa2V5KTsKKyAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLT5HZXRSZWZsZWN0aW9uKCktPlNldERvdWJsZSgKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSwKKyAgICAgICAgICBGdW5jKGtleV9pbnQzMl9kb3VibGUsIC0yKSk7CisKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZyA9IG1tZl9zdHJpbmdfc3RyaW5nLT5NdXRhYmxlKGkpOworICAgICAgc3RyaW5nIGtleV9zdHJpbmdfc3RyaW5nID0KKyAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmctPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICAqbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ19rZXkpOworICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlLAorICAgICAgICAgIFN0ckZ1bmMoSW50KGtleV9zdHJpbmdfc3RyaW5nKSwgLTUpKTsKKworICAgICAgTWVzc2FnZSogbWVzc2FnZV9pbnQzMl9tZXNzYWdlID0gbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+TXV0YWJsZShpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9tZXNzYWdlID0KKyAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgICAgICptZXNzYWdlX2ludDMyX21lc3NhZ2UsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5KTsKKyAgICAgIEZvcmVpZ25NZXNzYWdlKiB2YWx1ZV9pbnQzMl9tZXNzYWdlID0gZG93bl9jYXN0PEZvcmVpZ25NZXNzYWdlKj4oCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgICAgLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlX2ludDMyX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgICAgdmFsdWVfaW50MzJfbWVzc2FnZS0+c2V0X2MoRnVuYyhrZXlfaW50MzJfbWVzc2FnZSwgLTYpKTsKKyAgICB9CisgIH0KKworICAvLyBDaGVjayBnZXRzIHRocm91Z2ggbXV0YWJsZSBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAtMSksIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoaSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIC0yKSwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoaSkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIC01KSwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KFN0ckZ1bmMoaSwgMSkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAtNiksIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KGkpLmMoKSk7CisgIH0KK30KKworVEVTVF9GKE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlcGVhdGVkRmllbGRSZWZGb3JSZWd1bGFyRmllbGRzKSB7CisgIFRlc3RNYXAgbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgTWFwPGludDMyLCBpbnQzMj4qIG1hcF9pbnQzMl9pbnQzMiA9IG1lc3NhZ2UubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKTsKKyAgTWFwPGludDMyLCBkb3VibGU+KiBtYXBfaW50MzJfZG91YmxlID0gbWVzc2FnZS5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKTsKKyAgTWFwPHN0cmluZywgc3RyaW5nPiogbWFwX3N0cmluZ19zdHJpbmcgPSBtZXNzYWdlLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKTsKKyAgTWFwPGludDMyLCBGb3JlaWduTWVzc2FnZT4qIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgbWVzc2FnZS5tdXRhYmxlX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICAoKm1hcF9pbnQzMl9pbnQzMilbaV0gPSBGdW5jKGksIDEpOworICAgICgqbWFwX2ludDMyX2RvdWJsZSlbaV0gPSBGdW5jKGksIDIpOworICAgICgqbWFwX3N0cmluZ19zdHJpbmcpW1N0ckZ1bmMoaSwgMSldID0gU3RyRnVuYyhpLCA1KTsKKyAgICAoKm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UpW2ldLnNldF9jKEZ1bmMoaSwgNikpOworICB9CisKKyAgLy8gR2V0IEZpZWxkRGVzY3JpcHRvcnMgZm9yIGFsbCB0aGUgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9pbnQzMiA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9pbnQzMiIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9kb3VibGUgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZG91YmxlIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX3N0cmluZ19zdHJpbmcgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc3RyaW5nX3N0cmluZyIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIik7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfaW4zMl9rZXkgPQorICAgICAgZmRfbWFwX2ludDMyX2ludDMyLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfaW4zMl92YWx1ZSA9CisgICAgICBmZF9tYXBfaW50MzJfaW50MzItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2RvdWJsZV9rZXkgPQorICAgICAgZmRfbWFwX2ludDMyX2RvdWJsZS0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSA9CisgICAgICBmZF9tYXBfaW50MzJfZG91YmxlLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9zdHJpbmdfc3RyaW5nX2tleSA9CisgICAgICBmZF9tYXBfc3RyaW5nX3N0cmluZy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX3N0cmluZ19zdHJpbmdfdmFsdWUgPQorICAgICAgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXkgPQorICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSA9CisgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworCisgIC8vIEdldCBSZXBlYXRlZEZpZWxkUmVmIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4gbWZfaW50MzJfaW50MzIgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPihtZXNzYWdlLCBmZF9tYXBfaW50MzJfaW50MzIpOworICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1mX2ludDMyX2RvdWJsZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KG1lc3NhZ2UsIGZkX21hcF9pbnQzMl9kb3VibGUpOworICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1mX3N0cmluZ19zdHJpbmcgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPihtZXNzYWdlLCBmZF9tYXBfc3RyaW5nX3N0cmluZyk7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4gbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4obWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gR2V0IG11dGFibGUgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfaW50MzJfaW50MzIgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oJm1lc3NhZ2UsIGZkX21hcF9pbnQzMl9pbnQzMik7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1tZl9pbnQzMl9kb3VibGUgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oJm1lc3NhZ2UsIGZkX21hcF9pbnQzMl9kb3VibGUpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfc3RyaW5nX3N0cmluZyA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigmbWVzc2FnZSwgZmRfbWFwX3N0cmluZ19zdHJpbmcpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPgorICAgICAgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgICAgICZtZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKTsKKworICAvLyBHZXQgZW50cnkgZGVmYXVsdCBpbnN0YW5jZXMKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBlbnRyeV9pbnQzMl9pbnQzMigKKyAgICAgIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpCisgICAgICAgICAgLT5HZXRQcm90b3R5cGUoZmRfbWFwX2ludDMyX2ludDMyLT5tZXNzYWdlX3R5cGUoKSkKKyAgICAgICAgICAtPk5ldygpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBlbnRyeV9pbnQzMl9kb3VibGUoCisgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKQorICAgICAgICAgIC0+R2V0UHJvdG90eXBlKGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpKQorICAgICAgICAgIC0+TmV3KCkpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IGVudHJ5X3N0cmluZ19zdHJpbmcoCisgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKQorICAgICAgICAgIC0+R2V0UHJvdG90eXBlKGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKSkKKyAgICAgICAgICAtPk5ldygpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UoCisgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKQorICAgICAgICAgIC0+R2V0UHJvdG90eXBlKGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpKQorICAgICAgICAgIC0+TmV3KCkpOworCisgIEVYUEVDVF9FUSgxMCwgbWZfaW50MzJfaW50MzIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtbWZfaW50MzJfaW50MzIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtZl9pbnQzMl9kb3VibGUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtbWZfaW50MzJfZG91YmxlLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbWZfc3RyaW5nX3N0cmluZy5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1tZl9zdHJpbmdfc3RyaW5nLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5zaXplKCkpOworCisgIEVYUEVDVF9GQUxTRShtZl9pbnQzMl9pbnQzMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1tZl9pbnQzMl9pbnQzMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1mX2ludDMyX2RvdWJsZS5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1tZl9pbnQzMl9kb3VibGUuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtZl9zdHJpbmdfc3RyaW5nLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobW1mX3N0cmluZ19zdHJpbmcuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLmVtcHR5KCkpOworCisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gZG8gZ2V0cyB0aHJvdWdoIHRoZSBSZXBlYXRlZEZpZWxkUmVmIG9iamVjdHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIHsKKyAgICAgIC8vIENoZWNrIGdldHMgdGhyb3VnaCBjb25zdCBvYmplY3RzLgorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9pbnQzMiA9CisgICAgICAgICAgbWZfaW50MzJfaW50MzIuR2V0KGksIGVudHJ5X2ludDMyX2ludDMyLmdldCgpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9pbnQzMiA9IG1lc3NhZ2VfaW50MzJfaW50MzIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2ludDMyLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworICAgICAgaW50MzIgdmFsdWVfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2ludDMyLCBGdW5jKGtleV9pbnQzMl9pbnQzMiwgMSkpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2RvdWJsZSA9CisgICAgICAgICAgbWZfaW50MzJfZG91YmxlLkdldChpLCBlbnRyeV9pbnQzMl9kb3VibGUuZ2V0KCkpOworICAgICAgaW50MzIga2V5X2ludDMyX2RvdWJsZSA9IG1lc3NhZ2VfaW50MzJfZG91YmxlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfa2V5KTsKKyAgICAgIGRvdWJsZSB2YWx1ZV9pbnQzMl9kb3VibGUgPQorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKAorICAgICAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfaW50MzJfZG91YmxlLCBGdW5jKGtleV9pbnQzMl9kb3VibGUsIDIpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9zdHJpbmdfc3RyaW5nID0KKyAgICAgICAgICBtZl9zdHJpbmdfc3RyaW5nLkdldChpLCBlbnRyeV9zdHJpbmdfc3RyaW5nLmdldCgpKTsKKyAgICAgIHN0cmluZyBrZXlfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX2tleSk7CisgICAgICBzdHJpbmcgdmFsdWVfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9zdHJpbmdfc3RyaW5nLCBTdHJGdW5jKEludChrZXlfc3RyaW5nX3N0cmluZyksIDUpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9tZXNzYWdlID0KKyAgICAgICAgICBtZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuR2V0KGksIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfbWVzc2FnZSA9IG1lc3NhZ2VfaW50MzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXkpOworICAgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHZhbHVlX2ludDMyX21lc3NhZ2UgPQorICAgICAgICAgIGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSY+KAorICAgICAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgICAgICAgICAtPkdldE1lc3NhZ2UobWVzc2FnZV9pbnQzMl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9tZXNzYWdlLmMoKSwgRnVuYyhrZXlfaW50MzJfbWVzc2FnZSwgNikpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIENoZWNrIGdldHMgdGhyb3VnaCBtdXRhYmxlIG9iamVjdHMuCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2ludDMyID0KKyAgICAgICAgICBtbWZfaW50MzJfaW50MzIuR2V0KGksIGVudHJ5X2ludDMyX2ludDMyLmdldCgpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9pbnQzMiA9IG1lc3NhZ2VfaW50MzJfaW50MzIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2ludDMyLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworICAgICAgaW50MzIgdmFsdWVfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2ludDMyLCBGdW5jKGtleV9pbnQzMl9pbnQzMiwgMSkpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2RvdWJsZSA9CisgICAgICAgICAgbW1mX2ludDMyX2RvdWJsZS5HZXQoaSwgZW50cnlfaW50MzJfZG91YmxlLmdldCgpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9kb3VibGUgPSBtZXNzYWdlX2ludDMyX2RvdWJsZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX2tleSk7CisgICAgICBkb3VibGUgdmFsdWVfaW50MzJfZG91YmxlID0KKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZS5HZXRSZWZsZWN0aW9uKCktPkdldERvdWJsZSgKKyAgICAgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2RvdWJsZSwgRnVuYyhrZXlfaW50MzJfZG91YmxlLCAyKSk7CisKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbW1mX3N0cmluZ19zdHJpbmcuR2V0KGksIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCkpOworICAgICAgc3RyaW5nIGtleV9zdHJpbmdfc3RyaW5nID0KKyAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcuR2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoCisgICAgICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZywgZmRfbWFwX3N0cmluZ19zdHJpbmdfa2V5KTsKKyAgICAgIHN0cmluZyB2YWx1ZV9zdHJpbmdfc3RyaW5nID0KKyAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcuR2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoCisgICAgICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZywgZmRfbWFwX3N0cmluZ19zdHJpbmdfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX3N0cmluZ19zdHJpbmcsIFN0ckZ1bmMoSW50KGtleV9zdHJpbmdfc3RyaW5nKSwgNSkpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX21lc3NhZ2UgPQorICAgICAgICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuR2V0KGksIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfbWVzc2FnZSA9IG1lc3NhZ2VfaW50MzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXkpOworICAgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHZhbHVlX2ludDMyX21lc3NhZ2UgPQorICAgICAgICAgIGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSY+KAorICAgICAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgICAgICAgICAtPkdldE1lc3NhZ2UobWVzc2FnZV9pbnQzMl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9tZXNzYWdlLmMoKSwgRnVuYyhrZXlfaW50MzJfbWVzc2FnZSwgNikpOworICAgIH0KKyAgfQorCisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gZG8gc2V0cyB0aHJvdWdoIHRoZSBSZXBlYXRlZEZpZWxkUmVmIG9iamVjdHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfaW50MzIgPQorICAgICAgICBtbWZfaW50MzJfaW50MzIuR2V0KGksIGVudHJ5X2ludDMyX2ludDMyLmdldCgpKTsKKyAgICBpbnQga2V5ID0gbWVzc2FnZV9pbnQzMl9pbnQzMi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICBtZXNzYWdlX2ludDMyX2ludDMyLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworCisgICAgZW50cnlfaW50MzJfaW50MzItPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoCisgICAgICAgIGVudHJ5X2ludDMyX2ludDMyLmdldCgpLCBmZF9tYXBfaW50MzJfaW50MzItPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwKKyAgICAgICAga2V5KTsKKyAgICBlbnRyeV9pbnQzMl9pbnQzMi0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgICAgZW50cnlfaW50MzJfaW50MzIuZ2V0KCksIGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDEpLAorICAgICAgICBGdW5jKGtleSwgLTEpKTsKKyAgICBlbnRyeV9pbnQzMl9kb3VibGUtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoCisgICAgICAgIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSwgZmRfbWFwX2ludDMyX2RvdWJsZS0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDApLAorICAgICAgICBrZXkpOworICAgIGVudHJ5X2ludDMyX2RvdWJsZS0+R2V0UmVmbGVjdGlvbigpLT5TZXREb3VibGUoCisgICAgICAgIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSwgZmRfbWFwX2ludDMyX2RvdWJsZS0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDEpLAorICAgICAgICBGdW5jKGtleSwgLTIpKTsKKyAgICBlbnRyeV9zdHJpbmdfc3RyaW5nLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICAgICAgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSwKKyAgICAgICAgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwgU3RyRnVuYyhrZXksIDEpKTsKKyAgICBlbnRyeV9zdHJpbmdfc3RyaW5nLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICAgICAgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSwKKyAgICAgICAgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwgU3RyRnVuYyhrZXksIC01KSk7CisgICAgZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgICBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCksCisgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwga2V5KTsKKyAgICBNZXNzYWdlKiB2YWx1ZV9tZXNzYWdlID0KKyAgICAgICAgZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVNZXNzYWdlKAorICAgICAgICAgICAgZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlLmdldCgpLAorICAgICAgICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDEpKTsKKyAgICB2YWx1ZV9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgICB2YWx1ZV9tZXNzYWdlLCB2YWx1ZV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgiYyIpLAorICAgICAgICBGdW5jKGtleSwgLTYpKTsKKworICAgIG1tZl9pbnQzMl9pbnQzMi5TZXQoaSwgKmVudHJ5X2ludDMyX2ludDMyKTsKKyAgICBtbWZfaW50MzJfZG91YmxlLlNldChpLCAqZW50cnlfaW50MzJfZG91YmxlKTsKKyAgICBtbWZfc3RyaW5nX3N0cmluZy5TZXQoaSwgKmVudHJ5X3N0cmluZ19zdHJpbmcpOworICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuU2V0KGksICplbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgLTEpLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KGkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAtMiksIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KGkpKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAtNSksIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdChTdHJGdW5jKGksIDEpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgLTYpLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdChpKS5jKCkpOworICB9CisKKyAgLy8gVGVzdCBpdGVyYXRvcnMuCisgIHsKKyAgICBpbnQgaW5kZXggPSAwOworICAgIGhhc2hfbWFwPGludDMyLCBpbnQzMj4gcmVzdWx0OworICAgIGZvciAoUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPjo6aXRlcmF0b3IgaXQgPSBtZl9pbnQzMl9pbnQzMi5iZWdpbigpOworICAgICAgICAgaXQgIT0gbWZfaW50MzJfaW50MzIuZW5kKCk7ICsraXQpIHsKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UgPSAqaXQ7CisgICAgICBpbnQzMiBrZXkgPQorICAgICAgICAgIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlLCBmZF9tYXBfaW50MzJfaW4zMl9rZXkpOworICAgICAgaW50MzIgdmFsdWUgPQorICAgICAgICAgIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlLCBmZF9tYXBfaW50MzJfaW4zMl92YWx1ZSk7CisgICAgICByZXN1bHRba2V5XSA9IHZhbHVlOworICAgICAgKytpbmRleDsKKyAgICB9CisgICAgRVhQRUNUX0VRKDEwLCBpbmRleCk7CisgICAgZm9yIChoYXNoX21hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvciBpdCA9IHJlc3VsdC5iZWdpbigpOworICAgICAgICAgaXQgIT0gcmVzdWx0LmVuZCgpOyArK2l0KSB7CisgICAgICBFWFBFQ1RfRVEobWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdChpdC0+Zmlyc3QpLCBpdC0+c2Vjb25kKTsKKyAgICB9CisgIH0KKworICB7CisgICAgaW50IGluZGV4ID0gMDsKKyAgICBoYXNoX21hcDxpbnQzMiwgZG91YmxlPiByZXN1bHQ7CisgICAgZm9yIChSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+OjppdGVyYXRvciBpdCA9IG1mX2ludDMyX2RvdWJsZS5iZWdpbigpOworICAgICAgICAgaXQgIT0gbWZfaW50MzJfZG91YmxlLmVuZCgpOyArK2l0KSB7CisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gKml0OworICAgICAgaW50MzIga2V5ID0KKyAgICAgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZSwgZmRfbWFwX2ludDMyX2RvdWJsZV9rZXkpOworICAgICAgZG91YmxlIHZhbHVlID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldERvdWJsZSgKKyAgICAgICAgICBtZXNzYWdlLCBmZF9tYXBfaW50MzJfZG91YmxlX3ZhbHVlKTsKKyAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7CisgICAgICArK2luZGV4OworICAgIH0KKyAgICBFWFBFQ1RfRVEoMTAsIGluZGV4KTsKKyAgICBmb3IgKGhhc2hfbWFwPGludDMyLCBkb3VibGU+Ojpjb25zdF9pdGVyYXRvciBpdCA9IHJlc3VsdC5iZWdpbigpOworICAgICAgICAgaXQgIT0gcmVzdWx0LmVuZCgpOyArK2l0KSB7CisgICAgICBFWFBFQ1RfRVEobWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoaXQtPmZpcnN0KSwgaXQtPnNlY29uZCk7CisgICAgfQorICB9CisKKyAgeworICAgIGludCBpbmRleCA9IDA7CisgICAgaGFzaF9tYXA8c3RyaW5nLCBzdHJpbmc+IHJlc3VsdDsKKyAgICBmb3IgKFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT46Oml0ZXJhdG9yIGl0ID0gbWZfc3RyaW5nX3N0cmluZy5iZWdpbigpOworICAgICAgICAgaXQgIT0gbWZfc3RyaW5nX3N0cmluZy5lbmQoKTsgKytpdCkgeworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSA9ICppdDsKKyAgICAgIHN0cmluZyBrZXkgPQorICAgICAgICAgIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcobWVzc2FnZSwgZmRfbWFwX3N0cmluZ19zdHJpbmdfa2V5KTsKKyAgICAgIHN0cmluZyB2YWx1ZSA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoCisgICAgICAgICAgbWVzc2FnZSwgZmRfbWFwX3N0cmluZ19zdHJpbmdfdmFsdWUpOworICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTsKKyAgICAgICsraW5kZXg7CisgICAgfQorICAgIEVYUEVDVF9FUSgxMCwgaW5kZXgpOworICAgIGZvciAoaGFzaF9tYXA8c3RyaW5nLCBzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdCA9IHJlc3VsdC5iZWdpbigpOworICAgICAgICAgaXQgIT0gcmVzdWx0LmVuZCgpOyArK2l0KSB7CisgICAgICBFWFBFQ1RfRVEobWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KGl0LT5maXJzdCksIGl0LT5zZWNvbmQpOworICAgIH0KKyAgfQorCisgIHsKKyAgICBpbnQgaW5kZXggPSAwOworICAgIHN0ZDo6bWFwPGludDMyLCBGb3JlaWduTWVzc2FnZT4gcmVzdWx0OworICAgIGZvciAoUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPjo6aXRlcmF0b3IgaXQgPQorICAgICAgICAgICAgIG1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5iZWdpbigpOworICAgICAgICAgaXQgIT0gbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLmVuZCgpOyArK2l0KSB7CisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gKml0OworICAgICAgaW50MzIga2V5ID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2UsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5KTsKKyAgICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiBzdWJfbWVzc2FnZSA9IGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSY+KAorICAgICAgICAgIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbHVlKSk7CisgICAgICByZXN1bHRba2V5XS5NZXJnZUZyb20oc3ViX21lc3NhZ2UpOworICAgICAgKytpbmRleDsKKyAgICB9CisgICAgRVhQRUNUX0VRKDEwLCBpbmRleCk7CisgICAgZm9yIChzdGQ6Om1hcDxpbnQzMiwgRm9yZWlnbk1lc3NhZ2U+Ojpjb25zdF9pdGVyYXRvciBpdCA9IHJlc3VsdC5iZWdpbigpOworICAgICAgICAgaXQgIT0gcmVzdWx0LmVuZCgpOyArK2l0KSB7CisgICAgICBFWFBFQ1RfRVEobWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoaXQtPmZpcnN0KS5jKCksCisgICAgICAgICAgICAgICAgaXQtPnNlY29uZC5jKCkpOworICAgIH0KKyAgfQorCisgIC8vIFRlc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY6OkFkZCgpCisgIGVudHJ5X2ludDMyX2ludDMyLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgZW50cnlfaW50MzJfaW50MzIuZ2V0KCksIGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDApLAorICAgICAgNDMyMSk7CisgIGVudHJ5X2ludDMyX2ludDMyLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgZW50cnlfaW50MzJfaW50MzIuZ2V0KCksIGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDEpLAorICAgICAgMTIzNCk7CisgIG1tZl9pbnQzMl9pbnQzMi5BZGQoKmVudHJ5X2ludDMyX2ludDMyKTsKKyAgRVhQRUNUX0VRKDEyMzQsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoNDMyMSkpOworCisgIGVudHJ5X2ludDMyX2RvdWJsZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSwgZmRfbWFwX2ludDMyX2RvdWJsZS0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDApLAorICAgICAgNDMyMSk7CisgIGVudHJ5X2ludDMyX2RvdWJsZS0+R2V0UmVmbGVjdGlvbigpLT5TZXREb3VibGUoCisgICAgICBlbnRyeV9pbnQzMl9kb3VibGUuZ2V0KCksIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwKKyAgICAgIDEyMzQuMCk7CisgIG1tZl9pbnQzMl9kb3VibGUuQWRkKCplbnRyeV9pbnQzMl9kb3VibGUpOworICBFWFBFQ1RfRVEoMTIzNC4wLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5hdCg0MzIxKSk7CisKKyAgZW50cnlfc3RyaW5nX3N0cmluZy0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgICBlbnRyeV9zdHJpbmdfc3RyaW5nLmdldCgpLAorICAgICAgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwgIjQzMjEiKTsKKyAgZW50cnlfc3RyaW5nX3N0cmluZy0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgICBlbnRyeV9zdHJpbmdfc3RyaW5nLmdldCgpLCBmZF9tYXBfc3RyaW5nX3N0cmluZy0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDEpLAorICAgICAgIjEyMzQiKTsKKyAgbW1mX3N0cmluZ19zdHJpbmcuQWRkKCplbnRyeV9zdHJpbmdfc3RyaW5nKTsKKyAgRVhQRUNUX0VRKCIxMjM0IiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCI0MzIxIikpOworCisgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSwKKyAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwgNDMyMSk7CisgIE1lc3NhZ2UqIHZhbHVlX21lc3NhZ2UgPQorICAgICAgZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVNZXNzYWdlKAorICAgICAgICAgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSwKKyAgICAgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMSkpOworICBGb3JlaWduTWVzc2FnZSBmb3JlaWduX21lc3NhZ2U7CisgIGZvcmVpZ25fbWVzc2FnZS5zZXRfYygxMjM0KTsKKyAgdmFsdWVfbWVzc2FnZS0+Q29weUZyb20oZm9yZWlnbl9tZXNzYWdlKTsKKworICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkFkZCgqZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlKTsKKyAgRVhQRUNUX0VRKDEyMzQsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KDQzMjEpLmMoKSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6UmVtb3ZlTGFzdCgpCisgIG1tZl9pbnQzMl9pbnQzMi5SZW1vdmVMYXN0KCk7CisgIG1tZl9pbnQzMl9kb3VibGUuUmVtb3ZlTGFzdCgpOworICBtbWZfc3RyaW5nX3N0cmluZy5SZW1vdmVMYXN0KCk7CisgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuUmVtb3ZlTGFzdCgpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6U3dhcEVsZW1lbnRzKCkKKyAgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYSA9IG1tZl9pbnQzMl9pbnQzMi5HZXQoMCwgZW50cnlfaW50MzJfaW50MzIuZ2V0KCkpOworICAgIGludDMyIGludDMyX3ZhbHVlMGEgPQorICAgICAgICBtZXNzYWdlMGEuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlMGEsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWEgPSBtbWZfaW50MzJfaW50MzIuR2V0KDksIGVudHJ5X2ludDMyX2ludDMyLmdldCgpKTsKKyAgICBpbnQzMiBpbnQzMl92YWx1ZTlhID0KKyAgICAgICAgbWVzc2FnZTlhLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZTlhLCBmZF9tYXBfaW50MzJfaW4zMl92YWx1ZSk7CisKKyAgICBtbWZfaW50MzJfaW50MzIuU3dhcEVsZW1lbnRzKDAsIDkpOworCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTBiID0gbW1mX2ludDMyX2ludDMyLkdldCgwLCBlbnRyeV9pbnQzMl9pbnQzMi5nZXQoKSk7CisgICAgaW50MzIgaW50MzJfdmFsdWUwYiA9CisgICAgICAgIG1lc3NhZ2UwYi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UwYiwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2U5YiA9IG1tZl9pbnQzMl9pbnQzMi5HZXQoOSwgZW50cnlfaW50MzJfaW50MzIuZ2V0KCkpOworICAgIGludDMyIGludDMyX3ZhbHVlOWIgPQorICAgICAgICBtZXNzYWdlOWIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlOWIsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKworICAgIEVYUEVDVF9FUShpbnQzMl92YWx1ZTlhLCBpbnQzMl92YWx1ZTBiKTsKKyAgICBFWFBFQ1RfRVEoaW50MzJfdmFsdWUwYSwgaW50MzJfdmFsdWU5Yik7CisgIH0KKworICB7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTBhID0KKyAgICAgICAgbW1mX2ludDMyX2RvdWJsZS5HZXQoMCwgZW50cnlfaW50MzJfZG91YmxlLmdldCgpKTsKKyAgICBkb3VibGUgZG91YmxlX3ZhbHVlMGEgPSBtZXNzYWdlMGEuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgIG1lc3NhZ2UwYSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTlhID0KKyAgICAgICAgbW1mX2ludDMyX2RvdWJsZS5HZXQoOSwgZW50cnlfaW50MzJfZG91YmxlLmdldCgpKTsKKyAgICBkb3VibGUgZG91YmxlX3ZhbHVlOWEgPSBtZXNzYWdlOWEuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgIG1lc3NhZ2U5YSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisKKyAgICBtbWZfaW50MzJfZG91YmxlLlN3YXBFbGVtZW50cygwLCA5KTsKKworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYiA9CisgICAgICAgIG1tZl9pbnQzMl9kb3VibGUuR2V0KDAsIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSk7CisgICAgZG91YmxlIGRvdWJsZV92YWx1ZTBiID0gbWVzc2FnZTBiLkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKAorICAgICAgICBtZXNzYWdlMGIsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2U5YiA9CisgICAgICAgIG1tZl9pbnQzMl9kb3VibGUuR2V0KDksIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSk7CisgICAgZG91YmxlIGRvdWJsZV92YWx1ZTliID0gbWVzc2FnZTliLkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKAorICAgICAgICBtZXNzYWdlOWIsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworCisgICAgRVhQRUNUX0VRKGRvdWJsZV92YWx1ZTlhLCBkb3VibGVfdmFsdWUwYik7CisgICAgRVhQRUNUX0VRKGRvdWJsZV92YWx1ZTBhLCBkb3VibGVfdmFsdWU5Yik7CisgIH0KKworICB7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTBhID0KKyAgICAgICAgbW1mX3N0cmluZ19zdHJpbmcuR2V0KDAsIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCkpOworICAgIHN0cmluZyBzdHJpbmdfdmFsdWUwYSA9IG1lc3NhZ2UwYS5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgbWVzc2FnZTBhLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTlhID0KKyAgICAgICAgbW1mX3N0cmluZ19zdHJpbmcuR2V0KDksIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCkpOworICAgIHN0cmluZyBzdHJpbmdfdmFsdWU5YSA9IG1lc3NhZ2U5YS5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgbWVzc2FnZTlhLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisKKyAgICBtbWZfc3RyaW5nX3N0cmluZy5Td2FwRWxlbWVudHMoMCwgOSk7CisKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMGIgPQorICAgICAgICBtbWZfc3RyaW5nX3N0cmluZy5HZXQoMCwgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSk7CisgICAgc3RyaW5nIHN0cmluZ192YWx1ZTBiID0gbWVzc2FnZTBiLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICBtZXNzYWdlMGIsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWIgPQorICAgICAgICBtbWZfc3RyaW5nX3N0cmluZy5HZXQoOSwgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSk7CisgICAgc3RyaW5nIHN0cmluZ192YWx1ZTliID0gbWVzc2FnZTliLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICBtZXNzYWdlOWIsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKworICAgIEVYUEVDVF9FUShzdHJpbmdfdmFsdWU5YSwgc3RyaW5nX3ZhbHVlMGIpOworICAgIEVYUEVDVF9FUShzdHJpbmdfdmFsdWUwYSwgc3RyaW5nX3ZhbHVlOWIpOworICB9CisKKyAgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYSA9CisgICAgICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuR2V0KDAsIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSk7CisgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHN1Yl9tZXNzYWdlMGEgPSBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgbWVzc2FnZTBhLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgLT5HZXRNZXNzYWdlKG1lc3NhZ2UwYSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgIGludDMyIGludDMyX3ZhbHVlMGEgPSBzdWJfbWVzc2FnZTBhLmMoKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWEgPQorICAgICAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldCg5LCBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCkpOworICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiBzdWJfbWVzc2FnZTlhID0gZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgIG1lc3NhZ2U5YS5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlOWEsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICBpbnQzMiBpbnQzMl92YWx1ZTlhID0gc3ViX21lc3NhZ2U5YS5jKCk7CisKKyAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLlN3YXBFbGVtZW50cygwLCA5KTsKKworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYiA9CisgICAgICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuR2V0KDAsIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSk7CisgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHN1Yl9tZXNzYWdlMGIgPSBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgbWVzc2FnZTBiLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgLT5HZXRNZXNzYWdlKG1lc3NhZ2UwYiwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgIGludDMyIGludDMyX3ZhbHVlMGIgPSBzdWJfbWVzc2FnZTBiLmMoKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWIgPQorICAgICAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldCg5LCBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCkpOworICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiBzdWJfbWVzc2FnZTliID0gZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgIG1lc3NhZ2U5Yi5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlOWIsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICBpbnQzMiBpbnQzMl92YWx1ZTliID0gc3ViX21lc3NhZ2U5Yi5jKCk7CisKKyAgICBFWFBFQ1RfRVEoaW50MzJfdmFsdWU5YSwgaW50MzJfdmFsdWUwYik7CisgICAgRVhQRUNUX0VRKGludDMyX3ZhbHVlMGEsIGludDMyX3ZhbHVlOWIpOworICB9Cit9CisKK1RFU1RfRihNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZXBlYXRlZEZpZWxkUmVmTWVyZ2VGcm9tQW5kU3dhcCkgeworICAvLyBTZXQtdXAgbWVzc2FnZSBjb250ZW50LgorICBUZXN0TWFwIG0wLCBtMSwgbTI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgICgqbTAubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbaV0gPSBGdW5jKGksIDEpOworICAgICgqbTAubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpW2ldID0gRnVuYyhpLCAyKTsKKyAgICAoKm0wLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbU3RyRnVuYyhpLCAxKV0gPSBTdHJGdW5jKGksIDUpOworICAgICgqbTAubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpW2ldLnNldF9jKEZ1bmMoaSwgNikpOworICAgICgqbTEubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbaSArIDEwXSA9IEZ1bmMoaSwgMTEpOworICAgICgqbTEubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpW2kgKyAxMF0gPSBGdW5jKGksIDEyKTsKKyAgICAoKm0xLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbU3RyRnVuYyhpICsgMTAsIDEpXSA9IFN0ckZ1bmMoaSwgMTUpOworICAgICgqbTEubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpW2kgKyAxMF0uc2V0X2MoRnVuYyhpLCAxNikpOworICAgICgqbTIubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbaSArIDIwXSA9IEZ1bmMoaSwgMjEpOworICAgICgqbTIubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpW2kgKyAyMF0gPSBGdW5jKGksIDIyKTsKKyAgICAoKm0yLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbU3RyRnVuYyhpICsgMjAsIDEpXSA9IFN0ckZ1bmMoaSwgMjUpOworICAgICgqbTIubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpW2kgKyAyMF0uc2V0X2MoRnVuYyhpLCAyNikpOworICB9CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG0wLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG0wLkdldERlc2NyaXB0b3IoKTsKKworICAvLyBHZXQgRmllbGREZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ludDMyIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2RvdWJsZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9kb3VibGUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfc3RyaW5nX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zdHJpbmdfc3RyaW5nIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKTsKKworICAgIC8vIEdldCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfaW50MzJfaW50MzIgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgJm0wLCBmZF9tYXBfaW50MzJfaW50MzIpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfaW50MzJfZG91YmxlID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICZtMCwgZmRfbWFwX2ludDMyX2RvdWJsZSk7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1tZl9zdHJpbmdfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICZtMCwgZmRfbWFwX3N0cmluZ19zdHJpbmcpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPgorICAgICAgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgICAgICZtMCwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6OkNvcHlGcm9tCisgIG1tZl9pbnQzMl9pbnQzMi5Db3B5RnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgbTEsIGZkX21hcF9pbnQzMl9pbnQzMikpOworICBtbWZfaW50MzJfZG91YmxlLkNvcHlGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtMSwgZmRfbWFwX2ludDMyX2RvdWJsZSkpOworICBtbWZfc3RyaW5nX3N0cmluZy5Db3B5RnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgbTEsIGZkX21hcF9zdHJpbmdfc3RyaW5nKSk7CisgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuQ29weUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgIG0xLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTEpLCBtMC5tYXBfaW50MzJfaW50MzIoKS5hdChpICsgMTApKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAxMiksIG0wLm1hcF9pbnQzMl9kb3VibGUoKS5hdChpICsgMTApKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAxNSksIG0wLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoU3RyRnVuYyhpICsgMTAsIDEpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTYpLCBtMC5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoaSArIDEwKS5jKCkpOworICB9CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6Ok1lcmdlRnJvbQorICBtbWZfaW50MzJfaW50MzIuTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtMiwgZmRfbWFwX2ludDMyX2ludDMyKSk7CisgIG1tZl9pbnQzMl9kb3VibGUuTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtMiwgZmRfbWFwX2ludDMyX2RvdWJsZSkpOworICBtbWZfc3RyaW5nX3N0cmluZy5NZXJnZUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgIG0yLCBmZF9tYXBfc3RyaW5nX3N0cmluZykpOworICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLk1lcmdlRnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgbTIsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjEpLCBtMC5tYXBfaW50MzJfaW50MzIoKS5hdChpICsgMjApKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyMiksIG0wLm1hcF9pbnQzMl9kb3VibGUoKS5hdChpICsgMjApKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAyNSksIG0wLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoU3RyRnVuYyhpICsgMjAsIDEpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjYpLCBtMC5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoaSArIDIwKS5jKCkpOworICB9CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6OlN3YXAKKyAgLy8gU3dhcCBiZXR3ZWVuIG0wIGFuZCBtMi4KKyAgbW1mX2ludDMyX2ludDMyLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICAmbTIsIGZkX21hcF9pbnQzMl9pbnQzMikpOworICBtbWZfaW50MzJfZG91YmxlLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICAmbTIsIGZkX21hcF9pbnQzMl9kb3VibGUpKTsKKyAgbW1mX3N0cmluZ19zdHJpbmcuU3dhcCgKKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICZtMiwgZmRfbWFwX3N0cmluZ19zdHJpbmcpKTsKKyAgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5Td2FwKAorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgJm0yLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIC8vIENoZWNrIHRoZSBjb250ZW50IG9mIG0wLgorICAgIEVYUEVDVF9FUShGdW5jKGksIDIxKSwgbTAubWFwX2ludDMyX2ludDMyKCkuYXQoaSArIDIwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjIpLCBtMC5tYXBfaW50MzJfZG91YmxlKCkuYXQoaSArIDIwKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMjUpLCBtMC5tYXBfc3RyaW5nX3N0cmluZygpLmF0KFN0ckZ1bmMoaSArIDIwLCAxKSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDI2KSwgbTAubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KGkgKyAyMCkuYygpKTsKKworICAgIC8vIENoZWNrIHRoZSBjb250ZW50IG9mIG0yLgorICAgIEVYUEVDVF9FUShGdW5jKGksIDExKSwgbTIubWFwX2ludDMyX2ludDMyKCkuYXQoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTIpLCBtMi5tYXBfaW50MzJfZG91YmxlKCkuYXQoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMTUpLCBtMi5tYXBfc3RyaW5nX3N0cmluZygpLmF0KFN0ckZ1bmMoaSArIDEwLCAxKSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDE2KSwgbTIubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KGkgKyAxMCkuYygpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyMSksIG0yLm1hcF9pbnQzMl9pbnQzMigpLmF0KGkgKyAyMCkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDIyKSwgbTIubWFwX2ludDMyX2RvdWJsZSgpLmF0KGkgKyAyMCkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIDI1KSwgbTIubWFwX3N0cmluZ19zdHJpbmcoKS5hdChTdHJGdW5jKGkgKyAyMCwgMSkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyNiksIG0yLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdChpICsgMjApLmMoKSk7CisgIH0KKworICAvLyBUT0RPKHRlYm9yaW5nKTogYWRkIHRlc3QgZm9yIGR1cGxpY2F0ZWQga2V5Cit9CisKKy8vIEdlbmVyYXRlZCBNZXNzYWdlIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgQWNjZXNzb3JzKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6Ok1vZGlmeU1hcEZpZWxkcygmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNNb2RpZmllZChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFNldE1hcEZpZWxkc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkc0luaXRpYWxpemVkKCZtZXNzYWdlKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkKG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgUHJvdG8yU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbnVtU3RhcnRXaXRoTm9uWmVyb01hcCBtZXNzYWdlOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlBST1RPMl9OT05fWkVST19NQVBfRU5VTV9GT08sCisgICAgICAgICAgICAoKm1lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF0pOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgQ2xlYXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBDbGVhck1lc3NhZ2VNYXApIHsKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlTWFwIG1lc3NhZ2U7CisKKyAgLy8gQ3JlYXRlcyBhIFRlc3RBbGxUeXBlcyB3aXRoIGRlZmF1bHQgdmFsdWUKKyAgVGVzdFV0aWw6OkV4cGVjdENsZWFyKCgqbWVzc2FnZS5tdXRhYmxlX21hcF9pbnQzMl9tZXNzYWdlKCkpWzBdKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENvcHlGcm9tKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UxKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7CisKKyAgLy8gQ29weWluZyBmcm9tIHNlbGYgc2hvdWxkIGJlIGEgbm8tb3AuCisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBDb3B5RnJvbU1lc3NhZ2VNYXApIHsKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlTWFwIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICAoKm1lc3NhZ2UxLm11dGFibGVfbWFwX2ludDMyX21lc3NhZ2UoKSlbMF0uYWRkX3JlcGVhdGVkX2ludDMyKDEwMCk7CisgICgqbWVzc2FnZTIubXV0YWJsZV9tYXBfaW50MzJfbWVzc2FnZSgpKVswXS5hZGRfcmVwZWF0ZWRfaW50MzIoMTAxKTsKKworICBtZXNzYWdlMS5Db3B5RnJvbShtZXNzYWdlMik7CisKKyAgLy8gQ2hlY2tzIHJlcGVhdGVkIGZpZWxkIGlzIG92ZXJ3cml0dGVuLgorICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTEubWFwX2ludDMyX21lc3NhZ2UoKS5hdCgwKS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAxLCBtZXNzYWdlMS5tYXBfaW50MzJfbWVzc2FnZSgpLmF0KDApLnJlcGVhdGVkX2ludDMyKDApKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFN3YXBXaXRoRW1wdHkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMik7CisKKyAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdENsZWFyKG1lc3NhZ2UxKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFN3YXBXaXRoU2VsZikgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworCisgIG1lc3NhZ2UuU3dhcCgmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBTd2FwV2l0aE90aGVyKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6Ok1vZGlmeU1hcEZpZWxkcygmbWVzc2FnZTIpOworCisgIG1lc3NhZ2UxLlN3YXAoJm1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc01vZGlmaWVkKG1lc3NhZ2UxKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBDb3B5Q29uc3RydWN0b3IpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTE7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMihtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgQ29weUFzc2lnbm1lbnRPcGVyYXRvcikgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMTsKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworCisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UyOworICBtZXNzYWdlMiA9IG1lc3NhZ2UxOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxmLWFzc2lnbm1lbnQgZG9lcyBzb21ldGhpbmcgc2FuZS4KKyAgbWVzc2FnZTIub3BlcmF0b3I9KG1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKKyNpZiAhZGVmaW5lZChQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTKSB8fCBcCisgICAgICAgICFkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9OT19SVFRJKQorVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFVwY2FzdENvcHlGcm9tKSB7CisgIC8vIFRlc3QgdGhlIENvcHlGcm9tIG1ldGhvZCB0aGF0IHRha2VzIGluIHRoZSBnZW5lcmljIGNvbnN0IE1lc3NhZ2UmCisgIC8vIHBhcmFtZXRlci4KKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKworICBjb25zdCBNZXNzYWdlKiBzb3VyY2UgPSBpbXBsaWNpdF9jYXN0PGNvbnN0IE1lc3NhZ2UqPigmbWVzc2FnZTEpOworICBtZXNzYWdlMi5Db3B5RnJvbSgqc291cmNlKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENvcHlGcm9tRHluYW1pY01lc3NhZ2UpIHsKKyAgLy8gVGVzdCBjb3B5aW5nIGZyb20gYSBEeW5hbWljTWVzc2FnZSwgd2hpY2ggbXVzdCBmYWxsIGJhY2sgdG8gdXNpbmcKKyAgLy8gcmVmbGVjdGlvbi4KKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisKKyAgLy8gQ29uc3RydWN0IGEgbmV3IHZlcnNpb24gb2YgdGhlIGR5bmFtaWMgbWVzc2FnZSB2aWEgdGhlIGZhY3RvcnkuCisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UxOworICBtZXNzYWdlMS5yZXNldCgKKyAgICAgIGZhY3RvcnkuR2V0UHJvdG90eXBlKHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpLT5OZXcoKSk7CisKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgICB1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0TWFwRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlMS5nZXQoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oKm1lc3NhZ2UxKTsKKworICBtZXNzYWdlMi5Db3B5RnJvbSgqbWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIER5bmFtaWNNZXNzYWdlQ29weUZyb20pIHsKKyAgLy8gVGVzdCBjb3B5aW5nIHRvIGEgRHluYW1pY01lc3NhZ2UsIHdoaWNoIG11c3QgZmFsbCBiYWNrIHRvIHVzaW5nIHJlZmxlY3Rpb24uCisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UyOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMik7CisKKyAgLy8gQ29uc3RydWN0IGEgbmV3IHZlcnNpb24gb2YgdGhlIGR5bmFtaWMgbWVzc2FnZSB2aWEgdGhlIGZhY3RvcnkuCisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UxOworICBtZXNzYWdlMS5yZXNldCgKKyAgICAgIGZhY3RvcnkuR2V0UHJvdG90eXBlKHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpLT5OZXcoKSk7CisKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgICB1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKTsKKyAgbWVzc2FnZTEtPk1lcmdlRnJvbShtZXNzYWdlMik7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oKm1lc3NhZ2UxKTsKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgTm9uRW1wdHlNZXJnZUZyb20pIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKworICAvLyBUaGlzIGZpZWxkIHdpbGwgdGVzdCBtZXJnaW5nIGludG8gYW4gZW1wdHkgc3BvdC4KKyAgKCptZXNzYWdlMi5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpKVsxXSA9IDE7CisgIG1lc3NhZ2UxLm11dGFibGVfbWFwX2ludDMyX2ludDMyKCktPmVyYXNlKDEpOworCisgIC8vIFRoaXMgdGVzdHMgb3ZlcndyaXRpbmcuCisgICgqbWVzc2FnZTIubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlMS5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKSlbMV0gPSAyOworCisgIG1lc3NhZ2UxLk1lcmdlRnJvbShtZXNzYWdlMik7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTEpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgTWVyZ2VGcm9tTWVzc2FnZU1hcCkgeworICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgICgqbWVzc2FnZTEubXV0YWJsZV9tYXBfaW50MzJfbWVzc2FnZSgpKVswXS5hZGRfcmVwZWF0ZWRfaW50MzIoMTAwKTsKKyAgKCptZXNzYWdlMi5tdXRhYmxlX21hcF9pbnQzMl9tZXNzYWdlKCkpWzBdLmFkZF9yZXBlYXRlZF9pbnQzMigxMDEpOworCisgIG1lc3NhZ2UxLk1lcmdlRnJvbShtZXNzYWdlMik7CisKKyAgLy8gQ2hlY2tzIHJlcGVhdGVkIGZpZWxkIGlzIG92ZXJ3cml0dGVuLgorICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTEubWFwX2ludDMyX21lc3NhZ2UoKS5hdCgwKS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAxLCBtZXNzYWdlMS5tYXBfaW50MzJfbWVzc2FnZSgpLmF0KDApLnJlcGVhdGVkX2ludDMyKDApKTsKK30KKworLy8gVGVzdCB0aGUgZ2VuZXJhdGVkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoKQorVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFNlcmlhbGl6YXRpb25Ub0FycmF5KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgc3RyaW5nIGRhdGE7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZGF0YSkpOworICB1aW50OCogZW5kID0gbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIEVYUEVDVF9FUShzaXplLCBlbmQgLSBzdGFydCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCisvLyBUZXN0IHRoZSBnZW5lcmF0ZWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCkKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMSk7CisgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgc3RyaW5nIGRhdGE7CisgIGRhdGEucmVzaXplKHNpemUpOworICB7CisgICAgLy8gQWxsb3cgdGhlIG91dHB1dCBzdHJlYW0gdG8gYnVmZmVyIG9ubHkgb25lIGJ5dGUgYXQgYSB0aW1lLgorICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgb3V0cHV0X3N0cmVhbS5CeXRlQ291bnQoKSk7CisgIH0KKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFNhbWVUeXBlTWFwcykgeworICBjb25zdCBEZXNjcmlwdG9yKiBtYXAxID0gdW5pdHRlc3Q6OlRlc3RTYW1lVHlwZU1hcDo6ZGVzY3JpcHRvcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5GaW5kRmllbGRCeU5hbWUoIm1hcDEiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+bWVzc2FnZV90eXBlKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1hcDIgPSB1bml0dGVzdDo6VGVzdFNhbWVUeXBlTWFwOjpkZXNjcmlwdG9yKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPkZpbmRGaWVsZEJ5TmFtZSgibWFwMiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5tZXNzYWdlX3R5cGUoKTsKKworICBjb25zdCBNZXNzYWdlKiBtYXAxX2VudHJ5ID0KKyAgICAgIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLT5HZXRQcm90b3R5cGUobWFwMSk7CisgIGNvbnN0IE1lc3NhZ2UqIG1hcDJfZW50cnkgPQorICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZShtYXAyKTsKKworICBFWFBFQ1RfRVEobWFwMSwgbWFwMV9lbnRyeS0+R2V0RGVzY3JpcHRvcigpKTsKKyAgRVhQRUNUX0VRKG1hcDIsIG1hcDJfZW50cnktPkdldERlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBQcm90bzJVbmtub3duRW51bSkgeworICB1bml0dGVzdDo6VGVzdEVudW1NYXBQbHVzRXh0cmEgZnJvbTsKKyAgKCpmcm9tLm11dGFibGVfa25vd25fbWFwX2ZpZWxkKCkpWzBdID0gdW5pdHRlc3Q6OkVfUFJPVE8yX01BUF9FTlVNX0ZPTzsKKyAgKCpmcm9tLm11dGFibGVfdW5rbm93bl9tYXBfZmllbGQoKSlbMF0gPSB1bml0dGVzdDo6RV9QUk9UTzJfTUFQX0VOVU1fRVhUUkE7CisgIHN0cmluZyBkYXRhOworICBmcm9tLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICB1bml0dGVzdDo6VGVzdEVudW1NYXAgdG87CisgIEVYUEVDVF9UUlVFKHRvLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9FUSgwLCB0by51bmtub3duX21hcF9maWVsZCgpLnNpemUoKSk7CisgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZF9zZXQgPQorICAgICAgdG8uR2V0UmVmbGVjdGlvbigpLT5HZXRVbmtub3duRmllbGRzKHRvKTsKKyAgRVhQRUNUX0VRKDEsIHVua25vd25fZmllbGRfc2V0LmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgdG8ua25vd25fbWFwX2ZpZWxkKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpQUk9UTzJfTUFQX0VOVU1fRk9PLCB0by5rbm93bl9tYXBfZmllbGQoKS5hdCgwKSk7CisKKyAgZGF0YS5jbGVhcigpOworICBmcm9tLkNsZWFyKCk7CisgIHRvLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgRVhQRUNUX1RSVUUoZnJvbS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMCwgZnJvbS5HZXRSZWZsZWN0aW9uKCktPkdldFVua25vd25GaWVsZHMoZnJvbSkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBmcm9tLmtub3duX21hcF9maWVsZCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6RV9QUk9UTzJfTUFQX0VOVU1fRk9PLCBmcm9tLmtub3duX21hcF9maWVsZCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDEsIGZyb20udW5rbm93bl9tYXBfZmllbGQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkVfUFJPVE8yX01BUF9FTlVNX0VYVFJBLCBmcm9tLnVua25vd25fbWFwX2ZpZWxkKCkuYXQoMCkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgU3RhbmRhcmRXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIHN0cmluZyBkYXRhID0gIlx4MEFceDA0XHgwOFx4MDFceDEwXHgwMSI7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgxKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBVbm9yZGVyZWRXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gcHV0IHZhbHVlIGJlZm9yZSBrZXkgaW4gd2lyZSBmb3JtYXQKKyAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDRceDEwXHgwMVx4MDhceDAyIjsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDIpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIER1cGxpY2F0ZWRLZXlXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gVHdvIGtleSBmaWVsZHMgaW4gd2lyZSBmb3JtYXQKKyAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDZceDA4XHgwMVx4MDhceDAyXHgxMFx4MDEiOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMikpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgRHVwbGljYXRlZFZhbHVlV2lyZUZvcm1hdCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIC8vIFR3byB2YWx1ZSBmaWVsZHMgaW4gd2lyZSBmb3JtYXQKKyAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDZceDA4XHgwMVx4MTBceDAxXHgxMFx4MDIiOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMSkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgTWlzc2VkS2V5V2lyZUZvcm1hdCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIC8vIE5vIGtleSBmaWVsZCBpbiB3aXJlIGZvcm1hdAorICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwMlx4MTBceDAxIjsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDApKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIE1pc3NlZFZhbHVlV2lyZUZvcm1hdCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIC8vIE5vIHZhbHVlIGZpZWxkIGluIHdpcmUgZm9ybWF0CisgIHN0cmluZyBkYXRhID0gIlx4MEFceDAyXHgwOFx4MDEiOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMSkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgTWlzc2VkVmFsdWVUZXh0Rm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gTm8gdmFsdWUgZmllbGQgaW4gdGV4dCBmb3JtYXQKKyAgc3RyaW5nIHRleHQgPQorICAgICAgIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Uge1xuIgorICAgICAgIiAga2V5OiAxMjM0NTY3ODkwXG4iCisgICAgICAifSI7CisKKyAgRVhQRUNUX1RSVUUoZ29vZ2xlOjpwcm90b2J1Zjo6VGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKHRleHQsICZtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTEsIG1lc3NhZ2UuQnl0ZVNpemUoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBVbmtub3duRmllbGRXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gVW5rbm93biBmaWVsZCBpbiB3aXJlIGZvcm1hdAorICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNlx4MDhceDAyXHgxMFx4MDNceDE4XHgwMSI7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMywgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgyKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBDb3JydXB0ZWRXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gY29ycnVwdGVkIGRhdGEgaW4gd2lyZSBmb3JtYXQKKyAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDZceDA4XHgwMlx4MTFceDAzIjsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgSXNJbml0aWFsaXplZCkgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBtYXBfbWVzc2FnZTsKKworICAvLyBBZGQgYW4gdW5pbml0aWFsaXplZCBtZXNzYWdlLgorICAoKm1hcF9tZXNzYWdlLm11dGFibGVfbWFwX2ZpZWxkKCkpWzBdOworICBFWFBFQ1RfRkFMU0UobWFwX21lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKworICAvLyBJbml0aWFsaXplIHVuaW5pdGlhbGl6ZWQgbWVzc2FnZQorICAoKm1hcF9tZXNzYWdlLm11dGFibGVfbWFwX2ZpZWxkKCkpWzBdLnNldF9hKDApOworICAoKm1hcF9tZXNzYWdlLm11dGFibGVfbWFwX2ZpZWxkKCkpWzBdLnNldF9iKDApOworICAoKm1hcF9tZXNzYWdlLm11dGFibGVfbWFwX2ZpZWxkKCkpWzBdLnNldF9jKDApOworICBFWFBFQ1RfVFJVRShtYXBfbWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworfQorCisvLyBHZW5lcmF0ZWQgTWVzc2FnZSBSZWZsZWN0aW9uIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBTcGFjZVVzZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworCisgIEVYUEVDVF9MVCgwLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+U3BhY2VVc2VkKG1lc3NhZ2UpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBBY2Nlc3NvcnMpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlIHRoZW4gZ28gYmFjayBhbmQgY2hlY2sgYWxsIHRob3NlCisgIC8vIHZhbHVlcy4KKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLk1vZGlmeU1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgU3dhcCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFN3YXBXaXRoQm90aFNldCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMik7CisgIE1hcFRlc3RVdGlsOjpNb2RpZnlNYXBGaWVsZHMoJm1lc3NhZ2UyKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBTd2FwRmllbGRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMjsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMik7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlMiwgJmZpZWxkcyk7CisgIHJlZmxlY3Rpb24tPlN3YXBGaWVsZHMoJm1lc3NhZ2UxLCAmbWVzc2FnZTIsIGZpZWxkcyk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgQ2xlYXJGaWVsZCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKKworICBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5DbGVhck1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVtb3ZlTGFzdCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUobWVzc2FnZSwgMik7CisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBleHBlY3RlZF9lbnRyaWVzID0KKyAgICAgIE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzKG1lc3NhZ2UsIDApOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlJlbW92ZUxhc3RNYXBzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcHNTaXplKG1lc3NhZ2UsIDEpOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gcmVtYWluZWRfZW50cmllcyA9CisgICAgICBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAwKTsKKyAgRVhQRUNUX1RSVUUoZXhwZWN0ZWRfZW50cmllcyA9PSByZW1haW5lZF9lbnRyaWVzKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZWxlYXNlTGFzdCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIE1hcFRlc3RVdGlsOjpNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKGRlc2NyaXB0b3IpOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBzU2l6ZShtZXNzYWdlLCAyKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5SZWxlYXNlTGFzdE1hcHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUobWVzc2FnZSwgMSk7CisKKyAgLy8gTm93IHRlc3QgdGhhdCB3ZSBhY3R1YWxseSByZWxlYXNlIHRoZSByaWdodCBtZXNzYWdlLgorICBtZXNzYWdlLkNsZWFyKCk7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBzU2l6ZShtZXNzYWdlLCAyKTsKKyAgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IGV4cGVjdF9sYXN0ID0KKyAgICAgIE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzKG1lc3NhZ2UsIDEpOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gcmVsZWFzZV9sYXN0ID0KKyAgICAgIE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzRnJvbVJlbGVhc2UoJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUobWVzc2FnZSwgMSk7CisgIEVYUEVDVF9UUlVFKGV4cGVjdF9sYXN0ID09IHJlbGVhc2VfbGFzdCk7CisgIGZvciAoc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+OjppdGVyYXRvciBpdCA9IHJlbGVhc2VfbGFzdC5iZWdpbigpOworICAgICAgIGl0ICE9IHJlbGVhc2VfbGFzdC5lbmQoKTsgKytpdCkgeworICAgIGRlbGV0ZSAqaXQ7CisgIH0KK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBTd2FwRWxlbWVudHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgLy8gR2V0IHBvaW50ZXJzIG9mIG1hcCBlbnRyaWVzIGF0IHRoZWlyIG9yaWdpbmFsIHBvc2l0aW9uCisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBlbnRyaWVzMCA9IE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzKG1lc3NhZ2UsIDApOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZW50cmllczEgPSBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAxKTsKKworICAvLyBTd2FwIHRoZSBmaXJzdCB0aW1lLgorICByZWZsZWN0aW9uX3Rlc3Rlci5Td2FwTWFwc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworCisgIC8vIEdldCBwb2ludGVyIG9mIG1hcCBlbnRyeSBhZnRlciBzd2FwIG9uY2UuCisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBlbnRyaWVzMF9vbmNlID0KKyAgICAgIE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzKG1lc3NhZ2UsIDApOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZW50cmllczFfb25jZSA9CisgICAgICBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAxKTsKKworICAvLyBUZXN0IG1hcCBlbnRyaWVzIGFyZSBzd2FwcGVkLgorICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUobWVzc2FnZSwgMik7CisgIEVYUEVDVF9UUlVFKGVudHJpZXMwID09IGVudHJpZXMxX29uY2UpOworICBFWFBFQ1RfVFJVRShlbnRyaWVzMSA9PSBlbnRyaWVzMF9vbmNlKTsKKworICAvLyBTd2FwIHRoZSBzZWNvbmQgdGltZS4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU3dhcE1hcHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKworICAvLyBHZXQgcG9pbnRlciBvZiBtYXAgZW50cnkgYWZ0ZXIgc3dhcCBvbmNlLgorICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZW50cmllczBfdHdpY2UgPQorICAgICAgTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXMobWVzc2FnZSwgMCk7CisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBlbnRyaWVzMV90d2ljZSA9CisgICAgICBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAxKTsKKworICAvLyBUZXN0IG1hcCBlbnRyaWVzIGFyZSBzd2FwcGVkIGJhY2suCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBzU2l6ZShtZXNzYWdlLCAyKTsKKyAgRVhQRUNUX1RSVUUoZW50cmllczAgPT0gZW50cmllczBfdHdpY2UpOworICBFWFBFQ1RfVFJVRShlbnRyaWVzMSA9PSBlbnRyaWVzMV90d2ljZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgTXV0YWJsZVVua25vd25GaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLk11dGFibGVVbmtub3duRmllbGRzT2ZNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBFbWJlZFByb3RvMk1lc3NhZ2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlTWFwIG1lc3NhZ2U7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZmllbGQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlTWFwOjpkZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAibWFwX2ludDMyX21lc3NhZ2UiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9CisgICAgICBtYXBfZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisKKyAgTWVzc2FnZSogZW50cnlfbWVzc2FnZSA9CisgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+QWRkTWVzc2FnZSgmbWVzc2FnZSwgbWFwX2ZpZWxkKTsKKyAgRVhQRUNUX0VRKAorICAgICAgJmVudHJ5X21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0TWVzc2FnZSgqZW50cnlfbWVzc2FnZSwgdmFsdWUpLAorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBNZXNzYWdlKj4oJlRlc3RBbGxUeXBlczo6ZGVmYXVsdF9pbnN0YW5jZSgpKSk7CisKKyAgTWVzc2FnZSogcHJvdG8yX21lc3NhZ2UgPQorICAgICAgZW50cnlfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlTWVzc2FnZShlbnRyeV9tZXNzYWdlLCB2YWx1ZSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCksCisgICAgICAgICAgICBwcm90bzJfbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX21lc3NhZ2UoKS5zaXplKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIE1lcmdlRnJvbUNsZWFyTWFwRW50cnkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZmllbGQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPQorICAgICAgbWFwX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9CisgICAgICBtYXBfZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisKKyAgTWVzc2FnZSogZW50cnlfbWVzc2FnZTEgPQorICAgICAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkFkZE1lc3NhZ2UoJm1lc3NhZ2UsIG1hcF9maWVsZCk7CisgIEVYUEVDVF9GQUxTRShlbnRyeV9tZXNzYWdlMS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTEsIGtleSkpOworICBFWFBFQ1RfRkFMU0UoCisgICAgICBlbnRyeV9tZXNzYWdlMS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTEsIHZhbHVlKSk7CisKKyAgTWVzc2FnZSogZW50cnlfbWVzc2FnZTIgPQorICAgICAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkFkZE1lc3NhZ2UoJm1lc3NhZ2UsIG1hcF9maWVsZCk7CisgIEVYUEVDVF9GQUxTRShlbnRyeV9tZXNzYWdlMi0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTIsIGtleSkpOworICBFWFBFQ1RfRkFMU0UoCisgICAgICBlbnRyeV9tZXNzYWdlMi0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTIsIHZhbHVlKSk7CisKKyAgZW50cnlfbWVzc2FnZTEtPk1lcmdlRnJvbSgqZW50cnlfbWVzc2FnZTIpOworICBFWFBFQ1RfRkFMU0UoZW50cnlfbWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKmVudHJ5X21lc3NhZ2UxLCBrZXkpKTsKKyAgRVhQRUNUX0ZBTFNFKAorICAgICAgZW50cnlfbWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKmVudHJ5X21lc3NhZ2UxLCB2YWx1ZSkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIE1hcEVudHJ5Q2xlYXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLk11dGFibGVVbmtub3duRmllbGRzT2ZNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBQcm90bzJNYXBFbnRyeUNsZWFyKSB7CisgIHVuaXR0ZXN0OjpUZXN0RW51bVN0YXJ0V2l0aE5vblplcm9NYXAgbWVzc2FnZTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IgPQorICAgICAgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfZmllbGQiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgIGZpZWxkX2Rlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlID0KKyAgICAgIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5BZGRNZXNzYWdlKCZtZXNzYWdlLCBmaWVsZF9kZXNjcmlwdG9yKTsKKyAgRVhQRUNUX0VRKDEsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEVudW1WYWx1ZSgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworfQorCisvLyBEeW5hbWljIE1lc3NhZ2UgVGVzdCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgTWFwRmllbGRJbkR5bmFtaWNNZXNzYWdlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sXzsKKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3RvcnlfOworICBjb25zdCBEZXNjcmlwdG9yKiBtYXBfZGVzY3JpcHRvcl87CisgIGNvbnN0IE1lc3NhZ2UqIG1hcF9wcm90b3R5cGVfOworCisgIE1hcEZpZWxkSW5EeW5hbWljTWVzc2FnZVRlc3QoKQorICAgICAgOiBwb29sXyhEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSksIGZhY3RvcnlfKHBvb2xfKSB7fQorCisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBtYXBfZGVzY3JpcHRvcl8gPQorICAgICAgcG9vbF8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCIpOworICAgIEFTU0VSVF9UUlVFKG1hcF9kZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgICBtYXBfcHJvdG90eXBlXyA9IGZhY3RvcnlfLkdldFByb3RvdHlwZShtYXBfZGVzY3JpcHRvcl8pOworICB9Cit9OworCitURVNUX0YoTWFwRmllbGRJbkR5bmFtaWNNZXNzYWdlVGVzdCwgTWFwSW5kZXBlbmRlbnRPZmZzZXRzKSB7CisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIGluZGVwZW5kZW50IG9mZnNldHMgYnkgc2V0dGluZyBlYWNoCisgIC8vIG9uZSB0byBhIHVuaXF1ZSB2YWx1ZSB0aGVuIGNoZWNraW5nIHRoYXQgdGhleSBhbGwgc3RpbGwgaGF2ZSB0aG9zZQorICAvLyB1bmlxdWUgdmFsdWVzIChpLmUuIHRoZXkgZG9uJ3Qgc3RvbXAgZWFjaCBvdGhlcikuCisgIHNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShtYXBfcHJvdG90eXBlXy0+TmV3KCkpOworICBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihtYXBfZGVzY3JpcHRvcl8pOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24obWVzc2FnZS5nZXQoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oKm1lc3NhZ2UpOworfQorCitURVNUX0YoTWFwRmllbGRJbkR5bmFtaWNNZXNzYWdlVGVzdCwgTWFwKSB7CisgIC8vIENoZWNrIHRoYXQgbWFwIGZpZWxkcyB3b3JrIHByb3Blcmx5LgorICBzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UobWFwX3Byb3RvdHlwZV8tPk5ldygpKTsKKworICAvLyBDaGVjayBzZXQgZnVuY3Rpb25zLgorICBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihtYXBfZGVzY3JpcHRvcl8pOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UuZ2V0KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlKTsKK30KKworVEVTVF9GKE1hcEZpZWxkSW5EeW5hbWljTWVzc2FnZVRlc3QsIE1hcFNwYWNlVXNlZCkgeworICAvLyBUZXN0IHRoYXQgU3BhY2VVc2VkKCkgd29ya3MgcHJvcGVybHkKKworICAvLyBTaW5jZSB3ZSBzaGFyZSB0aGUgaW1wbGVtZW50YXRpb24gd2l0aCBnZW5lcmF0ZWQgbWVzc2FnZXMsIHdlIGRvbid0IG5lZWQKKyAgLy8gdG8gdGVzdCB2ZXJ5IG11Y2ggaGVyZS4gIEp1c3QgbWFrZSBzdXJlIGl0IGFwcGVhcnMgdG8gYmUgd29ya2luZy4KKworICBzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UobWFwX3Byb3RvdHlwZV8tPk5ldygpKTsKKyAgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIobWFwX2Rlc2NyaXB0b3JfKTsKKworICBpbnQgaW5pdGlhbF9zcGFjZV91c2VkID0gbWVzc2FnZS0+U3BhY2VVc2VkKCk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0TWFwRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgRVhQRUNUX0xUKGluaXRpYWxfc3BhY2VfdXNlZCwgbWVzc2FnZS0+U3BhY2VVc2VkKCkpOworfQorCisvLyBSZWZsZWN0aW9uT3BzIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVChSZWZsZWN0aW9uT3BzRm9yTWFwRmllbGRUZXN0LCBNYXBTYW5pdHlDaGVjaykgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNGb3JNYXBGaWVsZFRlc3QsIE1hcENvcHkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZSwgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworCisgIC8vIENvcHlpbmcgZnJvbSBzZWxmIHNob3VsZCBiZSBhIG5vLW9wLgorICBSZWZsZWN0aW9uT3BzOjpDb3B5KG1lc3NhZ2UyLCAmbWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzRm9yTWFwRmllbGRUZXN0LCBNZXJnZU1hcCkgeworICAvLyBOb3RlOiAgQ29weSBpcyBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiBNZXJnZSgpIHNvIHRlY2huaWNhbGx5IHRoZSBDb3B5CisgIC8vICAgdGVzdCBhbHJlYWR5IHRlc3RlZCBtb3N0IG9mIHRoaXMuCisKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZSwgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6TWVyZ2UobWVzc2FnZTIsICZtZXNzYWdlKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNGb3JNYXBGaWVsZFRlc3QsIENsZWFyTWFwKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzRm9yTWFwRmllbGRUZXN0LCBNYXBEaXNjYXJkVW5rbm93bkZpZWxkcykgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKworICAvLyBTZXQgc29tZSB1bmtub3duIGZpZWxkcyBpbiBtZXNzYWdlLgorICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoJm1lc3NhZ2UpLT4KKyAgICAgIEFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisKKyAgLy8gRGlzY2FyZCB0aGVtLgorICBSZWZsZWN0aW9uT3BzOjpEaXNjYXJkVW5rbm93bkZpZWxkcygmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT4KKyAgICAgIEdldFVua25vd25GaWVsZHMobWVzc2FnZSkuZmllbGRfY291bnQoKSk7Cit9CisKKy8vIFdpcmUgRm9ybWF0IFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKFdpcmVGb3JtYXRGb3JNYXBGaWVsZFRlc3QsIFBhcnNlTWFwKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIHNvdXJjZSwgZGVzdDsKKyAgc3RyaW5nIGRhdGE7CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBQYXJzZSB1c2luZyBXaXJlRm9ybWF0LgorICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJmRlc3QpOworCisgIC8vIENoZWNrLgorICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRGb3JNYXBGaWVsZFRlc3QsIE1hcEJ5dGVTaXplKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIEVYUEVDVF9FUShtZXNzYWdlLkJ5dGVTaXplKCksIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKK30KKworVEVTVChXaXJlRm9ybWF0Rm9yTWFwRmllbGRUZXN0LCBTZXJpYWxpemVNYXApIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgc3RyaW5nIGdlbmVyYXRlZF9kYXRhOworICBzdHJpbmcgZHluYW1pY19kYXRhOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIHsKKyAgICBtZXNzYWdlLkJ5dGVTaXplKCk7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZnZW5lcmF0ZWRfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgbWVzc2FnZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dCk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgfQorCisgIC8vIFNlcmlhbGl6ZSB1c2luZyBXaXJlRm9ybWF0LgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZkeW5hbWljX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIGludCBzaXplID0gV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZSk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG1lc3NhZ2UsIHNpemUsICZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTaG91bGQgYmUgdGhlIHNhbWUuCisgIC8vIERvbid0IHVzZSBFWFBFQ1RfRVEgaGVyZSBiZWNhdXNlIHdlJ3JlIGNvbXBhcmluZyByYXcgYmluYXJ5IGRhdGEgYW5kCisgIC8vIHdlIHJlYWxseSBkb24ndCB3YW50IGl0IGR1bXBlZCB0byBzdGRvdXQgb24gZmFpbHVyZS4KKyAgRVhQRUNUX1RSVUUoZHluYW1pY19kYXRhID09IGdlbmVyYXRlZF9kYXRhKTsKK30KKworVEVTVChXaXJlRm9ybWF0Rm9yTWFwRmllbGRUZXN0LCBNYXBQYXJzZUhlbHBlcnMpIHsKKyAgc3RyaW5nIGRhdGE7CisKKyAgeworICAgIC8vIFNldCB1cC4KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICAgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgUGFyc2VGcm9tU3RyaW5nLgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBQYXJzZUZyb21Jc3RyZWFtLgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgICAgc3RyaW5nc3RyZWFtIHN0cmVhbShkYXRhKTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbUlzdHJlYW0oJnN0cmVhbSkpOworICAgIEVYUEVDVF9UUlVFKHN0cmVhbS5lb2YoKSk7CisgICAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IFBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbS4KKyAgICBzdHJpbmcgZGF0YV93aXRoX2p1bmsoZGF0YSk7CisgICAgZGF0YV93aXRoX2p1bmsuYXBwZW5kKCJzb21lIGp1bmsgb24gdGhlIGVuZCIpOworICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHN0cmVhbShkYXRhX3dpdGhfanVuay5kYXRhKCksIGRhdGFfd2l0aF9qdW5rLnNpemUoKSk7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgmc3RyZWFtLCBkYXRhLnNpemUoKSkpOworICAgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCB0aGF0IFBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSBmYWlscyAoYnV0IGRvZXNuJ3QgY3Jhc2gpIGlmCisgICAgLy8gRU9GIGlzIHJlYWNoZWQgYmVmb3JlIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgYnl0ZXMuCisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gc3RyZWFtKGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICAgIEVYUEVDVF9GQUxTRSgKKyAgICAgIG1lc3NhZ2UuUGFyc2VGcm9tQm91bmRlZFplcm9Db3B5U3RyZWFtKCZzdHJlYW0sIGRhdGEuc2l6ZSgpICsgMSkpOworICB9Cit9CisKKy8vIFRleHQgRm9ybWF0IFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKFRleHRGb3JtYXRNYXBUZXN0LCBTZXJpYWxpemVBbmRQYXJzZSkgeworICB1bml0dGVzdDo6VGVzdE1hcCBzb3VyY2U7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIGRlc3Q7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJnNvdXJjZSk7CisgIHN0cmluZyBvdXRwdXQ7CisKKyAgLy8gVGVzdCBjb21wYWN0IEFTQ0lJCisgIFRleHRGb3JtYXQ6OlByaW50ZXIgcHJpbnRlcjsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKHNvdXJjZSwgJm91dHB1dCk7CisgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisgIEVYUEVDVF9UUlVFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcob3V0cHV0LCAmZGVzdCkpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KGRlc3QpOworfQorCisKKy8vIGFyZW5hIHN1cHBvcnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorVEVTVChBcmVuYVRlc3QsIFBhcnNpbmdBbmRTZXJpYWxpemluZ05vSGVhcEFsbG9jYXRpb24pIHsKKyAgLy8gQWxsb2NhdGUgYSBsYXJnZSBpbml0aWFsIGJsb2NrIHRvIGF2b2lkIG1hbGxvY3MgZHVyaW5nIGhvb2tlZCB0ZXN0LgorICBzdGQ6OnZlY3RvcjxjaGFyPiBhcmVuYV9ibG9jaygxMjggKiAxMDI0KTsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9IGFyZW5hX2Jsb2NrLmRhdGEoKTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hKG9wdGlvbnMpOworICBzdHJpbmcgZGF0YTsKKyAgZGF0YS5yZXNlcnZlKDEyOCAqIDEwMjQpOworCisgIHsKKyAgICBOb0hlYXBDaGVja2VyIG5vX2hlYXA7CisKKyAgICB1bml0dGVzdDo6VGVzdEFyZW5hTWFwKiBmcm9tID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBcmVuYU1hcD4oJmFyZW5hKTsKKyAgICBNYXBUZXN0VXRpbDo6U2V0QXJlbmFNYXBGaWVsZHMoZnJvbSk7CisgICAgZnJvbS0+U2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgICAgdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCogdG8gPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFyZW5hTWFwPigmYXJlbmEpOworICAgIHRvLT5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgTWFwVGVzdFV0aWw6OkV4cGVjdEFyZW5hTWFwRmllbGRzU2V0KCp0byk7CisgIH0KK30KKworLy8gVXNlIHRleHQgZm9ybWF0IHBhcnNpbmcgYW5kIHNlcmlhbGl6aW5nIHRvIHRlc3QgcmVmbGVjdGlvbiBhcGkuCitURVNUKEFyZW5hVGVzdCwgUmVsZmVjdGlvbkluVGV4dEZvcm1hdCkgeworICBBcmVuYSBhcmVuYTsKKyAgc3RyaW5nIGRhdGE7CisKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBUZXh0Rm9ybWF0OjpQYXJzZXIgcGFyc2VyOworCisgIHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXAqIGZyb20gPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBcmVuYU1hcD4oJmFyZW5hKTsKKyAgdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCogdG8gPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBcmVuYU1hcD4oJmFyZW5hKTsKKworICBNYXBUZXN0VXRpbDo6U2V0QXJlbmFNYXBGaWVsZHMoZnJvbSk7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZygqZnJvbSwgJmRhdGEpOworCisgIEVYUEVDVF9UUlVFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcoZGF0YSwgdG8pKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdEFyZW5hTWFwRmllbGRzU2V0KCp0byk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTcxM2UzNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5jYwpAQCAtMCwwICsxLDEyNjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbF9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3ZvaWQgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcyh1bml0dGVzdDo6VGVzdE1hcCogbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OlNldE1hcEZpZWxkczx1bml0dGVzdDo6TWFwRW51bSwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBWj4obWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6OlNldEFyZW5hTWFwRmllbGRzKHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXAqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpTZXRBcmVuYU1hcEZpZWxkczx1bml0dGVzdDo6TWFwRW51bSwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFaPihtZXNzYWdlKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQodW5pdHRlc3Q6OlRlc3RNYXAqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpTZXRNYXBGaWVsZHNJbml0aWFsaXplZChtZXNzYWdlKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6TW9kaWZ5TWFwRmllbGRzKHVuaXR0ZXN0OjpUZXN0TWFwKiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6TW9kaWZ5TWFwRmllbGRzPHVuaXR0ZXN0OjpNYXBFbnVtLCB1bml0dGVzdDo6TUFQX0VOVU1fRk9PPigKKyAgICAgIG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdENsZWFyKG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RNYXBGaWVsZHNTZXQ8dW5pdHRlc3Q6Ok1hcEVudW0sIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVo+KG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpFeHBlY3RBcmVuYU1hcEZpZWxkc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFyZW5hTWFwJiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQ8CisgICAgICB1bml0dGVzdDo6TWFwRW51bSwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUiwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBWj4oCisgICAgICBtZXNzYWdlKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RNYXBGaWVsZHNTZXRJbml0aWFsaXplZDx1bml0dGVzdDo6TWFwRW51bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fRk9PPigKKyAgICAgIG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc01vZGlmaWVkPAorICAgICAgdW5pdHRlc3Q6Ok1hcEVudW0sIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVIsIHVuaXR0ZXN0OjpNQVBfRU5VTV9GT08+KAorICAgICAgbWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcHNTaXplKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlLCBpbnQgc2l6ZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQ2NF9pbnQ2NCIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3VpbnQzMl91aW50MzIiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF91aW50NjRfdWludDY0IikpKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ludDMyX3NpbnQzMiIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3NpbnQ2NF9zaW50NjQiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3NmaXhlZDY0X3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZmxvYXQiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9kb3VibGUiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9ib29sX2Jvb2wiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zdHJpbmdfc3RyaW5nIikpKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfYnl0ZXMiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkpOworfQorCitzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXMoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UsIGludCBpbmRleCkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiByZXN1bHQ7CisKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9pbnQzMiIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDY0X2ludDY0IiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfdWludDMyX3VpbnQzMiIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3VpbnQ2NF91aW50NjQiKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zaW50MzJfc2ludDMyIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ludDY0X3NpbnQ2NCIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ZpeGVkMzJfZml4ZWQzMiIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3NmaXhlZDMyX3NmaXhlZDMyIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mbG9hdCIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2RvdWJsZSIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2Jvb2xfYm9vbCIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3N0cmluZ19zdHJpbmciKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9ieXRlcyIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2VudW0iKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSwgaW5kZXgpKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXNGcm9tUmVsZWFzZSgKKyAgICB1bml0dGVzdDo6VGVzdE1hcCogbWVzc2FnZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gcmVzdWx0OworCisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9pbnQzMiIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQ2NF9pbnQ2NCIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF91aW50MzJfdWludDMyIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3VpbnQ2NF91aW50NjQiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ludDMyX3NpbnQzMiIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zaW50NjRfc2ludDY0IikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZmxvYXQiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZG91YmxlIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2Jvb2xfYm9vbCIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zdHJpbmdfc3RyaW5nIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2J5dGVzIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2VudW0iKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIikpKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3Rlcjo6TWFwUmVmbGVjdGlvblRlc3RlcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBiYXNlX2Rlc2NyaXB0b3IpCisgIDogYmFzZV9kZXNjcmlwdG9yXyhiYXNlX2Rlc2NyaXB0b3IpIHsKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wgPSBiYXNlX2Rlc2NyaXB0b3ItPmZpbGUoKS0+cG9vbCgpOworCisgIG1hcF9lbnVtX2Zvb18gPSBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5NQVBfRU5VTV9GT08iKTsKKyAgbWFwX2VudW1fYmFyXyA9IHBvb2wtPkZpbmRFbnVtVmFsdWVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0Lk1BUF9FTlVNX0JBUiIpOworICBtYXBfZW51bV9iYXpfID0gcG9vbC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuTUFQX0VOVU1fQkFaIik7CisKKyAgZm9yZWlnbl9jXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZS5jIik7CisgIG1hcF9pbnQzMl9pbnQzMl9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJJbnQzMkVudHJ5LmtleSIpOworICBtYXBfaW50MzJfaW50MzJfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMySW50MzJFbnRyeS52YWx1ZSIpOworICBtYXBfaW50NjRfaW50NjRfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDY0SW50NjRFbnRyeS5rZXkiKTsKKyAgbWFwX2ludDY0X2ludDY0X3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQ2NEludDY0RW50cnkudmFsdWUiKTsKKyAgbWFwX3VpbnQzMl91aW50MzJfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFVpbnQzMlVpbnQzMkVudHJ5LmtleSIpOworICBtYXBfdWludDMyX3VpbnQzMl92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwVWludDMyVWludDMyRW50cnkudmFsdWUiKTsKKyAgbWFwX3VpbnQ2NF91aW50NjRfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFVpbnQ2NFVpbnQ2NEVudHJ5LmtleSIpOworICBtYXBfdWludDY0X3VpbnQ2NF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwVWludDY0VWludDY0RW50cnkudmFsdWUiKTsKKyAgbWFwX3NpbnQzMl9zaW50MzJfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNpbnQzMlNpbnQzMkVudHJ5LmtleSIpOworICBtYXBfc2ludDMyX3NpbnQzMl92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU2ludDMyU2ludDMyRW50cnkudmFsdWUiKTsKKyAgbWFwX3NpbnQ2NF9zaW50NjRfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNpbnQ2NFNpbnQ2NEVudHJ5LmtleSIpOworICBtYXBfc2ludDY0X3NpbnQ2NF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU2ludDY0U2ludDY0RW50cnkudmFsdWUiKTsKKyAgbWFwX2ZpeGVkMzJfZml4ZWQzMl9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwRml4ZWQzMkZpeGVkMzJFbnRyeS5rZXkiKTsKKyAgbWFwX2ZpeGVkMzJfZml4ZWQzMl92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwRml4ZWQzMkZpeGVkMzJFbnRyeS52YWx1ZSIpOworICBtYXBfZml4ZWQ2NF9maXhlZDY0X2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBGaXhlZDY0Rml4ZWQ2NEVudHJ5LmtleSIpOworICBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBGaXhlZDY0Rml4ZWQ2NEVudHJ5LnZhbHVlIik7CisgIG1hcF9zZml4ZWQzMl9zZml4ZWQzMl9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5LmtleSIpOworICBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeS52YWx1ZSIpOworICBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeS5rZXkiKTsKKyAgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkudmFsdWUiKTsKKyAgbWFwX2ludDMyX2Zsb2F0X2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkZsb2F0RW50cnkua2V5Iik7CisgIG1hcF9pbnQzMl9mbG9hdF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJGbG9hdEVudHJ5LnZhbHVlIik7CisgIG1hcF9pbnQzMl9kb3VibGVfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyRG91YmxlRW50cnkua2V5Iik7CisgIG1hcF9pbnQzMl9kb3VibGVfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyRG91YmxlRW50cnkudmFsdWUiKTsKKyAgbWFwX2Jvb2xfYm9vbF9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwQm9vbEJvb2xFbnRyeS5rZXkiKTsKKyAgbWFwX2Jvb2xfYm9vbF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwQm9vbEJvb2xFbnRyeS52YWx1ZSIpOworICBtYXBfc3RyaW5nX3N0cmluZ19rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU3RyaW5nU3RyaW5nRW50cnkua2V5Iik7CisgIG1hcF9zdHJpbmdfc3RyaW5nX3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTdHJpbmdTdHJpbmdFbnRyeS52YWx1ZSIpOworICBtYXBfaW50MzJfYnl0ZXNfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyQnl0ZXNFbnRyeS5rZXkiKTsKKyAgbWFwX2ludDMyX2J5dGVzX3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkJ5dGVzRW50cnkudmFsdWUiKTsKKyAgbWFwX2ludDMyX2VudW1fa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyRW51bUVudHJ5LmtleSIpOworICBtYXBfaW50MzJfZW51bV92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJFbnVtRW50cnkudmFsdWUiKTsKKyAgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5LmtleSIpOworICBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50cnkudmFsdWUiKTsKKworICBFWFBFQ1RfRkFMU0UobWFwX2VudW1fZm9vXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9lbnVtX2Jhcl8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfZW51bV9iYXpfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2ludDMyX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfaW50MzJfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQ2NF9pbnQ2NF9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDY0X2ludDY0X3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfdWludDMyX3VpbnQzMl9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3VpbnQzMl91aW50MzJfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF91aW50NjRfdWludDY0X2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfdWludDY0X3VpbnQ2NF92YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3NpbnQzMl9zaW50MzJfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zaW50MzJfc2ludDMyX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc2ludDY0X3NpbnQ2NF9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3NpbnQ2NF9zaW50NjRfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9maXhlZDMyX2ZpeGVkMzJfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9maXhlZDMyX2ZpeGVkMzJfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9maXhlZDY0X2ZpeGVkNjRfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9maXhlZDY0X2ZpeGVkNjRfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zZml4ZWQzMl9zZml4ZWQzMl9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3NmaXhlZDMyX3NmaXhlZDMyX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NF92YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2Zsb2F0X2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfZmxvYXRfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9kb3VibGVfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9kb3VibGVfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9ib29sX2Jvb2xfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9ib29sX2Jvb2xfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zdHJpbmdfc3RyaW5nX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc3RyaW5nX3N0cmluZ192YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2J5dGVzX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfYnl0ZXNfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9lbnVtX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfZW51bV92YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWxfID09IE5VTEwpOworfQorCisvLyBTaG9ydGhhbmQgdG8gZ2V0IGEgRmllbGREZXNjcmlwdG9yIGZvciBhIGZpZWxkIG9mIHVuaXR0ZXN0OjpUZXN0TWFwLgorY29uc3QgRmllbGREZXNjcmlwdG9yKiBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3Rlcjo6Rihjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPSBOVUxMOworICByZXN1bHQgPSBiYXNlX2Rlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUobmFtZSk7CisgIEdPT0dMRV9DSEVDSyhyZXN1bHQgIT0gTlVMTCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXI6OlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9IE5VTEw7CisgIE1lc3NhZ2UqIHN1Yl9mb3JlaWduX21lc3NhZ2UgPSBOVUxMOworCisgIC8vIEFkZCBmaXJzdCBlbGVtZW50LgorICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfaW50MzJfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl92YWxfLCAwKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfaW50NjRfaW50NjRfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9pbnQ2NF9pbnQ2NF92YWxfLCAwKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfdWludDMyX3VpbnQzMl9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDY0X3VpbnQ2NCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3VpbnQ2NF91aW50NjRfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ludDMyX3NpbnQzMl9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3NpbnQzMl9zaW50MzJfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50NjRfc2ludDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ludDY0X3NpbnQ2NF9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NpbnQ2NF9zaW50NjRfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQzMl9maXhlZDMyX2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkMzJfZml4ZWQzMl92YWxfLCAwKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDY0X2ZpeGVkNjRfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDY0KHN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQzMl9zZml4ZWQzMl9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDMyX3NmaXhlZDMyX3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NF9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mbG9hdF9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRGbG9hdChzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2Zsb2F0X3ZhbF8sIDAuMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9kb3VibGVfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0RG91YmxlKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZG91YmxlX3ZhbF8sIDAuMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0Qm9vbChzdWJfbWVzc2FnZSwgbWFwX2Jvb2xfYm9vbF9rZXlfLCBmYWxzZSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0Qm9vbChzdWJfbWVzc2FnZSwgbWFwX2Jvb2xfYm9vbF92YWxfLCBmYWxzZSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFN0cmluZyhzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfa2V5XywgIjAiKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRTdHJpbmcoc3ViX21lc3NhZ2UsIG1hcF9zdHJpbmdfc3RyaW5nX3ZhbF8sICIwIik7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2J5dGVzX2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFN0cmluZyhzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2J5dGVzX3ZhbF8sICIwIik7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZW51bV9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRFbnVtKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZW51bV92YWxfLCBtYXBfZW51bV9iYXJfKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleV8sIDApOworICBzdWJfZm9yZWlnbl9tZXNzYWdlID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+CisgICAgICBNdXRhYmxlTWVzc2FnZShzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWxfLCBOVUxMKTsKKyAgc3ViX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT4KKyAgICAgIFNldEludDMyKHN1Yl9mb3JlaWduX21lc3NhZ2UsIGZvcmVpZ25fY18sIDApOworCisgIC8vIEFkZCBzZWNvbmQgZWxlbWVudAorICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfaW50MzJfa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl92YWxfLCAxKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfaW50NjRfaW50NjRfa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9pbnQ2NF9pbnQ2NF92YWxfLCAxKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfdWludDMyX3VpbnQzMl9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDY0X3VpbnQ2NCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3VpbnQ2NF91aW50NjRfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ludDMyX3NpbnQzMl9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3NpbnQzMl9zaW50MzJfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50NjRfc2ludDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ludDY0X3NpbnQ2NF9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NpbnQ2NF9zaW50NjRfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQzMl9maXhlZDMyX2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkMzJfZml4ZWQzMl92YWxfLCAxKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDY0X2ZpeGVkNjRfa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDY0KHN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQzMl9zZml4ZWQzMl9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDMyX3NmaXhlZDMyX3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NF9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mbG9hdF9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRGbG9hdChzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2Zsb2F0X3ZhbF8sIDEuMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9kb3VibGVfa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0RG91YmxlKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZG91YmxlX3ZhbF8sIDEuMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0Qm9vbChzdWJfbWVzc2FnZSwgbWFwX2Jvb2xfYm9vbF9rZXlfLCB0cnVlKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRCb29sKHN1Yl9tZXNzYWdlLCBtYXBfYm9vbF9ib29sX3ZhbF8sIHRydWUpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRTdHJpbmcoc3ViX21lc3NhZ2UsIG1hcF9zdHJpbmdfc3RyaW5nX2tleV8sICIxIik7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0U3RyaW5nKHN1Yl9tZXNzYWdlLCBtYXBfc3RyaW5nX3N0cmluZ192YWxfLCAiMSIpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9ieXRlc19rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRTdHJpbmcoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9ieXRlc192YWxfLCAiMSIpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZW51bSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2VudW1fa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0RW51bShzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2VudW1fdmFsXywgbWFwX2VudW1fYmF6Xyk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uCisgICAgICAtPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXlfLCAxKTsKKyAgc3ViX2ZvcmVpZ25fbWVzc2FnZSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgTXV0YWJsZU1lc3NhZ2Uoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsXywgTlVMTCk7CisgIHN1Yl9mb3JlaWduX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+CisgICAgICBTZXRJbnQzMihzdWJfZm9yZWlnbl9tZXNzYWdlLCBmb3JlaWduX2NfLCAxKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3Rlcjo6Q2xlYXJNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICByZWZsZWN0aW9uLT5DbGVhckZpZWxkKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IikpOworICByZWZsZWN0aW9uLT5DbGVhckZpZWxkKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IikpOworICByZWZsZWN0aW9uLT5DbGVhckZpZWxkKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3Rlcjo6TW9kaWZ5TWFwRmllbGRzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworICBNZXNzYWdlKiBzdWJfZm9yZWlnbl9tZXNzYWdlOworCisgIC8vIEZpbmQgb3V0IHdoaWNoIG9uZSdzIGtleSBpcyAwLgorICBpbnQgc2l6ZSA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIikpOworICBpbnQgdGFyZ2V0ID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICBjb25zdCBNZXNzYWdlJiB0ZW1wX21lc3NhZ2UgPSByZWZsZWN0aW9uCisgICAgICAtPkdldFJlcGVhdGVkTWVzc2FnZSgqbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIiksIGkpOworICAgIGlmICh0ZW1wX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgLT5HZXRJbnQzMih0ZW1wX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl9rZXlfKSA9PSAxKSB7CisgICAgICB0YXJnZXQgPSBpOworICAgIH0KKyAgfQorCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfaW50MzJfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQ2NF9pbnQ2NCIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfaW50NjRfaW50NjRfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50MzJfdWludDMyIiksIHRhcmdldCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfdWludDMyX3VpbnQzMl92YWxfLCAyKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uCisgICAgICAtPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSwgdGFyZ2V0KTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X3ZhbF8sIDIpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ludDMyX3NpbnQzMl92YWxfLCAyKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uCisgICAgICAtPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSwgdGFyZ2V0KTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NpbnQ2NF9zaW50NjRfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSwgdGFyZ2V0KTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDMyX2ZpeGVkMzJfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSwgdGFyZ2V0KTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDY0X2ZpeGVkNjRfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfdmFsXywgMik7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEZsb2F0KHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZmxvYXRfdmFsXywgMi4wKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uCisgICAgICAtPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldERvdWJsZShzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2RvdWJsZV92YWxfLCAyLjApOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfYm9vbF9ib29sIiksIHRhcmdldCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0Qm9vbChzdWJfbWVzc2FnZSwgbWFwX2Jvb2xfYm9vbF92YWxfLCBmYWxzZSk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIiksIHRhcmdldCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0U3RyaW5nKHN1Yl9tZXNzYWdlLCBtYXBfc3RyaW5nX3N0cmluZ192YWxfLCAiMiIpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSwgdGFyZ2V0KTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRTdHJpbmcoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9ieXRlc192YWxfLCAiMiIpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZW51bSIpLCB0YXJnZXQpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEVudW0oc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9lbnVtX3ZhbF8sIG1hcF9lbnVtX2Zvb18pOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIiksIHRhcmdldCk7CisgIHN1Yl9mb3JlaWduX21lc3NhZ2UgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT4KKyAgICAgIE11dGFibGVNZXNzYWdlKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbF8sIE5VTEwpOworICBzdWJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgU2V0SW50MzIoc3ViX2ZvcmVpZ25fbWVzc2FnZSwgZm9yZWlnbl9jXywgMik7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6Ok1hcFJlZmxlY3Rpb25UZXN0ZXI6OlJlbW92ZUxhc3RNYXBzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3V0cHV0LnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG91dHB1dFtpXTsKKyAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpKSBjb250aW51ZTsKKyAgICByZWZsZWN0aW9uLT5SZW1vdmVMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgfQorfQorCit2b2lkIE1hcFRlc3RVdGlsOjpNYXBSZWZsZWN0aW9uVGVzdGVyOjpSZWxlYXNlTGFzdE1hcHNWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gb3V0cHV0OworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKCptZXNzYWdlLCAmb3V0cHV0KTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdXRwdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3V0cHV0W2ldOworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgY29udGludWU7CisKKyAgICBNZXNzYWdlKiByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBBU1NFUlRfVFJVRShyZWxlYXNlZCAhPSBOVUxMKSA8PCAiUmVsZWFzZUxhc3QgcmV0dXJuZWQgTlVMTCBmb3I6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBmaWVsZC0+bmFtZSgpOworICAgIGRlbGV0ZSByZWxlYXNlZDsKKyAgfQorfQorCit2b2lkIE1hcFRlc3RVdGlsOjpNYXBSZWZsZWN0aW9uVGVzdGVyOjpTd2FwTWFwc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gb3V0cHV0OworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKCptZXNzYWdlLCAmb3V0cHV0KTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdXRwdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3V0cHV0W2ldOworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworICAgIHJlZmxlY3Rpb24tPlN3YXBFbGVtZW50cyhtZXNzYWdlLCBmaWVsZCwgMCwgMSk7CisgIH0KK30KKwordm9pZCBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3Rlcjo6CisgICAgTXV0YWJsZVVua25vd25GaWVsZHNPZk1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9IE5VTEw7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhzdWJfbWVzc2FnZSkgIT0KKyAgICAgICAgICAgICAgTlVMTCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhzdWJfbWVzc2FnZSkgIT0KKyAgICAgICAgICAgICAgTlVMTCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhzdWJfbWVzc2FnZSkgIT0KKyAgICAgICAgICAgICAgTlVMTCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6TWFwUmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0TWFwRmllbGRzU2V0VmlhUmVmbGVjdGlvbigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIHN0cmluZyBzY3JhdGNoOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQ2NF9pbnQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3NmaXhlZDY0X3NmaXhlZDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIikpKTsKKworICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSwgaSk7CisgICAgICBpbnQzMiBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl9rZXlfKTsKKyAgICAgIGludDMyIHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ludDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50NjQsIGludDY0PiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSwgaSk7CisgICAgICBpbnQ2NCBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQ2NF9pbnQ2NF9rZXlfKTsKKyAgICAgIGludDY0IHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDY0X2ludDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDMyLCB1aW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50MzJfdWludDMyIiksIGkpOworICAgICAgdWludDMyIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX2tleV8pOworICAgICAgdWludDMyIHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDY0LCB1aW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IiksIGkpOworICAgICAgdWludDY0IGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X2tleV8pOworICAgICAgdWludDY0IHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpLCBpKTsKKyAgICAgIGludDMyIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3NpbnQzMl9zaW50MzJfa2V5Xyk7CisgICAgICBpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zaW50MzJfc2ludDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50NjQsIGludDY0PiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpLCBpKTsKKyAgICAgIGludDY0IGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3NpbnQ2NF9zaW50NjRfa2V5Xyk7CisgICAgICBpbnQ2NCB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zaW50NjRfc2ludDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDMyLCB1aW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSwgaSk7CisgICAgICB1aW50MzIga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkMzJfZml4ZWQzMl9rZXlfKTsKKyAgICAgIHVpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQzMl9maXhlZDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDY0LCB1aW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSwgaSk7CisgICAgICB1aW50NjQga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkNjRfZml4ZWQ2NF9rZXlfKTsKKyAgICAgIHVpbnQ2NCB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50NjQoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIiksIGkpOworICAgICAgaW50MzIga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfa2V5Xyk7CisgICAgICBpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQzMl9zZml4ZWQzMl92YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDY0LCBpbnQ2ND4gbWFwOworICAgIG1hcFswXSA9IDA7CisgICAgbWFwWzFdID0gMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpLCBpKTsKKyAgICAgIGludDY0IGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV8pOworICAgICAgaW50NjQgdmFsID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50NjQoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfdmFsXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgZmxvYXQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwLjA7CisgICAgbWFwWzFdID0gMS4wOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSwgaSk7CisgICAgICBpbnQzMiAga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZmxvYXRfa2V5Xyk7CisgICAgICBmbG9hdCB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRGbG9hdCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mbG9hdF92YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDMyLCBkb3VibGU+IG1hcDsKKyAgICBtYXBbMF0gPSAwLjA7CisgICAgbWFwWzFdID0gMS4wOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZG91YmxlIiksIGkpOworICAgICAgaW50MzIgIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2RvdWJsZV9rZXlfKTsKKyAgICAgIGRvdWJsZSB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZG91YmxlX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8Ym9vbCwgYm9vbD4gbWFwOworICAgIG1hcFtmYWxzZV0gPSBmYWxzZTsKKyAgICBtYXBbdHJ1ZV0gPSB0cnVlOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfYm9vbF9ib29sIiksIGkpOworICAgICAgYm9vbCBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRCb29sKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2Jvb2xfYm9vbF9rZXlfKTsKKyAgICAgIGJvb2wgdmFsID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0Qm9vbCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9ib29sX2Jvb2xfdmFsXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxzdHJpbmcsIHN0cmluZz4gbWFwOworICAgIG1hcFsiMCJdID0gIjAiOworICAgIG1hcFsiMSJdID0gIjEiOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpLCBpKTsKKyAgICAgIHN0cmluZyAga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfa2V5Xyk7CisgICAgICBzdHJpbmcgdmFsID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfdmFsXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgc3RyaW5nPiBtYXA7CisgICAgbWFwWzBdID0gIjAiOworICAgIG1hcFsxXSA9ICIxIjsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgc3ViX21lc3NhZ2UgPQorICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2J5dGVzIiksIGkpOworICAgICAgaW50MzIgIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2J5dGVzX2tleV8pOworICAgICAgc3RyaW5nIHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9ieXRlc192YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDMyLCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKj4gbWFwOworICAgIG1hcFswXSA9IG1hcF9lbnVtX2Jhcl87CisgICAgbWFwWzFdID0gbWFwX2VudW1fYmF6XzsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIiksIGkpOworICAgICAgaW50MzIga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZW51bV9rZXlfKTsKKyAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEVudW0oCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZW51bV92YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDMyLCBpbnQzMj4gbWFwOworICAgIG1hcFswXSA9IDA7CisgICAgbWFwWzFdID0gMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSwgaSk7CisgICAgICBpbnQzMiAga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleV8pOworICAgICAgY29uc3QgTWVzc2FnZSYgZm9yZWlnbl9tZXNzYWdlID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0TWVzc2FnZSgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsXyk7CisgICAgICBpbnQzMiB2YWwgPSBmb3JlaWduX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBmb3JlaWduX21lc3NhZ2UsIGZvcmVpZ25fY18pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgIH0KKyAgfQorfQorCit2b2lkIE1hcFRlc3RVdGlsOjpNYXBSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RDbGVhclZpYVJlZmxlY3Rpb24oCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIC8vIE1hcCBmaWVsZHMgYXJlIGVtcHR5LgorICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpNYXBSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RNYXBFbnRyeUNsZWFyVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworCisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfaW50MzJfaW50MzIiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfaW50NjRfaW50NjQiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfdWludDMyX3VpbnQzMiIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF91aW50NjRfdWludDY0Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50NjQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IpKTsKKyAgfQorICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gRigibWFwX3NpbnQzMl9zaW50MzIiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9zaW50NjRfc2ludDY0Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50NjRfc2ludDY0IikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfZml4ZWQzMl9maXhlZDMyIik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZGVzY3JpcHRvcikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZGVzY3JpcHRvcikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50NjQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NmaXhlZDY0X3NmaXhlZDY0IikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfaW50MzJfZmxvYXQiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEZsb2F0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfaW50MzJfZG91YmxlIik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IpKTsKKyAgfQorICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gRigibWFwX2Jvb2xfYm9vbCIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfYm9vbF9ib29sIikpOworICAgIEVYUEVDVF9FUShmYWxzZSwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0Qm9vbCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKGZhbHNlLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRCb29sKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfc3RyaW5nX3N0cmluZyIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpKTsKKyAgICBFWFBFQ1RfRVEoIiIsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoIiIsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfaW50MzJfYnl0ZXMiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2J5dGVzIikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKCIiLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9pbnQzMl9lbnVtIik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgICAgICAgICAgIC0+R2V0RW51bSgqc3ViX21lc3NhZ2UsIHZhbHVlX2Rlc2NyaXB0b3IpCisgICAgICAgICAgICAgICAgICAgICAtPm51bWJlcigpKTsKKyAgfQorICAvLyBNYXAgdXNpbmcgbWVzc2FnZSBhcyB2YWx1ZSBoYXMgYmVlbiB0ZXN0ZWQgaW4gb3RoZXIgcGxhY2UuIFRodXMsIHdlIGRvbid0CisgIC8vIHRlc3QgaXQgaGVyZS4KK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0MzdlMzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0X3V0aWwuaApAQCAtMCwwICsxLDE1NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01BUF9URVNUX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF91bml0dGVzdC5wYi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSB1bml0dGVzdCA9IDo6cHJvdG9idWZfdW5pdHRlc3Q7CisKK2NsYXNzIE1hcFRlc3RVdGlsIHsKKyBwdWJsaWM6CisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgVGVzdE1hcCBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICBzdGF0aWMgdm9pZCBTZXRNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RNYXAqIG1lc3NhZ2UpOworCisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgVGVzdEFyZW5hTWFwIG1lc3NhZ2UgdG8gYSB1bmlxdWUgdmFsdWUuCisgIHN0YXRpYyB2b2lkIFNldEFyZW5hTWFwRmllbGRzKHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXAqIG1lc3NhZ2UpOworCisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgbWVzc2FnZSB0byBhIGRlZmF1bHQgdmFsdWUuCisgIHN0YXRpYyB2b2lkIFNldE1hcEZpZWxkc0luaXRpYWxpemVkKHVuaXR0ZXN0OjpUZXN0TWFwKiBtZXNzYWdlKTsKKworICAvLyBNb2RpZnkgYWxsIHRoZSBtYXAgZmllbGRzIG9mIHRoZSBtZXNzc2FnZSAod2hpY2ggc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuCisgIC8vIGluaXRpYWxpemVkIHdpdGggU2V0TWFwRmllbGRzKCkpLgorICBzdGF0aWMgdm9pZCBNb2RpZnlNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RNYXAqIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIHRoZSB2YWx1ZXMgdGhhdCB0aGV5IHNob3VsZCBoYXZlIGFmdGVyCisgIC8vIFNldE1hcEZpZWxkcygpIGlzIGNhbGxlZC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0TWFwRmllbGRzU2V0KGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXRNYXBGaWVsZHMoKSBpcyBjYWxsZWQgZm9yIFRlc3RBcmVuYU1hcC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQoKSBpcyBjYWxsZWQuCisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UpOworCisgIC8vIEV4cGVjdCB0aGF0IHRoZSBtZXNzYWdlIGlzIG1vZGlmaWVkIGFzIHdvdWxkIGJlIGV4cGVjdGVkIGZyb20KKyAgLy8gTW9kaWZ5TWFwRmllbGRzKCkuCisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc01vZGlmaWVkKGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgYXJlIGVtcHR5LgorICBzdGF0aWMgdm9pZCBFeHBlY3RDbGVhcihjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgbWFwIGZpZWxkcyBoYXZlIHRoZSBnaXZlbiBzaXplLgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBzU2l6ZShjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSwgaW50IHNpemUpOworCisgIC8vIEdldCBwb2ludGVycyBvZiBtYXAgZW50cmllcyBhdCBnaXZlbiBpbmRleC4KKyAgc3RhdGljIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBHZXRNYXBFbnRyaWVzKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UsIGludCBpbmRleCk7CisKKyAgLy8gR2V0IHBvaW50ZXJzIG9mIG1hcCBlbnRyaWVzIGZyb20gcmVsZWFzZS4KKyAgc3RhdGljIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBHZXRNYXBFbnRyaWVzRnJvbVJlbGVhc2UoCisgICAgICB1bml0dGVzdDo6VGVzdE1hcCogbWVzc2FnZSk7CisKKyAgLy8gTGlrZSBhYm92ZSwgYnV0IHVzZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UuCisgIGNsYXNzIE1hcFJlZmxlY3Rpb25UZXN0ZXIgeworICAgcHVibGljOgorICAgIC8vIGJhc2VfZGVzY3JpcHRvciBtdXN0IGJlIGEgZGVzY3JpcHRvciBmb3IgVGVzdE1hcCwgd2hpY2ggaXMgdXNlZCBmb3IKKyAgICAvLyBNYXBSZWZsZWN0aW9uVGVzdGVyIHRvIGZldGNoIHRoZSBGaWVsZERlc2NyaXB0b3JzIG5lZWRlZCB0byB1c2UgdGhlCisgICAgLy8gcmVmbGVjdGlvbiBpbnRlcmZhY2UuCisgICAgZXhwbGljaXQgTWFwUmVmbGVjdGlvblRlc3Rlcihjb25zdCBEZXNjcmlwdG9yKiBiYXNlX2Rlc2NyaXB0b3IpOworCisgICAgdm9pZCBTZXRNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHZvaWQgQ2xlYXJNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHZvaWQgTW9kaWZ5TWFwRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIFJlbW92ZUxhc3RNYXBzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIFJlbGVhc2VMYXN0TWFwc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBTd2FwTWFwc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBNdXRhYmxlVW5rbm93bkZpZWxkc09mTWFwRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgICAgdm9pZCBFeHBlY3RDbGVhclZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgICAgdm9pZCBFeHBlY3RNYXBFbnRyeUNsZWFyVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKworICAgcHJpdmF0ZToKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEYoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICAgIGNvbnN0IERlc2NyaXB0b3IqIGJhc2VfZGVzY3JpcHRvcl87CisKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBtYXBfZW51bV9iYXJfOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIG1hcF9lbnVtX2Jhel87CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogbWFwX2VudW1fZm9vXzsKKworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZm9yZWlnbl9jXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9pbnQzMl9rZXlfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2ludDMyX3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50NjRfaW50NjRfa2V5XzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQ2NF9pbnQ2NF92YWxfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3VpbnQzMl91aW50MzJfa2V5XzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF91aW50MzJfdWludDMyX3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfdWludDY0X3VpbnQ2NF9rZXlfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3VpbnQ2NF91aW50NjRfdmFsXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9zaW50MzJfc2ludDMyX2tleV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfc2ludDMyX3NpbnQzMl92YWxfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NpbnQ2NF9zaW50NjRfa2V5XzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9zaW50NjRfc2ludDY0X3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZml4ZWQzMl9maXhlZDMyX2tleV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZml4ZWQzMl9maXhlZDMyX3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZml4ZWQ2NF9maXhlZDY0X2tleV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfa2V5XzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9zZml4ZWQzMl9zZml4ZWQzMl92YWxfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfdmFsXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9mbG9hdF9rZXlfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2Zsb2F0X3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50MzJfZG91YmxlX2tleV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50MzJfZG91YmxlX3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfYm9vbF9ib29sX2tleV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfYm9vbF9ib29sX3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfc3RyaW5nX3N0cmluZ19rZXlfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3N0cmluZ19zdHJpbmdfdmFsXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9ieXRlc19rZXlfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2J5dGVzX3ZhbF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50MzJfZW51bV9rZXlfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2VudW1fdmFsXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5XzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsXzsKKyAgfTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsX2ltcGwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbF9pbXBsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWU3ODgyYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbF9pbXBsLmgKQEAgLTAsMCArMSw0NzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0lNUExfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0lNUExfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKworI2RlZmluZSBFWFBFQ1RfVFJVRSBHT09HTEVfQ0hFQ0sKKyNkZWZpbmUgQVNTRVJUX1RSVUUgR09PR0xFX0NIRUNLCisjZGVmaW5lIEVYUEVDVF9GQUxTRShDT05EKSBHT09HTEVfQ0hFQ0soIShDT05EKSkKKyNkZWZpbmUgRVhQRUNUX0VRIEdPT0dMRV9DSEVDS19FUQorI2RlZmluZSBBU1NFUlRfRVEgR09PR0xFX0NIRUNLX0VRCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmX3VuaXR0ZXN0IHt9ICAvLyBmb3J3YXJkIGRlY2xhcmF0aW9uCisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSB1bml0dGVzdCA9IDo6cHJvdG9idWZfdW5pdHRlc3Q7CisKK2NsYXNzIE1hcFRlc3RVdGlsSW1wbCB7CisgcHVibGljOgorICAvLyBTZXQgZXZlcnkgZmllbGQgaW4gdGhlIFRlc3RNYXAgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBTZXRNYXBGaWVsZHMoTWFwTWVzc2FnZSogbWVzc2FnZSk7CisKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBUZXN0QXJlbmFNYXAgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBTZXRBcmVuYU1hcEZpZWxkcyhNYXBNZXNzYWdlKiBtZXNzYWdlKTsKKworICAvLyBTZXQgZXZlcnkgZmllbGQgaW4gdGhlIG1lc3NhZ2UgdG8gYSBkZWZhdWx0IHZhbHVlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgTWFwTWVzc2FnZT4KKyAgc3RhdGljIHZvaWQgU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQoTWFwTWVzc2FnZSogbWVzc2FnZSk7CisKKyAgLy8gTW9kaWZ5IGFsbCB0aGUgbWFwIGZpZWxkcyBvZiB0aGUgbWVzc3NhZ2UgKHdoaWNoIHNob3VsZCBhbHJlYWR5IGhhdmUgYmVlbgorICAvLyBpbml0aWFsaXplZCB3aXRoIFNldE1hcEZpZWxkcygpKS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBNb2RpZnlNYXBGaWVsZHMoTWFwTWVzc2FnZSogbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzKCkgaXMgY2FsbGVkLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+CisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldChjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXRNYXBGaWVsZHMoKSBpcyBjYWxsZWQgZm9yIFRlc3RBcmVuYU1hcC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBFeHBlY3RBcmVuYU1hcEZpZWxkc1NldChjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXRNYXBGaWVsZHNJbml0aWFsaXplZCgpIGlzIGNhbGxlZC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBGaWVsZHNTZXRJbml0aWFsaXplZChjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAvLyBFeHBlY3QgdGhhdCB0aGUgbWVzc2FnZSBpcyBtb2RpZmllZCBhcyB3b3VsZCBiZSBleHBlY3RlZCBmcm9tCisgIC8vIE1vZGlmeU1hcEZpZWxkcygpLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+CisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc01vZGlmaWVkKGNvbnN0IE1hcE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBhcmUgZW1wdHkuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBFeHBlY3RDbGVhcihjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAvLyAvLyBDaGVjayB0aGF0IGFsbCBtYXAgZmllbGRzIGhhdmUgdGhlIGdpdmVuIHNpemUuCisgIC8vIHRlbXBsYXRlIDx0eXBlbmFtZSBNYXBNZXNzYWdlPgorICAvLyBzdGF0aWMgdm9pZCBFeHBlY3RNYXBzU2l6ZShjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlLCBpbnQgc2l6ZSk7CisKKyAgLy8gLy8gR2V0IHBvaW50ZXJzIG9mIG1hcCBlbnRyaWVzIGF0IGdpdmVuIGluZGV4LgorICAvLyBzdGF0aWMgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IEdldE1hcEVudHJpZXMoCisgIC8vICAgICBjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlLCBpbnQgaW5kZXgpOworCisgIC8vIC8vIEdldCBwb2ludGVycyBvZiBtYXAgZW50cmllcyBmcm9tIHJlbGVhc2UuCisgIC8vIHN0YXRpYyBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gR2V0TWFwRW50cmllc0Zyb21SZWxlYXNlKAorICAvLyAgICAgTWFwTWVzc2FnZSogbWVzc2FnZSk7Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgordm9pZCBNYXBUZXN0VXRpbEltcGw6OlNldE1hcEZpZWxkcyhNYXBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIC8vIEFkZCBmaXJzdCBlbGVtZW50LgorICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQ2NF9pbnQ2NCgpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDMyX3VpbnQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDY0X3VpbnQ2NCgpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDMyX3NpbnQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDY0X3NpbnQ2NCgpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQzMl9maXhlZDMyKCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDY0X2ZpeGVkNjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZmxvYXQoKSlbMF0gPSAwLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzBdID0gMC4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2Jvb2xfYm9vbCgpKVswXSA9IGZhbHNlOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbIjAiXSA9ICIwIjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9ieXRlcygpKVswXSA9ICIwIjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9lbnVtKCkpWzBdID0gZW51bV92YWx1ZTA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpWzBdLnNldF9jKDApOworCisgIC8vIEFkZCBzZWNvbmQgZWxlbWVudAorICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQ2NF9pbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDMyX3VpbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDY0X3VpbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDMyX3NpbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDY0X3NpbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQzMl9maXhlZDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDY0X2ZpeGVkNjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZmxvYXQoKSlbMV0gPSAxLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzFdID0gMS4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2Jvb2xfYm9vbCgpKVsxXSA9IHRydWU7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc3RyaW5nX3N0cmluZygpKVsiMSJdID0gIjEiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2J5dGVzKCkpWzFdID0gIjEiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2VudW0oKSlbMV0gPSBlbnVtX3ZhbHVlMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKSlbMV0uc2V0X2MoMSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZTAsCisgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+Cit2b2lkIE1hcFRlc3RVdGlsSW1wbDo6U2V0QXJlbmFNYXBGaWVsZHMoTWFwTWVzc2FnZSogbWVzc2FnZSkgeworICAvLyBBZGQgZmlyc3QgZWxlbWVudC4KKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50NjRfaW50NjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQzMl91aW50MzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQ2NF91aW50NjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQzMl9zaW50MzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQ2NF9zaW50NjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkMzJfZml4ZWQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQ2NF9maXhlZDY0KCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQzMl9zZml4ZWQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2Zsb2F0KCkpWzBdID0gMC4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2RvdWJsZSgpKVswXSA9IDAuMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9ib29sX2Jvb2woKSlbMF0gPSBmYWxzZTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9lbnVtKCkpWzBdID0gZW51bV92YWx1ZTA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpWzBdLnNldF9jKDApOworCisgIC8vIEFkZCBzZWNvbmQgZWxlbWVudAorICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQ2NF9pbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDMyX3VpbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDY0X3VpbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDMyX3NpbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDY0X3NpbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQzMl9maXhlZDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDY0X2ZpeGVkNjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZmxvYXQoKSlbMV0gPSAxLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzFdID0gMS4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2Jvb2xfYm9vbCgpKVsxXSA9IHRydWU7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZW51bSgpKVsxXSA9IGVudW1fdmFsdWUxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpKVsxXS5zZXRfYygxKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIE1hcE1lc3NhZ2U+Cit2b2lkIE1hcFRlc3RVdGlsSW1wbDo6U2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQoTWFwTWVzc2FnZSogbWVzc2FnZSkgeworICAvLyBBZGQgZmlyc3QgZWxlbWVudCB1c2luZyBicmFja2V0IG9wZXJhdG9yLCB3aGljaCBzaG91bGQgYXNzaWduIGRlZmF1bHQKKyAgLy8gdmFsdWUgYXV0b21hdGljYWxseS4KKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQ2NF9pbnQ2NCgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF91aW50MzJfdWludDMyKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQ2NF91aW50NjQoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDMyX3NpbnQzMigpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zaW50NjRfc2ludDY0KCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkMzJfZml4ZWQzMigpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDY0X2ZpeGVkNjQoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZmxvYXQoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2Jvb2xfYm9vbCgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zdHJpbmdfc3RyaW5nKCkpWyIwIl07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfYnl0ZXMoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZW51bSgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKSlbMF07Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KK3ZvaWQgTWFwVGVzdFV0aWxJbXBsOjpNb2RpZnlNYXBGaWVsZHMoTWFwTWVzc2FnZSogbWVzc2FnZSkgeworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQ2NF9pbnQ2NCgpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDMyX3VpbnQzMigpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDY0X3VpbnQ2NCgpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDMyX3NpbnQzMigpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDY0X3NpbnQ2NCgpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQzMl9maXhlZDMyKCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDY0X2ZpeGVkNjQoKSlbMV0gPSAyOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZmxvYXQoKSlbMV0gPSAyLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzFdID0gMi4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2Jvb2xfYm9vbCgpKVsxXSA9IGZhbHNlOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbIjEiXSA9ICIyIjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9ieXRlcygpKVsxXSA9ICIyIjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9lbnVtKCkpWzFdID0gZW51bV92YWx1ZTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKSlbMV0uc2V0X2MoMik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBNYXBNZXNzYWdlPgordm9pZCBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdENsZWFyKGNvbnN0IE1hcE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3VpbnQzMl91aW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQ2NF9zaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQzMl9zZml4ZWQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfYm9vbF9ib29sKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5zaXplKCkpOworfQorCisKKwordGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICBFbnVtVHlwZSBlbnVtX3ZhbHVlMSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KK3ZvaWQgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RNYXBGaWVsZHNTZXQoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKCIwIiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCIwIikpOworICBFWFBFQ1RfRVEoIjAiLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLmF0KDApKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUwLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoMCkuYygpKTsKKworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQ2NF9pbnQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3VpbnQzMl91aW50MzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc2ludDMyX3NpbnQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NpbnQ2NF9zaW50NjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9maXhlZDY0X2ZpeGVkNjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zZml4ZWQzMl9zZml4ZWQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfZmxvYXQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgiMSIsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdCgiMSIpKTsKKyAgRVhQRUNUX0VRKCIxIiwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5hdCgxKSk7CisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlMSwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KDEpLmMoKSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZTAsCisgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+Cit2b2lkIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5zaXplKCkpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5hdCgwKSk7CisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlMCwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KDApLmMoKSk7CisKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMSkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5tYXBfYm9vbF9ib29sKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZTEsIG1lc3NhZ2UubWFwX2ludDMyX2VudW0oKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdCgxKS5jKCkpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+Cit2b2lkIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQoCisgICAgY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoIjAiKSk7CisgIEVYUEVDVF9FUSgiIiwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5hdCgwKSk7CisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoMCkuQnl0ZVNpemUoKSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZTAsCisgICAgICAgICAgICBFbnVtVHlwZSBlbnVtX3ZhbHVlMSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KK3ZvaWQgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RNYXBGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIC8vIE1vZGlmeU1hcEZpZWxkcyBvbmx5IHNldHMgdGhlIHNlY29uZCBlbGVtZW50IG9mIGVhY2ggZmllbGQuICBJbiBhZGRpdGlvbiB0bworICAvLyB2ZXJpZnlpbmcgdGhpcywgd2UgYWxzbyB2ZXJpZnkgdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBhbmQgc2l6ZSB3ZXJlICpub3QqCisgIC8vIG1vZGlmaWVkLgorICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKCIwIiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCIwIikpOworICBFWFBFQ1RfRVEoIjAiLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLmF0KDApKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUwLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoMCkuYygpKTsKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKCIyIiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCIxIikpOworICBFWFBFQ1RfRVEoIjIiLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUxLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoMSkuYygpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01BUF9URVNUX1VUSUxfSU1QTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdHlwZV9oYW5kbGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjc4Yjc4YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oCkBAIC0wLDAgKzEsNTE2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVFlQRV9IQU5ETEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVFlQRV9IQU5ETEVSX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVXNlZCBmb3IgY29tcGlsZSB0aW1lIHR5cGUgc2VsZWN0aW9uLiBNYXBJZjo6dHlwZSB3aWxsIGJlIFRydWVUeXBlIGlmIEZsYWcgaXMKKy8vIHRydWUgYW5kIEZhbHNlVHlwZSBvdGhlcndpc2UuCit0ZW1wbGF0ZTxib29sIEZsYWcsIHR5cGVuYW1lIFRydWVUeXBlLCB0eXBlbmFtZSBGYWxzZVR5cGU+CitzdHJ1Y3QgTWFwSWY7CisKK3RlbXBsYXRlPHR5cGVuYW1lIFRydWVUeXBlLCB0eXBlbmFtZSBGYWxzZVR5cGU+CitzdHJ1Y3QgTWFwSWY8dHJ1ZSwgVHJ1ZVR5cGUsIEZhbHNlVHlwZT4geworICB0eXBlZGVmIFRydWVUeXBlIHR5cGU7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUcnVlVHlwZSwgdHlwZW5hbWUgRmFsc2VUeXBlPgorc3RydWN0IE1hcElmPGZhbHNlLCBUcnVlVHlwZSwgRmFsc2VUeXBlPiB7CisgIHR5cGVkZWYgRmFsc2VUeXBlIHR5cGU7Cit9OworCisvLyBJbiBNYXBGaWVsZCwgc3RyaW5nIGFuZCBtZXNzYWdlIGFyZSBzdG9yZWQgYXMgcG9pbnRlciB3aGlsZSBvdGhlcnMgYXJlIHN0b3JlZAorLy8gYXMgb2JqZWN0LiBIb3dldmVyLCBnb29nbGU6OnByb3RvYnVmOjpNYXAgaGFzIHVuaWZpZWQgYXBpLiBGdW5jdGlvbnMgaW4gdGhpcyBjbGFzcworLy8gY29udmVydCBrZXkvdmFsdWUgdG8gdHlwZSB3YW50ZWQgaW4gYXBpIHJlZ2FyZGxlc3MgaG93IGl0J3Mgc3RvcmVkCisvLyBpbnRlcm5hbGx5LgordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBDb21tb25UeXBlSGFuZGxlciB7CisgcHVibGljOgorICBzdGF0aWMgaW5saW5lIFR5cGUmIFJlZmVyZW5jZShUeXBlKiB4KSB7IHJldHVybiAqeDsgfQorICBzdGF0aWMgaW5saW5lIFR5cGUmIFJlZmVyZW5jZShUeXBlJiB4KSB7IHJldHVybiB4OyB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgVHlwZSYgUmVmZXJlbmNlKGNvbnN0IFR5cGUmIHgpIHsgcmV0dXJuIHg7IH0KKyAgc3RhdGljIGlubGluZSBUeXBlKiBQb2ludGVyKFR5cGUqIHgpIHsgcmV0dXJuIHg7IH0KKyAgc3RhdGljIGlubGluZSBUeXBlKiBQb2ludGVyKFR5cGUmIHgpIHsgcmV0dXJuICZ4OyB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgVHlwZSogUG9pbnRlcihjb25zdCBUeXBlKiB4KSB7IHJldHVybiB4OyB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgVHlwZSogUG9pbnRlcihjb25zdCBUeXBlJiB4KSB7IHJldHVybiAmeDsgfQorfTsKKworLy8gSW4gcHJvdG8yIE1hcCwgZW51bSBuZWVkcyB0byBiZSBpbml0aWFsaXplZCB0byBnaXZlbiBkZWZhdWx0IHZhbHVlLCB3aGlsZQorLy8gb3RoZXIgdHlwZXMnIGRlZmF1bHQgdmFsdWUgY2FuIGJlIGluZmVycmVkIGZyb20gdGhlIHR5cGUuCit0ZW1wbGF0ZSA8Ym9vbCBJc0VudW0sIHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBWYWx1ZUluaXRpYWxpemVyIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUmIHR5cGUsIGludCBkZWZhdWx0X2VudW1fdmFsdWUpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBWYWx1ZUluaXRpYWxpemVyPHRydWUsIFR5cGU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUmIHZhbHVlLCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKSB7CisgICAgdmFsdWUgPSBzdGF0aWNfY2FzdDxUeXBlPihkZWZhdWx0X2VudW1fdmFsdWUpOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2NsYXNzIE1hcFZhbHVlSW5pdGlhbGl6ZXI8ZmFsc2UsIFR5cGU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUmIHZhbHVlLCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKSB7fQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGUsIGJvb2wgaXNfYXJlbmFfY29uc3RydWN0YWJsZT4KK2NsYXNzIE1hcEFyZW5hTWVzc2FnZUNyZWF0b3IgeworIHB1YmxpYzoKKyAgLy8gVXNlIGFyZW5hIHRvIGNyZWF0ZSBtZXNzYWdlIGlmIFR5cGUgaXMgYXJlbmEgY29uc3RydWN0YWJsZS4gT3RoZXJ3aXNlLAorICAvLyBjcmVhdGUgdGhlIG1lc3NhZ2Ugb24gaGVhcC4KKyAgc3RhdGljIGlubGluZSBUeXBlKiBDcmVhdGVNZXNzYWdlKEFyZW5hKiBhcmVuYSk7Cit9OwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBBcmVuYU1lc3NhZ2VDcmVhdG9yPFR5cGUsIHRydWU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgVHlwZSogQ3JlYXRlTWVzc2FnZShBcmVuYSogYXJlbmEpIHsKKyAgICByZXR1cm4gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VHlwZT4oYXJlbmEpOworICB9Cit9OwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBBcmVuYU1lc3NhZ2VDcmVhdG9yPFR5cGUsIGZhbHNlPiB7CisgcHVibGljOgorICBzdGF0aWMgaW5saW5lIFR5cGUqIENyZWF0ZU1lc3NhZ2UoQXJlbmEqIGFyZW5hKSB7CisgICAgcmV0dXJuIG5ldyBUeXBlOworICB9Cit9OworCisvLyBIYW5kbGVycyBmb3Iga2V5L3ZhbHVlIHN0b3JlZCB0eXBlIGluIE1hcEZpZWxkLiA9PT09PT09PT09PT09PT09PT0KKworLy8gSGFuZGxlciBmb3IgbWVzc2FnZQordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBDcHBUeXBlSGFuZGxlciA6IHB1YmxpYyBNYXBDb21tb25UeXBlSGFuZGxlcjxUeXBlPiB7CisgcHVibGljOgorICBzdGF0aWMgY29uc3QgYm9vbCBrSXNTdHJpbmdPck1lc3NhZ2UgPSB0cnVlOworICAvLyBTcGFjZVVzZWRJbk1hcEVudHJ5OiBSZXR1cm4gYnl0ZXMgdXNlZCBieSB2YWx1ZSBpbiBNYXBFbnRyeSwgZXhjbHVkaW5nCisgIC8vIHRob3NlIGFscmVhZHkgY2FsY3VsYXRlIGluIHNpemVvZihNYXBGaWVsZCkuCisgIHN0YXRpYyBpbnQgU3BhY2VVc2VkSW5NYXBFbnRyeShjb25zdCBUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZS0+U3BhY2VVc2VkKCk7CisgIH0KKyAgLy8gUmV0dXJuIGJ5dGVzIHVzZWQgYnkgdmFsdWUgaW4gTWFwLgorICBzdGF0aWMgaW50IFNwYWNlVXNlZEluTWFwKGNvbnN0IFR5cGUmIHZhbHVlKSB7IHJldHVybiB2YWx1ZS5TcGFjZVVzZWQoKTsgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXIoVHlwZSoqIHZhbHVlKSB7CisgICAgaWYgKCp2YWx1ZSAhPSBOVUxMKSAoKnZhbHVlKS0+VHlwZTo6Q2xlYXIoKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXJNYXliZUJ5RGVmYXVsdEVudW0oVHlwZSoqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZSkgeworICAgIGlmICgqdmFsdWUgIT0gTlVMTCkgKCp2YWx1ZSktPlR5cGU6OkNsZWFyKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIE1lcmdlKGNvbnN0IFR5cGUmIGZyb20sIFR5cGUqKiB0bykgeworICAgICgqdG8pLT5NZXJnZUZyb20oZnJvbSk7CisgIH0KKworICBzdGF0aWMgdm9pZCBEZWxldGUoY29uc3QgVHlwZSogcHRyKSB7IGRlbGV0ZSBwdHI7IH0KKworICAvLyBBc3NpZ24gZGVmYXVsdCB2YWx1ZSB0byBnaXZlbiBpbnN0YW5jZS4KKyAgc3RhdGljIGlubGluZSB2b2lkIEFzc2lnbkRlZmF1bHRWYWx1ZShUeXBlKiogdmFsdWUpIHsKKyAgICAqdmFsdWUgPSBjb25zdF9jYXN0PFR5cGUqPigmVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgfQorICAvLyBJbml0aWFsaXplIHZhbHVlIHdoZW4gY29uc3RydWN0aW5nIE1hcEVudHJ5CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUqKiB4LCBBcmVuYSogYXJlbmEpIHsgKnggPSBOVUxMOyB9CisgIC8vIFNhbWUgYXMgYWJvdmUsIGJ1dCB1c2UgZGVmYXVsdF9lbnVtX3ZhbHVlIHRvIGluaXRpYWxpemUgZW51bSB0eXBlIHZhbHVlLgorICBzdGF0aWMgaW5saW5lIHZvaWQgSW5pdGlhbGl6ZU1heWJlQnlEZWZhdWx0RW51bSgKKyAgICAgIFR5cGUqKiB4LCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlLCBBcmVuYSogYXJlbmEpIHsKKyAgICAqeCA9IE5VTEw7CisgIH0KKyAgLy8gSW5pdGlhbGl6ZSB2YWx1ZSBmb3IgdGhlIGZpcnN0IHRpbWUgbXV0YWJsZSBhY2Nlc3NvciBpcyBjYWxsZWQuCisgIHN0YXRpYyBpbmxpbmUgdm9pZCBFbnN1cmVNdXRhYmxlKFR5cGUqKiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKCp2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAqdmFsdWUgPQorICAgICAgICAgIE1hcEFyZW5hTWVzc2FnZUNyZWF0b3I8VHlwZSwgQXJlbmE6OmlzX2FyZW5hX2NvbnN0cnVjdGFibGU8VHlwZT46OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6OnZhbHVlPjo6Q3JlYXRlTWVzc2FnZShhcmVuYSk7CisgICAgfQorICB9CisgIC8vIFJldHVybiBkZWZhdWx0IGluc3RhbmNlIGlmIHZhbHVlIGlzIG5vdCBpbml0aWFsaXplZCB3aGVuIGNhbGxpbmcgY29uc3QKKyAgLy8gcmVmZXJlbmNlIGFjY2Vzc29yLgorICBzdGF0aWMgaW5saW5lIGNvbnN0IFR5cGUmIERlZmF1bHRJZk5vdEluaXRpYWxpemVkKGNvbnN0IFR5cGUqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFR5cGUqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICByZXR1cm4gdmFsdWUgIT0gTlVMTCA/ICp2YWx1ZSA6ICpkZWZhdWx0X3ZhbHVlOworICB9CisgIC8vIENoZWNrIGlmIGFsbCByZXF1aXJlZCBmaWVsZHMgaGF2ZSB2YWx1ZXMgc2V0LgorICBzdGF0aWMgaW5saW5lIGJvb2wgSXNJbml0aWFsaXplZChUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZS0+SXNJbml0aWFsaXplZCgpOworICB9Cit9OworCisvLyBIYW5kbGVyIGZvciBzdHJpbmcuCit0ZW1wbGF0ZSA8PgorY2xhc3MgTWFwQ3BwVHlwZUhhbmRsZXI8c3RyaW5nPiA6IHB1YmxpYyBNYXBDb21tb25UeXBlSGFuZGxlcjxzdHJpbmc+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBjb25zdCBib29sIGtJc1N0cmluZ09yTWVzc2FnZSA9IHRydWU7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBNZXJnZShjb25zdCBzdHJpbmcmIGZyb20sIHN0cmluZyoqIHRvKSB7ICoqdG8gPSBmcm9tOyB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBDbGVhcihzdHJpbmcqKiB2YWx1ZSkgeyAoKnZhbHVlKS0+Y2xlYXIoKTsgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXJNYXliZUJ5RGVmYXVsdEVudW0oc3RyaW5nKiogdmFsdWUsIGludCBkZWZhdWx0X2VudW0pIHsKKyAgICAoKnZhbHVlKS0+Y2xlYXIoKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGludCBTcGFjZVVzZWRJbk1hcEVudHJ5KGNvbnN0IHN0cmluZyogdmFsdWUpIHsKKyAgICByZXR1cm4gc2l6ZW9mKCp2YWx1ZSkgKyBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCp2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSBpbnQgU3BhY2VVc2VkSW5NYXAoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICAgIHJldHVybiBzaXplb2YodmFsdWUpICsgU3RyaW5nU3BhY2VVc2VkRXhjbHVkaW5nU2VsZih2YWx1ZSk7CisgIH0KKyAgc3RhdGljIHZvaWQgRGVsZXRlKGNvbnN0IHN0cmluZyogcHRyKSB7CisgICAgaWYgKHB0ciAhPSAmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKSkgZGVsZXRlIHB0cjsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQXNzaWduRGVmYXVsdFZhbHVlKHN0cmluZyoqIHZhbHVlKSB7fQorICBzdGF0aWMgaW5saW5lIHZvaWQgSW5pdGlhbGl6ZShzdHJpbmcqKiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7CisgICAgKnZhbHVlID0gY29uc3RfY2FzdDwgOjpzdGQ6OnN0cmluZyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpKTsKKyAgICBpZiAoYXJlbmEgIT0gTlVMTCkgYXJlbmEtPk93bigqdmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplTWF5YmVCeURlZmF1bHRFbnVtKAorICAgICAgc3RyaW5nKiogdmFsdWUsIGludCBkZWZhdWx0X2VudW1fdmFsdWUsIEFyZW5hKiBhcmVuYSkgeworICAgICp2YWx1ZSA9IGNvbnN0X2Nhc3Q8IDo6c3RkOjpzdHJpbmcqPigmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKSk7CisgICAgaWYgKGFyZW5hICE9IE5VTEwpIGFyZW5hLT5Pd24oKnZhbHVlKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgRW5zdXJlTXV0YWJsZShzdHJpbmcqKiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKCp2YWx1ZSA9PSAmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKSkgeworICAgICAgKnZhbHVlID0gQXJlbmE6OkNyZWF0ZTxzdHJpbmc+KGFyZW5hKTsKKyAgICB9CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCBzdHJpbmcmIERlZmF1bHRJZk5vdEluaXRpYWxpemVkKAorICAgICAgY29uc3Qgc3RyaW5nKiB2YWx1ZSwKKyAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF92YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZSAhPSBkZWZhdWx0X3ZhbHVlID8gKnZhbHVlIDogKmRlZmF1bHRfdmFsdWU7CisgIH0KKyAgc3RhdGljIGlubGluZSBib29sIElzSW5pdGlhbGl6ZWQoc3RyaW5nKiB2YWx1ZSkgeyByZXR1cm4gdHJ1ZTsgfQorfTsKKworLy8gQmFzZSBjbGFzcyBmb3IgcHJpbWl0aXZlIHR5cGUgaGFuZGxlcnMuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2NsYXNzIE1hcFByaW1pdGl2ZVR5cGVIYW5kbGVyIDogcHVibGljIE1hcENvbW1vblR5cGVIYW5kbGVyPFR5cGU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBjb25zdCBib29sIGtJc1N0cmluZ09yTWVzc2FnZSA9IGZhbHNlOworICBzdGF0aWMgaW5saW5lIHZvaWQgRGVsZXRlKGNvbnN0IFR5cGUmIHgpIHt9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBNZXJnZShjb25zdCBUeXBlJiBmcm9tLCBUeXBlKiB0bykgeyAqdG8gPSBmcm9tOyB9CisgIHN0YXRpYyBpbmxpbmUgaW50IFNwYWNlVXNlZEluTWFwRW50cnkoY29uc3QgVHlwZSYgdmFsdWUpIHsgcmV0dXJuIDA7IH0KKyAgc3RhdGljIGlubGluZSBpbnQgU3BhY2VVc2VkSW5NYXAoY29uc3QgVHlwZSYgdmFsdWUpIHsgcmV0dXJuIHNpemVvZihUeXBlKTsgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQXNzaWduRGVmYXVsdFZhbHVlKFR5cGUqIHZhbHVlKSB7fQorICBzdGF0aWMgaW5saW5lIGNvbnN0IFR5cGUmIERlZmF1bHRJZk5vdEluaXRpYWxpemVkKAorICAgICAgY29uc3QgVHlwZSYgdmFsdWUsIGNvbnN0IFR5cGUmIGRlZmF1bHRfdmFsdWUpIHsKKyAgICByZXR1cm4gdmFsdWU7CisgIH0KKyAgc3RhdGljIGlubGluZSBib29sIElzSW5pdGlhbGl6ZWQoY29uc3QgVHlwZSYgdmFsdWUpIHsgcmV0dXJuIHRydWU7IH0KK307CisKKy8vIEhhbmRsZXJzIGZvciBwcmltaXRpdmUgdHlwZXMuCisjZGVmaW5lIFBSSU1JVElWRV9IQU5ETEVSKENUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIE1hcENwcFR5cGVIYW5kbGVyPENUeXBlPiA6IHB1YmxpYyBNYXBQcmltaXRpdmVUeXBlSGFuZGxlcjxDVHlwZT4geyAgICBcCisgICBwdWJsaWM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGlubGluZSB2b2lkIENsZWFyKENUeXBlKiB2YWx1ZSkgeyAqdmFsdWUgPSAwOyB9ICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGlubGluZSB2b2lkIENsZWFyTWF5YmVCeURlZmF1bHRFbnVtKENUeXBlKiB2YWx1ZSwgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWUpIHsgICAgICBcCisgICAgICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxDVHlwZT4oZGVmYXVsdF9lbnVtX3ZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGlubGluZSB2b2lkIEluaXRpYWxpemUoQ1R5cGUqIHZhbHVlLCBBcmVuYSogYXJlbmEpIHsgKnZhbHVlID0gMDsgfSBcCisgICAgc3RhdGljIGlubGluZSB2b2lkIEluaXRpYWxpemVNYXliZUJ5RGVmYXVsdEVudW0oQ1R5cGUqIHZhbHVlLCAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZSwgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIGFyZW5hKSB7ICAgICAgICAgICBcCisgICAgICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxDVHlwZT4oZGVmYXVsdF9lbnVtX3ZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGlubGluZSB2b2lkIEVuc3VyZU11dGFibGUoQ1R5cGUqIHZhbHVlLCBBcmVuYSogYXJlbmEpIHt9ICAgICAgICAgICBcCisgIH07CisKK1BSSU1JVElWRV9IQU5ETEVSKGludDMyICkKK1BSSU1JVElWRV9IQU5ETEVSKGludDY0ICkKK1BSSU1JVElWRV9IQU5ETEVSKHVpbnQzMikKK1BSSU1JVElWRV9IQU5ETEVSKHVpbnQ2NCkKK1BSSU1JVElWRV9IQU5ETEVSKGRvdWJsZSkKK1BSSU1JVElWRV9IQU5ETEVSKGZsb2F0ICkKK1BSSU1JVElWRV9IQU5ETEVSKGJvb2wgICkKKworI3VuZGVmIFBSSU1JVElWRV9IQU5ETEVSCisKKy8vIERlZmluZSBjb25zdGFudHMgZm9yIGdpdmVuIHdpcmUgZmllbGQgdHlwZQordGVtcGxhdGUgPFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgZmllbGRfdHlwZT4KK2NsYXNzIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHMge307CisKKyNkZWZpbmUgVFlQRV9UUkFJVFMoRmllbGRUeXBlLCBDVHlwZSwgV2lyZUZvcm1hdFR5cGUsIElzTWVzc2FnZSwgSXNFbnVtKSBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjbGFzcyBNYXBXaXJlRmllbGRUeXBlVHJhaXRzPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlPiB7ICAgICAgIFwKKyAgIHB1YmxpYzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdHlwZWRlZiBDVHlwZSBDcHBUeXBlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHN0YXRpYyBjb25zdCBib29sIGtJc01lc3NhZ2UgPSBJc01lc3NhZ2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgY29uc3QgYm9vbCBrSXNFbnVtID0gSXNFbnVtOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGNvbnN0IFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSBrV2lyZVR5cGUgPSAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfIyNXaXJlRm9ybWF0VHlwZTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfTsKKworVFlQRV9UUkFJVFMoTUVTU0FHRSAsIE1lc3NhZ2VMaXRlLCBMRU5HVEhfREVMSU1JVEVELCB0cnVlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKFNUUklORyAgLCBzdHJpbmcgLCAgTEVOR1RIX0RFTElNSVRFRCwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoQllURVMgICAsIHN0cmluZyAsICBMRU5HVEhfREVMSU1JVEVELCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhJTlQ2NCAgICwgaW50NjQgICwgIFZBUklOVCAsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKFVJTlQ2NCAgLCB1aW50NjQgLCAgVkFSSU5UICwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoSU5UMzIgICAsIGludDMyICAsICBWQVJJTlQgLCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhVSU5UMzIgICwgdWludDMyICwgIFZBUklOVCAsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKFNJTlQ2NCAgLCBpbnQ2NCAgLCAgVkFSSU5UICwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoU0lOVDMyICAsIGludDMyICAsICBWQVJJTlQgLCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhFTlVNICAgICwgaW50ICAgICwgIFZBUklOVCAsIGZhbHNlLCB0cnVlICkKK1RZUEVfVFJBSVRTKERPVUJMRSAgLCBkb3VibGUgLCAgRklYRUQ2NCwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoRkxPQVQgICAsIGZsb2F0ICAsICBGSVhFRDMyLCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhGSVhFRDY0ICwgdWludDY0ICwgIEZJWEVENjQsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKEZJWEVEMzIgLCB1aW50MzIgLCAgRklYRUQzMiwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoU0ZJWEVENjQsIGludDY0ICAsICBGSVhFRDY0LCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhTRklYRUQzMiwgaW50MzIgICwgIEZJWEVEMzIsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKEJPT0wgICAgLCBib29sICAgLCAgVkFSSU5UICwgZmFsc2UsIGZhbHNlKQorCisjdW5kZWYgVFlQRV9UUkFJVFMKKwordGVtcGxhdGUgPFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgZmllbGRfdHlwZT4KK2NsYXNzIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyIHsKKyBwdWJsaWM6CisgIC8vIEludGVybmFsIHN0b3JlZCB0eXBlIGluIE1hcEVudHJ5TGl0ZSBmb3IgZ2l2ZW4gd2lyZSBmaWVsZCB0eXBlLgorICB0eXBlZGVmIHR5cGVuYW1lIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8ZmllbGRfdHlwZT46OkNwcFR5cGUgQ3BwVHlwZTsKKyAgLy8gQ29ycmVzcG9uZGluZyB3aXJlIHR5cGUgZm9yIGZpZWxkIHR5cGUuCisgIHN0YXRpYyBjb25zdCBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUga1dpcmVUeXBlID0KKyAgICAgIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8ZmllbGRfdHlwZT46OmtXaXJlVHlwZTsKKyAgLy8gV2hldGhlciB3aXJlIHR5cGUgaXMgZm9yIG1lc3NhZ2UuCisgIHN0YXRpYyBjb25zdCBib29sIGtJc01lc3NhZ2UgPSBNYXBXaXJlRmllbGRUeXBlVHJhaXRzPGZpZWxkX3R5cGU+OjprSXNNZXNzYWdlOworICAvLyBXaGV0aGVyIHdpcmUgdHlwZSBpcyBmb3IgZW51bS4KKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzRW51bSA9IE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8ZmllbGRfdHlwZT46OmtJc0VudW07CisKKyAgLy8gRnVuY3Rpb25zIHVzZWQgaW4gcGFyc2luZyBhbmQgc2VyaWFsaXphdGlvbi4gPT09PT09PT09PT09PT09PT09PQorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWVUeXBlPgorICBzdGF0aWMgaW5saW5lIGludCBCeXRlU2l6ZShjb25zdCBWYWx1ZVR5cGUmIHZhbHVlKTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlVHlwZT4KKyAgc3RhdGljIGlubGluZSBpbnQgR2V0Q2FjaGVkU2l6ZShjb25zdCBWYWx1ZVR5cGUmIHZhbHVlKTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBWYWx1ZVR5cGUqIHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlKGludCBmaWVsZCwgY29uc3QgQ3BwVHlwZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlVG9BcnJheShpbnQgZmllbGQsIGNvbnN0IENwcFR5cGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIG91dHB1dCk7Cit9OworCit0ZW1wbGF0ZSA8PgordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlVHlwZT4KK2lubGluZSBpbnQgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRT46OkJ5dGVTaXplKAorICAgIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCh2YWx1ZSk7Cit9CisKKyNkZWZpbmUgQllURV9TSVpFKEZpZWxkVHlwZSwgRGVjbGFyZWRUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZVR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBXaXJlRmllbGRUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZT46OkJ5dGVTaXplKCBcCisgICAgICBjb25zdCBWYWx1ZVR5cGUmIHZhbHVlKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OkRlY2xhcmVkVHlwZSMjU2l6ZSh2YWx1ZSk7ICAgICAgICAgICAgICAgICAgXAorICB9CisKK0JZVEVfU0laRShTVFJJTkcsIFN0cmluZykKK0JZVEVfU0laRShCWVRFUyAsIEJ5dGVzKQorQllURV9TSVpFKElOVDY0ICwgSW50NjQpCitCWVRFX1NJWkUoVUlOVDY0LCBVSW50NjQpCitCWVRFX1NJWkUoSU5UMzIgLCBJbnQzMikKK0JZVEVfU0laRShVSU5UMzIsIFVJbnQzMikKK0JZVEVfU0laRShTSU5UNjQsIFNJbnQ2NCkKK0JZVEVfU0laRShTSU5UMzIsIFNJbnQzMikKK0JZVEVfU0laRShFTlVNICAsIEVudW0pCisKKyN1bmRlZiBCWVRFX1NJWkUKKworI2RlZmluZSBGSVhFRF9CWVRFX1NJWkUoRmllbGRUeXBlLCBEZWNsYXJlZFR5cGUpICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlPjo6Qnl0ZVNpemUoIFwKKyAgICAgIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6ayMjRGVjbGFyZWRUeXBlIyNTaXplOyAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKworRklYRURfQllURV9TSVpFKERPVUJMRSAgLCBEb3VibGUpCitGSVhFRF9CWVRFX1NJWkUoRkxPQVQgICAsIEZsb2F0KQorRklYRURfQllURV9TSVpFKEZJWEVENjQgLCBGaXhlZDY0KQorRklYRURfQllURV9TSVpFKEZJWEVEMzIgLCBGaXhlZDMyKQorRklYRURfQllURV9TSVpFKFNGSVhFRDY0LCBTRml4ZWQ2NCkKK0ZJWEVEX0JZVEVfU0laRShTRklYRUQzMiwgU0ZpeGVkMzIpCitGSVhFRF9CWVRFX1NJWkUoQk9PTCAgICAsIEJvb2wpCisKKyN1bmRlZiBGSVhFRF9CWVRFX1NJWkUKKwordGVtcGxhdGUgPD4KK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZVR5cGU+CitpbmxpbmUgaW50IE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPAorICAgIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0U+OjpHZXRDYWNoZWRTaXplKGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpMZW5ndGhEZWxpbWl0ZWRTaXplKHZhbHVlLkdldENhY2hlZFNpemUoKSk7Cit9CisKKyNkZWZpbmUgR0VUX0NBQ0hFRF9TSVpFKEZpZWxkVHlwZSwgRGVjbGFyZWRUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWVUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlPjo6R2V0Q2FjaGVkU2l6ZSggXAorICAgICAgY29uc3QgVmFsdWVUeXBlJiB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OkRlY2xhcmVkVHlwZSMjU2l6ZSh2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKworR0VUX0NBQ0hFRF9TSVpFKFNUUklORywgU3RyaW5nKQorR0VUX0NBQ0hFRF9TSVpFKEJZVEVTICwgQnl0ZXMpCitHRVRfQ0FDSEVEX1NJWkUoSU5UNjQgLCBJbnQ2NCkKK0dFVF9DQUNIRURfU0laRShVSU5UNjQsIFVJbnQ2NCkKK0dFVF9DQUNIRURfU0laRShJTlQzMiAsIEludDMyKQorR0VUX0NBQ0hFRF9TSVpFKFVJTlQzMiwgVUludDMyKQorR0VUX0NBQ0hFRF9TSVpFKFNJTlQ2NCwgU0ludDY0KQorR0VUX0NBQ0hFRF9TSVpFKFNJTlQzMiwgU0ludDMyKQorR0VUX0NBQ0hFRF9TSVpFKEVOVU0gICwgRW51bSkKKworI3VuZGVmIEdFVF9DQUNIRURfU0laRQorCisjZGVmaW5lIEdFVF9GSVhFRF9DQUNIRURfU0laRShGaWVsZFR5cGUsIERlY2xhcmVkVHlwZSkgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBXaXJlRmllbGRUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZT46OkdldENhY2hlZFNpemUoIFwKKyAgICAgIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprIyNEZWNsYXJlZFR5cGUjI1NpemU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0dFVF9GSVhFRF9DQUNIRURfU0laRShET1VCTEUgICwgRG91YmxlKQorR0VUX0ZJWEVEX0NBQ0hFRF9TSVpFKEZMT0FUICAgLCBGbG9hdCkKK0dFVF9GSVhFRF9DQUNIRURfU0laRShGSVhFRDY0ICwgRml4ZWQ2NCkKK0dFVF9GSVhFRF9DQUNIRURfU0laRShGSVhFRDMyICwgRml4ZWQzMikKK0dFVF9GSVhFRF9DQUNIRURfU0laRShTRklYRUQ2NCwgU0ZpeGVkNjQpCitHRVRfRklYRURfQ0FDSEVEX1NJWkUoU0ZJWEVEMzIsIFNGaXhlZDMyKQorR0VUX0ZJWEVEX0NBQ0hFRF9TSVpFKEJPT0wgICAgLCBCb29sKQorCisjdW5kZWYgR0VUX0ZJWEVEX0NBQ0hFRF9TSVpFCisKK3RlbXBsYXRlIDw+CitpbmxpbmUgdm9pZCBNYXBXaXJlRmllbGRUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFPjo6V3JpdGUoCisgICAgaW50IGZpZWxkLCBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoZmllbGQsIHZhbHVlLCBvdXRwdXQpOworfQorCit0ZW1wbGF0ZSA8PgoraW5saW5lIHVpbnQ4KgorTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRT46OldyaXRlVG9BcnJheSgKKyAgICBpbnQgZmllbGQsIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwgdWludDgqIG91dHB1dCkgeworICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZVRvQXJyYXkoZmllbGQsIHZhbHVlLCBvdXRwdXQpOworfQorCisjZGVmaW5lIFdSSVRFX01FVEhPRChGaWVsZFR5cGUsIERlY2xhcmVkVHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlPjo6V3JpdGUoICAgICAgICAgICAgXAorICAgICAgaW50IGZpZWxkLCBjb25zdCBDcHBUeXBlJiB2YWx1ZSwgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsgICAgICAgIFwKKyAgICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OldyaXRlIyNEZWNsYXJlZFR5cGUoZmllbGQsIHZhbHVlLCBvdXRwdXQpOyAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHVpbnQ4KiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFdpcmVGaWVsZFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlPjo6V3JpdGVUb0FycmF5KCAgICAgXAorICAgICAgaW50IGZpZWxkLCBjb25zdCBDcHBUeXBlJiB2YWx1ZSwgdWludDgqIG91dHB1dCkgeyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OldyaXRlIyNEZWNsYXJlZFR5cGUjI1RvQXJyYXkoZmllbGQsIHZhbHVlLCBvdXRwdXQpOyBcCisgIH0KKworV1JJVEVfTUVUSE9EKFNUUklORyAgLCBTdHJpbmcpCitXUklURV9NRVRIT0QoQllURVMgICAsIEJ5dGVzKQorV1JJVEVfTUVUSE9EKElOVDY0ICAgLCBJbnQ2NCkKK1dSSVRFX01FVEhPRChVSU5UNjQgICwgVUludDY0KQorV1JJVEVfTUVUSE9EKElOVDMyICAgLCBJbnQzMikKK1dSSVRFX01FVEhPRChVSU5UMzIgICwgVUludDMyKQorV1JJVEVfTUVUSE9EKFNJTlQ2NCAgLCBTSW50NjQpCitXUklURV9NRVRIT0QoU0lOVDMyICAsIFNJbnQzMikKK1dSSVRFX01FVEhPRChFTlVNICAgICwgRW51bSkKK1dSSVRFX01FVEhPRChET1VCTEUgICwgRG91YmxlKQorV1JJVEVfTUVUSE9EKEZMT0FUICAgLCBGbG9hdCkKK1dSSVRFX01FVEhPRChGSVhFRDY0ICwgRml4ZWQ2NCkKK1dSSVRFX01FVEhPRChGSVhFRDMyICwgRml4ZWQzMikKK1dSSVRFX01FVEhPRChTRklYRUQ2NCwgU0ZpeGVkNjQpCitXUklURV9NRVRIT0QoU0ZJWEVEMzIsIFNGaXhlZDMyKQorV1JJVEVfTUVUSE9EKEJPT0wgICAgLCBCb29sKQorCisjdW5kZWYgV1JJVEVfTUVUSE9ECisKK3RlbXBsYXRlIDw+Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWVUeXBlPgoraW5saW5lIGJvb2wgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRT46OlJlYWQoCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBWYWx1ZVR5cGUqIHZhbHVlKSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoaW5wdXQsIHZhbHVlKTsKK30KKwordGVtcGxhdGUgPD4KK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZVR5cGU+CitpbmxpbmUgYm9vbCBNYXBXaXJlRmllbGRUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkc+OjpSZWFkKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgVmFsdWVUeXBlKiB2YWx1ZSkgeworICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoaW5wdXQsIHZhbHVlKTsKK30KKwordGVtcGxhdGUgPD4KK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZVR5cGU+CitpbmxpbmUgYm9vbCBNYXBXaXJlRmllbGRUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CWVRFUz46OlJlYWQoCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBWYWx1ZVR5cGUqIHZhbHVlKSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZEJ5dGVzKGlucHV0LCB2YWx1ZSk7Cit9CisKKyNkZWZpbmUgUkVBRF9NRVRIT0QoRmllbGRUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWVUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGJvb2wgTWFwV2lyZUZpZWxkVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGU+OjpSZWFkKCBcCisgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIFZhbHVlVHlwZSogdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxDcHBUeXBlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGU+KCAgICBcCisgICAgICAgIGlucHV0LCB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK1JFQURfTUVUSE9EKElOVDY0KQorUkVBRF9NRVRIT0QoVUlOVDY0KQorUkVBRF9NRVRIT0QoSU5UMzIpCitSRUFEX01FVEhPRChVSU5UMzIpCitSRUFEX01FVEhPRChTSU5UNjQpCitSRUFEX01FVEhPRChTSU5UMzIpCitSRUFEX01FVEhPRChFTlVNKQorUkVBRF9NRVRIT0QoRE9VQkxFKQorUkVBRF9NRVRIT0QoRkxPQVQpCitSRUFEX01FVEhPRChGSVhFRDY0KQorUkVBRF9NRVRIT0QoRklYRUQzMikKK1JFQURfTUVUSE9EKFNGSVhFRDY0KQorUkVBRF9NRVRIT0QoU0ZJWEVEMzIpCitSRUFEX01FVEhPRChCT09MKQorCisjdW5kZWYgUkVBRF9NRVRIT0QKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVFlQRV9IQU5ETEVSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF91bml0dGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzBmNjcyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucHJvdG8KQEAgLTAsMCArMSwxMDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworb3B0aW9uIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorLy8gSW4gbWFwX3Rlc3RfdXRpbC5oIHdlIGRvICJ1c2luZyBuYW1lc3BhY2UgdW5pdHRlc3QgPSBwcm90b2J1Zl91bml0dGVzdCIuCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCisvLyBUZXN0cyBtYXBzLgorbWVzc2FnZSBUZXN0TWFwIHsKKyAgbWFwPGludDMyICAgLCBpbnQzMiAgID4gbWFwX2ludDMyX2ludDMyICAgICAgID0gMTsKKyAgbWFwPGludDY0ICAgLCBpbnQ2NCAgID4gbWFwX2ludDY0X2ludDY0ICAgICAgID0gMjsKKyAgbWFwPHVpbnQzMiAgLCB1aW50MzIgID4gbWFwX3VpbnQzMl91aW50MzIgICAgID0gMzsKKyAgbWFwPHVpbnQ2NCAgLCB1aW50NjQgID4gbWFwX3VpbnQ2NF91aW50NjQgICAgID0gNDsKKyAgbWFwPHNpbnQzMiAgLCBzaW50MzIgID4gbWFwX3NpbnQzMl9zaW50MzIgICAgID0gNTsKKyAgbWFwPHNpbnQ2NCAgLCBzaW50NjQgID4gbWFwX3NpbnQ2NF9zaW50NjQgICAgID0gNjsKKyAgbWFwPGZpeGVkMzIgLCBmaXhlZDMyID4gbWFwX2ZpeGVkMzJfZml4ZWQzMiAgID0gNzsKKyAgbWFwPGZpeGVkNjQgLCBmaXhlZDY0ID4gbWFwX2ZpeGVkNjRfZml4ZWQ2NCAgID0gODsKKyAgbWFwPHNmaXhlZDMyLCBzZml4ZWQzMj4gbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTsKKyAgbWFwPHNmaXhlZDY0LCBzZml4ZWQ2ND4gbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7CisgIG1hcDxpbnQzMiAgICwgZmxvYXQgICA+IG1hcF9pbnQzMl9mbG9hdCAgICAgICA9IDExOworICBtYXA8aW50MzIgICAsIGRvdWJsZSAgPiBtYXBfaW50MzJfZG91YmxlICAgICAgPSAxMjsKKyAgbWFwPGJvb2wgICAgLCBib29sICAgID4gbWFwX2Jvb2xfYm9vbCAgICAgICAgID0gMTM7CisgIG1hcDxzdHJpbmcgICwgc3RyaW5nICA+IG1hcF9zdHJpbmdfc3RyaW5nICAgICA9IDE0OworICBtYXA8aW50MzIgICAsIGJ5dGVzICAgPiBtYXBfaW50MzJfYnl0ZXMgICAgICAgPSAxNTsKKyAgbWFwPGludDMyICAgLCBNYXBFbnVtID4gbWFwX2ludDMyX2VudW0gICAgICAgID0gMTY7CisgIG1hcDxpbnQzMiAgICwgRm9yZWlnbk1lc3NhZ2U+IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzsKK30KKworbWVzc2FnZSBUZXN0TWFwU3VibWVzc2FnZSB7CisgIG9wdGlvbmFsIFRlc3RNYXAgdGVzdF9tYXAgPSAxOworfQorCittZXNzYWdlIFRlc3RNZXNzYWdlTWFwIHsKKyAgbWFwPGludDMyLCBUZXN0QWxsVHlwZXM+IG1hcF9pbnQzMl9tZXNzYWdlID0gMTsKK30KKworLy8gVHdvIG1hcCBmaWVsZHMgc2hhcmUgdGhlIHNhbWUgZW50cnkgZGVmYXVsdCBpbnN0YW5jZS4KK21lc3NhZ2UgVGVzdFNhbWVUeXBlTWFwIHsKKyAgbWFwPGludDMyLCBpbnQzMj4gbWFwMSA9IDE7CisgIG1hcDxpbnQzMiwgaW50MzI+IG1hcDIgPSAyOworfQorCisKK2VudW0gTWFwRW51bSB7CisgIE1BUF9FTlVNX0ZPTyA9IDA7CisgIE1BUF9FTlVNX0JBUiA9IDE7CisgIE1BUF9FTlVNX0JBWiA9IDI7Cit9CisKKy8vIFRlc3QgZW1iZWRlZCBtZXNzYWdlIHdpdGggcmVxdWlyZWQgZmllbGRzCittZXNzYWdlIFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgeworICBtYXA8aW50MzIsIFRlc3RSZXF1aXJlZD4gbWFwX2ZpZWxkID0gMTsKK30KKworbWVzc2FnZSBUZXN0QXJlbmFNYXAgeworICBtYXA8aW50MzIgICAsIGludDMyICAgPiBtYXBfaW50MzJfaW50MzIgICAgICAgPSAxOworICBtYXA8aW50NjQgICAsIGludDY0ICAgPiBtYXBfaW50NjRfaW50NjQgICAgICAgPSAyOworICBtYXA8dWludDMyICAsIHVpbnQzMiAgPiBtYXBfdWludDMyX3VpbnQzMiAgICAgPSAzOworICBtYXA8dWludDY0ICAsIHVpbnQ2NCAgPiBtYXBfdWludDY0X3VpbnQ2NCAgICAgPSA0OworICBtYXA8c2ludDMyICAsIHNpbnQzMiAgPiBtYXBfc2ludDMyX3NpbnQzMiAgICAgPSA1OworICBtYXA8c2ludDY0ICAsIHNpbnQ2NCAgPiBtYXBfc2ludDY0X3NpbnQ2NCAgICAgPSA2OworICBtYXA8Zml4ZWQzMiAsIGZpeGVkMzIgPiBtYXBfZml4ZWQzMl9maXhlZDMyICAgPSA3OworICBtYXA8Zml4ZWQ2NCAsIGZpeGVkNjQgPiBtYXBfZml4ZWQ2NF9maXhlZDY0ICAgPSA4OworICBtYXA8c2ZpeGVkMzIsIHNmaXhlZDMyPiBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OworICBtYXA8c2ZpeGVkNjQsIHNmaXhlZDY0PiBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDsKKyAgbWFwPGludDMyICAgLCBmbG9hdCAgID4gbWFwX2ludDMyX2Zsb2F0ICAgICAgID0gMTE7CisgIG1hcDxpbnQzMiAgICwgZG91YmxlICA+IG1hcF9pbnQzMl9kb3VibGUgICAgICA9IDEyOworICBtYXA8Ym9vbCAgICAsIGJvb2wgICAgPiBtYXBfYm9vbF9ib29sICAgICAgICAgPSAxMzsKKyAgbWFwPGludDMyICAgLCBNYXBFbnVtID4gbWFwX2ludDMyX2VudW0gICAgICAgID0gMTQ7CisgIG1hcDxpbnQzMiAgICwgRm9yZWlnbk1lc3NhZ2U+IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNThiZTg0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmNjCkBAIC0wLDAgKzEsNDc1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxzdGFjaz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX2ludGVybmFsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaW5nbGV0b24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpSZWZsZWN0aW9uT3BzOworCitNZXNzYWdlOjp+TWVzc2FnZSgpIHt9CisKK3ZvaWQgTWVzc2FnZTo6TWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2UmIGZyb20pIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEdldERlc2NyaXB0b3IoKTsKKyAgR09PR0xFX0NIRUNLX0VRKGZyb20uR2V0RGVzY3JpcHRvcigpLCBkZXNjcmlwdG9yKQorICAgIDw8ICI6IFRyaWVkIHRvIG1lcmdlIGZyb20gYSBtZXNzYWdlIHdpdGggYSBkaWZmZXJlbnQgdHlwZS4gICIKKyAgICAgICAidG86ICIgPDwgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgPDwgIiwgIgorICAgICAgICJmcm9tOiIgPDwgZnJvbS5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpOworICBSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKK30KKwordm9pZCBNZXNzYWdlOjpDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgTWVzc2FnZUxpdGUmIG90aGVyKSB7CisgIE1lcmdlRnJvbSgqZG93bl9jYXN0PGNvbnN0IE1lc3NhZ2UqPigmb3RoZXIpKTsKK30KKwordm9pZCBNZXNzYWdlOjpDb3B5RnJvbShjb25zdCBNZXNzYWdlJiBmcm9tKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBHZXREZXNjcmlwdG9yKCk7CisgIEdPT0dMRV9DSEVDS19FUShmcm9tLkdldERlc2NyaXB0b3IoKSwgZGVzY3JpcHRvcikKKyAgICA8PCAiOiBUcmllZCB0byBjb3B5IGZyb20gYSBtZXNzYWdlIHdpdGggYSBkaWZmZXJlbnQgdHlwZS4gIgorICAgICAgICJ0bzogIiA8PCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSA8PCAiLCAiCisgICAgICAgImZyb206IiA8PCBmcm9tLkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCk7CisgIFJlZmxlY3Rpb25PcHM6OkNvcHkoZnJvbSwgdGhpcyk7Cit9CisKK3N0cmluZyBNZXNzYWdlOjpHZXRUeXBlTmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCk7Cit9CisKK3ZvaWQgTWVzc2FnZTo6Q2xlYXIoKSB7CisgIFJlZmxlY3Rpb25PcHM6OkNsZWFyKHRoaXMpOworfQorCitib29sIE1lc3NhZ2U6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisgIHJldHVybiBSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKCp0aGlzKTsKK30KKwordm9pZCBNZXNzYWdlOjpGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnModmVjdG9yPHN0cmluZz4qIGVycm9ycykgY29uc3QgeworICByZXR1cm4gUmVmbGVjdGlvbk9wczo6RmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCp0aGlzLCAiIiwgZXJyb3JzKTsKK30KKworc3RyaW5nIE1lc3NhZ2U6OkluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSBjb25zdCB7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCZlcnJvcnMpOworICByZXR1cm4gSm9pbihlcnJvcnMsICIsICIpOworfQorCit2b2lkIE1lc3NhZ2U6OkNoZWNrSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDSyhJc0luaXRpYWxpemVkKCkpCisgICAgPDwgIk1lc3NhZ2Ugb2YgdHlwZSBcIiIgPDwgR2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIiBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogIiA8PCBJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nKCk7Cit9CisKK3ZvaWQgTWVzc2FnZTo6RGlzY2FyZFVua25vd25GaWVsZHMoKSB7CisgIHJldHVybiBSZWZsZWN0aW9uT3BzOjpEaXNjYXJkVW5rbm93bkZpZWxkcyh0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIHJldHVybiBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbChpbnB1dCwgdGhpcyk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6UGFyc2VGcm9tRmlsZURlc2NyaXB0b3IoaW50IGZpbGVfZGVzY3JpcHRvcikgeworICBpbzo6RmlsZUlucHV0U3RyZWFtIGlucHV0KGZpbGVfZGVzY3JpcHRvcik7CisgIHJldHVybiBQYXJzZUZyb21aZXJvQ29weVN0cmVhbSgmaW5wdXQpICYmIGlucHV0LkdldEVycm5vKCkgPT0gMDsKK30KKworYm9vbCBNZXNzYWdlOjpQYXJzZVBhcnRpYWxGcm9tRmlsZURlc2NyaXB0b3IoaW50IGZpbGVfZGVzY3JpcHRvcikgeworICBpbzo6RmlsZUlucHV0U3RyZWFtIGlucHV0KGZpbGVfZGVzY3JpcHRvcik7CisgIHJldHVybiBQYXJzZVBhcnRpYWxGcm9tWmVyb0NvcHlTdHJlYW0oJmlucHV0KSAmJiBpbnB1dC5HZXRFcnJubygpID09IDA7Cit9CisKK2Jvb2wgTWVzc2FnZTo6UGFyc2VGcm9tSXN0cmVhbShpc3RyZWFtKiBpbnB1dCkgeworICBpbzo6SXN0cmVhbUlucHV0U3RyZWFtIHplcm9fY29weV9pbnB1dChpbnB1dCk7CisgIHJldHVybiBQYXJzZUZyb21aZXJvQ29weVN0cmVhbSgmemVyb19jb3B5X2lucHV0KSAmJiBpbnB1dC0+ZW9mKCk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6UGFyc2VQYXJ0aWFsRnJvbUlzdHJlYW0oaXN0cmVhbSogaW5wdXQpIHsKKyAgaW86OklzdHJlYW1JbnB1dFN0cmVhbSB6ZXJvX2NvcHlfaW5wdXQoaW5wdXQpOworICByZXR1cm4gUGFyc2VQYXJ0aWFsRnJvbVplcm9Db3B5U3RyZWFtKCZ6ZXJvX2NvcHlfaW5wdXQpICYmIGlucHV0LT5lb2YoKTsKK30KKworCit2b2lkIE1lc3NhZ2U6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBXaXJlRm9ybWF0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKnRoaXMsIEdldENhY2hlZFNpemUoKSwgb3V0cHV0KTsKK30KKworaW50IE1lc3NhZ2U6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgc2l6ZSA9IFdpcmVGb3JtYXQ6OkJ5dGVTaXplKCp0aGlzKTsKKyAgU2V0Q2FjaGVkU2l6ZShzaXplKTsKKyAgcmV0dXJuIHNpemU7Cit9CisKK3ZvaWQgTWVzc2FnZTo6U2V0Q2FjaGVkU2l6ZShpbnQgLyogc2l6ZSAqLykgY29uc3QgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTWVzc2FnZSBjbGFzcyBcIiIgPDwgR2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgICAgICAgICAgIDw8ICJcIiBpbXBsZW1lbnRzIG5laXRoZXIgU2V0Q2FjaGVkU2l6ZSgpIG5vciBCeXRlU2l6ZSgpLiAgIgorICAgICAgICAgICAgICAgICJNdXN0IGltcGxlbWVudCBvbmUgb3IgdGhlIG90aGVyLiI7Cit9CisKK2ludCBNZXNzYWdlOjpTcGFjZVVzZWQoKSBjb25zdCB7CisgIHJldHVybiBHZXRSZWZsZWN0aW9uKCktPlNwYWNlVXNlZCgqdGhpcyk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6U2VyaWFsaXplVG9GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dHB1dChmaWxlX2Rlc2NyaXB0b3IpOworICByZXR1cm4gU2VyaWFsaXplVG9aZXJvQ29weVN0cmVhbSgmb3V0cHV0KTsKK30KKworYm9vbCBNZXNzYWdlOjpTZXJpYWxpemVQYXJ0aWFsVG9GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dHB1dChmaWxlX2Rlc2NyaXB0b3IpOworICByZXR1cm4gU2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oJm91dHB1dCk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6U2VyaWFsaXplVG9Pc3RyZWFtKG9zdHJlYW0qIG91dHB1dCkgY29uc3QgeworICB7CisgICAgaW86Ok9zdHJlYW1PdXRwdXRTdHJlYW0gemVyb19jb3B5X291dHB1dChvdXRwdXQpOworICAgIGlmICghU2VyaWFsaXplVG9aZXJvQ29weVN0cmVhbSgmemVyb19jb3B5X291dHB1dCkpIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gb3V0cHV0LT5nb29kKCk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6U2VyaWFsaXplUGFydGlhbFRvT3N0cmVhbShvc3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaW86Ok9zdHJlYW1PdXRwdXRTdHJlYW0gemVyb19jb3B5X291dHB1dChvdXRwdXQpOworICByZXR1cm4gU2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oJnplcm9fY29weV9vdXRwdXQpOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBSZWZsZWN0aW9uIGFuZCBhc3NvY2lhdGVkIFRlbXBsYXRlIFNwZWNpYWxpemF0aW9ucworCitSZWZsZWN0aW9uOjp+UmVmbGVjdGlvbigpIHt9CisKKyNkZWZpbmUgSEFORExFX1RZUEUoVFlQRSwgQ1BQVFlQRSwgQ1RZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRGaWVsZDxUWVBFPiggICAgICAgIFwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7ICAgICBcCisgIHJldHVybiAqc3RhdGljX2Nhc3Q8UmVwZWF0ZWRGaWVsZDxUWVBFPiogPiggICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoY29uc3RfY2FzdDxNZXNzYWdlKj4oJm1lc3NhZ2UpLCAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQsIENQUFRZUEUsIENUWVBFLCBOVUxMKSk7ICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK3RlbXBsYXRlPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitSZXBlYXRlZEZpZWxkPFRZUEU+KiBSZWZsZWN0aW9uOjpNdXRhYmxlUmVwZWF0ZWRGaWVsZDxUWVBFPiggICAgICAgICAgXAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsgICAgICAgICAgIFwKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFJlcGVhdGVkRmllbGQ8VFlQRT4qID4oICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChtZXNzYWdlLCBmaWVsZCwgQ1BQVFlQRSwgQ1RZUEUsIE5VTEwpKTsgXAorfQorCitIQU5ETEVfVFlQRShpbnQzMiwgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMiwgIC0xKTsKK0hBTkRMRV9UWVBFKGludDY0LCAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0LCAgLTEpOworSEFORExFX1RZUEUodWludDMyLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyLCAtMSk7CitIQU5ETEVfVFlQRSh1aW50NjQsIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQsIC0xKTsKK0hBTkRMRV9UWVBFKGZsb2F0LCAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FULCAgLTEpOworSEFORExFX1RZUEUoZG91YmxlLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFLCAtMSk7CitIQU5ETEVfVFlQRShib29sLCAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MLCAgIC0xKTsKKworCisjdW5kZWYgSEFORExFX1RZUEUKKwordm9pZCogUmVmbGVjdGlvbjo6TXV0YWJsZVJhd1JlcGVhdGVkU3RyaW5nKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgaXNfc3RyaW5nKSBjb25zdCB7CisgIHJldHVybiBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChtZXNzYWdlLCBmaWVsZCwKKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcsIEZpZWxkT3B0aW9uczo6U1RSSU5HLCBOVUxMKTsKK30KKworCisvLyBEZWZhdWx0IEVudW1WYWx1ZSBBUEkgaW1wbGVtZW50YXRpb25zLiBSZWFsIHJlZmxlY3Rpb24gaW1wbGVtZW50YXRpb25zIHNob3VsZAorLy8gb3ZlcnJpZGUgdGhlc2UuIEhvd2V2ZXIsIHRoZXJlIGFyZSBzZXZlcmFsIGxlZ2FjeSBpbXBsZW1lbnRhdGlvbnMgdGhhdCBkbworLy8gbm90LCBhbmQgY2Fubm90IGVhc2lseSBiZSBjaGFuZ2VkIGF0IHRoZSBzYW1lIHRpbWUgYXMgdGhlIFJlZmxlY3Rpb24gQVBJLCBzbworLy8gd2UgcHJvdmlkZSB0aGVzZSBmb3Igbm93LgorLy8gVE9ETzogUmVtb3ZlIHRoZXNlIG9uY2UgYWxsIFJlZmxlY3Rpb24gaW1wbGVtZW50YXRpb25zIGFyZSB1cGRhdGVkLgoraW50IFJlZmxlY3Rpb246OkdldEVudW1WYWx1ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIEVudW1WYWx1ZSBBUEkuIjsKKyAgcmV0dXJuIDA7Cit9Cit2b2lkIFJlZmxlY3Rpb246OlNldEVudW1WYWx1ZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSkgY29uc3QgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5pbXBsZW1lbnRlZCBFbnVtVmFsdWUgQVBJLiI7Cit9CitpbnQgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRFbnVtVmFsdWUoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgRW51bVZhbHVlIEFQSS4iOworICByZXR1cm4gMDsKK30KK3ZvaWQgUmVmbGVjdGlvbjo6U2V0UmVwZWF0ZWRFbnVtVmFsdWUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIEVudW1WYWx1ZSBBUEkuIjsKK30KK3ZvaWQgUmVmbGVjdGlvbjo6QWRkRW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIEVudW1WYWx1ZSBBUEkuIjsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIE1lc3NhZ2VGYWN0b3J5CisKK01lc3NhZ2VGYWN0b3J5Ojp+TWVzc2FnZUZhY3RvcnkoKSB7fQorCituYW1lc3BhY2UgeworCitjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSA6IHB1YmxpYyBNZXNzYWdlRmFjdG9yeSB7CisgcHVibGljOgorICBHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSgpOworICB+R2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkoKTsKKworICBzdGF0aWMgR2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkqIHNpbmdsZXRvbigpOworCisgIHR5cGVkZWYgdm9pZCBSZWdpc3RyYXRpb25GdW5jKGNvbnN0IHN0cmluZyYpOworICB2b2lkIFJlZ2lzdGVyRmlsZShjb25zdCBjaGFyKiBmaWxlLCBSZWdpc3RyYXRpb25GdW5jKiByZWdpc3RyYXRpb25fZnVuYyk7CisgIHZvaWQgUmVnaXN0ZXJUeXBlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZSk7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlRmFjdG9yeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgY29uc3QgTWVzc2FnZSogR2V0UHJvdG90eXBlKGNvbnN0IERlc2NyaXB0b3IqIHR5cGUpOworCisgcHJpdmF0ZToKKyAgLy8gT25seSB3cml0dGVuIGF0IHN0YXRpYyBpbml0IHRpbWUsIHNvIGRvZXMgbm90IHJlcXVpcmUgbG9ja2luZy4KKyAgaGFzaF9tYXA8Y29uc3QgY2hhciosIFJlZ2lzdHJhdGlvbkZ1bmMqLAorICAgICAgICAgICBoYXNoPGNvbnN0IGNoYXIqPiwgc3RyZXE+IGZpbGVfbWFwXzsKKworICAvLyBJbml0aWFsaXplZCBsYXppbHksIHNvIHJlcXVpcmVzIGxvY2tpbmcuCisgIE11dGV4IG11dGV4XzsKKyAgaGFzaF9tYXA8Y29uc3QgRGVzY3JpcHRvciosIGNvbnN0IE1lc3NhZ2UqPiB0eXBlX21hcF87Cit9OworCitHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSogZ2VuZXJhdGVkX21lc3NhZ2VfZmFjdG9yeV8gPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShnZW5lcmF0ZWRfbWVzc2FnZV9mYWN0b3J5X29uY2VfaW5pdF8pOworCit2b2lkIFNodXRkb3duR2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkoKSB7CisgIGRlbGV0ZSBnZW5lcmF0ZWRfbWVzc2FnZV9mYWN0b3J5XzsKK30KKwordm9pZCBJbml0R2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkoKSB7CisgIGdlbmVyYXRlZF9tZXNzYWdlX2ZhY3RvcnlfID0gbmV3IEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OworICBpbnRlcm5hbDo6T25TaHV0ZG93bigmU2h1dGRvd25HZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSk7Cit9CisKK0dlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSgpIHt9CitHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeTo6fkdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5KCkge30KKworR2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkqIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpzaW5nbGV0b24oKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmdlbmVyYXRlZF9tZXNzYWdlX2ZhY3Rvcnlfb25jZV9pbml0XywKKyAgICAgICAgICAgICAgICAgJkluaXRHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSk7CisgIHJldHVybiBnZW5lcmF0ZWRfbWVzc2FnZV9mYWN0b3J5XzsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeTo6UmVnaXN0ZXJGaWxlKAorICAgIGNvbnN0IGNoYXIqIGZpbGUsIFJlZ2lzdHJhdGlvbkZ1bmMqIHJlZ2lzdHJhdGlvbl9mdW5jKSB7CisgIGlmICghSW5zZXJ0SWZOb3RQcmVzZW50KCZmaWxlX21hcF8sIGZpbGUsIHJlZ2lzdHJhdGlvbl9mdW5jKSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJGaWxlIGlzIGFscmVhZHkgcmVnaXN0ZXJlZDogIiA8PCBmaWxlOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OlJlZ2lzdGVyVHlwZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZSkgeworICBHT09HTEVfRENIRUNLX0VRKGRlc2NyaXB0b3ItPmZpbGUoKS0+cG9vbCgpLCBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkKKyAgICA8PCAiVHJpZWQgdG8gcmVnaXN0ZXIgYSBub24tZ2VuZXJhdGVkIHR5cGUgd2l0aCB0aGUgZ2VuZXJhdGVkICIKKyAgICAgICAidHlwZSByZWdpc3RyeS4iOworCisgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGFzIGEgcmVzdWx0IG9mIGNhbGxpbmcgYSBmaWxlIHJlZ2lzdHJhdGlvbgorICAvLyBmdW5jdGlvbiBkdXJpbmcgR2V0UHJvdG90eXBlKCksIGluIHdoaWNoIGNhc2Ugd2UgYWxyZWFkeSBoYXZlIGxvY2tlZAorICAvLyB0aGUgbXV0ZXguCisgIG11dGV4Xy5Bc3NlcnRIZWxkKCk7CisgIGlmICghSW5zZXJ0SWZOb3RQcmVzZW50KCZ0eXBlX21hcF8sIGRlc2NyaXB0b3IsIHByb3RvdHlwZSkpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIlR5cGUgaXMgYWxyZWFkeSByZWdpc3RlcmVkOiAiIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpOworICB9Cit9CisKKworY29uc3QgTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OkdldFByb3RvdHlwZShjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSB7CisgIHsKKyAgICBSZWFkZXJNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKyAgICBjb25zdCBNZXNzYWdlKiByZXN1bHQgPSBGaW5kUHRyT3JOdWxsKHR5cGVfbWFwXywgdHlwZSk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gSWYgdGhlIHR5cGUgaXMgbm90IGluIHRoZSBnZW5lcmF0ZWQgcG9vbCwgdGhlbiB3ZSBjYW4ndCBwb3NzaWJseSBoYW5kbGUKKyAgLy8gaXQuCisgIGlmICh0eXBlLT5maWxlKCktPnBvb2woKSAhPSBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkgcmV0dXJuIE5VTEw7CisKKyAgLy8gQXBwYXJlbnRseSB0aGUgZmlsZSBoYXNuJ3QgYmVlbiByZWdpc3RlcmVkIHlldC4gIExldCdzIGRvIHRoYXQgbm93LgorICBSZWdpc3RyYXRpb25GdW5jKiByZWdpc3RyYXRpb25fZnVuYyA9CisgICAgICBGaW5kUHRyT3JOdWxsKGZpbGVfbWFwXywgdHlwZS0+ZmlsZSgpLT5uYW1lKCkuY19zdHIoKSk7CisgIGlmIChyZWdpc3RyYXRpb25fZnVuYyA9PSBOVUxMKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJGaWxlIGFwcGVhcnMgdG8gYmUgaW4gZ2VuZXJhdGVkIHBvb2wgYnV0IHdhc24ndCAiCisgICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyZWQ6ICIgPDwgdHlwZS0+ZmlsZSgpLT5uYW1lKCk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBXcml0ZXJNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKworICAvLyBDaGVjayBpZiBhbm90aGVyIHRocmVhZCBwcmVlbXB0ZWQgdXMuCisgIGNvbnN0IE1lc3NhZ2UqIHJlc3VsdCA9IEZpbmRQdHJPck51bGwodHlwZV9tYXBfLCB0eXBlKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgLy8gTm9wZS4gIE9LLCByZWdpc3RlciBldmVyeXRoaW5nLgorICAgIHJlZ2lzdHJhdGlvbl9mdW5jKHR5cGUtPmZpbGUoKS0+bmFtZSgpKTsKKyAgICAvLyBTaG91bGQgYmUgaGVyZSBub3cuCisgICAgcmVzdWx0ID0gRmluZFB0ck9yTnVsbCh0eXBlX21hcF8sIHR5cGUpOworICB9CisKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJUeXBlIGFwcGVhcnMgdG8gYmUgaW4gZ2VuZXJhdGVkIHBvb2wgYnV0IHdhc24ndCAiCisgICAgICAgICAgICAgICAgPDwgInJlZ2lzdGVyZWQ6ICIgPDwgdHlwZS0+ZnVsbF9uYW1lKCk7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UKKworTWVzc2FnZUZhY3RvcnkqIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpIHsKKyAgcmV0dXJuIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpzaW5nbGV0b24oKTsKK30KKwordm9pZCBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgY29uc3QgY2hhciogZmlsZW5hbWUsIHZvaWQgKCpyZWdpc3Rlcl9tZXNzYWdlcykoY29uc3Qgc3RyaW5nJikpIHsKKyAgR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OnNpbmdsZXRvbigpLT5SZWdpc3RlckZpbGUoZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyX21lc3NhZ2VzKTsKK30KKwordm9pZCBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgTWVzc2FnZSogcHJvdG90eXBlKSB7CisgIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpzaW5nbGV0b24oKS0+UmVnaXN0ZXJUeXBlKGRlc2NyaXB0b3IsIHByb3RvdHlwZSk7Cit9CisKKworTWVzc2FnZUZhY3RvcnkqIFJlZmxlY3Rpb246OkdldE1lc3NhZ2VGYWN0b3J5KCkgY29uc3QgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm90IGltcGxlbWVudGVkLiI7CisgIHJldHVybiBOVUxMOworfQorCit2b2lkKiBSZWZsZWN0aW9uOjpSZXBlYXRlZEZpZWxkRGF0YSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSwKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUpIGNvbnN0IHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vdCBpbXBsZW1lbnRlZC4iOworICByZXR1cm4gTlVMTDsKK30KKworbmFtZXNwYWNlIGludGVybmFsIHsKK1JlcGVhdGVkRmllbGRBY2Nlc3Nvcjo6flJlcGVhdGVkRmllbGRBY2Nlc3NvcigpIHsKK30KK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCitjb25zdCBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBSZWZsZWN0aW9uOjpSZXBlYXRlZEZpZWxkQWNjZXNzb3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soZmllbGQtPmlzX3JlcGVhdGVkKCkpOworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9QUklNSVRJVkVfVFlQRShUWVBFLCB0eXBlKSBcCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfICMjIFRZUEU6IFwKKyAgICAgIHJldHVybiBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8dHlwZT4gPjo6Z2V0KCk7CisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKElOVDMyLCBpbnQzMikKKyAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoVUlOVDMyLCB1aW50MzIpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKElOVDY0LCBpbnQ2NCkKKyAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoVUlOVDY0LCB1aW50NjQpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEZMT0FULCBmbG9hdCkKKyAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoRE9VQkxFLCBkb3VibGUpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEJPT0wsIGJvb2wpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEVOVU0sIGludDMyKQorI3VuZGVmIEhBTkRMRV9QUklNSVRJVkVfVFlQRQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgcmV0dXJuIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6OlJlcGVhdGVkUHRyRmllbGRTdHJpbmdBY2Nlc3Nvcj46OmdldCgpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIGlmIChmaWVsZC0+aXNfbWFwKCkpIHsKKyAgICAgICAgcmV0dXJuIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6Ok1hcEZpZWxkQWNjZXNzb3I+OjpnZXQoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkTWVzc2FnZUFjY2Vzc29yPjo6Z2V0KCk7CisgICAgICB9CisgIH0KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlNob3VsZCBub3QgcmVhY2ggaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7Cit2b2lkIFNodXRkb3duUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKCkgeworICBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8aW50MzI+ID46OlNodXREb3duKCk7CisgIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6OlJlcGVhdGVkRmllbGRQcmltaXRpdmVBY2Nlc3Nvcjx1aW50MzI+ID46OlNodXREb3duKCk7CisgIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6OlJlcGVhdGVkRmllbGRQcmltaXRpdmVBY2Nlc3NvcjxpbnQ2ND4gPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yPHVpbnQ2ND4gPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yPGZsb2F0PiA+OjpTaHV0RG93bigpOworICBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8ZG91YmxlPiA+OjpTaHV0RG93bigpOworICBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8Ym9vbD4gPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZFN0cmluZ0FjY2Vzc29yPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZE1lc3NhZ2VBY2Nlc3Nvcj46OlNodXREb3duKCk7CisgIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6Ok1hcEZpZWxkQWNjZXNzb3I+OjpTaHV0RG93bigpOworfQorCitzdHJ1Y3QgU2h1dGRvd25SZXBlYXRlZEZpZWxkUmVnaXN0ZXIgeworICBTaHV0ZG93blJlcGVhdGVkRmllbGRSZWdpc3RlcigpIHsKKyAgICBPblNodXRkb3duKCZTaHV0ZG93blJlcGVhdGVkRmllbGRBY2Nlc3Nvcik7CisgIH0KK30gc2h1dGRvd25fOworCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCituYW1lc3BhY2UgaW50ZXJuYWwgeworLy8gTWFjcm8gZGVmaW5lZCBpbiByZXBlYXRlZF9maWVsZC5oLiBXZSBjYW4gb25seSBkZWZpbmUgdGhlIE1lc3NhZ2Utc3BlY2lmaWMKKy8vIEdlbmVyaWNUeXBlSGFuZGxlciBzcGVjaWFsaXphdGlvbnMgaGVyZSBiZWNhdXNlIHdlIGRlcGVuZCBvbiBNZXNzYWdlLCB3aGljaAorLy8gaXMgbm90IHBhcnQgb2YgcHJvdG8yLWxpdGUgaGVuY2UgaXMgbm90IGF2YWlsYWJsZSBpbiByZXBlYXRlZF9maWVsZC5oLgorREVGSU5FX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9QUk9UT19UWVBFU19OT0lOTElORShNZXNzYWdlKTsKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmUxOTI5ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oCkBAIC0wLDAgKzEsMTA1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIERlZmluZXMgTWVzc2FnZSwgdGhlIGFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBub24tbGl0ZQorLy8gcHJvdG9jb2wgbWVzc2FnZSBvYmplY3RzLiAgQWx0aG91Z2ggaXQncyBwb3NzaWJsZSB0byBpbXBsZW1lbnQgdGhpcworLy8gaW50ZXJmYWNlIG1hbnVhbGx5LCBtb3N0IHVzZXJzIHdpbGwgdXNlIHRoZSBwcm90b2NvbCBjb21waWxlciB0bworLy8gZ2VuZXJhdGUgaW1wbGVtZW50YXRpb25zLgorLy8KKy8vIEV4YW1wbGUgdXNhZ2U6CisvLworLy8gU2F5IHlvdSBoYXZlIGEgbWVzc2FnZSBkZWZpbmVkIGFzOgorLy8KKy8vICAgbWVzc2FnZSBGb28geworLy8gICAgIG9wdGlvbmFsIHN0cmluZyB0ZXh0ID0gMTsKKy8vICAgICByZXBlYXRlZCBpbnQzMiBudW1iZXJzID0gMjsKKy8vICAgfQorLy8KKy8vIFRoZW4sIGlmIHlvdSB1c2VkIHRoZSBwcm90b2NvbCBjb21waWxlciB0byBnZW5lcmF0ZSBhIGNsYXNzIGZyb20gdGhlIGFib3ZlCisvLyBkZWZpbml0aW9uLCB5b3UgY291bGQgdXNlIGl0IGxpa2Ugc286CisvLworLy8gICBzdHJpbmcgZGF0YTsgIC8vIFdpbGwgc3RvcmUgYSBzZXJpYWxpemVkIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UuCisvLworLy8gICB7CisvLyAgICAgLy8gQ3JlYXRlIGEgbWVzc2FnZSBhbmQgc2VyaWFsaXplIGl0LgorLy8gICAgIEZvbyBmb287CisvLyAgICAgZm9vLnNldF90ZXh0KCJIZWxsbyBXb3JsZCEiKTsKKy8vICAgICBmb28uYWRkX251bWJlcnMoMSk7CisvLyAgICAgZm9vLmFkZF9udW1iZXJzKDUpOworLy8gICAgIGZvby5hZGRfbnVtYmVycyg0Mik7CisvLworLy8gICAgIGZvby5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisvLyAgIH0KKy8vCisvLyAgIHsKKy8vICAgICAvLyBQYXJzZSB0aGUgc2VyaWFsaXplZCBtZXNzYWdlIGFuZCBjaGVjayB0aGF0IGl0IGNvbnRhaW5zIHRoZQorLy8gICAgIC8vIGNvcnJlY3QgZGF0YS4KKy8vICAgICBGb28gZm9vOworLy8gICAgIGZvby5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisvLworLy8gICAgIGFzc2VydChmb28udGV4dCgpID09ICJIZWxsbyBXb3JsZCEiKTsKKy8vICAgICBhc3NlcnQoZm9vLm51bWJlcnNfc2l6ZSgpID09IDMpOworLy8gICAgIGFzc2VydChmb28ubnVtYmVycygwKSA9PSAxKTsKKy8vICAgICBhc3NlcnQoZm9vLm51bWJlcnMoMSkgPT0gNSk7CisvLyAgICAgYXNzZXJ0KGZvby5udW1iZXJzKDIpID09IDQyKTsKKy8vICAgfQorLy8KKy8vICAgeworLy8gICAgIC8vIFNhbWUgYXMgdGhlIGxhc3QgYmxvY2ssIGJ1dCBkbyBpdCBkeW5hbWljYWxseSB2aWEgdGhlIE1lc3NhZ2UKKy8vICAgICAvLyByZWZsZWN0aW9uIGludGVyZmFjZS4KKy8vICAgICBNZXNzYWdlKiBmb28gPSBuZXcgRm9vOworLy8gICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBmb28tPkdldERlc2NyaXB0b3IoKTsKKy8vCisvLyAgICAgLy8gR2V0IHRoZSBkZXNjcmlwdG9ycyBmb3IgdGhlIGZpZWxkcyB3ZSdyZSBpbnRlcmVzdGVkIGluIGFuZCB2ZXJpZnkKKy8vICAgICAvLyB0aGVpciB0eXBlcy4KKy8vICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHRleHRfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoInRleHQiKTsKKy8vICAgICBhc3NlcnQodGV4dF9maWVsZCAhPSBOVUxMKTsKKy8vICAgICBhc3NlcnQodGV4dF9maWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpOworLy8gICAgIGFzc2VydCh0ZXh0X2ZpZWxkLT5sYWJlbCgpID09IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwpOworLy8gICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbnVtYmVyc19maWVsZCA9IGRlc2NyaXB0b3ItPgorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbmRGaWVsZEJ5TmFtZSgibnVtYmVycyIpOworLy8gICAgIGFzc2VydChudW1iZXJzX2ZpZWxkICE9IE5VTEwpOworLy8gICAgIGFzc2VydChudW1iZXJzX2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyKTsKKy8vICAgICBhc3NlcnQobnVtYmVyc19maWVsZC0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKTsKKy8vCisvLyAgICAgLy8gUGFyc2UgdGhlIG1lc3NhZ2UuCisvLyAgICAgZm9vLT5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisvLworLy8gICAgIC8vIFVzZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UgdG8gZXhhbWluZSB0aGUgY29udGVudHMuCisvLyAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IGZvby0+R2V0UmVmbGVjdGlvbigpOworLy8gICAgIGFzc2VydChyZWZsZWN0aW9uLT5HZXRTdHJpbmcoZm9vLCB0ZXh0X2ZpZWxkKSA9PSAiSGVsbG8gV29ybGQhIik7CisvLyAgICAgYXNzZXJ0KHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShmb28sIG51bWJlcnNfZmllbGQpID09IDMpOworLy8gICAgIGFzc2VydChyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyKGZvbywgbnVtYmVyc19maWVsZCwgMCkgPT0gMSk7CisvLyAgICAgYXNzZXJ0KHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIoZm9vLCBudW1iZXJzX2ZpZWxkLCAxKSA9PSA1KTsKKy8vICAgICBhc3NlcnQocmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMihmb28sIG51bWJlcnNfZmllbGQsIDIpID09IDQyKTsKKy8vCisvLyAgICAgZGVsZXRlIGZvbzsKKy8vICAgfQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NRVNTQUdFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUVTU0FHRV9IX18KKworI2luY2x1ZGUgPGlvc2Z3ZD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmg+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKKworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTX09ORU9GCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNfQVJFTkFTCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBNZXNzYWdlOworY2xhc3MgUmVmbGVjdGlvbjsKK2NsYXNzIE1lc3NhZ2VGYWN0b3J5OworCisvLyBEZWZpbmVkIGluIG90aGVyIGZpbGVzLgorY2xhc3MgVW5rbm93bkZpZWxkU2V0OyAgICAgICAgIC8vIHVua25vd25fZmllbGRfc2V0LmgKK25hbWVzcGFjZSBpbyB7CisgIGNsYXNzIFplcm9Db3B5SW5wdXRTdHJlYW07ICAgLy8gemVyb19jb3B5X3N0cmVhbS5oCisgIGNsYXNzIFplcm9Db3B5T3V0cHV0U3RyZWFtOyAgLy8gemVyb19jb3B5X3N0cmVhbS5oCisgIGNsYXNzIENvZGVkSW5wdXRTdHJlYW07ICAgICAgLy8gY29kZWRfc3RyZWFtLmgKKyAgY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07ICAgICAvLyBjb2RlZF9zdHJlYW0uaAorfQorCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkOyAgICAgLy8gcmVwZWF0ZWRfZmllbGQuaAorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZDsgIC8vIHJlcGVhdGVkX2ZpZWxkLmgKKworLy8gQSBjb250YWluZXIgdG8gaG9sZCBtZXNzYWdlIG1ldGFkYXRhLgorc3RydWN0IE1ldGFkYXRhIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcjsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbjsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgcHJvdG9jb2wgbWVzc2FnZXMuCisvLworLy8gU2VlIGFsc28gTWVzc2FnZUxpdGUsIHdoaWNoIGNvbnRhaW5zIG1vc3QgZXZlcnktZGF5IG9wZXJhdGlvbnMuICBNZXNzYWdlCisvLyBhZGRzIGRlc2NyaXB0b3JzIGFuZCByZWZsZWN0aW9uIG9uIHRvcCBvZiB0aGF0LgorLy8KKy8vIFRoZSBtZXRob2RzIG9mIHRoaXMgY2xhc3MgdGhhdCBhcmUgdmlydHVhbCBidXQgbm90IHB1cmUtdmlydHVhbCBoYXZlCisvLyBkZWZhdWx0IGltcGxlbWVudGF0aW9ucyBiYXNlZCBvbiByZWZsZWN0aW9uLiAgTWVzc2FnZSBjbGFzc2VzIHdoaWNoIGFyZQorLy8gb3B0aW1pemVkIGZvciBzcGVlZCB3aWxsIHdhbnQgdG8gb3ZlcnJpZGUgdGhlc2Ugd2l0aCBmYXN0ZXIgaW1wbGVtZW50YXRpb25zLAorLy8gYnV0IGNsYXNzZXMgb3B0aW1pemVkIGZvciBjb2RlIHNpemUgbWF5IGJlIGhhcHB5IHdpdGgga2VlcGluZyB0aGVtLiAgU2VlCisvLyB0aGUgb3B0aW1pemVfZm9yIG9wdGlvbiBpbiBkZXNjcmlwdG9yLnByb3RvLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1lc3NhZ2UgOiBwdWJsaWMgTWVzc2FnZUxpdGUgeworIHB1YmxpYzoKKyAgaW5saW5lIE1lc3NhZ2UoKSB7fQorICB2aXJ0dWFsIH5NZXNzYWdlKCk7CisKKyAgLy8gQmFzaWMgT3BlcmF0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHNhbWUgdHlwZS4gIE93bmVyc2hpcCBpcyBwYXNzZWQgdG8gdGhlCisgIC8vIGNhbGxlci4gIChUaGlzIGlzIGFsc28gZGVmaW5lZCBpbiBNZXNzYWdlTGl0ZSwgYnV0IGlzIGRlZmluZWQgYWdhaW4gaGVyZQorICAvLyBmb3IgcmV0dXJuLXR5cGUgY292YXJpYW5jZS4pCisgIHZpcnR1YWwgTWVzc2FnZSogTmV3KCkgY29uc3QgPSAwOworCisgIC8vIENvbnN0cnVjdCBhIG5ldyBpbnN0YW5jZSBvbiB0aGUgYXJlbmEuIE93bmVyc2hpcCBpcyBwYXNzZWQgdG8gdGhlIGNhbGxlcgorICAvLyBpZiBhcmVuYSBpcyBhIE5VTEwuIERlZmF1bHQgaW1wbGVtZW50YXRpb24gYWxsb3dzIGZvciBBUEkgY29tcGF0aWJpbGl0eQorICAvLyBkdXJpbmcgdGhlIEFyZW5hIHRyYW5zaXRpb24uCisgIHZpcnR1YWwgTWVzc2FnZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgICAgTWVzc2FnZSogbWVzc2FnZSA9IE5ldygpOworICAgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgICBhcmVuYS0+T3duKG1lc3NhZ2UpOworICAgIH0KKyAgICByZXR1cm4gbWVzc2FnZTsKKyAgfQorCisgIC8vIE1ha2UgdGhpcyBtZXNzYWdlIGludG8gYSBjb3B5IG9mIHRoZSBnaXZlbiBtZXNzYWdlLiAgVGhlIGdpdmVuIG1lc3NhZ2UKKyAgLy8gbXVzdCBoYXZlIHRoZSBzYW1lIGRlc2NyaXB0b3IsIGJ1dCBuZWVkIG5vdCBuZWNlc3NhcmlseSBiZSB0aGUgc2FtZSBjbGFzcy4KKyAgLy8gQnkgZGVmYXVsdCB0aGlzIGlzIGp1c3QgaW1wbGVtZW50ZWQgYXMgIkNsZWFyKCk7IE1lcmdlRnJvbShmcm9tKTsiLgorICB2aXJ0dWFsIHZvaWQgQ29weUZyb20oY29uc3QgTWVzc2FnZSYgZnJvbSk7CisKKyAgLy8gTWVyZ2UgdGhlIGZpZWxkcyBmcm9tIHRoZSBnaXZlbiBtZXNzYWdlIGludG8gdGhpcyBtZXNzYWdlLiAgU2luZ3VsYXIKKyAgLy8gZmllbGRzIHdpbGwgYmUgb3ZlcndyaXR0ZW4sIGlmIHNwZWNpZmllZCBpbiBmcm9tLCBleGNlcHQgZm9yIGVtYmVkZGVkCisgIC8vIG1lc3NhZ2VzIHdoaWNoIHdpbGwgYmUgbWVyZ2VkLiAgUmVwZWF0ZWQgZmllbGRzIHdpbGwgYmUgY29uY2F0ZW5hdGVkLgorICAvLyBUaGUgZ2l2ZW4gbWVzc2FnZSBtdXN0IGJlIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhpcyBtZXNzYWdlIChpLmUuIHRoZQorICAvLyBleGFjdCBzYW1lIGNsYXNzKS4KKyAgdmlydHVhbCB2b2lkIE1lcmdlRnJvbShjb25zdCBNZXNzYWdlJiBmcm9tKTsKKworICAvLyBWZXJpZmllcyB0aGF0IElzSW5pdGlhbGl6ZWQoKSByZXR1cm5zIHRydWUuICBHT09HTEVfQ0hFQ0stZmFpbHMgb3RoZXJ3aXNlLCB3aXRoCisgIC8vIGEgbmljZSBlcnJvciBtZXNzYWdlLgorICB2b2lkIENoZWNrSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICAvLyBTbG93bHkgYnVpbGQgYSBsaXN0IG9mIGFsbCByZXF1aXJlZCBmaWVsZHMgdGhhdCBhcmUgbm90IHNldC4KKyAgLy8gVGhpcyBpcyBtdWNoLCBtdWNoIHNsb3dlciB0aGFuIElzSW5pdGlhbGl6ZWQoKSBhcyBpdCBpcyBpbXBsZW1lbnRlZAorICAvLyBwdXJlbHkgdmlhIHJlZmxlY3Rpb24uICBHZW5lcmFsbHksIHlvdSBzaG91bGQgbm90IGNhbGwgdGhpcyB1bmxlc3MgeW91CisgIC8vIGhhdmUgYWxyZWFkeSBkZXRlcm1pbmVkIHRoYXQgYW4gZXJyb3IgZXhpc3RzIGJ5IGNhbGxpbmcgSXNJbml0aWFsaXplZCgpLgorICB2b2lkIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhzdGQ6OnZlY3RvcjxzdHJpbmc+KiBlcnJvcnMpIGNvbnN0OworCisgIC8vIExpa2UgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzLCBidXQgam9pbnMgYWxsIHRoZSBzdHJpbmdzLCBkZWxpbWl0ZWQgYnkKKyAgLy8gY29tbWFzLCBhbmQgcmV0dXJucyB0aGVtLgorICBzdHJpbmcgSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpIGNvbnN0OworCisgIC8vIENsZWFycyBhbGwgdW5rbm93biBmaWVsZHMgZnJvbSB0aGlzIG1lc3NhZ2UgYW5kIGFsbCBlbWJlZGRlZCBtZXNzYWdlcy4KKyAgLy8gTm9ybWFsbHksIGlmIHVua25vd24gdGFnIG51bWJlcnMgYXJlIGVuY291bnRlcmVkIHdoZW4gcGFyc2luZyBhIG1lc3NhZ2UsCisgIC8vIHRoZSB0YWcgYW5kIHZhbHVlIGFyZSBzdG9yZWQgaW4gdGhlIG1lc3NhZ2UncyBVbmtub3duRmllbGRTZXQgYW5kCisgIC8vIHRoZW4gd3JpdHRlbiBiYWNrIG91dCB3aGVuIHRoZSBtZXNzYWdlIGlzIHNlcmlhbGl6ZWQuICBUaGlzIGFsbG93cyBzZXJ2ZXJzCisgIC8vIHdoaWNoIHNpbXBseSByb3V0ZSBtZXNzYWdlcyB0byBvdGhlciBzZXJ2ZXJzIHRvIHBhc3MgdGhyb3VnaCBtZXNzYWdlcworICAvLyB0aGF0IGhhdmUgbmV3IGZpZWxkIGRlZmluaXRpb25zIHdoaWNoIHRoZXkgZG9uJ3QgeWV0IGtub3cgYWJvdXQuICBIb3dldmVyLAorICAvLyB0aGlzIGJlaGF2aW9yIGNhbiBoYXZlIHNlY3VyaXR5IGltcGxpY2F0aW9ucy4gIFRvIGF2b2lkIGl0LCBjYWxsIHRoaXMKKyAgLy8gbWV0aG9kIGFmdGVyIHBhcnNpbmcuCisgIC8vCisgIC8vIFNlZSBSZWZsZWN0aW9uOjpHZXRVbmtub3duRmllbGRzKCkgZm9yIG1vcmUgb24gdW5rbm93biBmaWVsZHMuCisgIHZpcnR1YWwgdm9pZCBEaXNjYXJkVW5rbm93bkZpZWxkcygpOworCisgIC8vIENvbXB1dGVzIChhbiBlc3RpbWF0ZSBvZikgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyBjdXJyZW50bHkgdXNlZCBmb3IKKyAgLy8gc3RvcmluZyB0aGUgbWVzc2FnZSBpbiBtZW1vcnkuICBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBjYWxscyB0aGUKKyAgLy8gUmVmbGVjdGlvbiBvYmplY3QncyBTcGFjZVVzZWQoKSBtZXRob2QuCisgIHZpcnR1YWwgaW50IFNwYWNlVXNlZCgpIGNvbnN0OworCisgIC8vIERlYnVnZ2luZyAmIFRlc3RpbmctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gR2VuZXJhdGVzIGEgaHVtYW4gcmVhZGFibGUgZm9ybSBvZiB0aGlzIG1lc3NhZ2UsIHVzZWZ1bCBmb3IgZGVidWdnaW5nCisgIC8vIGFuZCBvdGhlciBwdXJwb3Nlcy4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisgIC8vIExpa2UgRGVidWdTdHJpbmcoKSwgYnV0IHdpdGggbGVzcyB3aGl0ZXNwYWNlLgorICBzdHJpbmcgU2hvcnREZWJ1Z1N0cmluZygpIGNvbnN0OworICAvLyBMaWtlIERlYnVnU3RyaW5nKCksIGJ1dCBkbyBub3QgZXNjYXBlIFVURi04IGJ5dGUgc2VxdWVuY2VzLgorICBzdHJpbmcgVXRmOERlYnVnU3RyaW5nKCkgY29uc3Q7CisgIC8vIENvbnZlbmllbmNlIGZ1bmN0aW9uIHVzZWZ1bCBpbiBHREIuICBQcmludHMgRGVidWdTdHJpbmcoKSB0byBzdGRvdXQuCisgIHZvaWQgUHJpbnREZWJ1Z1N0cmluZygpIGNvbnN0OworCisgIC8vIEhlYXZ5IEkvTyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEFkZGl0aW9uYWwgcGFyc2luZyBhbmQgc2VyaWFsaXphdGlvbiBtZXRob2RzIG5vdCBpbXBsZW1lbnRlZCBieQorICAvLyBNZXNzYWdlTGl0ZSBiZWNhdXNlIHRoZXkgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGxpdGUgbGlicmFyeS4KKworICAvLyBQYXJzZSBhIHByb3RvY29sIGJ1ZmZlciBmcm9tIGEgZmlsZSBkZXNjcmlwdG9yLiAgSWYgc3VjY2Vzc2Z1bCwgdGhlIGVudGlyZQorICAvLyBpbnB1dCB3aWxsIGJlIGNvbnN1bWVkLgorICBib29sIFBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKGludCBmaWxlX2Rlc2NyaXB0b3IpOworICAvLyBMaWtlIFBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKCksIGJ1dCBhY2NlcHRzIG1lc3NhZ2VzIHRoYXQgYXJlIG1pc3NpbmcKKyAgLy8gcmVxdWlyZWQgZmllbGRzLgorICBib29sIFBhcnNlUGFydGlhbEZyb21GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKTsKKyAgLy8gUGFyc2UgYSBwcm90b2NvbCBidWZmZXIgZnJvbSBhIEMrKyBpc3RyZWFtLiAgSWYgc3VjY2Vzc2Z1bCwgdGhlIGVudGlyZQorICAvLyBpbnB1dCB3aWxsIGJlIGNvbnN1bWVkLgorICBib29sIFBhcnNlRnJvbUlzdHJlYW0oaXN0cmVhbSogaW5wdXQpOworICAvLyBMaWtlIFBhcnNlRnJvbUlzdHJlYW0oKSwgYnV0IGFjY2VwdHMgbWVzc2FnZXMgdGhhdCBhcmUgbWlzc2luZworICAvLyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgUGFyc2VQYXJ0aWFsRnJvbUlzdHJlYW0oaXN0cmVhbSogaW5wdXQpOworCisgIC8vIFNlcmlhbGl6ZSB0aGUgbWVzc2FnZSBhbmQgd3JpdGUgaXQgdG8gdGhlIGdpdmVuIGZpbGUgZGVzY3JpcHRvci4gIEFsbAorICAvLyByZXF1aXJlZCBmaWVsZHMgbXVzdCBiZSBzZXQuCisgIGJvb2wgU2VyaWFsaXplVG9GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb0ZpbGVEZXNjcmlwdG9yKCksIGJ1dCBhbGxvd3MgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgU2VyaWFsaXplUGFydGlhbFRvRmlsZURlc2NyaXB0b3IoaW50IGZpbGVfZGVzY3JpcHRvcikgY29uc3Q7CisgIC8vIFNlcmlhbGl6ZSB0aGUgbWVzc2FnZSBhbmQgd3JpdGUgaXQgdG8gdGhlIGdpdmVuIEMrKyBvc3RyZWFtLiAgQWxsCisgIC8vIHJlcXVpcmVkIGZpZWxkcyBtdXN0IGJlIHNldC4KKyAgYm9vbCBTZXJpYWxpemVUb09zdHJlYW0ob3N0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb09zdHJlYW0oKSwgYnV0IGFsbG93cyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBTZXJpYWxpemVQYXJ0aWFsVG9Pc3RyZWFtKG9zdHJlYW0qIG91dHB1dCkgY29uc3Q7CisKKworICAvLyBSZWZsZWN0aW9uLWJhc2VkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUaGVzZSBtZXRob2RzIGFyZSBwdXJlLXZpcnR1YWwgaW4gTWVzc2FnZUxpdGUsIGJ1dCBNZXNzYWdlIHByb3ZpZGVzCisgIC8vIHJlZmxlY3Rpb24tYmFzZWQgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMuCisKKyAgdmlydHVhbCBzdHJpbmcgR2V0VHlwZU5hbWUoKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIENsZWFyKCk7CisgIHZpcnR1YWwgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgTWVzc2FnZUxpdGUmIG90aGVyKTsKKyAgdmlydHVhbCBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2aXJ0dWFsIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKworIHByaXZhdGU6CisgIC8vIFRoaXMgaXMgY2FsbGVkIG9ubHkgYnkgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgQnl0ZVNpemUoKSwgdG8KKyAgLy8gdXBkYXRlIHRoZSBjYWNoZWQgc2l6ZS4gIElmIHlvdSBvdmVycmlkZSBCeXRlU2l6ZSgpLCB5b3UgZG8gbm90IG5lZWQKKyAgLy8gdG8gb3ZlcnJpZGUgdGhpcy4gIElmIHlvdSBkbyBub3Qgb3ZlcnJpZGUgQnl0ZVNpemUoKSwgeW91IE1VU1Qgb3ZlcnJpZGUKKyAgLy8gdGhpczsgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd2lsbCBjcmFzaC4KKyAgLy8KKyAgLy8gVGhlIG1ldGhvZCBpcyBwcml2YXRlIGJlY2F1c2Ugc3ViY2xhc3NlcyBzaG91bGQgbmV2ZXIgY2FsbCBpdDsgb25seQorICAvLyBvdmVycmlkZSBpdC4gIFllcywgQysrIGxldHMgeW91IGRvIHRoYXQuICBDcmF6eSwgaHVoPworICB2aXJ0dWFsIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisKKyBwdWJsaWM6CisKKyAgLy8gSW50cm9zcGVjdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBUeXBlZGVmIGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uIFJlZmxlY3Rpb247CisKKyAgLy8gR2V0IGEgRGVzY3JpcHRvciBmb3IgdGhpcyBtZXNzYWdlJ3MgdHlwZS4gIFRoaXMgZGVzY3JpYmVzIHdoYXQKKyAgLy8gZmllbGRzIHRoZSBtZXNzYWdlIGNvbnRhaW5zLCB0aGUgdHlwZXMgb2YgdGhvc2UgZmllbGRzLCBldGMuCisgIGNvbnN0IERlc2NyaXB0b3IqIEdldERlc2NyaXB0b3IoKSBjb25zdCB7IHJldHVybiBHZXRNZXRhZGF0YSgpLmRlc2NyaXB0b3I7IH0KKworICAvLyBHZXQgdGhlIFJlZmxlY3Rpb24gaW50ZXJmYWNlIGZvciB0aGlzIE1lc3NhZ2UsIHdoaWNoIGNhbiBiZSB1c2VkIHRvCisgIC8vIHJlYWQgYW5kIG1vZGlmeSB0aGUgZmllbGRzIG9mIHRoZSBNZXNzYWdlIGR5bmFtaWNhbGx5IChpbiBvdGhlciB3b3JkcywKKyAgLy8gd2l0aG91dCBrbm93aW5nIHRoZSBtZXNzYWdlIHR5cGUgYXQgY29tcGlsZSB0aW1lKS4gIFRoaXMgb2JqZWN0IHJlbWFpbnMKKyAgLy8gcHJvcGVydHkgb2YgdGhlIE1lc3NhZ2UuCisgIC8vCisgIC8vIFRoaXMgbWV0aG9kIHJlbWFpbnMgdmlydHVhbCBpbiBjYXNlIGEgc3ViY2xhc3MgZG9lcyBub3QgaW1wbGVtZW50CisgIC8vIHJlZmxlY3Rpb24gYW5kIHdhbnRzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGJlaGF2aW9yLgorICB2aXJ0dWFsIGNvbnN0IFJlZmxlY3Rpb24qIEdldFJlZmxlY3Rpb24oKSBjb25zdCB7CisgICAgcmV0dXJuIEdldE1ldGFkYXRhKCkucmVmbGVjdGlvbjsKKyAgfQorCisgcHJvdGVjdGVkOgorICAvLyBHZXQgYSBzdHJ1Y3QgY29udGFpbmluZyB0aGUgbWV0YWRhdGEgZm9yIHRoZSBNZXNzYWdlLiBNb3N0IHN1YmNsYXNzZXMgb25seQorICAvLyBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZCwgcmF0aGVyIHRoYW4gdGhlIEdldERlc2NyaXB0b3IoKSBhbmQKKyAgLy8gR2V0UmVmbGVjdGlvbigpIHdyYXBwZXJzLgorICB2aXJ0dWFsIE1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3QgID0gMDsKKworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2UpOworfTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKy8vIEZvcndhcmQtZGVjbGFyZSBpbnRlcmZhY2VzIHVzZWQgdG8gaW1wbGVtZW50IFJlcGVhdGVkRmllbGRSZWYuCisvLyBUaGVzZSBhcmUgcHJvdG9idWYgaW50ZXJuYWxzIHRoYXQgdXNlcnMgc2hvdWxkbid0IGNhcmUgYWJvdXQuCitjbGFzcyBSZXBlYXRlZEZpZWxkQWNjZXNzb3I7Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gRm9yd2FyZC1kZWNsYXJlIFJlcGVhdGVkRmllbGRSZWYgdGVtcGxhdGVzLiBUaGUgc2Vjb25kIHR5cGUgcGFyYW1ldGVyIGlzCisvLyB1c2VkIGZvciBTRklOQUUgdHJpY2tzLiBVc2VycyBzaG91bGQgaWdub3JlIGl0LgordGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRW5hYmxlID0gdm9pZD4KK2NsYXNzIFJlcGVhdGVkRmllbGRSZWY7CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEVuYWJsZSA9IHZvaWQ+CitjbGFzcyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjsKKworLy8gVGhpcyBpbnRlcmZhY2UgY29udGFpbnMgbWV0aG9kcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGR5bmFtaWNhbGx5IGFjY2VzcworLy8gYW5kIG1vZGlmeSB0aGUgZmllbGRzIG9mIGEgcHJvdG9jb2wgbWVzc2FnZS4gIFRoZWlyIHNlbWFudGljcyBhcmUKKy8vIHNpbWlsYXIgdG8gdGhlIGFjY2Vzc29ycyB0aGUgcHJvdG9jb2wgY29tcGlsZXIgZ2VuZXJhdGVzLgorLy8KKy8vIFRvIGdldCB0aGUgUmVmbGVjdGlvbiBmb3IgYSBnaXZlbiBNZXNzYWdlLCBjYWxsIE1lc3NhZ2U6OkdldFJlZmxlY3Rpb24oKS4KKy8vCisvLyBUaGlzIGludGVyZmFjZSBpcyBzZXBhcmF0ZSBmcm9tIE1lc3NhZ2Ugb25seSBmb3IgZWZmaWNpZW5jeSByZWFzb25zOworLy8gdGhlIHZhc3QgbWFqb3JpdHkgb2YgaW1wbGVtZW50YXRpb25zIG9mIE1lc3NhZ2Ugd2lsbCBzaGFyZSB0aGUgc2FtZQorLy8gaW1wbGVtZW50YXRpb24gb2YgUmVmbGVjdGlvbiAoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24sCisvLyBkZWZpbmVkIGluIGdlbmVyYXRlZF9tZXNzYWdlLmgpLCBhbmQgYWxsIE1lc3NhZ2VzIG9mIGEgcGFydGljdWxhciBjbGFzcworLy8gc2hvdWxkIHNoYXJlIHRoZSBzYW1lIFJlZmxlY3Rpb24gb2JqZWN0ICh0aG91Z2ggeW91IHNob3VsZCBub3QgcmVseSBvbgorLy8gdGhlIGxhdHRlciBmYWN0KS4KKy8vCisvLyBUaGVyZSBhcmUgc2V2ZXJhbCB3YXlzIHRoYXQgdGhlc2UgbWV0aG9kcyBjYW4gYmUgdXNlZCBpbmNvcnJlY3RseS4gIEZvcgorLy8gZXhhbXBsZSwgYW55IG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyB3aWxsIGxlYWQgdG8gdW5kZWZpbmVkCisvLyByZXN1bHRzIChwcm9iYWJseSBhc3NlcnRpb24gZmFpbHVyZXMpOgorLy8gLSBUaGUgRmllbGREZXNjcmlwdG9yIGlzIG5vdCBhIGZpZWxkIG9mIHRoaXMgbWVzc2FnZSB0eXBlLgorLy8gLSBUaGUgbWV0aG9kIGNhbGxlZCBpcyBub3QgYXBwcm9wcmlhdGUgZm9yIHRoZSBmaWVsZCdzIHR5cGUuICBGb3IKKy8vICAgZWFjaCBmaWVsZCB0eXBlIGluIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV8qLCB0aGVyZSBpcyBvbmx5IG9uZQorLy8gICBHZXQqKCkgbWV0aG9kLCBvbmUgU2V0KigpIG1ldGhvZCwgYW5kIG9uZSBBZGQqKCkgbWV0aG9kIHRoYXQgaXMKKy8vICAgdmFsaWQgZm9yIHRoYXQgdHlwZS4gIEl0IHNob3VsZCBiZSBvYnZpb3VzIHdoaWNoIChleGNlcHQgbWF5YmUKKy8vICAgZm9yIFRZUEVfQllURVMsIHdoaWNoIGFyZSByZXByZXNlbnRlZCB1c2luZyBzdHJpbmdzIGluIEMrKykuCisvLyAtIEEgR2V0KigpIG9yIFNldCooKSBtZXRob2QgZm9yIHNpbmd1bGFyIGZpZWxkcyBpcyBjYWxsZWQgb24gYSByZXBlYXRlZAorLy8gICBmaWVsZC4KKy8vIC0gR2V0UmVwZWF0ZWQqKCksIFNldFJlcGVhdGVkKigpLCBvciBBZGQqKCkgaXMgY2FsbGVkIG9uIGEgbm9uLXJlcGVhdGVkCisvLyAgIGZpZWxkLgorLy8gLSBUaGUgTWVzc2FnZSBvYmplY3QgcGFzc2VkIHRvIGFueSBtZXRob2QgaXMgbm90IG9mIHRoZSByaWdodCB0eXBlIGZvcgorLy8gICB0aGlzIFJlZmxlY3Rpb24gb2JqZWN0IChpLmUuIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpICE9IHJlZmxlY3Rpb24pLgorLy8KKy8vIFlvdSBtaWdodCB3b25kZXIgd2h5IHRoZXJlIGlzIG5vdCBhbnkgYWJzdHJhY3QgcmVwcmVzZW50YXRpb24gZm9yIGEgZmllbGQKKy8vIG9mIGFyYml0cmFyeSB0eXBlLiAgRS5nLiwgd2h5IGlzbid0IHRoZXJlIGp1c3QgYSAiR2V0RmllbGQoKSIgbWV0aG9kIHRoYXQKKy8vIHJldHVybnMgImNvbnN0IEZpZWxkJiIsIHdoZXJlICJGaWVsZCIgaXMgc29tZSBjbGFzcyB3aXRoIGFjY2Vzc29ycyBsaWtlCisvLyAiR2V0SW50MzJWYWx1ZSgpIi4gIFRoZSBwcm9ibGVtIGlzIHRoYXQgc29tZW9uZSB3b3VsZCBoYXZlIHRvIGRlYWwgd2l0aAorLy8gYWxsb2NhdGluZyB0aGVzZSBGaWVsZCBvYmplY3RzLiAgRm9yIGdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMsIGhhdmluZyB0bworLy8gYWxsb2NhdGUgc3BhY2UgZm9yIGFuIGFkZGl0aW9uYWwgb2JqZWN0IHRvIHdyYXAgZXZlcnkgZmllbGQgd291bGQgYXQgbGVhc3QKKy8vIGRvdWJsZSB0aGUgbWVzc2FnZSdzIG1lbW9yeSBmb290cHJpbnQsIHByb2JhYmx5IHdvcnNlLiAgQWxsb2NhdGluZyB0aGUKKy8vIG9iamVjdHMgb24tZGVtYW5kLCBvbiB0aGUgb3RoZXIgaGFuZCwgd291bGQgYmUgZXhwZW5zaXZlIGFuZCBwcm9uZSB0bworLy8gbWVtb3J5IGxlYWtzLiAgU28sIGluc3RlYWQgd2UgZW5kZWQgdXAgd2l0aCB0aGlzIGZsYXQgaW50ZXJmYWNlLgorLy8KKy8vIFRPRE8oa2VudG9uKTogIENyZWF0ZSBhIHV0aWxpdHkgY2xhc3Mgd2hpY2ggY2FsbGVycyBjYW4gdXNlIHRvIHJlYWQgYW5kCisvLyAgIHdyaXRlIGZpZWxkcyBmcm9tIGEgUmVmbGVjdGlvbiB3aXRob3V0IHBheWluZyBhdHRlbnRpb24gdG8gdGhlIHR5cGUuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUmVmbGVjdGlvbiB7CisgcHVibGljOgorICBpbmxpbmUgUmVmbGVjdGlvbigpIHt9CisgIHZpcnR1YWwgflJlZmxlY3Rpb24oKTsKKworICAvLyBHZXQgdGhlIFVua25vd25GaWVsZFNldCBmb3IgdGhlIG1lc3NhZ2UuICBUaGlzIGNvbnRhaW5zIGZpZWxkcyB3aGljaAorICAvLyB3ZXJlIHNlZW4gd2hlbiB0aGUgTWVzc2FnZSB3YXMgcGFyc2VkIGJ1dCB3ZXJlIG5vdCByZWNvZ25pemVkIGFjY29yZGluZworICAvLyB0byB0aGUgTWVzc2FnZSdzIGRlZmluaXRpb24uIEZvciBwcm90bzMgcHJvdG9zLCB0aGlzIG1ldGhvZCB3aWxsIGFsd2F5cworICAvLyByZXR1cm4gYW4gZW1wdHkgVW5rbm93bkZpZWxkU2V0LgorICB2aXJ0dWFsIGNvbnN0IFVua25vd25GaWVsZFNldCYgR2V0VW5rbm93bkZpZWxkcygKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0ID0gMDsKKyAgLy8gR2V0IGEgbXV0YWJsZSBwb2ludGVyIHRvIHRoZSBVbmtub3duRmllbGRTZXQgZm9yIHRoZSBtZXNzYWdlLiAgVGhpcworICAvLyBjb250YWlucyBmaWVsZHMgd2hpY2ggd2VyZSBzZWVuIHdoZW4gdGhlIE1lc3NhZ2Ugd2FzIHBhcnNlZCBidXQgd2VyZSBub3QKKyAgLy8gcmVjb2duaXplZCBhY2NvcmRpbmcgdG8gdGhlIE1lc3NhZ2UncyBkZWZpbml0aW9uLiBGb3IgcHJvdG8zIHByb3RvcywgdGhpcworICAvLyBtZXRob2Qgd2lsbCByZXR1cm4gYSB2YWxpZCBtdXRhYmxlIFVua25vd25GaWVsZFNldCBwb2ludGVyIGJ1dCBtb2RpZnlpbmcKKyAgLy8gaXQgd29uJ3QgYWZmZWN0IHRoZSBzZXJpYWxpemVkIGJ5dGVzIG9mIHRoZSBtZXNzYWdlLgorICB2aXJ0dWFsIFVua25vd25GaWVsZFNldCogTXV0YWJsZVVua25vd25GaWVsZHMoTWVzc2FnZSogbWVzc2FnZSkgY29uc3QgPSAwOworCisgIC8vIEVzdGltYXRlIHRoZSBhbW91bnQgb2YgbWVtb3J5IHVzZWQgYnkgdGhlIG1lc3NhZ2Ugb2JqZWN0LgorICB2aXJ0dWFsIGludCBTcGFjZVVzZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgPSAwOworCisgIC8vIENoZWNrIGlmIHRoZSBnaXZlbiBub24tcmVwZWF0ZWQgZmllbGQgaXMgc2V0LgorICB2aXJ0dWFsIGJvb2wgSGFzRmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKworICAvLyBHZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkLgorICB2aXJ0dWFsIGludCBGaWVsZFNpemUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKworICAvLyBDbGVhciB0aGUgdmFsdWUgb2YgYSBmaWVsZCwgc28gdGhhdCBIYXNGaWVsZCgpIHJldHVybnMgZmFsc2Ugb3IKKyAgLy8gRmllbGRTaXplKCkgcmV0dXJucyB6ZXJvLgorICB2aXJ0dWFsIHZvaWQgQ2xlYXJGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisKKyAgLy8gQ2hlY2sgaWYgdGhlIG9uZW9mIGlzIHNldC4gUmV0dXJucyB0cnVlIGlmIGFueSBmaWVsZCBpbiBvbmVvZgorICAvLyBpcyBzZXQsIGZhbHNlIG90aGVyd2lzZS4KKyAgLy8gVE9ETyhqaWVsdW8pIC0gbWFrZSBpdCBwdXJlIHZpcnR1YWwgYWZ0ZXIgdXBkYXRpbmcgYWxsCisgIC8vIHRoZSBzdWJjbGFzc2VzLgorICB2aXJ0dWFsIGJvb2wgSGFzT25lb2YoY29uc3QgTWVzc2FnZSYgLyptZXNzYWdlKi8sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIC8qb25lb2ZfZGVzY3JpcHRvciovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdmlydHVhbCB2b2lkIENsZWFyT25lb2YoTWVzc2FnZSogLyptZXNzYWdlKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogLypvbmVvZl9kZXNjcmlwdG9yKi8pIGNvbnN0IHt9CisKKyAgLy8gUmV0dXJucyB0aGUgZmllbGQgZGVzY3JpcHRvciBpZiB0aGUgb25lb2YgaXMgc2V0LiBOVUxMIG90aGVyd2lzZS4KKyAgLy8gVE9ETyhqaWVsdW8pIC0gbWFrZSBpdCBwdXJlIHZpcnR1YWwuCisgIHZpcnR1YWwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZXRPbmVvZkZpZWxkRGVzY3JpcHRvcigKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIC8qbWVzc2FnZSovLAorICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiAvKm9uZW9mX2Rlc2NyaXB0b3IqLykgY29uc3QgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gUmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgZmllbGQuCisgIC8vIFdlIGRvbid0IHByb3ZpZGUgYSB3YXkgdG8gcmVtb3ZlIGFueSBlbGVtZW50IG90aGVyIHRoYW4gdGhlIGxhc3QKKyAgLy8gYmVjYXVzZSBpdCBpbnZpdGVzIGluZWZmaWNpZW50IHVzZSwgc3VjaCBhcyBPKG5eMikgZmlsdGVyaW5nIGxvb3BzCisgIC8vIHRoYXQgc2hvdWxkIGhhdmUgYmVlbiBPKG4pLiAgSWYgeW91IHdhbnQgdG8gcmVtb3ZlIGFuIGVsZW1lbnQgb3RoZXIKKyAgLy8gdGhhbiB0aGUgbGFzdCwgdGhlIGJlc3Qgd2F5IHRvIGRvIGl0IGlzIHRvIHJlLWFycmFuZ2UgdGhlIGVsZW1lbnRzCisgIC8vICh1c2luZyBTd2FwKCkpIHNvIHRoYXQgdGhlIG9uZSB5b3Ugd2FudCByZW1vdmVkIGlzIGF0IHRoZSBlbmQsIHRoZW4KKyAgLy8gY2FsbCBSZW1vdmVMYXN0KCkuCisgIHZpcnR1YWwgdm9pZCBSZW1vdmVMYXN0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgLy8gUmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgbWVzc2FnZSBmaWVsZCwgYW5kIHJldHVybnMgdGhlCisgIC8vIHBvaW50ZXIgdG8gdGhlIGNhbGxlci4gIENhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIHBvaW50ZXIuCisgIHZpcnR1YWwgTWVzc2FnZSogUmVsZWFzZUxhc3QoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisKKyAgLy8gU3dhcCB0aGUgY29tcGxldGUgY29udGVudHMgb2YgdHdvIG1lc3NhZ2VzLgorICB2aXJ0dWFsIHZvaWQgU3dhcChNZXNzYWdlKiBtZXNzYWdlMSwgTWVzc2FnZSogbWVzc2FnZTIpIGNvbnN0ID0gMDsKKworICAvLyBTd2FwIGZpZWxkcyBsaXN0ZWQgaW4gZmllbGRzIHZlY3RvciBvZiB0d28gbWVzc2FnZXMuCisgIHZpcnR1YWwgdm9pZCBTd2FwRmllbGRzKE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjp2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcykKKyAgICAgIGNvbnN0ID0gMDsKKworICAvLyBTd2FwIHR3byBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkLgorICB2aXJ0dWFsIHZvaWQgU3dhcEVsZW1lbnRzKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleDIpIGNvbnN0ID0gMDsKKworICAvLyBMaXN0IGFsbCBmaWVsZHMgb2YgdGhlIG1lc3NhZ2Ugd2hpY2ggYXJlIGN1cnJlbnRseSBzZXQuICBUaGlzIGluY2x1ZGVzCisgIC8vIGV4dGVuc2lvbnMuICBTaW5ndWxhciBmaWVsZHMgd2lsbCBvbmx5IGJlIGxpc3RlZCBpZiBIYXNGaWVsZChmaWVsZCkgd291bGQKKyAgLy8gcmV0dXJuIHRydWUgYW5kIHJlcGVhdGVkIGZpZWxkcyB3aWxsIG9ubHkgYmUgbGlzdGVkIGlmIEZpZWxkU2l6ZShmaWVsZCkKKyAgLy8gd291bGQgcmV0dXJuIG5vbi16ZXJvLiAgRmllbGRzIChib3RoIG5vcm1hbCBmaWVsZHMgYW5kIGV4dGVuc2lvbiBmaWVsZHMpCisgIC8vIHdpbGwgYmUgbGlzdGVkIG9yZGVyZWQgYnkgZmllbGQgbnVtYmVyLgorICB2aXJ0dWFsIHZvaWQgTGlzdEZpZWxkcygKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICBzdGQ6OnZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogb3V0cHV0KSBjb25zdCA9IDA7CisKKyAgLy8gU2luZ3VsYXIgZmllbGQgZ2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgZ2V0IHRoZSB2YWx1ZSBvZiBhIG5vbi1yZXBlYXRlZCBmaWVsZC4gIFRoZXkgcmV0dXJuIHRoZSBkZWZhdWx0CisgIC8vIHZhbHVlIGZvciBmaWVsZHMgdGhhdCBhcmVuJ3Qgc2V0LgorCisgIHZpcnR1YWwgaW50MzIgIEdldEludDMyIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGludDY0ICBHZXRJbnQ2NCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB1aW50MzIgR2V0VUludDMyKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdWludDY0IEdldFVJbnQ2NChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGZsb2F0ICBHZXRGbG9hdCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBkb3VibGUgR2V0RG91YmxlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgYm9vbCAgIEdldEJvb2wgIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIHN0cmluZyBHZXRTdHJpbmcoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBHZXRFbnVtKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworCisgIC8vIEdldEVudW1WYWx1ZSgpIHJldHVybnMgYW4gZW51bSBmaWVsZCdzIHZhbHVlIGFzIGFuIGludGVnZXIgcmF0aGVyIHRoYW4KKyAgLy8gYW4gRW51bVZhbHVlRGVzY3JpcHRvciouIElmIHRoZSBpbnRlZ2VyIHZhbHVlIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYQorICAvLyBrbm93biB2YWx1ZSBkZXNjcmlwdG9yLCBhIG5ldyB2YWx1ZSBkZXNjcmlwdG9yIGlzIGNyZWF0ZWQuIChTdWNoIGEgdmFsdWUKKyAgLy8gd2lsbCBvbmx5IGJlIHByZXNlbnQgd2hlbiB0aGUgbmV3IHVua25vd24tZW51bS12YWx1ZSBzZW1hbnRpY3MgYXJlIGVuYWJsZWQKKyAgLy8gZm9yIGEgbWVzc2FnZS4pCisgIHZpcnR1YWwgaW50IEdldEVudW1WYWx1ZSgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIC8vIFNlZSBNdXRhYmxlTWVzc2FnZSgpIGZvciB0aGUgbWVhbmluZyBvZiB0aGUgImZhY3RvcnkiIHBhcmFtZXRlci4KKyAgdmlydHVhbCBjb25zdCBNZXNzYWdlJiBHZXRNZXNzYWdlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdCA9IDA7CisKKyAgLy8gR2V0IGEgc3RyaW5nIHZhbHVlIHdpdGhvdXQgY29weWluZywgaWYgcG9zc2libGUuCisgIC8vCisgIC8vIEdldFN0cmluZygpIG5lY2Vzc2FyaWx5IHJldHVybnMgYSBjb3B5IG9mIHRoZSBzdHJpbmcuICBUaGlzIGNhbiBiZQorICAvLyBpbmVmZmljaWVudCB3aGVuIHRoZSBzdHJpbmcgaXMgYWxyZWFkeSBzdG9yZWQgaW4gYSBzdHJpbmcgb2JqZWN0IGluIHRoZQorICAvLyB1bmRlcmx5aW5nIG1lc3NhZ2UuICBHZXRTdHJpbmdSZWZlcmVuY2UoKSB3aWxsIHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUKKyAgLy8gdW5kZXJseWluZyBzdHJpbmcgaW4gdGhpcyBjYXNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIGNvcHkgdGhlIHN0cmluZyBpbnRvCisgIC8vICpzY3JhdGNoIGFuZCByZXR1cm4gdGhhdC4KKyAgLy8KKyAgLy8gTm90ZTogIEl0IGlzIHBlcmZlY3RseSByZWFzb25hYmxlIGFuZCB1c2VmdWwgdG8gd3JpdGUgY29kZSBsaWtlOgorICAvLyAgICAgc3RyID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKGZpZWxkLCAmc3RyKTsKKyAgLy8gICBUaGlzIGxpbmUgd291bGQgZW5zdXJlIHRoYXQgb25seSBvbmUgY29weSBvZiB0aGUgc3RyaW5nIGlzIG1hZGUKKyAgLy8gICByZWdhcmRsZXNzIG9mIHRoZSBmaWVsZCdzIHVuZGVybHlpbmcgcmVwcmVzZW50YXRpb24uICBXaGVuIGluaXRpYWxpemluZworICAvLyAgIGEgbmV3bHktY29uc3RydWN0ZWQgc3RyaW5nLCB0aG91Z2gsIGl0J3MganVzdCBhcyBmYXN0IGFuZCBtb3JlIHJlYWRhYmxlCisgIC8vICAgdG8gdXNlIGNvZGUgbGlrZToKKyAgLy8gICAgIHN0cmluZyBzdHIgPSByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgZmllbGQpOworICB2aXJ0dWFsIGNvbnN0IHN0cmluZyYgR2V0U3RyaW5nUmVmZXJlbmNlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHNjcmF0Y2gpIGNvbnN0ID0gMDsKKworCisgIC8vIFNpbmd1bGFyIGZpZWxkIG11dGF0b3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIG11dGF0ZSB0aGUgdmFsdWUgb2YgYSBub24tcmVwZWF0ZWQgZmllbGQuCisKKyAgdmlydHVhbCB2b2lkIFNldEludDMyIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludDMyICB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0SW50NjQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50NjQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRVSW50MzIoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCB1aW50MzIgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFNldFVJbnQ2NChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHVpbnQ2NCB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0RmxvYXQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZmxvYXQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXREb3VibGUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBkb3VibGUgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFNldEJvb2wgIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgICB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0U3RyaW5nKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRFbnVtICAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCA9IDA7CisgIC8vIFNldCBhbiBlbnVtIGZpZWxkJ3MgdmFsdWUgd2l0aCBhbiBpbnRlZ2VyIHJhdGhlciB0aGFuIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgIC8vIElmIHRoZSB2YWx1ZSBkb2VzIG5vdCBjb3JyZXNwb25kIHRvIGEga25vd24gZW51bSB2YWx1ZSwgZWl0aGVyIGJlaGF2aW9yIGlzCisgIC8vIHVuZGVmaW5lZCAoZm9yIHByb3RvMiBtZXNzYWdlcyksIG9yIHRoZSB2YWx1ZSBpcyBhY2NlcHRlZCBzaWxlbnRseSBmb3IKKyAgLy8gbWVzc2FnZXMgd2l0aCBuZXcgdW5rbm93bi1lbnVtLXZhbHVlIHNlbWFudGljcy4KKyAgdmlydHVhbCB2b2lkIFNldEVudW1WYWx1ZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKworICAvLyBHZXQgYSBtdXRhYmxlIHBvaW50ZXIgdG8gYSBmaWVsZCB3aXRoIGEgbWVzc2FnZSB0eXBlLiAgSWYgYSBNZXNzYWdlRmFjdG9yeQorICAvLyBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkIHRvIGNvbnN0cnVjdCBpbnN0YW5jZXMgb2YgdGhlIHN1Yi1tZXNzYWdlOworICAvLyBvdGhlcndpc2UsIHRoZSBkZWZhdWx0IGZhY3RvcnkgaXMgdXNlZC4gIElmIHRoZSBmaWVsZCBpcyBhbiBleHRlbnNpb24gdGhhdAorICAvLyBkb2VzIG5vdCBsaXZlIGluIHRoZSBzYW1lIHBvb2wgYXMgdGhlIGNvbnRhaW5pbmcgbWVzc2FnZSdzIGRlc2NyaXB0b3IgKGUuZy4KKyAgLy8gaXQgbGl2ZXMgaW4gYW4gb3ZlcmxheSBwb29sKSwgdGhlbiBhIE1lc3NhZ2VGYWN0b3J5IG11c3QgYmUgcHJvdmlkZWQuCisgIC8vIElmIHlvdSBoYXZlIG5vIGlkZWEgd2hhdCB0aGF0IG1lYW50LCB0aGVuIHlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIHdvcnJ5CisgIC8vIGFib3V0IGl0IChkb24ndCBwcm92aWRlIGEgTWVzc2FnZUZhY3RvcnkpLiAgV0FSTklORzogIElmIHRoZQorICAvLyBGaWVsZERlc2NyaXB0b3IgaXMgZm9yIGEgY29tcGlsZWQtaW4gZXh0ZW5zaW9uLCB0aGVuCisgIC8vIGZhY3RvcnktPkdldFByb3RvdHlwZShmaWVsZC0+bWVzc2FnZV90eXBlKCkgTVVTVCByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlCisgIC8vIGNvbXBpbGVkLWluIGNsYXNzIGZvciB0aGlzIHR5cGUsIE5PVCBEeW5hbWljTWVzc2FnZS4KKyAgdmlydHVhbCBNZXNzYWdlKiBNdXRhYmxlTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdCA9IDA7CisgIC8vIFJlcGxhY2VzIHRoZSBtZXNzYWdlIHNwZWNpZmllZCBieSAnZmllbGQnIHdpdGggdGhlIGFscmVhZHktYWxsb2NhdGVkIG9iamVjdAorICAvLyBzdWJfbWVzc2FnZSwgcGFzc2luZyBvd25lcnNoaXAgdG8gdGhlIG1lc3NhZ2UuICBJZiB0aGUgZmllbGQgY29udGFpbmVkIGEKKyAgLy8gbWVzc2FnZSwgdGhhdCBtZXNzYWdlIGlzIGRlbGV0ZWQuICBJZiBzdWJfbWVzc2FnZSBpcyBOVUxMLCB0aGUgZmllbGQgaXMKKyAgLy8gY2xlYXJlZC4KKyAgdmlydHVhbCB2b2lkIFNldEFsbG9jYXRlZE1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgLy8gUmVsZWFzZXMgdGhlIG1lc3NhZ2Ugc3BlY2lmaWVkIGJ5ICdmaWVsZCcgYW5kIHJldHVybnMgdGhlIHBvaW50ZXIsCisgIC8vIFJlbGVhc2VNZXNzYWdlKCkgd2lsbCByZXR1cm4gdGhlIG1lc3NhZ2UgdGhlIG1lc3NhZ2Ugb2JqZWN0IGlmIGl0IGV4aXN0cy4KKyAgLy8gT3RoZXJ3aXNlLCBpdCBtYXkgb3IgbWF5IG5vdCByZXR1cm4gTlVMTC4gIEluIGFueSBjYXNlLCBpZiB0aGUgcmV0dXJuIHZhbHVlCisgIC8vIGlzIG5vbi1OVUxMLCB0aGUgY2FsbGVyIHRha2VzIG93bmVyc2hpcCBvZiB0aGUgcG9pbnRlci4KKyAgLy8gSWYgdGhlIGZpZWxkIGV4aXN0ZWQgKEhhc0ZpZWxkKCkgaXMgdHJ1ZSksIHRoZW4gdGhlIHJldHVybmVkIHBvaW50ZXIgd2lsbAorICAvLyBiZSB0aGUgc2FtZSBhcyB0aGUgcG9pbnRlciByZXR1cm5lZCBieSBNdXRhYmxlTWVzc2FnZSgpLgorICAvLyBUaGlzIGZ1bmN0aW9uIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgQ2xlYXJGaWVsZCgpLgorICB2aXJ0dWFsIE1lc3NhZ2UqIFJlbGVhc2VNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSA9IE5VTEwpIGNvbnN0ID0gMDsKKworCisgIC8vIFJlcGVhdGVkIGZpZWxkIGdldHRlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGdldCB0aGUgdmFsdWUgb2Ygb25lIGVsZW1lbnQgb2YgYSByZXBlYXRlZCBmaWVsZC4KKworICB2aXJ0dWFsIGludDMyICBHZXRSZXBlYXRlZEludDMyIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBpbnQ2NCAgR2V0UmVwZWF0ZWRJbnQ2NCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdWludDMyIEdldFJlcGVhdGVkVUludDMyKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3QgPSAwOworICB2aXJ0dWFsIHVpbnQ2NCBHZXRSZXBlYXRlZFVJbnQ2NChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBmbG9hdCAgR2V0UmVwZWF0ZWRGbG9hdCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdCA9IDA7CisgIHZpcnR1YWwgZG91YmxlIEdldFJlcGVhdGVkRG91YmxlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGJvb2wgICBHZXRSZXBlYXRlZEJvb2wgIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBzdHJpbmcgR2V0UmVwZWF0ZWRTdHJpbmcoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdCA9IDA7CisgIHZpcnR1YWwgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogR2V0UmVwZWF0ZWRFbnVtKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgPSAwOworICAvLyBHZXRSZXBlYXRlZEVudW1WYWx1ZSgpIHJldHVybnMgYW4gZW51bSBmaWVsZCdzIHZhbHVlIGFzIGFuIGludGVnZXIgcmF0aGVyCisgIC8vIHRoYW4gYW4gRW51bVZhbHVlRGVzY3JpcHRvciouIElmIHRoZSBpbnRlZ2VyIHZhbHVlIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYQorICAvLyBrbm93biB2YWx1ZSBkZXNjcmlwdG9yLCBhIG5ldyB2YWx1ZSBkZXNjcmlwdG9yIGlzIGNyZWF0ZWQuIChTdWNoIGEgdmFsdWUKKyAgLy8gd2lsbCBvbmx5IGJlIHByZXNlbnQgd2hlbiB0aGUgbmV3IHVua25vd24tZW51bS12YWx1ZSBzZW1hbnRpY3MgYXJlIGVuYWJsZWQKKyAgLy8gZm9yIGEgbWVzc2FnZS4pCisgIHZpcnR1YWwgaW50IEdldFJlcGVhdGVkRW51bVZhbHVlKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIHZpcnR1YWwgY29uc3QgTWVzc2FnZSYgR2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgPSAwOworCisgIC8vIFNlZSBHZXRTdHJpbmdSZWZlcmVuY2UoKSwgYWJvdmUuCisgIHZpcnR1YWwgY29uc3Qgc3RyaW5nJiBHZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZSgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBpbnQgaW5kZXgsIHN0cmluZyogc2NyYXRjaCkgY29uc3QgPSAwOworCisKKyAgLy8gUmVwZWF0ZWQgZmllbGQgbXV0YXRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgbXV0YXRlIHRoZSB2YWx1ZSBvZiBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkLgorCisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEludDMyIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgaW50MzIgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEludDY0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgaW50NjQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZFVJbnQzMihNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgdWludDMyIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZFVJbnQ2NChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgdWludDY0IHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEZsb2F0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZERvdWJsZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEJvb2wgIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgYm9vbCAgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZFN0cmluZyhNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0UmVwZWF0ZWRFbnVtKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCA9IDA7CisgIC8vIFNldCBhbiBlbnVtIGZpZWxkJ3MgdmFsdWUgd2l0aCBhbiBpbnRlZ2VyIHJhdGhlciB0aGFuIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgIC8vIElmIHRoZSB2YWx1ZSBkb2VzIG5vdCBjb3JyZXNwb25kIHRvIGEga25vd24gZW51bSB2YWx1ZSwgZWl0aGVyIGJlaGF2aW9yIGlzCisgIC8vIHVuZGVmaW5lZCAoZm9yIHByb3RvMiBtZXNzYWdlcyksIG9yIHRoZSB2YWx1ZSBpcyBhY2NlcHRlZCBzaWxlbnRseSBmb3IKKyAgLy8gbWVzc2FnZXMgd2l0aCBuZXcgdW5rbm93bi1lbnVtLXZhbHVlIHNlbWFudGljcy4KKyAgdmlydHVhbCB2b2lkIFNldFJlcGVhdGVkRW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmFsdWUpIGNvbnN0OworICAvLyBHZXQgYSBtdXRhYmxlIHBvaW50ZXIgdG8gYW4gZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkIHdpdGggYSBtZXNzYWdlCisgIC8vIHR5cGUuCisgIHZpcnR1YWwgTWVzc2FnZSogTXV0YWJsZVJlcGVhdGVkTWVzc2FnZSgKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgPSAwOworCisKKyAgLy8gUmVwZWF0ZWQgZmllbGQgYWRkZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgYWRkIGFuIGVsZW1lbnQgdG8gYSByZXBlYXRlZCBmaWVsZC4KKworICB2aXJ0dWFsIHZvaWQgQWRkSW50MzIgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50MzIgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGRJbnQ2NCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQ2NCAgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZFVJbnQzMihNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHVpbnQzMiB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgQWRkVUludDY0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgdWludDY0IHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGRGbG9hdCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBmbG9hdCAgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZERvdWJsZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGRvdWJsZSB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgQWRkQm9vbCAgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCAgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGRTdHJpbmcoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZEVudW0gIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIGNvbnN0ID0gMDsKKyAgLy8gU2V0IGFuIGVudW0gZmllbGQncyB2YWx1ZSB3aXRoIGFuIGludGVnZXIgcmF0aGVyIHRoYW4gRW51bVZhbHVlRGVzY3JpcHRvci4KKyAgLy8gSWYgdGhlIHZhbHVlIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYSBrbm93biBlbnVtIHZhbHVlLCBlaXRoZXIgYmVoYXZpb3IgaXMKKyAgLy8gdW5kZWZpbmVkIChmb3IgcHJvdG8yIG1lc3NhZ2VzKSwgb3IgdGhlIHZhbHVlIGlzIGFjY2VwdGVkIHNpbGVudGx5IGZvcgorICAvLyBtZXNzYWdlcyB3aXRoIG5ldyB1bmtub3duLWVudW0tdmFsdWUgc2VtYW50aWNzLgorICB2aXJ0dWFsIHZvaWQgQWRkRW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmFsdWUpIGNvbnN0OworICAvLyBTZWUgTXV0YWJsZU1lc3NhZ2UoKSBmb3IgY29tbWVudHMgb24gdGhlICJmYWN0b3J5IiBwYXJhbWV0ZXIuCisgIHZpcnR1YWwgTWVzc2FnZSogQWRkTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5ID0gTlVMTCkgY29uc3QgPSAwOworCisKKyAgLy8gR2V0IGEgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byByZWFkIHRoZSB1bmRlcmx5aW5nCisgIC8vIHJlcGVhdGVkIGZpZWxkLiBUaGUgdHlwZSBwYXJhbWV0ZXIgVCBtdXN0IGJlIHNldCBhY2NvcmRpbmcgdG8gdGhlCisgIC8vIGZpZWxkJ3MgY3BwIHR5cGUuIFRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIG1hcHBpbmcgZnJvbSBjcHAgdHlwZQorICAvLyB0byBhY2NlcHRhYmxlIFQuCisgIC8vCisgIC8vICAgZmllbGQtPmNwcF90eXBlKCkgICAgICBUCisgIC8vICAgQ1BQVFlQRV9JTlQzMiAgICAgICAgaW50MzIKKyAgLy8gICBDUFBUWVBFX1VJTlQzMiAgICAgICB1aW50MzIKKyAgLy8gICBDUFBUWVBFX0lOVDY0ICAgICAgICBpbnQ2NAorICAvLyAgIENQUFRZUEVfVUlOVDY0ICAgICAgIHVpbnQ2NAorICAvLyAgIENQUFRZUEVfRE9VQkxFICAgICAgIGRvdWJsZQorICAvLyAgIENQUFRZUEVfRkxPQVQgICAgICAgIGZsb2F0CisgIC8vICAgQ1BQVFlQRV9CT09MICAgICAgICAgYm9vbAorICAvLyAgIENQUFRZUEVfRU5VTSAgICAgICAgIGdlbmVyYXRlZCBlbnVtIHR5cGUgb3IgaW50MzIKKyAgLy8gICBDUFBUWVBFX1NUUklORyAgICAgICBzdHJpbmcKKyAgLy8gICBDUFBUWVBFX01FU1NBR0UgICAgICBnZW5lcmF0ZWQgbWVzc2FnZSB0eXBlIG9yIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UKKyAgLy8KKyAgLy8gQSBSZXBlYXRlZEZpZWxkUmVmIG9iamVjdCBjYW4gYmUgY29waWVkIGFuZCB0aGUgcmVzdWx0ZWQgb2JqZWN0IHdpbGwgcG9pbnQKKyAgLy8gdG8gdGhlIHNhbWUgcmVwZWF0ZWQgZmllbGQgaW4gdGhlIHNhbWUgbWVzc2FnZS4gVGhlIG9iamVjdCBjYW4gYmUgdXNlZCBhcworICAvLyBsb25nIGFzIHRoZSBtZXNzYWdlIGlzIG5vdCBkZXN0cm95ZWQuCisgIC8vCisgIC8vIE5vdGUgdGhhdCB0byB1c2UgdGhpcyBtZXRob2QgdXNlcnMgbmVlZCB0byBpbmNsdWRlIHRoZSBoZWFkZXIgZmlsZQorICAvLyAiZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24uaCIgKHdoaWNoIGRlZmluZXMgdGhlIFJlcGVhdGVkRmllbGRSZWYKKyAgLy8gY2xhc3MgdGVtcGxhdGVzKS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgUmVwZWF0ZWRGaWVsZFJlZjxUPiBHZXRSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgLy8gTGlrZSBHZXRSZXBlYXRlZEZpZWxkUmVmKCkgYnV0IHJldHVybiBhbiBvYmplY3QgdGhhdCBjYW4gYWxzbyBiZSB1c2VkCisgIC8vIG1hbmlwdWxhdGUgdGhlIHVuZGVybHlpbmcgcmVwZWF0ZWQgZmllbGQuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPFQ+IEdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgLy8gREVQUkVDQVRFRC4gUGxlYXNlIHVzZSBHZXQoTXV0YWJsZSlSZXBlYXRlZEZpZWxkUmVmKCkgZm9yIHJlcGVhdGVkIGZpZWxkCisgIC8vIGFjY2Vzcy4gVGhlIGZvbGxvd2luZyByZXBlYXRlZCBmaWVsZCBhY2Nlc29ycyB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlCisgIC8vIGZ1dHVyZS4KKyAgLy8KKyAgLy8gUmVwZWF0ZWQgZmllbGQgYWNjZXNzb3JzICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZSBtZXRob2RzIGFib3ZlLCBlLmcuIEdldFJlcGVhdGVkSW50MzIobXNnLCBmZCwgaW5kZXgpLCBwcm92aWRlIHNpbmd1bGFyCisgIC8vIGFjY2VzcyB0byB0aGUgZGF0YSBpbiBhIFJlcGVhdGVkRmllbGQuICBUaGUgbWV0aG9kcyBiZWxvdyBwcm92aWRlIGFnZ3JlZ2F0ZQorICAvLyBhY2Nlc3MgYnkgZXhwb3NpbmcgdGhlIFJlcGVhdGVkRmllbGQgb2JqZWN0IGl0c2VsZiB3aXRoIHRoZSBNZXNzYWdlLgorICAvLyBBcHBseWluZyB0aGVzZSB0ZW1wbGF0ZXMgdG8gaW5hcHByb3ByaWF0ZSB0eXBlcyB3aWxsIGxlYWQgdG8gYW4gdW5kZWZpbmVkCisgIC8vIHJlZmVyZW5jZSBhdCBsaW5rIHRpbWUgKGUuZy4gR2V0UmVwZWF0ZWRGaWVsZDwqKipkb3VibGU+KSwgb3IgcG9zc2libHkgYQorICAvLyB0ZW1wbGF0ZSBtYXRjaGluZyBlcnJvciBhdCBjb21waWxlIHRpbWUgKGUuZy4gR2V0UmVwZWF0ZWRQdHJGaWVsZDxGaWxlPikuCisgIC8vCisgIC8vIFVzYWdlIGV4YW1wbGU6IG15X2RvdWJzID0gcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZDxkb3VibGU+KG1zZywgZmQpOworCisgIC8vIERFUFJFQ0FURUQuIFBsZWFzZSB1c2UgR2V0UmVwZWF0ZWRGaWVsZFJlZigpLgorICAvLworICAvLyBmb3IgVCA9IENvcmQgYW5kIGFsbCBwcm90b2J1ZiBzY2FsYXIgdHlwZXMgZXhjZXB0IGVudW1zLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBjb25zdCBSZXBlYXRlZEZpZWxkPFQ+JiBHZXRSZXBlYXRlZEZpZWxkKAorICAgICAgY29uc3QgTWVzc2FnZSYsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciopIGNvbnN0OworCisgIC8vIERFUFJFQ0FURUQuIFBsZWFzZSB1c2UgR2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWYoKS4KKyAgLy8KKyAgLy8gZm9yIFQgPSBDb3JkIGFuZCBhbGwgcHJvdG9idWYgc2NhbGFyIHR5cGVzIGV4Y2VwdCBlbnVtcy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgUmVwZWF0ZWRGaWVsZDxUPiogTXV0YWJsZVJlcGVhdGVkRmllbGQoCisgICAgICBNZXNzYWdlKiwgY29uc3QgRmllbGREZXNjcmlwdG9yKikgY29uc3Q7CisKKyAgLy8gREVQUkVDQVRFRC4gUGxlYXNlIHVzZSBHZXRSZXBlYXRlZEZpZWxkUmVmKCkuCisgIC8vCisgIC8vIGZvciBUID0gc3RyaW5nLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6U3RyaW5nUGllY2VGaWVsZAorICAvLyAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgJiBkZXNjZW5kYW50cy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxUPiYgR2V0UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqKSBjb25zdDsKKworICAvLyBERVBSRUNBVEVELiBQbGVhc2UgdXNlIEdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKCkuCisgIC8vCisgIC8vIGZvciBUID0gc3RyaW5nLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6U3RyaW5nUGllY2VGaWVsZAorICAvLyAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgJiBkZXNjZW5kYW50cy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgUmVwZWF0ZWRQdHJGaWVsZDxUPiogTXV0YWJsZVJlcGVhdGVkUHRyRmllbGQoCisgICAgICBNZXNzYWdlKiwgY29uc3QgRmllbGREZXNjcmlwdG9yKikgY29uc3Q7CisKKyAgLy8gRXh0ZW5zaW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVHJ5IHRvIGZpbmQgYW4gZXh0ZW5zaW9uIG9mIHRoaXMgbWVzc2FnZSB0eXBlIGJ5IGZ1bGx5LXF1YWxpZmllZCBmaWVsZAorICAvLyBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vIGV4dGVuc2lvbiBpcyBrbm93biBmb3IgdGhpcyBuYW1lIG9yIG51bWJlci4KKyAgdmlydHVhbCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgPSAwOworCisgIC8vIFRyeSB0byBmaW5kIGFuIGV4dGVuc2lvbiBvZiB0aGlzIG1lc3NhZ2UgdHlwZSBieSBmaWVsZCBudW1iZXIuCisgIC8vIFJldHVybnMgTlVMTCBpZiBubyBleHRlbnNpb24gaXMga25vd24gZm9yIHRoaXMgbmFtZSBvciBudW1iZXIuCisgIHZpcnR1YWwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcigKKyAgICAgIGludCBudW1iZXIpIGNvbnN0ID0gMDsKKworICAvLyBGZWF0dXJlIEZsYWdzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBEb2VzIHRoaXMgbWVzc2FnZSBzdXBwb3J0IHN0b3JpbmcgYXJiaXRyYXJ5IGludGVnZXIgdmFsdWVzIGluIGVudW0gZmllbGRzPworICAvLyBJZiB8dHJ1ZXwsIEdldEVudW1WYWx1ZS9TZXRFbnVtVmFsdWUgYW5kIGFzc29jaWF0ZWQgcmVwZWF0ZWQtZmllbGQgdmVyc2lvbnMKKyAgLy8gdGFrZSBhcmJpdHJhcnkgaW50ZWdlciB2YWx1ZXMsIGFuZCB0aGUgbGVnYWN5IEdldEVudW0oKSBnZXR0ZXIgd2lsbAorICAvLyBkeW5hbWljYWxseSBjcmVhdGUgYW4gRW51bVZhbHVlRGVzY3JpcHRvciBmb3IgYW55IGludGVnZXIgdmFsdWUgd2l0aG91dAorICAvLyBvbmUuIElmIHxmYWxzZXwsIHNldHRpbmcgYW4gdW5rbm93biBlbnVtIHZhbHVlIHZpYSB0aGUgaW50ZWdlci1iYXNlZAorICAvLyBzZXR0ZXJzIHJlc3VsdHMgaW4gdW5kZWZpbmVkIGJlaGF2aW9yIChpbiBwcmFjdGljZSwgR09PR0xFX0RDSEVDSy1mYWlscykuCisgIC8vCisgIC8vIEdlbmVyaWMgY29kZSB0aGF0IHVzZXMgcmVmbGVjdGlvbiB0byBoYW5kbGUgbWVzc2FnZXMgd2l0aCBlbnVtIGZpZWxkcworICAvLyBzaG91bGQgY2hlY2sgdGhpcyBmbGFnIGJlZm9yZSB1c2luZyB0aGUgaW50ZWdlci1iYXNlZCBzZXR0ZXIsIGFuZCBlaXRoZXIKKyAgLy8gZG93bmdyYWRlIHRvIGEgY29tcGF0aWJsZSB2YWx1ZSBvciB1c2UgdGhlIFVua25vd25GaWVsZFNldCBpZiBub3QuIEZvcgorICAvLyBleGFtcGxlOgorICAvLworICAvLyBpbnQgbmV3X3ZhbHVlID0gR2V0VmFsdWVGcm9tQXBwbGljYXRpb25Mb2dpYygpOworICAvLyBpZiAocmVmbGVjdGlvbi0+U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpKSB7CisgIC8vICAgICByZWZsZWN0aW9uLT5TZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIG5ld192YWx1ZSk7CisgIC8vIH0gZWxzZSB7CisgIC8vICAgICBpZiAoZmllbGRfZGVzY3JpcHRvci0+ZW51bV90eXBlKCktPgorICAvLyAgICAgICAgICAgICBGaW5kVmFsdWVCeU51bXZlcihuZXdfdmFsdWUpICE9IE5VTEwpIHsKKyAgLy8gICAgICAgICByZWZsZWN0aW9uLT5TZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIG5ld192YWx1ZSk7CisgIC8vICAgICB9IGVsc2UgaWYgKGVtaXRfdW5rbm93bl9lbnVtX3ZhbHVlcykgeworICAvLyAgICAgICAgIHJlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpLT5BZGRWYXJpbnQoCisgIC8vICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwKKyAgLy8gICAgICAgICAgICAgbmV3X3ZhbHVlKTsKKyAgLy8gICAgIH0gZWxzZSB7CisgIC8vICAgICAgICAgLy8gY29udmVydCB2YWx1ZSB0byBhIGNvbXBhdGlibGUvZGVmYXVsdCB2YWx1ZS4KKyAgLy8gICAgICAgICBuZXdfdmFsdWUgPSBDb21wYXRpYmxlRG93bmdyYWRlKG5ld192YWx1ZSk7CisgIC8vICAgICAgICAgcmVmbGVjdGlvbi0+U2V0RW51bVZhbHVlKG1lc3NhZ2UsIGZpZWxkLCBuZXdfdmFsdWUpOworICAvLyAgICAgfQorICAvLyB9CisgIHZpcnR1YWwgYm9vbCBTdXBwb3J0c1Vua25vd25FbnVtVmFsdWVzKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLyBSZXR1cm5zIHRoZSBNZXNzYWdlRmFjdG9yeSBhc3NvY2lhdGVkIHdpdGggdGhpcyBtZXNzYWdlLiAgVGhpcyBjYW4gYmUKKyAgLy8gdXNlZnVsIGZvciBkZXRlcm1pbmluZyBpZiBhIG1lc3NhZ2UgaXMgYSBnZW5lcmF0ZWQgbWVzc2FnZSBvciBub3QsIGZvcgorICAvLyBleGFtcGxlOgorICAvLworICAvLyBpZiAobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRNZXNzYWdlRmFjdG9yeSgpID09CisgIC8vICAgICBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKSkgeworICAvLyAgIC8vIFRoaXMgaXMgYSBnZW5lcmF0ZWQgbWVzc2FnZS4KKyAgLy8gfQorICAvLworICAvLyBJdCBjYW4gYWxzbyBiZSB1c2VkIHRvIGNyZWF0ZSBtb3JlIG1lc3NhZ2VzIG9mIHRoaXMgdHlwZSwgdGhvdWdoCisgIC8vIE1lc3NhZ2U6Ok5ldygpIGlzIGFuIGVhc2llciB3YXkgdG8gYWNjb21wbGlzaCB0aGlzLgorICB2aXJ0dWFsIE1lc3NhZ2VGYWN0b3J5KiBHZXRNZXNzYWdlRmFjdG9yeSgpIGNvbnN0OworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgcHJvdGVjdGVkOgorICAvLyBPYnRhaW4gYSBwb2ludGVyIHRvIGEgUmVwZWF0ZWQgRmllbGQgU3RydWN0dXJlIGFuZCBkbyBzb21lIHR5cGUgY2hlY2tpbmc6CisgIC8vICAgb24gZmllbGQtPmNwcF90eXBlKCksCisgIC8vICAgb24gZmllbGQtPmZpZWxkX29wdGlvbigpLmN0eXBlKCkgKGlmIGN0eXBlID49IDApCisgIC8vICAgb2YgZmllbGQtPm1lc3NhZ2VfdHlwZSgpIChpZiBtZXNzYWdlX3R5cGUgIT0gTlVMTCkuCisgIC8vIFdlIHVzZSAxIHJvdXRpbmUgcmF0aGVyIHRoYW4gNCAoY29uc3QgdnMgbXV0YWJsZSkgeCAoc2NhbGFyIHZzIHBvaW50ZXIpLgorICB2aXJ0dWFsIHZvaWQqIE11dGFibGVSYXdSZXBlYXRlZEZpZWxkKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlLAorICAgICAgaW50IGN0eXBlLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUpIGNvbnN0ID0gMDsKKworICAvLyBUaGUgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gaW1wbGVtZW50IChNdXRhYmxlKVJlcGVhdGVkRmllbGRSZWYuCisgIC8vIEEgUmVmIG9iamVjdCB3aWxsIHN0b3JlIGEgcmF3IHBvaW50ZXIgdG8gdGhlIHJlcGVhdGVkIGZpZWxkIGRhdGEgKG9idGFpbmVkCisgIC8vIGZyb20gUmVwZWF0ZWRGaWVsZERhdGEoKSkgYW5kIGEgcG9pbnRlciB0byBhIEFjY2Vzc29yIChvYnRhaW5lZCBmcm9tCisgIC8vIFJlcGVhdGVkRmllbGRBY2Nlc3Nvcikgd2hpY2ggd2lsbCBiZSB1c2VkIHRvIGFjY2VzcyB0aGUgcmF3IGRhdGEuCisgIC8vCisgIC8vIFRPRE8oeGlhb2ZlbmcpOiBNYWtlIHRoZXNlIG1ldGhvZHMgcHVyZS12aXJ0dWFsLgorCisgIC8vIFJldHVybnMgYSByYXcgcG9pbnRlciB0byB0aGUgcmVwZWF0ZWQgZmllbGQKKyAgLy8KKyAgLy8gImNwcF90eXBlIiBhbmQgIm1lc3NhZ2VfdHlwZSIgYXJlIGRlY3VkZWQgZnJvbSB0aGUgdHlwZSBwYXJhbWV0ZXIgVCBwYXNzZWQKKyAgLy8gdG8gR2V0KE11dGFibGUpUmVwZWF0ZWRGaWVsZFJlZi4gSWYgVCBpcyBhIGdlbmVyYXRlZCBtZXNzYWdlIHR5cGUsCisgIC8vICJtZXNzYWdlX3R5cGUiIHNob3VsZCBiZSBzZXQgdG8gaXRzIGRlc2NyaXB0b3IuIE90aGVyd2lzZSAibWVzc2FnZV90eXBlIgorICAvLyBzaG91bGQgYmUgc2V0IHRvIE5VTEwuIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIG1ldGhvZCBzaG91bGQgY2hlY2sgd2hldGhlcgorICAvLyAiY3BwX3R5cGUiLyJtZXNzYWdlX3R5cGUiIGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgYWN0dWFsIHR5cGUgb2YgdGhlIGZpZWxkLgorICB2aXJ0dWFsIHZvaWQqIFJlcGVhdGVkRmllbGREYXRhKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSwKKyAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSkgY29uc3Q7CisKKyAgLy8gVGhlIHJldHVybmVkIHBvaW50ZXIgc2hvdWxkIHBvaW50IHRvIGEgc2luZ2xldG9uIGluc3RhbmNlIHdoaWNoIGltcGxlbWVudHMKKyAgLy8gdGhlIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbnRlcmZhY2UuCisgIHZpcnR1YWwgY29uc3QgaW50ZXJuYWw6OlJlcGVhdGVkRmllbGRBY2Nlc3NvciogUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyBwcml2YXRlOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBFbmFibGU+CisgIGZyaWVuZCBjbGFzcyBSZXBlYXRlZEZpZWxkUmVmOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBFbmFibGU+CisgIGZyaWVuZCBjbGFzcyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjsKKworICAvLyBTcGVjaWFsIHZlcnNpb24gZm9yIHNwZWNpYWxpemVkIGltcGxlbWVudGF0aW9ucyBvZiBzdHJpbmcuICBXZSBjYW4ndCBjYWxsCisgIC8vIE11dGFibGVSYXdSZXBlYXRlZEZpZWxkIGRpcmVjdGx5IGhlcmUgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIGFjY2VzcyB0bworICAvLyBGaWVsZE9wdGlvbnM6Oiogd2hpY2ggYXJlIGRlZmluZWQgaW4gZGVzY3JpcHRvci5wYi5oLiAgSW5jbHVkaW5nIHRoYXQKKyAgLy8gZmlsZSBoZXJlIGlzIG5vdCBwb3NzaWJsZSBiZWNhdXNlIGl0IHdvdWxkIGNhdXNlIGEgY2lyY3VsYXIgaW5jbHVkZSBjeWNsZS4KKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkU3RyaW5nKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCBpc19zdHJpbmcpIGNvbnN0OworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZWZsZWN0aW9uKTsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYSBmYWN0b3J5IGZvciBtZXNzYWdlIG9iamVjdHMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWVzc2FnZUZhY3RvcnkgeworIHB1YmxpYzoKKyAgaW5saW5lIE1lc3NhZ2VGYWN0b3J5KCkge30KKyAgdmlydHVhbCB+TWVzc2FnZUZhY3RvcnkoKTsKKworICAvLyBHaXZlbiBhIERlc2NyaXB0b3IsIGdldHMgb3IgY29uc3RydWN0cyB0aGUgZGVmYXVsdCAocHJvdG90eXBlKSBNZXNzYWdlCisgIC8vIG9mIHRoYXQgdHlwZS4gIFlvdSBjYW4gdGhlbiBjYWxsIHRoYXQgbWVzc2FnZSdzIE5ldygpIG1ldGhvZCB0byBjb25zdHJ1Y3QKKyAgLy8gYSBtdXRhYmxlIG1lc3NhZ2Ugb2YgdGhhdCB0eXBlLgorICAvLworICAvLyBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIHdpdGggdGhlIHNhbWUgRGVzY3JpcHRvciByZXR1cm5zIHRoZSBzYW1lCisgIC8vIG9iamVjdC4gIFRoZSByZXR1cm5lZCBvYmplY3QgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgZmFjdG9yeS4gIEFsc28sIGFueQorICAvLyBvYmplY3RzIGNyZWF0ZWQgYnkgY2FsbGluZyB0aGUgcHJvdG90eXBlJ3MgTmV3KCkgbWV0aG9kIHNoYXJlIHNvbWUgZGF0YQorICAvLyB3aXRoIHRoZSBwcm90b3R5cGUsIHNvIHRoZXNlIG11c3QgYmUgZGVzdHJveWVkIGJlZm9yZSB0aGUgTWVzc2FnZUZhY3RvcnkKKyAgLy8gaXMgZGVzdHJveWVkLgorICAvLworICAvLyBUaGUgZ2l2ZW4gZGVzY3JpcHRvciBtdXN0IG91dGxpdmUgdGhlIHJldHVybmVkIG1lc3NhZ2UsIGFuZCBoZW5jZSBtdXN0CisgIC8vIG91dGxpdmUgdGhlIE1lc3NhZ2VGYWN0b3J5LgorICAvLworICAvLyBTb21lIGltcGxlbWVudGF0aW9ucyBkbyBub3Qgc3VwcG9ydCBhbGwgdHlwZXMuICBHZXRQcm90b3R5cGUoKSB3aWxsCisgIC8vIHJldHVybiBOVUxMIGlmIHRoZSBkZXNjcmlwdG9yIHBhc3NlZCBpbiBpcyBub3Qgc3VwcG9ydGVkLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBtYXkgb3IgbWF5IG5vdCBiZSB0aHJlYWQtc2FmZSBkZXBlbmRpbmcgb24gdGhlIGltcGxlbWVudGF0aW9uLgorICAvLyBFYWNoIGltcGxlbWVudGF0aW9uIHNob3VsZCBkb2N1bWVudCBpdHMgb3duIGRlZ3JlZSB0aHJlYWQtc2FmZXR5LgorICB2aXJ0dWFsIGNvbnN0IE1lc3NhZ2UqIEdldFByb3RvdHlwZShjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSA9IDA7CisKKyAgLy8gR2V0cyBhIE1lc3NhZ2VGYWN0b3J5IHdoaWNoIHN1cHBvcnRzIGFsbCBnZW5lcmF0ZWQsIGNvbXBpbGVkLWluIG1lc3NhZ2VzLgorICAvLyBJbiBvdGhlciB3b3JkcywgZm9yIGFueSBjb21waWxlZC1pbiB0eXBlIEZvb01lc3NhZ2UsIHRoZSBmb2xsb3dpbmcgaXMgdHJ1ZToKKyAgLy8gICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKAorICAvLyAgICAgRm9vTWVzc2FnZTo6ZGVzY3JpcHRvcigpKSA9PSBGb29NZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCkKKyAgLy8gVGhpcyBmYWN0b3J5IHN1cHBvcnRzIGFsbCB0eXBlcyB3aGljaCBhcmUgZm91bmQgaW4KKyAgLy8gRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkuICBJZiBnaXZlbiBhIGRlc2NyaXB0b3IgZnJvbSBhbnkgb3RoZXIKKyAgLy8gcG9vbCwgR2V0UHJvdG90eXBlKCkgd2lsbCByZXR1cm4gTlVMTC4gIChZb3UgY2FuIGFsc28gY2hlY2sgaWYgYQorICAvLyBkZXNjcmlwdG9yIGlzIGZvciBhIGdlbmVyYXRlZCBtZXNzYWdlIGJ5IGNoZWNraW5nIGlmCisgIC8vIGRlc2NyaXB0b3ItPmZpbGUoKS0+cG9vbCgpID09IERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLikKKyAgLy8KKyAgLy8gVGhpcyBmYWN0b3J5IGlzIDEwMCUgdGhyZWFkLXNhZmU7IGNhbGxpbmcgR2V0UHJvdG90eXBlKCkgZG9lcyBub3QgbW9kaWZ5CisgIC8vIGFueSBzaGFyZWQgZGF0YS4KKyAgLy8KKyAgLy8gVGhpcyBmYWN0b3J5IGlzIGEgc2luZ2xldG9uLiAgVGhlIGNhbGxlciBtdXN0IG5vdCBkZWxldGUgdGhlIG9iamVjdC4KKyAgc3RhdGljIE1lc3NhZ2VGYWN0b3J5KiBnZW5lcmF0ZWRfZmFjdG9yeSgpOworCisgIC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seTogIFJlZ2lzdGVycyBhIC5wcm90byBmaWxlIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbgorICAvLyB0aW1lLCB0byBiZSBwbGFjZWQgaW4gZ2VuZXJhdGVkX2ZhY3RvcnkuICBUaGUgZmlyc3QgdGltZSBHZXRQcm90b3R5cGUoKQorICAvLyBpcyBjYWxsZWQgd2l0aCBhIGRlc2NyaXB0b3IgZnJvbSB0aGlzIGZpbGUsIHxyZWdpc3Rlcl9tZXNzYWdlc3wgd2lsbCBiZQorICAvLyBjYWxsZWQsIHdpdGggdGhlIGZpbGUgbmFtZSBhcyB0aGUgcGFyYW1ldGVyLiAgSXQgbXVzdCBjYWxsCisgIC8vIEludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKCkgKGJlbG93KSB0byByZWdpc3RlciBlYWNoIG1lc3NhZ2UgdHlwZQorICAvLyBpbiB0aGUgZmlsZS4gIFRoaXMgc3RyYW5nZSBtZWNoYW5pc20gaXMgbmVjZXNzYXJ5IGJlY2F1c2UgZGVzY3JpcHRvcnMgYXJlCisgIC8vIGJ1aWx0IGxhemlseSwgc28gd2UgY2FuJ3QgcmVnaXN0ZXIgdHlwZXMgYnkgdGhlaXIgZGVzY3JpcHRvciB1bnRpbCB3ZQorICAvLyBrbm93IHRoYXQgdGhlIGRlc2NyaXB0b3IgZXhpc3RzLiAgfGZpbGVuYW1lfCBtdXN0IGJlIGEgcGVybWFuZW50IHN0cmluZy4KKyAgc3RhdGljIHZvaWQgSW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgICBjb25zdCBjaGFyKiBmaWxlbmFtZSwgdm9pZCAoKnJlZ2lzdGVyX21lc3NhZ2VzKShjb25zdCBzdHJpbmcmKSk7CisKKyAgLy8gRm9yIGludGVybmFsIHVzZSBvbmx5OiAgUmVnaXN0ZXJzIGEgbWVzc2FnZSB0eXBlLiAgQ2FsbGVkIG9ubHkgYnkgdGhlCisgIC8vIGZ1bmN0aW9ucyB3aGljaCBhcmUgcmVnaXN0ZXJlZCB3aXRoIEludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRGaWxlKCksCisgIC8vIGFib3ZlLgorICBzdGF0aWMgdm9pZCBJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBwcm90b3R5cGUpOworCisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUZhY3RvcnkpOworfTsKKworI2RlZmluZSBERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK0xJQlBST1RPQlVGX0VYUE9SVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRGaWVsZDxUWVBFPiggICBcCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7IFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitMSUJQUk9UT0JVRl9FWFBPUlQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK1JlcGVhdGVkRmllbGQ8VFlQRT4qIFJlZmxlY3Rpb246Ok11dGFibGVSZXBlYXRlZEZpZWxkPFRZUEU+KCAgICAgXAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCitERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChpbnQzMikKK0RFQ0xBUkVfR0VUX1JFUEVBVEVEX0ZJRUxEKGludDY0KQorREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQodWludDMyKQorREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQodWludDY0KQorREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQoZmxvYXQpCitERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChkb3VibGUpCitERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChib29sKQorCisjdW5kZWYgREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgZm9yIHtHZXQsTXV0YWJsZX1SYXdSZXBlYXRlZFB0ckZpZWxkLiAgV2UgcHJvdmlkZQorLy8gc3BlY2lhbGl6YXRpb25zIGZvciA8c3RyaW5nPiwgPFN0cmluZ1BpZWNlRmllbGQ+IGFuZCA8TWVzc2FnZT4gYW5kIGhhbmRsZQorLy8gZXZlcnl0aGluZyBlbHNlIHdpdGggdGhlIGRlZmF1bHQgdGVtcGxhdGUgd2hpY2ggd2lsbCBtYXRjaCBhbnkgdHlwZSBoYXZpbmcKKy8vIGEgbWV0aG9kIHdpdGggc2lnbmF0dXJlICJzdGF0aWMgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpIi4KKy8vIFN1Y2ggYSB0eXBlIHByZXN1bWFibHkgaXMgYSBkZXNjZW5kYW50IG9mIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UuCisKK3RlbXBsYXRlPD4KK2lubGluZSBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4mIFJlZmxlY3Rpb246OkdldFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiAqc3RhdGljX2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiA+KAorICAgICAgTXV0YWJsZVJhd1JlcGVhdGVkU3RyaW5nKGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZtZXNzYWdlKSwgZmllbGQsIHRydWUpKTsKK30KKwordGVtcGxhdGU8PgoraW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiogUmVmbGVjdGlvbjo6TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPigKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qID4oCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRTdHJpbmcobWVzc2FnZSwgZmllbGQsIHRydWUpKTsKK30KKworCisvLyAtLS0tLQorCit0ZW1wbGF0ZTw+CitpbmxpbmUgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiAqc3RhdGljX2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiogPigKKyAgICAgIE11dGFibGVSYXdSZXBlYXRlZEZpZWxkKGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZtZXNzYWdlKSwgZmllbGQsCisgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UsIC0xLAorICAgICAgICAgIE5VTEwpKTsKK30KKwordGVtcGxhdGU8PgoraW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIFJlZmxlY3Rpb246Ok11dGFibGVSZXBlYXRlZFB0ckZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qID4oCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChtZXNzYWdlLCBmaWVsZCwKKyAgICAgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSwgLTEsCisgICAgICAgICAgTlVMTCkpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBQQj4KK2lubGluZSBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPFBCPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiAqc3RhdGljX2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxQQj4qID4oCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChjb25zdF9jYXN0PE1lc3NhZ2UqPigmbWVzc2FnZSksIGZpZWxkLAorICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLCAtMSwKKyAgICAgICAgICBQQjo6ZGVmYXVsdF9pbnN0YW5jZSgpLkdldERlc2NyaXB0b3IoKSkpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBQQj4KK2lubGluZSBSZXBlYXRlZFB0ckZpZWxkPFBCPiogUmVmbGVjdGlvbjo6TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxQQj4qID4oCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChtZXNzYWdlLCBmaWVsZCwKKyAgICAgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSwgLTEsCisgICAgICAgICAgUEI6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXREZXNjcmlwdG9yKCkpKTsKK30KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2JlMGU5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuY2MKQEAgLTAsMCArMSwzNTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3JzOiB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSksCisvLyAgICAgICAgICBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworTWVzc2FnZUxpdGU6On5NZXNzYWdlTGl0ZSgpIHt9CisKK3N0cmluZyBNZXNzYWdlTGl0ZTo6SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpIGNvbnN0IHsKKyAgcmV0dXJuICIoY2Fubm90IGRldGVybWluZSBtaXNzaW5nIGZpZWxkcyBmb3IgbGl0ZSBtZXNzYWdlKSI7Cit9CisKK25hbWVzcGFjZSB7CisKKy8vIFdoZW4gc2VyaWFsaXppbmcsIHdlIGZpcnN0IGNvbXB1dGUgdGhlIGJ5dGUgc2l6ZSwgdGhlbiBzZXJpYWxpemUgdGhlIG1lc3NhZ2UuCisvLyBJZiBzZXJpYWxpemF0aW9uIHByb2R1Y2VzIGEgZGlmZmVyZW50IG51bWJlciBvZiBieXRlcyB0aGFuIGV4cGVjdGVkLCB3ZQorLy8gY2FsbCB0aGlzIGZ1bmN0aW9uLCB3aGljaCBjcmFzaGVzLiAgVGhlIHByb2JsZW0gY291bGQgYmUgZHVlIHRvIGEgYnVnIGluIHRoZQorLy8gcHJvdG9idWYgaW1wbGVtZW50YXRpb24gYnV0IGlzIG1vcmUgbGlrZWx5IGNhdXNlZCBieSBjb25jdXJyZW50IG1vZGlmaWNhdGlvbgorLy8gb2YgdGhlIG1lc3NhZ2UuICBUaGlzIGZ1bmN0aW9uIGF0dGVtcHRzIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gdGhlIHR3byBhbmQKKy8vIHByb3ZpZGUgYSB1c2VmdWwgZXJyb3IgbWVzc2FnZS4KK3ZvaWQgQnl0ZVNpemVDb25zaXN0ZW5jeUVycm9yKGludCBieXRlX3NpemVfYmVmb3JlX3NlcmlhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZV9zaXplX2FmdGVyX3NlcmlhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZXNfcHJvZHVjZWRfYnlfc2VyaWFsaXphdGlvbikgeworICBHT09HTEVfQ0hFQ0tfRVEoYnl0ZV9zaXplX2JlZm9yZV9zZXJpYWxpemF0aW9uLCBieXRlX3NpemVfYWZ0ZXJfc2VyaWFsaXphdGlvbikKKyAgICAgIDw8ICJQcm90b2NvbCBtZXNzYWdlIHdhcyBtb2RpZmllZCBjb25jdXJyZW50bHkgZHVyaW5nIHNlcmlhbGl6YXRpb24uIjsKKyAgR09PR0xFX0NIRUNLX0VRKGJ5dGVzX3Byb2R1Y2VkX2J5X3NlcmlhbGl6YXRpb24sIGJ5dGVfc2l6ZV9iZWZvcmVfc2VyaWFsaXphdGlvbikKKyAgICAgIDw8ICJCeXRlIHNpemUgY2FsY3VsYXRpb24gYW5kIHNlcmlhbGl6YXRpb24gd2VyZSBpbmNvbnNpc3RlbnQuICBUaGlzICIKKyAgICAgICAgICJtYXkgaW5kaWNhdGUgYSBidWcgaW4gcHJvdG9jb2wgYnVmZmVycyBvciBpdCBtYXkgYmUgY2F1c2VkIGJ5ICIKKyAgICAgICAgICJjb25jdXJyZW50IG1vZGlmaWNhdGlvbiBvZiB0aGUgbWVzc2FnZS4iOworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGhpcyBzaG91bGRuJ3QgYmUgY2FsbGVkIGlmIGFsbCB0aGUgc2l6ZXMgYXJlIGVxdWFsLiI7Cit9CisKK3N0cmluZyBJbml0aWFsaXphdGlvbkVycm9yTWVzc2FnZShjb25zdCBjaGFyKiBhY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIG1lc3NhZ2UpIHsKKyAgLy8gTm90ZTogIFdlIHdhbnQgdG8gYXZvaWQgZGVwZW5kaW5nIG9uIHN0cnV0aWwgaW4gdGhlIGxpdGUgbGlicmFyeSwgb3RoZXJ3aXNlCisgIC8vICAgd2UnZCB1c2U6CisgIC8vCisgIC8vIHJldHVybiBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAvLyAgICJDYW4ndCAkMCBtZXNzYWdlIG9mIHR5cGUgXCIkMVwiIGJlY2F1c2UgaXQgaXMgbWlzc2luZyByZXF1aXJlZCAiCisgIC8vICAgImZpZWxkczogJDIiLAorICAvLyAgIGFjdGlvbiwgbWVzc2FnZS5HZXRUeXBlTmFtZSgpLAorICAvLyAgIG1lc3NhZ2UuSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKKworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQgKz0gIkNhbid0ICI7CisgIHJlc3VsdCArPSBhY3Rpb247CisgIHJlc3VsdCArPSAiIG1lc3NhZ2Ugb2YgdHlwZSBcIiI7CisgIHJlc3VsdCArPSBtZXNzYWdlLkdldFR5cGVOYW1lKCk7CisgIHJlc3VsdCArPSAiXCIgYmVjYXVzZSBpdCBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogIjsKKyAgcmVzdWx0ICs9IG1lc3NhZ2UuSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBTZXZlcmFsIG9mIHRoZSBQYXJzZSBtZXRob2RzIGJlbG93IGp1c3QgZG8gb25lIHRoaW5nIGFuZCB0aGVuIGNhbGwgYW5vdGhlcgorLy8gbWV0aG9kLiAgSW4gYSBuYWl2ZSBpbXBsZW1lbnRhdGlvbiwgd2UgbWlnaHQgaGF2ZSBQYXJzZUZyb21TdHJpbmcoKSBjYWxsCisvLyBQYXJzZUZyb21BcnJheSgpIHdoaWNoIHdvdWxkIGNhbGwgUGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oKSB3aGljaCB3b3VsZCBjYWxsCisvLyBQYXJzZUZyb21Db2RlZFN0cmVhbSgpIHdoaWNoIHdvdWxkIGNhbGwgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSB3aGljaCB3b3VsZAorLy8gY2FsbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oKS4gIEhvd2V2ZXIsIHdoZW4gcGFyc2luZyB2ZXJ5IHNtYWxsCisvLyBtZXNzYWdlcywgZXZlcnkgZnVuY3Rpb24gY2FsbCBpbnRyb2R1Y2VzIHNpZ25pZmljYW50IG92ZXJoZWFkLiAgVG8gYXZvaWQKKy8vIHRoaXMgd2l0aG91dCByZXByb2R1Y2luZyBjb2RlLCB3ZSB1c2UgdGhlc2UgZm9yY2VkLWlubGluZSBoZWxwZXJzLgorLy8KKy8vIE5vdGU6ICBHQ0Mgb25seSBhbGxvd3MgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIG9uIGRlY2xhcmF0aW9ucywgbm90CisvLyAgIGRlZmluaXRpb25zLgoraW5saW5lIGJvb2wgSW5saW5lTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkU7CitpbmxpbmUgYm9vbCBJbmxpbmVQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORTsKK2lubGluZSBib29sIElubGluZVBhcnNlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworaW5saW5lIGJvb2wgSW5saW5lUGFyc2VGcm9tQXJyYXkoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORTsKK2lubGluZSBib29sIElubGluZVBhcnNlUGFydGlhbEZyb21BcnJheShjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkU7CisKK2Jvb2wgSW5saW5lTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkgeworICBpZiAoIW1lc3NhZ2UtPk1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbnB1dCkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCFtZXNzYWdlLT5Jc0luaXRpYWxpemVkKCkpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCBJbml0aWFsaXphdGlvbkVycm9yTWVzc2FnZSgicGFyc2UiLCAqbWVzc2FnZSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCitib29sIElubGluZVBhcnNlRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+Q2xlYXIoKTsKKyAgcmV0dXJuIElubGluZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlucHV0LCBtZXNzYWdlKTsKK30KKworYm9vbCBJbmxpbmVQYXJzZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+Q2xlYXIoKTsKKyAgcmV0dXJuIG1lc3NhZ2UtPk1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbnB1dCk7Cit9CisKK2Jvb2wgSW5saW5lUGFyc2VGcm9tQXJyYXkoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhKSwgc2l6ZSk7CisgIHJldHVybiBJbmxpbmVQYXJzZUZyb21Db2RlZFN0cmVhbSgmaW5wdXQsIG1lc3NhZ2UpICYmCisgICAgICAgICBpbnB1dC5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKTsKK30KKworYm9vbCBJbmxpbmVQYXJzZVBhcnRpYWxGcm9tQXJyYXkoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGF0YSksIHNpemUpOworICByZXR1cm4gSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCwgbWVzc2FnZSkgJiYKKyAgICAgICAgIGlucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworCitNZXNzYWdlTGl0ZSogTWVzc2FnZUxpdGU6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBNZXNzYWdlTGl0ZSogbWVzc2FnZSA9IE5ldygpOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obWVzc2FnZSk7CisgIH0KKyAgcmV0dXJuIG1lc3NhZ2U7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6Ok1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICByZXR1cm4gSW5saW5lTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW5wdXQsIHRoaXMpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgcmV0dXJuIElubGluZVBhcnNlRnJvbUNvZGVkU3RyZWFtKGlucHV0LCB0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICByZXR1cm4gSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0LCB0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGRlY29kZXIoaW5wdXQpOworICByZXR1cm4gUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmRlY29kZXIpICYmIGRlY29kZXIuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCk7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlBhcnNlUGFydGlhbEZyb21aZXJvQ29weVN0cmVhbSgKKyAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gZGVjb2RlcihpbnB1dCk7CisgIHJldHVybiBQYXJzZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oJmRlY29kZXIpICYmCisgICAgICAgICBkZWNvZGVyLkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0oCisgICAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBpbnQgc2l6ZSkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBkZWNvZGVyKGlucHV0KTsKKyAgZGVjb2Rlci5QdXNoTGltaXQoc2l6ZSk7CisgIHJldHVybiBQYXJzZUZyb21Db2RlZFN0cmVhbSgmZGVjb2RlcikgJiYKKyAgICAgICAgIGRlY29kZXIuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgJiYKKyAgICAgICAgIGRlY29kZXIuQnl0ZXNVbnRpbExpbWl0KCkgPT0gMDsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VQYXJ0aWFsRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgKKyAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIGludCBzaXplKSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGRlY29kZXIoaW5wdXQpOworICBkZWNvZGVyLlB1c2hMaW1pdChzaXplKTsKKyAgcmV0dXJuIFBhcnNlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgmZGVjb2RlcikgJiYKKyAgICAgICAgIGRlY29kZXIuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgJiYKKyAgICAgICAgIGRlY29kZXIuQnl0ZXNVbnRpbExpbWl0KCkgPT0gMDsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgZGF0YSkgeworICByZXR1cm4gSW5saW5lUGFyc2VGcm9tQXJyYXkoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpLCB0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VQYXJ0aWFsRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGRhdGEpIHsKKyAgcmV0dXJuIElubGluZVBhcnNlUGFydGlhbEZyb21BcnJheShkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCksIHRoaXMpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpQYXJzZUZyb21BcnJheShjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgeworICByZXR1cm4gSW5saW5lUGFyc2VGcm9tQXJyYXkoZGF0YSwgc2l6ZSwgdGhpcyk7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlBhcnNlUGFydGlhbEZyb21BcnJheShjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgeworICByZXR1cm4gSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUFycmF5KGRhdGEsIHNpemUsIHRoaXMpOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordWludDgqIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gV2Ugb25seSBvcHRpbWl6ZSB0aGlzIHdoZW4gdXNpbmcgb3B0aW1pemVfZm9yID0gU1BFRUQuICBJbiBvdGhlciBjYXNlcworICAvLyB3ZSBqdXN0IHVzZSB0aGUgQ29kZWRPdXRwdXRTdHJlYW0gcGF0aC4KKyAgaW50IHNpemUgPSBHZXRDYWNoZWRTaXplKCk7CisgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBvdXQodGFyZ2V0LCBzaXplKTsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dCgmb3V0KTsKKyAgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZjb2RlZF9vdXQpOworICBHT09HTEVfQ0hFQ0soIWNvZGVkX291dC5IYWRFcnJvcigpKTsKKyAgcmV0dXJuIHRhcmdldCArIHNpemU7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVRvQ29kZWRTdHJlYW0oaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDSyhJc0luaXRpYWxpemVkKCkpIDw8IEluaXRpYWxpemF0aW9uRXJyb3JNZXNzYWdlKCJzZXJpYWxpemUiLCAqdGhpcyk7CisgIHJldHVybiBTZXJpYWxpemVQYXJ0aWFsVG9Db2RlZFN0cmVhbShvdXRwdXQpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVQYXJ0aWFsVG9Db2RlZFN0cmVhbSgKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBjb25zdCBpbnQgc2l6ZSA9IEJ5dGVTaXplKCk7ICAvLyBGb3JjZSBzaXplIHRvIGJlIGNhY2hlZC4KKyAgaWYgKHNpemUgPCAwKSB7CisgICAgLy8gTWVzc2FnZXMgPjJHIGNhbm5vdCBiZSBzZXJpYWxpemVkIGR1ZSB0byBvdmVyZmxvdyBjb21wdXRpbmcgQnl0ZVNpemUuCisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkVycm9yIGNvbXB1dGluZyBCeXRlU2l6ZSAocG9zc2libGUgb3ZlcmZsb3c/KS4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHVpbnQ4KiBidWZmZXIgPSBvdXRwdXQtPkdldERpcmVjdEJ1ZmZlckZvck5CeXRlc0FuZEFkdmFuY2Uoc2l6ZSk7CisgIGlmIChidWZmZXIgIT0gTlVMTCkgeworICAgIHVpbnQ4KiBlbmQgPSBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGJ1ZmZlcik7CisgICAgaWYgKGVuZCAtIGJ1ZmZlciAhPSBzaXplKSB7CisgICAgICBCeXRlU2l6ZUNvbnNpc3RlbmN5RXJyb3Ioc2l6ZSwgQnl0ZVNpemUoKSwgZW5kIC0gYnVmZmVyKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgaW50IG9yaWdpbmFsX2J5dGVfY291bnQgPSBvdXRwdXQtPkJ5dGVDb3VudCgpOworICAgIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICAgIGlmIChvdXRwdXQtPkhhZEVycm9yKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaW50IGZpbmFsX2J5dGVfY291bnQgPSBvdXRwdXQtPkJ5dGVDb3VudCgpOworCisgICAgaWYgKGZpbmFsX2J5dGVfY291bnQgLSBvcmlnaW5hbF9ieXRlX2NvdW50ICE9IHNpemUpIHsKKyAgICAgIEJ5dGVTaXplQ29uc2lzdGVuY3lFcnJvcihzaXplLCBCeXRlU2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX2J5dGVfY291bnQgLSBvcmlnaW5hbF9ieXRlX2NvdW50KTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitib29sIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVUb1plcm9Db3B5U3RyZWFtKAorICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBlbmNvZGVyKG91dHB1dCk7CisgIHJldHVybiBTZXJpYWxpemVUb0NvZGVkU3RyZWFtKCZlbmNvZGVyKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oCisgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIGVuY29kZXIob3V0cHV0KTsKKyAgcmV0dXJuIFNlcmlhbGl6ZVBhcnRpYWxUb0NvZGVkU3RyZWFtKCZlbmNvZGVyKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6QXBwZW5kVG9TdHJpbmcoc3RyaW5nKiBvdXRwdXQpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDSyhJc0luaXRpYWxpemVkKCkpIDw8IEluaXRpYWxpemF0aW9uRXJyb3JNZXNzYWdlKCJzZXJpYWxpemUiLCAqdGhpcyk7CisgIHJldHVybiBBcHBlbmRQYXJ0aWFsVG9TdHJpbmcob3V0cHV0KTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6QXBwZW5kUGFydGlhbFRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisgIGludCBvbGRfc2l6ZSA9IG91dHB1dC0+c2l6ZSgpOworICBpbnQgYnl0ZV9zaXplID0gQnl0ZVNpemUoKTsKKyAgaWYgKGJ5dGVfc2l6ZSA8IDApIHsKKyAgICAvLyBNZXNzYWdlcyA+MkcgY2Fubm90IGJlIHNlcmlhbGl6ZWQgZHVlIHRvIG92ZXJmbG93IGNvbXB1dGluZyBCeXRlU2l6ZS4KKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRXJyb3IgY29tcHV0aW5nIEJ5dGVTaXplIChwb3NzaWJsZSBvdmVyZmxvdz8pLiI7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZChvdXRwdXQsIG9sZF9zaXplICsgYnl0ZV9zaXplKTsKKyAgdWludDgqIHN0YXJ0ID0KKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihpbzo6bXV0YWJsZV9zdHJpbmdfZGF0YShvdXRwdXQpICsgb2xkX3NpemUpOworICB1aW50OCogZW5kID0gU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIGlmIChlbmQgLSBzdGFydCAhPSBieXRlX3NpemUpIHsKKyAgICBCeXRlU2l6ZUNvbnNpc3RlbmN5RXJyb3IoYnl0ZV9zaXplLCBCeXRlU2l6ZSgpLCBlbmQgLSBzdGFydCk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisgIG91dHB1dC0+Y2xlYXIoKTsKKyAgcmV0dXJuIEFwcGVuZFRvU3RyaW5nKG91dHB1dCk7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyhzdHJpbmcqIG91dHB1dCkgY29uc3QgeworICBvdXRwdXQtPmNsZWFyKCk7CisgIHJldHVybiBBcHBlbmRQYXJ0aWFsVG9TdHJpbmcob3V0cHV0KTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplVG9BcnJheSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfRENIRUNLKElzSW5pdGlhbGl6ZWQoKSkgPDwgSW5pdGlhbGl6YXRpb25FcnJvck1lc3NhZ2UoInNlcmlhbGl6ZSIsICp0aGlzKTsKKyAgcmV0dXJuIFNlcmlhbGl6ZVBhcnRpYWxUb0FycmF5KGRhdGEsIHNpemUpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVQYXJ0aWFsVG9BcnJheSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgY29uc3QgeworICBpbnQgYnl0ZV9zaXplID0gQnl0ZVNpemUoKTsKKyAgaWYgKHNpemUgPCBieXRlX3NpemUpIHJldHVybiBmYWxzZTsKKyAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KGRhdGEpOworICB1aW50OCogZW5kID0gU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIGlmIChlbmQgLSBzdGFydCAhPSBieXRlX3NpemUpIHsKKyAgICBCeXRlU2l6ZUNvbnNpc3RlbmN5RXJyb3IoYnl0ZV9zaXplLCBCeXRlU2l6ZSgpLCBlbmQgLSBzdGFydCk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0cmluZyBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplQXNTdHJpbmcoKSBjb25zdCB7CisgIC8vIElmIHRoZSBjb21waWxlciBpbXBsZW1lbnRzIHRoZSAoTmFtZWQpIFJldHVybiBWYWx1ZSBPcHRpbWl6YXRpb24sCisgIC8vIHRoZSBsb2NhbCB2YXJpYWJsZSAncmVzdWx0JyB3aWxsIG5vdCBhY3R1YWxseSByZXNpZGUgb24gdGhlIHN0YWNrCisgIC8vIG9mIHRoaXMgZnVuY3Rpb24sIGJ1dCB3aWxsIGJlIG92ZXJsYWlkIHdpdGggdGhlIG9iamVjdCB0aGF0IHRoZQorICAvLyBjYWxsZXIgc3VwcGxpZWQgZm9yIHRoZSByZXR1cm4gdmFsdWUgdG8gYmUgY29uc3RydWN0ZWQgaW4uCisgIHN0cmluZyBvdXRwdXQ7CisgIGlmICghQXBwZW5kVG9TdHJpbmcoJm91dHB1dCkpCisgICAgb3V0cHV0LmNsZWFyKCk7CisgIHJldHVybiBvdXRwdXQ7Cit9CisKK3N0cmluZyBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplUGFydGlhbEFzU3RyaW5nKCkgY29uc3QgeworICBzdHJpbmcgb3V0cHV0OworICBpZiAoIUFwcGVuZFBhcnRpYWxUb1N0cmluZygmb3V0cHV0KSkKKyAgICBvdXRwdXQuY2xlYXIoKTsKKyAgcmV0dXJuIG91dHB1dDsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWI2MWMxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuaApAQCAtMCwwICsxLDI3NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcnM6IHdpbmtAZ29vZ2xlLmNvbSAoV2luayBTYXZpbGxlKSwKKy8vICAgICAgICAgIGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBEZWZpbmVzIE1lc3NhZ2VMaXRlLCB0aGUgYWJzdHJhY3QgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IGFsbCAobGl0ZQorLy8gYW5kIG5vbi1saXRlKSBwcm90b2NvbCBtZXNzYWdlIG9iamVjdHMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01FU1NBR0VfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01FU1NBR0VfTElURV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIGNsYXNzIEFyZW5hOworbmFtZXNwYWNlIGlvIHsKKyAgY2xhc3MgQ29kZWRJbnB1dFN0cmVhbTsKKyAgY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07CisgIGNsYXNzIFplcm9Db3B5SW5wdXRTdHJlYW07CisgIGNsYXNzIFplcm9Db3B5T3V0cHV0U3RyZWFtOworfQorCisvLyBJbnRlcmZhY2UgdG8gbGlnaHQgd2VpZ2h0IHByb3RvY29sIG1lc3NhZ2VzLgorLy8KKy8vIFRoaXMgaW50ZXJmYWNlIGlzIGltcGxlbWVudGVkIGJ5IGFsbCBwcm90b2NvbCBtZXNzYWdlIG9iamVjdHMuICBOb24tbGl0ZQorLy8gbWVzc2FnZXMgYWRkaXRpb25hbGx5IGltcGxlbWVudCB0aGUgTWVzc2FnZSBpbnRlcmZhY2UsIHdoaWNoIGlzIGEKKy8vIHN1YmNsYXNzIG9mIE1lc3NhZ2VMaXRlLiAgVXNlIE1lc3NhZ2VMaXRlIGluc3RlYWQgd2hlbiB5b3Ugb25seSBuZWVkCisvLyB0aGUgc3Vic2V0IG9mIGZlYXR1cmVzIHdoaWNoIGl0IHN1cHBvcnRzIC0tIG5hbWVseSwgbm90aGluZyB0aGF0IHVzZXMKKy8vIGRlc2NyaXB0b3JzIG9yIHJlZmxlY3Rpb24uICBZb3UgY2FuIGluc3RydWN0IHRoZSBwcm90b2NvbCBjb21waWxlcgorLy8gdG8gZ2VuZXJhdGUgY2xhc3NlcyB3aGljaCBpbXBsZW1lbnQgb25seSBNZXNzYWdlTGl0ZSwgbm90IHRoZSBmdWxsCisvLyBNZXNzYWdlIGludGVyZmFjZSwgYnkgYWRkaW5nIHRoZSBmb2xsb3dpbmcgbGluZSB0byB0aGUgLnByb3RvIGZpbGU6CisvLworLy8gICBvcHRpb24gb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FOworLy8KKy8vIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBvbiByZXNvdXJjZS1jb25zdHJhaW5lZCBzeXN0ZW1zIHdoZXJlCisvLyB0aGUgZnVsbCBwcm90b2NvbCBidWZmZXJzIHJ1bnRpbWUgbGlicmFyeSBpcyB0b28gYmlnLgorLy8KKy8vIE5vdGUgdGhhdCBvbiBub24tY29uc3RyYWluZWQgc3lzdGVtcyAoZS5nLiBzZXJ2ZXJzKSB3aGVuIHlvdSBuZWVkCisvLyB0byBsaW5rIGluIGxvdHMgb2YgcHJvdG9jb2wgZGVmaW5pdGlvbnMsIGEgYmV0dGVyIHdheSB0byByZWR1Y2UKKy8vIHRvdGFsIGNvZGUgZm9vdHByaW50IGlzIHRvIHVzZSBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUuICBUaGlzCisvLyB3aWxsIG1ha2UgdGhlIGdlbmVyYXRlZCBjb2RlIHNtYWxsZXIgd2hpbGUgc3RpbGwgc3VwcG9ydGluZyBhbGwgdGhlCisvLyBzYW1lIGZlYXR1cmVzIChhdCB0aGUgZXhwZW5zZSBvZiBzcGVlZCkuICBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUKKy8vIGlzIGJlc3Qgd2hlbiB5b3Ugb25seSBoYXZlIGEgc21hbGwgbnVtYmVyIG9mIG1lc3NhZ2UgdHlwZXMgbGlua2VkCisvLyBpbnRvIHlvdXIgYmluYXJ5LCBpbiB3aGljaCBjYXNlIHRoZSBzaXplIG9mIHRoZSBwcm90b2NvbCBidWZmZXJzCisvLyBydW50aW1lIGl0c2VsZiBpcyB0aGUgYmlnZ2VzdCBwcm9ibGVtLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1lc3NhZ2VMaXRlIHsKKyBwdWJsaWM6CisgIGlubGluZSBNZXNzYWdlTGl0ZSgpIHt9CisgIHZpcnR1YWwgfk1lc3NhZ2VMaXRlKCk7CisKKyAgLy8gQmFzaWMgT3BlcmF0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBHZXQgdGhlIG5hbWUgb2YgdGhpcyBtZXNzYWdlIHR5cGUsIGUuZy4gImZvby5iYXIuQmF6UHJvdG8iLgorICB2aXJ0dWFsIHN0cmluZyBHZXRUeXBlTmFtZSgpIGNvbnN0ID0gMDsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHNhbWUgdHlwZS4gIE93bmVyc2hpcCBpcyBwYXNzZWQgdG8gdGhlCisgIC8vIGNhbGxlci4KKyAgdmlydHVhbCBNZXNzYWdlTGl0ZSogTmV3KCkgY29uc3QgPSAwOworCisgIC8vIENvbnN0cnVjdCBhIG5ldyBpbnN0YW5jZSBvbiB0aGUgYXJlbmEuIE93bmVyc2hpcCBpcyBwYXNzZWQgdG8gdGhlIGNhbGxlcgorICAvLyBpZiBhcmVuYSBpcyBhIE5VTEwuIERlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LgorICB2aXJ0dWFsIE1lc3NhZ2VMaXRlKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworCisgIC8vIEdldCB0aGUgYXJlbmEsIGlmIGFueSwgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbWVzc2FnZS4gVmlydHVhbCBtZXRob2QKKyAgLy8gcmVxdWlyZWQgZm9yIGdlbmVyaWMgb3BlcmF0aW9ucyBidXQgbW9zdCBhcmVuYS1yZWxhdGVkIG9wZXJhdGlvbnMgc2hvdWxkCisgIC8vIHVzZSB0aGUgR2V0QXJlbmFOb1ZpcnR1YWwoKSBnZW5lcmF0ZWQtY29kZSBtZXRob2QuIERlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgLy8gdG8gcmVkdWNlIGNvZGUgc2l6ZSBieSBhdm9pZGluZyB0aGUgbmVlZCBmb3IgcGVyLXR5cGUgaW1wbGVtZW50YXRpb25zIHdoZW4KKyAgLy8gdHlwZXMgZG8gbm90IGltcGxlbWVudCBhcmVuYSBzdXBwb3J0LgorICB2aXJ0dWFsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gTlVMTDsgfQorCisgIC8vIEdldCBhIHBvaW50ZXIgdGhhdCBtYXkgYmUgZXF1YWwgdG8gdGhpcyBtZXNzYWdlJ3MgYXJlbmEsIG9yIG1heSBub3QgYmUuIElmCisgIC8vIHRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBpcyBlcXVhbCB0byBzb21lIGFyZW5hIHBvaW50ZXIsIHRoZW4gdGhpcworICAvLyBtZXNzYWdlIGlzIG9uIHRoYXQgYXJlbmE7IGhvd2V2ZXIsIGlmIHRoaXMgbWVzc2FnZSBpcyBvbiBzb21lIGFyZW5hLCB0aGlzCisgIC8vIG1ldGhvZCBtYXkgb3IgbWF5IG5vdCByZXR1cm4gdGhhdCBhcmVuYSdzIHBvaW50ZXIuIEFzIGEgdHJhZGVvZmYsIHRoaXMKKyAgLy8gbWV0aG9kIG1heSBiZSBtb3JlIGVmZmljaWVudCB0aGFuIEdldEFyZW5hKCkuIFRoZSBpbnRlbnQgaXMgdG8gYWxsb3cKKyAgLy8gdW5kZXJseWluZyByZXByZXNlbnRhdGlvbnMgdGhhdCB1c2UgZS5nLiB0YWdnZWQgcG9pbnRlcnMgdG8gc29tZXRpbWVzIHN0b3JlCisgIC8vIHRoZSBhcmVuYSBwb2ludGVyIGRpcmVjdGx5LCBhbmQgc29tZXRpbWVzIGluIGEgbW9yZSBpbmRpcmVjdCB3YXksIGFuZCBhbGxvdworICAvLyBhIGZhc3RwYXRoIGNvbXBhcmlzb24gYWdhaW5zdCB0aGUgYXJlbmEgcG9pbnRlciB3aGVuIGl0J3MgZWFzeSB0byBvYnRhaW4uCisgIHZpcnR1YWwgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoKSBjb25zdCB7IHJldHVybiBHZXRBcmVuYSgpOyB9CisKKyAgLy8gQ2xlYXIgYWxsIGZpZWxkcyBvZiB0aGUgbWVzc2FnZSBhbmQgc2V0IHRoZW0gdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCisgIC8vIENsZWFyKCkgYXZvaWRzIGZyZWVpbmcgbWVtb3J5LCBhc3N1bWluZyB0aGF0IGFueSBtZW1vcnkgYWxsb2NhdGVkCisgIC8vIHRvIGhvbGQgcGFydHMgb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBuZWVkZWQgYWdhaW4gdG8gaG9sZCB0aGUgbmV4dAorICAvLyBtZXNzYWdlLiAgSWYgeW91IGFjdHVhbGx5IHdhbnQgdG8gZnJlZSB0aGUgbWVtb3J5IHVzZWQgYnkgYSBNZXNzYWdlLAorICAvLyB5b3UgbXVzdCBkZWxldGUgaXQuCisgIHZpcnR1YWwgdm9pZCBDbGVhcigpID0gMDsKKworICAvLyBRdWlja2x5IGNoZWNrIGlmIGFsbCByZXF1aXJlZCBmaWVsZHMgaGF2ZSB2YWx1ZXMgc2V0LgorICB2aXJ0dWFsIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0ID0gMDsKKworICAvLyBUaGlzIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgTGl0ZSBtZXNzYWdlcyAtLSBpdCBqdXN0IHJldHVybnMgIihjYW5ub3QKKyAgLy8gZGV0ZXJtaW5lIG1pc3NpbmcgZmllbGRzIGZvciBsaXRlIG1lc3NhZ2UpIi4gIEhvd2V2ZXIsIGl0IGlzIGltcGxlbWVudGVkCisgIC8vIGZvciBmdWxsIG1lc3NhZ2VzLiAgU2VlIG1lc3NhZ2UuaC4KKyAgdmlydHVhbCBzdHJpbmcgSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpIGNvbnN0OworCisgIC8vIElmIHxvdGhlcnwgaXMgdGhlIGV4YWN0IHNhbWUgY2xhc3MgYXMgdGhpcywgY2FsbHMgTWVyZ2VGcm9tKCkuICBPdGhlcndpc2UsCisgIC8vIHJlc3VsdHMgYXJlIHVuZGVmaW5lZCAocHJvYmFibHkgY3Jhc2gpLgorICB2aXJ0dWFsIHZvaWQgQ2hlY2tUeXBlQW5kTWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2VMaXRlJiBvdGhlcikgPSAwOworCisgIC8vIFBhcnNpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIE1ldGhvZHMgZm9yIHBhcnNpbmcgaW4gcHJvdG9jb2wgYnVmZmVyIGZvcm1hdC4gIE1vc3Qgb2YgdGhlc2UgYXJlCisgIC8vIGp1c3Qgc2ltcGxlIHdyYXBwZXJzIGFyb3VuZCBNZXJnZUZyb21Db2RlZFN0cmVhbSgpLiAgQ2xlYXIoKSB3aWxsIGJlIGNhbGxlZAorICAvLyBiZWZvcmUgbWVyZ2luZyB0aGUgaW5wdXQuCisKKyAgLy8gRmlsbCB0aGUgbWVzc2FnZSB3aXRoIGEgcHJvdG9jb2wgYnVmZmVyIHBhcnNlZCBmcm9tIHRoZSBnaXZlbiBpbnB1dCBzdHJlYW0uCisgIC8vIFJldHVybnMgZmFsc2Ugb24gYSByZWFkIGVycm9yIG9yIGlmIHRoZSBpbnB1dCBpcyBpbiB0aGUgd3JvbmcgZm9ybWF0LiAgQQorICAvLyBzdWNjZXNzZnVsIHJldHVybiBkb2VzIG5vdCBpbmRpY2F0ZSB0aGUgZW50aXJlIGlucHV0IGlzIGNvbnN1bWVkLCBlbnN1cmUKKyAgLy8geW91IGNhbGwgQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgdG8gY2hlY2sgdGhhdCBpZiBhcHBsaWNhYmxlLgorICBib29sIFBhcnNlRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIC8vIExpa2UgUGFyc2VGcm9tQ29kZWRTdHJlYW0oKSwgYnV0IGFjY2VwdHMgbWVzc2FnZXMgdGhhdCBhcmUgbWlzc2luZworICAvLyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgUGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIC8vIFJlYWQgYSBwcm90b2NvbCBidWZmZXIgZnJvbSB0aGUgZ2l2ZW4gemVyby1jb3B5IGlucHV0IHN0cmVhbS4gIElmCisgIC8vIHN1Y2Nlc3NmdWwsIHRoZSBlbnRpcmUgaW5wdXQgd2lsbCBiZSBjb25zdW1lZC4KKyAgYm9vbCBQYXJzZUZyb21aZXJvQ29weVN0cmVhbShpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQpOworICAvLyBMaWtlIFBhcnNlRnJvbVplcm9Db3B5U3RyZWFtKCksIGJ1dCBhY2NlcHRzIG1lc3NhZ2VzIHRoYXQgYXJlIG1pc3NpbmcKKyAgLy8gcmVxdWlyZWQgZmllbGRzLgorICBib29sIFBhcnNlUGFydGlhbEZyb21aZXJvQ29weVN0cmVhbShpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQpOworICAvLyBSZWFkIGEgcHJvdG9jb2wgYnVmZmVyIGZyb20gdGhlIGdpdmVuIHplcm8tY29weSBpbnB1dCBzdHJlYW0sIGV4cGVjdGluZworICAvLyB0aGUgbWVzc2FnZSB0byBiZSBleGFjdGx5ICJzaXplIiBieXRlcyBsb25nLiAgSWYgc3VjY2Vzc2Z1bCwgZXhhY3RseQorICAvLyB0aGlzIG1hbnkgYnl0ZXMgd2lsbCBoYXZlIGJlZW4gY29uc3VtZWQgZnJvbSB0aGUgaW5wdXQuCisgIGJvb2wgUGFyc2VGcm9tQm91bmRlZFplcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgaW50IHNpemUpOworICAvLyBMaWtlIFBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgpLCBidXQgYWNjZXB0cyBtZXNzYWdlcyB0aGF0IGFyZQorICAvLyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBQYXJzZVBhcnRpYWxGcm9tQm91bmRlZFplcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzaXplKTsKKyAgLy8gUGFyc2VzIGEgcHJvdG9jb2wgYnVmZmVyIGNvbnRhaW5lZCBpbiBhIHN0cmluZy4gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MuCisgIC8vIFRoaXMgZnVuY3Rpb24gdGFrZXMgYSBzdHJpbmcgaW4gdGhlIChub24taHVtYW4tcmVhZGFibGUpIGJpbmFyeSB3aXJlCisgIC8vIGZvcm1hdCwgbWF0Y2hpbmcgdGhlIGVuY29kaW5nIG91dHB1dCBieSBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplVG9TdHJpbmcoKS4KKyAgLy8gSWYgeW91J2QgbGlrZSB0byBjb252ZXJ0IGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIGludG8gYSBwcm90b2NvbCBidWZmZXIKKyAgLy8gb2JqZWN0LCBzZWUgZ29vZ2xlOjpwcm90b2J1Zjo6VGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKCkuCisgIGJvb2wgUGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgZGF0YSk7CisgIC8vIExpa2UgUGFyc2VGcm9tU3RyaW5nKCksIGJ1dCBhY2NlcHRzIG1lc3NhZ2VzIHRoYXQgYXJlIG1pc3NpbmcKKyAgLy8gcmVxdWlyZWQgZmllbGRzLgorICBib29sIFBhcnNlUGFydGlhbEZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBkYXRhKTsKKyAgLy8gUGFyc2UgYSBwcm90b2NvbCBidWZmZXIgY29udGFpbmVkIGluIGFuIGFycmF5IG9mIGJ5dGVzLgorICBib29sIFBhcnNlRnJvbUFycmF5KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKTsKKyAgLy8gTGlrZSBQYXJzZUZyb21BcnJheSgpLCBidXQgYWNjZXB0cyBtZXNzYWdlcyB0aGF0IGFyZSBtaXNzaW5nCisgIC8vIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBQYXJzZVBhcnRpYWxGcm9tQXJyYXkoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpOworCisKKyAgLy8gUmVhZHMgYSBwcm90b2NvbCBidWZmZXIgZnJvbSB0aGUgc3RyZWFtIGFuZCBtZXJnZXMgaXQgaW50byB0aGlzCisgIC8vIE1lc3NhZ2UuICBTaW5ndWxhciBmaWVsZHMgcmVhZCBmcm9tIHRoZSBpbnB1dCBvdmVyd3JpdGUgd2hhdCBpcworICAvLyBhbHJlYWR5IGluIHRoZSBNZXNzYWdlIGFuZCByZXBlYXRlZCBmaWVsZHMgYXJlIGFwcGVuZGVkIHRvIHRob3NlCisgIC8vIGFscmVhZHkgcHJlc2VudC4KKyAgLy8KKyAgLy8gSXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBjYWxsZXIgdG8gY2FsbCBpbnB1dC0+TGFzdFRhZ1dhcygpCisgIC8vIChmb3IgZ3JvdXBzKSBvciBpbnB1dC0+Q29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgKGZvciBub24tZ3JvdXBzKSBhZnRlcgorICAvLyB0aGlzIHJldHVybnMgdG8gdmVyaWZ5IHRoYXQgdGhlIG1lc3NhZ2UncyBlbmQgd2FzIGRlbGltaXRlZCBjb3JyZWN0bHkuCisgIC8vCisgIC8vIFBhcnNlZnJvbUNvZGVkU3RyZWFtKCkgaXMgaW1wbGVtZW50ZWQgYXMgQ2xlYXIoKSBmb2xsb3dlZCBieQorICAvLyBNZXJnZUZyb21Db2RlZFN0cmVhbSgpLgorICBib29sIE1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisKKyAgLy8gTGlrZSBNZXJnZUZyb21Db2RlZFN0cmVhbSgpLCBidXQgc3VjY2VlZHMgZXZlbiBpZiByZXF1aXJlZCBmaWVsZHMgYXJlCisgIC8vIG1pc3NpbmcgaW4gdGhlIGlucHV0LgorICAvLworICAvLyBNZXJnZUZyb21Db2RlZFN0cmVhbSgpIGlzIGp1c3QgaW1wbGVtZW50ZWQgYXMgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKCkKKyAgLy8gZm9sbG93ZWQgYnkgSXNJbml0aWFsaXplZCgpLgorICB2aXJ0dWFsIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgPSAwOworCisKKyAgLy8gU2VyaWFsaXphdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gTWV0aG9kcyBmb3Igc2VyaWFsaXppbmcgaW4gcHJvdG9jb2wgYnVmZmVyIGZvcm1hdC4gIE1vc3Qgb2YgdGhlc2UKKyAgLy8gYXJlIGp1c3Qgc2ltcGxlIHdyYXBwZXJzIGFyb3VuZCBCeXRlU2l6ZSgpIGFuZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKS4KKworICAvLyBXcml0ZSBhIHByb3RvY29sIGJ1ZmZlciBvZiB0aGlzIG1lc3NhZ2UgdG8gdGhlIGdpdmVuIG91dHB1dC4gIFJldHVybnMKKyAgLy8gZmFsc2Ugb24gYSB3cml0ZSBlcnJvci4gIElmIHRoZSBtZXNzYWdlIGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLAorICAvLyB0aGlzIG1heSBHT09HTEVfQ0hFQ0stZmFpbC4KKyAgYm9vbCBTZXJpYWxpemVUb0NvZGVkU3RyZWFtKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb0NvZGVkU3RyZWFtKCksIGJ1dCBhbGxvd3MgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgU2VyaWFsaXplUGFydGlhbFRvQ29kZWRTdHJlYW0oaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICAvLyBXcml0ZSB0aGUgbWVzc2FnZSB0byB0aGUgZ2l2ZW4gemVyby1jb3B5IG91dHB1dCBzdHJlYW0uICBBbGwgcmVxdWlyZWQKKyAgLy8gZmllbGRzIG11c3QgYmUgc2V0LgorICBib29sIFNlcmlhbGl6ZVRvWmVyb0NvcHlTdHJlYW0oaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICAvLyBMaWtlIFNlcmlhbGl6ZVRvWmVyb0NvcHlTdHJlYW0oKSwgYnV0IGFsbG93cyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBTZXJpYWxpemVQYXJ0aWFsVG9aZXJvQ29weVN0cmVhbShpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIC8vIFNlcmlhbGl6ZSB0aGUgbWVzc2FnZSBhbmQgc3RvcmUgaXQgaW4gdGhlIGdpdmVuIHN0cmluZy4gIEFsbCByZXF1aXJlZAorICAvLyBmaWVsZHMgbXVzdCBiZSBzZXQuCisgIGJvb2wgU2VyaWFsaXplVG9TdHJpbmcoc3RyaW5nKiBvdXRwdXQpIGNvbnN0OworICAvLyBMaWtlIFNlcmlhbGl6ZVRvU3RyaW5nKCksIGJ1dCBhbGxvd3MgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgU2VyaWFsaXplUGFydGlhbFRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdDsKKyAgLy8gU2VyaWFsaXplIHRoZSBtZXNzYWdlIGFuZCBzdG9yZSBpdCBpbiB0aGUgZ2l2ZW4gYnl0ZSBhcnJheS4gIEFsbCByZXF1aXJlZAorICAvLyBmaWVsZHMgbXVzdCBiZSBzZXQuCisgIGJvb2wgU2VyaWFsaXplVG9BcnJheSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgY29uc3Q7CisgIC8vIExpa2UgU2VyaWFsaXplVG9BcnJheSgpLCBidXQgYWxsb3dzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICBib29sIFNlcmlhbGl6ZVBhcnRpYWxUb0FycmF5KHZvaWQqIGRhdGEsIGludCBzaXplKSBjb25zdDsKKworICAvLyBNYWtlIGEgc3RyaW5nIGVuY29kaW5nIHRoZSBtZXNzYWdlLiBJcyBlcXVpdmFsZW50IHRvIGNhbGxpbmcKKyAgLy8gU2VyaWFsaXplVG9TdHJpbmcoKSBvbiBhIHN0cmluZyBhbmQgdXNpbmcgdGhhdC4gIFJldHVybnMgdGhlIGVtcHR5CisgIC8vIHN0cmluZyBpZiBTZXJpYWxpemVUb1N0cmluZygpIHdvdWxkIGhhdmUgcmV0dXJuZWQgYW4gZXJyb3IuCisgIC8vIE5vdGU6IElmIHlvdSBpbnRlbmQgdG8gZ2VuZXJhdGUgbWFueSBzdWNoIHN0cmluZ3MsIHlvdSBtYXkKKyAgLy8gcmVkdWNlIGhlYXAgZnJhZ21lbnRhdGlvbiBieSBpbnN0ZWFkIHJlLXVzaW5nIHRoZSBzYW1lIHN0cmluZworICAvLyBvYmplY3Qgd2l0aCBjYWxscyB0byBTZXJpYWxpemVUb1N0cmluZygpLgorICBzdHJpbmcgU2VyaWFsaXplQXNTdHJpbmcoKSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVBc1N0cmluZygpLCBidXQgYWxsb3dzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICBzdHJpbmcgU2VyaWFsaXplUGFydGlhbEFzU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gTGlrZSBTZXJpYWxpemVUb1N0cmluZygpLCBidXQgYXBwZW5kcyB0byB0aGUgZGF0YSB0byB0aGUgc3RyaW5nJ3MgZXhpc3RpbmcKKyAgLy8gY29udGVudHMuICBBbGwgcmVxdWlyZWQgZmllbGRzIG11c3QgYmUgc2V0LgorICBib29sIEFwcGVuZFRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdDsKKyAgLy8gTGlrZSBBcHBlbmRUb1N0cmluZygpLCBidXQgYWxsb3dzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICBib29sIEFwcGVuZFBhcnRpYWxUb1N0cmluZyhzdHJpbmcqIG91dHB1dCkgY29uc3Q7CisKKyAgLy8gQ29tcHV0ZXMgdGhlIHNlcmlhbGl6ZWQgc2l6ZSBvZiB0aGUgbWVzc2FnZS4gIFRoaXMgcmVjdXJzaXZlbHkgY2FsbHMKKyAgLy8gQnl0ZVNpemUoKSBvbiBhbGwgZW1iZWRkZWQgbWVzc2FnZXMuICBJZiBhIHN1YmNsYXNzIGRvZXMgbm90IG92ZXJyaWRlCisgIC8vIHRoaXMsIGl0IE1VU1Qgb3ZlcnJpZGUgU2V0Q2FjaGVkU2l6ZSgpLgorICB2aXJ0dWFsIGludCBCeXRlU2l6ZSgpIGNvbnN0ID0gMDsKKworICAvLyBTZXJpYWxpemVzIHRoZSBtZXNzYWdlIHdpdGhvdXQgcmVjb21wdXRpbmcgdGhlIHNpemUuICBUaGUgbWVzc2FnZSBtdXN0CisgIC8vIG5vdCBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgY2FsbCB0byBCeXRlU2l6ZSgpOyBpZiBpdCBoYXMsIHRoZSByZXN1bHRzCisgIC8vIGFyZSB1bmRlZmluZWQuCisgIHZpcnR1YWwgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgPSAwOworCisgIC8vIExpa2UgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzLCBidXQgd3JpdGVzIGRpcmVjdGx5IHRvICp0YXJnZXQsIHJldHVybmluZworICAvLyBhIHBvaW50ZXIgdG8gdGhlIGJ5dGUgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGxhc3QgYnl0ZSB3cml0dGVuLiAgInRhcmdldCIKKyAgLy8gbXVzdCBwb2ludCBhdCBhIGJ5dGUgYXJyYXkgb2YgYXQgbGVhc3QgQnl0ZVNpemUoKSBieXRlcy4KKyAgdmlydHVhbCB1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSh1aW50OCogdGFyZ2V0KSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgY2FsbCB0byBCeXRlU2l6ZSgpLiAgQW4gZW1iZWRkZWQgbWVzc2FnZSdzCisgIC8vIHNpemUgaXMgbmVlZGVkIGJvdGggdG8gc2VyaWFsaXplIGl0IChiZWNhdXNlIGVtYmVkZGVkIG1lc3NhZ2VzIGFyZQorICAvLyBsZW5ndGgtZGVsaW1pdGVkKSBhbmQgdG8gY29tcHV0ZSB0aGUgb3V0ZXIgbWVzc2FnZSdzIHNpemUuICBDYWNoaW5nCisgIC8vIHRoZSBzaXplIGF2b2lkcyBjb21wdXRpbmcgaXQgbXVsdGlwbGUgdGltZXMuCisgIC8vCisgIC8vIEJ5dGVTaXplKCkgZG9lcyBub3QgYXV0b21hdGljYWxseSB1c2UgdGhlIGNhY2hlZCBzaXplIHdoZW4gYXZhaWxhYmxlCisgIC8vIGJlY2F1c2UgdGhpcyB3b3VsZCByZXF1aXJlIGludmFsaWRhdGluZyBpdCBldmVyeSB0aW1lIHRoZSBtZXNzYWdlIHdhcworICAvLyBtb2RpZmllZCwgd2hpY2ggd291bGQgYmUgdG9vIGhhcmQgYW5kIGV4cGVuc2l2ZS4gIChFLmcuIGlmIGEgZGVlcGx5LW5lc3RlZAorICAvLyBzdWItbWVzc2FnZSBpcyBjaGFuZ2VkLCBhbGwgb2YgaXRzIHBhcmVudHMnIGNhY2hlZCBzaXplcyB3b3VsZCBuZWVkIHRvIGJlCisgIC8vIGludmFsaWRhdGVkLCB3aGljaCBpcyB0b28gbXVjaCB3b3JrIGZvciBhbiBvdGhlcndpc2UgaW5saW5lZCBzZXR0ZXIKKyAgLy8gbWV0aG9kLikKKyAgdmlydHVhbCBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0ID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlTGl0ZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUVTU0FHRV9MSVRFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViZmI0MzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw0NDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaWZkZWYgX01TQ19WRVIKKyNpbmNsdWRlIDxpby5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHNzdHJlYW0+CisjaW5jbHVkZSA8ZnN0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisjaWZuZGVmIE9fQklOQVJZCisjaWZkZWYgX09fQklOQVJZCisjZGVmaW5lIE9fQklOQVJZIF9PX0JJTkFSWQorI2Vsc2UKKyNkZWZpbmUgT19CSU5BUlkgMCAgICAgLy8gSWYgdGhpcyBpc24ndCBkZWZpbmVkLCB0aGUgcGxhdGZvcm0gZG9lc24ndCBuZWVkIGl0LgorI2VuZGlmCisjZW5kaWYKKworVEVTVChNZXNzYWdlVGVzdCwgU2VyaWFsaXplSGVscGVycykgeworICAvLyBUT0RPKGtlbnRvbik6ICBUZXN0IG1vcmUgaGVscGVycz8gIFRoZXkncmUgYWxsIHR3by1saW5lcnMgc28gaXQgc2VlbXMKKyAgLy8gICBsaWtlIGEgd2FzdGUgb2YgdGltZS4KKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBzdHJpbmdzdHJlYW0gc3RyZWFtOworCisgIHN0cmluZyBzdHIxKCJmb28iKTsKKyAgc3RyaW5nIHN0cjIoImJhciIpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnN0cjEpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5BcHBlbmRUb1N0cmluZygmc3RyMikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlNlcmlhbGl6ZVRvT3N0cmVhbSgmc3RyZWFtKSk7CisKKyAgRVhQRUNUX0VRKHN0cjEuc2l6ZSgpICsgMywgc3RyMi5zaXplKCkpOworICBFWFBFQ1RfRVEoImJhciIsIHN0cjIuc3Vic3RyKDAsIDMpKTsKKyAgLy8gRG9uJ3QgdXNlIEVYUEVDVF9FUSBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gZHVtcCByYXcgYmluYXJ5IGRhdGEgdG8KKyAgLy8gc3Rkb3V0LgorICBFWFBFQ1RfVFJVRShzdHIyLnN1YnN0cigzKSA9PSBzdHIxKTsKKworICAvLyBHQ0MgZ2l2ZXMgc29tZSBzb3J0IG9mIGVycm9yIGlmIHdlIHRyeSB0byBqdXN0IGRvIHN0cmVhbS5zdHIoKSA9PSBzdHIxLgorICBzdHJpbmcgdGVtcCA9IHN0cmVhbS5zdHIoKTsKKyAgRVhQRUNUX1RSVUUodGVtcCA9PSBzdHIxKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCkgPT0gc3RyMSk7CisKK30KKworVEVTVChNZXNzYWdlVGVzdCwgU2VyaWFsaXplVG9Ccm9rZW5Pc3RyZWFtKSB7CisgIG9mc3RyZWFtIG91dDsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMigxMjMpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlNlcmlhbGl6ZVRvT3N0cmVhbSgmb3V0KSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIFBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKSB7CisgIHN0cmluZyBmaWxlbmFtZSA9IFRlc3RTb3VyY2VEaXIoKSArCisgICAgICAgICAgICAgICAgICAgICIvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlIjsKKyAgaW50IGZpbGUgPSBvcGVuKGZpbGVuYW1lLmNfc3RyKCksIE9fUkRPTkxZIHwgT19CSU5BUlkpOworCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21GaWxlRGVzY3JpcHRvcihmaWxlKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0dFKGNsb3NlKGZpbGUpLCAwKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgUGFyc2VQYWNrZWRGcm9tRmlsZURlc2NyaXB0b3IpIHsKKyAgc3RyaW5nIGZpbGVuYW1lID0KKyAgICAgIFRlc3RTb3VyY2VEaXIoKSArCisgICAgICAiL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlIjsKKyAgaW50IGZpbGUgPSBvcGVuKGZpbGVuYW1lLmNfc3RyKCksIE9fUkRPTkxZIHwgT19CSU5BUlkpOworCisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgbWVzc2FnZTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21GaWxlRGVzY3JpcHRvcihmaWxlKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0dFKGNsb3NlKGZpbGUpLCAwKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgUGFyc2VIZWxwZXJzKSB7CisgIC8vIFRPRE8oa2VudG9uKTogIFRlc3QgbW9yZSBoZWxwZXJzPyAgVGhleSdyZSBhbGwgdHdvLWxpbmVycyBzbyBpdCBzZWVtcworICAvLyAgIGxpa2UgYSB3YXN0ZSBvZiB0aW1lLgorICBzdHJpbmcgZGF0YTsKKworICB7CisgICAgLy8gU2V0IHVwLgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IFBhcnNlRnJvbVN0cmluZy4KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBQYXJzZUZyb21Jc3RyZWFtLgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBzdHJpbmdzdHJlYW0gc3RyZWFtKGRhdGEpOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tSXN0cmVhbSgmc3RyZWFtKSk7CisgICAgRVhQRUNUX1RSVUUoc3RyZWFtLmVvZigpKTsKKyAgICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgUGFyc2VGcm9tQm91bmRlZFplcm9Db3B5U3RyZWFtLgorICAgIHN0cmluZyBkYXRhX3dpdGhfanVuayhkYXRhKTsKKyAgICBkYXRhX3dpdGhfanVuay5hcHBlbmQoInNvbWUganVuayBvbiB0aGUgZW5kIik7CisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gc3RyZWFtKGRhdGFfd2l0aF9qdW5rLmRhdGEoKSwgZGF0YV93aXRoX2p1bmsuc2l6ZSgpKTsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0oJnN0cmVhbSwgZGF0YS5zaXplKCkpKTsKKyAgICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgdGhhdCBQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0gZmFpbHMgKGJ1dCBkb2Vzbid0IGNyYXNoKSBpZgorICAgIC8vIEVPRiBpcyByZWFjaGVkIGJlZm9yZSB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIGJ5dGVzLgorICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHN0cmVhbShkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBFWFBFQ1RfRkFMU0UoCisgICAgICBtZXNzYWdlLlBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgmc3RyZWFtLCBkYXRhLnNpemUoKSArIDEpKTsKKyAgfQorfQorCitURVNUKE1lc3NhZ2VUZXN0LCBQYXJzZUZhaWxzSWZOb3RJbml0aWFsaXplZCkgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoIiIpKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgQVNTRVJUX0VRKDEsIGVycm9ycy5zaXplKCkpOworICBFWFBFQ1RfRVEoIkNhbid0IHBhcnNlIG1lc3NhZ2Ugb2YgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZFwiICIKKyAgICAgICAgICAgICJiZWNhdXNlIGl0IGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzOiBhLCBiLCBjIiwKKyAgICAgICAgICAgIGVycm9yc1swXSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIEJ5cGFzc0luaXRpYWxpemF0aW9uQ2hlY2tPblBhcnNlKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KE5VTEwsIDApOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5NZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oJmlucHV0KSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFWFBFQ1RfRVEoImEsIGIsIGMiLCBtZXNzYWdlLkluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSk7Cit9CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVCAgLy8gZGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyB5ZXQuCisKK1RFU1QoTWVzc2FnZVRlc3QsIFNlcmlhbGl6ZUZhaWxzSWZOb3RJbml0aWFsaXplZCkgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIHN0cmluZyBkYXRhOworICBFWFBFQ1RfREVCVUdfREVBVEgoRVhQRUNUX1RSVUUobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSkpLAorICAgICJDYW4ndCBzZXJpYWxpemUgbWVzc2FnZSBvZiB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkXCIgYmVjYXVzZSAiCisgICAgIml0IGlzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzOiBhLCBiLCBjIik7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIENoZWNrSW5pdGlhbGl6ZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFWFBFQ1RfREVBVEgobWVzc2FnZS5DaGVja0luaXRpYWxpemVkKCksCisgICAgIk1lc3NhZ2Ugb2YgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZFwiIGlzIG1pc3NpbmcgcmVxdWlyZWQgIgorICAgICJmaWVsZHM6IGEsIGIsIGMiKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgQ2hlY2tPdmVyZmxvdykgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIC8vIENyZWF0ZSBhIG1lc3NhZ2Ugd2l0aCBzaXplIGp1c3Qgb3ZlciAyR0IuIFRoaXMgdHJpZ2dlcnMgaW50ZWdlciBvdmVyZmxvdworICAvLyB3aGVuIGNvbXB1dGluZyBtZXNzYWdlIHNpemUuCisgIGNvbnN0IHN0cmluZyBkYXRhKDEwMjQsICd4Jyk7CisgIENvcmQgb25lX21lZ2FieXRlOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwMjQ7IGkrKykgeworICAgIG9uZV9tZWdhYnl0ZS5BcHBlbmQoZGF0YSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IDIgKiAxMDI0ICsgMTsgKytpKSB7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfY29yZCgpLT5Db3B5RnJvbShvbmVfbWVnYWJ5dGUpOworICB9CisKKyAgQ29yZCBzZXJpYWxpemVkOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5BcHBlbmRUb0NvcmQoJnNlcmlhbGl6ZWQpKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCituYW1lc3BhY2UgeworCitjbGFzcyBOZWdhdGl2ZUJ5dGVTaXplIDogcHVibGljIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgeworIHB1YmxpYzoKKyAgdmlydHVhbCBpbnQgQnl0ZVNpemUoKSBjb25zdCB7IHJldHVybiAtMTsgfQorfTsKKworfSAgLy8gbmFtZXNwYWNlCisKK1RFU1QoTWVzc2FnZVRlc3QsIFNlcmlhbGl6YXRpb25GYWlsc09uTmVnYXRpdmVCeXRlU2l6ZSkgeworICBOZWdhdGl2ZUJ5dGVTaXplIG1lc3NhZ2U7CisgIHN0cmluZyBzdHJpbmdfb3V0cHV0OworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5BcHBlbmRQYXJ0aWFsVG9TdHJpbmcoJnN0cmluZ19vdXRwdXQpKTsKKworICBpbzo6QXJyYXlPdXRwdXRTdHJlYW0gY29kZWRfcmF3X291dHB1dChOVUxMLCAxMDApOworICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZjb2RlZF9yYXdfb3V0cHV0KTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuU2VyaWFsaXplUGFydGlhbFRvQ29kZWRTdHJlYW0oJmNvZGVkX291dHB1dCkpOworfQorCitURVNUKE1lc3NhZ2VUZXN0LCBCeXBhc3NJbml0aWFsaXphdGlvbkNoZWNrT25TZXJpYWxpemUpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBpbzo6QXJyYXlPdXRwdXRTdHJlYW0gcmF3X291dHB1dChOVUxMLCAwKTsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuU2VyaWFsaXplUGFydGlhbFRvQ29kZWRTdHJlYW0oJm91dHB1dCkpOworfQorCitURVNUKE1lc3NhZ2VUZXN0LCBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIG1lc3NhZ2UuRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCZlcnJvcnMpOworICBBU1NFUlRfRVEoMywgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiYSIsIGVycm9yc1swXSk7CisgIEVYUEVDVF9FUSgiYiIsIGVycm9yc1sxXSk7CisgIEVYUEVDVF9FUSgiYyIsIGVycm9yc1syXSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIFBhcnNlRmFpbHNPbkludmFsaWRNZXNzYWdlRW5kKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICAvLyBDb250cm9sIGNhc2UuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tQXJyYXkoIiIsIDApKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhIHZhbGlkIHZhcmludCwgYnV0IG5vdCBhIHZhbGlkIHRhZyAoemVybykuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbUFycmF5KCJcMCIsIDEpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhIG1hbGZvcm1lZCB2YXJpbnQuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbUFycmF5KCJcMjAwIiwgMSkpOworCisgIC8vIFRoZSBieXRlIGlzIGFuIGVuZGdyb3VwIHRhZywgYnV0IHdlIGFyZW4ndCBwYXJzaW5nIGEgZ3JvdXAuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbUFycmF5KCJcMDE0IiwgMSkpOworfQorCituYW1lc3BhY2UgeworCit2b2lkIEV4cGVjdE1lc3NhZ2VNZXJnZWQoY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoMywgbWVzc2FnZS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2Uub3B0aW9uYWxfaW50NjQoKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpKTsKK30KKwordm9pZCBBc3NpZ25QYXJzaW5nTWVyZ2VNZXNzYWdlcygKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtc2cxLAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1zZzIsCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbXNnMykgeworICBtc2cxLT5zZXRfb3B0aW9uYWxfaW50MzIoMSk7CisgIG1zZzItPnNldF9vcHRpb25hbF9pbnQ2NCgyKTsKKyAgbXNnMy0+c2V0X29wdGlvbmFsX2ludDMyKDMpOworICBtc2czLT5zZXRfb3B0aW9uYWxfc3RyaW5nKCJoZWxsbyIpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gVGVzdCB0aGF0IGlmIGFuIG9wdGlvbmFsIG9yIHJlcXVpcmVkIG1lc3NhZ2UvZ3JvdXAgZmllbGQgYXBwZWFycyBtdWx0aXBsZQorLy8gdGltZXMgaW4gdGhlIGlucHV0LCB0aGV5IG5lZWQgdG8gYmUgbWVyZ2VkLgorVEVTVChNZXNzYWdlVGVzdCwgUGFyc2luZ01lcmdlKSB7CisgIHVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlOjpSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBnZW5lcmF0b3I7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1zZzI7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1zZzM7CisKKyNkZWZpbmUgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKEZJRUxEKSAgICAgICAgICAgICAgICBcCisgIG1zZzEgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKTsgICAgICAgICAgICAgICAgICAgXAorICBtc2cyID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCk7ICAgICAgICAgICAgICAgICAgIFwKKyAgbXNnMyA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpOyAgICAgICAgICAgICAgICAgICBcCisgIEFzc2lnblBhcnNpbmdNZXJnZU1lc3NhZ2VzKG1zZzEsIG1zZzIsIG1zZzMpCisKKyAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGZpZWxkMSk7CisgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChmaWVsZDIpOworICBBU1NJR05fUkVQRUFURURfRklFTEQoZmllbGQzKTsKKyAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGV4dDEpOworICBBU1NJR05fUkVQRUFURURfRklFTEQoZXh0Mik7CisKKyN1bmRlZiBBU1NJR05fUkVQRUFURURfRklFTEQKKyNkZWZpbmUgQVNTSUdOX1JFUEVBVEVEX0dST1VQKEZJRUxEKSAgICAgICAgICAgICAgICBcCisgIG1zZzEgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKS0+bXV0YWJsZV9maWVsZDEoKTsgXAorICBtc2cyID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCktPm11dGFibGVfZmllbGQxKCk7IFwKKyAgbXNnMyA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpLT5tdXRhYmxlX2ZpZWxkMSgpOyBcCisgIEFzc2lnblBhcnNpbmdNZXJnZU1lc3NhZ2VzKG1zZzEsIG1zZzIsIG1zZzMpCisKKyAgQVNTSUdOX1JFUEVBVEVEX0dST1VQKGdyb3VwMSk7CisgIEFTU0lHTl9SRVBFQVRFRF9HUk9VUChncm91cDIpOworCisjdW5kZWYgQVNTSUdOX1JFUEVBVEVEX0dST1VQCisKKyAgc3RyaW5nIGJ1ZmZlcjsKKyAgZ2VuZXJhdG9yLlNlcmlhbGl6ZVRvU3RyaW5nKCZidWZmZXIpOworICB1bml0dGVzdDo6VGVzdFBhcnNpbmdNZXJnZSBwYXJzaW5nX21lcmdlOworICBwYXJzaW5nX21lcmdlLlBhcnNlRnJvbVN0cmluZyhidWZmZXIpOworCisgIC8vIFJlcXVpcmVkIGFuZCBvcHRpb25hbCBmaWVsZHMgc2hvdWxkIGJlIG1lcmdlZC4KKyAgRXhwZWN0TWVzc2FnZU1lcmdlZChwYXJzaW5nX21lcmdlLnJlcXVpcmVkX2FsbF90eXBlcygpKTsKKyAgRXhwZWN0TWVzc2FnZU1lcmdlZChwYXJzaW5nX21lcmdlLm9wdGlvbmFsX2FsbF90eXBlcygpKTsKKyAgRXhwZWN0TWVzc2FnZU1lcmdlZCgKKyAgICAgIHBhcnNpbmdfbWVyZ2Uub3B0aW9uYWxncm91cCgpLm9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcygpKTsKKyAgRXhwZWN0TWVzc2FnZU1lcmdlZCgKKyAgICAgIHBhcnNpbmdfbWVyZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlOjpvcHRpb25hbF9leHQpKTsKKworICAvLyBSZXBlYXRlZCBmaWVsZHMgc2hvdWxkIG5vdCBiZSBtZXJnZWQuCisgIEVYUEVDVF9FUSgzLCBwYXJzaW5nX21lcmdlLnJlcGVhdGVkX2FsbF90eXBlc19zaXplKCkpOworICBFWFBFQ1RfRVEoMywgcGFyc2luZ19tZXJnZS5yZXBlYXRlZGdyb3VwX3NpemUoKSk7CisgIEVYUEVDVF9FUSgzLCBwYXJzaW5nX21lcmdlLkV4dGVuc2lvblNpemUoCisgICAgICB1bml0dGVzdDo6VGVzdFBhcnNpbmdNZXJnZTo6cmVwZWF0ZWRfZXh0KSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIE1lcmdlRnJvbSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBkZXN0OworCisgIC8vIE9wdGlvbmFsIGZpZWxkcworICBzb3VyY2Uuc2V0X29wdGlvbmFsX2ludDMyKDEpOyAgLy8gb25seSBzb3VyY2UKKyAgc291cmNlLnNldF9vcHRpb25hbF9pbnQ2NCgyKTsgIC8vIGJvdGggc291cmNlIGFuZCBkZXN0CisgIGRlc3Quc2V0X29wdGlvbmFsX2ludDY0KDMpOworICBkZXN0LnNldF9vcHRpb25hbF91aW50MzIoNCk7ICAgLy8gb25seSBkZXN0CisKKyAgLy8gT3B0aW9uYWwgZmllbGRzIHdpdGggZGVmYXVsdHMKKyAgc291cmNlLnNldF9kZWZhdWx0X2ludDMyKDEzKTsgIC8vIG9ubHkgc291cmNlCisgIHNvdXJjZS5zZXRfZGVmYXVsdF9pbnQ2NCgxNCk7ICAvLyBib3RoIHNvdXJjZSBhbmQgZGVzdAorICBkZXN0LnNldF9kZWZhdWx0X2ludDY0KDE1KTsKKyAgZGVzdC5zZXRfZGVmYXVsdF91aW50MzIoMTYpOyAgIC8vIG9ubHkgZGVzdAorCisgIC8vIFJlcGVhdGVkIGZpZWxkcworICBzb3VyY2UuYWRkX3JlcGVhdGVkX2ludDMyKDUpOyAgLy8gb25seSBzb3VyY2UKKyAgc291cmNlLmFkZF9yZXBlYXRlZF9pbnQzMig2KTsKKyAgc291cmNlLmFkZF9yZXBlYXRlZF9pbnQ2NCg3KTsgIC8vIGJvdGggc291cmNlIGFuZCBkZXN0CisgIHNvdXJjZS5hZGRfcmVwZWF0ZWRfaW50NjQoOCk7CisgIGRlc3QuYWRkX3JlcGVhdGVkX2ludDY0KDkpOworICBkZXN0LmFkZF9yZXBlYXRlZF9pbnQ2NCgxMCk7CisgIGRlc3QuYWRkX3JlcGVhdGVkX3VpbnQzMigxMSk7ICAvLyBvbmx5IGRlc3QKKyAgZGVzdC5hZGRfcmVwZWF0ZWRfdWludDMyKDEyKTsKKworICBkZXN0Lk1lcmdlRnJvbShzb3VyY2UpOworCisgIC8vIE9wdGlvbmFsIGZpZWxkczogc291cmNlIG92ZXJ3cml0ZXMgZGVzdCBpZiBzb3VyY2UgaXMgc3BlY2lmaWVkCisgIEVYUEVDVF9FUSgxLCBkZXN0Lm9wdGlvbmFsX2ludDMyKCkpOyAgLy8gb25seSBzb3VyY2U6IHVzZSBzb3VyY2UKKyAgRVhQRUNUX0VRKDIsIGRlc3Qub3B0aW9uYWxfaW50NjQoKSk7ICAvLyBzb3VyY2UgYW5kIGRlc3Q6IHVzZSBzb3VyY2UKKyAgRVhQRUNUX0VRKDQsIGRlc3Qub3B0aW9uYWxfdWludDMyKCkpOyAgLy8gb25seSBkZXN0OiB1c2UgZGVzdAorICBFWFBFQ1RfRVEoMCwgZGVzdC5vcHRpb25hbF91aW50NjQoKSk7ICAvLyBuZWl0aGVyOiB1c2UgZGVmYXVsdAorCisgIC8vIE9wdGlvbmFsIGZpZWxkcyB3aXRoIGRlZmF1bHRzCisgIEVYUEVDVF9FUSgxMywgZGVzdC5kZWZhdWx0X2ludDMyKCkpOyAgLy8gb25seSBzb3VyY2U6IHVzZSBzb3VyY2UKKyAgRVhQRUNUX0VRKDE0LCBkZXN0LmRlZmF1bHRfaW50NjQoKSk7ICAvLyBzb3VyY2UgYW5kIGRlc3Q6IHVzZSBzb3VyY2UKKyAgRVhQRUNUX0VRKDE2LCBkZXN0LmRlZmF1bHRfdWludDMyKCkpOyAgLy8gb25seSBkZXN0OiB1c2UgZGVzdAorICBFWFBFQ1RfRVEoNDQsIGRlc3QuZGVmYXVsdF91aW50NjQoKSk7ICAvLyBuZWl0aGVyOiB1c2UgZGVmYXVsdAorCisgIC8vIFJlcGVhdGVkIGZpZWxkczogY29uY2F0ZW5hdGUgc291cmNlIG9udG8gdGhlIGVuZCBvZiBkZXN0CisgIEFTU0VSVF9FUSgyLCBkZXN0LnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSg1LCBkZXN0LnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKDYsIGRlc3QucmVwZWF0ZWRfaW50MzIoMSkpOworICBBU1NFUlRfRVEoNCwgZGVzdC5yZXBlYXRlZF9pbnQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoOSwgIGRlc3QucmVwZWF0ZWRfaW50NjQoMCkpOworICBFWFBFQ1RfRVEoMTAsIGRlc3QucmVwZWF0ZWRfaW50NjQoMSkpOworICBFWFBFQ1RfRVEoNywgIGRlc3QucmVwZWF0ZWRfaW50NjQoMikpOworICBFWFBFQ1RfRVEoOCwgIGRlc3QucmVwZWF0ZWRfaW50NjQoMykpOworICBBU1NFUlRfRVEoMiwgZGVzdC5yZXBlYXRlZF91aW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDExLCBkZXN0LnJlcGVhdGVkX3VpbnQzMigwKSk7CisgIEVYUEVDVF9FUSgxMiwgZGVzdC5yZXBlYXRlZF91aW50MzIoMSkpOworICBBU1NFUlRfRVEoMCwgZGVzdC5yZXBlYXRlZF91aW50NjRfc2l6ZSgpKTsKK30KKworVEVTVChNZXNzYWdlRmFjdG9yeVRlc3QsIEdlbmVyYXRlZEZhY3RvcnlMb29rdXApIHsKKyAgRVhQRUNUX0VRKAorICAgIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLT5HZXRQcm90b3R5cGUoCisgICAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpLAorICAgICZwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitURVNUKE1lc3NhZ2VGYWN0b3J5VGVzdCwgR2VuZXJhdGVkRmFjdG9yeVVua25vd25UeXBlKSB7CisgIC8vIENvbnN0cnVjdCBhIG5ldyBkZXNjcmlwdG9yLgorICBEZXNjcmlwdG9yUG9vbCBwb29sOworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgIGZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworICBmaWxlLmFkZF9tZXNzYWdlX3R5cGUoKS0+c2V0X25hbWUoIkZvbyIpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gcG9vbC5CdWlsZEZpbGUoZmlsZSktPm1lc3NhZ2VfdHlwZSgwKTsKKworICAvLyBUcnlpbmcgdG8gY29uc3RydWN0IGl0IHNob3VsZCByZXR1cm4gTlVMTC4KKyAgRVhQRUNUX1RSVUUoCisgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZShkZXNjcmlwdG9yKSA9PSBOVUxMKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGIyYTZlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oCkBAIC0wLDAgKzEsMTY0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBoZWFkZXIgZmlsZSBkZWZpbmVzIGFuIGludGVybmFsIGNsYXNzIHRoYXQgZW5jYXBzdWxhdGVzIGludGVybmFsIG1lc3NhZ2UKKy8vIG1ldGFkYXRhIChVbmtub3duLWZpZWxkIHNldCwgQXJlbmEgcG9pbnRlciwgLi4uKSBhbmQgYWxsb3dzIGl0cworLy8gcmVwcmVzZW50YXRpb24gdG8gYmUgbWFkZSBtb3JlIHNwYWNlLWVmZmljaWVudCB2aWEgdmFyaW91cyBvcHRpbWl6YXRpb25zLgorLy8KKy8vIE5vdGUgdGhhdCB0aGlzIGlzIGRpc3RpbmN0IGZyb20gZ29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEsIHdoaWNoIGVuY2Fwc3VsYXRlcworLy8gRGVzY3JpcHRvciBhbmQgUmVmbGVjdGlvbiBwb2ludGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTUVUQURBVEFfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NRVRBREFUQV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVGhpcyBpcyB0aGUgcmVwcmVzZW50YXRpb24gZm9yIG1lc3NhZ2VzIHRoYXQgc3VwcG9ydCBhcmVuYSBhbGxvY2F0aW9uLiBJdAorLy8gdXNlcyBhIHRhZ2dlZCBwb2ludGVyIHRvIGVpdGhlciBzdG9yZSB0aGUgQXJlbmEgcG9pbnRlciwgaWYgdGhlcmUgYXJlIG5vCisvLyB1bmtub3duIGZpZWxkcywgb3IgYSBwb2ludGVyIHRvIGEgYmxvY2sgb2YgbWVtb3J5IHdpdGggYm90aCB0aGUgQXJlbmEgcG9pbnRlcgorLy8gYW5kIHRoZSBVbmtub3duRmllbGRTZXQsIGlmIHRoZXJlIGFyZSB1bmtub3duIGZpZWxkcy4gVGhpcyBvcHRpbWl6YXRpb24KKy8vIGFsbG93cyBmb3IgInplcm8tb3ZlcmhlYWQiIHN0b3JhZ2Ugb2YgdGhlIEFyZW5hIHBvaW50ZXIsIHJlbGF0aXZlIHRvIHRoZQorLy8gYWJvdmUgYmFzZWxpbmUgaW1wbGVtZW50YXRpb24uCisvLworLy8gVGhlIHRhZ2dlZCBwb2ludGVyIHVzZXMgdGhlIExTQiB0byBkaXNhbWJpZ3VhdGUgY2FzZXMsIGFuZCB1c2VzIGJpdCAwID09IDAgdG8KKy8vIGluZGljYXRlIGFuIGFyZW5hIHBvaW50ZXIgYW5kIGJpdCAwID09IDEgdG8gaW5kaWNhdGUgYSBVRlMrQXJlbmEtY29udGFpbmVyCisvLyBwb2ludGVyLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgeworIHB1YmxpYzoKKyAgSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSgpIDogcHRyXyhOVUxMKSB7fQorICBleHBsaWNpdCBJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKEFyZW5hKiBhcmVuYSkKKyAgICAgIDogcHRyXyAoYXJlbmEpIHt9CisKKyAgfkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEoKSB7CisgICAgaWYgKGhhdmVfdW5rbm93bl9maWVsZHMoKSAmJiBhcmVuYSgpID09IE5VTEwpIHsKKyAgICAgIGRlbGV0ZSBQdHJWYWx1ZTxDb250YWluZXI+KCk7CisgICAgfQorICAgIHB0cl8gPSBOVUxMOworICB9CisKKyAgaW5saW5lIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdAorICAgICAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHsKKyAgICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoaGF2ZV91bmtub3duX2ZpZWxkcygpKSkgeworICAgICAgcmV0dXJuIFB0clZhbHVlPENvbnRhaW5lcj4oKS0+dW5rbm93bl9maWVsZHNfOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gKlVua25vd25GaWVsZFNldDo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICAgIH0KKyAgfQorCisgIGlubGluZSBVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgeworICAgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKGhhdmVfdW5rbm93bl9maWVsZHMoKSkpIHsKKyAgICAgIHJldHVybiAmUHRyVmFsdWU8Q29udGFpbmVyPigpLT51bmtub3duX2ZpZWxkc187CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBtdXRhYmxlX3Vua25vd25fZmllbGRzX3Nsb3coKTsKKyAgICB9CisgIH0KKworICBpbmxpbmUgQXJlbmEqIGFyZW5hKCkgY29uc3QgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHsKKyAgICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoaGF2ZV91bmtub3duX2ZpZWxkcygpKSkgeworICAgICAgcmV0dXJuIFB0clZhbHVlPENvbnRhaW5lcj4oKS0+YXJlbmFfOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gUHRyVmFsdWU8QXJlbmE+KCk7CisgICAgfQorICB9CisKKyAgaW5saW5lIGJvb2wgaGF2ZV91bmtub3duX2ZpZWxkcygpIGNvbnN0IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSB7CisgICAgcmV0dXJuIFB0clRhZygpID09IGtUYWdDb250YWluZXI7CisgIH0KKworICBpbmxpbmUgdm9pZCBTd2FwKEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEqIG90aGVyKSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgeworICAgIC8vIFNlbWFudGljcyBoZXJlIGFyZSB0aGF0IHdlIHN3YXAgb25seSB0aGUgdW5rbm93biBmaWVsZHMsIG5vdCB0aGUgYXJlbmEKKyAgICAvLyBwb2ludGVyLiBXZSBjYW5ub3Qgc2ltcGx5IHN3YXAgcHRyXyB3aXRoIG90aGVyLT5wdHJfIGJlY2F1c2Ugd2UgbmVlZCB0bworICAgIC8vIG1haW50YWluIG91ciBvd24gYXJlbmEgcHRyLiBBbHNvLCBvdXIgcHRyXyBhbmQgb3RoZXIncyBwdHJfIG1heSBiZSBpbgorICAgIC8vIGRpZmZlcmVudCBzdGF0ZXMgKGRpcmVjdCBhcmVuYSBwb2ludGVyIHZzLiBjb250YWluZXIgd2l0aCBVRlMpIHNvIHdlCisgICAgLy8gY2Fubm90IHNpbXBseSBzd2FwIHB0cl8gYW5kIHRoZW4gcmVzdG9yZSB0aGUgYXJlbmEgcG9pbnRlcnMuIFdlIHJldXNlCisgICAgLy8gVUZTJ3Mgc3dhcCBpbXBsZW1lbnRhdGlvbiBpbnN0ZWFkLgorICAgIGlmIChoYXZlX3Vua25vd25fZmllbGRzKCkgfHwgb3RoZXItPmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5Td2FwKG90aGVyLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkpOworICAgIH0KKyAgfQorCisgIGlubGluZSB2b2lkKiByYXdfYXJlbmFfcHRyKCkgY29uc3QgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHsKKyAgICByZXR1cm4gcHRyXzsKKyAgfQorCisgcHJpdmF0ZToKKyAgdm9pZCogcHRyXzsKKworICAvLyBUYWdnZWQgcG9pbnRlciBpbXBsZW1lbnRhdGlvbi4KKyAgZW51bSB7CisgICAgLy8gcHRyXyBpcyBhbiBBcmVuYSouCisgICAga1RhZ0FyZW5hID0gMCwKKyAgICAvLyBwdHJfIGlzIGEgQ29udGFpbmVyKi4KKyAgICBrVGFnQ29udGFpbmVyID0gMSwKKyAgfTsKKyAgc3RhdGljIGNvbnN0IGludHB0cl90IGtQdHJUYWdNYXNrID0gMTsKKyAgc3RhdGljIGNvbnN0IGludHB0cl90IGtQdHJWYWx1ZU1hc2sgPSB+a1B0clRhZ01hc2s7CisKKyAgLy8gQWNjZXNzb3JzIGZvciBwb2ludGVyIHRhZyBhbmQgcG9pbnRlciB2YWx1ZS4KKyAgaW5saW5lIGludCBQdHJUYWcoKSBjb25zdCBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGludHB0cl90PihwdHJfKSAmIGtQdHJUYWdNYXNrOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gVCogUHRyVmFsdWUoKSBjb25zdCB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VCo+KAorICAgICAgICByZWludGVycHJldF9jYXN0PGludHB0cl90PihwdHJfKSAmIGtQdHJWYWx1ZU1hc2spOworICB9CisKKyAgLy8gSWYgcHRyXydzIHRhZyBpcyBrVGFnQ29udGFpbmVyLCBpdCBwb2ludHMgdG8gYW4gaW5zdGFuY2Ugb2YgdGhpcyBzdHJ1Y3QuCisgIHN0cnVjdCBDb250YWluZXIgeworICAgIFVua25vd25GaWVsZFNldCB1bmtub3duX2ZpZWxkc187CisgICAgQXJlbmEqIGFyZW5hXzsKKyAgfTsKKworICBVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHNfc2xvdygpIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgeworICAgIEFyZW5hKiBteV9hcmVuYSA9IGFyZW5hKCk7CisgICAgQ29udGFpbmVyKiBjb250YWluZXIgPSBBcmVuYTo6Q3JlYXRlPENvbnRhaW5lcj4obXlfYXJlbmEpOworICAgIHB0cl8gPSByZWludGVycHJldF9jYXN0PHZvaWQqPigKKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxpbnRwdHJfdD4oY29udGFpbmVyKSB8IGtUYWdDb250YWluZXIpOworICAgIGNvbnRhaW5lci0+YXJlbmFfID0gbXlfYXJlbmE7CisgICAgcmV0dXJuICYoY29udGFpbmVyLT51bmtub3duX2ZpZWxkc18pOworICB9Cit9OworCisvLyBUZW1wb3JhcnkgY29tcGF0aWJpbGl0eSB0eXBlZGVmLiBSZW1vdmUgb25jZSB0aGlzIGlzIHJlbGVhc2VkIGluIGNvbXBvbmVudHMKKy8vIGFuZCB1cGIgQ0wgaXMgc3VibWl0dGVkLgordHlwZWRlZiBJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIEludGVybmFsTWV0YWRhdGE7CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01FVEFEQVRBX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9ub19maWVsZF9wcmVzZW5jZV90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9ub19maWVsZF9wcmVzZW5jZV90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiN2IzMWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL25vX2ZpZWxkX3ByZXNlbmNlX3Rlc3QuY2MKQEAgLTAsMCArMSw1MzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2ZpZWxkX3ByZXNlbmNlLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7CisKKy8vIEhlbHBlcjogY2hlY2tzIHRoYXQgYWxsIGZpZWxkcyBoYXZlIGRlZmF1bHQgKHplcm8vZW1wdHkpIHZhbHVlcy4KK3ZvaWQgQ2hlY2tEZWZhdWx0VmFsdWVzKAorICAgIGNvbnN0IHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyYgbSkgeworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfaW50NjQoKSk7CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX3VpbnQzMigpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfdWludDY0KCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9zaW50MzIoKSk7CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX3NpbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfZml4ZWQzMigpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9mbG9hdCgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfZG91YmxlKCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG0ub3B0aW9uYWxfYm9vbCgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfc3RyaW5nKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfYnl0ZXMoKS5zaXplKCkpOworCisgIEVYUEVDVF9FUShmYWxzZSwgbS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIC8vIGFjY2Vzc29yIGZvciBtZXNzYWdlIGZpZWxkcyByZXR1cm5zIGRlZmF1bHQgaW5zdGFuY2Ugd2hlbiBub3QgcHJlc2VudAorICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG0uaGFzX29wdGlvbmFsX3Byb3RvMl9tZXNzYWdlKCkpOworICAvLyBFbWJlZGRlZCBwcm90bzIgbWVzc2FnZXMgc3RpbGwgaGF2ZSBwcm90bzIgc2VtYW50aWNzLCBlLmcuIG5vbi16ZXJvIGRlZmF1bHQKKyAgLy8gdmFsdWVzLiBIZXJlIHRoZSBzdWJtZXNzYWdlIGlzIG5vdCBwcmVzZW50IGJ1dCBpdHMgYWNjZXNzb3IgcmV0dXJucyB0aGUKKyAgLy8gZGVmYXVsdCBpbnN0YW5jZS4KKyAgRVhQRUNUX0VRKDQxLCBtLm9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlKCkuZGVmYXVsdF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtLmhhc19vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9GT08sCisgICAgICAgICAgICBtLm9wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6Rk9SRUlHTl9GT08sCisgICAgICAgICAgICBtLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKworCisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX3VpbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF91aW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfc2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX3NpbnQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9maXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfc2ZpeGVkMzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfZmxvYXRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfZG91YmxlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2Jvb2xfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2J5dGVzX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9wcm90bzJfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9mb3JlaWduX2VudW1fc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok9ORU9GX0ZJRUxEX05PVF9TRVQsCisgICAgICAgICAgICBtLm9uZW9mX2ZpZWxkX2Nhc2UoKSk7Cit9CisKK3ZvaWQgRmlsbFZhbHVlcyhwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG0pIHsKKyAgbS0+c2V0X29wdGlvbmFsX2ludDMyKDEwMCk7CisgIG0tPnNldF9vcHRpb25hbF9pbnQ2NCgxMDEpOworICBtLT5zZXRfb3B0aW9uYWxfdWludDMyKDEwMik7CisgIG0tPnNldF9vcHRpb25hbF91aW50NjQoMTAzKTsKKyAgbS0+c2V0X29wdGlvbmFsX3NpbnQzMigxMDQpOworICBtLT5zZXRfb3B0aW9uYWxfc2ludDY0KDEwNSk7CisgIG0tPnNldF9vcHRpb25hbF9maXhlZDMyKDEwNik7CisgIG0tPnNldF9vcHRpb25hbF9maXhlZDY0KDEwNyk7CisgIG0tPnNldF9vcHRpb25hbF9zZml4ZWQzMigxMDgpOworICBtLT5zZXRfb3B0aW9uYWxfc2ZpeGVkNjQoMTA5KTsKKyAgbS0+c2V0X29wdGlvbmFsX2Zsb2F0KDExMC4wKTsKKyAgbS0+c2V0X29wdGlvbmFsX2RvdWJsZSgxMTEuMCk7CisgIG0tPnNldF9vcHRpb25hbF9ib29sKHRydWUpOworICBtLT5zZXRfb3B0aW9uYWxfc3RyaW5nKCJhc2RmIik7CisgIG0tPnNldF9vcHRpb25hbF9ieXRlcygiamtsOyIpOworICBtLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig0Mik7CisgIG0tPm11dGFibGVfb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKDQzKTsKKyAgbS0+bXV0YWJsZV9vcHRpb25hbF9wcm90bzJfbWVzc2FnZSgpLT5zZXRfb3B0aW9uYWxfaW50MzIoNDQpOworICBtLT5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0oCisgICAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9CQVopOworICBtLT5zZXRfb3B0aW9uYWxfZm9yZWlnbl9lbnVtKAorICAgICAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6Rk9SRUlHTl9CQVopOworICBtLT5tdXRhYmxlX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDUpOworICBtLT5hZGRfcmVwZWF0ZWRfaW50MzIoMTAwKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2ludDY0KDEwMSk7CisgIG0tPmFkZF9yZXBlYXRlZF91aW50MzIoMTAyKTsKKyAgbS0+YWRkX3JlcGVhdGVkX3VpbnQ2NCgxMDMpOworICBtLT5hZGRfcmVwZWF0ZWRfc2ludDMyKDEwNCk7CisgIG0tPmFkZF9yZXBlYXRlZF9zaW50NjQoMTA1KTsKKyAgbS0+YWRkX3JlcGVhdGVkX2ZpeGVkMzIoMTA2KTsKKyAgbS0+YWRkX3JlcGVhdGVkX2ZpeGVkNjQoMTA3KTsKKyAgbS0+YWRkX3JlcGVhdGVkX3NmaXhlZDMyKDEwOCk7CisgIG0tPmFkZF9yZXBlYXRlZF9zZml4ZWQ2NCgxMDkpOworICBtLT5hZGRfcmVwZWF0ZWRfZmxvYXQoMTEwLjApOworICBtLT5hZGRfcmVwZWF0ZWRfZG91YmxlKDExMS4wKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2Jvb2wodHJ1ZSk7CisgIG0tPmFkZF9yZXBlYXRlZF9zdHJpbmcoImFzZGYiKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2J5dGVzKCJqa2w7Iik7CisgIG0tPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDYpOworICBtLT5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKDQ3KTsKKyAgbS0+YWRkX3JlcGVhdGVkX3Byb3RvMl9tZXNzYWdlKCktPnNldF9vcHRpb25hbF9pbnQzMig0OCk7CisgIG0tPmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSgKKyAgICAgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWik7CisgIG0tPmFkZF9yZXBlYXRlZF9mb3JlaWduX2VudW0oCisgICAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpGT1JFSUdOX0JBWik7CisgIG0tPmFkZF9yZXBlYXRlZF9sYXp5X21lc3NhZ2UoKS0+c2V0X2JiKDQ5KTsKKworICBtLT5zZXRfb25lb2ZfdWludDMyKDEpOworICBtLT5tdXRhYmxlX29uZW9mX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig1MCk7CisgIG0tPnNldF9vbmVvZl9zdHJpbmcoInRlc3QiKTsgIC8vIG9ubHkgdGhpcyBvbmUgcmVtYWlucyBzZXQKK30KKwordm9pZCBDaGVja05vbkRlZmF1bHRWYWx1ZXMoCitjb25zdCBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG0pIHsKKyAgRVhQRUNUX0VRKDEwMCwgbS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDEwMSwgbS5vcHRpb25hbF9pbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKDEwMiwgbS5vcHRpb25hbF91aW50MzIoKSk7CisgIEVYUEVDVF9FUSgxMDMsIG0ub3B0aW9uYWxfdWludDY0KCkpOworICBFWFBFQ1RfRVEoMTA0LCBtLm9wdGlvbmFsX3NpbnQzMigpKTsKKyAgRVhQRUNUX0VRKDEwNSwgbS5vcHRpb25hbF9zaW50NjQoKSk7CisgIEVYUEVDVF9FUSgxMDYsIG0ub3B0aW9uYWxfZml4ZWQzMigpKTsKKyAgRVhQRUNUX0VRKDEwNywgbS5vcHRpb25hbF9maXhlZDY0KCkpOworICBFWFBFQ1RfRVEoMTA4LCBtLm9wdGlvbmFsX3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoMTA5LCBtLm9wdGlvbmFsX3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRVEoMTEwLjAsIG0ub3B0aW9uYWxfZmxvYXQoKSk7CisgIEVYUEVDVF9FUSgxMTEuMCwgbS5vcHRpb25hbF9kb3VibGUoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtLm9wdGlvbmFsX2Jvb2woKSk7CisgIEVYUEVDVF9FUSgiYXNkZiIsIG0ub3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoImprbDsiLCBtLm9wdGlvbmFsX2J5dGVzKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSg0MiwgbS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoNDMsIG0ub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkuYygpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG0uaGFzX29wdGlvbmFsX3Byb3RvMl9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoNDQsIG0ub3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UoKS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWiwKKyAgICAgICAgICAgIG0ub3B0aW9uYWxfbmVzdGVkX2VudW0oKSk7CisgIEVYUEVDVF9FUShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpGT1JFSUdOX0JBWiwKKyAgICAgICAgICAgIG0ub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoNDUsIG0ub3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMCwgbS5yZXBlYXRlZF9pbnQzMigwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMDEsIG0ucmVwZWF0ZWRfaW50NjQoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF91aW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMiwgbS5yZXBlYXRlZF91aW50MzIoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF91aW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMywgbS5yZXBlYXRlZF91aW50NjQoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9zaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwNCwgbS5yZXBlYXRlZF9zaW50MzIoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9zaW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwNSwgbS5yZXBlYXRlZF9zaW50NjQoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9maXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMDYsIG0ucmVwZWF0ZWRfZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwNywgbS5yZXBlYXRlZF9maXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfc2ZpeGVkMzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwOCwgbS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMDksIG0ucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9mbG9hdF9zaXplKCkpOworICBFWFBFQ1RfRVEoMTEwLjAsIG0ucmVwZWF0ZWRfZmxvYXQoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDExMS4wLCBtLnJlcGVhdGVkX2RvdWJsZSgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2Jvb2xfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG0ucmVwZWF0ZWRfYm9vbCgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoImFzZGYiLCBtLnJlcGVhdGVkX3N0cmluZygwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2J5dGVzX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiamtsOyIsIG0ucmVwZWF0ZWRfYnl0ZXMoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNDYsIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNDcsIG0ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSg0OCwgbS5yZXBlYXRlZF9wcm90bzJfbWVzc2FnZSgwKS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWiwKKyAgICAgICAgICAgIG0ucmVwZWF0ZWRfbmVzdGVkX2VudW0oMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9mb3JlaWduX2VudW1fc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OkZPUkVJR05fQkFaLAorICAgICAgICAgICAgbS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9sYXp5X21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQ5LCBtLnJlcGVhdGVkX2xhenlfbWVzc2FnZSgwKS5iYigpKTsKKworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprT25lb2ZTdHJpbmcsCisgICAgICAgICAgICBtLm9uZW9mX2ZpZWxkX2Nhc2UoKSk7CisgIEVYUEVDVF9FUSgidGVzdCIsIG0ub25lb2Zfc3RyaW5nKCkpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIEJhc2ljTWVzc2FnZVRlc3QpIHsKKyAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIC8vIENoZWNrIGRlZmF1bHQgdmFsdWVzLCBmaWxsIGFsbCBmaWVsZHMsIGNoZWNrIHZhbHVlcy4gV2UganVzdCB3YW50IHRvCisgIC8vIGV4ZXJjaXNlIHRoZSBiYXNpYyBnZXR0ZXJzL3NldHRlciBwYXRocyBoZXJlIHRvIG1ha2Ugc3VyZSBubworICAvLyBmaWVsZC1wcmVzZW5jZS1yZWxhdGVkIGNoYW5nZXMgYnJva2UgdGhlc2UuCisgIENoZWNrRGVmYXVsdFZhbHVlcyhtZXNzYWdlKTsKKyAgRmlsbFZhbHVlcygmbWVzc2FnZSk7CisgIENoZWNrTm9uRGVmYXVsdFZhbHVlcyhtZXNzYWdlKTsKKworICAvLyBDbGVhcigpIHNob3VsZCBiZSBlcXVpdmFsZW50IHRvIGdldHRpbmcgYSBmcmVzaGx5LWNvbnN0cnVjdGVkIG1lc3NhZ2UuCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgQ2hlY2tEZWZhdWx0VmFsdWVzKG1lc3NhZ2UpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIE1lc3NhZ2VGaWVsZFByZXNlbmNlVGVzdCkgeworICAvLyBjaGVjayB0aGF0IHByZXNlbmNlIHN0aWxsIHdvcmtzIHByb3Blcmx5IGZvciBtZXNzYWdlIGZpZWxkcy4KKyAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIC8vIEdldHRlciBzaG91bGQgZmV0Y2ggZGVmYXVsdCBpbnN0YW5jZSwgYW5kIG5vdCBjYXVzZSB0aGUgZmllbGQgdG8gYmVjb21lCisgIC8vIHByZXNlbnQuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIG1lc3NhZ2UuY2xlYXJfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKworICAvLyBMaWtld2lzZSBmb3IgYSBsYXp5IG1lc3NhZ2UgZmllbGQuCisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkpOworICAvLyBHZXR0ZXIgc2hvdWxkIGZldGNoIGRlZmF1bHQgaW5zdGFuY2UsIGFuZCBub3QgY2F1c2UgdGhlIGZpZWxkIHRvIGJlY29tZQorICAvLyBwcmVzZW50LgorICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS5iYigpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKyAgbWVzc2FnZS5jbGVhcl9vcHRpb25hbF9sYXp5X21lc3NhZ2UoKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisKKyAgLy8gVGVzdCBmaWVsZCBwcmVzZW5jZSBvZiBhIG1lc3NhZ2UgZmllbGQgb24gdGhlIGRlZmF1bHQgaW5zdGFuY2UuCisgIEVYUEVDVF9FUShmYWxzZSwgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjoKKyAgICAgICAgICAgIGRlZmF1bHRfaW5zdGFuY2UoKS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7Cit9CisKK1RFU1QoTm9GaWVsZFByZXNlbmNlVGVzdCwgUmVmbGVjdGlvbkhhc0ZpZWxkVGVzdCkgeworICAvLyBjaGVjayB0aGF0IEhhc0ZpZWxkIHJlcG9ydHMgdHJ1ZSBvbiBhbGwgc2NhbGFyIGZpZWxkcy4gQ2hlY2sgdGhhdCBpdAorICAvLyBiZWhhdmVzIHByb3Blcmx5IGZvciBtZXNzYWdlIGZpZWxkcy4KKworICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogciA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgLy8gQ2hlY2sgaW5pdGlhbCBzdGF0ZTogc2NhbGFycyBub3QgcHJlc2VudCAoZHVlIHRvIG5lZWQgdG8gYmUgY29uc2lzdGVudCB3aXRoCisgIC8vIE1lcmdlRnJvbSgpKSwgbWVzc2FnZSBmaWVsZHMgbm90IHByZXNlbnQsIG9uZW9mcyBub3QgcHJlc2VudC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzYy0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSBjb250aW51ZTsKKyAgICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSk7CisgIH0KKworICAvLyBUZXN0IGZpZWxkIHByZXNlbmNlIG9mIGEgbWVzc2FnZSBmaWVsZCBvbiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBtc2dfZmllbGQgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKAorICAgICAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjoKKyAgICAgIGRlZmF1bHRfaW5zdGFuY2UoKSwgbXNnX2ZpZWxkKSk7CisKKyAgLy8gRmlsbCBhbGwgZmllbGRzLCBleHBlY3QgZXZlcnl0aGluZyB0byByZXBvcnQgdHJ1ZSAoY2hlY2sgb25lb2ZzIGJlbG93KS4KKyAgRmlsbFZhbHVlcygmbWVzc2FnZSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2MtPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSB8fCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgaWYgKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSAhPSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnM6OlNUUklORykgeworICAgICAgY29udGludWU7CisgICAgfQorICAgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZCkpOworICB9CisKKyAgbWVzc2FnZS5DbGVhcigpOworCisgIC8vIENoZWNrIHplcm8vZW1wdHktbWVhbnMtbm90LXByZXNlbnQgc2VtYW50aWNzLgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2ludDMyID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX2ludDMyIik7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGRfZG91YmxlID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX2RvdWJsZSIpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkX3N0cmluZyA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJvcHRpb25hbF9zdHJpbmciKTsKKworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkX2ludDMyKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGRfZG91YmxlKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGRfc3RyaW5nKSk7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoNDIpOworICBFWFBFQ1RfRVEodHJ1ZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGRfaW50MzIpKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoMCk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGRfaW50MzIpKTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9kb3VibGUoNDIuMCk7CisgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9kb3VibGUpKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfZG91YmxlKDAuMCk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGRfZG91YmxlKSk7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJ0ZXN0Iik7CisgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9zdHJpbmcpKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCIiKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9zdHJpbmcpKTsKK30KKworVEVTVChOb0ZpZWxkUHJlc2VuY2VUZXN0LCBIYXNGaWVsZE9uZW9mc1Rlc3QpIHsKKyAgLy8gY2hlY2sgdGhhdCBIYXNGaWVsZCBiZWhhdmVzIHByb3Blcmx5IGZvciBvbmVvZnMuCisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIHIgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGRlc2Nfb25lb2ZfdWludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgib25lb2ZfdWludDMyIik7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZGVzY19vbmVvZl9uZXN0ZWRfbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm9uZW9mX25lc3RlZF9tZXNzYWdlIik7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZGVzY19vbmVvZl9zdHJpbmcgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJvbmVvZl9zdHJpbmciKTsKKyAgR09PR0xFX0NIRUNLX05PVE5VTEwoZGVzY19vbmVvZl91aW50MzIpOworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChkZXNjX29uZW9mX25lc3RlZF9tZXNzYWdlKTsKKyAgR09PR0xFX0NIRUNLX05PVE5VTEwoZGVzY19vbmVvZl9zdHJpbmcpOworCisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl91aW50MzIpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX25lc3RlZF9tZXNzYWdlKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl9zdHJpbmcpKTsKKworICBtZXNzYWdlLnNldF9vbmVvZl9zdHJpbmcoInRlc3QiKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX3VpbnQzMikpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2ZfbmVzdGVkX21lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2Zfc3RyaW5nKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2ZfdWludDMyKSk7CisgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX25lc3RlZF9tZXNzYWdlKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl9zdHJpbmcpKTsKKworICBtZXNzYWdlLkNsZWFyKCk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl91aW50MzIpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX25lc3RlZF9tZXNzYWdlKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl9zdHJpbmcpKTsKK30KKworVEVTVChOb0ZpZWxkUHJlc2VuY2VUZXN0LCBEb250U2VyaWFsaXplRGVmYXVsdFZhbHVlc1Rlc3QpIHsKKyAgLy8gY2hlY2sgdGhhdCBzZXJpYWxpemVkIGRhdGEgY29udGFpbnMgb25seSBub24temVybyBudW1lcmljIGZpZWxkcy9ub24tZW1wdHkKKyAgLy8gc3RyaW5nL2J5dGUgZmllbGRzLgorICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgc3RyaW5nIG91dHB1dDsKKworICAvLyBBbGwgZGVmYXVsdCB2YWx1ZXMgLT4gbm8gb3V0cHV0LgorICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZvdXRwdXQpOworICBFWFBFQ1RfRVEoMCwgb3V0cHV0LnNpemUoKSk7CisKKyAgLy8gWmVybyB2YWx1ZXMgLT4gc3RpbGwgbm8gb3V0cHV0LgorICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50NjQoMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3VpbnQzMigwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfdWludDY0KDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zaW50MzIoMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3NpbnQ2NCgwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfZml4ZWQzMigwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfZml4ZWQ2NCgwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc2ZpeGVkMzIoMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3NmaXhlZDY0KDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9mbG9hdCgwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfZG91YmxlKDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9ib29sKDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zdHJpbmcoIiIpOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9ieXRlcygiIik7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX25lc3RlZF9lbnVtKAorICAgICAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fRk9PKTsgIC8vIGZpcnN0IGVudW0gZW50cnkKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfZm9yZWlnbl9lbnVtKAorICAgICAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6Rk9SRUlHTl9GT08pOyAgLy8gZmlyc3QgZW51bSBlbnRyeQorCisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJm91dHB1dCk7CisgIEVYUEVDVF9FUSgwLCBvdXRwdXQuc2l6ZSgpKTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMigxKTsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKDIsIG91dHB1dC5zaXplKCkpOworICBFWFBFQ1RfRVEoIlx4MDhceDAxIiwgb3V0cHV0KTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKDAsIG91dHB1dC5zaXplKCkpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIE1lcmdlRnJvbUlmTm9uemVyb1Rlc3QpIHsKKyAgLy8gY2hlY2sgdGhhdCBNZXJnZUZyb20gY29waWVzIGlmIG5vbnplcm8vbm9uZGVmYXVsdCBvbmx5LgorICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgc291cmNlOworICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgZGVzdDsKKworICBkZXN0LnNldF9vcHRpb25hbF9pbnQzMig0Mik7CisgIGRlc3Quc2V0X29wdGlvbmFsX3N0cmluZygidGVzdCIpOworICBzb3VyY2Uuc2V0X29wdGlvbmFsX2ludDMyKDApOworICBzb3VyY2Uuc2V0X29wdGlvbmFsX3N0cmluZygiIik7CisgIC8vIE1lcmdlRnJvbSgpIGNvcGllcyBvbmx5IGlmIHByZXNlbnQgaW4gc2VyaWFsaXphdGlvbiwgaS5lLiwgbm9uLXplcm8uCisgIGRlc3QuTWVyZ2VGcm9tKHNvdXJjZSk7CisgIEVYUEVDVF9FUSg0MiwgZGVzdC5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKCJ0ZXN0IiwgZGVzdC5vcHRpb25hbF9zdHJpbmcoKSk7CisKKyAgc291cmNlLnNldF9vcHRpb25hbF9pbnQzMig4NCk7CisgIHNvdXJjZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJ0ZXN0MiIpOworICBkZXN0Lk1lcmdlRnJvbShzb3VyY2UpOworICBFWFBFQ1RfRVEoODQsIGRlc3Qub3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSgidGVzdDIiLCBkZXN0Lm9wdGlvbmFsX3N0cmluZygpKTsKK30KKworVEVTVChOb0ZpZWxkUHJlc2VuY2VUZXN0LCBJc0luaXRpYWxpemVkVGVzdCkgeworICAvLyBDaGVjayB0aGF0IElzSW5pdGlhbGl6ZWQgd29ya3MgcHJvcGVybHkuCisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RQcm90bzJSZXF1aXJlZCBtZXNzYWdlOworCisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9wcm90bzIoKS0+c2V0X2EoMSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworICBtZXNzYWdlLm11dGFibGVfcHJvdG8yKCktPnNldF9iKDEpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5tdXRhYmxlX3Byb3RvMigpLT5zZXRfYygxKTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKK30KKworVEVTVChOb0ZpZWxkUHJlc2VuY2VUZXN0LCBMYXp5TWVzc2FnZUZpZWxkSGFzQml0KSB7CisgIC8vIENoZWNrIHRoYXQgaGFzLWJpdCBpbnRlcmFjdGlvbiB3aXRoIGxhenkgbWVzc2FnZSB3b3JrcyAoaGFzLWJpdCBiZWZvcmUgYW5kCisgIC8vIGFmdGVyIGxhenkgZGVjb2RlKS4KKyAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIHIgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIpOworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChmaWVsZCk7CisKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGQpKTsKKworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCktPnNldF9iYig0Mik7CisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZCkpOworCisgIC8vIFNlcmlhbGl6ZSBhbmQgcGFyc2Ugd2l0aCBhIG5ldyBtZXNzYWdlIG9iamVjdCBzbyB0aGF0IGxhenkgZmllbGQgb24gbmV3CisgIC8vIG9iamVjdCBpcyBpbiB1bnBhcnNlZCBzdGF0ZS4KKyAgc3RyaW5nIG91dHB1dDsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmb3V0cHV0KTsKKyAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UyOworICBtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcob3V0cHV0KTsKKworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZTIuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UyLCBmaWVsZCkpOworCisgIC8vIEFjY2VzcyBmaWVsZCB0byBmb3JjZSBsYXp5IHBhcnNlLgorICBFWFBFQ1RfRVEoNDIsIG1lc3NhZ2Uub3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlMi5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgci0+SGFzRmllbGQobWVzc2FnZTIsIGZpZWxkKSk7Cit9CisKK1RFU1QoTm9GaWVsZFByZXNlbmNlVGVzdCwgT25lb2ZQcmVzZW5jZSkgeworICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgLy8gb25lb2YgZmllbGRzIHN0aWxsIGhhdmUgZmllbGQgcHJlc2VuY2UgLS0gZW5zdXJlIHRoYXQgdGhpcyBnb2VzIG9uIHRoZSB3aXJlCisgIC8vIGV2ZW4gdGhvdWdoIGl0cyB2YWx1ZSBpcyB0aGUgZW1wdHkgc3RyaW5nLgorICBtZXNzYWdlLnNldF9vbmVvZl9zdHJpbmcoIiIpOworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgIC8vIFRhZzogMTEzIC0tPiB0YWcgaXMgKDExMyA8PCAzKSB8IDIgKGxlbmd0aCBkZWxpbWl0ZWQpID0gOTA2CisgIC8vIHZhcmludDogMHg4YSAweDA3CisgIC8vIExlbmd0aDogMHgwMAorICBFWFBFQ1RfRVEoMywgc2VyaWFsaXplZC5zaXplKCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8Y2hhcj4oMHg4YSksIHNlcmlhbGl6ZWQuYXQoMCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8Y2hhcj4oMHgwNyksIHNlcmlhbGl6ZWQuYXQoMSkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8Y2hhcj4oMHgwMCksIHNlcmlhbGl6ZWQuYXQoMikpOworCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprT25lb2ZTdHJpbmcsCisgICAgICAgICAgICBtZXNzYWdlLm9uZW9mX2ZpZWxkX2Nhc2UoKSk7CisKKyAgLy8gQWxzbyB0ZXN0IGludDMyIGFuZCBlbnVtIGZpZWxkcy4KKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLnNldF9vbmVvZl91aW50MzIoMCk7ICAvLyB3b3VsZCBub3QgZ28gb24gd2lyZSBpZiBvcmRpbmFyeSBmaWVsZC4KKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgIEVYUEVDVF9FUSgzLCBzZXJpYWxpemVkLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a09uZW9mVWludDMyLAorICAgICAgICAgICAgbWVzc2FnZS5vbmVvZl9maWVsZF9jYXNlKCkpOworCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgbWVzc2FnZS5zZXRfb25lb2ZfZW51bShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjoKKyAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9GT08pOyAgLy8gZGVmYXVsdCB2YWx1ZS4KKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgIEVYUEVDVF9FUSgzLCBzZXJpYWxpemVkLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a09uZW9mRW51bSwKKyAgICAgICAgICAgIG1lc3NhZ2Uub25lb2ZfZmllbGRfY2FzZSgpKTsKKworICBtZXNzYWdlLkNsZWFyKCk7CisgIG1lc3NhZ2Uuc2V0X29uZW9mX3N0cmluZygidGVzdCIpOworICBtZXNzYWdlLmNsZWFyX29uZW9mX3N0cmluZygpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9wYWNrYWdlX2luZm8uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvcGFja2FnZV9pbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTM1ZTk2MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcGFja2FnZV9pbmZvLmgKQEAgLTAsMCArMSw2NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBleGlzdHMgc29sZWx5IHRvIGRvY3VtZW50IHRoZSBnb29nbGU6OnByb3RvYnVmIG5hbWVzcGFjZS4KKy8vIEl0IGlzIG5vdCBjb21waWxlZCBpbnRvIGFueXRoaW5nLCBidXQgaXQgbWF5IGJlIHJlYWQgYnkgYW4gYXV0b21hdGVkCisvLyBkb2N1bWVudGF0aW9uIGdlbmVyYXRvci4KKworbmFtZXNwYWNlIGdvb2dsZSB7CisKKy8vIENvcmUgY29tcG9uZW50cyBvZiB0aGUgUHJvdG9jb2wgQnVmZmVycyBydW50aW1lIGxpYnJhcnkuCisvLworLy8gVGhlIGZpbGVzIGluIHRoaXMgcGFja2FnZSByZXByZXNlbnQgdGhlIGNvcmUgb2YgdGhlIFByb3RvY29sIEJ1ZmZlcgorLy8gc3lzdGVtLiAgQWxsIG9mIHRoZW0gYXJlIHBhcnQgb2YgdGhlIGxpYnByb3RvYnVmIGxpYnJhcnkuCisvLworLy8gQSBub3RlIG9uIHRocmVhZC1zYWZldHk6CisvLworLy8gVGhyZWFkLXNhZmV0eSBpbiB0aGUgUHJvdG9jb2wgQnVmZmVyIGxpYnJhcnkgZm9sbG93cyBhIHNpbXBsZSBydWxlOgorLy8gdW5sZXNzIGV4cGxpY2l0bHkgbm90ZWQgb3RoZXJ3aXNlLCBpdCBpcyBhbHdheXMgc2FmZSB0byB1c2UgYW4gb2JqZWN0CisvLyBmcm9tIG11bHRpcGxlIHRocmVhZHMgc2ltdWx0YW5lb3VzbHkgYXMgbG9uZyBhcyB0aGUgb2JqZWN0IGlzIGRlY2xhcmVkCisvLyBjb25zdCBpbiBhbGwgdGhyZWFkcyAob3IsIGl0IGlzIG9ubHkgdXNlZCBpbiB3YXlzIHRoYXQgd291bGQgYmUgYWxsb3dlZAorLy8gaWYgaXQgd2VyZSBkZWNsYXJlZCBjb25zdCkuICBIb3dldmVyLCBpZiBhbiBvYmplY3QgaXMgYWNjZXNzZWQgaW4gb25lCisvLyB0aHJlYWQgaW4gYSB3YXkgdGhhdCB3b3VsZCBub3QgYmUgYWxsb3dlZCBpZiBpdCB3ZXJlIGNvbnN0LCB0aGVuIGl0IGlzCisvLyBub3Qgc2FmZSB0byBhY2Nlc3MgdGhhdCBvYmplY3QgaW4gYW55IG90aGVyIHRocmVhZCBzaW11bHRhbmVvdXNseS4KKy8vCisvLyBQdXQgc2ltcGx5LCByZWFkLW9ubHkgYWNjZXNzIHRvIGFuIG9iamVjdCBjYW4gaGFwcGVuIGluIG11bHRpcGxlIHRocmVhZHMKKy8vIHNpbXVsdGFuZW91c2x5LCBidXQgd3JpdGUgYWNjZXNzIGNhbiBvbmx5IGhhcHBlbiBpbiBhIHNpbmdsZSB0aHJlYWQgYXQKKy8vIGEgdGltZS4KKy8vCisvLyBUaGUgaW1wbGVtZW50YXRpb24gZG9lcyBjb250YWluIHNvbWUgImNvbnN0IiBtZXRob2RzIHdoaWNoIGFjdHVhbGx5IG1vZGlmeQorLy8gdGhlIG9iamVjdCBiZWhpbmQgdGhlIHNjZW5lcyAtLSBlLmcuLCB0byBjYWNoZSByZXN1bHRzIC0tIGJ1dCBpbiB0aGVzZSBjYXNlcworLy8gbXV0ZXggbG9ja2luZyBpcyB1c2VkIHRvIG1ha2UgdGhlIGFjY2VzcyB0aHJlYWQtc2FmZS4KK25hbWVzcGFjZSBwcm90b2J1ZiB7fQorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9wcmVzZXJ2ZV91bmtub3duX2VudW1fdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcHJlc2VydmVfdW5rbm93bl9lbnVtX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWY4NzAzYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcHJlc2VydmVfdW5rbm93bl9lbnVtX3Rlc3QuY2MKQEAgLTAsMCArMSwyODkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bS5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKwordm9pZCBGaWxsTWVzc2FnZSgKKyAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2VQbHVzRXh0cmEqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X2UoCisgICAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2UoCisgICAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3BhY2tlZF9lKAorICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9wYWNrZWRfdW5leHBlY3RlZF9lKAorICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSk7CisgIG1lc3NhZ2UtPnNldF9vbmVvZl9lXzEoCisgICAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKTsKK30KKwordm9pZCBDaGVja01lc3NhZ2UoCisgICAgY29uc3QgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlUGx1c0V4dHJhJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9FUShwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBLAorICAgICAgICAgICAgbWVzc2FnZS5lKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9lX3NpemUoKSk7CisgIEVYUEVDVF9FUShwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBLAorICAgICAgICAgICAgbWVzc2FnZS5yZXBlYXRlZF9lKDApKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEsCisgICAgICAgICAgICBtZXNzYWdlLnJlcGVhdGVkX3BhY2tlZF9lKDApKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX3VuZXhwZWN0ZWRfZV9zaXplKCkpOworICBFWFBFQ1RfRVEocHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSwKKyAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX3VuZXhwZWN0ZWRfZSgwKSk7CisgIEVYUEVDVF9FUShwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBLAorICAgICAgICAgICAgbWVzc2FnZS5vbmVvZl9lXzEoKSk7Cit9CisKK3ZvaWQgQ2hlY2tNZXNzYWdlKAorICAgIGNvbnN0IHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PigKKyAgICAgICAgICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KG1lc3NhZ2UuZSgpKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHN0YXRpY19jYXN0PGludD4oCisgICAgICAgICAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50PihtZXNzYWdlLnJlcGVhdGVkX2UoMCkpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHN0YXRpY19jYXN0PGludD4oCisgICAgICAgICAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50PihtZXNzYWdlLnJlcGVhdGVkX3BhY2tlZF9lKDApKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3BhY2tlZF91bmV4cGVjdGVkX2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHN0YXRpY19jYXN0PGludD4oCisgICAgICAgICAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50PihtZXNzYWdlLnJlcGVhdGVkX3BhY2tlZF91bmV4cGVjdGVkX2UoMCkpKTsKKyAgRVhQRUNUX0VRKHN0YXRpY19jYXN0PGludD4oCisgICAgICAgICAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50PihtZXNzYWdlLm9uZW9mX2VfMSgpKSk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworLy8gVGVzdCB0aGF0IHBhcnNpbmcgcHJlc2VydmVzIGFuIHVua25vd24gdmFsdWUgaW4gdGhlIGVudW0gZmllbGQgYW5kIGRvZXMgbm90CisvLyBwdW50IGl0IHRvIHRoZSBVbmtub3duRmllbGRTZXQuCitURVNUKFByZXNlcnZlVW5rbm93bkVudW1UZXN0LCBQcmVzZXJ2ZVBhcnNlQW5kU2VyaWFsaXplKSB7CisgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZVBsdXNFeHRyYSBvcmlnX21lc3NhZ2U7CisgIEZpbGxNZXNzYWdlKCZvcmlnX21lc3NhZ2UpOworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgb3JpZ19tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2UgbWVzc2FnZTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgQ2hlY2tNZXNzYWdlKG1lc3NhZ2UpOworCisgIHNlcmlhbGl6ZWQuY2xlYXIoKTsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgIEVYUEVDVF9FUSh0cnVlLCBvcmlnX21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgQ2hlY2tNZXNzYWdlKG9yaWdfbWVzc2FnZSk7Cit9CisKKy8vIFRlc3QgdGhhdCByZWZsZWN0aW9uIGJhc2VkIGltcGxlbWVudGF0aW9uIGFsc28ga2VlcHMgdW5rbm93biBlbnVtIHZhbHVlcyBhbmQKKy8vIGRvZXNuJ3QgcHV0IHRoZW0gaW50byBVbmtub3duRmllbGRTZXQuCitURVNUKFByZXNlcnZlVW5rbm93bkVudW1UZXN0LCBQcmVzZXJ2ZVBhcnNlQW5kU2VyaWFsaXplRHluYW1pY01lc3NhZ2UpIHsKKyAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlUGx1c0V4dHJhIG9yaWdfbWVzc2FnZTsKKyAgRmlsbE1lc3NhZ2UoJm9yaWdfbWVzc2FnZSk7CisgIHN0cmluZyBzZXJpYWxpemVkID0gb3JpZ19tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6RHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZT4gbWVzc2FnZShmYWN0b3J5LkdldFByb3RvdHlwZSgKKyAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZTo6ZGVzY3JpcHRvcigpKS0+TmV3KCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgbWVzc2FnZS0+RGlzY2FyZFVua25vd25GaWVsZHMoKTsKKworICBzZXJpYWxpemVkID0gbWVzc2FnZS0+U2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgRVhQRUNUX0VRKHRydWUsIG9yaWdfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBDaGVja01lc3NhZ2Uob3JpZ19tZXNzYWdlKTsKK30KKworLy8gVGVzdCB0aGF0IGZvciBwcm90bzIgbWVzc2FnZXMsIHVua25vd24gdmFsdWVzIGFyZSBpbiB1bmtub3duIGZpZWxkcy4KK1RFU1QoUHJlc2VydmVVbmtub3duRW51bVRlc3QsIFByb3RvMkhpZGVzVW5rbm93blZhbHVlcykgeworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2VQbHVzRXh0cmEgb3JpZ19tZXNzYWdlOworICBGaWxsTWVzc2FnZSgmb3JpZ19tZXNzYWdlKTsKKworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgb3JpZ19tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKworICBwcm90bzJfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2UgbWVzc2FnZTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgLy8gVGhlIGludGVybWVkaWF0ZSBtZXNzYWdlIGhhcyBldmVyeXRoaW5nIGluIGl0cyAidW5rbm93biBmaWVsZHMiLgorICBwcm90bzJfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2UgbWVzc2FnZTIgPSBtZXNzYWdlOworICBtZXNzYWdlMi5EaXNjYXJkVW5rbm93bkZpZWxkcygpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZTIuQnl0ZVNpemUoKSk7CisKKyAgLy8gQnV0IHdoZW4gd2UgcGFzcyBpdCB0byB0aGUgY29ycmVjdCBzdHJ1Y3R1cmUsIGFsbCB2YWx1ZXMgYXJlIHRoZXJlLgorICBzZXJpYWxpemVkLmNsZWFyKCk7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworICBFWFBFQ1RfRVEodHJ1ZSwgb3JpZ19tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIENoZWNrTWVzc2FnZShvcmlnX21lc3NhZ2UpOworfQorCisvLyBTYW1lIGFzIGJlZm9yZSwgZm9yIGEgZHluYW1pYyBtZXNzYWdlLgorVEVTVChQcmVzZXJ2ZVVua25vd25FbnVtVGVzdCwgRHluYW1pY1Byb3RvMkhpZGVzVW5rbm93blZhbHVlcykgeworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2VQbHVzRXh0cmEgb3JpZ19tZXNzYWdlOworICBGaWxsTWVzc2FnZSgmb3JpZ19tZXNzYWdlKTsKKworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgb3JpZ19tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKworICBnb29nbGU6OnByb3RvYnVmOjpEeW5hbWljTWVzc2FnZUZhY3RvcnkgZmFjdG9yeTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlPiBtZXNzYWdlKGZhY3RvcnkuR2V0UHJvdG90eXBlKAorICAgICAgcHJvdG8yX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlOjpkZXNjcmlwdG9yKCkpLT5OZXcoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlLT5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICAvLyBUaGUgaW50ZXJtZWRpYXRlIG1lc3NhZ2UgaGFzIGV2ZXJ5dGhpbmcgaW4gaXRzICJ1bmtub3duIGZpZWxkcyIuCisgIHByb3RvMl9wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZSBtZXNzYWdlMjsKKyAgbWVzc2FnZTIuQ29weUZyb20oKm1lc3NhZ2UpOworICBtZXNzYWdlMi5EaXNjYXJkVW5rbm93bkZpZWxkcygpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZTIuQnl0ZVNpemUoKSk7CisKKyAgLy8gQnV0IHdoZW4gd2UgcGFzcyBpdCB0byB0aGUgY29ycmVjdCBzdHJ1Y3R1cmUsIGFsbCB2YWx1ZXMgYXJlIHRoZXJlLgorICBzZXJpYWxpemVkLmNsZWFyKCk7CisgIG1lc3NhZ2UtPlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKyAgRVhQRUNUX0VRKHRydWUsIG9yaWdfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBDaGVja01lc3NhZ2Uob3JpZ19tZXNzYWdlKTsKK30KKworLy8gVGVzdCB0aGF0IHJlZmxlY3Rpb24gcHJvdmlkZXMgRW51bVZhbHVlRGVzY3JpcHRvcnMgZm9yIHVua25vd24gdmFsdWVzLgorVEVTVChQcmVzZXJ2ZVVua25vd25FbnVtVGVzdCwgRHluYW1pY0VudW1WYWx1ZURlc2NyaXB0b3JzKSB7CisgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZVBsdXNFeHRyYSBvcmlnX21lc3NhZ2U7CisgIEZpbGxNZXNzYWdlKCZvcmlnX21lc3NhZ2UpOworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgb3JpZ19tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2UgbWVzc2FnZTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgQ2hlY2tNZXNzYWdlKG1lc3NhZ2UpOworCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIHIgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZCA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZC0+RmluZEZpZWxkQnlOYW1lKCJlIik7CisKKyAgLy8gVGhpcyBzaG91bGQgZHluYW1pY2FsbHkgY3JlYXRlIGFuIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPSByLT5HZXRFbnVtKG1lc3NhZ2UsIGZpZWxkKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUtPm51bWJlcigpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50Pihwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKSk7CisKKyAgLy8gRmV0Y2hpbmcgdmFsdWUgZm9yIGEgc2Vjb25kIHRpbWUgc2hvdWxkIHJldHVybiB0aGUgc2FtZSBwb2ludGVyLgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlX3NlY29uZCA9CisgICAgICByLT5HZXRFbnVtKG1lc3NhZ2UsIGZpZWxkKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUsIGVudW1fdmFsdWVfc2Vjb25kKTsKKworICAvLyBDaGVjayB0aGUgcmVwZWF0ZWQgY2FzZSB0b28uCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogcmVwZWF0ZWRfZmllbGQgPQorICAgICAgZC0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9lIik7CisgIGVudW1fdmFsdWUgPSByLT5HZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgcmVwZWF0ZWRfZmllbGQsIDApOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZS0+bnVtYmVyKCksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpKTsKKyAgLy8gU2hvdWxkIHJldXNlIHRoZSBzYW1lIEVudW1WYWx1ZURlc2NyaXB0b3IsIGV2ZW4gZm9yIGEgZGlmZmVyZW50IGZpZWxkLgorICBFWFBFQ1RfRVEoZW51bV92YWx1ZSwgZW51bV92YWx1ZV9zZWNvbmQpOworCisgIC8vIFdlIHNob3VsZCBiZSBhYmxlIHRvIHVzZSB0aGUgcmV0dXJuZWQgdmFsdWUgZGVzY3JpcHRvciB0byBzZXQgYSB2YWx1ZSBvbgorICAvLyBhbm90aGVyIG1lc3NhZ2UuCisgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIG0gPSBtZXNzYWdlLk5ldygpOworICByLT5TZXRFbnVtKG0sIGZpZWxkLCBlbnVtX3ZhbHVlKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUsIHItPkdldEVudW0oKm0sIGZpZWxkKSk7CisgIGRlbGV0ZSBtOworfQorCisvLyBUZXN0IHRoYXQgdGhlIG5ldyBpbnRlZ2VyLWJhc2VkIGVudW0gcmVmbGVjdGlvbiBBUEkgd29ya3MuCitURVNUKFByZXNlcnZlVW5rbm93bkVudW1UZXN0LCBJbnRlZ2VyRW51bVJlZmxlY3Rpb25BUEkpIHsKKyAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlIG1lc3NhZ2U7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIHIgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZCA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogc2luZ3VsYXJfZmllbGQgPSBkLT5GaW5kRmllbGRCeU5hbWUoImUiKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiByZXBlYXRlZF9maWVsZCA9CisgICAgICBkLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2UiKTsKKworICByLT5TZXRFbnVtVmFsdWUoJm1lc3NhZ2UsIHNpbmd1bGFyX2ZpZWxkLCA0Mik7CisgIEVYUEVDVF9FUSg0Miwgci0+R2V0RW51bVZhbHVlKG1lc3NhZ2UsIHNpbmd1bGFyX2ZpZWxkKSk7CisgIHItPkFkZEVudW1WYWx1ZSgmbWVzc2FnZSwgcmVwZWF0ZWRfZmllbGQsIDQyKTsKKyAgci0+QWRkRW51bVZhbHVlKCZtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgNDIpOworICBFWFBFQ1RfRVEoNDIsIHItPkdldFJlcGVhdGVkRW51bVZhbHVlKG1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCAwKSk7CisgIHItPlNldFJlcGVhdGVkRW51bVZhbHVlKCZtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgMSwgODQpOworICBFWFBFQ1RfRVEoODQsIHItPkdldFJlcGVhdGVkRW51bVZhbHVlKG1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCAxKSk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPSByLT5HZXRFbnVtKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2luZ3VsYXJfZmllbGQpOworICBFWFBFQ1RfRVEoNDIsIGVudW1fdmFsdWUtPm51bWJlcigpKTsKK30KKworLy8gVGVzdCB0aGF0IHRoZSBFbnVtVmFsdWUgQVBJIHdvcmtzIHByb3Blcmx5IGZvciBwcm90bzIgbWVzc2FnZXMgYXMgd2VsbC4KK1RFU1QoUHJlc2VydmVVbmtub3duRW51bVRlc3QsIFByb3RvMkNhdGNoZXNVbmtub3duVmFsdWVzKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsgIC8vIHByb3RvMiBtZXNzYWdlCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIHIgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZCA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIHNpbmd1bGFyX2ZpZWxkID0KKyAgICAgIGQtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX2VudW0iKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiByZXBlYXRlZF9maWVsZCA9CisgICAgICBkLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX25lc3RlZF9lbnVtIik7CisgIC8vIEFkZCBvbmUgZWxlbWVudCB0byB0aGUgcmVwZWF0ZWQgZmllbGQgc28gdGhhdCB3ZSBjYW4gdGVzdAorICAvLyBTZXRSZXBlYXRlZEVudW1WYWx1ZS4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICByZXBlYXRlZF9maWVsZC0+ZW51bV90eXBlKCktPkZpbmRWYWx1ZUJ5TmFtZSgiQkFSIik7CisgIEVYUEVDVF9UUlVFKGVudW1fdmFsdWUgIT0gTlVMTCk7CisgIHItPkFkZEVudW0oJm1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCBlbnVtX3ZhbHVlKTsKKworI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisgIC8vIEVudW0tZmllbGQgaW50ZWdlci1iYXNlZCBzZXR0ZXJzIEdPT0dMRV9EQ0hFQ0stZmFpbCBvbiBpbnZhbGlkIHZhbHVlcywgaW4gb3JkZXIgdG8KKyAgLy8gcmVtYWluIGNvbnNpc3RlbnQgd2l0aCBwcm90bzIgZ2VuZXJhdGVkIGNvZGUuCisgIEVYUEVDVF9ERUJVR19ERUFUSCh7CisgICAgci0+U2V0RW51bVZhbHVlKCZtZXNzYWdlLCBzaW5ndWxhcl9maWVsZCwgNDI0Mik7CisgICAgci0+R2V0RW51bShtZXNzYWdlLCBzaW5ndWxhcl9maWVsZCktPm51bWJlcigpOworICB9LCAiU2V0RW51bVZhbHVlIGFjY2VwdHMgb25seSB2YWxpZCBpbnRlZ2VyIHZhbHVlcyIpOworICBFWFBFQ1RfREVCVUdfREVBVEgoeworICAgIHItPlNldFJlcGVhdGVkRW51bVZhbHVlKCZtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgMCwgNDI0Mik7CisgICAgci0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCAwKTsKKyAgfSwgIlNldFJlcGVhdGVkRW51bVZhbHVlIGFjY2VwdHMgb25seSB2YWxpZCBpbnRlZ2VyIHZhbHVlcyIpOworICBFWFBFQ1RfREVCVUdfREVBVEgoeworICAgIHItPkFkZEVudW1WYWx1ZSgmbWVzc2FnZSwgcmVwZWF0ZWRfZmllbGQsIDQyNDIpOworICAgIHItPkdldFJlcGVhdGVkRW51bShtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgMSk7CisgIH0sICJBZGRFbnVtVmFsdWUgYWNjZXB0cyBvbmx5IHZhbGlkIGludGVnZXIgdmFsdWVzIik7CisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCit9CisKK1RFU1QoUHJlc2VydmVVbmtub3duRW51bVRlc3QsIFN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZXNBUEkpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBwcm90bzJfbWVzc2FnZTsKKyAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlIG5ld19tZXNzYWdlOworCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIHByb3RvMl9yZWZsZWN0aW9uID0gcHJvdG8yX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uKiBuZXdfcmVmbGVjdGlvbiA9IG5ld19tZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBFWFBFQ1RfRkFMU0UocHJvdG8yX3JlZmxlY3Rpb24tPlN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZXMoKSk7CisgIEVYUEVDVF9UUlVFKG5ld19yZWZsZWN0aW9uLT5TdXBwb3J0c1Vua25vd25FbnVtVmFsdWVzKCkpOworfQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Byb3RvM19hcmVuYV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzYjU5OTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Byb3RvM19hcmVuYV91bml0dGVzdC5jYwpAQCAtMCwwICsxLDE4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgewordXNpbmcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgeworLy8gV2Ugc2VsZWN0aXZlbHkgc2V0L2NoZWNrIGEgZmV3IHJlcHJlc2VudGF0aXZlIGZpZWxkcyByYXRoZXIgdGhhbiBhbGwgZmllbGRzCisvLyBhcyB0aGlzIHRlc3QgaXMgb25seSBleHBlY3RlZCB0byBjb3ZlciB0aGUgYmFzaWNzIG9mIGFyZW5hIHN1cHBvcnQuCit2b2lkIFNldEFsbEZpZWxkcyhUZXN0QWxsVHlwZXMqIG0pIHsKKyAgbS0+c2V0X29wdGlvbmFsX2ludDMyKDEwMCk7CisgIG0tPnNldF9vcHRpb25hbF9zdHJpbmcoImFzZGYiKTsKKyAgbS0+c2V0X29wdGlvbmFsX2J5dGVzKCJqa2w7Iik7CisgIG0tPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKyAgbS0+bXV0YWJsZV9vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoNDMpOworICBtLT5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0oCisgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWik7CisgIG0tPnNldF9vcHRpb25hbF9mb3JlaWduX2VudW0oCisgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OkZPUkVJR05fQkFaKTsKKyAgbS0+bXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS0+c2V0X2JiKDQ1KTsKKyAgbS0+YWRkX3JlcGVhdGVkX2ludDMyKDEwMCk7CisgIG0tPmFkZF9yZXBlYXRlZF9zdHJpbmcoImFzZGYiKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2J5dGVzKCJqa2w7Iik7CisgIG0tPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDYpOworICBtLT5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKDQ3KTsKKyAgbS0+YWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKAorICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9CQVopOworICBtLT5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9lbnVtKAorICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpGT1JFSUdOX0JBWik7CisgIG0tPmFkZF9yZXBlYXRlZF9sYXp5X21lc3NhZ2UoKS0+c2V0X2JiKDQ5KTsKKworICBtLT5zZXRfb25lb2ZfdWludDMyKDEpOworICBtLT5tdXRhYmxlX29uZW9mX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig1MCk7CisgIG0tPnNldF9vbmVvZl9zdHJpbmcoInRlc3QiKTsgIC8vIG9ubHkgdGhpcyBvbmUgcmVtYWlucyBzZXQKK30KKwordm9pZCBFeHBlY3RBbGxGaWVsZHNTZXQoY29uc3QgVGVzdEFsbFR5cGVzJiBtKSB7CisgIEVYUEVDVF9FUSgxMDAsIG0ub3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSgiYXNkZiIsIG0ub3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoImprbDsiLCBtLm9wdGlvbmFsX2J5dGVzKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSg0MiwgbS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoNDMsIG0ub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkuYygpKTsKKyAgRVhQRUNUX0VRKHByb3RvM19hcmVuYV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fQkFaLAorICAgICAgICAgICAgbS5vcHRpb25hbF9uZXN0ZWRfZW51bSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvM19hcmVuYV91bml0dGVzdDo6Rk9SRUlHTl9CQVosCisgICAgICAgICAgICBtLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG0uaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKDQ1LCBtLm9wdGlvbmFsX2xhenlfbWVzc2FnZSgpLmJiKCkpOworCisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMDAsIG0ucmVwZWF0ZWRfaW50MzIoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJhc2RmIiwgbS5yZXBlYXRlZF9zdHJpbmcoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9ieXRlc19zaXplKCkpOworICBFWFBFQ1RfRVEoImprbDsiLCBtLnJlcGVhdGVkX2J5dGVzKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQ2LCBtLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQ3LCBtLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEocHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9CQVosCisgICAgICAgICAgICBtLnJlcGVhdGVkX25lc3RlZF9lbnVtKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUoKSk7CisgIEVYUEVDVF9FUShwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OkZPUkVJR05fQkFaLAorICAgICAgICAgICAgbS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9sYXp5X21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQ5LCBtLnJlcGVhdGVkX2xhenlfbWVzc2FnZSgwKS5iYigpKTsKKworICBFWFBFQ1RfRVEocHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtPbmVvZlN0cmluZywKKyAgICAgICAgICAgIG0ub25lb2ZfZmllbGRfY2FzZSgpKTsKKyAgRVhQRUNUX0VRKCJ0ZXN0IiwgbS5vbmVvZl9zdHJpbmcoKSk7Cit9CisKKy8vIEluIHRoaXMgZmlsZSB3ZSBvbmx5IHRlc3Qgc29tZSBiYXNpYyBmdW5jdGlvbmFsaXRpZXMgb2YgYXJlbmEgc3VwcG9ydCBpbgorLy8gcHJvdG8zIGFuZCBleHBlY3QgdGhlIGFyZW5hIHN1cHBvcnQgdG8gYmUgZnVsbHkgdGVzdGVkIGluIHByb3RvMiB1bml0dGVzdHMKKy8vIGJlY2F1c2UgcHJvdG8zIHNoYXJlcyBtb3N0IGNvZGUgd2l0aCBwcm90bzIuCisKK1RFU1QoQXJlbmFUZXN0LCBQYXJzaW5nKSB7CisgIFRlc3RBbGxUeXBlcyBvcmlnaW5hbDsKKyAgU2V0QWxsRmllbGRzKCZvcmlnaW5hbCk7CisKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKG9yaWdpbmFsLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBFeHBlY3RBbGxGaWVsZHNTZXQoKmFyZW5hX21lc3NhZ2UpOworfQorCitURVNUKEFyZW5hVGVzdCwgVW5rbm93bkZpZWxkcykgeworICBUZXN0QWxsVHlwZXMgb3JpZ2luYWw7CisgIFNldEFsbEZpZWxkcygmb3JpZ2luYWwpOworCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIGFyZW5hX21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhvcmlnaW5hbC5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgRXhwZWN0QWxsRmllbGRzU2V0KCphcmVuYV9tZXNzYWdlKTsKKworICAvLyBJbiBwcm90bzMgd2UgY2FuIHN0aWxsIGdldCBhIHBvaW50ZXIgdG8gdGhlIFVua25vd25GaWVsZFNldCB0aHJvdWdoCisgIC8vIHJlZmxlY3Rpb24gQVBJLgorICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzID0KKyAgICAgIGFyZW5hX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoYXJlbmFfbWVzc2FnZSk7CisgIC8vIFdlIGNhbiBtb2RpZnkgdGhpcyBVbmtub3duRmllbGRTZXQuCisgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoMSwgMik7CisgIC8vIEJ1dCB0aGUgY2hhbmdlIHdpbGwgbmV2ZXIgd2lsbCBzZXJpYWxpemVkIGJhY2suCisgIEFTU0VSVF9FUShvcmlnaW5hbC5CeXRlU2l6ZSgpLCBhcmVuYV9tZXNzYWdlLT5CeXRlU2l6ZSgpKTsKKyAgQVNTRVJUX1RSVUUoCisgICAgICBhcmVuYV9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVua25vd25GaWVsZHMoKmFyZW5hX21lc3NhZ2UpLmVtcHR5KCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgU3dhcCkgeworICBBcmVuYSBhcmVuYTE7CisgIEFyZW5hIGFyZW5hMjsKKworICAvLyBUZXN0IFN3YXAoKS4KKyAgVGVzdEFsbFR5cGVzKiBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIFRlc3RBbGxUeXBlcyogYXJlbmEyX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTIpOworICBhcmVuYTFfbWVzc2FnZS0+U3dhcChhcmVuYTJfbWVzc2FnZSk7CisgIEVYUEVDVF9FUSgmYXJlbmExLCBhcmVuYTFfbWVzc2FnZS0+R2V0QXJlbmEoKSk7CisgIEVYUEVDVF9FUSgmYXJlbmEyLCBhcmVuYTJfbWVzc2FnZS0+R2V0QXJlbmEoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTZXRBbGxvY2F0ZWRNZXNzYWdlKSB7CisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMgKmFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkID0gbmV3IFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZTsKKyAgbmVzdGVkLT5zZXRfYmIoMTE4KTsKKyAgYXJlbmFfbWVzc2FnZS0+c2V0X2FsbG9jYXRlZF9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZShuZXN0ZWQpOworICBFWFBFQ1RfRVEoMTE4LCBhcmVuYV9tZXNzYWdlLT5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgUmVsZWFzZU1lc3NhZ2UpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTE4KTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+IG5lc3RlZCgKKyAgICAgIGFyZW5hX21lc3NhZ2UtPnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgxMTgsIG5lc3RlZC0+YmIoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Byb3RvX2Nhc3QuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvcHJvdG9fY2FzdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyNWMyMTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Byb3RvX2Nhc3QuaApAQCAtMCwwICsxLDU4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9QUk9UT19DQVNUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9QUk9UT19DQVNUX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisvLyBwcm90b19jYXN0PD4gaXMgdXNlZCB0byBzaW11bGF0ZSBvdmVyLXRoZS13aXJlIGNvbnZlcnNpb24gb2Ygb25lCisvLyBwcm90byBtZXNzYWdlIGludG8gYW5vdGhlci4gIFRoaXMgaXMgcHJpbWFyaWx5IHVzZWZ1bCBmb3IgdW5pdCB0ZXN0cworLy8gd2hpY2ggdmFsaWRhdGUgdGhlIHZlcnNpb24tY29tcGF0aWJpbGl0eSBzZW1hbnRpY3Mgb2YgcHJvdG9idWZzLgorLy8gVXNhZ2UgaXMgc2ltaWxhciB0byBDKystc3R5bGUgdHlwZWNhc3RzOgorLy8KKy8vIE9sZE1lc3NhZ2Ugb2xkX21lc3NhZ2UgPSAvKi4uLiovOworLy8gTmV3TWVzc2FnZSBuZXdfbWVzc2FnZSA9IHByb3RvX2Nhc3Q8TmV3TWVzc2FnZT4ob2xkX21lc3NhZ2UpOworbmFtZXNwYWNlIGdvb2dsZSB7Cit0ZW1wbGF0ZTx0eXBlbmFtZSBOZXdQcm90bywKKyAgICAgICAgIHR5cGVuYW1lIE9sZFByb3RvPgorTmV3UHJvdG8gcHJvdG9fY2FzdChjb25zdCBPbGRQcm90byYgb2xkX3Byb3RvKSB7CisgIHN0cmluZyB3aXJlX2Zvcm1hdDsKKyAgR09PR0xFX0NIRUNLKG9sZF9wcm90by5TZXJpYWxpemVUb1N0cmluZygmd2lyZV9mb3JtYXQpKTsKKworICBOZXdQcm90byBuZXdfcHJvdG87CisgIEdPT0dMRV9DSEVDSyhuZXdfcHJvdG8uUGFyc2VGcm9tU3RyaW5nKHdpcmVfZm9ybWF0KSk7CisgIHJldHVybiBuZXdfcHJvdG87Cit9CisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfUFJPVE9fQ0FTVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcHJvdG9fY2FzdF90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9wcm90b19jYXN0X3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWIxMDFlYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcHJvdG9fY2FzdF90ZXN0LmNjCkBAIC0wLDAgKzEsNjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvcHJvdG9fY2FzdC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvdW5rbm93bl9lbnVtX3Rlc3QucGIuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dtb2NrLmg+CisKK25hbWVzcGFjZSBnb29nbGUgewordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dXRpbDo6VXBSZXZpc2lvbjsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnV0aWw6OkRvd25SZXZpc2lvbjsKKworbmFtZXNwYWNlIHsKKworVEVTVChQcm90b0Nhc3RUZXN0LCBWMktub3duVmFsdWUpIHsKKyAgVXBSZXZpc2lvbiBzZW5kZXI7CisgIHNlbmRlci5zZXRfdmFsdWUoVXBSZXZpc2lvbjo6Tk9OREVGQVVMVF9WQUxVRSk7CisKKyAgRG93blJldmlzaW9uIHJlY2VpdmVyID0gcHJvdG9fY2FzdDxEb3duUmV2aXNpb24+KHNlbmRlcik7CisgIEFTU0VSVF9FUShEb3duUmV2aXNpb246Ok5PTkRFRkFVTFRfVkFMVUUsIHJlY2VpdmVyLnZhbHVlKCkpOworfQorCitURVNUKFByb3RvQ2FzdFRlc3QsIFYyVW5rbm93blZhbHVlKSB7CisgIFVwUmV2aXNpb24gc2VuZGVyOworICBzZW5kZXIuc2V0X3ZhbHVlKFVwUmV2aXNpb246Ok5FV19WQUxVRSk7CisKKyAgRG93blJldmlzaW9uIHJlY2VpdmVyID0gcHJvdG9fY2FzdDxEb3duUmV2aXNpb24+KHNlbmRlcik7CisgIEFTU0VSVF9FUShEb3duUmV2aXNpb246OkRFRkFVTFRfVkFMVUUsIHJlY2VpdmVyLnZhbHVlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDNjNzYxYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5oCkBAIC0wLDAgKzEsNTk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBoZWFkZXIgZGVmaW5lcyB0aGUgUmVwZWF0ZWRGaWVsZFJlZiBjbGFzcyB0ZW1wbGF0ZSB1c2VkIHRvIGFjY2VzcworLy8gcmVwZWF0ZWQgZmllbGRzIHdpdGggcHJvdG9idWYgcmVmbGVjdGlvbiBBUEkuCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9SRUZMRUNUSU9OX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBFbmFibGUgPSB2b2lkPgorc3RydWN0IFJlZlR5cGVUcmFpdHM7Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK1JlcGVhdGVkRmllbGRSZWY8VD4gUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRGaWVsZFJlZigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiBSZXBlYXRlZEZpZWxkUmVmPFQ+KG1lc3NhZ2UsIGZpZWxkKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK011dGFibGVSZXBlYXRlZEZpZWxkUmVmPFQ+IFJlZmxlY3Rpb246OkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgcmV0dXJuIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPFQ+KG1lc3NhZ2UsIGZpZWxkKTsKK30KKworLy8gUmVwZWF0ZWRGaWVsZFJlZiBkZWZpbml0aW9uIGZvciBub24tbWVzc2FnZSB0eXBlcy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkUmVmPAorICAgIFQsIHR5cGVuYW1lIGludGVybmFsOjplbmFibGVfaWY8IWludGVybmFsOjppc19iYXNlX29mPE1lc3NhZ2UsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6aXRlcmF0b3IgSXRlcmF0b3JUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclR5cGUgQWNjZXNzb3JUeXBlOworCisgcHVibGljOgorICBib29sIGVtcHR5KCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPklzRW1wdHkoZGF0YV8pOworICB9CisgIGludCBzaXplKCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPlNpemUoZGF0YV8pOworICB9CisgIFQgR2V0KGludCBpbmRleCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPnRlbXBsYXRlIEdldDxUPihkYXRhXywgaW5kZXgpOworICB9CisKKyAgdHlwZWRlZiBJdGVyYXRvclR5cGUgaXRlcmF0b3I7CisgIHR5cGVkZWYgSXRlcmF0b3JUeXBlIGNvbnN0X2l0ZXJhdG9yOworICBpdGVyYXRvciBiZWdpbigpIGNvbnN0IHsKKyAgICByZXR1cm4gaXRlcmF0b3IoZGF0YV8sIGFjY2Vzc29yXywgdHJ1ZSk7CisgIH0KKyAgaXRlcmF0b3IgZW5kKCkgY29uc3QgeworICAgIHJldHVybiBpdGVyYXRvcihkYXRhXywgYWNjZXNzb3JfLCBmYWxzZSk7CisgIH0KKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBSZWZsZWN0aW9uOworICBSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgICAgZGF0YV8gPSByZWZsZWN0aW9uLT5SZXBlYXRlZEZpZWxkRGF0YSgKKyAgICAgICAgY29uc3RfY2FzdDxNZXNzYWdlKj4oJm1lc3NhZ2UpLCBmaWVsZCwKKyAgICAgICAgaW50ZXJuYWw6OlJlZlR5cGVUcmFpdHM8VD46OmNwcF90eXBlLCBOVUxMKTsKKyAgICBhY2Nlc3Nvcl8gPSByZWZsZWN0aW9uLT5SZXBlYXRlZEZpZWxkQWNjZXNzb3IoZmllbGQpOworICB9CisKKyAgY29uc3Qgdm9pZCogZGF0YV87CisgIGNvbnN0IEFjY2Vzc29yVHlwZSogYWNjZXNzb3JfOworfTsKKworLy8gTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYgZGVmaW5pdGlvbiBmb3Igbm9uLW1lc3NhZ2UgdHlwZXMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjwhaW50ZXJuYWw6OmlzX2Jhc2Vfb2Y8TWVzc2FnZSwgVD46OnZhbHVlPjo6dHlwZT4geworICB0eXBlZGVmIHR5cGVuYW1lIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclR5cGUgQWNjZXNzb3JUeXBlOworCisgcHVibGljOgorICBib29sIGVtcHR5KCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPklzRW1wdHkoZGF0YV8pOworICB9CisgIGludCBzaXplKCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPlNpemUoZGF0YV8pOworICB9CisgIFQgR2V0KGludCBpbmRleCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPnRlbXBsYXRlIEdldDxUPihkYXRhXywgaW5kZXgpOworICB9CisKKyAgdm9pZCBTZXQoaW50IGluZGV4LCBjb25zdCBUJiB2YWx1ZSkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+dGVtcGxhdGUgU2V0PFQ+KGRhdGFfLCBpbmRleCwgdmFsdWUpOworICB9CisgIHZvaWQgQWRkKGNvbnN0IFQmIHZhbHVlKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT50ZW1wbGF0ZSBBZGQ8VD4oZGF0YV8sIHZhbHVlKTsKKyAgfQorICB2b2lkIFJlbW92ZUxhc3QoKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT5SZW1vdmVMYXN0KGRhdGFfKTsKKyAgfQorICB2b2lkIFN3YXBFbGVtZW50cyhpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT5Td2FwRWxlbWVudHMoZGF0YV8sIGluZGV4MSwgaW5kZXgyKTsKKyAgfQorICB2b2lkIENsZWFyKCkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+Q2xlYXIoZGF0YV8pOworICB9CisKKyAgdm9pZCBTd2FwKGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmJiBvdGhlcikgY29uc3QgeworICAgIGFjY2Vzc29yXy0+U3dhcChkYXRhXywgb3RoZXIuYWNjZXNzb3JfLCBvdGhlci5kYXRhXyk7CisgIH0KKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IENvbnRhaW5lciYgY29udGFpbmVyKSBjb25zdCB7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBDb250YWluZXI6OmNvbnN0X2l0ZXJhdG9yIEl0ZXJhdG9yOworICAgIGZvciAoSXRlcmF0b3IgaXQgPSBjb250YWluZXIuYmVnaW4oKTsgaXQgIT0gY29udGFpbmVyLmVuZCgpOyArK2l0KSB7CisgICAgICBBZGQoKml0KTsKKyAgICB9CisgIH0KKyAgdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgorICB2b2lkIENvcHlGcm9tKGNvbnN0IENvbnRhaW5lciYgY29udGFpbmVyKSBjb25zdCB7CisgICAgQ2xlYXIoKTsKKyAgICBNZXJnZUZyb20oY29udGFpbmVyKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIFJlZmxlY3Rpb247CisgIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICAgIGRhdGFfID0gcmVmbGVjdGlvbi0+UmVwZWF0ZWRGaWVsZERhdGEoCisgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6Y3BwX3R5cGUsIE5VTEwpOworICAgIGFjY2Vzc29yXyA9IHJlZmxlY3Rpb24tPlJlcGVhdGVkRmllbGRBY2Nlc3NvcihmaWVsZCk7CisgIH0KKworICB2b2lkKiBkYXRhXzsKKyAgY29uc3QgQWNjZXNzb3JUeXBlKiBhY2Nlc3Nvcl87Cit9OworCisvLyBSZXBlYXRlZEZpZWxkUmVmIGRlZmluaXRpb24gZm9yIG1lc3NhZ2UgdHlwZXMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgUmVwZWF0ZWRGaWVsZFJlZjwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPGludGVybmFsOjppc19iYXNlX29mPE1lc3NhZ2UsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6aXRlcmF0b3IgSXRlcmF0b3JUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclR5cGUgQWNjZXNzb3JUeXBlOworCisgcHVibGljOgorICBib29sIGVtcHR5KCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPklzRW1wdHkoZGF0YV8pOworICB9CisgIGludCBzaXplKCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPlNpemUoZGF0YV8pOworICB9CisgIC8vIFRoaXMgbWV0aG9kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgbWVzc2FnZSBvYmplY3QgaWYgaXQKKyAgLy8gZXhpc3RzLiBJZiBhIG1lc3NhZ2Ugb2JqZWN0IGRvZXNuJ3QgZXhpc3QgKGUuZy4sIGRhdGEgc3RvcmVkIGluIHNlcmlhbGl6ZWQKKyAgLy8gZm9ybSksIHNjcmF0Y2hfc3BhY2Ugd2lsbCBiZSBmaWxsZWQgd2l0aCB0aGUgZGF0YSBhbmQgYSByZWZlcmVuY2UgdG8gaXQKKyAgLy8gd2lsbCBiZSByZXR1cm5lZC4KKyAgLy8KKyAgLy8gRXhhbXBsZToKKyAgLy8gICBSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IGggPSAuLi4KKyAgLy8gICB1bmlxdWVfcHRyPE1lc3NhZ2U+IHNjcmF0Y2hfc3BhY2UoaC5OZXdNZXNzYWdlKCkpOworICAvLyAgIGNvbnN0IE1lc3NhZ2UmIGl0ZW0gPSBoLkdldChpbmRleCwgc2NyYXRjaF9zcGFjZS5nZXQoKSk7CisgIGNvbnN0IFQmIEdldChpbnQgaW5kZXgsIFQqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gKnN0YXRpY19jYXN0PGNvbnN0IFQqPihhY2Nlc3Nvcl8tPkdldChkYXRhXywgaW5kZXgsIHNjcmF0Y2hfc3BhY2UpKTsKKyAgfQorICAvLyBDcmVhdGUgYSBuZXcgbWVzc2FnZSBvZiB0aGUgc2FtZSB0eXBlIGFzIHRoZSBtZXNzYWdlcyBzdG9yZWQgaW4gdGhpcworICAvLyByZXBlYXRlZCBmaWVsZC4gQ2FsbGVyIHRha2VzIG93bmVyc2hpcCBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LgorICBUKiBOZXdNZXNzYWdlKCkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUKj4oZGVmYXVsdF9pbnN0YW5jZV8tPk5ldygpKTsKKyAgfQorCisgIHR5cGVkZWYgSXRlcmF0b3JUeXBlIGl0ZXJhdG9yOworICB0eXBlZGVmIEl0ZXJhdG9yVHlwZSBjb25zdF9pdGVyYXRvcjsKKyAgaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7CisgICAgcmV0dXJuIGl0ZXJhdG9yKGRhdGFfLCBhY2Nlc3Nvcl8sIHRydWUsIE5ld01lc3NhZ2UoKSk7CisgIH0KKyAgaXRlcmF0b3IgZW5kKCkgY29uc3QgeworICAgIHJldHVybiBpdGVyYXRvcihkYXRhXywgYWNjZXNzb3JfLCBmYWxzZSwgTmV3TWVzc2FnZSgpKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIFJlZmxlY3Rpb247CisgIFJlcGVhdGVkRmllbGRSZWYoCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgICBkYXRhXyA9IHJlZmxlY3Rpb24tPlJlcGVhdGVkRmllbGREYXRhKAorICAgICAgICBjb25zdF9jYXN0PE1lc3NhZ2UqPigmbWVzc2FnZSksIGZpZWxkLAorICAgICAgICBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6Y3BwX3R5cGUsCisgICAgICAgIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkpOworICAgIGFjY2Vzc29yXyA9IHJlZmxlY3Rpb24tPlJlcGVhdGVkRmllbGRBY2Nlc3NvcihmaWVsZCk7CisgICAgZGVmYXVsdF9pbnN0YW5jZV8gPQorICAgICAgICByZWZsZWN0aW9uLT5HZXRNZXNzYWdlRmFjdG9yeSgpLT5HZXRQcm90b3R5cGUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKTsKKyAgfQorCisgIGNvbnN0IHZvaWQqIGRhdGFfOworICBjb25zdCBBY2Nlc3NvclR5cGUqIGFjY2Vzc29yXzsKKyAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworCisvLyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiBkZWZpbml0aW9uIGZvciBtZXNzYWdlIHR5cGVzLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPAorICAgIFQsIHR5cGVuYW1lIGludGVybmFsOjplbmFibGVfaWY8aW50ZXJuYWw6OmlzX2Jhc2Vfb2Y8TWVzc2FnZSwgVD46OnZhbHVlPjo6dHlwZT4geworICB0eXBlZGVmIHR5cGVuYW1lIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclR5cGUgQWNjZXNzb3JUeXBlOworCisgcHVibGljOgorICBib29sIGVtcHR5KCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPklzRW1wdHkoZGF0YV8pOworICB9CisgIGludCBzaXplKCkgY29uc3QgeworICAgIHJldHVybiBhY2Nlc3Nvcl8tPlNpemUoZGF0YV8pOworICB9CisgIC8vIFNlZSBjb21tZW50cyBmb3IgUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPjo6R2V0KCkKKyAgY29uc3QgVCYgR2V0KGludCBpbmRleCwgVCogc2NyYXRjaF9zcGFjZSkgY29uc3QgeworICAgIHJldHVybiAqc3RhdGljX2Nhc3Q8Y29uc3QgVCo+KGFjY2Vzc29yXy0+R2V0KGRhdGFfLCBpbmRleCwgc2NyYXRjaF9zcGFjZSkpOworICB9CisgIC8vIENyZWF0ZSBhIG5ldyBtZXNzYWdlIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhlIG1lc3NhZ2VzIHN0b3JlZCBpbiB0aGlzCisgIC8vIHJlcGVhdGVkIGZpZWxkLiBDYWxsZXIgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSByZXR1cm5lZCBvYmplY3QuCisgIFQqIE5ld01lc3NhZ2UoKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQqPihkZWZhdWx0X2luc3RhbmNlXy0+TmV3KCkpOworICB9CisKKyAgdm9pZCBTZXQoaW50IGluZGV4LCBjb25zdCBUJiB2YWx1ZSkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+U2V0KGRhdGFfLCBpbmRleCwgJnZhbHVlKTsKKyAgfQorICB2b2lkIEFkZChjb25zdCBUJiB2YWx1ZSkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+QWRkKGRhdGFfLCAmdmFsdWUpOworICB9CisgIHZvaWQgUmVtb3ZlTGFzdCgpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPlJlbW92ZUxhc3QoZGF0YV8pOworICB9CisgIHZvaWQgU3dhcEVsZW1lbnRzKGludCBpbmRleDEsIGludCBpbmRleDIpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPlN3YXBFbGVtZW50cyhkYXRhXywgaW5kZXgxLCBpbmRleDIpOworICB9CisgIHZvaWQgQ2xlYXIoKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT5DbGVhcihkYXRhXyk7CisgIH0KKworICB2b2lkIFN3YXAoY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYmIG90aGVyKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT5Td2FwKGRhdGFfLCBvdGhlci5hY2Nlc3Nvcl8sIG90aGVyLmRhdGFfKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIENvbnRhaW5lcj4KKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgQ29udGFpbmVyJiBjb250YWluZXIpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIENvbnRhaW5lcjo6Y29uc3RfaXRlcmF0b3IgSXRlcmF0b3I7CisgICAgZm9yIChJdGVyYXRvciBpdCA9IGNvbnRhaW5lci5iZWdpbigpOyBpdCAhPSBjb250YWluZXIuZW5kKCk7ICsraXQpIHsKKyAgICAgIEFkZCgqaXQpOworICAgIH0KKyAgfQorICB0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+CisgIHZvaWQgQ29weUZyb20oY29uc3QgQ29udGFpbmVyJiBjb250YWluZXIpIGNvbnN0IHsKKyAgICBDbGVhcigpOworICAgIE1lcmdlRnJvbShjb250YWluZXIpOworICB9CisKKyBwcml2YXRlOgorICBmcmllbmQgY2xhc3MgUmVmbGVjdGlvbjsKKyAgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYoCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgZGF0YV8gPSByZWZsZWN0aW9uLT5SZXBlYXRlZEZpZWxkRGF0YSgKKyAgICAgICAgbWVzc2FnZSwgZmllbGQsIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpjcHBfdHlwZSwKKyAgICAgICAgaW50ZXJuYWw6OlJlZlR5cGVUcmFpdHM8VD46OkdldE1lc3NhZ2VGaWVsZERlc2NyaXB0b3IoKSk7CisgICAgYWNjZXNzb3JfID0gcmVmbGVjdGlvbi0+UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKGZpZWxkKTsKKyAgICBkZWZhdWx0X2luc3RhbmNlXyA9CisgICAgICAgIHJlZmxlY3Rpb24tPkdldE1lc3NhZ2VGYWN0b3J5KCktPkdldFByb3RvdHlwZShmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICB9CisKKyAgdm9pZCogZGF0YV87CisgIGNvbnN0IEFjY2Vzc29yVHlwZSogYWNjZXNzb3JfOworICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisvLyBJbnRlcmZhY2VzIHVzZWQgdG8gaW1wbGVtZW50IHJlZmxlY3Rpb24gUmVwZWF0ZWRGaWVsZFJlZiBBUEkuCisvLyBSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZEFjY2Vzc29yKCkgc2hvdWxkIHJldHVybiBhIHBvaW50ZXIgdG8gYW4gc2luZ2xldG9uCisvLyBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBiZWxvdyBpbnRlcmZhY2UuCisvLworLy8gVGhpcyBpbnRlcmZhY2UgcGFzc2VzL3JldHVybnMgdmFsdWVzIHVzaW5nIHZvaWQgcG9pbnRlcnMuIFRoZSBhY3R1YWwgdHlwZQorLy8gb2YgdGhlIHZhbHVlIGRlcGVuZHMgb24gdGhlIGZpZWxkJ3MgY3BwX3R5cGUuIEZvbGxvd2luZyBpcyBhIG1hcHBpbmcgZnJvbQorLy8gY3BwX3R5cGUgdG8gdGhlIHR5cGUgdGhhdCBzaG91bGQgYmUgdXNlZCBpbiB0aGlzIGludGVyZmFjZToKKy8vCisvLyAgIGZpZWxkLT5jcHBfdHlwZSgpICAgICAgVCAgICAgICAgICAgICAgICBBY3R1YWwgdHlwZSBvZiB2b2lkKgorLy8gICBDUFBUWVBFX0lOVDMyICAgICAgICBpbnQzMiAgICAgICAgICAgICAgICAgICBpbnQzMgorLy8gICBDUFBUWVBFX1VJTlQzMiAgICAgICB1aW50MzIgICAgICAgICAgICAgICAgICB1aW50MzIKKy8vICAgQ1BQVFlQRV9JTlQ2NCAgICAgICAgaW50NjQgICAgICAgICAgICAgICAgICAgaW50NjQKKy8vICAgQ1BQVFlQRV9VSU5UNjQgICAgICAgdWludDY0ICAgICAgICAgICAgICAgICAgdWludDY0CisvLyAgIENQUFRZUEVfRE9VQkxFICAgICAgIGRvdWJsZSAgICAgICAgICAgICAgICAgIGRvdWJsZQorLy8gICBDUFBUWVBFX0ZMT0FUICAgICAgICBmbG9hdCAgICAgICAgICAgICAgICAgICBmbG9hdAorLy8gICBDUFBUWVBFX0JPT0wgICAgICAgICBib29sICAgICAgICAgICAgICAgICAgICBib29sCisvLyAgIENQUFRZUEVfRU5VTSAgICAgICAgIGdlbmVyYXRlZCBlbnVtIHR5cGUgICAgIGludDMyCisvLyAgIENQUFRZUEVfU1RSSU5HICAgICAgIHN0cmluZyAgICAgICAgICAgICAgICAgIHN0cmluZworLy8gICBDUFBUWVBFX01FU1NBR0UgICAgICBnZW5lcmF0ZWQgbWVzc2FnZSB0eXBlICBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlCisvLyAgICAgICAgICAgICAgICAgICAgICAgIG9yIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UKKy8vCisvLyBOb3RlIHRoYXQgZm9yIGVudW1zIHdlIHVzZSBpbnQzMiBpbiB0aGUgaW50ZXJmYWNlLgorLy8KKy8vIFlvdSBjYW4gbWFwIGZyb20gVCB0byB0aGUgYWN0dWFsIHR5cGUgdXNpbmcgUmVmVHlwZVRyYWl0czoKKy8vICAgdHlwZWRlZiBSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclZhbHVlVHlwZSBBY3R1YWxUeXBlOworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJlcGVhdGVkRmllbGRBY2Nlc3NvciB7CisgcHVibGljOgorICAvLyBUeXBlZGVmcyBmb3IgY2xhcml0eS4KKyAgdHlwZWRlZiB2b2lkIEZpZWxkOworICB0eXBlZGVmIHZvaWQgVmFsdWU7CisgIHR5cGVkZWYgdm9pZCBJdGVyYXRvcjsKKworICB2aXJ0dWFsIH5SZXBlYXRlZEZpZWxkQWNjZXNzb3IoKTsKKyAgdmlydHVhbCBib29sIElzRW1wdHkoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBpbnQgU2l6ZShjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICAvLyBEZXBlbmRzIG9uIHRoZSB1bmRlcmx5aW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZXBlYXRlZCBmaWVsZCwgdGhpcworICAvLyBtZXRob2QgY2FuIHJldHVybiBhIHBvaW50ZXIgdG8gdGhlIHVuZGVybHlpbmcgb2JqZWN0IGlmIHN1Y2ggYW4gb2JqZWN0CisgIC8vIGV4aXN0cywgb3IgZmlsbCB0aGUgZGF0YSBpbnRvIHNjcmF0Y2hfc3BhY2UgYW5kIHJldHVybiBzY3JhdGNoX3NwYWNlLgorICAvLyBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIG11c3QgZW5zdXJlIHNjcmF0Y2hfc3BhY2UgaXMgYSB2YWxpZCBwb2ludGVyCisgIC8vIHRvIGEgbXV0YWJsZSBvYmplY3Qgb2YgdGhlIGNvcnJlY3QgdHlwZS4KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogR2V0KAorICAgICAgY29uc3QgRmllbGQqIGRhdGEsIGludCBpbmRleCwgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0ID0gMDsKKworICB2aXJ0dWFsIHZvaWQgQ2xlYXIoRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFNldChGaWVsZCogZGF0YSwgaW50IGluZGV4LCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZChGaWVsZCogZGF0YSwgY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBSZW1vdmVMYXN0KEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTd2FwRWxlbWVudHMoRmllbGQqIGRhdGEsIGludCBpbmRleDEsIGludCBpbmRleDIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFN3YXAoRmllbGQqIGRhdGEsIGNvbnN0IFJlcGVhdGVkRmllbGRBY2Nlc3Nvciogb3RoZXJfbXV0YXRvciwKKyAgICAgICAgICAgICAgICAgICAgRmllbGQqIG90aGVyX2RhdGEpIGNvbnN0ID0gMDsKKworICAvLyBDcmVhdGUgYW4gaXRlcmF0b3IgdGhhdCBwb2ludHMgYXQgdGhlIGJlZ2luaW5nIG9mIHRoZSByZXBlYXRlZCBmaWVsZC4KKyAgdmlydHVhbCBJdGVyYXRvciogQmVnaW5JdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICAvLyBDcmVhdGUgYW4gaXRlcmF0b3IgdGhhdCBwb2ludHMgYXQgdGhlIGVuZCBvZiB0aGUgcmVwZWF0ZWQgZmllbGQuCisgIHZpcnR1YWwgSXRlcmF0b3IqIEVuZEl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIC8vIE1ha2UgYSBjb3B5IG9mIGFuIGl0ZXJhdG9yIGFuZCByZXR1cm4gdGhlIG5ldyBjb3B5LgorICB2aXJ0dWFsIEl0ZXJhdG9yKiBDb3B5SXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogaXRlcmF0b3IpIGNvbnN0ID0gMDsKKyAgLy8gTW92ZSBhbiBpdGVyYXRvciB0byBwb2ludCB0byB0aGUgbmV4dCBlbGVtZW50LgorICB2aXJ0dWFsIEl0ZXJhdG9yKiBBZHZhbmNlSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciogaXRlcmF0b3IpIGNvbnN0ID0gMDsKKyAgLy8gQ29tcGFyZSB3aGV0aGVyIHR3byBpdGVyYXRvcnMgcG9pbnQgdG8gdGhlIHNhbWUgZWxlbWVudC4KKyAgdmlydHVhbCBib29sIEVxdWFsc0l0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhLCBjb25zdCBJdGVyYXRvciogYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBiKSBjb25zdCA9IDA7CisgIC8vIERlbGV0ZSBhbiBpdGVyYXRvciBjcmVhdGVkIGJ5IEJlZ2luSXRlcmF0b3IoKSwgRW5kSXRlcmF0b3IoKSBhbmQKKyAgLy8gQ29weUl0ZXJhdG9yKCkuCisgIHZpcnR1YWwgdm9pZCBEZWxldGVJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCA9IDA7CisgIC8vIExpa2UgR2V0KCkgYnV0IGZvciBpdGVyYXRvcnMuCisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldEl0ZXJhdG9yVmFsdWUoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSXRlcmF0b3IqIGl0ZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCA9IDA7CisKKyAgLy8gVGVtcGxhdGVkIG1ldGhvZHMgdGhhdCBtYWtlIHVzaW5nIHRoaXMgaW50ZXJmYWNlIGVhc2llciBmb3Igbm9uLW1lc3NhZ2UKKyAgLy8gdHlwZXMuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIFQgR2V0KGNvbnN0IEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjdHVhbFR5cGU7CisgICAgQWN0dWFsVHlwZSBzY3JhdGNoX3NwYWNlOworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUPigKKyAgICAgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgQWN0dWFsVHlwZSo+KAorICAgICAgICAgICAgR2V0KGRhdGEsIGluZGV4LCBzdGF0aWNfY2FzdDxWYWx1ZSo+KCZzY3JhdGNoX3NwYWNlKSkpKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFZhbHVlVHlwZT4KKyAgdm9pZCBTZXQoRmllbGQqIGRhdGEsIGludCBpbmRleCwgY29uc3QgVmFsdWVUeXBlJiB2YWx1ZSkgY29uc3QgeworICAgIHR5cGVkZWYgdHlwZW5hbWUgUmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JWYWx1ZVR5cGUgQWN0dWFsVHlwZTsKKyAgICAvLyBJbiB0aGlzIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbnRlcmZhY2Ugd2UgcGFzcy9yZXR1cm4gZGF0YSB1c2luZworICAgIC8vIHJhdyBwb2ludGVycy4gVHlwZSBvZiB0aGUgZGF0YSB0aGVzZSByYXcgcG9pbnRlcnMgcG9pbnQgdG8gc2hvdWxkCisgICAgLy8gYmUgQWN0dWFsVHlwZS4gSGVyZSB3ZSBoYXZlIGEgVmFsdWVUeXBlIG9iamVjdCBhbmQgd2FudCBhIEFjdHVhbFR5cGUKKyAgICAvLyBwb2ludGVyLiBXZSBjYW4ndCBjYXN0IGEgVmFsdWVUeXBlIHBvaW50ZXIgdG8gYW4gQWN0dWFsVHlwZSBwb2ludGVyCisgICAgLy8gZGlyZWN0bHkgYmVjYXVzZSB0aGVpciB0eXBlIG1pZ2h0IGJlIGRpZmZlcmVudCAoZm9yIGVudW1zIFZhbHVlVHlwZQorICAgIC8vIG1heSBiZSBhIGdlbmVyYXRlZCBlbnVtIHR5cGUgd2hpbGUgQWN0dWFsVHlwZSBpcyBpbnQzMikuIFRvIGJlIHNhZmUKKyAgICAvLyB3ZSBtYWtlIGEgY29weSB0byBnZXQgYSB0ZW1wb3JhcnkgQWN0dWFsVHlwZSBvYmplY3QgYW5kIHVzZSBpdC4KKyAgICBBY3R1YWxUeXBlIHRtcCA9IHN0YXRpY19jYXN0PEFjdHVhbFR5cGU+KHZhbHVlKTsKKyAgICBTZXQoZGF0YSwgaW5kZXgsIHN0YXRpY19jYXN0PGNvbnN0IFZhbHVlKj4oJnRtcCkpOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVmFsdWVUeXBlPgorICB2b2lkIEFkZChGaWVsZCogZGF0YSwgY29uc3QgVmFsdWVUeXBlJiB2YWx1ZSkgY29uc3QgeworICAgIHR5cGVkZWYgdHlwZW5hbWUgUmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JWYWx1ZVR5cGUgQWN0dWFsVHlwZTsKKyAgICAvLyBJbiB0aGlzIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbnRlcmZhY2Ugd2UgcGFzcy9yZXR1cm4gZGF0YSB1c2luZworICAgIC8vIHJhdyBwb2ludGVycy4gVHlwZSBvZiB0aGUgZGF0YSB0aGVzZSByYXcgcG9pbnRlcnMgcG9pbnQgdG8gc2hvdWxkCisgICAgLy8gYmUgQWN0dWFsVHlwZS4gSGVyZSB3ZSBoYXZlIGEgVmFsdWVUeXBlIG9iamVjdCBhbmQgd2FudCBhIEFjdHVhbFR5cGUKKyAgICAvLyBwb2ludGVyLiBXZSBjYW4ndCBjYXN0IGEgVmFsdWVUeXBlIHBvaW50ZXIgdG8gYW4gQWN0dWFsVHlwZSBwb2ludGVyCisgICAgLy8gZGlyZWN0bHkgYmVjYXVzZSB0aGVpciB0eXBlIG1pZ2h0IGJlIGRpZmZlcmVudCAoZm9yIGVudW1zIFZhbHVlVHlwZQorICAgIC8vIG1heSBiZSBhIGdlbmVyYXRlZCBlbnVtIHR5cGUgd2hpbGUgQWN0dWFsVHlwZSBpcyBpbnQzMikuIFRvIGJlIHNhZmUKKyAgICAvLyB3ZSBtYWtlIGEgY29weSB0byBnZXQgYSB0ZW1wb3JhcnkgQWN0dWFsVHlwZSBvYmplY3QgYW5kIHVzZSBpdC4KKyAgICBBY3R1YWxUeXBlIHRtcCA9IHN0YXRpY19jYXN0PEFjdHVhbFR5cGU+KHZhbHVlKTsKKyAgICBBZGQoZGF0YSwgc3RhdGljX2Nhc3Q8Y29uc3QgVmFsdWUqPigmdG1wKSk7CisgIH0KK307CisKKy8vIEltcGxlbWVudCAoTXV0YWJsZSlSZXBlYXRlZEZpZWxkUmVmOjppdGVyYXRvcgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcgorICAgIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywgVD4geworICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46Okl0ZXJhdG9yVmFsdWVUeXBlIEl0ZXJhdG9yVmFsdWVUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46Okl0ZXJhdG9yUG9pbnRlclR5cGUgSXRlcmF0b3JQb2ludGVyVHlwZTsKKworIHB1YmxpYzoKKyAgLy8gQ29uc3RydWN0b3IgZm9yIG5vbi1tZXNzYWdlIGZpZWxkcy4KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGNvbnN0IHZvaWQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIGFjY2Vzc29yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBiZWdpbikKKyAgICAgIDogZGF0YV8oZGF0YSksIGFjY2Vzc29yXyhhY2Nlc3NvciksCisgICAgICAgIGl0ZXJhdG9yXyhiZWdpbiA/IGFjY2Vzc29yLT5CZWdpbkl0ZXJhdG9yKGRhdGEpIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPkVuZEl0ZXJhdG9yKGRhdGEpKSwKKyAgICAgICAgc2NyYXRjaF9zcGFjZV8obmV3IEFjY2Vzc29yVmFsdWVUeXBlKSB7CisgIH0KKyAgLy8gQ29uc3RydWN0b3IgZm9yIG1lc3NhZ2UgZmllbGRzLgorICBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IoY29uc3Qgdm9pZCogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlcGVhdGVkRmllbGRBY2Nlc3NvciogYWNjZXNzb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJlZ2luLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzb3JWYWx1ZVR5cGUqIHNjcmF0Y2hfc3BhY2UpCisgICAgICA6IGRhdGFfKGRhdGEpLCBhY2Nlc3Nvcl8oYWNjZXNzb3IpLAorICAgICAgICBpdGVyYXRvcl8oYmVnaW4gPyBhY2Nlc3Nvci0+QmVnaW5JdGVyYXRvcihkYXRhKSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5FbmRJdGVyYXRvcihkYXRhKSksCisgICAgICAgIHNjcmF0Y2hfc3BhY2VfKHNjcmF0Y2hfc3BhY2UpIHsKKyAgfQorICB+UmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKCkgeworICAgIGFjY2Vzc29yXy0+RGVsZXRlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7CisgICAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yIHRtcCgqdGhpcyk7CisgICAgaXRlcmF0b3JfID0gYWNjZXNzb3JfLT5BZHZhbmNlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgICAgcmV0dXJuIHRtcDsKKyAgfQorICBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7CisgICAgaXRlcmF0b3JfID0gYWNjZXNzb3JfLT5BZHZhbmNlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIEl0ZXJhdG9yVmFsdWVUeXBlIG9wZXJhdG9yKigpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8SXRlcmF0b3JWYWx1ZVR5cGU+KAorICAgICAgICAqc3RhdGljX2Nhc3Q8Y29uc3QgQWNjZXNzb3JWYWx1ZVR5cGUqPigKKyAgICAgICAgICAgIGFjY2Vzc29yXy0+R2V0SXRlcmF0b3JWYWx1ZSgKKyAgICAgICAgICAgICAgICBkYXRhXywgaXRlcmF0b3JfLCBzY3JhdGNoX3NwYWNlXy5nZXQoKSkpKTsKKyAgfQorICBJdGVyYXRvclBvaW50ZXJUeXBlIG9wZXJhdG9yLT4oKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PEl0ZXJhdG9yUG9pbnRlclR5cGU+KAorICAgICAgICBhY2Nlc3Nvcl8tPkdldEl0ZXJhdG9yVmFsdWUoCisgICAgICAgICAgICBkYXRhXywgaXRlcmF0b3JfLCBzY3JhdGNoX3NwYWNlXy5nZXQoKSkpOworICB9CisgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKSBjb25zdCB7CisgICAgYXNzZXJ0KGRhdGFfID09IG90aGVyLmRhdGFfKTsKKyAgICBhc3NlcnQoYWNjZXNzb3JfID09IG90aGVyLmFjY2Vzc29yXyk7CisgICAgcmV0dXJuICFhY2Nlc3Nvcl8tPkVxdWFsc0l0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8sIG90aGVyLml0ZXJhdG9yXyk7CisgIH0KKyAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gIXRoaXMtPm9wZXJhdG9yIT0ob3RoZXIpOworICB9CisKKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGNvbnN0IFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3RoZXIpCisgICAgICA6IGRhdGFfKG90aGVyLmRhdGFfKSwgYWNjZXNzb3JfKG90aGVyLmFjY2Vzc29yXyksCisgICAgICAgIGl0ZXJhdG9yXyhhY2Nlc3Nvcl8tPkNvcHlJdGVyYXRvcihkYXRhXywgb3RoZXIuaXRlcmF0b3JfKSkgeworICB9CisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3BlcmF0b3I9KGNvbnN0IFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3RoZXIpIHsKKyAgICBpZiAodGhpcyAhPSAmb3RoZXIpIHsKKyAgICAgIGFjY2Vzc29yXy0+RGVsZXRlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgICAgICBkYXRhXyA9IG90aGVyLmRhdGFfOworICAgICAgYWNjZXNzb3JfID0gb3RoZXIuYWNjZXNzb3JfOworICAgICAgaXRlcmF0b3JfID0gYWNjZXNzb3JfLT5Db3B5SXRlcmF0b3IoZGF0YV8sIG90aGVyLml0ZXJhdG9yXyk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgcHJvdGVjdGVkOgorICBjb25zdCB2b2lkKiBkYXRhXzsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBhY2Nlc3Nvcl87CisgIHZvaWQqIGl0ZXJhdG9yXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxBY2Nlc3NvclZhbHVlVHlwZT4gc2NyYXRjaF9zcGFjZV87Cit9OworCisvLyBUeXBlVHJhaXRzIHRoYXQgbWFwcyB0aGUgdHlwZSBwYXJhbWV0ZXIgVCBvZiBSZXBlYXRlZEZpZWxkUmVmIG9yCisvLyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiB0byBjb3JyZXNwb25kaW5nIGl0ZXJhdG9yIHR5cGUsCisvLyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgdHlwZSwgZXRjLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBQcmltaXRpdmVUcmFpdHMgeworICBzdGF0aWMgY29uc3QgYm9vbCBpc19wcmltaXRpdmUgPSBmYWxzZTsKK307CisjZGVmaW5lIERFRklORV9QUklNSVRJVkUoVFlQRSwgdHlwZSkgXAorICAgIHRlbXBsYXRlPD4gc3RydWN0IFByaW1pdGl2ZVRyYWl0czx0eXBlPiB7IFwKKyAgICAgIHN0YXRpYyBjb25zdCBib29sIGlzX3ByaW1pdGl2ZSA9IHRydWU7IFwKKyAgICAgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUgPSBcCisgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyAjIyBUWVBFOyBcCisgICAgfTsKK0RFRklORV9QUklNSVRJVkUoSU5UMzIsIGludDMyKQorREVGSU5FX1BSSU1JVElWRShVSU5UMzIsIHVpbnQzMikKK0RFRklORV9QUklNSVRJVkUoSU5UNjQsIGludDY0KQorREVGSU5FX1BSSU1JVElWRShVSU5UNjQsIHVpbnQ2NCkKK0RFRklORV9QUklNSVRJVkUoRkxPQVQsIGZsb2F0KQorREVGSU5FX1BSSU1JVElWRShET1VCTEUsIGRvdWJsZSkKK0RFRklORV9QUklNSVRJVkUoQk9PTCwgYm9vbCkKKyN1bmRlZiBERUZJTkVfUFJJTUlUSVZFCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUmVmVHlwZVRyYWl0czwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPFByaW1pdGl2ZVRyYWl0czxUPjo6aXNfcHJpbWl0aXZlPjo6dHlwZT4geworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcjxUPiBpdGVyYXRvcjsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgQWNjZXNzb3JUeXBlOworICB0eXBlZGVmIFQgQWNjZXNzb3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgVCBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBUKiBJdGVyYXRvclBvaW50ZXJUeXBlOworICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0KKyAgICAgIFByaW1pdGl2ZVRyYWl0czxUPjo6Y3BwX3R5cGU7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxpc19wcm90b19lbnVtPFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgLy8gV2UgdXNlIGludDMyIGZvciByZXBlYXRlZCBlbnVtcyBpbiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IuCisgIHR5cGVkZWYgaW50MzIgQWNjZXNzb3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgVCBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBpbnQzMiogSXRlcmF0b3JQb2ludGVyVHlwZTsKKyAgc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSA9CisgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTsKKyAgc3RhdGljIGNvbnN0IERlc2NyaXB0b3IqIEdldE1lc3NhZ2VGaWVsZERlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUmVmVHlwZVRyYWl0czwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPGludGVybmFsOjppc19zYW1lPHN0cmluZywgVD46OnZhbHVlPjo6dHlwZT4geworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcjxUPiBpdGVyYXRvcjsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgQWNjZXNzb3JUeXBlOworICB0eXBlZGVmIHN0cmluZyBBY2Nlc3NvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBzdHJpbmcgSXRlcmF0b3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgc3RyaW5nKiBJdGVyYXRvclBvaW50ZXJUeXBlOworICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0KKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IE1lc3NhZ2VEZXNjcmlwdG9yR2V0dGVyIHsKKyAgc3RhdGljIGNvbnN0IERlc2NyaXB0b3IqIGdldCgpIHsKKyAgICByZXR1cm4gVDo6ZGVmYXVsdF9pbnN0YW5jZSgpLkdldERlc2NyaXB0b3IoKTsKKyAgfQorfTsKK3RlbXBsYXRlPD4KK3N0cnVjdCBNZXNzYWdlRGVzY3JpcHRvckdldHRlcjxNZXNzYWdlPiB7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBnZXQoKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUmVmVHlwZVRyYWl0czwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPGludGVybmFsOjppc19iYXNlX29mPE1lc3NhZ2UsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiBNZXNzYWdlIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIGNvbnN0IFQmIEl0ZXJhdG9yVmFsdWVUeXBlOworICB0eXBlZGVmIGNvbnN0IFQqIEl0ZXJhdG9yUG9pbnRlclR5cGU7CisgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUgPQorICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBNZXNzYWdlRGVzY3JpcHRvckdldHRlcjxUPjo6Z2V0KCk7CisgIH0KK307Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9SRUZMRUNUSU9OX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX2ludGVybmFsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25faW50ZXJuYWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mY2I0MjQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX2ludGVybmFsLmgKQEAgLTAsMCArMSwzNzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9SRUZMRUNUSU9OX0lOVEVSTkFMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9JTlRFUk5BTF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworLy8gQSBiYXNlIGNsYXNzIGZvciBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgaW1wbGVtZW50YXRpb25zIHRoYXQgY2FuIHN1cHBvcnQKKy8vIHJhbmRvbS1hY2Nlc3MgZWZmaWNpZW50bHkuIEFsbCBpdGVyYXRvciBtZXRob2RzIGRlbGVnYXRlcyB0aGUgd29yayB0bworLy8gY29ycmVzcG9uZGluZyByYW5kb20tYWNjZXNzIG1ldGhvZHMuCitjbGFzcyBSYW5kb21BY2Nlc3NSZXBlYXRlZEZpZWxkQWNjZXNzb3IgOiBwdWJsaWMgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgflJhbmRvbUFjY2Vzc1JlcGVhdGVkRmllbGRBY2Nlc3NvcigpIHt9CisKKyAgdmlydHVhbCBJdGVyYXRvciogQmVnaW5JdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgeworICAgIHJldHVybiBQb3NpdGlvblRvSXRlcmF0b3IoMCk7CisgIH0KKyAgdmlydHVhbCBJdGVyYXRvciogRW5kSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICByZXR1cm4gUG9zaXRpb25Ub0l0ZXJhdG9yKHRoaXMtPlNpemUoZGF0YSkpOworICB9CisgIHZpcnR1YWwgSXRlcmF0b3IqIENvcHlJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBpdGVyYXRvcikgY29uc3QgeworICAgIHJldHVybiBjb25zdF9jYXN0PEl0ZXJhdG9yKj4oaXRlcmF0b3IpOworICB9CisgIHZpcnR1YWwgSXRlcmF0b3IqIEFkdmFuY2VJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yKiBpdGVyYXRvcikgY29uc3QgeworICAgIHJldHVybiBQb3NpdGlvblRvSXRlcmF0b3IoSXRlcmF0b3JUb1Bvc2l0aW9uKGl0ZXJhdG9yKSArIDEpOworICB9CisgIHZpcnR1YWwgYm9vbCBFcXVhbHNJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSXRlcmF0b3IqIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYSA9PSBiOworICB9CisgIHZpcnR1YWwgdm9pZCBEZWxldGVJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCB7CisgIH0KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogR2V0SXRlcmF0b3JWYWx1ZShjb25zdCBGaWVsZCogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogaXRlcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0KGRhdGEsIHN0YXRpY19jYXN0PGludD4oSXRlcmF0b3JUb1Bvc2l0aW9uKGl0ZXJhdG9yKSksCisgICAgICAgICAgICAgICBzY3JhdGNoX3NwYWNlKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgc3RhdGljIGludHB0cl90IEl0ZXJhdG9yVG9Qb3NpdGlvbihjb25zdCBJdGVyYXRvciogaXRlcmF0b3IpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxpbnRwdHJfdD4oaXRlcmF0b3IpOworICB9CisgIHN0YXRpYyBJdGVyYXRvciogUG9zaXRpb25Ub0l0ZXJhdG9yKGludHB0cl90IHBvc2l0aW9uKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8SXRlcmF0b3IqPihwb3NpdGlvbik7CisgIH0KK307CisKKy8vIEJhc2UgY2xhc3MgZm9yIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbXBsZW1lbnRhdGlvbnMgdGhhdCBtYW5pcHVsYXRlcworLy8gUmVwZWF0ZWRGaWVsZDxUPi4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkV3JhcHBlciA6IHB1YmxpYyBSYW5kb21BY2Nlc3NSZXBlYXRlZEZpZWxkQWNjZXNzb3IgeworIHB1YmxpYzoKKyAgUmVwZWF0ZWRGaWVsZFdyYXBwZXIoKSB7fQorICB2aXJ0dWFsIH5SZXBlYXRlZEZpZWxkV3JhcHBlcigpIHt9CisgIHZpcnR1YWwgYm9vbCBJc0VtcHR5KGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgcmV0dXJuIEdldFJlcGVhdGVkRmllbGQoZGF0YSktPmVtcHR5KCk7CisgIH0KKyAgdmlydHVhbCBpbnQgU2l6ZShjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgeworICAgIHJldHVybiBHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5zaXplKCk7CisgIH0KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogR2V0KGNvbnN0IEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuIENvbnZlcnRGcm9tVChHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5HZXQoaW5kZXgpLCBzY3JhdGNoX3NwYWNlKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgQ2xlYXIoRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+Q2xlYXIoKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgU2V0KEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5TZXQoaW5kZXgsIENvbnZlcnRUb1QodmFsdWUpKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgQWRkKEZpZWxkKiBkYXRhLCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+QWRkKENvbnZlcnRUb1QodmFsdWUpKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgUmVtb3ZlTGFzdChGaWVsZCogZGF0YSkgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5SZW1vdmVMYXN0KCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFN3YXBFbGVtZW50cyhGaWVsZCogZGF0YSwgaW50IGluZGV4MSwgaW50IGluZGV4MikgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZDxUPiBSZXBlYXRlZEZpZWxkVHlwZTsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKiBHZXRSZXBlYXRlZEZpZWxkKGNvbnN0IEZpZWxkKiBkYXRhKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqPihkYXRhKTsKKyAgfQorICBzdGF0aWMgUmVwZWF0ZWRGaWVsZFR5cGUqIE11dGFibGVSZXBlYXRlZEZpZWxkKEZpZWxkKiBkYXRhKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRGaWVsZFR5cGUqPihkYXRhKTsKKyAgfQorCisgIC8vIENvbnZlcnQgYW4gb2JqZWN0IHJlY2V2aWVkIGJ5IHRoaXMgYWNjZXNzb3IgdG8gYW4gb2JqZWN0IHRvIGJlIHN0b3JlZCBpbgorICAvLyB0aGUgdW5kZXJseWluZyBSZXBlYXRlZEZpZWxkLgorICB2aXJ0dWFsIFQgQ29udmVydFRvVChjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0ID0gMDsKKworICAvLyBDb252ZXJ0IGFuIG9iamVjdCBzdG9yZWQgaW4gUmVwZWF0ZWRQdHJGaWVsZCB0byBhbiBvYmplY3QgdGhhdCB3aWxsIGJlCisgIC8vIHJldHVybmVkIGJ5IHRoaXMgYWNjZXNzb3IuIElmIHRoZSB0d28gb2JqZWN0cyBoYXZlIHRoZSBzYW1lIHR5cGUgKHRydWUKKyAgLy8gZm9yIHN0cmluZyBmaWVsZHMgd2l0aCBjdHlwZT1TVFJJTkcpLCBhIHBvaW50ZXIgdG8gdGhlIHNvdXJjZSBvYmplY3QgY2FuCisgIC8vIGJlIHJldHVybmVkIGRpcmVjdGx5LiBPdGhlcndpc2UsIGRhdGEgc2hvdWxkIGJlIGNvcGllZCBmcm9tIHZhbHVlIHRvCisgIC8vIHNjcmF0Y2hfc3BhY2UgYW5kIHNjcmF0Y2hfc3BhY2Ugc2hvdWxkIGJlIHJldHVybmVkLgorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBDb252ZXJ0RnJvbVQoY29uc3QgVCYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgPSAwOworfTsKKworLy8gQmFzZSBjbGFzcyBmb3IgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIGltcGxlbWVudGF0aW9ucyB0aGF0IG1hbmlwdWxhdGVzCisvLyBSZXBlYXRlZFB0ckZpZWxkPFQ+LgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFJlcGVhdGVkUHRyRmllbGRXcmFwcGVyIDogcHVibGljIFJhbmRvbUFjY2Vzc1JlcGVhdGVkRmllbGRBY2Nlc3NvciB7CisgcHVibGljOgorICBSZXBlYXRlZFB0ckZpZWxkV3JhcHBlcigpIHt9CisgIHZpcnR1YWwgflJlcGVhdGVkUHRyRmllbGRXcmFwcGVyKCkge30KKyAgdmlydHVhbCBib29sIElzRW1wdHkoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+ZW1wdHkoKTsKKyAgfQorICB2aXJ0dWFsIGludCBTaXplKGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgcmV0dXJuIEdldFJlcGVhdGVkRmllbGQoZGF0YSktPnNpemUoKTsKKyAgfQorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBHZXQoY29uc3QgRmllbGQqIGRhdGEsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuIENvbnZlcnRGcm9tVChHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5HZXQoaW5kZXgpLCBzY3JhdGNoX3NwYWNlKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgQ2xlYXIoRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+Q2xlYXIoKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgU2V0KEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgeworICAgIENvbnZlcnRUb1QodmFsdWUsIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5NdXRhYmxlKGluZGV4KSk7CisgIH0KKyAgdmlydHVhbCB2b2lkIEFkZChGaWVsZCogZGF0YSwgY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCB7CisgICAgVCogYWxsb2NhdGVkID0gTmV3KHZhbHVlKTsKKyAgICBDb252ZXJ0VG9UKHZhbHVlLCBhbGxvY2F0ZWQpOworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5BZGRBbGxvY2F0ZWQoYWxsb2NhdGVkKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgUmVtb3ZlTGFzdChGaWVsZCogZGF0YSkgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5SZW1vdmVMYXN0KCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFN3YXBFbGVtZW50cyhGaWVsZCogZGF0YSwgaW50IGluZGV4MSwgaW50IGluZGV4MikgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIHR5cGVkZWYgUmVwZWF0ZWRQdHJGaWVsZDxUPiBSZXBlYXRlZEZpZWxkVHlwZTsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKiBHZXRSZXBlYXRlZEZpZWxkKGNvbnN0IEZpZWxkKiBkYXRhKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqPihkYXRhKTsKKyAgfQorICBzdGF0aWMgUmVwZWF0ZWRGaWVsZFR5cGUqIE11dGFibGVSZXBlYXRlZEZpZWxkKEZpZWxkKiBkYXRhKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRGaWVsZFR5cGUqPihkYXRhKTsKKyAgfQorCisgIC8vIENyZWF0ZSBhIG5ldyBUIGluc3RhbmNlLiBGb3IgcmVwZWF0ZWQgbWVzc2FnZSBmaWVsZHMsIFQgY2FuIGJlIHNwZWNpZmllZAorICAvLyBhcyBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHNvIHdlIGNhbid0IHVzZSAibmV3IFQoKSIgZGlyZWN0bHkuIEluIHRoYXQgY2FzZSwgdmFsdWUKKyAgLy8gc2hvdWxkIGJlIGEgbWVzc2FnZSBvZiB0aGUgc2FtZSB0eXBlIChpdCdzIGVuc3VyZWQgYnkgdGhlIGNhbGxlcikgYW5kIGEKKyAgLy8gbmV3IG1lc3NhZ2Ugb2JqZWN0IHdpbGwgYmUgY3JlYXRlZCB1c2luZyBpdC4KKyAgdmlydHVhbCBUKiBOZXcoY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCA9IDA7CisKKyAgLy8gQ29udmVydCBhbiBvYmplY3QgcmVjZWl2ZWQgYnkgdGhpcyBhY2Nlc3NvciB0byBhbiBvYmplY3QgdGhhdCB3aWxsIGJlCisgIC8vIHN0b3JlZCBpbiB0aGUgdW5kZXJseWluZyBSZXBlYXRlZFB0ckZpZWxkLgorICB2aXJ0dWFsIHZvaWQgQ29udmVydFRvVChjb25zdCBWYWx1ZSogdmFsdWUsIFQqIHJlc3VsdCkgY29uc3QgPSAwOworCisgIC8vIENvbnZlcnQgYW4gb2JqZWN0IHN0b3JlZCBpbiBSZXBlYXRlZFB0ckZpZWxkIHRvIGFuIG9iamVjdCB0aGF0IHdpbGwgYmUKKyAgLy8gcmV0dXJuZWQgYnkgdGhpcyBhY2Nlc3Nvci4gSWYgdGhlIHR3byBvYmplY3RzIGhhdmUgdGhlIHNhbWUgdHlwZSAodHJ1ZQorICAvLyBmb3Igc3RyaW5nIGZpZWxkcyB3aXRoIGN0eXBlPVNUUklORyksIGEgcG9pbnRlciB0byB0aGUgc291cmNlIG9iamVjdCBjYW4KKyAgLy8gYmUgcmV0dXJuZWQgZGlyZWN0bHkuIE90aGVyd2lzZSwgZGF0YSBzaG91bGQgYmUgY29waWVkIGZyb20gdmFsdWUgdG8KKyAgLy8gc2NyYXRjaF9zcGFjZSBhbmQgc2NyYXRjaF9zcGFjZSBzaG91bGQgYmUgcmV0dXJuZWQuCisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIENvbnZlcnRGcm9tVChjb25zdCBUJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCA9IDA7Cit9OworCisvLyBBbiBpbXBsZW1lbnRhdGlvbiBvZiBSYW5kb21BY2Nlc3NSZXBlYXRlZEZpZWxkQWNjZXNzb3IgdGhhdCBtYW5pcHVsYXRlcworLy8gTWFwRmllbGRCYXNlLgorY2xhc3MgTWFwRmllbGRBY2Nlc3NvciA6IHB1YmxpYyBSYW5kb21BY2Nlc3NSZXBlYXRlZEZpZWxkQWNjZXNzb3IgeworIHB1YmxpYzoKKyAgTWFwRmllbGRBY2Nlc3NvcigpIHt9CisgIHZpcnR1YWwgfk1hcEZpZWxkQWNjZXNzb3IoKSB7fQorICB2aXJ0dWFsIGJvb2wgSXNFbXB0eShjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgeworICAgIHJldHVybiBHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5lbXB0eSgpOworICB9CisgIHZpcnR1YWwgaW50IFNpemUoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+c2l6ZSgpOworICB9CisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldChjb25zdCBGaWVsZCogZGF0YSwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gQ29udmVydEZyb21FbnRyeShHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5HZXQoaW5kZXgpLCBzY3JhdGNoX3NwYWNlKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgQ2xlYXIoRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+Q2xlYXIoKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgU2V0KEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgeworICAgIENvbnZlcnRUb0VudHJ5KHZhbHVlLCBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+TXV0YWJsZShpbmRleCkpOworICB9CisgIHZpcnR1YWwgdm9pZCBBZGQoRmllbGQqIGRhdGEsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgeworICAgIE1lc3NhZ2UqIGFsbG9jYXRlZCA9IE5ldyh2YWx1ZSk7CisgICAgQ29udmVydFRvRW50cnkodmFsdWUsIGFsbG9jYXRlZCk7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPkFkZEFsbG9jYXRlZChhbGxvY2F0ZWQpOworICB9CisgIHZpcnR1YWwgdm9pZCBSZW1vdmVMYXN0KEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPlJlbW92ZUxhc3QoKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgU3dhcEVsZW1lbnRzKEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSBjb25zdCB7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgIH0KKyAgdmlydHVhbCB2b2lkIFN3YXAoCisgICAgICBGaWVsZCogZGF0YSwKKyAgICAgIGNvbnN0IGludGVybmFsOjpSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIG90aGVyX211dGF0b3IsCisgICAgICBGaWVsZCogb3RoZXJfZGF0YSkgY29uc3QgeworICAgIEdPT0dMRV9DSEVDSyh0aGlzID09IG90aGVyX211dGF0b3IpOworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwKE11dGFibGVSZXBlYXRlZEZpZWxkKG90aGVyX2RhdGEpKTsKKyAgfQorCisgcHJvdGVjdGVkOgorICB0eXBlZGVmIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4gUmVwZWF0ZWRGaWVsZFR5cGU7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogR2V0UmVwZWF0ZWRGaWVsZChjb25zdCBGaWVsZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKj4oCisgICAgICAgICgmcmVpbnRlcnByZXRfY2FzdDxjb25zdCBNYXBGaWVsZEJhc2UqPihkYXRhKS0+R2V0UmVwZWF0ZWRGaWVsZCgpKSk7CisgIH0KKyAgc3RhdGljIFJlcGVhdGVkRmllbGRUeXBlKiBNdXRhYmxlUmVwZWF0ZWRGaWVsZChGaWVsZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGRUeXBlKj4oCisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8TWFwRmllbGRCYXNlKj4oZGF0YSktPk11dGFibGVSZXBlYXRlZEZpZWxkKCkpOworICB9CisgIHZpcnR1YWwgTWVzc2FnZSogTmV3KGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBNZXNzYWdlKj4odmFsdWUpLT5OZXcoKTsKKyAgfQorICAvLyBDb252ZXJ0IGFuIG9iamVjdCByZWNlaXZlZCBieSB0aGlzIGFjY2Vzc29yIHRvIGFuIE1hcEVudHJ5IG1lc3NhZ2UgdG8gYmUKKyAgLy8gc3RvcmVkIGluIHRoZSB1bmRlcmx5aW5nIE1hcEZpZWxkQmFzZS4KKyAgdmlydHVhbCB2b2lkIENvbnZlcnRUb0VudHJ5KGNvbnN0IFZhbHVlKiB2YWx1ZSwgTWVzc2FnZSogcmVzdWx0KSBjb25zdCB7CisgICAgcmVzdWx0LT5Db3B5RnJvbSgqc3RhdGljX2Nhc3Q8Y29uc3QgTWVzc2FnZSo+KHZhbHVlKSk7CisgIH0KKyAgLy8gQ29udmVydCBhIE1hcEVudHJ5IG1lc3NhZ2Ugc3RvcmVkIGluIHRoZSB1bmRlcmx5aW5nIE1hcEZpZWxkQmFzZSB0byBhbgorICAvLyBvYmplY3QgdGhhdCB3aWxsIGJlIHJldHVybmVkIGJ5IHRoaXMgYWNjZXNzb3IuCisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIENvbnZlcnRGcm9tRW50cnkoY29uc3QgTWVzc2FnZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVmFsdWUqPigmdmFsdWUpOworICB9Cit9OworCisvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9ucyBvZiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgZm9yIHByaW1pdGl2ZSB0eXBlcy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3IgOiBwdWJsaWMgUmVwZWF0ZWRGaWVsZFdyYXBwZXI8VD4geworICB0eXBlZGVmIHZvaWQgRmllbGQ7CisgIHR5cGVkZWYgdm9pZCBWYWx1ZTsKKyAgdXNpbmcgUmVwZWF0ZWRGaWVsZFdyYXBwZXI8VD46Ok11dGFibGVSZXBlYXRlZEZpZWxkOworCisgcHVibGljOgorICBSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3IoKSB7fQorICB2aXJ0dWFsIH5SZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3IoKSB7fQorICB2aXJ0dWFsIHZvaWQgU3dhcCgKKyAgICAgIEZpZWxkKiBkYXRhLAorICAgICAgY29uc3QgaW50ZXJuYWw6OlJlcGVhdGVkRmllbGRBY2Nlc3Nvciogb3RoZXJfbXV0YXRvciwKKyAgICAgIEZpZWxkKiBvdGhlcl9kYXRhKSBjb25zdCB7CisgICAgLy8gQ3VycmVudGx5IFJlcGVhdGVkRmllbGRQcmltaXRpdmVBY2Nlc3NvciBpcyB0aGUgb25seSBpbXBsZW1lbnRhdGlvbiBvZgorICAgIC8vIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBmb3IgcHJpbWl0aXZlIHR5cGVzLiBBcyB3ZSBhcmUgdXNpbmcgc2luZ2xldG9ucworICAgIC8vIGZvciB0aGVzZSBhY2Nlc3NvcnMsIGhlcmUgIm90aGVyX211dGF0b3IiIG11c3QgYmUgInRoaXMiLgorICAgIEdPT0dMRV9DSEVDSyh0aGlzID09IG90aGVyX211dGF0b3IpOworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwKE11dGFibGVSZXBlYXRlZEZpZWxkKG90aGVyX2RhdGEpKTsKKyAgfQorCisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIFQgQ29udmVydFRvVChjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICByZXR1cm4gKnN0YXRpY19jYXN0PGNvbnN0IFQqPih2YWx1ZSk7CisgIH0KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogQ29udmVydEZyb21UKGNvbnN0IFQmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVmFsdWUqPigmdmFsdWUpOworICB9Cit9OworCisvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBmb3Igc3RyaW5nIGZpZWxkcyB3aXRoCisvLyBjdHlwZT1TVFJJTkcuCitjbGFzcyBSZXBlYXRlZFB0ckZpZWxkU3RyaW5nQWNjZXNzb3IgOiBwdWJsaWMgUmVwZWF0ZWRQdHJGaWVsZFdyYXBwZXI8c3RyaW5nPiB7CisgIHR5cGVkZWYgdm9pZCBGaWVsZDsKKyAgdHlwZWRlZiB2b2lkIFZhbHVlOworICB1c2luZyBSZXBlYXRlZEZpZWxkQWNjZXNzb3I6OkFkZDsKKworIHB1YmxpYzoKKyAgUmVwZWF0ZWRQdHJGaWVsZFN0cmluZ0FjY2Vzc29yKCkge30KKyAgdmlydHVhbCB+UmVwZWF0ZWRQdHJGaWVsZFN0cmluZ0FjY2Vzc29yKCkge30KKyAgdmlydHVhbCB2b2lkIFN3YXAoCisgICAgICBGaWVsZCogZGF0YSwKKyAgICAgIGNvbnN0IGludGVybmFsOjpSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIG90aGVyX211dGF0b3IsCisgICAgICBGaWVsZCogb3RoZXJfZGF0YSkgY29uc3QgeworICAgIGlmICh0aGlzID09IG90aGVyX211dGF0b3IpIHsKKyAgICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwKE11dGFibGVSZXBlYXRlZEZpZWxkKG90aGVyX2RhdGEpKTsKKyAgICB9IGVsc2UgeworICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IHRtcDsKKyAgICAgIHRtcC5Td2FwKE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpKTsKKyAgICAgIGludCBvdGhlcl9zaXplID0gb3RoZXJfbXV0YXRvci0+U2l6ZShvdGhlcl9kYXRhKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb3RoZXJfc2l6ZTsgKytpKSB7CisgICAgICAgIEFkZDxzdHJpbmc+KGRhdGEsIG90aGVyX211dGF0b3ItPkdldDxzdHJpbmc+KG90aGVyX2RhdGEsIGkpKTsKKyAgICAgIH0KKyAgICAgIGludCBzaXplID0gU2l6ZShkYXRhKTsKKyAgICAgIG90aGVyX211dGF0b3ItPkNsZWFyKG90aGVyX2RhdGEpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKKyAgICAgICAgb3RoZXJfbXV0YXRvci0+QWRkPHN0cmluZz4ob3RoZXJfZGF0YSwgdG1wLkdldChpKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgc3RyaW5nKiBOZXcoY29uc3QgVmFsdWUqKSBjb25zdCB7CisgICAgcmV0dXJuIG5ldyBzdHJpbmcoKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgQ29udmVydFRvVChjb25zdCBWYWx1ZSogdmFsdWUsIHN0cmluZyogcmVzdWx0KSBjb25zdCB7CisgICAgKnJlc3VsdCA9ICpzdGF0aWNfY2FzdDxjb25zdCBzdHJpbmcqPih2YWx1ZSk7CisgIH0KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogQ29udmVydEZyb21UKGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBWYWx1ZSo+KCZ2YWx1ZSk7CisgIH0KK307CisKKworY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZE1lc3NhZ2VBY2Nlc3NvcgorICAgIDogcHVibGljIFJlcGVhdGVkUHRyRmllbGRXcmFwcGVyPE1lc3NhZ2U+IHsKKyAgdHlwZWRlZiB2b2lkIEZpZWxkOworICB0eXBlZGVmIHZvaWQgVmFsdWU7CisKKyBwdWJsaWM6CisgIFJlcGVhdGVkUHRyRmllbGRNZXNzYWdlQWNjZXNzb3IoKSB7fQorICB2aXJ0dWFsIH5SZXBlYXRlZFB0ckZpZWxkTWVzc2FnZUFjY2Vzc29yKCkge30KKyAgdmlydHVhbCB2b2lkIFN3YXAoCisgICAgICBGaWVsZCogZGF0YSwKKyAgICAgIGNvbnN0IGludGVybmFsOjpSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIG90aGVyX211dGF0b3IsCisgICAgICBGaWVsZCogb3RoZXJfZGF0YSkgY29uc3QgeworICAgIEdPT0dMRV9DSEVDSyh0aGlzID09IG90aGVyX211dGF0b3IpOworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwKE11dGFibGVSZXBlYXRlZEZpZWxkKG90aGVyX2RhdGEpKTsKKyAgfQorCisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIE1lc3NhZ2UqIE5ldyhjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgTWVzc2FnZSo+KHZhbHVlKS0+TmV3KCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIENvbnZlcnRUb1QoY29uc3QgVmFsdWUqIHZhbHVlLCBNZXNzYWdlKiByZXN1bHQpIGNvbnN0IHsKKyAgICByZXN1bHQtPkNvcHlGcm9tKCpzdGF0aWNfY2FzdDxjb25zdCBNZXNzYWdlKj4odmFsdWUpKTsKKyAgfQorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBDb252ZXJ0RnJvbVQoY29uc3QgTWVzc2FnZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBWYWx1ZSo+KCZ2YWx1ZSk7CisgIH0KK307Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9SRUZMRUNUSU9OX0lOVEVSTkFMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDYyOWRlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuY2MKQEAgLTAsMCArMSwyNjkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKwordm9pZCBSZWZsZWN0aW9uT3BzOjpDb3B5KGNvbnN0IE1lc3NhZ2UmIGZyb20sIE1lc3NhZ2UqIHRvKSB7CisgIGlmICgmZnJvbSA9PSB0bykgcmV0dXJuOworICBDbGVhcih0byk7CisgIE1lcmdlKGZyb20sIHRvKTsKK30KKwordm9pZCBSZWZsZWN0aW9uT3BzOjpNZXJnZShjb25zdCBNZXNzYWdlJiBmcm9tLCBNZXNzYWdlKiB0bykgeworICBHT09HTEVfQ0hFQ0tfTkUoJmZyb20sIHRvKTsKKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gZnJvbS5HZXREZXNjcmlwdG9yKCk7CisgIEdPT0dMRV9DSEVDS19FUSh0by0+R2V0RGVzY3JpcHRvcigpLCBkZXNjcmlwdG9yKQorICAgIDw8ICJUcmllZCB0byBtZXJnZSBtZXNzYWdlcyBvZiBkaWZmZXJlbnQgdHlwZXMgIgorICAgIDw8ICIobWVyZ2UgIiA8PCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKQorICAgIDw8ICIgdG8gIiA8PCB0by0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKSA8PCAiKSI7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogZnJvbV9yZWZsZWN0aW9uID0gZnJvbS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHRvX3JlZmxlY3Rpb24gPSB0by0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGZyb21fcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhmcm9tLCAmZmllbGRzKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworCisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBpbnQgY291bnQgPSBmcm9tX3JlZmxlY3Rpb24tPkZpZWxkU2l6ZShmcm9tLCBmaWVsZCk7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShDUFBUWVBFLCBNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICB0b19yZWZsZWN0aW9uLT5BZGQjI01FVEhPRCh0bywgZmllbGQsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICBmcm9tX3JlZmxlY3Rpb24tPkdldFJlcGVhdGVkIyNNRVRIT0QoZnJvbSwgZmllbGQsIGopKTsgICAgIFwKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgSEFORExFX1RZUEUoSU5UMzIgLCBJbnQzMiApOworICAgICAgICAgIEhBTkRMRV9UWVBFKElOVDY0ICwgSW50NjQgKTsKKyAgICAgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIFVJbnQzMik7CisgICAgICAgICAgSEFORExFX1RZUEUoVUlOVDY0LCBVSW50NjQpOworICAgICAgICAgIEhBTkRMRV9UWVBFKEZMT0FUICwgRmxvYXQgKTsKKyAgICAgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIERvdWJsZSk7CisgICAgICAgICAgSEFORExFX1RZUEUoQk9PTCAgLCBCb29sICApOworICAgICAgICAgIEhBTkRMRV9UWVBFKFNUUklORywgU3RyaW5nKTsKKyAgICAgICAgICBIQU5ETEVfVFlQRShFTlVNICAsIEVudW0gICk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgICB0b19yZWZsZWN0aW9uLT5BZGRNZXNzYWdlKHRvLCBmaWVsZCktPk1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgZnJvbV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UoZnJvbSwgZmllbGQsIGopKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoQ1BQVFlQRSwgTUVUSE9EKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjQ1BQVFlQRTogICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHRvX3JlZmxlY3Rpb24tPlNldCMjTUVUSE9EKHRvLCBmaWVsZCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGZyb21fcmVmbGVjdGlvbi0+R2V0IyNNRVRIT0QoZnJvbSwgZmllbGQpKTsgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgSEFORExFX1RZUEUoSU5UMzIgLCBJbnQzMiApOworICAgICAgICBIQU5ETEVfVFlQRShJTlQ2NCAsIEludDY0ICk7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgVUludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoVUlOVDY0LCBVSW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShGTE9BVCAsIEZsb2F0ICk7CisgICAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgRG91YmxlKTsKKyAgICAgICAgSEFORExFX1RZUEUoQk9PTCAgLCBCb29sICApOworICAgICAgICBIQU5ETEVfVFlQRShTVFJJTkcsIFN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKEVOVU0gICwgRW51bSAgKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgdG9fcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UodG8sIGZpZWxkKS0+TWVyZ2VGcm9tKAorICAgICAgICAgICAgZnJvbV9yZWZsZWN0aW9uLT5HZXRNZXNzYWdlKGZyb20sIGZpZWxkKSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisKKyAgdG9fcmVmbGVjdGlvbi0+TXV0YWJsZVVua25vd25GaWVsZHModG8pLT5NZXJnZUZyb20oCisgICAgZnJvbV9yZWZsZWN0aW9uLT5HZXRVbmtub3duRmllbGRzKGZyb20pKTsKK30KKwordm9pZCBSZWZsZWN0aW9uT3BzOjpDbGVhcihNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJmZpZWxkcyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBmaWVsZHNbaV0pOworICB9CisKKyAgcmVmbGVjdGlvbi0+TXV0YWJsZVVua25vd25GaWVsZHMobWVzc2FnZSktPkNsZWFyKCk7Cit9CisKK2Jvb2wgUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBvZiB0aGlzIG1lc3NhZ2UuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPmZpZWxkKGkpLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICBpZiAoIXJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2NyaXB0b3ItPmZpZWxkKGkpKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gQ2hlY2sgdGhhdCBzdWItbWVzc2FnZXMgYXJlIGluaXRpYWxpemVkLgorICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UsICZmaWVsZHMpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBmaWVsZHNbaV07CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisKKyAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBpbnQgc2l6ZSA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZCk7CisKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzaXplOyBqKyspIHsKKyAgICAgICAgICBpZiAoIXJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBmaWVsZCwgaikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLklzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKCFyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKS5Jc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBSZWZsZWN0aW9uT3BzOjpEaXNjYXJkVW5rbm93bkZpZWxkcyhNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgcmVmbGVjdGlvbi0+TXV0YWJsZVVua25vd25GaWVsZHMobWVzc2FnZSktPkNsZWFyKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJmZpZWxkcyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBpbnQgc2l6ZSA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgZmllbGQpOworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHNpemU7IGorKykgeworICAgICAgICAgIHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgZmllbGQsIGopCisgICAgICAgICAgICAgICAgICAgIC0+RGlzY2FyZFVua25vd25GaWVsZHMoKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UobWVzc2FnZSwgZmllbGQpLT5EaXNjYXJkVW5rbm93bkZpZWxkcygpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitzdGF0aWMgc3RyaW5nIFN1Yk1lc3NhZ2VQcmVmaXgoY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIHsKKyAgc3RyaW5nIHJlc3VsdChwcmVmaXgpOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmVzdWx0LmFwcGVuZCgiKCIpOworICAgIHJlc3VsdC5hcHBlbmQoZmllbGQtPmZ1bGxfbmFtZSgpKTsKKyAgICByZXN1bHQuYXBwZW5kKCIpIik7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0LmFwcGVuZChmaWVsZC0+bmFtZSgpKTsKKyAgfQorICBpZiAoaW5kZXggIT0gLTEpIHsKKyAgICByZXN1bHQuYXBwZW5kKCJbIik7CisgICAgcmVzdWx0LmFwcGVuZChTaW1wbGVJdG9hKGluZGV4KSk7CisgICAgcmVzdWx0LmFwcGVuZCgiXSIpOworICB9CisgIHJlc3VsdC5hcHBlbmQoIi4iKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBSZWZsZWN0aW9uT3BzOjpGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBjb25zdCBzdHJpbmcmIHByZWZpeCwKKyAgICB2ZWN0b3I8c3RyaW5nPiogZXJyb3JzKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBvZiB0aGlzIG1lc3NhZ2UuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPmZpZWxkKGkpLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICBpZiAoIXJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2NyaXB0b3ItPmZpZWxkKGkpKSkgeworICAgICAgICBlcnJvcnMtPnB1c2hfYmFjayhwcmVmaXggKyBkZXNjcmlwdG9yLT5maWVsZChpKS0+bmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBDaGVjayBzdWItbWVzc2FnZXMuCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZSwgJmZpZWxkcyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKworICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIGludCBzaXplID0gcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIGZpZWxkKTsKKworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHNpemU7IGorKykgeworICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBmaWVsZCwgaik7CisgICAgICAgICAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKHN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJNZXNzYWdlUHJlZml4KHByZWZpeCwgZmllbGQsIGopLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgZmllbGQpOworICAgICAgICBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJNZXNzYWdlUHJlZml4KHByZWZpeCwgZmllbGQsIC0xKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycyk7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDc3NTkxMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaApAQCAtMCwwICsxLDgxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBoZWFkZXIgaXMgbG9naWNhbGx5IGludGVybmFsLCBidXQgaXMgbWFkZSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCisvLyBmcm9tIHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZCBjb2RlLCB3aGljaCBtYXkgcmVzaWRlIGluIG90aGVyIGNvbXBvbmVudHMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1JFRkxFQ1RJT05fT1BTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9PUFNfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQmFzaWMgb3BlcmF0aW9ucyB0aGF0IGNhbiBiZSBwZXJmb3JtZWQgdXNpbmcgcmVmbGVjdGlvbi4KKy8vIFRoZXNlIGNhbiBiZSB1c2VkIGFzIGEgY2hlYXAgd2F5IHRvIGltcGxlbWVudCB0aGUgY29ycmVzcG9uZGluZworLy8gbWV0aG9kcyBvZiB0aGUgTWVzc2FnZSBpbnRlcmZhY2UsIHRob3VnaCB0aGV5IGFyZSBsaWtlbHkgdG8gYmUKKy8vIHNsb3dlciB0aGFuIGltcGxlbWVudGF0aW9ucyB0YWlsb3JlZCBmb3IgdGhlIHNwZWNpZmljIG1lc3NhZ2UgdHlwZS4KKy8vCisvLyBUaGlzIGNsYXNzIHNob3VsZCBzdGF5IGxpbWl0ZWQgdG8gb3BlcmF0aW9ucyBuZWVkZWQgdG8gaW1wbGVtZW50CisvLyB0aGUgTWVzc2FnZSBpbnRlcmZhY2UuCisvLworLy8gVGhpcyBjbGFzcyBpcyByZWFsbHkgYSBuYW1lc3BhY2UgdGhhdCBjb250YWlucyBvbmx5IHN0YXRpYyBtZXRob2RzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJlZmxlY3Rpb25PcHMgeworIHB1YmxpYzoKKyAgc3RhdGljIHZvaWQgQ29weShjb25zdCBNZXNzYWdlJiBmcm9tLCBNZXNzYWdlKiB0byk7CisgIHN0YXRpYyB2b2lkIE1lcmdlKGNvbnN0IE1lc3NhZ2UmIGZyb20sIE1lc3NhZ2UqIHRvKTsKKyAgc3RhdGljIHZvaWQgQ2xlYXIoTWVzc2FnZSogbWVzc2FnZSk7CisgIHN0YXRpYyBib29sIElzSW5pdGlhbGl6ZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIERpc2NhcmRVbmtub3duRmllbGRzKE1lc3NhZ2UqIG1lc3NhZ2UpOworCisgIC8vIEZpbmRzIGFsbCB1bnNldCByZXF1aXJlZCBmaWVsZHMgaW4gdGhlIG1lc3NhZ2UgYW5kIGFkZHMgdGhlaXIgZnVsbAorICAvLyBwYXRocyAoZS5nLiAiZm9vLmJhcls1XS5iYXoiKSB0byAqbmFtZXMuICAicHJlZml4IiB3aWxsIGJlIGF0dGFjaGVkIHRvCisgIC8vIHRoZSBmcm9udCBvZiBlYWNoIG5hbWUuCisgIHN0YXRpYyB2b2lkIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZXJyb3JzKTsKKworIHByaXZhdGU6CisgIC8vIEFsbCBtZXRob2RzIGFyZSBzdGF0aWMuICBObyBuZWVkIHRvIGNvbnN0cnVjdC4KKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlZmxlY3Rpb25PcHMpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9PUFNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wc191bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMjc0MGVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wc191bml0dGVzdC5jYwpAQCAtMCwwICsxLDQ3NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIFNhbml0eUNoZWNrKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgQ29weSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworCisgIFJlZmxlY3Rpb25PcHM6OkNvcHkobWVzc2FnZSwgJm1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlMiwgJm1lc3NhZ2UyKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIENvcHlFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgQ29weU9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlKTsKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6U2V0T25lb2YyKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlKTsKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQyKG1lc3NhZ2UyKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgTWVyZ2UpIHsKKyAgLy8gTm90ZTogIENvcHkgaXMgaW1wbGVtZW50ZWQgaW4gdGVybXMgb2YgTWVyZ2UoKSBzbyB0ZWNobmljYWxseSB0aGUgQ29weQorICAvLyAgIHRlc3QgYWxyZWFkeSB0ZXN0ZWQgbW9zdCBvZiB0aGlzLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZSwgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgLy8gVGhpcyBmaWVsZCB3aWxsIHRlc3QgbWVyZ2luZyBpbnRvIGFuIGVtcHR5IHNwb3QuCisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9pbnQzMihtZXNzYWdlLm9wdGlvbmFsX2ludDMyKCkpOworICBtZXNzYWdlLmNsZWFyX29wdGlvbmFsX2ludDMyKCk7CisKKyAgLy8gVGhpcyB0ZXN0cyBvdmVyd3JpdGluZy4KKyAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX3N0cmluZyhtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJzb21ldGhpbmcgZWxzZSIpOworCisgIC8vIFRoaXMgdGVzdHMgY29uY2F0ZW5hdGluZy4KKyAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX2ludDMyKG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIoMSkpOworICBpbnQzMiBpID0gbWVzc2FnZS5yZXBlYXRlZF9pbnQzMigwKTsKKyAgbWVzc2FnZS5jbGVhcl9yZXBlYXRlZF9pbnQzMigpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9pbnQzMihpKTsKKworICBSZWZsZWN0aW9uT3BzOjpNZXJnZShtZXNzYWdlMiwgJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIE1lcmdlRXh0ZW5zaW9ucykgeworICAvLyBOb3RlOiAgQ29weSBpcyBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiBNZXJnZSgpIHNvIHRlY2huaWNhbGx5IHRoZSBDb3B5CisgIC8vICAgdGVzdCBhbHJlYWR5IHRlc3RlZCBtb3N0IG9mIHRoaXMuCisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlKTsKKworICAvLyBUaGlzIGZpZWxkIHdpbGwgdGVzdCBtZXJnaW5nIGludG8gYW4gZW1wdHkgc3BvdC4KKyAgbWVzc2FnZTIuU2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sCisgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbikpOworICBtZXNzYWdlLkNsZWFyRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pOworCisgIC8vIFRoaXMgdGVzdHMgb3ZlcndyaXRpbmcuCisgIG1lc3NhZ2UyLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiwKKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbikpOworICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiwgInNvbWV0aGluZyBlbHNlIik7CisKKyAgLy8gVGhpcyB0ZXN0cyBjb25jYXRlbmF0aW5nLgorICBtZXNzYWdlMi5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiwKKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAxKSk7CisgIGludDMyIGkgPSBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAwKTsKKyAgbWVzc2FnZS5DbGVhckV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uKTsKKyAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiwgaSk7CisKKyAgUmVmbGVjdGlvbk9wczo6TWVyZ2UobWVzc2FnZTIsICZtZXNzYWdlKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgTWVyZ2VVbmtub3duKSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgbWVzc2FnZXMnIFVua25vd25GaWVsZFNldHMgYXJlIGNvcnJlY3RseSBtZXJnZWQuCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMTIzNCwgMSk7CisgIG1lc3NhZ2UyLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEyMzQsIDIpOworCisgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UyLCAmbWVzc2FnZTEpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwKKyAgICAgICAgICAgIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudHlwZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudmFyaW50KCkpOworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwKKyAgICAgICAgICAgIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMSkudHlwZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMSkudmFyaW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBNZXJnZU9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZTEpOworCisgIC8vIE1lcmdlIHRvIGVtcHR5IG1lc3NhZ2UKKyAgUmVmbGVjdGlvbk9wczo6TWVyZ2UobWVzc2FnZTEsICZtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZlNldDEobWVzc2FnZTIpOworCisgIC8vIE1lcmdlIHdpdGggdGhlIHNhbWUgb25lb2YgZmllbGRzCisgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UxLCAmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UyKTsKKworICAvLyBNZXJnZSB3aXRoIGRpZmZlcmVudCBvbmVvZiBmaWVsZHMKKyAgVGVzdFV0aWw6OlNldE9uZW9mMigmbWVzc2FnZTEpOworICBSZWZsZWN0aW9uT3BzOjpNZXJnZShtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlMik7Cit9CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBNZXJnZUZyb21TZWxmKSB7CisgIC8vIE5vdGU6ICBDb3B5IGlzIGltcGxlbWVudGVkIGluIHRlcm1zIG9mIE1lcmdlKCkgc28gdGVjaG5pY2FsbHkgdGhlIENvcHkKKyAgLy8gICB0ZXN0IGFscmVhZHkgdGVzdGVkIG1vc3Qgb2YgdGhpcy4KKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0RFQVRIKAorICAgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UsICZtZXNzYWdlKSwKKyAgICAiJmZyb20iKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBDbGVhcikgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGdldHRpbmcgZW1iZWRkZWQgbWVzc2FnZXMgcmV0dXJucyB0aGUgb2JqZWN0cyBjcmVhdGVkIGR1cmluZworICAvLyBTZXRBbGxGaWVsZHMoKSByYXRoZXIgdGhhbiBkZWZhdWx0IGluc3RhbmNlcy4KKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpPcHRpb25hbEdyb3VwOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbGdyb3VwKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UoKSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIENsZWFyRXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBnZXR0aW5nIGVtYmVkZGVkIG1lc3NhZ2VzIHJldHVybnMgdGhlIG9iamVjdHMgY3JlYXRlZCBkdXJpbmcKKyAgLy8gU2V0QWxsRXh0ZW5zaW9ucygpIHJhdGhlciB0aGFuIGRlZmF1bHQgaW5zdGFuY2VzLgorICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpPcHRpb25hbEdyb3VwX2V4dGVuc2lvbjo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbikpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9ORSgmdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24oCisgICAgICAgICAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9ORSgmdW5pdHRlc3RfaW1wb3J0OjpJbXBvcnRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbikpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBDbGVhclVua25vd24pIHsKKyAgLy8gVGVzdCB0aGF0IHRoZSBtZXNzYWdlJ3MgVW5rbm93bkZpZWxkU2V0IGlzIGNvcnJlY3RseSBjbGVhcmVkLgorICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEyMzQsIDEpOworCisgIFJlZmxlY3Rpb25PcHM6OkNsZWFyKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBDbGVhck9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mQ2xlYXIobWVzc2FnZSk7CisgIFRlc3RVdGlsOjpTZXRPbmVvZjEoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UpOworICBSZWZsZWN0aW9uT3BzOjpDbGVhcigmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZkNsZWFyKG1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpTZXRPbmVvZjEoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UpOworICBUZXN0VXRpbDo6U2V0T25lb2YyKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlKTsKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZDbGVhcihtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRGlzY2FyZFVua25vd25GaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKworICAvLyBTZXQgc29tZSB1bmtub3duIGZpZWxkcyBpbiBtZXNzYWdlLgorICBtZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKQorICAgICAgICAtPkFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpCisgICAgICAgIC0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpCisgICAgICAgIC0+QWRkVmFyaW50KDEyMzQ1NiwgNjU0MzIxKTsKKyAgbWVzc2FnZS5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApCisgICAgICAgIC0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpCisgICAgICAgIC0+QWRkVmFyaW50KDEyMzQ1NiwgNjU0MzIxKTsKKworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpCisgICAgICAgICAgICAgICAgICAgICAgLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApCisgICAgICAgICAgICAgICAgICAgICAgLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisKKyAgLy8gRGlzY2FyZCB0aGVtLgorICBSZWZsZWN0aW9uT3BzOjpEaXNjYXJkVW5rbm93bkZpZWxkcygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgwKQorICAgICAgICAgICAgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBEaXNjYXJkVW5rbm93bkV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlKTsKKworICAvLyBTZXQgc29tZSB1bmtub3duIGZpZWxkcy4KKyAgbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgICAgLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiwgMCkKKyAgICAgICAgLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworCisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLAorICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pCisgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwKKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uLCAwKQorICAgICAgICAgICAudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKworICAvLyBEaXNjYXJkIHRoZW0uCisgIFJlZmxlY3Rpb25PcHM6OkRpc2NhcmRVbmtub3duRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsCisgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgICAgICAgLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgwLAorICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24sIDApCisgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBJc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKworICBFWFBFQ1RfRkFMU0UoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisgIG1lc3NhZ2Uuc2V0X2EoMSk7CisgIEVYUEVDVF9GQUxTRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5zZXRfYigyKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworICBtZXNzYWdlLnNldF9jKDMpOworICBFWFBFQ1RfVFJVRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRm9yZWlnbklzSW5pdGlhbGl6ZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZEZvcmVpZ24gbWVzc2FnZTsKKworICAvLyBTdGFydHMgb3V0IGluaXRpYWxpemVkIGJlY2F1c2UgdGhlIGZvcmVpZ24gbWVzc2FnZSBpcyBpdHNlbGYgYW4gb3B0aW9uYWwKKyAgLy8gZmllbGQuCisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIE9uY2Ugd2UgY3JlYXRlIHRoYXQgZmllbGQsIHRoZSBtZXNzYWdlIGlzIG5vIGxvbmdlciBpbml0aWFsaXplZC4KKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEluaXRpYWxpemUgaXQuICBOb3cgd2UncmUgaW5pdGlhbGl6ZWQuCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9tZXNzYWdlKCktPnNldF9hKDEpOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpLT5zZXRfYigyKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEFkZCBhIHJlcGVhdGVkIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UuICBObyBsb25nZXIgaW5pdGlhbGl6ZWQuCisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQqIHN1Yl9tZXNzYWdlID0gbWVzc2FnZS5hZGRfcmVwZWF0ZWRfbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisKKyAgLy8gSW5pdGlhbGl6ZSB0aGF0IHJlcGVhdGVkIHZlcnNpb24uCisgIHN1Yl9tZXNzYWdlLT5zZXRfYSgxKTsKKyAgc3ViX21lc3NhZ2UtPnNldF9iKDIpOworICBzdWJfbWVzc2FnZS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBFeHRlbnNpb25Jc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworCisgIC8vIFN0YXJ0cyBvdXQgaW5pdGlhbGl6ZWQgYmVjYXVzZSB0aGUgZm9yZWlnbiBtZXNzYWdlIGlzIGl0c2VsZiBhbiBvcHRpb25hbAorICAvLyBmaWVsZC4KKyAgRVhQRUNUX1RSVUUoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisKKyAgLy8gT25jZSB3ZSBjcmVhdGUgdGhhdCBmaWVsZCwgdGhlIG1lc3NhZ2UgaXMgbm8gbG9uZ2VyIGluaXRpYWxpemVkLgorICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6c2luZ2xlKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEluaXRpYWxpemUgaXQuICBOb3cgd2UncmUgaW5pdGlhbGl6ZWQuCisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjpzaW5nbGUpLT5zZXRfYSgxKTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSktPnNldF9iKDIpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6c2luZ2xlKS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEFkZCBhIHJlcGVhdGVkIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UuICBObyBsb25nZXIgaW5pdGlhbGl6ZWQuCisgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEluaXRpYWxpemUgdGhhdCByZXBlYXRlZCB2ZXJzaW9uLgorICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6bXVsdGksIDApLT5zZXRfYSgxKTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpLCAwKS0+c2V0X2IoMik7CisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjptdWx0aSwgMCktPnNldF9jKDMpOworICBFWFBFQ1RfVFJVRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgT25lb2ZJc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWRPbmVvZiBtZXNzYWdlOworICBFWFBFQ1RfVFJVRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKKworICBtZXNzYWdlLm11dGFibGVfZm9vX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19pbnQoMSk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcmVxdWlyZWRfZG91YmxlKDAuMSk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworfQorCitzdGF0aWMgc3RyaW5nIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgUmVmbGVjdGlvbk9wczo6RmluZEluaXRpYWxpemF0aW9uRXJyb3JzKG1lc3NhZ2UsICIiLCAmZXJyb3JzKTsKKyAgcmV0dXJuIEpvaW4oZXJyb3JzLCAiLCIpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFWFBFQ1RfRVEoImEsYixjIiwgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRmluZEZvcmVpZ25Jbml0aWFsaXphdGlvbkVycm9ycykgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkRm9yZWlnbiBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9tZXNzYWdlKCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0VRKCJvcHRpb25hbF9tZXNzYWdlLmEsIgorICAgICAgICAgICAgIm9wdGlvbmFsX21lc3NhZ2UuYiwiCisgICAgICAgICAgICAib3B0aW9uYWxfbWVzc2FnZS5jLCIKKyAgICAgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzBdLmEsIgorICAgICAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMF0uYiwiCisgICAgICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVswXS5jLCIKKyAgICAgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzFdLmEsIgorICAgICAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMV0uYiwiCisgICAgICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVsxXS5jIiwKKyAgICAgICAgICAgIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhtZXNzYWdlKSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIEZpbmRFeHRlbnNpb25Jbml0aWFsaXphdGlvbkVycm9ycykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSk7CisgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpKTsKKyAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6bXVsdGkpOworICBFWFBFQ1RfRVEoIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQuc2luZ2xlKS5hLCIKKyAgICAgICAgICAgICIocHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkLnNpbmdsZSkuYiwiCisgICAgICAgICAgICAiKHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZC5zaW5nbGUpLmMsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzBdLmEsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzBdLmIsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzBdLmMsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzFdLmEsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzFdLmIsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzFdLmMiLAorICAgICAgICAgICAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRmluZE9uZW9mSW5pdGlhbGl6YXRpb25FcnJvcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZE9uZW9mIG1lc3NhZ2U7CisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpOworICBFWFBFQ1RfRVEoImZvb19tZXNzYWdlLnJlcXVpcmVkX2RvdWJsZSIsCisgICAgICAgICAgICBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMobWVzc2FnZSkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNWFlZGFkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5jYwpAQCAtMCwwICsxLDk3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKwordm9pZCoqIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpJbnRlcm5hbEV4dGVuZChpbnQgZXh0ZW5kX2Ftb3VudCkgeworICBpbnQgbmV3X3NpemUgPSBjdXJyZW50X3NpemVfICsgZXh0ZW5kX2Ftb3VudDsKKyAgaWYgKHRvdGFsX3NpemVfID49IG5ld19zaXplKSB7CisgICAgLy8gTi5CLjogcmVwXyBpcyBub24tTlVMTCBiZWNhdXNlIGV4dGVuZF9hbW91bnQgaXMgYWx3YXlzID4gMCwgaGVuY2UKKyAgICAvLyB0b3RhbF9zaXplIG11c3QgYmUgbm9uLXplcm8gc2luY2UgaXQgaXMgbG93ZXItYm91bmRlZCBieSBuZXdfc2l6ZS4KKyAgICByZXR1cm4gJnJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV9dOworICB9CisgIFJlcCogb2xkX3JlcCA9IHJlcF87CisgIEFyZW5hKiBhcmVuYSA9IEdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIG5ld19zaXplID0gbWF4KGtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUsCisgICAgICAgICAgICAgICAgIG1heCh0b3RhbF9zaXplXyAqIDIsIG5ld19zaXplKSk7CisgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgcmVwXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8UmVwKj4oCisgICAgICAgIG5ldyBjaGFyW2tSZXBIZWFkZXJTaXplICsgc2l6ZW9mKG9sZF9yZXAtPmVsZW1lbnRzWzBdKSpuZXdfc2l6ZV0pOworICB9IGVsc2UgeworICAgIHJlcF8gPSByZWludGVycHJldF9jYXN0PFJlcCo+KAorICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPihhcmVuYSwKKyAgICAgICAgICAgIGtSZXBIZWFkZXJTaXplICsgc2l6ZW9mKG9sZF9yZXAtPmVsZW1lbnRzWzBdKSpuZXdfc2l6ZSkpOworICB9CisgIHRvdGFsX3NpemVfID0gbmV3X3NpemU7CisgIGlmIChvbGRfcmVwICYmIG9sZF9yZXAtPmFsbG9jYXRlZF9zaXplID4gMCkgeworICAgIG1lbWNweShyZXBfLT5lbGVtZW50cywgb2xkX3JlcC0+ZWxlbWVudHMsCisgICAgICAgICAgIG9sZF9yZXAtPmFsbG9jYXRlZF9zaXplICogc2l6ZW9mKHJlcF8tPmVsZW1lbnRzWzBdKSk7CisgICAgcmVwXy0+YWxsb2NhdGVkX3NpemUgPSBvbGRfcmVwLT5hbGxvY2F0ZWRfc2l6ZTsKKyAgfSBlbHNlIHsKKyAgICByZXBfLT5hbGxvY2F0ZWRfc2l6ZSA9IDA7CisgIH0KKyAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICBkZWxldGUgW10gcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4ob2xkX3JlcCk7CisgIH0KKyAgcmV0dXJuICZyZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXTsKK30KKwordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVzZXJ2ZShpbnQgbmV3X3NpemUpIHsKKyAgaWYgKG5ld19zaXplID4gY3VycmVudF9zaXplXykgeworICAgIEludGVybmFsRXh0ZW5kKG5ld19zaXplIC0gY3VycmVudF9zaXplXyk7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2xvc2VHYXAoaW50IHN0YXJ0LCBpbnQgbnVtKSB7CisgIGlmIChyZXBfID09IE5VTEwpIHJldHVybjsKKyAgLy8gQ2xvc2UgdXAgYSBnYXAgb2YgIm51bSIgZWxlbWVudHMgc3RhcnRpbmcgYXQgb2Zmc2V0ICJzdGFydCIuCisgIGZvciAoaW50IGkgPSBzdGFydCArIG51bTsgaSA8IHJlcF8tPmFsbG9jYXRlZF9zaXplOyArK2kpCisgICAgcmVwXy0+ZWxlbWVudHNbaSAtIG51bV0gPSByZXBfLT5lbGVtZW50c1tpXTsKKyAgY3VycmVudF9zaXplXyAtPSBudW07CisgIHJlcF8tPmFsbG9jYXRlZF9zaXplIC09IG51bTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjVmNWQzZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaApAQCAtMCwwICsxLDIzOTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBSZXBlYXRlZEZpZWxkIGFuZCBSZXBlYXRlZFB0ckZpZWxkIGFyZSB1c2VkIGJ5IGdlbmVyYXRlZCBwcm90b2NvbCBtZXNzYWdlCisvLyBjbGFzc2VzIHRvIG1hbmlwdWxhdGUgcmVwZWF0ZWQgZmllbGRzLiAgVGhlc2UgY2xhc3NlcyBhcmUgdmVyeSBzaW1pbGFyIHRvCisvLyBTVEwncyB2ZWN0b3IsIGJ1dCBpbmNsdWRlIGEgbnVtYmVyIG9mIG9wdGltaXphdGlvbnMgZm91bmQgdG8gYmUgdXNlZnVsCisvLyBzcGVjaWZpY2FsbHkgaW4gdGhlIGNhc2Ugb2YgUHJvdG9jb2wgQnVmZmVycy4gIFJlcGVhdGVkUHRyRmllbGQgaXMKKy8vIHBhcnRpY3VsYXJseSBkaWZmZXJlbnQgZnJvbSBTVEwgdmVjdG9yIGFzIGl0IG1hbmFnZXMgb3duZXJzaGlwIG9mIHRoZQorLy8gcG9pbnRlcnMgdGhhdCBpdCBjb250YWlucy4KKy8vCisvLyBUeXBpY2FsbHksIGNsaWVudHMgc2hvdWxkIG5vdCBuZWVkIHRvIGFjY2VzcyBSZXBlYXRlZEZpZWxkIG9iamVjdHMgZGlyZWN0bHksCisvLyBidXQgc2hvdWxkIGluc3RlYWQgdXNlIHRoZSBhY2Nlc3NvciBmdW5jdGlvbnMgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHkgYnkgdGhlCisvLyBwcm90b2NvbCBjb21waWxlci4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfUkVQRUFURURfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9SRVBFQVRFRF9GSUVMRF9IX18KKworI2lmZGVmIF9NU0NfVkVSCisvLyBUaGlzIGlzIHJlcXVpcmVkIGZvciBtaW4vbWF4IG9uIFZTMjAxMyBvbmx5LgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNlbmRpZgorCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdHlwZV90cmFpdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSB1cGIgeworbmFtZXNwYWNlIGdvb2dsZV9vcGVuc291cmNlIHsKK2NsYXNzIEdNUl9IYW5kbGVyczsKK30gIC8vIG5hbWVzcGFjZSBnb29nbGVfb3BlbnNvdXJjZQorfSAgLy8gbmFtZXNwYWNlIHVwYgorCituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBNZXNzYWdlOworCituYW1lc3BhY2UgaW50ZXJuYWwgeworCitzdGF0aWMgY29uc3QgaW50IGtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUgPSA0OworCisvLyBBIHV0aWxpdHkgZnVuY3Rpb24gZm9yIGxvZ2dpbmcgdGhhdCBkb2Vzbid0IG5lZWQgYW55IHRlbXBsYXRlIHR5cGVzLgordm9pZCBMb2dJbmRleE91dE9mQm91bmRzKGludCBpbmRleCwgaW50IHNpemUpOworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KK2lubGluZSBpbnQgQ2FsY3VsYXRlUmVzZXJ2ZShJdGVyIGJlZ2luLCBJdGVyIGVuZCwgc3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZykgeworICByZXR1cm4gc3RkOjpkaXN0YW5jZShiZWdpbiwgZW5kKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CitpbmxpbmUgaW50IENhbGN1bGF0ZVJlc2VydmUoSXRlciAvKmJlZ2luKi8sIEl0ZXIgLyplbmQqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmlucHV0X2l0ZXJhdG9yX3RhZyAvKnVudXNlZCovKSB7CisgIHJldHVybiAtMTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CitpbmxpbmUgaW50IENhbGN1bGF0ZVJlc2VydmUoSXRlciBiZWdpbiwgSXRlciBlbmQpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czxJdGVyPjo6aXRlcmF0b3JfY2F0ZWdvcnkgQ2F0ZWdvcnk7CisgIHJldHVybiBDYWxjdWxhdGVSZXNlcnZlKGJlZ2luLCBlbmQsIENhdGVnb3J5KCkpOworfQorfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKworLy8gUmVwZWF0ZWRGaWVsZCBpcyB1c2VkIHRvIHJlcHJlc2VudCByZXBlYXRlZCBmaWVsZHMgb2YgYSBwcmltaXRpdmUgdHlwZSAoaW4KKy8vIG90aGVyIHdvcmRzLCBldmVyeXRoaW5nIGV4Y2VwdCBzdHJpbmdzIGFuZCBuZXN0ZWQgTWVzc2FnZXMpLiAgTW9zdCB1c2VycyB3aWxsCisvLyBub3QgZXZlciB1c2UgYSBSZXBlYXRlZEZpZWxkIGRpcmVjdGx5OyB0aGV5IHdpbGwgdXNlIHRoZSBnZXQtYnktaW5kZXgsCisvLyBzZXQtYnktaW5kZXgsIGFuZCBhZGQgYWNjZXNzb3JzIHRoYXQgYXJlIGdlbmVyYXRlZCBmb3IgYWxsIHJlcGVhdGVkIGZpZWxkcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgorY2xhc3MgUmVwZWF0ZWRGaWVsZCB7CisgcHVibGljOgorICBSZXBlYXRlZEZpZWxkKCk7CisgIGV4cGxpY2l0IFJlcGVhdGVkRmllbGQoQXJlbmEqIGFyZW5hKTsKKyAgUmVwZWF0ZWRGaWVsZChjb25zdCBSZXBlYXRlZEZpZWxkJiBvdGhlcik7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBJdGVyPgorICBSZXBlYXRlZEZpZWxkKEl0ZXIgYmVnaW4sIGNvbnN0IEl0ZXImIGVuZCk7CisgIH5SZXBlYXRlZEZpZWxkKCk7CisKKyAgUmVwZWF0ZWRGaWVsZCYgb3BlcmF0b3I9KGNvbnN0IFJlcGVhdGVkRmllbGQmIG90aGVyKTsKKworICBib29sIGVtcHR5KCkgY29uc3Q7CisgIGludCBzaXplKCkgY29uc3Q7CisKKyAgY29uc3QgRWxlbWVudCYgR2V0KGludCBpbmRleCkgY29uc3Q7CisgIEVsZW1lbnQqIE11dGFibGUoaW50IGluZGV4KTsKKyAgdm9pZCBTZXQoaW50IGluZGV4LCBjb25zdCBFbGVtZW50JiB2YWx1ZSk7CisgIHZvaWQgQWRkKGNvbnN0IEVsZW1lbnQmIHZhbHVlKTsKKyAgRWxlbWVudCogQWRkKCk7CisgIC8vIFJlbW92ZSB0aGUgbGFzdCBlbGVtZW50IGluIHRoZSBhcnJheS4KKyAgdm9pZCBSZW1vdmVMYXN0KCk7CisKKyAgLy8gRXh0cmFjdCBlbGVtZW50cyB3aXRoIGluZGljZXMgaW4gIltzdGFydCAuLiBzdGFydCtudW0tMV0iLgorICAvLyBDb3B5IHRoZW0gaW50byAiZWxlbWVudHNbMCAuLiBudW0tMV0iIGlmICJlbGVtZW50cyIgaXMgbm90IE5VTEwuCisgIC8vIENhdXRpb246IGltcGxlbWVudGF0aW9uIGFsc28gbW92ZXMgZWxlbWVudHMgd2l0aCBpbmRpY2VzIFtzdGFydCtudW0gLi5dLgorICAvLyBDYWxsaW5nIHRoaXMgcm91dGluZSBpbnNpZGUgYSBsb29wIGNhbiBjYXVzZSBxdWFkcmF0aWMgYmVoYXZpb3IuCisgIHZvaWQgRXh0cmFjdFN1YnJhbmdlKGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCogZWxlbWVudHMpOworCisgIHZvaWQgQ2xlYXIoKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgUmVwZWF0ZWRGaWVsZCYgb3RoZXIpOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFJlcGVhdGVkRmllbGQmIG90aGVyKTsKKworICAvLyBSZXNlcnZlIHNwYWNlIHRvIGV4cGFuZCB0aGUgZmllbGQgdG8gYXQgbGVhc3QgdGhlIGdpdmVuIHNpemUuICBJZiB0aGUKKyAgLy8gYXJyYXkgaXMgZ3Jvd24sIGl0IHdpbGwgYWx3YXlzIGJlIGF0IGxlYXN0IGRvdWJsZWQgaW4gc2l6ZS4KKyAgdm9pZCBSZXNlcnZlKGludCBuZXdfc2l6ZSk7CisKKyAgLy8gUmVzaXplIHRoZSBSZXBlYXRlZEZpZWxkIHRvIGEgbmV3LCBzbWFsbGVyIHNpemUuICBUaGlzIGlzIE8oMSkuCisgIHZvaWQgVHJ1bmNhdGUoaW50IG5ld19zaXplKTsKKworICB2b2lkIEFkZEFscmVhZHlSZXNlcnZlZChjb25zdCBFbGVtZW50JiB2YWx1ZSk7CisgIEVsZW1lbnQqIEFkZEFscmVhZHlSZXNlcnZlZCgpOworICBpbnQgQ2FwYWNpdHkoKSBjb25zdDsKKworICAvLyBMaWtlIFNUTCByZXNpemUuICBVc2VzIHZhbHVlIHRvIGZpbGwgYXBwZW5kZWQgZWxlbWVudHMuCisgIC8vIExpa2UgVHJ1bmNhdGUoKSBpZiBuZXdfc2l6ZSA8PSBzaXplKCksIG90aGVyd2lzZSB0aGlzIGlzCisgIC8vIE8obmV3X3NpemUgLSBzaXplKCkpLgorICB2b2lkIFJlc2l6ZShpbnQgbmV3X3NpemUsIGNvbnN0IEVsZW1lbnQmIHZhbHVlKTsKKworICAvLyBHZXRzIHRoZSB1bmRlcmx5aW5nIGFycmF5LiAgVGhpcyBwb2ludGVyIGlzIHBvc3NpYmx5IGludmFsaWRhdGVkIGJ5CisgIC8vIGFueSBhZGQgb3IgcmVtb3ZlIG9wZXJhdGlvbi4KKyAgRWxlbWVudCogbXV0YWJsZV9kYXRhKCk7CisgIGNvbnN0IEVsZW1lbnQqIGRhdGEoKSBjb25zdDsKKworICAvLyBTd2FwIGVudGlyZSBjb250ZW50cyB3aXRoICJvdGhlciIuIElmIHRoZXkgYXJlIHNlcGFyYXRlIGFyZW5hcyB0aGVuLCBjb3BpZXMKKyAgLy8gZGF0YSBiZXR3ZWVuIGVhY2ggb3RoZXIuCisgIHZvaWQgU3dhcChSZXBlYXRlZEZpZWxkKiBvdGhlcik7CisKKyAgLy8gU3dhcCBlbnRpcmUgY29udGVudHMgd2l0aCAib3RoZXIiLiBTaG91bGQgYmUgY2FsbGVkIG9ubHkgaWYgdGhlIGNhbGxlciBjYW4KKyAgLy8gZ3VhcmFudGVlIHRoYXQgYm90aCByZXBlYXRlZCBmaWVsZHMgYXJlIG9uIHRoZSBzYW1lIGFyZW5hIG9yIGFyZSBvbiB0aGUKKyAgLy8gaGVhcC4gU3dhcHBpbmcgYmV0d2VlbiBkaWZmZXJlbnQgYXJlbmFzIGlzIGRpc2FsbG93ZWQgYW5kIGNhdWdodCBieSBhCisgIC8vIEdPT0dMRV9EQ0hFQ0sgKHNlZSBBUEkgZG9jcyBmb3IgZGV0YWlscykuCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKFJlcGVhdGVkRmllbGQqIG90aGVyKTsKKworICAvLyBTd2FwIHR3byBlbGVtZW50cy4KKyAgdm9pZCBTd2FwRWxlbWVudHMoaW50IGluZGV4MSwgaW50IGluZGV4Mik7CisKKyAgLy8gU1RMLWxpa2UgaXRlcmF0b3Igc3VwcG9ydAorICB0eXBlZGVmIEVsZW1lbnQqIGl0ZXJhdG9yOworICB0eXBlZGVmIGNvbnN0IEVsZW1lbnQqIGNvbnN0X2l0ZXJhdG9yOworICB0eXBlZGVmIEVsZW1lbnQgdmFsdWVfdHlwZTsKKyAgdHlwZWRlZiB2YWx1ZV90eXBlJiByZWZlcmVuY2U7CisgIHR5cGVkZWYgY29uc3QgdmFsdWVfdHlwZSYgY29uc3RfcmVmZXJlbmNlOworICB0eXBlZGVmIHZhbHVlX3R5cGUqIHBvaW50ZXI7CisgIHR5cGVkZWYgY29uc3QgdmFsdWVfdHlwZSogY29uc3RfcG9pbnRlcjsKKyAgdHlwZWRlZiBpbnQgc2l6ZV90eXBlOworICB0eXBlZGVmIHB0cmRpZmZfdCBkaWZmZXJlbmNlX3R5cGU7CisKKyAgaXRlcmF0b3IgYmVnaW4oKTsKKyAgY29uc3RfaXRlcmF0b3IgYmVnaW4oKSBjb25zdDsKKyAgY29uc3RfaXRlcmF0b3IgY2JlZ2luKCkgY29uc3Q7CisgIGl0ZXJhdG9yIGVuZCgpOworICBjb25zdF9pdGVyYXRvciBlbmQoKSBjb25zdDsKKyAgY29uc3RfaXRlcmF0b3IgY2VuZCgpIGNvbnN0OworCisgIC8vIFJldmVyc2UgaXRlcmF0b3Igc3VwcG9ydAorICB0eXBlZGVmIHN0ZDo6cmV2ZXJzZV9pdGVyYXRvcjxjb25zdF9pdGVyYXRvcj4gY29uc3RfcmV2ZXJzZV9pdGVyYXRvcjsKKyAgdHlwZWRlZiBzdGQ6OnJldmVyc2VfaXRlcmF0b3I8aXRlcmF0b3I+IHJldmVyc2VfaXRlcmF0b3I7CisgIHJldmVyc2VfaXRlcmF0b3IgcmJlZ2luKCkgeworICAgIHJldHVybiByZXZlcnNlX2l0ZXJhdG9yKGVuZCgpKTsKKyAgfQorICBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yIHJiZWdpbigpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfcmV2ZXJzZV9pdGVyYXRvcihlbmQoKSk7CisgIH0KKyAgcmV2ZXJzZV9pdGVyYXRvciByZW5kKCkgeworICAgIHJldHVybiByZXZlcnNlX2l0ZXJhdG9yKGJlZ2luKCkpOworICB9CisgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmVuZCgpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfcmV2ZXJzZV9pdGVyYXRvcihiZWdpbigpKTsKKyAgfQorCisgIC8vIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB1c2VkIGJ5IHRoZSByZXBlYXRlZCBmaWVsZCwgZXhjbHVkaW5nCisgIC8vIHNpemVvZigqdGhpcykKKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworICAvLyBSZW1vdmUgdGhlIGVsZW1lbnQgcmVmZXJlbmNlZCBieSBwb3NpdGlvbi4KKyAgaXRlcmF0b3IgZXJhc2UoY29uc3RfaXRlcmF0b3IgcG9zaXRpb24pOworCisgIC8vIFJlbW92ZSB0aGUgZWxlbWVudHMgaW4gdGhlIHJhbmdlIFtmaXJzdCwgbGFzdCkuCisgIGl0ZXJhdG9yIGVyYXNlKGNvbnN0X2l0ZXJhdG9yIGZpcnN0LCBjb25zdF9pdGVyYXRvciBsYXN0KTsKKworICAvLyBHZXQgdGhlIEFyZW5hIG9uIHdoaWNoIHRoaXMgUmVwZWF0ZWRGaWVsZCBzdG9yZXMgaXRzIGVsZW1lbnRzLgorICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgc3RhdGljIGNvbnN0IGludCBrSW5pdGlhbFNpemUgPSAwOworICAvLyBBIG5vdGUgb24gdGhlIHJlcHJlc2VudGF0aW9uIGhlcmUgKHNlZSBhbHNvIGNvbW1lbnQgYmVsb3cgZm9yCisgIC8vIFJlcGVhdGVkUHRyRmllbGRCYXNlJ3Mgc3RydWN0IFJlcCk6CisgIC8vCisgIC8vIFdlIG1haW50YWluIHRoZSBzYW1lIHNpemVvZihSZXBlYXRlZEZpZWxkKSBhcyBiZWZvcmUgd2UgYWRkZWQgYXJlbmEgc3VwcG9ydAorICAvLyBzbyB0aGF0IHdlIGRvIG5vdCBkZWdyYWRlIHBlcmZvcm1hbmNlIGJ5IGJsb2F0aW5nIG1lbW9yeSB1c2FnZS4gRGlyZWN0bHkKKyAgLy8gYWRkaW5nIGFuIGFyZW5hXyBlbGVtZW50IHRvIFJlcGVhdGVkRmllbGQgaXMgcXVpdGUgY29zdGx5LiBCeSB1c2luZworICAvLyBpbmRpcmVjdGlvbiBpbiB0aGlzIHdheSwgd2Uga2VlcCB0aGUgc2FtZSBzaXplIHdoZW4gdGhlIFJlcGVhdGVkRmllbGQgaXMKKyAgLy8gZW1wdHkgKGNvbW1vbiBjYXNlKSwgYW5kIGFkZCBvbmx5IGFuIDgtYnl0ZSBoZWFkZXIgdG8gdGhlIGVsZW1lbnRzIGFycmF5CisgIC8vIHdoZW4gbm9uLWVtcHR5LiBXZSBtYWtlIHN1cmUgdG8gcGxhY2UgdGhlIHNpemUgZmllbGRzIGRpcmVjdGx5IGluIHRoZQorICAvLyBSZXBlYXRlZEZpZWxkIGNsYXNzIHRvIGF2b2lkIGNvc3RseSBjYWNoZSBtaXNzZXMgZHVlIHRvIHRoZSBpbmRpcmVjdGlvbi4KKyAgaW50IGN1cnJlbnRfc2l6ZV87CisgIGludCB0b3RhbF9zaXplXzsKKyAgc3RydWN0IFJlcCB7CisgICAgQXJlbmEqIGFyZW5hOworICAgIEVsZW1lbnQgIGVsZW1lbnRzWzFdOworICB9OworICAvLyBXZSBjYW4gbm90IHVzZSBzaXplb2YoUmVwKSAtIHNpemVvZihFbGVtZW50KSBkdWUgdG8gdGhlIHRyYWlsaW5nIHBhZGRpbmcgb24KKyAgLy8gdGhlIHN0cnVjdC4gV2UgY2FuIG5vdCB1c2Ugc2l6ZW9mKEFyZW5hKikgYXMgd2VsbCBiZWNhdXNlIHRoZXJlIG1pZ2h0IGJlCisgIC8vIGEgImdhcCIgYWZ0ZXIgdGhlIGZpZWxkIGFyZW5hIGFuZCBiZWZvcmUgdGhlIGZpZWxkIGVsZW1lbnRzIChlLmcuLCB3aGVuCisgIC8vIEVsZW1lbnQgaXMgZG91YmxlIGFuZCBwb2ludGVyIGlzIDMyYml0KS4KKyAgc3RhdGljIGNvbnN0IHNpemVfdCBrUmVwSGVhZGVyU2l6ZTsKKyAgLy8gQ29udGFpbnMgYXJlbmEgcHRyIGFuZCB0aGUgZWxlbWVudHMgYXJyYXkuIFdlIGFsc28ga2VlcCB0aGUgaW52YXJpYW50IHRoYXQKKyAgLy8gaWYgcmVwXyBpcyBOVUxMLCB0aGVuIGFyZW5hIGlzIE5VTEwuCisgIFJlcCogcmVwXzsKKworICBmcmllbmQgY2xhc3MgQXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisKKyAgLy8gTW92ZSB0aGUgY29udGVudHMgb2YgfGZyb218IGludG8gfHRvfCwgcG9zc2libHkgY2xvYmJlcmluZyB8ZnJvbXwgaW4gdGhlCisgIC8vIHByb2Nlc3MuICBGb3IgcHJpbWl0aXZlIHR5cGVzIHRoaXMgaXMganVzdCBhIG1lbWNweSgpLCBidXQgaXQgY291bGQgYmUKKyAgLy8gc3BlY2lhbGl6ZWQgZm9yIG5vbi1wcmltaXRpdmUgdHlwZXMgdG8sIHNheSwgc3dhcCBlYWNoIGVsZW1lbnQgaW5zdGVhZC4KKyAgdm9pZCBNb3ZlQXJyYXkoRWxlbWVudCogdG8sIEVsZW1lbnQqIGZyb20sIGludCBzaXplKTsKKworICAvLyBDb3B5IHRoZSBlbGVtZW50cyBvZiB8ZnJvbXwgaW50byB8dG98LgorICB2b2lkIENvcHlBcnJheShFbGVtZW50KiB0bywgY29uc3QgRWxlbWVudCogZnJvbSwgaW50IHNpemUpOworCisgIGlubGluZSB2b2lkIEludGVybmFsU3dhcChSZXBlYXRlZEZpZWxkKiBvdGhlcik7CisKKyAgLy8gSW50ZXJuYWwgaGVscGVyIGV4cGVjdGVkIGJ5IEFyZW5hIG1ldGhvZHMuCisgIGlubGluZSBBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIChyZXBfID09IE5VTEwpID8gTlVMTCA6IHJlcF8tPmFyZW5hOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBFbGVtZW50PgorY29uc3Qgc2l6ZV90IFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmtSZXBIZWFkZXJTaXplID0KKyAgICByZWludGVycHJldF9jYXN0PHNpemVfdD4oJnJlaW50ZXJwcmV0X2Nhc3Q8UmVwKj4oMTYpLT5lbGVtZW50c1swXSkgLSAxNjsKKworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlIDx0eXBlbmFtZSBJdD4gY2xhc3MgUmVwZWF0ZWRQdHJJdGVyYXRvcjsKK3RlbXBsYXRlIDx0eXBlbmFtZSBJdCwgdHlwZW5hbWUgVm9pZFB0cj4gY2xhc3MgUmVwZWF0ZWRQdHJPdmVyUHRyc0l0ZXJhdG9yOworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFRoaXMgaXMgYSBoZWxwZXIgdGVtcGxhdGUgdG8gY29weSBhbiBhcnJheSBvZiBlbGVtZW50cyBlZmZlY2llbnRseSB3aGVuIHRoZXkKKy8vIGhhdmUgYSB0cml2aWFsIGNvcHkgY29uc3RydWN0b3IsIGFuZCBjb3JyZWN0bHkgb3RoZXJ3aXNlLiBUaGlzIHJlYWxseQorLy8gc2hvdWxkbid0IGJlIG5lY2Vzc2FyeSwgYnV0IG91ciBjb21waWxlciBkb2Vzbid0IG9wdGltaXplIHN0ZDo6Y29weSB2ZXJ5CisvLyBlZmZlY3RpdmVseS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50LAorICAgICAgICAgIGJvb2wgSGFzVHJpdmlhbENvcHkgPSBoYXNfdHJpdmlhbF9jb3B5PEVsZW1lbnQ+Ojp2YWx1ZT4KK3N0cnVjdCBFbGVtZW50Q29waWVyIHsKKyAgdm9pZCBvcGVyYXRvcigpKEVsZW1lbnQqIHRvLCBjb25zdCBFbGVtZW50KiBmcm9tLCBpbnQgYXJyYXlfc2l6ZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gdHlwZS10cmFpdHMgaGVscGVyIGZvciBSZXBlYXRlZFB0ckZpZWxkQmFzZTogd2Ugb25seSB3YW50IHRvIGludm9rZQorLy8gYXJlbmEtcmVsYXRlZCAiY29weSBpZiBvbiBkaWZmZXJlbnQgYXJlbmEiIGJlaGF2aW9yIGlmIHRoZSBuZWNlc3NhcnkgbWV0aG9kcworLy8gZXhpc3Qgb24gdGhlIGNvbnRhaW5lZCB0eXBlLiBJbiBwYXJ0aWN1bGFyLCB3ZSByZWx5IG9uIE1lcmdlRnJvbSgpIGV4aXN0aW5nCisvLyBhcyBhIGdlbmVyYWwgcHJveHkgZm9yIHRoZSBmYWN0IHRoYXQgYSBjb3B5IHdpbGwgd29yaywgYW5kIHdlIGFsc28gcHJvdmlkZSBhCisvLyBzcGVjaWZpYyBvdmVycmlkZSBmb3Igc3RyaW5nKi4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgVHlwZUltcGxlbWVudHNNZXJnZUJlaGF2aW9yIHsKKyAgdHlwZWRlZiBjaGFyIEhhc01lcmdlOworICB0eXBlZGVmIGxvbmcgSGFzTm9NZXJnZTsKKworICAvLyBXZSBhY2NlcHQgZWl0aGVyIG9mOgorICAvLyAtIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFQmIG90aGVyKQorICAvLyAtIGJvb2wgTWVyZ2VGcm9tKGNvbnN0IFQmIG90aGVyKQorICAvLworICAvLyBXZSBtYW5nbGUgdGhlc2UgbmFtZXMgYSBiaXQgdG8gYXZvaWQgY29tcGF0aWJpbGl0eSBpc3N1ZXMgaW4gJ3VuY2xlYW4nCisgIC8vIGluY2x1ZGUgZW52aXJvbm1lbnRzIHRoYXQgbWF5IGhhdmUsIGUuZy4sICIjZGVmaW5lIHRlc3QgLi4uIiAoeWVzLCB0aGlzCisgIC8vIGV4aXN0cykuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFUsIHR5cGVuYW1lIFJldFR5cGUsIFJldFR5cGUgKFU6OiopKGNvbnN0IFUmIGFyZyk+CisgICAgICBzdHJ1Y3QgQ2hlY2tUeXBlOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiBzdGF0aWMgSGFzTWVyZ2UgQ2hlY2soCisgICAgICBDaGVja1R5cGU8VSwgdm9pZCwgJlU6Ok1lcmdlRnJvbT4qKTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVT4gc3RhdGljIEhhc01lcmdlIENoZWNrKAorICAgICAgQ2hlY2tUeXBlPFUsIGJvb2wsICZVOjpNZXJnZUZyb20+Kik7CisgIHRlbXBsYXRlPHR5cGVuYW1lIFU+IHN0YXRpYyBIYXNOb01lcmdlIENoZWNrKC4uLik7CisKKyAgLy8gUmVzb3ZsZXMgdG8gZWl0aGVyIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUgb3IgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUuCisgIHR5cGVkZWYgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmludGVncmFsX2NvbnN0YW50PGJvb2wsCisgICAgICAgICAgICAgICAoc2l6ZW9mKENoZWNrPFQ+KDApKSA9PSBzaXplb2YoSGFzTWVyZ2UpKT4gdHlwZTsKK307CisKK3RlbXBsYXRlPD4KK3N0cnVjdCBUeXBlSW1wbGVtZW50c01lcmdlQmVoYXZpb3I8IDo6c3RkOjpzdHJpbmcgPiB7CisgIHR5cGVkZWYgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSB0eXBlOworfTsKKworLy8gVGhpcyBpcyB0aGUgY29tbW9uIGJhc2UgY2xhc3MgZm9yIFJlcGVhdGVkUHRyRmllbGRzLiAgSXQgZGVhbHMgb25seSBpbiB2b2lkKgorLy8gcG9pbnRlcnMuICBVc2VycyBzaG91bGQgbm90IHVzZSB0aGlzIGludGVyZmFjZSBkaXJlY3RseS4KKy8vCisvLyBUaGUgbWV0aG9kcyBvZiB0aGlzIGludGVyZmFjZSBjb3JyZXNwb25kIHRvIHRoZSBtZXRob2RzIG9mIFJlcGVhdGVkUHRyRmllbGQsCisvLyBidXQgbWF5IGhhdmUgYSB0ZW1wbGF0ZSBhcmd1bWVudCBjYWxsZWQgVHlwZUhhbmRsZXIuICBJdHMgc2lnbmF0dXJlIGlzOgorLy8gICBjbGFzcyBUeXBlSGFuZGxlciB7CisvLyAgICBwdWJsaWM6CisvLyAgICAgdHlwZWRlZiBNeVR5cGUgVHlwZTsKKy8vICAgICBzdGF0aWMgVHlwZSogTmV3KCk7CisvLyAgICAgc3RhdGljIHZvaWQgRGVsZXRlKFR5cGUqKTsKKy8vICAgICBzdGF0aWMgdm9pZCBDbGVhcihUeXBlKik7CisvLyAgICAgc3RhdGljIHZvaWQgTWVyZ2UoY29uc3QgVHlwZSYgZnJvbSwgVHlwZSogdG8pOworLy8KKy8vICAgICAvLyBPbmx5IG5lZWRzIHRvIGJlIGltcGxlbWVudGVkIGlmIFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBpcyBjYWxsZWQuCisvLyAgICAgc3RhdGljIGludCBTcGFjZVVzZWQoY29uc3QgVHlwZSYpOworLy8gICB9OworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJlcGVhdGVkUHRyRmllbGRCYXNlIHsKKyBwcm90ZWN0ZWQ6CisgIC8vIFRoZSByZWZsZWN0aW9uIGltcGxlbWVudGF0aW9uIG5lZWRzIHRvIGNhbGwgcHJvdGVjdGVkIG1ldGhvZHMgZGlyZWN0bHksCisgIC8vIHJlaW50ZXJwcmV0aW5nIHBvaW50ZXJzIGFzIGJlaW5nIHRvIE1lc3NhZ2UgaW5zdGVhZCBvZiBhIHNwZWNpZmljIE1lc3NhZ2UKKyAgLy8gc3ViY2xhc3MuCisgIGZyaWVuZCBjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjsKKworICAvLyBFeHRlbnNpb25TZXQgc3RvcmVzIHJlcGVhdGVkIG1lc3NhZ2UgZXh0ZW5zaW9ucyBhcworICAvLyBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiwgYnV0IG5vbi1saXRlIEV4dGVuc2lvblNldHMgbmVlZCB0bworICAvLyBpbXBsZW1lbnQgU3BhY2VVc2VkKCksIGFuZCB0aHVzIG5lZWQgdG8gY2FsbCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkKKyAgLy8gcmVpbnRlcnByZXRpbmcgTWVzc2FnZUxpdGUgYXMgTWVzc2FnZS4gIEV4dGVuc2lvblNldCBhbHNvIG5lZWRzIHRvIG1ha2UKKyAgLy8gdXNlIG9mIEFkZEZyb21DbGVhcmVkKCksIHdoaWNoIGlzIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgaW50ZXJmYWNlLgorICBmcmllbmQgY2xhc3MgRXh0ZW5zaW9uU2V0OworCisgIC8vIFRoZSBNYXBGaWVsZEJhc2UgaW1wbGVtZW50YXRpb24gbmVlZHMgdG8gY2FsbCBwcm90ZWN0ZWQgbWV0aG9kcyBkaXJlY3RseSwKKyAgLy8gcmVpbnRlcnByZXRpbmcgcG9pbnRlcnMgYXMgYmVpbmcgdG8gTWVzc2FnZSBpbnN0ZWFkIG9mIGEgc3BlY2lmaWMgTWVzc2FnZQorICAvLyBzdWJjbGFzcy4KKyAgZnJpZW5kIGNsYXNzIE1hcEZpZWxkQmFzZTsKKworICAvLyBUbyBwYXJzZSBkaXJlY3RseSBpbnRvIGEgcHJvdG8yIGdlbmVyYXRlZCBjbGFzcywgdGhlIHVwYiBjbGFzcyBHTVJfSGFuZGxlcnMKKyAgLy8gbmVlZHMgdG8gYmUgYWJsZSB0byBtb2RpZnkgYSBSZXBlYXRlZFB0ckZpZWxkQmFzZSBkaXJlY3RseS4KKyAgZnJpZW5kIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCB1cGI6Omdvb2dsZV9vcGVuc291cmNlOjpHTVJfSGFuZGxlcnM7CisKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2UoKTsKKyAgZXhwbGljaXQgUmVwZWF0ZWRQdHJGaWVsZEJhc2UoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworICB+UmVwZWF0ZWRQdHJGaWVsZEJhc2UoKSB7fQorCisgIC8vIE11c3QgYmUgY2FsbGVkIGZyb20gZGVzdHJ1Y3Rvci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB2b2lkIERlc3Ryb3koKTsKKworICBib29sIGVtcHR5KCkgY29uc3Q7CisgIGludCBzaXplKCkgY29uc3Q7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICBjb25zdCB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSYgR2V0KGludCBpbmRleCkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIE11dGFibGUoaW50IGluZGV4KTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB2b2lkIERlbGV0ZShpbnQgaW5kZXgpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBBZGQodHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHByb3RvdHlwZSA9IE5VTEwpOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBSZW1vdmVMYXN0KCk7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBDbGVhcigpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFJlcGVhdGVkUHRyRmllbGRCYXNlJiBvdGhlcik7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBDb3B5RnJvbShjb25zdCBSZXBlYXRlZFB0ckZpZWxkQmFzZSYgb3RoZXIpOworCisgIHZvaWQgQ2xvc2VHYXAoaW50IHN0YXJ0LCBpbnQgbnVtKTsKKworICB2b2lkIFJlc2VydmUoaW50IG5ld19zaXplKTsKKworICBpbnQgQ2FwYWNpdHkoKSBjb25zdDsKKworICAvLyBVc2VkIGZvciBjb25zdHJ1Y3RpbmcgaXRlcmF0b3JzLgorICB2b2lkKiBjb25zdCogcmF3X2RhdGEoKSBjb25zdDsKKyAgdm9pZCoqIHJhd19tdXRhYmxlX2RhdGEoKSBjb25zdDsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiogbXV0YWJsZV9kYXRhKCk7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgY29uc3QgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIGNvbnN0KiBkYXRhKCkgY29uc3Q7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICBpbmxpbmUgdm9pZCBTd2FwKFJlcGVhdGVkUHRyRmllbGRCYXNlKiBvdGhlcikgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworCisgIHZvaWQgU3dhcEVsZW1lbnRzKGludCBpbmRleDEsIGludCBpbmRleDIpOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworCisgIC8vIEFkdmFuY2VkIG1lbW9yeSBtYW5hZ2VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gTGlrZSBBZGQoKSwgYnV0IGlmIHRoZXJlIGFyZSBubyBjbGVhcmVkIG9iamVjdHMgdG8gdXNlLCByZXR1cm5zIE5VTEwuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIEFkZEZyb21DbGVhcmVkKCk7CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkKHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSkgeworICAgIHR5cGVuYW1lIFR5cGVJbXBsZW1lbnRzTWVyZ2VCZWhhdmlvcjx0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZT46OnR5cGUgdDsKKyAgICBBZGRBbGxvY2F0ZWRJbnRlcm5hbDxUeXBlSGFuZGxlcj4odmFsdWUsIHQpOworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB2b2lkIFVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkKHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSk7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogUmVsZWFzZUxhc3QoKSB7CisgICAgdHlwZW5hbWUgVHlwZUltcGxlbWVudHNNZXJnZUJlaGF2aW9yPHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlPjo6dHlwZSB0OworICAgIHJldHVybiBSZWxlYXNlTGFzdEludGVybmFsPFR5cGVIYW5kbGVyPih0KTsKKyAgfQorCisgIC8vIFJlbGVhc2VzIGxhc3QgZWxlbWVudCBhbmQgcmV0dXJucyBpdCwgYnV0IGRvZXMgbm90IGRvIG91dC1vZi1hcmVuYSBjb3B5LgorICAvLyBBbmQganVzdCByZXR1cm5zIHRoZSByYXcgcG9pbnRlciB0byB0aGUgY29udGFpbmVkIGVsZW1lbnQgaW4gdGhlIGFyZW5hLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCk7CisKKyAgaW50IENsZWFyZWRDb3VudCgpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQ2xlYXJlZCh0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBSZWxlYXNlQ2xlYXJlZCgpOworCisgcHJvdGVjdGVkOgorICBpbmxpbmUgdm9pZCBJbnRlcm5hbFN3YXAoUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIG90aGVyKTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkSW50ZXJuYWwodHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkSW50ZXJuYWwodHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkU2xvd1dpdGhDb3B5KHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIHZhbHVlX2FyZW5hLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogbXlfYXJlbmEpCisgICAgICBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkU2xvd1dpdGhvdXRDb3B5KHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSkKKyAgICAgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkU7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogUmVsZWFzZUxhc3RJbnRlcm5hbChnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlKTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogUmVsZWFzZUxhc3RJbnRlcm5hbChnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSk7CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIGlubGluZSB2b2lkIFN3YXBGYWxsYmFjayhSZXBlYXRlZFB0ckZpZWxkQmFzZSogb3RoZXIpIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkU7CisKKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gYXJlbmFfOworICB9CisKKyBwcml2YXRlOgorICBzdGF0aWMgY29uc3QgaW50IGtJbml0aWFsU2l6ZSA9IDA7CisgIC8vIEEgZmV3IG5vdGVzIG9uIGludGVybmFsIHJlcHJlc2VudGF0aW9uOgorICAvLworICAvLyBXZSB1c2UgYW4gaW5kaXJlY3RlZCBhcHByb2FjaCwgd2l0aCBzdHJ1Y3QgUmVwLCB0byBrZWVwCisgIC8vIHNpemVvZihSZXBlYXRlZFB0ckZpZWxkQmFzZSkgZXF1aXZhbGVudCB0byB3aGF0IGl0IHdhcyBiZWZvcmUgYXJlbmEgc3VwcG9ydAorICAvLyB3YXMgYWRkZWQsIG5hbWVseSwgMyA4LWJ5dGUgbWFjaGluZSB3b3JkcyBvbiB4ODYtNjQuIEFuIGluc3RhbmNlIG9mIFJlcCBpcworICAvLyBhbGxvY2F0ZWQgb25seSB3aGVuIHRoZSByZXBlYXRlZCBmaWVsZCBpcyBub24tZW1wdHksIGFuZCBpdCBpcyBhCisgIC8vIGR5bmFtaWNhbGx5LXNpemVkIHN0cnVjdCAodGhlIGhlYWRlciBpcyBkaXJlY3RseSBmb2xsb3dlZCBieSBlbGVtZW50c1tdKS4KKyAgLy8gV2UgcGxhY2UgYXJlbmFfIGFuZCBjdXJyZW50X3NpemVfIGRpcmVjdGx5IGluIHRoZSBvYmplY3QgdG8gYXZvaWQgY2FjaGUKKyAgLy8gbWlzc2VzIGR1ZSB0byB0aGUgaW5kaXJlY3Rpb24sIGJlY2F1c2UgdGhlc2UgZmllbGRzIGFyZSBjaGVja2VkIGZyZXF1ZW50bHkuCisgIC8vIFBsYWNpbmcgYWxsIGZpZWxkcyBkaXJlY3RseSBpbiB0aGUgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgaW5zdGFuY2UgY29zdHMKKyAgLy8gc2lnbmlmaWNhbnQgcGVyZm9ybWFuY2UgZm9yIG1lbW9yeS1zZW5zaXRpdmUgd29ya2xvYWRzLgorICBBcmVuYSogYXJlbmFfOworICBpbnQgICAgY3VycmVudF9zaXplXzsKKyAgaW50ICAgIHRvdGFsX3NpemVfOworICBzdHJ1Y3QgUmVwIHsKKyAgICBpbnQgICAgYWxsb2NhdGVkX3NpemU7CisgICAgdm9pZCogIGVsZW1lbnRzWzFdOworICB9OworICBzdGF0aWMgY29uc3Qgc2l6ZV90IGtSZXBIZWFkZXJTaXplID0gc2l6ZW9mKFJlcCkgLSBzaXplb2Yodm9pZCopOworICAvLyBDb250YWlucyBhcmVuYSBwdHIgYW5kIHRoZSBlbGVtZW50cyBhcnJheS4gV2UgYWxzbyBrZWVwIHRoZSBpbnZhcmlhbnQgdGhhdAorICAvLyBpZiByZXBfIGlzIE5VTEwsIHRoZW4gYXJlbmEgaXMgTlVMTC4KKyAgUmVwKiByZXBfOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgc3RhdGljIGlubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogY2FzdCh2b2lkKiBlbGVtZW50KSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqPihlbGVtZW50KTsKKyAgfQorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIGNhc3QoY29uc3Qgdm9pZCogZWxlbWVudCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKj4oZWxlbWVudCk7CisgIH0KKworICAvLyBOb24tdGVtcGxhdGVkIGlubmVyIGZ1bmN0aW9uIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24uIFRha2VzIGEgZnVuY3Rpb24KKyAgLy8gcG9pbnRlciB0byB0aGUgdHlwZS1zcGVjaWZpYyAodGVtcGxhdGVkKSBpbm5lciBhbGxvY2F0ZS9tZXJnZSBsb29wLgorICB2b2lkIE1lcmdlRnJvbUludGVybmFsKAorICAgICAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZEJhc2UmIG90aGVyLAorICAgICAgdm9pZCAoUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Oippbm5lcl9sb29wKSh2b2lkKiosIHZvaWQqKiwgaW50LCBpbnQpKTsKKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBNZXJnZUZyb21Jbm5lckxvb3AoCisgICAgICB2b2lkKiogb3VyX2VsZW1zLCB2b2lkKiogb3RoZXJfZWxlbXMsIGludCBsZW5ndGgsIGludCBhbHJlYWR5X2FsbG9jYXRlZCk7CisKKyAgLy8gSW50ZXJuYWwgaGVscGVyOiBleHRlbmQgYXJyYXkgc3BhY2UgaWYgbmVjZXNzYXJ5IHRvIGNvbnRhaW4gfGV4dGVuZF9hbW91bnR8CisgIC8vIG1vcmUgZWxlbWVudHMsIGFuZCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBlbGVtZW50IGltbWVkaWF0ZWx5IGZvbGxvd2luZworICAvLyB0aGUgb2xkIGxpc3Qgb2YgZWxlbWVudHMuICBUaGlzIGludGVyZmFjZSBmYWN0b3JzIG91dCBjb21tb24gYmVoYXZpb3IgZnJvbQorICAvLyBSZXNlcnZlKCkgYW5kIE1lcmdlRnJvbSgpIHRvIHJlZHVjZSBjb2RlIHNpemUuIHxleHRlbmRfYW1vdW50fCBtdXN0IGJlID4gMC4KKyAgdm9pZCoqIEludGVybmFsRXh0ZW5kKGludCBleHRlbmRfYW1vdW50KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRQdHJGaWVsZEJhc2UpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEdlbmVyaWNUeXBlPgorY2xhc3MgR2VuZXJpY1R5cGVIYW5kbGVyIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgR2VuZXJpY1R5cGUgVHlwZTsKKyAgc3RhdGljIGlubGluZSBHZW5lcmljVHlwZSogTmV3KEFyZW5hKiBhcmVuYSkgeworICAgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNYXliZU1lc3NhZ2U8VHlwZT4oCisgICAgICAgIGFyZW5hLCBzdGF0aWNfY2FzdDxHZW5lcmljVHlwZSo+KDApKTsKKyAgfQorICAvLyBXZSBmb3JjZSBOZXdGcm9tUHJvdG90eXBlKCkgYW5kIERlbGV0ZSgpIHRvIGJlIG5vbi1pbmxpbmUgdG8gcmVkdWNlIGNvZGUKKyAgLy8gc2l6ZTogZWxzZSwgc2V2ZXJhbCBvdGhlciBtZXRob2RzIGdldCBpbmxpbmVkIGNvcGllcyBvZiBtZXNzYWdlIHR5cGVzJworICAvLyBjb25zdHJ1Y3RvcnMgYW5kIGRlc3RydWN0b3JzLiBOb3RlIHRoYXQgdGhlIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgbWFjcm8KKyAgLy8gcmVxdWlyZXMgdGhlICdpbmxpbmUnIHN0b3JhZ2UgY2xhc3MgaGVyZSwgd2hpY2ggaXMgc29tZXdoYXQgY29uZnVzaW5nLCBidXQKKyAgLy8gdGhlIGNvbXBpbGVyIGRvZXMgdGhlIHJpZ2h0IHRoaW5nLgorICBzdGF0aWMgaW5saW5lIEdlbmVyaWNUeXBlKiBOZXdGcm9tUHJvdG90eXBlKGNvbnN0IEdlbmVyaWNUeXBlKiBwcm90b3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEgPSBOVUxMKQorICAgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgeworICAgIHJldHVybiBOZXcoYXJlbmEpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBEZWxldGUoR2VuZXJpY1R5cGUqIHZhbHVlLCBBcmVuYSogYXJlbmEpCisgICAgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIGRlbGV0ZSB2YWx1ZTsKKyAgICB9CisgIH0KKyAgc3RhdGljIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYShHZW5lcmljVHlwZSogdmFsdWUpIHsKKyAgICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6R2V0QXJlbmE8VHlwZT4odmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoR2VuZXJpY1R5cGUqIHZhbHVlKSB7CisgICAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkdldEFyZW5hPFR5cGU+KHZhbHVlKTsKKyAgfQorCisgIHN0YXRpYyBpbmxpbmUgdm9pZCBDbGVhcihHZW5lcmljVHlwZSogdmFsdWUpIHsgdmFsdWUtPkNsZWFyKCk7IH0KKyAgc3RhdGljIGlubGluZSB2b2lkIE1lcmdlKGNvbnN0IEdlbmVyaWNUeXBlJiBmcm9tLCBHZW5lcmljVHlwZSogdG8pCisgICAgICBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FIHsKKyAgICB0by0+TWVyZ2VGcm9tKGZyb20pOworICB9CisgIHN0YXRpYyBpbmxpbmUgaW50IFNwYWNlVXNlZChjb25zdCBHZW5lcmljVHlwZSYgdmFsdWUpIHsKKyAgICByZXR1cm4gdmFsdWUuU3BhY2VVc2VkKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCBUeXBlJiBkZWZhdWx0X2luc3RhbmNlKCkgeworICAgIHJldHVybiBUeXBlOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIH0KK307CisKKy8vIE1hY3JvcyBmb3Igc3BlY2lhbGl6aW5nIEdlbmVyaWNUeXBlSGFuZGxlciBmb3IgYmFzZSBwcm90byB0eXBlcywgdGhlc2UgYXJlCisvLyBhcmUgZGVmaW5lZCBoZXJlLCB0byBhbGxvdyBpbmxpbmluZyB0aGVtIGF0IHRoZWlyIGNhbGxzaXRlcy4KKyNkZWZpbmUgREVGSU5FX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9QUk9UT19UWVBFUyhJbmxpbmUsIFR5cGVOYW1lKSAgICAgICAgICBcCisgICAgdGVtcGxhdGU8PiBcCisgICAgSW5saW5lIFR5cGVOYW1lKiBHZW5lcmljVHlwZUhhbmRsZXI8VHlwZU5hbWU+OjpOZXdGcm9tUHJvdG90eXBlKCAgICAgICAgICAgXAorICAgICAgICBjb25zdCBUeXBlTmFtZSogcHJvdG90eXBlLCBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsgICAgICAgICAgICAgICAgICAgICBcCisgICAgICByZXR1cm4gcHJvdG90eXBlLT5OZXcoYXJlbmEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0ZW1wbGF0ZTw+IFwKKyAgICBJbmxpbmUgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdlbmVyaWNUeXBlSGFuZGxlcjxUeXBlTmFtZT46OkdldEFyZW5hKCAgICAgICAgICAgICAgXAorICAgICAgICBUeXBlTmFtZSogdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiB2YWx1ZS0+R2V0QXJlbmEoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHRlbXBsYXRlPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBJbmxpbmUgdm9pZCogR2VuZXJpY1R5cGVIYW5kbGVyPFR5cGVOYW1lPjo6R2V0TWF5YmVBcmVuYVBvaW50ZXIoICAgICAgICAgICBcCisgICAgICAgIFR5cGVOYW1lKiB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIHZhbHVlLT5HZXRNYXliZUFyZW5hUG9pbnRlcigpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9CisjZGVmaW5lIERFRklORV9TUEVDSUFMSVpBVElPTlNfRk9SX0JBU0VfUFJPVE9fVFlQRVNfTk9JTkxJTkUoVHlwZU5hbWUpICAgICAgICAgXAorICAgIERFRklORV9TUEVDSUFMSVpBVElPTlNfRk9SX0JBU0VfUFJPVE9fVFlQRVMoLCBUeXBlTmFtZSkKKworLy8gSW1wbGVtZW50cyBHZW5lcmljVHlwZUhhbmRsZXIgc3BlY2lhbGl6YXRpb24gcmVxdWlyZWQgYnkgUmVwZWF0ZWRQdHJGaWVsZHMKKy8vIHRvIHdvcmsgd2l0aCBNZXNzYWdlTGl0ZSB0eXBlLgordGVtcGxhdGUgPD4KK2lubGluZSB2b2lkIEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlTGl0ZT46Ok1lcmdlKAorICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiBmcm9tLCBNZXNzYWdlTGl0ZSogdG8pIHsKKyAgdG8tPkNoZWNrVHlwZUFuZE1lcmdlRnJvbShmcm9tKTsKK30KKworREVGSU5FX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9QUk9UT19UWVBFUyhpbmxpbmUsIE1lc3NhZ2VMaXRlKTsKKworLy8gRGVjbGFyYXRpb25zIG9mIHRoZSBzcGVjaWFsaXphdGlvbiBhcyB3ZSBjYW5ub3QgZGVmaW5lIHRoZW0gaGVyZSwgYXMgdGhlCisvLyBoZWFkZXIgdGhhdCBkZWZpbmVzIFByb3RvY29sTWVzc2FnZSBkZXBlbmRzIG9uIHR5cGVzIGRlZmluZWQgaW4gdGhpcyBoZWFkZXIuCisjZGVmaW5lIERFQ0xBUkVfU1BFQ0lBTElaQVRJT05TX0ZPUl9CQVNFX1BST1RPX1RZUEVTKFR5cGVOYW1lKSAgICAgICAgICAgICAgICAgXAorICAgIHRlbXBsYXRlPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBUeXBlTmFtZSogR2VuZXJpY1R5cGVIYW5kbGVyPFR5cGVOYW1lPjo6TmV3RnJvbVByb3RvdHlwZSggICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNvbnN0IFR5cGVOYW1lKiBwcm90b3R5cGUsIGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0ZW1wbGF0ZTw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdlbmVyaWNUeXBlSGFuZGxlcjxUeXBlTmFtZT46OkdldEFyZW5hKCAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgVHlwZU5hbWUqIHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGU8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHZvaWQqIEdlbmVyaWNUeXBlSGFuZGxlcjxUeXBlTmFtZT46OkdldE1heWJlQXJlbmFQb2ludGVyKCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgVHlwZU5hbWUqIHZhbHVlKTsKKworLy8gTWVzc2FnZSBzcGVjaWFsaXphdGlvbiBib2RpZXMgZGVmaW5lZCBpbiBtZXNzYWdlLmNjLiBUaGlzIHNwbGl0IGlzIG5lY2Vzc2FyeQorLy8gdG8gYWxsb3cgcHJvdG8yLWxpdGUgKHdoaWNoIGluY2x1ZGVzIHRoaXMgaGVhZGVyKSB0byBiZSBpbmRlcGVuZGVudCBvZgorLy8gTWVzc2FnZS4KK0RFQ0xBUkVfU1BFQ0lBTElaQVRJT05TX0ZPUl9CQVNFX1BST1RPX1RZUEVTKE1lc3NhZ2UpOworCisKKyN1bmRlZiBERUNMQVJFX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9DTEFTU0VTCisKK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgTWVzc2FnZUxpdGUmIEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlTGl0ZT46OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIC8vIFllcywgdGhlIGJlaGF2aW9yIG9mIHRoZSBjb2RlIGlzIHVuZGVmaW5lZCwgYnV0IHRoaXMgZnVuY3Rpb24gaXMgb25seQorICAvLyBjYWxsZWQgd2hlbiB3ZSdyZSBhbHJlYWR5IGRlZXAgaW50byB0aGUgd29ybGQgb2YgdW5kZWZpbmVkLCBiZWNhdXNlIHRoZQorICAvLyBjYWxsZXIgY2FsbGVkIEdldChpbmRleCkgb3V0IG9mIGJvdW5kcy4KKyAgTWVzc2FnZUxpdGUqIG51bGwgPSBOVUxMOworICByZXR1cm4gKm51bGw7Cit9CisKK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgTWVzc2FnZSYgR2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+OjpkZWZhdWx0X2luc3RhbmNlKCkgeworICAvLyBZZXMsIHRoZSBiZWhhdmlvciBvZiB0aGUgY29kZSBpcyB1bmRlZmluZWQsIGJ1dCB0aGlzIGZ1bmN0aW9uIGlzIG9ubHkKKyAgLy8gY2FsbGVkIHdoZW4gd2UncmUgYWxyZWFkeSBkZWVwIGludG8gdGhlIHdvcmxkIG9mIHVuZGVmaW5lZCwgYmVjYXVzZSB0aGUKKyAgLy8gY2FsbGVyIGNhbGxlZCBHZXQoaW5kZXgpIG91dCBvZiBib3VuZHMuCisgIE1lc3NhZ2UqIG51bGwgPSBOVUxMOworICByZXR1cm4gKm51bGw7Cit9CisKKworLy8gSEFDSzogIElmIGEgY2xhc3MgaXMgZGVjbGFyZWQgYXMgRExMLWV4cG9ydGVkIGluIE1TVkMsIGl0IGluc2lzdHMgb24KKy8vICAgZ2VuZXJhdGluZyBjb3BpZXMgb2YgYWxsIGl0cyBtZXRob2RzIC0tIGV2ZW4gaW5saW5lIG9uZXMgLS0gdG8gaW5jbHVkZQorLy8gICBpbiB0aGUgRExMLiAgQnV0IFNwYWNlVXNlZCgpIGNhbGxzIFN0cmluZ1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSB3aGljaAorLy8gICBpc24ndCBpbiB0aGUgbGl0ZSBsaWJyYXJ5LCB0aGVyZWZvcmUgdGhlIGxpdGUgbGlicmFyeSBjYW5ub3QgbGluayBpZgorLy8gICBTdHJpbmdUeXBlSGFuZGxlciBpcyBleHBvcnRlZC4gIFNvLCB3ZSBmYWN0b3Igb3V0IFN0cmluZ1R5cGVIYW5kbGVyQmFzZSwKKy8vICAgZXhwb3J0IHRoYXQsIHRoZW4gbWFrZSBTdHJpbmdUeXBlSGFuZGxlciBiZSBhIHN1YmNsYXNzIHdoaWNoIGlzIE5PVAorLy8gICBleHBvcnRlZC4KKy8vIFRPRE8oa2VudG9uKTogIFRoZXJlIGhhcyB0byBiZSBhIGJldHRlciB3YXkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU3RyaW5nVHlwZUhhbmRsZXJCYXNlIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgc3RyaW5nIFR5cGU7CisKKyAgc3RhdGljIGlubGluZSBzdHJpbmcqIE5ldyhBcmVuYSogYXJlbmEpIHsKKyAgICByZXR1cm4gQXJlbmE6OkNyZWF0ZTxzdHJpbmc+KGFyZW5hKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHN0cmluZyogTmV3RnJvbVByb3RvdHlwZShjb25zdCBzdHJpbmcqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICAgIHJldHVybiBOZXcoYXJlbmEpOworICB9CisgIHN0YXRpYyBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmEoc3RyaW5nKikgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoc3RyaW5nKiB2YWx1ZSkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBEZWxldGUoc3RyaW5nKiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIGRlbGV0ZSB2YWx1ZTsKKyAgICB9CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIENsZWFyKHN0cmluZyogdmFsdWUpIHsgdmFsdWUtPmNsZWFyKCk7IH0KKyAgc3RhdGljIGlubGluZSB2b2lkIE1lcmdlKGNvbnN0IHN0cmluZyYgZnJvbSwgc3RyaW5nKiB0bykgeyAqdG8gPSBmcm9tOyB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgVHlwZSYgZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgfQorfTsKKworY2xhc3MgU3RyaW5nVHlwZUhhbmRsZXIgOiBwdWJsaWMgU3RyaW5nVHlwZUhhbmRsZXJCYXNlIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbnQgU3BhY2VVc2VkKGNvbnN0IHN0cmluZyYgdmFsdWUpICB7CisgICAgcmV0dXJuIHNpemVvZih2YWx1ZSkgKyBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKHZhbHVlKTsKKyAgfQorfTsKKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gUmVwZWF0ZWRQdHJGaWVsZCBpcyBsaWtlIFJlcGVhdGVkRmllbGQsIGJ1dCB1c2VkIGZvciByZXBlYXRlZCBzdHJpbmdzIG9yCisvLyBNZXNzYWdlcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgorY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZCA6IHB1YmxpYyBpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZEJhc2UgeworIHB1YmxpYzoKKyAgUmVwZWF0ZWRQdHJGaWVsZCgpOworICBleHBsaWNpdCBSZXBlYXRlZFB0ckZpZWxkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKworICBSZXBlYXRlZFB0ckZpZWxkKGNvbnN0IFJlcGVhdGVkUHRyRmllbGQmIG90aGVyKTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CisgIFJlcGVhdGVkUHRyRmllbGQoSXRlciBiZWdpbiwgY29uc3QgSXRlciYgZW5kKTsKKyAgflJlcGVhdGVkUHRyRmllbGQoKTsKKworICBSZXBlYXRlZFB0ckZpZWxkJiBvcGVyYXRvcj0oY29uc3QgUmVwZWF0ZWRQdHJGaWVsZCYgb3RoZXIpOworCisgIGJvb2wgZW1wdHkoKSBjb25zdDsKKyAgaW50IHNpemUoKSBjb25zdDsKKworICBjb25zdCBFbGVtZW50JiBHZXQoaW50IGluZGV4KSBjb25zdDsKKyAgRWxlbWVudCogTXV0YWJsZShpbnQgaW5kZXgpOworICBFbGVtZW50KiBBZGQoKTsKKworICAvLyBSZW1vdmUgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgYXJyYXkuCisgIC8vIE93bmVyc2hpcCBvZiB0aGUgZWxlbWVudCBpcyByZXRhaW5lZCBieSB0aGUgYXJyYXkuCisgIHZvaWQgUmVtb3ZlTGFzdCgpOworCisgIC8vIERlbGV0ZSBlbGVtZW50cyB3aXRoIGluZGljZXMgaW4gdGhlIHJhbmdlIFtzdGFydCAuLiBzdGFydCtudW0tMV0uCisgIC8vIENhdXRpb246IGltcGxlbWVudGF0aW9uIG1vdmVzIGFsbCBlbGVtZW50cyB3aXRoIGluZGljZXMgW3N0YXJ0K251bSAuLiBdLgorICAvLyBDYWxsaW5nIHRoaXMgcm91dGluZSBpbnNpZGUgYSBsb29wIGNhbiBjYXVzZSBxdWFkcmF0aWMgYmVoYXZpb3IuCisgIHZvaWQgRGVsZXRlU3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtKTsKKworICB2b2lkIENsZWFyKCk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFJlcGVhdGVkUHRyRmllbGQmIG90aGVyKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBSZXBlYXRlZFB0ckZpZWxkJiBvdGhlcik7CisKKyAgLy8gUmVzZXJ2ZSBzcGFjZSB0byBleHBhbmQgdGhlIGZpZWxkIHRvIGF0IGxlYXN0IHRoZSBnaXZlbiBzaXplLiAgVGhpcyBvbmx5CisgIC8vIHJlc2l6ZXMgdGhlIHBvaW50ZXIgYXJyYXk7IGl0IGRvZXNuJ3QgYWxsb2NhdGUgYW55IG9iamVjdHMuICBJZiB0aGUKKyAgLy8gYXJyYXkgaXMgZ3Jvd24sIGl0IHdpbGwgYWx3YXlzIGJlIGF0IGxlYXN0IGRvdWJsZWQgaW4gc2l6ZS4KKyAgdm9pZCBSZXNlcnZlKGludCBuZXdfc2l6ZSk7CisKKyAgaW50IENhcGFjaXR5KCkgY29uc3Q7CisKKyAgLy8gR2V0cyB0aGUgdW5kZXJseWluZyBhcnJheS4gIFRoaXMgcG9pbnRlciBpcyBwb3NzaWJseSBpbnZhbGlkYXRlZCBieQorICAvLyBhbnkgYWRkIG9yIHJlbW92ZSBvcGVyYXRpb24uCisgIEVsZW1lbnQqKiBtdXRhYmxlX2RhdGEoKTsKKyAgY29uc3QgRWxlbWVudCogY29uc3QqIGRhdGEoKSBjb25zdDsKKworICAvLyBTd2FwIGVudGlyZSBjb250ZW50cyB3aXRoICJvdGhlciIuIElmIHRoZXkgYXJlIG9uIHNlcGFyYXRlIGFyZW5hcywgdGhlbgorICAvLyBjb3BpZXMgZGF0YS4KKyAgdm9pZCBTd2FwKFJlcGVhdGVkUHRyRmllbGQqIG90aGVyKTsKKworICAvLyBTd2FwIGVudGlyZSBjb250ZW50cyB3aXRoICJvdGhlciIuIENhbGxlciBzaG91bGQgZ3VhcmFudGVlIHRoYXQgZWl0aGVyIGJvdGgKKyAgLy8gZmllbGRzIGFyZSBvbiB0aGUgc2FtZSBhcmVuYSBvciBib3RoIGFyZSBvbiB0aGUgaGVhcC4gU3dhcHBpbmcgYmV0d2VlbgorICAvLyBkaWZmZXJlbnQgYXJlbmFzIHdpdGggdGhpcyBmdW5jdGlvbiBpcyBkaXNhbGxvd2VkIGFuZCBpcyBjYXVnaHQgdmlhCisgIC8vIEdPT0dMRV9EQ0hFQ0suCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKFJlcGVhdGVkUHRyRmllbGQqIG90aGVyKTsKKworICAvLyBTd2FwIHR3byBlbGVtZW50cy4KKyAgdm9pZCBTd2FwRWxlbWVudHMoaW50IGluZGV4MSwgaW50IGluZGV4Mik7CisKKyAgLy8gU1RMLWxpa2UgaXRlcmF0b3Igc3VwcG9ydAorICB0eXBlZGVmIGludGVybmFsOjpSZXBlYXRlZFB0ckl0ZXJhdG9yPEVsZW1lbnQ+IGl0ZXJhdG9yOworICB0eXBlZGVmIGludGVybmFsOjpSZXBlYXRlZFB0ckl0ZXJhdG9yPGNvbnN0IEVsZW1lbnQ+IGNvbnN0X2l0ZXJhdG9yOworICB0eXBlZGVmIEVsZW1lbnQgdmFsdWVfdHlwZTsKKyAgdHlwZWRlZiB2YWx1ZV90eXBlJiByZWZlcmVuY2U7CisgIHR5cGVkZWYgY29uc3QgdmFsdWVfdHlwZSYgY29uc3RfcmVmZXJlbmNlOworICB0eXBlZGVmIHZhbHVlX3R5cGUqIHBvaW50ZXI7CisgIHR5cGVkZWYgY29uc3QgdmFsdWVfdHlwZSogY29uc3RfcG9pbnRlcjsKKyAgdHlwZWRlZiBpbnQgc2l6ZV90eXBlOworICB0eXBlZGVmIHB0cmRpZmZfdCBkaWZmZXJlbmNlX3R5cGU7CisKKyAgaXRlcmF0b3IgYmVnaW4oKTsKKyAgY29uc3RfaXRlcmF0b3IgYmVnaW4oKSBjb25zdDsKKyAgY29uc3RfaXRlcmF0b3IgY2JlZ2luKCkgY29uc3Q7CisgIGl0ZXJhdG9yIGVuZCgpOworICBjb25zdF9pdGVyYXRvciBlbmQoKSBjb25zdDsKKyAgY29uc3RfaXRlcmF0b3IgY2VuZCgpIGNvbnN0OworCisgIC8vIFJldmVyc2UgaXRlcmF0b3Igc3VwcG9ydAorICB0eXBlZGVmIHN0ZDo6cmV2ZXJzZV9pdGVyYXRvcjxjb25zdF9pdGVyYXRvcj4gY29uc3RfcmV2ZXJzZV9pdGVyYXRvcjsKKyAgdHlwZWRlZiBzdGQ6OnJldmVyc2VfaXRlcmF0b3I8aXRlcmF0b3I+IHJldmVyc2VfaXRlcmF0b3I7CisgIHJldmVyc2VfaXRlcmF0b3IgcmJlZ2luKCkgeworICAgIHJldHVybiByZXZlcnNlX2l0ZXJhdG9yKGVuZCgpKTsKKyAgfQorICBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yIHJiZWdpbigpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfcmV2ZXJzZV9pdGVyYXRvcihlbmQoKSk7CisgIH0KKyAgcmV2ZXJzZV9pdGVyYXRvciByZW5kKCkgeworICAgIHJldHVybiByZXZlcnNlX2l0ZXJhdG9yKGJlZ2luKCkpOworICB9CisgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmVuZCgpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfcmV2ZXJzZV9pdGVyYXRvcihiZWdpbigpKTsKKyAgfQorCisgIC8vIEN1c3RvbSBTVEwtbGlrZSBpdGVyYXRvciB0aGF0IGl0ZXJhdGVzIG92ZXIgYW5kIHJldHVybnMgdGhlIHVuZGVybHlpbmcKKyAgLy8gcG9pbnRlcnMgdG8gRWxlbWVudCByYXRoZXIgdGhhbiBFbGVtZW50IGl0c2VsZi4KKyAgdHlwZWRlZiBpbnRlcm5hbDo6UmVwZWF0ZWRQdHJPdmVyUHRyc0l0ZXJhdG9yPEVsZW1lbnQsIHZvaWQqPgorICBwb2ludGVyX2l0ZXJhdG9yOworICB0eXBlZGVmIGludGVybmFsOjpSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3I8Y29uc3QgRWxlbWVudCwgY29uc3Qgdm9pZCo+CisgIGNvbnN0X3BvaW50ZXJfaXRlcmF0b3I7CisgIHBvaW50ZXJfaXRlcmF0b3IgcG9pbnRlcl9iZWdpbigpOworICBjb25zdF9wb2ludGVyX2l0ZXJhdG9yIHBvaW50ZXJfYmVnaW4oKSBjb25zdDsKKyAgcG9pbnRlcl9pdGVyYXRvciBwb2ludGVyX2VuZCgpOworICBjb25zdF9wb2ludGVyX2l0ZXJhdG9yIHBvaW50ZXJfZW5kKCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyAoYW4gZXN0aW1hdGUgb2YpIHRoZSBudW1iZXIgb2YgYnl0ZXMgdXNlZCBieSB0aGUgcmVwZWF0ZWQgZmllbGQsCisgIC8vIGV4Y2x1ZGluZyBzaXplb2YoKnRoaXMpLgorICBpbnQgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpIGNvbnN0OworCisgIC8vIEFkdmFuY2VkIG1lbW9yeSBtYW5hZ2VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFdoZW4gaGFyZGNvcmUgbWVtb3J5IG1hbmFnZW1lbnQgYmVjb21lcyBuZWNlc3NhcnkgLS0gYXMgaXQgc29tZXRpbWVzCisgIC8vIGRvZXMgaGVyZSBhdCBHb29nbGUgLS0gdGhlIGZvbGxvd2luZyBtZXRob2RzIG1heSBiZSB1c2VmdWwuCisKKyAgLy8gQWRkIGFuIGFscmVhZHktYWxsb2NhdGVkIG9iamVjdCwgcGFzc2luZyBvd25lcnNoaXAgdG8gdGhlCisgIC8vIFJlcGVhdGVkUHRyRmllbGQuCisgIC8vCisgIC8vIE5vdGUgdGhhdCBzb21lIHNwZWNpYWwgYmVoYXZpb3Igb2NjdXJzIHdpdGggcmVzcGVjdCB0byBhcmVuYXM6CisgIC8vCisgIC8vICAgKGkpIGlmIHRoaXMgZmllbGQgaG9sZHMgc3VibWVzc2FnZXMsIHRoZSBuZXcgc3VibWVzc2FnZSB3aWxsIGJlIGNvcGllZCBpZgorICAvLyAgIHRoZSBvcmlnaW5hbCBpcyBpbiBhbiBhcmVuYSBhbmQgdGhpcyBSZXBlYXRlZFB0ckZpZWxkIGlzIGVpdGhlciBpbiBhCisgIC8vICAgZGlmZmVyZW50IGFyZW5hLCBvciBvbiB0aGUgaGVhcC4KKyAgLy8gICAoaWkpIGlmIHRoaXMgZmllbGQgaG9sZHMgc3RyaW5ncywgdGhlIHBhc3NlZC1pbiBzdHJpbmcgKm11c3QqIGJlCisgIC8vICAgaGVhcC1hbGxvY2F0ZWQsIG5vdCBhcmVuYS1hbGxvY2F0ZWQuIFRoZXJlIGlzIG5vIHdheSB0byBkeW5hbWljYWxseSBjaGVjaworICAvLyAgIHRoaXMgYXQgcnVudGltZSwgc28gVXNlciBCZXdhcmUuCisgIHZvaWQgQWRkQWxsb2NhdGVkKEVsZW1lbnQqIHZhbHVlKTsKKworICAvLyBSZW1vdmUgdGhlIGxhc3QgZWxlbWVudCBhbmQgcmV0dXJuIGl0LCBwYXNzaW5nIG93bmVyc2hpcCB0byB0aGUgY2FsbGVyLgorICAvLyBSZXF1aXJlczogIHNpemUoKSA+IDAKKyAgLy8KKyAgLy8gSWYgdGhpcyBSZXBlYXRlZFB0ckZpZWxkIGlzIG9uIGFuIGFyZW5hLCBhbiBvYmplY3QgY29weSBpcyByZXF1aXJlZCB0byBwYXNzCisgIC8vIG93bmVyc2hpcCBiYWNrIHRvIHRoZSB1c2VyIChmb3IgY29tcGF0aWJsZSBzZW1hbnRpY3MpLiBVc2UKKyAgLy8gVW5zYWZlQXJlbmFSZWxlYXNlTGFzdCgpIGlmIHRoaXMgYmVoYXZpb3IgaXMgdW5kZXNpcmVkLgorICBFbGVtZW50KiBSZWxlYXNlTGFzdCgpOworCisgIC8vIEFkZCBhbiBhbHJlYWR5LWFsbG9jYXRlZCBvYmplY3QsIHNraXBwaW5nIGFyZW5hLW93bmVyc2hpcCBjaGVja3MuIFRoZSB1c2VyCisgIC8vIG11c3QgZ3VhcmFudGVlIHRoYXQgdGhlIGdpdmVuIG9iamVjdCBpcyBpbiB0aGUgc2FtZSBhcmVuYSBhcyB0aGlzCisgIC8vIFJlcGVhdGVkUHRyRmllbGQuCisgIHZvaWQgVW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQoRWxlbWVudCogdmFsdWUpOworCisgIC8vIFJlbW92ZSB0aGUgbGFzdCBlbGVtZW50IGFuZCByZXR1cm4gaXQuICBXb3JrcyBvbmx5IHdoZW4gb3BlcmF0aW5nIG9uIGFuCisgIC8vIGFyZW5hLiBUaGUgcmV0dXJuZWQgcG9pbnRlciBpcyB0byB0aGUgb3JpZ2luYWwgb2JqZWN0IGluIHRoZSBhcmVuYSwgaGVuY2UKKyAgLy8gaGFzIHRoZSBhcmVuYSdzIGxpZmV0aW1lLgorICAvLyBSZXF1aXJlczogIGN1cnJlbnRfc2l6ZV8gPiAwCisgIEVsZW1lbnQqIFVuc2FmZUFyZW5hUmVsZWFzZUxhc3QoKTsKKworICAvLyBFeHRyYWN0IGVsZW1lbnRzIHdpdGggaW5kaWNlcyBpbiB0aGUgcmFuZ2UgIltzdGFydCAuLiBzdGFydCtudW0tMV0iLgorICAvLyBUaGUgY2FsbGVyIGFzc3VtZXMgb3duZXJzaGlwIG9mIHRoZSBleHRyYWN0ZWQgZWxlbWVudHMgYW5kIGlzIHJlc3BvbnNpYmxlCisgIC8vIGZvciBkZWxldGluZyB0aGVtIHdoZW4gdGhleSBhcmUgbm8gbG9uZ2VyIG5lZWRlZC4KKyAgLy8gSWYgImVsZW1lbnRzIiBpcyBub24tTlVMTCwgdGhlbiBwb2ludGVycyB0byB0aGUgZXh0cmFjdGVkIGVsZW1lbnRzCisgIC8vIGFyZSBzdG9yZWQgaW4gImVsZW1lbnRzWzAgLi4gbnVtLTFdIiBmb3IgdGhlIGNvbnZlbmllbmNlIG9mIHRoZSBjYWxsZXIuCisgIC8vIElmICJlbGVtZW50cyIgaXMgTlVMTCwgdGhlbiB0aGUgY2FsbGVyIG11c3QgdXNlIHNvbWUgb3RoZXIgbWVjaGFuaXNtCisgIC8vIHRvIHBlcmZvcm0gYW55IGZ1cnRoZXIgb3BlcmF0aW9ucyAobGlrZSBkZWxldGlvbikgb24gdGhlc2UgZWxlbWVudHMuCisgIC8vIENhdXRpb246IGltcGxlbWVudGF0aW9uIGFsc28gbW92ZXMgZWxlbWVudHMgd2l0aCBpbmRpY2VzIFtzdGFydCtudW0gLi5dLgorICAvLyBDYWxsaW5nIHRoaXMgcm91dGluZSBpbnNpZGUgYSBsb29wIGNhbiBjYXVzZSBxdWFkcmF0aWMgYmVoYXZpb3IuCisgIC8vCisgIC8vIE1lbW9yeSBjb3B5aW5nIGJlaGF2aW9yIGlzIGlkZW50aWNhbCB0byBSZWxlYXNlTGFzdCgpLCBkZXNjcmliZWQgYWJvdmU6IGlmCisgIC8vIHRoaXMgUmVwZWF0ZWRQdHJGaWVsZCBpcyBvbiBhbiBhcmVuYSwgYW4gb2JqZWN0IGNvcHkgaXMgcGVyZm9ybWVkIGZvciBlYWNoCisgIC8vIHJldHVybmVkIGVsZW1lbnQsIHNvIHRoYXQgYWxsIHJldHVybmVkIGVsZW1lbnQgcG9pbnRlcnMgYXJlIHRvCisgIC8vIGhlYXAtYWxsb2NhdGVkIGNvcGllcy4gSWYgdGhpcyBjb3B5IGlzIG5vdCBkZXNpcmVkLCB0aGUgdXNlciBzaG91bGQgY2FsbAorICAvLyBVbnNhZmVBcmVuYUV4dHJhY3RTdWJyYW5nZSgpLgorICB2b2lkIEV4dHJhY3RTdWJyYW5nZShpbnQgc3RhcnQsIGludCBudW0sIEVsZW1lbnQqKiBlbGVtZW50cyk7CisKKyAgLy8gSWRlbnRpY2FsIHRvIEV4dHJhY3RTdWJyYW5nZSgpIGRlc2NyaWJlZCBhYm92ZSwgZXhjZXB0IHRoYXQgd2hlbiB0aGlzCisgIC8vIHJlcGVhdGVkIGZpZWxkIGlzIG9uIGFuIGFyZW5hLCBubyBvYmplY3QgY29waWVzIGFyZSBwZXJmb3JtZWQuIEluc3RlYWQsIHRoZQorICAvLyByYXcgb2JqZWN0IHBvaW50ZXJzIGFyZSByZXR1cm5lZC4gVGh1cywgaWYgb24gYW4gYXJlbmEsIHRoZSByZXR1cm5lZAorICAvLyBvYmplY3RzIG11c3Qgbm90IGJlIGZyZWVkLCBiZWNhdXNlIHRoZXkgd2lsbCBub3QgYmUgaGVhcC1hbGxvY2F0ZWQgb2JqZWN0cy4KKyAgdm9pZCBVbnNhZmVBcmVuYUV4dHJhY3RTdWJyYW5nZShpbnQgc3RhcnQsIGludCBudW0sIEVsZW1lbnQqKiBlbGVtZW50cyk7CisKKyAgLy8gV2hlbiBlbGVtZW50cyBhcmUgcmVtb3ZlZCBieSBjYWxscyB0byBSZW1vdmVMYXN0KCkgb3IgQ2xlYXIoKSwgdGhleQorICAvLyBhcmUgbm90IGFjdHVhbGx5IGZyZWVkLiAgSW5zdGVhZCwgdGhleSBhcmUgY2xlYXJlZCBhbmQga2VwdCBzbyB0aGF0CisgIC8vIHRoZXkgY2FuIGJlIHJldXNlZCBsYXRlci4gIFRoaXMgY2FuIHNhdmUgbG90cyBvZiBDUFUgdGltZSB3aGVuCisgIC8vIHJlcGVhdGVkbHkgcmV1c2luZyBhIHByb3RvY29sIG1lc3NhZ2UgZm9yIHNpbWlsYXIgcHVycG9zZXMuCisgIC8vCisgIC8vIEhhcmRjb3JlIHByb2dyYW1zIG1heSBjaG9vc2UgdG8gbWFuaXB1bGF0ZSB0aGVzZSBjbGVhcmVkIG9iamVjdHMKKyAgLy8gdG8gYmV0dGVyIG9wdGltaXplIG1lbW9yeSBtYW5hZ2VtZW50IHVzaW5nIHRoZSBmb2xsb3dpbmcgcm91dGluZXMuCisKKyAgLy8gR2V0IHRoZSBudW1iZXIgb2YgY2xlYXJlZCBvYmplY3RzIHRoYXQgYXJlIGN1cnJlbnRseSBiZWluZyBrZXB0CisgIC8vIGFyb3VuZCBmb3IgcmV1c2UuCisgIGludCBDbGVhcmVkQ291bnQoKSBjb25zdDsKKyAgLy8gQWRkIGFuIGVsZW1lbnQgdG8gdGhlIHBvb2wgb2YgY2xlYXJlZCBvYmplY3RzLCBwYXNzaW5nIG93bmVyc2hpcCB0bworICAvLyB0aGUgUmVwZWF0ZWRQdHJGaWVsZC4gIFRoZSBlbGVtZW50IG11c3QgYmUgY2xlYXJlZCBwcmlvciB0byBjYWxsaW5nCisgIC8vIHRoaXMgbWV0aG9kLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBjYW5ub3QgYmUgY2FsbGVkIHdoZW4gdGhlIHJlcGVhdGVkIGZpZWxkIGlzIG9uIGFuIGFyZW5hIG9yIHdoZW4KKyAgLy8gfHZhbHVlfCBpczsgYm90aCBjYXNlcyB3aWxsIHRyaWdnZXIgYSBHT09HTEVfRENIRUNLLWZhaWx1cmUuCisgIHZvaWQgQWRkQ2xlYXJlZChFbGVtZW50KiB2YWx1ZSk7CisgIC8vIFJlbW92ZSBhIHNpbmdsZSBlbGVtZW50IGZyb20gdGhlIGNsZWFyZWQgcG9vbCBhbmQgcmV0dXJuIGl0LCBwYXNzaW5nCisgIC8vIG93bmVyc2hpcCB0byB0aGUgY2FsbGVyLiAgVGhlIGVsZW1lbnQgaXMgZ3VhcmFudGVlZCB0byBiZSBjbGVhcmVkLgorICAvLyBSZXF1aXJlczogIENsZWFyZWRDb3VudCgpID4gMAorICAvLworICAvLworICAvLyBUaGlzIG1ldGhvZCBjYW5ub3QgYmUgY2FsbGVkIHdoZW4gdGhlIHJlcGVhdGVkIGZpZWxkIGlzIG9uIGFuIGFyZW5hOyBkb2luZworICAvLyBzbyB3aWxsIHRyaWdnZXIgYSBHT09HTEVfRENIRUNLLWZhaWx1cmUuCisgIEVsZW1lbnQqIFJlbGVhc2VDbGVhcmVkKCk7CisKKyAgLy8gUmVtb3ZlIHRoZSBlbGVtZW50IHJlZmVyZW5jZWQgYnkgcG9zaXRpb24uCisgIGl0ZXJhdG9yIGVyYXNlKGNvbnN0X2l0ZXJhdG9yIHBvc2l0aW9uKTsKKworICAvLyBSZW1vdmVzIHRoZSBlbGVtZW50cyBpbiB0aGUgcmFuZ2UgW2ZpcnN0LCBsYXN0KS4KKyAgaXRlcmF0b3IgZXJhc2UoY29uc3RfaXRlcmF0b3IgZmlyc3QsIGNvbnN0X2l0ZXJhdG9yIGxhc3QpOworCisgIC8vIEdldHMgdGhlIGFyZW5hIG9uIHdoaWNoIHRoaXMgUmVwZWF0ZWRQdHJGaWVsZCBzdG9yZXMgaXRzIGVsZW1lbnRzLgorICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgfQorCisgcHJvdGVjdGVkOgorICAvLyBOb3RlOiAgUmVwZWF0ZWRQdHJGaWVsZCBTSE9VTEQgTk9UIGJlIHN1YmNsYXNzZWQgYnkgdXNlcnMuICBXZSBvbmx5CisgIC8vICAgc3ViY2xhc3MgaXQgaW4gb25lIHBsYWNlIGFzIGEgaGFjayBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIHByb3RvMS4gIFRoZQorICAvLyAgIHN1YmNsYXNzIG5lZWRzIHRvIGtub3cgYWJvdXQgVHlwZUhhbmRsZXIgaW4gb3JkZXIgdG8gY2FsbCBwcm90ZWN0ZWQKKyAgLy8gICBtZXRob2RzIG9uIFJlcGVhdGVkUHRyRmllbGRCYXNlLgorICBjbGFzcyBUeXBlSGFuZGxlcjsKKworICAvLyBJbnRlcm5hbCBhcmVuYSBhY2Nlc3NvciBleHBlY3RlZCBieSBoZWxwZXJzIGluIEFyZW5hLgorICBpbmxpbmUgQXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3Q7CisKKyBwcml2YXRlOgorICAvLyBJbXBsZW1lbnRhdGlvbnMgZm9yIEV4dHJhY3RTdWJyYW5nZSgpLiBUaGUgY29weWluZyBiZWhhdmlvciBtdXN0IGJlCisgIC8vIGluY2x1ZGVkIG9ubHkgaWYgdGhlIHR5cGUgc3VwcG9ydHMgdGhlIG5lY2Vzc2FyeSBvcGVyYXRpb25zIChlLmcuLAorICAvLyBNZXJnZUZyb20oKSksIHNvIHdlIG11c3QgcmVzb2x2ZSB0aGlzIGF0IGNvbXBpbGUgdGltZS4gRXh0cmFjdFN1YnJhbmdlKCkKKyAgLy8gdXNlcyBTRklOQUUgdG8gY2hvb3NlIG9uZSBvZiB0aGUgYmVsb3cgaW1wbGVtZW50YXRpb25zLgorICB2b2lkIEV4dHJhY3RTdWJyYW5nZUludGVybmFsKGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCoqIGVsZW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpOworICB2b2lkIEV4dHJhY3RTdWJyYW5nZUludGVybmFsKGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCoqIGVsZW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKTsKKworICBmcmllbmQgY2xhc3MgQXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisKK307CisKKy8vIGltcGxlbWVudGF0aW9uID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRGaWVsZCgpCisgIDogY3VycmVudF9zaXplXygwKSwKKyAgICB0b3RhbF9zaXplXygwKSwKKyAgICByZXBfKE5VTEwpIHsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRGaWVsZChBcmVuYSogYXJlbmEpCisgIDogY3VycmVudF9zaXplXygwKSwKKyAgICB0b3RhbF9zaXplXygwKSwKKyAgICByZXBfKE5VTEwpIHsKKyAvLyBJbiBjYXNlIGFyZW5hIGlzIE5VTEwsIHRoZW4gd2UgZG8gbm90IGNyZWF0ZSByZXBfLCBhcyBjb2RlIGhhcyBhbiBpbnZhcmlhbnQKKyAvLyBgcmVwXyA9PSBOVUxMIHRoZW4gYXJlbmEgPT0gTlVMTGAuCisgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgcmVwXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8UmVwKj4oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPihhcmVuYSwga1JlcEhlYWRlclNpemUpKTsKKyAgcmVwXy0+YXJlbmEgPSBhcmVuYTsKKyB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlJlcGVhdGVkRmllbGQoY29uc3QgUmVwZWF0ZWRGaWVsZCYgb3RoZXIpCisgIDogY3VycmVudF9zaXplXygwKSwKKyAgICB0b3RhbF9zaXplXygwKSwKKyAgICByZXBfKE5VTEwpIHsKKyAgQ29weUZyb20ob3RoZXIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK3RlbXBsYXRlIDx0eXBlbmFtZSBJdGVyPgorUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRGaWVsZChJdGVyIGJlZ2luLCBjb25zdCBJdGVyJiBlbmQpCisgIDogY3VycmVudF9zaXplXygwKSwKKyAgICB0b3RhbF9zaXplXygwKSwKKyAgICByZXBfKE5VTEwpIHsKKyAgaW50IHJlc2VydmUgPSBpbnRlcm5hbDo6Q2FsY3VsYXRlUmVzZXJ2ZShiZWdpbiwgZW5kKTsKKyAgaWYgKHJlc2VydmUgIT0gLTEpIHsKKyAgICBSZXNlcnZlKHJlc2VydmUpOworICAgIGZvciAoOyBiZWdpbiAhPSBlbmQ7ICsrYmVnaW4pIHsKKyAgICAgIEFkZEFscmVhZHlSZXNlcnZlZCgqYmVnaW4pOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBmb3IgKDsgYmVnaW4gIT0gZW5kOyArK2JlZ2luKSB7CisgICAgICBBZGQoKmJlZ2luKTsKKyAgICB9CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+Ojp+UmVwZWF0ZWRGaWVsZCgpIHsKKyAgLy8gU2VlIGV4cGxhbmF0aW9uIGluIFJlc2VydmUoKTogd2UgbmVlZCB0byBpbnZva2UgZGVzdHJ1Y3RvcnMgaGVyZSBmb3IgdGhlCisgIC8vIGNhc2UgdGhhdCBFbGVtZW50IGhhcyBhIG5vbi10cml2aWFsIGRlc3RydWN0b3IuIElmIEVsZW1lbnQgaGFzIGEgdHJpdmlhbAorICAvLyBkZXN0cnVjdG9yIChmb3IgZXhhbXBsZSwgaWYgaXQncyBhIHByaW1pdGl2ZSB0eXBlLCBsaWtlIGludDMyKSwgdGhpcyBlbnRpcmUKKyAgLy8gbG9vcCB3aWxsIGJlIHJlbW92ZWQgYnkgdGhlIG9wdGltaXplci4KKyAgaWYgKHJlcF8gIT0gTlVMTCkgeworICAgIEVsZW1lbnQqIGUgPSAmcmVwXy0+ZWxlbWVudHNbMF07CisgICAgRWxlbWVudCogbGltaXQgPSAmcmVwXy0+ZWxlbWVudHNbdG90YWxfc2l6ZV9dOworICAgIGZvciAoOyBlIDwgbGltaXQ7IGUrKykgeworICAgICAgZS0+RWxlbWVudDo6fkVsZW1lbnQoKTsKKyAgICB9CisgICAgaWYgKHJlcF8tPmFyZW5hID09IE5VTEwpIHsKKyAgICAgIGRlbGV0ZVtdIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHJlcF8pOworICAgIH0KKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+JgorUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6b3BlcmF0b3I9KGNvbnN0IFJlcGVhdGVkRmllbGQmIG90aGVyKSB7CisgIGlmICh0aGlzICE9ICZvdGhlcikKKyAgICBDb3B5RnJvbShvdGhlcik7CisgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgYm9vbCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjplbXB0eSgpIGNvbnN0IHsKKyAgcmV0dXJuIGN1cnJlbnRfc2l6ZV8gPT0gMDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgaW50IFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OnNpemUoKSBjb25zdCB7CisgIHJldHVybiBjdXJyZW50X3NpemVfOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBpbnQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Q2FwYWNpdHkoKSBjb25zdCB7CisgIHJldHVybiB0b3RhbF9zaXplXzsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkFkZEFscmVhZHlSZXNlcnZlZChjb25zdCBFbGVtZW50JiB2YWx1ZSkgeworICBHT09HTEVfRENIRUNLX0xUKGN1cnJlbnRfc2l6ZV8sIHRvdGFsX3NpemVfKTsKKyAgcmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplXysrXSA9IHZhbHVlOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkFkZEFscmVhZHlSZXNlcnZlZCgpIHsKKyAgR09PR0xFX0RDSEVDS19MVChjdXJyZW50X3NpemVfLCB0b3RhbF9zaXplXyk7CisgIHJldHVybiAmcmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplXysrXTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlJlc2l6ZShpbnQgbmV3X3NpemUsIGNvbnN0IEVsZW1lbnQmIHZhbHVlKSB7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobmV3X3NpemUsIDApOworICBpZiAobmV3X3NpemUgPiBjdXJyZW50X3NpemVfKSB7CisgICAgUmVzZXJ2ZShuZXdfc2l6ZSk7CisgICAgc3RkOjpmaWxsKCZyZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXSwKKyAgICAgICAgICAgICAgJnJlcF8tPmVsZW1lbnRzW25ld19zaXplXSwgdmFsdWUpOworICB9CisgIGN1cnJlbnRfc2l6ZV8gPSBuZXdfc2l6ZTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgY29uc3QgRWxlbWVudCYgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6R2V0KGludCBpbmRleCkgY29uc3QgeworICBHT09HTEVfRENIRUNLX0dFKGluZGV4LCAwKTsKKyAgR09PR0xFX0RDSEVDS19MVChpbmRleCwgY3VycmVudF9zaXplXyk7CisgIHJldHVybiByZXBfLT5lbGVtZW50c1tpbmRleF07Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46Ok11dGFibGUoaW50IGluZGV4KSB7CisgIEdPT0dMRV9EQ0hFQ0tfR0UoaW5kZXgsIDApOworICBHT09HTEVfRENIRUNLX0xUKGluZGV4LCBjdXJyZW50X3NpemVfKTsKKyAgcmV0dXJuICZyZXBfLT5lbGVtZW50c1tpbmRleF07Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6U2V0KGludCBpbmRleCwgY29uc3QgRWxlbWVudCYgdmFsdWUpIHsKKyAgR09PR0xFX0RDSEVDS19HRShpbmRleCwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfTFQoaW5kZXgsIGN1cnJlbnRfc2l6ZV8pOworICByZXBfLT5lbGVtZW50c1tpbmRleF0gPSB2YWx1ZTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpBZGQoY29uc3QgRWxlbWVudCYgdmFsdWUpIHsKKyAgaWYgKGN1cnJlbnRfc2l6ZV8gPT0gdG90YWxfc2l6ZV8pIFJlc2VydmUodG90YWxfc2l6ZV8gKyAxKTsKKyAgcmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplXysrXSA9IHZhbHVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpBZGQoKSB7CisgIGlmIChjdXJyZW50X3NpemVfID09IHRvdGFsX3NpemVfKSBSZXNlcnZlKHRvdGFsX3NpemVfICsgMSk7CisgIHJldHVybiAmcmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplXysrXTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpSZW1vdmVMYXN0KCkgeworICBHT09HTEVfRENIRUNLX0dUKGN1cnJlbnRfc2l6ZV8sIDApOworICBjdXJyZW50X3NpemVfLS07Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50Pgordm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpFeHRyYWN0U3VicmFuZ2UoCisgICAgaW50IHN0YXJ0LCBpbnQgbnVtLCBFbGVtZW50KiBlbGVtZW50cykgeworICBHT09HTEVfRENIRUNLX0dFKHN0YXJ0LCAwKTsKKyAgR09PR0xFX0RDSEVDS19HRShudW0sIDApOworICBHT09HTEVfRENIRUNLX0xFKHN0YXJ0ICsgbnVtLCB0aGlzLT5jdXJyZW50X3NpemVfKTsKKworICAvLyBTYXZlIHRoZSB2YWx1ZXMgb2YgdGhlIHJlbW92ZWQgZWxlbWVudHMgaWYgcmVxdWVzdGVkLgorICBpZiAoZWxlbWVudHMgIT0gTlVMTCkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpCisgICAgICBlbGVtZW50c1tpXSA9IHRoaXMtPkdldChpICsgc3RhcnQpOworICB9CisKKyAgLy8gU2xpZGUgcmVtYWluaW5nIGVsZW1lbnRzIGRvd24gdG8gZmlsbCB0aGUgZ2FwLgorICBpZiAobnVtID4gMCkgeworICAgIGZvciAoaW50IGkgPSBzdGFydCArIG51bTsgaSA8IHRoaXMtPmN1cnJlbnRfc2l6ZV87ICsraSkKKyAgICAgIHRoaXMtPlNldChpIC0gbnVtLCB0aGlzLT5HZXQoaSkpOworICAgIHRoaXMtPlRydW5jYXRlKHRoaXMtPmN1cnJlbnRfc2l6ZV8gLSBudW0pOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Q2xlYXIoKSB7CisgIGN1cnJlbnRfc2l6ZV8gPSAwOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46Ok1lcmdlRnJvbShjb25zdCBSZXBlYXRlZEZpZWxkJiBvdGhlcikgeworICBHT09HTEVfQ0hFQ0tfTkUoJm90aGVyLCB0aGlzKTsKKyAgaWYgKG90aGVyLmN1cnJlbnRfc2l6ZV8gIT0gMCkgeworICAgIFJlc2VydmUoY3VycmVudF9zaXplXyArIG90aGVyLmN1cnJlbnRfc2l6ZV8pOworICAgIENvcHlBcnJheShyZXBfLT5lbGVtZW50cyArIGN1cnJlbnRfc2l6ZV8sCisgICAgICAgICAgICAgIG90aGVyLnJlcF8tPmVsZW1lbnRzLCBvdGhlci5jdXJyZW50X3NpemVfKTsKKyAgICBjdXJyZW50X3NpemVfICs9IG90aGVyLmN1cnJlbnRfc2l6ZV87CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpDb3B5RnJvbShjb25zdCBSZXBlYXRlZEZpZWxkJiBvdGhlcikgeworICBpZiAoJm90aGVyID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKG90aGVyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6aXRlcmF0b3IgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6ZXJhc2UoCisgICAgY29uc3RfaXRlcmF0b3IgcG9zaXRpb24pIHsKKyAgcmV0dXJuIGVyYXNlKHBvc2l0aW9uLCBwb3NpdGlvbiArIDEpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjppdGVyYXRvciBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjplcmFzZSgKKyAgICBjb25zdF9pdGVyYXRvciBmaXJzdCwgY29uc3RfaXRlcmF0b3IgbGFzdCkgeworICBzaXplX3R5cGUgZmlyc3Rfb2Zmc2V0ID0gZmlyc3QgLSBjYmVnaW4oKTsKKyAgVHJ1bmNhdGUoc3RkOjpjb3B5KGxhc3QsIGNlbmQoKSwgYmVnaW4oKSArIGZpcnN0X29mZnNldCkgLSBjYmVnaW4oKSk7CisgIHJldHVybiBiZWdpbigpICsgZmlyc3Rfb2Zmc2V0OworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjptdXRhYmxlX2RhdGEoKSB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgOiBOVUxMOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBjb25zdCBFbGVtZW50KiBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpkYXRhKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/IHJlcF8tPmVsZW1lbnRzIDogTlVMTDsKK30KKworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkludGVybmFsU3dhcChSZXBlYXRlZEZpZWxkKiBvdGhlcikgeworICBzdGQ6OnN3YXAocmVwXywgb3RoZXItPnJlcF8pOworICBzdGQ6OnN3YXAoY3VycmVudF9zaXplXywgb3RoZXItPmN1cnJlbnRfc2l6ZV8pOworICBzdGQ6OnN3YXAodG90YWxfc2l6ZV8sIG90aGVyLT50b3RhbF9zaXplXyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50Pgordm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpTd2FwKFJlcGVhdGVkRmllbGQqIG90aGVyKSB7CisgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm47CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09ICBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgUmVwZWF0ZWRGaWVsZDxFbGVtZW50PiB0ZW1wKG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+VW5zYWZlQXJlbmFTd2FwKCZ0ZW1wKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK3ZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6VW5zYWZlQXJlbmFTd2FwKFJlcGVhdGVkRmllbGQqIG90aGVyKSB7CisgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm47CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50Pgordm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpTd2FwRWxlbWVudHMoaW50IGluZGV4MSwgaW50IGluZGV4MikgeworICB1c2luZyBzdGQ6OnN3YXA7ICAvLyBlbmFibGUgQURMIHdpdGggZmFsbGJhY2sKKyAgc3dhcChyZXBfLT5lbGVtZW50c1tpbmRleDFdLCByZXBfLT5lbGVtZW50c1tpbmRleDJdKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6aXRlcmF0b3IKK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46OmJlZ2luKCkgeworICByZXR1cm4gcmVwXyA/IHJlcF8tPmVsZW1lbnRzIDogTlVMTDsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpiZWdpbigpIGNvbnN0IHsKKyAgcmV0dXJuIHJlcF8gPyByZXBfLT5lbGVtZW50cyA6IE5VTEw7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+Ojpjb25zdF9pdGVyYXRvcgorUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Y2JlZ2luKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/IHJlcF8tPmVsZW1lbnRzIDogTlVMTDsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46Oml0ZXJhdG9yCitSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjplbmQoKSB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgKyBjdXJyZW50X3NpemVfIDogTlVMTDsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjplbmQoKSBjb25zdCB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgKyBjdXJyZW50X3NpemVfIDogTlVMTDsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpjZW5kKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/IHJlcF8tPmVsZW1lbnRzICsgY3VycmVudF9zaXplXyA6IE5VTEw7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGludCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/CisgICAgICAodG90YWxfc2l6ZV8gKiBzaXplb2YoRWxlbWVudCkgKyBrUmVwSGVhZGVyU2l6ZSkgOiAwOworfQorCisvLyBBdm9pZCBpbmxpbmluZyBvZiBSZXNlcnZlKCk6IG5ldywgY29weSwgYW5kIGRlbGV0ZVtdIGxlYWQgdG8gYSBzaWduaWZpY2FudAorLy8gYW1vdW50IG9mIGNvZGUgYmxvYXQuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK3ZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6UmVzZXJ2ZShpbnQgbmV3X3NpemUpIHsKKyAgaWYgKHRvdGFsX3NpemVfID49IG5ld19zaXplKSByZXR1cm47CisgIFJlcCogb2xkX3JlcCA9IHJlcF87CisgIEFyZW5hKiBhcmVuYSA9IEdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIG5ld19zaXplID0gbWF4KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjprTWluUmVwZWF0ZWRGaWVsZEFsbG9jYXRpb25TaXplLAorICAgICAgICAgICAgICAgICBtYXgodG90YWxfc2l6ZV8gKiAyLCBuZXdfc2l6ZSkpOworICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgIHJlcF8gPSByZWludGVycHJldF9jYXN0PFJlcCo+KAorICAgICAgICBuZXcgY2hhcltrUmVwSGVhZGVyU2l6ZSArIHNpemVvZihFbGVtZW50KSpuZXdfc2l6ZV0pOworICB9IGVsc2UgeworICAgIHJlcF8gPSByZWludGVycHJldF9jYXN0PFJlcCo+KAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlQXJyYXk8Y2hhcj4oYXJlbmEsCisgICAgICAgICAgICAgICAga1JlcEhlYWRlclNpemUgKyBzaXplb2YoRWxlbWVudCkqbmV3X3NpemUpKTsKKyAgfQorICByZXBfLT5hcmVuYSA9IGFyZW5hOworICB0b3RhbF9zaXplXyA9IG5ld19zaXplOworICAvLyBJbnZva2UgcGxhY2VtZW50LW5ldyBvbiBuZXdseSBhbGxvY2F0ZWQgZWxlbWVudHMuIFdlIHNob3VsZG4ndCBoYXZlIHRvIGRvCisgIC8vIHRoaXMsIHNpbmNlIEVsZW1lbnQgaXMgc3VwcG9zZWQgdG8gYmUgUE9ELCBidXQgYSBwcmV2aW91cyB2ZXJzaW9uIG9mIHRoaXMKKyAgLy8gY29kZSBhbGxvY2F0ZWQgc3RvcmFnZSB3aXRoICJuZXcgRWxlbWVudFtzaXplXSIgYW5kIHNvbWUgY29kZSB1c2VzCisgIC8vIFJlcGVhdGVkRmllbGQgd2l0aCBub24tUE9EIHR5cGVzLCByZWx5aW5nIG9uIGNvbnN0cnVjdG9yIGludm9jYXRpb24uIElmCisgIC8vIEVsZW1lbnQgaGFzIGEgdHJpdmlhbCBjb25zdHJ1Y3RvciAoZS5nLiwgaW50MzIpLCBnY2MgKHRlc3RlZCB3aXRoIC1PMikKKyAgLy8gY29tcGxldGVseSByZW1vdmVzIHRoaXMgbG9vcCBiZWNhdXNlIHRoZSBsb29wIGJvZHkgaXMgZW1wdHksIHNvIHRoaXMgaGFzIG5vCisgIC8vIGVmZmVjdCB1bmxlc3MgaXRzIHNpZGUtZWZmZWN0cyBhcmUgcmVxdWlyZWQgZm9yIGNvcnJlY3RuZXNzLgorICAvLyBOb3RlIHRoYXQgd2UgZG8gdGhpcyBiZWZvcmUgTW92ZUFycmF5KCkgYmVsb3cgYmVjYXVzZSBFbGVtZW50J3MgY29weQorICAvLyBhc3NpZ25tZW50IGltcGxlbWVudGF0aW9uIHdpbGwgd2FudCBhbiBpbml0aWFsaXplZCBpbnN0YW5jZSBmaXJzdC4KKyAgRWxlbWVudCogZSA9ICZyZXBfLT5lbGVtZW50c1swXTsKKyAgRWxlbWVudCogbGltaXQgPSAmcmVwXy0+ZWxlbWVudHNbdG90YWxfc2l6ZV9dOworICBmb3IgKDsgZSA8IGxpbWl0OyBlKyspIHsKKyAgICBuZXcgKGUpIEVsZW1lbnQoKTsKKyAgfQorICBpZiAoY3VycmVudF9zaXplXyA+IDApIHsKKyAgICBNb3ZlQXJyYXkocmVwXy0+ZWxlbWVudHMsIG9sZF9yZXAtPmVsZW1lbnRzLCBjdXJyZW50X3NpemVfKTsKKyAgfQorICAvLyBMaWtld2lzZSwgd2UgbmVlZCB0byBpbnZva2UgZGVzdHJ1Y3RvcnMgb24gdGhlIG9sZCBhcnJheS4gSWYgRWxlbWVudCBoYXMgbm8KKyAgLy8gZGVzdHJ1Y3RvciwgdGhpcyBsb29wIHdpbGwgZGlzYXBwZWFyLgorICBlID0gJm9sZF9yZXAtPmVsZW1lbnRzWzBdOworICBsaW1pdCA9ICZvbGRfcmVwLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXTsKKyAgZm9yICg7IGUgPCBsaW1pdDsgZSsrKSB7CisgICAgZS0+RWxlbWVudDo6fkVsZW1lbnQoKTsKKyAgfQorICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgIGRlbGV0ZVtdIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KG9sZF9yZXApOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6VHJ1bmNhdGUoaW50IG5ld19zaXplKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTEUobmV3X3NpemUsIGN1cnJlbnRfc2l6ZV8pOworICBpZiAoY3VycmVudF9zaXplXyA+IDApIHsKKyAgICBjdXJyZW50X3NpemVfID0gbmV3X3NpemU7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpNb3ZlQXJyYXkoCisgIEVsZW1lbnQqIHRvLCBFbGVtZW50KiBmcm9tLCBpbnQgYXJyYXlfc2l6ZSkgeworICBDb3B5QXJyYXkodG8sIGZyb20sIGFycmF5X3NpemUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkNvcHlBcnJheSgKKyAgRWxlbWVudCogdG8sIGNvbnN0IEVsZW1lbnQqIGZyb20sIGludCBhcnJheV9zaXplKSB7CisgIGludGVybmFsOjpFbGVtZW50Q29waWVyPEVsZW1lbnQ+KCkodG8sIGZyb20sIGFycmF5X3NpemUpOworfQorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudCwgYm9vbCBIYXNUcml2aWFsQ29weT4KK3ZvaWQgRWxlbWVudENvcGllcjxFbGVtZW50LCBIYXNUcml2aWFsQ29weT46Om9wZXJhdG9yKCkoCisgIEVsZW1lbnQqIHRvLCBjb25zdCBFbGVtZW50KiBmcm9tLCBpbnQgYXJyYXlfc2l6ZSkgeworICBzdGQ6OmNvcHkoZnJvbSwgZnJvbSArIGFycmF5X3NpemUsIHRvKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitzdHJ1Y3QgRWxlbWVudENvcGllcjxFbGVtZW50LCB0cnVlPiB7CisgIHZvaWQgb3BlcmF0b3IoKShFbGVtZW50KiB0bywgY29uc3QgRWxlbWVudCogZnJvbSwgaW50IGFycmF5X3NpemUpIHsKKyAgICBtZW1jcHkodG8sIGZyb20sIGFycmF5X3NpemUgKiBzaXplb2YoRWxlbWVudCkpOworICB9Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVwZWF0ZWRQdHJGaWVsZEJhc2UoKQorICA6IGFyZW5hXyhOVUxMKSwKKyAgICBjdXJyZW50X3NpemVfKDApLAorICAgIHRvdGFsX3NpemVfKDApLAorICAgIHJlcF8oTlVMTCkgeworfQorCitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlJlcGVhdGVkUHRyRmllbGRCYXNlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKQorICA6IGFyZW5hXyhhcmVuYSksCisgICAgY3VycmVudF9zaXplXygwKSwKKyAgICB0b3RhbF9zaXplXygwKSwKKyAgICByZXBfKE5VTEwpIHsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6RGVzdHJveSgpIHsKKyAgaWYgKHJlcF8gIT0gTlVMTCkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwXy0+YWxsb2NhdGVkX3NpemU7IGkrKykgeworICAgICAgVHlwZUhhbmRsZXI6OkRlbGV0ZShjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tpXSksIGFyZW5hXyk7CisgICAgfQorICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgZGVsZXRlIFtdIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHJlcF8pOworICAgIH0KKyAgfQorICByZXBfID0gTlVMTDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlN3YXAoUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIG90aGVyKSB7CisgIGlmIChvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBHZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgSW50ZXJuYWxTd2FwKG90aGVyKTsKKyAgfSBlbHNlIHsKKyAgICBTd2FwRmFsbGJhY2s8VHlwZUhhbmRsZXI+KG90aGVyKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6U3dhcEZhbGxiYWNrKFJlcGVhdGVkUHRyRmllbGRCYXNlKiBvdGhlcikgeworICBHT09HTEVfRENIRUNLKG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpICE9IEdldEFyZW5hTm9WaXJ0dWFsKCkpOworCisgIC8vIENvcHkgc2VtYW50aWNzIGluIHRoaXMgY2FzZS4gV2UgdHJ5IHRvIGltcHJvdmUgZWZmaWNpZW5jeSBieSBwbGFjaW5nIHRoZQorICAvLyB0ZW1wb3Jhcnkgb24gfG90aGVyfCdzIGFyZW5hIHNvIHRoYXQgbWVzc2FnZXMgYXJlIGNvcGllZCBjcm9zcy1hcmVuYSBvbmx5CisgIC8vIG9uY2UsIG5vdCB0d2ljZS4KKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgdGVtcChvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIHRlbXAuTWVyZ2VGcm9tPFR5cGVIYW5kbGVyPigqdGhpcyk7CisgIHRoaXMtPkNsZWFyPFR5cGVIYW5kbGVyPigpOworICB0aGlzLT5NZXJnZUZyb208VHlwZUhhbmRsZXI+KCpvdGhlcik7CisgIG90aGVyLT5DbGVhcjxUeXBlSGFuZGxlcj4oKTsKKyAgb3RoZXItPkludGVybmFsU3dhcCgmdGVtcCk7CisgIHRlbXAuRGVzdHJveTxUeXBlSGFuZGxlcj4oKTsgIC8vIEZyZWVzIHJlcF8gaWYgYG90aGVyYCBoYWQgbm8gYXJlbmEuCit9CisKK2lubGluZSBib29sIFJlcGVhdGVkUHRyRmllbGRCYXNlOjplbXB0eSgpIGNvbnN0IHsKKyAgcmV0dXJuIGN1cnJlbnRfc2l6ZV8gPT0gMDsKK30KKworaW5saW5lIGludCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6c2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGN1cnJlbnRfc2l6ZV87Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSBjb25zdCB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSYKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpHZXQoaW50IGluZGV4KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0tfR0UoaW5kZXgsIDApOworICBHT09HTEVfRENIRUNLX0xUKGluZGV4LCBjdXJyZW50X3NpemVfKTsKKyAgcmV0dXJuICpjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tpbmRleF0pOworfQorCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpNdXRhYmxlKGludCBpbmRleCkgeworICBHT09HTEVfRENIRUNLX0dFKGluZGV4LCAwKTsKKyAgR09PR0xFX0RDSEVDS19MVChpbmRleCwgY3VycmVudF9zaXplXyk7CisgIHJldHVybiBjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tpbmRleF0pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6RGVsZXRlKGludCBpbmRleCkgeworICBHT09HTEVfRENIRUNLX0dFKGluZGV4LCAwKTsKKyAgR09PR0xFX0RDSEVDS19MVChpbmRleCwgY3VycmVudF9zaXplXyk7CisgIFR5cGVIYW5kbGVyOjpEZWxldGUoY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbaW5kZXhdKSwgYXJlbmFfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkKAorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBwcm90b3R5cGUpIHsKKyAgaWYgKHJlcF8gIT0gTlVMTCAmJiBjdXJyZW50X3NpemVfIDwgcmVwXy0+YWxsb2NhdGVkX3NpemUpIHsKKyAgICByZXR1cm4gY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplXysrXSk7CisgIH0KKyAgaWYgKCFyZXBfIHx8IHJlcF8tPmFsbG9jYXRlZF9zaXplID09IHRvdGFsX3NpemVfKSB7CisgICAgUmVzZXJ2ZSh0b3RhbF9zaXplXyArIDEpOworICB9CisgICsrcmVwXy0+YWxsb2NhdGVkX3NpemU7CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiByZXN1bHQgPQorICAgICAgVHlwZUhhbmRsZXI6Ok5ld0Zyb21Qcm90b3R5cGUocHJvdG90eXBlLCBhcmVuYV8pOworICByZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfKytdID0gcmVzdWx0OworICByZXR1cm4gcmVzdWx0OworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVtb3ZlTGFzdCgpIHsKKyAgR09PR0xFX0RDSEVDS19HVChjdXJyZW50X3NpemVfLCAwKTsKKyAgVHlwZUhhbmRsZXI6OkNsZWFyKGNhc3Q8VHlwZUhhbmRsZXI+KHJlcF8tPmVsZW1lbnRzWy0tY3VycmVudF9zaXplX10pKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2xlYXIoKSB7CisgIGNvbnN0IGludCBuID0gY3VycmVudF9zaXplXzsKKyAgR09PR0xFX0RDSEVDS19HRShuLCAwKTsKKyAgaWYgKG4gPiAwKSB7CisgICAgdm9pZCogY29uc3QqIGVsZW1lbnRzID0gcmF3X2RhdGEoKTsKKyAgICBpbnQgaSA9IDA7CisgICAgZG8geworICAgICAgVHlwZUhhbmRsZXI6OkNsZWFyKGNhc3Q8VHlwZUhhbmRsZXI+KGVsZW1lbnRzW2krK10pKTsKKyAgICB9IHdoaWxlIChpIDwgbik7CisgICAgY3VycmVudF9zaXplXyA9IDA7CisgIH0KK30KKworLy8gVG8gYXZvaWQgdW5uZWNlc3NhcnkgY29kZSBkdXBsaWNhdGlvbiBhbmQgcmVkdWNlIGJpbmFyeSBzaXplLCB3ZSB1c2UgYQorLy8gbGF5ZXJlZCBhcHByb2FjaCB0byBpbXBsZW1lbnRpbmcgTWVyZ2VGcm9tKCkuIFRoZSB0b3BsZXZlbCBtZXRob2QgaXMKKy8vIHRlbXBsYXRlZCwgc28gd2UgZ2V0IGEgc21hbGwgdGh1bmsgcGVyIGNvbmNyZXRlIG1lc3NhZ2UgdHlwZSBpbiB0aGUgYmluYXJ5LgorLy8gVGhpcyBjYWxscyBhIHNoYXJlZCBpbXBsZW1lbnRhdGlvbiB3aXRoIG1vc3Qgb2YgdGhlIGxvZ2ljLCBwYXNzaW5nIGEgZnVuY3Rpb24KKy8vIHBvaW50ZXIgdG8gYW5vdGhlciB0eXBlLXNwZWNpZmljIHBpZWNlIG9mIGNvZGUgdGhhdCBjYWxscyB0aGUgb2JqZWN0LWFsbG9jYXRlCisvLyBhbmQgbWVyZ2UgaGFuZGxlcnMuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TWVyZ2VGcm9tKGNvbnN0IFJlcGVhdGVkUHRyRmllbGRCYXNlJiBvdGhlcikgeworICBHT09HTEVfRENIRUNLX05FKCZvdGhlciwgdGhpcyk7CisgIGlmIChvdGhlci5jdXJyZW50X3NpemVfID09IDApIHJldHVybjsKKyAgTWVyZ2VGcm9tSW50ZXJuYWwoCisgICAgICBvdGhlciwgJlJlcGVhdGVkUHRyRmllbGRCYXNlOjpNZXJnZUZyb21Jbm5lckxvb3A8VHlwZUhhbmRsZXI+KTsKK30KKworaW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Ok1lcmdlRnJvbUludGVybmFsKAorICAgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGRCYXNlJiBvdGhlciwKKyAgICB2b2lkIChSZXBlYXRlZFB0ckZpZWxkQmFzZTo6KmlubmVyX2xvb3ApKHZvaWQqKiwgdm9pZCoqLCBpbnQsIGludCkpIHsKKyAgLy8gTm90ZTogd3JhcHBlciBoYXMgYWxyZWFkeSBndWFyYW50ZWVkIHRoYXQgb3RoZXIucmVwXyAhPSBOVUxMIGhlcmUuCisgIGludCBvdGhlcl9zaXplID0gb3RoZXIuY3VycmVudF9zaXplXzsKKyAgdm9pZCoqIG90aGVyX2VsZW1lbnRzID0gb3RoZXIucmVwXy0+ZWxlbWVudHM7CisgIHZvaWQqKiBuZXdfZWxlbWVudHMgPSBJbnRlcm5hbEV4dGVuZChvdGhlcl9zaXplKTsKKyAgaW50IGFsbG9jYXRlZF9lbGVtcyA9IHJlcF8tPmFsbG9jYXRlZF9zaXplIC0gY3VycmVudF9zaXplXzsKKyAgKHRoaXMtPippbm5lcl9sb29wKShuZXdfZWxlbWVudHMsIG90aGVyX2VsZW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgIG90aGVyX3NpemUsIGFsbG9jYXRlZF9lbGVtcyk7CisgIGN1cnJlbnRfc2l6ZV8gKz0gb3RoZXJfc2l6ZTsKKyAgaWYgKHJlcF8tPmFsbG9jYXRlZF9zaXplIDwgY3VycmVudF9zaXplXykgeworICAgIHJlcF8tPmFsbG9jYXRlZF9zaXplID0gY3VycmVudF9zaXplXzsKKyAgfQorfQorCisvLyBNZXJnZXMgb3RoZXJfZWxlbXMgdG8gb3VyX2VsZW1zLgordGVtcGxhdGU8dHlwZW5hbWUgVHlwZUhhbmRsZXI+Cit2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpNZXJnZUZyb21Jbm5lckxvb3AoCisgICAgdm9pZCoqIG91cl9lbGVtcywgdm9pZCoqIG90aGVyX2VsZW1zLCBpbnQgbGVuZ3RoLCBpbnQgYWxyZWFkeV9hbGxvY2F0ZWQpIHsKKyAgLy8gU3BsaXQgaW50byB0d28gbG9vcHMsIG92ZXIgcmFuZ2VzIFswLCBhbGxvY2F0ZWQpIGFuZCBbYWxsb2NhdGVkLCBsZW5ndGgpLAorICAvLyB0byBhdm9pZCBhIGJyYW5jaCB3aXRoaW4gdGhlIGxvb3AuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxyZWFkeV9hbGxvY2F0ZWQgJiYgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgLy8gQWxyZWFkeSBhbGxvY2F0ZWQ6IHVzZSBleGlzdGluZyBlbGVtZW50LgorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBvdGhlcl9lbGVtID0KKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDx0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSo+KG90aGVyX2VsZW1zW2ldKTsKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogbmV3X2VsZW0gPQorICAgICAgICByZWludGVycHJldF9jYXN0PHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKj4ob3VyX2VsZW1zW2ldKTsKKyAgICBUeXBlSGFuZGxlcjo6TWVyZ2UoKm90aGVyX2VsZW0sIG5ld19lbGVtKTsKKyAgfQorICBBcmVuYSogYXJlbmEgPSBHZXRBcmVuYU5vVmlydHVhbCgpOworICBmb3IgKGludCBpID0gYWxyZWFkeV9hbGxvY2F0ZWQ7IGkgPCBsZW5ndGg7IGkrKykgeworICAgIC8vIE5vdCBhbGxvY2F0ZWQ6IGFsbG9jIGEgbmV3IGVsZW1lbnQgZmlyc3QsIHRoZW4gbWVyZ2UgaXQuCisgICAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIG90aGVyX2VsZW0gPQorICAgICAgICByZWludGVycHJldF9jYXN0PHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKj4ob3RoZXJfZWxlbXNbaV0pOworICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBuZXdfZWxlbSA9CisgICAgICAgIFR5cGVIYW5kbGVyOjpOZXdGcm9tUHJvdG90eXBlKG90aGVyX2VsZW0sIGFyZW5hKTsKKyAgICBUeXBlSGFuZGxlcjo6TWVyZ2UoKm90aGVyX2VsZW0sIG5ld19lbGVtKTsKKyAgICBvdXJfZWxlbXNbaV0gPSBuZXdfZWxlbTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q29weUZyb20oY29uc3QgUmVwZWF0ZWRQdHJGaWVsZEJhc2UmIG90aGVyKSB7CisgIGlmICgmb3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2xlYXI8VHlwZUhhbmRsZXI+KCk7CisgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpNZXJnZUZyb208VHlwZUhhbmRsZXI+KG90aGVyKTsKK30KKworaW5saW5lIGludCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2FwYWNpdHkoKSBjb25zdCB7CisgIHJldHVybiB0b3RhbF9zaXplXzsKK30KKworaW5saW5lIHZvaWQqIGNvbnN0KiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6cmF3X2RhdGEoKSBjb25zdCB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgOiBOVUxMOworfQorCitpbmxpbmUgdm9pZCoqIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpyYXdfbXV0YWJsZV9kYXRhKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/IGNvbnN0X2Nhc3Q8dm9pZCoqPihyZXBfLT5lbGVtZW50cykgOiBOVUxMOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqKiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6bXV0YWJsZV9kYXRhKCkgeworICAvLyBUT0RPKGtlbnRvbik6ICBCcmVha3MgQysrIGFsaWFzaW5nIHJ1bGVzLiAgV2Ugc2hvdWxkIHByb2JhYmx5IHJlbW92ZSB0aGlzCisgIC8vICAgbWV0aG9kIGVudGlyZWx5LgorICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDx0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoqPihyYXdfbXV0YWJsZV9kYXRhKCkpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgY29uc3QgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIGNvbnN0KgorUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OmRhdGEoKSBjb25zdCB7CisgIC8vIFRPRE8oa2VudG9uKTogIEJyZWFrcyBDKysgYWxpYXNpbmcgcnVsZXMuICBXZSBzaG91bGQgcHJvYmFibHkgcmVtb3ZlIHRoaXMKKyAgLy8gICBtZXRob2QgZW50aXJlbHkuCisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBjb25zdCo+KHJhd19kYXRhKCkpOworfQorCitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6U3dhcEVsZW1lbnRzKGludCBpbmRleDEsIGludCBpbmRleDIpIHsKKyAgdXNpbmcgc3RkOjpzd2FwOyAgLy8gZW5hYmxlIEFETCB3aXRoIGZhbGxiYWNrCisgIHN3YXAocmVwXy0+ZWxlbWVudHNbaW5kZXgxXSwgcmVwXy0+ZWxlbWVudHNbaW5kZXgyXSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSBpbnQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdCB7CisgIGludCBhbGxvY2F0ZWRfYnl0ZXMgPSB0b3RhbF9zaXplXyAqIHNpemVvZih2b2lkKik7CisgIGlmIChyZXBfICE9IE5VTEwpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcF8tPmFsbG9jYXRlZF9zaXplOyArK2kpIHsKKyAgICAgIGFsbG9jYXRlZF9ieXRlcyArPSBUeXBlSGFuZGxlcjo6U3BhY2VVc2VkKAorICAgICAgICAgICpjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tpXSkpOworICAgIH0KKyAgICBhbGxvY2F0ZWRfYnl0ZXMgKz0ga1JlcEhlYWRlclNpemU7CisgIH0KKyAgcmV0dXJuIGFsbG9jYXRlZF9ieXRlczsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkRnJvbUNsZWFyZWQoKSB7CisgIGlmIChyZXBfICE9IE5VTEwgJiYgY3VycmVudF9zaXplXyA8IHJlcF8tPmFsbG9jYXRlZF9zaXplKSB7CisgICAgcmV0dXJuIGNhc3Q8VHlwZUhhbmRsZXI+KHJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV8rK10pOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKKy8vIEFkZEFsbG9jYXRlZCB2ZXJzaW9uIHRoYXQgaW1wbGVtZW50cyBhcmVuYS1zYWZlIGNvcHlpbmcgYmVoYXZpb3IuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+Cit2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpBZGRBbGxvY2F0ZWRJbnRlcm5hbCgKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUsCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSkgeworICBBcmVuYSogZWxlbWVudF9hcmVuYSA9IHJlaW50ZXJwcmV0X2Nhc3Q8QXJlbmEqPigKKyAgICAgIFR5cGVIYW5kbGVyOjpHZXRNYXliZUFyZW5hUG9pbnRlcih2YWx1ZSkpOworICBBcmVuYSogYXJlbmEgPSBHZXRBcmVuYU5vVmlydHVhbCgpOworICBpZiAoYXJlbmEgPT0gZWxlbWVudF9hcmVuYSAmJiByZXBfICYmCisgICAgICByZXBfLT5hbGxvY2F0ZWRfc2l6ZSA8IHRvdGFsX3NpemVfKSB7CisgICAgLy8gRmFzdCBwYXRoOiB1bmRlcmx5aW5nIGFyZW5hIHJlcHJlc2VudGF0aW9uICh0YWdnZWQgcG9pbnRlcikgaXMgZXF1YWwgdG8KKyAgICAvLyBvdXIgYXJlbmEgcG9pbnRlciwgYW5kIHdlIGNhbiBhZGQgdG8gYXJyYXkgd2l0aG91dCByZXNpemluZyBpdCAoYXQgbGVhc3QKKyAgICAvLyBvbmUgc2xvdCB0aGF0IGlzIG5vdCBhbGxvY2F0ZWQpLgorICAgIHZvaWQqKiBlbGVtcyA9IHJlcF8tPmVsZW1lbnRzOworICAgIGlmIChjdXJyZW50X3NpemVfIDwgcmVwXy0+YWxsb2NhdGVkX3NpemUpIHsKKyAgICAgIC8vIE1ha2Ugc3BhY2UgYXQgW2N1cnJlbnRdIGJ5IG1vdmluZyBmaXJzdCBhbGxvY2F0ZWQgZWxlbWVudCB0byBlbmQgb2YKKyAgICAgIC8vIGFsbG9jYXRlZCBsaXN0LgorICAgICAgZWxlbXNbcmVwXy0+YWxsb2NhdGVkX3NpemVdID0gZWxlbXNbY3VycmVudF9zaXplX107CisgICAgfQorICAgIGVsZW1zW2N1cnJlbnRfc2l6ZV9dID0gdmFsdWU7CisgICAgY3VycmVudF9zaXplXyA9IGN1cnJlbnRfc2l6ZV8gKyAxOworICAgIHJlcF8tPmFsbG9jYXRlZF9zaXplID0gcmVwXy0+YWxsb2NhdGVkX3NpemUgKyAxOworICAgIHJldHVybjsKKyAgfSBlbHNlIHsKKyAgICBBZGRBbGxvY2F0ZWRTbG93V2l0aENvcHk8VHlwZUhhbmRsZXI+KAorICAgICAgICB2YWx1ZSwgVHlwZUhhbmRsZXI6OkdldEFyZW5hKHZhbHVlKSwgYXJlbmEpOworICB9Cit9CisKKy8vIFNsb3dwYXRoIGhhbmRsZXMgYWxsIGNhc2VzLCBjb3B5aW5nIGlmIG5lY2Vzc2FyeS4KK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkQWxsb2NhdGVkU2xvd1dpdGhDb3B5KAorICAgIC8vIFBhc3MgdmFsdWVfYXJlbmEgYW5kIG15X2FyZW5hIHRvIGF2b2lkIGR1cGxpY2F0ZSB2aXJ0dWFsIGNhbGwgKHZhbHVlKSBvcgorICAgIC8vIGxvYWQgKG1pbmUpLgorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSwgQXJlbmEqIHZhbHVlX2FyZW5hLCBBcmVuYSogbXlfYXJlbmEpIHsKKyAgLy8gRW5zdXJlIHRoYXQgZWl0aGVyIHRoZSB2YWx1ZSBpcyBpbiB0aGUgc2FtZSBhcmVuYSwgb3IgaWYgbm90LCB3ZSBkbyB0aGUKKyAgLy8gYXBwcm9wcmlhdGUgdGhpbmc6IE93bigpIGl0IChpZiBpdCdzIG9uIGhlYXAgYW5kIHdlJ3JlIGluIGFuIGFyZW5hKSBvciBjb3B5CisgIC8vIGl0IHRvIG91ciBhcmVuYS9oZWFwIChvdGhlcndpc2UpLgorICBpZiAobXlfYXJlbmEgIT0gTlVMTCAmJiB2YWx1ZV9hcmVuYSA9PSBOVUxMKSB7CisgICAgbXlfYXJlbmEtPk93bih2YWx1ZSk7CisgIH0gZWxzZSBpZiAobXlfYXJlbmEgIT0gdmFsdWVfYXJlbmEpIHsKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogbmV3X3ZhbHVlID0KKyAgICAgICAgVHlwZUhhbmRsZXI6Ok5ld0Zyb21Qcm90b3R5cGUodmFsdWUsIG15X2FyZW5hKTsKKyAgICBUeXBlSGFuZGxlcjo6TWVyZ2UoKnZhbHVlLCBuZXdfdmFsdWUpOworICAgIFR5cGVIYW5kbGVyOjpEZWxldGUodmFsdWUsIHZhbHVlX2FyZW5hKTsKKyAgICB2YWx1ZSA9IG5ld192YWx1ZTsKKyAgfQorCisgIFVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkPFR5cGVIYW5kbGVyPih2YWx1ZSk7Cit9CisKKy8vIEFkZEFsbG9jYXRlZCB2ZXJzaW9uIHRoYXQgZG9lcyBub3QgaW1wbGVtZW50IGFyZW5hLXNhZmUgY29weWluZyBiZWhhdmlvci4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK3ZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkFkZEFsbG9jYXRlZEludGVybmFsKAorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSwKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSkgeworICBpZiAocmVwXyAmJiAgcmVwXy0+YWxsb2NhdGVkX3NpemUgPCB0b3RhbF9zaXplXykgeworICAgIC8vIEZhc3QgcGF0aDogdW5kZXJseWluZyBhcmVuYSByZXByZXNlbnRhdGlvbiAodGFnZ2VkIHBvaW50ZXIpIGlzIGVxdWFsIHRvCisgICAgLy8gb3VyIGFyZW5hIHBvaW50ZXIsIGFuZCB3ZSBjYW4gYWRkIHRvIGFycmF5IHdpdGhvdXQgcmVzaXppbmcgaXQgKGF0IGxlYXN0CisgICAgLy8gb25lIHNsb3QgdGhhdCBpcyBub3QgYWxsb2NhdGVkKS4KKyAgICB2b2lkKiogZWxlbXMgPSByZXBfLT5lbGVtZW50czsKKyAgICBpZiAoY3VycmVudF9zaXplXyA8IHJlcF8tPmFsbG9jYXRlZF9zaXplKSB7CisgICAgICAvLyBNYWtlIHNwYWNlIGF0IFtjdXJyZW50XSBieSBtb3ZpbmcgZmlyc3QgYWxsb2NhdGVkIGVsZW1lbnQgdG8gZW5kIG9mCisgICAgICAvLyBhbGxvY2F0ZWQgbGlzdC4KKyAgICAgIGVsZW1zW3JlcF8tPmFsbG9jYXRlZF9zaXplXSA9IGVsZW1zW2N1cnJlbnRfc2l6ZV9dOworICAgIH0KKyAgICBlbGVtc1tjdXJyZW50X3NpemVfXSA9IHZhbHVlOworICAgIGN1cnJlbnRfc2l6ZV8gPSBjdXJyZW50X3NpemVfICsgMTsKKyAgICArK3JlcF8tPmFsbG9jYXRlZF9zaXplOworICAgIHJldHVybjsKKyAgfSBlbHNlIHsKKyAgICBVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZDxUeXBlSGFuZGxlcj4odmFsdWUpOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK3ZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkKAorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSkgeworICAvLyBNYWtlIHJvb20gZm9yIHRoZSBuZXcgcG9pbnRlci4KKyAgaWYgKCFyZXBfIHx8IGN1cnJlbnRfc2l6ZV8gPT0gdG90YWxfc2l6ZV8pIHsKKyAgICAvLyBUaGUgYXJyYXkgaXMgY29tcGxldGVseSBmdWxsIHdpdGggbm8gY2xlYXJlZCBvYmplY3RzLCBzbyBncm93IGl0LgorICAgIFJlc2VydmUodG90YWxfc2l6ZV8gKyAxKTsKKyAgICArK3JlcF8tPmFsbG9jYXRlZF9zaXplOworICB9IGVsc2UgaWYgKHJlcF8tPmFsbG9jYXRlZF9zaXplID09IHRvdGFsX3NpemVfKSB7CisgICAgLy8gVGhlcmUgaXMgbm8gbW9yZSBzcGFjZSBpbiB0aGUgcG9pbnRlciBhcnJheSBiZWNhdXNlIGl0IGNvbnRhaW5zIHNvbWUKKyAgICAvLyBjbGVhcmVkIG9iamVjdHMgYXdhaXRpbmcgcmV1c2UuICBXZSBkb24ndCB3YW50IHRvIGdyb3cgdGhlIGFycmF5IGluIHRoaXMKKyAgICAvLyBjYXNlIGJlY2F1c2Ugb3RoZXJ3aXNlIGEgbG9vcCBjYWxsaW5nIEFkZEFsbG9jYXRlZCgpIGZvbGxvd2VkIGJ5IENsZWFyKCkKKyAgICAvLyB3b3VsZCBsZWFrIG1lbW9yeS4KKyAgICBUeXBlSGFuZGxlcjo6RGVsZXRlKAorICAgICAgICBjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXSksIGFyZW5hXyk7CisgIH0gZWxzZSBpZiAoY3VycmVudF9zaXplXyA8IHJlcF8tPmFsbG9jYXRlZF9zaXplKSB7CisgICAgLy8gV2UgaGF2ZSBzb21lIGNsZWFyZWQgb2JqZWN0cy4gIFdlIGRvbid0IGNhcmUgYWJvdXQgdGhlaXIgb3JkZXIsIHNvIHdlCisgICAgLy8gY2FuIGp1c3QgbW92ZSB0aGUgZmlyc3Qgb25lIHRvIHRoZSBlbmQgdG8gbWFrZSBzcGFjZS4KKyAgICByZXBfLT5lbGVtZW50c1tyZXBfLT5hbGxvY2F0ZWRfc2l6ZV0gPSByZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXTsKKyAgICArK3JlcF8tPmFsbG9jYXRlZF9zaXplOworICB9IGVsc2UgeworICAgIC8vIFRoZXJlIGFyZSBubyBjbGVhcmVkIG9iamVjdHMuCisgICAgKytyZXBfLT5hbGxvY2F0ZWRfc2l6ZTsKKyAgfQorCisgIHJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV8rK10gPSB2YWx1ZTsKK30KKworLy8gUmVsZWFzZUxhc3QoKSBmb3IgdHlwZXMgdGhhdCBpbXBsZW1lbnQgbWVyZ2UvY29weSBiZWhhdmlvci4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpSZWxlYXNlTGFzdEludGVybmFsKGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpIHsKKyAgLy8gRmlyc3QsIHJlbGVhc2UgYW4gZWxlbWVudC4KKyAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHJlc3VsdCA9IFVuc2FmZUFyZW5hUmVsZWFzZUxhc3Q8VHlwZUhhbmRsZXI+KCk7CisgIC8vIE5vdyBwZXJmb3JtIGEgY29weSBpZiB3ZSdyZSBvbiBhbiBhcmVuYS4KKyAgQXJlbmEqIGFyZW5hID0gR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICByZXR1cm4gcmVzdWx0OworICB9IGVsc2UgeworICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBuZXdfcmVzdWx0ID0KKyAgICAgICAgVHlwZUhhbmRsZXI6Ok5ld0Zyb21Qcm90b3R5cGUocmVzdWx0LCBOVUxMKTsKKyAgICBUeXBlSGFuZGxlcjo6TWVyZ2UoKnJlc3VsdCwgbmV3X3Jlc3VsdCk7CisgICAgcmV0dXJuIG5ld19yZXN1bHQ7CisgIH0KK30KKworLy8gUmVsZWFzZUxhc3QoKSBmb3IgdHlwZXMgdGhhdCAqZG8gbm90KiBpbXBsZW1lbnQgbWVyZ2UvY29weSBiZWhhdmlvciAtLSB0aGlzCisvLyBpcyB0aGUgc2FtZSBhcyBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCkuIE5vdGUgdGhhdCB3ZSBHT09HTEVfRENIRUNLLWZhaWwgaWYgd2UncmUgb24KKy8vIGFuIGFyZW5hLCBzaW5jZSB0aGUgdXNlciByZWFsbHkgc2hvdWxkIGltcGxlbWVudCB0aGUgY29weSBvcGVyYXRpb24gaW4gdGhpcworLy8gY2FzZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpSZWxlYXNlTGFzdEludGVybmFsKGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKSB7CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMKQorICAgICAgPDwgIlJlbGVhc2VMYXN0KCkgY2FsbGVkIG9uIGEgUmVwZWF0ZWRQdHJGaWVsZCB0aGF0IGlzIG9uIGFuIGFyZW5hLCAiCisgICAgICA8PCAid2l0aCBhIHR5cGUgdGhhdCBkb2VzIG5vdCBpbXBsZW1lbnQgTWVyZ2VGcm9tLiBUaGlzIGlzIHVuc2FmZTsgIgorICAgICAgPDwgInBsZWFzZSBpbXBsZW1lbnQgTWVyZ2VGcm9tIGZvciB5b3VyIHR5cGUuIjsKKyAgcmV0dXJuIFVuc2FmZUFyZW5hUmVsZWFzZUxhc3Q8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlVuc2FmZUFyZW5hUmVsZWFzZUxhc3QoKSB7CisgIEdPT0dMRV9EQ0hFQ0tfR1QoY3VycmVudF9zaXplXywgMCk7CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiByZXN1bHQgPQorICAgICAgY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbLS1jdXJyZW50X3NpemVfXSk7CisgIC0tcmVwXy0+YWxsb2NhdGVkX3NpemU7CisgIGlmIChjdXJyZW50X3NpemVfIDwgcmVwXy0+YWxsb2NhdGVkX3NpemUpIHsKKyAgICAvLyBUaGVyZSBhcmUgY2xlYXJlZCBlbGVtZW50cyBvbiB0aGUgZW5kOyByZXBsYWNlIHRoZSByZW1vdmVkIGVsZW1lbnQKKyAgICAvLyB3aXRoIHRoZSBsYXN0IGFsbG9jYXRlZCBlbGVtZW50LgorICAgIHJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV9dID0gcmVwXy0+ZWxlbWVudHNbcmVwXy0+YWxsb2NhdGVkX3NpemVdOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBpbnQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNsZWFyZWRDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHJlcF8gPyAocmVwXy0+YWxsb2NhdGVkX3NpemUgLSBjdXJyZW50X3NpemVfKSA6IDA7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpBZGRDbGVhcmVkKAorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCkKKyAgICAgIDw8ICJBZGRDbGVhcmVkKCkgY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlcGVhdGVkUHRyRmllbGQgbm90IG9uIGFuIGFyZW5hLiI7CisgIEdPT0dMRV9EQ0hFQ0soVHlwZUhhbmRsZXI6OkdldEFyZW5hKHZhbHVlKSA9PSBOVUxMKQorICAgICAgPDwgIkFkZENsZWFyZWQoKSBjYW4gb25seSBhY2NlcHQgdmFsdWVzIG5vdCBvbiBhbiBhcmVuYS4iOworICBpZiAoIXJlcF8gfHwgcmVwXy0+YWxsb2NhdGVkX3NpemUgPT0gdG90YWxfc2l6ZV8pIHsKKyAgICBSZXNlcnZlKHRvdGFsX3NpemVfICsgMSk7CisgIH0KKyAgcmVwXy0+ZWxlbWVudHNbcmVwXy0+YWxsb2NhdGVkX3NpemUrK10gPSB2YWx1ZTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVsZWFzZUNsZWFyZWQoKSB7CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMKQorICAgICAgPDwgIlJlbGVhc2VDbGVhcmVkKCkgY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlcGVhdGVkUHRyRmllbGQgbm90IG9uICIKKyAgICAgIDw8ICJhbiBhcmVuYS4iOworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCk7CisgIEdPT0dMRV9EQ0hFQ0socmVwXyAhPSBOVUxMKTsKKyAgR09PR0xFX0RDSEVDS19HVChyZXBfLT5hbGxvY2F0ZWRfc2l6ZSwgY3VycmVudF9zaXplXyk7CisgIHJldHVybiBjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1stLXJlcF8tPmFsbG9jYXRlZF9zaXplXSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgorY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6VHlwZUhhbmRsZXIKKyAgICA6IHB1YmxpYyBpbnRlcm5hbDo6R2VuZXJpY1R5cGVIYW5kbGVyPEVsZW1lbnQ+IHsKK307CisKK3RlbXBsYXRlIDw+CitjbGFzcyBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OlR5cGVIYW5kbGVyCisgICAgOiBwdWJsaWMgaW50ZXJuYWw6OlN0cmluZ1R5cGVIYW5kbGVyIHsKK307CisKKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRQdHJGaWVsZCgpCisgIDogUmVwZWF0ZWRQdHJGaWVsZEJhc2UoKSB7fQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpSZXBlYXRlZFB0ckZpZWxkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSA6CisgIFJlcGVhdGVkUHRyRmllbGRCYXNlKGFyZW5hKSB7fQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpSZXBlYXRlZFB0ckZpZWxkKAorICAgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQmIG90aGVyKQorICA6IFJlcGVhdGVkUHRyRmllbGRCYXNlKCkgeworICBDb3B5RnJvbShvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgordGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICBJdGVyIGJlZ2luLCBjb25zdCBJdGVyJiBlbmQpIHsKKyAgaW50IHJlc2VydmUgPSBpbnRlcm5hbDo6Q2FsY3VsYXRlUmVzZXJ2ZShiZWdpbiwgZW5kKTsKKyAgaWYgKHJlc2VydmUgIT0gLTEpIHsKKyAgICBSZXNlcnZlKHJlc2VydmUpOworICB9CisgIGZvciAoOyBiZWdpbiAhPSBlbmQ7ICsrYmVnaW4pIHsKKyAgICAqQWRkKCkgPSAqYmVnaW47CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojp+UmVwZWF0ZWRQdHJGaWVsZCgpIHsKKyAgRGVzdHJveTxUeXBlSGFuZGxlcj4oKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50PiYgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6b3BlcmF0b3I9KAorICAgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQmIG90aGVyKSB7CisgIGlmICh0aGlzICE9ICZvdGhlcikKKyAgICBDb3B5RnJvbShvdGhlcik7CisgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgYm9vbCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjplbXB0eSgpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjplbXB0eSgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBpbnQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6c2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpzaXplKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGNvbnN0IEVsZW1lbnQmIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkdldChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpHZXQ8VHlwZUhhbmRsZXI+KGluZGV4KTsKK30KKworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpNdXRhYmxlKGludCBpbmRleCkgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Ok11dGFibGU8VHlwZUhhbmRsZXI+KGluZGV4KTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgRWxlbWVudCogUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6QWRkKCkgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkFkZDxUeXBlSGFuZGxlcj4oKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpSZW1vdmVMYXN0KCkgeworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVtb3ZlTGFzdDxUeXBlSGFuZGxlcj4oKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpEZWxldGVTdWJyYW5nZShpbnQgc3RhcnQsIGludCBudW0pIHsKKyAgR09PR0xFX0RDSEVDS19HRShzdGFydCwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobnVtLCAwKTsKKyAgR09PR0xFX0RDSEVDS19MRShzdGFydCArIG51bSwgc2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07ICsraSkgeworICAgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpEZWxldGU8VHlwZUhhbmRsZXI+KHN0YXJ0ICsgaSk7CisgIH0KKyAgRXh0cmFjdFN1YnJhbmdlKHN0YXJ0LCBudW0sIE5VTEwpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkV4dHJhY3RTdWJyYW5nZSgKKyAgICBpbnQgc3RhcnQsIGludCBudW0sIEVsZW1lbnQqKiBlbGVtZW50cykgeworICB0eXBlbmFtZSBpbnRlcm5hbDo6VHlwZUltcGxlbWVudHNNZXJnZUJlaGF2aW9yPAorICAgICAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGU+Ojp0eXBlIHQ7CisgIEV4dHJhY3RTdWJyYW5nZUludGVybmFsKHN0YXJ0LCBudW0sIGVsZW1lbnRzLCB0KTsKK30KKworLy8gRXh0cmFjdFN1YnJhbmdlKCkgaW1wbGVtZW50YXRpb24gZm9yIHR5cGVzIHRoYXQgaW1wbGVtZW50IG1lcmdlL2NvcHkKKy8vIGJlaGF2aW9yLgordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpFeHRyYWN0U3VicmFuZ2VJbnRlcm5hbCgKKyAgICBpbnQgc3RhcnQsIGludCBudW0sIEVsZW1lbnQqKiBlbGVtZW50cywgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSkgeworICBHT09HTEVfRENIRUNLX0dFKHN0YXJ0LCAwKTsKKyAgR09PR0xFX0RDSEVDS19HRShudW0sIDApOworICBHT09HTEVfRENIRUNLX0xFKHN0YXJ0ICsgbnVtLCBzaXplKCkpOworCisgIGlmIChudW0gPiAwKSB7CisgICAgLy8gU2F2ZSB0aGUgdmFsdWVzIG9mIHRoZSByZW1vdmVkIGVsZW1lbnRzIGlmIHJlcXVlc3RlZC4KKyAgICBpZiAoZWxlbWVudHMgIT0gTlVMTCkgeworICAgICAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkgeworICAgICAgICAvLyBJZiB3ZSdyZSBvbiBhbiBhcmVuYSwgd2UgcGVyZm9ybSBhIGNvcHkgZm9yIGVhY2ggZWxlbWVudCBzbyB0aGF0IHRoZQorICAgICAgICAvLyByZXR1cm5lZCBlbGVtZW50cyBhcmUgaGVhcC1hbGxvY2F0ZWQuCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpIHsKKyAgICAgICAgICBFbGVtZW50KiBlbGVtZW50ID0gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OgorICAgICAgICAgICAgICBNdXRhYmxlPFR5cGVIYW5kbGVyPihpICsgc3RhcnQpOworICAgICAgICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBuZXdfdmFsdWUgPQorICAgICAgICAgICAgICBUeXBlSGFuZGxlcjo6TmV3RnJvbVByb3RvdHlwZShlbGVtZW50LCBOVUxMKTsKKyAgICAgICAgICBUeXBlSGFuZGxlcjo6TWVyZ2UoKmVsZW1lbnQsIG5ld192YWx1ZSk7CisgICAgICAgICAgZWxlbWVudHNbaV0gPSBuZXdfdmFsdWU7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpIHsKKyAgICAgICAgICBlbGVtZW50c1tpXSA9IFJlcGVhdGVkUHRyRmllbGRCYXNlOjpNdXRhYmxlPFR5cGVIYW5kbGVyPihpICsgc3RhcnQpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIENsb3NlR2FwKHN0YXJ0LCBudW0pOworICB9Cit9CisKKy8vIEV4dHJhY3RTdWJyYW5nZSgpIGltcGxlbWVudGF0aW9uIGZvciB0eXBlcyB0aGF0IGRvIG5vdCBpbXBsZW1lbnQgbWVyZ2UvY29weQorLy8gYmVoYXZpb3IuCit0ZW1wbGF0ZTx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6RXh0cmFjdFN1YnJhbmdlSW50ZXJuYWwoCisgICAgaW50IHN0YXJ0LCBpbnQgbnVtLCBFbGVtZW50KiogZWxlbWVudHMsIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKSB7CisgIC8vIFRoaXMgY2FzZSBpcyBpZGVudGljYWwgdG8gVW5zYWZlQXJlbmFFeHRyYWN0U3VicmFuZ2UoKS4gSG93ZXZlciwgc2luY2UKKyAgLy8gRXh0cmFjdFN1YnJhbmdlKCkgbXVzdCByZXR1cm4gaGVhcC1hbGxvY2F0ZWQgb2JqZWN0cyBieSBjb250cmFjdCwgYW5kIHdlCisgIC8vIGNhbm5vdCBmdWxmaWxsIHRoaXMgY29udHJhY3QgaWYgd2UgYXJlIGFuIG9uIGFyZW5hLCB3ZSBtdXN0IEdPT0dMRV9EQ0hFQ0soKSB0aGF0CisgIC8vIHdlIGFyZSBub3Qgb24gYW4gYXJlbmEuCisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMKQorICAgICAgPDwgIkV4dHJhY3RTdWJyYW5nZSgpIHdoZW4gYXJlbmEgaXMgbm9uLU5VTEwgaXMgb25seSBzdXBwb3J0ZWQgd2hlbiAiCisgICAgICA8PCAidGhlIEVsZW1lbnQgdHlwZSBzdXBwbGllcyBhIE1lcmdlRnJvbSgpIG9wZXJhdGlvbiB0byBtYWtlIGNvcGllcy4iOworICBVbnNhZmVBcmVuYUV4dHJhY3RTdWJyYW5nZShzdGFydCwgbnVtLCBlbGVtZW50cyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6VW5zYWZlQXJlbmFFeHRyYWN0U3VicmFuZ2UoCisgICAgaW50IHN0YXJ0LCBpbnQgbnVtLCBFbGVtZW50KiogZWxlbWVudHMpIHsKKyAgR09PR0xFX0RDSEVDS19HRShzdGFydCwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobnVtLCAwKTsKKyAgR09PR0xFX0RDSEVDS19MRShzdGFydCArIG51bSwgc2l6ZSgpKTsKKworICBpZiAobnVtID4gMCkgeworICAgIC8vIFNhdmUgdGhlIHZhbHVlcyBvZiB0aGUgcmVtb3ZlZCBlbGVtZW50cyBpZiByZXF1ZXN0ZWQuCisgICAgaWYgKGVsZW1lbnRzICE9IE5VTEwpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpIHsKKyAgICAgICAgZWxlbWVudHNbaV0gPSBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TXV0YWJsZTxUeXBlSGFuZGxlcj4oaSArIHN0YXJ0KTsKKyAgICAgIH0KKyAgICB9CisgICAgQ2xvc2VHYXAoc3RhcnQsIG51bSk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpDbGVhcigpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNsZWFyPFR5cGVIYW5kbGVyPigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Ok1lcmdlRnJvbSgKKyAgICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkJiBvdGhlcikgeworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TWVyZ2VGcm9tPFR5cGVIYW5kbGVyPihvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Q29weUZyb20oCisgICAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZCYgb3RoZXIpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNvcHlGcm9tPFR5cGVIYW5kbGVyPihvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Oml0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjplcmFzZShjb25zdF9pdGVyYXRvciBwb3NpdGlvbikgeworICByZXR1cm4gZXJhc2UocG9zaXRpb24sIHBvc2l0aW9uICsgMSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Oml0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjplcmFzZShjb25zdF9pdGVyYXRvciBmaXJzdCwgY29uc3RfaXRlcmF0b3IgbGFzdCkgeworICBzaXplX3R5cGUgcG9zX29mZnNldCA9IHN0ZDo6ZGlzdGFuY2UoY2JlZ2luKCksIGZpcnN0KTsKKyAgc2l6ZV90eXBlIGxhc3Rfb2Zmc2V0ID0gc3RkOjpkaXN0YW5jZShjYmVnaW4oKSwgbGFzdCk7CisgIERlbGV0ZVN1YnJhbmdlKHBvc19vZmZzZXQsIGxhc3Rfb2Zmc2V0IC0gcG9zX29mZnNldCk7CisgIHJldHVybiBiZWdpbigpICsgcG9zX29mZnNldDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgRWxlbWVudCoqIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Om11dGFibGVfZGF0YSgpIHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjptdXRhYmxlX2RhdGE8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGNvbnN0IEVsZW1lbnQqIGNvbnN0KiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpkYXRhKCkgY29uc3QgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OmRhdGE8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6U3dhcChSZXBlYXRlZFB0ckZpZWxkKiBvdGhlcikgeworICBpZiAodGhpcyA9PSBvdGhlcikKKyAgICByZXR1cm47CisgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpTd2FwPFR5cGVIYW5kbGVyPihvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6VW5zYWZlQXJlbmFTd2FwKAorICAgIFJlcGVhdGVkUHRyRmllbGQqIG90aGVyKSB7CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIGlmICh0aGlzID09IG90aGVyKQorICAgICAgcmV0dXJuOworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6SW50ZXJuYWxTd2FwKG90aGVyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpTd2FwRWxlbWVudHMoaW50IGluZGV4MSwgaW50IGluZGV4MikgeworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgQXJlbmEqIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkdldEFyZW5hTm9WaXJ0dWFsKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGludCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGY8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6QWRkQWxsb2NhdGVkKEVsZW1lbnQqIHZhbHVlKSB7CisgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpBZGRBbGxvY2F0ZWQ8VHlwZUhhbmRsZXI+KHZhbHVlKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZChFbGVtZW50KiB2YWx1ZSkgeworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6VW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQ8VHlwZUhhbmRsZXI+KHZhbHVlKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgRWxlbWVudCogUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVsZWFzZUxhc3QoKSB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVsZWFzZUxhc3Q8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlVuc2FmZUFyZW5hUmVsZWFzZUxhc3QoKSB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6VW5zYWZlQXJlbmFSZWxlYXNlTGFzdDxUeXBlSGFuZGxlcj4oKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgaW50IFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkNsZWFyZWRDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpDbGVhcmVkQ291bnQoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpBZGRDbGVhcmVkKEVsZW1lbnQqIHZhbHVlKSB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkQ2xlYXJlZDxUeXBlSGFuZGxlcj4odmFsdWUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpSZWxlYXNlQ2xlYXJlZCgpIHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpSZWxlYXNlQ2xlYXJlZDxUeXBlSGFuZGxlcj4oKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpSZXNlcnZlKGludCBuZXdfc2l6ZSkgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlJlc2VydmUobmV3X3NpemUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBpbnQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Q2FwYWNpdHkoKSBjb25zdCB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2FwYWNpdHkoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBTVEwtbGlrZSBpdGVyYXRvciBpbXBsZW1lbnRhdGlvbiBmb3IgUmVwZWF0ZWRQdHJGaWVsZC4gIFlvdSBzaG91bGQgbm90CisvLyByZWZlciB0byB0aGlzIGNsYXNzIGRpcmVjdGx5OyB1c2UgUmVwZWF0ZWRQdHJGaWVsZDxUPjo6aXRlcmF0b3IgaW5zdGVhZC4KKy8vCisvLyBUaGUgaXRlcmF0b3IgZm9yIFJlcGVhdGVkUHRyRmllbGQ8VD4sIFJlcGVhdGVkUHRySXRlcmF0b3I8VD4sIGlzCisvLyB2ZXJ5IHNpbWlsYXIgdG8gaXRlcmF0b3JfcHRyPFQqKj4gaW4gdXRpbC9ndGwvaXRlcmF0b3JfYWRhcHRvcnMuaCwKKy8vIGJ1dCBhZGRzIHJhbmRvbS1hY2Nlc3Mgb3BlcmF0b3JzIGFuZCBpcyBtb2RpZmllZCB0byB3cmFwIGEgdm9pZCoqIGJhc2UKKy8vIGl0ZXJhdG9yIChzaW5jZSBSZXBlYXRlZFB0ckZpZWxkIHN0b3JlcyBpdHMgYXJyYXkgYXMgYSB2b2lkKiBhcnJheSBhbmQKKy8vIGNhc3Rpbmcgdm9pZCoqIHRvIFQqKiB3b3VsZCB2aW9sYXRlIEMrKyBhbGlhc2luZyBydWxlcykuCisvLworLy8gVGhpcyBjb2RlIGJhc2VkIG9uIG5ldC9wcm90by9wcm90by1hcnJheS1pbnRlcm5hbC5oIGJ5IEplZmZyZXkgWWFzc2tpbgorLy8gKGp5YXNza2luQGdvb2dsZS5jb20pLgordGVtcGxhdGU8dHlwZW5hbWUgRWxlbWVudD4KK2NsYXNzIFJlcGVhdGVkUHRySXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPAorICAgICAgICAgIHN0ZDo6cmFuZG9tX2FjY2Vzc19pdGVyYXRvcl90YWcsIEVsZW1lbnQ+IHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgUmVwZWF0ZWRQdHJJdGVyYXRvcjxFbGVtZW50PiBpdGVyYXRvcjsKKyAgdHlwZWRlZiBzdGQ6Oml0ZXJhdG9yPAorICAgICAgICAgIHN0ZDo6cmFuZG9tX2FjY2Vzc19pdGVyYXRvcl90YWcsIEVsZW1lbnQ+IHN1cGVyY2xhc3M7CisKKyAgLy8gU2hhZG93IHRoZSB2YWx1ZV90eXBlIGluIHN0ZDo6aXRlcmF0b3I8PiBiZWNhdXNlIGNvbnN0X2l0ZXJhdG9yOjp2YWx1ZV90eXBlCisgIC8vIG5lZWRzIHRvIGJlIFQsIG5vdCBjb25zdCBULgorICB0eXBlZGVmIHR5cGVuYW1lIHJlbW92ZV9jb25zdDxFbGVtZW50Pjo6dHlwZSB2YWx1ZV90eXBlOworCisgIC8vIExldCB0aGUgY29tcGlsZXIga25vdyB0aGF0IHRoZXNlIGFyZSB0eXBlIG5hbWVzLCBzbyB3ZSBkb24ndCBoYXZlIHRvCisgIC8vIHdyaXRlICJ0eXBlbmFtZSIgaW4gZnJvbnQgb2YgdGhlbSBldmVyeXdoZXJlLgorICB0eXBlZGVmIHR5cGVuYW1lIHN1cGVyY2xhc3M6OnJlZmVyZW5jZSByZWZlcmVuY2U7CisgIHR5cGVkZWYgdHlwZW5hbWUgc3VwZXJjbGFzczo6cG9pbnRlciBwb2ludGVyOworICB0eXBlZGVmIHR5cGVuYW1lIHN1cGVyY2xhc3M6OmRpZmZlcmVuY2VfdHlwZSBkaWZmZXJlbmNlX3R5cGU7CisKKyAgUmVwZWF0ZWRQdHJJdGVyYXRvcigpIDogaXRfKE5VTEwpIHt9CisgIGV4cGxpY2l0IFJlcGVhdGVkUHRySXRlcmF0b3Iodm9pZCogY29uc3QqIGl0KSA6IGl0XyhpdCkge30KKworICAvLyBBbGxvdyAidXBjYXN0aW5nIiBmcm9tIFJlcGVhdGVkUHRySXRlcmF0b3I8VCoqPiB0bworICAvLyBSZXBlYXRlZFB0ckl0ZXJhdG9yPGNvbnN0IFQqY29uc3QqPi4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgT3RoZXJFbGVtZW50PgorICBSZXBlYXRlZFB0ckl0ZXJhdG9yKGNvbnN0IFJlcGVhdGVkUHRySXRlcmF0b3I8T3RoZXJFbGVtZW50PiYgb3RoZXIpCisgICAgICA6IGl0XyhvdGhlci5pdF8pIHsKKyAgICAvLyBGb3JjZSBhIGNvbXBpbGVyIGVycm9yIGlmIHRoZSBvdGhlciB0eXBlIGlzIG5vdCBjb252ZXJ0aWJsZSB0byBvdXJzLgorICAgIGlmIChmYWxzZSkgeworICAgICAgaW1wbGljaXRfY2FzdDxFbGVtZW50KiwgT3RoZXJFbGVtZW50Kj4oMCk7CisgICAgfQorICB9CisKKyAgLy8gZGVyZWZlcmVuY2VhYmxlCisgIHJlZmVyZW5jZSBvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxFbGVtZW50Kj4oKml0Xyk7IH0KKyAgcG9pbnRlciAgIG9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiAmKG9wZXJhdG9yKigpKTsgfQorCisgIC8vIHtpbmMsZGVjfXJlbWVudGFibGUKKyAgaXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7ICsraXRfOyByZXR1cm4gKnRoaXM7IH0KKyAgaXRlcmF0b3IgIG9wZXJhdG9yKysoaW50KSB7IHJldHVybiBpdGVyYXRvcihpdF8rKyk7IH0KKyAgaXRlcmF0b3ImIG9wZXJhdG9yLS0oKSB7IC0taXRfOyByZXR1cm4gKnRoaXM7IH0KKyAgaXRlcmF0b3IgIG9wZXJhdG9yLS0oaW50KSB7IHJldHVybiBpdGVyYXRvcihpdF8tLSk7IH0KKworICAvLyBlcXVhbGl0eV9jb21wYXJhYmxlCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfID09IHguaXRfOyB9CisgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfICE9IHguaXRfOyB9CisKKyAgLy8gbGVzc190aGFuX2NvbXBhcmFibGUKKyAgYm9vbCBvcGVyYXRvcjwoY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA8IHguaXRfOyB9CisgIGJvb2wgb3BlcmF0b3I8PShjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfIDw9IHguaXRfOyB9CisgIGJvb2wgb3BlcmF0b3I+KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPiB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yPj0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA+PSB4Lml0XzsgfQorCisgIC8vIGFkZGFibGUsIHN1YnRyYWN0YWJsZQorICBpdGVyYXRvciYgb3BlcmF0b3IrPShkaWZmZXJlbmNlX3R5cGUgZCkgeworICAgIGl0XyArPSBkOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBmcmllbmQgaXRlcmF0b3Igb3BlcmF0b3IrKGl0ZXJhdG9yIGl0LCBjb25zdCBkaWZmZXJlbmNlX3R5cGUgZCkgeworICAgIGl0ICs9IGQ7CisgICAgcmV0dXJuIGl0OworICB9CisgIGZyaWVuZCBpdGVyYXRvciBvcGVyYXRvcisoY29uc3QgZGlmZmVyZW5jZV90eXBlIGQsIGl0ZXJhdG9yIGl0KSB7CisgICAgaXQgKz0gZDsKKyAgICByZXR1cm4gaXQ7CisgIH0KKyAgaXRlcmF0b3ImIG9wZXJhdG9yLT0oZGlmZmVyZW5jZV90eXBlIGQpIHsKKyAgICBpdF8gLT0gZDsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgZnJpZW5kIGl0ZXJhdG9yIG9wZXJhdG9yLShpdGVyYXRvciBpdCwgZGlmZmVyZW5jZV90eXBlIGQpIHsKKyAgICBpdCAtPSBkOworICAgIHJldHVybiBpdDsKKyAgfQorCisgIC8vIGluZGV4YWJsZQorICByZWZlcmVuY2Ugb3BlcmF0b3JbXShkaWZmZXJlbmNlX3R5cGUgZCkgY29uc3QgeyByZXR1cm4gKigqdGhpcyArIGQpOyB9CisKKyAgLy8gcmFuZG9tIGFjY2VzcyBpdGVyYXRvcgorICBkaWZmZXJlbmNlX3R5cGUgb3BlcmF0b3ItKGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gLSB4Lml0XzsgfQorCisgcHJpdmF0ZToKKyAgdGVtcGxhdGU8dHlwZW5hbWUgT3RoZXJFbGVtZW50PgorICBmcmllbmQgY2xhc3MgUmVwZWF0ZWRQdHJJdGVyYXRvcjsKKworICAvLyBUaGUgaW50ZXJuYWwgaXRlcmF0b3IuCisgIHZvaWQqIGNvbnN0KiBpdF87Cit9OworCisvLyBQcm92aWRlIGFuIGl0ZXJhdG9yIHRoYXQgb3BlcmF0ZXMgb24gcG9pbnRlcnMgdG8gdGhlIHVuZGVybHlpbmcgb2JqZWN0cworLy8gcmF0aGVyIHRoYW4gdGhlIG9iamVjdHMgdGhlbXNlbHZlcyBhcyBSZXBlYXRlZFB0ckl0ZXJhdG9yIGRvZXMuCisvLyBDb25zaWRlciB1c2luZyB0aGlzIHdoZW4gd29ya2luZyB3aXRoIHN0bCBhbGdvcml0aG1zIHRoYXQgY2hhbmdlCisvLyB0aGUgYXJyYXkuCisvLyBUaGUgVm9pZFB0ciB0ZW1wbGF0ZSBwYXJhbWV0ZXIgaG9sZHMgdGhlIHR5cGUtYWdub3N0aWMgcG9pbnRlciB2YWx1ZQorLy8gcmVmZXJlbmNlZCBieSB0aGUgaXRlcmF0b3IuICBJdCBzaG91bGQgZWl0aGVyIGJlICJ2b2lkICoiIGZvciBhIG11dGFibGUKKy8vIGl0ZXJhdG9yLCBvciAiY29uc3Qgdm9pZCAqIiBmb3IgYSBjb25zdGFudCBpdGVyYXRvci4KK3RlbXBsYXRlPHR5cGVuYW1lIEVsZW1lbnQsIHR5cGVuYW1lIFZvaWRQdHI+CitjbGFzcyBSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6cmFuZG9tX2FjY2Vzc19pdGVyYXRvcl90YWcsIEVsZW1lbnQqPiB7CisgcHVibGljOgorICB0eXBlZGVmIFJlcGVhdGVkUHRyT3ZlclB0cnNJdGVyYXRvcjxFbGVtZW50LCBWb2lkUHRyPiBpdGVyYXRvcjsKKyAgdHlwZWRlZiBzdGQ6Oml0ZXJhdG9yPAorICAgICAgICAgIHN0ZDo6cmFuZG9tX2FjY2Vzc19pdGVyYXRvcl90YWcsIEVsZW1lbnQqPiBzdXBlcmNsYXNzOworCisgIC8vIFNoYWRvdyB0aGUgdmFsdWVfdHlwZSBpbiBzdGQ6Oml0ZXJhdG9yPD4gYmVjYXVzZSBjb25zdF9pdGVyYXRvcjo6dmFsdWVfdHlwZQorICAvLyBuZWVkcyB0byBiZSBULCBub3QgY29uc3QgVC4KKyAgdHlwZWRlZiB0eXBlbmFtZSByZW1vdmVfY29uc3Q8RWxlbWVudCo+Ojp0eXBlIHZhbHVlX3R5cGU7CisKKyAgLy8gTGV0IHRoZSBjb21waWxlciBrbm93IHRoYXQgdGhlc2UgYXJlIHR5cGUgbmFtZXMsIHNvIHdlIGRvbid0IGhhdmUgdG8KKyAgLy8gd3JpdGUgInR5cGVuYW1lIiBpbiBmcm9udCBvZiB0aGVtIGV2ZXJ5d2hlcmUuCisgIHR5cGVkZWYgdHlwZW5hbWUgc3VwZXJjbGFzczo6cmVmZXJlbmNlIHJlZmVyZW5jZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBzdXBlcmNsYXNzOjpwb2ludGVyIHBvaW50ZXI7CisgIHR5cGVkZWYgdHlwZW5hbWUgc3VwZXJjbGFzczo6ZGlmZmVyZW5jZV90eXBlIGRpZmZlcmVuY2VfdHlwZTsKKworICBSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3IoKSA6IGl0XyhOVUxMKSB7fQorICBleHBsaWNpdCBSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3IoVm9pZFB0ciogaXQpIDogaXRfKGl0KSB7fQorCisgIC8vIGRlcmVmZXJlbmNlYWJsZQorICByZWZlcmVuY2Ugb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8RWxlbWVudCoqPihpdF8pOyB9CisgIHBvaW50ZXIgICBvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gJihvcGVyYXRvciooKSk7IH0KKworICAvLyB7aW5jLGRlY31yZW1lbnRhYmxlCisgIGl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeyArK2l0XzsgcmV0dXJuICp0aGlzOyB9CisgIGl0ZXJhdG9yICBvcGVyYXRvcisrKGludCkgeyByZXR1cm4gaXRlcmF0b3IoaXRfKyspOyB9CisgIGl0ZXJhdG9yJiBvcGVyYXRvci0tKCkgeyAtLWl0XzsgcmV0dXJuICp0aGlzOyB9CisgIGl0ZXJhdG9yICBvcGVyYXRvci0tKGludCkgeyByZXR1cm4gaXRlcmF0b3IoaXRfLS0pOyB9CisKKyAgLy8gZXF1YWxpdHlfY29tcGFyYWJsZQorICBib29sIG9wZXJhdG9yPT0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA9PSB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yIT0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyAhPSB4Lml0XzsgfQorCisgIC8vIGxlc3NfdGhhbl9jb21wYXJhYmxlCisgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPCB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yPD0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA8PSB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yPihjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfID4geC5pdF87IH0KKyAgYm9vbCBvcGVyYXRvcj49KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPj0geC5pdF87IH0KKworICAvLyBhZGRhYmxlLCBzdWJ0cmFjdGFibGUKKyAgaXRlcmF0b3ImIG9wZXJhdG9yKz0oZGlmZmVyZW5jZV90eXBlIGQpIHsKKyAgICBpdF8gKz0gZDsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgZnJpZW5kIGl0ZXJhdG9yIG9wZXJhdG9yKyhpdGVyYXRvciBpdCwgZGlmZmVyZW5jZV90eXBlIGQpIHsKKyAgICBpdCArPSBkOworICAgIHJldHVybiBpdDsKKyAgfQorICBmcmllbmQgaXRlcmF0b3Igb3BlcmF0b3IrKGRpZmZlcmVuY2VfdHlwZSBkLCBpdGVyYXRvciBpdCkgeworICAgIGl0ICs9IGQ7CisgICAgcmV0dXJuIGl0OworICB9CisgIGl0ZXJhdG9yJiBvcGVyYXRvci09KGRpZmZlcmVuY2VfdHlwZSBkKSB7CisgICAgaXRfIC09IGQ7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIGZyaWVuZCBpdGVyYXRvciBvcGVyYXRvci0oaXRlcmF0b3IgaXQsIGRpZmZlcmVuY2VfdHlwZSBkKSB7CisgICAgaXQgLT0gZDsKKyAgICByZXR1cm4gaXQ7CisgIH0KKworICAvLyBpbmRleGFibGUKKyAgcmVmZXJlbmNlIG9wZXJhdG9yW10oZGlmZmVyZW5jZV90eXBlIGQpIGNvbnN0IHsgcmV0dXJuICooKnRoaXMgKyBkKTsgfQorCisgIC8vIHJhbmRvbSBhY2Nlc3MgaXRlcmF0b3IKKyAgZGlmZmVyZW5jZV90eXBlIG9wZXJhdG9yLShjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfIC0geC5pdF87IH0KKworIHByaXZhdGU6CisgIHRlbXBsYXRlPHR5cGVuYW1lIE90aGVyRWxlbWVudD4KKyAgZnJpZW5kIGNsYXNzIFJlcGVhdGVkUHRySXRlcmF0b3I7CisKKyAgLy8gVGhlIGludGVybmFsIGl0ZXJhdG9yLgorICBWb2lkUHRyKiBpdF87Cit9OworCit2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpJbnRlcm5hbFN3YXAoUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChyZXBfLCBvdGhlci0+cmVwXyk7CisgIHN0ZDo6c3dhcChjdXJyZW50X3NpemVfLCBvdGhlci0+Y3VycmVudF9zaXplXyk7CisgIHN0ZDo6c3dhcCh0b3RhbF9zaXplXywgb3RoZXItPnRvdGFsX3NpemVfKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Oml0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpiZWdpbigpIHsKKyAgcmV0dXJuIGl0ZXJhdG9yKHJhd19kYXRhKCkpOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Y29uc3RfaXRlcmF0b3IKK1JlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OmJlZ2luKCkgY29uc3QgeworICByZXR1cm4gaXRlcmF0b3IocmF3X2RhdGEoKSk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpjb25zdF9pdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Y2JlZ2luKCkgY29uc3QgeworICByZXR1cm4gYmVnaW4oKTsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Oml0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjplbmQoKSB7CisgIHJldHVybiBpdGVyYXRvcihyYXdfZGF0YSgpICsgc2l6ZSgpKTsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjplbmQoKSBjb25zdCB7CisgIHJldHVybiBpdGVyYXRvcihyYXdfZGF0YSgpICsgc2l6ZSgpKTsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpjZW5kKCkgY29uc3QgeworICByZXR1cm4gZW5kKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OnBvaW50ZXJfaXRlcmF0b3IKK1JlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OnBvaW50ZXJfYmVnaW4oKSB7CisgIHJldHVybiBwb2ludGVyX2l0ZXJhdG9yKHJhd19tdXRhYmxlX2RhdGEoKSk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpwb2ludGVyX2JlZ2luKCkgY29uc3QgeworICByZXR1cm4gY29uc3RfcG9pbnRlcl9pdGVyYXRvcihjb25zdF9jYXN0PGNvbnN0IHZvaWQqKj4ocmF3X211dGFibGVfZGF0YSgpKSk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpwb2ludGVyX2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpwb2ludGVyX2VuZCgpIHsKKyAgcmV0dXJuIHBvaW50ZXJfaXRlcmF0b3IocmF3X211dGFibGVfZGF0YSgpICsgc2l6ZSgpKTsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OmNvbnN0X3BvaW50ZXJfaXRlcmF0b3IKK1JlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OnBvaW50ZXJfZW5kKCkgY29uc3QgeworICByZXR1cm4gY29uc3RfcG9pbnRlcl9pdGVyYXRvcigKKyAgICAgIGNvbnN0X2Nhc3Q8Y29uc3Qgdm9pZCoqPihyYXdfbXV0YWJsZV9kYXRhKCkgKyBzaXplKCkpKTsKK30KKworCisvLyBJdGVyYXRvcnMgYW5kIGhlbHBlciBmdW5jdGlvbnMgdGhhdCBmb2xsb3cgdGhlIHNwaXJpdCBvZiB0aGUgU1RMCisvLyBzdGQ6OmJhY2tfaW5zZXJ0X2l0ZXJhdG9yIGFuZCBzdGQ6OmJhY2tfaW5zZXJ0ZXIgYnV0IGFyZSB0YWlsb3ItbWFkZQorLy8gZm9yIFJlcGVhdGVkRmllbGQgYW5kIFJlcGVhdGVkUHRyRmllbGQuIFR5cGljYWwgdXNhZ2Ugd291bGQgYmU6CisvLworLy8gICBzdGQ6OmNvcHkoc29tZV9zZXF1ZW5jZS5iZWdpbigpLCBzb21lX3NlcXVlbmNlLmVuZCgpLAorLy8gICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlcihwcm90by5tdXRhYmxlX3NlcXVlbmNlKCkpKTsKKy8vCisvLyBQb3J0ZWQgYnkgam9oYW5uZXMgZnJvbSB1dGlsL2d0bC9wcm90by1hcnJheS1pdGVyYXRvcnMuaAorCituYW1lc3BhY2UgaW50ZXJuYWwgeworLy8gQSBiYWNrIGluc2VydGVyIGZvciBSZXBlYXRlZEZpZWxkIG9iamVjdHMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBjbGFzcyBSZXBlYXRlZEZpZWxkQmFja0luc2VydEl0ZXJhdG9yCisgICAgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjxzdGQ6Om91dHB1dF9pdGVyYXRvcl90YWcsIFQ+IHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3IoCisgICAgICBSZXBlYXRlZEZpZWxkPFQ+KiBjb25zdCBtdXRhYmxlX2ZpZWxkKQorICAgICAgOiBmaWVsZF8obXV0YWJsZV9maWVsZCkgeworICB9CisgIFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yPShjb25zdCBUJiB2YWx1ZSkgeworICAgIGZpZWxkXy0+QWRkKHZhbHVlKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IqKCkgeworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBSZXBlYXRlZEZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcisrKCkgeworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBSZXBlYXRlZEZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcisrKGludCAvKiB1bnVzZWQgKi8pIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIFJlcGVhdGVkRmllbGQ8VD4qIGZpZWxkXzsKK307CisKKy8vIEEgYmFjayBpbnNlcnRlciBmb3IgUmVwZWF0ZWRQdHJGaWVsZCBvYmplY3RzLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcgorICAgIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpvdXRwdXRfaXRlcmF0b3JfdGFnLCBUPiB7CisgcHVibGljOgorICBSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yKAorICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxUPiogY29uc3QgbXV0YWJsZV9maWVsZCkKKyAgICAgIDogZmllbGRfKG11dGFibGVfZmllbGQpIHsKKyAgfQorICBSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcj0oY29uc3QgVCYgdmFsdWUpIHsKKyAgICAqZmllbGRfLT5BZGQoKSA9IHZhbHVlOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcj0oCisgICAgICBjb25zdCBUKiBjb25zdCBwdHJfdG9fdmFsdWUpIHsKKyAgICAqZmllbGRfLT5BZGQoKSA9ICpwdHJfdG9fdmFsdWU7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yKigpIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IrKygpIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IrKyhpbnQgLyogdW51c2VkICovKSB7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyBwcml2YXRlOgorICBSZXBlYXRlZFB0ckZpZWxkPFQ+KiBmaWVsZF87Cit9OworCisvLyBBIGJhY2sgaW5zZXJ0ZXIgZm9yIFJlcGVhdGVkUHRyRmllbGRzIHRoYXQgaW5zZXJ0cyBieSB0cmFuc2ZlcmluZyBvd25lcnNoaXAKKy8vIG9mIGEgcG9pbnRlci4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6b3V0cHV0X2l0ZXJhdG9yX3RhZywgVD4geworIHB1YmxpYzoKKyAgZXhwbGljaXQgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcigKKyAgICAgIFJlcGVhdGVkUHRyRmllbGQ8VD4qIGNvbnN0IG11dGFibGVfZmllbGQpCisgICAgICA6IGZpZWxkXyhtdXRhYmxlX2ZpZWxkKSB7CisgIH0KKyAgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3I9KAorICAgICAgVCogY29uc3QgcHRyX3RvX3ZhbHVlKSB7CisgICAgZmllbGRfLT5BZGRBbGxvY2F0ZWQocHRyX3RvX3ZhbHVlKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IqKCkgeworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcisrKCkgeworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcisrKAorICAgICAgaW50IC8qIHVudXNlZCAqLykgeworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgcHJpdmF0ZToKKyAgUmVwZWF0ZWRQdHJGaWVsZDxUPiogZmllbGRfOworfTsKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyBQcm92aWRlcyBhIGJhY2sgaW5zZXJ0IGl0ZXJhdG9yIGZvciBSZXBlYXRlZEZpZWxkIGluc3RhbmNlcywKKy8vIHNpbWlsYXIgdG8gc3RkOjpiYWNrX2luc2VydGVyKCkuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPgorUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlcihSZXBlYXRlZEZpZWxkPFQ+KiBjb25zdCBtdXRhYmxlX2ZpZWxkKSB7CisgIHJldHVybiBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPihtdXRhYmxlX2ZpZWxkKTsKK30KKworLy8gUHJvdmlkZXMgYSBiYWNrIGluc2VydCBpdGVyYXRvciBmb3IgUmVwZWF0ZWRQdHJGaWVsZCBpbnN0YW5jZXMsCisvLyBzaW1pbGFyIHRvIHN0ZDo6YmFja19pbnNlcnRlcigpLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gaW50ZXJuYWw6OlJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4KK1JlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0ZXIoUmVwZWF0ZWRQdHJGaWVsZDxUPiogY29uc3QgbXV0YWJsZV9maWVsZCkgeworICByZXR1cm4gaW50ZXJuYWw6OlJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4obXV0YWJsZV9maWVsZCk7Cit9CisKKy8vIFNwZWNpYWwgYmFjayBpbnNlcnQgaXRlcmF0b3IgZm9yIFJlcGVhdGVkUHRyRmllbGQgaW5zdGFuY2VzLCBqdXN0IGluCisvLyBjYXNlIHNvbWVvbmUgd2FudHMgdG8gd3JpdGUgZ2VuZXJpYyB0ZW1wbGF0ZSBjb2RlIHRoYXQgY2FuIGFjY2VzcyBib3RoCisvLyBSZXBlYXRlZEZpZWxkcyBhbmQgUmVwZWF0ZWRQdHJGaWVsZHMgdXNpbmcgYSBjb21tb24gbmFtZS4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+CitSZXBlYXRlZEZpZWxkQmFja0luc2VydGVyKFJlcGVhdGVkUHRyRmllbGQ8VD4qIGNvbnN0IG11dGFibGVfZmllbGQpIHsKKyAgcmV0dXJuIGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+KG11dGFibGVfZmllbGQpOworfQorCisvLyBQcm92aWRlcyBhIGJhY2sgaW5zZXJ0IGl0ZXJhdG9yIGZvciBSZXBlYXRlZFB0ckZpZWxkIGluc3RhbmNlcworLy8gc2ltaWxhciB0byBzdGQ6OmJhY2tfaW5zZXJ0ZXIoKSB3aGljaCB0cmFuc2ZlcnMgdGhlIG93bmVyc2hpcCB3aGlsZQorLy8gY29weWluZyBlbGVtZW50cy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGludGVybmFsOjpBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+CitBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydGVyKAorICAgIFJlcGVhdGVkUHRyRmllbGQ8VD4qIGNvbnN0IG11dGFibGVfZmllbGQpIHsKKyAgcmV0dXJuIGludGVybmFsOjpBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+KAorICAgICAgbXV0YWJsZV9maWVsZCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9SRVBFQVRFRF9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF9yZWZsZWN0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRkMTRkNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbi5oCkBAIC0wLDAgKzEsMzM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBoZWFkZXIgZmlsZSBpcyBwcm90b2J1ZiBpbnRlcm5hbC4gVXNlcnMgc2hvdWxkIG5vdCBpbmNsdWRlIHRoaXMKKy8vIGZpbGUgZGlyZWN0bHkuCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9SRVBFQVRFRF9GSUVMRF9SRUZMRUNUSU9OX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUkVQRUFURURfRklFTERfUkVGTEVDVElPTl9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV9yZWZsZWN0aW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisvLyBJbnRlcmZhY2VzIHVzZWQgdG8gaW1wbGVtZW50IHJlZmxlY3Rpb24gUmVwZWF0ZWRGaWVsZFJlZiBBUEkuCisvLyBSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZEFjY2Vzc29yKCkgc2hvdWxkIHJldHVybiBhIHBvaW50ZXIgdG8gYW4gc2luZ2xldG9uCisvLyBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBiZWxvdyBpbnRlcmZhY2UuCisvLworLy8gVGhpcyBpbnRlcmZhY2UgcGFzc2VzL3JldHVybnMgdmFsdWVzIHVzaW5nIHZvaWQgcG9pbnRlcnMuIFRoZSBhY3R1YWwgdHlwZQorLy8gb2YgdGhlIHZhbHVlIGRlcGVuZHMgb24gdGhlIGZpZWxkJ3MgY3BwX3R5cGUuIEZvbGxvd2luZyBpcyBhIG1hcHBpbmcgZnJvbQorLy8gY3BwX3R5cGUgdG8gdGhlIHR5cGUgdGhhdCBzaG91bGQgYmUgdXNlZCBpbiB0aGlzIGludGVyZmFjZToKKy8vCisvLyAgIGZpZWxkLT5jcHBfdHlwZSgpICAgICAgVCAgICAgICAgICAgICAgICBBY3R1YWwgdHlwZSBvZiB2b2lkKgorLy8gICBDUFBUWVBFX0lOVDMyICAgICAgICBpbnQzMiAgICAgICAgICAgICAgICAgICBpbnQzMgorLy8gICBDUFBUWVBFX1VJTlQzMiAgICAgICB1aW50MzIgICAgICAgICAgICAgICAgICB1aW50MzIKKy8vICAgQ1BQVFlQRV9JTlQ2NCAgICAgICAgaW50NjQgICAgICAgICAgICAgICAgICAgaW50NjQKKy8vICAgQ1BQVFlQRV9VSU5UNjQgICAgICAgdWludDY0ICAgICAgICAgICAgICAgICAgdWludDY0CisvLyAgIENQUFRZUEVfRE9VQkxFICAgICAgIGRvdWJsZSAgICAgICAgICAgICAgICAgIGRvdWJsZQorLy8gICBDUFBUWVBFX0ZMT0FUICAgICAgICBmbG9hdCAgICAgICAgICAgICAgICAgICBmbG9hdAorLy8gICBDUFBUWVBFX0JPT0wgICAgICAgICBib29sICAgICAgICAgICAgICAgICAgICBib29sCisvLyAgIENQUFRZUEVfRU5VTSAgICAgICAgIGdlbmVyYXRlZCBlbnVtIHR5cGUgICAgIGludDMyCisvLyAgIENQUFRZUEVfU1RSSU5HICAgICAgIHN0cmluZyAgICAgICAgICAgICAgICAgIHN0cmluZworLy8gICBDUFBUWVBFX01FU1NBR0UgICAgICBnZW5lcmF0ZWQgbWVzc2FnZSB0eXBlICBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlCisvLyAgICAgICAgICAgICAgICAgICAgICAgIG9yIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UKKy8vCisvLyBOb3RlIHRoYXQgZm9yIGVudW1zIHdlIHVzZSBpbnQzMiBpbiB0aGUgaW50ZXJmYWNlLgorLy8KKy8vIFlvdSBjYW4gbWFwIGZyb20gVCB0byB0aGUgYWN0dWFsIHR5cGUgdXNpbmcgUmVmVHlwZVRyYWl0czoKKy8vICAgdHlwZWRlZiBSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclZhbHVlVHlwZSBBY3R1YWxUeXBlOworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJlcGVhdGVkRmllbGRBY2Nlc3NvciB7CisgcHVibGljOgorICAvLyBUeXBlZGVmcyBmb3IgY2xhcml0eS4KKyAgdHlwZWRlZiB2b2lkIEZpZWxkOworICB0eXBlZGVmIHZvaWQgVmFsdWU7CisgIHR5cGVkZWYgdm9pZCBJdGVyYXRvcjsKKworICB2aXJ0dWFsIH5SZXBlYXRlZEZpZWxkQWNjZXNzb3IoKTsKKyAgdmlydHVhbCBib29sIElzRW1wdHkoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBpbnQgU2l6ZShjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICAvLyBEZXBlbmRzIG9uIHRoZSB1bmRlcmx5aW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZXBlYXRlZCBmaWVsZCwgdGhpcworICAvLyBtZXRob2QgY2FuIHJldHVybiBhIHBvaW50ZXIgdG8gdGhlIHVuZGVybHlpbmcgb2JqZWN0IGlmIHN1Y2ggYW4gb2JqZWN0CisgIC8vIGV4aXN0cywgb3IgZmlsbCB0aGUgZGF0YSBpbnRvIHNjcmF0Y2hfc3BhY2UgYW5kIHJldHVybiBzY3JhdGNoX3NwYWNlLgorICAvLyBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIG11c3QgZW5zdXJlIHNjcmF0Y2hfc3BhY2UgaXMgYSB2YWxpZCBwb2ludGVyCisgIC8vIHRvIGEgbXV0YWJsZSBvYmplY3Qgb2YgdGhlIGNvcnJlY3QgdHlwZS4KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogR2V0KAorICAgICAgY29uc3QgRmllbGQqIGRhdGEsIGludCBpbmRleCwgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0ID0gMDsKKworICB2aXJ0dWFsIHZvaWQgQ2xlYXIoRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFNldChGaWVsZCogZGF0YSwgaW50IGluZGV4LCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZChGaWVsZCogZGF0YSwgY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBSZW1vdmVMYXN0KEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTd2FwRWxlbWVudHMoRmllbGQqIGRhdGEsIGludCBpbmRleDEsIGludCBpbmRleDIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFN3YXAoRmllbGQqIGRhdGEsIGNvbnN0IFJlcGVhdGVkRmllbGRBY2Nlc3Nvciogb3RoZXJfbXV0YXRvciwKKyAgICAgICAgICAgICAgICAgICAgRmllbGQqIG90aGVyX2RhdGEpIGNvbnN0ID0gMDsKKworICAvLyBDcmVhdGUgYW4gaXRlcmF0b3IgdGhhdCBwb2ludHMgYXQgdGhlIGJlZ2luaW5nIG9mIHRoZSByZXBlYXRlZCBmaWVsZC4KKyAgdmlydHVhbCBJdGVyYXRvciogQmVnaW5JdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICAvLyBDcmVhdGUgYW4gaXRlcmF0b3IgdGhhdCBwb2ludHMgYXQgdGhlIGVuZCBvZiB0aGUgcmVwZWF0ZWQgZmllbGQuCisgIHZpcnR1YWwgSXRlcmF0b3IqIEVuZEl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIC8vIE1ha2UgYSBjb3B5IG9mIGFuIGl0ZXJhdG9yIGFuZCByZXR1cm4gdGhlIG5ldyBjb3B5LgorICB2aXJ0dWFsIEl0ZXJhdG9yKiBDb3B5SXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogaXRlcmF0b3IpIGNvbnN0ID0gMDsKKyAgLy8gTW92ZSBhbiBpdGVyYXRvciB0byBwb2ludCB0byB0aGUgbmV4dCBlbGVtZW50LgorICB2aXJ0dWFsIEl0ZXJhdG9yKiBBZHZhbmNlSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciogaXRlcmF0b3IpIGNvbnN0ID0gMDsKKyAgLy8gQ29tcGFyZSB3aGV0aGVyIHR3byBpdGVyYXRvcnMgcG9pbnQgdG8gdGhlIHNhbWUgZWxlbWVudC4KKyAgdmlydHVhbCBib29sIEVxdWFsc0l0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhLCBjb25zdCBJdGVyYXRvciogYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBiKSBjb25zdCA9IDA7CisgIC8vIERlbGV0ZSBhbiBpdGVyYXRvciBjcmVhdGVkIGJ5IEJlZ2luSXRlcmF0b3IoKSwgRW5kSXRlcmF0b3IoKSBhbmQKKyAgLy8gQ29weUl0ZXJhdG9yKCkuCisgIHZpcnR1YWwgdm9pZCBEZWxldGVJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCA9IDA7CisgIC8vIExpa2UgR2V0KCkgYnV0IGZvciBpdGVyYXRvcnMuCisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldEl0ZXJhdG9yVmFsdWUoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSXRlcmF0b3IqIGl0ZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCA9IDA7CisKKyAgLy8gVGVtcGxhdGVkIG1ldGhvZHMgdGhhdCBtYWtlIHVzaW5nIHRoaXMgaW50ZXJmYWNlIGVhc2llciBmb3Igbm9uLW1lc3NhZ2UKKyAgLy8gdHlwZXMuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIFQgR2V0KGNvbnN0IEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjdHVhbFR5cGU7CisgICAgQWN0dWFsVHlwZSBzY3JhdGNoX3NwYWNlOworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUPigKKyAgICAgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgQWN0dWFsVHlwZSo+KAorICAgICAgICAgICAgR2V0KGRhdGEsIGluZGV4LCBzdGF0aWNfY2FzdDxWYWx1ZSo+KCZzY3JhdGNoX3NwYWNlKSkpKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFZhbHVlVHlwZT4KKyAgdm9pZCBTZXQoRmllbGQqIGRhdGEsIGludCBpbmRleCwgY29uc3QgVmFsdWVUeXBlJiB2YWx1ZSkgY29uc3QgeworICAgIHR5cGVkZWYgdHlwZW5hbWUgUmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JWYWx1ZVR5cGUgQWN0dWFsVHlwZTsKKyAgICAvLyBJbiB0aGlzIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbnRlcmZhY2Ugd2UgcGFzcy9yZXR1cm4gZGF0YSB1c2luZworICAgIC8vIHJhdyBwb2ludGVycy4gVHlwZSBvZiB0aGUgZGF0YSB0aGVzZSByYXcgcG9pbnRlcnMgcG9pbnQgdG8gc2hvdWxkCisgICAgLy8gYmUgQWN0dWFsVHlwZS4gSGVyZSB3ZSBoYXZlIGEgVmFsdWVUeXBlIG9iamVjdCBhbmQgd2FudCBhIEFjdHVhbFR5cGUKKyAgICAvLyBwb2ludGVyLiBXZSBjYW4ndCBjYXN0IGEgVmFsdWVUeXBlIHBvaW50ZXIgdG8gYW4gQWN0dWFsVHlwZSBwb2ludGVyCisgICAgLy8gZGlyZWN0bHkgYmVjYXVzZSB0aGVpciB0eXBlIG1pZ2h0IGJlIGRpZmZlcmVudCAoZm9yIGVudW1zIFZhbHVlVHlwZQorICAgIC8vIG1heSBiZSBhIGdlbmVyYXRlZCBlbnVtIHR5cGUgd2hpbGUgQWN0dWFsVHlwZSBpcyBpbnQzMikuIFRvIGJlIHNhZmUKKyAgICAvLyB3ZSBtYWtlIGEgY29weSB0byBnZXQgYSB0ZW1wb3JhcnkgQWN0dWFsVHlwZSBvYmplY3QgYW5kIHVzZSBpdC4KKyAgICBBY3R1YWxUeXBlIHRtcCA9IHN0YXRpY19jYXN0PEFjdHVhbFR5cGU+KHZhbHVlKTsKKyAgICBTZXQoZGF0YSwgaW5kZXgsIHN0YXRpY19jYXN0PGNvbnN0IFZhbHVlKj4oJnRtcCkpOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVmFsdWVUeXBlPgorICB2b2lkIEFkZChGaWVsZCogZGF0YSwgY29uc3QgVmFsdWVUeXBlJiB2YWx1ZSkgY29uc3QgeworICAgIHR5cGVkZWYgdHlwZW5hbWUgUmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JWYWx1ZVR5cGUgQWN0dWFsVHlwZTsKKyAgICAvLyBJbiB0aGlzIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbnRlcmZhY2Ugd2UgcGFzcy9yZXR1cm4gZGF0YSB1c2luZworICAgIC8vIHJhdyBwb2ludGVycy4gVHlwZSBvZiB0aGUgZGF0YSB0aGVzZSByYXcgcG9pbnRlcnMgcG9pbnQgdG8gc2hvdWxkCisgICAgLy8gYmUgQWN0dWFsVHlwZS4gSGVyZSB3ZSBoYXZlIGEgVmFsdWVUeXBlIG9iamVjdCBhbmQgd2FudCBhIEFjdHVhbFR5cGUKKyAgICAvLyBwb2ludGVyLiBXZSBjYW4ndCBjYXN0IGEgVmFsdWVUeXBlIHBvaW50ZXIgdG8gYW4gQWN0dWFsVHlwZSBwb2ludGVyCisgICAgLy8gZGlyZWN0bHkgYmVjYXVzZSB0aGVpciB0eXBlIG1pZ2h0IGJlIGRpZmZlcmVudCAoZm9yIGVudW1zIFZhbHVlVHlwZQorICAgIC8vIG1heSBiZSBhIGdlbmVyYXRlZCBlbnVtIHR5cGUgd2hpbGUgQWN0dWFsVHlwZSBpcyBpbnQzMikuIFRvIGJlIHNhZmUKKyAgICAvLyB3ZSBtYWtlIGEgY29weSB0byBnZXQgYSB0ZW1wb3JhcnkgQWN0dWFsVHlwZSBvYmplY3QgYW5kIHVzZSBpdC4KKyAgICBBY3R1YWxUeXBlIHRtcCA9IHN0YXRpY19jYXN0PEFjdHVhbFR5cGU+KHZhbHVlKTsKKyAgICBBZGQoZGF0YSwgc3RhdGljX2Nhc3Q8Y29uc3QgVmFsdWUqPigmdG1wKSk7CisgIH0KK307CisKKy8vIEltcGxlbWVudCAoTXV0YWJsZSlSZXBlYXRlZEZpZWxkUmVmOjppdGVyYXRvcgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcgorICAgIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywgVD4geworICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46Okl0ZXJhdG9yVmFsdWVUeXBlIEl0ZXJhdG9yVmFsdWVUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46Okl0ZXJhdG9yUG9pbnRlclR5cGUgSXRlcmF0b3JQb2ludGVyVHlwZTsKKworIHB1YmxpYzoKKyAgLy8gQ29uc3RydWN0b3IgZm9yIG5vbi1tZXNzYWdlIGZpZWxkcy4KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGNvbnN0IHZvaWQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIGFjY2Vzc29yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBiZWdpbikKKyAgICAgIDogZGF0YV8oZGF0YSksIGFjY2Vzc29yXyhhY2Nlc3NvciksCisgICAgICAgIGl0ZXJhdG9yXyhiZWdpbiA/IGFjY2Vzc29yLT5CZWdpbkl0ZXJhdG9yKGRhdGEpIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPkVuZEl0ZXJhdG9yKGRhdGEpKSwKKyAgICAgICAgc2NyYXRjaF9zcGFjZV8obmV3IEFjY2Vzc29yVmFsdWVUeXBlKSB7CisgIH0KKyAgLy8gQ29uc3RydWN0b3IgZm9yIG1lc3NhZ2UgZmllbGRzLgorICBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IoY29uc3Qgdm9pZCogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlcGVhdGVkRmllbGRBY2Nlc3NvciogYWNjZXNzb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJlZ2luLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzb3JWYWx1ZVR5cGUqIHNjcmF0Y2hfc3BhY2UpCisgICAgICA6IGRhdGFfKGRhdGEpLCBhY2Nlc3Nvcl8oYWNjZXNzb3IpLAorICAgICAgICBpdGVyYXRvcl8oYmVnaW4gPyBhY2Nlc3Nvci0+QmVnaW5JdGVyYXRvcihkYXRhKSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5FbmRJdGVyYXRvcihkYXRhKSksCisgICAgICAgIHNjcmF0Y2hfc3BhY2VfKHNjcmF0Y2hfc3BhY2UpIHsKKyAgfQorICB+UmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKCkgeworICAgIGFjY2Vzc29yXy0+RGVsZXRlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7CisgICAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yIHRtcCgqdGhpcyk7CisgICAgaXRlcmF0b3JfID0gYWNjZXNzb3JfLT5BZHZhbmNlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgICAgcmV0dXJuIHRtcDsKKyAgfQorICBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7CisgICAgaXRlcmF0b3JfID0gYWNjZXNzb3JfLT5BZHZhbmNlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIEl0ZXJhdG9yVmFsdWVUeXBlIG9wZXJhdG9yKigpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8SXRlcmF0b3JWYWx1ZVR5cGU+KAorICAgICAgICAqc3RhdGljX2Nhc3Q8Y29uc3QgQWNjZXNzb3JWYWx1ZVR5cGUqPigKKyAgICAgICAgICAgIGFjY2Vzc29yXy0+R2V0SXRlcmF0b3JWYWx1ZSgKKyAgICAgICAgICAgICAgICBkYXRhXywgaXRlcmF0b3JfLCBzY3JhdGNoX3NwYWNlXy5nZXQoKSkpKTsKKyAgfQorICBJdGVyYXRvclBvaW50ZXJUeXBlIG9wZXJhdG9yLT4oKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PEl0ZXJhdG9yUG9pbnRlclR5cGU+KAorICAgICAgICBhY2Nlc3Nvcl8tPkdldEl0ZXJhdG9yVmFsdWUoCisgICAgICAgICAgICBkYXRhXywgaXRlcmF0b3JfLCBzY3JhdGNoX3NwYWNlXy5nZXQoKSkpOworICB9CisgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKSBjb25zdCB7CisgICAgYXNzZXJ0KGRhdGFfID09IG90aGVyLmRhdGFfKTsKKyAgICBhc3NlcnQoYWNjZXNzb3JfID09IG90aGVyLmFjY2Vzc29yXyk7CisgICAgcmV0dXJuICFhY2Nlc3Nvcl8tPkVxdWFsc0l0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8sIG90aGVyLml0ZXJhdG9yXyk7CisgIH0KKyAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gIXRoaXMtPm9wZXJhdG9yIT0ob3RoZXIpOworICB9CisKKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGNvbnN0IFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3RoZXIpCisgICAgICA6IGRhdGFfKG90aGVyLmRhdGFfKSwgYWNjZXNzb3JfKG90aGVyLmFjY2Vzc29yXyksCisgICAgICAgIGl0ZXJhdG9yXyhhY2Nlc3Nvcl8tPkNvcHlJdGVyYXRvcihkYXRhXywgb3RoZXIuaXRlcmF0b3JfKSkgeworICB9CisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3BlcmF0b3I9KGNvbnN0IFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciYgb3RoZXIpIHsKKyAgICBpZiAodGhpcyAhPSAmb3RoZXIpIHsKKyAgICAgIGFjY2Vzc29yXy0+RGVsZXRlSXRlcmF0b3IoZGF0YV8sIGl0ZXJhdG9yXyk7CisgICAgICBkYXRhXyA9IG90aGVyLmRhdGFfOworICAgICAgYWNjZXNzb3JfID0gb3RoZXIuYWNjZXNzb3JfOworICAgICAgaXRlcmF0b3JfID0gYWNjZXNzb3JfLT5Db3B5SXRlcmF0b3IoZGF0YV8sIG90aGVyLml0ZXJhdG9yXyk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgcHJvdGVjdGVkOgorICBjb25zdCB2b2lkKiBkYXRhXzsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBhY2Nlc3Nvcl87CisgIHZvaWQqIGl0ZXJhdG9yXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxBY2Nlc3NvclZhbHVlVHlwZT4gc2NyYXRjaF9zcGFjZV87Cit9OworCisvLyBUeXBlVHJhaXRzIHRoYXQgbWFwcyB0aGUgdHlwZSBwYXJhbWV0ZXIgVCBvZiBSZXBlYXRlZEZpZWxkUmVmIG9yCisvLyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiB0byBjb3JyZXNwb25kaW5nIGl0ZXJhdG9yIHR5cGUsCisvLyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgdHlwZSwgZXRjLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBQcmltaXRpdmVUcmFpdHMgeworICBzdGF0aWMgY29uc3QgYm9vbCBpc19wcmltaXRpdmUgPSBmYWxzZTsKK307CisjZGVmaW5lIERFRklORV9QUklNSVRJVkUoVFlQRSwgdHlwZSkgXAorICAgIHRlbXBsYXRlPD4gc3RydWN0IFByaW1pdGl2ZVRyYWl0czx0eXBlPiB7IFwKKyAgICAgIHN0YXRpYyBjb25zdCBib29sIGlzX3ByaW1pdGl2ZSA9IHRydWU7IFwKKyAgICAgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUgPSBcCisgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyAjIyBUWVBFOyBcCisgICAgfTsKK0RFRklORV9QUklNSVRJVkUoSU5UMzIsIGludDMyKQorREVGSU5FX1BSSU1JVElWRShVSU5UMzIsIHVpbnQzMikKK0RFRklORV9QUklNSVRJVkUoSU5UNjQsIGludDY0KQorREVGSU5FX1BSSU1JVElWRShVSU5UNjQsIHVpbnQ2NCkKK0RFRklORV9QUklNSVRJVkUoRkxPQVQsIGZsb2F0KQorREVGSU5FX1BSSU1JVElWRShET1VCTEUsIGRvdWJsZSkKK0RFRklORV9QUklNSVRJVkUoQk9PTCwgYm9vbCkKKyN1bmRlZiBERUZJTkVfUFJJTUlUSVZFCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUmVmVHlwZVRyYWl0czwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPFByaW1pdGl2ZVRyYWl0czxUPjo6aXNfcHJpbWl0aXZlPjo6dHlwZT4geworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcjxUPiBpdGVyYXRvcjsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgQWNjZXNzb3JUeXBlOworICB0eXBlZGVmIFQgQWNjZXNzb3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgVCBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBUKiBJdGVyYXRvclBvaW50ZXJUeXBlOworICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0KKyAgICAgIFByaW1pdGl2ZVRyYWl0czxUPjo6Y3BwX3R5cGU7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxpc19wcm90b19lbnVtPFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgLy8gV2UgdXNlIGludDMyIGZvciByZXBlYXRlZCBlbnVtcyBpbiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IuCisgIHR5cGVkZWYgaW50MzIgQWNjZXNzb3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgVCBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBpbnQzMiogSXRlcmF0b3JQb2ludGVyVHlwZTsKKyAgc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSA9CisgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTsKKyAgc3RhdGljIGNvbnN0IERlc2NyaXB0b3IqIEdldE1lc3NhZ2VGaWVsZERlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUmVmVHlwZVRyYWl0czwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPGludGVybmFsOjppc19zYW1lPHN0cmluZywgVD46OnZhbHVlPjo6dHlwZT4geworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcjxUPiBpdGVyYXRvcjsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgQWNjZXNzb3JUeXBlOworICB0eXBlZGVmIHN0cmluZyBBY2Nlc3NvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBzdHJpbmcgSXRlcmF0b3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgc3RyaW5nKiBJdGVyYXRvclBvaW50ZXJUeXBlOworICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0KKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IE1lc3NhZ2VEZXNjcmlwdG9yR2V0dGVyIHsKKyAgc3RhdGljIGNvbnN0IERlc2NyaXB0b3IqIGdldCgpIHsKKyAgICByZXR1cm4gVDo6ZGVmYXVsdF9pbnN0YW5jZSgpLkdldERlc2NyaXB0b3IoKTsKKyAgfQorfTsKK3RlbXBsYXRlPD4KK3N0cnVjdCBNZXNzYWdlRGVzY3JpcHRvckdldHRlcjxNZXNzYWdlPiB7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBnZXQoKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUmVmVHlwZVRyYWl0czwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPGludGVybmFsOjppc19iYXNlX29mPE1lc3NhZ2UsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiBNZXNzYWdlIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIGNvbnN0IFQmIEl0ZXJhdG9yVmFsdWVUeXBlOworICB0eXBlZGVmIGNvbnN0IFQqIEl0ZXJhdG9yUG9pbnRlclR5cGU7CisgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUgPQorICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBNZXNzYWdlRGVzY3JpcHRvckdldHRlcjxUPjo6Z2V0KCk7CisgIH0KK307Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUkVQRUFURURfRklFTERfUkVGTEVDVElPTl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mY2ViZTVjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNzA2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiB0Z3NAZ29vZ2xlLmNvbSAoVG9tIFN6eW1hbnNraSkKKy8vCisvLyBUZXN0IHJlZmxlY3Rpb24gbWV0aG9kcyBmb3IgYWdncmVnYXRlIGFjY2VzcyB0byBSZXBlYXRlZFtQdHJdRmllbGRzLgorLy8gVGhpcyB0ZXN0IHByb3RvMiBtZXRob2RzIG9uIGEgcHJvdG8yIGxheW91dC4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCit1c2luZyB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U7Cit1c2luZyB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOwordXNpbmcgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOworCituYW1lc3BhY2UgeworCitzdGF0aWMgaW50IEZ1bmMoaW50IGksIGludCBqKSB7CisgIHJldHVybiBpICogajsKK30KKworc3RhdGljIHN0cmluZyBTdHJGdW5jKGludCBpLCBpbnQgaikgeworICBzdHJpbmcgc3RyOworICBTU3RyaW5nUHJpbnRmKCZzdHIsICIlZCIsIEZ1bmMoaSwgNCkpOworICByZXR1cm4gc3RyOworfQorCitURVNUKFJlcGVhdGVkRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVndWxhckZpZWxkcykgeworICBUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfaW50MzIoRnVuYyhpLCAxKSk7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKEZ1bmMoaSwgMikpOworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZyhTdHJGdW5jKGksIDUpKTsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoRnVuYyhpLCA2KSk7CisgIH0KKworICAvLyBHZXQgRmllbGREZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfcmVwZWF0ZWRfaW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2RvdWJsZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2RvdWJsZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX3N0cmluZyIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpOworCisgIC8vIEdldCBSZXBlYXRlZEZpZWxkIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50MzI+JiByZl9pbnQzMiA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkPGludDMyPihtZXNzYWdlLCBmZF9yZXBlYXRlZF9pbnQzMik7CisgIGNvbnN0IFJlcGVhdGVkRmllbGQ8ZG91YmxlPiYgcmZfZG91YmxlID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGQ8ZG91YmxlPihtZXNzYWdlLCBmZF9yZXBlYXRlZF9kb3VibGUpOworCisgIC8vIEdldCBtdXRhYmxlIFJlcGVhdGVkRmllbGQgb2JqZWN0cyBmb3IgYWxsIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgUmVwZWF0ZWRGaWVsZDxpbnQzMj4qIG1yZl9pbnQzMiA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZDxpbnQzMj4oJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ludDMyKTsKKyAgUmVwZWF0ZWRGaWVsZDxkb3VibGU+KiBtcmZfZG91YmxlID0KKyAgICAgIHJlZmwtPk11dGFibGVSZXBlYXRlZEZpZWxkPGRvdWJsZT4oJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX2RvdWJsZSk7CisKKyAgLy8gR2V0IFJlcGVhdGVkUHRyRmllbGQgb2JqZWN0cyBmb3IgYWxsIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+JiBycGZfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPihtZXNzYWdlLCBmZF9yZXBlYXRlZF9zdHJpbmcpOworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPEZvcmVpZ25NZXNzYWdlPiYgcnBmX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPEZvcmVpZ25NZXNzYWdlPigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+JiBycGZfbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KAorICAgICAgICAgIG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gR2V0IG11dGFibGUgUmVwZWF0ZWRQdHJGaWVsZCBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qIG1ycGZfc3RyaW5nID0KKyAgICAgIHJlZmwtPk11dGFibGVSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4oJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX3N0cmluZyk7CisgIFJlcGVhdGVkUHRyRmllbGQ8Rm9yZWlnbk1lc3NhZ2U+KiBtcnBmX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZDxGb3JlaWduTWVzc2FnZT4oCisgICAgICAgICAgJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSk7CisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIG1ycGZfbWVzc2FnZSA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigKKyAgICAgICAgICAmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIGRvIGdldHMgYW5kIHNldHMgdGhyb3VnaCB0aGUgUmVwZWF0ZWRbUHRyXUZpZWxkIG9iamVjdHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIC8vIENoZWNrIGdldHMgdGhyb3VnaCBjb25zdCBvYmplY3RzLgorICAgIEVYUEVDVF9FUShyZl9pbnQzMi5HZXQoaSksIEZ1bmMoaSwgMSkpOworICAgIEVYUEVDVF9FUShyZl9kb3VibGUuR2V0KGkpLCBGdW5jKGksIDIpKTsKKyAgICBFWFBFQ1RfRVEocnBmX3N0cmluZy5HZXQoaSksIFN0ckZ1bmMoaSwgNSkpOworICAgIEVYUEVDVF9FUShycGZfZm9yZWlnbl9tZXNzYWdlLkdldChpKS5jKCksIEZ1bmMoaSwgNikpOworICAgIEVYUEVDVF9FUShkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UqPigmcnBmX21lc3NhZ2UuR2V0KGkpKS0+YygpLAorICAgICAgICAgICAgICBGdW5jKGksIDYpKTsKKworICAgIC8vIENoZWNrIGdldHMgdGhyb3VnaCBtdXRhYmxlIG9iamVjdHMuCisgICAgRVhQRUNUX0VRKG1yZl9pbnQzMi0+R2V0KGkpLCBGdW5jKGksIDEpKTsKKyAgICBFWFBFQ1RfRVEobXJmX2RvdWJsZS0+R2V0KGkpLCBGdW5jKGksIDIpKTsKKyAgICBFWFBFQ1RfRVEobXJwZl9zdHJpbmctPkdldChpKSwgU3RyRnVuYyhpLCA1KSk7CisgICAgRVhQRUNUX0VRKG1ycGZfZm9yZWlnbl9tZXNzYWdlLT5HZXQoaSkuYygpLCBGdW5jKGksIDYpKTsKKyAgICBFWFBFQ1RfRVEoZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlKj4oJm1ycGZfbWVzc2FnZS0+R2V0KGkpKS0+YygpLAorICAgICAgICAgICAgICBGdW5jKGksIDYpKTsKKworICAgIC8vIENoZWNrIHNldHMgdGhyb3VnaCBtdXRhYmxlIG9iamVjdHMuCisgICAgbXJmX2ludDMyLT5TZXQoaSwgRnVuYyhpLCAtMSkpOworICAgIG1yZl9kb3VibGUtPlNldChpLCBGdW5jKGksIC0yKSk7CisgICAgbXJwZl9zdHJpbmctPk11dGFibGUoaSktPmFzc2lnbihTdHJGdW5jKGksIC01KSk7CisgICAgbXJwZl9mb3JlaWduX21lc3NhZ2UtPk11dGFibGUoaSktPnNldF9jKEZ1bmMoaSwgLTYpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9pbnQzMihpKSwgRnVuYyhpLCAtMSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZShpKSwgRnVuYyhpLCAtMikpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyhpKSwgU3RyRnVuYyhpLCAtNSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZShpKS5jKCksIEZ1bmMoaSwgLTYpKTsKKyAgICBkb3duX2Nhc3Q8Rm9yZWlnbk1lc3NhZ2UqPihtcnBmX21lc3NhZ2UtPk11dGFibGUoaSkpLT5zZXRfYyhGdW5jKGksIDcpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSkuYygpLCBGdW5jKGksIDcpKTsKKyAgfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKyAgLy8gTWFrZSBzdXJlIHR5cGVzIGFyZSBjaGVja2VkIGNvcnJlY3RseSBhdCBydW50aW1lLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX29wdGlvbmFsX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50MzIiKTsKKyAgRVhQRUNUX0RFQVRIKHJlZmwtPkdldFJlcGVhdGVkRmllbGQ8aW50MzI+KAorICAgICAgbWVzc2FnZSwgZmRfb3B0aW9uYWxfaW50MzIpLCAicmVxdWlyZXMgYSByZXBlYXRlZCBmaWVsZCIpOworICBFWFBFQ1RfREVBVEgocmVmbC0+R2V0UmVwZWF0ZWRGaWVsZDxkb3VibGU+KAorICAgICAgbWVzc2FnZSwgZmRfcmVwZWF0ZWRfaW50MzIpLCAibm90IHRoZSByaWdodCB0eXBlIik7CisgIEVYUEVDVF9ERUFUSChyZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPFRlc3RBbGxUeXBlcz4oCisgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpLCAid3Jvbmcgc3VibWVzc2FnZSB0eXBlIik7CisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCit9CisKKworVEVTVChSZXBlYXRlZEZpZWxkUmVmbGVjdGlvblRlc3QsIEV4dGVuc2lvbkZpZWxkcykgeworICBUZXN0QWxsRXh0ZW5zaW9ucyBleHRlbmRlZF9tZXNzYWdlOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsID0gZXh0ZW5kZWRfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBleHRlbmRlZF9tZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBleHRlbmRlZF9tZXNzYWdlLkFkZEV4dGVuc2lvbigKKyAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiwgRnVuYyhpLCAxKSk7CisgIH0KKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiA9CisgICAgICBkZXNjLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUoInJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiIpOworICBHT09HTEVfQ0hFQ0soZmRfcmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uICE9IE5VTEwpOworCisgIGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50NjQ+JiByZl9pbnQ2NF9leHRlbnNpb24gPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZDxpbnQ2ND4oZXh0ZW5kZWRfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbik7CisKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ2ND4qIG1yZl9pbnQ2NF9leHRlbnNpb24gPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkRmllbGQ8aW50NjQ+KCZleHRlbmRlZF9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMSksIHJmX2ludDY0X2V4dGVuc2lvbi5HZXQoaSkpOworICAgIG1yZl9pbnQ2NF9leHRlbnNpb24tPlNldChpLCBGdW5jKGksIC0xKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgLTEpLAorICAgICAgICBleHRlbmRlZF9tZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uLCBpKSk7CisgIH0KK30KKwordGVtcGxhdGU8dHlwZW5hbWUgUmVmLCB0eXBlbmFtZSBNZXNzYWdlVHlwZSwgdHlwZW5hbWUgVmFsdWVUeXBlPgordm9pZCBUZXN0UmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKAorICAgIGNvbnN0IFJlZiYgaGFuZGxlLCBjb25zdCBNZXNzYWdlVHlwZSYgbWVzc2FnZSwKKyAgICBWYWx1ZVR5cGUgKE1lc3NhZ2VUeXBlOjoqR2V0RnVuYykoaW50KSBjb25zdCkgeworICBpbnQgaW5kZXggPSAwOworICBmb3IgKHR5cGVuYW1lIFJlZjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBoYW5kbGUuYmVnaW4oKTsKKyAgICAgICBpdCAhPSBoYW5kbGUuZW5kKCk7ICsraXQpIHsKKyAgICBFWFBFQ1RfRVEoKG1lc3NhZ2UuKkdldEZ1bmMpKGluZGV4KSwgKml0KTsKKyAgICArK2luZGV4OworICB9CisgIEVYUEVDVF9FUShoYW5kbGUuc2l6ZSgpLCBpbmRleCk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZXBlYXRlZEZpZWxkUmVmRm9yUmVndWxhckZpZWxkcykgeworICBUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfaW50MzIoRnVuYyhpLCAxKSk7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKEZ1bmMoaSwgMikpOworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZyhTdHJGdW5jKGksIDUpKTsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoRnVuYyhpLCA2KSk7CisgIH0KKworICAvLyBHZXQgRmllbGREZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfcmVwZWF0ZWRfaW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2RvdWJsZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2RvdWJsZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX3N0cmluZyIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpOworCisgIC8vIEdldCBSZXBlYXRlZEZpZWxkUmVmIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8aW50MzI+IHJmX2ludDMyID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8aW50MzI+KG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ludDMyKTsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+IHJmX2RvdWJsZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4obWVzc2FnZSwgZmRfcmVwZWF0ZWRfZG91YmxlKTsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZFJlZjxzdHJpbmc+IHJmX3N0cmluZyA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPHN0cmluZz4obWVzc2FnZSwgZmRfcmVwZWF0ZWRfc3RyaW5nKTsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT4gcmZfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+KAorICAgICAgICAgIG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSk7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4gcmZfbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgIG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gR2V0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGludDMyPiBtcmZfaW50MzIgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50MzI+KCZtZXNzYWdlLCBmZF9yZXBlYXRlZF9pbnQzMik7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4gbXJmX2RvdWJsZSA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+KCZtZXNzYWdlLCBmZF9yZXBlYXRlZF9kb3VibGUpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxzdHJpbmc+IG1yZl9zdHJpbmcgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8c3RyaW5nPigmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfc3RyaW5nKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+IG1yZl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+KAorICAgICAgICAgICZtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtcmZfbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICAmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplKCksIHJmX2ludDMyLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUoKSwgbXJmX2ludDMyLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplKCksIHJmX2RvdWJsZS5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpLCBtcmZfZG91YmxlLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplKCksIHJmX3N0cmluZy5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpLCBtcmZfc3RyaW5nLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCksCisgICAgICAgICAgICByZl9mb3JlaWduX21lc3NhZ2Uuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSwKKyAgICAgICAgICAgIG1yZl9mb3JlaWduX21lc3NhZ2Uuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSwgcmZfbWVzc2FnZS5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpLCBtcmZfbWVzc2FnZS5zaXplKCkpOworCisgIEVYUEVDVF9GQUxTRShyZl9pbnQzMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1yZl9pbnQzMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHJmX2RvdWJsZS5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1yZl9kb3VibGUuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShyZl9zdHJpbmcuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtcmZfc3RyaW5nLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UocmZfZm9yZWlnbl9tZXNzYWdlLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobXJmX2ZvcmVpZ25fbWVzc2FnZS5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHJmX21lc3NhZ2UuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtcmZfbWVzc2FnZS5lbXB0eSgpKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIGRvIGdldHMgYW5kIHNldHMgdGhyb3VnaCB0aGUgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggY29uc3Qgb2JqZWN0cy4KKyAgICBFWFBFQ1RfRVEocmZfaW50MzIuR2V0KGkpLCBGdW5jKGksIDEpKTsKKyAgICBFWFBFQ1RfRVEocmZfZG91YmxlLkdldChpKSwgRnVuYyhpLCAyKSk7CisgICAgRVhQRUNUX0VRKHJmX3N0cmluZy5HZXQoaSksIFN0ckZ1bmMoaSwgNSkpOworICAgIEZvcmVpZ25NZXNzYWdlIHNjcmF0Y2hfc3BhY2U7CisgICAgRVhQRUNUX0VRKHJmX2ZvcmVpZ25fbWVzc2FnZS5HZXQoaSwgJnNjcmF0Y2hfc3BhY2UpLmMoKSwgRnVuYyhpLCA2KSk7CisgICAgRVhQRUNUX0VRKGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSY+KAorICAgICAgICByZl9tZXNzYWdlLkdldChpLCAmc2NyYXRjaF9zcGFjZSkpLmMoKSwgRnVuYyhpLCA2KSk7CisKKyAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggbXV0YWJsZSBvYmplY3RzLgorICAgIEVYUEVDVF9FUShtcmZfaW50MzIuR2V0KGkpLCBGdW5jKGksIDEpKTsKKyAgICBFWFBFQ1RfRVEobXJmX2RvdWJsZS5HZXQoaSksIEZ1bmMoaSwgMikpOworICAgIEVYUEVDVF9FUShtcmZfc3RyaW5nLkdldChpKSwgU3RyRnVuYyhpLCA1KSk7CisgICAgRVhQRUNUX0VRKG1yZl9mb3JlaWduX21lc3NhZ2UuR2V0KGksICZzY3JhdGNoX3NwYWNlKS5jKCksIEZ1bmMoaSwgNikpOworICAgIEVYUEVDVF9FUShkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgbXJmX21lc3NhZ2UuR2V0KGksICZzY3JhdGNoX3NwYWNlKSkuYygpLCBGdW5jKGksIDYpKTsKKworICAgIC8vIENoZWNrIHNldHMgdGhyb3VnaCBtdXRhYmxlIG9iamVjdHMuCisgICAgbXJmX2ludDMyLlNldChpLCBGdW5jKGksIC0xKSk7CisgICAgbXJmX2RvdWJsZS5TZXQoaSwgRnVuYyhpLCAtMikpOworICAgIG1yZl9zdHJpbmcuU2V0KGksIFN0ckZ1bmMoaSwgLTUpKTsKKyAgICBGb3JlaWduTWVzc2FnZSBmb3JlaWduX21lc3NhZ2U7CisgICAgZm9yZWlnbl9tZXNzYWdlLnNldF9jKEZ1bmMoaSwgLTYpKTsKKyAgICBtcmZfZm9yZWlnbl9tZXNzYWdlLlNldChpLCBmb3JlaWduX21lc3NhZ2UpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ludDMyKGkpLCBGdW5jKGksIC0xKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKGkpLCBGdW5jKGksIC0yKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKGkpLCBTdHJGdW5jKGksIC01KSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGkpLmMoKSwgRnVuYyhpLCAtNikpOworICAgIGZvcmVpZ25fbWVzc2FnZS5zZXRfYyhGdW5jKGksIDcpKTsKKyAgICBtcmZfbWVzc2FnZS5TZXQoaSwgZm9yZWlnbl9tZXNzYWdlKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSkuYygpLCBGdW5jKGksIDcpKTsKKyAgfQorCisgIC8vIFRlc3QgaXRlcmF0b3JzLgorICBUZXN0UmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKHJmX2ludDMyLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUZXN0QWxsVHlwZXM6OnJlcGVhdGVkX2ludDMyKTsKKyAgVGVzdFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihyZl9kb3VibGUsIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRlc3RBbGxUeXBlczo6cmVwZWF0ZWRfZG91YmxlKTsKKyAgVGVzdFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihyZl9zdHJpbmcsIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRlc3RBbGxUeXBlczo6cmVwZWF0ZWRfc3RyaW5nKTsKKworICAvLyBUZXN0IGl0ZXJhdG9ycyBmb3IgbWVzc2FnZSBmaWVsZHMuCisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT46Oml0ZXJhdG9yIE1lc3NhZ2VJdGVyYXRvcjsKKyAgaW50IGluZGV4ID0gMDsKKyAgZm9yIChNZXNzYWdlSXRlcmF0b3IgaXQgPSByZl9mb3JlaWduX21lc3NhZ2UuYmVnaW4oKTsKKyAgICAgICBpdCAhPSByZl9mb3JlaWduX21lc3NhZ2UuZW5kKCk7ICsraXQpIHsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaW5kZXgpLmMoKSwgaXQtPmMoKSk7CisgICAgKytpbmRleDsKKyAgfQorICBFWFBFQ1RfRVEoMTAsIGluZGV4KTsKKworICAvLyBUZXN0IGl0ZXJhdG9yIG9wZXJhdG9ycyB0aGF0IGFyZSBub3QgdXN1c2FsbHkgdXNlZCBpbiByZWd1bGFyIGZvci1sb29wcy4KKyAgLy8gSW5jbHVkaW5nOiBwb3N0IGluY3JlbWVudCwgYXNzaWduLCA9PS4KKyAgTWVzc2FnZUl0ZXJhdG9yIG9sZF9pdCA9IHJmX2ZvcmVpZ25fbWVzc2FnZS5iZWdpbigpOworICBNZXNzYWdlSXRlcmF0b3IgbmV3X2l0ID0gb2xkX2l0Kys7CisgIEVYUEVDVF9GQUxTRShvbGRfaXQgPT0gbmV3X2l0KTsKKyAgLy8gQ2hlY2sgdGhhdCBvbGRfaXQrKyBpbmNyZW1lbnRzIG9sZF9pdCBvbmNlLgorICBmb3IgKGluZGV4ID0gMTsgb2xkX2l0ICE9IHJmX2ZvcmVpZ25fbWVzc2FnZS5lbmQoKTsgKytvbGRfaXQsICsraW5kZXgpIHsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaW5kZXgpLmMoKSwgb2xkX2l0LT5jKCkpOworICB9CisgIEVYUEVDVF9FUSgxMCwgaW5kZXgpOworICAvLyBUZXN0IGFzc2lnbiBvcGVyYXRvci4KKyAgb2xkX2l0ID0gbmV3X2l0OworICBmb3IgKGluZGV4ID0gMDsgb2xkX2l0ICE9IHJmX2ZvcmVpZ25fbWVzc2FnZS5lbmQoKTsgKytvbGRfaXQsICsraW5kZXgpIHsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaW5kZXgpLmMoKSwgb2xkX2l0LT5jKCkpOworICB9CisgIEVYUEVDVF9FUSgxMCwgaW5kZXgpOworICAvLyBDaGVjayB0aGF0IHRoZSByZXR1cm5lZCB2YWx1ZSBvZiBvbGRfaXQrKyBpcyB0aGUgb25lIGJlZm9yZSBpbmNyZW1lbnQuCisgIGZvciAoaW5kZXggPSAwOyBuZXdfaXQgIT0gcmZfZm9yZWlnbl9tZXNzYWdlLmVuZCgpOyArK25ld19pdCwgKytpbmRleCkgeworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZShpbmRleCkuYygpLCBuZXdfaXQtPmMoKSk7CisgIH0KKyAgRVhQRUNUX0VRKDEwLCBpbmRleCk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6QWRkKCkKKyAgbXJmX2ludDMyLkFkZCgxMjM0KTsKKyAgbXJmX2RvdWJsZS5BZGQoMTIzNC4wKTsKKyAgbXJmX3N0cmluZy5BZGQoIjEyMzQiKTsKKyAgRm9yZWlnbk1lc3NhZ2UgZm9yZWlnbl9tZXNzYWdlOworICBmb3JlaWduX21lc3NhZ2Uuc2V0X2MoMTIzNCk7CisgIG1yZl9mb3JlaWduX21lc3NhZ2UuQWRkKGZvcmVpZ25fbWVzc2FnZSk7CisgIEVYUEVDVF9FUSgxMjM0LCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyKDEwKSk7CisgIEVYUEVDVF9FUSgxMjM0LjAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDEwKSk7CisgIEVYUEVDVF9FUSgiMTIzNCIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKDEwKSk7CisgIEVYUEVDVF9FUSgxMjM0LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgxMCkuYygpKTsKKworICAvLyBUZXN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmOjpSZW1vdmVMYXN0KCkKKyAgbXJmX2ludDMyLlJlbW92ZUxhc3QoKTsKKyAgbXJmX2RvdWJsZS5SZW1vdmVMYXN0KCk7CisgIG1yZl9zdHJpbmcuUmVtb3ZlTGFzdCgpOworICBtcmZfZm9yZWlnbl9tZXNzYWdlLlJlbW92ZUxhc3QoKTsKKyAgRVhQRUNUX0VRKDEwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6U3dhcEVsZW1lbnRzKCkKKyAgbXJmX2ludDMyLlN3YXBFbGVtZW50cygwLCA5KTsKKyAgbXJmX2RvdWJsZS5Td2FwRWxlbWVudHMoMCwgOSk7CisgIG1yZl9zdHJpbmcuU3dhcEVsZW1lbnRzKDAsIDkpOworICBtcmZfZm9yZWlnbl9tZXNzYWdlLlN3YXBFbGVtZW50cygwLCA5KTsKKyAgRVhQRUNUX0VRKEZ1bmMoOSwgLTEpLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKEZ1bmMoMCwgLTEpLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyKDkpKTsKKyAgRVhQRUNUX0VRKEZ1bmMoOSwgLTIpLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSgwKSk7CisgIEVYUEVDVF9FUShGdW5jKDAsIC0yKSwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoOSkpOworICBFWFBFQ1RfRVEoU3RyRnVuYyg5LCAtNSksIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKDApKTsKKyAgRVhQRUNUX0VRKFN0ckZ1bmMoMCwgLTUpLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyg5KSk7CisgIEVYUEVDVF9FUShGdW5jKDksIDcpLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoRnVuYygwLCA3KSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoOSkuYygpKTsKKworICAvLyBUZXN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmOjpDbGVhcigpCisgIG1yZl9pbnQzMi5DbGVhcigpOworICBtcmZfZG91YmxlLkNsZWFyKCk7CisgIG1yZl9zdHJpbmcuQ2xlYXIoKTsKKyAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworCisgIC8vIFRlc3QgKE11dGFibGUpUmVwZWF0ZWRGaWVsZFJlZjo6ZW1wdHkoKQorICBFWFBFQ1RfVFJVRShyZl9pbnQzMi5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUobXJmX2ludDMyLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShyZl9kb3VibGUuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKG1yZl9kb3VibGUuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKHJmX3N0cmluZy5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUobXJmX3N0cmluZy5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUocmZfZm9yZWlnbl9tZXNzYWdlLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShtcmZfZm9yZWlnbl9tZXNzYWdlLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShyZl9tZXNzYWdlLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShtcmZfbWVzc2FnZS5lbXB0eSgpKTsKKworI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisKKyAgLy8gTWFrZSBzdXJlIHR5cGVzIGFyZSBjaGVja2VkIGNvcnJlY3RseSBhdCBydW50aW1lLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX29wdGlvbmFsX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50MzIiKTsKKyAgRVhQRUNUX0RFQVRIKHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8aW50MzI+KAorICAgICAgbWVzc2FnZSwgZmRfb3B0aW9uYWxfaW50MzIpLCAiIik7CisgIEVYUEVDVF9ERUFUSChyZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4oCisgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9pbnQzMiksICIiKTsKKyAgRVhQRUNUX0RFQVRIKHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzPigKKyAgICAgIG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSksICIiKTsKKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorfQorCitURVNUKFJlcGVhdGVkRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVwZWF0ZWRGaWVsZFJlZkZvckVudW1zKSB7CisgIFRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bShUZXN0QWxsVHlwZXM6OkJBUik7CisgIH0KKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX2VudW0iKTsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+IGVudW1fcmVmID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtPigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSk7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPFRlc3RBbGxUeXBlczo6TmVzdGVkRW51bT4KKyAgbXV0YWJsZV9lbnVtX3JlZiA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+KAorICAgICAgICAgICZtZXNzYWdlLCBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSk7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8aW50MzI+IGludDMyX3JlZiA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGludDMyPigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSk7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGludDMyPiBtdXRhYmxlX2ludDMyX3JlZiA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4oCisgICAgICAgICAgJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCksIGVudW1fcmVmLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSwgbXV0YWJsZV9lbnVtX3JlZi5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCksIGludDMyX3JlZi5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCksIG11dGFibGVfaW50MzJfcmVmLnNpemUoKSk7CisKKyAgRVhQRUNUX0ZBTFNFKGVudW1fcmVmLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobXV0YWJsZV9lbnVtX3JlZi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKGludDMyX3JlZi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG11dGFibGVfaW50MzJfcmVmLmVtcHR5KCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBUiwgZW51bV9yZWYuR2V0KGkpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIG11dGFibGVfZW51bV9yZWYuR2V0KGkpKTsKKyAgICBtdXRhYmxlX2VudW1fcmVmLlNldChpLCBUZXN0QWxsVHlwZXM6OkJBWik7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFaLCBlbnVtX3JlZi5HZXQoaSkpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bShpKSk7CisKKyAgICBtZXNzYWdlLnNldF9yZXBlYXRlZF9uZXN0ZWRfZW51bShpLCBUZXN0QWxsVHlwZXM6OkJBUik7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBpbnQzMl9yZWYuR2V0KGkpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIG11dGFibGVfaW50MzJfcmVmLkdldChpKSk7CisgICAgbXV0YWJsZV9pbnQzMl9yZWYuU2V0KGksIFRlc3RBbGxUeXBlczo6QkFaKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIGludDMyX3JlZi5HZXQoaSkpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bShpKSk7CisgIH0KKworICBUZXN0UmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGVudW1fcmVmLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUZXN0QWxsVHlwZXM6OnJlcGVhdGVkX25lc3RlZF9lbnVtKTsKKyAgVGVzdFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihpbnQzMl9yZWYsIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRlc3RBbGxUeXBlczo6cmVwZWF0ZWRfbmVzdGVkX2VudW0pOworCisgIC8vIFRlc3QgQWRkKCkKKyAgbXV0YWJsZV9lbnVtX3JlZi5BZGQoVGVzdEFsbFR5cGVzOjpGT08pOworICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0oMTApKTsKKyAgbXV0YWJsZV9pbnQzMl9yZWYuQWRkKFRlc3RBbGxUeXBlczo6QkFSKTsKKyAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtKDExKSk7CisKKyAgLy8gVGVzdCBSZW1vdmVMYXN0KCkKKyAgbXV0YWJsZV9lbnVtX3JlZi5SZW1vdmVMYXN0KCk7CisgIEVYUEVDVF9FUSgxMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBtdXRhYmxlX2ludDMyX3JlZi5SZW1vdmVMYXN0KCk7CisgIEVYUEVDVF9FUSgxMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworCisgIC8vIFRlc3QgU3dhcEVsZW1lbnRzKCkKKyAgbXV0YWJsZV9lbnVtX3JlZi5TZXQoMCwgVGVzdEFsbFR5cGVzOjpCQVIpOworICBtdXRhYmxlX2VudW1fcmVmLlNldCg5LCBUZXN0QWxsVHlwZXM6OkJBWik7CisgIG11dGFibGVfZW51bV9yZWYuU3dhcEVsZW1lbnRzKDAsIDkpOworICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIGVudW1fcmVmLkdldCgwKSk7CisgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBUiwgZW51bV9yZWYuR2V0KDkpKTsKKyAgbXV0YWJsZV9pbnQzMl9yZWYuU3dhcEVsZW1lbnRzKDAsIDkpOworICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIGVudW1fcmVmLkdldCgwKSk7CisgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgZW51bV9yZWYuR2V0KDkpKTsKKworICAvLyBUZXN0IENsZWFyKCkKKyAgbXV0YWJsZV9lbnVtX3JlZi5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBtdXRhYmxlX2VudW1fcmVmLkFkZChUZXN0QWxsVHlwZXM6OkZPTyk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgIG11dGFibGVfaW50MzJfcmVmLkNsZWFyKCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisKKyAgLy8gVGVzdCBlbXB0eSgpCisgIEVYUEVDVF9UUlVFKGVudW1fcmVmLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShtdXRhYmxlX2VudW1fcmVmLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShpbnQzMl9yZWYuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKG11dGFibGVfaW50MzJfcmVmLmVtcHR5KCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVwZWF0ZWRGaWVsZFJlZkZvckV4dGVuc2lvbkZpZWxkcykgeworICBUZXN0QWxsRXh0ZW5zaW9ucyBleHRlbmRlZF9tZXNzYWdlOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsID0gZXh0ZW5kZWRfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBleHRlbmRlZF9tZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBleHRlbmRlZF9tZXNzYWdlLkFkZEV4dGVuc2lvbigKKyAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiwgRnVuYyhpLCAxKSk7CisgIH0KKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiA9CisgICAgICBkZXNjLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUoInJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiIpOworICBHT09HTEVfQ0hFQ0soZmRfcmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uICE9IE5VTEwpOworCisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8aW50NjQ+IHJmX2ludDY0X2V4dGVuc2lvbiA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGludDY0PihleHRlbmRlZF9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfcmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uKTsKKworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQ2ND4gbXJmX2ludDY0X2V4dGVuc2lvbiA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQ2ND4oJmV4dGVuZGVkX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfcmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAxKSwgcmZfaW50NjRfZXh0ZW5zaW9uLkdldChpKSk7CisgICAgbXJmX2ludDY0X2V4dGVuc2lvbi5TZXQoaSwgRnVuYyhpLCAtMSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIC0xKSwKKyAgICAgICAgZXh0ZW5kZWRfbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiwgaSkpOworICB9Cit9CisKKworVEVTVChSZXBlYXRlZEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlcGVhdGVkRmllbGRSZWZNZXJnZUZyb21BbmRTd2FwKSB7CisgIC8vIFNldC11cCBtZXNzYWdlIGNvbnRlbnQuCisgIFRlc3RBbGxUeXBlcyBtMCwgbTEsIG0yOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBtMC5hZGRfcmVwZWF0ZWRfaW50MzIoRnVuYyhpLCAxKSk7CisgICAgbTAuYWRkX3JlcGVhdGVkX2RvdWJsZShGdW5jKGksIDIpKTsKKyAgICBtMC5hZGRfcmVwZWF0ZWRfc3RyaW5nKFN0ckZ1bmMoaSwgNSkpOworICAgIG0wLmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoRnVuYyhpLCA2KSk7CisgICAgbTAuYWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKFRlc3RBbGxUeXBlczo6Rk9PKTsKKyAgICBtMS5hZGRfcmVwZWF0ZWRfaW50MzIoRnVuYyhpLCAxMSkpOworICAgIG0xLmFkZF9yZXBlYXRlZF9kb3VibGUoRnVuYyhpLCAxMikpOworICAgIG0xLmFkZF9yZXBlYXRlZF9zdHJpbmcoU3RyRnVuYyhpLCAxNSkpOworICAgIG0xLmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoRnVuYyhpLCAxNikpOworICAgIG0xLmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bShUZXN0QWxsVHlwZXM6OkJBUik7CisgICAgbTIuYWRkX3JlcGVhdGVkX2ludDMyKEZ1bmMoaSwgMjEpKTsKKyAgICBtMi5hZGRfcmVwZWF0ZWRfZG91YmxlKEZ1bmMoaSwgMjIpKTsKKyAgICBtMi5hZGRfcmVwZWF0ZWRfc3RyaW5nKFN0ckZ1bmMoaSwgMjUpKTsKKyAgICBtMi5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKEZ1bmMoaSwgMjYpKTsKKyAgICBtMi5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0oVGVzdEFsbFR5cGVzOjpCQVopOworICB9CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG0wLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG0wLkdldERlc2NyaXB0b3IoKTsKKworICAvLyBHZXQgRmllbGREZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfcmVwZWF0ZWRfaW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2RvdWJsZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2RvdWJsZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX3N0cmluZyIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX2VudW0iKTsKKworICAvLyBHZXQgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYgb2JqZWN0cyBmb3IgYWxsIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50MzI+IG1yZl9pbnQzMiA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4oJm0wLCBmZF9yZXBlYXRlZF9pbnQzMik7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4gbXJmX2RvdWJsZSA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+KCZtMCwgZmRfcmVwZWF0ZWRfZG91YmxlKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8c3RyaW5nPiBtcmZfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPHN0cmluZz4oJm0wLCBmZF9yZXBlYXRlZF9zdHJpbmcpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT4gbXJmX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT4oCisgICAgICAgICAgJm0wLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+CisgIG1yZl9uZXN0ZWRfZW51bSA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+KAorICAgICAgICAgICZtMCwgZmRfcmVwZWF0ZWRfbmVzdGVkX2VudW0pOworCisgIC8vIFRlc3QgTXV0YWJsZVJlcGVhdGVkUmVmOjpDb3B5RnJvbQorICBtcmZfaW50MzIuQ29weUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGludDMyPihtMSwgZmRfcmVwZWF0ZWRfaW50MzIpKTsKKyAgbXJmX2RvdWJsZS5Db3B5RnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8ZG91YmxlPihtMSwgZmRfcmVwZWF0ZWRfZG91YmxlKSk7CisgIG1yZl9zdHJpbmcuQ29weUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPHN0cmluZz4obTEsIGZkX3JlcGVhdGVkX3N0cmluZykpOworICBtcmZfZm9yZWlnbl9tZXNzYWdlLkNvcHlGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT4oCisgICAgICAgICAgbTEsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSkpOworICBtcmZfbmVzdGVkX2VudW0uQ29weUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPFRlc3RBbGxUeXBlczo6TmVzdGVkRW51bT4oCisgICAgICAgICAgbTEsIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIEVYUEVDVF9FUShGdW5jKGksIDExKSwgbTAucmVwZWF0ZWRfaW50MzIoaSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDEyKSwgbTAucmVwZWF0ZWRfZG91YmxlKGkpKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAxNSksIG0wLnJlcGVhdGVkX3N0cmluZyhpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTYpLCBtMC5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSkuYygpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIG0wLnJlcGVhdGVkX25lc3RlZF9lbnVtKGkpKTsKKyAgfQorCisgIC8vIFRlc3QgTXV0YWJsZVJlcGVhdGVkUmVmOjpNZXJnZUZyb20KKyAgbXJmX2ludDMyLk1lcmdlRnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8aW50MzI+KG0yLCBmZF9yZXBlYXRlZF9pbnQzMikpOworICBtcmZfZG91YmxlLk1lcmdlRnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8ZG91YmxlPihtMiwgZmRfcmVwZWF0ZWRfZG91YmxlKSk7CisgIG1yZl9zdHJpbmcuTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxzdHJpbmc+KG0yLCBmZF9yZXBlYXRlZF9zdHJpbmcpKTsKKyAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5NZXJnZUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPEZvcmVpZ25NZXNzYWdlPigKKyAgICAgICAgICBtMiwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKSk7CisgIG1yZl9uZXN0ZWRfZW51bS5NZXJnZUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPFRlc3RBbGxUeXBlczo6TmVzdGVkRW51bT4oCisgICAgICAgICAgbTIsIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIEVYUEVDVF9FUShGdW5jKGksIDIxKSwgbTAucmVwZWF0ZWRfaW50MzIoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjIpLCBtMC5yZXBlYXRlZF9kb3VibGUoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMjUpLCBtMC5yZXBlYXRlZF9zdHJpbmcoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjYpLCBtMC5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSArIDEwKS5jKCkpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgbTAucmVwZWF0ZWRfbmVzdGVkX2VudW0oaSArIDEwKSk7CisgIH0KKworICAvLyBUZXN0IE11dGFibGVSZXBlYXRlZFJlZjo6U3dhcAorICAvLyBTd2FwIGJldHdlZW4gbTAgYW5kIG0yLgorICBtcmZfaW50MzIuU3dhcCgKKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGludDMyPigmbTIsIGZkX3JlcGVhdGVkX2ludDMyKSk7CisgIG1yZl9kb3VibGUuU3dhcCgKKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4oJm0yLCBmZF9yZXBlYXRlZF9kb3VibGUpKTsKKyAgbXJmX3N0cmluZy5Td2FwKAorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8c3RyaW5nPigmbTIsIGZkX3JlcGVhdGVkX3N0cmluZykpOworICBtcmZfZm9yZWlnbl9tZXNzYWdlLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT4oCisgICAgICAgICAgJm0yLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpKTsKKyAgbXJmX25lc3RlZF9lbnVtLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+KAorICAgICAgICAgICZtMiwgZmRfcmVwZWF0ZWRfbmVzdGVkX2VudW0pKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgLy8gQ2hlY2sgdGhlIGNvbnRlbnQgb2YgbTAuCisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjEpLCBtMC5yZXBlYXRlZF9pbnQzMihpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjIpLCBtMC5yZXBlYXRlZF9kb3VibGUoaSkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIDI1KSwgbTAucmVwZWF0ZWRfc3RyaW5nKGkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyNiksIG0wLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZShpKS5jKCkpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgbTAucmVwZWF0ZWRfbmVzdGVkX2VudW0oaSkpOworCisgICAgLy8gQ2hlY2sgdGhlIGNvbnRlbnQgb2YgbTIuCisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTEpLCBtMi5yZXBlYXRlZF9pbnQzMihpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTIpLCBtMi5yZXBlYXRlZF9kb3VibGUoaSkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIDE1KSwgbTIucmVwZWF0ZWRfc3RyaW5nKGkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAxNiksIG0yLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZShpKS5jKCkpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBUiwgbTIucmVwZWF0ZWRfbmVzdGVkX2VudW0oaSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDIxKSwgbTIucmVwZWF0ZWRfaW50MzIoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjIpLCBtMi5yZXBlYXRlZF9kb3VibGUoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMjUpLCBtMi5yZXBlYXRlZF9zdHJpbmcoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjYpLCBtMi5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSArIDEwKS5jKCkpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgbTIucmVwZWF0ZWRfbmVzdGVkX2VudW0oaSArIDEwKSk7CisgIH0KK30KKworLy8gVGVzdCB0aGF0IEdldFJlcGVhdGVkRmllbGRSZWYvTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYgd29ya3Mgd2l0aAorLy8gRHluYW1pY01lc3NhZ2UuCitURVNUKFJlcGVhdGVkRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVwZWF0ZWRGaWVsZFJlZkR5bmFtaWNNZXNzYWdlKSB7CisgIC8vIER5bmFtaWNNZXNzYWdlIHNoYXJlcyB0aGUgc2FtZSBtZW1vcnkgbGF5b3V0IGFzIGdlbmVyYXRlZCBtZXNzYWdlCisgIC8vIGFuZCB1c2UgdGhlIHNhbWUgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24gY29kZSBmb3IgcmVmbGVjdGlvbi4KKyAgLy8gQWxsIGNvZGUgcGF0aHMgc2hvdWxkIGFscmVhZHkgYmUgY292ZXJlZCBieSB0aGUgb3RoZXIgdGVzdHMgZm9yCisgIC8vIGdlbmVyYXRlZCBtZXNzYWdlcy4gSGVyZSB3ZSBqdXN0IHRlc3Qgb25lIGZpZWxkLgorCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9pbnQzMiA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ludDMyIik7CisKKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gZHluYW1pY19tZXNzYWdlKGZhY3RvcnkuR2V0UHJvdG90eXBlKGRlc2MpLT5OZXcoKSk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmwgPSBkeW5hbWljX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4gcmZfaW50MzIgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50MzI+KAorICAgICAgICAgIGR5bmFtaWNfbWVzc2FnZS5nZXQoKSwgZmRfcmVwZWF0ZWRfaW50MzIpOworICByZl9pbnQzMi5BZGQoMTIzNCk7CisgIEVYUEVDVF9FUSgxLCByZWZsLT5GaWVsZFNpemUoKmR5bmFtaWNfbWVzc2FnZSwgZmRfcmVwZWF0ZWRfaW50MzIpKTsKKyAgRVhQRUNUX0VRKDEyMzQsIHJlZmwtPkdldFJlcGVhdGVkSW50MzIoKmR5bmFtaWNfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfcmVwZWF0ZWRfaW50MzIsIDApKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2ZTc0NTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTUwNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRPRE8oa2VudG9uKTogIEltcHJvdmUgdGhpcyB1bml0dGVzdCB0byBicmluZyBpdCB1cCB0byB0aGUgc3RhbmRhcmRzIG9mCisvLyAgIG90aGVyIHByb3RvMiB1bml0dGVzdHMuCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPGxpc3Q+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworLy8gVGVzdCBvcGVyYXRpb25zIG9uIGEgc21hbGwgUmVwZWF0ZWRGaWVsZC4KK1RFU1QoUmVwZWF0ZWRGaWVsZCwgU21hbGwpIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkOworCisgIEVYUEVDVF9UUlVFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAwKTsKKworICBmaWVsZC5BZGQoNSk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAxKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgNSk7CisKKyAgZmllbGQuQWRkKDQyKTsKKworICBFWFBFQ1RfRkFMU0UoZmllbGQuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQuR2V0KDApLCA1KTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgxKSwgNDIpOworCisgIGZpZWxkLlNldCgxLCAyMyk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMSksIDIzKTsKKworICBmaWVsZC5SZW1vdmVMYXN0KCk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAxKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgNSk7CisKKyAgZmllbGQuQ2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMCk7CisgIC8vIEFkZGl0aW9uYWwgYnl0ZXMgYXJlIGZvciAnc3RydWN0IFJlcCcgaGVhZGVyLgorICBpbnQgZXhwZWN0ZWRfdXNhZ2UgPSA0ICogc2l6ZW9mKGludCkgKyBzaXplb2YoQXJlbmEqKTsKKyAgRVhQRUNUX0VRKGZpZWxkLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSwgZXhwZWN0ZWRfdXNhZ2UpOworfQorCisKKy8vIFRlc3Qgb3BlcmF0aW9ucyBvbiBhIFJlcGVhdGVkRmllbGQgd2hpY2ggaXMgbGFyZ2UgZW5vdWdoIHRvIGFsbG9jYXRlIGEKKy8vIHNlcGFyYXRlIGFycmF5LgorVEVTVChSZXBlYXRlZEZpZWxkLCBMYXJnZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgZmllbGQuQWRkKGkgKiBpKTsKKyAgfQorCisgIEVYUEVDVF9GQUxTRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMTYpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZC5HZXQoaSksIGkgKiBpKTsKKyAgfQorCisgIGludCBleHBlY3RlZF91c2FnZSA9IDE2ICogc2l6ZW9mKGludCk7CisgIEVYUEVDVF9HRShmaWVsZC5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCksIGV4cGVjdGVkX3VzYWdlKTsKK30KKworLy8gVGVzdCBzd2FwcGluZyBiZXR3ZWVuIHZhcmlvdXMgdHlwZXMgb2YgUmVwZWF0ZWRGaWVsZHMuCitURVNUKFJlcGVhdGVkRmllbGQsIFN3YXBTbWFsbFNtYWxsKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDE7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDI7CisKKyAgZmllbGQxLkFkZCg1KTsKKyAgZmllbGQxLkFkZCg0Mik7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkMS5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZDEuR2V0KDEpLCA0Mik7CisKKyAgRVhQRUNUX1RSVUUoZmllbGQyLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQyLnNpemUoKSwgMCk7CisKKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisKKyAgRVhQRUNUX1RSVUUoZmllbGQxLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQxLnNpemUoKSwgMCk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQyLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZDIuR2V0KDEpLCA0Mik7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgU3dhcExhcmdlU21hbGwpIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkMTsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkMjsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICBmaWVsZDEuQWRkKGkgKiBpKTsKKyAgfQorICBmaWVsZDIuQWRkKDUpOworICBmaWVsZDIuQWRkKDQyKTsKKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZDEuR2V0KDEpLCA0Mik7CisgIEVYUEVDVF9FUShmaWVsZDIuc2l6ZSgpLCAxNik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZDIuR2V0KGkpLCBpICogaSk7CisgIH0KK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBTd2FwTGFyZ2VMYXJnZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQxOworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQyOworCisgIGZpZWxkMS5BZGQoNSk7CisgIGZpZWxkMS5BZGQoNDIpOworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICBmaWVsZDEuQWRkKGkpOworICAgIGZpZWxkMi5BZGQoaSAqIGkpOworICB9CisgIGZpZWxkMi5Td2FwKCZmaWVsZDEpOworCisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAxNik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZDEuR2V0KGkpLCBpICogaSk7CisgIH0KKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDE4KTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoMCksIDUpOworICBFWFBFQ1RfRVEoZmllbGQyLkdldCgxKSwgNDIpOworICBmb3IgKGludCBpID0gMjsgaSA8IDE4OyBpKyspIHsKKyAgICBFWFBFQ1RfRVEoZmllbGQyLkdldChpKSwgaSAtIDIpOworICB9Cit9CisKKy8vIERldGVybWluZXMgaG93IG11Y2ggc3BhY2Ugd2FzIHJlc2VydmVkIGJ5IHRoZSBnaXZlbiBmaWVsZCBieSBhZGRpbmcgZWxlbWVudHMKKy8vIHRvIGl0IHVudGlsIGl0IHJlLWFsbG9jYXRlcyBpdHMgc3BhY2UuCitzdGF0aWMgaW50IFJlc2VydmVkU3BhY2UoUmVwZWF0ZWRGaWVsZDxpbnQ+KiBmaWVsZCkgeworICBjb25zdCBpbnQqIHB0ciA9IGZpZWxkLT5kYXRhKCk7CisgIGRvIHsKKyAgICBmaWVsZC0+QWRkKDApOworICB9IHdoaWxlIChmaWVsZC0+ZGF0YSgpID09IHB0cik7CisKKyAgcmV0dXJuIGZpZWxkLT5zaXplKCkgLSAxOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFJlc2VydmVNb3JlVGhhbkRvdWJsZSkgeworICAvLyBSZXNlcnZlIG1vcmUgdGhhbiBkb3VibGUgdGhlIHByZXZpb3VzIHNwYWNlIGluIHRoZSBmaWVsZCBhbmQgZXhwZWN0IHRoZQorICAvLyBmaWVsZCB0byByZXNlcnZlIGV4YWN0bHkgdGhlIGFtb3VudCBzcGVjaWZpZWQuCisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDsKKyAgZmllbGQuUmVzZXJ2ZSgyMCk7CisKKyAgRVhQRUNUX0VRKDIwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFJlc2VydmVMZXNzVGhhbkRvdWJsZSkgeworICAvLyBSZXNlcnZlIGxlc3MgdGhhbiBkb3VibGUgdGhlIHByZXZpb3VzIHNwYWNlIGluIHRoZSBmaWVsZCBhbmQgZXhwZWN0IHRoZQorICAvLyBmaWVsZCB0byBncm93IGJ5IGRvdWJsZSBpbnN0ZWFkLgorICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLlJlc2VydmUoMjApOworICBmaWVsZC5SZXNlcnZlKDMwKTsKKworICBFWFBFQ1RfRVEoNDAsIFJlc2VydmVkU3BhY2UoJmZpZWxkKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgUmVzZXJ2ZUxlc3NUaGFuRXhpc3RpbmcpIHsKKyAgLy8gUmVzZXJ2ZSBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNwYWNlIGluIHRoZSBmaWVsZCBhbmQgZXhwZWN0IHRoZQorICAvLyBmaWVsZCB0byBub3QgcmUtYWxsb2NhdGUgYXQgYWxsLgorICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLlJlc2VydmUoMjApOworICBjb25zdCBpbnQqIHByZXZpb3VzX3B0ciA9IGZpZWxkLmRhdGEoKTsKKyAgZmllbGQuUmVzZXJ2ZSgxMCk7CisKKyAgRVhQRUNUX0VRKHByZXZpb3VzX3B0ciwgZmllbGQuZGF0YSgpKTsKKyAgRVhQRUNUX0VRKDIwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFJlc2l6ZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLlJlc2l6ZSgyLCAxKTsKKyAgRVhQRUNUX0VRKDIsIGZpZWxkLnNpemUoKSk7CisgIGZpZWxkLlJlc2l6ZSg1LCAyKTsKKyAgRVhQRUNUX0VRKDUsIGZpZWxkLnNpemUoKSk7CisgIGZpZWxkLlJlc2l6ZSg0LCAzKTsKKyAgQVNTRVJUX0VRKDQsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBmaWVsZC5HZXQoMCkpOworICBFWFBFQ1RfRVEoMSwgZmllbGQuR2V0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIGZpZWxkLkdldCgyKSk7CisgIEVYUEVDVF9FUSgyLCBmaWVsZC5HZXQoMykpOworICBmaWVsZC5SZXNpemUoMCwgNCk7CisgIEVYUEVDVF9UUlVFKGZpZWxkLmVtcHR5KCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIE1lcmdlRnJvbSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gc291cmNlLCBkZXN0aW5hdGlvbjsKKyAgc291cmNlLkFkZCg0KTsKKyAgc291cmNlLkFkZCg1KTsKKyAgZGVzdGluYXRpb24uQWRkKDEpOworICBkZXN0aW5hdGlvbi5BZGQoMik7CisgIGRlc3RpbmF0aW9uLkFkZCgzKTsKKworICBkZXN0aW5hdGlvbi5NZXJnZUZyb20oc291cmNlKTsKKworICBBU1NFUlRfRVEoNSwgZGVzdGluYXRpb24uc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIGRlc3RpbmF0aW9uLkdldCgwKSk7CisgIEVYUEVDVF9FUSgyLCBkZXN0aW5hdGlvbi5HZXQoMSkpOworICBFWFBFQ1RfRVEoMywgZGVzdGluYXRpb24uR2V0KDIpKTsKKyAgRVhQRUNUX0VRKDQsIGRlc3RpbmF0aW9uLkdldCgzKSk7CisgIEVYUEVDVF9FUSg1LCBkZXN0aW5hdGlvbi5HZXQoNCkpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgTWVyZ2VGcm9tU2VsZikgeworICBSZXBlYXRlZEZpZWxkPGludD4gbWU7CisgIG1lLkFkZCgzKTsKKyAgRVhQRUNUX0RFQVRIKG1lLk1lcmdlRnJvbShtZSksICIiKTsKK30KKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChSZXBlYXRlZEZpZWxkLCBDb3B5RnJvbSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gc291cmNlLCBkZXN0aW5hdGlvbjsKKyAgc291cmNlLkFkZCg0KTsKKyAgc291cmNlLkFkZCg1KTsKKyAgZGVzdGluYXRpb24uQWRkKDEpOworICBkZXN0aW5hdGlvbi5BZGQoMik7CisgIGRlc3RpbmF0aW9uLkFkZCgzKTsKKworICBkZXN0aW5hdGlvbi5Db3B5RnJvbShzb3VyY2UpOworCisgIEFTU0VSVF9FUSgyLCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoNCwgZGVzdGluYXRpb24uR2V0KDApKTsKKyAgRVhQRUNUX0VRKDUsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgQ29weUZyb21TZWxmKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBtZTsKKyAgbWUuQWRkKDMpOworICBtZS5Db3B5RnJvbShtZSk7CisgIEFTU0VSVF9FUSgxLCBtZS5zaXplKCkpOworICBFWFBFQ1RfRVEoMywgbWUuR2V0KDApKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBFcmFzZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gbWU7CisgIFJlcGVhdGVkRmllbGQ8aW50Pjo6aXRlcmF0b3IgaXQgPSBtZS5lcmFzZShtZS5iZWdpbigpLCBtZS5lbmQoKSk7CisgIEVYUEVDVF9UUlVFKG1lLmJlZ2luKCkgPT0gaXQpOworICBFWFBFQ1RfRVEoMCwgbWUuc2l6ZSgpKTsKKworICBtZS5BZGQoMSk7CisgIG1lLkFkZCgyKTsKKyAgbWUuQWRkKDMpOworICBpdCA9IG1lLmVyYXNlKG1lLmJlZ2luKCksIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSA9PSBpdCk7CisgIEVYUEVDVF9FUSgwLCBtZS5zaXplKCkpOworCisgIG1lLkFkZCg0KTsKKyAgbWUuQWRkKDUpOworICBtZS5BZGQoNik7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSArIDIsIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSArIDIgPT0gaXQpOworICBFWFBFQ1RfRVEoMiwgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQsIG1lLkdldCgwKSk7CisgIEVYUEVDVF9FUSg1LCBtZS5HZXQoMSkpOworCisgIG1lLkFkZCg2KTsKKyAgbWUuQWRkKDcpOworICBtZS5BZGQoOCk7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSArIDEsIG1lLmJlZ2luKCkgKyAzKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSArIDEgPT0gaXQpOworICBFWFBFQ1RfRVEoMywgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQsIG1lLkdldCgwKSk7CisgIEVYUEVDVF9FUSg3LCBtZS5HZXQoMSkpOworICBFWFBFQ1RfRVEoOCwgbWUuR2V0KDIpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBDb3B5Q29uc3RydWN0KSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBzb3VyY2U7CisgIHNvdXJjZS5BZGQoMSk7CisgIHNvdXJjZS5BZGQoMik7CisKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGRlc3RpbmF0aW9uKHNvdXJjZSk7CisKKyAgQVNTRVJUX0VRKDIsIGRlc3RpbmF0aW9uLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBkZXN0aW5hdGlvbi5HZXQoMCkpOworICBFWFBFQ1RfRVEoMiwgZGVzdGluYXRpb24uR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBJdGVyYXRvckNvbnN0cnVjdCkgeworICB2ZWN0b3I8aW50PiB2YWx1ZXM7CisgIHZhbHVlcy5wdXNoX2JhY2soMSk7CisgIHZhbHVlcy5wdXNoX2JhY2soMik7CisKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgZmllbGQuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXSwgZmllbGQuR2V0KDApKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXSwgZmllbGQuR2V0KDEpKTsKKworICBSZXBlYXRlZEZpZWxkPGludD4gb3RoZXIoZmllbGQuYmVnaW4oKSwgZmllbGQuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXSwgb3RoZXIuR2V0KDApKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXSwgb3RoZXIuR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBDb3B5QXNzaWduKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBzb3VyY2UsIGRlc3RpbmF0aW9uOworICBzb3VyY2UuQWRkKDQpOworICBzb3VyY2UuQWRkKDUpOworICBkZXN0aW5hdGlvbi5BZGQoMSk7CisgIGRlc3RpbmF0aW9uLkFkZCgyKTsKKyAgZGVzdGluYXRpb24uQWRkKDMpOworCisgIGRlc3RpbmF0aW9uID0gc291cmNlOworCisgIEFTU0VSVF9FUSgyLCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoNCwgZGVzdGluYXRpb24uR2V0KDApKTsKKyAgRVhQRUNUX0VRKDUsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgU2VsZkFzc2lnbikgeworICAvLyBWZXJpZnkgdGhhdCBhc3NpZ25tZW50IHRvIHNlbGYgZG9lcyBub3QgZGVzdHJveSBkYXRhLgorICBSZXBlYXRlZEZpZWxkPGludD4gc291cmNlLCAqcDsKKyAgcCA9ICZzb3VyY2U7CisgIHNvdXJjZS5BZGQoNyk7CisgIHNvdXJjZS5BZGQoOCk7CisKKyAgKnAgPSBzb3VyY2U7CisKKyAgQVNTRVJUX0VRKDIsIHNvdXJjZS5zaXplKCkpOworICBFWFBFQ1RfRVEoNywgc291cmNlLkdldCgwKSk7CisgIEVYUEVDVF9FUSg4LCBzb3VyY2UuR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBNdXRhYmxlRGF0YUlzTXV0YWJsZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLkFkZCgxKTsKKyAgRVhQRUNUX0VRKDEsIGZpZWxkLkdldCgwKSk7CisgIC8vIFRoZSBmYWN0IHRoYXQgdGhpcyBsaW5lIGNvbXBpbGVzIHdvdWxkIGJlIGVub3VnaCwgYnV0IHdlJ2xsIGNoZWNrIHRoZQorICAvLyB2YWx1ZSBhbnl3YXkuCisgICpmaWVsZC5tdXRhYmxlX2RhdGEoKSA9IDI7CisgIEVYUEVDVF9FUSgyLCBmaWVsZC5HZXQoMCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFRydW5jYXRlKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDsKKworICBmaWVsZC5BZGQoMTIpOworICBmaWVsZC5BZGQoMzQpOworICBmaWVsZC5BZGQoNTYpOworICBmaWVsZC5BZGQoNzgpOworICBFWFBFQ1RfRVEoNCwgZmllbGQuc2l6ZSgpKTsKKworICBmaWVsZC5UcnVuY2F0ZSgzKTsKKyAgRVhQRUNUX0VRKDMsIGZpZWxkLnNpemUoKSk7CisKKyAgZmllbGQuQWRkKDkwKTsKKyAgRVhQRUNUX0VRKDQsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSg5MCwgZmllbGQuR2V0KDMpKTsKKworICAvLyBUcnVuY2F0aW9ucyB0aGF0IGRvbid0IGNoYW5nZSB0aGUgc2l6ZSBhcmUgYWxsb3dlZCwgYnV0IGdyb3dpbmcgaXMgbm90CisgIC8vIGFsbG93ZWQuCisgIGZpZWxkLlRydW5jYXRlKGZpZWxkLnNpemUoKSk7CisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKGZpZWxkLlRydW5jYXRlKGZpZWxkLnNpemUoKSArIDEpLCAibmV3X3NpemUiKTsKKyNlbmRpZgorfQorCisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgRXh0cmFjdFN1YnJhbmdlKSB7CisgIC8vIEV4aGF1c3RpdmVseSB0ZXN0IGV2ZXJ5IHN1YnJhbmdlIGluIGFycmF5cyBvZiBhbGwgc2l6ZXMgZnJvbSAwIHRocm91Z2ggOS4KKyAgZm9yIChpbnQgc3ogPSAwOyBzeiA8IDEwOyArK3N6KSB7CisgICAgZm9yIChpbnQgbnVtID0gMDsgbnVtIDw9IHN6OyArK251bSkgeworICAgICAgZm9yIChpbnQgc3RhcnQgPSAwOyBzdGFydCA8IHN6IC0gbnVtOyArK3N0YXJ0KSB7CisgICAgICAgIC8vIENyZWF0ZSBSZXBlYXRlZEZpZWxkIHdpdGggc3ogZWxlbWVudHMgaGF2aW5nIHZhbHVlcyAwIHRocm91Z2ggc3otMS4KKyAgICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQzMj4gZmllbGQ7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3o7ICsraSkKKyAgICAgICAgICBmaWVsZC5BZGQoaSk7CisgICAgICAgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIHN6KTsKKworICAgICAgICAvLyBDcmVhdGUgYSBjYXRjaGVyIGFycmF5IGFuZCBjYWxsIEV4dHJhY3RTdWJyYW5nZS4KKyAgICAgICAgaW50MzIgY2F0Y2hlclsxMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkKKyAgICAgICAgICBjYXRjaGVyW2ldID0gLTE7CisgICAgICAgIGZpZWxkLkV4dHJhY3RTdWJyYW5nZShzdGFydCwgbnVtLCBjYXRjaGVyKTsKKworICAgICAgICAvLyBEb2VzIHRoZSByZXN1bHRpbmcgYXJyYXkgaGF2ZSB0aGUgcmlnaHQgc2l6ZT8KKyAgICAgICAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgc3ogLSBudW0pOworCisgICAgICAgIC8vIFdlcmUgdGhlIHJlbW92ZWQgZWxlbWVudHMgZXh0cmFjdGVkIGludG8gdGhlIGNhdGNoZXIgYXJyYXk/CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpCisgICAgICAgICAgRVhQRUNUX0VRKGNhdGNoZXJbaV0sIHN0YXJ0ICsgaSk7CisgICAgICAgIEVYUEVDVF9FUShjYXRjaGVyW251bV0sIC0xKTsKKworICAgICAgICAvLyBEb2VzIHRoZSByZXN1bHRpbmcgYXJyYXkgY29udGFpbiB0aGUgcmlnaHQgdmFsdWVzPworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YXJ0OyArK2kpCisgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLkdldChpKSwgaSk7CisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGZpZWxkLnNpemUoKTsgKytpKQorICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5HZXQoaSksIGkgKyBudW0pOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBSZXBlYXRlZFB0ckZpZWxkIHRlc3RzLiAgVGhlc2UgcHJldHR5IG11Y2gganVzdCBtaXJyb3IgdGhlIFJlcGVhdGVkRmllbGQKKy8vIHRlc3RzIGFib3ZlLgorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFNtYWxsKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKworICBFWFBFQ1RfVFJVRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMCk7CisKKyAgZmllbGQuQWRkKCktPmFzc2lnbigiZm9vIik7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAxKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgImZvbyIpOworCisgIGZpZWxkLkFkZCgpLT5hc3NpZ24oImJhciIpOworCisgIEVYUEVDVF9GQUxTRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMik7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMCksICJmb28iKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgxKSwgImJhciIpOworCisgIGZpZWxkLk11dGFibGUoMSktPmFzc2lnbigiYmF6Iik7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgImZvbyIpOworICBFWFBFQ1RfRVEoZmllbGQuR2V0KDEpLCAiYmF6Iik7CisKKyAgZmllbGQuUmVtb3ZlTGFzdCgpOworCisgIEVYUEVDVF9GQUxTRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMSk7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMCksICJmb28iKTsKKworICBmaWVsZC5DbGVhcigpOworCisgIEVYUEVDVF9UUlVFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAwKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBMYXJnZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgKmZpZWxkLkFkZCgpICs9ICdhJyArIGk7CisgIH0KKworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAxNik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgRVhQRUNUX0VRKGZpZWxkLkdldChpKS5zaXplKCksIDEpOworICAgIEVYUEVDVF9FUShmaWVsZC5HZXQoaSlbMF0sICdhJyArIGkpOworICB9CisKKyAgaW50IG1pbl9leHBlY3RlZF91c2FnZSA9IDE2ICogc2l6ZW9mKHN0cmluZyk7CisgIEVYUEVDVF9HRShmaWVsZC5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCksIG1pbl9leHBlY3RlZF91c2FnZSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgU3dhcFNtYWxsU21hbGwpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkMTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkMjsKKworICBFWFBFQ1RfVFJVRShmaWVsZDEuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAwKTsKKyAgRVhQRUNUX1RSVUUoZmllbGQyLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQyLnNpemUoKSwgMCk7CisKKyAgZmllbGQxLkFkZCgpLT5hc3NpZ24oImZvbyIpOworICBmaWVsZDEuQWRkKCktPmFzc2lnbigiYmFyIik7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkMS5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgwKSwgImZvbyIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgxKSwgImJhciIpOworCisgIEVYUEVDVF9UUlVFKGZpZWxkMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDApOworCisgIGZpZWxkMS5Td2FwKCZmaWVsZDIpOworCisgIEVYUEVDVF9UUlVFKGZpZWxkMS5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDApOworCisgIEVYUEVDVF9FUShmaWVsZDIuc2l6ZSgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoMCksICJmb28iKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoMSksICJiYXIiKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBTd2FwTGFyZ2VTbWFsbCkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQxOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQyOworCisgIGZpZWxkMi5BZGQoKS0+YXNzaWduKCJmb28iKTsKKyAgZmllbGQyLkFkZCgpLT5hc3NpZ24oImJhciIpOworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICAqZmllbGQxLkFkZCgpICs9ICdhJyArIGk7CisgIH0KKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgwKSwgImZvbyIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgxKSwgImJhciIpOworICBFWFBFQ1RfRVEoZmllbGQyLnNpemUoKSwgMTYpOworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICBFWFBFQ1RfRVEoZmllbGQyLkdldChpKS5zaXplKCksIDEpOworICAgIEVYUEVDVF9FUShmaWVsZDIuR2V0KGkpWzBdLCAnYScgKyBpKTsKKyAgfQorfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFN3YXBMYXJnZUxhcmdlKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDE7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDI7CisKKyAgZmllbGQxLkFkZCgpLT5hc3NpZ24oImZvbyIpOworICBmaWVsZDEuQWRkKCktPmFzc2lnbigiYmFyIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgICpmaWVsZDEuQWRkKCkgKz0gJ0EnICsgaTsKKyAgICAqZmllbGQyLkFkZCgpICs9ICdhJyArIGk7CisgIH0KKyAgZmllbGQyLlN3YXAoJmZpZWxkMSk7CisKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDE2KTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgRVhQRUNUX0VRKGZpZWxkMS5HZXQoaSkuc2l6ZSgpLCAxKTsKKyAgICBFWFBFQ1RfRVEoZmllbGQxLkdldChpKVswXSwgJ2EnICsgaSk7CisgIH0KKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDE4KTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoMCksICJmb28iKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoMSksICJiYXIiKTsKKyAgZm9yIChpbnQgaSA9IDI7IGkgPCAxODsgaSsrKSB7CisgICAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoaSkuc2l6ZSgpLCAxKTsKKyAgICBFWFBFQ1RfRVEoZmllbGQyLkdldChpKVswXSwgJ0EnICsgaSAtIDIpOworICB9Cit9CisKK3N0YXRpYyBpbnQgUmVzZXJ2ZWRTcGFjZShSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qIGZpZWxkKSB7CisgIGNvbnN0IHN0cmluZyogY29uc3QqIHB0ciA9IGZpZWxkLT5kYXRhKCk7CisgIGRvIHsKKyAgICBmaWVsZC0+QWRkKCk7CisgIH0gd2hpbGUgKGZpZWxkLT5kYXRhKCkgPT0gcHRyKTsKKworICByZXR1cm4gZmllbGQtPnNpemUoKSAtIDE7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgUmVzZXJ2ZU1vcmVUaGFuRG91YmxlKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKyAgZmllbGQuUmVzZXJ2ZSgyMCk7CisKKyAgRVhQRUNUX0VRKDIwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFJlc2VydmVMZXNzVGhhbkRvdWJsZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisgIGZpZWxkLlJlc2VydmUoMjApOworICBmaWVsZC5SZXNlcnZlKDMwKTsKKworICBFWFBFQ1RfRVEoNDAsIFJlc2VydmVkU3BhY2UoJmZpZWxkKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgUmVzZXJ2ZUxlc3NUaGFuRXhpc3RpbmcpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkOworICBmaWVsZC5SZXNlcnZlKDIwKTsKKyAgY29uc3Qgc3RyaW5nKiBjb25zdCogcHJldmlvdXNfcHRyID0gZmllbGQuZGF0YSgpOworICBmaWVsZC5SZXNlcnZlKDEwKTsKKworICBFWFBFQ1RfRVEocHJldmlvdXNfcHRyLCBmaWVsZC5kYXRhKCkpOworICBFWFBFQ1RfRVEoMjAsIFJlc2VydmVkU3BhY2UoJmZpZWxkKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgUmVzZXJ2ZURvZXNudExvc2VBbGxvY2F0ZWQpIHsKKyAgLy8gQ2hlY2sgdGhhdCBhIGJ1ZyBpcyBmaXhlZDogIEFuIGVhcmxpZXIgaW1wbGVtZW50YXRpb24gb2YgUmVzZXJ2ZSgpCisgIC8vIGZhaWxlZCB0byBjb3B5IHBvaW50ZXJzIHRvIGFsbG9jYXRlZC1idXQtY2xlYXJlZCBvYmplY3RzLCBwb3NzaWJseQorICAvLyBsZWFkaW5nIHRvIHNlZ2ZhdWx0cy4KKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkOworICBzdHJpbmcqIGZpcnN0ID0gZmllbGQuQWRkKCk7CisgIGZpZWxkLlJlbW92ZUxhc3QoKTsKKworICBmaWVsZC5SZXNlcnZlKDIwKTsKKyAgRVhQRUNUX0VRKGZpcnN0LCBmaWVsZC5BZGQoKSk7Cit9CisKKy8vIENsZWFyaW5nIGVsZW1lbnRzIGlzIHRyaWNreSB3aXRoIFJlcGVhdGVkUHRyRmllbGRzIHNpbmNlIHRoZSBtZW1vcnkgZm9yCisvLyB0aGUgZWxlbWVudHMgaXMgcmV0YWluZWQgYW5kIHJldXNlZC4KK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgQ2xlYXJlZEVsZW1lbnRzKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKworICBzdHJpbmcqIG9yaWdpbmFsID0gZmllbGQuQWRkKCk7CisgICpvcmlnaW5hbCA9ICJmb28iOworCisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisKKyAgZmllbGQuUmVtb3ZlTGFzdCgpOworICBFWFBFQ1RfVFJVRShvcmlnaW5hbC0+ZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMSk7CisKKyAgRVhQRUNUX0VRKGZpZWxkLkFkZCgpLCBvcmlnaW5hbCk7ICAvLyBTaG91bGQgcmV0dXJuIHNhbWUgc3RyaW5nIGZvciByZXVzZS4KKworICBFWFBFQ1RfRVEoZmllbGQuUmVsZWFzZUxhc3QoKSwgb3JpZ2luYWwpOyAgLy8gV2UgdGFrZSBvd25lcnNoaXAuCisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisKKyAgRVhQRUNUX05FKGZpZWxkLkFkZCgpLCBvcmlnaW5hbCk7ICAvLyBTaG91bGQgTk9UIHJldHVybiB0aGUgc2FtZSBzdHJpbmcuCisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisKKyAgZmllbGQuQWRkQWxsb2NhdGVkKG9yaWdpbmFsKTsgIC8vIEdpdmUgb3duZXJzaGlwIGJhY2suCisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisgIEVYUEVDVF9FUShmaWVsZC5NdXRhYmxlKDEpLCBvcmlnaW5hbCk7CisKKyAgZmllbGQuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkNsZWFyZWRDb3VudCgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkLlJlbGVhc2VDbGVhcmVkKCksIG9yaWdpbmFsKTsgIC8vIFRha2Ugb3duZXJzaGlwIGFnYWluLgorICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDEpOworICBFWFBFQ1RfTkUoZmllbGQuQWRkKCksIG9yaWdpbmFsKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkNsZWFyZWRDb3VudCgpLCAwKTsKKyAgRVhQRUNUX05FKGZpZWxkLkFkZCgpLCBvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisKKyAgZmllbGQuQWRkQ2xlYXJlZChvcmlnaW5hbCk7ICAvLyBHaXZlIG93bmVyc2hpcCBiYWNrLCBidXQgYXMgYSBjbGVhcmVkIG9iamVjdC4KKyAgRVhQRUNUX0VRKGZpZWxkLkNsZWFyZWRDb3VudCgpLCAxKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkFkZCgpLCBvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7Cit9CisKKy8vIFRlc3QgYWxsIGNvZGUgcGF0aHMgaW4gQWRkQWxsb2NhdGVkKCkuCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIEFkZEFsb2NhdGVkKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKyAgd2hpbGUgKGZpZWxkLnNpemUoKSA8IGZpZWxkLkNhcGFjaXR5KCkpIHsKKyAgICBmaWVsZC5BZGQoKS0+YXNzaWduKCJmaWxsZXIiKTsKKyAgfQorCisgIGludCBpbmRleCA9IGZpZWxkLnNpemUoKTsKKworICAvLyBGaXJzdCBicmFuY2g6ICBGaWVsZCBpcyBhdCBjYXBhY2l0eSB3aXRoIG5vIGNsZWFyZWQgb2JqZWN0cy4KKyAgc3RyaW5nKiBmb28gPSBuZXcgc3RyaW5nKCJmb28iKTsKKyAgZmllbGQuQWRkQWxsb2NhdGVkKGZvbyk7CisgIEVYUEVDVF9FUShpbmRleCArIDEsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBmaWVsZC5DbGVhcmVkQ291bnQoKSk7CisgIEVYUEVDVF9FUShmb28sICZmaWVsZC5HZXQoaW5kZXgpKTsKKworICAvLyBMYXN0IGJyYW5jaDogIEZpZWxkIGlzIG5vdCBhdCBjYXBhY2l0eSBhbmQgdGhlcmUgYXJlIG5vIGNsZWFyZWQgb2JqZWN0cy4KKyAgc3RyaW5nKiBiYXIgPSBuZXcgc3RyaW5nKCJiYXIiKTsKKyAgZmllbGQuQWRkQWxsb2NhdGVkKGJhcik7CisgICsraW5kZXg7CisgIEVYUEVDVF9FUShpbmRleCArIDEsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBmaWVsZC5DbGVhcmVkQ291bnQoKSk7CisgIEVYUEVDVF9FUShiYXIsICZmaWVsZC5HZXQoaW5kZXgpKTsKKworICAvLyBUaGlyZCBicmFuY2g6ICBGaWVsZCBpcyBub3QgYXQgY2FwYWNpdHkgYW5kIHRoZXJlIGFyZSBubyBjbGVhcmVkIG9iamVjdHMuCisgIGZpZWxkLlJlbW92ZUxhc3QoKTsKKyAgc3RyaW5nKiBiYXogPSBuZXcgc3RyaW5nKCJiYXoiKTsKKyAgZmllbGQuQWRkQWxsb2NhdGVkKGJheik7CisgIEVYUEVDVF9FUShpbmRleCArIDEsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBmaWVsZC5DbGVhcmVkQ291bnQoKSk7CisgIEVYUEVDVF9FUShiYXosICZmaWVsZC5HZXQoaW5kZXgpKTsKKworICAvLyBTZWNvbmQgYnJhbmNoOiAgRmllbGQgaXMgYXQgY2FwYWNpdHkgYnV0IGhhcyBzb21lIGNsZWFyZWQgb2JqZWN0cy4KKyAgd2hpbGUgKGZpZWxkLnNpemUoKSA8IGZpZWxkLkNhcGFjaXR5KCkpIHsKKyAgICBmaWVsZC5BZGQoKS0+YXNzaWduKCJmaWxsZXIyIik7CisgIH0KKyAgZmllbGQuUmVtb3ZlTGFzdCgpOworICBpbmRleCA9IGZpZWxkLnNpemUoKTsKKyAgc3RyaW5nKiBxdXggPSBuZXcgc3RyaW5nKCJxdXgiKTsKKyAgZmllbGQuQWRkQWxsb2NhdGVkKHF1eCk7CisgIEVYUEVDVF9FUShpbmRleCArIDEsIGZpZWxkLnNpemUoKSk7CisgIC8vIFdlIHNob3VsZCBoYXZlIGRpc2NhcmRlZCB0aGUgY2xlYXJlZCBvYmplY3QuCisgIEVYUEVDVF9FUSgwLCBmaWVsZC5DbGVhcmVkQ291bnQoKSk7CisgIEVYUEVDVF9FUShxdXgsICZmaWVsZC5HZXQoaW5kZXgpKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBNZXJnZUZyb20pIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IHNvdXJjZSwgZGVzdGluYXRpb247CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCI0Iik7CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCI1Iik7CisgIGRlc3RpbmF0aW9uLkFkZCgpLT5hc3NpZ24oIjEiKTsKKyAgZGVzdGluYXRpb24uQWRkKCktPmFzc2lnbigiMiIpOworICBkZXN0aW5hdGlvbi5BZGQoKS0+YXNzaWduKCIzIik7CisKKyAgZGVzdGluYXRpb24uTWVyZ2VGcm9tKHNvdXJjZSk7CisKKyAgQVNTRVJUX0VRKDUsIGRlc3RpbmF0aW9uLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiMSIsIGRlc3RpbmF0aW9uLkdldCgwKSk7CisgIEVYUEVDVF9FUSgiMiIsIGRlc3RpbmF0aW9uLkdldCgxKSk7CisgIEVYUEVDVF9FUSgiMyIsIGRlc3RpbmF0aW9uLkdldCgyKSk7CisgIEVYUEVDVF9FUSgiNCIsIGRlc3RpbmF0aW9uLkdldCgzKSk7CisgIEVYUEVDVF9FUSgiNSIsIGRlc3RpbmF0aW9uLkdldCg0KSk7Cit9CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBNZXJnZUZyb21TZWxmKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBtZTsKKyAgbWUuQWRkKCktPmFzc2lnbigiMSIpOworICBFWFBFQ1RfREVBVEgobWUuTWVyZ2VGcm9tKG1lKSwgIiIpOworfQorI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIENvcHlGcm9tKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBzb3VyY2UsIGRlc3RpbmF0aW9uOworICBzb3VyY2UuQWRkKCktPmFzc2lnbigiNCIpOworICBzb3VyY2UuQWRkKCktPmFzc2lnbigiNSIpOworICBkZXN0aW5hdGlvbi5BZGQoKS0+YXNzaWduKCIxIik7CisgIGRlc3RpbmF0aW9uLkFkZCgpLT5hc3NpZ24oIjIiKTsKKyAgZGVzdGluYXRpb24uQWRkKCktPmFzc2lnbigiMyIpOworCisgIGRlc3RpbmF0aW9uLkNvcHlGcm9tKHNvdXJjZSk7CisKKyAgQVNTRVJUX0VRKDIsIGRlc3RpbmF0aW9uLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiNCIsIGRlc3RpbmF0aW9uLkdldCgwKSk7CisgIEVYUEVDVF9FUSgiNSIsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgQ29weUZyb21TZWxmKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBtZTsKKyAgbWUuQWRkKCktPmFzc2lnbigiMSIpOworICBtZS5Db3B5RnJvbShtZSk7CisgIEFTU0VSVF9FUSgxLCBtZS5zaXplKCkpOworICBFWFBFQ1RfRVEoIjEiLCBtZS5HZXQoMCkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIEVyYXNlKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBtZTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+OjppdGVyYXRvciBpdCA9IG1lLmVyYXNlKG1lLmJlZ2luKCksIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSA9PSBpdCk7CisgIEVYUEVDVF9FUSgwLCBtZS5zaXplKCkpOworCisgICptZS5BZGQoKSA9ICIxIjsKKyAgKm1lLkFkZCgpID0gIjIiOworICAqbWUuQWRkKCkgPSAiMyI7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSwgbWUuZW5kKCkpOworICBFWFBFQ1RfVFJVRShtZS5iZWdpbigpID09IGl0KTsKKyAgRVhQRUNUX0VRKDAsIG1lLnNpemUoKSk7CisKKyAgKm1lLkFkZCgpID0gIjQiOworICAqbWUuQWRkKCkgPSAiNSI7CisgICptZS5BZGQoKSA9ICI2IjsKKyAgaXQgPSBtZS5lcmFzZShtZS5iZWdpbigpICsgMiwgbWUuZW5kKCkpOworICBFWFBFQ1RfVFJVRShtZS5iZWdpbigpICsgMiA9PSBpdCk7CisgIEVYUEVDVF9FUSgyLCBtZS5zaXplKCkpOworICBFWFBFQ1RfRVEoIjQiLCBtZS5HZXQoMCkpOworICBFWFBFQ1RfRVEoIjUiLCBtZS5HZXQoMSkpOworCisgICptZS5BZGQoKSA9ICI2IjsKKyAgKm1lLkFkZCgpID0gIjciOworICAqbWUuQWRkKCkgPSAiOCI7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSArIDEsIG1lLmJlZ2luKCkgKyAzKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSArIDEgPT0gaXQpOworICBFWFBFQ1RfRVEoMywgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCI0IiwgbWUuR2V0KDApKTsKKyAgRVhQRUNUX0VRKCI3IiwgbWUuR2V0KDEpKTsKKyAgRVhQRUNUX0VRKCI4IiwgbWUuR2V0KDIpKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBDb3B5Q29uc3RydWN0KSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBzb3VyY2U7CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCIxIik7CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCIyIik7CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGRlc3RpbmF0aW9uKHNvdXJjZSk7CisKKyAgQVNTRVJUX0VRKDIsIGRlc3RpbmF0aW9uLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiMSIsIGRlc3RpbmF0aW9uLkdldCgwKSk7CisgIEVYUEVDVF9FUSgiMiIsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgSXRlcmF0b3JDb25zdHJ1Y3RfU3RyaW5nKSB7CisgIHZlY3RvcjxzdHJpbmc+IHZhbHVlczsKKyAgdmFsdWVzLnB1c2hfYmFjaygiMSIpOworICB2YWx1ZXMucHVzaF9iYWNrKCIyIik7CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgZmllbGQuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXSwgZmllbGQuR2V0KDApKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXSwgZmllbGQuR2V0KDEpKTsKKworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gb3RoZXIoZmllbGQuYmVnaW4oKSwgZmllbGQuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXSwgb3RoZXIuR2V0KDApKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXSwgb3RoZXIuR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBJdGVyYXRvckNvbnN0cnVjdF9Qcm90bykgeworICB0eXBlZGVmIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSBOZXN0ZWQ7CisgIHZlY3RvcjxOZXN0ZWQ+IHZhbHVlczsKKyAgdmFsdWVzLnB1c2hfYmFjayhOZXN0ZWQoKSk7CisgIHZhbHVlcy5iYWNrKCkuc2V0X2JiKDEpOworICB2YWx1ZXMucHVzaF9iYWNrKE5lc3RlZCgpKTsKKyAgdmFsdWVzLmJhY2soKS5zZXRfYmIoMik7CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDxOZXN0ZWQ+IGZpZWxkKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgZmllbGQuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXS5iYigpLCBmaWVsZC5HZXQoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMV0uYmIoKSwgZmllbGQuR2V0KDEpLmJiKCkpOworCisgIFJlcGVhdGVkUHRyRmllbGQ8TmVzdGVkPiBvdGhlcihmaWVsZC5iZWdpbigpLCBmaWVsZC5lbmQoKSk7CisgIEFTU0VSVF9FUSh2YWx1ZXMuc2l6ZSgpLCBvdGhlci5zaXplKCkpOworICBFWFBFQ1RfRVEodmFsdWVzWzBdLmJiKCksIG90aGVyLkdldCgwKS5iYigpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXS5iYigpLCBvdGhlci5HZXQoMSkuYmIoKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgQ29weUFzc2lnbikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gc291cmNlLCBkZXN0aW5hdGlvbjsKKyAgc291cmNlLkFkZCgpLT5hc3NpZ24oIjQiKTsKKyAgc291cmNlLkFkZCgpLT5hc3NpZ24oIjUiKTsKKyAgZGVzdGluYXRpb24uQWRkKCktPmFzc2lnbigiMSIpOworICBkZXN0aW5hdGlvbi5BZGQoKS0+YXNzaWduKCIyIik7CisgIGRlc3RpbmF0aW9uLkFkZCgpLT5hc3NpZ24oIjMiKTsKKworICBkZXN0aW5hdGlvbiA9IHNvdXJjZTsKKworICBBU1NFUlRfRVEoMiwgZGVzdGluYXRpb24uc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCI0IiwgZGVzdGluYXRpb24uR2V0KDApKTsKKyAgRVhQRUNUX0VRKCI1IiwgZGVzdGluYXRpb24uR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBTZWxmQXNzaWduKSB7CisgIC8vIFZlcmlmeSB0aGF0IGFzc2lnbm1lbnQgdG8gc2VsZiBkb2VzIG5vdCBkZXN0cm95IGRhdGEuCisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBzb3VyY2UsICpwOworICBwID0gJnNvdXJjZTsKKyAgc291cmNlLkFkZCgpLT5hc3NpZ24oIjciKTsKKyAgc291cmNlLkFkZCgpLT5hc3NpZ24oIjgiKTsKKworICAqcCA9IHNvdXJjZTsKKworICBBU1NFUlRfRVEoMiwgc291cmNlLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiNyIsIHNvdXJjZS5HZXQoMCkpOworICBFWFBFQ1RfRVEoIjgiLCBzb3VyY2UuR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBNdXRhYmxlRGF0YUlzTXV0YWJsZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisgICpmaWVsZC5BZGQoKSA9ICIxIjsKKyAgRVhQRUNUX0VRKCIxIiwgZmllbGQuR2V0KDApKTsKKyAgLy8gVGhlIGZhY3QgdGhhdCB0aGlzIGxpbmUgY29tcGlsZXMgd291bGQgYmUgZW5vdWdoLCBidXQgd2UnbGwgY2hlY2sgdGhlCisgIC8vIHZhbHVlIGFueXdheS4KKyAgc3RyaW5nKiogZGF0YSA9IGZpZWxkLm11dGFibGVfZGF0YSgpOworICAqKmRhdGEgPSAiMiI7CisgIEVYUEVDVF9FUSgiMiIsIGZpZWxkLkdldCgwKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgRXh0cmFjdFN1YnJhbmdlKSB7CisgIC8vIEV4aGF1c3RpdmVseSB0ZXN0IGV2ZXJ5IHN1YnJhbmdlIGluIGFycmF5cyBvZiBhbGwgc2l6ZXMgZnJvbSAwIHRocm91Z2ggOQorICAvLyB3aXRoIDAgdGhyb3VnaCAzIGNsZWFyZWQgZWxlbWVudHMgYXQgdGhlIGVuZC4KKyAgZm9yIChpbnQgc3ogPSAwOyBzeiA8IDEwOyArK3N6KSB7CisgICAgZm9yIChpbnQgbnVtID0gMDsgbnVtIDw9IHN6OyArK251bSkgeworICAgICAgZm9yIChpbnQgc3RhcnQgPSAwOyBzdGFydCA8IHN6IC0gbnVtOyArK3N0YXJ0KSB7CisgICAgICAgIGZvciAoaW50IGV4dHJhID0gMDsgZXh0cmEgPCA0OyArK2V4dHJhKSB7CisgICAgICAgICAgdmVjdG9yPHN0cmluZyo+IHN1YmplY3Q7CisKKyAgICAgICAgICAvLyBDcmVhdGUgYW4gYXJyYXkgd2l0aCAic3oiIGVsZW1lbnRzIGFuZCAiZXh0cmEiIGNsZWFyZWQgZWxlbWVudHMuCisgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkOworICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3ogKyBleHRyYTsgKytpKSB7CisgICAgICAgICAgICBzdWJqZWN0LnB1c2hfYmFjayhuZXcgc3RyaW5nKCkpOworICAgICAgICAgICAgZmllbGQuQWRkQWxsb2NhdGVkKHN1YmplY3RbaV0pOworICAgICAgICAgIH0KKyAgICAgICAgICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCBzeiArIGV4dHJhKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4dHJhOyArK2kpCisgICAgICAgICAgICBmaWVsZC5SZW1vdmVMYXN0KCk7CisgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgc3opOworICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgZXh0cmEpOworCisgICAgICAgICAgLy8gQ3JlYXRlIGEgY2F0Y2hlciBhcnJheSBhbmQgY2FsbCBFeHRyYWN0U3VicmFuZ2UuCisgICAgICAgICAgc3RyaW5nKiBjYXRjaGVyWzEwXTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpCisgICAgICAgICAgICBjYXRjaGVyW2ldID0gTlVMTDsKKyAgICAgICAgICBmaWVsZC5FeHRyYWN0U3VicmFuZ2Uoc3RhcnQsIG51bSwgY2F0Y2hlcik7CisKKyAgICAgICAgICAvLyBEb2VzIHRoZSByZXN1bHRpbmcgYXJyYXkgaGF2ZSB0aGUgcmlnaHQgc2l6ZT8KKyAgICAgICAgICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCBzeiAtIG51bSk7CisKKyAgICAgICAgICAvLyBXZXJlIHRoZSByZW1vdmVkIGVsZW1lbnRzIGV4dHJhY3RlZCBpbnRvIHRoZSBjYXRjaGVyIGFycmF5PworICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpCisgICAgICAgICAgICBFWFBFQ1RfRVEoY2F0Y2hlcltpXSwgc3ViamVjdFtzdGFydCArIGldKTsKKyAgICAgICAgICBFWFBFQ1RfRVEoTlVMTCwgY2F0Y2hlcltudW1dKTsKKworICAgICAgICAgIC8vIERvZXMgdGhlIHJlc3VsdGluZyBhcnJheSBjb250YWluIHRoZSByaWdodCB2YWx1ZXM/CisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdGFydDsgKytpKQorICAgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLk11dGFibGUoaSksIHN1YmplY3RbaV0pOworICAgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGZpZWxkLnNpemUoKTsgKytpKQorICAgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLk11dGFibGUoaSksIHN1YmplY3RbaSArIG51bV0pOworCisgICAgICAgICAgLy8gUmVpbnN0YXRlIHRoZSBjbGVhcmVkIGVsZW1lbnRzLgorICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgZXh0cmEpOworICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0cmE7ICsraSkKKyAgICAgICAgICAgIGZpZWxkLkFkZCgpOworICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgc3ogLSBudW0gKyBleHRyYSk7CisKKyAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGV4dHJhIGVsZW1lbnRzIGFyZSBhbGwgdGhlcmUgKGluIHNvbWUgb3JkZXIpLgorICAgICAgICAgIGZvciAoaW50IGkgPSBzejsgaSA8IHN6ICsgZXh0cmE7ICsraSkgeworICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSBzejsgaiA8IHN6ICsgZXh0cmE7ICsraikgeworICAgICAgICAgICAgICBpZiAoZmllbGQuTXV0YWJsZShqIC0gbnVtKSA9PSBzdWJqZWN0W2ldKQorICAgICAgICAgICAgICAgIGNvdW50ICs9IDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBFWFBFQ1RfRVEoY291bnQsIDEpOworICAgICAgICAgIH0KKworICAgICAgICAgIC8vIFJlbGVhc2UgdGhlIGNhdWdodCBlbGVtZW50cy4KKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKQorICAgICAgICAgICAgZGVsZXRlIGNhdGNoZXJbaV07CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBEZWxldGVTdWJyYW5nZSkgeworICAvLyBEZWxldGVTdWJyYW5nZSBpcyBhIHRyaXZpYWwgZXh0ZW5zaW9uIG9mIEV4dGVuZFN1YnJhbmdlLgorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIEl0ZXJhdG9yIHRlc3RzIHN0b2xlbiBmcm9tIG5ldC9wcm90by9wcm90by1hcnJheV91bml0dGVzdC4KK2NsYXNzIFJlcGVhdGVkRmllbGRJdGVyYXRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyArK2kpIHsKKyAgICAgIHByb3RvX2FycmF5Xy5BZGQoaSk7CisgICAgfQorICB9CisKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IHByb3RvX2FycmF5XzsKK307CisKK1RFU1RfRihSZXBlYXRlZEZpZWxkSXRlcmF0b3JUZXN0LCBDb252ZXJ0aWJsZSkgeworICBSZXBlYXRlZEZpZWxkPGludD46Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+Ojpjb25zdF9pdGVyYXRvciBjX2l0ZXIgPSBpdGVyOworICBSZXBlYXRlZEZpZWxkPGludD46OnZhbHVlX3R5cGUgdmFsdWUgPSAqY19pdGVyOworICBFWFBFQ1RfRVEoMCwgdmFsdWUpOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEl0ZXJhdG9yVGVzdCwgTXV0YWJsZUl0ZXJhdGlvbikgeworICBSZXBlYXRlZEZpZWxkPGludD46Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgRVhQRUNUX0VRKDAsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfRVEoMSwgKml0ZXIrKyk7CisgIEVYUEVDVF9FUSgyLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX1RSVUUocHJvdG9fYXJyYXlfLmVuZCgpID09IGl0ZXIpOworCisgIEVYUEVDVF9FUSgyLCAqKHByb3RvX2FycmF5Xy5lbmQoKSAtIDEpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJdGVyYXRvclRlc3QsIENvbnN0SXRlcmF0aW9uKSB7CisgIGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50PiYgY29uc3RfcHJvdG9fYXJyYXkgPSBwcm90b19hcnJheV87CisgIFJlcGVhdGVkRmllbGQ8aW50Pjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGNvbnN0X3Byb3RvX2FycmF5LmJlZ2luKCk7CisgIEVYUEVDVF9FUSgwLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKDEsICppdGVyKyspOworICBFWFBFQ1RfRVEoMiwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9UUlVFKHByb3RvX2FycmF5Xy5lbmQoKSA9PSBpdGVyKTsKKyAgRVhQRUNUX0VRKDIsICoocHJvdG9fYXJyYXlfLmVuZCgpIC0gMSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEl0ZXJhdG9yVGVzdCwgTXV0YXRpb24pIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+OjppdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLmJlZ2luKCk7CisgICppdGVyID0gNzsKKyAgRVhQRUNUX0VRKDcsIHByb3RvX2FycmF5Xy5HZXQoMCkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImZvbyIpOworICAgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJiYXIiKTsKKyAgICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiYmF6Iik7CisgIH0KKworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gcHJvdG9fYXJyYXlfOworfTsKKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIENvbnZlcnRpYmxlKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6aXRlcmF0b3IgaXRlciA9IHByb3RvX2FycmF5Xy5iZWdpbigpOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OmNvbnN0X2l0ZXJhdG9yIGNfaXRlciA9IGl0ZXI7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6dmFsdWVfdHlwZSB2YWx1ZSA9ICpjX2l0ZXI7CisgIEVYUEVDVF9FUSgiZm9vIiwgdmFsdWUpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgTXV0YWJsZUl0ZXJhdGlvbikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgRVhQRUNUX0VRKCJmb28iLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKCJiYXIiLCAqKGl0ZXIrKykpOworICBFWFBFQ1RfRVEoImJheiIsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShwcm90b19hcnJheV8uZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgiYmF6IiwgKigtLXByb3RvX2FycmF5Xy5lbmQoKSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgQ29uc3RJdGVyYXRpb24pIHsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+JiBjb25zdF9wcm90b19hcnJheSA9IHByb3RvX2FycmF5XzsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gY29uc3RfcHJvdG9fYXJyYXkuYmVnaW4oKTsKKyAgRVhQRUNUX0VRKCJmb28iLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKCJiYXIiLCAqKGl0ZXIrKykpOworICBFWFBFQ1RfRVEoImJheiIsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShjb25zdF9wcm90b19hcnJheS5lbmQoKSA9PSBpdGVyKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqKC0tY29uc3RfcHJvdG9fYXJyYXkuZW5kKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIE11dGFibGVSZXZlcnNlSXRlcmF0aW9uKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6cmV2ZXJzZV9pdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLnJiZWdpbigpOworICBFWFBFQ1RfRVEoImJheiIsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfRVEoImJhciIsICooaXRlcisrKSk7CisgIEVYUEVDVF9FUSgiZm9vIiwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9UUlVFKHByb3RvX2FycmF5Xy5yZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgiZm9vIiwgKigtLXByb3RvX2FycmF5Xy5yZW5kKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIENvbnN0UmV2ZXJzZUl0ZXJhdGlvbikgeworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4mIGNvbnN0X3Byb3RvX2FycmF5ID0gcHJvdG9fYXJyYXlfOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OmNvbnN0X3JldmVyc2VfaXRlcmF0b3IgaXRlcgorICAgICAgPSBjb25zdF9wcm90b19hcnJheS5yYmVnaW4oKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKCJiYXIiLCAqKGl0ZXIrKykpOworICBFWFBFQ1RfRVEoImZvbyIsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShjb25zdF9wcm90b19hcnJheS5yZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgiZm9vIiwgKigtLWNvbnN0X3Byb3RvX2FycmF5LnJlbmQoKSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgUmFuZG9tQWNjZXNzKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6aXRlcmF0b3IgaXRlciA9IHByb3RvX2FycmF5Xy5iZWdpbigpOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46Oml0ZXJhdG9yIGl0ZXIyID0gaXRlcjsKKyAgKytpdGVyMjsKKyAgKytpdGVyMjsKKyAgRVhQRUNUX1RSVUUoaXRlciArIDIgPT0gaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyID09IGl0ZXIyIC0gMik7CisgIEVYUEVDVF9FUSgiYmF6IiwgaXRlclsyXSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgKihpdGVyICsgMikpOworICBFWFBFQ1RfRVEoMywgcHJvdG9fYXJyYXlfLmVuZCgpIC0gcHJvdG9fYXJyYXlfLmJlZ2luKCkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgQ29tcGFyYWJsZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdGVyMiA9IGl0ZXIgKyAxOworICBFWFBFQ1RfVFJVRShpdGVyID09IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8PSBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPD0gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIyID4gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIyID49IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyID49IGl0ZXIpOworfQorCisvLyBVbmluaXRpYWxpemVkIGl0ZXJhdG9yIGRvZXMgbm90IHBvaW50IHRvIGFueSBvZiB0aGUgUmVwZWF0ZWRQdHJGaWVsZC4KK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkSXRlcmF0b3JUZXN0LCBVbmluaXRpYWxpemVkSXRlcmF0b3IpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+OjppdGVyYXRvciBpdGVyOworICBFWFBFQ1RfVFJVRShpdGVyICE9IHByb3RvX2FycmF5Xy5iZWdpbigpKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8uYmVnaW4oKSArIDEpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IHByb3RvX2FycmF5Xy5iZWdpbigpICsgMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLmJlZ2luKCkgKyAzKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8uZW5kKCkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgU1RMQWxnb3JpdGhtc19sb3dlcl9ib3VuZCkgeworICBwcm90b19hcnJheV8uQ2xlYXIoKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImEiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImMiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImQiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oIm4iKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oInAiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oIngiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oInkiKTsKKworICBzdHJpbmcgdiA9ICJmIjsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdCA9CisgICAgICBzdGQ6Omxvd2VyX2JvdW5kKHByb3RvX2FycmF5Xy5iZWdpbigpLCBwcm90b19hcnJheV8uZW5kKCksIHYpOworCisgIEVYUEVDVF9FUSgqaXQsICJuIik7CisgIEVYUEVDVF9UUlVFKGl0ID09IHByb3RvX2FycmF5Xy5iZWdpbigpICsgMyk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkSXRlcmF0b3JUZXN0LCBNdXRhdGlvbikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgKml0ZXIgPSAicXV4IjsKKyAgRVhQRUNUX0VRKCJxdXgiLCBwcm90b19hcnJheV8uR2V0KDApKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBSZXBlYXRlZFB0ckZpZWxkUHRyc0l0ZXJhdG9yVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiZm9vIik7CisgICAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImJhciIpOworICAgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJiYXoiKTsKKyAgICBjb25zdF9wcm90b19hcnJheV8gPSAmcHJvdG9fYXJyYXlfOworICB9CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IHByb3RvX2FycmF5XzsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiBjb25zdF9wcm90b19hcnJheV87Cit9OworCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIENvbnZlcnRpYmxlUHRyKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6cG9pbnRlcl9pdGVyYXRvciBpdGVyID0KKyAgICAgIHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCk7CisgIHN0YXRpY19jYXN0PHZvaWQ+KGl0ZXIpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIENvbnZlcnRpYmxlQ29uc3RQdHIpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCk7CisgIHN0YXRpY19jYXN0PHZvaWQ+KGl0ZXIpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIE11dGFibGVQdHJJdGVyYXRpb24pIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpwb2ludGVyX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgcHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKTsKKyAgRVhQRUNUX0VRKCJmb28iLCAqKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUSgiYmFyIiwgKiooaXRlcisrKSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgKippdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShwcm90b19hcnJheV8ucG9pbnRlcl9lbmQoKSA9PSBpdGVyKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqKigtLXByb3RvX2FycmF5Xy5wb2ludGVyX2VuZCgpKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkUHRyc0l0ZXJhdG9yVGVzdCwgTXV0YWJsZUNvbnN0UHRySXRlcmF0aW9uKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvciBpdGVyID0KKyAgICAgIGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpOworICBFWFBFQ1RfRVEoImZvbyIsICoqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKCJiYXIiLCAqKihpdGVyKyspKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9UUlVFKGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9lbmQoKSA9PSBpdGVyKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqKigtLWNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9lbmQoKSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIFJhbmRvbVB0ckFjY2VzcykgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlcjIgPSBpdGVyOworICArK2l0ZXIyOworICArK2l0ZXIyOworICBFWFBFQ1RfVFJVRShpdGVyICsgMiA9PSBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPT0gaXRlcjIgLSAyKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqaXRlclsyXSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgKiooaXRlciArIDIpKTsKKyAgRVhQRUNUX0VRKDMsIHByb3RvX2FycmF5Xy5lbmQoKSAtIHByb3RvX2FycmF5Xy5iZWdpbigpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBSYW5kb21Db25zdFB0ckFjY2VzcykgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OmNvbnN0X3BvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfYmVnaW4oKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ZXIyID0gaXRlcjsKKyAgKytpdGVyMjsKKyAgKytpdGVyMjsKKyAgRVhQRUNUX1RSVUUoaXRlciArIDIgPT0gaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyID09IGl0ZXIyIC0gMik7CisgIEVYUEVDVF9FUSgiYmF6IiwgKml0ZXJbMl0pOworICBFWFBFQ1RfRVEoImJheiIsICoqKGl0ZXIgKyAyKSk7CisgIEVYUEVDVF9FUSgzLCBjb25zdF9wcm90b19hcnJheV8tPmVuZCgpIC0gY29uc3RfcHJvdG9fYXJyYXlfLT5iZWdpbigpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBDb21wYXJhYmxlUHRyKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6cG9pbnRlcl9pdGVyYXRvciBpdGVyID0KKyAgICAgIHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCk7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6cG9pbnRlcl9pdGVyYXRvciBpdGVyMiA9IGl0ZXIgKyAxOworICBFWFBFQ1RfVFJVRShpdGVyID09IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8PSBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPD0gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIyID4gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIyID49IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyID49IGl0ZXIpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIENvbXBhcmFibGVDb25zdFB0cikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OmNvbnN0X3BvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfYmVnaW4oKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ZXIyID0gaXRlciArIDE7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPT0gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyIDwgaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyIDw9IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8PSBpdGVyKTsKKyAgRVhQRUNUX1RSVUUoaXRlcjIgPiBpdGVyKTsKKyAgRVhQRUNUX1RSVUUoaXRlcjIgPj0gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPj0gaXRlcik7Cit9CisKKy8vIFVuaW5pdGlhbGl6ZWQgaXRlcmF0b3IgZG9lcyBub3QgcG9pbnQgdG8gYW55IG9mIHRoZSBSZXBlYXRlZFB0ck92ZXJQdHJzLgorLy8gRGVyZWZlcmVuY2luZyBhbiB1bmluaXRpYWxpemVkIGl0ZXJhdG9yIGNyYXNoZXMgdGhlIHByb2Nlc3MuCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIFVuaW5pdGlhbGl6ZWRQdHJJdGVyYXRvcikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlcjsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpICsgMSk7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKSArIDIpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCkgKyAzKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8ucG9pbnRlcl9lbmQoKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkUHRyc0l0ZXJhdG9yVGVzdCwgVW5pbml0aWFsaXplZENvbnN0UHRySXRlcmF0b3IpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ZXI7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCkpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpICsgMSk7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCkgKyAyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfYmVnaW4oKSArIDMpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9lbmQoKSk7Cit9CisKKy8vIFRoaXMgY29tcGFyaXNvbiBmdW5jdG9yIGlzIHJlcXVpcmVkIGJ5IHRoZSB0ZXN0cyBmb3IgUmVwZWF0ZWRQdHJPdmVyUHRycy4KKy8vIFRoZXkgb3BlcmF0ZSBvbiBzdHJpbmdzIGFuZCBuZWVkIHRvIGNvbXBhcmUgc3RyaW5ncyBhcyBzdHJpbmdzIGluCisvLyBhbnkgc3RsIGFsZ29yaXRobSwgZXZlbiB0aG91Z2ggdGhlIGl0ZXJhdG9yIHJldHVybnMgYSBwb2ludGVyIHRvIGEgc3RyaW5nCisvLyAtIGkuZS4gKml0ZXIgaGFzIHR5cGUgc3RyaW5nKi4KK3N0cnVjdCBTdHJpbmdMZXNzVGhhbiB7CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBzdHJpbmcqIHosIGNvbnN0IHN0cmluZyYgeSkgeworICAgIHJldHVybiAqeiA8IHk7CisgIH0KKyAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IHN0cmluZyogeiwgY29uc3Qgc3RyaW5nKiB5KSBjb25zdCB7IHJldHVybiAqeiA8ICp5OyB9Cit9OworCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIFB0clNUTEFsZ29yaXRobXNfbG93ZXJfYm91bmQpIHsKKyAgcHJvdG9fYXJyYXlfLkNsZWFyKCk7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJhIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJjIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJkIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJuIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJwIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJ4Iik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJ5Iik7CisKKyAgeworICAgIHN0cmluZyB2ID0gImYiOworICAgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6cG9pbnRlcl9pdGVyYXRvciBpdCA9CisgICAgICAgIHN0ZDo6bG93ZXJfYm91bmQocHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b19hcnJheV8ucG9pbnRlcl9lbmQoKSwgJnYsIFN0cmluZ0xlc3NUaGFuKCkpOworCisgICAgR09PR0xFX0NIRUNLKCppdCAhPSBOVUxMKTsKKworICAgIEVYUEVDVF9FUSgqKml0LCAibiIpOworICAgIEVYUEVDVF9UUlVFKGl0ID09IHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCkgKyAzKTsKKyAgfQorICB7CisgICAgc3RyaW5nIHYgPSAiZiI7CisgICAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ID0gc3RkOjpsb3dlcl9ib3VuZCgKKyAgICAgICAgY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCksIGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9lbmQoKSwKKyAgICAgICAgJnYsIFN0cmluZ0xlc3NUaGFuKCkpOworCisgICAgR09PR0xFX0NIRUNLKCppdCAhPSBOVUxMKTsKKworICAgIEVYUEVDVF9FUSgqKml0LCAibiIpOworICAgIEVYUEVDVF9UUlVFKGl0ID09IGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpICsgMyk7CisgIH0KK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBQdHJNdXRhdGlvbikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpOworICAqKml0ZXIgPSAicXV4IjsKKyAgRVhQRUNUX0VRKCJxdXgiLCBwcm90b19hcnJheV8uR2V0KDApKTsKKworICBFWFBFQ1RfRVEoImJhciIsIHByb3RvX2FycmF5Xy5HZXQoMSkpOworICBFWFBFQ1RfRVEoImJheiIsIHByb3RvX2FycmF5Xy5HZXQoMikpOworICArK2l0ZXI7CisgIGRlbGV0ZSAqaXRlcjsKKyAgKml0ZXIgPSBuZXcgc3RyaW5nKCJhIik7CisgICsraXRlcjsKKyAgZGVsZXRlICppdGVyOworICAqaXRlciA9IG5ldyBzdHJpbmcoImIiKTsKKyAgRVhQRUNUX0VRKCJhIiwgcHJvdG9fYXJyYXlfLkdldCgxKSk7CisgIEVYUEVDVF9FUSgiYiIsIHByb3RvX2FycmF5Xy5HZXQoMikpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIFNvcnQpIHsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImMiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImQiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oIm4iKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oInAiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImEiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oInkiKTsKKyAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oIngiKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBwcm90b19hcnJheV8uR2V0KDApKTsKKyAgRVhQRUNUX0VRKCJuIiwgcHJvdG9fYXJyYXlfLkdldCg1KSk7CisgIEVYUEVDVF9FUSgieCIsIHByb3RvX2FycmF5Xy5HZXQoOSkpOworICBzdGQ6OnNvcnQocHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKSwgcHJvdG9fYXJyYXlfLnBvaW50ZXJfZW5kKCksCisgICAgICAgICAgICBTdHJpbmdMZXNzVGhhbigpKTsKKyAgRVhQRUNUX0VRKCJhIiwgcHJvdG9fYXJyYXlfLkdldCgwKSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgcHJvdG9fYXJyYXlfLkdldCgyKSk7CisgIEVYUEVDVF9FUSgieSIsIHByb3RvX2FycmF5Xy5HZXQoOSkpOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBVbml0LXRlc3RzIGZvciB0aGUgaW5zZXJ0IGl0ZXJhdG9ycworLy8gZ29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlciwKKy8vIGdvb2dsZTo6cHJvdG9idWY6OkFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0ZXIKKy8vIFBvcnRlZCBmcm9tIHV0aWwvZ3RsL3Byb3RvLWFycmF5LWl0ZXJhdG9yc191bml0dGVzdC4KKworY2xhc3MgUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBzdGQ6Omxpc3Q8ZG91YmxlPiBoYWx2ZXM7CisgIHN0ZDo6bGlzdDxpbnQ+IGZpYm9uYWNjaTsKKyAgc3RkOjp2ZWN0b3I8c3RyaW5nPiB3b3JkczsKKyAgdHlwZWRlZiBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgTmVzdGVkOworICBOZXN0ZWQgbmVzdGVkc1syXTsKKyAgc3RkOjp2ZWN0b3I8TmVzdGVkKj4gbmVzdGVkX3B0cnM7CisgIFRlc3RBbGxUeXBlcyBwcm90b2J1ZmZlcjsKKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgZmlib25hY2NpLnB1c2hfYmFjaygxKTsKKyAgICBmaWJvbmFjY2kucHVzaF9iYWNrKDEpOworICAgIGZpYm9uYWNjaS5wdXNoX2JhY2soMik7CisgICAgZmlib25hY2NpLnB1c2hfYmFjaygzKTsKKyAgICBmaWJvbmFjY2kucHVzaF9iYWNrKDUpOworICAgIGZpYm9uYWNjaS5wdXNoX2JhY2soOCk7CisgICAgc3RkOjpjb3B5KGZpYm9uYWNjaS5iZWdpbigpLCBmaWJvbmFjY2kuZW5kKCksCisgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIocHJvdG9idWZmZXIubXV0YWJsZV9yZXBlYXRlZF9pbnQzMigpKSk7CisKKyAgICBoYWx2ZXMucHVzaF9iYWNrKDEuMCk7CisgICAgaGFsdmVzLnB1c2hfYmFjaygwLjUpOworICAgIGhhbHZlcy5wdXNoX2JhY2soMC4yNSk7CisgICAgaGFsdmVzLnB1c2hfYmFjaygwLjEyNSk7CisgICAgaGFsdmVzLnB1c2hfYmFjaygwLjA2MjUpOworICAgIHN0ZDo6Y29weShoYWx2ZXMuYmVnaW4oKSwgaGFsdmVzLmVuZCgpLAorICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkQmFja0luc2VydGVyKHByb3RvYnVmZmVyLm11dGFibGVfcmVwZWF0ZWRfZG91YmxlKCkpKTsKKworICAgIHdvcmRzLnB1c2hfYmFjaygiQWJsZSIpOworICAgIHdvcmRzLnB1c2hfYmFjaygid2FzIik7CisgICAgd29yZHMucHVzaF9iYWNrKCJJIik7CisgICAgd29yZHMucHVzaF9iYWNrKCJlcmUiKTsKKyAgICB3b3Jkcy5wdXNoX2JhY2soIkkiKTsKKyAgICB3b3Jkcy5wdXNoX2JhY2soInNhdyIpOworICAgIHdvcmRzLnB1c2hfYmFjaygiRWxiYSIpOworICAgIHN0ZDo6Y29weSh3b3Jkcy5iZWdpbigpLCB3b3Jkcy5lbmQoKSwKKyAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlcihwcm90b2J1ZmZlci5tdXRhYmxlX3JlcGVhdGVkX3N0cmluZygpKSk7CisKKyAgICBuZXN0ZWRzWzBdLnNldF9iYigxNyk7CisgICAgbmVzdGVkc1sxXS5zZXRfYmIoNDcxMSk7CisgICAgc3RkOjpjb3B5KCZuZXN0ZWRzWzBdLCAmbmVzdGVkc1syXSwKKyAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlcigKKyAgICAgICAgICAgICAgICAgIHByb3RvYnVmZmVyLm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKSkpOworCisgICAgbmVzdGVkX3B0cnMucHVzaF9iYWNrKG5ldyBOZXN0ZWQpOworICAgIG5lc3RlZF9wdHJzLmJhY2soKS0+c2V0X2JiKDE3MCk7CisgICAgbmVzdGVkX3B0cnMucHVzaF9iYWNrKG5ldyBOZXN0ZWQpOworICAgIG5lc3RlZF9wdHJzLmJhY2soKS0+c2V0X2JiKDQ3MTEwKTsKKyAgICBzdGQ6OmNvcHkobmVzdGVkX3B0cnMuYmVnaW4oKSwgbmVzdGVkX3B0cnMuZW5kKCksCisgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIoCisgICAgICAgICAgICAgICAgICBwcm90b2J1ZmZlci5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCkpKTsKKworICB9CisKKyAgdmlydHVhbCB2b2lkIFRlYXJEb3duKCkgeworICAgIFNUTERlbGV0ZUNvbnRhaW5lclBvaW50ZXJzKG5lc3RlZF9wdHJzLmJlZ2luKCksIG5lc3RlZF9wdHJzLmVuZCgpKTsKKyAgfQorfTsKKworVEVTVF9GKFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0LCBGaWJvbmFjY2kpIHsKKyAgRVhQRUNUX1RSVUUoc3RkOjplcXVhbChmaWJvbmFjY2kuYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBmaWJvbmFjY2kuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZmZXIucmVwZWF0ZWRfaW50MzIoKS5iZWdpbigpKSk7CisgIEVYUEVDVF9UUlVFKHN0ZDo6ZXF1YWwocHJvdG9idWZmZXIucmVwZWF0ZWRfaW50MzIoKS5iZWdpbigpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmZmVyLnJlcGVhdGVkX2ludDMyKCkuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgZmlib25hY2NpLmJlZ2luKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0LCBIYWx2ZXMpIHsKKyAgRVhQRUNUX1RSVUUoc3RkOjplcXVhbChoYWx2ZXMuYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBoYWx2ZXMuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZmZXIucmVwZWF0ZWRfZG91YmxlKCkuYmVnaW4oKSkpOworICBFWFBFQ1RfVFJVRShzdGQ6OmVxdWFsKHByb3RvYnVmZmVyLnJlcGVhdGVkX2RvdWJsZSgpLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZmZXIucmVwZWF0ZWRfZG91YmxlKCkuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgaGFsdmVzLmJlZ2luKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0LCBXb3JkcykgeworICBBU1NFUlRfRVEod29yZHMuc2l6ZSgpLCBwcm90b2J1ZmZlci5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB3b3Jkcy5zaXplKCk7ICsraSkKKyAgICBFWFBFQ1RfRVEod29yZHMuYXQoaSksIHByb3RvYnVmZmVyLnJlcGVhdGVkX3N0cmluZyhpKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZEZpZWxkSW5zZXJ0aW9uSXRlcmF0b3JzVGVzdCwgV29yZHMyKSB7CisgIHdvcmRzLmNsZWFyKCk7CisgIHdvcmRzLnB1c2hfYmFjaygic2luZyIpOworICB3b3Jkcy5wdXNoX2JhY2soImEiKTsKKyAgd29yZHMucHVzaF9iYWNrKCJzb25nIik7CisgIHdvcmRzLnB1c2hfYmFjaygib2YiKTsKKyAgd29yZHMucHVzaF9iYWNrKCJzaXgiKTsKKyAgd29yZHMucHVzaF9iYWNrKCJwZW5jZSIpOworICBwcm90b2J1ZmZlci5tdXRhYmxlX3JlcGVhdGVkX3N0cmluZygpLT5DbGVhcigpOworICBzdGQ6OmNvcHkod29yZHMuYmVnaW4oKSwgd29yZHMuZW5kKCksIFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0ZXIoCisgICAgICBwcm90b2J1ZmZlci5tdXRhYmxlX3JlcGVhdGVkX3N0cmluZygpKSk7CisgIEFTU0VSVF9FUSh3b3Jkcy5zaXplKCksIHByb3RvYnVmZmVyLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IHdvcmRzLnNpemUoKTsgKytpKQorICAgIEVYUEVDVF9FUSh3b3Jkcy5hdChpKSwgcHJvdG9idWZmZXIucmVwZWF0ZWRfc3RyaW5nKGkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0LCBOZXN0ZWRzKSB7CisgIEFTU0VSVF9FUShwcm90b2J1ZmZlci5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplKCksIDQpOworICBFWFBFQ1RfRVEocHJvdG9idWZmZXIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMCkuYmIoKSwgMTcpOworICBFWFBFQ1RfRVEocHJvdG9idWZmZXIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMSkuYmIoKSwgNDcxMSk7CisgIEVYUEVDVF9FUShwcm90b2J1ZmZlci5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgyKS5iYigpLCAxNzApOworICBFWFBFQ1RfRVEocHJvdG9idWZmZXIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMykuYmIoKSwgNDcxMTApOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QsCisgICAgICAgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZFdpdGhTdHJpbmdJbnREYXRhKSB7CisgIHZlY3RvcjxOZXN0ZWQqPiBkYXRhOworICBUZXN0QWxsVHlwZXMgZ29sZGVucHJvdG87CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIE5lc3RlZCogbmV3X2RhdGEgPSBuZXcgTmVzdGVkOworICAgIG5ld19kYXRhLT5zZXRfYmIoaSk7CisgICAgZGF0YS5wdXNoX2JhY2sobmV3X2RhdGEpOworCisgICAgbmV3X2RhdGEgPSBnb2xkZW5wcm90by5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKTsKKyAgICBuZXdfZGF0YS0+c2V0X2JiKGkpOworICB9CisgIFRlc3RBbGxUeXBlcyB0ZXN0cHJvdG87CisgIHN0ZDo6Y29weShkYXRhLmJlZ2luKCksIGRhdGEuZW5kKCksCisgICAgICAgICAgICBBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydGVyKAorICAgICAgICAgICAgICAgIHRlc3Rwcm90by5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCkpKTsKKyAgRVhQRUNUX0VRKHRlc3Rwcm90by5EZWJ1Z1N0cmluZygpLCBnb2xkZW5wcm90by5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0LAorICAgICAgIEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRXaXRoU3RyaW5nKSB7CisgIHZlY3RvcjxzdHJpbmcqPiBkYXRhOworICBUZXN0QWxsVHlwZXMgZ29sZGVucHJvdG87CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIHN0cmluZyogbmV3X2RhdGEgPSBuZXcgc3RyaW5nOworICAgICpuZXdfZGF0YSA9ICJuYW1lLSIgKyBTaW1wbGVJdG9hKGkpOworICAgIGRhdGEucHVzaF9iYWNrKG5ld19kYXRhKTsKKworICAgIG5ld19kYXRhID0gZ29sZGVucHJvdG8uYWRkX3JlcGVhdGVkX3N0cmluZygpOworICAgICpuZXdfZGF0YSA9ICJuYW1lLSIgKyBTaW1wbGVJdG9hKGkpOworICB9CisgIFRlc3RBbGxUeXBlcyB0ZXN0cHJvdG87CisgIHN0ZDo6Y29weShkYXRhLmJlZ2luKCksIGRhdGEuZW5kKCksIEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0ZXIoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0cHJvdG8ubXV0YWJsZV9yZXBlYXRlZF9zdHJpbmcoKSkpOworICBFWFBFQ1RfRVEodGVzdHByb3RvLkRlYnVnU3RyaW5nKCksIGdvbGRlbnByb3RvLkRlYnVnU3RyaW5nKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmZhOTE5ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc2VydmljZS5jYwpAQCAtMCwwICsxLDQ2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc2VydmljZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK1NlcnZpY2U6On5TZXJ2aWNlKCkge30KK1JwY0NoYW5uZWw6On5ScGNDaGFubmVsKCkge30KK1JwY0NvbnRyb2xsZXI6On5ScGNDb250cm9sbGVyKCkge30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc2VydmljZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2MwYjQ1ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc2VydmljZS5oCkBAIC0wLDAgKzEsMjkxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gREVQUkVDQVRFRDogIFRoaXMgbW9kdWxlIGRlY2xhcmVzIHRoZSBhYnN0cmFjdCBpbnRlcmZhY2VzIHVuZGVybHlpbmcgcHJvdG8yCisvLyBSUEMgc2VydmljZXMuICBUaGVzZSBhcmUgaW50ZW50ZWQgdG8gYmUgaW5kZXBlbmRlbnQgb2YgYW55IHBhcnRpY3VsYXIgUlBDCisvLyBpbXBsZW1lbnRhdGlvbiwgc28gdGhhdCBwcm90bzIgc2VydmljZXMgY2FuIGJlIHVzZWQgb24gdG9wIG9mIGEgdmFyaWV0eQorLy8gb2YgaW1wbGVtZW50YXRpb25zLiAgU3RhcnRpbmcgd2l0aCB2ZXJzaW9uIDIuMy4wLCBSUEMgaW1wbGVtZW50YXRpb25zIHNob3VsZAorLy8gbm90IHRyeSB0byBidWlsZCBvbiB0aGVzZSwgYnV0IHNob3VsZCBpbnN0ZWFkIHByb3ZpZGUgY29kZSBnZW5lcmF0b3IgcGx1Z2lucworLy8gd2hpY2ggZ2VuZXJhdGUgY29kZSBzcGVjaWZpYyB0byB0aGUgcGFydGljdWxhciBSUEMgaW1wbGVtZW50YXRpb24uICBUaGlzIHdheQorLy8gdGhlIGdlbmVyYXRlZCBjb2RlIGNhbiBiZSBtb3JlIGFwcHJvcHJpYXRlIGZvciB0aGUgaW1wbGVtZW50YXRpb24gaW4gdXNlCisvLyBhbmQgY2FuIGF2b2lkIHVubmVjZXNzYXJ5IGxheWVycyBvZiBpbmRpcmVjdGlvbi4KKy8vCisvLworLy8gV2hlbiB5b3UgdXNlIHRoZSBwcm90b2NvbCBjb21waWxlciB0byBjb21waWxlIGEgc2VydmljZSBkZWZpbml0aW9uLCBpdAorLy8gZ2VuZXJhdGVzIHR3byBjbGFzc2VzOiAgQW4gYWJzdHJhY3QgaW50ZXJmYWNlIGZvciB0aGUgc2VydmljZSAod2l0aAorLy8gbWV0aG9kcyBtYXRjaGluZyB0aGUgc2VydmljZSBkZWZpbml0aW9uKSBhbmQgYSAic3R1YiIgaW1wbGVtZW50YXRpb24uCisvLyBBIHN0dWIgaXMganVzdCBhIHR5cGUtc2FmZSB3cmFwcGVyIGFyb3VuZCBhbiBScGNDaGFubmVsIHdoaWNoIGVtdWxhdGVzIGEKKy8vIGxvY2FsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzZXJ2aWNlLgorLy8KKy8vIEZvciBleGFtcGxlLCB0aGUgc2VydmljZSBkZWZpbml0aW9uOgorLy8gICBzZXJ2aWNlIE15U2VydmljZSB7CisvLyAgICAgcnBjIEZvbyhNeVJlcXVlc3QpIHJldHVybnMoTXlSZXNwb25zZSk7CisvLyAgIH0KKy8vIHdpbGwgZ2VuZXJhdGUgYWJzdHJhY3QgaW50ZXJmYWNlICJNeVNlcnZpY2UiIGFuZCBjbGFzcyAiTXlTZXJ2aWNlOjpTdHViIi4KKy8vIFlvdSBjb3VsZCBpbXBsZW1lbnQgYSBNeVNlcnZpY2UgYXMgZm9sbG93czoKKy8vICAgY2xhc3MgTXlTZXJ2aWNlSW1wbCA6IHB1YmxpYyBNeVNlcnZpY2UgeworLy8gICAgcHVibGljOgorLy8gICAgIE15U2VydmljZUltcGwoKSB7fQorLy8gICAgIH5NeVNlcnZpY2VJbXBsKCkge30KKy8vCisvLyAgICAgLy8gaW1wbGVtZW50cyBNeVNlcnZpY2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICAgIHZvaWQgRm9vKGdvb2dsZTo6cHJvdG9idWY6OlJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsCisvLyAgICAgICAgICAgICAgY29uc3QgTXlSZXF1ZXN0KiByZXF1ZXN0LAorLy8gICAgICAgICAgICAgIE15UmVzcG9uc2UqIHJlc3BvbnNlLAorLy8gICAgICAgICAgICAgIENsb3N1cmUqIGRvbmUpIHsKKy8vICAgICAgIC8vIC4uLiByZWFkIHJlcXVlc3QgYW5kIGZpbGwgaW4gcmVzcG9uc2UgLi4uCisvLyAgICAgICBkb25lLT5SdW4oKTsKKy8vICAgICB9CisvLyAgIH07CisvLyBZb3Ugd291bGQgdGhlbiByZWdpc3RlciBhbiBpbnN0YW5jZSBvZiBNeVNlcnZpY2VJbXBsIHdpdGggeW91ciBSUEMgc2VydmVyCisvLyBpbXBsZW1lbnRhdGlvbi4gIChIb3cgdG8gZG8gdGhhdCBkZXBlbmRzIG9uIHRoZSBpbXBsZW1lbnRhdGlvbi4pCisvLworLy8gVG8gY2FsbCBhIHJlbW90ZSBNeVNlcnZpY2VJbXBsLCBmaXJzdCB5b3UgbmVlZCBhbiBScGNDaGFubmVsIGNvbm5lY3RlZCB0byBpdC4KKy8vIEhvdyB0byBjb25zdHJ1Y3QgYSBjaGFubmVsIGRlcGVuZHMsIGFnYWluLCBvbiB5b3VyIFJQQyBpbXBsZW1lbnRhdGlvbi4KKy8vIEhlcmUgd2UgdXNlIGEgaHlwb3RoZW50aWNhbCAiTXlScGNDaGFubmVsIiBhcyBhbiBleGFtcGxlOgorLy8gICBNeVJwY0NoYW5uZWwgY2hhbm5lbCgicnBjOmhvc3RuYW1lOjEyMzQvbXlzZXJ2aWNlIik7CisvLyAgIE15UnBjQ29udHJvbGxlciBjb250cm9sbGVyOworLy8gICBNeVNlcnZpY2VJbXBsOjpTdHViIHN0dWIoJmNoYW5uZWwpOworLy8gICBGb29SZXF1ZXN0IHJlcXVlc3Q7CisvLyAgIEZvb1Jlc3Bub3NlIHJlc3BvbnNlOworLy8KKy8vICAgLy8gLi4uIGZpbGwgaW4gcmVxdWVzdCAuLi4KKy8vCisvLyAgIHN0dWIuRm9vKCZjb250cm9sbGVyLCByZXF1ZXN0LCAmcmVzcG9uc2UsIE5ld0NhbGxiYWNrKEhhbmRsZVJlc3BvbnNlKSk7CisvLworLy8gT24gVGhyZWFkLVNhZmV0eToKKy8vCisvLyBEaWZmZXJlbnQgUlBDIGltcGxlbWVudGF0aW9ucyBtYXkgbWFrZSBkaWZmZXJlbnQgZ3VhcmFudGVlcyBhYm91dCB3aGF0CisvLyB0aHJlYWRzIHRoZXkgbWF5IHJ1biBjYWxsYmFja3Mgb24sIGFuZCB3aGF0IHRocmVhZHMgdGhlIGFwcGxpY2F0aW9uIGlzCisvLyBhbGxvd2VkIHRvIHVzZSB0byBjYWxsIHRoZSBSUEMgc3lzdGVtLiAgUG9ydGFibGUgc29mdHdhcmUgc2hvdWxkIGJlIHJlYWR5CisvLyBmb3IgY2FsbGJhY2tzIHRvIGJlIGNhbGxlZCBvbiBhbnkgdGhyZWFkLCBidXQgc2hvdWxkIG5vdCB0cnkgdG8gY2FsbCB0aGUKKy8vIFJQQyBzeXN0ZW0gZnJvbSBhbnkgdGhyZWFkIGV4Y2VwdCBmb3IgdGhlIG9uZXMgb24gd2hpY2ggaXQgcmVjZWl2ZWQgdGhlCisvLyBjYWxsYmFja3MuICBSZWFsaXN0aWNhbGx5LCB0aG91Z2gsIHNpbXBsZSBzb2Z0d2FyZSB3aWxsIHByb2JhYmx5IHdhbnQgdG8KKy8vIHVzZSBhIHNpbmdsZS10aHJlYWRlZCBSUEMgc3lzdGVtIHdoaWxlIGhpZ2gtZW5kIHNvZnR3YXJlIHdpbGwgd2FudCB0bworLy8gdXNlIG11bHRpcGxlIHRocmVhZHMuICBSUEMgaW1wbGVtZW50YXRpb25zIHNob3VsZCBwcm92aWRlIG11bHRpcGxlCisvLyBjaG9pY2VzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TRVJWSUNFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU0VSVklDRV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBTZXJ2aWNlOworY2xhc3MgUnBjQ29udHJvbGxlcjsKK2NsYXNzIFJwY0NoYW5uZWw7CisKKy8vIERlZmluZWQgaW4gb3RoZXIgZmlsZXMuCitjbGFzcyBEZXNjcmlwdG9yOyAgICAgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorY2xhc3MgU2VydmljZURlc2NyaXB0b3I7ICAgICAvLyBkZXNjcmlwdG9yLmgKK2NsYXNzIE1ldGhvZERlc2NyaXB0b3I7ICAgICAgLy8gZGVzY3JpcHRvci5oCitjbGFzcyBNZXNzYWdlOyAgICAgICAgICAgICAgIC8vIG1lc3NhZ2UuaAorCisvLyBBYnN0cmFjdCBiYXNlIGludGVyZmFjZSBmb3IgcHJvdG9jb2wtYnVmZmVyLWJhc2VkIFJQQyBzZXJ2aWNlcy4gIFNlcnZpY2VzCisvLyB0aGVtc2VsdmVzIGFyZSBhYnN0cmFjdCBpbnRlcmZhY2VzIChpbXBsZW1lbnRlZCBlaXRoZXIgYnkgc2VydmVycyBvciBhcworLy8gc3R1YnMpLCBidXQgdGhleSBzdWJjbGFzcyB0aGlzIGJhc2UgaW50ZXJmYWNlLiAgVGhlIG1ldGhvZHMgb2YgdGhpcworLy8gaW50ZXJmYWNlIGNhbiBiZSB1c2VkIHRvIGNhbGwgdGhlIG1ldGhvZHMgb2YgdGhlIFNlcnZpY2Ugd2l0aG91dCBrbm93aW5nCisvLyBpdHMgZXhhY3QgdHlwZSBhdCBjb21waWxlIHRpbWUgKGFuYWxvZ291cyB0byBSZWZsZWN0aW9uKS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTZXJ2aWNlIHsKKyBwdWJsaWM6CisgIGlubGluZSBTZXJ2aWNlKCkge30KKyAgdmlydHVhbCB+U2VydmljZSgpOworCisgIC8vIFdoZW4gY29uc3RydWN0aW5nIGEgc3R1YiwgeW91IG1heSBwYXNzIFNUVUJfT1dOU19DSEFOTkVMIGFzIHRoZSBzZWNvbmQKKyAgLy8gcGFyYW1ldGVyIHRvIHRoZSBjb25zdHJ1Y3RvciB0byB0ZWxsIGl0IHRvIGRlbGV0ZSBpdHMgUnBjQ2hhbm5lbCB3aGVuCisgIC8vIGRlc3Ryb3llZC4KKyAgZW51bSBDaGFubmVsT3duZXJzaGlwIHsKKyAgICBTVFVCX09XTlNfQ0hBTk5FTCwKKyAgICBTVFVCX0RPRVNOVF9PV05fQ0hBTk5FTAorICB9OworCisgIC8vIEdldCB0aGUgU2VydmljZURlc2NyaXB0b3IgZGVzY3JpYmluZyB0aGlzIHNlcnZpY2UgYW5kIGl0cyBtZXRob2RzLgorICB2aXJ0dWFsIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBHZXREZXNjcmlwdG9yKCkgPSAwOworCisgIC8vIENhbGwgYSBtZXRob2Qgb2YgdGhlIHNlcnZpY2Ugc3BlY2lmaWVkIGJ5IE1ldGhvZERlc2NyaXB0b3IuICBUaGlzIGlzCisgIC8vIG5vcm1hbGx5IGltcGxlbWVudGVkIGFzIGEgc2ltcGxlIHN3aXRjaCgpIHRoYXQgY2FsbHMgdGhlIHN0YW5kYXJkCisgIC8vIGRlZmluaXRpb25zIG9mIHRoZSBzZXJ2aWNlJ3MgbWV0aG9kcy4KKyAgLy8KKyAgLy8gUHJlY29uZGl0aW9uczoKKyAgLy8gKiBtZXRob2QtPnNlcnZpY2UoKSA9PSBHZXREZXNjcmlwdG9yKCkKKyAgLy8gKiByZXF1ZXN0IGFuZCByZXNwb25zZSBhcmUgb2YgdGhlIGV4YWN0IHNhbWUgY2xhc3NlcyBhcyB0aGUgb2JqZWN0cworICAvLyAgIHJldHVybmVkIGJ5IEdldFJlcXVlc3RQcm90b3R5cGUobWV0aG9kKSBhbmQKKyAgLy8gICBHZXRSZXNwb25zZVByb3RvdHlwZShtZXRob2QpLgorICAvLyAqIEFmdGVyIHRoZSBjYWxsIGhhcyBzdGFydGVkLCB0aGUgcmVxdWVzdCBtdXN0IG5vdCBiZSBtb2RpZmllZCBhbmQgdGhlCisgIC8vICAgcmVzcG9uc2UgbXVzdCBub3QgYmUgYWNjZXNzZWQgYXQgYWxsIHVudGlsICJkb25lIiBpcyBjYWxsZWQuCisgIC8vICogImNvbnRyb2xsZXIiIGlzIG9mIHRoZSBjb3JyZWN0IHR5cGUgZm9yIHRoZSBSUEMgaW1wbGVtZW50YXRpb24gYmVpbmcKKyAgLy8gICB1c2VkIGJ5IHRoaXMgU2VydmljZS4gIEZvciBzdHVicywgdGhlICJjb3JyZWN0IHR5cGUiIGRlcGVuZHMgb24gdGhlCisgIC8vICAgUnBjQ2hhbm5lbCB3aGljaCB0aGUgc3R1YiBpcyB1c2luZy4gIFNlcnZlci1zaWRlIFNlcnZpY2UKKyAgLy8gICBpbXBsZW1lbnRhdGlvbnMgYXJlIGV4cGVjdGVkIHRvIGFjY2VwdCB3aGF0ZXZlciB0eXBlIG9mIFJwY0NvbnRyb2xsZXIKKyAgLy8gICB0aGUgc2VydmVyLXNpZGUgUlBDIGltcGxlbWVudGF0aW9uIHVzZXMuCisgIC8vCisgIC8vIFBvc3Rjb25kaXRpb25zOgorICAvLyAqICJkb25lIiB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBtZXRob2QgaXMgY29tcGxldGUuICBUaGlzIG1heSBiZQorICAvLyAgIGJlZm9yZSBDYWxsTWV0aG9kKCkgcmV0dXJucyBvciBpdCBtYXkgYmUgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlLgorICAvLyAqIElmIHRoZSBSUEMgc3VjY2VlZGVkLCAicmVzcG9uc2UiIGNvbnRhaW5zIHRoZSByZXNwb25zZSByZXR1cm5lZCBieQorICAvLyAgIHRoZSBzZXJ2ZXIuCisgIC8vICogSWYgdGhlIFJQQyBmYWlsZWQsICJyZXNwb25zZSIncyBjb250ZW50cyBhcmUgdW5kZWZpbmVkLiAgVGhlCisgIC8vICAgUnBjQ29udHJvbGxlciBjYW4gYmUgcXVlcmllZCB0byBkZXRlcm1pbmUgaWYgYW4gZXJyb3Igb2NjdXJyZWQgYW5kCisgIC8vICAgcG9zc2libHkgdG8gZ2V0IG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGVycm9yLgorICB2aXJ0dWFsIHZvaWQgQ2FsbE1ldGhvZChjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIHJlcXVlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIHJlc3BvbnNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBDbG9zdXJlKiBkb25lKSA9IDA7CisKKyAgLy8gQ2FsbE1ldGhvZCgpIHJlcXVpcmVzIHRoYXQgdGhlIHJlcXVlc3QgYW5kIHJlc3BvbnNlIHBhc3NlZCBpbiBhcmUgb2YgYQorICAvLyBwYXJ0aWN1bGFyIHN1YmNsYXNzIG9mIE1lc3NhZ2UuICBHZXRSZXF1ZXN0UHJvdG90eXBlKCkgYW5kCisgIC8vIEdldFJlc3BvbnNlUHJvdG90eXBlKCkgZ2V0IHRoZSBkZWZhdWx0IGluc3RhbmNlcyBvZiB0aGVzZSByZXF1aXJlZCB0eXBlcy4KKyAgLy8gWW91IGNhbiB0aGVuIGNhbGwgTWVzc2FnZTo6TmV3KCkgb24gdGhlc2UgaW5zdGFuY2VzIHRvIGNvbnN0cnVjdCBtdXRhYmxlCisgIC8vIG9iamVjdHMgd2hpY2ggeW91IGNhbiB0aGVuIHBhc3MgdG8gQ2FsbE1ldGhvZCgpLgorICAvLworICAvLyBFeGFtcGxlOgorICAvLyAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9CisgIC8vICAgICBzZXJ2aWNlLT5HZXREZXNjcmlwdG9yKCktPkZpbmRNZXRob2RCeU5hbWUoIkZvbyIpOworICAvLyAgIE1lc3NhZ2UqIHJlcXVlc3QgID0gc3R1Yi0+R2V0UmVxdWVzdFByb3RvdHlwZSAobWV0aG9kKS0+TmV3KCk7CisgIC8vICAgTWVzc2FnZSogcmVzcG9uc2UgPSBzdHViLT5HZXRSZXNwb25zZVByb3RvdHlwZShtZXRob2QpLT5OZXcoKTsKKyAgLy8gICByZXF1ZXN0LT5QYXJzZUZyb21TdHJpbmcoaW5wdXQpOworICAvLyAgIHNlcnZpY2UtPkNhbGxNZXRob2QobWV0aG9kLCAqcmVxdWVzdCwgcmVzcG9uc2UsIGNhbGxiYWNrKTsKKyAgdmlydHVhbCBjb25zdCBNZXNzYWdlJiBHZXRSZXF1ZXN0UHJvdG90eXBlKAorICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGNvbnN0IE1lc3NhZ2UmIEdldFJlc3BvbnNlUHJvdG90eXBlKAorICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgY29uc3QgPSAwOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFNlcnZpY2UpOworfTsKKworLy8gQW4gUnBjQ29udHJvbGxlciBtZWRpYXRlcyBhIHNpbmdsZSBtZXRob2QgY2FsbC4gIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YKKy8vIHRoZSBjb250cm9sbGVyIGlzIHRvIHByb3ZpZGUgYSB3YXkgdG8gbWFuaXB1bGF0ZSBzZXR0aW5ncyBzcGVjaWZpYyB0byB0aGUKKy8vIFJQQyBpbXBsZW1lbnRhdGlvbiBhbmQgdG8gZmluZCBvdXQgYWJvdXQgUlBDLWxldmVsIGVycm9ycy4KKy8vCisvLyBUaGUgbWV0aG9kcyBwcm92aWRlZCBieSB0aGUgUnBjQ29udHJvbGxlciBpbnRlcmZhY2UgYXJlIGludGVuZGVkIHRvIGJlIGEKKy8vICJsZWFzdCBjb21tb24gZGVub21pbmF0b3IiIHNldCBvZiBmZWF0dXJlcyB3aGljaCB3ZSBleHBlY3QgYWxsCisvLyBpbXBsZW1lbnRhdGlvbnMgdG8gc3VwcG9ydC4gIFNwZWNpZmljIGltcGxlbWVudGF0aW9ucyBtYXkgcHJvdmlkZSBtb3JlCisvLyBhZHZhbmNlZCBmZWF0dXJlcyAoZS5nLiBkZWFkbGluZSBwcm9wYWdhdGlvbikuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUnBjQ29udHJvbGxlciB7CisgcHVibGljOgorICBpbmxpbmUgUnBjQ29udHJvbGxlcigpIHt9CisgIHZpcnR1YWwgflJwY0NvbnRyb2xsZXIoKTsKKworICAvLyBDbGllbnQtc2lkZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUaGVzZSBjYWxscyBtYXkgYmUgbWFkZSBmcm9tIHRoZSBjbGllbnQgc2lkZSBvbmx5LiAgVGhlaXIgcmVzdWx0cworICAvLyBhcmUgdW5kZWZpbmVkIG9uIHRoZSBzZXJ2ZXIgc2lkZSAobWF5IGNyYXNoKS4KKworICAvLyBSZXNldHMgdGhlIFJwY0NvbnRyb2xsZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUgc28gdGhhdCBpdCBtYXkgYmUgcmV1c2VkIGluCisgIC8vIGEgbmV3IGNhbGwuICBNdXN0IG5vdCBiZSBjYWxsZWQgd2hpbGUgYW4gUlBDIGlzIGluIHByb2dyZXNzLgorICB2aXJ0dWFsIHZvaWQgUmVzZXQoKSA9IDA7CisKKyAgLy8gQWZ0ZXIgYSBjYWxsIGhhcyBmaW5pc2hlZCwgcmV0dXJucyB0cnVlIGlmIHRoZSBjYWxsIGZhaWxlZC4gIFRoZSBwb3NzaWJsZQorICAvLyByZWFzb25zIGZvciBmYWlsdXJlIGRlcGVuZCBvbiB0aGUgUlBDIGltcGxlbWVudGF0aW9uLiAgRmFpbGVkKCkgbXVzdCBub3QKKyAgLy8gYmUgY2FsbGVkIGJlZm9yZSBhIGNhbGwgaGFzIGZpbmlzaGVkLiAgSWYgRmFpbGVkKCkgcmV0dXJucyB0cnVlLCB0aGUKKyAgLy8gY29udGVudHMgb2YgdGhlIHJlc3BvbnNlIG1lc3NhZ2UgYXJlIHVuZGVmaW5lZC4KKyAgdmlydHVhbCBib29sIEZhaWxlZCgpIGNvbnN0ID0gMDsKKworICAvLyBJZiBGYWlsZWQoKSBpcyB0cnVlLCByZXR1cm5zIGEgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIGVycm9yLgorICB2aXJ0dWFsIHN0cmluZyBFcnJvclRleHQoKSBjb25zdCA9IDA7CisKKyAgLy8gQWR2aXNlcyB0aGUgUlBDIHN5c3RlbSB0aGF0IHRoZSBjYWxsZXIgZGVzaXJlcyB0aGF0IHRoZSBSUEMgY2FsbCBiZQorICAvLyBjYW5jZWxlZC4gIFRoZSBSUEMgc3lzdGVtIG1heSBjYW5jZWwgaXQgaW1tZWRpYXRlbHksIG1heSB3YWl0IGF3aGlsZSBhbmQKKyAgLy8gdGhlbiBjYW5jZWwgaXQsIG9yIG1heSBub3QgZXZlbiBjYW5jZWwgdGhlIGNhbGwgYXQgYWxsLiAgSWYgdGhlIGNhbGwgaXMKKyAgLy8gY2FuY2VsZWQsIHRoZSAiZG9uZSIgY2FsbGJhY2sgd2lsbCBzdGlsbCBiZSBjYWxsZWQgYW5kIHRoZSBScGNDb250cm9sbGVyCisgIC8vIHdpbGwgaW5kaWNhdGUgdGhhdCB0aGUgY2FsbCBmYWlsZWQgYXQgdGhhdCB0aW1lLgorICB2aXJ0dWFsIHZvaWQgU3RhcnRDYW5jZWwoKSA9IDA7CisKKyAgLy8gU2VydmVyLXNpZGUgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgY2FsbHMgbWF5IGJlIG1hZGUgZnJvbSB0aGUgc2VydmVyIHNpZGUgb25seS4gIFRoZWlyIHJlc3VsdHMKKyAgLy8gYXJlIHVuZGVmaW5lZCBvbiB0aGUgY2xpZW50IHNpZGUgKG1heSBjcmFzaCkuCisKKyAgLy8gQ2F1c2VzIEZhaWxlZCgpIHRvIHJldHVybiB0cnVlIG9uIHRoZSBjbGllbnQgc2lkZS4gICJyZWFzb24iIHdpbGwgYmUKKyAgLy8gaW5jb3Jwb3JhdGVkIGludG8gdGhlIG1lc3NhZ2UgcmV0dXJuZWQgYnkgRXJyb3JUZXh0KCkuICBJZiB5b3UgZmluZAorICAvLyB5b3UgbmVlZCB0byByZXR1cm4gbWFjaGluZS1yZWFkYWJsZSBpbmZvcm1hdGlvbiBhYm91dCBmYWlsdXJlcywgeW91CisgIC8vIHNob3VsZCBpbmNvcnBvcmF0ZSBpdCBpbnRvIHlvdXIgcmVzcG9uc2UgcHJvdG9jb2wgYnVmZmVyIGFuZCBzaG91bGQKKyAgLy8gTk9UIGNhbGwgU2V0RmFpbGVkKCkuCisgIHZpcnR1YWwgdm9pZCBTZXRGYWlsZWQoY29uc3Qgc3RyaW5nJiByZWFzb24pID0gMDsKKworICAvLyBJZiB0cnVlLCBpbmRpY2F0ZXMgdGhhdCB0aGUgY2xpZW50IGNhbmNlbGVkIHRoZSBSUEMsIHNvIHRoZSBzZXJ2ZXIgbWF5CisgIC8vIGFzIHdlbGwgZ2l2ZSB1cCBvbiByZXBseWluZyB0byBpdC4gIFRoZSBzZXJ2ZXIgc2hvdWxkIHN0aWxsIGNhbGwgdGhlCisgIC8vIGZpbmFsICJkb25lIiBjYWxsYmFjay4KKyAgdmlydHVhbCBib29sIElzQ2FuY2VsZWQoKSBjb25zdCA9IDA7CisKKyAgLy8gQXNrcyB0aGF0IHRoZSBnaXZlbiBjYWxsYmFjayBiZSBjYWxsZWQgd2hlbiB0aGUgUlBDIGlzIGNhbmNlbGVkLiAgVGhlCisgIC8vIGNhbGxiYWNrIHdpbGwgYWx3YXlzIGJlIGNhbGxlZCBleGFjdGx5IG9uY2UuICBJZiB0aGUgUlBDIGNvbXBsZXRlcyB3aXRob3V0CisgIC8vIGJlaW5nIGNhbmNlbGVkLCB0aGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgY29tcGxldGlvbi4gIElmIHRoZSBSUEMKKyAgLy8gaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZCB3aGVuIE5vdGlmeU9uQ2FuY2VsKCkgaXMgY2FsbGVkLCB0aGUgY2FsbGJhY2sKKyAgLy8gd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkuCisgIC8vCisgIC8vIE5vdGlmeU9uQ2FuY2VsKCkgbXVzdCBiZSBjYWxsZWQgbm8gbW9yZSB0aGFuIG9uY2UgcGVyIHJlcXVlc3QuCisgIHZpcnR1YWwgdm9pZCBOb3RpZnlPbkNhbmNlbChDbG9zdXJlKiBjYWxsYmFjaykgPSAwOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJwY0NvbnRyb2xsZXIpOworfTsKKworLy8gQWJzdHJhY3QgaW50ZXJmYWNlIGZvciBhbiBSUEMgY2hhbm5lbC4gIEFuIFJwY0NoYW5uZWwgcmVwcmVzZW50cyBhCisvLyBjb21tdW5pY2F0aW9uIGxpbmUgdG8gYSBTZXJ2aWNlIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGNhbGwgdGhhdCBTZXJ2aWNlJ3MKKy8vIG1ldGhvZHMuICBUaGUgU2VydmljZSBtYXkgYmUgcnVubmluZyBvbiBhbm90aGVyIG1hY2hpbmUuICBOb3JtYWxseSwgeW91CisvLyBzaG91bGQgbm90IGNhbGwgYW4gUnBjQ2hhbm5lbCBkaXJlY3RseSwgYnV0IGluc3RlYWQgY29uc3RydWN0IGEgc3R1YiBTZXJ2aWNlCisvLyB3cmFwcGluZyBpdC4gIEV4YW1wbGU6CisvLyAgIFJwY0NoYW5uZWwqIGNoYW5uZWwgPSBuZXcgTXlScGNDaGFubmVsKCJyZW1vdGVob3N0LmV4YW1wbGUuY29tOjEyMzQiKTsKKy8vICAgTXlTZXJ2aWNlKiBzZXJ2aWNlID0gbmV3IE15U2VydmljZTo6U3R1YihjaGFubmVsKTsKKy8vICAgc2VydmljZS0+TXlNZXRob2QocmVxdWVzdCwgJnJlc3BvbnNlLCBjYWxsYmFjayk7CitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUnBjQ2hhbm5lbCB7CisgcHVibGljOgorICBpbmxpbmUgUnBjQ2hhbm5lbCgpIHt9CisgIHZpcnR1YWwgflJwY0NoYW5uZWwoKTsKKworICAvLyBDYWxsIHRoZSBnaXZlbiBtZXRob2Qgb2YgdGhlIHJlbW90ZSBzZXJ2aWNlLiAgVGhlIHNpZ25hdHVyZSBvZiB0aGlzCisgIC8vIHByb2NlZHVyZSBsb29rcyB0aGUgc2FtZSBhcyBTZXJ2aWNlOjpDYWxsTWV0aG9kKCksIGJ1dCB0aGUgcmVxdWlyZW1lbnRzCisgIC8vIGFyZSBsZXNzIHN0cmljdCBpbiBvbmUgaW1wb3J0YW50IHdheTogIHRoZSByZXF1ZXN0IGFuZCByZXNwb25zZSBvYmplY3RzCisgIC8vIG5lZWQgbm90IGJlIG9mIGFueSBzcGVjaWZpYyBjbGFzcyBhcyBsb25nIGFzIHRoZWlyIGRlc2NyaXB0b3JzIGFyZQorICAvLyBtZXRob2QtPmlucHV0X3R5cGUoKSBhbmQgbWV0aG9kLT5vdXRwdXRfdHlwZSgpLgorICB2aXJ0dWFsIHZvaWQgQ2FsbE1ldGhvZChjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIHJlcXVlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIHJlc3BvbnNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBDbG9zdXJlKiBkb25lKSA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUnBjQ2hhbm5lbCk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU0VSVklDRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYyN2ViNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvCkBAIC0wLDAgKzEsODMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlN0cnVjdFByb3RvIjsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKKworLy8gYFN0cnVjdGAgcmVwcmVzZW50cyBhIHN0cnVjdHVyZWQgZGF0YSB2YWx1ZSwgY29uc2lzdGluZyBvZiBmaWVsZHMKKy8vIHdoaWNoIG1hcCB0byBkeW5hbWljYWxseSB0eXBlZCB2YWx1ZXMuIEluIHNvbWUgbGFuZ3VhZ2VzLCBgU3RydWN0YAorLy8gbWlnaHQgYmUgc3VwcG9ydGVkIGJ5IGEgbmF0aXZlIHJlcHJlc2VudGF0aW9uLiBGb3IgZXhhbXBsZSwgaW4KKy8vIHNjcmlwdGluZyBsYW5ndWFnZXMgbGlrZSBKUyBhIHN0cnVjdCBpcyByZXByZXNlbnRlZCBhcyBhbgorLy8gb2JqZWN0LiBUaGUgZGV0YWlscyBvZiB0aGF0IHJlcHJlc2VudGF0aW9uIGFyZSBkZXNjcmliZWQgdG9nZXRoZXIKKy8vIHdpdGggdGhlIHByb3RvIHN1cHBvcnQgZm9yIHRoZSBsYW5ndWFnZS4KK21lc3NhZ2UgU3RydWN0IHsKKyAgLy8gTWFwIG9mIGR5bmFtaWNhbGx5IHR5cGVkIHZhbHVlcy4KKyAgbWFwPHN0cmluZywgVmFsdWU+IGZpZWxkcyA9IDE7Cit9CisKKy8vIGBWYWx1ZWAgcmVwcmVzZW50cyBhIGR5bmFtaWNhbGx5IHR5cGVkIHZhbHVlIHdoaWNoIGNhbiBiZSBlaXRoZXIKKy8vIG51bGwsIGEgbnVtYmVyLCBhIHN0cmluZywgYSBib29sZWFuLCBhIHJlY3Vyc2l2ZSBzdHJ1Y3QgdmFsdWUsIG9yIGEKKy8vIGxpc3Qgb2YgdmFsdWVzLiBBIHByb2R1Y2VyIG9mIHZhbHVlIGlzIGV4cGVjdGVkIHRvIHNldCBvbmUgb2YgdGhhdAorLy8gdmFyaWFudHMsIGFic2VuY2Ugb2YgYW55IHZhcmlhbnQgaW5kaWNhdGVzIGFuIGVycm9yLgorbWVzc2FnZSBWYWx1ZSB7CisgIG9uZW9mIGtpbmQgeworICAgIC8vIFJlcHJlc2VudHMgYSBudWxsIHZhbHVlLgorICAgIE51bGxWYWx1ZSBudWxsX3ZhbHVlID0gMTsKKyAgICAvLyBSZXByZXNlbnRzIGEgZG91YmxlIHZhbHVlLgorICAgIGRvdWJsZSBudW1iZXJfdmFsdWUgPSAyOworICAgIC8vIFJlcHJlc2VudHMgYSBzdHJpbmcgdmFsdWUuCisgICAgc3RyaW5nIHN0cmluZ192YWx1ZSA9IDM7CisgICAgLy8gUmVwcmVzZW50cyBhIGJvb2xlYW4gdmFsdWUuCisgICAgYm9vbCBib29sX3ZhbHVlID0gNDsKKyAgICAvLyBSZXByZXNlbnRzIGEgc3RydWN0dXJlZCB2YWx1ZS4KKyAgICBTdHJ1Y3Qgc3RydWN0X3ZhbHVlID0gNTsKKyAgICAvLyBSZXByZXNlbnRzIGEgcmVwZWF0ZWQgYFZhbHVlYC4KKyAgICBMaXN0VmFsdWUgbGlzdF92YWx1ZSA9IDY7CisgIH0KK30KKworLy8gYE51bGxWYWx1ZWAgaXMgYSBzaW5nbGV0b24gZW51bWVyYXRpb24gdG8gcmVwcmVzZW50IHRoZSBudWxsCisvLyB2YWx1ZSBmb3IgdGhlIGBWYWx1ZWAgdHlwZSB1bmlvbi4KK2VudW0gTnVsbFZhbHVlIHsKKyAgLy8gTnVsbCB2YWx1ZS4KKyAgTlVMTF9WQUxVRSA9IDA7Cit9CisKKy8vIGBMaXN0VmFsdWVgIGlzIGEgd3JhcHBlciBhcm91bmQgYSByZXBlYXRlZCBmaWVsZCBvZiB2YWx1ZXMuCittZXNzYWdlIExpc3RWYWx1ZSB7CisgIC8vIFJlcGVhdGVkIGZpZWxkIG9mIGR5bmFtaWNhbGx5IHR5cGVkIHZhbHVlcy4KKyAgcmVwZWF0ZWQgVmFsdWUgdmFsdWVzID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljX3NlcXVlbmNlX251bS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNfc2VxdWVuY2VfbnVtLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmIyMDk0MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljX3NlcXVlbmNlX251bS5oCkBAIC0wLDAgKzEsNTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDX1NFUVVFTkNFX05VTV9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDX1NFUVVFTkNFX05VTV9IXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitjbGFzcyBTZXF1ZW5jZU51bWJlciB7CisgcHVibGljOgorICBTZXF1ZW5jZU51bWJlcigpIDogd29yZF8oMCkge30KKworICBBdG9taWNXb3JkIEdldE5leHQoKSB7CisgICAgcmV0dXJuIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQoJndvcmRfLCAxKSAtIDE7CisgIH0KKyBwcml2YXRlOgorICBBdG9taWNXb3JkIHdvcmRfOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDX1NFUVVFTkNFX05VTV9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJlMmQ4NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmgKQEAgLTAsMCArMSwyNDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGUgcm91dGluZXMgZXhwb3J0ZWQgYnkgdGhpcyBtb2R1bGUgYXJlIHN1YnRsZS4gIElmIHlvdSB1c2UgdGhlbSwgZXZlbiBpZgorLy8geW91IGdldCB0aGUgY29kZSByaWdodCwgaXQgd2lsbCBkZXBlbmQgb24gY2FyZWZ1bCByZWFzb25pbmcgYWJvdXQgYXRvbWljaXR5CisvLyBhbmQgbWVtb3J5IG9yZGVyaW5nOyBpdCB3aWxsIGJlIGxlc3MgcmVhZGFibGUsIGFuZCBoYXJkZXIgdG8gbWFpbnRhaW4uICBJZgorLy8geW91IHBsYW4gdG8gdXNlIHRoZXNlIHJvdXRpbmVzLCB5b3Ugc2hvdWxkIGhhdmUgYSBnb29kIHJlYXNvbiwgc3VjaCBhcyBzb2xpZAorLy8gZXZpZGVuY2UgdGhhdCBwZXJmb3JtYW5jZSB3b3VsZCBvdGhlcndpc2Ugc3VmZmVyLCBvciB0aGVyZSBiZWluZyBubworLy8gYWx0ZXJuYXRpdmUuICBZb3Ugc2hvdWxkIGFzc3VtZSBvbmx5IHByb3BlcnRpZXMgZXhwbGljaXRseSBndWFyYW50ZWVkIGJ5IHRoZQorLy8gc3BlY2lmaWNhdGlvbnMgaW4gdGhpcyBmaWxlLiAgWW91IGFyZSBhbG1vc3QgY2VydGFpbmx5IF9ub3RfIHdyaXRpbmcgY29kZQorLy8ganVzdCBmb3IgdGhlIHg4NjsgaWYgeW91IGFzc3VtZSB4ODYgc2VtYW50aWNzLCB4ODYgaGFyZHdhcmUgYnVncyBhbmQKKy8vIGltcGxlbWVudGF0aW9ucyBvbiBvdGhlciBhcmNodGVjdHVyZXMgd2lsbCBjYXVzZSB5b3VyIGNvZGUgdG8gYnJlYWsuICBJZiB5b3UKKy8vIGRvIG5vdCBrbm93IHdoYXQgeW91IGFyZSBkb2luZywgYXZvaWQgdGhlc2Ugcm91dGluZXMsIGFuZCB1c2UgYSBNdXRleC4KKy8vCisvLyBJdCBpcyBpbmNvcnJlY3QgdG8gbWFrZSBkaXJlY3QgYXNzaWdubWVudHMgdG8vZnJvbSBhbiBhdG9taWMgdmFyaWFibGUuCisvLyBZb3Ugc2hvdWxkIHVzZSBvbmUgb2YgdGhlIExvYWQgb3IgU3RvcmUgcm91dGluZXMuICBUaGUgTm9CYXJyaWVyCisvLyB2ZXJzaW9ucyBhcmUgcHJvdmlkZWQgd2hlbiBubyBiYXJyaWVycyBhcmUgbmVlZGVkOgorLy8gICBOb0JhcnJpZXJfU3RvcmUoKQorLy8gICBOb0JhcnJpZXJfTG9hZCgpCisvLyBBbHRob3VnaCB0aGVyZSBhcmUgY3VycmVudGx5IG5vIGNvbXBpbGVyIGVuZm9yY2VtZW50LCB5b3UgYXJlIGVuY291cmFnZWQKKy8vIHRvIHVzZSB0aGVzZS4KKworLy8gVGhpcyBoZWFkZXIgYW5kIHRoZSBpbXBsZW1lbnRhdGlvbnMgZm9yIGVhY2ggcGxhdGZvcm0gKGxvY2F0ZWQgaW4KKy8vIGF0b21pY29wc19pbnRlcm5hbHNfKikgbXVzdCBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUgdXBzdHJlYW0gY29kZSAoVjgpLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19IXworCisvLyBEb24ndCBpbmNsdWRlIHRoaXMgZmlsZSBmb3IgcGVvcGxlIG5vdCBjb25jZXJuZWQgYWJvdXQgdGhyZWFkIHNhZmV0eS4KKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfUE9XRVIpCisjaWYgZGVmaW5lZChfTFA2NCkgfHwgZGVmaW5lZChfX0xQNjRfXykKK3R5cGVkZWYgaW50MzIgQXRvbWljMzI7Cit0eXBlZGVmIGludHB0cl90IEF0b21pYzY0OworI2Vsc2UKK3R5cGVkZWYgaW50cHRyX3QgQXRvbWljMzI7Cit0eXBlZGVmIGludDY0IEF0b21pYzY0OworI2VuZGlmCisjZWxzZQordHlwZWRlZiBpbnQzMiBBdG9taWMzMjsKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQKKy8vIFdlIG5lZWQgdG8gYmUgYWJsZSB0byBnbyBiZXR3ZWVuIEF0b21pYzY0IGFuZCBBdG9taWNXb3JkIGltcGxpY2l0bHkuICBUaGlzCisvLyBtZWFucyBBdG9taWM2NCBhbmQgQXRvbWljV29yZCBzaG91bGQgYmUgdGhlIHNhbWUgdHlwZSBvbiA2NC1iaXQuCisjaWYgZGVmaW5lZChfX0lMUDMyX18pIHx8IGRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX05BQ0wpIHx8IGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfU1BBUkMpCisvLyBOYUNsJ3MgaW50cHRyX3QgaXMgbm90IGFjdHVhbGx5IDY0LWJpdHMgb24gNjQtYml0IQorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL25hdGl2ZWNsaWVudC9pc3N1ZXMvZGV0YWlsP2lkPTExNjIKKy8vIHNwYXJjdjkncyBwb2ludGVyIHR5cGUgaXMgMzJiaXRzCit0eXBlZGVmIGludDY0IEF0b21pYzY0OworI2Vsc2UKK3R5cGVkZWYgaW50cHRyX3QgQXRvbWljNjQ7CisjZW5kaWYKKyNlbmRpZgorI2VuZGlmCisKKy8vIFVzZSBBdG9taWNXb3JkIGZvciBhIG1hY2hpbmUtc2l6ZWQgcG9pbnRlci4gIEl0IHdpbGwgdXNlIHRoZSBBdG9taWMzMiBvcgorLy8gQXRvbWljNjQgcm91dGluZXMgYmVsb3csIGRlcGVuZGluZyBvbiB5b3VyIGFyY2hpdGVjdHVyZS4KK3R5cGVkZWYgaW50cHRyX3QgQXRvbWljV29yZDsKKworLy8gQXRvbWljYWxseSBleGVjdXRlOgorLy8gICAgICByZXN1bHQgPSAqcHRyOworLy8gICAgICBpZiAoKnB0ciA9PSBvbGRfdmFsdWUpCisvLyAgICAgICAgKnB0ciA9IG5ld192YWx1ZTsKKy8vICAgICAgcmV0dXJuIHJlc3VsdDsKKy8vCisvLyBJLmUuLCByZXBsYWNlICIqcHRyIiB3aXRoICJuZXdfdmFsdWUiIGlmICIqcHRyIiB1c2VkIHRvIGJlICJvbGRfdmFsdWUiLgorLy8gQWx3YXlzIHJldHVybiB0aGUgb2xkIHZhbHVlIG9mICIqcHRyIgorLy8KKy8vIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK0F0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpOworCisvLyBBdG9taWNhbGx5IHN0b3JlIG5ld192YWx1ZSBpbnRvICpwdHIsIHJldHVybmluZyB0aGUgcHJldmlvdXMgdmFsdWUgaGVsZCBpbgorLy8gKnB0ci4gIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK0F0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiBuZXdfdmFsdWUpOworCisvLyBBdG9taWNhbGx5IGluY3JlbWVudCAqcHRyIGJ5ICJpbmNyZW1lbnQiLiAgUmV0dXJucyB0aGUgbmV3IHZhbHVlIG9mCisvLyAqcHRyIHdpdGggdGhlIGluY3JlbWVudCBhcHBsaWVkLiAgVGhpcyByb3V0aW5lIGltcGxpZXMgbm8gbWVtb3J5IGJhcnJpZXJzLgorQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiBpbmNyZW1lbnQpOworCitBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KTsKKworLy8gVGhlc2UgZm9sbG93aW5nIGxvd2VyLWxldmVsIG9wZXJhdGlvbnMgYXJlIHR5cGljYWxseSB1c2VmdWwgb25seSB0byBwZW9wbGUKKy8vIGltcGxlbWVudGluZyBoaWdoZXItbGV2ZWwgc3luY2hyb25pemF0aW9uIG9wZXJhdGlvbnMgbGlrZSBzcGlubG9ja3MsCisvLyBtdXRleGVzLCBhbmQgY29uZGl0aW9uLXZhcmlhYmxlcy4gIFRoZXkgY29tYmluZSBDb21wYXJlQW5kU3dhcCgpLCBhIGxvYWQsIG9yCisvLyBhIHN0b3JlIHdpdGggYXBwcm9wcmlhdGUgbWVtb3J5LW9yZGVyaW5nIGluc3RydWN0aW9ucy4gICJBY3F1aXJlIiBvcGVyYXRpb25zCisvLyBlbnN1cmUgdGhhdCBubyBsYXRlciBtZW1vcnkgYWNjZXNzIGNhbiBiZSByZW9yZGVyZWQgYWhlYWQgb2YgdGhlIG9wZXJhdGlvbi4KKy8vICJSZWxlYXNlIiBvcGVyYXRpb25zIGVuc3VyZSB0aGF0IG5vIHByZXZpb3VzIG1lbW9yeSBhY2Nlc3MgY2FuIGJlIHJlb3JkZXJlZAorLy8gYWZ0ZXIgdGhlIG9wZXJhdGlvbi4gICJCYXJyaWVyIiBvcGVyYXRpb25zIGhhdmUgYm90aCAiQWNxdWlyZSIgYW5kICJSZWxlYXNlIgorLy8gc2VtYW50aWNzLiAgIEEgTWVtb3J5QmFycmllcigpIGhhcyAiQmFycmllciIgc2VtYW50aWNzLCBidXQgZG9lcyBubyBtZW1vcnkKKy8vIGFjY2Vzcy4KK0F0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpOworQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSk7CisKKyNpZiBkZWZpbmVkKF9fTUlOR1czMl9fKSAmJiBkZWZpbmVkKE1lbW9yeUJhcnJpZXIpCisjdW5kZWYgTWVtb3J5QmFycmllcgorI2VuZGlmCit2b2lkIE1lbW9yeUJhcnJpZXIoKTsKK3ZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKTsKK3ZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSk7Cit2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpOworCitBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKTsKK0F0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKTsKK0F0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKTsKKworLy8gNjQtYml0IGF0b21pYyBvcGVyYXRpb25zIChvbmx5IGF2YWlsYWJsZSBvbiA2NC1iaXQgcHJvY2Vzc29ycykuCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUCitBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKTsKK0F0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCBuZXdfdmFsdWUpOworQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCBpbmNyZW1lbnQpOworQXRvbWljNjQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgaW5jcmVtZW50KTsKKworQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSk7CitBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKTsKK3ZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKTsKK3ZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSk7Cit2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpOworQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cik7CitBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cik7CitBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cik7CisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVAorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBJbmNsdWRlIG91ciBwbGF0Zm9ybSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbi4KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19FUlJPUiBcCisjZXJyb3IgIkF0b21pYyBvcGVyYXRpb25zIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgcGxhdGZvcm0iCisKKy8vIFRocmVhZFNhbml0aXplciwgaHR0cDovL2NsYW5nLmxsdm0ub3JnL2RvY3MvVGhyZWFkU2FuaXRpemVyLmh0bWwuCisjaWYgZGVmaW5lZChUSFJFQURfU0FOSVRJWkVSKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3RzYW4uaD4KKy8vIE1TVkMuCisjZWxpZiBkZWZpbmVkKF9NU0NfVkVSKQorI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfSUEzMikgfHwgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9YNjQpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuaD4KKyNlbHNlCitHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisjZW5kaWYKKworLy8gU29sYXJpcworI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfT1NfU09MQVJJUykKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmg+CisKKy8vIEFJWAorI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfT1NfQUlYKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FpeC5oPgorCisvLyBBcHBsZS4KKyNlbGlmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX0FQUExFKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX21hY29zeC5oPgorCisvLyBHQ0MuCisjZWxpZiBkZWZpbmVkKF9fR05VQ19fKQorI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfSUEzMikgfHwgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9YNjQpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oPgorI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9BUk0pICYmIGRlZmluZWQoX19saW51eF9fKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9nY2MuaD4KKyNlbGlmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfQUFSQ0g2NCkKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm02NF9nY2MuaD4KKyNlbGlmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfQVJNX1FOWCkKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm1fcW54Lmg+CisjZWxpZiBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9BUkNIX01JUFMpIHx8IGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfTUlQUzY0KQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX21pcHNfZ2NjLmg+CisjZWxpZiBkZWZpbmVkKF9fbmF0aXZlX2NsaWVudF9fKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3BuYWNsLmg+CisjZWxpZiAoKChfX0dOVUNfXyA9PSA0KSAmJiAoX19HTlVDX01JTk9SX18gPj0gNykpIHx8IChfX0dOVUNfXyA+IDQpKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2dlbmVyaWNfZ2NjLmg+CisjZWxpZiBkZWZpbmVkKF9fY2xhbmdfXykKKyNpZiBfX2hhc19leHRlbnNpb24oY19hdG9taWMpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaD4KKyNlbHNlCitHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisjZW5kaWYKKyNlbHNlCitHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisjZW5kaWYKKworLy8gVW5rbm93bi4KKyNlbHNlCitHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisjZW5kaWYKKworLy8gT24gc29tZSBwbGF0Zm9ybXMgd2UgbmVlZCBhZGRpdGlvbmFsIGRlY2xhcmF0aW9ucyB0byBtYWtlIEF0b21pY1dvcmQKKy8vIGNvbXBhdGlibGUgd2l0aCBvdXIgb3RoZXIgQXRvbWljKiB0eXBlcy4KKyNpZiBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9PU19BUFBMRSkKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hdG9taWN3b3JkX2NvbXBhdC5oPgorI2VuZGlmCisKKyN1bmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYWl4LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYWl4LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjhhNDJmMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19haXguaApAQCAtMCwwICsxLDQ0MCBAQAorLy8gQ29weXJpZ2h0IDIwMTQgQmxvb21iZXJnIEZpbmFuY2UgTFAuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgQmxvb21iZXJnIEZpbmFuY2UgTFAuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGZpbGUgaXMgYW4gaW50ZXJuYWwgYXRvbWljIGltcGxlbWVudGF0aW9uLCB1c2UgYXRvbWljb3BzLmggaW5zdGVhZC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BSVhfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQUlYX0hfCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGx3YXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgXG5cdCIgIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgY21wdyAlW2NtcF0sICVbcmVzXSAgICAgICAgICAgICBcblx0IiAgLy8gY29tcGFyZSB2YWx1ZXMKKyAgICAgICIgICAgICAgYm5lLSAyZiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBzdHdjeC4gJVt2YWxdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiICAvLyBzdG9yZSBuZXcgdmFsdWUKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIjI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFtjbXBdICAiYiIgICAob2xkX3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKG5ld192YWx1ZSksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGx3YXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIHN0d2N4LiAlW3ZhbF0sICVbemVyb10sICVbb2JqXSAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFt2YWxdICAiYiIgICAobmV3X3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsd2FyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGFkZCAlW3Jlc10sICVbdmFsXSwgJVtyZXNdICAgICAgXG5cdCIgIC8vIGFkZCB0aGUgb3BlcmFuZAorICAgICAgIiAgICAgICBzdHdjeC4gJVtyZXNdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiICAvLyBzdG9yZSBvbGQgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgc3RpbGwgcmVzZXJ2ZWQKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKGluY3JlbWVudCksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcih2b2lkKSB7CisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgaXN5bmMgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6CisgICAgICAgICAgICAgIDoKKyAgICAgICAgICAgICAgOiAibWVtb3J5Iik7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBBdG9taWMzMiByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIgICAgICAgbHdzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiMTogICAgIGx3YXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgXG5cdCIgIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgYWRkICVbcmVzXSwgJVt2YWxdLCAlW3Jlc10gICAgICBcblx0IiAgLy8gYWRkIHRoZSBvcGVyYW5kCisgICAgICAiICAgICAgIHN0d2N4LiAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgXG5cdCIgIC8vIHN0b3JlIG9sZCB2YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBzdGlsbCByZXNlcnZlZAorICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj0mYiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgImIiICAgKHB0ciksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChpbmNyZW1lbnQpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGx3YXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgXG5cdCIgIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgY21wdyAlW2NtcF0sICVbcmVzXSAgICAgICAgICAgICBcblx0IiAgLy8gY29tcGFyZSB2YWx1ZXMKKyAgICAgICIgICAgICAgYm5lLSAyZiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBzdHdjeC4gJVt2YWxdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiICAvLyBzdG9yZSBuZXcgdmFsdWUKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbY21wXSAgImIiICAgKG9sZF92YWx1ZSksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChuZXdfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIjE6ICAgICBsd2FyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGNtcHcgJVtjbXBdLCAlW3Jlc10gICAgICAgICAgICAgXG5cdCIgIC8vIGNvbXBhcmUgdmFsdWVzCisgICAgICAiICAgICAgIGJuZS0gMmYgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgc3R3Y3guICVbdmFsXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAgLy8gc3RvcmUgbmV3IHZhbHVlCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIjI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFtjbXBdICAiYiIgICAob2xkX3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKG5ld192YWx1ZSksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBzdHcgJVt2YWxdLCAlW29ial0gICAgICBcblx0IgorICAgICAgIiAgICAgICBpc3luYyAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtvYmpdICI9bSIgKCpwdHIpCisgICAgICAgICAgICAgIDogW3ZhbF0gICJiIiAgKHZhbHVlKSk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIgICAgICAgbHdzeW5jICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgc3R3ICVbdmFsXSwgJVtvYmpdICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbb2JqXSAiPW0iICgqcHRyKQorICAgICAgICAgICAgICA6IFt2YWxdICAiYiIgICh2YWx1ZSkpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsd3ogJVtyZXNdLCAlW29ial0gICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGNtcHcgJVtyZXNdLCAlW3Jlc10gICAgICAgICAgICAgXG5cdCIgLy8gY3JlYXRlIGRhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXBlbmRlbmN5IGZvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvYWQvbG9hZCBvcmRlcmluZworICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiIC8vIG5ldmVyIHRha2VuCisKKyAgICAgICIgICAgICAgaXN5bmMgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPWIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJtIiAgKCpwdHIpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBsd3N5bmMgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIxOiAgICAgbHd6ICVbcmVzXSwgJVtvYmpdICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBjbXB3ICVbcmVzXSwgJVtyZXNdICAgICAgICAgICAgIFxuXHQiIC8vIGNyZWF0ZSBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVwZW5kZW5jeSBmb3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2FkL2xvYWQgb3JkZXJpbmcKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IiAvLyBuZXZlciB0YWtlbgorICAgICAgICAgICAgICA6IFtyZXNdICAiPWIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJtIiAgKCpwdHIpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVAoraW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIxOiAgICAgbGRhcnggJVtyZXNdLCAlW3plcm9dLCAlW29ial0gICBcblx0IiAgLy8gbG9hZCBhbmQgcmVzZXJ2ZQorICAgICAgIiAgICAgICBjbXBkICVbY21wXSwgJVtyZXNdICAgICAgICAgICAgIFxuXHQiICAvLyBjb21wYXJlIHZhbHVlcworICAgICAgIiAgICAgICBibmUtIDJmICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIgICAgICAgc3RkY3guICVbdmFsXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAgLy8gc3RvcmUgdGhlIG5ldyB2YWx1ZQorICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiMjogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj0mYiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgImIiICAgKHB0ciksCisgICAgICAgICAgICAgICAgW2NtcF0gICJiIiAgIChvbGRfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt2YWxdICAiYiIgICAobmV3X3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIxOiAgICAgbGRhcnggJVtyZXNdLCAlW3plcm9dLCAlW29ial0gICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgc3RkY3guICVbdmFsXSwgJVt6ZXJvXSwgJVtvYmpdICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj0mYiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgImIiICAgKHB0ciksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChuZXdfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGxkYXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgXG5cdCIgLy8gbG9hZCBhbmQgcmVzZXJ2ZQorICAgICAgIiAgICAgICBhZGQgJVtyZXNdLCAlW3Jlc10sICVbdmFsXSAgICAgIFxuXHQiIC8vIGFkZCB0aGUgb3BlcmFuZAorICAgICAgIiAgICAgICBzdGRjeC4gJVtyZXNdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiIC8vIHN0b3JlIG9sZCB2YWx1ZSBpZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0aWxsIHJlc2VydmVkCisKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKGluY3JlbWVudCksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIjE6ICAgICBsZGFyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgYWRkICVbcmVzXSwgJVtyZXNdLCAlW3ZhbF0gICAgICBcblx0IiAvLyBhZGQgdGhlIG9wZXJhbmQKKyAgICAgICIgICAgICAgc3RkY3guICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAvLyBzdG9yZSBvbGQgdmFsdWUgaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdGlsbCByZXNlcnZlZAorCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIiAgICAgICBpc3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFt2YWxdICAiYiIgICAoaW5jcmVtZW50KSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsZGFyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGNtcGQgJVtjbXBdLCAlW3Jlc10gICAgICAgICAgICAgXG5cdCIgIC8vIGNvbXBhcmUgdmFsdWVzCisgICAgICAiICAgICAgIGJuZS0gMmYgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIiAgICAgICBzdGRjeC4gJVt2YWxdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiICAvLyBzdG9yZSB0aGUgbmV3IHZhbHVlCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgaXN5bmMgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIjI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFtjbXBdICAiYiIgICAob2xkX3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKG5ld192YWx1ZSksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIgICAgICAgbHdzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiMTogICAgIGxkYXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgXG5cdCIgIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgY21wZCAlW2NtcF0sICVbcmVzXSAgICAgICAgICAgICBcblx0IiAgLy8gY29tcGFyZSB2YWx1ZXMKKyAgICAgICIgICAgICAgYm5lLSAyZiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiICAgICAgIHN0ZGN4LiAlW3ZhbF0sICVbemVyb10sICVbb2JqXSAgXG5cdCIgIC8vIHN0b3JlIHRoZSBuZXcgdmFsdWUKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIjI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFtjbXBdICAiYiIgICAob2xkX3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKG5ld192YWx1ZSksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBzdGQgJVt2YWxdLCAlW29ial0gICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgaXN5bmMgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW29ial0gIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgOiBbdmFsXSAiYiIgICh2YWx1ZSkpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBzdGQgJVt2YWxdLCAlW29ial0gICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbb2JqXSAiPW0iICgqcHRyKQorICAgICAgICAgICAgICA6IFt2YWxdICJiIiAgKHZhbHVlKSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGxkICVbcmVzXSwgJVtvYmpdICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGNtcGQgJVtyZXNdLCAlW3Jlc10gICAgICAgICAgICAgICAgIFxuXHQiIC8vIGNyZWF0ZSBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlcGVuZGVuY3kgZm9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvYWQvbG9hZCBvcmRlcmluZworICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IiAvLyBuZXZlciB0YWtlbgorCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9YiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgIm0iICAoKnB0ciksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIxOiAgICAgbGQgJVtyZXNdLCAlW29ial0gICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgY21wZCAlW3Jlc10sICVbcmVzXSAgICAgICAgICAgICAgICAgXG5cdCIgLy8gY3JlYXRlIGRhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVwZW5kZW5jeSBmb3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbG9hZC9sb2FkIG9yZGVyaW5nCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiIC8vIG5ldmVyIHRha2VuCisgICAgICAgICAgICAgIDogW3Jlc10gICI9YiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgIm0iICAoKnB0ciksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorI2VuZGlmCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfU1BBUkNfR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtNjRfZ2NjLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtNjRfZ2NjLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGEyZDJiOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm02NF9nY2MuaApAQCAtMCwwICsxLDMyNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTTY0X0dDQ19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BUk02NF9HQ0NfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcigpIHsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCJkbWIgaXNoIiA6OjogIm1lbW9yeSIpOyAgLy8gTk9MSU5UCit9CisKKy8vIE5vQmFycmllciB2ZXJzaW9ucyBvZiB0aGUgb3BlcmF0aW9uIGluY2x1ZGUgIm1lbW9yeSIgaW4gdGhlIGNsb2JiZXIgbGlzdC4KKy8vIFRoaXMgaXMgbm90IHJlcXVpcmVkIGZvciBkaXJlY3QgdXNhZ2Ugb2YgdGhlIE5vQmFycmllciB2ZXJzaW9ucyBvZiB0aGUKKy8vIG9wZXJhdGlvbnMuIEhvd2V2ZXIgdGhpcyBpcyByZXF1aXJlZCBmb3IgY29ycmVjdG5lc3Mgd2hlbiB0aGV5IGFyZSB1c2VkIGFzCisvLyBwYXJ0IG9mIHRoZSBBY3F1aXJlIG9yIFJlbGVhc2UgdmVyc2lvbnMsIHRvIGVuc3VyZSB0aGF0IG5vdGhpbmcgZnJvbSBvdXRzaWRlCisvLyB0aGUgY2FsbCBpcyByZW9yZGVyZWQgYmV0d2VlbiB0aGUgb3BlcmF0aW9uIGFuZCB0aGUgbWVtb3J5IGJhcnJpZXIuIFRoaXMgZG9lcworLy8gbm90IGNoYW5nZSB0aGUgY29kZSBnZW5lcmF0ZWQsIHNvIGhhcyBubyBvciBtaW5pbWFsIGltcGFjdCBvbiB0aGUKKy8vIE5vQmFycmllciBvcGVyYXRpb25zLgorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHByZXY7CisgIGludDMyX3QgdGVtcDsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAiMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICJsZHhyICV3W3ByZXZdLCAlW3B0cl0gICAgICAgICAgICAgICAgIFxuXHQiICAvLyBMb2FkIHRoZSBwcmV2aW91cyB2YWx1ZS4KKyAgICAiY21wICV3W3ByZXZdLCAld1tvbGRfdmFsdWVdICAgICAgICAgICBcblx0IgorICAgICJibmUgMWYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgInN0eHIgJXdbdGVtcF0sICV3W25ld192YWx1ZV0sICVbcHRyXSAgXG5cdCIgIC8vIFRyeSB0byBzdG9yZSB0aGUgbmV3IHZhbHVlLgorICAgICJjYm56ICV3W3RlbXBdLCAwYiAgICAgICAgICAgICAgICAgICAgIFxuXHQiICAvLyBSZXRyeSBpZiBpdCBkaWQgbm90IHdvcmsuCisgICAgIjE6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICA6IFtwcmV2XSI9JnIiIChwcmV2KSwKKyAgICAgIFt0ZW1wXSI9JnIiICh0ZW1wKSwKKyAgICAgIFtwdHJdIitRIiAoKnB0cikKKyAgICA6IFtvbGRfdmFsdWVdIklKciIgKG9sZF92YWx1ZSksCisgICAgICBbbmV3X3ZhbHVlXSJyIiAobmV3X3ZhbHVlKQorICAgIDogImNjIiwgIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiBwcmV2OworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiByZXN1bHQ7CisgIGludDMyX3QgdGVtcDsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAiMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICJsZHhyICV3W3Jlc3VsdF0sICVbcHRyXSAgICAgICAgICAgICAgIFxuXHQiICAvLyBMb2FkIHRoZSBwcmV2aW91cyB2YWx1ZS4KKyAgICAic3R4ciAld1t0ZW1wXSwgJXdbbmV3X3ZhbHVlXSwgJVtwdHJdICBcblx0IiAgLy8gVHJ5IHRvIHN0b3JlIHRoZSBuZXcgdmFsdWUuCisgICAgImNibnogJXdbdGVtcF0sIDBiICAgICAgICAgICAgICAgICAgICAgXG5cdCIgIC8vIFJldHJ5IGlmIGl0IGRpZCBub3Qgd29yay4KKyAgICA6IFtyZXN1bHRdIj0mciIgKHJlc3VsdCksCisgICAgICBbdGVtcF0iPSZyIiAodGVtcCksCisgICAgICBbcHRyXSIrUSIgKCpwdHIpCisgICAgOiBbbmV3X3ZhbHVlXSJyIiAobmV3X3ZhbHVlKQorICAgIDogIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgQXRvbWljMzIgcmVzdWx0OworICBpbnQzMl90IHRlbXA7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgIjA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAibGR4ciAld1tyZXN1bHRdLCAlW3B0cl0gICAgICAgICAgICAgICAgICBcblx0IiAgLy8gTG9hZCB0aGUgcHJldmlvdXMgdmFsdWUuCisgICAgImFkZCAld1tyZXN1bHRdLCAld1tyZXN1bHRdLCAld1tpbmNyZW1lbnRdXG5cdCIKKyAgICAic3R4ciAld1t0ZW1wXSwgJXdbcmVzdWx0XSwgJVtwdHJdICAgICAgICBcblx0IiAgLy8gVHJ5IHRvIHN0b3JlIHRoZSByZXN1bHQuCisgICAgImNibnogJXdbdGVtcF0sIDBiICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIgIC8vIFJldHJ5IG9uIGZhaWx1cmUuCisgICAgOiBbcmVzdWx0XSI9JnIiIChyZXN1bHQpLAorICAgICAgW3RlbXBdIj0mciIgKHRlbXApLAorICAgICAgW3B0cl0iK1EiICgqcHRyKQorICAgIDogW2luY3JlbWVudF0iSUpyIiAoaW5jcmVtZW50KQorICAgIDogIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzMyIHJlc3VsdCA9IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworICBNZW1vcnlCYXJyaWVyKCk7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBwcmV2ID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworICBNZW1vcnlCYXJyaWVyKCk7CisKKyAgcmV0dXJuIHByZXY7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICBBdG9taWMzMiBwcmV2ID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworCisgIHJldHVybiBwcmV2OworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIF9fYXNtX18gX192b2xhdGlsZV9fICggIC8vIE5PTElOVAorICAgICJzdGxyICV3W3ZhbHVlXSwgJVtwdHJdICBcblx0IgorICAgIDogW3B0cl0iPVEiICgqcHRyKQorICAgIDogW3ZhbHVlXSJyIiAodmFsdWUpCisgICAgOiAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgQXRvbWljMzIgdmFsdWU7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgImxkYXIgJXdbdmFsdWVdLCAlW3B0cl0gIFxuXHQiCisgICAgOiBbdmFsdWVdIj1yIiAodmFsdWUpCisgICAgOiBbcHRyXSJRIiAoKnB0cikKKyAgICA6ICJtZW1vcnkiCisgICk7ICAvLyBOT0xJTlQKKworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCisvLyA2NC1iaXQgdmVyc2lvbnMgb2YgdGhlIG9wZXJhdGlvbnMuCisvLyBTZWUgdGhlIDMyLWJpdCB2ZXJzaW9ucyBmb3IgY29tbWVudHMuCisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcHJldjsKKyAgaW50MzJfdCB0ZW1wOworCisgIF9fYXNtX18gX192b2xhdGlsZV9fICggIC8vIE5PTElOVAorICAgICIwOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgImxkeHIgJVtwcmV2XSwgJVtwdHJdICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAiY21wICVbcHJldl0sICVbb2xkX3ZhbHVlXSAgICAgICAgICAgICBcblx0IgorICAgICJibmUgMWYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgInN0eHIgJXdbdGVtcF0sICVbbmV3X3ZhbHVlXSwgJVtwdHJdICAgXG5cdCIKKyAgICAiY2JueiAld1t0ZW1wXSwgMGIgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICIxOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgOiBbcHJldl0iPSZyIiAocHJldiksCisgICAgICBbdGVtcF0iPSZyIiAodGVtcCksCisgICAgICBbcHRyXSIrUSIgKCpwdHIpCisgICAgOiBbb2xkX3ZhbHVlXSJJSnIiIChvbGRfdmFsdWUpLAorICAgICAgW25ld192YWx1ZV0iciIgKG5ld192YWx1ZSkKKyAgICA6ICJjYyIsICJtZW1vcnkiCisgICk7ICAvLyBOT0xJTlQKKworICByZXR1cm4gcHJldjsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworICBpbnQzMl90IHRlbXA7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgIjA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAibGR4ciAlW3Jlc3VsdF0sICVbcHRyXSAgICAgICAgICAgICAgICBcblx0IgorICAgICJzdHhyICV3W3RlbXBdLCAlW25ld192YWx1ZV0sICVbcHRyXSAgIFxuXHQiCisgICAgImNibnogJXdbdGVtcF0sIDBiICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICA6IFtyZXN1bHRdIj0mciIgKHJlc3VsdCksCisgICAgICBbdGVtcF0iPSZyIiAodGVtcCksCisgICAgICBbcHRyXSIrUSIgKCpwdHIpCisgICAgOiBbbmV3X3ZhbHVlXSJyIiAobmV3X3ZhbHVlKQorICAgIDogIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworICBpbnQzMl90IHRlbXA7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgIjA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgImxkeHIgJVtyZXN1bHRdLCAlW3B0cl0gICAgICAgICAgICAgICAgIFxuXHQiCisgICAgImFkZCAlW3Jlc3VsdF0sICVbcmVzdWx0XSwgJVtpbmNyZW1lbnRdIFxuXHQiCisgICAgInN0eHIgJXdbdGVtcF0sICVbcmVzdWx0XSwgJVtwdHJdICAgICAgIFxuXHQiCisgICAgImNibnogJXdbdGVtcF0sIDBiICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgOiBbcmVzdWx0XSI9JnIiIChyZXN1bHQpLAorICAgICAgW3RlbXBdIj0mciIgKHRlbXApLAorICAgICAgW3B0cl0iK1EiICgqcHRyKQorICAgIDogW2luY3JlbWVudF0iSUpyIiAoaW5jcmVtZW50KQorICAgIDogIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzY0IHJlc3VsdCA9IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworICBNZW1vcnlCYXJyaWVyKCk7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBwcmV2ID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworICBNZW1vcnlCYXJyaWVyKCk7CisKKyAgcmV0dXJuIHByZXY7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICBBdG9taWM2NCBwcmV2ID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworCisgIHJldHVybiBwcmV2OworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIF9fYXNtX18gX192b2xhdGlsZV9fICggIC8vIE5PTElOVAorICAgICJzdGxyICV4W3ZhbHVlXSwgJVtwdHJdICBcblx0IgorICAgIDogW3B0cl0iPVEiICgqcHRyKQorICAgIDogW3ZhbHVlXSJyIiAodmFsdWUpCisgICAgOiAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgQXRvbWljNjQgdmFsdWU7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgImxkYXIgJXhbdmFsdWVdLCAlW3B0cl0gIFxuXHQiCisgICAgOiBbdmFsdWVdIj1yIiAodmFsdWUpCisgICAgOiBbcHRyXSJRIiAoKnB0cikKKyAgICA6ICJtZW1vcnkiCisgICk7ICAvLyBOT0xJTlQKKworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTTY0X0dDQ19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9nY2MuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm1fZ2NjLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBlNzI3YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm1fZ2NjLmgKQEAgLTAsMCArMSwxNTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGZpbGUgaXMgYW4gaW50ZXJuYWwgYXRvbWljIGltcGxlbWVudGF0aW9uLCB1c2UgYXRvbWljb3BzLmggaW5zdGVhZC4KKy8vCisvLyBMaW51eEtlcm5lbENtcHhjaGcgYW5kIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50IGFyZSBmcm9tIEdvb2dsZSBHZWFycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BUk1fR0NDX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTV9HQ0NfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gMHhmZmZmMGZjMCBpcyB0aGUgaGFyZCBjb2RlZCBhZGRyZXNzIG9mIGEgZnVuY3Rpb24gcHJvdmlkZWQgYnkKKy8vIHRoZSBrZXJuZWwgd2hpY2ggaW1wbGVtZW50cyBhbiBhdG9taWMgY29tcGFyZS1leGNoYW5nZS4gT24gb2xkZXIKKy8vIEFSTSBhcmNoaXRlY3R1cmUgcmV2aXNpb25zIChwcmUtdjYpIHRoaXMgbWF5IGJlIGltcGxlbWVudGVkIHVzaW5nCisvLyBhIHN5c2NhbGwuIFRoaXMgYWRkcmVzcyBpcyBzdGFibGUsIGFuZCBpbiBhY3RpdmUgdXNlIChoYXJkIGNvZGVkKQorLy8gYnkgYXQgbGVhc3QgZ2xpYmMtMi43IGFuZCB0aGUgQW5kcm9pZCBDIGxpYnJhcnkuCit0eXBlZGVmIEF0b21pYzMyICgqTGludXhLZXJuZWxDbXB4Y2hnRnVuYykoQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2xhdGlsZSBBdG9taWMzMiogcHRyKTsKK0xpbnV4S2VybmVsQ21weGNoZ0Z1bmMgcExpbnV4S2VybmVsQ21weGNoZyBfX2F0dHJpYnV0ZV9fKCh3ZWFrKSkgPQorICAgIChMaW51eEtlcm5lbENtcHhjaGdGdW5jKSAweGZmZmYwZmMwOworCit0eXBlZGVmIHZvaWQgKCpMaW51eEtlcm5lbE1lbW9yeUJhcnJpZXJGdW5jKSh2b2lkKTsKK0xpbnV4S2VybmVsTWVtb3J5QmFycmllckZ1bmMgcExpbnV4S2VybmVsTWVtb3J5QmFycmllciBfX2F0dHJpYnV0ZV9fKCh3ZWFrKSkgPQorICAgIChMaW51eEtlcm5lbE1lbW9yeUJhcnJpZXJGdW5jKSAweGZmZmYwZmEwOworCisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcHJldl92YWx1ZSA9ICpwdHI7CisgIGRvIHsKKyAgICBpZiAoIXBMaW51eEtlcm5lbENtcHhjaGcob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0X2Nhc3Q8QXRvbWljMzIqPihwdHIpKSkgeworICAgICAgcmV0dXJuIG9sZF92YWx1ZTsKKyAgICB9CisgICAgcHJldl92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKHByZXZfdmFsdWUgPT0gb2xkX3ZhbHVlKTsKKyAgcmV0dXJuIHByZXZfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIG9sZF92YWx1ZTsKKyAgZG8geworICAgIG9sZF92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKHBMaW51eEtlcm5lbENtcHhjaGcob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgZm9yICg7OykgeworICAgIC8vIEF0b21pYyBleGNoYW5nZSB0aGUgb2xkIHZhbHVlIHdpdGggYW4gaW5jcmVtZW50ZWQgb25lLgorICAgIEF0b21pYzMyIG9sZF92YWx1ZSA9ICpwdHI7CisgICAgQXRvbWljMzIgbmV3X3ZhbHVlID0gb2xkX3ZhbHVlICsgaW5jcmVtZW50OworICAgIGlmIChwTGludXhLZXJuZWxDbXB4Y2hnKG9sZF92YWx1ZSwgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0X2Nhc3Q8QXRvbWljMzIqPihwdHIpKSA9PSAwKSB7CisgICAgICAvLyBUaGUgZXhjaGFuZ2UgdG9vayBwbGFjZSBhcyBleHBlY3RlZC4KKyAgICAgIHJldHVybiBuZXdfdmFsdWU7CisgICAgfQorICAgIC8vIE90aGVyd2lzZSwgKnB0ciBjaGFuZ2VkIG1pZC1sb29wIGFuZCB3ZSBuZWVkIHRvIHJldHJ5LgorICB9Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBwTGludXhLZXJuZWxNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgQXRvbWljMzIgdmFsdWUgPSAqcHRyOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVJNX0dDQ19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9xbnguaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm1fcW54LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTdkZmFhNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm1fcW54LmgKQEAgLTAsMCArMSwxNDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGZpbGUgaXMgYW4gaW50ZXJuYWwgYXRvbWljIGltcGxlbWVudGF0aW9uLCB1c2UgYXRvbWljb3BzLmggaW5zdGVhZC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BUk1fUU5YX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTV9RTlhfSF8KKworLy8gRm9yIF9zbXBfY21weGNoZygpCisjaW5jbHVkZSA8cHRocmVhZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgQXRvbWljMzIgUU5YQ21weGNoZyhBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2xhdGlsZSBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxBdG9taWMzMj4oCisgICAgICBfc21wX2NtcHhjaGcoKHZvbGF0aWxlIHVuc2lnbmVkICopcHRyLAorICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZClvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkKW5ld192YWx1ZSkpOworfQorCisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcHJldl92YWx1ZSA9ICpwdHI7CisgIGRvIHsKKyAgICBpZiAoIVFOWENtcHhjaGcob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0X2Nhc3Q8QXRvbWljMzIqPihwdHIpKSkgeworICAgICAgcmV0dXJuIG9sZF92YWx1ZTsKKyAgICB9CisgICAgcHJldl92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKHByZXZfdmFsdWUgPT0gb2xkX3ZhbHVlKTsKKyAgcmV0dXJuIHByZXZfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIG9sZF92YWx1ZTsKKyAgZG8geworICAgIG9sZF92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKFFOWENtcHhjaGcob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgZm9yICg7OykgeworICAgIC8vIEF0b21pYyBleGNoYW5nZSB0aGUgb2xkIHZhbHVlIHdpdGggYW4gaW5jcmVtZW50ZWQgb25lLgorICAgIEF0b21pYzMyIG9sZF92YWx1ZSA9ICpwdHI7CisgICAgQXRvbWljMzIgbmV3X3ZhbHVlID0gb2xkX3ZhbHVlICsgaW5jcmVtZW50OworICAgIGlmIChRTlhDbXB4Y2hnKG9sZF92YWx1ZSwgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0X2Nhc3Q8QXRvbWljMzIqPihwdHIpKSA9PSAwKSB7CisgICAgICAvLyBUaGUgZXhjaGFuZ2UgdG9vayBwbGFjZSBhcyBleHBlY3RlZC4KKyAgICAgIHJldHVybiBuZXdfdmFsdWU7CisgICAgfQorICAgIC8vIE90aGVyd2lzZSwgKnB0ciBjaGFuZ2VkIG1pZC1sb29wIGFuZCB3ZSBuZWVkIHRvIHJldHJ5LgorICB9Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBfX3N5bmNfc3luY2hyb25pemUoKTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWx1ZSA9ICpwdHI7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gKnB0cjsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BUk1fUU5YX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXRvbWljd29yZF9jb21wYXQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hdG9taWN3b3JkX2NvbXBhdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViMTk4ZmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXRvbWljd29yZF9jb21wYXQuaApAQCAtMCwwICsxLDEyMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FUT01JQ1dPUkRfQ09NUEFUX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FUT01JQ1dPUkRfQ09NUEFUX0hfCisKKy8vIEF0b21pY1dvcmQgaXMgYSBzeW5vbnltIGZvciBpbnRwdHJfdCwgYW5kIEF0b21pYzMyIGlzIGEgc3lub255bSBmb3IgaW50MzIsCisvLyB3aGljaCBpbiB0dXJuIG1lYW5zIGludC4gT24gc29tZSBMUDMyIHBsYXRmb3JtcywgaW50cHRyX3QgaXMgYW4gaW50LCBidXQKKy8vIG9uIG90aGVycywgaXQncyBhIGxvbmcuIFdoZW4gQXRvbWljV29yZCBhbmQgQXRvbWljMzIgYXJlIGJhc2VkIG9uIGRpZmZlcmVudAorLy8gZnVuZGFtZW50YWwgdHlwZXMsIHRoZWlyIHBvaW50ZXJzIGFyZSBpbmNvbXBhdGlibGUuCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgZnVuY3Rpb24gb3ZlcmxvYWRzIHRvIGFsbG93IGJvdGggQXRvbWljV29yZCBhbmQgQXRvbWljMzIKKy8vIGRhdGEgdG8gYmUgdXNlZCB3aXRoIHRoaXMgaW50ZXJmYWNlLgorLy8KKy8vIE9uIExQNjQgcGxhdGZvcm1zLCBBdG9taWNXb3JkIGFuZCBBdG9taWM2NCBhcmUgYm90aCBhbHdheXMgbG9uZywKKy8vIHNvIHRoaXMgcHJvYmxlbSBkb2Vzbid0IG9jY3VyLgorCisjaWYgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUKQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgQXRvbWljV29yZCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljV29yZCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAoCisgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIEF0b21pYzMyKj4ocHRyKSwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljV29yZCBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljV29yZCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2UoCisgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIEF0b21pYzMyKj4ocHRyKSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pY1dvcmQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWNXb3JkKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgaW5jcmVtZW50KSB7CisgIHJldHVybiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIGluY3JlbWVudCk7Cit9CisKK2lubGluZSBBdG9taWNXb3JkIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pY1dvcmQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgaW5jcmVtZW50KSB7CisgIHJldHVybiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCBpbmNyZW1lbnQpOworfQorCitpbmxpbmUgQXRvbWljV29yZCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pY1dvcmQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pY1dvcmQgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWNXb3JkKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWNXb3JkIG5ld192YWx1ZSkgeworICByZXR1cm4gUmVsZWFzZV9Db21wYXJlQW5kU3dhcCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWNXb3JkICpwdHIsIEF0b21pY1dvcmQgdmFsdWUpIHsKKyAgTm9CYXJyaWVyX1N0b3JlKHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCB2YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljV29yZCogcHRyLCBBdG9taWNXb3JkIHZhbHVlKSB7CisgIHJldHVybiBBY3F1aXJlX1N0b3JlKHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCB2YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljV29yZCogcHRyLCBBdG9taWNXb3JkIHZhbHVlKSB7CisgIHJldHVybiBSZWxlYXNlX1N0b3JlKHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCB2YWx1ZSk7Cit9CisKK2lubGluZSBBdG9taWNXb3JkIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pY1dvcmQgKnB0cikgeworICByZXR1cm4gTm9CYXJyaWVyX0xvYWQocmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBjb25zdCBBdG9taWMzMio+KHB0cikpOworfQorCitpbmxpbmUgQXRvbWljV29yZCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljV29yZCogcHRyKSB7CisgIHJldHVybiBBY3F1aXJlX0xvYWQocmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBjb25zdCBBdG9taWMzMio+KHB0cikpOworfQorCitpbmxpbmUgQXRvbWljV29yZCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljV29yZCogcHRyKSB7CisgIHJldHVybiBSZWxlYXNlX0xvYWQocmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBjb25zdCBBdG9taWMzMio+KHB0cikpOworfQorCit9ICAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vICFkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCkKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BVE9NSUNXT1JEX0NPTVBBVF9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2dlbmVyaWNfZ2NjLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDdhYmY2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2dlbmVyaWNfZ2NjLmgKQEAgLTAsMCArMSwxMzcgQEAKKy8vIENvcHlyaWdodCAyMDEzIFJlZCBIYXQgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBSZWQgSGF0IEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0dFTkVSSUNfR0NDX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0dFTkVSSUNfR0NDX0hfCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgX19hdG9taWNfY29tcGFyZV9leGNoYW5nZV9uKHB0ciwgJm9sZF92YWx1ZSwgbmV3X3ZhbHVlLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19BVE9NSUNfUkVMQVhFRCwgX19BVE9NSUNfUkVMQVhFRCk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBfX2F0b21pY19leGNoYW5nZV9uKHB0ciwgbmV3X3ZhbHVlLCBfX0FUT01JQ19SRUxBWEVEKTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gX19hdG9taWNfYWRkX2ZldGNoKHB0ciwgaW5jcmVtZW50LCBfX0FUT01JQ19SRUxBWEVEKTsKK30KKworaW5saW5lIEF0b21pYzMyIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBfX2F0b21pY19hZGRfZmV0Y2gocHRyLCBpbmNyZW1lbnQsIF9fQVRPTUlDX1NFUV9DU1QpOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIF9fYXRvbWljX2NvbXBhcmVfZXhjaGFuZ2UocHRyLCAmb2xkX3ZhbHVlLCAmbmV3X3ZhbHVlLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fQVRPTUlDX0FDUVVJUkUsIF9fQVRPTUlDX0FDUVVJUkUpOworICByZXR1cm4gb2xkX3ZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIF9fYXRvbWljX2NvbXBhcmVfZXhjaGFuZ2VfbihwdHIsICZvbGRfdmFsdWUsIG5ld192YWx1ZSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fQVRPTUlDX1JFTEVBU0UsIF9fQVRPTUlDX0FDUVVJUkUpOworICByZXR1cm4gb2xkX3ZhbHVlOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgX19hdG9taWNfc3RvcmVfbihwdHIsIHZhbHVlLCBfX0FUT01JQ19SRUxBWEVEKTsKK30KKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcigpIHsKKyAgX19zeW5jX3N5bmNocm9uaXplKCk7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgX19hdG9taWNfc3RvcmVfbihwdHIsIHZhbHVlLCBfX0FUT01JQ19TRVFfQ1NUKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBfX2F0b21pY19zdG9yZV9uKHB0ciwgdmFsdWUsIF9fQVRPTUlDX1JFTEVBU0UpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gX19hdG9taWNfbG9hZF9uKHB0ciwgX19BVE9NSUNfUkVMQVhFRCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gX19hdG9taWNfbG9hZF9uKHB0ciwgX19BVE9NSUNfQUNRVUlSRSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gX19hdG9taWNfbG9hZF9uKHB0ciwgX19BVE9NSUNfU0VRX0NTVCk7Cit9CisKKyNpZmRlZiBfX0xQNjRfXworCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIF9fYXRvbWljX3N0b3JlX24ocHRyLCB2YWx1ZSwgX19BVE9NSUNfUkVMRUFTRSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gX19hdG9taWNfbG9hZF9uKHB0ciwgX19BVE9NSUNfQUNRVUlSRSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgX19hdG9taWNfY29tcGFyZV9leGNoYW5nZV9uKHB0ciwgJm9sZF92YWx1ZSwgbmV3X3ZhbHVlLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19BVE9NSUNfQUNRVUlSRSwgX19BVE9NSUNfQUNRVUlSRSk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgX19hdG9taWNfY29tcGFyZV9leGNoYW5nZV9uKHB0ciwgJm9sZF92YWx1ZSwgbmV3X3ZhbHVlLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19BVE9NSUNfUkVMQVhFRCwgX19BVE9NSUNfUkVMQVhFRCk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKKyNlbmRpZiAvLyBkZWZpbmVkKF9fTFA2NF9fKQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0dFTkVSSUNfR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWFjb3N4LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWFjb3N4LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzk2MzMyNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19tYWNvc3guaApAQCAtMCwwICsxLDIyNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX01BQ09TWF9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19NQUNPU1hfSF8KKworI2luY2x1ZGUgPGxpYmtlcm4vT1NBdG9taWMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBwcmV2X3ZhbHVlOworICBkbyB7CisgICAgaWYgKE9TQXRvbWljQ29tcGFyZUFuZFN3YXAzMihvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0X2Nhc3Q8QXRvbWljMzIqPihwdHIpKSkgeworICAgICAgcmV0dXJuIG9sZF92YWx1ZTsKKyAgICB9CisgICAgcHJldl92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKHByZXZfdmFsdWUgPT0gb2xkX3ZhbHVlKTsKKyAgcmV0dXJuIHByZXZfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIG9sZF92YWx1ZTsKKyAgZG8geworICAgIG9sZF92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKCFPU0F0b21pY0NvbXBhcmVBbmRTd2FwMzIob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gT1NBdG9taWNBZGQzMihpbmNyZW1lbnQsIGNvbnN0X2Nhc3Q8QXRvbWljMzIqPihwdHIpKTsKK30KKworaW5saW5lIEF0b21pYzMyIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIE9TQXRvbWljQWRkMzJCYXJyaWVyKGluY3JlbWVudCwgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBPU01lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBwcmV2X3ZhbHVlOworICBkbyB7CisgICAgaWYgKE9TQXRvbWljQ29tcGFyZUFuZFN3YXAzMkJhcnJpZXIob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKSB7CisgICAgICByZXR1cm4gb2xkX3ZhbHVlOworICAgIH0KKyAgICBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocHJldl92YWx1ZSA9PSBvbGRfdmFsdWUpOworICByZXR1cm4gcHJldl92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gQWNxdWlyZV9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWx1ZSA9ICpwdHI7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gKnB0cjsKK30KKworI2lmZGVmIF9fTFA2NF9fCisKKy8vIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvbiA2NC1iaXQgcGxhdGZvcm0KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBwcmV2X3ZhbHVlOworICBkbyB7CisgICAgaWYgKE9TQXRvbWljQ29tcGFyZUFuZFN3YXA2NChvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgaW50NjRfdCo+KHB0cikpKSB7CisgICAgICByZXR1cm4gb2xkX3ZhbHVlOworICAgIH0KKyAgICBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocHJldl92YWx1ZSA9PSBvbGRfdmFsdWUpOworICByZXR1cm4gcHJldl92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgb2xkX3ZhbHVlOworICBkbyB7CisgICAgb2xkX3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAoIU9TQXRvbWljQ29tcGFyZUFuZFN3YXA2NChvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGludDY0X3QqPihwdHIpKSk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIE9TQXRvbWljQWRkNjQoaW5jcmVtZW50LCByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGludDY0X3QqPihwdHIpKTsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIHJldHVybiBPU0F0b21pY0FkZDY0QmFycmllcihpbmNyZW1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGludDY0X3QqPihwdHIpKTsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBwcmV2X3ZhbHVlOworICBkbyB7CisgICAgaWYgKE9TQXRvbWljQ29tcGFyZUFuZFN3YXA2NEJhcnJpZXIoCisgICAgICAgIG9sZF92YWx1ZSwgbmV3X3ZhbHVlLCByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGludDY0X3QqPihwdHIpKSkgeworICAgICAgcmV0dXJuIG9sZF92YWx1ZTsKKyAgICB9CisgICAgcHJldl92YWx1ZSA9ICpwdHI7CisgIH0gd2hpbGUgKHByZXZfdmFsdWUgPT0gb2xkX3ZhbHVlKTsKKyAgcmV0dXJuIHByZXZfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgLy8gVGhlIGxpYiBrZXJuIGludGVyZmFjZSBkb2VzIG5vdCBkaXN0aW5ndWlzaCBiZXR3ZWVuCisgIC8vIEFjcXVpcmUgYW5kIFJlbGVhc2UgbWVtb3J5IGJhcnJpZXJzOyB0aGV5IGFyZSBlcXVpdmFsZW50LgorICByZXR1cm4gQWNxdWlyZV9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBBdG9taWM2NCB2YWx1ZSA9ICpwdHI7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gKnB0cjsKK30KKworI2VuZGlmICAvLyBkZWZpbmVkKF9fTFA2NF9fKQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX01BQ09TWF9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX21pcHNfZ2NjLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWlwc19nY2MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNTgzN2M5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX21pcHNfZ2NjLmgKQEAgLTAsMCArMSwzMTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGZpbGUgaXMgYW4gaW50ZXJuYWwgYXRvbWljIGltcGxlbWVudGF0aW9uLCB1c2UgYXRvbWljb3BzLmggaW5zdGVhZC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19NSVBTX0dDQ19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19NSVBTX0dDQ19IXworCisjZGVmaW5lIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCkgX19hc21fXyBfX3ZvbGF0aWxlX18oIiIgOiA6IDogIm1lbW9yeSIpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIEF0b21pY2FsbHkgZXhlY3V0ZToKKy8vICAgICAgcmVzdWx0ID0gKnB0cjsKKy8vICAgICAgaWYgKCpwdHIgPT0gb2xkX3ZhbHVlKQorLy8gICAgICAgICpwdHIgPSBuZXdfdmFsdWU7CisvLyAgICAgIHJldHVybiByZXN1bHQ7CisvLworLy8gSS5lLiwgcmVwbGFjZSAiKnB0ciIgd2l0aCAibmV3X3ZhbHVlIiBpZiAiKnB0ciIgdXNlZCB0byBiZSAib2xkX3ZhbHVlIi4KKy8vIEFsd2F5cyByZXR1cm4gdGhlIG9sZCB2YWx1ZSBvZiAiKnB0ciIKKy8vCisvLyBUaGlzIHJvdXRpbmUgaW1wbGllcyBubyBtZW1vcnkgYmFycmllcnMuCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHByZXYsIHRtcDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIi5zZXQgcHVzaFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBub3Jlb3JkZXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIjE6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICJsbCAlMCwgJTVcbiIgIC8vIHByZXYgPSAqcHRyCisgICAgICAgICAgICAgICAgICAgICAgICJibmUgJTAsICUzLCAyZlxuIiAgLy8gaWYgKHByZXYgIT0gb2xkX3ZhbHVlKSBnb3RvIDIKKyAgICAgICAgICAgICAgICAgICAgICAgIm1vdmUgJTIsICU0XG4iICAvLyB0bXAgPSBuZXdfdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgInNjICUyLCAlMVxuIiAgLy8gKnB0ciA9IHRtcCAod2l0aCBhdG9taWMgY2hlY2spCisgICAgICAgICAgICAgICAgICAgICAgICJiZXF6ICUyLCAxYlxuIiAgLy8gc3RhcnQgYWdhaW4gb24gYXRvbWljIGVycm9yCisgICAgICAgICAgICAgICAgICAgICAgICJub3BcbiIgIC8vIGRlbGF5IHNsb3Qgbm9wCisgICAgICAgICAgICAgICAgICAgICAgICIyOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBwb3BcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiPSZyIiAocHJldiksICI9bSIgKCpwdHIpLCAiPSZyIiAodG1wKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJyIiAob2xkX3ZhbHVlKSwgInIiIChuZXdfdmFsdWUpLCAibSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICByZXR1cm4gcHJldjsKK30KKworLy8gQXRvbWljYWxseSBzdG9yZSBuZXdfdmFsdWUgaW50byAqcHRyLCByZXR1cm5pbmcgdGhlIHByZXZpb3VzIHZhbHVlIGhlbGQgaW4KKy8vICpwdHIuICBUaGlzIHJvdXRpbmUgaW1wbGllcyBubyBtZW1vcnkgYmFycmllcnMuCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiB0ZW1wLCBvbGQ7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCIuc2V0IHB1c2hcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgbm9yZW9yZGVyXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIxOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAibGwgJTEsICU0XG4iICAvLyBvbGQgPSAqcHRyCisgICAgICAgICAgICAgICAgICAgICAgICJtb3ZlICUwLCAlM1xuIiAgLy8gdGVtcCA9IG5ld192YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAic2MgJTAsICUyXG4iICAvLyAqcHRyID0gdGVtcCAod2l0aCBhdG9taWMgY2hlY2spCisgICAgICAgICAgICAgICAgICAgICAgICJiZXF6ICUwLCAxYlxuIiAgLy8gc3RhcnQgYWdhaW4gb24gYXRvbWljIGVycm9yCisgICAgICAgICAgICAgICAgICAgICAgICJub3BcbiIgIC8vIGRlbGF5IHNsb3Qgbm9wCisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IHBvcFxuIgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9JnIiICh0ZW1wKSwgIj0mciIgKG9sZCksICI9bSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogInIiIChuZXdfdmFsdWUpLCAibSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworCisgIHJldHVybiBvbGQ7Cit9CisKKy8vIEF0b21pY2FsbHkgaW5jcmVtZW50ICpwdHIgYnkgImluY3JlbWVudCIuICBSZXR1cm5zIHRoZSBuZXcgdmFsdWUgb2YKKy8vICpwdHIgd2l0aCB0aGUgaW5jcmVtZW50IGFwcGxpZWQuICBUaGlzIHJvdXRpbmUgaW1wbGllcyBubyBtZW1vcnkgYmFycmllcnMuCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIEF0b21pYzMyIHRlbXAsIHRlbXAyOworCisgIF9fYXNtX18gX192b2xhdGlsZV9fKCIuc2V0IHB1c2hcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgbm9yZW9yZGVyXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIxOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAibGwgJTAsICU0XG4iICAvLyB0ZW1wID0gKnB0cgorICAgICAgICAgICAgICAgICAgICAgICAiYWRkdSAlMSwgJTAsICUzXG4iICAvLyB0ZW1wMiA9IHRlbXAgKyBpbmNyZW1lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgInNjICUxLCAlMlxuIiAgLy8gKnB0ciA9IHRlbXAyICh3aXRoIGF0b21pYyBjaGVjaykKKyAgICAgICAgICAgICAgICAgICAgICAgImJlcXogJTEsIDFiXG4iICAvLyBzdGFydCBhZ2FpbiBvbiBhdG9taWMgZXJyb3IKKyAgICAgICAgICAgICAgICAgICAgICAgImFkZHUgJTEsICUwLCAlM1xuIiAgLy8gdGVtcDIgPSB0ZW1wICsgaW5jcmVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IHBvcFxuIgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9JnIiICh0ZW1wKSwgIj0mciIgKHRlbXAyKSwgIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiSXIiIChpbmNyZW1lbnQpLCAibSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICAvLyB0ZW1wMiBub3cgaG9sZHMgdGhlIGZpbmFsIHZhbHVlLgorICByZXR1cm4gdGVtcDI7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICBBdG9taWMzMiByZXMgPSBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHB0ciwgaW5jcmVtZW50KTsKKyAgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKTsKKyAgcmV0dXJuIHJlczsKK30KKworLy8gIkFjcXVpcmUiIG9wZXJhdGlvbnMKKy8vIGVuc3VyZSB0aGF0IG5vIGxhdGVyIG1lbW9yeSBhY2Nlc3MgY2FuIGJlIHJlb3JkZXJlZCBhaGVhZCBvZiB0aGUgb3BlcmF0aW9uLgorLy8gIlJlbGVhc2UiIG9wZXJhdGlvbnMgZW5zdXJlIHRoYXQgbm8gcHJldmlvdXMgbWVtb3J5IGFjY2VzcyBjYW4gYmUgcmVvcmRlcmVkCisvLyBhZnRlciB0aGUgb3BlcmF0aW9uLiAgIkJhcnJpZXIiIG9wZXJhdGlvbnMgaGF2ZSBib3RoICJBY3F1aXJlIiBhbmQgIlJlbGVhc2UiCisvLyBzZW1hbnRpY3MuICAgQSBNZW1vcnlCYXJyaWVyKCkgaGFzICJCYXJyaWVyIiBzZW1hbnRpY3MsIGJ1dCBkb2VzIG5vIG1lbW9yeQorLy8gYWNjZXNzLgoraW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICBBdG9taWMzMiByZXMgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgIHJldHVybiByZXM7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKTsKKyAgQXRvbWljMzIgcmVzID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICByZXR1cm4gcmVzOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygic3luYyIgOiA6IDogIm1lbW9yeSIpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHZhbHVlID0gKnB0cjsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCisjaWYgZGVmaW5lZChfX0xQNjRfXykKKy8vIDY0LWJpdCB2ZXJzaW9ucyBvZiB0aGUgYXRvbWljIG9wcy4KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBwcmV2LCB0bXA7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCIuc2V0IHB1c2hcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgbm9yZW9yZGVyXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIxOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAibGxkICUwLCAlNVxuIiAgLy8gcHJldiA9ICpwdHIKKyAgICAgICAgICAgICAgICAgICAgICAgImJuZSAlMCwgJTMsIDJmXG4iICAvLyBpZiAocHJldiAhPSBvbGRfdmFsdWUpIGdvdG8gMgorICAgICAgICAgICAgICAgICAgICAgICAibW92ZSAlMiwgJTRcbiIgIC8vIHRtcCA9IG5ld192YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAic2NkICUyLCAlMVxuIiAgLy8gKnB0ciA9IHRtcCAod2l0aCBhdG9taWMgY2hlY2spCisgICAgICAgICAgICAgICAgICAgICAgICJiZXF6ICUyLCAxYlxuIiAgLy8gc3RhcnQgYWdhaW4gb24gYXRvbWljIGVycm9yCisgICAgICAgICAgICAgICAgICAgICAgICJub3BcbiIgIC8vIGRlbGF5IHNsb3Qgbm9wCisgICAgICAgICAgICAgICAgICAgICAgICIyOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBwb3BcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiPSZyIiAocHJldiksICI9bSIgKCpwdHIpLCAiPSZyIiAodG1wKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJyIiAob2xkX3ZhbHVlKSwgInIiIChuZXdfdmFsdWUpLCAibSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICByZXR1cm4gcHJldjsKK30KKworLy8gQXRvbWljYWxseSBzdG9yZSBuZXdfdmFsdWUgaW50byAqcHRyLCByZXR1cm5pbmcgdGhlIHByZXZpb3VzIHZhbHVlIGhlbGQgaW4KKy8vICpwdHIuICBUaGlzIHJvdXRpbmUgaW1wbGllcyBubyBtZW1vcnkgYmFycmllcnMuCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCB0ZW1wLCBvbGQ7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCIuc2V0IHB1c2hcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgbm9yZW9yZGVyXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIxOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAibGxkICUxLCAlNFxuIiAgLy8gb2xkID0gKnB0cgorICAgICAgICAgICAgICAgICAgICAgICAibW92ZSAlMCwgJTNcbiIgIC8vIHRlbXAgPSBuZXdfdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgInNjZCAlMCwgJTJcbiIgIC8vICpwdHIgPSB0ZW1wICh3aXRoIGF0b21pYyBjaGVjaykKKyAgICAgICAgICAgICAgICAgICAgICAgImJlcXogJTAsIDFiXG4iICAvLyBzdGFydCBhZ2FpbiBvbiBhdG9taWMgZXJyb3IKKyAgICAgICAgICAgICAgICAgICAgICAgIm5vcFxuIiAgLy8gZGVsYXkgc2xvdCBub3AKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgcG9wXG4iCisgICAgICAgICAgICAgICAgICAgICAgIDogIj0mciIgKHRlbXApLCAiPSZyIiAob2xkKSwgIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiciIgKG5ld192YWx1ZSksICJtIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisKKyAgcmV0dXJuIG9sZDsKK30KKworLy8gQXRvbWljYWxseSBpbmNyZW1lbnQgKnB0ciBieSAiaW5jcmVtZW50Ii4gIFJldHVybnMgdGhlIG5ldyB2YWx1ZSBvZgorLy8gKnB0ciB3aXRoIHRoZSBpbmNyZW1lbnQgYXBwbGllZC4gIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgQXRvbWljNjQgdGVtcCwgdGVtcDI7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIi5zZXQgcHVzaFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBub3Jlb3JkZXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIjE6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICJsbGQgJTAsICU0XG4iICAvLyB0ZW1wID0gKnB0cgorICAgICAgICAgICAgICAgICAgICAgICAiZGFkZHUgJTEsICUwLCAlM1xuIiAgLy8gdGVtcDIgPSB0ZW1wICsgaW5jcmVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICJzY2QgJTEsICUyXG4iICAvLyAqcHRyID0gdGVtcDIgKHdpdGggYXRvbWljIGNoZWNrKQorICAgICAgICAgICAgICAgICAgICAgICAiYmVxeiAlMSwgMWJcbiIgIC8vIHN0YXJ0IGFnYWluIG9uIGF0b21pYyBlcnJvcgorICAgICAgICAgICAgICAgICAgICAgICAiZGFkZHUgJTEsICUwLCAlM1xuIiAgLy8gdGVtcDIgPSB0ZW1wICsgaW5jcmVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IHBvcFxuIgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9JnIiICh0ZW1wKSwgIj0mciIgKHRlbXAyKSwgIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiSXIiIChpbmNyZW1lbnQpLCAibSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICAvLyB0ZW1wMiBub3cgaG9sZHMgdGhlIGZpbmFsIHZhbHVlLgorICByZXR1cm4gdGVtcDI7Cit9CisKK2lubGluZSBBdG9taWM2NCBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzY0IHJlcyA9IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiByZXM7Cit9CisKKy8vICJBY3F1aXJlIiBvcGVyYXRpb25zCisvLyBlbnN1cmUgdGhhdCBubyBsYXRlciBtZW1vcnkgYWNjZXNzIGNhbiBiZSByZW9yZGVyZWQgYWhlYWQgb2YgdGhlIG9wZXJhdGlvbi4KKy8vICJSZWxlYXNlIiBvcGVyYXRpb25zIGVuc3VyZSB0aGF0IG5vIHByZXZpb3VzIG1lbW9yeSBhY2Nlc3MgY2FuIGJlIHJlb3JkZXJlZAorLy8gYWZ0ZXIgdGhlIG9wZXJhdGlvbi4gICJCYXJyaWVyIiBvcGVyYXRpb25zIGhhdmUgYm90aCAiQWNxdWlyZSIgYW5kICJSZWxlYXNlIgorLy8gc2VtYW50aWNzLiAgIEEgTWVtb3J5QmFycmllcigpIGhhcyAiQmFycmllciIgc2VtYW50aWNzLCBidXQgZG9lcyBubyBtZW1vcnkKKy8vIGFjY2Vzcy4KK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcmVzID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiByZXM7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIEF0b21pYzY0IHZhbHVlID0gKnB0cjsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorI2VuZGlmCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyN1bmRlZiBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUgorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX01JUFNfR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfcG5hY2wuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19wbmFjbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxMGFjMDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfcG5hY2wuaApAQCAtMCwwICsxLDczIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfUE5BQ0xfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfUE5BQ0xfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gX19zeW5jX3ZhbF9jb21wYXJlX2FuZF9zd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBfX3N5bmNfc3luY2hyb25pemUoKTsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiByZXQgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHJldDsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHZhbHVlID0gKnB0cjsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfUE5BQ0xfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfc29sYXJpcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4MDU3ZWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfc29sYXJpcy5oCkBAIC0wLDAgKzEsMTg4IEBACisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfU1BBUkNfR0NDX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1NQQVJDX0dDQ19IXworCisjaW5jbHVkZSA8YXRvbWljLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIChBdG9taWMzMilhdG9taWNfY2FzXzMyKCh2b2xhdGlsZSB1aW50MzJfdCopcHRyLCAodWludDMyX3Qpb2xkX3ZhbHVlLCAodWludDMyX3QpbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIChBdG9taWMzMilhdG9taWNfc3dhcF8zMigodm9sYXRpbGUgdWludDMyX3QqKXB0ciwgKHVpbnQzMl90KW5ld192YWx1ZSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIChBdG9taWMzMilhdG9taWNfYWRkXzMyX252KCh2b2xhdGlsZSB1aW50MzJfdCopcHRyLCAodWludDMyX3QpaW5jcmVtZW50KTsKK30KKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcih2b2lkKSB7CisJbWVtYmFyX3Byb2R1Y2VyKCk7CisJbWVtYmFyX2NvbnN1bWVyKCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzMyIHJldCA9IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworICBNZW1vcnlCYXJyaWVyKCk7CisKKyAgcmV0dXJuIHJldDsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiByZXQgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKworICByZXR1cm4gcmV0OworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIG1lbWJhcl9wcm9kdWNlcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIG1lbWJhcl9jb25zdW1lcigpOworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgQXRvbWljMzIgdmFsID0gKnB0cjsKKyAgbWVtYmFyX2NvbnN1bWVyKCk7CisgIHJldHVybiB2YWw7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBtZW1iYXJfcHJvZHVjZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIGF0b21pY19jYXNfNjQoKHZvbGF0aWxlIHVpbnQ2NF90KilwdHIsICh1aW50NjRfdClvbGRfdmFsdWUsICh1aW50NjRfdCluZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IG5ld192YWx1ZSkgeworICByZXR1cm4gYXRvbWljX3N3YXBfNjQoKHZvbGF0aWxlIHVpbnQ2NF90KilwdHIsICh1aW50NjRfdCluZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGF0b21pY19hZGRfNjRfbnYoKHZvbGF0aWxlIHVpbnQ2NF90KilwdHIsIGluY3JlbWVudCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgTWVtb3J5QmFycmllcigpOworICBBdG9taWM2NCByZXQgPSBhdG9taWNfYWRkXzY0X252KCh2b2xhdGlsZSB1aW50NjRfdCopcHRyLCBpbmNyZW1lbnQpOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiByZXQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcmV0ID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiByZXQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgbWVtYmFyX3Byb2R1Y2VyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgbWVtYmFyX2NvbnN1bWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBBdG9taWM2NCByZXQgPSAqcHRyOworICBtZW1iYXJfY29uc3VtZXIoKTsKKyAgcmV0dXJuIHJldDsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIG1lbWJhcl9wcm9kdWNlcigpOworICByZXR1cm4gKnB0cjsKK30KKyNlbmRpZgorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1NQQVJDX0dDQ19IXworCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfdHNhbi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3RzYW4uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzkwMzU0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3RzYW4uaApAQCAtMCwwICsxLDIxOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMyBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24gZm9yIGNvbXBpbGVyLWJhc2VkCisvLyBUaHJlYWRTYW5pdGl6ZXIgKGh0dHA6Ly9jbGFuZy5sbHZtLm9yZy9kb2NzL1RocmVhZFNhbml0aXplci5odG1sKS4KKy8vIFVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1RTQU5fSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfVFNBTl9IXworCisjZGVmaW5lIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCkgX19hc21fXyBfX3ZvbGF0aWxlX18oIiIgOiA6IDogIm1lbW9yeSIpCisKKyNpbmNsdWRlIDxzYW5pdGl6ZXIvdHNhbl9pbnRlcmZhY2VfYXRvbWljLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgY21wID0gb2xkX3ZhbHVlOworICBfX3RzYW5fYXRvbWljMzJfY29tcGFyZV9leGNoYW5nZV9zdHJvbmcocHRyLCAmY21wLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIHJldHVybiBjbXA7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljMzJfZXhjaGFuZ2UocHRyLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljMzJfZXhjaGFuZ2UocHRyLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcXVpcmUpOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljMzJfZXhjaGFuZ2UocHRyLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGVhc2UpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBpbmNyZW1lbnQgKyBfX3RzYW5fYXRvbWljMzJfZmV0Y2hfYWRkKHB0ciwgaW5jcmVtZW50LAorICAgICAgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworaW5saW5lIEF0b21pYzMyIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBpbmNyZW1lbnQgKyBfX3RzYW5fYXRvbWljMzJfZmV0Y2hfYWRkKHB0ciwgaW5jcmVtZW50LAorICAgICAgX190c2FuX21lbW9yeV9vcmRlcl9hY3FfcmVsKTsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBjbXAgPSBvbGRfdmFsdWU7CisgIF9fdHNhbl9hdG9taWMzMl9jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhwdHIsICZjbXAsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfYWNxdWlyZSwgX190c2FuX21lbW9yeV9vcmRlcl9hY3F1aXJlKTsKKyAgcmV0dXJuIGNtcDsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBjbXAgPSBvbGRfdmFsdWU7CisgIF9fdHNhbl9hdG9taWMzMl9jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhwdHIsICZjbXAsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsZWFzZSwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKKyAgcmV0dXJuIGNtcDsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyICpwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIF9fdHNhbl9hdG9taWMzMl9zdG9yZShwdHIsIHZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyICpwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIF9fdHNhbl9hdG9taWMzMl9zdG9yZShwdHIsIHZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworICBfX3RzYW5fYXRvbWljX3RocmVhZF9mZW5jZShfX3RzYW5fbWVtb3J5X29yZGVyX3NlcV9jc3QpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyICpwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIF9fdHNhbl9hdG9taWMzMl9zdG9yZShwdHIsIHZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGVhc2UpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIgKnB0cikgeworICByZXR1cm4gX190c2FuX2F0b21pYzMyX2xvYWQocHRyLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyICpwdHIpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWMzMl9sb2FkKHB0ciwgX190c2FuX21lbW9yeV9vcmRlcl9hY3F1aXJlKTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiAqcHRyKSB7CisgIF9fdHNhbl9hdG9taWNfdGhyZWFkX2ZlbmNlKF9fdHNhbl9tZW1vcnlfb3JkZXJfc2VxX2NzdCk7CisgIHJldHVybiBfX3RzYW5fYXRvbWljMzJfbG9hZChwdHIsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgY21wID0gb2xkX3ZhbHVlOworICBfX3RzYW5fYXRvbWljNjRfY29tcGFyZV9leGNoYW5nZV9zdHJvbmcocHRyLCAmY21wLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIHJldHVybiBjbXA7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljNjRfZXhjaGFuZ2UocHRyLCBuZXdfdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWM2NF9leGNoYW5nZShwdHIsIG5ld192YWx1ZSwgX190c2FuX21lbW9yeV9vcmRlcl9hY3F1aXJlKTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICByZXR1cm4gX190c2FuX2F0b21pYzY0X2V4Y2hhbmdlKHB0ciwgbmV3X3ZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGVhc2UpOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIHJldHVybiBpbmNyZW1lbnQgKyBfX3RzYW5fYXRvbWljNjRfZmV0Y2hfYWRkKHB0ciwgaW5jcmVtZW50LAorICAgICAgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIHJldHVybiBpbmNyZW1lbnQgKyBfX3RzYW5fYXRvbWljNjRfZmV0Y2hfYWRkKHB0ciwgaW5jcmVtZW50LAorICAgICAgX190c2FuX21lbW9yeV9vcmRlcl9hY3FfcmVsKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIF9fdHNhbl9hdG9taWM2NF9zdG9yZShwdHIsIHZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIF9fdHNhbl9hdG9taWM2NF9zdG9yZShwdHIsIHZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworICBfX3RzYW5fYXRvbWljX3RocmVhZF9mZW5jZShfX3RzYW5fbWVtb3J5X29yZGVyX3NlcV9jc3QpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIF9fdHNhbl9hdG9taWM2NF9zdG9yZShwdHIsIHZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGVhc2UpOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQgKnB0cikgeworICByZXR1cm4gX190c2FuX2F0b21pYzY0X2xvYWQocHRyLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0ICpwdHIpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWM2NF9sb2FkKHB0ciwgX190c2FuX21lbW9yeV9vcmRlcl9hY3F1aXJlKTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCAqcHRyKSB7CisgIF9fdHNhbl9hdG9taWNfdGhyZWFkX2ZlbmNlKF9fdHNhbl9tZW1vcnlfb3JkZXJfc2VxX2NzdCk7CisgIHJldHVybiBfX3RzYW5fYXRvbWljNjRfbG9hZChwdHIsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgY21wID0gb2xkX3ZhbHVlOworICBfX3RzYW5fYXRvbWljNjRfY29tcGFyZV9leGNoYW5nZV9zdHJvbmcocHRyLCAmY21wLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcXVpcmUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfYWNxdWlyZSk7CisgIHJldHVybiBjbXA7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgY21wID0gb2xkX3ZhbHVlOworICBfX3RzYW5fYXRvbWljNjRfY29tcGFyZV9leGNoYW5nZV9zdHJvbmcocHRyLCAmY21wLCBuZXdfdmFsdWUsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGVhc2UsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIHJldHVybiBjbXA7Cit9CisKK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIoKSB7CisgIF9fdHNhbl9hdG9taWNfdGhyZWFkX2ZlbmNlKF9fdHNhbl9tZW1vcnlfb3JkZXJfc2VxX2NzdCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyN1bmRlZiBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUgorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1RTQU5fSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfZ2NjLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTNjOWVhZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfZ2NjLmNjCkBAIC0wLDAgKzEsMTM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBtb2R1bGUgZ2V0cyBlbm91Z2ggQ1BVIGluZm9ybWF0aW9uIHRvIG9wdGltaXplIHRoZQorLy8gYXRvbWljb3BzIG1vZHVsZSBvbiB4ODYuCisKKyNpbmNsdWRlIDxjc3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorCisvLyBUaGlzIGZpbGUgb25seSBtYWtlcyBzZW5zZSB3aXRoIGF0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oIC0tIGl0CisvLyBkZXBlbmRzIG9uIHN0cnVjdHMgdGhhdCBhcmUgZGVmaW5lZCBpbiB0aGF0IGZpbGUuICBJZiBhdG9taWNvcHMuaAorLy8gZG9lc24ndCBzdWItaW5jbHVkZSB0aGF0IGZpbGUsIHRoZW4gd2UgYXJlbid0IG5lZWRlZCwgYW5kIHNob3VsZG4ndAorLy8gdHJ5IHRvIGRvIGFueXRoaW5nLgorI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9HQ0NfSF8KKworLy8gSW5saW5lIGNwdWlkIGluc3RydWN0aW9uLiAgSW4gUElDIGNvbXBpbGF0aW9ucywgJWVieCBjb250YWlucyB0aGUgYWRkcmVzcworLy8gb2YgdGhlIGdsb2JhbCBvZmZzZXQgdGFibGUuICBUbyBhdm9pZCBicmVha2luZyBzdWNoIGV4ZWN1dGFibGVzLCB0aGlzIGNvZGUKKy8vIG11c3QgcHJlc2VydmUgdGhhdCByZWdpc3RlcidzIHZhbHVlIGFjcm9zcyBjcHVpZCBpbnN0cnVjdGlvbnMuCisjaWYgZGVmaW5lZChfX2kzODZfXykKKyNkZWZpbmUgY3B1aWQoYSwgYiwgYywgZCwgaW5wKSBcCisgIGFzbSgibW92ICUlZWJ4LCAlJWVkaVxuIiAgICAgXAorICAgICAgImNwdWlkXG4iICAgICAgICAgICAgICAgIFwKKyAgICAgICJ4Y2hnICUlZWRpLCAlJWVieFxuIiAgICBcCisgICAgICA6ICI9YSIgKGEpLCAiPUQiIChiKSwgIj1jIiAoYyksICI9ZCIgKGQpIDogImEiIChpbnApKQorI2VsaWYgZGVmaW5lZChfX3g4Nl82NF9fKQorI2RlZmluZSBjcHVpZChhLCBiLCBjLCBkLCBpbnApIFwKKyAgYXNtKCJtb3YgJSVyYngsICUlcmRpXG4iICAgICBcCisgICAgICAiY3B1aWRcbiIgICAgICAgICAgICAgICAgXAorICAgICAgInhjaGcgJSVyZGksICUlcmJ4XG4iICAgIFwKKyAgICAgIDogIj1hIiAoYSksICI9RCIgKGIpLCAiPWMiIChjKSwgIj1kIiAoZCkgOiAiYSIgKGlucCkpCisjZW5kaWYKKworI2lmIGRlZmluZWQoY3B1aWQpICAgICAgICAvLyBpbml0aWFsaXplIHRoZSBzdHJ1Y3Qgb25seSBvbiB4ODYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gU2V0IHRoZSBmbGFncyBzbyB0aGF0IGNvZGUgd2lsbCBydW4gY29ycmVjdGx5IGFuZCBjb25zZXJ2YXRpdmVseSwgc28gZXZlbgorLy8gaWYgd2UgaGF2ZW4ndCBiZWVuIGluaXRpYWxpemVkIHlldCwgd2UncmUgcHJvYmFibHkgc2luZ2xlIHRocmVhZGVkLCBhbmQgb3VyCisvLyBkZWZhdWx0IHZhbHVlcyBzaG91bGQgaG9wZWZ1bGx5IGJlIHByZXR0eSBzYWZlLgorc3RydWN0IEF0b21pY09wc194ODZDUFVGZWF0dXJlU3RydWN0IEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzID0geworICBmYWxzZSwgICAgICAgICAgLy8gYnVnIGNhbid0IGV4aXN0IGJlZm9yZSBwcm9jZXNzIHNwYXducyBtdWx0aXBsZSB0aHJlYWRzCisgIGZhbHNlLCAgICAgICAgICAvLyBubyBTU0UyCit9OworCituYW1lc3BhY2UgeworCisvLyBJbml0aWFsaXplIHRoZSBBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlcyBzdHJ1Y3QuCit2b2lkIEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzSW5pdCgpIHsKKyAgdWludDMyX3QgZWF4OworICB1aW50MzJfdCBlYng7CisgIHVpbnQzMl90IGVjeDsKKyAgdWludDMyX3QgZWR4OworCisgIC8vIEdldCB2ZW5kb3Igc3RyaW5nIChpc3N1ZSBDUFVJRCB3aXRoIGVheCA9IDApCisgIGNwdWlkKGVheCwgZWJ4LCBlY3gsIGVkeCwgMCk7CisgIGNoYXIgdmVuZG9yWzEzXTsKKyAgbWVtY3B5KHZlbmRvciwgJmVieCwgNCk7CisgIG1lbWNweSh2ZW5kb3IgKyA0LCAmZWR4LCA0KTsKKyAgbWVtY3B5KHZlbmRvciArIDgsICZlY3gsIDQpOworICB2ZW5kb3JbMTJdID0gMDsKKworICAvLyBnZXQgZmVhdHVyZSBmbGFncyBpbiBlY3gvZWR4LCBhbmQgZmFtaWx5L21vZGVsIGluIGVheAorICBjcHVpZChlYXgsIGVieCwgZWN4LCBlZHgsIDEpOworCisgIGludCBmYW1pbHkgPSAoZWF4ID4+IDgpICYgMHhmOyAgICAgICAgLy8gZmFtaWx5IGFuZCBtb2RlbCBmaWVsZHMKKyAgaW50IG1vZGVsID0gKGVheCA+PiA0KSAmIDB4ZjsKKyAgaWYgKGZhbWlseSA9PSAweGYpIHsgICAgICAgICAgICAgICAgICAvLyB1c2UgZXh0ZW5kZWQgZmFtaWx5IGFuZCBtb2RlbCBmaWVsZHMKKyAgICBmYW1pbHkgKz0gKGVheCA+PiAyMCkgJiAweGZmOworICAgIG1vZGVsICs9ICgoZWF4ID4+IDE2KSAmIDB4ZikgPDwgNDsKKyAgfQorCisgIC8vIE9wdGVyb24gUmV2IEUgaGFzIGEgYnVnIGluIHdoaWNoIG9uIHZlcnkgcmFyZSBvY2Nhc2lvbnMgYSBsb2NrZWQKKyAgLy8gaW5zdHJ1Y3Rpb24gZG9lc24ndCBhY3QgYXMgYSByZWFkLWFjcXVpcmUgYmFycmllciBpZiBmb2xsb3dlZCBieSBhCisgIC8vIG5vbi1sb2NrZWQgcmVhZC1tb2RpZnktd3JpdGUgaW5zdHJ1Y3Rpb24uICBSZXYgRiBoYXMgdGhpcyBidWcgaW4KKyAgLy8gcHJlLXJlbGVhc2UgdmVyc2lvbnMsIGJ1dCBub3QgaW4gdmVyc2lvbnMgcmVsZWFzZWQgdG8gY3VzdG9tZXJzLAorICAvLyBzbyB3ZSB0ZXN0IG9ubHkgZm9yIFJldiBFLCB3aGljaCBpcyBmYW1pbHkgMTUsIG1vZGVsIDMyLi42MyBpbmNsdXNpdmUuCisgIGlmIChzdHJjbXAodmVuZG9yLCAiQXV0aGVudGljQU1EIikgPT0gMCAmJiAgICAgICAvLyBBTUQKKyAgICAgIGZhbWlseSA9PSAxNSAmJgorICAgICAgMzIgPD0gbW9kZWwgJiYgbW9kZWwgPD0gNjMpIHsKKyAgICBBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlcy5oYXNfYW1kX2xvY2tfbWJfYnVnID0gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlcy5oYXNfYW1kX2xvY2tfbWJfYnVnID0gZmFsc2U7CisgIH0KKworICAvLyBlZHggYml0IDI2IGlzIFNTRTIgd2hpY2ggd2UgdXNlIHRvIHRlbGwgdXNlIHdoZXRoZXIgd2UgY2FuIHVzZSBtZmVuY2UKKyAgQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMuaGFzX3NzZTIgPSAoKGVkeCA+PiAyNikgJiAxKTsKK30KKworY2xhc3MgQXRvbWljT3BzeDg2SW5pdGlhbGl6ZXIgeworIHB1YmxpYzoKKyAgQXRvbWljT3BzeDg2SW5pdGlhbGl6ZXIoKSB7CisgICAgQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXNJbml0KCk7CisgIH0KK307CisKKy8vIEEgZ2xvYmFsIHRvIGdldCB1c2UgaW5pdGlhbGl6ZWQgb24gc3RhcnR1cCB2aWEgc3RhdGljIGluaXRpYWxpemF0aW9uIDovCitBdG9taWNPcHN4ODZJbml0aWFsaXplciBnX2luaXRlcjsKKworfSAgLy8gbmFtZXNwYWNlCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gX19pMzg2X18KKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19YODZfR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZGNjYzU5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuaApAQCAtMCwwICsxLDI5MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9HQ0NfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X0dDQ19IXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBUaGlzIHN0cnVjdCBpcyBub3QgcGFydCBvZiB0aGUgcHVibGljIEFQSSBvZiB0aGlzIG1vZHVsZTsgY2xpZW50cyBtYXkgbm90CisvLyB1c2UgaXQuCisvLyBGZWF0dXJlcyBvZiB0aGlzIHg4Ni4gIFZhbHVlcyBtYXkgbm90IGJlIGNvcnJlY3QgYmVmb3JlIG1haW4oKSBpcyBydW4sCisvLyBidXQgYXJlIHNldCBjb25zZXJ2YXRpdmVseS4KK3N0cnVjdCBBdG9taWNPcHNfeDg2Q1BVRmVhdHVyZVN0cnVjdCB7CisgIGJvb2wgaGFzX2FtZF9sb2NrX21iX2J1ZzsgIC8vIFByb2Nlc3NvciBoYXMgQU1EIG1lbW9yeS1iYXJyaWVyIGJ1ZzsgZG8gbGZlbmNlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFmdGVyIGFjcXVpcmUgY29tcGFyZS1hbmQtc3dhcC4KKyAgYm9vbCBoYXNfc3NlMjsgICAgICAgICAgICAgLy8gUHJvY2Vzc29yIGhhcyBTU0UyLgorfTsKK2V4dGVybiBzdHJ1Y3QgQXRvbWljT3BzX3g4NkNQVUZlYXR1cmVTdHJ1Y3QgQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXM7CisKKyNkZWZpbmUgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKSBfX2FzbV9fIF9fdm9sYXRpbGVfXygiIiA6IDogOiAibWVtb3J5IikKKworLy8gMzItYml0IGxvdy1sZXZlbCBvcGVyYXRpb25zIG9uIGFueSBwbGF0Zm9ybS4KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBwcmV2OworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibG9jazsgY21weGNoZ2wgJTEsJTIiCisgICAgICAgICAgICAgICAgICAgICAgIDogIj1hIiAocHJldikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAicSIgKG5ld192YWx1ZSksICJtIiAoKnB0ciksICIwIiAob2xkX3ZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJtZW1vcnkiKTsKKyAgcmV0dXJuIHByZXY7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJ4Y2hnbCAlMSwlMCIgIC8vIFRoZSBsb2NrIHByZWZpeCBpcyBpbXBsaWNpdCBmb3IgeGNoZy4KKyAgICAgICAgICAgICAgICAgICAgICAgOiAiPXIiIChuZXdfdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm0iICgqcHRyKSwgIjAiIChuZXdfdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICByZXR1cm4gbmV3X3ZhbHVlOyAgLy8gTm93IGl0J3MgdGhlIHByZXZpb3VzIHZhbHVlLgorfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIEF0b21pYzMyIHRlbXAgPSBpbmNyZW1lbnQ7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsb2NrOyB4YWRkbCAlMCwlMSIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiK3IiICh0ZW1wKSwgIittIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiA6ICJtZW1vcnkiKTsKKyAgLy8gdGVtcCBub3cgaG9sZHMgdGhlIG9sZCB2YWx1ZSBvZiAqcHRyCisgIHJldHVybiB0ZW1wICsgaW5jcmVtZW50OworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgQXRvbWljMzIgdGVtcCA9IGluY3JlbWVudDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oImxvY2s7IHhhZGRsICUwLCUxIgorICAgICAgICAgICAgICAgICAgICAgICA6ICIrciIgKHRlbXApLCAiK20iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6IDogIm1lbW9yeSIpOworICAvLyB0ZW1wIG5vdyBob2xkcyB0aGUgb2xkIHZhbHVlIG9mICpwdHIKKyAgaWYgKEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19hbWRfbG9ja19tYl9idWcpIHsKKyAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibGZlbmNlIiA6IDogOiAibWVtb3J5Iik7CisgIH0KKyAgcmV0dXJuIHRlbXAgKyBpbmNyZW1lbnQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgeCA9IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKKyAgaWYgKEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19hbWRfbG9ja19tYl9idWcpIHsKKyAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibGZlbmNlIiA6IDogOiAibWVtb3J5Iik7CisgIH0KKyAgcmV0dXJuIHg7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworI2lmIGRlZmluZWQoX194ODZfNjRfXykKKworLy8gNjQtYml0IGltcGxlbWVudGF0aW9ucyBvZiBtZW1vcnkgYmFycmllciBjYW4gYmUgc2ltcGxlciwgYmVjYXVzZSBpdAorLy8gIm1mZW5jZSIgaXMgZ3VhcmFudGVlZCB0byBleGlzdC4KK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIoKSB7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJtZmVuY2UiIDogOiA6ICJtZW1vcnkiKTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworI2Vsc2UKKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcigpIHsKKyAgaWYgKEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19zc2UyKSB7CisgICAgX19hc21fXyBfX3ZvbGF0aWxlX18oIm1mZW5jZSIgOiA6IDogIm1lbW9yeSIpOworICB9IGVsc2UgeyAgLy8gbWZlbmNlIGlzIGZhc3RlciBidXQgbm90IHByZXNlbnQgb24gUElJSQorICAgIEF0b21pYzMyIHggPSAwOworICAgIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSgmeCwgMCk7ICAvLyBhY3RzIGFzIGEgYmFycmllciBvbiBQSUlJCisgIH0KK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBpZiAoQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMuaGFzX3NzZTIpIHsKKyAgICAqcHRyID0gdmFsdWU7CisgICAgX19hc21fXyBfX3ZvbGF0aWxlX18oIm1mZW5jZSIgOiA6IDogIm1lbW9yeSIpOworICB9IGVsc2UgeworICAgIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZShwdHIsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWN0cyBhcyBhIGJhcnJpZXIgb24gUElJSQorICB9Cit9CisjZW5kaWYKKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICAqcHRyID0gdmFsdWU7ICAvLyBBbiB4ODYgc3RvcmUgYWN0cyBhcyBhIHJlbGVhc2UgYmFycmllci4KKyAgLy8gU2VlIGNvbW1lbnRzIGluIEF0b21pYzY0IHZlcnNpb24gb2YgUmVsZWFzZV9TdG9yZSgpLCBiZWxvdy4KK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWx1ZSA9ICpwdHI7ICAvLyBBbiB4ODYgbG9hZCBhY3RzIGFzIGEgYWNxdWlyZSBiYXJyaWVyLgorICAvLyBTZWUgY29tbWVudHMgaW4gQXRvbWljNjQgdmVyc2lvbiBvZiBSZWxlYXNlX1N0b3JlKCksIGJlbG93LgorICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCisjaWYgZGVmaW5lZChfX3g4Nl82NF9fKQorCisvLyA2NC1iaXQgbG93LWxldmVsIG9wZXJhdGlvbnMgb24gNjQtYml0IHBsYXRmb3JtLgorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHByZXY7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsb2NrOyBjbXB4Y2hncSAlMSwlMiIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiPWEiIChwcmV2KQorICAgICAgICAgICAgICAgICAgICAgICA6ICJxIiAobmV3X3ZhbHVlKSwgIm0iICgqcHRyKSwgIjAiIChvbGRfdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICByZXR1cm4gcHJldjsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oInhjaGdxICUxLCUwIiAgLy8gVGhlIGxvY2sgcHJlZml4IGlzIGltcGxpY2l0IGZvciB4Y2hnLgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9ciIgKG5ld192YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibSIgKCpwdHIpLCAiMCIgKG5ld192YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIHJldHVybiBuZXdfdmFsdWU7ICAvLyBOb3cgaXQncyB0aGUgcHJldmlvdXMgdmFsdWUuCit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgQXRvbWljNjQgdGVtcCA9IGluY3JlbWVudDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oImxvY2s7IHhhZGRxICUwLCUxIgorICAgICAgICAgICAgICAgICAgICAgICA6ICIrciIgKHRlbXApLCAiK20iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6IDogIm1lbW9yeSIpOworICAvLyB0ZW1wIG5vdyBjb250YWlucyB0aGUgcHJldmlvdXMgdmFsdWUgb2YgKnB0cgorICByZXR1cm4gdGVtcCArIGluY3JlbWVudDsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIEF0b21pYzY0IHRlbXAgPSBpbmNyZW1lbnQ7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsb2NrOyB4YWRkcSAlMCwlMSIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiK3IiICh0ZW1wKSwgIittIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiA6ICJtZW1vcnkiKTsKKyAgLy8gdGVtcCBub3cgY29udGFpbnMgdGhlIHByZXZpb3VzIHZhbHVlIG9mICpwdHIKKyAgaWYgKEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19hbWRfbG9ja19tYl9idWcpIHsKKyAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibGZlbmNlIiA6IDogOiAibWVtb3J5Iik7CisgIH0KKyAgcmV0dXJuIHRlbXAgKyBpbmNyZW1lbnQ7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKTsKKworICAqcHRyID0gdmFsdWU7ICAvLyBBbiB4ODYgc3RvcmUgYWN0cyBhcyBhIHJlbGVhc2UgYmFycmllcgorICAgICAgICAgICAgICAgICAvLyBmb3IgY3VycmVudCBBTUQvSW50ZWwgY2hpcHMgYXMgb2YgSmFuIDIwMDguCisgICAgICAgICAgICAgICAgIC8vIFNlZSBhbHNvIEFjcXVpcmVfTG9hZCgpLCBiZWxvdy4KKworICAvLyBXaGVuIG5ldyBjaGlwcyBjb21lIG91dCwgY2hlY2s6CisgIC8vICBJQS0zMiBJbnRlbCBBcmNoaXRlY3R1cmUgU29mdHdhcmUgRGV2ZWxvcGVyJ3MgTWFudWFsLCBWb2x1bWUgMzoKKyAgLy8gIFN5c3RlbSBQcm9ncmFtbWluZyBHdWlkZSwgQ2hhdHBlciA3OiBNdWx0aXBsZS1wcm9jZXNzb3IgbWFuYWdlbWVudCwKKyAgLy8gIFNlY3Rpb24gNy4yLCBNZW1vcnkgT3JkZXJpbmcuCisgIC8vIExhc3Qgc2VlbiBhdDoKKyAgLy8gICBodHRwOi8vZGV2ZWxvcGVyLmludGVsLmNvbS9kZXNpZ24vcGVudGl1bTQvbWFudWFscy9pbmRleF9uZXcuaHRtCisgIC8vCisgIC8vIHg4NiBzdG9yZXMvbG9hZHMgZmFpbCB0byBhY3QgYXMgYmFycmllcnMgZm9yIGEgZmV3IGluc3RydWN0aW9ucyAoY2xmbHVzaAorICAvLyBtYXNrbW92ZHF1IG1hc2ttb3ZxIG1vdm50ZHEgbW92bnRpIG1vdm50cGQgbW92bnRwcyBtb3ZudHEpIGJ1dCB0aGVzZSBhcmUKKyAgLy8gbm90IGdlbmVyYXRlZCBieSB0aGUgY29tcGlsZXIsIGFuZCBhcmUgcmFyZS4gIFVzZXJzIG9mIHRoZXNlIGluc3RydWN0aW9ucworICAvLyBuZWVkIHRvIGtub3cgYWJvdXQgY2FjaGUgYmVoYXZpb3VyIGluIGFueSBjYXNlIHNpbmNlIGFsbCBvZiB0aGVzZSBpbnZvbHZlCisgIC8vIGVpdGhlciBmbHVzaGluZyBjYWNoZSBsaW5lcyBvciBub24tdGVtcG9yYWwgY2FjaGUgaGludHMuCit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgQXRvbWljNjQgdmFsdWUgPSAqcHRyOyAgLy8gQW4geDg2IGxvYWQgYWN0cyBhcyBhIGFjcXVpcmUgYmFycmllciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGN1cnJlbnQgQU1EL0ludGVsIGNoaXBzIGFzIG9mIEphbiAyMDA4LgorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWUgYWxzbyBSZWxlYXNlX1N0b3JlKCksIGFib3ZlLgorICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHggPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIGlmIChBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlcy5oYXNfYW1kX2xvY2tfbWJfYnVnKSB7CisgICAgX19hc21fXyBfX3ZvbGF0aWxlX18oImxmZW5jZSIgOiA6IDogIm1lbW9yeSIpOworICB9CisgIHJldHVybiB4OworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKKyNlbmRpZiAgLy8gZGVmaW5lZChfX3g4Nl82NF9fKQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjdW5kZWYgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19YODZfR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzQxYjE2NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5jYwpAQCAtMCwwICsxLDExMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoZSBjb21waWxhdGlvbiBvZiBleHRlbnNpb25fc2V0LmNjIGZhaWxzIHdoZW4gd2luZG93cy5oIGlzIGluY2x1ZGVkLgorLy8gVGhlcmVmb3JlIHdlIG1vdmUgdGhlIGNvZGUgZGVwZW5kaW5nIG9uIHdpbmRvd3MuaCB0byB0aGlzIHNlcGFyYXRlIGNjIGZpbGUuCisKKy8vIERvbid0IGNvbXBpbGUgdGhpcyBmaWxlIGZvciBwZW9wbGUgbm90IGNvbmNlcm5lZCBhYm91dCB0aHJlYWQgc2FmZXR5LgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X01TVkNfSF8KKworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcigpIHsKKyAgLy8gV2UgdXNlIE1lbW9yeUJhcnJpZXIgZnJvbSBXaW5OVC5oCisgIDo6TWVtb3J5QmFycmllcigpOworfQorCitBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIExPTkcgcmVzdWx0ID0gSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoCisgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIExPTkcqPihwdHIpLAorICAgICAgc3RhdGljX2Nhc3Q8TE9ORz4obmV3X3ZhbHVlKSwKKyAgICAgIHN0YXRpY19jYXN0PExPTkc+KG9sZF92YWx1ZSkpOworICByZXR1cm4gc3RhdGljX2Nhc3Q8QXRvbWljMzI+KHJlc3VsdCk7Cit9CisKK0F0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBMT05HIHJlc3VsdCA9IEludGVybG9ja2VkRXhjaGFuZ2UoCisgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIExPTkcqPihwdHIpLAorICAgICAgc3RhdGljX2Nhc3Q8TE9ORz4obmV3X3ZhbHVlKSk7CisgIHJldHVybiBzdGF0aWNfY2FzdDxBdG9taWMzMj4ocmVzdWx0KTsKK30KKworQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gSW50ZXJsb2NrZWRFeGNoYW5nZUFkZCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgTE9ORyo+KHB0ciksCisgICAgICBzdGF0aWNfY2FzdDxMT05HPihpbmNyZW1lbnQpKSArIGluY3JlbWVudDsKK30KKworI2lmIGRlZmluZWQoX1dJTjY0KQorCisvLyA2NC1iaXQgbG93LWxldmVsIG9wZXJhdGlvbnMgb24gNjQtYml0IHBsYXRmb3JtLgorCitBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIFBWT0lEIHJlc3VsdCA9IEludGVybG9ja2VkQ29tcGFyZUV4Y2hhbmdlUG9pbnRlcigKKyAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIFBWT0lEKj4ocHRyKSwKKyAgICByZWludGVycHJldF9jYXN0PFBWT0lEPihuZXdfdmFsdWUpLCByZWludGVycHJldF9jYXN0PFBWT0lEPihvbGRfdmFsdWUpKTsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8QXRvbWljNjQ+KHJlc3VsdCk7Cit9CisKK0F0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBQVk9JRCByZXN1bHQgPSBJbnRlcmxvY2tlZEV4Y2hhbmdlUG9pbnRlcigKKyAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIFBWT0lEKj4ocHRyKSwKKyAgICByZWludGVycHJldF9jYXN0PFBWT0lEPihuZXdfdmFsdWUpKTsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8QXRvbWljNjQ+KHJlc3VsdCk7Cit9CisKK0F0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIEludGVybG9ja2VkRXhjaGFuZ2VBZGQ2NCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgTE9OR0xPTkcqPihwdHIpLAorICAgICAgc3RhdGljX2Nhc3Q8TE9OR0xPTkc+KGluY3JlbWVudCkpICsgaW5jcmVtZW50OworfQorCisjZW5kaWYgIC8vIGRlZmluZWQoX1dJTjY0KQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9NU1ZDX0hfCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9OT19USFJFQURfU0FGRVRZCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1M2E2NDEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuaApAQCAtMCwwICsxLDE1MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9NU1ZDX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9NU1ZDX0hfCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHB0ciwgaW5jcmVtZW50KTsKK30KKworI2lmICEoZGVmaW5lZChfTVNDX1ZFUikgJiYgX01TQ19WRVIgPj0gMTQwMCkKKyNlcnJvciAiV2UgcmVxdWlyZSBhdCBsZWFzdCB2czIwMDUgZm9yIE1lbW9yeUJhcnJpZXIiCisjZW5kaWYKKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHB0ciwgdmFsdWUpOworICAgICAgICAgICAgICAvLyBhY3RzIGFzIGEgYmFycmllciBpbiB0aGlzIGltcGxlbWVudGF0aW9uCit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOyAgLy8gd29ya3Mgdy9vIGJhcnJpZXIgZm9yIGN1cnJlbnQgSW50ZWwgY2hpcHMgYXMgb2YgSnVuZSAyMDA1CisgIC8vIFNlZSBjb21tZW50cyBpbiBBdG9taWM2NCB2ZXJzaW9uIG9mIFJlbGVhc2VfU3RvcmUoKSBiZWxvdy4KK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWx1ZSA9ICpwdHI7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKKyNpZiBkZWZpbmVkKF9XSU42NCkKKworLy8gNjQtYml0IGxvdy1sZXZlbCBvcGVyYXRpb25zIG9uIDY0LWJpdCBwbGF0Zm9ybS4KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICByZXR1cm4gQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZShwdHIsIHZhbHVlKTsKKyAgICAgICAgICAgICAgLy8gYWN0cyBhcyBhIGJhcnJpZXIgaW4gdGhpcyBpbXBsZW1lbnRhdGlvbgorfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsgIC8vIHdvcmtzIHcvbyBiYXJyaWVyIGZvciBjdXJyZW50IEludGVsIGNoaXBzIGFzIG9mIEp1bmUgMjAwNQorCisgIC8vIFdoZW4gbmV3IGNoaXBzIGNvbWUgb3V0LCBjaGVjazoKKyAgLy8gIElBLTMyIEludGVsIEFyY2hpdGVjdHVyZSBTb2Z0d2FyZSBEZXZlbG9wZXIncyBNYW51YWwsIFZvbHVtZSAzOgorICAvLyAgU3lzdGVtIFByb2dyYW1taW5nIEd1aWRlLCBDaGF0cGVyIDc6IE11bHRpcGxlLXByb2Nlc3NvciBtYW5hZ2VtZW50LAorICAvLyAgU2VjdGlvbiA3LjIsIE1lbW9yeSBPcmRlcmluZy4KKyAgLy8gTGFzdCBzZWVuIGF0OgorICAvLyAgIGh0dHA6Ly9kZXZlbG9wZXIuaW50ZWwuY29tL2Rlc2lnbi9wZW50aXVtNC9tYW51YWxzL2luZGV4X25ldy5odG0KK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBBdG9taWM2NCB2YWx1ZSA9ICpwdHI7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCisjZW5kaWYgIC8vIGRlZmluZWQoX1dJTjY0KQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9NU1ZDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Nhc3RzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Nhc3RzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NjZjY1YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaApAQCAtMCwwICsxLDEyMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NBU1RTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ0FTVFNfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisvLyBVc2UgaW1wbGljaXRfY2FzdCBhcyBhIHNhZmUgdmVyc2lvbiBvZiBzdGF0aWNfY2FzdCBvciBjb25zdF9jYXN0CisvLyBmb3IgdXBjYXN0aW5nIGluIHRoZSB0eXBlIGhpZXJhcmNoeSAoaS5lLiBjYXN0aW5nIGEgcG9pbnRlciB0byBGb28KKy8vIHRvIGEgcG9pbnRlciB0byBTdXBlcmNsYXNzT2ZGb28gb3IgY2FzdGluZyBhIHBvaW50ZXIgdG8gRm9vIHRvCisvLyBhIGNvbnN0IHBvaW50ZXIgdG8gRm9vKS4KKy8vIFdoZW4geW91IHVzZSBpbXBsaWNpdF9jYXN0LCB0aGUgY29tcGlsZXIgY2hlY2tzIHRoYXQgdGhlIGNhc3QgaXMgc2FmZS4KKy8vIFN1Y2ggZXhwbGljaXQgaW1wbGljaXRfY2FzdHMgYXJlIG5lY2Vzc2FyeSBpbiBzdXJwcmlzaW5nbHkgbWFueQorLy8gc2l0dWF0aW9ucyB3aGVyZSBDKysgZGVtYW5kcyBhbiBleGFjdCB0eXBlIG1hdGNoIGluc3RlYWQgb2YgYW4KKy8vIGFyZ3VtZW50IHR5cGUgY29udmVydGFibGUgdG8gYSB0YXJnZXQgdHlwZS4KKy8vCisvLyBUaGUgRnJvbSB0eXBlIGNhbiBiZSBpbmZlcnJlZCwgc28gdGhlIHByZWZlcnJlZCBzeW50YXggZm9yIHVzaW5nCisvLyBpbXBsaWNpdF9jYXN0IGlzIHRoZSBzYW1lIGFzIGZvciBzdGF0aWNfY2FzdCBldGMuOgorLy8KKy8vICAgaW1wbGljaXRfY2FzdDxUb1R5cGU+KGV4cHIpCisvLworLy8gaW1wbGljaXRfY2FzdCB3b3VsZCBoYXZlIGJlZW4gcGFydCBvZiB0aGUgQysrIHN0YW5kYXJkIGxpYnJhcnksCisvLyBidXQgdGhlIHByb3Bvc2FsIHdhcyBzdWJtaXR0ZWQgdG9vIGxhdGUuICBJdCB3aWxsIHByb2JhYmx5IG1ha2UKKy8vIGl0cyB3YXkgaW50byB0aGUgbGFuZ3VhZ2UgaW4gdGhlIGZ1dHVyZS4KK3RlbXBsYXRlPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgoraW5saW5lIFRvIGltcGxpY2l0X2Nhc3QoRnJvbSBjb25zdCAmZikgeworICByZXR1cm4gZjsKK30KKworLy8gV2hlbiB5b3UgdXBjYXN0ICh0aGF0IGlzLCBjYXN0IGEgcG9pbnRlciBmcm9tIHR5cGUgRm9vIHRvIHR5cGUKKy8vIFN1cGVyY2xhc3NPZkZvbyksIGl0J3MgZmluZSB0byB1c2UgaW1wbGljaXRfY2FzdDw+LCBzaW5jZSB1cGNhc3RzCisvLyBhbHdheXMgc3VjY2VlZC4gIFdoZW4geW91IGRvd25jYXN0ICh0aGF0IGlzLCBjYXN0IGEgcG9pbnRlciBmcm9tCisvLyB0eXBlIEZvbyB0byB0eXBlIFN1YmNsYXNzT2ZGb28pLCBzdGF0aWNfY2FzdDw+IGlzbid0IHNhZmUsIGJlY2F1c2UKKy8vIGhvdyBkbyB5b3Uga25vdyB0aGUgcG9pbnRlciBpcyByZWFsbHkgb2YgdHlwZSBTdWJjbGFzc09mRm9vPyAgSXQKKy8vIGNvdWxkIGJlIGEgYmFyZSBGb28sIG9yIG9mIHR5cGUgRGlmZmVyZW50U3ViY2xhc3NPZkZvby4gIFRodXMsCisvLyB3aGVuIHlvdSBkb3duY2FzdCwgeW91IHNob3VsZCB1c2UgdGhpcyBtYWNyby4gIEluIGRlYnVnIG1vZGUsIHdlCisvLyB1c2UgZHluYW1pY19jYXN0PD4gdG8gZG91YmxlLWNoZWNrIHRoZSBkb3duY2FzdCBpcyBsZWdhbCAod2UgZGllCisvLyBpZiBpdCdzIG5vdCkuICBJbiBub3JtYWwgbW9kZSwgd2UgZG8gdGhlIGVmZmljaWVudCBzdGF0aWNfY2FzdDw+CisvLyBpbnN0ZWFkLiAgVGh1cywgaXQncyBpbXBvcnRhbnQgdG8gdGVzdCBpbiBkZWJ1ZyBtb2RlIHRvIG1ha2Ugc3VyZQorLy8gdGhlIGNhc3QgaXMgbGVnYWwhCisvLyAgICBUaGlzIGlzIHRoZSBvbmx5IHBsYWNlIGluIHRoZSBjb2RlIHdlIHNob3VsZCB1c2UgZHluYW1pY19jYXN0PD4uCisvLyBJbiBwYXJ0aWN1bGFyLCB5b3UgU0hPVUxETidUIGJlIHVzaW5nIGR5bmFtaWNfY2FzdDw+IGluIG9yZGVyIHRvCisvLyBkbyBSVFRJIChlZyBjb2RlIGxpa2UgdGhpczoKKy8vICAgIGlmIChkeW5hbWljX2Nhc3Q8U3ViY2xhc3MxPihmb28pKSBIYW5kbGVBU3ViY2xhc3MxT2JqZWN0KGZvbyk7CisvLyAgICBpZiAoZHluYW1pY19jYXN0PFN1YmNsYXNzMj4oZm9vKSkgSGFuZGxlQVN1YmNsYXNzMk9iamVjdChmb28pOworLy8gWW91IHNob3VsZCBkZXNpZ24gdGhlIGNvZGUgc29tZSBvdGhlciB3YXkgbm90IHRvIG5lZWQgdGhpcy4KKwordGVtcGxhdGU8dHlwZW5hbWUgVG8sIHR5cGVuYW1lIEZyb20+ICAgICAvLyB1c2UgbGlrZSB0aGlzOiBkb3duX2Nhc3Q8VCo+KGZvbyk7CitpbmxpbmUgVG8gZG93bl9jYXN0KEZyb20qIGYpIHsgICAgICAgICAgICAgICAgICAgLy8gc28gd2Ugb25seSBhY2NlcHQgcG9pbnRlcnMKKyAgLy8gRW5zdXJlcyB0aGF0IFRvIGlzIGEgc3ViLXR5cGUgb2YgRnJvbSAqLiAgVGhpcyB0ZXN0IGlzIGhlcmUgb25seQorICAvLyBmb3IgY29tcGlsZS10aW1lIHR5cGUgY2hlY2tpbmcsIGFuZCBoYXMgbm8gb3ZlcmhlYWQgaW4gYW4KKyAgLy8gb3B0aW1pemVkIGJ1aWxkIGF0IHJ1bi10aW1lLCBhcyBpdCB3aWxsIGJlIG9wdGltaXplZCBhd2F5CisgIC8vIGNvbXBsZXRlbHkuCisgIGlmIChmYWxzZSkgeworICAgIGltcGxpY2l0X2Nhc3Q8RnJvbSosIFRvPigwKTsKKyAgfQorCisjaWYgIWRlZmluZWQoTkRFQlVHKSAmJiAhZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSkKKyAgYXNzZXJ0KGYgPT0gTlVMTCB8fCBkeW5hbWljX2Nhc3Q8VG8+KGYpICE9IE5VTEwpOyAgLy8gUlRUSTogZGVidWcgbW9kZSBvbmx5IQorI2VuZGlmCisgIHJldHVybiBzdGF0aWNfY2FzdDxUbz4oZik7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPiAgICAvLyB1c2UgbGlrZSB0aGlzOiBkb3duX2Nhc3Q8VCY+KGZvbyk7CitpbmxpbmUgVG8gZG93bl9jYXN0KEZyb20mIGYpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSByZW1vdmVfcmVmZXJlbmNlPFRvPjo6dHlwZSogVG9Bc1BvaW50ZXI7CisgIC8vIEVuc3VyZXMgdGhhdCBUbyBpcyBhIHN1Yi10eXBlIG9mIEZyb20gKi4gIFRoaXMgdGVzdCBpcyBoZXJlIG9ubHkKKyAgLy8gZm9yIGNvbXBpbGUtdGltZSB0eXBlIGNoZWNraW5nLCBhbmQgaGFzIG5vIG92ZXJoZWFkIGluIGFuCisgIC8vIG9wdGltaXplZCBidWlsZCBhdCBydW4tdGltZSwgYXMgaXQgd2lsbCBiZSBvcHRpbWl6ZWQgYXdheQorICAvLyBjb21wbGV0ZWx5LgorICBpZiAoZmFsc2UpIHsKKyAgICBpbXBsaWNpdF9jYXN0PEZyb20qLCBUb0FzUG9pbnRlcj4oMCk7CisgIH0KKworI2lmICFkZWZpbmVkKE5ERUJVRykgJiYgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1JUVEkpCisgIC8vIFJUVEk6IGRlYnVnIG1vZGUgb25seSEKKyAgYXNzZXJ0KGR5bmFtaWNfY2FzdDxUb0FzUG9pbnRlcj4oJmYpICE9IE5VTEwpOworI2VuZGlmCisgIHJldHVybiAqc3RhdGljX2Nhc3Q8VG9Bc1BvaW50ZXI+KCZmKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKy8vIFdlIG1hZGUgdGhlc2UgaW50ZXJuYWwgc28gdGhhdCB0aGV5IHdvdWxkIHNob3cgdXAgYXMgc3VjaCBpbiB0aGUgZG9jcywKKy8vIGJ1dCB3ZSBkb24ndCB3YW50IHRvIHN0aWNrICJpbnRlcm5hbDo6IiBpbiBmcm9udCBvZiB0aGVtIGV2ZXJ5d2hlcmUuCit1c2luZyBpbnRlcm5hbDo6aW1wbGljaXRfY2FzdDsKK3VzaW5nIGludGVybmFsOjpkb3duX2Nhc3Q7CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ0FTVFNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0ZTAwY2MKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5jYwpAQCAtMCwwICsxLDM5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlICJjb25maWcuaCIKKworI2lmZGVmIF9XSU4zMgorI2RlZmluZSBXSU4zMl9MRUFOX0FORF9NRUFOICAvLyBXZSBvbmx5IG5lZWQgbWluaW1hbCBpbmNsdWRlcworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNkZWZpbmUgc25wcmludGYgX3NucHJpbnRmICAgIC8vIHNlZSBjb21tZW50IGluIHN0cnV0aWwuY2MKKyNlbGlmIGRlZmluZWQoSEFWRV9QVEhSRUFEKQorI2luY2x1ZGUgPHB0aHJlYWQuaD4KKyNlbHNlCisjZXJyb3IgIk5vIHN1aXRhYmxlIHRocmVhZGluZyBsaWJyYXJ5IGF2YWlsYWJsZS4iCisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW50ZXJuYWwgeworCit2b2lkIFZlcmlmeVZlcnNpb24oaW50IGhlYWRlclZlcnNpb24sCisgICAgICAgICAgICAgICAgICAgaW50IG1pbkxpYnJhcnlWZXJzaW9uLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGZpbGVuYW1lKSB7CisgIGlmIChHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IG1pbkxpYnJhcnlWZXJzaW9uKSB7CisgICAgLy8gTGlicmFyeSBpcyB0b28gb2xkIGZvciBoZWFkZXJzLgorICAgIEdPT0dMRV9MT0coRkFUQUwpCisgICAgICA8PCAiVGhpcyBwcm9ncmFtIHJlcXVpcmVzIHZlcnNpb24gIiA8PCBWZXJzaW9uU3RyaW5nKG1pbkxpYnJhcnlWZXJzaW9uKQorICAgICAgPDwgIiBvZiB0aGUgUHJvdG9jb2wgQnVmZmVyIHJ1bnRpbWUgbGlicmFyeSwgYnV0IHRoZSBpbnN0YWxsZWQgdmVyc2lvbiAiCisgICAgICAgICAiaXMgIiA8PCBWZXJzaW9uU3RyaW5nKEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OKSA8PCAiLiAgUGxlYXNlIHVwZGF0ZSAiCisgICAgICAgICAieW91ciBsaWJyYXJ5LiAgSWYgeW91IGNvbXBpbGVkIHRoZSBwcm9ncmFtIHlvdXJzZWxmLCBtYWtlIHN1cmUgdGhhdCAiCisgICAgICAgICAieW91ciBoZWFkZXJzIGFyZSBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgUHJvdG9jb2wgQnVmZmVycyBhcyB5b3VyICIKKyAgICAgICAgICJsaW5rLXRpbWUgbGlicmFyeS4gIChWZXJzaW9uIHZlcmlmaWNhdGlvbiBmYWlsZWQgaW4gXCIiCisgICAgICA8PCBmaWxlbmFtZSA8PCAiXCIuKSI7CisgIH0KKyAgaWYgKGhlYWRlclZlcnNpb24gPCBrTWluSGVhZGVyVmVyc2lvbkZvckxpYnJhcnkpIHsKKyAgICAvLyBIZWFkZXJzIGFyZSB0b28gb2xkIGZvciBsaWJyYXJ5LgorICAgIEdPT0dMRV9MT0coRkFUQUwpCisgICAgICA8PCAiVGhpcyBwcm9ncmFtIHdhcyBjb21waWxlZCBhZ2FpbnN0IHZlcnNpb24gIgorICAgICAgPDwgVmVyc2lvblN0cmluZyhoZWFkZXJWZXJzaW9uKSA8PCAiIG9mIHRoZSBQcm90b2NvbCBCdWZmZXIgcnVudGltZSAiCisgICAgICAgICAibGlicmFyeSwgd2hpY2ggaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgaW5zdGFsbGVkIHZlcnNpb24gKCIKKyAgICAgIDw8IFZlcnNpb25TdHJpbmcoR09PR0xFX1BST1RPQlVGX1ZFUlNJT04pIDw8ICAiKS4gIENvbnRhY3QgdGhlIHByb2dyYW0gIgorICAgICAgICAgImF1dGhvciBmb3IgYW4gdXBkYXRlLiAgSWYgeW91IGNvbXBpbGVkIHRoZSBwcm9ncmFtIHlvdXJzZWxmLCBtYWtlICIKKyAgICAgICAgICJzdXJlIHRoYXQgeW91ciBoZWFkZXJzIGFyZSBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgUHJvdG9jb2wgQnVmZmVycyAiCisgICAgICAgICAiYXMgeW91ciBsaW5rLXRpbWUgbGlicmFyeS4gIChWZXJzaW9uIHZlcmlmaWNhdGlvbiBmYWlsZWQgaW4gXCIiCisgICAgICA8PCBmaWxlbmFtZSA8PCAiXCIuKSI7CisgIH0KK30KKworc3RyaW5nIFZlcnNpb25TdHJpbmcoaW50IHZlcnNpb24pIHsKKyAgaW50IG1ham9yID0gdmVyc2lvbiAvIDEwMDAwMDA7CisgIGludCBtaW5vciA9ICh2ZXJzaW9uIC8gMTAwMCkgJSAxMDAwOworICBpbnQgbWljcm8gPSB2ZXJzaW9uICUgMTAwMDsKKworICAvLyAxMjggYnl0ZXMgc2hvdWxkIGFsd2F5cyBiZSBlbm91Z2gsIGJ1dCB3ZSB1c2Ugc25wcmludGYoKSBhbnl3YXkgdG8gYmUKKyAgLy8gc2FmZS4KKyAgY2hhciBidWZmZXJbMTI4XTsKKyAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIiVkLiVkLiVkIiwgbWFqb3IsIG1pbm9yLCBtaWNybyk7CisKKyAgLy8gR3VhcmQgYWdhaW5zdCBicm9rZW4gTVNWQyBzbnByaW50ZigpLgorICBidWZmZXJbc2l6ZW9mKGJ1ZmZlciktMV0gPSAnXDAnOworCisgIHJldHVybiBidWZmZXI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvbG9nZ2luZy5jYworCituYW1lc3BhY2UgaW50ZXJuYWwgeworCit2b2lkIERlZmF1bHRMb2dIYW5kbGVyKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICBzdGF0aWMgY29uc3QgY2hhciogbGV2ZWxfbmFtZXNbXSA9IHsgIklORk8iLCAiV0FSTklORyIsICJFUlJPUiIsICJGQVRBTCIgfTsKKworICAvLyBXZSB1c2UgZnByaW50ZigpIGluc3RlYWQgb2YgY2VyciBiZWNhdXNlIHdlIHdhbnQgdGhpcyB0byB3b3JrIGF0IHN0YXRpYworICAvLyBpbml0aWFsaXphdGlvbiB0aW1lLgorICBmcHJpbnRmKHN0ZGVyciwgIltsaWJwcm90b2J1ZiAlcyAlczolZF0gJXNcbiIsCisgICAgICAgICAgbGV2ZWxfbmFtZXNbbGV2ZWxdLCBmaWxlbmFtZSwgbGluZSwgbWVzc2FnZS5jX3N0cigpKTsKKyAgZmZsdXNoKHN0ZGVycik7ICAvLyBOZWVkZWQgb24gTVNWQy4KK30KKwordm9pZCBOdWxsTG9nSGFuZGxlcihMb2dMZXZlbCAvKiBsZXZlbCAqLywgY29uc3QgY2hhciogLyogZmlsZW5hbWUgKi8sCisgICAgICAgICAgICAgICAgICAgIGludCAvKiBsaW5lICovLCBjb25zdCBzdHJpbmcmIC8qIG1lc3NhZ2UgKi8pIHsKKyAgLy8gTm90aGluZy4KK30KKworc3RhdGljIExvZ0hhbmRsZXIqIGxvZ19oYW5kbGVyXyA9ICZEZWZhdWx0TG9nSGFuZGxlcjsKK3N0YXRpYyBpbnQgbG9nX3NpbGVuY2VyX2NvdW50XyA9IDA7CisKK3N0YXRpYyBNdXRleCogbG9nX3NpbGVuY2VyX2NvdW50X211dGV4XyA9IE5VTEw7CitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGxvZ19zaWxlbmNlcl9jb3VudF9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlTG9nU2lsZW5jZXJDb3VudCgpIHsKKyAgZGVsZXRlIGxvZ19zaWxlbmNlcl9jb3VudF9tdXRleF87CisgIGxvZ19zaWxlbmNlcl9jb3VudF9tdXRleF8gPSBOVUxMOworfQordm9pZCBJbml0TG9nU2lsZW5jZXJDb3VudCgpIHsKKyAgbG9nX3NpbGVuY2VyX2NvdW50X211dGV4XyA9IG5ldyBNdXRleDsKKyAgT25TaHV0ZG93bigmRGVsZXRlTG9nU2lsZW5jZXJDb3VudCk7Cit9Cit2b2lkIEluaXRMb2dTaWxlbmNlckNvdW50T25jZSgpIHsKKyAgR29vZ2xlT25jZUluaXQoJmxvZ19zaWxlbmNlcl9jb3VudF9pbml0XywgJkluaXRMb2dTaWxlbmNlckNvdW50KTsKK30KKworTG9nTWVzc2FnZSYgTG9nTWVzc2FnZTo6b3BlcmF0b3I8PChjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIG1lc3NhZ2VfICs9IHZhbHVlOworICByZXR1cm4gKnRoaXM7Cit9CisKK0xvZ01lc3NhZ2UmIExvZ01lc3NhZ2U6Om9wZXJhdG9yPDwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgbWVzc2FnZV8gKz0gdmFsdWU7CisgIHJldHVybiAqdGhpczsKK30KKworLy8gU2luY2UgdGhpcyBpcyBqdXN0IGZvciBsb2dnaW5nLCB3ZSBkb24ndCBjYXJlIGlmIHRoZSBjdXJyZW50IGxvY2FsZSBjaGFuZ2VzCisvLyB0aGUgcmVzdWx0cyAtLSBpbiBmYWN0LCB3ZSBwcm9iYWJseSBwcmVmZXIgdGhhdC4gIFNvIHdlIHVzZSBzbnByaW50ZigpCisvLyBpbnN0ZWFkIG9mIFNpbXBsZSp0b2EoKS4KKyN1bmRlZiBERUNMQVJFX1NUUkVBTV9PUEVSQVRPUgorI2RlZmluZSBERUNMQVJFX1NUUkVBTV9PUEVSQVRPUihUWVBFLCBGT1JNQVQpICAgICAgICAgICAgICAgICAgICAgICBcCisgIExvZ01lc3NhZ2UmIExvZ01lc3NhZ2U6Om9wZXJhdG9yPDwoVFlQRSB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgIFwKKyAgICAvKiAxMjggYnl0ZXMgc2hvdWxkIGJlIGJpZyBlbm91Z2ggZm9yIGFueSBvZiB0aGUgcHJpbWl0aXZlICovICAgXAorICAgIC8qIHZhbHVlcyB3aGljaCB3ZSBwcmludCB3aXRoIHRoaXMsIGJ1dCB3ZWxsIHVzZSBzbnByaW50ZigpICovICBcCisgICAgLyogYW55d2F5IHRvIGJlIGV4dHJhIHNhZmUuICovICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjaGFyIGJ1ZmZlclsxMjhdOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksIEZPUk1BVCwgdmFsdWUpOyAgICAgICAgICAgICAgICBcCisgICAgLyogR3VhcmQgYWdhaW5zdCBicm9rZW4gTVNWQyBzbnByaW50ZigpLiAqLyAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBidWZmZXJbc2l6ZW9mKGJ1ZmZlciktMV0gPSAnXDAnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIG1lc3NhZ2VfICs9IGJ1ZmZlcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuICp0aGlzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCitERUNMQVJFX1NUUkVBTV9PUEVSQVRPUihjaGFyICAgICAgICAgLCAiJWMiICkKK0RFQ0xBUkVfU1RSRUFNX09QRVJBVE9SKGludCAgICAgICAgICAsICIlZCIgKQorREVDTEFSRV9TVFJFQU1fT1BFUkFUT1IodWludCAgICAgICAgICwgIiV1IiApCitERUNMQVJFX1NUUkVBTV9PUEVSQVRPUihsb25nICAgICAgICAgLCAiJWxkIikKK0RFQ0xBUkVfU1RSRUFNX09QRVJBVE9SKHVuc2lnbmVkIGxvbmcsICIlbHUiKQorREVDTEFSRV9TVFJFQU1fT1BFUkFUT1IoZG91YmxlICAgICAgICwgIiVnIiApCitERUNMQVJFX1NUUkVBTV9PUEVSQVRPUih2b2lkKiAgICAgICAgLCAiJXAiICkKKyN1bmRlZiBERUNMQVJFX1NUUkVBTV9PUEVSQVRPUgorCitMb2dNZXNzYWdlOjpMb2dNZXNzYWdlKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUpCisgIDogbGV2ZWxfKGxldmVsKSwgZmlsZW5hbWVfKGZpbGVuYW1lKSwgbGluZV8obGluZSkge30KK0xvZ01lc3NhZ2U6On5Mb2dNZXNzYWdlKCkge30KKwordm9pZCBMb2dNZXNzYWdlOjpGaW5pc2goKSB7CisgIGJvb2wgc3VwcHJlc3MgPSBmYWxzZTsKKworICBpZiAobGV2ZWxfICE9IExPR0xFVkVMX0ZBVEFMKSB7CisgICAgSW5pdExvZ1NpbGVuY2VyQ291bnRPbmNlKCk7CisgICAgTXV0ZXhMb2NrIGxvY2sobG9nX3NpbGVuY2VyX2NvdW50X211dGV4Xyk7CisgICAgc3VwcHJlc3MgPSBsb2dfc2lsZW5jZXJfY291bnRfID4gMDsKKyAgfQorCisgIGlmICghc3VwcHJlc3MpIHsKKyAgICBsb2dfaGFuZGxlcl8obGV2ZWxfLCBmaWxlbmFtZV8sIGxpbmVfLCBtZXNzYWdlXyk7CisgIH0KKworICBpZiAobGV2ZWxfID09IExPR0xFVkVMX0ZBVEFMKSB7CisjaWYgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMKKyAgICB0aHJvdyBGYXRhbEV4Y2VwdGlvbihmaWxlbmFtZV8sIGxpbmVfLCBtZXNzYWdlXyk7CisjZWxzZQorICAgIGFib3J0KCk7CisjZW5kaWYKKyAgfQorfQorCit2b2lkIExvZ0ZpbmlzaGVyOjpvcGVyYXRvcj0oTG9nTWVzc2FnZSYgb3RoZXIpIHsKKyAgb3RoZXIuRmluaXNoKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCitMb2dIYW5kbGVyKiBTZXRMb2dIYW5kbGVyKExvZ0hhbmRsZXIqIG5ld19mdW5jKSB7CisgIExvZ0hhbmRsZXIqIG9sZCA9IGludGVybmFsOjpsb2dfaGFuZGxlcl87CisgIGlmIChvbGQgPT0gJmludGVybmFsOjpOdWxsTG9nSGFuZGxlcikgeworICAgIG9sZCA9IE5VTEw7CisgIH0KKyAgaWYgKG5ld19mdW5jID09IE5VTEwpIHsKKyAgICBpbnRlcm5hbDo6bG9nX2hhbmRsZXJfID0gJmludGVybmFsOjpOdWxsTG9nSGFuZGxlcjsKKyAgfSBlbHNlIHsKKyAgICBpbnRlcm5hbDo6bG9nX2hhbmRsZXJfID0gbmV3X2Z1bmM7CisgIH0KKyAgcmV0dXJuIG9sZDsKK30KKworTG9nU2lsZW5jZXI6OkxvZ1NpbGVuY2VyKCkgeworICBpbnRlcm5hbDo6SW5pdExvZ1NpbGVuY2VyQ291bnRPbmNlKCk7CisgIE11dGV4TG9jayBsb2NrKGludGVybmFsOjpsb2dfc2lsZW5jZXJfY291bnRfbXV0ZXhfKTsKKyAgKytpbnRlcm5hbDo6bG9nX3NpbGVuY2VyX2NvdW50XzsKK307CisKK0xvZ1NpbGVuY2VyOjp+TG9nU2lsZW5jZXIoKSB7CisgIGludGVybmFsOjpJbml0TG9nU2lsZW5jZXJDb3VudE9uY2UoKTsKKyAgTXV0ZXhMb2NrIGxvY2soaW50ZXJuYWw6OmxvZ19zaWxlbmNlcl9jb3VudF9tdXRleF8pOworICAtLWludGVybmFsOjpsb2dfc2lsZW5jZXJfY291bnRfOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZW11bGF0ZXMgZ29vZ2xlMy9iYXNlL2NhbGxiYWNrLmNjCisKK0Nsb3N1cmU6On5DbG9zdXJlKCkge30KKworbmFtZXNwYWNlIGludGVybmFsIHsgRnVuY3Rpb25DbG9zdXJlMDo6fkZ1bmN0aW9uQ2xvc3VyZTAoKSB7fSB9CisKK3ZvaWQgRG9Ob3RoaW5nKCkge30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZW11bGF0ZXMgZ29vZ2xlMy9iYXNlL211dGV4LmNjCisKKyNpZmRlZiBfV0lOMzIKKworc3RydWN0IE11dGV4OjpJbnRlcm5hbCB7CisgIENSSVRJQ0FMX1NFQ1RJT04gbXV0ZXg7CisjaWZuZGVmIE5ERUJVRworICAvLyBVc2VkIG9ubHkgdG8gaW1wbGVtZW50IEFzc2VydEhlbGQoKS4KKyAgRFdPUkQgdGhyZWFkX2lkOworI2VuZGlmCit9OworCitNdXRleDo6TXV0ZXgoKQorICA6IG1JbnRlcm5hbChuZXcgSW50ZXJuYWwpIHsKKyAgSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmbUludGVybmFsLT5tdXRleCk7Cit9CisKK011dGV4Ojp+TXV0ZXgoKSB7CisgIERlbGV0ZUNyaXRpY2FsU2VjdGlvbigmbUludGVybmFsLT5tdXRleCk7CisgIGRlbGV0ZSBtSW50ZXJuYWw7Cit9CisKK3ZvaWQgTXV0ZXg6OkxvY2soKSB7CisgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZtSW50ZXJuYWwtPm11dGV4KTsKKyNpZm5kZWYgTkRFQlVHCisgIG1JbnRlcm5hbC0+dGhyZWFkX2lkID0gR2V0Q3VycmVudFRocmVhZElkKCk7CisjZW5kaWYKK30KKwordm9pZCBNdXRleDo6VW5sb2NrKCkgeworI2lmbmRlZiBOREVCVUcKKyAgbUludGVybmFsLT50aHJlYWRfaWQgPSAwOworI2VuZGlmCisgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZtSW50ZXJuYWwtPm11dGV4KTsKK30KKwordm9pZCBNdXRleDo6QXNzZXJ0SGVsZCgpIHsKKyNpZm5kZWYgTkRFQlVHCisgIEdPT0dMRV9EQ0hFQ0tfRVEobUludGVybmFsLT50aHJlYWRfaWQsIEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKKyNlbmRpZgorfQorCisjZWxpZiBkZWZpbmVkKEhBVkVfUFRIUkVBRCkKKworc3RydWN0IE11dGV4OjpJbnRlcm5hbCB7CisgIHB0aHJlYWRfbXV0ZXhfdCBtdXRleDsKK307CisKK011dGV4OjpNdXRleCgpCisgIDogbUludGVybmFsKG5ldyBJbnRlcm5hbCkgeworICBwdGhyZWFkX211dGV4X2luaXQoJm1JbnRlcm5hbC0+bXV0ZXgsIE5VTEwpOworfQorCitNdXRleDo6fk11dGV4KCkgeworICBwdGhyZWFkX211dGV4X2Rlc3Ryb3koJm1JbnRlcm5hbC0+bXV0ZXgpOworICBkZWxldGUgbUludGVybmFsOworfQorCit2b2lkIE11dGV4OjpMb2NrKCkgeworICBpbnQgcmVzdWx0ID0gcHRocmVhZF9tdXRleF9sb2NrKCZtSW50ZXJuYWwtPm11dGV4KTsKKyAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInB0aHJlYWRfbXV0ZXhfbG9jazogIiA8PCBzdHJlcnJvcihyZXN1bHQpOworICB9Cit9CisKK3ZvaWQgTXV0ZXg6OlVubG9jaygpIHsKKyAgaW50IHJlc3VsdCA9IHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZtSW50ZXJuYWwtPm11dGV4KTsKKyAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInB0aHJlYWRfbXV0ZXhfdW5sb2NrOiAiIDw8IHN0cmVycm9yKHJlc3VsdCk7CisgIH0KK30KKwordm9pZCBNdXRleDo6QXNzZXJ0SGVsZCgpIHsKKyAgLy8gcHRocmVhZHMgZG9zbid0IHByb3ZpZGUgYSB3YXkgdG8gY2hlY2sgd2hpY2ggdGhyZWFkIGhvbGRzIHRoZSBtdXRleC4KKyAgLy8gVE9ETyhrZW50b24pOiAgTWF5YmUga2VlcCB0cmFjayBvZiBsb2NraW5nIHRocmVhZCBJRCBsaWtlIHdpdGggV0lOMzI/Cit9CisKKyNlbmRpZgorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL3V0aWwvZW5kaWFuL2VuZGlhbi5oCisvLworLy8gVE9ETyh4aWFvZmVuZyk6IFBST1RPQlVGX0xJVFRMRV9FTkRJQU4gaXMgdW5mb3J0dW5hdGVseSBkZWZpbmVkIGluCisvLyBnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmggYW5kIHRoZXJlZm9yZSBjYW4gbm90IGJlIHVzZWQgaGVyZS4KKy8vIE1heWJlIG1vdmUgdGhhdCBtYWNybyBkZWZpbml0aW9uIGhlcmUgaW4gdGhlIGZ1cnR1cmUuCit1aW50MzIgZ2h0b25sKHVpbnQzMiB4KSB7CisgIHVuaW9uIHsKKyAgICB1aW50MzIgcmVzdWx0OworICAgIHVpbnQ4IHJlc3VsdF9hcnJheVs0XTsKKyAgfTsKKyAgcmVzdWx0X2FycmF5WzBdID0gc3RhdGljX2Nhc3Q8dWludDg+KHggPj4gMjQpOworICByZXN1bHRfYXJyYXlbMV0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHggPj4gMTYpICYgMHhGRik7CisgIHJlc3VsdF9hcnJheVsyXSA9IHN0YXRpY19jYXN0PHVpbnQ4PigoeCA+PiA4KSAmIDB4RkYpOworICByZXN1bHRfYXJyYXlbM10gPSBzdGF0aWNfY2FzdDx1aW50OD4oeCAmIDB4RkYpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBTaHV0ZG93biBzdXBwb3J0LgorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCit0eXBlZGVmIHZvaWQgT25TaHV0ZG93bkZ1bmMoKTsKK3ZlY3Rvcjx2b2lkICgqKSgpPiogc2h1dGRvd25fZnVuY3Rpb25zID0gTlVMTDsKK011dGV4KiBzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXggPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShzaHV0ZG93bl9mdW5jdGlvbnNfaW5pdCk7CisKK3ZvaWQgSW5pdFNodXRkb3duRnVuY3Rpb25zKCkgeworICBzaHV0ZG93bl9mdW5jdGlvbnMgPSBuZXcgdmVjdG9yPHZvaWQgKCopKCk+OworICBzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXggPSBuZXcgTXV0ZXg7Cit9CisKK2lubGluZSB2b2lkIEluaXRTaHV0ZG93bkZ1bmN0aW9uc09uY2UoKSB7CisgIEdvb2dsZU9uY2VJbml0KCZzaHV0ZG93bl9mdW5jdGlvbnNfaW5pdCwgJkluaXRTaHV0ZG93bkZ1bmN0aW9ucyk7Cit9CisKK3ZvaWQgT25TaHV0ZG93bih2b2lkICgqZnVuYykoKSkgeworICBJbml0U2h1dGRvd25GdW5jdGlvbnNPbmNlKCk7CisgIE11dGV4TG9jayBsb2NrKHNodXRkb3duX2Z1bmN0aW9uc19tdXRleCk7CisgIHNodXRkb3duX2Z1bmN0aW9ucy0+cHVzaF9iYWNrKGZ1bmMpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKwordm9pZCBTaHV0ZG93blByb3RvYnVmTGlicmFyeSgpIHsKKyAgaW50ZXJuYWw6OkluaXRTaHV0ZG93bkZ1bmN0aW9uc09uY2UoKTsKKworICAvLyBXZSBkb24ndCBuZWVkIHRvIGxvY2sgc2h1dGRvd25fZnVuY3Rpb25zX211dGV4IGJlY2F1c2UgaXQncyB1cCB0byB0aGUKKyAgLy8gY2FsbGVyIHRvIG1ha2Ugc3VyZSB0aGF0IG5vIG9uZSBpcyB1c2luZyB0aGUgbGlicmFyeSBiZWZvcmUgdGhpcyBpcworICAvLyBjYWxsZWQuCisKKyAgLy8gTWFrZSBpdCBzYWZlIHRvIGNhbGwgdGhpcyBtdWx0aXBsZSB0aW1lcy4KKyAgaWYgKGludGVybmFsOjpzaHV0ZG93bl9mdW5jdGlvbnMgPT0gTlVMTCkgcmV0dXJuOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50ZXJuYWw6OnNodXRkb3duX2Z1bmN0aW9ucy0+c2l6ZSgpOyBpKyspIHsKKyAgICBpbnRlcm5hbDo6c2h1dGRvd25fZnVuY3Rpb25zLT5hdChpKSgpOworICB9CisgIGRlbGV0ZSBpbnRlcm5hbDo6c2h1dGRvd25fZnVuY3Rpb25zOworICBpbnRlcm5hbDo6c2h1dGRvd25fZnVuY3Rpb25zID0gTlVMTDsKKyAgZGVsZXRlIGludGVybmFsOjpzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXg7CisgIGludGVybmFsOjpzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXggPSBOVUxMOworfQorCisjaWYgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMKK0ZhdGFsRXhjZXB0aW9uOjp+RmF0YWxFeGNlcHRpb24oKSB0aHJvdygpIHt9CisKK2NvbnN0IGNoYXIqIEZhdGFsRXhjZXB0aW9uOjp3aGF0KCkgY29uc3QgdGhyb3coKSB7CisgIHJldHVybiBtZXNzYWdlXy5jX3N0cigpOworfQorI2VuZGlmCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzNmNzM1YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmgKQEAgLTAsMCArMSwxMjM4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKSBhbmQgb3RoZXJzCisvLworLy8gQ29udGFpbnMgYmFzaWMgdHlwZXMgYW5kIHV0aWxpdGllcyB1c2VkIGJ5IHRoZSByZXN0IG9mIHRoZSBsaWJyYXJ5LgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01NT05fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01NT05fSF9fCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpZiBkZWZpbmVkKF9fb3NmX18pCisvLyBUcnU2NCBsYWNrcyBzdGRpbnQuaCwgYnV0IGhhcyBpbnR0eXBlcy5oIHdoaWNoIGRlZmluZXMgYSBzdXBlcnNldCBvZgorLy8gd2hhdCBzdGRpbnQuaCB3b3VsZCBkZWZpbmUuCisjaW5jbHVkZSA8aW50dHlwZXMuaD4KKyNlbGlmICFkZWZpbmVkKF9NU0NfVkVSKQorI2luY2x1ZGUgPHN0ZGludC5oPgorI2VuZGlmCisKKyNpZm5kZWYgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMKKyNpZiBkZWZpbmVkKF9NU0NfVkVSKSAmJiBkZWZpbmVkKF9DUFBVTldJTkQpCisgICNkZWZpbmUgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMgMQorI2VsaWYgZGVmaW5lZChfX0VYQ0VQVElPTlMpCisgICNkZWZpbmUgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMgMQorI2Vsc2UKKyAgI2RlZmluZSBQUk9UT0JVRl9VU0VfRVhDRVBUSU9OUyAwCisjZW5kaWYKKyNlbmRpZgorCisjaWYgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMKKyNpbmNsdWRlIDxleGNlcHRpb24+CisjZW5kaWYKKworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiBkZWZpbmVkKEdldE1lc3NhZ2UpCisvLyBBbGxvdyBHZXRNZXNzYWdlIHRvIGJlIHVzZWQgYXMgYSB2YWxpZCBtZXRob2QgbmFtZSBpbiBwcm90b2J1ZiBjbGFzc2VzLgorLy8gd2luZG93cy5oIGRlZmluZXMgR2V0TWVzc2FnZSgpIGFzIGEgbWFjcm8uICBMZXQncyByZS1kZWZpbmUgaXQgYXMgYW4gaW5saW5lCisvLyBmdW5jdGlvbi4gIFRoZSBpbmxpbmUgZnVuY3Rpb24gc2hvdWxkIGJlIGVxdWl2YWxlbnQgZm9yIEMrKyB1c2Vycy4KK2lubGluZSBCT09MIEdldE1lc3NhZ2VfV2luMzIoCisgICAgTFBNU0cgbHBNc2csIEhXTkQgaFduZCwKKyAgICBVSU5UIHdNc2dGaWx0ZXJNaW4sIFVJTlQgd01zZ0ZpbHRlck1heCkgeworICByZXR1cm4gR2V0TWVzc2FnZShscE1zZywgaFduZCwgd01zZ0ZpbHRlck1pbiwgd01zZ0ZpbHRlck1heCk7Cit9CisjdW5kZWYgR2V0TWVzc2FnZQoraW5saW5lIEJPT0wgR2V0TWVzc2FnZSgKKyAgICBMUE1TRyBscE1zZywgSFdORCBoV25kLAorICAgIFVJTlQgd01zZ0ZpbHRlck1pbiwgVUlOVCB3TXNnRmlsdGVyTWF4KSB7CisgIHJldHVybiBHZXRNZXNzYWdlX1dpbjMyKGxwTXNnLCBoV25kLCB3TXNnRmlsdGVyTWluLCB3TXNnRmlsdGVyTWF4KTsKK30KKyNlbmRpZgorCisKK25hbWVzcGFjZSBzdGQge30KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisjdW5kZWYgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTCisjZGVmaW5lIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUeXBlTmFtZSkgICAgXAorICBUeXBlTmFtZShjb25zdCBUeXBlTmFtZSYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdm9pZCBvcGVyYXRvcj0oY29uc3QgVHlwZU5hbWUmKQorCisjaWYgZGVmaW5lZChfTVNDX1ZFUikgJiYgZGVmaW5lZChQUk9UT0JVRl9VU0VfRExMUykKKyAgI2lmZGVmIExJQlBST1RPQlVGX0VYUE9SVFMKKyAgICAjZGVmaW5lIExJQlBST1RPQlVGX0VYUE9SVCBfX2RlY2xzcGVjKGRsbGV4cG9ydCkKKyAgI2Vsc2UKKyAgICAjZGVmaW5lIExJQlBST1RPQlVGX0VYUE9SVCBfX2RlY2xzcGVjKGRsbGltcG9ydCkKKyAgI2VuZGlmCisgICNpZmRlZiBMSUJQUk9UT0NfRVhQT1JUUworICAgICNkZWZpbmUgTElCUFJPVE9DX0VYUE9SVCAgIF9fZGVjbHNwZWMoZGxsZXhwb3J0KQorICAjZWxzZQorICAgICNkZWZpbmUgTElCUFJPVE9DX0VYUE9SVCAgIF9fZGVjbHNwZWMoZGxsaW1wb3J0KQorICAjZW5kaWYKKyNlbHNlCisgICNkZWZpbmUgTElCUFJPVE9CVUZfRVhQT1JUCisgICNkZWZpbmUgTElCUFJPVE9DX0VYUE9SVAorI2VuZGlmCisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFNvbWUgb2YgdGhlc2UgY29uc3RhbnRzIGFyZSBtYWNyb3MgcmF0aGVyIHRoYW4gY29uc3QgaW50cyBzbyB0aGF0IHRoZXkgY2FuCisvLyBiZSB1c2VkIGluICNpZiBkaXJlY3RpdmVzLgorCisvLyBUaGUgY3VycmVudCB2ZXJzaW9uLCByZXByZXNlbnRlZCBhcyBhIHNpbmdsZSBpbnRlZ2VyIHRvIG1ha2UgY29tcGFyaXNvbgorLy8gZWFzaWVyOiAgbWFqb3IgKiAxMF42ICsgbWlub3IgKiAxMF4zICsgbWljcm8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1ZFUlNJT04gMzAwMDAwMAorCisvLyBUaGUgbWluaW11bSBsaWJyYXJ5IHZlcnNpb24gd2hpY2ggd29ya3Mgd2l0aCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZQorLy8gaGVhZGVycy4KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01JTl9MSUJSQVJZX1ZFUlNJT04gMzAwMDAwMAorCisvLyBUaGUgbWluaW11bSBoZWFkZXIgdmVyc2lvbiB3aGljaCB3b3JrcyB3aXRoIHRoZSBjdXJyZW50IHZlcnNpb24gb2YKKy8vIHRoZSBsaWJyYXJ5LiAgVGhpcyBjb25zdGFudCBzaG91bGQgb25seSBiZSB1c2VkIGJ5IHByb3RvYydzIEMrKyBjb2RlCisvLyBnZW5lcmF0b3IuCitzdGF0aWMgY29uc3QgaW50IGtNaW5IZWFkZXJWZXJzaW9uRm9yTGlicmFyeSA9IDMwMDAwMDA7CisKKy8vIFRoZSBtaW5pbXVtIHByb3RvYyB2ZXJzaW9uIHdoaWNoIHdvcmtzIHdpdGggdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUKKy8vIGhlYWRlcnMuCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NSU5fUFJPVE9DX1ZFUlNJT04gMzAwMDAwMAorCisvLyBUaGUgbWluaW11bSBoZWFkZXIgdmVyc2lvbiB3aGljaCB3b3JrcyB3aXRoIHRoZSBjdXJyZW50IHZlcnNpb24gb2YKKy8vIHByb3RvYy4gIFRoaXMgY29uc3RhbnQgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBWZXJpZnlWZXJzaW9uKCkuCitzdGF0aWMgY29uc3QgaW50IGtNaW5IZWFkZXJWZXJzaW9uRm9yUHJvdG9jID0gMzAwMDAwMDsKKworLy8gVmVyaWZpZXMgdGhhdCB0aGUgaGVhZGVycyBhbmQgbGlicmFyaWVzIGFyZSBjb21wYXRpYmxlLiAgVXNlIHRoZSBtYWNybworLy8gYmVsb3cgdG8gY2FsbCB0aGlzLgordm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgVmVyaWZ5VmVyc2lvbihpbnQgaGVhZGVyVmVyc2lvbiwgaW50IG1pbkxpYnJhcnlWZXJzaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBmaWxlbmFtZSk7CisKKy8vIENvbnZlcnRzIGEgbnVtZXJpYyB2ZXJzaW9uIG51bWJlciB0byBhIHN0cmluZy4KK3N0ZDo6c3RyaW5nIExJQlBST1RPQlVGX0VYUE9SVCBWZXJzaW9uU3RyaW5nKGludCB2ZXJzaW9uKTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKy8vIFBsYWNlIHRoaXMgbWFjcm8gaW4geW91ciBtYWluKCkgZnVuY3Rpb24gKG9yIHNvbWV3aGVyZSBiZWZvcmUgeW91IGF0dGVtcHQKKy8vIHRvIHVzZSB0aGUgcHJvdG9idWYgbGlicmFyeSkgdG8gdmVyaWZ5IHRoYXQgdGhlIHZlcnNpb24geW91IGxpbmsgYWdhaW5zdAorLy8gbWF0Y2hlcyB0aGUgaGVhZGVycyB5b3UgY29tcGlsZWQgYWdhaW5zdC4gIElmIGEgdmVyc2lvbiBtaXNtYXRjaCBpcworLy8gZGV0ZWN0ZWQsIHRoZSBwcm9jZXNzIHdpbGwgYWJvcnQuCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6VmVyaWZ5VmVyc2lvbiggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OLCBHT09HTEVfUFJPVE9CVUZfTUlOX0xJQlJBUllfVkVSU0lPTiwgICAgICAgICBcCisgICAgX19GSUxFX18pCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGZyb20gZ29vZ2xlMy9iYXNlL3BvcnQuaAorCit0eXBlZGVmIHVuc2lnbmVkIGludCB1aW50OworCisjaWZkZWYgX01TQ19WRVIKK3R5cGVkZWYgX19pbnQ4ICBpbnQ4OwordHlwZWRlZiBfX2ludDE2IGludDE2OwordHlwZWRlZiBfX2ludDMyIGludDMyOwordHlwZWRlZiBfX2ludDY0IGludDY0OworCit0eXBlZGVmIHVuc2lnbmVkIF9faW50OCAgdWludDg7Cit0eXBlZGVmIHVuc2lnbmVkIF9faW50MTYgdWludDE2OwordHlwZWRlZiB1bnNpZ25lZCBfX2ludDMyIHVpbnQzMjsKK3R5cGVkZWYgdW5zaWduZWQgX19pbnQ2NCB1aW50NjQ7CisjZWxzZQordHlwZWRlZiBpbnQ4X3QgIGludDg7Cit0eXBlZGVmIGludDE2X3QgaW50MTY7Cit0eXBlZGVmIGludDMyX3QgaW50MzI7Cit0eXBlZGVmIGludDY0X3QgaW50NjQ7CisKK3R5cGVkZWYgdWludDhfdCAgdWludDg7Cit0eXBlZGVmIHVpbnQxNl90IHVpbnQxNjsKK3R5cGVkZWYgdWludDMyX3QgdWludDMyOwordHlwZWRlZiB1aW50NjRfdCB1aW50NjQ7CisjZW5kaWYKKworLy8gbG9uZyBsb25nIG1hY3JvcyB0byBiZSB1c2VkIGJlY2F1c2UgZ2NjIGFuZCB2YysrIHVzZSBkaWZmZXJlbnQgc3VmZml4ZXMsCisvLyBhbmQgZGlmZmVyZW50IHNpemUgc3BlY2lmaWVycyBpbiBmb3JtYXQgc3RyaW5ncworI3VuZGVmIEdPT0dMRV9MT05HTE9ORworI3VuZGVmIEdPT0dMRV9VTE9OR0xPTkcKKyN1bmRlZiBHT09HTEVfTExfRk9STUFUCisKKyNpZmRlZiBfTVNDX1ZFUgorI2RlZmluZSBHT09HTEVfTE9OR0xPTkcoeCkgeCMjSTY0CisjZGVmaW5lIEdPT0dMRV9VTE9OR0xPTkcoeCkgeCMjVUk2NAorI2RlZmluZSBHT09HTEVfTExfRk9STUFUICJJNjQiICAvLyBBcyBpbiBwcmludGYoIiVJNjRkIiwgLi4uKQorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX0xPTkdMT05HKHgpIHgjI0xMCisjZGVmaW5lIEdPT0dMRV9VTE9OR0xPTkcoeCkgeCMjVUxMCisjZGVmaW5lIEdPT0dMRV9MTF9GT1JNQVQgImxsIiAgLy8gQXMgaW4gIiVsbGQiLiBOb3RlIHRoYXQgInEiIGlzIHBvb3IgZm9ybSBhbHNvLgorI2VuZGlmCisKK3N0YXRpYyBjb25zdCBpbnQzMiBraW50MzJtYXggPSAweDdGRkZGRkZGOworc3RhdGljIGNvbnN0IGludDMyIGtpbnQzMm1pbiA9IC1raW50MzJtYXggLSAxOworc3RhdGljIGNvbnN0IGludDY0IGtpbnQ2NG1heCA9IEdPT0dMRV9MT05HTE9ORygweDdGRkZGRkZGRkZGRkZGRkYpOworc3RhdGljIGNvbnN0IGludDY0IGtpbnQ2NG1pbiA9IC1raW50NjRtYXggLSAxOworc3RhdGljIGNvbnN0IHVpbnQzMiBrdWludDMybWF4ID0gMHhGRkZGRkZGRnU7CitzdGF0aWMgY29uc3QgdWludDY0IGt1aW50NjRtYXggPSBHT09HTEVfVUxPTkdMT05HKDB4RkZGRkZGRkZGRkZGRkZGRik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEFubm90YXRpb25zOiAgU29tZSBwYXJ0cyBvZiB0aGUgY29kZSBoYXZlIGJlZW4gYW5ub3RhdGVkIGluIHdheXMgdGhhdCBtaWdodAorLy8gICBiZSB1c2VmdWwgdG8gc29tZSBjb21waWxlcnMgb3IgdG9vbHMsIGJ1dCBhcmUgbm90IHN1cHBvcnRlZCB1bml2ZXJzYWxseS4KKy8vICAgWW91IGNhbiAjZGVmaW5lIHRoZXNlIGFubm90YXRpb25zIHlvdXJzZWxmIGlmIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisvLyAgIGlzIG5vdCByaWdodCBmb3IgeW91LgorCisjaWZuZGVmIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorI2lmIGRlZmluZWQoX19HTlVDX18pICYmIChfX0dOVUNfXyA+IDMgfHwoX19HTlVDX18gPT0gMyAmJiBfX0dOVUNfTUlOT1JfXyA+PSAxKSkKKy8vIEZvciBmdW5jdGlvbnMgd2Ugd2FudCB0byBmb3JjZSBpbmxpbmUuCisvLyBJbnRyb2R1Y2VkIGluIGdjYyAzLjEuCisjZGVmaW5lIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBfX2F0dHJpYnV0ZV9fICgoYWx3YXlzX2lubGluZSkpCisjZWxzZQorLy8gT3RoZXIgY29tcGlsZXJzIHdpbGwgaGF2ZSB0byBmaWd1cmUgaXQgb3V0IGZvciB0aGVtc2VsdmVzLgorI2RlZmluZSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyNlbmRpZgorI2VuZGlmCisKKyNpZm5kZWYgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORQorI2lmIGRlZmluZWQoX19HTlVDX18pICYmIChfX0dOVUNfXyA+IDMgfHwoX19HTlVDX18gPT0gMyAmJiBfX0dOVUNfTUlOT1JfXyA+PSAxKSkKKy8vIEZvciBmdW5jdGlvbnMgd2Ugd2FudCB0byBmb3JjZSBub3QgaW5saW5lLgorLy8gSW50cm9kdWNlZCBpbiBnY2MgMy4xLgorI2RlZmluZSBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FIF9fYXR0cmlidXRlX18gKChub2lubGluZSkpCisjZWxzZQorLy8gT3RoZXIgY29tcGlsZXJzIHdpbGwgaGF2ZSB0byBmaWd1cmUgaXQgb3V0IGZvciB0aGVtc2VsdmVzLgorI2RlZmluZSBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FCisjZW5kaWYKKyNlbmRpZgorCisjaWZuZGVmIEdPT0dMRV9BVFRSSUJVVEVfREVQUkVDQVRFRAorI2lmZGVmIF9fR05VQ19fCisvLyBJZiB0aGUgbWV0aG9kL3ZhcmlhYmxlL3R5cGUgaXMgdXNlZCBhbnl3aGVyZSwgcHJvZHVjZSBhIHdhcm5pbmcuCisjZGVmaW5lIEdPT0dMRV9BVFRSSUJVVEVfREVQUkVDQVRFRCBfX2F0dHJpYnV0ZV9fKChkZXByZWNhdGVkKSkKKyNlbHNlCisjZGVmaW5lIEdPT0dMRV9BVFRSSUJVVEVfREVQUkVDQVRFRAorI2VuZGlmCisjZW5kaWYKKworI2lmbmRlZiBHT09HTEVfUFJFRElDVF9UUlVFCisjaWZkZWYgX19HTlVDX18KKy8vIFByb3ZpZGVkIGF0IGxlYXN0IHNpbmNlIEdDQyAzLjAuCisjZGVmaW5lIEdPT0dMRV9QUkVESUNUX1RSVUUoeCkgKF9fYnVpbHRpbl9leHBlY3QoISEoeCksIDEpKQorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX1BSRURJQ1RfVFJVRQorI2VuZGlmCisjZW5kaWYKKworI2lmbmRlZiBHT09HTEVfUFJFRElDVF9GQUxTRQorI2lmZGVmIF9fR05VQ19fCisvLyBQcm92aWRlZCBhdCBsZWFzdCBzaW5jZSBHQ0MgMy4wLgorI2RlZmluZSBHT09HTEVfUFJFRElDVF9GQUxTRSh4KSAoX19idWlsdGluX2V4cGVjdCghISh4KSwgMSkpCisjZWxzZQorI2RlZmluZSBHT09HTEVfUFJFRElDVF9GQUxTRQorI2VuZGlmCisjZW5kaWYKKworLy8gRGVsaW1pdHMgYSBibG9jayBvZiBjb2RlIHdoaWNoIG1heSB3cml0ZSB0byBtZW1vcnkgd2hpY2ggaXMgc2ltdWx0YW5lb3VzbHkKKy8vIHdyaXR0ZW4gYnkgb3RoZXIgdGhyZWFkcywgYnV0IHdoaWNoIGhhcyBiZWVuIGRldGVybWluZWQgdG8gYmUgdGhyZWFkLXNhZmUKKy8vIChlLmcuIGJlY2F1c2UgaXQgaXMgYW4gaWRlbXBvdGVudCB3cml0ZSkuCisjaWZuZGVmIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOCisjZGVmaW5lIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCkKKyNlbmRpZgorI2lmbmRlZiBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQKKyNkZWZpbmUgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCkKKyNlbmRpZgorCisjZGVmaW5lIEdPT0dMRV9HVUFSREVEX0JZKHgpCisjZGVmaW5lIEdPT0dMRV9GQUxMVEhST1VHSF9JTlRFTkRFRAorI2RlZmluZSBHT09HTEVfQVRUUklCVVRFX0NPTEQKKworLy8geDg2IGFuZCB4ODYtNjQgY2FuIHBlcmZvcm0gdW5hbGlnbmVkIGxvYWRzL3N0b3JlcyBkaXJlY3RseS4KKyNpZiBkZWZpbmVkKF9NX1g2NCkgfHwgZGVmaW5lZChfX3g4Nl82NF9fKSB8fCBcCisgICAgZGVmaW5lZChfTV9JWDg2KSB8fCBkZWZpbmVkKF9faTM4Nl9fKQorCisjZGVmaW5lIEdPT0dMRV9VTkFMSUdORURfTE9BRDE2KF9wKSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDE2ICo+KF9wKSkKKyNkZWZpbmUgR09PR0xFX1VOQUxJR05FRF9MT0FEMzIoX3ApICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50MzIgKj4oX3ApKQorI2RlZmluZSBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChfcCkgKCpyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ2NCAqPihfcCkpCisKKyNkZWZpbmUgR09PR0xFX1VOQUxJR05FRF9TVE9SRTE2KF9wLCBfdmFsKSAoKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDE2ICo+KF9wKSA9IChfdmFsKSkKKyNkZWZpbmUgR09PR0xFX1VOQUxJR05FRF9TVE9SRTMyKF9wLCBfdmFsKSAoKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDMyICo+KF9wKSA9IChfdmFsKSkKKyNkZWZpbmUgR09PR0xFX1VOQUxJR05FRF9TVE9SRTY0KF9wLCBfdmFsKSAoKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDY0ICo+KF9wKSA9IChfdmFsKSkKKworI2Vsc2UKK2lubGluZSB1aW50MTYgR09PR0xFX1VOQUxJR05FRF9MT0FEMTYoY29uc3Qgdm9pZCAqcCkgeworICB1aW50MTYgdDsKKyAgbWVtY3B5KCZ0LCBwLCBzaXplb2YgdCk7CisgIHJldHVybiB0OworfQorCitpbmxpbmUgdWludDMyIEdPT0dMRV9VTkFMSUdORURfTE9BRDMyKGNvbnN0IHZvaWQgKnApIHsKKyAgdWludDMyIHQ7CisgIG1lbWNweSgmdCwgcCwgc2l6ZW9mIHQpOworICByZXR1cm4gdDsKK30KKworaW5saW5lIHVpbnQ2NCBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChjb25zdCB2b2lkICpwKSB7CisgIHVpbnQ2NCB0OworICBtZW1jcHkoJnQsIHAsIHNpemVvZiB0KTsKKyAgcmV0dXJuIHQ7Cit9CisKK2lubGluZSB2b2lkIEdPT0dMRV9VTkFMSUdORURfU1RPUkUxNih2b2lkICpwLCB1aW50MTYgdikgeworICBtZW1jcHkocCwgJnYsIHNpemVvZiB2KTsKK30KKworaW5saW5lIHZvaWQgR09PR0xFX1VOQUxJR05FRF9TVE9SRTMyKHZvaWQgKnAsIHVpbnQzMiB2KSB7CisgIG1lbWNweShwLCAmdiwgc2l6ZW9mIHYpOworfQorCitpbmxpbmUgdm9pZCBHT09HTEVfVU5BTElHTkVEX1NUT1JFNjQodm9pZCAqcCwgdWludDY0IHYpIHsKKyAgbWVtY3B5KHAsICZ2LCBzaXplb2Ygdik7Cit9CisjZW5kaWYKKworI2lmIGRlZmluZWQoX01TQ19WRVIpCisjZGVmaW5lIEdPT0dMRV9USFJFQURfTE9DQUwgX19kZWNsc3BlYyh0aHJlYWQpCisjZWxzZQorI2RlZmluZSBHT09HTEVfVEhSRUFEX0xPQ0FMIF9fdGhyZWFkCisjZW5kaWYKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZnJvbSBnb29nbGUzL2Jhc2UvYmFzaWN0eXBlcy5oCisKKy8vIFRoZSBHT09HTEVfQVJSQVlTSVpFKGFycikgbWFjcm8gcmV0dXJucyB0aGUgIyBvZiBlbGVtZW50cyBpbiBhbiBhcnJheSBhcnIuCisvLyBUaGUgZXhwcmVzc2lvbiBpcyBhIGNvbXBpbGUtdGltZSBjb25zdGFudCwgYW5kIHRoZXJlZm9yZSBjYW4gYmUKKy8vIHVzZWQgaW4gZGVmaW5pbmcgbmV3IGFycmF5cywgZm9yIGV4YW1wbGUuCisvLworLy8gR09PR0xFX0FSUkFZU0laRSBjYXRjaGVzIGEgZmV3IHR5cGUgZXJyb3JzLiAgSWYgeW91IHNlZSBhIGNvbXBpbGVyIGVycm9yCisvLworLy8gICAid2FybmluZzogZGl2aXNpb24gYnkgemVybyBpbiAuLi4iCisvLworLy8gd2hlbiB1c2luZyBHT09HTEVfQVJSQVlTSVpFLCB5b3UgYXJlICh3cm9uZ2Z1bGx5KSBnaXZpbmcgaXQgYSBwb2ludGVyLgorLy8gWW91IHNob3VsZCBvbmx5IHVzZSBHT09HTEVfQVJSQVlTSVpFIG9uIHN0YXRpY2FsbHkgYWxsb2NhdGVkIGFycmF5cy4KKy8vCisvLyBUaGUgZm9sbG93aW5nIGNvbW1lbnRzIGFyZSBvbiB0aGUgaW1wbGVtZW50YXRpb24gZGV0YWlscywgYW5kIGNhbgorLy8gYmUgaWdub3JlZCBieSB0aGUgdXNlcnMuCisvLworLy8gQVJSQVlTSVpFKGFycikgd29ya3MgYnkgaW5zcGVjdGluZyBzaXplb2YoYXJyKSAodGhlICMgb2YgYnl0ZXMgaW4KKy8vIHRoZSBhcnJheSkgYW5kIHNpemVvZigqKGFycikpICh0aGUgIyBvZiBieXRlcyBpbiBvbmUgYXJyYXkKKy8vIGVsZW1lbnQpLiAgSWYgdGhlIGZvcm1lciBpcyBkaXZpc2libGUgYnkgdGhlIGxhdHRlciwgcGVyaGFwcyBhcnIgaXMKKy8vIGluZGVlZCBhbiBhcnJheSwgaW4gd2hpY2ggY2FzZSB0aGUgZGl2aXNpb24gcmVzdWx0IGlzIHRoZSAjIG9mCisvLyBlbGVtZW50cyBpbiB0aGUgYXJyYXkuICBPdGhlcndpc2UsIGFyciBjYW5ub3QgcG9zc2libHkgYmUgYW4gYXJyYXksCisvLyBhbmQgd2UgZ2VuZXJhdGUgYSBjb21waWxlciBlcnJvciB0byBwcmV2ZW50IHRoZSBjb2RlIGZyb20KKy8vIGNvbXBpbGluZy4KKy8vCisvLyBTaW5jZSB0aGUgc2l6ZSBvZiBib29sIGlzIGltcGxlbWVudGF0aW9uLWRlZmluZWQsIHdlIG5lZWQgdG8gY2FzdAorLy8gIShzaXplb2YoYSkgJiBzaXplb2YoKihhKSkpIHRvIHNpemVfdCBpbiBvcmRlciB0byBlbnN1cmUgdGhlIGZpbmFsCisvLyByZXN1bHQgaGFzIHR5cGUgc2l6ZV90LgorLy8KKy8vIFRoaXMgbWFjcm8gaXMgbm90IHBlcmZlY3QgYXMgaXQgd3JvbmdmdWxseSBhY2NlcHRzIGNlcnRhaW4KKy8vIHBvaW50ZXJzLCBuYW1lbHkgd2hlcmUgdGhlIHBvaW50ZXIgc2l6ZSBpcyBkaXZpc2libGUgYnkgdGhlIHBvaW50ZWUKKy8vIHNpemUuICBTaW5jZSBhbGwgb3VyIGNvZGUgaGFzIHRvIGdvIHRocm91Z2ggYSAzMi1iaXQgY29tcGlsZXIsCisvLyB3aGVyZSBhIHBvaW50ZXIgaXMgNCBieXRlcywgdGhpcyBtZWFucyBhbGwgcG9pbnRlcnMgdG8gYSB0eXBlIHdob3NlCisvLyBzaXplIGlzIDMgb3IgZ3JlYXRlciB0aGFuIDQgd2lsbCBiZSAocmlnaHRlb3VzbHkpIHJlamVjdGVkLgorLy8KKy8vIEt1ZG9zIHRvIEpvcmcgQnJvd24gZm9yIHRoaXMgc2ltcGxlIGFuZCBlbGVnYW50IGltcGxlbWVudGF0aW9uLgorCisjdW5kZWYgR09PR0xFX0FSUkFZU0laRQorI2RlZmluZSBHT09HTEVfQVJSQVlTSVpFKGEpIFwKKyAgKChzaXplb2YoYSkgLyBzaXplb2YoKihhKSkpIC8gXAorICAgc3RhdGljX2Nhc3Q8c2l6ZV90PighKHNpemVvZihhKSAlIHNpemVvZigqKGEpKSkpKQorCisvLyBUaGUgQ09NUElMRV9BU1NFUlQgbWFjcm8gY2FuIGJlIHVzZWQgdG8gdmVyaWZ5IHRoYXQgYSBjb21waWxlIHRpbWUKKy8vIGV4cHJlc3Npb24gaXMgdHJ1ZS4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCB1c2UgaXQgdG8gdmVyaWZ5IHRoZQorLy8gc2l6ZSBvZiBhIHN0YXRpYyBhcnJheToKKy8vCisvLyAgIENPTVBJTEVfQVNTRVJUKEFSUkFZU0laRShjb250ZW50X3R5cGVfbmFtZXMpID09IENPTlRFTlRfTlVNX1RZUEVTLAorLy8gICAgICAgICAgICAgICAgICBjb250ZW50X3R5cGVfbmFtZXNfaW5jb3JyZWN0X3NpemUpOworLy8KKy8vIG9yIHRvIG1ha2Ugc3VyZSBhIHN0cnVjdCBpcyBzbWFsbGVyIHRoYW4gYSBjZXJ0YWluIHNpemU6CisvLworLy8gICBDT01QSUxFX0FTU0VSVChzaXplb2YoZm9vKSA8IDEyOCwgZm9vX3Rvb19sYXJnZSk7CisvLworLy8gVGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgbWFjcm8gaXMgdGhlIG5hbWUgb2YgdGhlIHZhcmlhYmxlLiBJZgorLy8gdGhlIGV4cHJlc3Npb24gaXMgZmFsc2UsIG1vc3QgY29tcGlsZXJzIHdpbGwgaXNzdWUgYSB3YXJuaW5nL2Vycm9yCisvLyBjb250YWluaW5nIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZS4KKworbmFtZXNwYWNlIGludGVybmFsIHsKKwordGVtcGxhdGUgPGJvb2w+CitzdHJ1Y3QgQ29tcGlsZUFzc2VydCB7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworI3VuZGVmIEdPT0dMRV9DT01QSUxFX0FTU0VSVAorI2RlZmluZSBHT09HTEVfQ09NUElMRV9BU1NFUlQoZXhwciwgbXNnKSBcCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkNvbXBpbGVBc3NlcnQ8KGJvb2woZXhwcikpPiBcCisgICAgICAgICAgbXNnW2Jvb2woZXhwcikgPyAxIDogLTFdOyBcCisgICh2b2lkKW1zZworCisKKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgQ09NUElMRV9BU1NFUlQ6CisvLworLy8gLSBDT01QSUxFX0FTU0VSVCB3b3JrcyBieSBkZWZpbmluZyBhbiBhcnJheSB0eXBlIHRoYXQgaGFzIC0xCisvLyAgIGVsZW1lbnRzIChhbmQgdGh1cyBpcyBpbnZhbGlkKSB3aGVuIHRoZSBleHByZXNzaW9uIGlzIGZhbHNlLgorLy8KKy8vIC0gVGhlIHNpbXBsZXIgZGVmaW5pdGlvbgorLy8KKy8vICAgICAjZGVmaW5lIENPTVBJTEVfQVNTRVJUKGV4cHIsIG1zZykgdHlwZWRlZiBjaGFyIG1zZ1soZXhwcikgPyAxIDogLTFdCisvLworLy8gICBkb2VzIG5vdCB3b3JrLCBhcyBnY2Mgc3VwcG9ydHMgdmFyaWFibGUtbGVuZ3RoIGFycmF5cyB3aG9zZSBzaXplcworLy8gICBhcmUgZGV0ZXJtaW5lZCBhdCBydW4tdGltZSAodGhpcyBpcyBnY2MncyBleHRlbnNpb24gYW5kIG5vdCBwYXJ0CisvLyAgIG9mIHRoZSBDKysgc3RhbmRhcmQpLiAgQXMgYSByZXN1bHQsIGdjYyBmYWlscyB0byByZWplY3QgdGhlCisvLyAgIGZvbGxvd2luZyBjb2RlIHdpdGggdGhlIHNpbXBsZSBkZWZpbml0aW9uOgorLy8KKy8vICAgICBpbnQgZm9vOworLy8gICAgIENPTVBJTEVfQVNTRVJUKGZvbywgbXNnKTsgLy8gbm90IHN1cHBvc2VkIHRvIGNvbXBpbGUgYXMgZm9vIGlzCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3QgYSBjb21waWxlLXRpbWUgY29uc3RhbnQuCisvLworLy8gLSBCeSB1c2luZyB0aGUgdHlwZSBDb21waWxlQXNzZXJ0PChib29sKGV4cHIpKT4sIHdlIGVuc3VyZXMgdGhhdAorLy8gICBleHByIGlzIGEgY29tcGlsZS10aW1lIGNvbnN0YW50LiAgKFRlbXBsYXRlIGFyZ3VtZW50cyBtdXN0IGJlCisvLyAgIGRldGVybWluZWQgYXQgY29tcGlsZS10aW1lLikKKy8vCisvLyAtIFRoZSBvdXR0ZXIgcGFyZW50aGVzZXMgaW4gQ29tcGlsZUFzc2VydDwoYm9vbChleHByKSk+IGFyZSBuZWNlc3NhcnkKKy8vICAgdG8gd29yayBhcm91bmQgYSBidWcgaW4gZ2NjIDMuNC40IGFuZCA0LjAuMS4gIElmIHdlIGhhZCB3cml0dGVuCisvLworLy8gICAgIENvbXBpbGVBc3NlcnQ8Ym9vbChleHByKT4KKy8vCisvLyAgIGluc3RlYWQsIHRoZXNlIGNvbXBpbGVycyB3aWxsIHJlZnVzZSB0byBjb21waWxlCisvLworLy8gICAgIENPTVBJTEVfQVNTRVJUKDUgPiAwLCBzb21lX21lc3NhZ2UpOworLy8KKy8vICAgKFRoZXkgc2VlbSB0byB0aGluayB0aGUgIj4iIGluICI1ID4gMCIgbWFya3MgdGhlIGVuZCBvZiB0aGUKKy8vICAgdGVtcGxhdGUgYXJndW1lbnQgbGlzdC4pCisvLworLy8gLSBUaGUgYXJyYXkgc2l6ZSBpcyAoYm9vbChleHByKSA/IDEgOiAtMSksIGluc3RlYWQgb2Ygc2ltcGx5CisvLworLy8gICAgICgoZXhwcikgPyAxIDogLTEpLgorLy8KKy8vICAgVGhpcyBpcyB0byBhdm9pZCBydW5uaW5nIGludG8gYSBidWcgaW4gTVMgVkMgNy4xLCB3aGljaAorLy8gICBjYXVzZXMgKCgwLjApID8gMSA6IC0xKSB0byBpbmNvcnJlY3RseSBldmFsdWF0ZSB0byAxLgorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBmcm9tIGdvb2dsZTMvYmFzZS9zY29wZWRfcHRyLmgKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gZGVzaWduZWQgdG8gbWF0Y2ggdGhlIGFudGljaXBhdGVkIGZ1dHVyZSBUUjIKKy8vICBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2NvcGVkX3B0ciBjbGFzcywgYW5kIGl0cyBjbG9zZWx5LXJlbGF0ZWQgYnJldGhyZW4sCisvLyAgc2NvcGVkX2FycmF5LCBzY29wZWRfcHRyX21hbGxvYywgYW5kIG1ha2Vfc2NvcGVkX3B0ci4KKwordGVtcGxhdGUgPGNsYXNzIEM+IGNsYXNzIHNjb3BlZF9wdHI7Cit0ZW1wbGF0ZSA8Y2xhc3MgQz4gY2xhc3Mgc2NvcGVkX2FycmF5OworCisvLyBBIHNjb3BlZF9wdHI8VD4gaXMgbGlrZSBhIFQqLCBleGNlcHQgdGhhdCB0aGUgZGVzdHJ1Y3RvciBvZiBzY29wZWRfcHRyPFQ+CisvLyBhdXRvbWF0aWNhbGx5IGRlbGV0ZXMgdGhlIHBvaW50ZXIgaXQgaG9sZHMgKGlmIGFueSkuCisvLyBUaGF0IGlzLCBzY29wZWRfcHRyPFQ+IG93bnMgdGhlIFQgb2JqZWN0IHRoYXQgaXQgcG9pbnRzIHRvLgorLy8gTGlrZSBhIFQqLCBhIHNjb3BlZF9wdHI8VD4gbWF5IGhvbGQgZWl0aGVyIE5VTEwgb3IgYSBwb2ludGVyIHRvIGEgVCBvYmplY3QuCisvLworLy8gVGhlIHNpemUgb2YgYSBzY29wZWRfcHRyIGlzIHNtYWxsOgorLy8gc2l6ZW9mKHNjb3BlZF9wdHI8Qz4pID09IHNpemVvZihDKikKK3RlbXBsYXRlIDxjbGFzcyBDPgorY2xhc3Mgc2NvcGVkX3B0ciB7CisgcHVibGljOgorCisgIC8vIFRoZSBlbGVtZW50IHR5cGUKKyAgdHlwZWRlZiBDIGVsZW1lbnRfdHlwZTsKKworICAvLyBDb25zdHJ1Y3Rvci4gIERlZmF1bHRzIHRvIGluaXRpYWxpemluZyB3aXRoIE5VTEwuCisgIC8vIFRoZXJlIGlzIG5vIHdheSB0byBjcmVhdGUgYW4gdW5pbml0aWFsaXplZCBzY29wZWRfcHRyLgorICAvLyBUaGUgaW5wdXQgcGFyYW1ldGVyIG11c3QgYmUgYWxsb2NhdGVkIHdpdGggbmV3LgorICBleHBsaWNpdCBzY29wZWRfcHRyKEMqIHAgPSBOVUxMKSA6IHB0cl8ocCkgeyB9CisKKyAgLy8gRGVzdHJ1Y3Rvci4gIElmIHRoZXJlIGlzIGEgQyBvYmplY3QsIGRlbGV0ZSBpdC4KKyAgLy8gV2UgZG9uJ3QgbmVlZCB0byB0ZXN0IHB0cl8gPT0gTlVMTCBiZWNhdXNlIEMrKyBkb2VzIHRoYXQgZm9yIHVzLgorICB+c2NvcGVkX3B0cigpIHsKKyAgICBlbnVtIHsgdHlwZV9tdXN0X2JlX2NvbXBsZXRlID0gc2l6ZW9mKEMpIH07CisgICAgZGVsZXRlIHB0cl87CisgIH0KKworICAvLyBSZXNldC4gIERlbGV0ZXMgdGhlIGN1cnJlbnQgb3duZWQgb2JqZWN0LCBpZiBhbnkuCisgIC8vIFRoZW4gdGFrZXMgb3duZXJzaGlwIG9mIGEgbmV3IG9iamVjdCwgaWYgZ2l2ZW4uCisgIC8vIHRoaXMtPnJlc2V0KHRoaXMtPmdldCgpKSB3b3Jrcy4KKyAgdm9pZCByZXNldChDKiBwID0gTlVMTCkgeworICAgIGlmIChwICE9IHB0cl8pIHsKKyAgICAgIGVudW0geyB0eXBlX211c3RfYmVfY29tcGxldGUgPSBzaXplb2YoQykgfTsKKyAgICAgIGRlbGV0ZSBwdHJfOworICAgICAgcHRyXyA9IHA7CisgICAgfQorICB9CisKKyAgLy8gQWNjZXNzb3JzIHRvIGdldCB0aGUgb3duZWQgb2JqZWN0LgorICAvLyBvcGVyYXRvciogYW5kIG9wZXJhdG9yLT4gd2lsbCBhc3NlcnQoKSBpZiB0aGVyZSBpcyBubyBjdXJyZW50IG9iamVjdC4KKyAgQyYgb3BlcmF0b3IqKCkgY29uc3QgeworICAgIGFzc2VydChwdHJfICE9IE5VTEwpOworICAgIHJldHVybiAqcHRyXzsKKyAgfQorICBDKiBvcGVyYXRvci0+KCkgY29uc3QgIHsKKyAgICBhc3NlcnQocHRyXyAhPSBOVUxMKTsKKyAgICByZXR1cm4gcHRyXzsKKyAgfQorICBDKiBnZXQoKSBjb25zdCB7IHJldHVybiBwdHJfOyB9CisKKyAgLy8gQ29tcGFyaXNvbiBvcGVyYXRvcnMuCisgIC8vIFRoZXNlIHJldHVybiB3aGV0aGVyIHR3byBzY29wZWRfcHRyIHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdCwgbm90IGp1c3QgdG8KKyAgLy8gdHdvIGRpZmZlcmVudCBidXQgZXF1YWwgb2JqZWN0cy4KKyAgYm9vbCBvcGVyYXRvcj09KEMqIHApIGNvbnN0IHsgcmV0dXJuIHB0cl8gPT0gcDsgfQorICBib29sIG9wZXJhdG9yIT0oQyogcCkgY29uc3QgeyByZXR1cm4gcHRyXyAhPSBwOyB9CisKKyAgLy8gU3dhcCB0d28gc2NvcGVkIHBvaW50ZXJzLgorICB2b2lkIHN3YXAoc2NvcGVkX3B0ciYgcDIpIHsKKyAgICBDKiB0bXAgPSBwdHJfOworICAgIHB0cl8gPSBwMi5wdHJfOworICAgIHAyLnB0cl8gPSB0bXA7CisgIH0KKworICAvLyBSZWxlYXNlIGEgcG9pbnRlci4KKyAgLy8gVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgY3VycmVudCBwb2ludGVyIGhlbGQgYnkgdGhpcyBvYmplY3QuCisgIC8vIElmIHRoaXMgb2JqZWN0IGhvbGRzIGEgTlVMTCBwb2ludGVyLCB0aGUgcmV0dXJuIHZhbHVlIGlzIE5VTEwuCisgIC8vIEFmdGVyIHRoaXMgb3BlcmF0aW9uLCB0aGlzIG9iamVjdCB3aWxsIGhvbGQgYSBOVUxMIHBvaW50ZXIsCisgIC8vIGFuZCB3aWxsIG5vdCBvd24gdGhlIG9iamVjdCBhbnkgbW9yZS4KKyAgQyogcmVsZWFzZSgpIHsKKyAgICBDKiByZXRWYWwgPSBwdHJfOworICAgIHB0cl8gPSBOVUxMOworICAgIHJldHVybiByZXRWYWw7CisgIH0KKworIHByaXZhdGU6CisgIEMqIHB0cl87CisKKyAgLy8gRm9yYmlkIGNvbXBhcmlzb24gb2Ygc2NvcGVkX3B0ciB0eXBlcy4gIElmIEMyICE9IEMsIGl0IHRvdGFsbHkgZG9lc24ndAorICAvLyBtYWtlIHNlbnNlLCBhbmQgaWYgQzIgPT0gQywgaXQgc3RpbGwgZG9lc24ndCBtYWtlIHNlbnNlIGJlY2F1c2UgeW91IHNob3VsZAorICAvLyBuZXZlciBoYXZlIHRoZSBzYW1lIG9iamVjdCBvd25lZCBieSB0d28gZGlmZmVyZW50IHNjb3BlZF9wdHJzLgorICB0ZW1wbGF0ZSA8Y2xhc3MgQzI+IGJvb2wgb3BlcmF0b3I9PShzY29wZWRfcHRyPEMyPiBjb25zdCYgcDIpIGNvbnN0OworICB0ZW1wbGF0ZSA8Y2xhc3MgQzI+IGJvb2wgb3BlcmF0b3IhPShzY29wZWRfcHRyPEMyPiBjb25zdCYgcDIpIGNvbnN0OworCisgIC8vIERpc2FsbG93IGV2aWwgY29uc3RydWN0b3JzCisgIHNjb3BlZF9wdHIoY29uc3Qgc2NvcGVkX3B0ciYpOworICB2b2lkIG9wZXJhdG9yPShjb25zdCBzY29wZWRfcHRyJik7Cit9OworCisvLyBzY29wZWRfYXJyYXk8Qz4gaXMgbGlrZSBzY29wZWRfcHRyPEM+LCBleGNlcHQgdGhhdCB0aGUgY2FsbGVyIG11c3QgYWxsb2NhdGUKKy8vIHdpdGggbmV3IFtdIGFuZCB0aGUgZGVzdHJ1Y3RvciBkZWxldGVzIG9iamVjdHMgd2l0aCBkZWxldGUgW10uCisvLworLy8gQXMgd2l0aCBzY29wZWRfcHRyPEM+LCBhIHNjb3BlZF9hcnJheTxDPiBlaXRoZXIgcG9pbnRzIHRvIGFuIG9iamVjdAorLy8gb3IgaXMgTlVMTC4gIEEgc2NvcGVkX2FycmF5PEM+IG93bnMgdGhlIG9iamVjdCB0aGF0IGl0IHBvaW50cyB0by4KKy8vCisvLyBTaXplOiBzaXplb2Yoc2NvcGVkX2FycmF5PEM+KSA9PSBzaXplb2YoQyopCit0ZW1wbGF0ZSA8Y2xhc3MgQz4KK2NsYXNzIHNjb3BlZF9hcnJheSB7CisgcHVibGljOgorCisgIC8vIFRoZSBlbGVtZW50IHR5cGUKKyAgdHlwZWRlZiBDIGVsZW1lbnRfdHlwZTsKKworICAvLyBDb25zdHJ1Y3Rvci4gIERlZmF1bHRzIHRvIGluaXRpYWxpemluZyB3aXRoIE5VTEwuCisgIC8vIFRoZXJlIGlzIG5vIHdheSB0byBjcmVhdGUgYW4gdW5pbml0aWFsaXplZCBzY29wZWRfYXJyYXkuCisgIC8vIFRoZSBpbnB1dCBwYXJhbWV0ZXIgbXVzdCBiZSBhbGxvY2F0ZWQgd2l0aCBuZXcgW10uCisgIGV4cGxpY2l0IHNjb3BlZF9hcnJheShDKiBwID0gTlVMTCkgOiBhcnJheV8ocCkgeyB9CisKKyAgLy8gRGVzdHJ1Y3Rvci4gIElmIHRoZXJlIGlzIGEgQyBvYmplY3QsIGRlbGV0ZSBpdC4KKyAgLy8gV2UgZG9uJ3QgbmVlZCB0byB0ZXN0IHB0cl8gPT0gTlVMTCBiZWNhdXNlIEMrKyBkb2VzIHRoYXQgZm9yIHVzLgorICB+c2NvcGVkX2FycmF5KCkgeworICAgIGVudW0geyB0eXBlX211c3RfYmVfY29tcGxldGUgPSBzaXplb2YoQykgfTsKKyAgICBkZWxldGVbXSBhcnJheV87CisgIH0KKworICAvLyBSZXNldC4gIERlbGV0ZXMgdGhlIGN1cnJlbnQgb3duZWQgb2JqZWN0LCBpZiBhbnkuCisgIC8vIFRoZW4gdGFrZXMgb3duZXJzaGlwIG9mIGEgbmV3IG9iamVjdCwgaWYgZ2l2ZW4uCisgIC8vIHRoaXMtPnJlc2V0KHRoaXMtPmdldCgpKSB3b3Jrcy4KKyAgdm9pZCByZXNldChDKiBwID0gTlVMTCkgeworICAgIGlmIChwICE9IGFycmF5XykgeworICAgICAgZW51bSB7IHR5cGVfbXVzdF9iZV9jb21wbGV0ZSA9IHNpemVvZihDKSB9OworICAgICAgZGVsZXRlW10gYXJyYXlfOworICAgICAgYXJyYXlfID0gcDsKKyAgICB9CisgIH0KKworICAvLyBHZXQgb25lIGVsZW1lbnQgb2YgdGhlIGN1cnJlbnQgb2JqZWN0LgorICAvLyBXaWxsIGFzc2VydCgpIGlmIHRoZXJlIGlzIG5vIGN1cnJlbnQgb2JqZWN0LCBvciBpbmRleCBpIGlzIG5lZ2F0aXZlLgorICBDJiBvcGVyYXRvcltdKHN0ZDo6cHRyZGlmZl90IGkpIGNvbnN0IHsKKyAgICBhc3NlcnQoaSA+PSAwKTsKKyAgICBhc3NlcnQoYXJyYXlfICE9IE5VTEwpOworICAgIHJldHVybiBhcnJheV9baV07CisgIH0KKworICAvLyBHZXQgYSBwb2ludGVyIHRvIHRoZSB6ZXJvdGggZWxlbWVudCBvZiB0aGUgY3VycmVudCBvYmplY3QuCisgIC8vIElmIHRoZXJlIGlzIG5vIGN1cnJlbnQgb2JqZWN0LCByZXR1cm4gTlVMTC4KKyAgQyogZ2V0KCkgY29uc3QgeworICAgIHJldHVybiBhcnJheV87CisgIH0KKworICAvLyBDb21wYXJpc29uIG9wZXJhdG9ycy4KKyAgLy8gVGhlc2UgcmV0dXJuIHdoZXRoZXIgdHdvIHNjb3BlZF9hcnJheSByZWZlciB0byB0aGUgc2FtZSBvYmplY3QsIG5vdCBqdXN0IHRvCisgIC8vIHR3byBkaWZmZXJlbnQgYnV0IGVxdWFsIG9iamVjdHMuCisgIGJvb2wgb3BlcmF0b3I9PShDKiBwKSBjb25zdCB7IHJldHVybiBhcnJheV8gPT0gcDsgfQorICBib29sIG9wZXJhdG9yIT0oQyogcCkgY29uc3QgeyByZXR1cm4gYXJyYXlfICE9IHA7IH0KKworICAvLyBTd2FwIHR3byBzY29wZWQgYXJyYXlzLgorICB2b2lkIHN3YXAoc2NvcGVkX2FycmF5JiBwMikgeworICAgIEMqIHRtcCA9IGFycmF5XzsKKyAgICBhcnJheV8gPSBwMi5hcnJheV87CisgICAgcDIuYXJyYXlfID0gdG1wOworICB9CisKKyAgLy8gUmVsZWFzZSBhbiBhcnJheS4KKyAgLy8gVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgY3VycmVudCBwb2ludGVyIGhlbGQgYnkgdGhpcyBvYmplY3QuCisgIC8vIElmIHRoaXMgb2JqZWN0IGhvbGRzIGEgTlVMTCBwb2ludGVyLCB0aGUgcmV0dXJuIHZhbHVlIGlzIE5VTEwuCisgIC8vIEFmdGVyIHRoaXMgb3BlcmF0aW9uLCB0aGlzIG9iamVjdCB3aWxsIGhvbGQgYSBOVUxMIHBvaW50ZXIsCisgIC8vIGFuZCB3aWxsIG5vdCBvd24gdGhlIG9iamVjdCBhbnkgbW9yZS4KKyAgQyogcmVsZWFzZSgpIHsKKyAgICBDKiByZXRWYWwgPSBhcnJheV87CisgICAgYXJyYXlfID0gTlVMTDsKKyAgICByZXR1cm4gcmV0VmFsOworICB9CisKKyBwcml2YXRlOgorICBDKiBhcnJheV87CisKKyAgLy8gRm9yYmlkIGNvbXBhcmlzb24gb2YgZGlmZmVyZW50IHNjb3BlZF9hcnJheSB0eXBlcy4KKyAgdGVtcGxhdGUgPGNsYXNzIEMyPiBib29sIG9wZXJhdG9yPT0oc2NvcGVkX2FycmF5PEMyPiBjb25zdCYgcDIpIGNvbnN0OworICB0ZW1wbGF0ZSA8Y2xhc3MgQzI+IGJvb2wgb3BlcmF0b3IhPShzY29wZWRfYXJyYXk8QzI+IGNvbnN0JiBwMikgY29uc3Q7CisKKyAgLy8gRGlzYWxsb3cgZXZpbCBjb25zdHJ1Y3RvcnMKKyAgc2NvcGVkX2FycmF5KGNvbnN0IHNjb3BlZF9hcnJheSYpOworICB2b2lkIG9wZXJhdG9yPShjb25zdCBzY29wZWRfYXJyYXkmKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyBXZSBtYWRlIHRoZXNlIGludGVybmFsIHNvIHRoYXQgdGhleSB3b3VsZCBzaG93IHVwIGFzIHN1Y2ggaW4gdGhlIGRvY3MsCisvLyBidXQgd2UgZG9uJ3Qgd2FudCB0byBzdGljayAiaW50ZXJuYWw6OiIgaW4gZnJvbnQgb2YgdGhlbSBldmVyeXdoZXJlLgordXNpbmcgaW50ZXJuYWw6OnNjb3BlZF9wdHI7Cit1c2luZyBpbnRlcm5hbDo6c2NvcGVkX2FycmF5OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvbG9nZ2luZy5oCisKK2VudW0gTG9nTGV2ZWwgeworICBMT0dMRVZFTF9JTkZPLCAgICAgLy8gSW5mb3JtYXRpb25hbC4gIFRoaXMgaXMgbmV2ZXIgYWN0dWFsbHkgdXNlZCBieQorICAgICAgICAgICAgICAgICAgICAgLy8gbGlicHJvdG9idWYuCisgIExPR0xFVkVMX1dBUk5JTkcsICAvLyBXYXJucyBhYm91dCBpc3N1ZXMgdGhhdCwgYWx0aG91Z2ggbm90IHRlY2huaWNhbGx5IGEKKyAgICAgICAgICAgICAgICAgICAgIC8vIHByb2JsZW0gbm93LCBjb3VsZCBjYXVzZSBwcm9ibGVtcyBpbiB0aGUgZnV0dXJlLiAgRm9yCisgICAgICAgICAgICAgICAgICAgICAvLyBleGFtcGxlLCBhIC8vIHdhcm5pbmcgd2lsbCBiZSBwcmludGVkIHdoZW4gcGFyc2luZyBhCisgICAgICAgICAgICAgICAgICAgICAvLyBtZXNzYWdlIHRoYXQgaXMgbmVhciB0aGUgbWVzc2FnZSBzaXplIGxpbWl0LgorICBMT0dMRVZFTF9FUlJPUiwgICAgLy8gQW4gZXJyb3Igb2NjdXJyZWQgd2hpY2ggc2hvdWxkIG5ldmVyIGhhcHBlbiBkdXJpbmcKKyAgICAgICAgICAgICAgICAgICAgIC8vIG5vcm1hbCB1c2UuCisgIExPR0xFVkVMX0ZBVEFMLCAgICAvLyBBbiBlcnJvciBvY2N1cnJlZCBmcm9tIHdoaWNoIHRoZSBsaWJyYXJ5IGNhbm5vdAorICAgICAgICAgICAgICAgICAgICAgLy8gcmVjb3Zlci4gIFRoaXMgdXN1YWxseSBpbmRpY2F0ZXMgYSBwcm9ncmFtbWluZyBlcnJvcgorICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIGNvZGUgd2hpY2ggY2FsbHMgdGhlIGxpYnJhcnksIGVzcGVjaWFsbHkgd2hlbgorICAgICAgICAgICAgICAgICAgICAgLy8gY29tcGlsZWQgaW4gZGVidWcgbW9kZS4KKworI2lmZGVmIE5ERUJVRworICBMT0dMRVZFTF9ERkFUQUwgPSBMT0dMRVZFTF9FUlJPUgorI2Vsc2UKKyAgTE9HTEVWRUxfREZBVEFMID0gTE9HTEVWRUxfRkFUQUwKKyNlbmRpZgorfTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgTG9nRmluaXNoZXI7CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMb2dNZXNzYWdlIHsKKyBwdWJsaWM6CisgIExvZ01lc3NhZ2UoTG9nTGV2ZWwgbGV2ZWwsIGNvbnN0IGNoYXIqIGZpbGVuYW1lLCBpbnQgbGluZSk7CisgIH5Mb2dNZXNzYWdlKCk7CisKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChjb25zdCBzdGQ6OnN0cmluZyYgdmFsdWUpOworICBMb2dNZXNzYWdlJiBvcGVyYXRvcjw8KGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChjaGFyIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChpbnQgdmFsdWUpOworICBMb2dNZXNzYWdlJiBvcGVyYXRvcjw8KHVpbnQgdmFsdWUpOworICBMb2dNZXNzYWdlJiBvcGVyYXRvcjw8KGxvbmcgdmFsdWUpOworICBMb2dNZXNzYWdlJiBvcGVyYXRvcjw8KHVuc2lnbmVkIGxvbmcgdmFsdWUpOworICBMb2dNZXNzYWdlJiBvcGVyYXRvcjw8KGRvdWJsZSB2YWx1ZSk7CisgIExvZ01lc3NhZ2UmIG9wZXJhdG9yPDwodm9pZCogdmFsdWUpOworCisgcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIExvZ0ZpbmlzaGVyOworICB2b2lkIEZpbmlzaCgpOworCisgIExvZ0xldmVsIGxldmVsXzsKKyAgY29uc3QgY2hhciogZmlsZW5hbWVfOworICBpbnQgbGluZV87CisgIHN0ZDo6c3RyaW5nIG1lc3NhZ2VfOworfTsKKworLy8gVXNlZCB0byBtYWtlIHRoZSBlbnRpcmUgIkxPRyhCTEFIKSA8PCBldGMuIiBleHByZXNzaW9uIGhhdmUgYSB2b2lkIHJldHVybgorLy8gdHlwZSBhbmQgcHJpbnQgYSBuZXdsaW5lIGFmdGVyIGVhY2ggbWVzc2FnZS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMb2dGaW5pc2hlciB7CisgcHVibGljOgorICB2b2lkIG9wZXJhdG9yPShMb2dNZXNzYWdlJiBvdGhlcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gVW5kZWYgZXZlcnl0aGluZyBpbiBjYXNlIHdlJ3JlIGJlaW5nIG1peGVkIHdpdGggc29tZSBvdGhlciBHb29nbGUgbGlicmFyeQorLy8gd2hpY2ggYWxyZWFkeSBkZWZpbmVkIHRoZW0gaXRzZWxmLiAgUHJlc3VtYWJseSBhbGwgR29vZ2xlIGxpYnJhcmllcyB3aWxsCisvLyBzdXBwb3J0IHRoZSBzYW1lIHN5bnRheCBmb3IgdGhlc2Ugc28gaXQgc2hvdWxkIG5vdCBiZSBhIGJpZyBkZWFsIGlmIHRoZXkKKy8vIGVuZCB1cCB1c2luZyBvdXIgZGVmaW5pdGlvbnMgaW5zdGVhZC4KKyN1bmRlZiBHT09HTEVfTE9HCisjdW5kZWYgR09PR0xFX0xPR19JRgorCisjdW5kZWYgR09PR0xFX0NIRUNLCisjdW5kZWYgR09PR0xFX0NIRUNLX09LCisjdW5kZWYgR09PR0xFX0NIRUNLX0VRCisjdW5kZWYgR09PR0xFX0NIRUNLX05FCisjdW5kZWYgR09PR0xFX0NIRUNLX0xUCisjdW5kZWYgR09PR0xFX0NIRUNLX0xFCisjdW5kZWYgR09PR0xFX0NIRUNLX0dUCisjdW5kZWYgR09PR0xFX0NIRUNLX0dFCisjdW5kZWYgR09PR0xFX0NIRUNLX05PVE5VTEwKKworI3VuZGVmIEdPT0dMRV9ETE9HCisjdW5kZWYgR09PR0xFX0RDSEVDSworI3VuZGVmIEdPT0dMRV9EQ0hFQ0tfRVEKKyN1bmRlZiBHT09HTEVfRENIRUNLX05FCisjdW5kZWYgR09PR0xFX0RDSEVDS19MVAorI3VuZGVmIEdPT0dMRV9EQ0hFQ0tfTEUKKyN1bmRlZiBHT09HTEVfRENIRUNLX0dUCisjdW5kZWYgR09PR0xFX0RDSEVDS19HRQorCisjZGVmaW5lIEdPT0dMRV9MT0coTEVWRUwpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TG9nRmluaXNoZXIoKSA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkxvZ01lc3NhZ2UoICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkxPR0xFVkVMXyMjTEVWRUwsIF9fRklMRV9fLCBfX0xJTkVfXykKKyNkZWZpbmUgR09PR0xFX0xPR19JRihMRVZFTCwgQ09ORElUSU9OKSBcCisgICEoQ09ORElUSU9OKSA/ICh2b2lkKTAgOiBHT09HTEVfTE9HKExFVkVMKQorCisjZGVmaW5lIEdPT0dMRV9DSEVDSyhFWFBSRVNTSU9OKSBcCisgIEdPT0dMRV9MT0dfSUYoRkFUQUwsICEoRVhQUkVTU0lPTikpIDw8ICJDSEVDSyBmYWlsZWQ6ICIgI0VYUFJFU1NJT04gIjogIgorI2RlZmluZSBHT09HTEVfQ0hFQ0tfT0soQSkgR09PR0xFX0NIRUNLKEEpCisjZGVmaW5lIEdPT0dMRV9DSEVDS19FUShBLCBCKSBHT09HTEVfQ0hFQ0soKEEpID09IChCKSkKKyNkZWZpbmUgR09PR0xFX0NIRUNLX05FKEEsIEIpIEdPT0dMRV9DSEVDSygoQSkgIT0gKEIpKQorI2RlZmluZSBHT09HTEVfQ0hFQ0tfTFQoQSwgQikgR09PR0xFX0NIRUNLKChBKSA8ICAoQikpCisjZGVmaW5lIEdPT0dMRV9DSEVDS19MRShBLCBCKSBHT09HTEVfQ0hFQ0soKEEpIDw9IChCKSkKKyNkZWZpbmUgR09PR0xFX0NIRUNLX0dUKEEsIEIpIEdPT0dMRV9DSEVDSygoQSkgPiAgKEIpKQorI2RlZmluZSBHT09HTEVfQ0hFQ0tfR0UoQSwgQikgR09PR0xFX0NIRUNLKChBKSA+PSAoQikpCisKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorVCogQ2hlY2tOb3ROdWxsKGNvbnN0IGNoYXIqIC8qIGZpbGUgKi8sIGludCAvKiBsaW5lICovLAorICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIG5hbWUsIFQqIHZhbCkgeworICBpZiAodmFsID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCBuYW1lOworICB9CisgIHJldHVybiB2YWw7Cit9Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKyNkZWZpbmUgR09PR0xFX0NIRUNLX05PVE5VTEwoQSkgXAorICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpDaGVja05vdE51bGwoXAorICAgICAgX19GSUxFX18sIF9fTElORV9fLCAiJyIgI0EgIicgbXVzdCBub3QgYmUgTlVMTCIsIChBKSkKKworI2lmZGVmIE5ERUJVRworCisjZGVmaW5lIEdPT0dMRV9ETE9HIEdPT0dMRV9MT0dfSUYoSU5GTywgZmFsc2UpCisKKyNkZWZpbmUgR09PR0xFX0RDSEVDSyhFWFBSRVNTSU9OKSB3aGlsZShmYWxzZSkgR09PR0xFX0NIRUNLKEVYUFJFU1NJT04pCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfRVEoQSwgQikgR09PR0xFX0RDSEVDSygoQSkgPT0gKEIpKQorI2RlZmluZSBHT09HTEVfRENIRUNLX05FKEEsIEIpIEdPT0dMRV9EQ0hFQ0soKEEpICE9IChCKSkKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19MVChBLCBCKSBHT09HTEVfRENIRUNLKChBKSA8ICAoQikpCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfTEUoQSwgQikgR09PR0xFX0RDSEVDSygoQSkgPD0gKEIpKQorI2RlZmluZSBHT09HTEVfRENIRUNLX0dUKEEsIEIpIEdPT0dMRV9EQ0hFQ0soKEEpID4gIChCKSkKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19HRShBLCBCKSBHT09HTEVfRENIRUNLKChBKSA+PSAoQikpCisKKyNlbHNlICAvLyBOREVCVUcKKworI2RlZmluZSBHT09HTEVfRExPRyBHT09HTEVfTE9HCisKKyNkZWZpbmUgR09PR0xFX0RDSEVDSyAgICBHT09HTEVfQ0hFQ0sKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19FUSBHT09HTEVfQ0hFQ0tfRVEKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19ORSBHT09HTEVfQ0hFQ0tfTkUKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19MVCBHT09HTEVfQ0hFQ0tfTFQKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19MRSBHT09HTEVfQ0hFQ0tfTEUKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19HVCBHT09HTEVfQ0hFQ0tfR1QKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19HRSBHT09HTEVfQ0hFQ0tfR0UKKworI2VuZGlmICAvLyAhTkRFQlVHCisKK3R5cGVkZWYgdm9pZCBMb2dIYW5kbGVyKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgbWVzc2FnZSk7CisKKy8vIFRoZSBwcm90b2J1ZiBsaWJyYXJ5IHNvbWV0aW1lcyB3cml0ZXMgd2FybmluZyBhbmQgZXJyb3IgbWVzc2FnZXMgdG8KKy8vIHN0ZGVyci4gIFRoZXNlIG1lc3NhZ2VzIGFyZSBwcmltYXJpbHkgdXNlZnVsIGZvciBkZXZlbG9wZXJzLCBidXQgbWF5CisvLyBhbHNvIGhlbHAgZW5kIHVzZXJzIGZpZ3VyZSBvdXQgYSBwcm9ibGVtLiAgSWYgeW91IHdvdWxkIHByZWZlciB0aGF0CisvLyB0aGVzZSBtZXNzYWdlcyBiZSBzZW50IHNvbWV3aGVyZSBvdGhlciB0aGFuIHN0ZGVyciwgY2FsbCBTZXRMb2dIYW5kbGVyKCkKKy8vIHRvIHNldCB5b3VyIG93biBoYW5kbGVyLiAgVGhpcyByZXR1cm5zIHRoZSBvbGQgaGFuZGxlci4gIFNldCB0aGUgaGFuZGxlcgorLy8gdG8gTlVMTCB0byBpZ25vcmUgbG9nIG1lc3NhZ2VzIChidXQgc2VlIGFsc28gTG9nU2lsZW5jZXIsIGJlbG93KS4KKy8vCisvLyBPYnZpb3VzbHksIFNldExvZ0hhbmRsZXIgaXMgbm90IHRocmVhZC1zYWZlLiAgWW91IHNob3VsZCBvbmx5IGNhbGwgaXQKKy8vIGF0IGluaXRpYWxpemF0aW9uIHRpbWUsIGFuZCBwcm9iYWJseSBub3QgZnJvbSBsaWJyYXJ5IGNvZGUuICBJZiB5b3UKKy8vIHNpbXBseSB3YW50IHRvIHN1cHByZXNzIGxvZyBtZXNzYWdlcyB0ZW1wb3JhcmlseSAoZS5nLiBiZWNhdXNlIHlvdQorLy8gaGF2ZSBzb21lIGNvZGUgdGhhdCB0ZW5kcyB0byB0cmlnZ2VyIHRoZW0gZnJlcXVlbnRseSBhbmQgeW91IGtub3cKKy8vIHRoZSB3YXJuaW5ncyBhcmUgbm90IGltcG9ydGFudCB0byB5b3UpLCB1c2UgdGhlIExvZ1NpbGVuY2VyIGNsYXNzCisvLyBiZWxvdy4KK0xJQlBST1RPQlVGX0VYUE9SVCBMb2dIYW5kbGVyKiBTZXRMb2dIYW5kbGVyKExvZ0hhbmRsZXIqIG5ld19mdW5jKTsKKworLy8gQ3JlYXRlIGEgTG9nU2lsZW5jZXIgaWYgeW91IHdhbnQgdG8gdGVtcG9yYXJpbHkgc3VwcHJlc3MgYWxsIGxvZworLy8gbWVzc2FnZXMuICBBcyBsb25nIGFzIGFueSBMb2dTaWxlbmNlciBvYmplY3RzIGV4aXN0LCBub24tZmF0YWwKKy8vIGxvZyBtZXNzYWdlcyB3aWxsIGJlIGRpc2NhcmRlZCAodGhlIGN1cnJlbnQgTG9nSGFuZGxlciB3aWxsICpub3QqCisvLyBiZSBjYWxsZWQpLiAgQ29uc3RydWN0aW5nIGEgTG9nU2lsZW5jZXIgaXMgdGhyZWFkLXNhZmUuICBZb3UgbWF5CisvLyBhY2NpZGVudGFsbHkgc3VwcHJlc3MgbG9nIG1lc3NhZ2VzIG9jY3VycmluZyBpbiBhbm90aGVyIHRocmVhZCwgYnV0CisvLyBzaW5jZSBtZXNzYWdlcyBhcmUgZ2VuZXJhbGx5IGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMgb25seSwgdGhpcyBpc24ndAorLy8gYSBiaWcgZGVhbC4gIElmIHlvdSB3YW50IHRvIGludGVyY2VwdCBsb2cgbWVzc2FnZXMsIHVzZSBTZXRMb2dIYW5kbGVyKCkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTG9nU2lsZW5jZXIgeworIHB1YmxpYzoKKyAgTG9nU2lsZW5jZXIoKTsKKyAgfkxvZ1NpbGVuY2VyKCk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvY2FsbGJhY2suaAorCisvLyBBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIGEgY2FsbGJhY2suICBXaGVuIGNhbGxpbmcgYW4gUlBDLCB5b3UgbXVzdCBwcm92aWRlCisvLyBhIENsb3N1cmUgdG8gY2FsbCB3aGVuIHRoZSBwcm9jZWR1cmUgY29tcGxldGVzLiAgU2VlIHRoZSBTZXJ2aWNlIGludGVyZmFjZQorLy8gaW4gc2VydmljZS5oLgorLy8KKy8vIFRvIGF1dG9tYXRpY2FsbHkgY29uc3RydWN0IGEgQ2xvc3VyZSB3aGljaCBjYWxscyBhIHBhcnRpY3VsYXIgZnVuY3Rpb24gb3IKKy8vIG1ldGhvZCB3aXRoIGEgcGFydGljdWxhciBzZXQgb2YgcGFyYW1ldGVycywgdXNlIHRoZSBOZXdDYWxsYmFjaygpIGZ1bmN0aW9uLgorLy8gRXhhbXBsZToKKy8vICAgdm9pZCBGb29Eb25lKGNvbnN0IEZvb1Jlc3BvbnNlKiByZXNwb25zZSkgeworLy8gICAgIC4uLgorLy8gICB9CisvLworLy8gICB2b2lkIENhbGxGb28oKSB7CisvLyAgICAgLi4uCisvLyAgICAgLy8gV2hlbiBkb25lLCBjYWxsIEZvb0RvbmUoKSBhbmQgcGFzcyBpdCBhIHBvaW50ZXIgdG8gdGhlIHJlc3BvbnNlLgorLy8gICAgIENsb3N1cmUqIGNhbGxiYWNrID0gTmV3Q2FsbGJhY2soJkZvb0RvbmUsIHJlc3BvbnNlKTsKKy8vICAgICAvLyBNYWtlIHRoZSBjYWxsLgorLy8gICAgIHNlcnZpY2UtPkZvbyhjb250cm9sbGVyLCByZXF1ZXN0LCByZXNwb25zZSwgY2FsbGJhY2spOworLy8gICB9CisvLworLy8gRXhhbXBsZSB0aGF0IGNhbGxzIGEgbWV0aG9kOgorLy8gICBjbGFzcyBIYW5kbGVyIHsKKy8vICAgIHB1YmxpYzoKKy8vICAgICAuLi4KKy8vCisvLyAgICAgdm9pZCBGb29Eb25lKGNvbnN0IEZvb1Jlc3BvbnNlKiByZXNwb25zZSkgeworLy8gICAgICAgLi4uCisvLyAgICAgfQorLy8KKy8vICAgICB2b2lkIENhbGxGb28oKSB7CisvLyAgICAgICAuLi4KKy8vICAgICAgIC8vIFdoZW4gZG9uZSwgY2FsbCBGb29Eb25lKCkgYW5kIHBhc3MgaXQgYSBwb2ludGVyIHRvIHRoZSByZXNwb25zZS4KKy8vICAgICAgIENsb3N1cmUqIGNhbGxiYWNrID0gTmV3Q2FsbGJhY2sodGhpcywgJkhhbmRsZXI6OkZvb0RvbmUsIHJlc3BvbnNlKTsKKy8vICAgICAgIC8vIE1ha2UgdGhlIGNhbGwuCisvLyAgICAgICBzZXJ2aWNlLT5Gb28oY29udHJvbGxlciwgcmVxdWVzdCwgcmVzcG9uc2UsIGNhbGxiYWNrKTsKKy8vICAgICB9CisvLyAgIH07CisvLworLy8gQ3VycmVudGx5IE5ld0NhbGxiYWNrKCkgc3VwcG9ydHMgYmluZGluZyB6ZXJvLCBvbmUsIG9yIHR3byBhcmd1bWVudHMuCisvLworLy8gQ2FsbGJhY2tzIGNyZWF0ZWQgd2l0aCBOZXdDYWxsYmFjaygpIGF1dG9tYXRpY2FsbHkgZGVsZXRlIHRoZW1zZWx2ZXMgd2hlbgorLy8gZXhlY3V0ZWQuICBUaGV5IHNob3VsZCBiZSB1c2VkIHdoZW4gYSBjYWxsYmFjayBpcyB0byBiZSBjYWxsZWQgZXhhY3RseQorLy8gb25jZSAodXN1YWxseSB0aGUgY2FzZSB3aXRoIFJQQyBjYWxsYmFja3MpLiAgSWYgYSBjYWxsYmFjayBtYXkgYmUgY2FsbGVkCisvLyBhIGRpZmZlcmVudCBudW1iZXIgb2YgdGltZXMgKGluY2x1ZGluZyB6ZXJvKSwgY3JlYXRlIGl0IHdpdGgKKy8vIE5ld1Blcm1hbmVudENhbGxiYWNrKCkgaW5zdGVhZC4gIFlvdSBhcmUgdGhlbiByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgdGhlCisvLyBjYWxsYmFjayAodXNpbmcgdGhlICJkZWxldGUiIGtleXdvcmQgYXMgbm9ybWFsKS4KKy8vCisvLyBOb3RlIHRoYXQgTmV3Q2FsbGJhY2soKSBpcyBhIGJpdCB0b3VjaHkgcmVnYXJkaW5nIGFyZ3VtZW50IHR5cGVzLiAgR2VuZXJhbGx5LAorLy8gdGhlIHZhbHVlcyB5b3UgcHJvdmlkZSBmb3IgdGhlIHBhcmFtZXRlciBiaW5kaW5ncyBtdXN0IGV4YWN0bHkgbWF0Y2ggdGhlCisvLyB0eXBlcyBhY2NlcHRlZCBieSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uICBGb3IgZXhhbXBsZToKKy8vICAgdm9pZCBGb28oc3RyaW5nIHMpOworLy8gICBOZXdDYWxsYmFjaygmRm9vLCAiZm9vIik7ICAgICAgICAgIC8vIFdPTidUIFdPUks6ICBjb25zdCBjaGFyKiAhPSBzdHJpbmcKKy8vICAgTmV3Q2FsbGJhY2soJkZvbywgc3RyaW5nKCJmb28iKSk7ICAvLyBXT1JLUworLy8gQWxzbyBub3RlIHRoYXQgdGhlIGFyZ3VtZW50cyBjYW5ub3QgYmUgcmVmZXJlbmNlczoKKy8vICAgdm9pZCBGb28oY29uc3Qgc3RyaW5nJiBzKTsKKy8vICAgc3RyaW5nIG15X3N0cjsKKy8vICAgTmV3Q2FsbGJhY2soJkZvbywgbXlfc3RyKTsgIC8vIFdPTidUIFdPUks6ICBDYW4ndCB1c2UgcmVmZXJlY25lcy4KKy8vIEhvd2V2ZXIsIGNvcnJlY3RseS10eXBlZCBwb2ludGVycyB3aWxsIHdvcmsganVzdCBmaW5lLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIENsb3N1cmUgeworIHB1YmxpYzoKKyAgQ2xvc3VyZSgpIHt9CisgIHZpcnR1YWwgfkNsb3N1cmUoKTsKKworICB2aXJ0dWFsIHZvaWQgUnVuKCkgPSAwOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENsb3N1cmUpOworfTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZ1bmN0aW9uQ2xvc3VyZTAgOiBwdWJsaWMgQ2xvc3VyZSB7CisgcHVibGljOgorICB0eXBlZGVmIHZvaWQgKCpGdW5jdGlvblR5cGUpKCk7CisKKyAgRnVuY3Rpb25DbG9zdXJlMChGdW5jdGlvblR5cGUgZnVuY3Rpb24sIGJvb2wgc2VsZl9kZWxldGluZykKKyAgICA6IGZ1bmN0aW9uXyhmdW5jdGlvbiksIHNlbGZfZGVsZXRpbmdfKHNlbGZfZGVsZXRpbmcpIHt9CisgIH5GdW5jdGlvbkNsb3N1cmUwKCk7CisKKyAgdm9pZCBSdW4oKSB7CisgICAgYm9vbCBuZWVkc19kZWxldGUgPSBzZWxmX2RlbGV0aW5nXzsgIC8vIHJlYWQgaW4gY2FzZSBjYWxsYmFjayBkZWxldGVzCisgICAgZnVuY3Rpb25fKCk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIEZ1bmN0aW9uVHlwZSBmdW5jdGlvbl87CisgIGJvb2wgc2VsZl9kZWxldGluZ187Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2xhc3M+CitjbGFzcyBNZXRob2RDbG9zdXJlMCA6IHB1YmxpYyBDbG9zdXJlIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgdm9pZCAoQ2xhc3M6OipNZXRob2RUeXBlKSgpOworCisgIE1ldGhvZENsb3N1cmUwKENsYXNzKiBvYmplY3QsIE1ldGhvZFR5cGUgbWV0aG9kLCBib29sIHNlbGZfZGVsZXRpbmcpCisgICAgOiBvYmplY3RfKG9iamVjdCksIG1ldGhvZF8obWV0aG9kKSwgc2VsZl9kZWxldGluZ18oc2VsZl9kZWxldGluZykge30KKyAgfk1ldGhvZENsb3N1cmUwKCkge30KKworICB2b2lkIFJ1bigpIHsKKyAgICBib29sIG5lZWRzX2RlbGV0ZSA9IHNlbGZfZGVsZXRpbmdfOyAgLy8gcmVhZCBpbiBjYXNlIGNhbGxiYWNrIGRlbGV0ZXMKKyAgICAob2JqZWN0Xy0+Km1ldGhvZF8pKCk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIENsYXNzKiBvYmplY3RfOworICBNZXRob2RUeXBlIG1ldGhvZF87CisgIGJvb2wgc2VsZl9kZWxldGluZ187Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMT4KK2NsYXNzIEZ1bmN0aW9uQ2xvc3VyZTEgOiBwdWJsaWMgQ2xvc3VyZSB7CisgcHVibGljOgorICB0eXBlZGVmIHZvaWQgKCpGdW5jdGlvblR5cGUpKEFyZzEgYXJnMSk7CisKKyAgRnVuY3Rpb25DbG9zdXJlMShGdW5jdGlvblR5cGUgZnVuY3Rpb24sIGJvb2wgc2VsZl9kZWxldGluZywKKyAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEpCisgICAgOiBmdW5jdGlvbl8oZnVuY3Rpb24pLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSwKKyAgICAgIGFyZzFfKGFyZzEpIHt9CisgIH5GdW5jdGlvbkNsb3N1cmUxKCkge30KKworICB2b2lkIFJ1bigpIHsKKyAgICBib29sIG5lZWRzX2RlbGV0ZSA9IHNlbGZfZGVsZXRpbmdfOyAgLy8gcmVhZCBpbiBjYXNlIGNhbGxiYWNrIGRlbGV0ZXMKKyAgICBmdW5jdGlvbl8oYXJnMV8pOworICAgIGlmIChuZWVkc19kZWxldGUpIGRlbGV0ZSB0aGlzOworICB9CisKKyBwcml2YXRlOgorICBGdW5jdGlvblR5cGUgZnVuY3Rpb25fOworICBib29sIHNlbGZfZGVsZXRpbmdfOworICBBcmcxIGFyZzFfOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzLCB0eXBlbmFtZSBBcmcxPgorY2xhc3MgTWV0aG9kQ2xvc3VyZTEgOiBwdWJsaWMgQ2xvc3VyZSB7CisgcHVibGljOgorICB0eXBlZGVmIHZvaWQgKENsYXNzOjoqTWV0aG9kVHlwZSkoQXJnMSBhcmcxKTsKKworICBNZXRob2RDbG9zdXJlMShDbGFzcyogb2JqZWN0LCBNZXRob2RUeXBlIG1ldGhvZCwgYm9vbCBzZWxmX2RlbGV0aW5nLAorICAgICAgICAgICAgICAgICBBcmcxIGFyZzEpCisgICAgOiBvYmplY3RfKG9iamVjdCksIG1ldGhvZF8obWV0aG9kKSwgc2VsZl9kZWxldGluZ18oc2VsZl9kZWxldGluZyksCisgICAgICBhcmcxXyhhcmcxKSB7fQorICB+TWV0aG9kQ2xvc3VyZTEoKSB7fQorCisgIHZvaWQgUnVuKCkgeworICAgIGJvb2wgbmVlZHNfZGVsZXRlID0gc2VsZl9kZWxldGluZ187ICAvLyByZWFkIGluIGNhc2UgY2FsbGJhY2sgZGVsZXRlcworICAgIChvYmplY3RfLT4qbWV0aG9kXykoYXJnMV8pOworICAgIGlmIChuZWVkc19kZWxldGUpIGRlbGV0ZSB0aGlzOworICB9CisKKyBwcml2YXRlOgorICBDbGFzcyogb2JqZWN0XzsKKyAgTWV0aG9kVHlwZSBtZXRob2RfOworICBib29sIHNlbGZfZGVsZXRpbmdfOworICBBcmcxIGFyZzFfOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+CitjbGFzcyBGdW5jdGlvbkNsb3N1cmUyIDogcHVibGljIENsb3N1cmUgeworIHB1YmxpYzoKKyAgdHlwZWRlZiB2b2lkICgqRnVuY3Rpb25UeXBlKShBcmcxIGFyZzEsIEFyZzIgYXJnMik7CisKKyAgRnVuY3Rpb25DbG9zdXJlMihGdW5jdGlvblR5cGUgZnVuY3Rpb24sIGJvb2wgc2VsZl9kZWxldGluZywKKyAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEsIEFyZzIgYXJnMikKKyAgICA6IGZ1bmN0aW9uXyhmdW5jdGlvbiksIHNlbGZfZGVsZXRpbmdfKHNlbGZfZGVsZXRpbmcpLAorICAgICAgYXJnMV8oYXJnMSksIGFyZzJfKGFyZzIpIHt9CisgIH5GdW5jdGlvbkNsb3N1cmUyKCkge30KKworICB2b2lkIFJ1bigpIHsKKyAgICBib29sIG5lZWRzX2RlbGV0ZSA9IHNlbGZfZGVsZXRpbmdfOyAgLy8gcmVhZCBpbiBjYXNlIGNhbGxiYWNrIGRlbGV0ZXMKKyAgICBmdW5jdGlvbl8oYXJnMV8sIGFyZzJfKTsKKyAgICBpZiAobmVlZHNfZGVsZXRlKSBkZWxldGUgdGhpczsKKyAgfQorCisgcHJpdmF0ZToKKyAgRnVuY3Rpb25UeXBlIGZ1bmN0aW9uXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKKyAgQXJnMSBhcmcxXzsKKyAgQXJnMiBhcmcyXzsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBDbGFzcywgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMj4KK2NsYXNzIE1ldGhvZENsb3N1cmUyIDogcHVibGljIENsb3N1cmUgeworIHB1YmxpYzoKKyAgdHlwZWRlZiB2b2lkIChDbGFzczo6Kk1ldGhvZFR5cGUpKEFyZzEgYXJnMSwgQXJnMiBhcmcyKTsKKworICBNZXRob2RDbG9zdXJlMihDbGFzcyogb2JqZWN0LCBNZXRob2RUeXBlIG1ldGhvZCwgYm9vbCBzZWxmX2RlbGV0aW5nLAorICAgICAgICAgICAgICAgICBBcmcxIGFyZzEsIEFyZzIgYXJnMikKKyAgICA6IG9iamVjdF8ob2JqZWN0KSwgbWV0aG9kXyhtZXRob2QpLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSwKKyAgICAgIGFyZzFfKGFyZzEpLCBhcmcyXyhhcmcyKSB7fQorICB+TWV0aG9kQ2xvc3VyZTIoKSB7fQorCisgIHZvaWQgUnVuKCkgeworICAgIGJvb2wgbmVlZHNfZGVsZXRlID0gc2VsZl9kZWxldGluZ187ICAvLyByZWFkIGluIGNhc2UgY2FsbGJhY2sgZGVsZXRlcworICAgIChvYmplY3RfLT4qbWV0aG9kXykoYXJnMV8sIGFyZzJfKTsKKyAgICBpZiAobmVlZHNfZGVsZXRlKSBkZWxldGUgdGhpczsKKyAgfQorCisgcHJpdmF0ZToKKyAgQ2xhc3MqIG9iamVjdF87CisgIE1ldGhvZFR5cGUgbWV0aG9kXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKKyAgQXJnMSBhcmcxXzsKKyAgQXJnMiBhcmcyXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyBTZWUgQ2xvc3VyZS4KK2lubGluZSBDbG9zdXJlKiBOZXdDYWxsYmFjayh2b2lkICgqZnVuY3Rpb24pKCkpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25DbG9zdXJlMChmdW5jdGlvbiwgdHJ1ZSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgoraW5saW5lIENsb3N1cmUqIE5ld1Blcm1hbmVudENhbGxiYWNrKHZvaWQgKCpmdW5jdGlvbikoKSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvbkNsb3N1cmUwKGZ1bmN0aW9uLCBmYWxzZSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzPgoraW5saW5lIENsb3N1cmUqIE5ld0NhbGxiYWNrKENsYXNzKiBvYmplY3QsIHZvaWQgKENsYXNzOjoqbWV0aG9kKSgpKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6Ok1ldGhvZENsb3N1cmUwPENsYXNzPihvYmplY3QsIG1ldGhvZCwgdHJ1ZSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzPgoraW5saW5lIENsb3N1cmUqIE5ld1Blcm1hbmVudENhbGxiYWNrKENsYXNzKiBvYmplY3QsIHZvaWQgKENsYXNzOjoqbWV0aG9kKSgpKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6Ok1ldGhvZENsb3N1cmUwPENsYXNzPihvYmplY3QsIG1ldGhvZCwgZmFsc2UpOworfQorCisvLyBTZWUgQ2xvc3VyZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBBcmcxPgoraW5saW5lIENsb3N1cmUqIE5ld0NhbGxiYWNrKHZvaWQgKCpmdW5jdGlvbikoQXJnMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6OkZ1bmN0aW9uQ2xvc3VyZTE8QXJnMT4oZnVuY3Rpb24sIHRydWUsIGFyZzEpOworfQorCisvLyBTZWUgQ2xvc3VyZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBBcmcxPgoraW5saW5lIENsb3N1cmUqIE5ld1Blcm1hbmVudENhbGxiYWNrKHZvaWQgKCpmdW5jdGlvbikoQXJnMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6OkZ1bmN0aW9uQ2xvc3VyZTE8QXJnMT4oZnVuY3Rpb24sIGZhbHNlLCBhcmcxKTsKK30KKworLy8gU2VlIENsb3N1cmUuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2xhc3MsIHR5cGVuYW1lIEFyZzE+CitpbmxpbmUgQ2xvc3VyZSogTmV3Q2FsbGJhY2soQ2xhc3MqIG9iamVjdCwgdm9pZCAoQ2xhc3M6OiptZXRob2QpKEFyZzEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZzEgYXJnMSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpNZXRob2RDbG9zdXJlMTxDbGFzcywgQXJnMT4ob2JqZWN0LCBtZXRob2QsIHRydWUsIGFyZzEpOworfQorCisvLyBTZWUgQ2xvc3VyZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBDbGFzcywgdHlwZW5hbWUgQXJnMT4KK2lubGluZSBDbG9zdXJlKiBOZXdQZXJtYW5lbnRDYWxsYmFjayhDbGFzcyogb2JqZWN0LCB2b2lkIChDbGFzczo6Km1ldGhvZCkoQXJnMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6Ok1ldGhvZENsb3N1cmUxPENsYXNzLCBBcmcxPihvYmplY3QsIG1ldGhvZCwgZmFsc2UsIGFyZzEpOworfQorCisvLyBTZWUgQ2xvc3VyZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyPgoraW5saW5lIENsb3N1cmUqIE5ld0NhbGxiYWNrKHZvaWQgKCpmdW5jdGlvbikoQXJnMSwgQXJnMiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxLCBBcmcyIGFyZzIpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25DbG9zdXJlMjxBcmcxLCBBcmcyPigKKyAgICBmdW5jdGlvbiwgdHJ1ZSwgYXJnMSwgYXJnMik7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+CitpbmxpbmUgQ2xvc3VyZSogTmV3UGVybWFuZW50Q2FsbGJhY2sodm9pZCAoKmZ1bmN0aW9uKShBcmcxLCBBcmcyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEsIEFyZzIgYXJnMikgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvbkNsb3N1cmUyPEFyZzEsIEFyZzI+KAorICAgIGZ1bmN0aW9uLCBmYWxzZSwgYXJnMSwgYXJnMik7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzLCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyPgoraW5saW5lIENsb3N1cmUqIE5ld0NhbGxiYWNrKENsYXNzKiBvYmplY3QsIHZvaWQgKENsYXNzOjoqbWV0aG9kKShBcmcxLCBBcmcyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEsIEFyZzIgYXJnMikgeworICByZXR1cm4gbmV3IGludGVybmFsOjpNZXRob2RDbG9zdXJlMjxDbGFzcywgQXJnMSwgQXJnMj4oCisgICAgb2JqZWN0LCBtZXRob2QsIHRydWUsIGFyZzEsIGFyZzIpOworfQorCisvLyBTZWUgQ2xvc3VyZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBDbGFzcywgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMj4KK2lubGluZSBDbG9zdXJlKiBOZXdQZXJtYW5lbnRDYWxsYmFjaygKKyAgICBDbGFzcyogb2JqZWN0LCB2b2lkIChDbGFzczo6Km1ldGhvZCkoQXJnMSwgQXJnMiksCisgICAgQXJnMSBhcmcxLCBBcmcyIGFyZzIpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6TWV0aG9kQ2xvc3VyZTI8Q2xhc3MsIEFyZzEsIEFyZzI+KAorICAgIG9iamVjdCwgbWV0aG9kLCBmYWxzZSwgYXJnMSwgYXJnMik7Cit9CisKKy8vIEEgZnVuY3Rpb24gd2hpY2ggZG9lcyBub3RoaW5nLiAgVXNlZnVsIGZvciBjcmVhdGluZyBuby1vcCBjYWxsYmFja3MsIGUuZy46CisvLyAgIENsb3N1cmUqIG5vdGhpbmcgPSBOZXdDYWxsYmFjaygmRG9Ob3RoaW5nKTsKK3ZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIERvTm90aGluZygpOworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvbXV0ZXguaAorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBBIE11dGV4IGlzIGEgbm9uLXJlZW50cmFudCAoYWthIG5vbi1yZWN1cnNpdmUpIG11dGV4LiAgQXQgbW9zdCBvbmUgdGhyZWFkIFQKKy8vIG1heSBob2xkIGEgbXV0ZXggYXQgYSBnaXZlbiB0aW1lLiAgSWYgVCBhdHRlbXB0cyB0byBMb2NrKCkgdGhlIHNhbWUgTXV0ZXgKKy8vIHdoaWxlIGhvbGRpbmcgaXQsIFQgd2lsbCBkZWFkbG9jay4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNdXRleCB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBNdXRleCB0aGF0IGlzIG5vdCBoZWxkIGJ5IGFueWJvZHkuCisgIE11dGV4KCk7CisKKyAgLy8gRGVzdHJ1Y3RvcgorICB+TXV0ZXgoKTsKKworICAvLyBCbG9jayBpZiBuZWNlc3NhcnkgdW50aWwgdGhpcyBNdXRleCBpcyBmcmVlLCB0aGVuIGFjcXVpcmUgaXQgZXhjbHVzaXZlbHkuCisgIHZvaWQgTG9jaygpOworCisgIC8vIFJlbGVhc2UgdGhpcyBNdXRleC4gIENhbGxlciBtdXN0IGhvbGQgaXQgZXhjbHVzaXZlbHkuCisgIHZvaWQgVW5sb2NrKCk7CisKKyAgLy8gQ3Jhc2ggaWYgdGhpcyBNdXRleCBpcyBub3QgaGVsZCBleGNsdXNpdmVseSBieSB0aGlzIHRocmVhZC4KKyAgLy8gTWF5IGZhaWwgdG8gY3Jhc2ggd2hlbiBpdCBzaG91bGQ7IHdpbGwgbmV2ZXIgY3Jhc2ggd2hlbiBpdCBzaG91bGQgbm90LgorICB2b2lkIEFzc2VydEhlbGQoKTsKKworIHByaXZhdGU6CisgIHN0cnVjdCBJbnRlcm5hbDsKKyAgSW50ZXJuYWwqIG1JbnRlcm5hbDsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTXV0ZXgpOworfTsKKworLy8gTXV0ZXhMb2NrKG11KSBhY3F1aXJlcyBtdSB3aGVuIGNvbnN0cnVjdGVkIGFuZCByZWxlYXNlcyBpdCB3aGVuIGRlc3Ryb3llZC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNdXRleExvY2sgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTXV0ZXhMb2NrKE11dGV4ICptdSkgOiBtdV8obXUpIHsgdGhpcy0+bXVfLT5Mb2NrKCk7IH0KKyAgfk11dGV4TG9jaygpIHsgdGhpcy0+bXVfLT5VbmxvY2soKTsgfQorIHByaXZhdGU6CisgIE11dGV4ICpjb25zdCBtdV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNdXRleExvY2spOworfTsKKworLy8gVE9ETyhrZW50b24pOiAgSW1wbGVtZW50IHRoZXNlPyAgSGFyZCB0byBpbXBsZW1lbnQgcG9ydGFibHkuCit0eXBlZGVmIE11dGV4TG9jayBSZWFkZXJNdXRleExvY2s7Cit0eXBlZGVmIE11dGV4TG9jayBXcml0ZXJNdXRleExvY2s7CisKKy8vIE11dGV4TG9ja01heWJlIGlzIGxpa2UgTXV0ZXhMb2NrLCBidXQgaXMgYSBuby1vcCB3aGVuIG11IGlzIE5VTEwuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTXV0ZXhMb2NrTWF5YmUgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTXV0ZXhMb2NrTWF5YmUoTXV0ZXggKm11KSA6CisgICAgbXVfKG11KSB7IGlmICh0aGlzLT5tdV8gIT0gTlVMTCkgeyB0aGlzLT5tdV8tPkxvY2soKTsgfSB9CisgIH5NdXRleExvY2tNYXliZSgpIHsgaWYgKHRoaXMtPm11XyAhPSBOVUxMKSB7IHRoaXMtPm11Xy0+VW5sb2NrKCk7IH0gfQorIHByaXZhdGU6CisgIE11dGV4ICpjb25zdCBtdV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNdXRleExvY2tNYXliZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gV2UgbWFkZSB0aGVzZSBpbnRlcm5hbCBzbyB0aGF0IHRoZXkgd291bGQgc2hvdyB1cCBhcyBzdWNoIGluIHRoZSBkb2NzLAorLy8gYnV0IHdlIGRvbid0IHdhbnQgdG8gc3RpY2sgImludGVybmFsOjoiIGluIGZyb250IG9mIHRoZW0gZXZlcnl3aGVyZS4KK3VzaW5nIGludGVybmFsOjpNdXRleDsKK3VzaW5nIGludGVybmFsOjpNdXRleExvY2s7Cit1c2luZyBpbnRlcm5hbDo6UmVhZGVyTXV0ZXhMb2NrOwordXNpbmcgaW50ZXJuYWw6OldyaXRlck11dGV4TG9jazsKK3VzaW5nIGludGVybmFsOjpNdXRleExvY2tNYXliZTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZnJvbSBnb29nbGUzL3V0aWwvdXRmOC9wdWJsaWMvdW5pbGliLmgKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQ2hlY2tzIGlmIHRoZSBidWZmZXIgY29udGFpbnMgc3RydWN0dXJhbGx5LXZhbGlkIFVURi04LiAgSW1wbGVtZW50ZWQgaW4KKy8vIHN0cnVjdHVyYWxseV92YWxpZC5jYy4KK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGNvbnN0IGNoYXIqIGJ1ZiwgaW50IGxlbik7CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBmcm9tIGdvb2dsZTMvdXRpbC9lbmRpYW4vZW5kaWFuLmgKK0xJQlBST1RPQlVGX0VYUE9SVCB1aW50MzIgZ2h0b25sKHVpbnQzMiB4KTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gU2h1dGRvd24gc3VwcG9ydC4KKworLy8gU2h1dCBkb3duIHRoZSBlbnRpcmUgcHJvdG9jb2wgYnVmZmVycyBsaWJyYXJ5LCBkZWxldGluZyBhbGwgc3RhdGljLWR1cmF0aW9uCisvLyBvYmplY3RzIGFsbG9jYXRlZCBieSB0aGUgbGlicmFyeSBvciBieSBnZW5lcmF0ZWQgLnBiLmNjIGZpbGVzLgorLy8KKy8vIFRoZXJlIGFyZSB0d28gcmVhc29ucyB5b3UgbWlnaHQgd2FudCB0byBjYWxsIHRoaXM6CisvLyAqIFlvdSB1c2UgYSBkcmFjb25pYW4gZGVmaW5pdGlvbiBvZiAibWVtb3J5IGxlYWsiIGluIHdoaWNoIHlvdSBleHBlY3QKKy8vICAgZXZlcnkgc2luZ2xlIG1hbGxvYygpIHRvIGhhdmUgYSBjb3JyZXNwb25kaW5nIGZyZWUoKSwgZXZlbiBmb3Igb2JqZWN0cworLy8gICB3aGljaCBsaXZlIHVudGlsIHByb2dyYW0gZXhpdC4KKy8vICogWW91IGFyZSB3cml0aW5nIGEgZHluYW1pY2FsbHktbG9hZGVkIGxpYnJhcnkgd2hpY2ggbmVlZHMgdG8gY2xlYW4gdXAKKy8vICAgYWZ0ZXIgaXRzZWxmIHdoZW4gdGhlIGxpYnJhcnkgaXMgdW5sb2FkZWQuCisvLworLy8gSXQgaXMgc2FmZSB0byBjYWxsIHRoaXMgbXVsdGlwbGUgdGltZXMuICBIb3dldmVyLCBpdCBpcyBub3Qgc2FmZSB0byB1c2UKKy8vIGFueSBvdGhlciBwYXJ0IG9mIHRoZSBwcm90b2NvbCBidWZmZXJzIGxpYnJhcnkgYWZ0ZXIKKy8vIFNodXRkb3duUHJvdG9idWZMaWJyYXJ5KCkgaGFzIGJlZW4gY2FsbGVkLgorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gUmVnaXN0ZXIgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiBTaHV0ZG93blByb3RvY29sQnVmZmVycygpIGlzIGNhbGxlZC4KK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIE9uU2h1dGRvd24odm9pZCAoKmZ1bmMpKCkpOworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworI2lmIFBST1RPQlVGX1VTRV9FWENFUFRJT05TCitjbGFzcyBGYXRhbEV4Y2VwdGlvbiA6IHB1YmxpYyBzdGQ6OmV4Y2VwdGlvbiB7CisgcHVibGljOgorICBGYXRhbEV4Y2VwdGlvbihjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUsIGNvbnN0IHN0ZDo6c3RyaW5nJiBtZXNzYWdlKQorICAgICAgOiBmaWxlbmFtZV8oZmlsZW5hbWUpLCBsaW5lXyhsaW5lKSwgbWVzc2FnZV8obWVzc2FnZSkge30KKyAgdmlydHVhbCB+RmF0YWxFeGNlcHRpb24oKSB0aHJvdygpOworCisgIHZpcnR1YWwgY29uc3QgY2hhciogd2hhdCgpIGNvbnN0IHRocm93KCk7CisKKyAgY29uc3QgY2hhciogZmlsZW5hbWUoKSBjb25zdCB7IHJldHVybiBmaWxlbmFtZV87IH0KKyAgaW50IGxpbmUoKSBjb25zdCB7IHJldHVybiBsaW5lXzsgfQorICBjb25zdCBzdGQ6OnN0cmluZyYgbWVzc2FnZSgpIGNvbnN0IHsgcmV0dXJuIG1lc3NhZ2VfOyB9CisKKyBwcml2YXRlOgorICBjb25zdCBjaGFyKiBmaWxlbmFtZV87CisgIGNvbnN0IGludCBsaW5lXzsKKyAgY29uc3Qgc3RkOjpzdHJpbmcgbWVzc2FnZV87Cit9OworI2VuZGlmCisKKy8vIFRoaXMgaXMgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZSBpbnN0ZWFkIG9mIHRoZSBiZWdpbm5pbmcgdG8gd29yayBhcm91bmQgYSBidWcKKy8vIGluIHNvbWUgdmVyc2lvbnMgb2YgTVNWQy4KK3VzaW5nIG5hbWVzcGFjZSBzdGQ7ICAvLyBEb24ndCBkbyB0aGlzIGF0IGhvbWUsIGtpZHMuCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01NT05fSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmNDU4ZTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDM1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKKyNpbmNsdWRlICJjb25maWcuaCIKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworLy8gVE9ETyhrZW50b24pOiAgTW9yZSB0ZXN0cy4KKworI2lmZGVmIFBBQ0tBR0VfVkVSU0lPTiAgLy8gb25seSBkZWZpbmVkIHdoZW4gdXNpbmcgYXV0b21ha2UsIG5vdCBNU1ZDCisKK1RFU1QoVmVyc2lvblRlc3QsIFZlcnNpb25NYXRjaGVzQ29uZmlnKSB7CisgIC8vIFZlcmlmeSB0aGF0IHRoZSB2ZXJzaW9uIHN0cmluZyBzcGVjaWZpZWQgaW4gY29uZmlnLmggbWF0Y2hlcyB0aGUgb25lCisgIC8vIGluIGNvbW1vbi5oLiAgVGhlIGNvbmZpZy5oIHZlcnNpb24gaXMgYSBzdHJpbmcgd2hpY2ggbWF5IGhhdmUgYSBzdWZmaXgKKyAgLy8gbGlrZSAiYmV0YSIgb3IgInJjMSIsIHNvIHdlIHJlbW92ZSB0aGF0LgorICBzdHJpbmcgdmVyc2lvbiA9IFBBQ0tBR0VfVkVSU0lPTjsKKyAgaW50IHBvcyA9IDA7CisgIHdoaWxlIChwb3MgPCB2ZXJzaW9uLnNpemUoKSAmJgorICAgICAgICAgKGFzY2lpX2lzZGlnaXQodmVyc2lvbltwb3NdKSB8fCB2ZXJzaW9uW3Bvc10gPT0gJy4nKSkgeworICAgICsrcG9zOworICB9CisgIHZlcnNpb24uZXJhc2UocG9zKTsKKworICBFWFBFQ1RfRVEodmVyc2lvbiwgaW50ZXJuYWw6OlZlcnNpb25TdHJpbmcoR09PR0xFX1BST1RPQlVGX1ZFUlNJT04pKTsKK30KKworI2VuZGlmICAvLyBQQUNLQUdFX1ZFUlNJT04KKworVEVTVChDb21tb25UZXN0LCBJbnRNaW5NYXhDb25zdGFudHMpIHsKKyAgLy8ga2ludDMybWluIHdhcyBkZWNsYXJlZCBpbmNvcnJlY3RseSBpbiB0aGUgZmlyc3QgcmVsZWFzZSBvZiBwcm90b2J1ZnMuCisgIC8vIFVnaC4KKyAgRVhQRUNUX0xUKGtpbnQzMm1pbiwga2ludDMybWF4KTsKKyAgRVhQRUNUX0VRKHN0YXRpY19jYXN0PHVpbnQzMj4oa2ludDMybWluKSwgc3RhdGljX2Nhc3Q8dWludDMyPihraW50MzJtYXgpICsgMSk7CisgIEVYUEVDVF9MVChraW50NjRtaW4sIGtpbnQ2NG1heCk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDx1aW50NjQ+KGtpbnQ2NG1pbiksIHN0YXRpY19jYXN0PHVpbnQ2ND4oa2ludDY0bWF4KSArIDEpOworICBFWFBFQ1RfRVEoMCwga3VpbnQzMm1heCArIDEpOworICBFWFBFQ1RfRVEoMCwga3VpbnQ2NG1heCArIDEpOworfQorCit2ZWN0b3I8c3RyaW5nPiBjYXB0dXJlZF9tZXNzYWdlc187CisKK3ZvaWQgQ2FwdHVyZUxvZyhMb2dMZXZlbCBsZXZlbCwgY29uc3QgY2hhciogZmlsZW5hbWUsIGludCBsaW5lLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICBjYXB0dXJlZF9tZXNzYWdlc18ucHVzaF9iYWNrKAorICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIiQwICQxOiQyOiAkMyIsCisgICAgICBpbXBsaWNpdF9jYXN0PGludD4obGV2ZWwpLCBmaWxlbmFtZSwgbGluZSwgbWVzc2FnZSkpOworfQorCitURVNUKExvZ2dpbmdUZXN0LCBEZWZhdWx0TG9nZ2luZykgeworICBDYXB0dXJlVGVzdFN0ZGVycigpOworICBpbnQgbGluZSA9IF9fTElORV9fOworICBHT09HTEVfTE9HKElORk8gICApIDw8ICJBIG1lc3NhZ2UuIjsKKyAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiQSB3YXJuaW5nLiI7CisgIEdPT0dMRV9MT0coRVJST1IgICkgPDwgIkFuIGVycm9yLiI7CisKKyAgc3RyaW5nIHRleHQgPSBHZXRDYXB0dXJlZFRlc3RTdGRlcnIoKTsKKyAgRVhQRUNUX0VRKAorICAgICJbbGlicHJvdG9idWYgSU5GTyAiIF9fRklMRV9fICI6IiArIFNpbXBsZUl0b2EobGluZSArIDEpICsgIl0gQSBtZXNzYWdlLlxuIgorICAgICJbbGlicHJvdG9idWYgV0FSTklORyAiIF9fRklMRV9fICI6IiArIFNpbXBsZUl0b2EobGluZSArIDIpICsgIl0gQSB3YXJuaW5nLlxuIgorICAgICJbbGlicHJvdG9idWYgRVJST1IgIiBfX0ZJTEVfXyAiOiIgKyBTaW1wbGVJdG9hKGxpbmUgKyAzKSArICJdIEFuIGVycm9yLlxuIiwKKyAgICB0ZXh0KTsKK30KKworVEVTVChMb2dnaW5nVGVzdCwgTnVsbExvZ2dpbmcpIHsKKyAgTG9nSGFuZGxlciogb2xkX2hhbmRsZXIgPSBTZXRMb2dIYW5kbGVyKE5VTEwpOworCisgIENhcHR1cmVUZXN0U3RkZXJyKCk7CisgIEdPT0dMRV9MT0coSU5GTyAgICkgPDwgIkEgbWVzc2FnZS4iOworICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJBIHdhcm5pbmcuIjsKKyAgR09PR0xFX0xPRyhFUlJPUiAgKSA8PCAiQW4gZXJyb3IuIjsKKworICBFWFBFQ1RfVFJVRShTZXRMb2dIYW5kbGVyKG9sZF9oYW5kbGVyKSA9PSBOVUxMKTsKKworICBzdHJpbmcgdGV4dCA9IEdldENhcHR1cmVkVGVzdFN0ZGVycigpOworICBFWFBFQ1RfRVEoIiIsIHRleHQpOworfQorCitURVNUKExvZ2dpbmdUZXN0LCBDYXB0dXJlTG9nZ2luZykgeworICBjYXB0dXJlZF9tZXNzYWdlc18uY2xlYXIoKTsKKworICBMb2dIYW5kbGVyKiBvbGRfaGFuZGxlciA9IFNldExvZ0hhbmRsZXIoJkNhcHR1cmVMb2cpOworCisgIGludCBzdGFydF9saW5lID0gX19MSU5FX187CisgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJBbiBlcnJvci4iOworICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJBIHdhcm5pbmcuIjsKKworICBFWFBFQ1RfVFJVRShTZXRMb2dIYW5kbGVyKG9sZF9oYW5kbGVyKSA9PSAmQ2FwdHVyZUxvZyk7CisKKyAgQVNTRVJUX0VRKDIsIGNhcHR1cmVkX21lc3NhZ2VzXy5zaXplKCkpOworICBFWFBFQ1RfRVEoCisgICAgIjIgIiBfX0ZJTEVfXyAiOiIgKyBTaW1wbGVJdG9hKHN0YXJ0X2xpbmUgKyAxKSArICI6IEFuIGVycm9yLiIsCisgICAgY2FwdHVyZWRfbWVzc2FnZXNfWzBdKTsKKyAgRVhQRUNUX0VRKAorICAgICIxICIgX19GSUxFX18gIjoiICsgU2ltcGxlSXRvYShzdGFydF9saW5lICsgMikgKyAiOiBBIHdhcm5pbmcuIiwKKyAgICBjYXB0dXJlZF9tZXNzYWdlc19bMV0pOworfQorCitURVNUKExvZ2dpbmdUZXN0LCBTaWxlbmNlTG9nZ2luZykgeworICBjYXB0dXJlZF9tZXNzYWdlc18uY2xlYXIoKTsKKworICBMb2dIYW5kbGVyKiBvbGRfaGFuZGxlciA9IFNldExvZ0hhbmRsZXIoJkNhcHR1cmVMb2cpOworCisgIGludCBsaW5lMSA9IF9fTElORV9fOyBHT09HTEVfTE9HKElORk8pIDw8ICJWaXNpYmxlMSI7CisgIExvZ1NpbGVuY2VyKiBzaWxlbmNlcjEgPSBuZXcgTG9nU2lsZW5jZXI7CisgIEdPT0dMRV9MT0coSU5GTykgPDwgIk5vdCB2aXNpYmxlLiI7CisgIExvZ1NpbGVuY2VyKiBzaWxlbmNlcjIgPSBuZXcgTG9nU2lsZW5jZXI7CisgIEdPT0dMRV9MT0coSU5GTykgPDwgIk5vdCB2aXNpYmxlLiI7CisgIGRlbGV0ZSBzaWxlbmNlcjE7CisgIEdPT0dMRV9MT0coSU5GTykgPDwgIk5vdCB2aXNpYmxlLiI7CisgIGRlbGV0ZSBzaWxlbmNlcjI7CisgIGludCBsaW5lMiA9IF9fTElORV9fOyBHT09HTEVfTE9HKElORk8pIDw8ICJWaXNpYmxlMiI7CisKKyAgRVhQRUNUX1RSVUUoU2V0TG9nSGFuZGxlcihvbGRfaGFuZGxlcikgPT0gJkNhcHR1cmVMb2cpOworCisgIEFTU0VSVF9FUSgyLCBjYXB0dXJlZF9tZXNzYWdlc18uc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKAorICAgICIwICIgX19GSUxFX18gIjoiICsgU2ltcGxlSXRvYShsaW5lMSkgKyAiOiBWaXNpYmxlMSIsCisgICAgY2FwdHVyZWRfbWVzc2FnZXNfWzBdKTsKKyAgRVhQRUNUX0VRKAorICAgICIwICIgX19GSUxFX18gIjoiICsgU2ltcGxlSXRvYShsaW5lMikgKyAiOiBWaXNpYmxlMiIsCisgICAgY2FwdHVyZWRfbWVzc2FnZXNfWzFdKTsKK30KKworY2xhc3MgQ2xvc3VyZVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHVibGljOgorICB2b2lkIFNldEExMjNNZXRob2QoKSAgIHsgYV8gPSAxMjM7IH0KKyAgc3RhdGljIHZvaWQgU2V0QTEyM0Z1bmN0aW9uKCkgeyBjdXJyZW50X2luc3RhbmNlXy0+YV8gPSAxMjM7IH0KKworICB2b2lkIFNldEFNZXRob2QoaW50IGEpICAgICAgICAgeyBhXyA9IGE7IH0KKyAgdm9pZCBTZXRDTWV0aG9kKHN0cmluZyBjKSAgICAgIHsgY18gPSBjOyB9CisKKyAgc3RhdGljIHZvaWQgU2V0QUZ1bmN0aW9uKGludCBhKSAgICAgICAgIHsgY3VycmVudF9pbnN0YW5jZV8tPmFfID0gYTsgfQorICBzdGF0aWMgdm9pZCBTZXRDRnVuY3Rpb24oc3RyaW5nIGMpICAgICAgeyBjdXJyZW50X2luc3RhbmNlXy0+Y18gPSBjOyB9CisKKyAgdm9pZCBTZXRBQk1ldGhvZChpbnQgYSwgY29uc3QgY2hhciogYikgIHsgYV8gPSBhOyBiXyA9IGI7IH0KKyAgc3RhdGljIHZvaWQgU2V0QUJGdW5jdGlvbihpbnQgYSwgY29uc3QgY2hhciogYikgeworICAgIGN1cnJlbnRfaW5zdGFuY2VfLT5hXyA9IGE7CisgICAgY3VycmVudF9pbnN0YW5jZV8tPmJfID0gYjsKKyAgfQorCisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBjdXJyZW50X2luc3RhbmNlXyA9IHRoaXM7CisgICAgYV8gPSAwOworICAgIGJfID0gTlVMTDsKKyAgICBjXy5jbGVhcigpOworICAgIHBlcm1hbmVudF9jbG9zdXJlXyA9IE5VTEw7CisgIH0KKworICB2b2lkIERlbGV0ZUNsb3N1cmVJbkNhbGxiYWNrKCkgeworICAgIGRlbGV0ZSBwZXJtYW5lbnRfY2xvc3VyZV87CisgIH0KKworICBpbnQgYV87CisgIGNvbnN0IGNoYXIqIGJfOworICBzdHJpbmcgY187CisgIENsb3N1cmUqIHBlcm1hbmVudF9jbG9zdXJlXzsKKworICBzdGF0aWMgQ2xvc3VyZVRlc3QqIGN1cnJlbnRfaW5zdGFuY2VfOworfTsKKworQ2xvc3VyZVRlc3QqIENsb3N1cmVUZXN0OjpjdXJyZW50X2luc3RhbmNlXyA9IE5VTEw7CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdENsb3N1cmVGdW5jdGlvbjApIHsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld0NhbGxiYWNrKCZTZXRBMTIzRnVuY3Rpb24pOworICBFWFBFQ1RfTkUoMTIzLCBhXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoMTIzLCBhXyk7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdENsb3N1cmVNZXRob2QwKSB7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdDYWxsYmFjayhjdXJyZW50X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDbG9zdXJlVGVzdDo6U2V0QTEyM01ldGhvZCk7CisgIEVYUEVDVF9ORSgxMjMsIGFfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSgxMjMsIGFfKTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0Q2xvc3VyZUZ1bmN0aW9uMSkgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3Q2FsbGJhY2soJlNldEFGdW5jdGlvbiwgNDU2KTsKKyAgRVhQRUNUX05FKDQ1NiwgYV8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDQ1NiwgYV8pOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RDbG9zdXJlTWV0aG9kMSkgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3Q2FsbGJhY2soY3VycmVudF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmQ2xvc3VyZVRlc3Q6OlNldEFNZXRob2QsIDQ1Nik7CisgIEVYUEVDVF9ORSg0NTYsIGFfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg0NTYsIGFfKTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0Q2xvc3VyZUZ1bmN0aW9uMVN0cmluZykgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3Q2FsbGJhY2soJlNldENGdW5jdGlvbiwgc3RyaW5nKCJ0ZXN0IikpOworICBFWFBFQ1RfTkUoInRlc3QiLCBjXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoInRlc3QiLCBjXyk7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdENsb3N1cmVNZXRob2QxU3RyaW5nKSB7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdDYWxsYmFjayhjdXJyZW50X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDbG9zdXJlVGVzdDo6U2V0Q01ldGhvZCwgc3RyaW5nKCJ0ZXN0IikpOworICBFWFBFQ1RfTkUoInRlc3QiLCBjXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoInRlc3QiLCBjXyk7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdENsb3N1cmVGdW5jdGlvbjIpIHsKKyAgY29uc3QgY2hhciogY3N0ciA9ICJoZWxsbyI7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdDYWxsYmFjaygmU2V0QUJGdW5jdGlvbiwgNzg5LCBjc3RyKTsKKyAgRVhQRUNUX05FKDc4OSwgYV8pOworICBFWFBFQ1RfTkUoY3N0ciwgYl8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDc4OSwgYV8pOworICBFWFBFQ1RfRVEoY3N0ciwgYl8pOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RDbG9zdXJlTWV0aG9kMikgeworICBjb25zdCBjaGFyKiBjc3RyID0gImhlbGxvIjsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld0NhbGxiYWNrKGN1cnJlbnRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkNsb3N1cmVUZXN0OjpTZXRBQk1ldGhvZCwgNzg5LCBjc3RyKTsKKyAgRVhQRUNUX05FKDc4OSwgYV8pOworICBFWFBFQ1RfTkUoY3N0ciwgYl8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDc4OSwgYV8pOworICBFWFBFQ1RfRVEoY3N0ciwgYl8pOworfQorCisvLyBSZXBlYXQgYWxsIG9mIHRoZSBhYm92ZSB3aXRoIE5ld1Blcm1hbmVudENhbGxiYWNrKCkKKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0UGVybWFuZW50Q2xvc3VyZUZ1bmN0aW9uMCkgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3UGVybWFuZW50Q2FsbGJhY2soJlNldEExMjNGdW5jdGlvbik7CisgIEVYUEVDVF9ORSgxMjMsIGFfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSgxMjMsIGFfKTsKKyAgYV8gPSAwOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDEyMywgYV8pOworICBkZWxldGUgY2xvc3VyZTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0UGVybWFuZW50Q2xvc3VyZU1ldGhvZDApIHsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld1Blcm1hbmVudENhbGxiYWNrKGN1cnJlbnRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkNsb3N1cmVUZXN0OjpTZXRBMTIzTWV0aG9kKTsKKyAgRVhQRUNUX05FKDEyMywgYV8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDEyMywgYV8pOworICBhXyA9IDA7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoMTIzLCBhXyk7CisgIGRlbGV0ZSBjbG9zdXJlOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RQZXJtYW5lbnRDbG9zdXJlRnVuY3Rpb24xKSB7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdQZXJtYW5lbnRDYWxsYmFjaygmU2V0QUZ1bmN0aW9uLCA0NTYpOworICBFWFBFQ1RfTkUoNDU2LCBhXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNDU2LCBhXyk7CisgIGFfID0gMDsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg0NTYsIGFfKTsKKyAgZGVsZXRlIGNsb3N1cmU7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdFBlcm1hbmVudENsb3N1cmVNZXRob2QxKSB7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdQZXJtYW5lbnRDYWxsYmFjayhjdXJyZW50X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDbG9zdXJlVGVzdDo6U2V0QU1ldGhvZCwgNDU2KTsKKyAgRVhQRUNUX05FKDQ1NiwgYV8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDQ1NiwgYV8pOworICBhXyA9IDA7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNDU2LCBhXyk7CisgIGRlbGV0ZSBjbG9zdXJlOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RQZXJtYW5lbnRDbG9zdXJlRnVuY3Rpb24yKSB7CisgIGNvbnN0IGNoYXIqIGNzdHIgPSAiaGVsbG8iOworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3UGVybWFuZW50Q2FsbGJhY2soJlNldEFCRnVuY3Rpb24sIDc4OSwgY3N0cik7CisgIEVYUEVDVF9ORSg3ODksIGFfKTsKKyAgRVhQRUNUX05FKGNzdHIsIGJfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg3ODksIGFfKTsKKyAgRVhQRUNUX0VRKGNzdHIsIGJfKTsKKyAgYV8gPSAwOworICBiXyA9IE5VTEw7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNzg5LCBhXyk7CisgIEVYUEVDVF9FUShjc3RyLCBiXyk7CisgIGRlbGV0ZSBjbG9zdXJlOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RQZXJtYW5lbnRDbG9zdXJlTWV0aG9kMikgeworICBjb25zdCBjaGFyKiBjc3RyID0gImhlbGxvIjsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld1Blcm1hbmVudENhbGxiYWNrKGN1cnJlbnRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkNsb3N1cmVUZXN0OjpTZXRBQk1ldGhvZCwgNzg5LCBjc3RyKTsKKyAgRVhQRUNUX05FKDc4OSwgYV8pOworICBFWFBFQ1RfTkUoY3N0ciwgYl8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDc4OSwgYV8pOworICBFWFBFQ1RfRVEoY3N0ciwgYl8pOworICBhXyA9IDA7CisgIGJfID0gTlVMTDsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg3ODksIGFfKTsKKyAgRVhQRUNUX0VRKGNzdHIsIGJfKTsKKyAgZGVsZXRlIGNsb3N1cmU7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdFBlcm1hbmVudENsb3N1cmVEZWxldGVJbkNhbGxiYWNrKSB7CisgIHBlcm1hbmVudF9jbG9zdXJlXyA9IE5ld1Blcm1hbmVudENhbGxiYWNrKChDbG9zdXJlVGVzdCopIHRoaXMsCisgICAgICAmQ2xvc3VyZVRlc3Q6OkRlbGV0ZUNsb3N1cmVJbkNhbGxiYWNrKTsKKyAgcGVybWFuZW50X2Nsb3N1cmVfLT5SdW4oKTsKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Zhc3RtZW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvZmFzdG1lbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2M2E2ZTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Zhc3RtZW0uaApAQCAtMCwwICsxLDE1MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEZhc3QgbWVtb3J5IGNvcHlpbmcgYW5kIGNvbXBhcmlzb24gcm91dGluZXMuCisvLyAgIHN0cmluZ3M6OmZhc3RtZW1jbXBfaW5saW5lZCgpIHJlcGxhY2VzIG1lbWNtcCgpCisvLyAgIHN0cmluZ3M6Om1lbWNweV9pbmxpbmVkKCkgcmVwbGFjZXMgbWVtY3B5KCkKKy8vICAgc3RyaW5nczo6bWVtZXEoYSwgYiwgbikgcmVwbGFjZXMgbWVtY21wKGEsIGIsIG4pID09IDAKKy8vCisvLyBzdHJpbmdzOjoqX2lubGluZWQoKSByb3V0aW5lcyBhcmUgaW5saW5lIHZlcnNpb25zIG9mIHRoZQorLy8gcm91dGluZXMgZXhwb3J0ZWQgYnkgdGhpcyBtb2R1bGUuICBTb21ldGltZXMgdXNpbmcgdGhlIGlubGluZWQKKy8vIHZlcnNpb25zIGlzIGZhc3Rlci4gIE1lYXN1cmUgYmVmb3JlIHVzaW5nIHRoZSBpbmxpbmVkIHZlcnNpb25zLgorLy8KKy8vIFBlcmZvcm1hbmNlIG1lYXN1cmVtZW50OgorLy8gICBzdHJpbmdzOjpmYXN0bWVtY21wX2lubGluZWQKKy8vICAgICBBbmFseXNpczogbWVtY21wLCBmYXN0bWVtY21wX2lubGluZWQsIGZhc3RtZW1jbXAKKy8vICAgICAyMDEyLTAxLTMwCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX0ZBU1RNRU1fSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX0ZBU1RNRU1fSF8KKworI2luY2x1ZGUgPHN0ZGRlZi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFJldHVybiB0cnVlIGlmIHRoZSBuIGJ5dGVzIGF0IGEgZXF1YWwgdGhlIG4gYnl0ZXMgYXQgYi4KKy8vIFRoZSByZWdpb25zIGFyZSBhbGxvd2VkIHRvIG92ZXJsYXAuCisvLworLy8gVGhlIHBlcmZvcm1hbmNlIGlzIHNpbWlsYXIgdG8gdGhlIHBlcmZvcm1hbmNlIG1lbWNtcCgpLCBidXQgZmFzdGVyIGZvcgorLy8gbW9kZXJhdGVseS1zaXplZCBpbnB1dHMsIG9yIGlucHV0cyB0aGF0IHNoYXJlIGEgY29tbW9uIHByZWZpeCBhbmQgZGlmZmVyCisvLyBzb21ld2hlcmUgaW4gdGhlaXIgbGFzdCA4IGJ5dGVzLiBGdXJ0aGVyIG9wdGltaXphdGlvbnMgY2FuIGJlIGFkZGVkIGxhdGVyCisvLyBpZiBpdCBtYWtlcyBzZW5zZSB0byBkbyBzby46dworaW5saW5lIGJvb2wgbWVtZXEoY29uc3QgY2hhciogYSwgY29uc3QgY2hhciogYiwgc2l6ZV90IG4pIHsKKyAgc2l6ZV90IG5fcm91bmRlZF9kb3duID0gbiAmIH5zdGF0aWNfY2FzdDxzaXplX3Q+KDcpOworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0Uobl9yb3VuZGVkX2Rvd24gPT0gMCkpIHsgIC8vIG4gPD0gNworICAgIHJldHVybiBtZW1jbXAoYSwgYiwgbikgPT0gMDsKKyAgfQorICAvLyBuID49IDgKKyAgdWludDY0IHUgPSBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChhKSBeIEdPT0dMRV9VTkFMSUdORURfTE9BRDY0KGIpOworICB1aW50NjQgdiA9IEdPT0dMRV9VTkFMSUdORURfTE9BRDY0KGEgKyBuIC0gOCkgXiBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChiICsgbiAtIDgpOworICBpZiAoKHUgfCB2KSAhPSAwKSB7ICAvLyBUaGUgZmlyc3Qgb3IgbGFzdCA4IGJ5dGVzIGRpZmZlci4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgYSArPSA4OworICBiICs9IDg7CisgIG4gPSBuX3JvdW5kZWRfZG93biAtIDg7CisgIGlmIChuID4gMTI4KSB7CisgICAgLy8gQXMgb2YgMjAxMiwgbWVtY21wIG9uIHg4Ni02NCB1c2VzIGEgYmlnIHVucm9sbGVkIGxvb3Agd2l0aCBTU0UyCisgICAgLy8gaW5zdHJ1Y3Rpb25zLCBhbmQgd2hpbGUgd2UgY291bGQgdHJ5IHRvIGRvIHNvbWV0aGluZyBmYXN0ZXIsIGl0CisgICAgLy8gZG9lc24ndCBzZWVtIHdvcnRoIHB1cnN1aW5nLgorICAgIHJldHVybiBtZW1jbXAoYSwgYiwgbikgPT0gMDsKKyAgfQorICBmb3IgKDsgbiA+PSAxNjsgbiAtPSAxNikgeworICAgIHVpbnQ2NCB4ID0gR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYSkgXiBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChiKTsKKyAgICB1aW50NjQgeSA9IEdPT0dMRV9VTkFMSUdORURfTE9BRDY0KGEgKyA4KSBeIEdPT0dMRV9VTkFMSUdORURfTE9BRDY0KGIgKyA4KTsKKyAgICBpZiAoKHggfCB5KSAhPSAwKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGEgKz0gMTY7CisgICAgYiArPSAxNjsKKyAgfQorICAvLyBuIG11c3QgYmUgMCBvciA4IG5vdyBiZWNhdXNlIGl0IHdhcyBhIG11bHRpcGxlIG9mIDggYXQgdGhlIHRvcCBvZiB0aGUgbG9vcC4KKyAgcmV0dXJuIG4gPT0gMCB8fCBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChhKSA9PSBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChiKTsKK30KKworaW5saW5lIGludCBmYXN0bWVtY21wX2lubGluZWQoY29uc3QgY2hhciAqYSwgY29uc3QgY2hhciAqYiwgc2l6ZV90IG4pIHsKKyAgaWYgKG4gPj0gNjQpIHsKKyAgICByZXR1cm4gbWVtY21wKGEsIGIsIG4pOworICB9CisgIGNvbnN0IGNoYXIqIGFfbGltaXQgPSBhICsgbjsKKyAgd2hpbGUgKGEgKyBzaXplb2YodWludDY0KSA8PSBhX2xpbWl0ICYmCisgICAgICAgICBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChhKSA9PSBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChiKSkgeworICAgIGEgKz0gc2l6ZW9mKHVpbnQ2NCk7CisgICAgYiArPSBzaXplb2YodWludDY0KTsKKyAgfQorICBpZiAoYSArIHNpemVvZih1aW50MzIpIDw9IGFfbGltaXQgJiYKKyAgICAgIEdPT0dMRV9VTkFMSUdORURfTE9BRDMyKGEpID09IEdPT0dMRV9VTkFMSUdORURfTE9BRDMyKGIpKSB7CisgICAgYSArPSBzaXplb2YodWludDMyKTsKKyAgICBiICs9IHNpemVvZih1aW50MzIpOworICB9CisgIHdoaWxlIChhIDwgYV9saW1pdCkgeworICAgIGludCBkID0gc3RhdGljX2Nhc3Q8dWludDMyPigqYSsrKSAtIHN0YXRpY19jYXN0PHVpbnQzMj4oKmIrKyk7CisgICAgaWYgKGQpIHJldHVybiBkOworICB9CisgIHJldHVybiAwOworfQorCisvLyBUaGUgc3RhbmRhcmQgbWVtY3B5IG9wZXJhdGlvbiBpcyBzbG93IGZvciB2YXJpYWJsZSBzbWFsbCBzaXplcy4KKy8vIFRoaXMgaW1wbGVtZW50YXRpb24gaW5saW5lcyB0aGUgb3B0aW1hbCByZWFsaXphdGlvbiBmb3Igc2l6ZXMgMSB0byAxNi4KKy8vIFRvIGF2b2lkIGNvZGUgYmxvYXQgZG9uJ3QgdXNlIGl0IGluIGNhc2Ugb2Ygbm90IHBlcmZvcm1hbmNlLWNyaXRpY2FsIHNwb3RzLAorLy8gbm9yIHdoZW4geW91IGRvbid0IGV4cGVjdCB2ZXJ5IGZyZXF1ZW50IHZhbHVlcyBvZiBzaXplIDw9IDE2LgoraW5saW5lIHZvaWQgbWVtY3B5X2lubGluZWQoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBzaXplKSB7CisgIC8vIENvbXBpbGVyIGlubGluZXMgY29kZSB3aXRoIG1pbmltYWwgYW1vdW50IG9mIGRhdGEgbW92ZW1lbnQgd2hlbiB0aGlyZAorICAvLyBwYXJhbWV0ZXIgb2YgbWVtY3B5IGlzIGEgY29uc3RhbnQuCisgIHN3aXRjaCAoc2l6ZSkgeworICAgIGNhc2UgIDE6IG1lbWNweShkc3QsIHNyYywgMSk7IGJyZWFrOworICAgIGNhc2UgIDI6IG1lbWNweShkc3QsIHNyYywgMik7IGJyZWFrOworICAgIGNhc2UgIDM6IG1lbWNweShkc3QsIHNyYywgMyk7IGJyZWFrOworICAgIGNhc2UgIDQ6IG1lbWNweShkc3QsIHNyYywgNCk7IGJyZWFrOworICAgIGNhc2UgIDU6IG1lbWNweShkc3QsIHNyYywgNSk7IGJyZWFrOworICAgIGNhc2UgIDY6IG1lbWNweShkc3QsIHNyYywgNik7IGJyZWFrOworICAgIGNhc2UgIDc6IG1lbWNweShkc3QsIHNyYywgNyk7IGJyZWFrOworICAgIGNhc2UgIDg6IG1lbWNweShkc3QsIHNyYywgOCk7IGJyZWFrOworICAgIGNhc2UgIDk6IG1lbWNweShkc3QsIHNyYywgOSk7IGJyZWFrOworICAgIGNhc2UgMTA6IG1lbWNweShkc3QsIHNyYywgMTApOyBicmVhazsKKyAgICBjYXNlIDExOiBtZW1jcHkoZHN0LCBzcmMsIDExKTsgYnJlYWs7CisgICAgY2FzZSAxMjogbWVtY3B5KGRzdCwgc3JjLCAxMik7IGJyZWFrOworICAgIGNhc2UgMTM6IG1lbWNweShkc3QsIHNyYywgMTMpOyBicmVhazsKKyAgICBjYXNlIDE0OiBtZW1jcHkoZHN0LCBzcmMsIDE0KTsgYnJlYWs7CisgICAgY2FzZSAxNTogbWVtY3B5KGRzdCwgc3JjLCAxNSk7IGJyZWFrOworICAgIGNhc2UgMTY6IG1lbWNweShkc3QsIHNyYywgMTYpOyBicmVhazsKKyAgICBkZWZhdWx0OiBtZW1jcHkoZHN0LCBzcmMsIHNpemUpOyBicmVhazsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19GQVNUTUVNX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjgyZDUwNTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaApAQCAtMCwwICsxLDI0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vCisvLyBEZWFscyB3aXRoIHRoZSBmYWN0IHRoYXQgaGFzaF9tYXAgaXMgbm90IGRlZmluZWQgZXZlcnl3aGVyZS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfSEFTSF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX0hBU0hfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BiY29uZmlnLmg+CisKKyNpZiBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9IQVZFX0hBU0hfTUFQKSAmJiBcCisgICAgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfSEFWRV9IQVNIX1NFVCkKKyNpbmNsdWRlIEdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9ICisjaW5jbHVkZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9TRVRfSAorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01JU1NJTkdfSEFTSAorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzZXQ+CisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX01JU1NJTkdfSEFTSAorCisvLyBUaGlzIHN5c3RlbSBkb2Vzbid0IGhhdmUgaGFzaF9tYXAgb3IgaGFzaF9zZXQuICBFbXVsYXRlIHRoZW0gdXNpbmcgbWFwIGFuZAorLy8gc2V0LgorCisvLyBNYWtlIGhhc2g8VD4gYmUgdGhlIHNhbWUgYXMgbGVzczxUPi4gIE5vdGUgdGhhdCBldmVyeXdoZXJlIHdoZXJlIGN1c3RvbQorLy8gaGFzaCBmdW5jdGlvbnMgYXJlIGRlZmluZWQgaW4gdGhlIHByb3RvYnVmIGNvZGUsIHRoZXkgYXJlIGFsc28gZGVmaW5lZCBzdWNoCisvLyB0aGF0IHRoZXkgY2FuIGJlIHVzZWQgYXMgImxlc3MiIGZ1bmN0aW9ucywgd2hpY2ggaXMgcmVxdWlyZWQgYnkgTVNWQyBhbnl3YXkuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5Pgorc3RydWN0IGhhc2ggeworICAvLyBEdW1teSwganVzdCB0byBtYWtlIGRlcml2YXRpdmUgaGFzaCBmdW5jdGlvbnMgY29tcGlsZS4KKyAgaW50IG9wZXJhdG9yKCkoY29uc3QgS2V5JiBrZXkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2hvdWxkIG5ldmVyIGJlIGNhbGxlZC4iOworICAgIHJldHVybiAwOworICB9CisKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBLZXkmIGEsIGNvbnN0IEtleSYgYikgY29uc3QgeworICAgIHJldHVybiBhIDwgYjsKKyAgfQorfTsKKworLy8gTWFrZSBzdXJlIGNoYXIqIGlzIGNvbXBhcmVkIGJ5IHZhbHVlLgordGVtcGxhdGUgPD4KK3N0cnVjdCBoYXNoPGNvbnN0IGNoYXIqPiB7CisgIC8vIER1bW15LCBqdXN0IHRvIG1ha2UgZGVyaXZhdGl2ZSBoYXNoIGZ1bmN0aW9ucyBjb21waWxlLgorICBpbnQgb3BlcmF0b3IoKShjb25zdCBjaGFyKiBrZXkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2hvdWxkIG5ldmVyIGJlIGNhbGxlZC4iOworICAgIHJldHVybiAwOworICB9CisKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBjaGFyKiBhLCBjb25zdCBjaGFyKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIHN0cmNtcChhLCBiKSA8IDA7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIERhdGEsCisgICAgICAgICAgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBBbGxvYyA9IHN0ZDo6YWxsb2NhdG9yPCBzdGQ6OnBhaXI8Y29uc3QgS2V5LCBEYXRhPiA+ID4KK2NsYXNzIGhhc2hfbWFwIDogcHVibGljIHN0ZDo6bWFwPEtleSwgRGF0YSwgSGFzaEZjbiwgRXF1YWxLZXksIEFsbG9jPiB7CisgcHVibGljOgorICBoYXNoX21hcChpbnQgPSAwLCBjb25zdCBIYXNoRmNuJiA9IEhhc2hGY24oKSwgY29uc3QgRXF1YWxLZXkmID0gRXF1YWxLZXkoKSwKKyAgICAgICAgICAgY29uc3QgQWxsb2MmID0gQWxsb2MoKSkge30KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksCisgICAgICAgICAgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiA+CitjbGFzcyBoYXNoX3NldCA6IHB1YmxpYyBzdGQ6OnNldDxLZXksIEhhc2hGY24+IHsKKyBwdWJsaWM6CisgIGhhc2hfc2V0KGludCA9IDApIHt9Cit9OworCisjZWxpZiBkZWZpbmVkKF9NU0NfVkVSKSAmJiAhZGVmaW5lZChfU1RMUE9SVF9WRVJTSU9OKQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5Pgorc3RydWN0IGhhc2ggOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpoYXNoX2NvbXBhcmU8S2V5PiB7Cit9OworCisvLyBNU1ZDJ3MgaGFzaF9jb21wYXJlPGNvbnN0IGNoYXIqPiBoYXNoZXMgYmFzZWQgb24gdGhlIHN0cmluZyBjb250ZW50cyBidXQKKy8vIGNvbXBhcmVzIGJhc2VkIG9uIHRoZSBzdHJpbmcgcG9pbnRlci4gIFdURj8KK2NsYXNzIENzdHJpbmdMZXNzIHsKKyBwdWJsaWM6CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgY2hhciogYSwgY29uc3QgY2hhciogYikgY29uc3QgeworICAgIHJldHVybiBzdHJjbXAoYSwgYikgPCAwOworICB9Cit9OworCit0ZW1wbGF0ZSA8Pgorc3RydWN0IGhhc2g8Y29uc3QgY2hhcio+CisgICAgOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpoYXNoX2NvbXBhcmU8CisgICAgICAgIGNvbnN0IGNoYXIqLCBDc3RyaW5nTGVzcz4ge307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIERhdGEsCisgICAgICAgICAgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBBbGxvYyA9IHN0ZDo6YWxsb2NhdG9yPCBzdGQ6OnBhaXI8Y29uc3QgS2V5LCBEYXRhPiA+ID4KK2NsYXNzIGhhc2hfbWFwCisgICAgOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1M8CisgICAgICAgICAgS2V5LCBEYXRhLCBIYXNoRmNuLCBFcXVhbEtleSwgQWxsb2M+IHsKKyBwdWJsaWM6CisgIGhhc2hfbWFwKGludCA9IDAsIGNvbnN0IEhhc2hGY24mID0gSGFzaEZjbigpLCBjb25zdCBFcXVhbEtleSYgPSBFcXVhbEtleSgpLAorICAgICAgICAgICBjb25zdCBBbGxvYyYgPSBBbGxvYygpKSB7fQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiA+CitjbGFzcyBoYXNoX3NldAorICAgIDogcHVibGljIEdPT0dMRV9QUk9UT0JVRl9IQVNIX05BTUVTUEFDRTo6R09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTPAorICAgICAgICAgIEtleSwgSGFzaEZjbiwgRXF1YWxLZXk+IHsKKyBwdWJsaWM6CisgIGhhc2hfc2V0KGludCA9IDApIHt9Cit9OworCisjZWxzZQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5Pgorc3RydWN0IGhhc2ggOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpoYXNoPEtleT4geworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleT4KK3N0cnVjdCBoYXNoPGNvbnN0IEtleSo+IHsKKyAgaW5saW5lIHNpemVfdCBvcGVyYXRvcigpKGNvbnN0IEtleSoga2V5KSBjb25zdCB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8c2l6ZV90PihrZXkpOworICB9Cit9OworCisvLyBVbmxpa2UgdGhlIG9sZCBTR0kgdmVyc2lvbiwgdGhlIFRSMSAiaGFzaCIgZG9lcyBub3Qgc3BlY2lhbC1jYXNlIGNoYXIqLiAgU28sCisvLyB3ZSBnbyBhaGVhZCBhbmQgcHJvdmlkZSBvdXIgb3duIGltcGxlbWVudGF0aW9uLgordGVtcGxhdGUgPD4KK3N0cnVjdCBoYXNoPGNvbnN0IGNoYXIqPiB7CisgIGlubGluZSBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBjaGFyKiBzdHIpIGNvbnN0IHsKKyAgICBzaXplX3QgcmVzdWx0ID0gMDsKKyAgICBmb3IgKDsgKnN0ciAhPSAnXDAnOyBzdHIrKykgeworICAgICAgcmVzdWx0ID0gNSAqIHJlc3VsdCArICpzdHI7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIERhdGEsCisgICAgICAgICAgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBBbGxvYyA9IHN0ZDo6YWxsb2NhdG9yPCBzdGQ6OnBhaXI8Y29uc3QgS2V5LCBEYXRhPiA+ID4KK2NsYXNzIGhhc2hfbWFwCisgICAgOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1M8CisgICAgICAgICAgS2V5LCBEYXRhLCBIYXNoRmNuLCBFcXVhbEtleSwgQWxsb2M+IHsKKyBwdWJsaWM6CisgIGhhc2hfbWFwKGludCA9IDAsIGNvbnN0IEhhc2hGY24mID0gSGFzaEZjbigpLCBjb25zdCBFcXVhbEtleSYgPSBFcXVhbEtleSgpLAorICAgICAgICAgICBjb25zdCBBbGxvYyYgPSBBbGxvYygpKSB7fQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiA+CitjbGFzcyBoYXNoX3NldAorICAgIDogcHVibGljIEdPT0dMRV9QUk9UT0JVRl9IQVNIX05BTUVTUEFDRTo6R09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTPAorICAgICAgICAgIEtleSwgSGFzaEZjbiwgRXF1YWxLZXk+IHsKKyBwdWJsaWM6CisgIGhhc2hfc2V0KGludCA9IDApIHt9Cit9OworCisjdW5kZWYgR09PR0xFX1BST1RPQlVGX01JU1NJTkdfSEFTSAorI2VuZGlmICAvLyAhR09PR0xFX1BST1RPQlVGX01JU1NJTkdfSEFTSAorCit0ZW1wbGF0ZSA8Pgorc3RydWN0IGhhc2g8c3RyaW5nPiB7CisgIGlubGluZSBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICAgIHJldHVybiBoYXNoPGNvbnN0IGNoYXIqPigpKGtleS5jX3N0cigpKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCBzaXplX3QgYnVja2V0X3NpemUgPSA0OworICBzdGF0aWMgY29uc3Qgc2l6ZV90IG1pbl9idWNrZXRzID0gODsKKyAgaW5saW5lIHNpemVfdCBvcGVyYXRvcigpKGNvbnN0IHN0cmluZyYgYSwgY29uc3Qgc3RyaW5nJiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEgPCBiOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRmlyc3QsIHR5cGVuYW1lIFNlY29uZD4KK3N0cnVjdCBoYXNoPHBhaXI8Rmlyc3QsIFNlY29uZD4gPiB7CisgIGlubGluZSBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBwYWlyPEZpcnN0LCBTZWNvbmQ+JiBrZXkpIGNvbnN0IHsKKyAgICBzaXplX3QgZmlyc3RfaGFzaCA9IGhhc2g8Rmlyc3Q+KCkoa2V5LmZpcnN0KTsKKyAgICBzaXplX3Qgc2Vjb25kX2hhc2ggPSBoYXNoPFNlY29uZD4oKShrZXkuc2Vjb25kKTsKKworICAgIC8vIEZJWE1FKGtlbnRvbik6ICBXaGF0IGlzIHRoZSBiZXN0IHdheSB0byBjb21wdXRlIHRoaXMgaGFzaD8gIEkgaGF2ZQorICAgIC8vIG5vIGlkZWEhICBUaGlzIHNlZW1zIGEgYml0IGJldHRlciB0aGFuIGFuIFhPUi4KKyAgICByZXR1cm4gZmlyc3RfaGFzaCAqICgoMSA8PCAxNikgLSAxKSArIHNlY29uZF9oYXNoOworICB9CisKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBidWNrZXRfc2l6ZSA9IDQ7CisgIHN0YXRpYyBjb25zdCBzaXplX3QgbWluX2J1Y2tldHMgPSA4OworICBpbmxpbmUgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgcGFpcjxGaXJzdCwgU2Vjb25kPiYgYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhaXI8Rmlyc3QsIFNlY29uZD4mIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYSA8IGI7CisgIH0KK307CisKKy8vIFVzZWQgYnkgR0NDL1NHSSBTVEwgb25seS4gIChXaHkgaXNuJ3QgdGhpcyBwcm92aWRlZCBieSB0aGUgc3RhbmRhcmQKKy8vIGxpYnJhcnk/ICA6KCApCitzdHJ1Y3Qgc3RyZXEgeworICBpbmxpbmUgYm9vbCBvcGVyYXRvcigpKGNvbnN0IGNoYXIqIGEsIGNvbnN0IGNoYXIqIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RyY21wKGEsIGIpID09IDA7CisgIH0KK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19IQVNIX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjY2NiYmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmgKQEAgLTAsMCArMSw3NjkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBmcm9tIGdvb2dsZTMvdXRpbC9ndGwvbWFwX3V0aWwuaAorLy8gQXV0aG9yOiBBbnRvbiBDYXJ2ZXIKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTUFQX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19NQVBfVVRJTF9IX18KKworI2luY2x1ZGUgPHN0ZGRlZi5oPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKy8vIExvY2FsIGltcGxlbWVudGF0aW9uIG9mIFJlbW92ZUNvbnN0IHRvIGF2b2lkIGluY2x1ZGluZyBiYXNlL3R5cGVfdHJhaXRzLmguCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IFJlbW92ZUNvbnN0IHsgdHlwZWRlZiBUIHR5cGU7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IFJlbW92ZUNvbnN0PGNvbnN0IFQ+IDogUmVtb3ZlQ29uc3Q8VD4ge307Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8KKy8vIEZpbmQqKCkKKy8vCisKKy8vIFJldHVybnMgYSBjb25zdCByZWZlcmVuY2UgdG8gdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5IGlmIGl0CisvLyBleGlzdHMuIENyYXNoZXMgb3RoZXJ3aXNlLgorLy8KKy8vIFRoaXMgaXMgaW50ZW5kZWQgYXMgYSByZXBsYWNlbWVudCBmb3Igb3BlcmF0b3JbXSBhcyBhbiBydmFsdWUgKGZvciByZWFkaW5nKQorLy8gd2hlbiB0aGUga2V5IGlzIGd1YXJhbnRlZWQgdG8gZXhpc3QuCisvLworLy8gb3BlcmF0b3JbXSBmb3IgbG9va3VwIGlzIGRpc2NvdXJhZ2VkIGZvciBzZXZlcmFsIHJlYXNvbnM6CisvLyAgKiBJdCBoYXMgYSBzaWRlLWVmZmVjdCBvZiBpbnNlcnRpbmcgbWlzc2luZyBrZXlzCisvLyAgKiBJdCBpcyBub3QgdGhyZWFkLXNhZmUgKGV2ZW4gd2hlbiBpdCBpcyBub3QgaW5zZXJ0aW5nLCBpdCBjYW4gc3RpbGwKKy8vICAgICAgY2hvb3NlIHRvIHJlc2l6ZSB0aGUgdW5kZXJseWluZyBzdG9yYWdlKQorLy8gICogSXQgaW52YWxpZGF0ZXMgaXRlcmF0b3JzICh3aGVuIGl0IGNob29zZXMgdG8gcmVzaXplKQorLy8gICogSXQgZGVmYXVsdCBjb25zdHJ1Y3RzIGEgdmFsdWUgb2JqZWN0IGV2ZW4gaWYgaXQgZG9lc24ndCBuZWVkIHRvCisvLworLy8gVGhpcyB2ZXJzaW9uIGFzc3VtZXMgdGhlIGtleSBpcyBwcmludGFibGUsIGFuZCBpbmNsdWRlcyBpdCBpbiB0aGUgZmF0YWwgbG9nCisvLyBtZXNzYWdlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0ZpbmRPckRpZShjb25zdCBDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLAorICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjpjb25zdF9pdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBHT09HTEVfQ0hFQ0soaXQgIT0gY29sbGVjdGlvbi5lbmQoKSkgPDwgIk1hcCBrZXkgbm90IGZvdW5kOiAiIDw8IGtleTsKKyAgcmV0dXJuIGl0LT5zZWNvbmQ7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUsIGJ1dCByZXR1cm5zIGEgbm9uLWNvbnN0IHJlZmVyZW5jZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmCitGaW5kT3JEaWUoQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwgIC8vIE5PTElOVAorICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBHT09HTEVfQ0hFQ0soaXQgIT0gY29sbGVjdGlvbi5lbmQoKSkgPDwgIk1hcCBrZXkgbm90IGZvdW5kOiAiIDw8IGtleTsKKyAgcmV0dXJuIGl0LT5zZWNvbmQ7Cit9CisKKy8vIFNhbWUgYXMgRmluZE9yRGllIGFib3ZlLCBidXQgZG9lc24ndCBsb2cgdGhlIGtleSBvbiBmYWlsdXJlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0ZpbmRPckRpZU5vUHJpbnQoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIEdPT0dMRV9DSEVDSyhpdCAhPSBjb2xsZWN0aW9uLmVuZCgpKSA8PCAiTWFwIGtleSBub3QgZm91bmQiOworICByZXR1cm4gaXQtPnNlY29uZDsKK30KKworLy8gU2FtZSBhcyBhYm92ZSwgYnV0IHJldHVybnMgYSBub24tY29uc3QgcmVmZXJlbmNlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0ZpbmRPckRpZU5vUHJpbnQoQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwgIC8vIE5PTElOVAorICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgR09PR0xFX0NIRUNLKGl0ICE9IGNvbGxlY3Rpb24uZW5kKCkpIDw8ICJNYXAga2V5IG5vdCBmb3VuZCI7CisgIHJldHVybiBpdC0+c2Vjb25kOworfQorCisvLyBSZXR1cm5zIGEgY29uc3QgcmVmZXJlbmNlIHRvIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGtleSBpZiBpdAorLy8gZXhpc3RzLCBvdGhlcndpc2UgcmV0dXJucyBhIGNvbnN0IHJlZmVyZW5jZSB0byB0aGUgcHJvdmlkZWQgZGVmYXVsdCB2YWx1ZS4KKy8vCisvLyBXQVJOSU5HOiBJZiBhIHRlbXBvcmFyeSBvYmplY3QgaXMgcGFzc2VkIGFzIHRoZSBkZWZhdWx0ICJ2YWx1ZSwiCisvLyB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoYXQgdGVtcG9yYXJ5IG9iamVjdCwKKy8vIHdoaWNoIHdpbGwgYmUgZGVzdHJveWVkIGF0IHRoZSBlbmQgb2YgdGhlIHN0YXRlbWVudC4gQSBjb21tb24KKy8vIGV4YW1wbGU6IGlmIHlvdSBoYXZlIGEgbWFwIHdpdGggc3RyaW5nIHZhbHVlcywgYW5kIHlvdSBwYXNzIGEgY2hhcioKKy8vIGFzIHRoZSBkZWZhdWx0ICJ2YWx1ZSwiIGVpdGhlciB1c2UgdGhlIHJldHVybmVkIHZhbHVlIGltbWVkaWF0ZWx5CisvLyBvciBzdG9yZSBpdCBpbiBhIHN0cmluZyAobm90IHN0cmluZyYpLgorLy8gRGV0YWlsczogaHR0cDovL2dvL2ZpbmR3aXRoZGVmYXVsdAordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0ZpbmRXaXRoRGVmYXVsdChjb25zdCBDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgdmFsdWUpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgaWYgKGl0ID09IGNvbGxlY3Rpb24uZW5kKCkpIHsKKyAgICByZXR1cm4gdmFsdWU7CisgIH0KKyAgcmV0dXJuIGl0LT5zZWNvbmQ7Cit9CisKKy8vIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBjb25zdCB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGtleSBpZiBpdAorLy8gZXhpc3RzLCBvciBOVUxMIG90aGVyd2lzZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgorY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUqCitGaW5kT3JOdWxsKGNvbnN0IENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sCisgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjpjb25zdF9pdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBpZiAoaXQgPT0gY29sbGVjdGlvbi5lbmQoKSkgeworICAgIHJldHVybiAwOworICB9CisgIHJldHVybiAmaXQtPnNlY29uZDsKK30KKworLy8gU2FtZSBhcyBhYm92ZSBidXQgcmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIG5vbi1jb25zdCB2YWx1ZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUqCitGaW5kT3JOdWxsKENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sICAvLyBOT0xJTlQKKyAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLmVuZCgpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuICZpdC0+c2Vjb25kOworfQorCisvLyBSZXR1cm5zIHRoZSBwb2ludGVyIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5LiBJZiBub25lIGlzIGZvdW5kLAorLy8gTlVMTCBpcyByZXR1cm5lZC4gVGhlIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgd2l0aCBhIG1hcCBvZiBrZXlzIHRvCisvLyBwb2ludGVycy4KKy8vCisvLyBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gYSBtaXNzaW5nIGtleSBhbmQgYSBrZXkgbWFwcGVkCisvLyB0byBhIE5VTEwgdmFsdWUuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlCitGaW5kUHRyT3JOdWxsKGNvbnN0IENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjpjb25zdF9pdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBpZiAoaXQgPT0gY29sbGVjdGlvbi5lbmQoKSkgeworICAgIHJldHVybiB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSgpOworICB9CisgIHJldHVybiBpdC0+c2Vjb25kOworfQorCisvLyBTYW1lIGFzIGFib3ZlLCBleGNlcHQgdGFrZXMgbm9uLWNvbnN0IHJlZmVyZW5jZSB0byBjb2xsZWN0aW9uLgorLy8KKy8vIFRoaXMgZnVuY3Rpb24gaXMgbmVlZGVkIGZvciBjb250YWluZXJzIHRoYXQgcHJvcGFnYXRlIGNvbnN0bmVzcyB0byB0aGUKKy8vIHBvaW50ZWUsIHN1Y2ggYXMgYm9vc3Q6OnB0cl9tYXAuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlCitGaW5kUHRyT3JOdWxsKENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sICAvLyBOT0xJTlQKKyAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLmVuZCgpKSB7CisgICAgcmV0dXJuIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlKCk7CisgIH0KKyAgcmV0dXJuIGl0LT5zZWNvbmQ7Cit9CisKKy8vIEZpbmRzIHRoZSBwb2ludGVyIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5IGluIGEgbWFwIHdob3NlIHZhbHVlcworLy8gYXJlIGxpbmtlZF9wdHJzLiBSZXR1cm5zIE5VTEwgaWYga2V5IGlzIG5vdCBmb3VuZC4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU6OmVsZW1lbnRfdHlwZSoKK0ZpbmRMaW5rZWRQdHJPck51bGwoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLmVuZCgpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgLy8gU2luY2UgbGlua2VkX3B0cjo6Z2V0KCkgaXMgYSBjb25zdCBtZW1iZXIgcmV0dXJuaW5nIGEgbm9uIGNvbnN0LAorICAvLyB3ZSBkbyBub3QgbmVlZCBhIHZlcnNpb24gb2YgdGhpcyBmdW5jdGlvbiB0YWtpbmcgYSBub24gY29uc3QgY29sbGVjdGlvbi4KKyAgcmV0dXJuIGl0LT5zZWNvbmQuZ2V0KCk7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUsIGJ1dCBkaWVzIGlmIHRoZSBrZXkgaXMgbm90IGZvdW5kLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZTo6ZWxlbWVudF90eXBlJgorRmluZExpbmtlZFB0ck9yRGllKGNvbnN0IENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIENIRUNLKGl0ICE9IGNvbGxlY3Rpb24uZW5kKCkpIDw8ICAia2V5IG5vdCBmb3VuZDogIiA8PCBrZXk7CisgIC8vIFNpbmNlIGxpbmtlZF9wdHI6Om9wZXJhdG9yKigpIGlzIGEgY29uc3QgbWVtYmVyIHJldHVybmluZyBhIG5vbiBjb25zdCwKKyAgLy8gd2UgZG8gbm90IG5lZWQgYSB2ZXJzaW9uIG9mIHRoaXMgZnVuY3Rpb24gdGFraW5nIGEgbm9uIGNvbnN0IGNvbGxlY3Rpb24uCisgIHJldHVybiAqaXQtPnNlY29uZDsKK30KKworLy8gRmluZHMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5IGFuZCBjb3BpZXMgaXQgdG8gKnZhbHVlIChpZiBub3QKKy8vIE5VTEwpLiBSZXR1cm5zIGZhbHNlIGlmIHRoZSBrZXkgd2FzIG5vdCBmb3VuZCwgdHJ1ZSBvdGhlcndpc2UuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbiwgY2xhc3MgS2V5LCBjbGFzcyBWYWx1ZT4KK2Jvb2wgRmluZENvcHkoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgY29uc3QgS2V5JiBrZXksCisgICAgICAgICAgICAgIFZhbHVlKiBjb25zdCB2YWx1ZSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjpjb25zdF9pdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBpZiAoaXQgPT0gY29sbGVjdGlvbi5lbmQoKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAodmFsdWUpIHsKKyAgICAqdmFsdWUgPSBpdC0+c2Vjb25kOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLworLy8gQ29udGFpbnMqKCkKKy8vCisKKy8vIFJldHVybnMgdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGUgZ2l2ZW4gY29sbGVjdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4ga2V5LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24sIGNsYXNzIEtleT4KK2Jvb2wgQ29udGFpbnNLZXkoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwgY29uc3QgS2V5JiBrZXkpIHsKKyAgcmV0dXJuIGNvbGxlY3Rpb24uZmluZChrZXkpICE9IGNvbGxlY3Rpb24uZW5kKCk7Cit9CisKKy8vIFJldHVybnMgdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGUgZ2l2ZW4gY29sbGVjdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4ga2V5LXZhbHVlCisvLyBwYWlyLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24sIGNsYXNzIEtleSwgY2xhc3MgVmFsdWU+Citib29sIENvbnRhaW5zS2V5VmFsdWVQYWlyKGNvbnN0IENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEtleSYga2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBWYWx1ZSYgdmFsdWUpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBDb2xsZWN0aW9uOjpjb25zdF9pdGVyYXRvciBjb25zdF9pdGVyYXRvcjsKKyAgc3RkOjpwYWlyPGNvbnN0X2l0ZXJhdG9yLCBjb25zdF9pdGVyYXRvcj4gcmFuZ2UgPSBjb2xsZWN0aW9uLmVxdWFsX3JhbmdlKGtleSk7CisgIGZvciAoY29uc3RfaXRlcmF0b3IgaXQgPSByYW5nZS5maXJzdDsgaXQgIT0gcmFuZ2Uuc2Vjb25kOyArK2l0KSB7CisgICAgaWYgKGl0LT5zZWNvbmQgPT0gdmFsdWUpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vCisvLyBJbnNlcnQqKCkKKy8vCisKKy8vIEluc2VydHMgdGhlIGdpdmVuIGtleS12YWx1ZSBwYWlyIGludG8gdGhlIGNvbGxlY3Rpb24uIFJldHVybnMgdHJ1ZSBpZiBhbmQKKy8vIG9ubHkgaWYgdGhlIGtleSBmcm9tIHRoZSBnaXZlbiBwYWlyIGRpZG4ndCBwcmV2aW91c2x5IGV4aXN0LiBPdGhlcndpc2UsIHRoZQorLy8gdmFsdWUgaW4gdGhlIG1hcCBpcyByZXBsYWNlZCB3aXRoIHRoZSB2YWx1ZSBmcm9tIHRoZSBnaXZlbiBwYWlyLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citib29sIEluc2VydE9yVXBkYXRlKENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUmIHZ0KSB7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0gY29sbGVjdGlvbi0+aW5zZXJ0KHZ0KTsKKyAgaWYgKCFyZXQuc2Vjb25kKSB7CisgICAgLy8gdXBkYXRlCisgICAgcmV0LmZpcnN0LT5zZWNvbmQgPSB2dC5zZWNvbmQ7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBTYW1lIGFzIGFib3ZlLCBleGNlcHQgdGhhdCB0aGUga2V5IGFuZCB2YWx1ZSBhcmUgcGFzc2VkIHNlcGFyYXRlbHkuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2Jvb2wgSW5zZXJ0T3JVcGRhdGUoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgdmFsdWUpIHsKKyAgcmV0dXJuIEluc2VydE9yVXBkYXRlKAorICAgICAgY29sbGVjdGlvbiwgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIHZhbHVlKSk7Cit9CisKKy8vIEluc2VydHMvdXBkYXRlcyBhbGwgdGhlIGtleS12YWx1ZSBwYWlycyBmcm9tIHRoZSByYW5nZSBkZWZpbmVkIGJ5IHRoZQorLy8gaXRlcmF0b3JzICJmaXJzdCIgYW5kICJsYXN0IiBpbnRvIHRoZSBnaXZlbiBjb2xsZWN0aW9uLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24sIGNsYXNzIElucHV0SXRlcmF0b3I+Cit2b2lkIEluc2VydE9yVXBkYXRlTWFueShDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgSW5wdXRJdGVyYXRvciBmaXJzdCwgSW5wdXRJdGVyYXRvciBsYXN0KSB7CisgIGZvciAoOyBmaXJzdCAhPSBsYXN0OyArK2ZpcnN0KSB7CisgICAgSW5zZXJ0T3JVcGRhdGUoY29sbGVjdGlvbiwgKmZpcnN0KTsKKyAgfQorfQorCisvLyBDaGFuZ2UgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBhIHBhcnRpY3VsYXIga2V5IGluIGEgbWFwIG9yIGhhc2hfbWFwCisvLyBvZiB0aGUgZm9ybSBtYXA8S2V5LCBWYWx1ZSo+IHdoaWNoIG93bnMgdGhlIG9iamVjdHMgcG9pbnRlZCB0byBieSB0aGUKKy8vIHZhbHVlIHBvaW50ZXJzLiAgSWYgdGhlcmUgd2FzIGFuIGV4aXN0aW5nIHZhbHVlIGZvciB0aGUga2V5LCBpdCBpcyBkZWxldGVkLgorLy8gVHJ1ZSBpbmRpY2F0ZXMgYW4gaW5zZXJ0IHRvb2sgcGxhY2UsIGZhbHNlIGluZGljYXRlcyBhbiB1cGRhdGUgKyBkZWxldGUuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2Jvb2wgSW5zZXJ0QW5kRGVsZXRlRXhpc3RpbmcoCisgICAgQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXksCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmIHZhbHVlKSB7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgdmFsdWUpKTsKKyAgaWYgKCFyZXQuc2Vjb25kKSB7CisgICAgZGVsZXRlIHJldC5maXJzdC0+c2Vjb25kOworICAgIHJldC5maXJzdC0+c2Vjb25kID0gdmFsdWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBJbnNlcnRzIHRoZSBnaXZlbiBrZXkgYW5kIHZhbHVlIGludG8gdGhlIGdpdmVuIGNvbGxlY3Rpb24gaWYgYW5kIG9ubHkgaWYgdGhlCisvLyBnaXZlbiBrZXkgZGlkIE5PVCBhbHJlYWR5IGV4aXN0IGluIHRoZSBjb2xsZWN0aW9uLiBJZiB0aGUga2V5IHByZXZpb3VzbHkKKy8vIGV4aXN0ZWQgaW4gdGhlIGNvbGxlY3Rpb24sIHRoZSB2YWx1ZSBpcyBub3QgY2hhbmdlZC4gUmV0dXJucyB0cnVlIGlmIHRoZQorLy8ga2V5LXZhbHVlIHBhaXIgd2FzIGluc2VydGVkOyByZXR1cm5zIGZhbHNlIGlmIHRoZSBrZXkgd2FzIGFscmVhZHkgcHJlc2VudC4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgorYm9vbCBJbnNlcnRJZk5vdFByZXNlbnQoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUmIHZ0KSB7CisgIHJldHVybiBjb2xsZWN0aW9uLT5pbnNlcnQodnQpLnNlY29uZDsKK30KKworLy8gU2FtZSBhcyBhYm92ZSBleGNlcHQgdGhlIGtleSBhbmQgdmFsdWUgYXJlIHBhc3NlZCBzZXBhcmF0ZWx5LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citib29sIEluc2VydElmTm90UHJlc2VudCgKKyAgICBDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgdmFsdWUpIHsKKyAgcmV0dXJuIEluc2VydElmTm90UHJlc2VudCgKKyAgICAgIGNvbGxlY3Rpb24sIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoa2V5LCB2YWx1ZSkpOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGV4Y2VwdCBkaWVzIGlmIHRoZSBrZXkgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGNvbGxlY3Rpb24uCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3ZvaWQgSW5zZXJ0T3JEaWUoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZSYgdmFsdWUpIHsKKyAgQ0hFQ0soSW5zZXJ0SWZOb3RQcmVzZW50KGNvbGxlY3Rpb24sIHZhbHVlKSkgPDwgImR1cGxpY2F0ZSB2YWx1ZTogIiA8PCB2YWx1ZTsKK30KKworLy8gU2FtZSBhcyBhYm92ZSBleGNlcHQgZG9lc24ndCBsb2cgdGhlIHZhbHVlIG9uIGVycm9yLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit2b2lkIEluc2VydE9yRGllTm9QcmludChDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZSYgdmFsdWUpIHsKKyAgQ0hFQ0soSW5zZXJ0SWZOb3RQcmVzZW50KGNvbGxlY3Rpb24sIHZhbHVlKSkgPDwgImR1cGxpY2F0ZSB2YWx1ZS4iOworfQorCisvLyBJbnNlcnRzIHRoZSBrZXktdmFsdWUgcGFpciBpbnRvIHRoZSBjb2xsZWN0aW9uLiBEaWVzIGlmIGtleSB3YXMgYWxyZWFkeQorLy8gcHJlc2VudC4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordm9pZCBJbnNlcnRPckRpZShDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXksCisgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiBkYXRhKSB7CisgIEdPT0dMRV9DSEVDSyhJbnNlcnRJZk5vdFByZXNlbnQoY29sbGVjdGlvbiwga2V5LCBkYXRhKSkKKyAgICAgIDw8ICJkdXBsaWNhdGUga2V5OiAiIDw8IGtleTsKK30KKworLy8gU2FtZSBhcyBhYm92ZSBleGNlcHQgZG9lc24ndCBsb2cgdGhlIGtleSBvbiBlcnJvci4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordm9pZCBJbnNlcnRPckRpZU5vUHJpbnQoCisgICAgQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXksCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmIGRhdGEpIHsKKyAgR09PR0xFX0NIRUNLKEluc2VydElmTm90UHJlc2VudChjb2xsZWN0aW9uLCBrZXksIGRhdGEpKSA8PCAiZHVwbGljYXRlIGtleS4iOworfQorCisvLyBJbnNlcnRzIGEgbmV3IGtleSBhbmQgZGVmYXVsdC1pbml0aWFsaXplZCB2YWx1ZS4gRGllcyBpZiB0aGUga2V5IHdhcyBhbHJlYWR5CisvLyBwcmVzZW50LiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSB2YWx1ZS4gRXhhbXBsZSB1c2FnZToKKy8vCisvLyBtYXA8aW50LCBTb21lUHJvdG8+IG07CisvLyBTb21lUHJvdG8mIHByb3RvID0gSW5zZXJ0S2V5T3JEaWUoJm0sIDMpOworLy8gcHJvdG8uc2V0X2ZpZWxkKCJmb28iKTsKK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmIEluc2VydEtleU9yRGllKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZSB2YWx1ZV90eXBlOworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJlcyA9CisgICAgICBjb2xsZWN0aW9uLT5pbnNlcnQodmFsdWVfdHlwZShrZXksIHR5cGVuYW1lIHZhbHVlX3R5cGU6OnNlY29uZF90eXBlKCkpKTsKKyAgR09PR0xFX0NIRUNLKHJlcy5zZWNvbmQpIDw8ICJkdXBsaWNhdGUga2V5OiAiIDw8IGtleTsKKyAgcmV0dXJuIHJlcy5maXJzdC0+c2Vjb25kOworfQorCisvLworLy8gTG9va3VwKigpCisvLworCisvLyBMb29rcyB1cCBhIGdpdmVuIGtleSBhbmQgdmFsdWUgcGFpciBpbiBhIGNvbGxlY3Rpb24gYW5kIGluc2VydHMgdGhlIGtleS12YWx1ZQorLy8gcGFpciBpZiBpdCdzIG5vdCBhbHJlYWR5IHByZXNlbnQuIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHZhbHVlIGFzc29jaWF0ZWQKKy8vIHdpdGggdGhlIGtleS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmCitMb29rdXBPckluc2VydChDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZSYgdnQpIHsKKyAgcmV0dXJuIGNvbGxlY3Rpb24tPmluc2VydCh2dCkuZmlyc3QtPnNlY29uZDsKK30KKworLy8gU2FtZSBhcyBhYm92ZSBleGNlcHQgdGhlIGtleS12YWx1ZSBhcmUgcGFzc2VkIHNlcGFyYXRlbHkuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorTG9va3VwT3JJbnNlcnQoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiB2YWx1ZSkgeworICByZXR1cm4gTG9va3VwT3JJbnNlcnQoCisgICAgICBjb2xsZWN0aW9uLCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgdmFsdWUpKTsKK30KKworLy8gQ291bnRzIHRoZSBudW1iZXIgb2YgZXF1aXZhbGVudCBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gInNlcXVlbmNlIiwgYW5kIHN0b3JlcworLy8gdGhlIHJlc3VsdHMgaW4gImNvdW50X21hcCIgd2l0aCBlbGVtZW50IGFzIHRoZSBrZXkgYW5kIGNvdW50IGFzIHRoZSB2YWx1ZS4KKy8vCisvLyBFeGFtcGxlOgorLy8gICB2ZWN0b3I8c3RyaW5nPiB2ID0geyJhIiwgImIiLCAiYyIsICJhIiwgImIifTsKKy8vICAgbWFwPHN0cmluZywgaW50PiBtOworLy8gICBBZGRUb2tlbkNvdW50cyh2LCAxLCAmbSk7CisvLyAgIGFzc2VydChtWyJhIl0gPT0gMik7CisvLyAgIGFzc2VydChtWyJiIl0gPT0gMik7CisvLyAgIGFzc2VydChtWyJjIl0gPT0gMSk7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgU2VxdWVuY2UsIHR5cGVuYW1lIENvbGxlY3Rpb24+Cit2b2lkIEFkZFRva2VuQ291bnRzKAorICAgIGNvbnN0IFNlcXVlbmNlJiBzZXF1ZW5jZSwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgaW5jcmVtZW50LAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvdW50X21hcCkgeworICBmb3IgKHR5cGVuYW1lIFNlcXVlbmNlOjpjb25zdF9pdGVyYXRvciBpdCA9IHNlcXVlbmNlLmJlZ2luKCk7CisgICAgICAgaXQgIT0gc2VxdWVuY2UuZW5kKCk7ICsraXQpIHsKKyAgICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgdmFsdWUgPQorICAgICAgICBMb29rdXBPckluc2VydChjb3VudF9tYXAsICppdCwKKyAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUoKSk7CisgICAgdmFsdWUgKz0gaW5jcmVtZW50OworICB9Cit9CisKKy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBrZXkuIElmIG5vdCBmb3VuZCwgYSB2YWx1ZQorLy8gaXMgZGVmYXVsdCBjb25zdHJ1Y3RlZCBvbiB0aGUgaGVhcCBhbmQgYWRkZWQgdG8gdGhlIG1hcC4KKy8vCisvLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCBmb3IgY29udGFpbmVycyBvZiB0aGUgZm9ybSBtYXA8S2V5LCBWYWx1ZSo+LCB3aGVyZQorLy8gaW5zZXJ0aW5nIGEgbmV3IGtleSwgdmFsdWUgcGFpciBpbnZvbHZlcyBjb25zdHJ1Y3RpbmcgYSBuZXcgaGVhcC1hbGxvY2F0ZWQKKy8vIFZhbHVlLCBhbmQgc3RvcmluZyBhIHBvaW50ZXIgdG8gdGhhdCBpbiB0aGUgY29sbGVjdGlvbi4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmCitMb29rdXBPckluc2VydE5ldyhDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjppdGVyYXRvcl90cmFpdHM8CisgICAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU+Ojp2YWx1ZV90eXBlIEVsZW1lbnQ7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKAorICAgICAgICAgIGtleSwKKyAgICAgICAgICBzdGF0aWNfY2FzdDx0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZT4oTlVMTCkpKTsKKyAgaWYgKHJldC5zZWNvbmQpIHsKKyAgICByZXQuZmlyc3QtPnNlY29uZCA9IG5ldyBFbGVtZW50KCk7CisgIH0KKyAgcmV0dXJuIHJldC5maXJzdC0+c2Vjb25kOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGJ1dCBjb25zdHJ1Y3RzIHRoZSB2YWx1ZSB1c2luZyB0aGUgc2luZ2xlLWFyZ3VtZW50IGNvbnN0cnVjdG9yCisvLyBhbmQgdGhlIGdpdmVuICJhcmciLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24sIGNsYXNzIEFyZz4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorTG9va3VwT3JJbnNlcnROZXcoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZyYgYXJnKSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjppdGVyYXRvcl90cmFpdHM8CisgICAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU+Ojp2YWx1ZV90eXBlIEVsZW1lbnQ7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKAorICAgICAgICAgIGtleSwKKyAgICAgICAgICBzdGF0aWNfY2FzdDx0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZT4oTlVMTCkpKTsKKyAgaWYgKHJldC5zZWNvbmQpIHsKKyAgICByZXQuZmlyc3QtPnNlY29uZCA9IG5ldyBFbGVtZW50KGFyZyk7CisgIH0KKyAgcmV0dXJuIHJldC5maXJzdC0+c2Vjb25kOworfQorCisvLyBMb29rdXAgb2YgbGlua2VkL3NoYXJlZCBwb2ludGVycyBpcyB1c2VkIGluIHR3byBzY2VuYXJpb3M6CisvLworLy8gVXNlIExvb2t1cE9ySW5zZXJ0TmV3TGlua2VkUHRyIGlmIHRoZSBjb250YWluZXIgb3ducyB0aGUgZWxlbWVudHMuCisvLyBJbiB0aGlzIGNhc2UgaXQgaXMgZmluZSB3b3JraW5nIHdpdGggdGhlIHJhdyBwb2ludGVyIGFzIGxvbmcgYXMgaXQgaXMKKy8vIGd1YXJhbnRlZWQgdGhhdCBubyBvdGhlciB0aHJlYWQgY2FuIGRlbGV0ZS91cGRhdGUgYW4gYWNjZXNzZWQgZWxlbWVudC4KKy8vIEEgbXV0ZXggd2lsbCBuZWVkIHRvIGxvY2sgdGhlIGNvbnRhaW5lciBvcGVyYXRpb24gYXMgd2VsbCBhcyB0aGUgdXNlCisvLyBvZiB0aGUgcmV0dXJuZWQgZWxlbWVudHMuIEZpbmRpbmcgYW4gZWxlbWVudCBtYXkgYmUgcGVyZm9ybWVkIHVzaW5nCisvLyBGaW5kTGlua2VkUHRyKigpLgorLy8KKy8vIFVzZSBMb29rdXBPckluc2VydE5ld1NoYXJlZFB0ciBpZiB0aGUgY29udGFpbmVyIGRvZXMgbm90IG93biB0aGUgZWxlbWVudHMKKy8vIGZvciB0aGVpciB3aG9sZSBsaWZldGltZS4gVGhpcyBpcyB0eXBpY2FsbHkgdGhlIGNhc2Ugd2hlbiBhIHJlYWRlciBhbGxvd3MKKy8vIHBhcmFsbGVsIHVwZGF0ZXMgdG8gdGhlIGNvbnRhaW5lci4gSW4gdGhpcyBjYXNlIGEgTXV0ZXggb25seSBuZWVkcyB0byBsb2NrCisvLyBjb250YWluZXIgb3BlcmF0aW9ucywgYnV0IGFsbCBlbGVtZW50IG9wZXJhdGlvbnMgbXVzdCBiZSBwZXJmb3JtZWQgb24gdGhlCisvLyBzaGFyZWQgcG9pbnRlci4gRmluZGluZyBhbiBlbGVtZW50IG11c3QgYmUgcGVyZm9ybWVkIHVzaW5nIEZpbmRQdHIqKCkgYW5kCisvLyBjYW5ub3QgYmUgZG9uZSB3aXRoIEZpbmRMaW5rZWRQdHIqKCkgZXZlbiB0aG91Z2ggaXQgY29tcGlsZXMuCisKKy8vIExvb2t1cCBhIGtleSBpbiBhIG1hcCBvciBoYXNoX21hcCB3aG9zZSB2YWx1ZXMgYXJlIGxpbmtlZF9wdHJzLiAgSWYgaXQgaXMKKy8vIG1pc3NpbmcsIHNldCBjb2xsZWN0aW9uW2tleV0ucmVzZXQobmV3IFZhbHVlOjplbGVtZW50X3R5cGUpIGFuZCByZXR1cm4gdGhhdC4KKy8vIFZhbHVlOjplbGVtZW50X3R5cGUgbXVzdCBiZSBkZWZhdWx0IGNvbnN0cnVjdGFibGUuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlOjplbGVtZW50X3R5cGUqCitMb29rdXBPckluc2VydE5ld0xpbmtlZFB0cigKKyAgICBDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSkgeworICB0eXBlZGVmIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlIFZhbHVlOworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9CisgICAgICBjb2xsZWN0aW9uLT5pbnNlcnQodHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIFZhbHVlKCkpKTsKKyAgaWYgKHJldC5zZWNvbmQpIHsKKyAgICByZXQuZmlyc3QtPnNlY29uZC5yZXNldChuZXcgdHlwZW5hbWUgVmFsdWU6OmVsZW1lbnRfdHlwZSk7CisgIH0KKyAgcmV0dXJuIHJldC5maXJzdC0+c2Vjb25kLmdldCgpOworfQorCisvLyBBIHZhcmlhbnQgb2YgTG9va3VwT3JJbnNlcnROZXdMaW5rZWRQdHIgd2hlcmUgdGhlIHZhbHVlIGlzIGNvbnN0cnVjdGVkIHVzaW5nCisvLyBhIHNpbmdsZS1wYXJhbWV0ZXIgY29uc3RydWN0b3IuICBOb3RlOiB0aGUgY29uc3RydWN0b3IgYXJndW1lbnQgaXMgY29tcHV0ZWQKKy8vIGV2ZW4gaWYgaXQgd2lsbCBub3QgYmUgdXNlZCwgc28gb25seSB2YWx1ZXMgY2hlYXAgdG8gY29tcHV0ZSBzaG91bGQgYmUgcGFzc2VkCisvLyBoZXJlLiAgT24gdGhlIG90aGVyIGhhbmQgaXQgZG9lcyBub3QgbWF0dGVyIGhvdyBleHBlbnNpdmUgdGhlIGNvbnN0cnVjdGlvbiBvZgorLy8gdGhlIGFjdHVhbCBzdG9yZWQgdmFsdWUgaXMsIGFzIHRoYXQgb25seSBvY2N1cnMgaWYgbmVjZXNzYXJ5LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24sIGNsYXNzIEFyZz4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlOjplbGVtZW50X3R5cGUqCitMb29rdXBPckluc2VydE5ld0xpbmtlZFB0cigKKyAgICBDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICBjb25zdCBBcmcmIGFyZykgeworICB0eXBlZGVmIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlIFZhbHVlOworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9CisgICAgICBjb2xsZWN0aW9uLT5pbnNlcnQodHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIFZhbHVlKCkpKTsKKyAgaWYgKHJldC5zZWNvbmQpIHsKKyAgICByZXQuZmlyc3QtPnNlY29uZC5yZXNldChuZXcgdHlwZW5hbWUgVmFsdWU6OmVsZW1lbnRfdHlwZShhcmcpKTsKKyAgfQorICByZXR1cm4gcmV0LmZpcnN0LT5zZWNvbmQuZ2V0KCk7Cit9CisKKy8vIExvb2t1cCBhIGtleSBpbiBhIG1hcCBvciBoYXNoX21hcCB3aG9zZSB2YWx1ZXMgYXJlIHNoYXJlZF9wdHJzLiAgSWYgaXQgaXMKKy8vIG1pc3NpbmcsIHNldCBjb2xsZWN0aW9uW2tleV0ucmVzZXQobmV3IFZhbHVlOjplbGVtZW50X3R5cGUpLiBVbmxpa2UKKy8vIExvb2t1cE9ySW5zZXJ0TmV3TGlua2VkUHRyLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIHNoYXJlZF9wdHIgaW5zdGVhZCBvZgorLy8gdGhlIHJhdyBwb2ludGVyLiBWYWx1ZTo6ZWxlbWVudF90eXBlIG11c3QgYmUgZGVmYXVsdCBjb25zdHJ1Y3RhYmxlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0xvb2t1cE9ySW5zZXJ0TmV3U2hhcmVkUHRyKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUgU2hhcmVkUHRyOworICB0eXBlZGVmIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlOjplbGVtZW50X3R5cGUgRWxlbWVudDsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPQorICAgICAgY29sbGVjdGlvbi0+aW5zZXJ0KHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoa2V5LCBTaGFyZWRQdHIoKSkpOworICBpZiAocmV0LnNlY29uZCkgeworICAgIHJldC5maXJzdC0+c2Vjb25kLnJlc2V0KG5ldyBFbGVtZW50KCkpOworICB9CisgIHJldHVybiByZXQuZmlyc3QtPnNlY29uZDsKK30KKworLy8gQSB2YXJpYW50IG9mIExvb2t1cE9ySW5zZXJ0TmV3U2hhcmVkUHRyIHdoZXJlIHRoZSB2YWx1ZSBpcyBjb25zdHJ1Y3RlZCB1c2luZworLy8gYSBzaW5nbGUtcGFyYW1ldGVyIGNvbnN0cnVjdG9yLiAgTm90ZTogdGhlIGNvbnN0cnVjdG9yIGFyZ3VtZW50IGlzIGNvbXB1dGVkCisvLyBldmVuIGlmIGl0IHdpbGwgbm90IGJlIHVzZWQsIHNvIG9ubHkgdmFsdWVzIGNoZWFwIHRvIGNvbXB1dGUgc2hvdWxkIGJlIHBhc3NlZAorLy8gaGVyZS4gIE9uIHRoZSBvdGhlciBoYW5kIGl0IGRvZXMgbm90IG1hdHRlciBob3cgZXhwZW5zaXZlIHRoZSBjb25zdHJ1Y3Rpb24gb2YKKy8vIHRoZSBhY3R1YWwgc3RvcmVkIHZhbHVlIGlzLCBhcyB0aGF0IG9ubHkgb2NjdXJzIGlmIG5lY2Vzc2FyeS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uLCBjbGFzcyBBcmc+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0xvb2t1cE9ySW5zZXJ0TmV3U2hhcmVkUHRyKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgIGNvbnN0IEFyZyYgYXJnKSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUgU2hhcmVkUHRyOworICB0eXBlZGVmIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlOjplbGVtZW50X3R5cGUgRWxlbWVudDsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPQorICAgICAgY29sbGVjdGlvbi0+aW5zZXJ0KHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoa2V5LCBTaGFyZWRQdHIoKSkpOworICBpZiAocmV0LnNlY29uZCkgeworICAgIHJldC5maXJzdC0+c2Vjb25kLnJlc2V0KG5ldyBFbGVtZW50KGFyZykpOworICB9CisgIHJldHVybiByZXQuZmlyc3QtPnNlY29uZDsKK30KKworLy8KKy8vIE1pc2MgVXRpbGl0eSBGdW5jdGlvbnMKKy8vCisKKy8vIFVwZGF0ZXMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5LiBJZiB0aGUga2V5IHdhcyBub3QgYWxyZWFkeQorLy8gcHJlc2VudCwgdGhlbiB0aGUga2V5LXZhbHVlIHBhaXIgYXJlIGluc2VydGVkIGFuZCAicHJldmlvdXMiIGlzIHVuY2hhbmdlZC4gSWYKKy8vIHRoZSBrZXkgd2FzIGFscmVhZHkgcHJlc2VudCwgdGhlIHZhbHVlIGlzIHVwZGF0ZWQgYW5kICIqcHJldmlvdXMiIHdpbGwKKy8vIGNvbnRhaW4gYSBjb3B5IG9mIHRoZSBvbGQgdmFsdWUuCisvLworLy8gSW5zZXJ0T3JSZXR1cm5FeGlzdGluZyBoYXMgY29tcGxlbWVudGFyeSBiZWhhdmlvciB0aGF0IHJldHVybnMgdGhlCisvLyBhZGRyZXNzIG9mIGFuIGFscmVhZHkgZXhpc3RpbmcgdmFsdWUsIHJhdGhlciB0aGFuIHVwZGF0aW5nIGl0LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citib29sIFVwZGF0ZVJldHVybkNvcHkoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlKiBwcmV2aW91cykgeworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9CisgICAgICBjb2xsZWN0aW9uLT5pbnNlcnQodHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIHZhbHVlKSk7CisgIGlmICghcmV0LnNlY29uZCkgeworICAgIC8vIHVwZGF0ZQorICAgIGlmIChwcmV2aW91cykgeworICAgICAgKnByZXZpb3VzID0gcmV0LmZpcnN0LT5zZWNvbmQ7CisgICAgfQorICAgIHJldC5maXJzdC0+c2Vjb25kID0gdmFsdWU7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGV4Y2VwdCB0aGF0IHRoZSBrZXkgYW5kIHZhbHVlIGFyZSBwYXNzZWQgYXMgYSBwYWlyLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citib29sIFVwZGF0ZVJldHVybkNvcHkoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlJiB2dCwKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSogcHJldmlvdXMpIHsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPSBjb2xsZWN0aW9uLT5pbnNlcnQodnQpOworICBpZiAoIXJldC5zZWNvbmQpIHsKKyAgICAvLyB1cGRhdGUKKyAgICBpZiAocHJldmlvdXMpIHsKKyAgICAgICpwcmV2aW91cyA9IHJldC5maXJzdC0+c2Vjb25kOworICAgIH0KKyAgICByZXQuZmlyc3QtPnNlY29uZCA9IHZ0LnNlY29uZDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIFRyaWVzIHRvIGluc2VydCB0aGUgZ2l2ZW4ga2V5LXZhbHVlIHBhaXIgaW50byB0aGUgY29sbGVjdGlvbi4gUmV0dXJucyBOVUxMIGlmCisvLyB0aGUgaW5zZXJ0IHN1Y2NlZWRzLiBPdGhlcndpc2UsIHJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBleGlzdGluZyB2YWx1ZS4KKy8vCisvLyBUaGlzIGNvbXBsZW1lbnRzIFVwZGF0ZVJldHVybkNvcHkgaW4gdGhhdCBpdCBhbGxvd3MgdG8gdXBkYXRlIG9ubHkgYWZ0ZXIKKy8vIHZlcmlmeWluZyB0aGUgb2xkIHZhbHVlIGFuZCBzdGlsbCBpbnNlcnQgcXVpY2tseSB3aXRob3V0IGhhdmluZyB0byBsb29rIHVwCisvLyB0d2ljZS4gVW5saWtlIFVwZGF0ZVJldHVybkNvcHkgdGhpcyBhbHNvIGRvZXMgbm90IGNvbWUgd2l0aCB0aGUgaXNzdWUgb2YgYW4KKy8vIHVuZGVmaW5lZCBwcmV2aW91cyogaW4gY2FzZSBuZXcgZGF0YSB3YXMgaW5zZXJ0ZWQuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlKiBjb25zdAorSW5zZXJ0T3JSZXR1cm5FeGlzdGluZyhDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlJiB2dCkgeworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9IGNvbGxlY3Rpb24tPmluc2VydCh2dCk7CisgIGlmIChyZXQuc2Vjb25kKSB7CisgICAgcmV0dXJuIE5VTEw7ICAvLyBJbnNlcnRlZCwgbm8gZXhpc3RpbmcgcHJldmlvdXMgdmFsdWUuCisgIH0gZWxzZSB7CisgICAgcmV0dXJuICZyZXQuZmlyc3QtPnNlY29uZDsgIC8vIFJldHVybiBhZGRyZXNzIG9mIGFscmVhZHkgZXhpc3RpbmcgdmFsdWUuCisgIH0KK30KKworLy8gU2FtZSBhcyBhYm92ZSwgZXhjZXB0IGZvciBleHBsaWNpdCBrZXkgYW5kIGRhdGEuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlKiBjb25zdAorSW5zZXJ0T3JSZXR1cm5FeGlzdGluZygKKyAgICBDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgZGF0YSkgeworICByZXR1cm4gSW5zZXJ0T3JSZXR1cm5FeGlzdGluZyhjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgZGF0YSkpOworfQorCisvLyBFcmFzZXMgdGhlIGNvbGxlY3Rpb24gaXRlbSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBrZXksIGFuZCByZXR1cm5zIHRoZSB2YWx1ZQorLy8gYXNzb2NpYXRlZCB3aXRoIHRoYXQga2V5LiBJdCBpcyBhc3N1bWVkIHRoYXQgdGhlIHZhbHVlIChpLmUuLCB0aGUKKy8vIG1hcHBlZF90eXBlKSBpcyBhIHBvaW50ZXIuIFJldHVybnMgTlVMTCBpZiB0aGUga2V5IHdhcyBub3QgZm91bmQgaW4gdGhlCisvLyBjb2xsZWN0aW9uLgorLy8KKy8vIEV4YW1wbGVzOgorLy8gICBtYXA8c3RyaW5nLCBNeVR5cGUqPiBteV9tYXA7CisvLworLy8gT25lIGxpbmUgY2xlYW51cDoKKy8vICAgICBkZWxldGUgRXJhc2VLZXlSZXR1cm5WYWx1ZVB0cigmbXlfbWFwLCAiYWJjIik7CisvLworLy8gVXNlIHJldHVybmVkIHZhbHVlOgorLy8gICAgIHNjb3BlZF9wdHI8TXlUeXBlPiB2YWx1ZV9wdHIoRXJhc2VLZXlSZXR1cm5WYWx1ZVB0cigmbXlfbWFwLCAiYWJjIikpOworLy8gICAgIGlmICh2YWx1ZV9wdHIuZ2V0KCkpCisvLyAgICAgICB2YWx1ZV9wdHItPkRvU29tZXRoaW5nKCk7CisvLwordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSBFcmFzZUtleVJldHVyblZhbHVlUHRyKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi0+ZmluZChrZXkpOworICBpZiAoaXQgPT0gY29sbGVjdGlvbi0+ZW5kKCkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSB2ID0gaXQtPnNlY29uZDsKKyAgY29sbGVjdGlvbi0+ZXJhc2UoaXQpOworICByZXR1cm4gdjsKK30KKworLy8gSW5zZXJ0cyBhbGwgdGhlIGtleXMgZnJvbSBtYXBfY29udGFpbmVyIGludG8ga2V5X2NvbnRhaW5lciwgd2hpY2ggbXVzdAorLy8gc3VwcG9ydCBpbnNlcnQoTWFwQ29udGFpbmVyOjprZXlfdHlwZSkuCisvLworLy8gTm90ZTogYW55IGluaXRpYWwgY29udGVudHMgb2YgdGhlIGtleV9jb250YWluZXIgYXJlIG5vdCBjbGVhcmVkLgordGVtcGxhdGUgPGNsYXNzIE1hcENvbnRhaW5lciwgY2xhc3MgS2V5Q29udGFpbmVyPgordm9pZCBJbnNlcnRLZXlzRnJvbU1hcChjb25zdCBNYXBDb250YWluZXImIG1hcF9jb250YWluZXIsCisgICAgICAgICAgICAgICAgICAgICAgIEtleUNvbnRhaW5lcioga2V5X2NvbnRhaW5lcikgeworICBHT09HTEVfQ0hFQ0soa2V5X2NvbnRhaW5lciAhPSBOVUxMKTsKKyAgZm9yICh0eXBlbmFtZSBNYXBDb250YWluZXI6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gbWFwX2NvbnRhaW5lci5iZWdpbigpOworICAgICAgIGl0ICE9IG1hcF9jb250YWluZXIuZW5kKCk7ICsraXQpIHsKKyAgICBrZXlfY29udGFpbmVyLT5pbnNlcnQoaXQtPmZpcnN0KTsKKyAgfQorfQorCisvLyBBcHBlbmRzIGFsbCB0aGUga2V5cyBmcm9tIG1hcF9jb250YWluZXIgaW50byBrZXlfY29udGFpbmVyLCB3aGljaCBtdXN0CisvLyBzdXBwb3J0IHB1c2hfYmFjayhNYXBDb250YWluZXI6OmtleV90eXBlKS4KKy8vCisvLyBOb3RlOiBhbnkgaW5pdGlhbCBjb250ZW50cyBvZiB0aGUga2V5X2NvbnRhaW5lciBhcmUgbm90IGNsZWFyZWQuCit0ZW1wbGF0ZSA8Y2xhc3MgTWFwQ29udGFpbmVyLCBjbGFzcyBLZXlDb250YWluZXI+Cit2b2lkIEFwcGVuZEtleXNGcm9tTWFwKGNvbnN0IE1hcENvbnRhaW5lciYgbWFwX2NvbnRhaW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgS2V5Q29udGFpbmVyKiBrZXlfY29udGFpbmVyKSB7CisgIEdPT0dMRV9DSEVDSyhrZXlfY29udGFpbmVyICE9IE5VTEwpOworICBmb3IgKHR5cGVuYW1lIE1hcENvbnRhaW5lcjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfY29udGFpbmVyLmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwX2NvbnRhaW5lci5lbmQoKTsgKytpdCkgeworICAgIGtleV9jb250YWluZXItPnB1c2hfYmFjayhpdC0+Zmlyc3QpOworICB9Cit9CisKKy8vIEEgbW9yZSBzcGVjaWFsaXplZCBvdmVybG9hZCBvZiBBcHBlbmRLZXlzRnJvbU1hcCB0byBvcHRpbWl6ZSByZWFsbG9jYXRpb25zCisvLyBmb3IgdGhlIGNvbW1vbiBjYXNlIGluIHdoaWNoIHdlJ3JlIGFwcGVuZGluZyBrZXlzIHRvIGEgdmVjdG9yIGFuZCBoZW5jZSBjYW4KKy8vIChhbmQgc29tZXRpbWVzIHNob3VsZCkgY2FsbCByZXNlcnZlKCkgZmlyc3QuCisvLworLy8gKEl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIHBsYXkgU0ZJTkFFIGdhbWVzIHRvIGNhbGwgcmVzZXJ2ZSgpIGZvciBhbnkKKy8vIGNvbnRhaW5lciB0aGF0IHN1cHBvcnRzIGl0LCBidXQgdGhpcyBzZWVtcyB0byBnZXQgdXMgOTklIG9mIHdoYXQgd2UgbmVlZAorLy8gd2l0aG91dCB0aGUgY29tcGxleGl0eSBvZiBhIFNGSU5BRS1iYXNlZCBzb2x1dGlvbi4pCit0ZW1wbGF0ZSA8Y2xhc3MgTWFwQ29udGFpbmVyLCBjbGFzcyBLZXlUeXBlPgordm9pZCBBcHBlbmRLZXlzRnJvbU1hcChjb25zdCBNYXBDb250YWluZXImIG1hcF9jb250YWluZXIsCisgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxLZXlUeXBlPioga2V5X2NvbnRhaW5lcikgeworICBHT09HTEVfQ0hFQ0soa2V5X2NvbnRhaW5lciAhPSBOVUxMKTsKKyAgLy8gV2Ugbm93IGhhdmUgdGhlIG9wcG9ydHVuaXR5IHRvIGNhbGwgcmVzZXJ2ZSgpLiBDYWxsaW5nIHJlc2VydmUoKSBldmVyeQorICAvLyB0aW1lIGlzIGEgYmFkIGlkZWEgZm9yIHNvbWUgdXNlIGNhc2VzOiBsaWJzdGRjKysncyBpbXBsZW1lbnRhdGlvbiBvZgorICAvLyB2ZWN0b3I8Pjo6cmVzZXJ2ZSgpIHJlc2l6ZXMgdGhlIHZlY3RvcidzIGJhY2tpbmcgc3RvcmUgdG8gZXhhY3RseSB0aGUKKyAgLy8gZ2l2ZW4gc2l6ZSAodW5sZXNzIGl0J3MgYWxyZWFkeSBhdCBsZWFzdCB0aGF0IGJpZykuIEJlY2F1c2Ugb2YgdGhpcywKKyAgLy8gdGhlIHVzZSBjYXNlIHRoYXQgaW52b2x2ZXMgYXBwZW5kaW5nIGEgbG90IG9mIHNtYWxsIG1hcHMgKHRvdGFsIHNpemUKKyAgLy8gTikgb25lIGJ5IG9uZSB0byBhIHZlY3RvciB3b3VsZCBiZSBPKE5eMikuIEJ1dCBuZXZlciBjYWxsaW5nIHJlc2VydmUoKQorICAvLyBsb3NlcyB0aGUgb3Bwb3J0dW5pdHkgdG8gaW1wcm92ZSB0aGUgdXNlIGNhc2Ugb2YgYWRkaW5nIGZyb20gYSBsYXJnZQorICAvLyBtYXAgdG8gYW4gZW1wdHkgdmVjdG9yICh0aGlzIGltcHJvdmVzIHBlcmZvcm1hbmNlIGJ5IHVwIHRvIDMzJSkuIEEKKyAgLy8gbnVtYmVyIG9mIGhldXJpc3RpY3MgYXJlIHBvc3NpYmxlOyBzZWUgdGhlIGRpc2N1c3Npb24gaW4KKyAgLy8gY2wvMzQwODE2OTYuIEhlcmUgd2UgdXNlIHRoZSBzaW1wbGVzdCBvbmUuCisgIGlmIChrZXlfY29udGFpbmVyLT5lbXB0eSgpKSB7CisgICAga2V5X2NvbnRhaW5lci0+cmVzZXJ2ZShtYXBfY29udGFpbmVyLnNpemUoKSk7CisgIH0KKyAgZm9yICh0eXBlbmFtZSBNYXBDb250YWluZXI6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gbWFwX2NvbnRhaW5lci5iZWdpbigpOworICAgICAgIGl0ICE9IG1hcF9jb250YWluZXIuZW5kKCk7ICsraXQpIHsKKyAgICBrZXlfY29udGFpbmVyLT5wdXNoX2JhY2soaXQtPmZpcnN0KTsKKyAgfQorfQorCisvLyBJbnNlcnRzIGFsbCB0aGUgdmFsdWVzIGZyb20gbWFwX2NvbnRhaW5lciBpbnRvIHZhbHVlX2NvbnRhaW5lciwgd2hpY2ggbXVzdAorLy8gc3VwcG9ydCBwdXNoX2JhY2soTWFwQ29udGFpbmVyOjptYXBwZWRfdHlwZSkuCisvLworLy8gTm90ZTogYW55IGluaXRpYWwgY29udGVudHMgb2YgdGhlIHZhbHVlX2NvbnRhaW5lciBhcmUgbm90IGNsZWFyZWQuCit0ZW1wbGF0ZSA8Y2xhc3MgTWFwQ29udGFpbmVyLCBjbGFzcyBWYWx1ZUNvbnRhaW5lcj4KK3ZvaWQgQXBwZW5kVmFsdWVzRnJvbU1hcChjb25zdCBNYXBDb250YWluZXImIG1hcF9jb250YWluZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWVDb250YWluZXIqIHZhbHVlX2NvbnRhaW5lcikgeworICBHT09HTEVfQ0hFQ0sodmFsdWVfY29udGFpbmVyICE9IE5VTEwpOworICBmb3IgKHR5cGVuYW1lIE1hcENvbnRhaW5lcjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfY29udGFpbmVyLmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwX2NvbnRhaW5lci5lbmQoKTsgKytpdCkgeworICAgIHZhbHVlX2NvbnRhaW5lci0+cHVzaF9iYWNrKGl0LT5zZWNvbmQpOworICB9Cit9CisKKy8vIEEgbW9yZSBzcGVjaWFsaXplZCBvdmVybG9hZCBvZiBBcHBlbmRWYWx1ZXNGcm9tTWFwIHRvIG9wdGltaXplIHJlYWxsb2NhdGlvbnMKKy8vIGZvciB0aGUgY29tbW9uIGNhc2UgaW4gd2hpY2ggd2UncmUgYXBwZW5kaW5nIHZhbHVlcyB0byBhIHZlY3RvciBhbmQgaGVuY2UKKy8vIGNhbiAoYW5kIHNvbWV0aW1lcyBzaG91bGQpIGNhbGwgcmVzZXJ2ZSgpIGZpcnN0LgorLy8KKy8vIChJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBwbGF5IFNGSU5BRSBnYW1lcyB0byBjYWxsIHJlc2VydmUoKSBmb3IgYW55CisvLyBjb250YWluZXIgdGhhdCBzdXBwb3J0cyBpdCwgYnV0IHRoaXMgc2VlbXMgdG8gZ2V0IHVzIDk5JSBvZiB3aGF0IHdlIG5lZWQKKy8vIHdpdGhvdXQgdGhlIGNvbXBsZXhpdHkgb2YgYSBTRklOQUUtYmFzZWQgc29sdXRpb24uKQordGVtcGxhdGUgPGNsYXNzIE1hcENvbnRhaW5lciwgY2xhc3MgVmFsdWVUeXBlPgordm9pZCBBcHBlbmRWYWx1ZXNGcm9tTWFwKGNvbnN0IE1hcENvbnRhaW5lciYgbWFwX2NvbnRhaW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8VmFsdWVUeXBlPiogdmFsdWVfY29udGFpbmVyKSB7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZV9jb250YWluZXIgIT0gTlVMTCk7CisgIC8vIFNlZSBBcHBlbmRLZXlzRnJvbU1hcCBmb3Igd2h5IHRoaXMgaXMgZG9uZS4KKyAgaWYgKHZhbHVlX2NvbnRhaW5lci0+ZW1wdHkoKSkgeworICAgIHZhbHVlX2NvbnRhaW5lci0+cmVzZXJ2ZShtYXBfY29udGFpbmVyLnNpemUoKSk7CisgIH0KKyAgZm9yICh0eXBlbmFtZSBNYXBDb250YWluZXI6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gbWFwX2NvbnRhaW5lci5iZWdpbigpOworICAgICAgIGl0ICE9IG1hcF9jb250YWluZXIuZW5kKCk7ICsraXQpIHsKKyAgICB2YWx1ZV9jb250YWluZXItPnB1c2hfYmFjayhpdC0+c2Vjb25kKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTUFQX1VUSUxfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODg5YzY0NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5jYwpAQCAtMCwwICsxLDk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIGVtdWxhdGVzIGdvb2dsZTMvYmFzZS9vbmNlLmgKKy8vCisvLyBUaGlzIGhlYWRlciBpcyBpbnRlbmRlZCB0byBiZSBpbmNsdWRlZCBvbmx5IGJ5IGludGVybmFsIC5jYyBmaWxlcyBhbmQKKy8vIGdlbmVyYXRlZCAucGIuY2MgZmlsZXMuICBVc2VycyBzaG91bGQgbm90IHVzZSB0aGlzIGRpcmVjdGx5LgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaD4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2Vsc2UKKyNpbmNsdWRlIDxzY2hlZC5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTY2hlZFlpZWxkKCkgeworI2lmZGVmIF9XSU4zMgorICBTbGVlcCgwKTsKKyNlbHNlICAvLyBQT1NJWAorICBzY2hlZF95aWVsZCgpOworI2VuZGlmCit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIEdvb2dsZU9uY2VJbml0SW1wbChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCBDbG9zdXJlKiBjbG9zdXJlKSB7CisgIGludGVybmFsOjpBdG9taWNXb3JkIHN0YXRlID0gaW50ZXJuYWw6OkFjcXVpcmVfTG9hZChvbmNlKTsKKyAgLy8gRmFzdCBwYXRoLiBUaGUgcHJvdmlkZWQgY2xvc3VyZSB3YXMgYWxyZWFkeSBleGVjdXRlZC4KKyAgaWYgKHN0YXRlID09IE9OQ0VfU1RBVEVfRE9ORSkgeworICAgIHJldHVybjsKKyAgfQorICAvLyBUaGUgY2xvc3VyZSBleGVjdXRpb24gZGlkIG5vdCBjb21wbGV0ZSB5ZXQuIFRoZSBvbmNlIG9iamVjdCBjYW4gYmUgaW4gb25lCisgIC8vIG9mIHRoZSB0d28gZm9sbG93aW5nIHN0YXRlczoKKyAgLy8gICAtIFVOSU5JVElBTElaRUQ6IFdlIGFyZSB0aGUgZmlyc3QgdGhyZWFkIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KKyAgLy8gICAtIEVYRUNVVElOR19DTE9TVVJFOiBBbm90aGVyIHRocmVhZCBpcyBhbHJlYWR5IGV4ZWN1dGluZyB0aGUgY2xvc3VyZS4KKyAgLy8KKyAgLy8gRmlyc3QsIHRyeSB0byBjaGFuZ2UgdGhlIHN0YXRlIGZyb20gVU5JTklUSUFMSVpFRCB0byBFWEVDVVRJTkdfQ0xPU1VSRQorICAvLyBhdG9taWNhbGx5LgorICBzdGF0ZSA9IGludGVybmFsOjpBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKAorICAgICAgb25jZSwgT05DRV9TVEFURV9VTklOSVRJQUxJWkVELCBPTkNFX1NUQVRFX0VYRUNVVElOR19DTE9TVVJFKTsKKyAgaWYgKHN0YXRlID09IE9OQ0VfU1RBVEVfVU5JTklUSUFMSVpFRCkgeworICAgIC8vIFdlIGFyZSB0aGUgZmlyc3QgdGhyZWFkIHRvIGNhbGwgdGhpcyBmdW5jdGlvbiwgc28gd2UgaGF2ZSB0byBjYWxsIHRoZQorICAgIC8vIGNsb3N1cmUuCisgICAgY2xvc3VyZS0+UnVuKCk7CisgICAgaW50ZXJuYWw6OlJlbGVhc2VfU3RvcmUob25jZSwgT05DRV9TVEFURV9ET05FKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBBbm90aGVyIHRocmVhZCBoYXMgYWxyZWFkeSBzdGFydGVkIGV4ZWN1dGluZyB0aGUgY2xvc3VyZS4gV2UgbmVlZCB0bworICAgIC8vIHdhaXQgdW50aWwgaXQgY29tcGxldGVzIHRoZSBpbml0aWFsaXphdGlvbi4KKyAgICB3aGlsZSAoc3RhdGUgPT0gT05DRV9TVEFURV9FWEVDVVRJTkdfQ0xPU1VSRSkgeworICAgICAgLy8gTm90ZSB0aGF0IGZ1dGV4KCkgY291bGQgYmUgdXNlZCBoZXJlIG9uIExpbnV4IGFzIGFuIGltcHJvdmVtZW50LgorICAgICAgU2NoZWRZaWVsZCgpOworICAgICAgc3RhdGUgPSBpbnRlcm5hbDo6QWNxdWlyZV9Mb2FkKG9uY2UpOworICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzYyYmJhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmgKQEAgLTAsMCArMSwxNjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gZW11bGF0ZXMgZ29vZ2xlMy9iYXNlL29uY2UuaAorLy8KKy8vIFRoaXMgaGVhZGVyIGlzIGludGVuZGVkIHRvIGJlIGluY2x1ZGVkIG9ubHkgYnkgaW50ZXJuYWwgLmNjIGZpbGVzIGFuZAorLy8gZ2VuZXJhdGVkIC5wYi5jYyBmaWxlcy4gIFVzZXJzIHNob3VsZCBub3QgdXNlIHRoaXMgZGlyZWN0bHkuCisvLworLy8gVGhpcyBpcyBiYXNpY2FsbHkgYSBwb3J0YWJsZSB2ZXJzaW9uIG9mIHB0aHJlYWRfb25jZSgpLgorLy8KKy8vIFRoaXMgaGVhZGVyIGRlY2xhcmVzOgorLy8gKiBBIHR5cGUgY2FsbGVkIFByb3RvYnVmT25jZVR5cGUuCisvLyAqIEEgbWFjcm8gR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRSgpIHdoaWNoIGRlY2xhcmVzIGEgdmFyaWFibGUgb2YgdHlwZQorLy8gICBQcm90b2J1Zk9uY2VUeXBlLiAgVGhpcyBpcyB0aGUgb25seSBsZWdhbCB3YXkgdG8gZGVjbGFyZSBzdWNoIGEgdmFyaWFibGUuCisvLyAgIFRoZSBtYWNybyBtYXkgb25seSBiZSB1c2VkIGF0IHRoZSBnbG9iYWwgc2NvcGUgKHlvdSBjYW5ub3QgY3JlYXRlIGxvY2FsIG9yCisvLyAgIGNsYXNzIG1lbWJlciB2YXJpYWJsZXMgb2YgdGhpcyB0eXBlKS4KKy8vICogQSBmdW5jdGlvbiBHb29nbGVPbmNlSW5pdChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCB2b2lkICgqaW5pdF9mdW5jKSgpKS4KKy8vICAgVGhpcyBmdW5jdGlvbiwgd2hlbiBpbnZva2VkIG11bHRpcGxlIHRpbWVzIGdpdmVuIHRoZSBzYW1lIFByb3RvYnVmT25jZVR5cGUKKy8vICAgb2JqZWN0LCB3aWxsIGludm9rZSBpbml0X2Z1bmMgb24gdGhlIGZpcnN0IGNhbGwgb25seSwgYW5kIHdpbGwgbWFrZSBzdXJlCisvLyAgIG5vbmUgb2YgdGhlIGNhbGxzIHJldHVybiBiZWZvcmUgdGhhdCBmaXJzdCBjYWxsIHRvIGluaXRfZnVuYyBoYXMgZmluaXNoZWQuCisvLyAqIFRoZSB1c2VyIGNhbiBwcm92aWRlIGEgcGFyYW1ldGVyIHdoaWNoIEdvb2dsZU9uY2VJbml0KCkgZm9yd2FyZHMgdG8gdGhlCisvLyAgIHVzZXItcHJvdmlkZWQgZnVuY3Rpb24gd2hlbiBpdCBpcyBjYWxsZWQuIFVzYWdlIGV4YW1wbGU6CisvLyAgICAgaW50IGEgPSAxMDsKKy8vICAgICBHb29nbGVPbmNlSW5pdCgmbXlfb25jZSwgJk15RnVuY3Rpb25FeHBlY3RpbmdJbnRBcmd1bWVudCwgJmEpOworLy8gKiBUaGlzIGltcGxlbWVudGF0aW9uIGd1YXJhbnRlZXMgdGhhdCBQcm90b2J1Zk9uY2VUeXBlIGlzIGEgUE9EIChpLmUuIG5vCisvLyAgIHN0YXRpYyBpbml0aWFsaXplciBnZW5lcmF0ZWQpLgorLy8KKy8vIFRoaXMgaW1wbGVtZW50cyBhIHdheSB0byBwZXJmb3JtIGxhenkgaW5pdGlhbGl6YXRpb24uICBJdCdzIG1vcmUgZWZmaWNpZW50CisvLyB0aGFuIHVzaW5nIG11dGV4ZXMgYXMgbm8gbG9jayBpcyBuZWVkZWQgaWYgaW5pdGlhbGl6YXRpb24gaGFzIGFscmVhZHkKKy8vIGhhcHBlbmVkLgorLy8KKy8vIEV4YW1wbGUgdXNhZ2U6CisvLyAgIHZvaWQgSW5pdCgpOworLy8gICBHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKG9uY2VfaW5pdCk7CisvLworLy8gICAvLyBDYWxscyBJbml0KCkgZXhhY3RseSBvbmNlLgorLy8gICB2b2lkIEluaXRPbmNlKCkgeworLy8gICAgIEdvb2dsZU9uY2VJbml0KCZvbmNlX2luaXQsICZJbml0KTsKKy8vICAgfQorLy8KKy8vIE5vdGUgdGhhdCBpZiBHb29nbGVPbmNlSW5pdCgpIGlzIGNhbGxlZCBiZWZvcmUgbWFpbigpIGhhcyBiZWd1biwgaXQgbXVzdAorLy8gb25seSBiZSBjYWxsZWQgYnkgdGhlIHRocmVhZCB0aGF0IHdpbGwgZXZlbnR1YWxseSBjYWxsIG1haW4oKSAtLSB0aGF0IGlzLAorLy8gdGhlIHRocmVhZCB0aGF0IHBlcmZvcm1zIGR5bmFtaWMgaW5pdGlhbGl6YXRpb24uICBJbiBnZW5lcmFsIHRoaXMgaXMgYSBzYWZlCisvLyBhc3N1bXB0aW9uIHNpbmNlIHBlb3BsZSBkb24ndCB1c3VhbGx5IGNvbnN0cnVjdCB0aHJlYWRzIGJlZm9yZSBtYWluKCkgc3RhcnRzLAorLy8gYnV0IGl0IGlzIHRlY2huaWNhbGx5IG5vdCBndWFyYW50ZWVkLiAgVW5mb3J0dW5hdGVseSwgV2luMzIgcHJvdmlkZXMgbm8gd2F5CisvLyB3aGF0c29ldmVyIHRvIHN0YXRpY2FsbHktaW5pdGlhbGl6ZSBpdHMgc3luY2hyb25pemF0aW9uIHByaW1pdGl2ZXMsIHNvIG91cgorLy8gb25seSBjaG9pY2UgaXMgdG8gYXNzdW1lIHRoYXQgZHluYW1pYyBpbml0aWFsaXphdGlvbiBpcyBzaW5nbGUtdGhyZWFkZWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX09OQ0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19PTkNFX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKKwordHlwZWRlZiBib29sIFByb3RvYnVmT25jZVR5cGU7CisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX09OQ0VfSU5JVCBmYWxzZQorCitpbmxpbmUgdm9pZCBHb29nbGVPbmNlSW5pdChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCB2b2lkICgqaW5pdF9mdW5jKSgpKSB7CisgIGlmICghKm9uY2UpIHsKKyAgICAqb25jZSA9IHRydWU7CisgICAgaW5pdF9mdW5jKCk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEFyZz4KK2lubGluZSB2b2lkIEdvb2dsZU9uY2VJbml0KFByb3RvYnVmT25jZVR5cGUqIG9uY2UsIHZvaWQgKCppbml0X2Z1bmMpKEFyZyksCisgICAgQXJnIGFyZykgeworICBpZiAoISpvbmNlKSB7CisgICAgKm9uY2UgPSB0cnVlOworICAgIGluaXRfZnVuYyhhcmcpOworICB9Cit9CisKKyNlbHNlCisKK2VudW0geworICBPTkNFX1NUQVRFX1VOSU5JVElBTElaRUQgPSAwLAorICBPTkNFX1NUQVRFX0VYRUNVVElOR19DTE9TVVJFID0gMSwKKyAgT05DRV9TVEFURV9ET05FID0gMgorfTsKKwordHlwZWRlZiBpbnRlcm5hbDo6QXRvbWljV29yZCBQcm90b2J1Zk9uY2VUeXBlOworCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9PTkNFX0lOSVQgOjpnb29nbGU6OnByb3RvYnVmOjpPTkNFX1NUQVRFX1VOSU5JVElBTElaRUQKKworTElCUFJPVE9CVUZfRVhQT1JUCit2b2lkIEdvb2dsZU9uY2VJbml0SW1wbChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCBDbG9zdXJlKiBjbG9zdXJlKTsKKworaW5saW5lIHZvaWQgR29vZ2xlT25jZUluaXQoUHJvdG9idWZPbmNlVHlwZSogb25jZSwgdm9pZCAoKmluaXRfZnVuYykoKSkgeworICBpZiAoaW50ZXJuYWw6OkFjcXVpcmVfTG9hZChvbmNlKSAhPSBPTkNFX1NUQVRFX0RPTkUpIHsKKyAgICBpbnRlcm5hbDo6RnVuY3Rpb25DbG9zdXJlMCBmdW5jKGluaXRfZnVuYywgZmFsc2UpOworICAgIEdvb2dsZU9uY2VJbml0SW1wbChvbmNlLCAmZnVuYyk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEFyZz4KK2lubGluZSB2b2lkIEdvb2dsZU9uY2VJbml0KFByb3RvYnVmT25jZVR5cGUqIG9uY2UsIHZvaWQgKCppbml0X2Z1bmMpKEFyZyopLAorICAgIEFyZyogYXJnKSB7CisgIGlmIChpbnRlcm5hbDo6QWNxdWlyZV9Mb2FkKG9uY2UpICE9IE9OQ0VfU1RBVEVfRE9ORSkgeworICAgIGludGVybmFsOjpGdW5jdGlvbkNsb3N1cmUxPEFyZyo+IGZ1bmMoaW5pdF9mdW5jLCBmYWxzZSwgYXJnKTsKKyAgICBHb29nbGVPbmNlSW5pdEltcGwob25jZSwgJmZ1bmMpOworICB9Cit9CisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKKworY2xhc3MgR29vZ2xlT25jZUR5bmFtaWMgeworIHB1YmxpYzoKKyAgR29vZ2xlT25jZUR5bmFtaWMoKSA6IHN0YXRlXyhHT09HTEVfUFJPVE9CVUZfT05DRV9JTklUKSB7IH0KKworICAvLyBJZiB0aGlzLT5Jbml0KCkgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUgYnkgYW55IHRocmVhZCwKKyAgLy8gZXhlY3V0ZSAoKmZ1bmNfd2l0aF9hcmcpKGFyZykgdGhlbiByZXR1cm4uCisgIC8vIE90aGVyd2lzZSwgd2FpdCB1bnRpbCB0aGF0IHByaW9yIGludm9jYXRpb24gaGFzIGZpbmlzaGVkCisgIC8vIGV4ZWN1dGluZyBpdHMgZnVuY3Rpb24sIHRoZW4gcmV0dXJuLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICB2b2lkIEluaXQodm9pZCAoKmZ1bmNfd2l0aF9hcmcpKFQqKSwgVCogYXJnKSB7CisgICAgR29vZ2xlT25jZUluaXQ8VD4oJnRoaXMtPnN0YXRlXywKKyAgICAgICAgICAgICAgICAgICAgICBmdW5jX3dpdGhfYXJnLAorICAgICAgICAgICAgICAgICAgICAgIGFyZyk7CisgIH0KKyBwcml2YXRlOgorICBQcm90b2J1Zk9uY2VUeXBlIHN0YXRlXzsKK307CisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShOQU1FKSBcCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UHJvdG9idWZPbmNlVHlwZSBOQU1FID0gR09PR0xFX1BST1RPQlVGX09OQ0VfSU5JVAorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfT05DRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjVhMjBkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxwdGhyZWFkLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7CisKK2NsYXNzIE9uY2VJbml0VGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgU2V0VXAoKSB7CisgICAgc3RhdGVfID0gSU5JVF9OT1RfU1RBUlRFRDsKKyAgICBjdXJyZW50X3Rlc3RfID0gdGhpczsKKyAgfQorCisgIC8vIFNpbmNlIFByb3RvYnVmT25jZVR5cGUgaXMgb25seSBhbGxvd2VkIHRvIGJlIGFsbG9jYXRlZCBpbiBzdGF0aWMgc3RvcmFnZSwKKyAgLy8gZWFjaCB0ZXN0IG11c3QgdXNlIGEgZGlmZmVyZW50IHBhaXIgb2YgUHJvdG9idWZPbmNlVHlwZSBvYmplY3RzIHdoaWNoIGl0CisgIC8vIG11c3QgZGVjbGFyZSBpdHNlbGYuCisgIHZvaWQgU2V0T25jZXMoUHJvdG9idWZPbmNlVHlwZSogb25jZSwgUHJvdG9idWZPbmNlVHlwZSogcmVjdXJzaXZlX29uY2UpIHsKKyAgICBvbmNlXyA9IG9uY2U7CisgICAgcmVjdXJzaXZlX29uY2VfID0gcmVjdXJzaXZlX29uY2U7CisgIH0KKworICB2b2lkIEluaXRPbmNlKCkgeworICAgIEdvb2dsZU9uY2VJbml0KG9uY2VfLCAmSW5pdFN0YXRpYyk7CisgIH0KKyAgdm9pZCBJbml0UmVjdXJzaXZlT25jZSgpIHsKKyAgICBHb29nbGVPbmNlSW5pdChyZWN1cnNpdmVfb25jZV8sICZJbml0UmVjdXJzaXZlU3RhdGljKTsKKyAgfQorCisgIHZvaWQgQmxvY2tJbml0KCkgeyBpbml0X2Jsb2NrZXJfLkxvY2soKTsgfQorICB2b2lkIFVuYmxvY2tJbml0KCkgeyBpbml0X2Jsb2NrZXJfLlVubG9jaygpOyB9CisKKyAgY2xhc3MgVGVzdFRocmVhZCB7CisgICBwdWJsaWM6CisgICAgVGVzdFRocmVhZChDbG9zdXJlKiBjYWxsYmFjaykKKyAgICAgICAgOiBkb25lXyhmYWxzZSksIGpvaW5lZF8oZmFsc2UpLCBjYWxsYmFja18oY2FsbGJhY2spIHsKKyNpZmRlZiBfV0lOMzIKKyAgICAgIHRocmVhZF8gPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgJlN0YXJ0LCB0aGlzLCAwLCBOVUxMKTsKKyNlbHNlCisgICAgICBwdGhyZWFkX2NyZWF0ZSgmdGhyZWFkXywgTlVMTCwgJlN0YXJ0LCB0aGlzKTsKKyNlbmRpZgorICAgIH0KKyAgICB+VGVzdFRocmVhZCgpIHsKKyAgICAgIGlmICgham9pbmVkXykgSm9pbigpOworICAgIH0KKworICAgIGJvb2wgSXNEb25lKCkgeworICAgICAgTXV0ZXhMb2NrIGxvY2soJmRvbmVfbXV0ZXhfKTsKKyAgICAgIHJldHVybiBkb25lXzsKKyAgICB9CisgICAgdm9pZCBKb2luKCkgeworICAgICAgam9pbmVkXyA9IHRydWU7CisjaWZkZWYgX1dJTjMyCisgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHRocmVhZF8sIElORklOSVRFKTsKKyAgICAgIENsb3NlSGFuZGxlKHRocmVhZF8pOworI2Vsc2UKKyAgICAgIHB0aHJlYWRfam9pbih0aHJlYWRfLCBOVUxMKTsKKyNlbmRpZgorICAgIH0KKworICAgcHJpdmF0ZToKKyNpZmRlZiBfV0lOMzIKKyAgICBIQU5ETEUgdGhyZWFkXzsKKyNlbHNlCisgICAgcHRocmVhZF90IHRocmVhZF87CisjZW5kaWYKKworICAgIE11dGV4IGRvbmVfbXV0ZXhfOworICAgIGJvb2wgZG9uZV87CisgICAgYm9vbCBqb2luZWRfOworICAgIENsb3N1cmUqIGNhbGxiYWNrXzsKKworI2lmZGVmIF9XSU4zMgorICAgIHN0YXRpYyBEV09SRCBXSU5BUEkgU3RhcnQoTFBWT0lEIGFyZykgeworI2Vsc2UKKyAgICBzdGF0aWMgdm9pZCogU3RhcnQodm9pZCogYXJnKSB7CisjZW5kaWYKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8VGVzdFRocmVhZCo+KGFyZyktPlJ1bigpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgdm9pZCBSdW4oKSB7CisgICAgICBjYWxsYmFja18tPlJ1bigpOworICAgICAgTXV0ZXhMb2NrIGxvY2soJmRvbmVfbXV0ZXhfKTsKKyAgICAgIGRvbmVfID0gdHJ1ZTsKKyAgICB9CisgIH07CisKKyAgVGVzdFRocmVhZCogUnVuSW5pdE9uY2VJbk5ld1RocmVhZCgpIHsKKyAgICByZXR1cm4gbmV3IFRlc3RUaHJlYWQoTmV3Q2FsbGJhY2sodGhpcywgJk9uY2VJbml0VGVzdDo6SW5pdE9uY2UpKTsKKyAgfQorICBUZXN0VGhyZWFkKiBSdW5Jbml0UmVjdXJzaXZlT25jZUluTmV3VGhyZWFkKCkgeworICAgIHJldHVybiBuZXcgVGVzdFRocmVhZChOZXdDYWxsYmFjayh0aGlzLCAmT25jZUluaXRUZXN0OjpJbml0UmVjdXJzaXZlT25jZSkpOworICB9CisKKyAgZW51bSBTdGF0ZSB7CisgICAgSU5JVF9OT1RfU1RBUlRFRCwKKyAgICBJTklUX1NUQVJURUQsCisgICAgSU5JVF9ET05FCisgIH07CisgIFN0YXRlIEN1cnJlbnRTdGF0ZSgpIHsKKyAgICBNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKyAgICByZXR1cm4gc3RhdGVfOworICB9CisKKyAgdm9pZCBXYWl0QUJpdCgpIHsKKyNpZmRlZiBfV0lOMzIKKyAgICBTbGVlcCgxMDAwKTsKKyNlbHNlCisgICAgc2xlZXAoMSk7CisjZW5kaWYKKyAgfQorCisgcHJpdmF0ZToKKyAgTXV0ZXggbXV0ZXhfOworICBNdXRleCBpbml0X2Jsb2NrZXJfOworICBTdGF0ZSBzdGF0ZV87CisgIFByb3RvYnVmT25jZVR5cGUqIG9uY2VfOworICBQcm90b2J1Zk9uY2VUeXBlKiByZWN1cnNpdmVfb25jZV87CisKKyAgdm9pZCBJbml0KCkgeworICAgIE11dGV4TG9jayBsb2NrKCZtdXRleF8pOworICAgIEVYUEVDVF9FUShJTklUX05PVF9TVEFSVEVELCBzdGF0ZV8pOworICAgIHN0YXRlXyA9IElOSVRfU1RBUlRFRDsKKyAgICBtdXRleF8uVW5sb2NrKCk7CisgICAgaW5pdF9ibG9ja2VyXy5Mb2NrKCk7CisgICAgaW5pdF9ibG9ja2VyXy5VbmxvY2soKTsKKyAgICBtdXRleF8uTG9jaygpOworICAgIHN0YXRlXyA9IElOSVRfRE9ORTsKKyAgfQorCisgIHN0YXRpYyBPbmNlSW5pdFRlc3QqIGN1cnJlbnRfdGVzdF87CisgIHN0YXRpYyB2b2lkIEluaXRTdGF0aWMoKSB7IGN1cnJlbnRfdGVzdF8tPkluaXQoKTsgfQorICBzdGF0aWMgdm9pZCBJbml0UmVjdXJzaXZlU3RhdGljKCkgeyBjdXJyZW50X3Rlc3RfLT5Jbml0T25jZSgpOyB9Cit9OworCitPbmNlSW5pdFRlc3QqIE9uY2VJbml0VGVzdDo6Y3VycmVudF90ZXN0XyA9IE5VTEw7CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0Uoc2ltcGxlX29uY2UpOworCitURVNUX0YoT25jZUluaXRUZXN0LCBTaW1wbGUpIHsKKyAgU2V0T25jZXMoJnNpbXBsZV9vbmNlLCBOVUxMKTsKKworICBFWFBFQ1RfRVEoSU5JVF9OT1RfU1RBUlRFRCwgQ3VycmVudFN0YXRlKCkpOworICBJbml0T25jZSgpOworICBFWFBFQ1RfRVEoSU5JVF9ET05FLCBDdXJyZW50U3RhdGUoKSk7CisKKyAgLy8gQ2FsbGluZyBhZ2FpbiBoYXMgbm8gZWZmZWN0LgorICBJbml0T25jZSgpOworICBFWFBFQ1RfRVEoSU5JVF9ET05FLCBDdXJyZW50U3RhdGUoKSk7Cit9CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocmVjdXJzaXZlX29uY2UxKTsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocmVjdXJzaXZlX29uY2UyKTsKKworVEVTVF9GKE9uY2VJbml0VGVzdCwgUmVjdXJzaXZlKSB7CisgIFNldE9uY2VzKCZyZWN1cnNpdmVfb25jZTEsICZyZWN1cnNpdmVfb25jZTIpOworCisgIEVYUEVDVF9FUShJTklUX05PVF9TVEFSVEVELCBDdXJyZW50U3RhdGUoKSk7CisgIEluaXRSZWN1cnNpdmVPbmNlKCk7CisgIEVYUEVDVF9FUShJTklUX0RPTkUsIEN1cnJlbnRTdGF0ZSgpKTsKK30KKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShtdWx0aXBsZV90aHJlYWRzX29uY2UpOworCitURVNUX0YoT25jZUluaXRUZXN0LCBNdWx0aXBsZVRocmVhZHMpIHsKKyAgU2V0T25jZXMoJm11bHRpcGxlX3RocmVhZHNfb25jZSwgTlVMTCk7CisKKyAgc2NvcGVkX3B0cjxUZXN0VGhyZWFkPiB0aHJlYWRzWzRdOworICBFWFBFQ1RfRVEoSU5JVF9OT1RfU1RBUlRFRCwgQ3VycmVudFN0YXRlKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykgeworICAgIHRocmVhZHNbaV0ucmVzZXQoUnVuSW5pdE9uY2VJbk5ld1RocmVhZCgpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykgeworICAgIHRocmVhZHNbaV0tPkpvaW4oKTsKKyAgfQorICBFWFBFQ1RfRVEoSU5JVF9ET05FLCBDdXJyZW50U3RhdGUoKSk7Cit9CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UobXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UxKTsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UobXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UyKTsKKworVEVTVF9GKE9uY2VJbml0VGVzdCwgTXVsdGlwbGVUaHJlYWRzQmxvY2tlZCkgeworICBTZXRPbmNlcygmbXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UxLCAmbXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UyKTsKKworICBzY29wZWRfcHRyPFRlc3RUaHJlYWQ+IHRocmVhZHNbOF07CisgIEVYUEVDVF9FUShJTklUX05PVF9TVEFSVEVELCBDdXJyZW50U3RhdGUoKSk7CisKKyAgQmxvY2tJbml0KCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgdGhyZWFkc1tpXS5yZXNldChSdW5Jbml0T25jZUluTmV3VGhyZWFkKCkpOworICB9CisgIGZvciAoaW50IGkgPSA0OyBpIDwgODsgaSsrKSB7CisgICAgdGhyZWFkc1tpXS5yZXNldChSdW5Jbml0UmVjdXJzaXZlT25jZUluTmV3VGhyZWFkKCkpOworICB9CisKKyAgV2FpdEFCaXQoKTsKKworICAvLyBXZSBzaG91bGQgbm93IGhhdmUgb25lIHRocmVhZCBibG9ja2VkIGluc2lkZSBJbml0KCksIGZvdXIgYmxvY2tlZCB3YWl0aW5nCisgIC8vIGZvciBJbml0KCkgdG8gY29tcGxldGUsIGFuZCB0aHJlZSBibG9ja2VkIHdhaXRpbmcgZm9yIEluaXRSZWN1cnNpdmUoKSB0bworICAvLyBjb21wbGV0ZS4KKyAgRVhQRUNUX0VRKElOSVRfU1RBUlRFRCwgQ3VycmVudFN0YXRlKCkpOworICBVbmJsb2NrSW5pdCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgdGhyZWFkc1tpXS0+Sm9pbigpOworICB9CisgIEVYUEVDVF9FUShJTklUX0RPTkUsIEN1cnJlbnRTdGF0ZSgpKTsKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BsYXRmb3JtX21hY3Jvcy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmYwOWI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaApAQCAtMCwwICsxLDEwOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1BMQVRGT1JNX01BQ1JPU19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUExBVEZPUk1fTUFDUk9TX0hfCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1BMQVRGT1JNX0VSUk9SIFwKKyNlcnJvciAiSG9zdCBwbGF0Zm9ybSB3YXMgbm90IGRldGVjdGVkIGFzIHN1cHBvcnRlZCBieSBwcm90b2J1ZiIKKworLy8gUHJvY2Vzc29yIGFyY2hpdGVjdHVyZSBkZXRlY3Rpb24uICBGb3IgbW9yZSBpbmZvIG9uIHdoYXQncyBkZWZpbmVkLCBzZWU6CisvLyAgIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9iMDA4NGtheS5hc3B4CisvLyAgIGh0dHA6Ly93d3cuYWduZXIub3JnL29wdGltaXplL2NhbGxpbmdfY29udmVudGlvbnMucGRmCisvLyAgIG9yIHdpdGggZ2NjLCBydW46ICJlY2hvIHwgZ2NjIC1FIC1kTSAtIgorI2lmIGRlZmluZWQoX01fWDY0KSB8fCBkZWZpbmVkKF9feDg2XzY0X18pCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX1g2NCAxCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCAxCisjZWxpZiBkZWZpbmVkKF9NX0lYODYpIHx8IGRlZmluZWQoX19pMzg2X18pCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX0lBMzIgMQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF8zMl9CSVQgMQorI2VsaWYgZGVmaW5lZChfX1FOWF9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF9BUk1fUU5YIDEKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfMzJfQklUIDEKKyNlbGlmIGRlZmluZWQoX19BUk1FTF9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF9BUk0gMQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF8zMl9CSVQgMQorI2VsaWYgZGVmaW5lZChfX2FhcmNoNjRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfQUFSQ0g2NCAxCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCAxCisjZWxpZiBkZWZpbmVkKF9fTUlQU0VMX18pCisjaWYgZGVmaW5lZChfX0xQNjRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfTUlQUzY0IDEKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUIDEKKyNlbHNlCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX01JUFMgMQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF8zMl9CSVQgMQorI2VuZGlmCisjZWxpZiBkZWZpbmVkKF9fcG5hY2xfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfMzJfQklUIDEKKyNlbGlmIGRlZmluZWQoc3BhcmMpCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX1NQQVJDIDEKKyNpZmRlZiBTT0xBUklTXzY0QklUX0VOQUJMRUQKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUIDEKKyNlbHNlCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzMyX0JJVCAxCisjZW5kaWYKKyNlbGlmIGRlZmluZWQoX1BPV0VSKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF9QT1dFUiAxCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCAxCisjZWxpZiBkZWZpbmVkKF9fR05VQ19fKQorIyBpZiAoKChfX0dOVUNfXyA9PSA0KSAmJiAoX19HTlVDX01JTk9SX18gPj0gNykpIHx8IChfX0dOVUNfXyA+IDQpKQorLy8gV2UgZmFsbGJhY2sgdG8gdGhlIGdlbmVyaWMgQ2xhbmcvR0NDID49IDQuNyBpbXBsZW1lbnRhdGlvbiBpbiBhdG9taWNvcHMuaAorIyBlbGlmIGRlZmluZWQoX19jbGFuZ19fKQorIyAgaWYgIV9faGFzX2V4dGVuc2lvbihjX2F0b21pYykKK0dPT0dMRV9QUk9UT0JVRl9QTEFURk9STV9FUlJPUgorIyAgZW5kaWYKKy8vIFdlIGZhbGxiYWNrIHRvIHRoZSBnZW5lcmljIENsYW5nL0dDQyA+PSA0LjcgaW1wbGVtZW50YXRpb24gaW4gYXRvbWljb3BzLmgKKyMgZW5kaWYKKyMgaWYgX19MUDY0X18KKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQgMQorIyBlbHNlCisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfMzJfQklUIDEKKyMgZW5kaWYKKyNlbHNlCitHT09HTEVfUFJPVE9CVUZfUExBVEZPUk1fRVJST1IKKyNlbmRpZgorCisjaWYgZGVmaW5lZChfX0FQUExFX18pCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9PU19BUFBMRQorI2VsaWYgZGVmaW5lZChfX25hdGl2ZV9jbGllbnRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX09TX05BQ0wKKyNlbGlmIGRlZmluZWQoc3VuKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfT1NfU09MQVJJUworI2VsaWYgZGVmaW5lZChfQUlYKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfT1NfQUlYCisjZW5kaWYKKworI3VuZGVmIEdPT0dMRV9QUk9UT0JVRl9QTEFURk9STV9FUlJPUgorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QTEFURk9STV9NQUNST1NfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI1MGJmNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oCkBAIC0wLDAgKzEsNDcwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gZnJvbSBnb29nbGUzL3V0aWwvZ3RsL3NoYXJlZF9wdHIuaAorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TSEFSRURfUFRSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0hBUkVEX1BUUl9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4gIC8vIGZvciBzd2FwCisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8bWVtb3J5PgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBBbGlhcyB0byBzdGQ6OnNoYXJlZF9wdHIgZm9yIGFueSBDKysxMSBwbGF0Zm9ybSwKKy8vIGFuZCBmb3IgYW55IHN1cHBvcnRlZCBNU1ZDIGNvbXBpbGVyLgorI2lmICFkZWZpbmVkKFVUSUxfR1RMX1VTRV9TVERfU0hBUkVEX1BUUikgJiYgXAorICAgIChkZWZpbmVkKENPTVBJTEVSX01TVkMpIHx8IGRlZmluZWQoTEFOR19DWFgxMSkpCisjZGVmaW5lIFVUSUxfR1RMX1VTRV9TVERfU0hBUkVEX1BUUiAxCisjZW5kaWYKKworI2lmIGRlZmluZWQoVVRJTF9HVExfVVNFX1NURF9TSEFSRURfUFRSKSAmJiBVVElMX0dUTF9VU0VfU1REX1NIQVJFRF9QVFIKKworLy8gVGhlc2UgYXJlIHRyYW5zaXRpb25hbC4gIFRoZXkgd2lsbCBiZSBnb2luZyBhd2F5IHNvb24uCisvLyBQbGVhc2UganVzdCAjaW5jbHVkZSA8bWVtb3J5PiBhbmQganVzdCB0eXBlIHN0ZDo6c2hhcmVkX3B0ciB5b3Vyc2VsZiwgaW5zdGVhZAorLy8gb2YgcmVseWluZyBvbiB0aGlzIGZpbGUuCisvLworLy8gTWlncmF0aW9uIGRvYzogaHR0cDovL2dvL3N0ZC1zaGFyZWQtcHRyLWxzYwordXNpbmcgc3RkOjplbmFibGVfc2hhcmVkX2Zyb21fdGhpczsKK3VzaW5nIHN0ZDo6c2hhcmVkX3B0cjsKK3VzaW5nIHN0ZDo6c3RhdGljX3BvaW50ZXJfY2FzdDsKK3VzaW5nIHN0ZDo6d2Vha19wdHI7CisKKyNlbHNlICAvLyBiZWxvdywgVVRJTF9HVExfVVNFX1NURF9TSEFSRURfUFRSIG5vdCBzZXQgb3Igc2V0IHRvIDAuCisKKy8vIEZvciBldmVyeXRoaW5nIGVsc2UgdGhlcmUgaXMgdGhlIGdvb2dsZTMgaW1wbGVtZW50YXRpb24uCitpbmxpbmUgYm9vbCBSZWZDb3VudERlYyh2b2xhdGlsZSBBdG9taWMzMiAqcHRyKSB7CisgIHJldHVybiBCYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIC0xKSAhPSAwOworfQorCitpbmxpbmUgdm9pZCBSZWZDb3VudEluYyh2b2xhdGlsZSBBdG9taWMzMiAqcHRyKSB7CisgIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCAxKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGNsYXNzIHNoYXJlZF9wdHI7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gY2xhc3Mgd2Vha19wdHI7CisKKy8vIFRoaXMgY2xhc3MgaXMgYW4gaW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIGZvciBzaGFyZWRfcHRyLiBJZiB0d28KKy8vIHNoYXJlZF9wdHJzIHBvaW50IHRvIHRoZSBzYW1lIG9iamVjdCwgdGhleSBhbHNvIHNoYXJlIGEgY29udHJvbCBibG9jay4KKy8vIEFuICJlbXB0eSIgc2hhcmVkX3BvaW50ZXIgcmVmZXJzIHRvIE5VTEwgYW5kIGFsc28gaGFzIGEgTlVMTCBjb250cm9sIGJsb2NrLgorLy8gSXQgY29udGFpbnMgYWxsIG9mIHRoZSBzdGF0ZSB0aGF0J3MgbmVlZGVkIGZvciByZWZlcmVuY2UgY291bnRpbmcgb3IgYW55CisvLyBvdGhlciBraW5kIG9mIHJlc291cmNlIG1hbmFnZW1lbnQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24gdGhlIGNvbnRyb2wgYmxvY2sKKy8vIGhhcHBlbnMgdG8gY29uc2lzdCBvZiB0d28gYXRvbWljIHdvcmRzLCB0aGUgcmVmZXJlbmNlIGNvdW50ICh0aGUgbnVtYmVyCisvLyBvZiBzaGFyZWRfcHRycyB0aGF0IHNoYXJlIG93bmVyc2hpcCBvZiB0aGUgb2JqZWN0KSBhbmQgdGhlIHdlYWsgY291bnQKKy8vICh0aGUgbnVtYmVyIG9mIHdlYWtfcHRycyB0aGF0IG9ic2VydmUgdGhlIG9iamVjdCwgcGx1cyAxIGlmIHRoZQorLy8gcmVmY291bnQgaXMgbm9uemVybykuCisvLworLy8gVGhlICJwbHVzIDEiIGlzIHRvIHByZXZlbnQgYSByYWNlIGNvbmRpdGlvbiBpbiB0aGUgc2hhcmVkX3B0ciBhbmQKKy8vIHdlYWtfcHRyIGRlc3RydWN0b3JzLiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGUgY29udHJvbCBibG9jayBpcworLy8gb25seSBkZWxldGVkIG9uY2UsIHNvIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYXQgbW9zdCBvbmUKKy8vIG9iamVjdCBzZWVzIHRoZSB3ZWFrIGNvdW50IGRlY3JlbWVudGVkIGZyb20gMSB0byAwLgorY2xhc3MgU2hhcmVkUHRyQ29udHJvbEJsb2NrIHsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGZyaWVuZCBjbGFzcyBzaGFyZWRfcHRyOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gZnJpZW5kIGNsYXNzIHdlYWtfcHRyOworIHByaXZhdGU6CisgIFNoYXJlZFB0ckNvbnRyb2xCbG9jaygpIDogcmVmY291bnRfKDEpLCB3ZWFrX2NvdW50XygxKSB7IH0KKyAgQXRvbWljMzIgcmVmY291bnRfOworICBBdG9taWMzMiB3ZWFrX2NvdW50XzsKK307CisKKy8vIEZvcndhcmQgZGVjbGFyYXRpb24uIFRoZSBjbGFzcyBpcyBkZWZpbmVkIGJlbG93LgordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGNsYXNzIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzOworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2NsYXNzIHNoYXJlZF9wdHIgeworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gZnJpZW5kIGNsYXNzIHdlYWtfcHRyOworIHB1YmxpYzoKKyAgdHlwZWRlZiBUIGVsZW1lbnRfdHlwZTsKKworICBzaGFyZWRfcHRyKCkgOiBwdHJfKE5VTEwpLCBjb250cm9sX2Jsb2NrXyhOVUxMKSB7fQorCisgIGV4cGxpY2l0IHNoYXJlZF9wdHIoVCogcHRyKQorICAgICAgOiBwdHJfKHB0ciksCisgICAgICAgIGNvbnRyb2xfYmxvY2tfKHB0ciAhPSBOVUxMID8gbmV3IFNoYXJlZFB0ckNvbnRyb2xCbG9jayA6IE5VTEwpIHsKKyAgICAvLyBJZiBwIGlzIG5vbi1udWxsIGFuZCBUIGluaGVyaXRzIGZyb20gZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMsIHdlCisgICAgLy8gc2V0IHVwIHRoZSBkYXRhIHRoYXQgc2hhcmVkX2Zyb21fdGhpcyBuZWVkcy4KKyAgICBNYXliZVNldHVwV2Vha1RoaXMocHRyKTsKKyAgfQorCisgIC8vIENvcHkgY29uc3RydWN0b3I6IG1ha2VzIHRoaXMgb2JqZWN0IGEgY29weSBvZiBwdHIsIGFuZCBpbmNyZW1lbnRzCisgIC8vIHRoZSByZWZlcmVuY2UgY291bnQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgorICBzaGFyZWRfcHRyKGNvbnN0IHNoYXJlZF9wdHI8VT4mIHB0cikKKyAgICAgIDogcHRyXyhOVUxMKSwKKyAgICAgICAgY29udHJvbF9ibG9ja18oTlVMTCkgeworICAgIEluaXRpYWxpemUocHRyKTsKKyAgfQorICAvLyBOZWVkIG5vbi10ZW1wbGF0ZWQgdmVyc2lvbiB0byBwcmV2ZW50IHRoZSBjb21waWxlci1nZW5lcmF0ZWQgZGVmYXVsdAorICBzaGFyZWRfcHRyKGNvbnN0IHNoYXJlZF9wdHI8VD4mIHB0cikKKyAgICAgIDogcHRyXyhOVUxMKSwKKyAgICAgICAgY29udHJvbF9ibG9ja18oTlVMTCkgeworICAgIEluaXRpYWxpemUocHRyKTsKKyAgfQorCisgIC8vIEFzc2lnbm1lbnQgb3BlcmF0b3IuIFJlcGxhY2VzIHRoZSBleGlzdGluZyBzaGFyZWRfcHRyIHdpdGggcHRyLgorICAvLyBJbmNyZW1lbnQgcHRyJ3MgcmVmZXJlbmNlIGNvdW50IGFuZCBkZWNyZW1lbnQgdGhlIG9uZSBiZWluZyByZXBsYWNlZC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+CisgIHNoYXJlZF9wdHI8VD4mIG9wZXJhdG9yPShjb25zdCBzaGFyZWRfcHRyPFU+JiBwdHIpIHsKKyAgICBpZiAocHRyXyAhPSBwdHIucHRyXykgeworICAgICAgc2hhcmVkX3B0cjxUPiBtZShwdHIpOyAgIC8vIHdpbGwgaG9sZCBvdXIgcHJldmlvdXMgc3RhdGUgdG8gYmUgZGVzdHJveWVkLgorICAgICAgc3dhcChtZSk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIC8vIE5lZWQgbm9uLXRlbXBsYXRlZCB2ZXJzaW9uIHRvIHByZXZlbnQgdGhlIGNvbXBpbGVyLWdlbmVyYXRlZCBkZWZhdWx0CisgIHNoYXJlZF9wdHI8VD4mIG9wZXJhdG9yPShjb25zdCBzaGFyZWRfcHRyPFQ+JiBwdHIpIHsKKyAgICBpZiAocHRyXyAhPSBwdHIucHRyXykgeworICAgICAgc2hhcmVkX3B0cjxUPiBtZShwdHIpOyAgIC8vIHdpbGwgaG9sZCBvdXIgcHJldmlvdXMgc3RhdGUgdG8gYmUgZGVzdHJveWVkLgorICAgICAgc3dhcChtZSk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIC8vIFRPRE8oYXVzdGVybik6IENvbnNpZGVyIHByb3ZpZGluZyB0aGlzIGNvbnN0cnVjdG9yLiBUaGUgZHJhZnQgQysrIHN0YW5kYXJkCisgIC8vICgyMC44LjEwLjIuMSkgaW5jbHVkZXMgaXQuIEhvd2V2ZXIsIGl0IHNheXMgdGhhdCB0aGlzIGNvbnN0cnVjdG9yIHRocm93cworICAvLyBhIGJhZF93ZWFrX3B0ciBleGNlcHRpb24gd2hlbiBwdHIgaXMgZXhwaXJlZC4gSXMgaXQgYmV0dGVyIHRvIHByb3ZpZGUgdGhpcworICAvLyBjb25zdHJ1Y3RvciBhbmQgbWFrZSBpdCBkbyBzb21ldGhpbmcgZWxzZSwgbGlrZSBmYWlsIHdpdGggYSBDSEVDSywgb3IgdG8KKyAgLy8gbGVhdmUgdGhpcyBjb25zdHJ1Y3RvciBvdXQgZW50aXJlbHk/CisgIC8vCisgIC8vIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgorICAvLyBzaGFyZWRfcHRyKGNvbnN0IHdlYWtfcHRyPFU+JiBwdHIpOworCisgIH5zaGFyZWRfcHRyKCkgeworICAgIGlmIChwdHJfICE9IE5VTEwpIHsKKyAgICAgIGlmICghUmVmQ291bnREZWMoJmNvbnRyb2xfYmxvY2tfLT5yZWZjb3VudF8pKSB7CisgICAgICAgIGRlbGV0ZSBwdHJfOworCisgICAgICAgIC8vIHdlYWtfY291bnRfIGlzIGRlZmluZWQgYXMgdGhlIG51bWJlciBvZiB3ZWFrX3B0cnMgdGhhdCBvYnNlcnZlCisgICAgICAgIC8vIHB0cl8sIHBsdXMgMSBpZiByZWZjb3VudF8gaXMgbm9uemVyby4KKyAgICAgICAgaWYgKCFSZWZDb3VudERlYygmY29udHJvbF9ibG9ja18tPndlYWtfY291bnRfKSkgeworICAgICAgICAgIGRlbGV0ZSBjb250cm9sX2Jsb2NrXzsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFJlcGxhY2VzIHVuZGVybHlpbmcgcmF3IHBvaW50ZXIgd2l0aCB0aGUgb25lIHBhc3NlZCBpbi4gIFRoZSByZWZlcmVuY2UKKyAgLy8gY291bnQgaXMgc2V0IHRvIG9uZSAob3IgemVybyBpZiB0aGUgcG9pbnRlciBpcyBOVUxMKSBmb3IgdGhlIHBvaW50ZXIKKyAgLy8gYmVpbmcgcGFzc2VkIGluIGFuZCBkZWNyZW1lbnRlZCBmb3IgdGhlIG9uZSBiZWluZyByZXBsYWNlZC4KKyAgLy8KKyAgLy8gSWYgeW91IGhhdmUgYSBjb21waWxhdGlvbiBlcnJvciB3aXRoIHRoaXMgY29kZSwgbWFrZSBzdXJlIHlvdSBhcmVuJ3QKKyAgLy8gcGFzc2luZyBOVUxMLCBudWxscHRyLCBvciAwIHRvIHRoaXMgZnVuY3Rpb24uICBDYWxsIHJlc2V0IHdpdGhvdXQgYW4KKyAgLy8gYXJndW1lbnQgdG8gcmVzZXQgdG8gYSBudWxsIHB0ci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFk+CisgIHZvaWQgcmVzZXQoWSogcCkgeworICAgIGlmIChwICE9IHB0cl8pIHsKKyAgICAgIHNoYXJlZF9wdHI8VD4gdG1wKHApOworICAgICAgdG1wLnN3YXAoKnRoaXMpOworICAgIH0KKyAgfQorCisgIHZvaWQgcmVzZXQoKSB7CisgICAgcmVzZXQoc3RhdGljX2Nhc3Q8VCo+KE5VTEwpKTsKKyAgfQorCisgIC8vIEV4Y2hhbmdlcyB0aGUgY29udGVudHMgb2YgdGhpcyB3aXRoIHRoZSBjb250ZW50cyBvZiByLiAgVGhpcyBmdW5jdGlvbgorICAvLyBzdXBwb3J0cyBtb3JlIGVmZmljaWVudCBzd2FwcGluZyBzaW5jZSBpdCBlbGltaW5hdGVzIHRoZSBuZWVkIGZvciBhCisgIC8vIHRlbXBvcmFyeSBzaGFyZWRfcHRyIG9iamVjdC4KKyAgdm9pZCBzd2FwKHNoYXJlZF9wdHI8VD4mIHIpIHsKKyAgICB1c2luZyBzdGQ6OnN3YXA7ICAvLyBodHRwOi8vZ28vdXNpbmctc3RkLXN3YXAKKyAgICBzd2FwKHB0cl8sIHIucHRyXyk7CisgICAgc3dhcChjb250cm9sX2Jsb2NrXywgci5jb250cm9sX2Jsb2NrXyk7CisgIH0KKworICAvLyBUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIGlzIHVzZWZ1bCBmb3IgZ2FpbmluZyBhY2Nlc3MgdG8gdGhlIHVuZGVybHlpbmcKKyAgLy8gcG9pbnRlciB3aGVuIGEgc2hhcmVkX3B0ciByZW1haW5zIGluIHNjb3BlIHNvIHRoZSByZWZlcmVuY2UtY291bnQgaXMKKyAgLy8ga25vd24gdG8gYmUgPiAwIChlLmcuIGZvciBwYXJhbWV0ZXIgcGFzc2luZykuCisgIFQqIGdldCgpIGNvbnN0IHsKKyAgICByZXR1cm4gcHRyXzsKKyAgfQorCisgIFQmIG9wZXJhdG9yKigpIGNvbnN0IHsKKyAgICByZXR1cm4gKnB0cl87CisgIH0KKworICBUKiBvcGVyYXRvci0+KCkgY29uc3QgeworICAgIHJldHVybiBwdHJfOworICB9CisKKyAgbG9uZyB1c2VfY291bnQoKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnRyb2xfYmxvY2tfID8gY29udHJvbF9ibG9ja18tPnJlZmNvdW50XyA6IDE7CisgIH0KKworICBib29sIHVuaXF1ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gdXNlX2NvdW50KCkgPT0gMTsKKyAgfQorCisgcHJpdmF0ZToKKyAgLy8gSWYgciBpcyBub24tZW1wdHksIGluaXRpYWxpemUgKnRoaXMgdG8gc2hhcmUgb3duZXJzaGlwIHdpdGggciwKKyAgLy8gaW5jcmVhc2luZyB0aGUgdW5kZXJseWluZyByZWZlcmVuY2UgY291bnQuCisgIC8vIElmIHIgaXMgZW1wdHksICp0aGlzIHJlbWFpbnMgZW1wdHkuCisgIC8vIFJlcXVpcmVzOiB0aGlzIGlzIGVtcHR5LCBuYW1lbHkgdGhpcy0+cHRyXyA9PSBOVUxMLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KKyAgdm9pZCBJbml0aWFsaXplKGNvbnN0IHNoYXJlZF9wdHI8VT4mIHIpIHsKKyAgICAvLyBUaGlzIHBlcmZvcm1zIGEgc3RhdGljX2Nhc3Qgb24gci5wdHJfIHRvIFUqLCB3aGljaCBpcyBhIG5vLW9wIHNpbmNlIGl0CisgICAgLy8gaXMgYWxyZWFkeSBhIFUqLiBTbyBpbml0aWFsaXphdGlvbiBoZXJlIHJlcXVpcmVzIHRoYXQgci5wdHJfIGlzCisgICAgLy8gaW1wbGljaXRseSBjb252ZXJ0aWJsZSB0byBUKi4KKyAgICBJbml0aWFsaXplV2l0aFN0YXRpY0Nhc3Q8VT4ocik7CisgIH0KKworICAvLyBJbml0aWFsaXplcyAqdGhpcyBhcyBkZXNjcmliZWQgaW4gSW5pdGlhbGl6ZSwgYnV0IGFkZGl0aW9uYWxseSBwZXJmb3JtcyBhCisgIC8vIHN0YXRpY19jYXN0IGZyb20gci5wdHJfIChWKikgdG8gVSouCisgIC8vIE5PVEUoZ2ZjKTogV2UnZCBuZWVkIGEgbW9yZSBnZW5lcmFsIGZvcm0gdG8gc3VwcG9ydCBjb25zdF9wb2ludGVyX2Nhc3QgYW5kCisgIC8vIGR5bmFtaWNfcG9pbnRlcl9jYXN0LCBidXQgdGhvc2Ugb3BlcmF0aW9ucyBhcmUgc3VmZmljaWVudGx5IGRpc2NvdXJhZ2VkCisgIC8vIHRoYXQgc3VwcG9ydGluZyBzdGF0aWNfcG9pbnRlcl9jYXN0IGlzIHN1ZmZpY2llbnQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBVLCB0eXBlbmFtZSBWPgorICB2b2lkIEluaXRpYWxpemVXaXRoU3RhdGljQ2FzdChjb25zdCBzaGFyZWRfcHRyPFY+JiByKSB7CisgICAgaWYgKHIuY29udHJvbF9ibG9ja18gIT0gTlVMTCkgeworICAgICAgUmVmQ291bnRJbmMoJnIuY29udHJvbF9ibG9ja18tPnJlZmNvdW50Xyk7CisKKyAgICAgIHB0cl8gPSBzdGF0aWNfY2FzdDxVKj4oci5wdHJfKTsKKyAgICAgIGNvbnRyb2xfYmxvY2tfID0gci5jb250cm9sX2Jsb2NrXzsKKyAgICB9CisgIH0KKworICAvLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHRoZSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgcmF3IHBvaW50ZXIuIElmIFQKKyAgLy8gZG9lc24ndCBpbmhlcml0IGZyb20gZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8VD4gdGhlbiB3ZSBoYXZlIG5vdGhpbmcgdG8KKyAgLy8gZG8sIHNvIHRoaXMgZnVuY3Rpb24gaXMgdHJpdmlhbCBhbmQgaW5saW5lLiBUaGUgb3RoZXIgdmVyc2lvbiBpcyBkZWNsYXJlZAorICAvLyBvdXQgb2YgbGluZSwgYWZ0ZXIgdGhlIGNsYXNzIGRlZmluaXRpb24gb2YgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMuCisgIHZvaWQgTWF5YmVTZXR1cFdlYWtUaGlzKGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzPFQ+KiBwdHIpOworICB2b2lkIE1heWJlU2V0dXBXZWFrVGhpcyguLi4pIHsgfQorCisgIFQqIHB0cl87CisgIFNoYXJlZFB0ckNvbnRyb2xCbG9jayogY29udHJvbF9ibG9ja187CisKKyNpZm5kZWYgU1dJRworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KKyAgZnJpZW5kIGNsYXNzIHNoYXJlZF9wdHI7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFUsIHR5cGVuYW1lIFY+CisgIGZyaWVuZCBzaGFyZWRfcHRyPFU+IHN0YXRpY19wb2ludGVyX2Nhc3QoY29uc3Qgc2hhcmVkX3B0cjxWPiYgcmhzKTsKKyNlbmRpZgorfTsKKworLy8gTWF0Y2hlcyB0aGUgaW50ZXJmYWNlIG9mIHN0ZDo6c3dhcCBhcyBhbiBhaWQgdG8gZ2VuZXJpYyBwcm9ncmFtbWluZy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPiB2b2lkIHN3YXAoc2hhcmVkX3B0cjxUPiYgciwgc2hhcmVkX3B0cjxUPiYgcykgeworICByLnN3YXAocyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBVPgorc2hhcmVkX3B0cjxUPiBzdGF0aWNfcG9pbnRlcl9jYXN0KGNvbnN0IHNoYXJlZF9wdHI8VT4mIHJocykgeworICBzaGFyZWRfcHRyPFQ+IGxoczsKKyAgbGhzLnRlbXBsYXRlIEluaXRpYWxpemVXaXRoU3RhdGljQ2FzdDxUPihyaHMpOworICByZXR1cm4gbGhzOworfQorCisvLyBTZWUgY29tbWVudHMgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZSBmb3IgYSBkZXNjcmlwdGlvbiBvZiB3aHkgdGhpcworLy8gY2xhc3MgZXhpc3RzLCBhbmQgdGhlIGRyYWZ0IEMrKyBzdGFuZGFyZCAoYXMgb2YgSnVseSAyMDA5IHRoZQorLy8gbGF0ZXN0IGRyYWZ0IGlzIE4yOTE0KSBmb3IgdGhlIGRldGFpbGVkIHNwZWNpZmljYXRpb24uCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2NsYXNzIHdlYWtfcHRyIHsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IGZyaWVuZCBjbGFzcyB3ZWFrX3B0cjsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVCBlbGVtZW50X3R5cGU7CisKKyAgLy8gQ3JlYXRlIGFuIGVtcHR5IChpLmUuIGFscmVhZHkgZXhwaXJlZCkgd2Vha19wdHIuCisgIHdlYWtfcHRyKCkgOiBwdHJfKE5VTEwpLCBjb250cm9sX2Jsb2NrXyhOVUxMKSB7IH0KKworICAvLyBDcmVhdGUgYSB3ZWFrX3B0ciB0aGF0IG9ic2VydmVzIHRoZSBzYW1lIG9iamVjdCB0aGF0IHB0ciBwb2ludHMKKyAgLy8gdG8uICBOb3RlIHRoYXQgdGhlcmUgaXMgbm8gcmFjZSBjb25kaXRpb24gaGVyZTogd2Uga25vdyB0aGF0IHRoZQorICAvLyBjb250cm9sIGJsb2NrIGNhbid0IGRpc2FwcGVhciB3aGlsZSB3ZSdyZSBsb29raW5nIGF0IGl0IGJlY2F1c2UKKyAgLy8gaXQgaXMgb3duZWQgYnkgYXQgbGVhc3Qgb25lIHNoYXJlZF9wdHIsIHB0ci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyKGNvbnN0IHNoYXJlZF9wdHI8VT4mIHB0cikgeworICAgIENvcHlGcm9tKHB0ci5wdHJfLCBwdHIuY29udHJvbF9ibG9ja18pOworICB9CisKKyAgLy8gQ29weSBhIHdlYWtfcHRyLiBUaGUgb2JqZWN0IGl0IHBvaW50cyB0byBtaWdodCBkaXNhcHBlYXIsIGJ1dCB3ZQorICAvLyBkb24ndCBjYXJlOiB3ZSdyZSBvbmx5IHdvcmtpbmcgd2l0aCB0aGUgY29udHJvbCBibG9jaywgYW5kIGl0IGNhbid0CisgIC8vIGRpc2FwcGVhciB3aGlsZSB3ZSdyZSBsb29raW5nIGF0IGJlY2F1c2UgaXQncyBvd25lZCBieSBhdCBsZWFzdCBvbmUKKyAgLy8gd2Vha19wdHIsIHB0ci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyKGNvbnN0IHdlYWtfcHRyPFU+JiBwdHIpIHsKKyAgICBDb3B5RnJvbShwdHIucHRyXywgcHRyLmNvbnRyb2xfYmxvY2tfKTsKKyAgfQorCisgIC8vIE5lZWQgbm9uLXRlbXBsYXRlZCB2ZXJzaW9uIHRvIHByZXZlbnQgZGVmYXVsdCBjb3B5IGNvbnN0cnVjdG9yCisgIHdlYWtfcHRyKGNvbnN0IHdlYWtfcHRyJiBwdHIpIHsKKyAgICBDb3B5RnJvbShwdHIucHRyXywgcHRyLmNvbnRyb2xfYmxvY2tfKTsKKyAgfQorCisgIC8vIERlc3Ryb3kgdGhlIHdlYWtfcHRyLiBJZiBubyBzaGFyZWRfcHRyIG93bnMgdGhlIGNvbnRyb2wgYmxvY2ssIGFuZCBpZgorICAvLyB3ZSBhcmUgdGhlIGxhc3Qgd2Vha19wdHIgdG8gb3duIGl0LCB0aGVuIGl0IGNhbiBiZSBkZWxldGVkLiBOb3RlIHRoYXQKKyAgLy8gd2Vha19jb3VudF8gaXMgZGVmaW5lZCBhcyB0aGUgbnVtYmVyIG9mIHdlYWtfcHRycyBzaGFyaW5nIHRoaXMgY29udHJvbAorICAvLyBibG9jaywgcGx1cyAxIGlmIHRoZXJlIGFyZSBhbnkgc2hhcmVkX3B0cnMuIFdlIHRoZXJlZm9yZSBrbm93IHRoYXQgaXQncworICAvLyBzYWZlIHRvIGRlbGV0ZSB0aGUgY29udHJvbCBibG9jayB3aGVuIHdlYWtfY291bnRfIHJlYWNoZXMgMCwgd2l0aG91dAorICAvLyBoYXZpbmcgdG8gcGVyZm9ybSBhbnkgYWRkaXRpb25hbCB0ZXN0cy4KKyAgfndlYWtfcHRyKCkgeworICAgIGlmIChjb250cm9sX2Jsb2NrXyAhPSBOVUxMICYmCisgICAgICAgICFSZWZDb3VudERlYygmY29udHJvbF9ibG9ja18tPndlYWtfY291bnRfKSkgeworICAgICAgZGVsZXRlIGNvbnRyb2xfYmxvY2tfOworICAgIH0KKyAgfQorCisgIHdlYWtfcHRyJiBvcGVyYXRvcj0oY29uc3Qgd2Vha19wdHImIHB0cikgeworICAgIGlmICgmcHRyICE9IHRoaXMpIHsKKyAgICAgIHdlYWtfcHRyIHRtcChwdHIpOworICAgICAgdG1wLnN3YXAoKnRoaXMpOworICAgIH0KKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyJiBvcGVyYXRvcj0oY29uc3Qgd2Vha19wdHI8VT4mIHB0cikgeworICAgIHdlYWtfcHRyIHRtcChwdHIpOworICAgIHRtcC5zd2FwKCp0aGlzKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyJiBvcGVyYXRvcj0oY29uc3Qgc2hhcmVkX3B0cjxVPiYgcHRyKSB7CisgICAgd2Vha19wdHIgdG1wKHB0cik7CisgICAgdG1wLnN3YXAoKnRoaXMpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIHZvaWQgc3dhcCh3ZWFrX3B0ciYgcHRyKSB7CisgICAgdXNpbmcgc3RkOjpzd2FwOyAgLy8gaHR0cDovL2dvL3VzaW5nLXN0ZC1zd2FwCisgICAgc3dhcChwdHJfLCBwdHIucHRyXyk7CisgICAgc3dhcChjb250cm9sX2Jsb2NrXywgcHRyLmNvbnRyb2xfYmxvY2tfKTsKKyAgfQorCisgIHZvaWQgcmVzZXQoKSB7CisgICAgd2Vha19wdHIgdG1wOworICAgIHRtcC5zd2FwKCp0aGlzKTsKKyAgfQorCisgIC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIHNoYXJlZF9wdHJzIHRoYXQgb3duIHRoZSBvYmplY3Qgd2UgYXJlIG9ic2VydmluZy4KKyAgLy8gTm90ZSB0aGF0IHRoaXMgbnVtYmVyIGNhbiBiZSAwIChpZiB0aGlzIHBvaW50ZXIgaGFzIGV4cGlyZWQpLgorICBsb25nIHVzZV9jb3VudCgpIGNvbnN0IHsKKyAgICByZXR1cm4gY29udHJvbF9ibG9ja18gIT0gTlVMTCA/IGNvbnRyb2xfYmxvY2tfLT5yZWZjb3VudF8gOiAwOworICB9CisKKyAgYm9vbCBleHBpcmVkKCkgY29uc3QgeyByZXR1cm4gdXNlX2NvdW50KCkgPT0gMDsgfQorCisgIC8vIFJldHVybiBhIHNoYXJlZF9wdHIgdGhhdCBvd25zIHRoZSBvYmplY3Qgd2UgYXJlIG9ic2VydmluZy4gSWYgd2UKKyAgLy8gaGF2ZSBleHBpcmVkLCB0aGUgc2hhcmVkX3B0ciB3aWxsIGJlIGVtcHR5LiBXZSBoYXZlIHRvIGJlIGNhcmVmdWwKKyAgLy8gYWJvdXQgY29uY3VycmVuY3ksIHRob3VnaCwgc2luY2Ugc29tZSBvdGhlciB0aHJlYWQgbWlnaHQgYmUKKyAgLy8gZGVzdHJveWluZyB0aGUgbGFzdCBvd25pbmcgc2hhcmVkX3B0ciB3aGlsZSB3ZSdyZSBpbiB0aGlzCisgIC8vIGZ1bmN0aW9uLiAgV2Ugd2FudCB0byBpbmNyZW1lbnQgdGhlIHJlZmNvdW50IG9ubHkgaWYgaXQncyBub256ZXJvCisgIC8vIGFuZCBnZXQgdGhlIG5ldyB2YWx1ZSwgYW5kIHdlIHdhbnQgdGhhdCB3aG9sZSBvcGVyYXRpb24gdG8gYmUKKyAgLy8gYXRvbWljLgorICBzaGFyZWRfcHRyPFQ+IGxvY2soKSBjb25zdCB7CisgICAgc2hhcmVkX3B0cjxUPiByZXN1bHQ7CisgICAgaWYgKGNvbnRyb2xfYmxvY2tfICE9IE5VTEwpIHsKKyAgICAgIEF0b21pYzMyIG9sZF9yZWZjb3VudDsKKyAgICAgIGRvIHsKKyAgICAgICAgb2xkX3JlZmNvdW50ID0gY29udHJvbF9ibG9ja18tPnJlZmNvdW50XzsKKyAgICAgICAgaWYgKG9sZF9yZWZjb3VudCA9PSAwKQorICAgICAgICAgIGJyZWFrOworICAgICAgfSB3aGlsZSAob2xkX3JlZmNvdW50ICE9CisgICAgICAgICAgICAgICBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAoCisgICAgICAgICAgICAgICAgICAgJmNvbnRyb2xfYmxvY2tfLT5yZWZjb3VudF8sIG9sZF9yZWZjb3VudCwKKyAgICAgICAgICAgICAgICAgICBvbGRfcmVmY291bnQgKyAxKSk7CisgICAgICBpZiAob2xkX3JlZmNvdW50ID4gMCkgeworICAgICAgICByZXN1bHQucHRyXyA9IHB0cl87CisgICAgICAgIHJlc3VsdC5jb250cm9sX2Jsb2NrXyA9IGNvbnRyb2xfYmxvY2tfOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworIHByaXZhdGU6CisgIHZvaWQgQ29weUZyb20oVCogcHRyLCBTaGFyZWRQdHJDb250cm9sQmxvY2sqIGNvbnRyb2xfYmxvY2spIHsKKyAgICBwdHJfID0gcHRyOworICAgIGNvbnRyb2xfYmxvY2tfID0gY29udHJvbF9ibG9jazsKKyAgICBpZiAoY29udHJvbF9ibG9ja18gIT0gTlVMTCkKKyAgICAgIFJlZkNvdW50SW5jKCZjb250cm9sX2Jsb2NrXy0+d2Vha19jb3VudF8pOworICB9CisKKyBwcml2YXRlOgorICBlbGVtZW50X3R5cGUqIHB0cl87CisgIFNoYXJlZFB0ckNvbnRyb2xCbG9jayogY29udHJvbF9ibG9ja187Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gdm9pZCBzd2FwKHdlYWtfcHRyPFQ+JiByLCB3ZWFrX3B0cjxUPiYgcykgeworICByLnN3YXAocyk7Cit9CisKKy8vIFNlZSBjb21tZW50cyBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlIGZvciBhIGRlc2NyaXB0aW9uIG9mIHdoeSB0aGlzIGNsYXNzCisvLyBleGlzdHMsIGFuZCBzZWN0aW9uIDIwLjguMTAuNSBvZiB0aGUgZHJhZnQgQysrIHN0YW5kYXJkIChhcyBvZiBKdWx5IDIwMDkKKy8vIHRoZSBsYXRlc3QgZHJhZnQgaXMgTjI5MTQpIGZvciB0aGUgZGV0YWlsZWQgc3BlY2lmaWNhdGlvbi4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorY2xhc3MgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMgeworICBmcmllbmQgY2xhc3Mgc2hhcmVkX3B0cjxUPjsKKyBwdWJsaWM6CisgIC8vIFByZWNvbmRpdGlvbjogdGhlcmUgbXVzdCBiZSBhIHNoYXJlZF9wdHIgdGhhdCBvd25zICp0aGlzIGFuZCB0aGF0IHdhcworICAvLyBjcmVhdGVkLCBkaXJlY3RseSBvciBpbmRpcmVjdGx5LCBmcm9tIGEgcmF3IHBvaW50ZXIgb2YgdHlwZSBUKi4gKFRoZQorICAvLyBsYXR0ZXIgcGFydCBvZiB0aGUgY29uZGl0aW9uIGlzIHRlY2huaWNhbCBidXQgbm90IHF1aXRlIHJlZHVuZGFudDsgaXQKKyAgLy8gcnVsZXMgb3V0IHNvbWUgY29tcGxpY2F0ZWQgdXNlcyBpbnZvbHZpbmcgaW5oZXJpdGFuY2UgaGllcmFyY2hpZXMuKQorICBzaGFyZWRfcHRyPFQ+IHNoYXJlZF9mcm9tX3RoaXMoKSB7CisgICAgLy8gQmVoYXZpb3IgaXMgdW5kZWZpbmVkIGlmIHRoZSBwcmVjb25kaXRpb24gaXNuJ3Qgc2F0aXNmaWVkOyB3ZSBjaG9vc2UKKyAgICAvLyB0byBkaWUgd2l0aCBhIENIRUNLIGZhaWx1cmUuCisgICAgQ0hFQ0soIXdlYWtfdGhpc18uZXhwaXJlZCgpKSA8PCAiTm8gc2hhcmVkX3B0ciBvd25zIHRoaXMgb2JqZWN0IjsKKyAgICByZXR1cm4gd2Vha190aGlzXy5sb2NrKCk7CisgIH0KKyAgc2hhcmVkX3B0cjxjb25zdCBUPiBzaGFyZWRfZnJvbV90aGlzKCkgY29uc3QgeworICAgIENIRUNLKCF3ZWFrX3RoaXNfLmV4cGlyZWQoKSkgPDwgIk5vIHNoYXJlZF9wdHIgb3ducyB0aGlzIG9iamVjdCI7CisgICAgcmV0dXJuIHdlYWtfdGhpc18ubG9jaygpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzKCkgeyB9CisgIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzKGNvbnN0IGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzJiBvdGhlcikgeyB9CisgIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzJiBvcGVyYXRvcj0oY29uc3QgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMmIG90aGVyKSB7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIH5lbmFibGVfc2hhcmVkX2Zyb21fdGhpcygpIHsgfQorCisgcHJpdmF0ZToKKyAgd2Vha19wdHI8VD4gd2Vha190aGlzXzsKK307CisKKy8vIFRoaXMgaXMgYSBoZWxwZXIgZnVuY3Rpb24gY2FsbGVkIGJ5IHNoYXJlZF9wdHIncyBjb25zdHJ1Y3RvciBmcm9tIGEgcmF3CisvLyBwb2ludGVyLiBJZiBUIGluaGVyaXRzIGZyb20gZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8VD4sIGl0IHNldHMgdXAKKy8vIHdlYWtfdGhpc18gc28gdGhhdCBzaGFyZWRfZnJvbV90aGlzIHdvcmtzIGNvcnJlY3RseS4gSWYgVCBkb2VzIG5vdCBpbmhlcml0CisvLyBmcm9tIHdlYWtfdGhpcyB3ZSBnZXQgYSBkaWZmZXJlbnQgb3ZlcmxvYWQsIGRlZmluZWQgaW5saW5lLCB3aGljaCBkb2VzCisvLyBub3RoaW5nLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3ZvaWQgc2hhcmVkX3B0cjxUPjo6TWF5YmVTZXR1cFdlYWtUaGlzKGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzPFQ+KiBwdHIpIHsKKyAgaWYgKHB0cikgeworICAgIENIRUNLKHB0ci0+d2Vha190aGlzXy5leHBpcmVkKCkpIDw8ICJPYmplY3QgYWxyZWFkeSBvd25lZCBieSBhIHNoYXJlZF9wdHIiOworICAgIHB0ci0+d2Vha190aGlzXyA9ICp0aGlzOworICB9Cit9CisKKyNlbmRpZiAgLy8gVVRJTF9HVExfVVNFX1NURF9TSEFSRURfUFRSCisKK30gIC8vIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0hBUkVEX1BUUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc2luZ2xldG9uLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NpbmdsZXRvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzMDFmNTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NpbmdsZXRvbi5oCkBAIC0wLDAgKzEsNjggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0lOR0xFVE9OX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0lOR0xFVE9OX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFNpbmdsZXRvbiB7CisgcHVibGljOgorICBzdGF0aWMgVCogZ2V0KCkgeworICAgIEdvb2dsZU9uY2VJbml0KCZvbmNlXywgJlNpbmdsZXRvbjxUPjo6SW5pdCk7CisgICAgcmV0dXJuIGluc3RhbmNlXzsKKyAgfQorICBzdGF0aWMgdm9pZCBTaHV0RG93bigpIHsKKyAgICBkZWxldGUgaW5zdGFuY2VfOworICAgIGluc3RhbmNlXyA9IE5VTEw7CisgIH0KKyBwcml2YXRlOgorICBzdGF0aWMgdm9pZCBJbml0KCkgeworICAgIGluc3RhbmNlXyA9IG5ldyBUKCk7CisgIH0KKyAgc3RhdGljIFByb3RvYnVmT25jZVR5cGUgb25jZV87CisgIHN0YXRpYyBUKiBpbnN0YW5jZV87Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorUHJvdG9idWZPbmNlVHlwZSBTaW5nbGV0b248VD46Om9uY2VfOworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorVCogU2luZ2xldG9uPFQ+OjppbnN0YW5jZV8gPSBOVUxMOworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0lOR0xFVE9OX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllNGM4MmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmgKQEAgLTAsMCArMSwxMjEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBmcm9tIGdvb2dsZTMvdXRpbC9ndGwvc3RsX3V0aWwuaAorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVExfVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUTF9VVElMX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIFNUTERlbGV0ZUNvbnRhaW5lclBvaW50ZXJzKCkKKy8vICBGb3IgYSByYW5nZSB3aXRoaW4gYSBjb250YWluZXIgb2YgcG9pbnRlcnMsIGNhbGxzIGRlbGV0ZQorLy8gIChub24tYXJyYXkgdmVyc2lvbikgb24gdGhlc2UgcG9pbnRlcnMuCisvLyBOT1RFOiBmb3IgdGhlc2UgdGhyZWUgZnVuY3Rpb25zLCB3ZSBjb3VsZCBqdXN0IGltcGxlbWVudCBhIERlbGV0ZU9iamVjdAorLy8gZnVuY3RvciBhbmQgdGhlbiBjYWxsIGZvcl9lYWNoKCkgb24gdGhlIHJhbmdlIGFuZCBmdW5jdG9yLCBidXQgdGhpcworLy8gcmVxdWlyZXMgdXMgdG8gcHVsbCBpbiBhbGwgb2YgYWxnb3JpdGhtLmgsIHdoaWNoIHNlZW1zIGV4cGVuc2l2ZS4KKy8vIEZvciBoYXNoX1ttdWx0aV1zZXQsIGl0IGlzIGltcG9ydGFudCB0aGF0IHRoaXMgZGVsZXRlcyBiZWhpbmQgdGhlIGl0ZXJhdG9yCisvLyBiZWNhdXNlIHRoZSBoYXNoX3NldCBtYXkgY2FsbCB0aGUgaGFzaCBmdW5jdGlvbiBvbiB0aGUgaXRlcmF0b3Igd2hlbiBpdCBpcworLy8gYWR2YW5jZWQsIHdoaWNoIGNvdWxkIHJlc3VsdCBpbiB0aGUgaGFzaCBmdW5jdGlvbiB0cnlpbmcgdG8gZGVmZXJlbmNlIGEKKy8vIHN0YWxlIHBvaW50ZXIuCit0ZW1wbGF0ZSA8Y2xhc3MgRm9yd2FyZEl0ZXJhdG9yPgordm9pZCBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhGb3J3YXJkSXRlcmF0b3IgYmVnaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcndhcmRJdGVyYXRvciBlbmQpIHsKKyAgd2hpbGUgKGJlZ2luICE9IGVuZCkgeworICAgIEZvcndhcmRJdGVyYXRvciB0ZW1wID0gYmVnaW47CisgICAgKytiZWdpbjsKKyAgICBkZWxldGUgKnRlbXA7CisgIH0KK30KKworLy8gSW5zaWRlIEdvb2dsZSwgdGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIGEgaG9ycmlibGUsIGRpc2d1c3RpbmcgaGFjayBpbiB3aGljaAorLy8gd2UgcmVhY2ggaW50byB0aGUgc3RyaW5nJ3MgcHJpdmF0ZSBpbXBsZW1lbnRhdGlvbiBhbmQgcmVzaXplIGl0IHdpdGhvdXQKKy8vIGluaXRpYWxpemluZyB0aGUgbmV3IGJ5dGVzLiAgSW4gc29tZSBjYXNlcyBkb2luZyB0aGlzIGNhbiBzaWduaWZpY2FudGx5CisvLyBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgSG93ZXZlciwgc2luY2UgaXQncyB0b3RhbGx5IG5vbi1wb3J0YWJsZSBpdCBoYXMgbm8KKy8vIHBsYWNlIGluIG9wZW4gc291cmNlIGNvZGUuICBGZWVsIGZyZWUgdG8gZmlsbCB0aGlzIGZ1bmN0aW9uIGluIHdpdGggeW91cgorLy8gb3duIGRpc2d1c3RpbmcgaGFjayBpZiB5b3Ugd2FudCB0aGUgcGVyZiBib29zdC4KK2lubGluZSB2b2lkIFNUTFN0cmluZ1Jlc2l6ZVVuaW5pdGlhbGl6ZWQoc3RyaW5nKiBzLCBzaXplX3QgbmV3X3NpemUpIHsKKyAgcy0+cmVzaXplKG5ld19zaXplKTsKK30KKworLy8gUmV0dXJuIGEgbXV0YWJsZSBjaGFyKiBwb2ludGluZyB0byBhIHN0cmluZydzIGludGVybmFsIGJ1ZmZlciwKKy8vIHdoaWNoIG1heSBub3QgYmUgbnVsbC10ZXJtaW5hdGVkLiBXcml0aW5nIHRocm91Z2ggdGhpcyBwb2ludGVyIHdpbGwKKy8vIG1vZGlmeSB0aGUgc3RyaW5nLgorLy8KKy8vIHN0cmluZ19hc19hcnJheSgmc3RyKVtpXSBpcyB2YWxpZCBmb3IgMCA8PSBpIDwgc3RyLnNpemUoKSB1bnRpbCB0aGUKKy8vIG5leHQgY2FsbCB0byBhIHN0cmluZyBtZXRob2QgdGhhdCBpbnZhbGlkYXRlcyBpdGVyYXRvcnMuCisvLworLy8gQXMgb2YgMjAwNi0wNCwgdGhlcmUgaXMgbm8gc3RhbmRhcmQtYmxlc3NlZCB3YXkgb2YgZ2V0dGluZyBhCisvLyBtdXRhYmxlIHJlZmVyZW5jZSB0byBhIHN0cmluZydzIGludGVybmFsIGJ1ZmZlci4gSG93ZXZlciwgaXNzdWUgNTMwCisvLyAoaHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvSlRDMS9TQzIyL1dHMjEvZG9jcy9sd2ctYWN0aXZlLmh0bWwjNTMwKQorLy8gcHJvcG9zZXMgdGhpcyBhcyB0aGUgbWV0aG9kLiBBY2NvcmRpbmcgdG8gTWF0dCBBdXN0ZXJuLCB0aGlzIHNob3VsZAorLy8gYWxyZWFkeSB3b3JrIG9uIGFsbCBjdXJyZW50IGltcGxlbWVudGF0aW9ucy4KK2lubGluZSBjaGFyKiBzdHJpbmdfYXNfYXJyYXkoc3RyaW5nKiBzdHIpIHsKKyAgLy8gRE8gTk9UIFVTRSBjb25zdF9jYXN0PGNoYXIqPihzdHItPmRhdGEoKSkhIFNlZSB0aGUgdW5pdHRlc3QgZm9yIHdoeS4KKyAgcmV0dXJuIHN0ci0+ZW1wdHkoKSA/IE5VTEwgOiAmKnN0ci0+YmVnaW4oKTsKK30KKworLy8gU1RMRGVsZXRlRWxlbWVudHMoKSBkZWxldGVzIGFsbCB0aGUgZWxlbWVudHMgaW4gYW4gU1RMIGNvbnRhaW5lciBhbmQgY2xlYXJzCisvLyB0aGUgY29udGFpbmVyLiAgVGhpcyBmdW5jdGlvbiBpcyBzdWl0YWJsZSBmb3IgdXNlIHdpdGggYSB2ZWN0b3IsIHNldCwKKy8vIGhhc2hfc2V0LCBvciBhbnkgb3RoZXIgU1RMIGNvbnRhaW5lciB3aGljaCBkZWZpbmVzIHNlbnNpYmxlIGJlZ2luKCksIGVuZCgpLAorLy8gYW5kIGNsZWFyKCkgbWV0aG9kcy4KKy8vCisvLyBJZiBjb250YWluZXIgaXMgTlVMTCwgdGhpcyBmdW5jdGlvbiBpcyBhIG5vLW9wLgorLy8KKy8vIEFzIGFuIGFsdGVybmF0aXZlIHRvIGNhbGxpbmcgU1RMRGVsZXRlRWxlbWVudHMoKSBkaXJlY3RseSwgY29uc2lkZXIKKy8vIEVsZW1lbnREZWxldGVyIChkZWZpbmVkIGJlbG93KSwgd2hpY2ggZW5zdXJlcyB0aGF0IHlvdXIgY29udGFpbmVyJ3MgZWxlbWVudHMKKy8vIGFyZSBkZWxldGVkIHdoZW4gdGhlIEVsZW1lbnREZWxldGVyIGdvZXMgb3V0IG9mIHNjb3BlLgordGVtcGxhdGUgPGNsYXNzIFQ+Cit2b2lkIFNUTERlbGV0ZUVsZW1lbnRzKFQgKmNvbnRhaW5lcikgeworICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuOworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhjb250YWluZXItPmJlZ2luKCksIGNvbnRhaW5lci0+ZW5kKCkpOworICBjb250YWluZXItPmNsZWFyKCk7Cit9CisKKy8vIEdpdmVuIGFuIFNUTCBjb250YWluZXIgY29uc2lzdGluZyBvZiAoa2V5LCB2YWx1ZSkgcGFpcnMsIFNUTERlbGV0ZVZhbHVlcworLy8gZGVsZXRlcyBhbGwgdGhlICJ2YWx1ZSIgY29tcG9uZW50cyBhbmQgY2xlYXJzIHRoZSBjb250YWluZXIuICBEb2VzIG5vdGhpbmcKKy8vIGluIHRoZSBjYXNlIGl0J3MgZ2l2ZW4gYSBOVUxMIHBvaW50ZXIuCisKK3RlbXBsYXRlIDxjbGFzcyBUPgordm9pZCBTVExEZWxldGVWYWx1ZXMoVCAqdikgeworICBpZiAoIXYpIHJldHVybjsKKyAgZm9yICh0eXBlbmFtZSBUOjppdGVyYXRvciBpID0gdi0+YmVnaW4oKTsgaSAhPSB2LT5lbmQoKTsgKytpKSB7CisgICAgZGVsZXRlIGktPnNlY29uZDsKKyAgfQorICB2LT5jbGVhcigpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RMX1VUSUxfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyNzJkOGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5jYwpAQCAtMCwwICsxLDE3NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy9iYXNlL3N0cmluZ3ByaW50Zi5jYworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdGRhcmcuaD4gLy8gRm9yIHZhX2xpc3QgYW5kIHJlbGF0ZWQgb3BlcmF0aW9ucworI2luY2x1ZGUgPHN0ZGlvLmg+IC8vIE1TVkMgcmVxdWlyZXMgdGhpcyBmb3IgX3ZzbnByaW50ZgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyNpZmRlZiBfTVNDX1ZFUgorZW51bSB7IElTX0NPTVBJTEVSX01TVkMgPSAxIH07CisjaWZuZGVmIHZhX2NvcHkKKy8vIERlZmluZSB2YV9jb3B5IGZvciBNU1ZDLiBUaGlzIGlzIGEgaGFjaywgYXNzdW1pbmcgdmFfbGlzdCBpcyBzaW1wbHkgYQorLy8gcG9pbnRlciBpbnRvIHRoZSBzdGFjayBhbmQgaXMgc2FmZSB0byBjb3B5LgorI2RlZmluZSB2YV9jb3B5KGRlc3QsIHNyYykgKChkZXN0KSA9IChzcmMpKQorI2VuZGlmCisjZWxzZQorZW51bSB7IElTX0NPTVBJTEVSX01TVkMgPSAwIH07CisjZW5kaWYKKwordm9pZCBTdHJpbmdBcHBlbmRWKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIHZhX2xpc3QgYXApIHsKKyAgLy8gRmlyc3QgdHJ5IHdpdGggYSBzbWFsbCBmaXhlZCBzaXplIGJ1ZmZlcgorICBzdGF0aWMgY29uc3QgaW50IGtTcGFjZUxlbmd0aCA9IDEwMjQ7CisgIGNoYXIgc3BhY2Vba1NwYWNlTGVuZ3RoXTsKKworICAvLyBJdCdzIHBvc3NpYmxlIGZvciBtZXRob2RzIHRoYXQgdXNlIGEgdmFfbGlzdCB0byBpbnZhbGlkYXRlCisgIC8vIHRoZSBkYXRhIGluIGl0IHVwb24gdXNlLiAgVGhlIGZpeCBpcyB0byBtYWtlIGEgY29weQorICAvLyBvZiB0aGUgc3RydWN0dXJlIGJlZm9yZSB1c2luZyBpdCBhbmQgdXNlIHRoYXQgY29weSBpbnN0ZWFkLgorICB2YV9saXN0IGJhY2t1cF9hcDsKKyAgdmFfY29weShiYWNrdXBfYXAsIGFwKTsKKyAgaW50IHJlc3VsdCA9IHZzbnByaW50ZihzcGFjZSwga1NwYWNlTGVuZ3RoLCBmb3JtYXQsIGJhY2t1cF9hcCk7CisgIHZhX2VuZChiYWNrdXBfYXApOworCisgIGlmIChyZXN1bHQgPCBrU3BhY2VMZW5ndGgpIHsKKyAgICBpZiAocmVzdWx0ID49IDApIHsKKyAgICAgIC8vIE5vcm1hbCBjYXNlIC0tIGV2ZXJ5dGhpbmcgZml0LgorICAgICAgZHN0LT5hcHBlbmQoc3BhY2UsIHJlc3VsdCk7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKElTX0NPTVBJTEVSX01TVkMpIHsKKyAgICAgIC8vIEVycm9yIG9yIE1TVkMgcnVubmluZyBvdXQgb2Ygc3BhY2UuICBNU1ZDIDguMCBhbmQgaGlnaGVyCisgICAgICAvLyBjYW4gYmUgYXNrZWQgYWJvdXQgc3BhY2UgbmVlZGVkIHdpdGggdGhlIHNwZWNpYWwgaWRpb20gYmVsb3c6CisgICAgICB2YV9jb3B5KGJhY2t1cF9hcCwgYXApOworICAgICAgcmVzdWx0ID0gdnNucHJpbnRmKE5VTEwsIDAsIGZvcm1hdCwgYmFja3VwX2FwKTsKKyAgICAgIHZhX2VuZChiYWNrdXBfYXApOworICAgIH0KKworICAgIGlmIChyZXN1bHQgPCAwKSB7CisgICAgICAvLyBKdXN0IGFuIGVycm9yLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgfQorCisgIC8vIEluY3JlYXNlIHRoZSBidWZmZXIgc2l6ZSB0byB0aGUgc2l6ZSByZXF1ZXN0ZWQgYnkgdnNucHJpbnRmLAorICAvLyBwbHVzIG9uZSBmb3IgdGhlIGNsb3NpbmcgXDAuCisgIGludCBsZW5ndGggPSByZXN1bHQrMTsKKyAgY2hhciogYnVmID0gbmV3IGNoYXJbbGVuZ3RoXTsKKworICAvLyBSZXN0b3JlIHRoZSB2YV9saXN0IGJlZm9yZSB3ZSB1c2UgaXQgYWdhaW4KKyAgdmFfY29weShiYWNrdXBfYXAsIGFwKTsKKyAgcmVzdWx0ID0gdnNucHJpbnRmKGJ1ZiwgbGVuZ3RoLCBmb3JtYXQsIGJhY2t1cF9hcCk7CisgIHZhX2VuZChiYWNrdXBfYXApOworCisgIGlmIChyZXN1bHQgPj0gMCAmJiByZXN1bHQgPCBsZW5ndGgpIHsKKyAgICAvLyBJdCBmaXQKKyAgICBkc3QtPmFwcGVuZChidWYsIHJlc3VsdCk7CisgIH0KKyAgZGVsZXRlW10gYnVmOworfQorCisKK3N0cmluZyBTdHJpbmdQcmludGYoY29uc3QgY2hhciogZm9ybWF0LCAuLi4pIHsKKyAgdmFfbGlzdCBhcDsKKyAgdmFfc3RhcnQoYXAsIGZvcm1hdCk7CisgIHN0cmluZyByZXN1bHQ7CisgIFN0cmluZ0FwcGVuZFYoJnJlc3VsdCwgZm9ybWF0LCBhcCk7CisgIHZhX2VuZChhcCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2NvbnN0IHN0cmluZyYgU1N0cmluZ1ByaW50ZihzdHJpbmcqIGRzdCwgY29uc3QgY2hhciogZm9ybWF0LCAuLi4pIHsKKyAgdmFfbGlzdCBhcDsKKyAgdmFfc3RhcnQoYXAsIGZvcm1hdCk7CisgIGRzdC0+Y2xlYXIoKTsKKyAgU3RyaW5nQXBwZW5kVihkc3QsIGZvcm1hdCwgYXApOworICB2YV9lbmQoYXApOworICByZXR1cm4gKmRzdDsKK30KKwordm9pZCBTdHJpbmdBcHBlbmRGKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIC4uLikgeworICB2YV9saXN0IGFwOworICB2YV9zdGFydChhcCwgZm9ybWF0KTsKKyAgU3RyaW5nQXBwZW5kVihkc3QsIGZvcm1hdCwgYXApOworICB2YV9lbmQoYXApOworfQorCisvLyBNYXggYXJndW1lbnRzIHN1cHBvcnRlZCBieSBTdHJpbmdQcmludFZlY3RvcgorY29uc3QgaW50IGtTdHJpbmdQcmludGZWZWN0b3JNYXhBcmdzID0gMzI7CisKKy8vIEFuIGVtcHR5IGJsb2NrIG9mIHplcm8gZm9yIGZpbGxlciBhcmd1bWVudHMuICBUaGlzIGlzIGNvbnN0IHNvIHRoYXQgaWYKKy8vIHByaW50ZiB0cmllcyB0byB3cml0ZSB0byBpdCAodmlhICVuKSB0aGVuIHRoZSBwcm9ncmFtIGdldHMgYSBTSUdTRUdWCisvLyBhbmQgd2UgY2FuIGZpeCB0aGUgcHJvYmxlbSBvciBwcm90ZWN0IGFnYWluc3QgYW4gYXR0YWNrLgorc3RhdGljIGNvbnN0IGNoYXIgc3RyaW5nX3ByaW50Zl9lbXB0eV9ibG9ja1syNTZdID0geyAnXDAnIH07CisKK3N0cmluZyBTdHJpbmdQcmludGZWZWN0b3IoY29uc3QgY2hhciogZm9ybWF0LCBjb25zdCB2ZWN0b3I8c3RyaW5nPiYgdikgeworICBHT09HTEVfQ0hFQ0tfTEUodi5zaXplKCksIGtTdHJpbmdQcmludGZWZWN0b3JNYXhBcmdzKQorICAgICAgPDwgIlN0cmluZ1ByaW50ZlZlY3RvciBjdXJyZW50bHkgb25seSBzdXBwb3J0cyB1cCB0byAiCisgICAgICA8PCBrU3RyaW5nUHJpbnRmVmVjdG9yTWF4QXJncyA8PCAiIGFyZ3VtZW50cy4gIgorICAgICAgPDwgIkZlZWwgZnJlZSB0byBhZGQgc3VwcG9ydCBmb3IgbW9yZSBpZiB5b3UgbmVlZCBpdC4iOworCisgIC8vIEFkZCBmaWxsZXIgYXJndW1lbnRzIHNvIHRoYXQgYm9ndXMgZm9ybWF0K2FyZ3MgaGF2ZSBhIGhhcmRlciB0aW1lCisgIC8vIGNyYXNoaW5nIHRoZSBwcm9ncmFtLCBjb3JydXB0aW5nIHRoZSBwcm9ncmFtICglbiksCisgIC8vIG9yIGRpc3BsYXlpbmcgcmFuZG9tIGNodW5rcyBvZiBtZW1vcnkgdG8gdXNlcnMuCisKKyAgY29uc3QgY2hhciogY3N0cltrU3RyaW5nUHJpbnRmVmVjdG9yTWF4QXJnc107CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdi5zaXplKCk7ICsraSkgeworICAgIGNzdHJbaV0gPSB2W2ldLmNfc3RyKCk7CisgIH0KKyAgZm9yIChpbnQgaSA9IHYuc2l6ZSgpOyBpIDwgR09PR0xFX0FSUkFZU0laRShjc3RyKTsgKytpKSB7CisgICAgY3N0cltpXSA9ICZzdHJpbmdfcHJpbnRmX2VtcHR5X2Jsb2NrWzBdOworICB9CisKKyAgLy8gSSBkbyBub3Qga25vdyBhbnkgd2F5IHRvIHBhc3Mga1N0cmluZ1ByaW50ZlZlY3Rvck1heEFyZ3MgYXJndW1lbnRzLAorICAvLyBvciBhbnkgd2F5IHRvIGJ1aWxkIGEgdmFfbGlzdCBieSBoYW5kLCBvciBhbnkgQVBJIGZvciBwcmludGYKKyAgLy8gdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFyZ3VtZW50cy4gIFRoZSBiZXN0IEkgY2FuIGRvIGlzIHN0aWNrCisgIC8vIHRoaXMgQ09NUElMRV9BU1NFUlQgcmlnaHQgbmV4dCB0byB0aGUgYWN0dWFsIHN0YXRlbWVudC4KKworICBHT09HTEVfQ09NUElMRV9BU1NFUlQoa1N0cmluZ1ByaW50ZlZlY3Rvck1heEFyZ3MgPT0gMzIsIGFyZ19jb3VudF9taXNtYXRjaCk7CisgIHJldHVybiBTdHJpbmdQcmludGYoZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgIGNzdHJbMF0sIGNzdHJbMV0sIGNzdHJbMl0sIGNzdHJbM10sIGNzdHJbNF0sCisgICAgICAgICAgICAgICAgICAgICAgY3N0cls1XSwgY3N0cls2XSwgY3N0cls3XSwgY3N0cls4XSwgY3N0cls5XSwKKyAgICAgICAgICAgICAgICAgICAgICBjc3RyWzEwXSwgY3N0clsxMV0sIGNzdHJbMTJdLCBjc3RyWzEzXSwgY3N0clsxNF0sCisgICAgICAgICAgICAgICAgICAgICAgY3N0clsxNV0sIGNzdHJbMTZdLCBjc3RyWzE3XSwgY3N0clsxOF0sIGNzdHJbMTldLAorICAgICAgICAgICAgICAgICAgICAgIGNzdHJbMjBdLCBjc3RyWzIxXSwgY3N0clsyMl0sIGNzdHJbMjNdLCBjc3RyWzI0XSwKKyAgICAgICAgICAgICAgICAgICAgICBjc3RyWzI1XSwgY3N0clsyNl0sIGNzdHJbMjddLCBjc3RyWzI4XSwgY3N0clsyOV0sCisgICAgICAgICAgICAgICAgICAgICAgY3N0clszMF0sIGNzdHJbMzFdKTsKK30KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWIxYWI1NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmgKQEAgLTAsMCArMSw3NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy9iYXNlL3N0cmluZ3ByaW50Zi5oCisvLworLy8gUHJpbnRmIHZhcmlhbnRzIHRoYXQgcGxhY2UgdGhlaXIgb3V0cHV0IGluIGEgQysrIHN0cmluZy4KKy8vCisvLyBVc2FnZToKKy8vICAgICAgc3RyaW5nIHJlc3VsdCA9IFN0cmluZ1ByaW50ZigiJWQgJXNcbiIsIDEwLCAiaGVsbG8iKTsKKy8vICAgICAgU1N0cmluZ1ByaW50ZigmcmVzdWx0LCAiJWQgJXNcbiIsIDEwLCAiaGVsbG8iKTsKKy8vICAgICAgU3RyaW5nQXBwZW5kRigmcmVzdWx0LCAiJWQgJXNcbiIsIDIwLCAidGhlcmUiKTsKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RSSU5HUFJJTlRGX0gKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUUklOR1BSSU5URl9ICisKKyNpbmNsdWRlIDxzdGRhcmcuaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIFJldHVybiBhIEMrKyBzdHJpbmcKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gc3RyaW5nIFN0cmluZ1ByaW50Zihjb25zdCBjaGFyKiBmb3JtYXQsIC4uLik7CisKKy8vIFN0b3JlIHJlc3VsdCBpbnRvIGEgc3VwcGxpZWQgc3RyaW5nIGFuZCByZXR1cm4gaXQKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gY29uc3Qgc3RyaW5nJiBTU3RyaW5nUHJpbnRmKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIC4uLik7CisKKy8vIEFwcGVuZCByZXN1bHQgdG8gYSBzdXBwbGllZCBzdHJpbmcKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gdm9pZCBTdHJpbmdBcHBlbmRGKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIC4uLik7CisKKy8vIExvd2VyLWxldmVsIHJvdXRpbmUgdGhhdCB0YWtlcyBhIHZhX2xpc3QgYW5kIGFwcGVuZHMgdG8gYSBzcGVjaWZpZWQKKy8vIHN0cmluZy4gIEFsbCBvdGhlciByb3V0aW5lcyBhcmUganVzdCBjb252ZW5pZW5jZSB3cmFwcGVycyBhcm91bmQgaXQuCitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIHZvaWQgU3RyaW5nQXBwZW5kVihzdHJpbmcqIGRzdCwgY29uc3QgY2hhciogZm9ybWF0LCB2YV9saXN0IGFwKTsKKworLy8gVGhlIG1heCBhcmd1bWVudHMgc3VwcG9ydGVkIGJ5IFN0cmluZ1ByaW50ZlZlY3RvcgorTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBjb25zdCBpbnQga1N0cmluZ1ByaW50ZlZlY3Rvck1heEFyZ3M7CisKKy8vIFlvdSBjYW4gdXNlIHRoaXMgdmVyc2lvbiB3aGVuIGFsbCB5b3VyIGFyZ3VtZW50cyBhcmUgc3RyaW5ncywgYnV0CisvLyB5b3UgZG9uJ3Qga25vdyBob3cgbWFueSBhcmd1bWVudHMgeW91J2xsIGhhdmUgYXQgY29tcGlsZSB0aW1lLgorLy8gU3RyaW5nUHJpbnRmVmVjdG9yIHdpbGwgTE9HKEZBVEFMKSBpZiB2LnNpemUoKSA+IGtTdHJpbmdQcmludGZWZWN0b3JNYXhBcmdzCitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIHN0cmluZyBTdHJpbmdQcmludGZWZWN0b3IoY29uc3QgY2hhciogZm9ybWF0LCBjb25zdCB2ZWN0b3I8c3RyaW5nPiYgdik7CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVFJJTkdQUklOVEZfSApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNTg5NWU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBmcm9tIGdvb2dsZTMvYmFzZS9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKworI2luY2x1ZGUgPGNlcnJubz4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBFbXB0eSkgeworI2lmIDAKKyAgLy8gZ2NjIDIuOTUuMywgZ2NjIDQuMS4wLCBhbmQgZ2NjIDQuMi4yIGFsbCB3YXJuIGFib3V0IHRoaXM6CisgIC8vIHdhcm5pbmc6IHplcm8tbGVuZ3RoIHByaW50ZiBmb3JtYXQgc3RyaW5nLgorICAvLyBzbyB3ZSBkbyBub3QgYWxsb3cgdGhlbSBpbiBnb29nbGUzLgorICBFWFBFQ1RfRVEoIiIsIFN0cmluZ1ByaW50ZigiIikpOworI2VuZGlmCisgIEVYUEVDVF9FUSgiIiwgU3RyaW5nUHJpbnRmKCIlcyIsIHN0cmluZygpLmNfc3RyKCkpKTsKKyAgRVhQRUNUX0VRKCIiLCBTdHJpbmdQcmludGYoIiVzIiwgIiIpKTsKK30KKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBNaXNjKSB7CisvLyBNU1ZDIGFuZCBtaW5ndyBkb2VzIG5vdCBzdXBwb3J0ICQgZm9ybWF0IHNwZWNpZmllci4KKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgJiYgIWRlZmluZWQoX19NSU5HVzMyX18pCisgIEVYUEVDVF9FUSgiMTIzaGVsbG8gdyIsIFN0cmluZ1ByaW50ZigiJTMkZCUyJHMgJTEkYyIsICd3JywgImhlbGxvIiwgMTIzKSk7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorfQorCitURVNUKFN0cmluZ0FwcGVuZEZUZXN0LCBFbXB0eSkgeworICBzdHJpbmcgdmFsdWUoIkhlbGxvIik7CisgIGNvbnN0IGNoYXIqIGVtcHR5ID0gIiI7CisgIFN0cmluZ0FwcGVuZEYoJnZhbHVlLCAiJXMiLCBlbXB0eSk7CisgIEVYUEVDVF9FUSgiSGVsbG8iLCB2YWx1ZSk7Cit9CisKK1RFU1QoU3RyaW5nQXBwZW5kRlRlc3QsIEVtcHR5U3RyaW5nKSB7CisgIHN0cmluZyB2YWx1ZSgiSGVsbG8iKTsKKyAgU3RyaW5nQXBwZW5kRigmdmFsdWUsICIlcyIsICIiKTsKKyAgRVhQRUNUX0VRKCJIZWxsbyIsIHZhbHVlKTsKK30KKworVEVTVChTdHJpbmdBcHBlbmRGVGVzdCwgU3RyaW5nKSB7CisgIHN0cmluZyB2YWx1ZSgiSGVsbG8iKTsKKyAgU3RyaW5nQXBwZW5kRigmdmFsdWUsICIgJXMiLCAiV29ybGQiKTsKKyAgRVhQRUNUX0VRKCJIZWxsbyBXb3JsZCIsIHZhbHVlKTsKK30KKworVEVTVChTdHJpbmdBcHBlbmRGVGVzdCwgSW50KSB7CisgIHN0cmluZyB2YWx1ZSgiSGVsbG8iKTsKKyAgU3RyaW5nQXBwZW5kRigmdmFsdWUsICIgJWQiLCAxMjMpOworICBFWFBFQ1RfRVEoIkhlbGxvIDEyMyIsIHZhbHVlKTsKK30KKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBNdWx0aWJ5dGUpIHsKKyAgLy8gSWYgd2UgYXJlIGluIG11bHRpYnl0ZSBtb2RlIGFuZCBmZWVkIGludmFsaWQgbXVsdGlieXRlIHNlcXVlbmNlLAorICAvLyBTdHJpbmdQcmludGYgc2hvdWxkIHJldHVybiBhbiBlbXB0eSBzdHJpbmcgaW5zdGVhZCBvZiBydW5uaW5nCisgIC8vIG91dCBvZiBtZW1vcnkgd2hpbGUgdHJ5aW5nIHRvIGRldGVybWluZSBkZXN0aW5hdGlvbiBidWZmZXIgc2l6ZS4KKyAgLy8gc2VlIGIvNDE5NDU0My4KKworICBjaGFyKiBvbGRfbG9jYWxlID0gc2V0bG9jYWxlKExDX0NUWVBFLCBOVUxMKTsKKyAgLy8gUHVzaCBsb2NhbGUgd2l0aCBtdWx0aWJ5dGUgbW9kZQorICBzZXRsb2NhbGUoTENfQ1RZUEUsICJlbl9VUy51dGY4Iik7CisKKyAgY29uc3QgY2hhciBrSW52YWxpZENvZGVQb2ludFtdID0gIlwzNzVcMDY3cyI7CisgIHN0cmluZyB2YWx1ZSA9IFN0cmluZ1ByaW50ZigiJS4qcyIsIDMsIGtJbnZhbGlkQ29kZVBvaW50KTsKKworICAvLyBJbiBzb21lIHZlcnNpb25zIG9mIGdsaWJjIChlLmcuIGVnbGliYy0yLjExLjEsIGFrYSBHUlRFdjIpLCBzbnByaW50ZgorICAvLyByZXR1cm5zIGVycm9yIGdpdmVuIGFuIGludmFsaWQgY29kZXBvaW50LiBPdGhlciB2ZXJzaW9ucworICAvLyAoZS5nLiBlZ2xpYmMtMi4xNSwgYWthIHByZS1HUlRFdjMpIGVtaXQgdGhlIGNvZGVwb2ludCB2ZXJiYXRpbS4KKyAgLy8gV2UgdGVzdCB0aGF0IHRoZSBvdXRwdXQgaXMgb25lIG9mIHRoZSBhYm92ZS4KKyAgRVhQRUNUX1RSVUUodmFsdWUuZW1wdHkoKSB8fCB2YWx1ZSA9PSBrSW52YWxpZENvZGVQb2ludCk7CisKKyAgLy8gUmVwZWF0IHdpdGggbG9uZ2VyIHN0cmluZywgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGR5bmFtaWNhbGx5CisgIC8vIGFsbG9jYXRlZCBwYXRoIGluIFN0cmluZ0FwcGVuZFYgaXMgaGFuZGxlZCBjb3JyZWN0bHkuCisgIGludCBuID0gMjA0ODsKKyAgY2hhciogYnVmID0gbmV3IGNoYXJbbisxXTsKKyAgbWVtc2V0KGJ1ZiwgJyAnLCBuLTMpOworICBtZW1jcHkoYnVmICsgbiAtIDMsIGtJbnZhbGlkQ29kZVBvaW50LCA0KTsKKyAgdmFsdWUgPSAgU3RyaW5nUHJpbnRmKCIlLipzIiwgbiwgYnVmKTsKKyAgLy8gU2VlIEdSVEV2MiB2cy4gR1JURXYzIGNvbW1lbnQgYWJvdmUuCisgIEVYUEVDVF9UUlVFKHZhbHVlLmVtcHR5KCkgfHwgdmFsdWUgPT0gYnVmKTsKKyAgZGVsZXRlW10gYnVmOworCisgIHNldGxvY2FsZShMQ19DVFlQRSwgb2xkX2xvY2FsZSk7Cit9CisKK1RFU1QoU3RyaW5nUHJpbnRmVGVzdCwgTm9NdWx0aWJ5dGUpIHsKKyAgLy8gTm8gbXVsdGlieXRlIGhhbmRsaW5nLCBidXQgdGhlIHN0cmluZyBjb250YWlucyBmdW5ueSBjaGFycy4KKyAgY2hhciogb2xkX2xvY2FsZSA9IHNldGxvY2FsZShMQ19DVFlQRSwgTlVMTCk7CisgIHNldGxvY2FsZShMQ19DVFlQRSwgIlBPU0lYIik7CisgIHN0cmluZyB2YWx1ZSA9IFN0cmluZ1ByaW50ZigiJS4qcyIsIDMsICJcMzc1XDA2N3MiKTsKKyAgc2V0bG9jYWxlKExDX0NUWVBFLCBvbGRfbG9jYWxlKTsKKyAgRVhQRUNUX0VRKCJcMzc1XDA2N3MiLCB2YWx1ZSk7Cit9CisKK1RFU1QoU3RyaW5nUHJpbnRmVGVzdCwgRG9udE92ZXJ3cml0ZUVycm5vKSB7CisgIC8vIENoZWNrIHRoYXQgZXJybm8gaXNuJ3Qgb3ZlcndyaXR0ZW4gdW5sZXNzIHdlJ3JlIHByaW50aW5nCisgIC8vIHNvbWV0aGluZyBzaWduaWZpY2FudGx5IGxhcmdlciB0aGFuIHdoYXQgcGVvcGxlIGFyZSBub3JtYWxseQorICAvLyBwcmludGluZyBpbiB0aGVpciBiYWRseSB3cml0dGVuIFBMT0coKSBzdGF0ZW1lbnRzLgorICBlcnJubyA9IEVDSElMRDsKKyAgc3RyaW5nIHZhbHVlID0gU3RyaW5nUHJpbnRmKCJIZWxsbywgJXMhIiwgIldvcmxkIik7CisgIEVYUEVDVF9FUShFQ0hJTEQsIGVycm5vKTsKK30KKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBMYXJnZUJ1ZikgeworICAvLyBDaGVjayB0aGF0IHRoZSBsYXJnZSBidWZmZXIgaXMgaGFuZGxlZCBjb3JyZWN0bHkuCisgIGludCBuID0gMjA0ODsKKyAgY2hhciogYnVmID0gbmV3IGNoYXJbbisxXTsKKyAgbWVtc2V0KGJ1ZiwgJyAnLCBuKTsKKyAgYnVmW25dID0gMDsKKyAgc3RyaW5nIHZhbHVlID0gU3RyaW5nUHJpbnRmKCIlcyIsIGJ1Zik7CisgIEVYUEVDVF9FUShidWYsIHZhbHVlKTsKKyAgZGVsZXRlW10gYnVmOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGY2YWZlNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkLmNjCkBAIC0wLDAgKzEsNTM2IEBACisvLyBDb3B5cmlnaHQgMjAwNS0yMDA4IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisvLyBBdXRob3I6IGpybUBnb29nbGUuY29tIChKaW0gTWVlaGFuKQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBUaGVzZSBmb3VyLWJ5dGUgZW50cmllcyBjb21wYWN0bHkgZW5jb2RlIGhvdyBtYW55IGJ5dGVzIDAuLjI1NSB0byBkZWxldGUKKy8vIGluIG1ha2luZyBhIHN0cmluZyByZXBsYWNlbWVudCwgaG93IG1hbnkgYnl0ZXMgdG8gYWRkIDAuLjI1NSwgYW5kIHRoZSBvZmZzZXQKKy8vIDAuLjY0ay0xIG9mIHRoZSByZXBsYWNlbWVudCBzdHJpbmcgaW4gcmVtYXBfc3RyaW5nLgorc3RydWN0IFJlbWFwRW50cnkgeworICB1aW50OCBkZWxldGVfYnl0ZXM7CisgIHVpbnQ4IGFkZF9ieXRlczsKKyAgdWludDE2IGJ5dGVzX29mZnNldDsKK307CisKKy8vIEV4aXQgdHlwZSBjb2RlcyBmb3Igc3RhdGUgdGFibGVzLiBBbGwgYnV0IHRoZSBmaXJzdCBnZXQgc3R1ZmZlZCBpbnRvCisvLyBzaWduZWQgb25lLWJ5dGUgZW50cmllcy4gVGhlIGZpcnN0IGlzIG9ubHkgZ2VuZXJhdGVkIGJ5IGV4ZWN1dGFibGUgY29kZS4KKy8vIFRvIGRpc3Rpbmd1aXNoIGZyb20gbmV4dC1zdGF0ZSBlbnRyaWVzLCB0aGVzZSBtdXN0IGJlIGNvbnRpZ3VvdXMgYW5kCisvLyBhbGwgPD0ga0V4aXROb25lCit0eXBlZGVmIGVudW0geworICBrRXhpdERzdFNwYWNlRnVsbCA9IDIzOSwKKyAga0V4aXRJbGxlZ2FsU3RydWN0dXJlLCAgLy8gMjQwCisgIGtFeGl0T0ssICAgICAgICAgICAgICAgIC8vIDI0MQorICBrRXhpdFJlamVjdCwgICAgICAgICAgICAvLyAuLi4KKyAga0V4aXRSZXBsYWNlMSwKKyAga0V4aXRSZXBsYWNlMiwKKyAga0V4aXRSZXBsYWNlMywKKyAga0V4aXRSZXBsYWNlMjEsCisgIGtFeGl0UmVwbGFjZTMxLAorICBrRXhpdFJlcGxhY2UzMiwKKyAga0V4aXRSZXBsYWNlT2Zmc2V0MSwKKyAga0V4aXRSZXBsYWNlT2Zmc2V0MiwKKyAga0V4aXRSZXBsYWNlMVMwLAorICBrRXhpdFNwZWNpYWwsCisgIGtFeGl0RG9BZ2FpbiwKKyAga0V4aXRSZWplY3RBbHQsCisgIGtFeGl0Tm9uZSAgICAgICAgICAgICAgIC8vIDI1NQorfSBFeGl0UmVhc29uOworCisKKy8vIFRoaXMgc3RydWN0IHJlcHJlc2VudHMgb25lIGVudGlyZSBzdGF0ZSB0YWJsZS4gVGhlIHRocmVlIGluaXRpYWxpemVkIGJ5dGUKKy8vIGFyZWFzIGFyZSBzdGF0ZV90YWJsZSwgcmVtYXBfYmFzZSwgYW5kIHJlbWFwX3N0cmluZy4gc3RhdGUwIGFuZCBzdGF0ZTBfc2l6ZQorLy8gZ2l2ZSB0aGUgYnl0ZSBvZmZzZXQgYW5kIGxlbmd0aCB3aXRoaW4gc3RhdGVfdGFibGUgb2YgdGhlIGluaXRpYWwgc3RhdGUgLS0KKy8vIHRhYmxlIGxvb2t1cHMgYXJlIGV4cGVjdGVkIHRvIHN0YXJ0IGFuZCBlbmQgaW4gdGhpcyBzdGF0ZSwgYnV0IGZvcgorLy8gdHJ1bmNhdGVkIFVURi04IHN0cmluZ3MsIG1heSBlbmQgaW4gYSBkaWZmZXJlbnQgc3RhdGUuIFRoZXNlIGFsbG93IGEgcXVpY2sKKy8vIHRlc3QgZm9yIHRoYXQgY29uZGl0aW9uLiBlbnRyeV9zaGlmdCBpcyA4IGZvciB0YWJsZXMgc3Vic2NyaXB0ZWQgYnkgYSBmdWxsCisvLyBieXRlIHZhbHVlIGFuZCA2IGZvciBzcGFjZS1vcHRpbWl6ZWQgdGFibGVzIHN1YnNjcmlwdGVkIGJ5IG9ubHkgc2l4CisvLyBzaWduaWZpY2FudCBiaXRzIGluIFVURi04IGNvbnRpbnVhdGlvbiBieXRlcy4KK3R5cGVkZWYgc3RydWN0IHsKKyAgY29uc3QgdWludDMyIHN0YXRlMDsKKyAgY29uc3QgdWludDMyIHN0YXRlMF9zaXplOworICBjb25zdCB1aW50MzIgdG90YWxfc2l6ZTsKKyAgY29uc3QgaW50IG1heF9leHBhbmQ7CisgIGNvbnN0IGludCBlbnRyeV9zaGlmdDsKKyAgY29uc3QgaW50IGJ5dGVzX3Blcl9lbnRyeTsKKyAgY29uc3QgdWludDMyIGxvc3ViOworICBjb25zdCB1aW50MzIgaGlhZGQ7CisgIGNvbnN0IHVpbnQ4KiBzdGF0ZV90YWJsZTsKKyAgY29uc3QgUmVtYXBFbnRyeSogcmVtYXBfYmFzZTsKKyAgY29uc3QgdWludDgqIHJlbWFwX3N0cmluZzsKKyAgY29uc3QgdWludDgqIGZhc3Rfc3RhdGU7Cit9IFVURjhTdGF0ZU1hY2hpbmVPYmo7CisKK3R5cGVkZWYgVVRGOFN0YXRlTWFjaGluZU9iaiBVVEY4U2Nhbk9iajsKKworI2RlZmluZSBYX18gKGtFeGl0SWxsZWdhbFN0cnVjdHVyZSkKKyNkZWZpbmUgUkpfIChrRXhpdFJlamVjdCkKKyNkZWZpbmUgUzFfIChrRXhpdFJlcGxhY2UxKQorI2RlZmluZSBTMl8gKGtFeGl0UmVwbGFjZTIpCisjZGVmaW5lIFMzXyAoa0V4aXRSZXBsYWNlMykKKyNkZWZpbmUgUzIxIChrRXhpdFJlcGxhY2UyMSkKKyNkZWZpbmUgUzMxIChrRXhpdFJlcGxhY2UzMSkKKyNkZWZpbmUgUzMyIChrRXhpdFJlcGxhY2UzMikKKyNkZWZpbmUgVDFfIChrRXhpdFJlcGxhY2VPZmZzZXQxKQorI2RlZmluZSBUMl8gKGtFeGl0UmVwbGFjZU9mZnNldDIpCisjZGVmaW5lIFMxMSAoa0V4aXRSZXBsYWNlMVMwKQorI2RlZmluZSBTUF8gKGtFeGl0U3BlY2lhbCkKKyNkZWZpbmUgRF9fIChrRXhpdERvQWdhaW4pCisjZGVmaW5lIFJKQSAoa0V4aXRSZWplY3RBbHQpCisKKy8vICBFbnRpcmUgdGFibGUgaGFzIDkgc3RhdGUgYmxvY2tzIG9mIDI1NiBlbnRyaWVzIGVhY2gKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfU1RBVEUwID0gMDsgICAgIC8vIHN0YXRlWzBdCitzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1NUQVRFMF9TSVpFID0gMjU2OyAgLy8gPVsxXQorc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19UT1RBTF9TSVpFID0gMjMwNDsKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfTUFYX0VYUEFORF9YNCA9IDA7CitzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1NISUZUID0gODsKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfQllURVMgPSAxOworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19MT1NVQiA9IDB4MjAyMDIwMjA7CitzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX0hJQUREID0gMHgwMDAwMDAwMDsKKworc3RhdGljIGNvbnN0IHVpbnQ4IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzW10gPSB7CisvLyBzdGF0ZVswXSAweDAwMDAwMCBCeXRlIDEKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorICAyLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICA3LCAgIDMsICAgMywKKyAgNCwgICA1LCAgIDUsICAgNSwgICA2LCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKy8vIHN0YXRlWzFdIDB4MDAwMDgwIEJ5dGUgMiBvZiAyCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisvLyBzdGF0ZVsyXSAweDAwMDAwMCBCeXRlIDIgb2YgMworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworLy8gc3RhdGVbM10gMHgwMDEwMDAgQnl0ZSAyIG9mIDMKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKyAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwKKyAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKy8vIHN0YXRlWzRdIDB4MDAwMDAwIEJ5dGUgMiBvZiA0CitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywKKyAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsCisgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisvLyBzdGF0ZVs1XSAweDA0MDAwMCBCeXRlIDIgb2YgNAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywKKyAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsCisgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLAorICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworLy8gc3RhdGVbNl0gMHgxMDAwMDAgQnl0ZSAyIG9mIDQKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKyAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKy8vIHN0YXRlWzddIDB4MDBkMDAwIEJ5dGUgMiBvZiAzCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwKKyAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsCisgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisvLyBzdGF0ZVs4XSAweDAwZDgwMCBCeXRlIDMgb2YgMworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sICBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywKK1JKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCAgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sCitSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLAorUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sICBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK307CisKKy8vIFJlbWFwIGJhc2VbMF0gPSAoZGVsLCBhZGQsIHN0cmluZ19vZmZzZXQpCitzdGF0aWMgY29uc3QgUmVtYXBFbnRyeSB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19yZW1hcF9iYXNlW10gPSB7Cit7MCwgMCwgMH0gfTsKKworLy8gUmVtYXAgc3RyaW5nWzBdCitzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19yZW1hcF9zdHJpbmdbXSA9IHsKKzAgfTsKKworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfZmFzdFsyNTZdID0geworMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisKKzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorCisxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKzEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKworMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKzEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCit9OworCitzdGF0aWMgY29uc3QgVVRGOFNjYW5PYmogdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfb2JqID0geworICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19TVEFURTAsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1NUQVRFMF9TSVpFLAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19UT1RBTF9TSVpFLAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19NQVhfRVhQQU5EX1g0LAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19TSElGVCwKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfQllURVMsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX0xPU1VCLAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19ISUFERCwKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXMsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX3JlbWFwX2Jhc2UsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX3JlbWFwX3N0cmluZywKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfZmFzdAorfTsKKworCisjdW5kZWYgWF9fCisjdW5kZWYgUkpfCisjdW5kZWYgUzFfCisjdW5kZWYgUzJfCisjdW5kZWYgUzNfCisjdW5kZWYgUzIxCisjdW5kZWYgUzMxCisjdW5kZWYgUzMyCisjdW5kZWYgVDFfCisjdW5kZWYgVDJfCisjdW5kZWYgUzExCisjdW5kZWYgU1BfCisjdW5kZWYgRF9fCisjdW5kZWYgUkpBCisKKy8vIFJldHVybiB0cnVlIGlmIGN1cnJlbnQgVGJsIHBvaW50ZXIgaXMgd2l0aGluIHN0YXRlMCByYW5nZQorLy8gTm90ZSB0aGF0IHVuc2lnbmVkIGNvbXBhcmUgY2hlY2tzIGJvdGggZW5kcyBvZiByYW5nZSBzaW11bHRhbmVvdXNseQorc3RhdGljIGlubGluZSBib29sIEluU3RhdGVaZXJvKGNvbnN0IFVURjhTY2FuT2JqKiBzdCwgY29uc3QgdWludDgqIFRibCkgeworICBjb25zdCB1aW50OCogVGJsMCA9ICZzdC0+c3RhdGVfdGFibGVbc3QtPnN0YXRlMF07CisgIHJldHVybiAoc3RhdGljX2Nhc3Q8dWludDMyPihUYmwgLSBUYmwwKSA8IHN0LT5zdGF0ZTBfc2l6ZSk7Cit9CisKKy8vIFNjYW4gYSBVVEYtOCBzdHJpbmcgYmFzZWQgb24gc3RhdGUgdGFibGUuCisvLyBBbHdheXMgc2NhbiBjb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXJzCisvLyBTZXQgbnVtYmVyIG9mIGJ5dGVzIHNjYW5uZWQuIFJldHVybiByZWFzb24gZm9yIGV4aXRpbmcKK2ludCBVVEY4R2VuZXJpY1NjYW4oY29uc3QgVVRGOFNjYW5PYmoqIHN0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogc3RyLAorICAgICAgICAgICAgICAgICAgICBpbnQgc3RyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgaW50KiBieXRlc19jb25zdW1lZCkgeworICAqYnl0ZXNfY29uc3VtZWQgPSAwOworICBpZiAoc3RyX2xlbmd0aCA9PSAwKSByZXR1cm4ga0V4aXRPSzsKKworICBpbnQgZXNoaWZ0ID0gc3QtPmVudHJ5X3NoaWZ0OworICBjb25zdCB1aW50OCogaXNyYyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihzdHIpOworICBjb25zdCB1aW50OCogc3JjID0gaXNyYzsKKyAgY29uc3QgdWludDgqIHNyY2xpbWl0ID0gaXNyYyArIHN0cl9sZW5ndGg7CisgIGNvbnN0IHVpbnQ4KiBzcmNsaW1pdDggPSBzcmNsaW1pdCAtIDc7CisgIGNvbnN0IHVpbnQ4KiBUYmxfMCA9ICZzdC0+c3RhdGVfdGFibGVbc3QtPnN0YXRlMF07CisKKyBEb0FnYWluOgorICAvLyBEbyBzdGF0ZS10YWJsZSBzY2FuCisgIGludCBlID0gMDsKKyAgdWludDggYzsKKyAgY29uc3QgdWludDgqIFRibDIgPSAmc3QtPmZhc3Rfc3RhdGVbMF07CisgIGNvbnN0IHVpbnQzMiBsb3N1YiA9IHN0LT5sb3N1YjsKKyAgY29uc3QgdWludDMyIGhpYWRkID0gc3QtPmhpYWRkOworICAvLyBDaGVjayBpbml0aWFsIGZldyBieXRlcyBvbmUgYXQgYSB0aW1lIHVudGlsIDgtYnl0ZSBhbGlnbmVkCisgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB3aGlsZSAoKCgodWludHB0cl90KXNyYyAmIDB4MDcpICE9IDApICYmCisgICAgICAgICAoc3JjIDwgc3JjbGltaXQpICYmCisgICAgICAgICBUYmwyW3NyY1swXV0gPT0gMCkgeworICAgIHNyYysrOworICB9CisgIGlmICgoKHVpbnRwdHJfdClzcmMgJiAweDA3KSA9PSAwKSB7CisgICAgLy8gRG8gZmFzdCBmb3IgZ3JvdXBzIG9mIDggaWRlbnRpdHkgYnl0ZXMuCisgICAgLy8gVGhpcyBjb3ZlcnMgYSBsb3Qgb2YgNy1iaXQgQVNDSUkgfjh4IGZhc3RlciB0aGVuIHRoZSAxLWJ5dGUgbG9vcCwKKyAgICAvLyBpbmNsdWRpbmcgc2xvd2luZyBzbGlnaHRseSBvbiBjci9sZi9odAorICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIHdoaWxlIChzcmMgPCBzcmNsaW1pdDgpIHsKKyAgICAgIHVpbnQzMiBzMDEyMyA9IChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQzMiAqPihzcmMpKVswXTsKKyAgICAgIHVpbnQzMiBzNDU2NyA9IChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQzMiAqPihzcmMpKVsxXTsKKyAgICAgIHNyYyArPSA4OworICAgICAgLy8gVGhpcyBpcyBhIGZhc3QgcmFuZ2UgY2hlY2sgZm9yIGFsbCBieXRlcyBpbiBbbG93c3ViLi4weDgwLWhpYWRkKQorICAgICAgdWludDMyIHRlbXAgPSAoczAxMjMgLSBsb3N1YikgfCAoczAxMjMgKyBoaWFkZCkgfAorICAgICAgICAgICAgICAgICAgICAoczQ1NjcgLSBsb3N1YikgfCAoczQ1NjcgKyBoaWFkZCk7CisgICAgICBpZiAoKHRlbXAgJiAweDgwODA4MDgwKSAhPSAwKSB7CisgICAgICAgIC8vIFdlIHR5cGljYWxseSBlbmQgdXAgaGVyZSBvbiBjci9sZi9odDsgc3JjIHdhcyBpbmNyZW1lbnRlZAorICAgICAgICBpbnQgZTAxMjMgPSAoVGJsMltzcmNbLThdXSB8IFRibDJbc3JjWy03XV0pIHwKKyAgICAgICAgICAgICAgICAgICAgKFRibDJbc3JjWy02XV0gfCBUYmwyW3NyY1stNV1dKTsKKyAgICAgICAgaWYgKGUwMTIzICE9IDApIHsKKyAgICAgICAgICBzcmMgLT0gODsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfSAgICAvLyBFeGl0IG9uIE5vbi1pbnRlcmNoYW5nZQorICAgICAgICBlMDEyMyA9IChUYmwyW3NyY1stNF1dIHwgVGJsMltzcmNbLTNdXSkgfAorICAgICAgICAgICAgICAgIChUYmwyW3NyY1stMl1dIHwgVGJsMltzcmNbLTFdXSk7CisgICAgICAgIGlmIChlMDEyMyAhPSAwKSB7CisgICAgICAgICAgc3JjIC09IDQ7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0gICAgLy8gRXhpdCBvbiBOb24taW50ZXJjaGFuZ2UKKyAgICAgICAgLy8gRWxzZSBPSywgZ28gYXJvdW5kIGFnYWluCisgICAgICB9CisgICAgfQorICB9CisgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEJ5dGUtYXQtYS10aW1lIHNjYW4KKyAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGNvbnN0IHVpbnQ4KiBUYmwgPSBUYmxfMDsKKyAgd2hpbGUgKHNyYyA8IHNyY2xpbWl0KSB7CisgICAgYyA9ICpzcmM7CisgICAgZSA9IFRibFtjXTsKKyAgICBzcmMrKzsKKyAgICBpZiAoZSA+PSBrRXhpdElsbGVnYWxTdHJ1Y3R1cmUpIHticmVhazt9CisgICAgVGJsID0gJlRibF8wW2UgPDwgZXNoaWZ0XTsKKyAgfQorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworCisgIC8vIEV4aXQgcG9zaWJpbGl0aWVzOgorICAvLyAgU29tZSBleGl0IGNvZGUsICFzdGF0ZTAsIGJhY2sgdXAgb3ZlciBsYXN0IGNoYXIKKyAgLy8gIFNvbWUgZXhpdCBjb2RlLCBzdGF0ZTAsIGJhY2sgdXAgb25lIGJ5dGUgZXhhY3RseQorICAvLyAgc291cmNlIGNvbnN1bWVkLCAhc3RhdGUwLCBiYWNrIHVwIG92ZXIgcGFydGlhbCBjaGFyCisgIC8vICBzb3VyY2UgY29uc3VtZWQsIHN0YXRlMCwgZXhpdCBPSworICAvLyBGb3IgaWxsZWdhbCBieXRlIGluIHN0YXRlMCwgYXZvaWQgYmFja3VwIHVwIG92ZXIgUFJFVklPVVMgY2hhcgorICAvLyBGb3IgdHJ1bmNhdGVkIGxhc3QgY2hhciwgYmFjayB1cCB0byBiZWdpbm5pbmcgb2YgaXQKKworICBpZiAoZSA+PSBrRXhpdElsbGVnYWxTdHJ1Y3R1cmUpIHsKKyAgICAvLyBCYWNrIHVwIG92ZXIgZXhhY3RseSBvbmUgYnl0ZSBvZiByZWplY3RlZC9pbGxlZ2FsIFVURi04IGNoYXJhY3RlcgorICAgIHNyYy0tOworICAgIC8vIEJhY2sgdXAgbW9yZSBpZiBuZWVkZWQKKyAgICBpZiAoIUluU3RhdGVaZXJvKHN0LCBUYmwpKSB7CisgICAgICBkbyB7CisgICAgICAgIHNyYy0tOworICAgICAgfSB3aGlsZSAoKHNyYyA+IGlzcmMpICYmICgoc3JjWzBdICYgMHhjMCkgPT0gMHg4MCkpOworICAgIH0KKyAgfSBlbHNlIGlmICghSW5TdGF0ZVplcm8oc3QsIFRibCkpIHsKKyAgICAvLyBCYWNrIHVwIG92ZXIgdHJ1bmNhdGVkIFVURi04IGNoYXJhY3RlcgorICAgIGUgPSBrRXhpdElsbGVnYWxTdHJ1Y3R1cmU7CisgICAgZG8geworICAgICAgc3JjLS07CisgICAgfSB3aGlsZSAoKHNyYyA+IGlzcmMpICYmICgoc3JjWzBdICYgMHhjMCkgPT0gMHg4MCkpOworICB9IGVsc2UgeworICAgIC8vIE5vcm1hbCB0ZXJtaW5hdGlvbiwgc291cmNlIGZ1bGx5IGNvbnN1bWVkCisgICAgZSA9IGtFeGl0T0s7CisgIH0KKworICBpZiAoZSA9PSBrRXhpdERvQWdhaW4pIHsKKyAgICAvLyBMb29wIGJhY2sgdXAgdG8gdGhlIGZhc3Qgc2NhbgorICAgIGdvdG8gRG9BZ2FpbjsKKyAgfQorCisgICpieXRlc19jb25zdW1lZCA9IHNyYyAtIGlzcmM7CisgIHJldHVybiBlOworfQorCitpbnQgVVRGOEdlbmVyaWNTY2FuRmFzdEFzY2lpKGNvbnN0IFVURjhTY2FuT2JqKiBzdCwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqIHN0ciwKKyAgICAgICAgICAgICAgICAgICAgaW50IHN0cl9sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgIGludCogYnl0ZXNfY29uc3VtZWQpIHsKKyAgKmJ5dGVzX2NvbnN1bWVkID0gMDsKKyAgaWYgKHN0cl9sZW5ndGggPT0gMCkgcmV0dXJuIGtFeGl0T0s7CisKKyAgY29uc3QgdWludDgqIGlzcmMgPSAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KHN0cik7CisgIGNvbnN0IHVpbnQ4KiBzcmMgPSBpc3JjOworICBjb25zdCB1aW50OCogc3JjbGltaXQgPSBpc3JjICsgc3RyX2xlbmd0aDsKKyAgY29uc3QgdWludDgqIHNyY2xpbWl0OCA9IHNyY2xpbWl0IC0gNzsKKyAgaW50IG47CisgIGludCByZXN0X2NvbnN1bWVkOworICBpbnQgZXhpdF9yZWFzb247CisgIGRvIHsKKyAgICAvLyBDaGVjayBpbml0aWFsIGZldyBieXRlcyBvbmUgYXQgYSB0aW1lIHVudGlsIDgtYnl0ZSBhbGlnbmVkCisgICAgd2hpbGUgKCgoKHVpbnRwdHJfdClzcmMgJiAweDA3KSAhPSAwKSAmJgorICAgICAgICAgICAoc3JjIDwgc3JjbGltaXQpICYmIChzcmNbMF0gPCAweDgwKSkgeworICAgICAgc3JjKys7CisgICAgfQorICAgIGlmICgoKHVpbnRwdHJfdClzcmMgJiAweDA3KSA9PSAwKSB7CisgICAgICB3aGlsZSAoKHNyYyA8IHNyY2xpbWl0OCkgJiYKKyAgICAgICAgICAgICAoKChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQzMio+KHNyYylbMF0gfAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyKj4oc3JjKVsxXSkgJiAweDgwODA4MDgwKSA9PSAwKSkgeworICAgICAgICBzcmMgKz0gODsKKyAgICAgIH0KKyAgICB9CisgICAgd2hpbGUgKChzcmMgPCBzcmNsaW1pdCkgJiYgKHNyY1swXSA8IDB4ODApKSB7CisgICAgICBzcmMrKzsKKyAgICB9CisgICAgLy8gUnVuIHN0YXRlIHRhYmxlIG9uIHRoZSByZXN0CisgICAgbiA9IHNyYyAtIGlzcmM7CisgICAgZXhpdF9yZWFzb24gPSBVVEY4R2VuZXJpY1NjYW4oc3QsIHN0ciArIG4sIHN0cl9sZW5ndGggLSBuLCAmcmVzdF9jb25zdW1lZCk7CisgICAgc3JjICs9IHJlc3RfY29uc3VtZWQ7CisgIH0gd2hpbGUgKCBleGl0X3JlYXNvbiA9PSBrRXhpdERvQWdhaW4gKTsKKworICAqYnl0ZXNfY29uc3VtZWQgPSBzcmMgLSBpc3JjOworICByZXR1cm4gZXhpdF9yZWFzb247Cit9CisKKy8vIEhhY2s6ICBPbiBzb21lIGNvbXBpbGVycyB0aGUgc3RhdGljIHRhYmxlcyBhcmUgaW5pdGlhbGl6ZWQgYXQgc3RhcnR1cC4KKy8vICAgV2UgY2FuJ3QgdXNlIHRoZW0gdW50aWwgdGhleSBhcmUgaW5pdGlhbGl6ZWQuICBIb3dldmVyLCBzb21lIFByb3RvY29sCisvLyAgIEJ1ZmZlciBwYXJzaW5nIGhhcHBlbnMgYXQgc3RhdGljIGluaXQgdGltZSBhbmQgbWF5IHRyeSB0byB2YWxpZGF0ZQorLy8gICBVVEYtOCBzdHJpbmdzLiAgU2luY2UgVVRGLTggdmFsaWRhdGlvbiBpcyBvbmx5IHVzZWQgZm9yIGRlYnVnZ2luZworLy8gICBhbnl3YXksIHdlIHNpbXBseSBhbHdheXMgcmV0dXJuIHN1Y2Nlc3MgaWYgaW5pdGlhbGl6YXRpb24gaGFzbid0CisvLyAgIG9jY3VycmVkIHlldC4KK25hbWVzcGFjZSB7CisKK2Jvb2wgbW9kdWxlX2luaXRpYWxpemVkXyA9IGZhbHNlOworCitzdHJ1Y3QgSW5pdERldGVjdG9yIHsKKyAgSW5pdERldGVjdG9yKCkgeworICAgIG1vZHVsZV9pbml0aWFsaXplZF8gPSB0cnVlOworICB9Cit9OworSW5pdERldGVjdG9yIGluaXRfZGV0ZWN0b3I7CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGNvbnN0IGNoYXIqIGJ1ZiwgaW50IGxlbikgeworICBpZiAoIW1vZHVsZV9pbml0aWFsaXplZF8pIHJldHVybiB0cnVlOworICAKKyAgaW50IGJ5dGVzX2NvbnN1bWVkID0gMDsKKyAgVVRGOEdlbmVyaWNTY2FuRmFzdEFzY2lpKCZ1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19vYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsIGxlbiwgJmJ5dGVzX2NvbnN1bWVkKTsKKyAgcmV0dXJuIChieXRlc19jb25zdW1lZCA9PSBsZW4pOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWRfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnVjdHVyYWxseV92YWxpZF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDg4ODg4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWRfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw0MCBAQAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKy8vIEF1dGhvcjogeHBlbmdAZ29vZ2xlLmNvbSAoUGV0ZXIgUGVuZykKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworbmFtZXNwYWNlIHsKKworVEVTVChTdHJ1Y3R1cmFsbHlWYWxpZFRlc3QsIFZhbGlkVVRGOFN0cmluZykgeworICAvLyBPbiBHQ0MsIHRoaXMgc3RyaW5nIGNhbiBiZSB3cml0dGVuIGFzOgorICAvLyAgICJhYmNkIDEyMzQgLSBcdTIwMTRcdTIwMTNcdTIyMTIiCisgIC8vIE1TVkMgc2VlbXMgdG8gaW50ZXJwcmV0IFx1IGRpZmZlcmVudGx5LgorICBzdHJpbmcgdmFsaWRfc3RyKCJhYmNkIDEyMzQgLSBcMzQyXDIwMFwyMjRcMzQyXDIwMFwyMjNcMzQyXDIxMFwyMjIgLSB4eXo3ODkiKTsKKyAgRVhQRUNUX1RSVUUoSXNTdHJ1Y3R1cmFsbHlWYWxpZFVURjgodmFsaWRfc3RyLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRfc3RyLnNpemUoKSkpOworICAvLyBBZGRpdGlvbmFsIGNoZWNrIGZvciBwb2ludGVyIGFsaWdubWVudAorICBmb3IgKGludCBpID0gMTsgaSA8IDg7ICsraSkgeworICAgIEVYUEVDVF9UUlVFKElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KHZhbGlkX3N0ci5kYXRhKCkgKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkX3N0ci5zaXplKCkgLSBpKSk7CisgIH0KK30KKworVEVTVChTdHJ1Y3R1cmFsbHlWYWxpZFRlc3QsIEludmFsaWRVVEY4U3RyaW5nKSB7CisgIGNvbnN0IHN0cmluZyBpbnZhbGlkX3N0cigiYWJjZFx4QTBceEIwXHhBMFx4QjBceEEwXHhCMCAtIHh5ejc4OSIpOworICBFWFBFQ1RfRkFMU0UoSXNTdHJ1Y3R1cmFsbHlWYWxpZFVURjgoaW52YWxpZF9zdHIuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZF9zdHIuc2l6ZSgpKSk7CisgIC8vIEFkZGl0aW9uYWwgY2hlY2sgZm9yIHBvaW50ZXIgYWxpZ25tZW50CisgIGZvciAoaW50IGkgPSAxOyBpIDwgODsgKytpKSB7CisgICAgRVhQRUNUX0ZBTFNFKElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGludmFsaWRfc3RyLmRhdGEoKSArIGksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludmFsaWRfc3RyLnNpemUoKSAtIGkpKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzk1NWQyNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5jYwpAQCAtMCwwICsxLDE1NDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBmcm9tIGdvb2dsZTMvc3RyaW5ncy9zdHJ1dGlsLmNjCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8ZmxvYXQuaD4gICAgLy8gRkxUX0RJRyBhbmQgREJMX0RJRworI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxsaW1pdHMuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorCisjaWZkZWYgX1dJTjMyCisvLyBNU1ZDIGhhcyBvbmx5IF9zbnByaW50Ziwgbm90IHNucHJpbnRmLgorLy8KKy8vIE1pbkdXIGhhcyBib3RoIHNucHJpbnRmIGFuZCBfc25wcmludGYsIGJ1dCB0aGV5IGFwcGVhciB0byBiZSBkaWZmZXJlbnQKKy8vIGZ1bmN0aW9ucy4gIFRoZSBmb3JtZXIgaXMgYnVnZ3kuICBXaGVuIGludm9rZWQgbGlrZSBzbzoKKy8vICAgY2hhciBidWZmZXJbMzJdOworLy8gICBzbnByaW50ZihidWZmZXIsIDMyLCAiJS4qZ1xuIiwgRkxUX0RJRywgMS4yM2UxMGYpOworLy8gaXQgcHJpbnRzICIxLjIzMDAwZSsxMCIuICBUaGlzIGlzIHBsYWlubHkgd3Jvbmc6ICAlZyBzaG91bGQgbmV2ZXIgcHJpbnQKKy8vIHRyYWlsaW5nIHplcm9zIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LiAgRm9yIHNvbWUgcmVhc29uIHRoaXMgYnVnIG9ubHkKKy8vIG9jY3VycyB3aXRoIHNvbWUgaW5wdXQgdmFsdWVzLCBub3QgYWxsLiAgSW4gYW55IGNhc2UsIF9zbnByaW50ZiBkb2VzIHRoZQorLy8gcmlnaHQgdGhpbmcsIHNvIHdlIHVzZSBpdC4KKyNkZWZpbmUgc25wcmludGYgX3NucHJpbnRmCisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitpbmxpbmUgYm9vbCBJc05hTihkb3VibGUgdmFsdWUpIHsKKyAgLy8gTmFOIGlzIG5ldmVyIGVxdWFsIHRvIGFueXRoaW5nLCBldmVuIGl0c2VsZi4KKyAgcmV0dXJuIHZhbHVlICE9IHZhbHVlOworfQorCisvLyBUaGVzZSBhcmUgZGVmaW5lZCBhcyBtYWNyb3Mgb24gc29tZSBwbGF0Zm9ybXMuICAjdW5kZWYgdGhlbSBzbyB0aGF0IHdlIGNhbgorLy8gcmVkZWZpbmUgdGhlbS4KKyN1bmRlZiBpc3hkaWdpdAorI3VuZGVmIGlzcHJpbnQKKworLy8gVGhlIGRlZmluaXRpb25zIG9mIHRoZXNlIGluIGN0eXBlLmggY2hhbmdlIGJhc2VkIG9uIGxvY2FsZS4gIFNpbmNlIG91cgorLy8gc3RyaW5nIG1hbmlwdWxhdGlvbiBpcyBhbGwgaW4gcmVsYXRpb24gdG8gdGhlIHByb3RvY29sIGJ1ZmZlciBhbmQgQysrCisvLyBsYW5ndWFnZXMsIHdlIGFsd2F5cyB3YW50IHRvIHVzZSB0aGUgQyBsb2NhbGUuICBTbywgd2UgcmUtZGVmaW5lIHRoZXNlCisvLyBleGFjdGx5IGFzIHdlIHdhbnQgdGhlbS4KK2lubGluZSBib29sIGlzeGRpZ2l0KGNoYXIgYykgeworICByZXR1cm4gKCcwJyA8PSBjICYmIGMgPD0gJzknKSB8fAorICAgICAgICAgKCdhJyA8PSBjICYmIGMgPD0gJ2YnKSB8fAorICAgICAgICAgKCdBJyA8PSBjICYmIGMgPD0gJ0YnKTsKK30KKworaW5saW5lIGJvb2wgaXNwcmludChjaGFyIGMpIHsKKyAgcmV0dXJuIGMgPj0gMHgyMCAmJiBjIDw9IDB4N0U7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFN0cmlwU3RyaW5nCisvLyAgICBSZXBsYWNlcyBhbnkgb2NjdXJyZW5jZSBvZiB0aGUgY2hhcmFjdGVyICdyZW1vdmUnIChvciB0aGUgY2hhcmFjdGVycworLy8gICAgaW4gJ3JlbW92ZScpIHdpdGggdGhlIGNoYXJhY3RlciAncmVwbGFjZXdpdGgnLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQordm9pZCBTdHJpcFN0cmluZyhzdHJpbmcqIHMsIGNvbnN0IGNoYXIqIHJlbW92ZSwgY2hhciByZXBsYWNld2l0aCkgeworICBjb25zdCBjaGFyICogc3RyX3N0YXJ0ID0gcy0+Y19zdHIoKTsKKyAgY29uc3QgY2hhciAqIHN0ciA9IHN0cl9zdGFydDsKKyAgZm9yIChzdHIgPSBzdHJwYnJrKHN0ciwgcmVtb3ZlKTsKKyAgICAgICBzdHIgIT0gTlVMTDsKKyAgICAgICBzdHIgPSBzdHJwYnJrKHN0ciArIDEsIHJlbW92ZSkpIHsKKyAgICAoKnMpW3N0ciAtIHN0cl9zdGFydF0gPSByZXBsYWNld2l0aDsKKyAgfQorfQorCit2b2lkIFN0cmlwV2hpdGVzcGFjZShzdHJpbmcqIHN0cikgeworICBpbnQgc3RyX2xlbmd0aCA9IHN0ci0+bGVuZ3RoKCk7CisKKyAgLy8gU3RyaXAgb2ZmIGxlYWRpbmcgd2hpdGVzcGFjZS4KKyAgaW50IGZpcnN0ID0gMDsKKyAgd2hpbGUgKGZpcnN0IDwgc3RyX2xlbmd0aCAmJiBhc2NpaV9pc3NwYWNlKHN0ci0+YXQoZmlyc3QpKSkgeworICAgICsrZmlyc3Q7CisgIH0KKyAgLy8gSWYgZW50aXJlIHN0cmluZyBpcyB3aGl0ZSBzcGFjZS4KKyAgaWYgKGZpcnN0ID09IHN0cl9sZW5ndGgpIHsKKyAgICBzdHItPmNsZWFyKCk7CisgICAgcmV0dXJuOworICB9CisgIGlmIChmaXJzdCA+IDApIHsKKyAgICBzdHItPmVyYXNlKDAsIGZpcnN0KTsKKyAgICBzdHJfbGVuZ3RoIC09IGZpcnN0OworICB9CisKKyAgLy8gU3RyaXAgb2ZmIHRyYWlsaW5nIHdoaXRlc3BhY2UuCisgIGludCBsYXN0ID0gc3RyX2xlbmd0aCAtIDE7CisgIHdoaWxlIChsYXN0ID49IDAgJiYgYXNjaWlfaXNzcGFjZShzdHItPmF0KGxhc3QpKSkgeworICAgIC0tbGFzdDsKKyAgfQorICBpZiAobGFzdCAhPSAoc3RyX2xlbmd0aCAtIDEpICYmIGxhc3QgPj0gMCkgeworICAgIHN0ci0+ZXJhc2UobGFzdCArIDEsIHN0cmluZzo6bnBvcyk7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyaW5nUmVwbGFjZSgpCisvLyAgICBSZXBsYWNlIHRoZSAib2xkIiBwYXR0ZXJuIHdpdGggdGhlICJuZXciIHBhdHRlcm4gaW4gYSBzdHJpbmcsCisvLyAgICBhbmQgYXBwZW5kIHRoZSByZXN1bHQgdG8gInJlcyIuICBJZiByZXBsYWNlX2FsbCBpcyBmYWxzZSwKKy8vICAgIGl0IG9ubHkgcmVwbGFjZXMgdGhlIGZpcnN0IGluc3RhbmNlIG9mICJvbGQuIgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFN0cmluZ1JlcGxhY2UoY29uc3Qgc3RyaW5nJiBzLCBjb25zdCBzdHJpbmcmIG9sZHN1YiwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5ld3N1YiwgYm9vbCByZXBsYWNlX2FsbCwKKyAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHJlcykgeworICBpZiAob2xkc3ViLmVtcHR5KCkpIHsKKyAgICByZXMtPmFwcGVuZChzKTsgIC8vIGlmIGVtcHR5LCBhcHBlbmQgdGhlIGdpdmVuIHN0cmluZy4KKyAgICByZXR1cm47CisgIH0KKworICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydF9wb3MgPSAwOworICBzdHJpbmc6OnNpemVfdHlwZSBwb3M7CisgIGRvIHsKKyAgICBwb3MgPSBzLmZpbmQob2xkc3ViLCBzdGFydF9wb3MpOworICAgIGlmIChwb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICBicmVhazsKKyAgICB9CisgICAgcmVzLT5hcHBlbmQocywgc3RhcnRfcG9zLCBwb3MgLSBzdGFydF9wb3MpOworICAgIHJlcy0+YXBwZW5kKG5ld3N1Yik7CisgICAgc3RhcnRfcG9zID0gcG9zICsgb2xkc3ViLnNpemUoKTsgIC8vIHN0YXJ0IHNlYXJjaGluZyBhZ2FpbiBhZnRlciB0aGUgIm9sZCIKKyAgfSB3aGlsZSAocmVwbGFjZV9hbGwpOworICByZXMtPmFwcGVuZChzLCBzdGFydF9wb3MsIHMubGVuZ3RoKCkgLSBzdGFydF9wb3MpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTdHJpbmdSZXBsYWNlKCkKKy8vICAgIEdpdmUgbWUgYSBzdHJpbmcgYW5kIHR3byBwYXR0ZXJucyAib2xkIiBhbmQgIm5ldyIsIGFuZCBJIHJlcGxhY2UKKy8vICAgIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiAib2xkIiBpbiB0aGUgc3RyaW5nIHdpdGggIm5ldyIsIGlmIGl0CisvLyAgICBleGlzdHMuICBJZiAiZ2xvYmFsIiBpcyB0cnVlOyBjYWxsIHRoaXMgcmVwZWF0ZWRseSB1bnRpbCBpdAorLy8gICAgZmFpbHMuICBSRVRVUk4gYSBuZXcgc3RyaW5nLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIHJlcGxhY2VtZW50CisvLyAgICBoYXBwZW5lZCBvciBub3QuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cmluZyBTdHJpbmdSZXBsYWNlKGNvbnN0IHN0cmluZyYgcywgY29uc3Qgc3RyaW5nJiBvbGRzdWIsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5ld3N1YiwgYm9vbCByZXBsYWNlX2FsbCkgeworICBzdHJpbmcgcmV0OworICBTdHJpbmdSZXBsYWNlKHMsIG9sZHN1YiwgbmV3c3ViLCByZXBsYWNlX2FsbCwgJnJldCk7CisgIHJldHVybiByZXQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNwbGl0U3RyaW5nVXNpbmcoKQorLy8gICAgU3BsaXQgYSBzdHJpbmcgdXNpbmcgYSBjaGFyYWN0ZXIgZGVsaW1pdGVyLiBBcHBlbmQgdGhlIGNvbXBvbmVudHMKKy8vICAgIHRvICdyZXN1bHQnLgorLy8KKy8vIE5vdGU6IEZvciBtdWx0aS1jaGFyYWN0ZXIgZGVsaW1pdGVycywgdGhpcyByb3V0aW5lIHdpbGwgc3BsaXQgb24gKkFOWSogb2YKKy8vIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcsIG5vdCB0aGUgZW50aXJlIHN0cmluZyBhcyBhIHNpbmdsZSBkZWxpbWl0ZXIuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit0ZW1wbGF0ZSA8dHlwZW5hbWUgSVRSPgorc3RhdGljIGlubGluZQordm9pZCBTcGxpdFN0cmluZ1RvSXRlcmF0b3JVc2luZyhjb25zdCBzdHJpbmcmIGZ1bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGRlbGltLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVFImIHJlc3VsdCkgeworICAvLyBPcHRpbWl6ZSB0aGUgY29tbW9uIGNhc2Ugd2hlcmUgZGVsaW0gaXMgYSBzaW5nbGUgY2hhcmFjdGVyLgorICBpZiAoZGVsaW1bMF0gIT0gJ1wwJyAmJiBkZWxpbVsxXSA9PSAnXDAnKSB7CisgICAgY2hhciBjID0gZGVsaW1bMF07CisgICAgY29uc3QgY2hhciogcCA9IGZ1bGwuZGF0YSgpOworICAgIGNvbnN0IGNoYXIqIGVuZCA9IHAgKyBmdWxsLnNpemUoKTsKKyAgICB3aGlsZSAocCAhPSBlbmQpIHsKKyAgICAgIGlmICgqcCA9PSBjKSB7CisgICAgICAgICsrcDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbnN0IGNoYXIqIHN0YXJ0ID0gcDsKKyAgICAgICAgd2hpbGUgKCsrcCAhPSBlbmQgJiYgKnAgIT0gYyk7CisgICAgICAgICpyZXN1bHQrKyA9IHN0cmluZyhzdGFydCwgcCAtIHN0YXJ0KTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuOworICB9CisKKyAgc3RyaW5nOjpzaXplX3R5cGUgYmVnaW5faW5kZXgsIGVuZF9pbmRleDsKKyAgYmVnaW5faW5kZXggPSBmdWxsLmZpbmRfZmlyc3Rfbm90X29mKGRlbGltKTsKKyAgd2hpbGUgKGJlZ2luX2luZGV4ICE9IHN0cmluZzo6bnBvcykgeworICAgIGVuZF9pbmRleCA9IGZ1bGwuZmluZF9maXJzdF9vZihkZWxpbSwgYmVnaW5faW5kZXgpOworICAgIGlmIChlbmRfaW5kZXggPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICAqcmVzdWx0KysgPSBmdWxsLnN1YnN0cihiZWdpbl9pbmRleCk7CisgICAgICByZXR1cm47CisgICAgfQorICAgICpyZXN1bHQrKyA9IGZ1bGwuc3Vic3RyKGJlZ2luX2luZGV4LCAoZW5kX2luZGV4IC0gYmVnaW5faW5kZXgpKTsKKyAgICBiZWdpbl9pbmRleCA9IGZ1bGwuZmluZF9maXJzdF9ub3Rfb2YoZGVsaW0sIGVuZF9pbmRleCk7CisgIH0KK30KKwordm9pZCBTcGxpdFN0cmluZ1VzaW5nKGNvbnN0IHN0cmluZyYgZnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSwKKyAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogcmVzdWx0KSB7CisgIGJhY2tfaW5zZXJ0X2l0ZXJhdG9yPCB2ZWN0b3I8c3RyaW5nPiA+IGl0KCpyZXN1bHQpOworICBTcGxpdFN0cmluZ1RvSXRlcmF0b3JVc2luZyhmdWxsLCBkZWxpbSwgaXQpOworfQorCisvLyBTcGxpdCBhIHN0cmluZyB1c2luZyBhIGNoYXJhY3RlciBkZWxpbWl0ZXIuIEFwcGVuZCB0aGUgY29tcG9uZW50cworLy8gdG8gJ3Jlc3VsdCcuICBJZiB0aGVyZSBhcmUgY29uc2VjdXRpdmUgZGVsaW1pdGVycywgdGhpcyBmdW5jdGlvbgorLy8gd2lsbCByZXR1cm4gY29ycmVzcG9uZGluZyBlbXB0eSBzdHJpbmdzLiBUaGUgc3RyaW5nIGlzIHNwbGl0IGludG8KKy8vIGF0IG1vc3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgcGllY2VzIGdyZWVkaWx5LiBUaGlzIG1lYW5zIHRoYXQgdGhlCisvLyBsYXN0IHBpZWNlIG1heSBwb3NzaWJseSBiZSBzcGxpdCBmdXJ0aGVyLiBUbyBzcGxpdCBpbnRvIGFzIG1hbnkgcGllY2VzCisvLyBhcyBwb3NzaWJsZSwgc3BlY2lmeSAwIGFzIHRoZSBudW1iZXIgb2YgcGllY2VzLgorLy8KKy8vIElmICJmdWxsIiBpcyB0aGUgZW1wdHkgc3RyaW5nLCB5aWVsZHMgYW4gZW1wdHkgc3RyaW5nIGFzIHRoZSBvbmx5IHZhbHVlLgorLy8KKy8vIElmICJwaWVjZXMiIGlzIG5lZ2F0aXZlIGZvciBzb21lIHJlYXNvbiwgaXQgcmV0dXJucyB0aGUgd2hvbGUgc3RyaW5nCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3RyaW5nVHlwZSwgdHlwZW5hbWUgSVRSPgorc3RhdGljIGlubGluZQordm9pZCBTcGxpdFN0cmluZ1RvSXRlcmF0b3JBbGxvd0VtcHR5KGNvbnN0IFN0cmluZ1R5cGUmIGZ1bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBpZWNlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVFImIHJlc3VsdCkgeworICBzdHJpbmc6OnNpemVfdHlwZSBiZWdpbl9pbmRleCwgZW5kX2luZGV4OworICBiZWdpbl9pbmRleCA9IDA7CisKKyAgZm9yIChpbnQgaSA9IDA7IChpIDwgcGllY2VzLTEpIHx8IChwaWVjZXMgPT0gMCk7IGkrKykgeworICAgIGVuZF9pbmRleCA9IGZ1bGwuZmluZF9maXJzdF9vZihkZWxpbSwgYmVnaW5faW5kZXgpOworICAgIGlmIChlbmRfaW5kZXggPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICAqcmVzdWx0KysgPSBmdWxsLnN1YnN0cihiZWdpbl9pbmRleCk7CisgICAgICByZXR1cm47CisgICAgfQorICAgICpyZXN1bHQrKyA9IGZ1bGwuc3Vic3RyKGJlZ2luX2luZGV4LCAoZW5kX2luZGV4IC0gYmVnaW5faW5kZXgpKTsKKyAgICBiZWdpbl9pbmRleCA9IGVuZF9pbmRleCArIDE7CisgIH0KKyAgKnJlc3VsdCsrID0gZnVsbC5zdWJzdHIoYmVnaW5faW5kZXgpOworfQorCit2b2lkIFNwbGl0U3RyaW5nQWxsb3dFbXB0eShjb25zdCBzdHJpbmcmIGZ1bGwsIGNvbnN0IGNoYXIqIGRlbGltLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHJlc3VsdCkgeworICBiYWNrX2luc2VydF9pdGVyYXRvcjx2ZWN0b3I8c3RyaW5nPiA+IGl0KCpyZXN1bHQpOworICBTcGxpdFN0cmluZ1RvSXRlcmF0b3JBbGxvd0VtcHR5KGZ1bGwsIGRlbGltLCAwLCBpdCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEpvaW5TdHJpbmdzKCkKKy8vICAgIFRoaXMgbWVyZ2VzIGEgdmVjdG9yIG9mIHN0cmluZyBjb21wb25lbnRzIHdpdGggZGVsaW0gaW5zZXJ0ZWQKKy8vICAgIGFzIHNlcGFyYXRlcnMgYmV0d2VlbiBjb21wb25lbnRzLgorLy8KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3RlbXBsYXRlIDxjbGFzcyBJVEVSQVRPUj4KK3N0YXRpYyB2b2lkIEpvaW5TdHJpbmdzSXRlcmF0b3IoY29uc3QgSVRFUkFUT1ImIHN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJVEVSQVRPUiYgZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiByZXN1bHQpIHsKKyAgR09PR0xFX0NIRUNLKHJlc3VsdCAhPSBOVUxMKTsKKyAgcmVzdWx0LT5jbGVhcigpOworICBpbnQgZGVsaW1fbGVuZ3RoID0gc3RybGVuKGRlbGltKTsKKworICAvLyBQcmVjb21wdXRlIHJlc3VsdGluZyBsZW5ndGggc28gd2UgY2FuIHJlc2VydmUoKSBtZW1vcnkgaW4gb25lIHNob3QuCisgIGludCBsZW5ndGggPSAwOworICBmb3IgKElURVJBVE9SIGl0ZXIgPSBzdGFydDsgaXRlciAhPSBlbmQ7ICsraXRlcikgeworICAgIGlmIChpdGVyICE9IHN0YXJ0KSB7CisgICAgICBsZW5ndGggKz0gZGVsaW1fbGVuZ3RoOworICAgIH0KKyAgICBsZW5ndGggKz0gaXRlci0+c2l6ZSgpOworICB9CisgIHJlc3VsdC0+cmVzZXJ2ZShsZW5ndGgpOworCisgIC8vIE5vdyBjb21iaW5lIGV2ZXJ5dGhpbmcuCisgIGZvciAoSVRFUkFUT1IgaXRlciA9IHN0YXJ0OyBpdGVyICE9IGVuZDsgKytpdGVyKSB7CisgICAgaWYgKGl0ZXIgIT0gc3RhcnQpIHsKKyAgICAgIHJlc3VsdC0+YXBwZW5kKGRlbGltLCBkZWxpbV9sZW5ndGgpOworICAgIH0KKyAgICByZXN1bHQtPmFwcGVuZChpdGVyLT5kYXRhKCksIGl0ZXItPnNpemUoKSk7CisgIH0KK30KKwordm9pZCBKb2luU3RyaW5ncyhjb25zdCB2ZWN0b3I8c3RyaW5nPiYgY29tcG9uZW50cywKKyAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0sCisgICAgICAgICAgICAgICAgIHN0cmluZyAqIHJlc3VsdCkgeworICBKb2luU3RyaW5nc0l0ZXJhdG9yKGNvbXBvbmVudHMuYmVnaW4oKSwgY29tcG9uZW50cy5lbmQoKSwgZGVsaW0sIHJlc3VsdCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcygpCisvLyAgICBUaGlzIGRvZXMgYWxsIHRoZSB1bmVzY2FwaW5nIHRoYXQgQyBkb2VzOiBcb29vLCBcciwgXG4sIGV0YworLy8gICAgUmV0dXJucyBsZW5ndGggb2YgcmVzdWx0aW5nIHN0cmluZy4KKy8vICAgIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiBceCBwYXJzZXMgYW55IHBvc2l0aXZlIG51bWJlciBvZiBoZXggZGlnaXRzLAorLy8gICAgYnV0IGl0IGlzIGFuIGVycm9yIGlmIHRoZSB2YWx1ZSByZXF1aXJlcyBtb3JlIHRoYW4gOCBiaXRzLCBhbmQgdGhlCisvLyAgICByZXN1bHQgaXMgdHJ1bmNhdGVkIHRvIDggYml0cy4KKy8vCisvLyAgICBUaGUgc2Vjb25kIGNhbGwgc3RvcmVzIGl0cyBlcnJvcnMgaW4gYSBzdXBwbGllZCBzdHJpbmcgdmVjdG9yLgorLy8gICAgSWYgdGhlIHN0cmluZyB2ZWN0b3IgcG9pbnRlciBpcyBOVUxMLCBpdCByZXBvcnRzIHRoZSBlcnJvcnMgd2l0aCBMT0coKS4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBJU19PQ1RBTF9ESUdJVChjKSAoKChjKSA+PSAnMCcpICYmICgoYykgPD0gJzcnKSkKKworaW5saW5lIGludCBoZXhfZGlnaXRfdG9faW50KGNoYXIgYykgeworICAvKiBBc3N1bWUgQVNDSUkuICovCisgIGFzc2VydCgnMCcgPT0gMHgzMCAmJiAnQScgPT0gMHg0MSAmJiAnYScgPT0gMHg2MSk7CisgIGFzc2VydChpc3hkaWdpdChjKSk7CisgIGludCB4ID0gc3RhdGljX2Nhc3Q8dW5zaWduZWQgY2hhcj4oYyk7CisgIGlmICh4ID4gJzknKSB7CisgICAgeCArPSA5OworICB9CisgIHJldHVybiB4ICYgMHhmOworfQorCisvLyBQcm90b2NvbCBidWZmZXJzIGRvZXNuJ3QgZXZlciBjYXJlIGFib3V0IGVycm9ycywgYnV0IEkgZG9uJ3Qgd2FudCB0byByZW1vdmUKKy8vIHRoZSBjb2RlLgorI2RlZmluZSBMT0dfU1RSSU5HKExFVkVMLCBWRUNUT1IpIEdPT0dMRV9MT0dfSUYoTEVWRUwsIGZhbHNlKQorCitpbnQgVW5lc2NhcGVDRXNjYXBlU2VxdWVuY2VzKGNvbnN0IGNoYXIqIHNvdXJjZSwgY2hhciogZGVzdCkgeworICByZXR1cm4gVW5lc2NhcGVDRXNjYXBlU2VxdWVuY2VzKHNvdXJjZSwgZGVzdCwgTlVMTCk7Cit9CisKK2ludCBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMoY29uc3QgY2hhciogc291cmNlLCBjaGFyKiBkZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiAqZXJyb3JzKSB7CisgIEdPT0dMRV9EQ0hFQ0soZXJyb3JzID09IE5VTEwpIDw8ICJFcnJvciByZXBvcnRpbmcgbm90IGltcGxlbWVudGVkLiI7CisKKyAgY2hhciogZCA9IGRlc3Q7CisgIGNvbnN0IGNoYXIqIHAgPSBzb3VyY2U7CisKKyAgLy8gU21hbGwgb3B0aW1pemF0aW9uIGZvciBjYXNlIHdoZXJlIHNvdXJjZSA9IGRlc3QgYW5kIHRoZXJlJ3Mgbm8gZXNjYXBpbmcKKyAgd2hpbGUgKCBwID09IGQgJiYgKnAgIT0gJ1wwJyAmJiAqcCAhPSAnXFwnICkKKyAgICBwKyssIGQrKzsKKworICB3aGlsZSAoKnAgIT0gJ1wwJykgeworICAgIGlmICgqcCAhPSAnXFwnKSB7CisgICAgICAqZCsrID0gKnArKzsKKyAgICB9IGVsc2UgeworICAgICAgc3dpdGNoICggKisrcCApIHsgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgcGFzdCB0aGUgJ1xcJworICAgICAgICBjYXNlICdcMCc6CisgICAgICAgICAgTE9HX1NUUklORyhFUlJPUiwgZXJyb3JzKSA8PCAiU3RyaW5nIGNhbm5vdCBlbmQgd2l0aCBcXCI7CisgICAgICAgICAgKmQgPSAnXDAnOworICAgICAgICAgIHJldHVybiBkIC0gZGVzdDsgICAvLyB3ZSdyZSBkb25lIHdpdGggcAorICAgICAgICBjYXNlICdhJzogICpkKysgPSAnXGEnOyAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2InOiAgKmQrKyA9ICdcYic7ICBicmVhazsKKyAgICAgICAgY2FzZSAnZic6ICAqZCsrID0gJ1xmJzsgIGJyZWFrOworICAgICAgICBjYXNlICduJzogICpkKysgPSAnXG4nOyAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3InOiAgKmQrKyA9ICdccic7ICBicmVhazsKKyAgICAgICAgY2FzZSAndCc6ICAqZCsrID0gJ1x0JzsgIGJyZWFrOworICAgICAgICBjYXNlICd2JzogICpkKysgPSAnXHYnOyAgYnJlYWs7CisgICAgICAgIGNhc2UgJ1xcJzogKmQrKyA9ICdcXCc7ICBicmVhazsKKyAgICAgICAgY2FzZSAnPyc6ICAqZCsrID0gJ1w/JzsgIGJyZWFrOyAgICAvLyBcPyAgV2hvIGtuZXc/CisgICAgICAgIGNhc2UgJ1wnJzogKmQrKyA9ICdcJyc7ICBicmVhazsKKyAgICAgICAgY2FzZSAnIic6ICAqZCsrID0gJ1wiJzsgIGJyZWFrOworICAgICAgICBjYXNlICcwJzogY2FzZSAnMSc6IGNhc2UgJzInOiBjYXNlICczJzogIC8vIG9jdGFsIGRpZ2l0OiAxIHRvIDMgZGlnaXRzCisgICAgICAgIGNhc2UgJzQnOiBjYXNlICc1JzogY2FzZSAnNic6IGNhc2UgJzcnOiB7CisgICAgICAgICAgY2hhciBjaCA9ICpwIC0gJzAnOworICAgICAgICAgIGlmICggSVNfT0NUQUxfRElHSVQocFsxXSkgKQorICAgICAgICAgICAgY2ggPSBjaCAqIDggKyAqKytwIC0gJzAnOworICAgICAgICAgIGlmICggSVNfT0NUQUxfRElHSVQocFsxXSkgKSAgICAgIC8vIHNhZmUgKGFuZCBlYXN5KSB0byBkbyB0aGlzIHR3aWNlCisgICAgICAgICAgICBjaCA9IGNoICogOCArICorK3AgLSAnMCc7ICAgICAgLy8gbm93IHBvaW50cyBhdCBsYXN0IGRpZ2l0CisgICAgICAgICAgKmQrKyA9IGNoOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGNhc2UgJ3gnOiBjYXNlICdYJzogeworICAgICAgICAgIGlmICghaXN4ZGlnaXQocFsxXSkpIHsKKyAgICAgICAgICAgIGlmIChwWzFdID09ICdcMCcpIHsKKyAgICAgICAgICAgICAgTE9HX1NUUklORyhFUlJPUiwgZXJyb3JzKSA8PCAiU3RyaW5nIGNhbm5vdCBlbmQgd2l0aCBcXHgiOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgTE9HX1NUUklORyhFUlJPUiwgZXJyb3JzKSA8PAorICAgICAgICAgICAgICAgICJcXHggY2Fubm90IGJlIGZvbGxvd2VkIGJ5IG5vbi1oZXggZGlnaXQ6IFxcIiA8PCAqcCA8PCBwWzFdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIHVuc2lnbmVkIGludCBjaCA9IDA7CisgICAgICAgICAgY29uc3QgY2hhciAqaGV4X3N0YXJ0ID0gcDsKKyAgICAgICAgICB3aGlsZSAoaXN4ZGlnaXQocFsxXSkpICAvLyBhcmJpdHJhcmlseSBtYW55IGhleCBkaWdpdHMKKyAgICAgICAgICAgIGNoID0gKGNoIDw8IDQpICsgaGV4X2RpZ2l0X3RvX2ludCgqKytwKTsKKyAgICAgICAgICBpZiAoY2ggPiAweEZGKQorICAgICAgICAgICAgTE9HX1NUUklORyhFUlJPUiwgZXJyb3JzKSA8PCAiVmFsdWUgb2YgIiA8PAorICAgICAgICAgICAgICAiXFwiIDw8IHN0cmluZyhoZXhfc3RhcnQsIHArMS1oZXhfc3RhcnQpIDw8ICIgZXhjZWVkcyA4IGJpdHMiOworICAgICAgICAgICpkKysgPSBjaDsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorI2lmIDAgIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgXHUgYW5kIFxVPyAgUmVxdWlyZXMgcnVuZXRvY2hhcigpLgorICAgICAgICBjYXNlICd1JzogeworICAgICAgICAgIC8vIFx1aGhoaCA9PiBjb252ZXJ0IDQgaGV4IGRpZ2l0cyB0byBVVEYtOAorICAgICAgICAgIGNoYXIzMiBydW5lID0gMDsKKyAgICAgICAgICBjb25zdCBjaGFyICpoZXhfc3RhcnQgPSBwOworICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgKytpKSB7CisgICAgICAgICAgICBpZiAoaXN4ZGlnaXQocFsxXSkpIHsgIC8vIExvb2sgb25lIGNoYXIgYWhlYWQuCisgICAgICAgICAgICAgIHJ1bmUgPSAocnVuZSA8PCA0KSArIGhleF9kaWdpdF90b19pbnQoKisrcCk7ICAvLyBBZHZhbmNlIHAuCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBMT0dfU1RSSU5HKEVSUk9SLCBlcnJvcnMpCisgICAgICAgICAgICAgICAgPDwgIlxcdSBtdXN0IGJlIGZvbGxvd2VkIGJ5IDQgaGV4IGRpZ2l0czogXFwiCisgICAgICAgICAgICAgICAgPDwgIHN0cmluZyhoZXhfc3RhcnQsIHArMS1oZXhfc3RhcnQpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZCArPSBydW5ldG9jaGFyKGQsICZydW5lKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBjYXNlICdVJzogeworICAgICAgICAgIC8vIFxVaGhoaGhoaGggPT4gY29udmVydCA4IGhleCBkaWdpdHMgdG8gVVRGLTgKKyAgICAgICAgICBjaGFyMzIgcnVuZSA9IDA7CisgICAgICAgICAgY29uc3QgY2hhciAqaGV4X3N0YXJ0ID0gcDsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDg7ICsraSkgeworICAgICAgICAgICAgaWYgKGlzeGRpZ2l0KHBbMV0pKSB7ICAvLyBMb29rIG9uZSBjaGFyIGFoZWFkLgorICAgICAgICAgICAgICAvLyBEb24ndCBjaGFuZ2UgcnVuZSB1bnRpbCB3ZSdyZSBzdXJlIHRoaXMKKyAgICAgICAgICAgICAgLy8gaXMgd2l0aGluIHRoZSBVbmljb2RlIGxpbWl0LCBidXQgZG8gYWR2YW5jZSBwLgorICAgICAgICAgICAgICBjaGFyMzIgbmV3cnVuZSA9IChydW5lIDw8IDQpICsgaGV4X2RpZ2l0X3RvX2ludCgqKytwKTsKKyAgICAgICAgICAgICAgaWYgKG5ld3J1bmUgPiAweDEwRkZGRikgeworICAgICAgICAgICAgICAgIExPR19TVFJJTkcoRVJST1IsIGVycm9ycykKKyAgICAgICAgICAgICAgICAgIDw8ICJWYWx1ZSBvZiBcXCIKKyAgICAgICAgICAgICAgICAgIDw8IHN0cmluZyhoZXhfc3RhcnQsIHAgKyAxIC0gaGV4X3N0YXJ0KQorICAgICAgICAgICAgICAgICAgPDwgIiBleGNlZWRzIFVuaWNvZGUgbGltaXQgKDB4MTBGRkZGKSI7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcnVuZSA9IG5ld3J1bmU7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIExPR19TVFJJTkcoRVJST1IsIGVycm9ycykKKyAgICAgICAgICAgICAgICA8PCAiXFxVIG11c3QgYmUgZm9sbG93ZWQgYnkgOCBoZXggZGlnaXRzOiBcXCIKKyAgICAgICAgICAgICAgICA8PCAgc3RyaW5nKGhleF9zdGFydCwgcCsxLWhleF9zdGFydCk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBkICs9IHJ1bmV0b2NoYXIoZCwgJnJ1bmUpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBMT0dfU1RSSU5HKEVSUk9SLCBlcnJvcnMpIDw8ICJVbmtub3duIGVzY2FwZSBzZXF1ZW5jZTogXFwiIDw8ICpwOworICAgICAgfQorICAgICAgcCsrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlYWQgcGFzdCBsZXR0ZXIgd2UgZXNjYXBlZAorICAgIH0KKyAgfQorICAqZCA9ICdcMCc7CisgIHJldHVybiBkIC0gZGVzdDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVW5lc2NhcGVDRXNjYXBlU3RyaW5nKCkKKy8vICAgIFRoaXMgZG9lcyB0aGUgc2FtZSB0aGluZyBhcyBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMsIGJ1dCBjcmVhdGVzCisvLyAgICBhIG5ldyBzdHJpbmcuIFRoZSBjYWxsZXIgZG9lcyBub3QgbmVlZCB0byB3b3JyeSBhYm91dCBhbGxvY2F0aW5nCisvLyAgICBhIGRlc3QgYnVmZmVyLiBUaGlzIHNob3VsZCBiZSB1c2VkIGZvciBub24gcGVyZm9ybWFuY2UgY3JpdGljYWwKKy8vICAgIHRhc2tzIHN1Y2ggYXMgcHJpbnRpbmcgZGVidWcgbWVzc2FnZXMuIEl0IGlzIHNhZmUgZm9yIHNyYyBhbmQgZGVzdAorLy8gICAgdG8gYmUgdGhlIHNhbWUuCisvLworLy8gICAgVGhlIHNlY29uZCBjYWxsIHN0b3JlcyBpdHMgZXJyb3JzIGluIGEgc3VwcGxpZWQgc3RyaW5nIHZlY3Rvci4KKy8vICAgIElmIHRoZSBzdHJpbmcgdmVjdG9yIHBvaW50ZXIgaXMgTlVMTCwgaXQgcmVwb3J0cyB0aGUgZXJyb3JzIHdpdGggTE9HKCkuCisvLworLy8gICAgSW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgY2FsbHMsIHRoZSBsZW5ndGggb2YgZGVzdCBpcyByZXR1cm5lZC4gSW4gdGhlCisvLyAgICB0aGUgdGhpcmQgY2FsbCwgdGhlIG5ldyBzdHJpbmcgaXMgcmV0dXJuZWQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgVW5lc2NhcGVDRXNjYXBlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3JjLCBzdHJpbmcqIGRlc3QpIHsKKyAgcmV0dXJuIFVuZXNjYXBlQ0VzY2FwZVN0cmluZyhzcmMsIGRlc3QsIE5VTEwpOworfQorCitpbnQgVW5lc2NhcGVDRXNjYXBlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3JjLCBzdHJpbmcqIGRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+ICplcnJvcnMpIHsKKyAgc2NvcGVkX2FycmF5PGNoYXI+IHVuZXNjYXBlZChuZXcgY2hhcltzcmMuc2l6ZSgpICsgMV0pOworICBpbnQgbGVuID0gVW5lc2NhcGVDRXNjYXBlU2VxdWVuY2VzKHNyYy5jX3N0cigpLCB1bmVzY2FwZWQuZ2V0KCksIGVycm9ycyk7CisgIEdPT0dMRV9DSEVDSyhkZXN0KTsKKyAgZGVzdC0+YXNzaWduKHVuZXNjYXBlZC5nZXQoKSwgbGVuKTsKKyAgcmV0dXJuIGxlbjsKK30KKworc3RyaW5nIFVuZXNjYXBlQ0VzY2FwZVN0cmluZyhjb25zdCBzdHJpbmcmIHNyYykgeworICBzY29wZWRfYXJyYXk8Y2hhcj4gdW5lc2NhcGVkKG5ldyBjaGFyW3NyYy5zaXplKCkgKyAxXSk7CisgIGludCBsZW4gPSBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMoc3JjLmNfc3RyKCksIHVuZXNjYXBlZC5nZXQoKSwgTlVMTCk7CisgIHJldHVybiBzdHJpbmcodW5lc2NhcGVkLmdldCgpLCBsZW4pOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBDRXNjYXBlU3RyaW5nKCkKKy8vIENIZXhFc2NhcGVTdHJpbmcoKQorLy8gICAgQ29waWVzICdzcmMnIHRvICdkZXN0JywgZXNjYXBpbmcgZGFuZ2Vyb3VzIGNoYXJhY3RlcnMgdXNpbmcKKy8vICAgIEMtc3R5bGUgZXNjYXBlIHNlcXVlbmNlcy4gVGhpcyBpcyB2ZXJ5IHVzZWZ1bCBmb3IgcHJlcGFyaW5nIHF1ZXJ5CisvLyAgICBmbGFncy4gJ3NyYycgYW5kICdkZXN0JyBzaG91bGQgbm90IG92ZXJsYXAuIFRoZSAnSGV4JyB2ZXJzaW9uIHVzZXMKKy8vICAgIGhleGFkZWNpbWFsIHJhdGhlciB0aGFuIG9jdGFsIHNlcXVlbmNlcy4KKy8vICAgIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvICdkZXN0JyAobm90IGluY2x1ZGluZyB0aGUgXDApCisvLyAgICBvciAtMSBpZiB0aGVyZSB3YXMgaW5zdWZmaWNpZW50IHNwYWNlLgorLy8KKy8vICAgIEN1cnJlbnRseSBvbmx5IFxuLCBcciwgXHQsICIsICcsIFwgYW5kICFpc3ByaW50KCkgY2hhcnMgYXJlIGVzY2FwZWQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgQ0VzY2FwZUludGVybmFsKGNvbnN0IGNoYXIqIHNyYywgaW50IHNyY19sZW4sIGNoYXIqIGRlc3QsCisgICAgICAgICAgICAgICAgICAgIGludCBkZXN0X2xlbiwgYm9vbCB1c2VfaGV4LCBib29sIHV0Zjhfc2FmZSkgeworICBjb25zdCBjaGFyKiBzcmNfZW5kID0gc3JjICsgc3JjX2xlbjsKKyAgaW50IHVzZWQgPSAwOworICBib29sIGxhc3RfaGV4X2VzY2FwZSA9IGZhbHNlOyAvLyB0cnVlIGlmIGxhc3Qgb3V0cHV0IGNoYXIgd2FzIFx4Tk4KKworICBmb3IgKDsgc3JjIDwgc3JjX2VuZDsgc3JjKyspIHsKKyAgICBpZiAoZGVzdF9sZW4gLSB1c2VkIDwgMikgICAvLyBOZWVkIHNwYWNlIGZvciB0d28gbGV0dGVyIGVzY2FwZQorICAgICAgcmV0dXJuIC0xOworCisgICAgYm9vbCBpc19oZXhfZXNjYXBlID0gZmFsc2U7CisgICAgc3dpdGNoICgqc3JjKSB7CisgICAgICBjYXNlICdcbic6IGRlc3RbdXNlZCsrXSA9ICdcXCc7IGRlc3RbdXNlZCsrXSA9ICduJzsgIGJyZWFrOworICAgICAgY2FzZSAnXHInOiBkZXN0W3VzZWQrK10gPSAnXFwnOyBkZXN0W3VzZWQrK10gPSAncic7ICBicmVhazsKKyAgICAgIGNhc2UgJ1x0JzogZGVzdFt1c2VkKytdID0gJ1xcJzsgZGVzdFt1c2VkKytdID0gJ3QnOyAgYnJlYWs7CisgICAgICBjYXNlICdcIic6IGRlc3RbdXNlZCsrXSA9ICdcXCc7IGRlc3RbdXNlZCsrXSA9ICdcIic7IGJyZWFrOworICAgICAgY2FzZSAnXCcnOiBkZXN0W3VzZWQrK10gPSAnXFwnOyBkZXN0W3VzZWQrK10gPSAnXCcnOyBicmVhazsKKyAgICAgIGNhc2UgJ1xcJzogZGVzdFt1c2VkKytdID0gJ1xcJzsgZGVzdFt1c2VkKytdID0gJ1xcJzsgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICAvLyBOb3RlIHRoYXQgaWYgd2UgZW1pdCBceE5OIGFuZCB0aGUgc3JjIGNoYXJhY3RlciBhZnRlciB0aGF0IGlzIGEgaGV4CisgICAgICAgIC8vIGRpZ2l0IHRoZW4gdGhhdCBkaWdpdCBtdXN0IGJlIGVzY2FwZWQgdG9vIHRvIHByZXZlbnQgaXQgYmVpbmcKKyAgICAgICAgLy8gaW50ZXJwcmV0ZWQgYXMgcGFydCBvZiB0aGUgY2hhcmFjdGVyIGNvZGUgYnkgQy4KKyAgICAgICAgaWYgKCghdXRmOF9zYWZlIHx8IHN0YXRpY19jYXN0PHVpbnQ4Pigqc3JjKSA8IDB4ODApICYmCisgICAgICAgICAgICAoIWlzcHJpbnQoKnNyYykgfHwKKyAgICAgICAgICAgICAobGFzdF9oZXhfZXNjYXBlICYmIGlzeGRpZ2l0KCpzcmMpKSkpIHsKKyAgICAgICAgICBpZiAoZGVzdF9sZW4gLSB1c2VkIDwgNCkgLy8gbmVlZCBzcGFjZSBmb3IgNCBsZXR0ZXIgZXNjYXBlCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgc3ByaW50ZihkZXN0ICsgdXNlZCwgKHVzZV9oZXggPyAiXFx4JTAyeCIgOiAiXFwlMDNvIiksCisgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDx1aW50OD4oKnNyYykpOworICAgICAgICAgIGlzX2hleF9lc2NhcGUgPSB1c2VfaGV4OworICAgICAgICAgIHVzZWQgKz0gNDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBkZXN0W3VzZWQrK10gPSAqc3JjOyBicmVhazsKKyAgICAgICAgfQorICAgIH0KKyAgICBsYXN0X2hleF9lc2NhcGUgPSBpc19oZXhfZXNjYXBlOworICB9CisKKyAgaWYgKGRlc3RfbGVuIC0gdXNlZCA8IDEpICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlcmUgaXMgcm9vbSBmb3IgXDAKKyAgICByZXR1cm4gLTE7CisKKyAgZGVzdFt1c2VkXSA9ICdcMCc7ICAgLy8gZG9lc24ndCBjb3VudCB0b3dhcmRzIHJldHVybiB2YWx1ZSB0aG91Z2gKKyAgcmV0dXJuIHVzZWQ7Cit9CisKK2ludCBDRXNjYXBlU3RyaW5nKGNvbnN0IGNoYXIqIHNyYywgaW50IHNyY19sZW4sIGNoYXIqIGRlc3QsIGludCBkZXN0X2xlbikgeworICByZXR1cm4gQ0VzY2FwZUludGVybmFsKHNyYywgc3JjX2xlbiwgZGVzdCwgZGVzdF9sZW4sIGZhbHNlLCBmYWxzZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIENFc2NhcGUoKQorLy8gQ0hleEVzY2FwZSgpCisvLyAgICBDb3BpZXMgJ3NyYycgdG8gcmVzdWx0LCBlc2NhcGluZyBkYW5nZXJvdXMgY2hhcmFjdGVycyB1c2luZworLy8gICAgQy1zdHlsZSBlc2NhcGUgc2VxdWVuY2VzLiBUaGlzIGlzIHZlcnkgdXNlZnVsIGZvciBwcmVwYXJpbmcgcXVlcnkKKy8vICAgIGZsYWdzLiAnc3JjJyBhbmQgJ2Rlc3QnIHNob3VsZCBub3Qgb3ZlcmxhcC4gVGhlICdIZXgnIHZlcnNpb24KKy8vICAgIGhleGFkZWNpbWFsIHJhdGhlciB0aGFuIG9jdGFsIHNlcXVlbmNlcy4KKy8vCisvLyAgICBDdXJyZW50bHkgb25seSBcbiwgXHIsIFx0LCAiLCAnLCBcIGFuZCAhaXNwcmludCgpIGNoYXJzIGFyZSBlc2NhcGVkLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorc3RyaW5nIENFc2NhcGUoY29uc3Qgc3RyaW5nJiBzcmMpIHsKKyAgY29uc3QgaW50IGRlc3RfbGVuZ3RoID0gc3JjLnNpemUoKSAqIDQgKyAxOyAvLyBNYXhpbXVtIHBvc3NpYmxlIGV4cGFuc2lvbgorICBzY29wZWRfYXJyYXk8Y2hhcj4gZGVzdChuZXcgY2hhcltkZXN0X2xlbmd0aF0pOworICBjb25zdCBpbnQgbGVuID0gQ0VzY2FwZUludGVybmFsKHNyYy5kYXRhKCksIHNyYy5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdC5nZXQoKSwgZGVzdF9sZW5ndGgsIGZhbHNlLCBmYWxzZSk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobGVuLCAwKTsKKyAgcmV0dXJuIHN0cmluZyhkZXN0LmdldCgpLCBsZW4pOworfQorCituYW1lc3BhY2Ugc3RyaW5ncyB7CisKK3N0cmluZyBVdGY4U2FmZUNFc2NhcGUoY29uc3Qgc3RyaW5nJiBzcmMpIHsKKyAgY29uc3QgaW50IGRlc3RfbGVuZ3RoID0gc3JjLnNpemUoKSAqIDQgKyAxOyAvLyBNYXhpbXVtIHBvc3NpYmxlIGV4cGFuc2lvbgorICBzY29wZWRfYXJyYXk8Y2hhcj4gZGVzdChuZXcgY2hhcltkZXN0X2xlbmd0aF0pOworICBjb25zdCBpbnQgbGVuID0gQ0VzY2FwZUludGVybmFsKHNyYy5kYXRhKCksIHNyYy5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdC5nZXQoKSwgZGVzdF9sZW5ndGgsIGZhbHNlLCB0cnVlKTsKKyAgR09PR0xFX0RDSEVDS19HRShsZW4sIDApOworICByZXR1cm4gc3RyaW5nKGRlc3QuZ2V0KCksIGxlbik7Cit9CisKK3N0cmluZyBDSGV4RXNjYXBlKGNvbnN0IHN0cmluZyYgc3JjKSB7CisgIGNvbnN0IGludCBkZXN0X2xlbmd0aCA9IHNyYy5zaXplKCkgKiA0ICsgMTsgLy8gTWF4aW11bSBwb3NzaWJsZSBleHBhbnNpb24KKyAgc2NvcGVkX2FycmF5PGNoYXI+IGRlc3QobmV3IGNoYXJbZGVzdF9sZW5ndGhdKTsKKyAgY29uc3QgaW50IGxlbiA9IENFc2NhcGVJbnRlcm5hbChzcmMuZGF0YSgpLCBzcmMuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3QuZ2V0KCksIGRlc3RfbGVuZ3RoLCB0cnVlLCBmYWxzZSk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobGVuLCAwKTsKKyAgcmV0dXJuIHN0cmluZyhkZXN0LmdldCgpLCBsZW4pOworfQorCit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBzdHJ0bzMyX2FkYXB0b3IoKQorLy8gc3RydG91MzJfYWRhcHRvcigpCisvLyAgICBJbXBsZW1lbnRhdGlvbiBvZiBzdHJ0b1t1XWwgcmVwbGFjZW1lbnRzIHRoYXQgaGF2ZSBpZGVudGljYWwKKy8vICAgIG92ZXJmbG93IGFuZCB1bmRlcmZsb3cgY2hhcmFjdGVyaXN0aWNzIGZvciBib3RoIElMUC0zMiBhbmQgTFAtNjQKKy8vICAgIHBsYXRmb3JtcywgaW5jbHVkaW5nIGVycm5vIHByZXNlcnZhdGlvbiBpbiBlcnJvci1mcmVlIGNhbGxzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbnQzMiBzdHJ0bzMyX2FkYXB0b3IoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwgaW50IGJhc2UpIHsKKyAgY29uc3QgaW50IHNhdmVkX2Vycm5vID0gZXJybm87CisgIGVycm5vID0gMDsKKyAgY29uc3QgbG9uZyByZXN1bHQgPSBzdHJ0b2wobnB0ciwgZW5kcHRyLCBiYXNlKTsKKyAgaWYgKGVycm5vID09IEVSQU5HRSAmJiByZXN1bHQgPT0gTE9OR19NSU4pIHsKKyAgICByZXR1cm4ga2ludDMybWluOworICB9IGVsc2UgaWYgKGVycm5vID09IEVSQU5HRSAmJiByZXN1bHQgPT0gTE9OR19NQVgpIHsKKyAgICByZXR1cm4ga2ludDMybWF4OworICB9IGVsc2UgaWYgKGVycm5vID09IDAgJiYgcmVzdWx0IDwga2ludDMybWluKSB7CisgICAgZXJybm8gPSBFUkFOR0U7CisgICAgcmV0dXJuIGtpbnQzMm1pbjsKKyAgfSBlbHNlIGlmIChlcnJubyA9PSAwICYmIHJlc3VsdCA+IGtpbnQzMm1heCkgeworICAgIGVycm5vID0gRVJBTkdFOworICAgIHJldHVybiBraW50MzJtYXg7CisgIH0KKyAgaWYgKGVycm5vID09IDApCisgICAgZXJybm8gPSBzYXZlZF9lcnJubzsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludDMyPihyZXN1bHQpOworfQorCit1aW50MzIgc3RydG91MzJfYWRhcHRvcihjb25zdCBjaGFyICpucHRyLCBjaGFyICoqZW5kcHRyLCBpbnQgYmFzZSkgeworICBjb25zdCBpbnQgc2F2ZWRfZXJybm8gPSBlcnJubzsKKyAgZXJybm8gPSAwOworICBjb25zdCB1bnNpZ25lZCBsb25nIHJlc3VsdCA9IHN0cnRvdWwobnB0ciwgZW5kcHRyLCBiYXNlKTsKKyAgaWYgKGVycm5vID09IEVSQU5HRSAmJiByZXN1bHQgPT0gVUxPTkdfTUFYKSB7CisgICAgcmV0dXJuIGt1aW50MzJtYXg7CisgIH0gZWxzZSBpZiAoZXJybm8gPT0gMCAmJiByZXN1bHQgPiBrdWludDMybWF4KSB7CisgICAgZXJybm8gPSBFUkFOR0U7CisgICAgcmV0dXJuIGt1aW50MzJtYXg7CisgIH0KKyAgaWYgKGVycm5vID09IDApCisgICAgZXJybm8gPSBzYXZlZF9lcnJubzsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHVpbnQzMj4ocmVzdWx0KTsKK30KKworaW5saW5lIGJvb2wgc2FmZV9wYXJzZV9zaWduKHN0cmluZyogdGV4dCAgLyppbm91dCovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wqIG5lZ2F0aXZlX3B0ciAgLypvdXRwdXQqLykgeworICBjb25zdCBjaGFyKiBzdGFydCA9IHRleHQtPmRhdGEoKTsKKyAgY29uc3QgY2hhciogZW5kID0gc3RhcnQgKyB0ZXh0LT5zaXplKCk7CisKKyAgLy8gQ29uc3VtZSB3aGl0ZXNwYWNlLgorICB3aGlsZSAoc3RhcnQgPCBlbmQgJiYgKHN0YXJ0WzBdID09ICcgJykpIHsKKyAgICArK3N0YXJ0OworICB9CisgIHdoaWxlIChzdGFydCA8IGVuZCAmJiAoZW5kWy0xXSA9PSAnICcpKSB7CisgICAgLS1lbmQ7CisgIH0KKyAgaWYgKHN0YXJ0ID49IGVuZCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIENvbnN1bWUgc2lnbi4KKyAgKm5lZ2F0aXZlX3B0ciA9IChzdGFydFswXSA9PSAnLScpOworICBpZiAoKm5lZ2F0aXZlX3B0ciB8fCBzdGFydFswXSA9PSAnKycpIHsKKyAgICArK3N0YXJ0OworICAgIGlmIChzdGFydCA+PSBlbmQpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgKnRleHQgPSB0ZXh0LT5zdWJzdHIoc3RhcnQgLSB0ZXh0LT5kYXRhKCksIGVuZCAtIHN0YXJ0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2lubGluZSBib29sIHNhZmVfcGFyc2VfcG9zaXRpdmVfaW50KAorICAgIHN0cmluZyB0ZXh0LCBpbnQzMiogdmFsdWVfcCkgeworICBpbnQgYmFzZSA9IDEwOworICBpbnQzMiB2YWx1ZSA9IDA7CisgIGNvbnN0IGludDMyIHZtYXggPSBzdGQ6Om51bWVyaWNfbGltaXRzPGludDMyPjo6bWF4KCk7CisgIGFzc2VydCh2bWF4ID4gMCk7CisgIGFzc2VydCh2bWF4ID49IGJhc2UpOworICBjb25zdCBpbnQzMiB2bWF4X292ZXJfYmFzZSA9IHZtYXggLyBiYXNlOworICBjb25zdCBjaGFyKiBzdGFydCA9IHRleHQuZGF0YSgpOworICBjb25zdCBjaGFyKiBlbmQgPSBzdGFydCArIHRleHQuc2l6ZSgpOworICAvLyBsb29wIG92ZXIgZGlnaXRzCisgIGZvciAoOyBzdGFydCA8IGVuZDsgKytzdGFydCkgeworICAgIHVuc2lnbmVkIGNoYXIgYyA9IHN0YXRpY19jYXN0PHVuc2lnbmVkIGNoYXI+KHN0YXJ0WzBdKTsKKyAgICBpbnQgZGlnaXQgPSBjIC0gJzAnOworICAgIGlmIChkaWdpdCA+PSBiYXNlIHx8IGRpZ2l0IDwgMCkgeworICAgICAgKnZhbHVlX3AgPSB2YWx1ZTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKHZhbHVlID4gdm1heF9vdmVyX2Jhc2UpIHsKKyAgICAgICp2YWx1ZV9wID0gdm1heDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgdmFsdWUgKj0gYmFzZTsKKyAgICBpZiAodmFsdWUgPiB2bWF4IC0gZGlnaXQpIHsKKyAgICAgICp2YWx1ZV9wID0gdm1heDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgdmFsdWUgKz0gZGlnaXQ7CisgIH0KKyAgKnZhbHVlX3AgPSB2YWx1ZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2lubGluZSBib29sIHNhZmVfcGFyc2VfbmVnYXRpdmVfaW50KAorICAgIHN0cmluZyB0ZXh0LCBpbnQzMiogdmFsdWVfcCkgeworICBpbnQgYmFzZSA9IDEwOworICBpbnQzMiB2YWx1ZSA9IDA7CisgIGNvbnN0IGludDMyIHZtaW4gPSBzdGQ6Om51bWVyaWNfbGltaXRzPGludDMyPjo6bWluKCk7CisgIGFzc2VydCh2bWluIDwgMCk7CisgIGFzc2VydCh2bWluIDw9IDAgLSBiYXNlKTsKKyAgaW50MzIgdm1pbl9vdmVyX2Jhc2UgPSB2bWluIC8gYmFzZTsKKyAgLy8gMjAwMyBjKysgc3RhbmRhcmQgW2V4cHIubXVsXQorICAvLyAiLi4uIHRoZSBzaWduIG9mIHRoZSByZW1haW5kZXIgaXMgaW1wbGVtZW50YXRpb24tZGVmaW5lZC4iCisgIC8vIEFsdGhvdWdoICh2bWluL2Jhc2UpKmJhc2UgKyB2bWluJWJhc2UgaXMgYWx3YXlzIHZtaW4uCisgIC8vIDIwMTEgYysrIHN0YW5kYXJkIHRpZ2h0ZW5zIHRoZSBzcGVjIGJ1dCB3ZSBjYW5ub3QgcmVseSBvbiBpdC4KKyAgaWYgKHZtaW4gJSBiYXNlID4gMCkgeworICAgIHZtaW5fb3Zlcl9iYXNlICs9IDE7CisgIH0KKyAgY29uc3QgY2hhciogc3RhcnQgPSB0ZXh0LmRhdGEoKTsKKyAgY29uc3QgY2hhciogZW5kID0gc3RhcnQgKyB0ZXh0LnNpemUoKTsKKyAgLy8gbG9vcCBvdmVyIGRpZ2l0cworICBmb3IgKDsgc3RhcnQgPCBlbmQ7ICsrc3RhcnQpIHsKKyAgICB1bnNpZ25lZCBjaGFyIGMgPSBzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihzdGFydFswXSk7CisgICAgaW50IGRpZ2l0ID0gYyAtICcwJzsKKyAgICBpZiAoZGlnaXQgPj0gYmFzZSB8fCBkaWdpdCA8IDApIHsKKyAgICAgICp2YWx1ZV9wID0gdmFsdWU7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICh2YWx1ZSA8IHZtaW5fb3Zlcl9iYXNlKSB7CisgICAgICAqdmFsdWVfcCA9IHZtaW47CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHZhbHVlICo9IGJhc2U7CisgICAgaWYgKHZhbHVlIDwgdm1pbiArIGRpZ2l0KSB7CisgICAgICAqdmFsdWVfcCA9IHZtaW47CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHZhbHVlIC09IGRpZ2l0OworICB9CisgICp2YWx1ZV9wID0gdmFsdWU7CisgIHJldHVybiB0cnVlOworfQorCitib29sIHNhZmVfaW50KHN0cmluZyB0ZXh0LCBpbnQzMiogdmFsdWVfcCkgeworICAqdmFsdWVfcCA9IDA7CisgIGJvb2wgbmVnYXRpdmU7CisgIGlmICghc2FmZV9wYXJzZV9zaWduKCZ0ZXh0LCAmbmVnYXRpdmUpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmICghbmVnYXRpdmUpIHsKKyAgICByZXR1cm4gc2FmZV9wYXJzZV9wb3NpdGl2ZV9pbnQodGV4dCwgdmFsdWVfcCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHNhZmVfcGFyc2VfbmVnYXRpdmVfaW50KHRleHQsIHZhbHVlX3ApOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEZhc3RJbnRUb0J1ZmZlcigpCisvLyBGYXN0SW50NjRUb0J1ZmZlcigpCisvLyBGYXN0SGV4VG9CdWZmZXIoKQorLy8gRmFzdEhleDY0VG9CdWZmZXIoKQorLy8gRmFzdEhleDMyVG9CdWZmZXIoKQorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBPZmZzZXQgaW50byBidWZmZXIgd2hlcmUgRmFzdEludDY0VG9CdWZmZXIgcGxhY2VzIHRoZSBlbmQgb2Ygc3RyaW5nCisvLyBudWxsIGNoYXJhY3Rlci4gIEFsc28gdXNlZCBieSBGYXN0SW50NjRUb0J1ZmZlckxlZnQuCitzdGF0aWMgY29uc3QgaW50IGtGYXN0SW50NjRUb0J1ZmZlck9mZnNldCA9IDIxOworCitjaGFyICpGYXN0SW50NjRUb0J1ZmZlcihpbnQ2NCBpLCBjaGFyKiBidWZmZXIpIHsKKyAgLy8gV2UgY291bGQgY29sbGFwc2UgdGhlIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBzZWN0aW9ucywgYnV0IHRoYXQKKyAgLy8gd291bGQgYmUgc2xpZ2h0bHkgc2xvd2VyIGZvciBwb3NpdGl2ZSBudW1iZXJzLi4uCisgIC8vIDIyIGJ5dGVzIGlzIGVub3VnaCB0byBzdG9yZSAtMioqNjQsIC0xODQ0Njc0NDA3MzcwOTU1MTYxNi4KKyAgY2hhciogcCA9IGJ1ZmZlciArIGtGYXN0SW50NjRUb0J1ZmZlck9mZnNldDsKKyAgKnAtLSA9ICdcMCc7CisgIGlmIChpID49IDApIHsKKyAgICBkbyB7CisgICAgICAqcC0tID0gJzAnICsgaSAlIDEwOworICAgICAgaSAvPSAxMDsKKyAgICB9IHdoaWxlIChpID4gMCk7CisgICAgcmV0dXJuIHAgKyAxOworICB9IGVsc2UgeworICAgIC8vIE9uIGRpZmZlcmVudCBwbGF0Zm9ybXMsICUgYW5kIC8gaGF2ZSBkaWZmZXJlbnQgYmVoYXZpb3JzIGZvcgorICAgIC8vIG5lZ2F0aXZlIG51bWJlcnMsIHNvIHdlIG5lZWQgdG8ganVtcCB0aHJvdWdoIGhvb3BzIHRvIG1ha2Ugc3VyZQorICAgIC8vIHdlIGRvbid0IGRpdmlkZSBuZWdhdGl2ZSBudW1iZXJzLgorICAgIGlmIChpID4gLTEwKSB7CisgICAgICBpID0gLWk7CisgICAgICAqcC0tID0gJzAnICsgaTsKKyAgICAgICpwID0gJy0nOworICAgICAgcmV0dXJuIHA7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBhcmVuJ3QgYXQgTUlOX0lOVCwgaW4gd2hpY2ggY2FzZSB3ZSBjYW4ndCBzYXkgaSA9IC1pCisgICAgICBpID0gaSArIDEwOworICAgICAgaSA9IC1pOworICAgICAgKnAtLSA9ICcwJyArIGkgJSAxMDsKKyAgICAgIC8vIFVuZG8gd2hhdCB3ZSBkaWQgYSBtb21lbnQgYWdvCisgICAgICBpID0gaSAvIDEwICsgMTsKKyAgICAgIGRvIHsKKyAgICAgICAgKnAtLSA9ICcwJyArIGkgJSAxMDsKKyAgICAgICAgaSAvPSAxMDsKKyAgICAgIH0gd2hpbGUgKGkgPiAwKTsKKyAgICAgICpwID0gJy0nOworICAgICAgcmV0dXJuIHA7CisgICAgfQorICB9Cit9CisKKy8vIE9mZnNldCBpbnRvIGJ1ZmZlciB3aGVyZSBGYXN0SW50MzJUb0J1ZmZlciBwbGFjZXMgdGhlIGVuZCBvZiBzdHJpbmcKKy8vIG51bGwgY2hhcmFjdGVyLiAgQWxzbyB1c2VkIGJ5IEZhc3RJbnQzMlRvQnVmZmVyTGVmdAorc3RhdGljIGNvbnN0IGludCBrRmFzdEludDMyVG9CdWZmZXJPZmZzZXQgPSAxMTsKKworLy8gWWVzLCB0aGlzIGlzIGEgZHVwbGljYXRlIG9mIEZhc3RJbnQ2NFRvQnVmZmVyLiAgQnV0LCB3ZSBuZWVkIHRoaXMgZm9yIHRoZQorLy8gY29tcGlsZXIgdG8gZ2VuZXJhdGUgMzIgYml0IGFyaXRobWV0aWMgaW5zdHJ1Y3Rpb25zLiAgSXQncyBtdWNoIGZhc3RlciwgYXQKKy8vIGxlYXN0IHdpdGggMzIgYml0IGJpbmFyaWVzLgorY2hhciAqRmFzdEludDMyVG9CdWZmZXIoaW50MzIgaSwgY2hhciogYnVmZmVyKSB7CisgIC8vIFdlIGNvdWxkIGNvbGxhcHNlIHRoZSBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgc2VjdGlvbnMsIGJ1dCB0aGF0CisgIC8vIHdvdWxkIGJlIHNsaWdodGx5IHNsb3dlciBmb3IgcG9zaXRpdmUgbnVtYmVycy4uLgorICAvLyAxMiBieXRlcyBpcyBlbm91Z2ggdG8gc3RvcmUgLTIqKjMyLCAtNDI5NDk2NzI5Ni4KKyAgY2hhciogcCA9IGJ1ZmZlciArIGtGYXN0SW50MzJUb0J1ZmZlck9mZnNldDsKKyAgKnAtLSA9ICdcMCc7CisgIGlmIChpID49IDApIHsKKyAgICBkbyB7CisgICAgICAqcC0tID0gJzAnICsgaSAlIDEwOworICAgICAgaSAvPSAxMDsKKyAgICB9IHdoaWxlIChpID4gMCk7CisgICAgcmV0dXJuIHAgKyAxOworICB9IGVsc2UgeworICAgIC8vIE9uIGRpZmZlcmVudCBwbGF0Zm9ybXMsICUgYW5kIC8gaGF2ZSBkaWZmZXJlbnQgYmVoYXZpb3JzIGZvcgorICAgIC8vIG5lZ2F0aXZlIG51bWJlcnMsIHNvIHdlIG5lZWQgdG8ganVtcCB0aHJvdWdoIGhvb3BzIHRvIG1ha2Ugc3VyZQorICAgIC8vIHdlIGRvbid0IGRpdmlkZSBuZWdhdGl2ZSBudW1iZXJzLgorICAgIGlmIChpID4gLTEwKSB7CisgICAgICBpID0gLWk7CisgICAgICAqcC0tID0gJzAnICsgaTsKKyAgICAgICpwID0gJy0nOworICAgICAgcmV0dXJuIHA7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBhcmVuJ3QgYXQgTUlOX0lOVCwgaW4gd2hpY2ggY2FzZSB3ZSBjYW4ndCBzYXkgaSA9IC1pCisgICAgICBpID0gaSArIDEwOworICAgICAgaSA9IC1pOworICAgICAgKnAtLSA9ICcwJyArIGkgJSAxMDsKKyAgICAgIC8vIFVuZG8gd2hhdCB3ZSBkaWQgYSBtb21lbnQgYWdvCisgICAgICBpID0gaSAvIDEwICsgMTsKKyAgICAgIGRvIHsKKyAgICAgICAgKnAtLSA9ICcwJyArIGkgJSAxMDsKKyAgICAgICAgaSAvPSAxMDsKKyAgICAgIH0gd2hpbGUgKGkgPiAwKTsKKyAgICAgICpwID0gJy0nOworICAgICAgcmV0dXJuIHA7CisgICAgfQorICB9Cit9CisKK2NoYXIgKkZhc3RIZXhUb0J1ZmZlcihpbnQgaSwgY2hhciogYnVmZmVyKSB7CisgIEdPT0dMRV9DSEVDSyhpID49IDApIDw8ICJGYXN0SGV4VG9CdWZmZXIoKSB3YW50cyBub24tbmVnYXRpdmUgaW50ZWdlcnMsIG5vdCAiIDw8IGk7CisKKyAgc3RhdGljIGNvbnN0IGNoYXIgKmhleGRpZ2l0cyA9ICIwMTIzNDU2Nzg5YWJjZGVmIjsKKyAgY2hhciAqcCA9IGJ1ZmZlciArIDIxOworICAqcC0tID0gJ1wwJzsKKyAgZG8geworICAgICpwLS0gPSBoZXhkaWdpdHNbaSAmIDE1XTsgICAvLyBtb2QgYnkgMTYKKyAgICBpID4+PSA0OyAgICAgICAgICAgICAgICAgICAgLy8gZGl2aWRlIGJ5IDE2CisgIH0gd2hpbGUgKGkgPiAwKTsKKyAgcmV0dXJuIHAgKyAxOworfQorCitjaGFyICpJbnRlcm5hbEZhc3RIZXhUb0J1ZmZlcih1aW50NjQgdmFsdWUsIGNoYXIqIGJ1ZmZlciwgaW50IG51bV9ieXRlKSB7CisgIHN0YXRpYyBjb25zdCBjaGFyICpoZXhkaWdpdHMgPSAiMDEyMzQ1Njc4OWFiY2RlZiI7CisgIGJ1ZmZlcltudW1fYnl0ZV0gPSAnXDAnOworICBmb3IgKGludCBpID0gbnVtX2J5dGUgLSAxOyBpID49IDA7IGktLSkgeworI2lmZGVmIF9NX1g2NAorICAgIC8vIE1TVkMgeDY0IHBsYXRmb3JtIGhhcyBhIGJ1ZyBvcHRpbWl6aW5nIHRoZSB1aW50MzIodmFsdWUpIGluIHRoZSAjZWxzZQorICAgIC8vIGJsb2NrLiBHaXZlbiB0aGF0IHRoZSB1aW50MzIgY2FzdCB3YXMgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZSBvbiAzMi1iaXQKKyAgICAvLyBwbGF0Zm9ybXMsIHdlIHVzZSA2NC1iaXQgJyYnIGRpcmVjdGx5LgorICAgIGJ1ZmZlcltpXSA9IGhleGRpZ2l0c1t2YWx1ZSAmIDB4Zl07CisjZWxzZQorICAgIGJ1ZmZlcltpXSA9IGhleGRpZ2l0c1t1aW50MzIodmFsdWUpICYgMHhmXTsKKyNlbmRpZgorICAgIHZhbHVlID4+PSA0OworICB9CisgIHJldHVybiBidWZmZXI7Cit9CisKK2NoYXIgKkZhc3RIZXg2NFRvQnVmZmVyKHVpbnQ2NCB2YWx1ZSwgY2hhciogYnVmZmVyKSB7CisgIHJldHVybiBJbnRlcm5hbEZhc3RIZXhUb0J1ZmZlcih2YWx1ZSwgYnVmZmVyLCAxNik7Cit9CisKK2NoYXIgKkZhc3RIZXgzMlRvQnVmZmVyKHVpbnQzMiB2YWx1ZSwgY2hhciogYnVmZmVyKSB7CisgIHJldHVybiBJbnRlcm5hbEZhc3RIZXhUb0J1ZmZlcih2YWx1ZSwgYnVmZmVyLCA4KTsKK30KKworc3RhdGljIGlubGluZSBjaGFyKiBQbGFjZU51bShjaGFyKiBwLCBpbnQgbnVtLCBjaGFyIHByZXZfc2VwKSB7CisgICAqcC0tID0gJzAnICsgbnVtICUgMTA7CisgICAqcC0tID0gJzAnICsgbnVtIC8gMTA7CisgICAqcC0tID0gcHJldl9zZXA7CisgICByZXR1cm4gcDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRmFzdEludDMyVG9CdWZmZXJMZWZ0KCkKKy8vIEZhc3RVSW50MzJUb0J1ZmZlckxlZnQoKQorLy8gRmFzdEludDY0VG9CdWZmZXJMZWZ0KCkKKy8vIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQoKQorLy8KKy8vIExpa2UgdGhlIEZhc3QqVG9CdWZmZXIoKSBmdW5jdGlvbnMgYWJvdmUsIHRoZXNlIGFyZSBpbnRlbmRlZCBmb3Igc3BlZWQuCisvLyBVbmxpa2UgdGhlIEZhc3QqVG9CdWZmZXIoKSBmdW5jdGlvbnMsIGhvd2V2ZXIsIHRoZXNlIGZ1bmN0aW9ucyB3cml0ZQorLy8gdGhlaXIgb3V0cHV0IHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGJ1ZmZlciAoaGVuY2UgdGhlIG5hbWUsIGFzIHRoZQorLy8gb3V0cHV0IGlzIGxlZnQtYWxpZ25lZCkuICBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGF0CisvLyB0aGUgYnVmZmVyIGhhcyBlbm91Z2ggc3BhY2UgdG8gaG9sZCB0aGUgb3V0cHV0LgorLy8KKy8vIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBlbmQgb2YgdGhlIHN0cmluZyAoaS5lLiB0aGUgbnVsbCBjaGFyYWN0ZXIKKy8vIHRlcm1pbmF0aW5nIHRoZSBzdHJpbmcpLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgY29uc3QgY2hhciB0d29fQVNDSUlfZGlnaXRzWzEwMF1bMl0gPSB7CisgIHsnMCcsJzAnfSwgeycwJywnMSd9LCB7JzAnLCcyJ30sIHsnMCcsJzMnfSwgeycwJywnNCd9LAorICB7JzAnLCc1J30sIHsnMCcsJzYnfSwgeycwJywnNyd9LCB7JzAnLCc4J30sIHsnMCcsJzknfSwKKyAgeycxJywnMCd9LCB7JzEnLCcxJ30sIHsnMScsJzInfSwgeycxJywnMyd9LCB7JzEnLCc0J30sCisgIHsnMScsJzUnfSwgeycxJywnNid9LCB7JzEnLCc3J30sIHsnMScsJzgnfSwgeycxJywnOSd9LAorICB7JzInLCcwJ30sIHsnMicsJzEnfSwgeycyJywnMid9LCB7JzInLCczJ30sIHsnMicsJzQnfSwKKyAgeycyJywnNSd9LCB7JzInLCc2J30sIHsnMicsJzcnfSwgeycyJywnOCd9LCB7JzInLCc5J30sCisgIHsnMycsJzAnfSwgeyczJywnMSd9LCB7JzMnLCcyJ30sIHsnMycsJzMnfSwgeyczJywnNCd9LAorICB7JzMnLCc1J30sIHsnMycsJzYnfSwgeyczJywnNyd9LCB7JzMnLCc4J30sIHsnMycsJzknfSwKKyAgeyc0JywnMCd9LCB7JzQnLCcxJ30sIHsnNCcsJzInfSwgeyc0JywnMyd9LCB7JzQnLCc0J30sCisgIHsnNCcsJzUnfSwgeyc0JywnNid9LCB7JzQnLCc3J30sIHsnNCcsJzgnfSwgeyc0JywnOSd9LAorICB7JzUnLCcwJ30sIHsnNScsJzEnfSwgeyc1JywnMid9LCB7JzUnLCczJ30sIHsnNScsJzQnfSwKKyAgeyc1JywnNSd9LCB7JzUnLCc2J30sIHsnNScsJzcnfSwgeyc1JywnOCd9LCB7JzUnLCc5J30sCisgIHsnNicsJzAnfSwgeyc2JywnMSd9LCB7JzYnLCcyJ30sIHsnNicsJzMnfSwgeyc2JywnNCd9LAorICB7JzYnLCc1J30sIHsnNicsJzYnfSwgeyc2JywnNyd9LCB7JzYnLCc4J30sIHsnNicsJzknfSwKKyAgeyc3JywnMCd9LCB7JzcnLCcxJ30sIHsnNycsJzInfSwgeyc3JywnMyd9LCB7JzcnLCc0J30sCisgIHsnNycsJzUnfSwgeyc3JywnNid9LCB7JzcnLCc3J30sIHsnNycsJzgnfSwgeyc3JywnOSd9LAorICB7JzgnLCcwJ30sIHsnOCcsJzEnfSwgeyc4JywnMid9LCB7JzgnLCczJ30sIHsnOCcsJzQnfSwKKyAgeyc4JywnNSd9LCB7JzgnLCc2J30sIHsnOCcsJzcnfSwgeyc4JywnOCd9LCB7JzgnLCc5J30sCisgIHsnOScsJzAnfSwgeyc5JywnMSd9LCB7JzknLCcyJ30sIHsnOScsJzMnfSwgeyc5JywnNCd9LAorICB7JzknLCc1J30sIHsnOScsJzYnfSwgeyc5JywnNyd9LCB7JzknLCc4J30sIHsnOScsJzknfQorfTsKKworY2hhciogRmFzdFVJbnQzMlRvQnVmZmVyTGVmdCh1aW50MzIgdSwgY2hhciogYnVmZmVyKSB7CisgIGludCBkaWdpdHM7CisgIGNvbnN0IGNoYXIgKkFTQ0lJX2RpZ2l0cyA9IE5VTEw7CisgIC8vIFRoZSBpZGVhIG9mIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgdG8gdHJpbSB0aGUgbnVtYmVyIG9mIGRpdmlkZXMgdG8gYXMgZmV3CisgIC8vIGFzIHBvc3NpYmxlIGJ5IHVzaW5nIG11bHRpcGxpY2F0aW9uIGFuZCBzdWJ0cmFjdGlvbiByYXRoZXIgdGhhbiBtb2QgKCUpLAorICAvLyBhbmQgYnkgb3V0cHV0dGluZyB0d28gZGlnaXRzIGF0IGEgdGltZSByYXRoZXIgdGhhbiBvbmUuCisgIC8vIFRoZSBodWdlLW51bWJlciBjYXNlIGlzIGZpcnN0LCBpbiB0aGUgaG9wZXMgdGhhdCB0aGUgY29tcGlsZXIgd2lsbCBvdXRwdXQKKyAgLy8gdGhhdCBjYXNlIGluIG9uZSBicmFuY2gtZnJlZSBibG9jayBvZiBjb2RlLCBhbmQgb25seSBvdXRwdXQgY29uZGl0aW9uYWwKKyAgLy8gYnJhbmNoZXMgaW50byBpdCBmcm9tIGJlbG93LgorICBpZiAodSA+PSAxMDAwMDAwMDAwKSB7ICAvLyA+PSAxLDAwMCwwMDAsMDAwCisgICAgZGlnaXRzID0gdSAvIDEwMDAwMDAwMDsgIC8vIDEwMCwwMDAsMDAwCisgICAgQVNDSUlfZGlnaXRzID0gdHdvX0FTQ0lJX2RpZ2l0c1tkaWdpdHNdOworICAgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgICAgYnVmZmVyICs9IDI7CitzdWJsdDEwMF8wMDBfMDAwOgorICAgIHUgLT0gZGlnaXRzICogMTAwMDAwMDAwOyAgLy8gMTAwLDAwMCwwMDAKK2x0MTAwXzAwMF8wMDA6CisgICAgZGlnaXRzID0gdSAvIDEwMDAwMDA7ICAvLyAxLDAwMCwwMDAKKyAgICBBU0NJSV9kaWdpdHMgPSB0d29fQVNDSUlfZGlnaXRzW2RpZ2l0c107CisgICAgYnVmZmVyWzBdID0gQVNDSUlfZGlnaXRzWzBdOworICAgIGJ1ZmZlclsxXSA9IEFTQ0lJX2RpZ2l0c1sxXTsKKyAgICBidWZmZXIgKz0gMjsKK3N1Ymx0MV8wMDBfMDAwOgorICAgIHUgLT0gZGlnaXRzICogMTAwMDAwMDsgIC8vIDEsMDAwLDAwMAorbHQxXzAwMF8wMDA6CisgICAgZGlnaXRzID0gdSAvIDEwMDAwOyAgLy8gMTAsMDAwCisgICAgQVNDSUlfZGlnaXRzID0gdHdvX0FTQ0lJX2RpZ2l0c1tkaWdpdHNdOworICAgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgICAgYnVmZmVyICs9IDI7CitzdWJsdDEwXzAwMDoKKyAgICB1IC09IGRpZ2l0cyAqIDEwMDAwOyAgLy8gMTAsMDAwCitsdDEwXzAwMDoKKyAgICBkaWdpdHMgPSB1IC8gMTAwOworICAgIEFTQ0lJX2RpZ2l0cyA9IHR3b19BU0NJSV9kaWdpdHNbZGlnaXRzXTsKKyAgICBidWZmZXJbMF0gPSBBU0NJSV9kaWdpdHNbMF07CisgICAgYnVmZmVyWzFdID0gQVNDSUlfZGlnaXRzWzFdOworICAgIGJ1ZmZlciArPSAyOworc3VibHQxMDA6CisgICAgdSAtPSBkaWdpdHMgKiAxMDA7CitsdDEwMDoKKyAgICBkaWdpdHMgPSB1OworICAgIEFTQ0lJX2RpZ2l0cyA9IHR3b19BU0NJSV9kaWdpdHNbZGlnaXRzXTsKKyAgICBidWZmZXJbMF0gPSBBU0NJSV9kaWdpdHNbMF07CisgICAgYnVmZmVyWzFdID0gQVNDSUlfZGlnaXRzWzFdOworICAgIGJ1ZmZlciArPSAyOworZG9uZToKKyAgICAqYnVmZmVyID0gMDsKKyAgICByZXR1cm4gYnVmZmVyOworICB9CisKKyAgaWYgKHUgPCAxMDApIHsKKyAgICBkaWdpdHMgPSB1OworICAgIGlmICh1ID49IDEwKSBnb3RvIGx0MTAwOworICAgICpidWZmZXIrKyA9ICcwJyArIGRpZ2l0czsKKyAgICBnb3RvIGRvbmU7CisgIH0KKyAgaWYgKHUgIDwgIDEwMDAwKSB7ICAgLy8gMTAsMDAwCisgICAgaWYgKHUgPj0gMTAwMCkgZ290byBsdDEwXzAwMDsKKyAgICBkaWdpdHMgPSB1IC8gMTAwOworICAgICpidWZmZXIrKyA9ICcwJyArIGRpZ2l0czsKKyAgICBnb3RvIHN1Ymx0MTAwOworICB9CisgIGlmICh1ICA8ICAxMDAwMDAwKSB7ICAgLy8gMSwwMDAsMDAwCisgICAgaWYgKHUgPj0gMTAwMDAwKSBnb3RvIGx0MV8wMDBfMDAwOworICAgIGRpZ2l0cyA9IHUgLyAxMDAwMDsgIC8vICAgIDEwLDAwMAorICAgICpidWZmZXIrKyA9ICcwJyArIGRpZ2l0czsKKyAgICBnb3RvIHN1Ymx0MTBfMDAwOworICB9CisgIGlmICh1ICA8ICAxMDAwMDAwMDApIHsgICAvLyAxMDAsMDAwLDAwMAorICAgIGlmICh1ID49IDEwMDAwMDAwKSBnb3RvIGx0MTAwXzAwMF8wMDA7CisgICAgZGlnaXRzID0gdSAvIDEwMDAwMDA7ICAvLyAgIDEsMDAwLDAwMAorICAgICpidWZmZXIrKyA9ICcwJyArIGRpZ2l0czsKKyAgICBnb3RvIHN1Ymx0MV8wMDBfMDAwOworICB9CisgIC8vIHdlIGFscmVhZHkga25vdyB0aGF0IHUgPCAxLDAwMCwwMDAsMDAwCisgIGRpZ2l0cyA9IHUgLyAxMDAwMDAwMDA7ICAgLy8gMTAwLDAwMCwwMDAKKyAgKmJ1ZmZlcisrID0gJzAnICsgZGlnaXRzOworICBnb3RvIHN1Ymx0MTAwXzAwMF8wMDA7Cit9CisKK2NoYXIqIEZhc3RJbnQzMlRvQnVmZmVyTGVmdChpbnQzMiBpLCBjaGFyKiBidWZmZXIpIHsKKyAgdWludDMyIHUgPSBpOworICBpZiAoaSA8IDApIHsKKyAgICAqYnVmZmVyKysgPSAnLSc7CisgICAgdSA9IC1pOworICB9CisgIHJldHVybiBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KHUsIGJ1ZmZlcik7Cit9CisKK2NoYXIqIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQodWludDY0IHU2NCwgY2hhciogYnVmZmVyKSB7CisgIGludCBkaWdpdHM7CisgIGNvbnN0IGNoYXIgKkFTQ0lJX2RpZ2l0cyA9IE5VTEw7CisKKyAgdWludDMyIHUgPSBzdGF0aWNfY2FzdDx1aW50MzI+KHU2NCk7CisgIGlmICh1ID09IHU2NCkgcmV0dXJuIEZhc3RVSW50MzJUb0J1ZmZlckxlZnQodSwgYnVmZmVyKTsKKworICB1aW50NjQgdG9wXzExX2RpZ2l0cyA9IHU2NCAvIDEwMDAwMDAwMDA7CisgIGJ1ZmZlciA9IEZhc3RVSW50NjRUb0J1ZmZlckxlZnQodG9wXzExX2RpZ2l0cywgYnVmZmVyKTsKKyAgdSA9IHU2NCAtICh0b3BfMTFfZGlnaXRzICogMTAwMDAwMDAwMCk7CisKKyAgZGlnaXRzID0gdSAvIDEwMDAwMDAwOyAgLy8gMTAsMDAwLDAwMAorICBHT09HTEVfRENIRUNLX0xUKGRpZ2l0cywgMTAwKTsKKyAgQVNDSUlfZGlnaXRzID0gdHdvX0FTQ0lJX2RpZ2l0c1tkaWdpdHNdOworICBidWZmZXJbMF0gPSBBU0NJSV9kaWdpdHNbMF07CisgIGJ1ZmZlclsxXSA9IEFTQ0lJX2RpZ2l0c1sxXTsKKyAgYnVmZmVyICs9IDI7CisgIHUgLT0gZGlnaXRzICogMTAwMDAwMDA7ICAvLyAxMCwwMDAsMDAwCisgIGRpZ2l0cyA9IHUgLyAxMDAwMDA7ICAvLyAxMDAsMDAwCisgIEFTQ0lJX2RpZ2l0cyA9IHR3b19BU0NJSV9kaWdpdHNbZGlnaXRzXTsKKyAgYnVmZmVyWzBdID0gQVNDSUlfZGlnaXRzWzBdOworICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgIGJ1ZmZlciArPSAyOworICB1IC09IGRpZ2l0cyAqIDEwMDAwMDsgIC8vIDEwMCwwMDAKKyAgZGlnaXRzID0gdSAvIDEwMDA7ICAvLyAxLDAwMAorICBBU0NJSV9kaWdpdHMgPSB0d29fQVNDSUlfZGlnaXRzW2RpZ2l0c107CisgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgYnVmZmVyWzFdID0gQVNDSUlfZGlnaXRzWzFdOworICBidWZmZXIgKz0gMjsKKyAgdSAtPSBkaWdpdHMgKiAxMDAwOyAgLy8gMSwwMDAKKyAgZGlnaXRzID0gdSAvIDEwOworICBBU0NJSV9kaWdpdHMgPSB0d29fQVNDSUlfZGlnaXRzW2RpZ2l0c107CisgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgYnVmZmVyWzFdID0gQVNDSUlfZGlnaXRzWzFdOworICBidWZmZXIgKz0gMjsKKyAgdSAtPSBkaWdpdHMgKiAxMDsKKyAgZGlnaXRzID0gdTsKKyAgKmJ1ZmZlcisrID0gJzAnICsgZGlnaXRzOworICAqYnVmZmVyID0gMDsKKyAgcmV0dXJuIGJ1ZmZlcjsKK30KKworY2hhciogRmFzdEludDY0VG9CdWZmZXJMZWZ0KGludDY0IGksIGNoYXIqIGJ1ZmZlcikgeworICB1aW50NjQgdSA9IGk7CisgIGlmIChpIDwgMCkgeworICAgICpidWZmZXIrKyA9ICctJzsKKyAgICB1ID0gLWk7CisgIH0KKyAgcmV0dXJuIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQodSwgYnVmZmVyKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU2ltcGxlSXRvYSgpCisvLyAgICBEZXNjcmlwdGlvbjogY29udmVydHMgYW4gaW50ZWdlciB0byBhIHN0cmluZy4KKy8vCisvLyAgICBSZXR1cm4gdmFsdWU6IHN0cmluZworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJpbmcgU2ltcGxlSXRvYShpbnQgaSkgeworICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiAoc2l6ZW9mKGkpID09IDQpID8KKyAgICBGYXN0SW50MzJUb0J1ZmZlcihpLCBidWZmZXIpIDoKKyAgICBGYXN0SW50NjRUb0J1ZmZlcihpLCBidWZmZXIpOworfQorCitzdHJpbmcgU2ltcGxlSXRvYSh1bnNpZ25lZCBpbnQgaSkgeworICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiBzdHJpbmcoYnVmZmVyLCAoc2l6ZW9mKGkpID09IDQpID8KKyAgICBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KGksIGJ1ZmZlcikgOgorICAgIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQoaSwgYnVmZmVyKSk7Cit9CisKK3N0cmluZyBTaW1wbGVJdG9hKGxvbmcgaSkgeworICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiAoc2l6ZW9mKGkpID09IDQpID8KKyAgICBGYXN0SW50MzJUb0J1ZmZlcihpLCBidWZmZXIpIDoKKyAgICBGYXN0SW50NjRUb0J1ZmZlcihpLCBidWZmZXIpOworfQorCitzdHJpbmcgU2ltcGxlSXRvYSh1bnNpZ25lZCBsb25nIGkpIHsKKyAgY2hhciBidWZmZXJba0Zhc3RUb0J1ZmZlclNpemVdOworICByZXR1cm4gc3RyaW5nKGJ1ZmZlciwgKHNpemVvZihpKSA9PSA0KSA/CisgICAgRmFzdFVJbnQzMlRvQnVmZmVyTGVmdChpLCBidWZmZXIpIDoKKyAgICBGYXN0VUludDY0VG9CdWZmZXJMZWZ0KGksIGJ1ZmZlcikpOworfQorCitzdHJpbmcgU2ltcGxlSXRvYShsb25nIGxvbmcgaSkgeworICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiAoc2l6ZW9mKGkpID09IDQpID8KKyAgICBGYXN0SW50MzJUb0J1ZmZlcihpLCBidWZmZXIpIDoKKyAgICBGYXN0SW50NjRUb0J1ZmZlcihpLCBidWZmZXIpOworfQorCitzdHJpbmcgU2ltcGxlSXRvYSh1bnNpZ25lZCBsb25nIGxvbmcgaSkgeworICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiBzdHJpbmcoYnVmZmVyLCAoc2l6ZW9mKGkpID09IDQpID8KKyAgICBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KGksIGJ1ZmZlcikgOgorICAgIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQoaSwgYnVmZmVyKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNpbXBsZUR0b2EoKQorLy8gU2ltcGxlRnRvYSgpCisvLyBEb3VibGVUb0J1ZmZlcigpCisvLyBGbG9hdFRvQnVmZmVyKCkKKy8vICAgIFdlIHdhbnQgdG8gcHJpbnQgdGhlIHZhbHVlIHdpdGhvdXQgbG9zaW5nIHByZWNpc2lvbiwgYnV0IHdlIGFsc28gZG8KKy8vICAgIG5vdCB3YW50IHRvIHByaW50IG1vcmUgZGlnaXRzIHRoYW4gbmVjZXNzYXJ5LiAgVGhpcyB0dXJucyBvdXQgdG8gYmUKKy8vICAgIHRyaWNraWVyIHRoYW4gaXQgc291bmRzLiAgTnVtYmVycyBsaWtlIDAuMiBjYW5ub3QgYmUgcmVwcmVzZW50ZWQKKy8vICAgIGV4YWN0bHkgaW4gYmluYXJ5LiAgSWYgd2UgcHJpbnQgMC4yIHdpdGggYSB2ZXJ5IGxhcmdlIHByZWNpc2lvbiwKKy8vICAgIGUuZy4gIiUuNTBnIiwgd2UgZ2V0ICIwLjIwMDAwMDAwMDAwMDAwMDAxMTEwMjIzMDI0NjI1MTU2NTQwNDIzNjMxNjciLgorLy8gICAgT24gdGhlIG90aGVyIGhhbmQsIGlmIHdlIHNldCB0aGUgcHJlY2lzaW9uIHRvbyBsb3csIHdlIGxvc2UKKy8vICAgIHNpZ25pZmljYW50IGRpZ2l0cyB3aGVuIHByaW50aW5nIG51bWJlcnMgdGhhdCBhY3R1YWxseSBuZWVkIHRoZW0uCisvLyAgICBJdCB0dXJucyBvdXQgdGhlcmUgaXMgbm8gcHJlY2lzaW9uIHZhbHVlIHRoYXQgZG9lcyB0aGUgcmlnaHQgdGhpbmcKKy8vICAgIGZvciBhbGwgbnVtYmVycy4KKy8vCisvLyAgICBPdXIgc3RyYXRlZ3kgaXMgdG8gZmlyc3QgdHJ5IHByaW50aW5nIHdpdGggYSBwcmVjaXNpb24gdGhhdCBpcyBuZXZlcgorLy8gICAgb3Zlci1wcmVjaXNlLCB0aGVuIHBhcnNlIHRoZSByZXN1bHQgd2l0aCBzdHJ0b2QoKSB0byBzZWUgaWYgaXQKKy8vICAgIG1hdGNoZXMuICBJZiBub3QsIHdlIHByaW50IGFnYWluIHdpdGggYSBwcmVjaXNpb24gdGhhdCB3aWxsIGFsd2F5cworLy8gICAgZ2l2ZSBhIHByZWNpc2UgcmVzdWx0LCBidXQgbWF5IHVzZSBtb3JlIGRpZ2l0cyB0aGFuIG5lY2Vzc2FyeS4KKy8vCisvLyAgICBBbiBhcmd1YWJseSBiZXR0ZXIgc3RyYXRlZ3kgd291bGQgYmUgdG8gdXNlIHRoZSBhbGdvcml0aG0gZGVzY3JpYmVkCisvLyAgICBpbiAiSG93IHRvIFByaW50IEZsb2F0aW5nLVBvaW50IE51bWJlcnMgQWNjdXJhdGVseSIgYnkgU3RlZWxlICYKKy8vICAgIFdoaXRlLCBlLmcuIGFzIGltcGxlbWVudGVkIGJ5IERhdmlkIE0uIEdheSdzIGR0b2EoKS4gIEl0IHR1cm5zIG91dCwKKy8vICAgIGhvd2V2ZXIsIHRoYXQgdGhlIGZvbGxvd2luZyBpbXBsZW1lbnRhdGlvbiBpcyBhYm91dCBhcyBmYXN0IGFzCisvLyAgICBETUcncyBjb2RlLiAgRnVydGhlcm1vcmUsIERNRydzIGNvZGUgbG9ja3MgbXV0ZXhlcywgd2hpY2ggbWVhbnMgaXQKKy8vICAgIHdpbGwgbm90IHNjYWxlIHdlbGwgb24gbXVsdGktY29yZSBtYWNoaW5lcy4gIERNRydzIGNvZGUgaXMgc2xpZ2h0bHkKKy8vICAgIG1vcmUgYWNjdXJhdGUgKGluIHRoYXQgaXQgd2lsbCBuZXZlciB1c2UgbW9yZSBkaWdpdHMgdGhhbgorLy8gICAgbmVjZXNzYXJ5KSwgYnV0IHRoaXMgaXMgcHJvYmFibHkgaXJyZWxldmFudCBmb3IgbW9zdCB1c2Vycy4KKy8vCisvLyAgICBSb2IgUGlrZSBhbmQgS2VuIFRob21wc29uIGFsc28gaGF2ZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiBkdG9hKCkgaW4KKy8vICAgIHRoaXJkX3BhcnR5L2ZtdC9mbHRmbXQuY2MuICBUaGVpciBpbXBsZW1lbnRhdGlvbiBpcyBzaW1pbGFyIHRvIHRoaXMKKy8vICAgIG9uZSBpbiB0aGF0IGl0IG1ha2VzIGd1ZXNzZXMgYW5kIHRoZW4gdXNlcyBzdHJ0b2QoKSB0byBjaGVjayB0aGVtLgorLy8gICAgVGhlaXIgaW1wbGVtZW50YXRpb24gaXMgZmFzdGVyIGJlY2F1c2UgdGhleSB1c2UgdGhlaXIgb3duIGNvZGUgdG8KKy8vICAgIGdlbmVyYXRlIHRoZSBkaWdpdHMgaW4gdGhlIGZpcnN0IHBsYWNlIHJhdGhlciB0aGFuIHVzZSBzbnByaW50ZigpLAorLy8gICAgdGh1cyBhdm9pZGluZyBmb3JtYXQgc3RyaW5nIHBhcnNpbmcgb3ZlcmhlYWQuICBIb3dldmVyLCB0aGlzIG1ha2VzCisvLyAgICBpdCBjb25zaWRlcmFibHkgbW9yZSBjb21wbGljYXRlZCB0aGFuIHRoZSBmb2xsb3dpbmcgaW1wbGVtZW50YXRpb24sCisvLyAgICBhbmQgaXQgaXMgZW1iZWRkZWQgaW4gYSBsYXJnZXIgbGlicmFyeS4gIElmIHNwZWVkIHR1cm5zIG91dCB0byBiZQorLy8gICAgYW4gaXNzdWUsIHdlIGNvdWxkIHJlLWltcGxlbWVudCB0aGlzIGluIHRlcm1zIG9mIHRoZWlyCisvLyAgICBpbXBsZW1lbnRhdGlvbi4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RyaW5nIFNpbXBsZUR0b2EoZG91YmxlIHZhbHVlKSB7CisgIGNoYXIgYnVmZmVyW2tEb3VibGVUb0J1ZmZlclNpemVdOworICByZXR1cm4gRG91YmxlVG9CdWZmZXIodmFsdWUsIGJ1ZmZlcik7Cit9CisKK3N0cmluZyBTaW1wbGVGdG9hKGZsb2F0IHZhbHVlKSB7CisgIGNoYXIgYnVmZmVyW2tGbG9hdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiBGbG9hdFRvQnVmZmVyKHZhbHVlLCBidWZmZXIpOworfQorCitzdGF0aWMgaW5saW5lIGJvb2wgSXNWYWxpZEZsb2F0Q2hhcihjaGFyIGMpIHsKKyAgcmV0dXJuICgnMCcgPD0gYyAmJiBjIDw9ICc5JykgfHwKKyAgICAgICAgIGMgPT0gJ2UnIHx8IGMgPT0gJ0UnIHx8CisgICAgICAgICBjID09ICcrJyB8fCBjID09ICctJzsKK30KKwordm9pZCBEZWxvY2FsaXplUmFkaXgoY2hhciogYnVmZmVyKSB7CisgIC8vIEZhc3QgY2hlY2s6ICBpZiB0aGUgYnVmZmVyIGhhcyBhIG5vcm1hbCBkZWNpbWFsIHBvaW50LCBhc3N1bWUgbm8KKyAgLy8gdHJhbnNsYXRpb24gaXMgbmVlZGVkLgorICBpZiAoc3RyY2hyKGJ1ZmZlciwgJy4nKSAhPSBOVUxMKSByZXR1cm47CisKKyAgLy8gRmluZCB0aGUgZmlyc3QgdW5rbm93biBjaGFyYWN0ZXIuCisgIHdoaWxlIChJc1ZhbGlkRmxvYXRDaGFyKCpidWZmZXIpKSArK2J1ZmZlcjsKKworICBpZiAoKmJ1ZmZlciA9PSAnXDAnKSB7CisgICAgLy8gTm8gcmFkaXggY2hhcmFjdGVyIGZvdW5kLgorICAgIHJldHVybjsKKyAgfQorCisgIC8vIFdlIGFyZSBub3cgcG9pbnRpbmcgYXQgdGhlIGxvY2FsZS1zcGVjaWZpYyByYWRpeCBjaGFyYWN0ZXIuICBSZXBsYWNlIGl0CisgIC8vIHdpdGggJy4nLgorICAqYnVmZmVyID0gJy4nOworICArK2J1ZmZlcjsKKworICBpZiAoIUlzVmFsaWRGbG9hdENoYXIoKmJ1ZmZlcikgJiYgKmJ1ZmZlciAhPSAnXDAnKSB7CisgICAgLy8gSXQgYXBwZWFycyB0aGUgcmFkaXggd2FzIGEgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuICBXZSBuZWVkIHRvIHJlbW92ZSB0aGUKKyAgICAvLyBleHRyYSBieXRlcy4KKyAgICBjaGFyKiB0YXJnZXQgPSBidWZmZXI7CisgICAgZG8geyArK2J1ZmZlcjsgfSB3aGlsZSAoIUlzVmFsaWRGbG9hdENoYXIoKmJ1ZmZlcikgJiYgKmJ1ZmZlciAhPSAnXDAnKTsKKyAgICBtZW1tb3ZlKHRhcmdldCwgYnVmZmVyLCBzdHJsZW4oYnVmZmVyKSArIDEpOworICB9Cit9CisKK2NoYXIqIERvdWJsZVRvQnVmZmVyKGRvdWJsZSB2YWx1ZSwgY2hhciogYnVmZmVyKSB7CisgIC8vIERCTF9ESUcgaXMgMTUgZm9yIElFRUUtNzU0IGRvdWJsZXMsIHdoaWNoIGFyZSB1c2VkIG9uIGFsbW9zdCBhbGwKKyAgLy8gcGxhdGZvcm1zIHRoZXNlIGRheXMuICBKdXN0IGluIGNhc2Ugc29tZSBzeXN0ZW0gZXhpc3RzIHdoZXJlIERCTF9ESUcKKyAgLy8gaXMgc2lnbmlmaWNhbnRseSBsYXJnZXIgLS0gYW5kIHJpc2tzIG92ZXJmbG93aW5nIG91ciBidWZmZXIgLS0gd2UgaGF2ZQorICAvLyB0aGlzIGFzc2VydC4KKyAgR09PR0xFX0NPTVBJTEVfQVNTRVJUKERCTF9ESUcgPCAyMCwgREJMX0RJR19pc190b29fYmlnKTsKKworICBpZiAodmFsdWUgPT0gbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSkgeworICAgIHN0cmNweShidWZmZXIsICJpbmYiKTsKKyAgICByZXR1cm4gYnVmZmVyOworICB9IGVsc2UgaWYgKHZhbHVlID09IC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgc3RyY3B5KGJ1ZmZlciwgIi1pbmYiKTsKKyAgICByZXR1cm4gYnVmZmVyOworICB9IGVsc2UgaWYgKElzTmFOKHZhbHVlKSkgeworICAgIHN0cmNweShidWZmZXIsICJuYW4iKTsKKyAgICByZXR1cm4gYnVmZmVyOworICB9CisKKyAgaW50IHNucHJpbnRmX3Jlc3VsdCA9CisgICAgc25wcmludGYoYnVmZmVyLCBrRG91YmxlVG9CdWZmZXJTaXplLCAiJS4qZyIsIERCTF9ESUcsIHZhbHVlKTsKKworICAvLyBUaGUgc25wcmludGYgc2hvdWxkIG5ldmVyIG92ZXJmbG93IGJlY2F1c2UgdGhlIGJ1ZmZlciBpcyBzaWduaWZpY2FudGx5CisgIC8vIGxhcmdlciB0aGFuIHRoZSBwcmVjaXNpb24gd2UgYXNrZWQgZm9yLgorICBHT09HTEVfRENIRUNLKHNucHJpbnRmX3Jlc3VsdCA+IDAgJiYgc25wcmludGZfcmVzdWx0IDwga0RvdWJsZVRvQnVmZmVyU2l6ZSk7CisKKyAgLy8gV2UgbmVlZCB0byBtYWtlIHBhcnNlZF92YWx1ZSB2b2xhdGlsZSBpbiBvcmRlciB0byBmb3JjZSB0aGUgY29tcGlsZXIgdG8KKyAgLy8gd3JpdGUgaXQgb3V0IHRvIHRoZSBzdGFjay4gIE90aGVyd2lzZSwgaXQgbWF5IGtlZXAgdGhlIHZhbHVlIGluIGEKKyAgLy8gcmVnaXN0ZXIsIGFuZCBpZiBpdCBkb2VzIHRoYXQsIGl0IG1heSBrZWVwIGl0IGFzIGEgbG9uZyBkb3VibGUgaW5zdGVhZAorICAvLyBvZiBhIGRvdWJsZS4gIFRoaXMgbG9uZyBkb3VibGUgbWF5IGhhdmUgZXh0cmEgYml0cyB0aGF0IG1ha2UgaXQgY29tcGFyZQorICAvLyB1bmVxdWFsIHRvICJ2YWx1ZSIgZXZlbiB0aG91Z2ggaXQgd291bGQgYmUgZXhhY3RseSBlcXVhbCBpZiBpdCB3ZXJlCisgIC8vIHRydW5jYXRlZCB0byBhIGRvdWJsZS4KKyAgdm9sYXRpbGUgZG91YmxlIHBhcnNlZF92YWx1ZSA9IHN0cnRvZChidWZmZXIsIE5VTEwpOworICBpZiAocGFyc2VkX3ZhbHVlICE9IHZhbHVlKSB7CisgICAgaW50IHNucHJpbnRmX3Jlc3VsdCA9CisgICAgICBzbnByaW50ZihidWZmZXIsIGtEb3VibGVUb0J1ZmZlclNpemUsICIlLipnIiwgREJMX0RJRysyLCB2YWx1ZSk7CisKKyAgICAvLyBTaG91bGQgbmV2ZXIgb3ZlcmZsb3c7IHNlZSBhYm92ZS4KKyAgICBHT09HTEVfRENIRUNLKHNucHJpbnRmX3Jlc3VsdCA+IDAgJiYgc25wcmludGZfcmVzdWx0IDwga0RvdWJsZVRvQnVmZmVyU2l6ZSk7CisgIH0KKworICBEZWxvY2FsaXplUmFkaXgoYnVmZmVyKTsKKyAgcmV0dXJuIGJ1ZmZlcjsKK30KKworYm9vbCBzYWZlX3N0cnRvZihjb25zdCBjaGFyKiBzdHIsIGZsb2F0KiB2YWx1ZSkgeworICBjaGFyKiBlbmRwdHI7CisgIGVycm5vID0gMDsgIC8vIGVycm5vIG9ubHkgZ2V0cyBzZXQgb24gZXJyb3JzCisjaWYgZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQgKF9faHB1eCkgIC8vIGhhcyBubyBzdHJ0b2YoKQorICAqdmFsdWUgPSBzdHJ0b2Qoc3RyLCAmZW5kcHRyKTsKKyNlbHNlCisgICp2YWx1ZSA9IHN0cnRvZihzdHIsICZlbmRwdHIpOworI2VuZGlmCisgIHJldHVybiAqc3RyICE9IDAgJiYgKmVuZHB0ciA9PSAwICYmIGVycm5vID09IDA7Cit9CisKK2NoYXIqIEZsb2F0VG9CdWZmZXIoZmxvYXQgdmFsdWUsIGNoYXIqIGJ1ZmZlcikgeworICAvLyBGTFRfRElHIGlzIDYgZm9yIElFRUUtNzU0IGZsb2F0cywgd2hpY2ggYXJlIHVzZWQgb24gYWxtb3N0IGFsbAorICAvLyBwbGF0Zm9ybXMgdGhlc2UgZGF5cy4gIEp1c3QgaW4gY2FzZSBzb21lIHN5c3RlbSBleGlzdHMgd2hlcmUgRkxUX0RJRworICAvLyBpcyBzaWduaWZpY2FudGx5IGxhcmdlciAtLSBhbmQgcmlza3Mgb3ZlcmZsb3dpbmcgb3VyIGJ1ZmZlciAtLSB3ZSBoYXZlCisgIC8vIHRoaXMgYXNzZXJ0LgorICBHT09HTEVfQ09NUElMRV9BU1NFUlQoRkxUX0RJRyA8IDEwLCBGTFRfRElHX2lzX3Rvb19iaWcpOworCisgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgc3RyY3B5KGJ1ZmZlciwgImluZiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICBzdHJjcHkoYnVmZmVyLCAiLWluZiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0gZWxzZSBpZiAoSXNOYU4odmFsdWUpKSB7CisgICAgc3RyY3B5KGJ1ZmZlciwgIm5hbiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0KKworICBpbnQgc25wcmludGZfcmVzdWx0ID0KKyAgICBzbnByaW50ZihidWZmZXIsIGtGbG9hdFRvQnVmZmVyU2l6ZSwgIiUuKmciLCBGTFRfRElHLCB2YWx1ZSk7CisKKyAgLy8gVGhlIHNucHJpbnRmIHNob3VsZCBuZXZlciBvdmVyZmxvdyBiZWNhdXNlIHRoZSBidWZmZXIgaXMgc2lnbmlmaWNhbnRseQorICAvLyBsYXJnZXIgdGhhbiB0aGUgcHJlY2lzaW9uIHdlIGFza2VkIGZvci4KKyAgR09PR0xFX0RDSEVDSyhzbnByaW50Zl9yZXN1bHQgPiAwICYmIHNucHJpbnRmX3Jlc3VsdCA8IGtGbG9hdFRvQnVmZmVyU2l6ZSk7CisKKyAgZmxvYXQgcGFyc2VkX3ZhbHVlOworICBpZiAoIXNhZmVfc3RydG9mKGJ1ZmZlciwgJnBhcnNlZF92YWx1ZSkgfHwgcGFyc2VkX3ZhbHVlICE9IHZhbHVlKSB7CisgICAgaW50IHNucHJpbnRmX3Jlc3VsdCA9CisgICAgICBzbnByaW50ZihidWZmZXIsIGtGbG9hdFRvQnVmZmVyU2l6ZSwgIiUuKmciLCBGTFRfRElHKzIsIHZhbHVlKTsKKworICAgIC8vIFNob3VsZCBuZXZlciBvdmVyZmxvdzsgc2VlIGFib3ZlLgorICAgIEdPT0dMRV9EQ0hFQ0soc25wcmludGZfcmVzdWx0ID4gMCAmJiBzbnByaW50Zl9yZXN1bHQgPCBrRmxvYXRUb0J1ZmZlclNpemUpOworICB9CisKKyAgRGVsb2NhbGl6ZVJhZGl4KGJ1ZmZlcik7CisgIHJldHVybiBidWZmZXI7Cit9CisKK3N0cmluZyBUb0hleCh1aW50NjQgbnVtKSB7CisgIGlmIChudW0gPT0gMCkgeworICAgIHJldHVybiBzdHJpbmcoIjAiKTsKKyAgfQorCisgIC8vIENvbXB1dGUgaGV4IGJ5dGVzIGluIHJldmVyc2Ugb3JkZXIsIHdyaXRpbmcgdG8gdGhlIGJhY2sgb2YgdGhlCisgIC8vIGJ1ZmZlci4KKyAgY2hhciBidWZbMTZdOyAgLy8gTm8gbW9yZSB0aGFuIDE2IGhleCBkaWdpdHMgbmVlZGVkLgorICBjaGFyKiBidWZwdHIgPSBidWYgKyAxNjsKKyAgc3RhdGljIGNvbnN0IGNoYXIga0hleENoYXJzW10gPSAiMDEyMzQ1Njc4OWFiY2RlZiI7CisgIHdoaWxlIChudW0gIT0gMCkgeworICAgICotLWJ1ZnB0ciA9IGtIZXhDaGFyc1tudW0gJiAweGZdOworICAgIG51bSA+Pj0gNDsKKyAgfQorCisgIHJldHVybiBzdHJpbmcoYnVmcHRyLCBidWYgKyAxNiAtIGJ1ZnB0cik7Cit9CisKK25hbWVzcGFjZSBzdHJpbmdzIHsKKworQWxwaGFOdW06OkFscGhhTnVtKHN0cmluZ3M6OkhleCBoZXgpIHsKKyAgY2hhciAqY29uc3QgZW5kID0gJmRpZ2l0c1trRmFzdFRvQnVmZmVyU2l6ZV07CisgIGNoYXIgKndyaXRlciA9IGVuZDsKKyAgdWludDY0IHZhbHVlID0gaGV4LnZhbHVlOworICB1aW50NjQgd2lkdGggPSBoZXguc3BlYzsKKyAgLy8gV2UgYWNjb21wbGlzaCBtaW5pbXVtIHdpZHRoIGJ5IE9SJ2luZyBpbiAweDEwMDAwIHRvIHRoZSB1c2VyJ3MgdmFsdWUsCisgIC8vIHdoZXJlIDB4MTAwMDAgaXMgdGhlIHNtYWxsZXN0IGhleCBudW1iZXIgdGhhdCBpcyBhcyB3aWRlIGFzIHRoZSB1c2VyCisgIC8vIGFza2VkIGZvci4KKyAgdWludDY0IG1hc2sgPSAoKHN0YXRpY19jYXN0PHVpbnQ2ND4oMSkgPDwgKHdpZHRoIC0gMSkgKiA0KSkgfCB2YWx1ZTsKKyAgc3RhdGljIGNvbnN0IGNoYXIgaGV4ZGlnaXRzW10gPSAiMDEyMzQ1Njc4OWFiY2RlZiI7CisgIGRvIHsKKyAgICAqLS13cml0ZXIgPSBoZXhkaWdpdHNbdmFsdWUgJiAweEZdOworICAgIHZhbHVlID4+PSA0OworICAgIG1hc2sgPj49IDQ7CisgIH0gd2hpbGUgKG1hc2sgIT0gMCk7CisgIHBpZWNlX2RhdGFfID0gd3JpdGVyOworICBwaWVjZV9zaXplXyA9IGVuZCAtIHdyaXRlcjsKK30KKworfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyQ2F0KCkKKy8vICAgIFRoaXMgbWVyZ2VzIHRoZSBnaXZlbiBzdHJpbmdzIG9yIGludGVnZXJzLCB3aXRoIG5vIGRlbGltaXRlci4gIFRoaXMKKy8vICAgIGlzIGRlc2lnbmVkIHRvIGJlIHRoZSBmYXN0ZXN0IHBvc3NpYmxlIHdheSB0byBjb25zdHJ1Y3QgYSBzdHJpbmcgb3V0CisvLyAgICBvZiBhIG1peCBvZiByYXcgQyBzdHJpbmdzLCBDKysgc3RyaW5ncywgYW5kIGludGVnZXIgdmFsdWVzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBBcHBlbmQgaXMgbWVyZWx5IGEgdmVyc2lvbiBvZiBtZW1jcHkgdGhhdCByZXR1cm5zIHRoZSBhZGRyZXNzIG9mIHRoZSBieXRlCisvLyBhZnRlciB0aGUgYXJlYSBqdXN0IG92ZXJ3cml0dGVuLiAgSXQgY29tZXMgaW4gbXVsdGlwbGUgZmxhdm9ycyB0byBtaW5pbWl6ZQorLy8gY2FsbCBvdmVyaGVhZC4KK3N0YXRpYyBjaGFyICpBcHBlbmQxKGNoYXIgKm91dCwgY29uc3QgQWxwaGFOdW0gJngpIHsKKyAgbWVtY3B5KG91dCwgeC5kYXRhKCksIHguc2l6ZSgpKTsKKyAgcmV0dXJuIG91dCArIHguc2l6ZSgpOworfQorCitzdGF0aWMgY2hhciAqQXBwZW5kMihjaGFyICpvdXQsIGNvbnN0IEFscGhhTnVtICZ4MSwgY29uc3QgQWxwaGFOdW0gJngyKSB7CisgIG1lbWNweShvdXQsIHgxLmRhdGEoKSwgeDEuc2l6ZSgpKTsKKyAgb3V0ICs9IHgxLnNpemUoKTsKKworICBtZW1jcHkob3V0LCB4Mi5kYXRhKCksIHgyLnNpemUoKSk7CisgIHJldHVybiBvdXQgKyB4Mi5zaXplKCk7Cit9CisKK3N0YXRpYyBjaGFyICpBcHBlbmQ0KGNoYXIgKm91dCwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZ4MSwgY29uc3QgQWxwaGFOdW0gJngyLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJngzLCBjb25zdCBBbHBoYU51bSAmeDQpIHsKKyAgbWVtY3B5KG91dCwgeDEuZGF0YSgpLCB4MS5zaXplKCkpOworICBvdXQgKz0geDEuc2l6ZSgpOworCisgIG1lbWNweShvdXQsIHgyLmRhdGEoKSwgeDIuc2l6ZSgpKTsKKyAgb3V0ICs9IHgyLnNpemUoKTsKKworICBtZW1jcHkob3V0LCB4My5kYXRhKCksIHgzLnNpemUoKSk7CisgIG91dCArPSB4My5zaXplKCk7CisKKyAgbWVtY3B5KG91dCwgeDQuZGF0YSgpLCB4NC5zaXplKCkpOworICByZXR1cm4gb3V0ICsgeDQuc2l6ZSgpOworfQorCitzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYikgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkpOworICBjaGFyICpjb25zdCBiZWdpbiA9ICYqcmVzdWx0LmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDIoYmVnaW4sIGEsIGIpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQuc2l6ZSgpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIsIGNvbnN0IEFscGhhTnVtICZjKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNpemUoYS5zaXplKCkgKyBiLnNpemUoKSArIGMuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQyKGJlZ2luLCBhLCBiKTsKKyAgb3V0ID0gQXBwZW5kMShvdXQsIGMpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQuc2l6ZSgpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIsIGNvbnN0IEFscGhhTnVtICZjLAorICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmZCkgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSArIGQuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQ0KGJlZ2luLCBhLCBiLCBjLCBkKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNpemUoYS5zaXplKCkgKyBiLnNpemUoKSArIGMuc2l6ZSgpICsgZC5zaXplKCkgKyBlLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQuYmVnaW4oKTsKKyAgY2hhciAqb3V0ID0gQXBwZW5kNChiZWdpbiwgYSwgYiwgYywgZCk7CisgIG91dCA9IEFwcGVuZDEob3V0LCBlKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZikgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSArIGQuc2l6ZSgpICsgZS5zaXplKCkgKworICAgICAgICAgICAgICAgIGYuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQ0KGJlZ2luLCBhLCBiLCBjLCBkKTsKKyAgb3V0ID0gQXBwZW5kMihvdXQsIGUsIGYpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQuc2l6ZSgpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIsIGNvbnN0IEFscGhhTnVtICZjLAorICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmZCwgY29uc3QgQWxwaGFOdW0gJmUsIGNvbnN0IEFscGhhTnVtICZmLAorICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmZykgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSArIGQuc2l6ZSgpICsgZS5zaXplKCkgKworICAgICAgICAgICAgICAgIGYuc2l6ZSgpICsgZy5zaXplKCkpOworICBjaGFyICpjb25zdCBiZWdpbiA9ICYqcmVzdWx0LmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDQoYmVnaW4sIGEsIGIsIGMsIGQpOworICBvdXQgPSBBcHBlbmQyKG91dCwgZSwgZik7CisgIG91dCA9IEFwcGVuZDEob3V0LCBnKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZiwKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmcsIGNvbnN0IEFscGhhTnVtICZoKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNpemUoYS5zaXplKCkgKyBiLnNpemUoKSArIGMuc2l6ZSgpICsgZC5zaXplKCkgKyBlLnNpemUoKSArCisgICAgICAgICAgICAgICAgZi5zaXplKCkgKyBnLnNpemUoKSArIGguc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQ0KGJlZ2luLCBhLCBiLCBjLCBkKTsKKyAgb3V0ID0gQXBwZW5kNChvdXQsIGUsIGYsIGcsIGgpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQuc2l6ZSgpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIsIGNvbnN0IEFscGhhTnVtICZjLAorICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmZCwgY29uc3QgQWxwaGFOdW0gJmUsIGNvbnN0IEFscGhhTnVtICZmLAorICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmZywgY29uc3QgQWxwaGFOdW0gJmgsIGNvbnN0IEFscGhhTnVtICZpKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNpemUoYS5zaXplKCkgKyBiLnNpemUoKSArIGMuc2l6ZSgpICsgZC5zaXplKCkgKyBlLnNpemUoKSArCisgICAgICAgICAgICAgICAgZi5zaXplKCkgKyBnLnNpemUoKSArIGguc2l6ZSgpICsgaS5zaXplKCkpOworICBjaGFyICpjb25zdCBiZWdpbiA9ICYqcmVzdWx0LmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDQoYmVnaW4sIGEsIGIsIGMsIGQpOworICBvdXQgPSBBcHBlbmQ0KG91dCwgZSwgZiwgZywgaCk7CisgIG91dCA9IEFwcGVuZDEob3V0LCBpKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEl0J3MgcG9zc2libGUgdG8gY2FsbCBTdHJBcHBlbmQgd2l0aCBhIGNoYXIgKiBwb2ludGVyIHRoYXQgaXMgcGFydHdheSBpbnRvCisvLyB0aGUgc3RyaW5nIHdlJ3JlIGFwcGVuZGluZyB0by4gIEhvd2V2ZXIgdGhlIHJlc3VsdHMgb2YgdGhpcyBhcmUgcmFuZG9tLgorLy8gVGhlcmVmb3JlLCBjaGVjayBmb3IgdGhpcyBpbiBkZWJ1ZyBtb2RlLiAgVXNlIHVuc2lnbmVkIG1hdGggc28gd2Ugb25seSBoYXZlCisvLyB0byBkbyBvbmUgY29tcGFyaXNvbi4KKyNkZWZpbmUgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKGRlc3QsIHNyYykgXAorICAgIEdPT0dMRV9EQ0hFQ0tfR1QodWludHB0cl90KChzcmMpLmRhdGEoKSAtIChkZXN0KS5kYXRhKCkpLCBcCisgICAgICAgICAgICAgICAgICAgICB1aW50cHRyX3QoKGRlc3QpLnNpemUoKSkpCisKK3ZvaWQgU3RyQXBwZW5kKHN0cmluZyAqcmVzdWx0LCBjb25zdCBBbHBoYU51bSAmYSkgeworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgYSk7CisgIHJlc3VsdC0+YXBwZW5kKGEuZGF0YSgpLCBhLnNpemUoKSk7Cit9CisKK3ZvaWQgU3RyQXBwZW5kKHN0cmluZyAqcmVzdWx0LCBjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIpIHsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGEpOworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgYik7CisgIHN0cmluZzo6c2l6ZV90eXBlIG9sZF9zaXplID0gcmVzdWx0LT5zaXplKCk7CisgIHJlc3VsdC0+cmVzaXplKG9sZF9zaXplICsgYS5zaXplKCkgKyBiLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQtPmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDIoYmVnaW4gKyBvbGRfc2l6ZSwgYSwgYik7CisgIEdPT0dMRV9EQ0hFQ0tfRVEob3V0LCBiZWdpbiArIHJlc3VsdC0+c2l6ZSgpKTsKK30KKwordm9pZCBTdHJBcHBlbmQoc3RyaW5nICpyZXN1bHQsCisgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIsIGNvbnN0IEFscGhhTnVtICZjKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUCgqcmVzdWx0LCBhKTsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGIpOworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgYyk7CisgIHN0cmluZzo6c2l6ZV90eXBlIG9sZF9zaXplID0gcmVzdWx0LT5zaXplKCk7CisgIHJlc3VsdC0+cmVzaXplKG9sZF9zaXplICsgYS5zaXplKCkgKyBiLnNpemUoKSArIGMuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC0+YmVnaW4oKTsKKyAgY2hhciAqb3V0ID0gQXBwZW5kMihiZWdpbiArIG9sZF9zaXplLCBhLCBiKTsKKyAgb3V0ID0gQXBwZW5kMShvdXQsIGMpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQtPnNpemUoKSk7Cit9CisKK3ZvaWQgU3RyQXBwZW5kKHN0cmluZyAqcmVzdWx0LAorICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLAorICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmMsIGNvbnN0IEFscGhhTnVtICZkKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUCgqcmVzdWx0LCBhKTsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGIpOworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgYyk7CisgIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUCgqcmVzdWx0LCBkKTsKKyAgc3RyaW5nOjpzaXplX3R5cGUgb2xkX3NpemUgPSByZXN1bHQtPnNpemUoKTsKKyAgcmVzdWx0LT5yZXNpemUob2xkX3NpemUgKyBhLnNpemUoKSArIGIuc2l6ZSgpICsgYy5zaXplKCkgKyBkLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQtPmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDQoYmVnaW4gKyBvbGRfc2l6ZSwgYSwgYiwgYywgZCk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEob3V0LCBiZWdpbiArIHJlc3VsdC0+c2l6ZSgpKTsKK30KKworaW50IEdsb2JhbFJlcGxhY2VTdWJzdHJpbmcoY29uc3Qgc3RyaW5nJiBzdWJzdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHJlcGxhY2VtZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBzKSB7CisgIEdPT0dMRV9DSEVDSyhzICE9IE5VTEwpOworICBpZiAocy0+ZW1wdHkoKSB8fCBzdWJzdHJpbmcuZW1wdHkoKSkKKyAgICByZXR1cm4gMDsKKyAgc3RyaW5nIHRtcDsKKyAgaW50IG51bV9yZXBsYWNlbWVudHMgPSAwOworICBpbnQgcG9zID0gMDsKKyAgZm9yIChpbnQgbWF0Y2hfcG9zID0gcy0+ZmluZChzdWJzdHJpbmcuZGF0YSgpLCBwb3MsIHN1YnN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgbWF0Y2hfcG9zICE9IHN0cmluZzo6bnBvczsKKyAgICAgICBwb3MgPSBtYXRjaF9wb3MgKyBzdWJzdHJpbmcubGVuZ3RoKCksCisgICAgICAgICAgIG1hdGNoX3BvcyA9IHMtPmZpbmQoc3Vic3RyaW5nLmRhdGEoKSwgcG9zLCBzdWJzdHJpbmcubGVuZ3RoKCkpKSB7CisgICAgKytudW1fcmVwbGFjZW1lbnRzOworICAgIC8vIEFwcGVuZCB0aGUgb3JpZ2luYWwgY29udGVudCBiZWZvcmUgdGhlIG1hdGNoLgorICAgIHRtcC5hcHBlbmQoKnMsIHBvcywgbWF0Y2hfcG9zIC0gcG9zKTsKKyAgICAvLyBBcHBlbmQgdGhlIHJlcGxhY2VtZW50IGZvciB0aGUgbWF0Y2guCisgICAgdG1wLmFwcGVuZChyZXBsYWNlbWVudC5iZWdpbigpLCByZXBsYWNlbWVudC5lbmQoKSk7CisgIH0KKyAgLy8gQXBwZW5kIHRoZSBjb250ZW50IGFmdGVyIHRoZSBsYXN0IG1hdGNoLiBJZiBubyByZXBsYWNlbWVudHMgd2VyZSBtYWRlLCB0aGUKKyAgLy8gb3JpZ2luYWwgc3RyaW5nIGlzIGxlZnQgdW50b3VjaGVkLgorICBpZiAobnVtX3JlcGxhY2VtZW50cyA+IDApIHsKKyAgICB0bXAuYXBwZW5kKCpzLCBwb3MsIHMtPmxlbmd0aCgpIC0gcG9zKTsKKyAgICBzLT5zd2FwKHRtcCk7CisgIH0KKyAgcmV0dXJuIG51bV9yZXBsYWNlbWVudHM7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MjA3MDFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmgKQEAgLTAsMCArMSw3MDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBmcm9tIGdvb2dsZTMvc3RyaW5ncy9zdHJ1dGlsLmgKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RSVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUUlVUSUxfSF9fCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyNpZmRlZiBfTVNDX1ZFUgorI2RlZmluZSBzdHJ0b2xsICBfc3RydG9pNjQKKyNkZWZpbmUgc3RydG91bGwgX3N0cnRvdWk2NAorI2VsaWYgZGVmaW5lZChfX0RFQ0NYWCkgJiYgZGVmaW5lZChfX29zZl9fKQorLy8gSFAgQysrIG9uIFRydTY0IGRvZXMgbm90IGhhdmUgc3RydG9sbCwgYnV0IHN0cnRvbCBpcyBhbHJlYWR5IDY0LWJpdC4KKyNkZWZpbmUgc3RydG9sbCBzdHJ0b2wKKyNkZWZpbmUgc3RydG91bGwgc3RydG91bAorI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIGFzY2lpX2lzYWxudW0oKQorLy8gICAgQ2hlY2sgaWYgYW4gQVNDSUkgY2hhcmFjdGVyIGlzIGFscGhhbnVtZXJpYy4gIFdlIGNhbid0IHVzZSBjdHlwZSdzCisvLyAgICBpc2FsbnVtKCkgYmVjYXVzZSBpdCBpcyBhZmZlY3RlZCBieSBsb2NhbGUuICBUaGlzIGZ1bmN0aW9uIGlzIGFwcGxpZWQKKy8vICAgIHRvIGlkZW50aWZpZXJzIGluIHRoZSBwcm90b2NvbCBidWZmZXIgbGFuZ3VhZ2UsIG5vdCB0byBuYXR1cmFsLWxhbmd1YWdlCisvLyAgICBzdHJpbmdzLCBzbyBsb2NhbGUgc2hvdWxkIG5vdCBiZSB0YWtlbiBpbnRvIGFjY291bnQuCisvLyBhc2NpaV9pc2RpZ2l0KCkKKy8vICAgIExpa2UgYWJvdmUsIGJ1dCBvbmx5IGFjY2VwdHMgZGlnaXRzLgorLy8gYXNjaWlfaXNzcGFjZSgpCisvLyAgICBDaGVjayBpZiB0aGUgY2hhcmFjdGVyIGlzIGEgc3BhY2UgY2hhcmFjdGVyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbmxpbmUgYm9vbCBhc2NpaV9pc2FsbnVtKGNoYXIgYykgeworICByZXR1cm4gKCdhJyA8PSBjICYmIGMgPD0gJ3onKSB8fAorICAgICAgICAgKCdBJyA8PSBjICYmIGMgPD0gJ1onKSB8fAorICAgICAgICAgKCcwJyA8PSBjICYmIGMgPD0gJzknKTsKK30KKworaW5saW5lIGJvb2wgYXNjaWlfaXNkaWdpdChjaGFyIGMpIHsKKyAgcmV0dXJuICgnMCcgPD0gYyAmJiBjIDw9ICc5Jyk7Cit9CisKK2lubGluZSBib29sIGFzY2lpX2lzc3BhY2UoY2hhciBjKSB7CisgIHJldHVybiBjID09ICcgJzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gSGFzUHJlZml4U3RyaW5nKCkKKy8vICAgIENoZWNrIGlmIGEgc3RyaW5nIGJlZ2lucyB3aXRoIGEgZ2l2ZW4gcHJlZml4LgorLy8gU3RyaXBQcmVmaXhTdHJpbmcoKQorLy8gICAgR2l2ZW4gYSBzdHJpbmcgYW5kIGEgcHV0YXRpdmUgcHJlZml4LCByZXR1cm5zIHRoZSBzdHJpbmcgbWludXMgdGhlCisvLyAgICBwcmVmaXggc3RyaW5nIGlmIHRoZSBwcmVmaXggbWF0Y2hlcywgb3RoZXJ3aXNlIHRoZSBvcmlnaW5hbAorLy8gICAgc3RyaW5nLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoraW5saW5lIGJvb2wgSGFzUHJlZml4U3RyaW5nKGNvbnN0IHN0cmluZyYgc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4KSB7CisgIHJldHVybiBzdHIuc2l6ZSgpID49IHByZWZpeC5zaXplKCkgJiYKKyAgICAgICAgIHN0ci5jb21wYXJlKDAsIHByZWZpeC5zaXplKCksIHByZWZpeCkgPT0gMDsKK30KKworaW5saW5lIHN0cmluZyBTdHJpcFByZWZpeFN0cmluZyhjb25zdCBzdHJpbmcmIHN0ciwgY29uc3Qgc3RyaW5nJiBwcmVmaXgpIHsKKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhzdHIsIHByZWZpeCkpIHsKKyAgICByZXR1cm4gc3RyLnN1YnN0cihwcmVmaXguc2l6ZSgpKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gc3RyOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEhhc1N1ZmZpeFN0cmluZygpCisvLyAgICBSZXR1cm4gdHJ1ZSBpZiBzdHIgZW5kcyBpbiBzdWZmaXguCisvLyBTdHJpcFN1ZmZpeFN0cmluZygpCisvLyAgICBHaXZlbiBhIHN0cmluZyBhbmQgYSBwdXRhdGl2ZSBzdWZmaXgsIHJldHVybnMgdGhlIHN0cmluZyBtaW51cyB0aGUKKy8vICAgIHN1ZmZpeCBzdHJpbmcgaWYgdGhlIHN1ZmZpeCBtYXRjaGVzLCBvdGhlcndpc2UgdGhlIG9yaWdpbmFsCisvLyAgICBzdHJpbmcuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbmxpbmUgYm9vbCBIYXNTdWZmaXhTdHJpbmcoY29uc3Qgc3RyaW5nJiBzdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBzdWZmaXgpIHsKKyAgcmV0dXJuIHN0ci5zaXplKCkgPj0gc3VmZml4LnNpemUoKSAmJgorICAgICAgICAgc3RyLmNvbXBhcmUoc3RyLnNpemUoKSAtIHN1ZmZpeC5zaXplKCksIHN1ZmZpeC5zaXplKCksIHN1ZmZpeCkgPT0gMDsKK30KKworaW5saW5lIHN0cmluZyBTdHJpcFN1ZmZpeFN0cmluZyhjb25zdCBzdHJpbmcmIHN0ciwgY29uc3Qgc3RyaW5nJiBzdWZmaXgpIHsKKyAgaWYgKEhhc1N1ZmZpeFN0cmluZyhzdHIsIHN1ZmZpeCkpIHsKKyAgICByZXR1cm4gc3RyLnN1YnN0cigwLCBzdHIuc2l6ZSgpIC0gc3VmZml4LnNpemUoKSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHN0cjsKKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTdHJpcFN0cmluZworLy8gICAgUmVwbGFjZXMgYW55IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciAncmVtb3ZlJyAob3IgdGhlIGNoYXJhY3RlcnMKKy8vICAgIGluICdyZW1vdmUnKSB3aXRoIHRoZSBjaGFyYWN0ZXIgJ3JlcGxhY2V3aXRoJy4KKy8vICAgIEdvb2QgZm9yIGtlZXBpbmcgaHRtbCBjaGFyYWN0ZXJzIG9yIHByb3RvY29sIGNoYXJhY3RlcnMgKFx0KSBvdXQKKy8vICAgIG9mIHBsYWNlcyB3aGVyZSB0aGV5IG1pZ2h0IGNhdXNlIGEgcHJvYmxlbS4KKy8vIFN0cmlwV2hpdGVzcGFjZQorLy8gICAgUmVtb3ZlcyB3aGl0ZXNwYWNlcyBmcm9tIGJvdGggZW5kcyBvZiB0aGUgZ2l2ZW4gc3RyaW5nLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3RyaXBTdHJpbmcoc3RyaW5nKiBzLCBjb25zdCBjaGFyKiByZW1vdmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIHJlcGxhY2V3aXRoKTsKKworTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3RyaXBXaGl0ZXNwYWNlKHN0cmluZyogcyk7CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTG93ZXJTdHJpbmcoKQorLy8gVXBwZXJTdHJpbmcoKQorLy8gVG9VcHBlcigpCisvLyAgICBDb252ZXJ0IHRoZSBjaGFyYWN0ZXJzIGluICJzIiB0byBsb3dlcmNhc2Ugb3IgdXBwZXJjYXNlLiAgQVNDSUktb25seToKKy8vICAgIHRoZXNlIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGlnbm9yZSBsb2NhbGUgYmVjYXVzZSB0aGV5IGFyZSBhcHBsaWVkIHRvCisvLyAgICBpZGVudGlmaWVycyB1c2VkIGluIHRoZSBQcm90b2NvbCBCdWZmZXIgbGFuZ3VhZ2UsIG5vdCB0byBuYXR1cmFsLWxhbmd1YWdlCisvLyAgICBzdHJpbmdzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbmxpbmUgdm9pZCBMb3dlclN0cmluZyhzdHJpbmcgKiBzKSB7CisgIHN0cmluZzo6aXRlcmF0b3IgZW5kID0gcy0+ZW5kKCk7CisgIGZvciAoc3RyaW5nOjppdGVyYXRvciBpID0gcy0+YmVnaW4oKTsgaSAhPSBlbmQ7ICsraSkgeworICAgIC8vIHRvbG93ZXIoKSBjaGFuZ2VzIGJhc2VkIG9uIGxvY2FsZS4gIFdlIGRvbid0IHdhbnQgdGhpcyEKKyAgICBpZiAoJ0EnIDw9ICppICYmICppIDw9ICdaJykgKmkgKz0gJ2EnIC0gJ0EnOworICB9Cit9CisKK2lubGluZSB2b2lkIFVwcGVyU3RyaW5nKHN0cmluZyAqIHMpIHsKKyAgc3RyaW5nOjppdGVyYXRvciBlbmQgPSBzLT5lbmQoKTsKKyAgZm9yIChzdHJpbmc6Oml0ZXJhdG9yIGkgPSBzLT5iZWdpbigpOyBpICE9IGVuZDsgKytpKSB7CisgICAgLy8gdG91cHBlcigpIGNoYW5nZXMgYmFzZWQgb24gbG9jYWxlLiAgV2UgZG9uJ3Qgd2FudCB0aGlzIQorICAgIGlmICgnYScgPD0gKmkgJiYgKmkgPD0gJ3onKSAqaSArPSAnQScgLSAnYSc7CisgIH0KK30KKworaW5saW5lIHN0cmluZyBUb1VwcGVyKGNvbnN0IHN0cmluZyYgcykgeworICBzdHJpbmcgb3V0ID0gczsKKyAgVXBwZXJTdHJpbmcoJm91dCk7CisgIHJldHVybiBvdXQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFN0cmluZ1JlcGxhY2UoKQorLy8gICAgR2l2ZSBtZSBhIHN0cmluZyBhbmQgdHdvIHBhdHRlcm5zICJvbGQiIGFuZCAibmV3IiwgYW5kIEkgcmVwbGFjZQorLy8gICAgdGhlIGZpcnN0IGluc3RhbmNlIG9mICJvbGQiIGluIHRoZSBzdHJpbmcgd2l0aCAibmV3IiwgaWYgaXQKKy8vICAgIGV4aXN0cy4gIFJFVFVSTiBhIG5ldyBzdHJpbmcsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcmVwbGFjZW1lbnQKKy8vICAgIGhhcHBlbmVkIG9yIG5vdC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTdHJpbmdSZXBsYWNlKGNvbnN0IHN0cmluZyYgcywgY29uc3Qgc3RyaW5nJiBvbGRzdWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuZXdzdWIsIGJvb2wgcmVwbGFjZV9hbGwpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTcGxpdFN0cmluZ1VzaW5nKCkKKy8vICAgIFNwbGl0IGEgc3RyaW5nIHVzaW5nIGEgY2hhcmFjdGVyIGRlbGltaXRlci4gQXBwZW5kIHRoZSBjb21wb25lbnRzCisvLyAgICB0byAncmVzdWx0Jy4gIElmIHRoZXJlIGFyZSBjb25zZWN1dGl2ZSBkZWxpbWl0ZXJzLCB0aGlzIGZ1bmN0aW9uIHNraXBzCisvLyAgICBvdmVyIGFsbCBvZiB0aGVtLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3BsaXRTdHJpbmdVc2luZyhjb25zdCBzdHJpbmcmIGZ1bGwsIGNvbnN0IGNoYXIqIGRlbGltLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogcmVzKTsKKworLy8gU3BsaXQgYSBzdHJpbmcgdXNpbmcgb25lIG9yIG1vcmUgYnl0ZSBkZWxpbWl0ZXJzLCBwcmVzZW50ZWQKKy8vIGFzIGEgbnVsLXRlcm1pbmF0ZWQgYyBzdHJpbmcuIEFwcGVuZCB0aGUgY29tcG9uZW50cyB0byAncmVzdWx0Jy4KKy8vIElmIHRoZXJlIGFyZSBjb25zZWN1dGl2ZSBkZWxpbWl0ZXJzLCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuCisvLyBjb3JyZXNwb25kaW5nIGVtcHR5IHN0cmluZ3MuICBJZiB5b3Ugd2FudCB0byBkcm9wIHRoZSBlbXB0eQorLy8gc3RyaW5ncywgdHJ5IFNwbGl0U3RyaW5nVXNpbmcoKS4KKy8vCisvLyBJZiAiZnVsbCIgaXMgdGhlIGVtcHR5IHN0cmluZywgeWllbGRzIGFuIGVtcHR5IHN0cmluZyBhcyB0aGUgb25seSB2YWx1ZS4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIFNwbGl0U3RyaW5nQWxsb3dFbXB0eShjb25zdCBzdHJpbmcmIGZ1bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHJlc3VsdCk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNwbGl0KCkKKy8vICAgIFNwbGl0IGEgc3RyaW5nIHVzaW5nIGEgY2hhcmFjdGVyIGRlbGltaXRlci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2lubGluZSB2ZWN0b3I8c3RyaW5nPiBTcGxpdCgKKyAgICBjb25zdCBzdHJpbmcmIGZ1bGwsIGNvbnN0IGNoYXIqIGRlbGltLCBib29sIHNraXBfZW1wdHkgPSB0cnVlKSB7CisgIHZlY3RvcjxzdHJpbmc+IHJlc3VsdDsKKyAgaWYgKHNraXBfZW1wdHkpIHsKKyAgICBTcGxpdFN0cmluZ1VzaW5nKGZ1bGwsIGRlbGltLCAmcmVzdWx0KTsKKyAgfSBlbHNlIHsKKyAgICBTcGxpdFN0cmluZ0FsbG93RW1wdHkoZnVsbCwgZGVsaW0sICZyZXN1bHQpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEpvaW5TdHJpbmdzKCkKKy8vICAgIFRoZXNlIG1ldGhvZHMgY29uY2F0ZW5hdGUgYSB2ZWN0b3Igb2Ygc3RyaW5ncyBpbnRvIGEgQysrIHN0cmluZywgdXNpbmcKKy8vICAgIHRoZSBDLXN0cmluZyAiZGVsaW0iIGFzIGEgc2VwYXJhdG9yIGJldHdlZW4gY29tcG9uZW50cy4gVGhlcmUgYXJlIHR3bworLy8gICAgZmxhdm9ycyBvZiB0aGUgZnVuY3Rpb24sIG9uZSBmbGF2b3IgcmV0dXJucyB0aGUgY29uY2F0ZW5hdGVkIHN0cmluZywKKy8vICAgIGFub3RoZXIgdGFrZXMgYSBwb2ludGVyIHRvIHRoZSB0YXJnZXQgc3RyaW5nLiBJbiB0aGUgbGF0dGVyIGNhc2UgdGhlCisvLyAgICB0YXJnZXQgc3RyaW5nIGlzIGNsZWFyZWQgYW5kIG92ZXJ3cml0dGVuLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgSm9pblN0cmluZ3MoY29uc3QgdmVjdG9yPHN0cmluZz4mIGNvbXBvbmVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSwgc3RyaW5nKiByZXN1bHQpOworCitpbmxpbmUgc3RyaW5nIEpvaW5TdHJpbmdzKGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBjb21wb25lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSkgeworICBzdHJpbmcgcmVzdWx0OworICBKb2luU3RyaW5ncyhjb21wb25lbnRzLCBkZWxpbSwgJnJlc3VsdCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcygpCisvLyAgICBDb3BpZXMgInNvdXJjZSIgdG8gImRlc3QiLCByZXdyaXRpbmcgQy1zdHlsZSBlc2NhcGUgc2VxdWVuY2VzCisvLyAgICAtLSAnXG4nLCAnXHInLCAnXFwnLCAnXG9vbycsIGV0YyAtLSB0byB0aGVpciBBU0NJSQorLy8gICAgZXF1aXZhbGVudHMuICAiZGVzdCIgbXVzdCBiZSBzdWZmaWNpZW50bHkgbGFyZ2UgdG8gaG9sZCBhbGwKKy8vICAgIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSByZXdyaXR0ZW4gc3RyaW5nIChpLmUuIGF0IGxlYXN0IGFzIGxhcmdlCisvLyAgICBhcyBzdHJsZW4oc291cmNlKSArIDEgc2hvdWxkIGJlIHNhZmUsIHNpbmNlIHRoZSByZXBsYWNlbWVudHMKKy8vICAgIGFyZSBhbHdheXMgc2hvcnRlciB0aGFuIHRoZSBvcmlnaW5hbCBlc2NhcGVkIHNlcXVlbmNlcykuICBJdCdzCisvLyAgICBzYWZlIGZvciBzb3VyY2UgYW5kIGRlc3QgdG8gYmUgdGhlIHNhbWUuICBSRVRVUk5TIHRoZSBsZW5ndGgKKy8vICAgIG9mIGRlc3QuCisvLworLy8gICAgSXQgYWxsb3dzIGhleCBzZXF1ZW5jZXMgXHhoaCwgb3IgZ2VuZXJhbGx5IFx4aGhoaGggd2l0aCBhbgorLy8gICAgYXJiaXRyYXJ5IG51bWJlciBvZiBoZXggZGlnaXRzLCBidXQgYWxsIG9mIHRoZW0gdG9nZXRoZXIgbXVzdAorLy8gICAgc3BlY2lmeSBhIHZhbHVlIG9mIGEgc2luZ2xlIGJ5dGUgKGUuZy4gXHgwMDQ1IGlzIGVxdWl2YWxlbnQKKy8vICAgIHRvIFx4NDUsIGFuZCBceDEyMzQgaXMgZXJyb25lb3VzKS4KKy8vCisvLyAgICBJdCBhbHNvIGFsbG93cyBlc2NhcGUgc2VxdWVuY2VzIG9mIHRoZSBmb3JtIFx1aGhoaCAoZXhhY3RseSBmb3VyCisvLyAgICBoZXggZGlnaXRzLCB1cHBlciBvciBsb3dlciBjYXNlKSBvciBcVWhoaGhoaGhoIChleGFjdGx5IGVpZ2h0CisvLyAgICBoZXggZGlnaXRzLCB1cHBlciBvciBsb3dlciBjYXNlKSB0byBzcGVjaWZ5IGEgVW5pY29kZSBjb2RlCisvLyAgICBwb2ludC4gVGhlIGRlc3QgYXJyYXkgd2lsbCBjb250YWluIHRoZSBVVEY4LWVuY29kZWQgdmVyc2lvbiBvZgorLy8gICAgdGhhdCBjb2RlLXBvaW50IChlLmcuLCBpZiBzb3VyY2UgY29udGFpbnMgXHUyMDE5LCB0aGVuIGRlc3Qgd2lsbAorLy8gICAgY29udGFpbiB0aGUgdGhyZWUgYnl0ZXMgMHhFMiwgMHg4MCwgYW5kIDB4OTkpLgorLy8KKy8vICAgIEVycm9yczogSW4gdGhlIGZpcnN0IGZvcm0gb2YgdGhlIGNhbGwsIGVycm9ycyBhcmUgcmVwb3J0ZWQgd2l0aAorLy8gICAgTE9HKEVSUk9SKS4gVGhlIHNhbWUgaXMgdHJ1ZSBmb3IgdGhlIHNlY29uZCBmb3JtIG9mIHRoZSBjYWxsIGlmCisvLyAgICB0aGUgcG9pbnRlciB0byB0aGUgc3RyaW5nIHZlY3RvciBpcyBOVUxMOyBvdGhlcndpc2UsIGVycm9yCisvLyAgICBtZXNzYWdlcyBhcmUgc3RvcmVkIGluIHRoZSB2ZWN0b3IuIEluIGVpdGhlciBjYXNlLCB0aGUgZWZmZWN0IG9uCisvLyAgICB0aGUgZGVzdCBhcnJheSBpcyBub3QgZGVmaW5lZCwgYnV0IHJlc3Qgb2YgdGhlIHNvdXJjZSB3aWxsIGJlCisvLyAgICBwcm9jZXNzZWQuCisvLyAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgVW5lc2NhcGVDRXNjYXBlU2VxdWVuY2VzKGNvbnN0IGNoYXIqIHNvdXJjZSwgY2hhciogZGVzdCk7CitMSUJQUk9UT0JVRl9FWFBPUlQgaW50IFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcyhjb25zdCBjaGFyKiBzb3VyY2UsIGNoYXIqIGRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiAqZXJyb3JzKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVW5lc2NhcGVDRXNjYXBlU3RyaW5nKCkKKy8vICAgIFRoaXMgZG9lcyB0aGUgc2FtZSB0aGluZyBhcyBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMsIGJ1dCBjcmVhdGVzCisvLyAgICBhIG5ldyBzdHJpbmcuIFRoZSBjYWxsZXIgZG9lcyBub3QgbmVlZCB0byB3b3JyeSBhYm91dCBhbGxvY2F0aW5nCisvLyAgICBhIGRlc3QgYnVmZmVyLiBUaGlzIHNob3VsZCBiZSB1c2VkIGZvciBub24gcGVyZm9ybWFuY2UgY3JpdGljYWwKKy8vICAgIHRhc2tzIHN1Y2ggYXMgcHJpbnRpbmcgZGVidWcgbWVzc2FnZXMuIEl0IGlzIHNhZmUgZm9yIHNyYyBhbmQgZGVzdAorLy8gICAgdG8gYmUgdGhlIHNhbWUuCisvLworLy8gICAgVGhlIHNlY29uZCBjYWxsIHN0b3JlcyBpdHMgZXJyb3JzIGluIGEgc3VwcGxpZWQgc3RyaW5nIHZlY3Rvci4KKy8vICAgIElmIHRoZSBzdHJpbmcgdmVjdG9yIHBvaW50ZXIgaXMgTlVMTCwgaXQgcmVwb3J0cyB0aGUgZXJyb3JzIHdpdGggTE9HKCkuCisvLworLy8gICAgSW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgY2FsbHMsIHRoZSBsZW5ndGggb2YgZGVzdCBpcyByZXR1cm5lZC4gSW4gdGhlCisvLyAgICB0aGUgdGhpcmQgY2FsbCwgdGhlIG5ldyBzdHJpbmcgaXMgcmV0dXJuZWQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgVW5lc2NhcGVDRXNjYXBlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3JjLCBzdHJpbmcqIGRlc3QpOworTElCUFJPVE9CVUZfRVhQT1JUIGludCBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzcmMsIHN0cmluZyogZGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+ICplcnJvcnMpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzcmMpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBDRXNjYXBlU3RyaW5nKCkKKy8vICAgIENvcGllcyAnc3JjJyB0byAnZGVzdCcsIGVzY2FwaW5nIGRhbmdlcm91cyBjaGFyYWN0ZXJzIHVzaW5nCisvLyAgICBDLXN0eWxlIGVzY2FwZSBzZXF1ZW5jZXMuIFRoaXMgaXMgdmVyeSB1c2VmdWwgZm9yIHByZXBhcmluZyBxdWVyeQorLy8gICAgZmxhZ3MuICdzcmMnIGFuZCAnZGVzdCcgc2hvdWxkIG5vdCBvdmVybGFwLgorLy8gICAgUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gJ2Rlc3QnIChub3QgaW5jbHVkaW5nIHRoZSBcMCkKKy8vICAgIG9yIC0xIGlmIHRoZXJlIHdhcyBpbnN1ZmZpY2llbnQgc3BhY2UuCisvLworLy8gICAgQ3VycmVudGx5IG9ubHkgXG4sIFxyLCBcdCwgIiwgJywgXCBhbmQgIWlzcHJpbnQoKSBjaGFycyBhcmUgZXNjYXBlZC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgQ0VzY2FwZVN0cmluZyhjb25zdCBjaGFyKiBzcmMsIGludCBzcmNfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIqIGRlc3QsIGludCBkZXN0X2xlbik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIENFc2NhcGUoKQorLy8gICAgTW9yZSBjb252ZW5pZW50IGZvcm0gb2YgQ0VzY2FwZVN0cmluZzogcmV0dXJucyByZXN1bHQgYXMgYSAic3RyaW5nIi4KKy8vICAgIFRoaXMgdmVyc2lvbiBpcyBzbG93ZXIgdGhhbiBDRXNjYXBlU3RyaW5nKCkgYmVjYXVzZSBpdCBkb2VzIG1vcmUKKy8vICAgIGFsbG9jYXRpb24uICBIb3dldmVyLCBpdCBpcyBtdWNoIG1vcmUgY29udmVuaWVudCB0byB1c2UgaW4KKy8vICAgIG5vbi1zcGVlZC1jcml0aWNhbCBjb2RlIGxpa2UgbG9nZ2luZyBtZXNzYWdlcyBldGMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIENFc2NhcGUoY29uc3Qgc3RyaW5nJiBzcmMpOworCituYW1lc3BhY2Ugc3RyaW5ncyB7CisvLyBMaWtlIENFc2NhcGUoKSBidXQgZG9lcyBub3QgZXNjYXBlIGJ5dGVzIHdpdGggdGhlIHVwcGVyIGJpdCBzZXQuCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFV0ZjhTYWZlQ0VzY2FwZShjb25zdCBzdHJpbmcmIHNyYyk7CisKKy8vIExpa2UgQ0VzY2FwZSgpIGJ1dCB1c2VzIGhleCAoXHgpIGVzY2FwZXMgaW5zdGVhZCBvZiBvY3RhbHMuCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIENIZXhFc2NhcGUoY29uc3Qgc3RyaW5nJiBzcmMpOworfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gc3RydG8zMigpCisvLyBzdHJ0b3UzMigpCisvLyBzdHJ0bzY0KCkKKy8vIHN0cnRvdTY0KCkKKy8vICAgIEFyY2hpdGVjdHVyZS1uZXV0cmFsIHBsdWcgY29tcGF0aWJsZSByZXBsYWNlbWVudHMgZm9yIHN0cnRvbCgpIGFuZAorLy8gICAgc3RydG91bCgpLiAgTG9uZydzIGhhdmUgZGlmZmVyZW50IGxlbmd0aHMgb24gSUxQLTMyIGFuZCBMUC02NAorLy8gICAgcGxhdGZvcm1zLCBzbyB1c2luZyB0aGVzZSBpcyBzYWZlciwgZnJvbSB0aGUgcG9pbnQgb2YgdmlldyBvZgorLy8gICAgb3ZlcmZsb3cgYmVoYXZpb3IsIHRoYW4gdXNpbmcgdGhlIHN0YW5kYXJkIGxpYmMgZnVuY3Rpb25zLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIGludDMyIHN0cnRvMzJfYWRhcHRvcihjb25zdCBjaGFyICpucHRyLCBjaGFyICoqZW5kcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmFzZSk7CitMSUJQUk9UT0JVRl9FWFBPUlQgdWludDMyIHN0cnRvdTMyX2FkYXB0b3IoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmFzZSk7CisKK2lubGluZSBpbnQzMiBzdHJ0bzMyKGNvbnN0IGNoYXIgKm5wdHIsIGNoYXIgKiplbmRwdHIsIGludCBiYXNlKSB7CisgIGlmIChzaXplb2YoaW50MzIpID09IHNpemVvZihsb25nKSkKKyAgICByZXR1cm4gc3RydG9sKG5wdHIsIGVuZHB0ciwgYmFzZSk7CisgIGVsc2UKKyAgICByZXR1cm4gc3RydG8zMl9hZGFwdG9yKG5wdHIsIGVuZHB0ciwgYmFzZSk7Cit9CisKK2lubGluZSB1aW50MzIgc3RydG91MzIoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwgaW50IGJhc2UpIHsKKyAgaWYgKHNpemVvZih1aW50MzIpID09IHNpemVvZih1bnNpZ25lZCBsb25nKSkKKyAgICByZXR1cm4gc3RydG91bChucHRyLCBlbmRwdHIsIGJhc2UpOworICBlbHNlCisgICAgcmV0dXJuIHN0cnRvdTMyX2FkYXB0b3IobnB0ciwgZW5kcHRyLCBiYXNlKTsKK30KKworLy8gRm9yIG5vdywgbG9uZyBsb25nIGlzIDY0LWJpdCBvbiBhbGwgdGhlIHBsYXRmb3JtcyB3ZSBjYXJlIGFib3V0LCBzbyB0aGVzZQorLy8gZnVuY3Rpb25zIGNhbiBzaW1wbHkgcGFzcyB0aGUgY2FsbCB0byBzdHJ0b1t1XWxsLgoraW5saW5lIGludDY0IHN0cnRvNjQoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwgaW50IGJhc2UpIHsKKyAgR09PR0xFX0NPTVBJTEVfQVNTRVJUKHNpemVvZihpbnQ2NCkgPT0gc2l6ZW9mKGxvbmcgbG9uZyksCisgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2ZfaW50NjRfaXNfbm90X3NpemVvZl9sb25nX2xvbmcpOworICByZXR1cm4gc3RydG9sbChucHRyLCBlbmRwdHIsIGJhc2UpOworfQorCitpbmxpbmUgdWludDY0IHN0cnRvdTY0KGNvbnN0IGNoYXIgKm5wdHIsIGNoYXIgKiplbmRwdHIsIGludCBiYXNlKSB7CisgIEdPT0dMRV9DT01QSUxFX0FTU0VSVChzaXplb2YodWludDY0KSA9PSBzaXplb2YodW5zaWduZWQgbG9uZyBsb25nKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZl91aW50NjRfaXNfbm90X3NpemVvZl9sb25nX2xvbmcpOworICByZXR1cm4gc3RydG91bGwobnB0ciwgZW5kcHRyLCBiYXNlKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gc2FmZV9zdHJ0bzMyKCkKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIHNhZmVfaW50KHN0cmluZyB0ZXh0LCBpbnQzMiogdmFsdWVfcCk7CisKK2lubGluZSBib29sIHNhZmVfc3RydG8zMihzdHJpbmcgdGV4dCwgaW50MzIqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX2ludCh0ZXh0LCB2YWx1ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEZhc3RJbnRUb0J1ZmZlcigpCisvLyBGYXN0SGV4VG9CdWZmZXIoKQorLy8gRmFzdEhleDY0VG9CdWZmZXIoKQorLy8gRmFzdEhleDMyVG9CdWZmZXIoKQorLy8gRmFzdFRpbWVUb0J1ZmZlcigpCisvLyAgICBUaGVzZSBhcmUgaW50ZW5kZWQgZm9yIHNwZWVkLiAgRmFzdEludFRvQnVmZmVyKCkgYXNzdW1lcyB0aGUKKy8vICAgIGludGVnZXIgaXMgbm9uLW5lZ2F0aXZlLiAgRmFzdEhleFRvQnVmZmVyKCkgcHV0cyBvdXRwdXQgaW4KKy8vICAgIGhleCByYXRoZXIgdGhhbiBkZWNpbWFsLiAgRmFzdFRpbWVUb0J1ZmZlcigpIHB1dHMgdGhlIG91dHB1dAorLy8gICAgaW50byBSRkM4MjIgZm9ybWF0LgorLy8KKy8vICAgIEZhc3RIZXg2NFRvQnVmZmVyKCkgcHV0cyBhIDY0LWJpdCB1bnNpZ25lZCB2YWx1ZSBpbiBoZXgtZm9ybWF0LAorLy8gICAgcGFkZGVkIHRvIGV4YWN0bHkgMTYgYnl0ZXMgKHBsdXMgb25lIGJ5dGUgZm9yICdcMCcpCisvLworLy8gICAgRmFzdEhleDMyVG9CdWZmZXIoKSBwdXRzIGEgMzItYml0IHVuc2lnbmVkIHZhbHVlIGluIGhleC1mb3JtYXQsCisvLyAgICBwYWRkZWQgdG8gZXhhY3RseSA4IGJ5dGVzIChwbHVzIG9uZSBieXRlIGZvciAnXDAnKQorLy8KKy8vICAgICAgIEFsbCBmdW5jdGlvbnMgdGFrZSB0aGUgb3V0cHV0IGJ1ZmZlciBhcyBhbiBhcmcuCisvLyAgICBUaGV5IGFsbCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG91dHB1dCwKKy8vICAgIHdoaWNoIG1heSBub3QgYmUgdGhlIGJlZ2lubmluZyBvZiB0aGUgaW5wdXQgYnVmZmVyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBTdWdnZXN0ZWQgYnVmZmVyIHNpemUgZm9yIEZhc3RUb0J1ZmZlciBmdW5jdGlvbnMuICBBbHNvIHdvcmtzIHdpdGgKKy8vIERvdWJsZVRvQnVmZmVyKCkgYW5kIEZsb2F0VG9CdWZmZXIoKS4KK3N0YXRpYyBjb25zdCBpbnQga0Zhc3RUb0J1ZmZlclNpemUgPSAzMjsKKworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIEZhc3RJbnQzMlRvQnVmZmVyKGludDMyIGksIGNoYXIqIGJ1ZmZlcik7CitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdEludDY0VG9CdWZmZXIoaW50NjQgaSwgY2hhciogYnVmZmVyKTsKK2NoYXIqIEZhc3RVSW50MzJUb0J1ZmZlcih1aW50MzIgaSwgY2hhciogYnVmZmVyKTsgIC8vIGlubGluZSBiZWxvdworY2hhciogRmFzdFVJbnQ2NFRvQnVmZmVyKHVpbnQ2NCBpLCBjaGFyKiBidWZmZXIpOyAgLy8gaW5saW5lIGJlbG93CitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdEhleFRvQnVmZmVyKGludCBpLCBjaGFyKiBidWZmZXIpOworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIEZhc3RIZXg2NFRvQnVmZmVyKHVpbnQ2NCBpLCBjaGFyKiBidWZmZXIpOworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIEZhc3RIZXgzMlRvQnVmZmVyKHVpbnQzMiBpLCBjaGFyKiBidWZmZXIpOworCisvLyBhdCBsZWFzdCAyMiBieXRlcyBsb25nCitpbmxpbmUgY2hhciogRmFzdEludFRvQnVmZmVyKGludCBpLCBjaGFyKiBidWZmZXIpIHsKKyAgcmV0dXJuIChzaXplb2YoaSkgPT0gNCA/CisgICAgICAgICAgRmFzdEludDMyVG9CdWZmZXIoaSwgYnVmZmVyKSA6IEZhc3RJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcikpOworfQoraW5saW5lIGNoYXIqIEZhc3RVSW50VG9CdWZmZXIodW5zaWduZWQgaW50IGksIGNoYXIqIGJ1ZmZlcikgeworICByZXR1cm4gKHNpemVvZihpKSA9PSA0ID8KKyAgICAgICAgICBGYXN0VUludDMyVG9CdWZmZXIoaSwgYnVmZmVyKSA6IEZhc3RVSW50NjRUb0J1ZmZlcihpLCBidWZmZXIpKTsKK30KK2lubGluZSBjaGFyKiBGYXN0TG9uZ1RvQnVmZmVyKGxvbmcgaSwgY2hhciogYnVmZmVyKSB7CisgIHJldHVybiAoc2l6ZW9mKGkpID09IDQgPworICAgICAgICAgIEZhc3RJbnQzMlRvQnVmZmVyKGksIGJ1ZmZlcikgOiBGYXN0SW50NjRUb0J1ZmZlcihpLCBidWZmZXIpKTsKK30KK2lubGluZSBjaGFyKiBGYXN0VUxvbmdUb0J1ZmZlcih1bnNpZ25lZCBsb25nIGksIGNoYXIqIGJ1ZmZlcikgeworICByZXR1cm4gKHNpemVvZihpKSA9PSA0ID8KKyAgICAgICAgICBGYXN0VUludDMyVG9CdWZmZXIoaSwgYnVmZmVyKSA6IEZhc3RVSW50NjRUb0J1ZmZlcihpLCBidWZmZXIpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRmFzdEludDMyVG9CdWZmZXJMZWZ0KCkKKy8vIEZhc3RVSW50MzJUb0J1ZmZlckxlZnQoKQorLy8gRmFzdEludDY0VG9CdWZmZXJMZWZ0KCkKKy8vIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQoKQorLy8KKy8vIExpa2UgdGhlIEZhc3QqVG9CdWZmZXIoKSBmdW5jdGlvbnMgYWJvdmUsIHRoZXNlIGFyZSBpbnRlbmRlZCBmb3Igc3BlZWQuCisvLyBVbmxpa2UgdGhlIEZhc3QqVG9CdWZmZXIoKSBmdW5jdGlvbnMsIGhvd2V2ZXIsIHRoZXNlIGZ1bmN0aW9ucyB3cml0ZQorLy8gdGhlaXIgb3V0cHV0IHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGJ1ZmZlciAoaGVuY2UgdGhlIG5hbWUsIGFzIHRoZQorLy8gb3V0cHV0IGlzIGxlZnQtYWxpZ25lZCkuICBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGF0CisvLyB0aGUgYnVmZmVyIGhhcyBlbm91Z2ggc3BhY2UgdG8gaG9sZCB0aGUgb3V0cHV0LgorLy8KKy8vIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBlbmQgb2YgdGhlIHN0cmluZyAoaS5lLiB0aGUgbnVsbCBjaGFyYWN0ZXIKKy8vIHRlcm1pbmF0aW5nIHRoZSBzdHJpbmcpLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdEludDMyVG9CdWZmZXJMZWZ0KGludDMyIGksIGNoYXIqIGJ1ZmZlcik7CitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdFVJbnQzMlRvQnVmZmVyTGVmdCh1aW50MzIgaSwgY2hhciogYnVmZmVyKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBGYXN0SW50NjRUb0J1ZmZlckxlZnQoaW50NjQgaSwgY2hhciogYnVmZmVyKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBGYXN0VUludDY0VG9CdWZmZXJMZWZ0KHVpbnQ2NCBpLCBjaGFyKiBidWZmZXIpOworCisvLyBKdXN0IGRlZmluZSB0aGVzZSBpbiB0ZXJtcyBvZiB0aGUgYWJvdmUuCitpbmxpbmUgY2hhciogRmFzdFVJbnQzMlRvQnVmZmVyKHVpbnQzMiBpLCBjaGFyKiBidWZmZXIpIHsKKyAgRmFzdFVJbnQzMlRvQnVmZmVyTGVmdChpLCBidWZmZXIpOworICByZXR1cm4gYnVmZmVyOworfQoraW5saW5lIGNoYXIqIEZhc3RVSW50NjRUb0J1ZmZlcih1aW50NjQgaSwgY2hhciogYnVmZmVyKSB7CisgIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQoaSwgYnVmZmVyKTsKKyAgcmV0dXJuIGJ1ZmZlcjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU2ltcGxlSXRvYSgpCisvLyAgICBEZXNjcmlwdGlvbjogY29udmVydHMgYW4gaW50ZWdlciB0byBhIHN0cmluZy4KKy8vCisvLyAgICBSZXR1cm4gdmFsdWU6IHN0cmluZworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVJdG9hKGludCBpKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU2ltcGxlSXRvYSh1bnNpZ25lZCBpbnQgaSk7CitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFNpbXBsZUl0b2EobG9uZyBpKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU2ltcGxlSXRvYSh1bnNpZ25lZCBsb25nIGkpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVJdG9hKGxvbmcgbG9uZyBpKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU2ltcGxlSXRvYSh1bnNpZ25lZCBsb25nIGxvbmcgaSk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNpbXBsZUR0b2EoKQorLy8gU2ltcGxlRnRvYSgpCisvLyBEb3VibGVUb0J1ZmZlcigpCisvLyBGbG9hdFRvQnVmZmVyKCkKKy8vICAgIERlc2NyaXB0aW9uOiBjb252ZXJ0cyBhIGRvdWJsZSBvciBmbG9hdCB0byBhIHN0cmluZyB3aGljaCwgaWYKKy8vICAgIHBhc3NlZCB0byBOb0xvY2FsZVN0cnRvZCgpLCB3aWxsIHByb2R1Y2UgdGhlIGV4YWN0IHNhbWUgb3JpZ2luYWwgZG91YmxlCisvLyAgICAoZXhjZXB0IGluIGNhc2Ugb2YgTmFOOyBhbGwgTmFOcyBhcmUgY29uc2lkZXJlZCB0aGUgc2FtZSB2YWx1ZSkuCisvLyAgICBXZSB0cnkgdG8ga2VlcCB0aGUgc3RyaW5nIHNob3J0IGJ1dCBpdCdzIG5vdCBndWFyYW50ZWVkIHRvIGJlIGFzCisvLyAgICBzaG9ydCBhcyBwb3NzaWJsZS4KKy8vCisvLyAgICBEb3VibGVUb0J1ZmZlcigpIGFuZCBGbG9hdFRvQnVmZmVyKCkgd3JpdGUgdGhlIHRleHQgdG8gdGhlIGdpdmVuCisvLyAgICBidWZmZXIgYW5kIHJldHVybiBpdC4gIFRoZSBidWZmZXIgbXVzdCBiZSBhdCBsZWFzdAorLy8gICAga0RvdWJsZVRvQnVmZmVyU2l6ZSBieXRlcyBmb3IgZG91YmxlcyBhbmQga0Zsb2F0VG9CdWZmZXJTaXplCisvLyAgICBieXRlcyBmb3IgZmxvYXRzLiAga0Zhc3RUb0J1ZmZlclNpemUgaXMgYWxzbyBndWFyYW50ZWVkIHRvIGJlIGxhcmdlCisvLyAgICBlbm91Z2ggdG8gaG9sZCBlaXRoZXIuCisvLworLy8gICAgUmV0dXJuIHZhbHVlOiBzdHJpbmcKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU2ltcGxlRHRvYShkb3VibGUgdmFsdWUpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVGdG9hKGZsb2F0IHZhbHVlKTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIERvdWJsZVRvQnVmZmVyKGRvdWJsZSBpLCBjaGFyKiBidWZmZXIpOworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIEZsb2F0VG9CdWZmZXIoZmxvYXQgaSwgY2hhciogYnVmZmVyKTsKKworLy8gSW4gcHJhY3RpY2UsIGRvdWJsZXMgc2hvdWxkIG5ldmVyIG5lZWQgbW9yZSB0aGFuIDI0IGJ5dGVzIGFuZCBmbG9hdHMKKy8vIHNob3VsZCBuZXZlciBuZWVkIG1vcmUgdGhhbiAxNCAoaW5jbHVkaW5nIG51bGwgdGVybWluYXRvcnMpLCBidXQgd2UKKy8vIG92ZXJlc3RpbWF0ZSB0byBiZSBzYWZlLgorc3RhdGljIGNvbnN0IGludCBrRG91YmxlVG9CdWZmZXJTaXplID0gMzI7CitzdGF0aWMgY29uc3QgaW50IGtGbG9hdFRvQnVmZmVyU2l6ZSA9IDI0OworCituYW1lc3BhY2Ugc3RyaW5ncyB7CisKK3N0cnVjdCBIZXggeworICB1aW50NjQgdmFsdWU7CisgIGVudW0gUGFkU3BlYyB7CisgICAgTk9ORSA9IDEsCisgICAgWkVST19QQURfMiwKKyAgICBaRVJPX1BBRF8zLAorICAgIFpFUk9fUEFEXzQsCisgICAgWkVST19QQURfNSwKKyAgICBaRVJPX1BBRF82LAorICAgIFpFUk9fUEFEXzcsCisgICAgWkVST19QQURfOCwKKyAgICBaRVJPX1BBRF85LAorICAgIFpFUk9fUEFEXzEwLAorICAgIFpFUk9fUEFEXzExLAorICAgIFpFUk9fUEFEXzEyLAorICAgIFpFUk9fUEFEXzEzLAorICAgIFpFUk9fUEFEXzE0LAorICAgIFpFUk9fUEFEXzE1LAorICAgIFpFUk9fUEFEXzE2LAorICB9IHNwZWM7CisgIHRlbXBsYXRlIDxjbGFzcyBJbnQ+CisgIGV4cGxpY2l0IEhleChJbnQgdiwgUGFkU3BlYyBzID0gTk9ORSkKKyAgICAgIDogc3BlYyhzKSB7CisgICAgLy8gUHJldmVudCBzaWduLWV4dGVuc2lvbiBieSBjYXN0aW5nIGludGVnZXJzIHRvCisgICAgLy8gdGhlaXIgdW5zaWduZWQgY291bnRlcnBhcnRzLgorI2lmZGVmIExBTkdfQ1hYMTEKKyAgICBzdGF0aWNfYXNzZXJ0KAorICAgICAgICBzaXplb2YodikgPT0gMSB8fCBzaXplb2YodikgPT0gMiB8fCBzaXplb2YodikgPT0gNCB8fCBzaXplb2YodikgPT0gOCwKKyAgICAgICAgIlVua25vd24gaW50ZWdlciB0eXBlIik7CisjZW5kaWYKKyAgICB2YWx1ZSA9IHNpemVvZih2KSA9PSAxID8gc3RhdGljX2Nhc3Q8dWludDg+KHYpCisgICAgICAgICAgOiBzaXplb2YodikgPT0gMiA/IHN0YXRpY19jYXN0PHVpbnQxNj4odikKKyAgICAgICAgICA6IHNpemVvZih2KSA9PSA0ID8gc3RhdGljX2Nhc3Q8dWludDMyPih2KQorICAgICAgICAgIDogc3RhdGljX2Nhc3Q8dWludDY0Pih2KTsKKyAgfQorfTsKKworc3RydWN0IEFscGhhTnVtIHsKKyAgY29uc3QgY2hhciAqcGllY2VfZGF0YV87ICAvLyBtb3ZlIHRoZXNlIHRvIHN0cmluZ19yZWYgZXZlbnR1YWxseQorICBzaXplX3QgcGllY2Vfc2l6ZV87ICAgICAgIC8vIG1vdmUgdGhlc2UgdG8gc3RyaW5nX3JlZiBldmVudHVhbGx5CisKKyAgY2hhciBkaWdpdHNba0Zhc3RUb0J1ZmZlclNpemVdOworCisgIC8vIE5vIGJvb2wgY3RvciAtLSBib29scyBjb252ZXJ0IHRvIGFuIGludGVncmFsIHR5cGUuCisgIC8vIEEgYm9vbCBjdG9yIHdvdWxkIGFsc28gY29udmVydCBpbmNvbWluZyBwb2ludGVycyAoYmxldGNoKS4KKworICBBbHBoYU51bShpbnQzMiBpMzIpCisgICAgICA6IHBpZWNlX2RhdGFfKGRpZ2l0cyksCisgICAgICAgIHBpZWNlX3NpemVfKEZhc3RJbnQzMlRvQnVmZmVyTGVmdChpMzIsIGRpZ2l0cykgLSAmZGlnaXRzWzBdKSB7fQorICBBbHBoYU51bSh1aW50MzIgdTMyKQorICAgICAgOiBwaWVjZV9kYXRhXyhkaWdpdHMpLAorICAgICAgICBwaWVjZV9zaXplXyhGYXN0VUludDMyVG9CdWZmZXJMZWZ0KHUzMiwgZGlnaXRzKSAtICZkaWdpdHNbMF0pIHt9CisgIEFscGhhTnVtKGludDY0IGk2NCkKKyAgICAgIDogcGllY2VfZGF0YV8oZGlnaXRzKSwKKyAgICAgICAgcGllY2Vfc2l6ZV8oRmFzdEludDY0VG9CdWZmZXJMZWZ0KGk2NCwgZGlnaXRzKSAtICZkaWdpdHNbMF0pIHt9CisgIEFscGhhTnVtKHVpbnQ2NCB1NjQpCisgICAgICA6IHBpZWNlX2RhdGFfKGRpZ2l0cyksCisgICAgICAgIHBpZWNlX3NpemVfKEZhc3RVSW50NjRUb0J1ZmZlckxlZnQodTY0LCBkaWdpdHMpIC0gJmRpZ2l0c1swXSkge30KKworICBBbHBoYU51bShmbG9hdCBmKQorICAgIDogcGllY2VfZGF0YV8oZGlnaXRzKSwgcGllY2Vfc2l6ZV8oc3RybGVuKEZsb2F0VG9CdWZmZXIoZiwgZGlnaXRzKSkpIHt9CisgIEFscGhhTnVtKGRvdWJsZSBmKQorICAgIDogcGllY2VfZGF0YV8oZGlnaXRzKSwgcGllY2Vfc2l6ZV8oc3RybGVuKERvdWJsZVRvQnVmZmVyKGYsIGRpZ2l0cykpKSB7fQorCisgIEFscGhhTnVtKEhleCBoZXgpOworCisgIEFscGhhTnVtKGNvbnN0IGNoYXIqIGNfc3RyKQorICAgICAgOiBwaWVjZV9kYXRhXyhjX3N0ciksIHBpZWNlX3NpemVfKHN0cmxlbihjX3N0cikpIHt9CisgIC8vIFRPRE86IEFkZCBhIHN0cmluZ19yZWYgY29uc3RydWN0b3IsIGV2ZW50dWFsbHkKKyAgLy8gQWxwaGFOdW0oY29uc3QgU3RyaW5nUGllY2UgJnBjKSA6IHBpZWNlKHBjKSB7fQorCisgIEFscGhhTnVtKGNvbnN0IHN0cmluZyYgc3RyKQorICAgICAgOiBwaWVjZV9kYXRhXyhzdHIuZGF0YSgpKSwgcGllY2Vfc2l6ZV8oc3RyLnNpemUoKSkge30KKworICBzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIHBpZWNlX3NpemVfOyB9CisgIGNvbnN0IGNoYXIgKmRhdGEoKSBjb25zdCB7IHJldHVybiBwaWVjZV9kYXRhXzsgfQorCisgcHJpdmF0ZToKKyAgLy8gVXNlICI6IiBub3QgJzonCisgIEFscGhhTnVtKGNoYXIgYyk7ICAvLyBOT0xJTlQocnVudGltZS9leHBsaWNpdCkKKworICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ24uCisgIEFscGhhTnVtKGNvbnN0IEFscGhhTnVtJik7CisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IEFscGhhTnVtJik7Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworCit1c2luZyBzdHJpbmdzOjpBbHBoYU51bTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyQ2F0KCkKKy8vICAgIFRoaXMgbWVyZ2VzIHRoZSBnaXZlbiBzdHJpbmdzIG9yIG51bWJlcnMsIHdpdGggbm8gZGVsaW1pdGVyLiAgVGhpcworLy8gICAgaXMgZGVzaWduZWQgdG8gYmUgdGhlIGZhc3Rlc3QgcG9zc2libGUgd2F5IHRvIGNvbnN0cnVjdCBhIHN0cmluZyBvdXQKKy8vICAgIG9mIGEgbWl4IG9mIHJhdyBDIHN0cmluZ3MsIHN0cmluZ3MsIGJvb2wgdmFsdWVzLAorLy8gICAgYW5kIG51bWVyaWMgdmFsdWVzLgorLy8KKy8vICAgIERvbid0IHVzZSB0aGlzIGZvciB1c2VyLXZpc2libGUgc3RyaW5ncy4gIFRoZSBsb2NhbGl6YXRpb24gcHJvY2VzcworLy8gICAgd29ya3MgcG9vcmx5IG9uIHN0cmluZ3MgYnVpbHQgdXAgb3V0IG9mIGZyYWdtZW50cy4KKy8vCisvLyAgICBGb3IgY2xhcml0eSBhbmQgcGVyZm9ybWFuY2UsIGRvbid0IHVzZSBTdHJDYXQgd2hlbiBhcHBlbmRpbmcgdG8gYQorLy8gICAgc3RyaW5nLiAgSW4gcGFydGljdWxhciwgYXZvaWQgdXNpbmcgYW55IG9mIHRoZXNlIChhbnRpLSlwYXR0ZXJuczoKKy8vICAgICAgc3RyLmFwcGVuZChTdHJDYXQoLi4uKQorLy8gICAgICBzdHIgKz0gU3RyQ2F0KC4uLikKKy8vICAgICAgc3RyID0gU3RyQ2F0KHN0ciwgLi4uKQorLy8gICAgd2hlcmUgdGhlIGxhc3QgaXMgdGhlIHdvcnNlLCB3aXRoIHRoZSBwb3RlbnRpYWwgdG8gY2hhbmdlIGEgbG9vcAorLy8gICAgZnJvbSBhIGxpbmVhciB0aW1lIG9wZXJhdGlvbiB3aXRoIE8oMSkgZHluYW1pYyBhbGxvY2F0aW9ucyBpbnRvIGEKKy8vICAgIHF1YWRyYXRpYyB0aW1lIG9wZXJhdGlvbiB3aXRoIE8obikgZHluYW1pYyBhbGxvY2F0aW9ucy4gIFN0ckFwcGVuZAorLy8gICAgaXMgYSBiZXR0ZXIgY2hvaWNlIHRoYW4gYW55IG9mIHRoZSBhYm92ZSwgc3ViamVjdCB0byB0aGUgcmVzdHJpY3Rpb24KKy8vICAgIG9mIFN0ckFwcGVuZCgmc3RyLCBhLCBiLCBjLCAuLi4pIHRoYXQgbm9uZSBvZiB0aGUgYSwgYiwgYywgLi4uIG1heQorLy8gICAgYmUgYSByZWZlcmVuY2UgaW50byBzdHIuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiKTsKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYyk7CitzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYiwgY29uc3QgQWxwaGFOdW0gJmMsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZkKTsKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlKTsKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZik7CitzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYiwgY29uc3QgQWxwaGFOdW0gJmMsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZkLCBjb25zdCBBbHBoYU51bSAmZSwgY29uc3QgQWxwaGFOdW0gJmYsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZnKTsKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZiwKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmcsIGNvbnN0IEFscGhhTnVtICZoKTsKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZiwKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmcsIGNvbnN0IEFscGhhTnVtICZoLCBjb25zdCBBbHBoYU51bSAmaSk7CisKK2lubGluZSBzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtJiBhKSB7IHJldHVybiBzdHJpbmcoYS5kYXRhKCksIGEuc2l6ZSgpKTsgfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTdHJBcHBlbmQoKQorLy8gICAgU2FtZSBhcyBhYm92ZSwgYnV0IGFkZHMgdGhlIG91dHB1dCB0byB0aGUgZ2l2ZW4gc3RyaW5nLgorLy8gICAgV0FSTklORzogRm9yIHNwZWVkLCBTdHJBcHBlbmQgZG9lcyBub3QgdHJ5IHRvIGNoZWNrIGVhY2ggb2YgaXRzIGlucHV0CisvLyAgICBhcmd1bWVudHMgdG8gYmUgc3VyZSB0aGF0IHRoZXkgYXJlIG5vdCBhIHN1YnNldCBvZiB0aGUgc3RyaW5nIGJlaW5nCisvLyAgICBhcHBlbmRlZCB0by4gIFRoYXQgaXMsIHdoaWxlIHRoaXMgd2lsbCB3b3JrOgorLy8KKy8vICAgIHN0cmluZyBzID0gImZvbyI7CisvLyAgICBzICs9IHM7CisvLworLy8gICAgVGhpcyB3aWxsIG5vdCAobmVjZXNzYXJpbHkpIHdvcms6CisvLworLy8gICAgc3RyaW5nIHMgPSAiZm9vIjsKKy8vICAgIFN0ckFwcGVuZCgmcywgcyk7CisvLworLy8gICAgTm90ZTogd2hpbGUgU3RyQ2F0IHN1cHBvcnRzIGFwcGVuZGluZyB1cCB0byA5IGFyZ3VtZW50cywgU3RyQXBwZW5kCisvLyAgICBpcyBjdXJyZW50bHkgbGltaXRlZCB0byA0LiAgVGhhdCdzIHJhcmVseSBhbiBpc3N1ZSBleGNlcHQgd2hlbgorLy8gICAgYXV0b21hdGljYWxseSB0cmFuc2Zvcm1pbmcgU3RyQ2F0IHRvIFN0ckFwcGVuZCwgYW5kIGNhbiBlYXNpbHkgYmUKKy8vICAgIHdvcmtlZCBhcm91bmQgYXMgY29uc2VjdXRpdmUgY2FsbHMgdG8gU3RyQXBwZW5kIGFyZSBxdWl0ZSBlZmZpY2llbnQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgU3RyQXBwZW5kKHN0cmluZyogZGVzdCwgY29uc3QgQWxwaGFOdW0mIGEpOwordm9pZCBTdHJBcHBlbmQoc3RyaW5nKiBkZXN0LCBjb25zdCBBbHBoYU51bSYgYSwgY29uc3QgQWxwaGFOdW0mIGIpOwordm9pZCBTdHJBcHBlbmQoc3RyaW5nKiBkZXN0LCBjb25zdCBBbHBoYU51bSYgYSwgY29uc3QgQWxwaGFOdW0mIGIsCisgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgYyk7Cit2b2lkIFN0ckFwcGVuZChzdHJpbmcqIGRlc3QsIGNvbnN0IEFscGhhTnVtJiBhLCBjb25zdCBBbHBoYU51bSYgYiwKKyAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtJiBjLCBjb25zdCBBbHBoYU51bSYgZCk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEpvaW4oKQorLy8gICAgVGhlc2UgbWV0aG9kcyBjb25jYXRlbmF0ZSBhIHJhbmdlIG9mIGNvbXBvbmVudHMgaW50byBhIEMrKyBzdHJpbmcsIHVzaW5nCisvLyAgICB0aGUgQy1zdHJpbmcgImRlbGltIiBhcyBhIHNlcGFyYXRvciBiZXR3ZWVuIGNvbXBvbmVudHMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcmF0b3I+Cit2b2lkIEpvaW4oSXRlcmF0b3Igc3RhcnQsIEl0ZXJhdG9yIGVuZCwKKyAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSwgc3RyaW5nKiByZXN1bHQpIHsKKyAgZm9yIChJdGVyYXRvciBpdCA9IHN0YXJ0OyBpdCAhPSBlbmQ7ICsraXQpIHsKKyAgICBpZiAoaXQgIT0gc3RhcnQpIHsKKyAgICAgIHJlc3VsdC0+YXBwZW5kKGRlbGltKTsKKyAgICB9CisgICAgU3RyQXBwZW5kKHJlc3VsdCwgKml0KTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgUmFuZ2U+CitzdHJpbmcgSm9pbihjb25zdCBSYW5nZSYgY29tcG9uZW50cywKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIGRlbGltKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIEpvaW4oY29tcG9uZW50cy5iZWdpbigpLCBjb21wb25lbnRzLmVuZCgpLCBkZWxpbSwgJnJlc3VsdCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFRvSGV4KCkKKy8vICAgIFJldHVybiBhIGxvd2VyLWNhc2UgaGV4IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gaW50ZWdlci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgVG9IZXgodWludDY0IG51bSk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEdsb2JhbFJlcGxhY2VTdWJzdHJpbmcoKQorLy8gICAgUmVwbGFjZXMgYWxsIGluc3RhbmNlcyBvZiBhIHN1YnN0cmluZyBpbiBhIHN0cmluZy4gIERvZXMgbm90aGluZworLy8gICAgaWYgJ3N1YnN0cmluZycgaXMgZW1wdHkuICBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcmVwbGFjZW1lbnRzLgorLy8KKy8vICAgIE5PVEU6IFRoZSBzdHJpbmcgcGllY2VzIG11c3Qgbm90IG92ZXJsYXAgcy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgR2xvYmFsUmVwbGFjZVN1YnN0cmluZyhjb25zdCBzdHJpbmcmIHN1YnN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHJlcGxhY2VtZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogcyk7CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVFJVVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmMjdkY2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWxfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw3MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxsb2NhbGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworLy8gVE9ETyhrZW50b24pOiAgQ29weSBzdHJ1dGlsIHRlc3RzIGZyb20gZ29vZ2xlMz8KKworVEVTVChTdHJpbmdVdGlsaXR5VGVzdCwgSW1tdW5lVG9Mb2NhbGVzKSB7CisgIC8vIFJlbWVtYmVyIHRoZSBvbGQgbG9jYWxlLgorICBjaGFyKiBvbGRfbG9jYWxlX2NzdHIgPSBzZXRsb2NhbGUoTENfTlVNRVJJQywgTlVMTCk7CisgIEFTU0VSVF9UUlVFKG9sZF9sb2NhbGVfY3N0ciAhPSBOVUxMKTsKKyAgc3RyaW5nIG9sZF9sb2NhbGUgPSBvbGRfbG9jYWxlX2NzdHI7CisKKyAgLy8gU2V0IHRoZSBsb2NhbGUgdG8gIkMiLgorICBBU1NFUlRfVFJVRShzZXRsb2NhbGUoTENfTlVNRVJJQywgIkMiKSAhPSBOVUxMKTsKKworICBFWFBFQ1RfRVEoIjEuNSIsIFNpbXBsZUR0b2EoMS41KSk7CisgIEVYUEVDVF9FUSgiMS41IiwgU2ltcGxlRnRvYSgxLjUpKTsKKworICBpZiAoc2V0bG9jYWxlKExDX05VTUVSSUMsICJlc19FUyIpID09IE5VTEwgJiYKKyAgICAgIHNldGxvY2FsZShMQ19OVU1FUklDLCAiZXNfRVMudXRmOCIpID09IE5VTEwpIHsKKyAgICAvLyBTb21lIHN5c3RlbXMgbWF5IG5vdCBoYXZlIHRoZSBkZXNpcmVkIGxvY2FsZSBhdmFpbGFibGUuCisgICAgR09PR0xFX0xPRyhXQVJOSU5HKQorICAgICAgPDwgIkNvdWxkbid0IHNldCBsb2NhbGUgdG8gZXNfRVMuICBTa2lwcGluZyB0aGlzIHRlc3QuIjsKKyAgfSBlbHNlIHsKKyAgICBFWFBFQ1RfRVEoIjEuNSIsIFNpbXBsZUR0b2EoMS41KSk7CisgICAgRVhQRUNUX0VRKCIxLjUiLCBTaW1wbGVGdG9hKDEuNSkpOworICB9CisKKyAgLy8gUmV0dXJuIHRvIG9yaWdpbmFsIGxvY2FsZS4KKyAgc2V0bG9jYWxlKExDX05VTUVSSUMsIG9sZF9sb2NhbGUuY19zdHIoKSk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5ZDk1ODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuY2MKQEAgLTAsMCArMSwxMzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBzdHJpbmdzIHsKKwordXNpbmcgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmc7CisKKy8vIFJldHVybnMgdGhlIG51bWJlciBvZiBhcmdzIGluIGFyZ19hcnJheSB3aGljaCB3ZXJlIHBhc3NlZCBleHBsaWNpdGx5CisvLyB0byBTdWJzdGl0dXRlKCkuCitzdGF0aWMgaW50IENvdW50U3Vic3RpdHV0ZUFyZ3MoY29uc3QgU3Vic3RpdHV0ZUFyZyogY29uc3QqIGFyZ3NfYXJyYXkpIHsKKyAgaW50IGNvdW50ID0gMDsKKyAgd2hpbGUgKGFyZ3NfYXJyYXlbY291bnRdICE9IE5VTEwgJiYgYXJnc19hcnJheVtjb3VudF0tPnNpemUoKSAhPSAtMSkgeworICAgICsrY291bnQ7CisgIH0KKyAgcmV0dXJuIGNvdW50OworfQorCitzdHJpbmcgU3Vic3RpdHV0ZSgKKyAgICBjb25zdCBjaGFyKiBmb3JtYXQsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMCwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMSwKKyAgICBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmcyLCBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmczLAorICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzQsIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzUsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnNiwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnNywKKyAgICBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc4LCBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc5KSB7CisgIHN0cmluZyByZXN1bHQ7CisgIFN1YnN0aXR1dGVBbmRBcHBlbmQoJnJlc3VsdCwgZm9ybWF0LCBhcmcwLCBhcmcxLCBhcmcyLCBhcmczLCBhcmc0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnNSwgYXJnNiwgYXJnNywgYXJnOCwgYXJnOSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgU3Vic3RpdHV0ZUFuZEFwcGVuZCgKKyAgICBzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZm9ybWF0LAorICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzAsIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzEsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMiwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMywKKyAgICBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc0LCBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc1LAorICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzYsIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzcsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnOCwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnOSkgeworICBjb25zdCBTdWJzdGl0dXRlQXJnKiBjb25zdCBhcmdzX2FycmF5W10gPSB7CisgICAgJmFyZzAsICZhcmcxLCAmYXJnMiwgJmFyZzMsICZhcmc0LCAmYXJnNSwgJmFyZzYsICZhcmc3LCAmYXJnOCwgJmFyZzksIE5VTEwKKyAgfTsKKworICAvLyBEZXRlcm1pbmUgdG90YWwgc2l6ZSBuZWVkZWQuCisgIGludCBzaXplID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGZvcm1hdFtpXSAhPSAnXDAnOyBpKyspIHsKKyAgICBpZiAoZm9ybWF0W2ldID09ICckJykgeworICAgICAgaWYgKGFzY2lpX2lzZGlnaXQoZm9ybWF0W2krMV0pKSB7CisgICAgICAgIGludCBpbmRleCA9IGZvcm1hdFtpKzFdIC0gJzAnOworICAgICAgICBpZiAoYXJnc19hcnJheVtpbmRleF0tPnNpemUoKSA9PSAtMSkgeworICAgICAgICAgIEdPT0dMRV9MT0coREZBVEFMKQorICAgICAgICAgICAgPDwgInN0cmluZ3M6OlN1YnN0aXR1dGUgZm9ybWF0IHN0cmluZyBpbnZhbGlkOiBhc2tlZCBmb3IgXCIkIgorICAgICAgICAgICAgPDwgaW5kZXggPDwgIlwiLCBidXQgb25seSAiIDw8IENvdW50U3Vic3RpdHV0ZUFyZ3MoYXJnc19hcnJheSkKKyAgICAgICAgICAgIDw8ICIgYXJncyB3ZXJlIGdpdmVuLiAgRnVsbCBmb3JtYXQgc3RyaW5nIHdhczogXCIiCisgICAgICAgICAgICA8PCBDRXNjYXBlKGZvcm1hdCkgPDwgIlwiLiI7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHNpemUgKz0gYXJnc19hcnJheVtpbmRleF0tPnNpemUoKTsKKyAgICAgICAgKytpOyAgLy8gU2tpcCBuZXh0IGNoYXIuCisgICAgICB9IGVsc2UgaWYgKGZvcm1hdFtpKzFdID09ICckJykgeworICAgICAgICArK3NpemU7CisgICAgICAgICsraTsgIC8vIFNraXAgbmV4dCBjaGFyLgorICAgICAgfSBlbHNlIHsKKyAgICAgICAgR09PR0xFX0xPRyhERkFUQUwpCisgICAgICAgICAgPDwgIkludmFsaWQgc3RyaW5nczo6U3Vic3RpdHV0ZSgpIGZvcm1hdCBzdHJpbmc6IFwiIgorICAgICAgICAgIDw8IENFc2NhcGUoZm9ybWF0KSA8PCAiXCIuIjsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICArK3NpemU7CisgICAgfQorICB9CisKKyAgaWYgKHNpemUgPT0gMCkgcmV0dXJuOworCisgIC8vIEJ1aWxkIHRoZSBzdHJpbmcuCisgIGludCBvcmlnaW5hbF9zaXplID0gb3V0cHV0LT5zaXplKCk7CisgIFNUTFN0cmluZ1Jlc2l6ZVVuaW5pdGlhbGl6ZWQob3V0cHV0LCBvcmlnaW5hbF9zaXplICsgc2l6ZSk7CisgIGNoYXIqIHRhcmdldCA9IHN0cmluZ19hc19hcnJheShvdXRwdXQpICsgb3JpZ2luYWxfc2l6ZTsKKyAgZm9yIChpbnQgaSA9IDA7IGZvcm1hdFtpXSAhPSAnXDAnOyBpKyspIHsKKyAgICBpZiAoZm9ybWF0W2ldID09ICckJykgeworICAgICAgaWYgKGFzY2lpX2lzZGlnaXQoZm9ybWF0W2krMV0pKSB7CisgICAgICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcqIHNyYyA9IGFyZ3NfYXJyYXlbZm9ybWF0W2krMV0gLSAnMCddOworICAgICAgICBtZW1jcHkodGFyZ2V0LCBzcmMtPmRhdGEoKSwgc3JjLT5zaXplKCkpOworICAgICAgICB0YXJnZXQgKz0gc3JjLT5zaXplKCk7CisgICAgICAgICsraTsgIC8vIFNraXAgbmV4dCBjaGFyLgorICAgICAgfSBlbHNlIGlmIChmb3JtYXRbaSsxXSA9PSAnJCcpIHsKKyAgICAgICAgKnRhcmdldCsrID0gJyQnOworICAgICAgICArK2k7ICAvLyBTa2lwIG5leHQgY2hhci4KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgKnRhcmdldCsrID0gZm9ybWF0W2ldOworICAgIH0KKyAgfQorCisgIEdPT0dMRV9EQ0hFQ0tfRVEodGFyZ2V0IC0gb3V0cHV0LT5kYXRhKCksIG91dHB1dC0+c2l6ZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWU0NDJhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmgKQEAgLTAsMCArMSwxNzAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBmcm9tIGdvb2dsZTMvc3RyaW5ncy9zdWJzdGl0dXRlLmgKKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1VCU1RJVFVURV9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1VCU1RJVFVURV9IXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2Ugc3RyaW5ncyB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHN0cmluZ3M6OlN1YnN0aXR1dGUoKQorLy8gc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgpCisvLyAgIEtpbmQgb2YgbGlrZSBTdHJpbmdQcmludGYsIGJ1dCBkaWZmZXJlbnQuCisvLworLy8gICBFeGFtcGxlOgorLy8gICAgIHN0cmluZyBHZXRNZXNzYWdlKHN0cmluZyBmaXJzdF9uYW1lLCBzdHJpbmcgbGFzdF9uYW1lLCBpbnQgYWdlKSB7CisvLyAgICAgICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgiTXkgbmFtZSBpcyAkMCAkMSBhbmQgSSBhbSAkMiB5ZWFycyBvbGQuIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0X25hbWUsIGxhc3RfbmFtZSwgYWdlKTsKKy8vICAgICB9CisvLworLy8gICBEaWZmZXJlbmNlcyBmcm9tIFN0cmluZ1ByaW50ZjoKKy8vICAgKiBUaGUgZm9ybWF0IHN0cmluZyBkb2VzIG5vdCBpZGVudGlmeSB0aGUgdHlwZXMgb2YgYXJndW1lbnRzLgorLy8gICAgIEluc3RlYWQsIHRoZSBtYWdpYyBvZiBDKysgZGVhbHMgd2l0aCB0aGlzIGZvciB1cy4gIFNlZSBiZWxvdworLy8gICAgIGZvciBhIGxpc3Qgb2YgYWNjZXB0ZWQgdHlwZXMuCisvLyAgICogU3Vic3RpdHV0aW9ucyBpbiB0aGUgZm9ybWF0IHN0cmluZyBhcmUgaWRlbnRpZmllZCBieSBhICckJworLy8gICAgIGZvbGxvd2VkIGJ5IGEgZGlnaXQuICBTbywgeW91IGNhbiB1c2UgYXJndW1lbnRzIG91dC1vZi1vcmRlciBhbmQKKy8vICAgICB1c2UgdGhlIHNhbWUgYXJndW1lbnQgbXVsdGlwbGUgdGltZXMuCisvLyAgICogSXQncyBtdWNoIGZhc3RlciB0aGFuIFN0cmluZ1ByaW50Zi4KKy8vCisvLyAgIFN1cHBvcnRlZCB0eXBlczoKKy8vICAgKiBTdHJpbmdzIChjb25zdCBjaGFyKiwgY29uc3Qgc3RyaW5nJikKKy8vICAgICAqIE5vdGUgdGhhdCB0aGlzIG1lYW5zIHlvdSBkbyBub3QgaGF2ZSB0byBhZGQgLmNfc3RyKCkgdG8gYWxsIG9mCisvLyAgICAgICB5b3VyIHN0cmluZ3MuICBJbiBmYWN0LCB5b3Ugc2hvdWxkbid0OyBpdCB3aWxsIGJlIHNsb3dlci4KKy8vICAgKiBpbnQzMiwgaW50NjQsIHVpbnQzMiwgdWludDY0OiAgRm9ybWF0dGVkIHVzaW5nIFNpbXBsZUl0b2EoKS4KKy8vICAgKiBmbG9hdCwgZG91YmxlOiAgRm9ybWF0dGVkIHVzaW5nIFNpbXBsZUZ0b2EoKSBhbmQgU2ltcGxlRHRvYSgpLgorLy8gICAqIGJvb2w6ICBQcmludGVkIGFzICJ0cnVlIiBvciAiZmFsc2UiLgorLy8KKy8vICAgU3Vic3RpdHV0ZUFuZEFwcGVuZCgpIGlzIGxpa2UgU3Vic3RpdHV0ZSgpIGJ1dCBhcHBlbmRzIHRoZSByZXN1bHQgdG8KKy8vICAgKm91dHB1dC4gIEV4YW1wbGU6CisvLworLy8gICAgIHN0cmluZyBzdHI7CisvLyAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmc3RyLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk15IG5hbWUgaXMgJDAgJDEgYW5kIEkgYW0gJDIgeWVhcnMgb2xkLiIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF9uYW1lLCBsYXN0X25hbWUsIGFnZSk7CisvLworLy8gICBTdWJzdGl0dXRlKCkgaXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgdGhhbiBTdHJpbmdQcmludGYoKS4gIEZvciB2ZXJ5CisvLyAgIGxhcmdlIHN0cmluZ3MsIGl0IG1heSBiZSBvcmRlcnMgb2YgbWFnbml0dWRlIGZhc3Rlci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGludGVybmFsIHsgIC8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMuCisKK2NsYXNzIFN1YnN0aXR1dGVBcmcgeworIHB1YmxpYzoKKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcoY29uc3QgY2hhciogdmFsdWUpCisgICAgOiB0ZXh0Xyh2YWx1ZSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGNvbnN0IHN0cmluZyYgdmFsdWUpCisgICAgOiB0ZXh0Xyh2YWx1ZS5kYXRhKCkpLCBzaXplXyh2YWx1ZS5zaXplKCkpIHt9CisKKyAgLy8gSW5kaWNhdGVzIHRoYXQgbm8gYXJndW1lbnQgd2FzIGdpdmVuLgorICBpbmxpbmUgZXhwbGljaXQgU3Vic3RpdHV0ZUFyZygpCisgICAgOiB0ZXh0XyhOVUxMKSwgc2l6ZV8oLTEpIHt9CisKKyAgLy8gUHJpbWl0aXZlcworICAvLyBXZSBkb24ndCBvdmVybG9hZCBmb3Igc2lnbmVkIGFuZCB1bnNpZ25lZCBjaGFyIGJlY2F1c2UgaWYgcGVvcGxlIGFyZQorICAvLyBleHBsaWNpdGx5IGRlY2xhcmluZyB0aGVpciBjaGFycyBhcyBzaWduZWQgb3IgdW5zaWduZWQgdGhlbiB0aGV5IGFyZQorICAvLyBwcm9iYWJseSBhY3R1YWxseSB1c2luZyB0aGVtIGFzIDgtYml0IGludGVnZXJzIGFuZCB3b3VsZCBwcm9iYWJseQorICAvLyBwcmVmZXIgYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbi4gIEJ1dCwgd2UgZG9uJ3QgcmVhbGx5IGtub3cuICBTbywgd2UKKyAgLy8gbWFrZSB0aGUgY2FsbGVyIGRlY2lkZSB3aGF0IHRvIGRvLgorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyhjaGFyIHZhbHVlKQorICAgIDogdGV4dF8oc2NyYXRjaF8pLCBzaXplXygxKSB7IHNjcmF0Y2hfWzBdID0gdmFsdWU7IH0KKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcoc2hvcnQgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0SW50MzJUb0J1ZmZlcih2YWx1ZSwgc2NyYXRjaF8pKSwgc2l6ZV8oc3RybGVuKHRleHRfKSkge30KKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcodW5zaWduZWQgc2hvcnQgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0VUludDMyVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGludCB2YWx1ZSkKKyAgICA6IHRleHRfKEZhc3RJbnQzMlRvQnVmZmVyKHZhbHVlLCBzY3JhdGNoXykpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyh1bnNpZ25lZCBpbnQgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0VUludDMyVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGxvbmcgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0TG9uZ1RvQnVmZmVyKHZhbHVlLCBzY3JhdGNoXykpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyh1bnNpZ25lZCBsb25nIHZhbHVlKQorICAgIDogdGV4dF8oRmFzdFVMb25nVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGxvbmcgbG9uZyB2YWx1ZSkKKyAgICA6IHRleHRfKEZhc3RJbnQ2NFRvQnVmZmVyKHZhbHVlLCBzY3JhdGNoXykpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyh1bnNpZ25lZCBsb25nIGxvbmcgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0VUludDY0VG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGZsb2F0IHZhbHVlKQorICAgIDogdGV4dF8oRmxvYXRUb0J1ZmZlcih2YWx1ZSwgc2NyYXRjaF8pKSwgc2l6ZV8oc3RybGVuKHRleHRfKSkge30KKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcoZG91YmxlIHZhbHVlKQorICAgIDogdGV4dF8oRG91YmxlVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGJvb2wgdmFsdWUpCisgICAgOiB0ZXh0Xyh2YWx1ZSA/ICJ0cnVlIiA6ICJmYWxzZSIpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorCisgIGlubGluZSBjb25zdCBjaGFyKiBkYXRhKCkgY29uc3QgeyByZXR1cm4gdGV4dF87IH0KKyAgaW5saW5lIGludCBzaXplKCkgY29uc3QgeyByZXR1cm4gc2l6ZV87IH0KKworIHByaXZhdGU6CisgIGNvbnN0IGNoYXIqIHRleHRfOworICBpbnQgc2l6ZV87CisgIGNoYXIgc2NyYXRjaF9ba0Zhc3RUb0J1ZmZlclNpemVdOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU3Vic3RpdHV0ZSgKKyAgY29uc3QgY2hhciogZm9ybWF0LAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMCA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmcxID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzIgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMyA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc0ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzUgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnNiA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc3ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzggPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnOSA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCkpOworCitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBTdWJzdGl0dXRlQW5kQXBwZW5kKAorICBzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZm9ybWF0LAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMCA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmcxID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzIgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMyA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc0ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzUgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnNiA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc3ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzggPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnOSA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCkpOworCit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1VCU1RJVFVURV9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWVmOTA0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmgKQEAgLTAsMCArMSwxMzggQEAKKy8vIENvcHlyaWdodCAyMDA1IEdvb2dsZSBJbmMuCisvLyBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyAtLS0tCisvLyBBdXRob3I6IGxhckBnb29nbGUuY29tIChMYXJhbWllIExlYXZpdHQpCisvLworLy8gVGVtcGxhdGUgbWV0YXByb2dyYW1taW5nIHV0aWxpdHkgZnVuY3Rpb25zLgorLy8KKy8vIFRoaXMgY29kZSBpcyBjb21waWxlZCBkaXJlY3RseSBvbiBtYW55IHBsYXRmb3JtcywgaW5jbHVkaW5nIGNsaWVudAorLy8gcGxhdGZvcm1zIGxpa2UgV2luZG93cywgTWFjLCBhbmQgZW1iZWRkZWQgc3lzdGVtcy4gIEJlZm9yZSBtYWtpbmcKKy8vIGFueSBjaGFuZ2VzIGhlcmUsIG1ha2Ugc3VyZSB0aGF0IHlvdSdyZSBub3QgYnJlYWtpbmcgYW55IHBsYXRmb3Jtcy4KKy8vCisvLworLy8gVGhlIG5hbWVzIGNob3NlbiBoZXJlIHJlZmxlY3QgdGhvc2UgdXNlZCBpbiB0cjEgYW5kIHRoZSBib29zdDo6bXBsCisvLyBsaWJyYXJ5LCB0aGVyZSBhcmUgc2ltaWxhciBvcGVyYXRpb25zIHVzZWQgaW4gdGhlIExva2kgbGlicmFyeSBhcworLy8gd2VsbC4gIEkgcHJlZmVyIHRoZSBib29zdCBuYW1lcyBmb3IgMiByZWFzb25zOgorLy8gMS4gIEkgdGhpbmsgdGhhdCBwb3J0aW9ucyBvZiB0aGUgQm9vc3QgbGlicmFyaWVzIGFyZSBtb3JlIGxpa2VseSB0bworLy8gYmUgaW5jbHVkZWQgaW4gdGhlIGMrKyBzdGFuZGFyZC4KKy8vIDIuICBJdCBpcyBub3QgaW1wb3NzaWJsZSB0aGF0IHNvbWUgb2YgdGhlIGJvb3N0IGxpYnJhcmllcyB3aWxsIGJlCisvLyBpbmNsdWRlZCBpbiBvdXIgb3duIGJ1aWxkIGluIHRoZSBmdXR1cmUuCisvLyBCb3RoIG9mIHRoZXNlIG91dGNvbWVzIG1lYW5zIHRoYXQgd2UgbWF5IGJlIGFibGUgdG8gZGlyZWN0bHkgcmVwbGFjZQorLy8gc29tZSBvZiB0aGVzZSB3aXRoIGJvb3N0IGVxdWl2YWxlbnRzLgorLy8KKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1RFTVBMQVRFX1VUSUxfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1RFTVBMQVRFX1VUSUxfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVHlwZXMgc21hbGxfIGFuZCBiaWdfIGFyZSBndWFyYW50ZWVkIHN1Y2ggdGhhdCBzaXplb2Yoc21hbGxfKSA8CisvLyBzaXplb2YoYmlnXykKK3R5cGVkZWYgY2hhciBzbWFsbF87CisKK3N0cnVjdCBiaWdfIHsKKyAgY2hhciBkdW1teVsyXTsKK307CisKKy8vIElkZW50aXR5IG1ldGFmdW5jdGlvbi4KK3RlbXBsYXRlIDxjbGFzcyBUPgorc3RydWN0IGlkZW50aXR5XyB7CisgIHR5cGVkZWYgVCB0eXBlOworfTsKKworLy8gaW50ZWdyYWxfY29uc3RhbnQsIGRlZmluZWQgaW4gdHIxLCBpcyBhIHdyYXBwZXIgZm9yIGFuIGludGVnZXIKKy8vIHZhbHVlLiBXZSBkb24ndCByZWFsbHkgbmVlZCB0aGlzIGdlbmVyYWxpdHk7IHdlIGNvdWxkIGdldCBhd2F5CisvLyB3aXRoIGhhcmRjb2RpbmcgdGhlIGludGVnZXIgdHlwZSB0byBib29sLiBXZSB1c2UgdGhlIGZ1bGx5CisvLyBnZW5lcmFsIGludGVnZXJfY29uc3RhbnQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCB0cjEuCisKK3RlbXBsYXRlPGNsYXNzIFQsIFQgdj4KK3N0cnVjdCBpbnRlZ3JhbF9jb25zdGFudCB7CisgIHN0YXRpYyBjb25zdCBUIHZhbHVlID0gdjsKKyAgdHlwZWRlZiBUIHZhbHVlX3R5cGU7CisgIHR5cGVkZWYgaW50ZWdyYWxfY29uc3RhbnQ8VCwgdj4gdHlwZTsKK307CisKK3RlbXBsYXRlIDxjbGFzcyBULCBUIHY+IGNvbnN0IFQgaW50ZWdyYWxfY29uc3RhbnQ8VCwgdj46OnZhbHVlOworCisKKy8vIEFiYnJldmlhdGlvbnM6IHRydWVfdHlwZSBhbmQgZmFsc2VfdHlwZSBhcmUgc3RydWN0cyB0aGF0IHJlcHJlc2VudCBib29sZWFuCisvLyB0cnVlIGFuZCBmYWxzZSB2YWx1ZXMuIEFsc28gZGVmaW5lIHRoZSBib29zdDo6bXBsIHZlcnNpb25zIG9mIHRob3NlIG5hbWVzLAorLy8gdHJ1ZV8gYW5kIGZhbHNlXy4KK3R5cGVkZWYgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgdHJ1ZT4gIHRydWVfdHlwZTsKK3R5cGVkZWYgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgZmFsc2U+IGZhbHNlX3R5cGU7Cit0eXBlZGVmIHRydWVfdHlwZSAgdHJ1ZV87Cit0eXBlZGVmIGZhbHNlX3R5cGUgZmFsc2VfOworCisvLyBpZl8gaXMgYSB0ZW1wbGF0aXplZCBjb25kaXRpb25hbCBzdGF0ZW1lbnQuCisvLyBpZl88Y29uZCwgQSwgQj4gaXMgYSBjb21waWxlIHRpbWUgZXZhbHVhdGlvbiBvZiBjb25kLgorLy8gaWZfPD46OnR5cGUgY29udGFpbnMgQSBpZiBjb25kIGlzIHRydWUsIEIgb3RoZXJ3aXNlLgordGVtcGxhdGU8Ym9vbCBjb25kLCB0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IGlmX3sKKyAgdHlwZWRlZiBBIHR5cGU7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IGlmXzxmYWxzZSwgQSwgQj4geworICB0eXBlZGVmIEIgdHlwZTsKK307CisKKworLy8gdHlwZV9lcXVhbHNfIGlzIGEgdGVtcGxhdGUgdHlwZSBjb21wYXJhdG9yLCBzaW1pbGFyIHRvIExva2kgSXNTYW1lVHlwZS4KKy8vIHR5cGVfZXF1YWxzXzxBLCBCPjo6dmFsdWUgaXMgdHJ1ZSBpZmYgIkEiIGlzIHRoZSBzYW1lIHR5cGUgYXMgIkIiLgorLy8KKy8vIE5ldyBjb2RlIHNob3VsZCBwcmVmZXIgYmFzZTo6aXNfc2FtZSwgZGVmaW5lZCBpbiBiYXNlL3R5cGVfdHJhaXRzLmguCisvLyBJdCBpcyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsLCBidXQgaXNfc2FtZSBpcyB0aGUgc3RhbmRhcmQgc3BlbGxpbmcuCit0ZW1wbGF0ZTx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IHR5cGVfZXF1YWxzXyA6IHB1YmxpYyBmYWxzZV8geworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgQT4KK3N0cnVjdCB0eXBlX2VxdWFsc188QSwgQT4gOiBwdWJsaWMgdHJ1ZV8geworfTsKKworLy8gYW5kXyBpcyBhIHRlbXBsYXRlICYmIG9wZXJhdG9yLgorLy8gYW5kXzxBLCBCPjo6dmFsdWUgZXZhbHVhdGVzICJBOjp2YWx1ZSAmJiBCOjp2YWx1ZSIuCit0ZW1wbGF0ZTx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IGFuZF8gOiBwdWJsaWMgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgKEE6OnZhbHVlICYmIEI6OnZhbHVlKT4geworfTsKKworLy8gb3JfIGlzIGEgdGVtcGxhdGUgfHwgb3BlcmF0b3IuCisvLyBvcl88QSwgQj46OnZhbHVlIGV2YWx1YXRlcyAiQTo6dmFsdWUgfHwgQjo6dmFsdWUiLgordGVtcGxhdGU8dHlwZW5hbWUgQSwgdHlwZW5hbWUgQj4KK3N0cnVjdCBvcl8gOiBwdWJsaWMgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgKEE6OnZhbHVlIHx8IEI6OnZhbHVlKT4geworfTsKKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9URU1QTEFURV9VVElMX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWxfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWxfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE3NDVlMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvdGVtcGxhdGVfdXRpbF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDEzMCBAQAorLy8gQ29weXJpZ2h0IDIwMDUgR29vZ2xlIEluYy4KKy8vIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIC0tLS0KKy8vIEF1dGhvcjogbGFyQGdvb2dsZS5jb20gKExhcmFtaWUgTGVhdml0dCkKKy8vCisvLyBUaGVzZSB0ZXN0cyBhcmUgcmVhbGx5IGNvbXBpbGUgdGltZSB0ZXN0cy4KKy8vIElmIHlvdSB0cnkgdG8gc3RlcCB0aHJvdWdoIHRoaXMgaW4gYSBkZWJ1Z2dlcgorLy8geW91IHdpbGwgbm90IHNlZSBhbnkgZXZhbHVhdGlvbnMsIG1lcmVseSB0aGF0CisvLyB2YWx1ZSBpcyBhc3NpZ25lZCB0cnVlIG9yIGZhbHNlIHNlcXVlbnRpYWxseS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIEdPT0dMRV9OQU1FU1BBQ0UgPSBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoVGVtcGxhdGVVdGlsVGVzdCwgVGVzdFNpemUpIHsKKyAgRVhQRUNUX0dUKHNpemVvZihHT09HTEVfTkFNRVNQQUNFOjpiaWdfKSwgc2l6ZW9mKEdPT0dMRV9OQU1FU1BBQ0U6OnNtYWxsXykpOworfQorCitURVNUKFRlbXBsYXRlVXRpbFRlc3QsIFRlc3RJbnRlZ3JhbENvbnN0YW50cykgeworICAvLyB0ZXN0IHRoZSBidWlsdC1pbiB0eXBlcy4KKyAgRVhQRUNUX1RSVUUodHJ1ZV90eXBlOjp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShmYWxzZV90eXBlOjp2YWx1ZSk7CisKKyAgdHlwZWRlZiBpbnRlZ3JhbF9jb25zdGFudDxpbnQsIDE+IG9uZV90eXBlOworICBFWFBFQ1RfRVEoMSwgb25lX3R5cGU6OnZhbHVlKTsKK30KKworVEVTVChUZW1wbGF0ZVV0aWxUZXN0LCBUZXN0VGVtcGxhdGVJZikgeworICB0eXBlZGVmIGlmXzx0cnVlLCB0cnVlX3R5cGUsIGZhbHNlX3R5cGU+Ojp0eXBlIGlmX3RydWU7CisgIEVYUEVDVF9UUlVFKGlmX3RydWU6OnZhbHVlKTsKKworICB0eXBlZGVmIGlmXzxmYWxzZSwgdHJ1ZV90eXBlLCBmYWxzZV90eXBlPjo6dHlwZSBpZl9mYWxzZTsKKyAgRVhQRUNUX0ZBTFNFKGlmX2ZhbHNlOjp2YWx1ZSk7Cit9CisKK1RFU1QoVGVtcGxhdGVVdGlsVGVzdCwgVGVzdFRlbXBsYXRlVHlwZUVxdWFscykgeworICAvLyBDaGVjayB0aGF0IHRoZSBUZW1wbGF0ZVR5cGVFcXVhbHMgd29ya3MgY29ycmVjdGx5LgorICBib29sIHZhbHVlID0gZmFsc2U7CisKKyAgLy8gVGVzdCB0aGUgc2FtZSB0eXBlIGlzIHRydWUuCisgIHZhbHVlID0gdHlwZV9lcXVhbHNfPGludCwgaW50Pjo6dmFsdWU7CisgIEVYUEVDVF9UUlVFKHZhbHVlKTsKKworICAvLyBUZXN0IGRpZmZlcmVudCB0eXBlcyBhcmUgZmFsc2UuCisgIHZhbHVlID0gdHlwZV9lcXVhbHNfPGZsb2F0LCBpbnQ+Ojp2YWx1ZTsKKyAgRVhQRUNUX0ZBTFNFKHZhbHVlKTsKKworICAvLyBUZXN0IHR5cGUgYWxpYXNpbmcuCisgIHR5cGVkZWYgY29uc3QgaW50IGZvbzsKKyAgdmFsdWUgPSB0eXBlX2VxdWFsc188Y29uc3QgZm9vLCBjb25zdCBpbnQ+Ojp2YWx1ZTsKKyAgRVhQRUNUX1RSVUUodmFsdWUpOworfQorCitURVNUKFRlbXBsYXRlVXRpbFRlc3QsIFRlc3RUZW1wbGF0ZUFuZE9yKSB7CisgIC8vIENoZWNrIHRoYXQgdGhlIFRlbXBsYXRlVHlwZUVxdWFscyB3b3JrcyBjb3JyZWN0bHkuCisgIGJvb2wgdmFsdWUgPSBmYWxzZTsKKworICAvLyBZZXMgJiYgWWVzID09IHRydWUuCisgIHZhbHVlID0gYW5kXzx0cnVlXywgdHJ1ZV8+Ojp2YWx1ZTsKKyAgRVhQRUNUX1RSVUUodmFsdWUpOworICAvLyBZZXMgJiYgTm8gPT0gZmFsc2UuCisgIHZhbHVlID0gYW5kXzx0cnVlXywgZmFsc2VfPjo6dmFsdWU7CisgIEVYUEVDVF9GQUxTRSh2YWx1ZSk7CisgIC8vIE5vICYmIFllcyA9PSBmYWxzZS4KKyAgdmFsdWUgPSBhbmRfPGZhbHNlXywgdHJ1ZV8+Ojp2YWx1ZTsKKyAgRVhQRUNUX0ZBTFNFKHZhbHVlKTsKKyAgLy8gTm8gJiYgTm8gPT0gZmFsc2UuCisgIHZhbHVlID0gYW5kXzxmYWxzZV8sIGZhbHNlXz46OnZhbHVlOworICBFWFBFQ1RfRkFMU0UodmFsdWUpOworCisgIC8vIFllcyB8fCBZZXMgPT0gdHJ1ZS4KKyAgdmFsdWUgPSBvcl88dHJ1ZV8sIHRydWVfPjo6dmFsdWU7CisgIEVYUEVDVF9UUlVFKHZhbHVlKTsKKyAgLy8gWWVzIHx8IE5vID09IHRydWUuCisgIHZhbHVlID0gb3JfPHRydWVfLCBmYWxzZV8+Ojp2YWx1ZTsKKyAgRVhQRUNUX1RSVUUodmFsdWUpOworICAvLyBObyB8fCBZZXMgPT0gdHJ1ZS4KKyAgdmFsdWUgPSBvcl88ZmFsc2VfLCB0cnVlXz46OnZhbHVlOworICBFWFBFQ1RfVFJVRSh2YWx1ZSk7CisgIC8vIE5vIHx8IE5vID09IGZhbHNlLgorICB2YWx1ZSA9IG9yXzxmYWxzZV8sIGZhbHNlXz46OnZhbHVlOworICBFWFBFQ1RfRkFMU0UodmFsdWUpOworfQorCitURVNUKFRlbXBsYXRlVXRpbFRlc3QsIFRlc3RJZGVudGl0eSkgeworICBFWFBFQ1RfVFJVRSgKKyAgICAgICh0eXBlX2VxdWFsc188R09PR0xFX05BTUVTUEFDRTo6aWRlbnRpdHlfPGludD46OnR5cGUsIGludD46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKAorICAgICAgKHR5cGVfZXF1YWxzXzxHT09HTEVfTkFNRVNQQUNFOjppZGVudGl0eV88dm9pZD46OnR5cGUsIHZvaWQ+Ojp2YWx1ZSkpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1OGNhZTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmgKQEAgLTAsMCArMSwzNjAgQEAKKy8vIENvcHlyaWdodCAoYykgMjAwNiwgR29vZ2xlIEluYy4KKy8vIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIC0tLS0KKy8vIEF1dGhvcjogTWF0dCBBdXN0ZXJuCisvLworLy8gVGhpcyBjb2RlIGlzIGNvbXBpbGVkIGRpcmVjdGx5IG9uIG1hbnkgcGxhdGZvcm1zLCBpbmNsdWRpbmcgY2xpZW50CisvLyBwbGF0Zm9ybXMgbGlrZSBXaW5kb3dzLCBNYWMsIGFuZCBlbWJlZGRlZCBzeXN0ZW1zLiAgQmVmb3JlIG1ha2luZworLy8gYW55IGNoYW5nZXMgaGVyZSwgbWFrZSBzdXJlIHRoYXQgeW91J3JlIG5vdCBicmVha2luZyBhbnkgcGxhdGZvcm1zLgorLy8KKy8vIERlZmluZSBhIHNtYWxsIHN1YnNldCBvZiB0cjEgdHlwZSB0cmFpdHMuIFRoZSB0cmFpdHMgd2UgZGVmaW5lIGFyZToKKy8vICAgZW5hYmxlX2lmCisvLyAgIGlzX2ludGVncmFsCisvLyAgIGlzX2Zsb2F0aW5nX3BvaW50CisvLyAgIGlzX3BvaW50ZXIKKy8vICAgaXNfZW51bQorLy8gICBpc19yZWZlcmVuY2UKKy8vICAgaXNfcG9kCisvLyAgIGhhc190cml2aWFsX2NvbnN0cnVjdG9yCisvLyAgIGhhc190cml2aWFsX2NvcHkKKy8vICAgaGFzX3RyaXZpYWxfYXNzaWduCisvLyAgIGhhc190cml2aWFsX2Rlc3RydWN0b3IKKy8vICAgcmVtb3ZlX2NvbnN0CisvLyAgIHJlbW92ZV92b2xhdGlsZQorLy8gICByZW1vdmVfY3YKKy8vICAgcmVtb3ZlX3JlZmVyZW5jZQorLy8gICBhZGRfcmVmZXJlbmNlCisvLyAgIHJlbW92ZV9wb2ludGVyCisvLyAgIGlzX3NhbWUKKy8vICAgaXNfY29udmVydGlibGUKKy8vIFdlIGNhbiBhZGQgbW9yZSB0eXBlIHRyYWl0cyBhcyByZXF1aXJlZC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVFlQRV9UUkFJVFNfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1RZUEVfVFJBSVRTX0hfCisKKyNpbmNsdWRlIDx1dGlsaXR5PiAgICAgICAgICAgICAgICAgIC8vIEZvciBwYWlyCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWwuaD4gIC8vIEZvciB0cnVlX3R5cGUgYW5kIGZhbHNlX3R5cGUKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKwordGVtcGxhdGU8dHlwZW5hbWUgQiwgdHlwZW5hbWUgRD4KK3N0cnVjdCBpc19iYXNlX29mIHsKKyAgdHlwZWRlZiBjaGFyICgmeWVzKVsxXTsKKyAgdHlwZWRlZiBjaGFyICgmbm8pWzJdOworCisgIHN0YXRpYyB5ZXMgY2hlY2soY29uc3QgQiopOworICBzdGF0aWMgbm8gY2hlY2soY29uc3Qgdm9pZCopOworCisgIGVudW0geworICAgIHZhbHVlID0gc2l6ZW9mKGNoZWNrKHN0YXRpY19jYXN0PGNvbnN0IEQqPihOVUxMKSkpID09IHNpemVvZih5ZXMpLAorICB9OworfTsKKwordGVtcGxhdGUgPGJvb2wgY29uZCwgY2xhc3MgVCA9IHZvaWQ+IHN0cnVjdCBlbmFibGVfaWY7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2ludGVncmFsOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludDsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfcG9pbnRlcjsKKy8vIE1TVkMgY2FuJ3QgY29tcGlsZSB0aGlzIGNvcnJlY3RseSwgYW5kIG5laXRoZXIgY2FuIGdjYyAzLjMuNSAoYXQgbGVhc3QpCisjaWYgIWRlZmluZWQoX01TQ19WRVIpICYmICEoZGVmaW5lZChfX0dOVUNfXykgJiYgX19HTlVDX18gPD0gMykKKy8vIGlzX2VudW0gdXNlcyBpc19jb252ZXJ0aWJsZSwgd2hpY2ggaXMgbm90IGF2YWlsYWJsZSBvbiBNU1ZDLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19lbnVtOworI2VuZGlmCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3JlZmVyZW5jZTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfcG9kOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29weTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfYXNzaWduOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9kZXN0cnVjdG9yOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCByZW1vdmVfY29uc3Q7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IHJlbW92ZV92b2xhdGlsZTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgcmVtb3ZlX2N2OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCByZW1vdmVfcmVmZXJlbmNlOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBhZGRfcmVmZXJlbmNlOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCByZW1vdmVfcG9pbnRlcjsKK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPiBzdHJ1Y3QgaXNfc2FtZTsKKyNpZiAhKGRlZmluZWQoX19HTlVDX18pICYmIF9fR05VQ19fIDw9IDMpCit0ZW1wbGF0ZSA8Y2xhc3MgRnJvbSwgY2xhc3MgVG8+IHN0cnVjdCBpc19jb252ZXJ0aWJsZTsKKyNlbmRpZgorCisvLyBlbmFibGVfaWYsIGVxdWl2YWxlbnQgc2VtYW50aWNzIHRvIGMrKzExIHN0ZDo6ZW5hYmxlX2lmLCBzcGVjaWZpY2FsbHk6CisvLyAgICJJZiBCIGlzIHRydWUsIHRoZSBtZW1iZXIgdHlwZWRlZiB0eXBlIHNoYWxsIGVxdWFsIFQ7IG90aGVyd2lzZSwgdGhlcmUKKy8vICAgIHNoYWxsIGJlIG5vIG1lbWJlciB0eXBlZGVmIHR5cGUuIgorLy8gU3BlY2lmaWVkIGJ5IDIwLjkuNy42IFtPdGhlciB0cmFuc2Zvcm1hdGlvbnNdCisKK3RlbXBsYXRlPGJvb2wgY29uZCwgY2xhc3MgVD4gc3RydWN0IGVuYWJsZV9pZiB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8Y2xhc3MgVD4gc3RydWN0IGVuYWJsZV9pZjxmYWxzZSwgVD4ge307CisvLyBpc19pbnRlZ3JhbCBpcyBmYWxzZSBleGNlcHQgZm9yIHRoZSBidWlsdC1pbiBpbnRlZ2VyIHR5cGVzLiBBCisvLyBjdi1xdWFsaWZpZWQgdHlwZSBpcyBpbnRlZ3JhbCBpZiBhbmQgb25seSBpZiB0aGUgdW5kZXJseWluZyB0eXBlIGlzLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19pbnRlZ3JhbCA6IGZhbHNlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8Ym9vbD4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8Y2hhcj4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8dW5zaWduZWQgY2hhcj4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8c2lnbmVkIGNoYXI+IDogdHJ1ZV90eXBlIHsgfTsKKyNpZiBkZWZpbmVkKF9NU0NfVkVSKQorLy8gd2NoYXJfdCBpcyBub3QgYnkgZGVmYXVsdCBhIGRpc3RpbmN0IHR5cGUgZnJvbSB1bnNpZ25lZCBzaG9ydCBpbgorLy8gTWljcm9zb2Z0IEMuCisvLyBTZWUgaHR0cDovL21zZG4yLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9kaDhjaGU3cyhWUy44MCkuYXNweAordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8X193Y2hhcl90PiA6IHRydWVfdHlwZSB7IH07CisjZWxzZQordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8d2NoYXJfdD4gOiB0cnVlX3R5cGUgeyB9OworI2VuZGlmCit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19pbnRlZ3JhbDxzaG9ydD4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8dW5zaWduZWQgc2hvcnQ+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPGludD4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8dW5zaWduZWQgaW50PiA6IHRydWVfdHlwZSB7IH07Cit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19pbnRlZ3JhbDxsb25nPiA6IHRydWVfdHlwZSB7IH07Cit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19pbnRlZ3JhbDx1bnNpZ25lZCBsb25nPiA6IHRydWVfdHlwZSB7IH07CisjaWZkZWYgSEFWRV9MT05HX0xPTkcKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPGxvbmcgbG9uZz4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8dW5zaWduZWQgbG9uZyBsb25nPiA6IHRydWVfdHlwZSB7IH07CisjZW5kaWYKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfaW50ZWdyYWw8Y29uc3QgVD4gOiBpc19pbnRlZ3JhbDxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2ludGVncmFsPHZvbGF0aWxlIFQ+IDogaXNfaW50ZWdyYWw8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19pbnRlZ3JhbDxjb25zdCB2b2xhdGlsZSBUPiA6IGlzX2ludGVncmFsPFQ+IHsgfTsKKworLy8gaXNfZmxvYXRpbmdfcG9pbnQgaXMgZmFsc2UgZXhjZXB0IGZvciB0aGUgYnVpbHQtaW4gZmxvYXRpbmctcG9pbnQgdHlwZXMuCisvLyBBIGN2LXF1YWxpZmllZCB0eXBlIGlzIGludGVncmFsIGlmIGFuZCBvbmx5IGlmIHRoZSB1bmRlcmx5aW5nIHR5cGUgaXMuCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2Zsb2F0aW5nX3BvaW50IDogZmFsc2VfdHlwZSB7IH07Cit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludDxmbG9hdD4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ8ZG91YmxlPiA6IHRydWVfdHlwZSB7IH07Cit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludDxsb25nIGRvdWJsZT4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludDxjb25zdCBUPgorICAgIDogaXNfZmxvYXRpbmdfcG9pbnQ8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludDx2b2xhdGlsZSBUPgorICAgIDogaXNfZmxvYXRpbmdfcG9pbnQ8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludDxjb25zdCB2b2xhdGlsZSBUPgorICAgIDogaXNfZmxvYXRpbmdfcG9pbnQ8VD4geyB9OworCisvLyBpc19wb2ludGVyIGlzIGZhbHNlIGV4Y2VwdCBmb3IgcG9pbnRlciB0eXBlcy4gQSBjdi1xdWFsaWZpZWQgdHlwZSAoZS5nLgorLy8gImludCogY29uc3QiLCBhcyBvcHBvc2VkIHRvICJpbnQgY29uc3QqIikgaXMgY3YtcXVhbGlmaWVkIGlmIGFuZCBvbmx5IGlmCisvLyB0aGUgdW5kZXJseWluZyB0eXBlIGlzLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2ludGVyIDogZmFsc2VfdHlwZSB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvaW50ZXI8VCo+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfcG9pbnRlcjxjb25zdCBUPiA6IGlzX3BvaW50ZXI8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2ludGVyPHZvbGF0aWxlIFQ+IDogaXNfcG9pbnRlcjxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvaW50ZXI8Y29uc3Qgdm9sYXRpbGUgVD4gOiBpc19wb2ludGVyPFQ+IHsgfTsKKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSAmJiAhKGRlZmluZWQoX19HTlVDX18pICYmIF9fR05VQ19fIDw9IDMpCisKK25hbWVzcGFjZSB0eXBlX3RyYWl0c19pbnRlcm5hbCB7CisKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfY2xhc3Nfb3JfdW5pb24geworICB0ZW1wbGF0ZSA8Y2xhc3MgVT4gc3RhdGljIHNtYWxsXyB0ZXN0ZXIodm9pZCAoVTo6KikoKSk7CisgIHRlbXBsYXRlIDxjbGFzcyBVPiBzdGF0aWMgYmlnXyB0ZXN0ZXIoLi4uKTsKKyAgc3RhdGljIGNvbnN0IGJvb2wgdmFsdWUgPSBzaXplb2YodGVzdGVyPFQ+KDApKSA9PSBzaXplb2Yoc21hbGxfKTsKK307CisKKy8vIGlzX2NvbnZlcnRpYmxlIGNob2tlcyBpZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gYXJyYXkuIFRoYXQncyB3aHkKKy8vIHdlIHVzZSBhZGRfcmVmZXJlbmNlIGhlcmUuCit0ZW1wbGF0ZSA8Ym9vbCBOb3RVbnVtLCBjbGFzcyBUPiBzdHJ1Y3QgaXNfZW51bV9pbXBsCisgICAgOiBpc19jb252ZXJ0aWJsZTx0eXBlbmFtZSBhZGRfcmVmZXJlbmNlPFQ+Ojp0eXBlLCBpbnQ+IHsgfTsKKwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19lbnVtX2ltcGw8dHJ1ZSwgVD4gOiBmYWxzZV90eXBlIHsgfTsKKworfSAgLy8gbmFtZXNwYWNlIHR5cGVfdHJhaXRzX2ludGVybmFsCisKKy8vIFNwZWNpZmllZCBieSBUUjEgWzQuNS4xXSBwcmltYXJ5IHR5cGUgY2F0ZWdvcmllcy4KKworLy8gSW1wbGVtZW50YXRpb24gbm90ZToKKy8vCisvLyBFYWNoIHR5cGUgaXMgZWl0aGVyIHZvaWQsIGludGVncmFsLCBmbG9hdGluZyBwb2ludCwgYXJyYXksIHBvaW50ZXIsCisvLyByZWZlcmVuY2UsIG1lbWJlciBvYmplY3QgcG9pbnRlciwgbWVtYmVyIGZ1bmN0aW9uIHBvaW50ZXIsIGVudW0sCisvLyB1bmlvbiBvciBjbGFzcy4gT3V0IG9mIHRoZXNlLCBvbmx5IGludGVncmFsLCBmbG9hdGluZyBwb2ludCwgcmVmZXJlbmNlLAorLy8gY2xhc3MgYW5kIGVudW0gdHlwZXMgYXJlIHBvdGVudGlhbGx5IGNvbnZlcnRpYmxlIHRvIGludC4gVGhlcmVmb3JlLAorLy8gaWYgYSB0eXBlIGlzIG5vdCBhIHJlZmVyZW5jZSwgaW50ZWdyYWwsIGZsb2F0aW5nIHBvaW50IG9yIGNsYXNzIGFuZAorLy8gaXMgY29udmVydGlibGUgdG8gaW50LCBpdCdzIGEgZW51bS4gQWRkaW5nIGN2LXF1YWxpZmljYXRpb24gdG8gYSB0eXBlCisvLyBkb2VzIG5vdCBjaGFuZ2Ugd2hldGhlciBpdCdzIGFuIGVudW0uCisvLworLy8gSXMtY29udmVydGlibGUtdG8taW50IGNoZWNrIGlzIGRvbmUgb25seSBpZiBhbGwgb3RoZXIgY2hlY2tzIHBhc3MsCisvLyBiZWNhdXNlIGl0IGNhbid0IGJlIHVzZWQgd2l0aCBzb21lIHR5cGVzIChlLmcuIHZvaWQgb3IgY2xhc3NlcyB3aXRoCisvLyBpbmFjY2Vzc2libGUgY29udmVyc2lvbiBvcGVyYXRvcnMpLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19lbnVtCisgICAgOiB0eXBlX3RyYWl0c19pbnRlcm5hbDo6aXNfZW51bV9pbXBsPAorICAgICAgICAgIGlzX3NhbWU8VCwgdm9pZD46OnZhbHVlIHx8CisgICAgICAgICAgICAgIGlzX2ludGVncmFsPFQ+Ojp2YWx1ZSB8fAorICAgICAgICAgICAgICBpc19mbG9hdGluZ19wb2ludDxUPjo6dmFsdWUgfHwKKyAgICAgICAgICAgICAgaXNfcmVmZXJlbmNlPFQ+Ojp2YWx1ZSB8fAorICAgICAgICAgICAgICB0eXBlX3RyYWl0c19pbnRlcm5hbDo6aXNfY2xhc3Nfb3JfdW5pb248VD46OnZhbHVlLAorICAgICAgICAgIFQ+IHsgfTsKKwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19lbnVtPGNvbnN0IFQ+IDogaXNfZW51bTxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2VudW08dm9sYXRpbGUgVD4gOiBpc19lbnVtPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZW51bTxjb25zdCB2b2xhdGlsZSBUPiA6IGlzX2VudW08VD4geyB9OworCisjZW5kaWYKKworLy8gaXNfcmVmZXJlbmNlIGlzIGZhbHNlIGV4Y2VwdCBmb3IgcmVmZXJlbmNlIHR5cGVzLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IGlzX3JlZmVyZW5jZSA6IGZhbHNlX3R5cGUge307Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgaXNfcmVmZXJlbmNlPFQmPiA6IHRydWVfdHlwZSB7fTsKKworCisvLyBXZSBjYW4ndCBnZXQgaXNfcG9kIHJpZ2h0IHdpdGhvdXQgY29tcGlsZXIgaGVscCwgc28gZmFpbCBjb25zZXJ2YXRpdmVseS4KKy8vIFdlIHdpbGwgYXNzdW1lIGl0J3MgZmFsc2UgZXhjZXB0IGZvciBhcml0aG1ldGljIHR5cGVzLCBlbnVtZXJhdGlvbnMsCisvLyBwb2ludGVycyBhbmQgY3YtcXVhbGlmaWVkIHZlcnNpb25zIHRoZXJlb2YuIE5vdGUgdGhhdCBzdGQ6OnBhaXI8VCxVPgorLy8gaXMgbm90IGEgUE9EIGV2ZW4gaWYgVCBhbmQgVSBhcmUgUE9Ecy4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfcG9kCisgOiBpbnRlZ3JhbF9jb25zdGFudDxib29sLCAoaXNfaW50ZWdyYWw8VD46OnZhbHVlIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZmxvYXRpbmdfcG9pbnQ8VD46OnZhbHVlIHx8CisjaWYgIWRlZmluZWQoX01TQ19WRVIpICYmICEoZGVmaW5lZChfX0dOVUNfXykgJiYgX19HTlVDX18gPD0gMykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpc19lbnVtIGlzIG5vdCBhdmFpbGFibGUgb24gTVNWQy4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19lbnVtPFQ+Ojp2YWx1ZSB8fAorI2VuZGlmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfcG9pbnRlcjxUPjo6dmFsdWUpPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvZDxjb25zdCBUPiA6IGlzX3BvZDxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvZDx2b2xhdGlsZSBUPiA6IGlzX3BvZDxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvZDxjb25zdCB2b2xhdGlsZSBUPiA6IGlzX3BvZDxUPiB7IH07CisKKworLy8gV2UgY2FuJ3QgZ2V0IGhhc190cml2aWFsX2NvbnN0cnVjdG9yIHJpZ2h0IHdpdGhvdXQgY29tcGlsZXIgaGVscCwgc28KKy8vIGZhaWwgY29uc2VydmF0aXZlbHkuIFdlIHdpbGwgYXNzdW1lIGl0J3MgZmFsc2UgZXhjZXB0IGZvcjogKDEpIHR5cGVzCisvLyBmb3Igd2hpY2ggaXNfcG9kIGlzIHRydWUuICgyKSBzdGQ6OnBhaXIgb2YgdHlwZXMgd2l0aCB0cml2aWFsCisvLyBjb25zdHJ1Y3RvcnMuICgzKSBhcnJheSBvZiBhIHR5cGUgd2l0aCBhIHRyaXZpYWwgY29uc3RydWN0b3IuCisvLyAoNCkgY29uc3QgdmVyc2lvbnMgdGhlcmVvZi4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29uc3RydWN0b3IgOiBpc19wb2Q8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzIFU+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxzdGQ6OnBhaXI8VCwgVT4gPgorICA6IGludGVncmFsX2NvbnN0YW50PGJvb2wsCisgICAgICAgICAgICAgICAgICAgICAgKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPFQ+Ojp2YWx1ZSAmJgorICAgICAgICAgICAgICAgICAgICAgICBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxVPjo6dmFsdWUpPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgQSwgaW50IE4+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxBW05dPgorICA6IGhhc190cml2aWFsX2NvbnN0cnVjdG9yPEE+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8Y29uc3QgVD4KKyAgOiBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxUPiB7IH07CisKKy8vIFdlIGNhbid0IGdldCBoYXNfdHJpdmlhbF9jb3B5IHJpZ2h0IHdpdGhvdXQgY29tcGlsZXIgaGVscCwgc28gZmFpbAorLy8gY29uc2VydmF0aXZlbHkuIFdlIHdpbGwgYXNzdW1lIGl0J3MgZmFsc2UgZXhjZXB0IGZvcjogKDEpIHR5cGVzCisvLyBmb3Igd2hpY2ggaXNfcG9kIGlzIHRydWUuICgyKSBzdGQ6OnBhaXIgb2YgdHlwZXMgd2l0aCB0cml2aWFsIGNvcHkKKy8vIGNvbnN0cnVjdG9ycy4gKDMpIGFycmF5IG9mIGEgdHlwZSB3aXRoIGEgdHJpdmlhbCBjb3B5IGNvbnN0cnVjdG9yLgorLy8gKDQpIGNvbnN0IHZlcnNpb25zIHRoZXJlb2YuCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGhhc190cml2aWFsX2NvcHkgOiBpc19wb2Q8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzIFU+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb3B5PHN0ZDo6cGFpcjxULCBVPiA+CisgIDogaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAoaGFzX3RyaXZpYWxfY29weTxUPjo6dmFsdWUgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgaGFzX3RyaXZpYWxfY29weTxVPjo6dmFsdWUpPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgQSwgaW50IE4+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb3B5PEFbTl0+CisgIDogaGFzX3RyaXZpYWxfY29weTxBPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGhhc190cml2aWFsX2NvcHk8Y29uc3QgVD4gOiBoYXNfdHJpdmlhbF9jb3B5PFQ+IHsgfTsKKworLy8gV2UgY2FuJ3QgZ2V0IGhhc190cml2aWFsX2Fzc2lnbiByaWdodCB3aXRob3V0IGNvbXBpbGVyIGhlbHAsIHNvIGZhaWwKKy8vIGNvbnNlcnZhdGl2ZWx5LiBXZSB3aWxsIGFzc3VtZSBpdCdzIGZhbHNlIGV4Y2VwdCBmb3I6ICgxKSB0eXBlcworLy8gZm9yIHdoaWNoIGlzX3BvZCBpcyB0cnVlLiAoMikgc3RkOjpwYWlyIG9mIHR5cGVzIHdpdGggdHJpdmlhbCBjb3B5CisvLyBjb25zdHJ1Y3RvcnMuICgzKSBhcnJheSBvZiBhIHR5cGUgd2l0aCBhIHRyaXZpYWwgYXNzaWduIGNvbnN0cnVjdG9yLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9hc3NpZ24gOiBpc19wb2Q8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzIFU+IHN0cnVjdCBoYXNfdHJpdmlhbF9hc3NpZ248c3RkOjpwYWlyPFQsIFU+ID4KKyAgOiBpbnRlZ3JhbF9jb25zdGFudDxib29sLAorICAgICAgICAgICAgICAgICAgICAgIChoYXNfdHJpdmlhbF9hc3NpZ248VD46OnZhbHVlICYmCisgICAgICAgICAgICAgICAgICAgICAgIGhhc190cml2aWFsX2Fzc2lnbjxVPjo6dmFsdWUpPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgQSwgaW50IE4+IHN0cnVjdCBoYXNfdHJpdmlhbF9hc3NpZ248QVtOXT4KKyAgOiBoYXNfdHJpdmlhbF9hc3NpZ248QT4geyB9OworCisvLyBXZSBjYW4ndCBnZXQgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvciByaWdodCB3aXRob3V0IGNvbXBpbGVyIGhlbHAsIHNvCisvLyBmYWlsIGNvbnNlcnZhdGl2ZWx5LiBXZSB3aWxsIGFzc3VtZSBpdCdzIGZhbHNlIGV4Y2VwdCBmb3I6ICgxKSB0eXBlcworLy8gZm9yIHdoaWNoIGlzX3BvZCBpcyB0cnVlLiAoMikgc3RkOjpwYWlyIG9mIHR5cGVzIHdpdGggdHJpdmlhbAorLy8gZGVzdHJ1Y3RvcnMuICgzKSBhcnJheSBvZiBhIHR5cGUgd2l0aCBhIHRyaXZpYWwgZGVzdHJ1Y3Rvci4KKy8vICg0KSBjb25zdCB2ZXJzaW9ucyB0aGVyZW9mLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9kZXN0cnVjdG9yIDogaXNfcG9kPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxzdGQ6OnBhaXI8VCwgVT4gPgorICA6IGludGVncmFsX2NvbnN0YW50PGJvb2wsCisgICAgICAgICAgICAgICAgICAgICAgKGhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlICYmCisgICAgICAgICAgICAgICAgICAgICAgIGhhc190cml2aWFsX2Rlc3RydWN0b3I8VT46OnZhbHVlKT4geyB9OwordGVtcGxhdGUgPGNsYXNzIEEsIGludCBOPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxBW05dPgorICA6IGhhc190cml2aWFsX2Rlc3RydWN0b3I8QT4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGNvbnN0IFQ+CisgIDogaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxUPiB7IH07CisKKy8vIFNwZWNpZmllZCBieSBUUjEgWzQuNy4xXQordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9jb25zdCB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9jb25zdDxUIGNvbnN0PiB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV92b2xhdGlsZSB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV92b2xhdGlsZTxUIHZvbGF0aWxlPiB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9jdiB7CisgIHR5cGVkZWYgdHlwZW5hbWUgcmVtb3ZlX2NvbnN0PHR5cGVuYW1lIHJlbW92ZV92b2xhdGlsZTxUPjo6dHlwZT46OnR5cGUgdHlwZTsKK307CisKKworLy8gU3BlY2lmaWVkIGJ5IFRSMSBbNC43LjJdIFJlZmVyZW5jZSBtb2RpZmljYXRpb25zLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9yZWZlcmVuY2UgeyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfcmVmZXJlbmNlPFQmPiB7IHR5cGVkZWYgVCB0eXBlOyB9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IGFkZF9yZWZlcmVuY2UgeyB0eXBlZGVmIFQmIHR5cGU7IH07Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IGFkZF9yZWZlcmVuY2U8VCY+IHsgdHlwZWRlZiBUJiB0eXBlOyB9OworCisvLyBTcGVjaWZpZWQgYnkgVFIxIFs0LjcuNF0gUG9pbnRlciBtb2RpZmljYXRpb25zLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9wb2ludGVyIHsgdHlwZWRlZiBUIHR5cGU7IH07Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgcmVtb3ZlX3BvaW50ZXI8VCo+IHsgdHlwZWRlZiBUIHR5cGU7IH07Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgcmVtb3ZlX3BvaW50ZXI8VCogY29uc3Q+IHsgdHlwZWRlZiBUIHR5cGU7IH07Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgcmVtb3ZlX3BvaW50ZXI8VCogdm9sYXRpbGU+IHsgdHlwZWRlZiBUIHR5cGU7IH07Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgcmVtb3ZlX3BvaW50ZXI8VCogY29uc3Qgdm9sYXRpbGU+IHsKKyAgdHlwZWRlZiBUIHR5cGU7IH07CisKKy8vIFNwZWNpZmllZCBieSBUUjEgWzQuNl0gUmVsYXRpb25zaGlwcyBiZXR3ZWVuIHR5cGVzCit0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBVPiBzdHJ1Y3QgaXNfc2FtZSA6IHB1YmxpYyBmYWxzZV90eXBlIHsgfTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBpc19zYW1lPFQsIFQ+IDogcHVibGljIHRydWVfdHlwZSB7IH07CisKKy8vIFNwZWNpZmllZCBieSBUUjEgWzQuNl0gUmVsYXRpb25zaGlwcyBiZXR3ZWVuIHR5cGVzCisjaWYgIShkZWZpbmVkKF9fR05VQ19fKSAmJiBfX0dOVUNfXyA8PSAzKQorbmFtZXNwYWNlIHR5cGVfdHJhaXRzX2ludGVybmFsIHsKKworLy8gVGhpcyBjbGFzcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgZm9yIGlzX2NvbnZlcnRpYmxlLCBhbmQgeW91CisvLyBkb24ndCBuZWVkIHRvIGtub3cgaG93IGl0IHdvcmtzIHRvIHVzZSBpc19jb252ZXJ0aWJsZS4gRm9yIHRob3NlCisvLyB3aG8gY2FyZTogd2UgZGVjbGFyZSB0d28gZGlmZmVyZW50IGZ1bmN0aW9ucywgb25lIHdob3NlIGFyZ3VtZW50IGlzCisvLyBvZiB0eXBlIFRvIGFuZCBvbmUgd2l0aCBhIHZhcmlhZGljIGFyZ3VtZW50IGxpc3QuIFdlIGdpdmUgdGhlbQorLy8gcmV0dXJuIHR5cGVzIG9mIGRpZmZlcmVudCBzaXplLCBzbyB3ZSBjYW4gdXNlIHNpemVvZiB0byB0cmljayB0aGUKKy8vIGNvbXBpbGVyIGludG8gdGVsbGluZyB1cyB3aGljaCBmdW5jdGlvbiBpdCB3b3VsZCBoYXZlIGNob3NlbiBpZiB3ZQorLy8gaGFkIGNhbGxlZCBpdCB3aXRoIGFuIGFyZ3VtZW50IG9mIHR5cGUgRnJvbS4gIFNlZSBBbGV4YW5kcmVzY3UncworLy8gX01vZGVybiBDKysgRGVzaWduXyBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoaXMgc29ydCBvZiB0cmljay4KKwordGVtcGxhdGUgPHR5cGVuYW1lIEZyb20sIHR5cGVuYW1lIFRvPgorc3RydWN0IENvbnZlcnRIZWxwZXIgeworICBzdGF0aWMgc21hbGxfIFRlc3QoVG8pOworICBzdGF0aWMgYmlnXyBUZXN0KC4uLik7CisgIHN0YXRpYyBGcm9tIENyZWF0ZSgpOworICBlbnVtIHsKKyAgICB2YWx1ZSA9IHNpemVvZihUZXN0KENyZWF0ZSgpKSkgPT0gc2l6ZW9mKHNtYWxsXykKKyAgfTsKK307Cit9ICAvLyBuYW1lc3BhY2UgdHlwZV90cmFpdHNfaW50ZXJuYWwKKworLy8gSW5oZXJpdHMgZnJvbSB0cnVlX3R5cGUgaWYgRnJvbSBpcyBjb252ZXJ0aWJsZSB0byBUbywgZmFsc2VfdHlwZSBvdGhlcndpc2UuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRnJvbSwgdHlwZW5hbWUgVG8+CitzdHJ1Y3QgaXNfY29udmVydGlibGUKKyAgICA6IGludGVncmFsX2NvbnN0YW50PGJvb2wsCisgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX3RyYWl0c19pbnRlcm5hbDo6Q29udmVydEhlbHBlcjxGcm9tLCBUbz46OnZhbHVlPiB7Cit9OworI2VuZGlmCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1RZUEVfVFJBSVRTX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0c191bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OWMxMGFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0c191bml0dGVzdC5jYwpAQCAtMCwwICsxLDYzMSBAQAorLy8gQ29weXJpZ2h0IChjKSAyMDA2LCBHb29nbGUgSW5jLgorLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gLS0tLQorLy8gQXV0aG9yOiBNYXR0IEF1c3Rlcm4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oPgorCisjaW5jbHVkZSA8c3RkbGliLmg+ICAgLy8gZm9yIGV4aXQoKQorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCit0eXBlZGVmIGludCBpbnQzMjsKKy8vIElCTSBBSVggdHlwZWRlZnMgYGludDY0YCBpbiBgc3lzL2ludHR5cGVzLmhgLCBpbmNsdWRlZCB0cmFuc2l0aXZlbHkgYWJvdmUuCisjaWZuZGVmIF9BSVgKK3R5cGVkZWYgbG9uZyBpbnQ2NDsKKyNlbmRpZgorCit1c2luZyBzdGQ6OnN0cmluZzsKK3VzaW5nIHN0ZDo6dmVjdG9yOwordXNpbmcgc3RkOjpwYWlyOworCisKKy8vIFRoaXMgYXNzZXJ0aW9uIHByb2R1Y2VzIGVycm9ycyBsaWtlICJlcnJvcjogaW52YWxpZCB1c2Ugb2YKKy8vIGluY29tcGxldGUgdHlwZSAnc3RydWN0IDx1bm5hbWVkPjo6QXNzZXJ0VHlwZXNFcTxjb25zdCBpbnQsIGludD4nIgorLy8gd2hlbiBpdCBmYWlscy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IHN0cnVjdCBBc3NlcnRUeXBlc0VxOwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IEFzc2VydFR5cGVzRXE8VCwgVD4ge307CisjZGVmaW5lIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKFQsIFUpIHN0YXRpY19jYXN0PHZvaWQ+KEFzc2VydFR5cGVzRXE8VCwgVT4oKSkKKworLy8gQSB1c2VyLWRlZmluZWQgUE9EIHR5cGUuCitzdHJ1Y3QgQSB7CisgIGludCBuXzsKK307CisKKy8vIEEgdXNlci1kZWZpbmVkIG5vbi1QT0QgdHlwZSB3aXRoIGEgdHJpdmlhbCBjb3B5IGNvbnN0cnVjdG9yLgorY2xhc3MgQiB7CisgcHVibGljOgorICBleHBsaWNpdCBCKGludCBuKSA6IG5fKG4pIHsgfQorIHByaXZhdGU6CisgIGludCBuXzsKK307CisKKy8vIEFub3RoZXIgdXNlci1kZWZpbmVkIG5vbi1QT0QgdHlwZSB3aXRoIGEgdHJpdmlhbCBjb3B5IGNvbnN0cnVjdG9yLgorLy8gV2Ugd2lsbCBleHBsaWNpdGx5IGRlY2xhcmUgQyB0byBoYXZlIGEgdHJpdmlhbCBjb3B5IGNvbnN0cnVjdG9yCisvLyBieSBzcGVjaWFsaXppbmcgaGFzX3RyaXZpYWxfY29weS4KK2NsYXNzIEMgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgQyhpbnQgbikgOiBuXyhuKSB7IH0KKyBwcml2YXRlOgorICBpbnQgbl87Cit9OworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8PiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29weTxDPiA6IHRydWVfdHlwZSB7IH07Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBBbm90aGVyIHVzZXItZGVmaW5lZCBub24tUE9EIHR5cGUgd2l0aCBhIHRyaXZpYWwgYXNzaWdubWVudCBvcGVyYXRvci4KKy8vIFdlIHdpbGwgZXhwbGljaXRseSBkZWNsYXJlIEMgdG8gaGF2ZSBhIHRyaXZpYWwgYXNzaWdubWVudCBvcGVyYXRvcgorLy8gYnkgc3BlY2lhbGl6aW5nIGhhc190cml2aWFsX2Fzc2lnbi4KK2NsYXNzIEQgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRChpbnQgbikgOiBuXyhuKSB7IH0KKyBwcml2YXRlOgorICBpbnQgbl87Cit9OworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8PiBzdHJ1Y3QgaGFzX3RyaXZpYWxfYXNzaWduPEQ+IDogdHJ1ZV90eXBlIHsgfTsKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEFub3RoZXIgdXNlci1kZWZpbmVkIG5vbi1QT0QgdHlwZSB3aXRoIGEgdHJpdmlhbCBjb25zdHJ1Y3Rvci4KKy8vIFdlIHdpbGwgZXhwbGljaXRseSBkZWNsYXJlIEUgdG8gaGF2ZSBhIHRyaXZpYWwgY29uc3RydWN0b3IKKy8vIGJ5IHNwZWNpYWxpemluZyBoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvci4KK2NsYXNzIEUgeworIHB1YmxpYzoKKyAgaW50IG5fOworfTsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPD4gc3RydWN0IGhhc190cml2aWFsX2NvbnN0cnVjdG9yPEU+IDogdHJ1ZV90eXBlIHsgfTsKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEFub3RoZXIgdXNlci1kZWZpbmVkIG5vbi1QT0QgdHlwZSB3aXRoIGEgdHJpdmlhbCBkZXN0cnVjdG9yLgorLy8gV2Ugd2lsbCBleHBsaWNpdGx5IGRlY2xhcmUgRSB0byBoYXZlIGEgdHJpdmlhbCBkZXN0cnVjdG9yCisvLyBieSBzcGVjaWFsaXppbmcgaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvci4KK2NsYXNzIEYgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRihpbnQgbikgOiBuXyhuKSB7IH0KKyBwcml2YXRlOgorICBpbnQgbl87Cit9OworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8PiBzdHJ1Y3QgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxGPiA6IHRydWVfdHlwZSB7IH07Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCitlbnVtIEcge307CisKK3VuaW9uIEgge307CisKK2NsYXNzIEkgeworIHB1YmxpYzoKKyAgb3BlcmF0b3IgaW50KCkgY29uc3Q7Cit9OworCitjbGFzcyBKIHsKKyBwcml2YXRlOgorICBvcGVyYXRvciBpbnQoKSBjb25zdDsKK307CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CituYW1lc3BhY2UgeworCisvLyBBIGJhc2UgY2xhc3MgYW5kIGEgZGVyaXZlZCBjbGFzcyB0aGF0IGluaGVyaXRzIGZyb20gaXQsIHVzZWQgZm9yCisvLyB0ZXN0aW5nIGNvbnZlcnNpb24gdHlwZSB0cmFpdHMuCitjbGFzcyBCYXNlIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgfkJhc2UoKSB7IH0KK307CisKK2NsYXNzIERlcml2ZWQgOiBwdWJsaWMgQmFzZSB7Cit9OworCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SXNJbnRlZ2VyKSB7CisgIC8vIFZlcmlmeSB0aGF0IGlzX2ludGVncmFsIGlzIHRydWUgZm9yIGFsbCBpbnRlZ2VyIHR5cGVzLgorICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDxib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDxjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDx1bnNpZ25lZCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDxzaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8d2NoYXJfdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDx1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDx1bnNpZ25lZCBzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8dW5zaWduZWQgbG9uZz46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBpc19pbnRlZ3JhbCBpcyBmYWxzZSBmb3IgYSBmZXcgbm9uLWludGVnZXIgdHlwZXMuCisgIEVYUEVDVF9GQUxTRShpc19pbnRlZ3JhbDx2b2lkPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfaW50ZWdyYWw8ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19pbnRlZ3JhbDxzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19pbnRlZ3JhbDxpbnQqPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfaW50ZWdyYWw8QT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19pbnRlZ3JhbDxwYWlyPGludCwgaW50PiA+Ojp2YWx1ZSkpOworCisgIC8vIFZlcmlmeSB0aGF0IGN2LXF1YWxpZmllZCBpbnRlZ3JhbCB0eXBlcyBhcmUgc3RpbGwgaW50ZWdyYWwsIGFuZAorICAvLyBjdi1xdWFsaWZpZWQgbm9uLWludGVncmFsIHR5cGVzIGFyZSBzdGlsbCBub24taW50ZWdyYWwuCisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPGNvbnN0IGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPHZvbGF0aWxlIGJvb2w+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPGNvbnN0IHZvbGF0aWxlIHVuc2lnbmVkIGludD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2ludGVncmFsPGNvbnN0IGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfaW50ZWdyYWw8aW50KiB2b2xhdGlsZT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2ludGVncmFsPGNvbnN0IHZvbGF0aWxlIHN0cmluZz46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdElzRmxvYXRpbmcpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgaXNfZmxvYXRpbmdfcG9pbnQgaXMgdHJ1ZSBmb3IgYWxsIGZsb2F0aW5nLXBvaW50IHR5cGVzLgorICBFWFBFQ1RfVFJVRShpc19mbG9hdGluZ19wb2ludDxmbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfZmxvYXRpbmdfcG9pbnQ8ZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19mbG9hdGluZ19wb2ludDxsb25nIGRvdWJsZT46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBpc19mbG9hdGluZ19wb2ludCBpcyBmYWxzZSBmb3IgYSBmZXcgbm9uLWZsb2F0IHR5cGVzLgorICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8dm9pZD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2Zsb2F0aW5nX3BvaW50PGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDxzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDxmbG9hdCo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDxBPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoKGlzX2Zsb2F0aW5nX3BvaW50PHBhaXI8aW50LCBpbnQ+ID46OnZhbHVlKSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgY3YtcXVhbGlmaWVkIGZsb2F0aW5nIHBvaW50IHR5cGVzIGFyZSBzdGlsbCBmbG9hdGluZywgYW5kCisgIC8vIGN2LXF1YWxpZmllZCBub24tZmxvYXRpbmcgdHlwZXMgYXJlIHN0aWxsIG5vbi1mbG9hdGluZy4KKyAgRVhQRUNUX1RSVUUoaXNfZmxvYXRpbmdfcG9pbnQ8Y29uc3QgZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2Zsb2F0aW5nX3BvaW50PHZvbGF0aWxlIGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfZmxvYXRpbmdfcG9pbnQ8Y29uc3Qgdm9sYXRpbGUgbG9uZyBkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDxjb25zdCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDx2b2xhdGlsZSBzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDxjb25zdCB2b2xhdGlsZSBjaGFyPjo6dmFsdWUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SXNQb2ludGVyKSB7CisgIC8vIFZlcmlmeSB0aGF0IGlzX3BvaW50ZXIgaXMgdHJ1ZSBmb3Igc29tZSBwb2ludGVyIHR5cGVzLgorICBFWFBFQ1RfVFJVRShpc19wb2ludGVyPGludCo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8dm9pZCo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8c3RyaW5nKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9pbnRlcjxjb25zdCB2b2lkKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9pbnRlcjx2b2xhdGlsZSBmbG9hdCogY29uc3QqPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IGlzX3BvaW50ZXIgaXMgZmFsc2UgZm9yIHNvbWUgbm9uLXBvaW50ZXIgdHlwZXMuCisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPHZvaWQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPGZsb2F0Jj46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8dmVjdG9yPGludCo+ID46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8aW50WzVdPjo6dmFsdWUpOworCisgIC8vIEEgZnVuY3Rpb24gcG9pbnRlciBpcyBhIHBvaW50ZXIsIGJ1dCBhIGZ1bmN0aW9uIHR5cGUsIG9yIGEgZnVuY3Rpb24KKyAgLy8gcmVmZXJlbmNlIHR5cGUsIGlzIG5vdC4KKyAgRVhQRUNUX1RSVUUoaXNfcG9pbnRlcjxpbnQgKCopKGludCB4KT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8dm9pZChjaGFyIHgpPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9pbnRlcjxkb3VibGUgKCYpKHN0cmluZyB4KT46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBpc19wb2ludGVyPFQ+IGlzIHRydWUgZm9yIHNvbWUgY3YtcXVhbGlmaWVkIHBvaW50ZXIgdHlwZXMsCisgIC8vIGFuZCBmYWxzZSBmb3Igc29tZSBjdi1xdWFsaWZpZWQgbm9uLXBvaW50ZXIgdHlwZXMuCisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8aW50KiBjb25zdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9pbnRlcjxjb25zdCB2b2lkKiB2b2xhdGlsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9pbnRlcjxjaGFyKiogY29uc3Qgdm9sYXRpbGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPGNvbnN0IGludD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8dm9sYXRpbGUgdmVjdG9yPGludCo+ID46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8Y29uc3Qgdm9sYXRpbGUgZG91YmxlPjo6dmFsdWUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SXNFbnVtKSB7CisvLyBpc19lbnVtIGlzbid0IHN1cHBvcnRlZCBvbiBNU1ZDIG9yIGdjYyAzLngKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgJiYgIShkZWZpbmVkKF9fR05VQ19fKSAmJiBfX0dOVUNfXyA8PSAzKQorICAvLyBWZXJpZnkgdGhhdCBpc19lbnVtIGlzIHRydWUgZm9yIGVudW0gdHlwZXMuCisgIEVYUEVDVF9UUlVFKGlzX2VudW08Rz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfZW51bTxjb25zdCBHPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19lbnVtPHZvbGF0aWxlIEc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2VudW08Y29uc3Qgdm9sYXRpbGUgRz46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBpc19lbnVtIGlzIGZhbHNlIGZvciBhIGZldyBub24tZW51bSB0eXBlcy4KKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08dm9pZD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08RyY+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEdbMV0+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPGNvbnN0IEdbMV0+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEdbXT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxmbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08QT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08QSo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPGNvbnN0IEE+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEg+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEk+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPHZvaWQoKT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08dm9pZCgqKSgpPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxpbnQgQTo6Kj46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08dm9pZCAoQTo6KikoKT46OnZhbHVlKTsKKyNlbmRpZgorfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SXNSZWZlcmVuY2UpIHsKKyAgLy8gVmVyaWZpZXMgdGhhdCBpc19yZWZlcmVuY2UgaXMgdHJ1ZSBmb3IgYWxsIHJlZmVyZW5jZSB0eXBlcy4KKyAgdHlwZWRlZiBmbG9hdCYgUmVmRmxvYXQ7CisgIEVYUEVDVF9UUlVFKGlzX3JlZmVyZW5jZTxmbG9hdCY+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3JlZmVyZW5jZTxjb25zdCBpbnQmPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8Y29uc3QgaW50KiY+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3JlZmVyZW5jZTxpbnQgKCYpKGJvb2wpPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8UmVmRmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3JlZmVyZW5jZTxjb25zdCBSZWZGbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcmVmZXJlbmNlPHZvbGF0aWxlIFJlZkZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8Y29uc3Qgdm9sYXRpbGUgUmVmRmxvYXQ+Ojp2YWx1ZSk7CisKKworICAvLyBWZXJpZmllcyB0aGF0IGlzX3JlZmVyZW5jZSBpcyBmYWxzZSBmb3IgYWxsIG5vbi1yZWZlcmVuY2UgdHlwZXMuCisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8Y29uc3QgZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8dm9sYXRpbGUgZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8Y29uc3Qgdm9sYXRpbGUgZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8Y29uc3QgaW50Kj46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3JlZmVyZW5jZTxpbnQoKT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3JlZmVyZW5jZTx2b2lkKCopKGNvbnN0IGNoYXImKT46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdEFkZFJlZmVyZW5jZSkgeworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQmLCBhZGRfcmVmZXJlbmNlPGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCBpbnQmLCBhZGRfcmVmZXJlbmNlPGNvbnN0IGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUSh2b2xhdGlsZSBpbnQmLAorICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRfcmVmZXJlbmNlPHZvbGF0aWxlIGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCB2b2xhdGlsZSBpbnQmLAorICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRfcmVmZXJlbmNlPGNvbnN0IHZvbGF0aWxlIGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQmLCBhZGRfcmVmZXJlbmNlPGludCY+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3QgaW50JiwgYWRkX3JlZmVyZW5jZTxjb25zdCBpbnQmPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKHZvbGF0aWxlIGludCYsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZF9yZWZlcmVuY2U8dm9sYXRpbGUgaW50Jj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCB2b2xhdGlsZSBpbnQmLAorICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRfcmVmZXJlbmNlPGNvbnN0IHZvbGF0aWxlIGludCY+Ojp0eXBlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdElzUG9kKSB7CisgIC8vIFZlcmlmeSB0aGF0IGFyaXRobWV0aWMgdHlwZXMgYW5kIHBvaW50ZXJzIGFyZSBtYXJrZWQgYXMgUE9Ecy4KKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGJvb2w+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8dW5zaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHNpZ25lZCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8d2NoYXJfdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHVuc2lnbmVkIGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8dW5zaWduZWQgc2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxsb25nPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8dW5zaWduZWQgbG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8ZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8bG9uZyBkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxzdHJpbmcqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8QSo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxjb25zdCBCKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPEMqKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGNvbnN0IGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGNoYXIqIHZvbGF0aWxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8Y29uc3Qgdm9sYXRpbGUgZG91YmxlPjo6dmFsdWUpOworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSAmJiAhKGRlZmluZWQoX19HTlVDX18pICYmIF9fR05VQ19fIDw9IDMpCisgIEVYUEVDVF9UUlVFKGlzX3BvZDxHPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8Y29uc3QgRz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHZvbGF0aWxlIEc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxjb25zdCB2b2xhdGlsZSBHPjo6dmFsdWUpOworI2VuZGlmCisKKyAgLy8gVmVyaWZ5IHRoYXQgc29tZSBub24tUE9EIHR5cGVzIGFyZSBub3QgbWFya2VkIGFzIFBPRHMuCisgIEVYUEVDVF9GQUxTRShpc19wb2Q8dm9pZD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvZDxzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfcG9kPHBhaXI8aW50LCBpbnQ+ID46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2Q8QT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvZDxCPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9kPEM+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2Q8Y29uc3Qgc3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9kPHZvbGF0aWxlIEE+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2Q8Y29uc3Qgdm9sYXRpbGUgQj46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdEhhc1RyaXZpYWxDb25zdHJ1Y3RvcikgeworICAvLyBWZXJpZnkgdGhhdCBhcml0aG1ldGljIHR5cGVzIGFuZCBwb2ludGVycyBoYXZlIHRyaXZpYWwgY29uc3RydWN0b3JzLgorICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvcjxib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvcjx1bnNpZ25lZCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxzaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8d2NoYXJfdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvcjx1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvcjx1bnNpZ25lZCBzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8dW5zaWduZWQgbG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8bG9uZyBkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHN0cmluZyo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPEEqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvcjxjb25zdCBCKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8QyoqPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHBhaXJzIGFuZCBhcnJheXMgb2Ygc3VjaCB0eXBlcyBoYXZlIHRyaXZpYWwKKyAgLy8gY29uc3RydWN0b3JzLgorICB0eXBlZGVmIGludCBpbnQxMFsxMF07CisgIEVYUEVDVF9UUlVFKChoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxwYWlyPGludCwgY2hhcio+ID46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGludDEwPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHBhaXJzIG9mIHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBjb25zdHJ1Y3RvcnMKKyAgLy8gYXJlIG5vdCBtYXJrZWQgYXMgdHJpdmlhbC4KKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxwYWlyPGludCwgc3RyaW5nPiA+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHBhaXI8c3RyaW5nLCBpbnQ+ID46OnZhbHVlKSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgdHlwZXMgd2l0aG91dCB0cml2aWFsIGNvbnN0cnVjdG9ycyBhcmUKKyAgLy8gY29ycmVjdGx5IG1hcmtlZCBhcyBzdWNoLgorICBFWFBFQ1RfRkFMU0UoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8c3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8dmVjdG9yPGludD4gPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IEUsIHdoaWNoIHdlIGhhdmUgZGVjbGFyZWQgdG8gaGF2ZSBhIHRyaXZpYWwKKyAgLy8gY29uc3RydWN0b3IsIGlzIGNvcnJlY3RseSBtYXJrZWQgYXMgc3VjaC4KKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8RT46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdEhhc1RyaXZpYWxDb3B5KSB7CisgIC8vIFZlcmlmeSB0aGF0IGFyaXRobWV0aWMgdHlwZXMgYW5kIHBvaW50ZXJzIGhhdmUgdHJpdmlhbCBjb3B5CisgIC8vIGNvbnN0cnVjdG9ycy4KKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8dW5zaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxzaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTx3Y2hhcl90Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTx1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8c2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8dW5zaWduZWQgc2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTx1bnNpZ25lZCBsb25nPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxsb25nIGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxzdHJpbmcqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PEEqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PGNvbnN0IEIqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PEMqKj46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBhbmQgYXJyYXlzIG9mIHN1Y2ggdHlwZXMgaGF2ZSB0cml2aWFsCisgIC8vIGNvcHkgY29uc3RydWN0b3JzLgorICB0eXBlZGVmIGludCBpbnQxMFsxMF07CisgIEVYUEVDVF9UUlVFKChoYXNfdHJpdmlhbF9jb3B5PHBhaXI8aW50LCBjaGFyKj4gPjo6dmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxpbnQxMD46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBvZiB0eXBlcyB3aXRob3V0IHRyaXZpYWwgY29weSBjb25zdHJ1Y3RvcnMKKyAgLy8gYXJlIG5vdCBtYXJrZWQgYXMgdHJpdmlhbC4KKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9jb3B5PHBhaXI8aW50LCBzdHJpbmc+ID46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaGFzX3RyaXZpYWxfY29weTxwYWlyPHN0cmluZywgaW50PiA+Ojp2YWx1ZSkpOworCisgIC8vIFZlcmlmeSB0aGF0IHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBjb3B5IGNvbnN0cnVjdG9ycyBhcmUKKyAgLy8gY29ycmVjdGx5IG1hcmtlZCBhcyBzdWNoLgorICBFWFBFQ1RfRkFMU0UoaGFzX3RyaXZpYWxfY29weTxzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShoYXNfdHJpdmlhbF9jb3B5PHZlY3RvcjxpbnQ+ID46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBDLCB3aGljaCB3ZSBoYXZlIGRlY2xhcmVkIHRvIGhhdmUgYSB0cml2aWFsCisgIC8vIGNvcHkgY29uc3RydWN0b3IsIGlzIGNvcnJlY3RseSBtYXJrZWQgYXMgc3VjaC4KKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxDPjo6dmFsdWUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SGFzVHJpdmlhbEFzc2lnbikgeworICAvLyBWZXJpZnkgdGhhdCBhcml0aG1ldGljIHR5cGVzIGFuZCBwb2ludGVycyBoYXZlIHRyaXZpYWwgYXNzaWdubWVudAorICAvLyBvcGVyYXRvcnMuCisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248Y2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPHVuc2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxzaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPHdjaGFyX3Q+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjx1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPHVuc2lnbmVkIHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPHVuc2lnbmVkIGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxmbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPGxvbmcgZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248c3RyaW5nKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPEEqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248Y29uc3QgQio+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxDKio+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgcGFpcnMgYW5kIGFycmF5cyBvZiBzdWNoIHR5cGVzIGhhdmUgdHJpdmlhbAorICAvLyBhc3NpZ25tZW50IG9wZXJhdG9ycy4KKyAgdHlwZWRlZiBpbnQgaW50MTBbMTBdOworICBFWFBFQ1RfVFJVRSgoaGFzX3RyaXZpYWxfYXNzaWduPHBhaXI8aW50LCBjaGFyKj4gPjo6dmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPGludDEwPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHBhaXJzIG9mIHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBhc3NpZ25tZW50IG9wZXJhdG9ycworICAvLyBhcmUgbm90IG1hcmtlZCBhcyB0cml2aWFsLgorICBFWFBFQ1RfRkFMU0UoKGhhc190cml2aWFsX2Fzc2lnbjxwYWlyPGludCwgc3RyaW5nPiA+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGhhc190cml2aWFsX2Fzc2lnbjxwYWlyPHN0cmluZywgaW50PiA+Ojp2YWx1ZSkpOworCisgIC8vIFZlcmlmeSB0aGF0IHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBhc3NpZ25tZW50IG9wZXJhdG9ycyBhcmUKKyAgLy8gY29ycmVjdGx5IG1hcmtlZCBhcyBzdWNoLgorICBFWFBFQ1RfRkFMU0UoaGFzX3RyaXZpYWxfYXNzaWduPHN0cmluZz46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGhhc190cml2aWFsX2Fzc2lnbjx2ZWN0b3I8aW50PiA+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgRCwgd2hpY2ggd2UgaGF2ZSBkZWNsYXJlZCB0byBoYXZlIGEgdHJpdmlhbAorICAvLyBhc3NpZ25tZW50IG9wZXJhdG9yLCBpcyBjb3JyZWN0bHkgbWFya2VkIGFzIHN1Y2guCisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxEPjo6dmFsdWUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SGFzVHJpdmlhbERlc3RydWN0b3IpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgYXJpdGhtZXRpYyB0eXBlcyBhbmQgcG9pbnRlcnMgaGF2ZSB0cml2aWFsIGRlc3RydWN0b3JzLgorICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGJvb2w+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8Y2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjx1bnNpZ25lZCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHNpZ25lZCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHdjaGFyX3Q+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHVuc2lnbmVkIGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjx1bnNpZ25lZCBzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjxsb25nPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHVuc2lnbmVkIGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8ZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGxvbmcgZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHN0cmluZyo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8QSo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8Y29uc3QgQio+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8QyoqPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHBhaXJzIGFuZCBhcnJheXMgb2Ygc3VjaCB0eXBlcyBoYXZlIHRyaXZpYWwKKyAgLy8gZGVzdHJ1Y3RvcnMuCisgIHR5cGVkZWYgaW50IGludDEwWzEwXTsKKyAgRVhQRUNUX1RSVUUoKGhhc190cml2aWFsX2Rlc3RydWN0b3I8cGFpcjxpbnQsIGNoYXIqPiA+Ojp2YWx1ZSkpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGludDEwPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHBhaXJzIG9mIHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBkZXN0cnVjdG9ycworICAvLyBhcmUgbm90IG1hcmtlZCBhcyB0cml2aWFsLgorICBFWFBFQ1RfRkFMU0UoKGhhc190cml2aWFsX2Rlc3RydWN0b3I8cGFpcjxpbnQsIHN0cmluZz4gPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHBhaXI8c3RyaW5nLCBpbnQ+ID46OnZhbHVlKSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgdHlwZXMgd2l0aG91dCB0cml2aWFsIGRlc3RydWN0b3JzIGFyZQorICAvLyBjb3JyZWN0bHkgbWFya2VkIGFzIHN1Y2guCisgIEVYUEVDVF9GQUxTRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHN0cmluZz46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8dmVjdG9yPGludD4gPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IEYsIHdoaWNoIHdlIGhhdmUgZGVjbGFyZWQgdG8gaGF2ZSBhIHRyaXZpYWwKKyAgLy8gZGVzdHJ1Y3RvciwgaXMgY29ycmVjdGx5IG1hcmtlZCBhcyBzdWNoLgorICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPEY+Ojp2YWx1ZSk7Cit9CisKKy8vIFRlc3RzIHJlbW92ZV9wb2ludGVyLgorVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdFJlbW92ZVBvaW50ZXIpIHsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfcG9pbnRlcjxpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfcG9pbnRlcjxpbnQqPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGNvbnN0IGludCwgcmVtb3ZlX3BvaW50ZXI8Y29uc3QgaW50Kj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsIHJlbW92ZV9wb2ludGVyPGludCogY29uc3Q+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfcG9pbnRlcjxpbnQqIHZvbGF0aWxlPjo6dHlwZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RSZW1vdmVDb25zdCkgeworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsIHJlbW92ZV9jb25zdDxpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfY29uc3Q8Y29uc3QgaW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCAqLCByZW1vdmVfY29uc3Q8aW50ICogY29uc3Q+Ojp0eXBlKTsKKyAgLy8gVFIxIGV4YW1wbGVzLgorICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCBpbnQgKiwgcmVtb3ZlX2NvbnN0PGNvbnN0IGludCAqPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKHZvbGF0aWxlIGludCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlX2NvbnN0PGNvbnN0IHZvbGF0aWxlIGludD46OnR5cGUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0UmVtb3ZlVm9sYXRpbGUpIHsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfdm9sYXRpbGU8aW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3ZvbGF0aWxlPHZvbGF0aWxlIGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQgKiwgcmVtb3ZlX3ZvbGF0aWxlPGludCAqIHZvbGF0aWxlPjo6dHlwZSk7CisgIC8vIFRSMSBleGFtcGxlcy4KKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEodm9sYXRpbGUgaW50ICosCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZV92b2xhdGlsZTx2b2xhdGlsZSBpbnQgKj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCBpbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZV92b2xhdGlsZTxjb25zdCB2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdFJlbW92ZUNWKSB7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX2N2PGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsIHJlbW92ZV9jdjx2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfY3Y8Y29uc3QgaW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCAqLCByZW1vdmVfY3Y8aW50ICogY29uc3Qgdm9sYXRpbGU+Ojp0eXBlKTsKKyAgLy8gVFIxIGV4YW1wbGVzLgorICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCB2b2xhdGlsZSBpbnQgKiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlX2N2PGNvbnN0IHZvbGF0aWxlIGludCAqPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlX2N2PGNvbnN0IHZvbGF0aWxlIGludD46OnR5cGUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0UmVtb3ZlUmVmZXJlbmNlKSB7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3JlZmVyZW5jZTxpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfcmVmZXJlbmNlPGludCY+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3QgaW50LCByZW1vdmVfcmVmZXJlbmNlPGNvbnN0IGludCY+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50KiwgcmVtb3ZlX3JlZmVyZW5jZTxpbnQgKiAmPjo6dHlwZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RJc1NhbWUpIHsKKyAgRVhQRUNUX1RSVUUoKGlzX3NhbWU8aW50MzIsIGludDMyPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPGludDMyLCBpbnQ2ND46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTxpbnQ2NCwgaW50MzI+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8aW50LCBjb25zdCBpbnQ+Ojp2YWx1ZSkpOworCisgIEVYUEVDVF9UUlVFKChpc19zYW1lPHZvaWQsIHZvaWQ+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8dm9pZCwgaW50Pjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPGludCwgdm9pZD46OnZhbHVlKSk7CisKKyAgRVhQRUNUX1RSVUUoKGlzX3NhbWU8aW50KiwgaW50Kj46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKChpc19zYW1lPHZvaWQqLCB2b2lkKj46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTxpbnQqLCB2b2lkKj46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTx2b2lkKiwgaW50Kj46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTx2b2lkKiwgY29uc3Qgdm9pZCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8dm9pZCosIHZvaWQqIGNvbnN0Pjo6dmFsdWUpKTsKKworICBFWFBFQ1RfVFJVRSgoaXNfc2FtZTxCYXNlKiwgQmFzZSo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfVFJVRSgoaXNfc2FtZTxEZXJpdmVkKiwgRGVyaXZlZCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8QmFzZSosIERlcml2ZWQqPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPERlcml2ZWQqLCBCYXNlKj46OnZhbHVlKSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RDb252ZXJ0aWJsZSkgeworI2lmICEoZGVmaW5lZChfX0dOVUNfXykgJiYgX19HTlVDX18gPD0gMykKKyAgRVhQRUNUX1RSVUUoKGlzX2NvbnZlcnRpYmxlPGludCwgaW50Pjo6dmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoKGlzX2NvbnZlcnRpYmxlPGludCwgbG9uZz46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKChpc19jb252ZXJ0aWJsZTxsb25nLCBpbnQ+Ojp2YWx1ZSkpOworCisgIEVYUEVDVF9UUlVFKChpc19jb252ZXJ0aWJsZTxpbnQqLCB2b2lkKj46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfY29udmVydGlibGU8dm9pZCosIGludCo+Ojp2YWx1ZSkpOworCisgIEVYUEVDVF9UUlVFKChpc19jb252ZXJ0aWJsZTxEZXJpdmVkKiwgQmFzZSo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX2NvbnZlcnRpYmxlPEJhc2UqLCBEZXJpdmVkKj46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKChpc19jb252ZXJ0aWJsZTxEZXJpdmVkKiwgY29uc3QgQmFzZSo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX2NvbnZlcnRpYmxlPGNvbnN0IERlcml2ZWQqLCBCYXNlKj46OnZhbHVlKSk7CisjZW5kaWYKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmUxYzkwZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmNjCkBAIC0wLDAgKzEsMzM0NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZkZWYgX1dJTjMyCisvLyBWZXJpZnkgdGhhdCAjaW5jbHVkaW5nIHdpbmRvd3MuaCBkb2VzIG5vdCBicmVhayBhbnl0aGluZyAoZS5nLiBiZWNhdXNlCisvLyB3aW5kb3dzLmggI2RlZmluZXMgR2V0TWVzc2FnZSgpIGFzIGEgbWFjcm8pLgorI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCit2b2lkIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSkgeworICBTZXRPcHRpb25hbEZpZWxkcyhtZXNzYWdlKTsKKyAgQWRkUmVwZWF0ZWRGaWVsZHMxKG1lc3NhZ2UpOworICBBZGRSZXBlYXRlZEZpZWxkczIobWVzc2FnZSk7CisgIFNldERlZmF1bHRGaWVsZHMobWVzc2FnZSk7CisgIFNldE9uZW9mRmllbGRzKG1lc3NhZ2UpOworfQorCit2b2lkIFRlc3RVdGlsOjpTZXRPcHRpb25hbEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbnQzMiAgICgxMDEpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfaW50NjQgICAoMTAyKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3VpbnQzMiAgKDEwMyk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF91aW50NjQgICgxMDQpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfc2ludDMyICAoMTA1KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NpbnQ2NCAgKDEwNik7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9maXhlZDMyICgxMDcpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZml4ZWQ2NCAoMTA4KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NmaXhlZDMyKDEwOSk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9zZml4ZWQ2NCgxMTApOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZmxvYXQgICAoMTExKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2RvdWJsZSAgKDExMik7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9ib29sICAgICh0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3N0cmluZyAgKCIxMTUiKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2J5dGVzICAgKCIxMTYiKTsKKworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLT5zZXRfYSgxMTcpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLT5zZXRfYmIoMTE4KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS0+c2V0X2MoMTE5KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS0+c2V0X2QoMTIwKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS0+c2V0X2UoMTI2KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS0+c2V0X2JiKDEyNyk7CisKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX25lc3RlZF9lbnVtICh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVopOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZm9yZWlnbl9lbnVtKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiAgICAgICk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFaKTsKKworICAvLyBTdHJpbmdQaWVjZSBhbmQgQ29yZCBmaWVsZHMgYXJlIG9ubHkgYWNjZXNzaWJsZSB2aWEgcmVmbGVjdGlvbiBpbiB0aGUKKyAgLy8gb3BlbiBzb3VyY2UgcmVsZWFzZTsgc2VlIGNvbW1lbnRzIGluIGNvbXBpbGVyL2NwcC9zdHJpbmdfZmllbGQuY2MuCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgbWVzc2FnZSwKKyAgICBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfc3RyaW5nX3BpZWNlIiksCisgICAgIjEyNCIpOworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9jb3JkIiksCisgICAgIjEyNSIpOworI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkFkZFJlcGVhdGVkRmllbGRzMSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQzMiAgICgyMDEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50NjQgICAoMjAyKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQzMiAgKDIwMyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF91aW50NjQgICgyMDQpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ludDMyICAoMjA1KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NpbnQ2NCAgKDIwNik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9maXhlZDMyICgyMDcpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZml4ZWQ2NCAoMjA4KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDMyKDIwOSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zZml4ZWQ2NCgyMTApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZmxvYXQgICAoMjExKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2RvdWJsZSAgKDIxMik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9ib29sICAgICh0cnVlKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3N0cmluZyAgKCIyMTUiKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2J5dGVzICAgKCIyMTYiKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRncm91cCAgICAgICAgICAgKCktPnNldF9hKDIxNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoKS0+c2V0X2JiKDIxOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoMjE5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgpLT5zZXRfZCgyMjApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKCktPnNldF9iYigyMjcpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSAodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9CQVIgICAgICApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBUik7CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkFkZFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwKKyAgICAiMjI0Iik7CisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+QWRkU3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2NvcmQiKSwKKyAgICAiMjI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKK3ZvaWQgVGVzdFV0aWw6OkFkZFJlcGVhdGVkRmllbGRzMih1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ludDMyICAgKDMwMSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQ2NCAgICgzMDIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDMyICAoMzAzKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQ2NCAgKDMwNCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50MzIgICgzMDUpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ludDY0ICAoMzA2KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZpeGVkMzIgKDMwNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9maXhlZDY0ICgzMDgpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkMzIoMzA5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDY0KDMxMCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mbG9hdCAgICgzMTEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZG91YmxlICAoMzEyKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3N0cmluZyAgKCIzMTUiKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2J5dGVzICAgKCIzMTYiKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRncm91cCAgICAgICAgICAgKCktPnNldF9hKDMxNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoKS0+c2V0X2JiKDMxOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoMzE5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgpLT5zZXRfZCgzMjApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKCktPnNldF9iYigzMjcpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSAodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWik7CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkFkZFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwKKyAgICAiMzI0Iik7CisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+QWRkU3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2NvcmQiKSwKKyAgICAiMzI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6U2V0RGVmYXVsdEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ludDMyICAgKDQwMSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ludDY0ICAgKDQwMik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3VpbnQzMiAgKDQwMyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3VpbnQ2NCAgKDQwNCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NpbnQzMiAgKDQwNSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NpbnQ2NCAgKDQwNik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZpeGVkMzIgKDQwNyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZpeGVkNjQgKDQwOCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NmaXhlZDMyKDQwOSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NmaXhlZDY0KDQxMCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2Zsb2F0ICAgKDQxMSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2RvdWJsZSAgKDQxMik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc3RyaW5nICAoIjQxNSIpOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9ieXRlcyAgICgiNDE2Iik7CisKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfbmVzdGVkX2VudW0gKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICApOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PKTsKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0U3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImRlZmF1bHRfc3RyaW5nX3BpZWNlIiksCisgICAgIjQyNCIpOworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJkZWZhdWx0X2NvcmQiKSwKKyAgICAiNDI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6TW9kaWZ5UmVwZWF0ZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfaW50MzIgICAoMSwgNTAxKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ludDY0ICAgKDEsIDUwMik7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF91aW50MzIgICgxLCA1MDMpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfdWludDY0ICAoMSwgNTA0KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3NpbnQzMiAgKDEsIDUwNSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zaW50NjQgICgxLCA1MDYpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZml4ZWQzMiAoMSwgNTA3KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ZpeGVkNjQgKDEsIDUwOCk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zZml4ZWQzMigxLCA1MDkpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfc2ZpeGVkNjQoMSwgNTEwKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2Zsb2F0ICAgKDEsIDUxMSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9kb3VibGUgICgxLCA1MTIpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfYm9vbCAgICAoMSwgdHJ1ZSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zdHJpbmcgICgxLCAiNTE1Iik7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9ieXRlcyAgICgxLCAiNTE2Iik7CisKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMSktPnNldF9hKDUxNyk7CisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDEpLT5zZXRfYmIoNTE4KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMSktPnNldF9jKDUxOSk7CisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLT5zZXRfZCg1MjApOworICBtZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgxKS0+c2V0X2JiKDUyNyk7CisKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX25lc3RlZF9lbnVtICgxLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08pOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEsIHVuaXR0ZXN0OjpGT1JFSUdOX0ZPTyAgICAgICk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9pbXBvcnRfZW51bSAoMSwgdW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PKTsKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0UmVwZWF0ZWRTdHJpbmcoCisgICAgbWVzc2FnZSwKKyAgICBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksCisgICAgMSwgIjUyNCIpOworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldFJlcGVhdGVkU3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2NvcmQiKSwKKyAgICAxLCAiNTI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQordm9pZCBUZXN0VXRpbDo6U2V0T25lb2ZGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5zZXRfb25lb2ZfdWludDMyKDYwMSk7CisgIG1lc3NhZ2UtPm11dGFibGVfb25lb2ZfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDYwMik7CisgIG1lc3NhZ2UtPnNldF9vbmVvZl9zdHJpbmcoIjYwMyIpOworICBtZXNzYWdlLT5zZXRfb25lb2ZfYnl0ZXMoIjYwNCIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ludDMyICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDY0KCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2Jvb2wgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxncm91cCAgICAgICAgICAgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLmhhc19hKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLmhhc19iYigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS5oYXNfYygpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS5oYXNfZCgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS5oYXNfZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3N0cmluZ19waWVjZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfY29yZCgpKTsKKyNlbmRpZgorCisgIEVYUEVDVF9FUSgxMDEgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDEwMiAgLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoMTAzICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSgxMDQgICwgbWVzc2FnZS5vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDEwNSAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMTA2ICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgxMDcgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDEwOCAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoMTA5ICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgxMTAgICwgbWVzc2FnZS5vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDExMSAgLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoMTEyICAsIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCIxMTUiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIjExNiIsIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0VRKDExNywgbWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAgKCkuYSgpKTsKKyAgRVhQRUNUX0VRKDExOCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAgKCkuYmIoKSk7CisgIEVYUEVDVF9FUSgxMTksIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlICAgICAgICgpLmMoKSk7CisgIEVYUEVDVF9FUSgxMjAsIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgICgpLmQoKSk7CisgIEVYUEVDVF9FUSgxMjYsIG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlICgpLmUoKSk7CisgIEVYUEVDVF9FUSgxMjcsIG1lc3NhZ2Uub3B0aW9uYWxfbGF6eV9tZXNzYWdlICAgICAgICAgICgpLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaICAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWiwgbWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDApLmJiKCkpOworCisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDApKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMSkpOworICBFWFBFQ1RfRVEoMzAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoMzA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMSkpOworICBFWFBFQ1RfRVEoMzA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMSkpOworICBFWFBFQ1RfRVEoMzExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMSkpOworICBFWFBFQ1RfRVEoIjMxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMSkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMSkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDEpLmEoKSk7CisgIEVYUEVDVF9FUSgzMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgxKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgxKS5kKCkpOworICBFWFBFQ1RfRVEoMzI3LCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bSAoMSkpOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDY0ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3N0cmluZyAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRVEoNDAxICAsIG1lc3NhZ2UuZGVmYXVsdF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDQwMiAgLCBtZXNzYWdlLmRlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9FUSg0MDMgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoNDA0ICAsIG1lc3NhZ2UuZGVmYXVsdF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDQwNSAgLCBtZXNzYWdlLmRlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9FUSg0MDYgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoNDA3ICAsIG1lc3NhZ2UuZGVmYXVsdF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDQwOCAgLCBtZXNzYWdlLmRlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9FUSg0MDkgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoNDEwICAsIG1lc3NhZ2UuZGVmYXVsdF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDQxMSAgLCBtZXNzYWdlLmRlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9FUSg0MTIgICwgbWVzc2FnZS5kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UuZGVmYXVsdF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCI0MTUiLCBtZXNzYWdlLmRlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9FUSgiNDE2IiwgbWVzc2FnZS5kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UuZGVmYXVsdF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08sIG1lc3NhZ2UuZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfdWludDMyICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX3N0cmluZyAgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vbmVvZl9ieXRlcyAgICAgICAgICAoKSk7CisKKyAgRVhQRUNUX0VRKCI2MDQiLCBtZXNzYWdlLm9uZW9mX2J5dGVzKCkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpIHsKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgaW5pdGlhbGx5IGJlIGZhbHNlIGZvciBhbGwgb3B0aW9uYWwgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW50MzIgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfdWludDY0ICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZml4ZWQzMiAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfYm9vbCAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc3RyaW5nX3BpZWNlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfY29yZCgpKTsKKworICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHplcm8gb3Igc29tZXRoaW5nIGxpa2UgaXQuCisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9GQUxTRSggICAgbWVzc2FnZS5vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIiIgICAsIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLmhhc19hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5oYXNfYmIoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpLmhhc19jKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS5oYXNfZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuaGFzX2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpLmhhc19iYigpKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKS5hKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5iYigpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlICAgICAgKCkuYygpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkuZCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbGF6eV9tZXNzYWdlICAgICAgICAgKCkuYmIoKSk7CisKKyAgLy8gRW51bXMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZW51bS4KKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTywgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PLCBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19waWVjZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9jb3JkX3NpemUoKSk7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyBGaWVsZHMgd2l0aCBkZWZhdWx0cyBoYXZlIHRoZWlyIGRlZmF1bHQgdmFsdWVzIChkdWgpLgorICBFWFBFQ1RfRVEoIDQxICAgICwgbWVzc2FnZS5kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfRVEoIDQyICAgICwgbWVzc2FnZS5kZWZhdWx0X2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoIDQzICAgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoIDQ0ICAgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoLTQ1ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoIDQ2ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoIDQ3ICAgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfRVEoIDQ4ICAgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoIDQ5ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoLTUwICAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRVEoIDUxLjUgICwgbWVzc2FnZS5kZWZhdWx0X2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoIDUyZTMgICwgbWVzc2FnZS5kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfVFJVRSggICAgICAgbWVzc2FnZS5kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgbWVzc2FnZS5kZWZhdWx0X3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIndvcmxkIiwgbWVzc2FnZS5kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UuZGVmYXVsdF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVIgICAgICAsIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UuZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfdWludDMyICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX3N0cmluZyAgICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfYnl0ZXMgICAgICAgICAoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIC8vIE1vZGlmeVJlcGVhdGVkRmllbGRzIG9ubHkgc2V0cyB0aGUgc2Vjb25kIHJlcGVhdGVkIGVsZW1lbnQgb2YgZWFjaAorICAvLyBmaWVsZC4gIEluIGFkZGl0aW9uIHRvIHZlcmlmeWluZyB0aGlzLCB3ZSBhbHNvIHZlcmlmeSB0aGF0IHRoZSBmaXJzdAorICAvLyBlbGVtZW50IGFuZCBzaXplIHdlcmUgKm5vdCogbW9kaWZpZWQuCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7CisKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDUwMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwMyAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNCAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNiAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNyAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzIgKDEpKTsKKyAgRVhQRUNUX0VRKDUwOCAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjQgKDEpKTsKKyAgRVhQRUNUX0VRKDUwOSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDUxMCAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0KDEpKTsKKyAgRVhQRUNUX0VRKDUxMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUxMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnJlcGVhdGVkX2Jvb2wgICAgKDEpKTsKKyAgRVhQRUNUX0VRKCI1MTUiLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyAgKDEpKTsKKyAgRVhQRUNUX0VRKCI1MTYiLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzICAgKDEpKTsKKworICBFWFBFQ1RfRVEoNTE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXAgICAgICAgICAgICgxKS5hKCkpOworICBFWFBFQ1RfRVEoNTE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgxKS5iYigpKTsKKyAgRVhQRUNUX0VRKDUxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMSkuYygpKTsKKyAgRVhQRUNUX0VRKDUyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMSkuZCgpKTsKKyAgRVhQRUNUX0VRKDUyNywgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoMSkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTywgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08sIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDEpKTsKKworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OlNldFBhY2tlZEZpZWxkcyh1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfaW50MzIgICAoNjAxKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQ2NCAgICg2MDIpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3VpbnQzMiAgKDYwMyk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDY0ICAoNjA0KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zaW50MzIgICg2MDUpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQ2NCAgKDYwNik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZml4ZWQzMiAoNjA3KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDY0ICg2MDgpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NmaXhlZDMyKDYwOSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkNjQoNjEwKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9mbG9hdCAgICg2MTEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2RvdWJsZSAgKDYxMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfYm9vbCAgICAodHJ1ZSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZW51bSAgICAodW5pdHRlc3Q6OkZPUkVJR05fQkFSKTsKKyAgLy8gYWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkCisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfaW50MzIgICAoNzAxKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQ2NCAgICg3MDIpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3VpbnQzMiAgKDcwMyk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDY0ICAoNzA0KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zaW50MzIgICg3MDUpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQ2NCAgKDcwNik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZml4ZWQzMiAoNzA3KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDY0ICg3MDgpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NmaXhlZDMyKDcwOSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkNjQoNzEwKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9mbG9hdCAgICg3MTEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2RvdWJsZSAgKDcxMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfYm9vbCAgICAoZmFsc2UpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2VudW0gICAgKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWik7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlNldFVucGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRUeXBlcyogbWVzc2FnZSkgeworICAvLyBUaGUgdmFsdWVzIGFwcGxpZWQgaGVyZSBtdXN0IG1hdGNoIHRob3NlIG9mIFNldFBhY2tlZEZpZWxkcy4KKworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfaW50MzIgICAoNjAxKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ludDY0ICAgKDYwMik7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF91aW50MzIgICg2MDMpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfdWludDY0ICAoNjA0KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX3NpbnQzMiAgKDYwNSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9zaW50NjQgICg2MDYpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfZml4ZWQzMiAoNjA3KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ZpeGVkNjQgKDYwOCk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9zZml4ZWQzMig2MDkpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfc2ZpeGVkNjQoNjEwKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2Zsb2F0ICAgKDYxMSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9kb3VibGUgICg2MTIpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfYm9vbCAgICAodHJ1ZSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9lbnVtICAgICh1bml0dGVzdDo6Rk9SRUlHTl9CQVIpOworICAvLyBhZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ludDMyICAgKDcwMSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9pbnQ2NCAgICg3MDIpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfdWludDMyICAoNzAzKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX3VpbnQ2NCAgKDcwNCk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9zaW50MzIgICg3MDUpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfc2ludDY0ICAoNzA2KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ZpeGVkMzIgKDcwNyk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9maXhlZDY0ICg3MDgpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfc2ZpeGVkMzIoNzA5KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX3NmaXhlZDY0KDcxMCk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9mbG9hdCAgICg3MTEpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfZG91YmxlICAoNzEyKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2VudW0gICAgKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6TW9kaWZ5UGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9pbnQzMiAgICgxLCA4MDEpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ludDY0ICAgKDEsIDgwMik7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfdWludDMyICAoMSwgODAzKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF91aW50NjQgICgxLCA4MDQpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX3NpbnQzMiAgKDEsIDgwNSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ludDY0ICAoMSwgODA2KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9maXhlZDMyICgxLCA4MDcpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ZpeGVkNjQgKDEsIDgwOCk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ZpeGVkMzIoMSwgODA5KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9zZml4ZWQ2NCgxLCA4MTApOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2Zsb2F0ICAgKDEsIDgxMSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfZG91YmxlICAoMSwgODEyKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9ib29sICAgICgxLCB0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9lbnVtICAgICgxLCB1bml0dGVzdDo6Rk9SRUlHTl9GT08pOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UucGFja2VkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLnBhY2tlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5wYWNrZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UucGFja2VkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLnBhY2tlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5wYWNrZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLnBhY2tlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5wYWNrZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfVFJVRSggICAgIG1lc3NhZ2UucGFja2VkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwgbWVzc2FnZS5wYWNrZWRfZW51bSgwKSk7CisKKyAgRVhQRUNUX0VRKDcwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSg3MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg3MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSg3MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDcxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSg3MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVosIG1lc3NhZ2UucGFja2VkX2VudW0oMSkpOworfQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RVbnBhY2tlZEZpZWxkc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMmIG1lc3NhZ2UpIHsKKyAgLy8gVGhlIHZhbHVlcyBleHBlY3RlZCBoZXJlIG11c3QgbWF0Y2ggdGhvc2Ugb2YgRXhwZWN0UGFja2VkRmllbGRzU2V0LgorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLnVucGFja2VkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLnVucGFja2VkX2ludDY0ICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMyAgLCBtZXNzYWdlLnVucGFja2VkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLnVucGFja2VkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLnVucGFja2VkX3NpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNiAgLCBtZXNzYWdlLnVucGFja2VkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkNjQgKDApKTsKKyAgRVhQRUNUX0VRKDYwOSAgLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLnVucGFja2VkX2Zsb2F0ICAgKDApKTsKKyAgRVhQRUNUX0VRKDYxMiAgLCBtZXNzYWdlLnVucGFja2VkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnVucGFja2VkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwgbWVzc2FnZS51bnBhY2tlZF9lbnVtKDApKTsKKworICBFWFBFQ1RfRVEoNzAxICAsIG1lc3NhZ2UudW5wYWNrZWRfaW50MzIgICAoMSkpOworICBFWFBFQ1RfRVEoNzAyICAsIG1lc3NhZ2UudW5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIG1lc3NhZ2UudW5wYWNrZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA0ICAsIG1lc3NhZ2UudW5wYWNrZWRfdWludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoNzA1ICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoNzA3ICAsIG1lc3NhZ2UudW5wYWNrZWRfZml4ZWQzMiAoMSkpOworICBFWFBFQ1RfRVEoNzA4ICAsIG1lc3NhZ2UudW5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoNzEwICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ZpeGVkNjQoMSkpOworICBFWFBFQ1RfRVEoNzExICAsIG1lc3NhZ2UudW5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIG1lc3NhZ2UudW5wYWNrZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UudW5wYWNrZWRfYm9vbCAgICAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaLCBtZXNzYWdlLnVucGFja2VkX2VudW0oMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZENsZWFyKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMmIG1lc3NhZ2UpIHsKKyAgLy8gUGFja2VkIHJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzJiBtZXNzYWdlKSB7CisgIC8vIERvIHRoZSBzYW1lIGZvciBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzLgorICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfdWludDY0X3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zaW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQzMl9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9kb3VibGVfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfYm9vbF9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVIsIG1lc3NhZ2UucGFja2VkX2VudW0oMCkpOworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDgwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSg4MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoODAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg4MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoODA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSg4MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoODA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDgxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSg4MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoODEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08sIG1lc3NhZ2UucGFja2VkX2VudW0oMSkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBFeHRlbnNpb25zCisvLworLy8gQWxsIHRoaXMgY29kZSBpcyBleGFjdGx5IGVxdWl2YWxlbnQgdG8gdGhlIGFib3ZlIGNvZGUgZXhjZXB0IHRoYXQgaXQncworLy8gbWFuaXB1bGF0aW5nIGV4dGVuc2lvbiBmaWVsZHMgaW5zdGVhZCBvZiBub3JtYWwgb25lcy4KKy8vCisvLyBJIGdhdmUgdXAgb24gdGhlIDgwLWNoYXIgbGltaXQgaGVyZS4gIFNvcnJ5LgorCit2b2lkIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgICwgMTAxKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24gICAsIDEwMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbiAgLCAxMDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb24gICwgMTA0KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uICAsIDEwNSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbiAgLCAxMDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMTA3KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbiAsIDEwOCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAxMDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbiwgMTEwKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mbG9hdF9leHRlbnNpb24gICAsIDExMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbiAgLCAxMTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uICAgICwgdHJ1ZSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgLCAiMTE1Iik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uICAgLCAiMTE2Iik7CisKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24gICAgICAgICAgICktPnNldF9hKDExNyk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfYmIoMTE4KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9jKDExOSk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfZCgxMjApOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uLCB1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWik7CisKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uLCAiMTI0Iik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfY29yZF9leHRlbnNpb24sICIxMjUiKTsKKworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS0+c2V0X2UoMTI2KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9iYigxMjcpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24gICAsIDIwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAyMDIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24gICwgMjAzKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uICAsIDIwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAyMDUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb24gICwgMjA2KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDIwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAyMDgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMjA5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDIxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAyMTEpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24gICwgMjEyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbiAgICAsIHRydWUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgIjIxNSIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiAgICwgIjIxNiIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICktPnNldF9hKDIxNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICktPnNldF9iYigyMTgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLT5zZXRfYygyMTkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfZCgyMjApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApLT5zZXRfYmIoMjI3KTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgIjIyNCIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAiMjI1Iik7CisKKyAgLy8gQWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICwgMzAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAsIDMwMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgLCAzMDMpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICwgMzA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDMwNSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAzMDYpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMzA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDMwOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAzMDkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMzEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAsIDMxMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAzMTIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgIjMxNSIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiAgICwgIjMxNiIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICktPnNldF9hKDMxNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICktPnNldF9iYigzMTgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLT5zZXRfYygzMTkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfZCgzMjApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApLT5zZXRfYmIoMzI3KTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFaICAgICAgKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVopOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgIjMyNCIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAiMzI1Iik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uICAgLCA0MDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uICAgLCA0MDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgLCA0MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbiAgLCA0MDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbiAgLCA0MDUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgLCA0MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb24gLCA0MDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb24gLCA0MDgpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCA0MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCA0MTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uICAgLCA0MTEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgLCA0MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYm9vbF9leHRlbnNpb24gICAgLCBmYWxzZSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICAsICI0MTUiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbiAgICwgIjQxNiIpOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb24gLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08pOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0ZPTyk7CisKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19waWVjZV9leHRlbnNpb24sICI0MjQiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uLCAiNDI1Iik7CisKKyAgU2V0T25lb2ZGaWVsZHMobWVzc2FnZSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlNldE9uZW9mRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb24sIDYwMSk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9iYig2MDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3N0cmluZ19leHRlbnNpb24sICI2MDMiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb24sICI2MDQiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHNBbmRFeHRlbnNpb25zKAorICAgIHVuaXR0ZXN0OjpUZXN0RmllbGRPcmRlcmluZ3MqIG1lc3NhZ2UpIHsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2UpOworICBtZXNzYWdlLT5zZXRfbXlfaW50KDEpOworICBtZXNzYWdlLT5zZXRfbXlfc3RyaW5nKCJmb28iKTsKKyAgbWVzc2FnZS0+c2V0X215X2Zsb2F0KDEuMCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6bXlfZXh0ZW5zaW9uX2ludCwgMjMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om15X2V4dGVuc2lvbl9zdHJpbmcsICJiYXIiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpNb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxLCA1MDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSwgNTAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEsIDUwMyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxLCA1MDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSwgNTA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEsIDUwNik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxLCA1MDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSwgNTA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEsIDUwOSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxLCA1MTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSwgNTExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEsIDUxMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxLCB0cnVlKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAsIDEsICI1MTUiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEsICI1MTYiKTsKKworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgLCAxKS0+c2V0X2EoNTE3KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICwgMSktPnNldF9iYig1MTgpOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLCAxKS0+c2V0X2MoNTE5KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICwgMSktPnNldF9kKDUyMCk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAsIDEpLT5zZXRfYmIoNTI3KTsKKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIDEsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSwgdW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCAxLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08pOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgMSwgIjUyNCIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAxLCAiNTI1Iik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24gICAgICAgICAgICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICAgICkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgICAgICAgKS5oYXNfYSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICApLmhhc19iYigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gICAgICApLmhhc19jKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkuaGFzX2QoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS5oYXNfZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAgICAgICApLmhhc19iYigpKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9jb3JkX2V4dGVuc2lvbikpOworCisgIEVYUEVDVF9FUSgxMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMTAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDEwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgxMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMTA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDEwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgxMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMTA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDEwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgxMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMTExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDExMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRVEoIjExNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKCIxMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0VRKDExNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICApLmEoKSk7CisgIEVYUEVDVF9FUSgxMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gKS5iYigpKTsKKyAgRVhQRUNUX0VRKDExOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLmMoKSk7CisgIEVYUEVDVF9FUSgxMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKS5kKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb24gKSk7CisKKyAgRVhQRUNUX0VRKCIxMjQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoIjEyNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9jb3JkX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMTI2LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLmUoKSk7CisgIEVYUEVDVF9FUSgxMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uKS5iYigpKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gICAgKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbikpOworCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgLCAwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICAsIDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sIDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5kKCkpOworICBFWFBFQ1RfRVEoMjI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiAgICwgMCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKworICBFWFBFQ1RfRVEoIjIyNCIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgiMjI1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgRVhQRUNUX0VRKDMwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDMwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDMwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSgzMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDMxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSgzMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiMzE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEpKTsKKworICBFWFBFQ1RfRVEoMzE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDMxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDMyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSgzMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFaLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMSkpOworCisgIEVYUEVDVF9FUSgiMzI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKCIzMjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDEpKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiApKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDQwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDQwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDQwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDQwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDQwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDQxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDQxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDQxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKCI0MTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0ZPTywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9FUSgiNDI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoIjQyNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuaGFzX2JiKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2Zfc3RyaW5nX2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDYwMSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDYwMiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuYmIoKSk7CisgIEVYUEVDVF9FUSgiNjAzIiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3N0cmluZ19leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCI2MDQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCkpOworICBFWFBFQ1RfRVEoIiIsIHNlcmlhbGl6ZWQpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKworICAvLyBoYXNfYmxhaCgpIHNob3VsZCBpbml0aWFsbHkgYmUgZmFsc2UgZm9yIGFsbCBvcHRpb25hbCBmaWVsZHMuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gICAgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAgICAgICApKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgLy8gT3B0aW9uYWwgZmllbGRzIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB6ZXJvIG9yIHNvbWV0aGluZyBsaWtlIGl0LgorICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbiAgICkpOworCisgIC8vIEVtYmVkZGVkIG1lc3NhZ2VzIHNob3VsZCBhbHNvIGJlIGNsZWFyLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICAgICAgICApLmhhc19hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICApLmhhc19iYigpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgKS5oYXNfYygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gICAgICAgKS5oYXNfZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS5oYXNfZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICAgKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgICAgICAgKS5hKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICApLmJiKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gICAgICApLmMoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkuZCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS5lKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAgICAgICApLmJiKCkpOworCisgIC8vIEVudW1zIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlIGVudW0uCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08sIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb24gKSk7CisKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoIiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9jb3JkX2V4dGVuc2lvbikpOworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gICAgKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbikpOworCisgIC8vIGhhc19ibGFoKCkgc2hvdWxkIGFsc28gYmUgZmFsc2UgZm9yIGFsbCBkZWZhdWx0IGZpZWxkcy4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9jb3JkX2V4dGVuc2lvbikpOworCisgIC8vIEZpZWxkcyB3aXRoIGRlZmF1bHRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMgKGR1aCkuCisgIEVYUEVDVF9FUSggNDEgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKCA0MiAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDY0X2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoIDQzICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSggNDQgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKC00NSAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQzMl9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoIDQ2ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSggNDcgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKCA0OCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoIDQ5ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgtNTAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCA1MS41ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoIDUyZTMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoIndvcmxkIiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiApKTsKKworICBFWFBFQ1RfRVEoImFiYyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19waWVjZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCIxMjMiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9jb3JkX2V4dGVuc2lvbikpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfdWludDMyX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuaGFzX2JiKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3N0cmluZ19leHRlbnNpb24pKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb24pKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpIHsKKyAgLy8gTW9kaWZ5UmVwZWF0ZWRGaWVsZHMgb25seSBzZXRzIHRoZSBzZWNvbmQgcmVwZWF0ZWQgZWxlbWVudCBvZiBlYWNoCisgIC8vIGZpZWxkLiAgSW4gYWRkaXRpb24gdG8gdmVyaWZ5aW5nIHRoaXMsIHdlIGFsc28gdmVyaWZ5IHRoYXQgdGhlIGZpcnN0CisgIC8vIGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KiBtb2RpZmllZC4KKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAwKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMCkpOworCisgIEVYUEVDVF9FUSgiMjI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKCIyMjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDApKTsKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDUwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg1MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoNTAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg1MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNTA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg1MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoNTA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDUxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSg1MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoNTEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiNTE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoIjUxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEpKTsKKworICBFWFBFQ1RfRVEoNTE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDUxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoNTE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDUyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSg1MjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMSkpOworCisgIEVYUEVDVF9FUSgiNTI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKCI1MjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDEpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpTZXRQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDYwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICwgNjAyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgLCA2MDMpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDYwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICwgNjA1KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgLCA2MDYpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDYwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgNjA4KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCA2MDkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDYxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICwgNjExKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgLCA2MTIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIHRydWUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFSKTsKKyAgLy8gYWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICwgNzAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCA3MDIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICAsIDcwMyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICwgNzA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCA3MDUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDcwNik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgNzA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCA3MDgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24sIDcwOSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiwgNzEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCA3MTEpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDcxMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFaKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpNb2RpZnlQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDEsIDgwMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICwgMSwgODAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgLCAxLCA4MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDEsIDgwNCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICwgMSwgODA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAxLCA4MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDEsIDgwNyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSwgODA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAxLCA4MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDEsIDgxMCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSwgODExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAxLCA4MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDEsIHRydWUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgICAsIDEsCisgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6Rk9SRUlHTl9GT08pOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uICAgICkpOworCisgIEVYUEVDVF9FUSg2MDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSg2MTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDcwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoNzAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNzA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoNzA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg3MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDcxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEoNzExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcigKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb24gICAgKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc01vZGlmaWVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoNjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoNjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMCkpOworCisgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICBFWFBFQ1RfRVEoODAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoODA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoODA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg4MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEoODEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSg4MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfVFJVRSggICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08sCisgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uLCAxKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0VW5wYWNrZWRFeHRlbnNpb25zU2V0KAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRFeHRlbnNpb25zJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3VpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX2RvdWJsZV9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoNzAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3VpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNzA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNzA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg3MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEoNzEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDcxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX2RvdWJsZV9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc0FuZEV4dGVuc2lvbnNJbk9yZGVyKGNvbnN0IHN0cmluZyYgc2VyaWFsaXplZCkgeworICAvLyBXZSBzZXQgZWFjaCBmaWVsZCBpbmRpdmlkdWFsbHksIHNlcmlhbGl6ZSBzZXBhcmF0ZWx5LCBhbmQgY29uY2F0ZW5hdGUgYWxsCisgIC8vIHRoZSBzdHJpbmdzIGluIGNhbm9uaWNhbCBvcmRlciB0byBkZXRlcm1pbmUgdGhlIGV4cGVjdGVkIHNlcmlhbGl6YXRpb24uCisgIHN0cmluZyBleHBlY3RlZDsKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBtZXNzYWdlOworICBtZXNzYWdlLnNldF9teV9pbnQoMSk7ICAvLyBGaWVsZCAxLgorICBtZXNzYWdlLkFwcGVuZFRvU3RyaW5nKCZleHBlY3RlZCk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om15X2V4dGVuc2lvbl9pbnQsIDIzKTsgIC8vIEZpZWxkIDUuCisgIG1lc3NhZ2UuQXBwZW5kVG9TdHJpbmcoJmV4cGVjdGVkKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLnNldF9teV9zdHJpbmcoImZvbyIpOyAgLy8gRmllbGQgMTEuCisgIG1lc3NhZ2UuQXBwZW5kVG9TdHJpbmcoJmV4cGVjdGVkKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6bXlfZXh0ZW5zaW9uX3N0cmluZywgImJhciIpOyAgLy8gRmllbGQgNTAuCisgIG1lc3NhZ2UuQXBwZW5kVG9TdHJpbmcoJmV4cGVjdGVkKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLnNldF9teV9mbG9hdCgxLjApOyAgLy8gRmllbGQgMTAxLgorICBtZXNzYWdlLkFwcGVuZFRvU3RyaW5nKCZleHBlY3RlZCk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKworICAvLyBXZSBkb24ndCBFWFBFQ1RfRVEoKSBzaW5jZSB3ZSBkb24ndCB3YW50IHRvIHByaW50IHJhdyBieXRlcyB0byBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKHNlcmlhbGl6ZWQgPT0gZXhwZWN0ZWQpOworfQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RMYXN0UmVwZWF0ZWRzUmVtb3ZlZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIC8vIFRlc3QgdGhhdCB0aGUgcmVtYWluaW5nIGVsZW1lbnQgaXMgdGhlIGNvcnJlY3Qgb25lLgorICBFWFBFQ1RfRVEoMjAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMjA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMjA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoMjEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfVFJVRSggICAgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMCkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMCkpOworCisgIEVYUEVDVF9FUSgyMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoMjIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworICBFWFBFQ1RfRVEoMjIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZEV4dGVuc2lvbnNSZW1vdmVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworCisgIC8vIFRlc3QgdGhhdCBvbmUgZWxlbWVudCB3YXMgcmVtb3ZlZC4KKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgLy8gVGVzdCB0aGF0IHRoZSByZW1haW5pbmcgZWxlbWVudCBpcyB0aGUgY29ycmVjdCBvbmUuCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgLCAwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICAsIDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sIDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5kKCkpOworICBFWFBFQ1RfRVEoMjI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiAgICwgMCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKworICBFWFBFQ1RfRVEoIjIyNCIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgiMjI1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAwKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZHNSZWxlYXNlZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXBfc2l6ZSAgICAgICAgICAgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9zaXplICgpKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXAgICAgICAgICAgICgwKS5hKCkpOworICBFWFBFQ1RfRVEoMjE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMCkuZCgpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0TGFzdFJlcGVhdGVkRXh0ZW5zaW9uc1JlbGVhc2VkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAwKS5iYigpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRzU3dhcHBlZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIC8vIFRlc3QgdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBhbmQgc2Vjb25kIGVsZW1lbnQgYXJlIGZsaXBwZWQuCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgxKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgxKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigxKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgxKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgxKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgxKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgxKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMSkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDEpLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLmQoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLmQoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDEpKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMCkpOworICBFWFBFQ1RfRVEoMzAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMzA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMCkpOworICBFWFBFQ1RfRVEoMzA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMzExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMCkpOworICBFWFBFQ1RfRVEoIjMxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMCkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMCkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDApLmEoKSk7CisgIEVYUEVDVF9FUSgzMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFaLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRXh0ZW5zaW9uc1N3YXBwZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zJiBtZXNzYWdlKSB7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEpKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMSkpOworCisgIEVYUEVDVF9FUSgiMjI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKCIyMjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDEpKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDMwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSgzMDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDMwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgzMDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDMwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSgzMDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDMxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSgzMTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbiAgICAsIDApKTsKKyAgRVhQRUNUX0VRKCIzMTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMzE2IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiAgICwgMCkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgLCAwKS5hKCkpOworICBFWFBFQ1RfRVEoMzE4LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICwgMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgzMTksIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLCAwKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICwgMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDMyNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAsIDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCAwKSk7CisKKyAgRVhQRUNUX0VRKCIzMjQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoIjMyNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbiwgMCkpOworfQorCit2b2lkIFRlc3RVdGlsOjpTZXRPbmVvZjEodW5pdHRlc3Q6OlRlc3RPbmVvZjIqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+bXV0YWJsZV9mb29fbGF6eV9tZXNzYWdlKCktPnNldF9xdXhfaW50KDEwMCk7CisgIG1lc3NhZ2UtPnNldF9iYXJfc3RyaW5nKCIxMDEiKTsKKyAgbWVzc2FnZS0+c2V0X2Jhel9pbnQoMTAyKTsKKyAgbWVzc2FnZS0+c2V0X2Jhel9zdHJpbmcoIjEwMyIpOworfQorCit2b2lkIFRlc3RVdGlsOjpTZXRPbmVvZjIodW5pdHRlc3Q6OlRlc3RPbmVvZjIqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X2Zvb19pbnQoMjAwKTsKKyAgbWVzc2FnZS0+c2V0X2Jhcl9lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpCQVopOworICBtZXNzYWdlLT5zZXRfYmF6X2ludCgyMDIpOworICBtZXNzYWdlLT5zZXRfYmF6X3N0cmluZygiMjAzIik7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MShjb25zdCB1bml0dGVzdDo6VGVzdE9uZW9mMiYgbWVzc2FnZSkgeworICBFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX2xhenlfbWVzc2FnZSAgICAgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuZm9vX2xhenlfbWVzc2FnZSgpLmhhc19xdXhfaW50KCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Jhcl9zdHJpbmcoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Jhel9pbnQgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Jhel9zdHJpbmcoKSk7CisKKyAgQVNTRVJUX0VRKDAsIG1lc3NhZ2UuZm9vX2xhenlfbWVzc2FnZSgpLmNvcmdlX2ludF9zaXplKCkpOworCisgIEVYUEVDVF9FUSgxMDAgICwgbWVzc2FnZS5mb29fbGF6eV9tZXNzYWdlKCkucXV4X2ludCgpKTsKKyAgRVhQRUNUX0VRKCIxMDEiLCBtZXNzYWdlLmJhcl9zdHJpbmcgICAgICAgICAgICAgICAgKCkpOworICBFWFBFQ1RfRVEoMTAyICAsIG1lc3NhZ2UuYmF6X2ludCAgICAgICAgICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9FUSgiMTAzIiwgbWVzc2FnZS5iYXpfc3RyaW5nICAgICAgICAgICAgICAgICgpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKSB7CisgIEV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29faW50ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19iYXJfZW51bSAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19iYXpfaW50ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19iYXpfc3RyaW5nKCkpOworCisgIEVYUEVDVF9FUSgyMDAgICAgICAgICAgICAgICAgICAgICAgLCBtZXNzYWdlLmZvb19pbnQgICAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFaLCBtZXNzYWdlLmJhcl9lbnVtICAoKSk7CisgIEVYUEVDVF9FUSgyMDIgICAgICAgICAgICAgICAgICAgICAgLCBtZXNzYWdlLmJhel9pbnQgICAoKSk7CisgIEVYUEVDVF9FUSgiMjAzIiAgICAgICAgICAgICAgICAgICAgLCBtZXNzYWdlLmJhel9zdHJpbmcoKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdE9uZW9mQ2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RPbmVvZjImIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2J5dGVzKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb2dyb3VwKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2xhenlfbWVzc2FnZSgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfYmFyX2ludCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9zdHJpbmcoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iYXJfYnl0ZXMoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iYXJfZW51bSgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfYmF6X2ludCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhel9zdHJpbmcoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT09fTk9UX1NFVCwgbWVzc2FnZS5mb29fY2FzZSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpCQVJfTk9UX1NFVCwgbWVzc2FnZS5iYXJfY2FzZSgpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0QXRNb3N0T25lRmllbGRTZXRJbk9uZW9mKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKSB7CisgIGludCBjb3VudCA9IDA7CisgIGlmIChtZXNzYWdlLmhhc19mb29faW50KCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19mb29fYnl0ZXMoKSkgY291bnQrKzsKKyAgaWYgKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKSBjb3VudCsrOworICBpZiAobWVzc2FnZS5oYXNfZm9vZ3JvdXAoKSkgY291bnQrKzsKKyAgaWYgKG1lc3NhZ2UuaGFzX2Zvb19sYXp5X21lc3NhZ2UoKSkgY291bnQrKzsKKyAgRVhQRUNUX0xFKGNvdW50LCAxKTsKKyAgY291bnQgPSAwOworICBpZiAobWVzc2FnZS5oYXNfYmFyX2ludCgpKSBjb3VudCsrOworICBpZiAobWVzc2FnZS5oYXNfYmFyX3N0cmluZygpKSBjb3VudCsrOworICBpZiAobWVzc2FnZS5oYXNfYmFyX2J5dGVzKCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19iYXJfZW51bSgpKSBjb3VudCsrOworICBFWFBFQ1RfVFJVRShjb3VudCA9PSAwIHx8IGNvdW50ID09IDEpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1Rlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpSZWZsZWN0aW9uVGVzdGVyKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGJhc2VfZGVzY3JpcHRvcikKKyAgOiBiYXNlX2Rlc2NyaXB0b3JfKGJhc2VfZGVzY3JpcHRvcikgeworCisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sID0gYmFzZV9kZXNjcmlwdG9yLT5maWxlKCktPnBvb2woKTsKKworICBuZXN0ZWRfYl8gPQorICAgIHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuYmIiKTsKKyAgZm9yZWlnbl9jXyA9CisgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZS5jIik7CisgIGltcG9ydF9kXyA9CisgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZS5kIik7CisgIGltcG9ydF9lXyA9CisgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZS5lIik7CisgIG5lc3RlZF9mb29fID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuRk9PIik7CisgIG5lc3RlZF9iYXJfID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuQkFSIik7CisgIG5lc3RlZF9iYXpfID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuQkFaIik7CisgIGZvcmVpZ25fZm9vXyA9CisgICAgcG9vbC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuRk9SRUlHTl9GT08iKTsKKyAgZm9yZWlnbl9iYXJfID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5GT1JFSUdOX0JBUiIpOworICBmb3JlaWduX2Jhel8gPQorICAgIHBvb2wtPkZpbmRFbnVtVmFsdWVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LkZPUkVJR05fQkFaIik7CisgIGltcG9ydF9mb29fID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSU1QT1JUX0ZPTyIpOworICBpbXBvcnRfYmFyXyA9CisgICAgcG9vbC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LklNUE9SVF9CQVIiKTsKKyAgaW1wb3J0X2Jhel8gPQorICAgIHBvb2wtPkZpbmRFbnVtVmFsdWVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JTVBPUlRfQkFaIik7CisKKyAgaWYgKGJhc2VfZGVzY3JpcHRvcl8tPm5hbWUoKSA9PSAiVGVzdEFsbEV4dGVuc2lvbnMiKSB7CisgICAgZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbi5hIik7CisgICAgcmVwZWF0ZWRfZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5hIik7CisgIH0gZWxzZSB7CisgICAgZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5hIik7CisgICAgcmVwZWF0ZWRfZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5hIik7CisgIH0KKworICBFWFBFQ1RfVFJVRShncm91cF9hXyAgICAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocmVwZWF0ZWRfZ3JvdXBfYV8gIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG5lc3RlZF9iXyAgICAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb3JlaWduX2NfICAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoaW1wb3J0X2RfICAgICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGltcG9ydF9lXyAgICAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShuZXN0ZWRfZm9vXyAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobmVzdGVkX2Jhcl8gICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG5lc3RlZF9iYXpfICAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb3JlaWduX2Zvb18gICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9yZWlnbl9iYXJfICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvcmVpZ25fYmF6XyAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShpbXBvcnRfZm9vXyAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoaW1wb3J0X2Jhcl8gICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGltcG9ydF9iYXpfICAgICAgICE9IE5VTEwpOworfQorCisvLyBTaG9ydGhhbmQgdG8gZ2V0IGEgRmllbGREZXNjcmlwdG9yIGZvciBhIGZpZWxkIG9mIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpGKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9IE5VTEw7CisgIGlmIChiYXNlX2Rlc2NyaXB0b3JfLT5uYW1lKCkgPT0gIlRlc3RBbGxFeHRlbnNpb25zIiB8fAorICAgICAgYmFzZV9kZXNjcmlwdG9yXy0+bmFtZSgpID09ICJUZXN0UGFja2VkRXh0ZW5zaW9ucyIpIHsKKyAgICByZXN1bHQgPSBiYXNlX2Rlc2NyaXB0b3JfLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUobmFtZSArICJfZXh0ZW5zaW9uIik7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0gYmFzZV9kZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKG5hbWUpOworICB9CisgIEdPT0dMRV9DSEVDSyhyZXN1bHQgIT0gTlVMTCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6U2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworCisgIHJlZmxlY3Rpb24tPlNldEludDMyIChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQzMiIgICApLCAxMDEpOworICByZWZsZWN0aW9uLT5TZXRJbnQ2NCAobWVzc2FnZSwgRigib3B0aW9uYWxfaW50NjQiICAgKSwgMTAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3VpbnQzMiIgICksIDEwMyk7CisgIHJlZmxlY3Rpb24tPlNldFVJbnQ2NChtZXNzYWdlLCBGKCJvcHRpb25hbF91aW50NjQiICApLCAxMDQpOworICByZWZsZWN0aW9uLT5TZXRJbnQzMiAobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDMyIiAgKSwgMTA1KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQ2NCIgICksIDEwNik7CisgIHJlZmxlY3Rpb24tPlNldFVJbnQzMihtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDMyIiApLCAxMDcpOworICByZWZsZWN0aW9uLT5TZXRVSW50NjQobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQ2NCIgKSwgMTA4KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NmaXhlZDMyIiksIDEwOSk7CisgIHJlZmxlY3Rpb24tPlNldEludDY0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9zZml4ZWQ2NCIpLCAxMTApOworICByZWZsZWN0aW9uLT5TZXRGbG9hdCAobWVzc2FnZSwgRigib3B0aW9uYWxfZmxvYXQiICAgKSwgMTExKTsKKyAgcmVmbGVjdGlvbi0+U2V0RG91YmxlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2RvdWJsZSIgICksIDExMik7CisgIHJlZmxlY3Rpb24tPlNldEJvb2wgIChtZXNzYWdlLCBGKCJvcHRpb25hbF9ib29sIiAgICApLCB0cnVlKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZyIgICksICIxMTUiKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2J5dGVzIiAgICksICIxMTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsZ3JvdXAiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBncm91cF9hXywgMTE3KTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG5lc3RlZF9iXywgMTE4KTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCAxMTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgaW1wb3J0X2RfLCAxMjApOworCisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX2VudW0iICksICBuZXN0ZWRfYmF6Xyk7CisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9lbnVtIiksIGZvcmVpZ25fYmF6Xyk7CisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X2VudW0iICksICBpbXBvcnRfYmF6Xyk7CisKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpLCAiMTI0Iik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJvcHRpb25hbF9jb3JkIiksICIxMjUiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIGltcG9ydF9lXywgMTI2KTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG5lc3RlZF9iXywgMTI3KTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQzMiIgICApLCAyMDEpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfaW50NjQiICAgKSwgMjAyKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQzMiIgICksIDIwMyk7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBGKCJyZXBlYXRlZF91aW50NjQiICApLCAyMDQpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDMyIiAgKSwgMjA1KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQ2NCIgICksIDIwNik7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQzMihtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDMyIiApLCAyMDcpOworICByZWZsZWN0aW9uLT5BZGRVSW50NjQobWVzc2FnZSwgRigicmVwZWF0ZWRfZml4ZWQ2NCIgKSwgMjA4KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDMyIiksIDIwOSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zZml4ZWQ2NCIpLCAyMTApOworICByZWZsZWN0aW9uLT5BZGRGbG9hdCAobWVzc2FnZSwgRigicmVwZWF0ZWRfZmxvYXQiICAgKSwgMjExKTsKKyAgcmVmbGVjdGlvbi0+QWRkRG91YmxlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2RvdWJsZSIgICksIDIxMik7CisgIHJlZmxlY3Rpb24tPkFkZEJvb2wgIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9ib29sIiAgICApLCB0cnVlKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIgICksICIyMTUiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICksICIyMTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIHJlcGVhdGVkX2dyb3VwX2FfLCAyMTcpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDIxOCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCAyMTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8sIDIyMCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDIyNyk7CisKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwgIG5lc3RlZF9iYXJfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iKSwgZm9yZWlnbl9iYXJfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydF9iYXJfKTsKKworICByZWZsZWN0aW9uLT5BZGRTdHJpbmcobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksICIyMjQiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgIjIyNSIpOworCisgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICksIDMwMSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAzMDIpOworICByZWZsZWN0aW9uLT5BZGRVSW50MzIobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDMyIiAgKSwgMzAzKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDMwNCk7CisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50MzIiICApLCAzMDUpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDY0IiAgKSwgMzA2KTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDMwNyk7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDY0IiApLCAzMDgpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkMzIiKSwgMzA5KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDMxMCk7CisgIHJlZmxlY3Rpb24tPkFkZEZsb2F0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9mbG9hdCIgICApLCAzMTEpOworICByZWZsZWN0aW9uLT5BZGREb3VibGUobWVzc2FnZSwgRigicmVwZWF0ZWRfZG91YmxlIiAgKSwgMzEyKTsKKyAgcmVmbGVjdGlvbi0+QWRkQm9vbCAgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICksIGZhbHNlKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIgICksICIzMTUiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICksICIzMTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIHJlcGVhdGVkX2dyb3VwX2FfLCAzMTcpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDMxOCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCAzMTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8sIDMyMCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDMyNyk7CisKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwgIG5lc3RlZF9iYXpfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iKSwgZm9yZWlnbl9iYXpfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydF9iYXpfKTsKKworICByZWZsZWN0aW9uLT5BZGRTdHJpbmcobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksICIzMjQiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgIjMyNSIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfaW50MzIiICAgKSwgNDAxKTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfaW50NjQiICAgKSwgNDAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDMyIiAgKSwgNDAzKTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDY0KG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDY0IiAgKSwgNDA0KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDMyIiAgKSwgNDA1KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDY0IiAgKSwgNDA2KTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIEYoImRlZmF1bHRfZml4ZWQzMiIgKSwgNDA3KTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDY0KG1lc3NhZ2UsIEYoImRlZmF1bHRfZml4ZWQ2NCIgKSwgNDA4KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkMzIiKSwgNDA5KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkNjQiKSwgNDEwKTsKKyAgcmVmbGVjdGlvbi0+U2V0RmxvYXQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfZmxvYXQiICAgKSwgNDExKTsKKyAgcmVmbGVjdGlvbi0+U2V0RG91YmxlKG1lc3NhZ2UsIEYoImRlZmF1bHRfZG91YmxlIiAgKSwgNDEyKTsKKyAgcmVmbGVjdGlvbi0+U2V0Qm9vbCAgKG1lc3NhZ2UsIEYoImRlZmF1bHRfYm9vbCIgICAgKSwgZmFsc2UpOworICByZWZsZWN0aW9uLT5TZXRTdHJpbmcobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmciICApLCAiNDE1Iik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2J5dGVzIiAgICksICI0MTYiKTsKKworICByZWZsZWN0aW9uLT5TZXRFbnVtKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICksICBuZXN0ZWRfZm9vXyk7CisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigiZGVmYXVsdF9mb3JlaWduX2VudW0iKSwgZm9yZWlnbl9mb29fKTsKKyAgcmVmbGVjdGlvbi0+U2V0RW51bShtZXNzYWdlLCBGKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApLCAgaW1wb3J0X2Zvb18pOworCisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZ19waWVjZSIpLCAiNDI0Iik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSwgIjQyNSIpOworCisgIHJlZmxlY3Rpb24tPlNldFVJbnQzMihtZXNzYWdlLCBGKCJvbmVvZl91aW50MzIiICAgKSwgNjAxKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBGKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG5lc3RlZF9iXywgNjAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9uZW9mX3N0cmluZyIpLCAiNjAzIik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJvbmVvZl9ieXRlcyIgKSwgIjYwNCIpOworfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTZXRPbmVvZlZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQ2NCgKKyAgICAgIHN1Yl9tZXNzYWdlLAorICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5wb29sKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLnF1eF9pbnQiKSwKKyAgICAgIDEwMCk7CisKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIiksCisgICAgICAgICAgICAgICAgICAgICAgICAiMTAxIik7CisgIHJlZmxlY3Rpb24tPlNldEludDMyKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhel9pbnQiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgMTAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhel9zdHJpbmciKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICIxMDMiKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0T25lb2ZTZXRWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIHN0cmluZyBzY3JhdGNoOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZCgKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXpfaW50IikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhel9zdHJpbmciKSkpOworCisgIGNvbnN0IE1lc3NhZ2UqIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9FUSgxMDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgKnN1Yl9tZXNzYWdlLAorICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5wb29sKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLnF1eF9pbnQiKSkpOworCisgIEVYUEVDVF9FUSgiMTAxIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiMTAxIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpLCAmc2NyYXRjaCkpOworCisgIEVYUEVDVF9FUSgxMDIsIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXpfaW50IikpKTsKKworICBFWFBFQ1RfRVEoIjEwMyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmF6X3N0cmluZyIpKSk7CisgIEVYUEVDVF9FUSgiMTAzIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXpfc3RyaW5nIiksICZzY3JhdGNoKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OlNldFBhY2tlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX2ludDMyIiAgICksIDYwMSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSwgNjAyKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50MzIiICApLCA2MDMpOworICByZWZsZWN0aW9uLT5BZGRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX3VpbnQ2NCIgICksIDYwNCk7CisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSwgNjA1KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zaW50NjQiICApLCA2MDYpOworICByZWZsZWN0aW9uLT5BZGRVSW50MzIobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkMzIiICksIDYwNyk7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSwgNjA4KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQzMiIpLCA2MDkpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDY0IiksIDYxMCk7CisgIHJlZmxlY3Rpb24tPkFkZEZsb2F0IChtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSwgNjExKTsKKyAgcmVmbGVjdGlvbi0+QWRkRG91YmxlKG1lc3NhZ2UsIEYoInBhY2tlZF9kb3VibGUiICApLCA2MTIpOworICByZWZsZWN0aW9uLT5BZGRCb29sICAobWVzc2FnZSwgRigicGFja2VkX2Jvb2wiICAgICksIHRydWUpOworICByZWZsZWN0aW9uLT5BZGRFbnVtICAobWVzc2FnZSwgRigicGFja2VkX2VudW0iICAgICksIGZvcmVpZ25fYmFyXyk7CisKKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApLCA3MDEpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX2ludDY0IiAgICksIDcwMik7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQzMihtZXNzYWdlLCBGKCJwYWNrZWRfdWludDMyIiAgKSwgNzAzKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDY0KG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApLCA3MDQpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX3NpbnQzMiIgICksIDcwNSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDY0IiAgKSwgNzA2KTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApLCA3MDcpOworICByZWZsZWN0aW9uLT5BZGRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkNjQiICksIDcwOCk7CisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ZpeGVkMzIiKSwgNzA5KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpLCA3MTApOworICByZWZsZWN0aW9uLT5BZGRGbG9hdCAobWVzc2FnZSwgRigicGFja2VkX2Zsb2F0IiAgICksIDcxMSk7CisgIHJlZmxlY3Rpb24tPkFkZERvdWJsZShtZXNzYWdlLCBGKCJwYWNrZWRfZG91YmxlIiAgKSwgNzEyKTsKKyAgcmVmbGVjdGlvbi0+QWRkQm9vbCAgKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApLCBmYWxzZSk7CisgIHJlZmxlY3Rpb24tPkFkZEVudW0gIChtZXNzYWdlLCBGKCJwYWNrZWRfZW51bSIgICAgKSwgZm9yZWlnbl9iYXpfKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgLy8gV2UgaGF2ZSB0byBzcGxpdCB0aGlzIGludG8gdGhyZWUgZnVuY3Rpb24gb3RoZXJ3aXNlIGl0IGNyZWF0ZXMgYSBzdGFjaworICAvLyBmcmFtZSBzbyBsYXJnZSB0aGF0IGl0IHRyaWdnZXJzIGEgd2FybmluZy4KKyAgRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbjEobWVzc2FnZSk7CisgIEV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24yKG1lc3NhZ2UpOworICBFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uMyhtZXNzYWdlKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbjEoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIHN0cmluZyBzY3JhdGNoOworICBjb25zdCBNZXNzYWdlKiBzdWJfbWVzc2FnZTsKKworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQzMiIgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDMyIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF91aW50NjQiICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDMyIiApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9ib29sIiAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsZ3JvdXAiICAgICAgICAgICAgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiAgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIiAgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIgICAgICAgICApKSk7CisKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGdyb3VwX2FfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGZvcmVpZ25fY18pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2VfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbGF6eV9tZXNzYWdlIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfY29yZCIpKSk7CisKKyAgRVhQRUNUX0VRKDEwMSAgLCByZWZsZWN0aW9uLT5HZXRJbnQzMiAobWVzc2FnZSwgRigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRVEoMTAyICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQ2NCIgICApKSk7CisgIEVYUEVDVF9FUSgxMDMgICwgcmVmbGVjdGlvbi0+R2V0VUludDMyKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDEwNCAgLCByZWZsZWN0aW9uLT5HZXRVSW50NjQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRVEoMTA1ICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJvcHRpb25hbF9zaW50MzIiICApKSk7CisgIEVYUEVDVF9FUSgxMDYgICwgcmVmbGVjdGlvbi0+R2V0SW50NjQgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDEwNyAgLCByZWZsZWN0aW9uLT5HZXRVSW50MzIobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRVEoMTA4ICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDY0IiApKSk7CisgIEVYUEVDVF9FUSgxMDkgICwgcmVmbGVjdGlvbi0+R2V0SW50MzIgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDExMCAgLCByZWZsZWN0aW9uLT5HZXRJbnQ2NCAobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoMTExICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9mbG9hdCIgICApKSk7CisgIEVYUEVDVF9FUSgxMTIgICwgcmVmbGVjdGlvbi0+R2V0RG91YmxlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX1RSVUUoICAgICByZWZsZWN0aW9uLT5HZXRCb29sICAobWVzc2FnZSwgRigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRVEoIjExNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciICApKSk7CisgIEVYUEVDVF9FUSgiMTE2IiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoIjExNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciKSwgJnNjcmF0Y2gpKTsKKyAgRVhQRUNUX0VRKCIxMTYiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICksICZzY3JhdGNoKSk7CisKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIikpOworICBFWFBFQ1RfRVEoMTE3LCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIGdyb3VwX2FfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9FUSgxMTgsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpOworICBFWFBFQ1RfRVEoMTE5LCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIGZvcmVpZ25fY18pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX0VRKDEyMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9FUSgxMjYsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2VfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbGF6eV9tZXNzYWdlIikpOworICBFWFBFQ1RfRVEoMTI3LCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworCisgIEVYUEVDVF9FUSggbmVzdGVkX2Jhel8sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmF6XywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICBFWFBFQ1RfRVEoIGltcG9ydF9iYXpfLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX0VRKCIxMjQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCIxMjQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIiksICZzY3JhdGNoKSk7CisKKyAgRVhQRUNUX0VRKCIxMjUiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgRigib3B0aW9uYWxfY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiMTI1IiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2NvcmQiKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvbmVvZl9ieXRlcyIgKSkpOworICBFWFBFQ1RfRVEoIjYwNCIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJvbmVvZl9ieXRlcyIgICApKSk7CisKKyAgaWYgKGJhc2VfZGVzY3JpcHRvcl8tPm5hbWUoKSA9PSAiVGVzdEFsbFR5cGVzIikgeworICAgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvbmVvZl91aW50MzIiKSkpOworICAgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvbmVvZl9zdHJpbmciKSkpOworICB9IGVsc2UgeworICAgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9uZW9mX3VpbnQzMiIpKSk7CisgICAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib25lb2Zfc3RyaW5nIikpKTsKKyAgICBFWFBFQ1RfRVEoNjAxICAsIHJlZmxlY3Rpb24tPkdldFVJbnQzMihtZXNzYWdlLCBGKCJvbmVvZl91aW50MzIiKSkpOworICAgIEVYUEVDVF9FUSgiNjAzIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9uZW9mX3N0cmluZyIpKSk7CisgICAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgICBFWFBFQ1RfRVEoNjAyLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworICB9Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OkV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24yKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBzdHJpbmcgc2NyYXRjaDsKKyAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2U7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQ2NCIgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDMyIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50MzIiICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDY0IiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDY0IiApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkMzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mbG9hdCIgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZG91YmxlIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfYnl0ZXMiICAgKSkpOworCisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIgICAgICAgICAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiICAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiAgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgICAgKSkpOworCisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9jb3JkIikpKTsKKworICBFWFBFQ1RfRVEoMjAxICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICksIDApKTsKKyAgRVhQRUNUX0VRKDIwMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDMyIiAgKSwgMCkpOworICBFWFBFQ1RfRVEoMjA0ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDApKTsKKyAgRVhQRUNUX0VRKDIwNSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50MzIiICApLCAwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDY0IiAgKSwgMCkpOworICBFWFBFQ1RfRVEoMjA3ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDApKTsKKyAgRVhQRUNUX0VRKDIwOCAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQ2NChtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDY0IiApLCAwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkMzIiKSwgMCkpOworICBFWFBFQ1RfRVEoMjEwICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDApKTsKKyAgRVhQRUNUX0VRKDIxMSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEZsb2F0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9mbG9hdCIgICApLCAwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWREb3VibGUobWVzc2FnZSwgRigicmVwZWF0ZWRfZG91YmxlIiAgKSwgMCkpOworICBFWFBFQ1RfVFJVRSggICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICksIDApKTsKKyAgRVhQRUNUX0VRKCIyMTUiLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciICApLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmcobWVzc2FnZSwgRigicmVwZWF0ZWRfYnl0ZXMiICAgKSwgMCkpOworCisgIEVYUEVDVF9FUSgiMjE1IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nIiksIDAsICZzY3JhdGNoKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigicmVwZWF0ZWRfYnl0ZXMiKSwgMCwgJnNjcmF0Y2gpKTsKKworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpLCAwKTsKKyAgRVhQRUNUX0VRKDIxNywgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCByZXBlYXRlZF9ncm91cF9hXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMTgsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMTksIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMjAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2RfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMjcsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisKKyAgRVhQRUNUX0VRKCBuZXN0ZWRfYmFyXywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiApLDApKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmFyXywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIpLDApKTsKKyAgRVhQRUNUX0VRKCBpbXBvcnRfYmFyXywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ltcG9ydF9lbnVtIiApLDApKTsKKworICBFWFBFQ1RfRVEoIjIyNCIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpLCAwKSk7CisgIEVYUEVDVF9FUSgiMjI0IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMCwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjIyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgMCkpOworICBFWFBFQ1RfRVEoIjIyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSwgRigicmVwZWF0ZWRfY29yZCIpLCAwLCAmc2NyYXRjaCkpOworCisgIEVYUEVDVF9FUSgzMDEgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfaW50MzIiICAgKSwgMSkpOworICBFWFBFQ1RfRVEoMzAyICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDY0IiAgICksIDEpKTsKKyAgRVhQRUNUX0VRKDMwMyAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQzMihtZXNzYWdlLCBGKCJyZXBlYXRlZF91aW50MzIiICApLCAxKSk7CisgIEVYUEVDVF9FUSgzMDQgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDY0IiAgKSwgMSkpOworICBFWFBFQ1RfRVEoMzA1ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQzMiIgICksIDEpKTsKKyAgRVhQRUNUX0VRKDMwNiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50NjQiICApLCAxKSk7CisgIEVYUEVDVF9FUSgzMDcgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicmVwZWF0ZWRfZml4ZWQzMiIgKSwgMSkpOworICBFWFBFQ1RfRVEoMzA4ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDEpKTsKKyAgRVhQRUNUX0VRKDMwOSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zZml4ZWQzMiIpLCAxKSk7CisgIEVYUEVDVF9FUSgzMTAgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkNjQiKSwgMSkpOworICBFWFBFQ1RfRVEoMzExICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRmxvYXQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDEpKTsKKyAgRVhQRUNUX0VRKDMxMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZERvdWJsZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9kb3VibGUiICApLCAxKSk7CisgIEVYUEVDVF9GQUxTRSggICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRCb29sICAobWVzc2FnZSwgRigicmVwZWF0ZWRfYm9vbCIgICAgKSwgMSkpOworICBFWFBFQ1RfRVEoIjMxNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIgICksIDEpKTsKKyAgRVhQRUNUX0VRKCIzMTYiLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9ieXRlcyIgICApLCAxKSk7CisKKyAgRVhQRUNUX0VRKCIzMTUiLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAmc2NyYXRjaCkpOworICBFWFBFQ1RfRVEoIjMxNiIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgJnNjcmF0Y2gpKTsKKworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpLCAxKTsKKyAgRVhQRUNUX0VRKDMxNywgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCByZXBlYXRlZF9ncm91cF9hXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMTgsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMTksIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMjAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2RfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMjcsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisKKyAgRVhQRUNUX0VRKCBuZXN0ZWRfYmF6XywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiApLDEpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmF6XywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIpLDEpKTsKKyAgRVhQRUNUX0VRKCBpbXBvcnRfYmF6XywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ltcG9ydF9lbnVtIiApLDEpKTsKKworICBFWFBFQ1RfRVEoIjMyNCIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpLCAxKSk7CisgIEVYUEVDVF9FUSgiMzI0IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjMyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgMSkpOworICBFWFBFQ1RfRVEoIjMyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSwgRigicmVwZWF0ZWRfY29yZCIpLCAxLCAmc2NyYXRjaCkpOworfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uMygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgc3RyaW5nIHNjcmF0Y2g7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDMyIiAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9pbnQ2NCIgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDMyIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3VpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zaW50MzIiICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkMzIiICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9maXhlZDY0IiApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9mbG9hdCIgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2Jvb2wiICAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmciICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9mb3JlaWduX2VudW0iKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSkpOworCisgIEVYUEVDVF9FUSg0MDEgICwgcmVmbGVjdGlvbi0+R2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRVEoNDAyICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX0VRKDQwMyAgLCByZWZsZWN0aW9uLT5HZXRVSW50MzIobWVzc2FnZSwgRigiZGVmYXVsdF91aW50MzIiICApKSk7CisgIEVYUEVDVF9FUSg0MDQgICwgcmVmbGVjdGlvbi0+R2V0VUludDY0KG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRVEoNDA1ICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDQwNiAgLCByZWZsZWN0aW9uLT5HZXRJbnQ2NCAobWVzc2FnZSwgRigiZGVmYXVsdF9zaW50NjQiICApKSk7CisgIEVYUEVDVF9FUSg0MDcgICwgcmVmbGVjdGlvbi0+R2V0VUludDMyKG1lc3NhZ2UsIEYoImRlZmF1bHRfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRVEoNDA4ICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX0VRKDQwOSAgLCByZWZsZWN0aW9uLT5HZXRJbnQzMiAobWVzc2FnZSwgRigiZGVmYXVsdF9zZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUSg0MTAgICwgcmVmbGVjdGlvbi0+R2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoNDExICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX0VRKDQxMiAgLCByZWZsZWN0aW9uLT5HZXREb3VibGUobWVzc2FnZSwgRigiZGVmYXVsdF9kb3VibGUiICApKSk7CisgIEVYUEVDVF9GQUxTRSggICAgcmVmbGVjdGlvbi0+R2V0Qm9vbCAgKG1lc3NhZ2UsIEYoImRlZmF1bHRfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRVEoIjQxNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgRigiZGVmYXVsdF9ieXRlcyIgICApKSk7CisKKyAgRVhQRUNUX0VRKCI0MTUiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmciKSwgJnNjcmF0Y2gpKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9ieXRlcyIgKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIG5lc3RlZF9mb29fLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fZm9vXywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9FUSggaW1wb3J0X2Zvb18sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigiZGVmYXVsdF9pbXBvcnRfZW51bSIgKSkpOworCisgIEVYUEVDVF9FUSgiNDI0IiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCI0MjQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjQyNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIjQyNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSwgJnNjcmF0Y2gpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0UGFja2VkRmllbGRzU2V0VmlhUmVmbGVjdGlvbigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ludDY0IiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfdWludDMyIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX3NpbnQzMiIgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDY0IiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkNjQiICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfc2ZpeGVkMzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2Zsb2F0IiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZG91YmxlIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2VudW0iICAgICkpKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApLCAwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX2ludDY0IiAgICksIDApKTsKKyAgRVhQRUNUX0VRKDYwMyAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQzMihtZXNzYWdlLCBGKCJwYWNrZWRfdWludDMyIiAgKSwgMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApLCAwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX3NpbnQzMiIgICksIDApKTsKKyAgRVhQRUNUX0VRKDYwNiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDY0IiAgKSwgMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApLCAwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkNjQiICksIDApKTsKKyAgRVhQRUNUX0VRKDYwOSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ZpeGVkMzIiKSwgMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpLCAwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRGbG9hdCAobWVzc2FnZSwgRigicGFja2VkX2Zsb2F0IiAgICksIDApKTsKKyAgRVhQRUNUX0VRKDYxMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZERvdWJsZShtZXNzYWdlLCBGKCJwYWNrZWRfZG91YmxlIiAgKSwgMCkpOworICBFWFBFQ1RfVFJVRSggICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApLCAwKSk7CisgIEVYUEVDVF9FUShmb3JlaWduX2Jhcl8sCisgICAgICAgICAgICByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgRigicGFja2VkX2VudW0iKSwgMCkpOworCisgIEVYUEVDVF9FUSg3MDEgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX2ludDMyIiAgICksIDEpKTsKKyAgRVhQRUNUX0VRKDcwMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSwgMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50MzIiICApLCAxKSk7CisgIEVYUEVDVF9FUSg3MDQgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX3VpbnQ2NCIgICksIDEpKTsKKyAgRVhQRUNUX0VRKDcwNSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSwgMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zaW50NjQiICApLCAxKSk7CisgIEVYUEVDVF9FUSg3MDcgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkMzIiICksIDEpKTsKKyAgRVhQRUNUX0VRKDcwOCAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQ2NChtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSwgMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQzMiIpLCAxKSk7CisgIEVYUEVDVF9FUSg3MTAgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDY0IiksIDEpKTsKKyAgRVhQRUNUX0VRKDcxMSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEZsb2F0IChtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSwgMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRG91YmxlKG1lc3NhZ2UsIEYoInBhY2tlZF9kb3VibGUiICApLCAxKSk7CisgIEVYUEVDVF9GQUxTRSggICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRCb29sICAobWVzc2FnZSwgRigicGFja2VkX2Jvb2wiICAgICksIDEpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmF6XywKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRW51bShtZXNzYWdlLCBGKCJwYWNrZWRfZW51bSIpLCAxKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBzdHJpbmcgc2NyYXRjaDsKKyAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2U7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgaW5pdGlhbGx5IGJlIGZhbHNlIGZvciBhbGwgb3B0aW9uYWwgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfaW50NjQiICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDMyIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDMyIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQ2NCIgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZmxvYXQiICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIiAgICAgICAgICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIpKSk7CisKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X2VudW0iICkpKTsKKworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2NvcmQiKSkpOworCisgIC8vIE9wdGlvbmFsIGZpZWxkcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gemVybyBvciBzb21ldGhpbmcgbGlrZSBpdC4KKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRJbnQzMiAobWVzc2FnZSwgRigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQ2NCIgICApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0VUludDMyKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRVSW50NjQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJvcHRpb25hbF9zaW50MzIiICApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0SW50NjQgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRVSW50MzIobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDY0IiApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0SW50MzIgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRJbnQ2NCAobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9mbG9hdCIgICApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0RG91YmxlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICByZWZsZWN0aW9uLT5HZXRCb29sICAobWVzc2FnZSwgRigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRVEoIiIgICAsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciICApKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciKSwgJnNjcmF0Y2gpKTsKKyAgRVhQRUNUX0VRKCIiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICksICZzY3JhdGNoKSk7CisKKyAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxncm91cCIpKTsKKyAgRVhQRUNUX0ZBTFNFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgZ3JvdXBfYV8pKTsKKyAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgZ3JvdXBfYV8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX0ZBTFNFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpKTsKKyAgRVhQRUNUX0ZBTFNFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9GQUxTRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGltcG9ydF9kXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9GQUxTRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGltcG9ydF9lXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZV8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9GQUxTRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8pKTsKKworICAvLyBFbnVtcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBlbnVtLgorICBFWFBFQ1RfRVEoIG5lc3RlZF9mb29fLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9FUShmb3JlaWduX2Zvb18sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9lbnVtIikpKTsKKyAgRVhQRUNUX0VRKCBpbXBvcnRfZm9vXywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfZW51bSIgKSkpOworCisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpLCAmc2NyYXRjaCkpOworCisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9jb3JkIiksICZzY3JhdGNoKSk7CisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGFyZSBlbXB0eS4KKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQzMiIgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfaW50NjQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF91aW50NjQiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDMyIiAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDMyIiApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZml4ZWQ2NCIgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZmxvYXQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9ib29sIiAgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nIiAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkZ3JvdXAiICAgICAgICAgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfbGF6eV9tZXNzYWdlIiAgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X2VudW0iICAgICkpKTsKKworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfY29yZCIpKSk7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9pbnQzMiIgICApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDMyIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF91aW50NjQiICApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9maXhlZDMyIiApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9ib29sIiAgICApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfY29yZCIpKSk7CisKKyAgLy8gRmllbGRzIHdpdGggZGVmYXVsdHMgaGF2ZSB0aGVpciBkZWZhdWx0IHZhbHVlcyAoZHVoKS4KKyAgRVhQRUNUX0VRKCA0MSAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDMyIiAgICkpKTsKKyAgRVhQRUNUX0VRKCA0MiAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX0VRKCA0MyAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQzMihtZXNzYWdlLCBGKCJkZWZhdWx0X3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKCA0NCAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJkZWZhdWx0X3VpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKC00NSAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKCA0NiAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKCA0NyAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQzMihtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkMzIiICkpKTsKKyAgRVhQRUNUX0VRKCA0OCAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX0VRKCA0OSAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKC01MCAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX0VRKCA1MS41ICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX0VRKCA1MmUzICAsIHJlZmxlY3Rpb24tPkdldERvdWJsZShtZXNzYWdlLCBGKCJkZWZhdWx0X2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX1RSVUUoICAgICAgIHJlZmxlY3Rpb24tPkdldEJvb2wgIChtZXNzYWdlLCBGKCJkZWZhdWx0X2Jvb2wiICAgICkpKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX0VRKCJ3b3JsZCIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoImhlbGxvIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nIiksICZzY3JhdGNoKSk7CisgIEVYUEVDVF9FUSgid29ybGQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9ieXRlcyIgKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIG5lc3RlZF9iYXJfLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmFyXywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9FUSggaW1wb3J0X2Jhcl8sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigiZGVmYXVsdF9pbXBvcnRfZW51bSIgKSkpOworCisgIEVYUEVDVF9FUSgiYWJjIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCJhYmMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjEyMyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIjEyMyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSwgJnNjcmF0Y2gpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0UGFja2VkQ2xlYXJWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ludDMyIiAgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50MzIiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX3VpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9zaW50NjQiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkMzIiICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9kb3VibGUiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2Jvb2wiICAgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZW51bSIgICAgKSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6Ok1vZGlmeVJlcGVhdGVkRmllbGRzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworCisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICksIDEsIDUwMSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDY0IiAgICksIDEsIDUwMik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQzMiIgICksIDEsIDUwMyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDEsIDUwNCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQzMiIgICksIDEsIDUwNSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQ2NCIgICksIDEsIDUwNik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDEsIDUwNyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDEsIDUwOCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDMyIiksIDEsIDUwOSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDEsIDUxMCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRmxvYXQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDEsIDUxMSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRG91YmxlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2RvdWJsZSIgICksIDEsIDUxMik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICksIDEsIHRydWUpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciICApLCAxLCAiNTE1Iik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICksIDEsICI1MTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIHJlcGVhdGVkX2dyb3VwX2FfLCA1MTcpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDUxOCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCA1MTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8sIDUyMCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDUyNyk7CisKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiApLCAxLCAgbmVzdGVkX2Zvb18pOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgRigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiksIDEsIGZvcmVpZ25fZm9vXyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgMSwgIGltcG9ydF9mb29fKTsKKworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMSwgIjUyNCIpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9jb3JkIiksIDEsICI1MjUiKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6TW9kaWZ5UGFja2VkRmllbGRzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApLCAxLCA4MDEpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSwgMSwgODAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicGFja2VkX3VpbnQzMiIgICksIDEsIDgwMyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApLCAxLCA4MDQpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSwgMSwgODA1KTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX3NpbnQ2NCIgICksIDEsIDgwNik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApLCAxLCA4MDcpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFVJbnQ2NChtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSwgMSwgODA4KTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDMyIiksIDEsIDgwOSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpLCAxLCA4MTApOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEZsb2F0IChtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSwgMSwgODExKTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWREb3VibGUobWVzc2FnZSwgRigicGFja2VkX2RvdWJsZSIgICksIDEsIDgxMik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApLCAxLCB0cnVlKTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRFbnVtICAobWVzc2FnZSwgRigicGFja2VkX2VudW0iICAgICksIDEsIGZvcmVpZ25fZm9vXyk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OlJlbW92ZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gb3V0cHV0OworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKCptZXNzYWdlLCAmb3V0cHV0KTsKKyAgZm9yIChpbnQgaT0wOyBpPG91dHB1dC5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBvdXRwdXRbaV07CisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgY29udGludWU7CisKKyAgICByZWZsZWN0aW9uLT5SZW1vdmVMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgfQorfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpSZWxlYXNlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSwgYm9vbCBleHBlY3RfZXh0ZW5zaW9uc19ub3RudWxsKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGk9MDsgaTxvdXRwdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3V0cHV0W2ldOworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgY29udGludWU7CisKKyAgICBNZXNzYWdlKiByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBpZiAoIWZpZWxkLT5pc19leHRlbnNpb24oKSB8fCBleHBlY3RfZXh0ZW5zaW9uc19ub3RudWxsKSB7CisgICAgICBBU1NFUlRfVFJVRShyZWxlYXNlZCAhPSBOVUxMKSA8PCAiUmVsZWFzZUxhc3QgcmV0dXJuZWQgTlVMTCBmb3I6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpZWxkLT5uYW1lKCk7CisgICAgfQorICAgIGRlbGV0ZSByZWxlYXNlZDsKKyAgfQorfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTd2FwUmVwZWF0ZWRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGk9MDsgaTxvdXRwdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3V0cHV0W2ldOworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworCisgICAgcmVmbGVjdGlvbi0+U3dhcEVsZW1lbnRzKG1lc3NhZ2UsIGZpZWxkLCAwLCAxKTsKKyAgfQorfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjoKK1NldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMoKm1lc3NhZ2UsICZmaWVsZHMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBpZiAoIWZpZWxkLT5pc19vcHRpb25hbCgpIHx8CisgICAgICAgIGZpZWxkLT5jcHBfdHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSBjb250aW51ZTsKKworICAgIHJlZmxlY3Rpb24tPlNldEFsbG9jYXRlZE1lc3NhZ2UobWVzc2FnZSwgTlVMTCwgZmllbGQpOworICB9Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OgorU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBmcm9tX21lc3NhZ2UsCisgICAgTWVzc2FnZSogdG9fbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoZnJvbV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCksIHRvX21lc3NhZ2UtPkdldERlc2NyaXB0b3IoKSk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIGZyb21fcmVmbGVjdGlvbiA9IGZyb21fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBSZWZsZWN0aW9uKiB0b19yZWZsZWN0aW9uID0gdG9fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGZyb21fcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqZnJvbV9tZXNzYWdlLCAmZmllbGRzKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBmaWVsZHNbaV07CisgICAgaWYgKCFmaWVsZC0+aXNfb3B0aW9uYWwoKSB8fAorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgY29udGludWU7CisKKyAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9CisgICAgICAgIGZyb21fcmVmbGVjdGlvbi0+UmVsZWFzZU1lc3NhZ2UoZnJvbV9tZXNzYWdlLCBmaWVsZCk7CisgICAgdG9fcmVmbGVjdGlvbi0+U2V0QWxsb2NhdGVkTWVzc2FnZSh0b19tZXNzYWdlLCBzdWJfbWVzc2FnZSwgZmllbGQpOworICB9Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6Ok1lc3NhZ2VSZWxlYXNlU3RhdGUgZXhwZWN0ZWRfcmVsZWFzZV9zdGF0ZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHN0YXRpYyBjb25zdCBjaGFyKiBmaWVsZHNbXSA9IHsKKyAgICAib3B0aW9uYWxncm91cCIsCisgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiwKKyAgICAib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIiwKKyAgICAib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UiLAorICB9OworICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoZmllbGRzKTsgaSsrKSB7CisgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKCptZXNzYWdlLCBGKGZpZWxkc1tpXSkpOworICAgIE1lc3NhZ2UqIHJlbGVhc2VkID0gcmVmbGVjdGlvbi0+UmVsZWFzZU1lc3NhZ2UobWVzc2FnZSwgRihmaWVsZHNbaV0pKTsKKyAgICBzd2l0Y2ggKGV4cGVjdGVkX3JlbGVhc2Vfc3RhdGUpIHsKKyAgICAgIGNhc2UgSVNfTlVMTDoKKyAgICAgICAgRVhQRUNUX1RSVUUocmVsZWFzZWQgPT0gTlVMTCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOT1RfTlVMTDoKKyAgICAgICAgRVhQRUNUX1RSVUUocmVsZWFzZWQgIT0gTlVMTCk7CisgICAgICAgIEVYUEVDVF9FUSgmc3ViX21lc3NhZ2UsIHJlbGVhc2VkKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIENBTl9CRV9OVUxMOgorICAgICAgICBicmVhazsKKyAgICB9CisgICAgZGVsZXRlIHJlbGVhc2VkOworICAgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZCgqbWVzc2FnZSwgRihmaWVsZHNbaV0pKSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDQ5YzAwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaApAQCAtMCwwICsxLDIxNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxzdGFjaz4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgdW5pdHRlc3QgPSA6OnByb3RvYnVmX3VuaXR0ZXN0OworbmFtZXNwYWNlIHVuaXR0ZXN0X2ltcG9ydCA9IHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworY2xhc3MgVGVzdFV0aWwgeworIHB1YmxpYzoKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICBzdGF0aWMgdm9pZCBTZXRBbGxGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldE9wdGlvbmFsRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBBZGRSZXBlYXRlZEZpZWxkczEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEFkZFJlcGVhdGVkRmllbGRzMih1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0RGVmYXVsdEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0T25lb2ZGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldEFsbEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0T25lb2ZGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0QWxsRmllbGRzQW5kRXh0ZW5zaW9ucyh1bml0dGVzdDo6VGVzdEZpZWxkT3JkZXJpbmdzKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0UGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXRQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldFVucGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldE9uZW9mMSh1bml0dGVzdDo6VGVzdE9uZW9mMiogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldE9uZW9mMih1bml0dGVzdDo6VGVzdE9uZW9mMiogbWVzc2FnZSk7CisKKyAgLy8gVXNlIHRoZSByZXBlYXRlZCB2ZXJzaW9ucyBvZiB0aGUgc2V0XyooKSBhY2Nlc3NvcnMgdG8gbW9kaWZ5IGFsbCB0aGUKKyAgLy8gcmVwZWF0ZWQgZmllbGRzIG9mIHRoZSBtZXNzc2FnZSAod2hpY2ggc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuCisgIC8vIGluaXRpYWxpemVkIHdpdGggU2V0KkZpZWxkcygpKS4gIFNldCpGaWVsZHMoKSBpdHNlbGYgb25seSB0ZXN0cworICAvLyB0aGUgYWRkXyooKSBhY2Nlc3NvcnMuCisgIHN0YXRpYyB2b2lkIE1vZGlmeVJlcGVhdGVkRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBNb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgTW9kaWZ5UGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBNb2RpZnlQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0KkZpZWxkcygpIGlzIGNhbGxlZC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0QWxsRmllbGRzU2V0KGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RBbGxFeHRlbnNpb25zU2V0KAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRmllbGRzU2V0KGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0VW5wYWNrZWRGaWVsZHNTZXQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RVbnBhY2tlZEV4dGVuc2lvbnNTZXQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdFVucGFja2VkRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdE9uZW9mU2V0MShjb25zdCB1bml0dGVzdDo6VGVzdE9uZW9mMiYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdE9uZW9mU2V0Mihjb25zdCB1bml0dGVzdDo6VGVzdE9uZW9mMiYgbWVzc2FnZSk7CisKKyAgLy8gRXhwZWN0IHRoYXQgdGhlIG1lc3NhZ2UgaXMgbW9kaWZpZWQgYXMgd291bGQgYmUgZXhwZWN0ZWQgZnJvbQorICAvLyBNb2RpZnkqRmllbGRzKCkuCisgIHN0YXRpYyB2b2lkIEV4cGVjdFJlcGVhdGVkRmllbGRzTW9kaWZpZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRGaWVsZHNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRFeHRlbnNpb25zTW9kaWZpZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIHRoZWlyIGRlZmF1bHQgdmFsdWVzLgorICBzdGF0aWMgdm9pZCBFeHBlY3RDbGVhcihjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0RXh0ZW5zaW9uc0NsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRFeHRlbnNpb25zQ2xlYXIoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RPbmVvZkNsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IHRoZSBwYXNzZWQtaW4gc2VyaWFsaXphdGlvbiBpcyB0aGUgY2Fub25pY2FsIHNlcmlhbGl6YXRpb24gd2UKKyAgLy8gZXhwZWN0IGZvciBhIFRlc3RGaWVsZE9yZGVyaW5ncyBtZXNzYWdlIGZpbGxlZCBpbiBieQorICAvLyBTZXRBbGxGaWVsZHNBbmRFeHRlbnNpb25zKCkuCisgIHN0YXRpYyB2b2lkIEV4cGVjdEFsbEZpZWxkc0FuZEV4dGVuc2lvbnNJbk9yZGVyKGNvbnN0IHN0cmluZyYgc2VyaWFsaXplZCk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgcmVwZWF0ZWQgZmllbGRzIGhhdmUgaGFkIHRoZWlyIGxhc3QgZWxlbWVudHMgcmVtb3ZlZC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0TGFzdFJlcGVhdGVkc1JlbW92ZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0TGFzdFJlcGVhdGVkRXh0ZW5zaW9uc1JlbW92ZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RMYXN0UmVwZWF0ZWRzUmVsZWFzZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0TGFzdFJlcGVhdGVkRXh0ZW5zaW9uc1JlbGVhc2VkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCByZXBlYXRlZCBmaWVsZHMgaGF2ZSBoYWQgdGhlaXIgZmlyc3QgYW5kIGxhc3QgZWxlbWVudHMKKyAgLy8gc3dhcHBlZC4KKyAgc3RhdGljIHZvaWQgRXhwZWN0UmVwZWF0ZWRzU3dhcHBlZChjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UmVwZWF0ZWRFeHRlbnNpb25zU3dhcHBlZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisKKyAgc3RhdGljIHZvaWQgRXhwZWN0QXRNb3N0T25lRmllbGRTZXRJbk9uZW9mKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgJm1lc3NhZ2UpOworCisgIC8vIExpa2UgYWJvdmUsIGJ1dCB1c2UgdGhlIHJlZmxlY3Rpb24gaW50ZXJmYWNlLgorICBjbGFzcyBSZWZsZWN0aW9uVGVzdGVyIHsKKyAgIHB1YmxpYzoKKyAgICAvLyBiYXNlX2Rlc2NyaXB0b3IgbXVzdCBiZSBhIGRlc2NyaXB0b3IgZm9yIFRlc3RBbGxUeXBlcyBvcgorICAgIC8vIFRlc3RBbGxFeHRlbnNpb25zLiAgSW4gdGhlIGZvcm1lciBjYXNlLCBSZWZsZWN0aW9uVGVzdGVyIGZldGNoZXMgZnJvbQorICAgIC8vIGl0IHRoZSBGaWVsZERlc2NyaXB0b3JzIG5lZWRlZCB0byB1c2UgdGhlIHJlZmxlY3Rpb24gaW50ZXJmYWNlLiAgSW4KKyAgICAvLyB0aGUgbGF0dGVyIGNhc2UsIFJlZmxlY3Rpb25UZXN0ZXIgc2VhcmNoZXMgZm9yIGV4dGVuc2lvbiBmaWVsZHMgaW4KKyAgICAvLyBpdHMgZmlsZS4KKyAgICBleHBsaWNpdCBSZWZsZWN0aW9uVGVzdGVyKGNvbnN0IERlc2NyaXB0b3IqIGJhc2VfZGVzY3JpcHRvcik7CisKKyAgICB2b2lkIFNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBNb2RpZnlSZXBlYXRlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworICAgIHZvaWQgRXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgICAgdm9pZCBTZXRQYWNrZWRGaWVsZHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHZvaWQgTW9kaWZ5UGFja2VkRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIEV4cGVjdFBhY2tlZEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgICAgdm9pZCBFeHBlY3RQYWNrZWRDbGVhclZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgICB2b2lkIFJlbW92ZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHZvaWQgUmVsZWFzZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKAorICAgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBib29sIGV4cGVjdF9leHRlbnNpb25zX25vdG51bGwpOworICAgIHZvaWQgU3dhcFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBTZXRBbGxvY2F0ZWRPcHRpb25hbE1lc3NhZ2VGaWVsZHNUb051bGxWaWFSZWZsZWN0aW9uKAorICAgICAgICBNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICBzdGF0aWMgdm9pZCBTZXRBbGxvY2F0ZWRPcHRpb25hbE1lc3NhZ2VGaWVsZHNUb01lc3NhZ2VWaWFSZWZsZWN0aW9uKAorICAgICAgICBNZXNzYWdlKiBmcm9tX21lc3NhZ2UsCisgICAgICAgIE1lc3NhZ2UqIHRvX21lc3NhZ2UpOworCisgICAgZW51bSBNZXNzYWdlUmVsZWFzZVN0YXRlIHsKKyAgICAgIElTX05VTEwsCisgICAgICBDQU5fQkVfTlVMTCwKKyAgICAgIE5PVF9OVUxMLAorICAgIH07CisgICAgdm9pZCBFeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICAgTWVzc2FnZSogbWVzc2FnZSwgTWVzc2FnZVJlbGVhc2VTdGF0ZSBleHBlY3RlZF9yZWxlYXNlX3N0YXRlKTsKKworICAgIC8vIFNldCBhbmQgY2hlY2sgZnVuY3Rpb25zIGZvciBUZXN0T25lb2YyIG1lc3NhZ2VzLiBObyBuZWVkIHRvIGNvbnN0cnVjdAorICAgIC8vIHRoZSBSZWZsZWN0aW9uVGVzdGVyIGJ5IFRlc3RBbGxUeXBlcyBub3IgVGVzdEFsbEV4dGVuc2lvbnMuCisgICAgc3RhdGljIHZvaWQgU2V0T25lb2ZWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHN0YXRpYyB2b2lkIEV4cGVjdE9uZW9mU2V0VmlhUmVmbGVjdGlvbihjb25zdCBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAgcHJpdmF0ZToKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEYoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICAgIGNvbnN0IERlc2NyaXB0b3IqIGJhc2VfZGVzY3JpcHRvcl87CisKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGdyb3VwX2FfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVwZWF0ZWRfZ3JvdXBfYV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBuZXN0ZWRfYl87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmb3JlaWduX2NfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogaW1wb3J0X2RfOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogaW1wb3J0X2VfOworCisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogbmVzdGVkX2Zvb187CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogbmVzdGVkX2Jhcl87CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogbmVzdGVkX2Jhel87CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZm9yZWlnbl9mb29fOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGZvcmVpZ25fYmFyXzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBmb3JlaWduX2Jhel87CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogaW1wb3J0X2Zvb187CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogaW1wb3J0X2Jhcl87CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogaW1wb3J0X2Jhel87CisKKyAgICAvLyBXZSBoYXZlIHRvIHNwbGl0IHRoaXMgaW50byB0aHJlZSBmdW5jdGlvbiBvdGhlcndpc2UgaXQgY3JlYXRlcyBhIHN0YWNrCisgICAgLy8gZnJhbWUgc28gbGFyZ2UgdGhhdCBpdCB0cmlnZ2VycyBhIHdhcm5pbmcuCisgICAgdm9pZCBFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uMShjb25zdCBNZXNzYWdlJiBtZXNzYWdlKTsKKyAgICB2b2lkIEV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24yKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworICAgIHZvaWQgRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbjMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVmbGVjdGlvblRlc3Rlcik7CisgIH07CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGVzdFV0aWwpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1RFU1RfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4ZWNhMGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmNjCkBAIC0wLDAgKzEsMTU4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisKKyNkZWZpbmUgRVhQRUNUX1RSVUUgR09PR0xFX0NIRUNLCisjZGVmaW5lIEFTU0VSVF9UUlVFIEdPT0dMRV9DSEVDSworI2RlZmluZSBFWFBFQ1RfRkFMU0UoQ09ORCkgR09PR0xFX0NIRUNLKCEoQ09ORCkpCisjZGVmaW5lIEVYUEVDVF9FUSBHT09HTEVfQ0hFQ0tfRVEKKyNkZWZpbmUgQVNTRVJUX0VRIEdPT0dMRV9DSEVDS19FUQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpTZXRBbGxGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2ludDMyICAgKDEwMSk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbnQ2NCAgICgxMDIpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfdWludDMyICAoMTAzKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3VpbnQ2NCAgKDEwNCk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9zaW50MzIgICgxMDUpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfc2ludDY0ICAoMTA2KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2ZpeGVkMzIgKDEwNyk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9maXhlZDY0ICgxMDgpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfc2ZpeGVkMzIoMTA5KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NmaXhlZDY0KDExMCk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9mbG9hdCAgICgxMTEpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZG91YmxlICAoMTEyKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2Jvb2wgICAgKHRydWUpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfc3RyaW5nICAoIjExNSIpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfYnl0ZXMgICAoIjExNiIpOworCisgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxncm91cCAgICAgICAgICAgICAgICAgKCktPnNldF9hKDExNyk7CisgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgICAgICAgKCktPnNldF9iYigxMTgpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpLT5zZXRfYygxMTkpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICAgICAgICgpLT5zZXRfZCgxMjApOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSgpLT5zZXRfZSgxMjYpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpLT5zZXRfYmIoMTI3KTsKKworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0gKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVogKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWiAgICAgICk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVopOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50MzIgICAoMjAxKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ludDY0ICAgKDIwMik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF91aW50MzIgICgyMDMpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDY0ICAoMjA0KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NpbnQzMiAgKDIwNSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50NjQgICgyMDYpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZml4ZWQzMiAoMjA3KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZpeGVkNjQgKDIwOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zZml4ZWQzMigyMDkpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkNjQoMjEwKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2Zsb2F0ICAgKDIxMSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9kb3VibGUgICgyMTIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfYm9vbCAgICAodHJ1ZSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zdHJpbmcgICgiMjE1Iik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9ieXRlcyAgICgiMjE2Iik7CisKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkZ3JvdXAgICAgICAgICAgICgpLT5zZXRfYSgyMTcpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKCktPnNldF9iYigyMTgpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKDIxOSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoKS0+c2V0X2QoMjIwKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgpLT5zZXRfYmIoMjI3KTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0gKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiAgICAgICk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVIpOworCisKKyAgLy8gQWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50MzIgICAoMzAxKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ludDY0ICAgKDMwMik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF91aW50MzIgICgzMDMpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDY0ICAoMzA0KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NpbnQzMiAgKDMwNSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50NjQgICgzMDYpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZml4ZWQzMiAoMzA3KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZpeGVkNjQgKDMwOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zZml4ZWQzMigzMDkpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkNjQoMzEwKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2Zsb2F0ICAgKDMxMSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9kb3VibGUgICgzMTIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfYm9vbCAgICAoZmFsc2UpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc3RyaW5nICAoIjMxNSIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfYnl0ZXMgICAoIjMxNiIpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZGdyb3VwICAgICAgICAgICAoKS0+c2V0X2EoMzE3KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgpLT5zZXRfYmIoMzE4KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgpLT5zZXRfYygzMTkpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKCktPnNldF9kKDMyMCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoKS0+c2V0X2JiKDMyNyk7CisKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtICh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX2VudW0odW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFaKTsKKworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfaW50MzIgICAoNDAxKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfaW50NjQgICAoNDAyKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfdWludDMyICAoNDAzKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfdWludDY0ICAoNDA0KTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc2ludDMyICAoNDA1KTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc2ludDY0ICAoNDA2KTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfZml4ZWQzMiAoNDA3KTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfZml4ZWQ2NCAoNDA4KTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc2ZpeGVkMzIoNDA5KTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc2ZpeGVkNjQoNDEwKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfZmxvYXQgICAoNDExKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfZG91YmxlICAoNDEyKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfYm9vbCAgICAoZmFsc2UpOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9zdHJpbmcgICgiNDE1Iik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2J5dGVzICAgKCI0MTYiKTsKKworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9uZXN0ZWRfZW51bSAodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyApOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9mb3JlaWduX2VudW0odW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08gICAgICApOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08pOworCisKKyAgbWVzc2FnZS0+c2V0X29uZW9mX3VpbnQzMig2MDEpOworICBtZXNzYWdlLT5tdXRhYmxlX29uZW9mX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig2MDIpOworICBtZXNzYWdlLT5zZXRfb25lb2Zfc3RyaW5nKCI2MDMiKTsKKyAgbWVzc2FnZS0+c2V0X29uZW9mX2J5dGVzKCI2MDQiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6TW9kaWZ5UmVwZWF0ZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ludDMyICAgKDEsIDUwMSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9pbnQ2NCAgICgxLCA1MDIpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfdWludDMyICAoMSwgNTAzKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3VpbnQ2NCAgKDEsIDUwNCk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zaW50MzIgICgxLCA1MDUpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfc2ludDY0ICAoMSwgNTA2KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ZpeGVkMzIgKDEsIDUwNyk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9maXhlZDY0ICgxLCA1MDgpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfc2ZpeGVkMzIoMSwgNTA5KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3NmaXhlZDY0KDEsIDUxMCk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9mbG9hdCAgICgxLCA1MTEpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZG91YmxlICAoMSwgNTEyKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2Jvb2wgICAgKDEsIHRydWUpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfc3RyaW5nICAoMSwgIjUxNSIpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfYnl0ZXMgICAoMSwgIjUxNiIpOworCisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRncm91cCAgICAgICAgICAgKDEpLT5zZXRfYSg1MTcpOworICBtZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgxKS0+c2V0X2JiKDUxOCk7CisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDEpLT5zZXRfYyg1MTkpOworICBtZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgxKS0+c2V0X2QoNTIwKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoMSktPnNldF9iYig1MjcpOworCisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyApOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEsIHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ltcG9ydF9lbnVtICgxLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTyk7CisKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRmllbGRzU2V0KAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ludDMyICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDY0KCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2Jvb2wgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxncm91cCAgICAgICAgICAgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLmhhc19hKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLmhhc19iYigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS5oYXNfYygpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS5oYXNfZCgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS5oYXNfZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworCisgIEVYUEVDVF9FUSgxMDEgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDEwMiAgLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoMTAzICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSgxMDQgICwgbWVzc2FnZS5vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDEwNSAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMTA2ICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgxMDcgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDEwOCAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoMTA5ICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgxMTAgICwgbWVzc2FnZS5vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDExMSAgLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoMTEyICAsIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCIxMTUiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIjExNiIsIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0VRKDExNywgbWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKS5hKCkpOworICBFWFBFQ1RfRVEoMTE4LCBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLmJiKCkpOworICBFWFBFQ1RfRVEoMTE5LCBtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpLmMoKSk7CisgIEVYUEVDVF9FUSgxMjAsIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkuZCgpKTsKKyAgRVhQRUNUX0VRKDEyNiwgbWVzc2FnZS5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS5lKCkpOworICBFWFBFQ1RfRVEoMTI3LCBtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWiAgICAgICwgbWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWiwgbWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDIwMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0ICAgKDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDIwNSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDIwOCAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjQgKDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDIxMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0ICAgKDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKCIyMTUiLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyAgKDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzICAgKDApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXAgICAgICAgICAgICgwKS5hKCkpOworICBFWFBFQ1RfRVEoMjE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDIyNywgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoMCkuYmIoKSk7CisKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBUiAsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBUiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bSAoMCkpOworCisgIEVYUEVDVF9FUSgzMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSgzMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgxKSk7CisgIEVYUEVDVF9FUSgzMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSgzMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSgzMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSgzMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSgzMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSgzMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgxKSk7CisgIEVYUEVDVF9FUSgzMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigxKSk7CisgIEVYUEVDVF9FUSgzMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSgzMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgxKSk7CisgIEVYUEVDVF9FUSgzMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgxKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSgiMzE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgxKSk7CisgIEVYUEVDVF9FUSgiMzE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgxKSk7CisKKyAgRVhQRUNUX0VRKDMxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDMxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMSkuYmIoKSk7CisgIEVYUEVDVF9FUSgzMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDEpLmMoKSk7CisgIEVYUEVDVF9FUSgzMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLmQoKSk7CisgIEVYUEVDVF9FUSgzMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDEpLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFaLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgxKSk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfaW50MzIgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfdWludDMyICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfdWludDY0ICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZml4ZWQzMiAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZG91YmxlICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfYm9vbCAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZGVmYXVsdF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ltcG9ydF9lbnVtICgpKTsKKworCisgIEVYUEVDVF9FUSg0MDEgICwgbWVzc2FnZS5kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfRVEoNDAyICAsIG1lc3NhZ2UuZGVmYXVsdF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX0VRKDQwMyAgLCBtZXNzYWdlLmRlZmF1bHRfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSg0MDQgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoNDA1ICAsIG1lc3NhZ2UuZGVmYXVsdF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX0VRKDQwNiAgLCBtZXNzYWdlLmRlZmF1bHRfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSg0MDcgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfRVEoNDA4ICAsIG1lc3NhZ2UuZGVmYXVsdF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX0VRKDQwOSAgLCBtZXNzYWdlLmRlZmF1bHRfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSg0MTAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRVEoNDExICAsIG1lc3NhZ2UuZGVmYXVsdF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX0VRKDQxMiAgLCBtZXNzYWdlLmRlZmF1bHRfZG91YmxlICAoKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfRVEoIjQxNSIsIG1lc3NhZ2UuZGVmYXVsdF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCBtZXNzYWdlLmRlZmF1bHRfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gLCBtZXNzYWdlLmRlZmF1bHRfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08gICAgICAsIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTywgbWVzc2FnZS5kZWZhdWx0X2ltcG9ydF9lbnVtICgpKTsKKworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl91aW50MzIgICAgICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2Zfc3RyaW5nICAgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29uZW9mX2J5dGVzICAgICAgICAgICgpKTsKKworICBFWFBFQ1RfRVEoIjYwNCIsIG1lc3NhZ2Uub25lb2ZfYnl0ZXMoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlJiBtZXNzYWdlKSB7CisgIC8vIGhhc19ibGFoKCkgc2hvdWxkIGluaXRpYWxseSBiZSBmYWxzZSBmb3IgYWxsIG9wdGlvbmFsIGZpZWxkcy4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ludDMyICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW50NjQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF91aW50MzIgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ludDMyICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zaW50NjQgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zZml4ZWQzMigpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9kb3VibGUgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2Jvb2wgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9ieXRlcyAgICgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxncm91cCAgICAgICAgICAgICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlICAgICAgICAgKCkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHplcm8gb3Igc29tZXRoaW5nIGxpa2UgaXQuCisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIiIgICAsIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLmhhc19hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5oYXNfYmIoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpLmhhc19jKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS5oYXNfZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuaGFzX2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpLmhhc19iYigpKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAoKS5hKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAoKS5iYigpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkuYygpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgKCkuZCgpKTsKKworICAvLyBFbnVtcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBlbnVtLgorICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08gICAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08sIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X2VudW0gKCkpOworCisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGFyZSBlbXB0eS4KKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0X3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0X3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbF9zaXplICAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXNfc2l6ZSAgICgpKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZGdyb3VwX3NpemUgICAgICAgICAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUgICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW1fc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW1fc2l6ZSAgICAoKSk7CisKKworICAvLyBoYXNfYmxhaCgpIHNob3VsZCBhbHNvIGJlIGZhbHNlIGZvciBhbGwgZGVmYXVsdCBmaWVsZHMuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfdWludDMyICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZG91YmxlICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2ltcG9ydF9lbnVtICgpKTsKKworCisgIC8vIEZpZWxkcyB3aXRoIGRlZmF1bHRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMgKGR1aCkuCisgIEVYUEVDVF9FUSggNDEgICAgLCBtZXNzYWdlLmRlZmF1bHRfaW50MzIgICAoKSk7CisgIEVYUEVDVF9FUSggNDIgICAgLCBtZXNzYWdlLmRlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9FUSggNDMgICAgLCBtZXNzYWdlLmRlZmF1bHRfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSggNDQgICAgLCBtZXNzYWdlLmRlZmF1bHRfdWludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgtNDUgICAgLCBtZXNzYWdlLmRlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9FUSggNDYgICAgLCBtZXNzYWdlLmRlZmF1bHRfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSggNDcgICAgLCBtZXNzYWdlLmRlZmF1bHRfZml4ZWQzMiAoKSk7CisgIEVYUEVDVF9FUSggNDggICAgLCBtZXNzYWdlLmRlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9FUSggNDkgICAgLCBtZXNzYWdlLmRlZmF1bHRfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgtNTAgICAgLCBtZXNzYWdlLmRlZmF1bHRfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9FUSggNTEuNSAgLCBtZXNzYWdlLmRlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9FUSggNTJlMyAgLCBtZXNzYWdlLmRlZmF1bHRfZG91YmxlICAoKSk7CisgIEVYUEVDVF9FUSh0cnVlICAgLCBtZXNzYWdlLmRlZmF1bHRfYm9vbCAgICAoKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBtZXNzYWdlLmRlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9FUSgid29ybGQiLCBtZXNzYWdlLmRlZmF1bHRfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgLCBtZXNzYWdlLmRlZmF1bHRfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIgICAgICAsIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBUiwgbWVzc2FnZS5kZWZhdWx0X2ltcG9ydF9lbnVtICgpKTsKKworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl91aW50MzIgICAgICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2Zfc3RyaW5nICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9ieXRlcyAgICAgICAgICgpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSYgbWVzc2FnZSkgeworICAvLyBNb2RpZnlSZXBlYXRlZEZpZWxkcyBvbmx5IHNldHMgdGhlIHNlY29uZCByZXBlYXRlZCBlbGVtZW50IG9mIGVhY2gKKyAgLy8gZmllbGQuICBJbiBhZGRpdGlvbiB0byB2ZXJpZnlpbmcgdGhpcywgd2UgYWxzbyB2ZXJpZnkgdGhhdCB0aGUgZmlyc3QKKyAgLy8gZWxlbWVudCBhbmQgc2l6ZSB3ZXJlICpub3QqIG1vZGlmaWVkLgorICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NF9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0X3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMl9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NF9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdF9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9ib29sX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlc19zaXplICAgKCkpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXBfc2l6ZSAgICAgICAgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2Vfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bV9zaXplICAgICgpKTsKKworCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgwKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIgICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFSLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7CisKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDUwMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwMyAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNCAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNiAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNyAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzIgKDEpKTsKKyAgRVhQRUNUX0VRKDUwOCAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjQgKDEpKTsKKyAgRVhQRUNUX0VRKDUwOSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDUxMCAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0KDEpKTsKKyAgRVhQRUNUX0VRKDUxMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUxMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2wgICAgKDEpKTsKKyAgRVhQRUNUX0VRKCI1MTUiLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyAgKDEpKTsKKyAgRVhQRUNUX0VRKCI1MTYiLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzICAgKDEpKTsKKworICBFWFBFQ1RfRVEoNTE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXAgICAgICAgICAgICgxKS5hKCkpOworICBFWFBFQ1RfRVEoNTE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgxKS5iYigpKTsKKyAgRVhQRUNUX0VRKDUxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMSkuYygpKTsKKyAgRVhQRUNUX0VRKDUyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMSkuZCgpKTsKKyAgRVhQRUNUX0VRKDUyNywgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoMSkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08sIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDEpKTsKKworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpTZXRQYWNrZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQzMiAgICg2MDEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2ludDY0ICAgKDYwMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDMyICAoNjAzKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF91aW50NjQgICg2MDQpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQzMiAgKDYwNSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ludDY0ICAoNjA2KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDMyICg2MDcpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2ZpeGVkNjQgKDYwOCk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkMzIoNjA5KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zZml4ZWQ2NCg2MTApOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2Zsb2F0ICAgKDYxMSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZG91YmxlICAoNjEyKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9ib29sICAgICh0cnVlKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9lbnVtICAgICh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUik7CisgIC8vIGFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZAorICBtZXNzYWdlLT5hZGRfcGFja2VkX2ludDMyICAgKDcwMSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfaW50NjQgICAoNzAyKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF91aW50MzIgICg3MDMpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3VpbnQ2NCAgKDcwNCk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ludDMyICAoNzA1KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zaW50NjQgICg3MDYpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2ZpeGVkMzIgKDcwNyk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZml4ZWQ2NCAoNzA4KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zZml4ZWQzMig3MDkpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NmaXhlZDY0KDcxMCk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZmxvYXQgICAoNzExKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9kb3VibGUgICg3MTIpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9lbnVtICAgICh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6Ok1vZGlmeVBhY2tlZEZpZWxkcyh1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzTGl0ZSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ludDMyICAgKDEsIDgwMSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfaW50NjQgICAoMSwgODAyKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF91aW50MzIgICgxLCA4MDMpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX3VpbnQ2NCAgKDEsIDgwNCk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ludDMyICAoMSwgODA1KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9zaW50NjQgICgxLCA4MDYpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ZpeGVkMzIgKDEsIDgwNyk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfZml4ZWQ2NCAoMSwgODA4KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9zZml4ZWQzMigxLCA4MDkpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX3NmaXhlZDY0KDEsIDgxMCk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfZmxvYXQgICAoMSwgODExKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9kb3VibGUgICgxLCA4MTIpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2Jvb2wgICAgKDEsIHRydWUpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2VudW0gICAgKDEsIHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzU2V0KAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UucGFja2VkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLnBhY2tlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5wYWNrZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UucGFja2VkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLnBhY2tlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5wYWNrZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLnBhY2tlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5wYWNrZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UucGFja2VkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSLCBtZXNzYWdlLnBhY2tlZF9lbnVtKDApKTsKKworICBFWFBFQ1RfRVEoNzAxICAsIG1lc3NhZ2UucGFja2VkX2ludDMyICAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwMiAgLCBtZXNzYWdlLnBhY2tlZF9pbnQ2NCAgICgxKSk7CisgIEVYUEVDVF9FUSg3MDMgICwgbWVzc2FnZS5wYWNrZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA0ICAsIG1lc3NhZ2UucGFja2VkX3VpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNSAgLCBtZXNzYWdlLnBhY2tlZF9zaW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSg3MDYgICwgbWVzc2FnZS5wYWNrZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoNzA3ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkMzIgKDEpKTsKKyAgRVhQRUNUX0VRKDcwOCAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDY0ICgxKSk7CisgIEVYUEVDVF9FUSg3MDkgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoNzEwICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0KDEpKTsKKyAgRVhQRUNUX0VRKDcxMSAgLCBtZXNzYWdlLnBhY2tlZF9mbG9hdCAgICgxKSk7CisgIEVYUEVDVF9FUSg3MTIgICwgbWVzc2FnZS5wYWNrZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UucGFja2VkX2Jvb2wgICAgKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaLCBtZXNzYWdlLnBhY2tlZF9lbnVtKDEpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkQ2xlYXIoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUmIG1lc3NhZ2UpIHsKKyAgLy8gUGFja2VkIHJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzTW9kaWZpZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUmIG1lc3NhZ2UpIHsKKyAgLy8gRG8gdGhlIHNhbWUgZm9yIHBhY2tlZCByZXBlYXRlZCBmaWVsZHMuCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UucGFja2VkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLnBhY2tlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5wYWNrZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UucGFja2VkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLnBhY2tlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5wYWNrZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLnBhY2tlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5wYWNrZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UucGFja2VkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSLCBtZXNzYWdlLnBhY2tlZF9lbnVtKDApKTsKKyAgLy8gQWN0dWFsbHkgdmVyaWZ5IHRoZSBzZWNvbmQgKG1vZGlmaWVkKSBlbGVtZW50cyBub3cuCisgIEVYUEVDVF9FUSg4MDEgICwgbWVzc2FnZS5wYWNrZWRfaW50MzIgICAoMSkpOworICBFWFBFQ1RfRVEoODAyICAsIG1lc3NhZ2UucGFja2VkX2ludDY0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwMyAgLCBtZXNzYWdlLnBhY2tlZF91aW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSg4MDQgICwgbWVzc2FnZS5wYWNrZWRfdWludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoODA1ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwNiAgLCBtZXNzYWdlLnBhY2tlZF9zaW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg4MDcgICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMiAoMSkpOworICBFWFBFQ1RfRVEoODA4ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkNjQgKDEpKTsKKyAgRVhQRUNUX0VRKDgwOSAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQzMigxKSk7CisgIEVYUEVDVF9FUSg4MTAgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkNjQoMSkpOworICBFWFBFQ1RfRVEoODExICAsIG1lc3NhZ2UucGFja2VkX2Zsb2F0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDgxMiAgLCBtZXNzYWdlLnBhY2tlZF9kb3VibGUgICgxKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5wYWNrZWRfYm9vbCAgICAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08sIG1lc3NhZ2UucGFja2VkX2VudW0oMSkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBFeHRlbnNpb25zCisvLworLy8gQWxsIHRoaXMgY29kZSBpcyBleGFjdGx5IGVxdWl2YWxlbnQgdG8gdGhlIGFib3ZlIGNvZGUgZXhjZXB0IHRoYXQgaXQncworLy8gbWFuaXB1bGF0aW5nIGV4dGVuc2lvbiBmaWVsZHMgaW5zdGVhZCBvZiBub3JtYWwgb25lcy4KKy8vCisvLyBJIGdhdmUgdXAgb24gdGhlIDgwLWNoYXIgbGltaXQgaGVyZS4gIFNvcnJ5LgorCit2b2lkIFRlc3RVdGlsTGl0ZTo6U2V0QWxsRXh0ZW5zaW9ucyh1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnNMaXRlKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDEwMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDEwMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDEwMyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDEwNCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDEwNSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDEwNik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDEwNyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDEwOCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDEwOSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDExMCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDExMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDExMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIHRydWUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAiMTE1Iik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAsICIxMTYiKTsKKworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICAgICAgICApLT5zZXRfYSgxMTcpOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLT5zZXRfYmIoMTE4KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgKS0+c2V0X2MoMTE5KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKS0+c2V0X2QoMTIwKTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS0+c2V0X2UoMTI2KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICAgKS0+c2V0X2JiKDEyNyk7CisKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVogKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUsIHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaICAgICAgKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFaKTsKKworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMjAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMjAyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMjAzKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMjA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMjA1KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMjA2KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMjA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMjA4KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMjA5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMjEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMjExKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMjEyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgdHJ1ZSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAsICIyMTUiKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICwgIjIxNiIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgKS0+c2V0X2EoMjE3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSApLT5zZXRfYmIoMjE4KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLT5zZXRfYygyMTkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICktPnNldF9kKDIyMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgKS0+c2V0X2JiKDIyNyk7CisKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUsIHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSICAgICAgKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFSKTsKKworCisgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMzAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMzAyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMzAzKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMzA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMzA1KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMzA2KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMzA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMzA4KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMzA5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMzEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMzExKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMzEyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAiMzE1Iik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAsICIzMTYiKTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICktPnNldF9hKDMxNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKS0+c2V0X2JiKDMxOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS0+c2V0X2MoMzE5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSApLT5zZXRfZCgzMjApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICktPnNldF9iYigzMjcpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWiAgICAgICk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWik7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgNDAxKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCA0MDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDQwMyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgNDA0KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCA0MDUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDQwNik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgNDA3KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCA0MDgpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDQwOSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgNDEwKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCA0MTEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDQxMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAsICI0MTUiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAiNDE2Iik7CisKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfRk9PKTsKKworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfdWludDMyX2V4dGVuc2lvbl9saXRlLCA2MDEpOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSktPnNldF9iYig2MDIpOzsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUsICI2MDMiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb25fbGl0ZSwgIjYwNCIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpNb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnMoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAxLCA1MDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAxLCA1MDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxLCA1MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxLCA1MDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxLCA1MDUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxLCA1MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAxLCA1MDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAxLCA1MDgpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAxLCA1MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAxLCA1MTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAxLCA1MTEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAxLCA1MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAxLCB0cnVlKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICwgMSwgIjUxNSIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAxLCAiNTE2Iik7CisKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgLCAxKS0+c2V0X2EoNTE3KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgLCAxKS0+c2V0X2JiKDUxOCk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSwgMSktPnNldF9jKDUxOSk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMSktPnNldF9kKDUyMCk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICwgMSktPnNldF9iYig1MjcpOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAxLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6Rk9PICk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCAxLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAxLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTyk7CisKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnNMaXRlJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgICApKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgICAgICAgKS5oYXNfYSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuaGFzX2JiKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgKS5oYXNfYygpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuaGFzX2QoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLmhhc19lKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICAgKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIEVYUEVDVF9FUSgxMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgxMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgxMDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgxMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgxMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgxMDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgxMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgxMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgxMDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgxMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgxMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgxMTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEVYUEVDVF9FUSgiMTE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgiMTE2IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX0VRKDExNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICAgICAgICkuYSgpKTsKKyAgRVhQRUNUX0VRKDExOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuYmIoKSk7CisgIEVYUEVDVF9FUSgxMTksIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICApLmMoKSk7CisgIEVYUEVDVF9FUSgxMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmQoKSk7CisgIEVYUEVDVF9FUSgxMjYsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLmUoKSk7CisgIEVYUEVDVF9FUSgxMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgICApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFaLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICAgICkpOworCisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDIxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgLCAwKS5hKCkpOworICBFWFBFQ1RfRVEoMjE4LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgLCAwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSwgMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDIyNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICwgMCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAsIDApKTsKKworCisgIEVYUEVDVF9FUSgzMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAxKSk7CisgIEVYUEVDVF9FUSgzMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAxKSk7CisgIEVYUEVDVF9FUSgzMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiMzE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSgiMzE2IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisKKyAgRVhQRUNUX0VRKDMxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDMxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMSkuYmIoKSk7CisgIEVYUEVDVF9FUSgzMTksIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUsIDEpLmMoKSk7CisgIEVYUEVDVF9FUSgzMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSgzMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAsIDEpLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFaLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIEVYUEVDVF9FUSg0MDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDQwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoNDAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSg0MDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDQwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoNDA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSg0MDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDQwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEoNDA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSg0MTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDQxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoNDEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKCI0MTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoIjQxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfRk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl91aW50MzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5oYXNfYmIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX2J5dGVzX2V4dGVuc2lvbl9saXRlKSk7CisKKyAgRVhQRUNUX0VRKDYwMSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoNjAyLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLmJiKCkpOworICBFWFBFQ1RfRVEoIjYwMyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKCI2MDQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpIHsKKyAgc3RyaW5nIHNlcmlhbGl6ZWQ7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpKTsKKyAgRVhQRUNUX0VRKCIiLCBzZXJpYWxpemVkKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuQnl0ZVNpemUoKSk7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgaW5pdGlhbGx5IGJlIGZhbHNlIGZvciBhbGwgb3B0aW9uYWwgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICAgKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIC8vIE9wdGlvbmFsIGZpZWxkcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gemVybyBvciBzb21ldGhpbmcgbGlrZSBpdC4KKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICApKTsKKworICAvLyBFbWJlZGRlZCBtZXNzYWdlcyBzaG91bGQgYWxzbyBiZSBjbGVhci4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICAgICAgICApLmhhc19hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuaGFzX2JiKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICkuaGFzX2MoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKS5oYXNfZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLmhhc19lKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICAgICkuaGFzX2JiKCkpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgICAgICAgKS5hKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuYmIoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgKS5jKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuZCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLmUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICAgKS5iYigpKTsKKworICAvLyBFbnVtcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBlbnVtLgorICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICkpOworCisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGFyZSBlbXB0eS4KKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICApKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisKKworICAvLyBoYXNfYmxhaCgpIHNob3VsZCBhbHNvIGJlIGZhbHNlIGZvciBhbGwgZGVmYXVsdCBmaWVsZHMuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIC8vIEZpZWxkcyB3aXRoIGRlZmF1bHRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMgKGR1aCkuCisgIEVYUEVDVF9FUSggNDEgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoIDQyICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKCA0MyAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSggNDQgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoLTQ1ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKCA0NiAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSggNDcgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEoIDQ4ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKCA0OSAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgtNTAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoIDUxLjUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKCA1MmUzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSh0cnVlICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKCJ3b3JsZCIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfdWludDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLmhhc19iYigpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb25fbGl0ZSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnNMaXRlJiBtZXNzYWdlKSB7CisgIC8vIE1vZGlmeVJlcGVhdGVkRmllbGRzIG9ubHkgc2V0cyB0aGUgc2Vjb25kIHJlcGVhdGVkIGVsZW1lbnQgb2YgZWFjaAorICAvLyBmaWVsZC4gIEluIGFkZGl0aW9uIHRvIHZlcmlmeWluZyB0aGlzLCB3ZSBhbHNvIHZlcmlmeSB0aGF0IHRoZSBmaXJzdAorICAvLyBlbGVtZW50IGFuZCBzaXplIHdlcmUgKm5vdCogbW9kaWZpZWQuCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICAgICkpOworCisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDIxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgLCAwKS5hKCkpOworICBFWFBFQ1RfRVEoMjE4LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgLCAwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSwgMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDIyNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICwgMCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAsIDApKTsKKworCisgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICBFWFBFQ1RfRVEoNTAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoNTAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoNTAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNTA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNTA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNTA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNTA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEoNTA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEoNTA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoNTEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoNTExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoNTEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgMSkpOworICBFWFBFQ1RfRVEoIjUxNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoIjUxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICwgMSkpOworCisgIEVYUEVDVF9FUSg1MTcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICAsIDEpLmEoKSk7CisgIEVYUEVDVF9FUSg1MTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoNTE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlLCAxKS5jKCkpOworICBFWFBFQ1RfRVEoNTIwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgLCAxKS5kKCkpOworICBFWFBFQ1RfRVEoNTI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCAxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMSkpOworCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OlNldFBhY2tlZEV4dGVuc2lvbnMoCisgICAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgNjAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDYwMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCA2MDMpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgNjA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDYwNSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCA2MDYpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgNjA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDYwOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCA2MDkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgNjEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDYxMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCA2MTIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgdHJ1ZSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUsIHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSKTsKKyAgLy8gYWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCA3MDEpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgNzAyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDcwMyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCA3MDQpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgNzA1KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDcwNik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCA3MDcpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgNzA4KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDcwOSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCA3MTApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgNzExKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDcxMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCBmYWxzZSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUsIHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6TW9kaWZ5UGFja2VkRXh0ZW5zaW9ucygKKyAgICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAxLCA4MDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMSwgODAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDEsIDgwMyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxLCA4MDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSwgODA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDEsIDgwNik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAxLCA4MDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMSwgODA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDEsIDgwOSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAxLCA4MTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMSwgODExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDEsIDgxMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAxLCB0cnVlKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSAgICAsIDEsCisgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSwgMCkpOworICBFWFBFQ1RfRVEoNzAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNzA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNzA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoNzEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDEpKTsKKyAgRVhQRUNUX0VRKDcxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlLCAxKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcigKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc01vZGlmaWVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpIHsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlLCAwKSk7CisKKyAgLy8gQWN0dWFsbHkgdmVyaWZ5IHRoZSBzZWNvbmQgKG1vZGlmaWVkKSBlbGVtZW50cyBub3cuCisgIEVYUEVDVF9FUSg4MDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoODAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoODA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEoODA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAxKSk7CisgIEVYUEVDVF9FUSg4MTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoODExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08sCisgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUsIDEpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjI1MGM5MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsX2xpdGUuaApAQCAtMCwwICsxLDEwMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1RFU1RfVVRJTF9MSVRFX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgdW5pdHRlc3QgPSBwcm90b2J1Zl91bml0dGVzdDsKK25hbWVzcGFjZSB1bml0dGVzdF9pbXBvcnQgPSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK2NsYXNzIFRlc3RVdGlsTGl0ZSB7CisgcHVibGljOgorICAvLyBTZXQgZXZlcnkgZmllbGQgaW4gdGhlIG1lc3NhZ2UgdG8gYSB1bmlxdWUgdmFsdWUuCisgIHN0YXRpYyB2b2lkIFNldEFsbEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldEFsbEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldFBhY2tlZEZpZWxkcyh1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldFBhY2tlZEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSk7CisKKyAgLy8gVXNlIHRoZSByZXBlYXRlZCB2ZXJzaW9ucyBvZiB0aGUgc2V0XyooKSBhY2Nlc3NvcnMgdG8gbW9kaWZ5IGFsbCB0aGUKKyAgLy8gcmVwZWF0ZWQgZmllbGRzIG9mIHRoZSBtZXNzc2FnZSAod2hpY2ggc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuCisgIC8vIGluaXRpYWxpemVkIHdpdGggU2V0KkZpZWxkcygpKS4gIFNldCpGaWVsZHMoKSBpdHNlbGYgb25seSB0ZXN0cworICAvLyB0aGUgYWRkXyooKSBhY2Nlc3NvcnMuCisgIHN0YXRpYyB2b2lkIE1vZGlmeVJlcGVhdGVkRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgTW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zKAorICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIE1vZGlmeVBhY2tlZEZpZWxkcyh1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIE1vZGlmeVBhY2tlZEV4dGVuc2lvbnMoCisgICAgICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlKiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXQqRmllbGRzKCkgaXMgY2FsbGVkLgorICBzdGF0aWMgdm9pZCBFeHBlY3RBbGxGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RBbGxFeHRlbnNpb25zU2V0KAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZEZpZWxkc1NldCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRXh0ZW5zaW9uc1NldCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpOworCisgIC8vIEV4cGVjdCB0aGF0IHRoZSBtZXNzYWdlIGlzIG1vZGlmaWVkIGFzIHdvdWxkIGJlIGV4cGVjdGVkIGZyb20KKyAgLy8gTW9kaWZ5KkZpZWxkcygpLgorICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZEZpZWxkc01vZGlmaWVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRGaWVsZHNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRXh0ZW5zaW9uc01vZGlmaWVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCisgIHN0YXRpYyB2b2lkIEV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0RXh0ZW5zaW9uc0NsZWFyKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRXh0ZW5zaW9uc0NsZWFyKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGVzdFV0aWxMaXRlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvYmFkX3V0Zjhfc3RyaW5nIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9iYWRfdXRmOF9zdHJpbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTEzMzdlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvYmFkX3V0Zjhfc3RyaW5nCkBAIC0wLDAgKzEgQEAKK3IB/wpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2UgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiN2U2NTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2Vfb25lb2ZfaW1wbGVtZW50ZWQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlX29uZW9mX2ltcGxlbWVudGVkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0OGM4OTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlX29uZW9mX2ltcGxlbWVudGVkCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2VfcHJvdG8zIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9wcm90bzMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTM0ZjM2ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2VfcHJvdG8zCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3Rlc3RkYXRhL2dvbGRlbl9wYWNrZWRfZmllbGRzX21lc3NhZ2UgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9wYWNrZWRfZmllbGRzX21lc3NhZ2UKc2ltaWxhcml0eSBpbmRleCAxMDAlCmNvcHkgZnJvbSB0ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlCmNvcHkgdG8gc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhODc0YjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0CkBAIC0wLDAgKzEsMTM0IEBACitvcHRpb25hbF9pbnQzMjogMTAxCitvcHRpb25hbF9pbnQ2NDogMTAyCitvcHRpb25hbF91aW50MzI6IDEwMworb3B0aW9uYWxfdWludDY0OiAxMDQKK29wdGlvbmFsX3NpbnQzMjogMTA1CitvcHRpb25hbF9zaW50NjQ6IDEwNgorb3B0aW9uYWxfZml4ZWQzMjogMTA3CitvcHRpb25hbF9maXhlZDY0OiAxMDgKK29wdGlvbmFsX3NmaXhlZDMyOiAxMDkKK29wdGlvbmFsX3NmaXhlZDY0OiAxMTAKK29wdGlvbmFsX2Zsb2F0OiAxMTEKK29wdGlvbmFsX2RvdWJsZTogMTEyCitvcHRpb25hbF9ib29sOiB0cnVlCitvcHRpb25hbF9zdHJpbmc6ICIxMTUiCitvcHRpb25hbF9ieXRlczogIjExNiIKK09wdGlvbmFsR3JvdXAgeworICBhOiAxMTcKK30KK29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsKKyAgYmI6IDExOAorfQorb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIHsKKyAgYzogMTE5Cit9CitvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSB7CisgIGQ6IDEyMAorfQorb3B0aW9uYWxfbmVzdGVkX2VudW06IEJBWgorb3B0aW9uYWxfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorb3B0aW9uYWxfaW1wb3J0X2VudW06IElNUE9SVF9CQVoKK29wdGlvbmFsX3N0cmluZ19waWVjZTogIjEyNCIKK29wdGlvbmFsX2NvcmQ6ICIxMjUiCitvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgeworICBlOiAxMjYKK30KK29wdGlvbmFsX2xhenlfbWVzc2FnZSB7CisgIGJiOiAxMjcKK30KK3JlcGVhdGVkX2ludDMyOiAyMDEKK3JlcGVhdGVkX2ludDMyOiAzMDEKK3JlcGVhdGVkX2ludDY0OiAyMDIKK3JlcGVhdGVkX2ludDY0OiAzMDIKK3JlcGVhdGVkX3VpbnQzMjogMjAzCityZXBlYXRlZF91aW50MzI6IDMwMworcmVwZWF0ZWRfdWludDY0OiAyMDQKK3JlcGVhdGVkX3VpbnQ2NDogMzA0CityZXBlYXRlZF9zaW50MzI6IDIwNQorcmVwZWF0ZWRfc2ludDMyOiAzMDUKK3JlcGVhdGVkX3NpbnQ2NDogMjA2CityZXBlYXRlZF9zaW50NjQ6IDMwNgorcmVwZWF0ZWRfZml4ZWQzMjogMjA3CityZXBlYXRlZF9maXhlZDMyOiAzMDcKK3JlcGVhdGVkX2ZpeGVkNjQ6IDIwOAorcmVwZWF0ZWRfZml4ZWQ2NDogMzA4CityZXBlYXRlZF9zZml4ZWQzMjogMjA5CityZXBlYXRlZF9zZml4ZWQzMjogMzA5CityZXBlYXRlZF9zZml4ZWQ2NDogMjEwCityZXBlYXRlZF9zZml4ZWQ2NDogMzEwCityZXBlYXRlZF9mbG9hdDogMjExCityZXBlYXRlZF9mbG9hdDogMzExCityZXBlYXRlZF9kb3VibGU6IDIxMgorcmVwZWF0ZWRfZG91YmxlOiAzMTIKK3JlcGVhdGVkX2Jvb2w6IHRydWUKK3JlcGVhdGVkX2Jvb2w6IGZhbHNlCityZXBlYXRlZF9zdHJpbmc6ICIyMTUiCityZXBlYXRlZF9zdHJpbmc6ICIzMTUiCityZXBlYXRlZF9ieXRlczogIjIxNiIKK3JlcGVhdGVkX2J5dGVzOiAiMzE2IgorUmVwZWF0ZWRHcm91cCB7CisgIGE6IDIxNworfQorUmVwZWF0ZWRHcm91cCB7CisgIGE6IDMxNworfQorcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgeworICBiYjogMjE4Cit9CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7CisgIGJiOiAzMTgKK30KK3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSB7CisgIGM6IDIxOQorfQorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIHsKKyAgYzogMzE5Cit9CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSB7CisgIGQ6IDIyMAorfQorcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgeworICBkOiAzMjAKK30KK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVIKK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVoKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVIKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVoKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFSCityZXBlYXRlZF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMjI0IgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMzI0IgorcmVwZWF0ZWRfY29yZDogIjIyNSIKK3JlcGVhdGVkX2NvcmQ6ICIzMjUiCityZXBlYXRlZF9sYXp5X21lc3NhZ2UgeworICBiYjogMjI3Cit9CityZXBlYXRlZF9sYXp5X21lc3NhZ2UgeworICBiYjogMzI3Cit9CitkZWZhdWx0X2ludDMyOiA0MDEKK2RlZmF1bHRfaW50NjQ6IDQwMgorZGVmYXVsdF91aW50MzI6IDQwMworZGVmYXVsdF91aW50NjQ6IDQwNAorZGVmYXVsdF9zaW50MzI6IDQwNQorZGVmYXVsdF9zaW50NjQ6IDQwNgorZGVmYXVsdF9maXhlZDMyOiA0MDcKK2RlZmF1bHRfZml4ZWQ2NDogNDA4CitkZWZhdWx0X3NmaXhlZDMyOiA0MDkKK2RlZmF1bHRfc2ZpeGVkNjQ6IDQxMAorZGVmYXVsdF9mbG9hdDogNDExCitkZWZhdWx0X2RvdWJsZTogNDEyCitkZWZhdWx0X2Jvb2w6IGZhbHNlCitkZWZhdWx0X3N0cmluZzogIjQxNSIKK2RlZmF1bHRfYnl0ZXM6ICI0MTYiCitkZWZhdWx0X25lc3RlZF9lbnVtOiBGT08KK2RlZmF1bHRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0ZPTworZGVmYXVsdF9pbXBvcnRfZW51bTogSU1QT1JUX0ZPTworZGVmYXVsdF9zdHJpbmdfcGllY2U6ICI0MjQiCitkZWZhdWx0X2NvcmQ6ICI0MjUiCitvbmVvZl91aW50MzI6IDYwMQorb25lb2ZfbmVzdGVkX21lc3NhZ2UgeworICBiYjogNjAyCit9CitvbmVvZl9zdHJpbmc6ICI2MDMiCitvbmVvZl9ieXRlczogIjYwNCIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9vbmVvZl9pbXBsZW1lbnRlZC50eHQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfb25lb2ZfaW1wbGVtZW50ZWQudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjOTVlMWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfb25lb2ZfaW1wbGVtZW50ZWQudHh0CkBAIC0wLDAgKzEsMTI5IEBACitvcHRpb25hbF9pbnQzMjogMTAxCitvcHRpb25hbF9pbnQ2NDogMTAyCitvcHRpb25hbF91aW50MzI6IDEwMworb3B0aW9uYWxfdWludDY0OiAxMDQKK29wdGlvbmFsX3NpbnQzMjogMTA1CitvcHRpb25hbF9zaW50NjQ6IDEwNgorb3B0aW9uYWxfZml4ZWQzMjogMTA3CitvcHRpb25hbF9maXhlZDY0OiAxMDgKK29wdGlvbmFsX3NmaXhlZDMyOiAxMDkKK29wdGlvbmFsX3NmaXhlZDY0OiAxMTAKK29wdGlvbmFsX2Zsb2F0OiAxMTEKK29wdGlvbmFsX2RvdWJsZTogMTEyCitvcHRpb25hbF9ib29sOiB0cnVlCitvcHRpb25hbF9zdHJpbmc6ICIxMTUiCitvcHRpb25hbF9ieXRlczogIjExNiIKK09wdGlvbmFsR3JvdXAgeworICBhOiAxMTcKK30KK29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsKKyAgYmI6IDExOAorfQorb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIHsKKyAgYzogMTE5Cit9CitvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSB7CisgIGQ6IDEyMAorfQorb3B0aW9uYWxfbmVzdGVkX2VudW06IEJBWgorb3B0aW9uYWxfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorb3B0aW9uYWxfaW1wb3J0X2VudW06IElNUE9SVF9CQVoKK29wdGlvbmFsX3N0cmluZ19waWVjZTogIjEyNCIKK29wdGlvbmFsX2NvcmQ6ICIxMjUiCitvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgeworICBlOiAxMjYKK30KK29wdGlvbmFsX2xhenlfbWVzc2FnZSB7CisgIGJiOiAxMjcKK30KK3JlcGVhdGVkX2ludDMyOiAyMDEKK3JlcGVhdGVkX2ludDMyOiAzMDEKK3JlcGVhdGVkX2ludDY0OiAyMDIKK3JlcGVhdGVkX2ludDY0OiAzMDIKK3JlcGVhdGVkX3VpbnQzMjogMjAzCityZXBlYXRlZF91aW50MzI6IDMwMworcmVwZWF0ZWRfdWludDY0OiAyMDQKK3JlcGVhdGVkX3VpbnQ2NDogMzA0CityZXBlYXRlZF9zaW50MzI6IDIwNQorcmVwZWF0ZWRfc2ludDMyOiAzMDUKK3JlcGVhdGVkX3NpbnQ2NDogMjA2CityZXBlYXRlZF9zaW50NjQ6IDMwNgorcmVwZWF0ZWRfZml4ZWQzMjogMjA3CityZXBlYXRlZF9maXhlZDMyOiAzMDcKK3JlcGVhdGVkX2ZpeGVkNjQ6IDIwOAorcmVwZWF0ZWRfZml4ZWQ2NDogMzA4CityZXBlYXRlZF9zZml4ZWQzMjogMjA5CityZXBlYXRlZF9zZml4ZWQzMjogMzA5CityZXBlYXRlZF9zZml4ZWQ2NDogMjEwCityZXBlYXRlZF9zZml4ZWQ2NDogMzEwCityZXBlYXRlZF9mbG9hdDogMjExCityZXBlYXRlZF9mbG9hdDogMzExCityZXBlYXRlZF9kb3VibGU6IDIxMgorcmVwZWF0ZWRfZG91YmxlOiAzMTIKK3JlcGVhdGVkX2Jvb2w6IHRydWUKK3JlcGVhdGVkX2Jvb2w6IGZhbHNlCityZXBlYXRlZF9zdHJpbmc6ICIyMTUiCityZXBlYXRlZF9zdHJpbmc6ICIzMTUiCityZXBlYXRlZF9ieXRlczogIjIxNiIKK3JlcGVhdGVkX2J5dGVzOiAiMzE2IgorUmVwZWF0ZWRHcm91cCB7CisgIGE6IDIxNworfQorUmVwZWF0ZWRHcm91cCB7CisgIGE6IDMxNworfQorcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgeworICBiYjogMjE4Cit9CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7CisgIGJiOiAzMTgKK30KK3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSB7CisgIGM6IDIxOQorfQorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIHsKKyAgYzogMzE5Cit9CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSB7CisgIGQ6IDIyMAorfQorcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgeworICBkOiAzMjAKK30KK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVIKK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVoKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVIKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVoKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFSCityZXBlYXRlZF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMjI0IgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMzI0IgorcmVwZWF0ZWRfY29yZDogIjIyNSIKK3JlcGVhdGVkX2NvcmQ6ICIzMjUiCityZXBlYXRlZF9sYXp5X21lc3NhZ2UgeworICBiYjogMjI3Cit9CityZXBlYXRlZF9sYXp5X21lc3NhZ2UgeworICBiYjogMzI3Cit9CitkZWZhdWx0X2ludDMyOiA0MDEKK2RlZmF1bHRfaW50NjQ6IDQwMgorZGVmYXVsdF91aW50MzI6IDQwMworZGVmYXVsdF91aW50NjQ6IDQwNAorZGVmYXVsdF9zaW50MzI6IDQwNQorZGVmYXVsdF9zaW50NjQ6IDQwNgorZGVmYXVsdF9maXhlZDMyOiA0MDcKK2RlZmF1bHRfZml4ZWQ2NDogNDA4CitkZWZhdWx0X3NmaXhlZDMyOiA0MDkKK2RlZmF1bHRfc2ZpeGVkNjQ6IDQxMAorZGVmYXVsdF9mbG9hdDogNDExCitkZWZhdWx0X2RvdWJsZTogNDEyCitkZWZhdWx0X2Jvb2w6IGZhbHNlCitkZWZhdWx0X3N0cmluZzogIjQxNSIKK2RlZmF1bHRfYnl0ZXM6ICI0MTYiCitkZWZhdWx0X25lc3RlZF9lbnVtOiBGT08KK2RlZmF1bHRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0ZPTworZGVmYXVsdF9pbXBvcnRfZW51bTogSU1QT1JUX0ZPTworZGVmYXVsdF9zdHJpbmdfcGllY2U6ICI0MjQiCitkZWZhdWx0X2NvcmQ6ICI0MjUiCitvbmVvZl9ieXRlczogIjYwNCIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9wb2ludHkudHh0IGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX3BvaW50eS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTEwMTFlYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9wb2ludHkudHh0CkBAIC0wLDAgKzEsMTM0IEBACitvcHRpb25hbF9pbnQzMjogMTAxCitvcHRpb25hbF9pbnQ2NDogMTAyCitvcHRpb25hbF91aW50MzI6IDEwMworb3B0aW9uYWxfdWludDY0OiAxMDQKK29wdGlvbmFsX3NpbnQzMjogMTA1CitvcHRpb25hbF9zaW50NjQ6IDEwNgorb3B0aW9uYWxfZml4ZWQzMjogMTA3CitvcHRpb25hbF9maXhlZDY0OiAxMDgKK29wdGlvbmFsX3NmaXhlZDMyOiAxMDkKK29wdGlvbmFsX3NmaXhlZDY0OiAxMTAKK29wdGlvbmFsX2Zsb2F0OiAxMTEKK29wdGlvbmFsX2RvdWJsZTogMTEyCitvcHRpb25hbF9ib29sOiB0cnVlCitvcHRpb25hbF9zdHJpbmc6ICIxMTUiCitvcHRpb25hbF9ieXRlczogIjExNiIKK09wdGlvbmFsR3JvdXAgPAorICBhOiAxMTcKKz4KK29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIDwKKyAgYmI6IDExOAorPgorb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIDwKKyAgYzogMTE5Cis+CitvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA8CisgIGQ6IDEyMAorPgorb3B0aW9uYWxfbmVzdGVkX2VudW06IEJBWgorb3B0aW9uYWxfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorb3B0aW9uYWxfaW1wb3J0X2VudW06IElNUE9SVF9CQVoKK29wdGlvbmFsX3N0cmluZ19waWVjZTogIjEyNCIKK29wdGlvbmFsX2NvcmQ6ICIxMjUiCitvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPAorICBlOiAxMjYKKz4KK29wdGlvbmFsX2xhenlfbWVzc2FnZSA8CisgIGJiOiAxMjcKKz4KK3JlcGVhdGVkX2ludDMyOiAyMDEKK3JlcGVhdGVkX2ludDMyOiAzMDEKK3JlcGVhdGVkX2ludDY0OiAyMDIKK3JlcGVhdGVkX2ludDY0OiAzMDIKK3JlcGVhdGVkX3VpbnQzMjogMjAzCityZXBlYXRlZF91aW50MzI6IDMwMworcmVwZWF0ZWRfdWludDY0OiAyMDQKK3JlcGVhdGVkX3VpbnQ2NDogMzA0CityZXBlYXRlZF9zaW50MzI6IDIwNQorcmVwZWF0ZWRfc2ludDMyOiAzMDUKK3JlcGVhdGVkX3NpbnQ2NDogMjA2CityZXBlYXRlZF9zaW50NjQ6IDMwNgorcmVwZWF0ZWRfZml4ZWQzMjogMjA3CityZXBlYXRlZF9maXhlZDMyOiAzMDcKK3JlcGVhdGVkX2ZpeGVkNjQ6IDIwOAorcmVwZWF0ZWRfZml4ZWQ2NDogMzA4CityZXBlYXRlZF9zZml4ZWQzMjogMjA5CityZXBlYXRlZF9zZml4ZWQzMjogMzA5CityZXBlYXRlZF9zZml4ZWQ2NDogMjEwCityZXBlYXRlZF9zZml4ZWQ2NDogMzEwCityZXBlYXRlZF9mbG9hdDogMjExCityZXBlYXRlZF9mbG9hdDogMzExCityZXBlYXRlZF9kb3VibGU6IDIxMgorcmVwZWF0ZWRfZG91YmxlOiAzMTIKK3JlcGVhdGVkX2Jvb2w6IHRydWUKK3JlcGVhdGVkX2Jvb2w6IGZhbHNlCityZXBlYXRlZF9zdHJpbmc6ICIyMTUiCityZXBlYXRlZF9zdHJpbmc6ICIzMTUiCityZXBlYXRlZF9ieXRlczogIjIxNiIKK3JlcGVhdGVkX2J5dGVzOiAiMzE2IgorUmVwZWF0ZWRHcm91cCA8CisgIGE6IDIxNworPgorUmVwZWF0ZWRHcm91cCA8CisgIGE6IDMxNworPgorcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPAorICBiYjogMjE4Cis+CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8CisgIGJiOiAzMTgKKz4KK3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA8CisgIGM6IDIxOQorPgorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIDwKKyAgYzogMzE5Cis+CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA8CisgIGQ6IDIyMAorPgorcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPAorICBkOiAzMjAKKz4KK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVIKK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVoKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVIKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVoKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFSCityZXBlYXRlZF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMjI0IgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMzI0IgorcmVwZWF0ZWRfY29yZDogIjIyNSIKK3JlcGVhdGVkX2NvcmQ6ICIzMjUiCityZXBlYXRlZF9sYXp5X21lc3NhZ2UgPAorICBiYjogMjI3Cis+CityZXBlYXRlZF9sYXp5X21lc3NhZ2UgPAorICBiYjogMzI3Cis+CitkZWZhdWx0X2ludDMyOiA0MDEKK2RlZmF1bHRfaW50NjQ6IDQwMgorZGVmYXVsdF91aW50MzI6IDQwMworZGVmYXVsdF91aW50NjQ6IDQwNAorZGVmYXVsdF9zaW50MzI6IDQwNQorZGVmYXVsdF9zaW50NjQ6IDQwNgorZGVmYXVsdF9maXhlZDMyOiA0MDcKK2RlZmF1bHRfZml4ZWQ2NDogNDA4CitkZWZhdWx0X3NmaXhlZDMyOiA0MDkKK2RlZmF1bHRfc2ZpeGVkNjQ6IDQxMAorZGVmYXVsdF9mbG9hdDogNDExCitkZWZhdWx0X2RvdWJsZTogNDEyCitkZWZhdWx0X2Jvb2w6IGZhbHNlCitkZWZhdWx0X3N0cmluZzogIjQxNSIKK2RlZmF1bHRfYnl0ZXM6ICI0MTYiCitkZWZhdWx0X25lc3RlZF9lbnVtOiBGT08KK2RlZmF1bHRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0ZPTworZGVmYXVsdF9pbXBvcnRfZW51bTogSU1QT1JUX0ZPTworZGVmYXVsdF9zdHJpbmdfcGllY2U6ICI0MjQiCitkZWZhdWx0X2NvcmQ6ICI0MjUiCitvbmVvZl91aW50MzI6IDYwMQorb25lb2ZfbmVzdGVkX21lc3NhZ2UgPAorICBiYjogNjAyCis+CitvbmVvZl9zdHJpbmc6ICI2MDMiCitvbmVvZl9ieXRlczogIjYwNCIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9wb2ludHlfb25lb2YudHh0IGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX3BvaW50eV9vbmVvZi50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTUxMDlmNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9wb2ludHlfb25lb2YudHh0CkBAIC0wLDAgKzEsMTI5IEBACitvcHRpb25hbF9pbnQzMjogMTAxCitvcHRpb25hbF9pbnQ2NDogMTAyCitvcHRpb25hbF91aW50MzI6IDEwMworb3B0aW9uYWxfdWludDY0OiAxMDQKK29wdGlvbmFsX3NpbnQzMjogMTA1CitvcHRpb25hbF9zaW50NjQ6IDEwNgorb3B0aW9uYWxfZml4ZWQzMjogMTA3CitvcHRpb25hbF9maXhlZDY0OiAxMDgKK29wdGlvbmFsX3NmaXhlZDMyOiAxMDkKK29wdGlvbmFsX3NmaXhlZDY0OiAxMTAKK29wdGlvbmFsX2Zsb2F0OiAxMTEKK29wdGlvbmFsX2RvdWJsZTogMTEyCitvcHRpb25hbF9ib29sOiB0cnVlCitvcHRpb25hbF9zdHJpbmc6ICIxMTUiCitvcHRpb25hbF9ieXRlczogIjExNiIKK09wdGlvbmFsR3JvdXAgPAorICBhOiAxMTcKKz4KK29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIDwKKyAgYmI6IDExOAorPgorb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIDwKKyAgYzogMTE5Cis+CitvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA8CisgIGQ6IDEyMAorPgorb3B0aW9uYWxfbmVzdGVkX2VudW06IEJBWgorb3B0aW9uYWxfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorb3B0aW9uYWxfaW1wb3J0X2VudW06IElNUE9SVF9CQVoKK29wdGlvbmFsX3N0cmluZ19waWVjZTogIjEyNCIKK29wdGlvbmFsX2NvcmQ6ICIxMjUiCitvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPAorICBlOiAxMjYKKz4KK29wdGlvbmFsX2xhenlfbWVzc2FnZSA8CisgIGJiOiAxMjcKKz4KK3JlcGVhdGVkX2ludDMyOiAyMDEKK3JlcGVhdGVkX2ludDMyOiAzMDEKK3JlcGVhdGVkX2ludDY0OiAyMDIKK3JlcGVhdGVkX2ludDY0OiAzMDIKK3JlcGVhdGVkX3VpbnQzMjogMjAzCityZXBlYXRlZF91aW50MzI6IDMwMworcmVwZWF0ZWRfdWludDY0OiAyMDQKK3JlcGVhdGVkX3VpbnQ2NDogMzA0CityZXBlYXRlZF9zaW50MzI6IDIwNQorcmVwZWF0ZWRfc2ludDMyOiAzMDUKK3JlcGVhdGVkX3NpbnQ2NDogMjA2CityZXBlYXRlZF9zaW50NjQ6IDMwNgorcmVwZWF0ZWRfZml4ZWQzMjogMjA3CityZXBlYXRlZF9maXhlZDMyOiAzMDcKK3JlcGVhdGVkX2ZpeGVkNjQ6IDIwOAorcmVwZWF0ZWRfZml4ZWQ2NDogMzA4CityZXBlYXRlZF9zZml4ZWQzMjogMjA5CityZXBlYXRlZF9zZml4ZWQzMjogMzA5CityZXBlYXRlZF9zZml4ZWQ2NDogMjEwCityZXBlYXRlZF9zZml4ZWQ2NDogMzEwCityZXBlYXRlZF9mbG9hdDogMjExCityZXBlYXRlZF9mbG9hdDogMzExCityZXBlYXRlZF9kb3VibGU6IDIxMgorcmVwZWF0ZWRfZG91YmxlOiAzMTIKK3JlcGVhdGVkX2Jvb2w6IHRydWUKK3JlcGVhdGVkX2Jvb2w6IGZhbHNlCityZXBlYXRlZF9zdHJpbmc6ICIyMTUiCityZXBlYXRlZF9zdHJpbmc6ICIzMTUiCityZXBlYXRlZF9ieXRlczogIjIxNiIKK3JlcGVhdGVkX2J5dGVzOiAiMzE2IgorUmVwZWF0ZWRHcm91cCA8CisgIGE6IDIxNworPgorUmVwZWF0ZWRHcm91cCA8CisgIGE6IDMxNworPgorcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPAorICBiYjogMjE4Cis+CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8CisgIGJiOiAzMTgKKz4KK3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA8CisgIGM6IDIxOQorPgorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIDwKKyAgYzogMzE5Cis+CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA8CisgIGQ6IDIyMAorPgorcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPAorICBkOiAzMjAKKz4KK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVIKK3JlcGVhdGVkX25lc3RlZF9lbnVtOiBCQVoKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVIKK3JlcGVhdGVkX2ZvcmVpZ25fZW51bTogRk9SRUlHTl9CQVoKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFSCityZXBlYXRlZF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMjI0IgorcmVwZWF0ZWRfc3RyaW5nX3BpZWNlOiAiMzI0IgorcmVwZWF0ZWRfY29yZDogIjIyNSIKK3JlcGVhdGVkX2NvcmQ6ICIzMjUiCityZXBlYXRlZF9sYXp5X21lc3NhZ2UgPAorICBiYjogMjI3Cis+CityZXBlYXRlZF9sYXp5X21lc3NhZ2UgPAorICBiYjogMzI3Cis+CitkZWZhdWx0X2ludDMyOiA0MDEKK2RlZmF1bHRfaW50NjQ6IDQwMgorZGVmYXVsdF91aW50MzI6IDQwMworZGVmYXVsdF91aW50NjQ6IDQwNAorZGVmYXVsdF9zaW50MzI6IDQwNQorZGVmYXVsdF9zaW50NjQ6IDQwNgorZGVmYXVsdF9maXhlZDMyOiA0MDcKK2RlZmF1bHRfZml4ZWQ2NDogNDA4CitkZWZhdWx0X3NmaXhlZDMyOiA0MDkKK2RlZmF1bHRfc2ZpeGVkNjQ6IDQxMAorZGVmYXVsdF9mbG9hdDogNDExCitkZWZhdWx0X2RvdWJsZTogNDEyCitkZWZhdWx0X2Jvb2w6IGZhbHNlCitkZWZhdWx0X3N0cmluZzogIjQxNSIKK2RlZmF1bHRfYnl0ZXM6ICI0MTYiCitkZWZhdWx0X25lc3RlZF9lbnVtOiBGT08KK2RlZmF1bHRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0ZPTworZGVmYXVsdF9pbXBvcnRfZW51bTogSU1QT1JUX0ZPTworZGVmYXVsdF9zdHJpbmdfcGllY2U6ICI0MjQiCitkZWZhdWx0X2NvcmQ6ICI0MjUiCitvbmVvZl9ieXRlczogIjYwNCIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhLnR4dCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzhiMWViCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0CkBAIC0wLDAgKzEsMTM0IEBACitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXTogMTAxCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uXTogMTAyCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbl06IDEwMworW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25dOiAxMDQKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uXTogMTA1CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbl06IDEwNgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uXTogMTA3CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25dOiAxMDgKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb25dOiAxMDkKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb25dOiAxMTAKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9mbG9hdF9leHRlbnNpb25dOiAxMTEKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uXTogMTEyCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfYm9vbF9leHRlbnNpb25dOiB0cnVlCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbl06ICIxMTUiCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uXTogIjExNiIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbGdyb3VwX2V4dGVuc2lvbl0geworICBhOiAxMTcKK30KK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgYmI6IDExOAorfQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgYzogMTE5Cit9CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGQ6IDEyMAorfQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEJBWgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl06IElNUE9SVF9CQVoKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uXTogIjEyNCIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9jb3JkX2V4dGVuc2lvbl06ICIxMjUiCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl0geworICBlOiAxMjYKK30KK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGJiOiAxMjcKK30KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQzMl9leHRlbnNpb25dOiAyMDEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQzMl9leHRlbnNpb25dOiAzMDEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25dOiAyMDIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25dOiAzMDIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uXTogMjAzCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl06IDMwMworW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25dOiAyMDQKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uXTogMzA0CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl06IDIwNQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25dOiAzMDUKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uXTogMjA2CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl06IDMwNgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uXTogMjA3CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25dOiAzMDcKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl06IDIwOAorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uXTogMzA4CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uXTogMjA5CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uXTogMzA5CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uXTogMjEwCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uXTogMzEwCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uXTogMjExCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uXTogMzExCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl06IDIxMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25dOiAzMTIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ib29sX2V4dGVuc2lvbl06IHRydWUKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ib29sX2V4dGVuc2lvbl06IGZhbHNlCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl06ICIyMTUiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl06ICIzMTUiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uXTogIjIxNiIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ieXRlc19leHRlbnNpb25dOiAiMzE2IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uXSB7CisgIGE6IDIxNworfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uXSB7CisgIGE6IDMxNworfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0geworICBiYjogMjE4Cit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGJiOiAzMTgKK30KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGM6IDIxOQorfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgYzogMzE5Cit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGQ6IDIyMAorfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl0geworICBkOiAzMjAKK30KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25dOiBCQVIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25dOiBCQVoKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXTogRk9SRUlHTl9CQVIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXTogRk9SRUlHTl9CQVoKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25dOiBJTVBPUlRfQkFSCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXTogSU1QT1JUX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb25dOiAiMjI0IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb25dOiAiMzI0IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uXTogIjIyNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9jb3JkX2V4dGVuc2lvbl06ICIzMjUiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl0geworICBiYjogMjI3Cit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl0geworICBiYjogMzI3Cit9CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9pbnQzMl9leHRlbnNpb25dOiA0MDEKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ludDY0X2V4dGVuc2lvbl06IDQwMgorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbl06IDQwMworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl06IDQwNAorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbl06IDQwNQorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbl06IDQwNgorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25dOiA0MDcKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uXTogNDA4CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb25dOiA0MDkKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbl06IDQxMAorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uXTogNDExCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uXTogNDEyCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9ib29sX2V4dGVuc2lvbl06IGZhbHNlCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uXTogIjQxNSIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl06ICI0MTYiCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb25dOiBGT08KK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0ZPTworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXTogSU1QT1JUX0ZPTworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl06ICI0MjQiCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9jb3JkX2V4dGVuc2lvbl06ICI0MjUiCitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2ZfdWludDMyX2V4dGVuc2lvbl06IDYwMQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0geworICBiYjogNjAyCit9CitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2Zfc3RyaW5nX2V4dGVuc2lvbl06ICI2MDMiCitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2ZfYnl0ZXNfZXh0ZW5zaW9uXTogIjYwNCIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhX3BvaW50eS50eHQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2V4dGVuc2lvbnNfZGF0YV9wb2ludHkudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzMmY3NDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2V4dGVuc2lvbnNfZGF0YV9wb2ludHkudHh0CkBAIC0wLDAgKzEsMTM0IEBACitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uXTogMTAxCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uXTogMTAyCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbl06IDEwMworW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25dOiAxMDQKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uXTogMTA1CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbl06IDEwNgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uXTogMTA3CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25dOiAxMDgKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb25dOiAxMDkKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb25dOiAxMTAKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9mbG9hdF9leHRlbnNpb25dOiAxMTEKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uXTogMTEyCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfYm9vbF9leHRlbnNpb25dOiB0cnVlCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbl06ICIxMTUiCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uXTogIjExNiIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbGdyb3VwX2V4dGVuc2lvbl0gPAorICBhOiAxMTcKKz4KK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgYmI6IDExOAorPgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgYzogMTE5Cis+CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGQ6IDEyMAorPgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEJBWgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl06IElNUE9SVF9CQVoKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uXTogIjEyNCIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9jb3JkX2V4dGVuc2lvbl06ICIxMjUiCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBlOiAxMjYKKz4KK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGJiOiAxMjcKKz4KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQzMl9leHRlbnNpb25dOiAyMDEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQzMl9leHRlbnNpb25dOiAzMDEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25dOiAyMDIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25dOiAzMDIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uXTogMjAzCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl06IDMwMworW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25dOiAyMDQKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uXTogMzA0CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl06IDIwNQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25dOiAzMDUKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uXTogMjA2CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl06IDMwNgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uXTogMjA3CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25dOiAzMDcKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl06IDIwOAorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uXTogMzA4CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uXTogMjA5CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uXTogMzA5CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uXTogMjEwCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uXTogMzEwCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uXTogMjExCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uXTogMzExCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl06IDIxMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25dOiAzMTIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ib29sX2V4dGVuc2lvbl06IHRydWUKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ib29sX2V4dGVuc2lvbl06IGZhbHNlCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl06ICIyMTUiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl06ICIzMTUiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uXTogIjIxNiIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ieXRlc19leHRlbnNpb25dOiAiMzE2IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uXSA8CisgIGE6IDIxNworPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uXSA8CisgIGE6IDMxNworPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBiYjogMjE4Cis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGJiOiAzMTgKKz4KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGM6IDIxOQorPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgYzogMzE5Cis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGQ6IDIyMAorPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBkOiAzMjAKKz4KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25dOiBCQVIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25dOiBCQVoKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXTogRk9SRUlHTl9CQVIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXTogRk9SRUlHTl9CQVoKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25dOiBJTVBPUlRfQkFSCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXTogSU1QT1JUX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb25dOiAiMjI0IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb25dOiAiMzI0IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uXTogIjIyNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9jb3JkX2V4dGVuc2lvbl06ICIzMjUiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBiYjogMjI3Cis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBiYjogMzI3Cis+CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9pbnQzMl9leHRlbnNpb25dOiA0MDEKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ludDY0X2V4dGVuc2lvbl06IDQwMgorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbl06IDQwMworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl06IDQwNAorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbl06IDQwNQorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbl06IDQwNgorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25dOiA0MDcKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uXTogNDA4CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb25dOiA0MDkKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbl06IDQxMAorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uXTogNDExCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uXTogNDEyCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9ib29sX2V4dGVuc2lvbl06IGZhbHNlCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uXTogIjQxNSIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl06ICI0MTYiCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb25dOiBGT08KK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0ZPTworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXTogSU1QT1JUX0ZPTworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl06ICI0MjQiCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9jb3JkX2V4dGVuc2lvbl06ICI0MjUiCitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2ZfdWludDMyX2V4dGVuc2lvbl06IDYwMQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBiYjogNjAyCis+CitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2Zfc3RyaW5nX2V4dGVuc2lvbl06ICI2MDMiCitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2ZfYnl0ZXNfZXh0ZW5zaW9uXTogIjYwNCIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2QwN2IxMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmNjCkBAIC0wLDAgKzEsMjAwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gZW11bGF0ZXMgZ29vZ2xlMy9maWxlL2Jhc2UvZmlsZS5jYworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpZmRlZiBfTVNDX1ZFUgorI2RlZmluZSBXSU4zMl9MRUFOX0FORF9NRUFOICAvLyB5ZWFoLCByaWdodAorI2luY2x1ZGUgPHdpbmRvd3MuaD4gICAgICAgICAvLyBGaW5kKkZpbGUoKS4gIDooCisjaW5jbHVkZSA8aW8uaD4KKyNpbmNsdWRlIDxkaXJlY3QuaD4KKyNlbHNlCisjaW5jbHVkZSA8ZGlyZW50Lmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxlcnJuby5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyNpZmRlZiBfV0lOMzIKKyNkZWZpbmUgbWtkaXIobmFtZSwgbW9kZSkgbWtkaXIobmFtZSkKKy8vIFdpbmRvd3MgZG9lc24ndCBoYXZlIHN5bWJvbGljIGxpbmtzLgorI2RlZmluZSBsc3RhdCBzdGF0CisjaWZuZGVmIEZfT0sKKyNkZWZpbmUgRl9PSyAwMCAgLy8gbm90IGRlZmluZWQgYnkgTVNWQyBmb3Igd2hhdGV2ZXIgcmVhc29uCisjZW5kaWYKKyNlbmRpZgorCitib29sIEZpbGU6OkV4aXN0cyhjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgcmV0dXJuIGFjY2VzcyhuYW1lLmNfc3RyKCksIEZfT0spID09IDA7Cit9CisKK2Jvb2wgRmlsZTo6UmVhZEZpbGVUb1N0cmluZyhjb25zdCBzdHJpbmcmIG5hbWUsIHN0cmluZyogb3V0cHV0KSB7CisgIGNoYXIgYnVmZmVyWzEwMjRdOworICBGSUxFKiBmaWxlID0gZm9wZW4obmFtZS5jX3N0cigpLCAicmIiKTsKKyAgaWYgKGZpbGUgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgc2l6ZV90IG4gPSBmcmVhZChidWZmZXIsIDEsIHNpemVvZihidWZmZXIpLCBmaWxlKTsKKyAgICBpZiAobiA8PSAwKSBicmVhazsKKyAgICBvdXRwdXQtPmFwcGVuZChidWZmZXIsIG4pOworICB9CisKKyAgaW50IGVycm9yID0gZmVycm9yKGZpbGUpOworICBpZiAoZmNsb3NlKGZpbGUpICE9IDApIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIGVycm9yID09IDA7Cit9CisKK3ZvaWQgRmlsZTo6UmVhZEZpbGVUb1N0cmluZ09yRGllKGNvbnN0IHN0cmluZyYgbmFtZSwgc3RyaW5nKiBvdXRwdXQpIHsKKyAgR09PR0xFX0NIRUNLKFJlYWRGaWxlVG9TdHJpbmcobmFtZSwgb3V0cHV0KSkgPDwgIkNvdWxkIG5vdCByZWFkOiAiIDw8IG5hbWU7Cit9CisKK2Jvb2wgRmlsZTo6V3JpdGVTdHJpbmdUb0ZpbGUoY29uc3Qgc3RyaW5nJiBjb250ZW50cywgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEZJTEUqIGZpbGUgPSBmb3BlbihuYW1lLmNfc3RyKCksICJ3YiIpOworICBpZiAoZmlsZSA9PSBOVUxMKSB7CisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgImZvcGVuKCIgPDwgbmFtZSA8PCAiLCBcIndiXCIpOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoZndyaXRlKGNvbnRlbnRzLmRhdGEoKSwgMSwgY29udGVudHMuc2l6ZSgpLCBmaWxlKSAhPSBjb250ZW50cy5zaXplKCkpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiZndyaXRlKCIgPDwgbmFtZSA8PCAiKTogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaWYgKGZjbG9zZShmaWxlKSAhPSAwKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpbGU6OldyaXRlU3RyaW5nVG9GaWxlT3JEaWUoY29uc3Qgc3RyaW5nJiBjb250ZW50cywgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEZJTEUqIGZpbGUgPSBmb3BlbihuYW1lLmNfc3RyKCksICJ3YiIpOworICBHT09HTEVfQ0hFQ0soZmlsZSAhPSBOVUxMKQorICAgICAgPDwgImZvcGVuKCIgPDwgbmFtZSA8PCAiLCBcIndiXCIpOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgR09PR0xFX0NIRUNLX0VRKGZ3cml0ZShjb250ZW50cy5kYXRhKCksIDEsIGNvbnRlbnRzLnNpemUoKSwgZmlsZSksCisgICAgICAgICAgICAgICAgICBjb250ZW50cy5zaXplKCkpCisgICAgICA8PCAiZndyaXRlKCIgPDwgbmFtZSA8PCAiKTogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgIEdPT0dMRV9DSEVDSyhmY2xvc2UoZmlsZSkgPT0gMCkKKyAgICAgIDw8ICJmY2xvc2UoIiA8PCBuYW1lIDw8ICIpOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKK30KKworYm9vbCBGaWxlOjpDcmVhdGVEaXIoY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbW9kZSkgeworICByZXR1cm4gbWtkaXIobmFtZS5jX3N0cigpLCBtb2RlKSA9PSAwOworfQorCitib29sIEZpbGU6OlJlY3Vyc2l2ZWx5Q3JlYXRlRGlyKGNvbnN0IHN0cmluZyYgcGF0aCwgaW50IG1vZGUpIHsKKyAgaWYgKENyZWF0ZURpcihwYXRoLCBtb2RlKSkgcmV0dXJuIHRydWU7CisKKyAgaWYgKEV4aXN0cyhwYXRoKSkgcmV0dXJuIGZhbHNlOworCisgIC8vIFRyeSBjcmVhdGluZyB0aGUgcGFyZW50LgorICBzdHJpbmc6OnNpemVfdHlwZSBzbGFzaHBvcyA9IHBhdGguZmluZF9sYXN0X29mKCcvJyk7CisgIGlmIChzbGFzaHBvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAvLyBObyBwYXJlbnQgZ2l2ZW4uCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIFJlY3Vyc2l2ZWx5Q3JlYXRlRGlyKHBhdGguc3Vic3RyKDAsIHNsYXNocG9zKSwgbW9kZSkgJiYKKyAgICAgICAgIENyZWF0ZURpcihwYXRoLCBtb2RlKTsKK30KKwordm9pZCBGaWxlOjpEZWxldGVSZWN1cnNpdmVseShjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIGR1bW15MSwgdm9pZCogZHVtbXkyKSB7CisgIGlmIChuYW1lLmVtcHR5KCkpIHJldHVybjsKKworICAvLyBXZSBkb24ndCBjYXJlIHRvbyBtdWNoIGFib3V0IGVycm9yIGNoZWNraW5nIGhlcmUgc2luY2UgdGhpcyBpcyBvbmx5IHVzZWQKKyAgLy8gaW4gdGVzdHMgdG8gZGVsZXRlIHRlbXBvcmFyeSBkaXJlY3RvcmllcyB0aGF0IGFyZSB1bmRlciAvdG1wIGFueXdheS4KKworI2lmZGVmIF9NU0NfVkVSCisgIC8vIFRoaXMgaW50ZXJmYWNlIGlzIHNvIHdlaXJkLgorICBXSU4zMl9GSU5EX0RBVEEgZmluZF9kYXRhOworICBIQU5ETEUgZmluZF9oYW5kbGUgPSBGaW5kRmlyc3RGaWxlKChuYW1lICsgIi8qIikuY19zdHIoKSwgJmZpbmRfZGF0YSk7CisgIGlmIChmaW5kX2hhbmRsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgeworICAgIC8vIEp1c3QgZGVsZXRlIGl0LCB3aGF0ZXZlciBpdCBpcy4KKyAgICBEZWxldGVGaWxlKG5hbWUuY19zdHIoKSk7CisgICAgUmVtb3ZlRGlyZWN0b3J5KG5hbWUuY19zdHIoKSk7CisgICAgcmV0dXJuOworICB9CisKKyAgZG8geworICAgIHN0cmluZyBlbnRyeV9uYW1lID0gZmluZF9kYXRhLmNGaWxlTmFtZTsKKyAgICBpZiAoZW50cnlfbmFtZSAhPSAiLiIgJiYgZW50cnlfbmFtZSAhPSAiLi4iKSB7CisgICAgICBzdHJpbmcgcGF0aCA9IG5hbWUgKyAiLyIgKyBlbnRyeV9uYW1lOworICAgICAgaWYgKGZpbmRfZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CisgICAgICAgIERlbGV0ZVJlY3Vyc2l2ZWx5KHBhdGgsIE5VTEwsIE5VTEwpOworICAgICAgICBSZW1vdmVEaXJlY3RvcnkocGF0aC5jX3N0cigpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIERlbGV0ZUZpbGUocGF0aC5jX3N0cigpKTsKKyAgICAgIH0KKyAgICB9CisgIH0gd2hpbGUoRmluZE5leHRGaWxlKGZpbmRfaGFuZGxlLCAmZmluZF9kYXRhKSk7CisgIEZpbmRDbG9zZShmaW5kX2hhbmRsZSk7CisKKyAgUmVtb3ZlRGlyZWN0b3J5KG5hbWUuY19zdHIoKSk7CisjZWxzZQorICAvLyBVc2Ugb3BlbmRpcigpISAgWWF5IQorICAvLyBsc3RhdCA9IERvbid0IGZvbGxvdyBzeW1ib2xpYyBsaW5rcy4KKyAgc3RydWN0IHN0YXQgc3RhdHM7CisgIGlmIChsc3RhdChuYW1lLmNfc3RyKCksICZzdGF0cykgIT0gMCkgcmV0dXJuOworCisgIGlmIChTX0lTRElSKHN0YXRzLnN0X21vZGUpKSB7CisgICAgRElSKiBkaXIgPSBvcGVuZGlyKG5hbWUuY19zdHIoKSk7CisgICAgaWYgKGRpciAhPSBOVUxMKSB7CisgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICBzdHJ1Y3QgZGlyZW50KiBlbnRyeSA9IHJlYWRkaXIoZGlyKTsKKyAgICAgICAgaWYgKGVudHJ5ID09IE5VTEwpIGJyZWFrOworICAgICAgICBzdHJpbmcgZW50cnlfbmFtZSA9IGVudHJ5LT5kX25hbWU7CisgICAgICAgIGlmIChlbnRyeV9uYW1lICE9ICIuIiAmJiBlbnRyeV9uYW1lICE9ICIuLiIpIHsKKyAgICAgICAgICBEZWxldGVSZWN1cnNpdmVseShuYW1lICsgIi8iICsgZW50cnlfbmFtZSwgTlVMTCwgTlVMTCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBjbG9zZWRpcihkaXIpOworICAgIHJtZGlyKG5hbWUuY19zdHIoKSk7CisKKyAgfSBlbHNlIGlmIChTX0lTUkVHKHN0YXRzLnN0X21vZGUpKSB7CisgICAgcmVtb3ZlKG5hbWUuY19zdHIoKSk7CisgIH0KKyNlbmRpZgorfQorCitib29sIEZpbGU6OkNoYW5nZVdvcmtpbmdEaXJlY3RvcnkoY29uc3Qgc3RyaW5nJiBuZXdfd29ya2luZ19kaXJlY3RvcnkpIHsKKyAgcmV0dXJuIGNoZGlyKG5ld193b3JraW5nX2RpcmVjdG9yeS5jX3N0cigpKSA9PSAwOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmNjNmODAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oCkBAIC0wLDAgKzEsMTAwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gZW11bGF0ZXMgZ29vZ2xlMy9maWxlL2Jhc2UvZmlsZS5oCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1RFU1RJTkdfRklMRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1RFU1RJTkdfRklMRV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjb25zdCBpbnQgREVGQVVMVF9GSUxFX01PREUgPSAwNzc3OworCisvLyBQcm90b2NvbCBidWZmZXIgY29kZSBvbmx5IHVzZXMgYSBjb3VwbGUgc3RhdGljIG1ldGhvZHMgb2YgRmlsZSwgYW5kIG9ubHkKKy8vIGluIHRlc3RzLgorY2xhc3MgRmlsZSB7CisgcHVibGljOgorICAvLyBDaGVjayBpZiB0aGUgZmlsZSBleGlzdHMuCisgIHN0YXRpYyBib29sIEV4aXN0cyhjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIFJlYWQgYW4gZW50aXJlIGZpbGUgdG8gYSBzdHJpbmcuICBSZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLCBmYWxzZQorICAvLyBvdGhlcndpc2UuCisgIHN0YXRpYyBib29sIFJlYWRGaWxlVG9TdHJpbmcoY29uc3Qgc3RyaW5nJiBuYW1lLCBzdHJpbmcqIG91dHB1dCk7CisKKyAgLy8gU2FtZSBhcyBhYm92ZSwgYnV0IGNyYXNoIG9uIGZhaWx1cmUuCisgIHN0YXRpYyB2b2lkIFJlYWRGaWxlVG9TdHJpbmdPckRpZShjb25zdCBzdHJpbmcmIG5hbWUsIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBDcmVhdGUgYSBmaWxlIGFuZCB3cml0ZSBhIHN0cmluZyB0byBpdC4KKyAgc3RhdGljIGJvb2wgV3JpdGVTdHJpbmdUb0ZpbGUoY29uc3Qgc3RyaW5nJiBjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICAvLyBTYW1lIGFzIGFib3ZlLCBidXQgY3Jhc2ggb24gZmFpbHVyZS4KKyAgc3RhdGljIHZvaWQgV3JpdGVTdHJpbmdUb0ZpbGVPckRpZShjb25zdCBzdHJpbmcmIGNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5LgorICBzdGF0aWMgYm9vbCBDcmVhdGVEaXIoY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbW9kZSk7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGFuZCBhbGwgcGFyZW50IGRpcmVjdG9yaWVzIGlmIG5lY2Vzc2FyeS4KKyAgc3RhdGljIGJvb2wgUmVjdXJzaXZlbHlDcmVhdGVEaXIoY29uc3Qgc3RyaW5nJiBwYXRoLCBpbnQgbW9kZSk7CisKKyAgLy8gSWYgIm5hbWUiIGlzIGEgZmlsZSwgd2UgZGVsZXRlIGl0LiAgSWYgaXQgaXMgYSBkaXJlY3RvcnksIHdlCisgIC8vIGNhbGwgRGVsZXRlUmVjdXJzaXZlbHkoKSBmb3IgZWFjaCBmaWxlIG9yIGRpcmVjdG9yeSAob3RoZXIgdGhhbgorICAvLyBkb3QgYW5kIGRvdWJsZS1kb3QpIHdpdGhpbiBpdCwgYW5kIHRoZW4gZGVsZXRlIHRoZSBkaXJlY3RvcnkgaXRzZWxmLgorICAvLyBUaGUgImR1bW15IiBwYXJhbWV0ZXJzIGhhdmUgYSBtZWFuaW5nIGluIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKKyAgLy8gbWV0aG9kIGJ1dCB0aGV5IGFyZSBub3QgdXNlZCBhbnl3aGVyZSBpbiBwcm90b2NvbCBidWZmZXJzLgorICBzdGF0aWMgdm9pZCBEZWxldGVSZWN1cnNpdmVseShjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIGR1bW15MSwgdm9pZCogZHVtbXkyKTsKKworICAvLyBDaGFuZ2Ugd29ya2luZyBkaXJlY3RvcnkgdG8gZ2l2ZW4gZGlyZWN0b3J5LgorICBzdGF0aWMgYm9vbCBDaGFuZ2VXb3JraW5nRGlyZWN0b3J5KGNvbnN0IHN0cmluZyYgbmV3X3dvcmtpbmdfZGlyZWN0b3J5KTsKKworICBzdGF0aWMgYm9vbCBHZXRDb250ZW50cygKKyAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgc3RyaW5nKiBvdXRwdXQsIGJvb2wgLyppc19kZWZhdWx0Ki8pIHsKKyAgICByZXR1cm4gUmVhZEZpbGVUb1N0cmluZyhuYW1lLCBvdXRwdXQpOworICB9CisKKyAgc3RhdGljIGJvb2wgU2V0Q29udGVudHMoCisgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyYgY29udGVudHMsIGJvb2wgLyppc19kZWZhdWx0Ki8pIHsKKyAgICByZXR1cm4gV3JpdGVTdHJpbmdUb0ZpbGUoY29udGVudHMsIG5hbWUpOworICB9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmlsZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVEVTVElOR19GSUxFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNzJmYTVjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuY2MKQEAgLTAsMCArMSwyNTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBlbXVsYXRlcyBnb29nbGUzL3Rlc3RpbmcvYmFzZS9wdWJsaWMvZ29vZ2xldGVzdC5jYworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpZmRlZiBfTVNDX1ZFUgorI2luY2x1ZGUgPGlvLmg+CisjaW5jbHVkZSA8ZGlyZWN0Lmg+CisjZWxzZQorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPGZzdHJlYW0+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworI2lmZGVmIF9XSU4zMgorI2RlZmluZSBta2RpcihuYW1lLCBtb2RlKSBta2RpcihuYW1lKQorI2VuZGlmCisKKyNpZm5kZWYgT19CSU5BUlkKKyNpZmRlZiBfT19CSU5BUlkKKyNkZWZpbmUgT19CSU5BUlkgX09fQklOQVJZCisjZWxzZQorI2RlZmluZSBPX0JJTkFSWSAwICAgICAvLyBJZiB0aGlzIGlzbid0IGRlZmluZWQsIHRoZSBwbGF0Zm9ybSBkb2Vzbid0IG5lZWQgaXQuCisjZW5kaWYKKyNlbmRpZgorCitzdHJpbmcgVGVzdFNvdXJjZURpcigpIHsKKyNpZmRlZiBfTVNDX1ZFUgorICAvLyBMb29rIGZvciB0aGUgInNyYyIgZGlyZWN0b3J5LgorICBzdHJpbmcgcHJlZml4ID0gIi4iOworCisgIHdoaWxlICghRmlsZTo6RXhpc3RzKHByZWZpeCArICIvc3JjL2dvb2dsZS9wcm90b2J1ZiIpKSB7CisgICAgaWYgKCFGaWxlOjpFeGlzdHMocHJlZml4KSkgeworICAgICAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICAgICAgPDwgIkNvdWxkIG5vdCBmaW5kIHByb3RvYnVmIHNvdXJjZSBjb2RlLiAgUGxlYXNlIHJ1biB0ZXN0cyBmcm9tICIKKyAgICAgICAgICAgInNvbWV3aGVyZSB3aXRoaW4gdGhlIHByb3RvYnVmIHNvdXJjZSBwYWNrYWdlLiI7CisgICAgfQorICAgIHByZWZpeCArPSAiLy4uIjsKKyAgfQorICByZXR1cm4gcHJlZml4ICsgIi9zcmMiOworI2Vsc2UKKyAgLy8gYXV0b21ha2Ugc2V0cyB0aGUgInNyY2RpciIgZW52aXJvbm1lbnQgdmFyaWFibGUuCisgIGNoYXIqIHJlc3VsdCA9IGdldGVudigic3JjZGlyIik7CisgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgIC8vIE90aGVyd2lzZSwgdGhlIHRlc3QgbXVzdCBiZSBydW4gZnJvbSB0aGUgc291cmNlIGRpcmVjdG9yeS4KKyAgICByZXR1cm4gIi4iOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyNlbmRpZgorfQorCituYW1lc3BhY2UgeworCitzdHJpbmcgR2V0VGVtcG9yYXJ5RGlyZWN0b3J5TmFtZSgpIHsKKyAgLy8gdG1wbmFtKCkgaXMgZ2VuZXJhbGx5IG5vdCBjb25zaWRlcmVkIHNhZmUgYnV0IHdlJ3JlIG9ubHkgdXNpbmcgaXQgZm9yCisgIC8vIHRlc3RpbmcuICBXZSBjYW5ub3QgdXNlIHRtcGZpbGUoKSBvciBta3N0ZW1wKCkgc2luY2Ugd2UncmUgY3JlYXRpbmcgYQorICAvLyBkaXJlY3RvcnkuCisgIGNoYXIgYltMX3RtcG5hbSArIDFdOyAgICAgLy8gSFBVWCBtdWx0aXRocmVhZCByZXR1cm4gMCBpZiBzIGlzIDAKKyAgc3RyaW5nIHJlc3VsdCA9IHRtcG5hbShiKTsKKyNpZmRlZiBfV0lOMzIKKyAgLy8gT24gV2luMzIsIHRtcG5hbSgpIHJldHVybnMgYSBmaWxlIHByZWZpeGVkIHdpdGggJ1wnLCBidXQgd2hpY2ggaXMgc3VwcG9zZWQKKyAgLy8gdG8gYmUgdXNlZCBpbiB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4gIFdURj8KKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhyZXN1bHQsICJcXCIpKSB7CisgICAgcmVzdWx0LmVyYXNlKDAsIDEpOworICB9CisjZW5kaWYgIC8vIF9XSU4zMgorICByZXR1cm4gcmVzdWx0OworfQorCisvLyBDcmVhdGVzIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeSBvbiBkZW1hbmQgYW5kIGRlbGV0ZXMgaXQgd2hlbiB0aGUgcHJvY2VzcworLy8gcXVpdHMuCitjbGFzcyBUZW1wRGlyRGVsZXRlciB7CisgcHVibGljOgorICBUZW1wRGlyRGVsZXRlcigpIHt9CisgIH5UZW1wRGlyRGVsZXRlcigpIHsKKyAgICBpZiAoIW5hbWVfLmVtcHR5KCkpIHsKKyAgICAgIEZpbGU6OkRlbGV0ZVJlY3Vyc2l2ZWx5KG5hbWVfLCBOVUxMLCBOVUxMKTsKKyAgICB9CisgIH0KKworICBzdHJpbmcgR2V0VGVtcERpcigpIHsKKyAgICBpZiAobmFtZV8uZW1wdHkoKSkgeworICAgICAgbmFtZV8gPSBHZXRUZW1wb3JhcnlEaXJlY3RvcnlOYW1lKCk7CisgICAgICBHT09HTEVfQ0hFQ0sobWtkaXIobmFtZV8uY19zdHIoKSwgMDc3NykgPT0gMCkgPDwgc3RyZXJyb3IoZXJybm8pOworCisgICAgICAvLyBTdGljayBhIGZpbGUgaW4gdGhlIGRpcmVjdG9yeSB0aGF0IHRlbGxzIHBlb3BsZSB3aGF0IHRoaXMgaXMsIGluIGNhc2UKKyAgICAgIC8vIHdlIGFib3J0IGFuZCBkb24ndCBnZXQgYSBjaGFuY2UgdG8gZGVsZXRlIGl0LgorICAgICAgRmlsZTo6V3JpdGVTdHJpbmdUb0ZpbGVPckRpZSgiIiwgbmFtZV8gKyAiL1RFTVBfRElSX0ZPUl9QUk9UT0JVRl9URVNUUyIpOworICAgIH0KKyAgICByZXR1cm4gbmFtZV87CisgIH0KKworIHByaXZhdGU6CisgIHN0cmluZyBuYW1lXzsKK307CisKK1RlbXBEaXJEZWxldGVyIHRlbXBfZGlyX2RlbGV0ZXJfOworCit9ICAvLyBuYW1lc3BhY2UKKworc3RyaW5nIFRlc3RUZW1wRGlyKCkgeworICByZXR1cm4gdGVtcF9kaXJfZGVsZXRlcl8uR2V0VGVtcERpcigpOworfQorCisvLyBUT0RPKGtlbnRvbik6ICBTaGFyZSBkdXBsaWNhdGVkIGNvZGUgYmVsb3cuICBUb28gYnVzeS9sYXp5IGZvciBub3cuCisKK3N0YXRpYyBzdHJpbmcgc3Rkb3V0X2NhcHR1cmVfZmlsZW5hbWVfOworc3RhdGljIHN0cmluZyBzdGRlcnJfY2FwdHVyZV9maWxlbmFtZV87CitzdGF0aWMgaW50IG9yaWdpbmFsX3N0ZG91dF8gPSAtMTsKK3N0YXRpYyBpbnQgb3JpZ2luYWxfc3RkZXJyXyA9IC0xOworCit2b2lkIENhcHR1cmVUZXN0U3Rkb3V0KCkgeworICBHT09HTEVfQ0hFQ0tfRVEob3JpZ2luYWxfc3Rkb3V0XywgLTEpIDw8ICJBbHJlYWR5IGNhcHR1cmluZy4iOworCisgIHN0ZG91dF9jYXB0dXJlX2ZpbGVuYW1lXyA9IFRlc3RUZW1wRGlyKCkgKyAiL2NhcHR1cmVkX3N0ZG91dCI7CisKKyAgaW50IGZkID0gb3BlbihzdGRvdXRfY2FwdHVyZV9maWxlbmFtZV8uY19zdHIoKSwKKyAgICAgICAgICAgICAgICBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX0VYQ0wgfCBPX0JJTkFSWSwgMDc3Nyk7CisgIEdPT0dMRV9DSEVDSyhmZCA+PSAwKSA8PCAib3BlbjogIiA8PCBzdHJlcnJvcihlcnJubyk7CisKKyAgb3JpZ2luYWxfc3Rkb3V0XyA9IGR1cCgxKTsKKyAgY2xvc2UoMSk7CisgIGR1cDIoZmQsIDEpOworICBjbG9zZShmZCk7Cit9CisKK3ZvaWQgQ2FwdHVyZVRlc3RTdGRlcnIoKSB7CisgIEdPT0dMRV9DSEVDS19FUShvcmlnaW5hbF9zdGRlcnJfLCAtMSkgPDwgIkFscmVhZHkgY2FwdHVyaW5nLiI7CisKKyAgc3RkZXJyX2NhcHR1cmVfZmlsZW5hbWVfID0gVGVzdFRlbXBEaXIoKSArICIvY2FwdHVyZWRfc3RkZXJyIjsKKworICBpbnQgZmQgPSBvcGVuKHN0ZGVycl9jYXB0dXJlX2ZpbGVuYW1lXy5jX3N0cigpLAorICAgICAgICAgICAgICAgIE9fV1JPTkxZIHwgT19DUkVBVCB8IE9fRVhDTCB8IE9fQklOQVJZLCAwNzc3KTsKKyAgR09PR0xFX0NIRUNLKGZkID49IDApIDw8ICJvcGVuOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKworICBvcmlnaW5hbF9zdGRlcnJfID0gZHVwKDIpOworICBjbG9zZSgyKTsKKyAgZHVwMihmZCwgMik7CisgIGNsb3NlKGZkKTsKK30KKworc3RyaW5nIEdldENhcHR1cmVkVGVzdFN0ZG91dCgpIHsKKyAgR09PR0xFX0NIRUNLX05FKG9yaWdpbmFsX3N0ZG91dF8sIC0xKSA8PCAiTm90IGNhcHR1cmluZy4iOworCisgIGNsb3NlKDEpOworICBkdXAyKG9yaWdpbmFsX3N0ZG91dF8sIDEpOworICBvcmlnaW5hbF9zdGRvdXRfID0gLTE7CisKKyAgc3RyaW5nIHJlc3VsdDsKKyAgRmlsZTo6UmVhZEZpbGVUb1N0cmluZ09yRGllKHN0ZG91dF9jYXB0dXJlX2ZpbGVuYW1lXywgJnJlc3VsdCk7CisKKyAgcmVtb3ZlKHN0ZG91dF9jYXB0dXJlX2ZpbGVuYW1lXy5jX3N0cigpKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgR2V0Q2FwdHVyZWRUZXN0U3RkZXJyKCkgeworICBHT09HTEVfQ0hFQ0tfTkUob3JpZ2luYWxfc3RkZXJyXywgLTEpIDw8ICJOb3QgY2FwdHVyaW5nLiI7CisKKyAgY2xvc2UoMik7CisgIGR1cDIob3JpZ2luYWxfc3RkZXJyXywgMik7CisgIG9yaWdpbmFsX3N0ZGVycl8gPSAtMTsKKworICBzdHJpbmcgcmVzdWx0OworICBGaWxlOjpSZWFkRmlsZVRvU3RyaW5nT3JEaWUoc3RkZXJyX2NhcHR1cmVfZmlsZW5hbWVfLCAmcmVzdWx0KTsKKworICByZW1vdmUoc3RkZXJyX2NhcHR1cmVfZmlsZW5hbWVfLmNfc3RyKCkpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK1Njb3BlZE1lbW9yeUxvZyogU2NvcGVkTWVtb3J5TG9nOjphY3RpdmVfbG9nXyA9IE5VTEw7CisKK1Njb3BlZE1lbW9yeUxvZzo6U2NvcGVkTWVtb3J5TG9nKCkgeworICBHT09HTEVfQ0hFQ0soYWN0aXZlX2xvZ18gPT0gTlVMTCk7CisgIGFjdGl2ZV9sb2dfID0gdGhpczsKKyAgb2xkX2hhbmRsZXJfID0gU2V0TG9nSGFuZGxlcigmSGFuZGxlTG9nKTsKK30KKworU2NvcGVkTWVtb3J5TG9nOjp+U2NvcGVkTWVtb3J5TG9nKCkgeworICBTZXRMb2dIYW5kbGVyKG9sZF9oYW5kbGVyXyk7CisgIGFjdGl2ZV9sb2dfID0gTlVMTDsKK30KKworY29uc3QgdmVjdG9yPHN0cmluZz4mIFNjb3BlZE1lbW9yeUxvZzo6R2V0TWVzc2FnZXMoTG9nTGV2ZWwgbGV2ZWwpIHsKKyAgR09PR0xFX0NIRUNLKGxldmVsID09IEVSUk9SIHx8CisgICAgICAgICAgICAgICBsZXZlbCA9PSBXQVJOSU5HKTsKKyAgcmV0dXJuIG1lc3NhZ2VzX1tsZXZlbF07Cit9CisKK3ZvaWQgU2NvcGVkTWVtb3J5TG9nOjpIYW5kbGVMb2coTG9nTGV2ZWwgbGV2ZWwsIGNvbnN0IGNoYXIqIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGluZSwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgIEdPT0dMRV9DSEVDSyhhY3RpdmVfbG9nXyAhPSBOVUxMKTsKKyAgaWYgKGxldmVsID09IEVSUk9SIHx8IGxldmVsID09IFdBUk5JTkcpIHsKKyAgICBhY3RpdmVfbG9nXy0+bWVzc2FnZXNfW2xldmVsXS5wdXNoX2JhY2sobWVzc2FnZSk7CisgIH0KK30KKworbmFtZXNwYWNlIHsKKworLy8gRm9yY2Ugc2h1dGRvd24gYXQgcHJvY2VzcyBleGl0IHNvIHRoYXQgd2UgY2FuIHRlc3QgZm9yIG1lbW9yeSBsZWFrcy4gIFRvCisvLyBhY3R1YWxseSBjaGVjayBmb3IgbGVha3MsIEkgc3VnZ2VzdCB1c2luZyB0aGUgaGVhcCBjaGVja2VyIGluY2x1ZGVkIHdpdGgKKy8vIGdvb2dsZS1wZXJmdG9vbHMuICBTZXQgaXQgdG8gImRyYWNvbmlhbiIgbW9kZSB0byBlbnN1cmUgdGhhdCBldmVyeSBsYXN0CisvLyBjYWxsIHRvIG1hbGxvYygpIGhhcyBhIGNvcnJlc3BvbmRpbmcgZnJlZSgpLgorc3RydWN0IEZvcmNlU2h1dGRvd24geworICB+Rm9yY2VTaHV0ZG93bigpIHsKKyAgICBTaHV0ZG93blByb3RvYnVmTGlicmFyeSgpOworICB9Cit9IGZvcmNlX3NodXRkb3duOworCit9ICAvLyBuYW1lc3BhY2UKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMGQ5OWU2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaApAQCAtMCwwICsxLDEwMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vIGVtdWxhdGVzIGdvb2dsZTMvdGVzdGluZy9iYXNlL3B1YmxpYy9nb29nbGV0ZXN0LmgKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfR09PR0xFVEVTVF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0dPT0dMRVRFU1RfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworLy8gRGlzYWJsZSBkZWF0aCB0ZXN0cyBpZiB3ZSB1c2UgZXhjZXB0aW9ucyBpbiBDSEVDSygpLgorI2lmICFQUk9UT0JVRl9VU0VfRVhDRVBUSU9OUyAmJiBkZWZpbmVkKEdURVNUX0hBU19ERUFUSF9URVNUKQorI2RlZmluZSBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorI2VuZGlmCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gV2hlbiBydW5uaW5nIHVuaXR0ZXN0cywgZ2V0IHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgc291cmNlIGNvZGUuCitzdHJpbmcgVGVzdFNvdXJjZURpcigpOworCisvLyBXaGVuIHJ1bm5pbmcgdW5pdHRlc3RzLCBnZXQgYSBkaXJlY3Rvcnkgd2hlcmUgdGVtcG9yYXJ5IGZpbGVzIG1heSBiZQorLy8gcGxhY2VkLgorc3RyaW5nIFRlc3RUZW1wRGlyKCk7CisKKy8vIENhcHR1cmUgYWxsIHRleHQgd3JpdHRlbiB0byBzdGRvdXQgb3Igc3RkZXJyLgordm9pZCBDYXB0dXJlVGVzdFN0ZG91dCgpOwordm9pZCBDYXB0dXJlVGVzdFN0ZGVycigpOworCisvLyBTdG9wIGNhcHR1cmluZyBzdGRvdXQgb3Igc3RkZXJyIGFuZCByZXR1cm4gdGhlIHRleHQgY2FwdHVyZWQuCitzdHJpbmcgR2V0Q2FwdHVyZWRUZXN0U3Rkb3V0KCk7CitzdHJpbmcgR2V0Q2FwdHVyZWRUZXN0U3RkZXJyKCk7CisKKy8vIEZvciB1c2Ugd2l0aCBTY29wZWRNZW1vcnlMb2c6OkdldE1lc3NhZ2VzKCkuICBJbnNpZGUgR29vZ2xlIHRoZSBMb2dMZXZlbAorLy8gY29uc3RhbnRzIGRvbid0IGhhdmUgdGhlIExPR0xFVkVMXyBwcmVmaXgsIHNvIHRoZSBjb2RlIHRoYXQgdXNlZAorLy8gU2NvcGVkTWVtb3J5TG9nIHJlZmVycyB0byBMT0dMRVZFTF9FUlJPUiBhcyBqdXN0IEVSUk9SLgorI3VuZGVmIEVSUk9SICAvLyBkZWZlbmQgYWdhaW5zdCBwcm9taXNjdW91cyB3aW5kb3dzLmgKK3N0YXRpYyBjb25zdCBMb2dMZXZlbCBFUlJPUiA9IExPR0xFVkVMX0VSUk9SOworc3RhdGljIGNvbnN0IExvZ0xldmVsIFdBUk5JTkcgPSBMT0dMRVZFTF9XQVJOSU5HOworCisvLyBSZWNlaXZlcyBjb3BpZXMgb2YgYWxsIExPRyhFUlJPUikgbWVzc2FnZXMgd2hpbGUgaW4gc2NvcGUuICBTYW1wbGUgdXNhZ2U6CisvLyAgIHsKKy8vICAgICBTY29wZWRNZW1vcnlMb2cgbG9nOyAgLy8gY29uc3RydWN0b3IgcmVnaXN0ZXJzIG9iamVjdCBhcyBhIGxvZyBzaW5rCisvLyAgICAgU29tZVJvdXRpbmVUaGF0TWF5TG9nTWVzc2FnZXMoKTsKKy8vICAgICBjb25zdCB2ZWN0b3I8c3RyaW5nPiYgd2FybmluZ3MgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworLy8gICB9ICAvLyBkZXN0cnVjdG9yIHVucmVnaXN0ZXJzIG9iamVjdCBhcyBhIGxvZyBzaW5rCisvLyBUaGlzIGlzIGEgZHVtbXkgaW1wbGVtZW50YXRpb24gd2hpY2ggY292ZXJzIG9ubHkgd2hhdCBpcyB1c2VkIGJ5IHByb3RvY29sCisvLyBidWZmZXIgdW5pdCB0ZXN0cy4KK2NsYXNzIFNjb3BlZE1lbW9yeUxvZyB7CisgcHVibGljOgorICBTY29wZWRNZW1vcnlMb2coKTsKKyAgdmlydHVhbCB+U2NvcGVkTWVtb3J5TG9nKCk7CisKKyAgLy8gRmV0Y2hlcyBhbGwgbWVzc2FnZXMgd2l0aCB0aGUgZ2l2ZW4gc2V2ZXJpdHkgbGV2ZWwuCisgIGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBHZXRNZXNzYWdlcyhMb2dMZXZlbCBlcnJvcik7CisKKyBwcml2YXRlOgorICBtYXA8TG9nTGV2ZWwsIHZlY3RvcjxzdHJpbmc+ID4gbWVzc2FnZXNfOworICBMb2dIYW5kbGVyKiBvbGRfaGFuZGxlcl87CisKKyAgc3RhdGljIHZvaWQgSGFuZGxlTG9nKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpOworCisgIHN0YXRpYyBTY29wZWRNZW1vcnlMb2cqIGFjdGl2ZV9sb2dfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTY29wZWRNZW1vcnlMb2cpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0dPT0dMRVRFU1RfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvemNndW56aXAuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvemNndW56aXAuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFmNzRmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy96Y2d1bnppcC5jYwpAQCAtMCwwICsxLDczIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA5IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBicmlhbm9sc29uQGdvb2dsZS5jb20gKEJyaWFuIE9sc29uKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGVzdCBwcm9ncmFtIHRvIHZlcmlmeSB0aGF0IEd6aXBJbnB1dFN0cmVhbSBpcyBjb21wYXRpYmxlIHdpdGggY29tbWFuZCBsaW5lCisvLyBndW56aXAgb3IgamF2YS51dGlsLnppcC5HemlwSW5wdXRTdHJlYW0KKy8vCisvLyBSZWFkcyBnemlwIHN0cmVhbSBvbiBzdGFuZGFyZCBpbnB1dCBhbmQgd3JpdGVzIGRlY29tcHJlc3NlZCBkYXRhIHRvIHN0YW5kYXJkCisvLyBvdXRwdXQuCisKKyNpbmNsdWRlICJjb25maWcuaCIKKworI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkZpbGVJbnB1dFN0cmVhbTsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpHemlwSW5wdXRTdHJlYW07CisKK2ludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyKiogYXJndikgeworICBGaWxlSW5wdXRTdHJlYW0gZmluKFNURElOX0ZJTEVOTyk7CisgIEd6aXBJbnB1dFN0cmVhbSBpbigmZmluKTsKKworICB3aGlsZSAodHJ1ZSkgeworICAgIGNvbnN0IHZvaWQqIGlucHRyOworICAgIGludCBpbmxlbjsKKyAgICBib29sIG9rOworICAgIG9rID0gaW4uTmV4dCgmaW5wdHIsICZpbmxlbik7CisgICAgaWYgKCFvaykgeworICAgICAgYnJlYWs7CisgICAgfQorICAgIGlmIChpbmxlbiA+IDApIHsKKyAgICAgIGludCBlcnIgPSB3cml0ZShTVERPVVRfRklMRU5PLCBpbnB0ciwgaW5sZW4pOworICAgICAgYXNzZXJ0KGVyciA9PSBpbmxlbik7CisgICAgfQorICB9CisKKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvemNnemlwLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3ppcC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNDEwMTk5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3ppcC5jYwpAQCAtMCwwICsxLDc5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA5IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBicmlhbm9sc29uQGdvb2dsZS5jb20gKEJyaWFuIE9sc29uKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGVzdCBwcm9ncmFtIHRvIHZlcmlmeSB0aGF0IEd6aXBPdXRwdXRTdHJlYW0gaXMgY29tcGF0aWJsZSB3aXRoIGNvbW1hbmQgbGluZQorLy8gZ3ppcCBvciBqYXZhLnV0aWwuemlwLkd6aXBPdXRwdXRTdHJlYW0KKy8vCisvLyBSZWFkcyBkYXRhIG9uIHN0YW5kYXJkIGlucHV0IGFuZCB3cml0ZXMgY29tcHJlc3NlZCBnemlwIHN0cmVhbSB0byBzdGFuZGFyZAorLy8gb3V0cHV0LgorCisjaW5jbHVkZSAiY29uZmlnLmgiCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpGaWxlT3V0cHV0U3RyZWFtOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86Okd6aXBPdXRwdXRTdHJlYW07CisKK2ludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyKiogYXJndikgeworICBGaWxlT3V0cHV0U3RyZWFtIGZvdXQoU1RET1VUX0ZJTEVOTyk7CisgIEd6aXBPdXRwdXRTdHJlYW0gb3V0KCZmb3V0KTsKKyAgaW50IHJlYWRsZW47CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICB2b2lkKiBvdXRwdHI7CisgICAgaW50IG91dGxlbjsKKyAgICBib29sIG9rOworICAgIGRvIHsKKyAgICAgIG9rID0gb3V0Lk5leHQoJm91dHB0ciwgJm91dGxlbik7CisgICAgICBpZiAoIW9rKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0gd2hpbGUgKG91dGxlbiA8PSAwKTsKKyAgICByZWFkbGVuID0gcmVhZChTVERJTl9GSUxFTk8sIG91dHB0ciwgb3V0bGVuKTsKKyAgICBpZiAocmVhZGxlbiA8PSAwKSB7CisgICAgICBvdXQuQmFja1VwKG91dGxlbik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgaWYgKHJlYWRsZW4gPCBvdXRsZW4pIHsKKyAgICAgIG91dC5CYWNrVXAob3V0bGVuIC0gcmVhZGxlbik7CisgICAgfQorICB9CisKKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzA3MGM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5jYwpAQCAtMCwwICsxLDE3NTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGpzY2hvcnJAZ29vZ2xlLmNvbSAoSm9zZXBoIFNjaG9ycikKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGZsb2F0Lmg+CisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RhY2s+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitpbmxpbmUgYm9vbCBJc0hleE51bWJlcihjb25zdCBzdHJpbmcmIHN0cikgeworICByZXR1cm4gKHN0ci5sZW5ndGgoKSA+PSAyICYmIHN0clswXSA9PSAnMCcgJiYKKyAgICAgICAgICAoc3RyWzFdID09ICd4JyB8fCBzdHJbMV0gPT0gJ1gnKSk7Cit9CisKK2lubGluZSBib29sIElzT2N0TnVtYmVyKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIHJldHVybiAoc3RyLmxlbmd0aCgpID49IDIgJiYgc3RyWzBdID09ICcwJyAmJgorICAgICAgICAgIChzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8ICc4JykpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworc3RyaW5nIE1lc3NhZ2U6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBzdHJpbmcgZGVidWdfc3RyaW5nOworCisgIFRleHRGb3JtYXQ6OlByaW50VG9TdHJpbmcoKnRoaXMsICZkZWJ1Z19zdHJpbmcpOworCisgIHJldHVybiBkZWJ1Z19zdHJpbmc7Cit9CisKK3N0cmluZyBNZXNzYWdlOjpTaG9ydERlYnVnU3RyaW5nKCkgY29uc3QgeworICBzdHJpbmcgZGVidWdfc3RyaW5nOworCisgIFRleHRGb3JtYXQ6OlByaW50ZXIgcHJpbnRlcjsKKyAgcHJpbnRlci5TZXRTaW5nbGVMaW5lTW9kZSh0cnVlKTsKKworICBwcmludGVyLlByaW50VG9TdHJpbmcoKnRoaXMsICZkZWJ1Z19zdHJpbmcpOworICAvLyBTaW5nbGUgbGluZSBtb2RlIGN1cnJlbnRseSBtaWdodCBoYXZlIGFuIGV4dHJhIHNwYWNlIGF0IHRoZSBlbmQuCisgIGlmIChkZWJ1Z19zdHJpbmcuc2l6ZSgpID4gMCAmJgorICAgICAgZGVidWdfc3RyaW5nW2RlYnVnX3N0cmluZy5zaXplKCkgLSAxXSA9PSAnICcpIHsKKyAgICBkZWJ1Z19zdHJpbmcucmVzaXplKGRlYnVnX3N0cmluZy5zaXplKCkgLSAxKTsKKyAgfQorCisgIHJldHVybiBkZWJ1Z19zdHJpbmc7Cit9CisKK3N0cmluZyBNZXNzYWdlOjpVdGY4RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIHN0cmluZyBkZWJ1Z19zdHJpbmc7CisKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBwcmludGVyLlNldFVzZVV0ZjhTdHJpbmdFc2NhcGluZyh0cnVlKTsKKworICBwcmludGVyLlByaW50VG9TdHJpbmcoKnRoaXMsICZkZWJ1Z19zdHJpbmcpOworCisgIHJldHVybiBkZWJ1Z19zdHJpbmc7Cit9CisKK3ZvaWQgTWVzc2FnZTo6UHJpbnREZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgcHJpbnRmKCIlcyIsIERlYnVnU3RyaW5nKCkuY19zdHIoKSk7Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgcGFyc2UgaW5mb3JtYXRpb24gdHJlZSBjbGFzcy4KK1RleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWU6OlBhcnNlSW5mb1RyZWUoKSB7IH0KKworVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZTo6flBhcnNlSW5mb1RyZWUoKSB7CisgIC8vIFJlbW92ZSBhbnkgbmVzdGVkIGluZm9ybWF0aW9uIHRyZWVzLCBhcyB0aGV5IGFyZSBvd25lZCBieSB0aGlzIHRyZWUuCisgIGZvciAoTmVzdGVkTWFwOjppdGVyYXRvciBpdCA9IG5lc3RlZF8uYmVnaW4oKTsgaXQgIT0gbmVzdGVkXy5lbmQoKTsgKytpdCkgeworICAgIFNUTERlbGV0ZUVsZW1lbnRzKCYoaXQtPnNlY29uZCkpOworICB9Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZTo6UmVjb3JkTG9jYXRpb24oCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBUZXh0Rm9ybWF0OjpQYXJzZUxvY2F0aW9uIGxvY2F0aW9uKSB7CisgIGxvY2F0aW9uc19bZmllbGRdLnB1c2hfYmFjayhsb2NhdGlvbik7Cit9CisKK1RleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqIFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWU6OkNyZWF0ZU5lc3RlZCgKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIE93bmVkIGJ5IHVzIGluIHRoZSBtYXAuCisgIFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqIGluc3RhbmNlID0gbmV3IFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUoKTsKKyAgdmVjdG9yPFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqPiogdHJlZXMgPSAmbmVzdGVkX1tmaWVsZF07CisgIEdPT0dMRV9DSEVDSyh0cmVlcyk7CisgIHRyZWVzLT5wdXNoX2JhY2soaW5zdGFuY2UpOworICByZXR1cm4gaW5zdGFuY2U7Cit9CisKK3ZvaWQgQ2hlY2tGaWVsZEluZGV4KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgeworICBpZiAoZmllbGQgPT0gTlVMTCkgeyByZXR1cm47IH0KKworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgaW5kZXggPT0gLTEpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkluZGV4IG11c3QgYmUgaW4gcmFuZ2Ugb2YgcmVwZWF0ZWQgZmllbGQgdmFsdWVzLiAiCisgICAgICAgICAgICAgICAgPDwgIkZpZWxkOiAiIDw8IGZpZWxkLT5uYW1lKCk7CisgIH0gZWxzZSBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpICYmIGluZGV4ICE9IC0xKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJJbmRleCBtdXN0IGJlIC0xIGZvciBzaW5ndWxhciBmaWVsZHMuIgorICAgICAgICAgICAgICAgIDw8ICJGaWVsZDogIiA8PCBmaWVsZC0+bmFtZSgpOworICB9Cit9CisKK1RleHRGb3JtYXQ6OlBhcnNlTG9jYXRpb24gVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZTo6R2V0TG9jYXRpb24oCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIENoZWNrRmllbGRJbmRleChmaWVsZCwgaW5kZXgpOworICBpZiAoaW5kZXggPT0gLTEpIHsgaW5kZXggPSAwOyB9CisKKyAgY29uc3QgdmVjdG9yPFRleHRGb3JtYXQ6OlBhcnNlTG9jYXRpb24+KiBsb2NhdGlvbnMgPQorICAgICAgRmluZE9yTnVsbChsb2NhdGlvbnNfLCBmaWVsZCk7CisgIGlmIChsb2NhdGlvbnMgPT0gTlVMTCB8fCBpbmRleCA+PSBsb2NhdGlvbnMtPnNpemUoKSkgeworICAgIHJldHVybiBUZXh0Rm9ybWF0OjpQYXJzZUxvY2F0aW9uKCk7CisgIH0KKworICByZXR1cm4gKCpsb2NhdGlvbnMpW2luZGV4XTsKK30KKworVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSogVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZTo6R2V0VHJlZUZvck5lc3RlZCgKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgQ2hlY2tGaWVsZEluZGV4KGZpZWxkLCBpbmRleCk7CisgIGlmIChpbmRleCA9PSAtMSkgeyBpbmRleCA9IDA7IH0KKworICBjb25zdCB2ZWN0b3I8VGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSo+KiB0cmVlcyA9IEZpbmRPck51bGwobmVzdGVkXywgZmllbGQpOworICBpZiAodHJlZXMgPT0gTlVMTCB8fCBpbmRleCA+PSB0cmVlcy0+c2l6ZSgpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICByZXR1cm4gKCp0cmVlcylbaW5kZXhdOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gSW50ZXJuYWwgY2xhc3MgZm9yIHBhcnNpbmcgYW4gQVNDSUkgcmVwcmVzZW50YXRpb24gb2YgYSBQcm90b2NvbCBNZXNzYWdlLgorLy8gVGhpcyBjbGFzcyBtYWtlcyB1c2Ugb2YgdGhlIFByb3RvY29sIE1lc3NhZ2UgY29tcGlsZXIncyB0b2tlbml6ZXIgZm91bmQKKy8vIGluIC8vZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oLiBOb3RlIHRoYXQgY2xhc3MncyBQYXJzZQorLy8gbWV0aG9kIGlzICpub3QqIHRocmVhZC1zYWZlIGFuZCBzaG91bGQgb25seSBiZSB1c2VkIGluIGEgc2luZ2xlIHRocmVhZCBhdAorLy8gYSB0aW1lLgorCisvLyBNYWtlcyBjb2RlIHNsaWdodGx5IG1vcmUgcmVhZGFibGUuICBUaGUgbWVhbmluZyBvZiAiRE8oZm9vKSIgaXMKKy8vICJFeGVjdXRlIGZvbyBhbmQgZmFpbCBpZiBpdCBmYWlscy4iLCB3aGVyZSBmYWlsdXJlIGlzIGluZGljYXRlZCBieQorLy8gcmV0dXJuaW5nIGZhbHNlLiBCb3Jyb3dlZCBmcm9tIHBhcnNlci5jYyAoVGhhbmtzIEtlbnRvbiEpLgorI2RlZmluZSBETyhTVEFURU1FTlQpIGlmIChTVEFURU1FTlQpIHt9IGVsc2UgcmV0dXJuIGZhbHNlCisKK2NsYXNzIFRleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2VySW1wbCB7CisgcHVibGljOgorCisgIC8vIERldGVybWluZXMgaWYgcmVwZWF0ZWQgdmFsdWVzIGZvciBub24tcmVwZWF0ZWQgZmllbGRzIGFuZAorICAvLyBvbmVvZnMgYXJlIHBlcm1pdHRlZCwgZS5nLiwgdGhlIHN0cmluZyAiZm9vOiAxIGZvbzogMiIgZm9yIGEKKyAgLy8gcmVxdWlyZWQvb3B0aW9uYWwgZmllbGQgbmFtZWQgImZvbyIsIG9yICJiYXo6IDEgcXV4OiAyIgorICAvLyB3aGVyZSAiYmF6IiBhbmQgInF1eCIgYXJlIG1lbWJlcnMgb2YgdGhlIHNhbWUgb25lb2YuCisgIGVudW0gU2luZ3VsYXJPdmVyd3JpdGVQb2xpY3kgeworICAgIEFMTE9XX1NJTkdVTEFSX09WRVJXUklURVMgPSAwLCAgIC8vIHRoZSBsYXN0IHZhbHVlIGlzIHJldGFpbmVkCisgICAgRk9SQklEX1NJTkdVTEFSX09WRVJXUklURVMgPSAxLCAgLy8gYW4gZXJyb3IgaXMgaXNzdWVkCisgIH07CisKKyAgUGFyc2VySW1wbChjb25zdCBEZXNjcmlwdG9yKiByb290X21lc3NhZ2VfdHlwZSwKKyAgICAgICAgICAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXRfc3RyZWFtLAorICAgICAgICAgICAgIGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yLAorICAgICAgICAgICAgIFRleHRGb3JtYXQ6OkZpbmRlciogZmluZGVyLAorICAgICAgICAgICAgIFBhcnNlSW5mb1RyZWUqIHBhcnNlX2luZm9fdHJlZSwKKyAgICAgICAgICAgICBTaW5ndWxhck92ZXJ3cml0ZVBvbGljeSBzaW5ndWxhcl9vdmVyd3JpdGVfcG9saWN5LAorICAgICAgICAgICAgIGJvb2wgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZCwKKyAgICAgICAgICAgICBib29sIGFsbG93X3Vua25vd25fZmllbGQsCisgICAgICAgICAgICAgYm9vbCBhbGxvd191bmtub3duX2VudW0sCisgICAgICAgICAgICAgYm9vbCBhbGxvd19maWVsZF9udW1iZXIsCisgICAgICAgICAgICAgYm9vbCBhbGxvd19yZWxheGVkX3doaXRlc3BhY2UpCisgICAgOiBlcnJvcl9jb2xsZWN0b3JfKGVycm9yX2NvbGxlY3RvciksCisgICAgICBmaW5kZXJfKGZpbmRlciksCisgICAgICBwYXJzZV9pbmZvX3RyZWVfKHBhcnNlX2luZm9fdHJlZSksCisgICAgICB0b2tlbml6ZXJfZXJyb3JfY29sbGVjdG9yXyh0aGlzKSwKKyAgICAgIHRva2VuaXplcl8oaW5wdXRfc3RyZWFtLCAmdG9rZW5pemVyX2Vycm9yX2NvbGxlY3Rvcl8pLAorICAgICAgcm9vdF9tZXNzYWdlX3R5cGVfKHJvb3RfbWVzc2FnZV90eXBlKSwKKyAgICAgIHNpbmd1bGFyX292ZXJ3cml0ZV9wb2xpY3lfKHNpbmd1bGFyX292ZXJ3cml0ZV9wb2xpY3kpLAorICAgICAgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZF8oYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZCksCisgICAgICBhbGxvd191bmtub3duX2ZpZWxkXyhhbGxvd191bmtub3duX2ZpZWxkKSwKKyAgICAgIGFsbG93X3Vua25vd25fZW51bV8oYWxsb3dfdW5rbm93bl9lbnVtKSwKKyAgICAgIGFsbG93X2ZpZWxkX251bWJlcl8oYWxsb3dfZmllbGRfbnVtYmVyKSwKKyAgICAgIGhhZF9lcnJvcnNfKGZhbHNlKSB7CisgICAgLy8gRm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHdpdGggcHJvdG8xLCB3ZSBuZWVkIHRvIGFsbG93IHRoZSAnZicgc3VmZml4CisgICAgLy8gZm9yIGZsb2F0cy4KKyAgICB0b2tlbml6ZXJfLnNldF9hbGxvd19mX2FmdGVyX2Zsb2F0KHRydWUpOworCisgICAgLy8gJyMnIHN0YXJ0cyBhIGNvbW1lbnQuCisgICAgdG9rZW5pemVyXy5zZXRfY29tbWVudF9zdHlsZShpbzo6VG9rZW5pemVyOjpTSF9DT01NRU5UX1NUWUxFKTsKKworICAgIGlmIChhbGxvd19yZWxheGVkX3doaXRlc3BhY2UpIHsKKyAgICAgIHRva2VuaXplcl8uc2V0X3JlcXVpcmVfc3BhY2VfYWZ0ZXJfbnVtYmVyKGZhbHNlKTsKKyAgICAgIHRva2VuaXplcl8uc2V0X2FsbG93X211bHRpbGluZV9zdHJpbmdzKHRydWUpOworICAgIH0KKworICAgIC8vIENvbnN1bWUgdGhlIHN0YXJ0aW5nIHRva2VuLgorICAgIHRva2VuaXplcl8uTmV4dCgpOworICB9CisgIH5QYXJzZXJJbXBsKCkgeyB9CisKKyAgLy8gUGFyc2VzIHRoZSBBU0NJSSByZXByZXNlbnRhdGlvbiBzcGVjaWZpZWQgaW4gaW5wdXQgYW5kIHNhdmVzIHRoZQorICAvLyBpbmZvcm1hdGlvbiBpbnRvIHRoZSBvdXRwdXQgcG9pbnRlciAoYSBNZXNzYWdlKS4gUmV0dXJucworICAvLyBmYWxzZSBpZiBhbiBlcnJvciBvY2N1cnMgKGFuIGVycm9yIHdpbGwgYWxzbyBiZSBsb2dnZWQgdG8KKyAgLy8gR09PR0xFX0xPRyhFUlJPUikpLgorICBib29sIFBhcnNlKE1lc3NhZ2UqIG91dHB1dCkgeworICAgIC8vIENvbnN1bWUgZmllbGRzIHVudGlsIHdlIGNhbm5vdCBkbyBzbyBhbnltb3JlLgorICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCkpIHsKKyAgICAgICAgcmV0dXJuICFoYWRfZXJyb3JzXzsKKyAgICAgIH0KKworICAgICAgRE8oQ29uc3VtZUZpZWxkKG91dHB1dCkpOworICAgIH0KKyAgfQorCisgIGJvb2wgUGFyc2VGaWVsZChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBNZXNzYWdlKiBvdXRwdXQpIHsKKyAgICBib29sIHN1YzsKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIHN1YyA9IENvbnN1bWVGaWVsZE1lc3NhZ2Uob3V0cHV0LCBvdXRwdXQtPkdldFJlZmxlY3Rpb24oKSwgZmllbGQpOworICAgIH0gZWxzZSB7CisgICAgICBzdWMgPSBDb25zdW1lRmllbGRWYWx1ZShvdXRwdXQsIG91dHB1dC0+R2V0UmVmbGVjdGlvbigpLCBmaWVsZCk7CisgICAgfQorICAgIHJldHVybiBzdWMgJiYgTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCk7CisgIH0KKworICB2b2lkIFJlcG9ydEVycm9yKGludCBsaW5lLCBpbnQgY29sLCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBoYWRfZXJyb3JzXyA9IHRydWU7CisgICAgaWYgKGVycm9yX2NvbGxlY3Rvcl8gPT0gTlVMTCkgeworICAgICAgaWYgKGxpbmUgPj0gMCkgeworICAgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRXJyb3IgcGFyc2luZyB0ZXh0LWZvcm1hdCAiCisgICAgICAgICAgICAgICAgICAgPDwgcm9vdF9tZXNzYWdlX3R5cGVfLT5mdWxsX25hbWUoKQorICAgICAgICAgICAgICAgICAgIDw8ICI6ICIgPDwgKGxpbmUgKyAxKSA8PCAiOiIKKyAgICAgICAgICAgICAgICAgICA8PCAoY29sICsgMSkgPDwgIjogIiA8PCBtZXNzYWdlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkVycm9yIHBhcnNpbmcgdGV4dC1mb3JtYXQgIgorICAgICAgICAgICAgICAgICAgIDw8IHJvb3RfbWVzc2FnZV90eXBlXy0+ZnVsbF9uYW1lKCkKKyAgICAgICAgICAgICAgICAgICA8PCAiOiAiIDw8IG1lc3NhZ2U7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGxpbmUsIGNvbCwgbWVzc2FnZSk7CisgICAgfQorICB9CisKKyAgdm9pZCBSZXBvcnRXYXJuaW5nKGludCBsaW5lLCBpbnQgY29sLCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBpZiAoZXJyb3JfY29sbGVjdG9yXyA9PSBOVUxMKSB7CisgICAgICBpZiAobGluZSA+PSAwKSB7CisgICAgICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIldhcm5pbmcgcGFyc2luZyB0ZXh0LWZvcm1hdCAiCisgICAgICAgICAgICAgICAgICAgICA8PCByb290X21lc3NhZ2VfdHlwZV8tPmZ1bGxfbmFtZSgpCisgICAgICAgICAgICAgICAgICAgICA8PCAiOiAiIDw8IChsaW5lICsgMSkgPDwgIjoiCisgICAgICAgICAgICAgICAgICAgICA8PCAoY29sICsgMSkgPDwgIjogIiA8PCBtZXNzYWdlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiV2FybmluZyBwYXJzaW5nIHRleHQtZm9ybWF0ICIKKyAgICAgICAgICAgICAgICAgICAgIDw8IHJvb3RfbWVzc2FnZV90eXBlXy0+ZnVsbF9uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgIDw8ICI6ICIgPDwgbWVzc2FnZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgZXJyb3JfY29sbGVjdG9yXy0+QWRkV2FybmluZyhsaW5lLCBjb2wsIG1lc3NhZ2UpOworICAgIH0KKyAgfQorCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFBhcnNlckltcGwpOworCisgIC8vIFJlcG9ydHMgYW4gZXJyb3Igd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZSB3aXRoIGluZm9ybWF0aW9uIGluZGljYXRpbmcKKyAgLy8gdGhlIHBvc2l0aW9uIChhcyBkZXJpdmVkIGZyb20gdGhlIGN1cnJlbnQgdG9rZW4pLgorICB2b2lkIFJlcG9ydEVycm9yKGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIFJlcG9ydEVycm9yKHRva2VuaXplcl8uY3VycmVudCgpLmxpbmUsIHRva2VuaXplcl8uY3VycmVudCgpLmNvbHVtbiwKKyAgICAgICAgICAgICAgICBtZXNzYWdlKTsKKyAgfQorCisgIC8vIFJlcG9ydHMgYSB3YXJuaW5nIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2Ugd2l0aCBpbmZvcm1hdGlvbiBpbmRpY2F0aW5nCisgIC8vIHRoZSBwb3NpdGlvbiAoYXMgZGVyaXZlZCBmcm9tIHRoZSBjdXJyZW50IHRva2VuKS4KKyAgdm9pZCBSZXBvcnRXYXJuaW5nKGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIFJlcG9ydFdhcm5pbmcodG9rZW5pemVyXy5jdXJyZW50KCkubGluZSwgdG9rZW5pemVyXy5jdXJyZW50KCkuY29sdW1uLAorICAgICAgICAgICAgICAgICAgbWVzc2FnZSk7CisgIH0KKworICAvLyBDb25zdW1lcyB0aGUgc3BlY2lmaWVkIG1lc3NhZ2Ugd2l0aCB0aGUgZ2l2ZW4gc3RhcnRpbmcgZGVsaW1pdGVyLgorICAvLyBUaGlzIG1ldGhvZCBjaGVja3MgdG8gc2VlIHRoYXQgdGhlIGVuZCBkZWxpbWl0ZXIgYXQgdGhlIGNvbmNsdXNpb24gb2YKKyAgLy8gdGhlIGNvbnN1bXB0aW9uIG1hdGNoZXMgdGhlIHN0YXJ0aW5nIGRlbGltaXRlciBwYXNzZWQgaW4gaGVyZS4KKyAgYm9vbCBDb25zdW1lTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBzdHJpbmcgZGVsaW1pdGVyKSB7CisgICAgd2hpbGUgKCFMb29raW5nQXQoIj4iKSAmJiAgIUxvb2tpbmdBdCgifSIpKSB7CisgICAgICBETyhDb25zdW1lRmllbGQobWVzc2FnZSkpOworICAgIH0KKworICAgIC8vIENvbmZpcm0gdGhhdCB3ZSBoYXZlIGEgdmFsaWQgZW5kaW5nIGRlbGltaXRlci4KKyAgICBETyhDb25zdW1lKGRlbGltaXRlcikpOworCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworCisgIC8vIENvbnN1bWVzIHRoZSBjdXJyZW50IGZpZWxkIChhcyByZXR1cm5lZCBieSB0aGUgdG9rZW5pemVyKSBvbiB0aGUKKyAgLy8gcGFzc2VkIGluIG1lc3NhZ2UuCisgIGJvb2wgQ29uc3VtZUZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisKKyAgICBzdHJpbmcgZmllbGRfbmFtZTsKKworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBOVUxMOworICAgIGludCBzdGFydF9saW5lID0gdG9rZW5pemVyXy5jdXJyZW50KCkubGluZTsKKyAgICBpbnQgc3RhcnRfY29sdW1uID0gdG9rZW5pemVyXy5jdXJyZW50KCkuY29sdW1uOworCisgICAgaWYgKFRyeUNvbnN1bWUoIlsiKSkgeworICAgICAgLy8gRXh0ZW5zaW9uLgorICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmZpZWxkX25hbWUpKTsKKyAgICAgIHdoaWxlIChUcnlDb25zdW1lKCIuIikpIHsKKyAgICAgICAgc3RyaW5nIHBhcnQ7CisgICAgICAgIERPKENvbnN1bWVJZGVudGlmaWVyKCZwYXJ0KSk7CisgICAgICAgIGZpZWxkX25hbWUgKz0gIi4iOworICAgICAgICBmaWVsZF9uYW1lICs9IHBhcnQ7CisgICAgICB9CisgICAgICBETyhDb25zdW1lKCJdIikpOworCisgICAgICBmaWVsZCA9IChmaW5kZXJfICE9IE5VTEwKKyAgICAgICAgICAgICAgID8gZmluZGVyXy0+RmluZEV4dGVuc2lvbihtZXNzYWdlLCBmaWVsZF9uYW1lKQorICAgICAgICAgICAgICAgOiByZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU5hbWUoZmllbGRfbmFtZSkpOworCisgICAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgICBpZiAoIWFsbG93X3Vua25vd25fZmllbGRfKSB7CisgICAgICAgICAgUmVwb3J0RXJyb3IoIkV4dGVuc2lvbiBcIiIgKyBmaWVsZF9uYW1lICsgIlwiIGlzIG5vdCBkZWZpbmVkIG9yICIKKyAgICAgICAgICAgICAgICAgICAgICAiaXMgbm90IGFuIGV4dGVuc2lvbiBvZiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBSZXBvcnRXYXJuaW5nKCJFeHRlbnNpb24gXCIiICsgZmllbGRfbmFtZSArICJcIiBpcyBub3QgZGVmaW5lZCBvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAiaXMgbm90IGFuIGV4dGVuc2lvbiBvZiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmZpZWxkX25hbWUpKTsKKworICAgICAgaW50MzIgZmllbGRfbnVtYmVyOworICAgICAgaWYgKGFsbG93X2ZpZWxkX251bWJlcl8gJiYgc2FmZV9zdHJ0bzMyKGZpZWxkX25hbWUsICZmaWVsZF9udW1iZXIpKSB7CisgICAgICAgIGlmIChkZXNjcmlwdG9yLT5Jc0V4dGVuc2lvbk51bWJlcihmaWVsZF9udW1iZXIpKSB7CisgICAgICAgICAgZmllbGQgPSByZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihmaWVsZF9udW1iZXIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOdW1iZXIoZmllbGRfbnVtYmVyKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoZmllbGRfbmFtZSk7CisgICAgICAgIC8vIEdyb3VwIG5hbWVzIGFyZSBleHBlY3RlZCB0byBiZSBjYXBpdGFsaXplZCBhcyB0aGV5IGFwcGVhciBpbiB0aGUKKyAgICAgICAgLy8gLnByb3RvIGZpbGUsIHdoaWNoIGFjdHVhbGx5IG1hdGNoZXMgdGhlaXIgdHlwZSBuYW1lcywgbm90IHRoZWlyCisgICAgICAgIC8vIGZpZWxkIG5hbWVzLgorICAgICAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgICAgIHN0cmluZyBsb3dlcl9maWVsZF9uYW1lID0gZmllbGRfbmFtZTsKKyAgICAgICAgICBMb3dlclN0cmluZygmbG93ZXJfZmllbGRfbmFtZSk7CisgICAgICAgICAgZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUobG93ZXJfZmllbGRfbmFtZSk7CisgICAgICAgICAgLy8gSWYgdGhlIGNhc2UtaW5zZW5zaXRpdmUgbWF0Y2ggd29ya2VkIGJ1dCB0aGUgZmllbGQgaXMgTk9UIGEgZ3JvdXAsCisgICAgICAgICAgaWYgKGZpZWxkICE9IE5VTEwgJiYgZmllbGQtPnR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgICAgICAgIGZpZWxkID0gTlVMTDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gQWdhaW4sIHNwZWNpYWwtY2FzZSBncm91cCBuYW1lcyBhcyBkZXNjcmliZWQgYWJvdmUuCisgICAgICAgIGlmIChmaWVsZCAhPSBOVUxMICYmIGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQCisgICAgICAgICAgICAmJiBmaWVsZC0+bWVzc2FnZV90eXBlKCktPm5hbWUoKSAhPSBmaWVsZF9uYW1lKSB7CisgICAgICAgICAgZmllbGQgPSBOVUxMOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZpZWxkID09IE5VTEwgJiYgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZF8pIHsKKyAgICAgICAgICBzdHJpbmcgbG93ZXJfZmllbGRfbmFtZSA9IGZpZWxkX25hbWU7CisgICAgICAgICAgTG93ZXJTdHJpbmcoJmxvd2VyX2ZpZWxkX25hbWUpOworICAgICAgICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKGxvd2VyX2ZpZWxkX25hbWUpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICAgIGlmICghYWxsb3dfdW5rbm93bl9maWVsZF8pIHsKKyAgICAgICAgICBSZXBvcnRFcnJvcigiTWVzc2FnZSB0eXBlIFwiIiArIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgICAiXCIgaGFzIG5vIGZpZWxkIG5hbWVkIFwiIiArIGZpZWxkX25hbWUgKyAiXCIuIik7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFJlcG9ydFdhcm5pbmcoIk1lc3NhZ2UgdHlwZSBcIiIgKyBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAiXCIgaGFzIG5vIGZpZWxkIG5hbWVkIFwiIiArIGZpZWxkX25hbWUgKyAiXCIuIik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBTa2lwcyB1bmtub3duIGZpZWxkLgorICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICBHT09HTEVfQ0hFQ0soYWxsb3dfdW5rbm93bl9maWVsZF8pOworICAgICAgLy8gVHJ5IHRvIGd1ZXNzIHRoZSB0eXBlIG9mIHRoaXMgZmllbGQuCisgICAgICAvLyBJZiB0aGlzIGZpZWxkIGlzIG5vdCBhIG1lc3NhZ2UsIHRoZXJlIHNob3VsZCBiZSBhICI6IiBiZXR3ZWVuIHRoZQorICAgICAgLy8gZmllbGQgbmFtZSBhbmQgdGhlIGZpZWxkIHZhbHVlIGFuZCBhbHNvIHRoZSBmaWVsZCB2YWx1ZSBzaG91bGQgbm90CisgICAgICAvLyBzdGFydCB3aXRoICJ7IiBvciAiPCIgd2hpY2ggaW5kaWNhdGVzIHRoZSBiZWdpbm5pbmcgb2YgYSBtZXNzYWdlIGJvZHkuCisgICAgICAvLyBJZiB0aGVyZSBpcyBubyAiOiIgb3IgdGhlcmUgaXMgYSAieyIgb3IgIjwiIGFmdGVyICI6IiwgdGhpcyBmaWVsZCBoYXMKKyAgICAgIC8vIHRvIGJlIGEgbWVzc2FnZSBvciB0aGUgaW5wdXQgaXMgaWxsLWZvcm1lZC4KKyAgICAgIGlmIChUcnlDb25zdW1lKCI6IikgJiYgIUxvb2tpbmdBdCgieyIpICYmICFMb29raW5nQXQoIjwiKSkgeworICAgICAgICByZXR1cm4gU2tpcEZpZWxkVmFsdWUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBTa2lwRmllbGRNZXNzYWdlKCk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKHNpbmd1bGFyX292ZXJ3cml0ZV9wb2xpY3lfID09IEZPUkJJRF9TSU5HVUxBUl9PVkVSV1JJVEVTKSB7CisgICAgICAvLyBGYWlsIGlmIHRoZSBmaWVsZCBpcyBub3QgcmVwZWF0ZWQgYW5kIGl0IGhhcyBhbHJlYWR5IGJlZW4gc3BlY2lmaWVkLgorICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiByZWZsZWN0aW9uLT5IYXNGaWVsZCgqbWVzc2FnZSwgZmllbGQpKSB7CisgICAgICAgIFJlcG9ydEVycm9yKCJOb24tcmVwZWF0ZWQgZmllbGQgXCIiICsgZmllbGRfbmFtZSArCisgICAgICAgICAgICAgICAgICAgICJcIiBpcyBzcGVjaWZpZWQgbXVsdGlwbGUgdGltZXMuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIC8vIEZhaWwgaWYgdGhlIGZpZWxkIGlzIGEgbWVtYmVyIG9mIGEgb25lb2YgYW5kIGFub3RoZXIgbWVtYmVyIGhhcyBhbHJlYWR5CisgICAgICAvLyBiZWVuIHNwZWNpZmllZC4KKyAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YgPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpOworICAgICAgaWYgKG9uZW9mICE9IE5VTEwgJiYgcmVmbGVjdGlvbi0+SGFzT25lb2YoKm1lc3NhZ2UsIG9uZW9mKSkgeworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG90aGVyX2ZpZWxkID0KKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkdldE9uZW9mRmllbGREZXNjcmlwdG9yKCptZXNzYWdlLCBvbmVvZik7CisgICAgICAgIFJlcG9ydEVycm9yKCJGaWVsZCBcIiIgKyBmaWVsZF9uYW1lICsgIlwiIGlzIHNwZWNpZmllZCBhbG9uZyB3aXRoICIKKyAgICAgICAgICAgICAgICAgICAgImZpZWxkIFwiIiArIG90aGVyX2ZpZWxkLT5uYW1lKCkgKyAiXCIsIGFub3RoZXIgbWVtYmVyICIKKyAgICAgICAgICAgICAgICAgICAgIm9mIG9uZW9mIFwiIiArIG9uZW9mLT5uYW1lKCkgKyAiXCIuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBQZXJmb3JtIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGVtYmVkZGVkIG1lc3NhZ2UgdHlwZXMuCisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICAvLyAnOicgaXMgb3B0aW9uYWwgaGVyZS4KKyAgICAgIFRyeUNvbnN1bWUoIjoiKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gJzonIGlzIHJlcXVpcmVkIGhlcmUuCisgICAgICBETyhDb25zdW1lKCI6IikpOworICAgIH0KKworICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiBUcnlDb25zdW1lKCJbIikpIHsKKyAgICAgIC8vIFNob3J0IHJlcGVhdGVkIGZvcm1hdCwgZS5nLiAgImZvbzogWzEsIDIsIDNdIgorICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICAgICAgLy8gUGVyZm9ybSBzcGVjaWFsIGhhbmRsaW5nIGZvciBlbWJlZGRlZCBtZXNzYWdlIHR5cGVzLgorICAgICAgICAgIERPKENvbnN1bWVGaWVsZE1lc3NhZ2UobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBETyhDb25zdW1lRmllbGRWYWx1ZShtZXNzYWdlLCByZWZsZWN0aW9uLCBmaWVsZCkpOworICAgICAgICB9CisgICAgICAgIGlmIChUcnlDb25zdW1lKCJdIikpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBETyhDb25zdW1lKCIsIikpOworICAgICAgfQorICAgIH0gZWxzZSBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIERPKENvbnN1bWVGaWVsZE1lc3NhZ2UobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQpKTsKKyAgICB9IGVsc2UgeworICAgICAgRE8oQ29uc3VtZUZpZWxkVmFsdWUobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQpKTsKKyAgICB9CisKKyAgICAvLyBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBmaWVsZHMgbWF5IG9wdGlvbmFsbHkgYmUgc2VwYXJhdGVkIGJ5IGNvbW1hcyBvcgorICAgIC8vIHNlbWljb2xvbnMuCisgICAgVHJ5Q29uc3VtZSgiOyIpIHx8IFRyeUNvbnN1bWUoIiwiKTsKKworICAgIGlmIChmaWVsZC0+b3B0aW9ucygpLmRlcHJlY2F0ZWQoKSkgeworICAgICAgUmVwb3J0V2FybmluZygidGV4dCBmb3JtYXQgY29udGFpbnMgZGVwcmVjYXRlZCBmaWVsZCBcIiIKKyAgICAgICAgICAgICAgICAgICAgKyBmaWVsZF9uYW1lICsgIlwiIik7CisgICAgfQorCisgICAgLy8gSWYgYSBwYXJzZSBpbmZvIHRyZWUgZXhpc3RzLCBhZGQgdGhlIGxvY2F0aW9uIGZvciB0aGUgcGFyc2VkCisgICAgLy8gZmllbGQuCisgICAgaWYgKHBhcnNlX2luZm9fdHJlZV8gIT0gTlVMTCkgeworICAgICAgUmVjb3JkTG9jYXRpb24ocGFyc2VfaW5mb190cmVlXywgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICBQYXJzZUxvY2F0aW9uKHN0YXJ0X2xpbmUsIHN0YXJ0X2NvbHVtbikpOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gU2tpcHMgdGhlIG5leHQgZmllbGQgaW5jbHVkaW5nIHRoZSBmaWVsZCdzIG5hbWUgYW5kIHZhbHVlLgorICBib29sIFNraXBGaWVsZCgpIHsKKyAgICBzdHJpbmcgZmllbGRfbmFtZTsKKyAgICBpZiAoVHJ5Q29uc3VtZSgiWyIpKSB7CisgICAgICAvLyBFeHRlbnNpb24gbmFtZS4KKyAgICAgIERPKENvbnN1bWVJZGVudGlmaWVyKCZmaWVsZF9uYW1lKSk7CisgICAgICB3aGlsZSAoVHJ5Q29uc3VtZSgiLiIpKSB7CisgICAgICAgIHN0cmluZyBwYXJ0OworICAgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmcGFydCkpOworICAgICAgICBmaWVsZF9uYW1lICs9ICIuIjsKKyAgICAgICAgZmllbGRfbmFtZSArPSBwYXJ0OworICAgICAgfQorICAgICAgRE8oQ29uc3VtZSgiXSIpKTsKKyAgICB9IGVsc2UgeworICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmZpZWxkX25hbWUpKTsKKyAgICB9CisKKyAgICAvLyBUcnkgdG8gZ3Vlc3MgdGhlIHR5cGUgb2YgdGhpcyBmaWVsZC4KKyAgICAvLyBJZiB0aGlzIGZpZWxkIGlzIG5vdCBhIG1lc3NhZ2UsIHRoZXJlIHNob3VsZCBiZSBhICI6IiBiZXR3ZWVuIHRoZQorICAgIC8vIGZpZWxkIG5hbWUgYW5kIHRoZSBmaWVsZCB2YWx1ZSBhbmQgYWxzbyB0aGUgZmllbGQgdmFsdWUgc2hvdWxkIG5vdAorICAgIC8vIHN0YXJ0IHdpdGggInsiIG9yICI8IiB3aGljaCBpbmRpY2F0ZXMgdGhlIGJlZ2lubmluZyBvZiBhIG1lc3NhZ2UgYm9keS4KKyAgICAvLyBJZiB0aGVyZSBpcyBubyAiOiIgb3IgdGhlcmUgaXMgYSAieyIgb3IgIjwiIGFmdGVyICI6IiwgdGhpcyBmaWVsZCBoYXMKKyAgICAvLyB0byBiZSBhIG1lc3NhZ2Ugb3IgdGhlIGlucHV0IGlzIGlsbC1mb3JtZWQuCisgICAgaWYgKFRyeUNvbnN1bWUoIjoiKSAmJiAhTG9va2luZ0F0KCJ7IikgJiYgIUxvb2tpbmdBdCgiPCIpKSB7CisgICAgICBETyhTa2lwRmllbGRWYWx1ZSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgRE8oU2tpcEZpZWxkTWVzc2FnZSgpKTsKKyAgICB9CisgICAgLy8gRm9yIGhpc3RvcmljYWwgcmVhc29ucywgZmllbGRzIG1heSBvcHRpb25hbGx5IGJlIHNlcGFyYXRlZCBieSBjb21tYXMgb3IKKyAgICAvLyBzZW1pY29sb25zLgorICAgIFRyeUNvbnN1bWUoIjsiKSB8fCBUcnlDb25zdW1lKCIsIik7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBib29sIENvbnN1bWVGaWVsZE1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisKKyAgICAvLyBJZiB0aGUgcGFyc2UgaW5mb3JtYXRpb24gdHJlZSBpcyBub3QgTlVMTCwgY3JlYXRlIGEgbmVzdGVkIG9uZQorICAgIC8vIGZvciB0aGUgbmVzdGVkIG1lc3NhZ2UuCisgICAgUGFyc2VJbmZvVHJlZSogcGFyZW50ID0gcGFyc2VfaW5mb190cmVlXzsKKyAgICBpZiAocGFyZW50ICE9IE5VTEwpIHsKKyAgICAgIHBhcnNlX2luZm9fdHJlZV8gPSBDcmVhdGVOZXN0ZWQocGFyZW50LCBmaWVsZCk7CisgICAgfQorCisgICAgc3RyaW5nIGRlbGltaXRlcjsKKyAgICBpZiAoVHJ5Q29uc3VtZSgiPCIpKSB7CisgICAgICBkZWxpbWl0ZXIgPSAiPiI7CisgICAgfSBlbHNlIHsKKyAgICAgIERPKENvbnN1bWUoInsiKSk7CisgICAgICBkZWxpbWl0ZXIgPSAifSI7CisgICAgfQorCisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBETyhDb25zdW1lTWVzc2FnZShyZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKSwgZGVsaW1pdGVyKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIERPKENvbnN1bWVNZXNzYWdlKHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGltaXRlcikpOworICAgIH0KKworICAgIC8vIFJlc2V0IHRoZSBwYXJzZSBpbmZvcm1hdGlvbiB0cmVlLgorICAgIHBhcnNlX2luZm9fdHJlZV8gPSBwYXJlbnQ7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBTa2lwcyB0aGUgd2hvbGUgYm9keSBvZiBhIG1lc3NhZ2UgaW5jbHVkaW5nIHRoZSBiZWdpbm5pbmcgZGVsaW1pdGVyIGFuZAorICAvLyB0aGUgZW5kaW5nIGRlbGltaXRlci4KKyAgYm9vbCBTa2lwRmllbGRNZXNzYWdlKCkgeworICAgIHN0cmluZyBkZWxpbWl0ZXI7CisgICAgaWYgKFRyeUNvbnN1bWUoIjwiKSkgeworICAgICAgZGVsaW1pdGVyID0gIj4iOworICAgIH0gZWxzZSB7CisgICAgICBETyhDb25zdW1lKCJ7IikpOworICAgICAgZGVsaW1pdGVyID0gIn0iOworICAgIH0KKyAgICB3aGlsZSAoIUxvb2tpbmdBdCgiPiIpICYmICAhTG9va2luZ0F0KCJ9IikpIHsKKyAgICAgIERPKFNraXBGaWVsZCgpKTsKKyAgICB9CisgICAgRE8oQ29uc3VtZShkZWxpbWl0ZXIpKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGJvb2wgQ29uc3VtZUZpZWxkVmFsdWUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKworLy8gRGVmaW5lIGFuIGVhc3kgdG8gdXNlIG1hY3JvIGZvciBzZXR0aW5nIGZpZWxkcy4gVGhpcyBtYWNybyBjaGVja3MKKy8vIHRvIHNlZSBpZiB0aGUgZmllbGQgaXMgcmVwZWF0ZWQgKGluIHdoaWNoIGNhc2Ugd2UgbmVlZCB0byB1c2UgdGhlIEFkZAorLy8gbWV0aG9kcyBvciBub3QgKGluIHdoaWNoIGNhc2Ugd2UgbmVlZCB0byB1c2UgdGhlIFNldCBtZXRob2RzKS4KKyNkZWZpbmUgU0VUX0ZJRUxEKENQUFRZUEUsIFZBTFVFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlZmxlY3Rpb24tPkFkZCMjQ1BQVFlQRShtZXNzYWdlLCBmaWVsZCwgVkFMVUUpOyAgICAgICAgIFwKKyAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgcmVmbGVjdGlvbi0+U2V0IyNDUFBUWVBFKG1lc3NhZ2UsIGZpZWxkLCBWQUxVRSk7ICAgICAgICAgXAorICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKworICAgIHN3aXRjaChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6IHsKKyAgICAgICAgaW50NjQgdmFsdWU7CisgICAgICAgIERPKENvbnN1bWVTaWduZWRJbnRlZ2VyKCZ2YWx1ZSwga2ludDMybWF4KSk7CisgICAgICAgIFNFVF9GSUVMRChJbnQzMiwgc3RhdGljX2Nhc3Q8aW50MzI+KHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6IHsKKyAgICAgICAgdWludDY0IHZhbHVlOworICAgICAgICBETyhDb25zdW1lVW5zaWduZWRJbnRlZ2VyKCZ2YWx1ZSwga3VpbnQzMm1heCkpOworICAgICAgICBTRVRfRklFTEQoVUludDMyLCBzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDogeworICAgICAgICBpbnQ2NCB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZVNpZ25lZEludGVnZXIoJnZhbHVlLCBraW50NjRtYXgpKTsKKyAgICAgICAgU0VUX0ZJRUxEKEludDY0LCB2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6IHsKKyAgICAgICAgdWludDY0IHZhbHVlOworICAgICAgICBETyhDb25zdW1lVW5zaWduZWRJbnRlZ2VyKCZ2YWx1ZSwga3VpbnQ2NG1heCkpOworICAgICAgICBTRVRfRklFTEQoVUludDY0LCB2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDogeworICAgICAgICBkb3VibGUgdmFsdWU7CisgICAgICAgIERPKENvbnN1bWVEb3VibGUoJnZhbHVlKSk7CisgICAgICAgIFNFVF9GSUVMRChGbG9hdCwgc3RhdGljX2Nhc3Q8ZmxvYXQ+KHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6IHsKKyAgICAgICAgZG91YmxlIHZhbHVlOworICAgICAgICBETyhDb25zdW1lRG91YmxlKCZ2YWx1ZSkpOworICAgICAgICBTRVRfRklFTEQoRG91YmxlLCB2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6IHsKKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBETyhDb25zdW1lU3RyaW5nKCZ2YWx1ZSkpOworICAgICAgICBTRVRfRklFTEQoU3RyaW5nLCB2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOiB7CisgICAgICAgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSU5URUdFUikpIHsKKyAgICAgICAgICB1aW50NjQgdmFsdWU7CisgICAgICAgICAgRE8oQ29uc3VtZVVuc2lnbmVkSW50ZWdlcigmdmFsdWUsIDEpKTsKKyAgICAgICAgICBTRVRfRklFTEQoQm9vbCwgdmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHN0cmluZyB2YWx1ZTsKKyAgICAgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmdmFsdWUpKTsKKyAgICAgICAgICBpZiAodmFsdWUgPT0gInRydWUiIHx8IHZhbHVlID09ICJUcnVlIiB8fCB2YWx1ZSA9PSAidCIpIHsKKyAgICAgICAgICAgIFNFVF9GSUVMRChCb29sLCB0cnVlKTsKKyAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09ICJmYWxzZSIgfHwgdmFsdWUgPT0gIkZhbHNlIiB8fCB2YWx1ZSA9PSAiZiIpIHsKKyAgICAgICAgICAgIFNFVF9GSUVMRChCb29sLCBmYWxzZSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFJlcG9ydEVycm9yKCJJbnZhbGlkIHZhbHVlIGZvciBib29sZWFuIGZpZWxkIFwiIiArIGZpZWxkLT5uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIlwiLiBWYWx1ZTogXCIiICsgdmFsdWUgICsgIlwiLiIpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTogeworICAgICAgICBzdHJpbmcgdmFsdWU7CisgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUgPSBmaWVsZC0+ZW51bV90eXBlKCk7CisgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPSBOVUxMOworCisgICAgICAgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUikpIHsKKyAgICAgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmdmFsdWUpKTsKKyAgICAgICAgICAvLyBGaW5kIHRoZSBlbnVtZXJhdGlvbiB2YWx1ZS4KKyAgICAgICAgICBlbnVtX3ZhbHVlID0gZW51bV90eXBlLT5GaW5kVmFsdWVCeU5hbWUodmFsdWUpOworCisgICAgICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCItIikgfHwKKyAgICAgICAgICAgICAgICAgICBMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSU5URUdFUikpIHsKKyAgICAgICAgICBpbnQ2NCBpbnRfdmFsdWU7CisgICAgICAgICAgRE8oQ29uc3VtZVNpZ25lZEludGVnZXIoJmludF92YWx1ZSwga2ludDMybWF4KSk7CisgICAgICAgICAgdmFsdWUgPSBTaW1wbGVJdG9hKGludF92YWx1ZSk7ICAgICAgICAvLyBmb3IgZXJyb3IgcmVwb3J0aW5nCisgICAgICAgICAgZW51bV92YWx1ZSA9IGVudW1fdHlwZS0+RmluZFZhbHVlQnlOdW1iZXIoaW50X3ZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgaW50ZWdlciBvciBpZGVudGlmaWVyLiIpOworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlbnVtX3ZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgICBpZiAoIWFsbG93X3Vua25vd25fZW51bV8pIHsKKyAgICAgICAgICAgIFJlcG9ydEVycm9yKCJVbmtub3duIGVudW1lcmF0aW9uIHZhbHVlIG9mIFwiIiArIHZhbHVlICArICJcIiBmb3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgImZpZWxkIFwiIiArIGZpZWxkLT5uYW1lKCkgKyAiXCIuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFJlcG9ydFdhcm5pbmcoIlVua25vd24gZW51bWVyYXRpb24gdmFsdWUgb2YgXCIiICsgdmFsdWUgICsgIlwiIGZvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWVsZCBcIiIgKyBmaWVsZC0+bmFtZSgpICsgIlwiLiIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU0VUX0ZJRUxEKEVudW0sIGVudW1fdmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgICAvLyBXZSBzaG91bGQgbmV2ZXIgZ2V0IGhlcmUuIFB1dCBoZXJlIGluc3RlYWQgb2YgYSBkZWZhdWx0CisgICAgICAgIC8vIHNvIHRoYXQgaWYgbmV3IHR5cGVzIGFyZSBhZGRlZCwgd2UgZ2V0IGEgbmljZSBjb21waWxlciB3YXJuaW5nLgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiUmVhY2hlZCBhbiB1bmludGVuZGVkIHN0YXRlOiBDUFBUWVBFX01FU1NBR0UiOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisjdW5kZWYgU0VUX0ZJRUxECisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBib29sIFNraXBGaWVsZFZhbHVlKCkgeworICAgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HKSkgeworICAgICAgd2hpbGUgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9TVFJJTkcpKSB7CisgICAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIC8vIFBvc3NpYmxlIGZpZWxkIHZhbHVlcyBvdGhlciB0aGFuIHN0cmluZzoKKyAgICAvLyAgIDEyMzQ1ICAgICAgICA9PiBUWVBFX0lOVEVHRVIKKyAgICAvLyAgIC0xMjM0NSAgICAgICA9PiBUWVBFX1NZTUJPTCArIFRZUEVfSU5URUdFUgorICAgIC8vICAgMS4yMzQ1ICAgICAgID0+IFRZUEVfRkxPQVQKKyAgICAvLyAgIC0xLjIzNDUgICAgICA9PiBUWVBFX1NZTUJPTCArIFRZUEVfRkxPQVQKKyAgICAvLyAgIGluZiAgICAgICAgICA9PiBUWVBFX0lERU5USUZJRVIKKyAgICAvLyAgIC1pbmYgICAgICAgICA9PiBUWVBFX1NZTUJPTCArIFRZUEVfSURFTlRJRklFUgorICAgIC8vICAgVFlQRV9JTlRFR0VSID0+IFRZUEVfSURFTlRJRklFUgorICAgIC8vIERpdmlkZXMgdGhlbSBpbnRvIHR3byBncm91cCwgb25lIHdpdGggVFlQRV9TWU1CT0wKKyAgICAvLyBhbmQgdGhlIG90aGVyIHdpdGhvdXQ6CisgICAgLy8gICBHcm91cCBvbmU6CisgICAgLy8gICAgIDEyMzQ1ICAgICAgICA9PiBUWVBFX0lOVEVHRVIKKyAgICAvLyAgICAgMS4yMzQ1ICAgICAgID0+IFRZUEVfRkxPQVQKKyAgICAvLyAgICAgaW5mICAgICAgICAgID0+IFRZUEVfSURFTlRJRklFUgorICAgIC8vICAgICBUWVBFX0lOVEVHRVIgPT4gVFlQRV9JREVOVElGSUVSCisgICAgLy8gICBHcm91cCB0d286CisgICAgLy8gICAgIC0xMjM0NSAgICAgICA9PiBUWVBFX1NZTUJPTCArIFRZUEVfSU5URUdFUgorICAgIC8vICAgICAtMS4yMzQ1ICAgICAgPT4gVFlQRV9TWU1CT0wgKyBUWVBFX0ZMT0FUCisgICAgLy8gICAgIC1pbmYgICAgICAgICA9PiBUWVBFX1NZTUJPTCArIFRZUEVfSURFTlRJRklFUgorICAgIC8vIEFzIHdlIGNhbiBzZWUsIHRoZSBmaWVsZCB2YWx1ZSBjb25zaXN0cyBvZiBhbiBvcHRpb25hbCAnLScgYW5kIG9uZSBvZgorICAgIC8vIFRZUEVfSU5URUdFUiwgVFlQRV9GTE9BVCBhbmQgVFlQRV9JREVOVElGSUVSLgorICAgIGJvb2wgaGFzX21pbnVzID0gVHJ5Q29uc3VtZSgiLSIpOworICAgIGlmICghTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpICYmCisgICAgICAgICFMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfRkxPQVQpICYmCisgICAgICAgICFMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUikpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgLy8gQ29tYmluYXRpb24gb2YgJy0nIGFuZCBUWVBFX0lERU5USUZJRVIgbWF5IHJlc3VsdCBpbiBhbiBpbnZhbGlkIGZpZWxkCisgICAgLy8gdmFsdWUgd2hpbGUgb3RoZXIgY29tYmluYXRpb25zIGFsbCBnZW5lcmF0ZSB2YWxpZCB2YWx1ZXMuCisgICAgLy8gV2UgY2hlY2sgaWYgdGhlIHZhbHVlIG9mIHRoaXMgY29tYmluYXRpb24gaXMgdmFsaWQgaGVyZS4KKyAgICAvLyBUWVBFX0lERU5USUZJRVIgYWZ0ZXIgYSAnLScgc2hvdWxkIGJlIG9uZSBvZiB0aGUgZmxvYXQgdmFsdWVzIGxpc3RlZAorICAgIC8vIGJlbG93OgorICAgIC8vICAgaW5mLCBpbmZmLCBpbmZpbml0eSwgbmFuCisgICAgaWYgKGhhc19taW51cyAmJiBMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUikpIHsKKyAgICAgIHN0cmluZyB0ZXh0ID0gdG9rZW5pemVyXy5jdXJyZW50KCkudGV4dDsKKyAgICAgIExvd2VyU3RyaW5nKCZ0ZXh0KTsKKyAgICAgIGlmICh0ZXh0ICE9ICJpbmYiICYmCisgICAgICAgICAgdGV4dCAhPSAiaW5maW5pdHkiICYmCisgICAgICAgICAgdGV4dCAhPSAibmFuIikgeworICAgICAgICBSZXBvcnRFcnJvcigiSW52YWxpZCBmbG9hdCBudW1iZXI6ICIgKyB0ZXh0KTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICB0b2tlbml6ZXJfLk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCB0b2tlbidzIHRleHQgaXMgZXF1YWwgdG8gdGhhdCBzcGVjaWZpZWQuCisgIGJvb2wgTG9va2luZ0F0KGNvbnN0IHN0cmluZyYgdGV4dCkgeworICAgIHJldHVybiB0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0ID09IHRleHQ7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgdG9rZW4ncyB0eXBlIGlzIGVxdWFsIHRvIHRoYXQgc3BlY2lmaWVkLgorICBib29sIExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VG9rZW5UeXBlIHRva2VuX3R5cGUpIHsKKyAgICByZXR1cm4gdG9rZW5pemVyXy5jdXJyZW50KCkudHlwZSA9PSB0b2tlbl90eXBlOworICB9CisKKyAgLy8gQ29uc3VtZXMgYW4gaWRlbnRpZmllciBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSBpZGVudGlmaWVyIHBhcmFtZXRlci4KKyAgLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IG9mIHR5cGUgSURFTlRGSUVSLgorICBib29sIENvbnN1bWVJZGVudGlmaWVyKHN0cmluZyogaWRlbnRpZmllcikgeworICAgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUikpIHsKKyAgICAgICppZGVudGlmaWVyID0gdG9rZW5pemVyXy5jdXJyZW50KCkudGV4dDsKKyAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLy8gSWYgYWxsb3dfZmllbGRfbnVtZXJfIG9yIGFsbG93X3Vua25vd25fZmllbGRfIGlzIHRydWUsIHdlIHNob3VsZCBhYmxlCisgICAgLy8gdG8gcGFyc2UgaW50ZWdlciBpZGVudGlmaWVycy4KKyAgICBpZiAoKGFsbG93X2ZpZWxkX251bWJlcl8gfHwgYWxsb3dfdW5rbm93bl9maWVsZF8pCisgICAgICAgICYmIExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgICAgKmlkZW50aWZpZXIgPSB0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0OworICAgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgaWRlbnRpZmllci4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBDb25zdW1lcyBhIHN0cmluZyBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSB0ZXh0IHBhcmFtZXRlci4KKyAgLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IG9mIHR5cGUgU1RSSU5HLgorICBib29sIENvbnN1bWVTdHJpbmcoc3RyaW5nKiB0ZXh0KSB7CisgICAgaWYgKCFMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HKSkgeworICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdGVkIHN0cmluZy4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICB0ZXh0LT5jbGVhcigpOworICAgIHdoaWxlIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HKSkgeworICAgICAgaW86OlRva2VuaXplcjo6UGFyc2VTdHJpbmdBcHBlbmQodG9rZW5pemVyXy5jdXJyZW50KCkudGV4dCwgdGV4dCk7CisKKyAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gQ29uc3VtZXMgYSB1aW50NjQgYW5kIHNhdmVzIGl0cyB2YWx1ZSBpbiB0aGUgdmFsdWUgcGFyYW1ldGVyLgorICAvLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSB0b2tlbiBpcyBub3Qgb2YgdHlwZSBJTlRFR0VSLgorICBib29sIENvbnN1bWVVbnNpZ25lZEludGVnZXIodWludDY0KiB2YWx1ZSwgdWludDY0IG1heF92YWx1ZSkgeworICAgIGlmICghTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgaW50ZWdlci4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIWlvOjpUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcih0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heF92YWx1ZSwgdmFsdWUpKSB7CisgICAgICBSZXBvcnRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBDb25zdW1lcyBhbiBpbnQ2NCBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSB2YWx1ZSBwYXJhbWV0ZXIuCisgIC8vIE5vdGUgdGhhdCBzaW5jZSB0aGUgdG9rZW5pemVyIGRvZXMgbm90IHN1cHBvcnQgbmVnYXRpdmUgbnVtYmVycywKKyAgLy8gd2UgYWN0dWFsbHkgbWF5IGNvbnN1bWUgYW4gYWRkaXRpb25hbCB0b2tlbiAoZm9yIHRoZSBtaW51cyBzaWduKSBpbiB0aGlzCisgIC8vIG1ldGhvZC4gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IGFuIGludGVnZXIKKyAgLy8gKHNpZ25lZCBvciBvdGhlcndpc2UpLgorICBib29sIENvbnN1bWVTaWduZWRJbnRlZ2VyKGludDY0KiB2YWx1ZSwgdWludDY0IG1heF92YWx1ZSkgeworICAgIGJvb2wgbmVnYXRpdmUgPSBmYWxzZTsKKworICAgIGlmIChUcnlDb25zdW1lKCItIikpIHsKKyAgICAgIG5lZ2F0aXZlID0gdHJ1ZTsKKyAgICAgIC8vIFR3bydzIGNvbXBsZW1lbnQgYWx3YXlzIGFsbG93cyBvbmUgbW9yZSBuZWdhdGl2ZSBpbnRlZ2VyIHRoYW4KKyAgICAgIC8vIHBvc2l0aXZlLgorICAgICAgKyttYXhfdmFsdWU7CisgICAgfQorCisgICAgdWludDY0IHVuc2lnbmVkX3ZhbHVlOworCisgICAgRE8oQ29uc3VtZVVuc2lnbmVkSW50ZWdlcigmdW5zaWduZWRfdmFsdWUsIG1heF92YWx1ZSkpOworCisgICAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50NjQ+KHVuc2lnbmVkX3ZhbHVlKTsKKworICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgKnZhbHVlID0gLSp2YWx1ZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENvbnN1bWVzIGEgdWludDY0IGFuZCBzYXZlcyBpdHMgdmFsdWUgaW4gdGhlIHZhbHVlIHBhcmFtZXRlci4KKyAgLy8gQWNjZXB0cyBkZWNpbWFsIG51bWJlcnMgb25seSwgcmVqZWN0cyBoZXggb3Igb2N0IG51bWJlcnMuCisgIGJvb2wgQ29uc3VtZVVuc2lnbmVkRGVjaW1hbEludGVnZXIodWludDY0KiB2YWx1ZSwgdWludDY0IG1heF92YWx1ZSkgeworICAgIGlmICghTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgaW50ZWdlci4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBjb25zdCBzdHJpbmcmIHRleHQgPSB0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0OworICAgIGlmIChJc0hleE51bWJlcih0ZXh0KSB8fCBJc09jdE51bWJlcih0ZXh0KSkgeworICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdCBhIGRlY2ltYWwgbnVtYmVyLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghaW86OlRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKHRleHQsIG1heF92YWx1ZSwgdmFsdWUpKSB7CisgICAgICBSZXBvcnRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBDb25zdW1lcyBhIGRvdWJsZSBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSB2YWx1ZSBwYXJhbWV0ZXIuCisgIC8vIE5vdGUgdGhhdCBzaW5jZSB0aGUgdG9rZW5pemVyIGRvZXMgbm90IHN1cHBvcnQgbmVnYXRpdmUgbnVtYmVycywKKyAgLy8gd2UgYWN0dWFsbHkgbWF5IGNvbnN1bWUgYW4gYWRkaXRpb25hbCB0b2tlbiAoZm9yIHRoZSBtaW51cyBzaWduKSBpbiB0aGlzCisgIC8vIG1ldGhvZC4gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IGEgZG91YmxlCisgIC8vIChzaWduZWQgb3Igb3RoZXJ3aXNlKS4KKyAgYm9vbCBDb25zdW1lRG91YmxlKGRvdWJsZSogdmFsdWUpIHsKKyAgICBib29sIG5lZ2F0aXZlID0gZmFsc2U7CisKKyAgICBpZiAoVHJ5Q29uc3VtZSgiLSIpKSB7CisgICAgICBuZWdhdGl2ZSA9IHRydWU7CisgICAgfQorCisgICAgLy8gQSBkb3VibGUgY2FuIGFjdHVhbGx5IGJlIGFuIGludGVnZXIsIGFjY29yZGluZyB0byB0aGUgdG9rZW5pemVyLgorICAgIC8vIFRoZXJlZm9yZSwgd2UgbXVzdCBjaGVjayBib3RoIGNhc2VzIGhlcmUuCisgICAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgICAgLy8gV2UgaGF2ZSBmb3VuZCBhbiBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgZG91YmxlLgorICAgICAgdWludDY0IGludGVnZXJfdmFsdWU7CisgICAgICBETyhDb25zdW1lVW5zaWduZWREZWNpbWFsSW50ZWdlcigmaW50ZWdlcl92YWx1ZSwga3VpbnQ2NG1heCkpOworCisgICAgICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxkb3VibGU+KGludGVnZXJfdmFsdWUpOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0ZMT0FUKSkgeworICAgICAgLy8gV2UgaGF2ZSBmb3VuZCBhIGZsb2F0IHZhbHVlIGZvciB0aGUgZG91YmxlLgorICAgICAgKnZhbHVlID0gaW86OlRva2VuaXplcjo6UGFyc2VGbG9hdCh0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0KTsKKworICAgICAgLy8gTWFyayB0aGUgY3VycmVudCB0b2tlbiBhcyBjb25zdW1lZC4KKyAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICBzdHJpbmcgdGV4dCA9IHRva2VuaXplcl8uY3VycmVudCgpLnRleHQ7CisgICAgICBMb3dlclN0cmluZygmdGV4dCk7CisgICAgICBpZiAodGV4dCA9PSAiaW5mIiB8fAorICAgICAgICAgIHRleHQgPT0gImluZmluaXR5IikgeworICAgICAgICAqdmFsdWUgPSBzdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgfSBlbHNlIGlmICh0ZXh0ID09ICJuYW4iKSB7CisgICAgICAgICp2YWx1ZSA9IHN0ZDo6bnVtZXJpY19saW1pdHM8ZG91YmxlPjo6cXVpZXRfTmFOKCk7CisgICAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdGVkIGRvdWJsZS4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgZG91YmxlLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgKnZhbHVlID0gLSp2YWx1ZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENvbnN1bWVzIGEgdG9rZW4gYW5kIGNvbmZpcm1zIHRoYXQgaXQgbWF0Y2hlcyB0aGF0IHNwZWNpZmllZCBpbiB0aGUKKyAgLy8gdmFsdWUgcGFyYW1ldGVyLiBSZXR1cm5zIGZhbHNlIGlmIHRoZSB0b2tlbiBmb3VuZCBkb2VzIG5vdCBtYXRjaCB0aGF0CisgIC8vIHdoaWNoIHdhcyBzcGVjaWZpZWQuCisgIGJvb2wgQ29uc3VtZShjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgICAgY29uc3Qgc3RyaW5nJiBjdXJyZW50X3ZhbHVlID0gdG9rZW5pemVyXy5jdXJyZW50KCkudGV4dDsKKworICAgIGlmIChjdXJyZW50X3ZhbHVlICE9IHZhbHVlKSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgXCIiICsgdmFsdWUgKyAiXCIsIGZvdW5kIFwiIiArIGN1cnJlbnRfdmFsdWUKKyAgICAgICAgICAgICAgICAgICsgIlwiLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHRva2VuaXplcl8uTmV4dCgpOworCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBBdHRlbXB0cyB0byBjb25zdW1lIHRoZSBzdXBwbGllZCB2YWx1ZS4gUmV0dXJucyBmYWxzZSBpZiBhIHRoZQorICAvLyB0b2tlbiBmb3VuZCBkb2VzIG5vdCBtYXRjaCB0aGUgdmFsdWUgc3BlY2lmaWVkLgorICBib29sIFRyeUNvbnN1bWUoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICAgIGlmICh0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0ID09IHZhbHVlKSB7CisgICAgICB0b2tlbml6ZXJfLk5leHQoKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgLy8gQW4gaW50ZXJuYWwgaW5zdGFuY2Ugb2YgdGhlIFRva2VuaXplcidzIGVycm9yIGNvbGxlY3RvciwgdXNlZCB0bworICAvLyBjb2xsZWN0IGFueSBiYXNlLWxldmVsIHBhcnNlIGVycm9ycyBhbmQgZmVlZCB0aGVtIHRvIHRoZSBQYXJzZXJJbXBsLgorICBjbGFzcyBQYXJzZXJFcnJvckNvbGxlY3RvciA6IHB1YmxpYyBpbzo6RXJyb3JDb2xsZWN0b3IgeworICAgcHVibGljOgorICAgIGV4cGxpY2l0IFBhcnNlckVycm9yQ29sbGVjdG9yKFRleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2VySW1wbCogcGFyc2VyKSA6CisgICAgICAgIHBhcnNlcl8ocGFyc2VyKSB7IH0KKworICAgIHZpcnR1YWwgflBhcnNlckVycm9yQ29sbGVjdG9yKCkgeyB9CisKKyAgICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgICAgcGFyc2VyXy0+UmVwb3J0RXJyb3IobGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHZvaWQgQWRkV2FybmluZyhpbnQgbGluZSwgaW50IGNvbHVtbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgICBwYXJzZXJfLT5SZXBvcnRXYXJuaW5nKGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgICAgfQorCisgICBwcml2YXRlOgorICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQYXJzZXJFcnJvckNvbGxlY3Rvcik7CisgICAgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZXJJbXBsKiBwYXJzZXJfOworICB9OworCisgIGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKyAgVGV4dEZvcm1hdDo6RmluZGVyKiBmaW5kZXJfOworICBQYXJzZUluZm9UcmVlKiBwYXJzZV9pbmZvX3RyZWVfOworICBQYXJzZXJFcnJvckNvbGxlY3RvciB0b2tlbml6ZXJfZXJyb3JfY29sbGVjdG9yXzsKKyAgaW86OlRva2VuaXplciB0b2tlbml6ZXJfOworICBjb25zdCBEZXNjcmlwdG9yKiByb290X21lc3NhZ2VfdHlwZV87CisgIFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5IHNpbmd1bGFyX292ZXJ3cml0ZV9wb2xpY3lfOworICBjb25zdCBib29sIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfOworICBjb25zdCBib29sIGFsbG93X3Vua25vd25fZmllbGRfOworICBjb25zdCBib29sIGFsbG93X3Vua25vd25fZW51bV87CisgIGNvbnN0IGJvb2wgYWxsb3dfZmllbGRfbnVtYmVyXzsKKyAgYm9vbCBoYWRfZXJyb3JzXzsKK307CisKKyN1bmRlZiBETworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEludGVybmFsIGNsYXNzIGZvciB3cml0aW5nIHRleHQgdG8gdGhlIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbS4gQWRhcHRlZAorLy8gZnJvbSB0aGUgUHJpbnRlciBmb3VuZCBpbiAvL2dvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmgKK2NsYXNzIFRleHRGb3JtYXQ6OlByaW50ZXI6OlRleHRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgVGV4dEdlbmVyYXRvcihpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5pdGlhbF9pbmRlbnRfbGV2ZWwpCisgICAgOiBvdXRwdXRfKG91dHB1dCksCisgICAgICBidWZmZXJfKE5VTEwpLAorICAgICAgYnVmZmVyX3NpemVfKDApLAorICAgICAgYXRfc3RhcnRfb2ZfbGluZV8odHJ1ZSksCisgICAgICBmYWlsZWRfKGZhbHNlKSwKKyAgICAgIGluZGVudF8oIiIpLAorICAgICAgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfKGluaXRpYWxfaW5kZW50X2xldmVsKSB7CisgICAgaW5kZW50Xy5yZXNpemUoaW5pdGlhbF9pbmRlbnRfbGV2ZWxfICogMiwgJyAnKTsKKyAgfQorCisgIH5UZXh0R2VuZXJhdG9yKCkgeworICAgIC8vIE9ubHkgQmFja1VwKCkgaWYgd2UncmUgc3VyZSB3ZSd2ZSBzdWNjZXNzZnVsbHkgY2FsbGVkIE5leHQoKSBhdCBsZWFzdAorICAgIC8vIG9uY2UuCisgICAgaWYgKCFmYWlsZWRfICYmIGJ1ZmZlcl9zaXplXyA+IDApIHsKKyAgICAgIG91dHB1dF8tPkJhY2tVcChidWZmZXJfc2l6ZV8pOworICAgIH0KKyAgfQorCisgIC8vIEluZGVudCB0ZXh0IGJ5IHR3byBzcGFjZXMuICBBZnRlciBjYWxsaW5nIEluZGVudCgpLCB0d28gc3BhY2VzIHdpbGwgYmUKKyAgLy8gaW5zZXJ0ZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIGxpbmUgb2YgdGV4dC4gIEluZGVudCgpIG1heSBiZSBjYWxsZWQKKyAgLy8gbXVsdGlwbGUgdGltZXMgdG8gcHJvZHVjZSBkZWVwZXIgaW5kZW50cy4KKyAgdm9pZCBJbmRlbnQoKSB7CisgICAgaW5kZW50XyArPSAiICAiOworICB9CisKKyAgLy8gUmVkdWNlcyB0aGUgY3VycmVudCBpbmRlbnQgbGV2ZWwgYnkgdHdvIHNwYWNlcywgb3IgY3Jhc2hlcyBpZiB0aGUgaW5kZW50CisgIC8vIGxldmVsIGlzIHplcm8uCisgIHZvaWQgT3V0ZGVudCgpIHsKKyAgICBpZiAoaW5kZW50Xy5lbXB0eSgpIHx8CisgICAgICAgIGluZGVudF8uc2l6ZSgpIDwgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfICogMikgeworICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICIgT3V0ZGVudCgpIHdpdGhvdXQgbWF0Y2hpbmcgSW5kZW50KCkuIjsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbmRlbnRfLnJlc2l6ZShpbmRlbnRfLnNpemUoKSAtIDIpOworICB9CisKKyAgLy8gUHJpbnQgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgdm9pZCBQcmludChjb25zdCBzdHJpbmcmIHN0cikgeworICAgIFByaW50KHN0ci5kYXRhKCksIHN0ci5zaXplKCkpOworICB9CisKKyAgLy8gUHJpbnQgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgdm9pZCBQcmludChjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgUHJpbnQodGV4dCwgc3RybGVuKHRleHQpKTsKKyAgfQorCisgIC8vIFByaW50IHRleHQgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgaW50IHNpemUpIHsKKyAgICBpbnQgcG9zID0gMDsgIC8vIFRoZSBudW1iZXIgb2YgYnl0ZXMgd2UndmUgd3JpdHRlbiBzbyBmYXIuCisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgaWYgKHRleHRbaV0gPT0gJ1xuJykgeworICAgICAgICAvLyBTYXcgbmV3bGluZS4gIElmIHRoZXJlIGlzIG1vcmUgdGV4dCwgd2UgbWF5IG5lZWQgdG8gaW5zZXJ0IGFuIGluZGVudAorICAgICAgICAvLyBoZXJlLiAgU28sIHdyaXRlIHdoYXQgd2UgaGF2ZSBzbyBmYXIsIGluY2x1ZGluZyB0aGUgJ1xuJy4KKyAgICAgICAgV3JpdGUodGV4dCArIHBvcywgaSAtIHBvcyArIDEpOworICAgICAgICBwb3MgPSBpICsgMTsKKworICAgICAgICAvLyBTZXR0aW5nIHRoaXMgdHJ1ZSB3aWxsIGNhdXNlIHRoZSBuZXh0IFdyaXRlKCkgdG8gaW5zZXJ0IGFuIGluZGVudAorICAgICAgICAvLyBmaXJzdC4KKyAgICAgICAgYXRfc3RhcnRfb2ZfbGluZV8gPSB0cnVlOworICAgICAgfQorICAgIH0KKworICAgIC8vIFdyaXRlIHRoZSByZXN0LgorICAgIFdyaXRlKHRleHQgKyBwb3MsIHNpemUgLSBwb3MpOworICB9CisKKyAgLy8gVHJ1ZSBpZiBhbnkgd3JpdGUgdG8gdGhlIHVuZGVybHlpbmcgc3RyZWFtIGZhaWxlZC4gIChXZSBkb24ndCBqdXN0CisgIC8vIGNyYXNoIGluIHRoaXMgY2FzZSBiZWNhdXNlIHRoaXMgaXMgYW4gSS9PIGZhaWx1cmUsIG5vdCBhIHByb2dyYW1taW5nCisgIC8vIGVycm9yLikKKyAgYm9vbCBmYWlsZWQoKSBjb25zdCB7IHJldHVybiBmYWlsZWRfOyB9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGV4dEdlbmVyYXRvcik7CisKKyAgdm9pZCBXcml0ZShjb25zdCBjaGFyKiBkYXRhLCBpbnQgc2l6ZSkgeworICAgIGlmIChmYWlsZWRfKSByZXR1cm47CisgICAgaWYgKHNpemUgPT0gMCkgcmV0dXJuOworCisgICAgaWYgKGF0X3N0YXJ0X29mX2xpbmVfKSB7CisgICAgICAvLyBJbnNlcnQgYW4gaW5kZW50LgorICAgICAgYXRfc3RhcnRfb2ZfbGluZV8gPSBmYWxzZTsKKyAgICAgIFdyaXRlKGluZGVudF8uZGF0YSgpLCBpbmRlbnRfLnNpemUoKSk7CisgICAgICBpZiAoZmFpbGVkXykgcmV0dXJuOworICAgIH0KKworICAgIHdoaWxlIChzaXplID4gYnVmZmVyX3NpemVfKSB7CisgICAgICAvLyBEYXRhIGV4Y2VlZHMgc3BhY2UgaW4gdGhlIGJ1ZmZlci4gIENvcHkgd2hhdCB3ZSBjYW4gYW5kIHJlcXVlc3QgYQorICAgICAgLy8gbmV3IGJ1ZmZlci4KKyAgICAgIG1lbWNweShidWZmZXJfLCBkYXRhLCBidWZmZXJfc2l6ZV8pOworICAgICAgZGF0YSArPSBidWZmZXJfc2l6ZV87CisgICAgICBzaXplIC09IGJ1ZmZlcl9zaXplXzsKKyAgICAgIHZvaWQqIHZvaWRfYnVmZmVyOworICAgICAgZmFpbGVkXyA9ICFvdXRwdXRfLT5OZXh0KCZ2b2lkX2J1ZmZlciwgJmJ1ZmZlcl9zaXplXyk7CisgICAgICBpZiAoZmFpbGVkXykgcmV0dXJuOworICAgICAgYnVmZmVyXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHZvaWRfYnVmZmVyKTsKKyAgICB9CisKKyAgICAvLyBCdWZmZXIgaXMgYmlnIGVub3VnaCB0byByZWNlaXZlIHRoZSBkYXRhOyBjb3B5IGl0LgorICAgIG1lbWNweShidWZmZXJfLCBkYXRhLCBzaXplKTsKKyAgICBidWZmZXJfICs9IHNpemU7CisgICAgYnVmZmVyX3NpemVfIC09IHNpemU7CisgIH0KKworICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIGNvbnN0IG91dHB1dF87CisgIGNoYXIqIGJ1ZmZlcl87CisgIGludCBidWZmZXJfc2l6ZV87CisgIGJvb2wgYXRfc3RhcnRfb2ZfbGluZV87CisgIGJvb2wgZmFpbGVkXzsKKworICBzdHJpbmcgaW5kZW50XzsKKyAgaW50IGluaXRpYWxfaW5kZW50X2xldmVsXzsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitUZXh0Rm9ybWF0OjpGaW5kZXI6On5GaW5kZXIoKSB7Cit9CisKK1RleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2VyKCkKKyAgOiBlcnJvcl9jb2xsZWN0b3JfKE5VTEwpLAorICAgIGZpbmRlcl8oTlVMTCksCisgICAgcGFyc2VfaW5mb190cmVlXyhOVUxMKSwKKyAgICBhbGxvd19wYXJ0aWFsXyhmYWxzZSksCisgICAgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZF8oZmFsc2UpLAorICAgIGFsbG93X3Vua25vd25fZmllbGRfKGZhbHNlKSwKKyAgICBhbGxvd191bmtub3duX2VudW1fKGZhbHNlKSwKKyAgICBhbGxvd19maWVsZF9udW1iZXJfKGZhbHNlKSwKKyAgICBhbGxvd19yZWxheGVkX3doaXRlc3BhY2VfKGZhbHNlKSwKKyAgICBhbGxvd19zaW5ndWxhcl9vdmVyd3JpdGVzXyhmYWxzZSkgeworfQorCitUZXh0Rm9ybWF0OjpQYXJzZXI6On5QYXJzZXIoKSB7fQorCitib29sIFRleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCkgeworICBvdXRwdXQtPkNsZWFyKCk7CisKKyAgUGFyc2VySW1wbDo6U2luZ3VsYXJPdmVyd3JpdGVQb2xpY3kgb3ZlcndyaXRlc19wb2xpY3kgPQorICAgICAgYWxsb3dfc2luZ3VsYXJfb3ZlcndyaXRlc18KKyAgICAgID8gUGFyc2VySW1wbDo6QUxMT1dfU0lOR1VMQVJfT1ZFUldSSVRFUworICAgICAgOiBQYXJzZXJJbXBsOjpGT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUzsKKworICBQYXJzZXJJbXBsIHBhcnNlcihvdXRwdXQtPkdldERlc2NyaXB0b3IoKSwgaW5wdXQsIGVycm9yX2NvbGxlY3Rvcl8sCisgICAgICAgICAgICAgICAgICAgIGZpbmRlcl8sIHBhcnNlX2luZm9fdHJlZV8sCisgICAgICAgICAgICAgICAgICAgIG92ZXJ3cml0ZXNfcG9saWN5LAorICAgICAgICAgICAgICAgICAgICBhbGxvd19jYXNlX2luc2Vuc2l0aXZlX2ZpZWxkXywgYWxsb3dfdW5rbm93bl9maWVsZF8sCisgICAgICAgICAgICAgICAgICAgIGFsbG93X3Vua25vd25fZW51bV8sIGFsbG93X2ZpZWxkX251bWJlcl8sCisgICAgICAgICAgICAgICAgICAgIGFsbG93X3JlbGF4ZWRfd2hpdGVzcGFjZV8pOworICByZXR1cm4gTWVyZ2VVc2luZ0ltcGwoaW5wdXQsIG91dHB1dCwgJnBhcnNlcik7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShpbnB1dC5kYXRhKCksIGlucHV0LnNpemUoKSk7CisgIHJldHVybiBQYXJzZSgmaW5wdXRfc3RyZWFtLCBvdXRwdXQpOworfQorCitib29sIFRleHRGb3JtYXQ6OlBhcnNlcjo6TWVyZ2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCkgeworICBQYXJzZXJJbXBsIHBhcnNlcihvdXRwdXQtPkdldERlc2NyaXB0b3IoKSwgaW5wdXQsIGVycm9yX2NvbGxlY3Rvcl8sCisgICAgICAgICAgICAgICAgICAgIGZpbmRlcl8sIHBhcnNlX2luZm9fdHJlZV8sCisgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGw6OkFMTE9XX1NJTkdVTEFSX09WRVJXUklURVMsCisgICAgICAgICAgICAgICAgICAgIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfLCBhbGxvd191bmtub3duX2ZpZWxkXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfdW5rbm93bl9lbnVtXywgYWxsb3dfZmllbGRfbnVtYmVyXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfcmVsYXhlZF93aGl0ZXNwYWNlXyk7CisgIHJldHVybiBNZXJnZVVzaW5nSW1wbChpbnB1dCwgb3V0cHV0LCAmcGFyc2VyKTsKK30KKworYm9vbCBUZXh0Rm9ybWF0OjpQYXJzZXI6Ok1lcmdlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBvdXRwdXQpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKGlucHV0LmRhdGEoKSwgaW5wdXQuc2l6ZSgpKTsKKyAgcmV0dXJuIE1lcmdlKCZpbnB1dF9zdHJlYW0sIG91dHB1dCk7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UGFyc2VyOjpNZXJnZVVzaW5nSW1wbChpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogLyogaW5wdXQgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGwqIHBhcnNlcl9pbXBsKSB7CisgIGlmICghcGFyc2VyX2ltcGwtPlBhcnNlKG91dHB1dCkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCFhbGxvd19wYXJ0aWFsXyAmJiAhb3V0cHV0LT5Jc0luaXRpYWxpemVkKCkpIHsKKyAgICB2ZWN0b3I8c3RyaW5nPiBtaXNzaW5nX2ZpZWxkczsKKyAgICBvdXRwdXQtPkZpbmRJbml0aWFsaXphdGlvbkVycm9ycygmbWlzc2luZ19maWVsZHMpOworICAgIHBhcnNlcl9pbXBsLT5SZXBvcnRFcnJvcigtMSwgMCwgIk1lc3NhZ2UgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpvaW4obWlzc2luZ19maWVsZHMsICIsICIpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKAorICAgIGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlKiBvdXRwdXQpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKGlucHV0LmRhdGEoKSwgaW5wdXQuc2l6ZSgpKTsKKyAgUGFyc2VySW1wbCBwYXJzZXIob3V0cHV0LT5HZXREZXNjcmlwdG9yKCksICZpbnB1dF9zdHJlYW0sIGVycm9yX2NvbGxlY3Rvcl8sCisgICAgICAgICAgICAgICAgICAgIGZpbmRlcl8sIHBhcnNlX2luZm9fdHJlZV8sCisgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGw6OkFMTE9XX1NJTkdVTEFSX09WRVJXUklURVMsCisgICAgICAgICAgICAgICAgICAgIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfLCBhbGxvd191bmtub3duX2ZpZWxkXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfdW5rbm93bl9lbnVtXywgYWxsb3dfZmllbGRfbnVtYmVyXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfcmVsYXhlZF93aGl0ZXNwYWNlXyk7CisgIHJldHVybiBwYXJzZXIuUGFyc2VGaWVsZChmaWVsZCwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6UGFyc2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIHJldHVybiBQYXJzZXIoKS5QYXJzZShpbnB1dCwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6TWVyZ2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIHJldHVybiBQYXJzZXIoKS5NZXJnZShpbnB1dCwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIHJldHVybiBQYXJzZXIoKS5QYXJzZUZyb21TdHJpbmcoaW5wdXQsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCkgeworICByZXR1cm4gUGFyc2VyKCkuTWVyZ2VGcm9tU3RyaW5nKGlucHV0LCBvdXRwdXQpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIEZpZWxkVmFsdWVQcmludGVyLiBUaGUgYmFzZSBjbGFzcyBqdXN0CisvLyBkb2VzIHNpbXBsZSBmb3JtYXR0aW5nLiBUaGF0IHdheSwgZGVyaXZpbmcgY2xhc3NlcyBjb3VsZCBkZWNpZGUgdG8gZmFsbGJhY2sKKy8vIHRvIHRoYXQgYmVoYXZpb3IuCitUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6RmllbGRWYWx1ZVByaW50ZXIoKSB7fQorVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6On5GaWVsZFZhbHVlUHJpbnRlcigpIHt9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50Qm9vbChib29sIHZhbCkgY29uc3QgeworICByZXR1cm4gdmFsID8gInRydWUiIDogImZhbHNlIjsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRJbnQzMihpbnQzMiB2YWwpIGNvbnN0IHsKKyAgcmV0dXJuIFNpbXBsZUl0b2EodmFsKTsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRVSW50MzIodWludDMyIHZhbCkgY29uc3QgeworICByZXR1cm4gU2ltcGxlSXRvYSh2YWwpOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludEludDY0KGludDY0IHZhbCkgY29uc3QgeworICByZXR1cm4gU2ltcGxlSXRvYSh2YWwpOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludFVJbnQ2NCh1aW50NjQgdmFsKSBjb25zdCB7CisgIHJldHVybiBTaW1wbGVJdG9hKHZhbCk7Cit9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50RmxvYXQoZmxvYXQgdmFsKSBjb25zdCB7CisgIHJldHVybiBTaW1wbGVGdG9hKHZhbCk7Cit9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50RG91YmxlKGRvdWJsZSB2YWwpIGNvbnN0IHsKKyAgcmV0dXJuIFNpbXBsZUR0b2EodmFsKTsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRTdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWwpIGNvbnN0IHsKKyAgcmV0dXJuIFN0ckNhdCgiXCIiLCBDRXNjYXBlKHZhbCksICJcIiIpOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludEJ5dGVzKGNvbnN0IHN0cmluZyYgdmFsKSBjb25zdCB7CisgIHJldHVybiBQcmludFN0cmluZyh2YWwpOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludEVudW0oaW50MzIgdmFsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIHJldHVybiBuYW1lOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludEZpZWxkTmFtZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgLy8gV2Ugc3BlY2lhbC1jYXNlIE1lc3NhZ2VTZXQgZWxlbWVudHMgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBwcm90bzEuCisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkKKyAgICAgICAgJiYgZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRQorICAgICAgICAmJiBmaWVsZC0+aXNfb3B0aW9uYWwoKQorICAgICAgICAmJiBmaWVsZC0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSB7CisgICAgICByZXR1cm4gU3RyQ2F0KCJbIiwgZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5mdWxsX25hbWUoKSwgIl0iKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIFN0ckNhdCgiWyIsIGZpZWxkLT5mdWxsX25hbWUoKSwgIl0iKTsKKyAgICB9CisgIH0gZWxzZSBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAvLyBHcm91cHMgbXVzdCBiZSBzZXJpYWxpemVkIHdpdGggdGhlaXIgb3JpZ2luYWwgY2FwaXRhbGl6YXRpb24uCisgICAgcmV0dXJuIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+bmFtZSgpOworICB9IGVsc2UgeworICAgIHJldHVybiBmaWVsZC0+bmFtZSgpOworICB9Cit9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50TWVzc2FnZVN0YXJ0KAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgaW50IGZpZWxkX2luZGV4LAorICAgIGludCBmaWVsZF9jb3VudCwKKyAgICBib29sIHNpbmdsZV9saW5lX21vZGUpIGNvbnN0IHsKKyAgcmV0dXJuIHNpbmdsZV9saW5lX21vZGUgPyAiIHsgIiA6ICIge1xuIjsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRNZXNzYWdlRW5kKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgaW50IGZpZWxkX2luZGV4LAorICAgIGludCBmaWVsZF9jb3VudCwKKyAgICBib29sIHNpbmdsZV9saW5lX21vZGUpIGNvbnN0IHsKKyAgcmV0dXJuIHNpbmdsZV9saW5lX21vZGUgPyAifSAiIDogIn1cbiI7Cit9CisKK25hbWVzcGFjZSB7CisvLyBPdXIgb3duIHNwZWNpYWxpemF0aW9uOiBmb3IgVVRGOCBlc2NhcGVkIHN0cmluZ3MuCitjbGFzcyBGaWVsZFZhbHVlUHJpbnRlclV0ZjhFc2NhcGluZyA6IHB1YmxpYyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlciB7CisgcHVibGljOgorICB2aXJ0dWFsIHN0cmluZyBQcmludFN0cmluZyhjb25zdCBzdHJpbmcmIHZhbCkgY29uc3QgeworICAgIHJldHVybiBTdHJDYXQoIlwiIiwgc3RyaW5nczo6VXRmOFNhZmVDRXNjYXBlKHZhbCksICJcIiIpOworICB9CisgIHZpcnR1YWwgc3RyaW5nIFByaW50Qnl0ZXMoY29uc3Qgc3RyaW5nJiB2YWwpIGNvbnN0IHsKKyAgICByZXR1cm4gVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50U3RyaW5nKHZhbCk7CisgIH0KK307CisKK30gIC8vIG5hbWVzcGFjZQorCitUZXh0Rm9ybWF0OjpQcmludGVyOjpQcmludGVyKCkKKyAgOiBpbml0aWFsX2luZGVudF9sZXZlbF8oMCksCisgICAgc2luZ2xlX2xpbmVfbW9kZV8oZmFsc2UpLAorICAgIHVzZV9maWVsZF9udW1iZXJfKGZhbHNlKSwKKyAgICB1c2Vfc2hvcnRfcmVwZWF0ZWRfcHJpbWl0aXZlc18oZmFsc2UpLAorICAgIGhpZGVfdW5rbm93bl9maWVsZHNfKGZhbHNlKSwKKyAgICBwcmludF9tZXNzYWdlX2ZpZWxkc19pbl9pbmRleF9vcmRlcl8oZmFsc2UpIHsKKyAgU2V0VXNlVXRmOFN0cmluZ0VzY2FwaW5nKGZhbHNlKTsKK30KKworVGV4dEZvcm1hdDo6UHJpbnRlcjo6flByaW50ZXIoKSB7CisgIFNUTERlbGV0ZVZhbHVlcygmY3VzdG9tX3ByaW50ZXJzXyk7Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6U2V0VXNlVXRmOFN0cmluZ0VzY2FwaW5nKGJvb2wgYXNfdXRmOCkgeworICBTZXREZWZhdWx0RmllbGRWYWx1ZVByaW50ZXIoYXNfdXRmOAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgRmllbGRWYWx1ZVByaW50ZXJVdGY4RXNjYXBpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgRmllbGRWYWx1ZVByaW50ZXIoKSk7Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6U2V0RGVmYXVsdEZpZWxkVmFsdWVQcmludGVyKAorICAgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyKSB7CisgIGRlZmF1bHRfZmllbGRfdmFsdWVfcHJpbnRlcl8ucmVzZXQocHJpbnRlcik7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyKSB7CisgIHJldHVybiBmaWVsZCAhPSBOVUxMICYmIHByaW50ZXIgIT0gTlVMTCAmJgorICAgICAgICAgY3VzdG9tX3ByaW50ZXJzXy5pbnNlcnQoc3RkOjptYWtlX3BhaXIoZmllbGQsIHByaW50ZXIpKS5zZWNvbmQ7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0sob3V0cHV0KSA8PCAib3V0cHV0IHNwZWNpZmllZCBpcyBOVUxMIjsKKworICBvdXRwdXQtPmNsZWFyKCk7CisgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbShvdXRwdXQpOworCisgIHJldHVybiBQcmludChtZXNzYWdlLCAmb3V0cHV0X3N0cmVhbSk7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICBzdHJpbmcqIG91dHB1dCkgY29uc3QgeworICBHT09HTEVfRENIRUNLKG91dHB1dCkgPDwgIm91dHB1dCBzcGVjaWZpZWQgaXMgTlVMTCI7CisKKyAgb3V0cHV0LT5jbGVhcigpOworICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0ob3V0cHV0KTsKKyAgcmV0dXJuIFByaW50VW5rbm93bkZpZWxkcyh1bmtub3duX2ZpZWxkcywgJm91dHB1dF9zdHJlYW0pOworfQorCitib29sIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIFRleHRHZW5lcmF0b3IgZ2VuZXJhdG9yKG91dHB1dCwgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfKTsKKworICBQcmludChtZXNzYWdlLCBnZW5lcmF0b3IpOworCisgIC8vIE91dHB1dCBmYWxzZSBpZiB0aGUgZ2VuZXJhdG9yIGZhaWxlZCBpbnRlcm5hbGx5LgorICByZXR1cm4gIWdlbmVyYXRvci5mYWlsZWQoKTsKK30KKworYm9vbCBUZXh0Rm9ybWF0OjpQcmludGVyOjpQcmludFVua25vd25GaWVsZHMoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBUZXh0R2VuZXJhdG9yIGdlbmVyYXRvcihvdXRwdXQsIGluaXRpYWxfaW5kZW50X2xldmVsXyk7CisKKyAgUHJpbnRVbmtub3duRmllbGRzKHVua25vd25fZmllbGRzLCBnZW5lcmF0b3IpOworCisgIC8vIE91dHB1dCBmYWxzZSBpZiB0aGUgZ2VuZXJhdG9yIGZhaWxlZCBpbnRlcm5hbGx5LgorICByZXR1cm4gIWdlbmVyYXRvci5mYWlsZWQoKTsKK30KKworbmFtZXNwYWNlIHsKKy8vIENvbXBhcmlzb24gZnVuY3RvciBmb3Igc29ydGluZyBGaWVsZERlc2NyaXB0b3JzIGJ5IGZpZWxkIGluZGV4Lgorc3RydWN0IEZpZWxkSW5kZXhTb3J0ZXIgeworICBib29sIG9wZXJhdG9yKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBsZWZ0LAorICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByaWdodCkgY29uc3QgeworICAgIHJldHVybiBsZWZ0LT5pbmRleCgpIDwgcmlnaHQtPmluZGV4KCk7CisgIH0KK307Cit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBUZXh0Rm9ybWF0OjpQcmludGVyOjpQcmludChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0IHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UsICZmaWVsZHMpOworICBpZiAocHJpbnRfbWVzc2FnZV9maWVsZHNfaW5faW5kZXhfb3JkZXJfKSB7CisgICAgc3RkOjpzb3J0KGZpZWxkcy5iZWdpbigpLCBmaWVsZHMuZW5kKCksIEZpZWxkSW5kZXhTb3J0ZXIoKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBQcmludEZpZWxkKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkc1tpXSwgZ2VuZXJhdG9yKTsKKyAgfQorICBpZiAoIWhpZGVfdW5rbm93bl9maWVsZHNfKSB7CisgICAgUHJpbnRVbmtub3duRmllbGRzKHJlZmxlY3Rpb24tPkdldFVua25vd25GaWVsZHMobWVzc2FnZSksIGdlbmVyYXRvcik7CisgIH0KK30KKwordm9pZCBUZXh0Rm9ybWF0OjpQcmludGVyOjpQcmludEZpZWxkVmFsdWVUb1N0cmluZygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IGluZGV4LAorICAgIHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisKKyAgR09PR0xFX0RDSEVDSyhvdXRwdXQpIDw8ICJvdXRwdXQgc3BlY2lmaWVkIGlzIE5VTEwiOworCisgIG91dHB1dC0+Y2xlYXIoKTsKKyAgaW86OlN0cmluZ091dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKG91dHB1dCk7CisgIFRleHRHZW5lcmF0b3IgZ2VuZXJhdG9yKCZvdXRwdXRfc3RyZWFtLCBpbml0aWFsX2luZGVudF9sZXZlbF8pOworCisgIFByaW50RmllbGRWYWx1ZShtZXNzYWdlLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKSwgZmllbGQsIGluZGV4LCBnZW5lcmF0b3IpOworfQorCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50RmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdCB7CisgIGlmICh1c2Vfc2hvcnRfcmVwZWF0ZWRfcHJpbWl0aXZlc18gJiYKKyAgICAgIGZpZWxkLT5pc19yZXBlYXRlZCgpICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIFByaW50U2hvcnRSZXBlYXRlZEZpZWxkKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkLCBnZW5lcmF0b3IpOworICAgIHJldHVybjsKKyAgfQorCisgIGludCBjb3VudCA9IDA7CisKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgY291bnQgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgZmllbGQpOworICB9IGVsc2UgaWYgKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgIGNvdW50ID0gMTsKKyAgfQorCisgIGZvciAoaW50IGogPSAwOyBqIDwgY291bnQ7ICsraikgeworICAgIGNvbnN0IGludCBmaWVsZF9pbmRleCA9IGZpZWxkLT5pc19yZXBlYXRlZCgpID8gaiA6IC0xOworCisgICAgUHJpbnRGaWVsZE5hbWUobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQsIGdlbmVyYXRvcik7CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyID0gRmluZFdpdGhEZWZhdWx0KAorICAgICAgICAgIGN1c3RvbV9wcmludGVyc18sIGZpZWxkLCBkZWZhdWx0X2ZpZWxkX3ZhbHVlX3ByaW50ZXJfLmdldCgpKTsKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAgICAgZmllbGQtPmlzX3JlcGVhdGVkKCkKKyAgICAgICAgICAgICAgPyByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgZmllbGQsIGopCisgICAgICAgICAgICAgIDogcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBmaWVsZCk7CisgICAgICBnZW5lcmF0b3IuUHJpbnQoCisgICAgICAgICAgcHJpbnRlci0+UHJpbnRNZXNzYWdlU3RhcnQoCisgICAgICAgICAgICAgIHN1Yl9tZXNzYWdlLCBmaWVsZF9pbmRleCwgY291bnQsIHNpbmdsZV9saW5lX21vZGVfKSk7CisgICAgICBnZW5lcmF0b3IuSW5kZW50KCk7CisgICAgICBQcmludChzdWJfbWVzc2FnZSwgZ2VuZXJhdG9yKTsKKyAgICAgIGdlbmVyYXRvci5PdXRkZW50KCk7CisgICAgICBnZW5lcmF0b3IuUHJpbnQoCisgICAgICAgICAgcHJpbnRlci0+UHJpbnRNZXNzYWdlRW5kKAorICAgICAgICAgICAgICBzdWJfbWVzc2FnZSwgZmllbGRfaW5kZXgsIGNvdW50LCBzaW5nbGVfbGluZV9tb2RlXykpOworICAgIH0gZWxzZSB7CisgICAgICBnZW5lcmF0b3IuUHJpbnQoIjogIik7CisgICAgICAvLyBXcml0ZSB0aGUgZmllbGQgdmFsdWUuCisgICAgICBQcmludEZpZWxkVmFsdWUobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQsIGZpZWxkX2luZGV4LCBnZW5lcmF0b3IpOworICAgICAgaWYgKHNpbmdsZV9saW5lX21vZGVfKSB7CisgICAgICAgIGdlbmVyYXRvci5QcmludCgiICIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KCJcbiIpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50U2hvcnRSZXBlYXRlZEZpZWxkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3QgeworICAvLyBQcmludCBwcmltaXRpdmUgcmVwZWF0ZWQgZmllbGQgaW4gc2hvcnQgZm9ybS4KKyAgUHJpbnRGaWVsZE5hbWUobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQsIGdlbmVyYXRvcik7CisKKyAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgZmllbGQpOworICBnZW5lcmF0b3IuUHJpbnQoIjogWyIpOworICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgIGlmIChpID4gMCkgZ2VuZXJhdG9yLlByaW50KCIsICIpOworICAgIFByaW50RmllbGRWYWx1ZShtZXNzYWdlLCByZWZsZWN0aW9uLCBmaWVsZCwgaSwgZ2VuZXJhdG9yKTsKKyAgfQorICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICBnZW5lcmF0b3IuUHJpbnQoIl0gIik7CisgIH0gZWxzZSB7CisgICAgZ2VuZXJhdG9yLlByaW50KCJdXG4iKTsKKyAgfQorfQorCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50RmllbGROYW1lKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3QgeworICAvLyBpZiB1c2VfZmllbGRfbnVtYmVyXyBpcyB0cnVlLCBwcmludHMgZmllbGQgbnVtYmVyIGluc3RlYWQKKyAgLy8gb2YgZmllbGQgbmFtZS4KKyAgaWYgKHVzZV9maWVsZF9udW1iZXJfKSB7CisgICAgZ2VuZXJhdG9yLlByaW50KFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKSk7CisgICAgcmV0dXJuOworICB9CisKKyAgY29uc3QgRmllbGRWYWx1ZVByaW50ZXIqIHByaW50ZXIgPSBGaW5kV2l0aERlZmF1bHQoCisgICAgICBjdXN0b21fcHJpbnRlcnNfLCBmaWVsZCwgZGVmYXVsdF9maWVsZF92YWx1ZV9wcmludGVyXy5nZXQoKSk7CisgIGdlbmVyYXRvci5QcmludChwcmludGVyLT5QcmludEZpZWxkTmFtZShtZXNzYWdlLCByZWZsZWN0aW9uLCBmaWVsZCkpOworfQorCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50RmllbGRWYWx1ZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgaW5kZXgsCisgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0soZmllbGQtPmlzX3JlcGVhdGVkKCkgfHwgKGluZGV4ID09IC0xKSkKKyAgICAgIDw8ICJJbmRleCBtdXN0IGJlIC0xIGZvciBub24tcmVwZWF0ZWQgZmllbGRzIjsKKworICBjb25zdCBGaWVsZFZhbHVlUHJpbnRlciogcHJpbnRlcgorICAgICAgPSBGaW5kV2l0aERlZmF1bHQoY3VzdG9tX3ByaW50ZXJzXywgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2ZpZWxkX3ZhbHVlX3ByaW50ZXJfLmdldCgpKTsKKworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIE9VVFBVVF9GSUVMRChDUFBUWVBFLCBNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBnZW5lcmF0b3IuUHJpbnQocHJpbnRlci0+UHJpbnQjI01FVEhPRChmaWVsZC0+aXNfcmVwZWF0ZWQoKSAgICAgICBcCisgICAgICAgICAgICAgICA/IHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkIyNNRVRIT0QobWVzc2FnZSwgZmllbGQsIGluZGV4KSBcCisgICAgICAgICAgICAgICA6IHJlZmxlY3Rpb24tPkdldCMjTUVUSE9EKG1lc3NhZ2UsIGZpZWxkKSkpOyAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrCisKKyAgICBPVVRQVVRfRklFTEQoIElOVDMyLCAgSW50MzIpOworICAgIE9VVFBVVF9GSUVMRCggSU5UNjQsICBJbnQ2NCk7CisgICAgT1VUUFVUX0ZJRUxEKFVJTlQzMiwgVUludDMyKTsKKyAgICBPVVRQVVRfRklFTEQoVUlOVDY0LCBVSW50NjQpOworICAgIE9VVFBVVF9GSUVMRCggRkxPQVQsICBGbG9hdCk7CisgICAgT1VUUFVUX0ZJRUxEKERPVUJMRSwgRG91YmxlKTsKKyAgICBPVVRQVVRfRklFTEQoICBCT09MLCAgIEJvb2wpOworI3VuZGVmIE9VVFBVVF9GSUVMRAorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICBzdHJpbmcgc2NyYXRjaDsKKyAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKQorICAgICAgICAgID8gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbmRleCwgJnNjcmF0Y2gpCisgICAgICAgICAgOiByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgZmllbGQsICZzY3JhdGNoKTsKKyAgICAgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KHByaW50ZXItPlByaW50U3RyaW5nKHZhbHVlKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBHT09HTEVfRENIRUNLX0VRKGZpZWxkLT50eXBlKCksIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyk7CisgICAgICAgIGdlbmVyYXRvci5QcmludChwcmludGVyLT5QcmludEJ5dGVzKHZhbHVlKSk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOiB7CisgICAgICBpbnQgZW51bV92YWx1ZSA9IGZpZWxkLT5pc19yZXBlYXRlZCgpCisgICAgICAgICAgPyByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEVudW1WYWx1ZShtZXNzYWdlLCBmaWVsZCwgaW5kZXgpCisgICAgICAgICAgOiByZWZsZWN0aW9uLT5HZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQpOworICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV9kZXNjID0KKyAgICAgICAgICBmaWVsZC0+ZW51bV90eXBlKCktPkZpbmRWYWx1ZUJ5TnVtYmVyKGVudW1fdmFsdWUpOworICAgICAgaWYgKGVudW1fZGVzYyAhPSBOVUxMKSB7CisgICAgICAgIGdlbmVyYXRvci5QcmludChwcmludGVyLT5QcmludEVudW0oZW51bV92YWx1ZSwgZW51bV9kZXNjLT5uYW1lKCkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE9yZGluYXJpbHksIGVudW1fZGVzYyBzaG91bGQgbm90IGJlIG51bGwsIGJlY2F1c2UgcHJvdG8yIGhhcyB0aGUKKyAgICAgICAgLy8gaW52YXJpYW50IHRoYXQgc2V0IGVudW0gZmllbGQgdmFsdWVzIG11c3QgYmUgaW4tcmFuZ2UsIGJ1dCB3aXRoIHRoZQorICAgICAgICAvLyBuZXcgaW50ZWdlci1iYXNlZCBBUEkgZm9yIGVudW1zIChvciB0aGUgUmVwZWF0ZWRGaWVsZDxpbnQ+IGxvb3Bob2xlKSwKKyAgICAgICAgLy8gaXQgaXMgcG9zc2libGUgZm9yIHRoZSB1c2VyIHRvIGZvcmNlIGFuIHVua25vd24gaW50ZWdlciB2YWx1ZS4gIFNvIHdlCisgICAgICAgIC8vIHNpbXBseSB1c2UgdGhlIGludGVnZXIgdmFsdWUgaXRzZWxmIGFzIHRoZSBlbnVtIHZhbHVlIG5hbWUgaW4gdGhpcworICAgICAgICAvLyBjYXNlLgorICAgICAgICBnZW5lcmF0b3IuUHJpbnQocHJpbnRlci0+UHJpbnRFbnVtKGVudW1fdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUHJpbnRmKCIlZCIsIGVudW1fdmFsdWUpKSk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgUHJpbnQoZmllbGQtPmlzX3JlcGVhdGVkKCkKKyAgICAgICAgICAgID8gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkLCBpbmRleCkKKyAgICAgICAgICAgIDogcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBmaWVsZCksCisgICAgICAgICAgICBnZW5lcmF0b3IpOworICAgICAgYnJlYWs7CisgIH0KK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6UHJpbnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIHJldHVybiBQcmludGVyKCkuUHJpbnQobWVzc2FnZSwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6UHJpbnRVbmtub3duRmllbGRzKAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgcmV0dXJuIFByaW50ZXIoKS5QcmludFVua25vd25GaWVsZHModW5rbm93bl9maWVsZHMsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6OlByaW50VG9TdHJpbmcoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgc3RyaW5nKiBvdXRwdXQpIHsKKyAgcmV0dXJuIFByaW50ZXIoKS5QcmludFRvU3RyaW5nKG1lc3NhZ2UsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6OlByaW50VW5rbm93bkZpZWxkc1RvU3RyaW5nKAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsIHN0cmluZyogb3V0cHV0KSB7CisgIHJldHVybiBQcmludGVyKCkuUHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcodW5rbm93bl9maWVsZHMsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyB2b2lkIFRleHRGb3JtYXQ6OlByaW50RmllbGRWYWx1ZVRvU3RyaW5nKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgaW5kZXgsCisgICAgc3RyaW5nKiBvdXRwdXQpIHsKKyAgcmV0dXJuIFByaW50ZXIoKS5QcmludEZpZWxkVmFsdWVUb1N0cmluZyhtZXNzYWdlLCBmaWVsZCwgaW5kZXgsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6OlBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoCisgICAgY29uc3Qgc3RyaW5nJiBpbnB1dCwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgcmV0dXJuIFBhcnNlcigpLlBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoaW5wdXQsIGZpZWxkLCBtZXNzYWdlKTsKK30KKworLy8gUHJpbnRzIGFuIGludGVnZXIgYXMgaGV4IHdpdGggYSBmaXhlZCBudW1iZXIgb2YgZGlnaXRzIGRlcGVuZGVudCBvbiB0aGUKKy8vIGludGVnZXIgdHlwZS4KK3RlbXBsYXRlPHR5cGVuYW1lIEludFR5cGU+CitzdGF0aWMgc3RyaW5nIFBhZGRlZEhleChJbnRUeXBlIHZhbHVlKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNlcnZlKHNpemVvZih2YWx1ZSkgKiAyKTsKKyAgZm9yIChpbnQgaSA9IHNpemVvZih2YWx1ZSkgKiAyIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICByZXN1bHQucHVzaF9iYWNrKGludF90b19oZXhfZGlnaXQodmFsdWUgPj4gKGkqNCkgJiAweDBGKSk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBUZXh0Rm9ybWF0OjpQcmludGVyOjpQcmludFVua25vd25GaWVsZHMoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZCA9IHVua25vd25fZmllbGRzLmZpZWxkKGkpOworICAgIHN0cmluZyBmaWVsZF9udW1iZXIgPSBTaW1wbGVJdG9hKGZpZWxkLm51bWJlcigpKTsKKworICAgIHN3aXRjaCAoZmllbGQudHlwZSgpKSB7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQ6CisgICAgICAgIGdlbmVyYXRvci5QcmludChmaWVsZF9udW1iZXIpOworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIjogIik7CisgICAgICAgIGdlbmVyYXRvci5QcmludChTaW1wbGVJdG9hKGZpZWxkLnZhcmludCgpKSk7CisgICAgICAgIGlmIChzaW5nbGVfbGluZV9tb2RlXykgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiXG4iKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVEMzI6IHsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KGZpZWxkX251bWJlcik7CisgICAgICAgIGdlbmVyYXRvci5QcmludCgiOiAweCIpOworICAgICAgICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgICAgICAgIGdlbmVyYXRvci5QcmludChGYXN0SGV4MzJUb0J1ZmZlcihmaWVsZC5maXhlZDMyKCksIGJ1ZmZlcikpOworICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIiAiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIlxuIik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0OiB7CisgICAgICAgIGdlbmVyYXRvci5QcmludChmaWVsZF9udW1iZXIpOworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIjogMHgiKTsKKyAgICAgICAgY2hhciBidWZmZXJba0Zhc3RUb0J1ZmZlclNpemVdOworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoRmFzdEhleDY0VG9CdWZmZXIoZmllbGQuZml4ZWQ2NCgpLCBidWZmZXIpKTsKKyAgICAgICAgaWYgKHNpbmdsZV9saW5lX21vZGVfKSB7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCIgIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCJcbiIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDogeworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoZmllbGRfbnVtYmVyKTsKKyAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSA9IGZpZWxkLmxlbmd0aF9kZWxpbWl0ZWQoKTsKKyAgICAgICAgVW5rbm93bkZpZWxkU2V0IGVtYmVkZGVkX3Vua25vd25fZmllbGRzOworICAgICAgICBpZiAoIXZhbHVlLmVtcHR5KCkgJiYgZW1iZWRkZWRfdW5rbm93bl9maWVsZHMuUGFyc2VGcm9tU3RyaW5nKHZhbHVlKSkgeworICAgICAgICAgIC8vIFRoaXMgZmllbGQgaXMgcGFyc2VhYmxlIGFzIGEgTWVzc2FnZS4KKyAgICAgICAgICAvLyBTbyBpdCBpcyBwcm9iYWJseSBhbiBlbWJlZGRlZCBtZXNzYWdlLgorICAgICAgICAgIGlmIChzaW5nbGVfbGluZV9tb2RlXykgeworICAgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCIgeyAiKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCIge1xuIik7CisgICAgICAgICAgICBnZW5lcmF0b3IuSW5kZW50KCk7CisgICAgICAgICAgfQorICAgICAgICAgIFByaW50VW5rbm93bkZpZWxkcyhlbWJlZGRlZF91bmtub3duX2ZpZWxkcywgZ2VuZXJhdG9yKTsKKyAgICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICAgIGdlbmVyYXRvci5QcmludCgifSAiKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZ2VuZXJhdG9yLk91dGRlbnQoKTsKKyAgICAgICAgICAgIGdlbmVyYXRvci5QcmludCgifVxuIik7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFRoaXMgZmllbGQgaXMgbm90IHBhcnNlYWJsZSBhcyBhIE1lc3NhZ2UuCisgICAgICAgICAgLy8gU28gaXQgaXMgcHJvYmFibHkganVzdCBhIHBsYWluIHN0cmluZy4KKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIjogXCIiKTsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoQ0VzY2FwZSh2YWx1ZSkpOworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiXCIiKTsKKyAgICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiICIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIlxuIik7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6CisgICAgICAgIGdlbmVyYXRvci5QcmludChmaWVsZF9udW1iZXIpOworICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIiB7ICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiIHtcbiIpOworICAgICAgICAgIGdlbmVyYXRvci5JbmRlbnQoKTsKKyAgICAgICAgfQorICAgICAgICBQcmludFVua25vd25GaWVsZHMoZmllbGQuZ3JvdXAoKSwgZ2VuZXJhdG9yKTsKKyAgICAgICAgaWYgKHNpbmdsZV9saW5lX21vZGVfKSB7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCJ9ICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5PdXRkZW50KCk7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCJ9XG4iKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWUyY2IwNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaApAQCAtMCwwICsxLDQ4OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoganNjaG9yckBnb29nbGUuY29tIChKb3NlcGggU2Nob3JyKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVXRpbGl0aWVzIGZvciBwcmludGluZyBhbmQgcGFyc2luZyBwcm90b2NvbCBtZXNzYWdlcyBpbiBhIGh1bWFuLXJlYWRhYmxlLAorLy8gdGV4dC1iYXNlZCBmb3JtYXQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1RFWFRfRk9STUFUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVEVYVF9GT1JNQVRfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSBpbyB7CisgIGNsYXNzIEVycm9yQ29sbGVjdG9yOyAgICAgIC8vIHRva2VuaXplci5oCit9CisKKy8vIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBwcm90b2NvbCBidWZmZXIgdGV4dCBmb3JtYXQuICBQcmludGluZyBhbmQgcGFyc2luZworLy8gcHJvdG9jb2wgbWVzc2FnZXMgaW4gdGV4dCBmb3JtYXQgaXMgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgYW5kIGh1bWFuIGVkaXRpbmcKKy8vIG9mIG1lc3NhZ2VzLgorLy8KKy8vIFRoaXMgY2xhc3MgaXMgcmVhbGx5IGEgbmFtZXNwYWNlIHRoYXQgY29udGFpbnMgb25seSBzdGF0aWMgbWV0aG9kcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBUZXh0Rm9ybWF0IHsKKyBwdWJsaWM6CisgIC8vIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBtZXNzYWdlIHRvIHRoZSBnaXZlbgorICAvLyBvdXRwdXQgc3RyZWFtLgorICBzdGF0aWMgYm9vbCBQcmludChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gUHJpbnQgdGhlIGZpZWxkcyBpbiBhbiBVbmtub3duRmllbGRTZXQuICBUaGV5IGFyZSBwcmludGVkIGJ5IHRhZyBudW1iZXIKKyAgLy8gb25seS4gIEVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBoZXVyaXN0aWNhbGx5IGlkZW50aWZpZWQgYnkgYXR0ZW1wdGluZyB0bworICAvLyBwYXJzZSB0aGVtLgorICBzdGF0aWMgYm9vbCBQcmludFVua25vd25GaWVsZHMoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KTsKKworICAvLyBMaWtlIFByaW50KCksIGJ1dCBvdXRwdXRzIGRpcmVjdGx5IHRvIGEgc3RyaW5nLgorICBzdGF0aWMgYm9vbCBQcmludFRvU3RyaW5nKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBMaWtlIFByaW50VW5rbm93bkZpZWxkcygpLCBidXQgb3V0cHV0cyBkaXJlY3RseSB0byBhIHN0cmluZy4KKyAgc3RhdGljIGJvb2wgUHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBvdXRwdXQpOworCisgIC8vIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgc3VwcGxpZWQgb24KKyAgLy8gdGhlIG1lc3NhZ2Ugc3VwcGxpZWQuIEZvciBub24tcmVwZWF0ZWQgZmllbGRzLCBhbiBpbmRleCBvZiAtMSBtdXN0CisgIC8vIGJlIHN1cHBsaWVkLiBOb3RlIHRoYXQgdGhpcyBtZXRob2Qgd2lsbCBwcmludCB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgYQorICAvLyBmaWVsZCBpZiBpdCBpcyBub3Qgc2V0LgorICBzdGF0aWMgdm9pZCBQcmludEZpZWxkVmFsdWVUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBUaGUgZGVmYXVsdCBwcmludGVyIHRoYXQgY29udmVydHMgc2NhbGFyIHZhbHVlcyBmcm9tIGZpZWxkcyBpbnRvCisgIC8vIHRoZWlyIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgLy8gWW91IGNhbiBkZXJpdmUgZnJvbSB0aGlzIEZpZWxkVmFsdWVQcmludGVyIGlmIHlvdSB3YW50IHRvIGhhdmUKKyAgLy8gZmllbGRzIHRvIGJlIHByaW50ZWQgaW4gYSBkaWZmZXJlbnQgd2F5IGFuZCByZWdpc3RlciBpdCBhdCB0aGUKKyAgLy8gUHJpbnRlci4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkVmFsdWVQcmludGVyIHsKKyAgIHB1YmxpYzoKKyAgICBGaWVsZFZhbHVlUHJpbnRlcigpOworICAgIHZpcnR1YWwgfkZpZWxkVmFsdWVQcmludGVyKCk7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRCb29sKGJvb2wgdmFsKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludEludDMyKGludDMyIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRVSW50MzIodWludDMyIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRJbnQ2NChpbnQ2NCB2YWwpIGNvbnN0OworICAgIHZpcnR1YWwgc3RyaW5nIFByaW50VUludDY0KHVpbnQ2NCB2YWwpIGNvbnN0OworICAgIHZpcnR1YWwgc3RyaW5nIFByaW50RmxvYXQoZmxvYXQgdmFsKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludERvdWJsZShkb3VibGUgdmFsKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludFN0cmluZyhjb25zdCBzdHJpbmcmIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRCeXRlcyhjb25zdCBzdHJpbmcmIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRFbnVtKGludDMyIHZhbCwgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludEZpZWxkTmFtZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRNZXNzYWdlU3RhcnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2NvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2luZ2xlX2xpbmVfbW9kZSkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRNZXNzYWdlRW5kKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9pbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2NvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNpbmdsZV9saW5lX21vZGUpIGNvbnN0OworCisgICBwcml2YXRlOgorICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWVsZFZhbHVlUHJpbnRlcik7CisgIH07CisKKyAgLy8gQ2xhc3MgZm9yIHRob3NlIHVzZXJzIHdoaWNoIHJlcXVpcmUgbW9yZSBmaW5lLWdyYWluZWQgY29udHJvbCBvdmVyIGhvdworICAvLyBhIHByb3RvYnVmZmVyIG1lc3NhZ2UgaXMgcHJpbnRlZCBvdXQuCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBQcmludGVyIHsKKyAgIHB1YmxpYzoKKyAgICBQcmludGVyKCk7CisgICAgflByaW50ZXIoKTsKKworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6UHJpbnQKKyAgICBib29sIFByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgICAvLyBMaWtlIFRleHRGb3JtYXQ6OlByaW50VW5rbm93bkZpZWxkcworICAgIGJvb2wgUHJpbnRVbmtub3duRmllbGRzKGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6UHJpbnRUb1N0cmluZworICAgIGJvb2wgUHJpbnRUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBzdHJpbmcqIG91dHB1dCkgY29uc3Q7CisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpQcmludFVua25vd25GaWVsZHNUb1N0cmluZworICAgIGJvb2wgUHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KSBjb25zdDsKKyAgICAvLyBMaWtlIFRleHRGb3JtYXQ6OlByaW50RmllbGRWYWx1ZVRvU3RyaW5nCisgICAgdm9pZCBQcmludEZpZWxkVmFsdWVUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KSBjb25zdDsKKworICAgIC8vIEFkanVzdCB0aGUgaW5pdGlhbCBpbmRlbnQgbGV2ZWwgb2YgYWxsIG91dHB1dC4gIEVhY2ggaW5kZW50IGxldmVsIGlzCisgICAgLy8gZXF1YWwgdG8gdHdvIHNwYWNlcy4KKyAgICB2b2lkIFNldEluaXRpYWxJbmRlbnRMZXZlbChpbnQgaW5kZW50X2xldmVsKSB7CisgICAgICBpbml0aWFsX2luZGVudF9sZXZlbF8gPSBpbmRlbnRfbGV2ZWw7CisgICAgfQorCisgICAgLy8gSWYgcHJpbnRpbmcgaW4gc2luZ2xlIGxpbmUgbW9kZSwgdGhlbiB0aGUgZW50aXJlIG1lc3NhZ2Ugd2lsbCBiZSBvdXRwdXQKKyAgICAvLyBvbiBhIHNpbmdsZSBsaW5lIHdpdGggbm8gbGluZSBicmVha3MuCisgICAgdm9pZCBTZXRTaW5nbGVMaW5lTW9kZShib29sIHNpbmdsZV9saW5lX21vZGUpIHsKKyAgICAgIHNpbmdsZV9saW5lX21vZGVfID0gc2luZ2xlX2xpbmVfbW9kZTsKKyAgICB9CisKKyAgICBib29sIElzSW5TaW5nbGVMaW5lTW9kZSgpIHsKKyAgICAgIHJldHVybiBzaW5nbGVfbGluZV9tb2RlXzsKKyAgICB9CisKKyAgICAvLyBJZiB1c2VfZmllbGRfbnVtYmVyIGlzIHRydWUsIHVzZXMgZmllbGQgbnVtYmVyIGluc3RlYWQgb2YgZmllbGQgbmFtZS4KKyAgICB2b2lkIFNldFVzZUZpZWxkTnVtYmVyKGJvb2wgdXNlX2ZpZWxkX251bWJlcikgeworICAgICAgdXNlX2ZpZWxkX251bWJlcl8gPSB1c2VfZmllbGRfbnVtYmVyOworICAgIH0KKworICAgIC8vIFNldCB0cnVlIHRvIHByaW50IHJlcGVhdGVkIHByaW1pdGl2ZXMgaW4gYSBmb3JtYXQgbGlrZToKKyAgICAvLyAgIGZpZWxkX25hbWU6IFsxLCAyLCAzLCA0XQorICAgIC8vIGluc3RlYWQgb2YgcHJpbnRpbmcgZWFjaCB2YWx1ZSBvbiBpdHMgb3duIGxpbmUuICBTaG9ydCBmb3JtYXQgYXBwbGllcworICAgIC8vIG9ubHkgdG8gcHJpbWl0aXZlIHZhbHVlcyAtLSBpLmUuIGV2ZXJ5dGhpbmcgZXhjZXB0IHN0cmluZ3MgYW5kCisgICAgLy8gc3ViLW1lc3NhZ2VzL2dyb3Vwcy4KKyAgICB2b2lkIFNldFVzZVNob3J0UmVwZWF0ZWRQcmltaXRpdmVzKGJvb2wgdXNlX3Nob3J0X3JlcGVhdGVkX3ByaW1pdGl2ZXMpIHsKKyAgICAgIHVzZV9zaG9ydF9yZXBlYXRlZF9wcmltaXRpdmVzXyA9IHVzZV9zaG9ydF9yZXBlYXRlZF9wcmltaXRpdmVzOworICAgIH0KKworICAgIC8vIFNldCB0cnVlIHRvIG91dHB1dCBVVEYtOCBpbnN0ZWFkIG9mIEFTQ0lJLiAgVGhlIG9ubHkgZGlmZmVyZW5jZQorICAgIC8vIGlzIHRoYXQgYnl0ZXMgPj0gMHg4MCBpbiBzdHJpbmcgZmllbGRzIHdpbGwgbm90IGJlIGVzY2FwZWQsCisgICAgLy8gYmVjYXVzZSB0aGV5IGFyZSBhc3N1bWVkIHRvIGJlIHBhcnQgb2YgVVRGLTggbXVsdGktYnl0ZQorICAgIC8vIHNlcXVlbmNlcy4gVGhpcyB3aWxsIGNoYW5nZSB0aGUgZGVmYXVsdCBGaWVsZFZhbHVlUHJpbnRlci4KKyAgICB2b2lkIFNldFVzZVV0ZjhTdHJpbmdFc2NhcGluZyhib29sIGFzX3V0ZjgpOworCisgICAgLy8gU2V0IHRoZSBkZWZhdWx0IEZpZWxkVmFsdWVQcmludGVyIHRoYXQgaXMgdXNlZCBmb3IgYWxsIGZpZWxkcyB0aGF0CisgICAgLy8gZG9uJ3QgaGF2ZSBhIGZpZWxkLXNwZWNpZmljIHByaW50ZXIgcmVnaXN0ZXJlZC4KKyAgICAvLyBUYWtlcyBvd25lcnNoaXAgb2YgdGhlIHByaW50ZXIuCisgICAgdm9pZCBTZXREZWZhdWx0RmllbGRWYWx1ZVByaW50ZXIoY29uc3QgRmllbGRWYWx1ZVByaW50ZXIqIHByaW50ZXIpOworCisgICAgLy8gU2V0cyB3aGV0aGVyIHdlIHdhbnQgdG8gaGlkZSB1bmtub3duIGZpZWxkcyBvciBub3QuCisgICAgLy8gVXN1YWxseSB1bmtub3duIGZpZWxkcyBhcmUgcHJpbnRlZCBpbiBhIGdlbmVyaWMgd2F5IHRoYXQgaW5jbHVkZXMgdGhlCisgICAgLy8gdGFnIG51bWJlciBvZiB0aGUgZmllbGQgaW5zdGVhZCBvZiBmaWVsZCBuYW1lLiBIb3dldmVyLCBzb21ldGltZXMgaXQKKyAgICAvLyBpcyB1c2VmdWwgdG8gYmUgYWJsZSB0byBwcmludCB0aGUgbWVzc2FnZSB3aXRob3V0IHVua25vd24gZmllbGRzIChlLmcuCisgICAgLy8gZm9yIHRoZSBweXRob24gcHJvdG9idWYgdmVyc2lvbiB0byBtYWludGFpbiBjb25zaXN0ZW5jeSBiZXR3ZWVuIGl0cyBwdXJlCisgICAgLy8gcHl0aG9uIGFuZCBjKysgaW1wbGVtZW50YXRpb25zKS4KKyAgICB2b2lkIFNldEhpZGVVbmtub3duRmllbGRzKGJvb2wgaGlkZSkgeworICAgICAgaGlkZV91bmtub3duX2ZpZWxkc18gPSBoaWRlOworICAgIH0KKworICAgIC8vIElmIHByaW50X21lc3NhZ2VfZmllbGRzX2luX2luZGV4X29yZGVyIGlzIHRydWUsIHByaW50IGZpZWxkcyBvZiBhIHByb3RvCisgICAgLy8gbWVzc2FnZSB1c2luZyB0aGUgb3JkZXIgZGVmaW5lZCBpbiBzb3VyY2UgY29kZSBpbnN0ZWFkIG9mIHRoZSBmaWVsZAorICAgIC8vIG51bWJlci4gQnkgZGVmYXVsdCwgdXNlIHRoZSBmaWVsZCBudW1iZXIgb3JkZXIuCisgICAgdm9pZCBTZXRQcmludE1lc3NhZ2VGaWVsZHNJbkluZGV4T3JkZXIoCisgICAgICAgIGJvb2wgcHJpbnRfbWVzc2FnZV9maWVsZHNfaW5faW5kZXhfb3JkZXIpIHsKKyAgICAgIHByaW50X21lc3NhZ2VfZmllbGRzX2luX2luZGV4X29yZGVyXyA9CisgICAgICAgICAgcHJpbnRfbWVzc2FnZV9maWVsZHNfaW5faW5kZXhfb3JkZXI7CisgICAgfQorCisgICAgLy8gUmVnaXN0ZXIgYSBjdXN0b20gZmllbGQtc3BlY2lmaWMgRmllbGRWYWx1ZVByaW50ZXIgZm9yIGZpZWxkcworICAgIC8vIHdpdGggYSBwYXJ0aWN1bGFyIEZpZWxkRGVzY3JpcHRvci4KKyAgICAvLyBSZXR1cm5zICJ0cnVlIiBpZiB0aGUgcmVnaXN0cmF0aW9uIHN1Y2NlZWRlZCwgb3IgImZhbHNlIiwgaWYgdGhlcmUgaXMKKyAgICAvLyBhbHJlYWR5IGEgcHJpbnRlciBmb3IgdGhhdCBGaWVsZERlc2NyaXB0b3IuCisgICAgLy8gVGFrZXMgb3duZXJzaGlwIG9mIHRoZSBwcmludGVyIG9uIHN1Y2Nlc3NmdWwgcmVnaXN0cmF0aW9uLgorICAgIGJvb2wgUmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZFZhbHVlUHJpbnRlciogcHJpbnRlcik7CisKKyAgIHByaXZhdGU6CisgICAgLy8gRm9yd2FyZCBkZWNsYXJhdGlvbiBvZiBhbiBpbnRlcm5hbCBjbGFzcyB1c2VkIHRvIHByaW50IHRoZSB0ZXh0CisgICAgLy8gb3V0cHV0IHRvIHRoZSBPdXRwdXRTdHJlYW0gKHNlZSB0ZXh0X2Zvcm1hdC5jYyBmb3IgaW1wbGVtZW50YXRpb24pLgorICAgIGNsYXNzIFRleHRHZW5lcmF0b3I7CisKKyAgICAvLyBJbnRlcm5hbCBQcmludCBtZXRob2QsIHVzZWQgZm9yIHdyaXRpbmcgdG8gdGhlIE91dHB1dFN0cmVhbSB2aWEKKyAgICAvLyB0aGUgVGV4dEdlbmVyYXRvciBjbGFzcy4KKyAgICB2b2lkIFByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0OworCisgICAgLy8gUHJpbnQgYSBzaW5nbGUgZmllbGQuCisgICAgdm9pZCBQcmludEZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3Q7CisKKyAgICAvLyBQcmludCBhIHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZCBpbiBzaG9ydCBmb3JtLgorICAgIHZvaWQgUHJpbnRTaG9ydFJlcGVhdGVkRmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdDsKKworICAgIC8vIFByaW50IHRoZSBuYW1lIG9mIGEgZmllbGQgLS0gaS5lLiBldmVyeXRoaW5nIHRoYXQgY29tZXMgYmVmb3JlIHRoZQorICAgIC8vICc6JyBmb3IgYSBzaW5nbGUgbmFtZS92YWx1ZSBwYWlyLgorICAgIHZvaWQgUHJpbnRGaWVsZE5hbWUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdDsKKworICAgIC8vIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgc3VwcGxpZWQgb24KKyAgICAvLyB0aGUgbWVzc2FnZSBzdXBwbGllZCBvciB0aGUgZGVmYXVsdCB2YWx1ZSBpZiBub3Qgc2V0LgorICAgIHZvaWQgUHJpbnRGaWVsZFZhbHVlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0OworCisgICAgLy8gUHJpbnQgdGhlIGZpZWxkcyBpbiBhbiBVbmtub3duRmllbGRTZXQuICBUaGV5IGFyZSBwcmludGVkIGJ5IHRhZyBudW1iZXIKKyAgICAvLyBvbmx5LiAgRW1iZWRkZWQgbWVzc2FnZXMgYXJlIGhldXJpc3RpY2FsbHkgaWRlbnRpZmllZCBieSBhdHRlbXB0aW5nIHRvCisgICAgLy8gcGFyc2UgdGhlbS4KKyAgICB2b2lkIFByaW50VW5rbm93bkZpZWxkcyhjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3Q7CisKKyAgICBpbnQgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfOworCisgICAgYm9vbCBzaW5nbGVfbGluZV9tb2RlXzsKKworICAgIGJvb2wgdXNlX2ZpZWxkX251bWJlcl87CisKKyAgICBib29sIHVzZV9zaG9ydF9yZXBlYXRlZF9wcmltaXRpdmVzXzsKKworICAgIGJvb2wgaGlkZV91bmtub3duX2ZpZWxkc187CisKKyAgICBib29sIHByaW50X21lc3NhZ2VfZmllbGRzX2luX2luZGV4X29yZGVyXzsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Y29uc3QgRmllbGRWYWx1ZVByaW50ZXI+IGRlZmF1bHRfZmllbGRfdmFsdWVfcHJpbnRlcl87CisgICAgdHlwZWRlZiBtYXA8Y29uc3QgRmllbGREZXNjcmlwdG9yKiwKKyAgICAgICAgICAgICAgICBjb25zdCBGaWVsZFZhbHVlUHJpbnRlcio+IEN1c3RvbVByaW50ZXJNYXA7CisgICAgQ3VzdG9tUHJpbnRlck1hcCBjdXN0b21fcHJpbnRlcnNfOworICB9OworCisgIC8vIFBhcnNlcyBhIHRleHQtZm9ybWF0IHByb3RvY29sIG1lc3NhZ2UgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtIHRvCisgIC8vIHRoZSBnaXZlbiBtZXNzYWdlIG9iamVjdC4gVGhpcyBmdW5jdGlvbiBwYXJzZXMgdGhlIGh1bWFuLXJlYWRhYmxlIGZvcm1hdAorICAvLyB3cml0dGVuIGJ5IFByaW50KCkuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLiBUaGUgbWVzc2FnZSBpcyBjbGVhcmVkIGZpcnN0LAorICAvLyBldmVuIGlmIHRoZSBmdW5jdGlvbiBmYWlscyAtLSBTZWUgTWVyZ2UoKSB0byBhdm9pZCB0aGlzIGJlaGF2aW9yLgorICAvLworICAvLyBFeGFtcGxlIGlucHV0OiAidXNlciB7XG4gaWQ6IDEyMyBleHRyYSB7IGdlbmRlcjogTUFMRSBsYW5ndWFnZTogJ2VuJyB9XG59IgorICAvLworICAvLyBPbmUgdXNlIGZvciB0aGlzIGZ1bmN0aW9uIGlzIHBhcnNpbmcgaGFuZHdyaXR0ZW4gc3RyaW5ncyBpbiB0ZXN0IGNvZGUuCisgIC8vIEFub3RoZXIgdXNlIGlzIHRvIHBhcnNlIHRoZSBvdXRwdXQgZnJvbSBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlOjpEZWJ1Z1N0cmluZygpCisgIC8vIChvciBTaG9ydERlYnVnU3RyaW5nKCkpLCBiZWNhdXNlIHRoZXNlIGZ1bmN0aW9ucyBvdXRwdXQgdXNpbmcKKyAgLy8gZ29vZ2xlOjpwcm90b2J1Zjo6VGV4dEZvcm1hdDo6UHJpbnQoKS4KKyAgLy8KKyAgLy8gSWYgeW91IHdvdWxkIGxpa2UgdG8gcmVhZCBhIHByb3RvY29sIGJ1ZmZlciBzZXJpYWxpemVkIGluIHRoZQorICAvLyAobm9uLWh1bWFuLXJlYWRhYmxlKSBiaW5hcnkgd2lyZSBmb3JtYXQsIHNlZQorICAvLyBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlTGl0ZTo6UGFyc2VGcm9tU3RyaW5nKCkuCisgIHN0YXRpYyBib29sIFBhcnNlKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0KTsKKyAgLy8gTGlrZSBQYXJzZSgpLCBidXQgcmVhZHMgZGlyZWN0bHkgZnJvbSBhIHN0cmluZy4KKyAgc3RhdGljIGJvb2wgUGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCk7CisKKyAgLy8gTGlrZSBQYXJzZSgpLCBidXQgdGhlIGRhdGEgaXMgbWVyZ2VkIGludG8gdGhlIGdpdmVuIG1lc3NhZ2UsIGFzIGlmCisgIC8vIHVzaW5nIE1lc3NhZ2U6Ok1lcmdlRnJvbSgpLgorICBzdGF0aWMgYm9vbCBNZXJnZShpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCk7CisgIC8vIExpa2UgTWVyZ2UoKSwgYnV0IHJlYWRzIGRpcmVjdGx5IGZyb20gYSBzdHJpbmcuCisgIHN0YXRpYyBib29sIE1lcmdlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGlucHV0LCBNZXNzYWdlKiBvdXRwdXQpOworCisgIC8vIFBhcnNlIHRoZSBnaXZlbiB0ZXh0IGFzIGEgc2luZ2xlIGZpZWxkIHZhbHVlIGFuZCBzdG9yZSBpdCBpbnRvIHRoZQorICAvLyBnaXZlbiBmaWVsZCBvZiB0aGUgZ2l2ZW4gbWVzc2FnZS4gSWYgdGhlIGZpZWxkIGlzIGEgcmVwZWF0ZWQgZmllbGQsCisgIC8vIHRoZSBuZXcgdmFsdWUgd2lsbCBiZSBhZGRlZCB0byB0aGUgZW5kCisgIHN0YXRpYyBib29sIFBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpOworCisgIC8vIEludGVyZmFjZSB0aGF0IFRleHRGb3JtYXQ6OlBhcnNlciBjYW4gdXNlIHRvIGZpbmQgZXh0ZW5zaW9ucy4KKyAgLy8gVGhpcyBjbGFzcyBtYXkgYmUgZXh0ZW5kZWQgaW4gdGhlIGZ1dHVyZSB0byBmaW5kIG1vcmUgaW5mb3JtYXRpb24KKyAgLy8gbGlrZSBmaWVsZHMsIGV0Yy4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpbmRlciB7CisgICBwdWJsaWM6CisgICAgdmlydHVhbCB+RmluZGVyKCk7CisKKyAgICAvLyBUcnkgdG8gZmluZCBhbiBleHRlbnNpb24gb2YgKm1lc3NhZ2UgYnkgZnVsbHktcXVhbGlmaWVkIGZpZWxkCisgICAgLy8gbmFtZS4gIFJldHVybnMgTlVMTCBpZiBubyBleHRlbnNpb24gaXMga25vd24gZm9yIHRoaXMgbmFtZSBvciBudW1iZXIuCisgICAgdmlydHVhbCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb24oCisgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgPSAwOworICB9OworCisgIC8vIEEgbG9jYXRpb24gaW4gdGhlIHBhcnNlZCB0ZXh0LgorICBzdHJ1Y3QgUGFyc2VMb2NhdGlvbiB7CisgICAgaW50IGxpbmU7CisgICAgaW50IGNvbHVtbjsKKworICAgIFBhcnNlTG9jYXRpb24oKSA6IGxpbmUoLTEpLCBjb2x1bW4oLTEpIHt9CisgICAgUGFyc2VMb2NhdGlvbihpbnQgbGluZV9wYXJhbSwgaW50IGNvbHVtbl9wYXJhbSkKKyAgICAgICAgOiBsaW5lKGxpbmVfcGFyYW0pLCBjb2x1bW4oY29sdW1uX3BhcmFtKSB7fQorICB9OworCisgIC8vIERhdGEgc3RydWN0dXJlIHdoaWNoIGlzIHBvcHVsYXRlZCB3aXRoIHRoZSBsb2NhdGlvbnMgb2YgZWFjaCBmaWVsZAorICAvLyB2YWx1ZSBwYXJzZWQgZnJvbSB0aGUgdGV4dC4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFBhcnNlSW5mb1RyZWUgeworICAgcHVibGljOgorICAgIFBhcnNlSW5mb1RyZWUoKTsKKyAgICB+UGFyc2VJbmZvVHJlZSgpOworCisgICAgLy8gUmV0dXJucyB0aGUgcGFyc2UgbG9jYXRpb24gZm9yIGluZGV4LXRoIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgcGFyc2VkCisgICAgLy8gdGV4dC4gSWYgbm9uZSBleGlzdHMsIHJldHVybnMgYSBsb2NhdGlvbiB3aXRoIGxpbmUgPSAtMS4gSW5kZXggc2hvdWxkIGJlCisgICAgLy8gLTEgZm9yIG5vdC1yZXBlYXRlZCBmaWVsZHMuCisgICAgUGFyc2VMb2NhdGlvbiBHZXRMb2NhdGlvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworCisgICAgLy8gUmV0dXJucyB0aGUgcGFyc2UgaW5mbyB0cmVlIGZvciB0aGUgZ2l2ZW4gZmllbGQsIHdoaWNoIG11c3QgYmUgYSBtZXNzYWdlCisgICAgLy8gdHlwZS4gVGhlIG5lc3RlZCBpbmZvcm1hdGlvbiB0cmVlIGlzIG93bmVkIGJ5IHRoZSByb290IHRyZWUgYW5kIHdpbGwgYmUKKyAgICAvLyBkZWxldGVkIHdoZW4gaXQgaXMgZGVsZXRlZC4KKyAgICBQYXJzZUluZm9UcmVlKiBHZXRUcmVlRm9yTmVzdGVkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0OworCisgICBwcml2YXRlOgorICAgIC8vIEFsbG93IHRoZSB0ZXh0IGZvcm1hdCBwYXJzZXIgdG8gcmVjb3JkIGluZm9ybWF0aW9uIGludG8gdGhlIHRyZWUuCisgICAgZnJpZW5kIGNsYXNzIFRleHRGb3JtYXQ7CisKKyAgICAvLyBSZWNvcmRzIHRoZSBzdGFydGluZyBsb2NhdGlvbiBvZiBhIHNpbmdsZSB2YWx1ZSBmb3IgYSBmaWVsZC4KKyAgICB2b2lkIFJlY29yZExvY2F0aW9uKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIFBhcnNlTG9jYXRpb24gbG9jYXRpb24pOworCisgICAgLy8gQ3JlYXRlIGFuZCByZWNvcmRzIGEgbmVzdGVkIHRyZWUgZm9yIGEgbmVzdGVkIG1lc3NhZ2UgZmllbGQuCisgICAgUGFyc2VJbmZvVHJlZSogQ3JlYXRlTmVzdGVkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgICAgLy8gRGVmaW5lcyB0aGUgbWFwIGZyb20gdGhlIGluZGV4LXRoIGZpZWxkIGRlc2NyaXB0b3IgdG8gaXRzIHBhcnNlIGxvY2F0aW9uLgorICAgIHR5cGVkZWYgbWFwPGNvbnN0IEZpZWxkRGVzY3JpcHRvciosIHZlY3RvcjxQYXJzZUxvY2F0aW9uPiA+IExvY2F0aW9uTWFwOworCisgICAgLy8gRGVmaW5lcyB0aGUgbWFwIGZyb20gdGhlIGluZGV4LXRoIGZpZWxkIGRlc2NyaXB0b3IgdG8gdGhlIG5lc3RlZCBwYXJzZQorICAgIC8vIGluZm8gdHJlZS4KKyAgICB0eXBlZGVmIG1hcDxjb25zdCBGaWVsZERlc2NyaXB0b3IqLCB2ZWN0b3I8UGFyc2VJbmZvVHJlZSo+ID4gTmVzdGVkTWFwOworCisgICAgTG9jYXRpb25NYXAgbG9jYXRpb25zXzsKKyAgICBOZXN0ZWRNYXAgbmVzdGVkXzsKKworICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQYXJzZUluZm9UcmVlKTsKKyAgfTsKKworICAvLyBGb3IgbW9yZSBjb250cm9sIG92ZXIgcGFyc2luZywgdXNlIHRoaXMgY2xhc3MuCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBQYXJzZXIgeworICAgcHVibGljOgorICAgIFBhcnNlcigpOworICAgIH5QYXJzZXIoKTsKKworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6UGFyc2UoKS4KKyAgICBib29sIFBhcnNlKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0KTsKKyAgICAvLyBMaWtlIFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygpLgorICAgIGJvb2wgUGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCk7CisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpNZXJnZSgpLgorICAgIGJvb2wgTWVyZ2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBNZXNzYWdlKiBvdXRwdXQpOworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKCkuCisgICAgYm9vbCBNZXJnZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0KTsKKworICAgIC8vIFNldCB3aGVyZSB0byByZXBvcnQgcGFyc2UgZXJyb3JzLiAgSWYgTlVMTCAodGhlIGRlZmF1bHQpLCBlcnJvcnMgd2lsbAorICAgIC8vIGJlIHByaW50ZWQgdG8gc3RkZXJyLgorICAgIHZvaWQgUmVjb3JkRXJyb3JzVG8oaW86OkVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpIHsKKyAgICAgIGVycm9yX2NvbGxlY3Rvcl8gPSBlcnJvcl9jb2xsZWN0b3I7CisgICAgfQorCisgICAgLy8gU2V0IGhvdyBwYXJzZXIgZmluZHMgZXh0ZW5zaW9ucy4gIElmIE5VTEwgKHRoZSBkZWZhdWx0KSwgdGhlCisgICAgLy8gcGFyc2VyIHdpbGwgdXNlIHRoZSBzdGFuZGFyZCBSZWZsZWN0aW9uIG9iamVjdCBhc3NvY2lhdGVkIHdpdGgKKyAgICAvLyB0aGUgbWVzc2FnZSBiZWluZyBwYXJzZWQuCisgICAgdm9pZCBTZXRGaW5kZXIoRmluZGVyKiBmaW5kZXIpIHsKKyAgICAgIGZpbmRlcl8gPSBmaW5kZXI7CisgICAgfQorCisgICAgLy8gU2V0cyB3aGVyZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGFyc2Ugd2lsbCBiZSB3cml0dGVuLiBJZiBOVUxMCisgICAgLy8gKHRoZSBkZWZhdWx0KSwgdGhlbiBubyBsb2NhdGlvbiB3aWxsIGJlIHdyaXR0ZW4uCisgICAgdm9pZCBXcml0ZUxvY2F0aW9uc1RvKFBhcnNlSW5mb1RyZWUqIHRyZWUpIHsKKyAgICAgIHBhcnNlX2luZm9fdHJlZV8gPSB0cmVlOworICAgIH0KKworICAgIC8vIE5vcm1hbGx5IHBhcnNpbmcgZmFpbHMgaWYsIGFmdGVyIHBhcnNpbmcsIG91dHB1dC0+SXNJbml0aWFsaXplZCgpCisgICAgLy8gcmV0dXJucyBmYWxzZS4gIENhbGwgQWxsb3dQYXJ0aWFsTWVzc2FnZSh0cnVlKSB0byBza2lwIHRoaXMgY2hlY2suCisgICAgdm9pZCBBbGxvd1BhcnRpYWxNZXNzYWdlKGJvb2wgYWxsb3cpIHsKKyAgICAgIGFsbG93X3BhcnRpYWxfID0gYWxsb3c7CisgICAgfQorCisgICAgLy8gQWxsb3cgZmllbGQgbmFtZXMgdG8gYmUgbWF0Y2hlZCBjYXNlLWluc2Vuc2l0aXZlbHkuCisgICAgLy8gVGhpcyBpcyBub3QgYWR2aXNhYmxlIGlmIHRoZXJlIGFyZSBmaWVsZHMgdGhhdCBvbmx5IGRpZmZlciBpbiBjYXNlLCBvcgorICAgIC8vIGlmIHlvdSB3YW50IHRvIGVuZm9yY2Ugd3JpdGluZyBpbiB0aGUgY2Fub25pY2FsIGZvcm0uCisgICAgLy8gVGhpcyBpcyAnZmFsc2UnIGJ5IGRlZmF1bHQuCisgICAgdm9pZCBBbGxvd0Nhc2VJbnNlbnNpdGl2ZUZpZWxkKGJvb2wgYWxsb3cpIHsKKyAgICAgIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfID0gYWxsb3c7CisgICAgfQorCisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nCisgICAgYm9vbCBQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCk7CisKKworICAgIHZvaWQgQWxsb3dGaWVsZE51bWJlcihib29sIGFsbG93KSB7CisgICAgICBhbGxvd19maWVsZF9udW1iZXJfID0gYWxsb3c7CisgICAgfQorCisgICBwcml2YXRlOgorICAgIC8vIEZvcndhcmQgZGVjbGFyYXRpb24gb2YgYW4gaW50ZXJuYWwgY2xhc3MgdXNlZCB0byBwYXJzZSB0ZXh0CisgICAgLy8gcmVwcmVzZW50YXRpb25zIChzZWUgdGV4dF9mb3JtYXQuY2MgZm9yIGltcGxlbWVudGF0aW9uKS4KKyAgICBjbGFzcyBQYXJzZXJJbXBsOworCisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpNZXJnZSgpLiAgVGhlIHByb3ZpZGVkIGltcGxlbWVudGF0aW9uIGlzIHVzZWQKKyAgICAvLyB0byBkbyB0aGUgcGFyc2luZy4KKyAgICBib29sIE1lcmdlVXNpbmdJbXBsKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGwqIHBhcnNlcl9pbXBsKTsKKworICAgIGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKyAgICBGaW5kZXIqIGZpbmRlcl87CisgICAgUGFyc2VJbmZvVHJlZSogcGFyc2VfaW5mb190cmVlXzsKKyAgICBib29sIGFsbG93X3BhcnRpYWxfOworICAgIGJvb2wgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZF87CisgICAgYm9vbCBhbGxvd191bmtub3duX2ZpZWxkXzsKKyAgICBib29sIGFsbG93X3Vua25vd25fZW51bV87CisgICAgYm9vbCBhbGxvd19maWVsZF9udW1iZXJfOworICAgIGJvb2wgYWxsb3dfcmVsYXhlZF93aGl0ZXNwYWNlXzsKKyAgICBib29sIGFsbG93X3Npbmd1bGFyX292ZXJ3cml0ZXNfOworICB9OworCisKKyBwcml2YXRlOgorICAvLyBIYWNrOiBQYXJzZUluZm9UcmVlIGRlY2xhcmVzIFRleHRGb3JtYXQgYXMgYSBmcmllbmQgd2hpY2ggc2hvdWxkIGV4dGVuZAorICAvLyB0aGUgZnJpZW5kc2hpcCB0byBUZXh0Rm9ybWF0OjpQYXJzZXI6OlBhcnNlckltcGwsIGJ1dCB1bmZvcnR1bmF0ZWx5IHNvbWUKKyAgLy8gb2xkIGNvbXBpbGVycyAoZS5nLiBHQ0MgMy40LjYpIGRvbid0IGltcGxlbWVudCB0aGlzIGNvcnJlY3RseS4gV2UgcHJvdmlkZQorICAvLyBoZWxwZXJzIGZvciBQYXJzZXJJbXBsIHRvIGNhbGwgbWV0aG9kcyBvZiBQYXJzZUluZm9UcmVlLgorICBzdGF0aWMgaW5saW5lIHZvaWQgUmVjb3JkTG9jYXRpb24oUGFyc2VJbmZvVHJlZSogaW5mb190cmVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlTG9jYXRpb24gbG9jYXRpb24pOworICBzdGF0aWMgaW5saW5lIFBhcnNlSW5mb1RyZWUqIENyZWF0ZU5lc3RlZChQYXJzZUluZm9UcmVlKiBpbmZvX3RyZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUZXh0Rm9ybWF0KTsKK307CisKK2lubGluZSB2b2lkIFRleHRGb3JtYXQ6OlJlY29yZExvY2F0aW9uKFBhcnNlSW5mb1RyZWUqIGluZm9fdHJlZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJzZUxvY2F0aW9uIGxvY2F0aW9uKSB7CisgIGluZm9fdHJlZS0+UmVjb3JkTG9jYXRpb24oZmllbGQsIGxvY2F0aW9uKTsKK30KKworCitpbmxpbmUgVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSogVGV4dEZvcm1hdDo6Q3JlYXRlTmVzdGVkKAorICAgIFBhcnNlSW5mb1RyZWUqIGluZm9fdHJlZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gaW5mb190cmVlLT5DcmVhdGVOZXN0ZWQoZmllbGQpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVEVYVF9GT1JNQVRfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0X3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NzdmZGNiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDE0NzkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGpzY2hvcnJAZ29vZ2xlLmNvbSAoSm9zZXBoIFNjaG9ycikKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPGxpbWl0cz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBDYW4ndCB1c2UgYW4gYW5vbnltb3VzIG5hbWVzcGFjZSBoZXJlIGR1ZSB0byBicm9rZW5uZXNzIG9mIFRydTY0IGNvbXBpbGVyLgorbmFtZXNwYWNlIHRleHRfZm9ybWF0X3VuaXR0ZXN0IHsKKworaW5saW5lIGJvb2wgSXNOYU4oZG91YmxlIHZhbHVlKSB7CisgIC8vIE5hTiBpcyBuZXZlciBlcXVhbCB0byBhbnl0aGluZywgZXZlbiBpdHNlbGYuCisgIHJldHVybiB2YWx1ZSAhPSB2YWx1ZTsKK30KKworLy8gQSBiYXNpYyBzdHJpbmcgd2l0aCBkaWZmZXJlbnQgZXNjYXBhYmxlIGNoYXJhY3RlcnMgZm9yIHRlc3RpbmcuCitjb25zdCBzdHJpbmcga0VzY2FwZVRlc3RTdHJpbmcgPQorICAiXCJBIHN0cmluZyB3aXRoICcgY2hhcmFjdGVycyBcbiBhbmQgXHIgbmV3bGluZXMgYW5kIFx0IHRhYnMgYW5kIFwwMDEgIgorICAic2xhc2hlcyBcXCBhbmQgIG11bHRpcGxlICAgc3BhY2VzIjsKKworLy8gQSByZXByZXNlbnRhdGlvbiBvZiB0aGUgYWJvdmUgc3RyaW5nIHdpdGggYWxsIHRoZSBjaGFyYWN0ZXJzIGVzY2FwZWQuCitjb25zdCBzdHJpbmcga0VzY2FwZVRlc3RTdHJpbmdFc2NhcGVkID0KKyAgIlwiXFxcIkEgc3RyaW5nIHdpdGggXFwnIGNoYXJhY3RlcnMgXFxuIGFuZCBcXHIgbmV3bGluZXMgIgorICAiYW5kIFxcdCB0YWJzIGFuZCBcXDAwMSBzbGFzaGVzIFxcXFwgYW5kICBtdWx0aXBsZSAgIHNwYWNlc1wiIjsKKworY2xhc3MgVGV4dEZvcm1hdFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHVibGljOgorICBzdGF0aWMgdm9pZCBTZXRVcFRlc3RDYXNlKCkgeworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgICAgVGVzdFNvdXJjZURpcigpICsKKyAgICAgICAgICAgICIvZ29vZ2xlL3Byb3RvYnVmLyIKKyAgICAgICAgICAgICJ0ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX29uZW9mX2ltcGxlbWVudGVkLnR4dCIsCisgICAgICAgICZzdGF0aWNfcHJvdG9fZGVidWdfc3RyaW5nXywgdHJ1ZSkpOworICB9CisKKyAgVGV4dEZvcm1hdFRlc3QoKSA6IHByb3RvX2RlYnVnX3N0cmluZ18oc3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ18pIHt9CisKKyBwcm90ZWN0ZWQ6CisgIC8vIERlYnVnIHN0cmluZyByZWFkIGZyb20gdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQuCisgIGNvbnN0IHN0cmluZyBwcm90b19kZWJ1Z19zdHJpbmdfOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHByb3RvXzsKKworIHByaXZhdGU6CisgIHN0YXRpYyBzdHJpbmcgc3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ187Cit9Oworc3RyaW5nIFRleHRGb3JtYXRUZXN0OjpzdGF0aWNfcHJvdG9fZGVidWdfc3RyaW5nXzsKKworY2xhc3MgVGV4dEZvcm1hdEV4dGVuc2lvbnNUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHB1YmxpYzoKKyAgc3RhdGljIHZvaWQgU2V0VXBUZXN0Q2FzZSgpIHsKKyAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6R2V0Q29udGVudHMoVGVzdFNvdXJjZURpcigpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhLnR4dCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXRpY19wcm90b19kZWJ1Z19zdHJpbmdfLCB0cnVlKSk7CisgIH0KKworICBUZXh0Rm9ybWF0RXh0ZW5zaW9uc1Rlc3QoKQorICAgICAgOiBwcm90b19kZWJ1Z19zdHJpbmdfKHN0YXRpY19wcm90b19kZWJ1Z19zdHJpbmdfKSB7fQorCisgcHJvdGVjdGVkOgorICAvLyBEZWJ1ZyBzdHJpbmcgcmVhZCBmcm9tIHRleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0LgorICBjb25zdCBzdHJpbmcgcHJvdG9fZGVidWdfc3RyaW5nXzsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIHByb3RvXzsKKworIHByaXZhdGU6CisgIHN0YXRpYyBzdHJpbmcgc3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ187Cit9Oworc3RyaW5nIFRleHRGb3JtYXRFeHRlbnNpb25zVGVzdDo6c3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ187CisKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBCYXNpYykgeworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZwcm90b18pOworICBFWFBFQ1RfRVEocHJvdG9fZGVidWdfc3RyaW5nXywgcHJvdG9fLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdEV4dGVuc2lvbnNUZXN0LCBFeHRlbnNpb25zKSB7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZwcm90b18pOworICBFWFBFQ1RfRVEocHJvdG9fZGVidWdfc3RyaW5nXywgcHJvdG9fLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFNob3J0RGVidWdTdHJpbmcpIHsKKyAgcHJvdG9fLnNldF9vcHRpb25hbF9pbnQzMigxKTsKKyAgcHJvdG9fLnNldF9vcHRpb25hbF9zdHJpbmcoImhlbGxvIik7CisgIHByb3RvXy5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigyKTsKKyAgcHJvdG9fLm11dGFibGVfb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCk7CisKKyAgRVhQRUNUX0VRKCJvcHRpb25hbF9pbnQzMjogMSBvcHRpb25hbF9zdHJpbmc6IFwiaGVsbG9cIiAiCisgICAgICAgICAgICAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeyBiYjogMiB9ICIKKyAgICAgICAgICAgICJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgeyB9IiwKKyAgICAgICAgICAgIHByb3RvXy5TaG9ydERlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFNob3J0UHJpbWl0aXZlUmVwZWF0ZWRzKSB7CisgIHByb3RvXy5zZXRfb3B0aW9uYWxfaW50MzIoMTIzKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9pbnQzMig0NTYpOworICBwcm90b18uYWRkX3JlcGVhdGVkX2ludDMyKDc4OSk7CisgIHByb3RvXy5hZGRfcmVwZWF0ZWRfc3RyaW5nKCJmb28iKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9zdHJpbmcoImJhciIpOworICBwcm90b18uYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigyKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMyk7CisgIHByb3RvXy5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0odW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIpOworCisgIFRleHRGb3JtYXQ6OlByaW50ZXIgcHJpbnRlcjsKKyAgcHJpbnRlci5TZXRVc2VTaG9ydFJlcGVhdGVkUHJpbWl0aXZlcyh0cnVlKTsKKyAgc3RyaW5nIHRleHQ7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhwcm90b18sICZ0ZXh0KTsKKworICBFWFBFQ1RfRVEoIm9wdGlvbmFsX2ludDMyOiAxMjNcbiIKKyAgICAgICAgICAgICJyZXBlYXRlZF9pbnQzMjogWzQ1NiwgNzg5XVxuIgorICAgICAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJmb29cIlxuIgorICAgICAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJiYXJcIlxuIgorICAgICAgICAgICAgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHtcbiAgYmI6IDJcbn1cbiIKKyAgICAgICAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7XG4gIGJiOiAzXG59XG4iCisgICAgICAgICAgICAicmVwZWF0ZWRfbmVzdGVkX2VudW06IFtGT08sIEJBUl1cbiIsCisgICAgICAgICAgICB0ZXh0KTsKKworICAvLyBUcnkgaW4gc2luZ2xlLWxpbmUgbW9kZS4KKyAgcHJpbnRlci5TZXRTaW5nbGVMaW5lTW9kZSh0cnVlKTsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKHByb3RvXywgJnRleHQpOworCisgIEVYUEVDVF9FUSgib3B0aW9uYWxfaW50MzI6IDEyMyAiCisgICAgICAgICAgICAicmVwZWF0ZWRfaW50MzI6IFs0NTYsIDc4OV0gIgorICAgICAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJmb29cIiAiCisgICAgICAgICAgICAicmVwZWF0ZWRfc3RyaW5nOiBcImJhclwiICIKKyAgICAgICAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiAyIH0gIgorICAgICAgICAgICAgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHsgYmI6IDMgfSAiCisgICAgICAgICAgICAicmVwZWF0ZWRfbmVzdGVkX2VudW06IFtGT08sIEJBUl0gIiwKKyAgICAgICAgICAgIHRleHQpOworfQorCisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgU3RyaW5nRXNjYXBlKSB7CisgIC8vIFNldCB0aGUgc3RyaW5nIHZhbHVlIHRvIHRlc3QuCisgIHByb3RvXy5zZXRfb3B0aW9uYWxfc3RyaW5nKGtFc2NhcGVUZXN0U3RyaW5nKTsKKworICAvLyBHZXQgdGhlIERlYnVnU3RyaW5nIGZyb20gdGhlIHByb3RvLgorICBzdHJpbmcgZGVidWdfc3RyaW5nID0gcHJvdG9fLkRlYnVnU3RyaW5nKCk7CisgIHN0cmluZyB1dGY4X2RlYnVnX3N0cmluZyA9IHByb3RvXy5VdGY4RGVidWdTdHJpbmcoKTsKKworICAvLyBIYXJkY29kZSBhIGNvcnJlY3QgdmFsdWUgdG8gdGVzdCBhZ2FpbnN0LgorICBzdHJpbmcgY29ycmVjdF9zdHJpbmcgPSAib3B0aW9uYWxfc3RyaW5nOiAiCisgICAgICArIGtFc2NhcGVUZXN0U3RyaW5nRXNjYXBlZAorICAgICAgICsgIlxuIjsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoY29ycmVjdF9zdHJpbmcsIGRlYnVnX3N0cmluZyk7CisgIC8vIFVURi04IHN0cmluZyBpcyB0aGUgc2FtZSBhcyBub24tVVRGLTggYmVjYXVzZQorICAvLyB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbnRhaW5zIG5vIFVURi04IHRleHQuCisgIEVYUEVDVF9FUShjb3JyZWN0X3N0cmluZywgdXRmOF9kZWJ1Z19zdHJpbmcpOworCisgIHN0cmluZyBleHBlY3RlZF9zaG9ydF9kZWJ1Z19zdHJpbmcgPSAib3B0aW9uYWxfc3RyaW5nOiAiCisgICAgICArIGtFc2NhcGVUZXN0U3RyaW5nRXNjYXBlZDsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkX3Nob3J0X2RlYnVnX3N0cmluZywgcHJvdG9fLlNob3J0RGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgVXRmOERlYnVnU3RyaW5nKSB7CisgIC8vIFNldCB0aGUgc3RyaW5nIHZhbHVlIHRvIHRlc3QuCisgIHByb3RvXy5zZXRfb3B0aW9uYWxfc3RyaW5nKCJcMzUwXDI2MFwyNjdcMzQ2XDI1NVwyMTQiKTsKKyAgcHJvdG9fLnNldF9vcHRpb25hbF9ieXRlcygiXDM1MFwyNjBcMjY3XDM0NlwyNTVcMjE0Iik7CisKKyAgLy8gR2V0IHRoZSBEZWJ1Z1N0cmluZyBmcm9tIHRoZSBwcm90by4KKyAgc3RyaW5nIGRlYnVnX3N0cmluZyA9IHByb3RvXy5EZWJ1Z1N0cmluZygpOworICBzdHJpbmcgdXRmOF9kZWJ1Z19zdHJpbmcgPSBwcm90b18uVXRmOERlYnVnU3RyaW5nKCk7CisKKyAgLy8gSGFyZGNvZGUgYSBjb3JyZWN0IHZhbHVlIHRvIHRlc3QgYWdhaW5zdC4KKyAgc3RyaW5nIGNvcnJlY3RfdXRmOF9zdHJpbmcgPQorICAgICAgIm9wdGlvbmFsX3N0cmluZzogIgorICAgICAgIlwiXDM1MFwyNjBcMjY3XDM0NlwyNTVcMjE0XCIiCisgICAgICAiXG4iCisgICAgICAib3B0aW9uYWxfYnl0ZXM6ICIKKyAgICAgICJcIlxcMzUwXFwyNjBcXDI2N1xcMzQ2XFwyNTVcXDIxNFwiIgorICAgICAgIlxuIjsKKyAgc3RyaW5nIGNvcnJlY3Rfc3RyaW5nID0KKyAgICAgICJvcHRpb25hbF9zdHJpbmc6ICIKKyAgICAgICJcIlxcMzUwXFwyNjBcXDI2N1xcMzQ2XFwyNTVcXDIxNFwiIgorICAgICAgIlxuIgorICAgICAgIm9wdGlvbmFsX2J5dGVzOiAiCisgICAgICAiXCJcXDM1MFxcMjYwXFwyNjdcXDM0NlxcMjU1XFwyMTRcIiIKKyAgICAgICJcbiI7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKGNvcnJlY3RfdXRmOF9zdHJpbmcsIHV0ZjhfZGVidWdfc3RyaW5nKTsKKyAgRVhQRUNUX0VRKGNvcnJlY3Rfc3RyaW5nLCBkZWJ1Z19zdHJpbmcpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50VW5rbm93bkZpZWxkcykgeworICAvLyBUZXN0IHByaW50aW5nIG9mIHVua25vd24gZmllbGRzIGluIGEgbWVzc2FnZS4KKworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzID0gbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg1LCAxKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkMzIoNSwgMik7CisgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDY0KDUsIDMpOworICB1bmtub3duX2ZpZWxkcy0+QWRkTGVuZ3RoRGVsaW1pdGVkKDUsICI0Iik7CisgIHVua25vd25fZmllbGRzLT5BZGRHcm91cCg1KS0+QWRkVmFyaW50KDEwLCA1KTsKKworICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KDgsIDEpOworICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KDgsIDIpOworICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KDgsIDMpOworCisgIEVYUEVDVF9FUSgKKyAgICAiNTogMVxuIgorICAgICI1OiAweDAwMDAwMDAyXG4iCisgICAgIjU6IDB4MDAwMDAwMDAwMDAwMDAwM1xuIgorICAgICI1OiBcIjRcIlxuIgorICAgICI1IHtcbiIKKyAgICAiICAxMDogNVxuIgorICAgICJ9XG4iCisgICAgIjg6IDFcbiIKKyAgICAiODogMlxuIgorICAgICI4OiAzXG4iLAorICAgIG1lc3NhZ2UuRGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUHJpbnRVbmtub3duRmllbGRzSGlkZGVuKSB7CisgIC8vIFRlc3QgcHJpbnRpbmcgb2YgdW5rbm93biBmaWVsZHMgaW4gYSBtZXNzYWdlIHdoZW4gc3VwcHJlc3NlZC4KKworICB1bml0dGVzdDo6T25lU3RyaW5nIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X2RhdGEoImRhdGEiKTsKKyAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyA9IG1lc3NhZ2UubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworCisgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoNSwgMSk7CisgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDMyKDUsIDIpOworICB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQ2NCg1LCAzKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZExlbmd0aERlbGltaXRlZCg1LCAiNCIpOworICB1bmtub3duX2ZpZWxkcy0+QWRkR3JvdXAoNSktPkFkZFZhcmludCgxMCwgNSk7CisKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg4LCAxKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg4LCAyKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg4LCAzKTsKKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0SGlkZVVua25vd25GaWVsZHModHJ1ZSk7CisgIHN0cmluZyBvdXRwdXQ7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhtZXNzYWdlLCAmb3V0cHV0KTsKKworICBFWFBFQ1RfRVEoImRhdGE6IFwiZGF0YVwiXG4iLCBvdXRwdXQpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50VW5rbm93bk1lc3NhZ2UpIHsKKyAgLy8gVGVzdCBoZXVyaXN0aWMgcHJpbnRpbmcgb2YgbWVzc2FnZXMgaW4gYW4gVW5rbm93bkZpZWxkU2V0LgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICAvLyBDYXNlcyB3aGljaCBzaG91bGQgbm90IGJlIGludGVycHJldGVkIGFzIHN1Yi1tZXNzYWdlcy4KKworICAvLyAnYScgaXMgYSB2YWxpZCBGSVhFRDY0IHRhZywgc28gZm9yIHRoZSBzdHJpbmcgdG8gYmUgcGFyc2VhYmxlIGFzIGEgbWVzc2FnZQorICAvLyBpdCBzaG91bGQgYmUgZm9sbG93ZWQgYnkgOCBieXRlcy4gIFNpbmNlIHRoaXMgc3RyaW5nIG9ubHkgaGFzIHR3bworICAvLyBzdWJzZXF1ZW50IGJ5dGVzLCBpdCBzaG91bGQgYmUgdHJlYXRlZCBhcyBhIHN0cmluZy4KKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfc3RyaW5nKCJhYmMiKTsKKworICAvLyAnZCcgaGFwcGVucyB0byBiZSBhIHZhbGlkIEVOREdST1VQIHRhZy4gIFNvLAorICAvLyBVbmtub3duRmllbGRTZXQ6Ok1lcmdlRnJvbUNvZGVkU3RyZWFtKCkgd2lsbCBzdWNjZXNzZnVsbHkgcGFyc2UgImRlZiIsIGJ1dAorICAvLyB0aGUgQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgY2hlY2sgc2hvdWxkIGZhaWwuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZGVmIik7CisKKyAgLy8gQSB6ZXJvLWxlbmd0aCBzdHJpbmcgc2hvdWxkIG5ldmVyIGJlIGludGVycHJldGVkIGFzIGEgbWVzc2FnZSBldmVuIHRob3VnaAorICAvLyBpdCBpcyB0ZWNobmljYWxseSB2YWxpZCBhcyBvbmUuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiIik7CisKKyAgLy8gQ2FzZSB3aGljaCBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgYSBzdWItbWVzc2FnZS4KKworICAvLyBBbiBhY3R1YWwgbmVzdGVkIG1lc3NhZ2Ugd2l0aCBjb250ZW50IHNob3VsZCBhbHdheXMgYmUgaW50ZXJwcmV0ZWQgYXMgYQorICAvLyBuZXN0ZWQgbWVzc2FnZS4KKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEyMyk7CisKKyAgc3RyaW5nIGRhdGE7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIHN0cmluZyB0ZXh0OworICBVbmtub3duRmllbGRTZXQgdW5rbm93bl9maWVsZHM7CisgIEVYUEVDVF9UUlVFKHVua25vd25fZmllbGRzLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlByaW50VW5rbm93bkZpZWxkc1RvU3RyaW5nKHVua25vd25fZmllbGRzLCAmdGV4dCkpOworICBFWFBFQ1RfRVEoCisgICAgIjQ0OiBcImFiY1wiXG4iCisgICAgIjQ0OiBcImRlZlwiXG4iCisgICAgIjQ0OiBcIlwiXG4iCisgICAgIjQ4IHtcbiIKKyAgICAiICAxOiAxMjNcbiIKKyAgICAifVxuIiwKKyAgICB0ZXh0KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQcmludE1lc3NhZ2VXaXRoSW5kZW50KSB7CisgIC8vIFRlc3QgYWRkaW5nIGFuIGluaXRpYWwgaW5kZW50IHRvIHByaW50aW5nLgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoImFiYyIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoImRlZiIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTIzKTsKKworICBzdHJpbmcgdGV4dDsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBwcmludGVyLlNldEluaXRpYWxJbmRlbnRMZXZlbCgxKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KSk7CisgIEVYUEVDVF9FUSgKKyAgICAiICByZXBlYXRlZF9zdHJpbmc6IFwiYWJjXCJcbiIKKyAgICAiICByZXBlYXRlZF9zdHJpbmc6IFwiZGVmXCJcbiIKKyAgICAiICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7XG4iCisgICAgIiAgICBiYjogMTIzXG4iCisgICAgIiAgfVxuIiwKKyAgICB0ZXh0KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQcmludE1lc3NhZ2VTaW5nbGVMaW5lKSB7CisgIC8vIFRlc3QgcHJpbnRpbmcgYSBtZXNzYWdlIG9uIGEgc2luZ2xlIGxpbmUuCisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiYWJjIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZGVmIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigxMjMpOworCisgIHN0cmluZyB0ZXh0OworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0SW5pdGlhbEluZGVudExldmVsKDEpOworICBwcmludGVyLlNldFNpbmdsZUxpbmVNb2RlKHRydWUpOworICBFWFBFQ1RfVFJVRShwcmludGVyLlByaW50VG9TdHJpbmcobWVzc2FnZSwgJnRleHQpKTsKKyAgRVhQRUNUX0VRKAorICAgICIgIHJlcGVhdGVkX3N0cmluZzogXCJhYmNcIiByZXBlYXRlZF9zdHJpbmc6IFwiZGVmXCIgIgorICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiAxMjMgfSAiLAorICAgIHRleHQpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50QnVmZmVyVG9vU21hbGwpIHsKKyAgLy8gVGVzdCBwcmludGluZyBhIG1lc3NhZ2UgdG8gYSBidWZmZXIgdGhhdCBpcyB0b28gc21hbGwuCisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiYWJjIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZGVmIik7CisKKyAgY2hhciBidWZmZXJbMV0gPSAiIjsKKyAgaW86OkFycmF5T3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oYnVmZmVyLCAxKTsKKyAgRVhQRUNUX0ZBTFNFKFRleHRGb3JtYXQ6OlByaW50KG1lc3NhZ2UsICZvdXRwdXRfc3RyZWFtKSk7CisgIEVYUEVDVF9FUShidWZmZXJbMF0sICdyJyk7CisgIEVYUEVDVF9FUShvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpLCAxKTsKK30KKworLy8gQSBwcmludGVyIHRoYXQgYXBwZW5kcyAndScgdG8gYWxsIHVuc2lnbmVkIGludDMyLgorY2xhc3MgQ3VzdG9tVUludDMyRmllbGRWYWx1ZVByaW50ZXIgOiBwdWJsaWMgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCBzdHJpbmcgUHJpbnRVSW50MzIodWludDMyIHZhbCkgY29uc3QgeworICAgIHJldHVybiBTdHJDYXQoRmllbGRWYWx1ZVByaW50ZXI6OlByaW50VUludDMyKHZhbCksICJ1Iik7CisgIH0KK307CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgRGVmYXVsdEN1c3RvbUZpZWxkUHJpbnRlcikgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfdWludDMyKDQyKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfdWludDMyKDEpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF91aW50MzIoMik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3VpbnQzMigzKTsKKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0RGVmYXVsdEZpZWxkVmFsdWVQcmludGVyKG5ldyBDdXN0b21VSW50MzJGaWVsZFZhbHVlUHJpbnRlcigpKTsKKyAgLy8gTGV0J3Mgc2VlIGlmIHRoYXQgd29ya3Mgd2VsbCB0b2dldGhlciB3aXRoIHRoZSByZXBlYXRlZCBwcmltaXRpdmVzOgorICBwcmludGVyLlNldFVzZVNob3J0UmVwZWF0ZWRQcmltaXRpdmVzKHRydWUpOworICBzdHJpbmcgdGV4dDsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KTsKKyAgRVhQRUNUX0VRKCJvcHRpb25hbF91aW50MzI6IDQydVxucmVwZWF0ZWRfdWludDMyOiBbMXUsIDJ1LCAzdV1cbiIsIHRleHQpOworfQorCitjbGFzcyBDdXN0b21JbnQzMkZpZWxkVmFsdWVQcmludGVyIDogcHVibGljIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgc3RyaW5nIFByaW50SW50MzIoaW50MzIgdmFsKSBjb25zdCB7CisgICAgcmV0dXJuIFN0ckNhdCgidmFsdWUtaXMoIiwgRmllbGRWYWx1ZVByaW50ZXI6OlByaW50SW50MzIodmFsKSwgIikiKTsKKyAgfQorfTsKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBGaWVsZFNwZWNpZmljQ3VzdG9tUHJpbnRlcikgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoNDIpOyAgLy8gVGhpcyB3aWxsIGJlIGhhbmRsZWQgYnkgb3VyIFByaW50ZXIuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ludDMyKDQyKTsgIC8vIFRoaXMgd2lsbCBiZSBwcmludGVkIGFzIG51bWJlci4KKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIEVYUEVDVF9UUlVFKHByaW50ZXIuUmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcigKKyAgICAgIG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ludDMyIiksCisgICAgICBuZXcgQ3VzdG9tSW50MzJGaWVsZFZhbHVlUHJpbnRlcigpKSk7CisgIHN0cmluZyB0ZXh0OworICBwcmludGVyLlByaW50VG9TdHJpbmcobWVzc2FnZSwgJnRleHQpOworICBFWFBFQ1RfRVEoIm9wdGlvbmFsX2ludDMyOiB2YWx1ZS1pcyg0MilcbnJlcGVhdGVkX2ludDMyOiA0MlxuIiwgdGV4dCk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgRXJyb3JDYXNlc1JlZ2lzdGVyaW5nRmllbGRWYWx1ZVByaW50ZXJTaG91bGRGYWlsKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICAvLyBOVUxMIHByaW50ZXIuCisgIEVYUEVDVF9GQUxTRShwcmludGVyLlJlZ2lzdGVyRmllbGRWYWx1ZVByaW50ZXIoCisgICAgICBtZXNzYWdlLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpLAorICAgICAgTlVMTCkpOworICAvLyBCZWNhdXNlIHJlZ2lzdHJhdGlvbiBmYWlscywgdGhlIG93bmVyc2hpcCBvZiB0aGlzIHByaW50ZXIgaXMgbmV2ZXIgdGFrZW4uCisgIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyIG15X2ZpZWxkX3ByaW50ZXI7CisgIC8vIE5VTEwgZmllbGQKKyAgRVhQRUNUX0ZBTFNFKHByaW50ZXIuUmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcihOVUxMLCAmbXlfZmllbGRfcHJpbnRlcikpOworfQorCitjbGFzcyBDdXN0b21NZXNzYWdlRmllbGRWYWx1ZVByaW50ZXIgOiBwdWJsaWMgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCBzdHJpbmcgUHJpbnRJbnQzMihpbnQzMiB2KSBjb25zdCB7CisgICAgcmV0dXJuIFN0ckNhdChGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRJbnQzMih2KSwgIiAgIyB4IiwgVG9IZXgodikpOworICB9CisKKyAgdmlydHVhbCBzdHJpbmcgUHJpbnRNZXNzYWdlU3RhcnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2luZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfY291bnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2luZ2xlX2xpbmVfbW9kZSkgY29uc3QgeworICAgIGlmIChzaW5nbGVfbGluZV9tb2RlKSB7CisgICAgICByZXR1cm4gIiB7ICI7CisgICAgfQorICAgIHJldHVybiBTdHJDYXQoCisgICAgICAgICIgeyAgIyAiLCBtZXNzYWdlLkdldERlc2NyaXB0b3IoKS0+bmFtZSgpLCAiOiAiLCBmaWVsZF9pbmRleCwgIlxuIik7CisgIH0KK307CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgQ3VzdG9tUHJpbnRlckZvckNvbW1lbnRzKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCk7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSgpLT5zZXRfZCg0Mik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlKCktPnNldF9kKDQzKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UoKS0+c2V0X2QoNDQpOworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIEN1c3RvbU1lc3NhZ2VGaWVsZFZhbHVlUHJpbnRlciBteV9maWVsZF9wcmludGVyOworICBwcmludGVyLlNldERlZmF1bHRGaWVsZFZhbHVlUHJpbnRlcihuZXcgQ3VzdG9tTWVzc2FnZUZpZWxkVmFsdWVQcmludGVyKCkpOworICBzdHJpbmcgdGV4dDsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KTsKKyAgRVhQRUNUX0VRKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsgICMgTmVzdGVkTWVzc2FnZTogLTFcbiIKKyAgICAgICJ9XG4iCisgICAgICAib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgeyAgIyBJbXBvcnRNZXNzYWdlOiAtMVxuIgorICAgICAgIiAgZDogNDIgICMgeDJhXG4iCisgICAgICAifVxuIgorICAgICAgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHsgICMgTmVzdGVkTWVzc2FnZTogMFxuIgorICAgICAgIn1cbiIKKyAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7ICAjIE5lc3RlZE1lc3NhZ2U6IDFcbiIKKyAgICAgICJ9XG4iCisgICAgICAicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgeyAgIyBJbXBvcnRNZXNzYWdlOiAwXG4iCisgICAgICAiICBkOiA0MyAgIyB4MmJcbiIKKyAgICAgICJ9XG4iCisgICAgICAicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgeyAgIyBJbXBvcnRNZXNzYWdlOiAxXG4iCisgICAgICAiICBkOiA0NCAgIyB4MmNcbiIKKyAgICAgICJ9XG4iLAorICAgICAgdGV4dCk7Cit9CisKK2NsYXNzIEN1c3RvbU11bHRpbGluZUNvbW1lbnRQcmludGVyIDogcHVibGljIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgc3RyaW5nIFByaW50TWVzc2FnZVN0YXJ0KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9pbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2NvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNpbmdsZV9saW5lX2NvbW1lbnQpIGNvbnN0IHsKKyAgICByZXR1cm4gU3RyQ2F0KCIgeyAgIyAxXG4iLCAiICAjIDJcbiIpOworICB9Cit9OworCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIEN1c3RvbVByaW50ZXJGb3JNdWx0aWxpbmVDb21tZW50cykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UoKS0+c2V0X2QoNDIpOworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIEN1c3RvbU1lc3NhZ2VGaWVsZFZhbHVlUHJpbnRlciBteV9maWVsZF9wcmludGVyOworICBwcmludGVyLlNldERlZmF1bHRGaWVsZFZhbHVlUHJpbnRlcihuZXcgQ3VzdG9tTXVsdGlsaW5lQ29tbWVudFByaW50ZXIoKSk7CisgIHN0cmluZyB0ZXh0OworICBwcmludGVyLlByaW50VG9TdHJpbmcobWVzc2FnZSwgJnRleHQpOworICBFWFBFQ1RfRVEoCisgICAgICAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeyAgIyAxXG4iCisgICAgICAiICAjIDJcbiIKKyAgICAgICJ9XG4iCisgICAgICAib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgeyAgIyAxXG4iCisgICAgICAiICAjIDJcbiIKKyAgICAgICIgIGQ6IDQyXG4iCisgICAgICAifVxuIiwKKyAgICAgIHRleHQpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFBhcnNlQmFzaWMpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKHByb3RvX2RlYnVnX3N0cmluZ18uZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9fZGVidWdfc3RyaW5nXy5zaXplKCkpOworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtLCAmcHJvdG9fKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChwcm90b18pOworfQorCitURVNUX0YoVGV4dEZvcm1hdEV4dGVuc2lvbnNUZXN0LCBQYXJzZUV4dGVuc2lvbnMpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKHByb3RvX2RlYnVnX3N0cmluZ18uZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9fZGVidWdfc3RyaW5nXy5zaXplKCkpOworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtLCAmcHJvdG9fKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQocHJvdG9fKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQYXJzZUVudW1GaWVsZEZyb21OdW1iZXIpIHsKKyAgLy8gQ3JlYXRlIGEgcGFyc2Ugc3RyaW5nIHdpdGggYSBudW1lcmljYWwgdmFsdWUgZm9yIGFuIGVudW0gZmllbGQuCisgIHN0cmluZyBwYXJzZV9zdHJpbmcgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKCJvcHRpb25hbF9uZXN0ZWRfZW51bTogJDAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVopOworICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcocGFyc2Vfc3RyaW5nLCAmcHJvdG9fKSk7CisgIEVYUEVDVF9UUlVFKHByb3RvXy5oYXNfb3B0aW9uYWxfbmVzdGVkX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIHByb3RvXy5vcHRpb25hbF9uZXN0ZWRfZW51bSgpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQYXJzZUVudW1GaWVsZEZyb21OZWdhdGl2ZU51bWJlcikgeworICBBU1NFUlRfTFQodW5pdHRlc3Q6OlNQQVJTRV9FLCAwKTsKKyAgc3RyaW5nIHBhcnNlX3N0cmluZyA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoInNwYXJzZV9lbnVtOiAkMCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpTUEFSU0VfRSk7CisgIHVuaXR0ZXN0OjpTcGFyc2VFbnVtTWVzc2FnZSBwcm90bzsKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKHBhcnNlX3N0cmluZywgJnByb3RvKSk7CisgIEVYUEVDVF9UUlVFKHByb3RvLmhhc19zcGFyc2VfZW51bSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpTUEFSU0VfRSwgcHJvdG8uc3BhcnNlX2VudW0oKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VTdHJpbmdFc2NhcGUpIHsKKyAgLy8gQ3JlYXRlIGEgcGFyc2Ugc3RyaW5nIHdpdGggZXNjcGFlZCBjaGFyYWN0ZXJzIGluIGl0LgorICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0gIm9wdGlvbmFsX3N0cmluZzogIgorICAgICAgKyBrRXNjYXBlVGVzdFN0cmluZ0VzY2FwZWQKKyAgICAgICsgIlxuIjsKKworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSBpbnB1dF9zdHJlYW0ocGFyc2Vfc3RyaW5nLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX3N0cmluZy5zaXplKCkpOworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtLCAmcHJvdG9fKTsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoa0VzY2FwZVRlc3RTdHJpbmcsIHByb3RvXy5vcHRpb25hbF9zdHJpbmcoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VDb25jYXRlbmF0ZWRTdHJpbmcpIHsKKyAgLy8gQ3JlYXRlIGEgcGFyc2Ugc3RyaW5nIHdpdGggbXVsdGlwbGUgcGFydHMgb24gb25lIGxpbmUuCisgIHN0cmluZyBwYXJzZV9zdHJpbmcgPSAib3B0aW9uYWxfc3RyaW5nOiBcImZvb1wiIFwiYmFyXCJcbiI7CisKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtMShwYXJzZV9zdHJpbmcuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2Vfc3RyaW5nLnNpemUoKSk7CisgIFRleHRGb3JtYXQ6OlBhcnNlKCZpbnB1dF9zdHJlYW0xLCAmcHJvdG9fKTsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoImZvb2JhciIsIHByb3RvXy5vcHRpb25hbF9zdHJpbmcoKSk7CisKKyAgLy8gQ3JlYXRlIGEgcGFyc2Ugc3RyaW5nIHdpdGggbXVsdGlwbGUgcGFydHMgb24gc2VwYXJhdGUgbGluZXMuCisgIHBhcnNlX3N0cmluZyA9ICJvcHRpb25hbF9zdHJpbmc6IFwiZm9vXCJcbiIKKyAgICAgICAgICAgICAgICAgIlwiYmFyXCJcbiI7CisKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtMihwYXJzZV9zdHJpbmcuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2Vfc3RyaW5nLnNpemUoKSk7CisgIFRleHRGb3JtYXQ6OlBhcnNlKCZpbnB1dF9zdHJlYW0yLCAmcHJvdG9fKTsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoImZvb2JhciIsIHByb3RvXy5vcHRpb25hbF9zdHJpbmcoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VGbG9hdFdpdGhTdWZmaXgpIHsKKyAgLy8gVGVzdCB0aGF0IHdlIGNhbiBwYXJzZSBhIGZsb2F0aW5nLXBvaW50IHZhbHVlIHdpdGggJ2YnIGFwcGVuZGVkIHRvIHRoZQorICAvLyBlbmQuICBUaGlzIGlzIG5lZWRlZCBmb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCBwcm90bzEuCisKKyAgLy8gSGF2ZSBpdCBwYXJzZSBhIGZsb2F0IHdpdGggdGhlICdmJyBzdWZmaXguCisgIHN0cmluZyBwYXJzZV9zdHJpbmcgPSAib3B0aW9uYWxfZmxvYXQ6IDEuMGZcbiI7CisKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKHBhcnNlX3N0cmluZy5kYXRhKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZV9zdHJpbmcuc2l6ZSgpKTsKKworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtLCAmcHJvdG9fKTsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoMS4wLCBwcm90b18ub3B0aW9uYWxfZmxvYXQoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VTaG9ydFJlcGVhdGVkRm9ybSkgeworICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0KKyAgICAgIC8vIE1peGVkIHNob3J0LWZvcm0gYW5kIGxvbmctZm9ybSBhcmUgc2ltcGx5IGNvbmNhdGVuYXRlZC4KKyAgICAgICJyZXBlYXRlZF9pbnQzMjogMVxuIgorICAgICAgInJlcGVhdGVkX2ludDMyOiBbNDU2LCA3ODldXG4iCisgICAgICAicmVwZWF0ZWRfbmVzdGVkX2VudW06IFsgIEZPTyAsQkFSLCAjIGNvbW1lbnRcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgM11cbiIKKyAgICAgIC8vIE5vdGUgdGhhdCB3aGlsZSB0aGUgcHJpbnRlciB3b24ndCBwcmludCByZXBlYXRlZCBzdHJpbmdzIGluIHNob3J0LWZvcm0sCisgICAgICAvLyB0aGUgcGFyc2VyIHdpbGwgYWNjZXB0IHRoZW0uCisgICAgICAicmVwZWF0ZWRfc3RyaW5nOiBbIFwiZm9vXCIsICdiYXInIF1cbiIKKyAgICAgIC8vIFJlcGVhdGVkIG1lc3NhZ2UKKyAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZTogWyB7IGJiOiAxIH0sIHsgYmIgOiAyIH1dXG4iCisgICAgICAvLyBSZXBlYXRlZCBncm91cAorICAgICAgIlJlcGVhdGVkR3JvdXAgW3sgYTogMyB9LHsgYTogNCB9XVxuIjsKKworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcocGFyc2Vfc3RyaW5nLCAmcHJvdG9fKSk7CisKKyAgQVNTRVJUX0VRKDMsIHByb3RvXy5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgcHJvdG9fLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKDQ1NiwgcHJvdG9fLnJlcGVhdGVkX2ludDMyKDEpKTsKKyAgRVhQRUNUX0VRKDc4OSwgcHJvdG9fLnJlcGVhdGVkX2ludDMyKDIpKTsKKworICBBU1NFUlRfRVEoMywgcHJvdG9fLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIHByb3RvXy5yZXBlYXRlZF9uZXN0ZWRfZW51bSgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIHByb3RvXy5yZXBlYXRlZF9uZXN0ZWRfZW51bSgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIHByb3RvXy5yZXBlYXRlZF9uZXN0ZWRfZW51bSgyKSk7CisKKyAgQVNTRVJUX0VRKDIsIHByb3RvXy5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBwcm90b18ucmVwZWF0ZWRfc3RyaW5nKDApKTsKKyAgRVhQRUNUX0VRKCJiYXIiLCBwcm90b18ucmVwZWF0ZWRfc3RyaW5nKDEpKTsKKworICBBU1NFUlRfRVEoMiwgcHJvdG9fLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBwcm90b18ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyLCBwcm90b18ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMSkuYmIoKSk7CisKKyAgQVNTRVJUX0VRKDIsIHByb3RvXy5yZXBlYXRlZGdyb3VwX3NpemUoKSk7CisgIEVYUEVDVF9FUSgzLCBwcm90b18ucmVwZWF0ZWRncm91cCgwKS5hKCkpOworICBFWFBFQ1RfRVEoNCwgcHJvdG9fLnJlcGVhdGVkZ3JvdXAoMSkuYSgpKTsKK30KKworCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIENvbW1lbnRzKSB7CisgIC8vIFRlc3QgdGhhdCBjb21tZW50cyBhcmUgaWdub3JlZC4KKworICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0gIm9wdGlvbmFsX2ludDMyOiAxICAjIGEgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbmFsX2ludDY0OiAyICAjIGFub3RoZXIgY29tbWVudCI7CisKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKHBhcnNlX3N0cmluZy5kYXRhKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZV9zdHJpbmcuc2l6ZSgpKTsKKworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtLCAmcHJvdG9fKTsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoMSwgcHJvdG9fLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoMiwgcHJvdG9fLm9wdGlvbmFsX2ludDY0KCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIE9wdGlvbmFsQ29sb24pIHsKKyAgLy8gVGVzdCB0aGF0IHdlIGNhbiBwbGFjZSBhICc6JyBhZnRlciB0aGUgZmllbGQgbmFtZSBvZiBhIG5lc3RlZCBtZXNzYWdlLAorICAvLyBldmVuIHRob3VnaCB3ZSBkb24ndCBoYXZlIHRvLgorCisgIHN0cmluZyBwYXJzZV9zdHJpbmcgPSAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2U6IHsgYmI6IDF9XG4iOworCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShwYXJzZV9zdHJpbmcuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2Vfc3RyaW5nLnNpemUoKSk7CisKKyAgVGV4dEZvcm1hdDo6UGFyc2UoJmlucHV0X3N0cmVhbSwgJnByb3RvXyk7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX1RSVUUocHJvdG9fLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKDEsIHByb3RvXy5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworfQorCisvLyBTb21lIHBsYXRmb3JtcyAoZS5nLiBXaW5kb3dzKSBpbnNpc3Qgb24gcGFkZGluZyB0aGUgZXhwb25lbnQgdG8gdGhyZWUKKy8vIGRpZ2l0cyB3aGVuIG9uZSBvciB0d28gd291bGQgYmUganVzdCBmaW5lLgorc3RhdGljIHN0cmluZyBSZW1vdmVSZWR1bmRhbnRaZXJvcyhzdHJpbmcgdGV4dCkgeworICB0ZXh0ID0gU3RyaW5nUmVwbGFjZSh0ZXh0LCAiZSswIiwgImUrIiwgdHJ1ZSk7CisgIHRleHQgPSBTdHJpbmdSZXBsYWNlKHRleHQsICJlLTAiLCAiZS0iLCB0cnVlKTsKKyAgcmV0dXJuIHRleHQ7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUHJpbnRFeG90aWMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIC8vIE5vdGU6ICBJbiBDLCBhIG5lZ2F0aXZlIGludGVnZXIgbGl0ZXJhbCBpcyBhY3R1YWxseSB0aGUgdW5hcnkgbmVnYXRpb24KKyAgLy8gICBvcGVyYXRvciBiZWluZyBhcHBsaWVkIHRvIGEgcG9zaXRpdmUgaW50ZWdlciBsaXRlcmFsLCBhbmQKKyAgLy8gICA5MjIzMzcyMDM2ODU0Nzc1ODA4IGlzIG91dHNpZGUgdGhlIHJhbmdlIG9mIGludDY0LiAgSG93ZXZlciwgaXQgaXMgbm90CisgIC8vICAgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YgdWludDY0LiAgQ29uZnVzaW5nbHksIHRoaXMgbWVhbnMgdGhhdCBldmVyeXRoaW5nCisgIC8vICAgd29ya3MgaWYgd2UgbWFrZSB0aGUgbGl0ZXJhbCB1bnNpZ25lZCwgZXZlbiB0aG91Z2ggd2UgYXJlIG5lZ2F0aW5nIGl0LgorICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9pbnQ2NCgtR09PR0xFX1VMT05HTE9ORyg5MjIzMzcyMDM2ODU0Nzc1ODA4KSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3VpbnQ2NChHT09HTEVfVUxPTkdMT05HKDE4NDQ2NzQ0MDczNzA5NTUxNjE1KSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxMjMuNDU2KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjNlMjEpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yM2UtMTgpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKC1zdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjpxdWlldF9OYU4oKSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZyhzdHJpbmcoIlwwMDBcMDAxXGFcYlxmXG5cclx0XHZcXFwnXCIiLCAxMikpOworCisgIC8vIEZ1biBzdG9yeTogIFdlIHVzZWQgdG8gdXNlIDEuMjNlMjIgaW5zdGVhZCBvZiAxLjIzZTIxIGFib3ZlLCBidXQgdGhpcworICAvLyAgIHNlZW1lZCB0byB0cmlnZ2VyIGFuIG9kZCBjYXNlIG9uIE1pbkdXL0dDQyAzLjQuNSB3aGVyZSBHQ0MncyBwYXJzaW5nIG9mCisgIC8vICAgdGhlIHZhbHVlIGRpZmZlcmVkIGZyb20gc3RydG9kKCkncyBwYXJzaW5nLiAgVGhhdCBpcyB0byBzYXksIHRoZQorICAvLyAgIGZvbGxvd2luZyBhc3NlcnRpb24gZmFpbHMgb24gTWluR1c6CisgIC8vICAgICBhc3NlcnQoMS4yM2UyMiA9PSBzdHJ0b2QoIjEuMjNlMjIiLCBOVUxMKSk7CisgIC8vICAgQXMgYSByZXN1bHQsIFNpbXBsZUR0b2EoKSB3b3VsZCBwcmludCB0aGUgdmFsdWUgYXMKKyAgLy8gICAiMS4yMzAwMDAwMDAwMDAwMDAxZSsyMiIgdG8gbWFrZSBzdXJlIHN0cnRvZCgpIHByb2R1Y2UgdGhlIGV4YWN0IHNhbWUKKyAgLy8gICByZXN1bHQuICBPdXIgZ29hbCBpcyB0byB0ZXN0IHJ1bnRpbWUgcGFyc2luZywgbm90IGNvbXBpbGUtdGltZSBwYXJzaW5nLAorICAvLyAgIHNvIHRoaXMgd2Fzbid0IG91ciBwcm9ibGVtLiAgSXQgd2FzIGZvdW5kIHRoYXQgdXNpbmcgMS4yM2UyMSBkaWQgbm90CisgIC8vICAgaGF2ZSB0aGlzIHByb2JsZW0sIHNvIHdlIHN3aXRjaGVkIHRvIHRoYXQgaW5zdGVhZC4KKworICBFWFBFQ1RfRVEoCisgICAgInJlcGVhdGVkX2ludDY0OiAtOTIyMzM3MjAzNjg1NDc3NTgwOFxuIgorICAgICJyZXBlYXRlZF91aW50NjQ6IDE4NDQ2NzQ0MDczNzA5NTUxNjE1XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMTIzLjQ1NlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjNlKzIxXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yM2UtMThcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBpbmZcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAtaW5mXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogbmFuXG4iCisgICAgInJlcGVhdGVkX3N0cmluZzogXCJcXDAwMFxcMDAxXFwwMDdcXDAxMFxcMDE0XFxuXFxyXFx0XFwwMTNcXFxcXFwnXFxcIlwiXG4iLAorICAgIFJlbW92ZVJlZHVuZGFudFplcm9zKG1lc3NhZ2UuRGVidWdTdHJpbmcoKSkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50RmxvYXRQcmVjaXNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2Zsb2F0KDEuMik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2Zsb2F0KDEuMjMpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzNCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2Zsb2F0KDEuMjM0NSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2Zsb2F0KDEuMjM0NTYpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjJlMTApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzZTEwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZmxvYXQoMS4yMzRlMTApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzNDVlMTApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzNDU2ZTEwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3OCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4Nyk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODc2KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4NzY1KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4NzY1NCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODc2NTQzKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMmUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yM2UxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzRlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NWUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1NmUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1NjdlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3OGUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OWUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OThlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4N2UxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OTg3NmUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OTg3NjVlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4NzY1NGUxMDApOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OTg3NjU0M2UxMDApOworCisgIEVYUEVDVF9FUSgKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMlxuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yM1xuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yMzRcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjM0NVxuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yMzQ1NlxuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yZSsxMFxuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yM2UrMTBcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjM0ZSsxMFxuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yMzQ1ZSsxMFxuIgorICAgICJyZXBlYXRlZF9mbG9hdDogMS4yMzQ1NmUrMTBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjJcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzRcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDVcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1NjdcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2NzhcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OThcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODdcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODc2XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NjVcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODc2NTRcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODc2NTQzXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNGUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2N2UrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5OGUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODc2ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODc2NWUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NjU0ZSsxMDBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzNDU2Nzg5ODc2NTQzZSsxMDBcbiIsCisgICAgUmVtb3ZlUmVkdW5kYW50WmVyb3MobWVzc2FnZS5EZWJ1Z1N0cmluZygpKSk7Cit9CisKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBBbGxvd1BhcnRpYWwpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBUZXh0Rm9ybWF0OjpQYXJzZXIgcGFyc2VyOworICBwYXJzZXIuQWxsb3dQYXJ0aWFsTWVzc2FnZSh0cnVlKTsKKyAgRVhQRUNUX1RSVUUocGFyc2VyLlBhcnNlRnJvbVN0cmluZygiYTogMSIsICZtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLmEoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfYygpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQYXJzZUV4b3RpYykgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAicmVwZWF0ZWRfaW50MzI6IC0xXG4iCisgICAgInJlcGVhdGVkX2ludDMyOiAtMjE0NzQ4MzY0OFxuIgorICAgICJyZXBlYXRlZF9pbnQ2NDogLTFcbiIKKyAgICAicmVwZWF0ZWRfaW50NjQ6IC05MjIzMzcyMDM2ODU0Nzc1ODA4XG4iCisgICAgInJlcGVhdGVkX3VpbnQzMjogNDI5NDk2NzI5NVxuIgorICAgICJyZXBlYXRlZF91aW50MzI6IDIxNDc0ODM2NDhcbiIKKyAgICAicmVwZWF0ZWRfdWludDY0OiAxODQ0Njc0NDA3MzcwOTU1MTYxNVxuIgorICAgICJyZXBlYXRlZF91aW50NjQ6IDkyMjMzNzIwMzY4NTQ3NzU4MDhcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxMjMuMFxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEyMy41XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMC4xMjVcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzRTE3XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzVFKzIyXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzVlLTE4XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMTIzLjQ1Njc4OVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IGluZlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IEluZmluaXR5XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogLWluZlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IC1JbmZpbml0eVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IG5hblxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IE5hTlxuIgorICAgICJyZXBlYXRlZF9zdHJpbmc6IFwiXFwwMDBcXDAwMVxcYVxcYlxcZlxcblxcclxcdFxcdlxcXFxcXCdcXFwiXCJcbiIsCisgICAgJm1lc3NhZ2UpKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoLTEsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIoMCkpOworICAvLyBOb3RlOiAgSW4gQywgYSBuZWdhdGl2ZSBpbnRlZ2VyIGxpdGVyYWwgaXMgYWN0dWFsbHkgdGhlIHVuYXJ5IG5lZ2F0aW9uCisgIC8vICAgb3BlcmF0b3IgYmVpbmcgYXBwbGllZCB0byBhIHBvc2l0aXZlIGludGVnZXIgbGl0ZXJhbCwgYW5kIDIxNDc0ODM2NDggaXMKKyAgLy8gICBvdXRzaWRlIHRoZSByYW5nZSBvZiBpbnQzMi4gIEhvd2V2ZXIsIGl0IGlzIG5vdCBvdXRzaWRlIHRoZSByYW5nZSBvZgorICAvLyAgIHVpbnQzMi4gIENvbmZ1c2luZ2x5LCB0aGlzIG1lYW5zIHRoYXQgZXZlcnl0aGluZyB3b3JrcyBpZiB3ZSBtYWtlIHRoZQorICAvLyAgIGxpdGVyYWwgdW5zaWduZWQsIGV2ZW4gdGhvdWdoIHdlIGFyZSBuZWdhdGluZyBpdC4KKyAgRVhQRUNUX0VRKC0yMTQ3NDgzNjQ4dSwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMigxKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKC0xLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0KDApKTsKKyAgLy8gTm90ZTogIEluIEMsIGEgbmVnYXRpdmUgaW50ZWdlciBsaXRlcmFsIGlzIGFjdHVhbGx5IHRoZSB1bmFyeSBuZWdhdGlvbgorICAvLyAgIG9wZXJhdG9yIGJlaW5nIGFwcGxpZWQgdG8gYSBwb3NpdGl2ZSBpbnRlZ2VyIGxpdGVyYWwsIGFuZAorICAvLyAgIDkyMjMzNzIwMzY4NTQ3NzU4MDggaXMgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YgaW50NjQuICBIb3dldmVyLCBpdCBpcyBub3QKKyAgLy8gICBvdXRzaWRlIHRoZSByYW5nZSBvZiB1aW50NjQuICBDb25mdXNpbmdseSwgdGhpcyBtZWFucyB0aGF0IGV2ZXJ5dGhpbmcKKyAgLy8gICB3b3JrcyBpZiB3ZSBtYWtlIHRoZSBsaXRlcmFsIHVuc2lnbmVkLCBldmVuIHRob3VnaCB3ZSBhcmUgbmVnYXRpbmcgaXQuCisgIEVYUEVDVF9FUSgtR09PR0xFX1VMT05HTE9ORyg5MjIzMzcyMDM2ODU0Nzc1ODA4KSwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCgxKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSg0Mjk0OTY3Mjk1dSwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIoMCkpOworICBFWFBFQ1RfRVEoMjE0NzQ4MzY0OHUsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyKDEpKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKEdPT0dMRV9VTE9OR0xPTkcoMTg0NDY3NDQwNzM3MDk1NTE2MTUpLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NCgwKSk7CisgIEVYUEVDVF9FUShHT09HTEVfVUxPTkdMT05HKDkyMjMzNzIwMzY4NTQ3NzU4MDgpLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NCgxKSk7CisKKyAgQVNTRVJUX0VRKDEzLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMTIzLjAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoMCkpOworICBFWFBFQ1RfRVEoMTIzLjUgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoMSkpOworICBFWFBFQ1RfRVEoMC4xMjUgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoMikpOworICBFWFBFQ1RfRVEoMS4yM0UxNyAgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoMykpOworICBFWFBFQ1RfRVEoMS4yMzVFMjIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoNCkpOworICBFWFBFQ1RfRVEoMS4yMzVFLTE4ICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoNSkpOworICBFWFBFQ1RfRVEoMTIzLjQ1Njc4OSwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoNikpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoNyksIG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoOCksIG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoOSksIC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDEwKSwgLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpOworICBFWFBFQ1RfVFJVRShJc05hTihtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSgxMSkpKTsKKyAgRVhQRUNUX1RSVUUoSXNOYU4obWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoMTIpKSk7CisKKyAgLy8gTm90ZTogIFNpbmNlIHRoZXNlIHN0cmluZyBsaXRlcmFscyBoYXZlIFwwJ3MgaW4gdGhlbSwgd2UgbXVzdCBleHBsaWNpdGx5CisgIC8vICAgcGFzcyB0aGVpciBzaXplcyB0byBzdHJpbmcncyBjb25zdHJ1Y3Rvci4KKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUShzdHJpbmcoIlwwMDBcMDAxXGFcYlxmXG5cclx0XHZcXFwnXCIiLCAxMiksCisgICAgICAgICAgICBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZygwKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUHJpbnRGaWVsZHNJbkluZGV4T3JkZXIpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBtZXNzYWdlOworICAvLyBGaWVsZHMgYXJlIGxpc3RlZCBpbiBpbmRleCBvcmRlciBpbnN0ZWFkIG9mIGZpZWxkIG51bWJlci4KKyAgbWVzc2FnZS5zZXRfbXlfc3RyaW5nKCJUZXN0IFN0cmluZyIpOyAgIC8vIEZpZWxkIG51bWJlciAxMQorICBtZXNzYWdlLnNldF9teV9pbnQoMTIzNDUpOyAgICAgICAgICAgICAgLy8gRmllbGQgbnVtYmVyIDEKKyAgbWVzc2FnZS5zZXRfbXlfZmxvYXQoMC45OTkpOyAgICAgICAgICAgIC8vIEZpZWxkIG51bWJlciAxMDEKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBzdHJpbmcgdGV4dDsKKworICAvLyBCeSBkZWZhdWx0LCBwcmludCBpbiBmaWVsZCBudW1iZXIgb3JkZXIuCisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhtZXNzYWdlLCAmdGV4dCk7CisgIEVYUEVDVF9FUSgibXlfaW50OiAxMjM0NVxubXlfc3RyaW5nOiBcIlRlc3QgU3RyaW5nXCJcbm15X2Zsb2F0OiAwLjk5OVxuIiwKKyAgICAgICAgICAgIHRleHQpOworCisgIC8vIFByaW50IGluIGluZGV4IG9yZGVyLgorICBwcmludGVyLlNldFByaW50TWVzc2FnZUZpZWxkc0luSW5kZXhPcmRlcih0cnVlKTsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KTsKKyAgRVhQRUNUX0VRKCJteV9zdHJpbmc6IFwiVGVzdCBTdHJpbmdcIlxubXlfaW50OiAxMjM0NVxubXlfZmxvYXQ6IDAuOTk5XG4iLAorICAgICAgICAgICAgdGV4dCk7Cit9CisKK2NsYXNzIFRleHRGb3JtYXRQYXJzZXJUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdm9pZCBFeHBlY3RGYWlsdXJlKGNvbnN0IHN0cmluZyYgaW5wdXQsIGNvbnN0IHN0cmluZyYgbWVzc2FnZSwgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICBpbnQgY29sKSB7CisgICAgc2NvcGVkX3B0cjx1bml0dGVzdDo6VGVzdEFsbFR5cGVzPiBwcm90byhuZXcgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyk7CisgICAgRXhwZWN0RmFpbHVyZShpbnB1dCwgbWVzc2FnZSwgbGluZSwgY29sLCBwcm90by5nZXQoKSk7CisgIH0KKworICB2b2lkIEV4cGVjdEZhaWx1cmUoY29uc3Qgc3RyaW5nJiBpbnB1dCwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlLCBpbnQgbGluZSwKKyAgICAgICAgICAgICAgICAgICAgIGludCBjb2wsIE1lc3NhZ2UqIHByb3RvKSB7CisgICAgRXhwZWN0TWVzc2FnZShpbnB1dCwgbWVzc2FnZSwgbGluZSwgY29sLCBwcm90bywgZmFsc2UpOworICB9CisKKyAgdm9pZCBFeHBlY3RNZXNzYWdlKGNvbnN0IHN0cmluZyYgaW5wdXQsIGNvbnN0IHN0cmluZyYgbWVzc2FnZSwgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICBpbnQgY29sLCBNZXNzYWdlKiBwcm90bywgYm9vbCBleHBlY3RlZF9yZXN1bHQpIHsKKyAgICBUZXh0Rm9ybWF0OjpQYXJzZXIgcGFyc2VyOworICAgIE1vY2tFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgICAgcGFyc2VyLlJlY29yZEVycm9yc1RvKCZlcnJvcl9jb2xsZWN0b3IpOworICAgIEVYUEVDVF9FUShleHBlY3RlZF9yZXN1bHQsIHBhcnNlci5QYXJzZUZyb21TdHJpbmcoaW5wdXQsIHByb3RvKSkKKyAgICAgICAgPDwgaW5wdXQgPDwgIiAtPiAiIDw8IHByb3RvLT5EZWJ1Z1N0cmluZygpOworICAgIEVYUEVDVF9FUShTaW1wbGVJdG9hKGxpbmUpICsgIjoiICsgU2ltcGxlSXRvYShjb2wpICsgIjogIiArIG1lc3NhZ2UgKyAiXG4iLAorICAgICAgICAgICAgICBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworICB9CisKKyAgdm9pZCBFeHBlY3RTdWNjZXNzQW5kVHJlZShjb25zdCBzdHJpbmcmIGlucHV0LCBNZXNzYWdlKiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlKiBpbmZvX3RyZWUpIHsKKyAgICBUZXh0Rm9ybWF0OjpQYXJzZXIgcGFyc2VyOworICAgIE1vY2tFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgICAgcGFyc2VyLlJlY29yZEVycm9yc1RvKCZlcnJvcl9jb2xsZWN0b3IpOworICAgIHBhcnNlci5Xcml0ZUxvY2F0aW9uc1RvKGluZm9fdHJlZSk7CisKKyAgICBFWFBFQ1RfVFJVRShwYXJzZXIuUGFyc2VGcm9tU3RyaW5nKGlucHV0LCBwcm90bykpOworICB9CisKKyAgdm9pZCBFeHBlY3RMb2NhdGlvbihUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlKiB0cmVlLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGQsIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsIGludCBsaW5lLCBpbnQgY29sdW1uKSB7CisgICAgVGV4dEZvcm1hdDo6UGFyc2VMb2NhdGlvbiBsb2NhdGlvbiA9IHRyZWUtPkdldExvY2F0aW9uKAorICAgICAgICBkLT5GaW5kRmllbGRCeU5hbWUoZmllbGRfbmFtZSksIGluZGV4KTsKKyAgICBFWFBFQ1RfRVEobGluZSwgbG9jYXRpb24ubGluZSk7CisgICAgRVhQRUNUX0VRKGNvbHVtbiwgbG9jYXRpb24uY29sdW1uKTsKKyAgfQorCisgIC8vIEFuIGVycm9yIGNvbGxlY3RvciB3aGljaCBzaW1wbHkgY29uY2F0ZW5hdGVzIGFsbCBpdHMgZXJyb3JzIGludG8gYSBiaWcKKyAgLy8gYmxvY2sgb2YgdGV4dCB3aGljaCBjYW4gYmUgY2hlY2tlZC4KKyAgY2xhc3MgTW9ja0Vycm9yQ29sbGVjdG9yIDogcHVibGljIGlvOjpFcnJvckNvbGxlY3RvciB7CisgICBwdWJsaWM6CisgICAgTW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKyAgICB+TW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKworICAgIHN0cmluZyB0ZXh0XzsKKworICAgIC8vIGltcGxlbWVudHMgRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmdGV4dF8sICIkMDokMTogJDJcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgKyAxLCBjb2x1bW4gKyAxLCBtZXNzYWdlKTsKKyAgICB9CisKKyAgICB2b2lkIEFkZFdhcm5pbmcoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgICAgQWRkRXJyb3IobGluZSwgY29sdW1uLCAiV0FSTklORzoiICsgbWVzc2FnZSk7CisgICAgfQorICB9OworfTsKKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBQYXJzZUluZm9UcmVlQnVpbGRpbmcpIHsKKyAgc2NvcGVkX3B0cjx1bml0dGVzdDo6VGVzdEFsbFR5cGVzPiBtZXNzYWdlKG5ldyB1bml0dGVzdDo6VGVzdEFsbFR5cGVzKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKworICBzdHJpbmcgc3RyaW5nRGF0YSA9CisgICAgICAib3B0aW9uYWxfaW50MzI6IDFcbiIKKyAgICAgICJvcHRpb25hbF9pbnQ2NDogMlxuIgorICAgICAgIiAgb3B0aW9uYWxfZG91YmxlOiAyLjRcbiIKKyAgICAgICJyZXBlYXRlZF9pbnQzMjogNVxuIgorICAgICAgInJlcGVhdGVkX2ludDMyOiAxMFxuIgorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIDxcbiIKKyAgICAgICIgIGJiOiA3OFxuIgorICAgICAgIj5cbiIKKyAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8XG4iCisgICAgICAiICBiYjogNzlcbiIKKyAgICAgICI+XG4iCisgICAgICAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPFxuIgorICAgICAgIiAgYmI6IDgwXG4iCisgICAgICAiPiI7CisKKworICBUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlIHRyZWU7CisgIEV4cGVjdFN1Y2Nlc3NBbmRUcmVlKHN0cmluZ0RhdGEsIG1lc3NhZ2UuZ2V0KCksICZ0cmVlKTsKKworICAvLyBWZXJpZnkgdGhhdCB0aGUgdHJlZSBoYXMgdGhlIGNvcnJlY3QgcG9zaXRpb25zLgorICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgIm9wdGlvbmFsX2ludDMyIiwgLTEsIDAsIDApOworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgIm9wdGlvbmFsX2ludDY0IiwgLTEsIDEsIDApOworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgIm9wdGlvbmFsX2RvdWJsZSIsIC0xLCAyLCAyKTsKKworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgInJlcGVhdGVkX2ludDMyIiwgMCwgMywgMCk7CisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAicmVwZWF0ZWRfaW50MzIiLCAxLCA0LCAwKTsKKworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiwgLTEsIDUsIDApOworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIiwgMCwgOCwgMCk7CisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiLCAxLCAxMSwgMCk7CisKKyAgLy8gQ2hlY2sgZm9yIGZpZWxkcyBub3Qgc2V0LiBGb3IgYW4gaW52YWxpZCBmaWVsZCwgdGhlIGxvY2F0aW9uIHJldHVybmVkCisgIC8vIHNob3VsZCBiZSAtMSwgLTEuCisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAicmVwZWF0ZWRfaW50NjQiLCAwLCAtMSwgLTEpOworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgInJlcGVhdGVkX2ludDMyIiwgNiwgLTEsIC0xKTsKKyAgRXhwZWN0TG9jYXRpb24oJnRyZWUsIGQsICJzb21lX3Vua25vd25fZmllbGQiLCAtMSwgLTEsIC0xKTsKKworICAvLyBWZXJpZnkgaW5zaWRlIHRoZSBuZXN0ZWQgbWVzc2FnZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBuZXN0ZWRfZmllbGQgPQorICAgICAgZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworCisgIFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqIG5lc3RlZF90cmVlID0KKyAgICAgIHRyZWUuR2V0VHJlZUZvck5lc3RlZChuZXN0ZWRfZmllbGQsIC0xKTsKKyAgRXhwZWN0TG9jYXRpb24obmVzdGVkX3RyZWUsIG5lc3RlZF9maWVsZC0+bWVzc2FnZV90eXBlKCksICJiYiIsIC0xLCA2LCAyKTsKKworICAvLyBWZXJpZnkgaW5zaWRlIGFub3RoZXIgbmVzdGVkIG1lc3NhZ2UuCisgIG5lc3RlZF9maWVsZCA9IGQtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKTsKKyAgbmVzdGVkX3RyZWUgPSB0cmVlLkdldFRyZWVGb3JOZXN0ZWQobmVzdGVkX2ZpZWxkLCAwKTsKKyAgRXhwZWN0TG9jYXRpb24obmVzdGVkX3RyZWUsIG5lc3RlZF9maWVsZC0+bWVzc2FnZV90eXBlKCksICJiYiIsIC0xLCA5LCAyKTsKKworICBuZXN0ZWRfdHJlZSA9IHRyZWUuR2V0VHJlZUZvck5lc3RlZChuZXN0ZWRfZmllbGQsIDEpOworICBFeHBlY3RMb2NhdGlvbihuZXN0ZWRfdHJlZSwgbmVzdGVkX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgImJiIiwgLTEsIDEyLCAyKTsKKworICAvLyBWZXJpZnkgYSBOVUxMIHRyZWUgZm9yIGFuIHVua25vd24gbmVzdGVkIGZpZWxkLgorICBUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlKiB1bmtub3duX25lc3RlZF90cmVlID0KKyAgICAgIHRyZWUuR2V0VHJlZUZvck5lc3RlZChuZXN0ZWRfZmllbGQsIDIpOworCisgIEVYUEVDVF9FUShOVUxMLCB1bmtub3duX25lc3RlZF90cmVlKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKSB7CisgIHNjb3BlZF9wdHI8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlcz4gbWVzc2FnZShuZXcgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGQgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisKKyNkZWZpbmUgRVhQRUNUX0ZJRUxEKG5hbWUsIHZhbHVlLCB2YWx1ZXN0cmluZykgXAorICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKCBcCisgICAgdmFsdWVzdHJpbmcsIGQtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfIiAjbmFtZSksIG1lc3NhZ2UuZ2V0KCkpKTsgXAorICBFWFBFQ1RfRVEodmFsdWUsIG1lc3NhZ2UtPm9wdGlvbmFsXyMjbmFtZSgpKTsgXAorICBFWFBFQ1RfVFJVRShtZXNzYWdlLT5oYXNfb3B0aW9uYWxfIyNuYW1lKCkpOworCisjZGVmaW5lIEVYUEVDVF9CT09MX0ZJRUxEKG5hbWUsIHZhbHVlLCB2YWx1ZXN0cmluZykgXAorICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKCBcCisgICAgdmFsdWVzdHJpbmcsIGQtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfIiAjbmFtZSksIG1lc3NhZ2UuZ2V0KCkpKTsgXAorICBFWFBFQ1RfVFJVRShtZXNzYWdlLT5vcHRpb25hbF8jI25hbWUoKSA9PSB2YWx1ZSk7IFwKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS0+aGFzX29wdGlvbmFsXyMjbmFtZSgpKTsKKworI2RlZmluZSBFWFBFQ1RfRkxPQVRfRklFTEQobmFtZSwgdmFsdWUsIHZhbHVlc3RyaW5nKSBcCisgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoIFwKKyAgICB2YWx1ZXN0cmluZywgZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF8iICNuYW1lKSwgbWVzc2FnZS5nZXQoKSkpOyBcCisgIEVYUEVDVF9GTE9BVF9FUSh2YWx1ZSwgbWVzc2FnZS0+b3B0aW9uYWxfIyNuYW1lKCkpOyBcCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF8jI25hbWUoKSk7CisKKyNkZWZpbmUgRVhQRUNUX0RPVUJMRV9GSUVMRChuYW1lLCB2YWx1ZSwgdmFsdWVzdHJpbmcpIFwKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGaWVsZFZhbHVlRnJvbVN0cmluZyggXAorICAgIHZhbHVlc3RyaW5nLCBkLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsXyIgI25hbWUpLCBtZXNzYWdlLmdldCgpKSk7IFwKKyAgRVhQRUNUX0RPVUJMRV9FUSh2YWx1ZSwgbWVzc2FnZS0+b3B0aW9uYWxfIyNuYW1lKCkpOyBcCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF8jI25hbWUoKSk7CisKKyNkZWZpbmUgRVhQRUNUX0lOVkFMSUQobmFtZSwgdmFsdWVzdHJpbmcpIFwKKyAgRVhQRUNUX0ZBTFNFKFRleHRGb3JtYXQ6OlBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoIFwKKyAgICB2YWx1ZXN0cmluZywgZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF8iICNuYW1lKSwgbWVzc2FnZS5nZXQoKSkpOworCisgIC8vIGludDMyCisgIEVYUEVDVF9GSUVMRChpbnQzMiwgMSwgIjEiKTsKKyAgRVhQRUNUX0ZJRUxEKGludDMyLCAtMSwgIi0xIik7CisgIEVYUEVDVF9GSUVMRChpbnQzMiwgMHgxMjM0LCAiMHgxMjM0Iik7CisgIEVYUEVDVF9JTlZBTElEKGludDMyLCAiYSIpOworICBFWFBFQ1RfSU5WQUxJRChpbnQzMiwgIjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OSIpOworICBFWFBFQ1RfSU5WQUxJRChpbnQzMiwgIjEsMiIpOworCisgIC8vIGludDY0CisgIEVYUEVDVF9GSUVMRChpbnQ2NCwgMSwgIjEiKTsKKyAgRVhQRUNUX0ZJRUxEKGludDY0LCAtMSwgIi0xIik7CisgIEVYUEVDVF9GSUVMRChpbnQ2NCwgMHgxMjM0NTY3ODEyMzQ1Njc4TEwsICIweDEyMzQ1Njc4MTIzNDU2NzgiKTsKKyAgRVhQRUNUX0lOVkFMSUQoaW50NjQsICJhIik7CisgIEVYUEVDVF9JTlZBTElEKGludDY0LCAiOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5Iik7CisgIEVYUEVDVF9JTlZBTElEKGludDY0LCAiMSwyIik7CisKKyAgLy8gdWludDY0CisgIEVYUEVDVF9GSUVMRCh1aW50NjQsIDEsICIxIik7CisgIEVYUEVDVF9GSUVMRCh1aW50NjQsIDB4ZjIzNDU2NzgxMjM0NTY3OFVMTCwgIjB4ZjIzNDU2NzgxMjM0NTY3OCIpOworICBFWFBFQ1RfSU5WQUxJRCh1aW50NjQsICItMSIpOworICBFWFBFQ1RfSU5WQUxJRCh1aW50NjQsICJhIik7CisgIEVYUEVDVF9JTlZBTElEKHVpbnQ2NCwgIjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OSIpOworICBFWFBFQ1RfSU5WQUxJRCh1aW50NjQsICIxLDIiKTsKKworICAvLyBmaXhlZDMyCisgIEVYUEVDVF9GSUVMRChmaXhlZDMyLCAxLCAiMSIpOworICBFWFBFQ1RfRklFTEQoZml4ZWQzMiwgMHgxMjM0NTY3OCwgIjB4MTIzNDU2NzgiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQzMiwgIi0xIik7CisgIEVYUEVDVF9JTlZBTElEKGZpeGVkMzIsICJhIik7CisgIEVYUEVDVF9JTlZBTElEKGZpeGVkMzIsICI5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTkiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQzMiwgIjEsMiIpOworCisgIC8vIGZpeGVkNjQKKyAgRVhQRUNUX0ZJRUxEKGZpeGVkNjQsIDEsICIxIik7CisgIEVYUEVDVF9GSUVMRChmaXhlZDY0LCAweDEyMzQ1Njc4MTIzNDU2NzhVTEwsICIweDEyMzQ1Njc4MTIzNDU2NzgiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQ2NCwgIi0xIik7CisgIEVYUEVDVF9JTlZBTElEKGZpeGVkNjQsICJhIik7CisgIEVYUEVDVF9JTlZBTElEKGZpeGVkNjQsICI5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTkiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQ2NCwgIjEsMiIpOworCisgIC8vIGJvb2wKKyAgRVhQRUNUX0JPT0xfRklFTEQoYm9vbCwgdHJ1ZSwgInRydWUiKTsKKyAgRVhQRUNUX0JPT0xfRklFTEQoYm9vbCwgZmFsc2UsICJmYWxzZSIpOworICBFWFBFQ1RfQk9PTF9GSUVMRChib29sLCB0cnVlLCAiMSIpOworICBFWFBFQ1RfQk9PTF9GSUVMRChib29sLCB0cnVlLCAidCIpOworICBFWFBFQ1RfQk9PTF9GSUVMRChib29sLCBmYWxzZSwgIjAiKTsKKyAgRVhQRUNUX0JPT0xfRklFTEQoYm9vbCwgZmFsc2UsICJmIik7CisgIEVYUEVDVF9GSUVMRChib29sLCB0cnVlLCAiVHJ1ZSIpOworICBFWFBFQ1RfRklFTEQoYm9vbCwgZmFsc2UsICJGYWxzZSIpOworICBFWFBFQ1RfSU5WQUxJRChib29sLCAidFJ1ZSIpOworICBFWFBFQ1RfSU5WQUxJRChib29sLCAiZmFMc2UiKTsKKyAgRVhQRUNUX0lOVkFMSUQoYm9vbCwgIjIiKTsKKyAgRVhQRUNUX0lOVkFMSUQoYm9vbCwgIi0wIik7CisgIEVYUEVDVF9JTlZBTElEKGJvb2wsICJvbiIpOworICBFWFBFQ1RfSU5WQUxJRChib29sLCAiYSIpOworCisgIC8vIGZsb2F0CisgIEVYUEVDVF9GSUVMRChmbG9hdCwgMSwgIjEiKTsKKyAgRVhQRUNUX0ZMT0FUX0ZJRUxEKGZsb2F0LCAxLjUsICIxLjUiKTsKKyAgRVhQRUNUX0ZMT0FUX0ZJRUxEKGZsb2F0LCAxLjVlMywgIjEuNWUzIik7CisgIEVYUEVDVF9GTE9BVF9GSUVMRChmbG9hdCwgLTQuNTUsICItNC41NSIpOworICBFWFBFQ1RfSU5WQUxJRChmbG9hdCwgImEiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZmxvYXQsICIxLDIiKTsKKworICAvLyBkb3VibGUKKyAgRVhQRUNUX0ZJRUxEKGRvdWJsZSwgMSwgIjEiKTsKKyAgRVhQRUNUX0ZJRUxEKGRvdWJsZSwgLTEsICItMSIpOworICBFWFBFQ1RfRE9VQkxFX0ZJRUxEKGRvdWJsZSwgMi4zLCAiMi4zIik7CisgIEVYUEVDVF9ET1VCTEVfRklFTEQoZG91YmxlLCAzZTUsICIzZTUiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZG91YmxlLCAiYSIpOworICBFWFBFQ1RfSU5WQUxJRChkb3VibGUsICIxLDIiKTsKKyAgLy8gUmVqZWN0cyBoZXggYW5kIG9jdCBudW1iZXJzIGZvciBhIGRvdWJsZSBmaWVsZC4KKyAgRVhQRUNUX0lOVkFMSUQoZG91YmxlLCAiMHhmIik7CisgIEVYUEVDVF9JTlZBTElEKGRvdWJsZSwgIjAxMiIpOworCisgIC8vIHN0cmluZworICBFWFBFQ1RfRklFTEQoc3RyaW5nLCAiaGVsbG8iLCAiXCJoZWxsb1wiIik7CisgIEVYUEVDVF9GSUVMRChzdHJpbmcsICItMS44NyIsICInLTEuODcnIik7CisgIEVYUEVDVF9JTlZBTElEKHN0cmluZywgImhlbGxvIik7ICAvLyB3aXRob3V0IHF1b3RlIGZvciB2YWx1ZQorCisgIC8vIGVudW0KKyAgRVhQRUNUX0ZJRUxEKG5lc3RlZF9lbnVtLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsICJCQVIiKTsKKyAgRVhQRUNUX0ZJRUxEKG5lc3RlZF9lbnVtLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosCisgICAgICAgICAgICAgICBTaW1wbGVJdG9hKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWikpOworICBFWFBFQ1RfSU5WQUxJRChuZXN0ZWRfZW51bSwgIkZPT0JBUiIpOworCisgIC8vIG1lc3NhZ2UKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGaWVsZFZhbHVlRnJvbVN0cmluZygKKyAgICAiPGJiOjEyPiIsIGQtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSwgbWVzc2FnZS5nZXQoKSkpOworICBFWFBFQ1RfRVEoMTIsIG1lc3NhZ2UtPm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7IFwKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS0+aGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfSU5WQUxJRChuZXN0ZWRfbWVzc2FnZSwgImFueSIpOworCisjdW5kZWYgRVhQRUNUX0ZJRUxECisjdW5kZWYgRVhQRUNUX0JPT0xfRklFTEQKKyN1bmRlZiBFWFBFQ1RfRkxPQVRfRklFTEQKKyN1bmRlZiBFWFBFQ1RfRE9VQkxFX0ZJRUxECisjdW5kZWYgRVhQRUNUX0lOVkFMSUQKK30KKworCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIEludmFsaWRUb2tlbikgeworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9ib29sOiB0cnVlXG4tNVxuIiwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIiwKKyAgICAgICAgICAgICAgICAyLCAxKTsKKworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9ib29sOiB0cnVlIVxuIiwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIiwgMSwgMjApOworICBFeHBlY3RGYWlsdXJlKCJcInNvbWUgc3RyaW5nXCIiLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iLCAxLCAxKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBJbnZhbGlkRmllbGROYW1lKSB7CisgIEV4cGVjdEZhaWx1cmUoCisgICAgICAiaW52YWxpZF9maWVsZDogc29tZXZhbHVlXG4iLAorICAgICAgIk1lc3NhZ2UgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiIGhhcyBubyBmaWVsZCBuYW1lZCAiCisgICAgICAiXCJpbnZhbGlkX2ZpZWxkXCIuIiwKKyAgICAgIDEsIDE0KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBJbnZhbGlkQ2FwaXRhbGl6YXRpb24pIHsKKyAgLy8gV2UgcmVxdWlyZSB0aGF0IGdyb3VwIG5hbWVzIGJlIGV4YWN0bHkgYXMgdGhleSBhcHBlYXIgaW4gdGhlIC5wcm90by4KKyAgRXhwZWN0RmFpbHVyZSgKKyAgICAgICJvcHRpb25hbGdyb3VwIHtcbmE6IDE1XG59XG4iLAorICAgICAgIk1lc3NhZ2UgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiIGhhcyBubyBmaWVsZCBuYW1lZCAiCisgICAgICAiXCJvcHRpb25hbGdyb3VwXCIuIiwKKyAgICAgIDEsIDE1KTsKKyAgRXhwZWN0RmFpbHVyZSgKKyAgICAgICJPUFRJT05BTGdyb3VwIHtcbmE6IDE1XG59XG4iLAorICAgICAgIk1lc3NhZ2UgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiIGhhcyBubyBmaWVsZCBuYW1lZCAiCisgICAgICAiXCJPUFRJT05BTGdyb3VwXCIuIiwKKyAgICAgIDEsIDE1KTsKKyAgRXhwZWN0RmFpbHVyZSgKKyAgICAgICJPcHRpb25hbF9Eb3VibGU6IDEwLjBcbiIsCisgICAgICAiTWVzc2FnZSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIgaGFzIG5vIGZpZWxkIG5hbWVkICIKKyAgICAgICJcIk9wdGlvbmFsX0RvdWJsZVwiLiIsCisgICAgICAxLCAxNik7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgQWxsb3dJZ25vcmVDYXBpdGFsaXphdGlvbkVycm9yKSB7CisgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgcHJvdG87CisKKyAgLy8gVGhlc2UgZmllbGRzIGhhdmUgYSBtaXNtYXRjaGluZyBjYXNlLgorICBFWFBFQ1RfRkFMU0UocGFyc2VyLlBhcnNlRnJvbVN0cmluZygiT3B0aW9uYWxfRG91YmxlOiAxMC4wIiwgJnByb3RvKSk7CisgIEVYUEVDVF9GQUxTRShwYXJzZXIuUGFyc2VGcm9tU3RyaW5nKCJvUHRJb05hTGdSb1VwIHsgYTogMTUgfSIsICZwcm90bykpOworCisgIC8vIC4uLiBidXQgYXJlIHBhcnNlZCBjb3JyZWN0bHkgaWYgd2UgbWF0Y2ggY2FzZSBpbnNlbnNpdGl2ZS4KKyAgcGFyc2VyLkFsbG93Q2FzZUluc2Vuc2l0aXZlRmllbGQodHJ1ZSk7CisgIEVYUEVDVF9UUlVFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcoIk9wdGlvbmFsX0RvdWJsZTogMTAuMCIsICZwcm90bykpOworICBFWFBFQ1RfRVEoMTAuMCwgcHJvdG8ub3B0aW9uYWxfZG91YmxlKCkpOworICBFWFBFQ1RfVFJVRShwYXJzZXIuUGFyc2VGcm9tU3RyaW5nKCJvUHRJb05hTGdSb1VwIHsgYTogMTUgfSIsICZwcm90bykpOworICBFWFBFQ1RfRVEoMTUsIHByb3RvLm9wdGlvbmFsZ3JvdXAoKS5hKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIEludmFsaWRGaWVsZFZhbHVlcykgeworICAvLyBJbnZhbGlkIHZhbHVlcyBmb3IgYSBkb3VibGUvZmxvYXQgZmllbGQuCisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2RvdWJsZTogXCJoZWxsb1wiXG4iLCAiRXhwZWN0ZWQgZG91YmxlLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfZG91YmxlOiB0cnVlXG4iLCAiRXhwZWN0ZWQgZG91YmxlLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfZG91YmxlOiAhXG4iLCAiRXhwZWN0ZWQgZG91YmxlLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfZG91YmxlIHtcbiAgXG59XG4iLCAiRXhwZWN0ZWQgXCI6XCIsIGZvdW5kIFwie1wiLiIsCisgICAgICAgICAgICAgICAgMSwgMTcpOworCisgIC8vIEludmFsaWQgdmFsdWVzIGZvciBhIHNpZ25lZCBpbnRlZ2VyIGZpZWxkLgorICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQzMjogXCJoZWxsb1wiXG4iLCAiRXhwZWN0ZWQgaW50ZWdlci4iLCAxLCAxNyk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2ludDMyOiB0cnVlXG4iLCAiRXhwZWN0ZWQgaW50ZWdlci4iLCAxLCAxNyk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2ludDMyOiA0LjVcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE3KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50MzI6ICFcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE3KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50MzIge1xuIFxufVxuIiwgIkV4cGVjdGVkIFwiOlwiLCBmb3VuZCBcIntcIi4iLAorICAgICAgICAgICAgICAgIDEsIDE2KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50MzI6IDB4ODAwMDAwMDBcbiIsCisgICAgICAgICAgICAgICAgIkludGVnZXIgb3V0IG9mIHJhbmdlLiIsIDEsIDE3KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50NjQ6IDB4ODAwMDAwMDAwMDAwMDAwMFxuIiwKKyAgICAgICAgICAgICAgICAiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIiwgMSwgMTcpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQzMjogLTB4ODAwMDAwMDFcbiIsCisgICAgICAgICAgICAgICAgIkludGVnZXIgb3V0IG9mIHJhbmdlLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50NjQ6IC0weDgwMDAwMDAwMDAwMDAwMDFcbiIsCisgICAgICAgICAgICAgICAgIkludGVnZXIgb3V0IG9mIHJhbmdlLiIsIDEsIDE4KTsKKworICAvLyBJbnZhbGlkIHZhbHVlcyBmb3IgYW4gdW5zaWduZWQgaW50ZWdlciBmaWVsZC4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0OiBcImhlbGxvXCJcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0OiB0cnVlXG4iLCAiRXhwZWN0ZWQgaW50ZWdlci4iLCAxLCAxOCk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX3VpbnQ2NDogNC41XG4iLCAiRXhwZWN0ZWQgaW50ZWdlci4iLCAxLCAxOCk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX3VpbnQ2NDogLTVcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0OiAhXG4iLCAiRXhwZWN0ZWQgaW50ZWdlci4iLCAxLCAxOCk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX3VpbnQ2NCB7XG4gXG59XG4iLCAiRXhwZWN0ZWQgXCI6XCIsIGZvdW5kIFwie1wiLiIsCisgICAgICAgICAgICAgICAgMSwgMTcpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF91aW50MzI6IDB4MTAwMDAwMDAwXG4iLAorICAgICAgICAgICAgICAgICJJbnRlZ2VyIG91dCBvZiByYW5nZS4iLCAxLCAxOCk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX3VpbnQ2NDogMHgxMDAwMDAwMDAwMDAwMDAwMFxuIiwKKyAgICAgICAgICAgICAgICAiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIiwgMSwgMTgpOworCisgIC8vIEludmFsaWQgdmFsdWVzIGZvciBhIGJvb2xlYW4gZmllbGQuCisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2Jvb2w6IFwiaGVsbG9cIlxuIiwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIiwgMSwgMTYpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9ib29sOiA1XG4iLCAiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIiwgMSwgMTYpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9ib29sOiAtNy41XG4iLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iLCAxLCAxNik7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2Jvb2w6ICFcbiIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIsIDEsIDE2KTsKKworICBFeHBlY3RGYWlsdXJlKAorICAgICAgIm9wdGlvbmFsX2Jvb2w6IG1laFxuIiwKKyAgICAgICJJbnZhbGlkIHZhbHVlIGZvciBib29sZWFuIGZpZWxkIFwib3B0aW9uYWxfYm9vbFwiLiBWYWx1ZTogXCJtZWhcIi4iLAorICAgICAgMiwgMSk7CisKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfYm9vbCB7XG4gXG59XG4iLCAiRXhwZWN0ZWQgXCI6XCIsIGZvdW5kIFwie1wiLiIsCisgICAgICAgICAgICAgICAgMSwgMTUpOworCisgIC8vIEludmFsaWQgdmFsdWVzIGZvciBhIHN0cmluZyBmaWVsZC4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfc3RyaW5nOiB0cnVlXG4iLCAiRXhwZWN0ZWQgc3RyaW5nLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfc3RyaW5nOiA1XG4iLCAiRXhwZWN0ZWQgc3RyaW5nLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfc3RyaW5nOiAtNy41XG4iLCAiRXhwZWN0ZWQgc3RyaW5nLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfc3RyaW5nOiAhXG4iLCAiRXhwZWN0ZWQgc3RyaW5nLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfc3RyaW5nIHtcbiBcbn1cbiIsICJFeHBlY3RlZCBcIjpcIiwgZm91bmQgXCJ7XCIuIiwKKyAgICAgICAgICAgICAgICAxLCAxNyk7CisKKyAgLy8gSW52YWxpZCB2YWx1ZXMgZm9yIGFuIGVudW1lcmF0aW9uIGZpZWxkLgorICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9uZXN0ZWRfZW51bTogXCJoZWxsb1wiXG4iLAorICAgICAgICAgICAgICAgICJFeHBlY3RlZCBpbnRlZ2VyIG9yIGlkZW50aWZpZXIuIiwgMSwgMjMpOworCisgIC8vIFZhbGlkIHRva2VuLCBidXQgZW51bSB2YWx1ZSBpcyBub3QgZGVmaW5lZC4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfbmVzdGVkX2VudW06IDVcbiIsCisgICAgICAgICAgICAgICAgIlVua25vd24gZW51bWVyYXRpb24gdmFsdWUgb2YgXCI1XCIgZm9yIGZpZWxkICIKKyAgICAgICAgICAgICAgICAiXCJvcHRpb25hbF9uZXN0ZWRfZW51bVwiLiIsIDIsIDEpOworICAvLyBXZSBjb25zdW1lIHRoZSBuZWdhdGl2ZSBzaWduLCBzbyB0aGUgZXJyb3IgcG9zaXRpb24gc3RhcnRzIG9uZSBjaGFyYWN0ZXIKKyAgLy8gbGF0ZXIuCisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX25lc3RlZF9lbnVtOiAtNy41XG4iLCAiRXhwZWN0ZWQgaW50ZWdlci4iLCAxLCAyNCk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX25lc3RlZF9lbnVtOiAhXG4iLAorICAgICAgICAgICAgICAgICJFeHBlY3RlZCBpbnRlZ2VyIG9yIGlkZW50aWZpZXIuIiwgMSwgMjMpOworCisgIEV4cGVjdEZhaWx1cmUoCisgICAgICAib3B0aW9uYWxfbmVzdGVkX2VudW06IGdyYWhcbiIsCisgICAgICAiVW5rbm93biBlbnVtZXJhdGlvbiB2YWx1ZSBvZiBcImdyYWhcIiBmb3IgZmllbGQgIgorICAgICAgIlwib3B0aW9uYWxfbmVzdGVkX2VudW1cIi4iLCAyLCAxKTsKKworICBFeHBlY3RGYWlsdXJlKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9lbnVtIHtcbiBcbn1cbiIsCisgICAgICAiRXhwZWN0ZWQgXCI6XCIsIGZvdW5kIFwie1wiLiIsIDEsIDIyKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBNZXNzYWdlRGVsaW1pdGVycykgeworICAvLyBOb24tbWF0Y2hpbmcgZGVsaW1pdGVycy4KKyAgRXhwZWN0RmFpbHVyZSgiT3B0aW9uYWxHcm91cCA8XG4gXG59XG4iLCAiRXhwZWN0ZWQgXCI+XCIsIGZvdW5kIFwifVwiLiIsCisgICAgICAgICAgICAgICAgMywgMSk7CisKKyAgLy8gSW52YWxpZCBkZWxpbWl0ZXJzLgorICBFeHBlY3RGYWlsdXJlKCJPcHRpb25hbEdyb3VwIFtcbiBcbl1cbiIsICJFeHBlY3RlZCBcIntcIiwgZm91bmQgXCJbXCIuIiwKKyAgICAgICAgICAgICAgICAxLCAxNSk7CisKKyAgLy8gVW5lbmRpbmcgbWVzc2FnZS4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2Uge1xuIFxuYmI6IDExOFxuIiwKKyAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgaWRlbnRpZmllci4iLAorICAgICAgICAgICAgICAgIDQsIDEpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIFVua25vd25FeHRlbnNpb24pIHsKKyAgLy8gTm9uLW1hdGNoaW5nIGRlbGltaXRlcnMuCisgIEV4cGVjdEZhaWx1cmUoIltibGFoYmxhaF06IDEyMyIsCisgICAgICAgICAgICAgICAgIkV4dGVuc2lvbiBcImJsYWhibGFoXCIgaXMgbm90IGRlZmluZWQgb3IgaXMgbm90IGFuICIKKyAgICAgICAgICAgICAgICAiZXh0ZW5zaW9uIG9mIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIuIiwKKyAgICAgICAgICAgICAgICAxLCAxMSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgTWlzc2luZ1JlcXVpcmVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgRXhwZWN0RmFpbHVyZSgiYTogMSIsCisgICAgICAgICAgICAgICAgIk1lc3NhZ2UgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6IGIsIGMiLAorICAgICAgICAgICAgICAgIDAsIDEsICZtZXNzYWdlKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBQYXJzZUR1cGxpY2F0ZVJlcXVpcmVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgRXhwZWN0RmFpbHVyZSgiYTogMSBiOiAyIGM6IDMgYTogMSIsCisgICAgICAgICAgICAgICAgIk5vbi1yZXBlYXRlZCBmaWVsZCBcImFcIiBpcyBzcGVjaWZpZWQgbXVsdGlwbGUgdGltZXMuIiwKKyAgICAgICAgICAgICAgICAxLCAxNywgJm1lc3NhZ2UpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIFBhcnNlRHVwbGljYXRlT3B0aW9uYWwpIHsKKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2U7CisgIEV4cGVjdEZhaWx1cmUoImM6IDEgYzogMiIsCisgICAgICAgICAgICAgICAgIk5vbi1yZXBlYXRlZCBmaWVsZCBcImNcIiBpcyBzcGVjaWZpZWQgbXVsdGlwbGUgdGltZXMuIiwKKyAgICAgICAgICAgICAgICAxLCA3LCAmbWVzc2FnZSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgTWVyZ2VEdXBsaWNhdGVSZXF1aXJlZCkgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisgIEVYUEVDVF9UUlVFKHBhcnNlci5NZXJnZUZyb21TdHJpbmcoImE6IDEgYjogMiBjOiAzIGE6IDQiLCAmbWVzc2FnZSkpOworICBFWFBFQ1RfRVEoNCwgbWVzc2FnZS5hKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIE1lcmdlRHVwbGljYXRlT3B0aW9uYWwpIHsKKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2U7CisgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisgIEVYUEVDVF9UUlVFKHBhcnNlci5NZXJnZUZyb21TdHJpbmcoImM6IDEgYzogMiIsICZtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLmMoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgRXhwbGljaXREZWxpbWl0ZXJzKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKCJhOjEsYjoyO2M6MyIsICZtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLmEoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLmIoKSk7CisgIEVYUEVDVF9FUSgzLCBtZXNzYWdlLmMoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgUHJpbnRFcnJvcnNUb1N0ZGVycikgeworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBwcm90bzsKKyAgICBFWFBFQ1RfRkFMU0UoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKCJub19zdWNoX2ZpZWxkOiAxIiwgJnByb3RvKSk7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorCisgIEFTU0VSVF9FUSgxLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJFcnJvciBwYXJzaW5nIHRleHQtZm9ybWF0IHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlczogIgorICAgICAgICAgICAgIjE6MTQ6IE1lc3NhZ2UgdHlwZSBcInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiIGhhcyBubyBmaWVsZCAiCisgICAgICAgICAgICAibmFtZWQgXCJub19zdWNoX2ZpZWxkXCIuIiwKKyAgICAgICAgICAgIGVycm9yc1swXSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgRmFpbHNPblRva2VuaXphdGlvbkVycm9yKSB7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHByb3RvOworICAgIEVYUEVDVF9GQUxTRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoIlwwMjAiLCAmcHJvdG8pKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgQVNTRVJUX0VRKDEsIGVycm9ycy5zaXplKCkpOworICBFWFBFQ1RfRVEoIkVycm9yIHBhcnNpbmcgdGV4dC1mb3JtYXQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzOiAiCisgICAgICAgICAgICAiMToxOiBJbnZhbGlkIGNvbnRyb2wgY2hhcmFjdGVycyBlbmNvdW50ZXJlZCBpbiB0ZXh0LiIsCisgICAgICAgICAgICBlcnJvcnNbMF0pOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIFBhcnNlRGVwcmVjYXRlZEZpZWxkKSB7CisgIHVuaXR0ZXN0OjpUZXN0RGVwcmVjYXRlZEZpZWxkcyBtZXNzYWdlOworICBFeHBlY3RNZXNzYWdlKCJkZXByZWNhdGVkX2ludDMyOiA0MiIsCisgICAgICAgICAgICAgICAgIldBUk5JTkc6dGV4dCBmb3JtYXQgY29udGFpbnMgZGVwcmVjYXRlZCBmaWVsZCAiCisgICAgICAgICAgICAgICAgIlwiZGVwcmVjYXRlZF9pbnQzMlwiIiwgMSwgMjEsICZtZXNzYWdlLCB0cnVlKTsKK30KKworY2xhc3MgVGV4dEZvcm1hdE1lc3NhZ2VTZXRUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgc3RhdGljIGNvbnN0IGNoYXIgcHJvdG9fZGVidWdfc3RyaW5nX1tdOworfTsKK2NvbnN0IGNoYXIgVGV4dEZvcm1hdE1lc3NhZ2VTZXRUZXN0Ojpwcm90b19kZWJ1Z19zdHJpbmdfW10gPQorIm1lc3NhZ2Vfc2V0IHtcbiIKKyIgIFtwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjFdIHtcbiIKKyIgICAgaTogMjNcbiIKKyIgIH1cbiIKKyIgIFtwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjJdIHtcbiIKKyIgICAgc3RyOiBcImZvb1wiXG4iCisiICB9XG4iCisifVxuIjsKKworCitURVNUX0YoVGV4dEZvcm1hdE1lc3NhZ2VTZXRUZXN0LCBTZXJpYWxpemUpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHByb3RvOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xKiBpdGVtX2EgPQorICAgIHByb3RvLm11dGFibGVfbWVzc2FnZV9zZXQoKS0+TXV0YWJsZUV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbik7CisgIGl0ZW1fYS0+c2V0X2koMjMpOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yKiBpdGVtX2IgPQorICAgIHByb3RvLm11dGFibGVfbWVzc2FnZV9zZXQoKS0+TXV0YWJsZUV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbik7CisgIGl0ZW1fYi0+c2V0X3N0cigiZm9vIik7CisgIEVYUEVDVF9FUShwcm90b19kZWJ1Z19zdHJpbmdfLCBwcm90by5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRNZXNzYWdlU2V0VGVzdCwgRGVzZXJpYWxpemUpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHByb3RvOworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcocHJvdG9fZGVidWdfc3RyaW5nXywgJnByb3RvKSk7CisgIEVYUEVDVF9FUSgyMywgcHJvdG8ubWVzc2FnZV9zZXQoKS5HZXRFeHRlbnNpb24oCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS5pKCkpOworICBFWFBFQ1RfRVEoImZvbyIsIHByb3RvLm1lc3NhZ2Vfc2V0KCkuR2V0RXh0ZW5zaW9uKAorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbikuc3RyKCkpOworCisgIC8vIEVuc3VyZSB0aGF0IHRoZXNlIGFyZSB0aGUgb25seSBlbnRyaWVzIHByZXNlbnQuCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBkZXNjcmlwdG9yczsKKyAgcHJvdG8ubWVzc2FnZV9zZXQoKS5HZXRSZWZsZWN0aW9uKCktPkxpc3RGaWVsZHMoCisgICAgcHJvdG8ubWVzc2FnZV9zZXQoKSwgJmRlc2NyaXB0b3JzKTsKKyAgRVhQRUNUX0VRKDIsIGRlc2NyaXB0b3JzLnNpemUoKSk7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlIHRleHRfZm9ybWF0X3VuaXR0ZXN0Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWM4ZTAwOWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90bwpAQCAtMCwwICsxLDEwMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiVGltZXN0YW1wUHJvdG8iOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKKworCisvLyBBIFRpbWVzdGFtcCByZXByZXNlbnRzIGEgcG9pbnQgaW4gdGltZSBpbmRlcGVuZGVudCBvZiBhbnkgdGltZSB6b25lCisvLyBvciBjYWxlbmRhciwgcmVwcmVzZW50ZWQgYXMgc2Vjb25kcyBhbmQgZnJhY3Rpb25zIG9mIHNlY29uZHMgYXQKKy8vIG5hbm9zZWNvbmQgcmVzb2x1dGlvbiBpbiBVVEMgRXBvY2ggdGltZS4gSXQgaXMgZW5jb2RlZCB1c2luZyB0aGUKKy8vIFByb2xlcHRpYyBHcmVnb3JpYW4gQ2FsZW5kYXIgd2hpY2ggZXh0ZW5kcyB0aGUgR3JlZ29yaWFuIGNhbGVuZGFyCisvLyBiYWNrd2FyZHMgdG8geWVhciBvbmUuIEl0IGlzIGVuY29kZWQgYXNzdW1pbmcgYWxsIG1pbnV0ZXMgYXJlIDYwCisvLyBzZWNvbmRzIGxvbmcsIGkuZS4gbGVhcCBzZWNvbmRzIGFyZSAic21lYXJlZCIgc28gdGhhdCBubyBsZWFwIHNlY29uZAorLy8gdGFibGUgaXMgbmVlZGVkIGZvciBpbnRlcnByZXRhdGlvbi4gUmFuZ2UgaXMgZnJvbQorLy8gMDAwMS0wMS0wMVQwMDowMDowMFogdG8gOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5OTlaLgorLy8gQnkgcmVzdHJpY3RpbmcgdG8gdGhhdCByYW5nZSwgd2UgZW5zdXJlIHRoYXQgd2UgY2FuIGNvbnZlcnQgdG8KKy8vIGFuZCBmcm9tICBSRkMgMzMzOSBkYXRlIHN0cmluZ3MuIChTZWUgaHR0cHM6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMzMzkudHh0LikKKy8vCisvLyBFeGFtcGxlIDE6IGNvbXB1dGUgVGltZXN0YW1wIGZyb20gUE9TSVggYHRpbWUoKWAuCisvLworLy8gICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CisvLyAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKHRpbWUoTlVMTCkpOworLy8gICAgIHRpbWVzdGFtcC5zZXRfbmFub3MoMCk7CisvLworLy8gRXhhbXBsZSAyOiBjb21wdXRlIFRpbWVzdGFtcCBmcm9tIFBPU0lYIGBnZXR0aW1lb2ZkYXkoKWAuCisvLworLy8gICAgIHN0cnVjdCB0aW1ldmFsIHR2OworLy8gICAgIGdldHRpbWVvZmRheSgmdHYsIE5VTEwpOworLy8KKy8vICAgICBUaW1lc3RhbXAgdGltZXN0YW1wOworLy8gICAgIHRpbWVzdGFtcC5zZXRfc2Vjb25kcyh0di50dl9zZWMpOworLy8gICAgIHRpbWVzdGFtcC5zZXRfbmFub3ModHYudHZfdXNlYyAqIDEwMDApOworLy8KKy8vIEV4YW1wbGUgMzogY29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBXaW4zMiBgR2V0U3lzdGVtVGltZUFzRmlsZVRpbWUoKWAuCisvLworLy8gICAgIEZJTEVUSU1FIGZ0OworLy8gICAgIEdldFN5c3RlbVRpbWVBc0ZpbGVUaW1lKCZmdCk7CisvLyAgICAgVUlOVDY0IHRpY2tzID0gKCgoVUlOVDY0KWZ0LmR3SGlnaERhdGVUaW1lKSA8PCAzMikgfCBmdC5kd0xvd0RhdGVUaW1lOworLy8KKy8vICAgICAvLyBBIFdpbmRvd3MgdGljayBpcyAxMDAgbmFub3NlY29uZHMuIFdpbmRvd3MgZXBvY2ggMTYwMS0wMS0wMVQwMDowMDowMFoKKy8vICAgICAvLyBpcyAxMTY0NDQ3MzYwMCBzZWNvbmRzIGJlZm9yZSBVbml4IGVwb2NoIDE5NzAtMDEtMDFUMDA6MDA6MDBaLgorLy8gICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CisvLyAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKChJTlQ2NCkgKCh0aWNrcyAvIDEwMDAwMDAwKSAtIDExNjQ0NDczNjAwTEwpKTsKKy8vICAgICB0aW1lc3RhbXAuc2V0X25hbm9zKChJTlQzMikgKCh0aWNrcyAlIDEwMDAwMDAwKSAqIDEwMCkpOworLy8KKy8vIEV4YW1wbGUgNDogY29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBKYXZhIGBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKWAuCisvLworLy8gICAgIGxvbmcgbWlsbGlzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisvLworLy8gICAgIFRpbWVzdGFtcCB0aW1lc3RhbXAgPSBUaW1lc3RhbXAubmV3QnVpbGRlcigpLnNldFNlY29uZHMobWlsbGlzIC8gMTAwMCkKKy8vICAgICAgICAgLnNldE5hbm9zKChpbnQpICgobWlsbGlzICUgMTAwMCkgKiAxMDAwMDAwKSkuYnVpbGQoKTsKKy8vCisvLyBFeGFtcGxlIDU6IGNvbXB1dGUgVGltZXN0YW1wIGZyb20gUHl0aG9uIGBkYXRldGltZS5kYXRldGltZWAuCisvLworLy8gICAgIG5vdyA9IGRhdGV0aW1lLmRhdGV0aW1lLnV0Y25vdygpCisvLyAgICAgc2Vjb25kcyA9IGludCh0aW1lLm1rdGltZShub3cudGltZXR1cGxlKCkpKQorLy8gICAgIG5hbm9zID0gbm93Lm1pY3Jvc2Vjb25kICogMTAwMAorLy8gICAgIHRpbWVzdGFtcCA9IFRpbWVzdGFtcChzZWNvbmRzPXNlY29uZHMsIG5hbm9zPW5hbm9zKQorLy8KK21lc3NhZ2UgVGltZXN0YW1wIHsKKyAgLy8gUmVwcmVzZW50cyBzZWNvbmRzIG9mIFVUQyB0aW1lIHNpbmNlIFVuaXggZXBvY2gKKyAgLy8gMTk3MC0wMS0wMVQwMDowMDowMFouIE11c3QgYmUgZnJvbSBmcm9tIDAwMDEtMDEtMDFUMDA6MDA6MDBaIHRvCisgIC8vIDk5OTktMTItMzFUMjM6NTk6NTlaIGluY2x1c2l2ZS4KKyAgaW50NjQgc2Vjb25kcyA9IDE7CisKKyAgLy8gTm9uLW5lZ2F0aXZlIGZyYWN0aW9ucyBvZiBhIHNlY29uZCBhdCBuYW5vc2Vjb25kIHJlc29sdXRpb24uIE5lZ2F0aXZlCisgIC8vIHNlY29uZCB2YWx1ZXMgd2l0aCBmcmFjdGlvbnMgbXVzdCBzdGlsbCBoYXZlIG5vbi1uZWdhdGl2ZSBuYW5vcyB2YWx1ZXMKKyAgLy8gdGhhdCBjb3VudCBmb3J3YXJkIGluIHRpbWUuIE11c3QgYmUgZnJvbSAwIHRvIDk5OSw5OTksOTk5CisgIC8vIGluY2x1c2l2ZS4KKyAgaW50MzIgbmFub3MgPSAyOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzQ1Zjc3YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8KQEAgLTAsMCArMSw4NzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBBIHByb3RvIGZpbGUgd2Ugd2lsbCB1c2UgZm9yIHVuaXQgdGVzdGluZy4KKworc3ludGF4ID0gInByb3RvMiI7CisKKy8vIFNvbWUgZ2VuZXJpY19zZXJ2aWNlcyBvcHRpb24ocykgYWRkZWQgYXV0b21hdGljYWxseS4KKy8vIFNlZTogIGh0dHA6Ly9nby9wcm90bzItZ2VuZXJpYy1zZXJ2aWNlcy1kZWZhdWx0CitvcHRpb24gY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gamF2YV9nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90byI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorLy8gSW4gdGVzdF91dGlsLmggd2UgZG8gInVzaW5nIG5hbWVzcGFjZSB1bml0dGVzdCA9IHByb3RvYnVmX3VuaXR0ZXN0Ii4KK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKy8vIFByb3RvcyBvcHRpbWl6ZWQgZm9yIFNQRUVEIHVzZSBhIHN0cmljdCBzdXBlcnNldCBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUKKy8vIG9mIGVxdWl2YWxlbnQgb25lcyBvcHRpbWl6ZWQgZm9yIENPREVfU0laRSwgc28gd2Ugc2hvdWxkIG9wdGltaXplIGFsbCBvdXIKKy8vIHRlc3RzIGZvciBzcGVlZCB1bmxlc3MgZXhwbGljaXRseSB0ZXN0aW5nIGNvZGUgc2l6ZSBvcHRpbWl6YXRpb24uCitvcHRpb24gb3B0aW1pemVfZm9yID0gU1BFRUQ7CisKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJVbml0dGVzdFByb3RvIjsKKworLy8gVGhpcyBwcm90byBpbmNsdWRlcyBldmVyeSB0eXBlIG9mIGZpZWxkIGluIGJvdGggc2luZ3VsYXIgYW5kIHJlcGVhdGVkCisvLyBmb3Jtcy4KK21lc3NhZ2UgVGVzdEFsbFR5cGVzIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICAvLyBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAorICAgIC8vIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCisgICAgLy8gVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCisgICAgb3B0aW9uYWwgaW50MzIgYmIgPSAxOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAxOworICAgIEJBUiA9IDI7CisgICAgQkFaID0gMzsKKyAgICBORUcgPSAtMTsgIC8vIEludGVudGlvbmFsbHkgbmVnYXRpdmUuCisgIH0KKworICAvLyBTaW5ndWxhcgorICBvcHRpb25hbCAgICBpbnQzMiBvcHRpb25hbF9pbnQzMiAgICA9ICAxOworICBvcHRpb25hbCAgICBpbnQ2NCBvcHRpb25hbF9pbnQ2NCAgICA9ICAyOworICBvcHRpb25hbCAgIHVpbnQzMiBvcHRpb25hbF91aW50MzIgICA9ICAzOworICBvcHRpb25hbCAgIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgICA9ICA0OworICBvcHRpb25hbCAgIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgICA9ICA1OworICBvcHRpb25hbCAgIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgICA9ICA2OworICBvcHRpb25hbCAgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyICA9ICA3OworICBvcHRpb25hbCAgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ICA9ICA4OworICBvcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9ICA5OworICBvcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOworICBvcHRpb25hbCAgICBmbG9hdCBvcHRpb25hbF9mbG9hdCAgICA9IDExOworICBvcHRpb25hbCAgIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgICA9IDEyOworICBvcHRpb25hbCAgICAgYm9vbCBvcHRpb25hbF9ib29sICAgICA9IDEzOworICBvcHRpb25hbCAgIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgICA9IDE0OworICBvcHRpb25hbCAgICBieXRlcyBvcHRpb25hbF9ieXRlcyAgICA9IDE1OworCisgIG9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDE3OworICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDE4OworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICA9IDIwOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9uZXN0ZWRfZW51bSAgICAgPSAyMTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSAgICA9IDIyOworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICBvcHRpb25hbF9pbXBvcnRfZW51bSAgICAgPSAyMzsKKworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlPUNPUkRdOworCisgIC8vIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZQorICAgICAgb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDQ3OworICB9CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICA9IDQ4OworICByZXBlYXRlZCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICA9IDUwOworCisgIHJlcGVhdGVkIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9uZXN0ZWRfZW51bSAgICAgPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSAgICA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICByZXBlYXRlZF9pbXBvcnRfZW51bSAgICAgPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgLy8gU2luZ3VsYXIgd2l0aCBkZWZhdWx0cworICBvcHRpb25hbCAgICBpbnQzMiBkZWZhdWx0X2ludDMyICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NCAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyICAgPSA2MyBbZGVmYXVsdCA9ICA0MyAgICBdOworICBvcHRpb25hbCAgIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzIgICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0ICAgPSA2NiBbZGVmYXVsdCA9ICA0NiAgICBdOworICBvcHRpb25hbCAgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzIgPSA2OSBbZGVmYXVsdCA9ICA0OSAgICBdOworICBvcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdCAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlICAgPSA3MiBbZGVmYXVsdCA9ICA1MmUzICBdOworICBvcHRpb25hbCAgICAgYm9vbCBkZWZhdWx0X2Jvb2wgICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgICAgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gIGRlZmF1bHRfbmVzdGVkX2VudW0gID0gODEgW2RlZmF1bHQgPSBCQVIgICAgICAgIF07CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtCisgICAgICBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbY3R5cGU9U1RSSU5HX1BJRUNFLGRlZmF1bHQ9ImFiYyJdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2N0eXBlPUNPUkQsZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICB9Cit9CisKKy8vIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1c2l2ZWx5IG5lc3RlZCBtZXNzYWdlLgorbWVzc2FnZSBOZXN0ZWRUZXN0QWxsVHlwZXMgeworICBvcHRpb25hbCBOZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7Cit9CisKK21lc3NhZ2UgVGVzdERlcHJlY2F0ZWRGaWVsZHMgeworICBvcHRpb25hbCBpbnQzMiBkZXByZWNhdGVkX2ludDMyID0gMSBbZGVwcmVjYXRlZD10cnVlXTsKK30KKworLy8gRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKKy8vIHRoYXQuCittZXNzYWdlIEZvcmVpZ25NZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgYyA9IDE7Cit9CisKK2VudW0gRm9yZWlnbkVudW0geworICBGT1JFSUdOX0ZPTyA9IDQ7CisgIEZPUkVJR05fQkFSID0gNTsKKyAgRk9SRUlHTl9CQVogPSA2OworfQorCittZXNzYWdlIFRlc3RBbGxFeHRlbnNpb25zIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworZXh0ZW5kIFRlc3RBbGxFeHRlbnNpb25zIHsKKyAgLy8gU2luZ3VsYXIKKyAgb3B0aW9uYWwgICAgaW50MzIgb3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uICAgID0gIDE7CisgIG9wdGlvbmFsICAgIGludDY0IG9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbiAgICA9ICAyOworICBvcHRpb25hbCAgIHVpbnQzMiBvcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uICAgPSAgMzsKKyAgb3B0aW9uYWwgICB1aW50NjQgb3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbiAgID0gIDQ7CisgIG9wdGlvbmFsICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb24gICA9ICA1OworICBvcHRpb25hbCAgIHNpbnQ2NCBvcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uICAgPSAgNjsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb24gID0gIDc7CisgIG9wdGlvbmFsICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uICA9ICA4OworICBvcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb24gPSAgOTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uID0gMTA7CisgIG9wdGlvbmFsICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbiAgICA9IDExOworICBvcHRpb25hbCAgIGRvdWJsZSBvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uICAgPSAxMjsKKyAgb3B0aW9uYWwgICAgIGJvb2wgb3B0aW9uYWxfYm9vbF9leHRlbnNpb24gICAgID0gMTM7CisgIG9wdGlvbmFsICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19leHRlbnNpb24gICA9IDE0OworICBvcHRpb25hbCAgICBieXRlcyBvcHRpb25hbF9ieXRlc19leHRlbnNpb24gICAgPSAxNTsKKworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwX2V4dGVuc2lvbiA9IDE2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gMTc7CisgIH0KKworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gPSAxODsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiA9IDE5OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZQorICAgIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiA9IDIwOworCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbiA9IDIxOworICBvcHRpb25hbCBGb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uID0gMjI7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtCisgICAgb3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uID0gMjM7CisKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZV9leHRlbnNpb24gPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uID0gMjUgW2N0eXBlPUNPUkRdOworCisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlCisgICAgb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiA9IDI2OworCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlCisgICAgb3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiA9IDI3IFtsYXp5PXRydWVdOworCisgIC8vIFJlcGVhdGVkCisgIHJlcGVhdGVkICAgIGludDMyIHJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAgPSAzMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgID0gMzM7CisgIHJlcGVhdGVkICAgdWludDY0IHJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAgPSAzNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgID0gMzY7CisgIHJlcGVhdGVkICBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAgPSAzODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uID0gMzk7CisgIHJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAgPSA0MTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgID0gNDI7CisgIHJlcGVhdGVkICAgICBib29sIHJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAgPSA0NDsKKyAgcmVwZWF0ZWQgICAgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgID0gNDU7CisKKyAgcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gPSA0NiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDQ3OworICB9CisKKyAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uID0gNDg7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gPSA0OTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UKKyAgICByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gPSA1MDsKKworICByZXBlYXRlZCBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24gPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bQorICAgIHJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiA9IDUzOworCisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkX2V4dGVuc2lvbiA9IDU1IFtjdHlwZT1DT1JEXTsKKworICByZXBlYXRlZCBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZQorICAgIHJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gPSA1NyBbbGF6eT10cnVlXTsKKworICAvLyBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCisgIG9wdGlvbmFsICAgIGludDMyIGRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NF9leHRlbnNpb24gICAgPSA2MiBbZGVmYXVsdCA9ICA0MiAgICBdOworICBvcHRpb25hbCAgIHVpbnQzMiBkZWZhdWx0X3VpbnQzMl9leHRlbnNpb24gICA9IDYzIFtkZWZhdWx0ID0gIDQzICAgIF07CisgIG9wdGlvbmFsICAgdWludDY0IGRlZmF1bHRfdWludDY0X2V4dGVuc2lvbiAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uICAgPSA2NSBbZGVmYXVsdCA9IC00NSAgICBdOworICBvcHRpb25hbCAgIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb24gICA9IDY2IFtkZWZhdWx0ID0gIDQ2ICAgIF07CisgIG9wdGlvbmFsICBmaXhlZDMyIGRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb24gID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbiAgPSA2OCBbZGVmYXVsdCA9ICA0OCAgICBdOworICBvcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbiA9IDY5IFtkZWZhdWx0ID0gIDQ5ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDY0IGRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdF9leHRlbnNpb24gICAgPSA3MSBbZGVmYXVsdCA9ICA1MS41ICBdOworICBvcHRpb25hbCAgIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9leHRlbnNpb24gICA9IDcyIFtkZWZhdWx0ID0gIDUyZTMgIF07CisgIG9wdGlvbmFsICAgICBib29sIGRlZmF1bHRfYm9vbF9leHRlbnNpb24gICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICAgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOworICBvcHRpb25hbCAgICBieXRlcyBkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbiAgICA9IDc1IFtkZWZhdWx0ID0gIndvcmxkIl07CisKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0KKyAgICBkZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbiA9IDgxIFtkZWZhdWx0ID0gQkFSXTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW0KKyAgICBkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb24gPSA4MiBbZGVmYXVsdCA9IEZPUkVJR05fQkFSXTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0KKyAgICBkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiA9IDgzIFtkZWZhdWx0ID0gSU1QT1JUX0JBUl07CisKKyAgb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiA9IDg0IFtjdHlwZT1TVFJJTkdfUElFQ0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdD0iYWJjIl07CisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uID0gODUgW2N0eXBlPUNPUkQsIGRlZmF1bHQ9IjEyMyJdOworCisgIC8vIEZvciBvbmVvZiB0ZXN0CisgIG9wdGlvbmFsIHVpbnQzMiBvbmVvZl91aW50MzJfZXh0ZW5zaW9uID0gMTExOworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gPSAxMTI7CisgIG9wdGlvbmFsIHN0cmluZyBvbmVvZl9zdHJpbmdfZXh0ZW5zaW9uID0gMTEzOworICBvcHRpb25hbCBieXRlcyBvbmVvZl9ieXRlc19leHRlbnNpb24gPSAxMTQ7Cit9CisKK21lc3NhZ2UgVGVzdE5lc3RlZEV4dGVuc2lvbiB7CisgIGV4dGVuZCBUZXN0QWxsRXh0ZW5zaW9ucyB7CisgICAgLy8gQ2hlY2sgZm9yIGJ1ZyB3aGVyZSBzdHJpbmcgZXh0ZW5zaW9ucyBkZWNsYXJlZCBpbiB0ZXN0ZWQgc2NvcGUgZGlkIG5vdAorICAgIC8vIGNvbXBpbGUuCisgICAgb3B0aW9uYWwgc3RyaW5nIHRlc3QgPSAxMDAyIFtkZWZhdWx0PSJ0ZXN0Il07CisgICAgLy8gVXNlZCB0byB0ZXN0IGlmIGdlbmVyYXRlZCBleHRlbnNpb24gbmFtZSBpcyBjb3JyZWN0IHdoZW4gdGhlcmUgYXJlCisgICAgLy8gdW5kZXJzY29yZXMuCisgICAgb3B0aW9uYWwgc3RyaW5nIG5lc3RlZF9zdHJpbmdfZXh0ZW5zaW9uID0gMTAwMzsKKyAgfQorfQorCisvLyBXZSBoYXZlIHNlcGFyYXRlIG1lc3NhZ2VzIGZvciB0ZXN0aW5nIHJlcXVpcmVkIGZpZWxkcyBiZWNhdXNlIGl0J3MKKy8vIGFubm95aW5nIHRvIGhhdmUgdG8gZmlsbCBpbiByZXF1aXJlZCBmaWVsZHMgaW4gVGVzdFByb3RvIGluIG9yZGVyIHRvCisvLyBkbyBhbnl0aGluZyB3aXRoIGl0LiAgTm90ZSB0aGF0IHdlIGRvbid0IG5lZWQgdG8gdGVzdCBldmVyeSB0eXBlIG9mCisvLyByZXF1aXJlZCBmaWxlZCBiZWNhdXNlIHRoZSBjb2RlIG91dHB1dCBpcyBiYXNpY2FsbHkgaWRlbnRpY2FsIHRvCisvLyBvcHRpb25hbCBmaWVsZHMgZm9yIGFsbCB0eXBlcy4KK21lc3NhZ2UgVGVzdFJlcXVpcmVkIHsKKyAgcmVxdWlyZWQgaW50MzIgYSA9IDE7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MiA9IDI7CisgIHJlcXVpcmVkIGludDMyIGIgPSAzOworCisgIGV4dGVuZCBUZXN0QWxsRXh0ZW5zaW9ucyB7CisgICAgb3B0aW9uYWwgVGVzdFJlcXVpcmVkIHNpbmdsZSA9IDEwMDA7CisgICAgcmVwZWF0ZWQgVGVzdFJlcXVpcmVkIG11bHRpICA9IDEwMDE7CisgIH0KKworICAvLyBQYWQgdGhlIGZpZWxkIGNvdW50IHRvIDMyIHNvIHRoYXQgd2UgY2FuIHRlc3QgdGhhdCBJc0luaXRpYWxpemVkKCkKKyAgLy8gcHJvcGVybHkgY2hlY2tzIG11bHRpcGxlIGVsZW1lbnRzIG9mIGhhc19iaXRzXy4KKyAgb3B0aW9uYWwgaW50MzIgZHVtbXk0ICA9ICA0OworICBvcHRpb25hbCBpbnQzMiBkdW1teTUgID0gIDU7CisgIG9wdGlvbmFsIGludDMyIGR1bW15NiAgPSAgNjsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXk3ICA9ICA3OworICBvcHRpb25hbCBpbnQzMiBkdW1teTggID0gIDg7CisgIG9wdGlvbmFsIGludDMyIGR1bW15OSAgPSAgOTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxMCA9IDEwOworICBvcHRpb25hbCBpbnQzMiBkdW1teTExID0gMTE7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MTIgPSAxMjsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxMyA9IDEzOworICBvcHRpb25hbCBpbnQzMiBkdW1teTE0ID0gMTQ7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MTUgPSAxNTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxNiA9IDE2OworICBvcHRpb25hbCBpbnQzMiBkdW1teTE3ID0gMTc7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MTggPSAxODsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxOSA9IDE5OworICBvcHRpb25hbCBpbnQzMiBkdW1teTIwID0gMjA7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjEgPSAyMTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyMiA9IDIyOworICBvcHRpb25hbCBpbnQzMiBkdW1teTIzID0gMjM7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjQgPSAyNDsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyNSA9IDI1OworICBvcHRpb25hbCBpbnQzMiBkdW1teTI2ID0gMjY7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjcgPSAyNzsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyOCA9IDI4OworICBvcHRpb25hbCBpbnQzMiBkdW1teTI5ID0gMjk7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MzAgPSAzMDsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkzMSA9IDMxOworICBvcHRpb25hbCBpbnQzMiBkdW1teTMyID0gMzI7CisKKyAgcmVxdWlyZWQgaW50MzIgYyA9IDMzOworfQorCittZXNzYWdlIFRlc3RSZXF1aXJlZEZvcmVpZ24geworICBvcHRpb25hbCBUZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7CisgIHJlcGVhdGVkIFRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOworfQorCisvLyBUZXN0IHRoYXQgd2UgY2FuIHVzZSBOZXN0ZWRNZXNzYWdlIGZyb20gb3V0c2lkZSBUZXN0QWxsVHlwZXMuCittZXNzYWdlIFRlc3RGb3JlaWduTmVzdGVkIHsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOworfQorCisvLyBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCB1bmtub3duIGZpZWxkIHN1cHBvcnQuCittZXNzYWdlIFRlc3RFbXB0eU1lc3NhZ2UgeworfQorCisvLyBMaWtlIGFib3ZlLCBidXQgZGVjbGFyZSBhbGwgZmllbGQgbnVtYmVycyBhcyBwb3RlbnRpYWwgZXh0ZW5zaW9ucy4gIE5vCisvLyBhY3R1YWwgZXh0ZW5zaW9ucyBzaG91bGQgZXZlciBiZSBkZWZpbmVkIGZvciB0aGlzIHR5cGUuCittZXNzYWdlIFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7CisgIGV4dGVuc2lvbnMgMSB0byBtYXg7Cit9CisKK21lc3NhZ2UgVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHsKKyAgZXh0ZW5zaW9ucyA0MjsKKyAgZXh0ZW5zaW9ucyA0MTQzIHRvIDQyNDM7CisgIGV4dGVuc2lvbnMgNjU1MzYgdG8gbWF4OworfQorCisvLyBUZXN0IHRoYXQgcmVhbGx5IGxhcmdlIHRhZyBudW1iZXJzIGRvbid0IGJyZWFrIGFueXRoaW5nLgorbWVzc2FnZSBUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgeworICAvLyBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcworICAvLyB0aHJlZSBiaXRzIHRvIGNvbW11bmljYXRlIHdpcmUgdHlwZS4KKyAgb3B0aW9uYWwgaW50MzIgYSA9IDE7CisgIG9wdGlvbmFsIGludDMyIGJiID0gMjY4NDM1NDU1OworfQorCittZXNzYWdlIFRlc3RSZWN1cnNpdmVNZXNzYWdlIHsKKyAgb3B0aW9uYWwgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7CisgIG9wdGlvbmFsIGludDMyIGkgPSAyOworfQorCisvLyBUZXN0IHRoYXQgbXV0dWFsIHJlY3Vyc2lvbiB3b3Jrcy4KK21lc3NhZ2UgVGVzdE11dHVhbFJlY3Vyc2lvbkEgeworICBvcHRpb25hbCBUZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdE11dHVhbFJlY3Vyc2lvbkIgeworICBvcHRpb25hbCBUZXN0TXV0dWFsUmVjdXJzaW9uQSBhID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAyOworfQorCisvLyBUZXN0IHRoYXQgZ3JvdXBzIGhhdmUgZGlzam9pbnQgZmllbGQgbnVtYmVycyBmcm9tIHRoZWlyIHNpYmxpbmdzIGFuZAorLy8gcGFyZW50cy4gIFRoaXMgaXMgTk9UIHBvc3NpYmxlIGluIHByb3RvMTsgb25seSBnb29nbGUucHJvdG9idWYuICBXaGVuIGF0dGVtcHRpbmcKKy8vIHRvIGNvbXBpbGUgd2l0aCBwcm90bzEsIHRoaXMgd2lsbCBlbWl0IGFuIGVycm9yOyBzbyB3ZSBvbmx5IGluY2x1ZGUgaXQKKy8vIGluIHByb3RvYnVmX3VuaXR0ZXN0X3Byb3RvLgorbWVzc2FnZSBUZXN0RHVwRmllbGROdW1iZXIgeyAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMQorICBvcHRpb25hbCBpbnQzMiBhID0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMQorICBvcHRpb25hbCBncm91cCBGb28gPSAyIHsgb3B0aW9uYWwgaW50MzIgYSA9IDE7IH0gIC8vIE5PX1BST1RPMQorICBvcHRpb25hbCBncm91cCBCYXIgPSAzIHsgb3B0aW9uYWwgaW50MzIgYSA9IDE7IH0gIC8vIE5PX1BST1RPMQorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMQorCisvLyBBZGRpdGlvbmFsIG1lc3NhZ2VzIGZvciB0ZXN0aW5nIGxhenkgZmllbGRzLgorbWVzc2FnZSBUZXN0RWFnZXJNZXNzYWdlIHsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eT1mYWxzZV07Cit9CittZXNzYWdlIFRlc3RMYXp5TWVzc2FnZSB7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenk9dHJ1ZV07Cit9CisKKy8vIE5lZWRlZCBmb3IgYSBQeXRob24gdGVzdC4KK21lc3NhZ2UgVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICByZXBlYXRlZCBpbnQzMiBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyID0gMTsKKyAgICByZXBlYXRlZCBGb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjsKKyAgfQorICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTsKK30KKworCisvLyBUZXN0IGFuIGVudW0gdGhhdCBoYXMgbXVsdGlwbGUgdmFsdWVzIHdpdGggdGhlIHNhbWUgbnVtYmVyLgorZW51bSBUZXN0RW51bVdpdGhEdXBWYWx1ZSB7CisgIG9wdGlvbiBhbGxvd19hbGlhcyA9IHRydWU7CisKKyAgRk9PMSA9IDE7CisgIEJBUjEgPSAyOworICBCQVogPSAzOworICBGT08yID0gMTsKKyAgQkFSMiA9IDI7Cit9CisKKy8vIFRlc3QgYW4gZW51bSB3aXRoIGxhcmdlLCB1bm9yZGVyZWQgdmFsdWVzLgorZW51bSBUZXN0U3BhcnNlRW51bSB7CisgIFNQQVJTRV9BID0gMTIzOworICBTUEFSU0VfQiA9IDYyMzc0OworICBTUEFSU0VfQyA9IDEyNTg5MjM0OworICBTUEFSU0VfRCA9IC0xNTsKKyAgU1BBUlNFX0UgPSAtNTM0NTI7CisgIFNQQVJTRV9GID0gMDsKKyAgU1BBUlNFX0cgPSAyOworfQorCisvLyBUZXN0IG1lc3NhZ2Ugd2l0aCBDYW1lbENhc2UgZmllbGQgbmFtZXMuICBUaGlzIHZpb2xhdGVzIFByb3RvY29sIEJ1ZmZlcgorLy8gc3RhbmRhcmQgc3R5bGUuCittZXNzYWdlIFRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHsKKyAgb3B0aW9uYWwgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOworICBvcHRpb25hbCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyOworICBvcHRpb25hbCBGb3JlaWduRW51bSBFbnVtRmllbGQgPSAzOworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OworICBvcHRpb25hbCBzdHJpbmcgU3RyaW5nUGllY2VGaWVsZCA9IDUgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIHN0cmluZyBDb3JkRmllbGQgPSA2IFtjdHlwZT1DT1JEXTsKKworICByZXBlYXRlZCBpbnQzMiBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkID0gNzsKKyAgcmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nRmllbGQgPSA4OworICByZXBlYXRlZCBGb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7CisgIHJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgcmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlPUNPUkRdOworfQorCisKKy8vIFdlIGxpc3QgZmllbGRzIG91dCBvZiBvcmRlciwgdG8gZW5zdXJlIHRoYXQgd2UncmUgdXNpbmcgZmllbGQgbnVtYmVyIGFuZCBub3QKKy8vIGZpZWxkIGluZGV4IHRvIGRldGVybWluZSBzZXJpYWxpemF0aW9uIG9yZGVyLgorbWVzc2FnZSBUZXN0RmllbGRPcmRlcmluZ3MgeworICBvcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTE7CisgIGV4dGVuc2lvbnMgMiB0byAxMDsKKyAgb3B0aW9uYWwgaW50NjQgbXlfaW50ID0gMTsKKyAgZXh0ZW5zaW9ucyAxMiB0byAxMDA7CisgIG9wdGlvbmFsIGZsb2F0IG15X2Zsb2F0ID0gMTAxOworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDY0IG9vID0gMjsKKyAgICAvLyBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAorICAgIC8vIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCisgICAgLy8gVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCisgICAgb3B0aW9uYWwgaW50MzIgYmIgPSAxOworICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgPSAyMDA7Cit9CisKKworZXh0ZW5kIFRlc3RGaWVsZE9yZGVyaW5ncyB7CisgIG9wdGlvbmFsIHN0cmluZyBteV9leHRlbnNpb25fc3RyaW5nID0gNTA7CisgIG9wdGlvbmFsIGludDMyIG15X2V4dGVuc2lvbl9pbnQgPSA1OworfQorCisKK21lc3NhZ2UgVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzIHsKKyAgb3B0aW9uYWwgYnl0ZXMgZXNjYXBlZF9ieXRlcyA9IDEgW2RlZmF1bHQgPSAiXDBcMDAxXGFcYlxmXG5cclx0XHZcXFwnXCJceGZlIl07CisgIG9wdGlvbmFsIHVpbnQzMiBsYXJnZV91aW50MzIgPSAyIFtkZWZhdWx0ID0gMHhGRkZGRkZGRl07CisgIG9wdGlvbmFsIHVpbnQ2NCBsYXJnZV91aW50NjQgPSAzIFtkZWZhdWx0ID0gMHhGRkZGRkZGRkZGRkZGRkZGXTsKKyAgb3B0aW9uYWwgIGludDMyIHNtYWxsX2ludDMyICA9IDQgW2RlZmF1bHQgPSAtMHg3RkZGRkZGRl07CisgIG9wdGlvbmFsICBpbnQ2NCBzbWFsbF9pbnQ2NCAgPSA1IFtkZWZhdWx0ID0gLTB4N0ZGRkZGRkZGRkZGRkZGRl07CisgIG9wdGlvbmFsICBpbnQzMiByZWFsbHlfc21hbGxfaW50MzIgPSAyMSBbZGVmYXVsdCA9IC0weDgwMDAwMDAwXTsKKyAgb3B0aW9uYWwgIGludDY0IHJlYWxseV9zbWFsbF9pbnQ2NCA9IDIyIFtkZWZhdWx0ID0gLTB4ODAwMDAwMDAwMDAwMDAwMF07CisKKyAgLy8gVGhlIGRlZmF1bHQgdmFsdWUgaGVyZSBpcyBVVEYtOCBmb3IgIlx1MTIzNCIuICAoV2UgY291bGQgYWxzbyBqdXN0IHR5cGUKKyAgLy8gdGhlIFVURi04IHRleHQgZGlyZWN0bHkgaW50byB0aGlzIHRleHQgZmlsZSByYXRoZXIgdGhhbiBlc2NhcGUgaXQsIGJ1dAorICAvLyBsb3RzIG9mIHBlb3BsZSB1c2UgZWRpdG9ycyB0aGF0IHdvdWxkIGJlIGNvbmZ1c2VkIGJ5IHRoaXMuKQorICBvcHRpb25hbCBzdHJpbmcgdXRmOF9zdHJpbmcgPSA2IFtkZWZhdWx0ID0gIlwzNDFcMjEwXDI2NCJdOworCisgIC8vIFRlc3RzIGZvciBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KKyAgb3B0aW9uYWwgZmxvYXQgemVyb19mbG9hdCA9IDcgW2RlZmF1bHQgPSAwXTsKKyAgb3B0aW9uYWwgZmxvYXQgb25lX2Zsb2F0ID0gOCBbZGVmYXVsdCA9IDFdOworICBvcHRpb25hbCBmbG9hdCBzbWFsbF9mbG9hdCA9IDkgW2RlZmF1bHQgPSAxLjVdOworICBvcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9vbmVfZmxvYXQgPSAxMCBbZGVmYXVsdCA9IC0xXTsKKyAgb3B0aW9uYWwgZmxvYXQgbmVnYXRpdmVfZmxvYXQgPSAxMSBbZGVmYXVsdCA9IC0xLjVdOworICAvLyBVc2luZyBleHBvbmVudHMKKyAgb3B0aW9uYWwgZmxvYXQgbGFyZ2VfZmxvYXQgPSAxMiBbZGVmYXVsdCA9IDJFOF07CisgIG9wdGlvbmFsIGZsb2F0IHNtYWxsX25lZ2F0aXZlX2Zsb2F0ID0gMTMgW2RlZmF1bHQgPSAtOGUtMjhdOworCisgIC8vIFRleHQgZm9yIG5vbmZpbml0ZSBmbG9hdGluZy1wb2ludCB2YWx1ZXMuCisgIG9wdGlvbmFsIGRvdWJsZSBpbmZfZG91YmxlID0gMTQgW2RlZmF1bHQgPSBpbmZdOworICBvcHRpb25hbCBkb3VibGUgbmVnX2luZl9kb3VibGUgPSAxNSBbZGVmYXVsdCA9IC1pbmZdOworICBvcHRpb25hbCBkb3VibGUgbmFuX2RvdWJsZSA9IDE2IFtkZWZhdWx0ID0gbmFuXTsKKyAgb3B0aW9uYWwgZmxvYXQgaW5mX2Zsb2F0ID0gMTcgW2RlZmF1bHQgPSBpbmZdOworICBvcHRpb25hbCBmbG9hdCBuZWdfaW5mX2Zsb2F0ID0gMTggW2RlZmF1bHQgPSAtaW5mXTsKKyAgb3B0aW9uYWwgZmxvYXQgbmFuX2Zsb2F0ID0gMTkgW2RlZmF1bHQgPSBuYW5dOworCisgIC8vIFRlc3RzIGZvciBDKysgdHJpZ3JhcGhzLgorICAvLyBUcmlncmFwaHMgc2hvdWxkIGJlIGVzY2FwZWQgaW4gQysrIGdlbmVyYXRlZCBmaWxlcywgYnV0IHRoZXkgc2hvdWxkIG5vdCBiZQorICAvLyBlc2NhcGVkIGZvciBvdGhlciBsYW5ndWFnZXMuCisgIC8vIE5vdGUgdGhhdCBpbiAucHJvdG8gZmlsZSwgIlw/IiBpcyBhIHZhbGlkIHdheSB0byBlc2NhcGUgPyBpbiBzdHJpbmcKKyAgLy8gbGl0ZXJhbHMuCisgIG9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/IFw/ID8/IFw/PyBcPz8/ID8/LyA/XD8tIl07CisKKyAgLy8gU3RyaW5nIGRlZmF1bHRzIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlciAnXDAwMCcKKyAgb3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gICAgICAgPSAyMyBbZGVmYXVsdCA9ICJoZWxcMDAwbG8iXTsKKyAgb3B0aW9uYWwgIGJ5dGVzIGJ5dGVzX3dpdGhfemVybyAgICAgICAgPSAyNCBbZGVmYXVsdCA9ICJ3b3JcMDAwbGQiXTsKKyAgb3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbY3R5cGU9U1RSSU5HX1BJRUNFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0PSJhYlwwMDBjIl07CisgIG9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyAgICAgICAgID0gMjYgW2N0eXBlPUNPUkQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9IjEyXDAwMDMiXTsKKyAgb3B0aW9uYWwgc3RyaW5nIHJlcGxhY2VtZW50X3N0cmluZyAgICAgPSAyNyBbZGVmYXVsdD0iJHt1bmtub3dufSJdOworfQorCittZXNzYWdlIFNwYXJzZUVudW1NZXNzYWdlIHsKKyAgb3B0aW9uYWwgVGVzdFNwYXJzZUVudW0gc3BhcnNlX2VudW0gPSAxOworfQorCisvLyBUZXN0IFN0cmluZyBhbmQgQnl0ZXM6IHN0cmluZyBpcyBmb3IgdmFsaWQgVVRGLTggc3RyaW5ncworbWVzc2FnZSBPbmVTdHJpbmcgeworICBvcHRpb25hbCBzdHJpbmcgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgTW9yZVN0cmluZyB7CisgIHJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTsKK30KKworbWVzc2FnZSBPbmVCeXRlcyB7CisgIG9wdGlvbmFsIGJ5dGVzIGRhdGEgPSAxOworfQorCittZXNzYWdlIE1vcmVCeXRlcyB7CisgIHJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOworfQorCisvLyBUZXN0IGludDMyLCB1aW50MzIsIGludDY0LCB1aW50NjQsIGFuZCBib29sIGFyZSBhbGwgY29tcGF0aWJsZQorbWVzc2FnZSBJbnQzMk1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBkYXRhID0gMTsKK30KKworbWVzc2FnZSBVaW50MzJNZXNzYWdlIHsKKyAgb3B0aW9uYWwgdWludDMyIGRhdGEgPSAxOworfQorCittZXNzYWdlIEludDY0TWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDY0IGRhdGEgPSAxOworfQorCittZXNzYWdlIFVpbnQ2NE1lc3NhZ2UgeworICBvcHRpb25hbCB1aW50NjQgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgQm9vbE1lc3NhZ2UgeworICBvcHRpb25hbCBib29sIGRhdGEgPSAxOworfQorCisvLyBUZXN0IG9uZW9mcy4KK21lc3NhZ2UgVGVzdE9uZW9mIHsKKyAgb25lb2YgZm9vIHsKKyAgICBpbnQzMiBmb29faW50ID0gMTsKKyAgICBzdHJpbmcgZm9vX3N0cmluZyA9IDI7CisgICAgVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzsKKyAgICBncm91cCBGb29Hcm91cCA9IDQgeworICAgICAgb3B0aW9uYWwgaW50MzIgYSA9IDU7CisgICAgICBvcHRpb25hbCBzdHJpbmcgYiA9IDY7CisgICAgfQorICB9Cit9CisKK21lc3NhZ2UgVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSB7CisgIG9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOworICBvcHRpb25hbCBzdHJpbmcgZm9vX3N0cmluZyA9IDI7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7CisgIG9wdGlvbmFsIGdyb3VwIEZvb0dyb3VwID0gNCB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDU7CisgICAgb3B0aW9uYWwgc3RyaW5nIGIgPSA2OworICB9Cit9CisKK21lc3NhZ2UgVGVzdE9uZW9mMiB7CisgIG9uZW9mIGZvbyB7CisgICAgaW50MzIgZm9vX2ludCA9IDE7CisgICAgc3RyaW5nIGZvb19zdHJpbmcgPSAyOworICAgIHN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlPUNPUkRdOworICAgIHN0cmluZyBmb29fc3RyaW5nX3BpZWNlID0gNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgICBieXRlcyBmb29fYnl0ZXMgPSA1OworICAgIE5lc3RlZEVudW0gZm9vX2VudW0gPSA2OworICAgIE5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSA3OworICAgIGdyb3VwIEZvb0dyb3VwID0gOCB7CisgICAgICBvcHRpb25hbCBpbnQzMiBhID0gOTsKKyAgICAgIG9wdGlvbmFsIHN0cmluZyBiID0gMTA7CisgICAgfQorICAgIE5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDExIFtsYXp5PXRydWVdOworICB9CisKKyAgb25lb2YgYmFyIHsKKyAgICBpbnQzMiBiYXJfaW50ID0gMTIgW2RlZmF1bHQgPSA1XTsKKyAgICBzdHJpbmcgYmFyX3N0cmluZyA9IDEzIFtkZWZhdWx0ID0gIlNUUklORyJdOworICAgIHN0cmluZyBiYXJfY29yZCA9IDE0IFtjdHlwZT1DT1JELCBkZWZhdWx0ID0gIkNPUkQiXTsKKyAgICBzdHJpbmcgYmFyX3N0cmluZ19waWVjZSA9IDE1IFtjdHlwZT1TVFJJTkdfUElFQ0UsIGRlZmF1bHQgPSAiU1BJRUNFIl07CisgICAgYnl0ZXMgYmFyX2J5dGVzID0gMTYgW2RlZmF1bHQgPSAiQllURVMiXTsKKyAgICBOZXN0ZWRFbnVtIGJhcl9lbnVtID0gMTcgW2RlZmF1bHQgPSBCQVJdOworICB9CisKKyAgb3B0aW9uYWwgaW50MzIgYmF6X2ludCA9IDE4OworICBvcHRpb25hbCBzdHJpbmcgYmF6X3N0cmluZyA9IDE5IFtkZWZhdWx0ID0gIkJBWiJdOworCisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgaW50NjQgcXV4X2ludCA9IDE7CisgICAgcmVwZWF0ZWQgaW50MzIgY29yZ2VfaW50ID0gMjsKKyAgfQorCisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgRk9PID0gMTsKKyAgICBCQVIgPSAyOworICAgIEJBWiA9IDM7CisgIH0KK30KKworbWVzc2FnZSBUZXN0UmVxdWlyZWRPbmVvZiB7CisgIG9uZW9mIGZvbyB7CisgICAgaW50MzIgZm9vX2ludCA9IDE7CisgICAgc3RyaW5nIGZvb19zdHJpbmcgPSAyOworICAgIE5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSAzOworICB9CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgcmVxdWlyZWQgZG91YmxlIHJlcXVpcmVkX2RvdWJsZSA9IDE7CisgIH0KK30KKworLy8gVGVzdCBtZXNzYWdlcyBmb3IgcGFja2VkIGZpZWxkcworCittZXNzYWdlIFRlc3RQYWNrZWRUeXBlcyB7CisgIHJlcGVhdGVkICAgIGludDMyIHBhY2tlZF9pbnQzMiAgICA9ICA5MCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGludDY0IHBhY2tlZF9pbnQ2NCAgICA9ICA5MSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDMyIHBhY2tlZF91aW50MzIgICA9ICA5MiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDY0IHBhY2tlZF91aW50NjQgICA9ICA5MyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDMyIHBhY2tlZF9zaW50MzIgICA9ICA5NCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDY0IHBhY2tlZF9zaW50NjQgICA9ICA5NSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDMyIHBhY2tlZF9maXhlZDMyICA9ICA5NiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ICA9ICA5NyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9ICA5OCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9ICA5OSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGZsb2F0IHBhY2tlZF9mbG9hdCAgICA9IDEwMCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgZG91YmxlIHBhY2tlZF9kb3VibGUgICA9IDEwMSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgICBib29sIHBhY2tlZF9ib29sICAgICA9IDEwMiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtICA9IDEwMyBbcGFja2VkID0gdHJ1ZV07Cit9CisKKy8vIEEgbWVzc2FnZSB3aXRoIHRoZSBzYW1lIGZpZWxkcyBhcyBUZXN0UGFja2VkVHlwZXMsIGJ1dCB3aXRob3V0IHBhY2tpbmcuIFVzZWQKKy8vIHRvIHRlc3QgcGFja2VkIDwtPiB1bnBhY2tlZCB3aXJlIGNvbXBhdGliaWxpdHkuCittZXNzYWdlIFRlc3RVbnBhY2tlZFR5cGVzIHsKKyAgcmVwZWF0ZWQgICAgaW50MzIgdW5wYWNrZWRfaW50MzIgICAgPSAgOTAgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgdW5wYWNrZWRfaW50NjQgICAgPSAgOTEgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgdW5wYWNrZWRfdWludDMyICAgPSAgOTIgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgdW5wYWNrZWRfdWludDY0ICAgPSAgOTMgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50MzIgdW5wYWNrZWRfc2ludDMyICAgPSAgOTQgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgdW5wYWNrZWRfc2ludDY0ICAgPSAgOTUgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiAgPSAgOTYgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NCAgPSAgOTcgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzIgPSAgOTggW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSAgOTkgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgdW5wYWNrZWRfZmxvYXQgICAgPSAxMDAgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgdW5wYWNrZWRfZG91YmxlICAgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgdW5wYWNrZWRfYm9vbCAgICAgPSAxMDIgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSAgPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTsKK30KKworbWVzc2FnZSBUZXN0UGFja2VkRXh0ZW5zaW9ucyB7CisgIGV4dGVuc2lvbnMgMSB0byBtYXg7Cit9CisKK2V4dGVuZCBUZXN0UGFja2VkRXh0ZW5zaW9ucyB7CisgIHJlcGVhdGVkICAgIGludDMyIHBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAgPSAgOTAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBpbnQ2NCBwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgID0gIDkxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcGFja2VkX3VpbnQzMl9leHRlbnNpb24gICA9ICA5MiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDY0IHBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAgPSAgOTMgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQzMiBwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgID0gIDk0IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICA9ICA5NSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDMyIHBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAgPSAgOTYgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gID0gIDk3IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiA9ICA5OCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24gPSAgOTkgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBmbG9hdCBwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgID0gMTAwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcGFja2VkX2RvdWJsZV9leHRlbnNpb24gICA9IDEwMSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgICBib29sIHBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAgPSAxMDIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBGb3JlaWduRW51bSBwYWNrZWRfZW51bV9leHRlbnNpb24gID0gMTAzIFtwYWNrZWQgPSB0cnVlXTsKK30KKworbWVzc2FnZSBUZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworZXh0ZW5kIFRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgeworICByZXBlYXRlZCAgICBpbnQzMiB1bnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAgPSAgOTAgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgdW5wYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgID0gIDkxIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgdWludDMyIHVucGFja2VkX3VpbnQzMl9leHRlbnNpb24gICA9ICA5MiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHVpbnQ2NCB1bnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAgPSAgOTMgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50MzIgdW5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgID0gIDk0IFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgc2ludDY0IHVucGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICA9ICA5NSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAgPSAgOTYgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gID0gIDk3IFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkIHNmaXhlZDMyIHVucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiA9ICA5OCBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCBzZml4ZWQ2NCB1bnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24gPSAgOTkgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgdW5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgID0gMTAwIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgZG91YmxlIHVucGFja2VkX2RvdWJsZV9leHRlbnNpb24gICA9IDEwMSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICAgYm9vbCB1bnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAgPSAxMDIgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bV9leHRlbnNpb24gID0gMTAzIFtwYWNrZWQgPSBmYWxzZV07Cit9CisKKy8vIFVzZWQgYnkgRXh0ZW5zaW9uU2V0VGVzdC9EeW5hbWljRXh0ZW5zaW9ucy4gIFRoZSB0ZXN0IGFjdHVhbGx5IGJ1aWxkcworLy8gYSBzZXQgb2YgZXh0ZW5zaW9ucyB0byBUZXN0QWxsRXh0ZW5zaW9ucyBkeW5hbWljYWxseSwgYmFzZWQgb24gdGhlIGZpZWxkcworLy8gb2YgdGhpcyBtZXNzYWdlIHR5cGUuCittZXNzYWdlIFRlc3REeW5hbWljRXh0ZW5zaW9ucyB7CisgIGVudW0gRHluYW1pY0VudW1UeXBlIHsKKyAgICBEWU5BTUlDX0ZPTyA9IDIyMDA7CisgICAgRFlOQU1JQ19CQVIgPSAyMjAxOworICAgIERZTkFNSUNfQkFaID0gMjIwMjsKKyAgfQorICBtZXNzYWdlIER5bmFtaWNNZXNzYWdlVHlwZSB7CisgICAgb3B0aW9uYWwgaW50MzIgZHluYW1pY19maWVsZCA9IDIxMDA7CisgIH0KKworICBvcHRpb25hbCBmaXhlZDMyIHNjYWxhcl9leHRlbnNpb24gPSAyMDAwOworICBvcHRpb25hbCBGb3JlaWduRW51bSBlbnVtX2V4dGVuc2lvbiA9IDIwMDE7CisgIG9wdGlvbmFsIER5bmFtaWNFbnVtVHlwZSBkeW5hbWljX2VudW1fZXh0ZW5zaW9uID0gMjAwMjsKKworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSBtZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDM7CisgIG9wdGlvbmFsIER5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfZXh0ZW5zaW9uID0gMjAwNTsKKyAgcmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9leHRlbnNpb24gPSAyMDA2IFtwYWNrZWQgPSB0cnVlXTsKK30KKworbWVzc2FnZSBUZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyB7CisgIC8vIFBhcnNpbmcgcmVwZWF0ZWQgZml4ZWQgc2l6ZSB2YWx1ZXMgdXNlZCB0byBmYWlsLiBUaGlzIG1lc3NhZ2UgbmVlZHMgdG8gYmUKKyAgLy8gdXNlZCBpbiBvcmRlciB0byBnZXQgYSB0YWcgb2YgdGhlIHJpZ2h0IHNpemU7IGFsbCBvZiB0aGUgcmVwZWF0ZWQgZmllbGRzCisgIC8vIGluIFRlc3RBbGxUeXBlcyBkaWRuJ3QgdHJpZ2dlciB0aGUgY2hlY2suCisgIHJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOworICAvLyBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgorICByZXBlYXRlZCBpbnQzMiAgIHJlcGVhdGVkX2ludDMyICAgPSAxMzsKKworICAvLyBUaGVzZSBoYXZlIHR3by1ieXRlIHRhZ3MuCisgIHJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7CisgIHJlcGVhdGVkIGludDY0ICAgcmVwZWF0ZWRfaW50NjQgICA9IDIwNDc7CisKKyAgLy8gVGhyZWUgYnl0ZSB0YWdzLgorICByZXBlYXRlZCBmbG9hdCAgIHJlcGVhdGVkX2Zsb2F0ICAgPSAyNjIxNDI7CisgIHJlcGVhdGVkIHVpbnQ2NCAgcmVwZWF0ZWRfdWludDY0ICA9IDI2MjE0MzsKK30KKworLy8gVGVzdCB0aGF0IGlmIGFuIG9wdGlvbmFsIG9yIHJlcXVpcmVkIG1lc3NhZ2UvZ3JvdXAgZmllbGQgYXBwZWFycyBtdWx0aXBsZQorLy8gdGltZXMgaW4gdGhlIGlucHV0LCB0aGV5IG5lZWQgdG8gYmUgbWVyZ2VkLgorbWVzc2FnZSBUZXN0UGFyc2luZ01lcmdlIHsKKyAgLy8gUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgZGVmaW5lcyBtYXRjaGluZyBmaWVsZCB0eXBlcyBhcyBUZXN0UGFyc2luZ01lcmdlLAorICAvLyBleGNlcHQgdGhhdCBhbGwgZmllbGRzIGFyZSByZXBlYXRlZC4gSW4gdGhlIHRlc3RzLCB3ZSB3aWxsIHNlcmlhbGl6ZSB0aGUKKyAgLy8gUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgdG8gYnl0ZXMsIGFuZCBwYXJzZSB0aGUgYnl0ZXMgdG8gVGVzdFBhcnNpbmdNZXJnZS4KKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGluIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIGFyZSBleHBlY3RlZCB0byBiZSBtZXJnZWQgaW50bworICAvLyB0aGUgY29ycmVzcG9uZGluZyByZXF1aXJlZC9vcHRpb25hbCBmaWVsZHMgaW4gVGVzdFBhcnNpbmdNZXJnZS4KKyAgbWVzc2FnZSBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciB7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7CisgICAgcmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeworICAgICAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDExOworICAgIH0KKyAgICByZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7CisgICAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7CisgICAgfQorICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7CisgIH0KKyAgcmVxdWlyZWQgVGVzdEFsbFR5cGVzIHJlcXVpcmVkX2FsbF90eXBlcyA9IDE7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSAyOworICByZXBlYXRlZCBUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzsKKyAgb3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDEwIHsKKyAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7CisgIH0KKyAgcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsKKyAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfZ3JvdXBfYWxsX3R5cGVzID0gMjE7CisgIH0KKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKKyAgZXh0ZW5kIFRlc3RQYXJzaW5nTWVyZ2UgeworICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBvcHRpb25hbF9leHQgPSAxMDAwOworICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcyByZXBlYXRlZF9leHQgPSAxMDAxOworICB9Cit9CisKK21lc3NhZ2UgVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIHsKKyAgLy8gKi8gPC0gVGhpcyBzaG91bGQgbm90IGNsb3NlIHRoZSBnZW5lcmF0ZWQgZG9jIGNvbW1lbnQKKyAgb3B0aW9uYWwgc3RyaW5nIGEgPSAxIFtkZWZhdWx0PSIqLyA8LSBOZWl0aGVyIHNob3VsZCB0aGlzLiJdOworfQorCisKKy8vIFRlc3QgdGhhdCBSUEMgc2VydmljZXMgd29yay4KK21lc3NhZ2UgRm9vUmVxdWVzdCAge30KK21lc3NhZ2UgRm9vUmVzcG9uc2Uge30KKworbWVzc2FnZSBGb29DbGllbnRNZXNzYWdlIHt9CittZXNzYWdlIEZvb1NlcnZlck1lc3NhZ2V7fQorCitzZXJ2aWNlIFRlc3RTZXJ2aWNlIHsKKyAgcnBjIEZvbyhGb29SZXF1ZXN0KSByZXR1cm5zIChGb29SZXNwb25zZSk7CisgIHJwYyBCYXIoQmFyUmVxdWVzdCkgcmV0dXJucyAoQmFyUmVzcG9uc2UpOworfQorCisKK21lc3NhZ2UgQmFyUmVxdWVzdCAge30KK21lc3NhZ2UgQmFyUmVzcG9uc2Uge30KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9hcmVuYS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Q3ZTQzNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucHJvdG8KQEAgLTAsMCArMSw0NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYV9pbXBvcnQucHJvdG8iOworCitwYWNrYWdlIHByb3RvMl9hcmVuYV91bml0dGVzdDsKKworb3B0aW9uIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworCittZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBkID0gMTsKK30KKworbWVzc2FnZSBBcmVuYU1lc3NhZ2UgeworICByZXBlYXRlZCBOZXN0ZWRNZXNzYWdlICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDE7CisgIHJlcGVhdGVkIEltcG9ydE5vQXJlbmFOZXN0ZWRNZXNzYWdlICByZXBlYXRlZF9pbXBvcnRfbm9fYXJlbmFfbWVzc2FnZSA9IDI7Cit9OwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDRkNmU4NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8KQEAgLTAsMCArMSwzOTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGJlbmp5QGdvb2dsZS5jb20gKEJlbmp5IFdlaW5iZXJnZXIpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBBIHByb3RvIGZpbGUgdXNlZCB0byB0ZXN0IHRoZSAiY3VzdG9tIG9wdGlvbnMiIGZlYXR1cmUgb2YgZ29vZ2xlLnByb3RvYnVmLgorCitzeW50YXggPSAicHJvdG8yIjsKKworLy8gU29tZSBnZW5lcmljX3NlcnZpY2VzIG9wdGlvbihzKSBhZGRlZCBhdXRvbWF0aWNhbGx5LgorLy8gU2VlOiAgaHR0cDovL2dvL3Byb3RvMi1nZW5lcmljLXNlcnZpY2VzLWRlZmF1bHQKK29wdGlvbiBjY19nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAgIC8vIGF1dG8tYWRkZWQKK29wdGlvbiBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOyAgIC8vIGF1dG8tYWRkZWQKK29wdGlvbiBweV9nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsKKworLy8gQSBjdXN0b20gZmlsZSBvcHRpb24gKGRlZmluZWQgYmVsb3cpLgorb3B0aW9uIChmaWxlX29wdDEpID0gOTg3NjU0MzIxMDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworCisvLyBTb21lIHNpbXBsZSB0ZXN0IGN1c3RvbSBvcHRpb25zIG9mIHZhcmlvdXMgdHlwZXMuCisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgeworICBvcHRpb25hbCB1aW50NjQgZmlsZV9vcHQxID0gNzczNjk3NDsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7CisgIG9wdGlvbmFsIGludDMyIG1lc3NhZ2Vfb3B0MSA9IDc3MzkwMzY7Cit9CisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsKKyAgb3B0aW9uYWwgZml4ZWQ2NCBmaWVsZF9vcHQxID0gNzc0MDkzNjsKKyAgLy8gVGhpcyBpcyB1c2VmdWwgZm9yIHRlc3RpbmcgdGhhdCB3ZSBjb3JyZWN0bHkgcmVnaXN0ZXIgZGVmYXVsdCB2YWx1ZXMgZm9yCisgIC8vIGV4dGVuc2lvbiBvcHRpb25zLgorICBvcHRpb25hbCBpbnQzMiBmaWVsZF9vcHQyID0gNzc1MzkxMyBbZGVmYXVsdD00Ml07Cit9CisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMgeworICBvcHRpb25hbCBzZml4ZWQzMiBlbnVtX29wdDEgPSA3NzUzNTc2OworfQorCitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgeworICBvcHRpb25hbCBpbnQzMiBlbnVtX3ZhbHVlX29wdDEgPSAxNTYwNjc4OworfQorCitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIHsKKyAgb3B0aW9uYWwgc2ludDY0IHNlcnZpY2Vfb3B0MSA9IDc4ODc2NTA7Cit9CisKK2VudW0gTWV0aG9kT3B0MSB7CisgIE1FVEhPRE9QVDFfVkFMMSA9IDE7CisgIE1FVEhPRE9QVDFfVkFMMiA9IDI7Cit9CisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyB7CisgIG9wdGlvbmFsIE1ldGhvZE9wdDEgbWV0aG9kX29wdDEgPSA3ODkwODYwOworfQorCisvLyBBIHRlc3QgbWVzc2FnZSB3aXRoIGN1c3RvbSBvcHRpb25zIGF0IGFsbCBwb3NzaWJsZSBsb2NhdGlvbnMgKGFuZCBhbHNvIHNvbWUKKy8vIHJlZ3VsYXIgb3B0aW9ucywgdG8gbWFrZSBzdXJlIHRoZXkgaW50ZXJhY3QgbmljZWx5KS4KK21lc3NhZ2UgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyB7CisgIG9wdGlvbiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IGZhbHNlOworCisgIG9wdGlvbiAobWVzc2FnZV9vcHQxKSA9IC01NjsKKworICBvcHRpb25hbCBzdHJpbmcgZmllbGQxID0gMSBbY3R5cGU9Q09SRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmaWVsZF9vcHQxKT04NzY1NDMyMTA5XTsKKworICBlbnVtIEFuRW51bSB7CisgICAgb3B0aW9uIChlbnVtX29wdDEpID0gLTc4OTsKKworICAgIEFORU5VTV9WQUwxID0gMTsKKyAgICBBTkVOVU1fVkFMMiA9IDIgWyhlbnVtX3ZhbHVlX29wdDEpID0gMTIzXTsKKyAgfQorfQorCisKKy8vIEEgdGVzdCBSUEMgc2VydmljZSB3aXRoIGN1c3RvbSBvcHRpb25zIGF0IGFsbCBwb3NzaWJsZSBsb2NhdGlvbnMgKGFuZCBhbHNvCisvLyBzb21lIHJlZ3VsYXIgb3B0aW9ucywgdG8gbWFrZSBzdXJlIHRoZXkgaW50ZXJhY3QgbmljZWx5KS4KK21lc3NhZ2UgQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCB7Cit9CisKK21lc3NhZ2UgQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgeworfQorCittZXNzYWdlIEN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgeworfQorCittZXNzYWdlIEN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgeworfQorCitzZXJ2aWNlIFRlc3RTZXJ2aWNlV2l0aEN1c3RvbU9wdGlvbnMgeworICBvcHRpb24gKHNlcnZpY2Vfb3B0MSkgPSAtOTg3NjU0MzIxMDsKKworICBycGMgRm9vKEN1c3RvbU9wdGlvbkZvb1JlcXVlc3QpIHJldHVybnMgKEN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlKSB7CisgICAgb3B0aW9uIChtZXRob2Rfb3B0MSkgPSBNRVRIT0RPUFQxX1ZBTDI7CisgIH0KK30KKworCisKKy8vIE9wdGlvbnMgb2YgZXZlcnkgcG9zc2libGUgZmllbGQgdHlwZSwgc28gd2UgY2FuIHRlc3QgdGhlbSBhbGwgZXhoYXVzdGl2ZWx5LgorCittZXNzYWdlIER1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIHsKKyAgZW51bSBUZXN0RW51bVR5cGUgeworICAgIFRFU1RfT1BUSU9OX0VOVU1fVFlQRTEgPSAyMjsKKyAgICBURVNUX09QVElPTl9FTlVNX1RZUEUyID0gLTIzOworICB9Cit9CisKK21lc3NhZ2UgRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSB7Cit9CisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeworICBvcHRpb25hbCAgICAgICAgIGJvb2wgICAgIGJvb2xfb3B0ID0gNzcwNjA5MDsKKyAgb3B0aW9uYWwgICAgICAgIGludDMyICAgIGludDMyX29wdCA9IDc3MDU3MDk7CisgIG9wdGlvbmFsICAgICAgICBpbnQ2NCAgICBpbnQ2NF9vcHQgPSA3NzA1NTQyOworICBvcHRpb25hbCAgICAgICB1aW50MzIgICB1aW50MzJfb3B0ID0gNzcwNDg4MDsKKyAgb3B0aW9uYWwgICAgICAgdWludDY0ICAgdWludDY0X29wdCA9IDc3MDIzNjc7CisgIG9wdGlvbmFsICAgICAgIHNpbnQzMiAgIHNpbnQzMl9vcHQgPSA3NzAxNTY4OworICBvcHRpb25hbCAgICAgICBzaW50NjQgICBzaW50NjRfb3B0ID0gNzcwMDg2MzsKKyAgb3B0aW9uYWwgICAgICBmaXhlZDMyICBmaXhlZDMyX29wdCA9IDc3MDAzMDc7CisgIG9wdGlvbmFsICAgICAgZml4ZWQ2NCAgZml4ZWQ2NF9vcHQgPSA3NzAwMTk0OworICBvcHRpb25hbCAgICAgc2ZpeGVkMzIgc2ZpeGVkMzJfb3B0ID0gNzY5ODY0NTsKKyAgb3B0aW9uYWwgICAgIHNmaXhlZDY0IHNmaXhlZDY0X29wdCA9IDc2ODU0NzU7CisgIG9wdGlvbmFsICAgICAgICBmbG9hdCAgICBmbG9hdF9vcHQgPSA3Njc1MzkwOworICBvcHRpb25hbCAgICAgICBkb3VibGUgICBkb3VibGVfb3B0ID0gNzY3MzI5MzsKKyAgb3B0aW9uYWwgICAgICAgc3RyaW5nICAgc3RyaW5nX29wdCA9IDc2NzMyODU7CisgIG9wdGlvbmFsICAgICAgICBieXRlcyAgICBieXRlc19vcHQgPSA3NjczMjM4OworICBvcHRpb25hbCBEdW1teU1lc3NhZ2VDb250YWluaW5nRW51bS5UZXN0RW51bVR5cGUgZW51bV9vcHQgPSA3NjczMjMzOworICBvcHRpb25hbCBEdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIG1lc3NhZ2VfdHlwZV9vcHQgPSA3NjY1OTY3OworfQorCittZXNzYWdlIEN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgeworICBvcHRpb24gICAgIChib29sX29wdCkgPSBmYWxzZTsKKyAgb3B0aW9uICAgIChpbnQzMl9vcHQpID0gLTB4ODAwMDAwMDA7CisgIG9wdGlvbiAgICAoaW50NjRfb3B0KSA9IC0weDgwMDAwMDAwMDAwMDAwMDA7CisgIG9wdGlvbiAgICh1aW50MzJfb3B0KSA9IDA7CisgIG9wdGlvbiAgICh1aW50NjRfb3B0KSA9IDA7CisgIG9wdGlvbiAgIChzaW50MzJfb3B0KSA9IC0weDgwMDAwMDAwOworICBvcHRpb24gICAoc2ludDY0X29wdCkgPSAtMHg4MDAwMDAwMDAwMDAwMDAwOworICBvcHRpb24gIChmaXhlZDMyX29wdCkgPSAwOworICBvcHRpb24gIChmaXhlZDY0X29wdCkgPSAwOworICBvcHRpb24gKHNmaXhlZDMyX29wdCkgPSAtMHg4MDAwMDAwMDsKKyAgb3B0aW9uIChzZml4ZWQ2NF9vcHQpID0gLTB4ODAwMDAwMDAwMDAwMDAwMDsKK30KKworbWVzc2FnZSBDdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIHsKKyAgb3B0aW9uICAgICAoYm9vbF9vcHQpID0gdHJ1ZTsKKyAgb3B0aW9uICAgIChpbnQzMl9vcHQpID0gMHg3RkZGRkZGRjsKKyAgb3B0aW9uICAgIChpbnQ2NF9vcHQpID0gMHg3RkZGRkZGRkZGRkZGRkZGOworICBvcHRpb24gICAodWludDMyX29wdCkgPSAweEZGRkZGRkZGOworICBvcHRpb24gICAodWludDY0X29wdCkgPSAweEZGRkZGRkZGRkZGRkZGRkY7CisgIG9wdGlvbiAgIChzaW50MzJfb3B0KSA9IDB4N0ZGRkZGRkY7CisgIG9wdGlvbiAgIChzaW50NjRfb3B0KSA9IDB4N0ZGRkZGRkZGRkZGRkZGRjsKKyAgb3B0aW9uICAoZml4ZWQzMl9vcHQpID0gMHhGRkZGRkZGRjsKKyAgb3B0aW9uICAoZml4ZWQ2NF9vcHQpID0gMHhGRkZGRkZGRkZGRkZGRkZGOworICBvcHRpb24gKHNmaXhlZDMyX29wdCkgPSAweDdGRkZGRkZGOworICBvcHRpb24gKHNmaXhlZDY0X29wdCkgPSAweDdGRkZGRkZGRkZGRkZGRkY7Cit9CisKK21lc3NhZ2UgQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgeworICBvcHRpb24gIChpbnQzMl9vcHQpID0gLTEwMDsgIC8vIFRvIHRlc3Qgc2lnbi1leHRlbnNpb24uCisgIG9wdGlvbiAgKGZsb2F0X29wdCkgPSAxMi4zNDU2Nzg5OworICBvcHRpb24gKGRvdWJsZV9vcHQpID0gMS4yMzQ1Njc4OTAxMjM0NTY3ODk7CisgIG9wdGlvbiAoc3RyaW5nX29wdCkgPSAiSGVsbG8sIFwiV29ybGRcIiI7CisgIG9wdGlvbiAgKGJ5dGVzX29wdCkgPSAiSGVsbG9cMFdvcmxkIjsKKyAgb3B0aW9uICAgKGVudW1fb3B0KSA9IFRFU1RfT1BUSU9OX0VOVU1fVFlQRTI7Cit9CisKK21lc3NhZ2UgU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyB7CisgIG9wdGlvbiAgKGZsb2F0X29wdCkgPSAxMjsKKyAgb3B0aW9uIChkb3VibGVfb3B0KSA9IDE1NDsKK30KKworbWVzc2FnZSBTZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHsKKyAgb3B0aW9uICAoZmxvYXRfb3B0KSA9IC0xMjsKKyAgb3B0aW9uICAoZG91YmxlX29wdCkgPSAtMTU0OworfQorCisvLyBPcHRpb25zIG9mIGNvbXBsZXggbWVzc2FnZSB0eXBlcywgdGhlbXNlbHZlcyBjb21iaW5lZCBhbmQgZXh0ZW5kZWQgaW4KKy8vIHZhcmlvdXMgd2F5cy4KKworbWVzc2FnZSBDb21wbGV4T3B0aW9uVHlwZTEgeworICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOworICBvcHRpb25hbCBpbnQzMiBmb28yID0gMjsKKyAgb3B0aW9uYWwgaW50MzIgZm9vMyA9IDM7CisgIHJlcGVhdGVkIGludDMyIGZvbzQgPSA0OworCisgIGV4dGVuc2lvbnMgMTAwIHRvIG1heDsKK30KKworbWVzc2FnZSBDb21wbGV4T3B0aW9uVHlwZTIgeworICBvcHRpb25hbCBDb21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgYmF6ID0gMjsKKworICBtZXNzYWdlIENvbXBsZXhPcHRpb25UeXBlNCB7CisgICAgb3B0aW9uYWwgaW50MzIgd2FsZG8gPSAxOworCisgICAgZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7CisgICAgICBvcHRpb25hbCBDb21wbGV4T3B0aW9uVHlwZTQgY29tcGxleF9vcHQ0ID0gNzYzMzU0NjsKKyAgICB9CisgIH0KKworICBvcHRpb25hbCBDb21wbGV4T3B0aW9uVHlwZTQgZnJlZCA9IDM7CisgIHJlcGVhdGVkIENvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OworCisgIGV4dGVuc2lvbnMgMTAwIHRvIG1heDsKK30KKworbWVzc2FnZSBDb21wbGV4T3B0aW9uVHlwZTMgeworICBvcHRpb25hbCBpbnQzMiBxdXggPSAxOworCisgIG9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHRpb25UeXBlNSA9IDIgeworICAgIG9wdGlvbmFsIGludDMyIHBsdWdoID0gMzsKKyAgfQorfQorCitleHRlbmQgQ29tcGxleE9wdGlvblR5cGUxIHsKKyAgb3B0aW9uYWwgaW50MzIgcXV1eCA9IDc2NjM3MDc7CisgIG9wdGlvbmFsIENvbXBsZXhPcHRpb25UeXBlMyBjb3JnZSA9IDc2NjM0NDI7Cit9CisKK2V4dGVuZCBDb21wbGV4T3B0aW9uVHlwZTIgeworICBvcHRpb25hbCBpbnQzMiBncmF1bHQgPSA3NjUwOTI3OworICBvcHRpb25hbCBDb21wbGV4T3B0aW9uVHlwZTEgZ2FycGx5ID0gNzY0OTk5MjsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSBjb21wbGV4X29wdDEgPSA3NjQ2NzU2OworICBvcHRpb25hbCBDb21wbGV4T3B0aW9uVHlwZTIgY29tcGxleF9vcHQyID0gNzYzNjk0OTsKKyAgb3B0aW9uYWwgQ29tcGxleE9wdGlvblR5cGUzIGNvbXBsZXhfb3B0MyA9IDc2MzY0NjM7CisgIG9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHQ2ID0gNzU5NTQ2OCB7CisgICAgb3B0aW9uYWwgaW50MzIgeHl6enkgPSA3NTkzOTUxOworICB9Cit9CisKKy8vIE5vdGUgdGhhdCB3ZSB0cnkgdmFyaW91cyBkaWZmZXJlbnQgd2F5cyBvZiBuYW1pbmcgdGhlIHNhbWUgZXh0ZW5zaW9uLgorbWVzc2FnZSBWYXJpb3VzQ29tcGxleE9wdGlvbnMgeworICBvcHRpb24gKC5wcm90b2J1Zl91bml0dGVzdC5jb21wbGV4X29wdDEpLmZvbyA9IDQyOworICBvcHRpb24gKHByb3RvYnVmX3VuaXR0ZXN0LmNvbXBsZXhfb3B0MSkuKC5wcm90b2J1Zl91bml0dGVzdC5xdXV4KSA9IDMyNDsKKyAgb3B0aW9uICgucHJvdG9idWZfdW5pdHRlc3QuY29tcGxleF9vcHQxKS4ocHJvdG9idWZfdW5pdHRlc3QuY29yZ2UpLnF1eCA9IDg3NjsKKyAgb3B0aW9uIChwcm90b2J1Zl91bml0dGVzdC5jb21wbGV4X29wdDEpLmZvbzQgPSA5OTsKKyAgb3B0aW9uIChwcm90b2J1Zl91bml0dGVzdC5jb21wbGV4X29wdDEpLmZvbzQgPSA4ODsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLmJheiA9IDk4NzsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLihncmF1bHQpID0gNjU0OworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFyLmZvbyA9IDc0MzsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLmJhci4ocXV1eCkgPSAxOTk5OworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFyLihwcm90b2J1Zl91bml0dGVzdC5jb3JnZSkucXV4ID0gMjAwODsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLihnYXJwbHkpLmZvbyA9IDc0MTsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLihnYXJwbHkpLigucHJvdG9idWZfdW5pdHRlc3QucXV1eCkgPSAxOTk4OworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuKHByb3RvYnVmX3VuaXR0ZXN0LmdhcnBseSkuKGNvcmdlKS5xdXggPSAyMTIxOworICBvcHRpb24gKENvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuY29tcGxleF9vcHQ0KS53YWxkbyA9IDE5NzE7CisgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5mcmVkLndhbGRvID0gMzIxOworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFybmV5ID0geyB3YWxkbzogMTAxIH07CisgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5iYXJuZXkgPSB7IHdhbGRvOiAyMTIgfTsKKyAgb3B0aW9uIChwcm90b2J1Zl91bml0dGVzdC5jb21wbGV4X29wdDMpLnF1eCA9IDk7CisgIG9wdGlvbiAoY29tcGxleF9vcHQzKS5jb21wbGV4b3B0aW9udHlwZTUucGx1Z2ggPSAyMjsKKyAgb3B0aW9uIChjb21wbGV4b3B0NikueHl6enkgPSAyNDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBEZWZpbml0aW9ucyBmb3IgdGVzdGluZyBhZ2dyZWdhdGUgb3B0aW9uIHBhcnNpbmcuCisvLyBTZWUgZGVzY3JpcHRvcl91bml0dGVzdC5jYy4KKworbWVzc2FnZSBBZ2dyZWdhdGVNZXNzYWdlU2V0IHsKKyAgb3B0aW9uIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gdHJ1ZTsKKyAgZXh0ZW5zaW9ucyA0IHRvIG1heDsKK30KKworbWVzc2FnZSBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCB7CisgIGV4dGVuZCBBZ2dyZWdhdGVNZXNzYWdlU2V0IHsKKyAgICBvcHRpb25hbCBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCBtZXNzYWdlX3NldF9leHRlbnNpb24gPSAxNTQ0NzU0MjsKKyAgfQorICBvcHRpb25hbCBzdHJpbmcgcyA9IDE7Cit9CisKKy8vIEEgaGVscGVyIHR5cGUgdXNlZCB0byB0ZXN0IGFnZ3JlZ2F0ZSBvcHRpb24gcGFyc2luZworbWVzc2FnZSBBZ2dyZWdhdGUgeworICBvcHRpb25hbCBpbnQzMiBpID0gMTsKKyAgb3B0aW9uYWwgc3RyaW5nIHMgPSAyOworCisgIC8vIEEgbmVzdGVkIG9iamVjdAorICBvcHRpb25hbCBBZ2dyZWdhdGUgc3ViID0gMzsKKworICAvLyBUbyB0ZXN0IHRoZSBwYXJzaW5nIG9mIGV4dGVuc2lvbnMgaW5zaWRlIGFnZ3JlZ2F0ZSB2YWx1ZXMKKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OworICBleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIHsKKyAgICBvcHRpb25hbCBBZ2dyZWdhdGUgbmVzdGVkID0gMTU0NzY5MDM7CisgIH0KKworICAvLyBBbiBlbWJlZGRlZCBtZXNzYWdlIHNldAorICBvcHRpb25hbCBBZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXQgPSA1OworfQorCisvLyBBbGxvdyBBZ2dyZWdhdGUgdG8gYmUgdXNlZCBhcyBhbiBvcHRpb24gYXQgYWxsIHBvc3NpYmxlIGxvY2F0aW9ucworLy8gaW4gdGhlIC5wcm90byBncmFtbWVyLgorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyAgICAgIHsgb3B0aW9uYWwgQWdncmVnYXRlIGZpbGVvcHQgICAgPSAxNTQ3ODQ3OTsgfQorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyAgIHsgb3B0aW9uYWwgQWdncmVnYXRlIG1zZ29wdCAgICAgPSAxNTQ4MDA4ODsgfQorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgICAgIHsgb3B0aW9uYWwgQWdncmVnYXRlIGZpZWxkb3B0ICAgPSAxNTQ4MTM3NDsgfQorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyAgICAgIHsgb3B0aW9uYWwgQWdncmVnYXRlIGVudW1vcHQgICAgPSAxNTQ4MzIxODsgfQorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIHsgb3B0aW9uYWwgQWdncmVnYXRlIGVudW12YWxvcHQgPSAxNTQ4NjkyMTsgfQorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyAgIHsgb3B0aW9uYWwgQWdncmVnYXRlIHNlcnZpY2VvcHQgPSAxNTQ5NzE0NTsgfQorZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zICAgIHsgb3B0aW9uYWwgQWdncmVnYXRlIG1ldGhvZG9wdCAgPSAxNTUxMjcxMzsgfQorCisvLyBUcnkgdXNpbmcgQWdncmVnYXRlT3B0aW9uIGF0IGRpZmZlcmVudCBwb2ludHMgaW4gdGhlIHByb3RvIGdyYW1tYXIKK29wdGlvbiAoZmlsZW9wdCkgPSB7CisgIHM6ICdGaWxlQW5ub3RhdGlvbicKKyAgLy8gQWxzbyB0ZXN0IHRoZSBoYW5kbGluZyBvZiBjb21tZW50cworICAvKiBvZiBib3RoIHR5cGVzICovIGk6IDEwMAorCisgIHN1YiB7IHM6ICdOZXN0ZWRGaWxlQW5ub3RhdGlvbicgfQorCisgIC8vIEluY2x1ZGUgYSBnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgYW5kIHJlY3Vyc2l2ZWx5IGV4dGVuZCBpdCB3aXRoCisgIC8vIGFub3RoZXIgZmlsZW9wdC4KKyAgZmlsZSB7CisgICAgW3Byb3RvYnVmX3VuaXR0ZXN0LmZpbGVvcHRdIHsKKyAgICAgIHM6J0ZpbGVFeHRlbnNpb25Bbm5vdGF0aW9uJworICAgIH0KKyAgfQorCisgIC8vIEEgbWVzc2FnZSBzZXQgaW5zaWRlIGFuIG9wdGlvbiB2YWx1ZQorICBtc2V0IHsKKyAgICBbcHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQubWVzc2FnZV9zZXRfZXh0ZW5zaW9uXSB7CisgICAgICBzOiAnRW1iZWRkZWRNZXNzYWdlU2V0RWxlbWVudCcKKyAgICB9CisgIH0KK307CisKK21lc3NhZ2UgQWdncmVnYXRlTWVzc2FnZSB7CisgIG9wdGlvbiAobXNnb3B0KSA9IHsgaToxMDEgczonTWVzc2FnZUFubm90YXRpb24nIH07CisgIG9wdGlvbmFsIGludDMyIGZpZWxkbmFtZSA9IDEgWyhmaWVsZG9wdCkgPSB7IHM6J0ZpZWxkQW5ub3RhdGlvbicgfV07Cit9CisKK3NlcnZpY2UgQWdncmVnYXRlU2VydmljZSB7CisgIG9wdGlvbiAoc2VydmljZW9wdCkgPSB7IHM6J1NlcnZpY2VBbm5vdGF0aW9uJyB9OworICBycGMgTWV0aG9kIChBZ2dyZWdhdGVNZXNzYWdlKSByZXR1cm5zIChBZ2dyZWdhdGVNZXNzYWdlKSB7CisgICAgb3B0aW9uIChtZXRob2RvcHQpID0geyBzOidNZXRob2RBbm5vdGF0aW9uJyB9OworICB9Cit9CisKK2VudW0gQWdncmVnYXRlRW51bSB7CisgIG9wdGlvbiAoZW51bW9wdCkgPSB7IHM6J0VudW1Bbm5vdGF0aW9uJyB9OworICBWQUxVRSA9IDEgWyhlbnVtdmFsb3B0KSA9IHsgczonRW51bVZhbHVlQW5ub3RhdGlvbicgfV07Cit9CisKKy8vIFRlc3QgY3VzdG9tIG9wdGlvbnMgZm9yIG5lc3RlZCB0eXBlLgorbWVzc2FnZSBOZXN0ZWRPcHRpb25UeXBlIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBvcHRpb24gKG1lc3NhZ2Vfb3B0MSkgPSAxMDAxOworICAgIG9wdGlvbmFsIGludDMyIG5lc3RlZF9maWVsZCA9IDEgWyhmaWVsZF9vcHQxKSA9IDEwMDJdOworICB9CisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgb3B0aW9uIChlbnVtX29wdDEpID0gMTAwMzsKKyAgICBORVNURURfRU5VTV9WQUxVRSA9IDEgWyhlbnVtX3ZhbHVlX29wdDEpID0gMTAwNF07CisgIH0KKyAgZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyB7CisgICAgb3B0aW9uYWwgaW50MzIgbmVzdGVkX2V4dGVuc2lvbiA9IDc5MTI1NzMgWyhmaWVsZF9vcHQyKSA9IDEwMDVdOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Ryb3BfdW5rbm93bl9maWVsZHMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Ryb3BfdW5rbm93bl9maWVsZHMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjZiMzFhYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wcm90bwpAQCAtMCwwICsxLDU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkczsKKworbWVzc2FnZSBGb28geworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDA7CisgICAgQkFSID0gMTsKKyAgICBCQVogPSAyOworICB9CisgIG9wdGlvbmFsIGludDMyIGludDMyX3ZhbHVlID0gMTsKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBlbnVtX3ZhbHVlID0gMjsKK30KKworbWVzc2FnZSBGb29XaXRoRXh0cmFGaWVsZHMgeworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDA7CisgICAgQkFSID0gMTsKKyAgICBCQVogPSAyOworICAgIFFVWCA9IDM7CisgIH0KKyAgb3B0aW9uYWwgaW50MzIgaW50MzJfdmFsdWUgPSAxOworICBvcHRpb25hbCBOZXN0ZWRFbnVtIGVudW1fdmFsdWUgPSAyOworICBvcHRpb25hbCBpbnQzMiBleHRyYV9pbnQzMl92YWx1ZSA9IDM7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4YjBmOWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wcm90bwpAQCAtMCwwICsxLDUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gQSBwcm90byBmaWxlIHdoaWNoIGltcG9ydHMgYSBwcm90byBmaWxlIHRoYXQgdXNlcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUuCisKK3N5bnRheCA9ICJwcm90bzIiOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworLy8gV2Ugb3B0aW1pemUgZm9yIHNwZWVkIGhlcmUsIGJ1dCB3ZSBhcmUgaW1wb3J0aW5nIGEgcHJvdG8gdGhhdCBpcyBvcHRpbWl6ZWQKKy8vIGZvciBjb2RlIHNpemUuCitvcHRpb24gb3B0aW1pemVfZm9yID0gU1BFRUQ7CisKK21lc3NhZ2UgVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSB7CisgIC8vIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bworICAvLyBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KKyAgb3B0aW9uYWwgVGVzdE9wdGltaXplZEZvclNpemUgb3B0aW9uYWxfbWVzc2FnZSA9IDE7CisgIHJlcGVhdGVkIFRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbXB0eS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY0NDNlNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8KQEAgLTAsMCArMSwzOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuICAoQXQgb25lIHBvaW50IHRoaXMgd291bGRuJ3QgY29tcGlsZQorLy8gY29ycmVjdGx5LikKKworc3ludGF4ID0gInByb3RvMiI7CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI1MDI2MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW5vcm1vdXNfZGVzY3JpcHRvci5wcm90bwpAQCAtMCwwICsxLDEwNDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBBIHByb3RvIGZpbGUgdGhhdCBoYXMgYW4gZXh0cmVtZWx5IGxhcmdlIGRlc2NyaXB0b3IuICBVc2VkIHRvIHRlc3QgdGhhdAorLy8gZGVzY3JpcHRvcnMgb3ZlciA2NGsgZG9uJ3QgYnJlYWsgdGhlIHN0cmluZyBsaXRlcmFsIGxlbmd0aCBsaW1pdCBpbiBKYXZhLgorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworCisvLyBBdm9pZCBnZW5lcmF0aW5nIGluc2FuZWx5IGxvbmcgbWV0aG9kcy4KK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkU7CisKK21lc3NhZ2UgVGVzdEVub3Jtb3VzRGVzY3JpcHRvciB7CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xID0gMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMiA9IDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ID0gNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNSA9IDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ID0gNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOCA9IDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMCA9IDEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMSA9IDExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMiA9IDEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMyA9IDEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNCA9IDE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNSA9IDE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNiA9IDE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNyA9IDE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOCA9IDE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOSA9IDE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMCA9IDIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMSA9IDIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMiA9IDIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMyA9IDIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNCA9IDI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNSA9IDI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNiA9IDI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNyA9IDI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOCA9IDI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOSA9IDI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMCA9IDMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMSA9IDMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMiA9IDMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMyA9IDMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNCA9IDM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNSA9IDM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNiA9IDM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNyA9IDM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOCA9IDM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOSA9IDM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MCA9IDQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MSA9IDQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MiA9IDQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MyA9IDQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NCA9IDQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NSA9IDQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NiA9IDQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NyA9IDQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OCA9IDQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OSA9IDQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MCA9IDUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MSA9IDUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MiA9IDUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MyA9IDUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NCA9IDU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NSA9IDU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NiA9IDU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NyA9IDU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OCA9IDU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OSA9IDU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MCA9IDYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MSA9IDYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MiA9IDYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MyA9IDYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NCA9IDY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NSA9IDY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NiA9IDY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NyA9IDY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OCA9IDY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OSA9IDY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MCA9IDcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MSA9IDcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MiA9IDcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MyA9IDczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NCA9IDc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NSA9IDc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NiA9IDc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NyA9IDc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OCA9IDc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OSA9IDc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MCA9IDgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MSA9IDgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MiA9IDgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MyA9IDgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NCA9IDg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NSA9IDg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NiA9IDg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NyA9IDg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OCA9IDg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OSA9IDg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MCA9IDkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MSA9IDkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MiA9IDkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MyA9IDkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NCA9IDk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NSA9IDk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NiA9IDk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NyA9IDk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OCA9IDk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OSA9IDk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAgPSAxMDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMSA9IDEwMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAyID0gMTAyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDMgPSAxMDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNCA9IDEwNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA1ID0gMTA1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDYgPSAxMDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNyA9IDEwNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA4ID0gMTA4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDkgPSAxMDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMCA9IDExMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTExID0gMTExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTIgPSAxMTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMyA9IDExMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE0ID0gMTE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTUgPSAxMTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNiA9IDExNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE3ID0gMTE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTggPSAxMTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOSA9IDExOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIwID0gMTIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjEgPSAxMjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMiA9IDEyMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIzID0gMTIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjQgPSAxMjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNSA9IDEyNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI2ID0gMTI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjcgPSAxMjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOCA9IDEyOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI5ID0gMTI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzAgPSAxMzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMSA9IDEzMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMyID0gMTMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzMgPSAxMzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNCA9IDEzNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM1ID0gMTM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzYgPSAxMzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNyA9IDEzNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM4ID0gMTM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzkgPSAxMzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MCA9IDE0MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQxID0gMTQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDIgPSAxNDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MyA9IDE0MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ0ID0gMTQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDUgPSAxNDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NiA9IDE0NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ3ID0gMTQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDggPSAxNDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OSA9IDE0OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUwID0gMTUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTEgPSAxNTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MiA9IDE1MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUzID0gMTUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTQgPSAxNTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NSA9IDE1NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU2ID0gMTU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTcgPSAxNTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OCA9IDE1OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU5ID0gMTU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjAgPSAxNjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MSA9IDE2MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYyID0gMTYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjMgPSAxNjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NCA9IDE2NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY1ID0gMTY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjYgPSAxNjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NyA9IDE2NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY4ID0gMTY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjkgPSAxNjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MCA9IDE3MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcxID0gMTcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzIgPSAxNzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MyA9IDE3MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc0ID0gMTc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzUgPSAxNzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NiA9IDE3NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc3ID0gMTc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzggPSAxNzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OSA9IDE3OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgwID0gMTgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODEgPSAxODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MiA9IDE4MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgzID0gMTgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODQgPSAxODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NSA9IDE4NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg2ID0gMTg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODcgPSAxODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OCA9IDE4OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg5ID0gMTg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTAgPSAxOTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MSA9IDE5MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkyID0gMTkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTMgPSAxOTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NCA9IDE5NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk1ID0gMTk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTYgPSAxOTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NyA9IDE5NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk4ID0gMTk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTkgPSAxOTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMCA9IDIwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAxID0gMjAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDIgPSAyMDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMyA9IDIwMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA0ID0gMjA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDUgPSAyMDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNiA9IDIwNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA3ID0gMjA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDggPSAyMDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOSA9IDIwOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEwID0gMjEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTEgPSAyMTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMiA9IDIxMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEzID0gMjEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTQgPSAyMTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNSA9IDIxNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE2ID0gMjE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTcgPSAyMTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOCA9IDIxOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE5ID0gMjE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjAgPSAyMjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMSA9IDIyMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIyID0gMjIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjMgPSAyMjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNCA9IDIyNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI1ID0gMjI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjYgPSAyMjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNyA9IDIyNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI4ID0gMjI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjkgPSAyMjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMCA9IDIzMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMxID0gMjMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzIgPSAyMzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMyA9IDIzMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM0ID0gMjM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzUgPSAyMzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNiA9IDIzNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM3ID0gMjM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzggPSAyMzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOSA9IDIzOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQwID0gMjQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDEgPSAyNDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MiA9IDI0MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQzID0gMjQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDQgPSAyNDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NSA9IDI0NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ2ID0gMjQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDcgPSAyNDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OCA9IDI0OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ5ID0gMjQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTAgPSAyNTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MSA9IDI1MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUyID0gMjUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTMgPSAyNTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NCA9IDI1NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU1ID0gMjU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTYgPSAyNTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NyA9IDI1NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU4ID0gMjU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTkgPSAyNTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MCA9IDI2MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYxID0gMjYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjIgPSAyNjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MyA9IDI2MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY0ID0gMjY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjUgPSAyNjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NiA9IDI2NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY3ID0gMjY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjggPSAyNjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OSA9IDI2OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcwID0gMjcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzEgPSAyNzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MiA9IDI3MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjczID0gMjczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzQgPSAyNzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NSA9IDI3NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc2ID0gMjc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzcgPSAyNzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OCA9IDI3OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc5ID0gMjc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODAgPSAyODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MSA9IDI4MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgyID0gMjgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODMgPSAyODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NCA9IDI4NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg1ID0gMjg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODYgPSAyODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NyA9IDI4NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg4ID0gMjg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODkgPSAyODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MCA9IDI5MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkxID0gMjkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTIgPSAyOTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MyA9IDI5MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk0ID0gMjk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTUgPSAyOTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NiA9IDI5NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk3ID0gMjk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTggPSAyOTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OSA9IDI5OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAwID0gMzAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDEgPSAzMDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMiA9IDMwMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAzID0gMzAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDQgPSAzMDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNSA9IDMwNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA2ID0gMzA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDcgPSAzMDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOCA9IDMwOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA5ID0gMzA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTAgPSAzMTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMSA9IDMxMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEyID0gMzEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTMgPSAzMTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNCA9IDMxNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE1ID0gMzE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTYgPSAzMTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNyA9IDMxNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE4ID0gMzE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTkgPSAzMTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMCA9IDMyMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIxID0gMzIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMyA9IDMyMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI0ID0gMzI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNiA9IDMyNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI3ID0gMzI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOSA9IDMyOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMwID0gMzMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMiA9IDMzMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMzID0gMzMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNSA9IDMzNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM2ID0gMzM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOCA9IDMzOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM5ID0gMzM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MSA9IDM0MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQyID0gMzQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NCA9IDM0NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ1ID0gMzQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NyA9IDM0NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ4ID0gMzQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MCA9IDM1MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUxID0gMzUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MyA9IDM1MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU0ID0gMzU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NiA9IDM1NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU3ID0gMzU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OSA9IDM1OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYwID0gMzYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MiA9IDM2MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYzID0gMzYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NSA9IDM2NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY2ID0gMzY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OCA9IDM2OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY5ID0gMzY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MSA9IDM3MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcyID0gMzcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NCA9IDM3NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc1ID0gMzc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NyA9IDM3NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc4ID0gMzc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MCA9IDM4MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgxID0gMzgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MyA9IDM4MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg0ID0gMzg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NiA9IDM4NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg3ID0gMzg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OSA9IDM4OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkwID0gMzkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MiA9IDM5MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkzID0gMzkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NSA9IDM5NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk2ID0gMzk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OCA9IDM5OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk5ID0gMzk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMSA9IDQwMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAyID0gNDAyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNCA9IDQwNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA1ID0gNDA1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNyA9IDQwNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA4ID0gNDA4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMCA9IDQxMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDExID0gNDExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMyA9IDQxMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE0ID0gNDE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNiA9IDQxNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE3ID0gNDE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOSA9IDQxOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIwID0gNDIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMiA9IDQyMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIzID0gNDIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNSA9IDQyNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI2ID0gNDI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOCA9IDQyOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI5ID0gNDI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMSA9IDQzMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMyID0gNDMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNCA9IDQzNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM1ID0gNDM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNyA9IDQzNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM4ID0gNDM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MCA9IDQ0MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQxID0gNDQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MyA9IDQ0MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ0ID0gNDQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NiA9IDQ0NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ3ID0gNDQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OSA9IDQ0OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUwID0gNDUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MiA9IDQ1MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUzID0gNDUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NSA9IDQ1NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU2ID0gNDU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OCA9IDQ1OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU5ID0gNDU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MSA9IDQ2MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYyID0gNDYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NCA9IDQ2NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY1ID0gNDY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NyA9IDQ2NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY4ID0gNDY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MCA9IDQ3MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcxID0gNDcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MyA9IDQ3MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc0ID0gNDc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NiA9IDQ3NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc3ID0gNDc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OSA9IDQ3OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgwID0gNDgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MiA9IDQ4MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgzID0gNDgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NSA9IDQ4NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg2ID0gNDg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OCA9IDQ4OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg5ID0gNDg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MSA9IDQ5MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkyID0gNDkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NCA9IDQ5NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk1ID0gNDk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NyA9IDQ5NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk4ID0gNDk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMCA9IDUwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAxID0gNTAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMyA9IDUwMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA0ID0gNTA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNiA9IDUwNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA3ID0gNTA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOSA9IDUwOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEwID0gNTEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMiA9IDUxMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEzID0gNTEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNSA9IDUxNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE2ID0gNTE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOCA9IDUxOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE5ID0gNTE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMSA9IDUyMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIyID0gNTIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNCA9IDUyNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI1ID0gNTI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNyA9IDUyNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI4ID0gNTI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMCA9IDUzMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMxID0gNTMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMyA9IDUzMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM0ID0gNTM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNiA9IDUzNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM3ID0gNTM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOSA9IDUzOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQwID0gNTQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MiA9IDU0MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQzID0gNTQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NSA9IDU0NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ2ID0gNTQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OCA9IDU0OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ5ID0gNTQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MSA9IDU1MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUyID0gNTUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NCA9IDU1NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU1ID0gNTU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NyA9IDU1NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU4ID0gNTU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MCA9IDU2MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYxID0gNTYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MyA9IDU2MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY0ID0gNTY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NiA9IDU2NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY3ID0gNTY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OSA9IDU2OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcwID0gNTcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MiA9IDU3MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTczID0gNTczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NSA9IDU3NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc2ID0gNTc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OCA9IDU3OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc5ID0gNTc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MSA9IDU4MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgyID0gNTgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NCA9IDU4NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg1ID0gNTg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NyA9IDU4NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg4ID0gNTg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MCA9IDU5MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkxID0gNTkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MyA9IDU5MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk0ID0gNTk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NiA9IDU5NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk3ID0gNTk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OSA9IDU5OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAwID0gNjAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMiA9IDYwMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAzID0gNjAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNSA9IDYwNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA2ID0gNjA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOCA9IDYwOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA5ID0gNjA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMSA9IDYxMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEyID0gNjEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNCA9IDYxNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE1ID0gNjE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNyA9IDYxNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE4ID0gNjE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMCA9IDYyMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIxID0gNjIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMyA9IDYyMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI0ID0gNjI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNiA9IDYyNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI3ID0gNjI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOSA9IDYyOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMwID0gNjMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMiA9IDYzMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMzID0gNjMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNSA9IDYzNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM2ID0gNjM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOCA9IDYzOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM5ID0gNjM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MSA9IDY0MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQyID0gNjQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NCA9IDY0NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ1ID0gNjQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NyA9IDY0NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ4ID0gNjQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MCA9IDY1MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUxID0gNjUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MyA9IDY1MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU0ID0gNjU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NiA9IDY1NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU3ID0gNjU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OSA9IDY1OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYwID0gNjYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MiA9IDY2MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYzID0gNjYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NSA9IDY2NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY2ID0gNjY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OCA9IDY2OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY5ID0gNjY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MSA9IDY3MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcyID0gNjcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NCA9IDY3NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc1ID0gNjc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NyA9IDY3NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc4ID0gNjc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MCA9IDY4MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgxID0gNjgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MyA9IDY4MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg0ID0gNjg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NiA9IDY4NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg3ID0gNjg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OSA9IDY4OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkwID0gNjkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MiA9IDY5MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkzID0gNjkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NSA9IDY5NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk2ID0gNjk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OCA9IDY5OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk5ID0gNjk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMSA9IDcwMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAyID0gNzAyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNCA9IDcwNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA1ID0gNzA1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNyA9IDcwNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA4ID0gNzA4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMCA9IDcxMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzExID0gNzExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMyA9IDcxMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE0ID0gNzE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNiA9IDcxNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE3ID0gNzE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOSA9IDcxOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIwID0gNzIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMiA9IDcyMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIzID0gNzIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNSA9IDcyNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI2ID0gNzI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOCA9IDcyOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI5ID0gNzI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMSA9IDczMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMyID0gNzMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNCA9IDczNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM1ID0gNzM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNyA9IDczNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM4ID0gNzM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MCA9IDc0MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQxID0gNzQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MyA9IDc0MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ0ID0gNzQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NiA9IDc0NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ3ID0gNzQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OSA9IDc0OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUwID0gNzUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MiA9IDc1MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUzID0gNzUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NSA9IDc1NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU2ID0gNzU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OCA9IDc1OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU5ID0gNzU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MSA9IDc2MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYyID0gNzYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NCA9IDc2NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY1ID0gNzY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NyA9IDc2NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY4ID0gNzY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MCA9IDc3MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcxID0gNzcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MyA9IDc3MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc0ID0gNzc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NiA9IDc3NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc3ID0gNzc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OSA9IDc3OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgwID0gNzgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MiA9IDc4MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgzID0gNzgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NSA9IDc4NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg2ID0gNzg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OCA9IDc4OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg5ID0gNzg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MSA9IDc5MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkyID0gNzkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NCA9IDc5NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk1ID0gNzk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NyA9IDc5NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk4ID0gNzk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMCA9IDgwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAxID0gODAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMyA9IDgwMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA0ID0gODA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNiA9IDgwNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA3ID0gODA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOSA9IDgwOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEwID0gODEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMiA9IDgxMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEzID0gODEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNSA9IDgxNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE2ID0gODE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOCA9IDgxOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE5ID0gODE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMSA9IDgyMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIyID0gODIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNCA9IDgyNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI1ID0gODI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNyA9IDgyNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI4ID0gODI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMCA9IDgzMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMxID0gODMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMyA9IDgzMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM0ID0gODM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNiA9IDgzNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM3ID0gODM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOSA9IDgzOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQwID0gODQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MiA9IDg0MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQzID0gODQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NSA9IDg0NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ2ID0gODQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OCA9IDg0OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ5ID0gODQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MSA9IDg1MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUyID0gODUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NCA9IDg1NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU1ID0gODU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NyA9IDg1NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU4ID0gODU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MCA9IDg2MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYxID0gODYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MyA9IDg2MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY0ID0gODY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NiA9IDg2NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY3ID0gODY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OSA9IDg2OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcwID0gODcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MiA9IDg3MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODczID0gODczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NSA9IDg3NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc2ID0gODc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OCA9IDg3OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc5ID0gODc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MSA9IDg4MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgyID0gODgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NCA9IDg4NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg1ID0gODg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NyA9IDg4NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg4ID0gODg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MCA9IDg5MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkxID0gODkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MyA9IDg5MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk0ID0gODk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NiA9IDg5NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk3ID0gODk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OSA9IDg5OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAwID0gOTAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMiA9IDkwMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAzID0gOTAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNSA9IDkwNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA2ID0gOTA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOCA9IDkwOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA5ID0gOTA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMSA9IDkxMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEyID0gOTEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNCA9IDkxNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE1ID0gOTE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNyA9IDkxNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE4ID0gOTE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMCA9IDkyMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIxID0gOTIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMyA9IDkyMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI0ID0gOTI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNiA9IDkyNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI3ID0gOTI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOSA9IDkyOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMwID0gOTMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMiA9IDkzMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMzID0gOTMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNSA9IDkzNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM2ID0gOTM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOCA9IDkzOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM5ID0gOTM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MSA9IDk0MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQyID0gOTQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NCA9IDk0NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ1ID0gOTQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NyA9IDk0NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ4ID0gOTQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MCA9IDk1MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUxID0gOTUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MyA9IDk1MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU0ID0gOTU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NiA9IDk1NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU3ID0gOTU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OSA9IDk1OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYwID0gOTYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MiA9IDk2MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYzID0gOTYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NSA9IDk2NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY2ID0gOTY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OCA9IDk2OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY5ID0gOTY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MSA9IDk3MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcyID0gOTcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NCA9IDk3NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc1ID0gOTc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NyA9IDk3NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc4ID0gOTc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MCA9IDk4MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgxID0gOTgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MyA9IDk4MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg0ID0gOTg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NiA9IDk4NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg3ID0gOTg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OSA9IDk4OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkwID0gOTkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MiA9IDk5MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkzID0gOTkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NSA9IDk5NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk2ID0gOTk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OCA9IDk5OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk5ID0gOTk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAwID0gMTAwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTE2NTIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG8KQEAgLTAsMCArMSw2NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEEgcHJvdG8gZmlsZSB3aGljaCBpcyBpbXBvcnRlZCBieSB1bml0dGVzdC5wcm90byB0byB0ZXN0IGltcG9ydGluZy4KKworc3ludGF4ID0gInByb3RvMiI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorLy8gSW4gdGVzdF91dGlsLmggd2UgZG8KKy8vICJ1c2luZyBuYW1lc3BhY2UgdW5pdHRlc3RfaW1wb3J0ID0gcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0Ii4KK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OworCitvcHRpb24gb3B0aW1pemVfZm9yID0gU1BFRUQ7CitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CisKKy8vIEV4ZXJjaXNlIHRoZSBqYXZhX3BhY2thZ2Ugb3B0aW9uLgorb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QiOworCisvLyBEbyBub3Qgc2V0IGEgamF2YV9vdXRlcl9jbGFzc25hbWUgaGVyZSB0byB2ZXJpZnkgdGhhdCBQcm90bzIgd29ya3Mgd2l0aG91dAorLy8gb25lLgorCisvLyBUZXN0IHB1YmxpYyBpbXBvcnQKK2ltcG9ydCBwdWJsaWMgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvIjsKKworbWVzc2FnZSBJbXBvcnRNZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDE7Cit9CisKK2VudW0gSW1wb3J0RW51bSB7CisgIElNUE9SVF9GT08gPSA3OworICBJTVBPUlRfQkFSID0gODsKKyAgSU1QT1JUX0JBWiA9IDk7Cit9CisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3YWZhNDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvCkBAIC0wLDAgKzEsNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gVGhpcyBpcyBsaWtlIHVuaXR0ZXN0X2ltcG9ydC5wcm90byBidXQgd2l0aCBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUuCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKK2ltcG9ydCBwdWJsaWMgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8iOworCittZXNzYWdlIEltcG9ydE1lc3NhZ2VMaXRlIHsKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDE7Cit9CisKK2VudW0gSW1wb3J0RW51bUxpdGUgeworICBJTVBPUlRfTElURV9GT08gPSA3OworICBJTVBPUlRfTElURV9CQVIgPSA4OworICBJTVBPUlRfTElURV9CQVogPSA5OworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmYWY3NzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KQEAgLTAsMCArMSw0MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbGl1amlzaUBnb29nbGUuY29tIChQaGVybCBMaXUpCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QiOworCittZXNzYWdlIFB1YmxpY0ltcG9ydE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBlID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzM1NDljMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvCkBAIC0wLDAgKzEsNDMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGxpdWppc2lAZ29vZ2xlLmNvbSAoUGhlcmwgTGl1KQorCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKK21lc3NhZ2UgUHVibGljSW1wb3J0TWVzc2FnZUxpdGUgeworICBvcHRpb25hbCBpbnQzMiBlID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjJjMGU0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvCkBAIC0wLDAgKzEsMzg1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFRoaXMgaXMgbGlrZSB1bml0dGVzdC5wcm90byBidXQgd2l0aCBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUuCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8iOworCitvcHRpb24gb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FOworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworCisvLyBTYW1lIGFzIFRlc3RBbGxUeXBlcyBidXQgd2l0aCB0aGUgbGl0ZSBydW50aW1lLgorbWVzc2FnZSBUZXN0QWxsVHlwZXNMaXRlIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBvcHRpb25hbCBpbnQzMiBiYiA9IDE7CisgIH0KKworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDE7CisgICAgQkFSID0gMjsKKyAgICBCQVogPSAzOworICB9CisKKyAgLy8gU2luZ3VsYXIKKyAgb3B0aW9uYWwgICAgaW50MzIgb3B0aW9uYWxfaW50MzIgICAgPSAgMTsKKyAgb3B0aW9uYWwgICAgaW50NjQgb3B0aW9uYWxfaW50NjQgICAgPSAgMjsKKyAgb3B0aW9uYWwgICB1aW50MzIgb3B0aW9uYWxfdWludDMyICAgPSAgMzsKKyAgb3B0aW9uYWwgICB1aW50NjQgb3B0aW9uYWxfdWludDY0ICAgPSAgNDsKKyAgb3B0aW9uYWwgICBzaW50MzIgb3B0aW9uYWxfc2ludDMyICAgPSAgNTsKKyAgb3B0aW9uYWwgICBzaW50NjQgb3B0aW9uYWxfc2ludDY0ICAgPSAgNjsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiAgPSAgNzsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCAgPSAgODsKKyAgb3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSAgOTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDsKKyAgb3B0aW9uYWwgICAgZmxvYXQgb3B0aW9uYWxfZmxvYXQgICAgPSAxMTsKKyAgb3B0aW9uYWwgICBkb3VibGUgb3B0aW9uYWxfZG91YmxlICAgPSAxMjsKKyAgb3B0aW9uYWwgICAgIGJvb2wgb3B0aW9uYWxfYm9vbCAgICAgPSAxMzsKKyAgb3B0aW9uYWwgICBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nICAgPSAxNDsKKyAgb3B0aW9uYWwgICAgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgICAgPSAxNTsKKworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSAxNzsKKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2UgICAgICBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgPSAxODsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2VMaXRlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZUxpdGUKKyAgICBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gICAgICBvcHRpb25hbF9uZXN0ZWRfZW51bSAgICAgPSAyMTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW1MaXRlIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSAgICA9IDIyOworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUxpdGUgb3B0aW9uYWxfaW1wb3J0X2VudW0gPSAyMzsKKworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlPUNPUkRdOworCisgIC8vIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZUxpdGUKKyAgICAgIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OworCisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenk9dHJ1ZV07CisKKyAgLy8gUmVwZWF0ZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfaW50MzIgICAgPSAzMTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcmVwZWF0ZWRfaW50NjQgICAgPSAzMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyICAgPSAzMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcmVwZWF0ZWRfdWludDY0ICAgPSAzNDsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcmVwZWF0ZWRfc2ludDMyICAgPSAzNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ICAgPSAzNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiAgPSAzNzsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCAgPSAzODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgICAgPSA0MTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlICAgPSA0MjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcmVwZWF0ZWRfYm9vbCAgICAgPSA0MzsKKyAgcmVwZWF0ZWQgICBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nICAgPSA0NDsKKyAgcmVwZWF0ZWQgICAgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgICAgPSA0NTsKKworICByZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSA0NzsKKyAgfQorCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgICAgICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAgPSA0ODsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2VMaXRlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZUxpdGUKKyAgICByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOworCisgIHJlcGVhdGVkIE5lc3RlZEVudW0gICAgICByZXBlYXRlZF9uZXN0ZWRfZW51bSAgPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW1MaXRlIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUxpdGUgcmVwZWF0ZWRfaW1wb3J0X2VudW0gPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgLy8gU2luZ3VsYXIgd2l0aCBkZWZhdWx0cworICBvcHRpb25hbCAgICBpbnQzMiBkZWZhdWx0X2ludDMyICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NCAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyICAgPSA2MyBbZGVmYXVsdCA9ICA0MyAgICBdOworICBvcHRpb25hbCAgIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzIgICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0ICAgPSA2NiBbZGVmYXVsdCA9ICA0NiAgICBdOworICBvcHRpb25hbCAgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzIgPSA2OSBbZGVmYXVsdCA9ICA0OSAgICBdOworICBvcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdCAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlICAgPSA3MiBbZGVmYXVsdCA9ICA1MmUzICBdOworICBvcHRpb25hbCAgICAgYm9vbCBkZWZhdWx0X2Jvb2wgICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgICAgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gZGVmYXVsdF9uZXN0ZWRfZW51bSA9IDgxIFtkZWZhdWx0ID0gQkFSXTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW1MaXRlIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIKKyAgICAgIFtkZWZhdWx0ID0gRk9SRUlHTl9MSVRFX0JBUl07CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtTGl0ZQorICAgICAgZGVmYXVsdF9pbXBvcnRfZW51bSA9IDgzIFtkZWZhdWx0ID0gSU1QT1JUX0xJVEVfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbY3R5cGU9U1RSSU5HX1BJRUNFLGRlZmF1bHQ9ImFiYyJdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2N0eXBlPUNPUkQsZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICB9Cit9CisKK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2VMaXRlIHsKKyAgb3B0aW9uYWwgaW50MzIgYyA9IDE7Cit9CisKK2VudW0gRm9yZWlnbkVudW1MaXRlIHsKKyAgRk9SRUlHTl9MSVRFX0ZPTyA9IDQ7CisgIEZPUkVJR05fTElURV9CQVIgPSA1OworICBGT1JFSUdOX0xJVEVfQkFaID0gNjsKK30KKworbWVzc2FnZSBUZXN0UGFja2VkVHlwZXNMaXRlIHsKKyAgcmVwZWF0ZWQgICAgaW50MzIgcGFja2VkX2ludDMyICAgID0gIDkwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcGFja2VkX2ludDY0ICAgID0gIDkxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcGFja2VkX3VpbnQzMiAgID0gIDkyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcGFja2VkX3VpbnQ2NCAgID0gIDkzIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcGFja2VkX3NpbnQzMiAgID0gIDk0IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcGFja2VkX3NpbnQ2NCAgID0gIDk1IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgID0gIDk2IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgID0gIDk3IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gIDk4IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gIDk5IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcGFja2VkX2Zsb2F0ICAgID0gMTAwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcGFja2VkX2RvdWJsZSAgID0gMTAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcGFja2VkX2Jvb2wgICAgID0gMTAyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW1MaXRlIHBhY2tlZF9lbnVtICA9IDEwMyBbcGFja2VkID0gdHJ1ZV07Cit9CisKK21lc3NhZ2UgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworZXh0ZW5kIFRlc3RBbGxFeHRlbnNpb25zTGl0ZSB7CisgIC8vIFNpbmd1bGFyCisgIG9wdGlvbmFsICAgIGludDMyIG9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl9saXRlICAgID0gIDE7CisgIG9wdGlvbmFsICAgIGludDY0IG9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbl9saXRlICAgID0gIDI7CisgIG9wdGlvbmFsICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gIDM7CisgIG9wdGlvbmFsICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gIDQ7CisgIG9wdGlvbmFsICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gIDU7CisgIG9wdGlvbmFsICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gIDY7CisgIG9wdGlvbmFsICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgID0gIDc7CisgIG9wdGlvbmFsICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgID0gIDg7CisgIG9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlID0gIDk7CisgIG9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlID0gMTA7CisgIG9wdGlvbmFsICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgID0gMTE7CisgIG9wdGlvbmFsICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgID0gMTI7CisgIG9wdGlvbmFsICAgICBib29sIG9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgID0gMTM7CisgIG9wdGlvbmFsICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgID0gMTQ7CisgIG9wdGlvbmFsICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgID0gMTU7CisKKyAgb3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cF9leHRlbnNpb25fbGl0ZSA9IDE2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gMTc7CisgIH0KKworICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUKKyAgICAgID0gMTg7CisgIG9wdGlvbmFsIEZvcmVpZ25NZXNzYWdlTGl0ZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgPSAxOTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2VMaXRlCisgICAgb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgPSAyMDsKKworICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgPSAyMTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW1MaXRlIG9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSA9IDIyOworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUxpdGUKKyAgICBvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSA9IDIzOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uX2xpdGUgPSAyNAorICAgICAgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkX2V4dGVuc2lvbl9saXRlID0gMjUgW2N0eXBlPUNPUkRdOworCisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlTGl0ZQorICAgIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDI2OworCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZQorICAgIG9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDI3IFtsYXp5PXRydWVdOworCisgIC8vIFJlcGVhdGVkCisgIHJlcGVhdGVkICAgIGludDMyIHJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgID0gMzE7CisgIHJlcGVhdGVkICAgIGludDY0IHJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgID0gMzI7CisgIHJlcGVhdGVkICAgdWludDMyIHJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gMzM7CisgIHJlcGVhdGVkICAgdWludDY0IHJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gMzQ7CisgIHJlcGVhdGVkICAgc2ludDMyIHJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gMzU7CisgIHJlcGVhdGVkICAgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gMzY7CisgIHJlcGVhdGVkICBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgID0gMzc7CisgIHJlcGVhdGVkICBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgID0gMzg7CisgIHJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlID0gMzk7CisgIHJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlID0gNDA7CisgIHJlcGVhdGVkICAgIGZsb2F0IHJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgID0gNDE7CisgIHJlcGVhdGVkICAgZG91YmxlIHJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgID0gNDI7CisgIHJlcGVhdGVkICAgICBib29sIHJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgID0gNDM7CisgIHJlcGVhdGVkICAgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgID0gNDQ7CisgIHJlcGVhdGVkICAgIGJ5dGVzIHJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgID0gNDU7CisKKyAgcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cF9leHRlbnNpb25fbGl0ZSA9IDQ2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gNDc7CisgIH0KKworICByZXBlYXRlZCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUKKyAgICAgID0gNDg7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlTGl0ZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgPSA0OTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2VMaXRlCisgICAgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgPSA1MDsKKworICByZXBlYXRlZCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW1MaXRlIHJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUxpdGUKKyAgICByZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSA9IDUzOworCisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uX2xpdGUgPSA1NAorICAgICAgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkX2V4dGVuc2lvbl9saXRlID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZQorICAgIHJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDU3IFtsYXp5PXRydWVdOworCisgIC8vIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKKyAgb3B0aW9uYWwgICAgaW50MzIgZGVmYXVsdF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICA9IDYxIFtkZWZhdWx0ID0gIDQxICAgIF07CisgIG9wdGlvbmFsICAgIGludDY0IGRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAgPSA2MiBbZGVmYXVsdCA9ICA0MiAgICBdOworICBvcHRpb25hbCAgIHVpbnQzMiBkZWZhdWx0X3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gNjMgW2RlZmF1bHQgPSAgNDMgICAgXTsKKyAgb3B0aW9uYWwgICB1aW50NjQgZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICA9IDY0IFtkZWZhdWx0ID0gIDQ0ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDMyIGRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAgPSA2NSBbZGVmYXVsdCA9IC00NSAgICBdOworICBvcHRpb25hbCAgIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gNjYgW2RlZmF1bHQgPSAgNDYgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICA9IDY3IFtkZWZhdWx0ID0gIDQ3ICAgIF07CisgIG9wdGlvbmFsICBmaXhlZDY0IGRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAgPSA2OCBbZGVmYXVsdCA9ICA0OCAgICBdOworICBvcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlID0gNjkgW2RlZmF1bHQgPSAgNDkgICAgXTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSA9IDcwIFtkZWZhdWx0ID0gLTUwICAgIF07CisgIG9wdGlvbmFsICAgIGZsb2F0IGRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAgPSA3MSBbZGVmYXVsdCA9ICA1MS41ICBdOworICBvcHRpb25hbCAgIGRvdWJsZSBkZWZhdWx0X2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgID0gNzIgW2RlZmF1bHQgPSAgNTJlMyAgXTsKKyAgb3B0aW9uYWwgICAgIGJvb2wgZGVmYXVsdF9ib29sX2V4dGVuc2lvbl9saXRlICAgICA9IDczIFtkZWZhdWx0ID0gdHJ1ZSAgIF07CisgIG9wdGlvbmFsICAgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOworICBvcHRpb25hbCAgICBieXRlcyBkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbl9saXRlICAgID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTsKKworICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlLk5lc3RlZEVudW0KKyAgICBkZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlID0gODEgW2RlZmF1bHQgPSBCQVJdOworICBvcHRpb25hbCBGb3JlaWduRW51bUxpdGUKKyAgICBkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSA9IDgyIFtkZWZhdWx0ID0gRk9SRUlHTl9MSVRFX0JBUl07CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtTGl0ZQorICAgIGRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgPSA4MyBbZGVmYXVsdCA9IElNUE9SVF9MSVRFX0JBUl07CisKKyAgb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl9saXRlID0gODQgW2N0eXBlPVNUUklOR19QSUVDRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9ImFiYyJdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkX2V4dGVuc2lvbl9saXRlID0gODUgW2N0eXBlPUNPUkQsIGRlZmF1bHQ9IjEyMyJdOworCisgIC8vIEZvciBvbmVvZiB0ZXN0CisgIG9wdGlvbmFsIHVpbnQzMiBvbmVvZl91aW50MzJfZXh0ZW5zaW9uX2xpdGUgPSAxMTE7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDExMjsKKyAgb3B0aW9uYWwgc3RyaW5nIG9uZW9mX3N0cmluZ19leHRlbnNpb25fbGl0ZSA9IDExMzsKKyAgb3B0aW9uYWwgYnl0ZXMgb25lb2ZfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgPSAxMTQ7Cit9CisKK21lc3NhZ2UgVGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworZXh0ZW5kIFRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSB7CisgIHJlcGVhdGVkICAgIGludDMyIHBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICA9ICA5MCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGludDY0IHBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICA9ICA5MSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDMyIHBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICA9ICA5MiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDY0IHBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICA9ICA5MyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDMyIHBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICA9ICA5NCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDY0IHBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICA9ICA5NSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDMyIHBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICA9ICA5NiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDY0IHBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICA9ICA5NyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSA9ICA5OCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSA9ICA5OSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGZsb2F0IHBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICA9IDEwMCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgZG91YmxlIHBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICA9IDEwMSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgICBib29sIHBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICA9IDEwMiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtTGl0ZSBwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07Cit9CisKK21lc3NhZ2UgVGVzdE5lc3RlZEV4dGVuc2lvbkxpdGUgeworICBleHRlbmQgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIHsKKyAgICBvcHRpb25hbCBpbnQzMiBuZXN0ZWRfZXh0ZW5zaW9uID0gMTIzNDU7CisgIH0KK30KKworLy8gVGVzdCB0aGF0IGRlcHJlY2F0ZWQgZmllbGRzIHdvcmsuICBXZSBvbmx5IHZlcmlmeSB0aGF0IHRoZXkgY29tcGlsZSAoYXQgb25lCisvLyBwb2ludCB0aGlzIGZhaWxlZCkuCittZXNzYWdlIFRlc3REZXByZWNhdGVkTGl0ZSB7CisgIG9wdGlvbmFsIGludDMyIGRlcHJlY2F0ZWRfZmllbGQgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07Cit9CisKKy8vIFNlZSB0aGUgY29tbWVudHMgb2YgdGhlIHNhbWUgdHlwZSBpbiB1bml0dGVzdC5wcm90by4KK21lc3NhZ2UgVGVzdFBhcnNpbmdNZXJnZUxpdGUgeworICBtZXNzYWdlIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXNMaXRlIGZpZWxkMSA9IDE7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzTGl0ZSBmaWVsZDIgPSAyOworICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUgZmllbGQzID0gMzsKKyAgICByZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7CisgICAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlIGZpZWxkMSA9IDExOworICAgIH0KKyAgICByZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7CisgICAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlIGZpZWxkMSA9IDIxOworICAgIH0KKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXNMaXRlIGV4dDEgPSAxMDAwOworICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUgZXh0MiA9IDEwMDE7CisgIH0KKyAgcmVxdWlyZWQgVGVzdEFsbFR5cGVzTGl0ZSByZXF1aXJlZF9hbGxfdHlwZXMgPSAxOworICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzsKKyAgb3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDEwIHsKKyAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOworICB9CisgIHJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7CisgICAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzTGl0ZSByZXBlYXRlZF9ncm91cF9hbGxfdHlwZXMgPSAyMTsKKyAgfQorICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworICBleHRlbmQgVGVzdFBhcnNpbmdNZXJnZUxpdGUgeworICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUgb3B0aW9uYWxfZXh0ID0gMTAwMDsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXNMaXRlIHJlcGVhdGVkX2V4dCA9IDEwMDE7CisgIH0KK30KKworLy8gVGVzdEVtcHR5TWVzc2FnZUxpdGUgaXMgdXNlZCB0byB0ZXN0IHVua25vd24gZmllbGRzIHN1cHBvcnQgaW4gbGl0ZSBtb2RlLgorbWVzc2FnZSBUZXN0RW1wdHlNZXNzYWdlTGl0ZXsKK30KKworLy8gTGlrZSBhYm92ZSwgYnV0IGRlY2xhcmUgYWxsIGZpZWxkIG51bWJlcnMgYXMgcG90ZW50aWFsIGV4dGVuc2lvbnMuICBObworLy8gYWN0dWFsIGV4dGVuc2lvbnMgc2hvdWxkIGV2ZXIgYmUgZGVmaW5lZCBmb3IgdGhpcyB0eXBlLgorbWVzc2FnZSBUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNMaXRlIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGVfaW1wb3J0c19ub25saXRlLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzMmQ2YTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGVfaW1wb3J0c19ub25saXRlLnByb3RvCkBAIC0wLDAgKzEsNDQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gVGVzdHMgdGhhdCBhICJsaXRlIiBtZXNzYWdlIGNhbiBpbXBvcnQgYSByZWd1bGFyIG1lc3NhZ2UuCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iOworCitvcHRpb24gb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FOworCittZXNzYWdlIFRlc3RMaXRlSW1wb3J0c05vbmxpdGUgeworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2FhMzFmYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90bwpAQCAtMCwwICsxLDg1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG1lc3NhZ2VzIGZvciB0ZXN0aW5nIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0LgorCitzeW50YXggPSAicHJvdG8yIjsKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworLy8gQSBtZXNzYWdlIHdpdGggbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQuCittZXNzYWdlIFRlc3RNZXNzYWdlU2V0IHsKKyAgb3B0aW9uIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gdHJ1ZTsKKyAgZXh0ZW5zaW9ucyA0IHRvIG1heDsKK30KKworbWVzc2FnZSBUZXN0TWVzc2FnZVNldENvbnRhaW5lciB7CisgIG9wdGlvbmFsIFRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTsKK30KKworbWVzc2FnZSBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgeworICBleHRlbmQgVGVzdE1lc3NhZ2VTZXQgeworICAgIG9wdGlvbmFsIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBtZXNzYWdlX3NldF9leHRlbnNpb24gPSAxNTQ1MDA4OworICB9CisgIG9wdGlvbmFsIGludDMyIGkgPSAxNTsKK30KKworbWVzc2FnZSBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgeworICBleHRlbmQgVGVzdE1lc3NhZ2VTZXQgeworICAgIG9wdGlvbmFsIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBtZXNzYWdlX3NldF9leHRlbnNpb24gPSAxNTQ3NzY5OworICB9CisgIG9wdGlvbmFsIHN0cmluZyBzdHIgPSAyNTsKK30KKworLy8gVGhpcyBtZXNzYWdlIHdhcyB1c2VkIHRvIGdlbmVyYXRlCisvLyAvL25ldC9wcm90bzIvcHl0aG9uL2ludGVybmFsL3Rlc3RkYXRhL21lc3NhZ2Vfc2V0X21lc3NhZ2UsIGJ1dCBpcyBjb21tZW50ZWQKKy8vIG91dCBzaW5jZSBpdCBtdXN0IG5vdCBhY3R1YWxseSBleGlzdCBpbiBjb2RlLCB0byBzaW11bGF0ZSBhbiAidW5rbm93biIKKy8vIGV4dGVuc2lvbi4KKy8vIG1lc3NhZ2UgVGVzdE1lc3NhZ2VTZXRVbmtub3duRXh0ZW5zaW9uIHsKKy8vICAgZXh0ZW5kIFRlc3RNZXNzYWdlU2V0IHsKKy8vICAgICBvcHRpb25hbCBUZXN0TWVzc2FnZVNldFVua25vd25FeHRlbnNpb24gbWVzc2FnZV9zZXRfZXh0ZW5zaW9uID0gNTYxNDE0MjE7CisvLyAgIH0KKy8vICAgb3B0aW9uYWwgaW50NjQgYSA9IDE7CisvLyB9CisKKy8vIE1lc3NhZ2VTZXQgd2lyZSBmb3JtYXQgaXMgZXF1aXZhbGVudCB0byB0aGlzLgorbWVzc2FnZSBSYXdNZXNzYWdlU2V0IHsKKyAgcmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeworICAgIHJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOworICAgIHJlcXVpcmVkIGJ5dGVzIG1lc3NhZ2UgPSAzOworICB9Cit9CisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2ZmI4NjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hLnByb3RvCkBAIC0wLDAgKzEsMjAxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBwcm90byBmaWxlIGNvbnRhaW5zIGNvcGllcyBvZiBUZXN0QWxsVHlwZXMgYW5kIGZyaWVuZHMsIGJ1dCB3aXRoIGFyZW5hCisvLyBzdXBwb3J0IGRpc2FibGVkIGluIGNvZGUgZ2VuZXJhdGlvbi4gSXQgYWxsb3dzIHVzIHRvIHRlc3QgdGhlIHBlcmZvcm1hbmNlCisvLyBpbXBhY3QgYWdhaW5zdCBiYXNlbGluZSAobm9uLWFyZW5hKSBnb29nbGUucHJvdG9idWYuCisKK3N5bnRheCA9ICJwcm90bzIiOworCisvLyBTb21lIGdlbmVyaWNfc2VydmljZXMgb3B0aW9uKHMpIGFkZGVkIGF1dG9tYXRpY2FsbHkuCisvLyBTZWU6ICBodHRwOi8vZ28vcHJvdG8yLWdlbmVyaWMtc2VydmljZXMtZGVmYXVsdAorb3B0aW9uIGNjX2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOyAgICAgLy8gYXV0by1hZGRlZAorb3B0aW9uIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgLy8gYXV0by1hZGRlZAorb3B0aW9uIHB5X2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOyAgICAgLy8gYXV0by1hZGRlZAorb3B0aW9uIGNjX2VuYWJsZV9hcmVuYXMgPSBmYWxzZTsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2FyZW5hLnByb3RvIjsKKworLy8gV2UgZG9uJ3QgcHV0IHRoaXMgaW4gYSBwYWNrYWdlIHdpdGhpbiBwcm90bzIgYmVjYXVzZSB3ZSBuZWVkIHRvIG1ha2Ugc3VyZQorLy8gdGhhdCB0aGUgZ2VuZXJhdGVkIGNvZGUgZG9lc24ndCBkZXBlbmQgb24gYmVpbmcgaW4gdGhlIHByb3RvMiBuYW1lc3BhY2UuCisvLyBJbiB0ZXN0X3V0aWwuaCB3ZSBkbyAidXNpbmcgbmFtZXNwYWNlIHVuaXR0ZXN0ID0gcHJvdG9idWZfdW5pdHRlc3QiLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9ub19hcmVuYTsKKworLy8gUHJvdG9zIG9wdGltaXplZCBmb3IgU1BFRUQgdXNlIGEgc3RyaWN0IHN1cGVyc2V0IG9mIHRoZSBnZW5lcmF0ZWQgY29kZQorLy8gb2YgZXF1aXZhbGVudCBvbmVzIG9wdGltaXplZCBmb3IgQ09ERV9TSVpFLCBzbyB3ZSBzaG91bGQgb3B0aW1pemUgYWxsIG91cgorLy8gdGVzdHMgZm9yIHNwZWVkIHVubGVzcyBleHBsaWNpdGx5IHRlc3RpbmcgY29kZSBzaXplIG9wdGltaXphdGlvbi4KK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlVuaXR0ZXN0UHJvdG8iOworCisvLyBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKKy8vIGZvcm1zLgorbWVzc2FnZSBUZXN0QWxsVHlwZXMgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIC8vIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCisgICAgLy8gYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KKyAgICAvLyBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgICBvcHRpb25hbCBpbnQzMiBiYiA9IDE7CisgIH0KKworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDE7CisgICAgQkFSID0gMjsKKyAgICBCQVogPSAzOworICAgIE5FRyA9IC0xOyAgLy8gSW50ZW50aW9uYWxseSBuZWdhdGl2ZS4KKyAgfQorCisgIC8vIFNpbmd1bGFyCisgIG9wdGlvbmFsICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7CisgIG9wdGlvbmFsICAgIGludDY0IG9wdGlvbmFsX2ludDY0ICAgID0gIDI7CisgIG9wdGlvbmFsICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMiAgID0gIDM7CisgIG9wdGlvbmFsICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCAgID0gIDQ7CisgIG9wdGlvbmFsICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiAgID0gIDU7CisgIG9wdGlvbmFsICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCAgID0gIDY7CisgIG9wdGlvbmFsICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgID0gIDc7CisgIG9wdGlvbmFsICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgID0gIDg7CisgIG9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gIDk7CisgIG9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7CisgIG9wdGlvbmFsICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgIG9wdGlvbmFsICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgIG9wdGlvbmFsICAgICBib29sIG9wdGlvbmFsX2Jvb2wgICAgID0gMTM7CisgIG9wdGlvbmFsICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyAgID0gMTQ7CisgIG9wdGlvbmFsICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgb3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gMTc7CisgIH0KKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgID0gMTg7CisgIG9wdGlvbmFsIEZvcmVpZ25NZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgID0gMjA7CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9lbnVtICAgICA9IDIxOworICBvcHRpb25hbCBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9lbnVtICAgID0gMjI7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtICAgIG9wdGlvbmFsX2ltcG9ydF9lbnVtICAgICA9IDIzOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgLy8gRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlCisgICAgICBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjsKKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSAyNyBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDQ3OworICB9CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICA9IDQ4OworICByZXBlYXRlZCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICA9IDUwOworCisgIHJlcGVhdGVkIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9uZXN0ZWRfZW51bSAgICAgPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSAgICA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICByZXBlYXRlZF9pbXBvcnRfZW51bSAgICAgPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgLy8gU2luZ3VsYXIgd2l0aCBkZWZhdWx0cworICBvcHRpb25hbCAgICBpbnQzMiBkZWZhdWx0X2ludDMyICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NCAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyICAgPSA2MyBbZGVmYXVsdCA9ICA0MyAgICBdOworICBvcHRpb25hbCAgIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzIgICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0ICAgPSA2NiBbZGVmYXVsdCA9ICA0NiAgICBdOworICBvcHRpb25hbCAgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzIgPSA2OSBbZGVmYXVsdCA9ICA0OSAgICBdOworICBvcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdCAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlICAgPSA3MiBbZGVmYXVsdCA9ICA1MmUzICBdOworICBvcHRpb25hbCAgICAgYm9vbCBkZWZhdWx0X2Jvb2wgICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgICAgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gIGRlZmF1bHRfbmVzdGVkX2VudW0gID0gODEgW2RlZmF1bHQgPSBCQVIgICAgICAgIF07CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtCisgICAgICBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbY3R5cGU9U1RSSU5HX1BJRUNFLGRlZmF1bHQ9ImFiYyJdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2N0eXBlPUNPUkQsZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICAgIE5lc3RlZE1lc3NhZ2UgbGF6eV9vbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExNSBbbGF6eT10cnVlXTsKKyAgfQorfQorCisvLyBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQorLy8gdGhhdC4KK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bSB7CisgIEZPUkVJR05fRk9PID0gNDsKKyAgRk9SRUlHTl9CQVIgPSA1OworICBGT1JFSUdOX0JBWiA9IDY7Cit9CisKK21lc3NhZ2UgVGVzdE5vQXJlbmFNZXNzYWdlIHsKKyAgb3B0aW9uYWwgcHJvdG8yX2FyZW5hX3VuaXR0ZXN0LkFyZW5hTWVzc2FnZSBhcmVuYV9tZXNzYWdlID0gMTsKK307CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2ltcG9ydC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3MmFmNDkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2ltcG9ydC5wcm90bwpAQCAtMCwwICsxLDM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG8yX2FyZW5hX3VuaXR0ZXN0OworCittZXNzYWdlIEltcG9ydE5vQXJlbmFOZXN0ZWRNZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDE7Cit9OwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTA0ZGEwYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucHJvdG8KQEAgLTAsMCArMSwxMzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBIHByb3RvIGZpbGUgdXNlZCB0byB0ZXN0IGEgbWVzc2FnZSB0eXBlIHdpdGggbm8gZXhwbGljaXQgZmllbGQgcHJlc2VuY2UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCisvLyBXZSB3YW50IHRvIHRlc3QgZW1iZWRkZWQgcHJvdG8yIG1lc3NhZ2VzLCBzbyBpbmNsdWRlIHNvbWUgcHJvdG8yIHR5cGVzLgoraW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iOworCitwYWNrYWdlIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q7CisKKy8vIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAorLy8gZm9ybXMuCittZXNzYWdlIFRlc3RBbGxUeXBlcyB7CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgaW50MzIgYmIgPSAxOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAwOworICAgIEJBUiA9IDE7CisgICAgQkFaID0gMjsKKyAgfQorCisgIC8vIFNpbmd1bGFyCisgIC8vIFRPRE86IHJlbW92ZSAnb3B0aW9uYWwnIGxhYmVscyBhcyBzb29uIGFzIENMIDY5MTg4MDc3IGlzIExHVE0nZCB0byBtYWtlCisgIC8vICdvcHRpb25hbCcgb3B0aW9uYWwuCisgIG9wdGlvbmFsICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7CisgIG9wdGlvbmFsICAgIGludDY0IG9wdGlvbmFsX2ludDY0ICAgID0gIDI7CisgIG9wdGlvbmFsICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMiAgID0gIDM7CisgIG9wdGlvbmFsICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCAgID0gIDQ7CisgIG9wdGlvbmFsICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiAgID0gIDU7CisgIG9wdGlvbmFsICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCAgID0gIDY7CisgIG9wdGlvbmFsICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgID0gIDc7CisgIG9wdGlvbmFsICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgID0gIDg7CisgIG9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gIDk7CisgIG9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7CisgIG9wdGlvbmFsICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgIG9wdGlvbmFsICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgIG9wdGlvbmFsICAgICBib29sIG9wdGlvbmFsX2Jvb2wgICAgID0gMTM7CisgIG9wdGlvbmFsICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyAgID0gMTQ7CisgIG9wdGlvbmFsICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDE4OworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyAgICAgICAgIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gMjA7CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9lbnVtICAgICA9IDIxOworICBvcHRpb25hbCBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9lbnVtICAgID0gMjI7CisgIC8vIE4uQi46IHByb3RvMi1lbnVtLXR5cGUgZmllbGRzIG5vdCBhbGxvd2VkLCBiZWNhdXNlIHRoZWlyIGRlZmF1bHQgdmFsdWVzCisgIC8vIG1pZ2h0IG5vdCBiZSB6ZXJvLgorICAvL29wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtICAgICAgICAgIG9wdGlvbmFsX3Byb3RvMl9lbnVtICAgICA9IDIzOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAzMCBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAgPSA0ODsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgICAgICAgICByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSAgPSA1MDsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfbmVzdGVkX2VudW0gICAgID0gNTE7CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9mb3JlaWduX2VudW0gICAgPSA1MjsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIE5lc3RlZEVudW0gb25lb2ZfZW51bSA9IDExNDsKKyAgfQorfQorCittZXNzYWdlIFRlc3RQcm90bzJSZXF1aXJlZCB7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBwcm90bzIgPSAxOworfQorCisvLyBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQorLy8gdGhhdC4KK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bSB7CisgIEZPUkVJR05fRk9PID0gMDsKKyAgRk9SRUlHTl9CQVIgPSAxOworICBGT1JFSUdOX0JBWiA9IDI7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGZjNzcxMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wcm90bwpAQCAtMCwwICsxLDU0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCitzeW50YXggPSAicHJvdG8yIjsKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdDsKKworCisvLyAqX2dlbmVyaWNfc2VydmljZXMgYXJlIGZhbHNlIGJ5IGRlZmF1bHQuCisKK21lc3NhZ2UgVGVzdE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBhID0gMTsKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KKworZW51bSBUZXN0RW51bSB7CisgIEZPTyA9IDE7Cit9CisKK2V4dGVuZCBUZXN0TWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIHRlc3RfZXh0ZW5zaW9uID0gMTAwMDsKK30KKworc2VydmljZSBUZXN0U2VydmljZSB7CisgIHJwYyBGb28oVGVzdE1lc3NhZ2UpIHJldHVybnMoVGVzdE1lc3NhZ2UpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTljYzdiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8KQEAgLTAsMCArMSw2NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEEgcHJvdG8gZmlsZSB3aGljaCB1c2VzIG9wdGltaXplX2ZvciA9IENPREVfU0laRS4KKworc3ludGF4ID0gInByb3RvMiI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkU7CisKK21lc3NhZ2UgVGVzdE9wdGltaXplZEZvclNpemUgeworICBvcHRpb25hbCBpbnQzMiBpID0gMTsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7CisKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKKworICBleHRlbmQgVGVzdE9wdGltaXplZEZvclNpemUgeworICAgIG9wdGlvbmFsIGludDMyIHRlc3RfZXh0ZW5zaW9uID0gMTIzNDsKKyAgICBvcHRpb25hbCBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHRlc3RfZXh0ZW5zaW9uMiA9IDEyMzU7CisgIH0KKworICBvbmVvZiBmb28geworICAgIGludDMyIGludGVnZXJfZmllbGQgPSAyOworICAgIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOworICB9Cit9CisKK21lc3NhZ2UgVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSB7CisgIHJlcXVpcmVkIGludDMyIHggPSAxOworfQorCittZXNzYWdlIFRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUgeworICBvcHRpb25hbCBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIG8gPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42N2U1NzQ5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucHJvdG8KQEAgLTAsMCArMSw2OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q7CisKK2VudW0gTXlFbnVtIHsKKyAgRk9PID0gMDsKKyAgQkFSID0gMTsKKyAgQkFaID0gMjsKK30KKworZW51bSBNeUVudW1QbHVzRXh0cmEgeworICBFX0ZPTyA9IDA7CisgIEVfQkFSID0gMTsKKyAgRV9CQVogPSAyOworICBFX0VYVFJBID0gMzsKK30KKworbWVzc2FnZSBNeU1lc3NhZ2UgeworICBvcHRpb25hbCBNeUVudW0gZSA9IDE7CisgIHJlcGVhdGVkIE15RW51bSByZXBlYXRlZF9lID0gMjsKKyAgcmVwZWF0ZWQgTXlFbnVtIHJlcGVhdGVkX3BhY2tlZF9lID0gMyBbcGFja2VkPXRydWVdOworICByZXBlYXRlZCBNeUVudW1QbHVzRXh0cmEgcmVwZWF0ZWRfcGFja2VkX3VuZXhwZWN0ZWRfZSA9IDQ7ICAvLyBub3QgcGFja2VkCisgIG9uZW9mIG8geworICAgIE15RW51bSBvbmVvZl9lXzEgPSA1OworICAgIE15RW51bSBvbmVvZl9lXzIgPSA2OworICB9Cit9CisKK21lc3NhZ2UgTXlNZXNzYWdlUGx1c0V4dHJhIHsKKyAgb3B0aW9uYWwgTXlFbnVtUGx1c0V4dHJhIGUgPSAxOworICByZXBlYXRlZCBNeUVudW1QbHVzRXh0cmEgcmVwZWF0ZWRfZSA9IDI7CisgIHJlcGVhdGVkIE15RW51bVBsdXNFeHRyYSByZXBlYXRlZF9wYWNrZWRfZSA9IDMgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgTXlFbnVtUGx1c0V4dHJhIHJlcGVhdGVkX3BhY2tlZF91bmV4cGVjdGVkX2UgPSA0IFtwYWNrZWQ9dHJ1ZV07CisgIG9uZW9mIG8geworICAgIE15RW51bVBsdXNFeHRyYSBvbmVvZl9lXzEgPSA1OworICAgIE15RW51bVBsdXNFeHRyYSBvbmVvZl9lXzIgPSA2OworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bTIucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bTIucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWRmNDI5NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wcm90bwpAQCAtMCwwICsxLDUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG8yX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDsKKworZW51bSBNeUVudW0geworICBGT08gPSAwOworICBCQVIgPSAxOworICBCQVogPSAyOworfQorCittZXNzYWdlIE15TWVzc2FnZSB7CisgIG9wdGlvbmFsIE15RW51bSBlID0gMTsKKyAgcmVwZWF0ZWQgTXlFbnVtIHJlcGVhdGVkX2UgPSAyOworICByZXBlYXRlZCBNeUVudW0gcmVwZWF0ZWRfcGFja2VkX2UgPSAzIFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIE15RW51bSByZXBlYXRlZF9wYWNrZWRfdW5leHBlY3RlZF9lID0gNDsgIC8vIG5vdCBwYWNrZWQKKyAgb25lb2YgbyB7CisgICAgTXlFbnVtIG9uZW9mX2VfMSA9IDU7CisgICAgTXlFbnVtIG9uZW9mX2VfMiA9IDY7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfYXJlbmEucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmQ3YmFkYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvCkBAIC0wLDAgKzEsMTg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvIjsKKworcGFja2FnZSBwcm90bzNfYXJlbmFfdW5pdHRlc3Q7CisKKy8vIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAorLy8gZm9ybXMuCittZXNzYWdlIFRlc3RBbGxUeXBlcyB7CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgLy8gVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKKyAgICAvLyBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgorICAgIC8vIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgorICAgIG9wdGlvbmFsIGludDMyIGJiID0gMTsKKyAgfQorCisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgWkVSTyA9IDA7CisgICAgRk9PID0gMTsKKyAgICBCQVIgPSAyOworICAgIEJBWiA9IDM7CisgICAgTkVHID0gLTE7ICAvLyBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgorICB9CisKKyAgLy8gU2luZ3VsYXIKKyAgb3B0aW9uYWwgICAgaW50MzIgb3B0aW9uYWxfaW50MzIgICAgPSAgMTsKKyAgb3B0aW9uYWwgICAgaW50NjQgb3B0aW9uYWxfaW50NjQgICAgPSAgMjsKKyAgb3B0aW9uYWwgICB1aW50MzIgb3B0aW9uYWxfdWludDMyICAgPSAgMzsKKyAgb3B0aW9uYWwgICB1aW50NjQgb3B0aW9uYWxfdWludDY0ICAgPSAgNDsKKyAgb3B0aW9uYWwgICBzaW50MzIgb3B0aW9uYWxfc2ludDMyICAgPSAgNTsKKyAgb3B0aW9uYWwgICBzaW50NjQgb3B0aW9uYWxfc2ludDY0ICAgPSAgNjsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiAgPSAgNzsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCAgPSAgODsKKyAgb3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSAgOTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDsKKyAgb3B0aW9uYWwgICAgZmxvYXQgb3B0aW9uYWxfZmxvYXQgICAgPSAxMTsKKyAgb3B0aW9uYWwgICBkb3VibGUgb3B0aW9uYWxfZG91YmxlICAgPSAxMjsKKyAgb3B0aW9uYWwgICAgIGJvb2wgb3B0aW9uYWxfYm9vbCAgICAgPSAxMzsKKyAgb3B0aW9uYWwgICBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nICAgPSAxNDsKKyAgb3B0aW9uYWwgICAgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgICAgPSAxNTsKKworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSAxNzsKKyAgfQorCisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgPSAxODsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgPSAyMDsKKworICBvcHRpb25hbCBOZXN0ZWRFbnVtICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfbmVzdGVkX2VudW0gICAgID0gMjE7CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9mb3JlaWduX2VudW0gICAgPSAyMjsKKworICAvLyBPbWl0dGVkIChjb21wYXJlZCB0byB1bml0dGVzdC5wcm90bykgYmVjYXVzZSBwcm90bzIgZW51bXMgYXJlIG5vdCBhbGxvd2VkCisgIC8vIGluc2lkZSBwcm90bzIgbWVzc2FnZXMuCisgIC8vCisgIC8vIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtICAgIG9wdGlvbmFsX2ltcG9ydF9lbnVtICA9IDIzOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgLy8gRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlCisgICAgICBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjsKKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5PXRydWVdOworCisgIC8vIFJlcGVhdGVkCisgIHJlcGVhdGVkICAgIGludDMyIHJlcGVhdGVkX2ludDMyICAgID0gMzE7CisgIHJlcGVhdGVkICAgIGludDY0IHJlcGVhdGVkX2ludDY0ICAgID0gMzI7CisgIHJlcGVhdGVkICAgdWludDMyIHJlcGVhdGVkX3VpbnQzMiAgID0gMzM7CisgIHJlcGVhdGVkICAgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCAgID0gMzQ7CisgIHJlcGVhdGVkICAgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiAgID0gMzU7CisgIHJlcGVhdGVkICAgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCAgID0gMzY7CisgIHJlcGVhdGVkICBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgID0gMzc7CisgIHJlcGVhdGVkICBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgID0gMzg7CisgIHJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7CisgIHJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7CisgIHJlcGVhdGVkICAgIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ICAgID0gNDE7CisgIHJlcGVhdGVkICAgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSAgID0gNDI7CisgIHJlcGVhdGVkICAgICBib29sIHJlcGVhdGVkX2Jvb2wgICAgID0gNDM7CisgIHJlcGVhdGVkICAgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyAgID0gNDQ7CisgIHJlcGVhdGVkICAgIGJ5dGVzIHJlcGVhdGVkX2J5dGVzICAgID0gNDU7CisKKyAgcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gNDc7CisgIH0KKworICByZXBlYXRlZCBOZXN0ZWRNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgID0gNDg7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgID0gNTA7CisKKyAgcmVwZWF0ZWQgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9lbnVtICAgICA9IDUxOworICByZXBlYXRlZCBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9lbnVtICAgID0gNTI7CisKKyAgLy8gT21pdHRlZCAoY29tcGFyZWQgdG8gdW5pdHRlc3QucHJvdG8pIGJlY2F1c2UgcHJvdG8yIGVudW1zIGFyZSBub3QgYWxsb3dlZAorICAvLyBpbnNpZGUgcHJvdG8yIG1lc3NhZ2VzLgorICAvLworICAvLyByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICByZXBlYXRlZF9pbXBvcnRfZW51bSAgPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICB9Cit9CisKKy8vIFRlc3QgbWVzc2FnZXMgZm9yIHBhY2tlZCBmaWVsZHMKKworbWVzc2FnZSBUZXN0UGFja2VkVHlwZXMgeworICByZXBlYXRlZCAgICBpbnQzMiBwYWNrZWRfaW50MzIgICAgPSAgOTAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBpbnQ2NCBwYWNrZWRfaW50NjQgICAgPSAgOTEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQzMiBwYWNrZWRfdWludDMyICAgPSAgOTIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQ2NCBwYWNrZWRfdWludDY0ICAgPSAgOTMgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQzMiBwYWNrZWRfc2ludDMyICAgPSAgOTQgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQ2NCBwYWNrZWRfc2ludDY0ICAgPSAgOTUgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiAgPSAgOTYgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCAgPSAgOTcgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSAgOTggW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSAgOTkgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBmbG9hdCBwYWNrZWRfZmxvYXQgICAgPSAxMDAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIGRvdWJsZSBwYWNrZWRfZG91YmxlICAgPSAxMDEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICAgYm9vbCBwYWNrZWRfYm9vbCAgICAgPSAxMDIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBGb3JlaWduRW51bSBwYWNrZWRfZW51bSAgPSAxMDMgW3BhY2tlZCA9IHRydWVdOworfQorCisvLyBUaGlzIHByb3RvIGluY2x1ZGVzIGEgcmVjdXNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KK21lc3NhZ2UgTmVzdGVkVGVzdEFsbFR5cGVzIHsKKyAgTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTsKKyAgVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOworfQorCisvLyBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQorLy8gdGhhdC4KK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bSB7CisgIEZPUkVJR05fWkVSTyA9IDA7CisgIEZPUkVJR05fRk9PID0gNDsKKyAgRk9SRUlHTl9CQVIgPSA1OworICBGT1JFSUdOX0JBWiA9IDY7Cit9CisKKy8vIFRlc3RFbXB0eU1lc3NhZ2UgaXMgdXNlZCB0byB0ZXN0IGJlaGF2aW9yIG9mIHVua25vd24gZmllbGRzLgorbWVzc2FnZSBUZXN0RW1wdHlNZXNzYWdlIHsKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2VudW1faW1wbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2VudW1faW1wbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5YzEwY2IKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZW51bV9pbXBsLmgKQEAgLTAsMCArMSwxNTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VVElMX1VOS05PV05fRU5VTV9JTVBMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9VTktOT1dOX0VOVU1fSU1QTF9IX18KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgIm5ldC9wcm90by90YWdtYXBwZXIuaCIKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYnJpZGdlL2NvbXBhdGliaWxpdHlfbW9kZV9zdXBwb3J0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaAorY2xhc3MgTWVzc2FnZTsKKworbmFtZXNwYWNlIHV0aWwgeworCisvLyBOT1RFOiBZb3Ugc2hvdWxkIG5vdCBjYWxsIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseS4gIEluc3RlYWQgdXNlIGVpdGhlcgorLy8gSEFTX1VOS05PV05fRU5VTSgpIG9yIEdFVF9VTktOT1dOX0VOVU0oKSwgZGVmaW5lZCBpbiB0aGUgcHVibGljIGhlYWRlci4KKy8vIFRoZSBtYWNyby12ZXJzaW9ucyBvcGVyYXRlIGluIGEgdHlwZS1zYWZlIG1hbm5lciBhbmQgYmVoYXZlIGFwcHJvcHJpYXRlbHkKKy8vIGZvciB0aGUgcHJvdG8gdmVyc2lvbiBvZiB0aGUgbWVzc2FnZSwgd2hlcmVhcyB0aGVzZSB2ZXJzaW9ucyBhc3N1bWUgYQorLy8gc3BlY2lmaWMgcHJvdG8gdmVyc2lvbiBhbmQgYWxsb3cgdGhlIGNhbGxlciB0byBwYXNzIGluIGFueSBhcmJpdHJhcnkgaW50ZWdlcgorLy8gdmFsdWUgYXMgYSBmaWVsZCBudW1iZXIuCisvLworLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBtZXNzYWdlIGhhcyB1bnJlY29nbml6ZWQgdGhlIGVudW0gdmFsdWUgZm9yIGEgZ2l2ZW4KKy8vIGZpZWxkLiBJdCBhbHNvIHN0b3JlcyB0aGUgdmFsdWUgaW50byB0aGUgdW5rbm93bl92YWx1ZSBwYXJhbWV0ZXIgaWYgdGhlCisvLyBmdW5jdGlvbiByZXR1cm5zIHRydWUgYW5kIHRoZSBwb2ludGVyIGlzIG5vdCBOVUxMLgorLy8KKy8vIEluIHByb3RvMiwgaW52YWxpZCBlbnVtIHZhbHVlcyB3aWxsIGJlIHRyZWF0ZWQgYXMgdW5rbm93biBmaWVsZHMuIFRoaXMKKy8vIGZ1bmN0aW9uIGNoZWNrcyB0aGF0IGNhc2UuCitib29sIEhhc1Vua25vd25FbnVtKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGludDMyIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgaW50MzIqIHVua25vd25fdmFsdWUgPSBudWxscHRyKTsKKy8vIFNhbWUgYXMgYWJvdmUsIGJ1dCByZXR1cm5zIGFsbCB1bmtub3duIGVudW1zLgorYm9vbCBHZXRSZXBlYXRlZEVudW1Vbmtub3ducyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQzMj4qIHVua25vd25fdmFsdWVzID0gbnVsbHB0cik7CisvLyBJbiBwcm90bzEsIGludmFsdWUgZW51bSB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgc2FtZSB3YXkgYXMgdmFsaWQgZW51bQorLy8gdmFsdWVzLgorLy8gVE9ETyhrYXJuZXIpOiBEZWxldGUgdGhpcyBvbmNlIHRoZSBtaWdyYXRpb24gdG8gcHJvdG8yIGlzIGNvbXBsZXRlLgorYm9vbCBIYXNVbmtub3duRW51bVByb3RvMShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyKiB1bmtub3duX3ZhbHVlKTsKKy8vIFNhbWUgYXMgYWJvdmUsIGJ1dCByZXR1cm5zIGFsbCB1bmtub3duIGVudW1zLgorYm9vbCBHZXRSZXBlYXRlZEVudW1Vbmtub3duc1Byb3RvMShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQzMj4qIHVua25vd25fdmFsdWVzKTsKKy8vIEludm9rZXMgdGhlIGFwcHJvcHJpYXRlIHZlcnNpb24gYmFzZWQgb24gd2hldGhlciB0aGUgbWVzc2FnZSBpcyBwcm90bzEKKy8vIG9yIHByb3RvMi4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorYm9vbCBIYXNVbmtub3duRW51bV9UZW1wbGF0ZShjb25zdCBUJiBtZXNzYWdlLCBpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyKiB1bmtub3duX3ZhbHVlID0gbnVsbHB0cikgeworICBpZiAoaW50ZXJuYWw6OmlzX2Jhc2Vfb2Y8YnJpZGdlOjppbnRlcm5hbDo6UHJvdG8xQ29tcGF0aWJsZU1lc3NhZ2UsIFQ+Ojp2YWx1ZSB8fAorICAgICAgIWludGVybmFsOjppc19iYXNlX29mPFByb3RvY29sTWVzc2FnZSwgVD46OnZhbHVlKSB7CisgICAgcmV0dXJuIEhhc1Vua25vd25FbnVtKG1lc3NhZ2UsIGZpZWxkX251bWJlciwgdW5rbm93bl92YWx1ZSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIEhhc1Vua25vd25FbnVtUHJvdG8xKG1lc3NhZ2UsIGZpZWxkX251bWJlciwgdW5rbm93bl92YWx1ZSk7CisgIH0KK30KKy8vIEludm9rZXMgdGhlIGFwcHJvcHJpYXRlIHZlcnNpb24gYmFzZWQgb24gd2hldGhlciB0aGUgbWVzc2FnZSBpcyBwcm90bzEKKy8vIG9yIHByb3RvMi4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorYm9vbCBHZXRSZXBlYXRlZEVudW1Vbmtub3duc19UZW1wbGF0ZSgKKyAgICBjb25zdCBUJiBtZXNzYWdlLCBpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgdmVjdG9yPGludDMyPiogdW5rbm93bl92YWx1ZXMgPSBudWxscHRyKSB7CisgIGlmIChpbnRlcm5hbDo6aXNfYmFzZV9vZjxicmlkZ2U6OmludGVybmFsOjpQcm90bzFDb21wYXRpYmxlTWVzc2FnZSwgVD46OnZhbHVlIHx8CisgICAgICAhaW50ZXJuYWw6OmlzX2Jhc2Vfb2Y8UHJvdG9jb2xNZXNzYWdlLCBUPjo6dmFsdWUpIHsKKyAgICByZXR1cm4gR2V0UmVwZWF0ZWRFbnVtVW5rbm93bnMobWVzc2FnZSwgZmllbGRfbnVtYmVyLCB1bmtub3duX3ZhbHVlcyk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIEdldFJlcGVhdGVkRW51bVVua25vd25zUHJvdG8xKG1lc3NhZ2UsIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5rbm93bl92YWx1ZXMpOworICB9Cit9CisKKy8vIE5PVEU6IFlvdSBzaG91bGQgbm90IGNhbGwgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5LiAgSW5zdGVhZCB1c2UKKy8vIENMRUFSX1VOS05PV05fRU5VTSgpLCBkZWZpbmVkIGluIHRoZSBwdWJsaWMgaGVhZGVyLiAgVGhlIG1hY3JvLXZlcnNpb25zCisvLyBvcGVyYXRlIGluIGEgdHlwZS1zYWZlIG1hbm5lciBhbmQgYmVoYXZlIGFwcHJvcHJpYXRlbHkgZm9yIHRoZSBwcm90bworLy8gdmVyc2lvbiBvZiB0aGUgbWVzc2FnZSwgd2hlcmVhcyB0aGVzZSB2ZXJzaW9ucyBhc3N1bWUgYSBzcGVjaWZpYyBwcm90bworLy8gdmVyc2lvbiBhbmQgYWxsb3cgdGhlIGNhbGxlciB0byBwYXNzIGluIGFueSBhcmJpdHJhcnkgaW50ZWdlciB2YWx1ZSBhcyBhCisvLyBmaWVsZCBudW1iZXIuCisvLworLy8gQ2xlYXJzIHRoZSB1bmtub3duIGVudHJpZXMgb2YgdGhlIGdpdmVuIGZpZWxkIG9mIHRoZSBtZXNzYWdlLgordm9pZCBDbGVhclVua25vd25FbnVtKE1lc3NhZ2UqIG1lc3NhZ2UsIGludDMyIGZpZWxkX251bWJlcik7CisvLyBJbiBwcm90bzEsIGNsZWFycyB0aGUgZmllbGQgaWYgdGhlIHZhbHVlIGlzIG91dCBvZiByYW5nZS4KKy8vIFRPRE8oa2FybmVyKTogRGVsZXRlIHRoaXMgb3IgbWFrZSBpdCBwcm90bzItb25seSBvbmNlIHRoZSBtaWdyYXRpb24KKy8vIHRvIHByb3RvMiBpcyBjb21wbGV0ZS4KK3ZvaWQgQ2xlYXJVbmtub3duRW51bVByb3RvMShNZXNzYWdlKiBtZXNzYWdlLCBpbnQzMiBmaWVsZF9udW1iZXIpOwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+Cit2b2lkIENsZWFyVW5rbm93bkVudW1fVGVtcGxhdGUoVCogbWVzc2FnZSwgaW50MzIgZmllbGRfbnVtYmVyKSB7CisgIGlmIChpbnRlcm5hbDo6aXNfYmFzZV9vZjxicmlkZ2U6OmludGVybmFsOjpQcm90bzFDb21wYXRpYmxlTWVzc2FnZSwgVD46OnZhbHVlIHx8CisgICAgICAhaW50ZXJuYWw6OmlzX2Jhc2Vfb2Y8UHJvdG9jb2xNZXNzYWdlLCBUPjo6dmFsdWUpIHsKKyAgICBDbGVhclVua25vd25FbnVtKG1lc3NhZ2UsIGZpZWxkX251bWJlcik7CisgIH0gZWxzZSB7CisgICAgQ2xlYXJVbmtub3duRW51bVByb3RvMShtZXNzYWdlLCBmaWVsZF9udW1iZXIpOworICB9Cit9CisKKy8vIE5PVEU6IFlvdSBzaG91bGQgbm90IGNhbGwgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5LiAgSW5zdGVhZCB1c2UKKy8vIFNFVF9VTktOT1dOX0VOVU0oKSwgZGVmaW5lZCBpbiB0aGUgcHVibGljIGhlYWRlci4gIFRoZSBtYWNyby12ZXJzaW9ucworLy8gb3BlcmF0ZSBpbiBhIHR5cGUtc2FmZSBtYW5uZXIgYW5kIGJlaGF2ZSBhcHByb3ByaWF0ZWx5IGZvciB0aGUgcHJvdG8KKy8vIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UsIHdoZXJlYXMgdGhlc2UgdmVyc2lvbnMgYXNzdW1lIGEgc3BlY2lmaWMgcHJvdG8KKy8vIHZlcnNpb24gYW5kIGFsbG93IHRoZSBjYWxsZXIgdG8gcGFzcyBpbiBhbnkgYXJiaXRyYXJ5IGludGVnZXIgdmFsdWUgYXMgYQorLy8gZmllbGQgbnVtYmVyLgorLy8KKy8vIFNldHMgdGhlIGdpdmVuIHZhbHVlIGluIHRoZSB1bmtub3duIGZpZWxkcyBvZiB0aGUgbWVzc2FnZS4KK3ZvaWQgU2V0VW5rbm93bkVudW0oTWVzc2FnZSogbWVzc2FnZSwgaW50MzIgZmllbGRfbnVtYmVyLCBpbnQzMiB1bmtub3duX3ZhbHVlKTsKKy8vIEluIHByb3RvMSwgaW52YWx1ZSBlbnVtIHZhbHVlcyBhcmUgc3RvcmVkIGluIHRoZSBzYW1lIHdheSBhcyB2YWxpZCBlbnVtCisvLyB2YWx1ZXMuCisvLyBUT0RPKGthcm5lcik6IERlbGV0ZSB0aGlzIG9uY2UgdGhlIG1pZ3JhdGlvbiB0byBwcm90bzIgaXMgY29tcGxldGUuCit2b2lkIFNldFVua25vd25FbnVtUHJvdG8xKE1lc3NhZ2UqIG1lc3NhZ2UsIGludDMyIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzIgdW5rbm93bl92YWx1ZSk7CisvLyBJbnZva2VzIHRoZSBhcHByb3ByaWF0ZSB2ZXJzaW9uIGJhc2VkIG9uIHdoZXRoZXIgdGhlIG1lc3NhZ2UgaXMgcHJvdG8xCisvLyBvciBwcm90bzIuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK3ZvaWQgU2V0VW5rbm93bkVudW1fVGVtcGxhdGUoVCogbWVzc2FnZSwgaW50MzIgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMiB1bmtub3duX3ZhbHVlKSB7CisgIGlmIChpbnRlcm5hbDo6aXNfYmFzZV9vZjxicmlkZ2U6OmludGVybmFsOjpQcm90bzFDb21wYXRpYmxlTWVzc2FnZSwgVD46OnZhbHVlIHx8CisgICAgICAhaW50ZXJuYWw6OmlzX2Jhc2Vfb2Y8UHJvdG9jb2xNZXNzYWdlLCBUPjo6dmFsdWUpIHsKKyAgICBTZXRVbmtub3duRW51bShtZXNzYWdlLCBmaWVsZF9udW1iZXIsIHVua25vd25fdmFsdWUpOworICB9IGVsc2UgeworICAgIFNldFVua25vd25FbnVtUHJvdG8xKG1lc3NhZ2UsIGZpZWxkX251bWJlciwgdW5rbm93bl92YWx1ZSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX1VOS05PV05fRU5VTV9JTVBMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2VudW1fdGVzdC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9lbnVtX3Rlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2FhZmFkYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9lbnVtX3Rlc3QucHJvdG8KQEAgLTAsMCArMSw2MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIERlZmluaXRpb25zIG9mIHByb3RvcyBmb3IgdGVzdGluZyBjcm9zcy12ZXJzaW9uIGNvbXBhdGliaWxpdHkuICBUaGUKKy8vIFVwUmV2aXNpb24gbWVzc2FnZSBhY3RzIGFzIGlmIGl0IHdlcmUgYSBuZXdlciB2ZXJzaW9uIG9mIHRoZSBEb3duUmV2aXNpb24KKy8vIG1lc3NhZ2UuICBUaGF0IGlzLCBVcFJldmlzaW9uIHNoYXJlcyBhbGwgdGhlIHNhbWUgZmllbGRzIGFzIERvd25SZXZpc2lvbiwKKy8vIGJ1dCBVcFJldmlzaW9uIGNhbiBhZGQgZmllbGRzIGFuZCBhZGQgZW51bSB2YWx1ZXMuCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYudXRpbDsKKworCittZXNzYWdlIERvd25SZXZpc2lvbiB7CisgIGVudW0gRW51bSB7CisgICAgREVGQVVMVF9WQUxVRSA9IDI7CisgICAgTk9OREVGQVVMVF9WQUxVRSA9IDM7CisgIH0KKworICBvcHRpb25hbCBFbnVtIHZhbHVlID0gMSBbZGVmYXVsdCA9IERFRkFVTFRfVkFMVUVdOworICByZXBlYXRlZCBFbnVtIHZhbHVlcyA9IDI7Cit9CisKK21lc3NhZ2UgVXBSZXZpc2lvbiB7CisgIGVudW0gRW51bSB7CisgICAgREVGQVVMVF9WQUxVRSA9IDI7CisgICAgTk9OREVGQVVMVF9WQUxVRSA9IDM7CisgICAgTkVXX1ZBTFVFID0gNDsKKyAgICBORVdfVkFMVUVfMiA9IDU7CisgICAgTkVXX1ZBTFVFXzMgPSA2OworICB9CisKKyAgb3B0aW9uYWwgRW51bSB2YWx1ZSA9IDEgW2RlZmF1bHQgPSBERUZBVUxUX1ZBTFVFXTsKKyAgcmVwZWF0ZWQgRW51bSB2YWx1ZXMgPSAyOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTE1MjgwYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MKQEAgLTAsMCArMSwzNDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworLy8gVGhpcyBnbG9iYWwgaW5zdGFuY2UgaXMgcmV0dXJuZWQgYnkgdW5rbm93bl9maWVsZHMoKSBvbiBhbnkgbWVzc2FnZSBjbGFzcworLy8gd2hlbiB0aGUgb2JqZWN0IGhhcyBubyB1bmtub3duIGZpZWxkcy4gVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB3ZSBub3cKKy8vIGluc3RhbnRpYXRlIHRoZSBVbmtub3duRmllbGRTZXQgZHluYW1pY2FsbHkgb25seSB3aGVuIHJlcXVpcmVkLgorVW5rbm93bkZpZWxkU2V0KiBkZWZhdWx0X3Vua25vd25fZmllbGRfc2V0X2luc3RhbmNlXyA9IE5VTEw7CisKK3ZvaWQgSW5pdERlZmF1bHRVbmtub3duRmllbGRTZXQoKSB7CisgIGRlZmF1bHRfdW5rbm93bl9maWVsZF9zZXRfaW5zdGFuY2VfID0gbmV3IFVua25vd25GaWVsZFNldCgpOworfQorCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGRlZmF1bHRfdW5rbm93bl9maWVsZF9zZXRfb25jZV9pbml0Xyk7Cit9CisKK2NvbnN0IFVua25vd25GaWVsZFNldCogVW5rbm93bkZpZWxkU2V0OjpkZWZhdWx0X2luc3RhbmNlKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZkZWZhdWx0X3Vua25vd25fZmllbGRfc2V0X29uY2VfaW5pdF8sCisgICAgICAgICAgICAgICAgICZJbml0RGVmYXVsdFVua25vd25GaWVsZFNldCk7CisgIHJldHVybiBkZWZhdWx0X3Vua25vd25fZmllbGRfc2V0X2luc3RhbmNlXzsKK30KKworVW5rbm93bkZpZWxkU2V0OjpVbmtub3duRmllbGRTZXQoKQorICAgIDogZmllbGRzXyhOVUxMKSB7fQorCitVbmtub3duRmllbGRTZXQ6On5Vbmtub3duRmllbGRTZXQoKSB7CisgIENsZWFyKCk7CisgIGRlbGV0ZSBmaWVsZHNfOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6Q2xlYXJGYWxsYmFjaygpIHsKKyAgaWYgKGZpZWxkc18gIT0gTlVMTCkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzXy0+c2l6ZSgpOyBpKyspIHsKKyAgICAgICgqZmllbGRzXylbaV0uRGVsZXRlKCk7CisgICAgfQorICAgIGRlbGV0ZSBmaWVsZHNfOworICAgIGZpZWxkc18gPSBOVUxMOworICB9Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpDbGVhckFuZEZyZWVNZW1vcnkoKSB7CisgIGlmIChmaWVsZHNfICE9IE5VTEwpIHsKKyAgICBDbGVhcigpOworICB9Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpJbnRlcm5hbE1lcmdlRnJvbShjb25zdCBVbmtub3duRmllbGRTZXQmIG90aGVyKSB7CisgIGludCBvdGhlcl9maWVsZF9jb3VudCA9IG90aGVyLmZpZWxkX2NvdW50KCk7CisgIGlmIChvdGhlcl9maWVsZF9jb3VudCA+IDApIHsKKyAgICBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdGhlcl9maWVsZF9jb3VudDsgaSsrKSB7CisgICAgICBmaWVsZHNfLT5wdXNoX2JhY2soKCpvdGhlci5maWVsZHNfKVtpXSk7CisgICAgICBmaWVsZHNfLT5iYWNrKCkuRGVlcENvcHkoKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6Ok1lcmdlRnJvbShjb25zdCBVbmtub3duRmllbGRTZXQmIG90aGVyKSB7CisgIGludCBvdGhlcl9maWVsZF9jb3VudCA9IG90aGVyLmZpZWxkX2NvdW50KCk7CisgIGlmIChvdGhlcl9maWVsZF9jb3VudCA+IDApIHsKKyAgICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdGhlcl9maWVsZF9jb3VudDsgaSsrKSB7CisgICAgICBmaWVsZHNfLT5wdXNoX2JhY2soKCpvdGhlci5maWVsZHNfKVtpXSk7CisgICAgICBmaWVsZHNfLT5iYWNrKCkuRGVlcENvcHkoKTsKKyAgICB9CisgIH0KK30KKworLy8gQSBzcGVjaWFsaXplZCBNZXJnZUZyb20gZm9yIHBlcmZvcm1hbmNlIHdoZW4gd2UgYXJlIG1lcmdpbmcgZnJvbSBhbiBVRlMgdGhhdAorLy8gaXMgdGVtcG9yYXJ5IGFuZCBjYW4gYmUgZGVzdHJveWVkIGluIHRoZSBwcm9jZXNzLgordm9pZCBVbmtub3duRmllbGRTZXQ6Ok1lcmdlRnJvbUFuZERlc3Ryb3koVW5rbm93bkZpZWxkU2V0KiBvdGhlcikgeworICBpbnQgb3RoZXJfZmllbGRfY291bnQgPSBvdGhlci0+ZmllbGRfY291bnQoKTsKKyAgaWYgKG90aGVyX2ZpZWxkX2NvdW50ID4gMCkgeworICAgIGlmIChmaWVsZHNfID09IE5VTEwpIGZpZWxkc18gPSBuZXcgdmVjdG9yPFVua25vd25GaWVsZD4oKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG90aGVyX2ZpZWxkX2NvdW50OyBpKyspIHsKKyAgICAgIGZpZWxkc18tPnB1c2hfYmFjaygoKm90aGVyLT5maWVsZHNfKVtpXSk7CisgICAgICAoKm90aGVyLT5maWVsZHNfKVtpXS5SZXNldCgpOworICAgIH0KKyAgfQorICBkZWxldGUgb3RoZXItPmZpZWxkc187CisgIG90aGVyLT5maWVsZHNfID0gTlVMTDsKK30KKworaW50IFVua25vd25GaWVsZFNldDo6U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpIGNvbnN0IHsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgcmV0dXJuIDA7CisKKyAgaW50IHRvdGFsX3NpemUgPSBzaXplb2YoKmZpZWxkc18pICsgc2l6ZW9mKFVua25vd25GaWVsZCkgKiBmaWVsZHNfLT5zaXplKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHNfLT5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSAoKmZpZWxkc18pW2ldOworICAgIHN3aXRjaCAoZmllbGQudHlwZSgpKSB7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgICB0b3RhbF9zaXplICs9IHNpemVvZigqZmllbGQubGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXykgKworICAgICAgICAgICAgICAgICAgICAgIGludGVybmFsOjpTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKAorICAgICAgICAgICAgICAgICAgICAgICAgICAqZmllbGQubGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6CisgICAgICAgIHRvdGFsX3NpemUgKz0gZmllbGQuZ3JvdXBfLT5TcGFjZVVzZWQoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK2ludCBVbmtub3duRmllbGRTZXQ6OlNwYWNlVXNlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIHNpemVvZigqdGhpcykgKyBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpBZGRWYXJpbnQoaW50IG51bWJlciwgdWludDY0IHZhbHVlKSB7CisgIFVua25vd25GaWVsZCBmaWVsZDsKKyAgZmllbGQubnVtYmVyXyA9IG51bWJlcjsKKyAgZmllbGQuU2V0VHlwZShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5UKTsKKyAgZmllbGQudmFyaW50XyA9IHZhbHVlOworICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgIGZpZWxkc18tPnB1c2hfYmFjayhmaWVsZCk7Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpBZGRGaXhlZDMyKGludCBudW1iZXIsIHVpbnQzMiB2YWx1ZSkgeworICBVbmtub3duRmllbGQgZmllbGQ7CisgIGZpZWxkLm51bWJlcl8gPSBudW1iZXI7CisgIGZpZWxkLlNldFR5cGUoVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVEMzIpOworICBmaWVsZC5maXhlZDMyXyA9IHZhbHVlOworICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgIGZpZWxkc18tPnB1c2hfYmFjayhmaWVsZCk7Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpBZGRGaXhlZDY0KGludCBudW1iZXIsIHVpbnQ2NCB2YWx1ZSkgeworICBVbmtub3duRmllbGQgZmllbGQ7CisgIGZpZWxkLm51bWJlcl8gPSBudW1iZXI7CisgIGZpZWxkLlNldFR5cGUoVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVENjQpOworICBmaWVsZC5maXhlZDY0XyA9IHZhbHVlOworICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgIGZpZWxkc18tPnB1c2hfYmFjayhmaWVsZCk7Cit9CisKK3N0cmluZyogVW5rbm93bkZpZWxkU2V0OjpBZGRMZW5ndGhEZWxpbWl0ZWQoaW50IG51bWJlcikgeworICBVbmtub3duRmllbGQgZmllbGQ7CisgIGZpZWxkLm51bWJlcl8gPSBudW1iZXI7CisgIGZpZWxkLlNldFR5cGUoVW5rbm93bkZpZWxkOjpUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICBmaWVsZC5sZW5ndGhfZGVsaW1pdGVkXy5zdHJpbmdfdmFsdWVfID0gbmV3IHN0cmluZzsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgZmllbGRzXyA9IG5ldyB2ZWN0b3I8VW5rbm93bkZpZWxkPigpOworICBmaWVsZHNfLT5wdXNoX2JhY2soZmllbGQpOworICByZXR1cm4gZmllbGQubGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXzsKK30KKworCitVbmtub3duRmllbGRTZXQqIFVua25vd25GaWVsZFNldDo6QWRkR3JvdXAoaW50IG51bWJlcikgeworICBVbmtub3duRmllbGQgZmllbGQ7CisgIGZpZWxkLm51bWJlcl8gPSBudW1iZXI7CisgIGZpZWxkLlNldFR5cGUoVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQKTsKKyAgZmllbGQuZ3JvdXBfID0gbmV3IFVua25vd25GaWVsZFNldDsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgZmllbGRzXyA9IG5ldyB2ZWN0b3I8VW5rbm93bkZpZWxkPigpOworICBmaWVsZHNfLT5wdXNoX2JhY2soZmllbGQpOworICByZXR1cm4gZmllbGQuZ3JvdXBfOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6QWRkRmllbGQoY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZCkgeworICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgIGZpZWxkc18tPnB1c2hfYmFjayhmaWVsZCk7CisgIGZpZWxkc18tPmJhY2soKS5EZWVwQ29weSgpOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6RGVsZXRlU3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtKSB7CisgIC8vIERlbGV0ZSB0aGUgc3BlY2lmaWVkIGZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07ICsraSkgeworICAgICgqZmllbGRzXylbaSArIHN0YXJ0XS5EZWxldGUoKTsKKyAgfQorICAvLyBTbGlkZSBkb3duIHRoZSByZW1haW5pbmcgZmllbGRzLgorICBmb3IgKGludCBpID0gc3RhcnQgKyBudW07IGkgPCBmaWVsZHNfLT5zaXplKCk7ICsraSkgeworICAgICgqZmllbGRzXylbaSAtIG51bV0gPSAoKmZpZWxkc18pW2ldOworICB9CisgIC8vIFBvcCBvZmYgdGhlICMgb2YgZGVsZXRlZCBmaWVsZHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpIHsKKyAgICBmaWVsZHNfLT5wb3BfYmFjaygpOworICB9CisgIGlmIChmaWVsZHNfICYmIGZpZWxkc18tPnNpemUoKSA9PSAwKSB7CisgICAgLy8gbWFpbnRhaW4gaW52YXJpYW50OiBuZXZlciBob2xkIGZpZWxkc18gaWYgZW1wdHkuCisgICAgZGVsZXRlIGZpZWxkc187CisgICAgZmllbGRzXyA9IE5VTEw7CisgIH0KK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6OkRlbGV0ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgcmV0dXJuOworICBpbnQgbGVmdCA9IDA7ICAvLyBUaGUgbnVtYmVyIG9mIGZpZWxkcyBsZWZ0IGFmdGVyIGRlbGV0aW9uLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkc18tPnNpemUoKTsgKytpKSB7CisgICAgVW5rbm93bkZpZWxkKiBmaWVsZCA9ICYoKmZpZWxkc18pW2ldOworICAgIGlmIChmaWVsZC0+bnVtYmVyKCkgPT0gbnVtYmVyKSB7CisgICAgICBmaWVsZC0+RGVsZXRlKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChpICE9IGxlZnQpIHsKKyAgICAgICAgKCpmaWVsZHNfKVtsZWZ0XSA9ICgqZmllbGRzXylbaV07CisgICAgICB9CisgICAgICArK2xlZnQ7CisgICAgfQorICB9CisgIGZpZWxkc18tPnJlc2l6ZShsZWZ0KTsKKyAgaWYgKGxlZnQgPT0gMCkgeworICAgIC8vIG1haW50YWluIGludmFyaWFudDogbmV2ZXIgaG9sZCBmaWVsZHNfIGlmIGVtcHR5LgorICAgIGRlbGV0ZSBmaWVsZHNfOworICAgIGZpZWxkc18gPSBOVUxMOworICB9Cit9CisKK2Jvb2wgVW5rbm93bkZpZWxkU2V0OjpNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgVW5rbm93bkZpZWxkU2V0IG90aGVyOworICBpZiAoaW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBNZXNzYWdlKGlucHV0LCAmb3RoZXIpICYmCisgICAgICBpbnB1dC0+Q29uc3VtZWRFbnRpcmVNZXNzYWdlKCkpIHsKKyAgICBNZXJnZUZyb21BbmREZXN0cm95KCZvdGhlcik7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgVW5rbm93bkZpZWxkU2V0OjpQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgQ2xlYXIoKTsKKyAgcmV0dXJuIE1lcmdlRnJvbUNvZGVkU3RyZWFtKGlucHV0KTsKK30KKworYm9vbCBVbmtub3duRmllbGRTZXQ6OlBhcnNlRnJvbVplcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dChpbnB1dCk7CisgIHJldHVybiAoUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmNvZGVkX2lucHV0KSAmJgorICAgICAgICAgIGNvZGVkX2lucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKK30KKworYm9vbCBVbmtub3duRmllbGRTZXQ6OlBhcnNlRnJvbUFycmF5KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKSB7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0KGRhdGEsIHNpemUpOworICByZXR1cm4gUGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oJmlucHV0KTsKK30KKwordm9pZCBVbmtub3duRmllbGQ6OkRlbGV0ZSgpIHsKKyAgc3dpdGNoICh0eXBlKCkpIHsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgZGVsZXRlIGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV87CisgICAgICBicmVhazsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9HUk9VUDoKKyAgICAgIGRlbGV0ZSBncm91cF87CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworLy8gUmVzZXQgYWxsIG93bmVkIHB0cnMsIGEgc3BlY2lhbCBmdW5jdGlvbiBmb3IgcGVyZm9ybWFuY2UsIHRvIGF2b2lkIGRvdWJsZQorLy8gb3duaW5nIHRoZSBwdHJzLCB3aGVuIHdlIG1lcmdlIGZyb20gYSB0ZW1wb3JhcnkgVW5rbm93bkZpZWxkU2V0IG9iamVjdHMuCit2b2lkIFVua25vd25GaWVsZDo6UmVzZXQoKSB7CisgIHN3aXRjaCAodHlwZSgpKSB7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgIGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8gPSBOVUxMOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6IHsKKyAgICAgIGdyb3VwXyA9IE5VTEw7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkOjpEZWVwQ29weSgpIHsKKyAgc3dpdGNoICh0eXBlKCkpIHsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgbGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXyA9IG5ldyBzdHJpbmcoCisgICAgICAgICAgKmxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8pOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6IHsKKyAgICAgIFVua25vd25GaWVsZFNldCogZ3JvdXAgPSBuZXcgVW5rbm93bkZpZWxkU2V0KCk7CisgICAgICBncm91cC0+SW50ZXJuYWxNZXJnZUZyb20oKmdyb3VwXyk7CisgICAgICBncm91cF8gPSBncm91cDsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworCit2b2lkIFVua25vd25GaWVsZDo6U2VyaWFsaXplTGVuZ3RoRGVsaW1pdGVkTm9UYWcoCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDS19FUShUWVBFX0xFTkdUSF9ERUxJTUlURUQsIHR5cGUoKSk7CisgIGNvbnN0IHN0cmluZyYgZGF0YSA9ICpsZW5ndGhfZGVsaW1pdGVkXy5zdHJpbmdfdmFsdWVfOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoZGF0YS5zaXplKCkpOworICBvdXRwdXQtPldyaXRlUmF3TWF5YmVBbGlhc2VkKGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7Cit9CisKK3VpbnQ4KiBVbmtub3duRmllbGQ6OlNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnVG9BcnJheSh1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoVFlQRV9MRU5HVEhfREVMSU1JVEVELCB0eXBlKCkpOworICBjb25zdCBzdHJpbmcmIGRhdGEgPSAqbGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXzsKKyAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheShkYXRhLnNpemUoKSwgdGFyZ2V0KTsKKyAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVN0cmluZ1RvQXJyYXkoZGF0YSwgdGFyZ2V0KTsKKyAgcmV0dXJuIHRhcmdldDsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTg3YjE5NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaApAQCAtMCwwICsxLDMzOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIENvbnRhaW5zIGNsYXNzZXMgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHVucmVjb2duaXplZCBmaWVsZHMgc2VlbiB3aGlsZQorLy8gcGFyc2luZyBhIHByb3RvY29sIG1lc3NhZ2UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VOS05PV05fRklFTERfU0VUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVU5LTk9XTl9GSUVMRF9TRVRfSF9fCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIENvZGVkSW5wdXRTdHJlYW07ICAgICAgICAgLy8gY29kZWRfc3RyZWFtLmgKKyAgICBjbGFzcyBDb2RlZE91dHB1dFN0cmVhbTsgICAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCisgICAgY2xhc3MgWmVyb0NvcHlJbnB1dFN0cmVhbTsgICAgICAvLyB6ZXJvX2NvcHlfc3RyZWFtLmgKKyAgfQorICBuYW1lc3BhY2UgaW50ZXJuYWwgeworICAgIGNsYXNzIFdpcmVGb3JtYXQ7ICAgICAgICAgICAgICAgLy8gd2lyZV9mb3JtYXQuaAorICAgIGNsYXNzIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXJVc2luZ0NvcmQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRlbnNpb25fc2V0X2hlYXZ5LmNjCisgIH0KKworY2xhc3MgTWVzc2FnZTsgICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZS5oCitjbGFzcyBVbmtub3duRmllbGQ7ICAgICAgICAgICAgICAgICAvLyBiZWxvdworCisvLyBBbiBVbmtub3duRmllbGRTZXQgY29udGFpbnMgZmllbGRzIHRoYXQgd2VyZSBlbmNvdW50ZXJlZCB3aGlsZSBwYXJzaW5nIGEKKy8vIG1lc3NhZ2UgYnV0IHdlcmUgbm90IGRlZmluZWQgYnkgaXRzIHR5cGUuICBLZWVwaW5nIHRyYWNrIG9mIHRoZXNlIGNhbiBiZQorLy8gdXNlZnVsLCBlc3BlY2lhbGx5IGluIHRoYXQgdGhleSBtYXkgYmUgd3JpdHRlbiBpZiB0aGUgbWVzc2FnZSBpcyBzZXJpYWxpemVkCisvLyBhZ2FpbiB3aXRob3V0IGJlaW5nIGNsZWFyZWQgaW4gYmV0d2Vlbi4gIFRoaXMgbWVhbnMgdGhhdCBzb2Z0d2FyZSB3aGljaAorLy8gc2ltcGx5IHJlY2VpdmVzIG1lc3NhZ2VzIGFuZCBmb3J3YXJkcyB0aGVtIHRvIG90aGVyIHNlcnZlcnMgZG9lcyBub3QgbmVlZAorLy8gdG8gYmUgdXBkYXRlZCBldmVyeSB0aW1lIGEgbmV3IGZpZWxkIGlzIGFkZGVkIHRvIHRoZSBtZXNzYWdlIGRlZmluaXRpb24uCisvLworLy8gVG8gZ2V0IHRoZSBVbmtub3duRmllbGRTZXQgYXR0YWNoZWQgdG8gYW55IG1lc3NhZ2UsIGNhbGwKKy8vIFJlZmxlY3Rpb246OkdldFVua25vd25GaWVsZHMoKS4KKy8vCisvLyBUaGlzIGNsYXNzIGlzIG5lY2Vzc2FyaWx5IHRpZWQgdG8gdGhlIHByb3RvY29sIGJ1ZmZlciB3aXJlIGZvcm1hdCwgdW5saWtlCisvLyB0aGUgUmVmbGVjdGlvbiBpbnRlcmZhY2Ugd2hpY2ggaXMgaW5kZXBlbmRlbnQgb2YgYW55IHNlcmlhbGl6YXRpb24gc2NoZW1lLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVua25vd25GaWVsZFNldCB7CisgcHVibGljOgorICBVbmtub3duRmllbGRTZXQoKTsKKyAgflVua25vd25GaWVsZFNldCgpOworCisgIC8vIFJlbW92ZSBhbGwgZmllbGRzLgorICBpbmxpbmUgdm9pZCBDbGVhcigpOworCisgIC8vIFJlbW92ZSBhbGwgZmllbGRzIGFuZCBkZWFsbG9jYXRlIGludGVybmFsIGRhdGEgb2JqZWN0cworICB2b2lkIENsZWFyQW5kRnJlZU1lbW9yeSgpOworCisgIC8vIElzIHRoaXMgc2V0IGVtcHR5PworICBpbmxpbmUgYm9vbCBlbXB0eSgpIGNvbnN0OworCisgIC8vIE1lcmdlIHRoZSBjb250ZW50cyBvZiBzb21lIG90aGVyIFVua25vd25GaWVsZFNldCB3aXRoIHRoaXMgb25lLgorICB2b2lkIE1lcmdlRnJvbShjb25zdCBVbmtub3duRmllbGRTZXQmIG90aGVyKTsKKworICAvLyBTaW1pbGFyIHRvIGFib3ZlLCBidXQgdGhpcyBmdW5jdGlvbiB3aWxsIGRlc3Ryb3kgdGhlIGNvbnRlbnRzIG9mIG90aGVyLgorICB2b2lkIE1lcmdlRnJvbUFuZERlc3Ryb3koVW5rbm93bkZpZWxkU2V0KiBvdGhlcik7CisKKyAgLy8gU3dhcHMgdGhlIGNvbnRlbnRzIG9mIHNvbWUgb3RoZXIgVW5rbm93bkZpZWxkU2V0IHdpdGggdGhpcyBvbmUuCisgIGlubGluZSB2b2lkIFN3YXAoVW5rbm93bkZpZWxkU2V0KiB4KTsKKworICAvLyBDb21wdXRlcyAoYW4gZXN0aW1hdGUgb2YpIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgY3VycmVudGx5IHVzZWQgZm9yCisgIC8vIHN0b3JpbmcgdGhlIHVua25vd24gZmllbGRzIGluIG1lbW9yeS4gRG9lcyBOT1QgaW5jbHVkZQorICAvLyBzaXplb2YoKnRoaXMpIGluIHRoZSBjYWxjdWxhdGlvbi4KKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworICAvLyBWZXJzaW9uIG9mIFNwYWNlVXNlZCgpIGluY2x1ZGluZyBzaXplb2YoKnRoaXMpLgorICBpbnQgU3BhY2VVc2VkKCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGZpZWxkcyBwcmVzZW50IGluIHRoZSBVbmtub3duRmllbGRTZXQuCisgIGlubGluZSBpbnQgZmllbGRfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0IGEgZmllbGQgaW4gdGhlIHNldCwgd2hlcmUgMCA8PSBpbmRleCA8IGZpZWxkX2NvdW50KCkuICBUaGUgZmllbGRzCisgIC8vIGFwcGVhciBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlIGFkZGVkLgorICBpbmxpbmUgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZChpbnQgaW5kZXgpIGNvbnN0OworICAvLyBHZXQgYSBtdXRhYmxlIHBvaW50ZXIgdG8gYSBmaWVsZCBpbiB0aGUgc2V0LCB3aGVyZQorICAvLyAwIDw9IGluZGV4IDwgZmllbGRfY291bnQoKS4gIFRoZSBmaWVsZHMgYXBwZWFyIGluIHRoZSBvcmRlciBpbiB3aGljaAorICAvLyB0aGV5IHdlcmUgYWRkZWQuCisgIGlubGluZSBVbmtub3duRmllbGQqIG11dGFibGVfZmllbGQoaW50IGluZGV4KTsKKworICAvLyBBZGRpbmcgZmllbGRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHZvaWQgQWRkVmFyaW50KGludCBudW1iZXIsIHVpbnQ2NCB2YWx1ZSk7CisgIHZvaWQgQWRkRml4ZWQzMihpbnQgbnVtYmVyLCB1aW50MzIgdmFsdWUpOworICB2b2lkIEFkZEZpeGVkNjQoaW50IG51bWJlciwgdWludDY0IHZhbHVlKTsKKyAgdm9pZCBBZGRMZW5ndGhEZWxpbWl0ZWQoaW50IG51bWJlciwgY29uc3Qgc3RyaW5nJiB2YWx1ZSk7CisgIHN0cmluZyogQWRkTGVuZ3RoRGVsaW1pdGVkKGludCBudW1iZXIpOworICBVbmtub3duRmllbGRTZXQqIEFkZEdyb3VwKGludCBudW1iZXIpOworCisgIC8vIEFkZHMgYW4gdW5rbm93biBmaWVsZCBmcm9tIGFub3RoZXIgc2V0LgorICB2b2lkIEFkZEZpZWxkKGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQpOworCisgIC8vIERlbGV0ZSBmaWVsZHMgd2l0aCBpbmRpY2VzIGluIHRoZSByYW5nZSBbc3RhcnQgLi4gc3RhcnQrbnVtLTFdLgorICAvLyBDYXV0aW9uOiBpbXBsZW1lbnRhdGlvbiBtb3ZlcyBhbGwgZmllbGRzIHdpdGggaW5kaWNlcyBbc3RhcnQrbnVtIC4uIF0uCisgIHZvaWQgRGVsZXRlU3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtKTsKKworICAvLyBEZWxldGUgYWxsIGZpZWxkcyB3aXRoIGEgc3BlY2lmaWMgZmllbGQgbnVtYmVyLiBUaGUgb3JkZXIgb2YgbGVmdCBmaWVsZHMKKyAgLy8gaXMgcHJlc2VydmVkLgorICAvLyBDYXV0aW9uOiBpbXBsZW1lbnRhdGlvbiBtb3ZlcyBhbGwgZmllbGRzIGFmdGVyIHRoZSBmaXJzdCBkZWxldGVkIGZpZWxkLgorICB2b2lkIERlbGV0ZUJ5TnVtYmVyKGludCBudW1iZXIpOworCisgIC8vIFBhcnNpbmcgaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIHdvcmsgZXhhY3RseSBsaWtlIHRoZSBzaW1pbGFybHktbmFtZWQgbWV0aG9kcyBvZiBNZXNzYWdlLgorCisgIGJvb2wgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgYm9vbCBQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICBib29sIFBhcnNlRnJvbVplcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCk7CisgIGJvb2wgUGFyc2VGcm9tQXJyYXkoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpOworICBpbmxpbmUgYm9vbCBQYXJzZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBkYXRhKSB7CisgICAgcmV0dXJuIFBhcnNlRnJvbUFycmF5KGRhdGEuZGF0YSgpLCBzdGF0aWNfY2FzdDxpbnQ+KGRhdGEuc2l6ZSgpKSk7CisgIH0KKworICBzdGF0aWMgY29uc3QgVW5rbm93bkZpZWxkU2V0KiBkZWZhdWx0X2luc3RhbmNlKCk7CisgcHJpdmF0ZToKKyAgLy8gRm9yIEludGVybmFsTWVyZ2VGcm9tCisgIGZyaWVuZCBjbGFzcyBVbmtub3duRmllbGQ7CisgIC8vIE1lcmdlcyBmcm9tIG90aGVyIFVua25vd25GaWVsZFNldC4gVGhpcyBtZXRob2QgYXNzdW1lcywgdGhhdCB0aGlzIG9iamVjdAorICAvLyBpcyBuZXdseSBjcmVhdGVkIGFuZCBoYXMgZmllbGRzXyA9PSBOVUxMOworICB2b2lkIEludGVybmFsTWVyZ2VGcm9tKGNvbnN0IFVua25vd25GaWVsZFNldCYgb3RoZXIpOworICB2b2lkIENsZWFyRmFsbGJhY2soKTsKKworICAvLyBmaWVsZHNfIGlzIGVpdGhlciBOVUxMLCBvciBhIHBvaW50ZXIgdG8gYSB2ZWN0b3IgdGhhdCBpcyAqbm9uLWVtcHR5Ki4gV2UKKyAgLy8gbmV2ZXIgaG9sZCB0aGUgZW1wdHkgdmVjdG9yIGJlY2F1c2Ugd2Ugd2FudCB0aGUgJ2RvIHdlIGhhdmUgYW55IHVua25vd24KKyAgLy8gZmllbGRzJyBjaGVjayB0byBiZSBmYXN0LCBhbmQgYXZvaWQgYSBjYWNoZSBtaXNzOiB0aGUgVUZTIGluc3RhbmNlIGdldHMKKyAgLy8gZW1iZWRkZWQgaW4gdGhlIG1lc3NhZ2Ugb2JqZWN0LCBzbyAnZmllbGRzXyAhPSBOVUxMJyB0ZXN0cyBhIG1lbWJlcgorICAvLyB2YXJpYWJsZSBob3QgaW4gdGhlIGNhY2hlLCB3aXRob3V0IHRoZSBuZWVkIHRvIGdvIHRvdWNoIGEgdmVjdG9yIHNvbWV3aGVyZQorICAvLyBlbHNlIGluIG1lbW9yeS4KKyAgc3RkOjp2ZWN0b3I8VW5rbm93bkZpZWxkPiogZmllbGRzXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFVua25vd25GaWVsZFNldCk7Cit9OworCisvLyBSZXByZXNlbnRzIG9uZSBmaWVsZCBpbiBhbiBVbmtub3duRmllbGRTZXQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVW5rbm93bkZpZWxkIHsKKyBwdWJsaWM6CisgIGVudW0gVHlwZSB7CisgICAgVFlQRV9WQVJJTlQsCisgICAgVFlQRV9GSVhFRDMyLAorICAgIFRZUEVfRklYRUQ2NCwKKyAgICBUWVBFX0xFTkdUSF9ERUxJTUlURUQsCisgICAgVFlQRV9HUk9VUAorICB9OworCisgIC8vIFRoZSBmaWVsZCdzIHRhZyBudW1iZXIsIGFzIHNlZW4gb24gdGhlIHdpcmUuCisgIGlubGluZSBpbnQgbnVtYmVyKCkgY29uc3Q7CisKKyAgLy8gVGhlIGZpZWxkIHR5cGUuCisgIGlubGluZSBUeXBlIHR5cGUoKSBjb25zdDsKKworICAvLyBBY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBFYWNoIG1ldGhvZCB3b3JrcyBvbmx5IGZvciBVbmtub3duRmllbGRzIG9mIHRoZSBjb3JyZXNwb25kaW5nIHR5cGUuCisKKyAgaW5saW5lIHVpbnQ2NCB2YXJpbnQoKSBjb25zdDsKKyAgaW5saW5lIHVpbnQzMiBmaXhlZDMyKCkgY29uc3Q7CisgIGlubGluZSB1aW50NjQgZml4ZWQ2NCgpIGNvbnN0OworICBpbmxpbmUgY29uc3Qgc3RyaW5nJiBsZW5ndGhfZGVsaW1pdGVkKCkgY29uc3Q7CisgIGlubGluZSBjb25zdCBVbmtub3duRmllbGRTZXQmIGdyb3VwKCkgY29uc3Q7CisKKyAgaW5saW5lIHZvaWQgc2V0X3ZhcmludCh1aW50NjQgdmFsdWUpOworICBpbmxpbmUgdm9pZCBzZXRfZml4ZWQzMih1aW50MzIgdmFsdWUpOworICBpbmxpbmUgdm9pZCBzZXRfZml4ZWQ2NCh1aW50NjQgdmFsdWUpOworICBpbmxpbmUgdm9pZCBzZXRfbGVuZ3RoX2RlbGltaXRlZChjb25zdCBzdHJpbmcmIHZhbHVlKTsKKyAgaW5saW5lIHN0cmluZyogbXV0YWJsZV9sZW5ndGhfZGVsaW1pdGVkKCk7CisgIGlubGluZSBVbmtub3duRmllbGRTZXQqIG11dGFibGVfZ3JvdXAoKTsKKworICAvLyBTZXJpYWxpemF0aW9uIEFQSS4KKyAgLy8gVGhlc2UgbWV0aG9kcyBjYW4gdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gYW5kIG1heQorICAvLyBhcmNoaWV2ZSBhIGJldHRlciBwZXJmb3JtYW5jZSB0aGFuIHVzaW5nIGdldHRlcnMgdG8gcmV0cmlldmUgdGhlIGRhdGEgYW5kCisgIC8vIGRvIHRoZSBzZXJpYWxpemF0aW9uIHlvdXJzZWxmLgorICB2b2lkIFNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgdWludDgqIFNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnVG9BcnJheSh1aW50OCogdGFyZ2V0KSBjb25zdDsKKworICBpbmxpbmUgaW50IEdldExlbmd0aERlbGltaXRlZFNpemUoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBVbmtub3duRmllbGRTZXQ7CisKKyAgLy8gSWYgdGhpcyBVbmtub3duRmllbGQgY29udGFpbnMgYSBwb2ludGVyLCBkZWxldGUgaXQuCisgIHZvaWQgRGVsZXRlKCk7CisKKyAgLy8gUmVzZXQgYWxsIHRoZSB1bmRlcmx5aW5nIHBvaW50ZXJzIHRvIE5VTEwuIEEgc3BlY2lhbCBmdW5jdGlvbiB0byBiZSBvbmx5CisgIC8vIHVzZWQgd2hpbGUgbWVyZ2luZyBmcm9tIGEgdGVtcG9yYXJ5IFVGUy4KKyAgdm9pZCBSZXNldCgpOworCisgIC8vIE1ha2UgYSBkZWVwIGNvcHkgb2YgYW55IHBvaW50ZXJzIGluIHRoaXMgVW5rbm93bkZpZWxkLgorICB2b2lkIERlZXBDb3B5KCk7CisKKyAgLy8gU2V0IHRoZSB3aXJlIHR5cGUgb2YgdGhpcyBVbmtub3duRmllbGQuIFNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiB0aGlzCisgIC8vIFVua25vd25GaWVsZCBpcyBiZWluZyBjcmVhdGVkLgorICBpbmxpbmUgdm9pZCBTZXRUeXBlKFR5cGUgdHlwZSk7CisKKyAgdW5pb24gTGVuZ3RoRGVsaW1pdGVkIHsKKyAgICBzdHJpbmcqIHN0cmluZ192YWx1ZV87CisgIH07CisKKyAgdWludDMyIG51bWJlcl87CisgIHVpbnQzMiB0eXBlXzsKKyAgdW5pb24geworICAgIHVpbnQ2NCB2YXJpbnRfOworICAgIHVpbnQzMiBmaXhlZDMyXzsKKyAgICB1aW50NjQgZml4ZWQ2NF87CisgICAgbXV0YWJsZSB1bmlvbiBMZW5ndGhEZWxpbWl0ZWQgbGVuZ3RoX2RlbGltaXRlZF87CisgICAgVW5rbm93bkZpZWxkU2V0KiBncm91cF87CisgIH07Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBpbmxpbmUgaW1wbGVtZW50YXRpb25zCisKK2lubGluZSB2b2lkIFVua25vd25GaWVsZFNldDo6Q2xlYXIoKSB7CisgIGlmIChmaWVsZHNfKSB7CisgICAgQ2xlYXJGYWxsYmFjaygpOworICB9Cit9CisKK2lubGluZSBib29sIFVua25vd25GaWVsZFNldDo6ZW1wdHkoKSBjb25zdCB7CisgIC8vIEludmFyaWFudDogZmllbGRzXyBpcyBuZXZlciBlbXB0eSBpZiBwcmVzZW50LgorICByZXR1cm4gIWZpZWxkc187Cit9CisKK2lubGluZSB2b2lkIFVua25vd25GaWVsZFNldDo6U3dhcChVbmtub3duRmllbGRTZXQqIHgpIHsKKyAgc3RkOjpzd2FwKGZpZWxkc18sIHgtPmZpZWxkc18pOworfQorCitpbmxpbmUgaW50IFVua25vd25GaWVsZFNldDo6ZmllbGRfY291bnQoKSBjb25zdCB7CisgIHJldHVybiBmaWVsZHNfID8gc3RhdGljX2Nhc3Q8aW50PihmaWVsZHNfLT5zaXplKCkpIDogMDsKK30KK2lubGluZSBjb25zdCBVbmtub3duRmllbGQmIFVua25vd25GaWVsZFNldDo6ZmllbGQoaW50IGluZGV4KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0soZmllbGRzXyAhPSBOVUxMKTsKKyAgcmV0dXJuICgqZmllbGRzXylbaW5kZXhdOworfQoraW5saW5lIFVua25vd25GaWVsZCogVW5rbm93bkZpZWxkU2V0OjptdXRhYmxlX2ZpZWxkKGludCBpbmRleCkgeworICByZXR1cm4gJigqZmllbGRzXylbaW5kZXhdOworfQorCitpbmxpbmUgdm9pZCBVbmtub3duRmllbGRTZXQ6OkFkZExlbmd0aERlbGltaXRlZCgKKyAgICBpbnQgbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIEFkZExlbmd0aERlbGltaXRlZChudW1iZXIpLT5hc3NpZ24odmFsdWUpOworfQorCisKK2lubGluZSBpbnQgVW5rbm93bkZpZWxkOjpudW1iZXIoKSBjb25zdCB7IHJldHVybiBudW1iZXJfOyB9CitpbmxpbmUgVW5rbm93bkZpZWxkOjpUeXBlIFVua25vd25GaWVsZDo6dHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFR5cGU+KHR5cGVfKTsKK30KKworaW5saW5lIHVpbnQ2NCBVbmtub3duRmllbGQ6OnZhcmludCgpIGNvbnN0IHsKKyAgYXNzZXJ0KHR5cGUoKSA9PSBUWVBFX1ZBUklOVCk7CisgIHJldHVybiB2YXJpbnRfOworfQoraW5saW5lIHVpbnQzMiBVbmtub3duRmllbGQ6OmZpeGVkMzIoKSBjb25zdCB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9GSVhFRDMyKTsKKyAgcmV0dXJuIGZpeGVkMzJfOworfQoraW5saW5lIHVpbnQ2NCBVbmtub3duRmllbGQ6OmZpeGVkNjQoKSBjb25zdCB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9GSVhFRDY0KTsKKyAgcmV0dXJuIGZpeGVkNjRfOworfQoraW5saW5lIGNvbnN0IHN0cmluZyYgVW5rbm93bkZpZWxkOjpsZW5ndGhfZGVsaW1pdGVkKCkgY29uc3QgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgIHJldHVybiAqbGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXzsKK30KK2lubGluZSBjb25zdCBVbmtub3duRmllbGRTZXQmIFVua25vd25GaWVsZDo6Z3JvdXAoKSBjb25zdCB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9HUk9VUCk7CisgIHJldHVybiAqZ3JvdXBfOworfQorCitpbmxpbmUgdm9pZCBVbmtub3duRmllbGQ6OnNldF92YXJpbnQodWludDY0IHZhbHVlKSB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9WQVJJTlQpOworICB2YXJpbnRfID0gdmFsdWU7Cit9CitpbmxpbmUgdm9pZCBVbmtub3duRmllbGQ6OnNldF9maXhlZDMyKHVpbnQzMiB2YWx1ZSkgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfRklYRUQzMik7CisgIGZpeGVkMzJfID0gdmFsdWU7Cit9CitpbmxpbmUgdm9pZCBVbmtub3duRmllbGQ6OnNldF9maXhlZDY0KHVpbnQ2NCB2YWx1ZSkgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfRklYRUQ2NCk7CisgIGZpeGVkNjRfID0gdmFsdWU7Cit9CitpbmxpbmUgdm9pZCBVbmtub3duRmllbGQ6OnNldF9sZW5ndGhfZGVsaW1pdGVkKGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgYXNzZXJ0KHR5cGUoKSA9PSBUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICBsZW5ndGhfZGVsaW1pdGVkXy5zdHJpbmdfdmFsdWVfLT5hc3NpZ24odmFsdWUpOworfQoraW5saW5lIHN0cmluZyogVW5rbm93bkZpZWxkOjptdXRhYmxlX2xlbmd0aF9kZWxpbWl0ZWQoKSB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgcmV0dXJuIGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV87Cit9CitpbmxpbmUgVW5rbm93bkZpZWxkU2V0KiBVbmtub3duRmllbGQ6Om11dGFibGVfZ3JvdXAoKSB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9HUk9VUCk7CisgIHJldHVybiBncm91cF87Cit9CisKK2lubGluZSBpbnQgVW5rbm93bkZpZWxkOjpHZXRMZW5ndGhEZWxpbWl0ZWRTaXplKCkgY29uc3QgeworICBHT09HTEVfRENIRUNLX0VRKFRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdHlwZSgpKTsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4obGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXy0+c2l6ZSgpKTsKK30KKworaW5saW5lIHZvaWQgVW5rbm93bkZpZWxkOjpTZXRUeXBlKFR5cGUgdHlwZSkgeworICB0eXBlXyA9IHR5cGU7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VOS05PV05fRklFTERfU0VUX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldF91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXRfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWIwMmYwYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXRfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw2MDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIHRlc3QgaXMgdGVzdGluZyBhIGxvdCBtb3JlIHRoYW4ganVzdCB0aGUgVW5rbm93bkZpZWxkU2V0IGNsYXNzLiAgSXQKKy8vIHRlc3RzIGhhbmRsaW5nIG9mIHVua25vd24gZmllbGRzIHRocm91Z2hvdXQgdGhlIHN5c3RlbS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXQ7CisKK2NsYXNzIFVua25vd25GaWVsZFNldFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgZGVzY3JpcHRvcl8gPSB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCk7CisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmYWxsX2ZpZWxkc18pOworICAgIGFsbF9maWVsZHNfLlNlcmlhbGl6ZVRvU3RyaW5nKCZhbGxfZmllbGRzX2RhdGFfKTsKKyAgICBBU1NFUlRfVFJVRShlbXB0eV9tZXNzYWdlXy5QYXJzZUZyb21TdHJpbmcoYWxsX2ZpZWxkc19kYXRhXykpOworICAgIHVua25vd25fZmllbGRzXyA9IGVtcHR5X21lc3NhZ2VfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGNvbnN0IFVua25vd25GaWVsZCogR2V0RmllbGQoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgaWYgKGZpZWxkID09IE5VTEwpIHJldHVybiBOVUxMOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHNfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkc18tPmZpZWxkKGkpLm51bWJlcigpID09IGZpZWxkLT5udW1iZXIoKSkgeworICAgICAgICByZXR1cm4gJnVua25vd25fZmllbGRzXy0+ZmllbGQoaSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gQ29uc3RydWN0cyBhIHByb3RvY29sIGJ1ZmZlciB3aGljaCBjb250YWlucyBmaWVsZHMgd2l0aCBhbGwgdGhlIHNhbWUKKyAgLy8gbnVtYmVycyBhcyBhbGxfZmllbGRzX2RhdGFfIGV4Y2VwdCB0aGF0IGVhY2ggZmllbGQgaXMgc29tZSBvdGhlciB3aXJlCisgIC8vIHR5cGUuCisgIHN0cmluZyBHZXRCaXphcnJvRGF0YSgpIHsKKyAgICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBiaXphcnJvX21lc3NhZ2U7CisgICAgVW5rbm93bkZpZWxkU2V0KiBiaXphcnJvX3Vua25vd25fZmllbGRzID0KKyAgICAgIGJpemFycm9fbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgVW5rbm93bkZpZWxkJiB1bmtub3duX2ZpZWxkID0gdW5rbm93bl9maWVsZHNfLT5maWVsZChpKTsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkLnR5cGUoKSA9PSBVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5UKSB7CisgICAgICAgIGJpemFycm9fdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkMzIodW5rbm93bl9maWVsZC5udW1iZXIoKSwgMSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBiaXphcnJvX3Vua25vd25fZmllbGRzLT5BZGRWYXJpbnQodW5rbm93bl9maWVsZC5udW1iZXIoKSwgMSk7CisgICAgICB9CisgICAgfQorCisgICAgc3RyaW5nIGRhdGE7CisgICAgRVhQRUNUX1RSVUUoYml6YXJyb19tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKSk7CisgICAgcmV0dXJuIGRhdGE7CisgIH0KKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBhbGxfZmllbGRzXzsKKyAgc3RyaW5nIGFsbF9maWVsZHNfZGF0YV87CisKKyAgLy8gQW4gZW1wdHkgbWVzc2FnZSB0aGF0IGhhcyBiZWVuIHBhcnNlZCBmcm9tIGFsbF9maWVsZHNfZGF0YV8uICBTbywgaXQgaGFzCisgIC8vIHVua25vd24gZmllbGRzIG9mIGV2ZXJ5IHR5cGUuCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5X21lc3NhZ2VfOworICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzXzsKK307CisKK25hbWVzcGFjZSB7CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBBbGxGaWVsZHNQcmVzZW50KSB7CisgIC8vIEFsbCBmaWVsZHMgb2YgVGVzdEFsbFR5cGVzIHNob3VsZCBiZSBwcmVzZW50LCBpbiBudW1lcmljIG9yZGVyIChiZWNhdXNlCisgIC8vIHRoYXQncyB0aGUgb3JkZXIgd2UgcGFyc2VkIHRoZW0gaW4pLiAgRmllbGRzIHRoYXQgYXJlIG5vdCB2YWxpZCBmaWVsZAorICAvLyBudW1iZXJzIG9mIFRlc3RBbGxUeXBlcyBzaG91bGQgTk9UIGJlIHByZXNlbnQuCisKKyAgaW50IHBvcyA9IDA7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDAwOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TnVtYmVyKGkpOworICAgIGlmIChmaWVsZCAhPSBOVUxMKSB7CisgICAgICBBU1NFUlRfTFQocG9zLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworICAgICAgLy8gRG8gbm90IGNoZWNrIG9uZW9mIGZpZWxkIGlmIGl0IGlzIG5vdCBzZXQuCisgICAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMKSB7CisgICAgICAgIEVYUEVDVF9FUShpLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkKHBvcysrKS5udW1iZXIoKSk7CisgICAgICB9IGVsc2UgaWYgKGkgPT0gdW5rbm93bl9maWVsZHNfLT5maWVsZChwb3MpLm51bWJlcigpKSB7CisgICAgICAgIHBvcysrOworICAgICAgfQorICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIC8vIFNob3VsZCBoYXZlIGEgc2Vjb25kIGluc3RhbmNlLgorICAgICAgICBBU1NFUlRfTFQocG9zLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworICAgICAgICBFWFBFQ1RfRVEoaSwgdW5rbm93bl9maWVsZHNfLT5maWVsZChwb3MrKykubnVtYmVyKCkpOworICAgICAgfQorICAgIH0KKyAgfQorICBFWFBFQ1RfRVEodW5rbm93bl9maWVsZHNfLT5maWVsZF9jb3VudCgpLCBwb3MpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgVmFyaW50KSB7CisgIGNvbnN0IFVua25vd25GaWVsZCogZmllbGQgPSBHZXRGaWVsZCgib3B0aW9uYWxfaW50MzIiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQsIGZpZWxkLT50eXBlKCkpOworICBFWFBFQ1RfRVEoYWxsX2ZpZWxkc18ub3B0aW9uYWxfaW50MzIoKSwgZmllbGQtPnZhcmludCgpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIEZpeGVkMzIpIHsKKyAgY29uc3QgVW5rbm93bkZpZWxkKiBmaWVsZCA9IEdldEZpZWxkKCJvcHRpb25hbF9maXhlZDMyIik7CisgIEFTU0VSVF9UUlVFKGZpZWxkICE9IE5VTEwpOworCisgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfRklYRUQzMiwgZmllbGQtPnR5cGUoKSk7CisgIEVYUEVDVF9FUShhbGxfZmllbGRzXy5vcHRpb25hbF9maXhlZDMyKCksIGZpZWxkLT5maXhlZDMyKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgRml4ZWQ2NCkgeworICBjb25zdCBVbmtub3duRmllbGQqIGZpZWxkID0gR2V0RmllbGQoIm9wdGlvbmFsX2ZpeGVkNjQiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0LCBmaWVsZC0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGFsbF9maWVsZHNfLm9wdGlvbmFsX2ZpeGVkNjQoKSwgZmllbGQtPmZpeGVkNjQoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBMZW5ndGhEZWxpbWl0ZWQpIHsKKyAgY29uc3QgVW5rbm93bkZpZWxkKiBmaWVsZCA9IEdldEZpZWxkKCJvcHRpb25hbF9zdHJpbmciKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVELCBmaWVsZC0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGFsbF9maWVsZHNfLm9wdGlvbmFsX3N0cmluZygpLCBmaWVsZC0+bGVuZ3RoX2RlbGltaXRlZCgpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIEdyb3VwKSB7CisgIGNvbnN0IFVua25vd25GaWVsZCogZmllbGQgPSBHZXRGaWVsZCgib3B0aW9uYWxncm91cCIpOworICBBU1NFUlRfVFJVRShmaWVsZCAhPSBOVUxMKTsKKworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQLCBmaWVsZC0+dHlwZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGZpZWxkLT5ncm91cCgpLmZpZWxkX2NvdW50KCkpOworCisgIGNvbnN0IFVua25vd25GaWVsZCYgbmVzdGVkX2ZpZWxkID0gZmllbGQtPmdyb3VwKCkuZmllbGQoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmVzdGVkX2ZpZWxkX2Rlc2NyaXB0b3IgPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok9wdGlvbmFsR3JvdXA6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJhIik7CisgIEFTU0VSVF9UUlVFKG5lc3RlZF9maWVsZF9kZXNjcmlwdG9yICE9IE5VTEwpOworCisgIEVYUEVDVF9FUShuZXN0ZWRfZmllbGRfZGVzY3JpcHRvci0+bnVtYmVyKCksIG5lc3RlZF9maWVsZC5udW1iZXIoKSk7CisgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULCBuZXN0ZWRfZmllbGQudHlwZSgpKTsKKyAgRVhQRUNUX0VRKGFsbF9maWVsZHNfLm9wdGlvbmFsZ3JvdXAoKS5hKCksIG5lc3RlZF9maWVsZC52YXJpbnQoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBTZXJpYWxpemVGYXN0QW5kU2xvd0FyZUVxdWl2YWxlbnQpIHsKKyAgaW50IHNpemUgPSBXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICBlbXB0eV9tZXNzYWdlXy51bmtub3duX2ZpZWxkcygpKTsKKyAgc3RyaW5nIHNsb3dfYnVmZmVyOworICBzdHJpbmcgZmFzdF9idWZmZXI7CisgIHNsb3dfYnVmZmVyLnJlc2l6ZShzaXplKTsKKyAgZmFzdF9idWZmZXIucmVzaXplKHNpemUpOworCisgIHVpbnQ4KiB0YXJnZXQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZmYXN0X2J1ZmZlcikpOworICB1aW50OCogcmVzdWx0ID0gV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgICAgZW1wdHlfbWVzc2FnZV8udW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgRVhQRUNUX0VRKHNpemUsIHJlc3VsdCAtIHRhcmdldCk7CisKKyAgeworICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSByYXdfc3RyZWFtKHN0cmluZ19hc19hcnJheSgmc2xvd19idWZmZXIpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmcmF3X3N0cmVhbSk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcyhlbXB0eV9tZXNzYWdlXy51bmtub3duX2ZpZWxkcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm91dHB1dF9zdHJlYW0pOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICB9CisgIEVYUEVDVF9UUlVFKGZhc3RfYnVmZmVyID09IHNsb3dfYnVmZmVyKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFNlcmlhbGl6ZSkgeworICAvLyBDaGVjayB0aGF0IHNlcmlhbGl6aW5nIHRoZSBVbmtub3duRmllbGRTZXQgcHJvZHVjZXMgdGhlIG9yaWdpbmFsIGRhdGEKKyAgLy8gYWdhaW4uCisKKyAgc3RyaW5nIGRhdGE7CisgIGVtcHR5X21lc3NhZ2VfLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBkdW1wIHJhdyBiaW5hcnkgZGF0YSB0bworICAvLyBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKGRhdGEgPT0gYWxsX2ZpZWxkc19kYXRhXyk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBQYXJzZVZpYVJlZmxlY3Rpb24pIHsKKyAgLy8gTWFrZSBzdXJlIGZpZWxkcyBhcmUgcHJvcGVybHkgcGFyc2VkIHRvIHRoZSBVbmtub3duRmllbGRTZXQgd2hlbiBwYXJzaW5nCisgIC8vIHZpYSByZWZsZWN0aW9uLgorCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2U7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChhbGxfZmllbGRzX2RhdGFfLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbF9maWVsZHNfZGF0YV8uc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIEFTU0VSVF9UUlVFKFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJm1lc3NhZ2UpKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFNlcmlhbGl6ZVZpYVJlZmxlY3Rpb24pIHsKKyAgLy8gTWFrZSBzdXJlIGZpZWxkcyBhcmUgcHJvcGVybHkgd3JpdHRlbiBmcm9tIHRoZSBVbmtub3duRmllbGRTZXQgd2hlbgorICAvLyBzZXJpYWxpemluZyB2aWEgcmVmbGVjdGlvbi4KKworICBzdHJpbmcgZGF0YTsKKworICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZkYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBpbnQgc2l6ZSA9IFdpcmVGb3JtYXQ6OkJ5dGVTaXplKGVtcHR5X21lc3NhZ2VfKTsKKyAgICBXaXJlRm9ybWF0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoZW1wdHlfbWVzc2FnZV8sIHNpemUsICZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBkdW1wIHJhdyBiaW5hcnkgZGF0YSB0bworICAvLyBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKGRhdGEgPT0gYWxsX2ZpZWxkc19kYXRhXyk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBDb3B5RnJvbSkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworCisgIG1lc3NhZ2UuQ29weUZyb20oZW1wdHlfbWVzc2FnZV8pOworCisgIEVYUEVDVF9FUShlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpLCBtZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgU3dhcCkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBvdGhlcl9tZXNzYWdlOworICBBU1NFUlRfVFJVRShvdGhlcl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhHZXRCaXphcnJvRGF0YSgpKSk7CisKKyAgRVhQRUNUX0dUKGVtcHR5X21lc3NhZ2VfLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSwgMCk7CisgIEVYUEVDVF9HVChvdGhlcl9tZXNzYWdlLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSwgMCk7CisgIGNvbnN0IHN0cmluZyBkZWJ1Z19zdHJpbmcgPSBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpOworICBjb25zdCBzdHJpbmcgb3RoZXJfZGVidWdfc3RyaW5nID0gb3RoZXJfbWVzc2FnZS5EZWJ1Z1N0cmluZygpOworICBFWFBFQ1RfTkUoZGVidWdfc3RyaW5nLCBvdGhlcl9kZWJ1Z19zdHJpbmcpOworCisgIGVtcHR5X21lc3NhZ2VfLlN3YXAoJm90aGVyX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoZGVidWdfc3RyaW5nLCBvdGhlcl9tZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworICBFWFBFQ1RfRVEob3RoZXJfZGVidWdfc3RyaW5nLCBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFN3YXBXaXRoU2VsZikgeworICBjb25zdCBzdHJpbmcgZGVidWdfc3RyaW5nID0gZW1wdHlfbWVzc2FnZV8uRGVidWdTdHJpbmcoKTsKKyAgRVhQRUNUX0dUKGVtcHR5X21lc3NhZ2VfLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSwgMCk7CisKKyAgZW1wdHlfbWVzc2FnZV8uU3dhcCgmZW1wdHlfbWVzc2FnZV8pOworICBFWFBFQ1RfR1QoZW1wdHlfbWVzc2FnZV8udW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpLCAwKTsKKyAgRVhQRUNUX0VRKGRlYnVnX3N0cmluZywgZW1wdHlfbWVzc2FnZV8uRGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBNZXJnZUZyb20pIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2Ugc291cmNlLCBkZXN0aW5hdGlvbjsKKworICBkZXN0aW5hdGlvbi5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxLCAxKTsKKyAgZGVzdGluYXRpb24ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMywgMik7CisgIHNvdXJjZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgyLCAzKTsKKyAgc291cmNlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDMsIDQpOworCisgIGRlc3RpbmF0aW9uLk1lcmdlRnJvbShzb3VyY2UpOworCisgIEVYUEVDVF9FUSgKKyAgICAvLyBOb3RlOiAgVGhlIG9yZGVyaW5nIG9mIGZpZWxkcyBoZXJlIGRlcGVuZHMgb24gdGhlIG9yZGVyaW5nIG9mIGFkZHMKKyAgICAvLyAgIGFuZCBtZXJnaW5nLCBhYm92ZS4KKyAgICAiMTogMVxuIgorICAgICIzOiAyXG4iCisgICAgIjI6IDNcbiIKKyAgICAiMzogNFxuIiwKKyAgICBkZXN0aW5hdGlvbi5EZWJ1Z1N0cmluZygpKTsKK30KKworCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgQ2xlYXIpIHsKKyAgLy8gQ2xlYXIgdGhlIHNldC4KKyAgZW1wdHlfbWVzc2FnZV8uQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIHVua25vd25fZmllbGRzXy0+ZmllbGRfY291bnQoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBDbGVhckFuZEZyZWVNZW1vcnkpIHsKKyAgRVhQRUNUX0dUKHVua25vd25fZmllbGRzXy0+ZmllbGRfY291bnQoKSwgMCk7CisgIHVua25vd25fZmllbGRzXy0+Q2xlYXJBbmRGcmVlTWVtb3J5KCk7CisgIEVYUEVDVF9FUSgwLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworICB1bmtub3duX2ZpZWxkc18tPkFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisgIEVYUEVDVF9FUSgxLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgUGFyc2VLbm93bkFuZFVua25vd24pIHsKKyAgLy8gVGVzdCBtaXhpbmcga25vd24gYW5kIHVua25vd24gZmllbGRzIHdoZW4gcGFyc2luZy4KKworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBzb3VyY2U7CisgIHNvdXJjZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisgIHN0cmluZyBkYXRhOworICBBU1NFUlRfVFJVRShzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpKTsKKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIGRlc3RpbmF0aW9uOworICBBU1NFUlRfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoYWxsX2ZpZWxkc19kYXRhXyArIGRhdGEpKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KGRlc3RpbmF0aW9uKTsKKyAgQVNTRVJUX0VRKDEsIGRlc3RpbmF0aW9uLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULAorICAgICAgICAgICAgZGVzdGluYXRpb24udW5rbm93bl9maWVsZHMoKS5maWVsZCgwKS50eXBlKCkpOworICBFWFBFQ1RfRVEoNjU0MzIxLCBkZXN0aW5hdGlvbi51bmtub3duX2ZpZWxkcygpLmZpZWxkKDApLnZhcmludCgpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFdyb25nVHlwZVRyZWF0ZWRBc1Vua25vd24pIHsKKyAgLy8gVGVzdCB0aGF0IGZpZWxkcyBvZiB0aGUgd3Jvbmcgd2lyZSB0eXBlIGFyZSB0cmVhdGVkIGxpa2UgdW5rbm93biBmaWVsZHMKKyAgLy8gd2hlbiBwYXJzaW5nLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgYWxsX3R5cGVzX21lc3NhZ2U7CisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5X21lc3NhZ2U7CisgIHN0cmluZyBiaXphcnJvX2RhdGEgPSBHZXRCaXphcnJvRGF0YSgpOworICBBU1NFUlRfVFJVRShhbGxfdHlwZXNfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoYml6YXJyb19kYXRhKSk7CisgIEFTU0VSVF9UUlVFKGVtcHR5X21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGJpemFycm9fZGF0YSkpOworCisgIC8vIEFsbCBmaWVsZHMgc2hvdWxkIGhhdmUgYmVlbiBpbnRlcnByZXRlZCBhcyB1bmtub3duLCBzbyB0aGUgZGVidWcgc3RyaW5ncworICAvLyBzaG91bGQgYmUgdGhlIHNhbWUuCisgIEVYUEVDVF9FUShlbXB0eV9tZXNzYWdlLkRlYnVnU3RyaW5nKCksIGFsbF90eXBlc19tZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgV3JvbmdUeXBlVHJlYXRlZEFzVW5rbm93blZpYVJlZmxlY3Rpb24pIHsKKyAgLy8gU2FtZSBhcyBXcm9uZ1R5cGVUcmVhdGVkQXNVbmtub3duIGJ1dCB2aWEgdGhlIHJlZmxlY3Rpb24gaW50ZXJmYWNlLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgYWxsX3R5cGVzX21lc3NhZ2U7CisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5X21lc3NhZ2U7CisgIHN0cmluZyBiaXphcnJvX2RhdGEgPSBHZXRCaXphcnJvRGF0YSgpOworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoYml6YXJyb19kYXRhLmRhdGEoKSwgYml6YXJyb19kYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBBU1NFUlRfVFJVRShXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZhbGxfdHlwZXNfbWVzc2FnZSkpOworICBBU1NFUlRfVFJVRShlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhiaXphcnJvX2RhdGEpKTsKKworICBFWFBFQ1RfRVEoZW1wdHlfbWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBhbGxfdHlwZXNfbWVzc2FnZS5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFVua25vd25FeHRlbnNpb25zKSB7CisgIC8vIE1ha2Ugc3VyZSBmaWVsZHMgYXJlIHByb3Blcmx5IHBhcnNlZCB0byB0aGUgVW5rbm93bkZpZWxkU2V0IGV2ZW4gd2hlbgorICAvLyB0aGV5IGFyZSBkZWNsYXJlZCBhcyBleHRlbnNpb24gbnVtYmVycy4KKworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIG1lc3NhZ2U7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGFsbF9maWVsZHNfZGF0YV8pKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFVua25vd25FeHRlbnNpb25zUmVmbGVjdGlvbikgeworICAvLyBTYW1lIGFzIFVua25vd25FeHRlbnNpb25zIGV4Y2VwdCBwYXJzaW5nIHZpYSByZWZsZWN0aW9uLgorCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGFsbF9maWVsZHNfZGF0YV8uZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsX2ZpZWxkc19kYXRhXy5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgQVNTRVJUX1RSVUUoV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmbWVzc2FnZSkpOworCisgIEVYUEVDVF9FUShtZXNzYWdlLkRlYnVnU3RyaW5nKCksIGVtcHR5X21lc3NhZ2VfLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgV3JvbmdFeHRlbnNpb25UeXBlVHJlYXRlZEFzVW5rbm93bikgeworICAvLyBUZXN0IHRoYXQgZmllbGRzIG9mIHRoZSB3cm9uZyB3aXJlIHR5cGUgYXJlIHRyZWF0ZWQgbGlrZSB1bmtub3duIGZpZWxkcworICAvLyB3aGVuIHBhcnNpbmcgZXh0ZW5zaW9ucy4KKworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnNfbWVzc2FnZTsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgZW1wdHlfbWVzc2FnZTsKKyAgc3RyaW5nIGJpemFycm9fZGF0YSA9IEdldEJpemFycm9EYXRhKCk7CisgIEFTU0VSVF9UUlVFKGFsbF9leHRlbnNpb25zX21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGJpemFycm9fZGF0YSkpOworICBBU1NFUlRfVFJVRShlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhiaXphcnJvX2RhdGEpKTsKKworICAvLyBBbGwgZmllbGRzIHNob3VsZCBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQgYXMgdW5rbm93biwgc28gdGhlIGRlYnVnIHN0cmluZ3MKKyAgLy8gc2hvdWxkIGJlIHRoZSBzYW1lLgorICBFWFBFQ1RfRVEoZW1wdHlfbWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBhbGxfZXh0ZW5zaW9uc19tZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgVW5rbm93bkVudW1WYWx1ZSkgeworICB1c2luZyB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOworICB1c2luZyB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM7CisgIHVzaW5nIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogc2luZ3VsYXJfZmllbGQgPQorICAgIFRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9lbnVtIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVwZWF0ZWRfZmllbGQgPQorICAgIFRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX25lc3RlZF9lbnVtIik7CisgIEFTU0VSVF9UUlVFKHNpbmd1bGFyX2ZpZWxkICE9IE5VTEwpOworICBBU1NFUlRfVFJVRShyZXBlYXRlZF9maWVsZCAhPSBOVUxMKTsKKworICBzdHJpbmcgZGF0YTsKKworICB7CisgICAgVGVzdEVtcHR5TWVzc2FnZSBlbXB0eV9tZXNzYWdlOworICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMgPSBlbXB0eV9tZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KHNpbmd1bGFyX2ZpZWxkLT5udW1iZXIoKSwgVGVzdEFsbFR5cGVzOjpCQVIpOworICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoc2luZ3VsYXJfZmllbGQtPm51bWJlcigpLCA1KTsgIC8vIG5vdCB2YWxpZAorICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQocmVwZWF0ZWRfZmllbGQtPm51bWJlcigpLCBUZXN0QWxsVHlwZXM6OkZPTyk7CisgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIDQpOyAgLy8gbm90IHZhbGlkCisgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIFRlc3RBbGxUeXBlczo6QkFaKTsKKyAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KHJlcGVhdGVkX2ZpZWxkLT5udW1iZXIoKSwgNik7ICAvLyBub3QgdmFsaWQKKyAgICBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgfQorCisgIHsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBBU1NFUlRfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICAgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtKDApKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0oMSkpOworCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcyA9IG1lc3NhZ2UudW5rbm93bl9maWVsZHMoKTsKKyAgICBBU1NFUlRfRVEoMywgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKSk7CisKKyAgICBFWFBFQ1RfRVEoc2luZ3VsYXJfZmllbGQtPm51bWJlcigpLCB1bmtub3duX2ZpZWxkcy5maWVsZCgwKS5udW1iZXIoKSk7CisgICAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQsIHVua25vd25fZmllbGRzLmZpZWxkKDApLnR5cGUoKSk7CisgICAgRVhQRUNUX0VRKDUsIHVua25vd25fZmllbGRzLmZpZWxkKDApLnZhcmludCgpKTsKKworICAgIEVYUEVDVF9FUShyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIHVua25vd25fZmllbGRzLmZpZWxkKDEpLm51bWJlcigpKTsKKyAgICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwgdW5rbm93bl9maWVsZHMuZmllbGQoMSkudHlwZSgpKTsKKyAgICBFWFBFQ1RfRVEoNCwgdW5rbm93bl9maWVsZHMuZmllbGQoMSkudmFyaW50KCkpOworCisgICAgRVhQRUNUX0VRKHJlcGVhdGVkX2ZpZWxkLT5udW1iZXIoKSwgdW5rbm93bl9maWVsZHMuZmllbGQoMikubnVtYmVyKCkpOworICAgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULCB1bmtub3duX2ZpZWxkcy5maWVsZCgyKS50eXBlKCkpOworICAgIEVYUEVDVF9FUSg2LCB1bmtub3duX2ZpZWxkcy5maWVsZCgyKS52YXJpbnQoKSk7CisgIH0KKworICB7CisgICAgdXNpbmcgdW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbjsKKyAgICB1c2luZyB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uOworCisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgICBBU1NFUlRfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLAorICAgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbihvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24pKTsKKyAgICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbikpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkZPTywKKyAgICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24ocmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uLCAwKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFaLAorICAgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbihyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24sIDEpKTsKKworICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMgPSBtZXNzYWdlLnVua25vd25fZmllbGRzKCk7CisgICAgQVNTRVJUX0VRKDMsIHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCkpOworCisgICAgRVhQRUNUX0VRKHNpbmd1bGFyX2ZpZWxkLT5udW1iZXIoKSwgdW5rbm93bl9maWVsZHMuZmllbGQoMCkubnVtYmVyKCkpOworICAgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULCB1bmtub3duX2ZpZWxkcy5maWVsZCgwKS50eXBlKCkpOworICAgIEVYUEVDVF9FUSg1LCB1bmtub3duX2ZpZWxkcy5maWVsZCgwKS52YXJpbnQoKSk7CisKKyAgICBFWFBFQ1RfRVEocmVwZWF0ZWRfZmllbGQtPm51bWJlcigpLCB1bmtub3duX2ZpZWxkcy5maWVsZCgxKS5udW1iZXIoKSk7CisgICAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQsIHVua25vd25fZmllbGRzLmZpZWxkKDEpLnR5cGUoKSk7CisgICAgRVhQRUNUX0VRKDQsIHVua25vd25fZmllbGRzLmZpZWxkKDEpLnZhcmludCgpKTsKKworICAgIEVYUEVDVF9FUShyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIHVua25vd25fZmllbGRzLmZpZWxkKDIpLm51bWJlcigpKTsKKyAgICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwgdW5rbm93bl9maWVsZHMuZmllbGQoMikudHlwZSgpKTsKKyAgICBFWFBFQ1RfRVEoNiwgdW5rbm93bl9maWVsZHMuZmllbGQoMikudmFyaW50KCkpOworICB9Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKSB7CisgIFVua25vd25GaWVsZFNldCBlbXB0eTsKKyAgZW1wdHkuQWRkVmFyaW50KDEsIDApOworICBFWFBFQ1RfRVEoc2l6ZW9mKHZlY3RvcjxVbmtub3duRmllbGQ+KSArIHNpemVvZihVbmtub3duRmllbGQpLAorICAgICAgICAgICAgZW1wdHkuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFNwYWNlVXNlZCkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBlbXB0eV9tZXNzYWdlOworCisgIC8vIE1ha2Ugc3VyZSBhbiB1bmtub3duIGZpZWxkIHNldCBoYXMgemVybyBzcGFjZSB1c2VkIHVudGlsIGEgZmllbGQgaXMKKyAgLy8gYWN0dWFsbHkgYWRkZWQuCisgIGludCBiYXNlX3NpemUgPSBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpOworICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzID0gZW1wdHlfbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIEVYUEVDVF9FUShiYXNlX3NpemUsIGVtcHR5X21lc3NhZ2UuU3BhY2VVc2VkKCkpOworCisgIC8vIE1ha2Ugc3VyZSBlYWNoIHRoaW5nIHdlIGFkZCB0byB0aGUgc2V0IGluY3JlYXNlcyB0aGUgU3BhY2VVc2VkKCkuCisgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoMSwgMCk7CisgIEVYUEVDVF9MVChiYXNlX3NpemUsIGVtcHR5X21lc3NhZ2UuU3BhY2VVc2VkKCkpOworICBiYXNlX3NpemUgPSBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpOworCisgIHN0cmluZyogc3RyID0gdW5rbm93bl9maWVsZHMtPkFkZExlbmd0aERlbGltaXRlZCgxKTsKKyAgRVhQRUNUX0xUKGJhc2Vfc2l6ZSwgZW1wdHlfbWVzc2FnZS5TcGFjZVVzZWQoKSk7CisgIGJhc2Vfc2l6ZSA9IGVtcHR5X21lc3NhZ2UuU3BhY2VVc2VkKCk7CisKKyAgc3RyLT5hc3NpZ24oc2l6ZW9mKHN0cmluZykgKyAxLCAneCcpOworICBFWFBFQ1RfTFQoYmFzZV9zaXplLCBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgYmFzZV9zaXplID0gZW1wdHlfbWVzc2FnZS5TcGFjZVVzZWQoKTsKKworICBVbmtub3duRmllbGRTZXQqIGdyb3VwID0gdW5rbm93bl9maWVsZHMtPkFkZEdyb3VwKDEpOworICBFWFBFQ1RfTFQoYmFzZV9zaXplLCBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgYmFzZV9zaXplID0gZW1wdHlfbWVzc2FnZS5TcGFjZVVzZWQoKTsKKworICBncm91cC0+QWRkVmFyaW50KDEsIDApOworICBFWFBFQ1RfTFQoYmFzZV9zaXplLCBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpKTsKK30KKworCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgRW1wdHkpIHsKKyAgVW5rbm93bkZpZWxkU2V0IHVua25vd25fZmllbGRzOworICBFWFBFQ1RfVFJVRSh1bmtub3duX2ZpZWxkcy5lbXB0eSgpKTsKKyAgdW5rbm93bl9maWVsZHMuQWRkVmFyaW50KDYsIDEyMyk7CisgIEVYUEVDVF9GQUxTRSh1bmtub3duX2ZpZWxkcy5lbXB0eSgpKTsKKyAgdW5rbm93bl9maWVsZHMuQ2xlYXIoKTsKKyAgRVhQRUNUX1RSVUUodW5rbm93bl9maWVsZHMuZW1wdHkoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBEZWxldGVTdWJyYW5nZSkgeworICAvLyBFeGhhdXN0aXZlbHkgdGVzdCB0aGUgZGVsZXRpb24gb2YgZXZlcnkgcG9zc2libGUgc3VicmFuZ2UgaW4gYXJyYXlzIG9mIGFsbAorICAvLyBzaXplcyBmcm9tIDAgdGhyb3VnaCA5LgorICBmb3IgKGludCBzaXplID0gMDsgc2l6ZSA8IDEwOyArK3NpemUpIHsKKyAgICBmb3IgKGludCBudW0gPSAwOyBudW0gPD0gc2l6ZTsgKytudW0pIHsKKyAgICAgIGZvciAoaW50IHN0YXJ0ID0gMDsgc3RhcnQgPCBzaXplIC0gbnVtOyArK3N0YXJ0KSB7CisgICAgICAgIC8vIENyZWF0ZSBhIHNldCB3aXRoICJzaXplIiBmaWVsZHMuCisgICAgICAgIFVua25vd25GaWVsZFNldCB1bmtub3duOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgeworICAgICAgICAgIHVua25vd24uQWRkRml4ZWQzMihpLCBpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBEZWxldGUgdGhlIHNwZWNpZmllZCBzdWJyYW5nZS4KKyAgICAgICAgdW5rbm93bi5EZWxldGVTdWJyYW5nZShzdGFydCwgbnVtKTsKKyAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSByZXN1bHRpbmcgZmllbGQgdmFsdWVzIGFyZSBzdGlsbCBjb3JyZWN0LgorICAgICAgICBFWFBFQ1RfRVEoc2l6ZSAtIG51bSwgdW5rbm93bi5maWVsZF9jb3VudCgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duLmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgICAgICAgIGlmIChpIDwgc3RhcnQpIHsKKyAgICAgICAgICAgIEVYUEVDVF9FUShpLCB1bmtub3duLmZpZWxkKGkpLmZpeGVkMzIoKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEVYUEVDVF9FUShpICsgbnVtLCB1bmtub3duLmZpZWxkKGkpLmZpeGVkMzIoKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgQ2hlY2tEZWxldGVCeU51bWJlcihjb25zdCB2ZWN0b3I8aW50PiYgZmllbGRfbnVtYmVycywgaW50IGRlbGV0ZWRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPGludD4mIGV4cGVjdGVkX2ZpZWxkX251Ym1lcnMpIHsKKyAgVW5rbm93bkZpZWxkU2V0IHVua25vd25fZmllbGRzOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkX251bWJlcnMuc2l6ZSgpOyArK2kpIHsKKyAgICB1bmtub3duX2ZpZWxkcy5BZGRGaXhlZDMyKGZpZWxkX251bWJlcnNbaV0sIGkpOworICB9CisgIHVua25vd25fZmllbGRzLkRlbGV0ZUJ5TnVtYmVyKGRlbGV0ZWRfbnVtYmVyKTsKKyAgQVNTRVJUX0VRKGV4cGVjdGVkX2ZpZWxkX251Ym1lcnMuc2l6ZSgpLCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZF9maWVsZF9udWJtZXJzLnNpemUoKTsgKytpKSB7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2ZpZWxkX251Ym1lcnNbaV0sCisgICAgICAgICAgICAgIHVua25vd25fZmllbGRzLmZpZWxkKGkpLm51bWJlcigpKTsKKyAgfQorfQorCisjZGVmaW5lIE1BS0VfVkVDVE9SKHgpIHZlY3RvcjxpbnQ+KHgsIHggKyBHT09HTEVfQVJSQVlTSVpFKHgpKQorVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIERlbGV0ZUJ5TnVtYmVyKSB7CisgIENoZWNrRGVsZXRlQnlOdW1iZXIodmVjdG9yPGludD4oKSwgMSwgdmVjdG9yPGludD4oKSk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Rlc3RGaWVsZE51bWJlcnMxW10gPSB7MSwgMiwgM307CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpZWxkTnVtYmVyVG9EZWxldGUxID0gMTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXhwZWN0ZWRGaWVsZE51bWJlcnMxW10gPSB7MiwgM307CisgIENoZWNrRGVsZXRlQnlOdW1iZXIoTUFLRV9WRUNUT1Ioa1Rlc3RGaWVsZE51bWJlcnMxKSwga0ZpZWxkTnVtYmVyVG9EZWxldGUxLAorICAgICAgICAgICAgICAgICAgICAgIE1BS0VfVkVDVE9SKGtFeHBlY3RlZEZpZWxkTnVtYmVyczEpKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVGVzdEZpZWxkTnVtYmVyczJbXSA9IHsxLCAyLCAzfTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmllbGROdW1iZXJUb0RlbGV0ZTIgPSAyOworICBzdGF0aWMgY29uc3QgaW50IGtFeHBlY3RlZEZpZWxkTnVtYmVyczJbXSA9IHsxLCAzfTsKKyAgQ2hlY2tEZWxldGVCeU51bWJlcihNQUtFX1ZFQ1RPUihrVGVzdEZpZWxkTnVtYmVyczIpLCBrRmllbGROdW1iZXJUb0RlbGV0ZTIsCisgICAgICAgICAgICAgICAgICAgICAgTUFLRV9WRUNUT1Ioa0V4cGVjdGVkRmllbGROdW1iZXJzMikpOworICBzdGF0aWMgY29uc3QgaW50IGtUZXN0RmllbGROdW1iZXJzM1tdID0gezEsIDIsIDN9OworICBzdGF0aWMgY29uc3QgaW50IGtGaWVsZE51bWJlclRvRGVsZXRlMyA9IDM7CisgIHN0YXRpYyBjb25zdCBpbnQga0V4cGVjdGVkRmllbGROdW1iZXJzM1tdID0gezEsIDJ9OworICBDaGVja0RlbGV0ZUJ5TnVtYmVyKE1BS0VfVkVDVE9SKGtUZXN0RmllbGROdW1iZXJzMyksIGtGaWVsZE51bWJlclRvRGVsZXRlMywKKyAgICAgICAgICAgICAgICAgICAgICBNQUtFX1ZFQ1RPUihrRXhwZWN0ZWRGaWVsZE51bWJlcnMzKSk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Rlc3RGaWVsZE51bWJlcnM0W10gPSB7MSwgMiwgMSwgNCwgMX07CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpZWxkTnVtYmVyVG9EZWxldGU0ID0gMTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXhwZWN0ZWRGaWVsZE51bWJlcnM0W10gPSB7MiwgNH07CisgIENoZWNrRGVsZXRlQnlOdW1iZXIoTUFLRV9WRUNUT1Ioa1Rlc3RGaWVsZE51bWJlcnM0KSwga0ZpZWxkTnVtYmVyVG9EZWxldGU0LAorICAgICAgICAgICAgICAgICAgICAgIE1BS0VfVkVDVE9SKGtFeHBlY3RlZEZpZWxkTnVtYmVyczQpKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVGVzdEZpZWxkTnVtYmVyczVbXSA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmllbGROdW1iZXJUb0RlbGV0ZTUgPSA2OworICBzdGF0aWMgY29uc3QgaW50IGtFeHBlY3RlZEZpZWxkTnVtYmVyczVbXSA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgQ2hlY2tEZWxldGVCeU51bWJlcihNQUtFX1ZFQ1RPUihrVGVzdEZpZWxkTnVtYmVyczUpLCBrRmllbGROdW1iZXJUb0RlbGV0ZTUsCisgICAgICAgICAgICAgICAgICAgICAgTUFLRV9WRUNUT1Ioa0V4cGVjdGVkRmllbGROdW1iZXJzNSkpOworfQorI3VuZGVmIE1BS0VfVkVDVE9SCit9ICAvLyBuYW1lc3BhY2UKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNWJiYmYyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5jYwpAQCAtMCwwICsxLDExNDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPHN0YWNrPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKworCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK25hbWVzcGFjZSB7CisKKy8vIFRoaXMgZnVuY3Rpb24gdHVybnMgb3V0IHRvIGJlIGNvbnZlbmllbnQgd2hlbiB1c2luZyBzb21lIG1hY3JvcyBsYXRlci4KK2lubGluZSBpbnQgR2V0RW51bU51bWJlcihjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5udW1iZXIoKTsKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2Jvb2wgVW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyOjpTa2lwRmllbGQoCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnKSB7CisgIHJldHVybiBXaXJlRm9ybWF0OjpTa2lwRmllbGQoaW5wdXQsIHRhZywgdW5rbm93bl9maWVsZHNfKTsKK30KKworYm9vbCBVbmtub3duRmllbGRTZXRGaWVsZFNraXBwZXI6OlNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICByZXR1cm4gV2lyZUZvcm1hdDo6U2tpcE1lc3NhZ2UoaW5wdXQsIHVua25vd25fZmllbGRzXyk7Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyOjpTa2lwVW5rbm93bkVudW0oCisgICAgaW50IGZpZWxkX251bWJlciwgaW50IHZhbHVlKSB7CisgIHVua25vd25fZmllbGRzXy0+QWRkVmFyaW50KGZpZWxkX251bWJlciwgdmFsdWUpOworfQorCitib29sIFdpcmVGb3JtYXQ6OlNraXBGaWVsZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIGludCBudW1iZXIgPSBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKTsKKworICBzd2l0Y2ggKFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpKSB7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5UOiB7CisgICAgICB1aW50NjQgdmFsdWU7CisgICAgICBpZiAoIWlucHV0LT5SZWFkVmFyaW50NjQoJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHVua25vd25fZmllbGRzICE9IE5VTEwpIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQobnVtYmVyLCB2YWx1ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NDogeworICAgICAgdWludDY0IHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkcyAhPSBOVUxMKSB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQ2NChudW1iZXIsIHZhbHVlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOiB7CisgICAgICB1aW50MzIgbGVuZ3RoOworICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodW5rbm93bl9maWVsZHMgPT0gTlVMTCkgeworICAgICAgICBpZiAoIWlucHV0LT5Ta2lwKGxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmICghaW5wdXQtPlJlYWRTdHJpbmcodW5rbm93bl9maWVsZHMtPkFkZExlbmd0aERlbGltaXRlZChudW1iZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9TVEFSVF9HUk9VUDogeworICAgICAgaWYgKCFpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSkgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCFTa2lwTWVzc2FnZShpbnB1dCwgKHVua25vd25fZmllbGRzID09IE5VTEwpID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgOiB1bmtub3duX2ZpZWxkcy0+QWRkR3JvdXAobnVtYmVyKSkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgaW5wdXQtPkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAvLyBDaGVjayB0aGF0IHRoZSBlbmRpbmcgdGFnIG1hdGNoZWQgdGhlIHN0YXJ0aW5nIHRhZy4KKyAgICAgIGlmICghaW5wdXQtPkxhc3RUYWdXYXMoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVA6IHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMjogeworICAgICAgdWludDMyIHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkcyAhPSBOVUxMKSB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQzMihudW1iZXIsIHZhbHVlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBkZWZhdWx0OiB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6U2tpcE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIHdoaWxlICh0cnVlKSB7CisgICAgdWludDMyIHRhZyA9IGlucHV0LT5SZWFkVGFnKCk7CisgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAvLyBFbmQgb2YgaW5wdXQuICBUaGlzIGlzIGEgdmFsaWQgcGxhY2UgdG8gZW5kLCBzbyByZXR1cm4gdHJ1ZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSB3aXJlX3R5cGUgPSBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKTsKKworICAgIGlmICh3aXJlX3R5cGUgPT0gV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgLy8gTXVzdCBiZSB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLgorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKCFTa2lwRmllbGQoaW5wdXQsIHRhZywgdW5rbm93bl9maWVsZHMpKSByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBXaXJlRm9ybWF0OjpSZWFkUGFja2VkRW51bVByZXNlcnZlVW5rbm93bnMoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgKCppc192YWxpZCkoaW50KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPGludD4qIHZhbHVlcykgeworICB1aW50MzIgbGVuZ3RoOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gaW5wdXQtPlB1c2hMaW1pdChsZW5ndGgpOworICB3aGlsZSAoaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeworICAgIGludCB2YWx1ZTsKKyAgICBpZiAoIWdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgaW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPihpbnB1dCwgJnZhbHVlKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoaXNfdmFsaWQgPT0gTlVMTCB8fCBpc192YWxpZCh2YWx1ZSkpIHsKKyAgICAgIHZhbHVlcy0+QWRkKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChmaWVsZF9udW1iZXIsIHZhbHVlKTsKKyAgICB9CisgIH0KKyAgaW5wdXQtPlBvcExpbWl0KGxpbWl0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKwordm9pZCBXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBVbmtub3duRmllbGQmIGZpZWxkID0gdW5rbm93bl9maWVsZHMuZmllbGQoaSk7CisgICAgc3dpdGNoIChmaWVsZC50eXBlKCkpIHsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVDoKKyAgICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCkpOworICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50NjQoZmllbGQudmFyaW50KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVEMzI6CisgICAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDMyKSk7CisgICAgICAgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW4zMihmaWVsZC5maXhlZDMyKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVENjQ6CisgICAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0KSk7CisgICAgICAgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW42NChmaWVsZC5maXhlZDY0KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0xFTkdUSF9ERUxJTUlURUQ6CisgICAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKSk7CisgICAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihmaWVsZC5sZW5ndGhfZGVsaW1pdGVkKCkuc2l6ZSgpKTsKKyAgICAgICAgb3V0cHV0LT5Xcml0ZVJhd01heWJlQWxpYXNlZChmaWVsZC5sZW5ndGhfZGVsaW1pdGVkKCkuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLmxlbmd0aF9kZWxpbWl0ZWQoKS5zaXplKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQOgorICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVApKTsKKyAgICAgICAgU2VyaWFsaXplVW5rbm93bkZpZWxkcyhmaWVsZC5ncm91cCgpLCBvdXRwdXQpOworICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCit1aW50OCogV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICB1aW50OCogdGFyZ2V0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZCA9IHVua25vd25fZmllbGRzLmZpZWxkKGkpOworCisgICAgc3dpdGNoIChmaWVsZC50eXBlKCkpIHsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVDoKKyAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjRUb0FycmF5KAorICAgICAgICAgICAgZmllbGQubnVtYmVyKCksIGZpZWxkLnZhcmludCgpLCB0YXJnZXQpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVEMzI6CisgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZUZpeGVkMzJUb0FycmF5KAorICAgICAgICAgICAgZmllbGQubnVtYmVyKCksIGZpZWxkLmZpeGVkMzIoKSwgdGFyZ2V0KTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0OgorICAgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDY0VG9BcnJheSgKKyAgICAgICAgICAgIGZpZWxkLm51bWJlcigpLCBmaWVsZC5maXhlZDY0KCksIHRhcmdldCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlQnl0ZXNUb0FycmF5KAorICAgICAgICAgICAgZmllbGQubnVtYmVyKCksIGZpZWxkLmxlbmd0aF9kZWxpbWl0ZWQoKSwgdGFyZ2V0KTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9HUk9VUDoKKyAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlVGFnVG9BcnJheSgKKyAgICAgICAgICAgIGZpZWxkLm51bWJlcigpLCBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVAsIHRhcmdldCk7CisgICAgICAgIHRhcmdldCA9IFNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KGZpZWxkLmdyb3VwKCksIHRhcmdldCk7CisgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgICAgICAgICBmaWVsZC5udW1iZXIoKSwgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCwgdGFyZ2V0KTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHJldHVybiB0YXJnZXQ7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bk1lc3NhZ2VTZXRJdGVtcygKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZCA9IHVua25vd25fZmllbGRzLmZpZWxkKGkpOworICAgIC8vIFRoZSBvbmx5IHVua25vd24gZmllbGRzIHRoYXQgYXJlIGFsbG93ZWQgdG8gZXhpc3QgaW4gYSBNZXNzYWdlU2V0IGFyZQorICAgIC8vIG1lc3NhZ2VzLCB3aGljaCBhcmUgbGVuZ3RoLWRlbGltaXRlZC4KKyAgICBpZiAoZmllbGQudHlwZSgpID09IFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICAvLyBTdGFydCBncm91cC4KKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtU3RhcnRUYWcpOworCisgICAgICAvLyBXcml0ZSB0eXBlIElELgorICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZyk7CisgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoZmllbGQubnVtYmVyKCkpOworCisgICAgICAvLyBXcml0ZSBtZXNzYWdlLgorICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldE1lc3NhZ2VUYWcpOworICAgICAgZmllbGQuU2VyaWFsaXplTGVuZ3RoRGVsaW1pdGVkTm9UYWcob3V0cHV0KTsKKworICAgICAgLy8gRW5kIGdyb3VwLgorICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1FbmRUYWcpOworICAgIH0KKyAgfQorfQorCit1aW50OCogV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bk1lc3NhZ2VTZXRJdGVtc1RvQXJyYXkoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICB1aW50OCogdGFyZ2V0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZCA9IHVua25vd25fZmllbGRzLmZpZWxkKGkpOworCisgICAgLy8gVGhlIG9ubHkgdW5rbm93biBmaWVsZHMgdGhhdCBhcmUgYWxsb3dlZCB0byBleGlzdCBpbiBhIE1lc3NhZ2VTZXQgYXJlCisgICAgLy8gbWVzc2FnZXMsIHdoaWNoIGFyZSBsZW5ndGgtZGVsaW1pdGVkLgorICAgIGlmIChmaWVsZC50eXBlKCkgPT0gVW5rbm93bkZpZWxkOjpUWVBFX0xFTkdUSF9ERUxJTUlURUQpIHsKKyAgICAgIC8vIFN0YXJ0IGdyb3VwLgorICAgICAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnLCB0YXJnZXQpOworCisgICAgICAvLyBXcml0ZSB0eXBlIElELgorICAgICAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0VHlwZUlkVGFnLCB0YXJnZXQpOworICAgICAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSgKKyAgICAgICAgICBmaWVsZC5udW1iZXIoKSwgdGFyZ2V0KTsKKworICAgICAgLy8gV3JpdGUgbWVzc2FnZS4KKyAgICAgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldE1lc3NhZ2VUYWcsIHRhcmdldCk7CisgICAgICB0YXJnZXQgPSBmaWVsZC5TZXJpYWxpemVMZW5ndGhEZWxpbWl0ZWROb1RhZ1RvQXJyYXkodGFyZ2V0KTsKKworICAgICAgLy8gRW5kIGdyb3VwLgorICAgICAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZywgdGFyZ2V0KTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgV2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMpIHsKKyAgaW50IHNpemUgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSB1bmtub3duX2ZpZWxkcy5maWVsZChpKTsKKworICAgIHN3aXRjaCAoZmllbGQudHlwZSgpKSB7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQ6CisgICAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQpKTsKKyAgICAgICAgc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemU2NChmaWVsZC52YXJpbnQoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfRklYRUQzMjoKKyAgICAgICAgc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzIpKTsKKyAgICAgICAgc2l6ZSArPSBzaXplb2YoaW50MzIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVENjQ6CisgICAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0KSk7CisgICAgICAgIHNpemUgKz0gc2l6ZW9mKGludDY0KTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpOworICAgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgICAgICAgZmllbGQubGVuZ3RoX2RlbGltaXRlZCgpLnNpemUoKSk7CisgICAgICAgIHNpemUgKz0gZmllbGQubGVuZ3RoX2RlbGltaXRlZCgpLnNpemUoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9HUk9VUDoKKyAgICAgICAgc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1NUQVJUX0dST1VQKSk7CisgICAgICAgIHNpemUgKz0gQ29tcHV0ZVVua25vd25GaWVsZHNTaXplKGZpZWxkLmdyb3VwKCkpOworICAgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIHJldHVybiBzaXplOworfQorCitpbnQgV2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25NZXNzYWdlU2V0SXRlbXNTaXplKAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMpIHsKKyAgaW50IHNpemUgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSB1bmtub3duX2ZpZWxkcy5maWVsZChpKTsKKworICAgIC8vIFRoZSBvbmx5IHVua25vd24gZmllbGRzIHRoYXQgYXJlIGFsbG93ZWQgdG8gZXhpc3QgaW4gYSBNZXNzYWdlU2V0IGFyZQorICAgIC8vIG1lc3NhZ2VzLCB3aGljaCBhcmUgbGVuZ3RoLWRlbGltaXRlZC4KKyAgICBpZiAoZmllbGQudHlwZSgpID09IFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICBzaXplICs9IFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1UYWdzU2l6ZTsKKyAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoZmllbGQubnVtYmVyKCkpOworCisgICAgICBpbnQgZmllbGRfc2l6ZSA9IGZpZWxkLkdldExlbmd0aERlbGltaXRlZFNpemUoKTsKKyAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoZmllbGRfc2l6ZSk7CisgICAgICBzaXplICs9IGZpZWxkX3NpemU7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHNpemU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworYm9vbCBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHdoaWxlKHRydWUpIHsKKyAgICB1aW50MzIgdGFnID0gaW5wdXQtPlJlYWRUYWcoKTsKKyAgICBpZiAodGFnID09IDApIHsKKyAgICAgIC8vIEVuZCBvZiBpbnB1dC4gIFRoaXMgaXMgYSB2YWxpZCBwbGFjZSB0byBlbmQsIHNvIHJldHVybiB0cnVlLgorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgIC8vIE11c3QgYmUgdGhlIGVuZCBvZiB0aGUgbWVzc2FnZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBOVUxMOworCisgICAgaWYgKGRlc2NyaXB0b3IgIT0gTlVMTCkgeworICAgICAgaW50IGZpZWxkX251bWJlciA9IFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpOworICAgICAgZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU51bWJlcihmaWVsZF9udW1iZXIpOworCisgICAgICAvLyBJZiB0aGF0IGZhaWxlZCwgY2hlY2sgaWYgdGhlIGZpZWxkIGlzIGFuIGV4dGVuc2lvbi4KKyAgICAgIGlmIChmaWVsZCA9PSBOVUxMICYmIGRlc2NyaXB0b3ItPklzRXh0ZW5zaW9uTnVtYmVyKGZpZWxkX251bWJlcikpIHsKKyAgICAgICAgaWYgKGlucHV0LT5HZXRFeHRlbnNpb25Qb29sKCkgPT0gTlVMTCkgeworICAgICAgICAgIGZpZWxkID0gbWVzc2FnZV9yZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihmaWVsZF9udW1iZXIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGZpZWxkID0gaW5wdXQtPkdldEV4dGVuc2lvblBvb2woKQorICAgICAgICAgICAgICAgICAgICAgICAtPkZpbmRFeHRlbnNpb25CeU51bWJlcihkZXNjcmlwdG9yLCBmaWVsZF9udW1iZXIpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIElmIHRoYXQgZmFpbGVkLCBidXQgd2UncmUgYSBNZXNzYWdlU2V0LCBhbmQgdGhpcyBpcyB0aGUgdGFnIGZvciBhCisgICAgICAvLyBNZXNzYWdlU2V0IGl0ZW0sIHRoZW4gcGFyc2UgdGhhdC4KKyAgICAgIGlmIChmaWVsZCA9PSBOVUxMICYmCisgICAgICAgICAgZGVzY3JpcHRvci0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgJiYKKyAgICAgICAgICB0YWcgPT0gV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnKSB7CisgICAgICAgIGlmICghUGFyc2VBbmRNZXJnZU1lc3NhZ2VTZXRJdGVtKGlucHV0LCBtZXNzYWdlKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBjb250aW51ZTsgIC8vIFNraXAgUGFyc2VBbmRNZXJnZUZpZWxkKCk7IGFscmVhZHkgdGFrZW4gY2FyZSBvZi4KKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoIVBhcnNlQW5kTWVyZ2VGaWVsZCh0YWcsIGZpZWxkLCBtZXNzYWdlLCBpbnB1dCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KK30KKworYm9vbCBXaXJlRm9ybWF0OjpTa2lwTWVzc2FnZVNldEZpZWxkKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgdWludDMyIGxlbmd0aDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiBpbnB1dC0+UmVhZFN0cmluZygKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRMZW5ndGhEZWxpbWl0ZWQoZmllbGRfbnVtYmVyKSwgbGVuZ3RoKTsKK30KKworYm9vbCBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlTWVzc2FnZVNldEZpZWxkKHVpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgLy8gV2Ugc3RvcmUgdW5rbm93biBNZXNzYWdlU2V0IGV4dGVuc2lvbnMgYXMgZ3JvdXBzLgorICAgIHJldHVybiBTa2lwTWVzc2FnZVNldEZpZWxkKAorICAgICAgICBpbnB1dCwgZmllbGRfbnVtYmVyLCBtZXNzYWdlX3JlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpKTsKKyAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSB8fAorICAgICAgICAgICAgIGZpZWxkLT50eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICAvLyBUaGlzIHNob3VsZG4ndCBoYXBwZW4gYXMgd2Ugb25seSBhbGxvdyBvcHRpb25hbCBtZXNzYWdlIGV4dGVuc2lvbnMgdG8KKyAgICAvLyBNZXNzYWdlU2V0LgorICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJFeHRlbnNpb25zIG9mIE1lc3NhZ2VTZXRzIG11c3QgYmUgb3B0aW9uYWwgbWVzc2FnZXMuIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKAorICAgICAgICBtZXNzYWdlLCBmaWVsZCwgaW5wdXQtPkdldEV4dGVuc2lvbkZhY3RvcnkoKSk7CisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZShpbnB1dCwgc3ViX21lc3NhZ2UpOworICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZUZpZWxkKAorICAgIHVpbnQzMiB0YWcsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgICAgICAgIC8vIE1heSBiZSBOVUxMIGZvciB1bmtub3duCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIGVudW0geyBVTktOT1dOLCBOT1JNQUxfRk9STUFULCBQQUNLRURfRk9STUFUIH0gdmFsdWVfZm9ybWF0OworCisgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgdmFsdWVfZm9ybWF0ID0gVU5LTk9XTjsKKyAgfSBlbHNlIGlmIChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgIFdpcmVUeXBlRm9yRmllbGRUeXBlKGZpZWxkLT50eXBlKCkpKSB7CisgICAgdmFsdWVfZm9ybWF0ID0gTk9STUFMX0ZPUk1BVDsKKyAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcGFja2FibGUoKSAmJgorICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpIHsKKyAgICB2YWx1ZV9mb3JtYXQgPSBQQUNLRURfRk9STUFUOworICB9IGVsc2UgeworICAgIC8vIFdlIGRvbid0IHJlY29nbml6ZSB0aGlzIGZpZWxkLiBFaXRoZXIgdGhlIGZpZWxkIG51bWJlciBpcyB1bmtub3duCisgICAgLy8gb3IgdGhlIHdpcmUgdHlwZSBkb2Vzbid0IG1hdGNoLiBQdXQgaXQgaW4gb3VyIHVua25vd24gZmllbGQgc2V0LgorICAgIHZhbHVlX2Zvcm1hdCA9IFVOS05PV047CisgIH0KKworICBpZiAodmFsdWVfZm9ybWF0ID09IFVOS05PV04pIHsKKyAgICByZXR1cm4gU2tpcEZpZWxkKGlucHV0LCB0YWcsCisgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpKTsKKyAgfSBlbHNlIGlmICh2YWx1ZV9mb3JtYXQgPT0gUEFDS0VEX0ZPUk1BVCkgeworICAgIHVpbnQzMiBsZW5ndGg7CisgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gaW5wdXQtPlB1c2hMaW1pdChsZW5ndGgpOworCisgICAgc3dpdGNoIChmaWVsZC0+dHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9QQUNLRURfVFlQRShUWVBFLCBDUFBUWVBFLCBDUFBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgd2hpbGUgKGlucHV0LT5CeXRlc1VudGlsTGltaXQoKSA+IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgQ1BQVFlQRSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBDUFBUWVBFLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI1RZUEU+KGlucHV0LCAmdmFsdWUpKSAgICAgICAgICBcCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkIyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfQorCisgICAgICBIQU5ETEVfUEFDS0VEX1RZUEUoIElOVDMyLCAgaW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRSggSU5UNjQsICBpbnQ2NCwgIEludDY0KQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKFNJTlQzMiwgIGludDMyLCAgSW50MzIpCisgICAgICBIQU5ETEVfUEFDS0VEX1RZUEUoU0lOVDY0LCAgaW50NjQsICBJbnQ2NCkKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShVSU5UMzIsIHVpbnQzMiwgVUludDMyKQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKFVJTlQ2NCwgdWludDY0LCBVSW50NjQpCisKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRSggRklYRUQzMiwgdWludDMyLCBVSW50MzIpCisgICAgICBIQU5ETEVfUEFDS0VEX1RZUEUoIEZJWEVENjQsIHVpbnQ2NCwgVUludDY0KQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKFNGSVhFRDMyLCAgaW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShTRklYRUQ2NCwgIGludDY0LCAgSW50NjQpCisKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShGTE9BVCAsIGZsb2F0ICwgRmxvYXQgKQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUpCisKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShCT09MLCBib29sLCBCb29sKQorI3VuZGVmIEhBTkRMRV9QQUNLRURfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOiB7CisgICAgICAgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+ZmlsZSgpLT5zeW50YXgoKSA9PQorICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5BZGRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgICAgICAgICAgICBpZiAoZW51bV92YWx1ZSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBmaWVsZCwgZW51bV92YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAvLyBUaGUgZW51bSB2YWx1ZSBpcyBub3Qgb25lIG9mIHRoZSBrbm93biB2YWx1ZXMuICBBZGQgaXQgdG8gdGhlCisgICAgICAgICAgICAgIC8vIFVua25vd25GaWVsZFNldC4KKyAgICAgICAgICAgICAgaW50NjQgc2lnbl9leHRlbmRlZF92YWx1ZSA9IHN0YXRpY19jYXN0PGludDY0Pih2YWx1ZSk7CisgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+TXV0YWJsZVVua25vd25GaWVsZHMobWVzc2FnZSkKKyAgICAgICAgICAgICAgICAgIC0+QWRkVmFyaW50KAorICAgICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpLAorICAgICAgICAgICAgICAgICAgICAgIHNpZ25fZXh0ZW5kZWRfdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0U6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzoKKyAgICAgICAgLy8gQ2FuJ3QgaGF2ZSBwYWNrZWQgZmllbGRzIG9mIHRoZXNlIHR5cGVzOiB0aGVzZSBzaG91bGQgYmUgY2F1Z2h0IGJ5CisgICAgICAgIC8vIHRoZSBwcm90b2NvbCBjb21waWxlci4KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICBpbnB1dC0+UG9wTGltaXQobGltaXQpOworICB9IGVsc2UgeworICAgIC8vIE5vbi1wYWNrZWQgdmFsdWUgKHZhbHVlX2Zvcm1hdCA9PSBOT1JNQUxfRk9STUFUKQorICAgIHN3aXRjaCAoZmllbGQtPnR5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShUWVBFLCBDUFBUWVBFLCBDUFBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDUFBUWVBFIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgIENQUFRZUEUsIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVFlQRT4oaW5wdXQsICZ2YWx1ZSkpICAgICAgICAgXAorICAgICAgICAgIHJldHVybiBmYWxzZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkIyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgXAorICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+U2V0IyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgXAorICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfQorCisgICAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBpbnQzMiwgIEludDMyKQorICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQsICBJbnQ2NCkKKyAgICAgIEhBTkRMRV9UWVBFKFNJTlQzMiwgIGludDMyLCAgSW50MzIpCisgICAgICBIQU5ETEVfVFlQRShTSU5UNjQsICBpbnQ2NCwgIEludDY0KQorICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIsIFVJbnQzMikKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0LCBVSW50NjQpCisKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCB1aW50MzIsIFVJbnQzMikKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCB1aW50NjQsIFVJbnQ2NCkKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCAgaW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCAgaW50NjQsICBJbnQ2NCkKKworICAgICAgSEFORExFX1RZUEUoRkxPQVQgLCBmbG9hdCAsIEZsb2F0ICkKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUpCisKKyAgICAgIEhBTkRMRV9UWVBFKEJPT0wsIGJvb2wsIEJvb2wpCisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTTogeworICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAobWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5maWxlKCktPnN5bnRheCgpID09CisgICAgICAgICAgICBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5BZGRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5TZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICAgIGZpZWxkLT5lbnVtX3R5cGUoKS0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUpOworICAgICAgICAgIGlmIChlbnVtX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkFkZEVudW0obWVzc2FnZSwgZmllbGQsIGVudW1fdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5TZXRFbnVtKG1lc3NhZ2UsIGZpZWxkLCBlbnVtX3ZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVGhlIGVudW0gdmFsdWUgaXMgbm90IG9uZSBvZiB0aGUga25vd24gdmFsdWVzLiAgQWRkIGl0IHRvIHRoZQorICAgICAgICAgICAgLy8gVW5rbm93bkZpZWxkU2V0LgorICAgICAgICAgICAgaW50NjQgc2lnbl9leHRlbmRlZF92YWx1ZSA9IHN0YXRpY19jYXN0PGludDY0Pih2YWx1ZSk7CisgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPkFkZFZhcmludCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduX2V4dGVuZGVkX3ZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIEhhbmRsZSBzdHJpbmdzIHNlcGFyYXRlbHkgc28gdGhhdCB3ZSBjYW4gb3B0aW1pemUgdGhlIGN0eXBlPUNPUkQgY2FzZS4KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzogeworICAgICAgICBzdHJpbmcgdmFsdWU7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgICAgVmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQodmFsdWUuZGF0YSgpLCB2YWx1ZS5sZW5ndGgoKSwgUEFSU0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5uYW1lKCkuY19zdHIoKSk7CisgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5TZXRTdHJpbmcobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6IHsKKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5BZGRTdHJpbmcobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDogeworICAgICAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZTsKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkFkZE1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzdWJfbWVzc2FnZSA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRHcm91cChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LCBzdWJfbWVzc2FnZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRTogeworICAgICAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZTsKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkFkZE1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzdWJfbWVzc2FnZSA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlKGlucHV0LCBzdWJfbWVzc2FnZSkpIHJldHVybiBmYWxzZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZU1lc3NhZ2VTZXRJdGVtKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIG1lc3NhZ2VfcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBUaGlzIG1ldGhvZCBwYXJzZXMgYSBncm91cCB3aGljaCBzaG91bGQgY29udGFpbiB0d28gZmllbGRzOgorICAvLyAgIHJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOworICAvLyAgIHJlcXVpcmVkIGRhdGEgbWVzc2FnZSA9IDM7CisKKyAgdWludDMyIGxhc3RfdHlwZV9pZCA9IDA7CisKKyAgLy8gT25jZSB3ZSBzZWUgYSB0eXBlX2lkLCB3ZSdsbCBsb29rIHVwIHRoZSBGaWVsZERlc2NyaXB0b3IgZm9yIHRoZQorICAvLyBleHRlbnNpb24uCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBOVUxMOworCisgIC8vIElmIHdlIHNlZSBtZXNzYWdlIGRhdGEgYmVmb3JlIHRoZSB0eXBlX2lkLCB3ZSdsbCBhcHBlbmQgaXQgdG8gdGhpcyBzbworICAvLyB3ZSBjYW4gcGFyc2UgaXQgbGF0ZXIuCisgIHN0cmluZyBtZXNzYWdlX2RhdGE7CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICB1aW50MzIgdGFnID0gaW5wdXQtPlJlYWRUYWcoKTsKKyAgICBpZiAodGFnID09IDApIHJldHVybiBmYWxzZTsKKworICAgIHN3aXRjaCAodGFnKSB7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZzogeworICAgICAgICB1aW50MzIgdHlwZV9pZDsKKyAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZ0eXBlX2lkKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBsYXN0X3R5cGVfaWQgPSB0eXBlX2lkOworICAgICAgICBmaWVsZCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIodHlwZV9pZCk7CisKKyAgICAgICAgaWYgKCFtZXNzYWdlX2RhdGEuZW1wdHkoKSkgeworICAgICAgICAgIC8vIFdlIHNhdyBzb21lIG1lc3NhZ2UgZGF0YSBiZWZvcmUgdGhlIHR5cGVfaWQuICBIYXZlIHRvIHBhcnNlIGl0CisgICAgICAgICAgLy8gbm93LgorICAgICAgICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChtZXNzYWdlX2RhdGEuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2RhdGEuc2l6ZSgpKTsKKyAgICAgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBzdWJfaW5wdXQoJnJhd19pbnB1dCk7CisgICAgICAgICAgaWYgKCFQYXJzZUFuZE1lcmdlTWVzc2FnZVNldEZpZWxkKGxhc3RfdHlwZV9pZCwgZmllbGQsIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdWJfaW5wdXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIG1lc3NhZ2VfZGF0YS5jbGVhcigpOworICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZVRhZzogeworICAgICAgICBpZiAobGFzdF90eXBlX2lkID09IDApIHsKKyAgICAgICAgICAvLyBXZSBoYXZlbid0IHNlZW4gYSB0eXBlX2lkIHlldC4gIEFwcGVuZCB0aGlzIGRhdGEgdG8gbWVzc2FnZV9kYXRhLgorICAgICAgICAgIHN0cmluZyB0ZW1wOworICAgICAgICAgIHVpbnQzMiBsZW5ndGg7CisgICAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFN0cmluZygmdGVtcCwgbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmbWVzc2FnZV9kYXRhKTsKKyAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgICAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQzMihsZW5ndGgpOworICAgICAgICAgIGNvZGVkX291dHB1dC5Xcml0ZVN0cmluZyh0ZW1wKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBBbHJlYWR5IHNhdyB0eXBlX2lkLCBzbyB3ZSBjYW4gcGFyc2UgdGhpcyBkaXJlY3RseS4KKyAgICAgICAgICBpZiAoIVBhcnNlQW5kTWVyZ2VNZXNzYWdlU2V0RmllbGQobGFzdF90eXBlX2lkLCBmaWVsZCwgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZzogeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgICBpZiAoIVNraXBGaWVsZChpbnB1dCwgdGFnLCBOVUxMKSkgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgaW50IHNpemUsIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGludCBleHBlY3RlZF9lbmRwb2ludCA9IG91dHB1dC0+Qnl0ZUNvdW50KCkgKyBzaXplOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlLCAmZmllbGRzKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBTZXJpYWxpemVGaWVsZFdpdGhDYWNoZWRTaXplcyhmaWVsZHNbaV0sIG1lc3NhZ2UsIG91dHB1dCk7CisgIH0KKworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICBTZXJpYWxpemVVbmtub3duTWVzc2FnZVNldEl0ZW1zKAorICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFVua25vd25GaWVsZHMobWVzc2FnZSksIG91dHB1dCk7CisgIH0gZWxzZSB7CisgICAgU2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRVbmtub3duRmllbGRzKG1lc3NhZ2UpLCBvdXRwdXQpOworICB9CisKKyAgR09PR0xFX0NIRUNLX0VRKG91dHB1dC0+Qnl0ZUNvdW50KCksIGV4cGVjdGVkX2VuZHBvaW50KQorICAgIDw8ICI6IFByb3RvY29sIG1lc3NhZ2Ugc2VyaWFsaXplZCB0byBhIHNpemUgZGlmZmVyZW50IGZyb20gd2hhdCB3YXMgIgorICAgICAgICJvcmlnaW5hbGx5IGV4cGVjdGVkLiAgUGVyaGFwcyBpdCB3YXMgbW9kaWZpZWQgYnkgYW5vdGhlciB0aHJlYWQgIgorICAgICAgICJkdXJpbmcgc2VyaWFsaXphdGlvbj8iOworfQorCit2b2lkIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpICYmCisgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgIWZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgU2VyaWFsaXplTWVzc2FnZVNldEl0ZW1XaXRoQ2FjaGVkU2l6ZXMoZmllbGQsIG1lc3NhZ2UsIG91dHB1dCk7CisgICAgcmV0dXJuOworICB9CisKKyAgaW50IGNvdW50ID0gMDsKKworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBjb3VudCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIGZpZWxkKTsKKyAgfSBlbHNlIGlmIChtZXNzYWdlX3JlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgIGNvdW50ID0gMTsKKyAgfQorCisgIGNvbnN0IGJvb2wgaXNfcGFja2VkID0gZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKTsKKyAgaWYgKGlzX3BhY2tlZCAmJiBjb3VudCA+IDApIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoZmllbGQtPm51bWJlcigpLAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgICBjb25zdCBpbnQgZGF0YV9zaXplID0gRmllbGREYXRhT25seUJ5dGVTaXplKGZpZWxkLCBtZXNzYWdlKTsKKyAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoZGF0YV9zaXplKTsKKyAgfQorCisgIGZvciAoaW50IGogPSAwOyBqIDwgY291bnQ7IGorKykgeworICAgIHN3aXRjaCAoZmllbGQtPnR5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoVFlQRSwgQ1BQVFlQRSwgVFlQRV9NRVRIT0QsIENQUFRZUEVfTUVUSE9EKSAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFXyMjVFlQRTogeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNvbnN0IENQUFRZUEUgdmFsdWUgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZCMjQ1BQVFlQRV9NRVRIT0QoIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSwgZmllbGQsIGopIDogICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldCMjQ1BQVFlQRV9NRVRIT0QoICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKGlzX3BhY2tlZCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlIyNUWVBFX01FVEhPRCMjTm9UYWcodmFsdWUsIG91dHB1dCk7ICAgICAgICAgICAgXAorICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI1RZUEVfTUVUSE9EKGZpZWxkLT5udW1iZXIoKSwgdmFsdWUsIG91dHB1dCk7ICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIH0KKworICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKCBJTlQzMiwgIGludDMyLCAgSW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRSggSU5UNjQsICBpbnQ2NCwgIEludDY0LCAgSW50NjQpCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoU0lOVDMyLCAgaW50MzIsIFNJbnQzMiwgIEludDMyKQorICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKFNJTlQ2NCwgIGludDY0LCBTSW50NjQsICBJbnQ2NCkKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRShVSU5UMzIsIHVpbnQzMiwgVUludDMyLCBVSW50MzIpCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoVUlOVDY0LCB1aW50NjQsIFVJbnQ2NCwgVUludDY0KQorCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoIEZJWEVEMzIsIHVpbnQzMiwgIEZpeGVkMzIsIFVJbnQzMikKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRSggRklYRUQ2NCwgdWludDY0LCAgRml4ZWQ2NCwgVUludDY0KQorICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKFNGSVhFRDMyLCAgaW50MzIsIFNGaXhlZDMyLCAgSW50MzIpCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoU0ZJWEVENjQsICBpbnQ2NCwgU0ZpeGVkNjQsICBJbnQ2NCkKKworICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEZMT0FUICwgZmxvYXQgLCBGbG9hdCAsIEZsb2F0ICkKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRShET1VCTEUsIGRvdWJsZSwgRG91YmxlLCBEb3VibGUpCisKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRShCT09MLCBib29sLCBCb29sLCBCb29sKQorI3VuZGVmIEhBTkRMRV9QUklNSVRJVkVfVFlQRQorCisjZGVmaW5lIEhBTkRMRV9UWVBFKFRZUEUsIFRZUEVfTUVUSE9ELCBDUFBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFXyMjVFlQRTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI1RZUEVfTUVUSE9EKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgZmllbGQtPmlzX3JlcGVhdGVkKCkgPyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWQjI0NQUFRZUEVfTUVUSE9EKCAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBmaWVsZCwgaikgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldCMjQ1BQVFlQRV9NRVRIT0QobWVzc2FnZSwgZmllbGQpLCAgICAgXAorICAgICAgICAgICAgICBvdXRwdXQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOworCisgICAgICBIQU5ETEVfVFlQRShHUk9VUCAgLCBHcm91cCAgLCBNZXNzYWdlKQorICAgICAgSEFORExFX1RZUEUoTUVTU0FHRSwgTWVzc2FnZSwgTWVzc2FnZSkKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOiB7CisgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZmllbGQtPmlzX3JlcGVhdGVkKCkgPworICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIGZpZWxkLCBqKSA6CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgICAgaWYgKGlzX3BhY2tlZCkgeworICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ob1RhZyh2YWx1ZS0+bnVtYmVyKCksIG91dHB1dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlRW51bShmaWVsZC0+bnVtYmVyKCksIHZhbHVlLT5udW1iZXIoKSwgb3V0cHV0KTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gSGFuZGxlIHN0cmluZ3Mgc2VwYXJhdGVseSBzbyB0aGF0IHdlIGNhbiBnZXQgc3RyaW5nIHJlZmVyZW5jZXMKKyAgICAgIC8vIGluc3RlYWQgb2YgY29weWluZy4KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzogeworICAgICAgICBzdHJpbmcgc2NyYXRjaDsKKyAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSA9IGZpZWxkLT5pc19yZXBlYXRlZCgpID8KKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgICAgICAgICAgbWVzc2FnZSwgZmllbGQsIGosICZzY3JhdGNoKSA6CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgZmllbGQsICZzY3JhdGNoKTsKKyAgICAgICAgVmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQodmFsdWUuZGF0YSgpLCB2YWx1ZS5sZW5ndGgoKSwgU0VSSUFMSVpFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+bmFtZSgpLmNfc3RyKCkpOworICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmcoZmllbGQtPm51bWJlcigpLCB2YWx1ZSwgb3V0cHV0KTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOiB7CisgICAgICAgIHN0cmluZyBzY3JhdGNoOworICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlID0gZmllbGQtPmlzX3JlcGVhdGVkKCkgPworICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICBtZXNzYWdlLCBmaWVsZCwgaiwgJnNjcmF0Y2gpIDoKKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBmaWVsZCwgJnNjcmF0Y2gpOworICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlcyhmaWVsZC0+bnVtYmVyKCksIHZhbHVlLCBvdXRwdXQpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKwordm9pZCBXaXJlRm9ybWF0OjpTZXJpYWxpemVNZXNzYWdlU2V0SXRlbVdpdGhDYWNoZWRTaXplcygKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisKKyAgLy8gU3RhcnQgZ3JvdXAuCisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtU3RhcnRUYWcpOworCisgIC8vIFdyaXRlIHR5cGUgSUQuCisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRUeXBlSWRUYWcpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoZmllbGQtPm51bWJlcigpKTsKKworICAvLyBXcml0ZSBtZXNzYWdlLgorICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZVRhZyk7CisKKyAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgZmllbGQpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoc3ViX21lc3NhZ2UuR2V0Q2FjaGVkU2l6ZSgpKTsKKyAgc3ViX21lc3NhZ2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7CisKKyAgLy8gRW5kIGdyb3VwLgorICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZyk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworaW50IFdpcmVGb3JtYXQ6OkJ5dGVTaXplKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBpbnQgb3VyX3NpemUgPSAwOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlLCAmZmllbGRzKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBvdXJfc2l6ZSArPSBGaWVsZEJ5dGVTaXplKGZpZWxkc1tpXSwgbWVzc2FnZSk7CisgIH0KKworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICBvdXJfc2l6ZSArPSBDb21wdXRlVW5rbm93bk1lc3NhZ2VTZXRJdGVtc1NpemUoCisgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFVua25vd25GaWVsZHMobWVzc2FnZSkpOworICB9IGVsc2UgeworICAgIG91cl9zaXplICs9IENvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKSk7CisgIH0KKworICByZXR1cm4gb3VyX3NpemU7Cit9CisKK2ludCBXaXJlRm9ybWF0OjpGaWVsZEJ5dGVTaXplKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpICYmCisgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgIWZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgcmV0dXJuIE1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoZmllbGQsIG1lc3NhZ2UpOworICB9CisKKyAgaW50IGNvdW50ID0gMDsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgY291bnQgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZCk7CisgIH0gZWxzZSBpZiAobWVzc2FnZV9yZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZCkpIHsKKyAgICBjb3VudCA9IDE7CisgIH0KKworICBjb25zdCBpbnQgZGF0YV9zaXplID0gRmllbGREYXRhT25seUJ5dGVTaXplKGZpZWxkLCBtZXNzYWdlKTsKKyAgaW50IG91cl9zaXplID0gZGF0YV9zaXplOworICBpZiAoZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIGlmIChkYXRhX3NpemUgPiAwKSB7CisgICAgICAvLyBQYWNrZWQgZmllbGRzIGdldCBzZXJpYWxpemVkIGxpa2UgYSBzdHJpbmcsIG5vdCB0aGVpciBuYXRpdmUgdHlwZS4KKyAgICAgIC8vIFRlY2huaWNhbGx5IHRoaXMgZG9lc24ndCByZWFsbHkgbWF0dGVyOyB0aGUgc2l6ZSBvbmx5IGNoYW5nZXMgaWYgaXQncworICAgICAgLy8gYSBHUk9VUAorICAgICAgb3VyX3NpemUgKz0gVGFnU2l6ZShmaWVsZC0+bnVtYmVyKCksIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpOworICAgICAgb3VyX3NpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoZGF0YV9zaXplKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgb3VyX3NpemUgKz0gY291bnQgKiBUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSk7CisgIH0KKyAgcmV0dXJuIG91cl9zaXplOworfQorCitpbnQgV2lyZUZvcm1hdDo6RmllbGREYXRhT25seUJ5dGVTaXplKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBpbnQgY291bnQgPSAwOworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBjb3VudCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIGZpZWxkKTsKKyAgfSBlbHNlIGlmIChtZXNzYWdlX3JlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgIGNvdW50ID0gMTsKKyAgfQorCisgIGludCBkYXRhX3NpemUgPSAwOworICBzd2l0Y2ggKGZpZWxkLT50eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVFlQRSwgVFlQRV9NRVRIT0QsIENQUFRZUEVfTUVUSE9EKSAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV8jI1RZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBkYXRhX3NpemUgKz0gV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVUSE9EIyNTaXplKCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWQjI0NQUFRZUEVfTUVUSE9EKCAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgbWVzc2FnZSwgZmllbGQsIGopKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZGF0YV9zaXplICs9IFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FVEhPRCMjU2l6ZSggICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldCMjQ1BQVFlQRV9NRVRIT0QobWVzc2FnZSwgZmllbGQpKTsgICAgICAgIFwKKyAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGJyZWFrOworCisjZGVmaW5lIEhBTkRMRV9GSVhFRF9UWVBFKFRZUEUsIFRZUEVfTUVUSE9EKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBkYXRhX3NpemUgKz0gY291bnQgKiBXaXJlRm9ybWF0TGl0ZTo6ayMjVFlQRV9NRVRIT0QjI1NpemU7ICAgICAgICAgICBcCisgICAgICBicmVhazsKKworICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIEludDMyLCAgSW50MzIpCisgICAgSEFORExFX1RZUEUoIElOVDY0LCAgSW50NjQsICBJbnQ2NCkKKyAgICBIQU5ETEVfVFlQRShTSU5UMzIsIFNJbnQzMiwgIEludDMyKQorICAgIEhBTkRMRV9UWVBFKFNJTlQ2NCwgU0ludDY0LCAgSW50NjQpCisgICAgSEFORExFX1RZUEUoVUlOVDMyLCBVSW50MzIsIFVJbnQzMikKKyAgICBIQU5ETEVfVFlQRShVSU5UNjQsIFVJbnQ2NCwgVUludDY0KQorCisgICAgSEFORExFX0ZJWEVEX1RZUEUoIEZJWEVEMzIsICBGaXhlZDMyKQorICAgIEhBTkRMRV9GSVhFRF9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCkKKyAgICBIQU5ETEVfRklYRURfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIpCisgICAgSEFORExFX0ZJWEVEX1RZUEUoU0ZJWEVENjQsIFNGaXhlZDY0KQorCisgICAgSEFORExFX0ZJWEVEX1RZUEUoRkxPQVQgLCBGbG9hdCApCisgICAgSEFORExFX0ZJWEVEX1RZUEUoRE9VQkxFLCBEb3VibGUpCisKKyAgICBIQU5ETEVfRklYRURfVFlQRShCT09MLCBCb29sKQorCisgICAgSEFORExFX1RZUEUoR1JPVVAgICwgR3JvdXAgICwgTWVzc2FnZSkKKyAgICBIQU5ETEVfVFlQRShNRVNTQUdFLCBNZXNzYWdlLCBNZXNzYWdlKQorI3VuZGVmIEhBTkRMRV9UWVBFCisjdW5kZWYgSEFORExFX0ZJWEVEX1RZUEUKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06IHsKKyAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKKyAgICAgICAgICBkYXRhX3NpemUgKz0gV2lyZUZvcm1hdExpdGU6OkVudW1TaXplKAorICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgZmllbGQsIGopLT5udW1iZXIoKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGRhdGFfc2l6ZSArPSBXaXJlRm9ybWF0TGl0ZTo6RW51bVNpemUoCisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIGZpZWxkKS0+bnVtYmVyKCkpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorCisgICAgLy8gSGFuZGxlIHN0cmluZ3Mgc2VwYXJhdGVseSBzbyB0aGF0IHdlIGNhbiBnZXQgc3RyaW5nIHJlZmVyZW5jZXMKKyAgICAvLyBpbnN0ZWFkIG9mIGNvcHlpbmcuCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOiB7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKKyAgICAgICAgc3RyaW5nIHNjcmF0Y2g7CisgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZSgKKyAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBqLCAmc2NyYXRjaCkgOgorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIGZpZWxkLCAmc2NyYXRjaCk7CisgICAgICAgIGRhdGFfc2l6ZSArPSBXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSh2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGRhdGFfc2l6ZTsKK30KKworaW50IFdpcmVGb3JtYXQ6Ok1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIG1lc3NhZ2VfcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIGludCBvdXJfc2l6ZSA9IFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1UYWdzU2l6ZTsKKworICAvLyB0eXBlX2lkCisgIG91cl9zaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKGZpZWxkLT5udW1iZXIoKSk7CisKKyAgLy8gbWVzc2FnZQorICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBmaWVsZCk7CisgIGludCBtZXNzYWdlX3NpemUgPSBzdWJfbWVzc2FnZS5CeXRlU2l6ZSgpOworCisgIG91cl9zaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKG1lc3NhZ2Vfc2l6ZSk7CisgIG91cl9zaXplICs9IG1lc3NhZ2Vfc2l6ZTsKKworICByZXR1cm4gb3VyX3NpemU7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ0ZhbGxiYWNrKGNvbnN0IGNoYXIqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZXJhdGlvbiBvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGZpZWxkX25hbWUpIHsKKyAgaWYgKCFJc1N0cnVjdHVyYWxseVZhbGlkVVRGOChkYXRhLCBzaXplKSkgeworICAgIGNvbnN0IGNoYXIqIG9wZXJhdGlvbl9zdHIgPSBOVUxMOworICAgIHN3aXRjaCAob3ApIHsKKyAgICAgIGNhc2UgUEFSU0U6CisgICAgICAgIG9wZXJhdGlvbl9zdHIgPSAicGFyc2luZyI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBTRVJJQUxJWkU6CisgICAgICAgIG9wZXJhdGlvbl9zdHIgPSAic2VyaWFsaXppbmciOworICAgICAgICBicmVhazsKKyAgICAgIC8vIG5vIGRlZmF1bHQgY2FzZTogaGF2ZSB0aGUgY29tcGlsZXIgd2FybiBpZiBhIGNhc2UgaXMgbm90IGNvdmVyZWQuCisgICAgfQorICAgIHN0cmluZyBxdW90ZWRfZmllbGRfbmFtZSA9ICIiOworICAgIGlmIChmaWVsZF9uYW1lICE9IE5VTEwpIHsKKyAgICAgIHF1b3RlZF9maWVsZF9uYW1lID0gU3RyaW5nUHJpbnRmKCIgJyVzJyIsIGZpZWxkX25hbWUpOworICAgIH0KKyAgICAvLyBubyBzcGFjZSBiZWxvdyB0byBhdm9pZCBkb3VibGUgc3BhY2Ugd2hlbiB0aGUgZmllbGQgbmFtZSBpcyBtaXNzaW5nLgorICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJTdHJpbmcgZmllbGQiIDw8IHF1b3RlZF9maWVsZF9uYW1lIDw8ICIgY29udGFpbnMgaW52YWxpZCAiCisgICAgICAgICAgICAgICA8PCAiVVRGLTggZGF0YSB3aGVuICIgPDwgb3BlcmF0aW9uX3N0ciA8PCAiIGEgcHJvdG9jb2wgIgorICAgICAgICAgICAgICAgPDwgImJ1ZmZlci4gVXNlIHRoZSAnYnl0ZXMnIHR5cGUgaWYgeW91IGludGVuZCB0byBzZW5kIHJhdyAiCisgICAgICAgICAgICAgICA8PCAiYnl0ZXMuICI7CisgIH0KK30KKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkZTQ5MWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmgKQEAgLTAsMCArMSwzNDQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgICAgICAgIGF0ZW5hc2lvQGdvb2dsZS5jb20gKENocmlzIEF0ZW5hc2lvKSAoWmlnWmFnIHRyYW5zZm9ybSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgaGVhZGVyIGlzIGxvZ2ljYWxseSBpbnRlcm5hbCwgYnV0IGlzIG1hZGUgcHVibGljIGJlY2F1c2UgaXQgaXMgdXNlZAorLy8gZnJvbSBwcm90b2NvbC1jb21waWxlci1nZW5lcmF0ZWQgY29kZSwgd2hpY2ggbWF5IHJlc2lkZSBpbiBvdGhlciBjb21wb25lbnRzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oPgorCisvLyBEbyBVVEYtOCB2YWxpZGF0aW9uIG9uIHN0cmluZyB0eXBlIGluIERlYnVnIGJ1aWxkIG9ubHkKKyNpZm5kZWYgTkRFQlVHCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorI2VuZGlmCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBDb2RlZElucHV0U3RyZWFtOyAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCisgICAgY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07ICAgICAvLyBjb2RlZF9zdHJlYW0uaAorICB9CisgIGNsYXNzIFVua25vd25GaWVsZFNldDsgICAgICAgICAvLyB1bmtub3duX2ZpZWxkX3NldC5oCit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBUaGlzIGNsYXNzIGlzIGZvciBpbnRlcm5hbCB1c2UgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBsaWJyYXJ5IGFuZCBieQorLy8gcHJvdG9jb2wtY29tcGxpZXItZ2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3Nlcy4gIEl0IG11c3Qgbm90IGJlIGNhbGxlZAorLy8gZGlyZWN0bHkgYnkgY2xpZW50cy4KKy8vCisvLyBUaGlzIGNsYXNzIGNvbnRhaW5zIGNvZGUgZm9yIGltcGxlbWVudGluZyB0aGUgYmluYXJ5IHByb3RvY29sIGJ1ZmZlcgorLy8gd2lyZSBmb3JtYXQgdmlhIHJlZmxlY3Rpb24uICBUaGUgV2lyZUZvcm1hdExpdGUgY2xhc3MgaW1wbGVtZW50cyB0aGUKKy8vIG5vbi1yZWZsZWN0aW9uIGJhc2VkIHJvdXRpbmVzLgorLy8KKy8vIFRoaXMgY2xhc3MgaXMgcmVhbGx5IGEgbmFtZXNwYWNlIHRoYXQgY29udGFpbnMgb25seSBzdGF0aWMgbWV0aG9kcworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFdpcmVGb3JtYXQgeworIHB1YmxpYzoKKworICAvLyBHaXZlbiBhIGZpZWxkIHJldHVybiBpdHMgV2lyZVR5cGUKKyAgc3RhdGljIGlubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZVR5cGVGb3JGaWVsZCgKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIC8vIEdpdmVuIGEgRmllbGREZXNjcmlwdG9yOjpUeXBlIHJldHVybiBpdHMgV2lyZVR5cGUKKyAgc3RhdGljIGlubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZVR5cGVGb3JGaWVsZFR5cGUoCisgICAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSk7CisKKyAgLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIGEgdGFnLiAgRm9yIGdyb3VwcywgdGhpcyBpbmNsdWRlcyBib3RoIHRoZSBzdGFydAorICAvLyBhbmQgZW5kIHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgaW50IFRhZ1NpemUoaW50IGZpZWxkX251bWJlciwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpOworCisgIC8vIFRoZXNlIHByb2NlZHVyZXMgY2FuIGJlIHVzZWQgdG8gaW1wbGVtZW50IHRoZSBtZXRob2RzIG9mIE1lc3NhZ2Ugd2hpY2gKKyAgLy8gaGFuZGxlIHBhcnNpbmcgYW5kIHNlcmlhbGl6YXRpb24gb2YgdGhlIHByb3RvY29sIGJ1ZmZlciB3aXJlIGZvcm1hdAorICAvLyB1c2luZyBvbmx5IHRoZSBSZWZsZWN0aW9uIGludGVyZmFjZS4gIFdoZW4geW91IGFzayB0aGUgcHJvdG9jb2wKKyAgLy8gY29tcGlsZXIgdG8gb3B0aW1pemUgZm9yIGNvZGUgc2l6ZSByYXRoZXIgdGhhbiBzcGVlZCwgaXQgd2lsbCBpbXBsZW1lbnQKKyAgLy8gdGhvc2UgbWV0aG9kcyBpbiB0ZXJtcyBvZiB0aGVzZSBwcm9jZWR1cmVzLiAgT2YgY291cnNlLCB0aGVzZSBhcmUgbXVjaAorICAvLyBzbG93ZXIgdGhhbiB0aGUgc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zIHdoaWNoIHRoZSBwcm90b2NvbCBjb21waWxlcgorICAvLyBnZW5lcmF0ZXMgd2hlbiB0b2xkIHRvIG9wdGltaXplIGZvciBzcGVlZC4KKworICAvLyBSZWFkIGEgbWVzc2FnZSBpbiBwcm90b2NvbCBidWZmZXIgd2lyZSBmb3JtYXQuCisgIC8vCisgIC8vIFRoaXMgcHJvY2VkdXJlIHJlYWRzIGVpdGhlciB0byB0aGUgZW5kIG9mIHRoZSBpbnB1dCBzdHJlYW0gb3IgdGhyb3VnaAorICAvLyBhIFdJUkVUWVBFX0VORF9HUk9VUCB0YWcgZW5kaW5nIHRoZSBtZXNzYWdlLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCisgIC8vIEl0IHJldHVybnMgZmFsc2UgaWYgdGhlIGlucHV0IGlzIGludmFsaWQuCisgIC8vCisgIC8vIFJlcXVpcmVkIGZpZWxkcyBhcmUgTk9UIGNoZWNrZWQgYnkgdGhpcyBtZXRob2QuICBZb3UgbXVzdCBjYWxsCisgIC8vIElzSW5pdGlhbGl6ZWQoKSBvbiB0aGUgcmVzdWx0aW5nIG1lc3NhZ2UgeW91cnNlbGYuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VQYXJ0aWFsKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogbWVzc2FnZSk7CisKKyAgLy8gU2VyaWFsaXplIGEgbWVzc2FnZSBpbiBwcm90b2NvbCBidWZmZXIgd2lyZSBmb3JtYXQuCisgIC8vCisgIC8vIEFueSBlbWJlZGRlZCBtZXNzYWdlcyB3aXRoaW4gdGhlIG1lc3NhZ2UgbXVzdCBoYXZlIHRoZWlyIGNvcnJlY3Qgc2l6ZXMKKyAgLy8gY2FjaGVkLiAgSG93ZXZlciwgdGhlIHRvcC1sZXZlbCBtZXNzYWdlIG5lZWQgbm90OyBpdHMgc2l6ZSBpcyBwYXNzZWQgYXMKKyAgLy8gYSBwYXJhbWV0ZXIgdG8gdGhpcyBwcm9jZWR1cmUuCisgIC8vCisgIC8vIFRoZXNlIHJldHVybiBmYWxzZSBpZmYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIHJldHVybnMgYSB3cml0ZSBlcnJvci4KKyAgc3RhdGljIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGludCBzaXplLCBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gSW1wbGVtZW50cyBNZXNzYWdlOjpCeXRlU2l6ZSgpIHZpYSByZWZsZWN0aW9uLiAgV0FSTklORzogIFRoZSByZXN1bHQKKyAgLy8gb2YgdGhpcyBtZXRob2QgaXMgKm5vdCogY2FjaGVkIGFueXdoZXJlLiAgSG93ZXZlciwgYWxsIGVtYmVkZGVkIG1lc3NhZ2VzCisgIC8vIHdpbGwgaGF2ZSB0aGVpciBCeXRlU2l6ZSgpIG1ldGhvZHMgY2FsbGVkLCBzbyB0aGVpciBzaXplcyB3aWxsIGJlIGNhY2hlZC4KKyAgLy8gVGhlcmVmb3JlLCBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzIHN1ZmZpY2llbnQgdG8gYWxsb3cgeW91IHRvIGNhbGwKKyAgLy8gV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCkgb24gdGhlIHNhbWUgb2JqZWN0LgorICBzdGF0aWMgaW50IEJ5dGVTaXplKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEhlbHBlcnMgZm9yIGRlYWxpbmcgd2l0aCB1bmtub3duIGZpZWxkcworCisgIC8vIFNraXBzIGEgZmllbGQgdmFsdWUgb2YgdGhlIGdpdmVuIFdpcmVUeXBlLiAgVGhlIGlucHV0IHNob3VsZCBzdGFydAorICAvLyBwb3NpdGlvbmVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSB0YWcuICBJZiB1bmtub3duX2ZpZWxkcyBpcyBub24tTlVMTCwKKyAgLy8gdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWVsZCB3aWxsIGJlIGFkZGVkIHRvIGl0LgorICBzdGF0aWMgYm9vbCBTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisKKyAgLy8gUmVhZHMgYW5kIGlnbm9yZXMgYSBtZXNzYWdlIGZyb20gdGhlIGlucHV0LiAgSWYgdW5rbm93bl9maWVsZHMgaXMgbm9uLU5VTEwsCisgIC8vIHRoZSBjb250ZW50cyB3aWxsIGJlIGFkZGVkIHRvIGl0LgorICBzdGF0aWMgYm9vbCBTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpOworCisgIC8vIFJlYWQgYSBwYWNrZWQgZW51bSBmaWVsZC4gSWYgdGhlIGlzX3ZhbGlkIGZ1bmN0aW9uIGlzIG5vdCBOVUxMLCB2YWx1ZXMgZm9yCisgIC8vIHdoaWNoIGlzX3ZhbGlkKHZhbHVlKSByZXR1cm5zIGZhbHNlIGFyZSBhcHBlbmRlZCB0byB1bmtub3duX2ZpZWxkc19zdHJlYW0uCisgIHN0YXRpYyBib29sIFJlYWRQYWNrZWRFbnVtUHJlc2VydmVVbmtub3ducyhpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAoKmlzX3ZhbGlkKShpbnQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50PiogdmFsdWVzKTsKKworICAvLyBXcml0ZSB0aGUgY29udGVudHMgb2YgYW4gVW5rbm93bkZpZWxkU2V0IHRvIHRoZSBvdXRwdXQuCisgIHN0YXRpYyB2b2lkIFNlcmlhbGl6ZVVua25vd25GaWVsZHMoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIC8vIFNhbWUgYXMgYWJvdmUsIGV4Y2VwdCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSBwcm92aWRlZCBidWZmZXIuCisgIC8vIFJlcXVpcmVzIHRoYXQgdGhlIGJ1ZmZlciBoYXZlIHN1ZmZpY2llbnQgY2FwYWNpdHkgZm9yCisgIC8vIENvbXB1dGVVbmtub3duRmllbGRzU2l6ZSh1bmtub3duX2ZpZWxkcykuCisgIC8vCisgIC8vIFJldHVybnMgYSBwb2ludGVyIHBhc3QgdGhlIGxhc3Qgd3JpdHRlbiBieXRlLgorICBzdGF0aWMgdWludDgqIFNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIFNhbWUgdGhpbmcgZXhjZXB0IGZvciBtZXNzYWdlcyB0aGF0IGhhdmUgdGhlIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0CisgIC8vIG9wdGlvbi4KKyAgc3RhdGljIHZvaWQgU2VyaWFsaXplVW5rbm93bk1lc3NhZ2VTZXRJdGVtcygKKyAgICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIC8vIFNhbWUgYXMgYWJvdmUsIGV4Y2VwdCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSBwcm92aWRlZCBidWZmZXIuCisgIC8vIFJlcXVpcmVzIHRoYXQgdGhlIGJ1ZmZlciBoYXZlIHN1ZmZpY2llbnQgY2FwYWNpdHkgZm9yCisgIC8vIENvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSh1bmtub3duX2ZpZWxkcykuCisgIC8vCisgIC8vIFJldHVybnMgYSBwb2ludGVyIHBhc3QgdGhlIGxhc3Qgd3JpdHRlbiBieXRlLgorICBzdGF0aWMgdWludDgqIFNlcmlhbGl6ZVVua25vd25NZXNzYWdlU2V0SXRlbXNUb0FycmF5KAorICAgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIENvbXB1dGUgdGhlIHNpemUgb2YgdGhlIFVua25vd25GaWVsZFNldCBvbiB0aGUgd2lyZS4KKyAgc3RhdGljIGludCBDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcyk7CisKKyAgLy8gU2FtZSB0aGluZyBleGNlcHQgZm9yIG1lc3NhZ2VzIHRoYXQgaGF2ZSB0aGUgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQKKyAgLy8gb3B0aW9uLgorICBzdGF0aWMgaW50IENvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSgKKyAgICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMpOworCisKKyAgLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgZW5jb2RpbmcgYW5kIGRlY29kaW5nIHRhZ3MuICAoSW5saW5lZCBiZWxvdyBhbmQgaW4KKyAgLy8gX2lubC5oKQorICAvLworICAvLyBUaGlzIGlzIGRpZmZlcmVudCBmcm9tIE1ha2VUYWcoZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpKSBpbiB0aGUgY2FzZQorICAvLyBvZiBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzLgorICBzdGF0aWMgdWludDMyIE1ha2VUYWcoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgLy8gUGFyc2UgYSBzaW5nbGUgZmllbGQuICBUaGUgaW5wdXQgc2hvdWxkIHN0YXJ0IG91dCBwb3NpdGlvbmVkIGltbWVkaWF0ZWx5CisgIC8vIGFmdGVyIHRoZSB0YWcuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VGaWVsZCgKKyAgICAgIHVpbnQzMiB0YWcsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgLy8gTWF5IGJlIE5VTEwgZm9yIHVua25vd24KKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworCisgIC8vIFNlcmlhbGl6ZSBhIHNpbmdsZSBmaWVsZC4KKyAgc3RhdGljIHZvaWQgU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgLy8gQ2Fubm90IGJlIE5VTEwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gQ29tcHV0ZSBzaXplIG9mIGEgc2luZ2xlIGZpZWxkLiAgSWYgdGhlIGZpZWxkIGlzIGEgbWVzc2FnZSB0eXBlLCB0aGlzCisgIC8vIHdpbGwgY2FsbCBCeXRlU2l6ZSgpIGZvciB0aGUgZW1iZWRkZWQgbWVzc2FnZSwgaW5zdXJpbmcgdGhhdCBpdCBjYWNoZXMKKyAgLy8gaXRzIHNpemUuCisgIHN0YXRpYyBpbnQgRmllbGRCeXRlU2l6ZSgKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsICAgICAgICAvLyBDYW5ub3QgYmUgTlVMTAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gUGFyc2Uvc2VyaWFsaXplIGEgTWVzc2FnZVNldDo6SXRlbSBncm91cC4gIFVzZWQgd2l0aCBtZXNzYWdlcyB0aGF0IHVzZQorICAvLyBvcGlvbiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IHRydWUuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VNZXNzYWdlU2V0SXRlbSgKKyAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXJpYWxpemVNZXNzYWdlU2V0SXRlbVdpdGhDYWNoZWRTaXplcygKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOworICBzdGF0aWMgaW50IE1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gQ29tcHV0ZXMgdGhlIGJ5dGUgc2l6ZSBvZiBhIGZpZWxkLCBleGNsdWRpbmcgdGFncy4gRm9yIHBhY2tlZCBmaWVsZHMsIGl0CisgIC8vIG9ubHkgaW5jbHVkZXMgdGhlIHNpemUgb2YgdGhlIHJhdyBkYXRhLCBhbmQgbm90IHRoZSBzaXplIG9mIHRoZSB0b3RhbAorICAvLyBsZW5ndGgsIGJ1dCBmb3Igb3RoZXIgbGVuZ3RoLWRlbGltaXRlZCB0eXBlcywgdGhlIHNpemUgb2YgdGhlIGxlbmd0aCBpcworICAvLyBpbmNsdWRlZC4KKyAgc3RhdGljIGludCBGaWVsZERhdGFPbmx5Qnl0ZVNpemUoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgLy8gQ2Fubm90IGJlIE5VTEwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgIGVudW0gT3BlcmF0aW9uIHsKKyAgICBQQVJTRSwKKyAgICBTRVJJQUxJWkUsCisgIH07CisKKyAgLy8gVmVyaWZpZXMgdGhhdCBhIHN0cmluZyBmaWVsZCBpcyB2YWxpZCBVVEY4LCBsb2dnaW5nIGFuIGVycm9yIGlmIG5vdC4KKyAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIG5vdCBiZSBjYWxsZWQgYnkgbmV3bHkgZ2VuZXJhdGVkIHByb3RvYnVmIGNvZGUKKyAgLy8gYnV0IHJlbWFpbnMgcHJlc2VudCB0byBzdXBwb3J0IGV4aXN0aW5nIGNvZGUuCisgIHN0YXRpYyB2b2lkIFZlcmlmeVVURjhTdHJpbmcoY29uc3QgY2hhciogZGF0YSwgaW50IHNpemUsIE9wZXJhdGlvbiBvcCk7CisgIC8vIFRoZSBOYW1lZEZpZWxkIHZhcmlhbnQgdGFrZXMgYSBmaWVsZCBuYW1lIGluIG9yZGVyIHRvIHByb2R1Y2UgYW4KKyAgLy8gaW5mb3JtYXRpdmUgZXJyb3IgbWVzc2FnZSBpZiB2ZXJpZmljYXRpb24gZmFpbHMuCisgIHN0YXRpYyB2b2lkIFZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKGNvbnN0IGNoYXIqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVyYXRpb24gb3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGZpZWxkX25hbWUpOworCisgcHJpdmF0ZToKKyAgLy8gVmVyaWZpZXMgdGhhdCBhIHN0cmluZyBmaWVsZCBpcyB2YWxpZCBVVEY4LCBsb2dnaW5nIGFuIGVycm9yIGlmIG5vdC4KKyAgc3RhdGljIHZvaWQgVmVyaWZ5VVRGOFN0cmluZ0ZhbGxiYWNrKAorICAgICAgY29uc3QgY2hhciogZGF0YSwKKyAgICAgIGludCBzaXplLAorICAgICAgT3BlcmF0aW9uIG9wLAorICAgICAgY29uc3QgY2hhciogZmllbGRfbmFtZSk7CisKKyAgLy8gU2tpcCBhIE1lc3NhZ2VTZXQgZmllbGQuCisgIHN0YXRpYyBib29sIFNraXBNZXNzYWdlU2V0RmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisKKyAgLy8gUGFyc2UgYSBNZXNzYWdlU2V0IGZpZWxkLgorICBzdGF0aWMgYm9vbCBQYXJzZUFuZE1lcmdlTWVzc2FnZVNldEZpZWxkKHVpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisKKworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhXaXJlRm9ybWF0KTsKK307CisKKy8vIFN1YmNsYXNzIG9mIEZpZWxkU2tpcHBlciB3aGljaCBzYXZlcyBza2lwcGVkIGZpZWxkcyB0byBhbiBVbmtub3duRmllbGRTZXQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyIDogcHVibGljIEZpZWxkU2tpcHBlciB7CisgcHVibGljOgorICBVbmtub3duRmllbGRTZXRGaWVsZFNraXBwZXIoVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykKKyAgICAgIDogdW5rbm93bl9maWVsZHNfKHVua25vd25fZmllbGRzKSB7fQorICB2aXJ0dWFsIH5Vbmtub3duRmllbGRTZXRGaWVsZFNraXBwZXIoKSB7fQorCisgIC8vIGltcGxlbWVudHMgRmllbGRTa2lwcGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZpcnR1YWwgYm9vbCBTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnKTsKKyAgdmlydHVhbCBib29sIFNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZpcnR1YWwgdm9pZCBTa2lwVW5rbm93bkVudW0oaW50IGZpZWxkX251bWJlciwgaW50IHZhbHVlKTsKKworIHByb3RlY3RlZDoKKyAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkc187Cit9OworCisvLyBpbmxpbmUgbWV0aG9kcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2lubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZCgKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGlmIChmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOworICB9IGVsc2UgeworICAgIHJldHVybiBXaXJlVHlwZUZvckZpZWxkVHlwZShmaWVsZC0+dHlwZSgpKTsKKyAgfQorfQorCitpbmxpbmUgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIFdpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGRUeXBlKAorICAgIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgIC8vIFNvbWUgY29tcGlsZXJzIGRvbid0IGxpa2UgZW51bSAtPiBlbnVtIGNhc3RzLCBzbyB3ZSBpbXBsaWNpdF9jYXN0IHRvCisgIC8vIGludCBmaXJzdC4KKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZUZvckZpZWxkVHlwZSgKKyAgICAgIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGU+KAorICAgICAgICBpbXBsaWNpdF9jYXN0PGludD4odHlwZSkpKTsKK30KKworaW5saW5lIHVpbnQzMiBXaXJlRm9ybWF0OjpNYWtlVGFnKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwgV2lyZVR5cGVGb3JGaWVsZChmaWVsZCkpOworfQorCitpbmxpbmUgaW50IFdpcmVGb3JtYXQ6OlRhZ1NpemUoaW50IGZpZWxkX251bWJlciwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgLy8gU29tZSBjb21waWxlcnMgZG9uJ3QgbGlrZSBlbnVtIC0+IGVudW0gY2FzdHMsIHNvIHdlIGltcGxpY2l0X2Nhc3QgdG8KKyAgLy8gaW50IGZpcnN0LgorICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OlRhZ1NpemUoZmllbGRfbnVtYmVyLAorICAgICAgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZT4oCisgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50Pih0eXBlKSkpOworfQorCitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nKGNvbnN0IGNoYXIqIGRhdGEsIGludCBzaXplLAorICAgIFdpcmVGb3JtYXQ6Ok9wZXJhdGlvbiBvcCkgeworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorICBXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nRmFsbGJhY2soZGF0YSwgc2l6ZSwgb3AsIE5VTEwpOworI2Vsc2UKKyAgLy8gQXZvaWQgdGhlIGNvbXBpbGVyIHdhcm5pbmcgYWJvdXQgdW5zdWVkIHZhcmlhYmxlcy4KKyAgKHZvaWQpZGF0YTsgKHZvaWQpc2l6ZTsgKHZvaWQpb3A7CisjZW5kaWYKK30KKworaW5saW5lIHZvaWQgV2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgY29uc3QgY2hhciogZGF0YSwgaW50IHNpemUsIFdpcmVGb3JtYXQ6Ok9wZXJhdGlvbiBvcCwKKyAgICBjb25zdCBjaGFyKiBmaWVsZF9uYW1lKSB7CisjaWZkZWYgR09PR0xFX1BST1RPQlVGX1VURjhfVkFMSURBVElPTl9FTkFCTEVECisgIFdpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdGYWxsYmFjayhkYXRhLCBzaXplLCBvcCwgZmllbGRfbmFtZSk7CisjZW5kaWYKK30KKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yY2U0OTIwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmNjCkBAIC0wLDAgKzEsNTA5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKworI2luY2x1ZGUgPHN0YWNrPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworI2lmbmRlZiBfTVNDX1ZFUiAgICAvLyBNU1ZDIGRvZXNuJ3QgbGlrZSBkZWZpbml0aW9ucyBvZiBpbmxpbmUgY29uc3RhbnRzLCBHQ0MKKyAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWlyZXMgdGhlbS4KK2NvbnN0IGludCBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtU3RhcnRUYWc7Citjb25zdCBpbnQgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZzsKK2NvbnN0IGludCBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRUeXBlSWRUYWc7Citjb25zdCBpbnQgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZVRhZzsKKworI2VuZGlmCisKKy8vIElCTSB4bEMgcmVxdWlyZXMgcHJlZml4aW5nIGNvbnN0YW50cyB3aXRoIFdpcmVGb3JtYXRMaXRlOjoKK2NvbnN0IGludCBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtVGFnc1NpemUgPQorICBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlN0YXRpY1ZhcmludFNpemUzMjwKKyAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZz46OnZhbHVlICsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpTdGF0aWNWYXJpbnRTaXplMzI8CisgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnPjo6dmFsdWUgKworICBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlN0YXRpY1ZhcmludFNpemUzMjwKKyAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZz46OnZhbHVlICsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpTdGF0aWNWYXJpbnRTaXplMzI8CisgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlVGFnPjo6dmFsdWU7CisKK2NvbnN0IFdpcmVGb3JtYXRMaXRlOjpDcHBUeXBlCitXaXJlRm9ybWF0TGl0ZTo6a0ZpZWxkVHlwZVRvQ3BwVHlwZU1hcFtNQVhfRklFTERfVFlQRSArIDFdID0geworICBzdGF0aWNfY2FzdDxDcHBUeXBlPigwKSwgIC8vIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycworCisgIENQUFRZUEVfRE9VQkxFLCAgIC8vIFRZUEVfRE9VQkxFCisgIENQUFRZUEVfRkxPQVQsICAgIC8vIFRZUEVfRkxPQVQKKyAgQ1BQVFlQRV9JTlQ2NCwgICAgLy8gVFlQRV9JTlQ2NAorICBDUFBUWVBFX1VJTlQ2NCwgICAvLyBUWVBFX1VJTlQ2NAorICBDUFBUWVBFX0lOVDMyLCAgICAvLyBUWVBFX0lOVDMyCisgIENQUFRZUEVfVUlOVDY0LCAgIC8vIFRZUEVfRklYRUQ2NAorICBDUFBUWVBFX1VJTlQzMiwgICAvLyBUWVBFX0ZJWEVEMzIKKyAgQ1BQVFlQRV9CT09MLCAgICAgLy8gVFlQRV9CT09MCisgIENQUFRZUEVfU1RSSU5HLCAgIC8vIFRZUEVfU1RSSU5HCisgIENQUFRZUEVfTUVTU0FHRSwgIC8vIFRZUEVfR1JPVVAKKyAgQ1BQVFlQRV9NRVNTQUdFLCAgLy8gVFlQRV9NRVNTQUdFCisgIENQUFRZUEVfU1RSSU5HLCAgIC8vIFRZUEVfQllURVMKKyAgQ1BQVFlQRV9VSU5UMzIsICAgLy8gVFlQRV9VSU5UMzIKKyAgQ1BQVFlQRV9FTlVNLCAgICAgLy8gVFlQRV9FTlVNCisgIENQUFRZUEVfSU5UMzIsICAgIC8vIFRZUEVfU0ZJWEVEMzIKKyAgQ1BQVFlQRV9JTlQ2NCwgICAgLy8gVFlQRV9TRklYRUQ2NAorICBDUFBUWVBFX0lOVDMyLCAgICAvLyBUWVBFX1NJTlQzMgorICBDUFBUWVBFX0lOVDY0LCAgICAvLyBUWVBFX1NJTlQ2NAorfTsKKworY29uc3QgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlCitXaXJlRm9ybWF0TGl0ZTo6a1dpcmVUeXBlRm9yRmllbGRUeXBlW01BWF9GSUVMRF9UWVBFICsgMV0gPSB7CisgIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZT4oLTEpLCAgLy8gaW52YWxpZAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NCwgICAgICAgICAgIC8vIFRZUEVfRE9VQkxFCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDMyLCAgICAgICAgICAgLy8gVFlQRV9GTE9BVAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAgICAgICAgICAgIC8vIFRZUEVfSU5UNjQKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgICAgICAgICAgICAvLyBUWVBFX1VJTlQ2NAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAgICAgICAgICAgIC8vIFRZUEVfSU5UMzIKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVENjQsICAgICAgICAgICAvLyBUWVBFX0ZJWEVENjQKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzIsICAgICAgICAgICAvLyBUWVBFX0ZJWEVEMzIKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgICAgICAgICAgICAvLyBUWVBFX0JPT0wKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsICAvLyBUWVBFX1NUUklORworICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVAsICAgICAgIC8vIFRZUEVfR1JPVVAKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsICAvLyBUWVBFX01FU1NBR0UKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsICAvLyBUWVBFX0JZVEVTCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQsICAgICAgICAgICAgLy8gVFlQRV9VSU5UMzIKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgICAgICAgICAgICAvLyBUWVBFX0VOVU0KKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzIsICAgICAgICAgICAvLyBUWVBFX1NGSVhFRDMyCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0LCAgICAgICAgICAgLy8gVFlQRV9TRklYRUQ2NAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAgICAgICAgICAgIC8vIFRZUEVfU0lOVDMyCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQsICAgICAgICAgICAgLy8gVFlQRV9TSU5UNjQKK307CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpIHsKKyAgc3dpdGNoIChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSkgeworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVDogeworICAgICAgdWludDY0IHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0OiB7CisgICAgICB1aW50NjQgdmFsdWU7CisgICAgICBpZiAoIWlucHV0LT5SZWFkTGl0dGxlRW5kaWFuNjQoJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQ6IHsKKyAgICAgIHVpbnQzMiBsZW5ndGg7CisgICAgICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghaW5wdXQtPlNraXAobGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1NUQVJUX0dST1VQOiB7CisgICAgICBpZiAoIWlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKSByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoIVNraXBNZXNzYWdlKGlucHV0KSkgcmV0dXJuIGZhbHNlOworICAgICAgaW5wdXQtPkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAvLyBDaGVjayB0aGF0IHRoZSBlbmRpbmcgdGFnIG1hdGNoZWQgdGhlIHN0YXJ0aW5nIHRhZy4KKyAgICAgIGlmICghaW5wdXQtPkxhc3RUYWdXYXMoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVA6IHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMjogeworICAgICAgdWludDMyIHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBkZWZhdWx0OiB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcsIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIHN3aXRjaCAoV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykpIHsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQ6IHsKKyAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQ2NCgmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIodGFnKTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQ2NCh2YWx1ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NDogeworICAgICAgdWludDY0IHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjY0KHZhbHVlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOiB7CisgICAgICB1aW50MzIgbGVuZ3RoOworICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIodGFnKTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihsZW5ndGgpOworICAgICAgLy8gVE9ETyhta2lsYXZ1eik6IFByb3ZpZGUgQVBJIHRvIHByZXZlbnQgZXh0cmEgc3RyaW5nIGNvcHlpbmcuCisgICAgICBzdHJpbmcgdGVtcDsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRTdHJpbmcoJnRlbXAsIGxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgICAgIG91dHB1dC0+V3JpdGVTdHJpbmcodGVtcCk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVA6IHsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgaWYgKCFpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSkgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCFTa2lwTWVzc2FnZShpbnB1dCwgb3V0cHV0KSkgcmV0dXJuIGZhbHNlOworICAgICAgaW5wdXQtPkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAvLyBDaGVjayB0aGF0IHRoZSBlbmRpbmcgdGFnIG1hdGNoZWQgdGhlIHN0YXJ0aW5nIHRhZy4KKyAgICAgIGlmICghaW5wdXQtPkxhc3RUYWdXYXMoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVA6IHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMjogeworICAgICAgdWludDMyIHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjMyKHZhbHVlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBkZWZhdWx0OiB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICB3aGlsZSAodHJ1ZSkgeworICAgIHVpbnQzMiB0YWcgPSBpbnB1dC0+UmVhZFRhZygpOworICAgIGlmICh0YWcgPT0gMCkgeworICAgICAgLy8gRW5kIG9mIGlucHV0LiAgVGhpcyBpcyBhIHZhbGlkIHBsYWNlIHRvIGVuZCwgc28gcmV0dXJuIHRydWUuCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZV90eXBlID0gV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZyk7CisKKyAgICBpZiAod2lyZV90eXBlID09IFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgIC8vIE11c3QgYmUgdGhlIGVuZCBvZiB0aGUgbWVzc2FnZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGlmICghU2tpcEZpZWxkKGlucHV0LCB0YWcpKSByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBXaXJlRm9ybWF0TGl0ZTo6U2tpcE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIHdoaWxlICh0cnVlKSB7CisgICAgdWludDMyIHRhZyA9IGlucHV0LT5SZWFkVGFnKCk7CisgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAvLyBFbmQgb2YgaW5wdXQuICBUaGlzIGlzIGEgdmFsaWQgcGxhY2UgdG8gZW5kLCBzbyByZXR1cm4gdHJ1ZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSB3aXJlX3R5cGUgPSBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKTsKKworICAgIGlmICh3aXJlX3R5cGUgPT0gV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHRhZyk7CisgICAgICAvLyBNdXN0IGJlIHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UuCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBpZiAoIVNraXBGaWVsZChpbnB1dCwgdGFnLCBvdXRwdXQpKSByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBGaWVsZFNraXBwZXI6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZyk7Cit9CisKK2Jvb2wgRmllbGRTa2lwcGVyOjpTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpTa2lwTWVzc2FnZShpbnB1dCk7Cit9CisKK3ZvaWQgRmllbGRTa2lwcGVyOjpTa2lwVW5rbm93bkVudW0oCisgICAgaW50IC8qIGZpZWxkX251bWJlciAqLywgaW50IC8qIHZhbHVlICovKSB7CisgIC8vIE5vdGhpbmcuCit9CisKK2Jvb2wgQ29kZWRPdXRwdXRTdHJlYW1GaWVsZFNraXBwZXI6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZywgdW5rbm93bl9maWVsZHNfKTsKK30KKworYm9vbCBDb2RlZE91dHB1dFN0cmVhbUZpZWxkU2tpcHBlcjo6U2tpcE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6U2tpcE1lc3NhZ2UoaW5wdXQsIHVua25vd25fZmllbGRzXyk7Cit9CisKK3ZvaWQgQ29kZWRPdXRwdXRTdHJlYW1GaWVsZFNraXBwZXI6OlNraXBVbmtub3duRW51bSgKKyAgICBpbnQgZmllbGRfbnVtYmVyLCBpbnQgdmFsdWUpIHsKKyAgdW5rbm93bl9maWVsZHNfLT5Xcml0ZVZhcmludDMyKGZpZWxkX251bWJlcik7CisgIHVua25vd25fZmllbGRzXy0+V3JpdGVWYXJpbnQ2NCh2YWx1ZSk7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRFbnVtTm9JbmxpbmUoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sICgqaXNfdmFsaWQpKGludCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50PiogdmFsdWVzKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBpbnB1dC0+UHVzaExpbWl0KGxlbmd0aCk7CisgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgaW50IHZhbHVlOworICAgIGlmICghZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICBpbnQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KGlucHV0LCAmdmFsdWUpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChpc192YWxpZCA9PSBOVUxMIHx8IGlzX3ZhbGlkKHZhbHVlKSkgeworICAgICAgdmFsdWVzLT5BZGQodmFsdWUpOworICAgIH0KKyAgfQorICBpbnB1dC0+UG9wTGltaXQobGltaXQpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZEVudW1QcmVzZXJ2ZVVua25vd25zKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgIGJvb2wgKCppc192YWxpZCkoaW50KSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHVua25vd25fZmllbGRzX3N0cmVhbSwKKyAgICBSZXBlYXRlZEZpZWxkPGludD4qIHZhbHVlcykgeworICB1aW50MzIgbGVuZ3RoOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gaW5wdXQtPlB1c2hMaW1pdChsZW5ndGgpOworICB3aGlsZSAoaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeworICAgIGludCB2YWx1ZTsKKyAgICBpZiAoIWdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgaW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPihpbnB1dCwgJnZhbHVlKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoaXNfdmFsaWQgPT0gTlVMTCB8fCBpc192YWxpZCh2YWx1ZSkpIHsKKyAgICAgIHZhbHVlcy0+QWRkKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgdWludDMyIHRhZyA9IFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5UKTsKKyAgICAgIHVua25vd25fZmllbGRzX3N0cmVhbS0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgdW5rbm93bl9maWVsZHNfc3RyZWFtLT5Xcml0ZVZhcmludDMyKHZhbHVlKTsKKyAgICB9CisgIH0KKyAgaW5wdXQtPlBvcExpbWl0KGxpbWl0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoaW50IGZpZWxkX251bWJlciwgaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCBvdXRwdXQpOworICBXcml0ZUludDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0KGludCBmaWVsZF9udW1iZXIsIGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgb3V0cHV0KTsKKyAgV3JpdGVJbnQ2NE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzIoaW50IGZpZWxkX251bWJlciwgdWludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIG91dHB1dCk7CisgIFdyaXRlVUludDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NChpbnQgZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgb3V0cHV0KTsKKyAgV3JpdGVVSW50NjROb1RhZyh2YWx1ZSwgb3V0cHV0KTsKK30KK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ludDMyKGludCBmaWVsZF9udW1iZXIsIGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIG91dHB1dCk7CisgIFdyaXRlU0ludDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQ2NChpbnQgZmllbGRfbnVtYmVyLCBpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCBvdXRwdXQpOworICBXcml0ZVNJbnQ2NE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDMyKGludCBmaWVsZF9udW1iZXIsIHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVEMzIsIG91dHB1dCk7CisgIFdyaXRlRml4ZWQzMk5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDY0KGludCBmaWVsZF9udW1iZXIsIHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVENjQsIG91dHB1dCk7CisgIFdyaXRlRml4ZWQ2NE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQzMihpbnQgZmllbGRfbnVtYmVyLCBpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDMyLCBvdXRwdXQpOworICBXcml0ZVNGaXhlZDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNGaXhlZDY0KGludCBmaWVsZF9udW1iZXIsIGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVENjQsIG91dHB1dCk7CisgIFdyaXRlU0ZpeGVkNjROb1RhZyh2YWx1ZSwgb3V0cHV0KTsKK30KK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlRmxvYXQoaW50IGZpZWxkX251bWJlciwgZmxvYXQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRklYRUQzMiwgb3V0cHV0KTsKKyAgV3JpdGVGbG9hdE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGUoaW50IGZpZWxkX251bWJlciwgZG91YmxlIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDY0LCBvdXRwdXQpOworICBXcml0ZURvdWJsZU5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKGludCBmaWVsZF9udW1iZXIsIGJvb2wgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIG91dHB1dCk7CisgIFdyaXRlQm9vbE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKGludCBmaWVsZF9udW1iZXIsIGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgb3V0cHV0KTsKKyAgV3JpdGVFbnVtTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nKGludCBmaWVsZF9udW1iZXIsIGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICAvLyBTdHJpbmcgaXMgZm9yIFVURi04IHRleHQgb25seQorICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZS5zaXplKCkgPD0ga2ludDMybWF4KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlLnNpemUoKSk7CisgIG91dHB1dC0+V3JpdGVTdHJpbmcodmFsdWUpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgaW50IGZpZWxkX251bWJlciwgY29uc3Qgc3RyaW5nJiB2YWx1ZSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICAvLyBTdHJpbmcgaXMgZm9yIFVURi04IHRleHQgb25seQorICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZS5zaXplKCkgPD0ga2ludDMybWF4KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlLnNpemUoKSk7CisgIG91dHB1dC0+V3JpdGVSYXdNYXliZUFsaWFzZWQodmFsdWUuZGF0YSgpLCB2YWx1ZS5zaXplKCkpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlcyhpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZS5zaXplKCkgPD0ga2ludDMybWF4KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlLnNpemUoKSk7CisgIG91dHB1dC0+V3JpdGVTdHJpbmcodmFsdWUpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlc01heWJlQWxpYXNlZCgKKyAgICBpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgR09PR0xFX0NIRUNLKHZhbHVlLnNpemUoKSA8PSBraW50MzJtYXgpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIodmFsdWUuc2l6ZSgpKTsKKyAgb3V0cHV0LT5Xcml0ZVJhd01heWJlQWxpYXNlZCh2YWx1ZS5kYXRhKCksIHZhbHVlLnNpemUoKSk7Cit9CisKKwordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVHcm91cChpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfU1RBUlRfR1JPVVAsIG91dHB1dCk7CisgIHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0VORF9HUk9VUCwgb3V0cHV0KTsKK30KKwordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlKGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgY29uc3QgaW50IHNpemUgPSB2YWx1ZS5HZXRDYWNoZWRTaXplKCk7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihzaXplKTsKKyAgdmFsdWUuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlR3JvdXBNYXliZVRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1NUQVJUX0dST1VQLCBvdXRwdXQpOworICBjb25zdCBpbnQgc2l6ZSA9IHZhbHVlLkdldENhY2hlZFNpemUoKTsKKyAgdWludDgqIHRhcmdldCA9IG91dHB1dC0+R2V0RGlyZWN0QnVmZmVyRm9yTkJ5dGVzQW5kQWR2YW5jZShzaXplKTsKKyAgaWYgKHRhcmdldCAhPSBOVUxMKSB7CisgICAgdWludDgqIGVuZCA9IHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTsKKyAgICBHT09HTEVfRENIRUNLX0VRKGVuZCAtIHRhcmdldCwgc2l6ZSk7CisgIH0gZWxzZSB7CisgICAgdmFsdWUuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7CisgIH0KKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9FTkRfR1JPVVAsIG91dHB1dCk7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIGNvbnN0IGludCBzaXplID0gdmFsdWUuR2V0Q2FjaGVkU2l6ZSgpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoc2l6ZSk7CisgIHVpbnQ4KiB0YXJnZXQgPSBvdXRwdXQtPkdldERpcmVjdEJ1ZmZlckZvck5CeXRlc0FuZEFkdmFuY2Uoc2l6ZSk7CisgIGlmICh0YXJnZXQgIT0gTlVMTCkgeworICAgIHVpbnQ4KiBlbmQgPSB2YWx1ZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7CisgICAgR09PR0xFX0RDSEVDS19FUShlbmQgLSB0YXJnZXQsIHNpemUpOworICB9IGVsc2UgeworICAgIHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICB9Cit9CisKK3N0YXRpYyBpbmxpbmUgYm9vbCBSZWFkQnl0ZXNUb1N0cmluZyhpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiB2YWx1ZSkgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FOworc3RhdGljIGlubGluZSBib29sIFJlYWRCeXRlc1RvU3RyaW5nKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHZhbHVlKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIHJldHVybiBpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpICYmCisgICAgICBpbnB1dC0+SW50ZXJuYWxSZWFkU3RyaW5nSW5saW5lKHZhbHVlLCBsZW5ndGgpOworfQorCitib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBzdHJpbmcqIHZhbHVlKSB7CisgIHJldHVybiBSZWFkQnl0ZXNUb1N0cmluZyhpbnB1dCwgdmFsdWUpOworfQorCitib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBzdHJpbmcqKiBwKSB7CisgIGlmICgqcCA9PSAmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpIHsKKyAgICAqcCA9IG5ldyA6OnN0ZDo6c3RyaW5nKCk7CisgIH0KKyAgcmV0dXJuIFJlYWRCeXRlc1RvU3RyaW5nKGlucHV0LCAqcCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2YmM3NWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaApAQCAtMCwwICsxLDY5MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICAgICAgICAgYXRlbmFzaW9AZ29vZ2xlLmNvbSAoQ2hyaXMgQXRlbmFzaW8pIChaaWdaYWcgdHJhbnNmb3JtKQorLy8gICAgICAgICB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSkgKHJlZmFjdG9yZWQgZnJvbSB3aXJlX2Zvcm1hdC5oKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBoZWFkZXIgaXMgbG9naWNhbGx5IGludGVybmFsLCBidXQgaXMgbWFkZSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCisvLyBmcm9tIHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZCBjb2RlLCB3aGljaCBtYXkgcmVzaWRlIGluIG90aGVyIGNvbXBvbmVudHMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0xJVEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9MSVRFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPiAgLy8gZm9yIENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnQzMlNpemUKKworbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBjbGFzcyBSZXBlYXRlZEZpZWxkOyAgLy8gcmVwZWF0ZWRfZmllbGQuaAorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgU3RyaW5nUGllY2VGaWVsZDsKKworLy8gVGhpcyBjbGFzcyBpcyBmb3IgaW50ZXJuYWwgdXNlIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgbGlicmFyeSBhbmQgYnkKKy8vIHByb3RvY29sLWNvbXBsaWVyLWdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMuICBJdCBtdXN0IG5vdCBiZSBjYWxsZWQKKy8vIGRpcmVjdGx5IGJ5IGNsaWVudHMuCisvLworLy8gVGhpcyBjbGFzcyBjb250YWlucyBoZWxwZXJzIGZvciBpbXBsZW1lbnRpbmcgdGhlIGJpbmFyeSBwcm90b2NvbCBidWZmZXIKKy8vIHdpcmUgZm9ybWF0IHdpdGhvdXQgdGhlIG5lZWQgZm9yIHJlZmxlY3Rpb24uIFVzZSBXaXJlRm9ybWF0IHdoZW4gdXNpbmcKKy8vIHJlZmxlY3Rpb24uCisvLworLy8gVGhpcyBjbGFzcyBpcyByZWFsbHkgYSBuYW1lc3BhY2UgdGhhdCBjb250YWlucyBvbmx5IHN0YXRpYyBtZXRob2RzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFdpcmVGb3JtYXRMaXRlIHsKKyBwdWJsaWM6CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSGVscGVyIGNvbnN0YW50cyBhbmQgZnVuY3Rpb25zIHJlbGF0ZWQgdG8gdGhlIGZvcm1hdC4gIFRoZXNlIGFyZQorICAvLyBtb3N0bHkgbWVhbnQgZm9yIGludGVybmFsIGFuZCBnZW5lcmF0ZWQgY29kZSB0byB1c2UuCisKKyAgLy8gVGhlIHdpcmUgZm9ybWF0IGlzIGNvbXBvc2VkIG9mIGEgc2VxdWVuY2Ugb2YgdGFnL3ZhbHVlIHBhaXJzLCBlYWNoCisgIC8vIG9mIHdoaWNoIGNvbnRhaW5zIHRoZSB2YWx1ZSBvZiBvbmUgZmllbGQgKG9yIG9uZSBlbGVtZW50IG9mIGEgcmVwZWF0ZWQKKyAgLy8gZmllbGQpLiAgRWFjaCB0YWcgaXMgZW5jb2RlZCBhcyBhIHZhcmludC4gIFRoZSBsb3dlciBiaXRzIG9mIHRoZSB0YWcKKyAgLy8gaWRlbnRpZnkgaXRzIHdpcmUgdHlwZSwgd2hpY2ggc3BlY2lmaWVzIHRoZSBmb3JtYXQgb2YgdGhlIGRhdGEgdG8gZm9sbG93LgorICAvLyBUaGUgcmVzdCBvZiB0aGUgYml0cyBjb250YWluIHRoZSBmaWVsZCBudW1iZXIuICBFYWNoIHR5cGUgb2YgZmllbGQgKGFzCisgIC8vIGRlY2xhcmVkIGJ5IEZpZWxkRGVzY3JpcHRvcjo6VHlwZSwgaW4gZGVzY3JpcHRvci5oKSBtYXBzIHRvIG9uZSBvZgorICAvLyB0aGVzZSB3aXJlIHR5cGVzLiAgSW1tZWRpYXRlbHkgZm9sbG93aW5nIGVhY2ggdGFnIGlzIHRoZSBmaWVsZCdzIHZhbHVlLAorICAvLyBlbmNvZGVkIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkIGJ5IHRoZSB3aXJlIHR5cGUuICBCZWNhdXNlIHRoZSB0YWcKKyAgLy8gaWRlbnRpZmllcyB0aGUgZW5jb2Rpbmcgb2YgdGhpcyBkYXRhLCBpdCBpcyBwb3NzaWJsZSB0byBza2lwCisgIC8vIHVucmVjb2duaXplZCBmaWVsZHMgZm9yIGZvcndhcmRzIGNvbXBhdGliaWxpdHkuCisKKyAgZW51bSBXaXJlVHlwZSB7CisgICAgV0lSRVRZUEVfVkFSSU5UICAgICAgICAgICA9IDAsCisgICAgV0lSRVRZUEVfRklYRUQ2NCAgICAgICAgICA9IDEsCisgICAgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCA9IDIsCisgICAgV0lSRVRZUEVfU1RBUlRfR1JPVVAgICAgICA9IDMsCisgICAgV0lSRVRZUEVfRU5EX0dST1VQICAgICAgICA9IDQsCisgICAgV0lSRVRZUEVfRklYRUQzMiAgICAgICAgICA9IDUsCisgIH07CisKKyAgLy8gTGl0ZSBhbHRlcm5hdGl2ZSB0byBGaWVsZERlc2NyaXB0b3I6OlR5cGUuICBNdXN0IGJlIGtlcHQgaW4gc3luYy4KKyAgZW51bSBGaWVsZFR5cGUgeworICAgIFRZUEVfRE9VQkxFICAgICAgICAgPSAxLAorICAgIFRZUEVfRkxPQVQgICAgICAgICAgPSAyLAorICAgIFRZUEVfSU5UNjQgICAgICAgICAgPSAzLAorICAgIFRZUEVfVUlOVDY0ICAgICAgICAgPSA0LAorICAgIFRZUEVfSU5UMzIgICAgICAgICAgPSA1LAorICAgIFRZUEVfRklYRUQ2NCAgICAgICAgPSA2LAorICAgIFRZUEVfRklYRUQzMiAgICAgICAgPSA3LAorICAgIFRZUEVfQk9PTCAgICAgICAgICAgPSA4LAorICAgIFRZUEVfU1RSSU5HICAgICAgICAgPSA5LAorICAgIFRZUEVfR1JPVVAgICAgICAgICAgPSAxMCwKKyAgICBUWVBFX01FU1NBR0UgICAgICAgID0gMTEsCisgICAgVFlQRV9CWVRFUyAgICAgICAgICA9IDEyLAorICAgIFRZUEVfVUlOVDMyICAgICAgICAgPSAxMywKKyAgICBUWVBFX0VOVU0gICAgICAgICAgID0gMTQsCisgICAgVFlQRV9TRklYRUQzMiAgICAgICA9IDE1LAorICAgIFRZUEVfU0ZJWEVENjQgICAgICAgPSAxNiwKKyAgICBUWVBFX1NJTlQzMiAgICAgICAgID0gMTcsCisgICAgVFlQRV9TSU5UNjQgICAgICAgICA9IDE4LAorICAgIE1BWF9GSUVMRF9UWVBFICAgICAgPSAxOCwKKyAgfTsKKworICAvLyBMaXRlIGFsdGVybmF0aXZlIHRvIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZS4gIE11c3QgYmUga2VwdCBpbiBzeW5jLgorICBlbnVtIENwcFR5cGUgeworICAgIENQUFRZUEVfSU5UMzIgICAgICAgPSAxLAorICAgIENQUFRZUEVfSU5UNjQgICAgICAgPSAyLAorICAgIENQUFRZUEVfVUlOVDMyICAgICAgPSAzLAorICAgIENQUFRZUEVfVUlOVDY0ICAgICAgPSA0LAorICAgIENQUFRZUEVfRE9VQkxFICAgICAgPSA1LAorICAgIENQUFRZUEVfRkxPQVQgICAgICAgPSA2LAorICAgIENQUFRZUEVfQk9PTCAgICAgICAgPSA3LAorICAgIENQUFRZUEVfRU5VTSAgICAgICAgPSA4LAorICAgIENQUFRZUEVfU1RSSU5HICAgICAgPSA5LAorICAgIENQUFRZUEVfTUVTU0FHRSAgICAgPSAxMCwKKyAgICBNQVhfQ1BQVFlQRSAgICAgICAgID0gMTAsCisgIH07CisKKyAgLy8gSGVscGVyIG1ldGhvZCB0byBnZXQgdGhlIENwcFR5cGUgZm9yIGEgcGFydGljdWxhciBUeXBlLgorICBzdGF0aWMgQ3BwVHlwZSBGaWVsZFR5cGVUb0NwcFR5cGUoRmllbGRUeXBlIHR5cGUpOworCisgIC8vIEdpdmVuIGEgRmllbGRTZXNjcmlwdG9yOjpUeXBlIHJldHVybiBpdHMgV2lyZVR5cGUKKyAgc3RhdGljIGlubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZVR5cGVGb3JGaWVsZFR5cGUoCisgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHR5cGUpIHsKKyAgICByZXR1cm4ga1dpcmVUeXBlRm9yRmllbGRUeXBlW3R5cGVdOworICB9CisKKyAgLy8gTnVtYmVyIG9mIGJpdHMgaW4gYSB0YWcgd2hpY2ggaWRlbnRpZnkgdGhlIHdpcmUgdHlwZS4KKyAgc3RhdGljIGNvbnN0IGludCBrVGFnVHlwZUJpdHMgPSAzOworICAvLyBNYXNrIGZvciB0aG9zZSBiaXRzLgorICBzdGF0aWMgY29uc3QgdWludDMyIGtUYWdUeXBlTWFzayA9ICgxIDw8IGtUYWdUeXBlQml0cykgLSAxOworCisgIC8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyB0YWdzLiAgKElubGluZWQgYmVsb3cgYW5kIGluCisgIC8vIF9pbmwuaCkKKyAgLy8KKyAgLy8gVGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkgaW4gdGhlIGNhc2UKKyAgLy8gb2YgcGFja2VkIHJlcGVhdGVkIGZpZWxkcy4KKyAgc3RhdGljIHVpbnQzMiBNYWtlVGFnKGludCBmaWVsZF9udW1iZXIsIFdpcmVUeXBlIHR5cGUpOworICBzdGF0aWMgV2lyZVR5cGUgR2V0VGFnV2lyZVR5cGUodWludDMyIHRhZyk7CisgIHN0YXRpYyBpbnQgR2V0VGFnRmllbGROdW1iZXIodWludDMyIHRhZyk7CisKKyAgLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIGEgdGFnLiAgRm9yIGdyb3VwcywgdGhpcyBpbmNsdWRlcyBib3RoIHRoZSBzdGFydAorICAvLyBhbmQgZW5kIHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgaW50IFRhZ1NpemUoaW50IGZpZWxkX251bWJlciwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB0eXBlKTsKKworICAvLyBTa2lwcyBhIGZpZWxkIHZhbHVlIHdpdGggdGhlIGdpdmVuIHRhZy4gIFRoZSBpbnB1dCBzaG91bGQgc3RhcnQKKyAgLy8gcG9zaXRpb25lZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgdGFnLiAgU2tpcHBlZCB2YWx1ZXMgYXJlIHNpbXBseSBkaXNjYXJkZWQsCisgIC8vIG5vdCByZWNvcmRlZCBhbnl3aGVyZS4gIFNlZSBXaXJlRm9ybWF0OjpTa2lwRmllbGQoKSBmb3IgYSB2ZXJzaW9uIHRoYXQKKyAgLy8gcmVjb3JkcyB0byBhbiBVbmtub3duRmllbGRTZXQuCisgIHN0YXRpYyBib29sIFNraXBGaWVsZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpOworCisgIC8vIFNraXBzIGEgZmllbGQgdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gdGFnLiAgVGhlIGlucHV0IHNob3VsZCBzdGFydAorICAvLyBwb3NpdGlvbmVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSB0YWcuIFNraXBwZWQgdmFsdWVzIGFyZSByZWNvcmRlZCB0byBhCisgIC8vIENvZGVkT3V0cHV0U3RyZWFtLgorICBzdGF0aWMgYm9vbCBTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOworCisgIC8vIFJlYWRzIGFuZCBpZ25vcmVzIGEgbWVzc2FnZSBmcm9tIHRoZSBpbnB1dC4gIFNraXBwZWQgdmFsdWVzIGFyZSBzaW1wbHkKKyAgLy8gZGlzY2FyZGVkLCBub3QgcmVjb3JkZWQgYW55d2hlcmUuICBTZWUgV2lyZUZvcm1hdDo6U2tpcE1lc3NhZ2UoKSBmb3IgYQorICAvLyB2ZXJzaW9uIHRoYXQgcmVjb3JkcyB0byBhbiBVbmtub3duRmllbGRTZXQuCisgIHN0YXRpYyBib29sIFNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisKKyAgLy8gUmVhZHMgYW5kIGlnbm9yZXMgYSBtZXNzYWdlIGZyb20gdGhlIGlucHV0LiAgU2tpcHBlZCB2YWx1ZXMgYXJlIHJlY29yZGVkCisgIC8vIHRvIGEgQ29kZWRPdXRwdXRTdHJlYW0uCisgIHN0YXRpYyBib29sIFNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOworCisvLyBUaGlzIG1hY3JvIGRvZXMgdGhlIHNhbWUgdGhpbmcgYXMgV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoKSwgYnV0IHRoZQorLy8gcmVzdWx0IGlzIHVzYWJsZSBhcyBhIGNvbXBpbGUtdGltZSBjb25zdGFudCwgd2hpY2ggbWFrZXMgaXQgdXNhYmxlCisvLyBhcyBhIHN3aXRjaCBjYXNlIG9yIGEgdGVtcGxhdGUgaW5wdXQuICBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygpIGlzIG1vcmUKKy8vIHR5cGUtc2FmZSwgdGhvdWdoLCBzbyBwcmVmZXIgaXQgaWYgcG9zc2libGUuCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9NQUtFX1RBRyhGSUVMRF9OVU1CRVIsIFRZUEUpICAgICAgICAgICAgICAgICAgXAorICBzdGF0aWNfY2FzdDx1aW50MzI+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAoKEZJRUxEX05VTUJFUikgPDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtUYWdUeXBlQml0cykgXAorICAgICAgfCAoVFlQRSkpCisKKyAgLy8gVGhlc2UgYXJlIHRoZSB0YWdzIGZvciB0aGUgb2xkIE1lc3NhZ2VTZXQgZm9ybWF0LCB3aGljaCB3YXMgZGVmaW5lZCBhczoKKyAgLy8gICBtZXNzYWdlIE1lc3NhZ2VTZXQgeworICAvLyAgICAgcmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeworICAvLyAgICAgICByZXF1aXJlZCBpbnQzMiB0eXBlX2lkID0gMjsKKyAgLy8gICAgICAgcmVxdWlyZWQgc3RyaW5nIG1lc3NhZ2UgPSAzOworICAvLyAgICAgfQorICAvLyAgIH0KKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVNldEl0ZW1OdW1iZXIgPSAxOworICBzdGF0aWMgY29uc3QgaW50IGtNZXNzYWdlU2V0VHlwZUlkTnVtYmVyID0gMjsKKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVNldE1lc3NhZ2VOdW1iZXIgPSAzOworICBzdGF0aWMgY29uc3QgaW50IGtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnID0KKyAgICBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoa01lc3NhZ2VTZXRJdGVtTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVApOworICBzdGF0aWMgY29uc3QgaW50IGtNZXNzYWdlU2V0SXRlbUVuZFRhZyA9CisgICAgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX01BS0VfVEFHKGtNZXNzYWdlU2V0SXRlbU51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VTZXRUeXBlSWRUYWcgPQorICAgIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9NQUtFX1RBRyhrTWVzc2FnZVNldFR5cGVJZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VTZXRNZXNzYWdlVGFnID0KKyAgICBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoa01lc3NhZ2VTZXRNZXNzYWdlTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisKKyAgLy8gQnl0ZSBzaXplIG9mIGFsbCB0YWdzIG9mIGEgTWVzc2FnZVNldDo6SXRlbSBjb21iaW5lZC4KKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVNldEl0ZW1UYWdzU2l6ZTsKKworICAvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gZmxvYXRzL2RvdWJsZXMgYW5kIElFRUUtNzU0CisgIC8vIHVpbnQzMnMvdWludDY0cyBzbyB0aGF0IHRoZXkgY2FuIGJlIHdyaXR0ZW4uICAoQXNzdW1lcyB5b3VyIHBsYXRmb3JtCisgIC8vIHVzZXMgSUVFRS03NTQgZmxvYXRzLikKKyAgc3RhdGljIHVpbnQzMiBFbmNvZGVGbG9hdChmbG9hdCB2YWx1ZSk7CisgIHN0YXRpYyBmbG9hdCBEZWNvZGVGbG9hdCh1aW50MzIgdmFsdWUpOworICBzdGF0aWMgdWludDY0IEVuY29kZURvdWJsZShkb3VibGUgdmFsdWUpOworICBzdGF0aWMgZG91YmxlIERlY29kZURvdWJsZSh1aW50NjQgdmFsdWUpOworCisgIC8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIG1hcHBpbmcgc2lnbmVkIGludGVnZXJzIHRvIHVuc2lnbmVkIGludGVnZXJzIGluCisgIC8vIHN1Y2ggYSB3YXkgdGhhdCBudW1iZXJzIHdpdGggc21hbGwgbWFnbml0dWRlcyB3aWxsIGVuY29kZSB0byBzbWFsbGVyCisgIC8vIHZhcmludHMuICBJZiB5b3Ugc2ltcGx5IHN0YXRpY19jYXN0IGEgbmVnYXRpdmUgbnVtYmVyIHRvIGFuIHVuc2lnbmVkCisgIC8vIG51bWJlciBhbmQgdmFyaW50LWVuY29kZSBpdCwgaXQgd2lsbCBhbHdheXMgdGFrZSAxMCBieXRlcywgZGVmZWF0aW5nCisgIC8vIHRoZSBwdXJwb3NlIG9mIHZhcmludC4gIFNvLCBmb3IgdGhlICJzaW50MzIiIGFuZCAic2ludDY0IiBmaWVsZCB0eXBlcywKKyAgLy8gd2UgWmlnWmFnLWVuY29kZSB0aGUgdmFsdWVzLgorICBzdGF0aWMgdWludDMyIFppZ1phZ0VuY29kZTMyKGludDMyIG4pOworICBzdGF0aWMgaW50MzIgIFppZ1phZ0RlY29kZTMyKHVpbnQzMiBuKTsKKyAgc3RhdGljIHVpbnQ2NCBaaWdaYWdFbmNvZGU2NChpbnQ2NCBuKTsKKyAgc3RhdGljIGludDY0ICBaaWdaYWdEZWNvZGU2NCh1aW50NjQgbik7CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gTWV0aG9kcyBmb3IgcmVhZGluZy93cml0aW5nIGluZGl2aWR1YWwgZmllbGQuICBUaGUgaW1wbGVtZW50YXRpb25zCisgIC8vIG9mIHRoZXNlIG1ldGhvZHMgYXJlIGRlZmluZWQgaW4gd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaDsgeW91IG11c3QgI2luY2x1ZGUKKyAgLy8gdGhhdCBmaWxlIHRvIHVzZSB0aGVzZS4KKworLy8gQXZvaWQgdWdseSBsaW5lIHdyYXBwaW5nCisjZGVmaW5lIGlucHV0ICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogIGlucHV0X2FyZworI2RlZmluZSBvdXRwdXQgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXRfYXJnCisjZGVmaW5lIGZpZWxkX251bWJlciBpbnQgZmllbGRfbnVtYmVyX2FyZworI2RlZmluZSBJTkwgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisKKyAgLy8gUmVhZCBmaWVsZHMsIG5vdCBpbmNsdWRpbmcgdGFncy4gIFRoZSBhc3N1bXB0aW9uIGlzIHRoYXQgeW91IGFscmVhZHkKKyAgLy8gcmVhZCB0aGUgdGFnIHRvIGRldGVybWluZSB3aGF0IGZpZWxkIHRvIHJlYWQuCisKKyAgLy8gRm9yIHByaW1pdGl2ZSBmaWVsZHMsIHdlIGp1c3QgdXNlIGEgdGVtcGxhdGl6ZWQgcm91dGluZSBwYXJhbWV0ZXJpemVkIGJ5CisgIC8vIHRoZSByZXByZXNlbnRlZCB0eXBlIGFuZCB0aGUgRmllbGRUeXBlLiBUaGVzZSBhcmUgc3BlY2lhbGl6ZWQgd2l0aCB0aGUKKyAgLy8gYXBwcm9wcmlhdGUgZGVmaW5pdGlvbiBmb3IgZWFjaCBkZWNsYXJlZCB0eXBlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRQcmltaXRpdmUoaW5wdXQsIENUeXBlKiB2YWx1ZSkgSU5MOworCisgIC8vIFJlYWRzIHJlcGVhdGVkIHByaW1pdGl2ZSB2YWx1ZXMsIHdpdGggb3B0aW1pemF0aW9ucyBmb3IgcmVwZWF0cy4KKyAgLy8gdGFnX3NpemUgYW5kIHRhZyBzaG91bGQgYm90aCBiZSBjb21waWxlLXRpbWUgY29uc3RhbnRzIHByb3ZpZGVkIGJ5IHRoZQorICAvLyBwcm90b2NvbCBjb21waWxlci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIENUeXBlLCBlbnVtIEZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBSZWFkUmVwZWF0ZWRQcmltaXRpdmUoaW50IHRhZ19zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiB0YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlKSBJTkw7CisKKyAgLy8gSWRlbnRpY2FsIHRvIFJlYWRSZXBlYXRlZFByaW1pdGl2ZSwgZXhjZXB0IHdpbGwgbm90IGlubGluZSB0aGUKKyAgLy8gaW1wbGVtZW50YXRpb24uCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBDVHlwZSwgZW51bSBGaWVsZFR5cGUgRGVjbGFyZWRUeXBlPgorICBzdGF0aWMgYm9vbCBSZWFkUmVwZWF0ZWRQcmltaXRpdmVOb0lubGluZShpbnQgdGFnX3NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiB0YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWUpOworCisgIC8vIFJlYWRzIGEgcHJpbWl0aXZlIHZhbHVlIGRpcmVjdGx5IGZyb20gdGhlIHByb3ZpZGVkIGJ1ZmZlci4gSXQgcmV0dXJucyBhCisgIC8vIHBvaW50ZXIgcGFzdCB0aGUgc2VnbWVudCBvZiBkYXRhIHRoYXQgd2FzIHJlYWQuCisgIC8vCisgIC8vIFRoaXMgaXMgb25seSBpbXBsZW1lbnRlZCBmb3IgdGhlIHR5cGVzIHdpdGggZml4ZWQgd2lyZSBzaXplLCBlLmcuCisgIC8vIGZsb2F0LCBkb3VibGUsIGFuZCB0aGUgKHMpZml4ZWQqIHR5cGVzLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4KKyAgc3RhdGljIGlubGluZSBjb25zdCB1aW50OCogUmVhZFByaW1pdGl2ZUZyb21BcnJheShjb25zdCB1aW50OCogYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENUeXBlKiB2YWx1ZSkgSU5MOworCisgIC8vIFJlYWRzIGEgcHJpbWl0aXZlIHBhY2tlZCBmaWVsZC4KKyAgLy8KKyAgLy8gVGhpcyBpcyBvbmx5IGltcGxlbWVudGVkIGZvciBwYWNrYWJsZSB0eXBlcy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIENUeXBlLCBlbnVtIEZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBSZWFkUGFja2VkUHJpbWl0aXZlKGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWUpIElOTDsKKworICAvLyBJZGVudGljYWwgdG8gUmVhZFBhY2tlZFByaW1pdGl2ZSwgZXhjZXB0IHdpbGwgbm90IGlubGluZSB0aGUKKyAgLy8gaW1wbGVtZW50YXRpb24uCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBDVHlwZSwgZW51bSBGaWVsZFR5cGUgRGVjbGFyZWRUeXBlPgorICBzdGF0aWMgYm9vbCBSZWFkUGFja2VkUHJpbWl0aXZlTm9JbmxpbmUoaW5wdXQsIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZSk7CisKKyAgLy8gUmVhZCBhIHBhY2tlZCBlbnVtIGZpZWxkLiBJZiB0aGUgaXNfdmFsaWQgZnVuY3Rpb24gaXMgbm90IE5VTEwsIHZhbHVlcyBmb3IKKyAgLy8gd2hpY2ggaXNfdmFsaWQodmFsdWUpIHJldHVybnMgZmFsc2UgYXJlIHNpbGVudGx5IGRyb3BwZWQuCisgIHN0YXRpYyBib29sIFJlYWRQYWNrZWRFbnVtTm9JbmxpbmUoaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAoKmlzX3ZhbGlkKShpbnQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50PiogdmFsdWVzKTsKKworICAvLyBSZWFkIGEgcGFja2VkIGVudW0gZmllbGQuIElmIHRoZSBpc192YWxpZCBmdW5jdGlvbiBpcyBub3QgTlVMTCwgdmFsdWVzIGZvcgorICAvLyB3aGljaCBpc192YWxpZCh2YWx1ZSkgcmV0dXJucyBmYWxzZSBhcmUgYXBwZW5kZWQgdG8gdW5rbm93bl9maWVsZHNfc3RyZWFtLgorICBzdGF0aWMgYm9vbCBSZWFkUGFja2VkRW51bVByZXNlcnZlVW5rbm93bnMoCisgICAgICBpbnB1dCwKKyAgICAgIGZpZWxkX251bWJlciwKKyAgICAgIGJvb2wgKCppc192YWxpZCkoaW50KSwKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogdW5rbm93bl9maWVsZHNfc3RyZWFtLAorICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+KiB2YWx1ZXMpOworCisgIC8vIFJlYWQgYSBzdHJpbmcuICBSZWFkU3RyaW5nKC4uLiwgc3RyaW5nKiB2YWx1ZSkgcmVxdWlyZXMgYW4gZXhpc3Rpbmcgc3RyaW5nLgorICBzdGF0aWMgaW5saW5lIGJvb2wgUmVhZFN0cmluZyhpbnB1dCwgc3RyaW5nKiB2YWx1ZSk7CisgIC8vIFJlYWRTdHJpbmcoLi4uLCBzdHJpbmcqKiBwKSBpcyBpbnRlcm5hbC1vbmx5LCBhbmQgc2hvdWxkIG9ubHkgYmUgY2FsbGVkCisgIC8vIGZyb20gZ2VuZXJhdGVkIGNvZGUuIEl0IHN0YXJ0cyBieSBzZXR0aW5nICpwIHRvICJuZXcgc3RyaW5nIgorICAvLyBpZiAqcCA9PSAmR2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkuICBJdCB0aGVuIGludm9rZXMKKyAgLy8gUmVhZFN0cmluZyhpbnB1dCwgKnApLiAgVGhpcyBpcyB1c2VmdWwgZm9yIHJlZHVjaW5nIGNvZGUgc2l6ZS4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRTdHJpbmcoaW5wdXQsIHN0cmluZyoqIHApOworICAvLyBBbmFsb2dvdXMgdG8gUmVhZFN0cmluZygpLgorICBzdGF0aWMgYm9vbCBSZWFkQnl0ZXMoaW5wdXQsIHN0cmluZyogdmFsdWUpOworICBzdGF0aWMgYm9vbCBSZWFkQnl0ZXMoaW5wdXQsIHN0cmluZyoqIHApOworCisKKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRHcm91cCAgKGZpZWxkX251bWJlciwgaW5wdXQsIE1lc3NhZ2VMaXRlKiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBSZWFkTWVzc2FnZShpbnB1dCwgTWVzc2FnZUxpdGUqIHZhbHVlKTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oKS4KKyAgLy8gVGhlIHBvaW50ZXIgbXVzdCBwb2ludCBhdCBhbiBpbnN0YW5jZSBvZiBNZXNzYWdlVHlwZSwgKm5vdCogYSBzdWJjbGFzcyAob3IKKyAgLy8gdGhlIHN1YmNsYXNzIG11c3Qgbm90IG92ZXJyaWRlIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgpKS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGU+CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBSZWFkR3JvdXBOb1ZpcnR1YWwoZmllbGRfbnVtYmVyLCBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlVHlwZSogdmFsdWUpOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRNZXNzYWdlTm9WaXJ0dWFsKGlucHV0LCBNZXNzYWdlVHlwZSogdmFsdWUpOworCisgIC8vIFdyaXRlIGEgdGFnLiAgVGhlIFdyaXRlKigpIGZ1bmN0aW9ucyB0eXBpY2FsbHkgaW5jbHVkZSB0aGUgdGFnLCBzbworICAvLyBub3JtYWxseSB0aGVyZSdzIG5vIG5lZWQgdG8gY2FsbCB0aGlzIHVubGVzcyB1c2luZyB0aGUgV3JpdGUqTm9UYWcoKQorICAvLyB2YXJpYW50cy4KKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV2lyZVR5cGUgdHlwZSwgb3V0cHV0KSBJTkw7CisKKyAgLy8gV3JpdGUgZmllbGRzLCB3aXRob3V0IHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZUludDMyTm9UYWcgICAoaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVJbnQ2NE5vVGFnICAgKGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlVUludDMyTm9UYWcgICh1aW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVVSW50NjROb1RhZyAgKHVpbnQ2NCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZVNJbnQzMk5vVGFnICAoaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVTSW50NjROb1RhZyAgKGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlRml4ZWQzMk5vVGFnICh1aW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVGaXhlZDY0Tm9UYWcgKHVpbnQ2NCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZVNGaXhlZDMyTm9UYWcoaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVTRml4ZWQ2NE5vVGFnKGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlRmxvYXROb1RhZyAgIChmbG9hdCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZURvdWJsZU5vVGFnICAoZG91YmxlIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlQm9vbE5vVGFnICAgIChib29sIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB2b2lkIFdyaXRlRW51bU5vVGFnICAgIChpbnQgdmFsdWUsIG91dHB1dCkgSU5MOworCisgIC8vIFdyaXRlIGZpZWxkcywgaW5jbHVkaW5nIHRhZ3MuCisgIHN0YXRpYyB2b2lkIFdyaXRlSW50MzIgICAoZmllbGRfbnVtYmVyLCAgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlSW50NjQgICAoZmllbGRfbnVtYmVyLCAgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlVUludDMyICAoZmllbGRfbnVtYmVyLCB1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlVUludDY0ICAoZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ludDMyICAoZmllbGRfbnVtYmVyLCAgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ludDY0ICAoZmllbGRfbnVtYmVyLCAgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRml4ZWQzMiAoZmllbGRfbnVtYmVyLCB1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRml4ZWQ2NCAoZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ZpeGVkMzIoZmllbGRfbnVtYmVyLCAgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ZpeGVkNjQoZmllbGRfbnVtYmVyLCAgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRmxvYXQgICAoZmllbGRfbnVtYmVyLCAgZmxvYXQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRG91YmxlICAoZmllbGRfbnVtYmVyLCBkb3VibGUgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlQm9vbCAgICAoZmllbGRfbnVtYmVyLCAgIGJvb2wgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRW51bSAgICAoZmllbGRfbnVtYmVyLCAgICBpbnQgdmFsdWUsIG91dHB1dCk7CisKKyAgc3RhdGljIHZvaWQgV3JpdGVTdHJpbmcoZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworICBzdGF0aWMgdm9pZCBXcml0ZUJ5dGVzIChmaWVsZF9udW1iZXIsIGNvbnN0IHN0cmluZyYgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworICBzdGF0aWMgdm9pZCBXcml0ZUJ5dGVzTWF5YmVBbGlhc2VkKAorICAgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworCisgIHN0YXRpYyB2b2lkIFdyaXRlR3JvdXAoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlTWVzc2FnZSgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwgb3V0cHV0KTsKKyAgLy8gTGlrZSBhYm92ZSwgYnV0IHRoZXNlIHdpbGwgY2hlY2sgaWYgdGhlIG91dHB1dCBzdHJlYW0gaGFzIGVub3VnaAorICAvLyBzcGFjZSB0byB3cml0ZSBkaXJlY3RseSB0byBhIGZsYXQgYXJyYXkuCisgIHN0YXRpYyB2b2lkIFdyaXRlR3JvdXBNYXliZVRvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwgb3V0cHV0KTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKS4gIFRoZQorICAvLyBwb2ludGVyIG11c3QgcG9pbnQgYXQgYW4gaW5zdGFuY2Ugb2YgTWVzc2FnZVR5cGUsICpub3QqIGEgc3ViY2xhc3MgKG9yCisgIC8vIHRoZSBzdWJjbGFzcyBtdXN0IG5vdCBvdmVycmlkZSBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSkuCisgIHRlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlPgorICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVHcm91cE5vVmlydHVhbCgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlJiB2YWx1ZSwgb3V0cHV0KTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGU+CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlVHlwZSYgdmFsdWUsIG91dHB1dCk7CisKKyN1bmRlZiBvdXRwdXQKKyNkZWZpbmUgb3V0cHV0IHVpbnQ4KiB0YXJnZXQKKworICAvLyBMaWtlIGFib3ZlLCBidXQgdXNlIG9ubHkgKlRvQXJyYXkgbWV0aG9kcyBvZiBDb2RlZE91dHB1dFN0cmVhbS4KKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV2lyZVR5cGUgdHlwZSwgb3V0cHV0KSBJTkw7CisKKyAgLy8gV3JpdGUgZmllbGRzLCB3aXRob3V0IHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlSW50MzJOb1RhZ1RvQXJyYXkgICAoaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUludDY0Tm9UYWdUb0FycmF5ICAgKGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVVSW50MzJOb1RhZ1RvQXJyYXkgICh1aW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZVVJbnQ2NE5vVGFnVG9BcnJheSAgKHVpbnQ2NCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlU0ludDMyTm9UYWdUb0FycmF5ICAoaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZVNJbnQ2NE5vVGFnVG9BcnJheSAgKGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVGaXhlZDMyTm9UYWdUb0FycmF5ICh1aW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUZpeGVkNjROb1RhZ1RvQXJyYXkgKHVpbnQ2NCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlU0ZpeGVkMzJOb1RhZ1RvQXJyYXkoaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZVNGaXhlZDY0Tm9UYWdUb0FycmF5KGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVGbG9hdE5vVGFnVG9BcnJheSAgIChmbG9hdCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlRG91YmxlTm9UYWdUb0FycmF5ICAoZG91YmxlIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVCb29sTm9UYWdUb0FycmF5ICAgIChib29sIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVFbnVtTm9UYWdUb0FycmF5ICAgIChpbnQgdmFsdWUsIG91dHB1dCkgSU5MOworCisgIC8vIFdyaXRlIGZpZWxkcywgaW5jbHVkaW5nIHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlSW50MzJUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUludDY0VG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVVSW50MzJUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgdWludDMyIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVVSW50NjRUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgdWludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVTSW50MzJUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgaW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZVNJbnQ2NFRvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBpbnQ2NCB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlRml4ZWQzMlRvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCB1aW50MzIgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUZpeGVkNjRUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgdWludDY0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVTRml4ZWQzMlRvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBpbnQzMiB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHN0YXRpYyBpbmxpbmUgdWludDgqIFdyaXRlU0ZpeGVkNjRUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgaW50NjQgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUZsb2F0VG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGZsb2F0IHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVEb3VibGVUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgZG91YmxlIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVCb29sVG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGJvb2wgdmFsdWUsIG91dHB1dCkgSU5MOworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUVudW1Ub0FycmF5KAorICAgIGZpZWxkX251bWJlciwgaW50IHZhbHVlLCBvdXRwdXQpIElOTDsKKworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVCeXRlc1RvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpIElOTDsKKworICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUdyb3VwVG9BcnJheSgKKyAgICAgIGZpZWxkX251bWJlciwgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLCBvdXRwdXQpIElOTDsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVNZXNzYWdlVG9BcnJheSgKKyAgICAgIGZpZWxkX251bWJlciwgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLCBvdXRwdXQpIElOTDsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKS4gIFRoZQorICAvLyBwb2ludGVyIG11c3QgcG9pbnQgYXQgYW4gaW5zdGFuY2Ugb2YgTWVzc2FnZVR5cGUsICpub3QqIGEgc3ViY2xhc3MgKG9yCisgIC8vIHRoZSBzdWJjbGFzcyBtdXN0IG5vdCBvdmVycmlkZSBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSkuCisgIHRlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlPgorICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZUdyb3VwTm9WaXJ0dWFsVG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlJiB2YWx1ZSwgb3V0cHV0KSBJTkw7CisgIHRlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlPgorICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgY29uc3QgTWVzc2FnZVR5cGUmIHZhbHVlLCBvdXRwdXQpIElOTDsKKworI3VuZGVmIG91dHB1dAorI3VuZGVmIGlucHV0CisjdW5kZWYgSU5MCisKKyN1bmRlZiBmaWVsZF9udW1iZXIKKworICAvLyBDb21wdXRlIHRoZSBieXRlIHNpemUgb2YgYSBmaWVsZC4gIFRoZSBYeFNpemUoKSBmdW5jdGlvbnMgZG8gTk9UIGluY2x1ZGUKKyAgLy8gdGhlIHRhZywgc28geW91IG11c3QgYWxzbyBjYWxsIFRhZ1NpemUoKS4gIChUaGlzIGlzIGJlY2F1c2UsIGZvciByZXBlYXRlZAorICAvLyBmaWVsZHMsIHlvdSBzaG91bGQgb25seSBjYWxsIFRhZ1NpemUoKSBvbmNlIGFuZCBtdWx0aXBseSBpdCBieSB0aGUgZWxlbWVudAorICAvLyBjb3VudCwgYnV0IHlvdSBtYXkgaGF2ZSB0byBjYWxsIFh4U2l6ZSgpIGZvciBlYWNoIGluZGl2aWR1YWwgZWxlbWVudC4pCisgIHN0YXRpYyBpbmxpbmUgaW50IEludDMyU2l6ZSAgICggaW50MzIgdmFsdWUpOworICBzdGF0aWMgaW5saW5lIGludCBJbnQ2NFNpemUgICAoIGludDY0IHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgVUludDMyU2l6ZSAgKHVpbnQzMiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgaW50IFVJbnQ2NFNpemUgICh1aW50NjQgdmFsdWUpOworICBzdGF0aWMgaW5saW5lIGludCBTSW50MzJTaXplICAoIGludDMyIHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgU0ludDY0U2l6ZSAgKCBpbnQ2NCB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgaW50IEVudW1TaXplICAgICggICBpbnQgdmFsdWUpOworCisgIC8vIFRoZXNlIHR5cGVzIGFsd2F5cyBoYXZlIHRoZSBzYW1lIHNpemUuCisgIHN0YXRpYyBjb25zdCBpbnQga0ZpeGVkMzJTaXplICA9IDQ7CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpeGVkNjRTaXplICA9IDg7CisgIHN0YXRpYyBjb25zdCBpbnQga1NGaXhlZDMyU2l6ZSA9IDQ7CisgIHN0YXRpYyBjb25zdCBpbnQga1NGaXhlZDY0U2l6ZSA9IDg7CisgIHN0YXRpYyBjb25zdCBpbnQga0Zsb2F0U2l6ZSAgICA9IDQ7CisgIHN0YXRpYyBjb25zdCBpbnQga0RvdWJsZVNpemUgICA9IDg7CisgIHN0YXRpYyBjb25zdCBpbnQga0Jvb2xTaXplICAgICA9IDE7CisKKyAgc3RhdGljIGlubGluZSBpbnQgU3RyaW5nU2l6ZShjb25zdCBzdHJpbmcmIHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgQnl0ZXNTaXplIChjb25zdCBzdHJpbmcmIHZhbHVlKTsKKworICBzdGF0aWMgaW5saW5lIGludCBHcm91cFNpemUgIChjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUpOworICBzdGF0aWMgaW5saW5lIGludCBNZXNzYWdlU2l6ZShjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUpOworCisgIC8vIExpa2UgYWJvdmUsIGJ1dCBkZS12aXJ0dWFsaXplIHRoZSBjYWxsIHRvIEJ5dGVTaXplKCkuICBUaGUKKyAgLy8gcG9pbnRlciBtdXN0IHBvaW50IGF0IGFuIGluc3RhbmNlIG9mIE1lc3NhZ2VUeXBlLCAqbm90KiBhIHN1YmNsYXNzIChvcgorICAvLyB0aGUgc3ViY2xhc3MgbXVzdCBub3Qgb3ZlcnJpZGUgQnl0ZVNpemUoKSkuCisgIHRlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlPgorICBzdGF0aWMgaW5saW5lIGludCBHcm91cFNpemVOb1ZpcnR1YWwgIChjb25zdCBNZXNzYWdlVHlwZSYgdmFsdWUpOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZT4KKyAgc3RhdGljIGlubGluZSBpbnQgTWVzc2FnZVNpemVOb1ZpcnR1YWwoY29uc3QgTWVzc2FnZVR5cGUmIHZhbHVlKTsKKworICAvLyBHaXZlbiB0aGUgbGVuZ3RoIG9mIGRhdGEsIGNhbGN1bGF0ZSB0aGUgYnl0ZSBzaXplIG9mIHRoZSBkYXRhIG9uIHRoZQorICAvLyB3aXJlIGlmIHdlIGVuY29kZSB0aGUgZGF0YSBhcyBhIGxlbmd0aCBkZWxpbWl0ZWQgZmllbGQuCisgIHN0YXRpYyBpbmxpbmUgaW50IExlbmd0aERlbGltaXRlZFNpemUoaW50IGxlbmd0aCk7CisKKyBwcml2YXRlOgorICAvLyBBIGhlbHBlciBtZXRob2QgZm9yIHRoZSByZXBlYXRlZCBwcmltaXRpdmUgcmVhZGVyLiBUaGlzIG1ldGhvZCBoYXMKKyAgLy8gb3B0aW1pemF0aW9ucyBmb3IgcHJpbWl0aXZlIHR5cGVzIHRoYXQgaGF2ZSBmaXhlZCBzaXplIG9uIHRoZSB3aXJlLCBhbmQKKyAgLy8gY2FuIGJlIHJlYWQgdXNpbmcgcG90ZW50aWFsbHkgZmFzdGVyIHBhdGhzLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRSZXBlYXRlZEZpeGVkU2l6ZVByaW1pdGl2ZSgKKyAgICAgIGludCB0YWdfc2l6ZSwKKyAgICAgIHVpbnQzMiB0YWcsCisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWUpIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORTsKKworICAvLyBMaWtlIFJlYWRSZXBlYXRlZEZpeGVkU2l6ZVByaW1pdGl2ZSBidXQgZm9yIHBhY2tlZCBwcmltaXRpdmUgZmllbGRzLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRQYWNrZWRGaXhlZFNpemVQcmltaXRpdmUoCisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWUpIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORTsKKworICBzdGF0aWMgY29uc3QgQ3BwVHlwZSBrRmllbGRUeXBlVG9DcHBUeXBlTWFwW107CisgIHN0YXRpYyBjb25zdCBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUga1dpcmVUeXBlRm9yRmllbGRUeXBlW107CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFdpcmVGb3JtYXRMaXRlKTsKK307CisKKy8vIEEgY2xhc3Mgd2hpY2ggZGVhbHMgd2l0aCB1bmtub3duIHZhbHVlcy4gIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGp1c3QKKy8vIGRpc2NhcmRzIHRoZW0uICBXaXJlRm9ybWF0IGRlZmluZXMgYSBzdWJjbGFzcyB3aGljaCB3cml0ZXMgdG8gYW4KKy8vIFVua25vd25GaWVsZFNldC4gIFRoaXMgY2xhc3MgaXMgdXNlZCBieSBFeHRlbnNpb25TZXQ6OlBhcnNlRmllbGQoKSwgc2luY2UKKy8vIEV4dGVuc2lvblNldCBpcyBwYXJ0IG9mIHRoZSBsaXRlIGxpYnJhcnkgYnV0IFVua25vd25GaWVsZFNldCBpcyBub3QuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmllbGRTa2lwcGVyIHsKKyBwdWJsaWM6CisgIEZpZWxkU2tpcHBlcigpIHt9CisgIHZpcnR1YWwgfkZpZWxkU2tpcHBlcigpIHt9CisKKyAgLy8gU2tpcCBhIGZpZWxkIHdob3NlIHRhZyBoYXMgYWxyZWFkeSBiZWVuIGNvbnN1bWVkLgorICB2aXJ0dWFsIGJvb2wgU2tpcEZpZWxkKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgdWludDMyIHRhZyk7CisKKyAgLy8gU2tpcCBhbiBlbnRpcmUgbWVzc2FnZSBvciBncm91cCwgdXAgdG8gYW4gZW5kLWdyb3VwIHRhZyAod2hpY2ggaXMgY29uc3VtZWQpCisgIC8vIG9yIGVuZC1vZi1zdHJlYW0uCisgIHZpcnR1YWwgYm9vbCBTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworCisgIC8vIERlYWwgd2l0aCBhbiBhbHJlYWR5LXBhcnNlZCB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4gIFRoZSBkZWZhdWx0CisgIC8vIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZywgYnV0IHRoZSBVbmtub3duRmllbGRTZXQtYmFzZWQgaW1wbGVtZW50YXRpb24KKyAgLy8gc2F2ZXMgaXQgYXMgYW4gdW5rbm93biB2YXJpbnQuCisgIHZpcnR1YWwgdm9pZCBTa2lwVW5rbm93bkVudW0oaW50IGZpZWxkX251bWJlciwgaW50IHZhbHVlKTsKK307CisKKy8vIFN1YmNsYXNzIG9mIEZpZWxkU2tpcHBlciB3aGljaCBzYXZlcyBza2lwcGVkIGZpZWxkcyB0byBhIENvZGVkT3V0cHV0U3RyZWFtLgorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29kZWRPdXRwdXRTdHJlYW1GaWVsZFNraXBwZXIgOiBwdWJsaWMgRmllbGRTa2lwcGVyIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IENvZGVkT3V0cHV0U3RyZWFtRmllbGRTa2lwcGVyKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogdW5rbm93bl9maWVsZHMpCisgICAgICA6IHVua25vd25fZmllbGRzXyh1bmtub3duX2ZpZWxkcykge30KKyAgdmlydHVhbCB+Q29kZWRPdXRwdXRTdHJlYW1GaWVsZFNraXBwZXIoKSB7fQorCisgIC8vIGltcGxlbWVudHMgRmllbGRTa2lwcGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZpcnR1YWwgYm9vbCBTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnKTsKKyAgdmlydHVhbCBib29sIFNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZpcnR1YWwgdm9pZCBTa2lwVW5rbm93bkVudW0oaW50IGZpZWxkX251bWJlciwgaW50IHZhbHVlKTsKKworIHByb3RlY3RlZDoKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiB1bmtub3duX2ZpZWxkc187Cit9OworCisKKy8vIGlubGluZSBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworaW5saW5lIFdpcmVGb3JtYXRMaXRlOjpDcHBUeXBlCitXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlVG9DcHBUeXBlKEZpZWxkVHlwZSB0eXBlKSB7CisgIHJldHVybiBrRmllbGRUeXBlVG9DcHBUeXBlTWFwW3R5cGVdOworfQorCitpbmxpbmUgdWludDMyIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGludCBmaWVsZF9udW1iZXIsIFdpcmVUeXBlIHR5cGUpIHsKKyAgcmV0dXJuIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9NQUtFX1RBRyhmaWVsZF9udW1iZXIsIHR5cGUpOworfQorCitpbmxpbmUgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh1aW50MzIgdGFnKSB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxXaXJlVHlwZT4odGFnICYga1RhZ1R5cGVNYXNrKTsKK30KKworaW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodWludDMyIHRhZykgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0YWcgPj4ga1RhZ1R5cGVCaXRzKTsKK30KKworaW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6VGFnU2l6ZShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHR5cGUpIHsKKyAgaW50IHJlc3VsdCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgIGZpZWxkX251bWJlciA8PCBrVGFnVHlwZUJpdHMpOworICBpZiAodHlwZSA9PSBUWVBFX0dST1VQKSB7CisgICAgLy8gR3JvdXBzIGhhdmUgYm90aCBhIHN0YXJ0IGFuZCBhbiBlbmQgdGFnLgorICAgIHJldHVybiByZXN1bHQgKiAyOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworaW5saW5lIHVpbnQzMiBXaXJlRm9ybWF0TGl0ZTo6RW5jb2RlRmxvYXQoZmxvYXQgdmFsdWUpIHsKKyAgdW5pb24ge2Zsb2F0IGY7IHVpbnQzMiBpO307CisgIGYgPSB2YWx1ZTsKKyAgcmV0dXJuIGk7Cit9CisKK2lubGluZSBmbG9hdCBXaXJlRm9ybWF0TGl0ZTo6RGVjb2RlRmxvYXQodWludDMyIHZhbHVlKSB7CisgIHVuaW9uIHtmbG9hdCBmOyB1aW50MzIgaTt9OworICBpID0gdmFsdWU7CisgIHJldHVybiBmOworfQorCitpbmxpbmUgdWludDY0IFdpcmVGb3JtYXRMaXRlOjpFbmNvZGVEb3VibGUoZG91YmxlIHZhbHVlKSB7CisgIHVuaW9uIHtkb3VibGUgZjsgdWludDY0IGk7fTsKKyAgZiA9IHZhbHVlOworICByZXR1cm4gaTsKK30KKworaW5saW5lIGRvdWJsZSBXaXJlRm9ybWF0TGl0ZTo6RGVjb2RlRG91YmxlKHVpbnQ2NCB2YWx1ZSkgeworICB1bmlvbiB7ZG91YmxlIGY7IHVpbnQ2NCBpO307CisgIGkgPSB2YWx1ZTsKKyAgcmV0dXJuIGY7Cit9CisKKy8vIFppZ1phZyBUcmFuc2Zvcm06ICBFbmNvZGVzIHNpZ25lZCBpbnRlZ2VycyBzbyB0aGF0IHRoZXkgY2FuIGJlCisvLyBlZmZlY3RpdmVseSB1c2VkIHdpdGggdmFyaW50IGVuY29kaW5nLgorLy8KKy8vIHZhcmludCBvcGVyYXRlcyBvbiB1bnNpZ25lZCBpbnRlZ2VycywgZW5jb2Rpbmcgc21hbGxlciBudW1iZXJzIGludG8KKy8vIGZld2VyIGJ5dGVzLiAgSWYgeW91IHRyeSB0byB1c2UgaXQgb24gYSBzaWduZWQgaW50ZWdlciwgaXQgd2lsbCB0cmVhdAorLy8gdGhpcyBudW1iZXIgYXMgYSB2ZXJ5IGxhcmdlIHVuc2lnbmVkIGludGVnZXIsIHdoaWNoIG1lYW5zIHRoYXQgZXZlbgorLy8gc21hbGwgc2lnbmVkIG51bWJlcnMgbGlrZSAtMSB3aWxsIHRha2UgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzCisvLyAoMTApIHRvIGVuY29kZS4gIFppZ1phZ0VuY29kZSgpIG1hcHMgc2lnbmVkIGludGVnZXJzIHRvIHVuc2lnbmVkCisvLyBpbiBzdWNoIGEgd2F5IHRoYXQgdGhvc2Ugd2l0aCBhIHNtYWxsIGFic29sdXRlIHZhbHVlIHdpbGwgaGF2ZSBzbWFsbGVyCisvLyBlbmNvZGVkIHZhbHVlcywgbWFraW5nIHRoZW0gYXBwcm9wcmlhdGUgZm9yIGVuY29kaW5nIHVzaW5nIHZhcmludC4KKy8vCisvLyAgICAgICBpbnQzMiAtPiAgICAgdWludDMyCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyAgICAgICAgICAgMCAtPiAgICAgICAgICAwCisvLyAgICAgICAgICAtMSAtPiAgICAgICAgICAxCisvLyAgICAgICAgICAgMSAtPiAgICAgICAgICAyCisvLyAgICAgICAgICAtMiAtPiAgICAgICAgICAzCisvLyAgICAgICAgIC4uLiAtPiAgICAgICAgLi4uCisvLyAgMjE0NzQ4MzY0NyAtPiA0Mjk0OTY3Mjk0CisvLyAtMjE0NzQ4MzY0OCAtPiA0Mjk0OTY3Mjk1CisvLworLy8gICAgICAgID4+IGVuY29kZSA+PgorLy8gICAgICAgIDw8IGRlY29kZSA8PAorCitpbmxpbmUgdWludDMyIFdpcmVGb3JtYXRMaXRlOjpaaWdaYWdFbmNvZGUzMihpbnQzMiBuKSB7CisgIC8vIE5vdGU6ICB0aGUgcmlnaHQtc2hpZnQgbXVzdCBiZSBhcml0aG1ldGljCisgIHJldHVybiAoc3RhdGljX2Nhc3Q8dWludDMyPihuKSA8PCAxKSBeIChuID4+IDMxKTsKK30KKworaW5saW5lIGludDMyIFdpcmVGb3JtYXRMaXRlOjpaaWdaYWdEZWNvZGUzMih1aW50MzIgbikgeworICByZXR1cm4gKG4gPj4gMSkgXiAtc3RhdGljX2Nhc3Q8aW50MzI+KG4gJiAxKTsKK30KKworaW5saW5lIHVpbnQ2NCBXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRW5jb2RlNjQoaW50NjQgbikgeworICAvLyBOb3RlOiAgdGhlIHJpZ2h0LXNoaWZ0IG11c3QgYmUgYXJpdGhtZXRpYworICByZXR1cm4gKHN0YXRpY19jYXN0PHVpbnQ2ND4obikgPDwgMSkgXiAobiA+PiA2Myk7Cit9CisKK2lubGluZSBpbnQ2NCBXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRGVjb2RlNjQodWludDY0IG4pIHsKKyAgcmV0dXJuIChuID4+IDEpIF4gLXN0YXRpY19jYXN0PGludDY0PihuICYgMSk7Cit9CisKKy8vIFN0cmluZyBpcyBmb3IgVVRGLTggdGV4dCBvbmx5LCBidXQsIGV2ZW4gc28sIFJlYWRTdHJpbmcoKSBjYW4gc2ltcGx5CisvLyBjYWxsIFJlYWRCeXRlcygpLgorCitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZyhpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHZhbHVlKSB7CisgIHJldHVybiBSZWFkQnl0ZXMoaW5wdXQsIHZhbHVlKTsKK30KKworaW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiogcCkgeworICByZXR1cm4gUmVhZEJ5dGVzKGlucHV0LCBwKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjlmYzYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oCkBAIC0wLDAgKzEsODU2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gICAgICAgICB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSkgKHJlZmFjdG9yZWQgZnJvbSB3aXJlX2Zvcm1hdC5oKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0xJVEVfSU5MX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTElURV9JTkxfSF9fCisKKyNpZmRlZiBfTVNDX1ZFUgorLy8gVGhpcyBpcyByZXF1aXJlZCBmb3IgbWluL21heCBvbiBWUzIwMTMgb25seS4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjZW5kaWYKKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgUmVhZFByaW1pdGl2ZS4KKwordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGludDMyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGludDMyKiB2YWx1ZSkgeworICB1aW50MzIgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxpbnQzMj4odGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGludDY0LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQ2ND4oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGludDY0KiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxpbnQ2ND4odGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPHVpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfVUlOVDMyPigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgdWludDMyKiB2YWx1ZSkgeworICByZXR1cm4gaW5wdXQtPlJlYWRWYXJpbnQzMih2YWx1ZSk7Cit9Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8dWludDY0LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9VSU5UNjQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICB1aW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBpbnB1dC0+UmVhZFZhcmludDY0KHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0lOVDMyPigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgaW50MzIqIHZhbHVlKSB7CisgIHVpbnQzMiB0ZW1wOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJnRlbXApKSByZXR1cm4gZmFsc2U7CisgICp2YWx1ZSA9IFppZ1phZ0RlY29kZTMyKHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQ2NCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0lOVDY0PigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgaW50NjQqIHZhbHVlKSB7CisgIHVpbnQ2NCB0ZW1wOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50NjQoJnRlbXApKSByZXR1cm4gZmFsc2U7CisgICp2YWx1ZSA9IFppZ1phZ0RlY29kZTY0KHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTx1aW50MzIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVEMzI+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICB1aW50MzIqIHZhbHVlKSB7CisgIHJldHVybiBpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTx1aW50NjQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVENjQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICB1aW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0ZJWEVEMzI+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBpbnQzMiogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW4zMigmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50MzI+KHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQ2NCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0ZJWEVENjQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBpbnQ2NCogdmFsdWUpIHsKKyAgdWludDY0IHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW42NCgmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50NjQ+KHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxmbG9hdCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRkxPQVQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBmbG9hdCogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW4zMigmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gRGVjb2RlRmxvYXQodGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGRvdWJsZSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRE9VQkxFPigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgZG91YmxlKiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBEZWNvZGVEb3VibGUodGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGJvb2wsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBib29sKiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSB0ZW1wICE9IDA7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGludCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGludCogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50Pih0ZW1wKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlRnJvbUFycmF5PAorICB1aW50MzIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVEMzI+KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgdWludDMyKiB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW4zMkZyb21BcnJheShidWZmZXIsIHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlRnJvbUFycmF5PAorICB1aW50NjQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVENjQ+KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgdWludDY0KiB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheShidWZmZXIsIHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlRnJvbUFycmF5PAorICBpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0ZJWEVEMzI+KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgaW50MzIqIHZhbHVlKSB7CisgIHVpbnQzMiB0ZW1wOworICBidWZmZXIgPSBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6UmVhZExpdHRsZUVuZGlhbjMyRnJvbUFycmF5KGJ1ZmZlciwgJnRlbXApOworICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxpbnQzMj4odGVtcCk7CisgIHJldHVybiBidWZmZXI7Cit9Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZUZyb21BcnJheTwKKyAgaW50NjQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX1NGSVhFRDY0PigKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgIGludDY0KiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgYnVmZmVyID0gaW86OkNvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheShidWZmZXIsICZ0ZW1wKTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50NjQ+KHRlbXApOworICByZXR1cm4gYnVmZmVyOworfQordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCB1aW50OCogV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmVGcm9tQXJyYXk8CisgIGZsb2F0LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9GTE9BVD4oCisgICAgY29uc3QgdWludDgqIGJ1ZmZlciwKKyAgICBmbG9hdCogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGJ1ZmZlciA9IGlvOjpDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuMzJGcm9tQXJyYXkoYnVmZmVyLCAmdGVtcCk7CisgICp2YWx1ZSA9IERlY29kZUZsb2F0KHRlbXApOworICByZXR1cm4gYnVmZmVyOworfQordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCB1aW50OCogV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmVGcm9tQXJyYXk8CisgIGRvdWJsZSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRE9VQkxFPigKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgIGRvdWJsZSogdmFsdWUpIHsKKyAgdWludDY0IHRlbXA7CisgIGJ1ZmZlciA9IGlvOjpDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXkoYnVmZmVyLCAmdGVtcCk7CisgICp2YWx1ZSA9IERlY29kZURvdWJsZSh0ZW1wKTsKKyAgcmV0dXJuIGJ1ZmZlcjsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIENUeXBlLCBlbnVtIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgRGVjbGFyZWRUeXBlPgoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRSZXBlYXRlZFByaW1pdGl2ZSgKKyAgICBpbnQsICAvLyB0YWdfc2l6ZSwgdW51c2VkLgorICAgIHVpbnQzMiB0YWcsCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZXMpIHsKKyAgQ1R5cGUgdmFsdWU7CisgIGlmICghUmVhZFByaW1pdGl2ZTxDVHlwZSwgRGVjbGFyZWRUeXBlPihpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisgIGludCBlbGVtZW50c19hbHJlYWR5X3Jlc2VydmVkID0gdmFsdWVzLT5DYXBhY2l0eSgpIC0gdmFsdWVzLT5zaXplKCk7CisgIHdoaWxlIChlbGVtZW50c19hbHJlYWR5X3Jlc2VydmVkID4gMCAmJiBpbnB1dC0+RXhwZWN0VGFnKHRhZykpIHsKKyAgICBpZiAoIVJlYWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICB2YWx1ZXMtPkFkZEFscmVhZHlSZXNlcnZlZCh2YWx1ZSk7CisgICAgZWxlbWVudHNfYWxyZWFkeV9yZXNlcnZlZC0tOworICB9CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFJlcGVhdGVkRml4ZWRTaXplUHJpbWl0aXZlKAorICAgIGludCB0YWdfc2l6ZSwKKyAgICB1aW50MzIgdGFnLAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWVzKSB7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoVUludDMyU2l6ZSh0YWcpLCB0YWdfc2l6ZSk7CisgIENUeXBlIHZhbHVlOworICBpZiAoIVJlYWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oaW5wdXQsICZ2YWx1ZSkpCisgICAgcmV0dXJuIGZhbHNlOworICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisKKyAgLy8gRm9yIGZpeGVkIHNpemUgdmFsdWVzLCByZXBlYXRlZCB2YWx1ZXMgY2FuIGJlIHJlYWQgbW9yZSBxdWlja2x5IGJ5CisgIC8vIHJlYWRpbmcgZGlyZWN0bHkgZnJvbSBhIHJhdyBhcnJheS4KKyAgLy8KKyAgLy8gV2UgY2FuIGdldCBhIHRpZ2h0IGxvb3AgYnkgb25seSByZWFkaW5nIGFzIG1hbnkgZWxlbWVudHMgYXMgY2FuIGJlCisgIC8vIGFkZGVkIHRvIHRoZSBSZXBlYXRlZEZpZWxkIHdpdGhvdXQgaGF2aW5nIHRvIGRvIGFueSByZXNpemluZy4gQWRkaXRpb25hbGx5LAorICAvLyB3ZSBvbmx5IHRyeSB0byByZWFkIGFzIG1hbnkgZWxlbWVudHMgYXMgYXJlIGF2YWlsYWJsZSBmcm9tIHRoZSBjdXJyZW50CisgIC8vIGJ1ZmZlciBzcGFjZS4gRG9pbmcgc28gYXZvaWRzIGhhdmluZyB0byBwZXJmb3JtIGJvdW5kYXJ5IGNoZWNrcyB3aGVuCisgIC8vIHJlYWRpbmcgdGhlIHZhbHVlOiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZWxlbWVudHMgdGhhdCBjYW4gYmUgcmVhZCBpcworICAvLyBrbm93biBvdXRzaWRlIG9mIHRoZSBsb29wLgorICBjb25zdCB2b2lkKiB2b2lkX3BvaW50ZXI7CisgIGludCBzaXplOworICBpbnB1dC0+R2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZSgmdm9pZF9wb2ludGVyLCAmc2l6ZSk7CisgIGlmIChzaXplID4gMCkgeworICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4odm9pZF9wb2ludGVyKTsKKyAgICAvLyBUaGUgbnVtYmVyIG9mIGJ5dGVzIGVhY2ggdHlwZSBvY2N1cGllcyBvbiB0aGUgd2lyZS4KKyAgICBjb25zdCBpbnQgcGVyX3ZhbHVlX3NpemUgPSB0YWdfc2l6ZSArIHNpemVvZih2YWx1ZSk7CisKKyAgICBpbnQgZWxlbWVudHNfYXZhaWxhYmxlID0gbWluKHZhbHVlcy0+Q2FwYWNpdHkoKSAtIHZhbHVlcy0+c2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSAvIHBlcl92YWx1ZV9zaXplKTsKKyAgICBpbnQgbnVtX3JlYWQgPSAwOworICAgIHdoaWxlIChudW1fcmVhZCA8IGVsZW1lbnRzX2F2YWlsYWJsZSAmJgorICAgICAgICAgICAoYnVmZmVyID0gaW86OkNvZGVkSW5wdXRTdHJlYW06OkV4cGVjdFRhZ0Zyb21BcnJheSgKKyAgICAgICAgICAgICAgIGJ1ZmZlciwgdGFnKSkgIT0gTlVMTCkgeworICAgICAgYnVmZmVyID0gUmVhZFByaW1pdGl2ZUZyb21BcnJheTxDVHlwZSwgRGVjbGFyZWRUeXBlPihidWZmZXIsICZ2YWx1ZSk7CisgICAgICB2YWx1ZXMtPkFkZEFscmVhZHlSZXNlcnZlZCh2YWx1ZSk7CisgICAgICArK251bV9yZWFkOworICAgIH0KKyAgICBjb25zdCBpbnQgcmVhZF9ieXRlcyA9IG51bV9yZWFkICogcGVyX3ZhbHVlX3NpemU7CisgICAgaWYgKHJlYWRfYnl0ZXMgPiAwKSB7CisgICAgICBpbnB1dC0+U2tpcChyZWFkX2J5dGVzKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIFNwZWNpYWxpemF0aW9ucyBvZiBSZWFkUmVwZWF0ZWRQcmltaXRpdmUgZm9yIHRoZSBmaXhlZCBzaXplIHR5cGVzLCB3aGljaCB1c2UKKy8vIHRoZSBvcHRpbWl6ZWQgY29kZSBwYXRoLgorI2RlZmluZSBSRUFEX1JFUEVBVEVEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKENQUFRZUEUsIERFQ0xBUkVEX1RZUEUpICAgICAgICAgICAgIFwKK3RlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFJlcGVhdGVkUHJpbWl0aXZlPCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBDUFBUWVBFLCBXaXJlRm9ybWF0TGl0ZTo6REVDTEFSRURfVFlQRT4oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpbnQgdGFnX3NpemUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdWludDMyIHRhZywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBSZXBlYXRlZEZpZWxkPENQUFRZUEU+KiB2YWx1ZXMpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJldHVybiBSZWFkUmVwZWF0ZWRGaXhlZFNpemVQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIENQUFRZUEUsIFdpcmVGb3JtYXRMaXRlOjpERUNMQVJFRF9UWVBFPiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHRhZ19zaXplLCB0YWcsIGlucHV0LCB2YWx1ZXMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9CisKK1JFQURfUkVQRUFURURfRklYRURfU0laRV9QUklNSVRJVkUodWludDMyLCBUWVBFX0ZJWEVEMzIpCitSRUFEX1JFUEVBVEVEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKHVpbnQ2NCwgVFlQRV9GSVhFRDY0KQorUkVBRF9SRVBFQVRFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShpbnQzMiwgVFlQRV9TRklYRUQzMikKK1JFQURfUkVQRUFURURfRklYRURfU0laRV9QUklNSVRJVkUoaW50NjQsIFRZUEVfU0ZJWEVENjQpCitSRUFEX1JFUEVBVEVEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKGZsb2F0LCBUWVBFX0ZMT0FUKQorUkVBRF9SRVBFQVRFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShkb3VibGUsIFRZUEVfRE9VQkxFKQorCisjdW5kZWYgUkVBRF9SRVBFQVRFRF9GSVhFRF9TSVpFX1BSSU1JVElWRQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+Citib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUmVwZWF0ZWRQcmltaXRpdmVOb0lubGluZSgKKyAgICBpbnQgdGFnX3NpemUsCisgICAgdWludDMyIHRhZywKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlKSB7CisgIHJldHVybiBSZWFkUmVwZWF0ZWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oCisgICAgICB0YWdfc2l6ZSwgdGFnLCBpbnB1dCwgdmFsdWUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZFByaW1pdGl2ZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWVzKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBpbnB1dC0+UHVzaExpbWl0KGxlbmd0aCk7CisgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgQ1R5cGUgdmFsdWU7CisgICAgaWYgKCFSZWFkUHJpbWl0aXZlPENUeXBlLCBEZWNsYXJlZFR5cGU+KGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgdmFsdWVzLT5BZGQodmFsdWUpOworICB9CisgIGlucHV0LT5Qb3BMaW1pdChsaW1pdCk7CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZEZpeGVkU2l6ZVByaW1pdGl2ZSgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZXMpIHsKKyAgdWludDMyIGxlbmd0aDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgIGNvbnN0IHVpbnQzMiBvbGRfZW50cmllcyA9IHZhbHVlcy0+c2l6ZSgpOworICBjb25zdCB1aW50MzIgbmV3X2VudHJpZXMgPSBsZW5ndGggLyBzaXplb2YoQ1R5cGUpOworICBjb25zdCB1aW50MzIgbmV3X2J5dGVzID0gbmV3X2VudHJpZXMgKiBzaXplb2YoQ1R5cGUpOworICBpZiAobmV3X2J5dGVzICE9IGxlbmd0aCkgcmV0dXJuIGZhbHNlOworICAvLyBXZSB3b3VsZCAqbGlrZSogdG8gcHJlLWFsbG9jYXRlIHRoZSBidWZmZXIgdG8gd3JpdGUgaW50byAoZm9yCisgIC8vIHNwZWVkKSwgYnV0ICptdXN0KiBhdm9pZCBwZXJmb3JtaW5nIGEgdmVyeSBsYXJnZSBhbGxvY2F0aW9uIGR1ZQorICAvLyB0byBhIG1hbGljaW91cyB1c2VyLXN1cHBsaWVkICJsZW5ndGgiIGFib3ZlLiAgU28gd2UgaGF2ZSBhIGZhc3QKKyAgLy8gcGF0aCB0aGF0IHByZS1hbGxvY2F0ZXMgd2hlbiB0aGUgImxlbmd0aCIgaXMgbGVzcyB0aGFuIGEgYm91bmQuCisgIC8vIFdlIGRldGVybWluZSB0aGUgYm91bmQgYnkgY2FsbGluZyBCeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCkgYW5kCisgIC8vIEJ5dGVzVW50aWxMaW1pdCgpLiAgVGhlc2UgcmV0dXJuIC0xIHRvIG1lYW4gIm5vIGxpbWl0IHNldCIuCisgIC8vIFRoZXJlIGFyZSBmb3VyIGNhc2VzOgorICAvLyBUb3RhbEJ5dGVzTGltaXQgIExpbWl0CisgIC8vIC0xICAgICAgICAgICAgICAgLTEgICAgIFVzZSBzbG93IHBhdGguCisgIC8vIC0xICAgICAgICAgICAgICAgPj0gMCAgIFVzZSBmYXN0IHBhdGggaWYgbGVuZ3RoIDw9IExpbWl0LgorICAvLyA+PSAwICAgICAgICAgICAgIC0xICAgICBVc2Ugc2xvdyBwYXRoLgorICAvLyA+PSAwICAgICAgICAgICAgID49IDAgICBVc2UgZmFzdCBwYXRoIGlmIGxlbmd0aCA8PSBtaW4oYm90aCBsaW1pdHMpLgorICBpbnQ2NCBieXRlc19saW1pdCA9IGlucHV0LT5CeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCk7CisgIGlmIChieXRlc19saW1pdCA9PSAtMSkgeworICAgIGJ5dGVzX2xpbWl0ID0gaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpOworICB9IGVsc2UgeworICAgIGJ5dGVzX2xpbWl0ID0KKyAgICAgICAgbWluKGJ5dGVzX2xpbWl0LCBzdGF0aWNfY2FzdDxpbnQ2ND4oaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpKSk7CisgIH0KKyAgaWYgKGJ5dGVzX2xpbWl0ID49IG5ld19ieXRlcykgeworICAgIC8vIEZhc3QtcGF0aCB0aGF0IHByZS1hbGxvY2F0ZXMgKnZhbHVlcyB0byB0aGUgZmluYWwgc2l6ZS4KKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgICAgdmFsdWVzLT5SZXNpemUob2xkX2VudHJpZXMgKyBuZXdfZW50cmllcywgMCk7CisgICAgLy8gdmFsdWVzLT5tdXRhYmxlX2RhdGEoKSBtYXkgY2hhbmdlIGFmdGVyIFJlc2l6ZSgpLCBzbyBkbyB0aGlzIGFmdGVyOgorICAgIHZvaWQqIGRlc3QgPSByZWludGVycHJldF9jYXN0PHZvaWQqPih2YWx1ZXMtPm11dGFibGVfZGF0YSgpICsgb2xkX2VudHJpZXMpOworICAgIGlmICghaW5wdXQtPlJlYWRSYXcoZGVzdCwgbmV3X2J5dGVzKSkgeworICAgICAgdmFsdWVzLT5UcnVuY2F0ZShvbGRfZW50cmllcyk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorI2Vsc2UKKyAgICB2YWx1ZXMtPlJlc2VydmUob2xkX2VudHJpZXMgKyBuZXdfZW50cmllcyk7CisgICAgQ1R5cGUgdmFsdWU7CisgICAgZm9yICh1aW50MzIgaSA9IDA7IGkgPCBuZXdfZW50cmllczsgKytpKSB7CisgICAgICBpZiAoIVJlYWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIHZhbHVlcy0+QWRkQWxyZWFkeVJlc2VydmVkKHZhbHVlKTsKKyAgICB9CisjZW5kaWYKKyAgfSBlbHNlIHsKKyAgICAvLyBUaGlzIGlzIHRoZSBzbG93LXBhdGggY2FzZSB3aGVyZSAibGVuZ3RoIiBtYXkgYmUgdG9vIGxhcmdlIHRvCisgICAgLy8gc2FmZWx5IGFsbG9jYXRlLiAgV2UgcmVhZCBhcyBtdWNoIGFzIHdlIGNhbiBpbnRvICp2YWx1ZXMKKyAgICAvLyB3aXRob3V0IHByZS1hbGxvY2F0aW5nICJsZW5ndGgiIGJ5dGVzLgorICAgIENUeXBlIHZhbHVlOworICAgIGZvciAodWludDMyIGkgPSAwOyBpIDwgbmV3X2VudHJpZXM7ICsraSkgeworICAgICAgaWYgKCFSZWFkUHJpbWl0aXZlPENUeXBlLCBEZWNsYXJlZFR5cGU+KGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBTcGVjaWFsaXphdGlvbnMgb2YgUmVhZFBhY2tlZFByaW1pdGl2ZSBmb3IgdGhlIGZpeGVkIHNpemUgdHlwZXMsIHdoaWNoIHVzZQorLy8gYW4gb3B0aW1pemVkIGNvZGUgcGF0aC4KKyNkZWZpbmUgUkVBRF9SRVBFQVRFRF9QQUNLRURfRklYRURfU0laRV9QUklNSVRJVkUoQ1BQVFlQRSwgREVDTEFSRURfVFlQRSkgICAgICBcCit0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgQ1BQVFlQRSwgV2lyZUZvcm1hdExpdGU6OkRFQ0xBUkVEX1RZUEU+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkRmllbGQ8Q1BQVFlQRT4qIHZhbHVlcykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcmV0dXJuIFJlYWRQYWNrZWRGaXhlZFNpemVQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBDUFBUWVBFLCBXaXJlRm9ybWF0TGl0ZTo6REVDTEFSRURfVFlQRT4oaW5wdXQsIHZhbHVlcyk7ICAgICAgICAgICAgICAgICAgXAorfQorCitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRSh1aW50MzIsIFRZUEVfRklYRUQzMik7CitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRSh1aW50NjQsIFRZUEVfRklYRUQ2NCk7CitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShpbnQzMiwgVFlQRV9TRklYRUQzMik7CitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShpbnQ2NCwgVFlQRV9TRklYRUQ2NCk7CitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShmbG9hdCwgVFlQRV9GTE9BVCk7CitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShkb3VibGUsIFRZUEVfRE9VQkxFKTsKKworI3VuZGVmIFJFQURfUkVQRUFURURfUEFDS0VEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBDVHlwZSwgZW51bSBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIERlY2xhcmVkVHlwZT4KK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRQcmltaXRpdmVOb0lubGluZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlcykgeworICByZXR1cm4gUmVhZFBhY2tlZFByaW1pdGl2ZTxDVHlwZSwgRGVjbGFyZWRUeXBlPihpbnB1dCwgdmFsdWVzKTsKK30KKworCisKK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkR3JvdXAoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogdmFsdWUpIHsKKyAgaWYgKCFpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSkgcmV0dXJuIGZhbHNlOworICBpZiAoIXZhbHVlLT5NZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW5wdXQpKSByZXR1cm4gZmFsc2U7CisgIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAvLyBNYWtlIHN1cmUgdGhlIGxhc3QgdGhpbmcgcmVhZCB3YXMgYW4gZW5kIHRhZyBmb3IgdGhpcyBncm91cC4KKyAgaWYgKCFpbnB1dC0+TGFzdFRhZ1dhcyhNYWtlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRU5EX0dST1VQKSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VMaXRlKiB2YWx1ZSkgeworICB1aW50MzIgbGVuZ3RoOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgc3RkOjpwYWlyPGlvOjpDb2RlZElucHV0U3RyZWFtOjpMaW1pdCwgaW50PiBwID0KKyAgICAgIGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aEFuZFB1c2hMaW1pdChsZW5ndGgpOworICBpZiAocC5zZWNvbmQgPCAwIHx8ICF2YWx1ZS0+TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KSkgcmV0dXJuIGZhbHNlOworICAvLyBNYWtlIHN1cmUgdGhhdCBwYXJzaW5nIHN0b3BwZWQgd2hlbiB0aGUgbGltaXQgd2FzIGhpdCwgbm90IGF0IGFuIGVuZGdyb3VwCisgIC8vIHRhZy4KKyAgcmV0dXJuIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aEFuZFBvcExpbWl0KHAuZmlyc3QpOworfQorCisvLyBXZSBuYW1lIHRoZSB0ZW1wbGF0ZSBwYXJhbWV0ZXIgc29tZXRoaW5nIGxvbmcgYW5kIGV4dHJlbWVseSB1bmxpa2VseSB0byBvY2N1cgorLy8gZWxzZXdoZXJlIGJlY2F1c2UgYSAqcXVhbGlmaWVkKiBtZW1iZXIgYWNjZXNzIGV4cHJlc3Npb24gZGVzaWduZWQgdG8gYXZvaWQKKy8vIHZpcnR1YWwgZGlzcGF0Y2gsIEMrKzAzIFtiYXNpYy5sb29rdXAuY2xhc3NyZWZdIDMuNC41LzQgcmVxdWlyZXMgdGhhdCB0aGUKKy8vIG5hbWUgb2YgdGhlIHF1YWxpZnlpbmcgY2xhc3MgdG8gYmUgbG9va2VkIHVwIGJvdGggaW4gdGhlIGNvbnRleHQgb2YgdGhlIGZ1bGwKKy8vIGV4cHJlc3Npb24gKGZpbmRpbmcgdGhlIHRlbXBsYXRlIHBhcmFtZXRlcikgYW5kIGluIHRoZSBjb250ZXh0IG9mIHRoZSBvYmplY3QKKy8vIHdob3NlIG1lbWJlciB3ZSBhcmUgYWNjZXNzaW5nLiBUaGlzIGNvdWxkIHBvdGVudGlhbGx5IGZpbmQgYSBuZXN0ZWQgdHlwZQorLy8gd2l0aGluIHRoYXQgb2JqZWN0LiBUaGUgc3RhbmRhcmQgZ29lcyBvbiB0byByZXF1aXJlIHRoZXNlIG5hbWVzIHRvIHJlZmVyIHRvCisvLyB0aGUgc2FtZSBlbnRpdHksIHdoaWNoIHRoaXMgY29sbGlzaW9uIHdvdWxkIHZpb2xhdGUuIFRoZSBsYWNrIG9mIGEgc2FmZSB3YXkKKy8vIHRvIGF2b2lkIHRoaXMgY29sbGlzaW9uIGFwcGVhcnMgdG8gYmUgYSBkZWZlY3QgaW4gdGhlIHN0YW5kYXJkLCBidXQgdW50aWwgaXQKKy8vIGlzIGNvcnJlY3RlZCwgd2UgY2hvb3NlIHRoZSBuYW1lIHRvIGF2b2lkIGFjY2lkZW50YWwgY29sbGlzaW9ucy4KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZEdyb3VwTm9WaXJ0dWFsKAorICAgIGludCBmaWVsZF9udW1iZXIsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0KiB2YWx1ZSkgeworICBpZiAoIWlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKSByZXR1cm4gZmFsc2U7CisgIGlmICghdmFsdWUtPgorICAgICAgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KSkKKyAgICByZXR1cm4gZmFsc2U7CisgIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAvLyBNYWtlIHN1cmUgdGhlIGxhc3QgdGhpbmcgcmVhZCB3YXMgYW4gZW5kIHRhZyBmb3IgdGhpcyBncm91cC4KKyAgaWYgKCFpbnB1dC0+TGFzdFRhZ1dhcyhNYWtlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRU5EX0dST1VQKSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9Cit0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0PgoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdCogdmFsdWUpIHsKKyAgdWludDMyIGxlbmd0aDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgIHN0ZDo6cGFpcjxpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQsIGludD4gcCA9CisgICAgICBpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGhBbmRQdXNoTGltaXQobGVuZ3RoKTsKKyAgaWYgKHAuc2Vjb25kIDwgMCB8fCAhdmFsdWUtPgorICAgICAgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KSkKKyAgICByZXR1cm4gZmFsc2U7CisgIC8vIE1ha2Ugc3VyZSB0aGF0IHBhcnNpbmcgc3RvcHBlZCB3aGVuIHRoZSBsaW1pdCB3YXMgaGl0LCBub3QgYXQgYW4gZW5kZ3JvdXAKKyAgLy8gdGFnLgorICByZXR1cm4gaW5wdXQtPkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoQW5kUG9wTGltaXQocC5maXJzdCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworaW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlVGFnKGludCBmaWVsZF9udW1iZXIsIFdpcmVUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVRhZyhNYWtlVGFnKGZpZWxkX251bWJlciwgdHlwZSkpOworfQorCitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMk5vVGFnKGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWQodmFsdWUpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjROb1RhZyhpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDY0KHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUpKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQzMk5vVGFnKHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50NjROb1RhZyh1aW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlVmFyaW50NjQodmFsdWUpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ludDMyTm9UYWcoaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoWmlnWmFnRW5jb2RlMzIodmFsdWUpKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQ2NE5vVGFnKGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDY0KFppZ1phZ0VuY29kZTY0KHZhbHVlKSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDMyTm9UYWcodWludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW4zMih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDY0Tm9UYWcodWludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW42NCh2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQzMk5vVGFnKGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuMzIoc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSkpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkNjROb1RhZyhpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjY0KHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUpKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUZsb2F0Tm9UYWcoZmxvYXQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW4zMihFbmNvZGVGbG9hdCh2YWx1ZSkpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlRG91YmxlTm9UYWcoZG91YmxlIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjY0KEVuY29kZURvdWJsZSh2YWx1ZSkpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbE5vVGFnKGJvb2wgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlID8gMSA6IDApOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlRW51bU5vVGFnKGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWQodmFsdWUpOworfQorCisvLyBTZWUgY29tbWVudCBvbiBSZWFkR3JvdXBOb1ZpcnR1YWwgdG8gdW5kZXJzdGFuZCB0aGUgbmVlZCBmb3IgdGhpcyB0ZW1wbGF0ZQorLy8gcGFyYW1ldGVyIG5hbWUuCit0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0PgoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlR3JvdXBOb1ZpcnR1YWwoCisgICAgaW50IGZpZWxkX251bWJlciwgY29uc3QgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdCYgdmFsdWUsCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9TVEFSVF9HUk9VUCwgb3V0cHV0KTsKKyAgdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRU5EX0dST1VQLCBvdXRwdXQpOworfQordGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdD4KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgaW50IGZpZWxkX251bWJlciwgY29uc3QgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdCYgdmFsdWUsCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELCBvdXRwdXQpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoCisgICAgICB2YWx1ZS5NZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0OjpHZXRDYWNoZWRTaXplKCkpOworICB2YWx1ZS5NZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMob3V0cHV0KTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZ1RvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KE1ha2VUYWcoZmllbGRfbnVtYmVyLCB0eXBlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCk7Cit9CisKK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJOb1RhZ1RvQXJyYXkoaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZFRvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0Tm9UYWdUb0FycmF5KGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50NjRUb0FycmF5KAorICAgICAgc3RhdGljX2Nhc3Q8dWludDY0Pih2YWx1ZSksIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQzMk5vVGFnVG9BcnJheSh1aW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50NjROb1RhZ1RvQXJyYXkodWludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDY0VG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU0ludDMyTm9UYWdUb0FycmF5KGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheShaaWdaYWdFbmNvZGUzMih2YWx1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQ2NE5vVGFnVG9BcnJheShpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQ2NFRvQXJyYXkoWmlnWmFnRW5jb2RlNjQodmFsdWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDMyTm9UYWdUb0FycmF5KHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlTGl0dGxlRW5kaWFuMzJUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDY0Tm9UYWdUb0FycmF5KHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlTGl0dGxlRW5kaWFuNjRUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQzMk5vVGFnVG9BcnJheShpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjMyVG9BcnJheSgKKyAgICAgIHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUpLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQ2NE5vVGFnVG9BcnJheShpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjY0VG9BcnJheSgKKyAgICAgIHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUpLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGbG9hdE5vVGFnVG9BcnJheShmbG9hdCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjMyVG9BcnJheShFbmNvZGVGbG9hdCh2YWx1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZURvdWJsZU5vVGFnVG9BcnJheShkb3VibGUgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlTGl0dGxlRW5kaWFuNjRUb0FycmF5KEVuY29kZURvdWJsZSh2YWx1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xOb1RhZ1RvQXJyYXkoYm9vbCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJUb0FycmF5KHZhbHVlID8gMSA6IDAsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ob1RhZ1RvQXJyYXkoaW50IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZFRvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CisKK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVJbnQzMk5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjRUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVJbnQ2NE5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlVUludDMyVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlVUludDMyTm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50NjRUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVVSW50NjROb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQzMlRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlU0ludDMyTm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTSW50NjRUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZVNJbnQ2NE5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQzMlRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVEMzIsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZUZpeGVkMzJOb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUZpeGVkNjRUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDY0LCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVGaXhlZDY0Tm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQzMlRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDMyLCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVTRml4ZWQzMk5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkNjRUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfRklYRUQ2NCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlU0ZpeGVkNjROb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUZsb2F0VG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVEMzIsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZUZsb2F0Tm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGVUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfRklYRUQ2NCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlRG91YmxlTm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlQm9vbE5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlRW51bVRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlRW51bU5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KKworaW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIC8vIFN0cmluZyBpcyBmb3IgVVRGLTggdGV4dCBvbmx5CisgIC8vIFdBUk5JTkc6ICBJbiB3aXJlX2Zvcm1hdC5jYywgYm90aCBzdHJpbmdzIGFuZCBieXRlcyBhcmUgaGFuZGxlZCBieQorICAvLyAgIFdyaXRlU3RyaW5nKCkgdG8gYXZvaWQgY29kZSBkdXBsaWNhdGlvbi4gIElmIHRoZSBpbXBsZW1lbnRhdGlvbnMgYmVjb21lCisgIC8vICAgZGlmZmVyZW50LCB5b3Ugd2lsbCBuZWVkIHRvIHVwZGF0ZSB0aGF0IHVzYWdlLgorICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELCB0YXJnZXQpOworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVN0cmluZ1dpdGhTaXplVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlQnl0ZXNUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELCB0YXJnZXQpOworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVN0cmluZ1dpdGhTaXplVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KKworCitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUdyb3VwVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9TVEFSVF9HUk9VUCwgdGFyZ2V0KTsKKyAgdGFyZ2V0ID0gdmFsdWUuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSh0YXJnZXQpOworICByZXR1cm4gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfRU5EX0dST1VQLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdGFyZ2V0KTsKKyAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSgKKyAgICB2YWx1ZS5HZXRDYWNoZWRTaXplKCksIHRhcmdldCk7CisgIHJldHVybiB2YWx1ZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7Cit9CisKKy8vIFNlZSBjb21tZW50IG9uIFJlYWRHcm91cE5vVmlydHVhbCB0byB1bmRlcnN0YW5kIHRoZSBuZWVkIGZvciB0aGlzIHRlbXBsYXRlCisvLyBwYXJhbWV0ZXIgbmFtZS4KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUdyb3VwTm9WaXJ0dWFsVG9BcnJheSgKKyAgICBpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0JiB2YWx1ZSwKKyAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1NUQVJUX0dST1VQLCB0YXJnZXQpOworICB0YXJnZXQgPSB2YWx1ZS5NZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0CisgICAgICA6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0VORF9HUk9VUCwgdGFyZ2V0KTsKK30KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgIGludCBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3QmIHZhbHVlLAorICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdGFyZ2V0KTsKKyAgdGFyZ2V0ID0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSgKKyAgICB2YWx1ZS5NZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0OjpHZXRDYWNoZWRTaXplKCksIHRhcmdldCk7CisgIHJldHVybiB2YWx1ZS5NZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0CisgICAgICA6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoaW50MzIgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyU2lnbkV4dGVuZGVkKHZhbHVlKTsKK30KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OkludDY0U2l6ZShpbnQ2NCB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQoc3RhdGljX2Nhc3Q8dWludDY0Pih2YWx1ZSkpOworfQoraW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6VUludDMyU2l6ZSh1aW50MzIgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKHZhbHVlKTsKK30KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OlVJbnQ2NFNpemUodWludDY0IHZhbHVlKSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemU2NCh2YWx1ZSk7Cit9CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpTSW50MzJTaXplKGludDMyIHZhbHVlKSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihaaWdaYWdFbmNvZGUzMih2YWx1ZSkpOworfQoraW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6U0ludDY0U2l6ZShpbnQ2NCB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQoWmlnWmFnRW5jb2RlNjQodmFsdWUpKTsKK30KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OkVudW1TaXplKGludCB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzJTaWduRXh0ZW5kZWQodmFsdWUpOworfQorCitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKHZhbHVlLnNpemUoKSkgKworICAgICAgICAgdmFsdWUuc2l6ZSgpOworfQoraW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6Qnl0ZXNTaXplKGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKHZhbHVlLnNpemUoKSkgKworICAgICAgICAgdmFsdWUuc2l6ZSgpOworfQorCisKK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6Okdyb3VwU2l6ZShjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUpIHsKKyAgcmV0dXJuIHZhbHVlLkJ5dGVTaXplKCk7Cit9CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZShjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUpIHsKKyAgcmV0dXJuIExlbmd0aERlbGltaXRlZFNpemUodmFsdWUuQnl0ZVNpemUoKSk7Cit9CisKKy8vIFNlZSBjb21tZW50IG9uIFJlYWRHcm91cE5vVmlydHVhbCB0byB1bmRlcnN0YW5kIHRoZSBuZWVkIGZvciB0aGlzIHRlbXBsYXRlCisvLyBwYXJhbWV0ZXIgbmFtZS4KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpHcm91cFNpemVOb1ZpcnR1YWwoCisgICAgY29uc3QgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdCYgdmFsdWUpIHsKKyAgcmV0dXJuIHZhbHVlLk1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q6OkJ5dGVTaXplKCk7Cit9Cit0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0PgoraW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgY29uc3QgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdCYgdmFsdWUpIHsKKyAgcmV0dXJuIExlbmd0aERlbGltaXRlZFNpemUoCisgICAgICB2YWx1ZS5NZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0OjpCeXRlU2l6ZSgpKTsKK30KKworaW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6TGVuZ3RoRGVsaW1pdGVkU2l6ZShpbnQgbGVuZ3RoKSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihsZW5ndGgpICsgbGVuZ3RoOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9MSVRFX0lOTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzMDYyYTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTEyMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworbmFtZXNwYWNlIHsKKworVEVTVChXaXJlRm9ybWF0VGVzdCwgRW51bXNJblN5bmMpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBhbmQgV2lyZUZvcm1hdExpdGU6OkNwcFR5cGUgbWF0Y2gKKyAgLy8gRmllbGREZXNjcmlwdG9yOjpUeXBlIGFuZCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUuCisKKyAgRVhQRUNUX0VRKGltcGxpY2l0X2Nhc3Q8aW50PihGaWVsZERlc2NyaXB0b3I6Ok1BWF9UWVBFKSwKKyAgICAgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50PihXaXJlRm9ybWF0TGl0ZTo6TUFYX0ZJRUxEX1RZUEUpKTsKKyAgRVhQRUNUX0VRKGltcGxpY2l0X2Nhc3Q8aW50PihGaWVsZERlc2NyaXB0b3I6Ok1BWF9DUFBUWVBFKSwKKyAgICAgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50PihXaXJlRm9ybWF0TGl0ZTo6TUFYX0NQUFRZUEUpKTsKKworICBmb3IgKGludCBpID0gMTsgaSA8PSBXaXJlRm9ybWF0TGl0ZTo6TUFYX0ZJRUxEX1RZUEU7IGkrKykgeworICAgIEVYUEVDVF9FUSgKKyAgICAgIGltcGxpY2l0X2Nhc3Q8aW50PihGaWVsZERlc2NyaXB0b3I6OlR5cGVUb0NwcFR5cGUoCisgICAgICAgIHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvcjo6VHlwZT4oaSkpKSwKKyAgICAgIGltcGxpY2l0X2Nhc3Q8aW50PihXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlVG9DcHBUeXBlKAorICAgICAgICBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlPihpKSkpKTsKKyAgfQorfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBNYXhGaWVsZE51bWJlcikgeworICAvLyBNYWtlIHN1cmUgdGhlIG1heCBmaWVsZCBudW1iZXIgY29uc3RhbnQgaXMgYWNjdXJhdGUuCisgIEVYUEVDVF9FUSgoMSA8PCAoMzIgLSBXaXJlRm9ybWF0TGl0ZTo6a1RhZ1R5cGVCaXRzKSkgLSAxLAorICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBzb3VyY2UsIGRlc3Q7CisgIHN0cmluZyBkYXRhOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgLy8gUGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZkZXN0KTsKKworICAvLyBDaGVjay4KKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChkZXN0KTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBzb3VyY2UsIGRlc3Q7CisgIHN0cmluZyBkYXRhOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIC8vIFBhcnNlIHVzaW5nIFdpcmVGb3JtYXQuCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmZGVzdCk7CisKKyAgLy8gQ2hlY2suCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZVBhY2tlZCkgeworICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIHNvdXJjZSwgZGVzdDsKKyAgc3RyaW5nIGRhdGE7CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgVGVzdFV0aWw6OlNldFBhY2tlZEZpZWxkcygmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBQYXJzZSB1c2luZyBXaXJlRm9ybWF0LgorICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJmRlc3QpOworCisgIC8vIENoZWNrLgorICBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRmllbGRzU2V0KGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZVBhY2tlZEZyb21VbnBhY2tlZCkgeworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMgc291cmNlOworICBUZXN0VXRpbDo6U2V0VW5wYWNrZWRGaWVsZHMoJnNvdXJjZSk7CisgIHN0cmluZyBkYXRhID0gc291cmNlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisKKyAgLy8gUGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBkZXN0OworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJmRlc3QpOworCisgIC8vIENoZWNrLgorICBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRmllbGRzU2V0KGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZVVucGFja2VkRnJvbVBhY2tlZCkgeworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIHNvdXJjZTsKKyAgVGVzdFV0aWw6OlNldFBhY2tlZEZpZWxkcygmc291cmNlKTsKKyAgc3RyaW5nIGRhdGEgPSBzb3VyY2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKworICAvLyBQYXJzZSB1c2luZyBXaXJlRm9ybWF0LgorICB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMgZGVzdDsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZkZXN0KTsKKworICAvLyBDaGVjay4KKyAgVGVzdFV0aWw6OkV4cGVjdFVucGFja2VkRmllbGRzU2V0KGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZVBhY2tlZEV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIHNvdXJjZSwgZGVzdDsKKyAgc3RyaW5nIGRhdGE7CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgVGVzdFV0aWw6OlNldFBhY2tlZEV4dGVuc2lvbnMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgLy8gUGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZkZXN0KTsKKworICAvLyBDaGVjay4KKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQoZGVzdCk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFBhcnNlT25lb2YpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgc291cmNlLCBkZXN0OworICBzdHJpbmcgZGF0YTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICBUZXN0VXRpbDo6U2V0T25lb2YxKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIC8vIFBhcnNlIHVzaW5nIFdpcmVGb3JtYXQuCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmZGVzdCk7CisKKyAgLy8gQ2hlY2suCisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZlNldDEoZGVzdCk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIE9uZW9mT25seVNldExhc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgc291cmNlOworICB1bml0dGVzdDo6VGVzdE9uZW9mIG9uZW9mX2Rlc3Q7CisgIHN0cmluZyBkYXRhOworCisgIC8vIFNldCB0d28gZmllbGRzCisgIHNvdXJjZS5zZXRfZm9vX2ludCgxMDApOworICBzb3VyY2Uuc2V0X2Zvb19zdHJpbmcoIjEwMSIpOworCisgIC8vIFNlcmlhbGl6ZSBhbmQgcGFyc2UgdG8gb25lb2YgbWVzc2FnZS4KKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZvbmVvZl9kZXN0KTsKKworICAvLyBPbmx5IHRoZSBsYXN0IGZpZWxkIGlzIHNldC4KKyAgRVhQRUNUX0ZBTFNFKG9uZW9mX2Rlc3QuaGFzX2Zvb19pbnQoKSk7CisgIEVYUEVDVF9UUlVFKG9uZW9mX2Rlc3QuaGFzX2Zvb19zdHJpbmcoKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIEJ5dGVTaXplKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuQnl0ZVNpemUoKSwgV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZSkpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZSkpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBCeXRlU2l6ZUV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5CeXRlU2l6ZSgpLAorICAgICAgICAgICAgV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZSkpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZSkpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBCeXRlU2l6ZVBhY2tlZCkgeworICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRQYWNrZWRGaWVsZHMoJm1lc3NhZ2UpOworCisgIEVYUEVDVF9FUShtZXNzYWdlLkJ5dGVTaXplKCksIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgQnl0ZVNpemVQYWNrZWRFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0UGFja2VkRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuQnl0ZVNpemUoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgQnl0ZVNpemVPbmVvZikgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5CeXRlU2l6ZSgpLAorICBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgU2VyaWFsaXplKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgc3RyaW5nIGdlbmVyYXRlZF9kYXRhOworICBzdHJpbmcgZHluYW1pY19kYXRhOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBpbnQgc2l6ZSA9IG1lc3NhZ2UuQnl0ZVNpemUoKTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZnZW5lcmF0ZWRfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgbWVzc2FnZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dCk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgfQorCisgIC8vIFNlcmlhbGl6ZSB1c2luZyBXaXJlRm9ybWF0LgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZkeW5hbWljX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhtZXNzYWdlLCBzaXplLCAmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2hvdWxkIGJlIHRoZSBzYW1lLgorICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGhlcmUgYmVjYXVzZSB3ZSdyZSBjb21wYXJpbmcgcmF3IGJpbmFyeSBkYXRhIGFuZAorICAvLyB3ZSByZWFsbHkgZG9uJ3Qgd2FudCBpdCBkdW1wZWQgdG8gc3Rkb3V0IG9uIGZhaWx1cmUuCisgIEVYUEVDVF9UUlVFKGR5bmFtaWNfZGF0YSA9PSBnZW5lcmF0ZWRfZGF0YSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFNlcmlhbGl6ZUV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIHN0cmluZyBnZW5lcmF0ZWRfZGF0YTsKKyAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIGludCBzaXplID0gbWVzc2FnZS5CeXRlU2l6ZSgpOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmdlbmVyYXRlZF9kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIFdpcmVGb3JtYXQuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmR5bmFtaWNfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG1lc3NhZ2UsIHNpemUsICZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTaG91bGQgYmUgdGhlIHNhbWUuCisgIC8vIERvbid0IHVzZSBFWFBFQ1RfRVEgaGVyZSBiZWNhdXNlIHdlJ3JlIGNvbXBhcmluZyByYXcgYmluYXJ5IGRhdGEgYW5kCisgIC8vIHdlIHJlYWxseSBkb24ndCB3YW50IGl0IGR1bXBlZCB0byBzdGRvdXQgb24gZmFpbHVyZS4KKyAgRVhQRUNUX1RSVUUoZHluYW1pY19kYXRhID09IGdlbmVyYXRlZF9kYXRhKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgU2VyaWFsaXplRmllbGRzQW5kRXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdEZpZWxkT3JkZXJpbmdzIG1lc3NhZ2U7CisgIHN0cmluZyBnZW5lcmF0ZWRfZGF0YTsKKyAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzQW5kRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIGludCBzaXplID0gbWVzc2FnZS5CeXRlU2l6ZSgpOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmdlbmVyYXRlZF9kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIFdpcmVGb3JtYXQuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmR5bmFtaWNfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG1lc3NhZ2UsIHNpemUsICZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTaG91bGQgYmUgdGhlIHNhbWUuCisgIC8vIERvbid0IHVzZSBFWFBFQ1RfRVEgaGVyZSBiZWNhdXNlIHdlJ3JlIGNvbXBhcmluZyByYXcgYmluYXJ5IGRhdGEgYW5kCisgIC8vIHdlIHJlYWxseSBkb24ndCB3YW50IGl0IGR1bXBlZCB0byBzdGRvdXQgb24gZmFpbHVyZS4KKyAgRVhQRUNUX1RSVUUoZHluYW1pY19kYXRhID09IGdlbmVyYXRlZF9kYXRhKTsKKworICAvLyBTaG91bGQgb3V0cHV0IGluIGNhbm9uaWNhbCBvcmRlci4KKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc0FuZEV4dGVuc2lvbnNJbk9yZGVyKGR5bmFtaWNfZGF0YSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNBbmRFeHRlbnNpb25zSW5PcmRlcihnZW5lcmF0ZWRfZGF0YSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFNlcmlhbGl6ZU9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisgIHN0cmluZyBnZW5lcmF0ZWRfZGF0YTsKKyAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlLkJ5dGVTaXplKCk7CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmZ2VuZXJhdGVkX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTZXJpYWxpemUgdXNpbmcgV2lyZUZvcm1hdC4KKyAgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmZHluYW1pY19kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBXaXJlRm9ybWF0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMobWVzc2FnZSwgc2l6ZSwgJm91dHB1dCk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgfQorCisgIC8vIFNob3VsZCBiZSB0aGUgc2FtZS4KKyAgLy8gRG9uJ3QgdXNlIEVYUEVDVF9FUSBoZXJlIGJlY2F1c2Ugd2UncmUgY29tcGFyaW5nIHJhdyBiaW5hcnkgZGF0YSBhbmQKKyAgLy8gd2UgcmVhbGx5IGRvbid0IHdhbnQgaXQgZHVtcGVkIHRvIHN0ZG91dCBvbiBmYWlsdXJlLgorICBFWFBFQ1RfVFJVRShkeW5hbWljX2RhdGEgPT0gZ2VuZXJhdGVkX2RhdGEpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZU11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzKSB7CisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gcGFyc2UgYSBtZXNzYWdlIHRoYXQgY29udGFpbnMgbXVsdGlwbGUgZXh0ZW5zaW9ucyByYW5nZXMuCisgIHVuaXR0ZXN0OjpUZXN0RmllbGRPcmRlcmluZ3Mgc291cmNlOworICBzdHJpbmcgZGF0YTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzQW5kRXh0ZW5zaW9ucygmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBkZXN0OworICAgIEVYUEVDVF9UUlVFKGRlc3QuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEoc291cmNlLkRlYnVnU3RyaW5nKCksIGRlc3QuRGVidWdTdHJpbmcoKSk7CisgIH0KKworICAvLyBBbHNvIHRlc3QgdXNpbmcgcmVmbGVjdGlvbi1iYXNlZCBwYXJzaW5nLgorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBkZXN0OworICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZyYXdfaW5wdXQpOworICAgIEVYUEVDVF9UUlVFKFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZjb2RlZF9pbnB1dCwgJmRlc3QpKTsKKyAgICBFWFBFQ1RfRVEoc291cmNlLkRlYnVnU3RyaW5nKCksIGRlc3QuRGVidWdTdHJpbmcoKSk7CisgIH0KK30KKworY29uc3QgaW50IGtVbmtub3duVHlwZUlkID0gMTU1MDA1NTsKKworVEVTVChXaXJlRm9ybWF0VGVzdCwgU2VyaWFsaXplTWVzc2FnZVNldCkgeworICAvLyBTZXQgdXAgYSBUZXN0TWVzc2FnZVNldCB3aXRoIHR3byBrbm93biBtZXNzYWdlcyBhbmQgYW4gdW5rbm93biBvbmUuCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldDsKKyAgbWVzc2FnZV9zZXQuTXV0YWJsZUV4dGVuc2lvbigKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pLT5zZXRfaSgxMjMpOworICBtZXNzYWdlX3NldC5NdXRhYmxlRXh0ZW5zaW9uKAorICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiktPnNldF9zdHIoImZvbyIpOworICBtZXNzYWdlX3NldC5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZExlbmd0aERlbGltaXRlZCgKKyAgICBrVW5rbm93blR5cGVJZCwgImJhciIpOworCisgIHN0cmluZyBkYXRhOworICBBU1NFUlRfVFJVRShtZXNzYWdlX3NldC5TZXJpYWxpemVUb1N0cmluZygmZGF0YSkpOworCisgIC8vIFBhcnNlIGJhY2sgdXNpbmcgUmF3TWVzc2FnZVNldCBhbmQgY2hlY2sgdGhlIGNvbnRlbnRzLgorICB1bml0dGVzdDo6UmF3TWVzc2FnZVNldCByYXc7CisgIEFTU0VSVF9UUlVFKHJhdy5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworCisgIEVYUEVDVF9FUSgwLCByYXcudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKworICBBU1NFUlRfRVEoMywgcmF3Lml0ZW1fc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKAorICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6OmRlc2NyaXB0b3IoKS0+ZXh0ZW5zaW9uKDApLT5udW1iZXIoKSwKKyAgICByYXcuaXRlbSgwKS50eXBlX2lkKCkpOworICBFWFBFQ1RfRVEoCisgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMjo6ZGVzY3JpcHRvcigpLT5leHRlbnNpb24oMCktPm51bWJlcigpLAorICAgIHJhdy5pdGVtKDEpLnR5cGVfaWQoKSk7CisgIEVYUEVDVF9FUShrVW5rbm93blR5cGVJZCwgcmF3Lml0ZW0oMikudHlwZV9pZCgpKTsKKworICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIG1lc3NhZ2UxOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5QYXJzZUZyb21TdHJpbmcocmF3Lml0ZW0oMCkubWVzc2FnZSgpKSk7CisgIEVYUEVDVF9FUSgxMjMsIG1lc3NhZ2UxLmkoKSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBtZXNzYWdlMjsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKHJhdy5pdGVtKDEpLm1lc3NhZ2UoKSkpOworICBFWFBFQ1RfRVEoImZvbyIsIG1lc3NhZ2UyLnN0cigpKTsKKworICBFWFBFQ1RfRVEoImJhciIsIHJhdy5pdGVtKDIpLm1lc3NhZ2UoKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFNlcmlhbGl6ZU1lc3NhZ2VTZXRWYXJpb3VzV2F5c0FyZUVxdWFsKSB7CisgIC8vIFNlcmlhbGl6ZSBhIE1lc3NhZ2VTZXQgdG8gYSBzdHJlYW0gYW5kIHRvIGEgZmxhdCBhcnJheSB1c2luZyBnZW5lcmF0ZWQKKyAgLy8gY29kZSwgYW5kIGFsc28gdXNpbmcgV2lyZUZvcm1hdCwgYW5kIGNoZWNrIHRoYXQgdGhlIHJlc3VsdHMgYXJlIGVxdWFsLgorICAvLyBTZXQgdXAgYSBUZXN0TWVzc2FnZVNldCB3aXRoIHR3byBrbm93biBtZXNzYWdlcyBhbmQgYW4gdW5rbm93biBvbmUsIGFzCisgIC8vIGFib3ZlLgorCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldDsKKyAgbWVzc2FnZV9zZXQuTXV0YWJsZUV4dGVuc2lvbigKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pLT5zZXRfaSgxMjMpOworICBtZXNzYWdlX3NldC5NdXRhYmxlRXh0ZW5zaW9uKAorICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiktPnNldF9zdHIoImZvbyIpOworICBtZXNzYWdlX3NldC5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZExlbmd0aERlbGltaXRlZCgKKyAgICBrVW5rbm93blR5cGVJZCwgImJhciIpOworCisgIGludCBzaXplID0gbWVzc2FnZV9zZXQuQnl0ZVNpemUoKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2Vfc2V0LkdldENhY2hlZFNpemUoKSk7CisgIEFTU0VSVF9FUShzaXplLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlX3NldCkpOworCisgIHN0cmluZyBmbGF0X2RhdGE7CisgIHN0cmluZyBzdHJlYW1fZGF0YTsKKyAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKyAgZmxhdF9kYXRhLnJlc2l6ZShzaXplKTsKKyAgc3RyZWFtX2RhdGEucmVzaXplKHNpemUpOworCisgIC8vIFNlcmlhbGl6ZSB0byBmbGF0IGFycmF5CisgIHsKKyAgICB1aW50OCogdGFyZ2V0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZmxhdF9kYXRhKSk7CisgICAgdWludDgqIGVuZCA9IG1lc3NhZ2Vfc2V0LlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gdGFyZ2V0KTsKKyAgfQorCisgIC8vIFNlcmlhbGl6ZSB0byBidWZmZXIKKyAgeworICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZzdHJlYW1fZGF0YSksIHNpemUsIDEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZhcnJheV9zdHJlYW0pOworICAgIG1lc3NhZ2Vfc2V0LlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTZXJpYWxpemUgdG8gYnVmZmVyIHdpdGggV2lyZUZvcm1hdC4KKyAgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gc3RyaW5nX3N0cmVhbSgmZHluYW1pY19kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmc3RyaW5nX3N0cmVhbSk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG1lc3NhZ2Vfc2V0LCBzaXplLCAmb3V0cHV0X3N0cmVhbSk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgIH0KKworICBFWFBFQ1RfVFJVRShmbGF0X2RhdGEgPT0gc3RyZWFtX2RhdGEpOworICBFWFBFQ1RfVFJVRShmbGF0X2RhdGEgPT0gZHluYW1pY19kYXRhKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VNZXNzYWdlU2V0KSB7CisgIC8vIFNldCB1cCBhIFJhd01lc3NhZ2VTZXQgd2l0aCB0d28ga25vd24gbWVzc2FnZXMgYW5kIGFuIHVua25vd24gb25lLgorICB1bml0dGVzdDo6UmF3TWVzc2FnZVNldCByYXc7CisKKyAgeworICAgIHVuaXR0ZXN0OjpSYXdNZXNzYWdlU2V0OjpJdGVtKiBpdGVtID0gcmF3LmFkZF9pdGVtKCk7CisgICAgaXRlbS0+c2V0X3R5cGVfaWQoCisgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjpkZXNjcmlwdG9yKCktPmV4dGVuc2lvbigwKS0+bnVtYmVyKCkpOworICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgbWVzc2FnZTsKKyAgICBtZXNzYWdlLnNldF9pKDEyMyk7CisgICAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZyhpdGVtLT5tdXRhYmxlX21lc3NhZ2UoKSk7CisgIH0KKworICB7CisgICAgdW5pdHRlc3Q6OlJhd01lc3NhZ2VTZXQ6Okl0ZW0qIGl0ZW0gPSByYXcuYWRkX2l0ZW0oKTsKKyAgICBpdGVtLT5zZXRfdHlwZV9pZCgKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6OmRlc2NyaXB0b3IoKS0+ZXh0ZW5zaW9uKDApLT5udW1iZXIoKSk7CisgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBtZXNzYWdlOworICAgIG1lc3NhZ2Uuc2V0X3N0cigiZm9vIik7CisgICAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZyhpdGVtLT5tdXRhYmxlX21lc3NhZ2UoKSk7CisgIH0KKworICB7CisgICAgdW5pdHRlc3Q6OlJhd01lc3NhZ2VTZXQ6Okl0ZW0qIGl0ZW0gPSByYXcuYWRkX2l0ZW0oKTsKKyAgICBpdGVtLT5zZXRfdHlwZV9pZChrVW5rbm93blR5cGVJZCk7CisgICAgaXRlbS0+c2V0X21lc3NhZ2UoImJhciIpOworICB9CisKKyAgc3RyaW5nIGRhdGE7CisgIEFTU0VSVF9UUlVFKHJhdy5TZXJpYWxpemVUb1N0cmluZygmZGF0YSkpOworCisgIC8vIFBhcnNlIGFzIGEgVGVzdE1lc3NhZ2VTZXQgYW5kIGNoZWNrIHRoZSBjb250ZW50cy4KKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0OworICBBU1NFUlRfVFJVRShtZXNzYWdlX3NldC5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworCisgIEVYUEVDVF9FUSgxMjMsIG1lc3NhZ2Vfc2V0LkdldEV4dGVuc2lvbigKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pLmkoKSk7CisgIEVYUEVDVF9FUSgiZm9vIiwgbWVzc2FnZV9zZXQuR2V0RXh0ZW5zaW9uKAorICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbikuc3RyKCkpOworCisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlX3NldC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX0xFTkdUSF9ERUxJTUlURUQsCisgICAgICAgICAgICBtZXNzYWdlX3NldC51bmtub3duX2ZpZWxkcygpLmZpZWxkKDApLnR5cGUoKSk7CisgIEVYUEVDVF9FUSgiYmFyIiwgbWVzc2FnZV9zZXQudW5rbm93bl9maWVsZHMoKS5maWVsZCgwKS5sZW5ndGhfZGVsaW1pdGVkKCkpOworCisgIC8vIEFsc28gcGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IGR5bmFtaWNfbWVzc2FnZV9zZXQ7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhLmRhdGEoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuc2l6ZSgpKTsKKyAgQVNTRVJUX1RSVUUoV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmZHluYW1pY19tZXNzYWdlX3NldCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV9zZXQuRGVidWdTdHJpbmcoKSwgZHluYW1pY19tZXNzYWdlX3NldC5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VNZXNzYWdlU2V0V2l0aFJldmVyc2VUYWdPcmRlcikgeworICBzdHJpbmcgZGF0YTsKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgbWVzc2FnZTsKKyAgICBtZXNzYWdlLnNldF9pKDEyMyk7CisgICAgLy8gQnVpbGQgYSBNZXNzYWdlU2V0IG1hbnVhbGx5IHdpdGggaXRzIG1lc3NhZ2UgY29udGVudCBwdXQgYmVmb3JlIGl0cworICAgIC8vIHR5cGVfaWQuCisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZkYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXRfc3RyZWFtKTsKKyAgICBjb2RlZF9vdXRwdXQuV3JpdGVUYWcoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnKTsKKyAgICAvLyBXcml0ZSB0aGUgbWVzc2FnZSBjb250ZW50IGZpcnN0LgorICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZyhXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvZGVkX291dHB1dCk7CisgICAgY29kZWRfb3V0cHV0LldyaXRlVmFyaW50MzIobWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmY29kZWRfb3V0cHV0KTsKKyAgICAvLyBXcml0ZSB0aGUgdHlwZSBpZC4KKyAgICB1aW50MzIgdHlwZV9pZCA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpLT5leHRlbnNpb24oMCktPm51bWJlcigpOworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRUeXBlSWROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaWQsICZjb2RlZF9vdXRwdXQpOworICAgIGNvZGVkX291dHB1dC5Xcml0ZVRhZyhXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnKTsKKyAgfQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0OworICAgIEFTU0VSVF9UUlVFKG1lc3NhZ2Vfc2V0LlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisKKyAgICBFWFBFQ1RfRVEoMTIzLCBtZXNzYWdlX3NldC5HZXRFeHRlbnNpb24oCisgICAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbikuaSgpKTsKKyAgfQorICB7CisgICAgLy8gVGVzdCBwYXJzZSB0aGUgbWVzc2FnZSB2aWEgUmVmbGVjdGlvbi4KKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQ7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoCisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhLmRhdGEoKSksIGRhdGEuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfVFJVRShXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZtZXNzYWdlX3NldCkpOworICAgIEVYUEVDVF9UUlVFKGlucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKKworICAgIEVYUEVDVF9FUSgxMjMsIG1lc3NhZ2Vfc2V0LkdldEV4dGVuc2lvbigKKyAgICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS5pKCkpOworICB9Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFBhcnNlQnJva2VuTWVzc2FnZVNldCkgeworICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQ7CisgIHN0cmluZyBpbnB1dCgiZ29vZGJ5ZSIpOyAgLy8gSW52YWxpZCB3aXJlIGZvcm1hdCBkYXRhLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZV9zZXQuUGFyc2VGcm9tU3RyaW5nKGlucHV0KSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFJlY3Vyc2lvbkxpbWl0KSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVjdXJzaXZlTWVzc2FnZSBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfYSgpLT5tdXRhYmxlX2EoKS0+bXV0YWJsZV9hKCktPm11dGFibGVfYSgpLT5zZXRfaSgxKTsKKyAgc3RyaW5nIGRhdGE7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIHsKKyAgICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgICBpbnB1dC5TZXRSZWN1cnNpb25MaW1pdCg0KTsKKyAgICB1bml0dGVzdDo6VGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgbWVzc2FnZTI7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmlucHV0KSk7CisgIH0KKworICB7CisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgICAgaW5wdXQuU2V0UmVjdXJzaW9uTGltaXQoMyk7CisgICAgdW5pdHRlc3Q6OlRlc3RSZWN1cnNpdmVNZXNzYWdlIG1lc3NhZ2UyOworICAgIEVYUEVDVF9GQUxTRShtZXNzYWdlMi5QYXJzZUZyb21Db2RlZFN0cmVhbSgmaW5wdXQpKTsKKyAgfQorfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBVbmtub3duRmllbGRSZWN1cnNpb25MaW1pdCkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKQorICAgICAgICAtPkFkZEdyb3VwKDEyMzQpCisgICAgICAgIC0+QWRkR3JvdXAoMTIzNCkKKyAgICAgICAgLT5BZGRHcm91cCgxMjM0KQorICAgICAgICAtPkFkZEdyb3VwKDEyMzQpCisgICAgICAgIC0+QWRkVmFyaW50KDEyMzQsIDEyMyk7CisgIHN0cmluZyBkYXRhOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICB7CisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgICAgaW5wdXQuU2V0UmVjdXJzaW9uTGltaXQoNCk7CisgICAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgbWVzc2FnZTI7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmlucHV0KSk7CisgIH0KKworICB7CisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgICAgaW5wdXQuU2V0UmVjdXJzaW9uTGltaXQoMyk7CisgICAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgbWVzc2FnZTI7CisgICAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UyLlBhcnNlRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCkpOworICB9Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFppZ1phZykgeworLy8gYXZvaWQgbGluZS13cmFwcGluZworI2RlZmluZSBMTCh4KSBHT09HTEVfTE9OR0xPTkcoeCkKKyNkZWZpbmUgVUxMKHgpIEdPT0dMRV9VTE9OR0xPTkcoeCkKKyNkZWZpbmUgWmlnWmFnRW5jb2RlMzIoeCkgV2lyZUZvcm1hdExpdGU6OlppZ1phZ0VuY29kZTMyKHgpCisjZGVmaW5lIFppZ1phZ0RlY29kZTMyKHgpIFdpcmVGb3JtYXRMaXRlOjpaaWdaYWdEZWNvZGUzMih4KQorI2RlZmluZSBaaWdaYWdFbmNvZGU2NCh4KSBXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRW5jb2RlNjQoeCkKKyNkZWZpbmUgWmlnWmFnRGVjb2RlNjQoeCkgV2lyZUZvcm1hdExpdGU6OlppZ1phZ0RlY29kZTY0KHgpCisKKyAgRVhQRUNUX0VRKDB1LCBaaWdaYWdFbmNvZGUzMiggMCkpOworICBFWFBFQ1RfRVEoMXUsIFppZ1phZ0VuY29kZTMyKC0xKSk7CisgIEVYUEVDVF9FUSgydSwgWmlnWmFnRW5jb2RlMzIoIDEpKTsKKyAgRVhQRUNUX0VRKDN1LCBaaWdaYWdFbmNvZGUzMigtMikpOworICBFWFBFQ1RfRVEoMHg3RkZGRkZGRXUsIFppZ1phZ0VuY29kZTMyKDB4M0ZGRkZGRkYpKTsKKyAgRVhQRUNUX0VRKDB4N0ZGRkZGRkZ1LCBaaWdaYWdFbmNvZGUzMigweEMwMDAwMDAwKSk7CisgIEVYUEVDVF9FUSgweEZGRkZGRkZFdSwgWmlnWmFnRW5jb2RlMzIoMHg3RkZGRkZGRikpOworICBFWFBFQ1RfRVEoMHhGRkZGRkZGRnUsIFppZ1phZ0VuY29kZTMyKDB4ODAwMDAwMDApKTsKKworICBFWFBFQ1RfRVEoIDAsIFppZ1phZ0RlY29kZTMyKDB1KSk7CisgIEVYUEVDVF9FUSgtMSwgWmlnWmFnRGVjb2RlMzIoMXUpKTsKKyAgRVhQRUNUX0VRKCAxLCBaaWdaYWdEZWNvZGUzMigydSkpOworICBFWFBFQ1RfRVEoLTIsIFppZ1phZ0RlY29kZTMyKDN1KSk7CisgIEVYUEVDVF9FUSgweDNGRkZGRkZGLCBaaWdaYWdEZWNvZGUzMigweDdGRkZGRkZFdSkpOworICBFWFBFQ1RfRVEoMHhDMDAwMDAwMCwgWmlnWmFnRGVjb2RlMzIoMHg3RkZGRkZGRnUpKTsKKyAgRVhQRUNUX0VRKDB4N0ZGRkZGRkYsIFppZ1phZ0RlY29kZTMyKDB4RkZGRkZGRkV1KSk7CisgIEVYUEVDVF9FUSgweDgwMDAwMDAwLCBaaWdaYWdEZWNvZGUzMigweEZGRkZGRkZGdSkpOworCisgIEVYUEVDVF9FUSgwdSwgWmlnWmFnRW5jb2RlNjQoIDApKTsKKyAgRVhQRUNUX0VRKDF1LCBaaWdaYWdFbmNvZGU2NCgtMSkpOworICBFWFBFQ1RfRVEoMnUsIFppZ1phZ0VuY29kZTY0KCAxKSk7CisgIEVYUEVDVF9FUSgzdSwgWmlnWmFnRW5jb2RlNjQoLTIpKTsKKyAgRVhQRUNUX0VRKFVMTCgweDAwMDAwMDAwN0ZGRkZGRkUpLCBaaWdaYWdFbmNvZGU2NChMTCgweDAwMDAwMDAwM0ZGRkZGRkYpKSk7CisgIEVYUEVDVF9FUShVTEwoMHgwMDAwMDAwMDdGRkZGRkZGKSwgWmlnWmFnRW5jb2RlNjQoTEwoMHhGRkZGRkZGRkMwMDAwMDAwKSkpOworICBFWFBFQ1RfRVEoVUxMKDB4MDAwMDAwMDBGRkZGRkZGRSksIFppZ1phZ0VuY29kZTY0KExMKDB4MDAwMDAwMDA3RkZGRkZGRikpKTsKKyAgRVhQRUNUX0VRKFVMTCgweDAwMDAwMDAwRkZGRkZGRkYpLCBaaWdaYWdFbmNvZGU2NChMTCgweEZGRkZGRkZGODAwMDAwMDApKSk7CisgIEVYUEVDVF9FUShVTEwoMHhGRkZGRkZGRkZGRkZGRkZFKSwgWmlnWmFnRW5jb2RlNjQoTEwoMHg3RkZGRkZGRkZGRkZGRkZGKSkpOworICBFWFBFQ1RfRVEoVUxMKDB4RkZGRkZGRkZGRkZGRkZGRiksIFppZ1phZ0VuY29kZTY0KExMKDB4ODAwMDAwMDAwMDAwMDAwMCkpKTsKKworICBFWFBFQ1RfRVEoIDAsIFppZ1phZ0RlY29kZTY0KDB1KSk7CisgIEVYUEVDVF9FUSgtMSwgWmlnWmFnRGVjb2RlNjQoMXUpKTsKKyAgRVhQRUNUX0VRKCAxLCBaaWdaYWdEZWNvZGU2NCgydSkpOworICBFWFBFQ1RfRVEoLTIsIFppZ1phZ0RlY29kZTY0KDN1KSk7CisgIEVYUEVDVF9FUShMTCgweDAwMDAwMDAwM0ZGRkZGRkYpLCBaaWdaYWdEZWNvZGU2NChVTEwoMHgwMDAwMDAwMDdGRkZGRkZFKSkpOworICBFWFBFQ1RfRVEoTEwoMHhGRkZGRkZGRkMwMDAwMDAwKSwgWmlnWmFnRGVjb2RlNjQoVUxMKDB4MDAwMDAwMDA3RkZGRkZGRikpKTsKKyAgRVhQRUNUX0VRKExMKDB4MDAwMDAwMDA3RkZGRkZGRiksIFppZ1phZ0RlY29kZTY0KFVMTCgweDAwMDAwMDAwRkZGRkZGRkUpKSk7CisgIEVYUEVDVF9FUShMTCgweEZGRkZGRkZGODAwMDAwMDApLCBaaWdaYWdEZWNvZGU2NChVTEwoMHgwMDAwMDAwMEZGRkZGRkZGKSkpOworICBFWFBFQ1RfRVEoTEwoMHg3RkZGRkZGRkZGRkZGRkZGKSwgWmlnWmFnRGVjb2RlNjQoVUxMKDB4RkZGRkZGRkZGRkZGRkZGRSkpKTsKKyAgRVhQRUNUX0VRKExMKDB4ODAwMDAwMDAwMDAwMDAwMCksIFppZ1phZ0RlY29kZTY0KFVMTCgweEZGRkZGRkZGRkZGRkZGRkYpKSk7CisKKyAgLy8gU29tZSBlYXNpZXItdG8tdmVyaWZ5IHJvdW5kLXRyaXAgdGVzdHMuICBUaGUgaW5wdXRzIChvdGhlciB0aGFuIDAsIDEsIC0xKQorICAvLyB3ZXJlIGNob3NlbiBzZW1pLXJhbmRvbWx5IHZpYSBrZXlib2FyZCBiYXNoaW5nLgorICBFWFBFQ1RfRVEoICAgIDAsIFppZ1phZ0RlY29kZTMyKFppZ1phZ0VuY29kZTMyKCAgICAwKSkpOworICBFWFBFQ1RfRVEoICAgIDEsIFppZ1phZ0RlY29kZTMyKFppZ1phZ0VuY29kZTMyKCAgICAxKSkpOworICBFWFBFQ1RfRVEoICAgLTEsIFppZ1phZ0RlY29kZTMyKFppZ1phZ0VuY29kZTMyKCAgIC0xKSkpOworICBFWFBFQ1RfRVEoMTQ5MjcsIFppZ1phZ0RlY29kZTMyKFppZ1phZ0VuY29kZTMyKDE0OTI3KSkpOworICBFWFBFQ1RfRVEoLTM2MTIsIFppZ1phZ0RlY29kZTMyKFppZ1phZ0VuY29kZTMyKC0zNjEyKSkpOworCisgIEVYUEVDVF9FUSggICAgMCwgWmlnWmFnRGVjb2RlNjQoWmlnWmFnRW5jb2RlNjQoICAgIDApKSk7CisgIEVYUEVDVF9FUSggICAgMSwgWmlnWmFnRGVjb2RlNjQoWmlnWmFnRW5jb2RlNjQoICAgIDEpKSk7CisgIEVYUEVDVF9FUSggICAtMSwgWmlnWmFnRGVjb2RlNjQoWmlnWmFnRW5jb2RlNjQoICAgLTEpKSk7CisgIEVYUEVDVF9FUSgxNDkyNywgWmlnWmFnRGVjb2RlNjQoWmlnWmFnRW5jb2RlNjQoMTQ5MjcpKSk7CisgIEVYUEVDVF9FUSgtMzYxMiwgWmlnWmFnRGVjb2RlNjQoWmlnWmFnRW5jb2RlNjQoLTM2MTIpKSk7CisKKyAgRVhQRUNUX0VRKExMKDg1NjkxMjMwNDgwMTQxNiksIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KAorICAgICAgICAgICAgTEwoODU2OTEyMzA0ODAxNDE2KSkpKTsKKyAgRVhQRUNUX0VRKExMKC03NTEyMzkwNTQzOTU3MTI1NiksIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KAorICAgICAgICAgICAgTEwoLTc1MTIzOTA1NDM5NTcxMjU2KSkpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUmVwZWF0ZWRTY2FsYXJzRGlmZmVyZW50VGFnU2l6ZXMpIHsKKyAgLy8gQXQgb25lIHBvaW50IGNoZWNrcyB3b3VsZCB0cmlnZ2VyIHdoZW4gcGFyc2luZyByZXBlYXRlZCBmaXhlZCBzY2FsYXIKKyAgLy8gZmllbGRzLgorICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgbXNnMSwgbXNnMjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7ICsraSkgeworICAgIG1zZzEuYWRkX3JlcGVhdGVkX2ZpeGVkMzIoaSk7CisgICAgbXNnMS5hZGRfcmVwZWF0ZWRfaW50MzIoaSk7CisgICAgbXNnMS5hZGRfcmVwZWF0ZWRfZml4ZWQ2NChpKTsKKyAgICBtc2cxLmFkZF9yZXBlYXRlZF9pbnQ2NChpKTsKKyAgICBtc2cxLmFkZF9yZXBlYXRlZF9mbG9hdChpKTsKKyAgICBtc2cxLmFkZF9yZXBlYXRlZF91aW50NjQoaSk7CisgIH0KKworICAvLyBNYWtlIHN1cmUgdGhhdCB3ZSBoYXZlIGEgdmFyaWV0eSBvZiB0YWcgc2l6ZXMuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2MgPSBtc2cxLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZDsKKyAgZmllbGQgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ZpeGVkMzIiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgxLCBXaXJlRm9ybWF0OjpUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkpOworICBmaWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW50MzIiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgxLCBXaXJlRm9ybWF0OjpUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkpOworICBmaWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZml4ZWQ2NCIpOworICBBU1NFUlRfVFJVRShmaWVsZCAhPSBOVUxMKTsKKyAgQVNTRVJUX0VRKDIsIFdpcmVGb3JtYXQ6OlRhZ1NpemUoZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpKSk7CisgIGZpZWxkID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQ2NCIpOworICBBU1NFUlRfVFJVRShmaWVsZCAhPSBOVUxMKTsKKyAgQVNTRVJUX0VRKDIsIFdpcmVGb3JtYXQ6OlRhZ1NpemUoZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpKSk7CisgIGZpZWxkID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9mbG9hdCIpOworICBBU1NFUlRfVFJVRShmaWVsZCAhPSBOVUxMKTsKKyAgQVNTRVJUX0VRKDMsIFdpcmVGb3JtYXQ6OlRhZ1NpemUoZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpKSk7CisgIGZpZWxkID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF91aW50NjQiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgzLCBXaXJlRm9ybWF0OjpUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkpOworCisgIEVYUEVDVF9UUlVFKG1zZzIuUGFyc2VGcm9tU3RyaW5nKG1zZzEuU2VyaWFsaXplQXNTdHJpbmcoKSkpOworICBFWFBFQ1RfRVEobXNnMS5EZWJ1Z1N0cmluZygpLCBtc2cyLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBDb21wYXRpYmxlVHlwZXMpIHsKKyAgY29uc3QgaW50NjQgZGF0YSA9IDB4MTAwMDAwMDAwOworICB1bml0dGVzdDo6SW50NjRNZXNzYWdlIG1zZzE7CisgIG1zZzEuc2V0X2RhdGEoZGF0YSk7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBtc2cxLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKworICAvLyBUZXN0IGludDY0IGlzIGNvbXBhdGlibGUgd2l0aCBib29sCisgIHVuaXR0ZXN0OjpCb29sTWVzc2FnZSBtc2cyOworICBBU1NFUlRfVFJVRShtc2cyLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEFTU0VSVF9FUShzdGF0aWNfY2FzdDxib29sPihkYXRhKSwgbXNnMi5kYXRhKCkpOworCisgIC8vIFRlc3QgaW50NjQgaXMgY29tcGF0aWJsZSB3aXRoIHVpbnQ2NAorICB1bml0dGVzdDo6VWludDY0TWVzc2FnZSBtc2czOworICBBU1NFUlRfVFJVRShtc2czLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEFTU0VSVF9FUShzdGF0aWNfY2FzdDx1aW50NjQ+KGRhdGEpLCBtc2czLmRhdGEoKSk7CisKKyAgLy8gVGVzdCBpbnQ2NCBpcyBjb21wYXRpYmxlIHdpdGggaW50MzIKKyAgdW5pdHRlc3Q6OkludDMyTWVzc2FnZSBtc2c0OworICBBU1NFUlRfVFJVRShtc2c0LlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEFTU0VSVF9FUShzdGF0aWNfY2FzdDxpbnQzMj4oZGF0YSksIG1zZzQuZGF0YSgpKTsKKworICAvLyBUZXN0IGludDY0IGlzIGNvbXBhdGlibGUgd2l0aCB1aW50MzIKKyAgdW5pdHRlc3Q6OlVpbnQzMk1lc3NhZ2UgbXNnNTsKKyAgQVNTRVJUX1RSVUUobXNnNS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBBU1NFUlRfRVEoc3RhdGljX2Nhc3Q8dWludDMyPihkYXRhKSwgbXNnNS5kYXRhKCkpOworfQorCitjbGFzcyBXaXJlRm9ybWF0SW52YWxpZElucHV0VGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIC8vIE1ha2UgYSBzZXJpYWxpemVkIFRlc3RBbGxUeXBlcyBpbiB3aGljaCB0aGUgZmllbGQgb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UKKyAgLy8gY29udGFpbnMgZXhhY3RseSB0aGUgZ2l2ZW4gYnl0ZXMsIHdoaWNoIG1heSBiZSBpbnZhbGlkLgorICBzdHJpbmcgTWFrZUludmFsaWRFbWJlZGRlZE1lc3NhZ2UoY29uc3QgY2hhciogYnl0ZXMsIGludCBzaXplKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9CisgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisgICAgR09PR0xFX0NIRUNLKGZpZWxkICE9IE5VTEwpOworCisgICAgc3RyaW5nIHJlc3VsdDsKKworICAgIHsKKyAgICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmcmVzdWx0KTsKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworCisgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlcyhmaWVsZC0+bnVtYmVyKCksIHN0cmluZyhieXRlcywgc2l6ZSksICZvdXRwdXQpOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvLyBNYWtlIGEgc2VyaWFsaXplZCBUZXN0QWxsVHlwZXMgaW4gd2hpY2ggdGhlIGZpZWxkIG9wdGlvbmFsZ3JvdXAKKyAgLy8gY29udGFpbnMgZXhhY3RseSB0aGUgZ2l2ZW4gYnl0ZXMgLS0gd2hpY2ggbWF5IGJlIGludmFsaWQgLS0gYW5kCisgIC8vIHBvc3NpYmx5IG5vIGVuZCB0YWcuCisgIHN0cmluZyBNYWtlSW52YWxpZEdyb3VwKGNvbnN0IGNoYXIqIGJ5dGVzLCBpbnQgc2l6ZSwgYm9vbCBpbmNsdWRlX2VuZF90YWcpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgICAib3B0aW9uYWxncm91cCIpOworICAgIEdPT0dMRV9DSEVDSyhmaWVsZCAhPSBOVUxMKTsKKworICAgIHN0cmluZyByZXN1bHQ7CisKKyAgICB7CisgICAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJnJlc3VsdCk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKworICAgICAgb3V0cHV0LldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdDo6TWFrZVRhZyhmaWVsZCkpOworICAgICAgb3V0cHV0LldyaXRlU3RyaW5nKHN0cmluZyhieXRlcywgc2l6ZSkpOworICAgICAgaWYgKGluY2x1ZGVfZW5kX3RhZykgeworICAgICAgICBvdXRwdXQuV3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygKKyAgICAgICAgICBmaWVsZC0+bnVtYmVyKCksIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9OworCitURVNUX0YoV2lyZUZvcm1hdEludmFsaWRJbnB1dFRlc3QsIEludmFsaWRTdWJNZXNzYWdlKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICAvLyBDb250cm9sIGNhc2UuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkRW1iZWRkZWRNZXNzYWdlKCIiLCAwKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50LCBidXQgbm90IGEgdmFsaWQgdGFnICh6ZXJvKS4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkRW1iZWRkZWRNZXNzYWdlKCJcMCIsIDEpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYSBtYWxmb3JtZWQgdmFyaW50LgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRFbWJlZGRlZE1lc3NhZ2UoIlwyMDAiLCAxKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGFuIGVuZGdyb3VwIHRhZywgYnV0IHdlIGFyZW4ndCBwYXJzaW5nIGEgZ3JvdXAuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEVtYmVkZGVkTWVzc2FnZSgiXDAxNCIsIDEpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYSB2YWxpZCB2YXJpbnQgYnV0IG5vdCBhIHZhbGlkIHRhZyAoYmFkIHdpcmUgdHlwZSkuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEVtYmVkZGVkTWVzc2FnZSgiXDAxNyIsIDEpKSk7Cit9CisKK1RFU1RfRihXaXJlRm9ybWF0SW52YWxpZElucHV0VGVzdCwgSW52YWxpZEdyb3VwKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICAvLyBDb250cm9sIGNhc2UuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIiIsIDAsIHRydWUpKSk7CisKKyAgLy8gTWlzc2luZyBlbmQgdGFnLiAgR3JvdXBzIGNhbm5vdCBlbmQgYXQgRU9GLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiIiwgMCwgZmFsc2UpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYSB2YWxpZCB2YXJpbnQsIGJ1dCBub3QgYSB2YWxpZCB0YWcgKHplcm8pLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDAiLCAxLCBmYWxzZSkpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhIG1hbGZvcm1lZCB2YXJpbnQuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCJcMjAwIiwgMSwgZmFsc2UpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYW4gZW5kZ3JvdXAgdGFnLCBidXQgbm90IHRoZSByaWdodCBvbmUgZm9yIHRoaXMgZ3JvdXAuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCJcMDE0IiwgMSwgZmFsc2UpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYSB2YWxpZCB2YXJpbnQgYnV0IG5vdCBhIHZhbGlkIHRhZyAoYmFkIHdpcmUgdHlwZSkuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCJcMDE3IiwgMSwgdHJ1ZSkpKTsKK30KKworVEVTVF9GKFdpcmVGb3JtYXRJbnZhbGlkSW5wdXRUZXN0LCBJbnZhbGlkVW5rbm93bkdyb3VwKSB7CisgIC8vIFVzZSBUZXN0RW1wdHlNZXNzYWdlIHNvIHRoYXQgdGhlIGdyb3VwIG1hZGUgYnkgTWFrZUludmFsaWRHcm91cCB3aWxsIG5vdAorICAvLyBiZSBhIGtub3duIHRhZyBudW1iZXIuCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2U7CisKKyAgLy8gQ29udHJvbCBjYXNlLgorICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCIiLCAwLCB0cnVlKSkpOworCisgIC8vIE1pc3NpbmcgZW5kIHRhZy4gIEdyb3VwcyBjYW5ub3QgZW5kIGF0IEVPRi4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIiIsIDAsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50LCBidXQgbm90IGEgdmFsaWQgdGFnICh6ZXJvKS4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIlwwIiwgMSwgZmFsc2UpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYSBtYWxmb3JtZWQgdmFyaW50LgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDIwMCIsIDEsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGFuIGVuZGdyb3VwIHRhZywgYnV0IG5vdCB0aGUgcmlnaHQgb25lIGZvciB0aGlzIGdyb3VwLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDAxNCIsIDEsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50IGJ1dCBub3QgYSB2YWxpZCB0YWcgKGJhZCB3aXJlIHR5cGUpLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDAxNyIsIDEsIHRydWUpKSk7Cit9CisKK1RFU1RfRihXaXJlRm9ybWF0SW52YWxpZElucHV0VGVzdCwgSW52YWxpZFN0cmluZ0luVW5rbm93bkdyb3VwKSB7CisgIC8vIFRlc3QgYSBidWcgZml4OiAgU2tpcE1lc3NhZ2Ugc2hvdWxkIGZhaWwgaWYgdGhlIG1lc3NhZ2UgY29udGFpbnMgYSBzdHJpbmcKKyAgLy8gd2hvc2UgbGVuZ3RoIHdvdWxkIGV4dGVuZCBiZXlvbmQgdGhlIG1lc3NhZ2UgZW5kLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJmb28gZm9vIGZvbyBmb28iKTsKKyAgc3RyaW5nIGRhdGE7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIC8vIENob3Agc29tZSBieXRlcyBvZmYgdGhlIGVuZC4KKyAgZGF0YS5yZXNpemUoZGF0YS5zaXplKCkgLSA0KTsKKworICAvLyBUcnkgdG8gc2tpcCBpdC4gIE5vdGUgdGhhdCB0aGUgYnVnIHdhcyBvbmx5IHByZXNlbnQgd2hlbiBwYXJzaW5nIHRvIGFuCisgIC8vIFVua25vd25GaWVsZFNldC4KKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZyYXdfaW5wdXQpOworICBVbmtub3duRmllbGRTZXQgdW5rbm93bl9maWVsZHM7CisgIEVYUEVDVF9GQUxTRShXaXJlRm9ybWF0OjpTa2lwTWVzc2FnZSgmY29kZWRfaW5wdXQsICZ1bmtub3duX2ZpZWxkcykpOworfQorCisvLyBUZXN0IGRpZmZlcmVuY2VzIGJldHdlZW4gc3RyaW5nIGFuZCBieXRlcy4KKy8vIFZhbHVlIG9mIGEgc3RyaW5nIHR5cGUgbXVzdCBiZSB2YWxpZCBVVEYtOCBzdHJpbmcuICBXaGVuIFVURi04CisvLyB2YWxpZGF0aW9uIGlzIGVuYWJsZWQgKEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRCk6CisvLyBXcml0ZUludmFsaWRVVEY4U3RyaW5nOiAgc2VlIGVycm9yIG1lc3NhZ2UuCisvLyBSZWFkSW52YWxpZFVURjhTdHJpbmc6ICBzZWUgZXJyb3IgbWVzc2FnZS4KKy8vIFdyaXRlVmFsaWRVVEY4U3RyaW5nOiBmaW5lLgorLy8gUmVhZFZhbGlkVVRGOFN0cmluZzogIGZpbmUuCisvLyBXcml0ZUFueUJ5dGVzOiBmaW5lLgorLy8gUmVhZEFueUJ5dGVzOiBmaW5lLgorY29uc3QgY2hhciAqIGtJbnZhbGlkVVRGOFN0cmluZyA9ICJJbnZhbGlkIFVURi04OiBceEEwXHhCMFx4QzBceEQwIjsKKy8vIFRoaXMgdXNlZCB0byBiZSAiVmFsaWQgVVRGLTg6IFx4MDFceDAyXHU4QzM3XHU2QjRDIiwgYnV0IE1TVkMgc2VlbXMgdG8KKy8vIGludGVycHJldCBcdSBkaWZmZXJlbnRseSBmcm9tIEdDQy4KK2NvbnN0IGNoYXIgKiBrVmFsaWRVVEY4U3RyaW5nID0gIlZhbGlkIFVURi04OiBceDAxXHgwMlwzNTBcMjYwXDI2N1wzNDZcMjU1XDIxNCI7CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Citib29sIFdyaXRlTWVzc2FnZShjb25zdCBjaGFyICp2YWx1ZSwgVCAqbWVzc2FnZSwgc3RyaW5nICp3aXJlX2J1ZmZlcikgeworICBtZXNzYWdlLT5zZXRfZGF0YSh2YWx1ZSk7CisgIHdpcmVfYnVmZmVyLT5jbGVhcigpOworICBtZXNzYWdlLT5BcHBlbmRUb1N0cmluZyh3aXJlX2J1ZmZlcik7CisgIHJldHVybiAod2lyZV9idWZmZXItPnNpemUoKSA+IDApOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorYm9vbCBSZWFkTWVzc2FnZShjb25zdCBzdHJpbmcgJndpcmVfYnVmZmVyLCBUICptZXNzYWdlKSB7CisgIHJldHVybiBtZXNzYWdlLT5QYXJzZUZyb21BcnJheSh3aXJlX2J1ZmZlci5kYXRhKCksIHdpcmVfYnVmZmVyLnNpemUoKSk7Cit9CisKK2Jvb2wgU3RhcnRzV2l0aChjb25zdCBzdHJpbmcmIHMsIGNvbnN0IHN0cmluZyYgcHJlZml4KSB7CisgIHJldHVybiBzLnN1YnN0cigwLCBwcmVmaXgubGVuZ3RoKCkpID09IHByZWZpeDsKK30KKworY2xhc3MgVXRmOFZhbGlkYXRpb25UZXN0IDogcHVibGljIDo6dGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBVdGY4VmFsaWRhdGlvblRlc3QoKSB7fQorICB2aXJ0dWFsIH5VdGY4VmFsaWRhdGlvblRlc3QoKSB7fQorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgIH0KKworfTsKKworVEVTVF9GKFV0ZjhWYWxpZGF0aW9uVGVzdCwgV3JpdGVJbnZhbGlkVVRGOFN0cmluZykgeworICBzdHJpbmcgd2lyZV9idWZmZXI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVTdHJpbmcgaW5wdXQ7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgV3JpdGVNZXNzYWdlKGtJbnZhbGlkVVRGOFN0cmluZywgJmlucHV0LCAmd2lyZV9idWZmZXIpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfVVRGOF9WQUxJREFUSU9OX0VOQUJMRUQKKyAgQVNTRVJUX0VRKDEsIGVycm9ycy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShTdGFydHNXaXRoKGVycm9yc1swXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiU3RyaW5nIGZpZWxkICdwcm90b2J1Zl91bml0dGVzdC5PbmVTdHJpbmcuZGF0YScgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJjb250YWlucyBpbnZhbGlkIFVURi04IGRhdGEgd2hlbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgInNlcmlhbGl6aW5nIGEgcHJvdG9jb2wgYnVmZmVyLiBVc2UgdGhlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJ2J5dGVzJyB0eXBlIGlmIHlvdSBpbnRlbmQgdG8gc2VuZCByYXcgYnl0ZXMuIikpOworI2Vsc2UKKyAgQVNTRVJUX0VRKDAsIGVycm9ycy5zaXplKCkpOworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRGOF9WQUxJREFUSU9OX0VOQUJMRUQKK30KKworCitURVNUX0YoVXRmOFZhbGlkYXRpb25UZXN0LCBSZWFkSW52YWxpZFVURjhTdHJpbmcpIHsKKyAgc3RyaW5nIHdpcmVfYnVmZmVyOworICBwcm90b2J1Zl91bml0dGVzdDo6T25lU3RyaW5nIGlucHV0OworICBXcml0ZU1lc3NhZ2Uoa0ludmFsaWRVVEY4U3RyaW5nLCAmaW5wdXQsICZ3aXJlX2J1ZmZlcik7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVTdHJpbmcgb3V0cHV0OworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIFJlYWRNZXNzYWdlKHdpcmVfYnVmZmVyLCAmb3V0cHV0KTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisjaWZkZWYgR09PR0xFX1BST1RPQlVGX1VURjhfVkFMSURBVElPTl9FTkFCTEVECisgIEFTU0VSVF9FUSgxLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUoU3RhcnRzV2l0aChlcnJvcnNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIlN0cmluZyBmaWVsZCAncHJvdG9idWZfdW5pdHRlc3QuT25lU3RyaW5nLmRhdGEnICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiY29udGFpbnMgaW52YWxpZCBVVEYtOCBkYXRhIHdoZW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICJwYXJzaW5nIGEgcHJvdG9jb2wgYnVmZmVyLiBVc2UgdGhlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJ2J5dGVzJyB0eXBlIGlmIHlvdSBpbnRlbmQgdG8gc2VuZCByYXcgYnl0ZXMuIikpOworCisjZWxzZQorICBBU1NFUlRfRVEoMCwgZXJyb3JzLnNpemUoKSk7CisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorfQorCisKK1RFU1RfRihVdGY4VmFsaWRhdGlvblRlc3QsIFdyaXRlVmFsaWRVVEY4U3RyaW5nKSB7CisgIHN0cmluZyB3aXJlX2J1ZmZlcjsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok9uZVN0cmluZyBpbnB1dDsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBXcml0ZU1lc3NhZ2Uoa1ZhbGlkVVRGOFN0cmluZywgJmlucHV0LCAmd2lyZV9idWZmZXIpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKyAgQVNTRVJUX0VRKDAsIGVycm9ycy5zaXplKCkpOworfQorCitURVNUX0YoVXRmOFZhbGlkYXRpb25UZXN0LCBSZWFkVmFsaWRVVEY4U3RyaW5nKSB7CisgIHN0cmluZyB3aXJlX2J1ZmZlcjsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok9uZVN0cmluZyBpbnB1dDsKKyAgV3JpdGVNZXNzYWdlKGtWYWxpZFVURjhTdHJpbmcsICZpbnB1dCwgJndpcmVfYnVmZmVyKTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok9uZVN0cmluZyBvdXRwdXQ7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgUmVhZE1lc3NhZ2Uod2lyZV9idWZmZXIsICZvdXRwdXQpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKyAgQVNTRVJUX0VRKDAsIGVycm9ycy5zaXplKCkpOworICBFWFBFQ1RfRVEoaW5wdXQuZGF0YSgpLCBvdXRwdXQuZGF0YSgpKTsKK30KKworLy8gQnl0ZXM6IGFueXRoaW5nIGNhbiBwYXNzIGFzIGJ5dGVzLCB1c2UgaW52YWxpZCBVVEYtOCBzdHJpbmcgdG8gdGVzdAorVEVTVF9GKFV0ZjhWYWxpZGF0aW9uVGVzdCwgV3JpdGVBcmJpdHJhcnlCeXRlcykgeworICBzdHJpbmcgd2lyZV9idWZmZXI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVCeXRlcyBpbnB1dDsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBXcml0ZU1lc3NhZ2Uoa0ludmFsaWRVVEY4U3RyaW5nLCAmaW5wdXQsICZ3aXJlX2J1ZmZlcik7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorICBBU1NFUlRfRVEoMCwgZXJyb3JzLnNpemUoKSk7Cit9CisKK1RFU1RfRihVdGY4VmFsaWRhdGlvblRlc3QsIFJlYWRBcmJpdHJhcnlCeXRlcykgeworICBzdHJpbmcgd2lyZV9idWZmZXI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVCeXRlcyBpbnB1dDsKKyAgV3JpdGVNZXNzYWdlKGtJbnZhbGlkVVRGOFN0cmluZywgJmlucHV0LCAmd2lyZV9idWZmZXIpOworICBwcm90b2J1Zl91bml0dGVzdDo6T25lQnl0ZXMgb3V0cHV0OworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIFJlYWRNZXNzYWdlKHdpcmVfYnVmZmVyLCAmb3V0cHV0KTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisgIEFTU0VSVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKGlucHV0LmRhdGEoKSwgb3V0cHV0LmRhdGEoKSk7Cit9CisKK1RFU1RfRihVdGY4VmFsaWRhdGlvblRlc3QsIFBhcnNlUmVwZWF0ZWRTdHJpbmcpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok1vcmVCeXRlcyBpbnB1dDsKKyAgaW5wdXQuYWRkX2RhdGEoa1ZhbGlkVVRGOFN0cmluZyk7CisgIGlucHV0LmFkZF9kYXRhKGtJbnZhbGlkVVRGOFN0cmluZyk7CisgIGlucHV0LmFkZF9kYXRhKGtJbnZhbGlkVVRGOFN0cmluZyk7CisgIHN0cmluZyB3aXJlX2J1ZmZlciA9IGlucHV0LlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok1vcmVTdHJpbmcgb3V0cHV0OworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIFJlYWRNZXNzYWdlKHdpcmVfYnVmZmVyLCAmb3V0cHV0KTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisjaWZkZWYgR09PR0xFX1BST1RPQlVGX1VURjhfVkFMSURBVElPTl9FTkFCTEVECisgIEFTU0VSVF9FUSgyLCBlcnJvcnMuc2l6ZSgpKTsKKyNlbHNlCisgIEFTU0VSVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VURjhfVkFMSURBVElPTl9FTkFCTEVECisgIEVYUEVDVF9FUSh3aXJlX2J1ZmZlciwgb3V0cHV0LlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworfQorCisvLyBUZXN0IHRoZSBvbGQgVmVyaWZ5VVRGOFN0cmluZygpIGZ1bmN0aW9uLCB3aGljaCBtYXkgc3RpbGwgYmUgY2FsbGVkIGJ5IG9sZAorLy8gZ2VuZXJhdGVkIGNvZGUuCitURVNUX0YoVXRmOFZhbGlkYXRpb25UZXN0LCBPbGRWZXJpZnlVVEY4U3RyaW5nKSB7CisgIHN0cmluZyBkYXRhKGtJbnZhbGlkVVRGOFN0cmluZyk7CisKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nKGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXQ6OlNFUklBTElaRSk7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorICBBU1NFUlRfRVEoMSwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKFN0YXJ0c1dpdGgoZXJyb3JzWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJpbmcgZmllbGQgY29udGFpbnMgaW52YWxpZCBVVEYtOCBkYXRhIHdoZW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICJzZXJpYWxpemluZyBhIHByb3RvY29sIGJ1ZmZlci4gVXNlIHRoZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIidieXRlcycgdHlwZSBpZiB5b3UgaW50ZW5kIHRvIHNlbmQgcmF3IGJ5dGVzLiIpKTsKKyNlbHNlCisgIEFTU0VSVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyNlbmRpZgorfQorCisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxNjRjMjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnByb3RvCkBAIC0wLDAgKzEsOTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBXcmFwcGVycyBmb3IgcHJpbWl0aXZlIChub24tbWVzc2FnZSkgdHlwZXMuIFRoZXNlIHR5cGVzIGFyZSB1c2VmdWwKKy8vIGZvciBlbWJlZGRpbmcgcHJpbWl0aXZlcyBpbiB0aGUgYGdvb2dsZS5wcm90b2J1Zi5BbnlgIHR5cGUgYW5kIGZvciBwbGFjZXMKKy8vIHdoZXJlIHdlIG5lZWQgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiB0aGUgYWJzZW5jZSBvZiBhIHByaW1pdGl2ZQorLy8gdHlwZWQgZmllbGQgYW5kIGl0cyBkZWZhdWx0IHZhbHVlLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJXcmFwcGVyc1Byb3RvIjsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciBkb3VibGUuCittZXNzYWdlIERvdWJsZVZhbHVlIHsKKyAgLy8gVGhlIGRvdWJsZSB2YWx1ZS4KKyAgZG91YmxlIHZhbHVlID0gMTsKK30KKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciBmbG9hdC4KK21lc3NhZ2UgRmxvYXRWYWx1ZSB7CisgIC8vIFRoZSBmbG9hdCB2YWx1ZS4KKyAgZmxvYXQgdmFsdWUgPSAxOworfQorCisvLyBXcmFwcGVyIG1lc3NhZ2UgZm9yIGludDY0LgorbWVzc2FnZSBJbnQ2NFZhbHVlIHsKKyAgLy8gVGhlIGludDY0IHZhbHVlLgorICBpbnQ2NCB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3IgdWludDY0LgorbWVzc2FnZSBVSW50NjRWYWx1ZSB7CisgIC8vIFRoZSB1aW50NjQgdmFsdWUuCisgIHVpbnQ2NCB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3IgaW50MzIuCittZXNzYWdlIEludDMyVmFsdWUgeworICAvLyBUaGUgaW50MzIgdmFsdWUuCisgIGludDMyIHZhbHVlID0gMTsKK30KKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciB1aW50MzIuCittZXNzYWdlIFVJbnQzMlZhbHVlIHsKKyAgLy8gVGhlIHVpbnQzMiB2YWx1ZS4KKyAgdWludDMyIHZhbHVlID0gMTsKK30KKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciBib29sLgorbWVzc2FnZSBCb29sVmFsdWUgeworICAvLyBUaGUgYm9vbCB2YWx1ZS4KKyAgYm9vbCB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3Igc3RyaW5nLgorbWVzc2FnZSBTdHJpbmdWYWx1ZSB7CisgIC8vIFRoZSBzdHJpbmcgdmFsdWUuCisgIHN0cmluZyB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3IgYnl0ZXMuCittZXNzYWdlIEJ5dGVzVmFsdWUgeworICAvLyBUaGUgYnl0ZXMgdmFsdWUuCisgIGJ5dGVzIHZhbHVlID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9zb2xhcmlzL2xpYnN0ZGMrKy5sYSBiL3NyYy9zb2xhcmlzL2xpYnN0ZGMrKy5sYQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWRmNDI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NvbGFyaXMvbGlic3RkYysrLmxhCkBAIC0wLDAgKzEsNTEgQEAKKyMgbGlic3RkYysrLmxhIC0gYSBsaWJ0b29sIGxpYnJhcnkgZmlsZQorIyBHZW5lcmF0ZWQgYnkgbHRtYWluLnNoIC0gR05VIGxpYnRvb2wgMS40YS1HQ0MzLjAgKDEuNjQxLjIuMjU2IDIwMDEvMDUvMjggMjA6MDk6MDcgd2l0aCBHQ0MtbG9jYWwgY2hhbmdlcykKKyMKKyMgUGxlYXNlIERPIE5PVCBkZWxldGUgdGhpcyBmaWxlIQorIyBJdCBpcyBuZWNlc3NhcnkgZm9yIGxpbmtpbmcgdGhlIGxpYnJhcnkuCisKKyMgLS0tCisjIE5PVEU6IFRoaXMgZmlsZSBsaXZlcyBpbiAvdXNyL3Nmdy9saWIgb24gU29sYXJpcyAxMC4gIFVuZm9ydHVuYXRlbHksCisjIGR1ZSB0byBhbiBhcHBhcmVudCBidWcgaW4gdGhlIFNvbGFyaXMgMTAgNi8wNiByZWxlYXNlLAorIyAvdXNyL3Nmdy9saWIvbGlic3RkYysrLmxhIGlzIGVtcHR5LiAgQmVsb3cgaXMgdGhlIGNvcnJlY3QgY29udGVudCwKKyMgYWNjb3JkaW5nIHRvCisjICAgIGh0dHA6Ly9mb3J1bS5qYXZhLnN1bi5jb20vdGhyZWFkLmpzcGE/dGhyZWFkSUQ9NTA3MzE1MAorIyBCeSBwYXNzaW5nIExERkxBR1M9Jy1Mc3JjL3NvbGFyaXMnIHRvIGNvbmZpZ3VyZSwgbWFrZSB3aWxsIHBpY2sgdXAKKyMgdGhpcyBjb3B5IG9mIHRoZSBmaWxlIHJhdGhlciB0aGFuIHRoZSBlbXB0eSBjb3B5IGluIC91c3Ivc2Z3L2xpYi4KKyMKKyMgQWxzbyBzZWUKKyMgICBodHRwOi8vd3d3LnRlY2huaWNhbGFydGljbGVzLm9yZy9pbmRleC5waHAvQ29tcGlsaW5nX015U1FMXzUuMF9vbl9Tb2xhcmlzXzEwCisjCisjIE5vdGU6IHRoaXMgaXMgZm9yIDMyLWJpdCBzeXN0ZW1zLiAgSWYgeW91IGhhdmUgYSA2NC1iaXQgc3lzdGVtLAorIyB1bmNvbW1lbnQgdGhlIGFwcHJvcHJpYXRlIGRlcGVuZGVuY3lfbGlicyBsaW5lIGJlbG93LgorIyAtLS0tCisKKyMgVGhlIG5hbWUgdGhhdCB3ZSBjYW4gZGxvcGVuKDMpLgorZGxuYW1lPSdsaWJzdGRjKysuc28uNicKKworIyBOYW1lcyBvZiB0aGlzIGxpYnJhcnkuCitsaWJyYXJ5X25hbWVzPSdsaWJzdGRjKysuc28uNi4wLjMgbGlic3RkYysrLnNvLjYgbGlic3RkYysrLnNvJworCisjIFRoZSBuYW1lIG9mIHRoZSBzdGF0aWMgYXJjaGl2ZS4KK29sZF9saWJyYXJ5PSdsaWJzdGRjKysuYScKKworIyBMaWJyYXJpZXMgdGhhdCB0aGlzIG9uZSBkZXBlbmRzIHVwb24uCisjIDMyLWJpdCB2ZXJzaW9uOgorZGVwZW5kZW5jeV9saWJzPSctbGMgLWxtIC1ML3Vzci9zZncvbGliIC1sZ2NjX3MnCisjIDY0LWJpdCB2ZXJzaW9uOgorI2RlcGVuZGVuY3lfbGlicz0nLUwvbGliLzY0IC1sYyAtbG0gLUwvdXNyL3Nmdy9saWIvNjQgLWxnY2NfcycKKworIyBWZXJzaW9uIGluZm9ybWF0aW9uIGZvciBsaWJzdGRjKysuCitjdXJyZW50PTYKK2FnZT0wCityZXZpc2lvbj0zCisKKyMgSXMgdGhpcyBhbiBhbHJlYWR5IGluc3RhbGxlZCBsaWJyYXJ5PworaW5zdGFsbGVkPXllcworCisjIEZpbGVzIHRvIGRsb3Blbi9kbHByZW9wZW4KK2Rsb3Blbj0nJworZGxwcmVvcGVuPScnCisKKyMgRGlyZWN0b3J5IHRoYXQgdGhpcyBsaWJyYXJ5IG5lZWRzIHRvIGJlIGluc3RhbGxlZCBpbjoKK2xpYmRpcj0nL3Vzci9zZncvbGliJwpkaWZmIC0tZ2l0IGEvdnNwcm9qZWN0cy9jb25maWcuaCBiL3ZzcHJvamVjdHMvY29uZmlnLmgKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uYTkzYmIwMwotLS0gL2Rldi9udWxsCisrKyBiL3ZzcHJvamVjdHMvY29uZmlnLmgKQEAgLTAsMCArMSwyMCBAQAorLyogcHJvdG9idWYgY29uZmlnLmggZm9yIE1TVkMuICBPbiBvdGhlciBwbGF0Zm9ybXMsIHRoaXMgaXMgZ2VuZXJhdGVkCisgKiBhdXRvbWF0aWNhbGx5IGJ5IGF1dG9oZWFkZXIgLyBhdXRvY29uZiAvIGNvbmZpZ3VyZS4gKi8KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wYmNvbmZpZy5oPgorCisjZGVmaW5lIEhBU0hfTUFQX0ggR09PR0xFX1BST1RPQlVGX0hBU0hfTUFQX0gKKyNkZWZpbmUgSEFTSF9OQU1FU1BBQ0UgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFCisjZGVmaW5lIEhBU0hfU0VUX0ggR09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0gKKworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9IQVZFX0hBU0hfTUFQCisjZGVmaW5lIEhBVkVfSEFTSF9NQVAgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9NQVAKKyNlbmRpZgorCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9TRVQKKyNkZWZpbmUgSEFWRV9IQVNIX1NFVCBHT09HTEVfUFJPVE9CVUZfSEFWRV9IQVNIX1NFVAorI2VuZGlmCisKKy8qIGRlZmluZSBpZiB5b3Ugd2FudCB0byB1c2UgemxpYi4gIFNlZSByZWFkbWUudHh0IGZvciBhZGRpdGlvbmFsCisgKiByZXF1aXJlbWVudHMuICovCisvLyAjZGVmaW5lIEhBVkVfWkxJQiAxCmRpZmYgLS1naXQgYS92c3Byb2plY3RzL2NvbnZlcnQyMDA4dG8yMDA1LnNoIGIvdnNwcm9qZWN0cy9jb252ZXJ0MjAwOHRvMjAwNS5zaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi42MGVjY2FmCi0tLSAvZGV2L251bGwKKysrIGIvdnNwcm9qZWN0cy9jb252ZXJ0MjAwOHRvMjAwNS5zaApAQCAtMCwwICsxLDIwIEBACisjISAvYmluL3NoIC1lCisKKyMgVGhpcyBzY3JpcHQgZG93bmdyYWRlcyBNU1ZDIDIwMDggcHJvamVjdHMgdG8gTVNWQyAyMDA1IHByb2plY3RzLCBhbGxvd2luZworIyBwZW9wbGUgd2l0aCBNU1ZDIDIwMDUgdG8gb3BlbiB0aGVtLiAgT3RoZXJ3aXNlLCBNU1ZDIDIwMDUgc2ltcGx5IHJlZnVzZXMgdG8KKyMgb3BlbiBwcm9qZWN0cyBjcmVhdGVkIHdpdGggMjAwOC4gIFdlIHJ1biB0aGlzIGFzIHBhcnQgb2Ygb3VyIHJlbGVhc2UgcHJvY2Vzcy4KKyMgSWYgeW91IG9idGFpbmVkIHRoZSBjb2RlIGRpcmVjdCBmcm9tIHZlcnNpb24gY29udHJvbCBhbmQgeW91IHdhbnQgdG8gdXNlCisjIE1TVkMgMjAwNSwgeW91IG1heSBoYXZlIHRvIHJ1biB0aGlzIG1hbnVhbGx5LiAgKEhpbnQ6ICBVc2UgQ3lnd2luIG9yIE1TWVMuKQorCitmb3IgZmlsZSBpbiAqLnNsbjsgZG8KKyAgZWNobyAiZG93bmdyYWRpbmcgJGZpbGUuLi4iCisgIHNlZCAtaSAtcmUgJ3MvRm9ybWF0IFZlcnNpb24gMTAuMDAvRm9ybWF0IFZlcnNpb24gOS4wMC9nOworICAgICAgICAgICAgICBzL1Zpc3VhbCBTdHVkaW8gMjAwOC9WaXN1YWwgU3R1ZGlvIDIwMDUvZzsnICRmaWxlCitkb25lCisKK2ZvciBmaWxlIGluICoudmNwcm9qOyBkbworICBlY2hvICJkb3duZ3JhZGluZyAkZmlsZS4uLiIKKyAgc2VkIC1pIC1yZSAncy9WZXJzaW9uPSI5LjAwIi9WZXJzaW9uPSI4LjAwIi9nOycgJGZpbGUKK2RvbmUKKworIyBZZXMsIHJlYWxseSwgdGhhdCdzIGl0LgpkaWZmIC0tZ2l0IGEvdnNwcm9qZWN0cy9leHRyYWN0X2luY2x1ZGVzLmJhdCBiL3ZzcHJvamVjdHMvZXh0cmFjdF9pbmNsdWRlcy5iYXQKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZGRmN2YzMwotLS0gL2Rldi9udWxsCisrKyBiL3ZzcHJvamVjdHMvZXh0cmFjdF9pbmNsdWRlcy5iYXQKQEAgLTAsMCArMSw4NyBAQAorbWQgaW5jbHVkZQorbWQgaW5jbHVkZVxnb29nbGUKK21kIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmCittZCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVicworbWQgaW5jbHVkZVxnb29nbGVccHJvdG9idWZcaW8KK21kIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyCittZCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHAKK21kIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmEKK21kIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vCittZCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxweXRob24KK21kIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHJ1YnkKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxhcmVuYS5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGFyZW5hLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxhcmVuYXN0cmluZy5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGFyZW5hc3RyaW5nLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjb2RlX2dlbmVyYXRvci5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNvZGVfZ2VuZXJhdG9yLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjb21tYW5kX2xpbmVfaW50ZXJmYWNlLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY29tbWFuZF9saW5lX2ludGVyZmFjZS5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9nZW5lcmF0b3IuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2dlbmVyYXRvci5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcaW1wb3J0ZXIuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxpbXBvcnRlci5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2dlbmVyYXRvci5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9nZW5lcmF0b3IuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX2dlbmVyYXRvci5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX2dlbmVyYXRvci5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccGFyc2VyLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcY29tcGlsZXJccGFyc2VyLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxwbHVnaW4uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxwbHVnaW4uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHBsdWdpbi5wYi5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHBsdWdpbi5wYi5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccHl0aG9uXHB5dGhvbl9nZW5lcmF0b3IuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxweXRob25ccHl0aG9uX2dlbmVyYXRvci5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccnVieVxydWJ5X2dlbmVyYXRvci5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHJ1YnlccnVieV9nZW5lcmF0b3IuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGRlc2NyaXB0b3JfZGF0YWJhc2UuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxkZXNjcmlwdG9yX2RhdGFiYXNlLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxkZXNjcmlwdG9yLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcZGVzY3JpcHRvci5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcZGVzY3JpcHRvci5wYi5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGRlc2NyaXB0b3IucGIuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGR5bmFtaWNfbWVzc2FnZS5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGR5bmFtaWNfbWVzc2FnZS5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcZXh0ZW5zaW9uX3NldC5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGV4dGVuc2lvbl9zZXQuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGdlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxnZW5lcmF0ZWRfZW51bV9yZWZsZWN0aW9uLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxnZW5lcmF0ZWRfZW51bV91dGlsLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcZ2VuZXJhdGVkX2VudW1fdXRpbC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGdlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGdlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxnZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xjb2RlZF9zdHJlYW0uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxpb1xjb2RlZF9zdHJlYW0uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGd6aXBfc3RyZWFtLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcaW9cZ3ppcF9zdHJlYW0uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHByaW50ZXIuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxpb1xwcmludGVyLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xzdHJ0b2QuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxpb1xzdHJ0b2QuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHRva2VuaXplci5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGlvXHRva2VuaXplci5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cemVyb19jb3B5X3N0cmVhbS5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW0uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW1faW1wbC5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW1faW1wbC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlxpb1x6ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcbWFwX2VudHJ5LmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcbWFwX2VudHJ5LmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfZW50cnlfbGl0ZS5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXG1hcF9lbnRyeV9saXRlLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfZmllbGQuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxtYXBfZmllbGQuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF9maWVsZF9saXRlLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcbWFwX2ZpZWxkX2xpdGUuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF9maWVsZF9pbmwuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxtYXBfZmllbGRfaW5sLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXAuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxtYXAuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF90eXBlX2hhbmRsZXIuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxtYXBfdHlwZV9oYW5kbGVyLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtZXNzYWdlLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcbWVzc2FnZS5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcbWVzc2FnZV9saXRlLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcbWVzc2FnZV9saXRlLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtZXRhZGF0YS5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXG1ldGFkYXRhLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxyZWZsZWN0aW9uLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZccmVmbGVjdGlvbi5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZccmVmbGVjdGlvbl9vcHMuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxyZWZsZWN0aW9uX29wcy5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZccmVwZWF0ZWRfZmllbGQuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxyZXBlYXRlZF9maWVsZC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZccmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbi5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHJlcGVhdGVkX2ZpZWxkX3JlZmxlY3Rpb24uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHNlcnZpY2UuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzZXJ2aWNlLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHMuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHMuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfYWl4LmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19haXguaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfYXJtNjRfZ2NjLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19hcm02NF9nY2MuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfYXJtX2djYy5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfYXJtX2djYy5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19hcm1fcW54LmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19hcm1fcW54LmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHNfaW50ZXJuYWxzX2F0b21pY3dvcmRfY29tcGF0LmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19hdG9taWN3b3JkX2NvbXBhdC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19nZW5lcmljX2djYy5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfbWFjb3N4LmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19tYWNvc3guaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfbWlwc19nY2MuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHNfaW50ZXJuYWxzX21pcHNfZ2NjLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHNfaW50ZXJuYWxzX3BuYWNsLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19wbmFjbC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHNfaW50ZXJuYWxzX3RzYW4uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHNfaW50ZXJuYWxzX3RzYW4uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY19zZXF1ZW5jZV9udW0uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNfc2VxdWVuY2VfbnVtLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xjYXN0cy5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGNhc3RzLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xjb21tb24uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xjb21tb24uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGZhc3RtZW0uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xmYXN0bWVtLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xvbmNlLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcb25jZS5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNccGxhdGZvcm1fbWFjcm9zLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNccGxhdGZvcm1fbWFjcm9zLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzaW5nbGV0b24uaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzaW5nbGV0b24uaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGhhc2guaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xoYXNoLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdGxfdXRpbC5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXHN0bF91dGlsLmgKK2NvcHkgLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1x0ZW1wbGF0ZV91dGlsLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcc3R1YnNcdGVtcGxhdGVfdXRpbC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcdHlwZV90cmFpdHMuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1x0eXBlX3RyYWl0cy5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcdGV4dF9mb3JtYXQuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlx0ZXh0X2Zvcm1hdC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5rbm93bl9maWVsZF9zZXQuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlx1bmtub3duX2ZpZWxkX3NldC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcd2lyZV9mb3JtYXQuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1Zlx3aXJlX2Zvcm1hdC5oCitjb3B5IC4uXHNyY1xnb29nbGVccHJvdG9idWZcd2lyZV9mb3JtYXRfbGl0ZS5oIGluY2x1ZGVcZ29vZ2xlXHByb3RvYnVmXHdpcmVfZm9ybWF0X2xpdGUuaAorY29weSAuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHdpcmVfZm9ybWF0X2xpdGVfaW5sLmggaW5jbHVkZVxnb29nbGVccHJvdG9idWZcd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaAorY29weSBnb29nbGVccHJvdG9idWZcc3R1YnNccGJjb25maWcuaCBpbmNsdWRlXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xwYmNvbmZpZy5oCmRpZmYgLS1naXQgYS92c3Byb2plY3RzL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9wYmNvbmZpZy5oIGIvdnNwcm9qZWN0cy9nb29nbGUvcHJvdG9idWYvc3R1YnMvcGJjb25maWcuaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4xODI1MGEyCi0tLSAvZGV2L251bGwKKysrIGIvdnNwcm9qZWN0cy9nb29nbGUvcHJvdG9idWYvc3R1YnMvcGJjb25maWcuaApAQCAtMCwwICsxLDM5IEBACisvKiBwcm90b2J1ZiBjb25maWcuaCBmb3IgTVNWQy4gIE9uIG90aGVyIHBsYXRmb3JtcywgdGhpcyBpcyBnZW5lcmF0ZWQKKyAqIGF1dG9tYXRpY2FsbHkgYnkgYXV0b2hlYWRlciAvIGF1dG9jb25mIC8gY29uZmlndXJlLiAqLworCisvLyBOT1RFOiBpZiB5b3UgYWRkIG5ldyBtYWNyb3MgaW4gdGhpcyBmaWxlIG1hbnVhbGx5LCBwbGVhc2UgcHJvcGFnYXRlIHRoZSBtYWNybworLy8gdG8gdnNwcm9qZWN0cy9jb25maWcuaC4KKworLyogdGhlIG5hbWVzcGFjZSBvZiBoYXNoX21hcC9oYXNoX3NldCAqLworLy8gQXBwYXJlbnRseSBNaWNyb3NvZnQgZGVjaWRlZCB0byBtb3ZlIGhhc2hfbWFwICpiYWNrKiB0byB0aGUgc3RkIG5hbWVzcGFjZQorLy8gaW4gTVNWQyAyMDEwOgorLy8gICBodHRwOi8vYmxvZ3MubXNkbi5jb20vdmNibG9nL2FyY2hpdmUvMjAwOS8wNS8yNS9zdGwtYnJlYWtpbmctY2hhbmdlcy1pbi12aXN1YWwtc3R1ZGlvLTIwMTAtYmV0YS0xLmFzcHgKKy8vIEFuZC4uIHRoZXkgYXJlIG1vdmVkIGJhY2sgdG8gc3RkZXh0IGluIE1TVkMgMjAxMyAoaGF2ZW4ndCBjaGVja2VkIDIwMTIpLiBUaGF0CisvLyBzYWlkLCB1c2UgdW5vcmRlcmVkX21hcCBmb3IgTVNWQyAyMDEwIGFuZCBiZXlvbmQgaXMgb3VyIHNhZmVzdCBiZXQuCisjaWYgX01TQ19WRVIgPj0gMTYwMAorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0Ugc3RkCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9IIDx1bm9yZGVyZWRfbWFwPgorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1MgdW5vcmRlcmVkX21hcAorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9TRVRfSCA8dW5vcmRlcmVkX3NldD4KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTIHVub3JkZXJlZF9zZXQKKyNlbGlmIF9NU0NfVkVSID49IDEzMTAKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFIHN0ZGV4dAorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfSCA8aGFzaF9tYXA+CisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9DTEFTUyBoYXNoX21hcAorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9TRVRfSCA8aGFzaF9zZXQ+CisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX1NFVF9DTEFTUyBoYXNoX3NldAorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFIHN0ZAorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfSCA8aGFzaF9tYXA+CisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9DTEFTUyBoYXNoX21hcAorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9TRVRfSCA8aGFzaF9zZXQ+CisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX1NFVF9DTEFTUyBoYXNoX3NldAorI2VuZGlmCisKKy8qIHRoZSBsb2NhdGlvbiBvZiA8aGFzaF9zZXQ+ICovCisKKy8qIGRlZmluZSBpZiB0aGUgY29tcGlsZXIgaGFzIGhhc2hfbWFwICovCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVZFX0hBU0hfTUFQIDEKKworLyogZGVmaW5lIGlmIHRoZSBjb21waWxlciBoYXMgaGFzaF9zZXQgKi8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9TRVQgMQpkaWZmIC0tZ2l0IGEvdnNwcm9qZWN0cy9saWJwcm90b2J1Zi1saXRlLnZjcHJvaiBiL3ZzcHJvamVjdHMvbGlicHJvdG9idWYtbGl0ZS52Y3Byb2oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI0NTQ0OAotLS0gL2Rldi9udWxsCisrKyBiL3ZzcHJvamVjdHMvbGlicHJvdG9idWYtbGl0ZS52Y3Byb2oKQEAgLTAsMCArMSwzMjEgQEAKK++7vzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8VmlzdWFsU3R1ZGlvUHJvamVjdAorCVByb2plY3RUeXBlPSJWaXN1YWwgQysrIgorCVZlcnNpb249IjkuMDAiCisJTmFtZT0ibGlicHJvdG9idWYtbGl0ZSIKKwlQcm9qZWN0R1VJRD0iezQ5RUEwMTBELTcwNkYtNEJFMi1BMzk3LTc3ODU0QjcyQTA0MH0iCisJS2V5d29yZD0iV2luMzJQcm9qIgorCVRhcmdldEZyYW1ld29ya1ZlcnNpb249IjAiCisJPgorCTxQbGF0Zm9ybXM+CisJCTxQbGF0Zm9ybQorCQkJTmFtZT0iV2luMzIiCisJCS8+CisJPC9QbGF0Zm9ybXM+CisJPFRvb2xGaWxlcz4KKwk8L1Rvb2xGaWxlcz4KKwk8Q29uZmlndXJhdGlvbnM+CisJCTxDb25maWd1cmF0aW9uCisJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iRGVidWciCisJCQlJbnRlcm1lZGlhdGVEaXJlY3Rvcnk9IiQoT3V0RGlyKVwkKFByb2plY3ROYW1lKSIKKwkJCUNvbmZpZ3VyYXRpb25UeXBlPSI0IgorCQkJPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1ByZUJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1hNTERhdGFHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNXZWJTZXJ2aWNlUHJveHlHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNSURMVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ0xDb21waWxlclRvb2wiCisJCQkJQWRkaXRpb25hbE9wdGlvbnM9Ii93ZDQyNDQgL3dkNDI2NyAvd2Q0MDE4IC93ZDQzNTUgL3dkNDgwMCAvd2Q0MjUxIC93ZDQ5OTYgL3dkNDE0NiAvd2Q0MzA1IgorCQkJCU9wdGltaXphdGlvbj0iMCIKKwkJCQlBZGRpdGlvbmFsSW5jbHVkZURpcmVjdG9yaWVzPSIuLi9zcmM7LiIKKwkJCQlQcmVwcm9jZXNzb3JEZWZpbml0aW9ucz0iV0lOMzI7X0RFQlVHO19XSU5ET1dTO19VU1JETEw7TElCUFJPVE9CVUZfRVhQT1JUUzsiCisJCQkJTWluaW1hbFJlYnVpbGQ9InRydWUiCisJCQkJQmFzaWNSdW50aW1lQ2hlY2tzPSIzIgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIzIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iNCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlicmFyaWFuVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQUxpbmtUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCQk8Q29uZmlndXJhdGlvbgorCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iUmVsZWFzZSIKKwkJCUludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorCQkJQ29uZmlndXJhdGlvblR5cGU9IjQiCisJCQk+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlQnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1dlYlNlcnZpY2VQcm94eUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01JRExUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKwkJCQlBZGRpdGlvbmFsT3B0aW9ucz0iL3dkNDI0NCAvd2Q0MjY3IC93ZDQwMTggL3dkNDM1NSAvd2Q0ODAwIC93ZDQyNTEgL3dkNDk5NiAvd2Q0MTQ2IC93ZDQzMDUiCisJCQkJQWRkaXRpb25hbEluY2x1ZGVEaXJlY3Rvcmllcz0iLi4vc3JjOy4iCisJCQkJUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO05ERUJVRztfV0lORE9XUztfVVNSRExMO0xJQlBST1RPQlVGX0VYUE9SVFM7IgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIyIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iMyIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlicmFyaWFuVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQUxpbmtUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCTwvQ29uZmlndXJhdGlvbnM+CisJPFJlZmVyZW5jZXM+CisJPC9SZWZlcmVuY2VzPgorCTxGaWxlcz4KKwkJPEZpbHRlcgorCQkJTmFtZT0iSGVhZGVyIEZpbGVzIgorCQkJRmlsdGVyPSJoO2hwcDtoeHg7aG07aW5sO2luYzt4c2QiCisJCQlVbmlxdWVJZGVudGlmaWVyPSJ7OTM5OTUzODAtODlCRC00YjA0LTg4RUItNjI1RkJFNTJFQkZCfSIKKwkJCT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGNvZGVkX3N0cmVhbS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGNvZGVkX3N0cmVhbV9pbmwuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xjb21tb24uaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxjb25maWcuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcc3R1YnNccGJjb25maWcuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxleHRlbnNpb25fc2V0LmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGhhc2guaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xtYXAtdXRpbC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxnZW5lcmF0ZWRfZW51bV91dGlsLmgiPjwvRmlsZT4KKwkJCTxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfZW50cnlfbGl0ZS5oIj48L0ZpbGU+CisJCQk8RmlsZSBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWFwX2ZpZWxkX2xpdGUuaCI+PC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWVzc2FnZV9saXRlLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcb25jZS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wcy5oIgorCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oIgorCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNccGxhdGZvcm1fbWFjcm9zLmgiCisJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxyZXBlYXRlZF9maWVsZC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXHN0bF91dGlsLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcd2lyZV9mb3JtYXRfbGl0ZS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHdpcmVfZm9ybWF0X2xpdGVfaW5sLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cemVyb19jb3B5X3N0cmVhbS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3RyaW5ncHJpbnRmLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcdGVtcGxhdGVfdXRpbC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXHR5cGVfdHJhaXRzLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQk8L0ZpbHRlcj4KKwkJPEZpbHRlcgorCQkJTmFtZT0iUmVzb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9InJjO2ljbztjdXI7Ym1wO2RsZztyYzI7cmN0O2JpbjtyZ3M7Z2lmO2pwZztqcGVnO2pwZTtyZXN4IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezY3REE2QUI2LUY4MDAtNGMwOC04QjdBLTgzQkIxMjFBQUQwMX0iCisJCQk+CisJCTwvRmlsdGVyPgorCQk8RmlsdGVyCisJCQlOYW1lPSJTb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9ImNwcDtjO2NjO2N4eDtkZWY7b2RsO2lkbDtocGo7YmF0O2FzbTthc214IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezRGQzczN0YxLUM3QTUtNDM3Ni1BMDY2LTJBMzJENzUyQTJGRn0iCisJCQk+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xhdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xjb21tb24uY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcb25jZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdHJpbmdwcmludGYuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcYXJlbmEuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcYXJlbmFzdHJpbmcuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZXh0ZW5zaW9uX3NldC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxnZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1lc3NhZ2VfbGl0ZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxyZXBlYXRlZF9maWVsZC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx3aXJlX2Zvcm1hdF9saXRlLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGNvZGVkX3N0cmVhbS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1x6ZXJvX2NvcHlfc3RyZWFtLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJPC9GaWx0ZXI+CisJPC9GaWxlcz4KKwk8R2xvYmFscz4KKwk8L0dsb2JhbHM+Cis8L1Zpc3VhbFN0dWRpb1Byb2plY3Q+CmRpZmYgLS1naXQgYS92c3Byb2plY3RzL2xpYnByb3RvYnVmLnZjcHJvaiBiL3ZzcHJvamVjdHMvbGlicHJvdG9idWYudmNwcm9qCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3ODI4ODUKLS0tIC9kZXYvbnVsbAorKysgYi92c3Byb2plY3RzL2xpYnByb3RvYnVmLnZjcHJvagpAQCAtMCwwICsxLDUwNSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzxWaXN1YWxTdHVkaW9Qcm9qZWN0CisJUHJvamVjdFR5cGU9IlZpc3VhbCBDKysiCisJVmVyc2lvbj0iOS4wMCIKKwlOYW1lPSJsaWJwcm90b2J1ZiIKKwlQcm9qZWN0R1VJRD0iezNFMjgzRjM3LUE0RUQtNDFCNy1BM0U2LUEyRDg5RDEzMUEzMH0iCisJS2V5d29yZD0iV2luMzJQcm9qIgorCVRhcmdldEZyYW1ld29ya1ZlcnNpb249IjAiCisJPgorCTxQbGF0Zm9ybXM+CisJCTxQbGF0Zm9ybQorCQkJTmFtZT0iV2luMzIiCisJCS8+CisJPC9QbGF0Zm9ybXM+CisJPFRvb2xGaWxlcz4KKwk8L1Rvb2xGaWxlcz4KKwk8Q29uZmlndXJhdGlvbnM+CisJCTxDb25maWd1cmF0aW9uCisJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iRGVidWciCisJCQlJbnRlcm1lZGlhdGVEaXJlY3Rvcnk9IiQoT3V0RGlyKVwkKFByb2plY3ROYW1lKSIKKwkJCUNvbmZpZ3VyYXRpb25UeXBlPSI0IgorCQkJPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1ByZUJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1hNTERhdGFHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNXZWJTZXJ2aWNlUHJveHlHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNSURMVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ0xDb21waWxlclRvb2wiCisJCQkJQWRkaXRpb25hbE9wdGlvbnM9Ii93ZDQyNDQgL3dkNDI2NyAvd2Q0MDE4IC93ZDQzNTUgL3dkNDgwMCAvd2Q0MjUxIC93ZDQ5OTYgL3dkNDE0NiAvd2Q0MzA1IgorCQkJCU9wdGltaXphdGlvbj0iMCIKKwkJCQlBZGRpdGlvbmFsSW5jbHVkZURpcmVjdG9yaWVzPSIuLi9zcmM7LiIKKwkJCQlQcmVwcm9jZXNzb3JEZWZpbml0aW9ucz0iV0lOMzI7X0RFQlVHO19XSU5ET1dTO19VU1JETEw7TElCUFJPVE9CVUZfRVhQT1JUUzsiCisJCQkJTWluaW1hbFJlYnVpbGQ9InRydWUiCisJCQkJQmFzaWNSdW50aW1lQ2hlY2tzPSIzIgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIzIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iNCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlicmFyaWFuVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQUxpbmtUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCQk8Q29uZmlndXJhdGlvbgorCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iUmVsZWFzZSIKKwkJCUludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorCQkJQ29uZmlndXJhdGlvblR5cGU9IjQiCisJCQk+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlQnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1dlYlNlcnZpY2VQcm94eUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01JRExUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKwkJCQlBZGRpdGlvbmFsT3B0aW9ucz0iL3dkNDI0NCAvd2Q0MjY3IC93ZDQwMTggL3dkNDM1NSAvd2Q0ODAwIC93ZDQyNTEgL3dkNDk5NiAvd2Q0MTQ2IC93ZDQzMDUiCisJCQkJQWRkaXRpb25hbEluY2x1ZGVEaXJlY3Rvcmllcz0iLi4vc3JjOy4iCisJCQkJUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO05ERUJVRztfV0lORE9XUztfVVNSRExMO0xJQlBST1RPQlVGX0VYUE9SVFM7IgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIyIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iMyIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlicmFyaWFuVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQUxpbmtUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCTwvQ29uZmlndXJhdGlvbnM+CisJPFJlZmVyZW5jZXM+CisJPC9SZWZlcmVuY2VzPgorCTxGaWxlcz4KKwkJPEZpbHRlcgorCQkJTmFtZT0iSGVhZGVyIEZpbGVzIgorCQkJRmlsdGVyPSJoO2hwcDtoeHg7aG07aW5sO2luYzt4c2QiCisJCQlVbmlxdWVJZGVudGlmaWVyPSJ7OTM5OTUzODAtODlCRC00YjA0LTg4RUItNjI1RkJFNTJFQkZCfSIKKwkJCT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGNvZGVkX3N0cmVhbS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGNvZGVkX3N0cmVhbV9pbmwuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xjb21tb24uaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxjb25maWcuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcc3R1YnNccGJjb25maWcuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxkZXNjcmlwdG9yLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZGVzY3JpcHRvci5wYi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGRlc2NyaXB0b3JfZGF0YWJhc2UuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxkeW5hbWljX21lc3NhZ2UuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxleHRlbnNpb25fc2V0LmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGdlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xnemlwX3N0cmVhbS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xzdHJ0b2QuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xoYXNoLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcaW1wb3J0ZXIuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xtYXBfdXRpbC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1lc3NhZ2UuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtZXNzYWdlX2xpdGUuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZSBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZ2VuZXJhdGVkX2VudW1fdXRpbC5oIj48L0ZpbGU+CisJCQk8RmlsZSBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWFwX2VudHJ5X2xpdGUuaCI+PC9GaWxlPgorCQkJPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF9maWVsZF9saXRlLmgiPjwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wcy5oIgorCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oIgorCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNccGxhdGZvcm1fbWFjcm9zLmgiCisJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xvbmNlLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccGFyc2VyLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9ccHJpbnRlci5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHJlZmxlY3Rpb25fb3BzLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZccmVwZWF0ZWRfZmllbGQuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzZXJ2aWNlLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3RsX3V0aWwuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdHJpbmdwcmludGYuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1x0ZW1wbGF0ZV91dGlsLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcdHlwZV90cmFpdHMuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdHJ1dGlsLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3Vic3RpdHV0ZS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRleHRfZm9ybWF0LmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cdG9rZW5pemVyLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5rbm93bl9maWVsZF9zZXQuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx3aXJlX2Zvcm1hdC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHdpcmVfZm9ybWF0X2xpdGUuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx3aXJlX2Zvcm1hdF9saXRlX2lubC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW0uaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1x6ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1x6ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJPC9GaWx0ZXI+CisJCTxGaWx0ZXIKKwkJCU5hbWU9IlJlc291cmNlIEZpbGVzIgorCQkJRmlsdGVyPSJyYztpY287Y3VyO2JtcDtkbGc7cmMyO3JjdDtiaW47cmdzO2dpZjtqcGc7anBlZztqcGU7cmVzeCIKKwkJCVVuaXF1ZUlkZW50aWZpZXI9Ins2N0RBNkFCNi1GODAwLTRjMDgtOEI3QS04M0JCMTIxQUFEMDF9IgorCQkJPgorCQk8L0ZpbHRlcj4KKwkJPEZpbHRlcgorCQkJTmFtZT0iU291cmNlIEZpbGVzIgorCQkJRmlsdGVyPSJjcHA7YztjYztjeHg7ZGVmO29kbDtpZGw7aHBqO2JhdDthc207YXNteCIKKwkJCVVuaXF1ZUlkZW50aWZpZXI9Ins0RkM3MzdGMS1DN0E1LTQzNzYtQTA2Ni0yQTMyRDc1MkEyRkZ9IgorCQkJPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcYXRvbWljb3BzX2ludGVybmFsc194ODZfZ2NjLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGF0b21pY29wc19pbnRlcm5hbHNfeDg2X21zdmMuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcY29tbW9uLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXG9uY2UuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3RyaW5ncHJpbnRmLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGFyZW5hLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGFyZW5hc3RyaW5nLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGV4dGVuc2lvbl9zZXQuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfZmllbGQuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWVzc2FnZV9saXRlLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHJlcGVhdGVkX2ZpZWxkLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHdpcmVfZm9ybWF0X2xpdGUuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cY29kZWRfc3RyZWFtLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHplcm9fY29weV9zdHJlYW0uY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3RydXRpbC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdHJ1dGlsLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3Vic3RpdHV0ZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdWJzdGl0dXRlLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3RydWN0dXJhbGx5X3ZhbGlkLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGRlc2NyaXB0b3IuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZGVzY3JpcHRvcl9kYXRhYmFzZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxkZXNjcmlwdG9yLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGR5bmFtaWNfbWVzc2FnZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxleHRlbnNpb25fc2V0X2hlYXZ5LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGdlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWVzc2FnZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxyZWZsZWN0aW9uX2ludGVybmFsLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZccmVmbGVjdGlvbl9vcHMuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc2VydmljZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx0ZXh0X2Zvcm1hdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx1bmtub3duX2ZpZWxkX3NldC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx3aXJlX2Zvcm1hdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xnemlwX3N0cmVhbS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xwcmludGVyLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHN0cnRvZC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1x0b2tlbml6ZXIuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcaW9cemVyb19jb3B5X3N0cmVhbV9pbXBsLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGltcG9ydGVyLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHBhcnNlci5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCTwvRmlsdGVyPgorCTwvRmlsZXM+CisJPEdsb2JhbHM+CisJPC9HbG9iYWxzPgorPC9WaXN1YWxTdHVkaW9Qcm9qZWN0PgpkaWZmIC0tZ2l0IGEvdnNwcm9qZWN0cy9saWJwcm90b2MudmNwcm9qIGIvdnNwcm9qZWN0cy9saWJwcm90b2MudmNwcm9qCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1NWMyY2MKLS0tIC9kZXYvbnVsbAorKysgYi92c3Byb2plY3RzL2xpYnByb3RvYy52Y3Byb2oKQEAgLTAsMCArMSw1NDIgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8VmlzdWFsU3R1ZGlvUHJvamVjdAorICBQcm9qZWN0VHlwZT0iVmlzdWFsIEMrKyIKKyAgVmVyc2lvbj0iOS4wMCIKKyAgTmFtZT0ibGlicHJvdG9jIgorICBQcm9qZWN0R1VJRD0ie0I4NEZGMzFBLTVGOUEtNDZGOC1BQjIyLURCRkM5QkVDRTNCRX0iCisgIEtleXdvcmQ9IldpbjMyUHJvaiIKKyAgVGFyZ2V0RnJhbWV3b3JrVmVyc2lvbj0iMCIKKyAgPgorICA8UGxhdGZvcm1zPgorICAgIDxQbGF0Zm9ybQorICAgICAgTmFtZT0iV2luMzIiCisgICAgLz4KKyAgPC9QbGF0Zm9ybXM+CisgIDxUb29sRmlsZXM+CisgIDwvVG9vbEZpbGVzPgorICA8Q29uZmlndXJhdGlvbnM+CisgICAgPENvbmZpZ3VyYXRpb24KKyAgICAgIE5hbWU9IkRlYnVnfFdpbjMyIgorICAgICAgT3V0cHV0RGlyZWN0b3J5PSJEZWJ1ZyIKKyAgICAgIEludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorICAgICAgQ29uZmlndXJhdGlvblR5cGU9IjQiCisgICAgICA+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ1ByZUJ1aWxkRXZlbnRUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNXZWJTZXJ2aWNlUHJveHlHZW5lcmF0b3JUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDTUlETFRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKyAgICAgICAgQWRkaXRpb25hbE9wdGlvbnM9Ii93ZDQyNDQgL3dkNDI2NyAvd2Q0MDE4IC93ZDQzNTUgL3dkNDgwMCAvd2Q0MjUxIC93ZDQ5OTYgL3dkNDE0NiAvd2Q0MzA1IgorICAgICAgICBPcHRpbWl6YXRpb249IjAiCisgICAgICAgIEFkZGl0aW9uYWxJbmNsdWRlRGlyZWN0b3JpZXM9Ii4uL3NyYzsuIgorICAgICAgICBQcmVwcm9jZXNzb3JEZWZpbml0aW9ucz0iV0lOMzI7X0RFQlVHO19XSU5ET1dTO19VU1JETEw7TElCUFJPVE9DX0VYUE9SVFM7IgorICAgICAgICBNaW5pbWFsUmVidWlsZD0idHJ1ZSIKKyAgICAgICAgQmFzaWNSdW50aW1lQ2hlY2tzPSIzIgorICAgICAgICBSdW50aW1lTGlicmFyeT0iMyIKKyAgICAgICAgVXNlUHJlY29tcGlsZWRIZWFkZXI9IjAiCisgICAgICAgIFdhcm5pbmdMZXZlbD0iMyIKKyAgICAgICAgRGV0ZWN0NjRCaXRQb3J0YWJpbGl0eVByb2JsZW1zPSJ0cnVlIgorICAgICAgICBEZWJ1Z0luZm9ybWF0aW9uRm9ybWF0PSI0IgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDUmVzb3VyY2VDb21waWxlclRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNQcmVMaW5rRXZlbnRUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDTGlicmFyaWFuVG9vbCIKKyAgICAgIC8+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ0FMaW5rVG9vbCIKKyAgICAgIC8+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ1hEQ01ha2VUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDQnNjTWFrZVRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNGeENvcFRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNQb3N0QnVpbGRFdmVudFRvb2wiCisgICAgICAvPgorICAgIDwvQ29uZmlndXJhdGlvbj4KKyAgICA8Q29uZmlndXJhdGlvbgorICAgICAgTmFtZT0iUmVsZWFzZXxXaW4zMiIKKyAgICAgIE91dHB1dERpcmVjdG9yeT0iUmVsZWFzZSIKKyAgICAgIEludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorICAgICAgQ29uZmlndXJhdGlvblR5cGU9IjQiCisgICAgICA+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ1ByZUJ1aWxkRXZlbnRUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNXZWJTZXJ2aWNlUHJveHlHZW5lcmF0b3JUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDTUlETFRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKyAgICAgICAgQWRkaXRpb25hbE9wdGlvbnM9Ii93ZDQyNDQgL3dkNDI2NyAvd2Q0MDE4IC93ZDQzNTUgL3dkNDgwMCAvd2Q0MjUxIC93ZDQ5OTYgL3dkNDE0NiAvd2Q0MzA1IgorICAgICAgICBBZGRpdGlvbmFsSW5jbHVkZURpcmVjdG9yaWVzPSIuLi9zcmM7LiIKKyAgICAgICAgUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO05ERUJVRztfV0lORE9XUztfVVNSRExMO0xJQlBST1RPQ19FWFBPUlRTOyIKKyAgICAgICAgUnVudGltZUxpYnJhcnk9IjIiCisgICAgICAgIFVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorICAgICAgICBXYXJuaW5nTGV2ZWw9IjMiCisgICAgICAgIERldGVjdDY0Qml0UG9ydGFiaWxpdHlQcm9ibGVtcz0idHJ1ZSIKKyAgICAgICAgRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iMyIKKyAgICAgIC8+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ01hbmFnZWRSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKyAgICAgIC8+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ1Jlc291cmNlQ29tcGlsZXJUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKyAgICAgIC8+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ0xpYnJhcmlhblRvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNBTGlua1Rvb2wiCisgICAgICAvPgorICAgICAgPFRvb2wKKyAgICAgICAgTmFtZT0iVkNYRENNYWtlVG9vbCIKKyAgICAgIC8+CisgICAgICA8VG9vbAorICAgICAgICBOYW1lPSJWQ0JzY01ha2VUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDRnhDb3BUb29sIgorICAgICAgLz4KKyAgICAgIDxUb29sCisgICAgICAgIE5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorICAgICAgLz4KKyAgICA8L0NvbmZpZ3VyYXRpb24+CisgIDwvQ29uZmlndXJhdGlvbnM+CisgIDxSZWZlcmVuY2VzPgorICA8L1JlZmVyZW5jZXM+CisgIDxGaWxlcz4KKyAgICA8RmlsdGVyCisgICAgICBOYW1lPSJIZWFkZXIgRmlsZXMiCisgICAgICBGaWx0ZXI9Img7aHBwO2h4eDtobTtpbmw7aW5jO3hzZCIKKyAgICAgIFVuaXF1ZUlkZW50aWZpZXI9Ins5Mzk5NTM4MC04OUJELTRiMDQtODhFQi02MjVGQkU1MkVCRkJ9IgorICAgICAgPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNvZGVfZ2VuZXJhdG9yLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjb21tYW5kX2xpbmVfaW50ZXJmYWNlLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxzdWJwcm9jZXNzLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclx6aXBfd3JpdGVyLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxwbHVnaW4uaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHBsdWdpbi5wYi5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9lbnVtLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2VudW1fZmllbGQuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfZXh0ZW5zaW9uLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2ZpbGUuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfZ2VuZXJhdG9yLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2hlbHBlcnMuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfbWVzc2FnZS5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9tZXNzYWdlX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX29wdGlvbnMuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfcHJpbWl0aXZlX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX3NlcnZpY2UuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfc3RyaW5nX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfY29udGV4dC5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2VudW0uaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9lbnVtX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZXh0ZW5zaW9uLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZmllbGQuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9maWxlLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZ2VuZXJhdG9yLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9oZWxwZXJzLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfbGF6eV9tZXNzYWdlX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfbWVzc2FnZS5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX21lc3NhZ2VfZmllbGQuaCIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9uYW1lX3Jlc29sdmVyLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfcHJpbWl0aXZlX2ZpZWxkLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfc2VydmljZS5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX3N0cmluZ19maWVsZC5oIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2RvY19jb21tZW50LmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZG9jX2NvbW1lbnQuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19lbnVtX2ZpZWxkLmgiPjwvRmlsZT4KKyAgICAgIDxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19lbnVtLmgiPjwvRmlsZT4KKyAgICAgIDxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19leHRlbnNpb24uaCI+PC9GaWxlPgorICAgICAgPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX2ZpZWxkLmgiPjwvRmlsZT4KKyAgICAgIDxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19maWxlLmgiPjwvRmlsZT4KKyAgICAgIDxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19nZW5lcmF0b3IuaCI+PC9GaWxlPgorICAgICAgPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX2hlbHBlcnMuaCI+PC9GaWxlPgorICAgICAgPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX21hcF9maWVsZC5oIj48L0ZpbGU+CisgICAgICA8RmlsZSBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fbWVzc2FnZV9maWVsZC5oIj48L0ZpbGU+CisgICAgICA8RmlsZSBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fbWVzc2FnZS5oIj48L0ZpbGU+CisgICAgICA8RmlsZSBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fcGFyYW1zLmgiPjwvRmlsZT4KKyAgICAgIDxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19wcmltaXRpdmVfZmllbGQuaCI+PC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHB5dGhvblxweXRob25fZ2VuZXJhdG9yLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxydWJ5XHJ1YnlfZ2VuZXJhdG9yLmgiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICA8L0ZpbHRlcj4KKyAgICA8RmlsdGVyCisgICAgICBOYW1lPSJSZXNvdXJjZSBGaWxlcyIKKyAgICAgIEZpbHRlcj0icmM7aWNvO2N1cjtibXA7ZGxnO3JjMjtyY3Q7YmluO3JncztnaWY7anBnO2pwZWc7anBlO3Jlc3giCisgICAgICBVbmlxdWVJZGVudGlmaWVyPSJ7NjdEQTZBQjYtRjgwMC00YzA4LThCN0EtODNCQjEyMUFBRDAxfSIKKyAgICAgID4KKyAgICA8L0ZpbHRlcj4KKyAgICA8RmlsdGVyCisgICAgICBOYW1lPSJTb3VyY2UgRmlsZXMiCisgICAgICBGaWx0ZXI9ImNwcDtjO2NjO2N4eDtkZWY7b2RsO2lkbDtocGo7YmF0O2FzbTthc214IgorICAgICAgVW5pcXVlSWRlbnRpZmllcj0iezRGQzczN0YxLUM3QTUtNDM3Ni1BMDY2LTJBMzJENzUyQTJGRn0iCisgICAgICA+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY29kZV9nZW5lcmF0b3IuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjb21tYW5kX2xpbmVfaW50ZXJmYWNlLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9lbnVtLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9lbnVtX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9leHRlbnNpb24uY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9maWxlLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9nZW5lcmF0b3IuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX2hlbHBlcnMuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX21hcF9maWVsZC5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfbWVzc2FnZS5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfbWVzc2FnZV9maWVsZC5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfcHJpbWl0aXZlX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9zZXJ2aWNlLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF9zdHJpbmdfZmllbGQuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxydWJ5XHJ1YnlfZ2VuZXJhdG9yLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2NvbnRleHQuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZG9jX2NvbW1lbnQuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfZW51bS5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9lbnVtX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2V4dGVuc2lvbi5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9maWVsZC5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9maWxlLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2dlbmVyYXRvci5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9oZWxwZXJzLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2xhenlfbWVzc2FnZV9maWVsZC5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9tYXBfZmllbGQuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfbWVzc2FnZS5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9tZXNzYWdlX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX25hbWVfcmVzb2x2ZXIuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfcHJpbWl0aXZlX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX3NlcnZpY2UuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhXGphdmFfc2hhcmVkX2NvZGVfZ2VuZXJhdG9yLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX3N0cmluZ19maWVsZC5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX2VudW0uY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19lbnVtX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fZXh0ZW5zaW9uLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fZmllbGQuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19maWxlLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fZ2VuZXJhdG9yLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9faGVscGVycy5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX21hcF9maWVsZC5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgICAgPEZpbGUKKyAgICAgICAgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFuYW5vXGphdmFuYW5vX21lc3NhZ2UuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxqYXZhbmFub1xqYXZhbmFub19tZXNzYWdlX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YW5hbm9camF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccGx1Z2luLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccGx1Z2luLnBiLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccHl0aG9uXHB5dGhvbl9nZW5lcmF0b3IuY2MiCisgICAgICAgID4KKyAgICAgIDwvRmlsZT4KKyAgICAgIDxGaWxlCisgICAgICAgIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxzdWJwcm9jZXNzLmNjIgorICAgICAgICA+CisgICAgICA8L0ZpbGU+CisgICAgICA8RmlsZQorICAgICAgICBSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcemlwX3dyaXRlci5jYyIKKyAgICAgICAgPgorICAgICAgPC9GaWxlPgorICAgIDwvRmlsdGVyPgorICA8L0ZpbGVzPgorICA8R2xvYmFscz4KKyAgPC9HbG9iYWxzPgorPC9WaXN1YWxTdHVkaW9Qcm9qZWN0PgpkaWZmIC0tZ2l0IGEvdnNwcm9qZWN0cy9saXRlLXRlc3QudmNwcm9qIGIvdnNwcm9qZWN0cy9saXRlLXRlc3QudmNwcm9qCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkMTcyMjQKLS0tIC9kZXYvbnVsbAorKysgYi92c3Byb2plY3RzL2xpdGUtdGVzdC52Y3Byb2oKQEAgLTAsMCArMSwzMzMgQEAKK++7vzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8VmlzdWFsU3R1ZGlvUHJvamVjdAorCVByb2plY3RUeXBlPSJWaXN1YWwgQysrIgorCVZlcnNpb249IjkuMDAiCisJTmFtZT0ibGl0ZS10ZXN0IgorCVByb2plY3RHVUlEPSJ7MTIwMTVBQ0UtNDJCRS00OTUyLUE1QTAtNDRBOUE0NjkwOEUyfSIKKwlSb290TmFtZXNwYWNlPSJ0ZXN0cyIKKwlLZXl3b3JkPSJXaW4zMlByb2oiCisJVGFyZ2V0RnJhbWV3b3JrVmVyc2lvbj0iMCIKKwk+CisJPFBsYXRmb3Jtcz4KKwkJPFBsYXRmb3JtCisJCQlOYW1lPSJXaW4zMiIKKwkJLz4KKwk8L1BsYXRmb3Jtcz4KKwk8VG9vbEZpbGVzPgorCTwvVG9vbEZpbGVzPgorCTxDb25maWd1cmF0aW9ucz4KKwkJPENvbmZpZ3VyYXRpb24KKwkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJT3V0cHV0RGlyZWN0b3J5PSJEZWJ1ZyIKKwkJCUludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorCQkJQ29uZmlndXJhdGlvblR5cGU9IjEiCisJCQk+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlQnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQlEZXNjcmlwdGlvbj0iIgorCQkJCUNvbW1hbmRMaW5lPSIiCisJCQkJQWRkaXRpb25hbERlcGVuZGVuY2llcz0iIgorCQkJCU91dHB1dHM9IiIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1dlYlNlcnZpY2VQcm94eUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01JRExUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKwkJCQlBZGRpdGlvbmFsT3B0aW9ucz0iL3dkNDI0NCAvd2Q0MjY3IC93ZDQwMTggL3dkNDM1NSAvd2Q0ODAwIC93ZDQyNTEgL3dkNDk5NiAvd2Q0MTQ2IC93ZDQzMDUiCisJCQkJT3B0aW1pemF0aW9uPSIwIgorCQkJCUFkZGl0aW9uYWxJbmNsdWRlRGlyZWN0b3JpZXM9Ii4uL3NyYzsuOy4uL2d0ZXN0L2luY2x1ZGUiCisJCQkJUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO19ERUJVRztfQ09OU09MRTtfVkFSSUFESUNfTUFYPTEwOyIKKwkJCQlNaW5pbWFsUmVidWlsZD0idHJ1ZSIKKwkJCQlCYXNpY1J1bnRpbWVDaGVja3M9IjMiCisJCQkJUnVudGltZUxpYnJhcnk9IjMiCisJCQkJVXNlUHJlY29tcGlsZWRIZWFkZXI9IjAiCisJCQkJV2FybmluZ0xldmVsPSIzIgorCQkJCURldGVjdDY0Qml0UG9ydGFiaWxpdHlQcm9ibGVtcz0idHJ1ZSIKKwkJCQlEZWJ1Z0luZm9ybWF0aW9uRm9ybWF0PSI0IgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNYW5hZ2VkUmVzb3VyY2VDb21waWxlclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1Jlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQcmVMaW5rRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNMaW5rZXJUb29sIgorCQkJCUxpbmtJbmNyZW1lbnRhbD0iMiIKKwkJCQlHZW5lcmF0ZURlYnVnSW5mb3JtYXRpb249InRydWUiCisJCQkJU3ViU3lzdGVtPSIxIgorCQkJCVRhcmdldE1hY2hpbmU9IjEiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0FMaW5rVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuaWZlc3RUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQXBwVmVyaWZpZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQb3N0QnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQk8L0NvbmZpZ3VyYXRpb24+CisJCTxDb25maWd1cmF0aW9uCisJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJT3V0cHV0RGlyZWN0b3J5PSJSZWxlYXNlIgorCQkJSW50ZXJtZWRpYXRlRGlyZWN0b3J5PSIkKE91dERpcilcJChQcm9qZWN0TmFtZSkiCisJCQlDb25maWd1cmF0aW9uVHlwZT0iMSIKKwkJCT4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQcmVCdWlsZEV2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCURlc2NyaXB0aW9uPSIiCisJCQkJQ29tbWFuZExpbmU9IiIKKwkJCQlBZGRpdGlvbmFsRGVwZW5kZW5jaWVzPSIiCisJCQkJT3V0cHV0cz0iIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYTUxEYXRhR2VuZXJhdG9yVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDV2ViU2VydmljZVByb3h5R2VuZXJhdG9yVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTUlETFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0NMQ29tcGlsZXJUb29sIgorCQkJCUFkZGl0aW9uYWxPcHRpb25zPSIvd2Q0MjQ0IC93ZDQyNjcgL3dkNDAxOCAvd2Q0MzU1IC93ZDQ4MDAgL3dkNDI1MSAvd2Q0OTk2IC93ZDQxNDYgL3dkNDMwNSIKKwkJCQlBZGRpdGlvbmFsSW5jbHVkZURpcmVjdG9yaWVzPSIuLi9zcmM7LjsuLi9ndGVzdC9pbmNsdWRlIgorCQkJCVByZXByb2Nlc3NvckRlZmluaXRpb25zPSJXSU4zMjtOREVCVUc7X0NPTlNPTEU7X1ZBUklBRElDX01BWD0xMDsiCisJCQkJUnVudGltZUxpYnJhcnk9IjIiCisJCQkJVXNlUHJlY29tcGlsZWRIZWFkZXI9IjAiCisJCQkJV2FybmluZ0xldmVsPSIzIgorCQkJCURldGVjdDY0Qml0UG9ydGFiaWxpdHlQcm9ibGVtcz0idHJ1ZSIKKwkJCQlEZWJ1Z0luZm9ybWF0aW9uRm9ybWF0PSIzIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNYW5hZ2VkUmVzb3VyY2VDb21waWxlclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1Jlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQcmVMaW5rRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNMaW5rZXJUb29sIgorCQkJCUxpbmtJbmNyZW1lbnRhbD0iMiIKKwkJCQlHZW5lcmF0ZURlYnVnSW5mb3JtYXRpb249InRydWUiCisJCQkJU3ViU3lzdGVtPSIxIgorCQkJCU9wdGltaXplUmVmZXJlbmNlcz0iMiIKKwkJCQlFbmFibGVDT01EQVRGb2xkaW5nPSIyIgorCQkJCVRhcmdldE1hY2hpbmU9IjEiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0FMaW5rVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuaWZlc3RUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQXBwVmVyaWZpZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQb3N0QnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQk8L0NvbmZpZ3VyYXRpb24+CisJPC9Db25maWd1cmF0aW9ucz4KKwk8UmVmZXJlbmNlcz4KKwk8L1JlZmVyZW5jZXM+CisJPEZpbGVzPgorCQk8RmlsdGVyCisJCQlOYW1lPSJIZWFkZXIgRmlsZXMiCisJCQlGaWx0ZXI9Img7aHBwO2h4eDtobTtpbmw7aW5jO3hzZCIKKwkJCVVuaXF1ZUlkZW50aWZpZXI9Ins5Mzk5NTM4MC04OUJELTRiMDQtODhFQi02MjVGQkU1MkVCRkJ9IgorCQkJPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdGVzdF91dGlsX2xpdGUuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZSBSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXG1hcF9saXRlX3VuaXR0ZXN0LnBiLmgiPjwvRmlsZT4KKwkJCTxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfbGl0ZV90ZXN0X3V0aWwuaCI+PC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2xpdGUucGIuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQk8L0ZpbHRlcj4KKwkJPEZpbHRlcgorCQkJTmFtZT0iUmVzb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9InJjO2ljbztjdXI7Ym1wO2RsZztyYzI7cmN0O2JpbjtyZ3M7Z2lmO2pwZztqcGVnO2pwZTtyZXN4IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezY3REE2QUI2LUY4MDAtNGMwOC04QjdBLTgzQkIxMjFBQUQwMX0iCisJCQk+CisJCTwvRmlsdGVyPgorCQk8RmlsdGVyCisJCQlOYW1lPSJTb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9ImNwcDtjO2NjO2N4eDtkZWY7b2RsO2lkbDtocGo7YmF0O2FzbTthc214IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezRGQzczN0YxLUM3QTUtNDM3Ni1BMDY2LTJBMzJENzUyQTJGRn0iCisJCQk+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxsaXRlX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRlc3RfdXRpbF9saXRlLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlIFJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcbWFwX2xpdGVfdW5pdHRlc3QucGIuY2MiPjwvRmlsZT4KKwkJCTxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfbGl0ZV90ZXN0X3V0aWwuY2MiPjwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnRfbGl0ZS5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJPC9GaWx0ZXI+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfbGl0ZS5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvJiN4MEQ7JiN4MEE7IgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvJiN4MEQ7JiN4MEE7IgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2ltcG9ydF9saXRlLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvJiN4MEQ7JiN4MEE7IgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfbGl0ZS5wcm90byYjeDBEOyYjeDBBOyIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydF9saXRlLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydF9saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvJiN4MEQ7JiN4MEE7IgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWNfbGl0ZS5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8mI3gwRDsmI3gwQTsiCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWFwX2xpdGVfdW5pdHRlc3QucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIG1hcF9saXRlX3VuaXR0ZXN0LnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3VuaXR0ZXN0LnByb3RvJiN4MEQ7JiN4MEE7IgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcbWFwX2xpdGVfdW5pdHRlc3QucGIuaDtnb29nbGVccHJvdG9idWZcbWFwX2xpdGVfdW5pdHRlc3QucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgbWFwX2xpdGVfdW5pdHRlc3QucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV91bml0dGVzdC5wcm90byYjeDBEOyYjeDBBOyIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXG1hcF9saXRlX3VuaXR0ZXN0LnBiLmg7Z29vZ2xlXHByb3RvYnVmXG1hcF9saXRlX3VuaXR0ZXN0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJPC9GaWxlcz4KKwk8R2xvYmFscz4KKwk8L0dsb2JhbHM+Cis8L1Zpc3VhbFN0dWRpb1Byb2plY3Q+CmRpZmYgLS1naXQgYS92c3Byb2plY3RzL3Byb3RvYnVmLnNsbiBiL3ZzcHJvamVjdHMvcHJvdG9idWYuc2xuCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2N2RlZTYKLS0tIC9kZXYvbnVsbAorKysgYi92c3Byb2plY3RzL3Byb3RvYnVmLnNsbgpAQCAtMCwwICsxLDkyIEBACivvu78KK01pY3Jvc29mdCBWaXN1YWwgU3R1ZGlvIFNvbHV0aW9uIEZpbGUsIEZvcm1hdCBWZXJzaW9uIDEwLjAwCisjIFZpc3VhbCBTdHVkaW8gMjAwOAorUHJvamVjdCgiezhCQzlDRUI4LThCNEEtMTFEMC04RDExLTAwQTBDOTFCQzk0Mn0iKSA9ICJsaWJwcm90b2J1ZiIsICJsaWJwcm90b2J1Zi52Y3Byb2oiLCAiezNFMjgzRjM3LUE0RUQtNDFCNy1BM0U2LUEyRDg5RDEzMUEzMH0iCitFbmRQcm9qZWN0CitQcm9qZWN0KCJ7OEJDOUNFQjgtOEI0QS0xMUQwLThEMTEtMDBBMEM5MUJDOTQyfSIpID0gImxpYnByb3RvYyIsICJsaWJwcm90b2MudmNwcm9qIiwgIntCODRGRjMxQS01RjlBLTQ2RjgtQUIyMi1EQkZDOUJFQ0UzQkV9IgorCVByb2plY3RTZWN0aW9uKFByb2plY3REZXBlbmRlbmNpZXMpID0gcG9zdFByb2plY3QKKwkJezNFMjgzRjM3LUE0RUQtNDFCNy1BM0U2LUEyRDg5RDEzMUEzMH0gPSB7M0UyODNGMzctQTRFRC00MUI3LUEzRTYtQTJEODlEMTMxQTMwfQorCUVuZFByb2plY3RTZWN0aW9uCitFbmRQcm9qZWN0CitQcm9qZWN0KCJ7OEJDOUNFQjgtOEI0QS0xMUQwLThEMTEtMDBBMEM5MUJDOTQyfSIpID0gInByb3RvYyIsICJwcm90b2MudmNwcm9qIiwgInsxNzM4RDVGNi1FRDFFLTQ3RTAtQjJGMC00NTY4NjRCOTNDMUV9IgorCVByb2plY3RTZWN0aW9uKFByb2plY3REZXBlbmRlbmNpZXMpID0gcG9zdFByb2plY3QKKwkJe0I4NEZGMzFBLTVGOUEtNDZGOC1BQjIyLURCRkM5QkVDRTNCRX0gPSB7Qjg0RkYzMUEtNUY5QS00NkY4LUFCMjItREJGQzlCRUNFM0JFfQorCQl7M0UyODNGMzctQTRFRC00MUI3LUEzRTYtQTJEODlEMTMxQTMwfSA9IHszRTI4M0YzNy1BNEVELTQxQjctQTNFNi1BMkQ4OUQxMzFBMzB9CisJRW5kUHJvamVjdFNlY3Rpb24KK0VuZFByb2plY3QKK1Byb2plY3QoIns4QkM5Q0VCOC04QjRBLTExRDAtOEQxMS0wMEEwQzkxQkM5NDJ9IikgPSAidGVzdHMiLCAidGVzdHMudmNwcm9qIiwgIns0REY3Mjc2MC1DMDU1LTQwQTUtQTc3RS0zMEExN0UyQUMyREJ9IgorCVByb2plY3RTZWN0aW9uKFByb2plY3REZXBlbmRlbmNpZXMpID0gcG9zdFByb2plY3QKKwkJe0I4NEZGMzFBLTVGOUEtNDZGOC1BQjIyLURCRkM5QkVDRTNCRX0gPSB7Qjg0RkYzMUEtNUY5QS00NkY4LUFCMjItREJGQzlCRUNFM0JFfQorCQl7M0UyODNGMzctQTRFRC00MUI3LUEzRTYtQTJEODlEMTMxQTMwfSA9IHszRTI4M0YzNy1BNEVELTQxQjctQTNFNi1BMkQ4OUQxMzFBMzB9CisJCXtDOEY2QzE3Mi01NkYyLTRFNzYtQjVGQS1DM0I0MjNCMzFCRTd9ID0ge0M4RjZDMTcyLTU2RjItNEU3Ni1CNUZBLUMzQjQyM0IzMUJFN30KKwkJezNBRjU0QzhBLTEwQkYtNDMzMi05MTQ3LUY2OEVEOTg2MjAzMn0gPSB7M0FGNTRDOEEtMTBCRi00MzMyLTkxNDctRjY4RUQ5ODYyMDMyfQorCQl7Q0JCRDM0RTUtMDJCMC00MEQ1LUI2RDgtQkZFQTgzRTE4QjMyfSA9IHtDQkJEMzRFNS0wMkIwLTQwRDUtQjZEOC1CRkVBODNFMThCMzJ9CisJCXsxNzM4RDVGNi1FRDFFLTQ3RTAtQjJGMC00NTY4NjRCOTNDMUV9ID0gezE3MzhENUY2LUVEMUUtNDdFMC1CMkYwLTQ1Njg2NEI5M0MxRX0KKwlFbmRQcm9qZWN0U2VjdGlvbgorRW5kUHJvamVjdAorUHJvamVjdCgiezhCQzlDRUI4LThCNEEtMTFEMC04RDExLTAwQTBDOTFCQzk0Mn0iKSA9ICJndGVzdCIsICIuLlxndGVzdFxtc3ZjXGd0ZXN0LnZjcHJvaiIsICJ7QzhGNkMxNzItNTZGMi00RTc2LUI1RkEtQzNCNDIzQjMxQkU3fSIKK0VuZFByb2plY3QKK1Byb2plY3QoIns4QkM5Q0VCOC04QjRBLTExRDAtOEQxMS0wMEEwQzkxQkM5NDJ9IikgPSAiZ3Rlc3RfbWFpbiIsICIuLlxndGVzdFxtc3ZjXGd0ZXN0X21haW4udmNwcm9qIiwgInszQUY1NEM4QS0xMEJGLTQzMzItOTE0Ny1GNjhFRDk4NjIwMzJ9IgorRW5kUHJvamVjdAorUHJvamVjdCgiezhCQzlDRUI4LThCNEEtMTFEMC04RDExLTAwQTBDOTFCQzk0Mn0iKSA9ICJsaWJwcm90b2J1Zi1saXRlIiwgImxpYnByb3RvYnVmLWxpdGUudmNwcm9qIiwgIns0OUVBMDEwRC03MDZGLTRCRTItQTM5Ny03Nzg1NEI3MkEwNDB9IgorRW5kUHJvamVjdAorUHJvamVjdCgiezhCQzlDRUI4LThCNEEtMTFEMC04RDExLTAwQTBDOTFCQzk0Mn0iKSA9ICJsaXRlLXRlc3QiLCAibGl0ZS10ZXN0LnZjcHJvaiIsICJ7MTIwMTVBQ0UtNDJCRS00OTUyLUE1QTAtNDRBOUE0NjkwOEUyfSIKKwlQcm9qZWN0U2VjdGlvbihQcm9qZWN0RGVwZW5kZW5jaWVzKSA9IHBvc3RQcm9qZWN0CisJCXs0OUVBMDEwRC03MDZGLTRCRTItQTM5Ny03Nzg1NEI3MkEwNDB9ID0gezQ5RUEwMTBELTcwNkYtNEJFMi1BMzk3LTc3ODU0QjcyQTA0MH0KKwkJezE3MzhENUY2LUVEMUUtNDdFMC1CMkYwLTQ1Njg2NEI5M0MxRX0gPSB7MTczOEQ1RjYtRUQxRS00N0UwLUIyRjAtNDU2ODY0QjkzQzFFfQorCUVuZFByb2plY3RTZWN0aW9uCitFbmRQcm9qZWN0CitQcm9qZWN0KCJ7OEJDOUNFQjgtOEI0QS0xMUQwLThEMTEtMDBBMEM5MUJDOTQyfSIpID0gInRlc3RfcGx1Z2luIiwgInRlc3RfcGx1Z2luLnZjcHJvaiIsICJ7Q0JCRDM0RTUtMDJCMC00MEQ1LUI2RDgtQkZFQTgzRTE4QjMyfSIKKwlQcm9qZWN0U2VjdGlvbihQcm9qZWN0RGVwZW5kZW5jaWVzKSA9IHBvc3RQcm9qZWN0CisJCXtCODRGRjMxQS01RjlBLTQ2RjgtQUIyMi1EQkZDOUJFQ0UzQkV9ID0ge0I4NEZGMzFBLTVGOUEtNDZGOC1BQjIyLURCRkM5QkVDRTNCRX0KKwkJezNFMjgzRjM3LUE0RUQtNDFCNy1BM0U2LUEyRDg5RDEzMUEzMH0gPSB7M0UyODNGMzctQTRFRC00MUI3LUEzRTYtQTJEODlEMTMxQTMwfQorCQl7QzhGNkMxNzItNTZGMi00RTc2LUI1RkEtQzNCNDIzQjMxQkU3fSA9IHtDOEY2QzE3Mi01NkYyLTRFNzYtQjVGQS1DM0I0MjNCMzFCRTd9CisJRW5kUHJvamVjdFNlY3Rpb24KK0VuZFByb2plY3QKK0dsb2JhbAorCUdsb2JhbFNlY3Rpb24oU29sdXRpb25Db25maWd1cmF0aW9uUGxhdGZvcm1zKSA9IHByZVNvbHV0aW9uCisJCURlYnVnfFdpbjMyID0gRGVidWd8V2luMzIKKwkJUmVsZWFzZXxXaW4zMiA9IFJlbGVhc2V8V2luMzIKKwlFbmRHbG9iYWxTZWN0aW9uCisJR2xvYmFsU2VjdGlvbihQcm9qZWN0Q29uZmlndXJhdGlvblBsYXRmb3JtcykgPSBwb3N0U29sdXRpb24KKwkJezNFMjgzRjM3LUE0RUQtNDFCNy1BM0U2LUEyRDg5RDEzMUEzMH0uRGVidWd8V2luMzIuQWN0aXZlQ2ZnID0gRGVidWd8V2luMzIKKwkJezNFMjgzRjM3LUE0RUQtNDFCNy1BM0U2LUEyRDg5RDEzMUEzMH0uRGVidWd8V2luMzIuQnVpbGQuMCA9IERlYnVnfFdpbjMyCisJCXszRTI4M0YzNy1BNEVELTQxQjctQTNFNi1BMkQ4OUQxMzFBMzB9LlJlbGVhc2V8V2luMzIuQWN0aXZlQ2ZnID0gUmVsZWFzZXxXaW4zMgorCQl7M0UyODNGMzctQTRFRC00MUI3LUEzRTYtQTJEODlEMTMxQTMwfS5SZWxlYXNlfFdpbjMyLkJ1aWxkLjAgPSBSZWxlYXNlfFdpbjMyCisJCXtCODRGRjMxQS01RjlBLTQ2RjgtQUIyMi1EQkZDOUJFQ0UzQkV9LkRlYnVnfFdpbjMyLkFjdGl2ZUNmZyA9IERlYnVnfFdpbjMyCisJCXtCODRGRjMxQS01RjlBLTQ2RjgtQUIyMi1EQkZDOUJFQ0UzQkV9LkRlYnVnfFdpbjMyLkJ1aWxkLjAgPSBEZWJ1Z3xXaW4zMgorCQl7Qjg0RkYzMUEtNUY5QS00NkY4LUFCMjItREJGQzlCRUNFM0JFfS5SZWxlYXNlfFdpbjMyLkFjdGl2ZUNmZyA9IFJlbGVhc2V8V2luMzIKKwkJe0I4NEZGMzFBLTVGOUEtNDZGOC1BQjIyLURCRkM5QkVDRTNCRX0uUmVsZWFzZXxXaW4zMi5CdWlsZC4wID0gUmVsZWFzZXxXaW4zMgorCQl7MTczOEQ1RjYtRUQxRS00N0UwLUIyRjAtNDU2ODY0QjkzQzFFfS5EZWJ1Z3xXaW4zMi5BY3RpdmVDZmcgPSBEZWJ1Z3xXaW4zMgorCQl7MTczOEQ1RjYtRUQxRS00N0UwLUIyRjAtNDU2ODY0QjkzQzFFfS5EZWJ1Z3xXaW4zMi5CdWlsZC4wID0gRGVidWd8V2luMzIKKwkJezE3MzhENUY2LUVEMUUtNDdFMC1CMkYwLTQ1Njg2NEI5M0MxRX0uUmVsZWFzZXxXaW4zMi5BY3RpdmVDZmcgPSBSZWxlYXNlfFdpbjMyCisJCXsxNzM4RDVGNi1FRDFFLTQ3RTAtQjJGMC00NTY4NjRCOTNDMUV9LlJlbGVhc2V8V2luMzIuQnVpbGQuMCA9IFJlbGVhc2V8V2luMzIKKwkJezRERjcyNzYwLUMwNTUtNDBBNS1BNzdFLTMwQTE3RTJBQzJEQn0uRGVidWd8V2luMzIuQWN0aXZlQ2ZnID0gRGVidWd8V2luMzIKKwkJezRERjcyNzYwLUMwNTUtNDBBNS1BNzdFLTMwQTE3RTJBQzJEQn0uRGVidWd8V2luMzIuQnVpbGQuMCA9IERlYnVnfFdpbjMyCisJCXs0REY3Mjc2MC1DMDU1LTQwQTUtQTc3RS0zMEExN0UyQUMyREJ9LlJlbGVhc2V8V2luMzIuQWN0aXZlQ2ZnID0gUmVsZWFzZXxXaW4zMgorCQl7NERGNzI3NjAtQzA1NS00MEE1LUE3N0UtMzBBMTdFMkFDMkRCfS5SZWxlYXNlfFdpbjMyLkJ1aWxkLjAgPSBSZWxlYXNlfFdpbjMyCisJCXtDOEY2QzE3Mi01NkYyLTRFNzYtQjVGQS1DM0I0MjNCMzFCRTd9LkRlYnVnfFdpbjMyLkFjdGl2ZUNmZyA9IERlYnVnfFdpbjMyCisJCXtDOEY2QzE3Mi01NkYyLTRFNzYtQjVGQS1DM0I0MjNCMzFCRTd9LkRlYnVnfFdpbjMyLkJ1aWxkLjAgPSBEZWJ1Z3xXaW4zMgorCQl7QzhGNkMxNzItNTZGMi00RTc2LUI1RkEtQzNCNDIzQjMxQkU3fS5SZWxlYXNlfFdpbjMyLkFjdGl2ZUNmZyA9IFJlbGVhc2V8V2luMzIKKwkJe0M4RjZDMTcyLTU2RjItNEU3Ni1CNUZBLUMzQjQyM0IzMUJFN30uUmVsZWFzZXxXaW4zMi5CdWlsZC4wID0gUmVsZWFzZXxXaW4zMgorCQl7M0FGNTRDOEEtMTBCRi00MzMyLTkxNDctRjY4RUQ5ODYyMDMyfS5EZWJ1Z3xXaW4zMi5BY3RpdmVDZmcgPSBEZWJ1Z3xXaW4zMgorCQl7M0FGNTRDOEEtMTBCRi00MzMyLTkxNDctRjY4RUQ5ODYyMDMyfS5EZWJ1Z3xXaW4zMi5CdWlsZC4wID0gRGVidWd8V2luMzIKKwkJezNBRjU0QzhBLTEwQkYtNDMzMi05MTQ3LUY2OEVEOTg2MjAzMn0uUmVsZWFzZXxXaW4zMi5BY3RpdmVDZmcgPSBSZWxlYXNlfFdpbjMyCisJCXszQUY1NEM4QS0xMEJGLTQzMzItOTE0Ny1GNjhFRDk4NjIwMzJ9LlJlbGVhc2V8V2luMzIuQnVpbGQuMCA9IFJlbGVhc2V8V2luMzIKKwkJezQ5RUEwMTBELTcwNkYtNEJFMi1BMzk3LTc3ODU0QjcyQTA0MH0uRGVidWd8V2luMzIuQWN0aXZlQ2ZnID0gRGVidWd8V2luMzIKKwkJezQ5RUEwMTBELTcwNkYtNEJFMi1BMzk3LTc3ODU0QjcyQTA0MH0uRGVidWd8V2luMzIuQnVpbGQuMCA9IERlYnVnfFdpbjMyCisJCXs0OUVBMDEwRC03MDZGLTRCRTItQTM5Ny03Nzg1NEI3MkEwNDB9LlJlbGVhc2V8V2luMzIuQWN0aXZlQ2ZnID0gUmVsZWFzZXxXaW4zMgorCQl7NDlFQTAxMEQtNzA2Ri00QkUyLUEzOTctNzc4NTRCNzJBMDQwfS5SZWxlYXNlfFdpbjMyLkJ1aWxkLjAgPSBSZWxlYXNlfFdpbjMyCisJCXsxMjAxNUFDRS00MkJFLTQ5NTItQTVBMC00NEE5QTQ2OTA4RTJ9LkRlYnVnfFdpbjMyLkFjdGl2ZUNmZyA9IERlYnVnfFdpbjMyCisJCXsxMjAxNUFDRS00MkJFLTQ5NTItQTVBMC00NEE5QTQ2OTA4RTJ9LkRlYnVnfFdpbjMyLkJ1aWxkLjAgPSBEZWJ1Z3xXaW4zMgorCQl7MTIwMTVBQ0UtNDJCRS00OTUyLUE1QTAtNDRBOUE0NjkwOEUyfS5SZWxlYXNlfFdpbjMyLkFjdGl2ZUNmZyA9IFJlbGVhc2V8V2luMzIKKwkJezEyMDE1QUNFLTQyQkUtNDk1Mi1BNUEwLTQ0QTlBNDY5MDhFMn0uUmVsZWFzZXxXaW4zMi5CdWlsZC4wID0gUmVsZWFzZXxXaW4zMgorCQl7Q0JCRDM0RTUtMDJCMC00MEQ1LUI2RDgtQkZFQTgzRTE4QjMyfS5EZWJ1Z3xXaW4zMi5BY3RpdmVDZmcgPSBEZWJ1Z3xXaW4zMgorCQl7Q0JCRDM0RTUtMDJCMC00MEQ1LUI2RDgtQkZFQTgzRTE4QjMyfS5EZWJ1Z3xXaW4zMi5CdWlsZC4wID0gRGVidWd8V2luMzIKKwkJe0NCQkQzNEU1LTAyQjAtNDBENS1CNkQ4LUJGRUE4M0UxOEIzMn0uUmVsZWFzZXxXaW4zMi5BY3RpdmVDZmcgPSBSZWxlYXNlfFdpbjMyCisJCXtDQkJEMzRFNS0wMkIwLTQwRDUtQjZEOC1CRkVBODNFMThCMzJ9LlJlbGVhc2V8V2luMzIuQnVpbGQuMCA9IFJlbGVhc2V8V2luMzIKKwlFbmRHbG9iYWxTZWN0aW9uCisJR2xvYmFsU2VjdGlvbihTb2x1dGlvblByb3BlcnRpZXMpID0gcHJlU29sdXRpb24KKwkJSGlkZVNvbHV0aW9uTm9kZSA9IEZBTFNFCisJRW5kR2xvYmFsU2VjdGlvbgorRW5kR2xvYmFsCmRpZmYgLS1naXQgYS92c3Byb2plY3RzL3Byb3RvYy52Y3Byb2ogYi92c3Byb2plY3RzL3Byb3RvYy52Y3Byb2oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDM1OWUyMwotLS0gL2Rldi9udWxsCisrKyBiL3ZzcHJvamVjdHMvcHJvdG9jLnZjcHJvagpAQCAtMCwwICsxLDE5MiBAQAor77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzxWaXN1YWxTdHVkaW9Qcm9qZWN0CisJUHJvamVjdFR5cGU9IlZpc3VhbCBDKysiCisJVmVyc2lvbj0iOS4wMCIKKwlOYW1lPSJwcm90b2MiCisJUHJvamVjdEdVSUQ9InsxNzM4RDVGNi1FRDFFLTQ3RTAtQjJGMC00NTY4NjRCOTNDMUV9IgorCUtleXdvcmQ9IldpbjMyUHJvaiIKKwlUYXJnZXRGcmFtZXdvcmtWZXJzaW9uPSIwIgorCT4KKwk8UGxhdGZvcm1zPgorCQk8UGxhdGZvcm0KKwkJCU5hbWU9IldpbjMyIgorCQkvPgorCTwvUGxhdGZvcm1zPgorCTxUb29sRmlsZXM+CisJPC9Ub29sRmlsZXM+CisJPENvbmZpZ3VyYXRpb25zPgorCQk8Q29uZmlndXJhdGlvbgorCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQlPdXRwdXREaXJlY3Rvcnk9IkRlYnVnIgorCQkJSW50ZXJtZWRpYXRlRGlyZWN0b3J5PSIkKE91dERpcilcJChQcm9qZWN0TmFtZSkiCisJCQlDb25maWd1cmF0aW9uVHlwZT0iMSIKKwkJCT4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQcmVCdWlsZEV2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYTUxEYXRhR2VuZXJhdG9yVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDV2ViU2VydmljZVByb3h5R2VuZXJhdG9yVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTUlETFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0NMQ29tcGlsZXJUb29sIgorCQkJCUFkZGl0aW9uYWxPcHRpb25zPSIvd2Q0MjQ0IC93ZDQyNjcgL3dkNDAxOCAvd2Q0MzU1IC93ZDQ4MDAgL3dkNDI1MSAvd2Q0OTk2IC93ZDQxNDYgL3dkNDMwNSIKKwkJCQlPcHRpbWl6YXRpb249IjAiCisJCQkJQWRkaXRpb25hbEluY2x1ZGVEaXJlY3Rvcmllcz0iLi4vc3JjOy4iCisJCQkJUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO19ERUJVRztfQ09OU09MRTsiCisJCQkJTWluaW1hbFJlYnVpbGQ9InRydWUiCisJCQkJQmFzaWNSdW50aW1lQ2hlY2tzPSIzIgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIzIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iNCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlua2VyVG9vbCIKKwkJCQlMaW5rSW5jcmVtZW50YWw9IjIiCisJCQkJR2VuZXJhdGVEZWJ1Z0luZm9ybWF0aW9uPSJ0cnVlIgorCQkJCVN1YlN5c3RlbT0iMSIKKwkJCQlUYXJnZXRNYWNoaW5lPSIxIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNBTGlua1Rvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01hbmlmZXN0VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWERDTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0JzY01ha2VUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNGeENvcFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0FwcFZlcmlmaWVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCQk8Q29uZmlndXJhdGlvbgorCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iUmVsZWFzZSIKKwkJCUludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorCQkJQ29uZmlndXJhdGlvblR5cGU9IjEiCisJCQk+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlQnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1dlYlNlcnZpY2VQcm94eUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01JRExUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKwkJCQlBZGRpdGlvbmFsT3B0aW9ucz0iL3dkNDI0NCAvd2Q0MjY3IC93ZDQwMTggL3dkNDM1NSAvd2Q0ODAwIC93ZDQyNTEgL3dkNDk5NiAvd2Q0MTQ2IC93ZDQzMDUiCisJCQkJQWRkaXRpb25hbEluY2x1ZGVEaXJlY3Rvcmllcz0iLi4vc3JjOy4iCisJCQkJUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO05ERUJVRztfQ09OU09MRTsiCisJCQkJUnVudGltZUxpYnJhcnk9IjIiCisJCQkJVXNlUHJlY29tcGlsZWRIZWFkZXI9IjAiCisJCQkJV2FybmluZ0xldmVsPSIzIgorCQkJCURldGVjdDY0Qml0UG9ydGFiaWxpdHlQcm9ibGVtcz0idHJ1ZSIKKwkJCQlEZWJ1Z0luZm9ybWF0aW9uRm9ybWF0PSIzIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNYW5hZ2VkUmVzb3VyY2VDb21waWxlclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1Jlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQcmVMaW5rRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNMaW5rZXJUb29sIgorCQkJCUxpbmtJbmNyZW1lbnRhbD0iMiIKKwkJCQlHZW5lcmF0ZURlYnVnSW5mb3JtYXRpb249InRydWUiCisJCQkJU3ViU3lzdGVtPSIxIgorCQkJCU9wdGltaXplUmVmZXJlbmNlcz0iMiIKKwkJCQlFbmFibGVDT01EQVRGb2xkaW5nPSIyIgorCQkJCVRhcmdldE1hY2hpbmU9IjEiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0FMaW5rVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuaWZlc3RUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYRENNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQnNjTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0Z4Q29wVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQXBwVmVyaWZpZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQb3N0QnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQk8L0NvbmZpZ3VyYXRpb24+CisJPC9Db25maWd1cmF0aW9ucz4KKwk8UmVmZXJlbmNlcz4KKwk8L1JlZmVyZW5jZXM+CisJPEZpbGVzPgorCQk8RmlsdGVyCisJCQlOYW1lPSJIZWFkZXIgRmlsZXMiCisJCQlGaWx0ZXI9Img7aHBwO2h4eDtobTtpbmw7aW5jO3hzZCIKKwkJCVVuaXF1ZUlkZW50aWZpZXI9Ins5Mzk5NTM4MC04OUJELTRiMDQtODhFQi02MjVGQkU1MkVCRkJ9IgorCQkJPgorCQk8L0ZpbHRlcj4KKwkJPEZpbHRlcgorCQkJTmFtZT0iUmVzb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9InJjO2ljbztjdXI7Ym1wO2RsZztyYzI7cmN0O2JpbjtyZ3M7Z2lmO2pwZztqcGVnO2pwZTtyZXN4IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezY3REE2QUI2LUY4MDAtNGMwOC04QjdBLTgzQkIxMjFBQUQwMX0iCisJCQk+CisJCTwvRmlsdGVyPgorCQk8RmlsdGVyCisJCQlOYW1lPSJTb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9ImNwcDtjO2NjO2N4eDtkZWY7b2RsO2lkbDtocGo7YmF0O2FzbTthc214IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezRGQzczN0YxLUM3QTUtNDM3Ni1BMDY2LTJBMzJENzUyQTJGRn0iCisJCQk+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxtYWluLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJPC9GaWx0ZXI+CisJPC9GaWxlcz4KKwk8R2xvYmFscz4KKwk8L0dsb2JhbHM+Cis8L1Zpc3VhbFN0dWRpb1Byb2plY3Q+CmRpZmYgLS1naXQgYS92c3Byb2plY3RzL3JlYWRtZS50eHQgYi92c3Byb2plY3RzL3JlYWRtZS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQzNDI0OQotLS0gL2Rldi9udWxsCisrKyBiL3ZzcHJvamVjdHMvcmVhZG1lLnR4dApAQCAtMCwwICsxLDEyMSBAQAorVGhpcyBkaXJlY3RvcnkgY29udGFpbnMgcHJvamVjdCBmaWxlcyBmb3IgY29tcGlsaW5nIFByb3RvY29sIEJ1ZmZlcnMgdXNpbmcKK01TVkMuICBUaGlzIGlzIG5vdCB0aGUgcmVjb21tZW5kZWQgd2F5IHRvIGRvIFByb3RvY29sIEJ1ZmZlciBkZXZlbG9wbWVudCAtLQord2UgcHJlZmVyIHRvIGRldmVsb3AgdW5kZXIgYSBVbml4LWxpa2UgZW52aXJvbm1lbnQgLS0gYnV0IGl0IG1heSBiZSBtb3JlCithY2Nlc3NpYmxlIHRvIHRob3NlIHdobyBwcmltYXJpbHkgd29yayB3aXRoIE1TVkMuCisKK0NvbXBpbGluZyBhbmQgSW5zdGFsbGluZworPT09PT09PT09PT09PT09PT09PT09PT09CisKKzApIENoZWNrIHdoZXRoZXIgYSBndGVzdCBkaXJlY3RvcnkgZXhpc3RzIGluIHRoZSB1cHBlciBsZXZlbCBkaXJlY3RvcnkuIElmCisgICB5b3UgY2hlY2tvdXQgdGhlIGNvZGUgZnJvbSBnaXRodWIgdmlhICJnaXQgY2xvbmUiLCB0aGlzIGd0ZXN0IGRpcmVjdG9yeQorICAgd29uJ3QgZXhpc3QgYW5kIHlvdSB3b24ndCBiZSBhYmxlIHRvIGJ1aWxkIHRoZSB0ZXN0cyBkZXNjcmliZWQgYmVsb3cuIFRvCisgICBhdm9pZCB0aGlzIHByb2JsZW0gY29uc2lkZXIgZG93bmxvYWRpbmcgb25lIG9mIHRoZSByZWxlYXNlIHRhciBiYWxscyB3aGljaAorICAgY29udGFpbnMgZ3Rlc3QgYWxyZWFkeSBhbmQgY29weWluZyB0aGUgZ2VzdCBkaXJlY3RvcnkgZnJvbSB0aGVyZSB0byB5b3VyCisgICBwcm90b2J1ZiBkaXJlY3Rvcnk6CisgICAgICAgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9wcm90b2J1Zi9yZWxlYXNlcworMSkgT3BlbiBwcm90b2J1Zi5zbG4gaW4gTWljcm9zb2Z0IFZpc3VhbCBTdHVkaW8uCisyKSBDaG9vc2UgIkRlYnVnIiBvciAiUmVsZWFzZSIgY29uZmlndXJhdGlvbiBhcyBkZXNpcmVkLioKKzMpIEZyb20gdGhlIEJ1aWxkIG1lbnUsIGNob29zZSAiQnVpbGQgU29sdXRpb24iLiAgV2FpdCBmb3IgY29tcGlsaW5nIHRvIGZpbmlzaC4KKzQpIEZyb20gYSBjb21tYW5kIHNoZWxsLCBydW4gdGVzdHMuZXhlIGFuZCBsaXRlLXRlc3QuZXhlIGFuZCBjaGVjayB0aGF0IGFsbAorICAgdGVzdHMgcGFzcy4KKzUpIFJ1biBleHRyYWN0X2luY2x1ZGVzLmJhdCB0byBjb3B5IGFsbCB0aGUgcHVibGljIGhlYWRlcnMgaW50byBhIHNlcGFyYXRlCisgICAiaW5jbHVkZSIgZGlyZWN0b3J5ICh1bmRlciB0aGUgdG9wLWxldmVsIHBhY2thZ2UgZGlyZWN0b3J5KS4KKzYpIENvcHkgdGhlIGNvbnRlbnRzIG9mIHRoZSBpbmNsdWRlIGRpcmVjdG9yeSB0byB3aGVyZXZlciB5b3Ugd2FudCB0byBwdXQKKyAgIGhlYWRlcnMuCis3KSBDb3B5IHByb3RvYy5leGUgd2hlcmV2ZXIgeW91IHB1dCBidWlsZCB0b29scyAocHJvYmFibHkgc29tZXdoZXJlIGluIHlvdXIKKyAgIFBBVEgpLgorOCkgQ29weSBsaWJwcm90b2J1Zi5saWIsIGxpYnByb3RvYnVmLWxpdGUubGliLCBhbmQgbGlicHJvdG9jLmxpYiB3aGVyZXZlciB5b3UKKyAgIHB1dCBsaWJyYXJpZXMuCisKKyogVG8gYXZvaWQgY29uZmxpY3RzIGJldHdlZW4gdGhlIE1TVkMgZGVidWcgYW5kIHJlbGVhc2UgcnVudGltZSBsaWJyYXJpZXMsIHdoZW4KKyAgY29tcGlsaW5nIGEgZGVidWcgYnVpbGQgb2YgeW91ciBhcHBsaWNhdGlvbiwgeW91IG1heSBuZWVkIHRvIGxpbmsgYWdhaW5zdCBhCisgIGRlYnVnIGJ1aWxkIG9mIGxpYnByb3RvYnVmLmxpYi4gIFNpbWlsYXJseSwgcmVsZWFzZSBidWlsZHMgc2hvdWxkIGxpbmsgYWdhaW5zdAorICByZWxlYXNlIGxpYnMuCisKK0RMTHMgdnMuIHN0YXRpYyBsaW5raW5nCis9PT09PT09PT09PT09PT09PT09PT09PQorCitTdGF0aWMgbGlua2luZyBpcyBub3cgdGhlIGRlZmF1bHQgZm9yIHRoZSBQcm90b2NvbCBCdWZmZXIgbGlicmFyaWVzLiAgRHVlIHRvCitpc3N1ZXMgd2l0aCBXaW4zMidzIHVzZSBvZiBhIHNlcGFyYXRlIGhlYXAgZm9yIGVhY2ggRExMLCBhcyB3ZWxsIGFzIGJpbmFyeQorY29tcGF0aWJpbGl0eSBpc3N1ZXMgYmV0d2VlbiBkaWZmZXJlbnQgdmVyc2lvbnMgb2YgTVNWQydzIFNUTCBsaWJyYXJ5LCBpdCBpcworcmVjb21tZW5kZWQgdGhhdCB5b3UgdXNlIHN0YXRpYyBsaW5rYWdlIG9ubHkuICBIb3dldmVyLCBpdCBpcyBwb3NzaWJsZSB0bworYnVpbGQgbGlicHJvdG9idWYgYW5kIGxpYnByb3RvYyBhcyBETExzIGlmIHlvdSByZWFsbHkgd2FudC4gIFRvIGRvIHRoaXMsCitkbyB0aGUgZm9sbG93aW5nOgorCisgIDEpIE9wZW4gcHJvdG9idWYuc2xuIGluIE1TVkMuCisgIDIpIEZvciBlYWNoIG9mIHRoZSBwcm9qZWN0cyBsaWJwcm90b2J1ZiwgbGlicHJvdG9idWYtbGl0ZSwgYW5kIGxpYnByb3RvYywgZG8KKyAgICAgdGhlIGZvbGxvd2luZzoKKyAgICAyYSkgUmlnaHQtY2xpY2sgdGhlIHByb2plY3QgYW5kIGNob29zZSAicHJvcGVydGllcyIuCisgICAgMmIpIEZyb20gdGhlIHNpZGUgYmFyLCBjaG9vc2UgIkdlbmVyYWwiLCB1bmRlciAiQ29uZmlndXJhdGlvbiBQcm9wZXJ0aWVzIi4KKyAgICAyYykgQ2hhbmdlIHRoZSAiQ29uZmlndXJhdGlvbiBUeXBlIiB0byAiRHluYW1pYyBMaWJyYXJ5ICguZGxsKSIuCisgICAgMmQpIEZyb20gdGhlIHNpZGUgYmFyLCBjaG9vc2UgIlByZXByb2Nlc3NvciIsIHVuZGVyICJDL0MrKyIuCisgICAgMmUpIEFkZCBQUk9UT0JVRl9VU0VfRExMUyB0byB0aGUgbGlzdCBvZiBwcmVwcm9jZXNzb3IgZGVmaW5lcy4KKyAgMykgV2hlbiBjb21waWxpbmcgeW91ciBwcm9qZWN0LCBtYWtlIHN1cmUgdG8gI2RlZmluZSBQUk9UT0JVRl9VU0VfRExMUy4KKworV2hlbiBkaXN0cmlidXRpbmcgeW91ciBzb2Z0d2FyZSB0byBlbmQgdXNlcnMsIHdlIHN0cm9uZ2x5IHJlY29tbWVuZCB0aGF0IHlvdQorZG8gTk9UIGluc3RhbGwgbGlicHJvdG9idWYuZGxsIG9yIGxpYnByb3RvYy5kbGwgdG8gYW55IHNoYXJlZCBsb2NhdGlvbi4KK0luc3RlYWQsIGtlZXAgdGhlc2UgbGlicmFyaWVzIG5leHQgdG8geW91ciBiaW5hcmllcywgaW4geW91ciBhcHBsaWNhdGlvbidzCitvd24gaW5zdGFsbCBkaXJlY3RvcnkuICBDKysgbWFrZXMgaXQgdmVyeSBkaWZmaWN1bHQgdG8gbWFpbnRhaW4gYmluYXJ5Citjb21wYXRpYmlsaXR5IGJldHdlZW4gcmVsZWFzZXMsIHNvIGl0IGlzIGxpa2VseSB0aGF0IGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGVzZQorbGlicmFyaWVzIHdpbGwgKm5vdCogYmUgdXNhYmxlIGFzIGRyb3AtaW4gcmVwbGFjZW1lbnRzLgorCitJZiB5b3VyIHByb2plY3QgaXMgaXRzZWxmIGEgRExMIGludGVuZGVkIGZvciB1c2UgYnkgdGhpcmQtcGFydHkgc29mdHdhcmUsIHdlCityZWNvbW1lbmQgdGhhdCB5b3UgZG8gTk9UIGV4cG9zZSBwcm90b2NvbCBidWZmZXIgb2JqZWN0cyBpbiB5b3VyIGxpYnJhcnkncworcHVibGljIGludGVyZmFjZSwgYW5kIHRoYXQgeW91IHN0YXRpY2FsbHkgbGluayBwcm90b2NvbCBidWZmZXJzIGludG8geW91cgorbGlicmFyeS4KKworWkxpYiBzdXBwb3J0Cis9PT09PT09PT09PT0KKworSWYgeW91IHdhbnQgdG8gaW5jbHVkZSBHemlwSW5wdXRTdHJlYW0gYW5kIEd6aXBPdXRwdXRTdHJlYW0KKyhnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaCkgaW4gbGlicHJvdG9jLCB5b3Ugd2lsbCBuZWVkIHRvIGRvIGEgZmV3CithZGRpdGlvbmFsIHN0ZXBzOgorCisxKSBPYnRhaW4gYSBjb3B5IG9mIHRoZSB6bGliIGxpYnJhcnkuICBUaGUgcHJlLWNvbXBpbGVkIERMTCBhdCB6bGliLm5ldCB3b3Jrcy4KKzIpIE1ha2Ugc3VyZSB6bGliJ3MgdHdvIGhlYWRlcnMgYXJlIGluIHlvdXIgaW5jbHVkZSBwYXRoIGFuZCB0aGF0IHRoZSAubGliIGZpbGUKKyAgIGlzIGluIHlvdXIgbGlicmFyeSBwYXRoLiAgWW91IGNvdWxkIHBsYWNlIGFsbCB0aHJlZSBmaWxlcyBkaXJlY3RseSBpbnRvIHRoZQorICAgdnNwcm9qZWN0IGRpcmVjdG9yeSB0byBjb21waWxlIGxpYnByb3RvYnVmLCBidXQgdGhleSBuZWVkIHRvIGJlIHZpc2libGUgdG8KKyAgIHlvdXIgb3duIHByb2plY3QgYXMgd2VsbCwgc28geW91IHNob3VsZCBwcm9iYWJseSBqdXN0IHB1dCB0aGVtIGludG8gdGhlCisgICBWQyBzaGFyZWQgaWNubHVkZSBhbmQgbGlicmFyeSBkaXJlY3Rvcmllcy4KKzMpIFJpZ2h0LWNsaWNrIG9uIHRoZSAidGVzdHMiIHByb2plY3QgYW5kIGNob29zZSAicHJvcGVydGllcyIuICBOYXZpZ2F0ZSB0aGUKKyAgIHNpZGViYXIgdG8gIkNvbmZpZ3VyYXRpb24gUHJvcGVydGllcyIgLT4gIkxpbmtlciIgLT4gIklucHV0Ii4KKzQpIFVuZGVyICJBZGRpdGlvbmFsIERlcGVuZGVuY2llcyIsIGFkZCB0aGUgbmFtZSBvZiB0aGUgemxpYiAubGliIGZpbGUgKGUuZy4KKyAgIHpkbGwubGliKS4gIE1ha2Ugc3VyZSB0byB1cGRhdGUgYm90aCB0aGUgRGVidWcgYW5kIFJlbGVhc2UgY29uZmlndXJhdGlvbnMuCis1KSBJZiB5b3UgYXJlIGNvbXBpbGluZyBsaWJwcm90b2J1ZiBhbmQgbGlicHJvdG9jIGFzIERMTHMgKHNlZSBwcmV2aW91cworICAgc2VjdGlvbiksIHJlcGVhdCBzdGVwcyAyIGFuZCAzIGZvciB0aGUgbGlicHJvdG9idWYgYW5kIGxpYnByb3RvYyBwcm9qZWN0cy4KKyAgIElmIHlvdSBhcmUgY29tcGlsaW5nIHRoZW0gYXMgc3RhdGljIGxpYnJhcmllcywgdGhlbiB5b3Ugd2lsbCBuZWVkIHRvIGxpbmsKKyAgIGFnYWluc3QgdGhlIHpsaWIgbGlicmFyeSBkaXJlY3RseSBmcm9tIHlvdXIgb3duIGFwcC4KKzYpIEVkaXQgY29uZmlnLmggKGluIHRoZSB2c3Byb2plY3RzIGRpcmVjdG9yeSkgYW5kIHVuLWNvbW1lbnQgdGhlIGxpbmUgdGhhdAorICAgI2RlZmluZXMgSEFWRV9aTElCLiAgKE9yLCBhbHRlcm5hdGl2ZWx5LCBkZWZpbmUgdGhpcyBtYWNybyB2aWEgdGhlIHByb2plY3QKKyAgIHNldHRpbmdzLikKKworTm90ZXMgb24gQ29tcGlsZXIgV2FybmluZ3MKKz09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RoZSBmb2xsb3dpbmcgd2FybmluZ3MgaGF2ZSBiZWVuIGRpc2FibGVkIHdoaWxlIGJ1aWxkaW5nIHRoZSBwcm90b2J1ZiBsaWJyYXJpZXMKK2FuZCBjb21waWxlci4gIFlvdSBtYXkgaGF2ZSB0byBkaXNhYmxlIHNvbWUgb2YgdGhlbSBpbiB5b3VyIG93biBwcm9qZWN0IGFzCit3ZWxsLCBvciBsaXZlIHdpdGggdGhlbS4KKworQzQwMTggLSAnZXhwcmVzc2lvbicgOiBzaWduZWQvdW5zaWduZWQgbWlzbWF0Y2gKK0M0MTQ2IC0gdW5hcnkgbWludXMgb3BlcmF0b3IgYXBwbGllZCB0byB1bnNpZ25lZCB0eXBlLCByZXN1bHQgc3RpbGwgdW5zaWduZWQKK0M0MjQ0IC0gQ29udmVyc2lvbiBmcm9tICd0eXBlMScgdG8gJ3R5cGUyJywgcG9zc2libGUgbG9zcyBvZiBkYXRhLgorQzQyNTEgLSAnaWRlbnRpZmllcicgOiBjbGFzcyAndHlwZScgbmVlZHMgdG8gaGF2ZSBkbGwtaW50ZXJmYWNlIHRvIGJlIHVzZWQgYnkKKyAgICAgICAgY2xpZW50cyBvZiBjbGFzcyAndHlwZTInCitDNDI2NyAtIENvbnZlcnNpb24gZnJvbSAnc2l6ZV90JyB0byAndHlwZScsIHBvc3NpYmxlIGxvc3Mgb2YgZGF0YS4KK0M0MzA1IC0gJ2lkZW50aWZpZXInIDogdHJ1bmNhdGlvbiBmcm9tICd0eXBlMScgdG8gJ3R5cGUyJworQzQzNTUgLSAndGhpcycgOiB1c2VkIGluIGJhc2UgbWVtYmVyIGluaXRpYWxpemVyIGxpc3QKK0M0ODAwIC0gJ3R5cGUnIDogZm9yY2luZyB2YWx1ZSB0byBib29sICd0cnVlJyBvciAnZmFsc2UnIChwZXJmb3JtYW5jZSB3YXJuaW5nKQorQzQ5OTYgLSAnZnVuY3Rpb24nOiB3YXMgZGVjbGFyZWQgZGVwcmVjYXRlZAorCitDNDI1MSBpcyBvZiBwYXJ0aWN1bGFyIG5vdGUsIGlmIHlvdSBhcmUgY29tcGlsaW5nIHRoZSBQcm90b2NvbCBCdWZmZXIgbGlicmFyeQorYXMgYSBETEwgKHNlZSBwcmV2aW91cyBzZWN0aW9uKS4gIFRoZSBwcm90b2NvbCBidWZmZXIgbGlicmFyeSB1c2VzIHRlbXBsYXRlcyBpbgoraXRzIHB1YmxpYyBpbnRlcmZhY2VzLiAgTVNWQyBkb2VzIG5vdCBwcm92aWRlIGFueSByZWFzb25hYmxlIHdheSB0byBleHBvcnQKK3RlbXBsYXRlIGNsYXNzZXMgZnJvbSBhIERMTC4gIEhvd2V2ZXIsIGluIHByYWN0aWNlLCBpdCBhcHBlYXJzIHRoYXQgZXhwb3J0aW5nCit0ZW1wbGF0ZXMgaXMgbm90IG5lY2Vzc2FyeSBhbnl3YXkuICBTaW5jZSB0aGUgY29tcGxldGUgZGVmaW5pdGlvbiBvZiBhbnkKK3RlbXBsYXRlIGlzIGF2YWlsYWJsZSBpbiB0aGUgaGVhZGVyIGZpbGVzLCBhbnlvbmUgaW1wb3J0aW5nIHRoZSBETEwgd2lsbCBqdXN0CitlbmQgdXAgY29tcGlsaW5nIGluc3RhbmNlcyBvZiB0aGUgdGVtcGxhdGVzIGludG8gdGhlaXIgb3duIGJpbmFyeS4gIFRoZQorUHJvdG9jb2wgQnVmZmVyIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHJlbHkgb24gc3RhdGljIHRlbXBsYXRlIG1lbWJlcnMgYmVpbmcKK3VuaXF1ZSwgc28gdGhlcmUgc2hvdWxkIGJlIG5vIHByb2JsZW0gd2l0aCB0aGlzLCBidXQgTVNWQyBwcmludHMgd2FybmluZworbmV2ZXJ0aGVsZXNzLiAgU28sIHdlIGRpc2FibGUgaXQuICBVbmZvcnR1bmF0ZWx5LCB0aGlzIHdhcm5pbmcgd2lsbCBhbHNvIGJlCitwcm9kdWNlZCB3aGVuIGNvbXBpbGluZyBjb2RlIHdoaWNoIG1lcmVseSB1c2VzIHByb3RvY29sIGJ1ZmZlcnMsIG1lYW5pbmcgeW91CittYXkgaGF2ZSB0byBkaXNhYmxlIGl0IGluIHlvdXIgY29kZSB0b28uCmRpZmYgLS1naXQgYS92c3Byb2plY3RzL3Rlc3RfcGx1Z2luLnZjcHJvaiBiL3ZzcHJvamVjdHMvdGVzdF9wbHVnaW4udmNwcm9qCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjU0OWY5NTAKLS0tIC9kZXYvbnVsbAorKysgYi92c3Byb2plY3RzL3Rlc3RfcGx1Z2luLnZjcHJvagpAQCAtMCwwICsxLDIwOSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iV2luZG93cy0xMjUyIj8+Cis8VmlzdWFsU3R1ZGlvUHJvamVjdAorCVByb2plY3RUeXBlPSJWaXN1YWwgQysrIgorCVZlcnNpb249IjkuMDAiCisJTmFtZT0idGVzdF9wbHVnaW4iCisJUHJvamVjdEdVSUQ9IntDQkJEMzRFNS0wMkIwLTQwRDUtQjZEOC1CRkVBODNFMThCMzJ9IgorCVJvb3ROYW1lc3BhY2U9InRlc3RfcGx1Z2luIgorCUtleXdvcmQ9IldpbjMyUHJvaiIKKwlUYXJnZXRGcmFtZXdvcmtWZXJzaW9uPSIxOTY2MTMiCisJPgorCTxQbGF0Zm9ybXM+CisJCTxQbGF0Zm9ybQorCQkJTmFtZT0iV2luMzIiCisJCS8+CisJPC9QbGF0Zm9ybXM+CisJPFRvb2xGaWxlcz4KKwk8L1Rvb2xGaWxlcz4KKwk8Q29uZmlndXJhdGlvbnM+CisJCTxDb25maWd1cmF0aW9uCisJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iRGVidWciCisJCQlJbnRlcm1lZGlhdGVEaXJlY3Rvcnk9IiQoT3V0RGlyKVwkKFByb2plY3ROYW1lKSIKKwkJCUNvbmZpZ3VyYXRpb25UeXBlPSIxIgorCQkJPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1ByZUJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJRGVzY3JpcHRpb249IiIKKwkJCQlDb21tYW5kTGluZT0iIgorCQkJCUFkZGl0aW9uYWxEZXBlbmRlbmNpZXM9IiIKKwkJCQlPdXRwdXRzPSIiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1hNTERhdGFHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNXZWJTZXJ2aWNlUHJveHlHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNSURMVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ0xDb21waWxlclRvb2wiCisJCQkJQWRkaXRpb25hbE9wdGlvbnM9Ii93ZDQyNDQgL3dkNDI2NyAvd2Q0MDE4IC93ZDQzNTUgL3dkNDgwMCAvd2Q0MjUxIC93ZDQ5OTYgL3dkNDE0NiAvd2Q0MzA1IgorCQkJCU9wdGltaXphdGlvbj0iMCIKKwkJCQlBZGRpdGlvbmFsSW5jbHVkZURpcmVjdG9yaWVzPSIuLi9zcmM7LjsuLi9ndGVzdC9pbmNsdWRlIgorCQkJCVByZXByb2Nlc3NvckRlZmluaXRpb25zPSJXSU4zMjtfREVCVUc7X0NPTlNPTEU7X1ZBUklBRElDX01BWD0xMDsiCisJCQkJTWluaW1hbFJlYnVpbGQ9InRydWUiCisJCQkJQmFzaWNSdW50aW1lQ2hlY2tzPSIzIgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIzIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iNCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlua2VyVG9vbCIKKwkJCQlMaW5rSW5jcmVtZW50YWw9IjIiCisJCQkJR2VuZXJhdGVEZWJ1Z0luZm9ybWF0aW9uPSJ0cnVlIgorCQkJCVN1YlN5c3RlbT0iMSIKKwkJCQlUYXJnZXRNYWNoaW5lPSIxIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNBTGlua1Rvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01hbmlmZXN0VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWERDTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0JzY01ha2VUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNGeENvcFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0FwcFZlcmlmaWVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCQk8Q29uZmlndXJhdGlvbgorCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCU91dHB1dERpcmVjdG9yeT0iUmVsZWFzZSIKKwkJCUludGVybWVkaWF0ZURpcmVjdG9yeT0iJChPdXREaXIpXCQoUHJvamVjdE5hbWUpIgorCQkJQ29uZmlndXJhdGlvblR5cGU9IjEiCisJCQk+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlQnVpbGRFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQlEZXNjcmlwdGlvbj0iIgorCQkJCUNvbW1hbmRMaW5lPSIiCisJCQkJQWRkaXRpb25hbERlcGVuZGVuY2llcz0iIgorCQkJCU91dHB1dHM9IiIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWE1MRGF0YUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1dlYlNlcnZpY2VQcm94eUdlbmVyYXRvclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01JRExUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDTENvbXBpbGVyVG9vbCIKKwkJCQlBZGRpdGlvbmFsT3B0aW9ucz0iL3dkNDI0NCAvd2Q0MjY3IC93ZDQwMTggL3dkNDM1NSAvd2Q0ODAwIC93ZDQyNTEgL3dkNDk5NiAvd2Q0MTQ2IC93ZDQzMDUiCisJCQkJQWRkaXRpb25hbEluY2x1ZGVEaXJlY3Rvcmllcz0iLi4vc3JjOy47Li4vZ3Rlc3QvaW5jbHVkZSIKKwkJCQlQcmVwcm9jZXNzb3JEZWZpbml0aW9ucz0iV0lOMzI7TkRFQlVHO19DT05TT0xFO19WQVJJQURJQ19NQVg9MTA7IgorCQkJCVJ1bnRpbWVMaWJyYXJ5PSIyIgorCQkJCVVzZVByZWNvbXBpbGVkSGVhZGVyPSIwIgorCQkJCVdhcm5pbmdMZXZlbD0iMyIKKwkJCQlEZXRlY3Q2NEJpdFBvcnRhYmlsaXR5UHJvYmxlbXM9InRydWUiCisJCQkJRGVidWdJbmZvcm1hdGlvbkZvcm1hdD0iMyIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTWFuYWdlZFJlc291cmNlQ29tcGlsZXJUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUHJlTGlua0V2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTGlua2VyVG9vbCIKKwkJCQlMaW5rSW5jcmVtZW50YWw9IjIiCisJCQkJR2VuZXJhdGVEZWJ1Z0luZm9ybWF0aW9uPSJ0cnVlIgorCQkJCVN1YlN5c3RlbT0iMSIKKwkJCQlPcHRpbWl6ZVJlZmVyZW5jZXM9IjIiCisJCQkJRW5hYmxlQ09NREFURm9sZGluZz0iMiIKKwkJCQlUYXJnZXRNYWNoaW5lPSIxIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNBTGlua1Rvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01hbmlmZXN0VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDWERDTWFrZVRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0JzY01ha2VUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNGeENvcFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0FwcFZlcmlmaWVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUG9zdEJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJPC9Db25maWd1cmF0aW9uPgorCTwvQ29uZmlndXJhdGlvbnM+CisJPFJlZmVyZW5jZXM+CisJPC9SZWZlcmVuY2VzPgorCTxGaWxlcz4KKwkJPEZpbHRlcgorCQkJTmFtZT0iSGVhZGVyIEZpbGVzIgorCQkJRmlsdGVyPSJoO2hwcDtoeHg7aG07aW5sO2luYzt4c2QiCisJCQk+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxtb2NrX2NvZGVfZ2VuZXJhdG9yLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdGVzdGluZ1xmaWxlLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQk8L0ZpbHRlcj4KKwkJPEZpbHRlcgorCQkJTmFtZT0iU291cmNlIEZpbGVzIgorCQkJRmlsdGVyPSJjcHA7YztjYztjeHg7ZGVmO29kbDtpZGw7aHBqO2JhdDthc207YXNteCIKKwkJCT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXHRlc3RfcGx1Z2luLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXG1vY2tfY29kZV9nZW5lcmF0b3IuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdGVzdGluZ1xmaWxlLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJPC9GaWx0ZXI+CisJPC9GaWxlcz4KKwk8R2xvYmFscz4KKwk8L0dsb2JhbHM+Cis8L1Zpc3VhbFN0dWRpb1Byb2plY3Q+CmRpZmYgLS1naXQgYS92c3Byb2plY3RzL3Rlc3RzLnZjcHJvaiBiL3ZzcHJvamVjdHMvdGVzdHMudmNwcm9qCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkNDI5NDkKLS0tIC9kZXYvbnVsbAorKysgYi92c3Byb2plY3RzL3Rlc3RzLnZjcHJvagpAQCAtMCwwICsxLDExMDkgQEAKK++7vzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8VmlzdWFsU3R1ZGlvUHJvamVjdAorCVByb2plY3RUeXBlPSJWaXN1YWwgQysrIgorCVZlcnNpb249IjkuMDAiCisJTmFtZT0idGVzdHMiCisJUHJvamVjdEdVSUQ9Ins0REY3Mjc2MC1DMDU1LTQwQTUtQTc3RS0zMEExN0UyQUMyREJ9IgorCVJvb3ROYW1lc3BhY2U9InRlc3RzIgorCUtleXdvcmQ9IldpbjMyUHJvaiIKKwlUYXJnZXRGcmFtZXdvcmtWZXJzaW9uPSIwIgorCT4KKwk8UGxhdGZvcm1zPgorCQk8UGxhdGZvcm0KKwkJCU5hbWU9IldpbjMyIgorCQkvPgorCTwvUGxhdGZvcm1zPgorCTxUb29sRmlsZXM+CisJPC9Ub29sRmlsZXM+CisJPENvbmZpZ3VyYXRpb25zPgorCQk8Q29uZmlndXJhdGlvbgorCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQlPdXRwdXREaXJlY3Rvcnk9IkRlYnVnIgorCQkJSW50ZXJtZWRpYXRlRGlyZWN0b3J5PSIkKE91dERpcilcJChQcm9qZWN0TmFtZSkiCisJCQlDb25maWd1cmF0aW9uVHlwZT0iMSIKKwkJCT4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNQcmVCdWlsZEV2ZW50VG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCURlc2NyaXB0aW9uPSIiCisJCQkJQ29tbWFuZExpbmU9IiIKKwkJCQlBZGRpdGlvbmFsRGVwZW5kZW5jaWVzPSIiCisJCQkJT3V0cHV0cz0iIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNYTUxEYXRhR2VuZXJhdG9yVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDV2ViU2VydmljZVByb3h5R2VuZXJhdG9yVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDTUlETFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0NMQ29tcGlsZXJUb29sIgorCQkJCUFkZGl0aW9uYWxPcHRpb25zPSIvd2Q0MjQ0IC93ZDQyNjcgL3dkNDAxOCAvd2Q0MzU1IC93ZDQ4MDAgL3dkNDI1MSAvd2Q0OTk2IC93ZDQxNDYgL3dkNDMwNSIKKwkJCQlPcHRpbWl6YXRpb249IjAiCisJCQkJQWRkaXRpb25hbEluY2x1ZGVEaXJlY3Rvcmllcz0iLi4vc3JjOy47Li4vZ3Rlc3QvaW5jbHVkZSIKKwkJCQlQcmVwcm9jZXNzb3JEZWZpbml0aW9ucz0iV0lOMzI7X0RFQlVHO19DT05TT0xFO19WQVJJQURJQ19NQVg9MTA7IgorCQkJCU1pbmltYWxSZWJ1aWxkPSJ0cnVlIgorCQkJCUJhc2ljUnVudGltZUNoZWNrcz0iMyIKKwkJCQlSdW50aW1lTGlicmFyeT0iMyIKKwkJCQlVc2VQcmVjb21waWxlZEhlYWRlcj0iMCIKKwkJCQlXYXJuaW5nTGV2ZWw9IjMiCisJCQkJRGV0ZWN0NjRCaXRQb3J0YWJpbGl0eVByb2JsZW1zPSJ0cnVlIgorCQkJCURlYnVnSW5mb3JtYXRpb25Gb3JtYXQ9IjQiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01hbmFnZWRSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUmVzb3VyY2VDb21waWxlclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1ByZUxpbmtFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0xpbmtlclRvb2wiCisJCQkJTGlua0luY3JlbWVudGFsPSIyIgorCQkJCUdlbmVyYXRlRGVidWdJbmZvcm1hdGlvbj0idHJ1ZSIKKwkJCQlTdWJTeXN0ZW09IjEiCisJCQkJVGFyZ2V0TWFjaGluZT0iMSIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQUxpbmtUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNYW5pZmVzdFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1hEQ01ha2VUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNCc2NNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDRnhDb3BUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNBcHBWZXJpZmllclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1Bvc3RCdWlsZEV2ZW50VG9vbCIKKwkJCS8+CisJCTwvQ29uZmlndXJhdGlvbj4KKwkJPENvbmZpZ3VyYXRpb24KKwkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQlPdXRwdXREaXJlY3Rvcnk9IlJlbGVhc2UiCisJCQlJbnRlcm1lZGlhdGVEaXJlY3Rvcnk9IiQoT3V0RGlyKVwkKFByb2plY3ROYW1lKSIKKwkJCUNvbmZpZ3VyYXRpb25UeXBlPSIxIgorCQkJPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1ByZUJ1aWxkRXZlbnRUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJRGVzY3JpcHRpb249IiIKKwkJCQlDb21tYW5kTGluZT0iIgorCQkJCUFkZGl0aW9uYWxEZXBlbmRlbmNpZXM9IiIKKwkJCQlPdXRwdXRzPSIiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1hNTERhdGFHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNXZWJTZXJ2aWNlUHJveHlHZW5lcmF0b3JUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNSURMVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQ0xDb21waWxlclRvb2wiCisJCQkJQWRkaXRpb25hbE9wdGlvbnM9Ii93ZDQyNDQgL3dkNDI2NyAvd2Q0MDE4IC93ZDQzNTUgL3dkNDgwMCAvd2Q0MjUxIC93ZDQ5OTYgL3dkNDE0NiAvd2Q0MzA1IgorCQkJCUFkZGl0aW9uYWxJbmNsdWRlRGlyZWN0b3JpZXM9Ii4uL3NyYzsuOy4uL2d0ZXN0L2luY2x1ZGUiCisJCQkJUHJlcHJvY2Vzc29yRGVmaW5pdGlvbnM9IldJTjMyO05ERUJVRztfQ09OU09MRTtfVkFSSUFESUNfTUFYPTEwOyIKKwkJCQlSdW50aW1lTGlicmFyeT0iMiIKKwkJCQlVc2VQcmVjb21waWxlZEhlYWRlcj0iMCIKKwkJCQlXYXJuaW5nTGV2ZWw9IjMiCisJCQkJRGV0ZWN0NjRCaXRQb3J0YWJpbGl0eVByb2JsZW1zPSJ0cnVlIgorCQkJCURlYnVnSW5mb3JtYXRpb25Gb3JtYXQ9IjMiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ01hbmFnZWRSZXNvdXJjZUNvbXBpbGVyVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDUmVzb3VyY2VDb21waWxlclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1ByZUxpbmtFdmVudFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ0xpbmtlclRvb2wiCisJCQkJTGlua0luY3JlbWVudGFsPSIyIgorCQkJCUdlbmVyYXRlRGVidWdJbmZvcm1hdGlvbj0idHJ1ZSIKKwkJCQlTdWJTeXN0ZW09IjEiCisJCQkJT3B0aW1pemVSZWZlcmVuY2VzPSIyIgorCQkJCUVuYWJsZUNPTURBVEZvbGRpbmc9IjIiCisJCQkJVGFyZ2V0TWFjaGluZT0iMSIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDQUxpbmtUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNNYW5pZmVzdFRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1hEQ01ha2VUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNCc2NNYWtlVG9vbCIKKwkJCS8+CisJCQk8VG9vbAorCQkJCU5hbWU9IlZDRnhDb3BUb29sIgorCQkJLz4KKwkJCTxUb29sCisJCQkJTmFtZT0iVkNBcHBWZXJpZmllclRvb2wiCisJCQkvPgorCQkJPFRvb2wKKwkJCQlOYW1lPSJWQ1Bvc3RCdWlsZEV2ZW50VG9vbCIKKwkJCS8+CisJCTwvQ29uZmlndXJhdGlvbj4KKwk8L0NvbmZpZ3VyYXRpb25zPgorCTxSZWZlcmVuY2VzPgorCTwvUmVmZXJlbmNlcz4KKwk8RmlsZXM+CisJCTxGaWx0ZXIKKwkJCU5hbWU9IkhlYWRlciBGaWxlcyIKKwkJCUZpbHRlcj0iaDtocHA7aHh4O2htO2lubDtpbmM7eHNkIgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezkzOTk1MzgwLTg5QkQtNGIwNC04OEVCLTYyNUZCRTUyRUJGQn0iCisJCQk+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRlc3RpbmdcZmlsZS5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRlc3RpbmdcZ29vZ2xldGVzdC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRlc3RfdXRpbC5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlIFJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxtYXBfdGVzdF91dGlsX2ltcGwuaCI+PC9GaWxlPgorCQkJPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF90ZXN0X3V0aWwuaCI+PC9GaWxlPgorCQkJPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGFyZW5hX3Rlc3RfdXRpbC5oIj48L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxtb2NrX2NvZGVfZ2VuZXJhdG9yLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0LnBiLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnBiLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wYi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnQucGIuaCIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGluZS5wYi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9tc2V0LnBiLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X29wdGltaXplX2Zvci5wYi5oIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnBiLmgiCisJCQkJPgorCQkJPC9GaWxlPgorCQk8L0ZpbHRlcj4KKwkJPEZpbHRlcgorCQkJTmFtZT0iUmVzb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9InJjO2ljbztjdXI7Ym1wO2RsZztyYzI7cmN0O2JpbjtyZ3M7Z2lmO2pwZztqcGVnO2pwZTtyZXN4IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezY3REE2QUI2LUY4MDAtNGMwOC04QjdBLTgzQkIxMjFBQUQwMX0iCisJCQk+CisJCTwvRmlsdGVyPgorCQk8RmlsdGVyCisJCQlOYW1lPSJTb3VyY2UgRmlsZXMiCisJCQlGaWx0ZXI9ImNwcDtjO2NjO2N4eDtkZWY7b2RsO2lkbDtocGo7YmF0O2FzbTthc214IgorCQkJVW5pcXVlSWRlbnRpZmllcj0iezRGQzczN0YxLUM3QTUtNDM3Ni1BMDY2LTJBMzJENzUyQTJGRn0iCisJCQk+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxhcmVuYXN0cmluZ191bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxhcmVuYV91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjb21tYW5kX2xpbmVfaW50ZXJmYWNlX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfYm9vdHN0cmFwX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfcGx1Z2luX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcaW1wb3J0ZXJfdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcamF2YVxqYXZhX2RvY19jb21tZW50X3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGphdmFcamF2YV9wbHVnaW5fdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcbW9ja19jb2RlX2dlbmVyYXRvci5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxwYXJzZXJfdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJccHl0aG9uXHB5dGhvbl9wbHVnaW5fdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZGVzY3JpcHRvcl9kYXRhYmFzZV91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxkZXNjcmlwdG9yX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGRyb3BfdW5rbm93bl9maWVsZHNfdGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxkeW5hbWljX21lc3NhZ2VfdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcZXh0ZW5zaW9uX3NldF91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxnZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXGNvZGVkX3N0cmVhbV91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1xwcmludGVyX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGlvXHRva2VuaXplcl91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxpb1x6ZXJvX2NvcHlfc3RyZWFtX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF9maWVsZF90ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF90ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXG1hcF90ZXN0X3V0aWwuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUgUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXGFyZW5hX3Rlc3RfdXRpbC5jYyI+PC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWVzc2FnZV91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlxub19maWVsZF9wcmVzZW5jZV90ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHByZXNlcnZlX3Vua25vd25fZW51bV90ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHByb3RvM19hcmVuYV91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxyZWZsZWN0aW9uX29wc191bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxyZXBlYXRlZF9maWVsZF9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHJlcGVhdGVkX2ZpZWxkX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXGNvbW1vbl91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xvbmNlX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXHN0cmluZ3ByaW50Zl91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1xzdHJ1Y3R1cmFsbHlfdmFsaWRfdW5pdHRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcc3R1YnNcc3RydXRpbF91bml0dGVzdC5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1ZlxzdHVic1x0ZW1wbGF0ZV91dGlsX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHN0dWJzXHR5cGVfdHJhaXRzX3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRlc3RpbmdcZmlsZS5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLi5cc3JjXGdvb2dsZVxwcm90b2J1Zlx0ZXN0aW5nXGdvb2dsZXRlc3QuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdGVzdF91dGlsLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHRleHRfZm9ybWF0X3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHVua25vd25fZmllbGRfc2V0X3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuLlxzcmNcZ29vZ2xlXHByb3RvYnVmXHdpcmVfZm9ybWF0X3VuaXR0ZXN0LmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1ZlxtYXBfcHJvdG8yX3VuaXR0ZXN0LnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1ZlxtYXBfdW5pdHRlc3QucGIuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2FyZW5hLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9lbXB0eS5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydC5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnRfcHVibGljLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbXNldC5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJCTxGaWxlCisJCQkJUmVsYXRpdmVQYXRoPSIuXGdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9ub19hcmVuYS5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucGIuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X29wdGltaXplX2Zvci5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3QucGIuY2MiCisJCQkJPgorCQkJPC9GaWxlPgorCQkJPEZpbGUKKwkJCQlSZWxhdGl2ZVBhdGg9Ii5cZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bS5wYi5jYyIKKwkJCQk+CisJCQk8L0ZpbGU+CisJCQk8RmlsZQorCQkJCVJlbGF0aXZlUGF0aD0iLlxnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmNjIgorCQkJCT4KKwkJCTwvRmlsZT4KKwkJPC9GaWx0ZXI+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bTIucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWFwX3Byb3RvMl91bml0dGVzdC5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgbWFwX3Byb3RvMl91bml0dGVzdC5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcbWFwX3Byb3RvMl91bml0dGVzdC5wYi5oO2dvb2dsZVxwcm90b2J1ZlxtYXBfcHJvdG8yX3VuaXR0ZXN0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIG1hcF9wcm90bzJfdW5pdHRlc3QucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcbWFwX3Byb3RvMl91bml0dGVzdC5wYi5oO2dvb2dsZVxwcm90b2J1ZlxtYXBfcHJvdG8yX3VuaXR0ZXN0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcbWFwX3VuaXR0ZXN0LnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyBtYXBfdW5pdHRlc3QucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcbWFwX3VuaXR0ZXN0LnBiLmg7Z29vZ2xlXHByb3RvYnVmXG1hcF91bml0dGVzdC5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyBtYXBfdW5pdHRlc3QucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1ZlxtYXBfdW5pdHRlc3QucGIuaDtnb29nbGVccHJvdG9idWZcbWFwX3VuaXR0ZXN0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3QucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0LnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3QucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3QucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3QucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0LnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfYXJlbmEucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2FyZW5hLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2FyZW5hLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfYXJlbmEucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfYXJlbmEucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfYXJlbmEucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9hcmVuYS5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2FyZW5hLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2FyZW5hLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2Ryb3BfdW5rbm93bl9maWVsZHMucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9lbWJlZF9vcHRpbWl6ZV9mb3IucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9lbWJlZF9vcHRpbWl6ZV9mb3IucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbWJlZF9vcHRpbWl6ZV9mb3IucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9lbWJlZF9vcHRpbWl6ZV9mb3IucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1wdHkucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2VtcHR5LnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtcHR5LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1wdHkucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfZW1wdHkucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfZW1wdHkucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbXB0eS5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2VtcHR5LnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2VtcHR5LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2ltcG9ydF9saXRlLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfbGl0ZS5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydF9saXRlLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydF9saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0LnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9pbXBvcnQucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0LnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydC5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9pbXBvcnQucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnQucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWNfbGl0ZS5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnRfcHVibGljLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9pbXBvcnRfcHVibGljLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2xpdGVfaW1wb3J0c19ub25saXRlLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGVfaW1wb3J0c19ub25saXRlLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2xpdGVfaW1wb3J0c19ub25saXRlLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X2xpdGVfaW1wb3J0c19ub25saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfbGl0ZS5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X2xpdGUucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbGl0ZS5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9saXRlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbXNldC5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3RfbXNldC5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbXNldC5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9tc2V0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X21zZXQucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfbXNldC5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9tc2V0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9ub19hcmVuYV9pbXBvcnQucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X25vX2FyZW5hX2ltcG9ydC5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9ub19hcmVuYV9pbXBvcnQucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYV9pbXBvcnQucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9ub19hcmVuYV9pbXBvcnQucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmEucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X25vX2FyZW5hLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmEucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fYXJlbmEucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3Rfbm9fYXJlbmEucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYS5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X25vX2FyZW5hLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X25vX2FyZW5hLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucHJvdG8iCisJCQk+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJEZWJ1Z3xXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X25vX2ZpZWxkX3ByZXNlbmNlLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2ZpZWxkX3ByZXNlbmNlLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZS5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X25vX2ZpZWxkX3ByZXNlbmNlLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X25vX2ZpZWxkX3ByZXNlbmNlLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi57aCxjY30uLi4iCisJCQkJCUNvbW1hbmRMaW5lPSJEZWJ1Z1xwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iUmVsZWFzZXxXaW4zMiIKKwkJCQk+CisJCQkJPFRvb2wKKwkJCQkJTmFtZT0iVkNDdXN0b21CdWlsZFRvb2wiCisJCQkJCURlc2NyaXB0aW9uPSJHZW5lcmF0aW5nIHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5oO2dvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9vcHRpbWl6ZV9mb3IucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X29wdGltaXplX2Zvci5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9vcHRpbWl6ZV9mb3IucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9vcHRpbWl6ZV9mb3IucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bS5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvIgorCQkJPgorCQkJPEZpbGVDb25maWd1cmF0aW9uCisJCQkJTmFtZT0iRGVidWd8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9wcm90bzNfYXJlbmEucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iRGVidWdccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvIgorCQkJCQlPdXRwdXRzPSJnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmg7Z29vZ2xlXHByb3RvYnVmXHVuaXR0ZXN0X3Byb3RvM19hcmVuYS5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IlJlbGVhc2V8V2luMzIiCisJCQkJPgorCQkJCTxUb29sCisJCQkJCU5hbWU9IlZDQ3VzdG9tQnVpbGRUb29sIgorCQkJCQlEZXNjcmlwdGlvbj0iR2VuZXJhdGluZyB1bml0dGVzdF9wcm90bzNfYXJlbmEucGIue2gsY2N9Li4uIgorCQkJCQlDb21tYW5kTGluZT0iUmVsZWFzZVxwcm90b2MgLUkuLi9zcmMgLS1jcHBfb3V0PS4gLi4vc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfYXJlbmEucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlx1bml0dGVzdF9wcm90bzNfYXJlbmEucGIuaDtnb29nbGVccHJvdG9idWZcdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmNjIgorCQkJCS8+CisJCQk8L0ZpbGVDb25maWd1cmF0aW9uPgorCQk8L0ZpbGU+CisJCTxGaWxlCisJCQlSZWxhdGl2ZVBhdGg9Ii4uXHNyY1xnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byIKKwkJCT4KKwkJCTxGaWxlQ29uZmlndXJhdGlvbgorCQkJCU5hbWU9IkRlYnVnfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IkRlYnVnXHByb3RvYyAtSS4uL3NyYyAtLWNwcF9vdXQ9LiAuLi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG8iCisJCQkJCU91dHB1dHM9Imdvb2dsZVxwcm90b2J1Zlxjb21waWxlclxjcHBcY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnBiLmg7Z29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfdGVzdF9iYWRfaWRlbnRpZmllcnMucGIuY2MiCisJCQkJLz4KKwkJCTwvRmlsZUNvbmZpZ3VyYXRpb24+CisJCQk8RmlsZUNvbmZpZ3VyYXRpb24KKwkJCQlOYW1lPSJSZWxlYXNlfFdpbjMyIgorCQkJCT4KKwkJCQk8VG9vbAorCQkJCQlOYW1lPSJWQ0N1c3RvbUJ1aWxkVG9vbCIKKwkJCQkJRGVzY3JpcHRpb249IkdlbmVyYXRpbmcgY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnBiLntoLGNjfS4uLiIKKwkJCQkJQ29tbWFuZExpbmU9IlJlbGVhc2VccHJvdG9jIC1JLi4vc3JjIC0tY3BwX291dD0uIC4uL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90byIKKwkJCQkJT3V0cHV0cz0iZ29vZ2xlXHByb3RvYnVmXGNvbXBpbGVyXGNwcFxjcHBfdGVzdF9iYWRfaWRlbnRpZmllcnMucGIuaDtnb29nbGVccHJvdG9idWZcY29tcGlsZXJcY3BwXGNwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5jYyIKKwkJCQkvPgorCQkJPC9GaWxlQ29uZmlndXJhdGlvbj4KKwkJPC9GaWxlPgorCTwvRmlsZXM+CisJPEdsb2JhbHM+CisJPC9HbG9iYWxzPgorPC9WaXN1YWxTdHVkaW9Qcm9qZWN0Pgo=